blob: ab72fa0ef2deadfb880f65c3ef61d9b2957e513c [file] [log] [blame]
/**
* 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
* @version v2.2.10
* @link http://swagger.io
* @license Apache-2.0
*/
(function(){/* jshint ignore:start */
{(function() {
var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
templates['apikey_auth'] = template({"1":function(container,depth0,helpers,partials,data) {
var stack1;
return " <span class=\"key_auth__value\">"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.value : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "</span>\n";
},"3":function(container,depth0,helpers,partials,data) {
return " <input placeholder=\"api_key\" class=\"auth_input input_apiKey_entry\" name=\"apiKey\" type=\"text\"/>\n";
},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return "<div class=\"key_input_container\">\n <h3 class=\"auth__title\">Api key authorization</h3>\n <div class=\"auth__description\">"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "</div>\n <div>\n <div class=\"key_auth__field\">\n <span class=\"key_auth__label\">name:</span>\n <span class=\"key_auth__value\">"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "</span>\n </div>\n <div class=\"key_auth__field\">\n <span class=\"key_auth__label\">in:</span>\n <span class=\"key_auth__value\">"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0["in"] : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "</span>\n </div>\n <div class=\"key_auth__field\">\n <span class=\"key_auth__label\">value:</span>\n"
+ ((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 : "")
+ " </div>\n </div>\n</div>\n";
},"useData":true});
templates['auth_button'] = template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
return "<a class='authorize__btn' href=\"#\">Authorize</a>\n";
},"useData":true});
templates['auth_button_operation'] = template({"1":function(container,depth0,helpers,partials,data) {
return " authorize__btn_operation_login\n";
},"3":function(container,depth0,helpers,partials,data) {
return " authorize__btn_operation_logout\n";
},"5":function(container,depth0,helpers,partials,data) {
var stack1;
return " <ul class=\"authorize-scopes\">\n"
+ ((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 : "")
+ " </ul>\n";
},"6":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return " <li class=\"authorize__scope\" title=\""
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "\">"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.scope : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "</li>\n";
},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {};
return "<div class=\"authorize__btn authorize__btn_operation\n"
+ ((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 : "")
+ "\">\n"
+ ((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 : "")
+ "</div>\n";
},"useData":true});
templates['auth_view'] = template({"1":function(container,depth0,helpers,partials,data) {
return " <button type=\"button\" class=\"auth__button auth_submit__button\" data-sw-translate>Authorize</button>\n";
},"3":function(container,depth0,helpers,partials,data) {
return " <button type=\"button\" class=\"auth__button auth_logout__button\" data-sw-translate>Logout</button>\n";
},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {};
return "<div class=\"auth_container\">\n\n <div class=\"auth_inner\"></div>\n <div class=\"auth_submit\">\n"
+ ((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 : "")
+ ((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 : "")
+ " </div>\n\n</div>\n";
},"useData":true});
templates['basic_auth'] = template({"1":function(container,depth0,helpers,partials,data) {
return " - authorized";
},"3":function(container,depth0,helpers,partials,data) {
var stack1;
return " <span class=\"basic_auth__value\">"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.username : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "</span>\n";
},"5":function(container,depth0,helpers,partials,data) {
return " <input required placeholder=\"username\" class=\"basic_auth__username auth_input\" name=\"username\" type=\"text\"/>\n";
},"7":function(container,depth0,helpers,partials,data) {
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";
},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {};
return "<div class='basic_auth_container'>\n <h3 class=\"auth__title\">Basic authentication"
+ ((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 : "")
+ "</h3>\n <form class=\"basic_input_container\">\n <div class=\"auth__description\">"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "</div>\n <div class=\"auth_label\">\n <span class=\"basic_auth__label\" data-sw-translate>username:</span>\n"
+ ((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 : "")
+ " </div>\n"
+ ((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 : "")
+ " </form>\n</div>\n";
},"useData":true});
templates['content_type'] = template({"1":function(container,depth0,helpers,partials,data) {
var stack1;
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 : "");
},"2":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return " <option value=\""
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,depth0,{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "\">"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,depth0,{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "</option>\n";
},"4":function(container,depth0,helpers,partials,data) {
return " <option value=\"application/json\">application/json</option>\n";
},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return "<label data-sw-translate for=\""
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.contentTypeId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "\">Response Content Type</label>\n<select name=\"contentType\" id=\""
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.contentTypeId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "\">\n"
+ ((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 : "")
+ "</select>\n";
},"useData":true});
templates['main'] = template({"1":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return " <div class=\"info_title\">"
+ ((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 : "")
+ "</div>\n <div class=\"info_description markdown\">"
+ ((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 : "")
+ "</div>\n"
+ ((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 : "")
+ " "
+ ((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 : "")
+ "\n "
+ ((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 : "")
+ "\n "
+ ((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 : "")
+ "\n "
+ ((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 : "")
+ "\n "
+ ((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 : "")
+ "\n";
},"2":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return " <p>"
+ ((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 : "")
+ "</p>\n <a href=\""
+ ((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 : "")
+ "\" target=\"_blank\">"
+ ((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 : "")
+ "</a>\n";
},"4":function(container,depth0,helpers,partials,data) {
var stack1;
return "<div class=\"info_tos\"><a target=\"_blank\" href=\""
+ ((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 : "")
+ "\" data-sw-translate>Terms of service</a></div>";
},"6":function(container,depth0,helpers,partials,data) {
var stack1;
return "<div><div class='info_name' style=\"display: inline\" data-sw-translate>Created by </div> "
+ ((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 : "")
+ "</div>";
},"8":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return "<div class='info_url' data-sw-translate>See more at <a href=\""
+ ((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 : "")
+ "\">"
+ ((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 : "")
+ "</a></div>";
},"10":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return "<div class='info_email'><a target=\"_parent\" href=\"mailto:"
+ ((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 : "")
+ "?subject="
+ ((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 : "")
+ "\" data-sw-translate>Contact the developer</a></div>";
},"12":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return "<div class='info_license'><a target=\"_blank\" href='"
+ ((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 : "")
+ "'>"
+ ((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 : "")
+ "</a></div>";
},"14":function(container,depth0,helpers,partials,data) {
var stack1;
return " , <span style=\"font-variant: small-caps\" data-sw-translate>api version</span>: "
+ ((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 : "")
+ "\n ";
},"16":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return " <span style=\"float:right\"><a target=\"_blank\" href=\""
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.validatorUrl : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "/debug?url="
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.url : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "\"><img id=\"validator\" src=\""
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.validatorUrl : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "?url="
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.url : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "\"></a>\n </span>\n";
},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {};
return "<div class='info' id='api_info'>\n"
+ ((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 : "")
+ "</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>: "
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(alias1,(depth0 != null ? depth0.basePath : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "\n"
+ ((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 : "")
+ "]\n"
+ ((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 : "")
+ " </h4>\n </div>\n</div>\n";
},"useData":true});
templates['oauth2'] = template({"1":function(container,depth0,helpers,partials,data) {
var stack1;
return "<p>Authorization URL: "
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.authorizationUrl : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "</p>";
},"3":function(container,depth0,helpers,partials,data) {
var stack1;
return "<p>Token URL: "
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.tokenUrl : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "</p>";
},"5":function(container,depth0,helpers,partials,data) {
return " <p>Please input username and password for password flow authorization</p>\n <fieldset>\n <div><label>Username: <input class=\"oauth-username\" type=\"text\" name=\"username\"></label></div>\n <div><label>Password: <input class=\"oauth-password\" type=\"password\" name=\"password\"></label></div>\n </fieldset>\n";
},"7":function(container,depth0,helpers,partials,data) {
var stack1;
return " <p>Setup client authentication."
+ ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.requireClientAuthenticaiton : depth0),{"name":"if","hash":{},"fn":container.program(8, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ "</p>\n <fieldset>\n <div><label>Type:\n <select class=\"oauth-client-authentication-type\" name=\"client-authentication-type\">\n <option value=\"none\" selected>None or other</option>\n <option value=\"basic\">Basic auth</option>\n <option value=\"request-body\">Request body</option>\n </select>\n </label></div>\n <div class=\"oauth-client-authentication\" hidden>\n <div><label>ClientId: <input class=\"oauth-client-id\" type=\"text\" name=\"client-id\"></label></div>\n <div><label>Secret: <input class=\"oauth-client-secret\" type=\"text\" name=\"client-secret\"></label></div>\n </div>\n </fieldset>\n";
},"8":function(container,depth0,helpers,partials,data) {
return "(Required)";
},"10":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return " <li>\n <input class=\"oauth-scope\" type=\"checkbox\" data-scope=\""
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.scope : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "\" oauthtype=\""
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.OAuthSchemeKey : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "\"/>\n <label>"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.scope : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "</label><br/>\n <span class=\"api-scope-desc\">"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "\n"
+ ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.OAuthSchemeKey : depth0),{"name":"if","hash":{},"fn":container.program(11, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ " </span>\n </li>\n";
},"11":function(container,depth0,helpers,partials,data) {
var stack1;
return " ("
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.OAuthSchemeKey : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ ")\n";
},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return "<div>\n <h3 class=\"auth__title\">OAuth2.0</h3>\n <p>"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "</p>\n "
+ ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.authorizationUrl : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ "\n "
+ ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.tokenUrl : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ "\n <p>flow: "
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.flow : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "</p>\n"
+ ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isPasswordFlow : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.clientAuthentication : depth0),{"name":"if","hash":{},"fn":container.program(7, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ " <p><strong> "
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.appName : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ " </strong> API requires the following scopes. Select which ones you want to grant to Swagger UI.</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 <ul class=\"api-popup-scopes\">\n"
+ ((stack1 = helpers.each.call(alias1,(depth0 != null ? depth0.scopes : depth0),{"name":"each","hash":{},"fn":container.program(10, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ " </ul>\n</div>";
},"useData":true});
templates['operation'] = template({"1":function(container,depth0,helpers,partials,data) {
return "deprecated";
},"3":function(container,depth0,helpers,partials,data) {
return " <h4><span data-sw-translate>Warning: Deprecated</span></h4>\n";
},"5":function(container,depth0,helpers,partials,data) {
var stack1;
return " <h4><span data-sw-translate>Implementation Notes</span></h4>\n <div class=\"markdown\">"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "</div>\n";
},"7":function(container,depth0,helpers,partials,data) {
return " <div class='authorize-wrapper authorize-wrapper_operation'></div>\n";
},"9":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {};
return " <div class=\"response-class\">\n <h4><span data-sw-translate>Response Class</span> (<span data-sw-translate>Status</span> "
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(alias1,(depth0 != null ? depth0.successCode : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ ")</h4>\n "
+ ((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 : "")
+ "\n <p><span class=\"model-signature\" /></p>\n <br/>\n <div class=\"response-content-type\" />\n </div>\n";
},"10":function(container,depth0,helpers,partials,data) {
var stack1;
return "<div class=\"markdown\">"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.successDescription : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "</div>";
},"12":function(container,depth0,helpers,partials,data) {
var stack1;
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"
+ ((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 : "")
+ " </tbody>\n </table>\n";
},"13":function(container,depth0,helpers,partials,data) {
var stack1, helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return " <tr>\n <td>"
+ container.escapeExpression(((helper = (helper = helpers.key || (data && data.key)) != null ? helper : alias2),(typeof helper === "function" ? helper.call(alias1,{"name":"key","hash":{},"data":data}) : helper)))
+ "</td>\n <td>"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "</td>\n <td>"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.type : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "</td>\n <td>"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.other : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "</td>\n </tr>\n";
},"15":function(container,depth0,helpers,partials,data) {
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";
},"17":function(container,depth0,helpers,partials,data) {
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";
},"19":function(container,depth0,helpers,partials,data) {
return "";
},"21":function(container,depth0,helpers,partials,data) {
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";
},"23":function(container,depth0,helpers,partials,data) {
return " <h4 data-sw-translate>Request Headers</h4>\n <div class='block request_headers'></div>\n";
},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing, alias3=container.escapeExpression;
return " <ul class='operations' >\n <li class='"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.method : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ " operation' id='"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.parentId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "_"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.nickname : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "'>\n <div class='heading'>\n <h3>\n <span class='http_method'>\n <a href='#!/"
+ alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.encodedParentId : depth0),{"name":"sanitize","hash":{},"data":data}))
+ "/"
+ alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.nickname : depth0),{"name":"sanitize","hash":{},"data":data}))
+ "' class=\"toggleOperation\">"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.method : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "</a>\n </span>\n <span class='path'>\n <a href='#!/"
+ alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.encodedParentId : depth0),{"name":"sanitize","hash":{},"data":data}))
+ "/"
+ alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.nickname : depth0),{"name":"sanitize","hash":{},"data":data}))
+ "' class=\"toggleOperation "
+ ((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 : "")
+ "\">"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.path : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "</a>\n </span>\n </h3>\n <ul class='options'>\n <li>\n <a href='#!/"
+ alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.encodedParentId : depth0),{"name":"sanitize","hash":{},"data":data}))
+ "/"
+ alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.nickname : depth0),{"name":"sanitize","hash":{},"data":data}))
+ "' class=\"toggleOperation\"><span class=\"markdown\">"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.summary : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "</span></a>\n </li>\n </ul>\n </div>\n <div class='content' id='"
+ alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.encodedParentId : depth0),{"name":"sanitize","hash":{},"data":data}))
+ "_"
+ alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.nickname : depth0),{"name":"sanitize","hash":{},"data":data}))
+ "_content' style='display:none'>\n"
+ ((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 : "")
+ ((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 : "")
+ ((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 : "")
+ ((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 : "")
+ "\n"
+ ((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 : "")
+ "\n <form accept-charset='UTF-8' class='sandbox'>\n <div style='margin:0;padding:0;display:inline'></div>\n"
+ ((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 : "")
+ ((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 : "")
+ ((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 : "")
+ " </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"
+ ((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 : "")
+ " <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";
},"useData":true});
templates['param'] = template({"1":function(container,depth0,helpers,partials,data) {
var stack1;
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 : "");
},"2":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return " <input type=\"file\" name='"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "' id='"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "'/>\n <div class=\"parameter-content-type\" />\n";
},"4":function(container,depth0,helpers,partials,data) {
var stack1;
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 : "");
},"5":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return " <div class=\"editor_holder\"></div>\n <textarea class='body-textarea' name='"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "' id='"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "'>"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0["default"] : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "</textarea>\n <br />\n <div class=\"parameter-content-type\" />\n";
},"7":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return " <textarea class='body-textarea' name='"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "' id='"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "'></textarea>\n <div class=\"editor_holder\"></div>\n <br />\n <div class=\"parameter-content-type\" />\n";
},"9":function(container,depth0,helpers,partials,data) {
var stack1;
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 : "");
},"10":function(container,depth0,helpers,partials,data) {
var stack1;
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 : "");
},"11":function(container,depth0,helpers,partials,data) {
return "";
},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return "<td class='code'><label for='"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "'>"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "</label></td>\n<td>\n\n"
+ ((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 : "")
+ "\n</td>\n<td class=\"markdown\">"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "</td>\n<td>"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.paramType : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "</td>\n<td>\n <span class=\"model-signature\"></span>\n</td>\n";
},"useData":true});
templates['param_list'] = template({"1":function(container,depth0,helpers,partials,data) {
return " required";
},"3":function(container,depth0,helpers,partials,data) {
return " multiple=\"multiple\"";
},"5":function(container,depth0,helpers,partials,data) {
return " required ";
},"7":function(container,depth0,helpers,partials,data) {
var stack1;
return " <option "
+ ((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 : "")
+ " value=''></option>\n";
},"8":function(container,depth0,helpers,partials,data) {
return " selected=\"\" ";
},"10":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return "\n <option "
+ ((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 : "")
+ " value='"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.value : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "'> "
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.value : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ " "
+ ((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 : "")
+ " </option>\n\n";
},"11":function(container,depth0,helpers,partials,data) {
return " selected=\"\" ";
},"13":function(container,depth0,helpers,partials,data) {
return " (default) ";
},"15":function(container,depth0,helpers,partials,data) {
return "<strong>";
},"17":function(container,depth0,helpers,partials,data) {
return "</strong>";
},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
var stack1, helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return "<td class='code"
+ ((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 : "")
+ "'><label for='"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "'>"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "</label></td>\n<td>\n <select "
+ ((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 : "")
+ " class=\"parameter "
+ ((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 : "")
+ "\" name=\""
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "\" id=\""
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "\">\n\n"
+ ((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 : "")
+ "\n"
+ ((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 : "")
+ "\n </select>\n</td>\n<td class=\"markdown\">"
+ ((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 : "")
+ ((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 : "")
+ ((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 : "")
+ "</td>\n<td>"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.paramType : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "</td>\n<td><span class=\"model-signature\"></span></td>\n";
},"useData":true});
templates['param_readonly'] = template({"1":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return " <textarea class='body-textarea' readonly='readonly' name='"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "' id='"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "'>"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0["default"] : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "</textarea>\n <div class=\"parameter-content-type\" />\n";
},"3":function(container,depth0,helpers,partials,data) {
var stack1;
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 : "");
},"4":function(container,depth0,helpers,partials,data) {
var stack1;
return " "
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0["default"] : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "\n";
},"6":function(container,depth0,helpers,partials,data) {
return " (empty)\n";
},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return "<td class='code'><label for='"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "'>"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "</label></td>\n<td>\n"
+ ((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 : "")
+ "</td>\n<td class=\"markdown\">"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "</td>\n<td>"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.paramType : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "</td>\n<td><span class=\"model-signature\"></span></td>\n";
},"useData":true});
templates['param_readonly_required'] = template({"1":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return " <textarea class='body-textarea' readonly='readonly' placeholder='(required)' name='"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "' id='"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "'>"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0["default"] : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "</textarea>\n";
},"3":function(container,depth0,helpers,partials,data) {
var stack1;
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 : "");
},"4":function(container,depth0,helpers,partials,data) {
var stack1;
return " "
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0["default"] : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "\n";
},"6":function(container,depth0,helpers,partials,data) {
return " (empty)\n";
},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return "<td class='code required'><label for='"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "'>"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "</label></td>\n<td>\n"
+ ((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 : "")
+ "</td>\n<td class=\"markdown\">"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "</td>\n<td>"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.paramType : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "</td>\n<td><span class=\"model-signature\"></span></td>\n";
},"useData":true});
templates['param_required'] = template({"1":function(container,depth0,helpers,partials,data) {
var stack1;
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 : "");
},"2":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return " <input type=\"file\" name='"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "' id='"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "'/>\n";
},"4":function(container,depth0,helpers,partials,data) {
var stack1;
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 : "");
},"5":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return " <div class=\"editor_holder\"></div>\n <textarea class='body-textarea required' placeholder='(required)' name='"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "' id=\""
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "\">"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0["default"] : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "</textarea>\n <br />\n <div class=\"parameter-content-type\" />\n";
},"7":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return " <textarea class='body-textarea required' placeholder='(required)' name='"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "' id='"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "'></textarea>\n <div class=\"editor_holder\"></div>\n <br />\n <div class=\"parameter-content-type\" />\n";
},"9":function(container,depth0,helpers,partials,data) {
var stack1;
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 : "");
},"10":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return " <input class='parameter required' type='file' name='"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "' id='"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "'/>\n";
},"12":function(container,depth0,helpers,partials,data) {
var stack1;
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 : "");
},"13":function(container,depth0,helpers,partials,data) {
return "";
},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return "<td class='code required'><label for='"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "'>"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "</label></td>\n<td>\n"
+ ((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 : "")
+ "</td>\n<td>\n <strong><span class=\"markdown\">"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "</span></strong>\n</td>\n<td>"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.paramType : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "</td>\n<td><span class=\"model-signature\"></span></td>\n";
},"useData":true});
templates['parameter_content_type'] = template({"1":function(container,depth0,helpers,partials,data) {
var stack1;
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 : "");
},"2":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return " <option value=\""
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,depth0,{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "\">"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,depth0,{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "</option>\n";
},"4":function(container,depth0,helpers,partials,data) {
return " <option value=\"application/json\">application/json</option>\n";
},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
var stack1, helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return "<label for=\""
+ 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)))
+ "\" data-sw-translate>Parameter content type:</label>\n<select name=\"parameterContentType\" id=\""
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.parameterContentTypeId : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "\">\n"
+ ((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 : "")
+ "</select>\n";
},"useData":true});
templates['popup'] = template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
var helper;
return "<div class=\"api-popup-dialog-wrapper\">\n <div class=\"api-popup-title\">"
+ 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)))
+ "</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>";
},"useData":true});
templates['resource'] = template({"1":function(container,depth0,helpers,partials,data) {
return " : ";
},"3":function(container,depth0,helpers,partials,data) {
var stack1;
return " <li>\n <a href='"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.url : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "' data-sw-translate>Raw</a>\n </li>\n";
},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
var stack1, helper, options, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing, buffer =
"<div class='heading'>\n <h2>\n <a href='#!/"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "' class=\"toggleEndpointList\" data-id=\""
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "\">"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "</a> ";
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));
if (!helpers.summary) { stack1 = helpers.blockHelperMissing.call(depth0,stack1,options)}
if (stack1 != null) { buffer += stack1; }
return buffer + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.summary : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "\n </h2>\n <ul class='options'>\n <li>\n <a href='#!/"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "' id='endpointListTogger_"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "' class=\"toggleEndpointList\" data-id=\""
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "\" data-sw-translate>Show/Hide</a>\n </li>\n <li>\n <a href='#' class=\"collapseResource\" data-id=\""
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "\" data-sw-translate>\n List Operations\n </a>\n </li>\n <li>\n <a href='#' class=\"expandResource\" data-id=\""
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "\" data-sw-translate>\n Expand Operations\n </a>\n </li>\n"
+ ((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 : "")
+ " </ul>\n</div>\n<ul class='endpoints' id='"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "_endpoint_list' style='display:none'>\n\n</ul>\n";
},"useData":true});
templates['response_content_type'] = template({"1":function(container,depth0,helpers,partials,data) {
var stack1;
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 : "");
},"2":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return " <option value=\""
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,depth0,{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "\">"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,depth0,{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "</option>\n";
},"4":function(container,depth0,helpers,partials,data) {
return " <option value=\"application/json\">application/json</option>\n";
},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
var stack1, helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
return "<label data-sw-translate for=\""
+ 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)))
+ "\">Response Content Type</label>\n<select name=\"responseContentType\" id=\""
+ 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)))
+ "\">\n"
+ ((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 : "")
+ "</select>\n";
},"useData":true});
templates['signature'] = template({"1":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {};
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 "
+ container.escapeExpression((helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(alias1,(depth0 != null ? depth0.signature : depth0),{"name":"sanitize","hash":{},"data":data}))
+ "\n </div>\n\n <div class=\"snippet\">\n"
+ ((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 : "")
+ ((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 : "")
+ " </div>\n</div>\n";
},"2":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {};
return " <div class=\"snippet_json\">\n <pre><code>"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(alias1,(depth0 != null ? depth0.sampleJSON : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "</code></pre>\n "
+ ((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 : "")
+ "\n </div>\n";
},"3":function(container,depth0,helpers,partials,data) {
return "<small class=\"notice\" data-sw-translate></small>";
},"5":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {};
return " <div class=\"snippet_xml\">\n <pre><code>"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(alias1,(depth0 != null ? depth0.sampleXML : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "</code></pre>\n "
+ ((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 : "")
+ "\n </div>\n";
},"7":function(container,depth0,helpers,partials,data) {
var stack1;
return " "
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.signature : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "\n";
},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
var stack1;
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 : "");
},"useData":true});
templates['status_code'] = template({"1":function(container,depth0,helpers,partials,data) {
var stack1, helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return " <tr>\n <td>"
+ container.escapeExpression(((helper = (helper = helpers.key || (data && data.key)) != null ? helper : alias2),(typeof helper === "function" ? helper.call(alias1,{"name":"key","hash":{},"data":data}) : helper)))
+ "</td>\n <td>"
+ ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+ "</td>\n <td>"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.type : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "</td>\n </tr>\n";
},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
return "<td width='15%' class='code'>"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.code : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "</td>\n<td class=\"markdown\">"
+ ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.message : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+ "</td>\n<td width='50%'><span class=\"model-signature\" /></td>\n<td class=\"headers\">\n <table>\n <tbody>\n"
+ ((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 : "")
+ " </tbody>\n </table>\n</td>";
},"useData":true});
})();}
/* jshint ignore:end */
'use strict';
$(function() {
// Helper function for vertically aligning DOM elements
// http://www.seodenver.com/simple-vertical-align-plugin-for-jquery/
$.fn.vAlign = function() {
return this.each(function(){
var ah = $(this).height();
var ph = $(this).parent().height();
var mh = (ph - ah) / 2;
$(this).css('margin-top', mh);
});
};
$.fn.stretchFormtasticInputWidthToParent = function() {
return this.each(function(){
var p_width = $(this).closest("form").innerWidth();
var p_padding = parseInt($(this).closest("form").css('padding-left') ,10) + parseInt($(this).closest('form').css('padding-right'), 10);
var this_padding = parseInt($(this).css('padding-left'), 10) + parseInt($(this).css('padding-right'), 10);
$(this).css('width', p_width - p_padding - this_padding);
});
};
$('form.formtastic li.string input, form.formtastic textarea').stretchFormtasticInputWidthToParent();
// Vertically center these paragraphs
// Parent may need a min-height for this to work..
$('ul.downplayed li div.content p').vAlign();
// When a sandbox form is submitted..
$("form.sandbox").submit(function(){
var error_free = true;
// Cycle through the forms required inputs
$(this).find("input.required").each(function() {
// Remove any existing error styles from the input
$(this).removeClass('error');
// Tack the error style on if the input is empty..
if ($(this).val() === '') {
$(this).addClass('error');
$(this).wiggle();
error_free = false;
}
});
return error_free;
});
});
function clippyCopiedCallback() {
$('#api_key_copied').fadeIn().delay(1000).fadeOut();
// var b = $("#clippy_tooltip_" + a);
// b.length != 0 && (b.attr("title", "copied!").trigger("tipsy.reload"), setTimeout(function() {
// b.attr("title", "copy to clipboard")
// },
// 500))
}
// Logging function that accounts for browsers that don't have window.console
function log(){
log.history = log.history || [];
log.history.push(arguments);
if(this.console){
console.log( Array.prototype.slice.call(arguments)[0] );
}
}
// Handle browsers that do console incorrectly (IE9 and below, see http://stackoverflow.com/a/5539378/7913)
if (Function.prototype.bind && console && typeof console.log === "object") {
[
"log","info","warn","error","assert","dir","clear","profile","profileEnd"
].forEach(function (method) {
console[method] = this.bind(console[method], console);
}, Function.prototype.call);
}
window.Docs = {
shebang: function() {
// If shebang has an operation nickname in it..
// e.g. /docs/#!/words/get_search
var fragments = $.param.fragment().split('/');
fragments.shift(); // get rid of the bang
switch (fragments.length) {
case 1:
if (fragments[0].length > 0) { // prevent matching "#/"
// Expand all operations for the resource and scroll to it
var dom_id = 'resource_' + fragments[0];
Docs.expandEndpointListForResource(fragments[0]);
$("#"+dom_id).slideto({highlight: false});
}
break;
case 2:
// Refer to the endpoint DOM element, e.g. #words_get_search
// Expand Resource
Docs.expandEndpointListForResource(fragments[0]);
$("#"+dom_id).slideto({highlight: false});
// Expand operation
var li_dom_id = fragments.join('_');
var li_content_dom_id = li_dom_id + "_content";
Docs.expandOperation($('#'+li_content_dom_id));
$('#'+li_dom_id).slideto({highlight: false});
break;
}
},
toggleEndpointListForResource: function(resource) {
var elem = $('li#resource_' + Docs.escapeResourceName(resource) + ' ul.endpoints');
if (elem.is(':visible')) {
$.bbq.pushState('#/', 2);
Docs.collapseEndpointListForResource(resource);
} else {
$.bbq.pushState('#/' + resource, 2);
Docs.expandEndpointListForResource(resource);
}
},
// Expand resource
expandEndpointListForResource: function(resource) {
var resource = Docs.escapeResourceName(resource);
if (resource == '') {
$('.resource ul.endpoints').slideDown();
return;
}
$('li#resource_' + resource).addClass('active');
var elem = $('li#resource_' + resource + ' ul.endpoints');
elem.slideDown();
},
// Collapse resource and mark as explicitly closed
collapseEndpointListForResource: function(resource) {
var resource = Docs.escapeResourceName(resource);
if (resource == '') {
$('.resource ul.endpoints').slideUp();
return;
}
$('li#resource_' + resource).removeClass('active');
var elem = $('li#resource_' + resource + ' ul.endpoints');
elem.slideUp();
},
expandOperationsForResource: function(resource) {
// Make sure the resource container is open..
Docs.expandEndpointListForResource(resource);
if (resource == '') {
$('.resource ul.endpoints li.operation div.content').slideDown();
return;
}
$('li#resource_' + Docs.escapeResourceName(resource) + ' li.operation div.content').each(function() {
Docs.expandOperation($(this));
});
},
collapseOperationsForResource: function(resource) {
// Make sure the resource container is open..
Docs.expandEndpointListForResource(resource);
if (resource == '') {
$('.resource ul.endpoints li.operation div.content').slideUp();
return;
}
$('li#resource_' + Docs.escapeResourceName(resource) + ' li.operation div.content').each(function() {
Docs.collapseOperation($(this));
});
},
escapeResourceName: function(resource) {
return resource.replace(/[!"#$%&'()*+,.\/:;<=>?@\[\\\]\^`{|}~]/g, "\\$&");
},
expandOperation: function(elem) {
elem.slideDown();
},
collapseOperation: function(elem) {
elem.slideUp();
}
};
/*!
* https://github.com/es-shims/es5-shim
* @license es5-shim Copyright 2009-2015 by contributors, MIT License
* see https://github.com/es-shims/es5-shim/blob/master/LICENSE
*/
// vim: ts=4 sts=4 sw=4 expandtab
// Add semicolon to prevent IIFE from being passed as argument to concatenated code.
;
// UMD (Universal Module Definition)
// see https://github.com/umdjs/umd/blob/master/templates/returnExports.js
(function (root, factory) {
'use strict';
/* global define, exports, module */
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(factory);
} else if (typeof exports === 'object') {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like enviroments that support module.exports,
// like Node.
module.exports = factory();
} else {
// Browser globals (root is window)
root.returnExports = factory();
}
}(this, function () {
/**
* Brings an environment as close to ECMAScript 5 compliance
* as is possible with the facilities of erstwhile engines.
*
* Annotated ES5: http://es5.github.com/ (specific links below)
* ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
* Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/
*/
// Shortcut to an often accessed properties, in order to avoid multiple
// dereference that costs universally. This also holds a reference to known-good
// functions.
var $Array = Array;
var ArrayPrototype = $Array.prototype;
var $Object = Object;
var ObjectPrototype = $Object.prototype;
var $Function = Function;
var FunctionPrototype = $Function.prototype;
var $String = String;
var StringPrototype = $String.prototype;
var $Number = Number;
var NumberPrototype = $Number.prototype;
var array_slice = ArrayPrototype.slice;
var array_splice = ArrayPrototype.splice;
var array_push = ArrayPrototype.push;
var array_unshift = ArrayPrototype.unshift;
var array_concat = ArrayPrototype.concat;
var array_join = ArrayPrototype.join;
var call = FunctionPrototype.call;
var apply = FunctionPrototype.apply;
var max = Math.max;
var min = Math.min;
// Having a toString local variable name breaks in Opera so use to_string.
var to_string = ObjectPrototype.toString;
/* global Symbol */
/* eslint-disable one-var-declaration-per-line, no-redeclare, max-statements-per-line */
var hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';
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; };
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; };
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; };
/* eslint-enable one-var-declaration-per-line, no-redeclare, max-statements-per-line */
/* inlined from http://npmjs.com/define-properties */
var supportsDescriptors = $Object.defineProperty && (function () {
try {
var obj = {};
$Object.defineProperty(obj, 'x', { enumerable: false, value: obj });
for (var _ in obj) { // jscs:ignore disallowUnusedVariables
return false;
}
return obj.x === obj;
} catch (e) { /* this is ES3 */
return false;
}
}());
var defineProperties = (function (has) {
// Define configurable, writable, and non-enumerable props
// if they don't exist.
var defineProperty;
if (supportsDescriptors) {
defineProperty = function (object, name, method, forceAssign) {
if (!forceAssign && (name in object)) {
return;
}
$Object.defineProperty(object, name, {
configurable: true,
enumerable: false,
writable: true,
value: method
});
};
} else {
defineProperty = function (object, name, method, forceAssign) {
if (!forceAssign && (name in object)) {
return;
}
object[name] = method;
};
}
return function defineProperties(object, map, forceAssign) {
for (var name in map) {
if (has.call(map, name)) {
defineProperty(object, name, map[name], forceAssign);
}
}
};
}(ObjectPrototype.hasOwnProperty));
//
// Util
// ======
//
/* replaceable with https://npmjs.com/package/es-abstract /helpers/isPrimitive */
var isPrimitive = function isPrimitive(input) {
var type = typeof input;
return input === null || (type !== 'object' && type !== 'function');
};
var isActualNaN = $Number.isNaN || function isActualNaN(x) {
return x !== x;
};
var ES = {
// ES5 9.4
// http://es5.github.com/#x9.4
// http://jsperf.com/to-integer
/* replaceable with https://npmjs.com/package/es-abstract ES5.ToInteger */
ToInteger: function ToInteger(num) {
var n = +num;
if (isActualNaN(n)) {
n = 0;
} else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {
n = (n > 0 || -1) * Math.floor(Math.abs(n));
}
return n;
},
/* replaceable with https://npmjs.com/package/es-abstract ES5.ToPrimitive */
ToPrimitive: function ToPrimitive(input) {
var val, valueOf, toStr;
if (isPrimitive(input)) {
return input;
}
valueOf = input.valueOf;
if (isCallable(valueOf)) {
val = valueOf.call(input);
if (isPrimitive(val)) {
return val;
}
}
toStr = input.toString;
if (isCallable(toStr)) {
val = toStr.call(input);
if (isPrimitive(val)) {
return val;
}
}
throw new TypeError();
},
// ES5 9.9
// http://es5.github.com/#x9.9
/* replaceable with https://npmjs.com/package/es-abstract ES5.ToObject */
ToObject: function (o) {
if (o == null) { // this matches both null and undefined
throw new TypeError("can't convert " + o + ' to object');
}
return $Object(o);
},
/* replaceable with https://npmjs.com/package/es-abstract ES5.ToUint32 */
ToUint32: function ToUint32(x) {
return x >>> 0;
}
};
//
// Function
// ========
//
// ES-5 15.3.4.5
// http://es5.github.com/#x15.3.4.5
var Empty = function Empty() {};
defineProperties(FunctionPrototype, {
bind: function bind(that) { // .length is 1
// 1. Let Target be the this value.
var target = this;
// 2. If IsCallable(Target) is false, throw a TypeError exception.
if (!isCallable(target)) {
throw new TypeError('Function.prototype.bind called on incompatible ' + target);
}
// 3. Let A be a new (possibly empty) internal list of all of the
// argument values provided after thisArg (arg1, arg2 etc), in order.
// XXX slicedArgs will stand in for "A" if used
var args = array_slice.call(arguments, 1); // for normal call
// 4. Let F be a new native ECMAScript object.
// 11. Set the [[Prototype]] internal property of F to the standard
// built-in Function prototype object as specified in 15.3.3.1.
// 12. Set the [[Call]] internal property of F as described in
// 15.3.4.5.1.
// 13. Set the [[Construct]] internal property of F as described in
// 15.3.4.5.2.
// 14. Set the [[HasInstance]] internal property of F as described in
// 15.3.4.5.3.
var bound;
var binder = function () {
if (this instanceof bound) {
// 15.3.4.5.2 [[Construct]]
// When the [[Construct]] internal method of a function object,
// F that was created using the bind function is called with a
// list of arguments ExtraArgs, the following steps are taken:
// 1. Let target be the value of F's [[TargetFunction]]
// internal property.
// 2. If target has no [[Construct]] internal method, a
// TypeError exception is thrown.
// 3. Let boundArgs be the value of F's [[BoundArgs]] internal
// property.
// 4. Let args be a new list containing the same values as the
// list boundArgs in the same order followed by the same
// values as the list ExtraArgs in the same order.
// 5. Return the result of calling the [[Construct]] internal
// method of target providing args as the arguments.
var result = apply.call(
target,
this,
array_concat.call(args, array_slice.call(arguments))
);
if ($Object(result) === result) {
return result;
}
return this;
} else {
// 15.3.4.5.1 [[Call]]
// When the [[Call]] internal method of a function object, F,
// which was created using the bind function is called with a
// this value and a list of arguments ExtraArgs, the following
// steps are taken:
// 1. Let boundArgs be the value of F's [[BoundArgs]] internal
// property.
// 2. Let boundThis be the value of F's [[BoundThis]] internal
// property.
// 3. Let target be the value of F's [[TargetFunction]] internal
// property.
// 4. Let args be a new list containing the same values as the
// list boundArgs in the same order followed by the same
// values as the list ExtraArgs in the same order.
// 5. Return the result of calling the [[Call]] internal method
// of target providing boundThis as the this value and
// providing args as the arguments.
// equiv: target.call(this, ...boundArgs, ...args)
return apply.call(
target,
that,
array_concat.call(args, array_slice.call(arguments))
);
}
};
// 15. If the [[Class]] internal property of Target is "Function", then
// a. Let L be the length property of Target minus the length of A.
// b. Set the length own property of F to either 0 or L, whichever is
// larger.
// 16. Else set the length own property of F to 0.
var boundLength = max(0, target.length - args.length);
// 17. Set the attributes of the length own property of F to the values
// specified in 15.3.5.1.
var boundArgs = [];
for (var i = 0; i < boundLength; i++) {
array_push.call(boundArgs, '$' + i);
}
// XXX Build a dynamic function with desired amount of arguments is the only
// way to set the length property of a function.
// In environments where Content Security Policies enabled (Chrome extensions,
// for ex.) all use of eval or Function costructor throws an exception.
// However in all of these environments Function.prototype.bind exists
// and so this code will never be executed.
bound = $Function('binder', 'return function (' + array_join.call(boundArgs, ',') + '){ return binder.apply(this, arguments); }')(binder);
if (target.prototype) {
Empty.prototype = target.prototype;
bound.prototype = new Empty();
// Clean up dangling references.
Empty.prototype = null;
}
// TODO
// 18. Set the [[Extensible]] internal property of F to true.
// TODO
// 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
// 20. Call the [[DefineOwnProperty]] internal method of F with
// arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]:
// thrower, [[Enumerable]]: false, [[Configurable]]: false}, and
// false.
// 21. Call the [[DefineOwnProperty]] internal method of F with
// arguments "arguments", PropertyDescriptor {[[Get]]: thrower,
// [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},
// and false.
// TODO
// NOTE Function objects created using Function.prototype.bind do not
// have a prototype property or the [[Code]], [[FormalParameters]], and
// [[Scope]] internal properties.
// XXX can't delete prototype in pure-js.
// 22. Return F.
return bound;
}
});
// _Please note: Shortcuts are defined after `Function.prototype.bind` as we
// use it in defining shortcuts.
var owns = call.bind(ObjectPrototype.hasOwnProperty);
var toStr = call.bind(ObjectPrototype.toString);
var arraySlice = call.bind(array_slice);
var arraySliceApply = apply.bind(array_slice);
var strSlice = call.bind(StringPrototype.slice);
var strSplit = call.bind(StringPrototype.split);
var strIndexOf = call.bind(StringPrototype.indexOf);
var pushCall = call.bind(array_push);
var isEnum = call.bind(ObjectPrototype.propertyIsEnumerable);
var arraySort = call.bind(ArrayPrototype.sort);
//
// Array
// =====
//
var isArray = $Array.isArray || function isArray(obj) {
return toStr(obj) === '[object Array]';
};
// ES5 15.4.4.12
// http://es5.github.com/#x15.4.4.13
// Return len+argCount.
// [bugfix, ielt8]
// IE < 8 bug: [].unshift(0) === undefined but should be "1"
var hasUnshiftReturnValueBug = [].unshift(0) !== 1;
defineProperties(ArrayPrototype, {
unshift: function () {
array_unshift.apply(this, arguments);
return this.length;
}
}, hasUnshiftReturnValueBug);
// ES5 15.4.3.2
// http://es5.github.com/#x15.4.3.2
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
defineProperties($Array, { isArray: isArray });
// The IsCallable() check in the Array functions
// has been replaced with a strict check on the
// internal class of the object to trap cases where
// the provided function was actually a regular
// expression literal, which in V8 and
// JavaScriptCore is a typeof "function". Only in
// V8 are regular expression literals permitted as
// reduce parameters, so it is desirable in the
// general case for the shim to match the more
// strict and common behavior of rejecting regular
// expressions.
// ES5 15.4.4.18
// http://es5.github.com/#x15.4.4.18
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach
// Check failure of by-index access of string characters (IE < 9)
// and failure of `0 in boxedString` (Rhino)
var boxedString = $Object('a');
var splitString = boxedString[0] !== 'a' || !(0 in boxedString);
var properlyBoxesContext = function properlyBoxed(method) {
// Check node 0.6.21 bug where third parameter is not boxed
var properlyBoxesNonStrict = true;
var properlyBoxesStrict = true;
var threwException = false;
if (method) {
try {
method.call('foo', function (_, __, context) {
if (typeof context !== 'object') {
properlyBoxesNonStrict = false;
}
});
method.call([1], function () {
'use strict';
properlyBoxesStrict = typeof this === 'string';
}, 'x');
} catch (e) {
threwException = true;
}
}
return !!method && !threwException && properlyBoxesNonStrict && properlyBoxesStrict;
};
defineProperties(ArrayPrototype, {
forEach: function forEach(callbackfn/*, thisArg*/) {
var object = ES.ToObject(this);
var self = splitString && isString(this) ? strSplit(this, '') : object;
var i = -1;
var length = ES.ToUint32(self.length);
var T;
if (arguments.length > 1) {
T = arguments[1];
}
// If no callback function or if callback is not a callable function
if (!isCallable(callbackfn)) {
throw new TypeError('Array.prototype.forEach callback must be a function');
}
while (++i < length) {
if (i in self) {
// Invoke the callback function with call, passing arguments:
// context, property value, property key, thisArg object
if (typeof T === 'undefined') {
callbackfn(self[i], i, object);
} else {
callbackfn.call(T, self[i], i, object);
}
}
}
}
}, !properlyBoxesContext(ArrayPrototype.forEach));
// ES5 15.4.4.19
// http://es5.github.com/#x15.4.4.19
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
defineProperties(ArrayPrototype, {
map: function map(callbackfn/*, thisArg*/) {
var object = ES.ToObject(this);
var self = splitString && isString(this) ? strSplit(this, '') : object;
var length = ES.ToUint32(self.length);
var result = $Array(length);
var T;
if (arguments.length > 1) {
T = arguments[1];
}
// If no callback function or if callback is not a callable function
if (!isCallable(callbackfn)) {
throw new TypeError('Array.prototype.map callback must be a function');
}
for (var i = 0; i < length; i++) {
if (i in self) {
if (typeof T === 'undefined') {
result[i] = callbackfn(self[i], i, object);
} else {
result[i] = callbackfn.call(T, self[i], i, object);
}
}
}
return result;
}
}, !properlyBoxesContext(ArrayPrototype.map));
// ES5 15.4.4.20
// http://es5.github.com/#x15.4.4.20
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
defineProperties(ArrayPrototype, {
filter: function filter(callbackfn/*, thisArg*/) {
var object = ES.ToObject(this);
var self = splitString && isString(this) ? strSplit(this, '') : object;
var length = ES.ToUint32(self.length);
var result = [];
var value;
var T;
if (arguments.length > 1) {
T = arguments[1];
}
// If no callback function or if callback is not a callable function
if (!isCallable(callbackfn)) {
throw new TypeError('Array.prototype.filter callback must be a function');
}
for (var i = 0; i < length; i++) {
if (i in self) {
value = self[i];
if (typeof T === 'undefined' ? callbackfn(value, i, object) : callbackfn.call(T, value, i, object)) {
pushCall(result, value);
}
}
}
return result;
}
}, !properlyBoxesContext(ArrayPrototype.filter));
// ES5 15.4.4.16
// http://es5.github.com/#x15.4.4.16
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
defineProperties(ArrayPrototype, {
every: function every(callbackfn/*, thisArg*/) {
var object = ES.ToObject(this);
var self = splitString && isString(this) ? strSplit(this, '') : object;
var length = ES.ToUint32(self.length);
var T;
if (arguments.length > 1) {
T = arguments[1];
}
// If no callback function or if callback is not a callable function
if (!isCallable(callbackfn)) {
throw new TypeError('Array.prototype.every callback must be a function');
}
for (var i = 0; i < length; i++) {
if (i in self && !(typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
return false;
}
}
return true;
}
}, !properlyBoxesContext(ArrayPrototype.every));
// ES5 15.4.4.17
// http://es5.github.com/#x15.4.4.17
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
defineProperties(ArrayPrototype, {
some: function some(callbackfn/*, thisArg */) {
var object = ES.ToObject(this);
var self = splitString && isString(this) ? strSplit(this, '') : object;
var length = ES.ToUint32(self.length);
var T;
if (arguments.length > 1) {
T = arguments[1];
}
// If no callback function or if callback is not a callable function
if (!isCallable(callbackfn)) {
throw new TypeError('Array.prototype.some callback must be a function');
}
for (var i = 0; i < length; i++) {
if (i in self && (typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
return true;
}
}
return false;
}
}, !properlyBoxesContext(ArrayPrototype.some));
// ES5 15.4.4.21
// http://es5.github.com/#x15.4.4.21
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
var reduceCoercesToObject = false;
if (ArrayPrototype.reduce) {
reduceCoercesToObject = typeof ArrayPrototype.reduce.call('es5', function (_, __, ___, list) {
return list;
}) === 'object';
}
defineProperties(ArrayPrototype, {
reduce: function reduce(callbackfn/*, initialValue*/) {
var object = ES.ToObject(this);
var self = splitString && isString(this) ? strSplit(this, '') : object;
var length = ES.ToUint32(self.length);
// If no callback function or if callback is not a callable function
if (!isCallable(callbackfn)) {
throw new TypeError('Array.prototype.reduce callback must be a function');
}
// no value to return if no initial value and an empty array
if (length === 0 && arguments.length === 1) {
throw new TypeError('reduce of empty array with no initial value');
}
var i = 0;
var result;
if (arguments.length >= 2) {
result = arguments[1];
} else {
do {
if (i in self) {
result = self[i++];
break;
}
// if array contains no values, no initial value to return
if (++i >= length) {
throw new TypeError('reduce of empty array with no initial value');
}
} while (true);
}
for (; i < length; i++) {
if (i in self) {
result = callbackfn(result, self[i], i, object);
}
}
return result;
}
}, !reduceCoercesToObject);
// ES5 15.4.4.22
// http://es5.github.com/#x15.4.4.22
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
var reduceRightCoercesToObject = false;
if (ArrayPrototype.reduceRight) {
reduceRightCoercesToObject = typeof ArrayPrototype.reduceRight.call('es5', function (_, __, ___, list) {
return list;
}) === 'object';
}
defineProperties(ArrayPrototype, {
reduceRight: function reduceRight(callbackfn/*, initial*/) {
var object = ES.ToObject(this);
var self = splitString && isString(this) ? strSplit(this, '') : object;
var length = ES.ToUint32(self.length);
// If no callback function or if callback is not a callable function
if (!isCallable(callbackfn)) {
throw new TypeError('Array.prototype.reduceRight callback must be a function');
}
// no value to return if no initial value, empty array
if (length === 0 && arguments.length === 1) {
throw new TypeError('reduceRight of empty array with no initial value');
}
var result;
var i = length - 1;
if (arguments.length >= 2) {
result = arguments[1];
} else {
do {
if (i in self) {
result = self[i--];
break;
}
// if array contains no values, no initial value to return
if (--i < 0) {
throw new TypeError('reduceRight of empty array with no initial value');
}
} while (true);
}
if (i < 0) {
return result;
}
do {
if (i in self) {
result = callbackfn(result, self[i], i, object);
}
} while (i--);
return result;
}
}, !reduceRightCoercesToObject);
// ES5 15.4.4.14
// http://es5.github.com/#x15.4.4.14
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
var hasFirefox2IndexOfBug = ArrayPrototype.indexOf && [0, 1].indexOf(1, 2) !== -1;
defineProperties(ArrayPrototype, {
indexOf: function indexOf(searchElement/*, fromIndex */) {
var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this);
var length = ES.ToUint32(self.length);
if (length === 0) {
return -1;
}
var i = 0;
if (arguments.length > 1) {
i = ES.ToInteger(arguments[1]);
}
// handle negative indices
i = i >= 0 ? i : max(0, length + i);
for (; i < length; i++) {
if (i in self && self[i] === searchElement) {
return i;
}
}
return -1;
}
}, hasFirefox2IndexOfBug);
// ES5 15.4.4.15
// http://es5.github.com/#x15.4.4.15
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
var hasFirefox2LastIndexOfBug = ArrayPrototype.lastIndexOf && [0, 1].lastIndexOf(0, -3) !== -1;
defineProperties(ArrayPrototype, {
lastIndexOf: function lastIndexOf(searchElement/*, fromIndex */) {
var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this);
var length = ES.ToUint32(self.length);
if (length === 0) {
return -1;
}
var i = length - 1;
if (arguments.length > 1) {
i = min(i, ES.ToInteger(arguments[1]));
}
// handle negative indices
i = i >= 0 ? i : length - Math.abs(i);
for (; i >= 0; i--) {
if (i in self && searchElement === self[i]) {
return i;
}
}
return -1;
}
}, hasFirefox2LastIndexOfBug);
// ES5 15.4.4.12
// http://es5.github.com/#x15.4.4.12
var spliceNoopReturnsEmptyArray = (function () {
var a = [1, 2];
var result = a.splice();
return a.length === 2 && isArray(result) && result.length === 0;
}());
defineProperties(ArrayPrototype, {
// Safari 5.0 bug where .splice() returns undefined
splice: function splice(start, deleteCount) {
if (arguments.length === 0) {
return [];
} else {
return array_splice.apply(this, arguments);
}
}
}, !spliceNoopReturnsEmptyArray);
var spliceWorksWithEmptyObject = (function () {
var obj = {};
ArrayPrototype.splice.call(obj, 0, 0, 1);
return obj.length === 1;
}());
defineProperties(ArrayPrototype, {
splice: function splice(start, deleteCount) {
if (arguments.length === 0) {
return [];
}
var args = arguments;
this.length = max(ES.ToInteger(this.length), 0);
if (arguments.length > 0 && typeof deleteCount !== 'number') {
args = arraySlice(arguments);
if (args.length < 2) {
pushCall(args, this.length - start);
} else {
args[1] = ES.ToInteger(deleteCount);
}
}
return array_splice.apply(this, args);
}
}, !spliceWorksWithEmptyObject);
var spliceWorksWithLargeSparseArrays = (function () {
// Per https://github.com/es-shims/es5-shim/issues/295
// Safari 7/8 breaks with sparse arrays of size 1e5 or greater
var arr = new $Array(1e5);
// note: the index MUST be 8 or larger or the test will false pass
arr[8] = 'x';
arr.splice(1, 1);
// note: this test must be defined *after* the indexOf shim
// per https://github.com/es-shims/es5-shim/issues/313
return arr.indexOf('x') === 7;
}());
var spliceWorksWithSmallSparseArrays = (function () {
// Per https://github.com/es-shims/es5-shim/issues/295
// Opera 12.15 breaks on this, no idea why.
var n = 256;
var arr = [];
arr[n] = 'a';
arr.splice(n + 1, 0, 'b');
return arr[n] === 'a';
}());
defineProperties(ArrayPrototype, {
splice: function splice(start, deleteCount) {
var O = ES.ToObject(this);
var A = [];
var len = ES.ToUint32(O.length);
var relativeStart = ES.ToInteger(start);
var actualStart = relativeStart < 0 ? max((len + relativeStart), 0) : min(relativeStart, len);
var actualDeleteCount = min(max(ES.ToInteger(deleteCount), 0), len - actualStart);
var k = 0;
var from;
while (k < actualDeleteCount) {
from = $String(actualStart + k);
if (owns(O, from)) {
A[k] = O[from];
}
k += 1;
}
var items = arraySlice(arguments, 2);
var itemCount = items.length;
var to;
if (itemCount < actualDeleteCount) {
k = actualStart;
var maxK = len - actualDeleteCount;
while (k < maxK) {
from = $String(k + actualDeleteCount);
to = $String(k + itemCount);
if (owns(O, from)) {
O[to] = O[from];
} else {
delete O[to];
}
k += 1;
}
k = len;
var minK = len - actualDeleteCount + itemCount;
while (k > minK) {
delete O[k - 1];
k -= 1;
}
} else if (itemCount > actualDeleteCount) {
k = len - actualDeleteCount;
while (k > actualStart) {
from = $String(k + actualDeleteCount - 1);
to = $String(k + itemCount - 1);
if (owns(O, from)) {
O[to] = O[from];
} else {
delete O[to];
}
k -= 1;
}
}
k = actualStart;
for (var i = 0; i < items.length; ++i) {
O[k] = items[i];
k += 1;
}
O.length = len - actualDeleteCount + itemCount;
return A;
}
}, !spliceWorksWithLargeSparseArrays || !spliceWorksWithSmallSparseArrays);
var originalJoin = ArrayPrototype.join;
var hasStringJoinBug;
try {
hasStringJoinBug = Array.prototype.join.call('123', ',') !== '1,2,3';
} catch (e) {
hasStringJoinBug = true;
}
if (hasStringJoinBug) {
defineProperties(ArrayPrototype, {
join: function join(separator) {
var sep = typeof separator === 'undefined' ? ',' : separator;
return originalJoin.call(isString(this) ? strSplit(this, '') : this, sep);
}
}, hasStringJoinBug);
}
var hasJoinUndefinedBug = [1, 2].join(undefined) !== '1,2';
if (hasJoinUndefinedBug) {
defineProperties(ArrayPrototype, {
join: function join(separator) {
var sep = typeof separator === 'undefined' ? ',' : separator;
return originalJoin.call(this, sep);
}
}, hasJoinUndefinedBug);
}
var pushShim = function push(item) {
var O = ES.ToObject(this);
var n = ES.ToUint32(O.length);
var i = 0;
while (i < arguments.length) {
O[n + i] = arguments[i];
i += 1;
}
O.length = n + i;
return n + i;
};
var pushIsNotGeneric = (function () {
var obj = {};
var result = Array.prototype.push.call(obj, undefined);
return result !== 1 || obj.length !== 1 || typeof obj[0] !== 'undefined' || !owns(obj, 0);
}());
defineProperties(ArrayPrototype, {
push: function push(item) {
if (isArray(this)) {
return array_push.apply(this, arguments);
}
return pushShim.apply(this, arguments);
}
}, pushIsNotGeneric);
// This fixes a very weird bug in Opera 10.6 when pushing `undefined
var pushUndefinedIsWeird = (function () {
var arr = [];
var result = arr.push(undefined);
return result !== 1 || arr.length !== 1 || typeof arr[0] !== 'undefined' || !owns(arr, 0);
}());
defineProperties(ArrayPrototype, { push: pushShim }, pushUndefinedIsWeird);
// ES5 15.2.3.14
// http://es5.github.io/#x15.4.4.10
// Fix boxed string bug
defineProperties(ArrayPrototype, {
slice: function (start, end) {
var arr = isString(this) ? strSplit(this, '') : this;
return arraySliceApply(arr, arguments);
}
}, splitString);
var sortIgnoresNonFunctions = (function () {
try {
[1, 2].sort(null);
[1, 2].sort({});
return true;
} catch (e) {}
return false;
}());
var sortThrowsOnRegex = (function () {
// this is a problem in Firefox 4, in which `typeof /a/ === 'function'`
try {
[1, 2].sort(/a/);
return false;
} catch (e) {}
return true;
}());
var sortIgnoresUndefined = (function () {
// applies in IE 8, for one.
try {
[1, 2].sort(undefined);
return true;
} catch (e) {}
return false;
}());
defineProperties(ArrayPrototype, {
sort: function sort(compareFn) {
if (typeof compareFn === 'undefined') {
return arraySort(this);
}
if (!isCallable(compareFn)) {
throw new TypeError('Array.prototype.sort callback must be a function');
}
return arraySort(this, compareFn);
}
}, sortIgnoresNonFunctions || !sortIgnoresUndefined || !sortThrowsOnRegex);
//
// Object
// ======
//
// ES5 15.2.3.14
// http://es5.github.com/#x15.2.3.14
// http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
var hasDontEnumBug = !isEnum({ 'toString': null }, 'toString');
var hasProtoEnumBug = isEnum(function () {}, 'prototype');
var hasStringEnumBug = !owns('x', '0');
var equalsConstructorPrototype = function (o) {
var ctor = o.constructor;
return ctor && ctor.prototype === o;
};
var blacklistedKeys = {
$window: true,
$console: true,
$parent: true,
$self: true,
$frame: true,
$frames: true,
$frameElement: true,
$webkitIndexedDB: true,
$webkitStorageInfo: true,
$external: true
};
var hasAutomationEqualityBug = (function () {
/* globals window */
if (typeof window === 'undefined') {
return false;
}
for (var k in window) {
try {
if (!blacklistedKeys['$' + k] && owns(window, k) && window[k] !== null && typeof window[k] === 'object') {
equalsConstructorPrototype(window[k]);
}
} catch (e) {
return true;
}
}
return false;
}());
var equalsConstructorPrototypeIfNotBuggy = function (object) {
if (typeof window === 'undefined' || !hasAutomationEqualityBug) {
return equalsConstructorPrototype(object);
}
try {
return equalsConstructorPrototype(object);
} catch (e) {
return false;
}
};
var dontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
];
var dontEnumsLength = dontEnums.length;
// taken directly from https://github.com/ljharb/is-arguments/blob/master/index.js
// can be replaced with require('is-arguments') if we ever use a build process instead
var isStandardArguments = function isArguments(value) {
return toStr(value) === '[object Arguments]';
};
var isLegacyArguments = function isArguments(value) {
return value !== null &&
typeof value === 'object' &&
typeof value.length === 'number' &&
value.length >= 0 &&
!isArray(value) &&
isCallable(value.callee);
};
var isArguments = isStandardArguments(arguments) ? isStandardArguments : isLegacyArguments;
defineProperties($Object, {
keys: function keys(object) {
var isFn = isCallable(object);
var isArgs = isArguments(object);
var isObject = object !== null && typeof object === 'object';
var isStr = isObject && isString(object);
if (!isObject && !isFn && !isArgs) {
throw new TypeError('Object.keys called on a non-object');
}
var theKeys = [];
var skipProto = hasProtoEnumBug && isFn;
if ((isStr && hasStringEnumBug) || isArgs) {
for (var i = 0; i < object.length; ++i) {
pushCall(theKeys, $String(i));
}
}
if (!isArgs) {
for (var name in object) {
if (!(skipProto && name === 'prototype') && owns(object, name)) {
pushCall(theKeys, $String(name));
}
}
}
if (hasDontEnumBug) {
var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);
for (var j = 0; j < dontEnumsLength; j++) {
var dontEnum = dontEnums[j];
if (!(skipConstructor && dontEnum === 'constructor') && owns(object, dontEnum)) {
pushCall(theKeys, dontEnum);
}
}
}
return theKeys;
}
});
var keysWorksWithArguments = $Object.keys && (function () {
// Safari 5.0 bug
return $Object.keys(arguments).length === 2;
}(1, 2));
var keysHasArgumentsLengthBug = $Object.keys && (function () {
var argKeys = $Object.keys(arguments);
return arguments.length !== 1 || argKeys.length !== 1 || argKeys[0] !== 1;
}(1));
var originalKeys = $Object.keys;
defineProperties($Object, {
keys: function keys(object) {
if (isArguments(object)) {
return originalKeys(arraySlice(object));
} else {
return originalKeys(object);
}
}
}, !keysWorksWithArguments || keysHasArgumentsLengthBug);
//
// Date
// ====
//
var hasNegativeMonthYearBug = new Date(-3509827329600292).getUTCMonth() !== 0;
var aNegativeTestDate = new Date(-1509842289600292);
var aPositiveTestDate = new Date(1449662400000);
var hasToUTCStringFormatBug = aNegativeTestDate.toUTCString() !== 'Mon, 01 Jan -45875 11:59:59 GMT';
var hasToDateStringFormatBug;
var hasToStringFormatBug;
var timeZoneOffset = aNegativeTestDate.getTimezoneOffset();
if (timeZoneOffset < -720) {
hasToDateStringFormatBug = aNegativeTestDate.toDateString() !== 'Tue Jan 02 -45875';
hasToStringFormatBug = !(/^Thu Dec 10 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/).test(aPositiveTestDate.toString());
} else {
hasToDateStringFormatBug = aNegativeTestDate.toDateString() !== 'Mon Jan 01 -45875';
hasToStringFormatBug = !(/^Wed Dec 09 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/).test(aPositiveTestDate.toString());
}
var originalGetFullYear = call.bind(Date.prototype.getFullYear);
var originalGetMonth = call.bind(Date.prototype.getMonth);
var originalGetDate = call.bind(Date.prototype.getDate);
var originalGetUTCFullYear = call.bind(Date.prototype.getUTCFullYear);
var originalGetUTCMonth = call.bind(Date.prototype.getUTCMonth);
var originalGetUTCDate = call.bind(Date.prototype.getUTCDate);
var originalGetUTCDay = call.bind(Date.prototype.getUTCDay);
var originalGetUTCHours = call.bind(Date.prototype.getUTCHours);
var originalGetUTCMinutes = call.bind(Date.prototype.getUTCMinutes);
var originalGetUTCSeconds = call.bind(Date.prototype.getUTCSeconds);
var originalGetUTCMilliseconds = call.bind(Date.prototype.getUTCMilliseconds);
var dayName = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
var monthName = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
var daysInMonth = function daysInMonth(month, year) {
return originalGetDate(new Date(year, month, 0));
};
defineProperties(Date.prototype, {
getFullYear: function getFullYear() {
if (!this || !(this instanceof Date)) {
throw new TypeError('this is not a Date object.');
}
var year = originalGetFullYear(this);
if (year < 0 && originalGetMonth(this) > 11) {
return year + 1;
}
return year;
},
getMonth: function getMonth() {
if (!this || !(this instanceof Date)) {
throw new TypeError('this is not a Date object.');
}
var year = originalGetFullYear(this);
var month = originalGetMonth(this);
if (year < 0 && month > 11) {
return 0;
}
return month;
},
getDate: function getDate() {
if (!this || !(this instanceof Date)) {
throw new TypeError('this is not a Date object.');
}
var year = originalGetFullYear(this);
var month = originalGetMonth(this);
var date = originalGetDate(this);
if (year < 0 && month > 11) {
if (month === 12) {
return date;
}
var days = daysInMonth(0, year + 1);
return (days - date) + 1;
}
return date;
},
getUTCFullYear: function getUTCFullYear() {
if (!this || !(this instanceof Date)) {
throw new TypeError('this is not a Date object.');
}
var year = originalGetUTCFullYear(this);
if (year < 0 && originalGetUTCMonth(this) > 11) {
return year + 1;
}
return year;
},
getUTCMonth: function getUTCMonth() {
if (!this || !(this instanceof Date)) {
throw new TypeError('this is not a Date object.');
}
var year = originalGetUTCFullYear(this);
var month = originalGetUTCMonth(this);
if (year < 0 && month > 11) {
return 0;
}
return month;
},
getUTCDate: function getUTCDate() {
if (!this || !(this instanceof Date)) {
throw new TypeError('this is not a Date object.');
}
var year = originalGetUTCFullYear(this);
var month = originalGetUTCMonth(this);
var date = originalGetUTCDate(this);
if (year < 0 && month > 11) {
if (month === 12) {
return date;
}
var days = daysInMonth(0, year + 1);
return (days - date) + 1;
}
return date;
}
}, hasNegativeMonthYearBug);
defineProperties(Date.prototype, {
toUTCString: function toUTCString() {
if (!this || !(this instanceof Date)) {
throw new TypeError('this is not a Date object.');
}
var day = originalGetUTCDay(this);
var date = originalGetUTCDate(this);
var month = originalGetUTCMonth(this);
var year = originalGetUTCFullYear(this);
var hour = originalGetUTCHours(this);
var minute = originalGetUTCMinutes(this);
var second = originalGetUTCSeconds(this);
return dayName[day] + ', ' +
(date < 10 ? '0' + date : date) + ' ' +
monthName[month] + ' ' +
year + ' ' +
(hour < 10 ? '0' + hour : hour) + ':' +
(minute < 10 ? '0' + minute : minute) + ':' +
(second < 10 ? '0' + second : second) + ' GMT';
}
}, hasNegativeMonthYearBug || hasToUTCStringFormatBug);
// Opera 12 has `,`
defineProperties(Date.prototype, {
toDateString: function toDateString() {
if (!this || !(this instanceof Date)) {
throw new TypeError('this is not a Date object.');
}
var day = this.getDay();
var date = this.getDate();
var month = this.getMonth();
var year = this.getFullYear();
return dayName[day] + ' ' +
monthName[month] + ' ' +
(date < 10 ? '0' + date : date) + ' ' +
year;
}
}, hasNegativeMonthYearBug || hasToDateStringFormatBug);
// can't use defineProperties here because of toString enumeration issue in IE <= 8
if (hasNegativeMonthYearBug || hasToStringFormatBug) {
Date.prototype.toString = function toString() {
if (!this || !(this instanceof Date)) {
throw new TypeError('this is not a Date object.');
}
var day = this.getDay();
var date = this.getDate();
var month = this.getMonth();
var year = this.getFullYear();
var hour = this.getHours();
var minute = this.getMinutes();
var second = this.getSeconds();
var timezoneOffset = this.getTimezoneOffset();
var hoursOffset = Math.floor(Math.abs(timezoneOffset) / 60);
var minutesOffset = Math.floor(Math.abs(timezoneOffset) % 60);
return dayName[day] + ' ' +
monthName[month] + ' ' +
(date < 10 ? '0' + date : date) + ' ' +
year + ' ' +
(hour < 10 ? '0' + hour : hour) + ':' +
(minute < 10 ? '0' + minute : minute) + ':' +
(second < 10 ? '0' + second : second) + ' GMT' +
(timezoneOffset > 0 ? '-' : '+') +
(hoursOffset < 10 ? '0' + hoursOffset : hoursOffset) +
(minutesOffset < 10 ? '0' + minutesOffset : minutesOffset);
};
if (supportsDescriptors) {
$Object.defineProperty(Date.prototype, 'toString', {
configurable: true,
enumerable: false,
writable: true
});
}
}
// ES5 15.9.5.43
// http://es5.github.com/#x15.9.5.43
// This function returns a String value represent the instance in time
// represented by this Date object. The format of the String is the Date Time
// string format defined in 15.9.1.15. All fields are present in the String.
// The time zone is always UTC, denoted by the suffix Z. If the time value of
// this object is not a finite Number a RangeError exception is thrown.
var negativeDate = -62198755200000;
var negativeYearString = '-000001';
var hasNegativeDateBug = Date.prototype.toISOString && new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1;
var hasSafari51DateBug = Date.prototype.toISOString && new Date(-1).toISOString() !== '1969-12-31T23:59:59.999Z';
var getTime = call.bind(Date.prototype.getTime);
defineProperties(Date.prototype, {
toISOString: function toISOString() {
if (!isFinite(this) || !isFinite(getTime(this))) {
// Adope Photoshop requires the second check.
throw new RangeError('Date.prototype.toISOString called on non-finite value.');
}
var year = originalGetUTCFullYear(this);
var month = originalGetUTCMonth(this);
// see https://github.com/es-shims/es5-shim/issues/111
year += Math.floor(month / 12);
month = (month % 12 + 12) % 12;
// the date time string format is specified in 15.9.1.15.
var result = [month + 1, originalGetUTCDate(this), originalGetUTCHours(this), originalGetUTCMinutes(this), originalGetUTCSeconds(this)];
year = (
(year < 0 ? '-' : (year > 9999 ? '+' : '')) +
strSlice('00000' + Math.abs(year), (0 <= year && year <= 9999) ? -4 : -6)
);
for (var i = 0; i < result.length; ++i) {
// pad months, days, hours, minutes, and seconds to have two digits.
result[i] = strSlice('00' + result[i], -2);
}
// pad milliseconds to have three digits.
return (
year + '-' + arraySlice(result, 0, 2).join('-') +
'T' + arraySlice(result, 2).join(':') + '.' +
strSlice('000' + originalGetUTCMilliseconds(this), -3) + 'Z'
);
}
}, hasNegativeDateBug || hasSafari51DateBug);
// ES5 15.9.5.44
// http://es5.github.com/#x15.9.5.44
// This function provides a String representation of a Date object for use by
// JSON.stringify (15.12.3).
var dateToJSONIsSupported = (function () {
try {
return Date.prototype.toJSON &&
new Date(NaN).toJSON() === null &&
new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 &&
Date.prototype.toJSON.call({ // generic
toISOString: function () { return true; }
});
} catch (e) {
return false;
}
}());
if (!dateToJSONIsSupported) {
Date.prototype.toJSON = function toJSON(key) {
// When the toJSON method is called with argument key, the following
// steps are taken:
// 1. Let O be the result of calling ToObject, giving it the this
// value as its argument.
// 2. Let tv be ES.ToPrimitive(O, hint Number).
var O = $Object(this);
var tv = ES.ToPrimitive(O);
// 3. If tv is a Number and is not finite, return null.
if (typeof tv === 'number' && !isFinite(tv)) {
return null;
}
// 4. Let toISO be the result of calling the [[Get]] internal method of
// O with argument "toISOString".
var toISO = O.toISOString;
// 5. If IsCallable(toISO) is false, throw a TypeError exception.
if (!isCallable(toISO)) {
throw new TypeError('toISOString property is not callable');
}
// 6. Return the result of calling the [[Call]] internal method of
// toISO with O as the this value and an empty argument list.
return toISO.call(O);
// NOTE 1 The argument is ignored.
// NOTE 2 The toJSON function is intentionally generic; it does not
// require that its this value be a Date object. Therefore, it can be
// transferred to other kinds of objects for use as a method. However,
// it does require that any such object have a toISOString method. An
// object is free to use the argument key to filter its
// stringification.
};
}
// ES5 15.9.4.2
// http://es5.github.com/#x15.9.4.2
// based on work shared by Daniel Friesen (dantman)
// http://gist.github.com/303249
var supportsExtendedYears = Date.parse('+033658-09-27T01:46:40.000Z') === 1e15;
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'));
var doesNotParseY2KNewYear = isNaN(Date.parse('2000-01-01T00:00:00.000Z'));
if (doesNotParseY2KNewYear || acceptsInvalidDates || !supportsExtendedYears) {
// XXX global assignment won't work in embeddings that use
// an alternate object for the context.
/* global Date: true */
/* eslint-disable no-undef */
var maxSafeUnsigned32Bit = Math.pow(2, 31) - 1;
var hasSafariSignedIntBug = isActualNaN(new Date(1970, 0, 1, 0, 0, 0, maxSafeUnsigned32Bit + 1).getTime());
/* eslint-disable no-implicit-globals */
Date = (function (NativeDate) {
/* eslint-enable no-implicit-globals */
/* eslint-enable no-undef */
// Date.length === 7
var DateShim = function Date(Y, M, D, h, m, s, ms) {
var length = arguments.length;
var date;
if (this instanceof NativeDate) {
var seconds = s;
var millis = ms;
if (hasSafariSignedIntBug && length >= 7 && ms > maxSafeUnsigned32Bit) {
// work around a Safari 8/9 bug where it treats the seconds as signed
var msToShift = Math.floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit;
var sToShift = Math.floor(msToShift / 1e3);
seconds += sToShift;
millis -= sToShift * 1e3;
}
date = length === 1 && $String(Y) === Y ? // isString(Y)
// We explicitly pass it through parse:
new NativeDate(DateShim.parse(Y)) :
// We have to manually make calls depending on argument
// length here
length >= 7 ? new NativeDate(Y, M, D, h, m, seconds, millis) :
length >= 6 ? new NativeDate(Y, M, D, h, m, seconds) :
length >= 5 ? new NativeDate(Y, M, D, h, m) :
length >= 4 ? new NativeDate(Y, M, D, h) :
length >= 3 ? new NativeDate(Y, M, D) :
length >= 2 ? new NativeDate(Y, M) :
length >= 1 ? new NativeDate(Y instanceof NativeDate ? +Y : Y) :
new NativeDate();
} else {
date = NativeDate.apply(this, arguments);
}
if (!isPrimitive(date)) {
// Prevent mixups with unfixed Date object
defineProperties(date, { constructor: DateShim }, true);
}
return date;
};
// 15.9.1.15 Date Time String Format.
var isoDateExpression = new RegExp('^' +
'(\\d{4}|[+-]\\d{6})' + // four-digit year capture or sign +
// 6-digit extended year
'(?:-(\\d{2})' + // optional month capture
'(?:-(\\d{2})' + // optional day capture
'(?:' + // capture hours:minutes:seconds.milliseconds
'T(\\d{2})' + // hours capture
':(\\d{2})' + // minutes capture
'(?:' + // optional :seconds.milliseconds
':(\\d{2})' + // seconds capture
'(?:(\\.\\d{1,}))?' + // milliseconds capture
')?' +
'(' + // capture UTC offset component
'Z|' + // UTC capture
'(?:' + // offset specifier +/-hours:minutes
'([-+])' + // sign capture
'(\\d{2})' + // hours offset capture
':(\\d{2})' + // minutes offset capture
')' +
')?)?)?)?' +
'$');
var months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365];
var dayFromMonth = function dayFromMonth(year, month) {
var t = month > 1 ? 1 : 0;
return (
months[month] +
Math.floor((year - 1969 + t) / 4) -
Math.floor((year - 1901 + t) / 100) +
Math.floor((year - 1601 + t) / 400) +
365 * (year - 1970)
);
};
var toUTC = function toUTC(t) {
var s = 0;
var ms = t;
if (hasSafariSignedIntBug && ms > maxSafeUnsigned32Bit) {
// work around a Safari 8/9 bug where it treats the seconds as signed
var msToShift = Math.floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit;
var sToShift = Math.floor(msToShift / 1e3);
s += sToShift;
ms -= sToShift * 1e3;
}
return $Number(new NativeDate(1970, 0, 1, 0, 0, s, ms));
};
// Copy any custom methods a 3rd party library may have added
for (var key in NativeDate) {
if (owns(NativeDate, key)) {
DateShim[key] = NativeDate[key];
}
}
// Copy "native" methods explicitly; they may be non-enumerable
defineProperties(DateShim, {
now: NativeDate.now,
UTC: NativeDate.UTC
}, true);
DateShim.prototype = NativeDate.prototype;
defineProperties(DateShim.prototype, {
constructor: DateShim
}, true);
// Upgrade Date.parse to handle simplified ISO 8601 strings
var parseShim = function parse(string) {
var match = isoDateExpression.exec(string);
if (match) {
// parse months, days, hours, minutes, seconds, and milliseconds
// provide default values if necessary
// parse the UTC offset component
var year = $Number(match[1]),
month = $Number(match[2] || 1) - 1,
day = $Number(match[3] || 1) - 1,
hour = $Number(match[4] || 0),
minute = $Number(match[5] || 0),
second = $Number(match[6] || 0),
millisecond = Math.floor($Number(match[7] || 0) * 1000),
// When time zone is missed, local offset should be used
// (ES 5.1 bug)
// see https://bugs.ecmascript.org/show_bug.cgi?id=112
isLocalTime = Boolean(match[4] && !match[8]),
signOffset = match[9] === '-' ? 1 : -1,
hourOffset = $Number(match[10] || 0),
minuteOffset = $Number(match[11] || 0),
result;
var hasMinutesOrSecondsOrMilliseconds = minute > 0 || second > 0 || millisecond > 0;
if (
hour < (hasMinutesOrSecondsOrMilliseconds ? 24 : 25) &&
minute < 60 && second < 60 && millisecond < 1000 &&
month > -1 && month < 12 && hourOffset < 24 &&
minuteOffset < 60 && // detect invalid offsets
day > -1 &&
day < (dayFromMonth(year, month + 1) - dayFromMonth(year, month))
) {
result = (
(dayFromMonth(year, month) + day) * 24 +
hour +
hourOffset * signOffset
) * 60;
result = (
(result + minute + minuteOffset * signOffset) * 60 +
second
) * 1000 + millisecond;
if (isLocalTime) {
result = toUTC(result);
}
if (-8.64e15 <= result && result <= 8.64e15) {
return result;
}
}
return NaN;
}
return NativeDate.parse.apply(this, arguments);
};
defineProperties(DateShim, { parse: parseShim });
return DateShim;
}(Date));
/* global Date: false */
}
// ES5 15.9.4.4
// http://es5.github.com/#x15.9.4.4
if (!Date.now) {
Date.now = function now() {
return new Date().getTime();
};
}
//
// Number
// ======
//
// ES5.1 15.7.4.5
// http://es5.github.com/#x15.7.4.5
var hasToFixedBugs = NumberPrototype.toFixed && (
(0.00008).toFixed(3) !== '0.000' ||
(0.9).toFixed(0) !== '1' ||
(1.255).toFixed(2) !== '1.25' ||
(1000000000000000128).toFixed(0) !== '1000000000000000128'
);
var toFixedHelpers = {
base: 1e7,
size: 6,
data: [0, 0, 0, 0, 0, 0],
multiply: function multiply(n, c) {
var i = -1;
var c2 = c;
while (++i < toFixedHelpers.size) {
c2 += n * toFixedHelpers.data[i];
toFixedHelpers.data[i] = c2 % toFixedHelpers.base;
c2 = Math.floor(c2 / toFixedHelpers.base);
}
},
divide: function divide(n) {
var i = toFixedHelpers.size;
var c = 0;
while (--i >= 0) {
c += toFixedHelpers.data[i];
toFixedHelpers.data[i] = Math.floor(c / n);
c = (c % n) * toFixedHelpers.base;
}
},
numToString: function numToString() {
var i = toFixedHelpers.size;
var s = '';
while (--i >= 0) {
if (s !== '' || i === 0 || toFixedHelpers.data[i] !== 0) {
var t = $String(toFixedHelpers.data[i]);
if (s === '') {
s = t;
} else {
s += strSlice('0000000', 0, 7 - t.length) + t;
}
}
}
return s;
},
pow: function pow(x, n, acc) {
return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc)));
},
log: function log(x) {
var n = 0;
var x2 = x;
while (x2 >= 4096) {
n += 12;
x2 /= 4096;
}
while (x2 >= 2) {
n += 1;
x2 /= 2;
}
return n;
}
};
var toFixedShim = function toFixed(fractionDigits) {
var f, x, s, m, e, z, j, k;
// Test for NaN and round fractionDigits down
f = $Number(fractionDigits);
f = isActualNaN(f) ? 0 : Math.floor(f);
if (f < 0 || f > 20) {
throw new RangeError('Number.toFixed called with invalid number of decimals');
}
x = $Number(this);
if (isActualNaN(x)) {
return 'NaN';
}
// If it is too big or small, return the string value of the number
if (x <= -1e21 || x >= 1e21) {
return $String(x);
}
s = '';
if (x < 0) {
s = '-';
x = -x;
}
m = '0';
if (x > 1e-21) {
// 1e-21 < x < 1e21
// -70 < log2(x) < 70
e = toFixedHelpers.log(x * toFixedHelpers.pow(2, 69, 1)) - 69;
z = (e < 0 ? x * toFixedHelpers.pow(2, -e, 1) : x / toFixedHelpers.pow(2, e, 1));
z *= 0x10000000000000; // Math.pow(2, 52);
e = 52 - e;
// -18 < e < 122
// x = z / 2 ^ e
if (e > 0) {
toFixedHelpers.multiply(0, z);
j = f;
while (j >= 7) {
toFixedHelpers.multiply(1e7, 0);
j -= 7;
}
toFixedHelpers.multiply(toFixedHelpers.pow(10, j, 1), 0);
j = e - 1;
while (j >= 23) {
toFixedHelpers.divide(1 << 23);
j -= 23;
}
toFixedHelpers.divide(1 << j);
toFixedHelpers.multiply(1, 1);
toFixedHelpers.divide(2);
m = toFixedHelpers.numToString();
} else {
toFixedHelpers.multiply(0, z);
toFixedHelpers.multiply(1 << (-e), 0);
m = toFixedHelpers.numToString() + strSlice('0.00000000000000000000', 2, 2 + f);
}
}
if (f > 0) {
k = m.length;
if (k <= f) {
m = s + strSlice('0.0000000000000000000', 0, f - k + 2) + m;
} else {
m = s + strSlice(m, 0, k - f) + '.' + strSlice(m, k - f);
}
} else {
m = s + m;
}
return m;
};
defineProperties(NumberPrototype, { toFixed: toFixedShim }, hasToFixedBugs);
var hasToPrecisionUndefinedBug = (function () {
try {
return 1.0.toPrecision(undefined) === '1';
} catch (e) {
return true;
}
}());
var originalToPrecision = NumberPrototype.toPrecision;
defineProperties(NumberPrototype, {
toPrecision: function toPrecision(precision) {
return typeof precision === 'undefined' ? originalToPrecision.call(this) : originalToPrecision.call(this, precision);
}
}, hasToPrecisionUndefinedBug);
//
// String
// ======
//
// ES5 15.5.4.14
// http://es5.github.com/#x15.5.4.14
// [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers]
// Many browsers do not split properly with regular expressions or they
// do not perform the split correctly under obscure conditions.
// See http://blog.stevenlevithan.com/archives/cross-browser-split
// I've tested in many browsers and this seems to cover the deviant ones:
// 'ab'.split(/(?:ab)*/) should be ["", ""], not [""]
// '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""]
// 'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not
// [undefined, "t", undefined, "e", ...]
// ''.split(/.?/) should be [], not [""]
// '.'.split(/()()/) should be ["."], not ["", "", "."]
if (
'ab'.split(/(?:ab)*/).length !== 2 ||
'.'.split(/(.?)(.?)/).length !== 4 ||
'tesst'.split(/(s)*/)[1] === 't' ||
'test'.split(/(?:)/, -1).length !== 4 ||
''.split(/.?/).length ||
'.'.split(/()()/).length > 1
) {
(function () {
var compliantExecNpcg = typeof (/()??/).exec('')[1] === 'undefined'; // NPCG: nonparticipating capturing group
var maxSafe32BitInt = Math.pow(2, 32) - 1;
StringPrototype.split = function (separator, limit) {
var string = String(this);
if (typeof separator === 'undefined' && limit === 0) {
return [];
}
// If `separator` is not a regex, use native split
if (!isRegex(separator)) {
return strSplit(this, separator, limit);
}
var output = [];
var flags = (separator.ignoreCase ? 'i' : '') +
(separator.multiline ? 'm' : '') +
(separator.unicode ? 'u' : '') + // in ES6
(separator.sticky ? 'y' : ''), // Firefox 3+ and ES6
lastLastIndex = 0,
// Make `global` and avoid `lastIndex` issues by working with a copy
separator2, match, lastIndex, lastLength;
var separatorCopy = new RegExp(separator.source, flags + 'g');
if (!compliantExecNpcg) {
// Doesn't need flags gy, but they don't hurt
separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags);
}
/* Values for `limit`, per the spec:
* If undefined: 4294967295 // maxSafe32BitInt
* If 0, Infinity, or NaN: 0
* If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
* If negative number: 4294967296 - Math.floor(Math.abs(limit))
* If other: Type-convert, then use the above rules
*/
var splitLimit = typeof limit === 'undefined' ? maxSafe32BitInt : ES.ToUint32(limit);
match = separatorCopy.exec(string);
while (match) {
// `separatorCopy.lastIndex` is not reliable cross-browser
lastIndex = match.index + match[0].length;
if (lastIndex > lastLastIndex) {
pushCall(output, strSlice(string, lastLastIndex, match.index));
// Fix browsers whose `exec` methods don't consistently return `undefined` for
// nonparticipating capturing groups
if (!compliantExecNpcg && match.length > 1) {
/* eslint-disable no-loop-func */
match[0].replace(separator2, function () {
for (var i = 1; i < arguments.length - 2; i++) {
if (typeof arguments[i] === 'undefined') {
match[i] = void 0;
}
}
});
/* eslint-enable no-loop-func */
}
if (match.length > 1 && match.index < string.length) {
array_push.apply(output, arraySlice(match, 1));
}
lastLength = match[0].length;
lastLastIndex = lastIndex;
if (output.length >= splitLimit) {
break;
}
}
if (separatorCopy.lastIndex === match.index) {
separatorCopy.lastIndex++; // Avoid an infinite loop
}
match = separatorCopy.exec(string);
}
if (lastLastIndex === string.length) {
if (lastLength || !separatorCopy.test('')) {
pushCall(output, '');
}
} else {
pushCall(output, strSlice(string, lastLastIndex));
}
return output.length > splitLimit ? arraySlice(output, 0, splitLimit) : output;
};
}());
// [bugfix, chrome]
// If separator is undefined, then the result array contains just one String,
// which is the this value (converted to a String). If limit is not undefined,
// then the output array is truncated so that it contains no more than limit
// elements.
// "0".split(undefined, 0) -> []
} else if ('0'.split(void 0, 0).length) {
StringPrototype.split = function split(separator, limit) {
if (typeof separator === 'undefined' && limit === 0) {
return [];
}
return strSplit(this, separator, limit);
};
}
var str_replace = StringPrototype.replace;
var replaceReportsGroupsCorrectly = (function () {
var groups = [];
'x'.replace(/x(.)?/g, function (match, group) {
pushCall(groups, group);
});
return groups.length === 1 && typeof groups[0] === 'undefined';
}());
if (!replaceReportsGroupsCorrectly) {
StringPrototype.replace = function replace(searchValue, replaceValue) {
var isFn = isCallable(replaceValue);
var hasCapturingGroups = isRegex(searchValue) && (/\)[*?]/).test(searchValue.source);
if (!isFn || !hasCapturingGroups) {
return str_replace.call(this, searchValue, replaceValue);
} else {
var wrappedReplaceValue = function (match) {
var length = arguments.length;
var originalLastIndex = searchValue.lastIndex;
searchValue.lastIndex = 0;
var args = searchValue.exec(match) || [];
searchValue.lastIndex = originalLastIndex;
pushCall(args, arguments[length - 2], arguments[length - 1]);
return replaceValue.apply(this, args);
};
return str_replace.call(this, searchValue, wrappedReplaceValue);
}
};
}
// ECMA-262, 3rd B.2.3
// Not an ECMAScript standard, although ECMAScript 3rd Edition has a
// non-normative section suggesting uniform semantics and it should be
// normalized across all browsers
// [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE
var string_substr = StringPrototype.substr;
var hasNegativeSubstrBug = ''.substr && '0b'.substr(-1) !== 'b';
defineProperties(StringPrototype, {
substr: function substr(start, length) {
var normalizedStart = start;
if (start < 0) {
normalizedStart = max(this.length + start, 0);
}
return string_substr.call(this, normalizedStart, length);
}
}, hasNegativeSubstrBug);
// ES5 15.5.4.20
// whitespace from: http://es5.github.io/#x15.5.4.20
var ws = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' +
'\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028' +
'\u2029\uFEFF';
var zeroWidth = '\u200b';
var wsRegexChars = '[' + ws + ']';
var trimBeginRegexp = new RegExp('^' + wsRegexChars + wsRegexChars + '*');
var trimEndRegexp = new RegExp(wsRegexChars + wsRegexChars + '*$');
var hasTrimWhitespaceBug = StringPrototype.trim && (ws.trim() || !zeroWidth.trim());
defineProperties(StringPrototype, {
// http://blog.stevenlevithan.com/archives/faster-trim-javascript
// http://perfectionkills.com/whitespace-deviations/
trim: function trim() {
if (typeof this === 'undefined' || this === null) {
throw new TypeError("can't convert " + this + ' to object');
}
return $String(this).replace(trimBeginRegexp, '').replace(trimEndRegexp, '');
}
}, hasTrimWhitespaceBug);
var trim = call.bind(String.prototype.trim);
var hasLastIndexBug = StringPrototype.lastIndexOf && 'abcあい'.lastIndexOf('あい', 2) !== -1;
defineProperties(StringPrototype, {
lastIndexOf: function lastIndexOf(searchString) {
if (typeof this === 'undefined' || this === null) {
throw new TypeError("can't convert " + this + ' to object');
}
var S = $String(this);
var searchStr = $String(searchString);
var numPos = arguments.length > 1 ? $Number(arguments[1]) : NaN;
var pos = isActualNaN(numPos) ? Infinity : ES.ToInteger(numPos);
var start = min(max(pos, 0), S.length);
var searchLen = searchStr.length;
var k = start + searchLen;
while (k > 0) {
k = max(0, k - searchLen);
var index = strIndexOf(strSlice(S, k, start + searchLen), searchStr);
if (index !== -1) {
return k + index;
}
}
return -1;
}
}, hasLastIndexBug);
var originalLastIndexOf = StringPrototype.lastIndexOf;
defineProperties(StringPrototype, {
lastIndexOf: function lastIndexOf(searchString) {
return originalLastIndexOf.apply(this, arguments);
}
}, StringPrototype.lastIndexOf.length !== 1);
// ES-5 15.1.2.2
/* eslint-disable radix */
if (parseInt(ws + '08') !== 8 || parseInt(ws + '0x16') !== 22) {
/* eslint-enable radix */
/* global parseInt: true */
parseInt = (function (origParseInt) {
var hexRegex = /^[\-+]?0[xX]/;
return function parseInt(str, radix) {
var string = trim(String(str));
var defaultedRadix = $Number(radix) || (hexRegex.test(string) ? 16 : 10);
return origParseInt(string, defaultedRadix);
};
}(parseInt));
}
// https://es5.github.io/#x15.1.2.3
if (1 / parseFloat('-0') !== -Infinity) {
/* global parseFloat: true */
parseFloat = (function (origParseFloat) {
return function parseFloat(string) {
var inputString = trim(String(string));
var result = origParseFloat(inputString);
return result === 0 && strSlice(inputString, 0, 1) === '-' ? -0 : result;
};
}(parseFloat));
}
if (String(new RangeError('test')) !== 'RangeError: test') {
var errorToStringShim = function toString() {
if (typeof this === 'undefined' || this === null) {
throw new TypeError("can't convert " + this + ' to object');
}
var name = this.name;
if (typeof name === 'undefined') {
name = 'Error';
} else if (typeof name !== 'string') {
name = $String(name);
}
var msg = this.message;
if (typeof msg === 'undefined') {
msg = '';
} else if (typeof msg !== 'string') {
msg = $String(msg);
}
if (!name) {
return msg;
}
if (!msg) {
return name;
}
return name + ': ' + msg;
};
// can't use defineProperties here because of toString enumeration issue in IE <= 8
Error.prototype.toString = errorToStringShim;
}
if (supportsDescriptors) {
var ensureNonEnumerable = function (obj, prop) {
if (isEnum(obj, prop)) {
var desc = Object.getOwnPropertyDescriptor(obj, prop);
if (desc.configurable) {
desc.enumerable = false;
Object.defineProperty(obj, prop, desc);
}
}
};
ensureNonEnumerable(Error.prototype, 'message');
if (Error.prototype.message !== '') {
Error.prototype.message = '';
}
ensureNonEnumerable(Error.prototype, 'name');
}
if (String(/a/mig) !== '/a/gim') {
var regexToString = function toString() {
var str = '/' + this.source + '/';
if (this.global) {
str += 'g';
}
if (this.ignoreCase) {
str += 'i';
}
if (this.multiline) {
str += 'm';
}
return str;
};
// can't use defineProperties here because of toString enumeration issue in IE <= 8
RegExp.prototype.toString = regexToString;
}
}));
'use strict';
/*jslint eqeq: true*/
Handlebars.registerHelper('sanitize', function (text) {
var result;
if (text === undefined) { return ''; }
result = sanitizeHtml(text, {
allowedTags: [ 'div', 'span', 'b', 'i', 'em', 'strong', 'a', 'br', 'table', 'tbody', 'tr', 'th', 'td' ],
allowedAttributes: {
'div': [ 'class' ],
'span': [ 'class' ],
'table': [ 'class' ],
'td': [ 'class' ],
'th': [ 'colspan' ],
'a': [ 'href' ]
}
});
return new Handlebars.SafeString(result);
});
Handlebars.registerHelper('renderTextParam', function(param) {
var result, type = 'text', idAtt = '';
var paramType = param.type || param.schema && param.schema.type || '';
var isArray = paramType.toLowerCase() === 'array' || param.allowMultiple;
var defaultValue = isArray && Array.isArray(param.default) ? param.default.join('\n') : param.default;
var name = Handlebars.Utils.escapeExpression(param.name);
var valueId = Handlebars.Utils.escapeExpression(param.valueId);
paramType = Handlebars.Utils.escapeExpression(paramType);
var dataVendorExtensions = Object.keys(param).filter(function(property) {
// filter X-data- properties
return property.match(/^X-data-/i) !== null;
}).reduce(function(result, property) {
// remove X- from property name, so it results in html attributes like data-foo='bar'
return result += ' ' + property.substring(2, property.length) + '=\'' + param[property] + '\'';
}, '');
if(param.format && param.format === 'password') {
type = 'password';
}
if(valueId) {
idAtt = ' id=\'' + valueId + '\'';
}
if (defaultValue) {
defaultValue = sanitizeHtml(defaultValue);
} else {
defaultValue = '';
}
if(isArray) {
result = '<textarea class=\'body-textarea' + (param.required ? ' required' : '') + '\' name=\'' + name + '\'' + idAtt + dataVendorExtensions;
result += ' placeholder=\'Provide multiple values in new lines' + (param.required ? ' (at least one required).' : '.') + '\'>';
result += defaultValue + '</textarea>';
} else {
var parameterClass = 'parameter';
if(param.required) {
parameterClass += ' required';
}
result = '<input class=\'' + parameterClass + '\' minlength=\'' + (param.required ? 1 : 0) + '\'';
result += ' name=\'' + name +'\' placeholder=\'' + (param.required ? '(required)' : '') + '\'' + idAtt + dataVendorExtensions;
result += ' type=\'' + type + '\' value=\'' + defaultValue + '\'/>';
}
return new Handlebars.SafeString(result);
});
Handlebars.registerHelper('ifCond', function (v1, operator, v2, options) {
switch (operator) {
case '==':
return (v1 == v2) ? options.fn(this) : options.inverse(this);
case '===':
return (v1 === v2) ? options.fn(this) : options.inverse(this);
case '<':
return (v1 < v2) ? options.fn(this) : options.inverse(this);
case '<=':
return (v1 <= v2) ? options.fn(this) : options.inverse(this);
case '>':
return (v1 > v2) ? options.fn(this) : options.inverse(this);
case '>=':
return (v1 >= v2) ? options.fn(this) : options.inverse(this);
case '&&':
return (v1 && v2) ? options.fn(this) : options.inverse(this);
case '||':
return (v1 || v2) ? options.fn(this) : options.inverse(this);
default:
return options.inverse(this);
}
});
Handlebars.registerHelper('escape', function (value) {
var text = Handlebars.Utils.escapeExpression(value);
return new Handlebars.SafeString(text);
});
(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);
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)];
}}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);
}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){
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)){
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)});
/**
* swagger-client - swagger-client is a javascript client for use with swaggering APIs.
* @version v2.1.29
* @link http://swagger.io
* @license Apache-2.0
*/
(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){
'use strict';
var auth = require('./lib/auth');
var helpers = require('./lib/helpers');
var SwaggerClient = require('./lib/client');
var deprecationWrapper = function (url, options) {
helpers.log('This is deprecated, use "new SwaggerClient" instead.');
return new SwaggerClient(url, options);
};
/* Here for IE8 Support */
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function(obj, start) {
for (var i = (start || 0), j = this.length; i < j; i++) {
if (this[i] === obj) { return i; }
}
return -1;
};
}
/* Here for IE8 Support */
if (!String.prototype.trim) {
String.prototype.trim = function () {
return this.replace(/^\s+|\s+$/g, '');
};
}
/* Here for node 10.x support */
if (!String.prototype.endsWith) {
String.prototype.endsWith = function(suffix) {
return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
}
module.exports = SwaggerClient;
SwaggerClient.ApiKeyAuthorization = auth.ApiKeyAuthorization;
SwaggerClient.PasswordAuthorization = auth.PasswordAuthorization;
SwaggerClient.CookieAuthorization = auth.CookieAuthorization;
SwaggerClient.SwaggerApi = deprecationWrapper;
SwaggerClient.SwaggerClient = deprecationWrapper;
SwaggerClient.SchemaMarkup = require('./lib/schema-markup');
},{"./lib/auth":2,"./lib/client":3,"./lib/helpers":4,"./lib/schema-markup":7}],2:[function(require,module,exports){
'use strict';
var helpers = require('./helpers');
var btoa = require('btoa'); // jshint ignore:line
var CookieJar = require('cookiejar').CookieJar;
var _ = {
each: require('lodash-compat/collection/each'),
includes: require('lodash-compat/collection/includes'),
isObject: require('lodash-compat/lang/isObject'),
isArray: require('lodash-compat/lang/isArray')
};
/**
* SwaggerAuthorizations applies the correct authorization to an operation being executed
*/
var SwaggerAuthorizations = module.exports.SwaggerAuthorizations = function (authz) {
this.authz = authz || {};
};
/**
* Add auths to the hash
* Will overwrite any existing
*
*/
SwaggerAuthorizations.prototype.add = function (name, auth) {
if(_.isObject(name)) {
for (var key in name) {
this.authz[key] = name[key];
}
} else if(typeof name === 'string' ){
this.authz[name] = auth;
}
return auth;
};
SwaggerAuthorizations.prototype.remove = function (name) {
return delete this.authz[name];
};
SwaggerAuthorizations.prototype.apply = function (obj, securities) {
var status = true;
var applyAll = !securities;
var flattenedSecurities = [];
// favor the object-level authorizations over global
var authz = obj.clientAuthorizations || this.authz;
// Securities could be [ {} ]
_.each(securities, function (obj, key) {
// Make sure we account for securities being [ str ]
if(typeof key === 'string') {
flattenedSecurities.push(key);
}
// Flatten keys in to our array
_.each(obj, function (val, key) {
flattenedSecurities.push(key);
});
});
_.each(authz, function (auth, authName) {
if(applyAll || _.includes(flattenedSecurities, authName)) {
var newStatus = auth.apply(obj);
status = status && !!newStatus; // logical ORs regarding status
}
});
return status;
};
/**
* ApiKeyAuthorization allows a query param or header to be injected
*/
var ApiKeyAuthorization = module.exports.ApiKeyAuthorization = function (name, value, type) {
this.name = name;
this.value = value;
this.type = type;
};
ApiKeyAuthorization.prototype.apply = function (obj) {
if (this.type === 'query') {
// see if already applied. If so, don't do it again
var qp;
if (obj.url.indexOf('?') > 0) {
qp = obj.url.substring(obj.url.indexOf('?') + 1);
var parts = qp.split('&');
if(parts && parts.length > 0) {
for(var i = 0; i < parts.length; i++) {
var kv = parts[i].split('=');
if(kv && kv.length > 0) {
if (kv[0] === this.name) {
// skip it
return false;
}
}
}
}
}
if (obj.url.indexOf('?') > 0) {
obj.url = obj.url + '&' + this.name + '=' + this.value;
} else {
obj.url = obj.url + '?' + this.name + '=' + this.value;
}
return true;
} else if (this.type === 'header') {
if(typeof obj.headers[this.name] === 'undefined') {
obj.headers[this.name] = this.value;
}
return true;
}
};
var CookieAuthorization = module.exports.CookieAuthorization = function (cookie) {
this.cookie = cookie;
};
CookieAuthorization.prototype.apply = function (obj) {
obj.cookieJar = obj.cookieJar || new CookieJar();
obj.cookieJar.setCookie(this.cookie);
return true;
};
/**
* Password Authorization is a basic auth implementation
*/
var PasswordAuthorization = module.exports.PasswordAuthorization = function (username, password) {
if (arguments.length === 3) {
helpers.log('PasswordAuthorization: the \'name\' argument has been removed, pass only username and password');
username = arguments[1];
password = arguments[2];
}
this.username = username;
this.password = password;
};
PasswordAuthorization.prototype.apply = function (obj) {
if(typeof obj.headers.Authorization === 'undefined') {
obj.headers.Authorization = 'Basic ' + btoa(this.username + ':' + this.password);
}
return true;
};
},{"./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){
'use strict';
var _ = {
bind: require('lodash-compat/function/bind'),
cloneDeep: require('lodash-compat/lang/cloneDeep'),
find: require('lodash-compat/collection/find'),
forEach: require('lodash-compat/collection/forEach'),
indexOf: require('lodash-compat/array/indexOf'),
isArray: require('lodash-compat/lang/isArray'),
isObject: require('lodash-compat/lang/isObject'),
isFunction: require('lodash-compat/lang/isFunction'),
isPlainObject: require('lodash-compat/lang/isPlainObject'),
isUndefined: require('lodash-compat/lang/isUndefined')
};
var auth = require('./auth');
var helpers = require('./helpers');
var Model = require('./types/model');
var Operation = require('./types/operation');
var OperationGroup = require('./types/operationGroup');
var Resolver = require('./resolver');
var SwaggerHttp = require('./http');
var SwaggerSpecConverter = require('./spec-converter');
var Q = require('q');
// We have to keep track of the function/property names to avoid collisions for tag names which are used to allow the
// following usage: 'client.{tagName}'
var reservedClientTags = [
'apis',
'authorizationScheme',
'authorizations',
'basePath',
'build',
'buildFrom1_1Spec',
'buildFrom1_2Spec',
'buildFromSpec',
'clientAuthorizations',
'convertInfo',
'debug',
'defaultErrorCallback',
'defaultSuccessCallback',
'enableCookies',
'fail',
'failure',
'finish',
'help',
'host',
'idFromOp',
'info',
'initialize',
'isBuilt',
'isValid',
'modelPropertyMacro',
'models',
'modelsArray',
'options',
'parameterMacro',
'parseUri',
'progress',
'resourceCount',
'sampleModels',
'selfReflect',
'setConsolidatedModels',
'spec',
'supportedSubmitMethods',
'swaggerRequestHeaders',
'tagFromLabel',
'title',
'url',
'useJQuery',
'jqueryAjaxCache'
];
// We have to keep track of the function/property names to avoid collisions for tag names which are used to allow the
// following usage: 'client.apis.{tagName}'
var reservedApiTags = [
'apis',
'asCurl',
'description',
'externalDocs',
'help',
'label',
'name',
'operation',
'operations',
'operationsArray',
'path',
'tag'
];
var supportedOperationMethods = ['delete', 'get', 'head', 'options', 'patch', 'post', 'put'];
var SwaggerClient = module.exports = function (url, options) {
this.authorizations = null;
this.authorizationScheme = null;
this.basePath = null;
this.debug = false;
this.enableCookies = false;
this.info = null;
this.isBuilt = false;
this.isValid = false;
this.modelsArray = [];
this.resourceCount = 0;
this.url = null;
this.useJQuery = false;
this.jqueryAjaxCache = false;
this.swaggerObject = {};
this.deferredClient = undefined;
this.clientAuthorizations = new auth.SwaggerAuthorizations();
if (typeof url !== 'undefined') {
return this.initialize(url, options);
} else {
return this;
}
};
SwaggerClient.prototype.initialize = function (url, options) {
this.models = {};
this.sampleModels = {};
if (typeof url === 'string') {
this.url = url;
} else if (_.isObject(url)) {
options = url;
this.url = options.url;
}
if(this.url && this.url.indexOf('http:') === -1 && this.url.indexOf('https:') === -1) {
// no protocol, so we can only use window if it exists
if(typeof(window) !== 'undefined' && window && window.location) {
this.url = window.location.origin + this.url;
}
}
options = options || {};
this.clientAuthorizations.add(options.authorizations);
this.swaggerRequestHeaders = options.swaggerRequestHeaders || 'application/json;charset=utf-8,*/*';
this.defaultSuccessCallback = options.defaultSuccessCallback || null;
this.defaultErrorCallback = options.defaultErrorCallback || null;
this.modelPropertyMacro = options.modelPropertyMacro || null;
this.connectionAgent = options.connectionAgent || null;
this.parameterMacro = options.parameterMacro || null;
this.usePromise = options.usePromise || null;
// operation request timeout default
this.timeout = options.timeout || null;
// default to request timeout when not specified
this.fetchSpecTimeout = typeof options.fetchSpecTimeout !== 'undefined' ?
options.fetchSpecTimeout : options.timeout || null;
if(this.usePromise) {
this.deferredClient = Q.defer();
}
if (typeof options.success === 'function') {
this.success = options.success;
}
if (options.useJQuery) {
this.useJQuery = options.useJQuery;
}
if (options.jqueryAjaxCache) {
this.jqueryAjaxCache = options.jqueryAjaxCache;
}
if (options.enableCookies) {
this.enableCookies = options.enableCookies;
}
this.options = options || {};
// maybe don't need this?
this.options.timeout = this.timeout;
this.options.fetchSpecTimeout = this.fetchSpecTimeout;
this.supportedSubmitMethods = options.supportedSubmitMethods || [];
this.failure = options.failure || function (err) { throw err; };
this.progress = options.progress || function () {};
this.spec = _.cloneDeep(options.spec); // Clone so we do not alter the provided document
if (options.scheme) {
this.scheme = options.scheme;
}
if (this.usePromise || typeof options.success === 'function') {
this.ready = true;
return this.build();
}
};
SwaggerClient.prototype.build = function (mock) {
if (this.isBuilt) {
return this;
}
var self = this;
if (this.spec) {
this.progress('fetching resource list; Please wait.');
} else {
this.progress('fetching resource list: ' + this.url + '; Please wait.');
}
var obj = {
useJQuery: this.useJQuery,
jqueryAjaxCache: this.jqueryAjaxCache,
connectionAgent: this.connectionAgent,
enableCookies: this.enableCookies,
url: this.url,
method: 'get',
headers: {
accept: this.swaggerRequestHeaders
},
on: {
error: function (response) {
if (self.url.substring(0, 4) !== 'http') {
return self.fail('Please specify the protocol for ' + self.url);
} else if (response.errObj && (response.errObj.code === 'ECONNABORTED' || response.errObj.message.indexOf('timeout') !== -1)) {
return self.fail('Request timed out after ' + self.fetchSpecTimeout + 'ms');
} else if (response.status === 0) {
return self.fail('Can\'t read from server. It may not have the appropriate access-control-origin settings.');
} else if (response.status === 404) {
return self.fail('Can\'t read swagger JSON from ' + self.url);
} else {
return self.fail(response.status + ' : ' + response.statusText + ' ' + self.url);
}
},
response: function (resp) {
var responseObj = resp.obj;
if(!responseObj) {
return self.fail('failed to parse JSON/YAML response');
}
self.swaggerVersion = responseObj.swaggerVersion;
self.swaggerObject = responseObj;
if (responseObj.swagger && parseInt(responseObj.swagger) === 2) {
self.swaggerVersion = responseObj.swagger;
new Resolver().resolve(responseObj, self.url, self.buildFromSpec, self);
self.isValid = true;
} else {
var converter = new SwaggerSpecConverter();
self.oldSwaggerObject = self.swaggerObject;
converter.setDocumentationLocation(self.url);
converter.convert(responseObj, self.clientAuthorizations, self.options, function(spec) {
self.swaggerObject = spec;
new Resolver().resolve(spec, self.url, self.buildFromSpec, self);
self.isValid = true;
});
}
}
}
};
// only set timeout when specified
if (this.fetchSpecTimeout) {
obj.timeout = this.fetchSpecTimeout;
}
if (this.spec) {
self.swaggerObject = this.spec;
setTimeout(function () {
new Resolver().resolve(self.spec, self.url, self.buildFromSpec, self);
}, 10);
} else {
this.clientAuthorizations.apply(obj);
if (mock) {
return obj;
}
new SwaggerHttp().execute(obj, this.options);
}
return (this.usePromise) ? this.deferredClient.promise : this;
};
SwaggerClient.prototype.buildFromSpec = function (response) {
if (this.isBuilt) {
return this;
}
this.apis = {};
this.apisArray = [];
this.basePath = response.basePath || '';
this.consumes = response.consumes;
this.host = response.host || '';
this.info = response.info || {};
this.produces = response.produces;
this.schemes = response.schemes || [];
this.securityDefinitions = _.cloneDeep(response.securityDefinitions);
this.security = response.security;
this.title = response.title || '';
var key, definedTags = {}, k, location, self = this, i;
if (response.externalDocs) {
this.externalDocs = response.externalDocs;
}
// legacy support
this.authSchemes = this.securityDefinitions;
if(this.securityDefinitions) {
for(key in this.securityDefinitions) {
var securityDefinition = this.securityDefinitions[key];
securityDefinition.vendorExtensions = {};
for(var ext in securityDefinition) {
helpers.extractExtensions(ext, securityDefinition);
if (ext === 'scopes') {
var scopes = securityDefinition[ext];
if(typeof scopes === 'object') {
scopes.vendorExtensions = {};
for (var s in scopes) {
helpers.extractExtensions(s, scopes);
if(s.indexOf('x-') === 0) {
delete scopes[s];
}
}
}
}
}
}
}
if (Array.isArray(response.tags)) {
definedTags = {};
for (k = 0; k < response.tags.length; k++) {
var t = _.cloneDeep(response.tags[k]);
definedTags[t.name] = t;
for(i in t) {
if(i === 'externalDocs' && typeof t[i] === 'object') {
for(var j in t[i]) {
helpers.extractExtensions(j, t[i]);
}
}
helpers.extractExtensions(i, t);
}
}
}
if (typeof this.url === 'string') {
location = this.parseUri(this.url);
if (typeof this.scheme === 'undefined' && typeof this.schemes === 'undefined' || this.schemes.length === 0) {
if(typeof window !== 'undefined') {
// use the window scheme
this.scheme = window.location.protocol.replace(':','');
}
else {
this.scheme = location.scheme || 'http';
}
} else if (typeof window !== 'undefined' && window.location.protocol.indexOf('chrome-extension') === 0) {
// if it is chrome swagger ui extension scheme then let swagger doc url scheme decide the protocol
this.scheme = location.scheme;
} else if (typeof this.scheme === 'undefined') {
if(typeof window !== 'undefined') {
var scheme = window.location.protocol.replace(':','');
if(scheme === 'https' && this.schemes.indexOf(scheme) === -1) {
// can't call http from https served page in a browser!
helpers.log('Cannot call a http server from https inside a browser!');
this.scheme = 'http';
}
else if(this.schemes.indexOf(scheme) !== -1) {
this.scheme = scheme;
}
else {
if(this.schemes.indexOf('https') !== -1) {
this.scheme = 'https';
}
else {
this.scheme = 'http';
}
}
}
else {
this.scheme = this.schemes[0] || location.scheme;
}
}
if (typeof this.host === 'undefined' || this.host === '') {
this.host = location.host;
if (location.port) {
this.host = this.host + ':' + location.port;
}
}
}
else {
if (typeof this.schemes === 'undefined' || this.schemes.length === 0) {
this.scheme = 'http';
}
else if (typeof this.scheme === 'undefined') {
this.scheme = this.schemes[0];
}
}
this.definitions = response.definitions;
for (key in this.definitions) {
var model = new Model(key, this.definitions[key], this.models, this.modelPropertyMacro);
if (model) {
this.models[key] = model;
}
}
// get paths, create functions for each operationId
// Bind help to 'client.apis'
self.apis.help = _.bind(self.help, self);
_.forEach(response.paths, function (pathObj, path) {
// Only process a path if it's an object
if (!_.isPlainObject(pathObj)) {
return;
}
_.forEach(supportedOperationMethods, function (method) {
var operation = pathObj[method];
if (_.isUndefined(operation)) {
// Operation does not exist
return;
} else if (!_.isPlainObject(operation)) {
// Operation exists but it is not an Operation Object. Since this is invalid, log it.
helpers.log('The \'' + method + '\' operation for \'' + path + '\' path is not an Operation Object');
return;
}
var tags = operation.tags;
if (_.isUndefined(tags) || !_.isArray(tags) || tags.length === 0) {
tags = operation.tags = [ 'default' ];
}
var operationId = self.idFromOp(path, method, operation);
var operationObject = new Operation(self,
operation.scheme,
operationId,
method,
path,
operation,
self.definitions,
self.models,
self.clientAuthorizations);
operationObject.connectionAgent = self.connectionAgent;
operationObject.vendorExtensions = {};
for(i in operation) {
helpers.extractExtensions(i, operationObject, operation[i]);
}
operationObject.externalDocs = operation.externalDocs;
if(operationObject.externalDocs) {
operationObject.externalDocs = _.cloneDeep(operationObject.externalDocs);
operationObject.externalDocs.vendorExtensions = {};
for(i in operationObject.externalDocs) {
helpers.extractExtensions(i, operationObject.externalDocs);
}
}
// bind self operation's execute command to the api
_.forEach(tags, function (tag) {
var clientProperty = _.indexOf(reservedClientTags, tag) > -1 ? '_' + tag : tag;
var apiProperty = _.indexOf(reservedApiTags, tag) > -1 ? '_' + tag : tag;
var operationGroup = self[clientProperty];
if (clientProperty !== tag) {
helpers.log('The \'' + tag + '\' tag conflicts with a SwaggerClient function/property name. Use \'client.' +
clientProperty + '\' or \'client.apis.' + tag + '\' instead of \'client.' + tag + '\'.');
}
if (apiProperty !== tag) {
helpers.log('The \'' + tag + '\' tag conflicts with a SwaggerClient operation function/property name. Use ' +
'\'client.apis.' + apiProperty + '\' instead of \'client.apis.' + tag + '\'.');
}
if (_.indexOf(reservedApiTags, operationId) > -1) {
helpers.log('The \'' + operationId + '\' operationId conflicts with a SwaggerClient operation ' +
'function/property name. Use \'client.apis.' + apiProperty + '._' + operationId +
'\' instead of \'client.apis.' + apiProperty + '.' + operationId + '\'.');
operationId = '_' + operationId;
operationObject.nickname = operationId; // So 'client.apis.[tag].operationId.help() works properly
}
if (_.isUndefined(operationGroup)) {
operationGroup = self[clientProperty] = self.apis[apiProperty] = {};
operationGroup.operations = {};
operationGroup.label = apiProperty;
operationGroup.apis = {};
var tagDef = definedTags[tag];
if (!_.isUndefined(tagDef)) {
operationGroup.description = tagDef.description;
operationGroup.externalDocs = tagDef.externalDocs;
operationGroup.vendorExtensions = tagDef.vendorExtensions;
}
self[clientProperty].help = _.bind(self.help, operationGroup);
self.apisArray.push(new OperationGroup(tag, operationGroup.description, operationGroup.externalDocs, operationObject));
}
operationId = self.makeUniqueOperationId(operationId, self.apis[apiProperty]);
// Bind tag help
if (!_.isFunction(operationGroup.help)) {
operationGroup.help = _.bind(self.help, operationGroup);
}
// bind to the apis object
self.apis[apiProperty][operationId] = operationGroup[operationId] = _.bind(operationObject.execute,
operationObject);
self.apis[apiProperty][operationId].help = operationGroup[operationId].help = _.bind(operationObject.help,
operationObject);
self.apis[apiProperty][operationId].asCurl = operationGroup[operationId].asCurl = _.bind(operationObject.asCurl,
operationObject);
operationGroup.apis[operationId] = operationGroup.operations[operationId] = operationObject;
// legacy UI feature
var api = _.find(self.apisArray, function (api) {
return api.tag === tag;
});
if (api) {
api.operationsArray.push(operationObject);
}
});
});
});
// sort the apisArray according to the tags
var sortedApis = [];
_.forEach(Object.keys(definedTags), function (tag) {
var pos;
for(pos in self.apisArray) {
var _api = self.apisArray[pos];
if(_api && tag === _api.name) {
sortedApis.push(_api);
self.apisArray[pos] = null;
}
}
});
// add anything left
_.forEach(self.apisArray, function (api) {
if(api) {
sortedApis.push(api);
}
});
self.apisArray = sortedApis;
_.forEach(response.definitions, function (definitionObj, definition) {
definitionObj.id = definition.toLowerCase();
definitionObj.name = definition;
self.modelsArray.push(definitionObj);
});
this.isBuilt = true;
if (this.usePromise) {
this.isValid = true;
this.isBuilt = true;
this.deferredClient.resolve(this);
return this.deferredClient.promise;
}
if (this.success) {
this.success();
}
return this;
};
SwaggerClient.prototype.makeUniqueOperationId = function(operationId, api) {
var count = 0;
var name = operationId;
// make unique across this operation group
while(true) {
var matched = false;
_.forEach(api.operations, function (operation) {
if(operation.nickname === name) {
matched = true;
}
});
if(!matched) {
return name;
}
name = operationId + '_' + count;
count ++;
}
return operationId;
};
SwaggerClient.prototype.parseUri = function (uri) {
var urlParseRE = /^(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/;
var parts = urlParseRE.exec(uri);
return {
scheme: parts[4] ? parts[4].replace(':','') : undefined,
host: parts[11],
port: parts[12],
path: parts[15]
};
};
SwaggerClient.prototype.help = function (dontPrint) {
var output = '';
if (this instanceof SwaggerClient) {
_.forEach(this.apis, function (api, name) {
if (_.isPlainObject(api)) {
output += 'operations for the \'' + name + '\' tag\n';
_.forEach(api.operations, function (operation, name) {
output += ' * ' + name + ': ' + operation.summary + '\n';
});
}
});
} else if (this instanceof OperationGroup || _.isPlainObject(this)) {
output += 'operations for the \'' + this.label + '\' tag\n';
_.forEach(this.apis, function (operation, name) {
output += ' * ' + name + ': ' + operation.summary + '\n';
});
}
if (dontPrint) {
return output;
} else {
helpers.log(output);
return output;
}
};
SwaggerClient.prototype.tagFromLabel = function (label) {
return label;
};
SwaggerClient.prototype.idFromOp = function (path, httpMethod, op) {
if(!op || !op.operationId) {
op = op || {};
op.operationId = httpMethod + '_' + path;
}
var opId = op.operationId.replace(/[\s!@#$%^&*()_+=\[{\]};:<>|.\/?,\\'""-]/g, '_') || (path.substring(1) + '_' + httpMethod);
opId = opId.replace(/((_){2,})/g, '_');
opId = opId.replace(/^(_)*/g, '');
opId = opId.replace(/([_])*$/g, '');
return opId;
};
SwaggerClient.prototype.setHost = function (host) {
this.host = host;
if(this.apis) {
_.forEach(this.apis, function(api) {
if(api.operations) {
_.forEach(api.operations, function(operation) {
operation.host = host;
});
}
});
}
};
SwaggerClient.prototype.setBasePath = function (basePath) {
this.basePath = basePath;
if(this.apis) {
_.forEach(this.apis, function(api) {
if(api.operations) {
_.forEach(api.operations, function(operation) {
operation.basePath = basePath;
});
}
});
}
};
SwaggerClient.prototype.setSchemes = function (schemes) {
this.schemes = schemes;
if(schemes && schemes.length > 0) {
if(this.apis) {
_.forEach(this.apis, function (api) {
if (api.operations) {
_.forEach(api.operations, function (operation) {
operation.scheme = schemes[0];
});
}
});
}
}
};
SwaggerClient.prototype.fail = function (message) {
if (this.usePromise) {
this.deferredClient.reject(message);
return this.deferredClient.promise;
} else {
if (this.failure) {
this.failure(message);
}
else {
this.failure(message);
}
}
};
},{"./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){
(function (process){
'use strict';
var _ = {
isPlainObject: require('lodash-compat/lang/isPlainObject'),
indexOf: require('lodash-compat/array/indexOf')
};
module.exports.__bind = function (fn, me) {
return function(){
return fn.apply(me, arguments);
};
};
var log = module.exports.log = function() {
// Only log if available and we're not testing
if (console && process.env.NODE_ENV !== 'test') {
console.log(Array.prototype.slice.call(arguments)[0]);
}
};
module.exports.fail = function (message) {
log(message);
};
module.exports.optionHtml = function (label, value) {
return '<tr><td class="optionName">' + label + ':</td><td>' + value + '</td></tr>';
};
var resolveSchema = module.exports.resolveSchema = function (schema) {
if (_.isPlainObject(schema.schema)) {
schema = resolveSchema(schema.schema);
}
return schema;
};
module.exports.simpleRef = function (name) {
if (typeof name === 'undefined') {
return null;
}
if (name.indexOf('#/definitions/') === 0) {
return name.substring('#/definitions/'.length);
} else {
return name;
}
};
/**
* helper to remove extensions and add them to an object
*
* @param keyname
* @param obj
*/
module.exports.extractExtensions = function (keyname, obj, value) {
if(!keyname || !obj) {
return;
}
if (typeof keyname === 'string' && keyname.indexOf('x-') === 0) {
obj.vendorExtensions = obj.vendorExtensions || {};
if(value) {
obj.vendorExtensions[keyname] = value;
}
else {
obj.vendorExtensions[keyname] = obj[keyname];
}
}
};
}).call(this,require('_process'))
},{"_process":12,"lodash-compat/array/indexOf":49,"lodash-compat/lang/isPlainObject":145}],5:[function(require,module,exports){
(function (Buffer){
'use strict';
var helpers = require('./helpers');
var request = require('superagent');
var jsyaml = require('js-yaml');
var _ = {
isObject: require('lodash-compat/lang/isObject'),
keys: require('lodash-compat/object/keys')
};
/*
* JQueryHttpClient is a light-weight, node or browser HTTP client
*/
var JQueryHttpClient = function () {
this.type = 'JQueryHttpClient';
};
/*
* SuperagentHttpClient is a light-weight, node or browser HTTP client
*/
var SuperagentHttpClient = function () {
this.type = 'SuperagentHttpClient';
};
/**
* SwaggerHttp is a wrapper for executing requests
*/
var SwaggerHttp = module.exports = function () {};
SwaggerHttp.prototype.execute = function (obj, opts) {
var client;
if(opts && opts.client) {
client = opts.client;
}
else {
client = new SuperagentHttpClient(opts);
}
client.opts = opts || {};
if (opts && opts.requestAgent) {
request = opts.requestAgent;
}
// legacy support
var hasJQuery = false;
if(typeof window !== 'undefined') {
if(typeof window.jQuery !== 'undefined') {
hasJQuery = true;
}
}
// OPTIONS support
if(obj.method.toLowerCase() === 'options' && client.type === 'SuperagentHttpClient') {
log('forcing jQuery as OPTIONS are not supported by SuperAgent');
obj.useJQuery = true;
}
if(this.isInternetExplorer() && (obj.useJQuery === false || !hasJQuery )) {
throw new Error('Unsupported configuration! JQuery is required but not available');
}
if ((obj && obj.useJQuery === true) || this.isInternetExplorer() && hasJQuery) {
client = new JQueryHttpClient(opts);
}
var success = obj.on.response;
var error = obj.on.error;
var requestInterceptor = function(data) {
if(opts && opts.requestInterceptor) {
data = opts.requestInterceptor.apply(data);
}
return data;
};
var responseInterceptor = function(data) {
if(opts && opts.responseInterceptor) {
data = opts.responseInterceptor.apply(data, [obj]);
}
return success(data);
};
var errorInterceptor = function(data) {
if(opts && opts.responseInterceptor) {
data = opts.responseInterceptor.apply(data, [obj]);
}
error(data);
};
obj.on.error = function(data) {
errorInterceptor(data);
};
obj.on.response = function(data) {
if(data && data.status >= 400) {
errorInterceptor(data);
}
else {
responseInterceptor(data);
}
};
if (_.isObject(obj) && _.isObject(obj.body)) {
// special processing for file uploads via jquery
if (obj.body.type && obj.body.type === 'formData'){
if(opts.useJQuery) {
obj.contentType = false;
obj.processData = false;
delete obj.headers['Content-Type'];
}
}
}
obj = requestInterceptor(obj) || obj;
if (obj.beforeSend) {
obj.beforeSend(function(_obj) {
client.execute(_obj || obj);
});
} else {
client.execute(obj);
}
return (obj.deferred) ? obj.deferred.promise : obj;
};
SwaggerHttp.prototype.isInternetExplorer = function () {
var detectedIE = false;
if (typeof navigator !== 'undefined' && navigator.userAgent) {
var nav = navigator.userAgent.toLowerCase();
if (nav.indexOf('msie') !== -1) {
var version = parseInt(nav.split('msie')[1]);
if (version <= 8) {
detectedIE = true;
}
}
}
return detectedIE;
};
JQueryHttpClient.prototype.execute = function (obj) {
var jq = this.jQuery || (typeof window !== 'undefined' && window.jQuery);
var cb = obj.on;
var request = obj;
if(typeof jq === 'undefined' || jq === false) {
throw new Error('Unsupported configuration! JQuery is required but not available');
}
obj.type = obj.method;
obj.cache = obj.jqueryAjaxCache;
obj.data = obj.body;
delete obj.jqueryAjaxCache;
delete obj.useJQuery;
delete obj.body;
obj.complete = function (response) {
var headers = {};
var headerArray = response.getAllResponseHeaders().split('\n');
for (var i = 0; i < headerArray.length; i++) {
var toSplit = headerArray[i].trim();
if (toSplit.length === 0) {
continue;
}
var separator = toSplit.indexOf(':');
if (separator === -1) {
// Name but no value in the header
headers[toSplit] = null;
continue;
}
var name = toSplit.substring(0, separator).trim();
var value = toSplit.substring(separator + 1).trim();
headers[name] = value;
}
var out = {
url: request.url,
method: request.method,
status: response.status,
statusText: response.statusText,
data: response.responseText,
headers: headers
};
try {
var possibleObj = response.responseJSON || jsyaml.safeLoad(response.responseText);
out.obj = (typeof possibleObj === 'string') ? {} : possibleObj;
} catch (ex) {
// do not set out.obj
helpers.log('unable to parse JSON/YAML content');
}
// I can throw, or parse null?
out.obj = out.obj || null;
if (response.status >= 200 && response.status < 300) {
cb.response(out);
} else if (response.status === 0 || (response.status >= 400 && response.status < 599)) {
cb.error(out);
} else {
return cb.response(out);
}
};
jq.support.cors = true;
return jq.ajax(obj);
};
SuperagentHttpClient.prototype.execute = function (obj) {
var method = obj.method.toLowerCase();
var timeout = obj.timeout;
if (method === 'delete') {
method = 'del';
}
var headers = obj.headers || {};
var r = request[method](obj.url);
if (obj.connectionAgent) {
r.agent(obj.connectionAgent);
}
if (timeout) {
r.timeout(timeout);
}
if (obj.enableCookies) {
r.withCredentials();
}
var accept = obj.headers.Accept;
if(this.binaryRequest(accept)) {
r.on('request', function () {
if(this.xhr) {
this.xhr.responseType = 'blob';
}
});
}
if(obj.body) {
if(_.isObject(obj.body)) {
var contentType = obj.headers['Content-Type'] || '';
if (contentType.indexOf('multipart/form-data') === 0) {
delete headers['Content-Type'];
if({}.toString.apply(obj.body) === '[object FormData]') {
r.send(obj.body);
}
else {
var keyname, value, v;
for (keyname in obj.body) {
value = obj.body[keyname];
if(Array.isArray(value)) {
for(v in value) {
r.field(keyname, v);
}
}
else {
r.field(keyname, value);
}
}
}
}
else if (_.isObject(obj.body)) {
// non multipart/form-data
obj.body = JSON.stringify(obj.body);
r.send(obj.body);
}
}
else {
r.send(obj.body);
}
}
var name;
for (name in headers) {
r.set(name, headers[name]);
}
if(typeof r.buffer === 'function') {
r.buffer(); // force superagent to populate res.text with the raw response data
}
r.end(function (err, res) {
res = res || {
status: 0,
headers: {error: 'no response from server'}
};
var response = {
url: obj.url,
method: obj.method,
headers: res.headers
};
var cb;
if (!err && res.error) {
err = res.error;
}
if (err && obj.on && obj.on.error) {
response.errObj = err;
response.status = res ? res.status : 500;
response.statusText = res ? res.text : err.message;
if (res.headers && res.headers['content-type']) {
if (res.headers['content-type'].indexOf('application/json') >= 0) {
try {
response.obj = JSON.parse(response.statusText);
}
catch (e) {
response.obj = null;
}
}
}
cb = obj.on.error;
} else if (res && obj.on && obj.on.response) {
var possibleObj;
// Already parsed by by superagent?
if (res.body && _.keys(res.body).length > 0) {
possibleObj = res.body;
} else {
try {
possibleObj = jsyaml.safeLoad(res.text);
// can parse into a string... which we don't need running around in the system
possibleObj = (typeof possibleObj === 'string') ? null : possibleObj;
} catch (e) {
helpers.log('cannot parse JSON/YAML content');
}
}
// null means we can't parse into object
if(typeof Buffer === 'function' && Buffer.isBuffer(possibleObj)) {
response.data = possibleObj;
}
else {
response.obj = (typeof possibleObj === 'object') ? possibleObj : null;
}
response.status = res.status;
response.statusText = res.text;
cb = obj.on.response;
}
if (res.xhr && res.xhr.response) {
response.data = res.xhr.response;
}
else if(!response.data) {
response.data = response.statusText;
}
if (cb) {
cb(response);
}
});
};
SuperagentHttpClient.prototype. binaryRequest = function (accept) {
if(!accept) {
return false;
}
return (/^image/i).test(accept)
|| (/^application\/pdf/).test(accept)
|| (/^application\/octet-stream/).test(accept);
};
}).call(this,require("buffer").Buffer)
},{"./helpers":4,"buffer":14,"js-yaml":19,"lodash-compat/lang/isObject":144,"lodash-compat/object/keys":149,"superagent":158}],6:[function(require,module,exports){
'use strict';
var SwaggerHttp = require('./http');
var _ = {
isObject: require('lodash-compat/lang/isObject'),
cloneDeep: require('lodash-compat/lang/cloneDeep'),
isArray: require('lodash-compat/lang/isArray'),
isString: require('lodash-compat/lang/isString')
};
/**
* Resolves a spec's remote references
*/
var Resolver = module.exports = function () {
this.failedUrls = [];
this.resolverCache = {};
this.pendingUrls = {};
};
Resolver.prototype.processAllOf = function(root, name, definition, resolutionTable, unresolvedRefs, spec) {
var i, location, property;
definition['x-resolved-from'] = [ '#/definitions/' + name ];
var allOf = definition.allOf;
// the refs go first
allOf.sort(function(a, b) {
if(a.$ref && b.$ref) { return 0; }
else if(a.$ref) { return -1; }
else { return 1; }
});
for (i = 0; i < allOf.length; i++) {
property = allOf[i];
location = '/definitions/' + name + '/allOf';
this.resolveInline(root, spec, property, resolutionTable, unresolvedRefs, location);
}
};
Resolver.prototype.resolve = function (spec, arg1, arg2, arg3) {
this.spec = spec;
var root = arg1, callback = arg2, scope = arg3, opts = {}, location, i;
if(typeof arg1 === 'function') {
root = null;
callback = arg1;
scope = arg2;
}
var _root = root, modelName;
this.scope = (scope || this);
this.iteration = this.iteration || 0;
if(this.scope.options && this.scope.options.requestInterceptor){
opts.requestInterceptor = this.scope.options.requestInterceptor;
}
if(this.scope.options && this.scope.options.responseInterceptor){
opts.responseInterceptor = this.scope.options.responseInterceptor;
}
var name, path, property, propertyName, parameter, done, counter;
var processedCalls = 0, resolvedRefs = {}, unresolvedRefs = {};
var resolutionTable = []; // store objects for dereferencing
spec.definitions = spec.definitions || {};
// definitions
for (name in spec.definitions) {
var definition = spec.definitions[name];
if(definition.$ref) {
this.resolveInline(root, spec, definition, resolutionTable, unresolvedRefs, definition);
}
else {
for (propertyName in definition.properties) {
property = definition.properties[propertyName];
if (_.isArray(property.allOf)) {
this.processAllOf(root, name, property, resolutionTable, unresolvedRefs, spec);
}
else {
this.resolveTo(root, property, resolutionTable, '/definitions');
}
}
if (definition.allOf) {
this.processAllOf(root, name, definition, resolutionTable, unresolvedRefs, spec);
}
}
}
// shared parameters
spec.parameters = spec.parameters || {};
for(name in spec.parameters) {
parameter = spec.parameters[name];
if (parameter.in === 'body' && parameter.schema) {
if(_.isArray(parameter.schema.allOf)) {
// move to a definition
modelName = 'inline_model';
var _name = modelName;
done = false; counter = 0;
while(!done) {
if(typeof spec.definitions[_name] === 'undefined') {
done = true;
break;
}
_name = modelName + '_' + counter;
counter ++;
}
spec.definitions[_name] = { allOf: parameter.schema.allOf };
delete parameter.schema.allOf;
parameter.schema.$ref = '#/definitions/' + _name;
this.processAllOf(root, _name, spec.definitions[_name], resolutionTable, unresolvedRefs, spec);
}
else {
this.resolveTo(root, parameter.schema, resolutionTable, location);
}
}
if (parameter.$ref) {
// parameter reference
this.resolveInline(root, spec, parameter, resolutionTable, unresolvedRefs, parameter.$ref);
}
}
// operations
for (name in spec.paths) {
var method, operation, responseCode;
path = spec.paths[name];
if(typeof path === 'object') {
for (method in path) {
// operation reference
if (method === '$ref') {
// location = path[method];
location = '/paths' + name;
this.resolveInline(root, spec, path, resolutionTable, unresolvedRefs, location);
}
else {
operation = path[method];
var sharedParameters = path.parameters || [];
var parameters = operation.parameters || [];
sharedParameters.forEach(function(parameter) {
parameters.unshift(parameter);
});
if (method !== 'parameters' && _.isObject(operation)) {
operation.parameters = operation.parameters || parameters;
}
for (i in parameters) {
parameter = parameters[i];
location = '/paths' + name + '/' + method + '/parameters';
if (parameter.in === 'body' && parameter.schema) {
if (_.isArray(parameter.schema.allOf)) {
// move to a definition
modelName = 'inline_model';
name = modelName;
done = false;
counter = 0;
while (!done) {
if (typeof spec.definitions[name] === 'undefined') {
done = true;
break;
}
name = modelName + '_' + counter;
counter++;
}
spec.definitions[name] = {allOf: parameter.schema.allOf};
delete parameter.schema.allOf;
parameter.schema.$ref = '#/definitions/' + name;
this.processAllOf(root, name, spec.definitions[name], resolutionTable, unresolvedRefs, spec);
}
else {
this.resolveTo(root, parameter.schema, resolutionTable, location);
}
}
if (parameter.$ref) {
// parameter reference
this.resolveInline(root, spec, parameter, resolutionTable, unresolvedRefs, parameter.$ref);
}
}
for (responseCode in operation.responses) {
var response = operation.responses[responseCode];
location = '/paths' + name + '/' + method + '/responses/' + responseCode;
if (_.isObject(response)) {
if (response.$ref) {
// response reference
this.resolveInline(root, spec, response, resolutionTable, unresolvedRefs, location);
}
if (response.schema) {
var responseObj = response;
if (_.isArray(responseObj.schema.allOf)) {
// move to a definition
modelName = 'inline_model';
name = modelName;
done = false;
counter = 0;
while (!done) {
if (typeof spec.definitions[name] === 'undefined') {
done = true;
break;
}
name = modelName + '_' + counter;
counter++;
}
spec.definitions[name] = {allOf: responseObj.schema.allOf};
delete responseObj.schema.allOf;
delete responseObj.schema.type;
responseObj.schema.$ref = '#/definitions/' + name;
this.processAllOf(root, name, spec.definitions[name], resolutionTable, unresolvedRefs, spec);
}
else if ('array' === responseObj.schema.type) {
if (responseObj.schema.items && responseObj.schema.items.$ref) {
// response reference
this.resolveInline(root, spec, responseObj.schema.items, resolutionTable, unresolvedRefs, location);
}
}
else {
this.resolveTo(root, response.schema, resolutionTable, location);
}
}
}
}
}
}
// clear them out to avoid multiple resolutions
path.parameters = [];
}
}
var expectedCalls = 0, toResolve = [];
// if the root is same as obj[i].root we can resolve locally
var all = resolutionTable;
var parts;
for(i = 0; i < all.length; i++) {
var a = all[i];
if(root === a.root) {
if(a.resolveAs === 'ref') {
// resolve any path walking
var joined = ((a.root || '') + '/' + a.key).split('/');
var normalized = [];
var url = '';
var k;
if(a.key.indexOf('../') >= 0) {
for(var j = 0; j < joined.length; j++) {
if(joined[j] === '..') {
normalized = normalized.slice(0, normalized.length-1);
}
else {
normalized.push(joined[j]);
}
}
for(k = 0; k < normalized.length; k ++) {
if(k > 0) {
url += '/';
}
url += normalized[k];
}
// we now have to remote resolve this because the path has changed
a.root = url;
toResolve.push(a);
}
else {
parts = a.key.split('#');
if(parts.length === 2) {
if(parts[0].indexOf('http:') === 0 || parts[0].indexOf('https:') === 0) {
a.root = parts[0];
}
location = parts[1].split('/');
var r;
var s = spec;
for(k = 0; k < location.length; k++) {
var part = location[k];
if(part !== '') {
s = s[part];
if(typeof s !== 'undefined') {
r = s;
}
else {
r = null;
break;
}
}
}
if(r === null) {
// must resolve this too
toResolve.push(a);
}
}
}
}
else {
if (a.resolveAs === 'inline') {
if(a.key && a.key.indexOf('#') === -1 && a.key.charAt(0) !== '/') {
// handle relative schema
parts = a.root.split('/');
location = '';
for(i = 0; i < parts.length - 1; i++) {
location += parts[i] + '/';
}
location += a.key;
a.root = location;
a.location = '';
}
toResolve.push(a);
}
}
}
else {
toResolve.push(a);
}
}
expectedCalls = toResolve.length;
// resolve anything that is local
var lock = {};
for(var ii = 0; ii < toResolve.length; ii++) {
(function(item, spec, self, lock, ii) {
if(!item.root || item.root === root) {
// local resolve
self.resolveItem(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, item);
processedCalls += 1;
if(processedCalls === expectedCalls) {
self.finish(spec, root, resolutionTable, resolvedRefs, unresolvedRefs, callback, true);
}
}
else if(self.failedUrls.indexOf(item.root) === -1) {
var obj = {
useJQuery: false, // TODO
url: item.root,
method: 'get',
headers: {
accept: self.scope.swaggerRequestHeaders || 'application/json'
},
on: {
error: function (error) {
processedCalls += 1;
console.log('failed url: ' + obj.url);
self.failedUrls.push(obj.url);
if (lock) {
delete lock[item.root];
}
unresolvedRefs[item.key] = {
root: item.root,
location: item.location
};
if (processedCalls === expectedCalls) {
self.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback);
}
}, // jshint ignore:line
response: function (response) {
var swagger = response.obj;
if (lock) {
delete lock[item.root];
}
if (self.resolverCache) {
self.resolverCache[item.root] = swagger;
}
self.resolveItem(swagger, item.root, resolutionTable, resolvedRefs, unresolvedRefs, item);
processedCalls += 1;
if (processedCalls === expectedCalls) {
self.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback);
}
}
} // jshint ignore:line
};
// apply timeout only when specified
if (scope && scope.fetchSpecTimeout) {
obj.timeout = scope.fetchSpecTimeout;
}
if (scope && scope.clientAuthorizations) {
scope.clientAuthorizations.apply(obj);
}
(function waitForUnlock() {
setTimeout(function() {
if (lock[obj.url]) {
waitForUnlock();
}
else {
var cached = self.resolverCache[obj.url];
if (_.isObject(cached)) {
obj.on.response({obj: cached});
}
else {
lock[obj.url] = true;
new SwaggerHttp().execute(obj, opts);
}
}
}, 0);
})();
}
else {
processedCalls += 1;
unresolvedRefs[item.key] = {
root: item.root,
location: item.location
};
if (processedCalls === expectedCalls) {
self.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback);
}
}
}(toResolve[ii], spec, this, lock, ii));
}
if (Object.keys(toResolve).length === 0) {
this.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback);
}
};
Resolver.prototype.resolveItem = function(spec, root, resolutionTable, resolvedRefs, unresolvedRefs, item) {
var path = item.location;
var location = spec, parts = path.split('/');
if(path !== '') {
for (var j = 0; j < parts.length; j++) {
var segment = parts[j];
if (segment.indexOf('~1') !== -1) {
segment = parts[j].replace(/~0/g, '~').replace(/~1/g, '/');
if (segment.charAt(0) !== '/') {
segment = '/' + segment;
}
}
if (typeof location === 'undefined' || location === null) {
break;
}
if (segment === '' && j === (parts.length - 1) && parts.length > 1) {
location = null;
break;
}
if (segment.length > 0) {
location = location[segment];
}
}
}
var resolved = item.key;
parts = item.key.split('/');
var resolvedName = parts[parts.length-1];
if(resolvedName.indexOf('#') >= 0) {
resolvedName = resolvedName.split('#')[1];
}
if (location !== null && typeof location !== 'undefined') {
resolvedRefs[resolved] = {
name: resolvedName,
obj: location,
key: item.key,
root: item.root
};
} else {
unresolvedRefs[resolved] = {
root: item.root,
location: item.location
};
}
};
Resolver.prototype.finish = function (spec, root, resolutionTable, resolvedRefs, unresolvedRefs, callback, localResolve) {
// walk resolution table and replace with resolved refs
var ref, abs;
for (ref in resolutionTable) {
var item = resolutionTable[ref];
var key = item.key;
var resolvedTo = resolvedRefs[key];
if (resolvedTo) {
spec.definitions = spec.definitions || {};
if (item.resolveAs === 'ref') {
if (localResolve !== true) {
// don't retain root for local definitions
for (key in resolvedTo.obj) {
abs = this.retainRoot(key, resolvedTo.obj[key], item.root);
resolvedTo.obj[key] = abs;
}
}
spec.definitions[resolvedTo.name] = resolvedTo.obj;
item.obj.$ref = '#/definitions/' + resolvedTo.name;
} else if (item.resolveAs === 'inline') {
var targetObj = item.obj;
targetObj['x-resolved-from'] = [ item.key ];
delete targetObj.$ref;
for (key in resolvedTo.obj) {
abs = resolvedTo.obj[key];
if (localResolve !== true) {
// don't retain root for local definitions
abs = this.retainRoot(key, resolvedTo.obj[key], item.root);
}
targetObj[key] = abs;
}
}
}
}
var existingUnresolved = this.countUnresolvedRefs(spec);
if(existingUnresolved === 0 || this.iteration > 5) {
this.resolveAllOf(spec.definitions);
this.resolverCache = null;
callback.call(this.scope, spec, unresolvedRefs);
}
else {
this.iteration += 1;
this.resolve(spec, root, callback, this.scope);
}
};
Resolver.prototype.countUnresolvedRefs = function(spec) {
var i;
var refs = this.getRefs(spec);
var keys = [];
var unresolvedKeys = [];
for(i in refs) {
if(i.indexOf('#') === 0) {
keys.push(i.substring(1));
}
else {
unresolvedKeys.push(i);
}
}
// verify possible keys
for (i = 0; i < keys.length; i++) {
var part = keys[i];
var parts = part.split('/');
var obj = spec;
for (var k = 0; k < parts.length; k++) {
var key = parts[k];
if(key !== '') {
obj = obj[key];
if(typeof obj === 'undefined') {
unresolvedKeys.push(part);
break;
}
}
}
}
return unresolvedKeys.length;
};
Resolver.prototype.getRefs = function(spec, obj) {
obj = obj || spec;
var output = {};
for(var key in obj) {
if (!obj.hasOwnProperty(key)) {
continue;
}
var item = obj[key];
if(key === '$ref' && typeof item === 'string') {
output[item] = null;
}
else if(_.isObject(item)) {
var o = this.getRefs(item);
for(var k in o) {
output[k] = null;
}
}
}
return output;
};
function splitUrl(url) {
var result = {};
var proto = /[a-z]+:\/\//i.exec(url);
if (proto) {
result.proto = proto[0].slice(0, -3);
url = url.slice(result.proto.length + 1);
}
if (url.slice(0, 2) === '//') {
result.domain = url.slice(2).split('/')[0];
url = url.slice(2 + result.domain.length);
}
var p = url.split('#');
if (p[0].length) {
result.path = p[0];
}
if (p.length > 1) {
result.fragment = p.slice(1).join('#');
}
return result;
}
function unsplitUrl(url) {
var result = url.path;
if (result === undefined) {
result = '';
}
if (url.fragment !== undefined) {
result += '#' + url.fragment;
}
if (url.domain !== undefined) {
if (result.slice(0, 1) === '/') {
result = result.slice(1);
}
result = '//' + url.domain + '/' + result;
if (url.proto !== undefined) {
result = url.proto + ':' + result;
}
}
return result;
}
function joinUrl(base, rel) {
var relsp = splitUrl(rel);
if (relsp.domain !== undefined) {
return rel;
}
var result = splitUrl(base);
if (relsp.path === undefined) {
// change only fragment part
result.fragment = relsp.fragment;
} else if (relsp.path.slice(0, 1) === '/') {
// relative to domain
result.path = relsp.path;
result.fragment = relsp.fragment;
} else {
// relative to path
var path = result.path === undefined ? [] : result.path.split('/');
var relpath = relsp.path.split('/');
if (path.length) {
path.pop();
}
while (relpath[0] === '..' || relpath[0] === '.') {
if (relpath[0] === '..') {
path.pop();
}
relpath.shift();
}
result.path = path.concat(relpath).join('/');
result.fragment = relsp.fragment;
}
return unsplitUrl(result);
}
Resolver.prototype.retainRoot = function(origKey, obj, root) {
// walk object and look for relative $refs
if(_.isObject(obj)) {
for(var key in obj) {
var item = obj[key];
if (key === '$ref' && typeof item === 'string') {
obj[key] = joinUrl(root, item);
}
else if (_.isObject(item)) {
this.retainRoot(key, item, root);
}
}
}
else if(_.isString(obj) && origKey === '$ref') {
obj = joinUrl(root, obj);
}
return obj;
};
/**
* immediately in-lines local refs, queues remote refs
* for inline resolution
*/
Resolver.prototype.resolveInline = function (root, spec, property, resolutionTable, unresolvedRefs, location) {
var key = property.$ref, ref = property.$ref, i, p, p2, rs;
var rootTrimmed = false;
root = root || ''; // Guard against .split. @fehguy, you'll need to check if this logic fits
// More imporantly is how do we gracefully handle relative urls, when provided just a 'spec', not a 'url' ?
if (ref) {
if(ref.indexOf('../') === 0) {
// reset root
p = ref.split('../');
p2 = root.split('/');
ref = '';
for(i = 0; i < p.length; i++) {
if(p[i] === '') {
p2 = p2.slice(0, p2.length-1);
}
else {
ref += p[i];
}
}
root = '';
for(i = 0; i < p2.length - 1; i++) {
if(i > 0) { root += '/'; }
root += p2[i];
}
rootTrimmed = true;
}
if(ref.indexOf('#') >= 0) {
if(ref.indexOf('/') === 0) {
rs = ref.split('#');
p = root.split('//');
p2 = p[1].split('/');
root = p[0] + '//' + p2[0] + rs[0];
location = rs[1];
}
else {
rs = ref.split('#');
if(rs[0] !== '') {
p2 = root.split('/');
p2 = p2.slice(0, p2.length - 1);
if(!rootTrimmed) {
root = '';
for (var k = 0; k < p2.length; k++) {
if(k > 0) { root += '/'; }
root += p2[k];
}
}
root += '/' + ref.split('#')[0];
}
location = rs[1];
}
}
if (ref.indexOf('http:') === 0 || ref.indexOf('https:') === 0) {
if(ref.indexOf('#') >= 0) {
root = ref.split('#')[0];
location = ref.split('#')[1];
}
else {
root = ref;
location = '';
}
resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location});
} else if (ref.indexOf('#') === 0) {
location = ref.split('#')[1];
resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location});
} else if (ref.indexOf('/') === 0 && ref.indexOf('#') === -1) {
location = ref;
var matches = root.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);
if(matches) {
root = matches[0] + ref.substring(1);
location = '';
}
resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location});
}
else {
resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location});
}
}
else if (property.type === 'array') {
this.resolveTo(root, property.items, resolutionTable, location);
}
};
Resolver.prototype.resolveTo = function (root, property, resolutionTable, location) {
var sp, i;
var ref = property.$ref;
var lroot = root;
if ((typeof ref !== 'undefined') && (ref !== null)) {
if(ref.indexOf('#') >= 0) {
var parts = ref.split('#');
// #/definitions/foo
// foo.json#/bar
if(parts[0] && ref.indexOf('/') === 0) {
}
else if(parts[0] && (parts[0].indexOf('http:') === 0 || parts[0].indexOf('https:') === 0)) {
lroot = parts[0];
ref = parts[1];
}
else if(parts[0] && parts[0].length > 0) {
// relative file
sp = root.split('/');
lroot = '';
for(i = 0; i < sp.length - 1; i++) {
lroot += sp[i] + '/';
}
lroot += parts[0];
}
else {
}
location = parts[1];
}
else if (ref.indexOf('http:') === 0 || ref.indexOf('https:') === 0) {
lroot = ref;
location = '';
}
else {
// relative file
sp = root.split('/');
lroot = '';
for(i = 0; i < sp.length - 1; i++) {
lroot += sp[i] + '/';
}
lroot += ref;
location = '';
}
resolutionTable.push({
obj: property, resolveAs: 'ref', root: lroot, key: ref, location: location
});
} else if (property.type === 'array') {
var items = property.items;
this.resolveTo(root, items, resolutionTable, location);
} else {
if(property && (property.properties || property.additionalProperties)) {
var name = this.uniqueName('inline_model');
if (property.title) {
name = this.uniqueName(property.title);
}
delete property.title;
this.spec.definitions[name] = _.cloneDeep(property);
property.$ref = '#/definitions/' + name;
delete property.type;
delete property.properties;
}
}
};
Resolver.prototype.uniqueName = function(base) {
var name = base;
var count = 0;
while(true) {
if(!_.isObject(this.spec.definitions[name])) {
return name;
}
name = base + '_' + count;
count++;
}
};
Resolver.prototype.resolveAllOf = function(spec, obj, depth) {
depth = depth || 0;
obj = obj || spec;
var name;
for(var key in obj) {
if (!obj.hasOwnProperty(key)) {
continue;
}
var item = obj[key];
if(item === null) {
throw new TypeError('Swagger 2.0 does not support null types (' + obj + '). See https://github.com/swagger-api/swagger-spec/issues/229.');
}
if(typeof item === 'object') {
this.resolveAllOf(spec, item, depth + 1);
}
if(item && typeof item.allOf !== 'undefined') {
var allOf = item.allOf;
if(_.isArray(allOf)) {
var output = _.cloneDeep(item);
delete output.allOf;
output['x-composed'] = true;
if (typeof item['x-resolved-from'] !== 'undefined') {
output['x-resolved-from'] = item['x-resolved-from'];
}
for(var i = 0; i < allOf.length; i++) {
var component = allOf[i];
var source = 'self';
if(typeof component['x-resolved-from'] !== 'undefined') {
source = component['x-resolved-from'][0];
}
for(var part in component) {
if(!output.hasOwnProperty(part)) {
output[part] = _.cloneDeep(component[part]);
if(part === 'properties') {
for(name in output[part]) {
output[part][name]['x-resolved-from'] = source;
}
}
}
else {
if(part === 'properties') {
var properties = component[part];
for(name in properties) {
output.properties[name] = _.cloneDeep(properties[name]);
var resolvedFrom = properties[name]['x-resolved-from'];
if (typeof resolvedFrom === 'undefined' || resolvedFrom === 'self') {
resolvedFrom = source;
}
output.properties[name]['x-resolved-from'] = resolvedFrom;
}
}
else if(part === 'required') {
// merge & dedup the required array
var a = output.required.concat(component[part]);
for(var k = 0; k < a.length; ++k) {
for(var j = k + 1; j < a.length; ++j) {
if(a[k] === a[j]) { a.splice(j--, 1); }
}
}
output.required = a;
}
else if(part === 'x-resolved-from') {
output['x-resolved-from'].push(source);
}
else {
// TODO: need to merge this property
// console.log('what to do with ' + part)
}
}
}
}
obj[key] = output;
}
}
}
};
},{"./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){
'use strict';
var Helpers = require('./helpers');
var _ = {
isPlainObject: require('lodash-compat/lang/isPlainObject'),
isUndefined: require('lodash-compat/lang/isUndefined'),
isArray: require('lodash-compat/lang/isArray'),
isObject: require('lodash-compat/lang/isObject'),
isEmpty: require('lodash-compat/lang/isEmpty'),
map: require('lodash-compat/collection/map'),
indexOf: require('lodash-compat/array/indexOf'),
cloneDeep: require('lodash-compat/lang/cloneDeep'),
keys: require('lodash-compat/object/keys'),
forEach: require('lodash-compat/collection/forEach')
};
var optionHtml = module.exports.optionHtml = function (label, value) {
return '<tr><td class="optionName">' + label + ':</td><td>' + value + '</td></tr>';
};
module.exports.typeFromJsonSchema = function (type, format) {
var str;
if (type === 'integer' && format === 'int32') {
str = 'integer';
} else if (type === 'integer' && format === 'int64') {
str = 'long';
} else if (type === 'integer' && typeof format === 'undefined') {
str = 'long';
} else if (type === 'string' && format === 'date-time') {
str = 'date-time';
} else if (type === 'string' && format === 'date') {
str = 'date';
} else if (type === 'number' && format === 'float') {
str = 'float';
} else if (type === 'number' && format === 'double') {
str = 'double';
} else if (type === 'number' && typeof format === 'undefined') {
str = 'double';
} else if (type === 'boolean') {
str = 'boolean';
} else if (type === 'string') {
str = 'string';
}
return str;
};
var getStringSignature = module.exports.getStringSignature = function (obj, baseComponent) {
var str = '';
if (typeof obj.$ref !== 'undefined') {
str += Helpers.simpleRef(obj.$ref);
} else if (typeof obj.type === 'undefined') {
str += 'object';
} else if (obj.type === 'array') {
if (baseComponent) {
str += getStringSignature((obj.items || obj.$ref || {}));
} else {
str += 'Array[';
str += getStringSignature((obj.items || obj.$ref || {}));
str += ']';
}
} else if (obj.type === 'integer' && obj.format === 'int32') {
str += 'integer';
} else if (obj.type === 'integer' && obj.format === 'int64') {
str += 'long';
} else if (obj.type === 'integer' && typeof obj.format === 'undefined') {
str += 'long';
} else if (obj.type === 'string' && obj.format === 'date-time') {
str += 'date-time';
} else if (obj.type === 'string' && obj.format === 'date') {
str += 'date';
} else if (obj.type === 'string' && typeof obj.format === 'undefined') {
str += 'string';
} else if (obj.type === 'number' && obj.format === 'float') {
str += 'float';
} else if (obj.type === 'number' && obj.format === 'double') {
str += 'double';
} else if (obj.type === 'number' && typeof obj.format === 'undefined') {
str += 'double';
} else if (obj.type === 'boolean') {
str += 'boolean';
} else if (obj.$ref) {
str += Helpers.simpleRef(obj.$ref);
} else {
str += obj.type;
}
return str;
};
var schemaToJSON = module.exports.schemaToJSON = function (schema, models, modelsToIgnore, modelPropertyMacro) {
// Resolve the schema (Handle nested schemas)
schema = Helpers.resolveSchema(schema);
if(typeof modelPropertyMacro !== 'function') {
modelPropertyMacro = function(prop){
return (prop || {}).default;
};
}
modelsToIgnore= modelsToIgnore || {};
var type = schema.type || 'object';
var format = schema.format;
var model;
var output;
if (!_.isUndefined(schema.example)) {
output = schema.example;
} else if (_.isUndefined(schema.items) && _.isArray(schema.enum)) {
output = schema.enum[0];
}
if (_.isUndefined(output)) {
if (schema.$ref) {
model = models[Helpers.simpleRef(schema.$ref)];
if (!_.isUndefined(model)) {
if (_.isUndefined(modelsToIgnore[model.name])) {
modelsToIgnore[model.name] = model;
output = schemaToJSON(model.definition, models, modelsToIgnore, modelPropertyMacro);
delete modelsToIgnore[model.name];
} else {
if (model.type === 'array') {
output = [];
} else {
output = {};
}
}
}
} else if (!_.isUndefined(schema.default)) {
output = schema.default;
} else if (type === 'string') {
if (format === 'date-time') {
output = new Date().toISOString();
} else if (format === 'date') {
output = new Date().toISOString().split('T')[0];
} else {
output = 'string';
}
} else if (type === 'integer') {
output = 0;
} else if (type === 'number') {
output = 0.0;
} else if (type === 'boolean') {
output = true;
} else if (type === 'object') {
output = {};
_.forEach(schema.properties, function (property, name) {
var cProperty = _.cloneDeep(property);
// Allow macro to set the default value
cProperty.default = modelPropertyMacro(property);
output[name] = schemaToJSON(cProperty, models, modelsToIgnore, modelPropertyMacro);
});
} else if (type === 'array') {
output = [];
if (_.isArray(schema.items)) {
_.forEach(schema.items, function (item) {
output.push(schemaToJSON(item, models, modelsToIgnore, modelPropertyMacro));
});
} else if (_.isPlainObject(schema.items)) {
output.push(schemaToJSON(schema.items, models, modelsToIgnore, modelPropertyMacro));
} else if (_.isUndefined(schema.items)) {
output.push({});
} else {
Helpers.log('Array type\'s \'items\' property is not an array or an object, cannot process');
}
}
}
return output;
};
module.exports.schemaToHTML =function (name, schema, models, modelPropertyMacro) {
var strongOpen = '<span class="strong">';
var strongClose = '</span>';
// Allow for ignoring the 'name' argument.... shifting the rest
if(_.isObject(arguments[0])) {
name = void 0;
schema = arguments[0];
models = arguments[1];
modelPropertyMacro = arguments[2];
}
models = models || {};
// Resolve the schema (Handle nested schemas)
schema = Helpers.resolveSchema(schema);
// Return for empty object
if(_.isEmpty(schema)) {
return strongOpen + 'Empty' + strongClose;
}
// Dereference $ref from 'models'
if(typeof schema.$ref === 'string') {
name = Helpers.simpleRef(schema.$ref);
schema = models[name];
if(typeof schema === 'undefined')
{
return strongOpen + name + ' is not defined!' + strongClose;
}
}
if(typeof name !== 'string') {
name = schema.title || 'Inline Model';
}
// If we are a Model object... adjust accordingly
if(schema.definition) {
schema = schema.definition;
}
if(typeof modelPropertyMacro !== 'function') {
modelPropertyMacro = function(prop){
return (prop || {}).default;
};
}
var references = {};
var seenModels = [];
var inlineModels = 0;
// Generate current HTML
var html = processModel(schema, name);
// Generate references HTML
while (_.keys(references).length > 0) {
/* jshint ignore:start */
_.forEach(references, function (schema, name) {
var seenModel = _.indexOf(seenModels, name) > -1;
delete references[name];
if (!seenModel) {
seenModels.push(name);
html += '<br />' + processModel(schema, name);
}
});
/* jshint ignore:end */
}
return html;
/////////////////////////////////
function addReference(schema, name, skipRef) {
var modelName = name;
var model;
if (schema.$ref) {
modelName = schema.title || Helpers.simpleRef(schema.$ref);
model = models[modelName];
} else if (_.isUndefined(name)) {
modelName = schema.title || 'Inline Model ' + (++inlineModels);
model = {definition: schema};
}
if (skipRef !== true) {
references[modelName] = _.isUndefined(model) ? {} : model.definition;
}
return modelName;
}
function primitiveToHTML(schema) {
var html = '<span class="propType">';
var type = schema.type || 'object';
if (schema.$ref) {
html += addReference(schema, Helpers.simpleRef(schema.$ref));
} else if (type === 'object') {
if (!_.isUndefined(schema.properties)) {
html += addReference(schema);
} else {
html += 'object';
}
} else if (type === 'array') {
html += 'Array[';
if (_.isArray(schema.items)) {
html += _.map(schema.items, addReference).join(',');
} else if (_.isPlainObject(schema.items)) {
if (_.isUndefined(schema.items.$ref)) {
if (!_.isUndefined(schema.items.type) && _.indexOf(['array', 'object'], schema.items.type) === -1) {
html += schema.items.type;
} else {
html += addReference(schema.items);
}
} else {
html += addReference(schema.items, Helpers.simpleRef(schema.items.$ref));
}
} else {
Helpers.log('Array type\'s \'items\' schema is not an array or an object, cannot process');
html += 'object';
}
html += ']';
} else {
html += schema.type;
}
html += '</span>';
return html;
}
function primitiveToOptionsHTML(schema, html) {
var options = '';
var type = schema.type || 'object';
var isArray = type === 'array';
if (isArray) {
if (_.isPlainObject(schema.items) && !_.isUndefined(schema.items.type)) {
type = schema.items.type;
} else {
type = 'object';
}
}
if (!_.isUndefined(schema.default)) {
options += optionHtml('Default', schema.default);
}
switch (type) {
case 'string':
if (schema.minLength) {
options += optionHtml('Min. Length', schema.minLength);
}
if (schema.maxLength) {
options += optionHtml('Max. Length', schema.maxLength);
}
if (schema.pattern) {
options += optionHtml('Reg. Exp.', schema.pattern);
}
break;
case 'integer':
case 'number':
if (schema.minimum) {
options += optionHtml('Min. Value', schema.minimum);
}
if (schema.exclusiveMinimum) {
options += optionHtml('Exclusive Min.', 'true');
}
if (schema.maximum) {
options += optionHtml('Max. Value', schema.maximum);
}
if (schema.exclusiveMaximum) {
options += optionHtml('Exclusive Max.', 'true');
}
if (schema.multipleOf) {
options += optionHtml('Multiple Of', schema.multipleOf);
}
break;
}
if (isArray) {
if (schema.minItems) {
options += optionHtml('Min. Items', schema.minItems);
}
if (schema.maxItems) {
options += optionHtml('Max. Items', schema.maxItems);
}
if (schema.uniqueItems) {
options += optionHtml('Unique Items', 'true');
}
if (schema.collectionFormat) {
options += optionHtml('Coll. Format', schema.collectionFormat);
}
}
if (_.isUndefined(schema.items)) {
if (_.isArray(schema.enum)) {
var enumString;
if (type === 'number' || type === 'integer') {
enumString = schema.enum.join(', ');
} else {
enumString = '"' + schema.enum.join('", "') + '"';
}
options += optionHtml('Enum', enumString);
}
}
if (options.length > 0) {
html = '<span class="propWrap">' + html + '<table class="optionsWrapper"><tr><th colspan="2">' + type + '</th></tr>' + options + '</table></span>';
}
return html;
}
function processModel(schema, name) {
var type = schema.type || 'object';
var isArray = schema.type === 'array';
var html = strongOpen + name + ' ' + (isArray ? '[' : '{') + strongClose;
if (name) {
seenModels.push(name);
}
if (isArray) {
if (_.isArray(schema.items)) {
html += '<div>' + _.map(schema.items, function (item) {
var type = item.type || 'object';
if (_.isUndefined(item.$ref)) {
if (_.indexOf(['array', 'object'], type) > -1) {
if (type === 'object' && _.isUndefined(item.properties)) {
return 'object';
} else {
return addReference(item);
}
} else {
return primitiveToOptionsHTML(item, type);
}
} else {
return addReference(item, Helpers.simpleRef(item.$ref));
}
}).join(',</div><div>');
} else if (_.isPlainObject(schema.items)) {
if (_.isUndefined(schema.items.$ref)) {
if (_.indexOf(['array', 'object'], schema.items.type || 'object') > -1) {
if ((_.isUndefined(schema.items.type) || schema.items.type === 'object') && _.isUndefined(schema.items.properties)) {
html += '<div>object</div>';
} else {
html += '<div>' + addReference(schema.items) + '</div>';
}
} else {
html += '<div>' + primitiveToOptionsHTML(schema.items, schema.items.type) + '</div>';
}
} else {
html += '<div>' + addReference(schema.items, Helpers.simpleRef(schema.items.$ref)) + '</div>';
}
} else {
Helpers.log('Array type\'s \'items\' property is not an array or an object, cannot process');
html += '<div>object</div>';
}
} else {
if (schema.$ref) {
html += '<div>' + addReference(schema, name) + '</div>';
} else if (type === 'object') {
if (_.isPlainObject(schema.properties)) {
var contents = _.map(schema.properties, function (property, name) {
var propertyIsRequired = (_.indexOf(schema.required, name) >= 0);
var cProperty = _.cloneDeep(property);
var requiredClass = propertyIsRequired ? 'required' : '';
var html = '<span class="propName ' + requiredClass + '">' + name + '</span> (';
var model;
var propDescription;
// Allow macro to set the default value
cProperty.default = modelPropertyMacro(cProperty);
// Resolve the schema (Handle nested schemas)
cProperty = Helpers.resolveSchema(cProperty);
propDescription = property.description || cProperty.description;
// We need to handle property references to primitives (Issue 339)
if (!_.isUndefined(cProperty.$ref)) {
model = models[Helpers.simpleRef(cProperty.$ref)];
if (!_.isUndefined(model) && _.indexOf([undefined, 'array', 'object'], model.definition.type) === -1) {
// Use referenced schema
cProperty = Helpers.resolveSchema(model.definition);
}
}
html += primitiveToHTML(cProperty);
if(!propertyIsRequired) {
html += ', <span class="propOptKey">optional</span>';
}
if(property.readOnly) {
html += ', <span class="propReadOnly">read only</span>';
}
html += ')';
if (!_.isUndefined(propDescription)) {
html += ': ' + '<span class="propDesc">' + propDescription + '</span>';
}
if (cProperty.enum) {
html += ' = <span class="propVals">[\'' + cProperty.enum.join('\', \'') + '\']</span>';
}
return '<div' + (property.readOnly ? ' class="readOnly"' : '') + '>' + primitiveToOptionsHTML(cProperty, html);
}).join(',</div>');
if (contents) {
html += contents + '</div>';
}
}
} else {
html += '<div>' + primitiveToOptionsHTML(schema, type) + '</div>';
}
}
return html + strongOpen + (isArray ? ']' : '}') + strongClose;
}
};
},{"./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){
'use strict';
var SwaggerHttp = require('./http');
var _ = {
isObject: require('lodash-compat/lang/isObject')
};
var SwaggerSpecConverter = module.exports = function () {
this.errors = [];
this.warnings = [];
this.modelMap = {};
};
SwaggerSpecConverter.prototype.setDocumentationLocation = function (location) {
this.docLocation = location;
};
/**
* converts a resource listing OR api declaration
**/
SwaggerSpecConverter.prototype.convert = function (obj, clientAuthorizations, opts, callback) {
// not a valid spec
if(!obj || !Array.isArray(obj.apis)) {
return this.finish(callback, null);
}
this.clientAuthorizations = clientAuthorizations;
// create a new swagger object to return
var swagger = { swagger: '2.0' };
swagger.originalVersion = obj.swaggerVersion;
// add the info
this.apiInfo(obj, swagger);
// add security definitions
this.securityDefinitions(obj, swagger);
// take basePath into account
if (obj.basePath) {
this.setDocumentationLocation(obj.basePath);
}
// see if this is a single-file swagger definition
var isSingleFileSwagger = false;
var i;
for(i = 0; i < obj.apis.length; i++) {
var api = obj.apis[i];
if(Array.isArray(api.operations)) {
isSingleFileSwagger = true;
}
}
if(isSingleFileSwagger) {
this.declaration(obj, swagger);
this.finish(callback, swagger);
}
else {
this.resourceListing(obj, swagger, opts, callback);
}
};
SwaggerSpecConverter.prototype.declaration = function(obj, swagger) {
var name, i, p, pos;
if(!obj.apis) {
return;
}
if (obj.basePath.indexOf('http://') === 0) {
p = obj.basePath.substring('http://'.length);
pos = p.indexOf('/');
if (pos > 0) {
swagger.host = p.substring(0, pos);
swagger.basePath = p.substring(pos);
}
else {
swagger.host = p;
swagger.basePath = '/';
}
} else if (obj.basePath.indexOf('https://') === 0) {
p = obj.basePath.substring('https://'.length);
pos = p.indexOf('/');
if (pos > 0) {
swagger.host = p.substring(0, pos);
swagger.basePath = p.substring(pos);
}
else {
swagger.host = p;
swagger.basePath = '/';
}
} else {
swagger.basePath = obj.basePath;
}
var resourceLevelAuth;
if(obj.authorizations) {
resourceLevelAuth = obj.authorizations;
}
if(obj.consumes) {
swagger.consumes = obj.consumes;
}
if(obj.produces) {
swagger.produces = obj.produces;
}
// build a mapping of id to name for 1.0 model resolutions
if(_.isObject(obj)) {
for(name in obj.models) {
var existingModel = obj.models[name];
var key = (existingModel.id || name);
this.modelMap[key] = name;
}
}
for(i = 0; i < obj.apis.length; i++) {
var api = obj.apis[i];
var path = api.path;
var operations = api.operations;
this.operations(path, obj.resourcePath, operations, resourceLevelAuth, swagger);
}
var models = obj.models || {};
this.models(models, swagger);
};
SwaggerSpecConverter.prototype.models = function(obj, swagger) {
if(!_.isObject(obj)) {
return;
}
var name;
swagger.definitions = swagger.definitions || {};
for(name in obj) {
var existingModel = obj[name];
var _required = [];
var schema = { properties: {}};
var propertyName;
for(propertyName in existingModel.properties) {
var existingProperty = existingModel.properties[propertyName];
var property = {};
this.dataType(existingProperty, property);
if(existingProperty.description) {
property.description = existingProperty.description;
}
if(existingProperty['enum']) {
property['enum'] = existingProperty['enum'];
}
if(typeof existingProperty.required === 'boolean' && existingProperty.required === true) {
_required.push(propertyName);
}
if(typeof existingProperty.required === 'string' && existingProperty.required === 'true') {
_required.push(propertyName);
}
schema.properties[propertyName] = property;
}
if(_required.length > 0) {
schema.required = _required;
} else {
schema.required = existingModel.required;
}
swagger.definitions[name] = schema;
}
};
SwaggerSpecConverter.prototype.extractTag = function(resourcePath) {
var pathString = resourcePath || 'default';
if(pathString.indexOf('http:') === 0 || pathString.indexOf('https:') === 0) {
pathString = pathString.split(['/']);
pathString = pathString[pathString.length -1].substring();
}
if(pathString.endsWith('.json')) {
pathString = pathString.substring(0, pathString.length - '.json'.length);
}
return pathString.replace('/','');
};
SwaggerSpecConverter.prototype.operations = function(path, resourcePath, obj, resourceLevelAuth, swagger) {
if(!Array.isArray(obj)) {
return;
}
var i;
if(!swagger.paths) {
swagger.paths = {};
}
var pathObj = swagger.paths[path] || {};
var tag = this.extractTag(resourcePath);
swagger.tags = swagger.tags || [];
var matched = false;
for(i = 0; i < swagger.tags.length; i++) {
var tagObject = swagger.tags[i];
if(tagObject.name === tag) {
matched = true;
}
}
if(!matched) {
swagger.tags.push({name: tag});
}
for(i = 0; i < obj.length; i++) {
var existingOperation = obj[i];
var method = (existingOperation.method || existingOperation.httpMethod).toLowerCase();
var operation = {tags: [tag]};
var existingAuthorizations = existingOperation.authorizations;
if(existingAuthorizations && Object.keys(existingAuthorizations).length === 0) {
existingAuthorizations = resourceLevelAuth;
}
if(typeof existingAuthorizations !== 'undefined') {
var scopesObject;
for(var key in existingAuthorizations) {
operation.security = operation.security || [];
var scopes = existingAuthorizations[key];
if(scopes) {
var securityScopes = [];
for(var j in scopes) {
securityScopes.push(scopes[j].scope);
}
scopesObject = {};
scopesObject[key] = securityScopes;
operation.security.push(scopesObject);
}
else {
scopesObject = {};
scopesObject[key] = [];
operation.security.push(scopesObject);
}
}
}
if(existingOperation.consumes) {
operation.consumes = existingOperation.consumes;
}
else if(swagger.consumes) {
operation.consumes = swagger.consumes;
}
if(existingOperation.produces) {
operation.produces = existingOperation.produces;
}
else if(swagger.produces) {
operation.produces = swagger.produces;
}
if(existingOperation.summary) {
operation.summary = existingOperation.summary;
}
if(existingOperation.notes) {
operation.description = existingOperation.notes;
}
if(existingOperation.nickname) {
operation.operationId = existingOperation.nickname;
}
if(existingOperation.deprecated) {
operation.deprecated = existingOperation.deprecated;
}
this.authorizations(existingAuthorizations, swagger);
this.parameters(operation, existingOperation.parameters, swagger);
this.responseMessages(operation, existingOperation, swagger);
pathObj[method] = operation;
}
swagger.paths[path] = pathObj;
};
SwaggerSpecConverter.prototype.responseMessages = function(operation, existingOperation) {
if(!_.isObject(existingOperation)) {
return;
}
// build default response from the operation (1.x)
var defaultResponse = {};
this.dataType(existingOperation, defaultResponse);
// TODO: look into the real problem of rendering responses in swagger-ui
// ....should reponseType have an implicit schema?
if(!defaultResponse.schema && defaultResponse.type) {
defaultResponse = {schema: defaultResponse};
}
operation.responses = operation.responses || {};
// grab from responseMessages (1.2)
var has200 = false;
if(Array.isArray(existingOperation.responseMessages)) {
var i;
var existingResponses = existingOperation.responseMessages;
for(i = 0; i < existingResponses.length; i++) {
var existingResponse = existingResponses[i];
var response = { description: existingResponse.message };
if(existingResponse.code === 200) {
has200 = true;
}
// Convert responseModel -> schema{$ref: responseModel}
if(existingResponse.responseModel) {
response.schema = {'$ref': '#/definitions/' + existingResponse.responseModel};
}
operation.responses['' + existingResponse.code] = response;
}
}
if(has200) {
operation.responses['default'] = defaultResponse;
}
else {
operation.responses['200'] = defaultResponse;
}
};
SwaggerSpecConverter.prototype.authorizations = function(obj) {
// TODO
if(!_.isObject(obj)) {
return;
}
};
SwaggerSpecConverter.prototype.parameters = function(operation, obj) {
if(!Array.isArray(obj)) {
return;
}
var i;
for(i = 0; i < obj.length; i++) {
var existingParameter = obj[i];
var parameter = {};
parameter.name = existingParameter.name;
parameter.description = existingParameter.description;
parameter.required = existingParameter.required;
parameter.in = existingParameter.paramType;
// per #168
if(parameter.in === 'body') {
parameter.name = 'body';
}
if(parameter.in === 'form') {
parameter.in = 'formData';
}
if(existingParameter.enum) {
parameter.enum = existingParameter.enum;
}
if(existingParameter.allowMultiple === true || existingParameter.allowMultiple === 'true') {
var innerType = {};
this.dataType(existingParameter, innerType);
parameter.type = 'array';
parameter.items = innerType;
if(existingParameter.allowableValues) {
var av = existingParameter.allowableValues;
if(av.valueType === 'LIST') {
parameter['enum'] = av.values;
}
}
}
else {
this.dataType(existingParameter, parameter);
}
if(typeof existingParameter.defaultValue !== 'undefined') {
parameter.default = existingParameter.defaultValue;
}
operation.parameters = operation.parameters || [];
operation.parameters.push(parameter);
}
};
SwaggerSpecConverter.prototype.dataType = function(source, target) {
if(!_.isObject(source)) {
return;
}
if(source.minimum) {
target.minimum = source.minimum;
}
if(source.maximum) {
target.maximum = source.maximum;
}
if (source.format) {
target.format = source.format;
}
// default can be 'false'
if(typeof source.defaultValue !== 'undefined') {
target.default = source.defaultValue;
}
var jsonSchemaType = this.toJsonSchema(source);
if(jsonSchemaType) {
target = target || {};
if(jsonSchemaType.type) {
target.type = jsonSchemaType.type;
}
if(jsonSchemaType.format) {
target.format = jsonSchemaType.format;
}
if(jsonSchemaType.$ref) {
target.schema = {$ref: jsonSchemaType.$ref};
}
if(jsonSchemaType.items) {
target.items = jsonSchemaType.items;
}
}
};
SwaggerSpecConverter.prototype.toJsonSchema = function(source) {
if(!source) {
return 'object';
}
var detectedType = (source.type || source.dataType || source.responseClass || '');
var lcType = detectedType.toLowerCase();
var format = (source.format || '').toLowerCase();
if(lcType.indexOf('list[') === 0) {
var innerType = detectedType.substring(5, detectedType.length - 1);
var jsonType = this.toJsonSchema({type: innerType});
return {type: 'array', items: jsonType};
} else if(lcType === 'int' || (lcType === 'integer' && format === 'int32')) {
{return {type: 'integer', format: 'int32'};}
} else if(lcType === 'long' || (lcType === 'integer' && format === 'int64')) {
{return {type: 'integer', format: 'int64'};}
} else if(lcType === 'integer') {
{return {type: 'integer', format: 'int64'};}
} else if(lcType === 'float' || (lcType === 'number' && format === 'float')) {
{return {type: 'number', format: 'float'};}
} else if(lcType === 'double' || (lcType === 'number' && format === 'double')) {
{return {type: 'number', format: 'double'};}
} else if((lcType === 'string' && format === 'date-time') || (lcType === 'date')) {
{return {type: 'string', format: 'date-time'};}
} else if(lcType === 'string') {
{return {type: 'string'};}
} else if(lcType === 'file') {
{return {type: 'file'};}
} else if(lcType === 'boolean') {
{return {type: 'boolean'};}
} else if(lcType === 'boolean') {
{return {type: 'boolean'};}
} else if(lcType === 'array' || lcType === 'list') {
if(source.items) {
var it = this.toJsonSchema(source.items);
return {type: 'array', items: it};
}
else {
return {type: 'array', items: {type: 'object'}};
}
} else if(source.$ref) {
return {$ref: this.modelMap[source.$ref] ? '#/definitions/' + this.modelMap[source.$ref] : source.$ref};
} else if(lcType === 'void' || lcType === '') {
{return {};}
} else if (this.modelMap[source.type]) {
// If this a model using `type` instead of `$ref`, that's fine.
return {$ref: '#/definitions/' + this.modelMap[source.type]};
} else {
// Unknown model type or 'object', pass it along.
return {type: source.type};
}
};
SwaggerSpecConverter.prototype.resourceListing = function(obj, swagger, opts, callback) {
var i;
var processedCount = 0; // jshint ignore:line
var self = this; // jshint ignore:line
var expectedCount = obj.apis.length;
var _swagger = swagger; // jshint ignore:line
var _opts = {};
if(opts && opts.requestInterceptor){
_opts.requestInterceptor = opts.requestInterceptor;
}
if(opts && opts.responseInterceptor){
_opts.responseInterceptor = opts.responseInterceptor;
}
var swaggerRequestHeaders = 'application/json';
if(opts && opts.swaggerRequestHeaders) {
swaggerRequestHeaders = opts.swaggerRequestHeaders;
}
if(expectedCount === 0) {
this.finish(callback, swagger);
}
for(i = 0; i < expectedCount; i++) {
var api = obj.apis[i];
var path = api.path;
var absolutePath = this.getAbsolutePath(obj.swaggerVersion, this.docLocation, path);
if(api.description) {
swagger.tags = swagger.tags || [];
swagger.tags.push({
name : this.extractTag(api.path),
description : api.description || ''
});
}
var http = {
url: absolutePath,
headers: { accept: swaggerRequestHeaders },
on: {},
method: 'get',
timeout: opts.timeout
};
/* jshint ignore:start */
http.on.response = function(data) {
processedCount += 1;
var obj = data.obj;
if(obj) {
self.declaration(obj, _swagger);
}
if(processedCount === expectedCount) {
self.finish(callback, _swagger);
}
};
http.on.error = function(data) {
console.error(data);
processedCount += 1;
if(processedCount === expectedCount) {
self.finish(callback, _swagger);
}
};
/* jshint ignore:end */
if(this.clientAuthorizations && typeof this.clientAuthorizations.apply === 'function') {
this.clientAuthorizations.apply(http);
}
new SwaggerHttp().execute(http, _opts);
}
};
SwaggerSpecConverter.prototype.getAbsolutePath = function(version, docLocation, path) {
if(version === '1.0') {
if(docLocation.endsWith('.json')) {
// get root path
var pos = docLocation.lastIndexOf('/');
if(pos > 0) {
docLocation = docLocation.substring(0, pos);
}
}
}
var location = docLocation;
if(path.indexOf('http:') === 0 || path.indexOf('https:') === 0) {
location = path;
}
else {
if(docLocation.endsWith('/')) {
location = docLocation.substring(0, docLocation.length - 1);
}
location += path;
}
location = location.replace('{format}', 'json');
return location;
};
SwaggerSpecConverter.prototype.securityDefinitions = function(obj, swagger) {
if(obj.authorizations) {
var name;
for(name in obj.authorizations) {
var isValid = false;
var securityDefinition = {
vendorExtensions: {}
};
var definition = obj.authorizations[name];
if(definition.type === 'apiKey') {
securityDefinition.type = 'apiKey';
securityDefinition.in = definition.passAs;
securityDefinition.name = definition.keyname || name;
isValid = true;
}
else if(definition.type === 'basicAuth') {
securityDefinition.type = 'basicAuth';
isValid = true;
}
else if(definition.type === 'oauth2') {
var existingScopes = definition.scopes || [];
var scopes = {};
var i;
for(i in existingScopes) {
var scope = existingScopes[i];
scopes[scope.scope] = scope.description;
}
securityDefinition.type = 'oauth2';
if(i > 0) {
securityDefinition.scopes = scopes;
}
if(definition.grantTypes) {
if(definition.grantTypes.implicit) {
var implicit = definition.grantTypes.implicit;
securityDefinition.flow = 'implicit';
securityDefinition.authorizationUrl = implicit.loginEndpoint;
isValid = true;
}
/* jshint ignore:start */
if(definition.grantTypes['authorization_code']) {
if(!securityDefinition.flow) {
// cannot set if flow is already defined
var authCode = definition.grantTypes['authorization_code'];
securityDefinition.flow = 'accessCode';
securityDefinition.authorizationUrl = authCode.tokenRequestEndpoint.url;
securityDefinition.tokenUrl = authCode.tokenEndpoint.url;
isValid = true;
}
}
/* jshint ignore:end */
}
}
if(isValid) {
swagger.securityDefinitions = swagger.securityDefinitions || {};
swagger.securityDefinitions[name] = securityDefinition;
}
}
}
};
SwaggerSpecConverter.prototype.apiInfo = function(obj, swagger) {
// info section
if(obj.info) {
var info = obj.info;
swagger.info = {};
if(info.contact) {
swagger.info.contact = {};
swagger.info.contact.email = info.contact;
}
if(info.description) {
swagger.info.description = info.description;
}
if(info.title) {
swagger.info.title = info.title;
}
if(info.termsOfServiceUrl) {
swagger.info.termsOfService = info.termsOfServiceUrl;
}
if(info.license || info.licenseUrl) {
swagger.license = {};
if(info.license) {
swagger.license.name = info.license;
}
if(info.licenseUrl) {
swagger.license.url = info.licenseUrl;
}
}
}
else {
this.warnings.push('missing info section');
}
};
SwaggerSpecConverter.prototype.finish = function (callback, obj) {
callback(obj);
};
},{"./http":5,"lodash-compat/lang/isObject":144}],9:[function(require,module,exports){
'use strict';
var log = require('../helpers').log;
var _ = {
isPlainObject: require('lodash-compat/lang/isPlainObject'),
isString: require('lodash-compat/lang/isString'),
};
var SchemaMarkup = require('../schema-markup.js');
var jsyaml = require('js-yaml');
var Model = module.exports = function (name, definition, models, modelPropertyMacro) {
this.definition = definition || {};
this.isArray = definition.type === 'array';
this.models = models || {};
this.name = name || definition.title || 'Inline Model';
this.modelPropertyMacro = modelPropertyMacro || function (property) {
return property.default;
};
return this;
};
// Note! This function will be removed in 2.2.x!
Model.prototype.createJSONSample = Model.prototype.getSampleValue = function (modelsToIgnore) {
modelsToIgnore = modelsToIgnore || {};
modelsToIgnore[this.name] = this;
// Response support
if (this.examples && _.isPlainObject(this.examples) && this.examples['application/json']) {
this.definition.example = this.examples['application/json'];
if (_.isString(this.definition.example)) {
this.definition.example = jsyaml.safeLoad(this.definition.example);
}
} else if (!this.definition.example) {
this.definition.example = this.examples;
}
return SchemaMarkup.schemaToJSON(this.definition, this.models, modelsToIgnore, this.modelPropertyMacro);
};
Model.prototype.getMockSignature = function () {
return SchemaMarkup.schemaToHTML(this.name, this.definition, this.models, this.modelPropertyMacro);
};
},{"../helpers":4,"../schema-markup.js":7,"js-yaml":19,"lodash-compat/lang/isPlainObject":145,"lodash-compat/lang/isString":146}],10:[function(require,module,exports){
'use strict';
var _ = {
cloneDeep: require('lodash-compat/lang/cloneDeep'),
isUndefined: require('lodash-compat/lang/isUndefined'),
isEmpty: require('lodash-compat/lang/isEmpty'),
isObject: require('lodash-compat/lang/isObject')
};
var helpers = require('../helpers');
var Model = require('./model');
var SwaggerHttp = require('../http');
var Q = require('q');
var Operation = module.exports = function (parent, scheme, operationId, httpMethod, path, args, definitions, models, clientAuthorizations) {
var errors = [];
parent = parent || {};
args = args || {};
if(parent && parent.options) {
this.client = parent.options.client || null;
this.requestInterceptor = parent.options.requestInterceptor || null;
this.responseInterceptor = parent.options.responseInterceptor || null;
this.requestAgent = parent.options.requestAgent;
}
this.authorizations = args.security;
this.basePath = parent.basePath || '/';
this.clientAuthorizations = clientAuthorizations;
this.consumes = args.consumes || parent.consumes || ['application/json'];
this.produces = args.produces || parent.produces || ['application/json'];
this.deprecated = args.deprecated;
this.description = args.description;
this.host = parent.host;
this.method = (httpMethod || errors.push('Operation ' + operationId + ' is missing method.'));
this.models = models || {};
this.nickname = (operationId || errors.push('Operations must have a nickname.'));
this.operation = args;
this.operations = {};
this.parameters = args !== null ? (args.parameters || []) : {};
this.parent = parent;
this.path = (path || errors.push('Operation ' + this.nickname + ' is missing path.'));
this.responses = (args.responses || {});
this.scheme = scheme || parent.scheme || 'http';
this.schemes = args.schemes || parent.schemes;
this.security = args.security || parent.security;
this.summary = args.summary || '';
this.timeout = parent.timeout;
this.type = null;
this.useJQuery = parent.useJQuery;
this.jqueryAjaxCache = parent.jqueryAjaxCache;
this.enableCookies = parent.enableCookies;
var key;
if(!this.host) {
if(typeof window !== 'undefined') {
this.host = window.location.host;
}
else {
this.host = 'localhost';
}
}
this.parameterMacro = parent.parameterMacro || function (operation, parameter) {
return parameter.default;
};
this.inlineModels = [];
if(this.basePath !== '/' && this.basePath.slice(-1) === '/') {
this.basePath = this.basePath.slice(0, -1);
}
if (typeof this.deprecated === 'string') {
switch(this.deprecated.toLowerCase()) {
case 'true': case 'yes': case '1': {
this.deprecated = true;
break;
}
case 'false': case 'no': case '0': case null: {
this.deprecated = false;
break;
}
default: this.deprecated = Boolean(this.deprecated);
}
}
var i, model;
if (definitions) {
// add to global models
for (key in definitions) {
model = new Model(key, definitions[key], this.models, parent.modelPropertyMacro);
if (model) {
this.models[key] = model;
}
}
}
else {
definitions = {};
}
for (i = 0; i < this.parameters.length; i++) {
var d, param = this.parameters[i];
// Allow macro to set the default value
param.default = this.parameterMacro(this, param);
if (param.type === 'array') {
param.isList = true;
param.allowMultiple = true;
}
var innerType = this.getType(param);
if (innerType && innerType.toString().toLowerCase() === 'boolean') {
param.allowableValues = {};
param.isList = true;
param['enum'] = [true, false]; // use actual primitives
}
for(key in param) {
helpers.extractExtensions(key, param);
}
if(typeof param['x-example'] !== 'undefined') {
d = param['x-example'];
param.default = d;
}
if(param['x-examples']) {
d = param['x-examples'].default;
if(typeof d !== 'undefined') {
param.default = d;
}
}
var enumValues = param['enum'] || (param.items && param.items['enum']);
if (typeof enumValues !== 'undefined') {
var id;
param.allowableValues = {};
param.allowableValues.values = [];
param.allowableValues.descriptiveValues = [];
for (id = 0; id < enumValues.length; id++) {
var value = enumValues[id];
var isDefault = (value === param.default || value+'' === param.default);
param.allowableValues.values.push(value);
// Always have string for descriptive values....
param.allowableValues.descriptiveValues.push({value : value+'', isDefault: isDefault});
}
}
if (param.type === 'array') {
innerType = [innerType];
if (typeof param.allowableValues === 'undefined') {
// can't show as a list if no values to select from
delete param.isList;
delete param.allowMultiple;
}
}
param.modelSignature = {type: innerType, definitions: this.models};
param.signature = this.getModelSignature(innerType, this.models).toString();
param.sampleJSON = this.getModelSampleJSON(innerType, this.models);
param.responseClassSignature = param.signature;
}
var keyname, defaultResponseCode, response, responses = this.responses;
if (responses['200']) {
response = responses['200'];
defaultResponseCode = '200';
} else if (responses['201']) {
response = responses['201'];
defaultResponseCode = '201';
} else if (responses['202']) {
response = responses['202'];
defaultResponseCode = '202';
} else if (responses['203']) {
response = responses['203'];
defaultResponseCode = '203';
} else if (responses['204']) {
response = responses['204'];
defaultResponseCode = '204';
} else if (responses['205']) {
response = responses['205'];
defaultResponseCode = '205';
} else if (responses['206']) {
response = responses['206'];
defaultResponseCode = '206';
} else if (responses['default']) {
response = responses['default'];
defaultResponseCode = 'default';
}
for(keyname in responses) {
helpers.extractExtensions(keyname, responses);
if(typeof keyname === 'string' && keyname.indexOf('x-') === -1) {
var responseObject = responses[keyname];
if(typeof responseObject === 'object' && typeof responseObject.headers === 'object') {
var headers = responseObject.headers;
for(var headerName in headers) {
var header = headers[headerName];
if(typeof header === 'object') {
for(var headerKey in header) {
helpers.extractExtensions(headerKey, header);
}
}
}
}
}
}
if (response) {
for(keyname in response) {
helpers.extractExtensions(keyname, response);
}
}
if (response && response.schema) {
var resolvedModel = this.resolveModel(response.schema, definitions);
var successResponse;
delete responses[defaultResponseCode];
if (resolvedModel) {
this.successResponse = {};
successResponse = this.successResponse[defaultResponseCode] = resolvedModel;
} else if (!response.schema.type || response.schema.type === 'object' || response.schema.type === 'array') {
// Inline model
this.successResponse = {};
successResponse = this.successResponse[defaultResponseCode] = new Model(undefined, response.schema || {}, this.models, parent.modelPropertyMacro);
} else {
// Primitive
this.successResponse = {};
successResponse = this.successResponse[defaultResponseCode] = response.schema;
}
if (successResponse) {
successResponse.vendorExtensions = response.vendorExtensions;
// Attach response properties
if (response.description) {
successResponse.description = response.description;
}
if (response.examples) {
successResponse.examples = response.examples;
}
if (response.headers) {
successResponse.headers = response.headers;
}
}
this.type = response;
}
if (errors.length > 0) {
if (this.resource && this.resource.api && this.resource.api.fail) {
this.resource.api.fail(errors);
}
}
return this;
};
Operation.prototype.isDefaultArrayItemValue = function(value, param) {
if (param.default && Array.isArray(param.default)) {
return param.default.indexOf(value) !== -1;
}
return value === param.default;
};
Operation.prototype.getType = function (param) {
var type = param.type;
var format = param.format;
var isArray = false;
var str;
if (type === 'integer' && format === 'int32') {
str = 'integer';
} else if (type === 'integer' && format === 'int64') {
str = 'long';
} else if (type === 'integer') {
str = 'integer';
} else if (type === 'string') {
if (format === 'date-time') {
str = 'date-time';
} else if (format === 'date') {
str = 'date';
} else {
str = 'string';
}
} else if (type === 'number' && format === 'float') {
str = 'float';
} else if (type === 'number' && format === 'double') {
str = 'double';
} else if (type === 'number') {
str = 'double';
} else if (type === 'boolean') {
str = 'boolean';
} else if (type === 'array') {
isArray = true;
if (param.items) {
str = this.getType(param.items);
}
} else if (type === 'file') {
str = 'file';
}
if (param.$ref) {
str = helpers.simpleRef(param.$ref);
}
var schema = param.schema;
if (schema) {
var ref = schema.$ref;
if (ref) {
ref = helpers.simpleRef(ref);
if (isArray) {
return [ ref ];
} else {
return ref;
}
} else {
// If inline schema, we add it our interal hash -> which gives us it's ID (int)
if(schema.type === 'object') {
return this.addInlineModel(schema);
}
return this.getType(schema);
}
}
if (isArray) {
return [ str ];
} else {
return str;
}
};
/**
* adds an inline schema (model) to a hash, where we can ref it later
* @param {object} schema a schema
* @return {number} the ID of the schema being added, or null
**/
Operation.prototype.addInlineModel = function (schema) {
var len = this.inlineModels.length;
var model = this.resolveModel(schema, {});
if(model) {
this.inlineModels.push(model);
return 'Inline Model '+len; // return string ref of the inline model (used with #getInlineModel)
}
return null; // report errors?
};
/**
* gets the internal ref to an inline model
* @param {string} inline_str a string reference to an inline model
* @return {Model} the model being referenced. Or null
**/
Operation.prototype.getInlineModel = function(inlineStr) {
if(/^Inline Model \d+$/.test(inlineStr)) {
var id = parseInt(inlineStr.substr('Inline Model'.length).trim(),10); //
var model = this.inlineModels[id];
return model;
}
// I'm returning null here, should I rather throw an error?
return null;
};
Operation.prototype.resolveModel = function (schema, definitions) {
if (typeof schema.$ref !== 'undefined') {
var ref = schema.$ref;
if (ref.indexOf('#/definitions/') === 0) {
ref = ref.substring('#/definitions/'.length);
}
if (definitions[ref]) {
return new Model(ref, definitions[ref], this.models, this.parent.modelPropertyMacro);
}
// schema must at least be an object to get resolved to an inline Model
} else if (schema && typeof schema === 'object' &&
(schema.type === 'object' || _.isUndefined(schema.type))) {
return new Model(undefined, schema, this.models, this.parent.modelPropertyMacro);
}
return null;
};
Operation.prototype.help = function (dontPrint) {
var out = this.nickname + ': ' + this.summary + '\n';
for (var i = 0; i < this.parameters.length; i++) {
var param = this.parameters[i];
var typeInfo = param.signature;
out += '\n * ' + param.name + ' (' + typeInfo + '): ' + param.description;
}
if (typeof dontPrint === 'undefined') {
helpers.log(out);
}
return out;
};
Operation.prototype.getModelSignature = function (type, definitions) {
var isPrimitive, listType;
if (type instanceof Array) {
listType = true;
type = type[0];
}
// Convert undefined to string of 'undefined'
if (typeof type === 'undefined') {
type = 'undefined';
isPrimitive = true;
} else if (definitions[type]){
// a model def exists?
type = definitions[type]; /* Model */
isPrimitive = false;
} else if (this.getInlineModel(type)) {
type = this.getInlineModel(type); /* Model */
isPrimitive = false;
} else {
// We default to primitive
isPrimitive = true;
}
if (isPrimitive) {
if (listType) {
return 'Array[' + type + ']';
} else {
return type.toString();
}
} else {
if (listType) {
return 'Array[' + type.getMockSignature() + ']';
} else {
return type.getMockSignature();
}
}
};
Operation.prototype.supportHeaderParams = function () {
return true;
};
Operation.prototype.supportedSubmitMethods = function () {
return this.parent.supportedSubmitMethods;
};
Operation.prototype.getHeaderParams = function (args) {
var headers = this.setContentTypes(args, {});
var headerParamsByLowerCase = {};
for (var i = 0; i < this.parameters.length; i++) {
var param = this.parameters[i];
if (param.in === 'header') {
headerParamsByLowerCase[param.name.toLowerCase()] = param;
}
}
for (var arg in args) {
var headerParam = headerParamsByLowerCase[arg.toLowerCase()];
if (typeof headerParam !== 'undefined') {
var value = args[arg];
if (Array.isArray(value)) {
value = value.toString();
}
headers[headerParam.name] = value;
}
}
return headers;
};
Operation.prototype.urlify = function (args, maskPasswords) {
var formParams = {};
var requestUrl = this.path.replace(/#.*/, ''); // remove URL fragment
var querystring = ''; // grab params from the args, build the querystring along the way
for (var i = 0; i < this.parameters.length; i++) {
var param = this.parameters[i];
if (typeof args[param.name] !== 'undefined') {
var isPassword;
if(param.type === 'string' && param.format === 'password' && maskPasswords) {
isPassword = true;
}
if (param.in === 'path') {
var reg = new RegExp('\{' + param.name + '\}', 'gi');
var value = args[param.name];
if (Array.isArray(value)) {
value = this.encodePathCollection(param.collectionFormat, param.name, value, isPassword);
} else {
value = this.encodePathParam(value, isPassword);
}
requestUrl = requestUrl.replace(reg, value);
} else if (param.in === 'query' && typeof args[param.name] !== 'undefined') {
if (querystring === '' && requestUrl.indexOf('?') < 0) {
querystring += '?';
} else {
querystring += '&';
}
if (typeof param.collectionFormat !== 'undefined') {
var qp = args[param.name];
if (Array.isArray(qp)) {
querystring += this.encodeQueryCollection(param.collectionFormat, param.name, qp, isPassword);
} else {
querystring += this.encodeQueryKey(param.name) + '=' + this.encodeQueryParam(args[param.name], isPassword);
}
} else {
querystring += this.encodeQueryKey(param.name) + '=' + this.encodeQueryParam(args[param.name], isPassword);
}
} else if (param.in === 'formData') {
formParams[param.name] = args[param.name];
}
}
}
var url = this.scheme + '://' + this.host;
if (this.basePath !== '/') {
url += this.basePath;
}
return url + requestUrl + querystring;
};
Operation.prototype.getMissingParams = function (args) {
var missingParams = []; // check required params, track the ones that are missing
var i;
for (i = 0; i < this.parameters.length; i++) {
var param = this.parameters[i];
if (param.required === true) {
if (typeof args[param.name] === 'undefined') {
missingParams = param.name;
}
}
}
return missingParams;
};
Operation.prototype.getBody = function (headers, args, opts) {
var formParams = {}, hasFormParams, param, body, key, value, hasBody = false;
// look at each param and put form params in an object
for (var i = 0; i < this.parameters.length; i++) {
param = this.parameters[i];
if (typeof args[param.name] !== 'undefined') {
var isPassword;
if(param.type === 'string' && param.format === 'password') {
isPassword = 'password';
}
if (param.in === 'body') {
body = args[param.name];
} else if (param.in === 'formData') {
formParams[param.name] = {
param: param,
value: args[param.name],
password: isPassword
};
hasFormParams = true;
}
}
else {
if(param.in === 'body') {
hasBody = true;
}
}
}
// if body is null and hasBody is true, AND a JSON body is requested, send empty {}
if(hasBody && typeof body === 'undefined') {
var contentType = headers['Content-Type'];
if(contentType && contentType.indexOf('application/json') === 0) {
body = '{}';
}
}
var isMultiPart = false;
if(headers['Content-Type'] && headers['Content-Type'].indexOf('multipart/form-data') >= 0) {
isMultiPart = true;
}
// handle form params
if (hasFormParams && !isMultiPart) {
var encoded = '';
for (key in formParams) {
param = formParams[key].param;
value = formParams[key].value;
var password;
if(opts && opts.maskPasswords) {
password = formParams[key].password;
}
if (typeof value !== 'undefined') {
if (Array.isArray(value)) {
if (encoded !== '') {
encoded += '&';
}
encoded += this.encodeQueryCollection(param.collectionFormat, key, value, password);
}
else {
if (encoded !== '') {
encoded += '&';
}
encoded += encodeURIComponent(key) + '=' + mask(encodeURIComponent(value), password);
}
}
}
body = encoded;
} else if (isMultiPart) {
var bodyParam;
if (typeof FormData === 'function') {
bodyParam = new FormData();
bodyParam.type = 'formData';
for (key in formParams) {
param = formParams[key].param;
value = args[key];
if (typeof value !== 'undefined') {
if({}.toString.apply(value) === '[object File]') {
bodyParam.append(key, value);
}
else if (value.type === 'file' && value.value) {
bodyParam.append(key, value.value);
} else {
if (Array.isArray(value)) {
if(param.collectionFormat === 'multi') {
bodyParam.delete(key);
for(var v in value) {
bodyParam.append(key, value[v]);
}
}
else {
bodyParam.append(key, this.encodeQueryCollection(param.collectionFormat, key, value).split('=').slice(1).join('='));
}
}
else {
bodyParam.append(key, value);
}
}
}
}
body = bodyParam;
}
else {
bodyParam = {};
for (key in formParams) {
value = args[key];
if (Array.isArray(value)) {
var delimeter;
var format = param.collectionFormat || 'multi';
if(format === 'ssv') {
delimeter = ' ';
}
else if(format === 'pipes') {
delimeter = '|';
}
else if(format === 'tsv') {
delimeter = '\t';
}
else if(format === 'multi') {
bodyParam[key] = value;
break;
}
else {
delimeter = ',';
}
var data;
value.forEach(function(v) {
if(data) {
data += delimeter;
}
else {
data = '';
}
data += v;
});
bodyParam[key] = data;
}
else {
bodyParam[key] = value;
}
}
body = bodyParam;
}
headers['Content-Type'] = 'multipart/form-data';
}
return body;
};
/**
* gets sample response for a single operation
**/
Operation.prototype.getModelSampleJSON = function (type, models) {
var listType, sampleJson, innerType;
models = models || {};
listType = (type instanceof Array);
innerType = listType ? type[0] : type;
if(models[innerType]) {
sampleJson = models[innerType].createJSONSample();
} else if (this.getInlineModel(innerType)){
sampleJson = this.getInlineModel(innerType).createJSONSample(); // may return null, if type isn't correct
}
if (sampleJson) {
sampleJson = listType ? [sampleJson] : sampleJson;
if (typeof sampleJson === 'string') {
return sampleJson;
} else if (_.isObject(sampleJson)) {
var t = sampleJson;
if (sampleJson instanceof Array && sampleJson.length > 0) {
t = sampleJson[0];
}
if (t.nodeName && typeof t === 'Node') {
var xmlString = new XMLSerializer().serializeToString(t);
return this.formatXml(xmlString);
} else {
return JSON.stringify(sampleJson, null, 2);
}
} else {
return sampleJson;
}
}
};
/**
* legacy binding
**/
Operation.prototype.do = function (args, opts, callback, error, parent) {
return this.execute(args, opts, callback, error, parent);
};
/**
* executes an operation
**/
Operation.prototype.execute = function (arg1, arg2, arg3, arg4, parent) {
var args = arg1 || {};
var opts = {}, success, error, deferred, timeout;
if (_.isObject(arg2)) {
opts = arg2;
success = arg3;
error = arg4;
}
timeout = typeof opts.timeout !== 'undefined' ? opts.timeout : this.timeout;
if(this.client) {
opts.client = this.client;
}
if(this.requestAgent) {
opts.requestAgent = this.requestAgent;
}
// add the request interceptor from parent, if none sent from client
if(!opts.requestInterceptor && this.requestInterceptor ) {
opts.requestInterceptor = this.requestInterceptor ;
}
if(!opts.responseInterceptor && this.responseInterceptor) {
opts.responseInterceptor = this.responseInterceptor;
}
if (typeof arg2 === 'function') {
success = arg2;
error = arg3;
}
if (this.parent.usePromise) {
deferred = Q.defer();
} else {
success = (success || this.parent.defaultSuccessCallback || helpers.log);
error = (error || this.parent.defaultErrorCallback || helpers.log);
}
if (typeof opts.useJQuery === 'undefined') {
opts.useJQuery = this.useJQuery;
}
if (typeof opts.jqueryAjaxCache === 'undefined') {
opts.jqueryAjaxCache = this.jqueryAjaxCache;
}
if (typeof opts.enableCookies === 'undefined') {
opts.enableCookies = this.enableCookies;
}
var missingParams = this.getMissingParams(args);
if (missingParams.length > 0) {
var message = 'missing required params: ' + missingParams;
helpers.fail(message);
if (this.parent.usePromise) {
deferred.reject(message);
return deferred.promise;
} else {
error(message, parent);
return {};
}
}
var allHeaders = this.getHeaderParams(args);
var contentTypeHeaders = this.setContentTypes(args, opts);
var headers = {}, attrname;
for (attrname in allHeaders) { headers[attrname] = allHeaders[attrname]; }
for (attrname in contentTypeHeaders) { headers[attrname] = contentTypeHeaders[attrname]; }
var body = this.getBody(contentTypeHeaders, args, opts);
var url = this.urlify(args, opts.maskPasswords);
if(url.indexOf('.{format}') > 0) {
if(headers) {
var format = headers.Accept || headers.accept;
if(format && format.indexOf('json') > 0) {
url = url.replace('.{format}', '.json');
}
else if(format && format.indexOf('xml') > 0) {
url = url.replace('.{format}', '.xml');
}
}
}
var obj = {
url: url,
method: this.method.toUpperCase(),
body: body,
enableCookies: opts.enableCookies,
useJQuery: opts.useJQuery,
jqueryAjaxCache: opts.jqueryAjaxCache,
deferred: deferred,
headers: headers,
clientAuthorizations: opts.clientAuthorizations,
operation: this,
connectionAgent: this.connectionAgent,
on: {
response: function (response) {
if (deferred) {
deferred.resolve(response);
return deferred.promise;
} else {
return success(response, parent);
}
},
error: function (response) {
if (deferred) {
deferred.reject(response);
return deferred.promise;
} else {
return error(response, parent);
}
}
}
};
if (timeout) {
obj.timeout = timeout;
}
this.clientAuthorizations.apply(obj, this.operation.security);
if (opts.mock === true) {
return obj;
} else {
return new SwaggerHttp().execute(obj, opts);
}
};
function itemByPriority(col, itemPriority) {
// No priorities? return first...
if(_.isEmpty(itemPriority)) {
return col[0];
}
for (var i = 0, len = itemPriority.length; i < len; i++) {
if(col.indexOf(itemPriority[i]) > -1) {
return itemPriority[i];
}
}
// Otherwise return first
return col[0];
}
Operation.prototype.setContentTypes = function (args, opts) {
// default type
var allDefinedParams = this.parameters;
var body;
var consumes = args.parameterContentType || itemByPriority(this.consumes, ['application/json', 'application/yaml']);
var accepts = opts.responseContentType || itemByPriority(this.produces, ['application/json', 'application/yaml']);
var definedFileParams = [];
var definedFormParams = [];
var headers = {};
var i;
// get params from the operation and set them in definedFileParams, definedFormParams, headers
for (i = 0; i < allDefinedParams.length; i++) {
var param = allDefinedParams[i];
if (param.in === 'formData') {
if (param.type === 'file') {
definedFileParams.push(param);
} else {
definedFormParams.push(param);
}
} else if (param.in === 'header' && opts) {
var key = param.name;
var headerValue = opts[param.name];
if (typeof opts[param.name] !== 'undefined') {
headers[key] = headerValue;
}
} else if (param.in === 'body' && typeof args[param.name] !== 'undefined') {
body = args[param.name];
}
}
// if there's a body, need to set the consumes header via requestContentType
var hasBody = body || definedFileParams.length || definedFormParams.length;
if (this.method === 'post' || this.method === 'put' || this.method === 'patch' ||
((this.method === 'delete' || this.method === 'get') && hasBody)) {
if (opts.requestContentType) {
consumes = opts.requestContentType;
}
// if any form params, content type must be set
if (definedFormParams.length > 0) {
consumes = undefined;
if (opts.requestContentType) { // override if set
consumes = opts.requestContentType;
} else if (definedFileParams.length > 0) { // if a file, must be multipart/form-data
consumes = 'multipart/form-data';
} else {
if (this.consumes && this.consumes.length > 0) {
// use the consumes setting
for(var c in this.consumes) {
var chk = this.consumes[c];
if(chk.indexOf('application/x-www-form-urlencoded') === 0 || chk.indexOf('multipart/form-data') === 0) {
consumes = chk;
}
}
}
}
if(typeof consumes === 'undefined') {
// default to x-www-from-urlencoded
consumes = 'application/x-www-form-urlencoded';
}
}
}
else {
consumes = null;
}
if (consumes && this.consumes) {
if (this.consumes.indexOf(consumes) === -1) {
helpers.log('server doesn\'t consume ' + consumes + ', try ' + JSON.stringify(this.consumes));
}
}
if (!this.matchesAccept(accepts)) {
helpers.log('server can\'t produce ' + accepts);
}
if ((consumes && body !== '') || (consumes === 'application/x-www-form-urlencoded')) {
headers['Content-Type'] = consumes;
}
else if(this.consumes && this.consumes.length > 0 && this.consumes[0] === 'application/x-www-form-urlencoded') {
headers['Content-Type'] = this.consumes[0];
}
if (accepts) {
headers.Accept = accepts;
}
return headers;
};
/**
* Returns true if the request accepts header matches anything in this.produces.
* If this.produces contains * / *, ignore the accept header.
* @param {string=} accepts The client request accept header.
* @return {boolean}
*/
Operation.prototype.matchesAccept = function(accepts) {
// no accepts or produces, no problem!
if (!accepts || !this.produces) {
return true;
}
return this.produces.indexOf(accepts) !== -1 || this.produces.indexOf('*/*') !== -1;
};
Operation.prototype.asCurl = function (args1, args2) {
var opts = {mock: true, maskPasswords: true};
if (typeof args2 === 'object') {
for (var argKey in args2) {
opts[argKey] = args2[argKey];
}
}
var obj = this.execute(args1, opts);
this.clientAuthorizations.apply(obj, this.operation.security);
var results = [];
results.push('-X ' + this.method.toUpperCase());
if (typeof obj.headers !== 'undefined') {
var key;
for (key in obj.headers) {
var value = obj.headers[key];
if(typeof value === 'string'){
value = value.replace(/\'/g, '\\u0027');
}
results.push('--header \'' + key + ': ' + value + '\'');
}
}
var isFormData = false;
var isMultipart = false;
var type = obj.headers['Content-Type'];
if(type && type.indexOf('application/x-www-form-urlencoded') === 0) {
isFormData = true;
}
else if (type && type.indexOf('multipart/form-data') === 0) {
isFormData = true;
isMultipart = true;
}
if (obj.body) {
var body;
if (_.isObject(obj.body)) {
if(isMultipart) {
isMultipart = true;
// add the form data
for(var i = 0; i < this.parameters.length; i++) {
var parameter = this.parameters[i];
if(parameter.in === 'formData') {
if (!body) {
body = '';
}
var paramValue;
if(typeof FormData === 'function' && obj.body instanceof FormData) {
paramValue = obj.body.getAll(parameter.name);
}
else {
paramValue = obj.body[parameter.name];
}
if (paramValue) {
if (parameter.type === 'file') {
if(paramValue.name) {
body += '-F ' + parameter.name + '=@"' + paramValue.name + '" ';
}
}
else {
if (Array.isArray(paramValue)) {
if(parameter.collectionFormat === 'multi') {
for(var v in paramValue) {
body += '-F ' + this.encodeQueryKey(parameter.name) + '=' + mask(paramValue[v], parameter.format) + ' ';
}
}
else {
body += '-F ' + this.encodeQueryCollection(parameter.collectionFormat, parameter.name, mask(paramValue, parameter.format)) + ' ';
}
} else {
body += '-F ' + this.encodeQueryKey(parameter.name) + '=' + mask(paramValue, parameter.format) + ' ';
}
}
}
}
}
}
if(!body) {
body = JSON.stringify(obj.body);
}
} else {
body = obj.body;
}
// escape @ => %40, ' => %27
body = body.replace(/\'/g, '%27').replace(/\n/g, ' \\ \n ');
if(!isFormData) {
// escape & => %26
body = body.replace(/&/g, '%26');
}
if(isMultipart) {
results.push(body);
}
else {
results.push('-d \'' + body.replace(/@/g, '%40') + '\'');
}
}
return 'curl ' + (results.join(' ')) + ' \'' + obj.url + '\'';
};
Operation.prototype.encodePathCollection = function (type, name, value, maskPasswords) {
var encoded = '';
var i;
var separator = '';
if (type === 'ssv') {
separator = '%20';
} else if (type === 'tsv') {
separator = '%09';
} else if (type === 'pipes') {
separator = '|';
} else {
separator = ',';
}
for (i = 0; i < value.length; i++) {
if (i === 0) {
encoded = this.encodeQueryParam(value[i], maskPasswords);
} else {
encoded += separator + this.encodeQueryParam(value[i], maskPasswords);
}
}
return encoded;
};
Operation.prototype.encodeQueryCollection = function (type, name, value, maskPasswords) {
var encoded = '';
var i;
type = type || 'default';
if (type === 'default' || type === 'multi') {
for (i = 0; i < value.length; i++) {
if (i > 0) {encoded += '&';}
encoded += this.encodeQueryKey(name) + '=' + mask(this.encodeQueryParam(value[i]), maskPasswords);
}
} else {
var separator = '';
if (type === 'csv') {
separator = ',';
} else if (type === 'ssv') {
separator = '%20';
} else if (type === 'tsv') {
separator = '%09';
} else if (type === 'pipes') {
separator = '|';
} else if (type === 'brackets') {
for (i = 0; i < value.length; i++) {
if (i !== 0) {
encoded += '&';
}
encoded += this.encodeQueryKey(name) + '[]=' + mask(this.encodeQueryParam(value[i]), maskPasswords);
}
}
if (separator !== '') {
for (i = 0; i < value.length; i++) {
if (i === 0) {
encoded = this.encodeQueryKey(name) + '=' + this.encodeQueryParam(value[i]);
} else {
encoded += separator + this.encodeQueryParam(value[i]);
}
}
}
}
return encoded;
};
Operation.prototype.encodeQueryKey = function (arg) {
return encodeURIComponent(arg)
.replace('%5B','[').replace('%5D', ']').replace('%24', '$');
};
Operation.prototype.encodeQueryParam = function (arg, maskPasswords) {
if(maskPasswords) {
return "******";
}
return encodeURIComponent(arg);
};
/**
* TODO revisit, might not want to leave '/'
**/
Operation.prototype.encodePathParam = function (pathParam, maskPasswords) {
return encodeURIComponent(pathParam, maskPasswords);
};
var mask = function(value, format) {
if(typeof format === 'string' && format === 'password') {
return '******';
}
return value;
}
},{"../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){
'use strict';
var OperationGroup = module.exports = function (tag, description, externalDocs, operation) {
this.description = description;
this.externalDocs = externalDocs;
this.name = tag;
this.operation = operation;
this.operationsArray = [];
this.path = tag;
this.tag = tag;
};
OperationGroup.prototype.sort = function () {
};
},{}],12:[function(require,module,exports){
// shim for using process in browser
var process = module.exports = {};
var queue = [];
var draining = false;
function drainQueue() {
if (draining) {
return;
}
draining = true;
var currentQueue;
var len = queue.length;
while(len) {
currentQueue = queue;
queue = [];
var i = -1;
while (++i < len) {
currentQueue[i]();
}
len = queue.length;
}
draining = false;
}
process.nextTick = function (fun) {
queue.push(fun);
if (!draining) {
setTimeout(drainQueue, 0);
}
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
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');
};
// TODO(shtylman)
process.cwd = function () { return '/' };
process.chdir = function (dir) {
throw new Error('process.chdir is not supported');
};
process.umask = function() { return 0; };
},{}],13:[function(require,module,exports){
(function (Buffer){
(function () {
"use strict";
function btoa(str) {
var buffer
;
if (str instanceof Buffer) {
buffer = str;
} else {
buffer = new Buffer(str.toString(), 'binary');
}
return buffer.toString('base64');
}
module.exports = btoa;
}());
}).call(this,require("buffer").Buffer)
},{"buffer":14}],14:[function(require,module,exports){
/*!
* The buffer module from node.js, for the browser.
*
* @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
* @license MIT
*/
var base64 = require('base64-js')
var ieee754 = require('ieee754')
var isArray = require('is-array')
exports.Buffer = Buffer
exports.SlowBuffer = SlowBuffer
exports.INSPECT_MAX_BYTES = 50
Buffer.poolSize = 8192 // not used by this implementation
var rootParent = {}
/**
* If `Buffer.TYPED_ARRAY_SUPPORT`:
* === true Use Uint8Array implementation (fastest)
* === false Use Object implementation (most compatible, even IE6)
*
* Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
* Opera 11.6+, iOS 4.2+.
*
* Due to various browser bugs, sometimes the Object implementation will be used even
* when the browser supports typed arrays.
*
* Note:
*
* - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,
* See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
*
* - Safari 5-7 lacks support for changing the `Object.prototype.constructor` property
* on objects.
*
* - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
*
* - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
* incorrect length in some situations.
* We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they
* get the Object implementation, which is slower but behaves correctly.
*/
Buffer.TYPED_ARRAY_SUPPORT = (function () {
function Bar () {}
try {
var arr = new Uint8Array(1)
arr.foo = function () { return 42 }
arr.constructor = Bar
return arr.foo() === 42 && // typed array instances can be augmented
arr.constructor === Bar && // constructor can be set
typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
} catch (e) {
return false
}
})()
function kMaxLength () {
return Buffer.TYPED_ARRAY_SUPPORT
? 0x7fffffff
: 0x3fffffff
}
/**
* Class: Buffer
* =============
*
* The Buffer constructor returns instances of `Uint8Array` that are augmented
* with function properties for all the node `Buffer` API functions. We use
* `Uint8Array` so that square bracket notation works as expected -- it returns
* a single octet.
*
* By augmenting the instances, we can avoid modifying the `Uint8Array`
* prototype.
*/
function Buffer (arg) {
if (!(this instanceof Buffer)) {
// Avoid going through an ArgumentsAdaptorTrampoline in the common case.
if (arguments.length > 1) return new Buffer(arg, arguments[1])
return new Buffer(arg)
}
this.length = 0
this.parent = undefined
// Common case.
if (typeof arg === 'number') {
return fromNumber(this, arg)
}
// Slightly less common case.
if (typeof arg === 'string') {
return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8')
}
// Unusual.
return fromObject(this, arg)
}
function fromNumber (that, length) {
that = allocate(that, length < 0 ? 0 : checked(length) | 0)
if (!Buffer.TYPED_ARRAY_SUPPORT) {
for (var i = 0; i < length; i++) {
that[i] = 0
}
}
return that
}
function fromString (that, string, encoding) {
if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8'
// Assumption: byteLength() return value is always < kMaxLength.
var length = byteLength(string, encoding) | 0
that = allocate(that, length)
that.write(string, encoding)
return that
}
function fromObject (that, object) {
if (Buffer.isBuffer(object)) return fromBuffer(that, object)
if (isArray(object)) return fromArray(that, object)
if (object == null) {
throw new TypeError('must start with number, buffer, array or string')
}
if (typeof ArrayBuffer !== 'undefined') {
if (object.buffer instanceof ArrayBuffer) {
return fromTypedArray(that, object)
}
if (object instanceof ArrayBuffer) {
return fromArrayBuffer(that, object)
}
}
if (object.length) return fromArrayLike(that, object)
return fromJsonObject(that, object)
}
function fromBuffer (that, buffer) {
var length = checked(buffer.length) | 0
that = allocate(that, length)
buffer.copy(that, 0, 0, length)
return that
}
function fromArray (that, array) {
var length = checked(array.length) | 0
that = allocate(that, length)
for (var i = 0; i < length; i += 1) {
that[i] = array[i] & 255
}
return that
}
// Duplicate of fromArray() to keep fromArray() monomorphic.
function fromTypedArray (that, array) {
var length = checked(array.length) | 0
that = allocate(that, length)
// Truncating the elements is probably not what people expect from typed
// arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior
// of the old Buffer constructor.
for (var i = 0; i < length; i += 1) {
that[i] = array[i] & 255
}
return that
}
function fromArrayBuffer (that, array) {
if (Buffer.TYPED_ARRAY_SUPPORT) {
// Return an augmented `Uint8Array` instance, for best performance
array.byteLength
that = Buffer._augment(new Uint8Array(array))
} else {
// Fallback: Return an object instance of the Buffer class
that = fromTypedArray(that, new Uint8Array(array))
}
return that
}
function fromArrayLike (that, array) {
var length = checked(array.length) | 0
that = allocate(that, length)
for (var i = 0; i < length; i += 1) {
that[i] = array[i] & 255
}
return that
}
// Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object.
// Returns a zero-length buffer for inputs that don't conform to the spec.
function fromJsonObject (that, object) {
var array
var length = 0
if (object.type === 'Buffer' && isArray(object.data)) {
array = object.data
length = checked(array.length) | 0
}
that = allocate(that, length)
for (var i = 0; i < length; i += 1) {
that[i] = array[i] & 255
}
return that
}
function allocate (that, length) {
if (Buffer.TYPED_ARRAY_SUPPORT) {
// Return an augmented `Uint8Array` instance, for best performance
that = Buffer._augment(new Uint8Array(length))
} else {
// Fallback: Return an object instance of the Buffer class
that.length = length
that._isBuffer = true
}
var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1
if (fromPool) that.parent = rootParent
return that
}
function checked (length) {
// Note: cannot use `length < kMaxLength` here because that fails when
// length is NaN (which is otherwise coerced to zero.)
if (length >= kMaxLength()) {
throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
'size: 0x' + kMaxLength().toString(16) + ' bytes')
}
return length | 0
}
function SlowBuffer (subject, encoding) {
if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding)
var buf = new Buffer(subject, encoding)
delete buf.parent
return buf
}
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
var i = 0
var len = Math.min(x, y)
while (i < len) {
if (a[i] !== b[i]) break
++i
}
if (i !== len) {
x = a[i]
y = b[i]
}
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 'binary':
case 'base64':
case 'raw':
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 new Buffer(0)
}
var i
if (length === undefined) {
length = 0
for (i = 0; i < list.length; i++) {
length += list[i].length
}
}
var buf = new Buffer(length)
var pos = 0
for (i = 0; i < list.length; i++) {
var item = list[i]
item.copy(buf, pos)
pos += item.length
}
return buf
}
function byteLength (string, encoding) {
if (typeof string !== 'string') string = '' + string
var len = string.length
if (len === 0) return 0
// Use a for loop to avoid recursion
var loweredCase = false
for (;;) {
switch (encoding) {
case 'ascii':
case 'binary':
// Deprecated
case 'raw':
case 'raws':
return len
case 'utf8':
case 'utf-8':
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 // assume utf8
encoding = ('' + encoding).toLowerCase()
loweredCase = true
}
}
}
Buffer.byteLength = byteLength
// pre-set for values that may exist in the future
Buffer.prototype.length = undefined
Buffer.prototype.parent = undefined
function slowToString (encoding, start, end) {
var loweredCase = false
start = start | 0
end = end === undefined || end === Infinity ? this.length : end | 0
if (!encoding) encoding = 'utf8'
if (start < 0) start = 0
if (end > this.length) end = this.length
if (end <= start) return ''
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 'binary':
return binarySlice(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.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 (b) {
if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
if (this === b) return 0
return Buffer.compare(this, b)
}
Buffer.prototype.indexOf = function indexOf (val, byteOffset) {
if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff
else if (byteOffset < -0x80000000) byteOffset = -0x80000000
byteOffset >>= 0
if (this.length === 0) return -1
if (byteOffset >= this.length) return -1
// Negative offsets start from the end of the buffer
if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0)
if (typeof val === 'string') {
if (val.length === 0) return -1 // special case: looking for empty string always fails
return String.prototype.indexOf.call(this, val, byteOffset)
}
if (Buffer.isBuffer(val)) {
return arrayIndexOf(this, val, byteOffset)
}
if (typeof val === 'number') {
if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') {
return Uint8Array.prototype.indexOf.call(this, val, byteOffset)
}
return arrayIndexOf(this, [ val ], byteOffset)
}
function arrayIndexOf (arr, val, byteOffset) {
var foundIndex = -1
for (var i = 0; byteOffset + i < arr.length; i++) {
if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) {
if (foundIndex === -1) foundIndex = i
if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex
} else {
foundIndex = -1
}
}
return -1
}
throw new TypeError('val must be string, number or Buffer')
}
// `get` is deprecated
Buffer.prototype.get = function get (offset) {
console.log('.get() is deprecated. Access using array indexes instead.')
return this.readUInt8(offset)
}
// `set` is deprecated
Buffer.prototype.set = function set (v, offset) {
console.log('.set() is deprecated. Access using array indexes instead.')
return this.writeUInt8(v, offset)
}
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
}
}
// must be an even number of digits
var strLen = string.length
if (strLen % 2 !== 0) throw new Error('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)) throw new Error('Invalid hex string')
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 binaryWrite (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) {
// Buffer#write(string)
if (offset === undefined) {
encoding = 'utf8'
length = this.length
offset = 0
// Buffer#write(string, encoding)
} else if (length === undefined && typeof offset === 'string') {
encoding = offset
length = this.length
offset = 0
// Buffer#write(string, offset[, length][, encoding])
} else if (isFinite(offset)) {
offset = offset | 0
if (isFinite(length)) {
length = length | 0
if (encoding === undefined) encoding = 'utf8'
} else {
encoding = length
length = undefined
}
// legacy write(string, encoding, offset, length) - remove in v0.13
} else {
var swap = encoding
encoding = offset
offset = length | 0
length = swap
}
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 'binary':
return binaryWrite(this, string, offset, length)
case 'base64':
// Warning: maxLength not taken into account in base64Write
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 > 0xEF) ? 4
: (firstByte > 0xDF) ? 3
: (firstByte > 0xBF) ? 2
: 1
if (i + bytesPerSequence <= end) {
var secondByte, thirdByte, fourthByte, tempCodePoint
switch (bytesPerSequence) {
case 1:
if (firstByte < 0x80) {
codePoint = firstByte
}
break
case 2:
secondByte = buf[i + 1]
if ((secondByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
if (tempCodePoint > 0x7F) {
codePoint = tempCodePoint
}
}
break
case 3:
secondByte = buf[i + 1]
thirdByte = buf[i + 2]
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
codePoint = tempCodePoint
}
}
break
case 4:
secondByte = buf[i + 1]
thirdByte = buf[i + 2]
fourthByte = buf[i + 3]
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
codePoint = tempCodePoint
}
}
}
}
if (codePoint === null) {
// we did not generate a valid codePoint so insert a
// replacement char (U+FFFD) and advance only 1 byte
codePoint = 0xFFFD
bytesPerSequence = 1
} else if (codePoint > 0xFFFF) {
// encode to utf16 (surrogate pair dance)
codePoint -= 0x10000
res.push(codePoint >>> 10 & 0x3FF | 0xD800)
codePoint = 0xDC00 | codePoint & 0x3FF
}
res.push(codePoint)
i += bytesPerSequence
}
return decodeCodePointsArray(res)
}
// Based on http://stackoverflow.com/a/22747272/680742, the browser with
// the lowest limit is Chrome, with 0x10000 args.
// We go 1 magnitude less, for safety
var MAX_ARGUMENTS_LENGTH = 0x1000
function decodeCodePointsArray (codePoints) {
var len = codePoints.length
if (len <= MAX_ARGUMENTS_LENGTH) {
return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
}
// Decode in chunks to avoid "call stack size exceeded".
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] & 0x7F)
}
return ret
}
function binarySlice (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 = Buffer._augment(this.subarray(start, end))
} else {
var sliceLen = end - start
newBuf = new Buffer(sliceLen, undefined)
for (var i = 0; i < sliceLen; i++) {
newBuf[i] = this[i + start]
}
}
if (newBuf.length) newBuf.parent = this.parent || this
return newBuf
}
/*
* Need to make sure that buffer isn't trying to write out of bounds.
*/
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 *= 0x100)) {
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 *= 0x100)) {
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] * 0x1000000)
}
Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return (this[offset] * 0x1000000) +
((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 *= 0x100)) {
val += this[offset + i] * mul
}
mul *= 0x80
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)
var i = byteLength
var mul = 1
var val = this[offset + --i]
while (i > 0 && (mul *= 0x100)) {
val += this[offset + --i] * mul
}
mul *= 0x80
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] & 0x80)) return (this[offset])
return ((0xff - 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 & 0x8000) ? val | 0xFFFF0000 : 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 & 0x8000) ? val | 0xFFFF0000 : 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 must be a Buffer instance')
if (value > max || value < min) throw new RangeError('value 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) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
var mul = 1
var i = 0
this[offset] = value & 0xFF
while (++i < byteLength && (mul *= 0x100)) {
this[offset + i] = (value / mul) & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
value = +value
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
var i = byteLength - 1
var mul = 1
this[offset + i] = value & 0xFF
while (--i >= 0 && (mul *= 0x100)) {
this[offset + i] = (value / mul) & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
this[offset] = value
return offset + 1
}
function objectWriteUInt16 (buf, value, offset, littleEndian) {
if (value < 0) value = 0xffff + value + 1
for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) {
buf[offset + i] = (value & (0xff << (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, 0xffff, 0)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = value
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, 0xffff, 0)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value >>> 8)
this[offset + 1] = value
} else {
objectWriteUInt16(this, value, offset, false)
}
return offset + 2
}
function objectWriteUInt32 (buf, value, offset, littleEndian) {
if (value < 0) value = 0xffffffff + 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) & 0xff
}
}
Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset + 3] = (value >>> 24)
this[offset + 2] = (value >>> 16)
this[offset + 1] = (value >>> 8)
this[offset] = value
} 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, 0xffffffff, 0)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value >>> 24)
this[offset + 1] = (value >>> 16)
this[offset + 2] = (value >>> 8)
this[offset + 3] = value
} 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 = value < 0 ? 1 : 0
this[offset] = value & 0xFF
while (++i < byteLength && (mul *= 0x100)) {
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
}
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 = value < 0 ? 1 : 0
this[offset + i] = value & 0xFF
while (--i >= 0 && (mul *= 0x100)) {
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
if (value < 0) value = 0xff + value + 1
this[offset] = value
return offset + 1
}
Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = value
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, 0x7fff, -0x8000)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value >>> 8)
this[offset + 1] = value
} 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, 0x7fffffff, -0x80000000)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = value
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, 0x7fffffff, -0x80000000)
if (value < 0) value = 0xffffffff + 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
} else {
objectWriteUInt32(this, value, offset, false)
}
return offset + 4
}
function checkIEEE754 (buf, value, offset, ext, max, min) {
if (value > max || value < min) throw new RangeError('value is out of bounds')
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.4028234663852886e+38, -3.4028234663852886e+38)
}
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.7976931348623157E+308, -1.7976931348623157E+308)
}
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)
}
// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
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
// Copy 0 bytes; we're done
if (end === start) return 0
if (target.length === 0 || this.length === 0) return 0
// Fatal error conditions
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')
// Are we oob?
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) {
// descending copy from end
for (i = len - 1; i >= 0; i--) {
target[i + targetStart] = this[i + start]
}
} else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
// ascending copy from start
for (i = 0; i < len; i++) {
target[i + targetStart] = this[i + start]
}
} else {
target._set(this.subarray(start, start + len), targetStart)
}
return len
}
// fill(value, start=0, end=buffer.length)
Buffer.prototype.fill = function fill (value, start, end) {
if (!value) value = 0
if (!start) start = 0
if (!end) end = this.length
if (end < start) throw new RangeError('end < start')
// Fill 0 bytes; we're done
if (end === start) return
if (this.length === 0) return
if (start < 0 || start >= this.length) throw new RangeError('start out of bounds')
if (end < 0 || end > this.length) throw new RangeError('end out of bounds')
var i
if (typeof value === 'number') {
for (i = start; i < end; i++) {
this[i] = value
}
} else {
var bytes = utf8ToBytes(value.toString())
var len = bytes.length
for (i = start; i < end; i++) {
this[i] = bytes[i % len]
}
}
return this
}
/**
* Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance.
* Added in Node 0.12. Only available in browsers that support ArrayBuffer.
*/
Buffer.prototype.toArrayBuffer = function toArrayBuffer () {
if (typeof Uint8Array !== 'undefined') {
if (Buffer.TYPED_ARRAY_SUPPORT) {
return (new Buffer(this)).buffer
} else {
var buf = new Uint8Array(this.length)
for (var i = 0, len = buf.length; i < len; i += 1) {
buf[i] = this[i]
}
return buf.buffer
}
} else {
throw new TypeError('Buffer.toArrayBuffer not supported in this browser')
}
}
// HELPER FUNCTIONS
// ================
var BP = Buffer.prototype
/**
* Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods
*/
Buffer._augment = function _augment (arr) {
arr.constructor = Buffer
arr._isBuffer = true
// save reference to original Uint8Array set method before overwriting
arr._set = arr.set
// deprecated
arr.get = BP.get
arr.set = BP.set
arr.write = BP.write
arr.toString = BP.toString
arr.toLocaleString = BP.toString
arr.toJSON = BP.toJSON
arr.equals = BP.equals
arr.compare = BP.compare
arr.indexOf = BP.indexOf
arr.copy = BP.copy
arr.slice = BP.slice
arr.readUIntLE = BP.readUIntLE
arr.readUIntBE = BP.readUIntBE
arr.readUInt8 = BP.readUInt8
arr.readUInt16LE = BP.readUInt16LE
arr.readUInt16BE = BP.readUInt16BE
arr.readUInt32LE = BP.readUInt32LE
arr.readUInt32BE = BP.readUInt32BE
arr.readIntLE = BP.readIntLE
arr.readIntBE = BP.readIntBE
arr.readInt8 = BP.readInt8
arr.readInt16LE = BP.readInt16LE
arr.readInt16BE = BP.readInt16BE
arr.readInt32LE = BP.readInt32LE
arr.readInt32BE = BP.readInt32BE
arr.readFloatLE = BP.readFloatLE
arr.readFloatBE = BP.readFloatBE
arr.readDoubleLE = BP.readDoubleLE
arr.readDoubleBE = BP.readDoubleBE
arr.writeUInt8 = BP.writeUInt8
arr.writeUIntLE = BP.writeUIntLE
arr.writeUIntBE = BP.writeUIntBE
arr.writeUInt16LE = BP.writeUInt16LE
arr.writeUInt16BE = BP.writeUInt16BE
arr.writeUInt32LE = BP.writeUInt32LE
arr.writeUInt32BE = BP.writeUInt32BE
arr.writeIntLE = BP.writeIntLE
arr.writeIntBE = BP.writeIntBE
arr.writeInt8 = BP.writeInt8
arr.writeInt16LE = BP.writeInt16LE
arr.writeInt16BE = BP.writeInt16BE
arr.writeInt32LE = BP.writeInt32LE
arr.writeInt32BE = BP.writeInt32BE
arr.writeFloatLE = BP.writeFloatLE
arr.writeFloatBE = BP.writeFloatBE
arr.writeDoubleLE = BP.writeDoubleLE
arr.writeDoubleBE = BP.writeDoubleBE
arr.fill = BP.fill
arr.inspect = BP.inspect
arr.toArrayBuffer = BP.toArrayBuffer
return arr
}
var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g
function base64clean (str) {
// Node strips out invalid characters like \n and \t from the string, base64-js does not
str = stringtrim(str).replace(INVALID_BASE64_RE, '')
// Node converts strings with length < 2 to ''
if (str.length < 2) return ''
// Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
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)
// is surrogate component
if (codePoint > 0xD7FF && codePoint < 0xE000) {
// last char was a lead
if (!leadSurrogate) {
// no lead yet
if (codePoint > 0xDBFF) {
// unexpected trail
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
continue
} else if (i + 1 === length) {
// unpaired lead
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
continue
}
// valid lead
leadSurrogate = codePoint
continue
}
// 2 leads in a row
if (codePoint < 0xDC00) {
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
leadSurrogate = codePoint
continue
}
// valid surrogate pair
codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000
} else if (leadSurrogate) {
// valid bmp char, but last char was a lead
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
}
leadSurrogate = null
// encode utf8
if (codePoint < 0x80) {
if ((units -= 1) < 0) break
bytes.push(codePoint)
} else if (codePoint < 0x800) {
if ((units -= 2) < 0) break
bytes.push(
codePoint >> 0x6 | 0xC0,
codePoint & 0x3F | 0x80
)
} else if (codePoint < 0x10000) {
if ((units -= 3) < 0) break
bytes.push(
codePoint >> 0xC | 0xE0,
codePoint >> 0x6 & 0x3F | 0x80,
codePoint & 0x3F | 0x80
)
} else if (codePoint < 0x110000) {
if ((units -= 4) < 0) break
bytes.push(
codePoint >> 0x12 | 0xF0,
codePoint >> 0xC & 0x3F | 0x80,
codePoint >> 0x6 & 0x3F | 0x80,
codePoint & 0x3F | 0x80
)
} else {
throw new Error('Invalid code point')
}
}
return bytes
}
function asciiToBytes (str) {
var byteArray = []
for (var i = 0; i < str.length; i++) {
// Node's code seems to be doing this and not & 0x7F..
byteArray.push(str.charCodeAt(i) & 0xFF)
}
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
}
},{"base64-js":15,"ieee754":16,"is-array":17}],15:[function(require,module,exports){
var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
;(function (exports) {
'use strict';
var Arr = (typeof Uint8Array !== 'undefined')
? Uint8Array
: Array
var PLUS = '+'.charCodeAt(0)
var SLASH = '/'.charCodeAt(0)
var NUMBER = '0'.charCodeAt(0)
var LOWER = 'a'.charCodeAt(0)
var UPPER = 'A'.charCodeAt(0)
var PLUS_URL_SAFE = '-'.charCodeAt(0)
var SLASH_URL_SAFE = '_'.charCodeAt(0)
function decode (elt) {
var code = elt.charCodeAt(0)
if (code === PLUS ||
code === PLUS_URL_SAFE)
return 62 // '+'
if (code === SLASH ||
code === SLASH_URL_SAFE)
return 63 // '/'
if (code < NUMBER)
return -1 //no match
if (code < NUMBER + 10)
return code - NUMBER + 26 + 26
if (code < UPPER + 26)
return code - UPPER
if (code < LOWER + 26)
return code - LOWER + 26
}
function b64ToByteArray (b64) {
var i, j, l, tmp, placeHolders, arr
if (b64.length % 4 > 0) {
throw new Error('Invalid string. Length must be a multiple of 4')
}
// the number of equal signs (place holders)
// if there are two placeholders, than the two characters before it
// represent one byte
// if there is only one, then the three characters before it represent 2 bytes
// this is just a cheap hack to not do indexOf twice
var len = b64.length
placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0
// base64 is 4/3 + up to two characters of the original data
arr = new Arr(b64.length * 3 / 4 - placeHolders)
// if there are placeholders, only get up to the last complete 4 chars
l = placeHolders > 0 ? b64.length - 4 : b64.length
var L = 0
function push (v) {
arr[L++] = v
}
for (i = 0, j = 0; i < l; i += 4, j += 3) {
tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3))
push((tmp & 0xFF0000) >> 16)
push((tmp & 0xFF00) >> 8)
push(tmp & 0xFF)
}
if (placeHolders === 2) {
tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4)
push(tmp & 0xFF)
} else if (placeHolders === 1) {
tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2)
push((tmp >> 8) & 0xFF)
push(tmp & 0xFF)
}
return arr
}
function uint8ToBase64 (uint8) {
var i,
extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes
output = "",
temp, length
function encode (num) {
return lookup.charAt(num)
}
function tripletToBase64 (num) {
return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F)
}
// go through the array every three bytes, we'll deal with trailing stuff later
for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {
temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
output += tripletToBase64(temp)
}
// pad the end with zeros, but make sure to not forget the extra bytes
switch (extraBytes) {
case 1:
temp = uint8[uint8.length - 1]
output += encode(temp >> 2)
output += encode((temp << 4) & 0x3F)
output += '=='
break
case 2:
temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1])
output += encode(temp >> 10)
output += encode((temp >> 4) & 0x3F)
output += encode((temp << 2) & 0x3F)
output += '='
break
}
return output
}
exports.toByteArray = b64ToByteArray
exports.fromByteArray = uint8ToBase64
}(typeof exports === 'undefined' ? (this.base64js = {}) : exports))
},{}],16:[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 & 0xff, i += d, m /= 256, mLen -= 8) {}
e = (e << mLen) | m
eLen += mLen
for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
buffer[offset + i - d] |= s * 128
}
},{}],17:[function(require,module,exports){
/**
* isArray
*/
var isArray = Array.isArray;
/**
* toString
*/
var str = Object.prototype.toString;
/**
* Whether or not the given `val`
* is an array.
*
* example:
*
* isArray([]);
* // > true
* isArray(arguments);
* // > false
* isArray('');
* // > false
*
* @param {mixed} val
* @return {bool}
*/
module.exports = isArray || function (val) {
return !! val && '[object Array]' == str.call(val);
};
},{}],18:[function(require,module,exports){
/* jshint node: true */
(function () {
"use strict";
function CookieAccessInfo(domain, path, secure, script) {
if (this instanceof CookieAccessInfo) {
this.domain = domain || undefined;
this.path = path || "/";
this.secure = !!secure;
this.script = !!script;
return this;
}
return new CookieAccessInfo(domain, path, secure, script);
}
exports.CookieAccessInfo = CookieAccessInfo;
function Cookie(cookiestr, request_domain, request_path) {
if (cookiestr instanceof Cookie) {
return cookiestr;
}
if (this instanceof Cookie) {
this.name = null;
this.value = null;
this.expiration_date = Infinity;
this.path = String(request_path || "/");
this.explicit_path = false;
this.domain = request_domain || null;
this.explicit_domain = false;
this.secure = false; //how to define default?
this.noscript = false; //httponly
if (cookiestr) {
this.parse(cookiestr, request_domain, request_path);
}
return this;
}
return new Cookie(cookiestr, request_domain, request_path);
}
exports.Cookie = Cookie;
Cookie.prototype.toString = function toString() {
var str = [this.name + "=" + this.value];
if (this.expiration_date !== Infinity) {
str.push("expires=" + (new Date(this.expiration_date)).toGMTString());
}
if (this.domain) {
str.push("domain=" + this.domain);
}
if (this.path) {
str.push("path=" + this.path);
}
if (this.secure) {
str.push("secure");
}
if (this.noscript) {
str.push("httponly");
}
return str.join("; ");
};
Cookie.prototype.toValueString = function toValueString() {
return this.name + "=" + this.value;
};
var cookie_str_splitter = /[:](?=\s*[a-zA-Z0-9_\-]+\s*[=])/g;
Cookie.prototype.parse = function parse(str, request_domain, request_path) {
if (this instanceof Cookie) {
var parts = str.split(";").filter(function (value) {
return !!value;
}),
pair = parts[0].match(/([^=]+)=([\s\S]*)/),
key = pair[1],
value = pair[2],
i;
this.name = key;
this.value = value;
for (i = 1; i < parts.length; i += 1) {
pair = parts[i].match(/([^=]+)(?:=([\s\S]*))?/);
key = pair[1].trim().toLowerCase();
value = pair[2];
switch (key) {
case "httponly":
this.noscript = true;
break;
case "expires":
this.expiration_date = value ?
Number(Date.parse(value)) :
Infinity;
break;
case "path":
this.path = value ?
value.trim() :
"";
this.explicit_path = true;
break;
case "domain":
this.domain = value ?
value.trim() :
"";
this.explicit_domain = !!this.domain;
break;
case "secure":
this.secure = true;
break;
}
}
if (!this.explicit_path) {
this.path = request_path || "/";
}
if (!this.explicit_domain) {
this.domain = request_domain;
}
return this;
}
return new Cookie().parse(str, request_domain, request_path);
};
Cookie.prototype.matches = function matches(access_info) {
if (this.noscript && access_info.script ||
this.secure && !access_info.secure ||
!this.collidesWith(access_info)) {
return false;
}
return true;
};
Cookie.prototype.collidesWith = function collidesWith(access_info) {
if ((this.path && !access_info.path) || (this.domain && !access_info.domain)) {
return false;
}
if (this.path && access_info.path.indexOf(this.path) !== 0) {
return false;
}
if (this.explicit_path && access_info.path.indexOf( this.path ) !== 0) {
return false;
}
var access_domain = access_info.domain && access_info.domain.replace(/^[\.]/,'');
var cookie_domain = this.domain && this.domain.replace(/^[\.]/,'');
if (cookie_domain === access_domain) {
return true;
}
if (cookie_domain) {
if (!this.explicit_domain) {
return false; // we already checked if the domains were exactly the same
}
var wildcard = access_domain.indexOf(cookie_domain);
if (wildcard === -1 || wildcard !== access_domain.length - cookie_domain.length) {
return false;
}
return true;
}
return true;
};
function CookieJar() {
var cookies, cookies_list, collidable_cookie;
if (this instanceof CookieJar) {
cookies = Object.create(null); //name: [Cookie]
this.setCookie = function setCookie(cookie, request_domain, request_path) {
var remove, i;
cookie = new Cookie(cookie, request_domain, request_path);
//Delete the cookie if the set is past the current time
remove = cookie.expiration_date <= Date.now();
if (cookies[cookie.name] !== undefined) {
cookies_list = cookies[cookie.name];
for (i = 0; i < cookies_list.length; i += 1) {
collidable_cookie = cookies_list[i];
if (collidable_cookie.collidesWith(cookie)) {
if (remove) {
cookies_list.splice(i, 1);
if (cookies_list.length === 0) {
delete cookies[cookie.name];
}
return false;
}
cookies_list[i] = cookie;
return cookie;
}
}
if (remove) {
return false;
}
cookies_list.push(cookie);
return cookie;
}
if (remove) {
return false;
}
cookies[cookie.name] = [cookie];
return cookies[cookie.name];
};
//returns a cookie
this.getCookie = function getCookie(cookie_name, access_info) {
var cookie, i;
cookies_list = cookies[cookie_name];
if (!cookies_list) {
return;
}
for (i = 0; i < cookies_list.length; i += 1) {
cookie = cookies_list[i];
if (cookie.expiration_date <= Date.now()) {
if (cookies_list.length === 0) {
delete cookies[cookie.name];
}
continue;
}
if (cookie.matches(access_info)) {
return cookie;
}
}
};
//returns a list of cookies
this.getCookies = function getCookies(access_info) {
var matches = [], cookie_name, cookie;
for (cookie_name in cookies) {
cookie = this.getCookie(cookie_name, access_info);
if (cookie) {
matches.push(cookie);
}
}
matches.toString = function toString() {
return matches.join(":");
};
matches.toValueString = function toValueString() {
return matches.map(function (c) {
return c.toValueString();
}).join(';');
};
return matches;
};
return this;
}
return new CookieJar();
}
exports.CookieJar = CookieJar;
//returns list of cookies that were set correctly. Cookies that are expired and removed are not returned.
CookieJar.prototype.setCookies = function setCookies(cookies, request_domain, request_path) {
cookies = Array.isArray(cookies) ?
cookies :
cookies.split(cookie_str_splitter);
var successful = [],
i,
cookie;
cookies = cookies.map(function(item){
return new Cookie(item, request_domain, request_path);
});
for (i = 0; i < cookies.length; i += 1) {
cookie = cookies[i];
if (this.setCookie(cookie, request_domain, request_path)) {
successful.push(cookie);
}
}
return successful;
};
}());
},{}],19:[function(require,module,exports){
'use strict';
var yaml = require('./lib/js-yaml.js');
module.exports = yaml;
},{"./lib/js-yaml.js":20}],20:[function(require,module,exports){
'use strict';
var loader = require('./js-yaml/loader');
var dumper = require('./js-yaml/dumper');
function deprecated(name) {
return function () {
throw new Error('Function ' + name + ' is deprecated and cannot be used.');
};
}
module.exports.Type = require('./js-yaml/type');
module.exports.Schema = require('./js-yaml/schema');
module.exports.FAILSAFE_SCHEMA = require('./js-yaml/schema/failsafe');
module.exports.JSON_SCHEMA = require('./js-yaml/schema/json');
module.exports.CORE_SCHEMA = require('./js-yaml/schema/core');
module.exports.DEFAULT_SAFE_SCHEMA = require('./js-yaml/schema/default_safe');
module.exports.DEFAULT_FULL_SCHEMA = require('./js-yaml/schema/default_full');
module.exports.load = loader.load;
module.exports.loadAll = loader.loadAll;
module.exports.safeLoad = loader.safeLoad;
module.exports.safeLoadAll = loader.safeLoadAll;
module.exports.dump = dumper.dump;
module.exports.safeDump = dumper.safeDump;
module.exports.YAMLException = require('./js-yaml/exception');
// Deprecated schema names from JS-YAML 2.0.x
module.exports.MINIMAL_SCHEMA = require('./js-yaml/schema/failsafe');
module.exports.SAFE_SCHEMA = require('./js-yaml/schema/default_safe');
module.exports.DEFAULT_SCHEMA = require('./js-yaml/schema/default_full');
// Deprecated functions from JS-YAML 1.x.x
module.exports.scan = deprecated('scan');
module.exports.parse = deprecated('parse');
module.exports.compose = deprecated('compose');
module.exports.addConstructor = deprecated('addConstructor');
},{"./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){
'use strict';
function isNothing(subject) {
return (typeof subject === 'undefined') || (subject === null);
}
function isObject(subject) {
return (typeof subject === 'object') && (subject !== null);
}
function toArray(sequence) {
if (Array.isArray(sequence)) return sequence;
else if (isNothing(sequence)) return [];
return [ sequence ];
}
function extend(target, source) {
var index, length, key, sourceKeys;
if (source) {
sourceKeys = Object.keys(source);
for (index = 0, length = sourceKeys.length; index < length; index += 1) {
key = sourceKeys[index];
target[key] = source[key];
}
}
return target;
}
function repeat(string, count) {
var result = '', cycle;
for (cycle = 0; cycle < count; cycle += 1) {
result += string;
}
return result;
}
function isNegativeZero(number) {
return (number === 0) && (Number.NEGATIVE_INFINITY === 1 / number);
}
module.exports.isNothing = isNothing;
module.exports.isObject = isObject;
module.exports.toArray = toArray;
module.exports.repeat = repeat;
module.exports.isNegativeZero = isNegativeZero;
module.exports.extend = extend;
},{}],22:[function(require,module,exports){
'use strict';
/*eslint-disable no-use-before-define*/
var common = require('./common');
var YAMLException = require('./exception');
var DEFAULT_FULL_SCHEMA = require('./schema/default_full');
var DEFAULT_SAFE_SCHEMA = require('./schema/default_safe');
var _toString = Object.prototype.toString;
var _hasOwnProperty = Object.prototype.hasOwnProperty;
var CHAR_TAB = 0x09; /* Tab */
var CHAR_LINE_FEED = 0x0A; /* LF */
var CHAR_SPACE = 0x20; /* Space */
var CHAR_EXCLAMATION = 0x21; /* ! */
var CHAR_DOUBLE_QUOTE = 0x22; /* " */
var CHAR_SHARP = 0x23; /* # */
var CHAR_PERCENT = 0x25; /* % */
var CHAR_AMPERSAND = 0x26; /* & */
var CHAR_SINGLE_QUOTE = 0x27; /* ' */
var CHAR_ASTERISK = 0x2A; /* * */
var CHAR_COMMA = 0x2C; /* , */
var CHAR_MINUS = 0x2D; /* - */
var CHAR_COLON = 0x3A; /* : */
var CHAR_GREATER_THAN = 0x3E; /* > */
var CHAR_QUESTION = 0x3F; /* ? */
var CHAR_COMMERCIAL_AT = 0x40; /* @ */
var CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */
var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */
var CHAR_GRAVE_ACCENT = 0x60; /* ` */
var CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */
var CHAR_VERTICAL_LINE = 0x7C; /* | */
var CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */
var ESCAPE_SEQUENCES = {};
ESCAPE_SEQUENCES[0x00] = '\\0';
ESCAPE_SEQUENCES[0x07] = '\\a';
ESCAPE_SEQUENCES[0x08] = '\\b';
ESCAPE_SEQUENCES[0x09] = '\\t';
ESCAPE_SEQUENCES[0x0A] = '\\n';
ESCAPE_SEQUENCES[0x0B] = '\\v';
ESCAPE_SEQUENCES[0x0C] = '\\f';
ESCAPE_SEQUENCES[0x0D] = '\\r';
ESCAPE_SEQUENCES[0x1B] = '\\e';
ESCAPE_SEQUENCES[0x22] = '\\"';
ESCAPE_SEQUENCES[0x5C] = '\\\\';
ESCAPE_SEQUENCES[0x85] = '\\N';
ESCAPE_SEQUENCES[0xA0] = '\\_';
ESCAPE_SEQUENCES[0x2028] = '\\L';
ESCAPE_SEQUENCES[0x2029] = '\\P';
var DEPRECATED_BOOLEANS_SYNTAX = [
'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON',
'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF'
];
function compileStyleMap(schema, map) {
var result, keys, index, length, tag, style, type;
if (map === null) return {};
result = {};
keys = Object.keys(map);
for (index = 0, length = keys.length; index < length; index += 1) {
tag = keys[index];
style = String(map[tag]);
if (tag.slice(0, 2) === '!!') {
tag = 'tag:yaml.org,2002:' + tag.slice(2);
}
type = schema.compiledTypeMap[tag];
if (type && _hasOwnProperty.call(type.styleAliases, style)) {
style = type.styleAliases[style];
}
result[tag] = style;
}
return result;
}
function encodeHex(character) {
var string, handle, length;
string = character.toString(16).toUpperCase();
if (character <= 0xFF) {
handle = 'x';
length = 2;
} else if (character <= 0xFFFF) {
handle = 'u';
length = 4;
} else if (character <= 0xFFFFFFFF) {
handle = 'U';
length = 8;
} else {
throw new YAMLException('code point within a string may not be greater than 0xFFFFFFFF');
}
return '\\' + handle + common.repeat('0', length - string.length) + string;
}
function State(options) {
this.schema = options['schema'] || DEFAULT_FULL_SCHEMA;
this.indent = Math.max(1, (options['indent'] || 2));
this.skipInvalid = options['skipInvalid'] || false;
this.flowLevel = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']);
this.styleMap = compileStyleMap(this.schema, options['styles'] || null);
this.sortKeys = options['sortKeys'] || false;
this.lineWidth = options['lineWidth'] || 80;
this.noRefs = options['noRefs'] || false;
this.noCompatMode = options['noCompatMode'] || false;
this.implicitTypes = this.schema.compiledImplicit;
this.explicitTypes = this.schema.compiledExplicit;
this.tag = null;
this.result = '';
this.duplicates = [];
this.usedDuplicates = null;
}
// Indents every line in a string. Empty lines (\n only) are not indented.
function indentString(string, spaces) {
var ind = common.repeat(' ', spaces),
position = 0,
next = -1,
result = '',
line,
length = string.length;
while (position < length) {
next = string.indexOf('\n', position);
if (next === -1) {
line = string.slice(position);
position = length;
} else {
line = string.slice(position, next + 1);
position = next + 1;
}
if (line.length && line !== '\n') result += ind;
result += line;
}
return result;
}
function generateNextLine(state, level) {
return '\n' + common.repeat(' ', state.indent * level);
}
function testImplicitResolving(state, str) {
var index, length, type;
for (index = 0, length = state.implicitTypes.length; index < length; index += 1) {
type = state.implicitTypes[index];
if (type.resolve(str)) {
return true;
}
}
return false;
}
// [33] s-white ::= s-space | s-tab
function isWhitespace(c) {
return c === CHAR_SPACE || c === CHAR_TAB;
}
// Returns true if the character can be printed without escaping.
// From YAML 1.2: "any allowed characters known to be non-printable
// should also be escaped. [However,] This isn’t mandatory"
// Derived from nb-char - \t - #x85 - #xA0 - #x2028 - #x2029.
function isPrintable(c) {
return (0x00020 <= c && c <= 0x00007E)
|| ((0x000A1 <= c && c <= 0x00D7FF) && c !== 0x2028 && c !== 0x2029)
|| ((0x0E000 <= c && c <= 0x00FFFD) && c !== 0xFEFF /* BOM */)
|| (0x10000 <= c && c <= 0x10FFFF);
}
// Simplified test for values allowed after the first character in plain style.
function isPlainSafe(c) {
// Uses a subset of nb-char - c-flow-indicator - ":" - "#"
// where nb-char ::= c-printable - b-char - c-byte-order-mark.
return isPrintable(c) && c !== 0xFEFF
// - c-flow-indicator
&& c !== CHAR_COMMA
&& c !== CHAR_LEFT_SQUARE_BRACKET
&& c !== CHAR_RIGHT_SQUARE_BRACKET
&& c !== CHAR_LEFT_CURLY_BRACKET
&& c !== CHAR_RIGHT_CURLY_BRACKET
// - ":" - "#"
&& c !== CHAR_COLON
&& c !== CHAR_SHARP;
}
// Simplified test for values allowed as the first character in plain style.
function isPlainSafeFirst(c) {
// Uses a subset of ns-char - c-indicator
// where ns-char = nb-char - s-white.
return isPrintable(c) && c !== 0xFEFF
&& !isWhitespace(c) // - s-white
// - (c-indicator ::=
// “-” | “?” | “:” | “,” | “[” | “]” | “{” | “}”
&& c !== CHAR_MINUS
&& c !== CHAR_QUESTION
&& c !== CHAR_COLON
&& c !== CHAR_COMMA
&& c !== CHAR_LEFT_SQUARE_BRACKET
&& c !== CHAR_RIGHT_SQUARE_BRACKET
&& c !== CHAR_LEFT_CURLY_BRACKET
&& c !== CHAR_RIGHT_CURLY_BRACKET
// | “#” | “&” | “*” | “!” | “|” | “>” | “'” | “"”
&& c !== CHAR_SHARP
&& c !== CHAR_AMPERSAND
&& c !== CHAR_ASTERISK
&& c !== CHAR_EXCLAMATION
&& c !== CHAR_VERTICAL_LINE
&& c !== CHAR_GREATER_THAN
&& c !== CHAR_SINGLE_QUOTE
&& c !== CHAR_DOUBLE_QUOTE
// | “%” | “@” | “`”)
&& c !== CHAR_PERCENT
&& c !== CHAR_COMMERCIAL_AT
&& c !== CHAR_GRAVE_ACCENT;
}
var STYLE_PLAIN = 1,
STYLE_SINGLE = 2,
STYLE_LITERAL = 3,
STYLE_FOLDED = 4,
STYLE_DOUBLE = 5;
// Determines which scalar styles are possible and returns the preferred style.
// lineWidth = -1 => no limit.
// Pre-conditions: str.length > 0.
// Post-conditions:
// STYLE_PLAIN or STYLE_SINGLE => no \n are in the string.
// STYLE_LITERAL => no lines are suitable for folding (or lineWidth is -1).
// STYLE_FOLDED => a line > lineWidth and can be folded (and lineWidth != -1).
function chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth, testAmbiguousType) {
var i;
var char;
var hasLineBreak = false;
var hasFoldableLine = false; // only checked if shouldTrackWidth
var shouldTrackWidth = lineWidth !== -1;
var previousLineBreak = -1; // count the first line correctly
var plain = isPlainSafeFirst(string.charCodeAt(0))
&& !isWhitespace(string.charCodeAt(string.length - 1));
if (singleLineOnly) {
// Case: no block styles.
// Check for disallowed characters to rule out plain and single.
for (i = 0; i < string.length; i++) {
char = string.charCodeAt(i);
if (!isPrintable(char)) {
return STYLE_DOUBLE;
}
plain = plain && isPlainSafe(char);
}
} else {
// Case: block styles permitted.
for (i = 0; i < string.length; i++) {
char = string.charCodeAt(i);
if (char === CHAR_LINE_FEED) {
hasLineBreak = true;
// Check if any line can be folded.
if (shouldTrackWidth) {
hasFoldableLine = hasFoldableLine ||
// Foldable line = too long, and not more-indented.
(i - previousLineBreak - 1 > lineWidth &&
string[previousLineBreak + 1] !== ' ');
previousLineBreak = i;
}
} else if (!isPrintable(char)) {
return STYLE_DOUBLE;
}
plain = plain && isPlainSafe(char);
}
// in case the end is missing a \n
hasFoldableLine = hasFoldableLine || (shouldTrackWidth &&
(i - previousLineBreak - 1 > lineWidth &&
string[previousLineBreak + 1] !== ' '));
}
// Although every style can represent \n without escaping, prefer block styles
// for multiline, since they're more readable and they don't add empty lines.
// Also prefer folding a super-long line.
if (!hasLineBreak && !hasFoldableLine) {
// Strings interpretable as another type have to be quoted;
// e.g. the string 'true' vs. the boolean true.
return plain && !testAmbiguousType(string)
? STYLE_PLAIN : STYLE_SINGLE;
}
// Edge case: block indentation indicator can only have one digit.
if (string[0] === ' ' && indentPerLevel > 9) {
return STYLE_DOUBLE;
}
// At this point we know block styles are valid.
// Prefer literal style unless we want to fold.
return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL;
}
// Note: line breaking/folding is implemented for only the folded style.
// NB. We drop the last trailing newline (if any) of a returned block scalar
// since the dumper adds its own newline. This always works:
// • No ending newline => unaffected; already using strip "-" chomping.
// • Ending newline => removed then restored.
// Importantly, this keeps the "+" chomp indicator from gaining an extra line.
function writeScalar(state, string, level, iskey) {
state.dump = (function () {
if (string.length === 0) {
return "''";
}
if (!state.noCompatMode &&
DEPRECATED_BOOLEANS_SYNTAX.indexOf(string) !== -1) {
return "'" + string + "'";
}
var indent = state.indent * Math.max(1, level); // no 0-indent scalars
// As indentation gets deeper, let the width decrease monotonically
// to the lower bound min(state.lineWidth, 40).
// Note that this implies
// state.lineWidth ≤ 40 + state.indent: width is fixed at the lower bound.
// state.lineWidth > 40 + state.indent: width decreases until the lower bound.
// This behaves better than a constant minimum width which disallows narrower options,
// or an indent threshold which causes the width to suddenly increase.
var lineWidth = state.lineWidth === -1
? -1 : Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent);
// Without knowing if keys are implicit/explicit, assume implicit for safety.
var singleLineOnly = iskey
// No block styles in flow mode.
|| (state.flowLevel > -1 && level >= state.flowLevel);
function testAmbiguity(string) {
return testImplicitResolving(state, string);
}
switch (chooseScalarStyle(string, singleLineOnly, state.indent, lineWidth, testAmbiguity)) {
case STYLE_PLAIN:
return string;
case STYLE_SINGLE:
return "'" + string.replace(/'/g, "''") + "'";
case STYLE_LITERAL:
return '|' + blockHeader(string, state.indent)
+ dropEndingNewline(indentString(string, indent));
case STYLE_FOLDED:
return '>' + blockHeader(string, state.indent)
+ dropEndingNewline(indentString(foldString(string, lineWidth), indent));
case STYLE_DOUBLE:
return '"' + escapeString(string, lineWidth) + '"';
default:
throw new YAMLException('impossible error: invalid scalar style');
}
}());
}
// Pre-conditions: string is valid for a block scalar, 1 <= indentPerLevel <= 9.
function blockHeader(string, indentPerLevel) {
var indentIndicator = (string[0] === ' ') ? String(indentPerLevel) : '';
// note the special case: the string '\n' counts as a "trailing" empty line.
var clip = string[string.length - 1] === '\n';
var keep = clip && (string[string.length - 2] === '\n' || string === '\n');
var chomp = keep ? '+' : (clip ? '' : '-');
return indentIndicator + chomp + '\n';
}
// (See the note for writeScalar.)
function dropEndingNewline(string) {
return string[string.length - 1] === '\n' ? string.slice(0, -1) : string;
}
// Note: a long line without a suitable break point will exceed the width limit.
// Pre-conditions: every char in str isPrintable, str.length > 0, width > 0.
function foldString(string, width) {
// In folded style, $k$ consecutive newlines output as $k+1$ newlines—
// unless they're before or after a more-indented line, or at the very
// beginning or end, in which case $k$ maps to $k$.
// Therefore, parse each chunk as newline(s) followed by a content line.
var lineRe = /(\n+)([^\n]*)/g;
// first line (possibly an empty line)
var result = (function () {
var nextLF = string.indexOf('\n');
nextLF = nextLF !== -1 ? nextLF : string.length;
lineRe.lastIndex = nextLF;
return foldLine(string.slice(0, nextLF), width);
}());
// If we haven't reached the first content line yet, don't add an extra \n.
var prevMoreIndented = string[0] === '\n' || string[0] === ' ';
var moreIndented;
// rest of the lines
var match;
while ((match = lineRe.exec(string))) {
var prefix = match[1], line = match[2];
moreIndented = (line[0] === ' ');
result += prefix
+ (!prevMoreIndented && !moreIndented && line !== ''
? '\n' : '')
+ foldLine(line, width);
prevMoreIndented = moreIndented;
}
return result;
}
// Greedy line breaking.
// Picks the longest line under the limit each time,
// otherwise settles for the shortest line over the limit.
// NB. More-indented lines *cannot* be folded, as that would add an extra \n.
function foldLine(line, width) {
if (line === '' || line[0] === ' ') return line;
// Since a more-indented line adds a \n, breaks can't be followed by a space.
var breakRe = / [^ ]/g; // note: the match index will always be <= length-2.
var match;
// start is an inclusive index. end, curr, and next are exclusive.
var start = 0, end, curr = 0, next = 0;
var result = '';
// Invariants: 0 <= start <= length-1.
// 0 <= curr <= next <= max(0, length-2). curr - start <= width.
// Inside the loop:
// A match implies length >= 2, so curr and next are <= length-2.
while ((match = breakRe.exec(line))) {
next = match.index;
// maintain invariant: curr - start <= width
if (next - start > width) {
end = (curr > start) ? curr : next; // derive end <= length-2
result += '\n' + line.slice(start, end);
// skip the space that was output as \n
start = end + 1; // derive start <= length-1
}
curr = next;
}
// By the invariants, start <= length-1, so there is something left over.
// It is either the whole string or a part starting from non-whitespace.
result += '\n';
// Insert a break if the remainder is too long and there is a break available.
if (line.length - start > width && curr > start) {
result += line.slice(start, curr) + '\n' + line.slice(curr + 1);
} else {
result += line.slice(start);
}
return result.slice(1); // drop extra \n joiner
}
// Escapes a double-quoted string.
function escapeString(string) {
var result = '';
var char;
var escapeSeq;
for (var i = 0; i < string.length; i++) {
char = string.charCodeAt(i);
escapeSeq = ESCAPE_SEQUENCES[char];
result += !escapeSeq && isPrintable(char)
? string[i]
: escapeSeq || encodeHex(char);
}
return result;
}
function writeFlowSequence(state, level, object) {
var _result = '',
_tag = state.tag,
index,
length;
for (index = 0, length = object.length; index < length; index += 1) {
// Write only valid elements.
if (writeNode(state, level, object[index], false, false)) {
if (index !== 0) _result += ', ';
_result += state.dump;
}
}
state.tag = _tag;
state.dump = '[' + _result + ']';
}
function writeBlockSequence(state, level, object, compact) {
var _result = '',
_tag = state.tag,
index,
length;
for (index = 0, length = object.length; index < length; index += 1) {
// Write only valid elements.
if (writeNode(state, level + 1, object[index], true, true)) {
if (!compact || index !== 0) {
_result += generateNextLine(state, level);
}
_result += '- ' + state.dump;
}
}
state.tag = _tag;
state.dump = _result || '[]'; // Empty sequence if no valid values.
}
function writeFlowMapping(state, level, object) {
var _result = '',
_tag = state.tag,
objectKeyList = Object.keys(object),
index,
length,
objectKey,
objectValue,
pairBuffer;
for (index = 0, length = objectKeyList.length; index < length; index += 1) {
pairBuffer = '';
if (index !== 0) pairBuffer += ', ';
objectKey = objectKeyList[index];
objectValue = object[objectKey];
if (!writeNode(state, level, objectKey, false, false)) {
continue; // Skip this pair because of invalid key;
}
if (state.dump.length > 1024) pairBuffer += '? ';
pairBuffer += state.dump + ': ';
if (!writeNode(state, level, objectValue, false, false)) {
continue; // Skip this pair because of invalid value.
}
pairBuffer += state.dump;
// Both key and value are valid.
_result += pairBuffer;
}
state.tag = _tag;
state.dump = '{' + _result + '}';
}
function writeBlockMapping(state, level, object, compact) {
var _result = '',
_tag = state.tag,
objectKeyList = Object.keys(object),
index,
length,
objectKey,
objectValue,
explicitPair,
pairBuffer;
// Allow sorting keys so that the output file is deterministic
if (state.sortKeys === true) {
// Default sorting
objectKeyList.sort();
} else if (typeof state.sortKeys === 'function') {
// Custom sort function
objectKeyList.sort(state.sortKeys);
} else if (state.sortKeys) {
// Something is wrong
throw new YAMLException('sortKeys must be a boolean or a function');
}
for (index = 0, length = objectKeyList.length; index < length; index += 1) {
pairBuffer = '';
if (!compact || index !== 0) {
pairBuffer += generateNextLine(state, level);
}
objectKey = objectKeyList[index];
objectValue = object[objectKey];
if (!writeNode(state, level + 1, objectKey, true, true, true)) {
continue; // Skip this pair because of invalid key.
}
explicitPair = (state.tag !== null && state.tag !== '?') ||
(state.dump && state.dump.length > 1024);
if (explicitPair) {
if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {
pairBuffer += '?';
} else {
pairBuffer += '? ';
}
}
pairBuffer += state.dump;
if (explicitPair) {
pairBuffer += generateNextLine(state, level);
}
if (!writeNode(state, level + 1, objectValue, true, explicitPair)) {
continue; // Skip this pair because of invalid value.
}
if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {
pairBuffer += ':';
} else {
pairBuffer += ': ';
}
pairBuffer += state.dump;
// Both key and value are valid.
_result += pairBuffer;
}
state.tag = _tag;
state.dump = _result || '{}'; // Empty mapping if no valid pairs.
}
function detectType(state, object, explicit) {
var _result, typeList, index, length, type, style;
typeList = explicit ? state.explicitTypes : state.implicitTypes;
for (index = 0, length = typeList.length; index < length; index += 1) {
type = typeList[index];
if ((type.instanceOf || type.predicate) &&
(!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) &&
(!type.predicate || type.predicate(object))) {
state.tag = explicit ? type.tag : '?';
if (type.represent) {
style = state.styleMap[type.tag] || type.defaultStyle;
if (_toString.call(type.represent) === '[object Function]') {
_result = type.represent(object, style);
} else if (_hasOwnProperty.call(type.represent, style)) {
_result = type.represent[style](object, style);
} else {
throw new YAMLException('!<' + type.tag + '> tag resolver accepts not "' + style + '" style');
}
state.dump = _result;
}
return true;
}
}
return false;
}
// Serializes `object` and writes it to global `result`.
// Returns true on success, or false on invalid object.
//
function writeNode(state, level, object, block, compact, iskey) {
state.tag = null;
state.dump = object;
if (!detectType(state, object, false)) {
detectType(state, object, true);
}
var type = _toString.call(state.dump);
if (block) {
block = (state.flowLevel < 0 || state.flowLevel > level);
}
var objectOrArray = type === '[object Object]' || type === '[object Array]',
duplicateIndex,
duplicate;
if (objectOrArray) {
duplicateIndex = state.duplicates.indexOf(object);
duplicate = duplicateIndex !== -1;
}
if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) {
compact = false;
}
if (duplicate && state.usedDuplicates[duplicateIndex]) {
state.dump = '*ref_' + duplicateIndex;
} else {
if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) {
state.usedDuplicates[duplicateIndex] = true;
}
if (type === '[object Object]') {
if (block && (Object.keys(state.dump).length !== 0)) {
writeBlockMapping(state, level, state.dump, compact);
if (duplicate) {
state.dump = '&ref_' + duplicateIndex + state.dump;
}
} else {
writeFlowMapping(state, level, state.dump);
if (duplicate) {
state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;
}
}
} else if (type === '[object Array]') {
if (block && (state.dump.length !== 0)) {
writeBlockSequence(state, level, state.dump, compact);
if (duplicate) {
state.dump = '&ref_' + duplicateIndex + state.dump;
}
} else {
writeFlowSequence(state, level, state.dump);
if (duplicate) {
state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;
}
}
} else if (type === '[object String]') {
if (state.tag !== '?') {
writeScalar(state, state.dump, level, iskey);
}
} else {
if (state.skipInvalid) return false;
throw new YAMLException('unacceptable kind of an object to dump ' + type);
}
if (state.tag !== null && state.tag !== '?') {
state.dump = '!<' + state.tag + '> ' + state.dump;
}
}
return true;
}
function getDuplicateReferences(object, state) {
var objects = [],
duplicatesIndexes = [],
index,
length;
inspectNode(object, objects, duplicatesIndexes);
for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) {
state.duplicates.push(objects[duplicatesIndexes[index]]);
}
state.usedDuplicates = new Array(length);
}
function inspectNode(object, objects, duplicatesIndexes) {
var objectKeyList,
index,
length;
if (object !== null && typeof object === 'object') {
index = objects.indexOf(object);
if (index !== -1) {
if (duplicatesIndexes.indexOf(index) === -1) {
duplicatesIndexes.push(index);
}
} else {
objects.push(object);
if (Array.isArray(object)) {
for (index = 0, length = object.length; index < length; index += 1) {
inspectNode(object[index], objects, duplicatesIndexes);
}
} else {
objectKeyList = Object.keys(object);
for (index = 0, length = objectKeyList.length; index < length; index += 1) {
inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes);
}
}
}
}
}
function dump(input, options) {
options = options || {};
var state = new State(options);
if (!state.noRefs) getDuplicateReferences(input, state);
if (writeNode(state, 0, input, true, true)) return state.dump + '\n';
return '';
}
function safeDump(input, options) {
return dump(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options));
}
module.exports.dump = dump;
module.exports.safeDump = safeDump;
},{"./common":21,"./exception":23,"./schema/default_full":28,"./schema/default_safe":29}],23:[function(require,module,exports){
// YAML error class. http://stackoverflow.com/questions/8458984
//
'use strict';
function YAMLException(reason, mark) {
// Super constructor
Error.call(this);
// Include stack trace in error object
if (Error.captureStackTrace) {
// Chrome and NodeJS
Error.captureStackTrace(this, this.constructor);
} else {
// FF, IE 10+ and Safari 6+. Fallback for others
this.stack = (new Error()).stack || '';
}
this.name = 'YAMLException';
this.reason = reason;
this.mark = mark;
this.message = (this.reason || '(unknown reason)') + (this.mark ? ' ' + this.mark.toString() : '');
}
// Inherit from Error
YAMLException.prototype = Object.create(Error.prototype);
YAMLException.prototype.constructor = YAMLException;
YAMLException.prototype.toString = function toString(compact) {
var result = this.name + ': ';
result += this.reason || '(unknown reason)';
if (!compact && this.mark) {
result += ' ' + this.mark.toString();
}
return result;
};
module.exports = YAMLException;
},{}],24:[function(require,module,exports){
'use strict';
/*eslint-disable max-len,no-use-before-define*/
var common = require('./common');
var YAMLException = require('./exception');
var Mark = require('./mark');
var DEFAULT_SAFE_SCHEMA = require('./schema/default_safe');
var DEFAULT_FULL_SCHEMA = require('./schema/default_full');
var _hasOwnProperty = Object.prototype.hasOwnProperty;
var CONTEXT_FLOW_IN = 1;
var CONTEXT_FLOW_OUT = 2;
var CONTEXT_BLOCK_IN = 3;
var CONTEXT_BLOCK_OUT = 4;
var CHOMPING_CLIP = 1;
var CHOMPING_STRIP = 2;
var CHOMPING_KEEP = 3;
var PATTERN_NON_PRINTABLE = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/;
var PATTERN_NON_ASCII_LINE_BREAKS = /[\x85\u2028\u2029]/;
var PATTERN_FLOW_INDICATORS = /[,\[\]\{\}]/;
var PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\-]+!)$/i;
var PATTERN_TAG_URI = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;
function is_EOL(c) {
return (c === 0x0A/* LF */) || (c === 0x0D/* CR */);
}
function is_WHITE_SPACE(c) {
return (c === 0x09/* Tab */) || (c === 0x20/* Space */);
}
function is_WS_OR_EOL(c) {
return (c === 0x09/* Tab */) ||
(c === 0x20/* Space */) ||
(c === 0x0A/* LF */) ||
(c === 0x0D/* CR */);
}
function is_FLOW_INDICATOR(c) {
return c === 0x2C/* , */ ||
c === 0x5B/* [ */ ||
c === 0x5D/* ] */ ||
c === 0x7B/* { */ ||
c === 0x7D/* } */;
}
function fromHexCode(c) {
var lc;
if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {
return c - 0x30;
}
/*eslint-disable no-bitwise*/
lc = c | 0x20;
if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) {
return lc - 0x61 + 10;
}
return -1;
}
function escapedHexLen(c) {
if (c === 0x78/* x */) { return 2; }
if (c === 0x75/* u */) { return 4; }
if (c === 0x55/* U */) { return 8; }
return 0;
}
function fromDecimalCode(c) {
if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {
return c - 0x30;
}
return -1;
}
function simpleEscapeSequence(c) {
return (c === 0x30/* 0 */) ? '\x00' :
(c === 0x61/* a */) ? '\x07' :
(c === 0x62/* b */) ? '\x08' :
(c === 0x74/* t */) ? '\x09' :
(c === 0x09/* Tab */) ? '\x09' :
(c === 0x6E/* n */) ? '\x0A' :
(c === 0x76/* v */) ? '\x0B' :
(c === 0x66/* f */) ? '\x0C' :
(c === 0x72/* r */) ? '\x0D' :
(c === 0x65/* e */) ? '\x1B' :
(c === 0x20/* Space */) ? ' ' :
(c === 0x22/* " */) ? '\x22' :
(c === 0x2F/* / */) ? '/' :
(c === 0x5C/* \ */) ? '\x5C' :
(c === 0x4E/* N */) ? '\x85' :
(c === 0x5F/* _ */) ? '\xA0' :
(c === 0x4C/* L */) ? '\u2028' :
(c === 0x50/* P */) ? '\u2029' : '';
}
function charFromCodepoint(c) {
if (c <= 0xFFFF) {
return String.fromCharCode(c);
}
// Encode UTF-16 surrogate pair
// https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF
return String.fromCharCode(((c - 0x010000) >> 10) + 0xD800,
((c - 0x010000) & 0x03FF) + 0xDC00);
}
var simpleEscapeCheck = new Array(256); // integer, for fast access
var simpleEscapeMap = new Array(256);
for (var i = 0; i < 256; i++) {
simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0;
simpleEscapeMap[i] = simpleEscapeSequence(i);
}
function State(input, options) {
this.input = input;
this.filename = options['filename'] || null;
this.schema = options['schema'] || DEFAULT_FULL_SCHEMA;
this.onWarning = options['onWarning'] || null;
this.legacy = options['legacy'] || false;
this.json = options['json'] || false;
this.listener = options['listener'] || null;
this.implicitTypes = this.schema.compiledImplicit;
this.typeMap = this.schema.compiledTypeMap;
this.length = input.length;
this.position = 0;
this.line = 0;
this.lineStart = 0;
this.lineIndent = 0;
this.documents = [];
/*
this.version;
this.checkLineBreaks;
this.tagMap;
this.anchorMap;
this.tag;
this.anchor;
this.kind;
this.result;*/
}
function generateError(state, message) {
return new YAMLException(
message,
new Mark(state.filename, state.input, state.position, state.line, (state.position - state.lineStart)));
}
function throwError(state, message) {
throw generateError(state, message);
}
function throwWarning(state, message) {
if (state.onWarning) {
state.onWarning.call(null, generateError(state, message));
}
}
var directiveHandlers = {
YAML: function handleYamlDirective(state, name, args) {
var match, major, minor;
if (state.version !== null) {
throwError(state, 'duplication of %YAML directive');
}
if (args.length !== 1) {
throwError(state, 'YAML directive accepts exactly one argument');
}
match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]);
if (match === null) {
throwError(state, 'ill-formed argument of the YAML directive');
}
major = parseInt(match[1], 10);
minor = parseInt(match[2], 10);
if (major !== 1) {
throwError(state, 'unacceptable YAML version of the document');
}
state.version = args[0];
state.checkLineBreaks = (minor < 2);
if (minor !== 1 && minor !== 2) {
throwWarning(state, 'unsupported YAML version of the document');
}
},
TAG: function handleTagDirective(state, name, args) {
var handle, prefix;
if (args.length !== 2) {
throwError(state, 'TAG directive accepts exactly two arguments');
}
handle = args[0];
prefix = args[1];
if (!PATTERN_TAG_HANDLE.test(handle)) {
throwError(state, 'ill-formed tag handle (first argument) of the TAG directive');
}
if (_hasOwnProperty.call(state.tagMap, handle)) {
throwError(state, 'there is a previously declared suffix for "' + handle + '" tag handle');
}
if (!PATTERN_TAG_URI.test(prefix)) {
throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive');
}
state.tagMap[handle] = prefix;
}
};
function captureSegment(state, start, end, checkJson) {
var _position, _length, _character, _result;
if (start < end) {
_result = state.input.slice(start, end);
if (checkJson) {
for (_position = 0, _length = _result.length;
_position < _length;
_position += 1) {
_character = _result.charCodeAt(_position);
if (!(_character === 0x09 ||
(0x20 <= _character && _character <= 0x10FFFF))) {
throwError(state, 'expected valid JSON character');
}
}
} else if (PATTERN_NON_PRINTABLE.test(_result)) {
throwError(state, 'the stream contains non-printable characters');
}
state.result += _result;
}
}
function mergeMappings(state, destination, source, overridableKeys) {
var sourceKeys, key, index, quantity;
if (!common.isObject(source)) {
throwError(state, 'cannot merge mappings; the provided source object is unacceptable');
}
sourceKeys = Object.keys(source);
for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) {
key = sourceKeys[index];
if (!_hasOwnProperty.call(destination, key)) {
destination[key] = source[key];
overridableKeys[key] = true;
}
}
}
function storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode) {
var index, quantity;
keyNode = String(keyNode);
if (_result === null) {
_result = {};
}
if (keyTag === 'tag:yaml.org,2002:merge') {
if (Array.isArray(valueNode)) {
for (index = 0, quantity = valueNode.length; index < quantity; index += 1) {
mergeMappings(state, _result, valueNode[index], overridableKeys);
}
} else {
mergeMappings(state, _result, valueNode, overridableKeys);
}
} else {
if (!state.json &&
!_hasOwnProperty.call(overridableKeys, keyNode) &&
_hasOwnProperty.call(_result, keyNode)) {
throwError(state, 'duplicated mapping key');
}
_result[keyNode] = valueNode;
delete overridableKeys[keyNode];
}
return _result;
}
function readLineBreak(state) {
var ch;
ch = state.input.charCodeAt(state.position);
if (ch === 0x0A/* LF */) {
state.position++;
} else if (ch === 0x0D/* CR */) {
state.position++;
if (state.input.charCodeAt(state.position) === 0x0A/* LF */) {
state.position++;
}
} else {
throwError(state, 'a line break is expected');
}
state.line += 1;
state.lineStart = state.position;
}
function skipSeparationSpace(state, allowComments, checkIndent) {
var lineBreaks = 0,
ch = state.input.charCodeAt(state.position);
while (ch !== 0) {
while (is_WHITE_SPACE(ch)) {
ch = state.input.charCodeAt(++state.position);
}
if (allowComments && ch === 0x23/* # */) {
do {
ch = state.input.charCodeAt(++state.position);
} while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && ch !== 0);
}
if (is_EOL(ch)) {
readLineBreak(state);
ch = state.input.charCodeAt(state.position);
lineBreaks++;
state.lineIndent = 0;
while (ch === 0x20/* Space */) {
state.lineIndent++;
ch = state.input.charCodeAt(++state.position);
}
} else {
break;
}
}
if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) {
throwWarning(state, 'deficient indentation');
}
return lineBreaks;
}
function testDocumentSeparator(state) {
var _position = state.position,
ch;
ch = state.input.charCodeAt(_position);
// Condition state.position === state.lineStart is tested
// in parent on each call, for efficiency. No needs to test here again.
if ((ch === 0x2D/* - */ || ch === 0x2E/* . */) &&
ch === state.input.charCodeAt(_position + 1) &&
ch === state.input.charCodeAt(_position + 2)) {
_position += 3;
ch = state.input.charCodeAt(_position);
if (ch === 0 || is_WS_OR_EOL(ch)) {
return true;
}
}
return false;
}
function writeFoldedLines(state, count) {
if (count === 1) {
state.result += ' ';
} else if (count > 1) {
state.result += common.repeat('\n', count - 1);
}
}
function readPlainScalar(state, nodeIndent, withinFlowCollection) {
var preceding,
following,
captureStart,
captureEnd,
hasPendingContent,
_line,
_lineStart,
_lineIndent,
_kind = state.kind,
_result = state.result,
ch;
ch = state.input.charCodeAt(state.position);
if (is_WS_OR_EOL(ch) ||
is_FLOW_INDICATOR(ch) ||
ch === 0x23/* # */ ||
ch === 0x26/* & */ ||
ch === 0x2A/* * */ ||
ch === 0x21/* ! */ ||
ch === 0x7C/* | */ ||
ch === 0x3E/* > */ ||
ch === 0x27/* ' */ ||
ch === 0x22/* " */ ||
ch === 0x25/* % */ ||
ch === 0x40/* @ */ ||
ch === 0x60/* ` */) {
return false;
}
if (ch === 0x3F/* ? */ || ch === 0x2D/* - */) {
following = state.input.charCodeAt(state.position + 1);
if (is_WS_OR_EOL(following) ||
withinFlowCollection && is_FLOW_INDICATOR(following)) {
return false;
}
}
state.kind = 'scalar';
state.result = '';
captureStart = captureEnd = state.position;
hasPendingContent = false;
while (ch !== 0) {
if (ch === 0x3A/* : */) {
following = state.input.charCodeAt(state.position + 1);
if (is_WS_OR_EOL(following) ||
withinFlowCollection && is_FLOW_INDICATOR(following)) {
break;
}
} else if (ch === 0x23/* # */) {
preceding = state.input.charCodeAt(state.position - 1);
if (is_WS_OR_EOL(preceding)) {
break;
}
} else if ((state.position === state.lineStart && testDocumentSeparator(state)) ||
withinFlowCollection && is_FLOW_INDICATOR(ch)) {
break;
} else if (is_EOL(ch)) {
_line = state.line;
_lineStart = state.lineStart;
_lineIndent = state.lineIndent;
skipSeparationSpace(state, false, -1);
if (state.lineIndent >= nodeIndent) {
hasPendingContent = true;
ch = state.input.charCodeAt(state.position);
continue;
} else {
state.position = captureEnd;
state.line = _line;
state.lineStart = _lineStart;
state.lineIndent = _lineIndent;
break;
}
}
if (hasPendingContent) {
captureSegment(state, captureStart, captureEnd, false);
writeFoldedLines(state, state.line - _line);
captureStart = captureEnd = state.position;
hasPendingContent = false;
}
if (!is_WHITE_SPACE(ch)) {
captureEnd = state.position + 1;
}
ch = state.input.charCodeAt(++state.position);
}
captureSegment(state, captureStart, captureEnd, false);
if (state.result) {
return true;
}
state.kind = _kind;
state.result = _result;
return false;
}
function readSingleQuotedScalar(state, nodeIndent) {
var ch,
captureStart, captureEnd;
ch = state.input.charCodeAt(state.position);
if (ch !== 0x27/* ' */) {
return false;
}
state.kind = 'scalar';
state.result = '';
state.position++;
captureStart = captureEnd = state.position;
while ((ch = state.input.charCodeAt(state.position)) !== 0) {
if (ch === 0x27/* ' */) {
captureSegment(state, captureStart, state.position, true);
ch = state.input.charCodeAt(++state.position);
if (ch === 0x27/* ' */) {
captureStart = captureEnd = state.position;
state.position++;
} else {
return true;
}
} else if (is_EOL(ch)) {
captureSegment(state, captureStart, captureEnd, true);
writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));
captureStart = captureEnd = state.position;
} else if (state.position === state.lineStart && testDocumentSeparator(state)) {
throwError(state, 'unexpected end of the document within a single quoted scalar');
} else {
state.position++;
captureEnd = state.position;
}
}
throwError(state, 'unexpected end of the stream within a single quoted scalar');
}
function readDoubleQuotedScalar(state, nodeIndent) {
var captureStart,
captureEnd,
hexLength,
hexResult,
tmp,
ch;
ch = state.input.charCodeAt(state.position);
if (ch !== 0x22/* " */) {
return false;
}
state.kind = 'scalar';
state.result = '';
state.position++;
captureStart = captureEnd = state.position;
while ((ch = state.input.charCodeAt(state.position)) !== 0) {
if (ch === 0x22/* " */) {
captureSegment(state, captureStart, state.position, true);
state.position++;
return true;
} else if (ch === 0x5C/* \ */) {
captureSegment(state, captureStart, state.position, true);
ch = state.input.charCodeAt(++state.position);
if (is_EOL(ch)) {
skipSeparationSpace(state, false, nodeIndent);
// TODO: rework to inline fn with no type cast?
} else if (ch < 256 && simpleEscapeCheck[ch]) {
state.result += simpleEscapeMap[ch];
state.position++;
} else if ((tmp = escapedHexLen(ch)) > 0) {
hexLength = tmp;
hexResult = 0;
for (; hexLength > 0; hexLength--) {
ch = state.input.charCodeAt(++state.position);
if ((tmp = fromHexCode(ch)) >= 0) {
hexResult = (hexResult << 4) + tmp;
} else {
throwError(state, 'expected hexadecimal character');
}
}
state.result += charFromCodepoint(hexResult);
state.position++;
} else {
throwError(state, 'unknown escape sequence');
}
captureStart = captureEnd = state.position;
} else if (is_EOL(ch)) {
captureSegment(state, captureStart, captureEnd, true);
writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));
captureStart = captureEnd = state.position;
} else if (state.position === state.lineStart && testDocumentSeparator(state)) {
throwError(state, 'unexpected end of the document within a double quoted scalar');
} else {
state.position++;
captureEnd = state.position;
}
}
throwError(state, 'unexpected end of the stream within a double quoted scalar');
}
function readFlowCollection(state, nodeIndent) {
var readNext = true,
_line,
_tag = state.tag,
_result,
_anchor = state.anchor,
following,
terminator,
isPair,
isExplicitPair,
isMapping,
overridableKeys = {},
keyNode,
keyTag,
valueNode,
ch;
ch = state.input.charCodeAt(state.position);
if (ch === 0x5B/* [ */) {
terminator = 0x5D;/* ] */
isMapping = false;
_result = [];
} else if (ch === 0x7B/* { */) {
terminator = 0x7D;/* } */
isMapping = true;
_result = {};
} else {
return false;
}
if (state.anchor !== null) {
state.anchorMap[state.anchor] = _result;
}
ch = state.input.charCodeAt(++state.position);
while (ch !== 0) {
skipSeparationSpace(state, true, nodeIndent);
ch = state.input.charCodeAt(state.position);
if (ch === terminator) {
state.position++;
state.tag = _tag;
state.anchor = _anchor;
state.kind = isMapping ? 'mapping' : 'sequence';
state.result = _result;
return true;
} else if (!readNext) {
throwError(state, 'missed comma between flow collection entries');
}
keyTag = keyNode = valueNode = null;
isPair = isExplicitPair = false;
if (ch === 0x3F/* ? */) {
following = state.input.charCodeAt(state.position + 1);
if (is_WS_OR_EOL(following)) {
isPair = isExplicitPair = true;
state.position++;
skipSeparationSpace(state, true, nodeIndent);
}
}
_line = state.line;
composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);
keyTag = state.tag;
keyNode = state.result;
skipSeparationSpace(state, true, nodeIndent);
ch = state.input.charCodeAt(state.position);
if ((isExplicitPair || state.line === _line) && ch === 0x3A/* : */) {
isPair = true;
ch = state.input.charCodeAt(++state.position);
skipSeparationSpace(state, true, nodeIndent);
composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);
valueNode = state.result;
}
if (isMapping) {
storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode);
} else if (isPair) {
_result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode));
} else {
_result.push(keyNode);
}
skipSeparationSpace(state, true, nodeIndent);
ch = state.input.charCodeAt(state.position);
if (ch === 0x2C/* , */) {
readNext = true;
ch = state.input.charCodeAt(++state.position);
} else {
readNext = false;
}
}
throwError(state, 'unexpected end of the stream within a flow collection');
}
function readBlockScalar(state, nodeIndent) {
var captureStart,
folding,
chomping = CHOMPING_CLIP,
didReadContent = false,
detectedIndent = false,
textIndent = nodeIndent,
emptyLines = 0,
atMoreIndented = false,
tmp,
ch;
ch = state.input.charCodeAt(state.position);
if (ch === 0x7C/* | */) {
folding = false;
} else if (ch === 0x3E/* > */) {
folding = true;
} else {
return false;
}
state.kind = 'scalar';
state.result = '';
while (ch !== 0) {
ch = state.input.charCodeAt(++state.position);
if (ch === 0x2B/* + */ || ch === 0x2D/* - */) {
if (CHOMPING_CLIP === chomping) {
chomping = (ch === 0x2B/* + */) ? CHOMPING_KEEP : CHOMPING_STRIP;
} else {
throwError(state, 'repeat of a chomping mode identifier');
}
} else if ((tmp = fromDecimalCode(ch)) >= 0) {
if (tmp === 0) {
throwError(state, 'bad explicit indentation width of a block scalar; it cannot be less than one');
} else if (!detectedIndent) {
textIndent = nodeIndent + tmp - 1;
detectedIndent = true;
} else {
throwError(state, 'repeat of an indentation width identifier');
}
} else {
break;
}
}
if (is_WHITE_SPACE(ch)) {
do { ch = state.input.charCodeAt(++state.position); }
while (is_WHITE_SPACE(ch));
if (ch === 0x23/* # */) {
do { ch = state.input.charCodeAt(++state.position); }
while (!is_EOL(ch) && (ch !== 0));
}
}
while (ch !== 0) {
readLineBreak(state);
state.lineIndent = 0;
ch = state.input.charCodeAt(state.position);
while ((!detectedIndent || state.lineIndent < textIndent) &&
(ch === 0x20/* Space */)) {
state.lineIndent++;
ch = state.input.charCodeAt(++state.position);
}
if (!detectedIndent && state.lineIndent > textIndent) {
textIndent = state.lineIndent;
}
if (is_EOL(ch)) {
emptyLines++;
continue;
}
// End of the scalar.
if (state.lineIndent < textIndent) {
// Perform the chomping.
if (chomping === CHOMPING_KEEP) {
state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines);
} else if (chomping === CHOMPING_CLIP) {
if (didReadContent) { // i.e. only if the scalar is not empty.
state.result += '\n';
}
}
// Break this `while` cycle and go to the funciton's epilogue.
break;
}
// Folded style: use fancy rules to handle line breaks.
if (folding) {
// Lines starting with white space characters (more-indented lines) are not folded.
if (is_WHITE_SPACE(ch)) {
atMoreIndented = true;
// except for the first content line (cf. Example 8.1)
state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines);
// End of more-indented block.
} else if (atMoreIndented) {
atMoreIndented = false;
state.result += common.repeat('\n', emptyLines + 1);
// Just one line break - perceive as the same line.
} else if (emptyLines === 0) {
if (didReadContent) { // i.e. only if we have already read some scalar content.
state.result += ' ';
}
// Several line breaks - perceive as different lines.
} else {
state.result += common.repeat('\n', emptyLines);
}
// Literal style: just add exact number of line breaks between content lines.
} else {
// Keep all line breaks except the header line break.
state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines);
}
didReadContent = true;
detectedIndent = true;
emptyLines = 0;
captureStart = state.position;
while (!is_EOL(ch) && (ch !== 0)) {
ch = state.input.charCodeAt(++state.position);
}
captureSegment(state, captureStart, state.position, false);
}
return true;
}
function readBlockSequence(state, nodeIndent) {
var _line,
_tag = state.tag,
_anchor = state.anchor,
_result = [],
following,
detected = false,
ch;
if (state.anchor !== null) {
state.anchorMap[state.anchor] = _result;
}
ch = state.input.charCodeAt(state.position);
while (ch !== 0) {
if (ch !== 0x2D/* - */) {
break;
}
following = state.input.charCodeAt(state.position + 1);
if (!is_WS_OR_EOL(following)) {
break;
}
detected = true;
state.position++;
if (skipSeparationSpace(state, true, -1)) {
if (state.lineIndent <= nodeIndent) {
_result.push(null);
ch = state.input.charCodeAt(state.position);
continue;
}
}
_line = state.line;
composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true);
_result.push(state.result);
skipSeparationSpace(state, true, -1);
ch = state.input.charCodeAt(state.position);
if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) {
throwError(state, 'bad indentation of a sequence entry');
} else if (state.lineIndent < nodeIndent) {
break;
}
}
if (detected) {
state.tag = _tag;
state.anchor = _anchor;
state.kind = 'sequence';
state.result = _result;
return true;
}
return false;
}
function readBlockMapping(state, nodeIndent, flowIndent) {
var following,
allowCompact,
_line,
_tag = state.tag,
_anchor = state.anchor,
_result = {},
overridableKeys = {},
keyTag = null,
keyNode = null,
valueNode = null,
atExplicitKey = false,
detected = false,
ch;
if (state.anchor !== null) {
state.anchorMap[state.anchor] = _result;
}
ch = state.input.charCodeAt(state.position);
while (ch !== 0) {
following = state.input.charCodeAt(state.position + 1);
_line = state.line; // Save the current line.
//
// Explicit notation case. There are two separate blocks:
// first for the key (denoted by "?") and second for the value (denoted by ":")
//
if ((ch === 0x3F/* ? */ || ch === 0x3A/* : */) && is_WS_OR_EOL(following)) {
if (ch === 0x3F/* ? */) {
if (atExplicitKey) {
storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null);
keyTag = keyNode = valueNode = null;
}
detected = true;
atExplicitKey = true;
allowCompact = true;
} else if (atExplicitKey) {
// i.e. 0x3A/* : */ === character after the explicit key.
atExplicitKey = false;
allowCompact = true;
} else {
throwError(state, 'incomplete explicit mapping pair; a key node is missed');
}
state.position += 1;
ch = following;
//
// Implicit notation case. Flow-style node as the key first, then ":", and the value.
//
} else if (composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) {
if (state.line === _line) {
ch = state.input.charCodeAt(state.position);
while (is_WHITE_SPACE(ch)) {
ch = state.input.charCodeAt(++state.position);
}
if (ch === 0x3A/* : */) {
ch = state.input.charCodeAt(++state.position);
if (!is_WS_OR_EOL(ch)) {
throwError(state, 'a whitespace character is expected after the key-value separator within a block mapping');
}
if (atExplicitKey) {
storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null);
keyTag = keyNode = valueNode = null;
}
detected = true;
atExplicitKey = false;
allowCompact = false;
keyTag = state.tag;
keyNode = state.result;
} else if (detected) {
throwError(state, 'can not read an implicit mapping pair; a colon is missed');
} else {
state.tag = _tag;
state.anchor = _anchor;
return true; // Keep the result of `composeNode`.
}
} else if (detected) {
throwError(state, 'can not read a block mapping entry; a multiline key may not be an implicit key');
} else {
state.tag = _tag;
state.anchor = _anchor;
return true; // Keep the result of `composeNode`.
}
} else {
break; // Reading is done. Go to the epilogue.
}
//
// Common reading code for both explicit and implicit notations.
//
if (state.line === _line || state.lineIndent > nodeIndent) {
if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) {
if (atExplicitKey) {
keyNode = state.result;
} else {
valueNode = state.result;
}
}
if (!atExplicitKey) {
storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode);
keyTag = keyNode = valueNode = null;
}
skipSeparationSpace(state, true, -1);
ch = state.input.charCodeAt(state.position);
}
if (state.lineIndent > nodeIndent && (ch !== 0)) {
throwError(state, 'bad indentation of a mapping entry');
} else if (state.lineIndent < nodeIndent) {
break;
}
}
//
// Epilogue.
//
// Special case: last mapping's node contains only the key in explicit notation.
if (atExplicitKey) {
storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null);
}
// Expose the resulting mapping.
if (detected) {
state.tag = _tag;
state.anchor = _anchor;
state.kind = 'mapping';
state.result = _result;
}
return detected;
}
function readTagProperty(state) {
var _position,
isVerbatim = false,
isNamed = false,
tagHandle,
tagName,
ch;
ch = state.input.charCodeAt(state.position);
if (ch !== 0x21/* ! */) return false;
if (state.tag !== null) {
throwError(state, 'duplication of a tag property');
}
ch = state.input.charCodeAt(++state.position);
if (ch === 0x3C/* < */) {
isVerbatim = true;
ch = state.input.charCodeAt(++state.position);
} else if (ch === 0x21/* ! */) {
isNamed = true;
tagHandle = '!!';
ch = state.input.charCodeAt(++state.position);
} else {
tagHandle = '!';
}
_position = state.position;
if (isVerbatim) {
do { ch = state.input.charCodeAt(++state.position); }
while (ch !== 0 && ch !== 0x3E/* > */);
if (state.position < state.length) {
tagName = state.input.slice(_position, state.position);
ch = state.input.charCodeAt(++state.position);
} else {
throwError(state, 'unexpected end of the stream within a verbatim tag');
}
} else {
while (ch !== 0 && !is_WS_OR_EOL(ch)) {
if (ch === 0x21/* ! */) {
if (!isNamed) {
tagHandle = state.input.slice(_position - 1, state.position + 1);
if (!PATTERN_TAG_HANDLE.test(tagHandle)) {
throwError(state, 'named tag handle cannot contain such characters');
}
isNamed = true;
_position = state.position + 1;
} else {
throwError(state, 'tag suffix cannot contain exclamation marks');
}
}
ch = state.input.charCodeAt(++state.position);
}
tagName = state.input.slice(_position, state.position);
if (PATTERN_FLOW_INDICATORS.test(tagName)) {
throwError(state, 'tag suffix cannot contain flow indicator characters');
}
}
if (tagName && !PATTERN_TAG_URI.test(tagName)) {
throwError(state, 'tag name cannot contain such characters: ' + tagName);
}
if (isVerbatim) {
state.tag = tagName;
} else if (_hasOwnProperty.call(state.tagMap, tagHandle)) {
state.tag = state.tagMap[tagHandle] + tagName;
} else if (tagHandle === '!') {
state.tag = '!' + tagName;
} else if (tagHandle === '!!') {
state.tag = 'tag:yaml.org,2002:' + tagName;
} else {
throwError(state, 'undeclared tag handle "' + tagHandle + '"');
}
return true;
}
function readAnchorProperty(state) {
var _position,
ch;
ch = state.input.charCodeAt(state.position);
if (ch !== 0x26/* & */) return false;
if (state.anchor !== null) {
throwError(state, 'duplication of an anchor property');
}
ch = state.input.charCodeAt(++state.position);
_position = state.position;
while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {
ch = state.input.charCodeAt(++state.position);
}
if (state.position === _position) {
throwError(state, 'name of an anchor node must contain at least one character');
}
state.anchor = state.input.slice(_position, state.position);
return true;
}
function readAlias(state) {
var _position, alias,
ch;
ch = state.input.charCodeAt(state.position);
if (ch !== 0x2A/* * */) return false;
ch = state.input.charCodeAt(++state.position);
_position = state.position;
while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {
ch = state.input.charCodeAt(++state.position);
}
if (state.position === _position) {
throwError(state, 'name of an alias node must contain at least one character');
}
alias = state.input.slice(_position, state.position);
if (!state.anchorMap.hasOwnProperty(alias)) {
throwError(state, 'unidentified alias "' + alias + '"');
}
state.result = state.anchorMap[alias];
skipSeparationSpace(state, true, -1);
return true;
}
function composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) {
var allowBlockStyles,
allowBlockScalars,
allowBlockCollections,
indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this<parent
atNewLine = false,
hasContent = false,
typeIndex,
typeQuantity,
type,
flowIndent,
blockIndent;
if (state.listener !== null) {
state.listener('open', state);
}
state.tag = null;
state.anchor = null;
state.kind = null;
state.result = null;
allowBlockStyles = allowBlockScalars = allowBlockCollections =
CONTEXT_BLOCK_OUT === nodeContext ||
CONTEXT_BLOCK_IN === nodeContext;
if (allowToSeek) {
if (skipSeparationSpace(state, true, -1)) {
atNewLine = true;
if (state.lineIndent > parentIndent) {
indentStatus = 1;
} else if (state.lineIndent === parentIndent) {
indentStatus = 0;
} else if (state.lineIndent < parentIndent) {
indentStatus = -1;
}
}
}
if (indentStatus === 1) {
while (readTagProperty(state) || readAnchorProperty(state)) {
if (skipSeparationSpace(state, true, -1)) {
atNewLine = true;
allowBlockCollections = allowBlockStyles;
if (state.lineIndent > parentIndent) {
indentStatus = 1;
} else if (state.lineIndent === parentIndent) {
indentStatus = 0;
} else if (state.lineIndent < parentIndent) {
indentStatus = -1;
}
} else {
allowBlockCollections = false;
}
}
}
if (allowBlockCollections) {
allowBlockCollections = atNewLine || allowCompact;
}
if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) {
if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) {
flowIndent = parentIndent;
} else {
flowIndent = parentIndent + 1;
}
blockIndent = state.position - state.lineStart;
if (indentStatus === 1) {
if (allowBlockCollections &&
(readBlockSequence(state, blockIndent) ||
readBlockMapping(state, blockIndent, flowIndent)) ||
readFlowCollection(state, flowIndent)) {
hasContent = true;
} else {
if ((allowBlockScalars && readBlockScalar(state, flowIndent)) ||
readSingleQuotedScalar(state, flowIndent) ||
readDoubleQuotedScalar(state, flowIndent)) {
hasContent = true;
} else if (readAlias(state)) {
hasContent = true;
if (state.tag !== null || state.anchor !== null) {
throwError(state, 'alias node should not have any properties');
}
} else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) {
hasContent = true;
if (state.tag === null) {
state.tag = '?';
}
}
if (state.anchor !== null) {
state.anchorMap[state.anchor] = state.result;
}
}
} else if (indentStatus === 0) {
// Special case: block sequences are allowed to have same indentation level as the parent.
// http://www.yaml.org/spec/1.2/spec.html#id2799784
hasContent = allowBlockCollections && readBlockSequence(state, blockIndent);
}
}
if (state.tag !== null && state.tag !== '!') {
if (state.tag === '?') {
for (typeIndex = 0, typeQuantity = state.implicitTypes.length;
typeIndex < typeQuantity;
typeIndex += 1) {
type = state.implicitTypes[typeIndex];
// Implicit resolving is not allowed for non-scalar types, and '?'
// non-specific tag is only assigned to plain scalars. So, it isn't
// needed to check for 'kind' conformity.
if (type.resolve(state.result)) { // `state.result` updated in resolver if matched
state.result = type.construct(state.result);
state.tag = type.tag;
if (state.anchor !== null) {
state.anchorMap[state.anchor] = state.result;
}
break;
}
}
} else if (_hasOwnProperty.call(state.typeMap, state.tag)) {
type = state.typeMap[state.tag];
if (state.result !== null && type.kind !== state.kind) {
throwError(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be "' + type.kind + '", not "' + state.kind + '"');
}
if (!type.resolve(state.result)) { // `state.result` updated in resolver if matched
throwError(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag');
} else {
state.result = type.construct(state.result);
if (state.anchor !== null) {
state.anchorMap[state.anchor] = state.result;
}
}
} else {
throwError(state, 'unknown tag !<' + state.tag + '>');
}
}
if (state.listener !== null) {
state.listener('close', state);
}
return state.tag !== null || state.anchor !== null || hasContent;
}
function readDocument(state) {
var documentStart = state.position,
_position,
directiveName,
directiveArgs,
hasDirectives = false,
ch;
state.version = null;
state.checkLineBreaks = state.legacy;
state.tagMap = {};
state.anchorMap = {};
while ((ch = state.input.charCodeAt(state.position)) !== 0) {
skipSeparationSpace(state, true, -1);
ch = state.input.charCodeAt(state.position);
if (state.lineIndent > 0 || ch !== 0x25/* % */) {
break;
}
hasDirectives = true;
ch = state.input.charCodeAt(++state.position);
_position = state.position;
while (ch !== 0 && !is_WS_OR_EOL(ch)) {
ch = state.input.charCodeAt(++state.position);
}
directiveName = state.input.slice(_position, state.position);
directiveArgs = [];
if (directiveName.length < 1) {
throwError(state, 'directive name must not be less than one character in length');
}
while (ch !== 0) {
while (is_WHITE_SPACE(ch)) {
ch = state.input.charCodeAt(++state.position);
}
if (ch === 0x23/* # */) {
do { ch = state.input.charCodeAt(++state.position); }
while (ch !== 0 && !is_EOL(ch));
break;
}
if (is_EOL(ch)) break;
_position = state.position;
while (ch !== 0 && !is_WS_OR_EOL(ch)) {
ch = state.input.charCodeAt(++state.position);
}
directiveArgs.push(state.input.slice(_position, state.position));
}
if (ch !== 0) readLineBreak(state);
if (_hasOwnProperty.call(directiveHandlers, directiveName)) {
directiveHandlers[directiveName](state, directiveName, directiveArgs);
} else {
throwWarning(state, 'unknown document directive "' + directiveName + '"');
}
}
skipSeparationSpace(state, true, -1);
if (state.lineIndent === 0 &&
state.input.charCodeAt(state.position) === 0x2D/* - */ &&
state.input.charCodeAt(state.position + 1) === 0x2D/* - */ &&
state.input.charCodeAt(state.position + 2) === 0x2D/* - */) {
state.position += 3;
skipSeparationSpace(state, true, -1);
} else if (hasDirectives) {
throwError(state, 'directives end mark is expected');
}
composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true);
skipSeparationSpace(state, true, -1);
if (state.checkLineBreaks &&
PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) {
throwWarning(state, 'non-ASCII line breaks are interpreted as content');
}
state.documents.push(state.result);
if (state.position === state.lineStart && testDocumentSeparator(state)) {
if (state.input.charCodeAt(state.position) === 0x2E/* . */) {
state.position += 3;
skipSeparationSpace(state, true, -1);
}
return;
}
if (state.position < (state.length - 1)) {
throwError(state, 'end of the stream or a document separator is expected');
} else {
return;
}
}
function loadDocuments(input, options) {
input = String(input);
options = options || {};
if (input.length !== 0) {
// Add tailing `\n` if not exists
if (input.charCodeAt(input.length - 1) !== 0x0A/* LF */ &&
input.charCodeAt(input.length - 1) !== 0x0D/* CR */) {
input += '\n';
}
// Strip BOM
if (input.charCodeAt(0) === 0xFEFF) {
input = input.slice(1);
}
}
var state = new State(input, options);
// Use 0 as string terminator. That significantly simplifies bounds check.
state.input += '\0';
while (state.input.charCodeAt(state.position) === 0x20/* Space */) {
state.lineIndent += 1;
state.position += 1;
}
while (state.position < (state.length - 1)) {
readDocument(state);
}
return state.documents;
}
function loadAll(input, iterator, options) {
var documents = loadDocuments(input, options), index, length;
for (index = 0, length = documents.length; index < length; index += 1) {
iterator(documents[index]);
}
}
function load(input, options) {
var documents = loadDocuments(input, options);
if (documents.length === 0) {
/*eslint-disable no-undefined*/
return undefined;
} else if (documents.length === 1) {
return documents[0];
}
throw new YAMLException('expected a single document in the stream, but found more');
}
function safeLoadAll(input, output, options) {
loadAll(input, output, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options));
}
function safeLoad(input, options) {
return load(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options));
}
module.exports.loadAll = loadAll;
module.exports.load = load;
module.exports.safeLoadAll = safeLoadAll;
module.exports.safeLoad = safeLoad;
},{"./common":21,"./exception":23,"./mark":25,"./schema/default_full":28,"./schema/default_safe":29}],25:[function(require,module,exports){
'use strict';
var common = require('./common');
function Mark(name, buffer, position, line, column) {
this.name = name;
this.buffer = buffer;
this.position = position;
this.line = line;
this.column = column;
}
Mark.prototype.getSnippet = function getSnippet(indent, maxLength) {
var head, start, tail, end, snippet;
if (!this.buffer) return null;
indent = indent || 4;
maxLength = maxLength || 75;
head = '';
start = this.position;
while (start > 0 && '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(start - 1)) === -1) {
start -= 1;
if (this.position - start > (maxLength / 2 - 1)) {
head = ' ... ';
start += 5;
break;
}
}
tail = '';
end = this.position;
while (end < this.buffer.length && '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(end)) === -1) {
end += 1;
if (end - this.position > (maxLength / 2 - 1)) {
tail = ' ... ';
end -= 5;
break;
}
}
snippet = this.buffer.slice(start, end);
return common.repeat(' ', indent) + head + snippet + tail + '\n' +
common.repeat(' ', indent + this.position - start + head.length) + '^';
};
Mark.prototype.toString = function toString(compact) {
var snippet, where = '';
if (this.name) {
where += 'in "' + this.name + '" ';
}
where += 'at line ' + (this.line + 1) + ', column ' + (this.column + 1);
if (!compact) {
snippet = this.getSnippet();
if (snippet) {
where += ':\n' + snippet;
}
}
return where;
};
module.exports = Mark;
},{"./common":21}],26:[function(require,module,exports){
'use strict';
/*eslint-disable max-len*/
var common = require('./common');
var YAMLException = require('./exception');
var Type = require('./type');
function compileList(schema, name, result) {
var exclude = [];
schema.include.forEach(function (includedSchema) {
result = compileList(includedSchema, name, result);
});
schema[name].forEach(function (currentType) {
result.forEach(function (previousType, previousIndex) {
if (previousType.tag === currentType.tag) {
exclude.push(previousIndex);
}
});
result.push(currentType);
});
return result.filter(function (type, index) {
return exclude.indexOf(index) === -1;
});
}
function compileMap(/* lists... */) {
var result = {}, index, length;
function collectType(type) {
result[type.tag] = type;
}
for (index = 0, length = arguments.length; index < length; index += 1) {
arguments[index].forEach(collectType);
}
return result;
}
function Schema(definition) {
this.include = definition.include || [];
this.implicit = definition.implicit || [];
this.explicit = definition.explicit || [];
this.implicit.forEach(function (type) {
if (type.loadKind && type.loadKind !== 'scalar') {
throw new YAMLException('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.');
}
});
this.compiledImplicit = compileList(this, 'implicit', []);
this.compiledExplicit = compileList(this, 'explicit', []);
this.compiledTypeMap = compileMap(this.compiledImplicit, this.compiledExplicit);
}
Schema.DEFAULT = null;
Schema.create = function createSchema() {
var schemas, types;
switch (arguments.length) {
case 1:
schemas = Schema.DEFAULT;
types = arguments[0];
break;
case 2:
schemas = arguments[0];
types = arguments[1];
break;
default:
throw new YAMLException('Wrong number of arguments for Schema.create function');
}
schemas = common.toArray(schemas);
types = common.toArray(types);
if (!schemas.every(function (schema) { return schema instanceof Schema; })) {
throw new YAMLException('Specified list of super schemas (or a single Schema object) contains a non-Schema object.');
}
if (!types.every(function (type) { return type instanceof Type; })) {
throw new YAMLException('Specified list of YAML types (or a single Type object) contains a non-Type object.');
}
return new Schema({
include: schemas,
explicit: types
});
};
module.exports = Schema;
},{"./common":21,"./exception":23,"./type":32}],27:[function(require,module,exports){
// Standard YAML's Core schema.
// http://www.yaml.org/spec/1.2/spec.html#id2804923
//
// NOTE: JS-YAML does not support schema-specific tag resolution restrictions.
// So, Core schema has no distinctions from JSON schema is JS-YAML.
'use strict';
var Schema = require('../schema');
module.exports = new Schema({
include: [
require('./json')
]
});
},{"../schema":26,"./json":31}],28:[function(require,module,exports){
// JS-YAML's default schema for `load` function.
// It is not described in the YAML specification.
//
// This schema is based on JS-YAML's default safe schema and includes
// JavaScript-specific types: !!js/undefined, !!js/regexp and !!js/function.
//
// Also this schema is used as default base schema at `Schema.create` function.
'use strict';
var Schema = require('../schema');
module.exports = Schema.DEFAULT = new Schema({
include: [
require('./default_safe')
],
explicit: [
require('../type/js/undefined'),
require('../type/js/regexp'),
require('../type/js/function')
]
});
},{"../schema":26,"../type/js/function":37,"../type/js/regexp":38,"../type/js/undefined":39,"./default_safe":29}],29:[function(require,module,exports){
// JS-YAML's default schema for `safeLoad` function.
// It is not described in the YAML specification.
//
// This schema is based on standard YAML's Core schema and includes most of
// extra types described at YAML tag repository. (http://yaml.org/type/)
'use strict';
var Schema = require('../schema');
module.exports = new Schema({
include: [
require('./core')
],
implicit: [
require('../type/timestamp'),
require('../type/merge')
],
explicit: [
require('../type/binary'),
require('../type/omap'),
require('../type/pairs'),
require('../type/set')
]
});
},{"../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){
// Standard YAML's Failsafe schema.
// http://www.yaml.org/spec/1.2/spec.html#id2802346
'use strict';
var Schema = require('../schema');
module.exports = new Schema({
explicit: [
require('../type/str'),
require('../type/seq'),
require('../type/map')
]
});
},{"../schema":26,"../type/map":40,"../type/seq":45,"../type/str":47}],31:[function(require,module,exports){
// Standard YAML's JSON schema.
// http://www.yaml.org/spec/1.2/spec.html#id2803231
//
// NOTE: JS-YAML does not support schema-specific tag resolution restrictions.
// So, this schema is not such strict as defined in the YAML specification.
// It allows numbers in binary notaion, use `Null` and `NULL` as `null`, etc.
'use strict';
var Schema = require('../schema');
module.exports = new Schema({
include: [
require('./failsafe')
],
implicit: [
require('../type/null'),
require('../type/bool'),
require('../type/int'),
require('../type/float')
]
});
},{"../schema":26,"../type/bool":34,"../type/float":35,"../type/int":36,"../type/null":42,"./failsafe":30}],32:[function(require,module,exports){
'use strict';
var YAMLException = require('./exception');
var TYPE_CONSTRUCTOR_OPTIONS = [
'kind',
'resolve',
'construct',
'instanceOf',
'predicate',
'represent',
'defaultStyle',
'styleAliases'
];
var YAML_NODE_KINDS = [
'scalar',
'sequence',
'mapping'
];
function compileStyleAliases(map) {
var result = {};
if (map !== null) {
Object.keys(map).forEach(function (style) {
map[style].forEach(function (alias) {
result[String(alias)] = style;
});
});
}
return result;
}
function Type(tag, options) {
options = options || {};
Object.keys(options).forEach(function (name) {
if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) {
throw new YAMLException('Unknown option "' + name + '" is met in definition of "' + tag + '" YAML type.');
}
});
// TODO: Add tag format check.
this.tag = tag;
this.kind = options['kind'] || null;
this.resolve = options['resolve'] || function () { return true; };
this.construct = options['construct'] || function (data) { return data; };
this.instanceOf = options['instanceOf'] || null;
this.predicate = options['predicate'] || null;
this.represent = options['represent'] || null;
this.defaultStyle = options['defaultStyle'] || null;
this.styleAliases = compileStyleAliases(options['styleAliases'] || null);
if (YAML_NODE_KINDS.indexOf(this.kind) === -1) {
throw new YAMLException('Unknown kind "' + this.kind + '" is specified for "' + tag + '" YAML type.');
}
}
module.exports = Type;
},{"./exception":23}],33:[function(require,module,exports){
'use strict';
/*eslint-disable no-bitwise*/
var NodeBuffer;
try {
// A trick for browserified version, to not include `Buffer` shim
var _require = require;
NodeBuffer = _require('buffer').Buffer;
} catch (__) {}
var Type = require('../type');
// [ 64, 65, 66 ] -> [ padding, CR, LF ]
var BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r';
function resolveYamlBinary(data) {
if (data === null) return false;
var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP;
// Convert one by one.
for (idx = 0; idx < max; idx++) {
code = map.indexOf(data.charAt(idx));
// Skip CR/LF
if (code > 64) continue;
// Fail on illegal characters
if (code < 0) return false;
bitlen += 6;
}
// If there are any bits left, source was corrupted
return (bitlen % 8) === 0;
}
function constructYamlBinary(data) {
var idx, tailbits,
input = data.replace(/[\r\n=]/g, ''), // remove CR/LF & padding to simplify scan
max = input.length,
map = BASE64_MAP,
bits = 0,
result = [];
// Collect by 6*4 bits (3 bytes)
for (idx = 0; idx < max; idx++) {
if ((idx % 4 === 0) && idx) {
result.push((bits >> 16) & 0xFF);
result.push((bits >> 8) & 0xFF);
result.push(bits & 0xFF);
}
bits = (bits << 6) | map.indexOf(input.charAt(idx));
}
// Dump tail
tailbits = (max % 4) * 6;
if (tailbits === 0) {
result.push((bits >> 16) & 0xFF);
result.push((bits >> 8) & 0xFF);
result.push(bits & 0xFF);
} else if (tailbits === 18) {
result.push((bits >> 10) & 0xFF);
result.push((bits >> 2) & 0xFF);
} else if (tailbits === 12) {
result.push((bits >> 4) & 0xFF);
}
// Wrap into Buffer for NodeJS and leave Array for browser
if (NodeBuffer) return new NodeBuffer(result);
return result;
}
function representYamlBinary(object /*, style*/) {
var result = '', bits = 0, idx, tail,
max = object.length,
map = BASE64_MAP;
// Convert every three bytes to 4 ASCII characters.
for (idx = 0; idx < max; idx++) {
if ((idx % 3 === 0) && idx) {
result += map[(bits >> 18) & 0x3F];
result += map[(bits >> 12) & 0x3F];
result += map[(bits >> 6) & 0x3F];
result += map[bits & 0x3F];
}
bits = (bits << 8) + object[idx];
}
// Dump tail
tail = max % 3;
if (tail === 0) {
result += map[(bits >> 18) & 0x3F];
result += map[(bits >> 12) & 0x3F];
result += map[(bits >> 6) & 0x3F];
result += map[bits & 0x3F];
} else if (tail === 2) {
result += map[(bits >> 10) & 0x3F];
result += map[(bits >> 4) & 0x3F];
result += map[(bits << 2) & 0x3F];
result += map[64];
} else if (tail === 1) {
result += map[(bits >> 2) & 0x3F];
result += map[(bits << 4) & 0x3F];
result += map[64];
result += map[64];
}
return result;
}
function isBinary(object) {
return NodeBuffer && NodeBuffer.isBuffer(object);
}
module.exports = new Type('tag:yaml.org,2002:binary', {
kind: 'scalar',
resolve: resolveYamlBinary,
construct: constructYamlBinary,
predicate: isBinary,
represent: representYamlBinary
});
},{"../type":32}],34:[function(require,module,exports){
'use strict';
var Type = require('../type');
function resolveYamlBoolean(data) {
if (data === null) return false;
var max = data.length;
return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) ||
(max === 5 && (data === 'false' || data === 'False' || data === 'FALSE'));
}
function constructYamlBoolean(data) {
return data === 'true' ||
data === 'True' ||
data === 'TRUE';
}
function isBoolean(object) {
return Object.prototype.toString.call(object) === '[object Boolean]';
}
module.exports = new Type('tag:yaml.org,2002:bool', {
kind: 'scalar',
resolve: resolveYamlBoolean,
construct: constructYamlBoolean,
predicate: isBoolean,
represent: {
lowercase: function (object) { return object ? 'true' : 'false'; },
uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; },
camelcase: function (object) { return object ? 'True' : 'False'; }
},
defaultStyle: 'lowercase'
});
},{"../type":32}],35:[function(require,module,exports){
'use strict';
var common = require('../common');
var Type = require('../type');
var YAML_FLOAT_PATTERN = new RegExp(
'^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?' +
'|\\.[0-9_]+(?:[eE][-+][0-9]+)?' +
'|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*' +
'|[-+]?\\.(?:inf|Inf|INF)' +
'|\\.(?:nan|NaN|NAN))$');
function resolveYamlFloat(data) {
if (data === null) return false;
if (!YAML_FLOAT_PATTERN.test(data)) return false;
return true;
}
function constructYamlFloat(data) {
var value, sign, base, digits;
value = data.replace(/_/g, '').toLowerCase();
sign = value[0] === '-' ? -1 : 1;
digits = [];
if ('+-'.indexOf(value[0]) >= 0) {
value = value.slice(1);
}
if (value === '.inf') {
return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
} else if (value === '.nan') {
return NaN;
} else if (value.indexOf(':') >= 0) {
value.split(':').forEach(function (v) {
digits.unshift(parseFloat(v, 10));
});
value = 0.0;
base = 1;
digits.forEach(function (d) {
value += d * base;
base *= 60;
});
return sign * value;
}
return sign * parseFloat(value, 10);
}
var SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/;
function representYamlFloat(object, style) {
var res;
if (isNaN(object)) {
switch (style) {
case 'lowercase': return '.nan';
case 'uppercase': return '.NAN';
case 'camelcase': return '.NaN';
}
} else if (Number.POSITIVE_INFINITY === object) {
switch (style) {
case 'lowercase': return '.inf';
case 'uppercase': return '.INF';
case 'camelcase': return '.Inf';
}
} else if (Number.NEGATIVE_INFINITY === object) {
switch (style) {
case 'lowercase': return '-.inf';
case 'uppercase': return '-.INF';
case 'camelcase': return '-.Inf';
}
} else if (common.isNegativeZero(object)) {
return '-0.0';
}
res = object.toString(10);
// JS stringifier can build scientific format without dots: 5e-100,
// while YAML requres dot: 5.e-100. Fix it with simple hack
return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res;
}
function isFloat(object) {
return (Object.prototype.toString.call(object) === '[object Number]') &&
(object % 1 !== 0 || common.isNegativeZero(object));
}
module.exports = new Type('tag:yaml.org,2002:float', {
kind: 'scalar',
resolve: resolveYamlFloat,
construct: constructYamlFloat,
predicate: isFloat,
represent: representYamlFloat,
defaultStyle: 'lowercase'
});
},{"../common":21,"../type":32}],36:[function(require,module,exports){
'use strict';
var common = require('../common');
var Type = require('../type');
function isHexCode(c) {
return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) ||
((0x41/* A */ <= c) && (c <= 0x46/* F */)) ||
((0x61/* a */ <= c) && (c <= 0x66/* f */));
}
function isOctCode(c) {
return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */));
}
function isDecCode(c) {
return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */));
}
function resolveYamlInteger(data) {
if (data === null) return false;
var max = data.length,
index = 0,
hasDigits = false,
ch;
if (!max) return false;
ch = data[index];
// sign
if (ch === '-' || ch === '+') {
ch = data[++index];
}
if (ch === '0') {
// 0
if (index + 1 === max) return true;
ch = data[++index];
// base 2, base 8, base 16
if (ch === 'b') {
// base 2
index++;
for (; index < max; index++) {
ch = data[index];
if (ch === '_') continue;
if (ch !== '0' && ch !== '1') return false;
hasDigits = true;
}
return hasDigits;
}
if (ch === 'x') {
// base 16
index++;
for (; index < max; index++) {
ch = data[index];
if (ch === '_') continue;
if (!isHexCode(data.charCodeAt(index))) return false;
hasDigits = true;
}
return hasDigits;
}
// base 8
for (; index < max; index++) {
ch = data[index];
if (ch === '_') continue;
if (!isOctCode(data.charCodeAt(index))) return false;
hasDigits = true;
}
return hasDigits;
}
// base 10 (except 0) or base 60
for (; index < max; index++) {
ch = data[index];
if (ch === '_') continue;
if (ch === ':') break;
if (!isDecCode(data.charCodeAt(index))) {
return false;
}
hasDigits = true;
}
if (!hasDigits) return false;
// if !base60 - done;
if (ch !== ':') return true;
// base60 almost not used, no needs to optimize
return /^(:[0-5]?[0-9])+$/.test(data.slice(index));
}
function constructYamlInteger(data) {
var value = data, sign = 1, ch, base, digits = [];
if (value.indexOf('_') !== -1) {
value = value.replace(/_/g, '');
}
ch = value[0];
if (ch === '-' || ch === '+') {
if (ch === '-') sign = -1;
value = value.slice(1);
ch = value[0];
}
if (value === '0') return 0;
if (ch === '0') {
if (value[1] === 'b') return sign * parseInt(value.slice(2), 2);
if (value[1] === 'x') return sign * parseInt(value, 16);
return sign * parseInt(value, 8);
}
if (value.indexOf(':') !== -1) {
value.split(':').forEach(function (v) {
digits.unshift(parseInt(v, 10));
});
value = 0;
base = 1;
digits.forEach(function (d) {
value += (d * base);
base *= 60;
});
return sign * value;
}
return sign * parseInt(value, 10);
}
function isInteger(object) {
return (Object.prototype.toString.call(object)) === '[object Number]' &&
(object % 1 === 0 && !common.isNegativeZero(object));
}
module.exports = new Type('tag:yaml.org,2002:int', {
kind: 'scalar',
resolve: resolveYamlInteger,
construct: constructYamlInteger,
predicate: isInteger,
represent: {
binary: function (object) { return '0b' + object.toString(2); },
octal: function (object) { return '0' + object.toString(8); },
decimal: function (object) { return object.toString(10); },
hexadecimal: function (object) { return '0x' + object.toString(16).toUpperCase(); }
},
defaultStyle: 'decimal',
styleAliases: {
binary: [ 2, 'bin' ],
octal: [ 8, 'oct' ],
decimal: [ 10, 'dec' ],
hexadecimal: [ 16, 'hex' ]
}
});
},{"../common":21,"../type":32}],37:[function(require,module,exports){
'use strict';
var esprima;
// Browserified version does not have esprima
//
// 1. For node.js just require module as deps
// 2. For browser try to require mudule via external AMD system.
// If not found - try to fallback to window.esprima. If not
// found too - then fail to parse.
//
try {
// workaround to exclude package from browserify list.
var _require = require;
esprima = _require('esprima');
} catch (_) {
/*global window */
if (typeof window !== 'undefined') esprima = window.esprima;
}
var Type = require('../../type');
function resolveJavascriptFunction(data) {
if (data === null) return false;
try {
var source = '(' + data + ')',
ast = esprima.parse(source, { range: true });
if (ast.type !== 'Program' ||
ast.body.length !== 1 ||
ast.body[0].type !== 'ExpressionStatement' ||
ast.body[0].expression.type !== 'FunctionExpression') {
return false;
}
return true;
} catch (err) {
return false;
}
}
function constructJavascriptFunction(data) {
/*jslint evil:true*/
var source = '(' + data + ')',
ast = esprima.parse(source, { range: true }),
params = [],
body;
if (ast.type !== 'Program' ||
ast.body.length !== 1 ||
ast.body[0].type !== 'ExpressionStatement' ||
ast.body[0].expression.type !== 'FunctionExpression') {
throw new Error('Failed to resolve function');
}
ast.body[0].expression.params.forEach(function (param) {
params.push(param.name);
});
body = ast.body[0].expression.body.range;
// Esprima's ranges include the first '{' and the last '}' characters on
// function expressions. So cut them out.
/*eslint-disable no-new-func*/
return new Function(params, source.slice(body[0] + 1, body[1] - 1));
}
function representJavascriptFunction(object /*, style*/) {
return object.toString();
}
function isFunction(object) {
return Object.prototype.toString.call(object) === '[object Function]';
}
module.exports = new Type('tag:yaml.org,2002:js/function', {
kind: 'scalar',
resolve: resolveJavascriptFunction,
construct: constructJavascriptFunction,
predicate: isFunction,
represent: representJavascriptFunction
});
},{"../../type":32}],38:[function(require,module,exports){
'use strict';
var Type = require('../../type');
function resolveJavascriptRegExp(data) {
if (data === null) return false;
if (data.length === 0) return false;
var regexp = data,
tail = /\/([gim]*)$/.exec(data),
modifiers = '';
// if regexp starts with '/' it can have modifiers and must be properly closed
// `/foo/gim` - modifiers tail can be maximum 3 chars
if (regexp[0] === '/') {
if (tail) modifiers = tail[1];
if (modifiers.length > 3) return false;
// if expression starts with /, is should be properly terminated
if (regexp[regexp.length - modifiers.length - 1] !== '/') return false;
}
return true;
}
function constructJavascriptRegExp(data) {
var regexp = data,
tail = /\/([gim]*)$/.exec(data),
modifiers = '';
// `/foo/gim` - tail can be maximum 4 chars
if (regexp[0] === '/') {
if (tail) modifiers = tail[1];
regexp = regexp.slice(1, regexp.length - modifiers.length - 1);
}
return new RegExp(regexp, modifiers);
}
function representJavascriptRegExp(object /*, style*/) {
var result = '/' + object.source + '/';
if (object.global) result += 'g';
if (object.multiline) result += 'm';
if (object.ignoreCase) result += 'i';
return result;
}
function isRegExp(object) {
return Object.prototype.toString.call(object) === '[object RegExp]';
}
module.exports = new Type('tag:yaml.org,2002:js/regexp', {
kind: 'scalar',
resolve: resolveJavascriptRegExp,
construct: constructJavascriptRegExp,
predicate: isRegExp,
represent: representJavascriptRegExp
});
},{"../../type":32}],39:[function(require,module,exports){
'use strict';
var Type = require('../../type');
function resolveJavascriptUndefined() {
return true;
}
function constructJavascriptUndefined() {
/*eslint-disable no-undefined*/
return undefined;
}
function representJavascriptUndefined() {
return '';
}
function isUndefined(object) {
return typeof object === 'undefined';
}
module.exports = new Type('tag:yaml.org,2002:js/undefined', {
kind: 'scalar',
resolve: resolveJavascriptUndefined,
construct: constructJavascriptUndefined,
predicate: isUndefined,
represent: representJavascriptUndefined
});
},{"../../type":32}],40:[function(require,module,exports){
'use strict';
var Type = require('../type');
module.exports = new Type('tag:yaml.org,2002:map', {
kind: 'mapping',
construct: function (data) { return data !== null ? data : {}; }
});
},{"../type":32}],41:[function(require,module,exports){
'use strict';
var Type = require('../type');
function resolveYamlMerge(data) {
return data === '<<' || data === null;
}
module.exports = new Type('tag:yaml.org,2002:merge', {
kind: 'scalar',
resolve: resolveYamlMerge
});
},{"../type":32}],42:[function(require,module,exports){
'use strict';
var Type = require('../type');
function resolveYamlNull(data) {
if (data === null) return true;
var max = data.length;
return (max === 1 && data === '~') ||
(max === 4 && (data === 'null' || data === 'Null' || data === 'NULL'));
}
function constructYamlNull() {
return null;
}
function isNull(object) {
return object === null;
}
module.exports = new Type('tag:yaml.org,2002:null', {
kind: 'scalar',
resolve: resolveYamlNull,
construct: constructYamlNull,
predicate: isNull,
represent: {
canonical: function () { return '~'; },
lowercase: function () { return 'null'; },
uppercase: function () { return 'NULL'; },
camelcase: function () { return 'Null'; }
},
defaultStyle: 'lowercase'
});
},{"../type":32}],43:[function(require,module,exports){
'use strict';
var Type = require('../type');
var _hasOwnProperty = Object.prototype.hasOwnProperty;
var _toString = Object.prototype.toString;
function resolveYamlOmap(data) {
if (data === null) return true;
var objectKeys = [], index, length, pair, pairKey, pairHasKey,
object = data;
for (index = 0, length = object.length; index < length; index += 1) {
pair = object[index];
pairHasKey = false;
if (_toString.call(pair) !== '[object Object]') return false;
for (pairKey in pair) {
if (_hasOwnProperty.call(pair, pairKey)) {
if (!pairHasKey) pairHasKey = true;
else return false;
}
}
if (!pairHasKey) return false;
if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey);
else return false;
}
return true;
}
function constructYamlOmap(data) {
return data !== null ? data : [];
}
module.exports = new Type('tag:yaml.org,2002:omap', {
kind: 'sequence',
resolve: resolveYamlOmap,
construct: constructYamlOmap
});
},{"../type":32}],44:[function(require,module,exports){
'use strict';
var Type = require('../type');
var _toString = Object.prototype.toString;
function resolveYamlPairs(data) {
if (data === null) return true;
var index, length, pair, keys, result,
object = data;
result = new Array(object.length);
for (index = 0, length = object.length; index < length; index += 1) {
pair = object[index];
if (_toString.call(pair) !== '[object Object]') return false;
keys = Object.keys(pair);
if (keys.length !== 1) return false;
result[index] = [ keys[0], pair[keys[0]] ];
}
return true;
}
function constructYamlPairs(data) {
if (data === null) return [];
var index, length, pair, keys, result,
object = data;
result = new Array(object.length);
for (index = 0, length = object.length; index < length; index += 1) {
pair = object[index];
keys = Object.keys(pair);
result[index] = [ keys[0], pair[keys[0]] ];
}
return result;
}
module.exports = new Type('tag:yaml.org,2002:pairs', {
kind: 'sequence',
resolve: resolveYamlPairs,
construct: constructYamlPairs
});
},{"../type":32}],45:[function(require,module,exports){
'use strict';
var Type = require('../type');
module.exports = new Type('tag:yaml.org,2002:seq', {
kind: 'sequence',
construct: function (data) { return data !== null ? data : []; }
});
},{"../type":32}],46:[function(require,module,exports){
'use strict';
var Type = require('../type');
var _hasOwnProperty = Object.prototype.hasOwnProperty;
function resolveYamlSet(data) {
if (data === null) return true;
var key, object = data;
for (key in object) {
if (_hasOwnProperty.call(object, key)) {
if (object[key] !== null) return false;
}
}
return true;
}
function constructYamlSet(data) {
return data !== null ? data : {};
}
module.exports = new Type('tag:yaml.org,2002:set', {
kind: 'mapping',
resolve: resolveYamlSet,
construct: constructYamlSet
});
},{"../type":32}],47:[function(require,module,exports){
'use strict';
var Type = require('../type');
module.exports = new Type('tag:yaml.org,2002:str', {
kind: 'scalar',
construct: function (data) { return data !== null ? data : ''; }
});
},{"../type":32}],48:[function(require,module,exports){
'use strict';
var Type = require('../type');
var YAML_DATE_REGEXP = new RegExp(
'^([0-9][0-9][0-9][0-9])' + // [1] year
'-([0-9][0-9])' + // [2] month
'-([0-9][0-9])$'); // [3] day
var YAML_TIMESTAMP_REGEXP = new RegExp(
'^([0-9][0-9][0-9][0-9])' + // [1] year
'-([0-9][0-9]?)' + // [2] month
'-([0-9][0-9]?)' + // [3] day
'(?:[Tt]|[ \\t]+)' + // ...
'([0-9][0-9]?)' + // [4] hour
':([0-9][0-9])' + // [5] minute
':([0-9][0-9])' + // [6] second
'(?:\\.([0-9]*))?' + // [7] fraction
'(?:[ \\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour
'(?::([0-9][0-9]))?))?$'); // [11] tz_minute
function resolveYamlTimestamp(data) {
if (data === null) return false;
if (YAML_DATE_REGEXP.exec(data) !== null) return true;
if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true;
return false;
}
function constructYamlTimestamp(data) {
var match, year, month, day, hour, minute, second, fraction = 0,
delta = null, tz_hour, tz_minute, date;
match = YAML_DATE_REGEXP.exec(data);
if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data);
if (match === null) throw new Error('Date resolve error');
// match: [1] year [2] month [3] day
year = +(match[1]);
month = +(match[2]) - 1; // JS month starts with 0
day = +(match[3]);
if (!match[4]) { // no hour
return new Date(Date.UTC(year, month, day));
}
// match: [4] hour [5] minute [6] second [7] fraction
hour = +(match[4]);
minute = +(match[5]);
second = +(match[6]);
if (match[7]) {
fraction = match[7].slice(0, 3);
while (fraction.length < 3) { // milli-seconds
fraction += '0';
}
fraction = +fraction;
}
// match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute
if (match[9]) {
tz_hour = +(match[10]);
tz_minute = +(match[11] || 0);
delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds
if (match[9] === '-') delta = -delta;
}
date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction));
if (delta) date.setTime(date.getTime() - delta);
return date;
}
function representYamlTimestamp(object /*, style*/) {
return object.toISOString();
}
module.exports = new Type('tag:yaml.org,2002:timestamp', {
kind: 'scalar',
resolve: resolveYamlTimestamp,
construct: constructYamlTimestamp,
instanceOf: Date,
represent: representYamlTimestamp
});
},{"../type":32}],49:[function(require,module,exports){
var baseIndexOf = require('../internal/baseIndexOf'),
binaryIndex = require('../internal/binaryIndex');
/* Native method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max;
/**
* Gets the index at which the first occurrence of `value` is found in `array`
* using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
* for equality comparisons. If `fromIndex` is negative, it's used as the offset
* from the end of `array`. If `array` is sorted providing `true` for `fromIndex`
* performs a faster binary search.
*
* @static
* @memberOf _
* @category Array
* @param {Array} array The array to search.
* @param {*} value The value to search for.
* @param {boolean|number} [fromIndex=0] The index to search from or `true`
* to perform a binary search on a sorted array.
* @returns {number} Returns the index of the matched value, else `-1`.
* @example
*
* _.indexOf([1, 2, 1, 2], 2);
* // => 1
*
* // using `fromIndex`
* _.indexOf([1, 2, 1, 2], 2, 2);
* // => 3
*
* // performing a binary search
* _.indexOf([1, 1, 2, 2], 2, true);
* // => 2
*/
function indexOf(array, value, fromIndex) {
var length = array ? array.length : 0;
if (!length) {
return -1;
}
if (typeof fromIndex == 'number') {
fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex;
} else if (fromIndex) {
var index = binaryIndex(array, value);
if (index < length &&
(value === value ? (value === array[index]) : (array[index] !== array[index]))) {
return index;
}
return -1;
}
return baseIndexOf(array, value, fromIndex || 0);
}
module.exports = indexOf;
},{"../internal/baseIndexOf":78,"../internal/binaryIndex":92}],50:[function(require,module,exports){
/**
* Gets the last element of `array`.
*
* @static
* @memberOf _
* @category Array
* @param {Array} array The array to query.
* @returns {*} Returns the last element of `array`.
* @example
*
* _.last([1, 2, 3]);
* // => 3
*/
function last(array) {
var length = array ? array.length : 0;
return length ? array[length - 1] : undefined;
}
module.exports = last;
},{}],51:[function(require,module,exports){
var LazyWrapper = require('../internal/LazyWrapper'),
LodashWrapper = require('../internal/LodashWrapper'),
baseLodash = require('../internal/baseLodash'),
isArray = require('../lang/isArray'),
isObjectLike = require('../internal/isObjectLike'),
wrapperClone = require('../internal/wrapperClone');
/** Used for native method references. */
var objectProto = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/**
* Creates a `lodash` object which wraps `value` to enable implicit chaining.
* Methods that operate on and return arrays, collections, and functions can
* be chained together. Methods that retrieve a single value or may return a
* primitive value will automatically end the chain returning the unwrapped
* value. Explicit chaining may be enabled using `_.chain`. The execution of
* chained methods is lazy, that is, execution is deferred until `_#value`
* is implicitly or explicitly called.
*
* Lazy evaluation allows several methods to support shortcut fusion. Shortcut
* fusion is an optimization strategy which merge iteratee calls; this can help
* to avoid the creation of intermediate data structures and greatly reduce the
* number of iteratee executions.
*
* Chaining is supported in custom builds as long as the `_#value` method is
* directly or indirectly included in the build.
*
* In addition to lodash methods, wrappers have `Array` and `String` methods.
*
* The wrapper `Array` methods are:
* `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`,
* `splice`, and `unshift`
*
* The wrapper `String` methods are:
* `replace` and `split`
*
* The wrapper methods that support shortcut fusion are:
* `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`,
* `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`,
* `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`,
* and `where`
*
* The chainable wrapper methods are:
* `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`,
* `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`,
* `countBy`, `create`, `curry`, `debounce`, `defaults`, `defaultsDeep`,
* `defer`, `delay`, `difference`, `drop`, `dropRight`, `dropRightWhile`,
* `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`,
* `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,
* `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,
* `invoke`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`,
* `matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`,
* `modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`,
* `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`,
* `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`,
* `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`,
* `sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`,
* `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`,
* `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`,
* `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWith`
*
* The wrapper methods that are **not** chainable by default are:
* `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`,
* `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`,
* `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`,
* `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`,
* `inRange`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
* `isEmpty`, `isEqual`, `isError`, `isFinite` `isFunction`, `isMatch`,
* `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`,
* `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`,
* `last`, `lastIndexOf`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`,
* `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`,
* `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`,
* `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`,
* `startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`,
* `unescape`, `uniqueId`, `value`, and `words`
*
* The wrapper method `sample` will return a wrapped value when `n` is provided,
* otherwise an unwrapped value is returned.
*
* @name _
* @constructor
* @category Chain
* @param {*} value The value to wrap in a `lodash` instance.
* @returns {Object} Returns the new `lodash` wrapper instance.
* @example
*
* var wrapped = _([1, 2, 3]);
*
* // returns an unwrapped value
* wrapped.reduce(function(total, n) {
* return total + n;
* });
* // => 6
*
* // returns a wrapped value
* var squares = wrapped.map(function(n) {
* return n * n;
* });
*
* _.isArray(squares);
* // => false
*
* _.isArray(squares.value());
* // => true
*/
function lodash(value) {
if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
if (value instanceof LodashWrapper) {
return value;
}
if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) {
return wrapperClone(value);
}
}
return new LodashWrapper(value);
}
// Ensure wrappers are instances of `baseLodash`.
lodash.prototype = baseLodash.prototype;
module.exports = lodash;
},{"../internal/LazyWrapper":60,"../internal/LodashWrapper":61,"../internal/baseLodash":82,"../internal/isObjectLike":126,"../internal/wrapperClone":137,"../lang/isArray":140}],52:[function(require,module,exports){
module.exports = require('./forEach');
},{"./forEach":54}],53:[function(require,module,exports){
var baseEach = require('../internal/baseEach'),
createFind = require('../internal/createFind');
/**
* Iterates over elements of `collection`, returning the first element
* `predicate` returns truthy for. The predicate is bound to `thisArg` and
* invoked with three arguments: (value, index|key, collection).
*
* If a property name is provided for `predicate` the created `_.property`
* style callback returns the property value of the given element.
*
* If a value is also provided for `thisArg` the created `_.matchesProperty`
* style callback returns `true` for elements that have a matching property
* value, else `false`.
*
* If an object is provided for `predicate` the created `_.matches` style
* callback returns `true` for elements that have the properties of the given
* object, else `false`.
*
* @static
* @memberOf _
* @alias detect
* @category Collection
* @param {Array|Object|string} collection The collection to search.
* @param {Function|Object|string} [predicate=_.identity] The function invoked
* per iteration.
* @param {*} [thisArg] The `this` binding of `predicate`.
* @returns {*} Returns the matched element, else `undefined`.
* @example
*
* var users = [
* { 'user': 'barney', 'age': 36, 'active': true },
* { 'user': 'fred', 'age': 40, 'active': false },
* { 'user': 'pebbles', 'age': 1, 'active': true }
* ];
*
* _.result(_.find(users, function(chr) {
* return chr.age < 40;
* }), 'user');
* // => 'barney'
*
* // using the `_.matches` callback shorthand
* _.result(_.find(users, { 'age': 1, 'active': true }), 'user');
* // => 'pebbles'
*
* // using the `_.matchesProperty` callback shorthand
* _.result(_.find(users, 'active', false), 'user');
* // => 'fred'
*
* // using the `_.property` callback shorthand
* _.result(_.find(users, 'active'), 'user');
* // => 'barney'
*/
var find = createFind(baseEach);
module.exports = find;
},{"../internal/baseEach":71,"../internal/createFind":102}],54:[function(require,module,exports){
var arrayEach = require('../internal/arrayEach'),
baseEach = require('../internal/baseEach'),
createForEach = require('../internal/createForEach');
/**
* Iterates over elements of `collection` invoking `iteratee` for each element.
* The `iteratee` is bound to `thisArg` and invoked with three arguments:
* (value, index|key, collection). Iteratee functions may exit iteration early
* by explicitly returning `false`.
*
* **Note:** As with other "Collections" methods, objects with a "length" property
* are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
* may be used for object iteration.
*
* @static
* @memberOf _
* @alias each
* @category Collection
* @param {Array|Object|string} collection The collection to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
* @param {*} [thisArg] The `this` binding of `iteratee`.
* @returns {Array|Object|string} Returns `collection`.
* @example
*
* _([1, 2]).forEach(function(n) {
* console.log(n);
* }).value();
* // => logs each value from left to right and returns the array
*
* _.forEach({ 'a': 1, 'b': 2 }, function(n, key) {
* console.log(n, key);
* });
* // => logs each value-key pair and returns the object (iteration order is not guaranteed)
*/
var forEach = createForEach(arrayEach, baseEach);
module.exports = forEach;
},{"../internal/arrayEach":63,"../internal/baseEach":71,"../internal/createForEach":103}],55:[function(require,module,exports){
var baseIndexOf = require('../internal/baseIndexOf'),
getLength = require('../internal/getLength'),
isArray = require('../lang/isArray'),
isIterateeCall = require('../internal/isIterateeCall'),
isLength = require('../internal/isLength'),
isString = require('../lang/isString'),
values = require('../object/values');
/* Native method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max;
/**
* Checks if `target` is in `collection` using
* [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
* for equality comparisons. If `fromIndex` is negative, it's used as the offset
* from the end of `collection`.
*
* @static
* @memberOf _
* @alias contains, include
* @category Collection
* @param {Array|Object|string} collection The collection to search.
* @param {*} target The value to search for.
* @param {number} [fromIndex=0] The index to search from.
* @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`.
* @returns {boolean} Returns `true` if a matching element is found, else `false`.
* @example
*
* _.includes([1, 2, 3], 1);
* // => true
*
* _.includes([1, 2, 3], 1, 2);
* // => false
*
* _.includes({ 'user': 'fred', 'age': 40 }, 'fred');
* // => true
*
* _.includes('pebbles', 'eb');
* // => true
*/
function includes(collection, target, fromIndex, guard) {
var length = collection ? getLength(collection) : 0;
if (!isLength(length)) {
collection = values(collection);
length = collection.length;
}
if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) {
fromIndex = 0;
} else {
fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0);
}
return (typeof collection == 'string' || !isArray(collection) && isString(collection))
? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1)
: (!!length && baseIndexOf(collection, target, fromIndex) > -1);
}
module.exports = includes;
},{"../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){
var arrayMap = require('../internal/arrayMap'),
baseCallback = require('../internal/baseCallback'),
baseMap = require('../internal/baseMap'),
isArray = require('../lang/isArray');
/**
* Creates an array of values by running each element in `collection` through
* `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three
* arguments: (value, index|key, collection).
*
* If a property name is provided for `iteratee` the created `_.property`
* style callback returns the property value of the given element.
*
* If a value is also provided for `thisArg` the created `_.matchesProperty`
* style callback returns `true` for elements that have a matching property
* value, else `false`.
*
* If an object is provided for `iteratee` the created `_.matches` style
* callback returns `true` for elements that have the properties of the given
* object, else `false`.
*
* Many lodash methods are guarded to work as iteratees for methods like
* `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
*
* The guarded methods are:
* `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`,
* `drop`, `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`,
* `parseInt`, `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`,
* `trimLeft`, `trimRight`, `trunc`, `random`, `range`, `sample`, `some`,
* `sum`, `uniq`, and `words`
*
* @static
* @memberOf _
* @alias collect
* @category Collection
* @param {Array|Object|string} collection The collection to iterate over.
* @param {Function|Object|string} [iteratee=_.identity] The function invoked
* per iteration.
* @param {*} [thisArg] The `this` binding of `iteratee`.
* @returns {Array} Returns the new mapped array.
* @example
*
* function timesThree(n) {
* return n * 3;
* }
*
* _.map([1, 2], timesThree);
* // => [3, 6]
*
* _.map({ 'a': 1, 'b': 2 }, timesThree);
* // => [3, 6] (iteration order is not guaranteed)
*
* var users = [
* { 'user': 'barney' },
* { 'user': 'fred' }
* ];
*
* // using the `_.property` callback shorthand
* _.map(users, 'user');
* // => ['barney', 'fred']
*/
function map(collection, iteratee, thisArg) {
var func = isArray(collection) ? arrayMap : baseMap;
iteratee = baseCallback(iteratee, thisArg, 3);
return func(collection, iteratee);
}
module.exports = map;
},{"../internal/arrayMap":64,"../internal/baseCallback":67,"../internal/baseMap":83,"../lang/isArray":140}],57:[function(require,module,exports){
var getNative = require('../internal/getNative');
/* Native method references for those with the same name as other `lodash` methods. */
var nativeNow = getNative(Date, 'now');
/**
* Gets the number of milliseconds that have elapsed since the Unix epoch
* (1 January 1970 00:00:00 UTC).
*
* @static
* @memberOf _
* @category Date
* @example
*
* _.defer(function(stamp) {
* console.log(_.now() - stamp);
* }, _.now());
* // => logs the number of milliseconds it took for the deferred function to be invoked
*/
var now = nativeNow || function() {
return new Date().getTime();
};
module.exports = now;
},{"../internal/getNative":114}],58:[function(require,module,exports){
var createWrapper = require('../internal/createWrapper'),
replaceHolders = require('../internal/replaceHolders'),
restParam = require('./restParam');
/** Used to compose bitmasks for wrapper metadata. */
var BIND_FLAG = 1,
PARTIAL_FLAG = 32;
/**
* Creates a function that invokes `func` with the `this` binding of `thisArg`
* and prepends any additional `_.bind` arguments to those provided to the
* bound function.
*
* The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
* may be used as a placeholder for partially applied arguments.
*
* **Note:** Unlike native `Function#bind` this method does not set the "length"
* property of bound functions.
*
* @static
* @memberOf _
* @category Function
* @param {Function} func The function to bind.
* @param {*} thisArg The `this` binding of `func`.
* @param {...*} [partials] The arguments to be partially applied.
* @returns {Function} Returns the new bound function.
* @example
*
* var greet = function(greeting, punctuation) {
* return greeting + ' ' + this.user + punctuation;
* };
*
* var object = { 'user': 'fred' };
*
* var bound = _.bind(greet, object, 'hi');
* bound('!');
* // => 'hi fred!'
*
* // using placeholders
* var bound = _.bind(greet, object, _, '!');
* bound('hi');
* // => 'hi fred!'
*/
var bind = restParam(function(func, thisArg, partials) {
var bitmask = BIND_FLAG;
if (partials.length) {
var holders = replaceHolders(partials, bind.placeholder);
bitmask |= PARTIAL_FLAG;
}
return createWrapper(func, bitmask, thisArg, partials, holders);
});
// Assign default placeholders.
bind.placeholder = {};
module.exports = bind;
},{"../internal/createWrapper":106,"../internal/replaceHolders":132,"./restParam":59}],59:[function(require,module,exports){
/** Used as the `TypeError` message for "Functions" methods. */
var FUNC_ERROR_TEXT = 'Expected a function';
/* Native method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max;
/**
* Creates a function that invokes `func` with the `this` binding of the
* created function and arguments from `start` and beyond provided as an array.
*
* **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/Web/JavaScript/Reference/Functions/rest_parameters).
*
* @static
* @memberOf _
* @category Function
* @param {Function} func The function to apply a rest parameter to.
* @param {number} [start=func.length-1] The start position of the rest parameter.
* @returns {Function} Returns the new function.
* @example
*
* var say = _.restParam(function(what, names) {
* return what + ' ' + _.initial(names).join(', ') +
* (_.size(names) > 1 ? ', & ' : '') + _.last(names);
* });
*
* say('hello', 'fred', 'barney', 'pebbles');
* // => 'hello fred, barney, & pebbles'
*/
function restParam(func, start) {
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0);
return function() {
var args = arguments,
index = -1,
length = nativeMax(args.length - start, 0),
rest = Array(length);
while (++index < length) {
rest[index] = args[start + index];
}
switch (start) {
case 0: return func.call(this, rest);
case 1: return func.call(this, args[0], rest);
case 2: return func.call(this, args[0], args[1], rest);
}
var otherArgs = Array(start + 1);
index = -1;
while (++index < start) {
otherArgs[index] = args[index];
}
otherArgs[start] = rest;
return func.apply(this, otherArgs);
};
}
module.exports = restParam;
},{}],60:[function(require,module,exports){
var baseCreate = require('./baseCreate'),
baseLodash = require('./baseLodash');
/** Used as references for `-Infinity` and `Infinity`. */
var POSITIVE_INFINITY = Number.POSITIVE_INFINITY;
/**
* Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
*
* @private
* @param {*} value The value to wrap.
*/
function LazyWrapper(value) {
this.__wrapped__ = value;
this.__actions__ = [];
this.__dir__ = 1;
this.__filtered__ = false;
this.__iteratees__ = [];
this.__takeCount__ = POSITIVE_INFINITY;
this.__views__ = [];
}
LazyWrapper.prototype = baseCreate(baseLodash.prototype);
LazyWrapper.prototype.constructor = LazyWrapper;
module.exports = LazyWrapper;
},{"./baseCreate":70,"./baseLodash":82}],61:[function(require,module,exports){
var baseCreate = require('./baseCreate'),
baseLodash = require('./baseLodash');
/**
* The base constructor for creating `lodash` wrapper objects.
*
* @private
* @param {*} value The value to wrap.
* @param {boolean} [chainAll] Enable chaining for all wrapper methods.
* @param {Array} [actions=[]] Actions to peform to resolve the unwrapped value.
*/
function LodashWrapper(value, chainAll, actions) {
this.__wrapped__ = value;
this.__actions__ = actions || [];
this.__chain__ = !!chainAll;
}
LodashWrapper.prototype = baseCreate(baseLodash.prototype);
LodashWrapper.prototype.constructor = LodashWrapper;
module.exports = LodashWrapper;
},{"./baseCreate":70,"./baseLodash":82}],62:[function(require,module,exports){
/**
* Copies the values of `source` to `array`.
*
* @private
* @param {Array} source The array to copy values from.
* @param {Array} [array=[]] The array to copy values to.
* @returns {Array} Returns `array`.
*/
function arrayCopy(source, array) {
var index = -1,
length = source.length;
array || (array = Array(length));
while (++index < length) {
array[index] = source[index];
}
return array;
}
module.exports = arrayCopy;
},{}],63:[function(require,module,exports){
/**
* A specialized version of `_.forEach` for arrays without support for callback
* shorthands and `this` binding.
*
* @private
* @param {Array} array The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array} Returns `array`.
*/
function arrayEach(array, iteratee) {
var index = -1,
length = array.length;
while (++index < length) {
if (iteratee(array[index], index, array) === false) {
break;
}
}
return array;
}
module.exports = arrayEach;
},{}],64:[function(require,module,exports){
/**
* A specialized version of `_.map` for arrays without support for callback
* shorthands and `this` binding.
*
* @private
* @param {Array} array The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array} Returns the new mapped array.
*/
function arrayMap(array, iteratee) {
var index = -1,
length = array.length,
result = Array(length);
while (++index < length) {
result[index] = iteratee(array[index], index, array);
}
return result;
}
module.exports = arrayMap;
},{}],65:[function(require,module,exports){
/**
* A specialized version of `_.some` for arrays without support for callback
* shorthands and `this` binding.
*
* @private
* @param {Array} array The array to iterate over.
* @param {Function} predicate The function invoked per iteration.
* @returns {boolean} Returns `true` if any element passes the predicate check,
* else `false`.
*/
function arraySome(array, predicate) {
var index = -1,
length = array.length;
while (++index < length) {
if (predicate(array[index], index, array)) {
return true;
}
}
return false;
}
module.exports = arraySome;
},{}],66:[function(require,module,exports){
var baseCopy = require('./baseCopy'),
keys = require('../object/keys');
/**
* The base implementation of `_.assign` without support for argument juggling,
* multiple sources, and `customizer` functions.
*
* @private
* @param {Object} object The destination object.
* @param {Object} source The source object.
* @returns {Object} Returns `object`.
*/
function baseAssign(object, source) {
return source == null
? object
: baseCopy(source, keys(source), object);
}
module.exports = baseAssign;
},{"../object/keys":149,"./baseCopy":69}],67:[function(require,module,exports){
var baseMatches = require('./baseMatches'),
baseMatchesProperty = require('./baseMatchesProperty'),
bindCallback = require('./bindCallback'),
identity = require('../utility/identity'),
property = require('../utility/property');
/**
* The base implementation of `_.callback` which supports specifying the
* number of arguments to provide to `func`.
*
* @private
* @param {*} [func=_.identity] The value to convert to a callback.
* @param {*} [thisArg] The `this` binding of `func`.
* @param {number} [argCount] The number of arguments to provide to `func`.
* @returns {Function} Returns the callback.
*/
function baseCallback(func, thisArg, argCount) {
var type = typeof func;
if (type == 'function') {
return thisArg === undefined
? func
: bindCallback(func, thisArg, argCount);
}
if (func == null) {
return identity;
}
if (type == 'object') {
return baseMatches(func);
}
return thisArg === undefined
? property(func)
: baseMatchesProperty(func, thisArg);
}
module.exports = baseCallback;
},{"../utility/identity":154,"../utility/property":156,"./baseMatches":84,"./baseMatchesProperty":85,"./bindCallback":94}],68:[function(require,module,exports){
var arrayCopy = require('./arrayCopy'),
arrayEach = require('./arrayEach'),
baseAssign = require('./baseAssign'),
baseForOwn = require('./baseForOwn'),
initCloneArray = require('./initCloneArray'),
initCloneByTag = require('./initCloneByTag'),
initCloneObject = require('./initCloneObject'),
isArray = require('../lang/isArray'),
isHostObject = require('./isHostObject'),
isObject = require('../lang/isObject');
/** `Object#toString` result references. */
var argsTag = '[object Arguments]',
arrayTag = '[object Array]',
boolTag = '[object Boolean]',
dateTag = '[object Date]',
errorTag = '[object Error]',
funcTag = '[object Function]',
mapTag = '[object Map]',
numberTag = '[object Number]',
objectTag = '[object Object]',
regexpTag = '[object RegExp]',
setTag = '[object Set]',
stringTag = '[object String]',
weakMapTag = '[object WeakMap]';
var arrayBufferTag = '[object ArrayBuffer]',
float32Tag = '[object Float32Array]',
float64Tag = '[object Float64Array]',
int8Tag = '[object Int8Array]',
int16Tag = '[object Int16Array]',
int32Tag = '[object Int32Array]',
uint8Tag = '[object Uint8Array]',
uint8ClampedTag = '[object Uint8ClampedArray]',
uint16Tag = '[object Uint16Array]',
uint32Tag = '[object Uint32Array]';
/** Used to identify `toStringTag` values supported by `_.clone`. */
var cloneableTags = {};
cloneableTags[argsTag] = cloneableTags[arrayTag] =
cloneableTags[arrayBufferTag] = cloneableTags[boolTag] =
cloneableTags[dateTag] = cloneableTags[float32Tag] =
cloneableTags[float64Tag] = cloneableTags[int8Tag] =
cloneableTags[int16Tag] = cloneableTags[int32Tag] =
cloneableTags[numberTag] = cloneableTags[objectTag] =
cloneableTags[regexpTag] = cloneableTags[stringTag] =
cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
cloneableTags[errorTag] = cloneableTags[funcTag] =
cloneableTags[mapTag] = cloneableTags[setTag] =
cloneableTags[weakMapTag] = false;
/** Used for native method references. */
var objectProto = Object.prototype;
/**
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
var objToString = objectProto.toString;
/**
* The base implementation of `_.clone` without support for argument juggling
* and `this` binding `customizer` functions.
*
* @private
* @param {*} value The value to clone.
* @param {boolean} [isDeep] Specify a deep clone.
* @param {Function} [customizer] The function to customize cloning values.
* @param {string} [key] The key of `value`.
* @param {Object} [object] The object `value` belongs to.
* @param {Array} [stackA=[]] Tracks traversed source objects.
* @param {Array} [stackB=[]] Associates clones with source counterparts.
* @returns {*} Returns the cloned value.
*/
function baseClone(value, isDeep, customizer, key, object, stackA, stackB) {
var result;
if (customizer) {
result = object ? customizer(value, key, object) : customizer(value);
}
if (result !== undefined) {
return result;
}
if (!isObject(value)) {
return value;
}
var isArr = isArray(value);
if (isArr) {
result = initCloneArray(value);
if (!isDeep) {
return arrayCopy(value, result);
}
} else {
var tag = objToString.call(value),
isFunc = tag == funcTag;
if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
if (isHostObject(value)) {
return object ? value : {};
}
result = initCloneObject(isFunc ? {} : value);
if (!isDeep) {
return baseAssign(result, value);
}
} else {
return cloneableTags[tag]
? initCloneByTag(value, tag, isDeep)
: (object ? value : {});
}
}
// Check for circular references and return its corresponding clone.
stackA || (stackA = []);
stackB || (stackB = []);
var length = stackA.length;
while (length--) {
if (stackA[length] == value) {
return stackB[length];
}
}
// Add the source value to the stack of traversed objects and associate it with its clone.
stackA.push(value);
stackB.push(result);
// Recursively populate clone (susceptible to call stack limits).
(isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {
result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB);
});
return result;
}
module.exports = baseClone;
},{"../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){
/**
* Copies properties of `source` to `object`.
*
* @private
* @param {Object} source The object to copy properties from.
* @param {Array} props The property names to copy.
* @param {Object} [object={}] The object to copy properties to.
* @returns {Object} Returns `object`.
*/
function baseCopy(source, props, object) {
object || (object = {});
var index = -1,
length = props.length;
while (++index < length) {
var key = props[index];
object[key] = source[key];
}
return object;
}
module.exports = baseCopy;
},{}],70:[function(require,module,exports){
var isObject = require('../lang/isObject');
/**
* The base implementation of `_.create` without support for assigning
* properties to the created object.
*
* @private
* @param {Object} prototype The object to inherit from.
* @returns {Object} Returns the new object.
*/
var baseCreate = (function() {
function object() {}
return function(prototype) {
if (isObject(prototype)) {
object.prototype = prototype;
var result = new object;
object.prototype = undefined;
}
return result || {};
};
}());
module.exports = baseCreate;
},{"../lang/isObject":144}],71:[function(require,module,exports){
var baseForOwn = require('./baseForOwn'),
createBaseEach = require('./createBaseEach');
/**
* The base implementation of `_.forEach` without support for callback
* shorthands and `this` binding.
*
* @private
* @param {Array|Object|string} collection The collection to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array|Object|string} Returns `collection`.
*/
var baseEach = createBaseEach(baseForOwn);
module.exports = baseEach;
},{"./baseForOwn":76,"./createBaseEach":98}],72:[function(require,module,exports){
/**
* The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.findLastKey`,
* without support for callback shorthands and `this` binding, which iterates
* over `collection` using the provided `eachFunc`.
*
* @private
* @param {Array|Object|string} collection The collection to search.
* @param {Function} predicate The function invoked per iteration.
* @param {Function} eachFunc The function to iterate over `collection`.
* @param {boolean} [retKey] Specify returning the key of the found element
* instead of the element itself.
* @returns {*} Returns the found element or its key, else `undefined`.
*/
function baseFind(collection, predicate, eachFunc, retKey) {
var result;
eachFunc(collection, function(value, key, collection) {
if (predicate(value, key, collection)) {
result = retKey ? key : value;
return false;
}
});
return result;
}
module.exports = baseFind;
},{}],73:[function(require,module,exports){
/**
* The base implementation of `_.findIndex` and `_.findLastIndex` without
* support for callback shorthands and `this` binding.
*
* @private
* @param {Array} array The array to search.
* @param {Function} predicate The function invoked per iteration.
* @param {boolean} [fromRight] Specify iterating from right to left.
* @returns {number} Returns the index of the matched value, else `-1`.
*/
function baseFindIndex(array, predicate, fromRight) {
var length = array.length,
index = fromRight ? length : -1;
while ((fromRight ? index-- : ++index < length)) {
if (predicate(array[index], index, array)) {
return index;
}
}
return -1;
}
module.exports = baseFindIndex;
},{}],74:[function(require,module,exports){
var createBaseFor = require('./createBaseFor');
/**
* The base implementation of `baseForIn` and `baseForOwn` which iterates
* over `object` properties returned by `keysFunc` invoking `iteratee` for
* each property. Iteratee functions may exit iteration early by explicitly
* returning `false`.
*
* @private
* @param {Object} object The object to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @param {Function} keysFunc The function to get the keys of `object`.
* @returns {Object} Returns `object`.
*/
var baseFor = createBaseFor();
module.exports = baseFor;
},{"./createBaseFor":99}],75:[function(require,module,exports){
var baseFor = require('./baseFor'),
keysIn = require('../object/keysIn');
/**
* The base implementation of `_.forIn` without support for callback
* shorthands and `this` binding.
*
* @private
* @param {Object} object The object to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Object} Returns `object`.
*/
function baseForIn(object, iteratee) {
return baseFor(object, iteratee, keysIn);
}
module.exports = baseForIn;
},{"../object/keysIn":150,"./baseFor":74}],76:[function(require,module,exports){
var baseFor = require('./baseFor'),
keys = require('../object/keys');
/**
* The base implementation of `_.forOwn` without support for callback
* shorthands and `this` binding.
*
* @private
* @param {Object} object The object to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Object} Returns `object`.
*/
function baseForOwn(object, iteratee) {
return baseFor(object, iteratee, keys);
}
module.exports = baseForOwn;
},{"../object/keys":149,"./baseFor":74}],77:[function(require,module,exports){
var toObject = require('./toObject');
/**
* The base implementation of `get` without support for string paths
* and default values.
*
* @private
* @param {Object} object The object to query.
* @param {Array} path The path of the property to get.
* @param {string} [pathKey] The key representation of path.
* @returns {*} Returns the resolved value.
*/
function baseGet(object, path, pathKey) {
if (object == null) {
return;
}
object = toObject(object);
if (pathKey !== undefined && pathKey in object) {
path = [pathKey];
}
var index = 0,
length = path.length;
while (object != null && index < length) {
object = toObject(object)[path[index++]];
}
return (index && index == length) ? object : undefined;
}
module.exports = baseGet;
},{"./toObject":135}],78:[function(require,module,exports){
var indexOfNaN = require('./indexOfNaN');
/**
* The base implementation of `_.indexOf` without support for binary searches.
*
* @private
* @param {Array} array The array to search.
* @param {*} value The value to search for.
* @param {number} fromIndex The index to search from.
* @returns {number} Returns the index of the matched value, else `-1`.
*/
function baseIndexOf(array, value, fromIndex) {
if (value !== value) {
return indexOfNaN(array, fromIndex);
}
var index = fromIndex - 1,
length = array.length;
while (++index < length) {
if (array[index] === value) {
return index;
}
}
return -1;
}
module.exports = baseIndexOf;
},{"./indexOfNaN":115}],79:[function(require,module,exports){
var baseIsEqualDeep = require('./baseIsEqualDeep'),
isObject = require('../lang/isObject'),
isObjectLike = require('./isObjectLike');
/**
* The base implementation of `_.isEqual` without support for `this` binding
* `customizer` functions.
*
* @private
* @param {*} value The value to compare.
* @param {*} other The other value to compare.
* @param {Function} [customizer] The function to customize comparing values.
* @param {boolean} [isLoose] Specify performing partial comparisons.
* @param {Array} [stackA] Tracks traversed `value` objects.
* @param {Array} [stackB] Tracks traversed `other` objects.
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
*/
function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) {
if (value === other) {
return true;
}
if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
return value !== value && other !== other;
}
return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB);
}
module.exports = baseIsEqual;
},{"../lang/isObject":144,"./baseIsEqualDeep":80,"./isObjectLike":126}],80:[function(require,module,exports){
var equalArrays = require('./equalArrays'),
equalByTag = require('./equalByTag'),
equalObjects = require('./equalObjects'),
isArray = require('../lang/isArray'),
isHostObject = require('./isHostObject'),
isTypedArray = require('../lang/isTypedArray');
/** `Object#toString` result references. */
var argsTag = '[object Arguments]',
arrayTag = '[object Array]',
objectTag = '[object Object]';
/** Used for native method references. */
var objectProto = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/**
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
var objToString = objectProto.toString;
/**
* A specialized version of `baseIsEqual` for arrays and objects which performs
* deep comparisons and tracks traversed objects enabling objects with circular
* references to be compared.
*
* @private
* @param {Object} object The object to compare.
* @param {Object} other The other object to compare.
* @param {Function} equalFunc The function to determine equivalents of values.
* @param {Function} [customizer] The function to customize comparing objects.
* @param {boolean} [isLoose] Specify performing partial comparisons.
* @param {Array} [stackA=[]] Tracks traversed `value` objects.
* @param {Array} [stackB=[]] Tracks traversed `other` objects.
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
*/
function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
var objIsArr = isArray(object),
othIsArr = isArray(other),
objTag = arrayTag,
othTag = arrayTag;
if (!objIsArr) {
objTag = objToString.call(object);
if (objTag == argsTag) {
objTag = objectTag;
} else if (objTag != objectTag) {
objIsArr = isTypedArray(object);
}
}
if (!othIsArr) {
othTag = objToString.call(other);
if (othTag == argsTag) {
othTag = objectTag;
} else if (othTag != objectTag) {
othIsArr = isTypedArray(other);
}
}
var objIsObj = objTag == objectTag && !isHostObject(object),
othIsObj = othTag == objectTag && !isHostObject(other),
isSameTag = objTag == othTag;
if (isSameTag && !(objIsArr || objIsObj)) {
return equalByTag(object, other, objTag);
}
if (!isLoose) {
var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
if (objIsWrapped || othIsWrapped) {
return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB);
}
}
if (!isSameTag) {
return false;
}
// Assume cyclic values are equal.
// For more information on detecting circular references see https://es5.github.io/#JO.
stackA || (stackA = []);
stackB || (stackB = []);
var length = stackA.length;
while (length--) {
if (stackA[length] == object) {
return stackB[length] == other;
}
}
// Add `object` and `other` to the stack of traversed objects.
stackA.push(object);
stackB.push(other);
var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB);
stackA.pop();
stackB.pop();
return result;
}
module.exports = baseIsEqualDeep;
},{"../lang/isArray":140,"../lang/isTypedArray":147,"./equalArrays":107,"./equalByTag":108,"./equalObjects":109,"./isHostObject":120}],81:[function(require,module,exports){
var baseIsEqual = require('./baseIsEqual'),
toObject = require('./toObject');
/**
* The base implementation of `_.isMatch` without support for callback
* shorthands and `this` binding.
*
* @private
* @param {Object} object The object to inspect.
* @param {Array} matchData The propery names, values, and compare flags to match.
* @param {Function} [customizer] The function to customize comparing objects.
* @returns {boolean} Returns `true` if `object` is a match, else `false`.
*/
function baseIsMatch(object, matchData, customizer) {
var index = matchData.length,
length = index,
noCustomizer = !customizer;
if (object == null) {
return !length;
}
object = toObject(object);
while (index--) {
var data = matchData[index];
if ((noCustomizer && data[2])
? data[1] !== object[data[0]]
: !(data[0] in object)
) {
return false;
}
}
while (++index < length) {
data = matchData[index];
var key = data[0],
objValue = object[key],
srcValue = data[1];
if (noCustomizer && data[2]) {
if (objValue === undefined && !(key in object)) {
return false;
}
} else {
var result = customizer ? customizer(objValue, srcValue, key) : undefined;
if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) {
return false;
}
}
}
return true;
}
module.exports = baseIsMatch;
},{"./baseIsEqual":79,"./toObject":135}],82:[function(require,module,exports){
/**
* The function whose prototype all chaining wrappers inherit from.
*
* @private
*/
function baseLodash() {
// No operation performed.
}
module.exports = baseLodash;
},{}],83:[function(require,module,exports){
var baseEach = require('./baseEach'),
isArrayLike = require('./isArrayLike');
/**
* The base implementation of `_.map` without support for callback shorthands
* and `this` binding.
*
* @private
* @param {Array|Object|string} collection The collection to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array} Returns the new mapped array.
*/
function baseMap(collection, iteratee) {
var index = -1,
result = isArrayLike(collection) ? Array(collection.length) : [];
baseEach(collection, function(value, key, collection) {
result[++index] = iteratee(value, key, collection);
});
return result;
}
module.exports = baseMap;
},{"./baseEach":71,"./isArrayLike":119}],84:[function(require,module,exports){
var baseIsMatch = require('./baseIsMatch'),
getMatchData = require('./getMatchData'),
toObject = require('./toObject');
/**
* The base implementation of `_.matches` which does not clone `source`.
*
* @private
* @param {Object} source The object of property values to match.
* @returns {Function} Returns the new function.
*/
function baseMatches(source) {
var matchData = getMatchData(source);
if (matchData.length == 1 && matchData[0][2]) {
var key = matchData[0][0],
value = matchData[0][1];
return function(object) {
if (object == null) {
return false;
}
object = toObject(object);
return object[key] === value && (value !== undefined || (key in object));
};
}
return function(object) {
return baseIsMatch(object, matchData);
};
}
module.exports = baseMatches;
},{"./baseIsMatch":81,"./getMatchData":113,"./toObject":135}],85:[function(require,module,exports){
var baseGet = require('./baseGet'),
baseIsEqual = require('./baseIsEqual'),
baseSlice = require('./baseSlice'),
isArray = require('../lang/isArray'),
isKey = require('./isKey'),
isStrictComparable = require('./isStrictComparable'),
last = require('../array/last'),
toObject = require('./toObject'),
toPath = require('./toPath');
/**
* The base implementation of `_.matchesProperty` which does not clone `srcValue`.
*
* @private
* @param {string} path The path of the property to get.
* @param {*} srcValue The value to compare.
* @returns {Function} Returns the new function.
*/
function baseMatchesProperty(path, srcValue) {
var isArr = isArray(path),
isCommon = isKey(path) && isStrictComparable(srcValue),
pathKey = (path + '');
path = toPath(path);
return function(object) {
if (object == null) {
return false;
}
var key = pathKey;
object = toObject(object);
if ((isArr || !isCommon) && !(key in object)) {
object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
if (object == null) {
return false;
}
key = last(path);
object = toObject(object);
}
return object[key] === srcValue
? (srcValue !== undefined || (key in object))
: baseIsEqual(srcValue, object[key], undefined, true);
};
}
module.exports = baseMatchesProperty;
},{"../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){
var toObject = require('./toObject');
/**
* The base implementation of `_.property` without support for deep paths.
*
* @private
* @param {string} key The key of the property to get.
* @returns {Function} Returns the new function.
*/
function baseProperty(key) {
return function(object) {
return object == null ? undefined : toObject(object)[key];
};
}
module.exports = baseProperty;
},{"./toObject":135}],87:[function(require,module,exports){
var baseGet = require('./baseGet'),
toPath = require('./toPath');
/**
* A specialized version of `baseProperty` which supports deep paths.
*
* @private
* @param {Array|string} path The path of the property to get.
* @returns {Function} Returns the new function.
*/
function basePropertyDeep(path) {
var pathKey = (path + '');
path = toPath(path);
return function(object) {
return baseGet(object, path, pathKey);
};
}
module.exports = basePropertyDeep;
},{"./baseGet":77,"./toPath":136}],88:[function(require,module,exports){
var identity = require('../utility/identity'),
metaMap = require('./metaMap');
/**
* The base implementation of `setData` without support for hot loop detection.
*
* @private
* @param {Function} func The function to associate metadata with.
* @param {*} data The metadata.
* @returns {Function} Returns `func`.
*/
var baseSetData = !metaMap ? identity : function(func, data) {
metaMap.set(func, data);
return func;
};
module.exports = baseSetData;
},{"../utility/identity":154,"./metaMap":129}],89:[function(require,module,exports){
/**
* The base implementation of `_.slice` without an iteratee call guard.
*
* @private
* @param {Array} array The array to slice.
* @param {number} [start=0] The start position.
* @param {number} [end=array.length] The end position.
* @returns {Array} Returns the slice of `array`.
*/
function baseSlice(array, start, end) {
var index = -1,
length = array.length;
start = start == null ? 0 : (+start || 0);
if (start < 0) {
start = -start > length ? 0 : (length + start);
}
end = (end === undefined || end > length) ? length : (+end || 0);
if (end < 0) {
end += length;
}
length = start > end ? 0 : ((end - start) >>> 0);
start >>>= 0;
var result = Array(length);
while (++index < length) {
result[index] = array[index + start];
}
return result;
}
module.exports = baseSlice;
},{}],90:[function(require,module,exports){
/**
* Converts `value` to a string if it's not one. An empty string is returned
* for `null` or `undefined` values.
*
* @private
* @param {*} value The value to process.
* @returns {string} Returns the string.
*/
function baseToString(value) {
return value == null ? '' : (value + '');
}
module.exports = baseToString;
},{}],91:[function(require,module,exports){
/**
* The base implementation of `_.values` and `_.valuesIn` which creates an
* array of `object` property values corresponding to the property names
* of `props`.
*
* @private
* @param {Object} object The object to query.
* @param {Array} props The property names to get values for.
* @returns {Object} Returns the array of property values.
*/
function baseValues(object, props) {
var index = -1,
length = props.length,
result = Array(length);
while (++index < length) {
result[index] = object[props[index]];
}
return result;
}
module.exports = baseValues;
},{}],92:[function(require,module,exports){
var binaryIndexBy = require('./binaryIndexBy'),
identity = require('../utility/identity');
/** Used as references for the maximum length and index of an array. */
var MAX_ARRAY_LENGTH = 4294967295,
HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
/**
* Performs a binary search of `array` to determine the index at which `value`
* should be inserted into `array` in order to maintain its sort order.
*
* @private
* @param {Array} array The sorted array to inspect.
* @param {*} value The value to evaluate.
* @param {boolean} [retHighest] Specify returning the highest qualified index.
* @returns {number} Returns the index at which `value` should be inserted
* into `array`.
*/
function binaryIndex(array, value, retHighest) {
var low = 0,
high = array ? array.length : low;
if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
while (low < high) {
var mid = (low + high) >>> 1,
computed = array[mid];
if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) {
low = mid + 1;
} else {
high = mid;
}
}
return high;
}
return binaryIndexBy(array, value, identity, retHighest);
}
module.exports = binaryIndex;
},{"../utility/identity":154,"./binaryIndexBy":93}],93:[function(require,module,exports){
/* Native method references for those with the same name as other `lodash` methods. */
var nativeFloor = Math.floor,
nativeMin = Math.min;
/** Used as references for the maximum length and index of an array. */
var MAX_ARRAY_LENGTH = 4294967295,
MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1;
/**
* This function is like `binaryIndex` except that it invokes `iteratee` for
* `value` and each element of `array` to compute their sort ranking. The
* iteratee is invoked with one argument; (value).
*
* @private
* @param {Array} array The sorted array to inspect.
* @param {*} value The value to evaluate.
* @param {Function} iteratee The function invoked per iteration.
* @param {boolean} [retHighest] Specify returning the highest qualified index.
* @returns {number} Returns the index at which `value` should be inserted
* into `array`.
*/
function binaryIndexBy(array, value, iteratee, retHighest) {
value = iteratee(value);
var low = 0,
high = array ? array.length : 0,
valIsNaN = value !== value,
valIsNull = value === null,
valIsUndef = value === undefined;
while (low < high) {
var mid = nativeFloor((low + high) / 2),
computed = iteratee(array[mid]),
isDef = computed !== undefined,
isReflexive = computed === computed;
if (valIsNaN) {
var setLow = isReflexive || retHighest;
} else if (valIsNull) {
setLow = isReflexive && isDef && (retHighest || computed != null);
} else if (valIsUndef) {
setLow = isReflexive && (retHighest || isDef);
} else if (computed == null) {
setLow = false;
} else {
setLow = retHighest ? (computed <= value) : (computed < value);
}
if (setLow) {
low = mid + 1;
} else {
high = mid;
}
}
return nativeMin(high, MAX_ARRAY_INDEX);
}
module.exports = binaryIndexBy;
},{}],94:[function(require,module,exports){
var identity = require('../utility/identity');
/**
* A specialized version of `baseCallback` which only supports `this` binding
* and specifying the number of arguments to provide to `func`.
*
* @private
* @param {Function} func The function to bind.
* @param {*} thisArg The `this` binding of `func`.
* @param {number} [argCount] The number of arguments to provide to `func`.
* @returns {Function} Returns the callback.
*/
function bindCallback(func, thisArg, argCount) {
if (typeof func != 'function') {
return identity;
}
if (thisArg === undefined) {
return func;
}
switch (argCount) {
case 1: return function(value) {
return func.call(thisArg, value);
};
case 3: return function(value, index, collection) {
return func.call(thisArg, value, index, collection);
};
case 4: return function(accumulator, value, index, collection) {
return func.call(thisArg, accumulator, value, index, collection);
};
case 5: return function(value, other, key, object, source) {
return func.call(thisArg, value, other, key, object, source);
};
}
return function() {
return func.apply(thisArg, arguments);
};
}
module.exports = bindCallback;
},{"../utility/identity":154}],95:[function(require,module,exports){
(function (global){
/** Native method references. */
var ArrayBuffer = global.ArrayBuffer,
Uint8Array = global.Uint8Array;
/**
* Creates a clone of the given array buffer.
*
* @private
* @param {ArrayBuffer} buffer The array buffer to clone.
* @returns {ArrayBuffer} Returns the cloned array buffer.
*/
function bufferClone(buffer) {
var result = new ArrayBuffer(buffer.byteLength),
view = new Uint8Array(result);
view.set(new Uint8Array(buffer));
return result;
}
module.exports = bufferClone;
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],96:[function(require,module,exports){
/* Native method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max;
/**
* Creates an array that is the composition of partially applied arguments,
* placeholders, and provided arguments into a single array of arguments.
*
* @private
* @param {Array|Object} args The provided arguments.
* @param {Array} partials The arguments to prepend to those provided.
* @param {Array} holders The `partials` placeholder indexes.
* @returns {Array} Returns the new array of composed arguments.
*/
function composeArgs(args, partials, holders) {
var holdersLength = holders.length,
argsIndex = -1,
argsLength = nativeMax(args.length - holdersLength, 0),
leftIndex = -1,
leftLength = partials.length,
result = Array(leftLength + argsLength);
while (++leftIndex < leftLength) {
result[leftIndex] = partials[leftIndex];
}
while (++argsIndex < holdersLength) {
result[holders[argsIndex]] = args[argsIndex];
}
while (argsLength--) {
result[leftIndex++] = args[argsIndex++];
}
return result;
}
module.exports = composeArgs;
},{}],97:[function(require,module,exports){
/* Native method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max;
/**
* This function is like `composeArgs` except that the arguments composition
* is tailored for `_.partialRight`.
*
* @private
* @param {Array|Object} args The provided arguments.
* @param {Array} partials The arguments to append to those provided.
* @param {Array} holders The `partials` placeholder indexes.
* @returns {Array} Returns the new array of composed arguments.
*/
function composeArgsRight(args, partials, holders) {
var holdersIndex = -1,
holdersLength = holders.length,
argsIndex = -1,
argsLength = nativeMax(args.length - holdersLength, 0),
rightIndex = -1,
rightLength = partials.length,
result = Array(argsLength + rightLength);
while (++argsIndex < argsLength) {
result[argsIndex] = args[argsIndex];
}
var offset = argsIndex;
while (++rightIndex < rightLength) {
result[offset + rightIndex] = partials[rightIndex];
}
while (++holdersIndex < holdersLength) {
result[offset + holders[holdersIndex]] = args[argsIndex++];
}
return result;
}
module.exports = composeArgsRight;
},{}],98:[function(require,module,exports){
var getLength = require('./getLength'),
isLength = require('./isLength'),
toObject = require('./toObject');
/**
* Creates a `baseEach` or `baseEachRight` function.
*
* @private
* @param {Function} eachFunc The function to iterate over a collection.
* @param {boolean} [fromRight] Specify iterating from right to left.
* @returns {Function} Returns the new base function.
*/
function createBaseEach(eachFunc, fromRight) {
return function(collection, iteratee) {
var length = collection ? getLength(collection) : 0;
if (!isLength(length)) {
return eachFunc(collection, iteratee);
}
var index = fromRight ? length : -1,
iterable = toObject(collection);
while ((fromRight ? index-- : ++index < length)) {
if (iteratee(iterable[index], index, iterable) === false) {
break;
}
}
return collection;
};
}
module.exports = createBaseEach;
},{"./getLength":112,"./isLength":125,"./toObject":135}],99:[function(require,module,exports){
var toObject = require('./toObject');
/**
* Creates a base function for `_.forIn` or `_.forInRight`.
*
* @private
* @param {boolean} [fromRight] Specify iterating from right to left.
* @returns {Function} Returns the new base function.
*/
function createBaseFor(fromRight) {
return function(object, iteratee, keysFunc) {
var iterable = toObject(object),
props = keysFunc(object),
length = props.length,
index = fromRight ? length : -1;
while ((fromRight ? index-- : ++index < length)) {
var key = props[index];
if (iteratee(iterable[key], key, iterable) === false) {
break;
}
}
return object;
};
}
module.exports = createBaseFor;
},{"./toObject":135}],100:[function(require,module,exports){
(function (global){
var createCtorWrapper = require('./createCtorWrapper');
/**
* Creates a function that wraps `func` and invokes it with the `this`
* binding of `thisArg`.
*
* @private
* @param {Function} func The function to bind.
* @param {*} [thisArg] The `this` binding of `func`.
* @returns {Function} Returns the new bound function.
*/
function createBindWrapper(func, thisArg) {
var Ctor = createCtorWrapper(func);
function wrapper() {
var fn = (this && this !== global && this instanceof wrapper) ? Ctor : func;
return fn.apply(thisArg, arguments);
}
return wrapper;
}
module.exports = createBindWrapper;
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./createCtorWrapper":101}],101:[function(require,module,exports){
var baseCreate = require('./baseCreate'),
isObject = require('../lang/isObject');
/**
* Creates a function that produces an instance of `Ctor` regardless of
* whether it was invoked as part of a `new` expression or by `call` or `apply`.
*
* @private
* @param {Function} Ctor The constructor to wrap.
* @returns {Function} Returns the new wrapped function.
*/
function createCtorWrapper(Ctor) {
return function() {
// Use a `switch` statement to work with class constructors.
// See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
// for more details.
var args = arguments;
switch (args.length) {
case 0: return new Ctor;
case 1: return new Ctor(args[0]);
case 2: return new Ctor(args[0], args[1]);
case 3: return new Ctor(args[0], args[1], args[2]);
case 4: return new Ctor(args[0], args[1], args[2], args[3]);
case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
}
var thisBinding = baseCreate(Ctor.prototype),
result = Ctor.apply(thisBinding, args);
// Mimic the constructor's `return` behavior.
// See https://es5.github.io/#x13.2.2 for more details.
return isObject(result) ? result : thisBinding;
};
}
module.exports = createCtorWrapper;
},{"../lang/isObject":144,"./baseCreate":70}],102:[function(require,module,exports){
var baseCallback = require('./baseCallback'),
baseFind = require('./baseFind'),
baseFindIndex = require('./baseFindIndex'),
isArray = require('../lang/isArray');
/**
* Creates a `_.find` or `_.findLast` function.
*
* @private
* @param {Function} eachFunc The function to iterate over a collection.
* @param {boolean} [fromRight] Specify iterating from right to left.
* @returns {Function} Returns the new find function.
*/
function createFind(eachFunc, fromRight) {
return function(collection, predicate, thisArg) {
predicate = baseCallback(predicate, thisArg, 3);
if (isArray(collection)) {
var index = baseFindIndex(collection, predicate, fromRight);
return index > -1 ? collection[index] : undefined;
}
return baseFind(collection, predicate, eachFunc);
};
}
module.exports = createFind;
},{"../lang/isArray":140,"./baseCallback":67,"./baseFind":72,"./baseFindIndex":73}],103:[function(require,module,exports){
var bindCallback = require('./bindCallback'),
isArray = require('../lang/isArray');
/**
* Creates a function for `_.forEach` or `_.forEachRight`.
*
* @private
* @param {Function} arrayFunc The function to iterate over an array.
* @param {Function} eachFunc The function to iterate over a collection.
* @returns {Function} Returns the new each function.
*/
function createForEach(arrayFunc, eachFunc) {
return function(collection, iteratee, thisArg) {
return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection))
? arrayFunc(collection, iteratee)
: eachFunc(collection, bindCallback(iteratee, thisArg, 3));
};
}
module.exports = createForEach;
},{"../lang/isArray":140,"./bindCallback":94}],104:[function(require,module,exports){
(function (global){
var arrayCopy = require('./arrayCopy'),
composeArgs = require('./composeArgs'),
composeArgsRight = require('./composeArgsRight'),
createCtorWrapper = require('./createCtorWrapper'),
isLaziable = require('./isLaziable'),
reorder = require('./reorder'),
replaceHolders = require('./replaceHolders'),
setData = require('./setData');
/** Used to compose bitmasks for wrapper metadata. */
var BIND_FLAG = 1,
BIND_KEY_FLAG = 2,
CURRY_BOUND_FLAG = 4,
CURRY_FLAG = 8,
CURRY_RIGHT_FLAG = 16,
PARTIAL_FLAG = 32,
PARTIAL_RIGHT_FLAG = 64,
ARY_FLAG = 128;
/* Native method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max;
/**
* Creates a function that wraps `func` and invokes it with optional `this`
* binding of, partial application, and currying.
*
* @private
* @param {Function|string} func The function or method name to reference.
* @param {number} bitmask The bitmask of flags. See `createWrapper` for more details.
* @param {*} [thisArg] The `this` binding of `func`.
* @param {Array} [partials] The arguments to prepend to those provided to the new function.
* @param {Array} [holders] The `partials` placeholder indexes.
* @param {Array} [partialsRight] The arguments to append to those provided to the new function.
* @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
* @param {Array} [argPos] The argument positions of the new function.
* @param {number} [ary] The arity cap of `func`.
* @param {number} [arity] The arity of `func`.
* @returns {Function} Returns the new wrapped function.
*/
function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
var isAry = bitmask & ARY_FLAG,
isBind = bitmask & BIND_FLAG,
isBindKey = bitmask & BIND_KEY_FLAG,
isCurry = bitmask & CURRY_FLAG,
isCurryBound = bitmask & CURRY_BOUND_FLAG,
isCurryRight = bitmask & CURRY_RIGHT_FLAG,
Ctor = isBindKey ? undefined : createCtorWrapper(func);
function wrapper() {
// Avoid `arguments` object use disqualifying optimizations by
// converting it to an array before providing it to other functions.
var length = arguments.length,
index = length,
args = Array(length);
while (index--) {
args[index] = arguments[index];
}
if (partials) {
args = composeArgs(args, partials, holders);
}
if (partialsRight) {
args = composeArgsRight(args, partialsRight, holdersRight);
}
if (isCurry || isCurryRight) {
var placeholder = wrapper.placeholder,
argsHolders = replaceHolders(args, placeholder);
length -= argsHolders.length;
if (length < arity) {
var newArgPos = argPos ? arrayCopy(argPos) : undefined,
newArity = nativeMax(arity - length, 0),
newsHolders = isCurry ? argsHolders : undefined,
newHoldersRight = isCurry ? undefined : argsHolders,
newPartials = isCurry ? args : undefined,
newPartialsRight = isCurry ? undefined : args;
bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);
bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);
if (!isCurryBound) {
bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
}
var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity],
result = createHybridWrapper.apply(undefined, newData);
if (isLaziable(func)) {
setData(result, newData);
}
result.placeholder = placeholder;
return result;
}
}
var thisBinding = isBind ? thisArg : this,
fn = isBindKey ? thisBinding[func] : func;
if (argPos) {
args = reorder(args, argPos);
}
if (isAry && ary < args.length) {
args.length = ary;
}
if (this && this !== global && this instanceof wrapper) {
fn = Ctor || createCtorWrapper(func);
}
return fn.apply(thisBinding, args);
}
return wrapper;
}
module.exports = createHybridWrapper;
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./arrayCopy":62,"./composeArgs":96,"./composeArgsRight":97,"./createCtorWrapper":101,"./isLaziable":124,"./reorder":131,"./replaceHolders":132,"./setData":133}],105:[function(require,module,exports){
(function (global){
var createCtorWrapper = require('./createCtorWrapper');
/** Used to compose bitmasks for wrapper metadata. */
var BIND_FLAG = 1;
/**
* Creates a function that wraps `func` and invokes it with the optional `this`
* binding of `thisArg` and the `partials` prepended to those provided to
* the wrapper.
*
* @private
* @param {Function} func The function to partially apply arguments to.
* @param {number} bitmask The bitmask of flags. See `createWrapper` for more details.
* @param {*} thisArg The `this` binding of `func`.
* @param {Array} partials The arguments to prepend to those provided to the new function.
* @returns {Function} Returns the new bound function.
*/
function createPartialWrapper(func, bitmask, thisArg, partials) {
var isBind = bitmask & BIND_FLAG,
Ctor = createCtorWrapper(func);
function wrapper() {
// Avoid `arguments` object use disqualifying optimizations by
// converting it to an array before providing it `func`.
var argsIndex = -1,
argsLength = arguments.length,
leftIndex = -1,
leftLength = partials.length,
args = Array(leftLength + argsLength);
while (++leftIndex < leftLength) {
args[leftIndex] = partials[leftIndex];
}
while (argsLength--) {
args[leftIndex++] = arguments[++argsIndex];
}
var fn = (this && this !== global && this instanceof wrapper) ? Ctor : func;
return fn.apply(isBind ? thisArg : this, args);
}
return wrapper;
}
module.exports = createPartialWrapper;
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./createCtorWrapper":101}],106:[function(require,module,exports){
var baseSetData = require('./baseSetData'),
createBindWrapper = require('./createBindWrapper'),
createHybridWrapper = require('./createHybridWrapper'),
createPartialWrapper = require('./createPartialWrapper'),
getData = require('./getData'),
mergeData = require('./mergeData'),
setData = require('./setData');
/** Used to compose bitmasks for wrapper metadata. */
var BIND_FLAG = 1,
BIND_KEY_FLAG = 2,
PARTIAL_FLAG = 32,
PARTIAL_RIGHT_FLAG = 64;
/** Used as the `TypeError` message for "Functions" methods. */
var FUNC_ERROR_TEXT = 'Expected a function';
/* Native method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max;
/**
* Creates a function that either curries or invokes `func` with optional
* `this` binding and partially applied arguments.
*
* @private
* @param {Function|string} func The function or method name to reference.
* @param {number} bitmask The bitmask of flags.
* The bitmask may be composed of the following flags:
* 1 - `_.bind`
* 2 - `_.bindKey`
* 4 - `_.curry` or `_.curryRight` of a bound function
* 8 - `_.curry`
* 16 - `_.curryRight`
* 32 - `_.partial`
* 64 - `_.partialRight`
* 128 - `_.rearg`
* 256 - `_.ary`
* @param {*} [thisArg] The `this` binding of `func`.
* @param {Array} [partials] The arguments to be partially applied.
* @param {Array} [holders] The `partials` placeholder indexes.
* @param {Array} [argPos] The argument positions of the new function.
* @param {number} [ary] The arity cap of `func`.
* @param {number} [arity] The arity of `func`.
* @returns {Function} Returns the new wrapped function.
*/
function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
var isBindKey = bitmask & BIND_KEY_FLAG;
if (!isBindKey && typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
var length = partials ? partials.length : 0;
if (!length) {
bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);
partials = holders = undefined;
}
length -= (holders ? holders.length : 0);
if (bitmask & PARTIAL_RIGHT_FLAG) {
var partialsRight = partials,
holdersRight = holders;
partials = holders = undefined;
}
var data = isBindKey ? undefined : getData(func),
newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity];
if (data) {
mergeData(newData, data);
bitmask = newData[1];
arity = newData[9];
}
newData[9] = arity == null
? (isBindKey ? 0 : func.length)
: (nativeMax(arity - length, 0) || 0);
if (bitmask == BIND_FLAG) {
var result = createBindWrapper(newData[0], newData[2]);
} else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) {
result = createPartialWrapper.apply(undefined, newData);
} else {
result = createHybridWrapper.apply(undefined, newData);
}
var setter = data ? baseSetData : setData;
return setter(result, newData);
}
module.exports = createWrapper;
},{"./baseSetData":88,"./createBindWrapper":100,"./createHybridWrapper":104,"./createPartialWrapper":105,"./getData":110,"./mergeData":128,"./setData":133}],107:[function(require,module,exports){
var arraySome = require('./arraySome');
/**
* A specialized version of `baseIsEqualDeep` for arrays with support for
* partial deep comparisons.
*
* @private
* @param {Array} array The array to compare.
* @param {Array} other The other array to compare.
* @param {Function} equalFunc The function to determine equivalents of values.
* @param {Function} [customizer] The function to customize comparing arrays.
* @param {boolean} [isLoose] Specify performing partial comparisons.
* @param {Array} [stackA] Tracks traversed `value` objects.
* @param {Array} [stackB] Tracks traversed `other` objects.
* @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
*/
function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) {
var index = -1,
arrLength = array.length,
othLength = other.length;
if (arrLength != othLength && !(isLoose && othLength > arrLength)) {
return false;
}
// Ignore non-index properties.
while (++index < arrLength) {
var arrValue = array[index],
othValue = other[index],
result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined;
if (result !== undefined) {
if (result) {
continue;
}
return false;
}
// Recursively compare arrays (susceptible to call stack limits).
if (isLoose) {
if (!arraySome(other, function(othValue) {
return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB);
})) {
return false;
}
} else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) {
return false;
}
}
return true;
}
module.exports = equalArrays;
},{"./arraySome":65}],108:[function(require,module,exports){
/** `Object#toString` result references. */
var boolTag = '[object Boolean]',
dateTag = '[object Date]',
errorTag = '[object Error]',
numberTag = '[object Number]',
regexpTag = '[object RegExp]',
stringTag = '[object String]';
/**
* A specialized version of `baseIsEqualDeep` for comparing objects of
* the same `toStringTag`.
*
* **Note:** This function only supports comparing values with tags of
* `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
*
* @private
* @param {Object} object The object to compare.
* @param {Object} other The other object to compare.
* @param {string} tag The `toStringTag` of the objects to compare.
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
*/
function equalByTag(object, other, tag) {
switch (tag) {
case boolTag:
case dateTag:
// Coerce dates and booleans to numbers, dates to milliseconds and booleans
// to `1` or `0` treating invalid dates coerced to `NaN` as not equal.
return +object == +other;
case errorTag:
return object.name == other.name && object.message == other.message;
case numberTag:
// Treat `NaN` vs. `NaN` as equal.
return (object != +object)
? other != +other
: object == +other;
case regexpTag:
case stringTag:
// Coerce regexes to strings and treat strings primitives and string
// objects as equal. See https://es5.github.io/#x15.10.6.4 for more details.
return object == (other + '');
}
return false;
}
module.exports = equalByTag;
},{}],109:[function(require,module,exports){
var keys = require('../object/keys');
/** Used for native method references. */
var objectProto = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/**
* A specialized version of `baseIsEqualDeep` for objects with support for
* partial deep comparisons.
*
* @private
* @param {Object} object The object to compare.
* @param {Object} other The other object to compare.
* @param {Function} equalFunc The function to determine equivalents of values.
* @param {Function} [customizer] The function to customize comparing values.
* @param {boolean} [isLoose] Specify performing partial comparisons.
* @param {Array} [stackA] Tracks traversed `value` objects.
* @param {Array} [stackB] Tracks traversed `other` objects.
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
*/
function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
var objProps = keys(object),
objLength = objProps.length,
othProps = keys(other),
othLength = othProps.length;
if (objLength != othLength && !isLoose) {
return false;
}
var index = objLength;
while (index--) {
var key = objProps[index];
if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) {
return false;
}
}
var skipCtor = isLoose;
while (++index < objLength) {
key = objProps[index];
var objValue = object[key],
othValue = other[key],
result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined;
// Recursively compare objects (susceptible to call stack limits).
if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) {
return false;
}
skipCtor || (skipCtor = key == 'constructor');
}
if (!skipCtor) {
var objCtor = object.constructor,
othCtor = other.constructor;
// Non `Object` object instances with different constructors are not equal.
if (objCtor != othCtor &&
('constructor' in object && 'constructor' in other) &&
!(typeof objCtor == 'function' && objCtor instanceof objCtor &&
typeof othCtor == 'function' && othCtor instanceof othCtor)) {
return false;
}
}
return true;
}
module.exports = equalObjects;
},{"../object/keys":149}],110:[function(require,module,exports){
var metaMap = require('./metaMap'),
noop = require('../utility/noop');
/**
* Gets metadata for `func`.
*
* @private
* @param {Function} func The function to query.
* @returns {*} Returns the metadata for `func`.
*/
var getData = !metaMap ? noop : function(func) {
return metaMap.get(func);
};
module.exports = getData;
},{"../utility/noop":155,"./metaMap":129}],111:[function(require,module,exports){
var realNames = require('./realNames');
/**
* Gets the name of `func`.
*
* @private
* @param {Function} func The function to query.
* @returns {string} Returns the function name.
*/
function getFuncName(func) {
var result = (func.name + ''),
array = realNames[result],
length = array ? array.length : 0;
while (length--) {
var data = array[length],
otherFunc = data.func;
if (otherFunc == null || otherFunc == func) {
return data.name;
}
}
return result;
}
module.exports = getFuncName;
},{"./realNames":130}],112:[function(require,module,exports){
var baseProperty = require('./baseProperty');
/**
* Gets the "length" property value of `object`.
*
* **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
* that affects Safari on at least iOS 8.1-8.3 ARM64.
*
* @private
* @param {Object} object The object to query.
* @returns {*} Returns the "length" value.
*/
var getLength = baseProperty('length');
module.exports = getLength;
},{"./baseProperty":86}],113:[function(require,module,exports){
var isStrictComparable = require('./isStrictComparable'),
pairs = require('../object/pairs');
/**
* Gets the propery names, values, and compare flags of `object`.
*
* @private
* @param {Object} object The object to query.
* @returns {Array} Returns the match data of `object`.
*/
function getMatchData(object) {
var result = pairs(object),
length = result.length;
while (length--) {
result[length][2] = isStrictComparable(result[length][1]);
}
return result;
}
module.exports = getMatchData;
},{"../object/pairs":151,"./isStrictComparable":127}],114:[function(require,module,exports){
var isNative = require('../lang/isNative');
/**
* Gets the native function at `key` of `object`.
*
* @private
* @param {Object} object The object to query.
* @param {string} key The key of the method to get.
* @returns {*} Returns the function if it's native, else `undefined`.
*/
function getNative(object, key) {
var value = object == null ? undefined : object[key];
return isNative(value) ? value : undefined;
}
module.exports = getNative;
},{"../lang/isNative":143}],115:[function(require,module,exports){
/**
* Gets the index at which the first occurrence of `NaN` is found in `array`.
*
* @private
* @param {Array} array The array to search.
* @param {number} fromIndex The index to search from.
* @param {boolean} [fromRight] Specify iterating from right to left.
* @returns {number} Returns the index of the matched `NaN`, else `-1`.
*/
function indexOfNaN(array, fromIndex, fromRight) {
var length = array.length,
index = fromIndex + (fromRight ? 0 : -1);
while ((fromRight ? index-- : ++index < length)) {
var other = array[index];
if (other !== other) {
return index;
}
}
return -1;
}
module.exports = indexOfNaN;
},{}],116:[function(require,module,exports){
/** Used for native method references. */
var objectProto = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/**
* Initializes an array clone.
*
* @private
* @param {Array} array The array to clone.
* @returns {Array} Returns the initialized clone.
*/
function initCloneArray(array) {
var length = array.length,
result = new array.constructor(length);
// Add array properties assigned by `RegExp#exec`.
if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
result.index = array.index;
result.input = array.input;
}
return result;
}
module.exports = initCloneArray;
},{}],117:[function(require,module,exports){
(function (global){
var bufferClone = require('./bufferClone');
/** `Object#toString` result references. */
var boolTag = '[object Boolean]',
dateTag = '[object Date]',
numberTag = '[object Number]',
regexpTag = '[object RegExp]',
stringTag = '[object String]';
var arrayBufferTag = '[object ArrayBuffer]',
float32Tag = '[object Float32Array]',
float64Tag = '[object Float64Array]',
int8Tag = '[object Int8Array]',
int16Tag = '[object Int16Array]',
int32Tag = '[object Int32Array]',
uint8Tag = '[object Uint8Array]',
uint8ClampedTag = '[object Uint8ClampedArray]',
uint16Tag = '[object Uint16Array]',
uint32Tag = '[object Uint32Array]';
/** Used to match `RegExp` flags from their coerced string values. */
var reFlags = /\w*$/;
/** Native method references. */
var Uint8Array = global.Uint8Array;
/** Used to lookup a type array constructors by `toStringTag`. */
var ctorByTag = {};
ctorByTag[float32Tag] = global.Float32Array;
ctorByTag[float64Tag] = global.Float64Array;
ctorByTag[int8Tag] = global.Int8Array;
ctorByTag[int16Tag] = global.Int16Array;
ctorByTag[int32Tag] = global.Int32Array;
ctorByTag[uint8Tag] = Uint8Array;
ctorByTag[uint8ClampedTag] = global.Uint8ClampedArray;
ctorByTag[uint16Tag] = global.Uint16Array;
ctorByTag[uint32Tag] = global.Uint32Array;
/**
* Initializes an object clone based on its `toStringTag`.
*
* **Note:** This function only supports cloning values with tags of
* `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
*
* @private
* @param {Object} object The object to clone.
* @param {string} tag The `toStringTag` of the object to clone.
* @param {boolean} [isDeep] Specify a deep clone.
* @returns {Object} Returns the initialized clone.
*/
function initCloneByTag(object, tag, isDeep) {
var Ctor = object.constructor;
switch (tag) {
case arrayBufferTag:
return bufferClone(object);
case boolTag:
case dateTag:
return new Ctor(+object);
case float32Tag: case float64Tag:
case int8Tag: case int16Tag: case int32Tag:
case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
// Safari 5 mobile incorrectly has `Object` as the constructor of typed arrays.
if (Ctor instanceof Ctor) {
Ctor = ctorByTag[tag];
}
var buffer = object.buffer;
return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length);
case numberTag:
case stringTag:
return new Ctor(object);
case regexpTag:
var result = new Ctor(object.source, reFlags.exec(object));
result.lastIndex = object.lastIndex;
}
return result;
}
module.exports = initCloneByTag;
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./bufferClone":95}],118:[function(require,module,exports){
/**
* Initializes an object clone.
*
* @private
* @param {Object} object The object to clone.
* @returns {Object} Returns the initialized clone.
*/
function initCloneObject(object) {
var Ctor = object.constructor;
if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) {
Ctor = Object;
}
return new Ctor;
}
module.exports = initCloneObject;
},{}],119:[function(require,module,exports){
var getLength = require('./getLength'),
isLength = require('./isLength');
/**
* Checks if `value` is array-like.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is array-like, else `false`.
*/
function isArrayLike(value) {
return value != null && isLength(getLength(value));
}
module.exports = isArrayLike;
},{"./getLength":112,"./isLength":125}],120:[function(require,module,exports){
/**
* Checks if `value` is a host object in IE < 9.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a host object, else `false`.
*/
var isHostObject = (function() {
try {
Object({ 'toString': 0 } + '');
} catch(e) {
return function() { return false; };
}
return function(value) {
// IE < 9 presents many host objects as `Object` objects that can coerce
// to strings despite having improperly defined `toString` methods.
return typeof value.toString != 'function' && typeof (value + '') == 'string';
};
}());
module.exports = isHostObject;
},{}],121:[function(require,module,exports){
/** Used to detect unsigned integer values. */
var reIsUint = /^\d+$/;
/**
* Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
* of an array-like value.
*/
var MAX_SAFE_INTEGER = 9007199254740991;
/**
* Checks if `value` is a valid array-like index.
*
* @private
* @param {*} value The value to check.
* @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
* @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
*/
function isIndex(value, length) {
value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
length = length == null ? MAX_SAFE_INTEGER : length;
return value > -1 && value % 1 == 0 && value < length;
}
module.exports = isIndex;
},{}],122:[function(require,module,exports){
var isArrayLike = require('./isArrayLike'),
isIndex = require('./isIndex'),
isObject = require('../lang/isObject');
/**
* Checks if the provided arguments are from an iteratee call.
*
* @private
* @param {*} value The potential iteratee value argument.
* @param {*} index The potential iteratee index or key argument.
* @param {*} object The potential iteratee object argument.
* @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.
*/
function isIterateeCall(value, index, object) {
if (!isObject(object)) {
return false;
}
var type = typeof index;
if (type == 'number'
? (isArrayLike(object) && isIndex(index, object.length))
: (type == 'string' && index in object)) {
var other = object[index];
return value === value ? (value === other) : (other !== other);
}
return false;
}
module.exports = isIterateeCall;
},{"../lang/isObject":144,"./isArrayLike":119,"./isIndex":121}],123:[function(require,module,exports){
var isArray = require('../lang/isArray'),
toObject = require('./toObject');
/** Used to match property names within property paths. */
var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,
reIsPlainProp = /^\w*$/;
/**
* Checks if `value` is a property name and not a property path.
*
* @private
* @param {*} value The value to check.
* @param {Object} [object] The object to query keys on.
* @returns {boolean} Returns `true` if `value` is a property name, else `false`.
*/
function isKey(value, object) {
var type = typeof value;
if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') {
return true;
}
if (isArray(value)) {
return false;
}
var result = !reIsDeepProp.test(value);
return result || (object != null && value in toObject(object));
}
module.exports = isKey;
},{"../lang/isArray":140,"./toObject":135}],124:[function(require,module,exports){
var LazyWrapper = require('./LazyWrapper'),
getData = require('./getData'),
getFuncName = require('./getFuncName'),
lodash = require('../chain/lodash');
/**
* Checks if `func` has a lazy counterpart.
*
* @private
* @param {Function} func The function to check.
* @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`.
*/
function isLaziable(func) {
var funcName = getFuncName(func),
other = lodash[funcName];
if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
return false;
}
if (func === other) {
return true;
}
var data = getData(other);
return !!data && func === data[0];
}
module.exports = isLaziable;
},{"../chain/lodash":51,"./LazyWrapper":60,"./getData":110,"./getFuncName":111}],125:[function(require,module,exports){
/**
* Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
* of an array-like value.
*/
var MAX_SAFE_INTEGER = 9007199254740991;
/**
* Checks if `value` is a valid array-like length.
*
* **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
*/
function isLength(value) {
return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
}
module.exports = isLength;
},{}],126:[function(require,module,exports){
/**
* Checks if `value` is object-like.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
*/
function isObjectLike(value) {
return !!value && typeof value == 'object';
}
module.exports = isObjectLike;
},{}],127:[function(require,module,exports){
var isObject = require('../lang/isObject');
/**
* Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` if suitable for strict
* equality comparisons, else `false`.
*/
function isStrictComparable(value) {
return value === value && !isObject(value);
}
module.exports = isStrictComparable;
},{"../lang/isObject":144}],128:[function(require,module,exports){
var arrayCopy = require('./arrayCopy'),
composeArgs = require('./composeArgs'),
composeArgsRight = require('./composeArgsRight'),
replaceHolders = require('./replaceHolders');
/** Used to compose bitmasks for wrapper metadata. */
var BIND_FLAG = 1,
CURRY_BOUND_FLAG = 4,
CURRY_FLAG = 8,
ARY_FLAG = 128,
REARG_FLAG = 256;
/** Used as the internal argument placeholder. */
var PLACEHOLDER = '__lodash_placeholder__';
/* Native method references for those with the same name as other `lodash` methods. */
var nativeMin = Math.min;
/**
* Merges the function metadata of `source` into `data`.
*
* Merging metadata reduces the number of wrappers required to invoke a function.
* This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
* may be applied regardless of execution order. Methods like `_.ary` and `_.rearg`
* augment function arguments, making the order in which they are executed important,
* preventing the merging of metadata. However, we make an exception for a safe
* common case where curried functions have `_.ary` and or `_.rearg` applied.
*
* @private
* @param {Array} data The destination metadata.
* @param {Array} source The source metadata.
* @returns {Array} Returns `data`.
*/
function mergeData(data, source) {
var bitmask = data[1],
srcBitmask = source[1],
newBitmask = bitmask | srcBitmask,
isCommon = newBitmask < ARY_FLAG;
var isCombo =
(srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) ||
(srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) ||
(srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG);
// Exit early if metadata can't be merged.
if (!(isCommon || isCombo)) {
return data;
}
// Use source `thisArg` if available.
if (srcBitmask & BIND_FLAG) {
data[2] = source[2];
// Set when currying a bound function.
newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG;
}
// Compose partial arguments.
var value = source[3];
if (value) {
var partials = data[3];
data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value);
data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]);
}
// Compose partial right arguments.
value = source[5];
if (value) {
partials = data[5];
data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value);
data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]);
}
// Use source `argPos` if available.
value = source[7];
if (value) {
data[7] = arrayCopy(value);
}
// Use source `ary` if it's smaller.
if (srcBitmask & ARY_FLAG) {
data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
}
// Use source `arity` if one is not provided.
if (data[9] == null) {
data[9] = source[9];
}
// Use source `func` and merge bitmasks.
data[0] = source[0];
data[1] = newBitmask;
return data;
}
module.exports = mergeData;
},{"./arrayCopy":62,"./composeArgs":96,"./composeArgsRight":97,"./replaceHolders":132}],129:[function(require,module,exports){
(function (global){
var getNative = require('./getNative');
/** Native method references. */
var WeakMap = getNative(global, 'WeakMap');
/** Used to store function metadata. */
var metaMap = WeakMap && new WeakMap;
module.exports = metaMap;
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./getNative":114}],130:[function(require,module,exports){
/** Used to lookup unminified function names. */
var realNames = {};
module.exports = realNames;
},{}],131:[function(require,module,exports){
var arrayCopy = require('./arrayCopy'),
isIndex = require('./isIndex');
/* Native method references for those with the same name as other `lodash` methods. */
var nativeMin = Math.min;
/**
* Reorder `array` according to the specified indexes where the element at
* the first index is assigned as the first element, the element at
* the second index is assigned as the second element, and so on.
*
* @private
* @param {Array} array The array to reorder.
* @param {Array} indexes The arranged array indexes.
* @returns {Array} Returns `array`.
*/
function reorder(array, indexes) {
var arrLength = array.length,
length = nativeMin(indexes.length, arrLength),
oldArray = arrayCopy(array);
while (length--) {
var index = indexes[length];
array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
}
return array;
}
module.exports = reorder;
},{"./arrayCopy":62,"./isIndex":121}],132:[function(require,module,exports){
/** Used as the internal argument placeholder. */
var PLACEHOLDER = '__lodash_placeholder__';
/**
* Replaces all `placeholder` elements in `array` with an internal placeholder
* and returns an array of their indexes.
*
* @private
* @param {Array} array The array to modify.
* @param {*} placeholder The placeholder to replace.
* @returns {Array} Returns the new array of placeholder indexes.
*/
function replaceHolders(array, placeholder) {
var index = -1,
length = array.length,
resIndex = -1,
result = [];
while (++index < length) {
if (array[index] === placeholder) {
array[index] = PLACEHOLDER;
result[++resIndex] = index;
}
}
return result;
}
module.exports = replaceHolders;
},{}],133:[function(require,module,exports){
var baseSetData = require('./baseSetData'),
now = require('../date/now');
/** Used to detect when a function becomes hot. */
var HOT_COUNT = 150,
HOT_SPAN = 16;
/**
* Sets metadata for `func`.
*
* **Note:** If this function becomes hot, i.e. is invoked a lot in a short
* period of time, it will trip its breaker and transition to an identity function
* to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070)
* for more details.
*
* @private
* @param {Function} func The function to associate metadata with.
* @param {*} data The metadata.
* @returns {Function} Returns `func`.
*/
var setData = (function() {
var count = 0,
lastCalled = 0;
return function(key, value) {
var stamp = now(),
remaining = HOT_SPAN - (stamp - lastCalled);
lastCalled = stamp;
if (remaining > 0) {
if (++count >= HOT_COUNT) {
return key;
}
} else {
count = 0;
}
return baseSetData(key, value);
};
}());
module.exports = setData;
},{"../date/now":57,"./baseSetData":88}],134:[function(require,module,exports){
var isArguments = require('../lang/isArguments'),
isArray = require('../lang/isArray'),
isIndex = require('./isIndex'),
isLength = require('./isLength'),
isString = require('../lang/isString'),
keysIn = require('../object/keysIn');
/** Used for native method references. */
var objectProto = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/**
* A fallback implementation of `Object.keys` which creates an array of the
* own enumerable property names of `object`.
*
* @private
* @param {Object} object The object to query.
* @returns {Array} Returns the array of property names.
*/
function shimKeys(object) {
var props = keysIn(object),
propsLength = props.length,
length = propsLength && object.length;
var allowIndexes = !!length && isLength(length) &&
(isArray(object) || isArguments(object) || isString(object));
var index = -1,
result = [];
while (++index < propsLength) {
var key = props[index];
if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {
result.push(key);
}
}
return result;
}
module.exports = shimKeys;
},{"../lang/isArguments":139,"../lang/isArray":140,"../lang/isString":146,"../object/keysIn":150,"./isIndex":121,"./isLength":125}],135:[function(require,module,exports){
var isObject = require('../lang/isObject'),
isString = require('../lang/isString'),
support = require('../support');
/**
* Converts `value` to an object if it's not one.
*
* @private
* @param {*} value The value to process.
* @returns {Object} Returns the object.
*/
function toObject(value) {
if (support.unindexedChars && isString(value)) {
var index = -1,
length = value.length,
result = Object(value);
while (++index < length) {
result[index] = value.charAt(index);
}
return result;
}
return isObject(value) ? value : Object(value);
}
module.exports = toObject;
},{"../lang/isObject":144,"../lang/isString":146,"../support":153}],136:[function(require,module,exports){
var baseToString = require('./baseToString'),
isArray = require('../lang/isArray');
/** Used to match property names within property paths. */
var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g;
/** Used to match backslashes in property paths. */
var reEscapeChar = /\\(\\)?/g;
/**
* Converts `value` to property path array if it's not one.
*
* @private
* @param {*} value The value to process.
* @returns {Array} Returns the property path array.
*/
function toPath(value) {
if (isArray(value)) {
return value;
}
var result = [];
baseToString(value).replace(rePropName, function(match, number, quote, string) {
result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
});
return result;
}
module.exports = toPath;
},{"../lang/isArray":140,"./baseToString":90}],137:[function(require,module,exports){
var LazyWrapper = require('./LazyWrapper'),
LodashWrapper = require('./LodashWrapper'),
arrayCopy = require('./arrayCopy');
/**
* Creates a clone of `wrapper`.
*
* @private
* @param {Object} wrapper The wrapper to clone.
* @returns {Object} Returns the cloned wrapper.
*/
function wrapperClone(wrapper) {
return wrapper instanceof LazyWrapper
? wrapper.clone()
: new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__));
}
module.exports = wrapperClone;
},{"./LazyWrapper":60,"./LodashWrapper":61,"./arrayCopy":62}],138:[function(require,module,exports){
var baseClone = require('../internal/baseClone'),
bindCallback = require('../internal/bindCallback');
/**
* Creates a deep clone of `value`. If `customizer` is provided it's invoked
* to produce the cloned values. If `customizer` returns `undefined` cloning
* is handled by the method instead. The `customizer` is bound to `thisArg`
* and invoked with up to three argument; (value [, index|key, object]).
*
* **Note:** This method is loosely based on the
* [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm).
* The enumerable properties of `arguments` objects and objects created by
* constructors other than `Object` are cloned to plain `Object` objects. An
* empty object is returned for uncloneable values such as functions, DOM nodes,
* Maps, Sets, and WeakMaps.
*
* @static
* @memberOf _
* @category Lang
* @param {*} value The value to deep clone.
* @param {Function} [customizer] The function to customize cloning values.
* @param {*} [thisArg] The `this` binding of `customizer`.
* @returns {*} Returns the deep cloned value.
* @example
*
* var users = [
* { 'user': 'barney' },
* { 'user': 'fred' }
* ];
*
* var deep = _.cloneDeep(users);
* deep[0] === users[0];
* // => false
*
* // using a customizer callback
* var el = _.cloneDeep(document.body, function(value) {
* if (_.isElement(value)) {
* return value.cloneNode(true);
* }
* });
*
* el === document.body
* // => false
* el.nodeName
* // => BODY
* el.childNodes.length;
* // => 20
*/
function cloneDeep(value, customizer, thisArg) {
return typeof customizer == 'function'
? baseClone(value, true, bindCallback(customizer, thisArg, 3))
: baseClone(value, true);
}
module.exports = cloneDeep;
},{"../internal/baseClone":68,"../internal/bindCallback":94}],139:[function(require,module,exports){
var isArrayLike = require('../internal/isArrayLike'),
isObjectLike = require('../internal/isObjectLike');
/** Used for native method references. */
var objectProto = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/** Native method references. */
var propertyIsEnumerable = objectProto.propertyIsEnumerable;
/**
* Checks if `value` is classified as an `arguments` object.
*
* @static
* @memberOf _
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
* @example
*
* _.isArguments(function() { return arguments; }());
* // => true
*
* _.isArguments([1, 2, 3]);
* // => false
*/
function isArguments(value) {
return isObjectLike(value) && isArrayLike(value) &&
hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee');
}
module.exports = isArguments;
},{"../internal/isArrayLike":119,"../internal/isObjectLike":126}],140:[function(require,module,exports){
var getNative = require('../internal/getNative'),
isLength = require('../internal/isLength'),
isObjectLike = require('../internal/isObjectLike');
/** `Object#toString` result references. */
var arrayTag = '[object Array]';
/** Used for native method references. */
var objectProto = Object.prototype;
/**
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
var objToString = objectProto.toString;
/* Native method references for those with the same name as other `lodash` methods. */
var nativeIsArray = getNative(Array, 'isArray');
/**
* Checks if `value` is classified as an `Array` object.
*
* @static
* @memberOf _
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
* @example
*
* _.isArray([1, 2, 3]);
* // => true
*
* _.isArray(function() { return arguments; }());
* // => false
*/
var isArray = nativeIsArray || function(value) {
return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;
};
module.exports = isArray;
},{"../internal/getNative":114,"../internal/isLength":125,"../internal/isObjectLike":126}],141:[function(require,module,exports){
var isArguments = require('./isArguments'),
isArray = require('./isArray'),
isArrayLike = require('../internal/isArrayLike'),
isFunction = require('./isFunction'),
isObjectLike = require('../internal/isObjectLike'),
isString = require('./isString'),
keys = require('../object/keys');
/**
* Checks if `value` is empty. A value is considered empty unless it's an
* `arguments` object, array, string, or jQuery-like collection with a length
* greater than `0` or an object with own enumerable properties.
*
* @static
* @memberOf _
* @category Lang
* @param {Array|Object|string} value The value to inspect.
* @returns {boolean} Returns `true` if `value` is empty, else `false`.
* @example
*
* _.isEmpty(null);
* // => true
*
* _.isEmpty(true);
* // => true
*
* _.isEmpty(1);
* // => true
*
* _.isEmpty([1, 2, 3]);
* // => false
*
* _.isEmpty({ 'a': 1 });
* // => false
*/
function isEmpty(value) {
if (value == null) {
return true;
}
if (isArrayLike(value) && (isArray(value) || isString(value) || isArguments(value) ||
(isObjectLike(value) && isFunction(value.splice)))) {
return !value.length;
}
return !keys(value).length;
}
module.exports = isEmpty;
},{"../internal/isArrayLike":119,"../internal/isObjectLike":126,"../object/keys":149,"./isArguments":139,"./isArray":140,"./isFunction":142,"./isString":146}],142:[function(require,module,exports){
var isObject = require('./isObject');
/** `Object#toString` result references. */
var funcTag = '[object Function]';
/** Used for native method references. */
var objectProto = Object.prototype;
/**
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
var objToString = objectProto.toString;
/**
* Checks if `value` is classified as a `Function` object.
*
* @static
* @memberOf _
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
* @example
*
* _.isFunction(_);
* // => true
*
* _.isFunction(/abc/);
* // => false
*/
function isFunction(value) {
// The use of `Object#toString` avoids issues with the `typeof` operator
// in older versions of Chrome and Safari which return 'function' for regexes
// and Safari 8 which returns 'object' for typed array constructors.
return isObject(value) && objToString.call(value) == funcTag;
}
module.exports = isFunction;
},{"./isObject":144}],143:[function(require,module,exports){
var isFunction = require('./isFunction'),
isHostObject = require('../internal/isHostObject'),
isObjectLike = require('../internal/isObjectLike');
/** Used to detect host constructors (Safari > 5). */
var reIsHostCtor = /^\[object .+?Constructor\]$/;
/** Used for native method references. */
var objectProto = Object.prototype;
/** Used to resolve the decompiled source of functions. */
var fnToString = Function.prototype.toString;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/** Used to detect if a method is native. */
var reIsNative = RegExp('^' +
fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
.replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
);
/**
* Checks if `value` is a native function.
*
* @static
* @memberOf _
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a native function, else `false`.
* @example
*
* _.isNative(Array.prototype.push);
* // => true
*
* _.isNative(_);
* // => false
*/
function isNative(value) {
if (value == null) {
return false;
}
if (isFunction(value)) {
return reIsNative.test(fnToString.call(value));
}
return isObjectLike(value) && (isHostObject(value) ? reIsNative : reIsHostCtor).test(value);
}
module.exports = isNative;
},{"../internal/isHostObject":120,"../internal/isObjectLike":126,"./isFunction":142}],144:[function(require,module,exports){
/**
* Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
* (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
*
* @static
* @memberOf _
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
* @example
*
* _.isObject({});
* // => true
*
* _.isObject([1, 2, 3]);
* // => true
*
* _.isObject(1);
* // => false
*/
function isObject(value) {
// Avoid a V8 JIT bug in Chrome 19-20.
// See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
var type = typeof value;
return !!value && (type == 'object' || type == 'function');
}
module.exports = isObject;
},{}],145:[function(require,module,exports){
var baseForIn = require('../internal/baseForIn'),
isArguments = require('./isArguments'),
isHostObject = require('../internal/isHostObject'),
isObjectLike = require('../internal/isObjectLike'),
support = require('../support');
/** `Object#toString` result references. */
var objectTag = '[object Object]';
/** Used for native method references. */
var objectProto = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/**
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
var objToString = objectProto.toString;
/**
* Checks if `value` is a plain object, that is, an object created by the
* `Object` constructor or one with a `[[Prototype]]` of `null`.
*
* **Note:** This method assumes objects created by the `Object` constructor
* have no inherited enumerable properties.
*
* @static
* @memberOf _
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
* @example
*
* function Foo() {
* this.a = 1;
* }
*
* _.isPlainObject(new Foo);
* // => false
*
* _.isPlainObject([1, 2, 3]);
* // => false
*
* _.isPlainObject({ 'x': 0, 'y': 0 });
* // => true
*
* _.isPlainObject(Object.create(null));
* // => true
*/
function isPlainObject(value) {
var Ctor;
// Exit early for non `Object` objects.
if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isHostObject(value) && !isArguments(value)) ||
(!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) {
return false;
}
// IE < 9 iterates inherited properties before own properties. If the first
// iterated property is an object's own property then there are no inherited
// enumerable properties.
var result;
if (support.ownLast) {
baseForIn(value, function(subValue, key, object) {
result = hasOwnProperty.call(object, key);
return false;
});
return result !== false;
}
// In most environments an object's own properties are iterated before
// its inherited properties. If the last iterated property is an object's
// own property then there are no inherited enumerable properties.
baseForIn(value, function(subValue, key) {
result = key;
});
return result === undefined || hasOwnProperty.call(value, result);
}
module.exports = isPlainObject;
},{"../internal/baseForIn":75,"../internal/isHostObject":120,"../internal/isObjectLike":126,"../support":153,"./isArguments":139}],146:[function(require,module,exports){
var isObjectLike = require('../internal/isObjectLike');
/** `Object#toString` result references. */
var stringTag = '[object String]';
/** Used for native method references. */
var objectProto = Object.prototype;
/**
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
var objToString = objectProto.toString;
/**
* Checks if `value` is classified as a `String` primitive or object.
*
* @static
* @memberOf _
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
* @example
*
* _.isString('abc');
* // => true
*
* _.isString(1);
* // => false
*/
function isString(value) {
return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag);
}
module.exports = isString;
},{"../internal/isObjectLike":126}],147:[function(require,module,exports){
var isLength = require('../internal/isLength'),
isObjectLike = require('../internal/isObjectLike');
/** `Object#toString` result references. */
var argsTag = '[object Arguments]',
arrayTag = '[object Array]',
boolTag = '[object Boolean]',
dateTag = '[object Date]',
errorTag = '[object Error]',
funcTag = '[object Function]',
mapTag = '[object Map]',
numberTag = '[object Number]',
objectTag = '[object Object]',
regexpTag = '[object RegExp]',
setTag = '[object Set]',
stringTag = '[object String]',
weakMapTag = '[object WeakMap]';
var arrayBufferTag = '[object ArrayBuffer]',
float32Tag = '[object Float32Array]',
float64Tag = '[object Float64Array]',
int8Tag = '[object Int8Array]',
int16Tag = '[object Int16Array]',
int32Tag = '[object Int32Array]',
uint8Tag = '[object Uint8Array]',
uint8ClampedTag = '[object Uint8ClampedArray]',
uint16Tag = '[object Uint16Array]',
uint32Tag = '[object Uint32Array]';
/** Used to identify `toStringTag` values of typed arrays. */
var typedArrayTags = {};
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
typedArrayTags[uint32Tag] = true;
typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
typedArrayTags[dateTag] = typedArrayTags[errorTag] =
typedArrayTags[funcTag] = typedArrayTags[mapTag] =
typedArrayTags[numberTag] = typedArrayTags[objectTag] =
typedArrayTags[regexpTag] = typedArrayTags[setTag] =
typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
/** Used for native method references. */
var objectProto = Object.prototype;
/**
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
var objToString = objectProto.toString;
/**
* Checks if `value` is classified as a typed array.
*
* @static
* @memberOf _
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
* @example
*
* _.isTypedArray(new Uint8Array);
* // => true
*
* _.isTypedArray([]);
* // => false
*/
function isTypedArray(value) {
return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
}
module.exports = isTypedArray;
},{"../internal/isLength":125,"../internal/isObjectLike":126}],148:[function(require,module,exports){
/**
* Checks if `value` is `undefined`.
*
* @static
* @memberOf _
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
* @example
*
* _.isUndefined(void 0);
* // => true
*
* _.isUndefined(null);
* // => false
*/
function isUndefined(value) {
return value === undefined;
}
module.exports = isUndefined;
},{}],149:[function(require,module,exports){
var getNative = require('../internal/getNative'),
isArrayLike = require('../internal/isArrayLike'),
isObject = require('../lang/isObject'),
shimKeys = require('../internal/shimKeys'),
support = require('../support');
/* Native method references for those with the same name as other `lodash` methods. */
var nativeKeys = getNative(Object, 'keys');
/**
* Creates an array of the own enumerable property names of `object`.
*
* **Note:** Non-object values are coerced to objects. See the
* [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
* for more details.
*
* @static
* @memberOf _
* @category Object
* @param {Object} object The object to query.
* @returns {Array} Returns the array of property names.
* @example
*
* function Foo() {
* this.a = 1;
* this.b = 2;
* }
*
* Foo.prototype.c = 3;
*
* _.keys(new Foo);
* // => ['a', 'b'] (iteration order is not guaranteed)
*
* _.keys('hi');
* // => ['0', '1']
*/
var keys = !nativeKeys ? shimKeys : function(object) {
var Ctor = object == null ? undefined : object.constructor;
if ((typeof Ctor == 'function' && Ctor.prototype === object) ||
(typeof object == 'function' ? support.enumPrototypes : isArrayLike(object))) {
return shimKeys(object);
}
return isObject(object) ? nativeKeys(object) : [];
};
module.exports = keys;
},{"../internal/getNative":114,"../internal/isArrayLike":119,"../internal/shimKeys":134,"../lang/isObject":144,"../support":153}],150:[function(require,module,exports){
var arrayEach = require('../internal/arrayEach'),
isArguments = require('../lang/isArguments'),
isArray = require('../lang/isArray'),
isFunction = require('../lang/isFunction'),
isIndex = require('../internal/isIndex'),
isLength = require('../internal/isLength'),
isObject = require('../lang/isObject'),
isString = require('../lang/isString'),
support = require('../support');
/** `Object#toString` result references. */
var arrayTag = '[object Array]',
boolTag = '[object Boolean]',
dateTag = '[object Date]',
errorTag = '[object Error]',
funcTag = '[object Function]',
numberTag = '[object Number]',
objectTag = '[object Object]',
regexpTag = '[object RegExp]',
stringTag = '[object String]';
/** Used to fix the JScript `[[DontEnum]]` bug. */
var shadowProps = [
'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',
'toLocaleString', 'toString', 'valueOf'
];
/** Used for native method references. */
var errorProto = Error.prototype,
objectProto = Object.prototype,
stringProto = String.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/**
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
var objToString = objectProto.toString;
/** Used to avoid iterating over non-enumerable properties in IE < 9. */
var nonEnumProps = {};
nonEnumProps[arrayTag] = nonEnumProps[dateTag] = nonEnumProps[numberTag] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true };
nonEnumProps[boolTag] = nonEnumProps[stringTag] = { 'constructor': true, 'toString': true, 'valueOf': true };
nonEnumProps[errorTag] = nonEnumProps[funcTag] = nonEnumProps[regexpTag] = { 'constructor': true, 'toString': true };
nonEnumProps[objectTag] = { 'constructor': true };
arrayEach(shadowProps, function(key) {
for (var tag in nonEnumProps) {
if (hasOwnProperty.call(nonEnumProps, tag)) {
var props = nonEnumProps[tag];
props[key] = hasOwnProperty.call(props, key);
}
}
});
/**
* Creates an array of the own and inherited enumerable property names of `object`.
*
* **Note:** Non-object values are coerced to objects.
*
* @static
* @memberOf _
* @category Object
* @param {Object} object The object to query.
* @returns {Array} Returns the array of property names.
* @example
*
* function Foo() {
* this.a = 1;
* this.b = 2;
* }
*
* Foo.prototype.c = 3;
*
* _.keysIn(new Foo);
* // => ['a', 'b', 'c'] (iteration order is not guaranteed)
*/
function keysIn(object) {
if (object == null) {
return [];
}
if (!isObject(object)) {
object = Object(object);
}
var length = object.length;
length = (length && isLength(length) &&
(isArray(object) || isArguments(object) || isString(object)) && length) || 0;
var Ctor = object.constructor,
index = -1,
proto = (isFunction(Ctor) && Ctor.prototype) || objectProto,
isProto = proto === object,
result = Array(length),
skipIndexes = length > 0,
skipErrorProps = support.enumErrorProps && (object === errorProto || object instanceof Error),
skipProto = support.enumPrototypes && isFunction(object);
while (++index < length) {
result[index] = (index + '');
}
// lodash skips the `constructor` property when it infers it's iterating
// over a `prototype` object because IE < 9 can't set the `[[Enumerable]]`
// attribute of an existing property and the `constructor` property of a
// prototype defaults to non-enumerable.
for (var key in object) {
if (!(skipProto && key == 'prototype') &&
!(skipErrorProps && (key == 'message' || key == 'name')) &&
!(skipIndexes && isIndex(key, length)) &&
!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
result.push(key);
}
}
if (support.nonEnumShadows && object !== objectProto) {
var tag = object === stringProto ? stringTag : (object === errorProto ? errorTag : objToString.call(object)),
nonEnums = nonEnumProps[tag] || nonEnumProps[objectTag];
if (tag == objectTag) {
proto = objectProto;
}
length = shadowProps.length;
while (length--) {
key = shadowProps[length];
var nonEnum = nonEnums[key];
if (!(isProto && nonEnum) &&
(nonEnum ? hasOwnProperty.call(object, key) : object[key] !== proto[key])) {
result.push(key);
}
}
}
return result;
}
module.exports = keysIn;
},{"../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){
var keys = require('./keys'),
toObject = require('../internal/toObject');
/**
* Creates a two dimensional array of the key-value pairs for `object`,
* e.g. `[[key1, value1], [key2, value2]]`.
*
* @static
* @memberOf _
* @category Object
* @param {Object} object The object to query.
* @returns {Array} Returns the new array of key-value pairs.
* @example
*
* _.pairs({ 'barney': 36, 'fred': 40 });
* // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed)
*/
function pairs(object) {
object = toObject(object);
var index = -1,
props = keys(object),
length = props.length,
result = Array(length);
while (++index < length) {
var key = props[index];
result[index] = [key, object[key]];
}
return result;
}
module.exports = pairs;
},{"../internal/toObject":135,"./keys":149}],152:[function(require,module,exports){
var baseValues = require('../internal/baseValues'),
keys = require('./keys');
/**
* Creates an array of the own enumerable property values of `object`.
*
* **Note:** Non-object values are coerced to objects.
*
* @static
* @memberOf _
* @category Object
* @param {Object} object The object to query.
* @returns {Array} Returns the array of property values.
* @example
*
* function Foo() {
* this.a = 1;
* this.b = 2;
* }
*
* Foo.prototype.c = 3;
*
* _.values(new Foo);
* // => [1, 2] (iteration order is not guaranteed)
*
* _.values('hi');
* // => ['h', 'i']
*/
function values(object) {
return baseValues(object, keys(object));
}
module.exports = values;
},{"../internal/baseValues":91,"./keys":149}],153:[function(require,module,exports){
/** Used for native method references. */
var arrayProto = Array.prototype,
errorProto = Error.prototype,
objectProto = Object.prototype;
/** Native method references. */
var propertyIsEnumerable = objectProto.propertyIsEnumerable,
splice = arrayProto.splice;
/**
* An object environment feature flags.
*
* @static
* @memberOf _
* @type Object
*/
var support = {};
(function(x) {
var Ctor = function() { this.x = x; },
object = { '0': x, 'length': x },
props = [];
Ctor.prototype = { 'valueOf': x, 'y': x };
for (var key in new Ctor) { props.push(key); }
/**
* Detect if `name` or `message` properties of `Error.prototype` are
* enumerable by default (IE < 9, Safari < 5.1).
*
* @memberOf _.support
* @type boolean
*/
support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') ||
propertyIsEnumerable.call(errorProto, 'name');
/**
* Detect if `prototype` properties are enumerable by default.
*
* Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1
* (if the prototype or a property on the prototype has been set)
* incorrectly set the `[[Enumerable]]` value of a function's `prototype`
* property to `true`.
*
* @memberOf _.support
* @type boolean
*/
support.enumPrototypes = propertyIsEnumerable.call(Ctor, 'prototype');
/**
* Detect if properties shadowing those on `Object.prototype` are non-enumerable.
*
* In IE < 9 an object's own properties, shadowing non-enumerable ones,
* are made non-enumerable as well (a.k.a the JScript `[[DontEnum]]` bug).
*
* @memberOf _.support
* @type boolean
*/
support.nonEnumShadows = !/valueOf/.test(props);
/**
* Detect if own properties are iterated after inherited properties (IE < 9).
*
* @memberOf _.support
* @type boolean
*/
support.ownLast = props[0] != 'x';
/**
* Detect if `Array#shift` and `Array#splice` augment array-like objects
* correctly.
*
* Firefox < 10, compatibility modes of IE 8, and IE < 9 have buggy Array
* `shift()` and `splice()` functions that fail to remove the last element,
* `value[0]`, of array-like objects even though the "length" property is
* set to `0`. The `shift()` method is buggy in compatibility modes of IE 8,
* while `splice()` is buggy regardless of mode in IE < 9.
*
* @memberOf _.support
* @type boolean
*/
support.spliceObjects = (splice.call(object, 0, 1), !object[0]);
/**
* Detect lack of support for accessing string characters by index.
*
* IE < 8 can't access characters by index. IE 8 can only access characters
* by index on string literals, not string objects.
*
* @memberOf _.support
* @type boolean
*/
support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx';
}(1, 0));
module.exports = support;
},{}],154:[function(require,module,exports){
/**
* This method returns the first argument provided to it.
*
* @static
* @memberOf _
* @category Utility
* @param {*} value Any value.
* @returns {*} Returns `value`.
* @example
*
* var object = { 'user': 'fred' };
*
* _.identity(object) === object;
* // => true
*/
function identity(value) {
return value;
}
module.exports = identity;
},{}],155:[function(require,module,exports){
/**
* A no-operation function that returns `undefined` regardless of the
* arguments it receives.
*
* @static
* @memberOf _
* @category Utility
* @example
*
* var object = { 'user': 'fred' };
*
* _.noop(object) === undefined;
* // => true
*/
function noop() {
// No operation performed.
}
module.exports = noop;
},{}],156:[function(require,module,exports){
var baseProperty = require('../internal/baseProperty'),
basePropertyDeep = require('../internal/basePropertyDeep'),
isKey = require('../internal/isKey');
/**
* Creates a function that returns the property value at `path` on a
* given object.
*
* @static
* @memberOf _
* @category Utility
* @param {Array|string} path The path of the property to get.
* @returns {Function} Returns the new function.
* @example
*
* var objects = [
* { 'a': { 'b': { 'c': 2 } } },
* { 'a': { 'b': { 'c': 1 } } }
* ];
*
* _.map(objects, _.property('a.b.c'));
* // => [2, 1]
*
* _.pluck(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c');
* // => [1, 2]
*/
function property(path) {
return isKey(path) ? baseProperty(path) : basePropertyDeep(path);
}
module.exports = property;
},{"../internal/baseProperty":86,"../internal/basePropertyDeep":87,"../internal/isKey":123}],157:[function(require,module,exports){
(function (process){
// vim:ts=4:sts=4:sw=4:
/*!
*
* Copyright 2009-2012 Kris Kowal under the terms of the MIT
* license found at http://github.com/kriskowal/q/raw/master/LICENSE
*
* With parts by Tyler Close
* Copyright 2007-2009 Tyler Close under the terms of the MIT X license found
* at http://www.opensource.org/licenses/mit-license.html
* Forked at ref_send.js version: 2009-05-11
*
* With parts by Mark Miller
* Copyright (C) 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
(function (definition) {
"use strict";
// This file will function properly as a <script> tag, or a module
// using CommonJS and NodeJS or RequireJS module formats. In
// Common/Node/RequireJS, the module exports the Q API and when
// executed as a simple <script>, it creates a Q global instead.
// Montage Require
if (typeof bootstrap === "function") {
bootstrap("promise", definition);
// CommonJS
} else if (typeof exports === "object" && typeof module === "object") {
module.exports = definition();
// RequireJS
} else if (typeof define === "function" && define.amd) {
define(definition);
// SES (Secure EcmaScript)
} else if (typeof ses !== "undefined") {
if (!ses.ok()) {
return;
} else {
ses.makeQ = definition;
}
// <script>
} else if (typeof window !== "undefined" || typeof self !== "undefined") {
// Prefer window over self for add-on scripts. Use self for
// non-windowed contexts.
var global = typeof window !== "undefined" ? window : self;
// Get the `window` object, save the previous Q global
// and initialize Q as a global.
var previousQ = global.Q;
global.Q = definition();
// Add a noConflict function so Q can be removed from the
// global namespace.
global.Q.noConflict = function () {
global.Q = previousQ;
return this;
};
} else {
throw new Error("This environment was not anticipated by Q. Please file a bug.");
}
})(function () {
"use strict";
var hasStacks = false;
try {
throw new Error();
} catch (e) {
hasStacks = !!e.stack;
}
// All code after this point will be filtered from stack traces reported
// by Q.
var qStartingLine = captureLine();
var qFileName;
// shims
// used for fallback in "allResolved"
var noop = function () {};
// Use the fastest possible means to execute a task in a future turn
// of the event loop.
var nextTick =(function () {
// linked list of tasks (single, with head node)
var head = {task: void 0, next: null};
var tail = head;
var flushing = false;
var requestTick = void 0;
var isNodeJS = false;
// queue for late tasks, used by unhandled rejection tracking
var laterQueue = [];
function flush() {
/* jshint loopfunc: true */
var task, domain;
while (head.next) {
head = head.next;
task = head.task;
head.task = void 0;
domain = head.domain;
if (domain) {
head.domain = void 0;
domain.enter();
}
runSingle(task, domain);
}
while (laterQueue.length) {
task = laterQueue.pop();
runSingle(task);
}
flushing = false;
}
// runs a single function in the async queue
function runSingle(task, domain) {
try {
task();
} catch (e) {
if (isNodeJS) {
// In node, uncaught exceptions are considered fatal errors.
// Re-throw them synchronously to interrupt flushing!
// Ensure continuation if the uncaught exception is suppressed
// listening "uncaughtException" events (as domains does).
// Continue in next event to avoid tick recursion.
if (domain) {
domain.exit();
}
setTimeout(flush, 0);
if (domain) {
domain.enter();
}
throw e;
} else {
// In browsers, uncaught exceptions are not fatal.
// Re-throw them asynchronously to avoid slow-downs.
setTimeout(function () {
throw e;
}, 0);
}
}
if (domain) {
domain.exit();
}
}
nextTick = function (task) {
tail = tail.next = {
task: task,
domain: isNodeJS && process.domain,
next: null
};
if (!flushing) {
flushing = true;
requestTick();
}
};
if (typeof process === "object" &&
process.toString() === "[object process]" && process.nextTick) {
// Ensure Q is in a real Node environment, with a `process.nextTick`.
// To see through fake Node environments:
// * Mocha test runner - exposes a `process` global without a `nextTick`
// * Browserify - exposes a `process.nexTick` function that uses
// `setTimeout`. In this case `setImmediate` is preferred because
// it is faster. Browserify's `process.toString()` yields
// "[object Object]", while in a real Node environment
// `process.nextTick()` yields "[object process]".
isNodeJS = true;
requestTick = function () {
process.nextTick(flush);
};
} else if (typeof setImmediate === "function") {
// In IE10, Node.js 0.9+, or https://github.com/NobleJS/setImmediate
if (typeof window !== "undefined") {
requestTick = setImmediate.bind(window, flush);
} else {
requestTick = function () {
setImmediate(flush);
};
}
} else if (typeof MessageChannel !== "undefined") {
// modern browsers
// http://www.nonblocking.io/2011/06/windownexttick.html
var channel = new MessageChannel();
// At least Safari Version 6.0.5 (8536.30.1) intermittently cannot create
// working message ports the first time a page loads.
channel.port1.onmessage = function () {
requestTick = requestPortTick;
channel.port1.onmessage = flush;
flush();
};
var requestPortTick = function () {
// Opera requires us to provide a message payload, regardless of
// whether we use it.
channel.port2.postMessage(0);
};
requestTick = function () {
setTimeout(flush, 0);
requestPortTick();
};
} else {
// old browsers
requestTick = function () {
setTimeout(flush, 0);
};
}
// runs a task after all other tasks have been run
// this is useful for unhandled rejection tracking that needs to happen
// after all `then`d tasks have been run.
nextTick.runAfter = function (task) {
laterQueue.push(task);
if (!flushing) {
flushing = true;
requestTick();
}
};
return nextTick;
})();
// Attempt to make generics safe in the face of downstream
// modifications.
// There is no situation where this is necessary.
// If you need a security guarantee, these primordials need to be
// deeply frozen anyway, and if you don’t need a security guarantee,
// this is just plain paranoid.
// However, this **might** have the nice side-effect of reducing the size of
// the minified code by reducing x.call() to merely x()
// See Mark Miller’s explanation of what this does.
// http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming
var call = Function.call;
function uncurryThis(f) {
return function () {
return call.apply(f, arguments);
};
}
// This is equivalent, but slower:
// uncurryThis = Function_bind.bind(Function_bind.call);
// http://jsperf.com/uncurrythis
var array_slice = uncurryThis(Array.prototype.slice);
var array_reduce = uncurryThis(
Array.prototype.reduce || function (callback, basis) {
var index = 0,
length = this.length;
// concerning the initial value, if one is not provided
if (arguments.length === 1) {
// seek to the first value in the array, accounting
// for the possibility that is is a sparse array
do {
if (index in this) {
basis = this[index++];
break;
}
if (++index >= length) {
throw new TypeError();
}
} while (1);
}
// reduce
for (; index < length; index++) {
// account for the possibility that the array is sparse
if (index in this) {
basis = callback(basis, this[index], index);
}
}
return basis;
}
);
var array_indexOf = uncurryThis(
Array.prototype.indexOf || function (value) {
// not a very good shim, but good enough for our one use of it
for (var i = 0; i < this.length; i++) {
if (this[i] === value) {
return i;
}
}
return -1;
}
);
var array_map = uncurryThis(
Array.prototype.map || function (callback, thisp) {
var self = this;
var collect = [];
array_reduce(self, function (undefined, value, index) {
collect.push(callback.call(thisp, value, index, self));
}, void 0);
return collect;
}
);
var object_create = Object.create || function (prototype) {
function Type() { }
Type.prototype = prototype;
return new Type();
};
var object_hasOwnProperty = uncurryThis(Object.prototype.hasOwnProperty);
var object_keys = Object.keys || function (object) {
var keys = [];
for (var key in object) {
if (object_hasOwnProperty(object, key)) {
keys.push(key);
}
}
return keys;
};
var object_toString = uncurryThis(Object.prototype.toString);
function isObject(value) {
return value === Object(value);
}
// generator related shims
// FIXME: Remove this function once ES6 generators are in SpiderMonkey.
function isStopIteration(exception) {
return (
object_toString(exception) === "[object StopIteration]" ||
exception instanceof QReturnValue
);
}
// FIXME: Remove this helper and Q.return once ES6 generators are in
// SpiderMonkey.
var QReturnValue;
if (typeof ReturnValue !== "undefined") {
QReturnValue = ReturnValue;
} else {
QReturnValue = function (value) {
this.value = value;
};
}
// long stack traces
var STACK_JUMP_SEPARATOR = "From previous event:";
function makeStackTraceLong(error, promise) {
// If possible, transform the error stack trace by removing Node and Q
// cruft, then concatenating with the stack trace of `promise`. See #57.
if (hasStacks &&
promise.stack &&
typeof error === "object" &&
error !== null &&
error.stack &&
error.stack.indexOf(STACK_JUMP_SEPARATOR) === -1
) {
var stacks = [];
for (var p = promise; !!p; p = p.source) {
if (p.stack) {
stacks.unshift(p.stack);
}
}
stacks.unshift(error.stack);
var concatedStacks = stacks.join("\n" + STACK_JUMP_SEPARATOR + "\n");
error.stack = filterStackString(concatedStacks);
}
}
function filterStackString(stackString) {
var lines = stackString.split("\n");
var desiredLines = [];
for (var i = 0; i < lines.length; ++i) {
var line = lines[i];
if (!isInternalFrame(line) && !isNodeFrame(line) && line) {
desiredLines.push(line);
}
}
return desiredLines.join("\n");
}
function isNodeFrame(stackLine) {
return stackLine.indexOf("(module.js:") !== -1 ||
stackLine.indexOf("(node.js:") !== -1;
}
function getFileNameAndLineNumber(stackLine) {
// Named functions: "at functionName (filename:lineNumber:columnNumber)"
// In IE10 function name can have spaces ("Anonymous function") O_o
var attempt1 = /at .+ \((.+):(\d+):(?:\d+)\)$/.exec(stackLine);
if (attempt1) {
return [attempt1[1], Number(attempt1[2])];
}
// Anonymous functions: "at filename:lineNumber:columnNumber"
var attempt2 = /at ([^ ]+):(\d+):(?:\d+)$/.exec(stackLine);
if (attempt2) {
return [attempt2[1], Number(attempt2[2])];
}
// Firefox style: "function@filename:lineNumber or @filename:lineNumber"
var attempt3 = /.*@(.+):(\d+)$/.exec(stackLine);
if (attempt3) {
return [attempt3[1], Number(attempt3[2])];
}
}
function isInternalFrame(stackLine) {
var fileNameAndLineNumber = getFileNameAndLineNumber(stackLine);
if (!fileNameAndLineNumber) {
return false;
}
var fileName = fileNameAndLineNumber[0];
var lineNumber = fileNameAndLineNumber[1];
return fileName === qFileName &&
lineNumber >= qStartingLine &&
lineNumber <= qEndingLine;
}
// discover own file name and line number range for filtering stack
// traces
function captureLine() {
if (!hasStacks) {
return;
}
try {
throw new Error();
} catch (e) {
var lines = e.stack.split("\n");
var firstLine = lines[0].indexOf("@") > 0 ? lines[1] : lines[2];
var fileNameAndLineNumber = getFileNameAndLineNumber(firstLine);
if (!fileNameAndLineNumber) {
return;
}
qFileName = fileNameAndLineNumber[0];
return fileNameAndLineNumber[1];
}
}
function deprecate(callback, name, alternative) {
return function () {
if (typeof console !== "undefined" &&
typeof console.warn === "function") {
console.warn(name + " is deprecated, use " + alternative +
" instead.", new Error("").stack);
}
return callback.apply(callback, arguments);
};
}
// end of shims
// beginning of real work
/**
* Constructs a promise for an immediate reference, passes promises through, or
* coerces promises from different systems.
* @param value immediate reference or promise
*/
function Q(value) {
// If the object is already a Promise, return it directly. This enables
// the resolve function to both be used to created references from objects,
// but to tolerably coerce non-promises to promises.
if (value instanceof Promise) {
return value;
}
// assimilate thenables
if (isPromiseAlike(value)) {
return coerce(value);
} else {
return fulfill(value);
}
}
Q.resolve = Q;
/**
* Performs a task in a future turn of the event loop.
* @param {Function} task
*/
Q.nextTick = nextTick;
/**
* Controls whether or not long stack traces will be on
*/
Q.longStackSupport = false;
// enable long stacks if Q_DEBUG is set
if (typeof process === "object" && process && process.env && process.env.Q_DEBUG) {
Q.longStackSupport = true;
}
/**
* Constructs a {promise, resolve, reject} object.
*
* `resolve` is a callback to invoke with a more resolved value for the
* promise. To fulfill the promise, invoke `resolve` with any value that is
* not a thenable. To reject the promise, invoke `resolve` with a rejected
* thenable, or invoke `reject` with the reason directly. To resolve the
* promise to another thenable, thus putting it in the same state, invoke
* `resolve` with that other thenable.
*/
Q.defer = defer;
function defer() {
// if "messages" is an "Array", that indicates that the promise has not yet
// been resolved. If it is "undefined", it has been resolved. Each
// element of the messages array is itself an array of complete arguments to
// forward to the resolved promise. We coerce the resolution value to a
// promise using the `resolve` function because it handles both fully
// non-thenable values and other thenables gracefully.
var messages = [], progressListeners = [], resolvedPromise;
var deferred = object_create(defer.prototype);
var promise = object_create(Promise.prototype);
promise.promiseDispatch = function (resolve, op, operands) {
var args = array_slice(arguments);
if (messages) {
messages.push(args);
if (op === "when" && operands[1]) { // progress operand
progressListeners.push(operands[1]);
}
} else {
Q.nextTick(function () {
resolvedPromise.promiseDispatch.apply(resolvedPromise, args);
});
}
};
// XXX deprecated
promise.valueOf = function () {
if (messages) {
return promise;
}
var nearerValue = nearer(resolvedPromise);
if (isPromise(nearerValue)) {
resolvedPromise = nearerValue; // shorten chain
}
return nearerValue;
};
promise.inspect = function () {
if (!resolvedPromise) {
return { state: "pending" };
}
return resolvedPromise.inspect();
};
if (Q.longStackSupport && hasStacks) {
try {
throw new Error();
} catch (e) {
// NOTE: don't try to use `Error.captureStackTrace` or transfer the
// accessor around; that causes memory leaks as per GH-111. Just
// reify the stack trace as a string ASAP.
//
// At the same time, cut off the first line; it's always just
// "[object Promise]\n", as per the `toString`.
promise.stack = e.stack.substring(e.stack.indexOf("\n") + 1);
}
}
// NOTE: we do the checks for `resolvedPromise` in each method, instead of
// consolidating them into `become`, since otherwise we'd create new
// promises with the lines `become(whatever(value))`. See e.g. GH-252.
function become(newPromise) {
resolvedPromise = newPromise;
promise.source = newPromise;
array_reduce(messages, function (undefined, message) {
Q.nextTick(function () {
newPromise.promiseDispatch.apply(newPromise, message);
});
}, void 0);
messages = void 0;
progressListeners = void 0;
}
deferred.promise = promise;
deferred.resolve = function (value) {
if (resolvedPromise) {
return;
}
become(Q(value));
};
deferred.fulfill = function (value) {
if (resolvedPromise) {
return;
}
become(fulfill(value));
};
deferred.reject = function (reason) {
if (resolvedPromise) {
return;
}
become(reject(reason));
};
deferred.notify = function (progress) {
if (resolvedPromise) {
return;
}
array_reduce(progressListeners, function (undefined, progressListener) {
Q.nextTick(function () {
progressListener(progress);
});
}, void 0);
};
return deferred;
}
/**
* Creates a Node-style callback that will resolve or reject the deferred
* promise.
* @returns a nodeback
*/
defer.prototype.makeNodeResolver = function () {
var self = this;
return function (error, value) {
if (error) {
self.reject(error);
} else if (arguments.length > 2) {
self.resolve(array_slice(arguments, 1));
} else {
self.resolve(value);
}
};
};
/**
* @param resolver {Function} a function that returns nothing and accepts
* the resolve, reject, and notify functions for a deferred.
* @returns a promise that may be resolved with the given resolve and reject
* functions, or rejected by a thrown exception in resolver
*/
Q.Promise = promise; // ES6
Q.promise = promise;
function promise(resolver) {
if (typeof resolver !== "function") {
throw new TypeError("resolver must be a function.");
}
var deferred = defer();
try {
resolver(deferred.resolve, deferred.reject, deferred.notify);
} catch (reason) {
deferred.reject(reason);
}
return deferred.promise;
}
promise.race = race; // ES6
promise.all = all; // ES6
promise.reject = reject; // ES6
promise.resolve = Q; // ES6
// XXX experimental. This method is a way to denote that a local value is
// serializable and should be immediately dispatched to a remote upon request,
// instead of passing a reference.
Q.passByCopy = function (object) {
//freeze(object);
//passByCopies.set(object, true);
return object;
};
Promise.prototype.passByCopy = function () {
//freeze(object);
//passByCopies.set(object, true);
return this;
};
/**
* If two promises eventually fulfill to the same value, promises that value,
* but otherwise rejects.
* @param x {Any*}
* @param y {Any*}
* @returns {Any*} a promise for x and y if they are the same, but a rejection
* otherwise.
*
*/
Q.join = function (x, y) {
return Q(x).join(y);
};
Promise.prototype.join = function (that) {
return Q([this, that]).spread(function (x, y) {
if (x === y) {
// TODO: "===" should be Object.is or equiv
return x;
} else {
throw new Error("Can't join: not the same: " + x + " " + y);
}
});
};
/**
* Returns a promise for the first of an array of promises to become settled.
* @param answers {Array[Any*]} promises to race
* @returns {Any*} the first promise to be settled
*/
Q.race = race;
function race(answerPs) {
return promise(function (resolve, reject) {
// Switch to this once we can assume at least ES5
// answerPs.forEach(function (answerP) {
// Q(answerP).then(resolve, reject);
// });
// Use this in the meantime
for (var i = 0, len = answerPs.length; i < len; i++) {
Q(answerPs[i]).then(resolve, reject);
}
});
}
Promise.prototype.race = function () {
return this.then(Q.race);
};
/**
* Constructs a Promise with a promise descriptor object and optional fallback
* function. The descriptor contains methods like when(rejected), get(name),
* set(name, value), post(name, args), and delete(name), which all
* return either a value, a promise for a value, or a rejection. The fallback
* accepts the operation name, a resolver, and any further arguments that would
* have been forwarded to the appropriate method above had a method been
* provided with the proper name. The API makes no guarantees about the nature
* of the returned object, apart from that it is usable whereever promises are
* bought and sold.
*/
Q.makePromise = Promise;
function Promise(descriptor, fallback, inspect) {
if (fallback === void 0) {
fallback = function (op) {
return reject(new Error(
"Promise does not support operation: " + op
));
};
}
if (inspect === void 0) {
inspect = function () {
return {state: "unknown"};
};
}
var promise = object_create(Promise.prototype);
promise.promiseDispatch = function (resolve, op, args) {
var result;
try {
if (descriptor[op]) {
result = descriptor[op].apply(promise, args);
} else {
result = fallback.call(promise, op, args);
}
} catch (exception) {
result = reject(exception);
}
if (resolve) {
resolve(result);
}
};
promise.inspect = inspect;
// XXX deprecated `valueOf` and `exception` support
if (inspect) {
var inspected = inspect();
if (inspected.state === "rejected") {
promise.exception = inspected.reason;
}
promise.valueOf = function () {
var inspected = inspect();
if (inspected.state === "pending" ||
inspected.state === "rejected") {
return promise;
}
return inspected.value;
};
}
return promise;
}
Promise.prototype.toString = function () {
return "[object Promise]";
};
Promise.prototype.then = function (fulfilled, rejected, progressed) {
var self = this;
var deferred = defer();
var done = false; // ensure the untrusted promise makes at most a
// single call to one of the callbacks
function _fulfilled(value) {
try {
return typeof fulfilled === "function" ? fulfilled(value) : value;
} catch (exception) {
return reject(exception);
}
}
function _rejected(exception) {
if (typeof rejected === "function") {
makeStackTraceLong(exception, self);
try {
return rejected(exception);
} catch (newException) {
return reject(newException);
}
}
return reject(exception);
}
function _progressed(value) {
return typeof progressed === "function" ? progressed(value) : value;
}
Q.nextTick(function () {
self.promiseDispatch(function (value) {
if (done) {
return;
}
done = true;
deferred.resolve(_fulfilled(value));
}, "when", [function (exception) {
if (done) {
return;
}
done = true;
deferred.resolve(_rejected(exception));
}]);
});
// Progress propagator need to be attached in the current tick.
self.promiseDispatch(void 0, "when", [void 0, function (value) {
var newValue;
var threw = false;
try {
newValue = _progressed(value);
} catch (e) {
threw = true;
if (Q.onerror) {
Q.onerror(e);
} else {
throw e;
}
}
if (!threw) {
deferred.notify(newValue);
}
}]);
return deferred.promise;
};
Q.tap = function (promise, callback) {
return Q(promise).tap(callback);
};
/**
* Works almost like "finally", but not called for rejections.
* Original resolution value is passed through callback unaffected.
* Callback may return a promise that will be awaited for.
* @param {Function} callback
* @returns {Q.Promise}
* @example
* doSomething()
* .then(...)
* .tap(console.log)
* .then(...);
*/
Promise.prototype.tap = function (callback) {
callback = Q(callback);
return this.then(function (value) {
return callback.fcall(value).thenResolve(value);
});
};
/**
* Registers an observer on a promise.
*
* Guarantees:
*
* 1. that fulfilled and rejected will be called only once.
* 2. that either the fulfilled callback or the rejected callback will be
* called, but not both.
* 3. that fulfilled and rejected will not be called in this turn.
*
* @param value promise or immediate reference to observe
* @param fulfilled function to be called with the fulfilled value
* @param rejected function to be called with the rejection exception
* @param progressed function to be called on any progress notifications
* @return promise for the return value from the invoked callback
*/
Q.when = when;
function when(value, fulfilled, rejected, progressed) {
return Q(value).then(fulfilled, rejected, progressed);
}
Promise.prototype.thenResolve = function (value) {
return this.then(function () { return value; });
};
Q.thenResolve = function (promise, value) {
return Q(promise).thenResolve(value);
};
Promise.prototype.thenReject = function (reason) {
return this.then(function () { throw reason; });
};
Q.thenReject = function (promise, reason) {
return Q(promise).thenReject(reason);
};
/**
* If an object is not a promise, it is as "near" as possible.
* If a promise is rejected, it is as "near" as possible too.
* If it’s a fulfilled promise, the fulfillment value is nearer.
* If it’s a deferred promise and the deferred has been resolved, the
* resolution is "nearer".
* @param object
* @returns most resolved (nearest) form of the object
*/
// XXX should we re-do this?
Q.nearer = nearer;
function nearer(value) {
if (isPromise(value)) {
var inspected = value.inspect();
if (inspected.state === "fulfilled") {
return inspected.value;
}
}
return value;
}
/**
* @returns whether the given object is a promise.
* Otherwise it is a fulfilled value.
*/
Q.isPromise = isPromise;
function isPromise(object) {
return object instanceof Promise;
}
Q.isPromiseAlike = isPromiseAlike;
function isPromiseAlike(object) {
return isObject(object) && typeof object.then === "function";
}
/**
* @returns whether the given object is a pending promise, meaning not
* fulfilled or rejected.
*/
Q.isPending = isPending;
function isPending(object) {
return isPromise(object) && object.inspect().state === "pending";
}
Promise.prototype.isPending = function () {
return this.inspect().state === "pending";
};
/**
* @returns whether the given object is a value or fulfilled
* promise.
*/
Q.isFulfilled = isFulfilled;
function isFulfilled(object) {
return !isPromise(object) || object.inspect().state === "fulfilled";
}
Promise.prototype.isFulfilled = function () {
return this.inspect().state === "fulfilled";
};
/**
* @returns whether the given object is a rejected promise.
*/
Q.isRejected = isRejected;
function isRejected(object) {
return isPromise(object) && object.inspect().state === "rejected";
}
Promise.prototype.isRejected = function () {
return this.inspect().state === "rejected";
};
//// BEGIN UNHANDLED REJECTION TRACKING
// This promise library consumes exceptions thrown in handlers so they can be
// handled by a subsequent promise. The exceptions get added to this array when
// they are created, and removed when they are handled. Note that in ES6 or
// shimmed environments, this would naturally be a `Set`.
var unhandledReasons = [];
var unhandledRejections = [];
var reportedUnhandledRejections = [];
var trackUnhandledRejections = true;
function resetUnhandledRejections() {
unhandledReasons.length = 0;
unhandledRejections.length = 0;
if (!trackUnhandledRejections) {
trackUnhandledRejections = true;
}
}
function trackRejection(promise, reason) {
if (!trackUnhandledRejections) {
return;
}
if (typeof process === "object" && typeof process.emit === "function") {
Q.nextTick.runAfter(function () {
if (array_indexOf(unhandledRejections, promise) !== -1) {
process.emit("unhandledRejection", reason, promise);
reportedUnhandledRejections.push(promise);
}
});
}
unhandledRejections.push(promise);
if (reason && typeof reason.stack !== "undefined") {
unhandledReasons.push(reason.stack);
} else {
unhandledReasons.push("(no stack) " + reason);
}
}
function untrackRejection(promise) {
if (!trackUnhandledRejections) {
return;
}
var at = array_indexOf(unhandledRejections, promise);
if (at !== -1) {
if (typeof process === "object" && typeof process.emit === "function") {
Q.nextTick.runAfter(function () {
var atReport = array_indexOf(reportedUnhandledRejections, promise);
if (atReport !== -1) {
process.emit("rejectionHandled", unhandledReasons[at], promise);
reportedUnhandledRejections.splice(atReport, 1);
}
});
}
unhandledRejections.splice(at, 1);
unhandledReasons.splice(at, 1);
}
}
Q.resetUnhandledRejections = resetUnhandledRejections;
Q.getUnhandledReasons = function () {
// Make a copy so that consumers can't interfere with our internal state.
return unhandledReasons.slice();
};
Q.stopUnhandledRejectionTracking = function () {
resetUnhandledRejections();
trackUnhandledRejections = false;
};
resetUnhandledRejections();
//// END UNHANDLED REJECTION TRACKING
/**
* Constructs a rejected promise.
* @param reason value describing the failure
*/
Q.reject = reject;
function reject(reason) {
var rejection = Promise({
"when": function (rejected) {
// note that the error has been handled
if (rejected) {
untrackRejection(this);
}
return rejected ? rejected(reason) : this;
}
}, function fallback() {
return this;
}, function inspect() {
return { state: "rejected", reason: reason };
});
// Note that the reason has not been handled.
trackRejection(rejection, reason);
return rejection;
}
/**
* Constructs a fulfilled promise for an immediate reference.
* @param value immediate reference
*/
Q.fulfill = fulfill;
function fulfill(value) {
return Promise({
"when": function () {
return value;
},
"get": function (name) {
return value[name];
},
"set": function (name, rhs) {
value[name] = rhs;
},
"delete": function (name) {
delete value[name];
},
"post": function (name, args) {
// Mark Miller proposes that post with no name should apply a
// promised function.
if (name === null || name === void 0) {
return value.apply(void 0, args);
} else {
return value[name].apply(value, args);
}
},
"apply": function (thisp, args) {
return value.apply(thisp, args);
},
"keys": function () {
return object_keys(value);
}
}, void 0, function inspect() {
return { state: "fulfilled", value: value };
});
}
/**
* Converts thenables to Q promises.
* @param promise thenable promise
* @returns a Q promise
*/
function coerce(promise) {
var deferred = defer();
Q.nextTick(function () {
try {
promise.then(deferred.resolve, deferred.reject, deferred.notify);
} catch (exception) {
deferred.reject(exception);
}
});
return deferred.promise;
}
/**
* Annotates an object such that it will never be
* transferred away from this process over any promise
* communication channel.
* @param object
* @returns promise a wrapping of that object that
* additionally responds to the "isDef" message
* without a rejection.
*/
Q.master = master;
function master(object) {
return Promise({
"isDef": function () {}
}, function fallback(op, args) {
return dispatch(object, op, args);
}, function () {
return Q(object).inspect();
});
}
/**
* Spreads the values of a promised array of arguments into the
* fulfillment callback.
* @param fulfilled callback that receives variadic arguments from the
* promised array
* @param rejected callback that receives the exception if the promise
* is rejected.
* @returns a promise for the return value or thrown exception of
* either callback.
*/
Q.spread = spread;
function spread(value, fulfilled, rejected) {
return Q(value).spread(fulfilled, rejected);
}
Promise.prototype.spread = function (fulfilled, rejected) {
return this.all().then(function (array) {
return fulfilled.apply(void 0, array);
}, rejected);
};
/**
* The async function is a decorator for generator functions, turning
* them into asynchronous generators. Although generators are only part
* of the newest ECMAScript 6 drafts, this code does not cause syntax
* errors in older engines. This code should continue to work and will
* in fact improve over time as the language improves.
*
* ES6 generators are currently part of V8 version 3.19 with the
* --harmony-generators runtime flag enabled. SpiderMonkey has had them
* for longer, but under an older Python-inspired form. This function
* works on both kinds of generators.
*
* Decorates a generator function such that:
* - it may yield promises
* - execution will continue when that promise is fulfilled
* - the value of the yield expression will be the fulfilled value
* - it returns a promise for the return value (when the generator
* stops iterating)
* - the decorated function returns a promise for the return value
* of the generator or the first rejected promise among those
* yielded.
* - if an error is thrown in the generator, it propagates through
* every following yield until it is caught, or until it escapes
* the generator function altogether, and is translated into a
* rejection for the promise returned by the decorated generator.
*/
Q.async = async;
function async(makeGenerator) {
return function () {
// when verb is "send", arg is a value
// when verb is "throw", arg is an exception
function continuer(verb, arg) {
var result;
// Until V8 3.19 / Chromium 29 is released, SpiderMonkey is the only
// engine that has a deployed base of browsers that support generators.
// However, SM's generators use the Python-inspired semantics of
// outdated ES6 drafts. We would like to support ES6, but we'd also
// like to make it possible to use generators in deployed browsers, so
// we also support Python-style generators. At some point we can remove
// this block.
if (typeof StopIteration === "undefined") {
// ES6 Generators
try {
result = generator[verb](arg);
} catch (exception) {
return reject(exception);
}
if (result.done) {
return Q(result.value);
} else {
return when(result.value, callback, errback);
}
} else {
// SpiderMonkey Generators
// FIXME: Remove this case when SM does ES6 generators.
try {
result = generator[verb](arg);
} catch (exception) {
if (isStopIteration(exception)) {
return Q(exception.value);
} else {
return reject(exception);
}
}
return when(result, callback, errback);
}
}
var generator = makeGenerator.apply(this, arguments);
var callback = continuer.bind(continuer, "next");
var errback = continuer.bind(continuer, "throw");
return callback();
};
}
/**
* The spawn function is a small wrapper around async that immediately
* calls the generator and also ends the promise chain, so that any
* unhandled errors are thrown instead of forwarded to the error
* handler. This is useful because it's extremely common to run
* generators at the top-level to work with libraries.
*/
Q.spawn = spawn;
function spawn(makeGenerator) {
Q.done(Q.async(makeGenerator)());
}
// FIXME: Remove this interface once ES6 generators are in SpiderMonkey.
/**
* Throws a ReturnValue exception to stop an asynchronous generator.
*
* This interface is a stop-gap measure to support generator return
* values in older Firefox/SpiderMonkey. In browsers that support ES6
* generators like Chromium 29, just use "return" in your generator
* functions.
*
* @param value the return value for the surrounding generator
* @throws ReturnValue exception with the value.
* @example
* // ES6 style
* Q.async(function* () {
* var foo = yield getFooPromise();
* var bar = yield getBarPromise();
* return foo + bar;
* })
* // Older SpiderMonkey style
* Q.async(function () {
* var foo = yield getFooPromise();
* var bar = yield getBarPromise();
* Q.return(foo + bar);
* })
*/
Q["return"] = _return;
function _return(value) {
throw new QReturnValue(value);
}
/**
* The promised function decorator ensures that any promise arguments
* are settled and passed as values (`this` is also settled and passed
* as a value). It will also ensure that the result of a function is
* always a promise.
*
* @example
* var add = Q.promised(function (a, b) {
* return a + b;
* });
* add(Q(a), Q(B));
*
* @param {function} callback The function to decorate
* @returns {function} a function that has been decorated.
*/
Q.promised = promised;
function promised(callback) {
return function () {
return spread([this, all(arguments)], function (self, args) {
return callback.apply(self, args);
});
};
}
/**
* sends a message to a value in a future turn
* @param object* the recipient
* @param op the name of the message operation, e.g., "when",
* @param args further arguments to be forwarded to the operation
* @returns result {Promise} a promise for the result of the operation
*/
Q.dispatch = dispatch;
function dispatch(object, op, args) {
return Q(object).dispatch(op, args);
}
Promise.prototype.dispatch = function (op, args) {
var self = this;
var deferred = defer();
Q.nextTick(function () {
self.promiseDispatch(deferred.resolve, op, args);
});
return deferred.promise;
};
/**
* Gets the value of a property in a future turn.
* @param object promise or immediate reference for target object
* @param name name of property to get
* @return promise for the property value
*/
Q.get = function (object, key) {
return Q(object).dispatch("get", [key]);
};
Promise.prototype.get = function (key) {
return this.dispatch("get", [key]);
};
/**
* Sets the value of a property in a future turn.
* @param object promise or immediate reference for object object
* @param name name of property to set
* @param value new value of property
* @return promise for the return value
*/
Q.set = function (object, key, value) {
return Q(object).dispatch("set", [key, value]);
};
Promise.prototype.set = function (key, value) {
return this.dispatch("set", [key, value]);
};
/**
* Deletes a property in a future turn.
* @param object promise or immediate reference for target object
* @param name name of property to delete
* @return promise for the return value
*/
Q.del = // XXX legacy
Q["delete"] = function (object, key) {
return Q(object).dispatch("delete", [key]);
};
Promise.prototype.del = // XXX legacy
Promise.prototype["delete"] = function (key) {
return this.dispatch("delete", [key]);
};
/**
* Invokes a method in a future turn.
* @param object promise or immediate reference for target object
* @param name name of method to invoke
* @param value a value to post, typically an array of
* invocation arguments for promises that
* are ultimately backed with `resolve` values,
* as opposed to those backed with URLs
* wherein the posted value can be any
* JSON serializable object.
* @return promise for the return value
*/
// bound locally because it is used by other methods
Q.mapply = // XXX As proposed by "Redsandro"
Q.post = function (object, name, args) {
return Q(object).dispatch("post", [name, args]);
};
Promise.prototype.mapply = // XXX As proposed by "Redsandro"
Promise.prototype.post = function (name, args) {
return this.dispatch("post", [name, args]);
};
/**
* Invokes a method in a future turn.
* @param object promise or immediate reference for target object
* @param name name of method to invoke
* @param ...args array of invocation arguments
* @return promise for the return value
*/
Q.send = // XXX Mark Miller's proposed parlance
Q.mcall = // XXX As proposed by "Redsandro"
Q.invoke = function (object, name /*...args*/) {
return Q(object).dispatch("post", [name, array_slice(arguments, 2)]);
};
Promise.prototype.send = // XXX Mark Miller's proposed parlance
Promise.prototype.mcall = // XXX As proposed by "Redsandro"
Promise.prototype.invoke = function (name /*...args*/) {
return this.dispatch("post", [name, array_slice(arguments, 1)]);
};
/**
* Applies the promised function in a future turn.
* @param object promise or immediate reference for target function
* @param args array of application arguments
*/
Q.fapply = function (object, args) {
return Q(object).dispatch("apply", [void 0, args]);
};
Promise.prototype.fapply = function (args) {
return this.dispatch("apply", [void 0, args]);
};
/**
* Calls the promised function in a future turn.
* @param object promise or immediate reference for target function
* @param ...args array of application arguments
*/
Q["try"] =
Q.fcall = function (object /* ...args*/) {
return Q(object).dispatch("apply", [void 0, array_slice(arguments, 1)]);
};
Promise.prototype.fcall = function (/*...args*/) {
return this.dispatch("apply", [void 0, array_slice(arguments)]);
};
/**
* Binds the promised function, transforming return values into a fulfilled
* promise and thrown errors into a rejected one.
* @param object promise or immediate reference for target function
* @param ...args array of application arguments
*/
Q.fbind = function (object /*...args*/) {
var promise = Q(object);
var args = array_slice(arguments, 1);
return function fbound() {
return promise.dispatch("apply", [
this,
args.concat(array_slice(arguments))
]);
};
};
Promise.prototype.fbind = function (/*...args*/) {
var promise = this;
var args = array_slice(arguments);
return function fbound() {
return promise.dispatch("apply", [
this,
args.concat(array_slice(arguments))
]);
};
};
/**
* Requests the names of the owned properties of a promised
* object in a future turn.
* @param object promise or immediate reference for target object
* @return promise for the keys of the eventually settled object
*/
Q.keys = function (object) {
return Q(object).dispatch("keys", []);
};
Promise.prototype.keys = function () {
return this.dispatch("keys", []);
};
/**
* Turns an array of promises into a promise for an array. If any of
* the promises gets rejected, the whole array is rejected immediately.
* @param {Array*} an array (or promise for an array) of values (or
* promises for values)
* @returns a promise for an array of the corresponding values
*/
// By Mark Miller
// http://wiki.ecmascript.org/doku.php?id=strawman:concurrency&rev=1308776521#allfulfilled
Q.all = all;
function all(promises) {
return when(promises, function (promises) {
var pendingCount = 0;
var deferred = defer();
array_reduce(promises, function (undefined, promise, index) {
var snapshot;
if (
isPromise(promise) &&
(snapshot = promise.inspect()).state === "fulfilled"
) {
promises[index] = snapshot.value;
} else {
++pendingCount;
when(
promise,
function (value) {
promises[index] = value;
if (--pendingCount === 0) {
deferred.resolve(promises);
}
},
deferred.reject,
function (progress) {
deferred.notify({ index: index, value: progress });
}
);
}
}, void 0);
if (pendingCount === 0) {
deferred.resolve(promises);
}
return deferred.promise;
});
}
Promise.prototype.all = function () {
return all(this);
};
/**
* Returns the first resolved promise of an array. Prior rejected promises are
* ignored. Rejects only if all promises are rejected.
* @param {Array*} an array containing values or promises for values
* @returns a promise fulfilled with the value of the first resolved promise,
* or a rejected promise if all promises are rejected.
*/
Q.any = any;
function any(promises) {
if (promises.length === 0) {
return Q.resolve();
}
var deferred = Q.defer();
var pendingCount = 0;
array_reduce(promises, function (prev, current, index) {
var promise = promises[index];
pendingCount++;
when(promise, onFulfilled, onRejected, onProgress);
function onFulfilled(result) {
deferred.resolve(result);
}
function onRejected() {
pendingCount--;
if (pendingCount === 0) {
deferred.reject(new Error(
"Can't get fulfillment value from any promise, all " +
"promises were rejected."
));
}
}
function onProgress(progress) {
deferred.notify({
index: index,
value: progress
});
}
}, undefined);
return deferred.promise;
}
Promise.prototype.any = function () {
return any(this);
};
/**
* Waits for all promises to be settled, either fulfilled or
* rejected. This is distinct from `all` since that would stop
* waiting at the first rejection. The promise returned by
* `allResolved` will never be rejected.
* @param promises a promise for an array (or an array) of promises
* (or values)
* @return a promise for an array of promises
*/
Q.allResolved = deprecate(allResolved, "allResolved", "allSettled");
function allResolved(promises) {
return when(promises, function (promises) {
promises = array_map(promises, Q);
return when(all(array_map(promises, function (promise) {
return when(promise, noop, noop);
})), function () {
return promises;
});
});
}
Promise.prototype.allResolved = function () {
return allResolved(this);
};
/**
* @see Promise#allSettled
*/
Q.allSettled = allSettled;
function allSettled(promises) {
return Q(promises).allSettled();
}
/**
* Turns an array of promises into a promise for an array of their states (as
* returned by `inspect`) when they have all settled.
* @param {Array[Any*]} values an array (or promise for an array) of values (or
* promises for values)
* @returns {Array[State]} an array of states for the respective values.
*/
Promise.prototype.allSettled = function () {
return this.then(function (promises) {
return all(array_map(promises, function (promise) {
promise = Q(promise);
function regardless() {
return promise.inspect();
}
return promise.then(regardless, regardless);
}));
});
};
/**
* Captures the failure of a promise, giving an oportunity to recover
* with a callback. If the given promise is fulfilled, the returned
* promise is fulfilled.
* @param {Any*} promise for something
* @param {Function} callback to fulfill the returned promise if the
* given promise is rejected
* @returns a promise for the return value of the callback
*/
Q.fail = // XXX legacy
Q["catch"] = function (object, rejected) {
return Q(object).then(void 0, rejected);
};
Promise.prototype.fail = // XXX legacy
Promise.prototype["catch"] = function (rejected) {
return this.then(void 0, rejected);
};
/**
* Attaches a listener that can respond to progress notifications from a
* promise's originating deferred. This listener receives the exact arguments
* passed to ``deferred.notify``.
* @param {Any*} promise for something
* @param {Function} callback to receive any progress notifications
* @returns the given promise, unchanged
*/
Q.progress = progress;
function progress(object, progressed) {
return Q(object).then(void 0, void 0, progressed);
}
Promise.prototype.progress = function (progressed) {
return this.then(void 0, void 0, progressed);
};
/**
* Provides an opportunity to observe the settling of a promise,
* regardless of whether the promise is fulfilled or rejected. Forwards
* the resolution to the returned promise when the callback is done.
* The callback can return a promise to defer completion.
* @param {Any*} promise
* @param {Function} callback to observe the resolution of the given
* promise, takes no arguments.
* @returns a promise for the resolution of the given promise when
* ``fin`` is done.
*/
Q.fin = // XXX legacy
Q["finally"] = function (object, callback) {
return Q(object)["finally"](callback);
};
Promise.prototype.fin = // XXX legacy
Promise.prototype["finally"] = function (callback) {
callback = Q(callback);
return this.then(function (value) {
return callback.fcall().then(function () {
return value;
});
}, function (reason) {
// TODO attempt to recycle the rejection with "this".
return callback.fcall().then(function () {
throw reason;
});
});
};
/**
* Terminates a chain of promises, forcing rejections to be
* thrown as exceptions.
* @param {Any*} promise at the end of a chain of promises
* @returns nothing
*/
Q.done = function (object, fulfilled, rejected, progress) {
return Q(object).done(fulfilled, rejected, progress);
};
Promise.prototype.done = function (fulfilled, rejected, progress) {
var onUnhandledError = function (error) {
// forward to a future turn so that ``when``
// does not catch it and turn it into a rejection.
Q.nextTick(function () {
makeStackTraceLong(error, promise);
if (Q.onerror) {
Q.onerror(error);
} else {
throw error;
}
});
};
// Avoid unnecessary `nextTick`ing via an unnecessary `when`.
var promise = fulfilled || rejected || progress ?
this.then(fulfilled, rejected, progress) :
this;
if (typeof process === "object" && process && process.domain) {
onUnhandledError = process.domain.bind(onUnhandledError);
}
promise.then(void 0, onUnhandledError);
};
/**
* Causes a promise to be rejected if it does not get fulfilled before
* some milliseconds time out.
* @param {Any*} promise
* @param {Number} milliseconds timeout
* @param {Any*} custom error message or Error object (optional)
* @returns a promise for the resolution of the given promise if it is
* fulfilled before the timeout, otherwise rejected.
*/
Q.timeout = function (object, ms, error) {
return Q(object).timeout(ms, error);
};
Promise.prototype.timeout = function (ms, error) {
var deferred = defer();
var timeoutId = setTimeout(function () {
if (!error || "string" === typeof error) {
error = new Error(error || "Timed out after " + ms + " ms");
error.code = "ETIMEDOUT";
}
deferred.reject(error);
}, ms);
this.then(function (value) {
clearTimeout(timeoutId);
deferred.resolve(value);
}, function (exception) {
clearTimeout(timeoutId);
deferred.reject(exception);
}, deferred.notify);
return deferred.promise;
};
/**
* Returns a promise for the given value (or promised value), some
* milliseconds after it resolved. Passes rejections immediately.
* @param {Any*} promise
* @param {Number} milliseconds
* @returns a promise for the resolution of the given promise after milliseconds
* time has elapsed since the resolution of the given promise.
* If the given promise rejects, that is passed immediately.
*/
Q.delay = function (object, timeout) {
if (timeout === void 0) {
timeout = object;
object = void 0;
}
return Q(object).delay(timeout);
};
Promise.prototype.delay = function (timeout) {
return this.then(function (value) {
var deferred = defer();
setTimeout(function () {
deferred.resolve(value);
}, timeout);
return deferred.promise;
});
};
/**
* Passes a continuation to a Node function, which is called with the given
* arguments provided as an array, and returns a promise.
*
* Q.nfapply(FS.readFile, [__filename])
* .then(function (content) {
* })
*
*/
Q.nfapply = function (callback, args) {
return Q(callback).nfapply(args);
};
Promise.prototype.nfapply = function (args) {
var deferred = defer();
var nodeArgs = array_slice(args);
nodeArgs.push(deferred.makeNodeResolver());
this.fapply(nodeArgs).fail(deferred.reject);
return deferred.promise;
};
/**
* Passes a continuation to a Node function, which is called with the given
* arguments provided individually, and returns a promise.
* @example
* Q.nfcall(FS.readFile, __filename)
* .then(function (content) {
* })
*
*/
Q.nfcall = function (callback /*...args*/) {
var args = array_slice(arguments, 1);
return Q(callback).nfapply(args);
};
Promise.prototype.nfcall = function (/*...args*/) {
var nodeArgs = array_slice(arguments);
var deferred = defer();
nodeArgs.push(deferred.makeNodeResolver());
this.fapply(nodeArgs).fail(deferred.reject);
return deferred.promise;
};
/**
* Wraps a NodeJS continuation passing function and returns an equivalent
* version that returns a promise.
* @example
* Q.nfbind(FS.readFile, __filename)("utf-8")
* .then(console.log)
* .done()
*/
Q.nfbind =
Q.denodeify = function (callback /*...args*/) {
var baseArgs = array_slice(arguments, 1);
return function () {
var nodeArgs = baseArgs.concat(array_slice(arguments));
var deferred = defer();
nodeArgs.push(deferred.makeNodeResolver());
Q(callback).fapply(nodeArgs).fail(deferred.reject);
return deferred.promise;
};
};
Promise.prototype.nfbind =
Promise.prototype.denodeify = function (/*...args*/) {
var args = array_slice(arguments);
args.unshift(this);
return Q.denodeify.apply(void 0, args);
};
Q.nbind = function (callback, thisp /*...args*/) {
var baseArgs = array_slice(arguments, 2);
return function () {
var nodeArgs = baseArgs.concat(array_slice(arguments));
var deferred = defer();
nodeArgs.push(deferred.makeNodeResolver());
function bound() {
return callback.apply(thisp, arguments);
}
Q(bound).fapply(nodeArgs).fail(deferred.reject);
return deferred.promise;
};
};
Promise.prototype.nbind = function (/*thisp, ...args*/) {
var args = array_slice(arguments, 0);
args.unshift(this);
return Q.nbind.apply(void 0, args);
};
/**
* Calls a method of a Node-style object that accepts a Node-style
* callback with a given array of arguments, plus a provided callback.
* @param object an object that has the named method
* @param {String} name name of the method of object
* @param {Array} args arguments to pass to the method; the callback
* will be provided by Q and appended to these arguments.
* @returns a promise for the value or error
*/
Q.nmapply = // XXX As proposed by "Redsandro"
Q.npost = function (object, name, args) {
return Q(object).npost(name, args);
};
Promise.prototype.nmapply = // XXX As proposed by "Redsandro"
Promise.prototype.npost = function (name, args) {
var nodeArgs = array_slice(args || []);
var deferred = defer();
nodeArgs.push(deferred.makeNodeResolver());
this.dispatch("post", [name, nodeArgs]).fail(deferred.reject);
return deferred.promise;
};
/**
* Calls a method of a Node-style object that accepts a Node-style
* callback, forwarding the given variadic arguments, plus a provided
* callback argument.
* @param object an object that has the named method
* @param {String} name name of the method of object
* @param ...args arguments to pass to the method; the callback will
* be provided by Q and appended to these arguments.
* @returns a promise for the value or error
*/
Q.nsend = // XXX Based on Mark Miller's proposed "send"
Q.nmcall = // XXX Based on "Redsandro's" proposal
Q.ninvoke = function (object, name /*...args*/) {
var nodeArgs = array_slice(arguments, 2);
var deferred = defer();
nodeArgs.push(deferred.makeNodeResolver());
Q(object).dispatch("post", [name, nodeArgs]).fail(deferred.reject);
return deferred.promise;
};
Promise.prototype.nsend = // XXX Based on Mark Miller's proposed "send"
Promise.prototype.nmcall = // XXX Based on "Redsandro's" proposal
Promise.prototype.ninvoke = function (name /*...args*/) {
var nodeArgs = array_slice(arguments, 1);
var deferred = defer();
nodeArgs.push(deferred.makeNodeResolver());
this.dispatch("post", [name, nodeArgs]).fail(deferred.reject);
return deferred.promise;
};
/**
* If a function would like to support both Node continuation-passing-style and
* promise-returning-style, it can end its internal promise chain with
* `nodeify(nodeback)`, forwarding the optional nodeback argument. If the user
* elects to use a nodeback, the result will be sent there. If they do not
* pass a nodeback, they will receive the result promise.
* @param object a result (or a promise for a result)
* @param {Function} nodeback a Node.js-style callback
* @returns either the promise or nothing
*/
Q.nodeify = nodeify;
function nodeify(object, nodeback) {
return Q(object).nodeify(nodeback);
}
Promise.prototype.nodeify = function (nodeback) {
if (nodeback) {
this.then(function (value) {
Q.nextTick(function () {
nodeback(null, value);
});
}, function (error) {
Q.nextTick(function () {
nodeback(error);
});
});
} else {
return this;
}
};
Q.noConflict = function() {
throw new Error("Q.noConflict only works when Q is used as a global");
};
// All code before this point will be filtered from stack traces.
var qEndingLine = captureLine();
return Q;
});
}).call(this,require('_process'))
},{"_process":12}],158:[function(require,module,exports){
/**
* Root reference for iframes.
*/
var root;
if (typeof window !== 'undefined') { // Browser window
root = window;
} else if (typeof self !== 'undefined') { // Web Worker
root = self;
} else { // Other environments
console.warn("Using browser-only version of superagent in non-browser environment");
root = this;
}
var Emitter = require('emitter');
var requestBase = require('./request-base');
var isObject = require('./is-object');
/**
* Noop.
*/
function noop(){};
/**
* Expose `request`.
*/
var request = module.exports = require('./request').bind(null, Request);
/**
* Determine XHR.
*/
request.getXHR = function () {
if (root.XMLHttpRequest
&& (!root.location || 'file:' != root.location.protocol
|| !root.ActiveXObject)) {
return new XMLHttpRequest;
} else {
try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {}
try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {}
try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {}
try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {}
}
throw Error("Browser-only verison of superagent could not find XHR");
};
/**
* Removes leading and trailing whitespace, added to support IE.
*
* @param {String} s
* @return {String}
* @api private
*/
var trim = ''.trim
? function(s) { return s.trim(); }
: function(s) { return s.replace(/(^\s*|\s*$)/g, ''); };
/**
* Serialize the given `obj`.
*
* @param {Object} obj
* @return {String}
* @api private
*/
function serialize(obj) {
if (!isObject(obj)) return obj;
var pairs = [];
for (var key in obj) {
pushEncodedKeyValuePair(pairs, key, obj[key]);
}
return pairs.join('&');
}
/**
* Helps 'serialize' with serializing arrays.
* Mutates the pairs array.
*
* @param {Array} pairs
* @param {String} key
* @param {Mixed} val
*/
function pushEncodedKeyValuePair(pairs, key, val) {
if (val != null) {
if (Array.isArray(val)) {
val.forEach(function(v) {
pushEncodedKeyValuePair(pairs, key, v);
});
} else if (isObject(val)) {
for(var subkey in val) {
pushEncodedKeyValuePair(pairs, key + '[' + subkey + ']', val[subkey]);
}
} else {
pairs.push(encodeURIComponent(key)
+ '=' + encodeURIComponent(val));
}
} else if (val === null) {
pairs.push(encodeURIComponent(key));
}
}
/**
* Expose serialization method.
*/
request.serializeObject = serialize;
/**
* Parse the given x-www-form-urlencoded `str`.
*
* @param {String} str
* @return {Object}
* @api private
*/
function parseString(str) {
var obj = {};
var pairs = str.split('&');
var pair;
var pos;
for (var i = 0, len = pairs.length; i < len; ++i) {
pair = pairs[i];
pos = pair.indexOf('=');
if (pos == -1) {
obj[decodeURIComponent(pair)] = '';
} else {
obj[decodeURIComponent(pair.slice(0, pos))] =
decodeURIComponent(pair.slice(pos + 1));
}
}
return obj;
}
/**
* Expose parser.
*/
request.parseString = parseString;
/**
* Default MIME type map.
*
* superagent.types.xml = 'application/xml';
*
*/
request.types = {
html: 'text/html',
json: 'application/json',
xml: 'application/xml',
urlencoded: 'application/x-www-form-urlencoded',
'form': 'application/x-www-form-urlencoded',
'form-data': 'application/x-www-form-urlencoded'
};
/**
* Default serialization map.
*
* superagent.serialize['application/xml'] = function(obj){
* return 'generated xml here';
* };
*
*/
request.serialize = {
'application/x-www-form-urlencoded': serialize,
'application/json': JSON.stringify
};
/**
* Default parsers.
*
* superagent.parse['application/xml'] = function(str){
* return { object parsed from str };
* };
*
*/
request.parse = {
'application/x-www-form-urlencoded': parseString,
'application/json': JSON.parse
};
/**
* Parse the given header `str` into
* an object containing the mapped fields.
*
* @param {String} str
* @return {Object}
* @api private
*/
function parseHeader(str) {
var lines = str.split(/\r?\n/);
var fields = {};
var index;
var line;
var field;
var val;
lines.pop(); // trailing CRLF
for (var i = 0, len = lines.length; i < len; ++i) {
line = lines[i];
index = line.indexOf(':');
field = line.slice(0, index).toLowerCase();
val = trim(line.slice(index + 1));
fields[field] = val;
}
return fields;
}
/**
* Check if `mime` is json or has +json structured syntax suffix.
*
* @param {String} mime
* @return {Boolean}
* @api private
*/
function isJSON(mime) {
return /[\/+]json\b/.test(mime);
}
/**
* Return the mime type for the given `str`.
*
* @param {String} str
* @return {String}
* @api private
*/
function type(str){
return str.split(/ *; */).shift();
};
/**
* Return header field parameters.
*
* @param {String} str
* @return {Object}
* @api private
*/
function params(str){
return str.split(/ *; */).reduce(function(obj, str){
var parts = str.split(/ *= */),
key = parts.shift(),
val = parts.shift();
if (key && val) obj[key] = val;
return obj;
}, {});
};
/**
* Initialize a new `Response` with the given `xhr`.
*
* - set flags (.ok, .error, etc)
* - parse header
*
* Examples:
*
* Aliasing `superagent` as `request` is nice:
*
* request = superagent;
*
* We can use the promise-like API, or pass callbacks:
*
* request.get('/').end(function(res){});
* request.get('/', function(res){});
*
* Sending data can be chained:
*
* request
* .post('/user')
* .send({ name: 'tj' })
* .end(function(res){});
*
* Or passed to `.send()`:
*
* request
* .post('/user')
* .send({ name: 'tj' }, function(res){});
*
* Or passed to `.post()`:
*
* request
* .post('/user', { name: 'tj' })
* .end(function(res){});
*
* Or further reduced to a single call for simple cases:
*
* request
* .post('/user', { name: 'tj' }, function(res){});
*
* @param {XMLHTTPRequest} xhr
* @param {Object} options
* @api private
*/
function Response(req, options) {
options = options || {};
this.req = req;
this.xhr = this.req.xhr;
// responseText is accessible only if responseType is '' or 'text' and on older browsers
this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined')
? this.xhr.responseText
: null;
this.statusText = this.req.xhr.statusText;
this._setStatusProperties(this.xhr.status);
this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders());
// getAllResponseHeaders sometimes falsely returns "" for CORS requests, but
// getResponseHeader still works. so we get content-type even if getting
// other headers fails.
this.header['content-type'] = this.xhr.getResponseHeader('content-type');
this._setHeaderProperties(this.header);
this.body = this.req.method != 'HEAD'
? this._parseBody(this.text ? this.text : this.xhr.response)
: null;
}
/**
* Get case-insensitive `field` value.
*
* @param {String} field
* @return {String}
* @api public
*/
Response.prototype.get = function(field){
return this.header[field.toLowerCase()];
};
/**
* Set header related properties:
*
* - `.type` the content type without params
*
* A response of "Content-Type: text/plain; charset=utf-8"
* will provide you with a `.type` of "text/plain".
*
* @param {Object} header
* @api private
*/
Response.prototype._setHeaderProperties = function(header){
// content-type
var ct = this.header['content-type'] || '';
this.type = type(ct);
// params
var obj = params(ct);
for (var key in obj) this[key] = obj[key];
};
/**
* Parse the given body `str`.
*
* Used for auto-parsing of bodies. Parsers
* are defined on the `superagent.parse` object.
*
* @param {String} str
* @return {Mixed}
* @api private
*/
Response.prototype._parseBody = function(str){
var parse = request.parse[this.type];
if (!parse && isJSON(this.type)) {
parse = request.parse['application/json'];
}
return parse && str && (str.length || str instanceof Object)
? parse(str)
: null;
};
/**
* Set flags such as `.ok` based on `status`.
*
* For example a 2xx response will give you a `.ok` of __true__
* whereas 5xx will be __false__ and `.error` will be __true__. The
* `.clientError` and `.serverError` are also available to be more
* specific, and `.statusType` is the class of error ranging from 1..5
* sometimes useful for mapping respond colors etc.
*
* "sugar" properties are also defined for common cases. Currently providing:
*
* - .noContent
* - .badRequest
* - .unauthorized
* - .notAcceptable
* - .notFound
*
* @param {Number} status
* @api private
*/
Response.prototype._setStatusProperties = function(status){
// handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request
if (status === 1223) {
status = 204;
}
var type = status / 100 | 0;
// status / class
this.status = this.statusCode = status;
this.statusType = type;
// basics
this.info = 1 == type;
this.ok = 2 == type;
this.clientError = 4 == type;
this.serverError = 5 == type;
this.error = (4 == type || 5 == type)
? this.toError()
: false;
// sugar
this.accepted = 202 == status;
this.noContent = 204 == status;
this.badRequest = 400 == status;
this.unauthorized = 401 == status;
this.notAcceptable = 406 == status;
this.notFound = 404 == status;
this.forbidden = 403 == status;
};
/**
* Return an `Error` representative of this response.
*
* @return {Error}
* @api public
*/
Response.prototype.toError = function(){
var req = this.req;
var method = req.method;
var url = req.url;
var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')';
var err = new Error(msg);
err.status = this.status;
err.method = method;
err.url = url;
return err;
};
/**
* Expose `Response`.
*/
request.Response = Response;
/**
* Initialize a new `Request` with the given `method` and `url`.
*
* @param {String} method
* @param {String} url
* @api public
*/
function Request(method, url) {
var self = this;
this._query = this._query || [];
this.method = method;
this.url = url;
this.header = {}; // preserves header name case
this._header = {}; // coerces header names to lowercase
this.on('end', function(){
var err = null;
var res = null;
try {
res = new Response(self);
} catch(e) {
err = new Error('Parser is unable to parse the response');
err.parse = true;
err.original = e;
// issue #675: return the raw response if the response parsing fails
err.rawResponse = self.xhr && self.xhr.responseText ? self.xhr.responseText : null;
// issue #876: return the http status code if the response parsing fails
err.statusCode = self.xhr && self.xhr.status ? self.xhr.status : null;
return self.callback(err);
}
self.emit('response', res);
var new_err;
try {
if (res.status < 200 || res.status >= 300) {
new_err = new Error(res.statusText || 'Unsuccessful HTTP response');
new_err.original = err;
new_err.response = res;
new_err.status = res.status;
}
} catch(e) {
new_err = e; // #985 touching res may cause INVALID_STATE_ERR on old Android
}
// #1000 don't catch errors from the callback to avoid double calling it
if (new_err) {
self.callback(new_err, res);
} else {
self.callback(null, res);
}
});
}
/**
* Mixin `Emitter` and `requestBase`.
*/
Emitter(Request.prototype);
for (var key in requestBase) {
Request.prototype[key] = requestBase[key];
}
/**
* Set Content-Type to `type`, mapping values from `request.types`.
*
* Examples:
*
* superagent.types.xml = 'application/xml';
*
* request.post('/')
* .type('xml')
* .send(xmlstring)
* .end(callback);
*
* request.post('/')
* .type('application/xml')
* .send(xmlstring)
* .end(callback);
*
* @param {String} type
* @return {Request} for chaining
* @api public
*/
Request.prototype.type = function(type){
this.set('Content-Type', request.types[type] || type);
return this;
};
/**
* Set responseType to `val`. Presently valid responseTypes are 'blob' and
* 'arraybuffer'.
*
* Examples:
*
* req.get('/')
* .responseType('blob')
* .end(callback);
*
* @param {String} val
* @return {Request} for chaining
* @api public
*/
Request.prototype.responseType = function(val){
this._responseType = val;
return this;
};
/**
* Set Accept to `type`, mapping values from `request.types`.
*
* Examples:
*
* superagent.types.json = 'application/json';
*
* request.get('/agent')
* .accept('json')
* .end(callback);
*
* request.get('/agent')
* .accept('application/json')
* .end(callback);
*
* @param {String} accept
* @return {Request} for chaining
* @api public
*/
Request.prototype.accept = function(type){
this.set('Accept', request.types[type] || type);
return this;
};
/**
* Set Authorization field value with `user` and `pass`.
*
* @param {String} user
* @param {String} pass
* @param {Object} options with 'type' property 'auto' or 'basic' (default 'basic')
* @return {Request} for chaining
* @api public
*/
Request.prototype.auth = function(user, pass, options){
if (!options) {
options = {
type: 'basic'
}
}
switch (options.type) {
case 'basic':
var str = btoa(user + ':' + pass);
this.set('Authorization', 'Basic ' + str);
break;
case 'auto':
this.username = user;
this.password = pass;
break;
}
return this;
};
/**
* Add query-string `val`.
*
* Examples:
*
* request.get('/shoes')
* .query('size=10')
* .query({ color: 'blue' })
*
* @param {Object|String} val
* @return {Request} for chaining
* @api public
*/
Request.prototype.query = function(val){
if ('string' != typeof val) val = serialize(val);
if (val) this._query.push(val);
return this;
};
/**
* Queue the given `file` as an attachment to the specified `field`,
* with optional `filename`.
*
* ``` js
* request.post('/upload')
* .attach('content', new Blob(['<a id="a"><b id="b">hey!</b></a>'], { type: "text/html"}))
* .end(callback);
* ```
*
* @param {String} field
* @param {Blob|File} file
* @param {String} filename
* @return {Request} for chaining
* @api public
*/
Request.prototype.attach = function(field, file, filename){
this._getFormData().append(field, file, filename || file.name);
return this;
};
Request.prototype._getFormData = function(){
if (!this._formData) {
this._formData = new root.FormData();
}
return this._formData;
};
/**
* Invoke the callback with `err` and `res`
* and handle arity check.
*
* @param {Error} err
* @param {Response} res
* @api private
*/
Request.prototype.callback = function(err, res){
var fn = this._callback;
this.clearTimeout();
fn(err, res);
};
/**
* Invoke callback with x-domain error.
*
* @api private
*/
Request.prototype.crossDomainError = function(){
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.');
err.crossDomain = true;
err.status = this.status;
err.method = this.method;
err.url = this.url;
this.callback(err);
};
/**
* Invoke callback with timeout error.
*
* @api private
*/
Request.prototype._timeoutError = function(){
var timeout = this._timeout;
var err = new Error('timeout of ' + timeout + 'ms exceeded');
err.timeout = timeout;
this.callback(err);
};
/**
* Compose querystring to append to req.url
*
* @api private
*/
Request.prototype._appendQueryString = function(){
var query = this._query.join('&');
if (query) {
this.url += ~this.url.indexOf('?')
? '&' + query
: '?' + query;
}
};
/**
* Initiate request, invoking callback `fn(res)`
* with an instanceof `Response`.
*
* @param {Function} fn
* @return {Request} for chaining
* @api public
*/
Request.prototype.end = function(fn){
var self = this;
var xhr = this.xhr = request.getXHR();
var timeout = this._timeout;
var data = this._formData || this._data;
// store callback
this._callback = fn || noop;
// state change
xhr.onreadystatechange = function(){
if (4 != xhr.readyState) return;
// In IE9, reads to any property (e.g. status) off of an aborted XHR will
// result in the error "Could not complete the operation due to error c00c023f"
var status;
try { status = xhr.status } catch(e) { status = 0; }
if (0 == status) {
if (self.timedout) return self._timeoutError();
if (self._aborted) return;
return self.crossDomainError();
}
self.emit('end');
};
// progress
var handleProgress = function(e){
if (e.total > 0) {
e.percent = e.loaded / e.total * 100;
}
e.direction = 'download';
self.emit('progress', e);
};
if (this.hasListeners('progress')) {
xhr.onprogress = handleProgress;
}
try {
if (xhr.upload && this.hasListeners('progress')) {
xhr.upload.onprogress = handleProgress;
}
} catch(e) {
// Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist.
// Reported here:
// https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context
}
// timeout
if (timeout && !this._timer) {
this._timer = setTimeout(function(){
self.timedout = true;
self.abort();
}, timeout);
}
// querystring
this._appendQueryString();
// initiate request
if (this.username && this.password) {
xhr.open(this.method, this.url, true, this.username, this.password);
} else {
xhr.open(this.method, this.url, true);
}
// CORS
if (this._withCredentials) xhr.withCredentials = true;
// body
if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !this._isHost(data)) {
// serialize stuff
var contentType = this._header['content-type'];
var serialize = this._serializer || request.serialize[contentType ? contentType.split(';')[0] : ''];
if (!serialize && isJSON(contentType)) serialize = request.serialize['application/json'];
if (serialize) data = serialize(data);
}
// set header fields
for (var field in this.header) {
if (null == this.header[field]) continue;
xhr.setRequestHeader(field, this.header[field]);
}
if (this._responseType) {
xhr.responseType = this._responseType;
}
// send stuff
this.emit('request', this);
// IE11 xhr.send(undefined) sends 'undefined' string as POST payload (instead of nothing)
// We need null here if data is undefined
xhr.send(typeof data !== 'undefined' ? data : null);
return this;
};
/**
* Expose `Request`.
*/
request.Request = Request;
/**
* GET `url` with optional callback `fn(res)`.
*
* @param {String} url
* @param {Mixed|Function} [data] or fn
* @param {Function} [fn]
* @return {Request}
* @api public
*/
request.get = function(url, data, fn){
var req = request('GET', url);
if ('function' == typeof data) fn = data, data = null;
if (data) req.query(data);
if (fn) req.end(fn);
return req;
};
/**
* HEAD `url` with optional callback `fn(res)`.
*
* @param {String} url
* @param {Mixed|Function} [data] or fn
* @param {Function} [fn]
* @return {Request}
* @api public
*/
request.head = function(url, data, fn){
var req = request('HEAD', url);
if ('function' == typeof data) fn = data, data = null;
if (data) req.send(data);
if (fn) req.end(fn);
return req;
};
/**
* OPTIONS query to `url` with optional callback `fn(res)`.
*
* @param {String} url
* @param {Mixed|Function} [data] or fn
* @param {Function} [fn]
* @return {Request}
* @api public
*/
request.options = function(url, data, fn){
var req = request('OPTIONS', url);
if ('function' == typeof data) fn = data, data = null;
if (data) req.send(data);
if (fn) req.end(fn);
return req;
};
/**
* DELETE `url` with optional callback `fn(res)`.
*
* @param {String} url
* @param {Function} [fn]
* @return {Request}
* @api public
*/
function del(url, fn){
var req = request('DELETE', url);
if (fn) req.end(fn);
return req;
};
request['del'] = del;
request['delete'] = del;
/**
* PATCH `url` with optional `data` and callback `fn(res)`.
*
* @param {String} url
* @param {Mixed} [data]
* @param {Function} [fn]
* @return {Request}
* @api public
*/
request.patch = function(url, data, fn){
var req = request('PATCH', url);
if ('function' == typeof data) fn = data, data = null;
if (data) req.send(data);
if (fn) req.end(fn);
return req;
};
/**
* POST `url` with optional `data` and callback `fn(res)`.
*
* @param {String} url
* @param {Mixed} [data]
* @param {Function} [fn]
* @return {Request}
* @api public
*/
request.post = function(url, data, fn){
var req = request('POST', url);
if ('function' == typeof data) fn = data, data = null;
if (data) req.send(data);
if (fn) req.end(fn);
return req;
};
/**
* PUT `url` with optional `data` and callback `fn(res)`.
*
* @param {String} url
* @param {Mixed|Function} [data] or fn
* @param {Function} [fn]
* @return {Request}
* @api public
*/
request.put = function(url, data, fn){
var req = request('PUT', url);
if ('function' == typeof data) fn = data, data = null;
if (data) req.send(data);
if (fn) req.end(fn);
return req;
};
},{"./is-object":159,"./request":161,"./request-base":160,"emitter":162}],159:[function(require,module,exports){
/**
* Check if `obj` is an object.
*
* @param {Object} obj
* @return {Boolean}
* @api private
*/
function isObject(obj) {
return null !== obj && 'object' === typeof obj;
}
module.exports = isObject;
},{}],160:[function(require,module,exports){
/**
* Module of mixed-in functions shared between node and client code
*/
var isObject = require('./is-object');
/**
* Clear previous timeout.
*
* @return {Request} for chaining
* @api public
*/
exports.clearTimeout = function _clearTimeout(){
this._timeout = 0;
clearTimeout(this._timer);
return this;
};
/**
* Override default response body parser
*
* This function will be called to convert incoming data into request.body
*
* @param {Function}
* @api public
*/
exports.parse = function parse(fn){
this._parser = fn;
return this;
};
/**
* Override default request body serializer
*
* This function will be called to convert data set via .send or .attach into payload to send
*
* @param {Function}
* @api public
*/
exports.serialize = function serialize(fn){
this._serializer = fn;
return this;
};
/**
* Set timeout to `ms`.
*
* @param {Number} ms
* @return {Request} for chaining
* @api public
*/
exports.timeout = function timeout(ms){
this._timeout = ms;
return this;
};
/**
* Promise support
*
* @param {Function} resolve
* @param {Function} reject
* @return {Request}
*/
exports.then = function then(resolve, reject) {
if (!this._fullfilledPromise) {
var self = this;
this._fullfilledPromise = new Promise(function(innerResolve, innerReject){
self.end(function(err, res){
if (err) innerReject(err); else innerResolve(res);
});
});
}
return this._fullfilledPromise.then(resolve, reject);
}
/**
* Allow for extension
*/
exports.use = function use(fn) {
fn(this);
return this;
}
/**
* Get request header `field`.
* Case-insensitive.
*
* @param {String} field
* @return {String}
* @api public
*/
exports.get = function(field){
return this._header[field.toLowerCase()];
};
/**
* Get case-insensitive header `field` value.
* This is a deprecated internal API. Use `.get(field)` instead.
*
* (getHeader is no longer used internally by the superagent code base)
*
* @param {String} field
* @return {String}
* @api private
* @deprecated
*/
exports.getHeader = exports.get;
/**
* Set header `field` to `val`, or multiple fields with one object.
* Case-insensitive.
*
* Examples:
*
* req.get('/')
* .set('Accept', 'application/json')
* .set('X-API-Key', 'foobar')
* .end(callback);
*
* req.get('/')
* .set({ Accept: 'application/json', 'X-API-Key': 'foobar' })
* .end(callback);
*
* @param {String|Object} field
* @param {String} val
* @return {Request} for chaining
* @api public
*/
exports.set = function(field, val){
if (isObject(field)) {
for (var key in field) {
this.set(key, field[key]);
}
return this;
}
this._header[field.toLowerCase()] = val;
this.header[field] = val;
return this;
};
/**
* Remove header `field`.
* Case-insensitive.
*
* Example:
*
* req.get('/')
* .unset('User-Agent')
* .end(callback);
*
* @param {String} field
*/
exports.unset = function(field){
delete this._header[field.toLowerCase()];
delete this.header[field];
return this;
};
/**
* Write the field `name` and `val` for "multipart/form-data"
* request bodies.
*
* ``` js
* request.post('/upload')
* .field('foo', 'bar')
* .end(callback);
* ```
*
* @param {String} name
* @param {String|Blob|File|Buffer|fs.ReadStream} val
* @return {Request} for chaining
* @api public
*/
exports.field = function(name, val) {
this._getFormData().append(name, val);
return this;
};
/**
* Abort the request, and clear potential timeout.
*
* @return {Request}
* @api public
*/
exports.abort = function(){
if (this._aborted) {
return this;
}
this._aborted = true;
this.xhr && this.xhr.abort(); // browser
this.req && this.req.abort(); // node
this.clearTimeout();
this.emit('abort');
return this;
};
/**
* Enable transmission of cookies with x-domain requests.
*
* Note that for this to work the origin must not be
* using "Access-Control-Allow-Origin" with a wildcard,
* and also must set "Access-Control-Allow-Credentials"
* to "true".
*
* @api public
*/
exports.withCredentials = function(){
// This is browser-only functionality. Node side is no-op.
this._withCredentials = true;
return this;
};
/**
* Set the max redirects to `n`. Does noting in browser XHR implementation.
*
* @param {Number} n
* @return {Request} for chaining
* @api public
*/
exports.redirects = function(n){
this._maxRedirects = n;
return this;
};
/**
* Convert to a plain javascript object (not JSON string) of scalar properties.
* Note as this method is designed to return a useful non-this value,
* it cannot be chained.
*
* @return {Object} describing method, url, and data of this request
* @api public
*/
exports.toJSON = function(){
return {
method: this.method,
url: this.url,
data: this._data,
headers: this._header
};
};
/**
* Check if `obj` is a host object,
* we don't want to serialize these :)
*
* TODO: future proof, move to compoent land
*
* @param {Object} obj
* @return {Boolean}
* @api private
*/
exports._isHost = function _isHost(obj) {
var str = {}.toString.call(obj);
switch (str) {
case '[object File]':
case '[object Blob]':
case '[object FormData]':
return true;
default:
return false;
}
}
/**
* Send `data` as the request body, defaulting the `.type()` to "json" when
* an object is given.
*
* Examples:
*
* // manual json
* request.post('/user')
* .type('json')
* .send('{"name":"tj"}')
* .end(callback)
*
* // auto json
* request.post('/user')
* .send({ name: 'tj' })
* .end(callback)
*
* // manual x-www-form-urlencoded
* request.post('/user')
* .type('form')
* .send('name=tj')
* .end(callback)
*
* // auto x-www-form-urlencoded
* request.post('/user')
* .type('form')
* .send({ name: 'tj' })
* .end(callback)
*
* // defaults to x-www-form-urlencoded
* request.post('/user')
* .send('name=tobi')
* .send('species=ferret')
* .end(callback)
*
* @param {String|Object} data
* @return {Request} for chaining
* @api public
*/
exports.send = function(data){
var obj = isObject(data);
var type = this._header['content-type'];
// merge
if (obj && isObject(this._data)) {
for (var key in data) {
this._data[key] = data[key];
}
} else if ('string' == typeof data) {
// default to x-www-form-urlencoded
if (!type) this.type('form');
type = this._header['content-type'];
if ('application/x-www-form-urlencoded' == type) {
this._data = this._data
? this._data + '&' + data
: data;
} else {
this._data = (this._data || '') + data;
}
} else {
this._data = data;
}
if (!obj || this._isHost(data)) return this;
// default to json
if (!type) this.type('json');
return this;
};
},{"./is-object":159}],161:[function(require,module,exports){
// The node and browser modules expose versions of this with the
// appropriate constructor function bound as first argument
/**
* Issue a request:
*
* Examples:
*
* request('GET', '/users').end(callback)
* request('/users').end(callback)
* request('/users', callback)
*
* @param {String} method
* @param {String|Function} url or callback
* @return {Request}
* @api public
*/
function request(RequestConstructor, method, url) {
// callback
if ('function' == typeof url) {
return new RequestConstructor('GET', method).end(url);
}
// url first
if (2 == arguments.length) {
return new RequestConstructor('GET', method);
}
return new RequestConstructor(method, url);
}
module.exports = request;
},{}],162:[function(require,module,exports){
/**
* Expose `Emitter`.
*/
if (typeof module !== 'undefined') {
module.exports = Emitter;
}
/**
* Initialize a new `Emitter`.
*
* @api public
*/
function Emitter(obj) {
if (obj) return mixin(obj);
};
/**
* Mixin the emitter properties.
*
* @param {Object} obj
* @return {Object}
* @api private
*/
function mixin(obj) {
for (var key in Emitter.prototype) {
obj[key] = Emitter.prototype[key];
}
return obj;
}
/**
* Listen on the given `event` with `fn`.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.on =
Emitter.prototype.addEventListener = function(event, fn){
this._callbacks = this._callbacks || {};
(this._callbacks['$' + event] = this._callbacks['$' + event] || [])
.push(fn);
return this;
};
/**
* Adds an `event` listener that will be invoked a single
* time then automatically removed.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.once = function(event, fn){
function on() {
this.off(event, on);
fn.apply(this, arguments);
}
on.fn = fn;
this.on(event, on);
return this;
};
/**
* Remove the given callback for `event` or all
* registered callbacks.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.off =
Emitter.prototype.removeListener =
Emitter.prototype.removeAllListeners =
Emitter.prototype.removeEventListener = function(event, fn){
this._callbacks = this._callbacks || {};
// all
if (0 == arguments.length) {
this._callbacks = {};
return this;
}
// specific event
var callbacks = this._callbacks['$' + event];
if (!callbacks) return this;
// remove all handlers
if (1 == arguments.length) {
delete this._callbacks['$' + event];
return this;
}
// remove specific handler
var cb;
for (var i = 0; i < callbacks.length; i++) {
cb = callbacks[i];
if (cb === fn || cb.fn === fn) {
callbacks.splice(i, 1);
break;
}
}
return this;
};
/**
* Emit `event` with the given args.
*
* @param {String} event
* @param {Mixed} ...
* @return {Emitter}
*/
Emitter.prototype.emit = function(event){
this._callbacks = this._callbacks || {};
var args = [].slice.call(arguments, 1)
, callbacks = this._callbacks['$' + event];
if (callbacks) {
callbacks = callbacks.slice(0);
for (var i = 0, len = callbacks.length; i < len; ++i) {
callbacks[i].apply(this, args);
}
}
return this;
};
/**
* Return array of callbacks for `event`.
*
* @param {String} event
* @return {Array}
* @api public
*/
Emitter.prototype.listeners = function(event){
this._callbacks = this._callbacks || {};
return this._callbacks['$' + event] || [];
};
/**
* Check if this emitter has `event` handlers.
*
* @param {String} event
* @return {Boolean}
* @api public
*/
Emitter.prototype.hasListeners = function(event){
return !! this.listeners(event).length;
};
},{}]},{},[1])(1)
});
/*global JSONEditor*/
'use strict';
window.SwaggerUi = Backbone.Router.extend({
dom_id: 'swagger_ui',
// Attributes
options: null,
api: null,
headerView: null,
mainView: null,
// SwaggerUi accepts all the same options as SwaggerApi
initialize: function(options) {
options = options || {};
if (options.defaultModelRendering !== 'model') {
options.defaultModelRendering = 'schema';
}
if (!options.highlightSizeThreshold) {
options.highlightSizeThreshold = 100000;
}
// Allow dom_id to be overridden
if (options.dom_id) {
this.dom_id = options.dom_id;
delete options.dom_id;
}
if (!options.supportedSubmitMethods){
options.supportedSubmitMethods = [
'get',
'put',
'post',
'delete',
'head',
'options',
'patch'
];
}
if (typeof options.oauth2RedirectUrl === 'string') {
window.oAuthRedirectUrl = options.oauth2RedirectUrl;
}
// Create an empty div which contains the dom_id
if (! $('#' + this.dom_id).length){
$('body').append('<div id="' + this.dom_id + '"></div>') ;
}
this.options = options;
// set marked options
marked.setOptions({gfm: true});
// Set the callbacks
var that = this;
this.options.success = function() { return that.render(); };
this.options.progress = function(d) { return that.showMessage(d); };
this.options.failure = function(d) { return that.onLoadFailure(d); };
// Create view to handle the header inputs
this.headerView = new SwaggerUi.Views.HeaderView({el: $('#header')});
// Event handler for when the baseUrl/apiKey is entered by user
this.headerView.on('update-swagger-ui', function(data) {
return that.updateSwaggerUi(data);
});
// JSon Editor custom theming
JSONEditor.defaults.iconlibs.swagger = JSONEditor.AbstractIconLib.extend({
mapping: {
collapse: 'collapse',
expand: 'expand'
},
icon_prefix: 'swagger-'
});
},
// Set an option after initializing
setOption: function(option, value) {
this.options[option] = value;
},
// Get the value of a previously set option
getOption: function(option) {
return this.options[option];
},
// Event handler for when url/key is received from user
updateSwaggerUi: function(data){
this.options.url = data.url;
this.load();
},
// Create an api and render
load: function(){
// Initialize the API object
if (this.mainView) {
this.mainView.clear();
}
if (this.authView) {
this.authView.remove();
}
var url = this.options.url;
if (url && url.indexOf('http') !== 0) {
url = this.buildUrl(window.location.href.toString(), url);
}
if(this.api) {
this.options.authorizations = this.api.clientAuthorizations.authz;
}
this.options.url = url;
this.headerView.update(url);
this.api = new SwaggerClient(this.options);
},
// collapse all sections
collapseAll: function(){
Docs.collapseEndpointListForResource('');
},
// list operations for all sections
listAll: function(){
Docs.collapseOperationsForResource('');
},
// expand operations for all sections
expandAll: function(){
Docs.expandOperationsForResource('');
},
// This is bound to success handler for SwaggerApi
// so it gets called when SwaggerApi completes loading
render: function(){
var authsModel;
this.showMessage('Finished Loading Resource Information. Rendering Swagger UI...');
this.mainView = new SwaggerUi.Views.MainView({
model: this.api,
el: $('#' + this.dom_id),
swaggerOptions: this.options,
router: this
}).render();
if (!_.isEmpty(this.api.securityDefinitions)){
authsModel = _.map(this.api.securityDefinitions, function (auth, name) {
var result = {};
result[name] = auth;
return result;
});
this.authView = new SwaggerUi.Views.AuthButtonView({
data: SwaggerUi.utils.parseSecurityDefinitions(authsModel),
router: this
});
$('#auth_container').append(this.authView.render().el);
}
this.showMessage();
switch (this.options.docExpansion) {
case 'full':
this.expandAll(); break;
case 'list':
this.listAll(); break;
default:
break;
}
this.renderGFM();
if (this.options.onComplete){
this.options.onComplete(this.api, this);
}
setTimeout(Docs.shebang.bind(this), 100);
},
buildUrl: function(base, url){
if (url.indexOf('/') === 0) {
var parts = base.split('/');
base = parts[0] + '//' + parts[2];
return base + url;
} else {
var endOfPath = base.length;
if (base.indexOf('?') > -1){
endOfPath = Math.min(endOfPath, base.indexOf('?'));
}
if (base.indexOf('#') > -1){
endOfPath = Math.min(endOfPath, base.indexOf('#'));
}
base = base.substring(0, endOfPath);
if (base.indexOf('/', base.length - 1 ) !== -1){
return base + url;
}
return base + '/' + url;
}
},
// Shows message on topbar of the ui
showMessage: function(data){
if (data === undefined) {
data = '';
}
var $msgbar = $('#message-bar');
$msgbar.removeClass('message-fail');
$msgbar.addClass('message-success');
$msgbar.text(data);
if(window.SwaggerTranslator) {
window.SwaggerTranslator.translate($msgbar);
}
},
// shows message in red
onLoadFailure: function(data){
if (data === undefined) {
data = '';
}
$('#message-bar').removeClass('message-success');
$('#message-bar').addClass('message-fail');
var val = $('#message-bar').text(data);
if (this.options.onFailure) {
this.options.onFailure(data);
}
return val;
},
// Renders GFM for elements with 'markdown' class
renderGFM: function(){
$('.markdown').each(function(){
$(this).html(marked($(this).html()));
});
$('.propDesc', '.model-signature .description').each(function () {
$(this).html(marked($(this).html())).addClass('markdown');
});
}
});
window.SwaggerUi.Views = {};
window.SwaggerUi.Models = {};
window.SwaggerUi.Collections = {};
window.SwaggerUi.partials = {};
window.SwaggerUi.utils = {};
// don't break backward compatibility with previous versions and warn users to upgrade their code
(function(){
window.authorizations = {
add: function() {
warn('Using window.authorizations is deprecated. Please use SwaggerUi.api.clientAuthorizations.add().');
if (typeof window.swaggerUi === 'undefined') {
throw new TypeError('window.swaggerUi is not defined');
}
if (window.swaggerUi instanceof SwaggerUi) {
window.swaggerUi.api.clientAuthorizations.add.apply(window.swaggerUi.api.clientAuthorizations, arguments);
}
}
};
window.ApiKeyAuthorization = function() {
warn('window.ApiKeyAuthorization is deprecated. Please use SwaggerClient.ApiKeyAuthorization.');
SwaggerClient.ApiKeyAuthorization.apply(window, arguments);
};
window.PasswordAuthorization = function() {
warn('window.PasswordAuthorization is deprecated. Please use SwaggerClient.PasswordAuthorization.');
SwaggerClient.PasswordAuthorization.apply(window, arguments);
};
function warn(message) {
if ('console' in window && typeof window.console.warn === 'function') {
console.warn(message);
}
}
})();
// UMD
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['b'], function (b) {
return (root.SwaggerUi = factory(b));
});
} else if (typeof exports === 'object') {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like environments that support module.exports,
// like Node.
module.exports = factory(require('b'));
} else {
// Browser globals
root.SwaggerUi = factory(root.b);
}
}(this, function () {
return SwaggerUi;
}));
'use strict';
window.SwaggerUi.utils = {
parseSecurityDefinitions: function (security, securityDefinitions) {
var auths = Object.assign({}, securityDefinitions);
var oauth2Arr = [];
var authsArr = [];
var scopes = [];
var utils = window.SwaggerUi.utils;
if (!Array.isArray(security)) { return null; }
security.forEach(function (item) {
var singleSecurity = {};
var singleOauth2Security = {};
for (var key in item) {
if (Array.isArray(item[key])) {
if (!auths[key]) { continue; }
auths[key] = auths[key] || {};
if (auths[key].type === 'oauth2') {
singleOauth2Security[key] = Object.assign({}, auths[key]);
singleOauth2Security[key].scopes = Object.assign({}, auths[key].scopes);
for (var i in singleOauth2Security[key].scopes) {
if (item[key].indexOf(i) < 0) {
delete singleOauth2Security[key].scopes[i];
}
}
singleOauth2Security[key].scopes = utils.parseOauth2Scopes(singleOauth2Security[key].scopes);
scopes = _.merge(scopes, singleOauth2Security[key].scopes);
} else {
singleSecurity[key] = Object.assign({}, auths[key]);
}
} else {
if (item[key].type === 'oauth2') {
singleOauth2Security[key] = Object.assign({}, item[key]);
singleOauth2Security[key].scopes = utils.parseOauth2Scopes(singleOauth2Security[key].scopes);
scopes = _.merge(scopes, singleOauth2Security[key].scopes);
} else {
singleSecurity[key] = item[key];
}
}
}
if (!_.isEmpty(singleSecurity)) {
authsArr.push(singleSecurity);
}
if (!_.isEmpty(singleOauth2Security)){
oauth2Arr.push(singleOauth2Security);
}
});
return {
auths : authsArr,
oauth2: oauth2Arr,
scopes: scopes
};
},
parseOauth2Scopes: function (data) {
var scopes = Object.assign({}, data);
var result = [];
var key;
for (key in scopes) {
result.push({scope: key, description: scopes[key]});
}
return result;
},
sanitize: function(html) {
// Strip the script tags from the html and inline evenhandlers
html = html.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
html = html.replace(/(on\w+="[^"]*")*(on\w+='[^']*')*(on\w+=\w*\(\w*\))*/gi, '');
return html;
}
};
'use strict';
SwaggerUi.Models.ApiKeyAuthModel = Backbone.Model.extend({
defaults: {
'in': '',
name: '',
title: '',
value: ''
},
initialize: function () {
this.on('change', this.validate);
},
validate: function () {
var valid = !!this.get('value');
this.set('valid', valid);
return valid;
}
});
'use strict';
SwaggerUi.Views.ApiKeyAuthView = Backbone.View.extend({ // TODO: append this to global SwaggerUi
events: {
'change .input_apiKey_entry': 'apiKeyChange'
},
selectors: {
apikeyInput: '.input_apiKey_entry'
},
template: Handlebars.templates.apikey_auth,
initialize: function(opts) {
this.options = opts || {};
this.router = this.options.router;
},
render: function (){
this.$el.html(this.template(this.model.toJSON()));
return this;
},
apiKeyChange: function (e) {
var val = $(e.target).val();
if (val) {
this.$(this.selectors.apikeyInput).removeClass('error');
}
this.model.set('value', val);
},
isValid: function () {
return this.model.validate();
},
highlightInvalid: function () {
if (!this.isValid()) {
this.$(this.selectors.apikeyInput).addClass('error');
}
}
});
'use strict';
SwaggerUi.Views.AuthButtonView = Backbone.View.extend({
events: {
'click .authorize__btn': 'authorizeBtnClick'
},
tpls: {
popup: Handlebars.templates.popup,
authBtn: Handlebars.templates.auth_button,
authBtnOperation: Handlebars.templates.auth_button_operation
},
initialize: function(opts) {
this.options = opts || {};
this.options.data = this.options.data || {};
this.isOperation = this.options.isOperation;
this.model = this.model || {};
this.router = this.options.router;
this.auths = this.options.data.oauth2.concat(this.options.data.auths);
},
render: function () {
var tplName = this.isOperation ? 'authBtnOperation' : 'authBtn';
this.$authEl = this.renderAuths(this.auths);
this.$el.html(this.tpls[tplName](this.model));
return this;
},
authorizeBtnClick: function (e) {
var authsModel;
e.preventDefault();
authsModel = {
title: 'Available authorizations',
content: this.$authEl
};
// The content of the popup is removed and all events unbound after clicking the 'Cancel' button of the popup.
// We'll have to re-render the contents before creating a new popup view.
this.render();
this.popup = new SwaggerUi.Views.PopupView({model: authsModel});
this.popup.render();
},
renderAuths: function (auths) {
var $el = $('<div>');
var isLogout = false;
auths.forEach(function (auth) {
var authView = new SwaggerUi.Views.AuthView({data: auth, router: this.router});
var authEl = authView.render().el;
$el.append(authEl);
if (authView.isLogout) {
isLogout = true;
}
}, this);
this.model.isLogout = isLogout;
return $el;
}
});
'use strict';
SwaggerUi.Collections.AuthsCollection = Backbone.Collection.extend({
constructor: function() {
var args = Array.prototype.slice.call(arguments);
args[0] = this.parse(args[0]);
Backbone.Collection.apply(this, args);
},
add: function (model) {
var args = Array.prototype.slice.call(arguments);
if (Array.isArray(model)) {
args[0] = _.map(model, function(val) {
return this.handleOne(val);
}, this);
} else {
args[0] = this.handleOne(model);
}
Backbone.Collection.prototype.add.apply(this, args);
},
handleOne: function (model) {
var result = model;
if (! (model instanceof Backbone.Model) ) {
switch (model.type) {
case 'oauth2':
result = new SwaggerUi.Models.Oauth2Model(model);
break;
case 'basic':
result = new SwaggerUi.Models.BasicAuthModel(model);
break;
case 'apiKey':
result = new SwaggerUi.Models.ApiKeyAuthModel(model);
break;
default:
result = new Backbone.Model(model);
}
}
return result;
},
isValid: function () {
var valid = true;
this.models.forEach(function(model) {
if (!model.validate()) {
valid = false;
}
});
return valid;
},
isAuthorized: function () {
return this.length === this.where({ isLogout: true }).length;
},
isPartiallyAuthorized: function () {
return this.where({ isLogout: true }).length > 0;
},
parse: function (data) {
var authz = {};
if(typeof window.swaggerUi !== 'undefined') {
authz = Object.assign({}, window.swaggerUi.api.clientAuthorizations.authz);
}
return _.map(data, function (auth, name) {
var isBasic = authz[name] && auth.type === 'basic' && authz[name].username && authz[name].password;
_.extend(auth, {
title: name
});
if (authz[name] || isBasic) {
_.extend(auth, {
isLogout: true,
value: isBasic ? undefined : authz[name].value,
username: isBasic ? authz[name].username : undefined,
password: isBasic ? authz[name].password : undefined,
valid: true
});
}
return auth;
});
}
});
'use strict';
SwaggerUi.Views.AuthsCollectionView = Backbone.View.extend({
initialize: function(opts) {
this.options = opts || {};
this.options.data = this.options.data || {};
this.router = this.options.router;
this.collection = new SwaggerUi.Collections.AuthsCollection(opts.data);
this.$innerEl = $('<div>');
this.authViews = [];
},
render: function () {
this.collection.each(function (auth) {
this.renderOneAuth(auth);
}, this);
this.$el.html(this.$innerEl.html() ? this.$innerEl : '');
return this;
},
renderOneAuth: function (authModel) {
var authViewEl, authView, authViewName;
var type = authModel.get('type');
if (type === 'apiKey') {
authViewName = 'ApiKeyAuthView';
} else if (type === 'basic' && this.$innerEl.find('.basic_auth_container').length === 0) {
authViewName = 'BasicAuthView';
} else if (type === 'oauth2') {
authViewName = 'Oauth2View';
}
if (authViewName) {
authView = new SwaggerUi.Views[authViewName]({model: authModel, router: this.router});
authViewEl = authView.render().el;
this.authViews.push(authView);
}
this.$innerEl.append(authViewEl);
},
highlightInvalid: function () {
this.authViews.forEach(function (view) {
view.highlightInvalid();
}, this);
}
});
'use strict';
/* global redirect_uri:true */
/* global clientId */
/* global scopeSeparator */
/* global additionalQueryStringParams */
/* global clientSecret */
/* global onOAuthComplete */
/* global realm */
/*jshint unused:false*/
SwaggerUi.Views.AuthView = Backbone.View.extend({
events: {
'click .auth_submit__button': 'authorizeClick',
'click .auth_logout__button': 'logoutClick'
},
tpls: {
main: Handlebars.templates.auth_view
},
selectors: {
innerEl: '.auth_inner',
authBtn: '.auth_submit__button'
},
initialize: function(opts) {
this.options = opts || {};
opts.data = opts.data || {};
this.router = this.options.router;
this.authsCollectionView = new SwaggerUi.Views.AuthsCollectionView({data: opts.data});
this.$el.html(this.tpls.main({
isLogout: this.authsCollectionView.collection.isAuthorized(),
isAuthorized: this.authsCollectionView.collection.isPartiallyAuthorized()
}));
this.$innerEl = this.$(this.selectors.innerEl);
this.isLogout = this.authsCollectionView.collection.isPartiallyAuthorized();
},
render: function () {
this.$innerEl.html(this.authsCollectionView.render().el);
return this;
},
authorizeClick: function (e) {
e.preventDefault();
e.stopPropagation();
if (this.authsCollectionView.collection.isValid()) {
this.authorize();
} else {
this.authsCollectionView.highlightInvalid();
}
},
authorize: function () {
this.authsCollectionView.collection.forEach(function (auth) {
var keyAuth, basicAuth;
var type = auth.get('type');
if (type === 'apiKey') {
keyAuth = new SwaggerClient.ApiKeyAuthorization(
auth.get('name'),
auth.get('value'),
auth.get('in')
);
this.router.api.clientAuthorizations.add(auth.get('title'), keyAuth);
} else if (type === 'basic') {
basicAuth = new SwaggerClient.PasswordAuthorization(auth.get('username'), auth.get('password'));
this.router.api.clientAuthorizations.add(auth.get('title'), basicAuth);
} else if (type === 'oauth2') {
this.handleOauth2Login(auth);
}
}, this);
this.router.load();
},
logoutClick: function (e) {
e.preventDefault();
this.authsCollectionView.collection.forEach(function (auth) {
window.swaggerUi.api.clientAuthorizations.remove(auth.get('title'));
});
this.router.load();
},
// taken from lib/swagger-oauth.js
handleOauth2Login: function (auth) {
var host = window.location;
var pathname = location.pathname.substring(0, location.pathname.lastIndexOf('/'));
var defaultRedirectUrl = host.protocol + '//' + host.host + pathname + '/o2c.html';
var redirectUrl = window.oAuthRedirectUrl || defaultRedirectUrl;
var url = null;
var scopes = _.map(auth.get('scopes'), function (scope) {
if(scope.checked) {
return scope.scope;
}
});
var container = window.swaggerUiAuth || (window.swaggerUiAuth = {});
var state, dets, ep;
container.OAuthSchemeKey = auth.get('title');
window.enabledScopes = scopes;
var flow = auth.get('flow');
/**
* Returns the name of the access token parameter returned by the server.
*
* @param dets
* The authorisation scheme configuration.
* @return the name of the access token parameter
*/
function getTokenName(dets) {
return dets.vendorExtensions['x-tokenName'] || dets.tokenName;
}
if(auth.get('type') === 'oauth2' && flow && (flow === 'implicit' || flow === 'accessCode')) {
dets = auth.attributes;
url = dets.authorizationUrl + '?response_type=' + (flow === 'implicit' ? 'token' : 'code');
container.tokenName = getTokenName(dets) || 'access_token';
container.tokenUrl = (flow === 'accessCode' ? dets.tokenUrl : null);
state = container.OAuthSchemeKey;
}
else if(auth.get('type') === 'oauth2' && flow && (flow === 'application')) {
dets = auth.attributes;
container.tokenName = getTokenName(dets) || 'access_token';
this.clientCredentialsFlow(scopes, dets, container.OAuthSchemeKey);
return;
}
else if(auth.get('type') === 'oauth2' && flow && (flow === 'password')) {
dets = auth.attributes;
container.tokenName = getTokenName(dets) || 'access_token';
this.passwordFlow(scopes, dets, container.OAuthSchemeKey);
return;
}
else if(auth.get('grantTypes')) {
// 1.2 support
var o = auth.get('grantTypes');
for(var t in o) {
if(o.hasOwnProperty(t) && t === 'implicit') {
dets = o[t];
ep = dets.loginEndpoint.url;
url = dets.loginEndpoint.url + '?response_type=token';
container.tokenName = getTokenName(dets);
}
else if (o.hasOwnProperty(t) && t === 'accessCode') {
dets = o[t];
ep = dets.tokenRequestEndpoint.url;
url = dets.tokenRequestEndpoint.url + '?response_type=code';
container.tokenName = getTokenName(dets);
}
}
}
redirect_uri = redirectUrl;
url += '&redirect_uri=' + encodeURIComponent(redirectUrl);
url += '&realm=' + encodeURIComponent(realm);
url += '&client_id=' + encodeURIComponent(clientId);
url += '&scope=' + encodeURIComponent(scopes.join(scopeSeparator));
url += '&state=' + encodeURIComponent(state);
for (var key in additionalQueryStringParams) {
url += '&' + key + '=' + encodeURIComponent(additionalQueryStringParams[key]);
}
window.open(url);
},
// taken from lib/swagger-oauth.js
clientCredentialsFlow: function (scopes, oauth, OAuthSchemeKey) {
this.accessTokenRequest(scopes, oauth, OAuthSchemeKey, 'client_credentials');
},
passwordFlow: function (scopes, oauth, OAuthSchemeKey) {
this.accessTokenRequest(scopes, oauth, OAuthSchemeKey, 'password', {
'username': oauth.username,
'password': oauth.password
});
},
accessTokenRequest: function (scopes, oauth, OAuthSchemeKey, grantType, params) {
params = $.extend({}, {
'scope': scopes.join(' '),
'grant_type': grantType
}, params);
var headers= {};
switch (oauth.clientAuthenticationType) {
case 'basic':
headers.Authorization = 'Basic ' + btoa(oauth.clientId + ':' + oauth.clientSecret);
break;
case 'request-body':
params.client_id = oauth.clientId;
params.client_secret = oauth.clientSecret;
break;
}
$.ajax({
url : oauth.tokenUrl,
type: 'POST',
data: params,
headers: headers,
success: function (data)
{
onOAuthComplete(data, OAuthSchemeKey);
},
error: function ()
{
onOAuthComplete('');
}
});
}
});
'use strict';
SwaggerUi.Models.BasicAuthModel = Backbone.Model.extend({
defaults: {
username: '',
password: '',
title: 'basic'
},
initialize: function () {
this.on('change', this.validate);
},
validate: function () {
var valid = !!this.get('password') && !!this.get('username');
this.set('valid', valid);
return valid;
}
});
'use strict';
SwaggerUi.Views.BasicAuthView = Backbone.View.extend({
initialize: function (opts) {
this.options = opts || {};
this.router = this.options.router;
},
events: {
'change .auth_input': 'inputChange'
},
selectors: {
usernameInput: '.basic_auth__username',
passwordInput: '.basic_auth__password'
},
cls: {
error: 'error'
},
template: Handlebars.templates.basic_auth,
render: function(){
$(this.el).html(this.template(this.model.toJSON()));
return this;
},
inputChange: function (e) {
var $el = $(e.target);
var val = $el.val();
var attr = $el.prop('name');
if (val) {
$el.removeClass(this.cls.error);
}
this.model.set(attr, val);
},
isValid: function () {
return this.model.validate();
},
highlightInvalid: function () {
if (!this.model.get('username')) {
this.$(this.selectors.usernameInput).addClass(this.cls.error);
}
}
});
'use strict';
SwaggerUi.Views.ContentTypeView = Backbone.View.extend({
initialize: function() {},
render: function(){
this.model.contentTypeId = 'ct' + Math.random();
$(this.el).html(Handlebars.templates.content_type(this.model));
return this;
}
});
'use strict';
SwaggerUi.Views.HeaderView = Backbone.View.extend({
events: {
'click #show-pet-store-icon' : 'showPetStore',
'click #explore' : 'showCustom',
'submit #api_selector' : 'showCustom',
'keyup #input_baseUrl' : 'showCustomOnKeyup',
'keyup #input_apiKey' : 'showCustomOnKeyup'
},
initialize: function(){},
showPetStore: function(){
this.trigger('update-swagger-ui', {
url:'http://petstore.swagger.io/v2/swagger.json'
});
},
showCustomOnKeyup: function(e){
if (e.keyCode === 13) {
this.showCustom();
}
},
showCustom: function(e){
if (e) {
e.preventDefault();
}
this.trigger('update-swagger-ui', {
url: $('#input_baseUrl').val()
});
},
update: function(url, apiKey, trigger){
if (trigger === undefined) {
trigger = false;
}
$('#input_baseUrl').val(url);
if (trigger) {
this.trigger('update-swagger-ui', {url:url});
}
}
});
'use strict';
SwaggerUi.Views.MainView = Backbone.View.extend({
apisSorter : {
alpha : function(a,b){ return a.name.localeCompare(b.name); }
},
operationsSorters : {
alpha : function(a,b){ return a.path.localeCompare(b.path); },
method : function(a,b){ return a.method.localeCompare(b.method); }
},
initialize: function(opts){
var sorterOption, sorterFn, key, value;
opts = opts || {};
this.router = opts.router;
// Sort APIs
if (opts.swaggerOptions.apisSorter) {
sorterOption = opts.swaggerOptions.apisSorter;
if (_.isFunction(sorterOption)) {
sorterFn = sorterOption;
} else {
sorterFn = this.apisSorter[sorterOption];
}
if (_.isFunction(sorterFn)) {
this.model.apisArray.sort(sorterFn);
}
}
// Sort operations of each API
if (opts.swaggerOptions.operationsSorter) {
sorterOption = opts.swaggerOptions.operationsSorter;
if (_.isFunction(sorterOption)) {
sorterFn = sorterOption;
} else {
sorterFn = this.operationsSorters[sorterOption];
}
if (_.isFunction(sorterFn)) {
for (key in this.model.apisArray) {
this.model.apisArray[key].operationsArray.sort(sorterFn);
}
}
}
// set up the UI for input
this.model.auths = [];
for (key in this.model.securityDefinitions) {
value = this.model.securityDefinitions[key];
this.model.auths.push({
name: key,
type: value.type,
value: value
});
}
if ('validatorUrl' in opts.swaggerOptions) {
// Validator URL specified explicitly
this.model.validatorUrl = opts.swaggerOptions.validatorUrl;
} else if (this.model.url.indexOf('localhost') > 0 || this.model.url.indexOf('127.0.0.1') > 0) {
// Localhost override
this.model.validatorUrl = null;
} else {
this.model.validatorUrl = '//online.swagger.io/validator';
}
// JSonEditor requires type='object' to be present on defined types, we add it if it's missing
// is there any valid case were it should not be added ?
var def;
for(def in this.model.definitions){
if (!this.model.definitions[def].type){
this.model.definitions[def].type = 'object';
}
}
},
render: function () {
$(this.el).html(Handlebars.templates.main(this.model));
this.info = this.$('.info')[0];
if (this.info) {
this.info.addEventListener('click', this.onLinkClick, true);
}
this.model.securityDefinitions = this.model.securityDefinitions || {};
// Render each resource
var resources = {};
var counter = 0;
for (var i = 0; i < this.model.apisArray.length; i++) {
var resource = this.model.apisArray[i];
var id = resource.name;
while (typeof resources[id] !== 'undefined') {
id = id + '_' + counter;
counter += 1;
}
resource.id = sanitizeHtml(id);
resources[id] = resource;
this.addResource(resource, this.model.auths);
}
$('.propWrap').hover(function onHover(){
$('.optionsWrapper', $(this)).show();
}, function offhover(){
$('.optionsWrapper', $(this)).hide();
});
return this;
},
addResource: function(resource, auths){
// Render a resource and add it to resources li
resource.id = resource.id.replace(/[^a-zA-Z\d]/g, function(str) { return str.charCodeAt(0); });
// Make all definitions available at the root of the resource so that they can
// be loaded by the JSonEditor
resource.definitions = this.model.definitions;
var resourceView = new SwaggerUi.Views.ResourceView({
model: resource,
router: this.router,
tagName: 'li',
id: 'resource_' + resource.id,
className: 'resource',
auths: auths,
swaggerOptions: this.options.swaggerOptions
});
$('#resources', this.el).append(resourceView.render().el);
},
clear: function(){
$(this.el).html('');
},
onLinkClick: function (e) {
var el = e.target;
if (el.tagName === 'A' && el.href && !el.target) {
e.preventDefault();
window.open(el.href, '_blank');
}
}
});
'use strict';
SwaggerUi.Models.Oauth2Model = Backbone.Model.extend({
defaults: {
scopes: {},
isPasswordFlow: false,
clientAuthenticationType: 'none'
},
initialize: function () {
if(this.attributes && this.attributes.scopes) {
var attributes = _.cloneDeep(this.attributes);
var i, scopes = [];
for(i in attributes.scopes) {
var scope = attributes.scopes[i];
if(typeof scope.description === 'string') {
scopes[scope] = attributes.scopes[i];
scopes.push(attributes.scopes[i]);
}
}
attributes.scopes = scopes;
this.attributes = attributes;
}
if (this.attributes && this.attributes.flow) {
var flow = this.attributes.flow;
this.set('isPasswordFlow', flow === 'password');
this.set('requireClientAuthentication', flow === 'application');
this.set('clientAuthentication', flow === 'password' || flow === 'application');
}
this.on('change', this.validate);
},
setScopes: function (name, val) {
var auth = _.extend({}, this.attributes);
var index = _.findIndex(auth.scopes, function(o) {
return o.scope === name;
});
auth.scopes[index].checked = val;
this.set(auth);
this.validate();
},
validate: function () {
var valid = false;
if (this.get('isPasswordFlow') &&
(!this.get('username'))) {
return false;
}
if (this.get('clientAuthenticationType') in ['basic', 'request-body'] &&
(!this.get('clientId'))) {
return false;
}
var scp = this.get('scopes');
var idx = _.findIndex(scp, function (o) {
return o.checked === true;
});
if(scp.length > 0 && idx >= 0) {
valid = true;
}
if(scp.length === 0) {
valid = true;
}
this.set('valid', valid);
return valid;
}
});
'use strict';
SwaggerUi.Views.Oauth2View = Backbone.View.extend({
events: {
'change .oauth-scope': 'scopeChange',
'change .oauth-username': 'setUsername',
'change .oauth-password': 'setPassword',
'change .oauth-client-authentication-type': 'setClientAuthenticationType',
'change .oauth-client-id': 'setClientId',
'change .oauth-client-secret': 'setClientSecret'
},
template: Handlebars.templates.oauth2,
cls: {
error: 'error'
},
render: function () {
this.$el.html(this.template(this.model.toJSON()));
return this;
},
scopeChange: function (e) {
var val = $(e.target).prop('checked');
var scope = $(e.target).data('scope');
this.model.setScopes(scope, val);
},
setUsername: function (e) {
var val= $(e.target).val();
this.model.set('username', val);
if (val) {
$(e.target).removeClass(this.cls.error);
}
},
setPassword: function (e) {
this.model.set('password', $(e.target).val());
},
setClientAuthenticationType: function (e) {
var type = $(e.target).val();
var $el = this.$el;
this.model.set('clientAuthenticationType', type);
switch(type) {
case 'none':
$el.find('.oauth-client-authentication').hide();
break;
case 'basic':
case 'request-body':
$el.find('.oauth-client-id').removeClass(this.cls.error);
$el.find('.oauth-client-authentication').show();
break;
}
},
setClientId: function (e) {
var val = $(e.target).val();
this.model.set('clientId', val);
if (val) {
$(e.target).removeClass(this.cls.error);
}
},
setClientSecret: function (e) {
this.model.set('clientSecret', $(e.target).val());
$(e.target).removeClass('error');
},
highlightInvalid: function () {
if (!this.model.get('username')) {
this.$el.find('.oauth-username').addClass(this.cls.error);
}
if (!this.model.get('clientId')) {
this.$el.find('.oauth-client-id').addClass(this.cls.error);
}
}
});
'use strict';
SwaggerUi.Views.OperationView = Backbone.View.extend({
invocationUrl: null,
events: {
'submit .sandbox' : 'submitOperation',
'click .submit' : 'submitOperation',
'click .response_hider' : 'hideResponse',
'click .toggleOperation' : 'toggleOperationContent',
'mouseenter .api-ic' : 'mouseEnter',
'dblclick .curl' : 'selectText',
'change [name=responseContentType]' : 'showSnippet'
},
initialize: function(opts) {
opts = opts || {};
this.router = opts.router;
this.auths = opts.auths;
this.parentId = this.model.parentId;
this.nickname = this.model.nickname;
this.model.encodedParentId = encodeURIComponent(this.parentId);
if (opts.swaggerOptions) {
this.model.defaultRendering = opts.swaggerOptions.defaultModelRendering;
if (opts.swaggerOptions.showRequestHeaders) {
this.model.showRequestHeaders = true;
}
if (opts.swaggerOptions.showOperationIds) {
this.model.showOperationIds = true;
}
}
return this;
},
selectText: function(event) {
var doc = document,
text = event.target.firstChild,
range,
selection;
if (doc.body.createTextRange) {
range = document.body.createTextRange();
range.moveToElementText(text);
range.select();
} else if (window.getSelection) {
selection = window.getSelection();
range = document.createRange();
range.selectNodeContents(text);
selection.removeAllRanges();
selection.addRange(range);
}
},
mouseEnter: function(e) {
var elem = $(this.el).find('.content');
var x = e.pageX;
var y = e.pageY;
var scX = $(window).scrollLeft();
var scY = $(window).scrollTop();
var scMaxX = scX + $(window).width();
var scMaxY = scY + $(window).height();
var wd = elem.width();
var hgh = elem.height();
if (x + wd > scMaxX) {
x = scMaxX - wd;
}
if (x < scX) {
x = scX;
}
if (y + hgh > scMaxY) {
y = scMaxY - hgh;
}
if (y < scY) {
y = scY;
}
var pos = {};
pos.top = y;
pos.left = x;
elem.css(pos);
},
// Note: copied from CoffeeScript compiled file
// TODO: refactor
render: function() {
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;
isMethodSubmissionSupported = jQuery.inArray(this.model.method, this.model.supportedSubmitMethods()) >= 0;
if (!isMethodSubmissionSupported) {
this.model.isReadOnly = true;
}
this.model.description = this.model.description || this.model.notes;
this.model.oauth = null;
modelAuths = this.model.authorizations || this.model.security;
if (modelAuths) {
if (Array.isArray(modelAuths)) {
for (l = 0, len = modelAuths.length; l < len; l++) {
auths = modelAuths[l];
for (key in auths) {
for (a in this.auths) {
auth = this.auths[a];
if (key === auth.name) {
if (auth.type === 'oauth2') {
this.model.oauth = {};
this.model.oauth.scopes = [];
ref1 = auth.value.scopes;
for (k in ref1) {
v = ref1[k];
scopeIndex = auths[key].indexOf(k);
if (scopeIndex >= 0) {
o = {
scope: k,
description: v
};
this.model.oauth.scopes.push(o);
}
}
}
}
}
}
}
} else {
for (k in modelAuths) {
v = modelAuths[k];
if (k === 'oauth2') {
if (this.model.oauth === null) {
this.model.oauth = {};
}
if (this.model.oauth.scopes === void 0) {
this.model.oauth.scopes = [];
}
for (m = 0, len1 = v.length; m < len1; m++) {
o = v[m];
this.model.oauth.scopes.push(o);
}
}
}
}
}
if (typeof this.model.responses !== 'undefined') {
this.model.responseMessages = [];
ref2 = this.model.responses;
for (code in ref2) {
value = ref2[code];
schema = null;
schemaObj = this.model.responses[code].schema;
if (schemaObj && schemaObj.$ref) {
schema = schemaObj.$ref;
if (schema.indexOf('#/definitions/') !== -1) {
schema = schema.replace(/^.*#\/definitions\//, '');
}
}
this.model.responseMessages.push({
code: code,
message: value.description,
responseModel: schema,
headers: value.headers,
schema: schemaObj
});
}
}
if (typeof this.model.responseMessages === 'undefined') {
this.model.responseMessages = [];
}
signatureModel = null;
produces = this.model.produces;
isXML = this.contains(produces, 'xml');
isJSON = isXML ? this.contains(produces, 'json') : true;
if (this.model.successResponse) {
successResponse = this.model.successResponse;
for (key in successResponse) {
value = successResponse[key];
this.model.successCode = key;
if (typeof value === 'object' && typeof value.createJSONSample === 'function') {
this.model.successDescription = value.description;
this.model.headers = this.parseResponseHeaders(value.headers);
signatureModel = {
sampleJSON: isJSON ? JSON.stringify(SwaggerUi.partials.signature.createJSONSample(value), void 0, 2) : false,
isParam: false,
sampleXML: isXML ? SwaggerUi.partials.signature.createXMLSample(value.name, value.definition, value.models) : false,
signature: SwaggerUi.partials.signature.getModelSignature(value.name, value.definition, value.models, value.modelPropertyMacro)
};
} else {
signatureModel = {
signature: SwaggerUi.partials.signature.getPrimitiveSignature(value)
};
}
}
} else if (this.model.responseClassSignature && this.model.responseClassSignature !== 'string') {
signatureModel = {
sampleJSON: this.model.responseSampleJSON,
isParam: false,
signature: this.model.responseClassSignature
};
}
$(this.el).html(Handlebars.templates.operation(this.model));
if (signatureModel) {
signatureModel.defaultRendering = this.model.defaultRendering;
responseSignatureView = new SwaggerUi.Views.SignatureView({
model: signatureModel,
router: this.router,
tagName: 'div'
});
$('.model-signature', $(this.el)).append(responseSignatureView.render().el);
} else {
this.model.responseClassSignature = 'string';
$('.model-signature', $(this.el)).html(this.model.type);
}
contentTypeModel = {
isParam: false
};
contentTypeModel.consumes = this.model.consumes;
contentTypeModel.produces = this.model.produces;
ref3 = this.model.parameters;
for (n = 0, len2 = ref3.length; n < len2; n++) {
param = ref3[n];
type = param.type || param.dataType || '';
if (typeof type === 'undefined') {
schema = param.schema;
if (schema && schema.$ref) {
ref = schema.$ref;
if (ref.indexOf('#/definitions/') === 0) {
type = ref.substring('#/definitions/'.length);
} else {
type = ref;
}
}
}
if (type && type.toLowerCase() === 'file') {
if (!contentTypeModel.consumes) {
contentTypeModel.consumes = 'multipart/form-data';
}
}
param.type = type;
}
responseContentTypeView = new SwaggerUi.Views.ResponseContentTypeView({
model: contentTypeModel,
router: this.router
});
$('.response-content-type', $(this.el)).append(responseContentTypeView.render().el);
ref4 = this.model.parameters;
for (p = 0, len3 = ref4.length; p < len3; p++) {
param = ref4[p];
this.addParameter(param, contentTypeModel.consumes);
}
ref5 = this.model.responseMessages;
for (q = 0, len4 = ref5.length; q < len4; q++) {
statusCode = ref5[q];
statusCode.isXML = isXML;
statusCode.isJSON = isJSON;
if (!_.isUndefined(statusCode.headers)) {
statusCode.headers = this.parseHeadersType(statusCode.headers);
}
this.addStatusCode(statusCode);
}
if (Array.isArray(this.model.security)) {
var authsModel = SwaggerUi.utils.parseSecurityDefinitions(this.model.security, this.model.parent.securityDefinitions);
authsModel.isLogout = !_.isEmpty(this.model.clientAuthorizations.authz);
this.authView = new SwaggerUi.Views.AuthButtonView({
data: authsModel,
router: this.router,
isOperation: true,
model: {
scopes: authsModel.scopes
}
});
this.$('.authorize-wrapper').append(this.authView.render().el);
}
this.showSnippet();
return this;
},
parseHeadersType: function (headers) {
var map = {
'string': {
'date-time': 'dateTime',
'date' : 'date'
}
};
_.forEach(headers, function (header) {
var value;
header = header || {};
value = map[header.type] && map[header.type][header.format];
if (!_.isUndefined(value)) {
header.type = value;
}
});
return headers;
},
contains: function (produces, type) {
return produces.filter(function (val) {
if (val.indexOf(type) > -1) {
return true;
}
}).length;
},
parseResponseHeaders: function (data) {
var HEADERS_SEPARATOR = '; ';
var headers = _.clone(data);
_.forEach(headers, function (header) {
var other = [];
_.forEach(header, function (value, key) {
var properties = ['type', 'description'];
if (properties.indexOf(key.toLowerCase()) === -1) {
other.push(key + ': ' + value);
}
});
other.join(HEADERS_SEPARATOR);
header.other = other;
});
return headers;
},
addParameter: function(param, consumes) {
// Render a parameter
param.consumes = consumes;
param.defaultRendering = this.model.defaultRendering;
// Copy this param JSON spec so that it will be available for JsonEditor
if(param.schema){
$.extend(true, param.schema, this.model.definitions[param.type]);
param.schema.definitions = this.model.definitions;
// This is required for JsonEditor to display the root properly
if(!param.schema.type){
param.schema.type = 'object';
}
// This is the title that will be used by JsonEditor for the root
// Since we already display the parameter's name in the Parameter column
// We set this to space, we can't set it to null or space otherwise JsonEditor
// will replace it with the text "root" which won't look good on screen
if(!param.schema.title){
param.schema.title = ' ';
}
}
var paramView = new SwaggerUi.Views.ParameterView({
model: param,
tagName: 'tr',
readOnly: this.model.isReadOnly,
swaggerOptions: this.options.swaggerOptions
});
$('.operation-params', $(this.el)).append(paramView.render().el);
},
addStatusCode: function(statusCode) {
// Render status codes
statusCode.defaultRendering = this.model.defaultRendering;
var statusCodeView = new SwaggerUi.Views.StatusCodeView({
model: statusCode,
tagName: 'tr',
router: this.router
});
$('.operation-status', $(this.el)).append(statusCodeView.render().el);
},
// Note: copied from CoffeeScript compiled file
// TODO: redactor
submitOperation: function(e) {
var error_free, form, isFileUpload, map, opts;
if (e !== null) {
e.preventDefault();
}
form = $('.sandbox', $(this.el));
error_free = true;
form.find('input.required').each(function() {
$(this).removeClass('error');
if (jQuery.trim($(this).val()) === '') {
$(this).addClass('error');
$(this).wiggle({
callback: (function(_this) {
return function() {
$(_this).focus();
};
})(this)
});
error_free = false;
}
});
form.find('textarea.required:visible').each(function() {
$(this).removeClass('error');
if (jQuery.trim($(this).val()) === '') {
$(this).addClass('error');
$(this).wiggle({
callback: (function(_this) {
return function() {
return $(_this).focus();
};
})(this)
});
error_free = false;
}
});
form.find('select.required').each(function() {
$(this).removeClass('error');
if (this.selectedIndex === -1) {
$(this).addClass('error');
$(this).wiggle({
callback: (function(_this) {
return function() {
$(_this).focus();
};
})(this)
});
error_free = false;
}
});
if (error_free) {
map = this.getInputMap(form);
isFileUpload = this.isFileUpload(form);
opts = {
parent: this
};
if (this.options.swaggerOptions) {
for(var key in this.options.swaggerOptions) {
opts[key] = this.options.swaggerOptions[key];
}
}
var pi;
for(pi = 0; pi < this.model.parameters.length; pi++){
var p = this.model.parameters[pi];
if( p.jsonEditor && p.jsonEditor.isEnabled()){
var json = p.jsonEditor.getValue();
map[p.name] = JSON.stringify(json);
}
}
opts.responseContentType = $('div select[name=responseContentType]', $(this.el)).val();
opts.requestContentType = $('div select[name=parameterContentType]', $(this.el)).val();
$('.response_throbber', $(this.el)).show();
if (isFileUpload) {
$('.request_url', $(this.el)).html('<pre></pre>');
$('.request_url pre', $(this.el)).text(this.invocationUrl);
opts.useJQuery = true;
map.parameterContentType = 'multipart/form-data';
this.map = map;
return this.model.execute(map, opts, this.showCompleteStatus, this.showErrorStatus, this);
} else {
this.map = map;
return this.model.execute(map, opts, this.showCompleteStatus, this.showErrorStatus, this);
}
}
},
getInputMap: function (form) {
var map, ref1, l, len, o, ref2, m, len1, val, ref3, n, len2;
map = {};
ref1 = form.find('input');
for (l = 0, len = ref1.length; l < len; l++) {
o = ref1[l];
if ((o.value !== null) && jQuery.trim(o.value).length > 0) {
map[o.name] = o.value;
}
if (o.type === 'file') {
map[o.name] = o.files[0];
}
}
ref2 = form.find('textarea');
for (m = 0, len1 = ref2.length; m < len1; m++) {
o = ref2[m];
val = this.getTextAreaValue(o);
if ((val !== null) && jQuery.trim(val).length > 0) {
map[o.name] = val;
}
}
ref3 = form.find('select');
for (n = 0, len2 = ref3.length; n < len2; n++) {
o = ref3[n];
val = this.getSelectedValue(o);
if ((val !== null) && jQuery.trim(val).length > 0) {
map[o.name] = val;
}
}
return map;
},
isFileUpload: function (form) {
var ref1, l, len, o;
var isFileUpload = false;
ref1 = form.find('input');
for (l = 0, len = ref1.length; l < len; l++) {
o = ref1[l];
if (o.type === 'file') {
isFileUpload = true;
}
}
return isFileUpload;
},
success: function(response, parent) {
parent.showCompleteStatus(response);
},
// wraps a jquery response as a shred response
wrap: function(data) {
var h, headerArray, headers, i, l, len, o;
headers = {};
headerArray = data.getAllResponseHeaders().split('\r');
for (l = 0, len = headerArray.length; l < len; l++) {
i = headerArray[l];
h = i.match(/^([^:]*?):(.*)$/);
if (!h) {
h = [];
}
h.shift();
if (h[0] !== void 0 && h[1] !== void 0) {
headers[h[0].trim()] = h[1].trim();
}
}
o = {};
o.content = {};
o.content.data = data.responseText;
o.headers = headers;
o.request = {};
o.request.url = this.invocationUrl;
o.status = data.status;
return o;
},
getSelectedValue: function(select) {
if (!select.multiple) {
return select.value;
} else {
var options = [];
for (var l = 0, len = select.options.length; l < len; l++) {
var opt = select.options[l];
if (opt.selected) {
options.push(opt.value);
}
}
if (options.length > 0) {
return options;
} else {
return null;
}
}
},
// handler for hide response link
hideResponse: function(e) {
if (e) { e.preventDefault(); }
$('.response', $(this.el)).slideUp();
$('.response_hider', $(this.el)).fadeOut();
},
// Show response from server
showResponse: function(response) {
var prettyJson = JSON.stringify(response, null, '\t').replace(/\n/g, '<br>');
$('.response_body', $(this.el)).html(_.escape(prettyJson));
},
// Show error from server
showErrorStatus: function(data, parent) {
parent.showStatus(data);
},
// show the status codes
showCompleteStatus: function(data, parent){
parent.showStatus(data);
},
// Adapted from http://stackoverflow.com/a/2893259/454004
// Note: directly ported from CoffeeScript
// TODO: Cleanup CoffeeScript artifacts
formatXml: function(xml) {
var contexp, fn, formatted, indent, l, lastType, len, lines, ln, pad, reg, transitions, wsexp;
reg = /(>)(<)(\/*)/g;
wsexp = /[ ]*(.*)[ ]+\n/g;
contexp = /(<.+>)(.+\n)/g;
xml = xml.replace(/\r\n/g, '\n').replace(reg, '$1\n$2$3').replace(wsexp, '$1\n').replace(contexp, '$1\n$2');
pad = 0;
formatted = '';
lines = xml.split('\n');
indent = 0;
lastType = 'other';
transitions = {
'single->single': 0,
'single->closing': -1,
'single->opening': 0,
'single->other': 0,
'closing->single': 0,
'closing->closing': -1,
'closing->opening': 0,
'closing->other': 0,
'opening->single': 1,
'opening->closing': 0,
'opening->opening': 1,
'opening->other': 1,
'other->single': 0,
'other->closing': -1,
'other->opening': 0,
'other->other': 0
};
fn = function(ln) {
var fromTo, j, key, padding, type, types, value;
types = {
single: Boolean(ln.match(/<.+\/>/)),
closing: Boolean(ln.match(/<\/.+>/)),
opening: Boolean(ln.match(/<[^!?].*>/))
};
type = ((function() {
var results;
results = [];
for (key in types) {
value = types[key];
if (value) {
results.push(key);
}
}
return results;
})())[0];
type = type === void 0 ? 'other' : type;
fromTo = lastType + '->' + type;
lastType = type;
padding = '';
indent += transitions[fromTo];
padding = ((function() {
var m, ref1, results;
results = [];
for (j = m = 0, ref1 = indent; 0 <= ref1 ? m < ref1 : m > ref1; j = 0 <= ref1 ? ++m : --m) {
results.push(' ');
}
return results;
})()).join('');
if (fromTo === 'opening->closing') {
formatted = formatted.substr(0, formatted.length - 1) + ln + '\n';
} else {
formatted += padding + ln + '\n';
}
};
for (l = 0, len = lines.length; l < len; l++) {
ln = lines[l];
fn(ln);
}
return formatted;
},
// puts the response data in UI
showStatus: function(response) {
var url, content;
if (response.content === undefined) {
content = response.data;
url = response.url;
} else {
content = response.content.data;
url = response.request.url;
}
var headers = response.headers;
if(typeof content === 'string') {
content = jQuery.trim(content);
}
// if server is nice, and sends content-type back, we can use it
var contentType = null;
if (headers) {
contentType = headers['Content-Type'] || headers['content-type'];
if (contentType) {
contentType = contentType.split(';')[0].trim();
}
}
$('.response_body', $(this.el)).removeClass('json');
$('.response_body', $(this.el)).removeClass('xml');
var supportsAudioPlayback = function(contentType){
var audioElement = document.createElement('audio');
return !!(audioElement.canPlayType && audioElement.canPlayType(contentType).replace(/no/, ''));
};
var pre;
var code;
var skipHighlight = false;
if (!content) {
code = $('<code />').text('no content');
pre = $('<pre class="json" />').append(code);
// JSON
} else if (
contentType === 'application/octet-stream' ||
headers['Content-Disposition'] && (/attachment/).test(headers['Content-Disposition']) ||
headers['content-disposition'] && (/attachment/).test(headers['content-disposition']) ||
headers['Content-Description'] && (/File Transfer/).test(headers['Content-Description']) ||
headers['content-description'] && (/File Transfer/).test(headers['content-description'])) {
if ('Blob' in window) {
var type = contentType || 'text/html';
var a = document.createElement('a');
var href;
if({}.toString.apply(content) === '[object Blob]') {
href = window.URL.createObjectURL(content);
}
else {
var binaryData = [];
binaryData.push(content);
href = window.URL.createObjectURL(new Blob(binaryData, {type: type}));
}
var fileName = response.url.substr(response.url.lastIndexOf('/') + 1);
var download = [type, fileName, href].join(':');
// Use filename from response header
var disposition = headers['content-disposition'] || headers['Content-Disposition'];
if(typeof disposition !== 'undefined') {
var responseFilename = /filename=([^;]*);?/.exec(disposition);
if(responseFilename !== null && responseFilename.length > 1) {
download = responseFilename[1];
fileName = download;
}
}
a.setAttribute('href', href);
a.setAttribute('download', download);
a.innerText = 'Download ' + fileName;
pre = $('<div/>').append(a);
skipHighlight = true;
} else {
pre = $('<pre class="json" />').append('Download headers detected but your browser does not support downloading binary via XHR (Blob).');
}
} else if (contentType === 'application/json' || /\+json$/.test(contentType)) {
var json = null;
try {
json = JSON.stringify(JSON.parse(content), null, ' ');
} catch (_error) {
json = 'can\'t parse JSON. Raw result:\n\n' + content;
}
code = $('<code />').text(json);
pre = $('<pre class="json" />').append(code);
// XML
} else if (contentType === 'application/xml' || /\+xml$/.test(contentType)) {
code = $('<code />').text(this.formatXml(content));
pre = $('<pre class="xml" />').append(code);
// HTML
} else if (contentType === 'text/html') {
code = $('<code />').html(_.escape(content));
pre = $('<pre class="xml" />').append(code);
// Plain Text
} else if (/text\/plain/.test(contentType)) {
code = $('<code />').text(content);
pre = $('<pre class="plain" />').append(code);
// Image
} else if (/^image\//.test(contentType)) {
var urlCreator = window.URL || window.webkitURL;
var imageUrl = urlCreator.createObjectURL(content);
pre = $('<img>').attr( 'src', imageUrl);
// Audio
} else if (/^audio\//.test(contentType) && supportsAudioPlayback(contentType)) {
pre = $('<audio controls>').append($('<source>').attr('src', url).attr('type', contentType));
} else if(headers.location || headers.Location) {
// Location header based redirect download
window.location = response.url;
// Anything else (CORS)
} else {
code = $('<code />').text(content);
pre = $('<pre class="json" />').append(code);
}
var response_body = pre;
$('.request_url', $(this.el)).html('<pre></pre>');
$('.request_url pre', $(this.el)).text(url);
$('.response_code', $(this.el)).html('<pre>' + response.status + '</pre>');
$('.response_body', $(this.el)).html(response_body);
$('.response_headers', $(this.el)).html('<pre>' + _.escape(JSON.stringify(response.headers, null, ' ')).replace(/\n/g, '<br>') + '</pre>');
$('.response', $(this.el)).slideDown();
$('.response_hider', $(this.el)).show();
$('.response_throbber', $(this.el)).hide();
// adds curl output
var curlCommand = this.model.asCurl(this.map, {responseContentType: contentType});
curlCommand = curlCommand.replace('!', '&#33;');
$( 'div.curl', $(this.el)).html('<pre>' + _.escape(curlCommand) + '</pre>');
// only highlight the response if response is less than threshold, default state is highlight response
var opts = this.options.swaggerOptions;
if (opts.showRequestHeaders) {
var form = $('.sandbox', $(this.el)),
map = this.getInputMap(form),
requestHeaders = this.model.getHeaderParams(map);
delete requestHeaders['Content-Type'];
$('.request_headers', $(this.el)).html('<pre>' + _.escape(JSON.stringify(requestHeaders, null, ' ')).replace(/\n/g, '<br>') + '</pre>');
}
// Call user-defined hook
if (opts.responseHooks && opts.responseHooks[this.nickname]) {
opts.responseHooks[this.nickname](response, this);
}
var response_body_el = $('.response_body', $(this.el))[0];
// only highlight the response if response is less than threshold, default state is highlight response
if (opts.highlightSizeThreshold && typeof response.data !== 'undefined' && response.data.length > opts.highlightSizeThreshold || skipHighlight) {
return response_body_el;
} else {
return hljs.highlightBlock(response_body_el);
}
},
toggleOperationContent: function (event) {
var elem = $('#' + Docs.escapeResourceName(this.parentId + '_' + this.nickname + '_content'));
if (elem.is(':visible')){
$.bbq.pushState('#/', 2);
event.preventDefault();
Docs.collapseOperation(elem);
} else {
Docs.expandOperation(elem);
}
},
getTextAreaValue: function(textArea) {
var param, parsed, result, i;
if (textArea.value === null || jQuery.trim(textArea.value).length === 0) {
return null;
}
param = this.getParamByName(textArea.name);
if (param && param.type && param.type.toLowerCase() === 'array') {
parsed = textArea.value.split('\n');
result = [];
for (i = 0; i < parsed.length; i++) {
if (parsed[i] !== null && jQuery.trim(parsed[i]).length > 0) {
result.push(parsed[i]);
}
}
return result.length > 0 ? result : null;
} else {
return textArea.value;
}
},
showSnippet: function () {
var contentTypeEl = this.$('[name=responseContentType]');
var xmlSnippetEl = this.$('.operation-status .snippet_xml, .response-class .snippet_xml');
var jsonSnippetEl = this.$('.operation-status .snippet_json, .response-class .snippet_json');
var contentType;
if (!contentTypeEl.length) { return; }
contentType = contentTypeEl.val();
if (contentType.indexOf('xml') > -1) {
xmlSnippetEl.show();
jsonSnippetEl.hide();
} else {
jsonSnippetEl.show();
xmlSnippetEl.hide();
}
},
getParamByName: function(name) {
var i;
if (this.model.parameters) {
for(i = 0; i < this.model.parameters.length; i++) {
if (this.model.parameters[i].name === name) {
return this.model.parameters[i];
}
}
}
return null;
}
});
'use strict';
SwaggerUi.Views.ParameterContentTypeView = Backbone.View.extend({
initialize: function () {},
render: function(){
this.model.parameterContentTypeId = 'pct' + Math.random();
$(this.el).html(Handlebars.templates.parameter_content_type(this.model));
return this;
}
});
'use strict';
SwaggerUi.Views.ParameterView = Backbone.View.extend({
events: {
'change [name=parameterContentType]' : 'toggleParameterSnippet'
},
initialize: function(){
Handlebars.registerHelper('isArray', function(param, opts) {
var paramType = param.type && param.type.toLowerCase();
if (paramType === 'array' || param.allowMultiple) {
return opts.fn(this);
} else {
return opts.inverse(this);
}
});
},
render: function() {
var type = this.model.type || this.model.dataType;
var modelType = this.model.modelSignature.type;
var modelDefinitions = this.model.modelSignature.definitions;
var schema = this.model.schema || {};
var consumes = this.model.consumes || [];
var sampleJSON, signatureView;
if (typeof type === 'undefined') {
if (schema.$ref) {
var ref = schema.$ref;
if (ref.indexOf('#/definitions/') === 0) {
type = ref.substring('#/definitions/'.length);
} else {
type = ref;
}
}
}
this.model.type = type;
this.model.paramType = this.model.in || this.model.paramType;
this.model.isBody = this.model.paramType === 'body' || this.model.in === 'body';
this.model.isFile = type && type.toLowerCase() === 'file';
// Allow for default === false
if(typeof this.model.default === 'undefined') {
this.model.default = this.model.defaultValue;
}
this.model.hasDefault = (typeof this.model.default !== 'undefined');
this.model.valueId = 'm' + this.model.name + Math.random();
if (this.model.allowableValues) {
this.model.isList = true;
}
var isXML = this.contains(consumes, 'xml');
var isJSON = isXML ? this.contains(consumes, 'json') : true;
sampleJSON = SwaggerUi.partials.signature.createParameterJSONSample(modelType, modelDefinitions);
var template = this.template();
$(this.el).html(template(this.model));
var signatureModel = {
sampleJSON: isJSON ? sampleJSON : false,
sampleXML: sampleJSON && isXML ? SwaggerUi.partials.signature.createXMLSample('', schema, modelDefinitions, true) : false,
isParam: true,
signature: SwaggerUi.partials.signature.getParameterModelSignature(modelType, modelDefinitions),
defaultRendering: this.model.defaultRendering
};
if (sampleJSON) {
signatureView = new SwaggerUi.Views.SignatureView({model: signatureModel, tagName: 'div'});
$('.model-signature', $(this.el)).append(signatureView.render().el);
}
else {
$('.model-signature', $(this.el)).html(this.model.signature);
}
var isParam = false;
if( this.options.swaggerOptions.jsonEditor && this.model.isBody && this.model.schema){
var $self = $(this.el);
this.model.jsonEditor =
/* global JSONEditor */
new JSONEditor($('.editor_holder', $self)[0],
{schema: this.model.schema, startval : this.model.default,
ajax:true,
disable_properties:true,
disable_edit_json:true,
iconlib: 'swagger' });
// This is so that the signature can send back the sample to the json editor
// TODO: SignatureView should expose an event "onSampleClicked" instead
signatureModel.jsonEditor = this.model.jsonEditor;
$('.body-textarea', $self).hide();
$('.editor_holder', $self).show();
$('.parameter-content-type', $self)
.change(function(e){
if(e.target.value === 'application/xml'){
$('.body-textarea', $self).show();
$('.editor_holder', $self).hide();
this.model.jsonEditor.disable();
}
else {
$('.body-textarea', $self).hide();
$('.editor_holder', $self).show();
this.model.jsonEditor.enable();
}
});
}
if (this.model.isBody) {
isParam = true;
}
var contentTypeModel = {
isParam: isParam
};
contentTypeModel.consumes = this.model.consumes;
if (isParam) {
var parameterContentTypeView = new SwaggerUi.Views.ParameterContentTypeView({model: contentTypeModel});
$('.parameter-content-type', $(this.el)).append(parameterContentTypeView.render().el);
this.toggleParameterSnippet();
}
else {
var responseContentTypeView = new SwaggerUi.Views.ResponseContentTypeView({model: contentTypeModel});
$('.response-content-type', $(this.el)).append(responseContentTypeView.render().el);
this.toggleResponseSnippet();
}
return this;
},
contains: function (consumes, type) {
return consumes.filter(function (val) {
if (val.indexOf(type) > -1) {
return true;
}
}).length;
},
toggleParameterSnippet: function () {
var contentType = this.$('[name=parameterContentType]').val();
this.toggleSnippet(contentType);
},
toggleResponseSnippet: function () {
var contentEl = this.$('[name=responseContentType]');
if (!contentEl.length) { return; }
this.toggleSnippet(contentEl.val());
},
toggleSnippet: function (type) {
type = type || '';
if (type.indexOf('xml') > -1) {
this.$('.snippet_xml').show();
this.$('.snippet_json').hide();
} else {
this.$('.snippet_json').show();
this.$('.snippet_xml').hide();
}
},
// Return an appropriate template based on if the parameter is a list, readonly, required
template: function(){
if (this.model.isList) {
return Handlebars.templates.param_list;
} else {
if (this.options.readOnly) {
if (this.model.required) {
return Handlebars.templates.param_readonly_required;
} else {
return Handlebars.templates.param_readonly;
}
} else {
if (this.model.required) {
return Handlebars.templates.param_required;
} else {
return Handlebars.templates.param;
}
}
}
}
});
'use strict';
/* jshint -W122 */
SwaggerUi.partials.signature = (function () {
// copy-pasted from swagger-js
var resolveSchema = function (schema) {
if (_.isPlainObject(schema.schema)) {
schema = resolveSchema(schema.schema);
}
return schema;
};
// copy-pasted from swagger-js
var simpleRef = function (name) {
if (typeof name === 'undefined') {
return null;
}
if (name.indexOf('#/definitions/') === 0) {
return name.substring('#/definitions/'.length);
} else {
return name;
}
};
// copy-pasted from swagger-js
var getInlineModel = function(inlineStr) {
if(/^Inline Model \d+$/.test(inlineStr) && this.inlineModels) {
var id = parseInt(inlineStr.substr('Inline Model'.length).trim(),10); //
var model = this.inlineModels[id];
return model;
}
// I'm returning null here, should I rather throw an error?
return null;
};
// copy-pasted from swagger-js
var formatXml = function(xml) {
var contexp, fn, formatted, indent, l, lastType, len, lines, ln, pad, reg, transitions, wsexp;
reg = /(>)(<)(\/*)/g;
wsexp = /[ ]*(.*)[ ]+\n/g;
contexp = /(<.+>)(.+\n)/g;
xml = xml.replace(reg, '$1\n$2$3').replace(wsexp, '$1\n').replace(contexp, '$1\n$2');
pad = 0;
formatted = '';
lines = xml.split('\n');
indent = 0;
lastType = 'other';
transitions = {
'single->single': 0,
'single->closing': -1,
'single->opening': 0,
'single->other': 0,
'closing->single': 0,
'closing->closing': -1,
'closing->opening': 0,
'closing->other': 0,
'opening->single': 1,
'opening->closing': 0,
'opening->opening': 1,
'opening->other': 1,
'other->single': 0,
'other->closing': -1,
'other->opening': 0,
'other->other': 0
};
fn = function(ln) {
var fromTo, j, key, padding, type, types, value;
types = {
single: Boolean(ln.match(/<.+\/>/)),
closing: Boolean(ln.match(/<\/.+>/)),
opening: Boolean(ln.match(/<[^!?].*>/))
};
type = ((function() {
var results;
results = [];
for (key in types) {
value = types[key];
if (value) {
results.push(key);
}
}
return results;
})())[0];
type = type === void 0 ? 'other' : type;
fromTo = lastType + '->' + type;
lastType = type;
padding = '';
indent += transitions[fromTo];
padding = ((function() {
var m, ref1, results;
results = [];
for (j = m = 0, ref1 = indent; 0 <= ref1 ? m < ref1 : m > ref1; j = 0 <= ref1 ? ++m : --m) {
results.push(' ');
}
return results;
})()).join('');
if (fromTo === 'opening->closing') {
formatted = formatted.substr(0, formatted.length - 1) + ln + '\n';
} else {
formatted += padding + ln + '\n';
}
};
for (l = 0, len = lines.length; l < len; l++) {
ln = lines[l];
fn(ln);
}
return formatted;
};
// copy-pasted from swagger-js
var getModelSignature = function (name, schema, models, modelPropertyMacro) {
var strongOpen = '<span class="strong">';
var strongClose = '</span>';
var optionHtml = function (label, value) {
return '<tr><td class="optionName">' + label + ':</td><td>' + value + '</td></tr>';
};
// Allow for ignoring the 'name' argument.... shifting the rest
if(_.isObject(arguments[0])) {
name = void 0;
schema = arguments[0];
models = arguments[1];
modelPropertyMacro = arguments[2];
}
models = models || {};
// Resolve the schema (Handle nested schemas)
schema = resolveSchema(schema);
// Return for empty object
if(_.isEmpty(schema)) {
return strongOpen + 'Empty' + strongClose;
}
// Dereference $ref from 'models'
if(typeof schema.$ref === 'string') {
name = simpleRef(schema.$ref);
schema = models[name];
if(typeof schema === 'undefined')
{
return strongOpen + name + ' is not defined!' + strongClose;
}
}
if(typeof name !== 'string') {
name = schema.title || 'Inline Model';
}
// If we are a Model object... adjust accordingly
if(schema.definition) {
schema = schema.definition;
}
if(typeof modelPropertyMacro !== 'function') {
modelPropertyMacro = function(prop){
return (prop || {}).default;
};
}
var references = {};
var seenModels = [];
var inlineModels = 0;
// Generate current HTML
var html = processModel(schema, name);
// Generate references HTML
while (_.keys(references).length > 0) {
/* jshint ignore:start */
_.forEach(references, function (schema, name) {
var seenModel = _.indexOf(seenModels, name) > -1;
delete references[name];
if (!seenModel) {
seenModels.push(name);
html += '<br />' + processModel(schema, name);
}
});
/* jshint ignore:end */
}
return html;
function addReference(schema, name, skipRef) {
var modelName = name;
var model;
if (schema.$ref) {
modelName = schema.title || simpleRef(schema.$ref);
model = models[simpleRef(schema.$ref)];
} else if (_.isUndefined(name)) {
modelName = schema.title || 'Inline Model ' + (++inlineModels);
model = {definition: schema};
}
if (skipRef !== true) {
references[modelName] = _.isUndefined(model) ? {} : model.definition;
}
return modelName;
}
function primitiveToHTML(schema) {
var html = '<span class="propType">';
var type = schema.type || 'object';
if (schema.$ref) {
html += addReference(schema, simpleRef(schema.$ref));
} else if (type === 'object') {
if (!_.isUndefined(schema.properties)) {
html += addReference(schema);
} else {
html += 'object';
}
} else if (type === 'array') {
html += 'Array[';
if (_.isArray(schema.items)) {
html += _.map(schema.items, addReference).join(',');
} else if (_.isPlainObject(schema.items)) {
if (_.isUndefined(schema.items.$ref)) {
if (!_.isUndefined(schema.items.type) && _.indexOf(['array', 'object'], schema.items.type) === -1) {
html += schema.items.type;
} else {
html += addReference(schema.items);
}
} else {
html += addReference(schema.items, simpleRef(schema.items.$ref));
}
} else {
console.log('Array type\'s \'items\' schema is not an array or an object, cannot process');
html += 'object';
}
html += ']';
} else {
html += schema.type;
}
html += '</span>';
return html;
}
function primitiveToOptionsHTML(schema, html) {
var options = '';
var type = schema.type || 'object';
var isArray = type === 'array';
if (!_.isUndefined(schema.description)) {
html += ': ' + '<span class="propDesc">' + schema.description + '</span>';
}
if (schema.enum) {
html += ' = <span class="propVals">[\'' + schema.enum.join('\', \'') + '\']</span>';
}
if (isArray) {
if (_.isPlainObject(schema.items) && !_.isUndefined(schema.items.type)) {
type = schema.items.type;
} else {
type = 'object';
}
}
if (!_.isUndefined(schema.default)) {
options += optionHtml('Default', schema.default);
}
switch (type) {
case 'string':
if (schema.minLength) {
options += optionHtml('Min. Length', schema.minLength);
}
if (schema.maxLength) {
options += optionHtml('Max. Length', schema.maxLength);
}
if (schema.pattern) {
options += optionHtml('Reg. Exp.', schema.pattern);
}
break;
case 'integer':
case 'number':
if (schema.minimum) {
options += optionHtml('Min. Value', schema.minimum);
}
if (schema.exclusiveMinimum) {
options += optionHtml('Exclusive Min.', 'true');
}
if (schema.maximum) {
options += optionHtml('Max. Value', schema.maximum);
}
if (schema.exclusiveMaximum) {
options += optionHtml('Exclusive Max.', 'true');
}
if (schema.multipleOf) {
options += optionHtml('Multiple Of', schema.multipleOf);
}
break;
}
if (isArray) {
if (schema.minItems) {
options += optionHtml('Min. Items', schema.minItems);
}
if (schema.maxItems) {
options += optionHtml('Max. Items', schema.maxItems);
}
if (schema.uniqueItems) {
options += optionHtml('Unique Items', 'true');
}
if (schema.collectionFormat) {
options += optionHtml('Coll. Format', schema.collectionFormat);
}
}
if (_.isUndefined(schema.items)) {
if (_.isArray(schema.enum)) {
var enumString;
if (type === 'number' || type === 'integer') {
enumString = schema.enum.join(', ');
} else {
enumString = '"' + schema.enum.join('", "') + '"';
}
options += optionHtml('Enum', enumString);
}
}
if (options.length > 0) {
html = '<span class="propWrap">' + html + '<table class="optionsWrapper"><tr><th colspan="2">' + type + '</th></tr>' + options + '</table></span>';
}
return html;
}
function processModel(schema, name) {
var type = schema.type || 'object';
var isArray = schema.type === 'array';
var html = strongOpen + name + ' ' + (isArray ? '[' : '{') + strongClose;
var contents;
if (name) {
seenModels.push(name);
}
if (isArray) {
if (_.isArray(schema.items)) {
html += '<div>' + _.map(schema.items, function (item) {
var type = item.type || 'object';
if (_.isUndefined(item.$ref)) {
if (_.indexOf(['array', 'object'], type) > -1) {
if (type === 'object' && _.isUndefined(item.properties)) {
return 'object';
} else {
return addReference(item);
}
} else {
return primitiveToOptionsHTML(item, type);
}
} else {
return addReference(item, simpleRef(item.$ref));
}
}).join(',</div><div>');
} else if (_.isPlainObject(schema.items)) {
if (_.isUndefined(schema.items.$ref)) {
if (_.indexOf(['array', 'object'], schema.items.type || 'object') > -1) {
if ((_.isUndefined(schema.items.type) || schema.items.type === 'object') && _.isUndefined(schema.items.properties)) {
html += '<div>object</div>';
} else {
html += '<div>' + addReference(schema.items) + '</div>';
}
} else {
html += '<div>' + primitiveToOptionsHTML(schema.items, schema.items.type) + '</div>';
}
} else {
html += '<div>' + addReference(schema.items, simpleRef(schema.items.$ref)) + '</div>';
}
} else {
console.log('Array type\'s \'items\' property is not an array or an object, cannot process');
html += '<div>object</div>';
}
} else {
if (schema.$ref) {
html += '<div>' + addReference(schema, name) + '</div>';
} else if (type === 'object') {
if (_.isPlainObject(schema.properties)) {
contents = _.map(schema.properties, function (property, name) {
var propertyIsRequired = (_.indexOf(schema.required, name) >= 0);
var cProperty = _.cloneDeep(property);
var requiredClass = propertyIsRequired ? 'required' : '';
var html = '<span class="propName ' + requiredClass + '">' + name + '</span> (';
var model;
// Allow macro to set the default value
cProperty.default = modelPropertyMacro(cProperty);
// Resolve the schema (Handle nested schemas)
cProperty = resolveSchema(cProperty);
// We need to handle property references to primitives (Issue 339)
if (!_.isUndefined(cProperty.$ref)) {
model = models[simpleRef(cProperty.$ref)];
if (!_.isUndefined(model) && _.indexOf([undefined, 'array', 'object'], model.definition.type) === -1) {
// Use referenced schema
cProperty = resolveSchema(model.definition);
}
}
html += primitiveToHTML(cProperty);
if(!propertyIsRequired) {
html += ', <span class="propOptKey">optional</span>';
}
if(property.readOnly) {
html += ', <span class="propReadOnly">read only</span>';
}
html += ')';
return '<div' + (property.readOnly ? ' class="readOnly"' : '') + '>' + primitiveToOptionsHTML(cProperty, html);
}).join(',</div>');
}
if (contents) {
html += contents + '</div>';
}
} else {
html += '<div>' + primitiveToOptionsHTML(schema, type) + '</div>';
}
}
return html + strongOpen + (isArray ? ']' : '}') + strongClose;
}
};
// copy-pasted from swagger-js
var schemaToJSON = function (schema, models, modelsToIgnore, modelPropertyMacro) {
// Resolve the schema (Handle nested schemas)
schema = resolveSchema(schema);
if(typeof modelPropertyMacro !== 'function') {
modelPropertyMacro = function(prop){
return (prop || {}).default;
};
}
modelsToIgnore= modelsToIgnore || {};
var type = schema.type || 'object';
var format = schema.format;
var model;
var output;
if (!_.isUndefined(schema.example)) {
output = schema.example;
} else if (_.isUndefined(schema.items) && _.isArray(schema.enum)) {
output = schema.enum[0];
}
if (_.isUndefined(output)) {
if (schema.$ref) {
model = models[simpleRef(schema.$ref)];
if (!_.isUndefined(model)) {
if (_.isUndefined(modelsToIgnore[model.name])) {
modelsToIgnore[model.name] = model;
output = schemaToJSON(model.definition, models, modelsToIgnore, modelPropertyMacro);
delete modelsToIgnore[model.name];
} else {
if (model.type === 'array') {
output = [];
} else {
output = {};
}
}
}
} else if (!_.isUndefined(schema.default)) {
output = schema.default;
} else if (type === 'string') {
if (format === 'date-time') {
output = new Date().toISOString();
} else if (format === 'date') {
output = new Date().toISOString().split('T')[0];
} else {
output = 'string';
}
} else if (type === 'integer') {
output = 0;
} else if (type === 'number') {
output = 0.0;
} else if (type === 'boolean') {
output = true;
} else if (type === 'object') {
output = {};
_.forEach(schema.properties, function (property, name) {
var cProperty = _.cloneDeep(property);
// Allow macro to set the default value
cProperty.default = modelPropertyMacro(property);
output[name] = schemaToJSON(cProperty, models, modelsToIgnore, modelPropertyMacro);
});
} else if (type === 'array') {
output = [];
if (_.isArray(schema.items)) {
_.forEach(schema.items, function (item) {
output.push(schemaToJSON(item, models, modelsToIgnore, modelPropertyMacro));
});
} else if (_.isPlainObject(schema.items)) {
output.push(schemaToJSON(schema.items, models, modelsToIgnore, modelPropertyMacro));
} else if (_.isUndefined(schema.items)) {
output.push({});
} else {
console.log('Array type\'s \'items\' property is not an array or an object, cannot process');
}
}
}
return output;
};
// copy-pasted from swagger-js
var createJSONSample = function (value, modelsToIgnore) {
modelsToIgnore = modelsToIgnore || {};
modelsToIgnore[value.name] = value;
// Response support
if (value.examples && _.isPlainObject(value.examples)) {
value = _.cloneDeep(value);
var keys = Object.keys(value.examples);
_.forEach(keys, function(key) {
if(key.indexOf('application/json') === 0) {
var example = value.examples[key];
if (_.isString(example)) {
example = jsyaml.safeLoad(example);
}
value.definition.example = example;
return schemaToJSON(value.definition, example, modelsToIgnore, value.modelPropertyMacro);
}
});
}
if (value.examples) {
value = _.cloneDeep(value);
var example = value.examples;
if (_.isString(example)) {
example = jsyaml.safeLoad(example);
}
value.definition.example = example;
return schemaToJSON(value.definition, example, modelsToIgnore, value.modelPropertyMacro);
}
return schemaToJSON(value.definition, value.models, modelsToIgnore, value.modelPropertyMacro);
};
// copy-pasted from swagger-js
var getParameterModelSignature = function (type, definitions) {
var isPrimitive, listType;
if (type instanceof Array) {
listType = true;
type = type[0];
}
// Convert undefined to string of 'undefined'
if (typeof type === 'undefined') {
type = 'undefined';
isPrimitive = true;
} else if (definitions[type]){
// a model def exists?
type = definitions[type]; /* Model */
isPrimitive = false;
} else if (getInlineModel(type)) {
type = getInlineModel(type); /* Model */
isPrimitive = false;
} else {
// We default to primitive
isPrimitive = true;
}
if (isPrimitive) {
if (listType) {
return 'Array[' + type + ']';
} else {
return type.toString();
}
} else {
if (listType) {
return 'Array[' + getModelSignature(type.name, type.definition, type.models, type.modelPropertyMacro) + ']';
} else {
return getModelSignature(type.name, type.definition, type.models, type.modelPropertyMacro);
}
}
};
// copy-pasted from swagger-js
var createParameterJSONSample = function (type, models) {
var listType, sampleJson, innerType;
models = models || {};
listType = (type instanceof Array);
innerType = listType ? type[0] : type;
if(models[innerType]) {
sampleJson = createJSONSample(models[innerType]);
} else if (getInlineModel(innerType)){
sampleJson = createJSONSample(getInlineModel(innerType)); // may return null, if type isn't correct
}
if (sampleJson) {
sampleJson = listType ? [sampleJson] : sampleJson;
if (typeof sampleJson === 'string') {
return sampleJson;
} else if (_.isObject(sampleJson)) {
var t = sampleJson;
if (sampleJson instanceof Array && sampleJson.length > 0) {
t = sampleJson[0];
}
if (t.nodeName && typeof t === 'Node') {
var xmlString = new XMLSerializer().serializeToString(t);
return formatXml(xmlString);
} else {
return JSON.stringify(sampleJson, null, 2);
}
} else {
return sampleJson;
}
}
};
var wrapTag = function (name, value, attrs) {
var str, attributes;
attrs = attrs || [];
attributes = attrs.map(function (attr) {
return ' ' + attr.name + '="' + attr.value + '"';
}).join('');
if (!name) {
return getErrorMessage('Node name is not provided');
}
str = [
'<', name,
attributes,
'>',
value,
'</', name, '>'
];
return str.join('');
};
// Commenting this funtion as the names are now determined beforehand and the prefix part is exposed as a separate function | https://github.com/swagger-api/swagger-ui/issues/2577
/** var getName = function (name, xml) {
var result = name || '';
xml = xml || {};
if (xml.name) {
result = xml.name;
}
if (xml.prefix) {
result = xml.prefix + ':' + result;
}
return result;
};
*/
var getPrefix = function (name, xml) {
var result = name || '';
xml = xml || {};
if (xml.prefix) {
result = xml.prefix + ':' + result;
}
return result;
};
var getNamespace = function (xml) {
var namespace = '';
var name = 'xmlns';
xml = xml || {};
if (xml.namespace) {
namespace = xml.namespace;
} else {
return namespace;
}
if (xml.prefix) {
name += ':' + xml.prefix;
}
return {
name: name,
value: namespace
};
};
var createArrayXML = function (descriptor) {
var name = descriptor.name;
var config = descriptor.config;
var definition = descriptor.definition;
var models = descriptor.models;
var value;
var items = definition.items;
var xml = definition.xml || {};
var namespace = getNamespace(xml);
var attributes = [];
if (!items) { return getErrorMessage(); }
var key = name;
// If there is a name specified for the array elements, use that for the array elements name | https://github.com/swagger-api/swagger-ui/issues/2577
if(items.xml && items.xml.name) {
key = items.xml.name;
}
value = createSchemaXML(key, items, models, config);
if (namespace) {
attributes.push(namespace);
}
if (xml.wrapped) {
value = wrapTag(name, value, attributes);
}
return value;
};
var getPrimitiveSignature = function (schema) {
var type, items;
schema = schema || {};
items = schema.items || {};
type = schema.type || '';
switch (type) {
case 'object': return 'Object is not a primitive';
case 'array' : return 'Array[' + (items.format || items.type) + ']';
default: return schema.format || type;
}
};
var createPrimitiveXML = function (descriptor) {
var name = descriptor.name;
var definition = descriptor.definition;
var primitivesMap = {
'string': {
'date': new Date(1).toISOString().split('T')[0],
'date-time' : new Date(1).toISOString(),
'default': 'string'
},
'integer': {
'default': 1
},
'number': {
'default': 1.1
},
'boolean': {
'default': true
}
};
var type = definition.type;
var format = definition.format;
var xml = definition.xml || {};
var namespace = getNamespace(xml);
var attributes = [];
var value;
if (_.keys(primitivesMap).indexOf(type) < 0) { return getErrorMessage(); }
if (_.isArray(definition.enum)){
value = definition.enum[0];
} else {
value = definition.example || primitivesMap[type][format] || primitivesMap[type].default;
}
if (xml.attribute) {
return {name: name, value: value};
}
if (namespace) {
attributes.push(namespace);
}
return wrapTag(name, value, attributes);
};
function createObjectXML (descriptor) {
var name = descriptor.name;
var definition = descriptor.definition;
var config = descriptor.config;
var models = descriptor.models;
var isParam = descriptor.config.isParam;
var serializedProperties;
var attrs = [];
var properties = definition.properties;
var additionalProperties = definition.additionalProperties;
var xml = definition.xml;
var namespace = getNamespace(xml);
if (namespace) {
attrs.push(namespace);
}
if (!properties && !additionalProperties) { return getErrorMessage(); }
properties = properties || {};
serializedProperties = _.map(properties, function (prop, key) {
var xml, result;
if (isParam && prop.readOnly) {
return '';
}
xml = prop.xml || {};
result = createSchemaXML(key, prop, models, config);
if (xml.attribute) {
attrs.push(result);
return '';
}
return result;
}).join('');
if (additionalProperties) {
serializedProperties += '<!-- additional elements allowed -->';
}
return wrapTag(name, serializedProperties, attrs);
}
function getInfiniteLoopMessage (name, loopTo) {
return wrapTag(name, '<!-- Infinite loop $ref:' + loopTo + ' -->');
}
function getErrorMessage (details) {
details = details ? ': ' + details : '';
return '<!-- invalid XML' + details + ' -->';
}
function createSchemaXML (name, definition, models, config) {
var $ref = _.isObject(definition) ? definition.$ref : null;
var output, index;
config = config || {};
config.modelsToIgnore = config.modelsToIgnore || [];
var descriptor = _.isString($ref) ? getDescriptorByRef($ref, name, models, config)
: getDescriptor(name, definition, models, config);
if (!descriptor) {
return getErrorMessage();
}
switch (descriptor.type) {
case 'array':
output = createArrayXML(descriptor); break;
case 'object':
output = createObjectXML(descriptor); break;
case 'loop':
output = getInfiniteLoopMessage(descriptor.name, descriptor.config.loopTo); break;
default:
output = createPrimitiveXML(descriptor);
}
if ($ref && descriptor.type !== 'loop') {
index = config.modelsToIgnore.indexOf($ref);
if (index > -1) {
config.modelsToIgnore.splice(index, 1);
}
}
return output;
}
function Descriptor (name, type, definition, models, config) {
if (arguments.length < 4) {
throw new Error();
}
this.config = config || {};
this.config.modelsToIgnore = this.config.modelsToIgnore || [];
// name is already set by getDescriptorByRef or getDescriptor function depending on the type. Only prefix, if present is needed to be set here | https://github.com/swagger-api/swagger-ui/issues/2577
this.name = getPrefix(name, definition.xml);
this.definition = definition;
this.models = models;
this.type = type;
}
function getDescriptorByRef($ref, name, models, config) {
var modelType = simpleRef($ref);
var model = models[modelType] || {};
var type = model.definition && model.definition.type ? model.definition.type : 'object';
// If model definition xml name is present, then that will be preferred over model name. This is the case of preferring XmlElement name over XmlRootElement name if XmlElement name is provided | https://github.com/swagger-api/swagger-ui/issues/2577
if(model.definition && model.definition.xml && model.definition.xml.name) {
name = name || model.definition.xml.name || model.name;
}
// else only model name will be considered for determination | https://github.com/swagger-api/swagger-ui/issues/2577
else {
name = name || model.name;
}
if (config.modelsToIgnore.indexOf($ref) > -1) {
type = 'loop';
config.loopTo = modelType;
} else {
config.modelsToIgnore.push($ref);
}
if (!model.definition) {
return null;
}
return new Descriptor(name, type, model.definition, models, config);
}
function getDescriptor (name, definition, models, config){
var type = definition.type || 'object';
// If definition xml name is present, then that will be preferred over name | https://github.com/swagger-api/swagger-ui/issues/2577
if(definition.xml && definition.xml.name) {
name = definition.xml.name || name;
}
if (!definition) {
return null;
}
return new Descriptor(name, type, definition, models, config);
}
function createXMLSample (name, definition, models, isParam) {
var prolog = '<?xml version="1.0"?>';
return formatXml(prolog + createSchemaXML(name, definition, models, { isParam: isParam } ));
}
return {
getModelSignature: getModelSignature,
createJSONSample: createJSONSample,
getParameterModelSignature: getParameterModelSignature,
createParameterJSONSample: createParameterJSONSample,
createSchemaXML: createSchemaXML,
createXMLSample: createXMLSample,
getPrimitiveSignature: getPrimitiveSignature
};
})();
'use strict';
SwaggerUi.Views.PopupView = Backbone.View.extend({
events: {
'click .api-popup-cancel': 'cancelClick'
},
template: Handlebars.templates.popup,
className: 'api-popup-dialog',
selectors: {
content: '.api-popup-content',
main : '#swagger-ui-container'
},
initialize: function(){
this.$el.html(this.template(this.model));
},
render: function () {
this.$(this.selectors.content).append(this.model.content);
$(this.selectors.main).first().append(this.el);
this.showPopup();
return this;
},
showPopup: function () {
this.$el.show();
},
cancelClick: function () {
this.remove();
}
});
'use strict';
SwaggerUi.Views.ResourceView = Backbone.View.extend({
initialize: function(opts) {
opts = opts || {};
this.router = opts.router;
this.auths = opts.auths;
if ('' === this.model.description) {
this.model.description = null;
}
if (this.model.description) {
this.model.summary = this.model.description;
}
this.number = 0;
},
render: function(){
var methods = {};
$(this.el).html(Handlebars.templates.resource(this.model));
// Render each operation
for (var i = 0; i < this.model.operationsArray.length; i++) {
var operation = this.model.operationsArray[i];
var counter = 0;
var id = operation.nickname;
while (typeof methods[id] !== 'undefined') {
id = id + '_' + counter;
counter += 1;
}
methods[id] = operation;
operation.nickname = id;
operation.parentId = this.model.id;
operation.definitions = this.model.definitions; // make Json Schema available for JSonEditor in this operation
this.addOperation(operation);
}
$('.toggleEndpointList', this.el).click(this.callDocs.bind(this, 'toggleEndpointListForResource'));
$('.collapseResource', this.el).click(this.callDocs.bind(this, 'collapseOperationsForResource'));
$('.expandResource', this.el).click(this.callDocs.bind(this, 'expandOperationsForResource'));
return this;
},
addOperation: function(operation) {
operation.number = this.number;
// Render an operation and add it to operations li
var operationView = new SwaggerUi.Views.OperationView({
model: operation,
router: this.router,
tagName: 'li',
className: 'endpoint',
swaggerOptions: this.options.swaggerOptions,
auths: this.auths
});
$('.endpoints', $(this.el)).append(operationView.render().el);
this.number++;
},
// Generic Event handler (`Docs` is global)
callDocs: function(fnName, e) {
e.preventDefault();
Docs[fnName](e.currentTarget.getAttribute('data-id'));
}
});
'use strict';
SwaggerUi.Views.ResponseContentTypeView = Backbone.View.extend({
initialize: function(){},
render: function(){
this.model.responseContentTypeId = 'rct' + Math.random();
$(this.el).html(Handlebars.templates.response_content_type(this.model));
return this;
}
});
'use strict';
SwaggerUi.Views.SignatureView = Backbone.View.extend({
events: {
'click a.description-link' : 'switchToDescription',
'click a.snippet-link' : 'switchToSnippet',
'mousedown .snippet_json' : 'jsonSnippetMouseDown',
'mousedown .snippet_xml' : 'xmlSnippetMouseDown'
},
initialize: function () {
},
render: function(){
$(this.el).html(Handlebars.templates.signature(this.model));
if (this.model.defaultRendering === 'model') {
this.switchToDescription();
} else {
this.switchToSnippet();
}
return this;
},
// handler for show signature
switchToDescription: function(e){
if (e) { e.preventDefault(); }
$('.snippet', $(this.el)).hide();
$('.description', $(this.el)).show();
$('.description-link', $(this.el)).addClass('selected');
$('.snippet-link', $(this.el)).removeClass('selected');
},
// handler for show sample
switchToSnippet: function(e){
if (e) { e.preventDefault(); }
$('.snippet', $(this.el)).show();
$('.description', $(this.el)).hide();
$('.snippet-link', $(this.el)).addClass('selected');
$('.description-link', $(this.el)).removeClass('selected');
},
// handler for snippet to text area
snippetToTextArea: function(val) {
var textArea = $('textarea', $(this.el.parentNode.parentNode.parentNode));
// Fix for bug in IE 10/11 which causes placeholder text to be copied to "value"
if ($.trim(textArea.val()) === '' || textArea.prop('placeholder') === textArea.val()) {
textArea.val(val);
// TODO move this code outside of the view and expose an event instead
if( this.model.jsonEditor && this.model.jsonEditor.isEnabled()){
this.model.jsonEditor.setValue(JSON.parse(this.model.sampleJSON));
}
}
},
jsonSnippetMouseDown: function (e) {
if (this.model.isParam) {
if (e) { e.preventDefault(); }
this.snippetToTextArea(this.model.sampleJSON);
}
},
xmlSnippetMouseDown: function (e) {
if (this.model.isParam) {
if (e) { e.preventDefault(); }
this.snippetToTextArea(this.model.sampleXML);
}
}
});
'use strict';
SwaggerUi.Views.StatusCodeView = Backbone.View.extend({
initialize: function (opts) {
this.options = opts || {};
this.router = this.options.router;
},
render: function(){
var responseModel, responseModelView;
var value = this.router.api.models[this.model.responseModel];
$(this.el).html(Handlebars.templates.status_code(this.model));
if (this.router.api.models.hasOwnProperty(this.model.responseModel)) {
responseModel = {
sampleJSON: JSON.stringify(SwaggerUi.partials.signature.createJSONSample(value), void 0, 2),
sampleXML: this.model.isXML ? SwaggerUi.partials.signature.createXMLSample('', this.model.schema, this.router.api.models) : false,
isParam: false,
signature: SwaggerUi.partials.signature.getModelSignature(this.model.responseModel, value, this.router.api.models),
defaultRendering: this.model.defaultRendering
};
} else {
responseModel = {
signature: SwaggerUi.partials.signature.getPrimitiveSignature(this.model.schema)
};
}
responseModelView = new SwaggerUi.Views.SignatureView({model: responseModel, tagName: 'div'});
$('.model-signature', this.$el).append(responseModelView.render().el);
return this;
}
});}).call(this);
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlbXBsYXRlcy5qcyIsImRvYy5qcyIsImVzNS1zaGltLmpzIiwiaGVscGVycy9oYW5kbGViYXJzLmpzIiwic2FuaXRpemUtaHRtbC5taW4uanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1wYWNrL19wcmVsdWRlLmpzIiwiaW5kZXguanMiLCJsaWIvYXV0aC5qcyIsImxpYi9jbGllbnQuanMiLCJsaWIvaGVscGVycy5qcyIsImxpYi9odHRwLmpzIiwibGliL3Jlc29sdmVyLmpzIiwibGliL3NjaGVtYS1tYXJrdXAuanMiLCJsaWIvc3BlYy1jb252ZXJ0ZXIuanMiLCJsaWIvdHlwZXMvbW9kZWwuanMiLCJsaWIvdHlwZXMvb3BlcmF0aW9uLmpzIiwibGliL3R5cGVzL29wZXJhdGlvbkdyb3VwLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9idG9hL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2J1ZmZlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9idWZmZXIvbm9kZV9tb2R1bGVzL2Jhc2U2NC1qcy9saWIvYjY0LmpzIiwibm9kZV9tb2R1bGVzL2J1ZmZlci9ub2RlX21vZHVsZXMvaWVlZTc1NC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9idWZmZXIvbm9kZV9tb2R1bGVzL2lzLWFycmF5L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Nvb2tpZWphci9jb29raWVqYXIuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvY29tbW9uLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvZHVtcGVyLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvZXhjZXB0aW9uLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvbG9hZGVyLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvbWFyay5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3NjaGVtYS5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3NjaGVtYS9jb3JlLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvc2NoZW1hL2RlZmF1bHRfZnVsbC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3NjaGVtYS9kZWZhdWx0X3NhZmUuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC9zY2hlbWEvZmFpbHNhZmUuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC9zY2hlbWEvanNvbi5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL2JpbmFyeS5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvYm9vbC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvZmxvYXQuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL2ludC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvanMvZnVuY3Rpb24uanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL2pzL3JlZ2V4cC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvanMvdW5kZWZpbmVkLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9tYXAuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL21lcmdlLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9udWxsLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9vbWFwLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9wYWlycy5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvc2VxLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9zZXQuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL3N0ci5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvdGltZXN0YW1wLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvYXJyYXkvaW5kZXhPZi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2FycmF5L2xhc3QuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jaGFpbi9sb2Rhc2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2VhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2ZpbmQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2ZvckVhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2luY2x1ZGVzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9tYXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9kYXRlL25vdy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2Z1bmN0aW9uL2JpbmQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9mdW5jdGlvbi9yZXN0UGFyYW0uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9MYXp5V3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL0xvZGFzaFdyYXBwZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9hcnJheUNvcHkuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9hcnJheUVhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9hcnJheU1hcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2FycmF5U29tZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VBc3NpZ24uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlQ2FsbGJhY2suanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlQ2xvbmUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlQ29weS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VDcmVhdGUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlRWFjaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VGaW5kLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUZpbmRJbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VGb3IuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlRm9ySW4uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlRm9yT3duLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUdldC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VJbmRleE9mLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUlzRXF1YWwuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlSXNFcXVhbERlZXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlSXNNYXRjaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VMb2Rhc2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlTWFwLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZU1hdGNoZXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlTWF0Y2hlc1Byb3BlcnR5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVByb3BlcnR5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVByb3BlcnR5RGVlcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VTZXREYXRhLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVNsaWNlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVRvU3RyaW5nLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVZhbHVlcy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2JpbmFyeUluZGV4LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmluYXJ5SW5kZXhCeS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2JpbmRDYWxsYmFjay5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2J1ZmZlckNsb25lLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY29tcG9zZUFyZ3MuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jb21wb3NlQXJnc1JpZ2h0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlQmFzZUVhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jcmVhdGVCYXNlRm9yLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlQmluZFdyYXBwZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jcmVhdGVDdG9yV3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NyZWF0ZUZpbmQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jcmVhdGVGb3JFYWNoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlSHlicmlkV3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NyZWF0ZVBhcnRpYWxXcmFwcGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlV3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2VxdWFsQXJyYXlzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvZXF1YWxCeVRhZy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2VxdWFsT2JqZWN0cy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldERhdGEuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9nZXRGdW5jTmFtZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldExlbmd0aC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldE1hdGNoRGF0YS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldE5hdGl2ZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2luZGV4T2ZOYU4uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pbml0Q2xvbmVBcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2luaXRDbG9uZUJ5VGFnLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaW5pdENsb25lT2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaXNBcnJheUxpa2UuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0hvc3RPYmplY3QuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaXNJdGVyYXRlZUNhbGwuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0tleS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2lzTGF6aWFibGUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0xlbmd0aC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2lzT2JqZWN0TGlrZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2lzU3RyaWN0Q29tcGFyYWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL21lcmdlRGF0YS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL21ldGFNYXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9yZWFsTmFtZXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9yZW9yZGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvcmVwbGFjZUhvbGRlcnMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9zZXREYXRhLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvc2hpbUtleXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC90b09iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL3RvUGF0aC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL3dyYXBwZXJDbG9uZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvY2xvbmVEZWVwLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc0FyZ3VtZW50cy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNBcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNFbXB0eS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNGdW5jdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNOYXRpdmUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9sYW5nL2lzT2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc1BsYWluT2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc1N0cmluZy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNUeXBlZEFycmF5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc1VuZGVmaW5lZC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L29iamVjdC9rZXlzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvb2JqZWN0L2tleXNJbi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L29iamVjdC9wYWlycy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L29iamVjdC92YWx1ZXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9zdXBwb3J0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvdXRpbGl0eS9pZGVudGl0eS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L3V0aWxpdHkvbm9vcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L3V0aWxpdHkvcHJvcGVydHkuanMiLCJub2RlX21vZHVsZXMvcS9xLmpzIiwibm9kZV9tb2R1bGVzL3N1cGVyYWdlbnQvbGliL2NsaWVudC5qcyIsIm5vZGVfbW9kdWxlcy9zdXBlcmFnZW50L2xpYi9pcy1vYmplY3QuanMiLCJub2RlX21vZHVsZXMvc3VwZXJhZ2VudC9saWIvcmVxdWVzdC1iYXNlLmpzIiwibm9kZV9tb2R1bGVzL3N1cGVyYWdlbnQvbGliL3JlcXVlc3QuanMiLCJub2RlX21vZHVsZXMvc3VwZXJhZ2VudC9ub2RlX21vZHVsZXMvY29tcG9uZW50LWVtaXR0ZXIvaW5kZXguanMiLCJTd2FnZ2VyVWkuanMiLCJ1dGlscy91dGlscy5qcyIsInZpZXcvQXBpS2V5QXV0aE1vZGVsLmpzIiwidmlldy9BcGlLZXlBdXRoVmlldy5qcyIsInZpZXcvQXV0aEJ1dHRvblZpZXcuanMiLCJ2aWV3L0F1dGhzQ29sbGVjdGlvbi5qcyIsInZpZXcvQXV0aHNDb2xsZWN0aW9uVmlldy5qcyIsInZpZXcvQXV0aFZpZXcuanMiLCJ2aWV3L0Jhc2ljQXV0aE1vZGVsLmpzIiwidmlldy9CYXNpY0F1dGhWaWV3LmpzIiwidmlldy9Db250ZW50VHlwZVZpZXcuanMiLCJ2aWV3L0hlYWRlclZpZXcuanMiLCJ2aWV3L01haW5WaWV3LmpzIiwidmlldy9PYXV0aDJNb2RlbC5qcyIsInZpZXcvT2F1dGgyVmlldy5qcyIsInZpZXcvT3BlcmF0aW9uVmlldy5qcyIsInZpZXcvUGFyYW1ldGVyQ29udGVudFR5cGVWaWV3LmpzIiwidmlldy9QYXJhbWV0ZXJWaWV3LmpzIiwidmlldy9wYXJ0aWFscy9zaWduYXR1cmUuanMiLCJ2aWV3L1BvcHVwVmlldy5qcyIsInZpZXcvUmVzb3VyY2VWaWV3LmpzIiwidmlldy9SZXNwb25zZUNvbnRlbnRUeXBlVmlldy5qcyIsInZpZXcvU2lnbmF0dXJlVmlldy5qcyIsInZpZXcvU3RhdHVzQ29kZVZpZXcuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDMXhCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUN4TUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ2poRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNuR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNOQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNySkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4WEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5NEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdnQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM29CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2x0Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzcvQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2x5QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xqREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0hBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcElBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNiQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeElBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25nRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDbktBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDbFRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUMvRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDNUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ3BFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDOUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ3JEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDNU5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDcERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUMvQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNoSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDMUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNsRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ24zQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUM3TEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDNzlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ3BDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQzNFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUMzRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJzd2FnZ2VyLXVpLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyoganNoaW50IGlnbm9yZTpzdGFydCAqLyBcbiB7KGZ1bmN0aW9uKCkge1xuICB2YXIgdGVtcGxhdGUgPSBIYW5kbGViYXJzLnRlbXBsYXRlLCB0ZW1wbGF0ZXMgPSBIYW5kbGViYXJzLnRlbXBsYXRlcyA9IEhhbmRsZWJhcnMudGVtcGxhdGVzIHx8IHt9O1xudGVtcGxhdGVzWydhcGlrZXlfYXV0aCddID0gdGVtcGxhdGUoe1wiMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gXCIgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XFxcImtleV9hdXRoX192YWx1ZVxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWx1ZSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3NwYW4+XFxuXCI7XG59LFwiM1wiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiICAgICAgICAgICAgICAgIDxpbnB1dCBwbGFjZWhvbGRlcj1cXFwiYXBpX2tleVxcXCIgY2xhc3M9XFxcImF1dGhfaW5wdXQgaW5wdXRfYXBpS2V5X2VudHJ5XFxcIiBuYW1lPVxcXCJhcGlLZXlcXFwiIHR5cGU9XFxcInRleHRcXFwiLz5cXG5cIjtcbn0sXCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCI8ZGl2IGNsYXNzPVxcXCJrZXlfaW5wdXRfY29udGFpbmVyXFxcIj5cXG4gICAgPGgzIGNsYXNzPVxcXCJhdXRoX190aXRsZVxcXCI+QXBpIGtleSBhdXRob3JpemF0aW9uPC9oMz5cXG4gICAgPGRpdiBjbGFzcz1cXFwiYXV0aF9fZGVzY3JpcHRpb25cXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5kZXNjcmlwdGlvbiA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2Rpdj5cXG4gICAgPGRpdj5cXG4gICAgICAgIDxkaXYgY2xhc3M9XFxcImtleV9hdXRoX19maWVsZFxcXCI+XFxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XFxcImtleV9hdXRoX19sYWJlbFxcXCI+bmFtZTo8L3NwYW4+XFxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XFxcImtleV9hdXRoX192YWx1ZVxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9zcGFuPlxcbiAgICAgICAgPC9kaXY+XFxuICAgICAgICA8ZGl2IGNsYXNzPVxcXCJrZXlfYXV0aF9fZmllbGRcXFwiPlxcbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVxcXCJrZXlfYXV0aF9fbGFiZWxcXFwiPmluOjwvc3Bhbj5cXG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cXFwia2V5X2F1dGhfX3ZhbHVlXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMFtcImluXCJdIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3NwYW4+XFxuICAgICAgICA8L2Rpdj5cXG4gICAgICAgIDxkaXYgY2xhc3M9XFxcImtleV9hdXRoX19maWVsZFxcXCI+XFxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XFxcImtleV9hdXRoX19sYWJlbFxcXCI+dmFsdWU6PC9zcGFuPlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaXNMb2dvdXQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5wcm9ncmFtKDMsIGRhdGEsIDApLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgICAgICAgPC9kaXY+XFxuICAgIDwvZGl2PlxcbjwvZGl2PlxcblwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ2F1dGhfYnV0dG9uJ10gPSB0ZW1wbGF0ZSh7XCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCI8YSBjbGFzcz0nYXV0aG9yaXplX19idG4nIGhyZWY9XFxcIiNcXFwiPkF1dGhvcml6ZTwvYT5cXG5cIjtcbn0sXCJ1c2VEYXRhXCI6dHJ1ZX0pO1xudGVtcGxhdGVzWydhdXRoX2J1dHRvbl9vcGVyYXRpb24nXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgICAgICAgYXV0aG9yaXplX19idG5fb3BlcmF0aW9uX2xvZ2luXFxuXCI7XG59LFwiM1wiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiICAgICAgICBhdXRob3JpemVfX2J0bl9vcGVyYXRpb25fbG9nb3V0XFxuXCI7XG59LFwiNVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gXCIgICAgICAgIDx1bCBjbGFzcz1cXFwiYXV0aG9yaXplLXNjb3Blc1xcXCI+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVycy5lYWNoLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc2NvcGVzIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlYWNoXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDYsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgICAgICAgPC91bD5cXG5cIjtcbn0sXCI2XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCIgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVxcXCJhdXRob3JpemVfX3Njb3BlXFxcIiB0aXRsZT1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZGVzY3JpcHRpb24gOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc2NvcGUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvbGk+XFxuXCI7XG59LFwiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge307XG5cbiAgcmV0dXJuIFwiPGRpdiBjbGFzcz1cXFwiYXV0aG9yaXplX19idG4gYXV0aG9yaXplX19idG5fb3BlcmF0aW9uXFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc0xvZ291dCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oMywgZGF0YSwgMCksXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIj5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnNjb3BlcyA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oNSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9kaXY+XFxuXCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1snYXV0aF92aWV3J10gPSB0ZW1wbGF0ZSh7XCIxXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XFxcImJ1dHRvblxcXCIgY2xhc3M9XFxcImF1dGhfX2J1dHRvbiBhdXRoX3N1Ym1pdF9fYnV0dG9uXFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5BdXRob3JpemU8L2J1dHRvbj5cXG5cIjtcbn0sXCIzXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XFxcImJ1dHRvblxcXCIgY2xhc3M9XFxcImF1dGhfX2J1dHRvbiBhdXRoX2xvZ291dF9fYnV0dG9uXFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5Mb2dvdXQ8L2J1dHRvbj5cXG5cIjtcbn0sXCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fTtcblxuICByZXR1cm4gXCI8ZGl2IGNsYXNzPVxcXCJhdXRoX2NvbnRhaW5lclxcXCI+XFxuXFxuICAgIDxkaXYgY2xhc3M9XFxcImF1dGhfaW5uZXJcXFwiPjwvZGl2PlxcbiAgICA8ZGl2IGNsYXNzPVxcXCJhdXRoX3N1Ym1pdFxcXCI+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVycy51bmxlc3MuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzTG9nb3V0IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJ1bmxlc3NcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc0F1dGhvcml6ZWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDMsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgICA8L2Rpdj5cXG5cXG48L2Rpdj5cXG5cIjtcbn0sXCJ1c2VEYXRhXCI6dHJ1ZX0pO1xudGVtcGxhdGVzWydiYXNpY19hdXRoJ10gPSB0ZW1wbGF0ZSh7XCIxXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgLSBhdXRob3JpemVkXCI7XG59LFwiM1wiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gXCIgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XFxcImJhc2ljX2F1dGhfX3ZhbHVlXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudXNlcm5hbWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvc3Bhbj5cXG5cIjtcbn0sXCI1XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgICAgICAgICAgICAgICAgPGlucHV0IHJlcXVpcmVkIHBsYWNlaG9sZGVyPVxcXCJ1c2VybmFtZVxcXCIgY2xhc3M9XFxcImJhc2ljX2F1dGhfX3VzZXJuYW1lIGF1dGhfaW5wdXRcXFwiIG5hbWU9XFxcInVzZXJuYW1lXFxcIiB0eXBlPVxcXCJ0ZXh0XFxcIi8+XFxuXCI7XG59LFwiN1wiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwiYXV0aF9sYWJlbFxcXCI+XFxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVxcXCJiYXNpY19hdXRoX19sYWJlbFxcXCIgZGF0YS1zdy10cmFuc2xhdGU+cGFzc3dvcmQ6PC9zcGFuPlxcbiAgICAgICAgICAgICAgICA8aW5wdXQgcmVxdWlyZWQgcGxhY2Vob2xkZXI9XFxcInBhc3N3b3JkXFxcIiBjbGFzcz1cXFwiYmFzaWNfYXV0aF9fcGFzc3dvcmQgYXV0aF9pbnB1dFxcXCIgbmFtZT1cXFwicGFzc3dvcmRcXFwiIHR5cGU9XFxcInBhc3N3b3JkXFxcIi8+PC9sYWJlbD5cXG4gICAgICAgICAgICA8L2Rpdj5cXG5cIjtcbn0sXCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fTtcblxuICByZXR1cm4gXCI8ZGl2IGNsYXNzPSdiYXNpY19hdXRoX2NvbnRhaW5lcic+XFxuICAgIDxoMyBjbGFzcz1cXFwiYXV0aF9fdGl0bGVcXFwiPkJhc2ljIGF1dGhlbnRpY2F0aW9uXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc0xvZ291dCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9oMz5cXG4gICAgPGZvcm0gY2xhc3M9XFxcImJhc2ljX2lucHV0X2NvbnRhaW5lclxcXCI+XFxuICAgICAgICA8ZGl2IGNsYXNzPVxcXCJhdXRoX19kZXNjcmlwdGlvblxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmRlc2NyaXB0aW9uIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvZGl2PlxcbiAgICAgICAgPGRpdiBjbGFzcz1cXFwiYXV0aF9sYWJlbFxcXCI+XFxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XFxcImJhc2ljX2F1dGhfX2xhYmVsXFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT51c2VybmFtZTo8L3NwYW4+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc0xvZ291dCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMywgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oNSwgZGF0YSwgMCksXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiICAgICAgICA8L2Rpdj5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzLnVubGVzcy5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaXNMb2dvdXQgOiBkZXB0aDApLHtcIm5hbWVcIjpcInVubGVzc1wiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSg3LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgICAgPC9mb3JtPlxcbjwvZGl2PlxcblwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ2NvbnRlbnRfdHlwZSddID0gdGVtcGxhdGUoe1wiMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gKChzdGFjazEgPSBoZWxwZXJzLmVhY2guY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5wcm9kdWNlcyA6IGRlcHRoMCkse1wibmFtZVwiOlwiZWFjaFwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgyLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKTtcbn0sXCIyXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCJcdDxvcHRpb24gdmFsdWU9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLGRlcHRoMCx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsZGVwdGgwLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9vcHRpb24+XFxuXCI7XG59LFwiNFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiICA8b3B0aW9uIHZhbHVlPVxcXCJhcHBsaWNhdGlvbi9qc29uXFxcIj5hcHBsaWNhdGlvbi9qc29uPC9vcHRpb24+XFxuXCI7XG59LFwiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiPGxhYmVsIGRhdGEtc3ctdHJhbnNsYXRlIGZvcj1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuY29udGVudFR5cGVJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIj5SZXNwb25zZSBDb250ZW50IFR5cGU8L2xhYmVsPlxcbjxzZWxlY3QgbmFtZT1cXFwiY29udGVudFR5cGVcXFwiIGlkPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5jb250ZW50VHlwZUlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiPlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucHJvZHVjZXMgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5wcm9ncmFtKDQsIGRhdGEsIDApLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvc2VsZWN0PlxcblwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ21haW4nXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIiAgPGRpdiBjbGFzcz1cXFwiaW5mb190aXRsZVxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEudGl0bGUgOiBzdGFjazEpLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9kaXY+XFxuICA8ZGl2IGNsYXNzPVxcXCJpbmZvX2Rlc2NyaXB0aW9uIG1hcmtkb3duXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS5kZXNjcmlwdGlvbiA6IHN0YWNrMSkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2Rpdj5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmV4dGVybmFsRG9jcyA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMiwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiICBcIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEudGVybXNPZlNlcnZpY2VVcmwgOiBzdGFjazEpLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDQsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcbiAgXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEuY29udGFjdCA6IHN0YWNrMSkpICE9IG51bGwgPyBzdGFjazEubmFtZSA6IHN0YWNrMSkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oNiwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuICBcIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKChzdGFjazEgPSAoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS5jb250YWN0IDogc3RhY2sxKSkgIT0gbnVsbCA/IHN0YWNrMS51cmwgOiBzdGFjazEpLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDgsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcbiAgXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEuY29udGFjdCA6IHN0YWNrMSkpICE9IG51bGwgPyBzdGFjazEuZW1haWwgOiBzdGFjazEpLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEwLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG4gIFwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS5saWNlbnNlIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxMiwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuXCI7XG59LFwiMlwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiICA8cD5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5leHRlcm5hbERvY3MgOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLmRlc2NyaXB0aW9uIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvcD5cXG4gIDxhIGhyZWY9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZXh0ZXJuYWxEb2NzIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS51cmwgOiBzdGFjazEpLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCIgdGFyZ2V0PVxcXCJfYmxhbmtcXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZXh0ZXJuYWxEb2NzIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS51cmwgOiBzdGFjazEpLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvYT5cXG5cIjtcbn0sXCI0XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiBcIjxkaXYgY2xhc3M9XFxcImluZm9fdG9zXFxcIj48YSB0YXJnZXQ9XFxcIl9ibGFua1xcXCIgaHJlZj1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEudGVybXNPZlNlcnZpY2VVcmwgOiBzdGFjazEpLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCIgZGF0YS1zdy10cmFuc2xhdGU+VGVybXMgb2Ygc2VydmljZTwvYT48L2Rpdj5cIjtcbn0sXCI2XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiBcIjxkaXY+PGRpdiBjbGFzcz0naW5mb19uYW1lJyBzdHlsZT1cXFwiZGlzcGxheTogaW5saW5lXFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5DcmVhdGVkIGJ5IDwvZGl2PiBcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoKHN0YWNrMSA9ICgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmluZm8gOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLmNvbnRhY3QgOiBzdGFjazEpKSAhPSBudWxsID8gc3RhY2sxLm5hbWUgOiBzdGFjazEpLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvZGl2PlwiO1xufSxcIjhcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIjxkaXYgY2xhc3M9J2luZm9fdXJsJyBkYXRhLXN3LXRyYW5zbGF0ZT5TZWUgbW9yZSBhdCA8YSBocmVmPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEuY29udGFjdCA6IHN0YWNrMSkpICE9IG51bGwgPyBzdGFjazEudXJsIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKChzdGFjazEgPSAoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS5jb250YWN0IDogc3RhY2sxKSkgIT0gbnVsbCA/IHN0YWNrMS51cmwgOiBzdGFjazEpLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvYT48L2Rpdj5cIjtcbn0sXCIxMFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiPGRpdiBjbGFzcz0naW5mb19lbWFpbCc+PGEgdGFyZ2V0PVxcXCJfcGFyZW50XFxcIiBocmVmPVxcXCJtYWlsdG86XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9ICgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmluZm8gOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLmNvbnRhY3QgOiBzdGFjazEpKSAhPSBudWxsID8gc3RhY2sxLmVtYWlsIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI/c3ViamVjdD1cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmluZm8gOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLnRpdGxlIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPkNvbnRhY3QgdGhlIGRldmVsb3BlcjwvYT48L2Rpdj5cIjtcbn0sXCIxMlwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiPGRpdiBjbGFzcz0naW5mb19saWNlbnNlJz48YSB0YXJnZXQ9XFxcIl9ibGFua1xcXCIgaHJlZj0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9ICgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmluZm8gOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLmxpY2Vuc2UgOiBzdGFjazEpKSAhPSBudWxsID8gc3RhY2sxLnVybCA6IHN0YWNrMSkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJz5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEubGljZW5zZSA6IHN0YWNrMSkpICE9IG51bGwgPyBzdGFjazEubmFtZSA6IHN0YWNrMSkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9hPjwvZGl2PlwiO1xufSxcIjE0XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiBcIiAgLCA8c3BhbiBzdHlsZT1cXFwiZm9udC12YXJpYW50OiBzbWFsbC1jYXBzXFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5hcGkgdmVyc2lvbjwvc3Bhbj46IFwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmluZm8gOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLnZlcnNpb24gOiBzdGFjazEpLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcbiAgICBcIjtcbn0sXCIxNlwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiICAgIDxzcGFuIHN0eWxlPVxcXCJmbG9hdDpyaWdodFxcXCI+PGEgdGFyZ2V0PVxcXCJfYmxhbmtcXFwiIGhyZWY9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbGlkYXRvclVybCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiL2RlYnVnP3VybD1cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC51cmwgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCI+PGltZyBpZD1cXFwidmFsaWRhdG9yXFxcIiBzcmM9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbGlkYXRvclVybCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiP3VybD1cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC51cmwgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCI+PC9hPlxcbiAgICA8L3NwYW4+XFxuXCI7XG59LFwiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge307XG5cbiAgcmV0dXJuIFwiPGRpdiBjbGFzcz0naW5mbycgaWQ9J2FwaV9pbmZvJz5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmluZm8gOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvZGl2PlxcbjxkaXYgY2xhc3M9J2NvbnRhaW5lcicgaWQ9J3Jlc291cmNlc19jb250YWluZXInPlxcbiAgPGRpdiBjbGFzcz0nYXV0aG9yaXplLXdyYXBwZXInPjwvZGl2PlxcblxcbiAgPHVsIGlkPSdyZXNvdXJjZXMnPjwvdWw+XFxuXFxuICA8ZGl2IGNsYXNzPVxcXCJmb290ZXJcXFwiPlxcbiAgICA8aDQgc3R5bGU9XFxcImNvbG9yOiAjOTk5XFxcIj5bIDxzcGFuIHN0eWxlPVxcXCJmb250LXZhcmlhbnQ6IHNtYWxsLWNhcHNcXFwiPmJhc2UgdXJsPC9zcGFuPjogXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuYmFzZVBhdGggOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS52ZXJzaW9uIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxNCwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXVxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsaWRhdG9yVXJsIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxNiwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiICAgIDwvaDQ+XFxuICAgIDwvZGl2PlxcbjwvZGl2PlxcblwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ29hdXRoMiddID0gdGVtcGxhdGUoe1wiMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gXCI8cD5BdXRob3JpemF0aW9uIFVSTDogXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5hdXRob3JpemF0aW9uVXJsIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvcD5cIjtcbn0sXCIzXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiBcIjxwPlRva2VuIFVSTDogXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC50b2tlblVybCA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3A+XCI7XG59LFwiNVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiICAgICAgICA8cD5QbGVhc2UgaW5wdXQgdXNlcm5hbWUgYW5kIHBhc3N3b3JkIGZvciBwYXNzd29yZCBmbG93IGF1dGhvcml6YXRpb248L3A+XFxuICAgICAgICA8ZmllbGRzZXQ+XFxuICAgICAgICAgICAgPGRpdj48bGFiZWw+VXNlcm5hbWU6IDxpbnB1dCBjbGFzcz1cXFwib2F1dGgtdXNlcm5hbWVcXFwiIHR5cGU9XFxcInRleHRcXFwiIG5hbWU9XFxcInVzZXJuYW1lXFxcIj48L2xhYmVsPjwvZGl2PlxcbiAgICAgICAgICAgIDxkaXY+PGxhYmVsPlBhc3N3b3JkOiA8aW5wdXQgY2xhc3M9XFxcIm9hdXRoLXBhc3N3b3JkXFxcIiB0eXBlPVxcXCJwYXNzd29yZFxcXCIgbmFtZT1cXFwicGFzc3dvcmRcXFwiPjwvbGFiZWw+PC9kaXY+XFxuICAgICAgICA8L2ZpZWxkc2V0PlxcblwiO1xufSxcIjdcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuIFwiICAgICAgICA8cD5TZXR1cCBjbGllbnQgYXV0aGVudGljYXRpb24uXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucmVxdWlyZUNsaWVudEF1dGhlbnRpY2FpdG9uIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSg4LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3A+XFxuICAgICAgICA8ZmllbGRzZXQ+XFxuICAgICAgICAgICAgPGRpdj48bGFiZWw+VHlwZTpcXG4gICAgICAgICAgICAgICAgPHNlbGVjdCBjbGFzcz1cXFwib2F1dGgtY2xpZW50LWF1dGhlbnRpY2F0aW9uLXR5cGVcXFwiIG5hbWU9XFxcImNsaWVudC1hdXRoZW50aWNhdGlvbi10eXBlXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XFxcIm5vbmVcXFwiIHNlbGVjdGVkPk5vbmUgb3Igb3RoZXI8L29wdGlvbj5cXG4gICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XFxcImJhc2ljXFxcIj5CYXNpYyBhdXRoPC9vcHRpb24+XFxuICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVxcXCJyZXF1ZXN0LWJvZHlcXFwiPlJlcXVlc3QgYm9keTwvb3B0aW9uPlxcbiAgICAgICAgICAgICAgICA8L3NlbGVjdD5cXG4gICAgICAgICAgICA8L2xhYmVsPjwvZGl2PlxcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcIm9hdXRoLWNsaWVudC1hdXRoZW50aWNhdGlvblxcXCIgaGlkZGVuPlxcbiAgICAgICAgICAgICAgICA8ZGl2PjxsYWJlbD5DbGllbnRJZDogPGlucHV0IGNsYXNzPVxcXCJvYXV0aC1jbGllbnQtaWRcXFwiIHR5cGU9XFxcInRleHRcXFwiIG5hbWU9XFxcImNsaWVudC1pZFxcXCI+PC9sYWJlbD48L2Rpdj5cXG4gICAgICAgICAgICAgICAgPGRpdj48bGFiZWw+U2VjcmV0OiA8aW5wdXQgY2xhc3M9XFxcIm9hdXRoLWNsaWVudC1zZWNyZXRcXFwiIHR5cGU9XFxcInRleHRcXFwiIG5hbWU9XFxcImNsaWVudC1zZWNyZXRcXFwiPjwvbGFiZWw+PC9kaXY+XFxuICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICA8L2ZpZWxkc2V0PlxcblwiO1xufSxcIjhcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIihSZXF1aXJlZClcIjtcbn0sXCIxMFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiICAgICAgICAgICAgPGxpPlxcbiAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XFxcIm9hdXRoLXNjb3BlXFxcIiB0eXBlPVxcXCJjaGVja2JveFxcXCIgZGF0YS1zY29wZT1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc2NvcGUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCIgb2F1dGh0eXBlPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5PQXV0aFNjaGVtZUtleSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIi8+XFxuICAgICAgICAgICAgICAgIDxsYWJlbD5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zY29wZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9sYWJlbD48YnIvPlxcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cXFwiYXBpLXNjb3BlLWRlc2NcXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmRlc2NyaXB0aW9uIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLk9BdXRoU2NoZW1lS2V5IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiICAgICAgICAgICAgICAgIDwvc3Bhbj5cXG4gICAgICAgICAgICA8L2xpPlxcblwiO1xufSxcIjExXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiBcIiAgICAgICAgICAgICAgICAgICAgICAgIChcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuT0F1dGhTY2hlbWVLZXkgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIilcXG5cIjtcbn0sXCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCI8ZGl2PlxcbiAgICA8aDMgY2xhc3M9XFxcImF1dGhfX3RpdGxlXFxcIj5PQXV0aDIuMDwvaDM+XFxuICAgIDxwPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5kZXNjcmlwdGlvbiA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3A+XFxuICAgIFwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuYXV0aG9yaXphdGlvblVybCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuICAgIFwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudG9rZW5VcmwgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDMsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcbiAgICA8cD5mbG93OiBcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5mbG93IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3A+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc1Bhc3N3b3JkRmxvdyA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oNSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5jbGllbnRBdXRoZW50aWNhdGlvbiA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oNywgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiICAgIDxwPjxzdHJvbmc+IFwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmFwcE5hbWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiA8L3N0cm9uZz4gQVBJIHJlcXVpcmVzIHRoZSBmb2xsb3dpbmcgc2NvcGVzLiBTZWxlY3Qgd2hpY2ggb25lcyB5b3Ugd2FudCB0byBncmFudCB0byBTd2FnZ2VyIFVJLjwvcD5cXG4gICAgPHA+U2NvcGVzIGFyZSB1c2VkIHRvIGdyYW50IGFuIGFwcGxpY2F0aW9uIGRpZmZlcmVudCBsZXZlbHMgb2YgYWNjZXNzIHRvIGRhdGEgb24gYmVoYWxmIG9mIHRoZSBlbmQgdXNlci4gRWFjaCBBUEkgbWF5IGRlY2xhcmUgb25lIG9yIG1vcmUgc2NvcGVzLlxcbiAgICAgICAgPGEgaHJlZj1cXFwiI1xcXCI+TGVhcm4gaG93IHRvIHVzZTwvYT5cXG4gICAgPC9wPlxcbiAgICA8dWwgY2xhc3M9XFxcImFwaS1wb3B1cC1zY29wZXNcXFwiPlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnMuZWFjaC5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc2NvcGVzIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlYWNoXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEwLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgICAgPC91bD5cXG48L2Rpdj5cIjtcbn0sXCJ1c2VEYXRhXCI6dHJ1ZX0pO1xudGVtcGxhdGVzWydvcGVyYXRpb24nXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcImRlcHJlY2F0ZWRcIjtcbn0sXCIzXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgICAgICAgICAgICA8aDQ+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+XFxuXHRcdFx0XHQ8ZGl2IGNsYXNzPVxcXCJlZGl0b3JfaG9sZGVyXFxcIj48L2Rpdj5cXG5cdFx0XHRcdDxiciAvPlxcblx0XHRcdFx0PGRpdiBjbGFzcz1cXFwicGFyYW1ldGVyLWNvbnRlbnQtdHlwZVxcXCIgLz5cXG5cIjtcbn0sXCI5XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzRmlsZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTAsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5wcm9ncmFtKDEyLCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKTtcbn0sXCIxMFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiXHRcdFx0PGlucHV0IGNsYXNzPSdwYXJhbWV0ZXIgcmVxdWlyZWQnIHR5cGU9J2ZpbGUnIG5hbWU9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIicgaWQ9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbHVlSWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIicvPlxcblwiO1xufSxcIjEyXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiAoKHN0YWNrMSA9IChoZWxwZXJzLnJlbmRlclRleHRQYXJhbSB8fCAoZGVwdGgwICYmIGRlcHRoMC5yZW5kZXJUZXh0UGFyYW0pIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LGRlcHRoMCx7XCJuYW1lXCI6XCJyZW5kZXJUZXh0UGFyYW1cIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTMsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpO1xufSxcIjEzXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCJcIjtcbn0sXCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCI8dGQgY2xhc3M9J2NvZGUgcmVxdWlyZWQnPjxsYWJlbCBmb3I9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbHVlSWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIic+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9sYWJlbD48L3RkPlxcbjx0ZD5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzQm9keSA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oOSwgZGF0YSwgMCksXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZD5cXG48dGQ+XFxuXHQ8c3Ryb25nPjxzcGFuIGNsYXNzPVxcXCJtYXJrZG93blxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmRlc2NyaXB0aW9uIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvc3Bhbj48L3N0cm9uZz5cXG48L3RkPlxcbjx0ZD5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5wYXJhbVR5cGUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGQ+XFxuPHRkPjxzcGFuIGNsYXNzPVxcXCJtb2RlbC1zaWduYXR1cmVcXFwiPjwvc3Bhbj48L3RkPlxcblwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ3BhcmFtZXRlcl9jb250ZW50X3R5cGUnXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuICgoc3RhY2sxID0gaGVscGVycy5lYWNoLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuY29uc3VtZXMgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVhY2hcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMiwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIik7XG59LFwiMlwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiICA8b3B0aW9uIHZhbHVlPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSxkZXB0aDAse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLGRlcHRoMCx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvb3B0aW9uPlxcblwiO1xufSxcIjRcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgPG9wdGlvbiB2YWx1ZT1cXFwiYXBwbGljYXRpb24vanNvblxcXCI+YXBwbGljYXRpb24vanNvbjwvb3B0aW9uPlxcblwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGhlbHBlciwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiPGxhYmVsIGZvcj1cXFwiXCJcbiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMucGFyYW1ldGVyQ29udGVudFR5cGVJZCB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucGFyYW1ldGVyQ29udGVudFR5cGVJZCA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBhbGlhczIpLCh0eXBlb2YgaGVscGVyID09PSBcImZ1bmN0aW9uXCIgPyBoZWxwZXIuY2FsbChhbGlhczEse1wibmFtZVwiOlwicGFyYW1ldGVyQ29udGVudFR5cGVJZFwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSA6IGhlbHBlcikpKVxuICAgICsgXCJcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPlBhcmFtZXRlciBjb250ZW50IHR5cGU6PC9sYWJlbD5cXG48c2VsZWN0IG5hbWU9XFxcInBhcmFtZXRlckNvbnRlbnRUeXBlXFxcIiBpZD1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnBhcmFtZXRlckNvbnRlbnRUeXBlSWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIj5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmNvbnN1bWVzIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSg0LCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3NlbGVjdD5cXG5cIjtcbn0sXCJ1c2VEYXRhXCI6dHJ1ZX0pO1xudGVtcGxhdGVzWydwb3B1cCddID0gdGVtcGxhdGUoe1wiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIGhlbHBlcjtcblxuICByZXR1cm4gXCI8ZGl2IGNsYXNzPVxcXCJhcGktcG9wdXAtZGlhbG9nLXdyYXBwZXJcXFwiPlxcbiAgICA8ZGl2IGNsYXNzPVxcXCJhcGktcG9wdXAtdGl0bGVcXFwiPlwiXG4gICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoKGhlbHBlciA9IChoZWxwZXIgPSBoZWxwZXJzLnRpdGxlIHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC50aXRsZSA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLCh0eXBlb2YgaGVscGVyID09PSBcImZ1bmN0aW9uXCIgPyBoZWxwZXIuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LHtcIm5hbWVcIjpcInRpdGxlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pIDogaGVscGVyKSkpXG4gICAgKyBcIjwvZGl2PlxcbiAgICA8ZGl2IGNsYXNzPVxcXCJhcGktcG9wdXAtY29udGVudFxcXCI+PC9kaXY+XFxuICAgIDxwIGNsYXNzPVxcXCJlcnJvci1tc2dcXFwiPjwvcD5cXG4gICAgPGRpdiBjbGFzcz1cXFwiYXBpLXBvcHVwLWFjdGlvbnNcXFwiPlxcbiAgICAgICAgPGJ1dHRvbiBjbGFzcz1cXFwiYXBpLXBvcHVwLWNhbmNlbCBhcGktYnV0dG9uIGdyYXlcXFwiIHR5cGU9XFxcImJ1dHRvblxcXCI+Q2FuY2VsPC9idXR0b24+XFxuICAgIDwvZGl2PlxcbjwvZGl2PlxcbjxkaXYgY2xhc3M9XFxcImFwaS1wb3B1cC1kaWFsb2ctc2hhZG93XFxcIj48L2Rpdj5cIjtcbn0sXCJ1c2VEYXRhXCI6dHJ1ZX0pO1xudGVtcGxhdGVzWydyZXNvdXJjZSddID0gdGVtcGxhdGUoe1wiMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiIDogXCI7XG59LFwiM1wiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gXCIgICAgPGxpPlxcbiAgICAgIDxhIGhyZWY9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudXJsIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIicgZGF0YS1zdy10cmFuc2xhdGU+UmF3PC9hPlxcbiAgICA8L2xpPlxcblwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGhlbHBlciwgb3B0aW9ucywgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3NpbmcsIGJ1ZmZlciA9IFxuICBcIjxkaXYgY2xhc3M9J2hlYWRpbmcnPlxcbiAgPGgyPlxcbiAgICA8YSBocmVmPScjIS9cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJyBjbGFzcz1cXFwidG9nZ2xlRW5kcG9pbnRMaXN0XFxcIiBkYXRhLWlkPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2E+IFwiO1xuICBzdGFjazEgPSAoKGhlbHBlciA9IChoZWxwZXIgPSBoZWxwZXJzLnN1bW1hcnkgfHwgKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnN1bW1hcnkgOiBkZXB0aDApKSAhPSBudWxsID8gaGVscGVyIDogYWxpYXMyKSwob3B0aW9ucz17XCJuYW1lXCI6XCJzdW1tYXJ5XCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSwodHlwZW9mIGhlbHBlciA9PT0gXCJmdW5jdGlvblwiID8gaGVscGVyLmNhbGwoYWxpYXMxLG9wdGlvbnMpIDogaGVscGVyKSk7XG4gIGlmICghaGVscGVycy5zdW1tYXJ5KSB7IHN0YWNrMSA9IGhlbHBlcnMuYmxvY2tIZWxwZXJNaXNzaW5nLmNhbGwoZGVwdGgwLHN0YWNrMSxvcHRpb25zKX1cbiAgaWYgKHN0YWNrMSAhPSBudWxsKSB7IGJ1ZmZlciArPSBzdGFjazE7IH1cbiAgcmV0dXJuIGJ1ZmZlciArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnN1bW1hcnkgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuICA8L2gyPlxcbiAgPHVsIGNsYXNzPSdvcHRpb25zJz5cXG4gICAgPGxpPlxcbiAgICAgIDxhIGhyZWY9JyMhL1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pZCA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInIGlkPSdlbmRwb2ludExpc3RUb2dnZXJfXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIicgY2xhc3M9XFxcInRvZ2dsZUVuZHBvaW50TGlzdFxcXCIgZGF0YS1pZD1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCIgZGF0YS1zdy10cmFuc2xhdGU+U2hvdy9IaWRlPC9hPlxcbiAgICA8L2xpPlxcbiAgICA8bGk+XFxuICAgICAgPGEgaHJlZj0nIycgY2xhc3M9XFxcImNvbGxhcHNlUmVzb3VyY2VcXFwiIGRhdGEtaWQ9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pZCA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPlxcbiAgICAgICAgTGlzdCBPcGVyYXRpb25zXFxuICAgICAgPC9hPlxcbiAgICA8L2xpPlxcbiAgICA8bGk+XFxuICAgICAgPGEgaHJlZj0nIycgY2xhc3M9XFxcImV4cGFuZFJlc291cmNlXFxcIiBkYXRhLWlkPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5cXG4gICAgICAgIEV4cGFuZCBPcGVyYXRpb25zXFxuICAgICAgPC9hPlxcbiAgICA8L2xpPlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudXJsIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgzLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgIDwvdWw+XFxuPC9kaXY+XFxuPHVsIGNsYXNzPSdlbmRwb2ludHMnIGlkPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiX2VuZHBvaW50X2xpc3QnIHN0eWxlPSdkaXNwbGF5Om5vbmUnPlxcblxcbjwvdWw+XFxuXCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1sncmVzcG9uc2VfY29udGVudF90eXBlJ10gPSB0ZW1wbGF0ZSh7XCIxXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiAoKHN0YWNrMSA9IGhlbHBlcnMuZWFjaC5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnByb2R1Y2VzIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlYWNoXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDIsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpO1xufSxcIjJcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIiAgPG9wdGlvbiB2YWx1ZT1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsZGVwdGgwLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSxkZXB0aDAse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L29wdGlvbj5cXG5cIjtcbn0sXCI0XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgIDxvcHRpb24gdmFsdWU9XFxcImFwcGxpY2F0aW9uL2pzb25cXFwiPmFwcGxpY2F0aW9uL2pzb248L29wdGlvbj5cXG5cIjtcbn0sXCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBoZWxwZXIsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nLCBhbGlhczM9XCJmdW5jdGlvblwiLCBhbGlhczQ9Y29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb247XG5cbiAgcmV0dXJuIFwiPGxhYmVsIGRhdGEtc3ctdHJhbnNsYXRlIGZvcj1cXFwiXCJcbiAgICArIGFsaWFzNCgoKGhlbHBlciA9IChoZWxwZXIgPSBoZWxwZXJzLnJlc3BvbnNlQ29udGVudFR5cGVJZCB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucmVzcG9uc2VDb250ZW50VHlwZUlkIDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGFsaWFzMiksKHR5cGVvZiBoZWxwZXIgPT09IGFsaWFzMyA/IGhlbHBlci5jYWxsKGFsaWFzMSx7XCJuYW1lXCI6XCJyZXNwb25zZUNvbnRlbnRUeXBlSWRcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkgOiBoZWxwZXIpKSlcbiAgICArIFwiXFxcIj5SZXNwb25zZSBDb250ZW50IFR5cGU8L2xhYmVsPlxcbjxzZWxlY3QgbmFtZT1cXFwicmVzcG9uc2VDb250ZW50VHlwZVxcXCIgaWQ9XFxcIlwiXG4gICAgKyBhbGlhczQoKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5yZXNwb25zZUNvbnRlbnRUeXBlSWQgfHwgKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnJlc3BvbnNlQ29udGVudFR5cGVJZCA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBhbGlhczIpLCh0eXBlb2YgaGVscGVyID09PSBhbGlhczMgPyBoZWxwZXIuY2FsbChhbGlhczEse1wibmFtZVwiOlwicmVzcG9uc2VDb250ZW50VHlwZUlkXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pIDogaGVscGVyKSkpXG4gICAgKyBcIlxcXCI+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5wcm9kdWNlcyA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oNCwgZGF0YSwgMCksXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9zZWxlY3Q+XFxuXCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1snc2lnbmF0dXJlJ10gPSB0ZW1wbGF0ZSh7XCIxXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fTtcblxuICByZXR1cm4gXCJcXG48ZGl2Plxcbjx1bCBjbGFzcz1cXFwic2lnbmF0dXJlLW5hdlxcXCI+XFxuICA8bGk+PGEgY2xhc3M9XFxcImRlc2NyaXB0aW9uLWxpbmtcXFwiIGhyZWY9XFxcIiNcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPk1vZGVsPC9hPjwvbGk+XFxuICA8bGk+PGEgY2xhc3M9XFxcInNuaXBwZXQtbGlua1xcXCIgaHJlZj1cXFwiI1xcXCIgZGF0YS1zdy10cmFuc2xhdGU+RXhhbXBsZSBWYWx1ZTwvYT48L2xpPlxcbjwvdWw+XFxuPGRpdj5cXG5cXG48ZGl2IGNsYXNzPVxcXCJzaWduYXR1cmUtY29udGFpbmVyXFxcIj5cXG4gIDxkaXYgY2xhc3M9XFxcImRlc2NyaXB0aW9uXFxcIj5cXG4gICAgICBcIlxuICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnNpZ25hdHVyZSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpXG4gICAgKyBcIlxcbiAgPC9kaXY+XFxuXFxuICA8ZGl2IGNsYXNzPVxcXCJzbmlwcGV0XFxcIj5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnNhbXBsZUpTT04gOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDIsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc2FtcGxlWE1MIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSg1LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgIDwvZGl2PlxcbjwvZGl2PlxcblwiO1xufSxcIjJcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9O1xuXG4gIHJldHVybiBcIiAgICAgIDxkaXYgY2xhc3M9XFxcInNuaXBwZXRfanNvblxcXCI+XFxuICAgICAgICA8cHJlPjxjb2RlPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnNhbXBsZUpTT04gOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvY29kZT48L3ByZT5cXG4gICAgICAgIFwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaXNQYXJhbSA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMywgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuICAgICAgPC9kaXY+XFxuXCI7XG59LFwiM1wiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiPHNtYWxsIGNsYXNzPVxcXCJub3RpY2VcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPjwvc21hbGw+XCI7XG59LFwiNVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge307XG5cbiAgcmV0dXJuIFwiICAgIDxkaXYgY2xhc3M9XFxcInNuaXBwZXRfeG1sXFxcIj5cXG4gICAgICA8cHJlPjxjb2RlPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnNhbXBsZVhNTCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9jb2RlPjwvcHJlPlxcbiAgICAgIFwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaXNQYXJhbSA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMywgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuICAgIDwvZGl2PlxcblwiO1xufSxcIjdcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuIFwiICAgIFwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zaWduYXR1cmUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcblwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuICgoc3RhY2sxID0gKGhlbHBlcnMuaWZDb25kIHx8IChkZXB0aDAgJiYgZGVwdGgwLmlmQ29uZCkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnNhbXBsZUpTT04gOiBkZXB0aDApLFwifHxcIiwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc2FtcGxlWE1MIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZkNvbmRcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oNywgZGF0YSwgMCksXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIik7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1snc3RhdHVzX2NvZGUnXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGhlbHBlciwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiICAgICAgPHRyPlxcbiAgICAgICAgPHRkPlwiXG4gICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoKGhlbHBlciA9IChoZWxwZXIgPSBoZWxwZXJzLmtleSB8fCAoZGF0YSAmJiBkYXRhLmtleSkpICE9IG51bGwgPyBoZWxwZXIgOiBhbGlhczIpLCh0eXBlb2YgaGVscGVyID09PSBcImZ1bmN0aW9uXCIgPyBoZWxwZXIuY2FsbChhbGlhczEse1wibmFtZVwiOlwia2V5XCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pIDogaGVscGVyKSkpXG4gICAgKyBcIjwvdGQ+XFxuICAgICAgICA8dGQ+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmRlc2NyaXB0aW9uIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGQ+XFxuICAgICAgICA8dGQ+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudHlwZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZD5cXG4gICAgICA8L3RyPlxcblwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIjx0ZCB3aWR0aD0nMTUlJyBjbGFzcz0nY29kZSc+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuY29kZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZD5cXG48dGQgY2xhc3M9XFxcIm1hcmtkb3duXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5tZXNzYWdlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RkPlxcbjx0ZCB3aWR0aD0nNTAlJz48c3BhbiBjbGFzcz1cXFwibW9kZWwtc2lnbmF0dXJlXFxcIiAvPjwvdGQ+XFxuPHRkIGNsYXNzPVxcXCJoZWFkZXJzXFxcIj5cXG4gIDx0YWJsZT5cXG4gICAgPHRib2R5PlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnMuZWFjaC5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaGVhZGVycyA6IGRlcHRoMCkse1wibmFtZVwiOlwiZWFjaFwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgICAgPC90Ym9keT5cXG4gIDwvdGFibGU+XFxuPC90ZD5cIjtcbn0sXCJ1c2VEYXRhXCI6dHJ1ZX0pO1xufSkoKTt9IFxuIC8qIGpzaGludCBpZ25vcmU6ZW5kICovIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbiQoZnVuY3Rpb24oKSB7XG5cblx0Ly8gSGVscGVyIGZ1bmN0aW9uIGZvciB2ZXJ0aWNhbGx5IGFsaWduaW5nIERPTSBlbGVtZW50c1xuXHQvLyBodHRwOi8vd3d3LnNlb2RlbnZlci5jb20vc2ltcGxlLXZlcnRpY2FsLWFsaWduLXBsdWdpbi1mb3ItanF1ZXJ5L1xuXHQkLmZuLnZBbGlnbiA9IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKXtcblx0XHRcdHZhciBhaCA9ICQodGhpcykuaGVpZ2h0KCk7XG5cdFx0XHR2YXIgcGggPSAkKHRoaXMpLnBhcmVudCgpLmhlaWdodCgpO1xuXHRcdFx0dmFyIG1oID0gKHBoIC0gYWgpIC8gMjtcblx0XHRcdCQodGhpcykuY3NzKCdtYXJnaW4tdG9wJywgbWgpO1xuXHRcdH0pO1xuXHR9O1xuXG5cdCQuZm4uc3RyZXRjaEZvcm10YXN0aWNJbnB1dFdpZHRoVG9QYXJlbnQgPSBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCl7XG5cdFx0XHR2YXIgcF93aWR0aCA9ICQodGhpcykuY2xvc2VzdChcImZvcm1cIikuaW5uZXJXaWR0aCgpO1xuXHRcdFx0dmFyIHBfcGFkZGluZyA9IHBhcnNlSW50KCQodGhpcykuY2xvc2VzdChcImZvcm1cIikuY3NzKCdwYWRkaW5nLWxlZnQnKSAsMTApICsgcGFyc2VJbnQoJCh0aGlzKS5jbG9zZXN0KCdmb3JtJykuY3NzKCdwYWRkaW5nLXJpZ2h0JyksIDEwKTtcblx0XHRcdHZhciB0aGlzX3BhZGRpbmcgPSBwYXJzZUludCgkKHRoaXMpLmNzcygncGFkZGluZy1sZWZ0JyksIDEwKSArIHBhcnNlSW50KCQodGhpcykuY3NzKCdwYWRkaW5nLXJpZ2h0JyksIDEwKTtcblx0XHRcdCQodGhpcykuY3NzKCd3aWR0aCcsIHBfd2lkdGggLSBwX3BhZGRpbmcgLSB0aGlzX3BhZGRpbmcpO1xuXHRcdH0pO1xuXHR9O1xuXG5cdCQoJ2Zvcm0uZm9ybXRhc3RpYyBsaS5zdHJpbmcgaW5wdXQsIGZvcm0uZm9ybXRhc3RpYyB0ZXh0YXJlYScpLnN0cmV0Y2hGb3JtdGFzdGljSW5wdXRXaWR0aFRvUGFyZW50KCk7XG5cblx0Ly8gVmVydGljYWxseSBjZW50ZXIgdGhlc2UgcGFyYWdyYXBoc1xuXHQvLyBQYXJlbnQgbWF5IG5lZWQgYSBtaW4taGVpZ2h0IGZvciB0aGlzIHRvIHdvcmsuLlxuXHQkKCd1bC5kb3ducGxheWVkIGxpIGRpdi5jb250ZW50IHAnKS52QWxpZ24oKTtcblxuXHQvLyBXaGVuIGEgc2FuZGJveCBmb3JtIGlzIHN1Ym1pdHRlZC4uXG5cdCQoXCJmb3JtLnNhbmRib3hcIikuc3VibWl0KGZ1bmN0aW9uKCl7XG5cblx0XHR2YXIgZXJyb3JfZnJlZSA9IHRydWU7XG5cblx0XHQvLyBDeWNsZSB0aHJvdWdoIHRoZSBmb3JtcyByZXF1aXJlZCBpbnB1dHNcbiBcdFx0JCh0aGlzKS5maW5kKFwiaW5wdXQucmVxdWlyZWRcIikuZWFjaChmdW5jdGlvbigpIHtcblxuXHRcdFx0Ly8gUmVtb3ZlIGFueSBleGlzdGluZyBlcnJvciBzdHlsZXMgZnJvbSB0aGUgaW5wdXRcblx0XHRcdCQodGhpcykucmVtb3ZlQ2xhc3MoJ2Vycm9yJyk7XG5cblx0XHRcdC8vIFRhY2sgdGhlIGVycm9yIHN0eWxlIG9uIGlmIHRoZSBpbnB1dCBpcyBlbXB0eS4uXG5cdFx0XHRpZiAoJCh0aGlzKS52YWwoKSA9PT0gJycpIHtcblx0XHRcdFx0JCh0aGlzKS5hZGRDbGFzcygnZXJyb3InKTtcblx0XHRcdFx0JCh0aGlzKS53aWdnbGUoKTtcblx0XHRcdFx0ZXJyb3JfZnJlZSA9IGZhbHNlO1xuXHRcdFx0fVxuXG5cdFx0fSk7XG5cblx0XHRyZXR1cm4gZXJyb3JfZnJlZTtcblx0fSk7XG5cbn0pO1xuXG5mdW5jdGlvbiBjbGlwcHlDb3BpZWRDYWxsYmFjaygpIHtcbiAgJCgnI2FwaV9rZXlfY29waWVkJykuZmFkZUluKCkuZGVsYXkoMTAwMCkuZmFkZU91dCgpO1xuXG4gIC8vIHZhciBiID0gJChcIiNjbGlwcHlfdG9vbHRpcF9cIiArIGEpO1xuICAvLyBiLmxlbmd0aCAhPSAwICYmIChiLmF0dHIoXCJ0aXRsZVwiLCBcImNvcGllZCFcIikudHJpZ2dlcihcInRpcHN5LnJlbG9hZFwiKSwgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgLy8gICBiLmF0dHIoXCJ0aXRsZVwiLCBcImNvcHkgdG8gY2xpcGJvYXJkXCIpXG4gIC8vIH0sXG4gIC8vIDUwMCkpXG59XG5cbi8vIExvZ2dpbmcgZnVuY3Rpb24gdGhhdCBhY2NvdW50cyBmb3IgYnJvd3NlcnMgdGhhdCBkb24ndCBoYXZlIHdpbmRvdy5jb25zb2xlXG5mdW5jdGlvbiBsb2coKXtcbiAgbG9nLmhpc3RvcnkgPSBsb2cuaGlzdG9yeSB8fCBbXTtcbiAgbG9nLmhpc3RvcnkucHVzaChhcmd1bWVudHMpO1xuICBpZih0aGlzLmNvbnNvbGUpe1xuICAgIGNvbnNvbGUubG9nKCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpWzBdICk7XG4gIH1cbn1cblxuLy8gSGFuZGxlIGJyb3dzZXJzIHRoYXQgZG8gY29uc29sZSBpbmNvcnJlY3RseSAoSUU5IGFuZCBiZWxvdywgc2VlIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzU1MzkzNzgvNzkxMylcbmlmIChGdW5jdGlvbi5wcm90b3R5cGUuYmluZCAmJiBjb25zb2xlICYmIHR5cGVvZiBjb25zb2xlLmxvZyA9PT0gXCJvYmplY3RcIikge1xuICAgIFtcbiAgICAgIFwibG9nXCIsXCJpbmZvXCIsXCJ3YXJuXCIsXCJlcnJvclwiLFwiYXNzZXJ0XCIsXCJkaXJcIixcImNsZWFyXCIsXCJwcm9maWxlXCIsXCJwcm9maWxlRW5kXCJcbiAgICBdLmZvckVhY2goZnVuY3Rpb24gKG1ldGhvZCkge1xuICAgICAgICBjb25zb2xlW21ldGhvZF0gPSB0aGlzLmJpbmQoY29uc29sZVttZXRob2RdLCBjb25zb2xlKTtcbiAgICB9LCBGdW5jdGlvbi5wcm90b3R5cGUuY2FsbCk7XG59XG5cbndpbmRvdy5Eb2NzID0ge1xuXG5cdHNoZWJhbmc6IGZ1bmN0aW9uKCkge1xuXG5cdFx0Ly8gSWYgc2hlYmFuZyBoYXMgYW4gb3BlcmF0aW9uIG5pY2tuYW1lIGluIGl0Li5cblx0XHQvLyBlLmcuIC9kb2NzLyMhL3dvcmRzL2dldF9zZWFyY2hcblx0XHR2YXIgZnJhZ21lbnRzID0gJC5wYXJhbS5mcmFnbWVudCgpLnNwbGl0KCcvJyk7XG5cdFx0ZnJhZ21lbnRzLnNoaWZ0KCk7IC8vIGdldCByaWQgb2YgdGhlIGJhbmdcblxuXHRcdHN3aXRjaCAoZnJhZ21lbnRzLmxlbmd0aCkge1xuXHRcdFx0Y2FzZSAxOlxuICAgICAgICBpZiAoZnJhZ21lbnRzWzBdLmxlbmd0aCA+IDApIHsgLy8gcHJldmVudCBtYXRjaGluZyBcIiMvXCJcbiAgICAgICAgICAvLyBFeHBhbmQgYWxsIG9wZXJhdGlvbnMgZm9yIHRoZSByZXNvdXJjZSBhbmQgc2Nyb2xsIHRvIGl0XG4gICAgICAgICAgdmFyIGRvbV9pZCA9ICdyZXNvdXJjZV8nICsgZnJhZ21lbnRzWzBdO1xuXG4gICAgICAgICAgRG9jcy5leHBhbmRFbmRwb2ludExpc3RGb3JSZXNvdXJjZShmcmFnbWVudHNbMF0pO1xuICAgICAgICAgICQoXCIjXCIrZG9tX2lkKS5zbGlkZXRvKHtoaWdobGlnaHQ6IGZhbHNlfSk7XG4gICAgICAgIH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIDI6XG5cdFx0XHRcdC8vIFJlZmVyIHRvIHRoZSBlbmRwb2ludCBET00gZWxlbWVudCwgZS5nLiAjd29yZHNfZ2V0X3NlYXJjaFxuXG4gICAgICAgIC8vIEV4cGFuZCBSZXNvdXJjZVxuICAgICAgICBEb2NzLmV4cGFuZEVuZHBvaW50TGlzdEZvclJlc291cmNlKGZyYWdtZW50c1swXSk7XG4gICAgICAgICQoXCIjXCIrZG9tX2lkKS5zbGlkZXRvKHtoaWdobGlnaHQ6IGZhbHNlfSk7XG5cbiAgICAgICAgICAgIC8vIEV4cGFuZCBvcGVyYXRpb25cbiAgICAgICAgICAgIHZhciBsaV9kb21faWQgPSBmcmFnbWVudHMuam9pbignXycpO1xuICAgICAgICAgICAgdmFyIGxpX2NvbnRlbnRfZG9tX2lkID0gbGlfZG9tX2lkICsgXCJfY29udGVudFwiO1xuXG5cbiAgICAgICAgICAgIERvY3MuZXhwYW5kT3BlcmF0aW9uKCQoJyMnK2xpX2NvbnRlbnRfZG9tX2lkKSk7XG4gICAgICAgICAgICAkKCcjJytsaV9kb21faWQpLnNsaWRldG8oe2hpZ2hsaWdodDogZmFsc2V9KTtcbiAgICAgICAgICAgIGJyZWFrO1xuXHRcdH1cblx0fSxcblxuXHR0b2dnbGVFbmRwb2ludExpc3RGb3JSZXNvdXJjZTogZnVuY3Rpb24ocmVzb3VyY2UpIHtcblx0XHR2YXIgZWxlbSA9ICQoJ2xpI3Jlc291cmNlXycgKyBEb2NzLmVzY2FwZVJlc291cmNlTmFtZShyZXNvdXJjZSkgKyAnIHVsLmVuZHBvaW50cycpO1xuXHRcdGlmIChlbGVtLmlzKCc6dmlzaWJsZScpKSB7XG5cdFx0XHQkLmJicS5wdXNoU3RhdGUoJyMvJywgMik7XG5cdFx0XHREb2NzLmNvbGxhcHNlRW5kcG9pbnRMaXN0Rm9yUmVzb3VyY2UocmVzb3VyY2UpO1xuXHRcdH0gZWxzZSB7XG4gICAgICAgICAgICAkLmJicS5wdXNoU3RhdGUoJyMvJyArIHJlc291cmNlLCAyKTtcblx0XHRcdERvY3MuZXhwYW5kRW5kcG9pbnRMaXN0Rm9yUmVzb3VyY2UocmVzb3VyY2UpO1xuXHRcdH1cblx0fSxcblxuXHQvLyBFeHBhbmQgcmVzb3VyY2Vcblx0ZXhwYW5kRW5kcG9pbnRMaXN0Rm9yUmVzb3VyY2U6IGZ1bmN0aW9uKHJlc291cmNlKSB7XG5cdFx0dmFyIHJlc291cmNlID0gRG9jcy5lc2NhcGVSZXNvdXJjZU5hbWUocmVzb3VyY2UpO1xuXHRcdGlmIChyZXNvdXJjZSA9PSAnJykge1xuXHRcdFx0JCgnLnJlc291cmNlIHVsLmVuZHBvaW50cycpLnNsaWRlRG93bigpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdCQoJ2xpI3Jlc291cmNlXycgKyByZXNvdXJjZSkuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuXG5cdFx0dmFyIGVsZW0gPSAkKCdsaSNyZXNvdXJjZV8nICsgcmVzb3VyY2UgKyAnIHVsLmVuZHBvaW50cycpO1xuXHRcdGVsZW0uc2xpZGVEb3duKCk7XG5cdH0sXG5cblx0Ly8gQ29sbGFwc2UgcmVzb3VyY2UgYW5kIG1hcmsgYXMgZXhwbGljaXRseSBjbG9zZWRcblx0Y29sbGFwc2VFbmRwb2ludExpc3RGb3JSZXNvdXJjZTogZnVuY3Rpb24ocmVzb3VyY2UpIHtcblx0XHR2YXIgcmVzb3VyY2UgPSBEb2NzLmVzY2FwZVJlc291cmNlTmFtZShyZXNvdXJjZSk7XG5cdFx0aWYgKHJlc291cmNlID09ICcnKSB7XG5cdFx0XHQkKCcucmVzb3VyY2UgdWwuZW5kcG9pbnRzJykuc2xpZGVVcCgpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdCQoJ2xpI3Jlc291cmNlXycgKyByZXNvdXJjZSkucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuXG5cdFx0dmFyIGVsZW0gPSAkKCdsaSNyZXNvdXJjZV8nICsgcmVzb3VyY2UgKyAnIHVsLmVuZHBvaW50cycpO1xuXHRcdGVsZW0uc2xpZGVVcCgpO1xuXHR9LFxuXG5cdGV4cGFuZE9wZXJhdGlvbnNGb3JSZXNvdXJjZTogZnVuY3Rpb24ocmVzb3VyY2UpIHtcblx0XHQvLyBNYWtlIHN1cmUgdGhlIHJlc291cmNlIGNvbnRhaW5lciBpcyBvcGVuLi5cblx0XHREb2NzLmV4cGFuZEVuZHBvaW50TGlzdEZvclJlc291cmNlKHJlc291cmNlKTtcblxuXHRcdGlmIChyZXNvdXJjZSA9PSAnJykge1xuXHRcdFx0JCgnLnJlc291cmNlIHVsLmVuZHBvaW50cyBsaS5vcGVyYXRpb24gZGl2LmNvbnRlbnQnKS5zbGlkZURvd24oKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQkKCdsaSNyZXNvdXJjZV8nICsgRG9jcy5lc2NhcGVSZXNvdXJjZU5hbWUocmVzb3VyY2UpICsgJyBsaS5vcGVyYXRpb24gZGl2LmNvbnRlbnQnKS5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0RG9jcy5leHBhbmRPcGVyYXRpb24oJCh0aGlzKSk7XG5cdFx0fSk7XG5cdH0sXG5cblx0Y29sbGFwc2VPcGVyYXRpb25zRm9yUmVzb3VyY2U6IGZ1bmN0aW9uKHJlc291cmNlKSB7XG5cdFx0Ly8gTWFrZSBzdXJlIHRoZSByZXNvdXJjZSBjb250YWluZXIgaXMgb3Blbi4uXG5cdFx0RG9jcy5leHBhbmRFbmRwb2ludExpc3RGb3JSZXNvdXJjZShyZXNvdXJjZSk7XG5cblx0XHRpZiAocmVzb3VyY2UgPT0gJycpIHtcblx0XHRcdCQoJy5yZXNvdXJjZSB1bC5lbmRwb2ludHMgbGkub3BlcmF0aW9uIGRpdi5jb250ZW50Jykuc2xpZGVVcCgpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdCQoJ2xpI3Jlc291cmNlXycgKyBEb2NzLmVzY2FwZVJlc291cmNlTmFtZShyZXNvdXJjZSkgKyAnIGxpLm9wZXJhdGlvbiBkaXYuY29udGVudCcpLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHREb2NzLmNvbGxhcHNlT3BlcmF0aW9uKCQodGhpcykpO1xuXHRcdH0pO1xuXHR9LFxuXG5cdGVzY2FwZVJlc291cmNlTmFtZTogZnVuY3Rpb24ocmVzb3VyY2UpIHtcblx0XHRyZXR1cm4gcmVzb3VyY2UucmVwbGFjZSgvWyFcIiMkJSYnKCkqKywuXFwvOjs8PT4/QFxcW1xcXFxcXF1cXF5ge3x9fl0vZywgXCJcXFxcJCZcIik7XG5cdH0sXG5cblx0ZXhwYW5kT3BlcmF0aW9uOiBmdW5jdGlvbihlbGVtKSB7XG5cdFx0ZWxlbS5zbGlkZURvd24oKTtcblx0fSxcblxuXHRjb2xsYXBzZU9wZXJhdGlvbjogZnVuY3Rpb24oZWxlbSkge1xuXHRcdGVsZW0uc2xpZGVVcCgpO1xuXHR9XG59O1xuIiwiLyohXG4gKiBodHRwczovL2dpdGh1Yi5jb20vZXMtc2hpbXMvZXM1LXNoaW1cbiAqIEBsaWNlbnNlIGVzNS1zaGltIENvcHlyaWdodCAyMDA5LTIwMTUgYnkgY29udHJpYnV0b3JzLCBNSVQgTGljZW5zZVxuICogc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9lcy1zaGltcy9lczUtc2hpbS9ibG9iL21hc3Rlci9MSUNFTlNFXG4gKi9cblxuLy8gdmltOiB0cz00IHN0cz00IHN3PTQgZXhwYW5kdGFiXG5cbi8vIEFkZCBzZW1pY29sb24gdG8gcHJldmVudCBJSUZFIGZyb20gYmVpbmcgcGFzc2VkIGFzIGFyZ3VtZW50IHRvIGNvbmNhdGVuYXRlZCBjb2RlLlxuO1xuXG4vLyBVTUQgKFVuaXZlcnNhbCBNb2R1bGUgRGVmaW5pdGlvbilcbi8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vdW1kanMvdW1kL2Jsb2IvbWFzdGVyL3RlbXBsYXRlcy9yZXR1cm5FeHBvcnRzLmpzXG4oZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnkpIHtcbiAgICAndXNlIHN0cmljdCc7XG5cbiAgICAvKiBnbG9iYWwgZGVmaW5lLCBleHBvcnRzLCBtb2R1bGUgKi9cbiAgICBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XG4gICAgICAgIC8vIEFNRC4gUmVnaXN0ZXIgYXMgYW4gYW5vbnltb3VzIG1vZHVsZS5cbiAgICAgICAgZGVmaW5lKGZhY3RvcnkpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIC8vIE5vZGUuIERvZXMgbm90IHdvcmsgd2l0aCBzdHJpY3QgQ29tbW9uSlMsIGJ1dFxuICAgICAgICAvLyBvbmx5IENvbW1vbkpTLWxpa2UgZW52aXJvbWVudHMgdGhhdCBzdXBwb3J0IG1vZHVsZS5leHBvcnRzLFxuICAgICAgICAvLyBsaWtlIE5vZGUuXG4gICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEJyb3dzZXIgZ2xvYmFscyAocm9vdCBpcyB3aW5kb3cpXG4gICAgICAgIHJvb3QucmV0dXJuRXhwb3J0cyA9IGZhY3RvcnkoKTtcbiAgICB9XG59KHRoaXMsIGZ1bmN0aW9uICgpIHtcbiAgICAvKipcbiAgICAgKiBCcmluZ3MgYW4gZW52aXJvbm1lbnQgYXMgY2xvc2UgdG8gRUNNQVNjcmlwdCA1IGNvbXBsaWFuY2VcbiAgICAgKiBhcyBpcyBwb3NzaWJsZSB3aXRoIHRoZSBmYWNpbGl0aWVzIG9mIGVyc3R3aGlsZSBlbmdpbmVzLlxuICAgICAqXG4gICAgICogQW5ub3RhdGVkIEVTNTogaHR0cDovL2VzNS5naXRodWIuY29tLyAoc3BlY2lmaWMgbGlua3MgYmVsb3cpXG4gICAgICogRVM1IFNwZWM6IGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9wdWJsaWNhdGlvbnMvZmlsZXMvRUNNQS1TVC9FY21hLTI2Mi5wZGZcbiAgICAgKiBSZXF1aXJlZCByZWFkaW5nOiBodHRwOi8vamF2YXNjcmlwdHdlYmxvZy53b3JkcHJlc3MuY29tLzIwMTEvMTIvMDUvZXh0ZW5kaW5nLWphdmFzY3JpcHQtbmF0aXZlcy9cbiAgICAgKi9cblxuICAgIC8vIFNob3J0Y3V0IHRvIGFuIG9mdGVuIGFjY2Vzc2VkIHByb3BlcnRpZXMsIGluIG9yZGVyIHRvIGF2b2lkIG11bHRpcGxlXG4gICAgLy8gZGVyZWZlcmVuY2UgdGhhdCBjb3N0cyB1bml2ZXJzYWxseS4gVGhpcyBhbHNvIGhvbGRzIGEgcmVmZXJlbmNlIHRvIGtub3duLWdvb2RcbiAgICAvLyBmdW5jdGlvbnMuXG4gICAgdmFyICRBcnJheSA9IEFycmF5O1xuICAgIHZhciBBcnJheVByb3RvdHlwZSA9ICRBcnJheS5wcm90b3R5cGU7XG4gICAgdmFyICRPYmplY3QgPSBPYmplY3Q7XG4gICAgdmFyIE9iamVjdFByb3RvdHlwZSA9ICRPYmplY3QucHJvdG90eXBlO1xuICAgIHZhciAkRnVuY3Rpb24gPSBGdW5jdGlvbjtcbiAgICB2YXIgRnVuY3Rpb25Qcm90b3R5cGUgPSAkRnVuY3Rpb24ucHJvdG90eXBlO1xuICAgIHZhciAkU3RyaW5nID0gU3RyaW5nO1xuICAgIHZhciBTdHJpbmdQcm90b3R5cGUgPSAkU3RyaW5nLnByb3RvdHlwZTtcbiAgICB2YXIgJE51bWJlciA9IE51bWJlcjtcbiAgICB2YXIgTnVtYmVyUHJvdG90eXBlID0gJE51bWJlci5wcm90b3R5cGU7XG4gICAgdmFyIGFycmF5X3NsaWNlID0gQXJyYXlQcm90b3R5cGUuc2xpY2U7XG4gICAgdmFyIGFycmF5X3NwbGljZSA9IEFycmF5UHJvdG90eXBlLnNwbGljZTtcbiAgICB2YXIgYXJyYXlfcHVzaCA9IEFycmF5UHJvdG90eXBlLnB1c2g7XG4gICAgdmFyIGFycmF5X3Vuc2hpZnQgPSBBcnJheVByb3RvdHlwZS51bnNoaWZ0O1xuICAgIHZhciBhcnJheV9jb25jYXQgPSBBcnJheVByb3RvdHlwZS5jb25jYXQ7XG4gICAgdmFyIGFycmF5X2pvaW4gPSBBcnJheVByb3RvdHlwZS5qb2luO1xuICAgIHZhciBjYWxsID0gRnVuY3Rpb25Qcm90b3R5cGUuY2FsbDtcbiAgICB2YXIgYXBwbHkgPSBGdW5jdGlvblByb3RvdHlwZS5hcHBseTtcbiAgICB2YXIgbWF4ID0gTWF0aC5tYXg7XG4gICAgdmFyIG1pbiA9IE1hdGgubWluO1xuXG4gICAgLy8gSGF2aW5nIGEgdG9TdHJpbmcgbG9jYWwgdmFyaWFibGUgbmFtZSBicmVha3MgaW4gT3BlcmEgc28gdXNlIHRvX3N0cmluZy5cbiAgICB2YXIgdG9fc3RyaW5nID0gT2JqZWN0UHJvdG90eXBlLnRvU3RyaW5nO1xuXG4gICAgLyogZ2xvYmFsIFN5bWJvbCAqL1xuICAgIC8qIGVzbGludC1kaXNhYmxlIG9uZS12YXItZGVjbGFyYXRpb24tcGVyLWxpbmUsIG5vLXJlZGVjbGFyZSwgbWF4LXN0YXRlbWVudHMtcGVyLWxpbmUgKi9cbiAgICB2YXIgaGFzVG9TdHJpbmdUYWcgPSB0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBTeW1ib2wudG9TdHJpbmdUYWcgPT09ICdzeW1ib2wnO1xuICAgIHZhciBpc0NhbGxhYmxlOyAvKiBpbmxpbmVkIGZyb20gaHR0cHM6Ly9ucG1qcy5jb20vaXMtY2FsbGFibGUgKi8gdmFyIGZuVG9TdHIgPSBGdW5jdGlvbi5wcm90b3R5cGUudG9TdHJpbmcsIGNvbnN0cnVjdG9yUmVnZXggPSAvXlxccypjbGFzcyAvLCBpc0VTNkNsYXNzRm4gPSBmdW5jdGlvbiBpc0VTNkNsYXNzRm4odmFsdWUpIHsgdHJ5IHsgdmFyIGZuU3RyID0gZm5Ub1N0ci5jYWxsKHZhbHVlKTsgdmFyIHNpbmdsZVN0cmlwcGVkID0gZm5TdHIucmVwbGFjZSgvXFwvXFwvLipcXG4vZywgJycpOyB2YXIgbXVsdGlTdHJpcHBlZCA9IHNpbmdsZVN0cmlwcGVkLnJlcGxhY2UoL1xcL1xcKlsuXFxzXFxTXSpcXCpcXC8vZywgJycpOyB2YXIgc3BhY2VTdHJpcHBlZCA9IG11bHRpU3RyaXBwZWQucmVwbGFjZSgvXFxuL21nLCAnICcpLnJlcGxhY2UoLyB7Mn0vZywgJyAnKTsgcmV0dXJuIGNvbnN0cnVjdG9yUmVnZXgudGVzdChzcGFjZVN0cmlwcGVkKTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IC8qIG5vdCBhIGZ1bmN0aW9uICovIH0gfSwgdHJ5RnVuY3Rpb25PYmplY3QgPSBmdW5jdGlvbiB0cnlGdW5jdGlvbk9iamVjdCh2YWx1ZSkgeyB0cnkgeyBpZiAoaXNFUzZDbGFzc0ZuKHZhbHVlKSkgeyByZXR1cm4gZmFsc2U7IH0gZm5Ub1N0ci5jYWxsKHZhbHVlKTsgcmV0dXJuIHRydWU7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIGZhbHNlOyB9IH0sIGZuQ2xhc3MgPSAnW29iamVjdCBGdW5jdGlvbl0nLCBnZW5DbGFzcyA9ICdbb2JqZWN0IEdlbmVyYXRvckZ1bmN0aW9uXScsIGlzQ2FsbGFibGUgPSBmdW5jdGlvbiBpc0NhbGxhYmxlKHZhbHVlKSB7IGlmICghdmFsdWUpIHsgcmV0dXJuIGZhbHNlOyB9IGlmICh0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JykgeyByZXR1cm4gZmFsc2U7IH0gaWYgKGhhc1RvU3RyaW5nVGFnKSB7IHJldHVybiB0cnlGdW5jdGlvbk9iamVjdCh2YWx1ZSk7IH0gaWYgKGlzRVM2Q2xhc3NGbih2YWx1ZSkpIHsgcmV0dXJuIGZhbHNlOyB9IHZhciBzdHJDbGFzcyA9IHRvX3N0cmluZy5jYWxsKHZhbHVlKTsgcmV0dXJuIHN0ckNsYXNzID09PSBmbkNsYXNzIHx8IHN0ckNsYXNzID09PSBnZW5DbGFzczsgfTtcblxuICAgIHZhciBpc1JlZ2V4OyAvKiBpbmxpbmVkIGZyb20gaHR0cHM6Ly9ucG1qcy5jb20vaXMtcmVnZXggKi8gdmFyIHJlZ2V4RXhlYyA9IFJlZ0V4cC5wcm90b3R5cGUuZXhlYywgdHJ5UmVnZXhFeGVjID0gZnVuY3Rpb24gdHJ5UmVnZXhFeGVjKHZhbHVlKSB7IHRyeSB7IHJlZ2V4RXhlYy5jYWxsKHZhbHVlKTsgcmV0dXJuIHRydWU7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIGZhbHNlOyB9IH0sIHJlZ2V4Q2xhc3MgPSAnW29iamVjdCBSZWdFeHBdJzsgaXNSZWdleCA9IGZ1bmN0aW9uIGlzUmVnZXgodmFsdWUpIHsgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcpIHsgcmV0dXJuIGZhbHNlOyB9IHJldHVybiBoYXNUb1N0cmluZ1RhZyA/IHRyeVJlZ2V4RXhlYyh2YWx1ZSkgOiB0b19zdHJpbmcuY2FsbCh2YWx1ZSkgPT09IHJlZ2V4Q2xhc3M7IH07XG4gICAgdmFyIGlzU3RyaW5nOyAvKiBpbmxpbmVkIGZyb20gaHR0cHM6Ly9ucG1qcy5jb20vaXMtc3RyaW5nICovIHZhciBzdHJWYWx1ZSA9IFN0cmluZy5wcm90b3R5cGUudmFsdWVPZiwgdHJ5U3RyaW5nT2JqZWN0ID0gZnVuY3Rpb24gdHJ5U3RyaW5nT2JqZWN0KHZhbHVlKSB7IHRyeSB7IHN0clZhbHVlLmNhbGwodmFsdWUpOyByZXR1cm4gdHJ1ZTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0gfSwgc3RyaW5nQ2xhc3MgPSAnW29iamVjdCBTdHJpbmddJzsgaXNTdHJpbmcgPSBmdW5jdGlvbiBpc1N0cmluZyh2YWx1ZSkgeyBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykgeyByZXR1cm4gdHJ1ZTsgfSBpZiAodHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JykgeyByZXR1cm4gZmFsc2U7IH0gcmV0dXJuIGhhc1RvU3RyaW5nVGFnID8gdHJ5U3RyaW5nT2JqZWN0KHZhbHVlKSA6IHRvX3N0cmluZy5jYWxsKHZhbHVlKSA9PT0gc3RyaW5nQ2xhc3M7IH07XG4gICAgLyogZXNsaW50LWVuYWJsZSBvbmUtdmFyLWRlY2xhcmF0aW9uLXBlci1saW5lLCBuby1yZWRlY2xhcmUsIG1heC1zdGF0ZW1lbnRzLXBlci1saW5lICovXG5cbiAgICAvKiBpbmxpbmVkIGZyb20gaHR0cDovL25wbWpzLmNvbS9kZWZpbmUtcHJvcGVydGllcyAqL1xuICAgIHZhciBzdXBwb3J0c0Rlc2NyaXB0b3JzID0gJE9iamVjdC5kZWZpbmVQcm9wZXJ0eSAmJiAoZnVuY3Rpb24gKCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdmFyIG9iaiA9IHt9O1xuICAgICAgICAgICAgJE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosICd4JywgeyBlbnVtZXJhYmxlOiBmYWxzZSwgdmFsdWU6IG9iaiB9KTtcbiAgICAgICAgICAgIGZvciAodmFyIF8gaW4gb2JqKSB7IC8vIGpzY3M6aWdub3JlIGRpc2FsbG93VW51c2VkVmFyaWFibGVzXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG9iai54ID09PSBvYmo7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHsgLyogdGhpcyBpcyBFUzMgKi9cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH0oKSk7XG4gICAgdmFyIGRlZmluZVByb3BlcnRpZXMgPSAoZnVuY3Rpb24gKGhhcykge1xuICAgICAgICAvLyBEZWZpbmUgY29uZmlndXJhYmxlLCB3cml0YWJsZSwgYW5kIG5vbi1lbnVtZXJhYmxlIHByb3BzXG4gICAgICAgIC8vIGlmIHRoZXkgZG9uJ3QgZXhpc3QuXG4gICAgICAgIHZhciBkZWZpbmVQcm9wZXJ0eTtcbiAgICAgICAgaWYgKHN1cHBvcnRzRGVzY3JpcHRvcnMpIHtcbiAgICAgICAgICAgIGRlZmluZVByb3BlcnR5ID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSwgbWV0aG9kLCBmb3JjZUFzc2lnbikge1xuICAgICAgICAgICAgICAgIGlmICghZm9yY2VBc3NpZ24gJiYgKG5hbWUgaW4gb2JqZWN0KSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICRPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqZWN0LCBuYW1lLCB7XG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogbWV0aG9kXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGVmaW5lUHJvcGVydHkgPSBmdW5jdGlvbiAob2JqZWN0LCBuYW1lLCBtZXRob2QsIGZvcmNlQXNzaWduKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFmb3JjZUFzc2lnbiAmJiAobmFtZSBpbiBvYmplY3QpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgb2JqZWN0W25hbWVdID0gbWV0aG9kO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyhvYmplY3QsIG1hcCwgZm9yY2VBc3NpZ24pIHtcbiAgICAgICAgICAgIGZvciAodmFyIG5hbWUgaW4gbWFwKSB7XG4gICAgICAgICAgICAgICAgaWYgKGhhcy5jYWxsKG1hcCwgbmFtZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVmaW5lUHJvcGVydHkob2JqZWN0LCBuYW1lLCBtYXBbbmFtZV0sIGZvcmNlQXNzaWduKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfShPYmplY3RQcm90b3R5cGUuaGFzT3duUHJvcGVydHkpKTtcblxuICAgIC8vXG4gICAgLy8gVXRpbFxuICAgIC8vID09PT09PVxuICAgIC8vXG5cbiAgICAvKiByZXBsYWNlYWJsZSB3aXRoIGh0dHBzOi8vbnBtanMuY29tL3BhY2thZ2UvZXMtYWJzdHJhY3QgL2hlbHBlcnMvaXNQcmltaXRpdmUgKi9cbiAgICB2YXIgaXNQcmltaXRpdmUgPSBmdW5jdGlvbiBpc1ByaW1pdGl2ZShpbnB1dCkge1xuICAgICAgICB2YXIgdHlwZSA9IHR5cGVvZiBpbnB1dDtcbiAgICAgICAgcmV0dXJuIGlucHV0ID09PSBudWxsIHx8ICh0eXBlICE9PSAnb2JqZWN0JyAmJiB0eXBlICE9PSAnZnVuY3Rpb24nKTtcbiAgICB9O1xuXG4gICAgdmFyIGlzQWN0dWFsTmFOID0gJE51bWJlci5pc05hTiB8fCBmdW5jdGlvbiBpc0FjdHVhbE5hTih4KSB7XG4gICAgICAgIHJldHVybiB4ICE9PSB4O1xuICAgIH07XG5cbiAgICB2YXIgRVMgPSB7XG4gICAgICAgIC8vIEVTNSA5LjRcbiAgICAgICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4OS40XG4gICAgICAgIC8vIGh0dHA6Ly9qc3BlcmYuY29tL3RvLWludGVnZXJcbiAgICAgICAgLyogcmVwbGFjZWFibGUgd2l0aCBodHRwczovL25wbWpzLmNvbS9wYWNrYWdlL2VzLWFic3RyYWN0IEVTNS5Ub0ludGVnZXIgKi9cbiAgICAgICAgVG9JbnRlZ2VyOiBmdW5jdGlvbiBUb0ludGVnZXIobnVtKSB7XG4gICAgICAgICAgICB2YXIgbiA9ICtudW07XG4gICAgICAgICAgICBpZiAoaXNBY3R1YWxOYU4obikpIHtcbiAgICAgICAgICAgICAgICBuID0gMDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAobiAhPT0gMCAmJiBuICE9PSAoMSAvIDApICYmIG4gIT09IC0oMSAvIDApKSB7XG4gICAgICAgICAgICAgICAgbiA9IChuID4gMCB8fCAtMSkgKiBNYXRoLmZsb29yKE1hdGguYWJzKG4pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBuO1xuICAgICAgICB9LFxuXG4gICAgICAgIC8qIHJlcGxhY2VhYmxlIHdpdGggaHR0cHM6Ly9ucG1qcy5jb20vcGFja2FnZS9lcy1hYnN0cmFjdCBFUzUuVG9QcmltaXRpdmUgKi9cbiAgICAgICAgVG9QcmltaXRpdmU6IGZ1bmN0aW9uIFRvUHJpbWl0aXZlKGlucHV0KSB7XG4gICAgICAgICAgICB2YXIgdmFsLCB2YWx1ZU9mLCB0b1N0cjtcbiAgICAgICAgICAgIGlmIChpc1ByaW1pdGl2ZShpbnB1dCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YWx1ZU9mID0gaW5wdXQudmFsdWVPZjtcbiAgICAgICAgICAgIGlmIChpc0NhbGxhYmxlKHZhbHVlT2YpKSB7XG4gICAgICAgICAgICAgICAgdmFsID0gdmFsdWVPZi5jYWxsKGlucHV0KTtcbiAgICAgICAgICAgICAgICBpZiAoaXNQcmltaXRpdmUodmFsKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRvU3RyID0gaW5wdXQudG9TdHJpbmc7XG4gICAgICAgICAgICBpZiAoaXNDYWxsYWJsZSh0b1N0cikpIHtcbiAgICAgICAgICAgICAgICB2YWwgPSB0b1N0ci5jYWxsKGlucHV0KTtcbiAgICAgICAgICAgICAgICBpZiAoaXNQcmltaXRpdmUodmFsKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgfSxcblxuICAgICAgICAvLyBFUzUgOS45XG4gICAgICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDkuOVxuICAgICAgICAvKiByZXBsYWNlYWJsZSB3aXRoIGh0dHBzOi8vbnBtanMuY29tL3BhY2thZ2UvZXMtYWJzdHJhY3QgRVM1LlRvT2JqZWN0ICovXG4gICAgICAgIFRvT2JqZWN0OiBmdW5jdGlvbiAobykge1xuICAgICAgICAgICAgaWYgKG8gPT0gbnVsbCkgeyAvLyB0aGlzIG1hdGNoZXMgYm90aCBudWxsIGFuZCB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiY2FuJ3QgY29udmVydCBcIiArIG8gKyAnIHRvIG9iamVjdCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuICRPYmplY3Qobyk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgLyogcmVwbGFjZWFibGUgd2l0aCBodHRwczovL25wbWpzLmNvbS9wYWNrYWdlL2VzLWFic3RyYWN0IEVTNS5Ub1VpbnQzMiAqL1xuICAgICAgICBUb1VpbnQzMjogZnVuY3Rpb24gVG9VaW50MzIoeCkge1xuICAgICAgICAgICAgcmV0dXJuIHggPj4+IDA7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgLy9cbiAgICAvLyBGdW5jdGlvblxuICAgIC8vID09PT09PT09XG4gICAgLy9cblxuICAgIC8vIEVTLTUgMTUuMy40LjVcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS4zLjQuNVxuXG4gICAgdmFyIEVtcHR5ID0gZnVuY3Rpb24gRW1wdHkoKSB7fTtcblxuICAgIGRlZmluZVByb3BlcnRpZXMoRnVuY3Rpb25Qcm90b3R5cGUsIHtcbiAgICAgICAgYmluZDogZnVuY3Rpb24gYmluZCh0aGF0KSB7IC8vIC5sZW5ndGggaXMgMVxuICAgICAgICAgICAgLy8gMS4gTGV0IFRhcmdldCBiZSB0aGUgdGhpcyB2YWx1ZS5cbiAgICAgICAgICAgIHZhciB0YXJnZXQgPSB0aGlzO1xuICAgICAgICAgICAgLy8gMi4gSWYgSXNDYWxsYWJsZShUYXJnZXQpIGlzIGZhbHNlLCB0aHJvdyBhIFR5cGVFcnJvciBleGNlcHRpb24uXG4gICAgICAgICAgICBpZiAoIWlzQ2FsbGFibGUodGFyZ2V0KSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0Z1bmN0aW9uLnByb3RvdHlwZS5iaW5kIGNhbGxlZCBvbiBpbmNvbXBhdGlibGUgJyArIHRhcmdldCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyAzLiBMZXQgQSBiZSBhIG5ldyAocG9zc2libHkgZW1wdHkpIGludGVybmFsIGxpc3Qgb2YgYWxsIG9mIHRoZVxuICAgICAgICAgICAgLy8gICBhcmd1bWVudCB2YWx1ZXMgcHJvdmlkZWQgYWZ0ZXIgdGhpc0FyZyAoYXJnMSwgYXJnMiBldGMpLCBpbiBvcmRlci5cbiAgICAgICAgICAgIC8vIFhYWCBzbGljZWRBcmdzIHdpbGwgc3RhbmQgaW4gZm9yIFwiQVwiIGlmIHVzZWRcbiAgICAgICAgICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpOyAvLyBmb3Igbm9ybWFsIGNhbGxcbiAgICAgICAgICAgIC8vIDQuIExldCBGIGJlIGEgbmV3IG5hdGl2ZSBFQ01BU2NyaXB0IG9iamVjdC5cbiAgICAgICAgICAgIC8vIDExLiBTZXQgdGhlIFtbUHJvdG90eXBlXV0gaW50ZXJuYWwgcHJvcGVydHkgb2YgRiB0byB0aGUgc3RhbmRhcmRcbiAgICAgICAgICAgIC8vICAgYnVpbHQtaW4gRnVuY3Rpb24gcHJvdG90eXBlIG9iamVjdCBhcyBzcGVjaWZpZWQgaW4gMTUuMy4zLjEuXG4gICAgICAgICAgICAvLyAxMi4gU2V0IHRoZSBbW0NhbGxdXSBpbnRlcm5hbCBwcm9wZXJ0eSBvZiBGIGFzIGRlc2NyaWJlZCBpblxuICAgICAgICAgICAgLy8gICAxNS4zLjQuNS4xLlxuICAgICAgICAgICAgLy8gMTMuIFNldCB0aGUgW1tDb25zdHJ1Y3RdXSBpbnRlcm5hbCBwcm9wZXJ0eSBvZiBGIGFzIGRlc2NyaWJlZCBpblxuICAgICAgICAgICAgLy8gICAxNS4zLjQuNS4yLlxuICAgICAgICAgICAgLy8gMTQuIFNldCB0aGUgW1tIYXNJbnN0YW5jZV1dIGludGVybmFsIHByb3BlcnR5IG9mIEYgYXMgZGVzY3JpYmVkIGluXG4gICAgICAgICAgICAvLyAgIDE1LjMuNC41LjMuXG4gICAgICAgICAgICB2YXIgYm91bmQ7XG4gICAgICAgICAgICB2YXIgYmluZGVyID0gZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBib3VuZCkge1xuICAgICAgICAgICAgICAgICAgICAvLyAxNS4zLjQuNS4yIFtbQ29uc3RydWN0XV1cbiAgICAgICAgICAgICAgICAgICAgLy8gV2hlbiB0aGUgW1tDb25zdHJ1Y3RdXSBpbnRlcm5hbCBtZXRob2Qgb2YgYSBmdW5jdGlvbiBvYmplY3QsXG4gICAgICAgICAgICAgICAgICAgIC8vIEYgdGhhdCB3YXMgY3JlYXRlZCB1c2luZyB0aGUgYmluZCBmdW5jdGlvbiBpcyBjYWxsZWQgd2l0aCBhXG4gICAgICAgICAgICAgICAgICAgIC8vIGxpc3Qgb2YgYXJndW1lbnRzIEV4dHJhQXJncywgdGhlIGZvbGxvd2luZyBzdGVwcyBhcmUgdGFrZW46XG4gICAgICAgICAgICAgICAgICAgIC8vIDEuIExldCB0YXJnZXQgYmUgdGhlIHZhbHVlIG9mIEYncyBbW1RhcmdldEZ1bmN0aW9uXV1cbiAgICAgICAgICAgICAgICAgICAgLy8gICBpbnRlcm5hbCBwcm9wZXJ0eS5cbiAgICAgICAgICAgICAgICAgICAgLy8gMi4gSWYgdGFyZ2V0IGhhcyBubyBbW0NvbnN0cnVjdF1dIGludGVybmFsIG1ldGhvZCwgYVxuICAgICAgICAgICAgICAgICAgICAvLyAgIFR5cGVFcnJvciBleGNlcHRpb24gaXMgdGhyb3duLlxuICAgICAgICAgICAgICAgICAgICAvLyAzLiBMZXQgYm91bmRBcmdzIGJlIHRoZSB2YWx1ZSBvZiBGJ3MgW1tCb3VuZEFyZ3NdXSBpbnRlcm5hbFxuICAgICAgICAgICAgICAgICAgICAvLyAgIHByb3BlcnR5LlxuICAgICAgICAgICAgICAgICAgICAvLyA0LiBMZXQgYXJncyBiZSBhIG5ldyBsaXN0IGNvbnRhaW5pbmcgdGhlIHNhbWUgdmFsdWVzIGFzIHRoZVxuICAgICAgICAgICAgICAgICAgICAvLyAgIGxpc3QgYm91bmRBcmdzIGluIHRoZSBzYW1lIG9yZGVyIGZvbGxvd2VkIGJ5IHRoZSBzYW1lXG4gICAgICAgICAgICAgICAgICAgIC8vICAgdmFsdWVzIGFzIHRoZSBsaXN0IEV4dHJhQXJncyBpbiB0aGUgc2FtZSBvcmRlci5cbiAgICAgICAgICAgICAgICAgICAgLy8gNS4gUmV0dXJuIHRoZSByZXN1bHQgb2YgY2FsbGluZyB0aGUgW1tDb25zdHJ1Y3RdXSBpbnRlcm5hbFxuICAgICAgICAgICAgICAgICAgICAvLyAgIG1ldGhvZCBvZiB0YXJnZXQgcHJvdmlkaW5nIGFyZ3MgYXMgdGhlIGFyZ3VtZW50cy5cblxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gYXBwbHkuY2FsbChcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICAgICAgICAgICAgICBhcnJheV9jb25jYXQuY2FsbChhcmdzLCBhcnJheV9zbGljZS5jYWxsKGFyZ3VtZW50cykpXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIGlmICgkT2JqZWN0KHJlc3VsdCkgPT09IHJlc3VsdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIDE1LjMuNC41LjEgW1tDYWxsXV1cbiAgICAgICAgICAgICAgICAgICAgLy8gV2hlbiB0aGUgW1tDYWxsXV0gaW50ZXJuYWwgbWV0aG9kIG9mIGEgZnVuY3Rpb24gb2JqZWN0LCBGLFxuICAgICAgICAgICAgICAgICAgICAvLyB3aGljaCB3YXMgY3JlYXRlZCB1c2luZyB0aGUgYmluZCBmdW5jdGlvbiBpcyBjYWxsZWQgd2l0aCBhXG4gICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgdmFsdWUgYW5kIGEgbGlzdCBvZiBhcmd1bWVudHMgRXh0cmFBcmdzLCB0aGUgZm9sbG93aW5nXG4gICAgICAgICAgICAgICAgICAgIC8vIHN0ZXBzIGFyZSB0YWtlbjpcbiAgICAgICAgICAgICAgICAgICAgLy8gMS4gTGV0IGJvdW5kQXJncyBiZSB0aGUgdmFsdWUgb2YgRidzIFtbQm91bmRBcmdzXV0gaW50ZXJuYWxcbiAgICAgICAgICAgICAgICAgICAgLy8gICBwcm9wZXJ0eS5cbiAgICAgICAgICAgICAgICAgICAgLy8gMi4gTGV0IGJvdW5kVGhpcyBiZSB0aGUgdmFsdWUgb2YgRidzIFtbQm91bmRUaGlzXV0gaW50ZXJuYWxcbiAgICAgICAgICAgICAgICAgICAgLy8gICBwcm9wZXJ0eS5cbiAgICAgICAgICAgICAgICAgICAgLy8gMy4gTGV0IHRhcmdldCBiZSB0aGUgdmFsdWUgb2YgRidzIFtbVGFyZ2V0RnVuY3Rpb25dXSBpbnRlcm5hbFxuICAgICAgICAgICAgICAgICAgICAvLyAgIHByb3BlcnR5LlxuICAgICAgICAgICAgICAgICAgICAvLyA0LiBMZXQgYXJncyBiZSBhIG5ldyBsaXN0IGNvbnRhaW5pbmcgdGhlIHNhbWUgdmFsdWVzIGFzIHRoZVxuICAgICAgICAgICAgICAgICAgICAvLyAgIGxpc3QgYm91bmRBcmdzIGluIHRoZSBzYW1lIG9yZGVyIGZvbGxvd2VkIGJ5IHRoZSBzYW1lXG4gICAgICAgICAgICAgICAgICAgIC8vICAgdmFsdWVzIGFzIHRoZSBsaXN0IEV4dHJhQXJncyBpbiB0aGUgc2FtZSBvcmRlci5cbiAgICAgICAgICAgICAgICAgICAgLy8gNS4gUmV0dXJuIHRoZSByZXN1bHQgb2YgY2FsbGluZyB0aGUgW1tDYWxsXV0gaW50ZXJuYWwgbWV0aG9kXG4gICAgICAgICAgICAgICAgICAgIC8vICAgb2YgdGFyZ2V0IHByb3ZpZGluZyBib3VuZFRoaXMgYXMgdGhlIHRoaXMgdmFsdWUgYW5kXG4gICAgICAgICAgICAgICAgICAgIC8vICAgcHJvdmlkaW5nIGFyZ3MgYXMgdGhlIGFyZ3VtZW50cy5cblxuICAgICAgICAgICAgICAgICAgICAvLyBlcXVpdjogdGFyZ2V0LmNhbGwodGhpcywgLi4uYm91bmRBcmdzLCAuLi5hcmdzKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXBwbHkuY2FsbChcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQsXG4gICAgICAgICAgICAgICAgICAgICAgICBhcnJheV9jb25jYXQuY2FsbChhcmdzLCBhcnJheV9zbGljZS5jYWxsKGFyZ3VtZW50cykpXG4gICAgICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8vIDE1LiBJZiB0aGUgW1tDbGFzc11dIGludGVybmFsIHByb3BlcnR5IG9mIFRhcmdldCBpcyBcIkZ1bmN0aW9uXCIsIHRoZW5cbiAgICAgICAgICAgIC8vICAgICBhLiBMZXQgTCBiZSB0aGUgbGVuZ3RoIHByb3BlcnR5IG9mIFRhcmdldCBtaW51cyB0aGUgbGVuZ3RoIG9mIEEuXG4gICAgICAgICAgICAvLyAgICAgYi4gU2V0IHRoZSBsZW5ndGggb3duIHByb3BlcnR5IG9mIEYgdG8gZWl0aGVyIDAgb3IgTCwgd2hpY2hldmVyIGlzXG4gICAgICAgICAgICAvLyAgICAgICBsYXJnZXIuXG4gICAgICAgICAgICAvLyAxNi4gRWxzZSBzZXQgdGhlIGxlbmd0aCBvd24gcHJvcGVydHkgb2YgRiB0byAwLlxuXG4gICAgICAgICAgICB2YXIgYm91bmRMZW5ndGggPSBtYXgoMCwgdGFyZ2V0Lmxlbmd0aCAtIGFyZ3MubGVuZ3RoKTtcblxuICAgICAgICAgICAgLy8gMTcuIFNldCB0aGUgYXR0cmlidXRlcyBvZiB0aGUgbGVuZ3RoIG93biBwcm9wZXJ0eSBvZiBGIHRvIHRoZSB2YWx1ZXNcbiAgICAgICAgICAgIC8vICAgc3BlY2lmaWVkIGluIDE1LjMuNS4xLlxuICAgICAgICAgICAgdmFyIGJvdW5kQXJncyA9IFtdO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBib3VuZExlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgYXJyYXlfcHVzaC5jYWxsKGJvdW5kQXJncywgJyQnICsgaSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFhYWCBCdWlsZCBhIGR5bmFtaWMgZnVuY3Rpb24gd2l0aCBkZXNpcmVkIGFtb3VudCBvZiBhcmd1bWVudHMgaXMgdGhlIG9ubHlcbiAgICAgICAgICAgIC8vIHdheSB0byBzZXQgdGhlIGxlbmd0aCBwcm9wZXJ0eSBvZiBhIGZ1bmN0aW9uLlxuICAgICAgICAgICAgLy8gSW4gZW52aXJvbm1lbnRzIHdoZXJlIENvbnRlbnQgU2VjdXJpdHkgUG9saWNpZXMgZW5hYmxlZCAoQ2hyb21lIGV4dGVuc2lvbnMsXG4gICAgICAgICAgICAvLyBmb3IgZXguKSBhbGwgdXNlIG9mIGV2YWwgb3IgRnVuY3Rpb24gY29zdHJ1Y3RvciB0aHJvd3MgYW4gZXhjZXB0aW9uLlxuICAgICAgICAgICAgLy8gSG93ZXZlciBpbiBhbGwgb2YgdGhlc2UgZW52aXJvbm1lbnRzIEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kIGV4aXN0c1xuICAgICAgICAgICAgLy8gYW5kIHNvIHRoaXMgY29kZSB3aWxsIG5ldmVyIGJlIGV4ZWN1dGVkLlxuICAgICAgICAgICAgYm91bmQgPSAkRnVuY3Rpb24oJ2JpbmRlcicsICdyZXR1cm4gZnVuY3Rpb24gKCcgKyBhcnJheV9qb2luLmNhbGwoYm91bmRBcmdzLCAnLCcpICsgJyl7IHJldHVybiBiaW5kZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfScpKGJpbmRlcik7XG5cbiAgICAgICAgICAgIGlmICh0YXJnZXQucHJvdG90eXBlKSB7XG4gICAgICAgICAgICAgICAgRW1wdHkucHJvdG90eXBlID0gdGFyZ2V0LnByb3RvdHlwZTtcbiAgICAgICAgICAgICAgICBib3VuZC5wcm90b3R5cGUgPSBuZXcgRW1wdHkoKTtcbiAgICAgICAgICAgICAgICAvLyBDbGVhbiB1cCBkYW5nbGluZyByZWZlcmVuY2VzLlxuICAgICAgICAgICAgICAgIEVtcHR5LnByb3RvdHlwZSA9IG51bGw7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFRPRE9cbiAgICAgICAgICAgIC8vIDE4LiBTZXQgdGhlIFtbRXh0ZW5zaWJsZV1dIGludGVybmFsIHByb3BlcnR5IG9mIEYgdG8gdHJ1ZS5cblxuICAgICAgICAgICAgLy8gVE9ET1xuICAgICAgICAgICAgLy8gMTkuIExldCB0aHJvd2VyIGJlIHRoZSBbW1Rocm93VHlwZUVycm9yXV0gZnVuY3Rpb24gT2JqZWN0ICgxMy4yLjMpLlxuICAgICAgICAgICAgLy8gMjAuIENhbGwgdGhlIFtbRGVmaW5lT3duUHJvcGVydHldXSBpbnRlcm5hbCBtZXRob2Qgb2YgRiB3aXRoXG4gICAgICAgICAgICAvLyAgIGFyZ3VtZW50cyBcImNhbGxlclwiLCBQcm9wZXJ0eURlc2NyaXB0b3Ige1tbR2V0XV06IHRocm93ZXIsIFtbU2V0XV06XG4gICAgICAgICAgICAvLyAgIHRocm93ZXIsIFtbRW51bWVyYWJsZV1dOiBmYWxzZSwgW1tDb25maWd1cmFibGVdXTogZmFsc2V9LCBhbmRcbiAgICAgICAgICAgIC8vICAgZmFsc2UuXG4gICAgICAgICAgICAvLyAyMS4gQ2FsbCB0aGUgW1tEZWZpbmVPd25Qcm9wZXJ0eV1dIGludGVybmFsIG1ldGhvZCBvZiBGIHdpdGhcbiAgICAgICAgICAgIC8vICAgYXJndW1lbnRzIFwiYXJndW1lbnRzXCIsIFByb3BlcnR5RGVzY3JpcHRvciB7W1tHZXRdXTogdGhyb3dlcixcbiAgICAgICAgICAgIC8vICAgW1tTZXRdXTogdGhyb3dlciwgW1tFbnVtZXJhYmxlXV06IGZhbHNlLCBbW0NvbmZpZ3VyYWJsZV1dOiBmYWxzZX0sXG4gICAgICAgICAgICAvLyAgIGFuZCBmYWxzZS5cblxuICAgICAgICAgICAgLy8gVE9ET1xuICAgICAgICAgICAgLy8gTk9URSBGdW5jdGlvbiBvYmplY3RzIGNyZWF0ZWQgdXNpbmcgRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgZG8gbm90XG4gICAgICAgICAgICAvLyBoYXZlIGEgcHJvdG90eXBlIHByb3BlcnR5IG9yIHRoZSBbW0NvZGVdXSwgW1tGb3JtYWxQYXJhbWV0ZXJzXV0sIGFuZFxuICAgICAgICAgICAgLy8gW1tTY29wZV1dIGludGVybmFsIHByb3BlcnRpZXMuXG4gICAgICAgICAgICAvLyBYWFggY2FuJ3QgZGVsZXRlIHByb3RvdHlwZSBpbiBwdXJlLWpzLlxuXG4gICAgICAgICAgICAvLyAyMi4gUmV0dXJuIEYuXG4gICAgICAgICAgICByZXR1cm4gYm91bmQ7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIF9QbGVhc2Ugbm90ZTogU2hvcnRjdXRzIGFyZSBkZWZpbmVkIGFmdGVyIGBGdW5jdGlvbi5wcm90b3R5cGUuYmluZGAgYXMgd2VcbiAgICAvLyB1c2UgaXQgaW4gZGVmaW5pbmcgc2hvcnRjdXRzLlxuICAgIHZhciBvd25zID0gY2FsbC5iaW5kKE9iamVjdFByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eSk7XG4gICAgdmFyIHRvU3RyID0gY2FsbC5iaW5kKE9iamVjdFByb3RvdHlwZS50b1N0cmluZyk7XG4gICAgdmFyIGFycmF5U2xpY2UgPSBjYWxsLmJpbmQoYXJyYXlfc2xpY2UpO1xuICAgIHZhciBhcnJheVNsaWNlQXBwbHkgPSBhcHBseS5iaW5kKGFycmF5X3NsaWNlKTtcbiAgICB2YXIgc3RyU2xpY2UgPSBjYWxsLmJpbmQoU3RyaW5nUHJvdG90eXBlLnNsaWNlKTtcbiAgICB2YXIgc3RyU3BsaXQgPSBjYWxsLmJpbmQoU3RyaW5nUHJvdG90eXBlLnNwbGl0KTtcbiAgICB2YXIgc3RySW5kZXhPZiA9IGNhbGwuYmluZChTdHJpbmdQcm90b3R5cGUuaW5kZXhPZik7XG4gICAgdmFyIHB1c2hDYWxsID0gY2FsbC5iaW5kKGFycmF5X3B1c2gpO1xuICAgIHZhciBpc0VudW0gPSBjYWxsLmJpbmQoT2JqZWN0UHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlKTtcbiAgICB2YXIgYXJyYXlTb3J0ID0gY2FsbC5iaW5kKEFycmF5UHJvdG90eXBlLnNvcnQpO1xuXG4gICAgLy9cbiAgICAvLyBBcnJheVxuICAgIC8vID09PT09XG4gICAgLy9cblxuICAgIHZhciBpc0FycmF5ID0gJEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gaXNBcnJheShvYmopIHtcbiAgICAgICAgcmV0dXJuIHRvU3RyKG9iaikgPT09ICdbb2JqZWN0IEFycmF5XSc7XG4gICAgfTtcblxuICAgIC8vIEVTNSAxNS40LjQuMTJcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS40LjQuMTNcbiAgICAvLyBSZXR1cm4gbGVuK2FyZ0NvdW50LlxuICAgIC8vIFtidWdmaXgsIGllbHQ4XVxuICAgIC8vIElFIDwgOCBidWc6IFtdLnVuc2hpZnQoMCkgPT09IHVuZGVmaW5lZCBidXQgc2hvdWxkIGJlIFwiMVwiXG4gICAgdmFyIGhhc1Vuc2hpZnRSZXR1cm5WYWx1ZUJ1ZyA9IFtdLnVuc2hpZnQoMCkgIT09IDE7XG4gICAgZGVmaW5lUHJvcGVydGllcyhBcnJheVByb3RvdHlwZSwge1xuICAgICAgICB1bnNoaWZ0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBhcnJheV91bnNoaWZ0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5sZW5ndGg7XG4gICAgICAgIH1cbiAgICB9LCBoYXNVbnNoaWZ0UmV0dXJuVmFsdWVCdWcpO1xuXG4gICAgLy8gRVM1IDE1LjQuMy4yXG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuNC4zLjJcbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9BcnJheS9pc0FycmF5XG4gICAgZGVmaW5lUHJvcGVydGllcygkQXJyYXksIHsgaXNBcnJheTogaXNBcnJheSB9KTtcblxuICAgIC8vIFRoZSBJc0NhbGxhYmxlKCkgY2hlY2sgaW4gdGhlIEFycmF5IGZ1bmN0aW9uc1xuICAgIC8vIGhhcyBiZWVuIHJlcGxhY2VkIHdpdGggYSBzdHJpY3QgY2hlY2sgb24gdGhlXG4gICAgLy8gaW50ZXJuYWwgY2xhc3Mgb2YgdGhlIG9iamVjdCB0byB0cmFwIGNhc2VzIHdoZXJlXG4gICAgLy8gdGhlIHByb3ZpZGVkIGZ1bmN0aW9uIHdhcyBhY3R1YWxseSBhIHJlZ3VsYXJcbiAgICAvLyBleHByZXNzaW9uIGxpdGVyYWwsIHdoaWNoIGluIFY4IGFuZFxuICAgIC8vIEphdmFTY3JpcHRDb3JlIGlzIGEgdHlwZW9mIFwiZnVuY3Rpb25cIi4gIE9ubHkgaW5cbiAgICAvLyBWOCBhcmUgcmVndWxhciBleHByZXNzaW9uIGxpdGVyYWxzIHBlcm1pdHRlZCBhc1xuICAgIC8vIHJlZHVjZSBwYXJhbWV0ZXJzLCBzbyBpdCBpcyBkZXNpcmFibGUgaW4gdGhlXG4gICAgLy8gZ2VuZXJhbCBjYXNlIGZvciB0aGUgc2hpbSB0byBtYXRjaCB0aGUgbW9yZVxuICAgIC8vIHN0cmljdCBhbmQgY29tbW9uIGJlaGF2aW9yIG9mIHJlamVjdGluZyByZWd1bGFyXG4gICAgLy8gZXhwcmVzc2lvbnMuXG5cbiAgICAvLyBFUzUgMTUuNC40LjE4XG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuNC40LjE4XG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4vSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvYXJyYXkvZm9yRWFjaFxuXG4gICAgLy8gQ2hlY2sgZmFpbHVyZSBvZiBieS1pbmRleCBhY2Nlc3Mgb2Ygc3RyaW5nIGNoYXJhY3RlcnMgKElFIDwgOSlcbiAgICAvLyBhbmQgZmFpbHVyZSBvZiBgMCBpbiBib3hlZFN0cmluZ2AgKFJoaW5vKVxuICAgIHZhciBib3hlZFN0cmluZyA9ICRPYmplY3QoJ2EnKTtcbiAgICB2YXIgc3BsaXRTdHJpbmcgPSBib3hlZFN0cmluZ1swXSAhPT0gJ2EnIHx8ICEoMCBpbiBib3hlZFN0cmluZyk7XG5cbiAgICB2YXIgcHJvcGVybHlCb3hlc0NvbnRleHQgPSBmdW5jdGlvbiBwcm9wZXJseUJveGVkKG1ldGhvZCkge1xuICAgICAgICAvLyBDaGVjayBub2RlIDAuNi4yMSBidWcgd2hlcmUgdGhpcmQgcGFyYW1ldGVyIGlzIG5vdCBib3hlZFxuICAgICAgICB2YXIgcHJvcGVybHlCb3hlc05vblN0cmljdCA9IHRydWU7XG4gICAgICAgIHZhciBwcm9wZXJseUJveGVzU3RyaWN0ID0gdHJ1ZTtcbiAgICAgICAgdmFyIHRocmV3RXhjZXB0aW9uID0gZmFsc2U7XG4gICAgICAgIGlmIChtZXRob2QpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgbWV0aG9kLmNhbGwoJ2ZvbycsIGZ1bmN0aW9uIChfLCBfXywgY29udGV4dCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGNvbnRleHQgIT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJseUJveGVzTm9uU3RyaWN0ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIG1ldGhvZC5jYWxsKFsxXSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAndXNlIHN0cmljdCc7XG5cbiAgICAgICAgICAgICAgICAgICAgcHJvcGVybHlCb3hlc1N0cmljdCA9IHR5cGVvZiB0aGlzID09PSAnc3RyaW5nJztcbiAgICAgICAgICAgICAgICB9LCAneCcpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIHRocmV3RXhjZXB0aW9uID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gISFtZXRob2QgJiYgIXRocmV3RXhjZXB0aW9uICYmIHByb3Blcmx5Qm94ZXNOb25TdHJpY3QgJiYgcHJvcGVybHlCb3hlc1N0cmljdDtcbiAgICB9O1xuXG4gICAgZGVmaW5lUHJvcGVydGllcyhBcnJheVByb3RvdHlwZSwge1xuICAgICAgICBmb3JFYWNoOiBmdW5jdGlvbiBmb3JFYWNoKGNhbGxiYWNrZm4vKiwgdGhpc0FyZyovKSB7XG4gICAgICAgICAgICB2YXIgb2JqZWN0ID0gRVMuVG9PYmplY3QodGhpcyk7XG4gICAgICAgICAgICB2YXIgc2VsZiA9IHNwbGl0U3RyaW5nICYmIGlzU3RyaW5nKHRoaXMpID8gc3RyU3BsaXQodGhpcywgJycpIDogb2JqZWN0O1xuICAgICAgICAgICAgdmFyIGkgPSAtMTtcbiAgICAgICAgICAgIHZhciBsZW5ndGggPSBFUy5Ub1VpbnQzMihzZWxmLmxlbmd0aCk7XG4gICAgICAgICAgICB2YXIgVDtcbiAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICAgIFQgPSBhcmd1bWVudHNbMV07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIElmIG5vIGNhbGxiYWNrIGZ1bmN0aW9uIG9yIGlmIGNhbGxiYWNrIGlzIG5vdCBhIGNhbGxhYmxlIGZ1bmN0aW9uXG4gICAgICAgICAgICBpZiAoIWlzQ2FsbGFibGUoY2FsbGJhY2tmbikpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcnJheS5wcm90b3R5cGUuZm9yRWFjaCBjYWxsYmFjayBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgd2hpbGUgKCsraSA8IGxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGlmIChpIGluIHNlbGYpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSW52b2tlIHRoZSBjYWxsYmFjayBmdW5jdGlvbiB3aXRoIGNhbGwsIHBhc3NpbmcgYXJndW1lbnRzOlxuICAgICAgICAgICAgICAgICAgICAvLyBjb250ZXh0LCBwcm9wZXJ0eSB2YWx1ZSwgcHJvcGVydHkga2V5LCB0aGlzQXJnIG9iamVjdFxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIFQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFja2ZuKHNlbGZbaV0sIGksIG9iamVjdCk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFja2ZuLmNhbGwoVCwgc2VsZltpXSwgaSwgb2JqZWN0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0sICFwcm9wZXJseUJveGVzQ29udGV4dChBcnJheVByb3RvdHlwZS5mb3JFYWNoKSk7XG5cbiAgICAvLyBFUzUgMTUuNC40LjE5XG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuNC40LjE5XG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4vQ29yZV9KYXZhU2NyaXB0XzEuNV9SZWZlcmVuY2UvT2JqZWN0cy9BcnJheS9tYXBcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIG1hcDogZnVuY3Rpb24gbWFwKGNhbGxiYWNrZm4vKiwgdGhpc0FyZyovKSB7XG4gICAgICAgICAgICB2YXIgb2JqZWN0ID0gRVMuVG9PYmplY3QodGhpcyk7XG4gICAgICAgICAgICB2YXIgc2VsZiA9IHNwbGl0U3RyaW5nICYmIGlzU3RyaW5nKHRoaXMpID8gc3RyU3BsaXQodGhpcywgJycpIDogb2JqZWN0O1xuICAgICAgICAgICAgdmFyIGxlbmd0aCA9IEVTLlRvVWludDMyKHNlbGYubGVuZ3RoKTtcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSAkQXJyYXkobGVuZ3RoKTtcbiAgICAgICAgICAgIHZhciBUO1xuICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgVCA9IGFyZ3VtZW50c1sxXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gSWYgbm8gY2FsbGJhY2sgZnVuY3Rpb24gb3IgaWYgY2FsbGJhY2sgaXMgbm90IGEgY2FsbGFibGUgZnVuY3Rpb25cbiAgICAgICAgICAgIGlmICghaXNDYWxsYWJsZShjYWxsYmFja2ZuKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FycmF5LnByb3RvdHlwZS5tYXAgY2FsbGJhY2sgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoaSBpbiBzZWxmKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgVCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdFtpXSA9IGNhbGxiYWNrZm4oc2VsZltpXSwgaSwgb2JqZWN0KTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdFtpXSA9IGNhbGxiYWNrZm4uY2FsbChULCBzZWxmW2ldLCBpLCBvYmplY3QpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuICAgIH0sICFwcm9wZXJseUJveGVzQ29udGV4dChBcnJheVByb3RvdHlwZS5tYXApKTtcblxuICAgIC8vIEVTNSAxNS40LjQuMjBcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS40LjQuMjBcbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9Db3JlX0phdmFTY3JpcHRfMS41X1JlZmVyZW5jZS9PYmplY3RzL0FycmF5L2ZpbHRlclxuICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgZmlsdGVyOiBmdW5jdGlvbiBmaWx0ZXIoY2FsbGJhY2tmbi8qLCB0aGlzQXJnKi8pIHtcbiAgICAgICAgICAgIHZhciBvYmplY3QgPSBFUy5Ub09iamVjdCh0aGlzKTtcbiAgICAgICAgICAgIHZhciBzZWxmID0gc3BsaXRTdHJpbmcgJiYgaXNTdHJpbmcodGhpcykgPyBzdHJTcGxpdCh0aGlzLCAnJykgOiBvYmplY3Q7XG4gICAgICAgICAgICB2YXIgbGVuZ3RoID0gRVMuVG9VaW50MzIoc2VsZi5sZW5ndGgpO1xuICAgICAgICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgICAgICAgdmFyIHZhbHVlO1xuICAgICAgICAgICAgdmFyIFQ7XG4gICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgICAgICBUID0gYXJndW1lbnRzWzFdO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBJZiBubyBjYWxsYmFjayBmdW5jdGlvbiBvciBpZiBjYWxsYmFjayBpcyBub3QgYSBjYWxsYWJsZSBmdW5jdGlvblxuICAgICAgICAgICAgaWYgKCFpc0NhbGxhYmxlKGNhbGxiYWNrZm4pKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJyYXkucHJvdG90eXBlLmZpbHRlciBjYWxsYmFjayBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmIChpIGluIHNlbGYpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBzZWxmW2ldO1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIFQgPT09ICd1bmRlZmluZWQnID8gY2FsbGJhY2tmbih2YWx1ZSwgaSwgb2JqZWN0KSA6IGNhbGxiYWNrZm4uY2FsbChULCB2YWx1ZSwgaSwgb2JqZWN0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcHVzaENhbGwocmVzdWx0LCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgfSwgIXByb3Blcmx5Qm94ZXNDb250ZXh0KEFycmF5UHJvdG90eXBlLmZpbHRlcikpO1xuXG4gICAgLy8gRVM1IDE1LjQuNC4xNlxuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjQuNC4xNlxuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0FycmF5L2V2ZXJ5XG4gICAgZGVmaW5lUHJvcGVydGllcyhBcnJheVByb3RvdHlwZSwge1xuICAgICAgICBldmVyeTogZnVuY3Rpb24gZXZlcnkoY2FsbGJhY2tmbi8qLCB0aGlzQXJnKi8pIHtcbiAgICAgICAgICAgIHZhciBvYmplY3QgPSBFUy5Ub09iamVjdCh0aGlzKTtcbiAgICAgICAgICAgIHZhciBzZWxmID0gc3BsaXRTdHJpbmcgJiYgaXNTdHJpbmcodGhpcykgPyBzdHJTcGxpdCh0aGlzLCAnJykgOiBvYmplY3Q7XG4gICAgICAgICAgICB2YXIgbGVuZ3RoID0gRVMuVG9VaW50MzIoc2VsZi5sZW5ndGgpO1xuICAgICAgICAgICAgdmFyIFQ7XG4gICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgICAgICBUID0gYXJndW1lbnRzWzFdO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBJZiBubyBjYWxsYmFjayBmdW5jdGlvbiBvciBpZiBjYWxsYmFjayBpcyBub3QgYSBjYWxsYWJsZSBmdW5jdGlvblxuICAgICAgICAgICAgaWYgKCFpc0NhbGxhYmxlKGNhbGxiYWNrZm4pKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJyYXkucHJvdG90eXBlLmV2ZXJ5IGNhbGxiYWNrIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGkgaW4gc2VsZiAmJiAhKHR5cGVvZiBUID09PSAndW5kZWZpbmVkJyA/IGNhbGxiYWNrZm4oc2VsZltpXSwgaSwgb2JqZWN0KSA6IGNhbGxiYWNrZm4uY2FsbChULCBzZWxmW2ldLCBpLCBvYmplY3QpKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9LCAhcHJvcGVybHlCb3hlc0NvbnRleHQoQXJyYXlQcm90b3R5cGUuZXZlcnkpKTtcblxuICAgIC8vIEVTNSAxNS40LjQuMTdcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS40LjQuMTdcbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9BcnJheS9zb21lXG4gICAgZGVmaW5lUHJvcGVydGllcyhBcnJheVByb3RvdHlwZSwge1xuICAgICAgICBzb21lOiBmdW5jdGlvbiBzb21lKGNhbGxiYWNrZm4vKiwgdGhpc0FyZyAqLykge1xuICAgICAgICAgICAgdmFyIG9iamVjdCA9IEVTLlRvT2JqZWN0KHRoaXMpO1xuICAgICAgICAgICAgdmFyIHNlbGYgPSBzcGxpdFN0cmluZyAmJiBpc1N0cmluZyh0aGlzKSA/IHN0clNwbGl0KHRoaXMsICcnKSA6IG9iamVjdDtcbiAgICAgICAgICAgIHZhciBsZW5ndGggPSBFUy5Ub1VpbnQzMihzZWxmLmxlbmd0aCk7XG4gICAgICAgICAgICB2YXIgVDtcbiAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICAgIFQgPSBhcmd1bWVudHNbMV07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIElmIG5vIGNhbGxiYWNrIGZ1bmN0aW9uIG9yIGlmIGNhbGxiYWNrIGlzIG5vdCBhIGNhbGxhYmxlIGZ1bmN0aW9uXG4gICAgICAgICAgICBpZiAoIWlzQ2FsbGFibGUoY2FsbGJhY2tmbikpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcnJheS5wcm90b3R5cGUuc29tZSBjYWxsYmFjayBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmIChpIGluIHNlbGYgJiYgKHR5cGVvZiBUID09PSAndW5kZWZpbmVkJyA/IGNhbGxiYWNrZm4oc2VsZltpXSwgaSwgb2JqZWN0KSA6IGNhbGxiYWNrZm4uY2FsbChULCBzZWxmW2ldLCBpLCBvYmplY3QpKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9LCAhcHJvcGVybHlCb3hlc0NvbnRleHQoQXJyYXlQcm90b3R5cGUuc29tZSkpO1xuXG4gICAgLy8gRVM1IDE1LjQuNC4yMVxuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjQuNC4yMVxuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0NvcmVfSmF2YVNjcmlwdF8xLjVfUmVmZXJlbmNlL09iamVjdHMvQXJyYXkvcmVkdWNlXG4gICAgdmFyIHJlZHVjZUNvZXJjZXNUb09iamVjdCA9IGZhbHNlO1xuICAgIGlmIChBcnJheVByb3RvdHlwZS5yZWR1Y2UpIHtcbiAgICAgICAgcmVkdWNlQ29lcmNlc1RvT2JqZWN0ID0gdHlwZW9mIEFycmF5UHJvdG90eXBlLnJlZHVjZS5jYWxsKCdlczUnLCBmdW5jdGlvbiAoXywgX18sIF9fXywgbGlzdCkge1xuICAgICAgICAgICAgcmV0dXJuIGxpc3Q7XG4gICAgICAgIH0pID09PSAnb2JqZWN0JztcbiAgICB9XG4gICAgZGVmaW5lUHJvcGVydGllcyhBcnJheVByb3RvdHlwZSwge1xuICAgICAgICByZWR1Y2U6IGZ1bmN0aW9uIHJlZHVjZShjYWxsYmFja2ZuLyosIGluaXRpYWxWYWx1ZSovKSB7XG4gICAgICAgICAgICB2YXIgb2JqZWN0ID0gRVMuVG9PYmplY3QodGhpcyk7XG4gICAgICAgICAgICB2YXIgc2VsZiA9IHNwbGl0U3RyaW5nICYmIGlzU3RyaW5nKHRoaXMpID8gc3RyU3BsaXQodGhpcywgJycpIDogb2JqZWN0O1xuICAgICAgICAgICAgdmFyIGxlbmd0aCA9IEVTLlRvVWludDMyKHNlbGYubGVuZ3RoKTtcblxuICAgICAgICAgICAgLy8gSWYgbm8gY2FsbGJhY2sgZnVuY3Rpb24gb3IgaWYgY2FsbGJhY2sgaXMgbm90IGEgY2FsbGFibGUgZnVuY3Rpb25cbiAgICAgICAgICAgIGlmICghaXNDYWxsYWJsZShjYWxsYmFja2ZuKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FycmF5LnByb3RvdHlwZS5yZWR1Y2UgY2FsbGJhY2sgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIG5vIHZhbHVlIHRvIHJldHVybiBpZiBubyBpbml0aWFsIHZhbHVlIGFuZCBhbiBlbXB0eSBhcnJheVxuICAgICAgICAgICAgaWYgKGxlbmd0aCA9PT0gMCAmJiBhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigncmVkdWNlIG9mIGVtcHR5IGFycmF5IHdpdGggbm8gaW5pdGlhbCB2YWx1ZScpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgaSA9IDA7XG4gICAgICAgICAgICB2YXIgcmVzdWx0O1xuICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gMikge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGFyZ3VtZW50c1sxXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaSBpbiBzZWxmKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBzZWxmW2krK107XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIGlmIGFycmF5IGNvbnRhaW5zIG5vIHZhbHVlcywgbm8gaW5pdGlhbCB2YWx1ZSB0byByZXR1cm5cbiAgICAgICAgICAgICAgICAgICAgaWYgKCsraSA+PSBsZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3JlZHVjZSBvZiBlbXB0eSBhcnJheSB3aXRoIG5vIGluaXRpYWwgdmFsdWUnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gd2hpbGUgKHRydWUpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGkgaW4gc2VsZikge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBjYWxsYmFja2ZuKHJlc3VsdCwgc2VsZltpXSwgaSwgb2JqZWN0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cbiAgICB9LCAhcmVkdWNlQ29lcmNlc1RvT2JqZWN0KTtcblxuICAgIC8vIEVTNSAxNS40LjQuMjJcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS40LjQuMjJcbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9Db3JlX0phdmFTY3JpcHRfMS41X1JlZmVyZW5jZS9PYmplY3RzL0FycmF5L3JlZHVjZVJpZ2h0XG4gICAgdmFyIHJlZHVjZVJpZ2h0Q29lcmNlc1RvT2JqZWN0ID0gZmFsc2U7XG4gICAgaWYgKEFycmF5UHJvdG90eXBlLnJlZHVjZVJpZ2h0KSB7XG4gICAgICAgIHJlZHVjZVJpZ2h0Q29lcmNlc1RvT2JqZWN0ID0gdHlwZW9mIEFycmF5UHJvdG90eXBlLnJlZHVjZVJpZ2h0LmNhbGwoJ2VzNScsIGZ1bmN0aW9uIChfLCBfXywgX19fLCBsaXN0KSB7XG4gICAgICAgICAgICByZXR1cm4gbGlzdDtcbiAgICAgICAgfSkgPT09ICdvYmplY3QnO1xuICAgIH1cbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIHJlZHVjZVJpZ2h0OiBmdW5jdGlvbiByZWR1Y2VSaWdodChjYWxsYmFja2ZuLyosIGluaXRpYWwqLykge1xuICAgICAgICAgICAgdmFyIG9iamVjdCA9IEVTLlRvT2JqZWN0KHRoaXMpO1xuICAgICAgICAgICAgdmFyIHNlbGYgPSBzcGxpdFN0cmluZyAmJiBpc1N0cmluZyh0aGlzKSA/IHN0clNwbGl0KHRoaXMsICcnKSA6IG9iamVjdDtcbiAgICAgICAgICAgIHZhciBsZW5ndGggPSBFUy5Ub1VpbnQzMihzZWxmLmxlbmd0aCk7XG5cbiAgICAgICAgICAgIC8vIElmIG5vIGNhbGxiYWNrIGZ1bmN0aW9uIG9yIGlmIGNhbGxiYWNrIGlzIG5vdCBhIGNhbGxhYmxlIGZ1bmN0aW9uXG4gICAgICAgICAgICBpZiAoIWlzQ2FsbGFibGUoY2FsbGJhY2tmbikpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcnJheS5wcm90b3R5cGUucmVkdWNlUmlnaHQgY2FsbGJhY2sgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIG5vIHZhbHVlIHRvIHJldHVybiBpZiBubyBpbml0aWFsIHZhbHVlLCBlbXB0eSBhcnJheVxuICAgICAgICAgICAgaWYgKGxlbmd0aCA9PT0gMCAmJiBhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigncmVkdWNlUmlnaHQgb2YgZW1wdHkgYXJyYXkgd2l0aCBubyBpbml0aWFsIHZhbHVlJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciByZXN1bHQ7XG4gICAgICAgICAgICB2YXIgaSA9IGxlbmd0aCAtIDE7XG4gICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSAyKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gYXJndW1lbnRzWzFdO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpIGluIHNlbGYpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHNlbGZbaS0tXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gaWYgYXJyYXkgY29udGFpbnMgbm8gdmFsdWVzLCBubyBpbml0aWFsIHZhbHVlIHRvIHJldHVyblxuICAgICAgICAgICAgICAgICAgICBpZiAoLS1pIDwgMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigncmVkdWNlUmlnaHQgb2YgZW1wdHkgYXJyYXkgd2l0aCBubyBpbml0aWFsIHZhbHVlJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IHdoaWxlICh0cnVlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGkgPCAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICAgIGlmIChpIGluIHNlbGYpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gY2FsbGJhY2tmbihyZXN1bHQsIHNlbGZbaV0sIGksIG9iamVjdCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSB3aGlsZSAoaS0tKTtcblxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuICAgIH0sICFyZWR1Y2VSaWdodENvZXJjZXNUb09iamVjdCk7XG5cbiAgICAvLyBFUzUgMTUuNC40LjE0XG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuNC40LjE0XG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4vSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvQXJyYXkvaW5kZXhPZlxuICAgIHZhciBoYXNGaXJlZm94MkluZGV4T2ZCdWcgPSBBcnJheVByb3RvdHlwZS5pbmRleE9mICYmIFswLCAxXS5pbmRleE9mKDEsIDIpICE9PSAtMTtcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIGluZGV4T2Y6IGZ1bmN0aW9uIGluZGV4T2Yoc2VhcmNoRWxlbWVudC8qLCBmcm9tSW5kZXggKi8pIHtcbiAgICAgICAgICAgIHZhciBzZWxmID0gc3BsaXRTdHJpbmcgJiYgaXNTdHJpbmcodGhpcykgPyBzdHJTcGxpdCh0aGlzLCAnJykgOiBFUy5Ub09iamVjdCh0aGlzKTtcbiAgICAgICAgICAgIHZhciBsZW5ndGggPSBFUy5Ub1VpbnQzMihzZWxmLmxlbmd0aCk7XG5cbiAgICAgICAgICAgIGlmIChsZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBpID0gMDtcbiAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICAgIGkgPSBFUy5Ub0ludGVnZXIoYXJndW1lbnRzWzFdKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gaGFuZGxlIG5lZ2F0aXZlIGluZGljZXNcbiAgICAgICAgICAgIGkgPSBpID49IDAgPyBpIDogbWF4KDAsIGxlbmd0aCArIGkpO1xuICAgICAgICAgICAgZm9yICg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmIChpIGluIHNlbGYgJiYgc2VsZltpXSA9PT0gc2VhcmNoRWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH1cbiAgICB9LCBoYXNGaXJlZm94MkluZGV4T2ZCdWcpO1xuXG4gICAgLy8gRVM1IDE1LjQuNC4xNVxuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjQuNC4xNVxuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0FycmF5L2xhc3RJbmRleE9mXG4gICAgdmFyIGhhc0ZpcmVmb3gyTGFzdEluZGV4T2ZCdWcgPSBBcnJheVByb3RvdHlwZS5sYXN0SW5kZXhPZiAmJiBbMCwgMV0ubGFzdEluZGV4T2YoMCwgLTMpICE9PSAtMTtcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIGxhc3RJbmRleE9mOiBmdW5jdGlvbiBsYXN0SW5kZXhPZihzZWFyY2hFbGVtZW50LyosIGZyb21JbmRleCAqLykge1xuICAgICAgICAgICAgdmFyIHNlbGYgPSBzcGxpdFN0cmluZyAmJiBpc1N0cmluZyh0aGlzKSA/IHN0clNwbGl0KHRoaXMsICcnKSA6IEVTLlRvT2JqZWN0KHRoaXMpO1xuICAgICAgICAgICAgdmFyIGxlbmd0aCA9IEVTLlRvVWludDMyKHNlbGYubGVuZ3RoKTtcblxuICAgICAgICAgICAgaWYgKGxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBpID0gbGVuZ3RoIC0gMTtcbiAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICAgIGkgPSBtaW4oaSwgRVMuVG9JbnRlZ2VyKGFyZ3VtZW50c1sxXSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gaGFuZGxlIG5lZ2F0aXZlIGluZGljZXNcbiAgICAgICAgICAgIGkgPSBpID49IDAgPyBpIDogbGVuZ3RoIC0gTWF0aC5hYnMoaSk7XG4gICAgICAgICAgICBmb3IgKDsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgICAgICBpZiAoaSBpbiBzZWxmICYmIHNlYXJjaEVsZW1lbnQgPT09IHNlbGZbaV0pIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICB9XG4gICAgfSwgaGFzRmlyZWZveDJMYXN0SW5kZXhPZkJ1Zyk7XG5cbiAgICAvLyBFUzUgMTUuNC40LjEyXG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuNC40LjEyXG4gICAgdmFyIHNwbGljZU5vb3BSZXR1cm5zRW1wdHlBcnJheSA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBhID0gWzEsIDJdO1xuICAgICAgICB2YXIgcmVzdWx0ID0gYS5zcGxpY2UoKTtcbiAgICAgICAgcmV0dXJuIGEubGVuZ3RoID09PSAyICYmIGlzQXJyYXkocmVzdWx0KSAmJiByZXN1bHQubGVuZ3RoID09PSAwO1xuICAgIH0oKSk7XG4gICAgZGVmaW5lUHJvcGVydGllcyhBcnJheVByb3RvdHlwZSwge1xuICAgICAgICAvLyBTYWZhcmkgNS4wIGJ1ZyB3aGVyZSAuc3BsaWNlKCkgcmV0dXJucyB1bmRlZmluZWRcbiAgICAgICAgc3BsaWNlOiBmdW5jdGlvbiBzcGxpY2Uoc3RhcnQsIGRlbGV0ZUNvdW50KSB7XG4gICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5X3NwbGljZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSwgIXNwbGljZU5vb3BSZXR1cm5zRW1wdHlBcnJheSk7XG5cbiAgICB2YXIgc3BsaWNlV29ya3NXaXRoRW1wdHlPYmplY3QgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgb2JqID0ge307XG4gICAgICAgIEFycmF5UHJvdG90eXBlLnNwbGljZS5jYWxsKG9iaiwgMCwgMCwgMSk7XG4gICAgICAgIHJldHVybiBvYmoubGVuZ3RoID09PSAxO1xuICAgIH0oKSk7XG4gICAgZGVmaW5lUHJvcGVydGllcyhBcnJheVByb3RvdHlwZSwge1xuICAgICAgICBzcGxpY2U6IGZ1bmN0aW9uIHNwbGljZShzdGFydCwgZGVsZXRlQ291bnQpIHtcbiAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7XG4gICAgICAgICAgICB0aGlzLmxlbmd0aCA9IG1heChFUy5Ub0ludGVnZXIodGhpcy5sZW5ndGgpLCAwKTtcbiAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMCAmJiB0eXBlb2YgZGVsZXRlQ291bnQgIT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICAgICAgYXJncyA9IGFycmF5U2xpY2UoYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgICBpZiAoYXJncy5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgICAgICAgICAgIHB1c2hDYWxsKGFyZ3MsIHRoaXMubGVuZ3RoIC0gc3RhcnQpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGFyZ3NbMV0gPSBFUy5Ub0ludGVnZXIoZGVsZXRlQ291bnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBhcnJheV9zcGxpY2UuYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgIH1cbiAgICB9LCAhc3BsaWNlV29ya3NXaXRoRW1wdHlPYmplY3QpO1xuICAgIHZhciBzcGxpY2VXb3Jrc1dpdGhMYXJnZVNwYXJzZUFycmF5cyA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIFBlciBodHRwczovL2dpdGh1Yi5jb20vZXMtc2hpbXMvZXM1LXNoaW0vaXNzdWVzLzI5NVxuICAgICAgICAvLyBTYWZhcmkgNy84IGJyZWFrcyB3aXRoIHNwYXJzZSBhcnJheXMgb2Ygc2l6ZSAxZTUgb3IgZ3JlYXRlclxuICAgICAgICB2YXIgYXJyID0gbmV3ICRBcnJheSgxZTUpO1xuICAgICAgICAvLyBub3RlOiB0aGUgaW5kZXggTVVTVCBiZSA4IG9yIGxhcmdlciBvciB0aGUgdGVzdCB3aWxsIGZhbHNlIHBhc3NcbiAgICAgICAgYXJyWzhdID0gJ3gnO1xuICAgICAgICBhcnIuc3BsaWNlKDEsIDEpO1xuICAgICAgICAvLyBub3RlOiB0aGlzIHRlc3QgbXVzdCBiZSBkZWZpbmVkICphZnRlciogdGhlIGluZGV4T2Ygc2hpbVxuICAgICAgICAvLyBwZXIgaHR0cHM6Ly9naXRodWIuY29tL2VzLXNoaW1zL2VzNS1zaGltL2lzc3Vlcy8zMTNcbiAgICAgICAgcmV0dXJuIGFyci5pbmRleE9mKCd4JykgPT09IDc7XG4gICAgfSgpKTtcbiAgICB2YXIgc3BsaWNlV29ya3NXaXRoU21hbGxTcGFyc2VBcnJheXMgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBQZXIgaHR0cHM6Ly9naXRodWIuY29tL2VzLXNoaW1zL2VzNS1zaGltL2lzc3Vlcy8yOTVcbiAgICAgICAgLy8gT3BlcmEgMTIuMTUgYnJlYWtzIG9uIHRoaXMsIG5vIGlkZWEgd2h5LlxuICAgICAgICB2YXIgbiA9IDI1NjtcbiAgICAgICAgdmFyIGFyciA9IFtdO1xuICAgICAgICBhcnJbbl0gPSAnYSc7XG4gICAgICAgIGFyci5zcGxpY2UobiArIDEsIDAsICdiJyk7XG4gICAgICAgIHJldHVybiBhcnJbbl0gPT09ICdhJztcbiAgICB9KCkpO1xuICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgc3BsaWNlOiBmdW5jdGlvbiBzcGxpY2Uoc3RhcnQsIGRlbGV0ZUNvdW50KSB7XG4gICAgICAgICAgICB2YXIgTyA9IEVTLlRvT2JqZWN0KHRoaXMpO1xuICAgICAgICAgICAgdmFyIEEgPSBbXTtcbiAgICAgICAgICAgIHZhciBsZW4gPSBFUy5Ub1VpbnQzMihPLmxlbmd0aCk7XG4gICAgICAgICAgICB2YXIgcmVsYXRpdmVTdGFydCA9IEVTLlRvSW50ZWdlcihzdGFydCk7XG4gICAgICAgICAgICB2YXIgYWN0dWFsU3RhcnQgPSByZWxhdGl2ZVN0YXJ0IDwgMCA/IG1heCgobGVuICsgcmVsYXRpdmVTdGFydCksIDApIDogbWluKHJlbGF0aXZlU3RhcnQsIGxlbik7XG4gICAgICAgICAgICB2YXIgYWN0dWFsRGVsZXRlQ291bnQgPSBtaW4obWF4KEVTLlRvSW50ZWdlcihkZWxldGVDb3VudCksIDApLCBsZW4gLSBhY3R1YWxTdGFydCk7XG5cbiAgICAgICAgICAgIHZhciBrID0gMDtcbiAgICAgICAgICAgIHZhciBmcm9tO1xuICAgICAgICAgICAgd2hpbGUgKGsgPCBhY3R1YWxEZWxldGVDb3VudCkge1xuICAgICAgICAgICAgICAgIGZyb20gPSAkU3RyaW5nKGFjdHVhbFN0YXJ0ICsgayk7XG4gICAgICAgICAgICAgICAgaWYgKG93bnMoTywgZnJvbSkpIHtcbiAgICAgICAgICAgICAgICAgICAgQVtrXSA9IE9bZnJvbV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGsgKz0gMTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIGl0ZW1zID0gYXJyYXlTbGljZShhcmd1bWVudHMsIDIpO1xuICAgICAgICAgICAgdmFyIGl0ZW1Db3VudCA9IGl0ZW1zLmxlbmd0aDtcbiAgICAgICAgICAgIHZhciB0bztcbiAgICAgICAgICAgIGlmIChpdGVtQ291bnQgPCBhY3R1YWxEZWxldGVDb3VudCkge1xuICAgICAgICAgICAgICAgIGsgPSBhY3R1YWxTdGFydDtcbiAgICAgICAgICAgICAgICB2YXIgbWF4SyA9IGxlbiAtIGFjdHVhbERlbGV0ZUNvdW50O1xuICAgICAgICAgICAgICAgIHdoaWxlIChrIDwgbWF4Sykge1xuICAgICAgICAgICAgICAgICAgICBmcm9tID0gJFN0cmluZyhrICsgYWN0dWFsRGVsZXRlQ291bnQpO1xuICAgICAgICAgICAgICAgICAgICB0byA9ICRTdHJpbmcoayArIGl0ZW1Db3VudCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChvd25zKE8sIGZyb20pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBPW3RvXSA9IE9bZnJvbV07XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgT1t0b107XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgayArPSAxO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBrID0gbGVuO1xuICAgICAgICAgICAgICAgIHZhciBtaW5LID0gbGVuIC0gYWN0dWFsRGVsZXRlQ291bnQgKyBpdGVtQ291bnQ7XG4gICAgICAgICAgICAgICAgd2hpbGUgKGsgPiBtaW5LKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBPW2sgLSAxXTtcbiAgICAgICAgICAgICAgICAgICAgayAtPSAxO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXRlbUNvdW50ID4gYWN0dWFsRGVsZXRlQ291bnQpIHtcbiAgICAgICAgICAgICAgICBrID0gbGVuIC0gYWN0dWFsRGVsZXRlQ291bnQ7XG4gICAgICAgICAgICAgICAgd2hpbGUgKGsgPiBhY3R1YWxTdGFydCkge1xuICAgICAgICAgICAgICAgICAgICBmcm9tID0gJFN0cmluZyhrICsgYWN0dWFsRGVsZXRlQ291bnQgLSAxKTtcbiAgICAgICAgICAgICAgICAgICAgdG8gPSAkU3RyaW5nKGsgKyBpdGVtQ291bnQgLSAxKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG93bnMoTywgZnJvbSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIE9bdG9dID0gT1tmcm9tXTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBPW3RvXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBrIC09IDE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgayA9IGFjdHVhbFN0YXJ0O1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpdGVtcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgIE9ba10gPSBpdGVtc1tpXTtcbiAgICAgICAgICAgICAgICBrICs9IDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBPLmxlbmd0aCA9IGxlbiAtIGFjdHVhbERlbGV0ZUNvdW50ICsgaXRlbUNvdW50O1xuXG4gICAgICAgICAgICByZXR1cm4gQTtcbiAgICAgICAgfVxuICAgIH0sICFzcGxpY2VXb3Jrc1dpdGhMYXJnZVNwYXJzZUFycmF5cyB8fCAhc3BsaWNlV29ya3NXaXRoU21hbGxTcGFyc2VBcnJheXMpO1xuXG4gICAgdmFyIG9yaWdpbmFsSm9pbiA9IEFycmF5UHJvdG90eXBlLmpvaW47XG4gICAgdmFyIGhhc1N0cmluZ0pvaW5CdWc7XG4gICAgdHJ5IHtcbiAgICAgICAgaGFzU3RyaW5nSm9pbkJ1ZyA9IEFycmF5LnByb3RvdHlwZS5qb2luLmNhbGwoJzEyMycsICcsJykgIT09ICcxLDIsMyc7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBoYXNTdHJpbmdKb2luQnVnID0gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKGhhc1N0cmluZ0pvaW5CdWcpIHtcbiAgICAgICAgZGVmaW5lUHJvcGVydGllcyhBcnJheVByb3RvdHlwZSwge1xuICAgICAgICAgICAgam9pbjogZnVuY3Rpb24gam9pbihzZXBhcmF0b3IpIHtcbiAgICAgICAgICAgICAgICB2YXIgc2VwID0gdHlwZW9mIHNlcGFyYXRvciA9PT0gJ3VuZGVmaW5lZCcgPyAnLCcgOiBzZXBhcmF0b3I7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9yaWdpbmFsSm9pbi5jYWxsKGlzU3RyaW5nKHRoaXMpID8gc3RyU3BsaXQodGhpcywgJycpIDogdGhpcywgc2VwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgaGFzU3RyaW5nSm9pbkJ1Zyk7XG4gICAgfVxuXG4gICAgdmFyIGhhc0pvaW5VbmRlZmluZWRCdWcgPSBbMSwgMl0uam9pbih1bmRlZmluZWQpICE9PSAnMSwyJztcbiAgICBpZiAoaGFzSm9pblVuZGVmaW5lZEJ1Zykge1xuICAgICAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgICAgICBqb2luOiBmdW5jdGlvbiBqb2luKHNlcGFyYXRvcikge1xuICAgICAgICAgICAgICAgIHZhciBzZXAgPSB0eXBlb2Ygc2VwYXJhdG9yID09PSAndW5kZWZpbmVkJyA/ICcsJyA6IHNlcGFyYXRvcjtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3JpZ2luYWxKb2luLmNhbGwodGhpcywgc2VwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgaGFzSm9pblVuZGVmaW5lZEJ1Zyk7XG4gICAgfVxuXG4gICAgdmFyIHB1c2hTaGltID0gZnVuY3Rpb24gcHVzaChpdGVtKSB7XG4gICAgICAgIHZhciBPID0gRVMuVG9PYmplY3QodGhpcyk7XG4gICAgICAgIHZhciBuID0gRVMuVG9VaW50MzIoTy5sZW5ndGgpO1xuICAgICAgICB2YXIgaSA9IDA7XG4gICAgICAgIHdoaWxlIChpIDwgYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgT1tuICsgaV0gPSBhcmd1bWVudHNbaV07XG4gICAgICAgICAgICBpICs9IDE7XG4gICAgICAgIH1cbiAgICAgICAgTy5sZW5ndGggPSBuICsgaTtcbiAgICAgICAgcmV0dXJuIG4gKyBpO1xuICAgIH07XG5cbiAgICB2YXIgcHVzaElzTm90R2VuZXJpYyA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBvYmogPSB7fTtcbiAgICAgICAgdmFyIHJlc3VsdCA9IEFycmF5LnByb3RvdHlwZS5wdXNoLmNhbGwob2JqLCB1bmRlZmluZWQpO1xuICAgICAgICByZXR1cm4gcmVzdWx0ICE9PSAxIHx8IG9iai5sZW5ndGggIT09IDEgfHwgdHlwZW9mIG9ialswXSAhPT0gJ3VuZGVmaW5lZCcgfHwgIW93bnMob2JqLCAwKTtcbiAgICB9KCkpO1xuICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgcHVzaDogZnVuY3Rpb24gcHVzaChpdGVtKSB7XG4gICAgICAgICAgICBpZiAoaXNBcnJheSh0aGlzKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBhcnJheV9wdXNoLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcHVzaFNoaW0uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfVxuICAgIH0sIHB1c2hJc05vdEdlbmVyaWMpO1xuXG4gICAgLy8gVGhpcyBmaXhlcyBhIHZlcnkgd2VpcmQgYnVnIGluIE9wZXJhIDEwLjYgd2hlbiBwdXNoaW5nIGB1bmRlZmluZWRcbiAgICB2YXIgcHVzaFVuZGVmaW5lZElzV2VpcmQgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgYXJyID0gW107XG4gICAgICAgIHZhciByZXN1bHQgPSBhcnIucHVzaCh1bmRlZmluZWQpO1xuICAgICAgICByZXR1cm4gcmVzdWx0ICE9PSAxIHx8IGFyci5sZW5ndGggIT09IDEgfHwgdHlwZW9mIGFyclswXSAhPT0gJ3VuZGVmaW5lZCcgfHwgIW93bnMoYXJyLCAwKTtcbiAgICB9KCkpO1xuICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHsgcHVzaDogcHVzaFNoaW0gfSwgcHVzaFVuZGVmaW5lZElzV2VpcmQpO1xuXG4gICAgLy8gRVM1IDE1LjIuMy4xNFxuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmlvLyN4MTUuNC40LjEwXG4gICAgLy8gRml4IGJveGVkIHN0cmluZyBidWdcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIHNsaWNlOiBmdW5jdGlvbiAoc3RhcnQsIGVuZCkge1xuICAgICAgICAgICAgdmFyIGFyciA9IGlzU3RyaW5nKHRoaXMpID8gc3RyU3BsaXQodGhpcywgJycpIDogdGhpcztcbiAgICAgICAgICAgIHJldHVybiBhcnJheVNsaWNlQXBwbHkoYXJyLCBhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgfSwgc3BsaXRTdHJpbmcpO1xuXG4gICAgdmFyIHNvcnRJZ25vcmVzTm9uRnVuY3Rpb25zID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIFsxLCAyXS5zb3J0KG51bGwpO1xuICAgICAgICAgICAgWzEsIDJdLnNvcnQoe30pO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9KCkpO1xuICAgIHZhciBzb3J0VGhyb3dzT25SZWdleCA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIHRoaXMgaXMgYSBwcm9ibGVtIGluIEZpcmVmb3ggNCwgaW4gd2hpY2ggYHR5cGVvZiAvYS8gPT09ICdmdW5jdGlvbidgXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBbMSwgMl0uc29ydCgvYS8pO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9IGNhdGNoIChlKSB7fVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9KCkpO1xuICAgIHZhciBzb3J0SWdub3Jlc1VuZGVmaW5lZCA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIGFwcGxpZXMgaW4gSUUgOCwgZm9yIG9uZS5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIFsxLCAyXS5zb3J0KHVuZGVmaW5lZCk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0oKSk7XG4gICAgZGVmaW5lUHJvcGVydGllcyhBcnJheVByb3RvdHlwZSwge1xuICAgICAgICBzb3J0OiBmdW5jdGlvbiBzb3J0KGNvbXBhcmVGbikge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBjb21wYXJlRm4gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5U29ydCh0aGlzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghaXNDYWxsYWJsZShjb21wYXJlRm4pKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJyYXkucHJvdG90eXBlLnNvcnQgY2FsbGJhY2sgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gYXJyYXlTb3J0KHRoaXMsIGNvbXBhcmVGbik7XG4gICAgICAgIH1cbiAgICB9LCBzb3J0SWdub3Jlc05vbkZ1bmN0aW9ucyB8fCAhc29ydElnbm9yZXNVbmRlZmluZWQgfHwgIXNvcnRUaHJvd3NPblJlZ2V4KTtcblxuICAgIC8vXG4gICAgLy8gT2JqZWN0XG4gICAgLy8gPT09PT09XG4gICAgLy9cblxuICAgIC8vIEVTNSAxNS4yLjMuMTRcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS4yLjMuMTRcblxuICAgIC8vIGh0dHA6Ly93aGF0dGhlaGVhZHNhaWQuY29tLzIwMTAvMTAvYS1zYWZlci1vYmplY3Qta2V5cy1jb21wYXRpYmlsaXR5LWltcGxlbWVudGF0aW9uXG4gICAgdmFyIGhhc0RvbnRFbnVtQnVnID0gIWlzRW51bSh7ICd0b1N0cmluZyc6IG51bGwgfSwgJ3RvU3RyaW5nJyk7XG4gICAgdmFyIGhhc1Byb3RvRW51bUJ1ZyA9IGlzRW51bShmdW5jdGlvbiAoKSB7fSwgJ3Byb3RvdHlwZScpO1xuICAgIHZhciBoYXNTdHJpbmdFbnVtQnVnID0gIW93bnMoJ3gnLCAnMCcpO1xuICAgIHZhciBlcXVhbHNDb25zdHJ1Y3RvclByb3RvdHlwZSA9IGZ1bmN0aW9uIChvKSB7XG4gICAgICAgIHZhciBjdG9yID0gby5jb25zdHJ1Y3RvcjtcbiAgICAgICAgcmV0dXJuIGN0b3IgJiYgY3Rvci5wcm90b3R5cGUgPT09IG87XG4gICAgfTtcbiAgICB2YXIgYmxhY2tsaXN0ZWRLZXlzID0ge1xuICAgICAgICAkd2luZG93OiB0cnVlLFxuICAgICAgICAkY29uc29sZTogdHJ1ZSxcbiAgICAgICAgJHBhcmVudDogdHJ1ZSxcbiAgICAgICAgJHNlbGY6IHRydWUsXG4gICAgICAgICRmcmFtZTogdHJ1ZSxcbiAgICAgICAgJGZyYW1lczogdHJ1ZSxcbiAgICAgICAgJGZyYW1lRWxlbWVudDogdHJ1ZSxcbiAgICAgICAgJHdlYmtpdEluZGV4ZWREQjogdHJ1ZSxcbiAgICAgICAgJHdlYmtpdFN0b3JhZ2VJbmZvOiB0cnVlLFxuICAgICAgICAkZXh0ZXJuYWw6IHRydWVcbiAgICB9O1xuICAgIHZhciBoYXNBdXRvbWF0aW9uRXF1YWxpdHlCdWcgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICAvKiBnbG9iYWxzIHdpbmRvdyAqL1xuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKHZhciBrIGluIHdpbmRvdykge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBpZiAoIWJsYWNrbGlzdGVkS2V5c1snJCcgKyBrXSAmJiBvd25zKHdpbmRvdywgaykgJiYgd2luZG93W2tdICE9PSBudWxsICYmIHR5cGVvZiB3aW5kb3dba10gPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAgICAgICAgIGVxdWFsc0NvbnN0cnVjdG9yUHJvdG90eXBlKHdpbmRvd1trXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9KCkpO1xuICAgIHZhciBlcXVhbHNDb25zdHJ1Y3RvclByb3RvdHlwZUlmTm90QnVnZ3kgPSBmdW5jdGlvbiAob2JqZWN0KSB7XG4gICAgICAgIGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJyB8fCAhaGFzQXV0b21hdGlvbkVxdWFsaXR5QnVnKSB7XG4gICAgICAgICAgICByZXR1cm4gZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUob2JqZWN0KTtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIGVxdWFsc0NvbnN0cnVjdG9yUHJvdG90eXBlKG9iamVjdCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgdmFyIGRvbnRFbnVtcyA9IFtcbiAgICAgICAgJ3RvU3RyaW5nJyxcbiAgICAgICAgJ3RvTG9jYWxlU3RyaW5nJyxcbiAgICAgICAgJ3ZhbHVlT2YnLFxuICAgICAgICAnaGFzT3duUHJvcGVydHknLFxuICAgICAgICAnaXNQcm90b3R5cGVPZicsXG4gICAgICAgICdwcm9wZXJ0eUlzRW51bWVyYWJsZScsXG4gICAgICAgICdjb25zdHJ1Y3RvcidcbiAgICBdO1xuICAgIHZhciBkb250RW51bXNMZW5ndGggPSBkb250RW51bXMubGVuZ3RoO1xuXG4gICAgLy8gdGFrZW4gZGlyZWN0bHkgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vbGpoYXJiL2lzLWFyZ3VtZW50cy9ibG9iL21hc3Rlci9pbmRleC5qc1xuICAgIC8vIGNhbiBiZSByZXBsYWNlZCB3aXRoIHJlcXVpcmUoJ2lzLWFyZ3VtZW50cycpIGlmIHdlIGV2ZXIgdXNlIGEgYnVpbGQgcHJvY2VzcyBpbnN0ZWFkXG4gICAgdmFyIGlzU3RhbmRhcmRBcmd1bWVudHMgPSBmdW5jdGlvbiBpc0FyZ3VtZW50cyh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdG9TdHIodmFsdWUpID09PSAnW29iamVjdCBBcmd1bWVudHNdJztcbiAgICB9O1xuICAgIHZhciBpc0xlZ2FjeUFyZ3VtZW50cyA9IGZ1bmN0aW9uIGlzQXJndW1lbnRzKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZSAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJlxuICAgICAgICAgICAgdHlwZW9mIHZhbHVlLmxlbmd0aCA9PT0gJ251bWJlcicgJiZcbiAgICAgICAgICAgIHZhbHVlLmxlbmd0aCA+PSAwICYmXG4gICAgICAgICAgICAhaXNBcnJheSh2YWx1ZSkgJiZcbiAgICAgICAgICAgIGlzQ2FsbGFibGUodmFsdWUuY2FsbGVlKTtcbiAgICB9O1xuICAgIHZhciBpc0FyZ3VtZW50cyA9IGlzU3RhbmRhcmRBcmd1bWVudHMoYXJndW1lbnRzKSA/IGlzU3RhbmRhcmRBcmd1bWVudHMgOiBpc0xlZ2FjeUFyZ3VtZW50cztcblxuICAgIGRlZmluZVByb3BlcnRpZXMoJE9iamVjdCwge1xuICAgICAgICBrZXlzOiBmdW5jdGlvbiBrZXlzKG9iamVjdCkge1xuICAgICAgICAgICAgdmFyIGlzRm4gPSBpc0NhbGxhYmxlKG9iamVjdCk7XG4gICAgICAgICAgICB2YXIgaXNBcmdzID0gaXNBcmd1bWVudHMob2JqZWN0KTtcbiAgICAgICAgICAgIHZhciBpc09iamVjdCA9IG9iamVjdCAhPT0gbnVsbCAmJiB0eXBlb2Ygb2JqZWN0ID09PSAnb2JqZWN0JztcbiAgICAgICAgICAgIHZhciBpc1N0ciA9IGlzT2JqZWN0ICYmIGlzU3RyaW5nKG9iamVjdCk7XG5cbiAgICAgICAgICAgIGlmICghaXNPYmplY3QgJiYgIWlzRm4gJiYgIWlzQXJncykge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ09iamVjdC5rZXlzIGNhbGxlZCBvbiBhIG5vbi1vYmplY3QnKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIHRoZUtleXMgPSBbXTtcbiAgICAgICAgICAgIHZhciBza2lwUHJvdG8gPSBoYXNQcm90b0VudW1CdWcgJiYgaXNGbjtcbiAgICAgICAgICAgIGlmICgoaXNTdHIgJiYgaGFzU3RyaW5nRW51bUJ1ZykgfHwgaXNBcmdzKSB7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgcHVzaENhbGwodGhlS2V5cywgJFN0cmluZyhpKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIWlzQXJncykge1xuICAgICAgICAgICAgICAgIGZvciAodmFyIG5hbWUgaW4gb2JqZWN0KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghKHNraXBQcm90byAmJiBuYW1lID09PSAncHJvdG90eXBlJykgJiYgb3ducyhvYmplY3QsIG5hbWUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwdXNoQ2FsbCh0aGVLZXlzLCAkU3RyaW5nKG5hbWUpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGhhc0RvbnRFbnVtQnVnKSB7XG4gICAgICAgICAgICAgICAgdmFyIHNraXBDb25zdHJ1Y3RvciA9IGVxdWFsc0NvbnN0cnVjdG9yUHJvdG90eXBlSWZOb3RCdWdneShvYmplY3QpO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgZG9udEVudW1zTGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGRvbnRFbnVtID0gZG9udEVudW1zW2pdO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIShza2lwQ29uc3RydWN0b3IgJiYgZG9udEVudW0gPT09ICdjb25zdHJ1Y3RvcicpICYmIG93bnMob2JqZWN0LCBkb250RW51bSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1c2hDYWxsKHRoZUtleXMsIGRvbnRFbnVtKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGVLZXlzO1xuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICB2YXIga2V5c1dvcmtzV2l0aEFyZ3VtZW50cyA9ICRPYmplY3Qua2V5cyAmJiAoZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBTYWZhcmkgNS4wIGJ1Z1xuICAgICAgICByZXR1cm4gJE9iamVjdC5rZXlzKGFyZ3VtZW50cykubGVuZ3RoID09PSAyO1xuICAgIH0oMSwgMikpO1xuICAgIHZhciBrZXlzSGFzQXJndW1lbnRzTGVuZ3RoQnVnID0gJE9iamVjdC5rZXlzICYmIChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBhcmdLZXlzID0gJE9iamVjdC5rZXlzKGFyZ3VtZW50cyk7XG4gICAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoICE9PSAxIHx8IGFyZ0tleXMubGVuZ3RoICE9PSAxIHx8IGFyZ0tleXNbMF0gIT09IDE7XG4gICAgfSgxKSk7XG4gICAgdmFyIG9yaWdpbmFsS2V5cyA9ICRPYmplY3Qua2V5cztcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKCRPYmplY3QsIHtcbiAgICAgICAga2V5czogZnVuY3Rpb24ga2V5cyhvYmplY3QpIHtcbiAgICAgICAgICAgIGlmIChpc0FyZ3VtZW50cyhvYmplY3QpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9yaWdpbmFsS2V5cyhhcnJheVNsaWNlKG9iamVjdCkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3JpZ2luYWxLZXlzKG9iamVjdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LCAha2V5c1dvcmtzV2l0aEFyZ3VtZW50cyB8fCBrZXlzSGFzQXJndW1lbnRzTGVuZ3RoQnVnKTtcblxuICAgIC8vXG4gICAgLy8gRGF0ZVxuICAgIC8vID09PT1cbiAgICAvL1xuXG4gICAgdmFyIGhhc05lZ2F0aXZlTW9udGhZZWFyQnVnID0gbmV3IERhdGUoLTM1MDk4MjczMjk2MDAyOTIpLmdldFVUQ01vbnRoKCkgIT09IDA7XG4gICAgdmFyIGFOZWdhdGl2ZVRlc3REYXRlID0gbmV3IERhdGUoLTE1MDk4NDIyODk2MDAyOTIpO1xuICAgIHZhciBhUG9zaXRpdmVUZXN0RGF0ZSA9IG5ldyBEYXRlKDE0NDk2NjI0MDAwMDApO1xuICAgIHZhciBoYXNUb1VUQ1N0cmluZ0Zvcm1hdEJ1ZyA9IGFOZWdhdGl2ZVRlc3REYXRlLnRvVVRDU3RyaW5nKCkgIT09ICdNb24sIDAxIEphbiAtNDU4NzUgMTE6NTk6NTkgR01UJztcbiAgICB2YXIgaGFzVG9EYXRlU3RyaW5nRm9ybWF0QnVnO1xuICAgIHZhciBoYXNUb1N0cmluZ0Zvcm1hdEJ1ZztcbiAgICB2YXIgdGltZVpvbmVPZmZzZXQgPSBhTmVnYXRpdmVUZXN0RGF0ZS5nZXRUaW1lem9uZU9mZnNldCgpO1xuICAgIGlmICh0aW1lWm9uZU9mZnNldCA8IC03MjApIHtcbiAgICAgICAgaGFzVG9EYXRlU3RyaW5nRm9ybWF0QnVnID0gYU5lZ2F0aXZlVGVzdERhdGUudG9EYXRlU3RyaW5nKCkgIT09ICdUdWUgSmFuIDAyIC00NTg3NSc7XG4gICAgICAgIGhhc1RvU3RyaW5nRm9ybWF0QnVnID0gISgvXlRodSBEZWMgMTAgMjAxNSBcXGRcXGQ6XFxkXFxkOlxcZFxcZCBHTVRbLVxcK11cXGRcXGRcXGRcXGQoPzogfCQpLykudGVzdChhUG9zaXRpdmVUZXN0RGF0ZS50b1N0cmluZygpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBoYXNUb0RhdGVTdHJpbmdGb3JtYXRCdWcgPSBhTmVnYXRpdmVUZXN0RGF0ZS50b0RhdGVTdHJpbmcoKSAhPT0gJ01vbiBKYW4gMDEgLTQ1ODc1JztcbiAgICAgICAgaGFzVG9TdHJpbmdGb3JtYXRCdWcgPSAhKC9eV2VkIERlYyAwOSAyMDE1IFxcZFxcZDpcXGRcXGQ6XFxkXFxkIEdNVFstXFwrXVxcZFxcZFxcZFxcZCg/OiB8JCkvKS50ZXN0KGFQb3NpdGl2ZVRlc3REYXRlLnRvU3RyaW5nKCkpO1xuICAgIH1cblxuICAgIHZhciBvcmlnaW5hbEdldEZ1bGxZZWFyID0gY2FsbC5iaW5kKERhdGUucHJvdG90eXBlLmdldEZ1bGxZZWFyKTtcbiAgICB2YXIgb3JpZ2luYWxHZXRNb250aCA9IGNhbGwuYmluZChEYXRlLnByb3RvdHlwZS5nZXRNb250aCk7XG4gICAgdmFyIG9yaWdpbmFsR2V0RGF0ZSA9IGNhbGwuYmluZChEYXRlLnByb3RvdHlwZS5nZXREYXRlKTtcbiAgICB2YXIgb3JpZ2luYWxHZXRVVENGdWxsWWVhciA9IGNhbGwuYmluZChEYXRlLnByb3RvdHlwZS5nZXRVVENGdWxsWWVhcik7XG4gICAgdmFyIG9yaWdpbmFsR2V0VVRDTW9udGggPSBjYWxsLmJpbmQoRGF0ZS5wcm90b3R5cGUuZ2V0VVRDTW9udGgpO1xuICAgIHZhciBvcmlnaW5hbEdldFVUQ0RhdGUgPSBjYWxsLmJpbmQoRGF0ZS5wcm90b3R5cGUuZ2V0VVRDRGF0ZSk7XG4gICAgdmFyIG9yaWdpbmFsR2V0VVRDRGF5ID0gY2FsbC5iaW5kKERhdGUucHJvdG90eXBlLmdldFVUQ0RheSk7XG4gICAgdmFyIG9yaWdpbmFsR2V0VVRDSG91cnMgPSBjYWxsLmJpbmQoRGF0ZS5wcm90b3R5cGUuZ2V0VVRDSG91cnMpO1xuICAgIHZhciBvcmlnaW5hbEdldFVUQ01pbnV0ZXMgPSBjYWxsLmJpbmQoRGF0ZS5wcm90b3R5cGUuZ2V0VVRDTWludXRlcyk7XG4gICAgdmFyIG9yaWdpbmFsR2V0VVRDU2Vjb25kcyA9IGNhbGwuYmluZChEYXRlLnByb3RvdHlwZS5nZXRVVENTZWNvbmRzKTtcbiAgICB2YXIgb3JpZ2luYWxHZXRVVENNaWxsaXNlY29uZHMgPSBjYWxsLmJpbmQoRGF0ZS5wcm90b3R5cGUuZ2V0VVRDTWlsbGlzZWNvbmRzKTtcbiAgICB2YXIgZGF5TmFtZSA9IFsnU3VuJywgJ01vbicsICdUdWUnLCAnV2VkJywgJ1RodScsICdGcmknLCAnU2F0J107XG4gICAgdmFyIG1vbnRoTmFtZSA9IFsnSmFuJywgJ0ZlYicsICdNYXInLCAnQXByJywgJ01heScsICdKdW4nLCAnSnVsJywgJ0F1ZycsICdTZXAnLCAnT2N0JywgJ05vdicsICdEZWMnXTtcbiAgICB2YXIgZGF5c0luTW9udGggPSBmdW5jdGlvbiBkYXlzSW5Nb250aChtb250aCwgeWVhcikge1xuICAgICAgICByZXR1cm4gb3JpZ2luYWxHZXREYXRlKG5ldyBEYXRlKHllYXIsIG1vbnRoLCAwKSk7XG4gICAgfTtcblxuICAgIGRlZmluZVByb3BlcnRpZXMoRGF0ZS5wcm90b3R5cGUsIHtcbiAgICAgICAgZ2V0RnVsbFllYXI6IGZ1bmN0aW9uIGdldEZ1bGxZZWFyKCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzIHx8ICEodGhpcyBpbnN0YW5jZW9mIERhdGUpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndGhpcyBpcyBub3QgYSBEYXRlIG9iamVjdC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciB5ZWFyID0gb3JpZ2luYWxHZXRGdWxsWWVhcih0aGlzKTtcbiAgICAgICAgICAgIGlmICh5ZWFyIDwgMCAmJiBvcmlnaW5hbEdldE1vbnRoKHRoaXMpID4gMTEpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4geWVhciArIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4geWVhcjtcbiAgICAgICAgfSxcbiAgICAgICAgZ2V0TW9udGg6IGZ1bmN0aW9uIGdldE1vbnRoKCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzIHx8ICEodGhpcyBpbnN0YW5jZW9mIERhdGUpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndGhpcyBpcyBub3QgYSBEYXRlIG9iamVjdC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciB5ZWFyID0gb3JpZ2luYWxHZXRGdWxsWWVhcih0aGlzKTtcbiAgICAgICAgICAgIHZhciBtb250aCA9IG9yaWdpbmFsR2V0TW9udGgodGhpcyk7XG4gICAgICAgICAgICBpZiAoeWVhciA8IDAgJiYgbW9udGggPiAxMSkge1xuICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG1vbnRoO1xuICAgICAgICB9LFxuICAgICAgICBnZXREYXRlOiBmdW5jdGlvbiBnZXREYXRlKCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzIHx8ICEodGhpcyBpbnN0YW5jZW9mIERhdGUpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndGhpcyBpcyBub3QgYSBEYXRlIG9iamVjdC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciB5ZWFyID0gb3JpZ2luYWxHZXRGdWxsWWVhcih0aGlzKTtcbiAgICAgICAgICAgIHZhciBtb250aCA9IG9yaWdpbmFsR2V0TW9udGgodGhpcyk7XG4gICAgICAgICAgICB2YXIgZGF0ZSA9IG9yaWdpbmFsR2V0RGF0ZSh0aGlzKTtcbiAgICAgICAgICAgIGlmICh5ZWFyIDwgMCAmJiBtb250aCA+IDExKSB7XG4gICAgICAgICAgICAgICAgaWYgKG1vbnRoID09PSAxMikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFyIGRheXMgPSBkYXlzSW5Nb250aCgwLCB5ZWFyICsgMSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChkYXlzIC0gZGF0ZSkgKyAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGRhdGU7XG4gICAgICAgIH0sXG4gICAgICAgIGdldFVUQ0Z1bGxZZWFyOiBmdW5jdGlvbiBnZXRVVENGdWxsWWVhcigpIHtcbiAgICAgICAgICAgIGlmICghdGhpcyB8fCAhKHRoaXMgaW5zdGFuY2VvZiBEYXRlKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3RoaXMgaXMgbm90IGEgRGF0ZSBvYmplY3QuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgeWVhciA9IG9yaWdpbmFsR2V0VVRDRnVsbFllYXIodGhpcyk7XG4gICAgICAgICAgICBpZiAoeWVhciA8IDAgJiYgb3JpZ2luYWxHZXRVVENNb250aCh0aGlzKSA+IDExKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHllYXIgKyAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHllYXI7XG4gICAgICAgIH0sXG4gICAgICAgIGdldFVUQ01vbnRoOiBmdW5jdGlvbiBnZXRVVENNb250aCgpIHtcbiAgICAgICAgICAgIGlmICghdGhpcyB8fCAhKHRoaXMgaW5zdGFuY2VvZiBEYXRlKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3RoaXMgaXMgbm90IGEgRGF0ZSBvYmplY3QuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgeWVhciA9IG9yaWdpbmFsR2V0VVRDRnVsbFllYXIodGhpcyk7XG4gICAgICAgICAgICB2YXIgbW9udGggPSBvcmlnaW5hbEdldFVUQ01vbnRoKHRoaXMpO1xuICAgICAgICAgICAgaWYgKHllYXIgPCAwICYmIG1vbnRoID4gMTEpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBtb250aDtcbiAgICAgICAgfSxcbiAgICAgICAgZ2V0VVRDRGF0ZTogZnVuY3Rpb24gZ2V0VVRDRGF0ZSgpIHtcbiAgICAgICAgICAgIGlmICghdGhpcyB8fCAhKHRoaXMgaW5zdGFuY2VvZiBEYXRlKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3RoaXMgaXMgbm90IGEgRGF0ZSBvYmplY3QuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgeWVhciA9IG9yaWdpbmFsR2V0VVRDRnVsbFllYXIodGhpcyk7XG4gICAgICAgICAgICB2YXIgbW9udGggPSBvcmlnaW5hbEdldFVUQ01vbnRoKHRoaXMpO1xuICAgICAgICAgICAgdmFyIGRhdGUgPSBvcmlnaW5hbEdldFVUQ0RhdGUodGhpcyk7XG4gICAgICAgICAgICBpZiAoeWVhciA8IDAgJiYgbW9udGggPiAxMSkge1xuICAgICAgICAgICAgICAgIGlmIChtb250aCA9PT0gMTIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhciBkYXlzID0gZGF5c0luTW9udGgoMCwgeWVhciArIDEpO1xuICAgICAgICAgICAgICAgIHJldHVybiAoZGF5cyAtIGRhdGUpICsgMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBkYXRlO1xuICAgICAgICB9XG4gICAgfSwgaGFzTmVnYXRpdmVNb250aFllYXJCdWcpO1xuXG4gICAgZGVmaW5lUHJvcGVydGllcyhEYXRlLnByb3RvdHlwZSwge1xuICAgICAgICB0b1VUQ1N0cmluZzogZnVuY3Rpb24gdG9VVENTdHJpbmcoKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMgfHwgISh0aGlzIGluc3RhbmNlb2YgRGF0ZSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd0aGlzIGlzIG5vdCBhIERhdGUgb2JqZWN0LicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGRheSA9IG9yaWdpbmFsR2V0VVRDRGF5KHRoaXMpO1xuICAgICAgICAgICAgdmFyIGRhdGUgPSBvcmlnaW5hbEdldFVUQ0RhdGUodGhpcyk7XG4gICAgICAgICAgICB2YXIgbW9udGggPSBvcmlnaW5hbEdldFVUQ01vbnRoKHRoaXMpO1xuICAgICAgICAgICAgdmFyIHllYXIgPSBvcmlnaW5hbEdldFVUQ0Z1bGxZZWFyKHRoaXMpO1xuICAgICAgICAgICAgdmFyIGhvdXIgPSBvcmlnaW5hbEdldFVUQ0hvdXJzKHRoaXMpO1xuICAgICAgICAgICAgdmFyIG1pbnV0ZSA9IG9yaWdpbmFsR2V0VVRDTWludXRlcyh0aGlzKTtcbiAgICAgICAgICAgIHZhciBzZWNvbmQgPSBvcmlnaW5hbEdldFVUQ1NlY29uZHModGhpcyk7XG4gICAgICAgICAgICByZXR1cm4gZGF5TmFtZVtkYXldICsgJywgJyArXG4gICAgICAgICAgICAgICAgKGRhdGUgPCAxMCA/ICcwJyArIGRhdGUgOiBkYXRlKSArICcgJyArXG4gICAgICAgICAgICAgICAgbW9udGhOYW1lW21vbnRoXSArICcgJyArXG4gICAgICAgICAgICAgICAgeWVhciArICcgJyArXG4gICAgICAgICAgICAgICAgKGhvdXIgPCAxMCA/ICcwJyArIGhvdXIgOiBob3VyKSArICc6JyArXG4gICAgICAgICAgICAgICAgKG1pbnV0ZSA8IDEwID8gJzAnICsgbWludXRlIDogbWludXRlKSArICc6JyArXG4gICAgICAgICAgICAgICAgKHNlY29uZCA8IDEwID8gJzAnICsgc2Vjb25kIDogc2Vjb25kKSArICcgR01UJztcbiAgICAgICAgfVxuICAgIH0sIGhhc05lZ2F0aXZlTW9udGhZZWFyQnVnIHx8IGhhc1RvVVRDU3RyaW5nRm9ybWF0QnVnKTtcblxuICAgIC8vIE9wZXJhIDEyIGhhcyBgLGBcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKERhdGUucHJvdG90eXBlLCB7XG4gICAgICAgIHRvRGF0ZVN0cmluZzogZnVuY3Rpb24gdG9EYXRlU3RyaW5nKCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzIHx8ICEodGhpcyBpbnN0YW5jZW9mIERhdGUpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndGhpcyBpcyBub3QgYSBEYXRlIG9iamVjdC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBkYXkgPSB0aGlzLmdldERheSgpO1xuICAgICAgICAgICAgdmFyIGRhdGUgPSB0aGlzLmdldERhdGUoKTtcbiAgICAgICAgICAgIHZhciBtb250aCA9IHRoaXMuZ2V0TW9udGgoKTtcbiAgICAgICAgICAgIHZhciB5ZWFyID0gdGhpcy5nZXRGdWxsWWVhcigpO1xuICAgICAgICAgICAgcmV0dXJuIGRheU5hbWVbZGF5XSArICcgJyArXG4gICAgICAgICAgICAgICAgbW9udGhOYW1lW21vbnRoXSArICcgJyArXG4gICAgICAgICAgICAgICAgKGRhdGUgPCAxMCA/ICcwJyArIGRhdGUgOiBkYXRlKSArICcgJyArXG4gICAgICAgICAgICAgICAgeWVhcjtcbiAgICAgICAgfVxuICAgIH0sIGhhc05lZ2F0aXZlTW9udGhZZWFyQnVnIHx8IGhhc1RvRGF0ZVN0cmluZ0Zvcm1hdEJ1Zyk7XG5cbiAgICAvLyBjYW4ndCB1c2UgZGVmaW5lUHJvcGVydGllcyBoZXJlIGJlY2F1c2Ugb2YgdG9TdHJpbmcgZW51bWVyYXRpb24gaXNzdWUgaW4gSUUgPD0gOFxuICAgIGlmIChoYXNOZWdhdGl2ZU1vbnRoWWVhckJ1ZyB8fCBoYXNUb1N0cmluZ0Zvcm1hdEJ1Zykge1xuICAgICAgICBEYXRlLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzIHx8ICEodGhpcyBpbnN0YW5jZW9mIERhdGUpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndGhpcyBpcyBub3QgYSBEYXRlIG9iamVjdC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBkYXkgPSB0aGlzLmdldERheSgpO1xuICAgICAgICAgICAgdmFyIGRhdGUgPSB0aGlzLmdldERhdGUoKTtcbiAgICAgICAgICAgIHZhciBtb250aCA9IHRoaXMuZ2V0TW9udGgoKTtcbiAgICAgICAgICAgIHZhciB5ZWFyID0gdGhpcy5nZXRGdWxsWWVhcigpO1xuICAgICAgICAgICAgdmFyIGhvdXIgPSB0aGlzLmdldEhvdXJzKCk7XG4gICAgICAgICAgICB2YXIgbWludXRlID0gdGhpcy5nZXRNaW51dGVzKCk7XG4gICAgICAgICAgICB2YXIgc2Vjb25kID0gdGhpcy5nZXRTZWNvbmRzKCk7XG4gICAgICAgICAgICB2YXIgdGltZXpvbmVPZmZzZXQgPSB0aGlzLmdldFRpbWV6b25lT2Zmc2V0KCk7XG4gICAgICAgICAgICB2YXIgaG91cnNPZmZzZXQgPSBNYXRoLmZsb29yKE1hdGguYWJzKHRpbWV6b25lT2Zmc2V0KSAvIDYwKTtcbiAgICAgICAgICAgIHZhciBtaW51dGVzT2Zmc2V0ID0gTWF0aC5mbG9vcihNYXRoLmFicyh0aW1lem9uZU9mZnNldCkgJSA2MCk7XG4gICAgICAgICAgICByZXR1cm4gZGF5TmFtZVtkYXldICsgJyAnICtcbiAgICAgICAgICAgICAgICBtb250aE5hbWVbbW9udGhdICsgJyAnICtcbiAgICAgICAgICAgICAgICAoZGF0ZSA8IDEwID8gJzAnICsgZGF0ZSA6IGRhdGUpICsgJyAnICtcbiAgICAgICAgICAgICAgICB5ZWFyICsgJyAnICtcbiAgICAgICAgICAgICAgICAoaG91ciA8IDEwID8gJzAnICsgaG91ciA6IGhvdXIpICsgJzonICtcbiAgICAgICAgICAgICAgICAobWludXRlIDwgMTAgPyAnMCcgKyBtaW51dGUgOiBtaW51dGUpICsgJzonICtcbiAgICAgICAgICAgICAgICAoc2Vjb25kIDwgMTAgPyAnMCcgKyBzZWNvbmQgOiBzZWNvbmQpICsgJyBHTVQnICtcbiAgICAgICAgICAgICAgICAodGltZXpvbmVPZmZzZXQgPiAwID8gJy0nIDogJysnKSArXG4gICAgICAgICAgICAgICAgKGhvdXJzT2Zmc2V0IDwgMTAgPyAnMCcgKyBob3Vyc09mZnNldCA6IGhvdXJzT2Zmc2V0KSArXG4gICAgICAgICAgICAgICAgKG1pbnV0ZXNPZmZzZXQgPCAxMCA/ICcwJyArIG1pbnV0ZXNPZmZzZXQgOiBtaW51dGVzT2Zmc2V0KTtcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKHN1cHBvcnRzRGVzY3JpcHRvcnMpIHtcbiAgICAgICAgICAgICRPYmplY3QuZGVmaW5lUHJvcGVydHkoRGF0ZS5wcm90b3R5cGUsICd0b1N0cmluZycsIHtcbiAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgd3JpdGFibGU6IHRydWVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gRVM1IDE1LjkuNS40M1xuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjkuNS40M1xuICAgIC8vIFRoaXMgZnVuY3Rpb24gcmV0dXJucyBhIFN0cmluZyB2YWx1ZSByZXByZXNlbnQgdGhlIGluc3RhbmNlIGluIHRpbWVcbiAgICAvLyByZXByZXNlbnRlZCBieSB0aGlzIERhdGUgb2JqZWN0LiBUaGUgZm9ybWF0IG9mIHRoZSBTdHJpbmcgaXMgdGhlIERhdGUgVGltZVxuICAgIC8vIHN0cmluZyBmb3JtYXQgZGVmaW5lZCBpbiAxNS45LjEuMTUuIEFsbCBmaWVsZHMgYXJlIHByZXNlbnQgaW4gdGhlIFN0cmluZy5cbiAgICAvLyBUaGUgdGltZSB6b25lIGlzIGFsd2F5cyBVVEMsIGRlbm90ZWQgYnkgdGhlIHN1ZmZpeCBaLiBJZiB0aGUgdGltZSB2YWx1ZSBvZlxuICAgIC8vIHRoaXMgb2JqZWN0IGlzIG5vdCBhIGZpbml0ZSBOdW1iZXIgYSBSYW5nZUVycm9yIGV4Y2VwdGlvbiBpcyB0aHJvd24uXG4gICAgdmFyIG5lZ2F0aXZlRGF0ZSA9IC02MjE5ODc1NTIwMDAwMDtcbiAgICB2YXIgbmVnYXRpdmVZZWFyU3RyaW5nID0gJy0wMDAwMDEnO1xuICAgIHZhciBoYXNOZWdhdGl2ZURhdGVCdWcgPSBEYXRlLnByb3RvdHlwZS50b0lTT1N0cmluZyAmJiBuZXcgRGF0ZShuZWdhdGl2ZURhdGUpLnRvSVNPU3RyaW5nKCkuaW5kZXhPZihuZWdhdGl2ZVllYXJTdHJpbmcpID09PSAtMTtcbiAgICB2YXIgaGFzU2FmYXJpNTFEYXRlQnVnID0gRGF0ZS5wcm90b3R5cGUudG9JU09TdHJpbmcgJiYgbmV3IERhdGUoLTEpLnRvSVNPU3RyaW5nKCkgIT09ICcxOTY5LTEyLTMxVDIzOjU5OjU5Ljk5OVonO1xuXG4gICAgdmFyIGdldFRpbWUgPSBjYWxsLmJpbmQoRGF0ZS5wcm90b3R5cGUuZ2V0VGltZSk7XG5cbiAgICBkZWZpbmVQcm9wZXJ0aWVzKERhdGUucHJvdG90eXBlLCB7XG4gICAgICAgIHRvSVNPU3RyaW5nOiBmdW5jdGlvbiB0b0lTT1N0cmluZygpIHtcbiAgICAgICAgICAgIGlmICghaXNGaW5pdGUodGhpcykgfHwgIWlzRmluaXRlKGdldFRpbWUodGhpcykpKSB7XG4gICAgICAgICAgICAgICAgLy8gQWRvcGUgUGhvdG9zaG9wIHJlcXVpcmVzIHRoZSBzZWNvbmQgY2hlY2suXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0RhdGUucHJvdG90eXBlLnRvSVNPU3RyaW5nIGNhbGxlZCBvbiBub24tZmluaXRlIHZhbHVlLicpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgeWVhciA9IG9yaWdpbmFsR2V0VVRDRnVsbFllYXIodGhpcyk7XG5cbiAgICAgICAgICAgIHZhciBtb250aCA9IG9yaWdpbmFsR2V0VVRDTW9udGgodGhpcyk7XG4gICAgICAgICAgICAvLyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2VzLXNoaW1zL2VzNS1zaGltL2lzc3Vlcy8xMTFcbiAgICAgICAgICAgIHllYXIgKz0gTWF0aC5mbG9vcihtb250aCAvIDEyKTtcbiAgICAgICAgICAgIG1vbnRoID0gKG1vbnRoICUgMTIgKyAxMikgJSAxMjtcblxuICAgICAgICAgICAgLy8gdGhlIGRhdGUgdGltZSBzdHJpbmcgZm9ybWF0IGlzIHNwZWNpZmllZCBpbiAxNS45LjEuMTUuXG4gICAgICAgICAgICB2YXIgcmVzdWx0ID0gW21vbnRoICsgMSwgb3JpZ2luYWxHZXRVVENEYXRlKHRoaXMpLCBvcmlnaW5hbEdldFVUQ0hvdXJzKHRoaXMpLCBvcmlnaW5hbEdldFVUQ01pbnV0ZXModGhpcyksIG9yaWdpbmFsR2V0VVRDU2Vjb25kcyh0aGlzKV07XG4gICAgICAgICAgICB5ZWFyID0gKFxuICAgICAgICAgICAgICAgICh5ZWFyIDwgMCA/ICctJyA6ICh5ZWFyID4gOTk5OSA/ICcrJyA6ICcnKSkgK1xuICAgICAgICAgICAgICAgIHN0clNsaWNlKCcwMDAwMCcgKyBNYXRoLmFicyh5ZWFyKSwgKDAgPD0geWVhciAmJiB5ZWFyIDw9IDk5OTkpID8gLTQgOiAtNilcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVzdWx0Lmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgLy8gcGFkIG1vbnRocywgZGF5cywgaG91cnMsIG1pbnV0ZXMsIGFuZCBzZWNvbmRzIHRvIGhhdmUgdHdvIGRpZ2l0cy5cbiAgICAgICAgICAgICAgICByZXN1bHRbaV0gPSBzdHJTbGljZSgnMDAnICsgcmVzdWx0W2ldLCAtMik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBwYWQgbWlsbGlzZWNvbmRzIHRvIGhhdmUgdGhyZWUgZGlnaXRzLlxuICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICB5ZWFyICsgJy0nICsgYXJyYXlTbGljZShyZXN1bHQsIDAsIDIpLmpvaW4oJy0nKSArXG4gICAgICAgICAgICAgICAgJ1QnICsgYXJyYXlTbGljZShyZXN1bHQsIDIpLmpvaW4oJzonKSArICcuJyArXG4gICAgICAgICAgICAgICAgc3RyU2xpY2UoJzAwMCcgKyBvcmlnaW5hbEdldFVUQ01pbGxpc2Vjb25kcyh0aGlzKSwgLTMpICsgJ1onXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfSwgaGFzTmVnYXRpdmVEYXRlQnVnIHx8IGhhc1NhZmFyaTUxRGF0ZUJ1Zyk7XG5cbiAgICAvLyBFUzUgMTUuOS41LjQ0XG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuOS41LjQ0XG4gICAgLy8gVGhpcyBmdW5jdGlvbiBwcm92aWRlcyBhIFN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIERhdGUgb2JqZWN0IGZvciB1c2UgYnlcbiAgICAvLyBKU09OLnN0cmluZ2lmeSAoMTUuMTIuMykuXG4gICAgdmFyIGRhdGVUb0pTT05Jc1N1cHBvcnRlZCA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gRGF0ZS5wcm90b3R5cGUudG9KU09OICYmXG4gICAgICAgICAgICAgICAgbmV3IERhdGUoTmFOKS50b0pTT04oKSA9PT0gbnVsbCAmJlxuICAgICAgICAgICAgICAgIG5ldyBEYXRlKG5lZ2F0aXZlRGF0ZSkudG9KU09OKCkuaW5kZXhPZihuZWdhdGl2ZVllYXJTdHJpbmcpICE9PSAtMSAmJlxuICAgICAgICAgICAgICAgIERhdGUucHJvdG90eXBlLnRvSlNPTi5jYWxsKHsgLy8gZ2VuZXJpY1xuICAgICAgICAgICAgICAgICAgICB0b0lTT1N0cmluZzogZnVuY3Rpb24gKCkgeyByZXR1cm4gdHJ1ZTsgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9KCkpO1xuICAgIGlmICghZGF0ZVRvSlNPTklzU3VwcG9ydGVkKSB7XG4gICAgICAgIERhdGUucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTihrZXkpIHtcbiAgICAgICAgICAgIC8vIFdoZW4gdGhlIHRvSlNPTiBtZXRob2QgaXMgY2FsbGVkIHdpdGggYXJndW1lbnQga2V5LCB0aGUgZm9sbG93aW5nXG4gICAgICAgICAgICAvLyBzdGVwcyBhcmUgdGFrZW46XG5cbiAgICAgICAgICAgIC8vIDEuICBMZXQgTyBiZSB0aGUgcmVzdWx0IG9mIGNhbGxpbmcgVG9PYmplY3QsIGdpdmluZyBpdCB0aGUgdGhpc1xuICAgICAgICAgICAgLy8gdmFsdWUgYXMgaXRzIGFyZ3VtZW50LlxuICAgICAgICAgICAgLy8gMi4gTGV0IHR2IGJlIEVTLlRvUHJpbWl0aXZlKE8sIGhpbnQgTnVtYmVyKS5cbiAgICAgICAgICAgIHZhciBPID0gJE9iamVjdCh0aGlzKTtcbiAgICAgICAgICAgIHZhciB0diA9IEVTLlRvUHJpbWl0aXZlKE8pO1xuICAgICAgICAgICAgLy8gMy4gSWYgdHYgaXMgYSBOdW1iZXIgYW5kIGlzIG5vdCBmaW5pdGUsIHJldHVybiBudWxsLlxuICAgICAgICAgICAgaWYgKHR5cGVvZiB0diA9PT0gJ251bWJlcicgJiYgIWlzRmluaXRlKHR2KSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gNC4gTGV0IHRvSVNPIGJlIHRoZSByZXN1bHQgb2YgY2FsbGluZyB0aGUgW1tHZXRdXSBpbnRlcm5hbCBtZXRob2Qgb2ZcbiAgICAgICAgICAgIC8vIE8gd2l0aCBhcmd1bWVudCBcInRvSVNPU3RyaW5nXCIuXG4gICAgICAgICAgICB2YXIgdG9JU08gPSBPLnRvSVNPU3RyaW5nO1xuICAgICAgICAgICAgLy8gNS4gSWYgSXNDYWxsYWJsZSh0b0lTTykgaXMgZmFsc2UsIHRocm93IGEgVHlwZUVycm9yIGV4Y2VwdGlvbi5cbiAgICAgICAgICAgIGlmICghaXNDYWxsYWJsZSh0b0lTTykpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd0b0lTT1N0cmluZyBwcm9wZXJ0eSBpcyBub3QgY2FsbGFibGUnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIDYuIFJldHVybiB0aGUgcmVzdWx0IG9mIGNhbGxpbmcgdGhlIFtbQ2FsbF1dIGludGVybmFsIG1ldGhvZCBvZlxuICAgICAgICAgICAgLy8gIHRvSVNPIHdpdGggTyBhcyB0aGUgdGhpcyB2YWx1ZSBhbmQgYW4gZW1wdHkgYXJndW1lbnQgbGlzdC5cbiAgICAgICAgICAgIHJldHVybiB0b0lTTy5jYWxsKE8pO1xuXG4gICAgICAgICAgICAvLyBOT1RFIDEgVGhlIGFyZ3VtZW50IGlzIGlnbm9yZWQuXG5cbiAgICAgICAgICAgIC8vIE5PVEUgMiBUaGUgdG9KU09OIGZ1bmN0aW9uIGlzIGludGVudGlvbmFsbHkgZ2VuZXJpYzsgaXQgZG9lcyBub3RcbiAgICAgICAgICAgIC8vIHJlcXVpcmUgdGhhdCBpdHMgdGhpcyB2YWx1ZSBiZSBhIERhdGUgb2JqZWN0LiBUaGVyZWZvcmUsIGl0IGNhbiBiZVxuICAgICAgICAgICAgLy8gdHJhbnNmZXJyZWQgdG8gb3RoZXIga2luZHMgb2Ygb2JqZWN0cyBmb3IgdXNlIGFzIGEgbWV0aG9kLiBIb3dldmVyLFxuICAgICAgICAgICAgLy8gaXQgZG9lcyByZXF1aXJlIHRoYXQgYW55IHN1Y2ggb2JqZWN0IGhhdmUgYSB0b0lTT1N0cmluZyBtZXRob2QuIEFuXG4gICAgICAgICAgICAvLyBvYmplY3QgaXMgZnJlZSB0byB1c2UgdGhlIGFyZ3VtZW50IGtleSB0byBmaWx0ZXIgaXRzXG4gICAgICAgICAgICAvLyBzdHJpbmdpZmljYXRpb24uXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gRVM1IDE1LjkuNC4yXG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuOS40LjJcbiAgICAvLyBiYXNlZCBvbiB3b3JrIHNoYXJlZCBieSBEYW5pZWwgRnJpZXNlbiAoZGFudG1hbilcbiAgICAvLyBodHRwOi8vZ2lzdC5naXRodWIuY29tLzMwMzI0OVxuICAgIHZhciBzdXBwb3J0c0V4dGVuZGVkWWVhcnMgPSBEYXRlLnBhcnNlKCcrMDMzNjU4LTA5LTI3VDAxOjQ2OjQwLjAwMFonKSA9PT0gMWUxNTtcbiAgICB2YXIgYWNjZXB0c0ludmFsaWREYXRlcyA9ICFpc05hTihEYXRlLnBhcnNlKCcyMDEyLTA0LTA0VDI0OjAwOjAwLjUwMFonKSkgfHwgIWlzTmFOKERhdGUucGFyc2UoJzIwMTItMTEtMzFUMjM6NTk6NTkuMDAwWicpKSB8fCAhaXNOYU4oRGF0ZS5wYXJzZSgnMjAxMi0xMi0zMVQyMzo1OTo2MC4wMDBaJykpO1xuICAgIHZhciBkb2VzTm90UGFyc2VZMktOZXdZZWFyID0gaXNOYU4oRGF0ZS5wYXJzZSgnMjAwMC0wMS0wMVQwMDowMDowMC4wMDBaJykpO1xuICAgIGlmIChkb2VzTm90UGFyc2VZMktOZXdZZWFyIHx8IGFjY2VwdHNJbnZhbGlkRGF0ZXMgfHwgIXN1cHBvcnRzRXh0ZW5kZWRZZWFycykge1xuICAgICAgICAvLyBYWFggZ2xvYmFsIGFzc2lnbm1lbnQgd29uJ3Qgd29yayBpbiBlbWJlZGRpbmdzIHRoYXQgdXNlXG4gICAgICAgIC8vIGFuIGFsdGVybmF0ZSBvYmplY3QgZm9yIHRoZSBjb250ZXh0LlxuICAgICAgICAvKiBnbG9iYWwgRGF0ZTogdHJ1ZSAqL1xuICAgICAgICAvKiBlc2xpbnQtZGlzYWJsZSBuby11bmRlZiAqL1xuICAgICAgICB2YXIgbWF4U2FmZVVuc2lnbmVkMzJCaXQgPSBNYXRoLnBvdygyLCAzMSkgLSAxO1xuICAgICAgICB2YXIgaGFzU2FmYXJpU2lnbmVkSW50QnVnID0gaXNBY3R1YWxOYU4obmV3IERhdGUoMTk3MCwgMCwgMSwgMCwgMCwgMCwgbWF4U2FmZVVuc2lnbmVkMzJCaXQgKyAxKS5nZXRUaW1lKCkpO1xuICAgICAgICAvKiBlc2xpbnQtZGlzYWJsZSBuby1pbXBsaWNpdC1nbG9iYWxzICovXG4gICAgICAgIERhdGUgPSAoZnVuY3Rpb24gKE5hdGl2ZURhdGUpIHtcbiAgICAgICAgLyogZXNsaW50LWVuYWJsZSBuby1pbXBsaWNpdC1nbG9iYWxzICovXG4gICAgICAgIC8qIGVzbGludC1lbmFibGUgbm8tdW5kZWYgKi9cbiAgICAgICAgICAgIC8vIERhdGUubGVuZ3RoID09PSA3XG4gICAgICAgICAgICB2YXIgRGF0ZVNoaW0gPSBmdW5jdGlvbiBEYXRlKFksIE0sIEQsIGgsIG0sIHMsIG1zKSB7XG4gICAgICAgICAgICAgICAgdmFyIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgICAgICAgICAgICAgdmFyIGRhdGU7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBOYXRpdmVEYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBzZWNvbmRzID0gcztcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1pbGxpcyA9IG1zO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaGFzU2FmYXJpU2lnbmVkSW50QnVnICYmIGxlbmd0aCA+PSA3ICYmIG1zID4gbWF4U2FmZVVuc2lnbmVkMzJCaXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdvcmsgYXJvdW5kIGEgU2FmYXJpIDgvOSBidWcgd2hlcmUgaXQgdHJlYXRzIHRoZSBzZWNvbmRzIGFzIHNpZ25lZFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1zVG9TaGlmdCA9IE1hdGguZmxvb3IobXMgLyBtYXhTYWZlVW5zaWduZWQzMkJpdCkgKiBtYXhTYWZlVW5zaWduZWQzMkJpdDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzVG9TaGlmdCA9IE1hdGguZmxvb3IobXNUb1NoaWZ0IC8gMWUzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlY29uZHMgKz0gc1RvU2hpZnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICBtaWxsaXMgLT0gc1RvU2hpZnQgKiAxZTM7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZGF0ZSA9IGxlbmd0aCA9PT0gMSAmJiAkU3RyaW5nKFkpID09PSBZID8gLy8gaXNTdHJpbmcoWSlcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdlIGV4cGxpY2l0bHkgcGFzcyBpdCB0aHJvdWdoIHBhcnNlOlxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE5hdGl2ZURhdGUoRGF0ZVNoaW0ucGFyc2UoWSkpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdlIGhhdmUgdG8gbWFudWFsbHkgbWFrZSBjYWxscyBkZXBlbmRpbmcgb24gYXJndW1lbnRcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxlbmd0aCBoZXJlXG4gICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGggPj0gNyA/IG5ldyBOYXRpdmVEYXRlKFksIE0sIEQsIGgsIG0sIHNlY29uZHMsIG1pbGxpcykgOlxuICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoID49IDYgPyBuZXcgTmF0aXZlRGF0ZShZLCBNLCBELCBoLCBtLCBzZWNvbmRzKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGggPj0gNSA/IG5ldyBOYXRpdmVEYXRlKFksIE0sIEQsIGgsIG0pIDpcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCA+PSA0ID8gbmV3IE5hdGl2ZURhdGUoWSwgTSwgRCwgaCkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoID49IDMgPyBuZXcgTmF0aXZlRGF0ZShZLCBNLCBEKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGggPj0gMiA/IG5ldyBOYXRpdmVEYXRlKFksIE0pIDpcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCA+PSAxID8gbmV3IE5hdGl2ZURhdGUoWSBpbnN0YW5jZW9mIE5hdGl2ZURhdGUgPyArWSA6IFkpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE5hdGl2ZURhdGUoKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBkYXRlID0gTmF0aXZlRGF0ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIWlzUHJpbWl0aXZlKGRhdGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFByZXZlbnQgbWl4dXBzIHdpdGggdW5maXhlZCBEYXRlIG9iamVjdFxuICAgICAgICAgICAgICAgICAgICBkZWZpbmVQcm9wZXJ0aWVzKGRhdGUsIHsgY29uc3RydWN0b3I6IERhdGVTaGltIH0sIHRydWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gZGF0ZTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8vIDE1LjkuMS4xNSBEYXRlIFRpbWUgU3RyaW5nIEZvcm1hdC5cbiAgICAgICAgICAgIHZhciBpc29EYXRlRXhwcmVzc2lvbiA9IG5ldyBSZWdFeHAoJ14nICtcbiAgICAgICAgICAgICAgICAnKFxcXFxkezR9fFsrLV1cXFxcZHs2fSknICsgLy8gZm91ci1kaWdpdCB5ZWFyIGNhcHR1cmUgb3Igc2lnbiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyA2LWRpZ2l0IGV4dGVuZGVkIHllYXJcbiAgICAgICAgICAgICAgICAnKD86LShcXFxcZHsyfSknICsgLy8gb3B0aW9uYWwgbW9udGggY2FwdHVyZVxuICAgICAgICAgICAgICAgICcoPzotKFxcXFxkezJ9KScgKyAvLyBvcHRpb25hbCBkYXkgY2FwdHVyZVxuICAgICAgICAgICAgICAgICcoPzonICsgLy8gY2FwdHVyZSBob3VyczptaW51dGVzOnNlY29uZHMubWlsbGlzZWNvbmRzXG4gICAgICAgICAgICAgICAgICAgICdUKFxcXFxkezJ9KScgKyAvLyBob3VycyBjYXB0dXJlXG4gICAgICAgICAgICAgICAgICAgICc6KFxcXFxkezJ9KScgKyAvLyBtaW51dGVzIGNhcHR1cmVcbiAgICAgICAgICAgICAgICAgICAgJyg/OicgKyAvLyBvcHRpb25hbCA6c2Vjb25kcy5taWxsaXNlY29uZHNcbiAgICAgICAgICAgICAgICAgICAgICAgICc6KFxcXFxkezJ9KScgKyAvLyBzZWNvbmRzIGNhcHR1cmVcbiAgICAgICAgICAgICAgICAgICAgICAgICcoPzooXFxcXC5cXFxcZHsxLH0pKT8nICsgLy8gbWlsbGlzZWNvbmRzIGNhcHR1cmVcbiAgICAgICAgICAgICAgICAgICAgJyk/JyArXG4gICAgICAgICAgICAgICAgJygnICsgLy8gY2FwdHVyZSBVVEMgb2Zmc2V0IGNvbXBvbmVudFxuICAgICAgICAgICAgICAgICAgICAnWnwnICsgLy8gVVRDIGNhcHR1cmVcbiAgICAgICAgICAgICAgICAgICAgJyg/OicgKyAvLyBvZmZzZXQgc3BlY2lmaWVyICsvLWhvdXJzOm1pbnV0ZXNcbiAgICAgICAgICAgICAgICAgICAgICAgICcoWy0rXSknICsgLy8gc2lnbiBjYXB0dXJlXG4gICAgICAgICAgICAgICAgICAgICAgICAnKFxcXFxkezJ9KScgKyAvLyBob3VycyBvZmZzZXQgY2FwdHVyZVxuICAgICAgICAgICAgICAgICAgICAgICAgJzooXFxcXGR7Mn0pJyArIC8vIG1pbnV0ZXMgb2Zmc2V0IGNhcHR1cmVcbiAgICAgICAgICAgICAgICAgICAgJyknICtcbiAgICAgICAgICAgICAgICAnKT8pPyk/KT8nICtcbiAgICAgICAgICAgICckJyk7XG5cbiAgICAgICAgICAgIHZhciBtb250aHMgPSBbMCwgMzEsIDU5LCA5MCwgMTIwLCAxNTEsIDE4MSwgMjEyLCAyNDMsIDI3MywgMzA0LCAzMzQsIDM2NV07XG5cbiAgICAgICAgICAgIHZhciBkYXlGcm9tTW9udGggPSBmdW5jdGlvbiBkYXlGcm9tTW9udGgoeWVhciwgbW9udGgpIHtcbiAgICAgICAgICAgICAgICB2YXIgdCA9IG1vbnRoID4gMSA/IDEgOiAwO1xuICAgICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgICAgIG1vbnRoc1ttb250aF0gK1xuICAgICAgICAgICAgICAgICAgICBNYXRoLmZsb29yKCh5ZWFyIC0gMTk2OSArIHQpIC8gNCkgLVxuICAgICAgICAgICAgICAgICAgICBNYXRoLmZsb29yKCh5ZWFyIC0gMTkwMSArIHQpIC8gMTAwKSArXG4gICAgICAgICAgICAgICAgICAgIE1hdGguZmxvb3IoKHllYXIgLSAxNjAxICsgdCkgLyA0MDApICtcbiAgICAgICAgICAgICAgICAgICAgMzY1ICogKHllYXIgLSAxOTcwKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB2YXIgdG9VVEMgPSBmdW5jdGlvbiB0b1VUQyh0KSB7XG4gICAgICAgICAgICAgICAgdmFyIHMgPSAwO1xuICAgICAgICAgICAgICAgIHZhciBtcyA9IHQ7XG4gICAgICAgICAgICAgICAgaWYgKGhhc1NhZmFyaVNpZ25lZEludEJ1ZyAmJiBtcyA+IG1heFNhZmVVbnNpZ25lZDMyQml0KSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHdvcmsgYXJvdW5kIGEgU2FmYXJpIDgvOSBidWcgd2hlcmUgaXQgdHJlYXRzIHRoZSBzZWNvbmRzIGFzIHNpZ25lZFxuICAgICAgICAgICAgICAgICAgICB2YXIgbXNUb1NoaWZ0ID0gTWF0aC5mbG9vcihtcyAvIG1heFNhZmVVbnNpZ25lZDMyQml0KSAqIG1heFNhZmVVbnNpZ25lZDMyQml0O1xuICAgICAgICAgICAgICAgICAgICB2YXIgc1RvU2hpZnQgPSBNYXRoLmZsb29yKG1zVG9TaGlmdCAvIDFlMyk7XG4gICAgICAgICAgICAgICAgICAgIHMgKz0gc1RvU2hpZnQ7XG4gICAgICAgICAgICAgICAgICAgIG1zIC09IHNUb1NoaWZ0ICogMWUzO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gJE51bWJlcihuZXcgTmF0aXZlRGF0ZSgxOTcwLCAwLCAxLCAwLCAwLCBzLCBtcykpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLy8gQ29weSBhbnkgY3VzdG9tIG1ldGhvZHMgYSAzcmQgcGFydHkgbGlicmFyeSBtYXkgaGF2ZSBhZGRlZFxuICAgICAgICAgICAgZm9yICh2YXIga2V5IGluIE5hdGl2ZURhdGUpIHtcbiAgICAgICAgICAgICAgICBpZiAob3ducyhOYXRpdmVEYXRlLCBrZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgIERhdGVTaGltW2tleV0gPSBOYXRpdmVEYXRlW2tleV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBDb3B5IFwibmF0aXZlXCIgbWV0aG9kcyBleHBsaWNpdGx5OyB0aGV5IG1heSBiZSBub24tZW51bWVyYWJsZVxuICAgICAgICAgICAgZGVmaW5lUHJvcGVydGllcyhEYXRlU2hpbSwge1xuICAgICAgICAgICAgICAgIG5vdzogTmF0aXZlRGF0ZS5ub3csXG4gICAgICAgICAgICAgICAgVVRDOiBOYXRpdmVEYXRlLlVUQ1xuICAgICAgICAgICAgfSwgdHJ1ZSk7XG4gICAgICAgICAgICBEYXRlU2hpbS5wcm90b3R5cGUgPSBOYXRpdmVEYXRlLnByb3RvdHlwZTtcbiAgICAgICAgICAgIGRlZmluZVByb3BlcnRpZXMoRGF0ZVNoaW0ucHJvdG90eXBlLCB7XG4gICAgICAgICAgICAgICAgY29uc3RydWN0b3I6IERhdGVTaGltXG4gICAgICAgICAgICB9LCB0cnVlKTtcblxuICAgICAgICAgICAgLy8gVXBncmFkZSBEYXRlLnBhcnNlIHRvIGhhbmRsZSBzaW1wbGlmaWVkIElTTyA4NjAxIHN0cmluZ3NcbiAgICAgICAgICAgIHZhciBwYXJzZVNoaW0gPSBmdW5jdGlvbiBwYXJzZShzdHJpbmcpIHtcbiAgICAgICAgICAgICAgICB2YXIgbWF0Y2ggPSBpc29EYXRlRXhwcmVzc2lvbi5leGVjKHN0cmluZyk7XG4gICAgICAgICAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHBhcnNlIG1vbnRocywgZGF5cywgaG91cnMsIG1pbnV0ZXMsIHNlY29uZHMsIGFuZCBtaWxsaXNlY29uZHNcbiAgICAgICAgICAgICAgICAgICAgLy8gcHJvdmlkZSBkZWZhdWx0IHZhbHVlcyBpZiBuZWNlc3NhcnlcbiAgICAgICAgICAgICAgICAgICAgLy8gcGFyc2UgdGhlIFVUQyBvZmZzZXQgY29tcG9uZW50XG4gICAgICAgICAgICAgICAgICAgIHZhciB5ZWFyID0gJE51bWJlcihtYXRjaFsxXSksXG4gICAgICAgICAgICAgICAgICAgICAgICBtb250aCA9ICROdW1iZXIobWF0Y2hbMl0gfHwgMSkgLSAxLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGF5ID0gJE51bWJlcihtYXRjaFszXSB8fCAxKSAtIDEsXG4gICAgICAgICAgICAgICAgICAgICAgICBob3VyID0gJE51bWJlcihtYXRjaFs0XSB8fCAwKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1pbnV0ZSA9ICROdW1iZXIobWF0Y2hbNV0gfHwgMCksXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWNvbmQgPSAkTnVtYmVyKG1hdGNoWzZdIHx8IDApLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWlsbGlzZWNvbmQgPSBNYXRoLmZsb29yKCROdW1iZXIobWF0Y2hbN10gfHwgMCkgKiAxMDAwKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdoZW4gdGltZSB6b25lIGlzIG1pc3NlZCwgbG9jYWwgb2Zmc2V0IHNob3VsZCBiZSB1c2VkXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyAoRVMgNS4xIGJ1ZylcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNlZSBodHRwczovL2J1Z3MuZWNtYXNjcmlwdC5vcmcvc2hvd19idWcuY2dpP2lkPTExMlxuICAgICAgICAgICAgICAgICAgICAgICAgaXNMb2NhbFRpbWUgPSBCb29sZWFuKG1hdGNoWzRdICYmICFtYXRjaFs4XSksXG4gICAgICAgICAgICAgICAgICAgICAgICBzaWduT2Zmc2V0ID0gbWF0Y2hbOV0gPT09ICctJyA/IDEgOiAtMSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGhvdXJPZmZzZXQgPSAkTnVtYmVyKG1hdGNoWzEwXSB8fCAwKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1pbnV0ZU9mZnNldCA9ICROdW1iZXIobWF0Y2hbMTFdIHx8IDApLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0O1xuICAgICAgICAgICAgICAgICAgICB2YXIgaGFzTWludXRlc09yU2Vjb25kc09yTWlsbGlzZWNvbmRzID0gbWludXRlID4gMCB8fCBzZWNvbmQgPiAwIHx8IG1pbGxpc2Vjb25kID4gMDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgaG91ciA8IChoYXNNaW51dGVzT3JTZWNvbmRzT3JNaWxsaXNlY29uZHMgPyAyNCA6IDI1KSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgbWludXRlIDwgNjAgJiYgc2Vjb25kIDwgNjAgJiYgbWlsbGlzZWNvbmQgPCAxMDAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBtb250aCA+IC0xICYmIG1vbnRoIDwgMTIgJiYgaG91ck9mZnNldCA8IDI0ICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBtaW51dGVPZmZzZXQgPCA2MCAmJiAvLyBkZXRlY3QgaW52YWxpZCBvZmZzZXRzXG4gICAgICAgICAgICAgICAgICAgICAgICBkYXkgPiAtMSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgZGF5IDwgKGRheUZyb21Nb250aCh5ZWFyLCBtb250aCArIDEpIC0gZGF5RnJvbU1vbnRoKHllYXIsIG1vbnRoKSlcbiAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRheUZyb21Nb250aCh5ZWFyLCBtb250aCkgKyBkYXkpICogMjQgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhvdXIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhvdXJPZmZzZXQgKiBzaWduT2Zmc2V0XG4gICAgICAgICAgICAgICAgICAgICAgICApICogNjA7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlc3VsdCArIG1pbnV0ZSArIG1pbnV0ZU9mZnNldCAqIHNpZ25PZmZzZXQpICogNjAgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlY29uZFxuICAgICAgICAgICAgICAgICAgICAgICAgKSAqIDEwMDAgKyBtaWxsaXNlY29uZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0xvY2FsVGltZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHRvVVRDKHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoLTguNjRlMTUgPD0gcmVzdWx0ICYmIHJlc3VsdCA8PSA4LjY0ZTE1KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gTmFOO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gTmF0aXZlRGF0ZS5wYXJzZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGRlZmluZVByb3BlcnRpZXMoRGF0ZVNoaW0sIHsgcGFyc2U6IHBhcnNlU2hpbSB9KTtcblxuICAgICAgICAgICAgcmV0dXJuIERhdGVTaGltO1xuICAgICAgICB9KERhdGUpKTtcbiAgICAgICAgLyogZ2xvYmFsIERhdGU6IGZhbHNlICovXG4gICAgfVxuXG4gICAgLy8gRVM1IDE1LjkuNC40XG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuOS40LjRcbiAgICBpZiAoIURhdGUubm93KSB7XG4gICAgICAgIERhdGUubm93ID0gZnVuY3Rpb24gbm93KCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8vXG4gICAgLy8gTnVtYmVyXG4gICAgLy8gPT09PT09XG4gICAgLy9cblxuICAgIC8vIEVTNS4xIDE1LjcuNC41XG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuNy40LjVcbiAgICB2YXIgaGFzVG9GaXhlZEJ1Z3MgPSBOdW1iZXJQcm90b3R5cGUudG9GaXhlZCAmJiAoXG4gICAgICAoMC4wMDAwOCkudG9GaXhlZCgzKSAhPT0gJzAuMDAwJyB8fFxuICAgICAgKDAuOSkudG9GaXhlZCgwKSAhPT0gJzEnIHx8XG4gICAgICAoMS4yNTUpLnRvRml4ZWQoMikgIT09ICcxLjI1JyB8fFxuICAgICAgKDEwMDAwMDAwMDAwMDAwMDAxMjgpLnRvRml4ZWQoMCkgIT09ICcxMDAwMDAwMDAwMDAwMDAwMTI4J1xuICAgICk7XG5cbiAgICB2YXIgdG9GaXhlZEhlbHBlcnMgPSB7XG4gICAgICAgIGJhc2U6IDFlNyxcbiAgICAgICAgc2l6ZTogNixcbiAgICAgICAgZGF0YTogWzAsIDAsIDAsIDAsIDAsIDBdLFxuICAgICAgICBtdWx0aXBseTogZnVuY3Rpb24gbXVsdGlwbHkobiwgYykge1xuICAgICAgICAgICAgdmFyIGkgPSAtMTtcbiAgICAgICAgICAgIHZhciBjMiA9IGM7XG4gICAgICAgICAgICB3aGlsZSAoKytpIDwgdG9GaXhlZEhlbHBlcnMuc2l6ZSkge1xuICAgICAgICAgICAgICAgIGMyICs9IG4gKiB0b0ZpeGVkSGVscGVycy5kYXRhW2ldO1xuICAgICAgICAgICAgICAgIHRvRml4ZWRIZWxwZXJzLmRhdGFbaV0gPSBjMiAlIHRvRml4ZWRIZWxwZXJzLmJhc2U7XG4gICAgICAgICAgICAgICAgYzIgPSBNYXRoLmZsb29yKGMyIC8gdG9GaXhlZEhlbHBlcnMuYmFzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGRpdmlkZTogZnVuY3Rpb24gZGl2aWRlKG4pIHtcbiAgICAgICAgICAgIHZhciBpID0gdG9GaXhlZEhlbHBlcnMuc2l6ZTtcbiAgICAgICAgICAgIHZhciBjID0gMDtcbiAgICAgICAgICAgIHdoaWxlICgtLWkgPj0gMCkge1xuICAgICAgICAgICAgICAgIGMgKz0gdG9GaXhlZEhlbHBlcnMuZGF0YVtpXTtcbiAgICAgICAgICAgICAgICB0b0ZpeGVkSGVscGVycy5kYXRhW2ldID0gTWF0aC5mbG9vcihjIC8gbik7XG4gICAgICAgICAgICAgICAgYyA9IChjICUgbikgKiB0b0ZpeGVkSGVscGVycy5iYXNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBudW1Ub1N0cmluZzogZnVuY3Rpb24gbnVtVG9TdHJpbmcoKSB7XG4gICAgICAgICAgICB2YXIgaSA9IHRvRml4ZWRIZWxwZXJzLnNpemU7XG4gICAgICAgICAgICB2YXIgcyA9ICcnO1xuICAgICAgICAgICAgd2hpbGUgKC0taSA+PSAwKSB7XG4gICAgICAgICAgICAgICAgaWYgKHMgIT09ICcnIHx8IGkgPT09IDAgfHwgdG9GaXhlZEhlbHBlcnMuZGF0YVtpXSAhPT0gMCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgdCA9ICRTdHJpbmcodG9GaXhlZEhlbHBlcnMuZGF0YVtpXSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzID09PSAnJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcyA9IHQ7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzICs9IHN0clNsaWNlKCcwMDAwMDAwJywgMCwgNyAtIHQubGVuZ3RoKSArIHQ7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcztcbiAgICAgICAgfSxcbiAgICAgICAgcG93OiBmdW5jdGlvbiBwb3coeCwgbiwgYWNjKSB7XG4gICAgICAgICAgICByZXR1cm4gKG4gPT09IDAgPyBhY2MgOiAobiAlIDIgPT09IDEgPyBwb3coeCwgbiAtIDEsIGFjYyAqIHgpIDogcG93KHggKiB4LCBuIC8gMiwgYWNjKSkpO1xuICAgICAgICB9LFxuICAgICAgICBsb2c6IGZ1bmN0aW9uIGxvZyh4KSB7XG4gICAgICAgICAgICB2YXIgbiA9IDA7XG4gICAgICAgICAgICB2YXIgeDIgPSB4O1xuICAgICAgICAgICAgd2hpbGUgKHgyID49IDQwOTYpIHtcbiAgICAgICAgICAgICAgICBuICs9IDEyO1xuICAgICAgICAgICAgICAgIHgyIC89IDQwOTY7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB3aGlsZSAoeDIgPj0gMikge1xuICAgICAgICAgICAgICAgIG4gKz0gMTtcbiAgICAgICAgICAgICAgICB4MiAvPSAyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG47XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgdmFyIHRvRml4ZWRTaGltID0gZnVuY3Rpb24gdG9GaXhlZChmcmFjdGlvbkRpZ2l0cykge1xuICAgICAgICB2YXIgZiwgeCwgcywgbSwgZSwgeiwgaiwgaztcblxuICAgICAgICAvLyBUZXN0IGZvciBOYU4gYW5kIHJvdW5kIGZyYWN0aW9uRGlnaXRzIGRvd25cbiAgICAgICAgZiA9ICROdW1iZXIoZnJhY3Rpb25EaWdpdHMpO1xuICAgICAgICBmID0gaXNBY3R1YWxOYU4oZikgPyAwIDogTWF0aC5mbG9vcihmKTtcblxuICAgICAgICBpZiAoZiA8IDAgfHwgZiA+IDIwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignTnVtYmVyLnRvRml4ZWQgY2FsbGVkIHdpdGggaW52YWxpZCBudW1iZXIgb2YgZGVjaW1hbHMnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHggPSAkTnVtYmVyKHRoaXMpO1xuXG4gICAgICAgIGlmIChpc0FjdHVhbE5hTih4KSkge1xuICAgICAgICAgICAgcmV0dXJuICdOYU4nO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWYgaXQgaXMgdG9vIGJpZyBvciBzbWFsbCwgcmV0dXJuIHRoZSBzdHJpbmcgdmFsdWUgb2YgdGhlIG51bWJlclxuICAgICAgICBpZiAoeCA8PSAtMWUyMSB8fCB4ID49IDFlMjEpIHtcbiAgICAgICAgICAgIHJldHVybiAkU3RyaW5nKHgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcyA9ICcnO1xuXG4gICAgICAgIGlmICh4IDwgMCkge1xuICAgICAgICAgICAgcyA9ICctJztcbiAgICAgICAgICAgIHggPSAteDtcbiAgICAgICAgfVxuXG4gICAgICAgIG0gPSAnMCc7XG5cbiAgICAgICAgaWYgKHggPiAxZS0yMSkge1xuICAgICAgICAgICAgLy8gMWUtMjEgPCB4IDwgMWUyMVxuICAgICAgICAgICAgLy8gLTcwIDwgbG9nMih4KSA8IDcwXG4gICAgICAgICAgICBlID0gdG9GaXhlZEhlbHBlcnMubG9nKHggKiB0b0ZpeGVkSGVscGVycy5wb3coMiwgNjksIDEpKSAtIDY5O1xuICAgICAgICAgICAgeiA9IChlIDwgMCA/IHggKiB0b0ZpeGVkSGVscGVycy5wb3coMiwgLWUsIDEpIDogeCAvIHRvRml4ZWRIZWxwZXJzLnBvdygyLCBlLCAxKSk7XG4gICAgICAgICAgICB6ICo9IDB4MTAwMDAwMDAwMDAwMDA7IC8vIE1hdGgucG93KDIsIDUyKTtcbiAgICAgICAgICAgIGUgPSA1MiAtIGU7XG5cbiAgICAgICAgICAgIC8vIC0xOCA8IGUgPCAxMjJcbiAgICAgICAgICAgIC8vIHggPSB6IC8gMiBeIGVcbiAgICAgICAgICAgIGlmIChlID4gMCkge1xuICAgICAgICAgICAgICAgIHRvRml4ZWRIZWxwZXJzLm11bHRpcGx5KDAsIHopO1xuICAgICAgICAgICAgICAgIGogPSBmO1xuXG4gICAgICAgICAgICAgICAgd2hpbGUgKGogPj0gNykge1xuICAgICAgICAgICAgICAgICAgICB0b0ZpeGVkSGVscGVycy5tdWx0aXBseSgxZTcsIDApO1xuICAgICAgICAgICAgICAgICAgICBqIC09IDc7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdG9GaXhlZEhlbHBlcnMubXVsdGlwbHkodG9GaXhlZEhlbHBlcnMucG93KDEwLCBqLCAxKSwgMCk7XG4gICAgICAgICAgICAgICAgaiA9IGUgLSAxO1xuXG4gICAgICAgICAgICAgICAgd2hpbGUgKGogPj0gMjMpIHtcbiAgICAgICAgICAgICAgICAgICAgdG9GaXhlZEhlbHBlcnMuZGl2aWRlKDEgPDwgMjMpO1xuICAgICAgICAgICAgICAgICAgICBqIC09IDIzO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRvRml4ZWRIZWxwZXJzLmRpdmlkZSgxIDw8IGopO1xuICAgICAgICAgICAgICAgIHRvRml4ZWRIZWxwZXJzLm11bHRpcGx5KDEsIDEpO1xuICAgICAgICAgICAgICAgIHRvRml4ZWRIZWxwZXJzLmRpdmlkZSgyKTtcbiAgICAgICAgICAgICAgICBtID0gdG9GaXhlZEhlbHBlcnMubnVtVG9TdHJpbmcoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdG9GaXhlZEhlbHBlcnMubXVsdGlwbHkoMCwgeik7XG4gICAgICAgICAgICAgICAgdG9GaXhlZEhlbHBlcnMubXVsdGlwbHkoMSA8PCAoLWUpLCAwKTtcbiAgICAgICAgICAgICAgICBtID0gdG9GaXhlZEhlbHBlcnMubnVtVG9TdHJpbmcoKSArIHN0clNsaWNlKCcwLjAwMDAwMDAwMDAwMDAwMDAwMDAwJywgMiwgMiArIGYpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGYgPiAwKSB7XG4gICAgICAgICAgICBrID0gbS5sZW5ndGg7XG5cbiAgICAgICAgICAgIGlmIChrIDw9IGYpIHtcbiAgICAgICAgICAgICAgICBtID0gcyArIHN0clNsaWNlKCcwLjAwMDAwMDAwMDAwMDAwMDAwMDAnLCAwLCBmIC0gayArIDIpICsgbTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbSA9IHMgKyBzdHJTbGljZShtLCAwLCBrIC0gZikgKyAnLicgKyBzdHJTbGljZShtLCBrIC0gZik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBtID0gcyArIG07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbTtcbiAgICB9O1xuICAgIGRlZmluZVByb3BlcnRpZXMoTnVtYmVyUHJvdG90eXBlLCB7IHRvRml4ZWQ6IHRvRml4ZWRTaGltIH0sIGhhc1RvRml4ZWRCdWdzKTtcblxuICAgIHZhciBoYXNUb1ByZWNpc2lvblVuZGVmaW5lZEJ1ZyA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gMS4wLnRvUHJlY2lzaW9uKHVuZGVmaW5lZCkgPT09ICcxJztcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9KCkpO1xuICAgIHZhciBvcmlnaW5hbFRvUHJlY2lzaW9uID0gTnVtYmVyUHJvdG90eXBlLnRvUHJlY2lzaW9uO1xuICAgIGRlZmluZVByb3BlcnRpZXMoTnVtYmVyUHJvdG90eXBlLCB7XG4gICAgICAgIHRvUHJlY2lzaW9uOiBmdW5jdGlvbiB0b1ByZWNpc2lvbihwcmVjaXNpb24pIHtcbiAgICAgICAgICAgIHJldHVybiB0eXBlb2YgcHJlY2lzaW9uID09PSAndW5kZWZpbmVkJyA/IG9yaWdpbmFsVG9QcmVjaXNpb24uY2FsbCh0aGlzKSA6IG9yaWdpbmFsVG9QcmVjaXNpb24uY2FsbCh0aGlzLCBwcmVjaXNpb24pO1xuICAgICAgICB9XG4gICAgfSwgaGFzVG9QcmVjaXNpb25VbmRlZmluZWRCdWcpO1xuXG4gICAgLy9cbiAgICAvLyBTdHJpbmdcbiAgICAvLyA9PT09PT1cbiAgICAvL1xuXG4gICAgLy8gRVM1IDE1LjUuNC4xNFxuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjUuNC4xNFxuXG4gICAgLy8gW2J1Z2ZpeCwgSUUgbHQgOSwgZmlyZWZveCA0LCBLb25xdWVyb3IsIE9wZXJhLCBvYnNjdXJlIGJyb3dzZXJzXVxuICAgIC8vIE1hbnkgYnJvd3NlcnMgZG8gbm90IHNwbGl0IHByb3Blcmx5IHdpdGggcmVndWxhciBleHByZXNzaW9ucyBvciB0aGV5XG4gICAgLy8gZG8gbm90IHBlcmZvcm0gdGhlIHNwbGl0IGNvcnJlY3RseSB1bmRlciBvYnNjdXJlIGNvbmRpdGlvbnMuXG4gICAgLy8gU2VlIGh0dHA6Ly9ibG9nLnN0ZXZlbmxldml0aGFuLmNvbS9hcmNoaXZlcy9jcm9zcy1icm93c2VyLXNwbGl0XG4gICAgLy8gSSd2ZSB0ZXN0ZWQgaW4gbWFueSBicm93c2VycyBhbmQgdGhpcyBzZWVtcyB0byBjb3ZlciB0aGUgZGV2aWFudCBvbmVzOlxuICAgIC8vICAgICdhYicuc3BsaXQoLyg/OmFiKSovKSBzaG91bGQgYmUgW1wiXCIsIFwiXCJdLCBub3QgW1wiXCJdXG4gICAgLy8gICAgJy4nLnNwbGl0KC8oLj8pKC4/KS8pIHNob3VsZCBiZSBbXCJcIiwgXCIuXCIsIFwiXCIsIFwiXCJdLCBub3QgW1wiXCIsIFwiXCJdXG4gICAgLy8gICAgJ3Rlc3N0Jy5zcGxpdCgvKHMpKi8pIHNob3VsZCBiZSBbXCJ0XCIsIHVuZGVmaW5lZCwgXCJlXCIsIFwic1wiLCBcInRcIl0sIG5vdFxuICAgIC8vICAgICAgIFt1bmRlZmluZWQsIFwidFwiLCB1bmRlZmluZWQsIFwiZVwiLCAuLi5dXG4gICAgLy8gICAgJycuc3BsaXQoLy4/Lykgc2hvdWxkIGJlIFtdLCBub3QgW1wiXCJdXG4gICAgLy8gICAgJy4nLnNwbGl0KC8oKSgpLykgc2hvdWxkIGJlIFtcIi5cIl0sIG5vdCBbXCJcIiwgXCJcIiwgXCIuXCJdXG5cbiAgICBpZiAoXG4gICAgICAgICdhYicuc3BsaXQoLyg/OmFiKSovKS5sZW5ndGggIT09IDIgfHxcbiAgICAgICAgJy4nLnNwbGl0KC8oLj8pKC4/KS8pLmxlbmd0aCAhPT0gNCB8fFxuICAgICAgICAndGVzc3QnLnNwbGl0KC8ocykqLylbMV0gPT09ICd0JyB8fFxuICAgICAgICAndGVzdCcuc3BsaXQoLyg/OikvLCAtMSkubGVuZ3RoICE9PSA0IHx8XG4gICAgICAgICcnLnNwbGl0KC8uPy8pLmxlbmd0aCB8fFxuICAgICAgICAnLicuc3BsaXQoLygpKCkvKS5sZW5ndGggPiAxXG4gICAgKSB7XG4gICAgICAgIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgY29tcGxpYW50RXhlY05wY2cgPSB0eXBlb2YgKC8oKT8/LykuZXhlYygnJylbMV0gPT09ICd1bmRlZmluZWQnOyAvLyBOUENHOiBub25wYXJ0aWNpcGF0aW5nIGNhcHR1cmluZyBncm91cFxuICAgICAgICAgICAgdmFyIG1heFNhZmUzMkJpdEludCA9IE1hdGgucG93KDIsIDMyKSAtIDE7XG5cbiAgICAgICAgICAgIFN0cmluZ1Byb3RvdHlwZS5zcGxpdCA9IGZ1bmN0aW9uIChzZXBhcmF0b3IsIGxpbWl0KSB7XG4gICAgICAgICAgICAgICAgdmFyIHN0cmluZyA9IFN0cmluZyh0aGlzKTtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHNlcGFyYXRvciA9PT0gJ3VuZGVmaW5lZCcgJiYgbGltaXQgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIElmIGBzZXBhcmF0b3JgIGlzIG5vdCBhIHJlZ2V4LCB1c2UgbmF0aXZlIHNwbGl0XG4gICAgICAgICAgICAgICAgaWYgKCFpc1JlZ2V4KHNlcGFyYXRvcikpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN0clNwbGl0KHRoaXMsIHNlcGFyYXRvciwgbGltaXQpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHZhciBvdXRwdXQgPSBbXTtcbiAgICAgICAgICAgICAgICB2YXIgZmxhZ3MgPSAoc2VwYXJhdG9yLmlnbm9yZUNhc2UgPyAnaScgOiAnJykgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzZXBhcmF0b3IubXVsdGlsaW5lID8gJ20nIDogJycpICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc2VwYXJhdG9yLnVuaWNvZGUgPyAndScgOiAnJykgKyAvLyBpbiBFUzZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc2VwYXJhdG9yLnN0aWNreSA/ICd5JyA6ICcnKSwgLy8gRmlyZWZveCAzKyBhbmQgRVM2XG4gICAgICAgICAgICAgICAgICAgIGxhc3RMYXN0SW5kZXggPSAwLFxuICAgICAgICAgICAgICAgICAgICAvLyBNYWtlIGBnbG9iYWxgIGFuZCBhdm9pZCBgbGFzdEluZGV4YCBpc3N1ZXMgYnkgd29ya2luZyB3aXRoIGEgY29weVxuICAgICAgICAgICAgICAgICAgICBzZXBhcmF0b3IyLCBtYXRjaCwgbGFzdEluZGV4LCBsYXN0TGVuZ3RoO1xuICAgICAgICAgICAgICAgIHZhciBzZXBhcmF0b3JDb3B5ID0gbmV3IFJlZ0V4cChzZXBhcmF0b3Iuc291cmNlLCBmbGFncyArICdnJyk7XG4gICAgICAgICAgICAgICAgaWYgKCFjb21wbGlhbnRFeGVjTnBjZykge1xuICAgICAgICAgICAgICAgICAgICAvLyBEb2Vzbid0IG5lZWQgZmxhZ3MgZ3ksIGJ1dCB0aGV5IGRvbid0IGh1cnRcbiAgICAgICAgICAgICAgICAgICAgc2VwYXJhdG9yMiA9IG5ldyBSZWdFeHAoJ14nICsgc2VwYXJhdG9yQ29weS5zb3VyY2UgKyAnJCg/IVxcXFxzKScsIGZsYWdzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLyogVmFsdWVzIGZvciBgbGltaXRgLCBwZXIgdGhlIHNwZWM6XG4gICAgICAgICAgICAgICAgICogSWYgdW5kZWZpbmVkOiA0Mjk0OTY3Mjk1IC8vIG1heFNhZmUzMkJpdEludFxuICAgICAgICAgICAgICAgICAqIElmIDAsIEluZmluaXR5LCBvciBOYU46IDBcbiAgICAgICAgICAgICAgICAgKiBJZiBwb3NpdGl2ZSBudW1iZXI6IGxpbWl0ID0gTWF0aC5mbG9vcihsaW1pdCk7IGlmIChsaW1pdCA+IDQyOTQ5NjcyOTUpIGxpbWl0IC09IDQyOTQ5NjcyOTY7XG4gICAgICAgICAgICAgICAgICogSWYgbmVnYXRpdmUgbnVtYmVyOiA0Mjk0OTY3Mjk2IC0gTWF0aC5mbG9vcihNYXRoLmFicyhsaW1pdCkpXG4gICAgICAgICAgICAgICAgICogSWYgb3RoZXI6IFR5cGUtY29udmVydCwgdGhlbiB1c2UgdGhlIGFib3ZlIHJ1bGVzXG4gICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgdmFyIHNwbGl0TGltaXQgPSB0eXBlb2YgbGltaXQgPT09ICd1bmRlZmluZWQnID8gbWF4U2FmZTMyQml0SW50IDogRVMuVG9VaW50MzIobGltaXQpO1xuICAgICAgICAgICAgICAgIG1hdGNoID0gc2VwYXJhdG9yQ29weS5leGVjKHN0cmluZyk7XG4gICAgICAgICAgICAgICAgd2hpbGUgKG1hdGNoKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGBzZXBhcmF0b3JDb3B5Lmxhc3RJbmRleGAgaXMgbm90IHJlbGlhYmxlIGNyb3NzLWJyb3dzZXJcbiAgICAgICAgICAgICAgICAgICAgbGFzdEluZGV4ID0gbWF0Y2guaW5kZXggKyBtYXRjaFswXS5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgIGlmIChsYXN0SW5kZXggPiBsYXN0TGFzdEluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwdXNoQ2FsbChvdXRwdXQsIHN0clNsaWNlKHN0cmluZywgbGFzdExhc3RJbmRleCwgbWF0Y2guaW5kZXgpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZpeCBicm93c2VycyB3aG9zZSBgZXhlY2AgbWV0aG9kcyBkb24ndCBjb25zaXN0ZW50bHkgcmV0dXJuIGB1bmRlZmluZWRgIGZvclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gbm9ucGFydGljaXBhdGluZyBjYXB0dXJpbmcgZ3JvdXBzXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWNvbXBsaWFudEV4ZWNOcGNnICYmIG1hdGNoLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBlc2xpbnQtZGlzYWJsZSBuby1sb29wLWZ1bmMgKi9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaFswXS5yZXBsYWNlKHNlcGFyYXRvcjIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoIC0gMjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGFyZ3VtZW50c1tpXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaFtpXSA9IHZvaWQgMDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGVzbGludC1lbmFibGUgbm8tbG9vcC1mdW5jICovXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobWF0Y2gubGVuZ3RoID4gMSAmJiBtYXRjaC5pbmRleCA8IHN0cmluZy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJheV9wdXNoLmFwcGx5KG91dHB1dCwgYXJyYXlTbGljZShtYXRjaCwgMSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgbGFzdExlbmd0aCA9IG1hdGNoWzBdLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RMYXN0SW5kZXggPSBsYXN0SW5kZXg7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAob3V0cHV0Lmxlbmd0aCA+PSBzcGxpdExpbWl0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlcGFyYXRvckNvcHkubGFzdEluZGV4ID09PSBtYXRjaC5pbmRleCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2VwYXJhdG9yQ29weS5sYXN0SW5kZXgrKzsgLy8gQXZvaWQgYW4gaW5maW5pdGUgbG9vcFxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIG1hdGNoID0gc2VwYXJhdG9yQ29weS5leGVjKHN0cmluZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChsYXN0TGFzdEluZGV4ID09PSBzdHJpbmcubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChsYXN0TGVuZ3RoIHx8ICFzZXBhcmF0b3JDb3B5LnRlc3QoJycpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwdXNoQ2FsbChvdXRwdXQsICcnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHB1c2hDYWxsKG91dHB1dCwgc3RyU2xpY2Uoc3RyaW5nLCBsYXN0TGFzdEluZGV4KSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBvdXRwdXQubGVuZ3RoID4gc3BsaXRMaW1pdCA/IGFycmF5U2xpY2Uob3V0cHV0LCAwLCBzcGxpdExpbWl0KSA6IG91dHB1dDtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0oKSk7XG5cbiAgICAvLyBbYnVnZml4LCBjaHJvbWVdXG4gICAgLy8gSWYgc2VwYXJhdG9yIGlzIHVuZGVmaW5lZCwgdGhlbiB0aGUgcmVzdWx0IGFycmF5IGNvbnRhaW5zIGp1c3Qgb25lIFN0cmluZyxcbiAgICAvLyB3aGljaCBpcyB0aGUgdGhpcyB2YWx1ZSAoY29udmVydGVkIHRvIGEgU3RyaW5nKS4gSWYgbGltaXQgaXMgbm90IHVuZGVmaW5lZCxcbiAgICAvLyB0aGVuIHRoZSBvdXRwdXQgYXJyYXkgaXMgdHJ1bmNhdGVkIHNvIHRoYXQgaXQgY29udGFpbnMgbm8gbW9yZSB0aGFuIGxpbWl0XG4gICAgLy8gZWxlbWVudHMuXG4gICAgLy8gXCIwXCIuc3BsaXQodW5kZWZpbmVkLCAwKSAtPiBbXVxuICAgIH0gZWxzZSBpZiAoJzAnLnNwbGl0KHZvaWQgMCwgMCkubGVuZ3RoKSB7XG4gICAgICAgIFN0cmluZ1Byb3RvdHlwZS5zcGxpdCA9IGZ1bmN0aW9uIHNwbGl0KHNlcGFyYXRvciwgbGltaXQpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygc2VwYXJhdG9yID09PSAndW5kZWZpbmVkJyAmJiBsaW1pdCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzdHJTcGxpdCh0aGlzLCBzZXBhcmF0b3IsIGxpbWl0KTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICB2YXIgc3RyX3JlcGxhY2UgPSBTdHJpbmdQcm90b3R5cGUucmVwbGFjZTtcbiAgICB2YXIgcmVwbGFjZVJlcG9ydHNHcm91cHNDb3JyZWN0bHkgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZ3JvdXBzID0gW107XG4gICAgICAgICd4Jy5yZXBsYWNlKC94KC4pPy9nLCBmdW5jdGlvbiAobWF0Y2gsIGdyb3VwKSB7XG4gICAgICAgICAgICBwdXNoQ2FsbChncm91cHMsIGdyb3VwKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBncm91cHMubGVuZ3RoID09PSAxICYmIHR5cGVvZiBncm91cHNbMF0gPT09ICd1bmRlZmluZWQnO1xuICAgIH0oKSk7XG5cbiAgICBpZiAoIXJlcGxhY2VSZXBvcnRzR3JvdXBzQ29ycmVjdGx5KSB7XG4gICAgICAgIFN0cmluZ1Byb3RvdHlwZS5yZXBsYWNlID0gZnVuY3Rpb24gcmVwbGFjZShzZWFyY2hWYWx1ZSwgcmVwbGFjZVZhbHVlKSB7XG4gICAgICAgICAgICB2YXIgaXNGbiA9IGlzQ2FsbGFibGUocmVwbGFjZVZhbHVlKTtcbiAgICAgICAgICAgIHZhciBoYXNDYXB0dXJpbmdHcm91cHMgPSBpc1JlZ2V4KHNlYXJjaFZhbHVlKSAmJiAoL1xcKVsqP10vKS50ZXN0KHNlYXJjaFZhbHVlLnNvdXJjZSk7XG4gICAgICAgICAgICBpZiAoIWlzRm4gfHwgIWhhc0NhcHR1cmluZ0dyb3Vwcykge1xuICAgICAgICAgICAgICAgIHJldHVybiBzdHJfcmVwbGFjZS5jYWxsKHRoaXMsIHNlYXJjaFZhbHVlLCByZXBsYWNlVmFsdWUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YXIgd3JhcHBlZFJlcGxhY2VWYWx1ZSA9IGZ1bmN0aW9uIChtYXRjaCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgbGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9yaWdpbmFsTGFzdEluZGV4ID0gc2VhcmNoVmFsdWUubGFzdEluZGV4O1xuICAgICAgICAgICAgICAgICAgICBzZWFyY2hWYWx1ZS5sYXN0SW5kZXggPSAwO1xuICAgICAgICAgICAgICAgICAgICB2YXIgYXJncyA9IHNlYXJjaFZhbHVlLmV4ZWMobWF0Y2gpIHx8IFtdO1xuICAgICAgICAgICAgICAgICAgICBzZWFyY2hWYWx1ZS5sYXN0SW5kZXggPSBvcmlnaW5hbExhc3RJbmRleDtcbiAgICAgICAgICAgICAgICAgICAgcHVzaENhbGwoYXJncywgYXJndW1lbnRzW2xlbmd0aCAtIDJdLCBhcmd1bWVudHNbbGVuZ3RoIC0gMV0pO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVwbGFjZVZhbHVlLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgcmV0dXJuIHN0cl9yZXBsYWNlLmNhbGwodGhpcywgc2VhcmNoVmFsdWUsIHdyYXBwZWRSZXBsYWNlVmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8vIEVDTUEtMjYyLCAzcmQgQi4yLjNcbiAgICAvLyBOb3QgYW4gRUNNQVNjcmlwdCBzdGFuZGFyZCwgYWx0aG91Z2ggRUNNQVNjcmlwdCAzcmQgRWRpdGlvbiBoYXMgYVxuICAgIC8vIG5vbi1ub3JtYXRpdmUgc2VjdGlvbiBzdWdnZXN0aW5nIHVuaWZvcm0gc2VtYW50aWNzIGFuZCBpdCBzaG91bGQgYmVcbiAgICAvLyBub3JtYWxpemVkIGFjcm9zcyBhbGwgYnJvd3NlcnNcbiAgICAvLyBbYnVnZml4LCBJRSBsdCA5XSBJRSA8IDkgc3Vic3RyKCkgd2l0aCBuZWdhdGl2ZSB2YWx1ZSBub3Qgd29ya2luZyBpbiBJRVxuICAgIHZhciBzdHJpbmdfc3Vic3RyID0gU3RyaW5nUHJvdG90eXBlLnN1YnN0cjtcbiAgICB2YXIgaGFzTmVnYXRpdmVTdWJzdHJCdWcgPSAnJy5zdWJzdHIgJiYgJzBiJy5zdWJzdHIoLTEpICE9PSAnYic7XG4gICAgZGVmaW5lUHJvcGVydGllcyhTdHJpbmdQcm90b3R5cGUsIHtcbiAgICAgICAgc3Vic3RyOiBmdW5jdGlvbiBzdWJzdHIoc3RhcnQsIGxlbmd0aCkge1xuICAgICAgICAgICAgdmFyIG5vcm1hbGl6ZWRTdGFydCA9IHN0YXJ0O1xuICAgICAgICAgICAgaWYgKHN0YXJ0IDwgMCkge1xuICAgICAgICAgICAgICAgIG5vcm1hbGl6ZWRTdGFydCA9IG1heCh0aGlzLmxlbmd0aCArIHN0YXJ0LCAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzdHJpbmdfc3Vic3RyLmNhbGwodGhpcywgbm9ybWFsaXplZFN0YXJ0LCBsZW5ndGgpO1xuICAgICAgICB9XG4gICAgfSwgaGFzTmVnYXRpdmVTdWJzdHJCdWcpO1xuXG4gICAgLy8gRVM1IDE1LjUuNC4yMFxuICAgIC8vIHdoaXRlc3BhY2UgZnJvbTogaHR0cDovL2VzNS5naXRodWIuaW8vI3gxNS41LjQuMjBcbiAgICB2YXIgd3MgPSAnXFx4MDlcXHgwQVxceDBCXFx4MENcXHgwRFxceDIwXFx4QTBcXHUxNjgwXFx1MTgwRVxcdTIwMDBcXHUyMDAxXFx1MjAwMlxcdTIwMDMnICtcbiAgICAgICAgJ1xcdTIwMDRcXHUyMDA1XFx1MjAwNlxcdTIwMDdcXHUyMDA4XFx1MjAwOVxcdTIwMEFcXHUyMDJGXFx1MjA1RlxcdTMwMDBcXHUyMDI4JyArXG4gICAgICAgICdcXHUyMDI5XFx1RkVGRic7XG4gICAgdmFyIHplcm9XaWR0aCA9ICdcXHUyMDBiJztcbiAgICB2YXIgd3NSZWdleENoYXJzID0gJ1snICsgd3MgKyAnXSc7XG4gICAgdmFyIHRyaW1CZWdpblJlZ2V4cCA9IG5ldyBSZWdFeHAoJ14nICsgd3NSZWdleENoYXJzICsgd3NSZWdleENoYXJzICsgJyonKTtcbiAgICB2YXIgdHJpbUVuZFJlZ2V4cCA9IG5ldyBSZWdFeHAod3NSZWdleENoYXJzICsgd3NSZWdleENoYXJzICsgJyokJyk7XG4gICAgdmFyIGhhc1RyaW1XaGl0ZXNwYWNlQnVnID0gU3RyaW5nUHJvdG90eXBlLnRyaW0gJiYgKHdzLnRyaW0oKSB8fCAhemVyb1dpZHRoLnRyaW0oKSk7XG4gICAgZGVmaW5lUHJvcGVydGllcyhTdHJpbmdQcm90b3R5cGUsIHtcbiAgICAgICAgLy8gaHR0cDovL2Jsb2cuc3RldmVubGV2aXRoYW4uY29tL2FyY2hpdmVzL2Zhc3Rlci10cmltLWphdmFzY3JpcHRcbiAgICAgICAgLy8gaHR0cDovL3BlcmZlY3Rpb25raWxscy5jb20vd2hpdGVzcGFjZS1kZXZpYXRpb25zL1xuICAgICAgICB0cmltOiBmdW5jdGlvbiB0cmltKCkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB0aGlzID09PSAndW5kZWZpbmVkJyB8fCB0aGlzID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImNhbid0IGNvbnZlcnQgXCIgKyB0aGlzICsgJyB0byBvYmplY3QnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAkU3RyaW5nKHRoaXMpLnJlcGxhY2UodHJpbUJlZ2luUmVnZXhwLCAnJykucmVwbGFjZSh0cmltRW5kUmVnZXhwLCAnJyk7XG4gICAgICAgIH1cbiAgICB9LCBoYXNUcmltV2hpdGVzcGFjZUJ1Zyk7XG4gICAgdmFyIHRyaW0gPSBjYWxsLmJpbmQoU3RyaW5nLnByb3RvdHlwZS50cmltKTtcblxuICAgIHZhciBoYXNMYXN0SW5kZXhCdWcgPSBTdHJpbmdQcm90b3R5cGUubGFzdEluZGV4T2YgJiYgJ2FiY+OBguOBhCcubGFzdEluZGV4T2YoJ+OBguOBhCcsIDIpICE9PSAtMTtcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKFN0cmluZ1Byb3RvdHlwZSwge1xuICAgICAgICBsYXN0SW5kZXhPZjogZnVuY3Rpb24gbGFzdEluZGV4T2Yoc2VhcmNoU3RyaW5nKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHRoaXMgPT09ICd1bmRlZmluZWQnIHx8IHRoaXMgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiY2FuJ3QgY29udmVydCBcIiArIHRoaXMgKyAnIHRvIG9iamVjdCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIFMgPSAkU3RyaW5nKHRoaXMpO1xuICAgICAgICAgICAgdmFyIHNlYXJjaFN0ciA9ICRTdHJpbmcoc2VhcmNoU3RyaW5nKTtcbiAgICAgICAgICAgIHZhciBudW1Qb3MgPSBhcmd1bWVudHMubGVuZ3RoID4gMSA/ICROdW1iZXIoYXJndW1lbnRzWzFdKSA6IE5hTjtcbiAgICAgICAgICAgIHZhciBwb3MgPSBpc0FjdHVhbE5hTihudW1Qb3MpID8gSW5maW5pdHkgOiBFUy5Ub0ludGVnZXIobnVtUG9zKTtcbiAgICAgICAgICAgIHZhciBzdGFydCA9IG1pbihtYXgocG9zLCAwKSwgUy5sZW5ndGgpO1xuICAgICAgICAgICAgdmFyIHNlYXJjaExlbiA9IHNlYXJjaFN0ci5sZW5ndGg7XG4gICAgICAgICAgICB2YXIgayA9IHN0YXJ0ICsgc2VhcmNoTGVuO1xuICAgICAgICAgICAgd2hpbGUgKGsgPiAwKSB7XG4gICAgICAgICAgICAgICAgayA9IG1heCgwLCBrIC0gc2VhcmNoTGVuKTtcbiAgICAgICAgICAgICAgICB2YXIgaW5kZXggPSBzdHJJbmRleE9mKHN0clNsaWNlKFMsIGssIHN0YXJ0ICsgc2VhcmNoTGVuKSwgc2VhcmNoU3RyKTtcbiAgICAgICAgICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBrICsgaW5kZXg7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICB9XG4gICAgfSwgaGFzTGFzdEluZGV4QnVnKTtcblxuICAgIHZhciBvcmlnaW5hbExhc3RJbmRleE9mID0gU3RyaW5nUHJvdG90eXBlLmxhc3RJbmRleE9mO1xuICAgIGRlZmluZVByb3BlcnRpZXMoU3RyaW5nUHJvdG90eXBlLCB7XG4gICAgICAgIGxhc3RJbmRleE9mOiBmdW5jdGlvbiBsYXN0SW5kZXhPZihzZWFyY2hTdHJpbmcpIHtcbiAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbExhc3RJbmRleE9mLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICB9LCBTdHJpbmdQcm90b3R5cGUubGFzdEluZGV4T2YubGVuZ3RoICE9PSAxKTtcblxuICAgIC8vIEVTLTUgMTUuMS4yLjJcbiAgICAvKiBlc2xpbnQtZGlzYWJsZSByYWRpeCAqL1xuICAgIGlmIChwYXJzZUludCh3cyArICcwOCcpICE9PSA4IHx8IHBhcnNlSW50KHdzICsgJzB4MTYnKSAhPT0gMjIpIHtcbiAgICAvKiBlc2xpbnQtZW5hYmxlIHJhZGl4ICovXG4gICAgICAgIC8qIGdsb2JhbCBwYXJzZUludDogdHJ1ZSAqL1xuICAgICAgICBwYXJzZUludCA9IChmdW5jdGlvbiAob3JpZ1BhcnNlSW50KSB7XG4gICAgICAgICAgICB2YXIgaGV4UmVnZXggPSAvXltcXC0rXT8wW3hYXS87XG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gcGFyc2VJbnQoc3RyLCByYWRpeCkge1xuICAgICAgICAgICAgICAgIHZhciBzdHJpbmcgPSB0cmltKFN0cmluZyhzdHIpKTtcbiAgICAgICAgICAgICAgICB2YXIgZGVmYXVsdGVkUmFkaXggPSAkTnVtYmVyKHJhZGl4KSB8fCAoaGV4UmVnZXgudGVzdChzdHJpbmcpID8gMTYgOiAxMCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9yaWdQYXJzZUludChzdHJpbmcsIGRlZmF1bHRlZFJhZGl4KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0ocGFyc2VJbnQpKTtcbiAgICB9XG5cbiAgICAvLyBodHRwczovL2VzNS5naXRodWIuaW8vI3gxNS4xLjIuM1xuICAgIGlmICgxIC8gcGFyc2VGbG9hdCgnLTAnKSAhPT0gLUluZmluaXR5KSB7XG4gICAgICAgIC8qIGdsb2JhbCBwYXJzZUZsb2F0OiB0cnVlICovXG4gICAgICAgIHBhcnNlRmxvYXQgPSAoZnVuY3Rpb24gKG9yaWdQYXJzZUZsb2F0KSB7XG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gcGFyc2VGbG9hdChzdHJpbmcpIHtcbiAgICAgICAgICAgICAgICB2YXIgaW5wdXRTdHJpbmcgPSB0cmltKFN0cmluZyhzdHJpbmcpKTtcbiAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gb3JpZ1BhcnNlRmxvYXQoaW5wdXRTdHJpbmcpO1xuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgPT09IDAgJiYgc3RyU2xpY2UoaW5wdXRTdHJpbmcsIDAsIDEpID09PSAnLScgPyAtMCA6IHJlc3VsdDtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0ocGFyc2VGbG9hdCkpO1xuICAgIH1cblxuICAgIGlmIChTdHJpbmcobmV3IFJhbmdlRXJyb3IoJ3Rlc3QnKSkgIT09ICdSYW5nZUVycm9yOiB0ZXN0Jykge1xuICAgICAgICB2YXIgZXJyb3JUb1N0cmluZ1NoaW0gPSBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdGhpcyA9PT0gJ3VuZGVmaW5lZCcgfHwgdGhpcyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJjYW4ndCBjb252ZXJ0IFwiICsgdGhpcyArICcgdG8gb2JqZWN0Jyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgbmFtZSA9IHRoaXMubmFtZTtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgbmFtZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICBuYW1lID0gJ0Vycm9yJztcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIG5hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgbmFtZSA9ICRTdHJpbmcobmFtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgbXNnID0gdGhpcy5tZXNzYWdlO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBtc2cgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgbXNnID0gJyc7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBtc2cgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgbXNnID0gJFN0cmluZyhtc2cpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFuYW1lKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1zZztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghbXNnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5hbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbmFtZSArICc6ICcgKyBtc2c7XG4gICAgICAgIH07XG4gICAgICAgIC8vIGNhbid0IHVzZSBkZWZpbmVQcm9wZXJ0aWVzIGhlcmUgYmVjYXVzZSBvZiB0b1N0cmluZyBlbnVtZXJhdGlvbiBpc3N1ZSBpbiBJRSA8PSA4XG4gICAgICAgIEVycm9yLnByb3RvdHlwZS50b1N0cmluZyA9IGVycm9yVG9TdHJpbmdTaGltO1xuICAgIH1cblxuICAgIGlmIChzdXBwb3J0c0Rlc2NyaXB0b3JzKSB7XG4gICAgICAgIHZhciBlbnN1cmVOb25FbnVtZXJhYmxlID0gZnVuY3Rpb24gKG9iaiwgcHJvcCkge1xuICAgICAgICAgICAgaWYgKGlzRW51bShvYmosIHByb3ApKSB7XG4gICAgICAgICAgICAgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwgcHJvcCk7XG4gICAgICAgICAgICAgICAgaWYgKGRlc2MuY29uZmlndXJhYmxlKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlc2MuZW51bWVyYWJsZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqLCBwcm9wLCBkZXNjKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGVuc3VyZU5vbkVudW1lcmFibGUoRXJyb3IucHJvdG90eXBlLCAnbWVzc2FnZScpO1xuICAgICAgICBpZiAoRXJyb3IucHJvdG90eXBlLm1lc3NhZ2UgIT09ICcnKSB7XG4gICAgICAgICAgICBFcnJvci5wcm90b3R5cGUubWVzc2FnZSA9ICcnO1xuICAgICAgICB9XG4gICAgICAgIGVuc3VyZU5vbkVudW1lcmFibGUoRXJyb3IucHJvdG90eXBlLCAnbmFtZScpO1xuICAgIH1cblxuICAgIGlmIChTdHJpbmcoL2EvbWlnKSAhPT0gJy9hL2dpbScpIHtcbiAgICAgICAgdmFyIHJlZ2V4VG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgICAgICAgICAgIHZhciBzdHIgPSAnLycgKyB0aGlzLnNvdXJjZSArICcvJztcbiAgICAgICAgICAgIGlmICh0aGlzLmdsb2JhbCkge1xuICAgICAgICAgICAgICAgIHN0ciArPSAnZyc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5pZ25vcmVDYXNlKSB7XG4gICAgICAgICAgICAgICAgc3RyICs9ICdpJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLm11bHRpbGluZSkge1xuICAgICAgICAgICAgICAgIHN0ciArPSAnbSc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gc3RyO1xuICAgICAgICB9O1xuICAgICAgICAvLyBjYW4ndCB1c2UgZGVmaW5lUHJvcGVydGllcyBoZXJlIGJlY2F1c2Ugb2YgdG9TdHJpbmcgZW51bWVyYXRpb24gaXNzdWUgaW4gSUUgPD0gOFxuICAgICAgICBSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nID0gcmVnZXhUb1N0cmluZztcbiAgICB9XG59KSk7XG4iLCIndXNlIHN0cmljdCc7XG4vKmpzbGludCBlcWVxOiB0cnVlKi9cblxuSGFuZGxlYmFycy5yZWdpc3RlckhlbHBlcignc2FuaXRpemUnLCBmdW5jdGlvbiAodGV4dCkge1xuICAgIHZhciByZXN1bHQ7XG5cbiAgICBpZiAodGV4dCA9PT0gdW5kZWZpbmVkKSB7IHJldHVybiAnJzsgfVxuXG4gICAgcmVzdWx0ID0gc2FuaXRpemVIdG1sKHRleHQsIHtcbiAgICAgICAgYWxsb3dlZFRhZ3M6IFsgJ2RpdicsICdzcGFuJywgJ2InLCAnaScsICdlbScsICdzdHJvbmcnLCAnYScsICdicicsICd0YWJsZScsICd0Ym9keScsICd0cicsICd0aCcsICd0ZCcgXSxcbiAgICAgICAgYWxsb3dlZEF0dHJpYnV0ZXM6IHtcbiAgICAgICAgICAgICdkaXYnOiBbICdjbGFzcycgXSxcbiAgICAgICAgICAgICdzcGFuJzogWyAnY2xhc3MnIF0sXG4gICAgICAgICAgICAndGFibGUnOiBbICdjbGFzcycgXSxcbiAgICAgICAgICAgICd0ZCc6IFsgJ2NsYXNzJyBdLFxuICAgICAgICAgICAgJ3RoJzogWyAnY29sc3BhbicgXSxcbiAgICAgICAgICAgICdhJzogWyAnaHJlZicgXVxuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gbmV3IEhhbmRsZWJhcnMuU2FmZVN0cmluZyhyZXN1bHQpO1xufSk7XG5cbkhhbmRsZWJhcnMucmVnaXN0ZXJIZWxwZXIoJ3JlbmRlclRleHRQYXJhbScsIGZ1bmN0aW9uKHBhcmFtKSB7XG4gICAgdmFyIHJlc3VsdCwgdHlwZSA9ICd0ZXh0JywgaWRBdHQgPSAnJztcbiAgICB2YXIgcGFyYW1UeXBlID0gcGFyYW0udHlwZSB8fCBwYXJhbS5zY2hlbWEgJiYgcGFyYW0uc2NoZW1hLnR5cGUgfHwgJyc7XG4gICAgdmFyIGlzQXJyYXkgPSBwYXJhbVR5cGUudG9Mb3dlckNhc2UoKSA9PT0gJ2FycmF5JyB8fCBwYXJhbS5hbGxvd011bHRpcGxlO1xuICAgIHZhciBkZWZhdWx0VmFsdWUgPSBpc0FycmF5ICYmIEFycmF5LmlzQXJyYXkocGFyYW0uZGVmYXVsdCkgPyBwYXJhbS5kZWZhdWx0LmpvaW4oJ1xcbicpIDogcGFyYW0uZGVmYXVsdDtcbiAgICB2YXIgbmFtZSA9IEhhbmRsZWJhcnMuVXRpbHMuZXNjYXBlRXhwcmVzc2lvbihwYXJhbS5uYW1lKTtcbiAgICB2YXIgdmFsdWVJZCA9IEhhbmRsZWJhcnMuVXRpbHMuZXNjYXBlRXhwcmVzc2lvbihwYXJhbS52YWx1ZUlkKTtcbiAgICBwYXJhbVR5cGUgPSBIYW5kbGViYXJzLlV0aWxzLmVzY2FwZUV4cHJlc3Npb24ocGFyYW1UeXBlKTtcblxuICAgIHZhciBkYXRhVmVuZG9yRXh0ZW5zaW9ucyA9IE9iamVjdC5rZXlzKHBhcmFtKS5maWx0ZXIoZnVuY3Rpb24ocHJvcGVydHkpIHtcbiAgICAgICAgLy8gZmlsdGVyIFgtZGF0YS0gcHJvcGVydGllc1xuICAgICAgICByZXR1cm4gcHJvcGVydHkubWF0Y2goL15YLWRhdGEtL2kpICE9PSBudWxsO1xuICAgIH0pLnJlZHVjZShmdW5jdGlvbihyZXN1bHQsIHByb3BlcnR5KSB7XG4gICAgICAgIC8vIHJlbW92ZSBYLSBmcm9tIHByb3BlcnR5IG5hbWUsIHNvIGl0IHJlc3VsdHMgaW4gaHRtbCBhdHRyaWJ1dGVzIGxpa2UgZGF0YS1mb289J2JhcidcbiAgICAgICAgcmV0dXJuIHJlc3VsdCArPSAnICcgKyBwcm9wZXJ0eS5zdWJzdHJpbmcoMiwgcHJvcGVydHkubGVuZ3RoKSArICc9XFwnJyArIHBhcmFtW3Byb3BlcnR5XSArICdcXCcnO1xuICAgIH0sICcnKTtcblxuICAgIGlmKHBhcmFtLmZvcm1hdCAmJiBwYXJhbS5mb3JtYXQgPT09ICdwYXNzd29yZCcpIHtcbiAgICAgICAgdHlwZSA9ICdwYXNzd29yZCc7XG4gICAgfVxuXG4gICAgaWYodmFsdWVJZCkge1xuICAgICAgICBpZEF0dCA9ICcgaWQ9XFwnJyArIHZhbHVlSWQgKyAnXFwnJztcbiAgICB9XG5cbiAgICBpZiAoZGVmYXVsdFZhbHVlKSB7XG4gICAgICBkZWZhdWx0VmFsdWUgPSBzYW5pdGl6ZUh0bWwoZGVmYXVsdFZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGVmYXVsdFZhbHVlID0gJyc7XG4gICAgfVxuXG4gICAgaWYoaXNBcnJheSkge1xuICAgICAgICByZXN1bHQgPSAnPHRleHRhcmVhIGNsYXNzPVxcJ2JvZHktdGV4dGFyZWEnICsgKHBhcmFtLnJlcXVpcmVkID8gJyByZXF1aXJlZCcgOiAnJykgKyAnXFwnIG5hbWU9XFwnJyArIG5hbWUgKyAnXFwnJyArIGlkQXR0ICsgZGF0YVZlbmRvckV4dGVuc2lvbnM7XG4gICAgICAgIHJlc3VsdCArPSAnIHBsYWNlaG9sZGVyPVxcJ1Byb3ZpZGUgbXVsdGlwbGUgdmFsdWVzIGluIG5ldyBsaW5lcycgKyAocGFyYW0ucmVxdWlyZWQgPyAnIChhdCBsZWFzdCBvbmUgcmVxdWlyZWQpLicgOiAnLicpICsgJ1xcJz4nO1xuICAgICAgICByZXN1bHQgKz0gZGVmYXVsdFZhbHVlICsgJzwvdGV4dGFyZWE+JztcbiAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgcGFyYW1ldGVyQ2xhc3MgPSAncGFyYW1ldGVyJztcbiAgICAgICAgaWYocGFyYW0ucmVxdWlyZWQpIHtcbiAgICAgICAgICBwYXJhbWV0ZXJDbGFzcyArPSAnIHJlcXVpcmVkJztcbiAgICAgICAgfVxuICAgICAgICByZXN1bHQgPSAnPGlucHV0IGNsYXNzPVxcJycgKyBwYXJhbWV0ZXJDbGFzcyArICdcXCcgbWlubGVuZ3RoPVxcJycgKyAocGFyYW0ucmVxdWlyZWQgPyAxIDogMCkgKyAnXFwnJztcbiAgICAgICAgcmVzdWx0ICs9ICcgbmFtZT1cXCcnICsgbmFtZSArJ1xcJyBwbGFjZWhvbGRlcj1cXCcnICsgKHBhcmFtLnJlcXVpcmVkID8gJyhyZXF1aXJlZCknIDogJycpICsgJ1xcJycgKyBpZEF0dCArIGRhdGFWZW5kb3JFeHRlbnNpb25zO1xuICAgICAgICByZXN1bHQgKz0gJyB0eXBlPVxcJycgKyB0eXBlICsgJ1xcJyB2YWx1ZT1cXCcnICsgZGVmYXVsdFZhbHVlICsgJ1xcJy8+JztcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBIYW5kbGViYXJzLlNhZmVTdHJpbmcocmVzdWx0KTtcbn0pO1xuXG5IYW5kbGViYXJzLnJlZ2lzdGVySGVscGVyKCdpZkNvbmQnLCBmdW5jdGlvbiAodjEsIG9wZXJhdG9yLCB2Miwgb3B0aW9ucykge1xuXG4gICAgc3dpdGNoIChvcGVyYXRvcikge1xuICAgICAgICBjYXNlICc9PSc6XG4gICAgICAgICAgICByZXR1cm4gKHYxID09IHYyKSA/IG9wdGlvbnMuZm4odGhpcykgOiBvcHRpb25zLmludmVyc2UodGhpcyk7XG4gICAgICAgIGNhc2UgJz09PSc6XG4gICAgICAgICAgICByZXR1cm4gKHYxID09PSB2MikgPyBvcHRpb25zLmZuKHRoaXMpIDogb3B0aW9ucy5pbnZlcnNlKHRoaXMpO1xuICAgICAgICBjYXNlICc8JzpcbiAgICAgICAgICAgIHJldHVybiAodjEgPCB2MikgPyBvcHRpb25zLmZuKHRoaXMpIDogb3B0aW9ucy5pbnZlcnNlKHRoaXMpO1xuICAgICAgICBjYXNlICc8PSc6XG4gICAgICAgICAgICByZXR1cm4gKHYxIDw9IHYyKSA/IG9wdGlvbnMuZm4odGhpcykgOiBvcHRpb25zLmludmVyc2UodGhpcyk7XG4gICAgICAgIGNhc2UgJz4nOlxuICAgICAgICAgICAgcmV0dXJuICh2MSA+IHYyKSA/IG9wdGlvbnMuZm4odGhpcykgOiBvcHRpb25zLmludmVyc2UodGhpcyk7XG4gICAgICAgIGNhc2UgJz49JzpcbiAgICAgICAgICAgIHJldHVybiAodjEgPj0gdjIpID8gb3B0aW9ucy5mbih0aGlzKSA6IG9wdGlvbnMuaW52ZXJzZSh0aGlzKTtcbiAgICAgICAgY2FzZSAnJiYnOlxuICAgICAgICAgICAgcmV0dXJuICh2MSAmJiB2MikgPyBvcHRpb25zLmZuKHRoaXMpIDogb3B0aW9ucy5pbnZlcnNlKHRoaXMpO1xuICAgICAgICBjYXNlICd8fCc6XG4gICAgICAgICAgICByZXR1cm4gKHYxIHx8IHYyKSA/IG9wdGlvbnMuZm4odGhpcykgOiBvcHRpb25zLmludmVyc2UodGhpcyk7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gb3B0aW9ucy5pbnZlcnNlKHRoaXMpO1xuICAgIH1cbn0pO1xuXG5IYW5kbGViYXJzLnJlZ2lzdGVySGVscGVyKCdlc2NhcGUnLCBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICB2YXIgdGV4dCA9IEhhbmRsZWJhcnMuVXRpbHMuZXNjYXBlRXhwcmVzc2lvbih2YWx1ZSk7XG5cbiAgICByZXR1cm4gbmV3IEhhbmRsZWJhcnMuU2FmZVN0cmluZyh0ZXh0KTtcbn0pO1xuIiwiKGZ1bmN0aW9uKGYpe2lmKHR5cGVvZiBleHBvcnRzPT09XCJvYmplY3RcIiYmdHlwZW9mIG1vZHVsZSE9PVwidW5kZWZpbmVkXCIpe21vZHVsZS5leHBvcnRzPWYoKX1lbHNlIGlmKHR5cGVvZiBkZWZpbmU9PT1cImZ1bmN0aW9uXCImJmRlZmluZS5hbWQpe2RlZmluZShbXSxmKX1lbHNle3ZhciBnO2lmKHR5cGVvZiB3aW5kb3chPT1cInVuZGVmaW5lZFwiKXtnPXdpbmRvd31lbHNlIGlmKHR5cGVvZiBnbG9iYWwhPT1cInVuZGVmaW5lZFwiKXtnPWdsb2JhbH1lbHNlIGlmKHR5cGVvZiBzZWxmIT09XCJ1bmRlZmluZWRcIil7Zz1zZWxmfWVsc2V7Zz10aGlzfWcuc2FuaXRpemVIdG1sPWYoKX19KShmdW5jdGlvbigpe3ZhciBkZWZpbmUsbW9kdWxlLGV4cG9ydHM7cmV0dXJuIGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSh7MTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIGh0bWxwYXJzZXI9cmVxdWlyZShcImh0bWxwYXJzZXIyXCIpO3ZhciBleHRlbmQ9cmVxdWlyZShcInh0ZW5kXCIpO3ZhciBxdW90ZVJlZ2V4cD1yZXF1aXJlKFwicmVnZXhwLXF1b3RlXCIpO2Z1bmN0aW9uIGVhY2gob2JqLGNiKXtpZihvYmopT2JqZWN0LmtleXMob2JqKS5mb3JFYWNoKGZ1bmN0aW9uKGtleSl7Y2Iob2JqW2tleV0sa2V5KX0pfWZ1bmN0aW9uIGhhcyhvYmosa2V5KXtyZXR1cm57fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaixrZXkpfW1vZHVsZS5leHBvcnRzPXNhbml0aXplSHRtbDtmdW5jdGlvbiBzYW5pdGl6ZUh0bWwoaHRtbCxvcHRpb25zLF9yZWN1cnNpbmcpe3ZhciByZXN1bHQ9XCJcIjtmdW5jdGlvbiBGcmFtZSh0YWcsYXR0cmlicyl7dmFyIHRoYXQ9dGhpczt0aGlzLnRhZz10YWc7dGhpcy5hdHRyaWJzPWF0dHJpYnN8fHt9O3RoaXMudGFnUG9zaXRpb249cmVzdWx0Lmxlbmd0aDt0aGlzLnRleHQ9XCJcIjt0aGlzLnVwZGF0ZVBhcmVudE5vZGVUZXh0PWZ1bmN0aW9uKCl7aWYoc3RhY2subGVuZ3RoKXt2YXIgcGFyZW50RnJhbWU9c3RhY2tbc3RhY2subGVuZ3RoLTFdO3BhcmVudEZyYW1lLnRleHQrPXRoYXQudGV4dH19fWlmKCFvcHRpb25zKXtvcHRpb25zPXNhbml0aXplSHRtbC5kZWZhdWx0cztvcHRpb25zLnBhcnNlcj1odG1sUGFyc2VyRGVmYXVsdHN9ZWxzZXtvcHRpb25zPWV4dGVuZChzYW5pdGl6ZUh0bWwuZGVmYXVsdHMsb3B0aW9ucyk7aWYob3B0aW9ucy5wYXJzZXIpe29wdGlvbnMucGFyc2VyPWV4dGVuZChodG1sUGFyc2VyRGVmYXVsdHMsb3B0aW9ucy5wYXJzZXIpfWVsc2V7b3B0aW9ucy5wYXJzZXI9aHRtbFBhcnNlckRlZmF1bHRzfX12YXIgbm9uVGV4dFRhZ3NBcnJheT1vcHRpb25zLm5vblRleHRUYWdzfHxbXCJzY3JpcHRcIixcInN0eWxlXCIsXCJ0ZXh0YXJlYVwiXTt2YXIgYWxsb3dlZEF0dHJpYnV0ZXNNYXA7dmFyIGFsbG93ZWRBdHRyaWJ1dGVzR2xvYk1hcDtpZihvcHRpb25zLmFsbG93ZWRBdHRyaWJ1dGVzKXthbGxvd2VkQXR0cmlidXRlc01hcD17fTthbGxvd2VkQXR0cmlidXRlc0dsb2JNYXA9e307ZWFjaChvcHRpb25zLmFsbG93ZWRBdHRyaWJ1dGVzLGZ1bmN0aW9uKGF0dHJpYnV0ZXMsdGFnKXthbGxvd2VkQXR0cmlidXRlc01hcFt0YWddPVtdO3ZhciBnbG9iUmVnZXg9W107YXR0cmlidXRlcy5mb3JFYWNoKGZ1bmN0aW9uKG5hbWUpe2lmKG5hbWUuaW5kZXhPZihcIipcIik+PTApe2dsb2JSZWdleC5wdXNoKHF1b3RlUmVnZXhwKG5hbWUpLnJlcGxhY2UoL1xcXFxcXCovZyxcIi4qXCIpKX1lbHNle2FsbG93ZWRBdHRyaWJ1dGVzTWFwW3RhZ10ucHVzaChuYW1lKX19KTthbGxvd2VkQXR0cmlidXRlc0dsb2JNYXBbdGFnXT1uZXcgUmVnRXhwKFwiXihcIitnbG9iUmVnZXguam9pbihcInxcIikrXCIpJFwiKX0pfXZhciBhbGxvd2VkQ2xhc3Nlc01hcD17fTtlYWNoKG9wdGlvbnMuYWxsb3dlZENsYXNzZXMsZnVuY3Rpb24oY2xhc3Nlcyx0YWcpe2lmKGFsbG93ZWRBdHRyaWJ1dGVzTWFwKXtpZighaGFzKGFsbG93ZWRBdHRyaWJ1dGVzTWFwLHRhZykpe2FsbG93ZWRBdHRyaWJ1dGVzTWFwW3RhZ109W119YWxsb3dlZEF0dHJpYnV0ZXNNYXBbdGFnXS5wdXNoKFwiY2xhc3NcIil9YWxsb3dlZENsYXNzZXNNYXBbdGFnXT1jbGFzc2VzfSk7dmFyIHRyYW5zZm9ybVRhZ3NNYXA9e307dmFyIHRyYW5zZm9ybVRhZ3NBbGw7ZWFjaChvcHRpb25zLnRyYW5zZm9ybVRhZ3MsZnVuY3Rpb24odHJhbnNmb3JtLHRhZyl7dmFyIHRyYW5zRnVuO2lmKHR5cGVvZiB0cmFuc2Zvcm09PT1cImZ1bmN0aW9uXCIpe3RyYW5zRnVuPXRyYW5zZm9ybX1lbHNlIGlmKHR5cGVvZiB0cmFuc2Zvcm09PT1cInN0cmluZ1wiKXt0cmFuc0Z1bj1zYW5pdGl6ZUh0bWwuc2ltcGxlVHJhbnNmb3JtKHRyYW5zZm9ybSl9aWYodGFnPT09XCIqXCIpe3RyYW5zZm9ybVRhZ3NBbGw9dHJhbnNGdW59ZWxzZXt0cmFuc2Zvcm1UYWdzTWFwW3RhZ109dHJhbnNGdW59fSk7dmFyIGRlcHRoPTA7dmFyIHN0YWNrPVtdO3ZhciBza2lwTWFwPXt9O3ZhciB0cmFuc2Zvcm1NYXA9e307dmFyIHNraXBUZXh0PWZhbHNlO3ZhciBza2lwVGV4dERlcHRoPTA7dmFyIHBhcnNlcj1uZXcgaHRtbHBhcnNlci5QYXJzZXIoe29ub3BlbnRhZzpmdW5jdGlvbihuYW1lLGF0dHJpYnMpe2lmKHNraXBUZXh0KXtza2lwVGV4dERlcHRoKys7cmV0dXJufXZhciBmcmFtZT1uZXcgRnJhbWUobmFtZSxhdHRyaWJzKTtzdGFjay5wdXNoKGZyYW1lKTt2YXIgc2tpcD1mYWxzZTt2YXIgaGFzVGV4dD1mcmFtZS50ZXh0P3RydWU6ZmFsc2U7dmFyIHRyYW5zZm9ybWVkVGFnO2lmKGhhcyh0cmFuc2Zvcm1UYWdzTWFwLG5hbWUpKXt0cmFuc2Zvcm1lZFRhZz10cmFuc2Zvcm1UYWdzTWFwW25hbWVdKG5hbWUsYXR0cmlicyk7ZnJhbWUuYXR0cmlicz1hdHRyaWJzPXRyYW5zZm9ybWVkVGFnLmF0dHJpYnM7aWYodHJhbnNmb3JtZWRUYWcudGV4dCE9PXVuZGVmaW5lZCl7ZnJhbWUuaW5uZXJUZXh0PXRyYW5zZm9ybWVkVGFnLnRleHR9aWYobmFtZSE9PXRyYW5zZm9ybWVkVGFnLnRhZ05hbWUpe2ZyYW1lLm5hbWU9bmFtZT10cmFuc2Zvcm1lZFRhZy50YWdOYW1lO3RyYW5zZm9ybU1hcFtkZXB0aF09dHJhbnNmb3JtZWRUYWcudGFnTmFtZX19aWYodHJhbnNmb3JtVGFnc0FsbCl7dHJhbnNmb3JtZWRUYWc9dHJhbnNmb3JtVGFnc0FsbChuYW1lLGF0dHJpYnMpO2ZyYW1lLmF0dHJpYnM9YXR0cmlicz10cmFuc2Zvcm1lZFRhZy5hdHRyaWJzO2lmKG5hbWUhPT10cmFuc2Zvcm1lZFRhZy50YWdOYW1lKXtmcmFtZS5uYW1lPW5hbWU9dHJhbnNmb3JtZWRUYWcudGFnTmFtZTt0cmFuc2Zvcm1NYXBbZGVwdGhdPXRyYW5zZm9ybWVkVGFnLnRhZ05hbWV9fWlmKG9wdGlvbnMuYWxsb3dlZFRhZ3MmJm9wdGlvbnMuYWxsb3dlZFRhZ3MuaW5kZXhPZihuYW1lKT09PS0xKXtza2lwPXRydWU7aWYobm9uVGV4dFRhZ3NBcnJheS5pbmRleE9mKG5hbWUpIT09LTEpe3NraXBUZXh0PXRydWU7c2tpcFRleHREZXB0aD0xfXNraXBNYXBbZGVwdGhdPXRydWV9ZGVwdGgrKztpZihza2lwKXtyZXR1cm59cmVzdWx0Kz1cIjxcIituYW1lO2lmKCFhbGxvd2VkQXR0cmlidXRlc01hcHx8aGFzKGFsbG93ZWRBdHRyaWJ1dGVzTWFwLG5hbWUpfHxhbGxvd2VkQXR0cmlidXRlc01hcFtcIipcIl0pe2VhY2goYXR0cmlicyxmdW5jdGlvbih2YWx1ZSxhKXtpZighYWxsb3dlZEF0dHJpYnV0ZXNNYXB8fGhhcyhhbGxvd2VkQXR0cmlidXRlc01hcCxuYW1lKSYmYWxsb3dlZEF0dHJpYnV0ZXNNYXBbbmFtZV0uaW5kZXhPZihhKSE9PS0xfHxhbGxvd2VkQXR0cmlidXRlc01hcFtcIipcIl0mJmFsbG93ZWRBdHRyaWJ1dGVzTWFwW1wiKlwiXS5pbmRleE9mKGEpIT09LTF8fGhhcyhhbGxvd2VkQXR0cmlidXRlc0dsb2JNYXAsbmFtZSkmJmFsbG93ZWRBdHRyaWJ1dGVzR2xvYk1hcFtuYW1lXS50ZXN0KGEpfHxhbGxvd2VkQXR0cmlidXRlc0dsb2JNYXBbXCIqXCJdJiZhbGxvd2VkQXR0cmlidXRlc0dsb2JNYXBbXCIqXCJdLnRlc3QoYSkpe2lmKGE9PT1cImhyZWZcInx8YT09PVwic3JjXCIpe2lmKG5hdWdodHlIcmVmKG5hbWUsdmFsdWUpKXtkZWxldGUgZnJhbWUuYXR0cmlic1thXTtyZXR1cm59fWlmKGE9PT1cImNsYXNzXCIpe3ZhbHVlPWZpbHRlckNsYXNzZXModmFsdWUsYWxsb3dlZENsYXNzZXNNYXBbbmFtZV0pO2lmKCF2YWx1ZS5sZW5ndGgpe2RlbGV0ZSBmcmFtZS5hdHRyaWJzW2FdO3JldHVybn19cmVzdWx0Kz1cIiBcIithO2lmKHZhbHVlLmxlbmd0aCl7cmVzdWx0Kz0nPVwiJytlc2NhcGVIdG1sKHZhbHVlKSsnXCInfX1lbHNle2RlbGV0ZSBmcmFtZS5hdHRyaWJzW2FdfX0pfWlmKG9wdGlvbnMuc2VsZkNsb3NpbmcuaW5kZXhPZihuYW1lKSE9PS0xKXtyZXN1bHQrPVwiIC8+XCJ9ZWxzZXtyZXN1bHQrPVwiPlwiO2lmKGZyYW1lLmlubmVyVGV4dCYmIWhhc1RleHQmJiFvcHRpb25zLnRleHRGaWx0ZXIpe3Jlc3VsdCs9ZnJhbWUuaW5uZXJUZXh0fX19LG9udGV4dDpmdW5jdGlvbih0ZXh0KXtpZihza2lwVGV4dCl7cmV0dXJufXZhciBsYXN0RnJhbWU9c3RhY2tbc3RhY2subGVuZ3RoLTFdO3ZhciB0YWc7aWYobGFzdEZyYW1lKXt0YWc9bGFzdEZyYW1lLnRhZzt0ZXh0PWxhc3RGcmFtZS5pbm5lclRleHQhPT11bmRlZmluZWQ/bGFzdEZyYW1lLmlubmVyVGV4dDp0ZXh0fWlmKHRhZz09PVwic2NyaXB0XCJ8fHRhZz09PVwic3R5bGVcIil7cmVzdWx0Kz10ZXh0fWVsc2V7dmFyIGVzY2FwZWQ9ZXNjYXBlSHRtbCh0ZXh0KTtpZihvcHRpb25zLnRleHRGaWx0ZXIpe3Jlc3VsdCs9b3B0aW9ucy50ZXh0RmlsdGVyKGVzY2FwZWQpfWVsc2V7cmVzdWx0Kz1lc2NhcGVkfX1pZihzdGFjay5sZW5ndGgpe3ZhciBmcmFtZT1zdGFja1tzdGFjay5sZW5ndGgtMV07ZnJhbWUudGV4dCs9dGV4dH19LG9uY2xvc2V0YWc6ZnVuY3Rpb24obmFtZSl7aWYoc2tpcFRleHQpe3NraXBUZXh0RGVwdGgtLTtpZighc2tpcFRleHREZXB0aCl7c2tpcFRleHQ9ZmFsc2V9ZWxzZXtyZXR1cm59fXZhciBmcmFtZT1zdGFjay5wb3AoKTtpZighZnJhbWUpe3JldHVybn1za2lwVGV4dD1mYWxzZTtkZXB0aC0tO2lmKHNraXBNYXBbZGVwdGhdKXtkZWxldGUgc2tpcE1hcFtkZXB0aF07ZnJhbWUudXBkYXRlUGFyZW50Tm9kZVRleHQoKTtyZXR1cm59aWYodHJhbnNmb3JtTWFwW2RlcHRoXSl7bmFtZT10cmFuc2Zvcm1NYXBbZGVwdGhdO2RlbGV0ZSB0cmFuc2Zvcm1NYXBbZGVwdGhdfWlmKG9wdGlvbnMuZXhjbHVzaXZlRmlsdGVyJiZvcHRpb25zLmV4Y2x1c2l2ZUZpbHRlcihmcmFtZSkpe3Jlc3VsdD1yZXN1bHQuc3Vic3RyKDAsZnJhbWUudGFnUG9zaXRpb24pO3JldHVybn1mcmFtZS51cGRhdGVQYXJlbnROb2RlVGV4dCgpO2lmKG9wdGlvbnMuc2VsZkNsb3NpbmcuaW5kZXhPZihuYW1lKSE9PS0xKXtyZXR1cm59cmVzdWx0Kz1cIjwvXCIrbmFtZStcIj5cIn19LG9wdGlvbnMucGFyc2VyKTtwYXJzZXIud3JpdGUoaHRtbCk7cGFyc2VyLmVuZCgpO3JldHVybiByZXN1bHQ7ZnVuY3Rpb24gZXNjYXBlSHRtbChzKXtpZih0eXBlb2YgcyE9PVwic3RyaW5nXCIpe3M9cytcIlwifXJldHVybiBzLnJlcGxhY2UoL1xcJi9nLFwiJmFtcDtcIikucmVwbGFjZSgvPC9nLFwiJmx0O1wiKS5yZXBsYWNlKC9cXD4vZyxcIiZndDtcIikucmVwbGFjZSgvXFxcIi9nLFwiJnF1b3Q7XCIpfWZ1bmN0aW9uIG5hdWdodHlIcmVmKG5hbWUsaHJlZil7aHJlZj1ocmVmLnJlcGxhY2UoL1tcXHgwMC1cXHgyMF0rL2csXCJcIik7aHJlZj1ocmVmLnJlcGxhY2UoLzxcXCFcXC1cXC0uKj9cXC1cXC1cXD4vZyxcIlwiKTt2YXIgbWF0Y2hlcz1ocmVmLm1hdGNoKC9eKFthLXpBLVpdKylcXDovKTtpZighbWF0Y2hlcyl7cmV0dXJuIGZhbHNlfXZhciBzY2hlbWU9bWF0Y2hlc1sxXS50b0xvd2VyQ2FzZSgpO2lmKGhhcyhvcHRpb25zLmFsbG93ZWRTY2hlbWVzQnlUYWcsbmFtZSkpe3JldHVybiBvcHRpb25zLmFsbG93ZWRTY2hlbWVzQnlUYWdbbmFtZV0uaW5kZXhPZihzY2hlbWUpPT09LTF9cmV0dXJuIW9wdGlvbnMuYWxsb3dlZFNjaGVtZXN8fG9wdGlvbnMuYWxsb3dlZFNjaGVtZXMuaW5kZXhPZihzY2hlbWUpPT09LTF9ZnVuY3Rpb24gZmlsdGVyQ2xhc3NlcyhjbGFzc2VzLGFsbG93ZWQpe2lmKCFhbGxvd2VkKXtyZXR1cm4gY2xhc3Nlc31jbGFzc2VzPWNsYXNzZXMuc3BsaXQoL1xccysvKTtyZXR1cm4gY2xhc3Nlcy5maWx0ZXIoZnVuY3Rpb24oY2xzcyl7cmV0dXJuIGFsbG93ZWQuaW5kZXhPZihjbHNzKSE9PS0xfSkuam9pbihcIiBcIil9fXZhciBodG1sUGFyc2VyRGVmYXVsdHM9e2RlY29kZUVudGl0aWVzOnRydWV9O3Nhbml0aXplSHRtbC5kZWZhdWx0cz17YWxsb3dlZFRhZ3M6W1wiaDNcIixcImg0XCIsXCJoNVwiLFwiaDZcIixcImJsb2NrcXVvdGVcIixcInBcIixcImFcIixcInVsXCIsXCJvbFwiLFwibmxcIixcImxpXCIsXCJiXCIsXCJpXCIsXCJzdHJvbmdcIixcImVtXCIsXCJzdHJpa2VcIixcImNvZGVcIixcImhyXCIsXCJiclwiLFwiZGl2XCIsXCJ0YWJsZVwiLFwidGhlYWRcIixcImNhcHRpb25cIixcInRib2R5XCIsXCJ0clwiLFwidGhcIixcInRkXCIsXCJwcmVcIl0sYWxsb3dlZEF0dHJpYnV0ZXM6e2E6W1wiaHJlZlwiLFwibmFtZVwiLFwidGFyZ2V0XCJdLGltZzpbXCJzcmNcIl19LHNlbGZDbG9zaW5nOltcImltZ1wiLFwiYnJcIixcImhyXCIsXCJhcmVhXCIsXCJiYXNlXCIsXCJiYXNlZm9udFwiLFwiaW5wdXRcIixcImxpbmtcIixcIm1ldGFcIl0sYWxsb3dlZFNjaGVtZXM6W1wiaHR0cFwiLFwiaHR0cHNcIixcImZ0cFwiLFwibWFpbHRvXCJdLGFsbG93ZWRTY2hlbWVzQnlUYWc6e319O3Nhbml0aXplSHRtbC5zaW1wbGVUcmFuc2Zvcm09ZnVuY3Rpb24obmV3VGFnTmFtZSxuZXdBdHRyaWJzLG1lcmdlKXttZXJnZT1tZXJnZT09PXVuZGVmaW5lZD90cnVlOm1lcmdlO25ld0F0dHJpYnM9bmV3QXR0cmlic3x8e307cmV0dXJuIGZ1bmN0aW9uKHRhZ05hbWUsYXR0cmlicyl7dmFyIGF0dHJpYjtpZihtZXJnZSl7Zm9yKGF0dHJpYiBpbiBuZXdBdHRyaWJzKXthdHRyaWJzW2F0dHJpYl09bmV3QXR0cmlic1thdHRyaWJdfX1lbHNle2F0dHJpYnM9bmV3QXR0cmlic31yZXR1cm57dGFnTmFtZTpuZXdUYWdOYW1lLGF0dHJpYnM6YXR0cmlic319fX0se2h0bWxwYXJzZXIyOjM2LFwicmVnZXhwLXF1b3RlXCI6NTQseHRlbmQ6NTh9XSwyOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcInVzZSBzdHJpY3RcIjtleHBvcnRzLnRvQnl0ZUFycmF5PXRvQnl0ZUFycmF5O2V4cG9ydHMuZnJvbUJ5dGVBcnJheT1mcm9tQnl0ZUFycmF5O3ZhciBsb29rdXA9W107dmFyIHJldkxvb2t1cD1bXTt2YXIgQXJyPXR5cGVvZiBVaW50OEFycmF5IT09XCJ1bmRlZmluZWRcIj9VaW50OEFycmF5OkFycmF5O2Z1bmN0aW9uIGluaXQoKXt2YXIgY29kZT1cIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky9cIjtmb3IodmFyIGk9MCxsZW49Y29kZS5sZW5ndGg7aTxsZW47KytpKXtsb29rdXBbaV09Y29kZVtpXTtyZXZMb29rdXBbY29kZS5jaGFyQ29kZUF0KGkpXT1pfXJldkxvb2t1cFtcIi1cIi5jaGFyQ29kZUF0KDApXT02MjtyZXZMb29rdXBbXCJfXCIuY2hhckNvZGVBdCgwKV09NjN9aW5pdCgpO2Z1bmN0aW9uIHRvQnl0ZUFycmF5KGI2NCl7dmFyIGksaixsLHRtcCxwbGFjZUhvbGRlcnMsYXJyO3ZhciBsZW49YjY0Lmxlbmd0aDtpZihsZW4lND4wKXt0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIHN0cmluZy4gTGVuZ3RoIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA0XCIpfXBsYWNlSG9sZGVycz1iNjRbbGVuLTJdPT09XCI9XCI/MjpiNjRbbGVuLTFdPT09XCI9XCI/MTowO2Fycj1uZXcgQXJyKGxlbiozLzQtcGxhY2VIb2xkZXJzKTtsPXBsYWNlSG9sZGVycz4wP2xlbi00Omxlbjt2YXIgTD0wO2ZvcihpPTAsaj0wO2k8bDtpKz00LGorPTMpe3RtcD1yZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldPDwxOHxyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSsxKV08PDEyfHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKzIpXTw8NnxyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSszKV07YXJyW0wrK109dG1wPj4xNiYyNTU7YXJyW0wrK109dG1wPj44JjI1NTthcnJbTCsrXT10bXAmMjU1fWlmKHBsYWNlSG9sZGVycz09PTIpe3RtcD1yZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldPDwyfHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKzEpXT4+NDthcnJbTCsrXT10bXAmMjU1fWVsc2UgaWYocGxhY2VIb2xkZXJzPT09MSl7dG1wPXJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV08PDEwfHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKzEpXTw8NHxyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSsyKV0+PjI7YXJyW0wrK109dG1wPj44JjI1NTthcnJbTCsrXT10bXAmMjU1fXJldHVybiBhcnJ9ZnVuY3Rpb24gdHJpcGxldFRvQmFzZTY0KG51bSl7cmV0dXJuIGxvb2t1cFtudW0+PjE4JjYzXStsb29rdXBbbnVtPj4xMiY2M10rbG9va3VwW251bT4+NiY2M10rbG9va3VwW251bSY2M119ZnVuY3Rpb24gZW5jb2RlQ2h1bmsodWludDgsc3RhcnQsZW5kKXt2YXIgdG1wO3ZhciBvdXRwdXQ9W107Zm9yKHZhciBpPXN0YXJ0O2k8ZW5kO2krPTMpe3RtcD0odWludDhbaV08PDE2KSsodWludDhbaSsxXTw8OCkrdWludDhbaSsyXTtvdXRwdXQucHVzaCh0cmlwbGV0VG9CYXNlNjQodG1wKSl9cmV0dXJuIG91dHB1dC5qb2luKFwiXCIpfWZ1bmN0aW9uIGZyb21CeXRlQXJyYXkodWludDgpe3ZhciB0bXA7dmFyIGxlbj11aW50OC5sZW5ndGg7dmFyIGV4dHJhQnl0ZXM9bGVuJTM7dmFyIG91dHB1dD1cIlwiO3ZhciBwYXJ0cz1bXTt2YXIgbWF4Q2h1bmtMZW5ndGg9MTYzODM7Zm9yKHZhciBpPTAsbGVuMj1sZW4tZXh0cmFCeXRlcztpPGxlbjI7aSs9bWF4Q2h1bmtMZW5ndGgpe3BhcnRzLnB1c2goZW5jb2RlQ2h1bmsodWludDgsaSxpK21heENodW5rTGVuZ3RoPmxlbjI/bGVuMjppK21heENodW5rTGVuZ3RoKSl9aWYoZXh0cmFCeXRlcz09PTEpe3RtcD11aW50OFtsZW4tMV07b3V0cHV0Kz1sb29rdXBbdG1wPj4yXTtvdXRwdXQrPWxvb2t1cFt0bXA8PDQmNjNdO291dHB1dCs9XCI9PVwifWVsc2UgaWYoZXh0cmFCeXRlcz09PTIpe3RtcD0odWludDhbbGVuLTJdPDw4KSt1aW50OFtsZW4tMV07b3V0cHV0Kz1sb29rdXBbdG1wPj4xMF07b3V0cHV0Kz1sb29rdXBbdG1wPj40JjYzXTtvdXRwdXQrPWxvb2t1cFt0bXA8PDImNjNdO291dHB1dCs9XCI9XCJ9cGFydHMucHVzaChvdXRwdXQpO3JldHVybiBwYXJ0cy5qb2luKFwiXCIpfX0se31dLDM6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe30se31dLDQ6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpeyhmdW5jdGlvbihnbG9iYWwpe1widXNlIHN0cmljdFwiO3ZhciBidWZmZXI9cmVxdWlyZShcImJ1ZmZlclwiKTt2YXIgQnVmZmVyPWJ1ZmZlci5CdWZmZXI7dmFyIFNsb3dCdWZmZXI9YnVmZmVyLlNsb3dCdWZmZXI7dmFyIE1BWF9MRU49YnVmZmVyLmtNYXhMZW5ndGh8fDIxNDc0ODM2NDc7ZXhwb3J0cy5hbGxvYz1mdW5jdGlvbiBhbGxvYyhzaXplLGZpbGwsZW5jb2Rpbmcpe2lmKHR5cGVvZiBCdWZmZXIuYWxsb2M9PT1cImZ1bmN0aW9uXCIpe3JldHVybiBCdWZmZXIuYWxsb2Moc2l6ZSxmaWxsLGVuY29kaW5nKX1pZih0eXBlb2YgZW5jb2Rpbmc9PT1cIm51bWJlclwiKXt0aHJvdyBuZXcgVHlwZUVycm9yKFwiZW5jb2RpbmcgbXVzdCBub3QgYmUgbnVtYmVyXCIpfWlmKHR5cGVvZiBzaXplIT09XCJudW1iZXJcIil7dGhyb3cgbmV3IFR5cGVFcnJvcihcInNpemUgbXVzdCBiZSBhIG51bWJlclwiKX1pZihzaXplPk1BWF9MRU4pe3Rocm93IG5ldyBSYW5nZUVycm9yKFwic2l6ZSBpcyB0b28gbGFyZ2VcIil9dmFyIGVuYz1lbmNvZGluZzt2YXIgX2ZpbGw9ZmlsbDtpZihfZmlsbD09PXVuZGVmaW5lZCl7ZW5jPXVuZGVmaW5lZDtfZmlsbD0wfXZhciBidWY9bmV3IEJ1ZmZlcihzaXplKTtpZih0eXBlb2YgX2ZpbGw9PT1cInN0cmluZ1wiKXt2YXIgZmlsbEJ1Zj1uZXcgQnVmZmVyKF9maWxsLGVuYyk7dmFyIGZsZW49ZmlsbEJ1Zi5sZW5ndGg7dmFyIGk9LTE7d2hpbGUoKytpPHNpemUpe2J1ZltpXT1maWxsQnVmW2klZmxlbl19fWVsc2V7YnVmLmZpbGwoX2ZpbGwpfXJldHVybiBidWZ9O2V4cG9ydHMuYWxsb2NVbnNhZmU9ZnVuY3Rpb24gYWxsb2NVbnNhZmUoc2l6ZSl7aWYodHlwZW9mIEJ1ZmZlci5hbGxvY1Vuc2FmZT09PVwiZnVuY3Rpb25cIil7cmV0dXJuIEJ1ZmZlci5hbGxvY1Vuc2FmZShzaXplKX1pZih0eXBlb2Ygc2l6ZSE9PVwibnVtYmVyXCIpe3Rocm93IG5ldyBUeXBlRXJyb3IoXCJzaXplIG11c3QgYmUgYSBudW1iZXJcIil9aWYoc2l6ZT5NQVhfTEVOKXt0aHJvdyBuZXcgUmFuZ2VFcnJvcihcInNpemUgaXMgdG9vIGxhcmdlXCIpfXJldHVybiBuZXcgQnVmZmVyKHNpemUpfTtleHBvcnRzLmZyb209ZnVuY3Rpb24gZnJvbSh2YWx1ZSxlbmNvZGluZ09yT2Zmc2V0LGxlbmd0aCl7aWYodHlwZW9mIEJ1ZmZlci5mcm9tPT09XCJmdW5jdGlvblwiJiYoIWdsb2JhbC5VaW50OEFycmF5fHxVaW50OEFycmF5LmZyb20hPT1CdWZmZXIuZnJvbSkpe3JldHVybiBCdWZmZXIuZnJvbSh2YWx1ZSxlbmNvZGluZ09yT2Zmc2V0LGxlbmd0aCl9aWYodHlwZW9mIHZhbHVlPT09XCJudW1iZXJcIil7dGhyb3cgbmV3IFR5cGVFcnJvcignXCJ2YWx1ZVwiIGFyZ3VtZW50IG11c3Qgbm90IGJlIGEgbnVtYmVyJyl9aWYodHlwZW9mIHZhbHVlPT09XCJzdHJpbmdcIil7cmV0dXJuIG5ldyBCdWZmZXIodmFsdWUsZW5jb2RpbmdPck9mZnNldCl9aWYodHlwZW9mIEFycmF5QnVmZmVyIT09XCJ1bmRlZmluZWRcIiYmdmFsdWUgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcil7dmFyIG9mZnNldD1lbmNvZGluZ09yT2Zmc2V0O2lmKGFyZ3VtZW50cy5sZW5ndGg9PT0xKXtyZXR1cm4gbmV3IEJ1ZmZlcih2YWx1ZSl9aWYodHlwZW9mIG9mZnNldD09PVwidW5kZWZpbmVkXCIpe29mZnNldD0wfXZhciBsZW49bGVuZ3RoO2lmKHR5cGVvZiBsZW49PT1cInVuZGVmaW5lZFwiKXtsZW49dmFsdWUuYnl0ZUxlbmd0aC1vZmZzZXR9aWYob2Zmc2V0Pj12YWx1ZS5ieXRlTGVuZ3RoKXt0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIidvZmZzZXQnIGlzIG91dCBvZiBib3VuZHNcIil9aWYobGVuPnZhbHVlLmJ5dGVMZW5ndGgtb2Zmc2V0KXt0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIidsZW5ndGgnIGlzIG91dCBvZiBib3VuZHNcIil9cmV0dXJuIG5ldyBCdWZmZXIodmFsdWUuc2xpY2Uob2Zmc2V0LG9mZnNldCtsZW4pKX1pZihCdWZmZXIuaXNCdWZmZXIodmFsdWUpKXt2YXIgb3V0PW5ldyBCdWZmZXIodmFsdWUubGVuZ3RoKTt2YWx1ZS5jb3B5KG91dCwwLDAsdmFsdWUubGVuZ3RoKTtyZXR1cm4gb3V0fWlmKHZhbHVlKXtpZihBcnJheS5pc0FycmF5KHZhbHVlKXx8dHlwZW9mIEFycmF5QnVmZmVyIT09XCJ1bmRlZmluZWRcIiYmdmFsdWUuYnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXJ8fFwibGVuZ3RoXCJpbiB2YWx1ZSl7cmV0dXJuIG5ldyBCdWZmZXIodmFsdWUpfWlmKHZhbHVlLnR5cGU9PT1cIkJ1ZmZlclwiJiZBcnJheS5pc0FycmF5KHZhbHVlLmRhdGEpKXtyZXR1cm4gbmV3IEJ1ZmZlcih2YWx1ZS5kYXRhKX19dGhyb3cgbmV3IFR5cGVFcnJvcihcIkZpcnN0IGFyZ3VtZW50IG11c3QgYmUgYSBzdHJpbmcsIEJ1ZmZlciwgXCIrXCJBcnJheUJ1ZmZlciwgQXJyYXksIG9yIGFycmF5LWxpa2Ugb2JqZWN0LlwiKX07ZXhwb3J0cy5hbGxvY1Vuc2FmZVNsb3c9ZnVuY3Rpb24gYWxsb2NVbnNhZmVTbG93KHNpemUpe2lmKHR5cGVvZiBCdWZmZXIuYWxsb2NVbnNhZmVTbG93PT09XCJmdW5jdGlvblwiKXtyZXR1cm4gQnVmZmVyLmFsbG9jVW5zYWZlU2xvdyhzaXplKX1pZih0eXBlb2Ygc2l6ZSE9PVwibnVtYmVyXCIpe3Rocm93IG5ldyBUeXBlRXJyb3IoXCJzaXplIG11c3QgYmUgYSBudW1iZXJcIil9aWYoc2l6ZT49TUFYX0xFTil7dGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJzaXplIGlzIHRvbyBsYXJnZVwiKX1yZXR1cm4gbmV3IFNsb3dCdWZmZXIoc2l6ZSl9fSkuY2FsbCh0aGlzLHR5cGVvZiBnbG9iYWwhPT1cInVuZGVmaW5lZFwiP2dsb2JhbDp0eXBlb2Ygc2VsZiE9PVwidW5kZWZpbmVkXCI/c2VsZjp0eXBlb2Ygd2luZG93IT09XCJ1bmRlZmluZWRcIj93aW5kb3c6e30pfSx7YnVmZmVyOjV9XSw1OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsoZnVuY3Rpb24oZ2xvYmFsKXtcInVzZSBzdHJpY3RcIjt2YXIgYmFzZTY0PXJlcXVpcmUoXCJiYXNlNjQtanNcIik7dmFyIGllZWU3NTQ9cmVxdWlyZShcImllZWU3NTRcIik7dmFyIGlzQXJyYXk9cmVxdWlyZShcImlzYXJyYXlcIik7ZXhwb3J0cy5CdWZmZXI9QnVmZmVyO2V4cG9ydHMuU2xvd0J1ZmZlcj1TbG93QnVmZmVyO2V4cG9ydHMuSU5TUEVDVF9NQVhfQllURVM9NTA7QnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQ9Z2xvYmFsLlRZUEVEX0FSUkFZX1NVUFBPUlQhPT11bmRlZmluZWQ/Z2xvYmFsLlRZUEVEX0FSUkFZX1NVUFBPUlQ6dHlwZWRBcnJheVN1cHBvcnQoKTtleHBvcnRzLmtNYXhMZW5ndGg9a01heExlbmd0aCgpO2Z1bmN0aW9uIHR5cGVkQXJyYXlTdXBwb3J0KCl7dHJ5e3ZhciBhcnI9bmV3IFVpbnQ4QXJyYXkoMSk7YXJyLl9fcHJvdG9fXz17X19wcm90b19fOlVpbnQ4QXJyYXkucHJvdG90eXBlLGZvbzpmdW5jdGlvbigpe3JldHVybiA0Mn19O3JldHVybiBhcnIuZm9vKCk9PT00MiYmdHlwZW9mIGFyci5zdWJhcnJheT09PVwiZnVuY3Rpb25cIiYmYXJyLnN1YmFycmF5KDEsMSkuYnl0ZUxlbmd0aD09PTB9Y2F0Y2goZSl7cmV0dXJuIGZhbHNlfX1mdW5jdGlvbiBrTWF4TGVuZ3RoKCl7cmV0dXJuIEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUPzIxNDc0ODM2NDc6MTA3Mzc0MTgyM31mdW5jdGlvbiBjcmVhdGVCdWZmZXIodGhhdCxsZW5ndGgpe2lmKGtNYXhMZW5ndGgoKTxsZW5ndGgpe3Rocm93IG5ldyBSYW5nZUVycm9yKFwiSW52YWxpZCB0eXBlZCBhcnJheSBsZW5ndGhcIil9aWYoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpe3RoYXQ9bmV3IFVpbnQ4QXJyYXkobGVuZ3RoKTt0aGF0Ll9fcHJvdG9fXz1CdWZmZXIucHJvdG90eXBlfWVsc2V7aWYodGhhdD09PW51bGwpe3RoYXQ9bmV3IEJ1ZmZlcihsZW5ndGgpfXRoYXQubGVuZ3RoPWxlbmd0aH1yZXR1cm4gdGhhdH1mdW5jdGlvbiBCdWZmZXIoYXJnLGVuY29kaW5nT3JPZmZzZXQsbGVuZ3RoKXtpZighQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQmJiEodGhpcyBpbnN0YW5jZW9mIEJ1ZmZlcikpe3JldHVybiBuZXcgQnVmZmVyKGFyZyxlbmNvZGluZ09yT2Zmc2V0LGxlbmd0aCl9aWYodHlwZW9mIGFyZz09PVwibnVtYmVyXCIpe2lmKHR5cGVvZiBlbmNvZGluZ09yT2Zmc2V0PT09XCJzdHJpbmdcIil7dGhyb3cgbmV3IEVycm9yKFwiSWYgZW5jb2RpbmcgaXMgc3BlY2lmaWVkIHRoZW4gdGhlIGZpcnN0IGFyZ3VtZW50IG11c3QgYmUgYSBzdHJpbmdcIil9cmV0dXJuIGFsbG9jVW5zYWZlKHRoaXMsYXJnKX1yZXR1cm4gZnJvbSh0aGlzLGFyZyxlbmNvZGluZ09yT2Zmc2V0LGxlbmd0aCl9QnVmZmVyLnBvb2xTaXplPTgxOTI7QnVmZmVyLl9hdWdtZW50PWZ1bmN0aW9uKGFycil7YXJyLl9fcHJvdG9fXz1CdWZmZXIucHJvdG90eXBlO3JldHVybiBhcnJ9O2Z1bmN0aW9uIGZyb20odGhhdCx2YWx1ZSxlbmNvZGluZ09yT2Zmc2V0LGxlbmd0aCl7aWYodHlwZW9mIHZhbHVlPT09XCJudW1iZXJcIil7dGhyb3cgbmV3IFR5cGVFcnJvcignXCJ2YWx1ZVwiIGFyZ3VtZW50IG11c3Qgbm90IGJlIGEgbnVtYmVyJyl9aWYodHlwZW9mIEFycmF5QnVmZmVyIT09XCJ1bmRlZmluZWRcIiYmdmFsdWUgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcil7cmV0dXJuIGZyb21BcnJheUJ1ZmZlcih0aGF0LHZhbHVlLGVuY29kaW5nT3JPZmZzZXQsbGVuZ3RoKX1pZih0eXBlb2YgdmFsdWU9PT1cInN0cmluZ1wiKXtyZXR1cm4gZnJvbVN0cmluZyh0aGF0LHZhbHVlLGVuY29kaW5nT3JPZmZzZXQpfXJldHVybiBmcm9tT2JqZWN0KHRoYXQsdmFsdWUpfUJ1ZmZlci5mcm9tPWZ1bmN0aW9uKHZhbHVlLGVuY29kaW5nT3JPZmZzZXQsbGVuZ3RoKXtyZXR1cm4gZnJvbShudWxsLHZhbHVlLGVuY29kaW5nT3JPZmZzZXQsbGVuZ3RoKX07aWYoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpe0J1ZmZlci5wcm90b3R5cGUuX19wcm90b19fPVVpbnQ4QXJyYXkucHJvdG90eXBlO0J1ZmZlci5fX3Byb3RvX189VWludDhBcnJheTtpZih0eXBlb2YgU3ltYm9sIT09XCJ1bmRlZmluZWRcIiYmU3ltYm9sLnNwZWNpZXMmJkJ1ZmZlcltTeW1ib2wuc3BlY2llc109PT1CdWZmZXIpe09iamVjdC5kZWZpbmVQcm9wZXJ0eShCdWZmZXIsU3ltYm9sLnNwZWNpZXMse3ZhbHVlOm51bGwsY29uZmlndXJhYmxlOnRydWV9KX19ZnVuY3Rpb24gYXNzZXJ0U2l6ZShzaXplKXtpZih0eXBlb2Ygc2l6ZSE9PVwibnVtYmVyXCIpe3Rocm93IG5ldyBUeXBlRXJyb3IoJ1wic2l6ZVwiIGFyZ3VtZW50IG11c3QgYmUgYSBudW1iZXInKX1lbHNlIGlmKHNpemU8MCl7dGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1wic2l6ZVwiIGFyZ3VtZW50IG11c3Qgbm90IGJlIG5lZ2F0aXZlJyl9fWZ1bmN0aW9uIGFsbG9jKHRoYXQsc2l6ZSxmaWxsLGVuY29kaW5nKXthc3NlcnRTaXplKHNpemUpO2lmKHNpemU8PTApe3JldHVybiBjcmVhdGVCdWZmZXIodGhhdCxzaXplKX1pZihmaWxsIT09dW5kZWZpbmVkKXtyZXR1cm4gdHlwZW9mIGVuY29kaW5nPT09XCJzdHJpbmdcIj9jcmVhdGVCdWZmZXIodGhhdCxzaXplKS5maWxsKGZpbGwsZW5jb2RpbmcpOmNyZWF0ZUJ1ZmZlcih0aGF0LHNpemUpLmZpbGwoZmlsbCl9cmV0dXJuIGNyZWF0ZUJ1ZmZlcih0aGF0LHNpemUpfUJ1ZmZlci5hbGxvYz1mdW5jdGlvbihzaXplLGZpbGwsZW5jb2Rpbmcpe3JldHVybiBhbGxvYyhudWxsLHNpemUsZmlsbCxlbmNvZGluZyl9O2Z1bmN0aW9uIGFsbG9jVW5zYWZlKHRoYXQsc2l6ZSl7YXNzZXJ0U2l6ZShzaXplKTt0aGF0PWNyZWF0ZUJ1ZmZlcih0aGF0LHNpemU8MD8wOmNoZWNrZWQoc2l6ZSl8MCk7aWYoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKXtmb3IodmFyIGk9MDtpPHNpemU7KytpKXt0aGF0W2ldPTB9fXJldHVybiB0aGF0fUJ1ZmZlci5hbGxvY1Vuc2FmZT1mdW5jdGlvbihzaXplKXtyZXR1cm4gYWxsb2NVbnNhZmUobnVsbCxzaXplKX07QnVmZmVyLmFsbG9jVW5zYWZlU2xvdz1mdW5jdGlvbihzaXplKXtyZXR1cm4gYWxsb2NVbnNhZmUobnVsbCxzaXplKX07ZnVuY3Rpb24gZnJvbVN0cmluZyh0aGF0LHN0cmluZyxlbmNvZGluZyl7aWYodHlwZW9mIGVuY29kaW5nIT09XCJzdHJpbmdcInx8ZW5jb2Rpbmc9PT1cIlwiKXtlbmNvZGluZz1cInV0ZjhcIn1pZighQnVmZmVyLmlzRW5jb2RpbmcoZW5jb2RpbmcpKXt0aHJvdyBuZXcgVHlwZUVycm9yKCdcImVuY29kaW5nXCIgbXVzdCBiZSBhIHZhbGlkIHN0cmluZyBlbmNvZGluZycpfXZhciBsZW5ndGg9Ynl0ZUxlbmd0aChzdHJpbmcsZW5jb2RpbmcpfDA7dGhhdD1jcmVhdGVCdWZmZXIodGhhdCxsZW5ndGgpO3ZhciBhY3R1YWw9dGhhdC53cml0ZShzdHJpbmcsZW5jb2RpbmcpO2lmKGFjdHVhbCE9PWxlbmd0aCl7dGhhdD10aGF0LnNsaWNlKDAsYWN0dWFsKX1yZXR1cm4gdGhhdH1mdW5jdGlvbiBmcm9tQXJyYXlMaWtlKHRoYXQsYXJyYXkpe3ZhciBsZW5ndGg9YXJyYXkubGVuZ3RoPDA/MDpjaGVja2VkKGFycmF5Lmxlbmd0aCl8MDt0aGF0PWNyZWF0ZUJ1ZmZlcih0aGF0LGxlbmd0aCk7Zm9yKHZhciBpPTA7aTxsZW5ndGg7aSs9MSl7dGhhdFtpXT1hcnJheVtpXSYyNTV9cmV0dXJuIHRoYXR9ZnVuY3Rpb24gZnJvbUFycmF5QnVmZmVyKHRoYXQsYXJyYXksYnl0ZU9mZnNldCxsZW5ndGgpe2FycmF5LmJ5dGVMZW5ndGg7aWYoYnl0ZU9mZnNldDwwfHxhcnJheS5ieXRlTGVuZ3RoPGJ5dGVPZmZzZXQpe3Rocm93IG5ldyBSYW5nZUVycm9yKFwiJ29mZnNldCcgaXMgb3V0IG9mIGJvdW5kc1wiKX1pZihhcnJheS5ieXRlTGVuZ3RoPGJ5dGVPZmZzZXQrKGxlbmd0aHx8MCkpe3Rocm93IG5ldyBSYW5nZUVycm9yKFwiJ2xlbmd0aCcgaXMgb3V0IG9mIGJvdW5kc1wiKX1pZihieXRlT2Zmc2V0PT09dW5kZWZpbmVkJiZsZW5ndGg9PT11bmRlZmluZWQpe2FycmF5PW5ldyBVaW50OEFycmF5KGFycmF5KX1lbHNlIGlmKGxlbmd0aD09PXVuZGVmaW5lZCl7YXJyYXk9bmV3IFVpbnQ4QXJyYXkoYXJyYXksYnl0ZU9mZnNldCl9ZWxzZXthcnJheT1uZXcgVWludDhBcnJheShhcnJheSxieXRlT2Zmc2V0LGxlbmd0aCl9aWYoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpe3RoYXQ9YXJyYXk7dGhhdC5fX3Byb3RvX189QnVmZmVyLnByb3RvdHlwZX1lbHNle3RoYXQ9ZnJvbUFycmF5TGlrZSh0aGF0LGFycmF5KX1yZXR1cm4gdGhhdH1mdW5jdGlvbiBmcm9tT2JqZWN0KHRoYXQsb2JqKXtpZihCdWZmZXIuaXNCdWZmZXIob2JqKSl7dmFyIGxlbj1jaGVja2VkKG9iai5sZW5ndGgpfDA7dGhhdD1jcmVhdGVCdWZmZXIodGhhdCxsZW4pO2lmKHRoYXQubGVuZ3RoPT09MCl7cmV0dXJuIHRoYXR9b2JqLmNvcHkodGhhdCwwLDAsbGVuKTtyZXR1cm4gdGhhdH1pZihvYmope2lmKHR5cGVvZiBBcnJheUJ1ZmZlciE9PVwidW5kZWZpbmVkXCImJm9iai5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcnx8XCJsZW5ndGhcImluIG9iail7aWYodHlwZW9mIG9iai5sZW5ndGghPT1cIm51bWJlclwifHxpc25hbihvYmoubGVuZ3RoKSl7cmV0dXJuIGNyZWF0ZUJ1ZmZlcih0aGF0LDApfXJldHVybiBmcm9tQXJyYXlMaWtlKHRoYXQsb2JqKX1pZihvYmoudHlwZT09PVwiQnVmZmVyXCImJmlzQXJyYXkob2JqLmRhdGEpKXtyZXR1cm4gZnJvbUFycmF5TGlrZSh0aGF0LG9iai5kYXRhKX19dGhyb3cgbmV3IFR5cGVFcnJvcihcIkZpcnN0IGFyZ3VtZW50IG11c3QgYmUgYSBzdHJpbmcsIEJ1ZmZlciwgQXJyYXlCdWZmZXIsIEFycmF5LCBvciBhcnJheS1saWtlIG9iamVjdC5cIil9ZnVuY3Rpb24gY2hlY2tlZChsZW5ndGgpe2lmKGxlbmd0aD49a01heExlbmd0aCgpKXt0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkF0dGVtcHQgdG8gYWxsb2NhdGUgQnVmZmVyIGxhcmdlciB0aGFuIG1heGltdW0gXCIrXCJzaXplOiAweFwiK2tNYXhMZW5ndGgoKS50b1N0cmluZygxNikrXCIgYnl0ZXNcIil9cmV0dXJuIGxlbmd0aHwwfWZ1bmN0aW9uIFNsb3dCdWZmZXIobGVuZ3RoKXtpZigrbGVuZ3RoIT1sZW5ndGgpe2xlbmd0aD0wfXJldHVybiBCdWZmZXIuYWxsb2MoK2xlbmd0aCl9QnVmZmVyLmlzQnVmZmVyPWZ1bmN0aW9uIGlzQnVmZmVyKGIpe3JldHVybiEhKGIhPW51bGwmJmIuX2lzQnVmZmVyKX07QnVmZmVyLmNvbXBhcmU9ZnVuY3Rpb24gY29tcGFyZShhLGIpe2lmKCFCdWZmZXIuaXNCdWZmZXIoYSl8fCFCdWZmZXIuaXNCdWZmZXIoYikpe3Rocm93IG5ldyBUeXBlRXJyb3IoXCJBcmd1bWVudHMgbXVzdCBiZSBCdWZmZXJzXCIpfWlmKGE9PT1iKXJldHVybiAwO3ZhciB4PWEubGVuZ3RoO3ZhciB5PWIubGVuZ3RoO2Zvcih2YXIgaT0wLGxlbj1NYXRoLm1pbih4LHkpO2k8bGVuOysraSl7aWYoYVtpXSE9PWJbaV0pe3g9YVtpXTt5PWJbaV07YnJlYWt9fWlmKHg8eSlyZXR1cm4tMTtpZih5PHgpcmV0dXJuIDE7cmV0dXJuIDB9O0J1ZmZlci5pc0VuY29kaW5nPWZ1bmN0aW9uIGlzRW5jb2RpbmcoZW5jb2Rpbmcpe3N3aXRjaChTdHJpbmcoZW5jb2RpbmcpLnRvTG93ZXJDYXNlKCkpe2Nhc2VcImhleFwiOmNhc2VcInV0ZjhcIjpjYXNlXCJ1dGYtOFwiOmNhc2VcImFzY2lpXCI6Y2FzZVwibGF0aW4xXCI6Y2FzZVwiYmluYXJ5XCI6Y2FzZVwiYmFzZTY0XCI6Y2FzZVwidWNzMlwiOmNhc2VcInVjcy0yXCI6Y2FzZVwidXRmMTZsZVwiOmNhc2VcInV0Zi0xNmxlXCI6cmV0dXJuIHRydWU7ZGVmYXVsdDpyZXR1cm4gZmFsc2V9fTtCdWZmZXIuY29uY2F0PWZ1bmN0aW9uIGNvbmNhdChsaXN0LGxlbmd0aCl7aWYoIWlzQXJyYXkobGlzdCkpe3Rocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdFwiIGFyZ3VtZW50IG11c3QgYmUgYW4gQXJyYXkgb2YgQnVmZmVycycpfWlmKGxpc3QubGVuZ3RoPT09MCl7cmV0dXJuIEJ1ZmZlci5hbGxvYygwKX12YXIgaTtpZihsZW5ndGg9PT11bmRlZmluZWQpe2xlbmd0aD0wO2ZvcihpPTA7aTxsaXN0Lmxlbmd0aDsrK2kpe2xlbmd0aCs9bGlzdFtpXS5sZW5ndGh9fXZhciBidWZmZXI9QnVmZmVyLmFsbG9jVW5zYWZlKGxlbmd0aCk7dmFyIHBvcz0wO2ZvcihpPTA7aTxsaXN0Lmxlbmd0aDsrK2kpe3ZhciBidWY9bGlzdFtpXTtpZighQnVmZmVyLmlzQnVmZmVyKGJ1Zikpe3Rocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdFwiIGFyZ3VtZW50IG11c3QgYmUgYW4gQXJyYXkgb2YgQnVmZmVycycpfWJ1Zi5jb3B5KGJ1ZmZlcixwb3MpO3Bvcys9YnVmLmxlbmd0aH1yZXR1cm4gYnVmZmVyfTtmdW5jdGlvbiBieXRlTGVuZ3RoKHN0cmluZyxlbmNvZGluZyl7aWYoQnVmZmVyLmlzQnVmZmVyKHN0cmluZykpe3JldHVybiBzdHJpbmcubGVuZ3RofWlmKHR5cGVvZiBBcnJheUJ1ZmZlciE9PVwidW5kZWZpbmVkXCImJnR5cGVvZiBBcnJheUJ1ZmZlci5pc1ZpZXc9PT1cImZ1bmN0aW9uXCImJihBcnJheUJ1ZmZlci5pc1ZpZXcoc3RyaW5nKXx8c3RyaW5nIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpKXtyZXR1cm4gc3RyaW5nLmJ5dGVMZW5ndGh9aWYodHlwZW9mIHN0cmluZyE9PVwic3RyaW5nXCIpe3N0cmluZz1cIlwiK3N0cmluZ312YXIgbGVuPXN0cmluZy5sZW5ndGg7aWYobGVuPT09MClyZXR1cm4gMDt2YXIgbG93ZXJlZENhc2U9ZmFsc2U7Zm9yKDs7KXtzd2l0Y2goZW5jb2Rpbmcpe2Nhc2VcImFzY2lpXCI6Y2FzZVwibGF0aW4xXCI6Y2FzZVwiYmluYXJ5XCI6cmV0dXJuIGxlbjtjYXNlXCJ1dGY4XCI6Y2FzZVwidXRmLThcIjpjYXNlIHVuZGVmaW5lZDpyZXR1cm4gdXRmOFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGg7Y2FzZVwidWNzMlwiOmNhc2VcInVjcy0yXCI6Y2FzZVwidXRmMTZsZVwiOmNhc2VcInV0Zi0xNmxlXCI6cmV0dXJuIGxlbioyO2Nhc2VcImhleFwiOnJldHVybiBsZW4+Pj4xO2Nhc2VcImJhc2U2NFwiOnJldHVybiBiYXNlNjRUb0J5dGVzKHN0cmluZykubGVuZ3RoO2RlZmF1bHQ6aWYobG93ZXJlZENhc2UpcmV0dXJuIHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoO2VuY29kaW5nPShcIlwiK2VuY29kaW5nKS50b0xvd2VyQ2FzZSgpO2xvd2VyZWRDYXNlPXRydWV9fX1CdWZmZXIuYnl0ZUxlbmd0aD1ieXRlTGVuZ3RoO2Z1bmN0aW9uIHNsb3dUb1N0cmluZyhlbmNvZGluZyxzdGFydCxlbmQpe3ZhciBsb3dlcmVkQ2FzZT1mYWxzZTtpZihzdGFydD09PXVuZGVmaW5lZHx8c3RhcnQ8MCl7c3RhcnQ9MH1pZihzdGFydD50aGlzLmxlbmd0aCl7cmV0dXJuXCJcIn1pZihlbmQ9PT11bmRlZmluZWR8fGVuZD50aGlzLmxlbmd0aCl7ZW5kPXRoaXMubGVuZ3RofWlmKGVuZDw9MCl7cmV0dXJuXCJcIn1lbmQ+Pj49MDtzdGFydD4+Pj0wO2lmKGVuZDw9c3RhcnQpe3JldHVyblwiXCJ9aWYoIWVuY29kaW5nKWVuY29kaW5nPVwidXRmOFwiO3doaWxlKHRydWUpe3N3aXRjaChlbmNvZGluZyl7Y2FzZVwiaGV4XCI6cmV0dXJuIGhleFNsaWNlKHRoaXMsc3RhcnQsZW5kKTtjYXNlXCJ1dGY4XCI6Y2FzZVwidXRmLThcIjpyZXR1cm4gdXRmOFNsaWNlKHRoaXMsc3RhcnQsZW5kKTtjYXNlXCJhc2NpaVwiOnJldHVybiBhc2NpaVNsaWNlKHRoaXMsc3RhcnQsZW5kKTtjYXNlXCJsYXRpbjFcIjpjYXNlXCJiaW5hcnlcIjpyZXR1cm4gbGF0aW4xU2xpY2UodGhpcyxzdGFydCxlbmQpO2Nhc2VcImJhc2U2NFwiOnJldHVybiBiYXNlNjRTbGljZSh0aGlzLHN0YXJ0LGVuZCk7Y2FzZVwidWNzMlwiOmNhc2VcInVjcy0yXCI6Y2FzZVwidXRmMTZsZVwiOmNhc2VcInV0Zi0xNmxlXCI6cmV0dXJuIHV0ZjE2bGVTbGljZSh0aGlzLHN0YXJ0LGVuZCk7ZGVmYXVsdDppZihsb3dlcmVkQ2FzZSl0aHJvdyBuZXcgVHlwZUVycm9yKFwiVW5rbm93biBlbmNvZGluZzogXCIrZW5jb2RpbmcpO2VuY29kaW5nPShlbmNvZGluZytcIlwiKS50b0xvd2VyQ2FzZSgpO2xvd2VyZWRDYXNlPXRydWV9fX1CdWZmZXIucHJvdG90eXBlLl9pc0J1ZmZlcj10cnVlO2Z1bmN0aW9uIHN3YXAoYixuLG0pe3ZhciBpPWJbbl07YltuXT1iW21dO2JbbV09aX1CdWZmZXIucHJvdG90eXBlLnN3YXAxNj1mdW5jdGlvbiBzd2FwMTYoKXt2YXIgbGVuPXRoaXMubGVuZ3RoO2lmKGxlbiUyIT09MCl7dGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgMTYtYml0c1wiKX1mb3IodmFyIGk9MDtpPGxlbjtpKz0yKXtzd2FwKHRoaXMsaSxpKzEpfXJldHVybiB0aGlzfTtCdWZmZXIucHJvdG90eXBlLnN3YXAzMj1mdW5jdGlvbiBzd2FwMzIoKXt2YXIgbGVuPXRoaXMubGVuZ3RoO2lmKGxlbiU0IT09MCl7dGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgMzItYml0c1wiKX1mb3IodmFyIGk9MDtpPGxlbjtpKz00KXtzd2FwKHRoaXMsaSxpKzMpO3N3YXAodGhpcyxpKzEsaSsyKX1yZXR1cm4gdGhpc307QnVmZmVyLnByb3RvdHlwZS5zd2FwNjQ9ZnVuY3Rpb24gc3dhcDY0KCl7dmFyIGxlbj10aGlzLmxlbmd0aDtpZihsZW4lOCE9PTApe3Rocm93IG5ldyBSYW5nZUVycm9yKFwiQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDY0LWJpdHNcIil9Zm9yKHZhciBpPTA7aTxsZW47aSs9OCl7c3dhcCh0aGlzLGksaSs3KTtzd2FwKHRoaXMsaSsxLGkrNik7c3dhcCh0aGlzLGkrMixpKzUpO3N3YXAodGhpcyxpKzMsaSs0KX1yZXR1cm4gdGhpc307QnVmZmVyLnByb3RvdHlwZS50b1N0cmluZz1mdW5jdGlvbiB0b1N0cmluZygpe3ZhciBsZW5ndGg9dGhpcy5sZW5ndGh8MDtpZihsZW5ndGg9PT0wKXJldHVyblwiXCI7aWYoYXJndW1lbnRzLmxlbmd0aD09PTApcmV0dXJuIHV0ZjhTbGljZSh0aGlzLDAsbGVuZ3RoKTtyZXR1cm4gc2xvd1RvU3RyaW5nLmFwcGx5KHRoaXMsYXJndW1lbnRzKX07QnVmZmVyLnByb3RvdHlwZS5lcXVhbHM9ZnVuY3Rpb24gZXF1YWxzKGIpe2lmKCFCdWZmZXIuaXNCdWZmZXIoYikpdGhyb3cgbmV3IFR5cGVFcnJvcihcIkFyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXJcIik7aWYodGhpcz09PWIpcmV0dXJuIHRydWU7cmV0dXJuIEJ1ZmZlci5jb21wYXJlKHRoaXMsYik9PT0wfTtCdWZmZXIucHJvdG90eXBlLmluc3BlY3Q9ZnVuY3Rpb24gaW5zcGVjdCgpe3ZhciBzdHI9XCJcIjt2YXIgbWF4PWV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVM7aWYodGhpcy5sZW5ndGg+MCl7c3RyPXRoaXMudG9TdHJpbmcoXCJoZXhcIiwwLG1heCkubWF0Y2goLy57Mn0vZykuam9pbihcIiBcIik7aWYodGhpcy5sZW5ndGg+bWF4KXN0cis9XCIgLi4uIFwifXJldHVyblwiPEJ1ZmZlciBcIitzdHIrXCI+XCJ9O0J1ZmZlci5wcm90b3R5cGUuY29tcGFyZT1mdW5jdGlvbiBjb21wYXJlKHRhcmdldCxzdGFydCxlbmQsdGhpc1N0YXJ0LHRoaXNFbmQpe2lmKCFCdWZmZXIuaXNCdWZmZXIodGFyZ2V0KSl7dGhyb3cgbmV3IFR5cGVFcnJvcihcIkFyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXJcIil9aWYoc3RhcnQ9PT11bmRlZmluZWQpe3N0YXJ0PTB9aWYoZW5kPT09dW5kZWZpbmVkKXtlbmQ9dGFyZ2V0P3RhcmdldC5sZW5ndGg6MH1pZih0aGlzU3RhcnQ9PT11bmRlZmluZWQpe3RoaXNTdGFydD0wfWlmKHRoaXNFbmQ9PT11bmRlZmluZWQpe3RoaXNFbmQ9dGhpcy5sZW5ndGh9aWYoc3RhcnQ8MHx8ZW5kPnRhcmdldC5sZW5ndGh8fHRoaXNTdGFydDwwfHx0aGlzRW5kPnRoaXMubGVuZ3RoKXt0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIm91dCBvZiByYW5nZSBpbmRleFwiKX1pZih0aGlzU3RhcnQ+PXRoaXNFbmQmJnN0YXJ0Pj1lbmQpe3JldHVybiAwfWlmKHRoaXNTdGFydD49dGhpc0VuZCl7cmV0dXJuLTF9aWYoc3RhcnQ+PWVuZCl7cmV0dXJuIDF9c3RhcnQ+Pj49MDtlbmQ+Pj49MDt0aGlzU3RhcnQ+Pj49MDt0aGlzRW5kPj4+PTA7aWYodGhpcz09PXRhcmdldClyZXR1cm4gMDt2YXIgeD10aGlzRW5kLXRoaXNTdGFydDt2YXIgeT1lbmQtc3RhcnQ7dmFyIGxlbj1NYXRoLm1pbih4LHkpO3ZhciB0aGlzQ29weT10aGlzLnNsaWNlKHRoaXNTdGFydCx0aGlzRW5kKTt2YXIgdGFyZ2V0Q29weT10YXJnZXQuc2xpY2Uoc3RhcnQsZW5kKTtmb3IodmFyIGk9MDtpPGxlbjsrK2kpe2lmKHRoaXNDb3B5W2ldIT09dGFyZ2V0Q29weVtpXSl7eD10aGlzQ29weVtpXTt5PXRhcmdldENvcHlbaV07YnJlYWt9fWlmKHg8eSlyZXR1cm4tMTtpZih5PHgpcmV0dXJuIDE7cmV0dXJuIDB9O2Z1bmN0aW9uIGJpZGlyZWN0aW9uYWxJbmRleE9mKGJ1ZmZlcix2YWwsYnl0ZU9mZnNldCxlbmNvZGluZyxkaXIpe2lmKGJ1ZmZlci5sZW5ndGg9PT0wKXJldHVybi0xO2lmKHR5cGVvZiBieXRlT2Zmc2V0PT09XCJzdHJpbmdcIil7ZW5jb2Rpbmc9Ynl0ZU9mZnNldDtieXRlT2Zmc2V0PTB9ZWxzZSBpZihieXRlT2Zmc2V0PjIxNDc0ODM2NDcpe2J5dGVPZmZzZXQ9MjE0NzQ4MzY0N31lbHNlIGlmKGJ5dGVPZmZzZXQ8LTIxNDc0ODM2NDgpe2J5dGVPZmZzZXQ9LTIxNDc0ODM2NDh9Ynl0ZU9mZnNldD0rYnl0ZU9mZnNldDtpZihpc05hTihieXRlT2Zmc2V0KSl7Ynl0ZU9mZnNldD1kaXI/MDpidWZmZXIubGVuZ3RoLTF9aWYoYnl0ZU9mZnNldDwwKWJ5dGVPZmZzZXQ9YnVmZmVyLmxlbmd0aCtieXRlT2Zmc2V0O2lmKGJ5dGVPZmZzZXQ+PWJ1ZmZlci5sZW5ndGgpe2lmKGRpcilyZXR1cm4tMTtlbHNlIGJ5dGVPZmZzZXQ9YnVmZmVyLmxlbmd0aC0xfWVsc2UgaWYoYnl0ZU9mZnNldDwwKXtpZihkaXIpYnl0ZU9mZnNldD0wO2Vsc2UgcmV0dXJuLTF9aWYodHlwZW9mIHZhbD09PVwic3RyaW5nXCIpe3ZhbD1CdWZmZXIuZnJvbSh2YWwsZW5jb2RpbmcpfWlmKEJ1ZmZlci5pc0J1ZmZlcih2YWwpKXtpZih2YWwubGVuZ3RoPT09MCl7cmV0dXJuLTF9cmV0dXJuIGFycmF5SW5kZXhPZihidWZmZXIsdmFsLGJ5dGVPZmZzZXQsZW5jb2RpbmcsZGlyKX1lbHNlIGlmKHR5cGVvZiB2YWw9PT1cIm51bWJlclwiKXt2YWw9dmFsJjI1NTtpZihCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCYmdHlwZW9mIFVpbnQ4QXJyYXkucHJvdG90eXBlLmluZGV4T2Y9PT1cImZ1bmN0aW9uXCIpe2lmKGRpcil7cmV0dXJuIFVpbnQ4QXJyYXkucHJvdG90eXBlLmluZGV4T2YuY2FsbChidWZmZXIsdmFsLGJ5dGVPZmZzZXQpfWVsc2V7cmV0dXJuIFVpbnQ4QXJyYXkucHJvdG90eXBlLmxhc3RJbmRleE9mLmNhbGwoYnVmZmVyLHZhbCxieXRlT2Zmc2V0KX19cmV0dXJuIGFycmF5SW5kZXhPZihidWZmZXIsW3ZhbF0sYnl0ZU9mZnNldCxlbmNvZGluZyxkaXIpfXRocm93IG5ldyBUeXBlRXJyb3IoXCJ2YWwgbXVzdCBiZSBzdHJpbmcsIG51bWJlciBvciBCdWZmZXJcIil9ZnVuY3Rpb24gYXJyYXlJbmRleE9mKGFycix2YWwsYnl0ZU9mZnNldCxlbmNvZGluZyxkaXIpe3ZhciBpbmRleFNpemU9MTt2YXIgYXJyTGVuZ3RoPWFyci5sZW5ndGg7dmFyIHZhbExlbmd0aD12YWwubGVuZ3RoO2lmKGVuY29kaW5nIT09dW5kZWZpbmVkKXtlbmNvZGluZz1TdHJpbmcoZW5jb2RpbmcpLnRvTG93ZXJDYXNlKCk7aWYoZW5jb2Rpbmc9PT1cInVjczJcInx8ZW5jb2Rpbmc9PT1cInVjcy0yXCJ8fGVuY29kaW5nPT09XCJ1dGYxNmxlXCJ8fGVuY29kaW5nPT09XCJ1dGYtMTZsZVwiKXtpZihhcnIubGVuZ3RoPDJ8fHZhbC5sZW5ndGg8Mil7cmV0dXJuLTF9aW5kZXhTaXplPTI7YXJyTGVuZ3RoLz0yO3ZhbExlbmd0aC89MjtieXRlT2Zmc2V0Lz0yfX1mdW5jdGlvbiByZWFkKGJ1ZixpKXtpZihpbmRleFNpemU9PT0xKXtyZXR1cm4gYnVmW2ldfWVsc2V7cmV0dXJuIGJ1Zi5yZWFkVUludDE2QkUoaSppbmRleFNpemUpfX12YXIgaTtpZihkaXIpe3ZhciBmb3VuZEluZGV4PS0xO2ZvcihpPWJ5dGVPZmZzZXQ7aTxhcnJMZW5ndGg7aSsrKXtpZihyZWFkKGFycixpKT09PXJlYWQodmFsLGZvdW5kSW5kZXg9PT0tMT8wOmktZm91bmRJbmRleCkpe2lmKGZvdW5kSW5kZXg9PT0tMSlmb3VuZEluZGV4PWk7aWYoaS1mb3VuZEluZGV4KzE9PT12YWxMZW5ndGgpcmV0dXJuIGZvdW5kSW5kZXgqaW5kZXhTaXplfWVsc2V7aWYoZm91bmRJbmRleCE9PS0xKWktPWktZm91bmRJbmRleDtmb3VuZEluZGV4PS0xfX19ZWxzZXtpZihieXRlT2Zmc2V0K3ZhbExlbmd0aD5hcnJMZW5ndGgpYnl0ZU9mZnNldD1hcnJMZW5ndGgtdmFsTGVuZ3RoO2ZvcihpPWJ5dGVPZmZzZXQ7aT49MDtpLS0pe3ZhciBmb3VuZD10cnVlO2Zvcih2YXIgaj0wO2o8dmFsTGVuZ3RoO2orKyl7aWYocmVhZChhcnIsaStqKSE9PXJlYWQodmFsLGopKXtmb3VuZD1mYWxzZTticmVha319aWYoZm91bmQpcmV0dXJuIGl9fXJldHVybi0xfUJ1ZmZlci5wcm90b3R5cGUuaW5jbHVkZXM9ZnVuY3Rpb24gaW5jbHVkZXModmFsLGJ5dGVPZmZzZXQsZW5jb2Rpbmcpe3JldHVybiB0aGlzLmluZGV4T2YodmFsLGJ5dGVPZmZzZXQsZW5jb2RpbmcpIT09LTF9O0J1ZmZlci5wcm90b3R5cGUuaW5kZXhPZj1mdW5jdGlvbiBpbmRleE9mKHZhbCxieXRlT2Zmc2V0LGVuY29kaW5nKXtyZXR1cm4gYmlkaXJlY3Rpb25hbEluZGV4T2YodGhpcyx2YWwsYnl0ZU9mZnNldCxlbmNvZGluZyx0cnVlKX07QnVmZmVyLnByb3RvdHlwZS5sYXN0SW5kZXhPZj1mdW5jdGlvbiBsYXN0SW5kZXhPZih2YWwsYnl0ZU9mZnNldCxlbmNvZGluZyl7cmV0dXJuIGJpZGlyZWN0aW9uYWxJbmRleE9mKHRoaXMsdmFsLGJ5dGVPZmZzZXQsZW5jb2RpbmcsZmFsc2UpfTtmdW5jdGlvbiBoZXhXcml0ZShidWYsc3RyaW5nLG9mZnNldCxsZW5ndGgpe29mZnNldD1OdW1iZXIob2Zmc2V0KXx8MDt2YXIgcmVtYWluaW5nPWJ1Zi5sZW5ndGgtb2Zmc2V0O2lmKCFsZW5ndGgpe2xlbmd0aD1yZW1haW5pbmd9ZWxzZXtsZW5ndGg9TnVtYmVyKGxlbmd0aCk7aWYobGVuZ3RoPnJlbWFpbmluZyl7bGVuZ3RoPXJlbWFpbmluZ319dmFyIHN0ckxlbj1zdHJpbmcubGVuZ3RoO2lmKHN0ckxlbiUyIT09MCl0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBoZXggc3RyaW5nXCIpO2lmKGxlbmd0aD5zdHJMZW4vMil7bGVuZ3RoPXN0ckxlbi8yfWZvcih2YXIgaT0wO2k8bGVuZ3RoOysraSl7dmFyIHBhcnNlZD1wYXJzZUludChzdHJpbmcuc3Vic3RyKGkqMiwyKSwxNik7aWYoaXNOYU4ocGFyc2VkKSlyZXR1cm4gaTtidWZbb2Zmc2V0K2ldPXBhcnNlZH1yZXR1cm4gaX1mdW5jdGlvbiB1dGY4V3JpdGUoYnVmLHN0cmluZyxvZmZzZXQsbGVuZ3RoKXtyZXR1cm4gYmxpdEJ1ZmZlcih1dGY4VG9CeXRlcyhzdHJpbmcsYnVmLmxlbmd0aC1vZmZzZXQpLGJ1ZixvZmZzZXQsbGVuZ3RoKX1mdW5jdGlvbiBhc2NpaVdyaXRlKGJ1ZixzdHJpbmcsb2Zmc2V0LGxlbmd0aCl7cmV0dXJuIGJsaXRCdWZmZXIoYXNjaWlUb0J5dGVzKHN0cmluZyksYnVmLG9mZnNldCxsZW5ndGgpfWZ1bmN0aW9uIGxhdGluMVdyaXRlKGJ1ZixzdHJpbmcsb2Zmc2V0LGxlbmd0aCl7cmV0dXJuIGFzY2lpV3JpdGUoYnVmLHN0cmluZyxvZmZzZXQsbGVuZ3RoKX1mdW5jdGlvbiBiYXNlNjRXcml0ZShidWYsc3RyaW5nLG9mZnNldCxsZW5ndGgpe3JldHVybiBibGl0QnVmZmVyKGJhc2U2NFRvQnl0ZXMoc3RyaW5nKSxidWYsb2Zmc2V0LGxlbmd0aCl9ZnVuY3Rpb24gdWNzMldyaXRlKGJ1ZixzdHJpbmcsb2Zmc2V0LGxlbmd0aCl7cmV0dXJuIGJsaXRCdWZmZXIodXRmMTZsZVRvQnl0ZXMoc3RyaW5nLGJ1Zi5sZW5ndGgtb2Zmc2V0KSxidWYsb2Zmc2V0LGxlbmd0aCl9QnVmZmVyLnByb3RvdHlwZS53cml0ZT1mdW5jdGlvbiB3cml0ZShzdHJpbmcsb2Zmc2V0LGxlbmd0aCxlbmNvZGluZyl7aWYob2Zmc2V0PT09dW5kZWZpbmVkKXtlbmNvZGluZz1cInV0ZjhcIjtsZW5ndGg9dGhpcy5sZW5ndGg7b2Zmc2V0PTB9ZWxzZSBpZihsZW5ndGg9PT11bmRlZmluZWQmJnR5cGVvZiBvZmZzZXQ9PT1cInN0cmluZ1wiKXtlbmNvZGluZz1vZmZzZXQ7bGVuZ3RoPXRoaXMubGVuZ3RoO29mZnNldD0wfWVsc2UgaWYoaXNGaW5pdGUob2Zmc2V0KSl7b2Zmc2V0PW9mZnNldHwwO2lmKGlzRmluaXRlKGxlbmd0aCkpe2xlbmd0aD1sZW5ndGh8MDtpZihlbmNvZGluZz09PXVuZGVmaW5lZCllbmNvZGluZz1cInV0ZjhcIn1lbHNle2VuY29kaW5nPWxlbmd0aDtsZW5ndGg9dW5kZWZpbmVkfX1lbHNle3Rocm93IG5ldyBFcnJvcihcIkJ1ZmZlci53cml0ZShzdHJpbmcsIGVuY29kaW5nLCBvZmZzZXRbLCBsZW5ndGhdKSBpcyBubyBsb25nZXIgc3VwcG9ydGVkXCIpfXZhciByZW1haW5pbmc9dGhpcy5sZW5ndGgtb2Zmc2V0O2lmKGxlbmd0aD09PXVuZGVmaW5lZHx8bGVuZ3RoPnJlbWFpbmluZylsZW5ndGg9cmVtYWluaW5nO2lmKHN0cmluZy5sZW5ndGg+MCYmKGxlbmd0aDwwfHxvZmZzZXQ8MCl8fG9mZnNldD50aGlzLmxlbmd0aCl7dGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJBdHRlbXB0IHRvIHdyaXRlIG91dHNpZGUgYnVmZmVyIGJvdW5kc1wiKX1pZighZW5jb2RpbmcpZW5jb2Rpbmc9XCJ1dGY4XCI7dmFyIGxvd2VyZWRDYXNlPWZhbHNlO2Zvcig7Oyl7c3dpdGNoKGVuY29kaW5nKXtjYXNlXCJoZXhcIjpyZXR1cm4gaGV4V3JpdGUodGhpcyxzdHJpbmcsb2Zmc2V0LGxlbmd0aCk7Y2FzZVwidXRmOFwiOmNhc2VcInV0Zi04XCI6cmV0dXJuIHV0ZjhXcml0ZSh0aGlzLHN0cmluZyxvZmZzZXQsbGVuZ3RoKTtjYXNlXCJhc2NpaVwiOnJldHVybiBhc2NpaVdyaXRlKHRoaXMsc3RyaW5nLG9mZnNldCxsZW5ndGgpO2Nhc2VcImxhdGluMVwiOmNhc2VcImJpbmFyeVwiOnJldHVybiBsYXRpbjFXcml0ZSh0aGlzLHN0cmluZyxvZmZzZXQsbGVuZ3RoKTtjYXNlXCJiYXNlNjRcIjpyZXR1cm4gYmFzZTY0V3JpdGUodGhpcyxzdHJpbmcsb2Zmc2V0LGxlbmd0aCk7Y2FzZVwidWNzMlwiOmNhc2VcInVjcy0yXCI6Y2FzZVwidXRmMTZsZVwiOmNhc2VcInV0Zi0xNmxlXCI6cmV0dXJuIHVjczJXcml0ZSh0aGlzLHN0cmluZyxvZmZzZXQsbGVuZ3RoKTtkZWZhdWx0OmlmKGxvd2VyZWRDYXNlKXRocm93IG5ldyBUeXBlRXJyb3IoXCJVbmtub3duIGVuY29kaW5nOiBcIitlbmNvZGluZyk7ZW5jb2Rpbmc9KFwiXCIrZW5jb2RpbmcpLnRvTG93ZXJDYXNlKCk7bG93ZXJlZENhc2U9dHJ1ZX19fTtCdWZmZXIucHJvdG90eXBlLnRvSlNPTj1mdW5jdGlvbiB0b0pTT04oKXtyZXR1cm57dHlwZTpcIkJ1ZmZlclwiLGRhdGE6QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwodGhpcy5fYXJyfHx0aGlzLDApfX07ZnVuY3Rpb24gYmFzZTY0U2xpY2UoYnVmLHN0YXJ0LGVuZCl7aWYoc3RhcnQ9PT0wJiZlbmQ9PT1idWYubGVuZ3RoKXtyZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmKX1lbHNle3JldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYuc2xpY2Uoc3RhcnQsZW5kKSl9fWZ1bmN0aW9uIHV0ZjhTbGljZShidWYsc3RhcnQsZW5kKXtlbmQ9TWF0aC5taW4oYnVmLmxlbmd0aCxlbmQpO3ZhciByZXM9W107dmFyIGk9c3RhcnQ7d2hpbGUoaTxlbmQpe3ZhciBmaXJzdEJ5dGU9YnVmW2ldO3ZhciBjb2RlUG9pbnQ9bnVsbDt2YXIgYnl0ZXNQZXJTZXF1ZW5jZT1maXJzdEJ5dGU+MjM5PzQ6Zmlyc3RCeXRlPjIyMz8zOmZpcnN0Qnl0ZT4xOTE/MjoxO2lmKGkrYnl0ZXNQZXJTZXF1ZW5jZTw9ZW5kKXt2YXIgc2Vjb25kQnl0ZSx0aGlyZEJ5dGUsZm91cnRoQnl0ZSx0ZW1wQ29kZVBvaW50O3N3aXRjaChieXRlc1BlclNlcXVlbmNlKXtjYXNlIDE6aWYoZmlyc3RCeXRlPDEyOCl7Y29kZVBvaW50PWZpcnN0Qnl0ZX1icmVhaztjYXNlIDI6c2Vjb25kQnl0ZT1idWZbaSsxXTtpZigoc2Vjb25kQnl0ZSYxOTIpPT09MTI4KXt0ZW1wQ29kZVBvaW50PShmaXJzdEJ5dGUmMzEpPDw2fHNlY29uZEJ5dGUmNjM7aWYodGVtcENvZGVQb2ludD4xMjcpe2NvZGVQb2ludD10ZW1wQ29kZVBvaW50fX1icmVhaztjYXNlIDM6c2Vjb25kQnl0ZT1idWZbaSsxXTt0aGlyZEJ5dGU9YnVmW2krMl07aWYoKHNlY29uZEJ5dGUmMTkyKT09PTEyOCYmKHRoaXJkQnl0ZSYxOTIpPT09MTI4KXt0ZW1wQ29kZVBvaW50PShmaXJzdEJ5dGUmMTUpPDwxMnwoc2Vjb25kQnl0ZSY2Myk8PDZ8dGhpcmRCeXRlJjYzO2lmKHRlbXBDb2RlUG9pbnQ+MjA0NyYmKHRlbXBDb2RlUG9pbnQ8NTUyOTZ8fHRlbXBDb2RlUG9pbnQ+NTczNDMpKXtjb2RlUG9pbnQ9dGVtcENvZGVQb2ludH19YnJlYWs7Y2FzZSA0OnNlY29uZEJ5dGU9YnVmW2krMV07dGhpcmRCeXRlPWJ1ZltpKzJdO2ZvdXJ0aEJ5dGU9YnVmW2krM107aWYoKHNlY29uZEJ5dGUmMTkyKT09PTEyOCYmKHRoaXJkQnl0ZSYxOTIpPT09MTI4JiYoZm91cnRoQnl0ZSYxOTIpPT09MTI4KXt0ZW1wQ29kZVBvaW50PShmaXJzdEJ5dGUmMTUpPDwxOHwoc2Vjb25kQnl0ZSY2Myk8PDEyfCh0aGlyZEJ5dGUmNjMpPDw2fGZvdXJ0aEJ5dGUmNjM7aWYodGVtcENvZGVQb2ludD42NTUzNSYmdGVtcENvZGVQb2ludDwxMTE0MTEyKXtjb2RlUG9pbnQ9dGVtcENvZGVQb2ludH19fX1pZihjb2RlUG9pbnQ9PT1udWxsKXtjb2RlUG9pbnQ9NjU1MzM7Ynl0ZXNQZXJTZXF1ZW5jZT0xfWVsc2UgaWYoY29kZVBvaW50PjY1NTM1KXtjb2RlUG9pbnQtPTY1NTM2O3Jlcy5wdXNoKGNvZGVQb2ludD4+PjEwJjEwMjN8NTUyOTYpO2NvZGVQb2ludD01NjMyMHxjb2RlUG9pbnQmMTAyM31yZXMucHVzaChjb2RlUG9pbnQpO2krPWJ5dGVzUGVyU2VxdWVuY2V9cmV0dXJuIGRlY29kZUNvZGVQb2ludHNBcnJheShyZXMpfXZhciBNQVhfQVJHVU1FTlRTX0xFTkdUSD00MDk2O2Z1bmN0aW9uIGRlY29kZUNvZGVQb2ludHNBcnJheShjb2RlUG9pbnRzKXt2YXIgbGVuPWNvZGVQb2ludHMubGVuZ3RoO2lmKGxlbjw9TUFYX0FSR1VNRU5UU19MRU5HVEgpe3JldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZyxjb2RlUG9pbnRzKX12YXIgcmVzPVwiXCI7dmFyIGk9MDt3aGlsZShpPGxlbil7cmVzKz1TdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZyxjb2RlUG9pbnRzLnNsaWNlKGksaSs9TUFYX0FSR1VNRU5UU19MRU5HVEgpKX1yZXR1cm4gcmVzfWZ1bmN0aW9uIGFzY2lpU2xpY2UoYnVmLHN0YXJ0LGVuZCl7dmFyIHJldD1cIlwiO2VuZD1NYXRoLm1pbihidWYubGVuZ3RoLGVuZCk7Zm9yKHZhciBpPXN0YXJ0O2k8ZW5kOysraSl7cmV0Kz1TdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSYxMjcpfXJldHVybiByZXR9ZnVuY3Rpb24gbGF0aW4xU2xpY2UoYnVmLHN0YXJ0LGVuZCl7dmFyIHJldD1cIlwiO2VuZD1NYXRoLm1pbihidWYubGVuZ3RoLGVuZCk7Zm9yKHZhciBpPXN0YXJ0O2k8ZW5kOysraSl7cmV0Kz1TdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSl9cmV0dXJuIHJldH1mdW5jdGlvbiBoZXhTbGljZShidWYsc3RhcnQsZW5kKXt2YXIgbGVuPWJ1Zi5sZW5ndGg7aWYoIXN0YXJ0fHxzdGFydDwwKXN0YXJ0PTA7aWYoIWVuZHx8ZW5kPDB8fGVuZD5sZW4pZW5kPWxlbjt2YXIgb3V0PVwiXCI7Zm9yKHZhciBpPXN0YXJ0O2k8ZW5kOysraSl7b3V0Kz10b0hleChidWZbaV0pfXJldHVybiBvdXR9ZnVuY3Rpb24gdXRmMTZsZVNsaWNlKGJ1ZixzdGFydCxlbmQpe3ZhciBieXRlcz1idWYuc2xpY2Uoc3RhcnQsZW5kKTt2YXIgcmVzPVwiXCI7Zm9yKHZhciBpPTA7aTxieXRlcy5sZW5ndGg7aSs9Mil7cmVzKz1TdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGVzW2ldK2J5dGVzW2krMV0qMjU2KX1yZXR1cm4gcmVzfUJ1ZmZlci5wcm90b3R5cGUuc2xpY2U9ZnVuY3Rpb24gc2xpY2Uoc3RhcnQsZW5kKXt2YXIgbGVuPXRoaXMubGVuZ3RoO3N0YXJ0PX5+c3RhcnQ7ZW5kPWVuZD09PXVuZGVmaW5lZD9sZW46fn5lbmQ7aWYoc3RhcnQ8MCl7c3RhcnQrPWxlbjtpZihzdGFydDwwKXN0YXJ0PTB9ZWxzZSBpZihzdGFydD5sZW4pe3N0YXJ0PWxlbn1pZihlbmQ8MCl7ZW5kKz1sZW47aWYoZW5kPDApZW5kPTB9ZWxzZSBpZihlbmQ+bGVuKXtlbmQ9bGVufWlmKGVuZDxzdGFydCllbmQ9c3RhcnQ7dmFyIG5ld0J1ZjtpZihCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCl7bmV3QnVmPXRoaXMuc3ViYXJyYXkoc3RhcnQsZW5kKTtuZXdCdWYuX19wcm90b19fPUJ1ZmZlci5wcm90b3R5cGV9ZWxzZXt2YXIgc2xpY2VMZW49ZW5kLXN0YXJ0O25ld0J1Zj1uZXcgQnVmZmVyKHNsaWNlTGVuLHVuZGVmaW5lZCk7Zm9yKHZhciBpPTA7aTxzbGljZUxlbjsrK2kpe25ld0J1ZltpXT10aGlzW2krc3RhcnRdfX1yZXR1cm4gbmV3QnVmfTtmdW5jdGlvbiBjaGVja09mZnNldChvZmZzZXQsZXh0LGxlbmd0aCl7aWYob2Zmc2V0JTEhPT0wfHxvZmZzZXQ8MCl0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIm9mZnNldCBpcyBub3QgdWludFwiKTtpZihvZmZzZXQrZXh0Pmxlbmd0aCl0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIlRyeWluZyB0byBhY2Nlc3MgYmV5b25kIGJ1ZmZlciBsZW5ndGhcIil9QnVmZmVyLnByb3RvdHlwZS5yZWFkVUludExFPWZ1bmN0aW9uIHJlYWRVSW50TEUob2Zmc2V0LGJ5dGVMZW5ndGgsbm9Bc3NlcnQpe29mZnNldD1vZmZzZXR8MDtieXRlTGVuZ3RoPWJ5dGVMZW5ndGh8MDtpZighbm9Bc3NlcnQpY2hlY2tPZmZzZXQob2Zmc2V0LGJ5dGVMZW5ndGgsdGhpcy5sZW5ndGgpO3ZhciB2YWw9dGhpc1tvZmZzZXRdO3ZhciBtdWw9MTt2YXIgaT0wO3doaWxlKCsraTxieXRlTGVuZ3RoJiYobXVsKj0yNTYpKXt2YWwrPXRoaXNbb2Zmc2V0K2ldKm11bH1yZXR1cm4gdmFsfTtCdWZmZXIucHJvdG90eXBlLnJlYWRVSW50QkU9ZnVuY3Rpb24gcmVhZFVJbnRCRShvZmZzZXQsYnl0ZUxlbmd0aCxub0Fzc2VydCl7b2Zmc2V0PW9mZnNldHwwO2J5dGVMZW5ndGg9Ynl0ZUxlbmd0aHwwO2lmKCFub0Fzc2VydCl7Y2hlY2tPZmZzZXQob2Zmc2V0LGJ5dGVMZW5ndGgsdGhpcy5sZW5ndGgpfXZhciB2YWw9dGhpc1tvZmZzZXQrLS1ieXRlTGVuZ3RoXTt2YXIgbXVsPTE7d2hpbGUoYnl0ZUxlbmd0aD4wJiYobXVsKj0yNTYpKXt2YWwrPXRoaXNbb2Zmc2V0Ky0tYnl0ZUxlbmd0aF0qbXVsfXJldHVybiB2YWx9O0J1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQ4PWZ1bmN0aW9uIHJlYWRVSW50OChvZmZzZXQsbm9Bc3NlcnQpe2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsMSx0aGlzLmxlbmd0aCk7cmV0dXJuIHRoaXNbb2Zmc2V0XX07QnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2TEU9ZnVuY3Rpb24gcmVhZFVJbnQxNkxFKG9mZnNldCxub0Fzc2VydCl7aWYoIW5vQXNzZXJ0KWNoZWNrT2Zmc2V0KG9mZnNldCwyLHRoaXMubGVuZ3RoKTtyZXR1cm4gdGhpc1tvZmZzZXRdfHRoaXNbb2Zmc2V0KzFdPDw4fTtCdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZCRT1mdW5jdGlvbiByZWFkVUludDE2QkUob2Zmc2V0LG5vQXNzZXJ0KXtpZighbm9Bc3NlcnQpY2hlY2tPZmZzZXQob2Zmc2V0LDIsdGhpcy5sZW5ndGgpO3JldHVybiB0aGlzW29mZnNldF08PDh8dGhpc1tvZmZzZXQrMV19O0J1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkxFPWZ1bmN0aW9uIHJlYWRVSW50MzJMRShvZmZzZXQsbm9Bc3NlcnQpe2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsNCx0aGlzLmxlbmd0aCk7cmV0dXJuKHRoaXNbb2Zmc2V0XXx0aGlzW29mZnNldCsxXTw8OHx0aGlzW29mZnNldCsyXTw8MTYpK3RoaXNbb2Zmc2V0KzNdKjE2Nzc3MjE2fTtCdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJCRT1mdW5jdGlvbiByZWFkVUludDMyQkUob2Zmc2V0LG5vQXNzZXJ0KXtpZighbm9Bc3NlcnQpY2hlY2tPZmZzZXQob2Zmc2V0LDQsdGhpcy5sZW5ndGgpO3JldHVybiB0aGlzW29mZnNldF0qMTY3NzcyMTYrKHRoaXNbb2Zmc2V0KzFdPDwxNnx0aGlzW29mZnNldCsyXTw8OHx0aGlzW29mZnNldCszXSl9O0J1ZmZlci5wcm90b3R5cGUucmVhZEludExFPWZ1bmN0aW9uIHJlYWRJbnRMRShvZmZzZXQsYnl0ZUxlbmd0aCxub0Fzc2VydCl7b2Zmc2V0PW9mZnNldHwwO2J5dGVMZW5ndGg9Ynl0ZUxlbmd0aHwwO2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsYnl0ZUxlbmd0aCx0aGlzLmxlbmd0aCk7dmFyIHZhbD10aGlzW29mZnNldF07dmFyIG11bD0xO3ZhciBpPTA7d2hpbGUoKytpPGJ5dGVMZW5ndGgmJihtdWwqPTI1Nikpe3ZhbCs9dGhpc1tvZmZzZXQraV0qbXVsfW11bCo9MTI4O2lmKHZhbD49bXVsKXZhbC09TWF0aC5wb3coMiw4KmJ5dGVMZW5ndGgpO3JldHVybiB2YWx9O0J1ZmZlci5wcm90b3R5cGUucmVhZEludEJFPWZ1bmN0aW9uIHJlYWRJbnRCRShvZmZzZXQsYnl0ZUxlbmd0aCxub0Fzc2VydCl7b2Zmc2V0PW9mZnNldHwwO2J5dGVMZW5ndGg9Ynl0ZUxlbmd0aHwwO2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsYnl0ZUxlbmd0aCx0aGlzLmxlbmd0aCk7XG52YXIgaT1ieXRlTGVuZ3RoO3ZhciBtdWw9MTt2YXIgdmFsPXRoaXNbb2Zmc2V0Ky0taV07d2hpbGUoaT4wJiYobXVsKj0yNTYpKXt2YWwrPXRoaXNbb2Zmc2V0Ky0taV0qbXVsfW11bCo9MTI4O2lmKHZhbD49bXVsKXZhbC09TWF0aC5wb3coMiw4KmJ5dGVMZW5ndGgpO3JldHVybiB2YWx9O0J1ZmZlci5wcm90b3R5cGUucmVhZEludDg9ZnVuY3Rpb24gcmVhZEludDgob2Zmc2V0LG5vQXNzZXJ0KXtpZighbm9Bc3NlcnQpY2hlY2tPZmZzZXQob2Zmc2V0LDEsdGhpcy5sZW5ndGgpO2lmKCEodGhpc1tvZmZzZXRdJjEyOCkpcmV0dXJuIHRoaXNbb2Zmc2V0XTtyZXR1cm4oMjU1LXRoaXNbb2Zmc2V0XSsxKSotMX07QnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZMRT1mdW5jdGlvbiByZWFkSW50MTZMRShvZmZzZXQsbm9Bc3NlcnQpe2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsMix0aGlzLmxlbmd0aCk7dmFyIHZhbD10aGlzW29mZnNldF18dGhpc1tvZmZzZXQrMV08PDg7cmV0dXJuIHZhbCYzMjc2OD92YWx8NDI5NDkwMTc2MDp2YWx9O0J1ZmZlci5wcm90b3R5cGUucmVhZEludDE2QkU9ZnVuY3Rpb24gcmVhZEludDE2QkUob2Zmc2V0LG5vQXNzZXJ0KXtpZighbm9Bc3NlcnQpY2hlY2tPZmZzZXQob2Zmc2V0LDIsdGhpcy5sZW5ndGgpO3ZhciB2YWw9dGhpc1tvZmZzZXQrMV18dGhpc1tvZmZzZXRdPDw4O3JldHVybiB2YWwmMzI3Njg/dmFsfDQyOTQ5MDE3NjA6dmFsfTtCdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkxFPWZ1bmN0aW9uIHJlYWRJbnQzMkxFKG9mZnNldCxub0Fzc2VydCl7aWYoIW5vQXNzZXJ0KWNoZWNrT2Zmc2V0KG9mZnNldCw0LHRoaXMubGVuZ3RoKTtyZXR1cm4gdGhpc1tvZmZzZXRdfHRoaXNbb2Zmc2V0KzFdPDw4fHRoaXNbb2Zmc2V0KzJdPDwxNnx0aGlzW29mZnNldCszXTw8MjR9O0J1ZmZlci5wcm90b3R5cGUucmVhZEludDMyQkU9ZnVuY3Rpb24gcmVhZEludDMyQkUob2Zmc2V0LG5vQXNzZXJ0KXtpZighbm9Bc3NlcnQpY2hlY2tPZmZzZXQob2Zmc2V0LDQsdGhpcy5sZW5ndGgpO3JldHVybiB0aGlzW29mZnNldF08PDI0fHRoaXNbb2Zmc2V0KzFdPDwxNnx0aGlzW29mZnNldCsyXTw8OHx0aGlzW29mZnNldCszXX07QnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRMRT1mdW5jdGlvbiByZWFkRmxvYXRMRShvZmZzZXQsbm9Bc3NlcnQpe2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsNCx0aGlzLmxlbmd0aCk7cmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLG9mZnNldCx0cnVlLDIzLDQpfTtCdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdEJFPWZ1bmN0aW9uIHJlYWRGbG9hdEJFKG9mZnNldCxub0Fzc2VydCl7aWYoIW5vQXNzZXJ0KWNoZWNrT2Zmc2V0KG9mZnNldCw0LHRoaXMubGVuZ3RoKTtyZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsb2Zmc2V0LGZhbHNlLDIzLDQpfTtCdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVMRT1mdW5jdGlvbiByZWFkRG91YmxlTEUob2Zmc2V0LG5vQXNzZXJ0KXtpZighbm9Bc3NlcnQpY2hlY2tPZmZzZXQob2Zmc2V0LDgsdGhpcy5sZW5ndGgpO3JldHVybiBpZWVlNzU0LnJlYWQodGhpcyxvZmZzZXQsdHJ1ZSw1Miw4KX07QnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlQkU9ZnVuY3Rpb24gcmVhZERvdWJsZUJFKG9mZnNldCxub0Fzc2VydCl7aWYoIW5vQXNzZXJ0KWNoZWNrT2Zmc2V0KG9mZnNldCw4LHRoaXMubGVuZ3RoKTtyZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsb2Zmc2V0LGZhbHNlLDUyLDgpfTtmdW5jdGlvbiBjaGVja0ludChidWYsdmFsdWUsb2Zmc2V0LGV4dCxtYXgsbWluKXtpZighQnVmZmVyLmlzQnVmZmVyKGJ1ZikpdGhyb3cgbmV3IFR5cGVFcnJvcignXCJidWZmZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyIGluc3RhbmNlJyk7aWYodmFsdWU+bWF4fHx2YWx1ZTxtaW4pdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1widmFsdWVcIiBhcmd1bWVudCBpcyBvdXQgb2YgYm91bmRzJyk7aWYob2Zmc2V0K2V4dD5idWYubGVuZ3RoKXRocm93IG5ldyBSYW5nZUVycm9yKFwiSW5kZXggb3V0IG9mIHJhbmdlXCIpfUJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50TEU9ZnVuY3Rpb24gd3JpdGVVSW50TEUodmFsdWUsb2Zmc2V0LGJ5dGVMZW5ndGgsbm9Bc3NlcnQpe3ZhbHVlPSt2YWx1ZTtvZmZzZXQ9b2Zmc2V0fDA7Ynl0ZUxlbmd0aD1ieXRlTGVuZ3RofDA7aWYoIW5vQXNzZXJ0KXt2YXIgbWF4Qnl0ZXM9TWF0aC5wb3coMiw4KmJ5dGVMZW5ndGgpLTE7Y2hlY2tJbnQodGhpcyx2YWx1ZSxvZmZzZXQsYnl0ZUxlbmd0aCxtYXhCeXRlcywwKX12YXIgbXVsPTE7dmFyIGk9MDt0aGlzW29mZnNldF09dmFsdWUmMjU1O3doaWxlKCsraTxieXRlTGVuZ3RoJiYobXVsKj0yNTYpKXt0aGlzW29mZnNldCtpXT12YWx1ZS9tdWwmMjU1fXJldHVybiBvZmZzZXQrYnl0ZUxlbmd0aH07QnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRCRT1mdW5jdGlvbiB3cml0ZVVJbnRCRSh2YWx1ZSxvZmZzZXQsYnl0ZUxlbmd0aCxub0Fzc2VydCl7dmFsdWU9K3ZhbHVlO29mZnNldD1vZmZzZXR8MDtieXRlTGVuZ3RoPWJ5dGVMZW5ndGh8MDtpZighbm9Bc3NlcnQpe3ZhciBtYXhCeXRlcz1NYXRoLnBvdygyLDgqYnl0ZUxlbmd0aCktMTtjaGVja0ludCh0aGlzLHZhbHVlLG9mZnNldCxieXRlTGVuZ3RoLG1heEJ5dGVzLDApfXZhciBpPWJ5dGVMZW5ndGgtMTt2YXIgbXVsPTE7dGhpc1tvZmZzZXQraV09dmFsdWUmMjU1O3doaWxlKC0taT49MCYmKG11bCo9MjU2KSl7dGhpc1tvZmZzZXQraV09dmFsdWUvbXVsJjI1NX1yZXR1cm4gb2Zmc2V0K2J5dGVMZW5ndGh9O0J1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50OD1mdW5jdGlvbiB3cml0ZVVJbnQ4KHZhbHVlLG9mZnNldCxub0Fzc2VydCl7dmFsdWU9K3ZhbHVlO29mZnNldD1vZmZzZXR8MDtpZighbm9Bc3NlcnQpY2hlY2tJbnQodGhpcyx2YWx1ZSxvZmZzZXQsMSwyNTUsMCk7aWYoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKXZhbHVlPU1hdGguZmxvb3IodmFsdWUpO3RoaXNbb2Zmc2V0XT12YWx1ZSYyNTU7cmV0dXJuIG9mZnNldCsxfTtmdW5jdGlvbiBvYmplY3RXcml0ZVVJbnQxNihidWYsdmFsdWUsb2Zmc2V0LGxpdHRsZUVuZGlhbil7aWYodmFsdWU8MCl2YWx1ZT02NTUzNSt2YWx1ZSsxO2Zvcih2YXIgaT0wLGo9TWF0aC5taW4oYnVmLmxlbmd0aC1vZmZzZXQsMik7aTxqOysraSl7YnVmW29mZnNldCtpXT0odmFsdWUmMjU1PDw4KihsaXR0bGVFbmRpYW4/aToxLWkpKT4+PihsaXR0bGVFbmRpYW4/aToxLWkpKjh9fUJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZMRT1mdW5jdGlvbiB3cml0ZVVJbnQxNkxFKHZhbHVlLG9mZnNldCxub0Fzc2VydCl7dmFsdWU9K3ZhbHVlO29mZnNldD1vZmZzZXR8MDtpZighbm9Bc3NlcnQpY2hlY2tJbnQodGhpcyx2YWx1ZSxvZmZzZXQsMiw2NTUzNSwwKTtpZihCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCl7dGhpc1tvZmZzZXRdPXZhbHVlJjI1NTt0aGlzW29mZnNldCsxXT12YWx1ZT4+Pjh9ZWxzZXtvYmplY3RXcml0ZVVJbnQxNih0aGlzLHZhbHVlLG9mZnNldCx0cnVlKX1yZXR1cm4gb2Zmc2V0KzJ9O0J1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZCRT1mdW5jdGlvbiB3cml0ZVVJbnQxNkJFKHZhbHVlLG9mZnNldCxub0Fzc2VydCl7dmFsdWU9K3ZhbHVlO29mZnNldD1vZmZzZXR8MDtpZighbm9Bc3NlcnQpY2hlY2tJbnQodGhpcyx2YWx1ZSxvZmZzZXQsMiw2NTUzNSwwKTtpZihCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCl7dGhpc1tvZmZzZXRdPXZhbHVlPj4+ODt0aGlzW29mZnNldCsxXT12YWx1ZSYyNTV9ZWxzZXtvYmplY3RXcml0ZVVJbnQxNih0aGlzLHZhbHVlLG9mZnNldCxmYWxzZSl9cmV0dXJuIG9mZnNldCsyfTtmdW5jdGlvbiBvYmplY3RXcml0ZVVJbnQzMihidWYsdmFsdWUsb2Zmc2V0LGxpdHRsZUVuZGlhbil7aWYodmFsdWU8MCl2YWx1ZT00Mjk0OTY3Mjk1K3ZhbHVlKzE7Zm9yKHZhciBpPTAsaj1NYXRoLm1pbihidWYubGVuZ3RoLW9mZnNldCw0KTtpPGo7KytpKXtidWZbb2Zmc2V0K2ldPXZhbHVlPj4+KGxpdHRsZUVuZGlhbj9pOjMtaSkqOCYyNTV9fUJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJMRT1mdW5jdGlvbiB3cml0ZVVJbnQzMkxFKHZhbHVlLG9mZnNldCxub0Fzc2VydCl7dmFsdWU9K3ZhbHVlO29mZnNldD1vZmZzZXR8MDtpZighbm9Bc3NlcnQpY2hlY2tJbnQodGhpcyx2YWx1ZSxvZmZzZXQsNCw0Mjk0OTY3Mjk1LDApO2lmKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKXt0aGlzW29mZnNldCszXT12YWx1ZT4+PjI0O3RoaXNbb2Zmc2V0KzJdPXZhbHVlPj4+MTY7dGhpc1tvZmZzZXQrMV09dmFsdWU+Pj44O3RoaXNbb2Zmc2V0XT12YWx1ZSYyNTV9ZWxzZXtvYmplY3RXcml0ZVVJbnQzMih0aGlzLHZhbHVlLG9mZnNldCx0cnVlKX1yZXR1cm4gb2Zmc2V0KzR9O0J1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJCRT1mdW5jdGlvbiB3cml0ZVVJbnQzMkJFKHZhbHVlLG9mZnNldCxub0Fzc2VydCl7dmFsdWU9K3ZhbHVlO29mZnNldD1vZmZzZXR8MDtpZighbm9Bc3NlcnQpY2hlY2tJbnQodGhpcyx2YWx1ZSxvZmZzZXQsNCw0Mjk0OTY3Mjk1LDApO2lmKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKXt0aGlzW29mZnNldF09dmFsdWU+Pj4yNDt0aGlzW29mZnNldCsxXT12YWx1ZT4+PjE2O3RoaXNbb2Zmc2V0KzJdPXZhbHVlPj4+ODt0aGlzW29mZnNldCszXT12YWx1ZSYyNTV9ZWxzZXtvYmplY3RXcml0ZVVJbnQzMih0aGlzLHZhbHVlLG9mZnNldCxmYWxzZSl9cmV0dXJuIG9mZnNldCs0fTtCdWZmZXIucHJvdG90eXBlLndyaXRlSW50TEU9ZnVuY3Rpb24gd3JpdGVJbnRMRSh2YWx1ZSxvZmZzZXQsYnl0ZUxlbmd0aCxub0Fzc2VydCl7dmFsdWU9K3ZhbHVlO29mZnNldD1vZmZzZXR8MDtpZighbm9Bc3NlcnQpe3ZhciBsaW1pdD1NYXRoLnBvdygyLDgqYnl0ZUxlbmd0aC0xKTtjaGVja0ludCh0aGlzLHZhbHVlLG9mZnNldCxieXRlTGVuZ3RoLGxpbWl0LTEsLWxpbWl0KX12YXIgaT0wO3ZhciBtdWw9MTt2YXIgc3ViPTA7dGhpc1tvZmZzZXRdPXZhbHVlJjI1NTt3aGlsZSgrK2k8Ynl0ZUxlbmd0aCYmKG11bCo9MjU2KSl7aWYodmFsdWU8MCYmc3ViPT09MCYmdGhpc1tvZmZzZXQraS0xXSE9PTApe3N1Yj0xfXRoaXNbb2Zmc2V0K2ldPSh2YWx1ZS9tdWw+PjApLXN1YiYyNTV9cmV0dXJuIG9mZnNldCtieXRlTGVuZ3RofTtCdWZmZXIucHJvdG90eXBlLndyaXRlSW50QkU9ZnVuY3Rpb24gd3JpdGVJbnRCRSh2YWx1ZSxvZmZzZXQsYnl0ZUxlbmd0aCxub0Fzc2VydCl7dmFsdWU9K3ZhbHVlO29mZnNldD1vZmZzZXR8MDtpZighbm9Bc3NlcnQpe3ZhciBsaW1pdD1NYXRoLnBvdygyLDgqYnl0ZUxlbmd0aC0xKTtjaGVja0ludCh0aGlzLHZhbHVlLG9mZnNldCxieXRlTGVuZ3RoLGxpbWl0LTEsLWxpbWl0KX12YXIgaT1ieXRlTGVuZ3RoLTE7dmFyIG11bD0xO3ZhciBzdWI9MDt0aGlzW29mZnNldCtpXT12YWx1ZSYyNTU7d2hpbGUoLS1pPj0wJiYobXVsKj0yNTYpKXtpZih2YWx1ZTwwJiZzdWI9PT0wJiZ0aGlzW29mZnNldCtpKzFdIT09MCl7c3ViPTF9dGhpc1tvZmZzZXQraV09KHZhbHVlL211bD4+MCktc3ViJjI1NX1yZXR1cm4gb2Zmc2V0K2J5dGVMZW5ndGh9O0J1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQ4PWZ1bmN0aW9uIHdyaXRlSW50OCh2YWx1ZSxvZmZzZXQsbm9Bc3NlcnQpe3ZhbHVlPSt2YWx1ZTtvZmZzZXQ9b2Zmc2V0fDA7aWYoIW5vQXNzZXJ0KWNoZWNrSW50KHRoaXMsdmFsdWUsb2Zmc2V0LDEsMTI3LC0xMjgpO2lmKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCl2YWx1ZT1NYXRoLmZsb29yKHZhbHVlKTtpZih2YWx1ZTwwKXZhbHVlPTI1NSt2YWx1ZSsxO3RoaXNbb2Zmc2V0XT12YWx1ZSYyNTU7cmV0dXJuIG9mZnNldCsxfTtCdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZMRT1mdW5jdGlvbiB3cml0ZUludDE2TEUodmFsdWUsb2Zmc2V0LG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2lmKCFub0Fzc2VydCljaGVja0ludCh0aGlzLHZhbHVlLG9mZnNldCwyLDMyNzY3LC0zMjc2OCk7aWYoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpe3RoaXNbb2Zmc2V0XT12YWx1ZSYyNTU7dGhpc1tvZmZzZXQrMV09dmFsdWU+Pj44fWVsc2V7b2JqZWN0V3JpdGVVSW50MTYodGhpcyx2YWx1ZSxvZmZzZXQsdHJ1ZSl9cmV0dXJuIG9mZnNldCsyfTtCdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZCRT1mdW5jdGlvbiB3cml0ZUludDE2QkUodmFsdWUsb2Zmc2V0LG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2lmKCFub0Fzc2VydCljaGVja0ludCh0aGlzLHZhbHVlLG9mZnNldCwyLDMyNzY3LC0zMjc2OCk7aWYoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpe3RoaXNbb2Zmc2V0XT12YWx1ZT4+Pjg7dGhpc1tvZmZzZXQrMV09dmFsdWUmMjU1fWVsc2V7b2JqZWN0V3JpdGVVSW50MTYodGhpcyx2YWx1ZSxvZmZzZXQsZmFsc2UpfXJldHVybiBvZmZzZXQrMn07QnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyTEU9ZnVuY3Rpb24gd3JpdGVJbnQzMkxFKHZhbHVlLG9mZnNldCxub0Fzc2VydCl7dmFsdWU9K3ZhbHVlO29mZnNldD1vZmZzZXR8MDtpZighbm9Bc3NlcnQpY2hlY2tJbnQodGhpcyx2YWx1ZSxvZmZzZXQsNCwyMTQ3NDgzNjQ3LC0yMTQ3NDgzNjQ4KTtpZihCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCl7dGhpc1tvZmZzZXRdPXZhbHVlJjI1NTt0aGlzW29mZnNldCsxXT12YWx1ZT4+Pjg7dGhpc1tvZmZzZXQrMl09dmFsdWU+Pj4xNjt0aGlzW29mZnNldCszXT12YWx1ZT4+PjI0fWVsc2V7b2JqZWN0V3JpdGVVSW50MzIodGhpcyx2YWx1ZSxvZmZzZXQsdHJ1ZSl9cmV0dXJuIG9mZnNldCs0fTtCdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJCRT1mdW5jdGlvbiB3cml0ZUludDMyQkUodmFsdWUsb2Zmc2V0LG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2lmKCFub0Fzc2VydCljaGVja0ludCh0aGlzLHZhbHVlLG9mZnNldCw0LDIxNDc0ODM2NDcsLTIxNDc0ODM2NDgpO2lmKHZhbHVlPDApdmFsdWU9NDI5NDk2NzI5NSt2YWx1ZSsxO2lmKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKXt0aGlzW29mZnNldF09dmFsdWU+Pj4yNDt0aGlzW29mZnNldCsxXT12YWx1ZT4+PjE2O3RoaXNbb2Zmc2V0KzJdPXZhbHVlPj4+ODt0aGlzW29mZnNldCszXT12YWx1ZSYyNTV9ZWxzZXtvYmplY3RXcml0ZVVJbnQzMih0aGlzLHZhbHVlLG9mZnNldCxmYWxzZSl9cmV0dXJuIG9mZnNldCs0fTtmdW5jdGlvbiBjaGVja0lFRUU3NTQoYnVmLHZhbHVlLG9mZnNldCxleHQsbWF4LG1pbil7aWYob2Zmc2V0K2V4dD5idWYubGVuZ3RoKXRocm93IG5ldyBSYW5nZUVycm9yKFwiSW5kZXggb3V0IG9mIHJhbmdlXCIpO2lmKG9mZnNldDwwKXRocm93IG5ldyBSYW5nZUVycm9yKFwiSW5kZXggb3V0IG9mIHJhbmdlXCIpfWZ1bmN0aW9uIHdyaXRlRmxvYXQoYnVmLHZhbHVlLG9mZnNldCxsaXR0bGVFbmRpYW4sbm9Bc3NlcnQpe2lmKCFub0Fzc2VydCl7Y2hlY2tJRUVFNzU0KGJ1Zix2YWx1ZSxvZmZzZXQsNCwzLjQwMjgyMzQ2NjM4NTI4ODZlMzgsLTMuNDAyODIzNDY2Mzg1Mjg4NmUzOCl9aWVlZTc1NC53cml0ZShidWYsdmFsdWUsb2Zmc2V0LGxpdHRsZUVuZGlhbiwyMyw0KTtyZXR1cm4gb2Zmc2V0KzR9QnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0TEU9ZnVuY3Rpb24gd3JpdGVGbG9hdExFKHZhbHVlLG9mZnNldCxub0Fzc2VydCl7cmV0dXJuIHdyaXRlRmxvYXQodGhpcyx2YWx1ZSxvZmZzZXQsdHJ1ZSxub0Fzc2VydCl9O0J1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdEJFPWZ1bmN0aW9uIHdyaXRlRmxvYXRCRSh2YWx1ZSxvZmZzZXQsbm9Bc3NlcnQpe3JldHVybiB3cml0ZUZsb2F0KHRoaXMsdmFsdWUsb2Zmc2V0LGZhbHNlLG5vQXNzZXJ0KX07ZnVuY3Rpb24gd3JpdGVEb3VibGUoYnVmLHZhbHVlLG9mZnNldCxsaXR0bGVFbmRpYW4sbm9Bc3NlcnQpe2lmKCFub0Fzc2VydCl7Y2hlY2tJRUVFNzU0KGJ1Zix2YWx1ZSxvZmZzZXQsOCwxLjc5NzY5MzEzNDg2MjMxNTdlMzA4LC0xLjc5NzY5MzEzNDg2MjMxNTdlMzA4KX1pZWVlNzU0LndyaXRlKGJ1Zix2YWx1ZSxvZmZzZXQsbGl0dGxlRW5kaWFuLDUyLDgpO3JldHVybiBvZmZzZXQrOH1CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlTEU9ZnVuY3Rpb24gd3JpdGVEb3VibGVMRSh2YWx1ZSxvZmZzZXQsbm9Bc3NlcnQpe3JldHVybiB3cml0ZURvdWJsZSh0aGlzLHZhbHVlLG9mZnNldCx0cnVlLG5vQXNzZXJ0KX07QnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUJFPWZ1bmN0aW9uIHdyaXRlRG91YmxlQkUodmFsdWUsb2Zmc2V0LG5vQXNzZXJ0KXtyZXR1cm4gd3JpdGVEb3VibGUodGhpcyx2YWx1ZSxvZmZzZXQsZmFsc2Usbm9Bc3NlcnQpfTtCdWZmZXIucHJvdG90eXBlLmNvcHk9ZnVuY3Rpb24gY29weSh0YXJnZXQsdGFyZ2V0U3RhcnQsc3RhcnQsZW5kKXtpZighc3RhcnQpc3RhcnQ9MDtpZighZW5kJiZlbmQhPT0wKWVuZD10aGlzLmxlbmd0aDtpZih0YXJnZXRTdGFydD49dGFyZ2V0Lmxlbmd0aCl0YXJnZXRTdGFydD10YXJnZXQubGVuZ3RoO2lmKCF0YXJnZXRTdGFydCl0YXJnZXRTdGFydD0wO2lmKGVuZD4wJiZlbmQ8c3RhcnQpZW5kPXN0YXJ0O2lmKGVuZD09PXN0YXJ0KXJldHVybiAwO2lmKHRhcmdldC5sZW5ndGg9PT0wfHx0aGlzLmxlbmd0aD09PTApcmV0dXJuIDA7aWYodGFyZ2V0U3RhcnQ8MCl7dGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJ0YXJnZXRTdGFydCBvdXQgb2YgYm91bmRzXCIpfWlmKHN0YXJ0PDB8fHN0YXJ0Pj10aGlzLmxlbmd0aCl0aHJvdyBuZXcgUmFuZ2VFcnJvcihcInNvdXJjZVN0YXJ0IG91dCBvZiBib3VuZHNcIik7aWYoZW5kPDApdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJzb3VyY2VFbmQgb3V0IG9mIGJvdW5kc1wiKTtpZihlbmQ+dGhpcy5sZW5ndGgpZW5kPXRoaXMubGVuZ3RoO2lmKHRhcmdldC5sZW5ndGgtdGFyZ2V0U3RhcnQ8ZW5kLXN0YXJ0KXtlbmQ9dGFyZ2V0Lmxlbmd0aC10YXJnZXRTdGFydCtzdGFydH12YXIgbGVuPWVuZC1zdGFydDt2YXIgaTtpZih0aGlzPT09dGFyZ2V0JiZzdGFydDx0YXJnZXRTdGFydCYmdGFyZ2V0U3RhcnQ8ZW5kKXtmb3IoaT1sZW4tMTtpPj0wOy0taSl7dGFyZ2V0W2krdGFyZ2V0U3RhcnRdPXRoaXNbaStzdGFydF19fWVsc2UgaWYobGVuPDFlM3x8IUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKXtmb3IoaT0wO2k8bGVuOysraSl7dGFyZ2V0W2krdGFyZ2V0U3RhcnRdPXRoaXNbaStzdGFydF19fWVsc2V7VWludDhBcnJheS5wcm90b3R5cGUuc2V0LmNhbGwodGFyZ2V0LHRoaXMuc3ViYXJyYXkoc3RhcnQsc3RhcnQrbGVuKSx0YXJnZXRTdGFydCl9cmV0dXJuIGxlbn07QnVmZmVyLnByb3RvdHlwZS5maWxsPWZ1bmN0aW9uIGZpbGwodmFsLHN0YXJ0LGVuZCxlbmNvZGluZyl7aWYodHlwZW9mIHZhbD09PVwic3RyaW5nXCIpe2lmKHR5cGVvZiBzdGFydD09PVwic3RyaW5nXCIpe2VuY29kaW5nPXN0YXJ0O3N0YXJ0PTA7ZW5kPXRoaXMubGVuZ3RofWVsc2UgaWYodHlwZW9mIGVuZD09PVwic3RyaW5nXCIpe2VuY29kaW5nPWVuZDtlbmQ9dGhpcy5sZW5ndGh9aWYodmFsLmxlbmd0aD09PTEpe3ZhciBjb2RlPXZhbC5jaGFyQ29kZUF0KDApO2lmKGNvZGU8MjU2KXt2YWw9Y29kZX19aWYoZW5jb2RpbmchPT11bmRlZmluZWQmJnR5cGVvZiBlbmNvZGluZyE9PVwic3RyaW5nXCIpe3Rocm93IG5ldyBUeXBlRXJyb3IoXCJlbmNvZGluZyBtdXN0IGJlIGEgc3RyaW5nXCIpfWlmKHR5cGVvZiBlbmNvZGluZz09PVwic3RyaW5nXCImJiFCdWZmZXIuaXNFbmNvZGluZyhlbmNvZGluZykpe3Rocm93IG5ldyBUeXBlRXJyb3IoXCJVbmtub3duIGVuY29kaW5nOiBcIitlbmNvZGluZyl9fWVsc2UgaWYodHlwZW9mIHZhbD09PVwibnVtYmVyXCIpe3ZhbD12YWwmMjU1fWlmKHN0YXJ0PDB8fHRoaXMubGVuZ3RoPHN0YXJ0fHx0aGlzLmxlbmd0aDxlbmQpe3Rocm93IG5ldyBSYW5nZUVycm9yKFwiT3V0IG9mIHJhbmdlIGluZGV4XCIpfWlmKGVuZDw9c3RhcnQpe3JldHVybiB0aGlzfXN0YXJ0PXN0YXJ0Pj4+MDtlbmQ9ZW5kPT09dW5kZWZpbmVkP3RoaXMubGVuZ3RoOmVuZD4+PjA7aWYoIXZhbCl2YWw9MDt2YXIgaTtpZih0eXBlb2YgdmFsPT09XCJudW1iZXJcIil7Zm9yKGk9c3RhcnQ7aTxlbmQ7KytpKXt0aGlzW2ldPXZhbH19ZWxzZXt2YXIgYnl0ZXM9QnVmZmVyLmlzQnVmZmVyKHZhbCk/dmFsOnV0ZjhUb0J5dGVzKG5ldyBCdWZmZXIodmFsLGVuY29kaW5nKS50b1N0cmluZygpKTt2YXIgbGVuPWJ5dGVzLmxlbmd0aDtmb3IoaT0wO2k8ZW5kLXN0YXJ0OysraSl7dGhpc1tpK3N0YXJ0XT1ieXRlc1tpJWxlbl19fXJldHVybiB0aGlzfTt2YXIgSU5WQUxJRF9CQVNFNjRfUkU9L1teK1xcLzAtOUEtWmEtei1fXS9nO2Z1bmN0aW9uIGJhc2U2NGNsZWFuKHN0cil7c3RyPXN0cmluZ3RyaW0oc3RyKS5yZXBsYWNlKElOVkFMSURfQkFTRTY0X1JFLFwiXCIpO2lmKHN0ci5sZW5ndGg8MilyZXR1cm5cIlwiO3doaWxlKHN0ci5sZW5ndGglNCE9PTApe3N0cj1zdHIrXCI9XCJ9cmV0dXJuIHN0cn1mdW5jdGlvbiBzdHJpbmd0cmltKHN0cil7aWYoc3RyLnRyaW0pcmV0dXJuIHN0ci50cmltKCk7cmV0dXJuIHN0ci5yZXBsYWNlKC9eXFxzK3xcXHMrJC9nLFwiXCIpfWZ1bmN0aW9uIHRvSGV4KG4pe2lmKG48MTYpcmV0dXJuXCIwXCIrbi50b1N0cmluZygxNik7cmV0dXJuIG4udG9TdHJpbmcoMTYpfWZ1bmN0aW9uIHV0ZjhUb0J5dGVzKHN0cmluZyx1bml0cyl7dW5pdHM9dW5pdHN8fEluZmluaXR5O3ZhciBjb2RlUG9pbnQ7dmFyIGxlbmd0aD1zdHJpbmcubGVuZ3RoO3ZhciBsZWFkU3Vycm9nYXRlPW51bGw7dmFyIGJ5dGVzPVtdO2Zvcih2YXIgaT0wO2k8bGVuZ3RoOysraSl7Y29kZVBvaW50PXN0cmluZy5jaGFyQ29kZUF0KGkpO2lmKGNvZGVQb2ludD41NTI5NSYmY29kZVBvaW50PDU3MzQ0KXtpZighbGVhZFN1cnJvZ2F0ZSl7aWYoY29kZVBvaW50PjU2MzE5KXtpZigodW5pdHMtPTMpPi0xKWJ5dGVzLnB1c2goMjM5LDE5MSwxODkpO2NvbnRpbnVlfWVsc2UgaWYoaSsxPT09bGVuZ3RoKXtpZigodW5pdHMtPTMpPi0xKWJ5dGVzLnB1c2goMjM5LDE5MSwxODkpO2NvbnRpbnVlfWxlYWRTdXJyb2dhdGU9Y29kZVBvaW50O2NvbnRpbnVlfWlmKGNvZGVQb2ludDw1NjMyMCl7aWYoKHVuaXRzLT0zKT4tMSlieXRlcy5wdXNoKDIzOSwxOTEsMTg5KTtsZWFkU3Vycm9nYXRlPWNvZGVQb2ludDtjb250aW51ZX1jb2RlUG9pbnQ9KGxlYWRTdXJyb2dhdGUtNTUyOTY8PDEwfGNvZGVQb2ludC01NjMyMCkrNjU1MzZ9ZWxzZSBpZihsZWFkU3Vycm9nYXRlKXtpZigodW5pdHMtPTMpPi0xKWJ5dGVzLnB1c2goMjM5LDE5MSwxODkpfWxlYWRTdXJyb2dhdGU9bnVsbDtpZihjb2RlUG9pbnQ8MTI4KXtpZigodW5pdHMtPTEpPDApYnJlYWs7Ynl0ZXMucHVzaChjb2RlUG9pbnQpfWVsc2UgaWYoY29kZVBvaW50PDIwNDgpe2lmKCh1bml0cy09Mik8MClicmVhaztieXRlcy5wdXNoKGNvZGVQb2ludD4+NnwxOTIsY29kZVBvaW50JjYzfDEyOCl9ZWxzZSBpZihjb2RlUG9pbnQ8NjU1MzYpe2lmKCh1bml0cy09Myk8MClicmVhaztieXRlcy5wdXNoKGNvZGVQb2ludD4+MTJ8MjI0LGNvZGVQb2ludD4+NiY2M3wxMjgsY29kZVBvaW50JjYzfDEyOCl9ZWxzZSBpZihjb2RlUG9pbnQ8MTExNDExMil7aWYoKHVuaXRzLT00KTwwKWJyZWFrO2J5dGVzLnB1c2goY29kZVBvaW50Pj4xOHwyNDAsY29kZVBvaW50Pj4xMiY2M3wxMjgsY29kZVBvaW50Pj42JjYzfDEyOCxjb2RlUG9pbnQmNjN8MTI4KX1lbHNle3Rocm93IG5ldyBFcnJvcihcIkludmFsaWQgY29kZSBwb2ludFwiKX19cmV0dXJuIGJ5dGVzfWZ1bmN0aW9uIGFzY2lpVG9CeXRlcyhzdHIpe3ZhciBieXRlQXJyYXk9W107Zm9yKHZhciBpPTA7aTxzdHIubGVuZ3RoOysraSl7Ynl0ZUFycmF5LnB1c2goc3RyLmNoYXJDb2RlQXQoaSkmMjU1KX1yZXR1cm4gYnl0ZUFycmF5fWZ1bmN0aW9uIHV0ZjE2bGVUb0J5dGVzKHN0cix1bml0cyl7dmFyIGMsaGksbG87dmFyIGJ5dGVBcnJheT1bXTtmb3IodmFyIGk9MDtpPHN0ci5sZW5ndGg7KytpKXtpZigodW5pdHMtPTIpPDApYnJlYWs7Yz1zdHIuY2hhckNvZGVBdChpKTtoaT1jPj44O2xvPWMlMjU2O2J5dGVBcnJheS5wdXNoKGxvKTtieXRlQXJyYXkucHVzaChoaSl9cmV0dXJuIGJ5dGVBcnJheX1mdW5jdGlvbiBiYXNlNjRUb0J5dGVzKHN0cil7cmV0dXJuIGJhc2U2NC50b0J5dGVBcnJheShiYXNlNjRjbGVhbihzdHIpKX1mdW5jdGlvbiBibGl0QnVmZmVyKHNyYyxkc3Qsb2Zmc2V0LGxlbmd0aCl7Zm9yKHZhciBpPTA7aTxsZW5ndGg7KytpKXtpZihpK29mZnNldD49ZHN0Lmxlbmd0aHx8aT49c3JjLmxlbmd0aClicmVhaztkc3RbaStvZmZzZXRdPXNyY1tpXX1yZXR1cm4gaX1mdW5jdGlvbiBpc25hbih2YWwpe3JldHVybiB2YWwhPT12YWx9fSkuY2FsbCh0aGlzLHR5cGVvZiBnbG9iYWwhPT1cInVuZGVmaW5lZFwiP2dsb2JhbDp0eXBlb2Ygc2VsZiE9PVwidW5kZWZpbmVkXCI/c2VsZjp0eXBlb2Ygd2luZG93IT09XCJ1bmRlZmluZWRcIj93aW5kb3c6e30pfSx7XCJiYXNlNjQtanNcIjoyLGllZWU3NTQ6MzcsaXNhcnJheTo0MH1dLDY6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpeyhmdW5jdGlvbihCdWZmZXIpe2Z1bmN0aW9uIGlzQXJyYXkoYXJnKXtpZihBcnJheS5pc0FycmF5KXtyZXR1cm4gQXJyYXkuaXNBcnJheShhcmcpfXJldHVybiBvYmplY3RUb1N0cmluZyhhcmcpPT09XCJbb2JqZWN0IEFycmF5XVwifWV4cG9ydHMuaXNBcnJheT1pc0FycmF5O2Z1bmN0aW9uIGlzQm9vbGVhbihhcmcpe3JldHVybiB0eXBlb2YgYXJnPT09XCJib29sZWFuXCJ9ZXhwb3J0cy5pc0Jvb2xlYW49aXNCb29sZWFuO2Z1bmN0aW9uIGlzTnVsbChhcmcpe3JldHVybiBhcmc9PT1udWxsfWV4cG9ydHMuaXNOdWxsPWlzTnVsbDtmdW5jdGlvbiBpc051bGxPclVuZGVmaW5lZChhcmcpe3JldHVybiBhcmc9PW51bGx9ZXhwb3J0cy5pc051bGxPclVuZGVmaW5lZD1pc051bGxPclVuZGVmaW5lZDtmdW5jdGlvbiBpc051bWJlcihhcmcpe3JldHVybiB0eXBlb2YgYXJnPT09XCJudW1iZXJcIn1leHBvcnRzLmlzTnVtYmVyPWlzTnVtYmVyO2Z1bmN0aW9uIGlzU3RyaW5nKGFyZyl7cmV0dXJuIHR5cGVvZiBhcmc9PT1cInN0cmluZ1wifWV4cG9ydHMuaXNTdHJpbmc9aXNTdHJpbmc7ZnVuY3Rpb24gaXNTeW1ib2woYXJnKXtyZXR1cm4gdHlwZW9mIGFyZz09PVwic3ltYm9sXCJ9ZXhwb3J0cy5pc1N5bWJvbD1pc1N5bWJvbDtmdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpe3JldHVybiBhcmc9PT12b2lkIDB9ZXhwb3J0cy5pc1VuZGVmaW5lZD1pc1VuZGVmaW5lZDtmdW5jdGlvbiBpc1JlZ0V4cChyZSl7cmV0dXJuIG9iamVjdFRvU3RyaW5nKHJlKT09PVwiW29iamVjdCBSZWdFeHBdXCJ9ZXhwb3J0cy5pc1JlZ0V4cD1pc1JlZ0V4cDtmdW5jdGlvbiBpc09iamVjdChhcmcpe3JldHVybiB0eXBlb2YgYXJnPT09XCJvYmplY3RcIiYmYXJnIT09bnVsbH1leHBvcnRzLmlzT2JqZWN0PWlzT2JqZWN0O2Z1bmN0aW9uIGlzRGF0ZShkKXtyZXR1cm4gb2JqZWN0VG9TdHJpbmcoZCk9PT1cIltvYmplY3QgRGF0ZV1cIn1leHBvcnRzLmlzRGF0ZT1pc0RhdGU7ZnVuY3Rpb24gaXNFcnJvcihlKXtyZXR1cm4gb2JqZWN0VG9TdHJpbmcoZSk9PT1cIltvYmplY3QgRXJyb3JdXCJ8fGUgaW5zdGFuY2VvZiBFcnJvcn1leHBvcnRzLmlzRXJyb3I9aXNFcnJvcjtmdW5jdGlvbiBpc0Z1bmN0aW9uKGFyZyl7cmV0dXJuIHR5cGVvZiBhcmc9PT1cImZ1bmN0aW9uXCJ9ZXhwb3J0cy5pc0Z1bmN0aW9uPWlzRnVuY3Rpb247ZnVuY3Rpb24gaXNQcmltaXRpdmUoYXJnKXtyZXR1cm4gYXJnPT09bnVsbHx8dHlwZW9mIGFyZz09PVwiYm9vbGVhblwifHx0eXBlb2YgYXJnPT09XCJudW1iZXJcInx8dHlwZW9mIGFyZz09PVwic3RyaW5nXCJ8fHR5cGVvZiBhcmc9PT1cInN5bWJvbFwifHx0eXBlb2YgYXJnPT09XCJ1bmRlZmluZWRcIn1leHBvcnRzLmlzUHJpbWl0aXZlPWlzUHJpbWl0aXZlO2V4cG9ydHMuaXNCdWZmZXI9QnVmZmVyLmlzQnVmZmVyO2Z1bmN0aW9uIG9iamVjdFRvU3RyaW5nKG8pe3JldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobyl9fSkuY2FsbCh0aGlzLHtpc0J1ZmZlcjpyZXF1aXJlKFwiLi4vLi4vaXMtYnVmZmVyL2luZGV4LmpzXCIpfSl9LHtcIi4uLy4uL2lzLWJ1ZmZlci9pbmRleC5qc1wiOjM5fV0sNzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIEVsZW1lbnRUeXBlPXJlcXVpcmUoXCJkb21lbGVtZW50dHlwZVwiKTt2YXIgZW50aXRpZXM9cmVxdWlyZShcImVudGl0aWVzXCIpO3ZhciBib29sZWFuQXR0cmlidXRlcz17X19wcm90b19fOm51bGwsYWxsb3dmdWxsc2NyZWVuOnRydWUsYXN5bmM6dHJ1ZSxhdXRvZm9jdXM6dHJ1ZSxhdXRvcGxheTp0cnVlLGNoZWNrZWQ6dHJ1ZSxjb250cm9sczp0cnVlLGRlZmF1bHQ6dHJ1ZSxkZWZlcjp0cnVlLGRpc2FibGVkOnRydWUsaGlkZGVuOnRydWUsaXNtYXA6dHJ1ZSxsb29wOnRydWUsbXVsdGlwbGU6dHJ1ZSxtdXRlZDp0cnVlLG9wZW46dHJ1ZSxyZWFkb25seTp0cnVlLHJlcXVpcmVkOnRydWUscmV2ZXJzZWQ6dHJ1ZSxzY29wZWQ6dHJ1ZSxzZWFtbGVzczp0cnVlLHNlbGVjdGVkOnRydWUsdHlwZW11c3RtYXRjaDp0cnVlfTt2YXIgdW5lbmNvZGVkRWxlbWVudHM9e19fcHJvdG9fXzpudWxsLHN0eWxlOnRydWUsc2NyaXB0OnRydWUseG1wOnRydWUsaWZyYW1lOnRydWUsbm9lbWJlZDp0cnVlLG5vZnJhbWVzOnRydWUscGxhaW50ZXh0OnRydWUsbm9zY3JpcHQ6dHJ1ZX07ZnVuY3Rpb24gZm9ybWF0QXR0cnMoYXR0cmlidXRlcyxvcHRzKXtpZighYXR0cmlidXRlcylyZXR1cm47dmFyIG91dHB1dD1cIlwiLHZhbHVlO2Zvcih2YXIga2V5IGluIGF0dHJpYnV0ZXMpe3ZhbHVlPWF0dHJpYnV0ZXNba2V5XTtpZihvdXRwdXQpe291dHB1dCs9XCIgXCJ9aWYoIXZhbHVlJiZib29sZWFuQXR0cmlidXRlc1trZXldKXtvdXRwdXQrPWtleX1lbHNle291dHB1dCs9a2V5Kyc9XCInKyhvcHRzLmRlY29kZUVudGl0aWVzP2VudGl0aWVzLmVuY29kZVhNTCh2YWx1ZSk6dmFsdWUpKydcIid9fXJldHVybiBvdXRwdXR9dmFyIHNpbmdsZVRhZz17X19wcm90b19fOm51bGwsYXJlYTp0cnVlLGJhc2U6dHJ1ZSxiYXNlZm9udDp0cnVlLGJyOnRydWUsY29sOnRydWUsY29tbWFuZDp0cnVlLGVtYmVkOnRydWUsZnJhbWU6dHJ1ZSxocjp0cnVlLGltZzp0cnVlLGlucHV0OnRydWUsaXNpbmRleDp0cnVlLGtleWdlbjp0cnVlLGxpbms6dHJ1ZSxtZXRhOnRydWUscGFyYW06dHJ1ZSxzb3VyY2U6dHJ1ZSx0cmFjazp0cnVlLHdicjp0cnVlfTt2YXIgcmVuZGVyPW1vZHVsZS5leHBvcnRzPWZ1bmN0aW9uKGRvbSxvcHRzKXtpZighQXJyYXkuaXNBcnJheShkb20pJiYhZG9tLmNoZWVyaW8pZG9tPVtkb21dO29wdHM9b3B0c3x8e307dmFyIG91dHB1dD1cIlwiO2Zvcih2YXIgaT0wO2k8ZG9tLmxlbmd0aDtpKyspe3ZhciBlbGVtPWRvbVtpXTtpZihlbGVtLnR5cGU9PT1cInJvb3RcIilvdXRwdXQrPXJlbmRlcihlbGVtLmNoaWxkcmVuLG9wdHMpO2Vsc2UgaWYoRWxlbWVudFR5cGUuaXNUYWcoZWxlbSkpb3V0cHV0Kz1yZW5kZXJUYWcoZWxlbSxvcHRzKTtlbHNlIGlmKGVsZW0udHlwZT09PUVsZW1lbnRUeXBlLkRpcmVjdGl2ZSlvdXRwdXQrPXJlbmRlckRpcmVjdGl2ZShlbGVtKTtlbHNlIGlmKGVsZW0udHlwZT09PUVsZW1lbnRUeXBlLkNvbW1lbnQpb3V0cHV0Kz1yZW5kZXJDb21tZW50KGVsZW0pO2Vsc2UgaWYoZWxlbS50eXBlPT09RWxlbWVudFR5cGUuQ0RBVEEpb3V0cHV0Kz1yZW5kZXJDZGF0YShlbGVtKTtlbHNlIG91dHB1dCs9cmVuZGVyVGV4dChlbGVtLG9wdHMpfXJldHVybiBvdXRwdXR9O2Z1bmN0aW9uIHJlbmRlclRhZyhlbGVtLG9wdHMpe2lmKGVsZW0ubmFtZT09PVwic3ZnXCIpb3B0cz17ZGVjb2RlRW50aXRpZXM6b3B0cy5kZWNvZGVFbnRpdGllcyx4bWxNb2RlOnRydWV9O3ZhciB0YWc9XCI8XCIrZWxlbS5uYW1lLGF0dHJpYnM9Zm9ybWF0QXR0cnMoZWxlbS5hdHRyaWJzLG9wdHMpO2lmKGF0dHJpYnMpe3RhZys9XCIgXCIrYXR0cmlic31pZihvcHRzLnhtbE1vZGUmJighZWxlbS5jaGlsZHJlbnx8ZWxlbS5jaGlsZHJlbi5sZW5ndGg9PT0wKSl7dGFnKz1cIi8+XCJ9ZWxzZXt0YWcrPVwiPlwiO2lmKGVsZW0uY2hpbGRyZW4pe3RhZys9cmVuZGVyKGVsZW0uY2hpbGRyZW4sb3B0cyl9aWYoIXNpbmdsZVRhZ1tlbGVtLm5hbWVdfHxvcHRzLnhtbE1vZGUpe3RhZys9XCI8L1wiK2VsZW0ubmFtZStcIj5cIn19cmV0dXJuIHRhZ31mdW5jdGlvbiByZW5kZXJEaXJlY3RpdmUoZWxlbSl7cmV0dXJuXCI8XCIrZWxlbS5kYXRhK1wiPlwifWZ1bmN0aW9uIHJlbmRlclRleHQoZWxlbSxvcHRzKXt2YXIgZGF0YT1lbGVtLmRhdGF8fFwiXCI7aWYob3B0cy5kZWNvZGVFbnRpdGllcyYmIShlbGVtLnBhcmVudCYmZWxlbS5wYXJlbnQubmFtZSBpbiB1bmVuY29kZWRFbGVtZW50cykpe2RhdGE9ZW50aXRpZXMuZW5jb2RlWE1MKGRhdGEpfXJldHVybiBkYXRhfWZ1bmN0aW9uIHJlbmRlckNkYXRhKGVsZW0pe3JldHVyblwiPCFbQ0RBVEFbXCIrZWxlbS5jaGlsZHJlblswXS5kYXRhK1wiXV0+XCJ9ZnVuY3Rpb24gcmVuZGVyQ29tbWVudChlbGVtKXtyZXR1cm5cIjwhLS1cIitlbGVtLmRhdGErXCItLT5cIn19LHtkb21lbGVtZW50dHlwZTo4LGVudGl0aWVzOjIwfV0sODpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9e1RleHQ6XCJ0ZXh0XCIsRGlyZWN0aXZlOlwiZGlyZWN0aXZlXCIsQ29tbWVudDpcImNvbW1lbnRcIixTY3JpcHQ6XCJzY3JpcHRcIixTdHlsZTpcInN0eWxlXCIsVGFnOlwidGFnXCIsQ0RBVEE6XCJjZGF0YVwiLGlzVGFnOmZ1bmN0aW9uKGVsZW0pe3JldHVybiBlbGVtLnR5cGU9PT1cInRhZ1wifHxlbGVtLnR5cGU9PT1cInNjcmlwdFwifHxlbGVtLnR5cGU9PT1cInN0eWxlXCJ9fX0se31dLDk6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe21vZHVsZS5leHBvcnRzPXtUZXh0OlwidGV4dFwiLERpcmVjdGl2ZTpcImRpcmVjdGl2ZVwiLENvbW1lbnQ6XCJjb21tZW50XCIsU2NyaXB0Olwic2NyaXB0XCIsU3R5bGU6XCJzdHlsZVwiLFRhZzpcInRhZ1wiLENEQVRBOlwiY2RhdGFcIixEb2N0eXBlOlwiZG9jdHlwZVwiLGlzVGFnOmZ1bmN0aW9uKGVsZW0pe3JldHVybiBlbGVtLnR5cGU9PT1cInRhZ1wifHxlbGVtLnR5cGU9PT1cInNjcmlwdFwifHxlbGVtLnR5cGU9PT1cInN0eWxlXCJ9fX0se31dLDEwOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgRWxlbWVudFR5cGU9cmVxdWlyZShcImRvbWVsZW1lbnR0eXBlXCIpO3ZhciByZV93aGl0ZXNwYWNlPS9cXHMrL2c7dmFyIE5vZGVQcm90b3R5cGU9cmVxdWlyZShcIi4vbGliL25vZGVcIik7dmFyIEVsZW1lbnRQcm90b3R5cGU9cmVxdWlyZShcIi4vbGliL2VsZW1lbnRcIik7ZnVuY3Rpb24gRG9tSGFuZGxlcihjYWxsYmFjayxvcHRpb25zLGVsZW1lbnRDQil7aWYodHlwZW9mIGNhbGxiYWNrPT09XCJvYmplY3RcIil7ZWxlbWVudENCPW9wdGlvbnM7b3B0aW9ucz1jYWxsYmFjaztjYWxsYmFjaz1udWxsfWVsc2UgaWYodHlwZW9mIG9wdGlvbnM9PT1cImZ1bmN0aW9uXCIpe2VsZW1lbnRDQj1vcHRpb25zO29wdGlvbnM9ZGVmYXVsdE9wdHN9dGhpcy5fY2FsbGJhY2s9Y2FsbGJhY2s7dGhpcy5fb3B0aW9ucz1vcHRpb25zfHxkZWZhdWx0T3B0czt0aGlzLl9lbGVtZW50Q0I9ZWxlbWVudENCO3RoaXMuZG9tPVtdO3RoaXMuX2RvbmU9ZmFsc2U7dGhpcy5fdGFnU3RhY2s9W107dGhpcy5fcGFyc2VyPXRoaXMuX3BhcnNlcnx8bnVsbH12YXIgZGVmYXVsdE9wdHM9e25vcm1hbGl6ZVdoaXRlc3BhY2U6ZmFsc2Usd2l0aFN0YXJ0SW5kaWNlczpmYWxzZX07RG9tSGFuZGxlci5wcm90b3R5cGUub25wYXJzZXJpbml0PWZ1bmN0aW9uKHBhcnNlcil7dGhpcy5fcGFyc2VyPXBhcnNlcn07RG9tSGFuZGxlci5wcm90b3R5cGUub25yZXNldD1mdW5jdGlvbigpe0RvbUhhbmRsZXIuY2FsbCh0aGlzLHRoaXMuX2NhbGxiYWNrLHRoaXMuX29wdGlvbnMsdGhpcy5fZWxlbWVudENCKX07RG9tSGFuZGxlci5wcm90b3R5cGUub25lbmQ9ZnVuY3Rpb24oKXtpZih0aGlzLl9kb25lKXJldHVybjt0aGlzLl9kb25lPXRydWU7dGhpcy5fcGFyc2VyPW51bGw7dGhpcy5faGFuZGxlQ2FsbGJhY2sobnVsbCl9O0RvbUhhbmRsZXIucHJvdG90eXBlLl9oYW5kbGVDYWxsYmFjaz1Eb21IYW5kbGVyLnByb3RvdHlwZS5vbmVycm9yPWZ1bmN0aW9uKGVycm9yKXtpZih0eXBlb2YgdGhpcy5fY2FsbGJhY2s9PT1cImZ1bmN0aW9uXCIpe3RoaXMuX2NhbGxiYWNrKGVycm9yLHRoaXMuZG9tKX1lbHNle2lmKGVycm9yKXRocm93IGVycm9yfX07RG9tSGFuZGxlci5wcm90b3R5cGUub25jbG9zZXRhZz1mdW5jdGlvbigpe3ZhciBlbGVtPXRoaXMuX3RhZ1N0YWNrLnBvcCgpO2lmKHRoaXMuX2VsZW1lbnRDQil0aGlzLl9lbGVtZW50Q0IoZWxlbSl9O0RvbUhhbmRsZXIucHJvdG90eXBlLl9hZGREb21FbGVtZW50PWZ1bmN0aW9uKGVsZW1lbnQpe3ZhciBwYXJlbnQ9dGhpcy5fdGFnU3RhY2tbdGhpcy5fdGFnU3RhY2subGVuZ3RoLTFdO3ZhciBzaWJsaW5ncz1wYXJlbnQ/cGFyZW50LmNoaWxkcmVuOnRoaXMuZG9tO3ZhciBwcmV2aW91c1NpYmxpbmc9c2libGluZ3Nbc2libGluZ3MubGVuZ3RoLTFdO2VsZW1lbnQubmV4dD1udWxsO2lmKHRoaXMuX29wdGlvbnMud2l0aFN0YXJ0SW5kaWNlcyl7ZWxlbWVudC5zdGFydEluZGV4PXRoaXMuX3BhcnNlci5zdGFydEluZGV4fWlmKHRoaXMuX29wdGlvbnMud2l0aERvbUx2bDEpe2VsZW1lbnQuX19wcm90b19fPWVsZW1lbnQudHlwZT09PVwidGFnXCI/RWxlbWVudFByb3RvdHlwZTpOb2RlUHJvdG90eXBlfWlmKHByZXZpb3VzU2libGluZyl7ZWxlbWVudC5wcmV2PXByZXZpb3VzU2libGluZztwcmV2aW91c1NpYmxpbmcubmV4dD1lbGVtZW50fWVsc2V7ZWxlbWVudC5wcmV2PW51bGx9c2libGluZ3MucHVzaChlbGVtZW50KTtlbGVtZW50LnBhcmVudD1wYXJlbnR8fG51bGx9O0RvbUhhbmRsZXIucHJvdG90eXBlLm9ub3BlbnRhZz1mdW5jdGlvbihuYW1lLGF0dHJpYnMpe3ZhciBlbGVtZW50PXt0eXBlOm5hbWU9PT1cInNjcmlwdFwiP0VsZW1lbnRUeXBlLlNjcmlwdDpuYW1lPT09XCJzdHlsZVwiP0VsZW1lbnRUeXBlLlN0eWxlOkVsZW1lbnRUeXBlLlRhZyxuYW1lOm5hbWUsYXR0cmliczphdHRyaWJzLGNoaWxkcmVuOltdfTt0aGlzLl9hZGREb21FbGVtZW50KGVsZW1lbnQpO3RoaXMuX3RhZ1N0YWNrLnB1c2goZWxlbWVudCl9O0RvbUhhbmRsZXIucHJvdG90eXBlLm9udGV4dD1mdW5jdGlvbihkYXRhKXt2YXIgbm9ybWFsaXplPXRoaXMuX29wdGlvbnMubm9ybWFsaXplV2hpdGVzcGFjZXx8dGhpcy5fb3B0aW9ucy5pZ25vcmVXaGl0ZXNwYWNlO3ZhciBsYXN0VGFnO2lmKCF0aGlzLl90YWdTdGFjay5sZW5ndGgmJnRoaXMuZG9tLmxlbmd0aCYmKGxhc3RUYWc9dGhpcy5kb21bdGhpcy5kb20ubGVuZ3RoLTFdKS50eXBlPT09RWxlbWVudFR5cGUuVGV4dCl7aWYobm9ybWFsaXplKXtsYXN0VGFnLmRhdGE9KGxhc3RUYWcuZGF0YStkYXRhKS5yZXBsYWNlKHJlX3doaXRlc3BhY2UsXCIgXCIpfWVsc2V7bGFzdFRhZy5kYXRhKz1kYXRhfX1lbHNle2lmKHRoaXMuX3RhZ1N0YWNrLmxlbmd0aCYmKGxhc3RUYWc9dGhpcy5fdGFnU3RhY2tbdGhpcy5fdGFnU3RhY2subGVuZ3RoLTFdKSYmKGxhc3RUYWc9bGFzdFRhZy5jaGlsZHJlbltsYXN0VGFnLmNoaWxkcmVuLmxlbmd0aC0xXSkmJmxhc3RUYWcudHlwZT09PUVsZW1lbnRUeXBlLlRleHQpe2lmKG5vcm1hbGl6ZSl7bGFzdFRhZy5kYXRhPShsYXN0VGFnLmRhdGErZGF0YSkucmVwbGFjZShyZV93aGl0ZXNwYWNlLFwiIFwiKX1lbHNle2xhc3RUYWcuZGF0YSs9ZGF0YX19ZWxzZXtpZihub3JtYWxpemUpe2RhdGE9ZGF0YS5yZXBsYWNlKHJlX3doaXRlc3BhY2UsXCIgXCIpfXRoaXMuX2FkZERvbUVsZW1lbnQoe2RhdGE6ZGF0YSx0eXBlOkVsZW1lbnRUeXBlLlRleHR9KX19fTtEb21IYW5kbGVyLnByb3RvdHlwZS5vbmNvbW1lbnQ9ZnVuY3Rpb24oZGF0YSl7dmFyIGxhc3RUYWc9dGhpcy5fdGFnU3RhY2tbdGhpcy5fdGFnU3RhY2subGVuZ3RoLTFdO2lmKGxhc3RUYWcmJmxhc3RUYWcudHlwZT09PUVsZW1lbnRUeXBlLkNvbW1lbnQpe2xhc3RUYWcuZGF0YSs9ZGF0YTtyZXR1cm59dmFyIGVsZW1lbnQ9e2RhdGE6ZGF0YSx0eXBlOkVsZW1lbnRUeXBlLkNvbW1lbnR9O3RoaXMuX2FkZERvbUVsZW1lbnQoZWxlbWVudCk7dGhpcy5fdGFnU3RhY2sucHVzaChlbGVtZW50KX07RG9tSGFuZGxlci5wcm90b3R5cGUub25jZGF0YXN0YXJ0PWZ1bmN0aW9uKCl7dmFyIGVsZW1lbnQ9e2NoaWxkcmVuOlt7ZGF0YTpcIlwiLHR5cGU6RWxlbWVudFR5cGUuVGV4dH1dLHR5cGU6RWxlbWVudFR5cGUuQ0RBVEF9O3RoaXMuX2FkZERvbUVsZW1lbnQoZWxlbWVudCk7dGhpcy5fdGFnU3RhY2sucHVzaChlbGVtZW50KX07RG9tSGFuZGxlci5wcm90b3R5cGUub25jb21tZW50ZW5kPURvbUhhbmRsZXIucHJvdG90eXBlLm9uY2RhdGFlbmQ9ZnVuY3Rpb24oKXt0aGlzLl90YWdTdGFjay5wb3AoKX07RG9tSGFuZGxlci5wcm90b3R5cGUub25wcm9jZXNzaW5naW5zdHJ1Y3Rpb249ZnVuY3Rpb24obmFtZSxkYXRhKXt0aGlzLl9hZGREb21FbGVtZW50KHtuYW1lOm5hbWUsZGF0YTpkYXRhLHR5cGU6RWxlbWVudFR5cGUuRGlyZWN0aXZlfSl9O21vZHVsZS5leHBvcnRzPURvbUhhbmRsZXJ9LHtcIi4vbGliL2VsZW1lbnRcIjoxMSxcIi4vbGliL25vZGVcIjoxMixkb21lbGVtZW50dHlwZTo5fV0sMTE6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciBOb2RlUHJvdG90eXBlPXJlcXVpcmUoXCIuL25vZGVcIik7dmFyIEVsZW1lbnRQcm90b3R5cGU9bW9kdWxlLmV4cG9ydHM9T2JqZWN0LmNyZWF0ZShOb2RlUHJvdG90eXBlKTt2YXIgZG9tTHZsMT17dGFnTmFtZTpcIm5hbWVcIn07T2JqZWN0LmtleXMoZG9tTHZsMSkuZm9yRWFjaChmdW5jdGlvbihrZXkpe3ZhciBzaG9ydGhhbmQ9ZG9tTHZsMVtrZXldO09iamVjdC5kZWZpbmVQcm9wZXJ0eShFbGVtZW50UHJvdG90eXBlLGtleSx7Z2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXNbc2hvcnRoYW5kXXx8bnVsbH0sc2V0OmZ1bmN0aW9uKHZhbCl7dGhpc1tzaG9ydGhhbmRdPXZhbDtyZXR1cm4gdmFsfX0pfSl9LHtcIi4vbm9kZVwiOjEyfV0sMTI6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciBOb2RlUHJvdG90eXBlPW1vZHVsZS5leHBvcnRzPXtnZXQgZmlyc3RDaGlsZCgpe3ZhciBjaGlsZHJlbj10aGlzLmNoaWxkcmVuO3JldHVybiBjaGlsZHJlbiYmY2hpbGRyZW5bMF18fG51bGx9LGdldCBsYXN0Q2hpbGQoKXt2YXIgY2hpbGRyZW49dGhpcy5jaGlsZHJlbjtyZXR1cm4gY2hpbGRyZW4mJmNoaWxkcmVuW2NoaWxkcmVuLmxlbmd0aC0xXXx8bnVsbH0sZ2V0IG5vZGVUeXBlKCl7cmV0dXJuIG5vZGVUeXBlc1t0aGlzLnR5cGVdfHxub2RlVHlwZXMuZWxlbWVudH19O3ZhciBkb21MdmwxPXt0YWdOYW1lOlwibmFtZVwiLGNoaWxkTm9kZXM6XCJjaGlsZHJlblwiLHBhcmVudE5vZGU6XCJwYXJlbnRcIixwcmV2aW91c1NpYmxpbmc6XCJwcmV2XCIsbmV4dFNpYmxpbmc6XCJuZXh0XCIsbm9kZVZhbHVlOlwiZGF0YVwifTt2YXIgbm9kZVR5cGVzPXtlbGVtZW50OjEsdGV4dDozLGNkYXRhOjQsY29tbWVudDo4fTtPYmplY3Qua2V5cyhkb21MdmwxKS5mb3JFYWNoKGZ1bmN0aW9uKGtleSl7dmFyIHNob3J0aGFuZD1kb21MdmwxW2tleV07T2JqZWN0LmRlZmluZVByb3BlcnR5KE5vZGVQcm90b3R5cGUsa2V5LHtnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpc1tzaG9ydGhhbmRdfHxudWxsfSxzZXQ6ZnVuY3Rpb24odmFsKXt0aGlzW3Nob3J0aGFuZF09dmFsO3JldHVybiB2YWx9fSl9KX0se31dLDEzOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgRG9tVXRpbHM9bW9kdWxlLmV4cG9ydHM7W3JlcXVpcmUoXCIuL2xpYi9zdHJpbmdpZnlcIikscmVxdWlyZShcIi4vbGliL3RyYXZlcnNhbFwiKSxyZXF1aXJlKFwiLi9saWIvbWFuaXB1bGF0aW9uXCIpLHJlcXVpcmUoXCIuL2xpYi9xdWVyeWluZ1wiKSxyZXF1aXJlKFwiLi9saWIvbGVnYWN5XCIpLHJlcXVpcmUoXCIuL2xpYi9oZWxwZXJzXCIpXS5mb3JFYWNoKGZ1bmN0aW9uKGV4dCl7T2JqZWN0LmtleXMoZXh0KS5mb3JFYWNoKGZ1bmN0aW9uKGtleSl7RG9tVXRpbHNba2V5XT1leHRba2V5XS5iaW5kKERvbVV0aWxzKX0pfSl9LHtcIi4vbGliL2hlbHBlcnNcIjoxNCxcIi4vbGliL2xlZ2FjeVwiOjE1LFwiLi9saWIvbWFuaXB1bGF0aW9uXCI6MTYsXCIuL2xpYi9xdWVyeWluZ1wiOjE3LFwiLi9saWIvc3RyaW5naWZ5XCI6MTgsXCIuL2xpYi90cmF2ZXJzYWxcIjoxOX1dLDE0OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtleHBvcnRzLnJlbW92ZVN1YnNldHM9ZnVuY3Rpb24obm9kZXMpe3ZhciBpZHg9bm9kZXMubGVuZ3RoLG5vZGUsYW5jZXN0b3IscmVwbGFjZTt3aGlsZSgtLWlkeD4tMSl7bm9kZT1hbmNlc3Rvcj1ub2Rlc1tpZHhdO25vZGVzW2lkeF09bnVsbDtyZXBsYWNlPXRydWU7d2hpbGUoYW5jZXN0b3Ipe2lmKG5vZGVzLmluZGV4T2YoYW5jZXN0b3IpPi0xKXtyZXBsYWNlPWZhbHNlO25vZGVzLnNwbGljZShpZHgsMSk7YnJlYWt9YW5jZXN0b3I9YW5jZXN0b3IucGFyZW50fWlmKHJlcGxhY2Upe25vZGVzW2lkeF09bm9kZX19cmV0dXJuIG5vZGVzfTt2YXIgUE9TSVRJT049e0RJU0NPTk5FQ1RFRDoxLFBSRUNFRElORzoyLEZPTExPV0lORzo0LENPTlRBSU5TOjgsQ09OVEFJTkVEX0JZOjE2fTt2YXIgY29tcGFyZVBvcz1leHBvcnRzLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uPWZ1bmN0aW9uKG5vZGVBLG5vZGVCKXt2YXIgYVBhcmVudHM9W107dmFyIGJQYXJlbnRzPVtdO3ZhciBjdXJyZW50LHNoYXJlZFBhcmVudCxzaWJsaW5ncyxhU2libGluZyxiU2libGluZyxpZHg7aWYobm9kZUE9PT1ub2RlQil7cmV0dXJuIDB9Y3VycmVudD1ub2RlQTt3aGlsZShjdXJyZW50KXthUGFyZW50cy51bnNoaWZ0KGN1cnJlbnQpO2N1cnJlbnQ9Y3VycmVudC5wYXJlbnR9Y3VycmVudD1ub2RlQjt3aGlsZShjdXJyZW50KXtiUGFyZW50cy51bnNoaWZ0KGN1cnJlbnQpO2N1cnJlbnQ9Y3VycmVudC5wYXJlbnR9aWR4PTA7d2hpbGUoYVBhcmVudHNbaWR4XT09PWJQYXJlbnRzW2lkeF0pe2lkeCsrfWlmKGlkeD09PTApe3JldHVybiBQT1NJVElPTi5ESVNDT05ORUNURUR9c2hhcmVkUGFyZW50PWFQYXJlbnRzW2lkeC0xXTtzaWJsaW5ncz1zaGFyZWRQYXJlbnQuY2hpbGRyZW47YVNpYmxpbmc9YVBhcmVudHNbaWR4XTtiU2libGluZz1iUGFyZW50c1tpZHhdO2lmKHNpYmxpbmdzLmluZGV4T2YoYVNpYmxpbmcpPnNpYmxpbmdzLmluZGV4T2YoYlNpYmxpbmcpKXtpZihzaGFyZWRQYXJlbnQ9PT1ub2RlQil7cmV0dXJuIFBPU0lUSU9OLkZPTExPV0lOR3xQT1NJVElPTi5DT05UQUlORURfQll9cmV0dXJuIFBPU0lUSU9OLkZPTExPV0lOR31lbHNle2lmKHNoYXJlZFBhcmVudD09PW5vZGVBKXtyZXR1cm4gUE9TSVRJT04uUFJFQ0VESU5HfFBPU0lUSU9OLkNPTlRBSU5TfXJldHVybiBQT1NJVElPTi5QUkVDRURJTkd9fTtleHBvcnRzLnVuaXF1ZVNvcnQ9ZnVuY3Rpb24obm9kZXMpe3ZhciBpZHg9bm9kZXMubGVuZ3RoLG5vZGUscG9zaXRpb247bm9kZXM9bm9kZXMuc2xpY2UoKTt3aGlsZSgtLWlkeD4tMSl7bm9kZT1ub2Rlc1tpZHhdO3Bvc2l0aW9uPW5vZGVzLmluZGV4T2Yobm9kZSk7aWYocG9zaXRpb24+LTEmJnBvc2l0aW9uPGlkeCl7bm9kZXMuc3BsaWNlKGlkeCwxKX19bm9kZXMuc29ydChmdW5jdGlvbihhLGIpe3ZhciByZWxhdGl2ZT1jb21wYXJlUG9zKGEsYik7aWYocmVsYXRpdmUmUE9TSVRJT04uUFJFQ0VESU5HKXtyZXR1cm4tMX1lbHNlIGlmKHJlbGF0aXZlJlBPU0lUSU9OLkZPTExPV0lORyl7cmV0dXJuIDF9cmV0dXJuIDB9KTtyZXR1cm4gbm9kZXN9fSx7fV0sMTU6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciBFbGVtZW50VHlwZT1yZXF1aXJlKFwiZG9tZWxlbWVudHR5cGVcIik7dmFyIGlzVGFnPWV4cG9ydHMuaXNUYWc9RWxlbWVudFR5cGUuaXNUYWc7ZXhwb3J0cy50ZXN0RWxlbWVudD1mdW5jdGlvbihvcHRpb25zLGVsZW1lbnQpe2Zvcih2YXIga2V5IGluIG9wdGlvbnMpe2lmKCFvcHRpb25zLmhhc093blByb3BlcnR5KGtleSkpO2Vsc2UgaWYoa2V5PT09XCJ0YWdfbmFtZVwiKXtpZighaXNUYWcoZWxlbWVudCl8fCFvcHRpb25zLnRhZ19uYW1lKGVsZW1lbnQubmFtZSkpe3JldHVybiBmYWxzZX19ZWxzZSBpZihrZXk9PT1cInRhZ190eXBlXCIpe2lmKCFvcHRpb25zLnRhZ190eXBlKGVsZW1lbnQudHlwZSkpcmV0dXJuIGZhbHNlfWVsc2UgaWYoa2V5PT09XCJ0YWdfY29udGFpbnNcIil7aWYoaXNUYWcoZWxlbWVudCl8fCFvcHRpb25zLnRhZ19jb250YWlucyhlbGVtZW50LmRhdGEpKXtyZXR1cm4gZmFsc2V9fWVsc2UgaWYoIWVsZW1lbnQuYXR0cmlic3x8IW9wdGlvbnNba2V5XShlbGVtZW50LmF0dHJpYnNba2V5XSkpe3JldHVybiBmYWxzZX19cmV0dXJuIHRydWV9O3ZhciBDaGVja3M9e3RhZ19uYW1lOmZ1bmN0aW9uKG5hbWUpe2lmKHR5cGVvZiBuYW1lPT09XCJmdW5jdGlvblwiKXtyZXR1cm4gZnVuY3Rpb24oZWxlbSl7cmV0dXJuIGlzVGFnKGVsZW0pJiZuYW1lKGVsZW0ubmFtZSl9fWVsc2UgaWYobmFtZT09PVwiKlwiKXtyZXR1cm4gaXNUYWd9ZWxzZXtyZXR1cm4gZnVuY3Rpb24oZWxlbSl7cmV0dXJuIGlzVGFnKGVsZW0pJiZlbGVtLm5hbWU9PT1uYW1lfX19LHRhZ190eXBlOmZ1bmN0aW9uKHR5cGUpe2lmKHR5cGVvZiB0eXBlPT09XCJmdW5jdGlvblwiKXtyZXR1cm4gZnVuY3Rpb24oZWxlbSl7cmV0dXJuIHR5cGUoZWxlbS50eXBlKX19ZWxzZXtyZXR1cm4gZnVuY3Rpb24oZWxlbSl7cmV0dXJuIGVsZW0udHlwZT09PXR5cGV9fX0sdGFnX2NvbnRhaW5zOmZ1bmN0aW9uKGRhdGEpe2lmKHR5cGVvZiBkYXRhPT09XCJmdW5jdGlvblwiKXtyZXR1cm4gZnVuY3Rpb24oZWxlbSl7cmV0dXJuIWlzVGFnKGVsZW0pJiZkYXRhKGVsZW0uZGF0YSl9fWVsc2V7cmV0dXJuIGZ1bmN0aW9uKGVsZW0pe3JldHVybiFpc1RhZyhlbGVtKSYmZWxlbS5kYXRhPT09ZGF0YX19fX07ZnVuY3Rpb24gZ2V0QXR0cmliQ2hlY2soYXR0cmliLHZhbHVlKXtpZih0eXBlb2YgdmFsdWU9PT1cImZ1bmN0aW9uXCIpe3JldHVybiBmdW5jdGlvbihlbGVtKXtyZXR1cm4gZWxlbS5hdHRyaWJzJiZ2YWx1ZShlbGVtLmF0dHJpYnNbYXR0cmliXSl9fWVsc2V7cmV0dXJuIGZ1bmN0aW9uKGVsZW0pe3JldHVybiBlbGVtLmF0dHJpYnMmJmVsZW0uYXR0cmlic1thdHRyaWJdPT09dmFsdWV9fX1mdW5jdGlvbiBjb21iaW5lRnVuY3MoYSxiKXtyZXR1cm4gZnVuY3Rpb24oZWxlbSl7cmV0dXJuIGEoZWxlbSl8fGIoZWxlbSl9fWV4cG9ydHMuZ2V0RWxlbWVudHM9ZnVuY3Rpb24ob3B0aW9ucyxlbGVtZW50LHJlY3Vyc2UsbGltaXQpe3ZhciBmdW5jcz1PYmplY3Qua2V5cyhvcHRpb25zKS5tYXAoZnVuY3Rpb24oa2V5KXt2YXIgdmFsdWU9b3B0aW9uc1trZXldO3JldHVybiBrZXkgaW4gQ2hlY2tzP0NoZWNrc1trZXldKHZhbHVlKTpnZXRBdHRyaWJDaGVjayhrZXksdmFsdWUpfSk7cmV0dXJuIGZ1bmNzLmxlbmd0aD09PTA/W106dGhpcy5maWx0ZXIoZnVuY3MucmVkdWNlKGNvbWJpbmVGdW5jcyksZWxlbWVudCxyZWN1cnNlLGxpbWl0KX07ZXhwb3J0cy5nZXRFbGVtZW50QnlJZD1mdW5jdGlvbihpZCxlbGVtZW50LHJlY3Vyc2Upe2lmKCFBcnJheS5pc0FycmF5KGVsZW1lbnQpKWVsZW1lbnQ9W2VsZW1lbnRdO3JldHVybiB0aGlzLmZpbmRPbmUoZ2V0QXR0cmliQ2hlY2soXCJpZFwiLGlkKSxlbGVtZW50LHJlY3Vyc2UhPT1mYWxzZSl9O2V4cG9ydHMuZ2V0RWxlbWVudHNCeVRhZ05hbWU9ZnVuY3Rpb24obmFtZSxlbGVtZW50LHJlY3Vyc2UsbGltaXQpe3JldHVybiB0aGlzLmZpbHRlcihDaGVja3MudGFnX25hbWUobmFtZSksZWxlbWVudCxyZWN1cnNlLGxpbWl0KX07ZXhwb3J0cy5nZXRFbGVtZW50c0J5VGFnVHlwZT1mdW5jdGlvbih0eXBlLGVsZW1lbnQscmVjdXJzZSxsaW1pdCl7cmV0dXJuIHRoaXMuZmlsdGVyKENoZWNrcy50YWdfdHlwZSh0eXBlKSxlbGVtZW50LHJlY3Vyc2UsbGltaXQpfX0se2RvbWVsZW1lbnR0eXBlOjl9XSwxNjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7ZXhwb3J0cy5yZW1vdmVFbGVtZW50PWZ1bmN0aW9uKGVsZW0pe2lmKGVsZW0ucHJldillbGVtLnByZXYubmV4dD1lbGVtLm5leHQ7aWYoZWxlbS5uZXh0KWVsZW0ubmV4dC5wcmV2PWVsZW0ucHJldjtpZihlbGVtLnBhcmVudCl7dmFyIGNoaWxkcz1lbGVtLnBhcmVudC5jaGlsZHJlbjtjaGlsZHMuc3BsaWNlKGNoaWxkcy5sYXN0SW5kZXhPZihlbGVtKSwxKX19O2V4cG9ydHMucmVwbGFjZUVsZW1lbnQ9ZnVuY3Rpb24oZWxlbSxyZXBsYWNlbWVudCl7dmFyIHByZXY9cmVwbGFjZW1lbnQucHJldj1lbGVtLnByZXY7aWYocHJldil7cHJldi5uZXh0PXJlcGxhY2VtZW50fXZhciBuZXh0PXJlcGxhY2VtZW50Lm5leHQ9ZWxlbS5uZXh0O2lmKG5leHQpe25leHQucHJldj1yZXBsYWNlbWVudH12YXIgcGFyZW50PXJlcGxhY2VtZW50LnBhcmVudD1lbGVtLnBhcmVudDtpZihwYXJlbnQpe3ZhciBjaGlsZHM9cGFyZW50LmNoaWxkcmVuO2NoaWxkc1tjaGlsZHMubGFzdEluZGV4T2YoZWxlbSldPXJlcGxhY2VtZW50fX07ZXhwb3J0cy5hcHBlbmRDaGlsZD1mdW5jdGlvbihlbGVtLGNoaWxkKXtjaGlsZC5wYXJlbnQ9ZWxlbTtpZihlbGVtLmNoaWxkcmVuLnB1c2goY2hpbGQpIT09MSl7dmFyIHNpYmxpbmc9ZWxlbS5jaGlsZHJlbltlbGVtLmNoaWxkcmVuLmxlbmd0aC0yXTtzaWJsaW5nLm5leHQ9Y2hpbGQ7Y2hpbGQucHJldj1zaWJsaW5nO2NoaWxkLm5leHQ9bnVsbH19O2V4cG9ydHMuYXBwZW5kPWZ1bmN0aW9uKGVsZW0sbmV4dCl7dmFyIHBhcmVudD1lbGVtLnBhcmVudCxjdXJyTmV4dD1lbGVtLm5leHQ7bmV4dC5uZXh0PWN1cnJOZXh0O25leHQucHJldj1lbGVtO2VsZW0ubmV4dD1uZXh0O25leHQucGFyZW50PXBhcmVudDtpZihjdXJyTmV4dCl7Y3Vyck5leHQucHJldj1uZXh0O2lmKHBhcmVudCl7dmFyIGNoaWxkcz1wYXJlbnQuY2hpbGRyZW47Y2hpbGRzLnNwbGljZShjaGlsZHMubGFzdEluZGV4T2YoY3Vyck5leHQpLDAsbmV4dCl9fWVsc2UgaWYocGFyZW50KXtwYXJlbnQuY2hpbGRyZW4ucHVzaChuZXh0KX19O2V4cG9ydHMucHJlcGVuZD1mdW5jdGlvbihlbGVtLHByZXYpe3ZhciBwYXJlbnQ9ZWxlbS5wYXJlbnQ7aWYocGFyZW50KXt2YXIgY2hpbGRzPXBhcmVudC5jaGlsZHJlbjtjaGlsZHMuc3BsaWNlKGNoaWxkcy5sYXN0SW5kZXhPZihlbGVtKSwwLHByZXYpfWlmKGVsZW0ucHJldil7ZWxlbS5wcmV2Lm5leHQ9cHJldn1wcmV2LnBhcmVudD1wYXJlbnQ7cHJldi5wcmV2PWVsZW0ucHJldjtwcmV2Lm5leHQ9ZWxlbTtlbGVtLnByZXY9cHJldn19LHt9XSwxNzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIGlzVGFnPXJlcXVpcmUoXCJkb21lbGVtZW50dHlwZVwiKS5pc1RhZzttb2R1bGUuZXhwb3J0cz17ZmlsdGVyOmZpbHRlcixmaW5kOmZpbmQsZmluZE9uZUNoaWxkOmZpbmRPbmVDaGlsZCxmaW5kT25lOmZpbmRPbmUsZXhpc3RzT25lOmV4aXN0c09uZSxmaW5kQWxsOmZpbmRBbGx9O2Z1bmN0aW9uIGZpbHRlcih0ZXN0LGVsZW1lbnQscmVjdXJzZSxsaW1pdCl7aWYoIUFycmF5LmlzQXJyYXkoZWxlbWVudCkpZWxlbWVudD1bZWxlbWVudF07aWYodHlwZW9mIGxpbWl0IT09XCJudW1iZXJcInx8IWlzRmluaXRlKGxpbWl0KSl7bGltaXQ9SW5maW5pdHl9cmV0dXJuIGZpbmQodGVzdCxlbGVtZW50LHJlY3Vyc2UhPT1mYWxzZSxsaW1pdCl9ZnVuY3Rpb24gZmluZCh0ZXN0LGVsZW1zLHJlY3Vyc2UsbGltaXQpe3ZhciByZXN1bHQ9W10sY2hpbGRzO2Zvcih2YXIgaT0wLGo9ZWxlbXMubGVuZ3RoO2k8ajtpKyspe2lmKHRlc3QoZWxlbXNbaV0pKXtyZXN1bHQucHVzaChlbGVtc1tpXSk7aWYoLS1saW1pdDw9MClicmVha31jaGlsZHM9ZWxlbXNbaV0uY2hpbGRyZW47aWYocmVjdXJzZSYmY2hpbGRzJiZjaGlsZHMubGVuZ3RoPjApe2NoaWxkcz1maW5kKHRlc3QsY2hpbGRzLHJlY3Vyc2UsbGltaXQpO3Jlc3VsdD1yZXN1bHQuY29uY2F0KGNoaWxkcyk7bGltaXQtPWNoaWxkcy5sZW5ndGg7aWYobGltaXQ8PTApYnJlYWt9fXJldHVybiByZXN1bHR9ZnVuY3Rpb24gZmluZE9uZUNoaWxkKHRlc3QsZWxlbXMpe2Zvcih2YXIgaT0wLGw9ZWxlbXMubGVuZ3RoO2k8bDtpKyspe2lmKHRlc3QoZWxlbXNbaV0pKXJldHVybiBlbGVtc1tpXX1yZXR1cm4gbnVsbH1mdW5jdGlvbiBmaW5kT25lKHRlc3QsZWxlbXMpe3ZhciBlbGVtPW51bGw7Zm9yKHZhciBpPTAsbD1lbGVtcy5sZW5ndGg7aTxsJiYhZWxlbTtpKyspe2lmKCFpc1RhZyhlbGVtc1tpXSkpe2NvbnRpbnVlfWVsc2UgaWYodGVzdChlbGVtc1tpXSkpe2VsZW09ZWxlbXNbaV19ZWxzZSBpZihlbGVtc1tpXS5jaGlsZHJlbi5sZW5ndGg+MCl7ZWxlbT1maW5kT25lKHRlc3QsZWxlbXNbaV0uY2hpbGRyZW4pfX1yZXR1cm4gZWxlbX1mdW5jdGlvbiBleGlzdHNPbmUodGVzdCxlbGVtcyl7Zm9yKHZhciBpPTAsbD1lbGVtcy5sZW5ndGg7aTxsO2krKyl7aWYoaXNUYWcoZWxlbXNbaV0pJiYodGVzdChlbGVtc1tpXSl8fGVsZW1zW2ldLmNoaWxkcmVuLmxlbmd0aD4wJiZleGlzdHNPbmUodGVzdCxlbGVtc1tpXS5jaGlsZHJlbikpKXtyZXR1cm4gdHJ1ZX19cmV0dXJuIGZhbHNlfWZ1bmN0aW9uIGZpbmRBbGwodGVzdCxlbGVtcyl7dmFyIHJlc3VsdD1bXTtmb3IodmFyIGk9MCxqPWVsZW1zLmxlbmd0aDtpPGo7aSsrKXtpZighaXNUYWcoZWxlbXNbaV0pKWNvbnRpbnVlO2lmKHRlc3QoZWxlbXNbaV0pKXJlc3VsdC5wdXNoKGVsZW1zW2ldKTtpZihlbGVtc1tpXS5jaGlsZHJlbi5sZW5ndGg+MCl7cmVzdWx0PXJlc3VsdC5jb25jYXQoZmluZEFsbCh0ZXN0LGVsZW1zW2ldLmNoaWxkcmVuKSl9fXJldHVybiByZXN1bHR9fSx7ZG9tZWxlbWVudHR5cGU6OX1dLDE4OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgRWxlbWVudFR5cGU9cmVxdWlyZShcImRvbWVsZW1lbnR0eXBlXCIpLGdldE91dGVySFRNTD1yZXF1aXJlKFwiZG9tLXNlcmlhbGl6ZXJcIiksaXNUYWc9RWxlbWVudFR5cGUuaXNUYWc7bW9kdWxlLmV4cG9ydHM9e2dldElubmVySFRNTDpnZXRJbm5lckhUTUwsZ2V0T3V0ZXJIVE1MOmdldE91dGVySFRNTCxnZXRUZXh0OmdldFRleHR9O2Z1bmN0aW9uIGdldElubmVySFRNTChlbGVtLG9wdHMpe3JldHVybiBlbGVtLmNoaWxkcmVuP2VsZW0uY2hpbGRyZW4ubWFwKGZ1bmN0aW9uKGVsZW0pe3JldHVybiBnZXRPdXRlckhUTUwoZWxlbSxvcHRzKX0pLmpvaW4oXCJcIik6XCJcIn1mdW5jdGlvbiBnZXRUZXh0KGVsZW0pe2lmKEFycmF5LmlzQXJyYXkoZWxlbSkpcmV0dXJuIGVsZW0ubWFwKGdldFRleHQpLmpvaW4oXCJcIik7aWYoaXNUYWcoZWxlbSl8fGVsZW0udHlwZT09PUVsZW1lbnRUeXBlLkNEQVRBKXJldHVybiBnZXRUZXh0KGVsZW0uY2hpbGRyZW4pO2lmKGVsZW0udHlwZT09PUVsZW1lbnRUeXBlLlRleHQpcmV0dXJuIGVsZW0uZGF0YTtyZXR1cm5cIlwifX0se1wiZG9tLXNlcmlhbGl6ZXJcIjo3LGRvbWVsZW1lbnR0eXBlOjl9XSwxOTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIGdldENoaWxkcmVuPWV4cG9ydHMuZ2V0Q2hpbGRyZW49ZnVuY3Rpb24oZWxlbSl7cmV0dXJuIGVsZW0uY2hpbGRyZW59O3ZhciBnZXRQYXJlbnQ9ZXhwb3J0cy5nZXRQYXJlbnQ9ZnVuY3Rpb24oZWxlbSl7cmV0dXJuIGVsZW0ucGFyZW50fTtleHBvcnRzLmdldFNpYmxpbmdzPWZ1bmN0aW9uKGVsZW0pe3ZhciBwYXJlbnQ9Z2V0UGFyZW50KGVsZW0pO3JldHVybiBwYXJlbnQ/Z2V0Q2hpbGRyZW4ocGFyZW50KTpbZWxlbV19O2V4cG9ydHMuZ2V0QXR0cmlidXRlVmFsdWU9ZnVuY3Rpb24oZWxlbSxuYW1lKXtyZXR1cm4gZWxlbS5hdHRyaWJzJiZlbGVtLmF0dHJpYnNbbmFtZV19O2V4cG9ydHMuaGFzQXR0cmliPWZ1bmN0aW9uKGVsZW0sbmFtZSl7cmV0dXJuISFlbGVtLmF0dHJpYnMmJmhhc093blByb3BlcnR5LmNhbGwoZWxlbS5hdHRyaWJzLG5hbWUpfTtleHBvcnRzLmdldE5hbWU9ZnVuY3Rpb24oZWxlbSl7cmV0dXJuIGVsZW0ubmFtZX19LHt9XSwyMDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIGVuY29kZT1yZXF1aXJlKFwiLi9saWIvZW5jb2RlLmpzXCIpLGRlY29kZT1yZXF1aXJlKFwiLi9saWIvZGVjb2RlLmpzXCIpO2V4cG9ydHMuZGVjb2RlPWZ1bmN0aW9uKGRhdGEsbGV2ZWwpe3JldHVybighbGV2ZWx8fGxldmVsPD0wP2RlY29kZS5YTUw6ZGVjb2RlLkhUTUwpKGRhdGEpfTtleHBvcnRzLmRlY29kZVN0cmljdD1mdW5jdGlvbihkYXRhLGxldmVsKXtyZXR1cm4oIWxldmVsfHxsZXZlbDw9MD9kZWNvZGUuWE1MOmRlY29kZS5IVE1MU3RyaWN0KShkYXRhKX07ZXhwb3J0cy5lbmNvZGU9ZnVuY3Rpb24oZGF0YSxsZXZlbCl7cmV0dXJuKCFsZXZlbHx8bGV2ZWw8PTA/ZW5jb2RlLlhNTDplbmNvZGUuSFRNTCkoZGF0YSl9O2V4cG9ydHMuZW5jb2RlWE1MPWVuY29kZS5YTUw7ZXhwb3J0cy5lbmNvZGVIVE1MND1leHBvcnRzLmVuY29kZUhUTUw1PWV4cG9ydHMuZW5jb2RlSFRNTD1lbmNvZGUuSFRNTDtleHBvcnRzLmRlY29kZVhNTD1leHBvcnRzLmRlY29kZVhNTFN0cmljdD1kZWNvZGUuWE1MO2V4cG9ydHMuZGVjb2RlSFRNTDQ9ZXhwb3J0cy5kZWNvZGVIVE1MNT1leHBvcnRzLmRlY29kZUhUTUw9ZGVjb2RlLkhUTUw7ZXhwb3J0cy5kZWNvZGVIVE1MNFN0cmljdD1leHBvcnRzLmRlY29kZUhUTUw1U3RyaWN0PWV4cG9ydHMuZGVjb2RlSFRNTFN0cmljdD1kZWNvZGUuSFRNTFN0cmljdDtleHBvcnRzLmVzY2FwZT1lbmNvZGUuZXNjYXBlfSx7XCIuL2xpYi9kZWNvZGUuanNcIjoyMSxcIi4vbGliL2VuY29kZS5qc1wiOjIzfV0sMjE6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciBlbnRpdHlNYXA9cmVxdWlyZShcIi4uL21hcHMvZW50aXRpZXMuanNvblwiKSxsZWdhY3lNYXA9cmVxdWlyZShcIi4uL21hcHMvbGVnYWN5Lmpzb25cIikseG1sTWFwPXJlcXVpcmUoXCIuLi9tYXBzL3htbC5qc29uXCIpLGRlY29kZUNvZGVQb2ludD1yZXF1aXJlKFwiLi9kZWNvZGVfY29kZXBvaW50LmpzXCIpO3ZhciBkZWNvZGVYTUxTdHJpY3Q9Z2V0U3RyaWN0RGVjb2Rlcih4bWxNYXApLGRlY29kZUhUTUxTdHJpY3Q9Z2V0U3RyaWN0RGVjb2RlcihlbnRpdHlNYXApO2Z1bmN0aW9uIGdldFN0cmljdERlY29kZXIobWFwKXt2YXIga2V5cz1PYmplY3Qua2V5cyhtYXApLmpvaW4oXCJ8XCIpLHJlcGxhY2U9Z2V0UmVwbGFjZXIobWFwKTtrZXlzKz1cInwjW3hYXVtcXFxcZGEtZkEtRl0rfCNcXFxcZCtcIjt2YXIgcmU9bmV3IFJlZ0V4cChcIiYoPzpcIitrZXlzK1wiKTtcIixcImdcIik7cmV0dXJuIGZ1bmN0aW9uKHN0cil7cmV0dXJuIFN0cmluZyhzdHIpLnJlcGxhY2UocmUscmVwbGFjZSl9fXZhciBkZWNvZGVIVE1MPWZ1bmN0aW9uKCl7dmFyIGxlZ2FjeT1PYmplY3Qua2V5cyhsZWdhY3lNYXApLnNvcnQoc29ydGVyKTt2YXIga2V5cz1PYmplY3Qua2V5cyhlbnRpdHlNYXApLnNvcnQoc29ydGVyKTtmb3IodmFyIGk9MCxqPTA7aTxrZXlzLmxlbmd0aDtpKyspe2lmKGxlZ2FjeVtqXT09PWtleXNbaV0pe2tleXNbaV0rPVwiOz9cIjtqKyt9ZWxzZXtrZXlzW2ldKz1cIjtcIn19dmFyIHJlPW5ldyBSZWdFeHAoXCImKD86XCIra2V5cy5qb2luKFwifFwiKStcInwjW3hYXVtcXFxcZGEtZkEtRl0rOz98I1xcXFxkKzs/KVwiLFwiZ1wiKSxyZXBsYWNlPWdldFJlcGxhY2VyKGVudGl0eU1hcCk7ZnVuY3Rpb24gcmVwbGFjZXIoc3RyKXtpZihzdHIuc3Vic3RyKC0xKSE9PVwiO1wiKXN0cis9XCI7XCI7cmV0dXJuIHJlcGxhY2Uoc3RyKX1yZXR1cm4gZnVuY3Rpb24oc3RyKXtyZXR1cm4gU3RyaW5nKHN0cikucmVwbGFjZShyZSxyZXBsYWNlcil9fSgpO2Z1bmN0aW9uIHNvcnRlcihhLGIpe3JldHVybiBhPGI/MTotMX1mdW5jdGlvbiBnZXRSZXBsYWNlcihtYXApe3JldHVybiBmdW5jdGlvbiByZXBsYWNlKHN0cil7aWYoc3RyLmNoYXJBdCgxKT09PVwiI1wiKXtpZihzdHIuY2hhckF0KDIpPT09XCJYXCJ8fHN0ci5jaGFyQXQoMik9PT1cInhcIil7cmV0dXJuIGRlY29kZUNvZGVQb2ludChwYXJzZUludChzdHIuc3Vic3RyKDMpLDE2KSl9cmV0dXJuIGRlY29kZUNvZGVQb2ludChwYXJzZUludChzdHIuc3Vic3RyKDIpLDEwKSl9cmV0dXJuIG1hcFtzdHIuc2xpY2UoMSwtMSldO1xufX1tb2R1bGUuZXhwb3J0cz17WE1MOmRlY29kZVhNTFN0cmljdCxIVE1MOmRlY29kZUhUTUwsSFRNTFN0cmljdDpkZWNvZGVIVE1MU3RyaWN0fX0se1wiLi4vbWFwcy9lbnRpdGllcy5qc29uXCI6MjUsXCIuLi9tYXBzL2xlZ2FjeS5qc29uXCI6MjYsXCIuLi9tYXBzL3htbC5qc29uXCI6MjcsXCIuL2RlY29kZV9jb2RlcG9pbnQuanNcIjoyMn1dLDIyOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgZGVjb2RlTWFwPXJlcXVpcmUoXCIuLi9tYXBzL2RlY29kZS5qc29uXCIpO21vZHVsZS5leHBvcnRzPWRlY29kZUNvZGVQb2ludDtmdW5jdGlvbiBkZWNvZGVDb2RlUG9pbnQoY29kZVBvaW50KXtpZihjb2RlUG9pbnQ+PTU1Mjk2JiZjb2RlUG9pbnQ8PTU3MzQzfHxjb2RlUG9pbnQ+MTExNDExMSl7cmV0dXJuXCLvv71cIn1pZihjb2RlUG9pbnQgaW4gZGVjb2RlTWFwKXtjb2RlUG9pbnQ9ZGVjb2RlTWFwW2NvZGVQb2ludF19dmFyIG91dHB1dD1cIlwiO2lmKGNvZGVQb2ludD42NTUzNSl7Y29kZVBvaW50LT02NTUzNjtvdXRwdXQrPVN0cmluZy5mcm9tQ2hhckNvZGUoY29kZVBvaW50Pj4+MTAmMTAyM3w1NTI5Nik7Y29kZVBvaW50PTU2MzIwfGNvZGVQb2ludCYxMDIzfW91dHB1dCs9U3RyaW5nLmZyb21DaGFyQ29kZShjb2RlUG9pbnQpO3JldHVybiBvdXRwdXR9fSx7XCIuLi9tYXBzL2RlY29kZS5qc29uXCI6MjR9XSwyMzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIGludmVyc2VYTUw9Z2V0SW52ZXJzZU9iaihyZXF1aXJlKFwiLi4vbWFwcy94bWwuanNvblwiKSkseG1sUmVwbGFjZXI9Z2V0SW52ZXJzZVJlcGxhY2VyKGludmVyc2VYTUwpO2V4cG9ydHMuWE1MPWdldEludmVyc2UoaW52ZXJzZVhNTCx4bWxSZXBsYWNlcik7dmFyIGludmVyc2VIVE1MPWdldEludmVyc2VPYmoocmVxdWlyZShcIi4uL21hcHMvZW50aXRpZXMuanNvblwiKSksaHRtbFJlcGxhY2VyPWdldEludmVyc2VSZXBsYWNlcihpbnZlcnNlSFRNTCk7ZXhwb3J0cy5IVE1MPWdldEludmVyc2UoaW52ZXJzZUhUTUwsaHRtbFJlcGxhY2VyKTtmdW5jdGlvbiBnZXRJbnZlcnNlT2JqKG9iail7cmV0dXJuIE9iamVjdC5rZXlzKG9iaikuc29ydCgpLnJlZHVjZShmdW5jdGlvbihpbnZlcnNlLG5hbWUpe2ludmVyc2Vbb2JqW25hbWVdXT1cIiZcIituYW1lK1wiO1wiO3JldHVybiBpbnZlcnNlfSx7fSl9ZnVuY3Rpb24gZ2V0SW52ZXJzZVJlcGxhY2VyKGludmVyc2Upe3ZhciBzaW5nbGU9W10sbXVsdGlwbGU9W107T2JqZWN0LmtleXMoaW52ZXJzZSkuZm9yRWFjaChmdW5jdGlvbihrKXtpZihrLmxlbmd0aD09PTEpe3NpbmdsZS5wdXNoKFwiXFxcXFwiK2spfWVsc2V7bXVsdGlwbGUucHVzaChrKX19KTttdWx0aXBsZS51bnNoaWZ0KFwiW1wiK3NpbmdsZS5qb2luKFwiXCIpK1wiXVwiKTtyZXR1cm4gbmV3IFJlZ0V4cChtdWx0aXBsZS5qb2luKFwifFwiKSxcImdcIil9dmFyIHJlX25vbkFTQ0lJPS9bXlxcMC1cXHg3Rl0vZyxyZV9hc3RyYWxTeW1ib2xzPS9bXFx1RDgwMC1cXHVEQkZGXVtcXHVEQzAwLVxcdURGRkZdL2c7ZnVuY3Rpb24gc2luZ2xlQ2hhclJlcGxhY2VyKGMpe3JldHVyblwiJiN4XCIrYy5jaGFyQ29kZUF0KDApLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpK1wiO1wifWZ1bmN0aW9uIGFzdHJhbFJlcGxhY2VyKGMpe3ZhciBoaWdoPWMuY2hhckNvZGVBdCgwKTt2YXIgbG93PWMuY2hhckNvZGVBdCgxKTt2YXIgY29kZVBvaW50PShoaWdoLTU1Mjk2KSoxMDI0K2xvdy01NjMyMCs2NTUzNjtyZXR1cm5cIiYjeFwiK2NvZGVQb2ludC50b1N0cmluZygxNikudG9VcHBlckNhc2UoKStcIjtcIn1mdW5jdGlvbiBnZXRJbnZlcnNlKGludmVyc2UscmUpe2Z1bmN0aW9uIGZ1bmMobmFtZSl7cmV0dXJuIGludmVyc2VbbmFtZV19cmV0dXJuIGZ1bmN0aW9uKGRhdGEpe3JldHVybiBkYXRhLnJlcGxhY2UocmUsZnVuYykucmVwbGFjZShyZV9hc3RyYWxTeW1ib2xzLGFzdHJhbFJlcGxhY2VyKS5yZXBsYWNlKHJlX25vbkFTQ0lJLHNpbmdsZUNoYXJSZXBsYWNlcil9fXZhciByZV94bWxDaGFycz1nZXRJbnZlcnNlUmVwbGFjZXIoaW52ZXJzZVhNTCk7ZnVuY3Rpb24gZXNjYXBlWE1MKGRhdGEpe3JldHVybiBkYXRhLnJlcGxhY2UocmVfeG1sQ2hhcnMsc2luZ2xlQ2hhclJlcGxhY2VyKS5yZXBsYWNlKHJlX2FzdHJhbFN5bWJvbHMsYXN0cmFsUmVwbGFjZXIpLnJlcGxhY2UocmVfbm9uQVNDSUksc2luZ2xlQ2hhclJlcGxhY2VyKX1leHBvcnRzLmVzY2FwZT1lc2NhcGVYTUx9LHtcIi4uL21hcHMvZW50aXRpZXMuanNvblwiOjI1LFwiLi4vbWFwcy94bWwuanNvblwiOjI3fV0sMjQ6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe21vZHVsZS5leHBvcnRzPXswOjY1NTMzLDEyODo4MzY0LDEzMDo4MjE4LDEzMTo0MDIsMTMyOjgyMjIsMTMzOjgyMzAsMTM0OjgyMjQsMTM1OjgyMjUsMTM2OjcxMCwxMzc6ODI0MCwxMzg6MzUyLDEzOTo4MjQ5LDE0MDozMzgsMTQyOjM4MSwxNDU6ODIxNiwxNDY6ODIxNywxNDc6ODIyMCwxNDg6ODIyMSwxNDk6ODIyNiwxNTA6ODIxMSwxNTE6ODIxMiwxNTI6NzMyLDE1Mzo4NDgyLDE1NDozNTMsMTU1OjgyNTAsMTU2OjMzOSwxNTg6MzgyLDE1OTozNzZ9fSx7fV0sMjU6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe21vZHVsZS5leHBvcnRzPXtBYWN1dGU6XCLDgVwiLGFhY3V0ZTpcIsOhXCIsQWJyZXZlOlwixIJcIixhYnJldmU6XCLEg1wiLGFjOlwi4oi+XCIsYWNkOlwi4oi/XCIsYWNFOlwi4oi+zLNcIixBY2lyYzpcIsOCXCIsYWNpcmM6XCLDolwiLGFjdXRlOlwiwrRcIixBY3k6XCLQkFwiLGFjeTpcItCwXCIsQUVsaWc6XCLDhlwiLGFlbGlnOlwiw6ZcIixhZjpcIuKBoVwiLEFmcjpcIvCdlIRcIixhZnI6XCLwnZSeXCIsQWdyYXZlOlwiw4BcIixhZ3JhdmU6XCLDoFwiLGFsZWZzeW06XCLihLVcIixhbGVwaDpcIuKEtVwiLEFscGhhOlwizpFcIixhbHBoYTpcIs6xXCIsQW1hY3I6XCLEgFwiLGFtYWNyOlwixIFcIixhbWFsZzpcIuKov1wiLGFtcDpcIiZcIixBTVA6XCImXCIsYW5kYW5kOlwi4qmVXCIsQW5kOlwi4qmTXCIsYW5kOlwi4oinXCIsYW5kZDpcIuKpnFwiLGFuZHNsb3BlOlwi4qmYXCIsYW5kdjpcIuKpmlwiLGFuZzpcIuKIoFwiLGFuZ2U6XCLipqRcIixhbmdsZTpcIuKIoFwiLGFuZ21zZGFhOlwi4qaoXCIsYW5nbXNkYWI6XCLipqlcIixhbmdtc2RhYzpcIuKmqlwiLGFuZ21zZGFkOlwi4qarXCIsYW5nbXNkYWU6XCLipqxcIixhbmdtc2RhZjpcIuKmrVwiLGFuZ21zZGFnOlwi4qauXCIsYW5nbXNkYWg6XCLipq9cIixhbmdtc2Q6XCLiiKFcIixhbmdydDpcIuKIn1wiLGFuZ3J0dmI6XCLiir5cIixhbmdydHZiZDpcIuKmnVwiLGFuZ3NwaDpcIuKIolwiLGFuZ3N0Olwiw4VcIixhbmd6YXJyOlwi4o28XCIsQW9nb246XCLEhFwiLGFvZ29uOlwixIVcIixBb3BmOlwi8J2UuFwiLGFvcGY6XCLwnZWSXCIsYXBhY2lyOlwi4qmvXCIsYXA6XCLiiYhcIixhcEU6XCLiqbBcIixhcGU6XCLiiYpcIixhcGlkOlwi4omLXCIsYXBvczpcIidcIixBcHBseUZ1bmN0aW9uOlwi4oGhXCIsYXBwcm94Olwi4omIXCIsYXBwcm94ZXE6XCLiiYpcIixBcmluZzpcIsOFXCIsYXJpbmc6XCLDpVwiLEFzY3I6XCLwnZKcXCIsYXNjcjpcIvCdkrZcIixBc3NpZ246XCLiiZRcIixhc3Q6XCIqXCIsYXN5bXA6XCLiiYhcIixhc3ltcGVxOlwi4omNXCIsQXRpbGRlOlwiw4NcIixhdGlsZGU6XCLDo1wiLEF1bWw6XCLDhFwiLGF1bWw6XCLDpFwiLGF3Y29uaW50Olwi4oizXCIsYXdpbnQ6XCLiqJFcIixiYWNrY29uZzpcIuKJjFwiLGJhY2tlcHNpbG9uOlwiz7ZcIixiYWNrcHJpbWU6XCLigLVcIixiYWNrc2ltOlwi4oi9XCIsYmFja3NpbWVxOlwi4ouNXCIsQmFja3NsYXNoOlwi4oiWXCIsQmFydjpcIuKrp1wiLGJhcnZlZTpcIuKKvVwiLGJhcndlZDpcIuKMhVwiLEJhcndlZDpcIuKMhlwiLGJhcndlZGdlOlwi4oyFXCIsYmJyazpcIuKOtVwiLGJicmt0YnJrOlwi4o62XCIsYmNvbmc6XCLiiYxcIixCY3k6XCLQkVwiLGJjeTpcItCxXCIsYmRxdW86XCLigJ5cIixiZWNhdXM6XCLiiLVcIixiZWNhdXNlOlwi4oi1XCIsQmVjYXVzZTpcIuKItVwiLGJlbXB0eXY6XCLiprBcIixiZXBzaTpcIs+2XCIsYmVybm91Olwi4oSsXCIsQmVybm91bGxpczpcIuKErFwiLEJldGE6XCLOklwiLGJldGE6XCLOslwiLGJldGg6XCLihLZcIixiZXR3ZWVuOlwi4omsXCIsQmZyOlwi8J2UhVwiLGJmcjpcIvCdlJ9cIixiaWdjYXA6XCLii4JcIixiaWdjaXJjOlwi4pevXCIsYmlnY3VwOlwi4ouDXCIsYmlnb2RvdDpcIuKogFwiLGJpZ29wbHVzOlwi4qiBXCIsYmlnb3RpbWVzOlwi4qiCXCIsYmlnc3FjdXA6XCLiqIZcIixiaWdzdGFyOlwi4piFXCIsYmlndHJpYW5nbGVkb3duOlwi4pa9XCIsYmlndHJpYW5nbGV1cDpcIuKWs1wiLGJpZ3VwbHVzOlwi4qiEXCIsYmlndmVlOlwi4ouBXCIsYmlnd2VkZ2U6XCLii4BcIixia2Fyb3c6XCLipI1cIixibGFja2xvemVuZ2U6XCLip6tcIixibGFja3NxdWFyZTpcIuKWqlwiLGJsYWNrdHJpYW5nbGU6XCLilrRcIixibGFja3RyaWFuZ2xlZG93bjpcIuKWvlwiLGJsYWNrdHJpYW5nbGVsZWZ0Olwi4peCXCIsYmxhY2t0cmlhbmdsZXJpZ2h0Olwi4pa4XCIsYmxhbms6XCLikKNcIixibGsxMjpcIuKWklwiLGJsazE0Olwi4paRXCIsYmxrMzQ6XCLilpNcIixibG9jazpcIuKWiFwiLGJuZTpcIj3ig6VcIixibmVxdWl2Olwi4omh4oOlXCIsYk5vdDpcIuKrrVwiLGJub3Q6XCLijJBcIixCb3BmOlwi8J2UuVwiLGJvcGY6XCLwnZWTXCIsYm90Olwi4oqlXCIsYm90dG9tOlwi4oqlXCIsYm93dGllOlwi4ouIXCIsYm94Ym94Olwi4qeJXCIsYm94ZGw6XCLilJBcIixib3hkTDpcIuKVlVwiLGJveERsOlwi4pWWXCIsYm94REw6XCLilZdcIixib3hkcjpcIuKUjFwiLGJveGRSOlwi4pWSXCIsYm94RHI6XCLilZNcIixib3hEUjpcIuKVlFwiLGJveGg6XCLilIBcIixib3hIOlwi4pWQXCIsYm94aGQ6XCLilKxcIixib3hIZDpcIuKVpFwiLGJveGhEOlwi4pWlXCIsYm94SEQ6XCLilaZcIixib3hodTpcIuKUtFwiLGJveEh1Olwi4pWnXCIsYm94aFU6XCLilahcIixib3hIVTpcIuKVqVwiLGJveG1pbnVzOlwi4oqfXCIsYm94cGx1czpcIuKKnlwiLGJveHRpbWVzOlwi4oqgXCIsYm94dWw6XCLilJhcIixib3h1TDpcIuKVm1wiLGJveFVsOlwi4pWcXCIsYm94VUw6XCLilZ1cIixib3h1cjpcIuKUlFwiLGJveHVSOlwi4pWYXCIsYm94VXI6XCLilZlcIixib3hVUjpcIuKVmlwiLGJveHY6XCLilIJcIixib3hWOlwi4pWRXCIsYm94dmg6XCLilLxcIixib3h2SDpcIuKVqlwiLGJveFZoOlwi4pWrXCIsYm94Vkg6XCLilaxcIixib3h2bDpcIuKUpFwiLGJveHZMOlwi4pWhXCIsYm94Vmw6XCLilaJcIixib3hWTDpcIuKVo1wiLGJveHZyOlwi4pScXCIsYm94dlI6XCLilZ5cIixib3hWcjpcIuKVn1wiLGJveFZSOlwi4pWgXCIsYnByaW1lOlwi4oC1XCIsYnJldmU6XCLLmFwiLEJyZXZlOlwiy5hcIixicnZiYXI6XCLCplwiLGJzY3I6XCLwnZK3XCIsQnNjcjpcIuKErFwiLGJzZW1pOlwi4oGPXCIsYnNpbTpcIuKIvVwiLGJzaW1lOlwi4ouNXCIsYnNvbGI6XCLip4VcIixic29sOlwiXFxcXFwiLGJzb2xoc3ViOlwi4p+IXCIsYnVsbDpcIuKAolwiLGJ1bGxldDpcIuKAolwiLGJ1bXA6XCLiiY5cIixidW1wRTpcIuKqrlwiLGJ1bXBlOlwi4omPXCIsQnVtcGVxOlwi4omOXCIsYnVtcGVxOlwi4omPXCIsQ2FjdXRlOlwixIZcIixjYWN1dGU6XCLEh1wiLGNhcGFuZDpcIuKphFwiLGNhcGJyY3VwOlwi4qmJXCIsY2FwY2FwOlwi4qmLXCIsY2FwOlwi4oipXCIsQ2FwOlwi4ouSXCIsY2FwY3VwOlwi4qmHXCIsY2FwZG90Olwi4qmAXCIsQ2FwaXRhbERpZmZlcmVudGlhbEQ6XCLihYVcIixjYXBzOlwi4oip77iAXCIsY2FyZXQ6XCLigYFcIixjYXJvbjpcIsuHXCIsQ2F5bGV5czpcIuKErVwiLGNjYXBzOlwi4qmNXCIsQ2Nhcm9uOlwixIxcIixjY2Fyb246XCLEjVwiLENjZWRpbDpcIsOHXCIsY2NlZGlsOlwiw6dcIixDY2lyYzpcIsSIXCIsY2NpcmM6XCLEiVwiLENjb25pbnQ6XCLiiLBcIixjY3VwczpcIuKpjFwiLGNjdXBzc206XCLiqZBcIixDZG90OlwixIpcIixjZG90OlwixItcIixjZWRpbDpcIsK4XCIsQ2VkaWxsYTpcIsK4XCIsY2VtcHR5djpcIuKmslwiLGNlbnQ6XCLColwiLGNlbnRlcmRvdDpcIsK3XCIsQ2VudGVyRG90OlwiwrdcIixjZnI6XCLwnZSgXCIsQ2ZyOlwi4oStXCIsQ0hjeTpcItCnXCIsY2hjeTpcItGHXCIsY2hlY2s6XCLinJNcIixjaGVja21hcms6XCLinJNcIixDaGk6XCLOp1wiLGNoaTpcIs+HXCIsY2lyYzpcIsuGXCIsY2lyY2VxOlwi4omXXCIsY2lyY2xlYXJyb3dsZWZ0Olwi4oa6XCIsY2lyY2xlYXJyb3dyaWdodDpcIuKGu1wiLGNpcmNsZWRhc3Q6XCLiiptcIixjaXJjbGVkY2lyYzpcIuKKmlwiLGNpcmNsZWRkYXNoOlwi4oqdXCIsQ2lyY2xlRG90Olwi4oqZXCIsY2lyY2xlZFI6XCLCrlwiLGNpcmNsZWRTOlwi4pOIXCIsQ2lyY2xlTWludXM6XCLiipZcIixDaXJjbGVQbHVzOlwi4oqVXCIsQ2lyY2xlVGltZXM6XCLiipdcIixjaXI6XCLil4tcIixjaXJFOlwi4qeDXCIsY2lyZTpcIuKJl1wiLGNpcmZuaW50Olwi4qiQXCIsY2lybWlkOlwi4quvXCIsY2lyc2NpcjpcIuKnglwiLENsb2Nrd2lzZUNvbnRvdXJJbnRlZ3JhbDpcIuKIslwiLENsb3NlQ3VybHlEb3VibGVRdW90ZTpcIuKAnVwiLENsb3NlQ3VybHlRdW90ZTpcIuKAmVwiLGNsdWJzOlwi4pmjXCIsY2x1YnN1aXQ6XCLimaNcIixjb2xvbjpcIjpcIixDb2xvbjpcIuKIt1wiLENvbG9uZTpcIuKptFwiLGNvbG9uZTpcIuKJlFwiLGNvbG9uZXE6XCLiiZRcIixjb21tYTpcIixcIixjb21tYXQ6XCJAXCIsY29tcDpcIuKIgVwiLGNvbXBmbjpcIuKImFwiLGNvbXBsZW1lbnQ6XCLiiIFcIixjb21wbGV4ZXM6XCLihIJcIixjb25nOlwi4omFXCIsY29uZ2RvdDpcIuKprVwiLENvbmdydWVudDpcIuKJoVwiLGNvbmludDpcIuKIrlwiLENvbmludDpcIuKIr1wiLENvbnRvdXJJbnRlZ3JhbDpcIuKIrlwiLGNvcGY6XCLwnZWUXCIsQ29wZjpcIuKEglwiLGNvcHJvZDpcIuKIkFwiLENvcHJvZHVjdDpcIuKIkFwiLGNvcHk6XCLCqVwiLENPUFk6XCLCqVwiLGNvcHlzcjpcIuKEl1wiLENvdW50ZXJDbG9ja3dpc2VDb250b3VySW50ZWdyYWw6XCLiiLNcIixjcmFycjpcIuKGtVwiLGNyb3NzOlwi4pyXXCIsQ3Jvc3M6XCLiqK9cIixDc2NyOlwi8J2SnlwiLGNzY3I6XCLwnZK4XCIsY3N1YjpcIuKrj1wiLGNzdWJlOlwi4quRXCIsY3N1cDpcIuKrkFwiLGNzdXBlOlwi4quSXCIsY3Rkb3Q6XCLii69cIixjdWRhcnJsOlwi4qS4XCIsY3VkYXJycjpcIuKktVwiLGN1ZXByOlwi4oueXCIsY3Vlc2M6XCLii59cIixjdWxhcnI6XCLihrZcIixjdWxhcnJwOlwi4qS9XCIsY3VwYnJjYXA6XCLiqYhcIixjdXBjYXA6XCLiqYZcIixDdXBDYXA6XCLiiY1cIixjdXA6XCLiiKpcIixDdXA6XCLii5NcIixjdXBjdXA6XCLiqYpcIixjdXBkb3Q6XCLiio1cIixjdXBvcjpcIuKphVwiLGN1cHM6XCLiiKrvuIBcIixjdXJhcnI6XCLihrdcIixjdXJhcnJtOlwi4qS8XCIsY3VybHllcXByZWM6XCLii55cIixjdXJseWVxc3VjYzpcIuKLn1wiLGN1cmx5dmVlOlwi4ouOXCIsY3VybHl3ZWRnZTpcIuKLj1wiLGN1cnJlbjpcIsKkXCIsY3VydmVhcnJvd2xlZnQ6XCLihrZcIixjdXJ2ZWFycm93cmlnaHQ6XCLihrdcIixjdXZlZTpcIuKLjlwiLGN1d2VkOlwi4ouPXCIsY3djb25pbnQ6XCLiiLJcIixjd2ludDpcIuKIsVwiLGN5bGN0eTpcIuKMrVwiLGRhZ2dlcjpcIuKAoFwiLERhZ2dlcjpcIuKAoVwiLGRhbGV0aDpcIuKEuFwiLGRhcnI6XCLihpNcIixEYXJyOlwi4oahXCIsZEFycjpcIuKHk1wiLGRhc2g6XCLigJBcIixEYXNodjpcIuKrpFwiLGRhc2h2Olwi4oqjXCIsZGJrYXJvdzpcIuKkj1wiLGRibGFjOlwiy51cIixEY2Fyb246XCLEjlwiLGRjYXJvbjpcIsSPXCIsRGN5Olwi0JRcIixkY3k6XCLQtFwiLGRkYWdnZXI6XCLigKFcIixkZGFycjpcIuKHilwiLEREOlwi4oWFXCIsZGQ6XCLihYZcIixERG90cmFoZDpcIuKkkVwiLGRkb3RzZXE6XCLiqbdcIixkZWc6XCLCsFwiLERlbDpcIuKIh1wiLERlbHRhOlwizpRcIixkZWx0YTpcIs60XCIsZGVtcHR5djpcIuKmsVwiLGRmaXNodDpcIuKlv1wiLERmcjpcIvCdlIdcIixkZnI6XCLwnZShXCIsZEhhcjpcIuKlpVwiLGRoYXJsOlwi4oeDXCIsZGhhcnI6XCLih4JcIixEaWFjcml0aWNhbEFjdXRlOlwiwrRcIixEaWFjcml0aWNhbERvdDpcIsuZXCIsRGlhY3JpdGljYWxEb3VibGVBY3V0ZTpcIsudXCIsRGlhY3JpdGljYWxHcmF2ZTpcImBcIixEaWFjcml0aWNhbFRpbGRlOlwiy5xcIixkaWFtOlwi4ouEXCIsZGlhbW9uZDpcIuKLhFwiLERpYW1vbmQ6XCLii4RcIixkaWFtb25kc3VpdDpcIuKZplwiLGRpYW1zOlwi4pmmXCIsZGllOlwiwqhcIixEaWZmZXJlbnRpYWxEOlwi4oWGXCIsZGlnYW1tYTpcIs+dXCIsZGlzaW46XCLii7JcIixkaXY6XCLDt1wiLGRpdmlkZTpcIsO3XCIsZGl2aWRlb250aW1lczpcIuKLh1wiLGRpdm9ueDpcIuKLh1wiLERKY3k6XCLQglwiLGRqY3k6XCLRklwiLGRsY29ybjpcIuKMnlwiLGRsY3JvcDpcIuKMjVwiLGRvbGxhcjpcIiRcIixEb3BmOlwi8J2Uu1wiLGRvcGY6XCLwnZWVXCIsRG90OlwiwqhcIixkb3Q6XCLLmVwiLERvdERvdDpcIuKDnFwiLGRvdGVxOlwi4omQXCIsZG90ZXFkb3Q6XCLiiZFcIixEb3RFcXVhbDpcIuKJkFwiLGRvdG1pbnVzOlwi4oi4XCIsZG90cGx1czpcIuKIlFwiLGRvdHNxdWFyZTpcIuKKoVwiLGRvdWJsZWJhcndlZGdlOlwi4oyGXCIsRG91YmxlQ29udG91ckludGVncmFsOlwi4oivXCIsRG91YmxlRG90OlwiwqhcIixEb3VibGVEb3duQXJyb3c6XCLih5NcIixEb3VibGVMZWZ0QXJyb3c6XCLih5BcIixEb3VibGVMZWZ0UmlnaHRBcnJvdzpcIuKHlFwiLERvdWJsZUxlZnRUZWU6XCLiq6RcIixEb3VibGVMb25nTGVmdEFycm93Olwi4p+4XCIsRG91YmxlTG9uZ0xlZnRSaWdodEFycm93Olwi4p+6XCIsRG91YmxlTG9uZ1JpZ2h0QXJyb3c6XCLin7lcIixEb3VibGVSaWdodEFycm93Olwi4oeSXCIsRG91YmxlUmlnaHRUZWU6XCLiiqhcIixEb3VibGVVcEFycm93Olwi4oeRXCIsRG91YmxlVXBEb3duQXJyb3c6XCLih5VcIixEb3VibGVWZXJ0aWNhbEJhcjpcIuKIpVwiLERvd25BcnJvd0JhcjpcIuKkk1wiLGRvd25hcnJvdzpcIuKGk1wiLERvd25BcnJvdzpcIuKGk1wiLERvd25hcnJvdzpcIuKHk1wiLERvd25BcnJvd1VwQXJyb3c6XCLih7VcIixEb3duQnJldmU6XCLMkVwiLGRvd25kb3duYXJyb3dzOlwi4oeKXCIsZG93bmhhcnBvb25sZWZ0Olwi4oeDXCIsZG93bmhhcnBvb25yaWdodDpcIuKHglwiLERvd25MZWZ0UmlnaHRWZWN0b3I6XCLipZBcIixEb3duTGVmdFRlZVZlY3RvcjpcIuKlnlwiLERvd25MZWZ0VmVjdG9yQmFyOlwi4qWWXCIsRG93bkxlZnRWZWN0b3I6XCLihr1cIixEb3duUmlnaHRUZWVWZWN0b3I6XCLipZ9cIixEb3duUmlnaHRWZWN0b3JCYXI6XCLipZdcIixEb3duUmlnaHRWZWN0b3I6XCLih4FcIixEb3duVGVlQXJyb3c6XCLihqdcIixEb3duVGVlOlwi4oqkXCIsZHJia2Fyb3c6XCLipJBcIixkcmNvcm46XCLijJ9cIixkcmNyb3A6XCLijIxcIixEc2NyOlwi8J2Sn1wiLGRzY3I6XCLwnZK5XCIsRFNjeTpcItCFXCIsZHNjeTpcItGVXCIsZHNvbDpcIuKntlwiLERzdHJvazpcIsSQXCIsZHN0cm9rOlwixJFcIixkdGRvdDpcIuKLsVwiLGR0cmk6XCLilr9cIixkdHJpZjpcIuKWvlwiLGR1YXJyOlwi4oe1XCIsZHVoYXI6XCLipa9cIixkd2FuZ2xlOlwi4qamXCIsRFpjeTpcItCPXCIsZHpjeTpcItGfXCIsZHppZ3JhcnI6XCLin79cIixFYWN1dGU6XCLDiVwiLGVhY3V0ZTpcIsOpXCIsZWFzdGVyOlwi4qmuXCIsRWNhcm9uOlwixJpcIixlY2Fyb246XCLEm1wiLEVjaXJjOlwiw4pcIixlY2lyYzpcIsOqXCIsZWNpcjpcIuKJllwiLGVjb2xvbjpcIuKJlVwiLEVjeTpcItCtXCIsZWN5Olwi0Y1cIixlRERvdDpcIuKpt1wiLEVkb3Q6XCLEllwiLGVkb3Q6XCLEl1wiLGVEb3Q6XCLiiZFcIixlZTpcIuKFh1wiLGVmRG90Olwi4omSXCIsRWZyOlwi8J2UiFwiLGVmcjpcIvCdlKJcIixlZzpcIuKqmlwiLEVncmF2ZTpcIsOIXCIsZWdyYXZlOlwiw6hcIixlZ3M6XCLiqpZcIixlZ3Nkb3Q6XCLiqphcIixlbDpcIuKqmVwiLEVsZW1lbnQ6XCLiiIhcIixlbGludGVyczpcIuKPp1wiLGVsbDpcIuKEk1wiLGVsczpcIuKqlVwiLGVsc2RvdDpcIuKql1wiLEVtYWNyOlwixJJcIixlbWFjcjpcIsSTXCIsZW1wdHk6XCLiiIVcIixlbXB0eXNldDpcIuKIhVwiLEVtcHR5U21hbGxTcXVhcmU6XCLil7tcIixlbXB0eXY6XCLiiIVcIixFbXB0eVZlcnlTbWFsbFNxdWFyZTpcIuKWq1wiLGVtc3AxMzpcIuKAhFwiLGVtc3AxNDpcIuKAhVwiLGVtc3A6XCLigINcIixFTkc6XCLFilwiLGVuZzpcIsWLXCIsZW5zcDpcIuKAglwiLEVvZ29uOlwixJhcIixlb2dvbjpcIsSZXCIsRW9wZjpcIvCdlLxcIixlb3BmOlwi8J2VllwiLGVwYXI6XCLii5VcIixlcGFyc2w6XCLip6NcIixlcGx1czpcIuKpsVwiLGVwc2k6XCLOtVwiLEVwc2lsb246XCLOlVwiLGVwc2lsb246XCLOtVwiLGVwc2l2Olwiz7VcIixlcWNpcmM6XCLiiZZcIixlcWNvbG9uOlwi4omVXCIsZXFzaW06XCLiiYJcIixlcXNsYW50Z3RyOlwi4qqWXCIsZXFzbGFudGxlc3M6XCLiqpVcIixFcXVhbDpcIuKptVwiLGVxdWFsczpcIj1cIixFcXVhbFRpbGRlOlwi4omCXCIsZXF1ZXN0Olwi4omfXCIsRXF1aWxpYnJpdW06XCLih4xcIixlcXVpdjpcIuKJoVwiLGVxdWl2REQ6XCLiqbhcIixlcXZwYXJzbDpcIuKnpVwiLGVyYXJyOlwi4qWxXCIsZXJEb3Q6XCLiiZNcIixlc2NyOlwi4oSvXCIsRXNjcjpcIuKEsFwiLGVzZG90Olwi4omQXCIsRXNpbTpcIuKps1wiLGVzaW06XCLiiYJcIixFdGE6XCLOl1wiLGV0YTpcIs63XCIsRVRIOlwiw5BcIixldGg6XCLDsFwiLEV1bWw6XCLDi1wiLGV1bWw6XCLDq1wiLGV1cm86XCLigqxcIixleGNsOlwiIVwiLGV4aXN0Olwi4oiDXCIsRXhpc3RzOlwi4oiDXCIsZXhwZWN0YXRpb246XCLihLBcIixleHBvbmVudGlhbGU6XCLihYdcIixFeHBvbmVudGlhbEU6XCLihYdcIixmYWxsaW5nZG90c2VxOlwi4omSXCIsRmN5Olwi0KRcIixmY3k6XCLRhFwiLGZlbWFsZTpcIuKZgFwiLGZmaWxpZzpcIu+sg1wiLGZmbGlnOlwi76yAXCIsZmZsbGlnOlwi76yEXCIsRmZyOlwi8J2UiVwiLGZmcjpcIvCdlKNcIixmaWxpZzpcIu+sgVwiLEZpbGxlZFNtYWxsU3F1YXJlOlwi4pe8XCIsRmlsbGVkVmVyeVNtYWxsU3F1YXJlOlwi4paqXCIsZmpsaWc6XCJmalwiLGZsYXQ6XCLima1cIixmbGxpZzpcIu+sglwiLGZsdG5zOlwi4paxXCIsZm5vZjpcIsaSXCIsRm9wZjpcIvCdlL1cIixmb3BmOlwi8J2Vl1wiLGZvcmFsbDpcIuKIgFwiLEZvckFsbDpcIuKIgFwiLGZvcms6XCLii5RcIixmb3JrdjpcIuKrmVwiLEZvdXJpZXJ0cmY6XCLihLFcIixmcGFydGludDpcIuKojVwiLGZyYWMxMjpcIsK9XCIsZnJhYzEzOlwi4oWTXCIsZnJhYzE0OlwiwrxcIixmcmFjMTU6XCLihZVcIixmcmFjMTY6XCLihZlcIixmcmFjMTg6XCLihZtcIixmcmFjMjM6XCLihZRcIixmcmFjMjU6XCLihZZcIixmcmFjMzQ6XCLCvlwiLGZyYWMzNTpcIuKFl1wiLGZyYWMzODpcIuKFnFwiLGZyYWM0NTpcIuKFmFwiLGZyYWM1NjpcIuKFmlwiLGZyYWM1ODpcIuKFnVwiLGZyYWM3ODpcIuKFnlwiLGZyYXNsOlwi4oGEXCIsZnJvd246XCLijKJcIixmc2NyOlwi8J2Su1wiLEZzY3I6XCLihLFcIixnYWN1dGU6XCLHtVwiLEdhbW1hOlwizpNcIixnYW1tYTpcIs6zXCIsR2FtbWFkOlwiz5xcIixnYW1tYWQ6XCLPnVwiLGdhcDpcIuKqhlwiLEdicmV2ZTpcIsSeXCIsZ2JyZXZlOlwixJ9cIixHY2VkaWw6XCLEolwiLEdjaXJjOlwixJxcIixnY2lyYzpcIsSdXCIsR2N5Olwi0JNcIixnY3k6XCLQs1wiLEdkb3Q6XCLEoFwiLGdkb3Q6XCLEoVwiLGdlOlwi4omlXCIsZ0U6XCLiiadcIixnRWw6XCLiqoxcIixnZWw6XCLii5tcIixnZXE6XCLiiaVcIixnZXFxOlwi4omnXCIsZ2Vxc2xhbnQ6XCLiqb5cIixnZXNjYzpcIuKqqVwiLGdlczpcIuKpvlwiLGdlc2RvdDpcIuKqgFwiLGdlc2RvdG86XCLiqoJcIixnZXNkb3RvbDpcIuKqhFwiLGdlc2w6XCLii5vvuIBcIixnZXNsZXM6XCLiqpRcIixHZnI6XCLwnZSKXCIsZ2ZyOlwi8J2UpFwiLGdnOlwi4omrXCIsR2c6XCLii5lcIixnZ2c6XCLii5lcIixnaW1lbDpcIuKEt1wiLEdKY3k6XCLQg1wiLGdqY3k6XCLRk1wiLGdsYTpcIuKqpVwiLGdsOlwi4om3XCIsZ2xFOlwi4qqSXCIsZ2xqOlwi4qqkXCIsZ25hcDpcIuKqilwiLGduYXBwcm94Olwi4qqKXCIsZ25lOlwi4qqIXCIsZ25FOlwi4ompXCIsZ25lcTpcIuKqiFwiLGduZXFxOlwi4ompXCIsZ25zaW06XCLii6dcIixHb3BmOlwi8J2UvlwiLGdvcGY6XCLwnZWYXCIsZ3JhdmU6XCJgXCIsR3JlYXRlckVxdWFsOlwi4omlXCIsR3JlYXRlckVxdWFsTGVzczpcIuKLm1wiLEdyZWF0ZXJGdWxsRXF1YWw6XCLiiadcIixHcmVhdGVyR3JlYXRlcjpcIuKqolwiLEdyZWF0ZXJMZXNzOlwi4om3XCIsR3JlYXRlclNsYW50RXF1YWw6XCLiqb5cIixHcmVhdGVyVGlsZGU6XCLiibNcIixHc2NyOlwi8J2SolwiLGdzY3I6XCLihIpcIixnc2ltOlwi4omzXCIsZ3NpbWU6XCLiqo5cIixnc2ltbDpcIuKqkFwiLGd0Y2M6XCLiqqdcIixndGNpcjpcIuKpulwiLGd0OlwiPlwiLEdUOlwiPlwiLEd0Olwi4omrXCIsZ3Rkb3Q6XCLii5dcIixndGxQYXI6XCLippVcIixndHF1ZXN0Olwi4qm8XCIsZ3RyYXBwcm94Olwi4qqGXCIsZ3RyYXJyOlwi4qW4XCIsZ3RyZG90Olwi4ouXXCIsZ3RyZXFsZXNzOlwi4oubXCIsZ3RyZXFxbGVzczpcIuKqjFwiLGd0cmxlc3M6XCLiibdcIixndHJzaW06XCLiibNcIixndmVydG5lcXE6XCLiianvuIBcIixndm5FOlwi4omp77iAXCIsSGFjZWs6XCLLh1wiLGhhaXJzcDpcIuKAilwiLGhhbGY6XCLCvVwiLGhhbWlsdDpcIuKEi1wiLEhBUkRjeTpcItCqXCIsaGFyZGN5Olwi0YpcIixoYXJyY2lyOlwi4qWIXCIsaGFycjpcIuKGlFwiLGhBcnI6XCLih5RcIixoYXJydzpcIuKGrVwiLEhhdDpcIl5cIixoYmFyOlwi4oSPXCIsSGNpcmM6XCLEpFwiLGhjaXJjOlwixKVcIixoZWFydHM6XCLimaVcIixoZWFydHN1aXQ6XCLimaVcIixoZWxsaXA6XCLigKZcIixoZXJjb246XCLiirlcIixoZnI6XCLwnZSlXCIsSGZyOlwi4oSMXCIsSGlsYmVydFNwYWNlOlwi4oSLXCIsaGtzZWFyb3c6XCLipKVcIixoa3N3YXJvdzpcIuKkplwiLGhvYXJyOlwi4oe/XCIsaG9tdGh0Olwi4oi7XCIsaG9va2xlZnRhcnJvdzpcIuKGqVwiLGhvb2tyaWdodGFycm93Olwi4oaqXCIsaG9wZjpcIvCdlZlcIixIb3BmOlwi4oSNXCIsaG9yYmFyOlwi4oCVXCIsSG9yaXpvbnRhbExpbmU6XCLilIBcIixoc2NyOlwi8J2SvVwiLEhzY3I6XCLihItcIixoc2xhc2g6XCLihI9cIixIc3Ryb2s6XCLEplwiLGhzdHJvazpcIsSnXCIsSHVtcERvd25IdW1wOlwi4omOXCIsSHVtcEVxdWFsOlwi4omPXCIsaHlidWxsOlwi4oGDXCIsaHlwaGVuOlwi4oCQXCIsSWFjdXRlOlwiw41cIixpYWN1dGU6XCLDrVwiLGljOlwi4oGjXCIsSWNpcmM6XCLDjlwiLGljaXJjOlwiw65cIixJY3k6XCLQmFwiLGljeTpcItC4XCIsSWRvdDpcIsSwXCIsSUVjeTpcItCVXCIsaWVjeTpcItC1XCIsaWV4Y2w6XCLCoVwiLGlmZjpcIuKHlFwiLGlmcjpcIvCdlKZcIixJZnI6XCLihJFcIixJZ3JhdmU6XCLDjFwiLGlncmF2ZTpcIsOsXCIsaWk6XCLihYhcIixpaWlpbnQ6XCLiqIxcIixpaWludDpcIuKIrVwiLGlpbmZpbjpcIuKnnFwiLGlpb3RhOlwi4oSpXCIsSUpsaWc6XCLEslwiLGlqbGlnOlwixLNcIixJbWFjcjpcIsSqXCIsaW1hY3I6XCLEq1wiLGltYWdlOlwi4oSRXCIsSW1hZ2luYXJ5STpcIuKFiFwiLGltYWdsaW5lOlwi4oSQXCIsaW1hZ3BhcnQ6XCLihJFcIixpbWF0aDpcIsSxXCIsSW06XCLihJFcIixpbW9mOlwi4oq3XCIsaW1wZWQ6XCLGtVwiLEltcGxpZXM6XCLih5JcIixpbmNhcmU6XCLihIVcIixpbjpcIuKIiFwiLGluZmluOlwi4oieXCIsaW5maW50aWU6XCLip51cIixpbm9kb3Q6XCLEsVwiLGludGNhbDpcIuKKulwiLGludDpcIuKIq1wiLEludDpcIuKIrFwiLGludGVnZXJzOlwi4oSkXCIsSW50ZWdyYWw6XCLiiKtcIixpbnRlcmNhbDpcIuKKulwiLEludGVyc2VjdGlvbjpcIuKLglwiLGludGxhcmhrOlwi4qiXXCIsaW50cHJvZDpcIuKovFwiLEludmlzaWJsZUNvbW1hOlwi4oGjXCIsSW52aXNpYmxlVGltZXM6XCLigaJcIixJT2N5Olwi0IFcIixpb2N5Olwi0ZFcIixJb2dvbjpcIsSuXCIsaW9nb246XCLEr1wiLElvcGY6XCLwnZWAXCIsaW9wZjpcIvCdlZpcIixJb3RhOlwizplcIixpb3RhOlwizrlcIixpcHJvZDpcIuKovFwiLGlxdWVzdDpcIsK/XCIsaXNjcjpcIvCdkr5cIixJc2NyOlwi4oSQXCIsaXNpbjpcIuKIiFwiLGlzaW5kb3Q6XCLii7VcIixpc2luRTpcIuKLuVwiLGlzaW5zOlwi4ou0XCIsaXNpbnN2Olwi4ouzXCIsaXNpbnY6XCLiiIhcIixpdDpcIuKBolwiLEl0aWxkZTpcIsSoXCIsaXRpbGRlOlwixKlcIixJdWtjeTpcItCGXCIsaXVrY3k6XCLRllwiLEl1bWw6XCLDj1wiLGl1bWw6XCLDr1wiLEpjaXJjOlwixLRcIixqY2lyYzpcIsS1XCIsSmN5Olwi0JlcIixqY3k6XCLQuVwiLEpmcjpcIvCdlI1cIixqZnI6XCLwnZSnXCIsam1hdGg6XCLIt1wiLEpvcGY6XCLwnZWBXCIsam9wZjpcIvCdlZtcIixKc2NyOlwi8J2SpVwiLGpzY3I6XCLwnZK/XCIsSnNlcmN5Olwi0IhcIixqc2VyY3k6XCLRmFwiLEp1a2N5Olwi0IRcIixqdWtjeTpcItGUXCIsS2FwcGE6XCLOmlwiLGthcHBhOlwizrpcIixrYXBwYXY6XCLPsFwiLEtjZWRpbDpcIsS2XCIsa2NlZGlsOlwixLdcIixLY3k6XCLQmlwiLGtjeTpcItC6XCIsS2ZyOlwi8J2UjlwiLGtmcjpcIvCdlKhcIixrZ3JlZW46XCLEuFwiLEtIY3k6XCLQpVwiLGtoY3k6XCLRhVwiLEtKY3k6XCLQjFwiLGtqY3k6XCLRnFwiLEtvcGY6XCLwnZWCXCIsa29wZjpcIvCdlZxcIixLc2NyOlwi8J2SplwiLGtzY3I6XCLwnZOAXCIsbEFhcnI6XCLih5pcIixMYWN1dGU6XCLEuVwiLGxhY3V0ZTpcIsS6XCIsbGFlbXB0eXY6XCLiprRcIixsYWdyYW46XCLihJJcIixMYW1iZGE6XCLOm1wiLGxhbWJkYTpcIs67XCIsbGFuZzpcIuKfqFwiLExhbmc6XCLin6pcIixsYW5nZDpcIuKmkVwiLGxhbmdsZTpcIuKfqFwiLGxhcDpcIuKqhVwiLExhcGxhY2V0cmY6XCLihJJcIixsYXF1bzpcIsKrXCIsbGFycmI6XCLih6RcIixsYXJyYmZzOlwi4qSfXCIsbGFycjpcIuKGkFwiLExhcnI6XCLihp5cIixsQXJyOlwi4oeQXCIsbGFycmZzOlwi4qSdXCIsbGFycmhrOlwi4oapXCIsbGFycmxwOlwi4oarXCIsbGFycnBsOlwi4qS5XCIsbGFycnNpbTpcIuKls1wiLGxhcnJ0bDpcIuKGolwiLGxhdGFpbDpcIuKkmVwiLGxBdGFpbDpcIuKkm1wiLGxhdDpcIuKqq1wiLGxhdGU6XCLiqq1cIixsYXRlczpcIuKqre+4gFwiLGxiYXJyOlwi4qSMXCIsbEJhcnI6XCLipI5cIixsYmJyazpcIuKdslwiLGxicmFjZTpcIntcIixsYnJhY2s6XCJbXCIsbGJya2U6XCLipotcIixsYnJrc2xkOlwi4qaPXCIsbGJya3NsdTpcIuKmjVwiLExjYXJvbjpcIsS9XCIsbGNhcm9uOlwixL5cIixMY2VkaWw6XCLEu1wiLGxjZWRpbDpcIsS8XCIsbGNlaWw6XCLijIhcIixsY3ViOlwie1wiLExjeTpcItCbXCIsbGN5Olwi0LtcIixsZGNhOlwi4qS2XCIsbGRxdW86XCLigJxcIixsZHF1b3I6XCLigJ5cIixsZHJkaGFyOlwi4qWnXCIsbGRydXNoYXI6XCLipYtcIixsZHNoOlwi4oayXCIsbGU6XCLiiaRcIixsRTpcIuKJplwiLExlZnRBbmdsZUJyYWNrZXQ6XCLin6hcIixMZWZ0QXJyb3dCYXI6XCLih6RcIixsZWZ0YXJyb3c6XCLihpBcIixMZWZ0QXJyb3c6XCLihpBcIixMZWZ0YXJyb3c6XCLih5BcIixMZWZ0QXJyb3dSaWdodEFycm93Olwi4oeGXCIsbGVmdGFycm93dGFpbDpcIuKGolwiLExlZnRDZWlsaW5nOlwi4oyIXCIsTGVmdERvdWJsZUJyYWNrZXQ6XCLin6ZcIixMZWZ0RG93blRlZVZlY3RvcjpcIuKloVwiLExlZnREb3duVmVjdG9yQmFyOlwi4qWZXCIsTGVmdERvd25WZWN0b3I6XCLih4NcIixMZWZ0Rmxvb3I6XCLijIpcIixsZWZ0aGFycG9vbmRvd246XCLihr1cIixsZWZ0aGFycG9vbnVwOlwi4oa8XCIsbGVmdGxlZnRhcnJvd3M6XCLih4dcIixsZWZ0cmlnaHRhcnJvdzpcIuKGlFwiLExlZnRSaWdodEFycm93Olwi4oaUXCIsTGVmdHJpZ2h0YXJyb3c6XCLih5RcIixsZWZ0cmlnaHRhcnJvd3M6XCLih4ZcIixsZWZ0cmlnaHRoYXJwb29uczpcIuKHi1wiLGxlZnRyaWdodHNxdWlnYXJyb3c6XCLihq1cIixMZWZ0UmlnaHRWZWN0b3I6XCLipY5cIixMZWZ0VGVlQXJyb3c6XCLihqRcIixMZWZ0VGVlOlwi4oqjXCIsTGVmdFRlZVZlY3RvcjpcIuKlmlwiLGxlZnR0aHJlZXRpbWVzOlwi4ouLXCIsTGVmdFRyaWFuZ2xlQmFyOlwi4qePXCIsTGVmdFRyaWFuZ2xlOlwi4oqyXCIsTGVmdFRyaWFuZ2xlRXF1YWw6XCLiirRcIixMZWZ0VXBEb3duVmVjdG9yOlwi4qWRXCIsTGVmdFVwVGVlVmVjdG9yOlwi4qWgXCIsTGVmdFVwVmVjdG9yQmFyOlwi4qWYXCIsTGVmdFVwVmVjdG9yOlwi4oa/XCIsTGVmdFZlY3RvckJhcjpcIuKlklwiLExlZnRWZWN0b3I6XCLihrxcIixsRWc6XCLiqotcIixsZWc6XCLii5pcIixsZXE6XCLiiaRcIixsZXFxOlwi4ommXCIsbGVxc2xhbnQ6XCLiqb1cIixsZXNjYzpcIuKqqFwiLGxlczpcIuKpvVwiLGxlc2RvdDpcIuKpv1wiLGxlc2RvdG86XCLiqoFcIixsZXNkb3RvcjpcIuKqg1wiLGxlc2c6XCLii5rvuIBcIixsZXNnZXM6XCLiqpNcIixsZXNzYXBwcm94Olwi4qqFXCIsbGVzc2RvdDpcIuKLllwiLGxlc3NlcWd0cjpcIuKLmlwiLGxlc3NlcXFndHI6XCLiqotcIixMZXNzRXF1YWxHcmVhdGVyOlwi4ouaXCIsTGVzc0Z1bGxFcXVhbDpcIuKJplwiLExlc3NHcmVhdGVyOlwi4om2XCIsbGVzc2d0cjpcIuKJtlwiLExlc3NMZXNzOlwi4qqhXCIsbGVzc3NpbTpcIuKJslwiLExlc3NTbGFudEVxdWFsOlwi4qm9XCIsTGVzc1RpbGRlOlwi4omyXCIsbGZpc2h0Olwi4qW8XCIsbGZsb29yOlwi4oyKXCIsTGZyOlwi8J2Uj1wiLGxmcjpcIvCdlKlcIixsZzpcIuKJtlwiLGxnRTpcIuKqkVwiLGxIYXI6XCLipaJcIixsaGFyZDpcIuKGvVwiLGxoYXJ1Olwi4oa8XCIsbGhhcnVsOlwi4qWqXCIsbGhibGs6XCLiloRcIixMSmN5Olwi0IlcIixsamN5Olwi0ZlcIixsbGFycjpcIuKHh1wiLGxsOlwi4omqXCIsTGw6XCLii5hcIixsbGNvcm5lcjpcIuKMnlwiLExsZWZ0YXJyb3c6XCLih5pcIixsbGhhcmQ6XCLipatcIixsbHRyaTpcIuKXulwiLExtaWRvdDpcIsS/XCIsbG1pZG90OlwixYBcIixsbW91c3RhY2hlOlwi4o6wXCIsbG1vdXN0Olwi4o6wXCIsbG5hcDpcIuKqiVwiLGxuYXBwcm94Olwi4qqJXCIsbG5lOlwi4qqHXCIsbG5FOlwi4omoXCIsbG5lcTpcIuKqh1wiLGxuZXFxOlwi4omoXCIsbG5zaW06XCLii6ZcIixsb2FuZzpcIuKfrFwiLGxvYXJyOlwi4oe9XCIsbG9icms6XCLin6ZcIixsb25nbGVmdGFycm93Olwi4p+1XCIsTG9uZ0xlZnRBcnJvdzpcIuKftVwiLExvbmdsZWZ0YXJyb3c6XCLin7hcIixsb25nbGVmdHJpZ2h0YXJyb3c6XCLin7dcIixMb25nTGVmdFJpZ2h0QXJyb3c6XCLin7dcIixMb25nbGVmdHJpZ2h0YXJyb3c6XCLin7pcIixsb25nbWFwc3RvOlwi4p+8XCIsbG9uZ3JpZ2h0YXJyb3c6XCLin7ZcIixMb25nUmlnaHRBcnJvdzpcIuKftlwiLExvbmdyaWdodGFycm93Olwi4p+5XCIsbG9vcGFycm93bGVmdDpcIuKGq1wiLGxvb3BhcnJvd3JpZ2h0Olwi4oasXCIsbG9wYXI6XCLipoVcIixMb3BmOlwi8J2Vg1wiLGxvcGY6XCLwnZWdXCIsbG9wbHVzOlwi4qitXCIsbG90aW1lczpcIuKotFwiLGxvd2FzdDpcIuKIl1wiLGxvd2JhcjpcIl9cIixMb3dlckxlZnRBcnJvdzpcIuKGmVwiLExvd2VyUmlnaHRBcnJvdzpcIuKGmFwiLGxvejpcIuKXilwiLGxvemVuZ2U6XCLil4pcIixsb3pmOlwi4qerXCIsbHBhcjpcIihcIixscGFybHQ6XCLippNcIixscmFycjpcIuKHhlwiLGxyY29ybmVyOlwi4oyfXCIsbHJoYXI6XCLih4tcIixscmhhcmQ6XCLipa1cIixscm06XCLigI5cIixscnRyaTpcIuKKv1wiLGxzYXF1bzpcIuKAuVwiLGxzY3I6XCLwnZOBXCIsTHNjcjpcIuKEklwiLGxzaDpcIuKGsFwiLExzaDpcIuKGsFwiLGxzaW06XCLiibJcIixsc2ltZTpcIuKqjVwiLGxzaW1nOlwi4qqPXCIsbHNxYjpcIltcIixsc3F1bzpcIuKAmFwiLGxzcXVvcjpcIuKAmlwiLExzdHJvazpcIsWBXCIsbHN0cm9rOlwixYJcIixsdGNjOlwi4qqmXCIsbHRjaXI6XCLiqblcIixsdDpcIjxcIixMVDpcIjxcIixMdDpcIuKJqlwiLGx0ZG90Olwi4ouWXCIsbHRocmVlOlwi4ouLXCIsbHRpbWVzOlwi4ouJXCIsbHRsYXJyOlwi4qW2XCIsbHRxdWVzdDpcIuKpu1wiLGx0cmk6XCLil4NcIixsdHJpZTpcIuKKtFwiLGx0cmlmOlwi4peCXCIsbHRyUGFyOlwi4qaWXCIsbHVyZHNoYXI6XCLipYpcIixsdXJ1aGFyOlwi4qWmXCIsbHZlcnRuZXFxOlwi4omo77iAXCIsbHZuRTpcIuKJqO+4gFwiLG1hY3I6XCLCr1wiLG1hbGU6XCLimYJcIixtYWx0Olwi4pygXCIsbWFsdGVzZTpcIuKcoFwiLE1hcDpcIuKkhVwiLG1hcDpcIuKGplwiLG1hcHN0bzpcIuKGplwiLG1hcHN0b2Rvd246XCLihqdcIixtYXBzdG9sZWZ0Olwi4oakXCIsbWFwc3RvdXA6XCLihqVcIixtYXJrZXI6XCLilq5cIixtY29tbWE6XCLiqKlcIixNY3k6XCLQnFwiLG1jeTpcItC8XCIsbWRhc2g6XCLigJRcIixtRERvdDpcIuKIulwiLG1lYXN1cmVkYW5nbGU6XCLiiKFcIixNZWRpdW1TcGFjZTpcIuKBn1wiLE1lbGxpbnRyZjpcIuKEs1wiLE1mcjpcIvCdlJBcIixtZnI6XCLwnZSqXCIsbWhvOlwi4oSnXCIsbWljcm86XCLCtVwiLG1pZGFzdDpcIipcIixtaWRjaXI6XCLiq7BcIixtaWQ6XCLiiKNcIixtaWRkb3Q6XCLCt1wiLG1pbnVzYjpcIuKKn1wiLG1pbnVzOlwi4oiSXCIsbWludXNkOlwi4oi4XCIsbWludXNkdTpcIuKoqlwiLE1pbnVzUGx1czpcIuKIk1wiLG1sY3A6XCLiq5tcIixtbGRyOlwi4oCmXCIsbW5wbHVzOlwi4oiTXCIsbW9kZWxzOlwi4oqnXCIsTW9wZjpcIvCdlYRcIixtb3BmOlwi8J2VnlwiLG1wOlwi4oiTXCIsbXNjcjpcIvCdk4JcIixNc2NyOlwi4oSzXCIsbXN0cG9zOlwi4oi+XCIsTXU6XCLOnFwiLG11OlwizrxcIixtdWx0aW1hcDpcIuKKuFwiLG11bWFwOlwi4oq4XCIsbmFibGE6XCLiiIdcIixOYWN1dGU6XCLFg1wiLG5hY3V0ZTpcIsWEXCIsbmFuZzpcIuKIoOKDklwiLG5hcDpcIuKJiVwiLG5hcEU6XCLiqbDMuFwiLG5hcGlkOlwi4omLzLhcIixuYXBvczpcIsWJXCIsbmFwcHJveDpcIuKJiVwiLG5hdHVyYWw6XCLima5cIixuYXR1cmFsczpcIuKElVwiLG5hdHVyOlwi4pmuXCIsbmJzcDpcIsKgXCIsbmJ1bXA6XCLiiY7MuFwiLG5idW1wZTpcIuKJj8y4XCIsbmNhcDpcIuKpg1wiLE5jYXJvbjpcIsWHXCIsbmNhcm9uOlwixYhcIixOY2VkaWw6XCLFhVwiLG5jZWRpbDpcIsWGXCIsbmNvbmc6XCLiiYdcIixuY29uZ2RvdDpcIuKprcy4XCIsbmN1cDpcIuKpglwiLE5jeTpcItCdXCIsbmN5Olwi0L1cIixuZGFzaDpcIuKAk1wiLG5lYXJoazpcIuKkpFwiLG5lYXJyOlwi4oaXXCIsbmVBcnI6XCLih5dcIixuZWFycm93Olwi4oaXXCIsbmU6XCLiiaBcIixuZWRvdDpcIuKJkMy4XCIsTmVnYXRpdmVNZWRpdW1TcGFjZTpcIuKAi1wiLE5lZ2F0aXZlVGhpY2tTcGFjZTpcIuKAi1wiLE5lZ2F0aXZlVGhpblNwYWNlOlwi4oCLXCIsTmVnYXRpdmVWZXJ5VGhpblNwYWNlOlwi4oCLXCIsbmVxdWl2Olwi4omiXCIsbmVzZWFyOlwi4qSoXCIsbmVzaW06XCLiiYLMuFwiLE5lc3RlZEdyZWF0ZXJHcmVhdGVyOlwi4omrXCIsTmVzdGVkTGVzc0xlc3M6XCLiiapcIixOZXdMaW5lOlwiXFxuXCIsbmV4aXN0Olwi4oiEXCIsbmV4aXN0czpcIuKIhFwiLE5mcjpcIvCdlJFcIixuZnI6XCLwnZSrXCIsbmdFOlwi4omnzLhcIixuZ2U6XCLiibFcIixuZ2VxOlwi4omxXCIsbmdlcXE6XCLiiafMuFwiLG5nZXFzbGFudDpcIuKpvsy4XCIsbmdlczpcIuKpvsy4XCIsbkdnOlwi4ouZzLhcIixuZ3NpbTpcIuKJtVwiLG5HdDpcIuKJq+KDklwiLG5ndDpcIuKJr1wiLG5ndHI6XCLiia9cIixuR3R2Olwi4omrzLhcIixuaGFycjpcIuKGrlwiLG5oQXJyOlwi4oeOXCIsbmhwYXI6XCLiq7JcIixuaTpcIuKIi1wiLG5pczpcIuKLvFwiLG5pc2Q6XCLii7pcIixuaXY6XCLiiItcIixOSmN5Olwi0IpcIixuamN5Olwi0ZpcIixubGFycjpcIuKGmlwiLG5sQXJyOlwi4oeNXCIsbmxkcjpcIuKApVwiLG5sRTpcIuKJpsy4XCIsbmxlOlwi4omwXCIsbmxlZnRhcnJvdzpcIuKGmlwiLG5MZWZ0YXJyb3c6XCLih41cIixubGVmdHJpZ2h0YXJyb3c6XCLihq5cIixuTGVmdHJpZ2h0YXJyb3c6XCLih45cIixubGVxOlwi4omwXCIsbmxlcXE6XCLiiabMuFwiLG5sZXFzbGFudDpcIuKpvcy4XCIsbmxlczpcIuKpvcy4XCIsbmxlc3M6XCLiia5cIixuTGw6XCLii5jMuFwiLG5sc2ltOlwi4om0XCIsbkx0Olwi4omq4oOSXCIsbmx0Olwi4omuXCIsbmx0cmk6XCLii6pcIixubHRyaWU6XCLii6xcIixuTHR2Olwi4omqzLhcIixubWlkOlwi4oikXCIsTm9CcmVhazpcIuKBoFwiLE5vbkJyZWFraW5nU3BhY2U6XCLCoFwiLG5vcGY6XCLwnZWfXCIsTm9wZjpcIuKElVwiLE5vdDpcIuKrrFwiLG5vdDpcIsKsXCIsTm90Q29uZ3J1ZW50Olwi4omiXCIsTm90Q3VwQ2FwOlwi4omtXCIsTm90RG91YmxlVmVydGljYWxCYXI6XCLiiKZcIixOb3RFbGVtZW50Olwi4oiJXCIsTm90RXF1YWw6XCLiiaBcIixOb3RFcXVhbFRpbGRlOlwi4omCzLhcIixOb3RFeGlzdHM6XCLiiIRcIixOb3RHcmVhdGVyOlwi4omvXCIsTm90R3JlYXRlckVxdWFsOlwi4omxXCIsTm90R3JlYXRlckZ1bGxFcXVhbDpcIuKJp8y4XCIsTm90R3JlYXRlckdyZWF0ZXI6XCLiiavMuFwiLE5vdEdyZWF0ZXJMZXNzOlwi4om5XCIsTm90R3JlYXRlclNsYW50RXF1YWw6XCLiqb7MuFwiLE5vdEdyZWF0ZXJUaWxkZTpcIuKJtVwiLE5vdEh1bXBEb3duSHVtcDpcIuKJjsy4XCIsTm90SHVtcEVxdWFsOlwi4omPzLhcIixub3RpbjpcIuKIiVwiLG5vdGluZG90Olwi4ou1zLhcIixub3RpbkU6XCLii7nMuFwiLG5vdGludmE6XCLiiIlcIixub3RpbnZiOlwi4ou3XCIsbm90aW52YzpcIuKLtlwiLE5vdExlZnRUcmlhbmdsZUJhcjpcIuKnj8y4XCIsTm90TGVmdFRyaWFuZ2xlOlwi4ouqXCIsTm90TGVmdFRyaWFuZ2xlRXF1YWw6XCLii6xcIixOb3RMZXNzOlwi4omuXCIsTm90TGVzc0VxdWFsOlwi4omwXCIsTm90TGVzc0dyZWF0ZXI6XCLiibhcIixOb3RMZXNzTGVzczpcIuKJqsy4XCIsTm90TGVzc1NsYW50RXF1YWw6XCLiqb3MuFwiLE5vdExlc3NUaWxkZTpcIuKJtFwiLE5vdE5lc3RlZEdyZWF0ZXJHcmVhdGVyOlwi4qqizLhcIixOb3ROZXN0ZWRMZXNzTGVzczpcIuKqocy4XCIsbm90bmk6XCLiiIxcIixub3RuaXZhOlwi4oiMXCIsbm90bml2YjpcIuKLvlwiLG5vdG5pdmM6XCLii71cIixOb3RQcmVjZWRlczpcIuKKgFwiLE5vdFByZWNlZGVzRXF1YWw6XCLiqq/MuFwiLE5vdFByZWNlZGVzU2xhbnRFcXVhbDpcIuKLoFwiLE5vdFJldmVyc2VFbGVtZW50Olwi4oiMXCIsTm90UmlnaHRUcmlhbmdsZUJhcjpcIuKnkMy4XCIsTm90UmlnaHRUcmlhbmdsZTpcIuKLq1wiLE5vdFJpZ2h0VHJpYW5nbGVFcXVhbDpcIuKLrVwiLE5vdFNxdWFyZVN1YnNldDpcIuKKj8y4XCIsTm90U3F1YXJlU3Vic2V0RXF1YWw6XCLii6JcIixOb3RTcXVhcmVTdXBlcnNldDpcIuKKkMy4XCIsTm90U3F1YXJlU3VwZXJzZXRFcXVhbDpcIuKLo1wiLE5vdFN1YnNldDpcIuKKguKDklwiLE5vdFN1YnNldEVxdWFsOlwi4oqIXCIsTm90U3VjY2VlZHM6XCLiioFcIixOb3RTdWNjZWVkc0VxdWFsOlwi4qqwzLhcIixOb3RTdWNjZWVkc1NsYW50RXF1YWw6XCLii6FcIixOb3RTdWNjZWVkc1RpbGRlOlwi4om/zLhcIixOb3RTdXBlcnNldDpcIuKKg+KDklwiLE5vdFN1cGVyc2V0RXF1YWw6XCLiiolcIixOb3RUaWxkZTpcIuKJgVwiLE5vdFRpbGRlRXF1YWw6XCLiiYRcIixOb3RUaWxkZUZ1bGxFcXVhbDpcIuKJh1wiLE5vdFRpbGRlVGlsZGU6XCLiiYlcIixOb3RWZXJ0aWNhbEJhcjpcIuKIpFwiLG5wYXJhbGxlbDpcIuKIplwiLG5wYXI6XCLiiKZcIixucGFyc2w6XCLiq73ig6VcIixucGFydDpcIuKIgsy4XCIsbnBvbGludDpcIuKolFwiLG5wcjpcIuKKgFwiLG5wcmN1ZTpcIuKLoFwiLG5wcmVjOlwi4oqAXCIsbnByZWNlcTpcIuKqr8y4XCIsbnByZTpcIuKqr8y4XCIsbnJhcnJjOlwi4qSzzLhcIixucmFycjpcIuKGm1wiLG5yQXJyOlwi4oePXCIsbnJhcnJ3Olwi4oadzLhcIixucmlnaHRhcnJvdzpcIuKGm1wiLG5SaWdodGFycm93Olwi4oePXCIsbnJ0cmk6XCLii6tcIixucnRyaWU6XCLii61cIixuc2M6XCLiioFcIixuc2NjdWU6XCLii6FcIixuc2NlOlwi4qqwzLhcIixOc2NyOlwi8J2SqVwiLG5zY3I6XCLwnZODXCIsbnNob3J0bWlkOlwi4oikXCIsbnNob3J0cGFyYWxsZWw6XCLiiKZcIixuc2ltOlwi4omBXCIsbnNpbWU6XCLiiYRcIixuc2ltZXE6XCLiiYRcIixuc21pZDpcIuKIpFwiLG5zcGFyOlwi4oimXCIsbnNxc3ViZTpcIuKLolwiLG5zcXN1cGU6XCLii6NcIixuc3ViOlwi4oqEXCIsbnN1YkU6XCLiq4XMuFwiLG5zdWJlOlwi4oqIXCIsbnN1YnNldDpcIuKKguKDklwiLG5zdWJzZXRlcTpcIuKKiFwiLG5zdWJzZXRlcXE6XCLiq4XMuFwiLG5zdWNjOlwi4oqBXCIsbnN1Y2NlcTpcIuKqsMy4XCIsbnN1cDpcIuKKhVwiLG5zdXBFOlwi4quGzLhcIixuc3VwZTpcIuKKiVwiLG5zdXBzZXQ6XCLiioPig5JcIixuc3Vwc2V0ZXE6XCLiiolcIixuc3Vwc2V0ZXFxOlwi4quGzLhcIixudGdsOlwi4om5XCIsTnRpbGRlOlwiw5FcIixudGlsZGU6XCLDsVwiLG50bGc6XCLiibhcIixudHJpYW5nbGVsZWZ0Olwi4ouqXCIsbnRyaWFuZ2xlbGVmdGVxOlwi4ousXCIsbnRyaWFuZ2xlcmlnaHQ6XCLii6tcIixudHJpYW5nbGVyaWdodGVxOlwi4outXCIsTnU6XCLOnVwiLG51Olwizr1cIixudW06XCIjXCIsbnVtZXJvOlwi4oSWXCIsbnVtc3A6XCLigIdcIixudmFwOlwi4omN4oOSXCIsbnZkYXNoOlwi4oqsXCIsbnZEYXNoOlwi4oqtXCIsblZkYXNoOlwi4oquXCIsblZEYXNoOlwi4oqvXCIsbnZnZTpcIuKJpeKDklwiLG52Z3Q6XCI+4oOSXCIsbnZIYXJyOlwi4qSEXCIsbnZpbmZpbjpcIuKnnlwiLG52bEFycjpcIuKkglwiLG52bGU6XCLiiaTig5JcIixudmx0OlwiPOKDklwiLG52bHRyaWU6XCLiirTig5JcIixudnJBcnI6XCLipINcIixudnJ0cmllOlwi4oq14oOSXCIsbnZzaW06XCLiiLzig5JcIixud2FyaGs6XCLipKNcIixud2FycjpcIuKGllwiLG53QXJyOlwi4oeWXCIsbndhcnJvdzpcIuKGllwiLG53bmVhcjpcIuKkp1wiLE9hY3V0ZTpcIsOTXCIsb2FjdXRlOlwiw7NcIixvYXN0Olwi4oqbXCIsT2NpcmM6XCLDlFwiLG9jaXJjOlwiw7RcIixvY2lyOlwi4oqaXCIsT2N5Olwi0J5cIixvY3k6XCLQvlwiLG9kYXNoOlwi4oqdXCIsT2RibGFjOlwixZBcIixvZGJsYWM6XCLFkVwiLG9kaXY6XCLiqLhcIixvZG90Olwi4oqZXCIsb2Rzb2xkOlwi4qa8XCIsT0VsaWc6XCLFklwiLG9lbGlnOlwixZNcIixvZmNpcjpcIuKmv1wiLE9mcjpcIvCdlJJcIixvZnI6XCLwnZSsXCIsb2dvbjpcIsubXCIsT2dyYXZlOlwiw5JcIixvZ3JhdmU6XCLDslwiLG9ndDpcIuKngVwiLG9oYmFyOlwi4qa1XCIsb2htOlwizqlcIixvaW50Olwi4oiuXCIsb2xhcnI6XCLihrpcIixvbGNpcjpcIuKmvlwiLG9sY3Jvc3M6XCLiprtcIixvbGluZTpcIuKAvlwiLG9sdDpcIuKngFwiLE9tYWNyOlwixYxcIixvbWFjcjpcIsWNXCIsT21lZ2E6XCLOqVwiLG9tZWdhOlwiz4lcIixPbWljcm9uOlwizp9cIixvbWljcm9uOlwizr9cIixvbWlkOlwi4qa2XCIsb21pbnVzOlwi4oqWXCIsT29wZjpcIvCdlYZcIixvb3BmOlwi8J2VoFwiLG9wYXI6XCLiprdcIixPcGVuQ3VybHlEb3VibGVRdW90ZTpcIuKAnFwiLE9wZW5DdXJseVF1b3RlOlwi4oCYXCIsb3BlcnA6XCLiprlcIixvcGx1czpcIuKKlVwiLG9yYXJyOlwi4oa7XCIsT3I6XCLiqZRcIixvcjpcIuKIqFwiLG9yZDpcIuKpnVwiLG9yZGVyOlwi4oS0XCIsb3JkZXJvZjpcIuKEtFwiLG9yZGY6XCLCqlwiLG9yZG06XCLCulwiLG9yaWdvZjpcIuKKtlwiLG9yb3I6XCLiqZZcIixvcnNsb3BlOlwi4qmXXCIsb3J2Olwi4qmbXCIsb1M6XCLik4hcIixPc2NyOlwi8J2SqlwiLG9zY3I6XCLihLRcIixPc2xhc2g6XCLDmFwiLG9zbGFzaDpcIsO4XCIsb3NvbDpcIuKKmFwiLE90aWxkZTpcIsOVXCIsb3RpbGRlOlwiw7VcIixvdGltZXNhczpcIuKotlwiLE90aW1lczpcIuKot1wiLG90aW1lczpcIuKKl1wiLE91bWw6XCLDllwiLG91bWw6XCLDtlwiLG92YmFyOlwi4oy9XCIsT3ZlckJhcjpcIuKAvlwiLE92ZXJCcmFjZTpcIuKPnlwiLE92ZXJCcmFja2V0Olwi4o60XCIsT3ZlclBhcmVudGhlc2lzOlwi4o+cXCIscGFyYTpcIsK2XCIscGFyYWxsZWw6XCLiiKVcIixwYXI6XCLiiKVcIixwYXJzaW06XCLiq7NcIixwYXJzbDpcIuKrvVwiLHBhcnQ6XCLiiIJcIixQYXJ0aWFsRDpcIuKIglwiLFBjeTpcItCfXCIscGN5Olwi0L9cIixwZXJjbnQ6XCIlXCIscGVyaW9kOlwiLlwiLHBlcm1pbDpcIuKAsFwiLHBlcnA6XCLiiqVcIixwZXJ0ZW5rOlwi4oCxXCIsUGZyOlwi8J2Uk1wiLHBmcjpcIvCdlK1cIixQaGk6XCLOplwiLHBoaTpcIs+GXCIscGhpdjpcIs+VXCIscGhtbWF0Olwi4oSzXCIscGhvbmU6XCLimI5cIixQaTpcIs6gXCIscGk6XCLPgFwiLHBpdGNoZm9yazpcIuKLlFwiLHBpdjpcIs+WXCIscGxhbmNrOlwi4oSPXCIscGxhbmNraDpcIuKEjlwiLHBsYW5rdjpcIuKEj1wiLHBsdXNhY2lyOlwi4qijXCIscGx1c2I6XCLiip5cIixwbHVzY2lyOlwi4qiiXCIscGx1czpcIitcIixwbHVzZG86XCLiiJRcIixwbHVzZHU6XCLiqKVcIixwbHVzZTpcIuKpslwiLFBsdXNNaW51czpcIsKxXCIscGx1c21uOlwiwrFcIixwbHVzc2ltOlwi4qimXCIscGx1c3R3bzpcIuKop1wiLHBtOlwiwrFcIixQb2luY2FyZXBsYW5lOlwi4oSMXCIscG9pbnRpbnQ6XCLiqJVcIixwb3BmOlwi8J2VoVwiLFBvcGY6XCLihJlcIixwb3VuZDpcIsKjXCIscHJhcDpcIuKqt1wiLFByOlwi4qq7XCIscHI6XCLiibpcIixwcmN1ZTpcIuKJvFwiLHByZWNhcHByb3g6XCLiqrdcIixwcmVjOlwi4om6XCIscHJlY2N1cmx5ZXE6XCLiibxcIixQcmVjZWRlczpcIuKJulwiLFByZWNlZGVzRXF1YWw6XCLiqq9cIixQcmVjZWRlc1NsYW50RXF1YWw6XCLiibxcIixQcmVjZWRlc1RpbGRlOlwi4om+XCIscHJlY2VxOlwi4qqvXCIscHJlY25hcHByb3g6XCLiqrlcIixwcmVjbmVxcTpcIuKqtVwiLHByZWNuc2ltOlwi4ouoXCIscHJlOlwi4qqvXCIscHJFOlwi4qqzXCIscHJlY3NpbTpcIuKJvlwiLHByaW1lOlwi4oCyXCIsUHJpbWU6XCLigLNcIixwcmltZXM6XCLihJlcIixwcm5hcDpcIuKquVwiLHBybkU6XCLiqrVcIixwcm5zaW06XCLii6hcIixwcm9kOlwi4oiPXCIsUHJvZHVjdDpcIuKIj1wiLHByb2ZhbGFyOlwi4oyuXCIscHJvZmxpbmU6XCLijJJcIixwcm9mc3VyZjpcIuKMk1wiLHByb3A6XCLiiJ1cIixQcm9wb3J0aW9uYWw6XCLiiJ1cIixQcm9wb3J0aW9uOlwi4oi3XCIscHJvcHRvOlwi4oidXCIscHJzaW06XCLiib5cIixwcnVyZWw6XCLiirBcIixQc2NyOlwi8J2Sq1wiLHBzY3I6XCLwnZOFXCIsUHNpOlwizqhcIixwc2k6XCLPiFwiLHB1bmNzcDpcIuKAiFwiLFFmcjpcIvCdlJRcIixxZnI6XCLwnZSuXCIscWludDpcIuKojFwiLHFvcGY6XCLwnZWiXCIsUW9wZjpcIuKEmlwiLHFwcmltZTpcIuKBl1wiLFFzY3I6XCLwnZKsXCIscXNjcjpcIvCdk4ZcIixxdWF0ZXJuaW9uczpcIuKEjVwiLHF1YXRpbnQ6XCLiqJZcIixxdWVzdDpcIj9cIixxdWVzdGVxOlwi4omfXCIscXVvdDonXCInLFFVT1Q6J1wiJyxyQWFycjpcIuKHm1wiLHJhY2U6XCLiiL3MsVwiLFJhY3V0ZTpcIsWUXCIscmFjdXRlOlwixZVcIixyYWRpYzpcIuKImlwiLHJhZW1wdHl2Olwi4qazXCIscmFuZzpcIuKfqVwiLFJhbmc6XCLin6tcIixyYW5nZDpcIuKmklwiLHJhbmdlOlwi4qalXCIscmFuZ2xlOlwi4p+pXCIscmFxdW86XCLCu1wiLHJhcnJhcDpcIuKltVwiLHJhcnJiOlwi4oelXCIscmFycmJmczpcIuKkoFwiLHJhcnJjOlwi4qSzXCIscmFycjpcIuKGklwiLFJhcnI6XCLihqBcIixyQXJyOlwi4oeSXCIscmFycmZzOlwi4qSeXCIscmFycmhrOlwi4oaqXCIscmFycmxwOlwi4oasXCIscmFycnBsOlwi4qWFXCIscmFycnNpbTpcIuKltFwiLFJhcnJ0bDpcIuKkllwiLHJhcnJ0bDpcIuKGo1wiLHJhcnJ3Olwi4oadXCIscmF0YWlsOlwi4qSaXCIsckF0YWlsOlwi4qScXCIscmF0aW86XCLiiLZcIixyYXRpb25hbHM6XCLihJpcIixyYmFycjpcIuKkjVwiLHJCYXJyOlwi4qSPXCIsUkJhcnI6XCLipJBcIixyYmJyazpcIuKds1wiLHJicmFjZTpcIn1cIixyYnJhY2s6XCJdXCIscmJya2U6XCLipoxcIixyYnJrc2xkOlwi4qaOXCIscmJya3NsdTpcIuKmkFwiLFJjYXJvbjpcIsWYXCIscmNhcm9uOlwixZlcIixSY2VkaWw6XCLFllwiLHJjZWRpbDpcIsWXXCIscmNlaWw6XCLijIlcIixyY3ViOlwifVwiLFJjeTpcItCgXCIscmN5Olwi0YBcIixyZGNhOlwi4qS3XCIscmRsZGhhcjpcIuKlqVwiLHJkcXVvOlwi4oCdXCIscmRxdW9yOlwi4oCdXCIscmRzaDpcIuKGs1wiLHJlYWw6XCLihJxcIixyZWFsaW5lOlwi4oSbXCIscmVhbHBhcnQ6XCLihJxcIixyZWFsczpcIuKEnVwiLFJlOlwi4oScXCIscmVjdDpcIuKWrVwiLHJlZzpcIsKuXCIsUkVHOlwiwq5cIixSZXZlcnNlRWxlbWVudDpcIuKIi1wiLFJldmVyc2VFcXVpbGlicml1bTpcIuKHi1wiLFJldmVyc2VVcEVxdWlsaWJyaXVtOlwi4qWvXCIscmZpc2h0Olwi4qW9XCIscmZsb29yOlwi4oyLXCIscmZyOlwi8J2Ur1wiLFJmcjpcIuKEnFwiLHJIYXI6XCLipaRcIixyaGFyZDpcIuKHgVwiLHJoYXJ1Olwi4oeAXCIscmhhcnVsOlwi4qWsXCIsUmhvOlwizqFcIixyaG86XCLPgVwiLHJob3Y6XCLPsVwiLFJpZ2h0QW5nbGVCcmFja2V0Olwi4p+pXCIsUmlnaHRBcnJvd0JhcjpcIuKHpVwiLHJpZ2h0YXJyb3c6XCLihpJcIixSaWdodEFycm93Olwi4oaSXCIsUmlnaHRhcnJvdzpcIuKHklwiLFJpZ2h0QXJyb3dMZWZ0QXJyb3c6XCLih4RcIixyaWdodGFycm93dGFpbDpcIuKGo1wiLFJpZ2h0Q2VpbGluZzpcIuKMiVwiLFJpZ2h0RG91YmxlQnJhY2tldDpcIuKfp1wiLFJpZ2h0RG93blRlZVZlY3RvcjpcIuKlnVwiLFJpZ2h0RG93blZlY3RvckJhcjpcIuKllVwiLFJpZ2h0RG93blZlY3RvcjpcIuKHglwiLFJpZ2h0Rmxvb3I6XCLijItcIixyaWdodGhhcnBvb25kb3duOlwi4oeBXCIscmlnaHRoYXJwb29udXA6XCLih4BcIixyaWdodGxlZnRhcnJvd3M6XCLih4RcIixyaWdodGxlZnRoYXJwb29uczpcIuKHjFwiLHJpZ2h0cmlnaHRhcnJvd3M6XCLih4lcIixyaWdodHNxdWlnYXJyb3c6XCLihp1cIixSaWdodFRlZUFycm93Olwi4oamXCIsUmlnaHRUZWU6XCLiiqJcIixSaWdodFRlZVZlY3RvcjpcIuKlm1wiLHJpZ2h0dGhyZWV0aW1lczpcIuKLjFwiLFJpZ2h0VHJpYW5nbGVCYXI6XCLip5BcIixSaWdodFRyaWFuZ2xlOlwi4oqzXCIsUmlnaHRUcmlhbmdsZUVxdWFsOlwi4oq1XCIsUmlnaHRVcERvd25WZWN0b3I6XCLipY9cIixSaWdodFVwVGVlVmVjdG9yOlwi4qWcXCIsUmlnaHRVcFZlY3RvckJhcjpcIuKllFwiLFJpZ2h0VXBWZWN0b3I6XCLihr5cIixSaWdodFZlY3RvckJhcjpcIuKlk1wiLFJpZ2h0VmVjdG9yOlwi4oeAXCIscmluZzpcIsuaXCIscmlzaW5nZG90c2VxOlwi4omTXCIscmxhcnI6XCLih4RcIixybGhhcjpcIuKHjFwiLHJsbTpcIuKAj1wiLHJtb3VzdGFjaGU6XCLijrFcIixybW91c3Q6XCLijrFcIixybm1pZDpcIuKrrlwiLHJvYW5nOlwi4p+tXCIscm9hcnI6XCLih75cIixyb2JyazpcIuKfp1wiLHJvcGFyOlwi4qaGXCIscm9wZjpcIvCdlaNcIixSb3BmOlwi4oSdXCIscm9wbHVzOlwi4qiuXCIscm90aW1lczpcIuKotVwiLFJvdW5kSW1wbGllczpcIuKlsFwiLHJwYXI6XCIpXCIscnBhcmd0Olwi4qaUXCIscnBwb2xpbnQ6XCLiqJJcIixycmFycjpcIuKHiVwiLFJyaWdodGFycm93Olwi4oebXCIscnNhcXVvOlwi4oC6XCIscnNjcjpcIvCdk4dcIixSc2NyOlwi4oSbXCIscnNoOlwi4oaxXCIsUnNoOlwi4oaxXCIscnNxYjpcIl1cIixyc3F1bzpcIuKAmVwiLHJzcXVvcjpcIuKAmVwiLHJ0aHJlZTpcIuKLjFwiLHJ0aW1lczpcIuKLilwiLHJ0cmk6XCLilrlcIixydHJpZTpcIuKKtVwiLHJ0cmlmOlwi4pa4XCIscnRyaWx0cmk6XCLip45cIixSdWxlRGVsYXllZDpcIuKntFwiLHJ1bHVoYXI6XCLipahcIixyeDpcIuKEnlwiLFNhY3V0ZTpcIsWaXCIsc2FjdXRlOlwixZtcIixzYnF1bzpcIuKAmlwiLHNjYXA6XCLiqrhcIixTY2Fyb246XCLFoFwiLHNjYXJvbjpcIsWhXCIsU2M6XCLiqrxcIixzYzpcIuKJu1wiLHNjY3VlOlwi4om9XCIsc2NlOlwi4qqwXCIsc2NFOlwi4qq0XCIsU2NlZGlsOlwixZ5cIixzY2VkaWw6XCLFn1wiLFNjaXJjOlwixZxcIixzY2lyYzpcIsWdXCIsc2NuYXA6XCLiqrpcIixzY25FOlwi4qq2XCIsc2Nuc2ltOlwi4oupXCIsc2Nwb2xpbnQ6XCLiqJNcIixzY3NpbTpcIuKJv1wiLFNjeTpcItChXCIsc2N5Olwi0YFcIixzZG90YjpcIuKKoVwiLHNkb3Q6XCLii4VcIixzZG90ZTpcIuKpplwiLHNlYXJoazpcIuKkpVwiLHNlYXJyOlwi4oaYXCIsc2VBcnI6XCLih5hcIixzZWFycm93Olwi4oaYXCIsc2VjdDpcIsKnXCIsc2VtaTpcIjtcIixzZXN3YXI6XCLipKlcIixzZXRtaW51czpcIuKIllwiLHNldG1uOlwi4oiWXCIsc2V4dDpcIuKctlwiLFNmcjpcIvCdlJZcIixzZnI6XCLwnZSwXCIsc2Zyb3duOlwi4oyiXCIsc2hhcnA6XCLima9cIixTSENIY3k6XCLQqVwiLHNoY2hjeTpcItGJXCIsU0hjeTpcItCoXCIsc2hjeTpcItGIXCIsU2hvcnREb3duQXJyb3c6XCLihpNcIixTaG9ydExlZnRBcnJvdzpcIuKGkFwiLHNob3J0bWlkOlwi4oijXCIsc2hvcnRwYXJhbGxlbDpcIuKIpVwiLFNob3J0UmlnaHRBcnJvdzpcIuKGklwiLFNob3J0VXBBcnJvdzpcIuKGkVwiLHNoeTpcIsKtXCIsU2lnbWE6XCLOo1wiLHNpZ21hOlwiz4NcIixzaWdtYWY6XCLPglwiLHNpZ21hdjpcIs+CXCIsc2ltOlwi4oi8XCIsc2ltZG90Olwi4qmqXCIsc2ltZTpcIuKJg1wiLHNpbWVxOlwi4omDXCIsc2ltZzpcIuKqnlwiLHNpbWdFOlwi4qqgXCIsc2ltbDpcIuKqnVwiLHNpbWxFOlwi4qqfXCIsc2ltbmU6XCLiiYZcIixzaW1wbHVzOlwi4qikXCIsc2ltcmFycjpcIuKlslwiLHNsYXJyOlwi4oaQXCIsU21hbGxDaXJjbGU6XCLiiJhcIixzbWFsbHNldG1pbnVzOlwi4oiWXCIsc21hc2hwOlwi4qizXCIsc21lcGFyc2w6XCLip6RcIixzbWlkOlwi4oijXCIsc21pbGU6XCLijKNcIixzbXQ6XCLiqqpcIixzbXRlOlwi4qqsXCIsc210ZXM6XCLiqqzvuIBcIixTT0ZUY3k6XCLQrFwiLHNvZnRjeTpcItGMXCIsc29sYmFyOlwi4oy/XCIsc29sYjpcIuKnhFwiLHNvbDpcIi9cIixTb3BmOlwi8J2VilwiLHNvcGY6XCLwnZWkXCIsc3BhZGVzOlwi4pmgXCIsc3BhZGVzdWl0Olwi4pmgXCIsc3BhcjpcIuKIpVwiLHNxY2FwOlwi4oqTXCIsc3FjYXBzOlwi4oqT77iAXCIsc3FjdXA6XCLiipRcIixzcWN1cHM6XCLiipTvuIBcIixTcXJ0Olwi4oiaXCIsc3FzdWI6XCLiio9cIixzcXN1YmU6XCLiipFcIixzcXN1YnNldDpcIuKKj1wiLHNxc3Vic2V0ZXE6XCLiipFcIixzcXN1cDpcIuKKkFwiLHNxc3VwZTpcIuKKklwiLHNxc3Vwc2V0Olwi4oqQXCIsc3FzdXBzZXRlcTpcIuKKklwiLHNxdWFyZTpcIuKWoVwiLFNxdWFyZTpcIuKWoVwiLFNxdWFyZUludGVyc2VjdGlvbjpcIuKKk1wiLFNxdWFyZVN1YnNldDpcIuKKj1wiLFNxdWFyZVN1YnNldEVxdWFsOlwi4oqRXCIsU3F1YXJlU3VwZXJzZXQ6XCLiipBcIixTcXVhcmVTdXBlcnNldEVxdWFsOlwi4oqSXCIsU3F1YXJlVW5pb246XCLiipRcIixzcXVhcmY6XCLilqpcIixzcXU6XCLilqFcIixzcXVmOlwi4paqXCIsc3JhcnI6XCLihpJcIixTc2NyOlwi8J2SrlwiLHNzY3I6XCLwnZOIXCIsc3NldG1uOlwi4oiWXCIsc3NtaWxlOlwi4oyjXCIsc3N0YXJmOlwi4ouGXCIsU3RhcjpcIuKLhlwiLHN0YXI6XCLimIZcIixzdGFyZjpcIuKYhVwiLHN0cmFpZ2h0ZXBzaWxvbjpcIs+1XCIsc3RyYWlnaHRwaGk6XCLPlVwiLHN0cm5zOlwiwq9cIixzdWI6XCLiioJcIixTdWI6XCLii5BcIixzdWJkb3Q6XCLiqr1cIixzdWJFOlwi4quFXCIsc3ViZTpcIuKKhlwiLHN1YmVkb3Q6XCLiq4NcIixzdWJtdWx0Olwi4quBXCIsc3VibkU6XCLiq4tcIixzdWJuZTpcIuKKilwiLHN1YnBsdXM6XCLiqr9cIixzdWJyYXJyOlwi4qW5XCIsc3Vic2V0Olwi4oqCXCIsU3Vic2V0Olwi4ouQXCIsc3Vic2V0ZXE6XCLiioZcIixzdWJzZXRlcXE6XCLiq4VcIixTdWJzZXRFcXVhbDpcIuKKhlwiLHN1YnNldG5lcTpcIuKKilwiLHN1YnNldG5lcXE6XCLiq4tcIixzdWJzaW06XCLiq4dcIixzdWJzdWI6XCLiq5VcIixzdWJzdXA6XCLiq5NcIixzdWNjYXBwcm94Olwi4qq4XCIsc3VjYzpcIuKJu1wiLHN1Y2NjdXJseWVxOlwi4om9XCIsU3VjY2VlZHM6XCLiibtcIixTdWNjZWVkc0VxdWFsOlwi4qqwXCIsU3VjY2VlZHNTbGFudEVxdWFsOlwi4om9XCIsU3VjY2VlZHNUaWxkZTpcIuKJv1wiLHN1Y2NlcTpcIuKqsFwiLHN1Y2NuYXBwcm94Olwi4qq6XCIsc3VjY25lcXE6XCLiqrZcIixzdWNjbnNpbTpcIuKLqVwiLHN1Y2NzaW06XCLiib9cIixTdWNoVGhhdDpcIuKIi1wiLHN1bTpcIuKIkVwiLFN1bTpcIuKIkVwiLHN1bmc6XCLimapcIixzdXAxOlwiwrlcIixzdXAyOlwiwrJcIixzdXAzOlwiwrNcIixzdXA6XCLiioNcIixTdXA6XCLii5FcIixzdXBkb3Q6XCLiqr5cIixzdXBkc3ViOlwi4quYXCIsc3VwRTpcIuKrhlwiLHN1cGU6XCLiiodcIixzdXBlZG90Olwi4quEXCIsU3VwZXJzZXQ6XCLiioNcIixTdXBlcnNldEVxdWFsOlwi4oqHXCIsc3VwaHNvbDpcIuKfiVwiLHN1cGhzdWI6XCLiq5dcIixzdXBsYXJyOlwi4qW7XCIsc3VwbXVsdDpcIuKrglwiLHN1cG5FOlwi4quMXCIsc3VwbmU6XCLiiotcIixzdXBwbHVzOlwi4quAXCIsc3Vwc2V0Olwi4oqDXCIsU3Vwc2V0Olwi4ouRXCIsc3Vwc2V0ZXE6XCLiiodcIixzdXBzZXRlcXE6XCLiq4ZcIixzdXBzZXRuZXE6XCLiiotcIixzdXBzZXRuZXFxOlwi4quMXCIsc3Vwc2ltOlwi4quIXCIsc3Vwc3ViOlwi4quUXCIsc3Vwc3VwOlwi4quWXCIsc3dhcmhrOlwi4qSmXCIsc3dhcnI6XCLihplcIixzd0FycjpcIuKHmVwiLHN3YXJyb3c6XCLihplcIixzd253YXI6XCLipKpcIixzemxpZzpcIsOfXCIsVGFiOlwiXFx0XCIsdGFyZ2V0Olwi4oyWXCIsVGF1OlwizqRcIix0YXU6XCLPhFwiLHRicms6XCLijrRcIixUY2Fyb246XCLFpFwiLHRjYXJvbjpcIsWlXCIsVGNlZGlsOlwixaJcIix0Y2VkaWw6XCLFo1wiLFRjeTpcItCiXCIsdGN5Olwi0YJcIix0ZG90Olwi4oObXCIsdGVscmVjOlwi4oyVXCIsVGZyOlwi8J2Ul1wiLHRmcjpcIvCdlLFcIix0aGVyZTQ6XCLiiLRcIix0aGVyZWZvcmU6XCLiiLRcIixUaGVyZWZvcmU6XCLiiLRcIixUaGV0YTpcIs6YXCIsdGhldGE6XCLOuFwiLHRoZXRhc3ltOlwiz5FcIix0aGV0YXY6XCLPkVwiLHRoaWNrYXBwcm94Olwi4omIXCIsdGhpY2tzaW06XCLiiLxcIixUaGlja1NwYWNlOlwi4oGf4oCKXCIsVGhpblNwYWNlOlwi4oCJXCIsdGhpbnNwOlwi4oCJXCIsdGhrYXA6XCLiiYhcIix0aGtzaW06XCLiiLxcIixUSE9STjpcIsOeXCIsdGhvcm46XCLDvlwiLHRpbGRlOlwiy5xcIixUaWxkZTpcIuKIvFwiLFRpbGRlRXF1YWw6XCLiiYNcIixUaWxkZUZ1bGxFcXVhbDpcIuKJhVwiLFRpbGRlVGlsZGU6XCLiiYhcIix0aW1lc2JhcjpcIuKosVwiLHRpbWVzYjpcIuKKoFwiLHRpbWVzOlwiw5dcIix0aW1lc2Q6XCLiqLBcIix0aW50Olwi4oitXCIsdG9lYTpcIuKkqFwiLHRvcGJvdDpcIuKMtlwiLHRvcGNpcjpcIuKrsVwiLHRvcDpcIuKKpFwiLFRvcGY6XCLwnZWLXCIsdG9wZjpcIvCdlaVcIix0b3Bmb3JrOlwi4quaXCIsdG9zYTpcIuKkqVwiLHRwcmltZTpcIuKAtFwiLHRyYWRlOlwi4oSiXCIsVFJBREU6XCLihKJcIix0cmlhbmdsZTpcIuKWtVwiLHRyaWFuZ2xlZG93bjpcIuKWv1wiLHRyaWFuZ2xlbGVmdDpcIuKXg1wiLHRyaWFuZ2xlbGVmdGVxOlwi4oq0XCIsdHJpYW5nbGVxOlwi4omcXCIsdHJpYW5nbGVyaWdodDpcIuKWuVwiLHRyaWFuZ2xlcmlnaHRlcTpcIuKKtVwiLHRyaWRvdDpcIuKXrFwiLHRyaWU6XCLiiZxcIix0cmltaW51czpcIuKoulwiLFRyaXBsZURvdDpcIuKDm1wiLHRyaXBsdXM6XCLiqLlcIix0cmlzYjpcIuKnjVwiLHRyaXRpbWU6XCLiqLtcIix0cnBleml1bTpcIuKPolwiLFRzY3I6XCLwnZKvXCIsdHNjcjpcIvCdk4lcIixUU2N5Olwi0KZcIix0c2N5Olwi0YZcIixUU0hjeTpcItCLXCIsdHNoY3k6XCLRm1wiLFRzdHJvazpcIsWmXCIsdHN0cm9rOlwixadcIix0d2l4dDpcIuKJrFwiLHR3b2hlYWRsZWZ0YXJyb3c6XCLihp5cIix0d29oZWFkcmlnaHRhcnJvdzpcIuKGoFwiLFVhY3V0ZTpcIsOaXCIsdWFjdXRlOlwiw7pcIix1YXJyOlwi4oaRXCIsVWFycjpcIuKGn1wiLHVBcnI6XCLih5FcIixVYXJyb2NpcjpcIuKliVwiLFVicmN5Olwi0I5cIix1YnJjeTpcItGeXCIsVWJyZXZlOlwixaxcIix1YnJldmU6XCLFrVwiLFVjaXJjOlwiw5tcIix1Y2lyYzpcIsO7XCIsVWN5Olwi0KNcIix1Y3k6XCLRg1wiLHVkYXJyOlwi4oeFXCIsVWRibGFjOlwixbBcIix1ZGJsYWM6XCLFsVwiLHVkaGFyOlwi4qWuXCIsdWZpc2h0Olwi4qW+XCIsVWZyOlwi8J2UmFwiLHVmcjpcIvCdlLJcIixVZ3JhdmU6XCLDmVwiLHVncmF2ZTpcIsO5XCIsdUhhcjpcIuKlo1wiLHVoYXJsOlwi4oa/XCIsdWhhcnI6XCLihr5cIix1aGJsazpcIuKWgFwiLHVsY29ybjpcIuKMnFwiLHVsY29ybmVyOlwi4oycXCIsdWxjcm9wOlwi4oyPXCIsdWx0cmk6XCLil7hcIixVbWFjcjpcIsWqXCIsdW1hY3I6XCLFq1wiLHVtbDpcIsKoXCIsVW5kZXJCYXI6XCJfXCIsVW5kZXJCcmFjZTpcIuKPn1wiLFVuZGVyQnJhY2tldDpcIuKOtVwiLFVuZGVyUGFyZW50aGVzaXM6XCLij51cIixVbmlvbjpcIuKLg1wiLFVuaW9uUGx1czpcIuKKjlwiLFVvZ29uOlwixbJcIix1b2dvbjpcIsWzXCIsVW9wZjpcIvCdlYxcIix1b3BmOlwi8J2VplwiLFVwQXJyb3dCYXI6XCLipJJcIix1cGFycm93Olwi4oaRXCIsVXBBcnJvdzpcIuKGkVwiLFVwYXJyb3c6XCLih5FcIixVcEFycm93RG93bkFycm93Olwi4oeFXCIsdXBkb3duYXJyb3c6XCLihpVcIixVcERvd25BcnJvdzpcIuKGlVwiLFVwZG93bmFycm93Olwi4oeVXCIsVXBFcXVpbGlicml1bTpcIuKlrlwiLHVwaGFycG9vbmxlZnQ6XCLihr9cIix1cGhhcnBvb25yaWdodDpcIuKGvlwiLHVwbHVzOlwi4oqOXCIsVXBwZXJMZWZ0QXJyb3c6XCLihpZcIixVcHBlclJpZ2h0QXJyb3c6XCLihpdcIix1cHNpOlwiz4VcIixVcHNpOlwiz5JcIix1cHNpaDpcIs+SXCIsVXBzaWxvbjpcIs6lXCIsdXBzaWxvbjpcIs+FXCIsVXBUZWVBcnJvdzpcIuKGpVwiLFVwVGVlOlwi4oqlXCIsdXB1cGFycm93czpcIuKHiFwiLHVyY29ybjpcIuKMnVwiLHVyY29ybmVyOlwi4oydXCIsdXJjcm9wOlwi4oyOXCIsVXJpbmc6XCLFrlwiLHVyaW5nOlwixa9cIix1cnRyaTpcIuKXuVwiLFVzY3I6XCLwnZKwXCIsdXNjcjpcIvCdk4pcIix1dGRvdDpcIuKLsFwiLFV0aWxkZTpcIsWoXCIsdXRpbGRlOlwixalcIix1dHJpOlwi4pa1XCIsdXRyaWY6XCLilrRcIix1dWFycjpcIuKHiFwiLFV1bWw6XCLDnFwiLHV1bWw6XCLDvFwiLHV3YW5nbGU6XCLipqdcIix2YW5ncnQ6XCLippxcIix2YXJlcHNpbG9uOlwiz7VcIix2YXJrYXBwYTpcIs+wXCIsdmFybm90aGluZzpcIuKIhVwiLHZhcnBoaTpcIs+VXCIsdmFycGk6XCLPllwiLHZhcnByb3B0bzpcIuKInVwiLHZhcnI6XCLihpVcIix2QXJyOlwi4oeVXCIsdmFycmhvOlwiz7FcIix2YXJzaWdtYTpcIs+CXCIsdmFyc3Vic2V0bmVxOlwi4oqK77iAXCIsdmFyc3Vic2V0bmVxcTpcIuKri++4gFwiLHZhcnN1cHNldG5lcTpcIuKKi++4gFwiLHZhcnN1cHNldG5lcXE6XCLiq4zvuIBcIix2YXJ0aGV0YTpcIs+RXCIsdmFydHJpYW5nbGVsZWZ0Olwi4oqyXCIsdmFydHJpYW5nbGVyaWdodDpcIuKKs1wiLHZCYXI6XCLiq6hcIixWYmFyOlwi4qurXCIsdkJhcnY6XCLiq6lcIixWY3k6XCLQklwiLHZjeTpcItCyXCIsdmRhc2g6XCLiiqJcIix2RGFzaDpcIuKKqFwiLFZkYXNoOlwi4oqpXCIsVkRhc2g6XCLiiqtcIixWZGFzaGw6XCLiq6ZcIix2ZWViYXI6XCLiirtcIix2ZWU6XCLiiKhcIixWZWU6XCLii4FcIix2ZWVlcTpcIuKJmlwiLHZlbGxpcDpcIuKLrlwiLHZlcmJhcjpcInxcIixWZXJiYXI6XCLigJZcIix2ZXJ0OlwifFwiLFZlcnQ6XCLigJZcIixWZXJ0aWNhbEJhcjpcIuKIo1wiLFZlcnRpY2FsTGluZTpcInxcIixWZXJ0aWNhbFNlcGFyYXRvcjpcIuKdmFwiLFZlcnRpY2FsVGlsZGU6XCLiiYBcIixWZXJ5VGhpblNwYWNlOlwi4oCKXCIsVmZyOlwi8J2UmVwiLHZmcjpcIvCdlLNcIix2bHRyaTpcIuKKslwiLHZuc3ViOlwi4oqC4oOSXCIsdm5zdXA6XCLiioPig5JcIixWb3BmOlwi8J2VjVwiLHZvcGY6XCLwnZWnXCIsdnByb3A6XCLiiJ1cIix2cnRyaTpcIuKKs1wiLFZzY3I6XCLwnZKxXCIsdnNjcjpcIvCdk4tcIix2c3VibkU6XCLiq4vvuIBcIix2c3VibmU6XCLiiorvuIBcIix2c3VwbkU6XCLiq4zvuIBcIix2c3VwbmU6XCLiiovvuIBcIixWdmRhc2g6XCLiiqpcIix2emlnemFnOlwi4qaaXCIsV2NpcmM6XCLFtFwiLHdjaXJjOlwixbVcIix3ZWRiYXI6XCLiqZ9cIix3ZWRnZTpcIuKIp1wiLFdlZGdlOlwi4ouAXCIsd2VkZ2VxOlwi4omZXCIsd2VpZXJwOlwi4oSYXCIsV2ZyOlwi8J2UmlwiLHdmcjpcIvCdlLRcIixXb3BmOlwi8J2VjlwiLHdvcGY6XCLwnZWoXCIsd3A6XCLihJhcIix3cjpcIuKJgFwiLHdyZWF0aDpcIuKJgFwiLFdzY3I6XCLwnZKyXCIsd3NjcjpcIvCdk4xcIix4Y2FwOlwi4ouCXCIseGNpcmM6XCLil69cIix4Y3VwOlwi4ouDXCIseGR0cmk6XCLilr1cIixYZnI6XCLwnZSbXCIseGZyOlwi8J2UtVwiLHhoYXJyOlwi4p+3XCIseGhBcnI6XCLin7pcIixYaTpcIs6eXCIseGk6XCLOvlwiLHhsYXJyOlwi4p+1XCIseGxBcnI6XCLin7hcIix4bWFwOlwi4p+8XCIseG5pczpcIuKLu1wiLHhvZG90Olwi4qiAXCIsWG9wZjpcIvCdlY9cIix4b3BmOlwi8J2VqVwiLHhvcGx1czpcIuKogVwiLHhvdGltZTpcIuKoglwiLHhyYXJyOlwi4p+2XCIseHJBcnI6XCLin7lcIixYc2NyOlwi8J2Ss1wiLHhzY3I6XCLwnZONXCIseHNxY3VwOlwi4qiGXCIseHVwbHVzOlwi4qiEXCIseHV0cmk6XCLilrNcIix4dmVlOlwi4ouBXCIseHdlZGdlOlwi4ouAXCIsWWFjdXRlOlwiw51cIix5YWN1dGU6XCLDvVwiLFlBY3k6XCLQr1wiLHlhY3k6XCLRj1wiLFljaXJjOlwixbZcIix5Y2lyYzpcIsW3XCIsWWN5Olwi0KtcIix5Y3k6XCLRi1wiLHllbjpcIsKlXCIsWWZyOlwi8J2UnFwiLHlmcjpcIvCdlLZcIixZSWN5Olwi0IdcIix5aWN5Olwi0ZdcIixZb3BmOlwi8J2VkFwiLHlvcGY6XCLwnZWqXCIsWXNjcjpcIvCdkrRcIix5c2NyOlwi8J2TjlwiLFlVY3k6XCLQrlwiLHl1Y3k6XCLRjlwiLHl1bWw6XCLDv1wiLFl1bWw6XCLFuFwiLFphY3V0ZTpcIsW5XCIsemFjdXRlOlwixbpcIixaY2Fyb246XCLFvVwiLHpjYXJvbjpcIsW+XCIsWmN5Olwi0JdcIix6Y3k6XCLQt1wiLFpkb3Q6XCLFu1wiLHpkb3Q6XCLFvFwiLHplZXRyZjpcIuKEqFwiLFplcm9XaWR0aFNwYWNlOlwi4oCLXCIsWmV0YTpcIs6WXCIsemV0YTpcIs62XCIsemZyOlwi8J2Ut1wiLFpmcjpcIuKEqFwiLFpIY3k6XCLQllwiLHpoY3k6XCLQtlwiLHppZ3JhcnI6XCLih51cIix6b3BmOlwi8J2Vq1wiLFpvcGY6XCLihKRcIixac2NyOlwi8J2StVwiLHpzY3I6XCLwnZOPXCIsendqOlwi4oCNXCIsenduajpcIuKAjFwifX0se31dLDI2OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXttb2R1bGUuZXhwb3J0cz17QWFjdXRlOlwiw4FcIixhYWN1dGU6XCLDoVwiLEFjaXJjOlwiw4JcIixhY2lyYzpcIsOiXCIsYWN1dGU6XCLCtFwiLEFFbGlnOlwiw4ZcIixhZWxpZzpcIsOmXCIsQWdyYXZlOlwiw4BcIixhZ3JhdmU6XCLDoFwiLGFtcDpcIiZcIixBTVA6XCImXCIsQXJpbmc6XCLDhVwiLGFyaW5nOlwiw6VcIixBdGlsZGU6XCLDg1wiLGF0aWxkZTpcIsOjXCIsQXVtbDpcIsOEXCIsYXVtbDpcIsOkXCIsYnJ2YmFyOlwiwqZcIixDY2VkaWw6XCLDh1wiLGNjZWRpbDpcIsOnXCIsY2VkaWw6XCLCuFwiLGNlbnQ6XCLColwiLGNvcHk6XCLCqVwiLENPUFk6XCLCqVwiLGN1cnJlbjpcIsKkXCIsZGVnOlwiwrBcIixkaXZpZGU6XCLDt1wiLEVhY3V0ZTpcIsOJXCIsZWFjdXRlOlwiw6lcIixFY2lyYzpcIsOKXCIsZWNpcmM6XCLDqlwiLEVncmF2ZTpcIsOIXCIsZWdyYXZlOlwiw6hcIixFVEg6XCLDkFwiLGV0aDpcIsOwXCIsRXVtbDpcIsOLXCIsZXVtbDpcIsOrXCIsZnJhYzEyOlwiwr1cIixmcmFjMTQ6XCLCvFwiLGZyYWMzNDpcIsK+XCIsZ3Q6XCI+XCIsR1Q6XCI+XCIsSWFjdXRlOlwiw41cIixpYWN1dGU6XCLDrVwiLEljaXJjOlwiw45cIixpY2lyYzpcIsOuXCIsaWV4Y2w6XCLCoVwiLElncmF2ZTpcIsOMXCIsaWdyYXZlOlwiw6xcIixpcXVlc3Q6XCLCv1wiLEl1bWw6XCLDj1wiLGl1bWw6XCLDr1wiLGxhcXVvOlwiwqtcIixsdDpcIjxcIixMVDpcIjxcIixtYWNyOlwiwq9cIixtaWNybzpcIsK1XCIsbWlkZG90OlwiwrdcIixuYnNwOlwiwqBcIixub3Q6XCLCrFwiLE50aWxkZTpcIsORXCIsbnRpbGRlOlwiw7FcIixPYWN1dGU6XCLDk1wiLG9hY3V0ZTpcIsOzXCIsT2NpcmM6XCLDlFwiLG9jaXJjOlwiw7RcIixPZ3JhdmU6XCLDklwiLG9ncmF2ZTpcIsOyXCIsb3JkZjpcIsKqXCIsb3JkbTpcIsK6XCIsT3NsYXNoOlwiw5hcIixvc2xhc2g6XCLDuFwiLE90aWxkZTpcIsOVXCIsb3RpbGRlOlwiw7VcIixPdW1sOlwiw5ZcIixvdW1sOlwiw7ZcIixwYXJhOlwiwrZcIixwbHVzbW46XCLCsVwiLHBvdW5kOlwiwqNcIixxdW90OidcIicsUVVPVDonXCInLHJhcXVvOlwiwrtcIixyZWc6XCLCrlwiLFJFRzpcIsKuXCIsc2VjdDpcIsKnXCIsc2h5Olwiwq1cIixzdXAxOlwiwrlcIixzdXAyOlwiwrJcIixzdXAzOlwiwrNcIixzemxpZzpcIsOfXCIsVEhPUk46XCLDnlwiLHRob3JuOlwiw75cIix0aW1lczpcIsOXXCIsVWFjdXRlOlwiw5pcIix1YWN1dGU6XCLDulwiLFVjaXJjOlwiw5tcIix1Y2lyYzpcIsO7XCIsVWdyYXZlOlwiw5lcIix1Z3JhdmU6XCLDuVwiLHVtbDpcIsKoXCIsVXVtbDpcIsOcXCIsdXVtbDpcIsO8XCIsWWFjdXRlOlwiw51cIix5YWN1dGU6XCLDvVwiLHllbjpcIsKlXCIseXVtbDpcIsO/XCJ9fSx7fV0sMjc6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe21vZHVsZS5leHBvcnRzPXthbXA6XCImXCIsYXBvczpcIidcIixndDpcIj5cIixsdDpcIjxcIixxdW90OidcIid9fSx7fV0sMjg6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe2Z1bmN0aW9uIEV2ZW50RW1pdHRlcigpe3RoaXMuX2V2ZW50cz10aGlzLl9ldmVudHN8fHt9O3RoaXMuX21heExpc3RlbmVycz10aGlzLl9tYXhMaXN0ZW5lcnN8fHVuZGVmaW5lZH1tb2R1bGUuZXhwb3J0cz1FdmVudEVtaXR0ZXI7RXZlbnRFbWl0dGVyLkV2ZW50RW1pdHRlcj1FdmVudEVtaXR0ZXI7RXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fZXZlbnRzPXVuZGVmaW5lZDtFdmVudEVtaXR0ZXIucHJvdG90eXBlLl9tYXhMaXN0ZW5lcnM9dW5kZWZpbmVkO0V2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzPTEwO0V2ZW50RW1pdHRlci5wcm90b3R5cGUuc2V0TWF4TGlzdGVuZXJzPWZ1bmN0aW9uKG4pe2lmKCFpc051bWJlcihuKXx8bjwwfHxpc05hTihuKSl0aHJvdyBUeXBlRXJyb3IoXCJuIG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXJcIik7dGhpcy5fbWF4TGlzdGVuZXJzPW47cmV0dXJuIHRoaXN9O0V2ZW50RW1pdHRlci5wcm90b3R5cGUuZW1pdD1mdW5jdGlvbih0eXBlKXt2YXIgZXIsaGFuZGxlcixsZW4sYXJncyxpLGxpc3RlbmVycztpZighdGhpcy5fZXZlbnRzKXRoaXMuX2V2ZW50cz17fTtpZih0eXBlPT09XCJlcnJvclwiKXtpZighdGhpcy5fZXZlbnRzLmVycm9yfHxpc09iamVjdCh0aGlzLl9ldmVudHMuZXJyb3IpJiYhdGhpcy5fZXZlbnRzLmVycm9yLmxlbmd0aCl7ZXI9YXJndW1lbnRzWzFdO2lmKGVyIGluc3RhbmNlb2YgRXJyb3Ipe3Rocm93IGVyfWVsc2V7dmFyIGVycj1uZXcgRXJyb3IoJ1VuY2F1Z2h0LCB1bnNwZWNpZmllZCBcImVycm9yXCIgZXZlbnQuICgnK2VyK1wiKVwiKTtlcnIuY29udGV4dD1lcjt0aHJvdyBlcnJ9fX1oYW5kbGVyPXRoaXMuX2V2ZW50c1t0eXBlXTtpZihpc1VuZGVmaW5lZChoYW5kbGVyKSlyZXR1cm4gZmFsc2U7aWYoaXNGdW5jdGlvbihoYW5kbGVyKSl7c3dpdGNoKGFyZ3VtZW50cy5sZW5ndGgpe2Nhc2UgMTpoYW5kbGVyLmNhbGwodGhpcyk7YnJlYWs7Y2FzZSAyOmhhbmRsZXIuY2FsbCh0aGlzLGFyZ3VtZW50c1sxXSk7YnJlYWs7Y2FzZSAzOmhhbmRsZXIuY2FsbCh0aGlzLGFyZ3VtZW50c1sxXSxhcmd1bWVudHNbMl0pO2JyZWFrO2RlZmF1bHQ6YXJncz1BcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsMSk7aGFuZGxlci5hcHBseSh0aGlzLGFyZ3MpfX1lbHNlIGlmKGlzT2JqZWN0KGhhbmRsZXIpKXthcmdzPUFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywxKTtsaXN0ZW5lcnM9aGFuZGxlci5zbGljZSgpO2xlbj1saXN0ZW5lcnMubGVuZ3RoO2ZvcihpPTA7aTxsZW47aSsrKWxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLGFyZ3MpfXJldHVybiB0cnVlfTtFdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyPWZ1bmN0aW9uKHR5cGUsbGlzdGVuZXIpe3ZhciBtO2lmKCFpc0Z1bmN0aW9uKGxpc3RlbmVyKSl0aHJvdyBUeXBlRXJyb3IoXCJsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb25cIik7aWYoIXRoaXMuX2V2ZW50cyl0aGlzLl9ldmVudHM9e307aWYodGhpcy5fZXZlbnRzLm5ld0xpc3RlbmVyKXRoaXMuZW1pdChcIm5ld0xpc3RlbmVyXCIsdHlwZSxpc0Z1bmN0aW9uKGxpc3RlbmVyLmxpc3RlbmVyKT9saXN0ZW5lci5saXN0ZW5lcjpsaXN0ZW5lcik7aWYoIXRoaXMuX2V2ZW50c1t0eXBlXSl0aGlzLl9ldmVudHNbdHlwZV09bGlzdGVuZXI7ZWxzZSBpZihpc09iamVjdCh0aGlzLl9ldmVudHNbdHlwZV0pKXRoaXMuX2V2ZW50c1t0eXBlXS5wdXNoKGxpc3RlbmVyKTtlbHNlIHRoaXMuX2V2ZW50c1t0eXBlXT1bdGhpcy5fZXZlbnRzW3R5cGVdLGxpc3RlbmVyXTtpZihpc09iamVjdCh0aGlzLl9ldmVudHNbdHlwZV0pJiYhdGhpcy5fZXZlbnRzW3R5cGVdLndhcm5lZCl7aWYoIWlzVW5kZWZpbmVkKHRoaXMuX21heExpc3RlbmVycykpe209dGhpcy5fbWF4TGlzdGVuZXJzfWVsc2V7bT1FdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVyc31pZihtJiZtPjAmJnRoaXMuX2V2ZW50c1t0eXBlXS5sZW5ndGg+bSl7dGhpcy5fZXZlbnRzW3R5cGVdLndhcm5lZD10cnVlO2NvbnNvbGUuZXJyb3IoXCIobm9kZSkgd2FybmluZzogcG9zc2libGUgRXZlbnRFbWl0dGVyIG1lbW9yeSBcIitcImxlYWsgZGV0ZWN0ZWQuICVkIGxpc3RlbmVycyBhZGRlZC4gXCIrXCJVc2UgZW1pdHRlci5zZXRNYXhMaXN0ZW5lcnMoKSB0byBpbmNyZWFzZSBsaW1pdC5cIix0aGlzLl9ldmVudHNbdHlwZV0ubGVuZ3RoKTtpZih0eXBlb2YgY29uc29sZS50cmFjZT09PVwiZnVuY3Rpb25cIil7Y29uc29sZS50cmFjZSgpfX19cmV0dXJuIHRoaXN9O0V2ZW50RW1pdHRlci5wcm90b3R5cGUub249RXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lcjtFdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2U9ZnVuY3Rpb24odHlwZSxsaXN0ZW5lcil7aWYoIWlzRnVuY3Rpb24obGlzdGVuZXIpKXRocm93IFR5cGVFcnJvcihcImxpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvblwiKTt2YXIgZmlyZWQ9ZmFsc2U7ZnVuY3Rpb24gZygpe3RoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSxnKTtpZighZmlyZWQpe2ZpcmVkPXRydWU7bGlzdGVuZXIuYXBwbHkodGhpcyxhcmd1bWVudHMpfX1nLmxpc3RlbmVyPWxpc3RlbmVyO3RoaXMub24odHlwZSxnKTtyZXR1cm4gdGhpc307RXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lcj1mdW5jdGlvbih0eXBlLGxpc3RlbmVyKXt2YXIgbGlzdCxwb3NpdGlvbixsZW5ndGgsaTtpZighaXNGdW5jdGlvbihsaXN0ZW5lcikpdGhyb3cgVHlwZUVycm9yKFwibGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uXCIpO2lmKCF0aGlzLl9ldmVudHN8fCF0aGlzLl9ldmVudHNbdHlwZV0pcmV0dXJuIHRoaXM7bGlzdD10aGlzLl9ldmVudHNbdHlwZV07bGVuZ3RoPWxpc3QubGVuZ3RoO3Bvc2l0aW9uPS0xO2lmKGxpc3Q9PT1saXN0ZW5lcnx8aXNGdW5jdGlvbihsaXN0Lmxpc3RlbmVyKSYmbGlzdC5saXN0ZW5lcj09PWxpc3RlbmVyKXtkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO2lmKHRoaXMuX2V2ZW50cy5yZW1vdmVMaXN0ZW5lcil0aGlzLmVtaXQoXCJyZW1vdmVMaXN0ZW5lclwiLHR5cGUsbGlzdGVuZXIpfWVsc2UgaWYoaXNPYmplY3QobGlzdCkpe2ZvcihpPWxlbmd0aDtpLS0gPjA7KXtpZihsaXN0W2ldPT09bGlzdGVuZXJ8fGxpc3RbaV0ubGlzdGVuZXImJmxpc3RbaV0ubGlzdGVuZXI9PT1saXN0ZW5lcil7cG9zaXRpb249aTticmVha319aWYocG9zaXRpb248MClyZXR1cm4gdGhpcztpZihsaXN0Lmxlbmd0aD09PTEpe2xpc3QubGVuZ3RoPTA7ZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXX1lbHNle2xpc3Quc3BsaWNlKHBvc2l0aW9uLDEpO1xufWlmKHRoaXMuX2V2ZW50cy5yZW1vdmVMaXN0ZW5lcil0aGlzLmVtaXQoXCJyZW1vdmVMaXN0ZW5lclwiLHR5cGUsbGlzdGVuZXIpfXJldHVybiB0aGlzfTtFdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycz1mdW5jdGlvbih0eXBlKXt2YXIga2V5LGxpc3RlbmVycztpZighdGhpcy5fZXZlbnRzKXJldHVybiB0aGlzO2lmKCF0aGlzLl9ldmVudHMucmVtb3ZlTGlzdGVuZXIpe2lmKGFyZ3VtZW50cy5sZW5ndGg9PT0wKXRoaXMuX2V2ZW50cz17fTtlbHNlIGlmKHRoaXMuX2V2ZW50c1t0eXBlXSlkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO3JldHVybiB0aGlzfWlmKGFyZ3VtZW50cy5sZW5ndGg9PT0wKXtmb3Ioa2V5IGluIHRoaXMuX2V2ZW50cyl7aWYoa2V5PT09XCJyZW1vdmVMaXN0ZW5lclwiKWNvbnRpbnVlO3RoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKGtleSl9dGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoXCJyZW1vdmVMaXN0ZW5lclwiKTt0aGlzLl9ldmVudHM9e307cmV0dXJuIHRoaXN9bGlzdGVuZXJzPXRoaXMuX2V2ZW50c1t0eXBlXTtpZihpc0Z1bmN0aW9uKGxpc3RlbmVycykpe3RoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSxsaXN0ZW5lcnMpfWVsc2UgaWYobGlzdGVuZXJzKXt3aGlsZShsaXN0ZW5lcnMubGVuZ3RoKXRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSxsaXN0ZW5lcnNbbGlzdGVuZXJzLmxlbmd0aC0xXSl9ZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtyZXR1cm4gdGhpc307RXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lcnM9ZnVuY3Rpb24odHlwZSl7dmFyIHJldDtpZighdGhpcy5fZXZlbnRzfHwhdGhpcy5fZXZlbnRzW3R5cGVdKXJldD1bXTtlbHNlIGlmKGlzRnVuY3Rpb24odGhpcy5fZXZlbnRzW3R5cGVdKSlyZXQ9W3RoaXMuX2V2ZW50c1t0eXBlXV07ZWxzZSByZXQ9dGhpcy5fZXZlbnRzW3R5cGVdLnNsaWNlKCk7cmV0dXJuIHJldH07RXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lckNvdW50PWZ1bmN0aW9uKHR5cGUpe2lmKHRoaXMuX2V2ZW50cyl7dmFyIGV2bGlzdGVuZXI9dGhpcy5fZXZlbnRzW3R5cGVdO2lmKGlzRnVuY3Rpb24oZXZsaXN0ZW5lcikpcmV0dXJuIDE7ZWxzZSBpZihldmxpc3RlbmVyKXJldHVybiBldmxpc3RlbmVyLmxlbmd0aH1yZXR1cm4gMH07RXZlbnRFbWl0dGVyLmxpc3RlbmVyQ291bnQ9ZnVuY3Rpb24oZW1pdHRlcix0eXBlKXtyZXR1cm4gZW1pdHRlci5saXN0ZW5lckNvdW50KHR5cGUpfTtmdW5jdGlvbiBpc0Z1bmN0aW9uKGFyZyl7cmV0dXJuIHR5cGVvZiBhcmc9PT1cImZ1bmN0aW9uXCJ9ZnVuY3Rpb24gaXNOdW1iZXIoYXJnKXtyZXR1cm4gdHlwZW9mIGFyZz09PVwibnVtYmVyXCJ9ZnVuY3Rpb24gaXNPYmplY3QoYXJnKXtyZXR1cm4gdHlwZW9mIGFyZz09PVwib2JqZWN0XCImJmFyZyE9PW51bGx9ZnVuY3Rpb24gaXNVbmRlZmluZWQoYXJnKXtyZXR1cm4gYXJnPT09dm9pZCAwfX0se31dLDI5OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXttb2R1bGUuZXhwb3J0cz1Db2xsZWN0aW5nSGFuZGxlcjtmdW5jdGlvbiBDb2xsZWN0aW5nSGFuZGxlcihjYnMpe3RoaXMuX2Nicz1jYnN8fHt9O3RoaXMuZXZlbnRzPVtdfXZhciBFVkVOVFM9cmVxdWlyZShcIi4vXCIpLkVWRU5UUztPYmplY3Qua2V5cyhFVkVOVFMpLmZvckVhY2goZnVuY3Rpb24obmFtZSl7aWYoRVZFTlRTW25hbWVdPT09MCl7bmFtZT1cIm9uXCIrbmFtZTtDb2xsZWN0aW5nSGFuZGxlci5wcm90b3R5cGVbbmFtZV09ZnVuY3Rpb24oKXt0aGlzLmV2ZW50cy5wdXNoKFtuYW1lXSk7aWYodGhpcy5fY2JzW25hbWVdKXRoaXMuX2Nic1tuYW1lXSgpfX1lbHNlIGlmKEVWRU5UU1tuYW1lXT09PTEpe25hbWU9XCJvblwiK25hbWU7Q29sbGVjdGluZ0hhbmRsZXIucHJvdG90eXBlW25hbWVdPWZ1bmN0aW9uKGEpe3RoaXMuZXZlbnRzLnB1c2goW25hbWUsYV0pO2lmKHRoaXMuX2Nic1tuYW1lXSl0aGlzLl9jYnNbbmFtZV0oYSl9fWVsc2UgaWYoRVZFTlRTW25hbWVdPT09Mil7bmFtZT1cIm9uXCIrbmFtZTtDb2xsZWN0aW5nSGFuZGxlci5wcm90b3R5cGVbbmFtZV09ZnVuY3Rpb24oYSxiKXt0aGlzLmV2ZW50cy5wdXNoKFtuYW1lLGEsYl0pO2lmKHRoaXMuX2Nic1tuYW1lXSl0aGlzLl9jYnNbbmFtZV0oYSxiKX19ZWxzZXt0aHJvdyBFcnJvcihcIndyb25nIG51bWJlciBvZiBhcmd1bWVudHNcIil9fSk7Q29sbGVjdGluZ0hhbmRsZXIucHJvdG90eXBlLm9ucmVzZXQ9ZnVuY3Rpb24oKXt0aGlzLmV2ZW50cz1bXTtpZih0aGlzLl9jYnMub25yZXNldCl0aGlzLl9jYnMub25yZXNldCgpfTtDb2xsZWN0aW5nSGFuZGxlci5wcm90b3R5cGUucmVzdGFydD1mdW5jdGlvbigpe2lmKHRoaXMuX2Nicy5vbnJlc2V0KXRoaXMuX2Nicy5vbnJlc2V0KCk7Zm9yKHZhciBpPTAsbGVuPXRoaXMuZXZlbnRzLmxlbmd0aDtpPGxlbjtpKyspe2lmKHRoaXMuX2Nic1t0aGlzLmV2ZW50c1tpXVswXV0pe3ZhciBudW09dGhpcy5ldmVudHNbaV0ubGVuZ3RoO2lmKG51bT09PTEpe3RoaXMuX2Nic1t0aGlzLmV2ZW50c1tpXVswXV0oKX1lbHNlIGlmKG51bT09PTIpe3RoaXMuX2Nic1t0aGlzLmV2ZW50c1tpXVswXV0odGhpcy5ldmVudHNbaV1bMV0pfWVsc2V7dGhpcy5fY2JzW3RoaXMuZXZlbnRzW2ldWzBdXSh0aGlzLmV2ZW50c1tpXVsxXSx0aGlzLmV2ZW50c1tpXVsyXSl9fX19fSx7XCIuL1wiOjM2fV0sMzA6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciBpbmRleD1yZXF1aXJlKFwiLi9pbmRleC5qc1wiKSxEb21IYW5kbGVyPWluZGV4LkRvbUhhbmRsZXIsRG9tVXRpbHM9aW5kZXguRG9tVXRpbHM7ZnVuY3Rpb24gRmVlZEhhbmRsZXIoY2FsbGJhY2ssb3B0aW9ucyl7dGhpcy5pbml0KGNhbGxiYWNrLG9wdGlvbnMpfXJlcXVpcmUoXCJpbmhlcml0c1wiKShGZWVkSGFuZGxlcixEb21IYW5kbGVyKTtGZWVkSGFuZGxlci5wcm90b3R5cGUuaW5pdD1Eb21IYW5kbGVyO2Z1bmN0aW9uIGdldEVsZW1lbnRzKHdoYXQsd2hlcmUpe3JldHVybiBEb21VdGlscy5nZXRFbGVtZW50c0J5VGFnTmFtZSh3aGF0LHdoZXJlLHRydWUpfWZ1bmN0aW9uIGdldE9uZUVsZW1lbnQod2hhdCx3aGVyZSl7cmV0dXJuIERvbVV0aWxzLmdldEVsZW1lbnRzQnlUYWdOYW1lKHdoYXQsd2hlcmUsdHJ1ZSwxKVswXX1mdW5jdGlvbiBmZXRjaCh3aGF0LHdoZXJlLHJlY3Vyc2Upe3JldHVybiBEb21VdGlscy5nZXRUZXh0KERvbVV0aWxzLmdldEVsZW1lbnRzQnlUYWdOYW1lKHdoYXQsd2hlcmUscmVjdXJzZSwxKSkudHJpbSgpfWZ1bmN0aW9uIGFkZENvbmRpdGlvbmFsbHkob2JqLHByb3Asd2hhdCx3aGVyZSxyZWN1cnNlKXt2YXIgdG1wPWZldGNoKHdoYXQsd2hlcmUscmVjdXJzZSk7aWYodG1wKW9ialtwcm9wXT10bXB9dmFyIGlzVmFsaWRGZWVkPWZ1bmN0aW9uKHZhbHVlKXtyZXR1cm4gdmFsdWU9PT1cInJzc1wifHx2YWx1ZT09PVwiZmVlZFwifHx2YWx1ZT09PVwicmRmOlJERlwifTtGZWVkSGFuZGxlci5wcm90b3R5cGUub25lbmQ9ZnVuY3Rpb24oKXt2YXIgZmVlZD17fSxmZWVkUm9vdD1nZXRPbmVFbGVtZW50KGlzVmFsaWRGZWVkLHRoaXMuZG9tKSx0bXAsY2hpbGRzO2lmKGZlZWRSb290KXtpZihmZWVkUm9vdC5uYW1lPT09XCJmZWVkXCIpe2NoaWxkcz1mZWVkUm9vdC5jaGlsZHJlbjtmZWVkLnR5cGU9XCJhdG9tXCI7YWRkQ29uZGl0aW9uYWxseShmZWVkLFwiaWRcIixcImlkXCIsY2hpbGRzKTthZGRDb25kaXRpb25hbGx5KGZlZWQsXCJ0aXRsZVwiLFwidGl0bGVcIixjaGlsZHMpO2lmKCh0bXA9Z2V0T25lRWxlbWVudChcImxpbmtcIixjaGlsZHMpKSYmKHRtcD10bXAuYXR0cmlicykmJih0bXA9dG1wLmhyZWYpKWZlZWQubGluaz10bXA7YWRkQ29uZGl0aW9uYWxseShmZWVkLFwiZGVzY3JpcHRpb25cIixcInN1YnRpdGxlXCIsY2hpbGRzKTtpZih0bXA9ZmV0Y2goXCJ1cGRhdGVkXCIsY2hpbGRzKSlmZWVkLnVwZGF0ZWQ9bmV3IERhdGUodG1wKTthZGRDb25kaXRpb25hbGx5KGZlZWQsXCJhdXRob3JcIixcImVtYWlsXCIsY2hpbGRzLHRydWUpO2ZlZWQuaXRlbXM9Z2V0RWxlbWVudHMoXCJlbnRyeVwiLGNoaWxkcykubWFwKGZ1bmN0aW9uKGl0ZW0pe3ZhciBlbnRyeT17fSx0bXA7aXRlbT1pdGVtLmNoaWxkcmVuO2FkZENvbmRpdGlvbmFsbHkoZW50cnksXCJpZFwiLFwiaWRcIixpdGVtKTthZGRDb25kaXRpb25hbGx5KGVudHJ5LFwidGl0bGVcIixcInRpdGxlXCIsaXRlbSk7aWYoKHRtcD1nZXRPbmVFbGVtZW50KFwibGlua1wiLGl0ZW0pKSYmKHRtcD10bXAuYXR0cmlicykmJih0bXA9dG1wLmhyZWYpKWVudHJ5Lmxpbms9dG1wO2lmKHRtcD1mZXRjaChcInN1bW1hcnlcIixpdGVtKXx8ZmV0Y2goXCJjb250ZW50XCIsaXRlbSkpZW50cnkuZGVzY3JpcHRpb249dG1wO2lmKHRtcD1mZXRjaChcInVwZGF0ZWRcIixpdGVtKSllbnRyeS5wdWJEYXRlPW5ldyBEYXRlKHRtcCk7cmV0dXJuIGVudHJ5fSl9ZWxzZXtjaGlsZHM9Z2V0T25lRWxlbWVudChcImNoYW5uZWxcIixmZWVkUm9vdC5jaGlsZHJlbikuY2hpbGRyZW47ZmVlZC50eXBlPWZlZWRSb290Lm5hbWUuc3Vic3RyKDAsMyk7ZmVlZC5pZD1cIlwiO2FkZENvbmRpdGlvbmFsbHkoZmVlZCxcInRpdGxlXCIsXCJ0aXRsZVwiLGNoaWxkcyk7YWRkQ29uZGl0aW9uYWxseShmZWVkLFwibGlua1wiLFwibGlua1wiLGNoaWxkcyk7YWRkQ29uZGl0aW9uYWxseShmZWVkLFwiZGVzY3JpcHRpb25cIixcImRlc2NyaXB0aW9uXCIsY2hpbGRzKTtpZih0bXA9ZmV0Y2goXCJsYXN0QnVpbGREYXRlXCIsY2hpbGRzKSlmZWVkLnVwZGF0ZWQ9bmV3IERhdGUodG1wKTthZGRDb25kaXRpb25hbGx5KGZlZWQsXCJhdXRob3JcIixcIm1hbmFnaW5nRWRpdG9yXCIsY2hpbGRzLHRydWUpO2ZlZWQuaXRlbXM9Z2V0RWxlbWVudHMoXCJpdGVtXCIsZmVlZFJvb3QuY2hpbGRyZW4pLm1hcChmdW5jdGlvbihpdGVtKXt2YXIgZW50cnk9e30sdG1wO2l0ZW09aXRlbS5jaGlsZHJlbjthZGRDb25kaXRpb25hbGx5KGVudHJ5LFwiaWRcIixcImd1aWRcIixpdGVtKTthZGRDb25kaXRpb25hbGx5KGVudHJ5LFwidGl0bGVcIixcInRpdGxlXCIsaXRlbSk7YWRkQ29uZGl0aW9uYWxseShlbnRyeSxcImxpbmtcIixcImxpbmtcIixpdGVtKTthZGRDb25kaXRpb25hbGx5KGVudHJ5LFwiZGVzY3JpcHRpb25cIixcImRlc2NyaXB0aW9uXCIsaXRlbSk7aWYodG1wPWZldGNoKFwicHViRGF0ZVwiLGl0ZW0pKWVudHJ5LnB1YkRhdGU9bmV3IERhdGUodG1wKTtyZXR1cm4gZW50cnl9KX19dGhpcy5kb209ZmVlZDtEb21IYW5kbGVyLnByb3RvdHlwZS5faGFuZGxlQ2FsbGJhY2suY2FsbCh0aGlzLGZlZWRSb290P251bGw6RXJyb3IoXCJjb3VsZG4ndCBmaW5kIHJvb3Qgb2YgZmVlZFwiKSl9O21vZHVsZS5leHBvcnRzPUZlZWRIYW5kbGVyfSx7XCIuL2luZGV4LmpzXCI6MzYsaW5oZXJpdHM6Mzh9XSwzMTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIFRva2VuaXplcj1yZXF1aXJlKFwiLi9Ub2tlbml6ZXIuanNcIik7dmFyIGZvcm1UYWdzPXtpbnB1dDp0cnVlLG9wdGlvbjp0cnVlLG9wdGdyb3VwOnRydWUsc2VsZWN0OnRydWUsYnV0dG9uOnRydWUsZGF0YWxpc3Q6dHJ1ZSx0ZXh0YXJlYTp0cnVlfTt2YXIgb3BlbkltcGxpZXNDbG9zZT17dHI6e3RyOnRydWUsdGg6dHJ1ZSx0ZDp0cnVlfSx0aDp7dGg6dHJ1ZX0sdGQ6e3RoZWFkOnRydWUsdGg6dHJ1ZSx0ZDp0cnVlfSxib2R5OntoZWFkOnRydWUsbGluazp0cnVlLHNjcmlwdDp0cnVlfSxsaTp7bGk6dHJ1ZX0scDp7cDp0cnVlfSxoMTp7cDp0cnVlfSxoMjp7cDp0cnVlfSxoMzp7cDp0cnVlfSxoNDp7cDp0cnVlfSxoNTp7cDp0cnVlfSxoNjp7cDp0cnVlfSxzZWxlY3Q6Zm9ybVRhZ3MsaW5wdXQ6Zm9ybVRhZ3Msb3V0cHV0OmZvcm1UYWdzLGJ1dHRvbjpmb3JtVGFncyxkYXRhbGlzdDpmb3JtVGFncyx0ZXh0YXJlYTpmb3JtVGFncyxvcHRpb246e29wdGlvbjp0cnVlfSxvcHRncm91cDp7b3B0Z3JvdXA6dHJ1ZX19O3ZhciB2b2lkRWxlbWVudHM9e19fcHJvdG9fXzpudWxsLGFyZWE6dHJ1ZSxiYXNlOnRydWUsYmFzZWZvbnQ6dHJ1ZSxicjp0cnVlLGNvbDp0cnVlLGNvbW1hbmQ6dHJ1ZSxlbWJlZDp0cnVlLGZyYW1lOnRydWUsaHI6dHJ1ZSxpbWc6dHJ1ZSxpbnB1dDp0cnVlLGlzaW5kZXg6dHJ1ZSxrZXlnZW46dHJ1ZSxsaW5rOnRydWUsbWV0YTp0cnVlLHBhcmFtOnRydWUsc291cmNlOnRydWUsdHJhY2s6dHJ1ZSx3YnI6dHJ1ZSxwYXRoOnRydWUsY2lyY2xlOnRydWUsZWxsaXBzZTp0cnVlLGxpbmU6dHJ1ZSxyZWN0OnRydWUsdXNlOnRydWUsc3RvcDp0cnVlLHBvbHlsaW5lOnRydWUscG9seWdvbjp0cnVlfTt2YXIgcmVfbmFtZUVuZD0vXFxzfFxcLy87ZnVuY3Rpb24gUGFyc2VyKGNicyxvcHRpb25zKXt0aGlzLl9vcHRpb25zPW9wdGlvbnN8fHt9O3RoaXMuX2Nicz1jYnN8fHt9O3RoaXMuX3RhZ25hbWU9XCJcIjt0aGlzLl9hdHRyaWJuYW1lPVwiXCI7dGhpcy5fYXR0cmlidmFsdWU9XCJcIjt0aGlzLl9hdHRyaWJzPW51bGw7dGhpcy5fc3RhY2s9W107dGhpcy5zdGFydEluZGV4PTA7dGhpcy5lbmRJbmRleD1udWxsO3RoaXMuX2xvd2VyQ2FzZVRhZ05hbWVzPVwibG93ZXJDYXNlVGFnc1wiaW4gdGhpcy5fb3B0aW9ucz8hIXRoaXMuX29wdGlvbnMubG93ZXJDYXNlVGFnczohdGhpcy5fb3B0aW9ucy54bWxNb2RlO3RoaXMuX2xvd2VyQ2FzZUF0dHJpYnV0ZU5hbWVzPVwibG93ZXJDYXNlQXR0cmlidXRlTmFtZXNcImluIHRoaXMuX29wdGlvbnM/ISF0aGlzLl9vcHRpb25zLmxvd2VyQ2FzZUF0dHJpYnV0ZU5hbWVzOiF0aGlzLl9vcHRpb25zLnhtbE1vZGU7aWYodGhpcy5fb3B0aW9ucy5Ub2tlbml6ZXIpe1Rva2VuaXplcj10aGlzLl9vcHRpb25zLlRva2VuaXplcn10aGlzLl90b2tlbml6ZXI9bmV3IFRva2VuaXplcih0aGlzLl9vcHRpb25zLHRoaXMpO2lmKHRoaXMuX2Nicy5vbnBhcnNlcmluaXQpdGhpcy5fY2JzLm9ucGFyc2VyaW5pdCh0aGlzKX1yZXF1aXJlKFwiaW5oZXJpdHNcIikoUGFyc2VyLHJlcXVpcmUoXCJldmVudHNcIikuRXZlbnRFbWl0dGVyKTtQYXJzZXIucHJvdG90eXBlLl91cGRhdGVQb3NpdGlvbj1mdW5jdGlvbihpbml0aWFsT2Zmc2V0KXtpZih0aGlzLmVuZEluZGV4PT09bnVsbCl7aWYodGhpcy5fdG9rZW5pemVyLl9zZWN0aW9uU3RhcnQ8PWluaXRpYWxPZmZzZXQpe3RoaXMuc3RhcnRJbmRleD0wfWVsc2V7dGhpcy5zdGFydEluZGV4PXRoaXMuX3Rva2VuaXplci5fc2VjdGlvblN0YXJ0LWluaXRpYWxPZmZzZXR9fWVsc2UgdGhpcy5zdGFydEluZGV4PXRoaXMuZW5kSW5kZXgrMTt0aGlzLmVuZEluZGV4PXRoaXMuX3Rva2VuaXplci5nZXRBYnNvbHV0ZUluZGV4KCl9O1BhcnNlci5wcm90b3R5cGUub250ZXh0PWZ1bmN0aW9uKGRhdGEpe3RoaXMuX3VwZGF0ZVBvc2l0aW9uKDEpO3RoaXMuZW5kSW5kZXgtLTtpZih0aGlzLl9jYnMub250ZXh0KXRoaXMuX2Nicy5vbnRleHQoZGF0YSl9O1BhcnNlci5wcm90b3R5cGUub25vcGVudGFnbmFtZT1mdW5jdGlvbihuYW1lKXtpZih0aGlzLl9sb3dlckNhc2VUYWdOYW1lcyl7bmFtZT1uYW1lLnRvTG93ZXJDYXNlKCl9dGhpcy5fdGFnbmFtZT1uYW1lO2lmKCF0aGlzLl9vcHRpb25zLnhtbE1vZGUmJm5hbWUgaW4gb3BlbkltcGxpZXNDbG9zZSl7Zm9yKHZhciBlbDsoZWw9dGhpcy5fc3RhY2tbdGhpcy5fc3RhY2subGVuZ3RoLTFdKWluIG9wZW5JbXBsaWVzQ2xvc2VbbmFtZV07dGhpcy5vbmNsb3NldGFnKGVsKSk7fWlmKHRoaXMuX29wdGlvbnMueG1sTW9kZXx8IShuYW1lIGluIHZvaWRFbGVtZW50cykpe3RoaXMuX3N0YWNrLnB1c2gobmFtZSl9aWYodGhpcy5fY2JzLm9ub3BlbnRhZ25hbWUpdGhpcy5fY2JzLm9ub3BlbnRhZ25hbWUobmFtZSk7aWYodGhpcy5fY2JzLm9ub3BlbnRhZyl0aGlzLl9hdHRyaWJzPXt9fTtQYXJzZXIucHJvdG90eXBlLm9ub3BlbnRhZ2VuZD1mdW5jdGlvbigpe3RoaXMuX3VwZGF0ZVBvc2l0aW9uKDEpO2lmKHRoaXMuX2F0dHJpYnMpe2lmKHRoaXMuX2Nicy5vbm9wZW50YWcpdGhpcy5fY2JzLm9ub3BlbnRhZyh0aGlzLl90YWduYW1lLHRoaXMuX2F0dHJpYnMpO3RoaXMuX2F0dHJpYnM9bnVsbH1pZighdGhpcy5fb3B0aW9ucy54bWxNb2RlJiZ0aGlzLl9jYnMub25jbG9zZXRhZyYmdGhpcy5fdGFnbmFtZSBpbiB2b2lkRWxlbWVudHMpe3RoaXMuX2Nicy5vbmNsb3NldGFnKHRoaXMuX3RhZ25hbWUpfXRoaXMuX3RhZ25hbWU9XCJcIn07UGFyc2VyLnByb3RvdHlwZS5vbmNsb3NldGFnPWZ1bmN0aW9uKG5hbWUpe3RoaXMuX3VwZGF0ZVBvc2l0aW9uKDEpO2lmKHRoaXMuX2xvd2VyQ2FzZVRhZ05hbWVzKXtuYW1lPW5hbWUudG9Mb3dlckNhc2UoKX1pZih0aGlzLl9zdGFjay5sZW5ndGgmJighKG5hbWUgaW4gdm9pZEVsZW1lbnRzKXx8dGhpcy5fb3B0aW9ucy54bWxNb2RlKSl7dmFyIHBvcz10aGlzLl9zdGFjay5sYXN0SW5kZXhPZihuYW1lKTtpZihwb3MhPT0tMSl7aWYodGhpcy5fY2JzLm9uY2xvc2V0YWcpe3Bvcz10aGlzLl9zdGFjay5sZW5ndGgtcG9zO3doaWxlKHBvcy0tKXRoaXMuX2Nicy5vbmNsb3NldGFnKHRoaXMuX3N0YWNrLnBvcCgpKX1lbHNlIHRoaXMuX3N0YWNrLmxlbmd0aD1wb3N9ZWxzZSBpZihuYW1lPT09XCJwXCImJiF0aGlzLl9vcHRpb25zLnhtbE1vZGUpe3RoaXMub25vcGVudGFnbmFtZShuYW1lKTt0aGlzLl9jbG9zZUN1cnJlbnRUYWcoKX19ZWxzZSBpZighdGhpcy5fb3B0aW9ucy54bWxNb2RlJiYobmFtZT09PVwiYnJcInx8bmFtZT09PVwicFwiKSl7dGhpcy5vbm9wZW50YWduYW1lKG5hbWUpO3RoaXMuX2Nsb3NlQ3VycmVudFRhZygpfX07UGFyc2VyLnByb3RvdHlwZS5vbnNlbGZjbG9zaW5ndGFnPWZ1bmN0aW9uKCl7aWYodGhpcy5fb3B0aW9ucy54bWxNb2RlfHx0aGlzLl9vcHRpb25zLnJlY29nbml6ZVNlbGZDbG9zaW5nKXt0aGlzLl9jbG9zZUN1cnJlbnRUYWcoKX1lbHNle3RoaXMub25vcGVudGFnZW5kKCl9fTtQYXJzZXIucHJvdG90eXBlLl9jbG9zZUN1cnJlbnRUYWc9ZnVuY3Rpb24oKXt2YXIgbmFtZT10aGlzLl90YWduYW1lO3RoaXMub25vcGVudGFnZW5kKCk7aWYodGhpcy5fc3RhY2tbdGhpcy5fc3RhY2subGVuZ3RoLTFdPT09bmFtZSl7aWYodGhpcy5fY2JzLm9uY2xvc2V0YWcpe3RoaXMuX2Nicy5vbmNsb3NldGFnKG5hbWUpfXRoaXMuX3N0YWNrLnBvcCgpfX07UGFyc2VyLnByb3RvdHlwZS5vbmF0dHJpYm5hbWU9ZnVuY3Rpb24obmFtZSl7aWYodGhpcy5fbG93ZXJDYXNlQXR0cmlidXRlTmFtZXMpe25hbWU9bmFtZS50b0xvd2VyQ2FzZSgpfXRoaXMuX2F0dHJpYm5hbWU9bmFtZX07UGFyc2VyLnByb3RvdHlwZS5vbmF0dHJpYmRhdGE9ZnVuY3Rpb24odmFsdWUpe3RoaXMuX2F0dHJpYnZhbHVlKz12YWx1ZX07UGFyc2VyLnByb3RvdHlwZS5vbmF0dHJpYmVuZD1mdW5jdGlvbigpe2lmKHRoaXMuX2Nicy5vbmF0dHJpYnV0ZSl0aGlzLl9jYnMub25hdHRyaWJ1dGUodGhpcy5fYXR0cmlibmFtZSx0aGlzLl9hdHRyaWJ2YWx1ZSk7aWYodGhpcy5fYXR0cmlicyYmIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLl9hdHRyaWJzLHRoaXMuX2F0dHJpYm5hbWUpKXt0aGlzLl9hdHRyaWJzW3RoaXMuX2F0dHJpYm5hbWVdPXRoaXMuX2F0dHJpYnZhbHVlfXRoaXMuX2F0dHJpYm5hbWU9XCJcIjt0aGlzLl9hdHRyaWJ2YWx1ZT1cIlwifTtQYXJzZXIucHJvdG90eXBlLl9nZXRJbnN0cnVjdGlvbk5hbWU9ZnVuY3Rpb24odmFsdWUpe3ZhciBpZHg9dmFsdWUuc2VhcmNoKHJlX25hbWVFbmQpLG5hbWU9aWR4PDA/dmFsdWU6dmFsdWUuc3Vic3RyKDAsaWR4KTtpZih0aGlzLl9sb3dlckNhc2VUYWdOYW1lcyl7bmFtZT1uYW1lLnRvTG93ZXJDYXNlKCl9cmV0dXJuIG5hbWV9O1BhcnNlci5wcm90b3R5cGUub25kZWNsYXJhdGlvbj1mdW5jdGlvbih2YWx1ZSl7aWYodGhpcy5fY2JzLm9ucHJvY2Vzc2luZ2luc3RydWN0aW9uKXt2YXIgbmFtZT10aGlzLl9nZXRJbnN0cnVjdGlvbk5hbWUodmFsdWUpO3RoaXMuX2Nicy5vbnByb2Nlc3NpbmdpbnN0cnVjdGlvbihcIiFcIituYW1lLFwiIVwiK3ZhbHVlKX19O1BhcnNlci5wcm90b3R5cGUub25wcm9jZXNzaW5naW5zdHJ1Y3Rpb249ZnVuY3Rpb24odmFsdWUpe2lmKHRoaXMuX2Nicy5vbnByb2Nlc3NpbmdpbnN0cnVjdGlvbil7dmFyIG5hbWU9dGhpcy5fZ2V0SW5zdHJ1Y3Rpb25OYW1lKHZhbHVlKTt0aGlzLl9jYnMub25wcm9jZXNzaW5naW5zdHJ1Y3Rpb24oXCI/XCIrbmFtZSxcIj9cIit2YWx1ZSl9fTtQYXJzZXIucHJvdG90eXBlLm9uY29tbWVudD1mdW5jdGlvbih2YWx1ZSl7dGhpcy5fdXBkYXRlUG9zaXRpb24oNCk7aWYodGhpcy5fY2JzLm9uY29tbWVudCl0aGlzLl9jYnMub25jb21tZW50KHZhbHVlKTtpZih0aGlzLl9jYnMub25jb21tZW50ZW5kKXRoaXMuX2Nicy5vbmNvbW1lbnRlbmQoKX07UGFyc2VyLnByb3RvdHlwZS5vbmNkYXRhPWZ1bmN0aW9uKHZhbHVlKXt0aGlzLl91cGRhdGVQb3NpdGlvbigxKTtpZih0aGlzLl9vcHRpb25zLnhtbE1vZGV8fHRoaXMuX29wdGlvbnMucmVjb2duaXplQ0RBVEEpe2lmKHRoaXMuX2Nicy5vbmNkYXRhc3RhcnQpdGhpcy5fY2JzLm9uY2RhdGFzdGFydCgpO2lmKHRoaXMuX2Nicy5vbnRleHQpdGhpcy5fY2JzLm9udGV4dCh2YWx1ZSk7aWYodGhpcy5fY2JzLm9uY2RhdGFlbmQpdGhpcy5fY2JzLm9uY2RhdGFlbmQoKX1lbHNle3RoaXMub25jb21tZW50KFwiW0NEQVRBW1wiK3ZhbHVlK1wiXV1cIil9fTtQYXJzZXIucHJvdG90eXBlLm9uZXJyb3I9ZnVuY3Rpb24oZXJyKXtpZih0aGlzLl9jYnMub25lcnJvcil0aGlzLl9jYnMub25lcnJvcihlcnIpfTtQYXJzZXIucHJvdG90eXBlLm9uZW5kPWZ1bmN0aW9uKCl7aWYodGhpcy5fY2JzLm9uY2xvc2V0YWcpe2Zvcih2YXIgaT10aGlzLl9zdGFjay5sZW5ndGg7aT4wO3RoaXMuX2Nicy5vbmNsb3NldGFnKHRoaXMuX3N0YWNrWy0taV0pKTt9aWYodGhpcy5fY2JzLm9uZW5kKXRoaXMuX2Nicy5vbmVuZCgpfTtQYXJzZXIucHJvdG90eXBlLnJlc2V0PWZ1bmN0aW9uKCl7aWYodGhpcy5fY2JzLm9ucmVzZXQpdGhpcy5fY2JzLm9ucmVzZXQoKTt0aGlzLl90b2tlbml6ZXIucmVzZXQoKTt0aGlzLl90YWduYW1lPVwiXCI7dGhpcy5fYXR0cmlibmFtZT1cIlwiO3RoaXMuX2F0dHJpYnM9bnVsbDt0aGlzLl9zdGFjaz1bXTtpZih0aGlzLl9jYnMub25wYXJzZXJpbml0KXRoaXMuX2Nicy5vbnBhcnNlcmluaXQodGhpcyl9O1BhcnNlci5wcm90b3R5cGUucGFyc2VDb21wbGV0ZT1mdW5jdGlvbihkYXRhKXt0aGlzLnJlc2V0KCk7dGhpcy5lbmQoZGF0YSl9O1BhcnNlci5wcm90b3R5cGUud3JpdGU9ZnVuY3Rpb24oY2h1bmspe3RoaXMuX3Rva2VuaXplci53cml0ZShjaHVuayl9O1BhcnNlci5wcm90b3R5cGUuZW5kPWZ1bmN0aW9uKGNodW5rKXt0aGlzLl90b2tlbml6ZXIuZW5kKGNodW5rKX07UGFyc2VyLnByb3RvdHlwZS5wYXVzZT1mdW5jdGlvbigpe3RoaXMuX3Rva2VuaXplci5wYXVzZSgpfTtQYXJzZXIucHJvdG90eXBlLnJlc3VtZT1mdW5jdGlvbigpe3RoaXMuX3Rva2VuaXplci5yZXN1bWUoKX07UGFyc2VyLnByb3RvdHlwZS5wYXJzZUNodW5rPVBhcnNlci5wcm90b3R5cGUud3JpdGU7UGFyc2VyLnByb3RvdHlwZS5kb25lPVBhcnNlci5wcm90b3R5cGUuZW5kO21vZHVsZS5leHBvcnRzPVBhcnNlcn0se1wiLi9Ub2tlbml6ZXIuanNcIjozNCxldmVudHM6MjgsaW5oZXJpdHM6Mzh9XSwzMjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9UHJveHlIYW5kbGVyO2Z1bmN0aW9uIFByb3h5SGFuZGxlcihjYnMpe3RoaXMuX2Nicz1jYnN8fHt9fXZhciBFVkVOVFM9cmVxdWlyZShcIi4vXCIpLkVWRU5UUztPYmplY3Qua2V5cyhFVkVOVFMpLmZvckVhY2goZnVuY3Rpb24obmFtZSl7aWYoRVZFTlRTW25hbWVdPT09MCl7bmFtZT1cIm9uXCIrbmFtZTtQcm94eUhhbmRsZXIucHJvdG90eXBlW25hbWVdPWZ1bmN0aW9uKCl7aWYodGhpcy5fY2JzW25hbWVdKXRoaXMuX2Nic1tuYW1lXSgpfX1lbHNlIGlmKEVWRU5UU1tuYW1lXT09PTEpe25hbWU9XCJvblwiK25hbWU7UHJveHlIYW5kbGVyLnByb3RvdHlwZVtuYW1lXT1mdW5jdGlvbihhKXtpZih0aGlzLl9jYnNbbmFtZV0pdGhpcy5fY2JzW25hbWVdKGEpfX1lbHNlIGlmKEVWRU5UU1tuYW1lXT09PTIpe25hbWU9XCJvblwiK25hbWU7UHJveHlIYW5kbGVyLnByb3RvdHlwZVtuYW1lXT1mdW5jdGlvbihhLGIpe2lmKHRoaXMuX2Nic1tuYW1lXSl0aGlzLl9jYnNbbmFtZV0oYSxiKX19ZWxzZXt0aHJvdyBFcnJvcihcIndyb25nIG51bWJlciBvZiBhcmd1bWVudHNcIil9fSl9LHtcIi4vXCI6MzZ9XSwzMzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9U3RyZWFtO3ZhciBQYXJzZXI9cmVxdWlyZShcIi4vV3JpdGFibGVTdHJlYW0uanNcIik7ZnVuY3Rpb24gU3RyZWFtKG9wdGlvbnMpe1BhcnNlci5jYWxsKHRoaXMsbmV3IENicyh0aGlzKSxvcHRpb25zKX1yZXF1aXJlKFwiaW5oZXJpdHNcIikoU3RyZWFtLFBhcnNlcik7U3RyZWFtLnByb3RvdHlwZS5yZWFkYWJsZT10cnVlO2Z1bmN0aW9uIENicyhzY29wZSl7dGhpcy5zY29wZT1zY29wZX12YXIgRVZFTlRTPXJlcXVpcmUoXCIuLi9cIikuRVZFTlRTO09iamVjdC5rZXlzKEVWRU5UUykuZm9yRWFjaChmdW5jdGlvbihuYW1lKXtpZihFVkVOVFNbbmFtZV09PT0wKXtDYnMucHJvdG90eXBlW1wib25cIituYW1lXT1mdW5jdGlvbigpe3RoaXMuc2NvcGUuZW1pdChuYW1lKX19ZWxzZSBpZihFVkVOVFNbbmFtZV09PT0xKXtDYnMucHJvdG90eXBlW1wib25cIituYW1lXT1mdW5jdGlvbihhKXt0aGlzLnNjb3BlLmVtaXQobmFtZSxhKX19ZWxzZSBpZihFVkVOVFNbbmFtZV09PT0yKXtDYnMucHJvdG90eXBlW1wib25cIituYW1lXT1mdW5jdGlvbihhLGIpe3RoaXMuc2NvcGUuZW1pdChuYW1lLGEsYil9fWVsc2V7dGhyb3cgRXJyb3IoXCJ3cm9uZyBudW1iZXIgb2YgYXJndW1lbnRzIVwiKX19KX0se1wiLi4vXCI6MzYsXCIuL1dyaXRhYmxlU3RyZWFtLmpzXCI6MzUsaW5oZXJpdHM6Mzh9XSwzNDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9VG9rZW5pemVyO3ZhciBkZWNvZGVDb2RlUG9pbnQ9cmVxdWlyZShcImVudGl0aWVzL2xpYi9kZWNvZGVfY29kZXBvaW50LmpzXCIpLGVudGl0eU1hcD1yZXF1aXJlKFwiZW50aXRpZXMvbWFwcy9lbnRpdGllcy5qc29uXCIpLGxlZ2FjeU1hcD1yZXF1aXJlKFwiZW50aXRpZXMvbWFwcy9sZWdhY3kuanNvblwiKSx4bWxNYXA9cmVxdWlyZShcImVudGl0aWVzL21hcHMveG1sLmpzb25cIiksaT0wLFRFWFQ9aSsrLEJFRk9SRV9UQUdfTkFNRT1pKyssSU5fVEFHX05BTUU9aSsrLElOX1NFTEZfQ0xPU0lOR19UQUc9aSsrLEJFRk9SRV9DTE9TSU5HX1RBR19OQU1FPWkrKyxJTl9DTE9TSU5HX1RBR19OQU1FPWkrKyxBRlRFUl9DTE9TSU5HX1RBR19OQU1FPWkrKyxCRUZPUkVfQVRUUklCVVRFX05BTUU9aSsrLElOX0FUVFJJQlVURV9OQU1FPWkrKyxBRlRFUl9BVFRSSUJVVEVfTkFNRT1pKyssQkVGT1JFX0FUVFJJQlVURV9WQUxVRT1pKyssSU5fQVRUUklCVVRFX1ZBTFVFX0RRPWkrKyxJTl9BVFRSSUJVVEVfVkFMVUVfU1E9aSsrLElOX0FUVFJJQlVURV9WQUxVRV9OUT1pKyssQkVGT1JFX0RFQ0xBUkFUSU9OPWkrKyxJTl9ERUNMQVJBVElPTj1pKyssSU5fUFJPQ0VTU0lOR19JTlNUUlVDVElPTj1pKyssQkVGT1JFX0NPTU1FTlQ9aSsrLElOX0NPTU1FTlQ9aSsrLEFGVEVSX0NPTU1FTlRfMT1pKyssQUZURVJfQ09NTUVOVF8yPWkrKyxCRUZPUkVfQ0RBVEFfMT1pKyssQkVGT1JFX0NEQVRBXzI9aSsrLEJFRk9SRV9DREFUQV8zPWkrKyxCRUZPUkVfQ0RBVEFfND1pKyssQkVGT1JFX0NEQVRBXzU9aSsrLEJFRk9SRV9DREFUQV82PWkrKyxJTl9DREFUQT1pKyssQUZURVJfQ0RBVEFfMT1pKyssQUZURVJfQ0RBVEFfMj1pKyssQkVGT1JFX1NQRUNJQUw9aSsrLEJFRk9SRV9TUEVDSUFMX0VORD1pKyssQkVGT1JFX1NDUklQVF8xPWkrKyxCRUZPUkVfU0NSSVBUXzI9aSsrLEJFRk9SRV9TQ1JJUFRfMz1pKyssQkVGT1JFX1NDUklQVF80PWkrKyxCRUZPUkVfU0NSSVBUXzU9aSsrLEFGVEVSX1NDUklQVF8xPWkrKyxBRlRFUl9TQ1JJUFRfMj1pKyssQUZURVJfU0NSSVBUXzM9aSsrLEFGVEVSX1NDUklQVF80PWkrKyxBRlRFUl9TQ1JJUFRfNT1pKyssQkVGT1JFX1NUWUxFXzE9aSsrLEJFRk9SRV9TVFlMRV8yPWkrKyxCRUZPUkVfU1RZTEVfMz1pKyssQkVGT1JFX1NUWUxFXzQ9aSsrLEFGVEVSX1NUWUxFXzE9aSsrLEFGVEVSX1NUWUxFXzI9aSsrLEFGVEVSX1NUWUxFXzM9aSsrLEFGVEVSX1NUWUxFXzQ9aSsrLEJFRk9SRV9FTlRJVFk9aSsrLEJFRk9SRV9OVU1FUklDX0VOVElUWT1pKyssSU5fTkFNRURfRU5USVRZPWkrKyxJTl9OVU1FUklDX0VOVElUWT1pKyssSU5fSEVYX0VOVElUWT1pKyssaj0wLFNQRUNJQUxfTk9ORT1qKyssU1BFQ0lBTF9TQ1JJUFQ9aisrLFNQRUNJQUxfU1RZTEU9aisrO2Z1bmN0aW9uIHdoaXRlc3BhY2UoYyl7cmV0dXJuIGM9PT1cIiBcInx8Yz09PVwiXFxuXCJ8fGM9PT1cIlxcdFwifHxjPT09XCJcXGZcInx8Yz09PVwiXFxyXCJ9ZnVuY3Rpb24gY2hhcmFjdGVyU3RhdGUoY2hhcixTVUNDRVNTKXtyZXR1cm4gZnVuY3Rpb24oYyl7aWYoYz09PWNoYXIpdGhpcy5fc3RhdGU9U1VDQ0VTU319ZnVuY3Rpb24gaWZFbHNlU3RhdGUodXBwZXIsU1VDQ0VTUyxGQUlMVVJFKXt2YXIgbG93ZXI9dXBwZXIudG9Mb3dlckNhc2UoKTtpZih1cHBlcj09PWxvd2VyKXtyZXR1cm4gZnVuY3Rpb24oYyl7aWYoYz09PWxvd2VyKXt0aGlzLl9zdGF0ZT1TVUNDRVNTfWVsc2V7dGhpcy5fc3RhdGU9RkFJTFVSRTt0aGlzLl9pbmRleC0tfX19ZWxzZXtyZXR1cm4gZnVuY3Rpb24oYyl7aWYoYz09PWxvd2VyfHxjPT09dXBwZXIpe3RoaXMuX3N0YXRlPVNVQ0NFU1N9ZWxzZXt0aGlzLl9zdGF0ZT1GQUlMVVJFO3RoaXMuX2luZGV4LS19fX19ZnVuY3Rpb24gY29uc3VtZVNwZWNpYWxOYW1lQ2hhcih1cHBlcixORVhUX1NUQVRFKXt2YXIgbG93ZXI9dXBwZXIudG9Mb3dlckNhc2UoKTtyZXR1cm4gZnVuY3Rpb24oYyl7aWYoYz09PWxvd2VyfHxjPT09dXBwZXIpe3RoaXMuX3N0YXRlPU5FWFRfU1RBVEV9ZWxzZXt0aGlzLl9zdGF0ZT1JTl9UQUdfTkFNRTt0aGlzLl9pbmRleC0tfX19ZnVuY3Rpb24gVG9rZW5pemVyKG9wdGlvbnMsY2JzKXt0aGlzLl9zdGF0ZT1URVhUO3RoaXMuX2J1ZmZlcj1cIlwiO3RoaXMuX3NlY3Rpb25TdGFydD0wO3RoaXMuX2luZGV4PTA7dGhpcy5fYnVmZmVyT2Zmc2V0PTA7dGhpcy5fYmFzZVN0YXRlPVRFWFQ7dGhpcy5fc3BlY2lhbD1TUEVDSUFMX05PTkU7dGhpcy5fY2JzPWNiczt0aGlzLl9ydW5uaW5nPXRydWU7dGhpcy5fZW5kZWQ9ZmFsc2U7dGhpcy5feG1sTW9kZT0hIShvcHRpb25zJiZvcHRpb25zLnhtbE1vZGUpO3RoaXMuX2RlY29kZUVudGl0aWVzPSEhKG9wdGlvbnMmJm9wdGlvbnMuZGVjb2RlRW50aXRpZXMpfVRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlVGV4dD1mdW5jdGlvbihjKXtpZihjPT09XCI8XCIpe2lmKHRoaXMuX2luZGV4PnRoaXMuX3NlY3Rpb25TdGFydCl7dGhpcy5fY2JzLm9udGV4dCh0aGlzLl9nZXRTZWN0aW9uKCkpfXRoaXMuX3N0YXRlPUJFRk9SRV9UQUdfTkFNRTt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXh9ZWxzZSBpZih0aGlzLl9kZWNvZGVFbnRpdGllcyYmdGhpcy5fc3BlY2lhbD09PVNQRUNJQUxfTk9ORSYmYz09PVwiJlwiKXtpZih0aGlzLl9pbmRleD50aGlzLl9zZWN0aW9uU3RhcnQpe3RoaXMuX2Nicy5vbnRleHQodGhpcy5fZ2V0U2VjdGlvbigpKX10aGlzLl9iYXNlU3RhdGU9VEVYVDt0aGlzLl9zdGF0ZT1CRUZPUkVfRU5USVRZO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleH19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlVGFnTmFtZT1mdW5jdGlvbihjKXtpZihjPT09XCIvXCIpe3RoaXMuX3N0YXRlPUJFRk9SRV9DTE9TSU5HX1RBR19OQU1FfWVsc2UgaWYoYz09PVwiPFwiKXt0aGlzLl9jYnMub250ZXh0KHRoaXMuX2dldFNlY3Rpb24oKSk7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4fWVsc2UgaWYoYz09PVwiPlwifHx0aGlzLl9zcGVjaWFsIT09U1BFQ0lBTF9OT05FfHx3aGl0ZXNwYWNlKGMpKXt0aGlzLl9zdGF0ZT1URVhUfWVsc2UgaWYoYz09PVwiIVwiKXt0aGlzLl9zdGF0ZT1CRUZPUkVfREVDTEFSQVRJT047dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4KzF9ZWxzZSBpZihjPT09XCI/XCIpe3RoaXMuX3N0YXRlPUlOX1BST0NFU1NJTkdfSU5TVFJVQ1RJT047dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4KzF9ZWxzZXt0aGlzLl9zdGF0ZT0hdGhpcy5feG1sTW9kZSYmKGM9PT1cInNcInx8Yz09PVwiU1wiKT9CRUZPUkVfU1BFQ0lBTDpJTl9UQUdfTkFNRTt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXh9fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUluVGFnTmFtZT1mdW5jdGlvbihjKXtpZihjPT09XCIvXCJ8fGM9PT1cIj5cInx8d2hpdGVzcGFjZShjKSl7dGhpcy5fZW1pdFRva2VuKFwib25vcGVudGFnbmFtZVwiKTt0aGlzLl9zdGF0ZT1CRUZPUkVfQVRUUklCVVRFX05BTUU7dGhpcy5faW5kZXgtLX19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlQ2xvc2VpbmdUYWdOYW1lPWZ1bmN0aW9uKGMpe2lmKHdoaXRlc3BhY2UoYykpO2Vsc2UgaWYoYz09PVwiPlwiKXt0aGlzLl9zdGF0ZT1URVhUfWVsc2UgaWYodGhpcy5fc3BlY2lhbCE9PVNQRUNJQUxfTk9ORSl7aWYoYz09PVwic1wifHxjPT09XCJTXCIpe3RoaXMuX3N0YXRlPUJFRk9SRV9TUEVDSUFMX0VORH1lbHNle3RoaXMuX3N0YXRlPVRFWFQ7dGhpcy5faW5kZXgtLX19ZWxzZXt0aGlzLl9zdGF0ZT1JTl9DTE9TSU5HX1RBR19OQU1FO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleH19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5DbG9zZWluZ1RhZ05hbWU9ZnVuY3Rpb24oYyl7aWYoYz09PVwiPlwifHx3aGl0ZXNwYWNlKGMpKXt0aGlzLl9lbWl0VG9rZW4oXCJvbmNsb3NldGFnXCIpO3RoaXMuX3N0YXRlPUFGVEVSX0NMT1NJTkdfVEFHX05BTUU7dGhpcy5faW5kZXgtLX19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJDbG9zZWluZ1RhZ05hbWU9ZnVuY3Rpb24oYyl7aWYoYz09PVwiPlwiKXt0aGlzLl9zdGF0ZT1URVhUO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleCsxfX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVBdHRyaWJ1dGVOYW1lPWZ1bmN0aW9uKGMpe2lmKGM9PT1cIj5cIil7dGhpcy5fY2JzLm9ub3BlbnRhZ2VuZCgpO3RoaXMuX3N0YXRlPVRFWFQ7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4KzF9ZWxzZSBpZihjPT09XCIvXCIpe3RoaXMuX3N0YXRlPUlOX1NFTEZfQ0xPU0lOR19UQUd9ZWxzZSBpZighd2hpdGVzcGFjZShjKSl7dGhpcy5fc3RhdGU9SU5fQVRUUklCVVRFX05BTUU7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4fX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJblNlbGZDbG9zaW5nVGFnPWZ1bmN0aW9uKGMpe2lmKGM9PT1cIj5cIil7dGhpcy5fY2JzLm9uc2VsZmNsb3Npbmd0YWcoKTt0aGlzLl9zdGF0ZT1URVhUO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleCsxfWVsc2UgaWYoIXdoaXRlc3BhY2UoYykpe3RoaXMuX3N0YXRlPUJFRk9SRV9BVFRSSUJVVEVfTkFNRTt0aGlzLl9pbmRleC0tfX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJbkF0dHJpYnV0ZU5hbWU9ZnVuY3Rpb24oYyl7aWYoYz09PVwiPVwifHxjPT09XCIvXCJ8fGM9PT1cIj5cInx8d2hpdGVzcGFjZShjKSl7dGhpcy5fY2JzLm9uYXR0cmlibmFtZSh0aGlzLl9nZXRTZWN0aW9uKCkpO3RoaXMuX3NlY3Rpb25TdGFydD0tMTt0aGlzLl9zdGF0ZT1BRlRFUl9BVFRSSUJVVEVfTkFNRTt0aGlzLl9pbmRleC0tfX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlckF0dHJpYnV0ZU5hbWU9ZnVuY3Rpb24oYyl7aWYoYz09PVwiPVwiKXt0aGlzLl9zdGF0ZT1CRUZPUkVfQVRUUklCVVRFX1ZBTFVFfWVsc2UgaWYoYz09PVwiL1wifHxjPT09XCI+XCIpe3RoaXMuX2Nicy5vbmF0dHJpYmVuZCgpO3RoaXMuX3N0YXRlPUJFRk9SRV9BVFRSSUJVVEVfTkFNRTt0aGlzLl9pbmRleC0tfWVsc2UgaWYoIXdoaXRlc3BhY2UoYykpe3RoaXMuX2Nicy5vbmF0dHJpYmVuZCgpO3RoaXMuX3N0YXRlPUlOX0FUVFJJQlVURV9OQU1FO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleH19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlQXR0cmlidXRlVmFsdWU9ZnVuY3Rpb24oYyl7aWYoYz09PSdcIicpe3RoaXMuX3N0YXRlPUlOX0FUVFJJQlVURV9WQUxVRV9EUTt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXgrMX1lbHNlIGlmKGM9PT1cIidcIil7dGhpcy5fc3RhdGU9SU5fQVRUUklCVVRFX1ZBTFVFX1NRO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleCsxfWVsc2UgaWYoIXdoaXRlc3BhY2UoYykpe3RoaXMuX3N0YXRlPUlOX0FUVFJJQlVURV9WQUxVRV9OUTt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXg7dGhpcy5faW5kZXgtLX19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5BdHRyaWJ1dGVWYWx1ZURvdWJsZVF1b3Rlcz1mdW5jdGlvbihjKXtpZihjPT09J1wiJyl7dGhpcy5fZW1pdFRva2VuKFwib25hdHRyaWJkYXRhXCIpO3RoaXMuX2Nicy5vbmF0dHJpYmVuZCgpO3RoaXMuX3N0YXRlPUJFRk9SRV9BVFRSSUJVVEVfTkFNRX1lbHNlIGlmKHRoaXMuX2RlY29kZUVudGl0aWVzJiZjPT09XCImXCIpe3RoaXMuX2VtaXRUb2tlbihcIm9uYXR0cmliZGF0YVwiKTt0aGlzLl9iYXNlU3RhdGU9dGhpcy5fc3RhdGU7dGhpcy5fc3RhdGU9QkVGT1JFX0VOVElUWTt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXh9fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUluQXR0cmlidXRlVmFsdWVTaW5nbGVRdW90ZXM9ZnVuY3Rpb24oYyl7aWYoYz09PVwiJ1wiKXt0aGlzLl9lbWl0VG9rZW4oXCJvbmF0dHJpYmRhdGFcIik7dGhpcy5fY2JzLm9uYXR0cmliZW5kKCk7dGhpcy5fc3RhdGU9QkVGT1JFX0FUVFJJQlVURV9OQU1FfWVsc2UgaWYodGhpcy5fZGVjb2RlRW50aXRpZXMmJmM9PT1cIiZcIil7dGhpcy5fZW1pdFRva2VuKFwib25hdHRyaWJkYXRhXCIpO3RoaXMuX2Jhc2VTdGF0ZT10aGlzLl9zdGF0ZTt0aGlzLl9zdGF0ZT1CRUZPUkVfRU5USVRZO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleH19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5BdHRyaWJ1dGVWYWx1ZU5vUXVvdGVzPWZ1bmN0aW9uKGMpe2lmKHdoaXRlc3BhY2UoYyl8fGM9PT1cIj5cIil7dGhpcy5fZW1pdFRva2VuKFwib25hdHRyaWJkYXRhXCIpO3RoaXMuX2Nicy5vbmF0dHJpYmVuZCgpO3RoaXMuX3N0YXRlPUJFRk9SRV9BVFRSSUJVVEVfTkFNRTt0aGlzLl9pbmRleC0tfWVsc2UgaWYodGhpcy5fZGVjb2RlRW50aXRpZXMmJmM9PT1cIiZcIil7dGhpcy5fZW1pdFRva2VuKFwib25hdHRyaWJkYXRhXCIpO3RoaXMuX2Jhc2VTdGF0ZT10aGlzLl9zdGF0ZTt0aGlzLl9zdGF0ZT1CRUZPUkVfRU5USVRZO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleH19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlRGVjbGFyYXRpb249ZnVuY3Rpb24oYyl7dGhpcy5fc3RhdGU9Yz09PVwiW1wiP0JFRk9SRV9DREFUQV8xOmM9PT1cIi1cIj9CRUZPUkVfQ09NTUVOVDpJTl9ERUNMQVJBVElPTn07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJbkRlY2xhcmF0aW9uPWZ1bmN0aW9uKGMpe2lmKGM9PT1cIj5cIil7dGhpcy5fY2JzLm9uZGVjbGFyYXRpb24odGhpcy5fZ2V0U2VjdGlvbigpKTt0aGlzLl9zdGF0ZT1URVhUO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleCsxfX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJblByb2Nlc3NpbmdJbnN0cnVjdGlvbj1mdW5jdGlvbihjKXtpZihjPT09XCI+XCIpe3RoaXMuX2Nicy5vbnByb2Nlc3NpbmdpbnN0cnVjdGlvbih0aGlzLl9nZXRTZWN0aW9uKCkpO3RoaXMuX3N0YXRlPVRFWFQ7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4KzF9fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZUNvbW1lbnQ9ZnVuY3Rpb24oYyl7aWYoYz09PVwiLVwiKXt0aGlzLl9zdGF0ZT1JTl9DT01NRU5UO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleCsxfWVsc2V7dGhpcy5fc3RhdGU9SU5fREVDTEFSQVRJT059fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUluQ29tbWVudD1mdW5jdGlvbihjKXtpZihjPT09XCItXCIpdGhpcy5fc3RhdGU9QUZURVJfQ09NTUVOVF8xfTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUFmdGVyQ29tbWVudDE9ZnVuY3Rpb24oYyl7aWYoYz09PVwiLVwiKXt0aGlzLl9zdGF0ZT1BRlRFUl9DT01NRU5UXzJ9ZWxzZXt0aGlzLl9zdGF0ZT1JTl9DT01NRU5UfX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlckNvbW1lbnQyPWZ1bmN0aW9uKGMpe2lmKGM9PT1cIj5cIil7dGhpcy5fY2JzLm9uY29tbWVudCh0aGlzLl9idWZmZXIuc3Vic3RyaW5nKHRoaXMuX3NlY3Rpb25TdGFydCx0aGlzLl9pbmRleC0yKSk7dGhpcy5fc3RhdGU9VEVYVDt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXgrMX1lbHNlIGlmKGMhPT1cIi1cIil7dGhpcy5fc3RhdGU9SU5fQ09NTUVOVH19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlQ2RhdGExPWlmRWxzZVN0YXRlKFwiQ1wiLEJFRk9SRV9DREFUQV8yLElOX0RFQ0xBUkFUSU9OKTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZUNkYXRhMj1pZkVsc2VTdGF0ZShcIkRcIixCRUZPUkVfQ0RBVEFfMyxJTl9ERUNMQVJBVElPTik7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVDZGF0YTM9aWZFbHNlU3RhdGUoXCJBXCIsQkVGT1JFX0NEQVRBXzQsSU5fREVDTEFSQVRJT04pO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlQ2RhdGE0PWlmRWxzZVN0YXRlKFwiVFwiLEJFRk9SRV9DREFUQV81LElOX0RFQ0xBUkFUSU9OKTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZUNkYXRhNT1pZkVsc2VTdGF0ZShcIkFcIixCRUZPUkVfQ0RBVEFfNixJTl9ERUNMQVJBVElPTik7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVDZGF0YTY9ZnVuY3Rpb24oYyl7aWYoYz09PVwiW1wiKXt0aGlzLl9zdGF0ZT1JTl9DREFUQTt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXgrMX1lbHNle3RoaXMuX3N0YXRlPUlOX0RFQ0xBUkFUSU9OO3RoaXMuX2luZGV4LS19fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUluQ2RhdGE9ZnVuY3Rpb24oYyl7aWYoYz09PVwiXVwiKXRoaXMuX3N0YXRlPUFGVEVSX0NEQVRBXzF9O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJDZGF0YTE9Y2hhcmFjdGVyU3RhdGUoXCJdXCIsQUZURVJfQ0RBVEFfMik7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlckNkYXRhMj1mdW5jdGlvbihjKXtpZihjPT09XCI+XCIpe3RoaXMuX2Nicy5vbmNkYXRhKHRoaXMuX2J1ZmZlci5zdWJzdHJpbmcodGhpcy5fc2VjdGlvblN0YXJ0LHRoaXMuX2luZGV4LTIpKTt0aGlzLl9zdGF0ZT1URVhUO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleCsxfWVsc2UgaWYoYyE9PVwiXVwiKXt0aGlzLl9zdGF0ZT1JTl9DREFUQX19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlU3BlY2lhbD1mdW5jdGlvbihjKXtpZihjPT09XCJjXCJ8fGM9PT1cIkNcIil7dGhpcy5fc3RhdGU9QkVGT1JFX1NDUklQVF8xfWVsc2UgaWYoYz09PVwidFwifHxjPT09XCJUXCIpe3RoaXMuX3N0YXRlPUJFRk9SRV9TVFlMRV8xfWVsc2V7dGhpcy5fc3RhdGU9SU5fVEFHX05BTUU7dGhpcy5faW5kZXgtLX19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlU3BlY2lhbEVuZD1mdW5jdGlvbihjKXtpZih0aGlzLl9zcGVjaWFsPT09U1BFQ0lBTF9TQ1JJUFQmJihjPT09XCJjXCJ8fGM9PT1cIkNcIikpe3RoaXMuX3N0YXRlPUFGVEVSX1NDUklQVF8xfWVsc2UgaWYodGhpcy5fc3BlY2lhbD09PVNQRUNJQUxfU1RZTEUmJihjPT09XCJ0XCJ8fGM9PT1cIlRcIikpe3RoaXMuX3N0YXRlPUFGVEVSX1NUWUxFXzF9ZWxzZSB0aGlzLl9zdGF0ZT1URVhUfTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZVNjcmlwdDE9Y29uc3VtZVNwZWNpYWxOYW1lQ2hhcihcIlJcIixCRUZPUkVfU0NSSVBUXzIpO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlU2NyaXB0Mj1jb25zdW1lU3BlY2lhbE5hbWVDaGFyKFwiSVwiLEJFRk9SRV9TQ1JJUFRfMyk7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTY3JpcHQzPWNvbnN1bWVTcGVjaWFsTmFtZUNoYXIoXCJQXCIsQkVGT1JFX1NDUklQVF80KTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZVNjcmlwdDQ9Y29uc3VtZVNwZWNpYWxOYW1lQ2hhcihcIlRcIixCRUZPUkVfU0NSSVBUXzUpO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlU2NyaXB0NT1mdW5jdGlvbihjKXtpZihjPT09XCIvXCJ8fGM9PT1cIj5cInx8d2hpdGVzcGFjZShjKSl7dGhpcy5fc3BlY2lhbD1TUEVDSUFMX1NDUklQVH10aGlzLl9zdGF0ZT1JTl9UQUdfTkFNRTt0aGlzLl9pbmRleC0tfTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUFmdGVyU2NyaXB0MT1pZkVsc2VTdGF0ZShcIlJcIixBRlRFUl9TQ1JJUFRfMixURVhUKTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUFmdGVyU2NyaXB0Mj1pZkVsc2VTdGF0ZShcIklcIixBRlRFUl9TQ1JJUFRfMyxURVhUKTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUFmdGVyU2NyaXB0Mz1pZkVsc2VTdGF0ZShcIlBcIixBRlRFUl9TQ1JJUFRfNCxURVhUKTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUFmdGVyU2NyaXB0ND1pZkVsc2VTdGF0ZShcIlRcIixBRlRFUl9TQ1JJUFRfNSxURVhUKTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUFmdGVyU2NyaXB0NT1mdW5jdGlvbihjKXtpZihjPT09XCI+XCJ8fHdoaXRlc3BhY2UoYykpe3RoaXMuX3NwZWNpYWw9U1BFQ0lBTF9OT05FO3RoaXMuX3N0YXRlPUlOX0NMT1NJTkdfVEFHX05BTUU7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4LTY7dGhpcy5faW5kZXgtLX1lbHNlIHRoaXMuX3N0YXRlPVRFWFR9O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlU3R5bGUxPWNvbnN1bWVTcGVjaWFsTmFtZUNoYXIoXCJZXCIsQkVGT1JFX1NUWUxFXzIpO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlU3R5bGUyPWNvbnN1bWVTcGVjaWFsTmFtZUNoYXIoXCJMXCIsQkVGT1JFX1NUWUxFXzMpO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlU3R5bGUzPWNvbnN1bWVTcGVjaWFsTmFtZUNoYXIoXCJFXCIsQkVGT1JFX1NUWUxFXzQpO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlU3R5bGU0PWZ1bmN0aW9uKGMpe2lmKGM9PT1cIi9cInx8Yz09PVwiPlwifHx3aGl0ZXNwYWNlKGMpKXt0aGlzLl9zcGVjaWFsPVNQRUNJQUxfU1RZTEV9dGhpcy5fc3RhdGU9SU5fVEFHX05BTUU7dGhpcy5faW5kZXgtLX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlclN0eWxlMT1pZkVsc2VTdGF0ZShcIllcIixBRlRFUl9TVFlMRV8yLFRFWFQpO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTdHlsZTI9aWZFbHNlU3RhdGUoXCJMXCIsQUZURVJfU1RZTEVfMyxURVhUKTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUFmdGVyU3R5bGUzPWlmRWxzZVN0YXRlKFwiRVwiLEFGVEVSX1NUWUxFXzQsVEVYVCk7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlclN0eWxlND1mdW5jdGlvbihjKXtpZihjPT09XCI+XCJ8fHdoaXRlc3BhY2UoYykpe3RoaXMuX3NwZWNpYWw9U1BFQ0lBTF9OT05FO3RoaXMuX3N0YXRlPUlOX0NMT1NJTkdfVEFHX05BTUU7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4LTU7dGhpcy5faW5kZXgtLX1lbHNlIHRoaXMuX3N0YXRlPVRFWFR9O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlRW50aXR5PWlmRWxzZVN0YXRlKFwiI1wiLEJFRk9SRV9OVU1FUklDX0VOVElUWSxJTl9OQU1FRF9FTlRJVFkpO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlTnVtZXJpY0VudGl0eT1pZkVsc2VTdGF0ZShcIlhcIixJTl9IRVhfRU5USVRZLElOX05VTUVSSUNfRU5USVRZKTtUb2tlbml6ZXIucHJvdG90eXBlLl9wYXJzZU5hbWVkRW50aXR5U3RyaWN0PWZ1bmN0aW9uKCl7aWYodGhpcy5fc2VjdGlvblN0YXJ0KzE8dGhpcy5faW5kZXgpe3ZhciBlbnRpdHk9dGhpcy5fYnVmZmVyLnN1YnN0cmluZyh0aGlzLl9zZWN0aW9uU3RhcnQrMSx0aGlzLl9pbmRleCksbWFwPXRoaXMuX3htbE1vZGU/eG1sTWFwOmVudGl0eU1hcDtpZihtYXAuaGFzT3duUHJvcGVydHkoZW50aXR5KSl7dGhpcy5fZW1pdFBhcnRpYWwobWFwW2VudGl0eV0pO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleCsxfX19O1Rva2VuaXplci5wcm90b3R5cGUuX3BhcnNlTGVnYWN5RW50aXR5PWZ1bmN0aW9uKCl7dmFyIHN0YXJ0PXRoaXMuX3NlY3Rpb25TdGFydCsxLGxpbWl0PXRoaXMuX2luZGV4LXN0YXJ0O2lmKGxpbWl0PjYpbGltaXQ9Njt3aGlsZShsaW1pdD49Mil7dmFyIGVudGl0eT10aGlzLl9idWZmZXIuc3Vic3RyKHN0YXJ0LGxpbWl0KTtpZihsZWdhY3lNYXAuaGFzT3duUHJvcGVydHkoZW50aXR5KSl7dGhpcy5fZW1pdFBhcnRpYWwobGVnYWN5TWFwW2VudGl0eV0pO3RoaXMuX3NlY3Rpb25TdGFydCs9bGltaXQrMTtyZXR1cm59ZWxzZXtsaW1pdC0tfX19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5OYW1lZEVudGl0eT1mdW5jdGlvbihjKXtpZihjPT09XCI7XCIpe3RoaXMuX3BhcnNlTmFtZWRFbnRpdHlTdHJpY3QoKTtpZih0aGlzLl9zZWN0aW9uU3RhcnQrMTx0aGlzLl9pbmRleCYmIXRoaXMuX3htbE1vZGUpe3RoaXMuX3BhcnNlTGVnYWN5RW50aXR5KCl9dGhpcy5fc3RhdGU9dGhpcy5fYmFzZVN0YXRlfWVsc2UgaWYoKGM8XCJhXCJ8fGM+XCJ6XCIpJiYoYzxcIkFcInx8Yz5cIlpcIikmJihjPFwiMFwifHxjPlwiOVwiKSl7aWYodGhpcy5feG1sTW9kZSk7ZWxzZSBpZih0aGlzLl9zZWN0aW9uU3RhcnQrMT09PXRoaXMuX2luZGV4KTtlbHNlIGlmKHRoaXMuX2Jhc2VTdGF0ZSE9PVRFWFQpe2lmKGMhPT1cIj1cIil7dGhpcy5fcGFyc2VOYW1lZEVudGl0eVN0cmljdCgpfX1lbHNle3RoaXMuX3BhcnNlTGVnYWN5RW50aXR5KCl9dGhpcy5fc3RhdGU9dGhpcy5fYmFzZVN0YXRlO3RoaXMuX2luZGV4LS19fTtUb2tlbml6ZXIucHJvdG90eXBlLl9kZWNvZGVOdW1lcmljRW50aXR5PWZ1bmN0aW9uKG9mZnNldCxiYXNlKXt2YXIgc2VjdGlvblN0YXJ0PXRoaXMuX3NlY3Rpb25TdGFydCtvZmZzZXQ7aWYoc2VjdGlvblN0YXJ0IT09dGhpcy5faW5kZXgpe3ZhciBlbnRpdHk9dGhpcy5fYnVmZmVyLnN1YnN0cmluZyhzZWN0aW9uU3RhcnQsdGhpcy5faW5kZXgpO3ZhciBwYXJzZWQ9cGFyc2VJbnQoZW50aXR5LGJhc2UpO3RoaXMuX2VtaXRQYXJ0aWFsKGRlY29kZUNvZGVQb2ludChwYXJzZWQpKTt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXh9ZWxzZXt0aGlzLl9zZWN0aW9uU3RhcnQtLX10aGlzLl9zdGF0ZT10aGlzLl9iYXNlU3RhdGV9O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5OdW1lcmljRW50aXR5PWZ1bmN0aW9uKGMpe2lmKGM9PT1cIjtcIil7dGhpcy5fZGVjb2RlTnVtZXJpY0VudGl0eSgyLDEwKTt0aGlzLl9zZWN0aW9uU3RhcnQrK31lbHNlIGlmKGM8XCIwXCJ8fGM+XCI5XCIpe2lmKCF0aGlzLl94bWxNb2RlKXt0aGlzLl9kZWNvZGVOdW1lcmljRW50aXR5KDIsMTApfWVsc2V7dGhpcy5fc3RhdGU9dGhpcy5fYmFzZVN0YXRlfXRoaXMuX2luZGV4LS19fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUluSGV4RW50aXR5PWZ1bmN0aW9uKGMpe2lmKGM9PT1cIjtcIil7dGhpcy5fZGVjb2RlTnVtZXJpY0VudGl0eSgzLDE2KTt0aGlzLl9zZWN0aW9uU3RhcnQrK31lbHNlIGlmKChjPFwiYVwifHxjPlwiZlwiKSYmKGM8XCJBXCJ8fGM+XCJGXCIpJiYoYzxcIjBcInx8Yz5cIjlcIikpe2lmKCF0aGlzLl94bWxNb2RlKXt0aGlzLl9kZWNvZGVOdW1lcmljRW50aXR5KDMsMTYpfWVsc2V7dGhpcy5fc3RhdGU9dGhpcy5fYmFzZVN0YXRlfXRoaXMuX2luZGV4LS19fTtUb2tlbml6ZXIucHJvdG90eXBlLl9jbGVhbnVwPWZ1bmN0aW9uKCl7aWYodGhpcy5fc2VjdGlvblN0YXJ0PDApe3RoaXMuX2J1ZmZlcj1cIlwiO3RoaXMuX2luZGV4PTA7dGhpcy5fYnVmZmVyT2Zmc2V0Kz10aGlzLl9pbmRleH1lbHNlIGlmKHRoaXMuX3J1bm5pbmcpe2lmKHRoaXMuX3N0YXRlPT09VEVYVCl7aWYodGhpcy5fc2VjdGlvblN0YXJ0IT09dGhpcy5faW5kZXgpe3RoaXMuX2Nicy5vbnRleHQodGhpcy5fYnVmZmVyLnN1YnN0cih0aGlzLl9zZWN0aW9uU3RhcnQpKX10aGlzLl9idWZmZXI9XCJcIjt0aGlzLl9idWZmZXJPZmZzZXQrPXRoaXMuX2luZGV4O3RoaXMuX2luZGV4PTB9ZWxzZSBpZih0aGlzLl9zZWN0aW9uU3RhcnQ9PT10aGlzLl9pbmRleCl7dGhpcy5fYnVmZmVyPVwiXCI7dGhpcy5fYnVmZmVyT2Zmc2V0Kz10aGlzLl9pbmRleDt0aGlzLl9pbmRleD0wfWVsc2V7dGhpcy5fYnVmZmVyPXRoaXMuX2J1ZmZlci5zdWJzdHIodGhpcy5fc2VjdGlvblN0YXJ0KTt0aGlzLl9pbmRleC09dGhpcy5fc2VjdGlvblN0YXJ0O3RoaXMuX2J1ZmZlck9mZnNldCs9dGhpcy5fc2VjdGlvblN0YXJ0fXRoaXMuX3NlY3Rpb25TdGFydD0wfX07VG9rZW5pemVyLnByb3RvdHlwZS53cml0ZT1mdW5jdGlvbihjaHVuayl7aWYodGhpcy5fZW5kZWQpdGhpcy5fY2JzLm9uZXJyb3IoRXJyb3IoXCIud3JpdGUoKSBhZnRlciBkb25lIVwiKSk7dGhpcy5fYnVmZmVyKz1jaHVuazt0aGlzLl9wYXJzZSgpfTtUb2tlbml6ZXIucHJvdG90eXBlLl9wYXJzZT1mdW5jdGlvbigpe3doaWxlKHRoaXMuX2luZGV4PHRoaXMuX2J1ZmZlci5sZW5ndGgmJnRoaXMuX3J1bm5pbmcpe3ZhciBjPXRoaXMuX2J1ZmZlci5jaGFyQXQodGhpcy5faW5kZXgpO2lmKHRoaXMuX3N0YXRlPT09VEVYVCl7dGhpcy5fc3RhdGVUZXh0KGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfVEFHX05BTUUpe3RoaXMuX3N0YXRlQmVmb3JlVGFnTmFtZShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09SU5fVEFHX05BTUUpe3RoaXMuX3N0YXRlSW5UYWdOYW1lKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfQ0xPU0lOR19UQUdfTkFNRSl7dGhpcy5fc3RhdGVCZWZvcmVDbG9zZWluZ1RhZ05hbWUoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX0NMT1NJTkdfVEFHX05BTUUpe3RoaXMuX3N0YXRlSW5DbG9zZWluZ1RhZ05hbWUoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUFGVEVSX0NMT1NJTkdfVEFHX05BTUUpe3RoaXMuX3N0YXRlQWZ0ZXJDbG9zZWluZ1RhZ05hbWUoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX1NFTEZfQ0xPU0lOR19UQUcpe3RoaXMuX3N0YXRlSW5TZWxmQ2xvc2luZ1RhZyhjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX0FUVFJJQlVURV9OQU1FKXt0aGlzLl9zdGF0ZUJlZm9yZUF0dHJpYnV0ZU5hbWUoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX0FUVFJJQlVURV9OQU1FKXt0aGlzLl9zdGF0ZUluQXR0cmlidXRlTmFtZShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QUZURVJfQVRUUklCVVRFX05BTUUpe3RoaXMuX3N0YXRlQWZ0ZXJBdHRyaWJ1dGVOYW1lKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfQVRUUklCVVRFX1ZBTFVFKXt0aGlzLl9zdGF0ZUJlZm9yZUF0dHJpYnV0ZVZhbHVlKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9BVFRSSUJVVEVfVkFMVUVfRFEpe3RoaXMuX3N0YXRlSW5BdHRyaWJ1dGVWYWx1ZURvdWJsZVF1b3RlcyhjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09SU5fQVRUUklCVVRFX1ZBTFVFX1NRKXt0aGlzLl9zdGF0ZUluQXR0cmlidXRlVmFsdWVTaW5nbGVRdW90ZXMoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX0FUVFJJQlVURV9WQUxVRV9OUSl7dGhpcy5fc3RhdGVJbkF0dHJpYnV0ZVZhbHVlTm9RdW90ZXMoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9ERUNMQVJBVElPTil7dGhpcy5fc3RhdGVCZWZvcmVEZWNsYXJhdGlvbihjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09SU5fREVDTEFSQVRJT04pe3RoaXMuX3N0YXRlSW5EZWNsYXJhdGlvbihjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09SU5fUFJPQ0VTU0lOR19JTlNUUlVDVElPTil7dGhpcy5fc3RhdGVJblByb2Nlc3NpbmdJbnN0cnVjdGlvbihjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX0NPTU1FTlQpe3RoaXMuX3N0YXRlQmVmb3JlQ29tbWVudChjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09SU5fQ09NTUVOVCl7dGhpcy5fc3RhdGVJbkNvbW1lbnQoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUFGVEVSX0NPTU1FTlRfMSl7dGhpcy5fc3RhdGVBZnRlckNvbW1lbnQxKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9DT01NRU5UXzIpe3RoaXMuX3N0YXRlQWZ0ZXJDb21tZW50MihjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX0NEQVRBXzEpe3RoaXMuX3N0YXRlQmVmb3JlQ2RhdGExKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfQ0RBVEFfMil7dGhpcy5fc3RhdGVCZWZvcmVDZGF0YTIoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9DREFUQV8zKXt0aGlzLl9zdGF0ZUJlZm9yZUNkYXRhMyhjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX0NEQVRBXzQpe3RoaXMuX3N0YXRlQmVmb3JlQ2RhdGE0KGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfQ0RBVEFfNSl7dGhpcy5fc3RhdGVCZWZvcmVDZGF0YTUoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9DREFUQV82KXt0aGlzLl9zdGF0ZUJlZm9yZUNkYXRhNihjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09SU5fQ0RBVEEpe3RoaXMuX3N0YXRlSW5DZGF0YShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QUZURVJfQ0RBVEFfMSl7dGhpcy5fc3RhdGVBZnRlckNkYXRhMShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QUZURVJfQ0RBVEFfMil7dGhpcy5fc3RhdGVBZnRlckNkYXRhMihjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX1NQRUNJQUwpe3RoaXMuX3N0YXRlQmVmb3JlU3BlY2lhbChjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX1NQRUNJQUxfRU5EKXt0aGlzLl9zdGF0ZUJlZm9yZVNwZWNpYWxFbmQoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9TQ1JJUFRfMSl7dGhpcy5fc3RhdGVCZWZvcmVTY3JpcHQxKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfU0NSSVBUXzIpe3RoaXMuX3N0YXRlQmVmb3JlU2NyaXB0MihjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX1NDUklQVF8zKXt0aGlzLl9zdGF0ZUJlZm9yZVNjcmlwdDMoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9TQ1JJUFRfNCl7dGhpcy5fc3RhdGVCZWZvcmVTY3JpcHQ0KGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfU0NSSVBUXzUpe3RoaXMuX3N0YXRlQmVmb3JlU2NyaXB0NShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QUZURVJfU0NSSVBUXzEpe3RoaXMuX3N0YXRlQWZ0ZXJTY3JpcHQxKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9TQ1JJUFRfMil7dGhpcy5fc3RhdGVBZnRlclNjcmlwdDIoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUFGVEVSX1NDUklQVF8zKXt0aGlzLl9zdGF0ZUFmdGVyU2NyaXB0MyhjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QUZURVJfU0NSSVBUXzQpe3RoaXMuX3N0YXRlQWZ0ZXJTY3JpcHQ0KGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9TQ1JJUFRfNSl7dGhpcy5fc3RhdGVBZnRlclNjcmlwdDUoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9TVFlMRV8xKXt0aGlzLl9zdGF0ZUJlZm9yZVN0eWxlMShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX1NUWUxFXzIpe3RoaXMuX3N0YXRlQmVmb3JlU3R5bGUyKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfU1RZTEVfMyl7dGhpcy5fc3RhdGVCZWZvcmVTdHlsZTMoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9TVFlMRV80KXt0aGlzLl9zdGF0ZUJlZm9yZVN0eWxlNChjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QUZURVJfU1RZTEVfMSl7dGhpcy5fc3RhdGVBZnRlclN0eWxlMShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QUZURVJfU1RZTEVfMil7dGhpcy5fc3RhdGVBZnRlclN0eWxlMihjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QUZURVJfU1RZTEVfMyl7dGhpcy5fc3RhdGVBZnRlclN0eWxlMyhjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QUZURVJfU1RZTEVfNCl7dGhpcy5fc3RhdGVBZnRlclN0eWxlNChjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX0VOVElUWSl7dGhpcy5fc3RhdGVCZWZvcmVFbnRpdHkoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9OVU1FUklDX0VOVElUWSl7dGhpcy5fc3RhdGVCZWZvcmVOdW1lcmljRW50aXR5KGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9OQU1FRF9FTlRJVFkpe3RoaXMuX3N0YXRlSW5OYW1lZEVudGl0eShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09SU5fTlVNRVJJQ19FTlRJVFkpe3RoaXMuX3N0YXRlSW5OdW1lcmljRW50aXR5KGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9IRVhfRU5USVRZKXt0aGlzLl9zdGF0ZUluSGV4RW50aXR5KGMpfWVsc2V7dGhpcy5fY2JzLm9uZXJyb3IoRXJyb3IoXCJ1bmtub3duIF9zdGF0ZVwiKSx0aGlzLl9zdGF0ZSl9dGhpcy5faW5kZXgrK310aGlzLl9jbGVhbnVwKCl9O1Rva2VuaXplci5wcm90b3R5cGUucGF1c2U9ZnVuY3Rpb24oKXt0aGlzLl9ydW5uaW5nPWZhbHNlfTtUb2tlbml6ZXIucHJvdG90eXBlLnJlc3VtZT1mdW5jdGlvbigpe3RoaXMuX3J1bm5pbmc9dHJ1ZTtpZih0aGlzLl9pbmRleDx0aGlzLl9idWZmZXIubGVuZ3RoKXt0aGlzLl9wYXJzZSgpfWlmKHRoaXMuX2VuZGVkKXt0aGlzLl9maW5pc2goKX19O1Rva2VuaXplci5wcm90b3R5cGUuZW5kPWZ1bmN0aW9uKGNodW5rKXtpZih0aGlzLl9lbmRlZCl0aGlzLl9jYnMub25lcnJvcihFcnJvcihcIi5lbmQoKSBhZnRlciBkb25lIVwiKSk7aWYoY2h1bmspdGhpcy53cml0ZShjaHVuayk7dGhpcy5fZW5kZWQ9dHJ1ZTtpZih0aGlzLl9ydW5uaW5nKXRoaXMuX2ZpbmlzaCgpfTtUb2tlbml6ZXIucHJvdG90eXBlLl9maW5pc2g9ZnVuY3Rpb24oKXtpZih0aGlzLl9zZWN0aW9uU3RhcnQ8dGhpcy5faW5kZXgpe3RoaXMuX2hhbmRsZVRyYWlsaW5nRGF0YSgpfXRoaXMuX2Nicy5vbmVuZCgpfTtUb2tlbml6ZXIucHJvdG90eXBlLl9oYW5kbGVUcmFpbGluZ0RhdGE9ZnVuY3Rpb24oKXt2YXIgZGF0YT10aGlzLl9idWZmZXIuc3Vic3RyKHRoaXMuX3NlY3Rpb25TdGFydCk7aWYodGhpcy5fc3RhdGU9PT1JTl9DREFUQXx8dGhpcy5fc3RhdGU9PT1BRlRFUl9DREFUQV8xfHx0aGlzLl9zdGF0ZT09PUFGVEVSX0NEQVRBXzIpe3RoaXMuX2Nicy5vbmNkYXRhKGRhdGEpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9DT01NRU5UfHx0aGlzLl9zdGF0ZT09PUFGVEVSX0NPTU1FTlRfMXx8dGhpcy5fc3RhdGU9PT1BRlRFUl9DT01NRU5UXzIpe3RoaXMuX2Nicy5vbmNvbW1lbnQoZGF0YSl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX05BTUVEX0VOVElUWSYmIXRoaXMuX3htbE1vZGUpe3RoaXMuX3BhcnNlTGVnYWN5RW50aXR5KCk7aWYodGhpcy5fc2VjdGlvblN0YXJ0PHRoaXMuX2luZGV4KXt0aGlzLl9zdGF0ZT10aGlzLl9iYXNlU3RhdGU7dGhpcy5faGFuZGxlVHJhaWxpbmdEYXRhKCl9fWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9OVU1FUklDX0VOVElUWSYmIXRoaXMuX3htbE1vZGUpe3RoaXMuX2RlY29kZU51bWVyaWNFbnRpdHkoMiwxMCk7aWYodGhpcy5fc2VjdGlvblN0YXJ0PHRoaXMuX2luZGV4KXt0aGlzLl9zdGF0ZT10aGlzLl9iYXNlU3RhdGU7dGhpcy5faGFuZGxlVHJhaWxpbmdEYXRhKCl9fWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9IRVhfRU5USVRZJiYhdGhpcy5feG1sTW9kZSl7dGhpcy5fZGVjb2RlTnVtZXJpY0VudGl0eSgzLDE2KTtpZih0aGlzLl9zZWN0aW9uU3RhcnQ8dGhpcy5faW5kZXgpe3RoaXMuX3N0YXRlPXRoaXMuX2Jhc2VTdGF0ZTt0aGlzLl9oYW5kbGVUcmFpbGluZ0RhdGEoKX19ZWxzZSBpZih0aGlzLl9zdGF0ZSE9PUlOX1RBR19OQU1FJiZ0aGlzLl9zdGF0ZSE9PUJFRk9SRV9BVFRSSUJVVEVfTkFNRSYmdGhpcy5fc3RhdGUhPT1CRUZPUkVfQVRUUklCVVRFX1ZBTFVFJiZ0aGlzLl9zdGF0ZSE9PUFGVEVSX0FUVFJJQlVURV9OQU1FJiZ0aGlzLl9zdGF0ZSE9PUlOX0FUVFJJQlVURV9OQU1FJiZ0aGlzLl9zdGF0ZSE9PUlOX0FUVFJJQlVURV9WQUxVRV9TUSYmdGhpcy5fc3RhdGUhPT1JTl9BVFRSSUJVVEVfVkFMVUVfRFEmJnRoaXMuX3N0YXRlIT09SU5fQVRUUklCVVRFX1ZBTFVFX05RJiZ0aGlzLl9zdGF0ZSE9PUlOX0NMT1NJTkdfVEFHX05BTUUpe1xudGhpcy5fY2JzLm9udGV4dChkYXRhKX19O1Rva2VuaXplci5wcm90b3R5cGUucmVzZXQ9ZnVuY3Rpb24oKXtUb2tlbml6ZXIuY2FsbCh0aGlzLHt4bWxNb2RlOnRoaXMuX3htbE1vZGUsZGVjb2RlRW50aXRpZXM6dGhpcy5fZGVjb2RlRW50aXRpZXN9LHRoaXMuX2Nicyl9O1Rva2VuaXplci5wcm90b3R5cGUuZ2V0QWJzb2x1dGVJbmRleD1mdW5jdGlvbigpe3JldHVybiB0aGlzLl9idWZmZXJPZmZzZXQrdGhpcy5faW5kZXh9O1Rva2VuaXplci5wcm90b3R5cGUuX2dldFNlY3Rpb249ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5fYnVmZmVyLnN1YnN0cmluZyh0aGlzLl9zZWN0aW9uU3RhcnQsdGhpcy5faW5kZXgpfTtUb2tlbml6ZXIucHJvdG90eXBlLl9lbWl0VG9rZW49ZnVuY3Rpb24obmFtZSl7dGhpcy5fY2JzW25hbWVdKHRoaXMuX2dldFNlY3Rpb24oKSk7dGhpcy5fc2VjdGlvblN0YXJ0PS0xfTtUb2tlbml6ZXIucHJvdG90eXBlLl9lbWl0UGFydGlhbD1mdW5jdGlvbih2YWx1ZSl7aWYodGhpcy5fYmFzZVN0YXRlIT09VEVYVCl7dGhpcy5fY2JzLm9uYXR0cmliZGF0YSh2YWx1ZSl9ZWxzZXt0aGlzLl9jYnMub250ZXh0KHZhbHVlKX19fSx7XCJlbnRpdGllcy9saWIvZGVjb2RlX2NvZGVwb2ludC5qc1wiOjIyLFwiZW50aXRpZXMvbWFwcy9lbnRpdGllcy5qc29uXCI6MjUsXCJlbnRpdGllcy9tYXBzL2xlZ2FjeS5qc29uXCI6MjYsXCJlbnRpdGllcy9tYXBzL3htbC5qc29uXCI6Mjd9XSwzNTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9U3RyZWFtO3ZhciBQYXJzZXI9cmVxdWlyZShcIi4vUGFyc2VyLmpzXCIpLFdyaXRhYmxlU3RyZWFtPXJlcXVpcmUoXCJzdHJlYW1cIikuV3JpdGFibGV8fHJlcXVpcmUoXCJyZWFkYWJsZS1zdHJlYW1cIikuV3JpdGFibGUsU3RyaW5nRGVjb2Rlcj1yZXF1aXJlKFwic3RyaW5nX2RlY29kZXJcIikuU3RyaW5nRGVjb2RlcixCdWZmZXI9cmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXI7ZnVuY3Rpb24gU3RyZWFtKGNicyxvcHRpb25zKXt2YXIgcGFyc2VyPXRoaXMuX3BhcnNlcj1uZXcgUGFyc2VyKGNicyxvcHRpb25zKTt2YXIgZGVjb2Rlcj10aGlzLl9kZWNvZGVyPW5ldyBTdHJpbmdEZWNvZGVyO1dyaXRhYmxlU3RyZWFtLmNhbGwodGhpcyx7ZGVjb2RlU3RyaW5nczpmYWxzZX0pO3RoaXMub25jZShcImZpbmlzaFwiLGZ1bmN0aW9uKCl7cGFyc2VyLmVuZChkZWNvZGVyLmVuZCgpKX0pfXJlcXVpcmUoXCJpbmhlcml0c1wiKShTdHJlYW0sV3JpdGFibGVTdHJlYW0pO1dyaXRhYmxlU3RyZWFtLnByb3RvdHlwZS5fd3JpdGU9ZnVuY3Rpb24oY2h1bmssZW5jb2RpbmcsY2Ipe2lmKGNodW5rIGluc3RhbmNlb2YgQnVmZmVyKWNodW5rPXRoaXMuX2RlY29kZXIud3JpdGUoY2h1bmspO3RoaXMuX3BhcnNlci53cml0ZShjaHVuayk7Y2IoKX19LHtcIi4vUGFyc2VyLmpzXCI6MzEsYnVmZmVyOjUsaW5oZXJpdHM6MzgsXCJyZWFkYWJsZS1zdHJlYW1cIjozLHN0cmVhbTo1NSxzdHJpbmdfZGVjb2Rlcjo1Nn1dLDM2OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgUGFyc2VyPXJlcXVpcmUoXCIuL1BhcnNlci5qc1wiKSxEb21IYW5kbGVyPXJlcXVpcmUoXCJkb21oYW5kbGVyXCIpO2Z1bmN0aW9uIGRlZmluZVByb3AobmFtZSx2YWx1ZSl7ZGVsZXRlIG1vZHVsZS5leHBvcnRzW25hbWVdO21vZHVsZS5leHBvcnRzW25hbWVdPXZhbHVlO3JldHVybiB2YWx1ZX1tb2R1bGUuZXhwb3J0cz17UGFyc2VyOlBhcnNlcixUb2tlbml6ZXI6cmVxdWlyZShcIi4vVG9rZW5pemVyLmpzXCIpLEVsZW1lbnRUeXBlOnJlcXVpcmUoXCJkb21lbGVtZW50dHlwZVwiKSxEb21IYW5kbGVyOkRvbUhhbmRsZXIsZ2V0IEZlZWRIYW5kbGVyKCl7cmV0dXJuIGRlZmluZVByb3AoXCJGZWVkSGFuZGxlclwiLHJlcXVpcmUoXCIuL0ZlZWRIYW5kbGVyLmpzXCIpKX0sZ2V0IFN0cmVhbSgpe3JldHVybiBkZWZpbmVQcm9wKFwiU3RyZWFtXCIscmVxdWlyZShcIi4vU3RyZWFtLmpzXCIpKX0sZ2V0IFdyaXRhYmxlU3RyZWFtKCl7cmV0dXJuIGRlZmluZVByb3AoXCJXcml0YWJsZVN0cmVhbVwiLHJlcXVpcmUoXCIuL1dyaXRhYmxlU3RyZWFtLmpzXCIpKX0sZ2V0IFByb3h5SGFuZGxlcigpe3JldHVybiBkZWZpbmVQcm9wKFwiUHJveHlIYW5kbGVyXCIscmVxdWlyZShcIi4vUHJveHlIYW5kbGVyLmpzXCIpKX0sZ2V0IERvbVV0aWxzKCl7cmV0dXJuIGRlZmluZVByb3AoXCJEb21VdGlsc1wiLHJlcXVpcmUoXCJkb211dGlsc1wiKSl9LGdldCBDb2xsZWN0aW5nSGFuZGxlcigpe3JldHVybiBkZWZpbmVQcm9wKFwiQ29sbGVjdGluZ0hhbmRsZXJcIixyZXF1aXJlKFwiLi9Db2xsZWN0aW5nSGFuZGxlci5qc1wiKSl9LERlZmF1bHRIYW5kbGVyOkRvbUhhbmRsZXIsZ2V0IFJzc0hhbmRsZXIoKXtyZXR1cm4gZGVmaW5lUHJvcChcIlJzc0hhbmRsZXJcIix0aGlzLkZlZWRIYW5kbGVyKX0scGFyc2VET006ZnVuY3Rpb24oZGF0YSxvcHRpb25zKXt2YXIgaGFuZGxlcj1uZXcgRG9tSGFuZGxlcihvcHRpb25zKTtuZXcgUGFyc2VyKGhhbmRsZXIsb3B0aW9ucykuZW5kKGRhdGEpO3JldHVybiBoYW5kbGVyLmRvbX0scGFyc2VGZWVkOmZ1bmN0aW9uKGZlZWQsb3B0aW9ucyl7dmFyIGhhbmRsZXI9bmV3IG1vZHVsZS5leHBvcnRzLkZlZWRIYW5kbGVyKG9wdGlvbnMpO25ldyBQYXJzZXIoaGFuZGxlcixvcHRpb25zKS5lbmQoZmVlZCk7cmV0dXJuIGhhbmRsZXIuZG9tfSxjcmVhdGVEb21TdHJlYW06ZnVuY3Rpb24oY2Isb3B0aW9ucyxlbGVtZW50Q2Ipe3ZhciBoYW5kbGVyPW5ldyBEb21IYW5kbGVyKGNiLG9wdGlvbnMsZWxlbWVudENiKTtyZXR1cm4gbmV3IFBhcnNlcihoYW5kbGVyLG9wdGlvbnMpfSxFVkVOVFM6e2F0dHJpYnV0ZToyLGNkYXRhc3RhcnQ6MCxjZGF0YWVuZDowLHRleHQ6MSxwcm9jZXNzaW5naW5zdHJ1Y3Rpb246Mixjb21tZW50OjEsY29tbWVudGVuZDowLGNsb3NldGFnOjEsb3BlbnRhZzoyLG9wZW50YWduYW1lOjEsZXJyb3I6MSxlbmQ6MH19fSx7XCIuL0NvbGxlY3RpbmdIYW5kbGVyLmpzXCI6MjksXCIuL0ZlZWRIYW5kbGVyLmpzXCI6MzAsXCIuL1BhcnNlci5qc1wiOjMxLFwiLi9Qcm94eUhhbmRsZXIuanNcIjozMixcIi4vU3RyZWFtLmpzXCI6MzMsXCIuL1Rva2VuaXplci5qc1wiOjM0LFwiLi9Xcml0YWJsZVN0cmVhbS5qc1wiOjM1LGRvbWVsZW1lbnR0eXBlOjksZG9taGFuZGxlcjoxMCxkb211dGlsczoxM31dLDM3OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtleHBvcnRzLnJlYWQ9ZnVuY3Rpb24oYnVmZmVyLG9mZnNldCxpc0xFLG1MZW4sbkJ5dGVzKXt2YXIgZSxtO3ZhciBlTGVuPW5CeXRlcyo4LW1MZW4tMTt2YXIgZU1heD0oMTw8ZUxlbiktMTt2YXIgZUJpYXM9ZU1heD4+MTt2YXIgbkJpdHM9LTc7dmFyIGk9aXNMRT9uQnl0ZXMtMTowO3ZhciBkPWlzTEU/LTE6MTt2YXIgcz1idWZmZXJbb2Zmc2V0K2ldO2krPWQ7ZT1zJigxPDwtbkJpdHMpLTE7cz4+PS1uQml0cztuQml0cys9ZUxlbjtmb3IoO25CaXRzPjA7ZT1lKjI1NitidWZmZXJbb2Zmc2V0K2ldLGkrPWQsbkJpdHMtPTgpe31tPWUmKDE8PC1uQml0cyktMTtlPj49LW5CaXRzO25CaXRzKz1tTGVuO2Zvcig7bkJpdHM+MDttPW0qMjU2K2J1ZmZlcltvZmZzZXQraV0saSs9ZCxuQml0cy09OCl7fWlmKGU9PT0wKXtlPTEtZUJpYXN9ZWxzZSBpZihlPT09ZU1heCl7cmV0dXJuIG0/TmFOOihzPy0xOjEpKkluZmluaXR5fWVsc2V7bT1tK01hdGgucG93KDIsbUxlbik7ZT1lLWVCaWFzfXJldHVybihzPy0xOjEpKm0qTWF0aC5wb3coMixlLW1MZW4pfTtleHBvcnRzLndyaXRlPWZ1bmN0aW9uKGJ1ZmZlcix2YWx1ZSxvZmZzZXQsaXNMRSxtTGVuLG5CeXRlcyl7dmFyIGUsbSxjO3ZhciBlTGVuPW5CeXRlcyo4LW1MZW4tMTt2YXIgZU1heD0oMTw8ZUxlbiktMTt2YXIgZUJpYXM9ZU1heD4+MTt2YXIgcnQ9bUxlbj09PTIzP01hdGgucG93KDIsLTI0KS1NYXRoLnBvdygyLC03Nyk6MDt2YXIgaT1pc0xFPzA6bkJ5dGVzLTE7dmFyIGQ9aXNMRT8xOi0xO3ZhciBzPXZhbHVlPDB8fHZhbHVlPT09MCYmMS92YWx1ZTwwPzE6MDt2YWx1ZT1NYXRoLmFicyh2YWx1ZSk7aWYoaXNOYU4odmFsdWUpfHx2YWx1ZT09PUluZmluaXR5KXttPWlzTmFOKHZhbHVlKT8xOjA7ZT1lTWF4fWVsc2V7ZT1NYXRoLmZsb29yKE1hdGgubG9nKHZhbHVlKS9NYXRoLkxOMik7aWYodmFsdWUqKGM9TWF0aC5wb3coMiwtZSkpPDEpe2UtLTtjKj0yfWlmKGUrZUJpYXM+PTEpe3ZhbHVlKz1ydC9jfWVsc2V7dmFsdWUrPXJ0Kk1hdGgucG93KDIsMS1lQmlhcyl9aWYodmFsdWUqYz49Mil7ZSsrO2MvPTJ9aWYoZStlQmlhcz49ZU1heCl7bT0wO2U9ZU1heH1lbHNlIGlmKGUrZUJpYXM+PTEpe209KHZhbHVlKmMtMSkqTWF0aC5wb3coMixtTGVuKTtlPWUrZUJpYXN9ZWxzZXttPXZhbHVlKk1hdGgucG93KDIsZUJpYXMtMSkqTWF0aC5wb3coMixtTGVuKTtlPTB9fWZvcig7bUxlbj49ODtidWZmZXJbb2Zmc2V0K2ldPW0mMjU1LGkrPWQsbS89MjU2LG1MZW4tPTgpe31lPWU8PG1MZW58bTtlTGVuKz1tTGVuO2Zvcig7ZUxlbj4wO2J1ZmZlcltvZmZzZXQraV09ZSYyNTUsaSs9ZCxlLz0yNTYsZUxlbi09OCl7fWJ1ZmZlcltvZmZzZXQraS1kXXw9cyoxMjh9fSx7fV0sMzg6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe2lmKHR5cGVvZiBPYmplY3QuY3JlYXRlPT09XCJmdW5jdGlvblwiKXttb2R1bGUuZXhwb3J0cz1mdW5jdGlvbiBpbmhlcml0cyhjdG9yLHN1cGVyQ3Rvcil7Y3Rvci5zdXBlcl89c3VwZXJDdG9yO2N0b3IucHJvdG90eXBlPU9iamVjdC5jcmVhdGUoc3VwZXJDdG9yLnByb3RvdHlwZSx7Y29uc3RydWN0b3I6e3ZhbHVlOmN0b3IsZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVlfX0pfX1lbHNle21vZHVsZS5leHBvcnRzPWZ1bmN0aW9uIGluaGVyaXRzKGN0b3Isc3VwZXJDdG9yKXtjdG9yLnN1cGVyXz1zdXBlckN0b3I7dmFyIFRlbXBDdG9yPWZ1bmN0aW9uKCl7fTtUZW1wQ3Rvci5wcm90b3R5cGU9c3VwZXJDdG9yLnByb3RvdHlwZTtjdG9yLnByb3RvdHlwZT1uZXcgVGVtcEN0b3I7Y3Rvci5wcm90b3R5cGUuY29uc3RydWN0b3I9Y3Rvcn19fSx7fV0sMzk6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe21vZHVsZS5leHBvcnRzPWZ1bmN0aW9uKG9iail7cmV0dXJuIG9iaiE9bnVsbCYmKGlzQnVmZmVyKG9iail8fGlzU2xvd0J1ZmZlcihvYmopfHwhIW9iai5faXNCdWZmZXIpfTtmdW5jdGlvbiBpc0J1ZmZlcihvYmope3JldHVybiEhb2JqLmNvbnN0cnVjdG9yJiZ0eXBlb2Ygb2JqLmNvbnN0cnVjdG9yLmlzQnVmZmVyPT09XCJmdW5jdGlvblwiJiZvYmouY29uc3RydWN0b3IuaXNCdWZmZXIob2JqKX1mdW5jdGlvbiBpc1Nsb3dCdWZmZXIob2JqKXtyZXR1cm4gdHlwZW9mIG9iai5yZWFkRmxvYXRMRT09PVwiZnVuY3Rpb25cIiYmdHlwZW9mIG9iai5zbGljZT09PVwiZnVuY3Rpb25cIiYmaXNCdWZmZXIob2JqLnNsaWNlKDAsMCkpfX0se31dLDQwOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgdG9TdHJpbmc9e30udG9TdHJpbmc7bW9kdWxlLmV4cG9ydHM9QXJyYXkuaXNBcnJheXx8ZnVuY3Rpb24oYXJyKXtyZXR1cm4gdG9TdHJpbmcuY2FsbChhcnIpPT1cIltvYmplY3QgQXJyYXldXCJ9fSx7fV0sNDE6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpeyhmdW5jdGlvbihwcm9jZXNzKXtcInVzZSBzdHJpY3RcIjtpZighcHJvY2Vzcy52ZXJzaW9ufHxwcm9jZXNzLnZlcnNpb24uaW5kZXhPZihcInYwLlwiKT09PTB8fHByb2Nlc3MudmVyc2lvbi5pbmRleE9mKFwidjEuXCIpPT09MCYmcHJvY2Vzcy52ZXJzaW9uLmluZGV4T2YoXCJ2MS44LlwiKSE9PTApe21vZHVsZS5leHBvcnRzPW5leHRUaWNrfWVsc2V7bW9kdWxlLmV4cG9ydHM9cHJvY2Vzcy5uZXh0VGlja31mdW5jdGlvbiBuZXh0VGljayhmbixhcmcxLGFyZzIsYXJnMyl7aWYodHlwZW9mIGZuIT09XCJmdW5jdGlvblwiKXt0aHJvdyBuZXcgVHlwZUVycm9yKCdcImNhbGxiYWNrXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyl9dmFyIGxlbj1hcmd1bWVudHMubGVuZ3RoO3ZhciBhcmdzLGk7c3dpdGNoKGxlbil7Y2FzZSAwOmNhc2UgMTpyZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmbik7Y2FzZSAyOnJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uIGFmdGVyVGlja09uZSgpe2ZuLmNhbGwobnVsbCxhcmcxKX0pO2Nhc2UgMzpyZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiBhZnRlclRpY2tUd28oKXtmbi5jYWxsKG51bGwsYXJnMSxhcmcyKX0pO2Nhc2UgNDpyZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiBhZnRlclRpY2tUaHJlZSgpe2ZuLmNhbGwobnVsbCxhcmcxLGFyZzIsYXJnMyl9KTtkZWZhdWx0OmFyZ3M9bmV3IEFycmF5KGxlbi0xKTtpPTA7d2hpbGUoaTxhcmdzLmxlbmd0aCl7YXJnc1tpKytdPWFyZ3VtZW50c1tpXX1yZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiBhZnRlclRpY2soKXtmbi5hcHBseShudWxsLGFyZ3MpfSl9fX0pLmNhbGwodGhpcyxyZXF1aXJlKFwiX3Byb2Nlc3NcIikpfSx7X3Byb2Nlc3M6NDJ9XSw0MjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIHByb2Nlc3M9bW9kdWxlLmV4cG9ydHM9e307dmFyIGNhY2hlZFNldFRpbWVvdXQ7dmFyIGNhY2hlZENsZWFyVGltZW91dDtmdW5jdGlvbiBkZWZhdWx0U2V0VGltb3V0KCl7dGhyb3cgbmV3IEVycm9yKFwic2V0VGltZW91dCBoYXMgbm90IGJlZW4gZGVmaW5lZFwiKX1mdW5jdGlvbiBkZWZhdWx0Q2xlYXJUaW1lb3V0KCl7dGhyb3cgbmV3IEVycm9yKFwiY2xlYXJUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkXCIpfShmdW5jdGlvbigpe3RyeXtpZih0eXBlb2Ygc2V0VGltZW91dD09PVwiZnVuY3Rpb25cIil7Y2FjaGVkU2V0VGltZW91dD1zZXRUaW1lb3V0fWVsc2V7Y2FjaGVkU2V0VGltZW91dD1kZWZhdWx0U2V0VGltb3V0fX1jYXRjaChlKXtjYWNoZWRTZXRUaW1lb3V0PWRlZmF1bHRTZXRUaW1vdXR9dHJ5e2lmKHR5cGVvZiBjbGVhclRpbWVvdXQ9PT1cImZ1bmN0aW9uXCIpe2NhY2hlZENsZWFyVGltZW91dD1jbGVhclRpbWVvdXR9ZWxzZXtjYWNoZWRDbGVhclRpbWVvdXQ9ZGVmYXVsdENsZWFyVGltZW91dH19Y2F0Y2goZSl7Y2FjaGVkQ2xlYXJUaW1lb3V0PWRlZmF1bHRDbGVhclRpbWVvdXR9fSkoKTtmdW5jdGlvbiBydW5UaW1lb3V0KGZ1bil7aWYoY2FjaGVkU2V0VGltZW91dD09PXNldFRpbWVvdXQpe3JldHVybiBzZXRUaW1lb3V0KGZ1biwwKX1pZigoY2FjaGVkU2V0VGltZW91dD09PWRlZmF1bHRTZXRUaW1vdXR8fCFjYWNoZWRTZXRUaW1lb3V0KSYmc2V0VGltZW91dCl7Y2FjaGVkU2V0VGltZW91dD1zZXRUaW1lb3V0O3JldHVybiBzZXRUaW1lb3V0KGZ1biwwKX10cnl7cmV0dXJuIGNhY2hlZFNldFRpbWVvdXQoZnVuLDApfWNhdGNoKGUpe3RyeXtyZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKG51bGwsZnVuLDApfWNhdGNoKGUpe3JldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwodGhpcyxmdW4sMCl9fX1mdW5jdGlvbiBydW5DbGVhclRpbWVvdXQobWFya2VyKXtpZihjYWNoZWRDbGVhclRpbWVvdXQ9PT1jbGVhclRpbWVvdXQpe3JldHVybiBjbGVhclRpbWVvdXQobWFya2VyKX1pZigoY2FjaGVkQ2xlYXJUaW1lb3V0PT09ZGVmYXVsdENsZWFyVGltZW91dHx8IWNhY2hlZENsZWFyVGltZW91dCkmJmNsZWFyVGltZW91dCl7Y2FjaGVkQ2xlYXJUaW1lb3V0PWNsZWFyVGltZW91dDtyZXR1cm4gY2xlYXJUaW1lb3V0KG1hcmtlcil9dHJ5e3JldHVybiBjYWNoZWRDbGVhclRpbWVvdXQobWFya2VyKX1jYXRjaChlKXt0cnl7cmV0dXJuIGNhY2hlZENsZWFyVGltZW91dC5jYWxsKG51bGwsbWFya2VyKX1jYXRjaChlKXtyZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0LmNhbGwodGhpcyxtYXJrZXIpfX19dmFyIHF1ZXVlPVtdO3ZhciBkcmFpbmluZz1mYWxzZTt2YXIgY3VycmVudFF1ZXVlO3ZhciBxdWV1ZUluZGV4PS0xO2Z1bmN0aW9uIGNsZWFuVXBOZXh0VGljaygpe2lmKCFkcmFpbmluZ3x8IWN1cnJlbnRRdWV1ZSl7cmV0dXJufWRyYWluaW5nPWZhbHNlO2lmKGN1cnJlbnRRdWV1ZS5sZW5ndGgpe3F1ZXVlPWN1cnJlbnRRdWV1ZS5jb25jYXQocXVldWUpfWVsc2V7cXVldWVJbmRleD0tMX1pZihxdWV1ZS5sZW5ndGgpe2RyYWluUXVldWUoKX19ZnVuY3Rpb24gZHJhaW5RdWV1ZSgpe2lmKGRyYWluaW5nKXtyZXR1cm59dmFyIHRpbWVvdXQ9cnVuVGltZW91dChjbGVhblVwTmV4dFRpY2spO2RyYWluaW5nPXRydWU7dmFyIGxlbj1xdWV1ZS5sZW5ndGg7d2hpbGUobGVuKXtjdXJyZW50UXVldWU9cXVldWU7cXVldWU9W107d2hpbGUoKytxdWV1ZUluZGV4PGxlbil7aWYoY3VycmVudFF1ZXVlKXtjdXJyZW50UXVldWVbcXVldWVJbmRleF0ucnVuKCl9fXF1ZXVlSW5kZXg9LTE7bGVuPXF1ZXVlLmxlbmd0aH1jdXJyZW50UXVldWU9bnVsbDtkcmFpbmluZz1mYWxzZTtydW5DbGVhclRpbWVvdXQodGltZW91dCl9cHJvY2Vzcy5uZXh0VGljaz1mdW5jdGlvbihmdW4pe3ZhciBhcmdzPW5ldyBBcnJheShhcmd1bWVudHMubGVuZ3RoLTEpO2lmKGFyZ3VtZW50cy5sZW5ndGg+MSl7Zm9yKHZhciBpPTE7aTxhcmd1bWVudHMubGVuZ3RoO2krKyl7YXJnc1tpLTFdPWFyZ3VtZW50c1tpXX19cXVldWUucHVzaChuZXcgSXRlbShmdW4sYXJncykpO2lmKHF1ZXVlLmxlbmd0aD09PTEmJiFkcmFpbmluZyl7cnVuVGltZW91dChkcmFpblF1ZXVlKX19O2Z1bmN0aW9uIEl0ZW0oZnVuLGFycmF5KXt0aGlzLmZ1bj1mdW47dGhpcy5hcnJheT1hcnJheX1JdGVtLnByb3RvdHlwZS5ydW49ZnVuY3Rpb24oKXt0aGlzLmZ1bi5hcHBseShudWxsLHRoaXMuYXJyYXkpfTtwcm9jZXNzLnRpdGxlPVwiYnJvd3NlclwiO3Byb2Nlc3MuYnJvd3Nlcj10cnVlO3Byb2Nlc3MuZW52PXt9O3Byb2Nlc3MuYXJndj1bXTtwcm9jZXNzLnZlcnNpb249XCJcIjtwcm9jZXNzLnZlcnNpb25zPXt9O2Z1bmN0aW9uIG5vb3AoKXt9cHJvY2Vzcy5vbj1ub29wO3Byb2Nlc3MuYWRkTGlzdGVuZXI9bm9vcDtwcm9jZXNzLm9uY2U9bm9vcDtwcm9jZXNzLm9mZj1ub29wO3Byb2Nlc3MucmVtb3ZlTGlzdGVuZXI9bm9vcDtwcm9jZXNzLnJlbW92ZUFsbExpc3RlbmVycz1ub29wO3Byb2Nlc3MuZW1pdD1ub29wO3Byb2Nlc3MuYmluZGluZz1mdW5jdGlvbihuYW1lKXt0aHJvdyBuZXcgRXJyb3IoXCJwcm9jZXNzLmJpbmRpbmcgaXMgbm90IHN1cHBvcnRlZFwiKX07cHJvY2Vzcy5jd2Q9ZnVuY3Rpb24oKXtyZXR1cm5cIi9cIn07cHJvY2Vzcy5jaGRpcj1mdW5jdGlvbihkaXIpe3Rocm93IG5ldyBFcnJvcihcInByb2Nlc3MuY2hkaXIgaXMgbm90IHN1cHBvcnRlZFwiKX07cHJvY2Vzcy51bWFzaz1mdW5jdGlvbigpe3JldHVybiAwfX0se31dLDQzOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXttb2R1bGUuZXhwb3J0cz1yZXF1aXJlKFwiLi9saWIvX3N0cmVhbV9kdXBsZXguanNcIil9LHtcIi4vbGliL19zdHJlYW1fZHVwbGV4LmpzXCI6NDR9XSw0NDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XCJ1c2Ugc3RyaWN0XCI7dmFyIG9iamVjdEtleXM9T2JqZWN0LmtleXN8fGZ1bmN0aW9uKG9iail7dmFyIGtleXM9W107Zm9yKHZhciBrZXkgaW4gb2JqKXtrZXlzLnB1c2goa2V5KX1yZXR1cm4ga2V5c307bW9kdWxlLmV4cG9ydHM9RHVwbGV4O3ZhciBwcm9jZXNzTmV4dFRpY2s9cmVxdWlyZShcInByb2Nlc3MtbmV4dGljay1hcmdzXCIpO3ZhciB1dGlsPXJlcXVpcmUoXCJjb3JlLXV0aWwtaXNcIik7dXRpbC5pbmhlcml0cz1yZXF1aXJlKFwiaW5oZXJpdHNcIik7dmFyIFJlYWRhYmxlPXJlcXVpcmUoXCIuL19zdHJlYW1fcmVhZGFibGVcIik7dmFyIFdyaXRhYmxlPXJlcXVpcmUoXCIuL19zdHJlYW1fd3JpdGFibGVcIik7dXRpbC5pbmhlcml0cyhEdXBsZXgsUmVhZGFibGUpO3ZhciBrZXlzPW9iamVjdEtleXMoV3JpdGFibGUucHJvdG90eXBlKTtmb3IodmFyIHY9MDt2PGtleXMubGVuZ3RoO3YrKyl7dmFyIG1ldGhvZD1rZXlzW3ZdO2lmKCFEdXBsZXgucHJvdG90eXBlW21ldGhvZF0pRHVwbGV4LnByb3RvdHlwZVttZXRob2RdPVdyaXRhYmxlLnByb3RvdHlwZVttZXRob2RdfWZ1bmN0aW9uIER1cGxleChvcHRpb25zKXtpZighKHRoaXMgaW5zdGFuY2VvZiBEdXBsZXgpKXJldHVybiBuZXcgRHVwbGV4KG9wdGlvbnMpO1JlYWRhYmxlLmNhbGwodGhpcyxvcHRpb25zKTtXcml0YWJsZS5jYWxsKHRoaXMsb3B0aW9ucyk7aWYob3B0aW9ucyYmb3B0aW9ucy5yZWFkYWJsZT09PWZhbHNlKXRoaXMucmVhZGFibGU9ZmFsc2U7aWYob3B0aW9ucyYmb3B0aW9ucy53cml0YWJsZT09PWZhbHNlKXRoaXMud3JpdGFibGU9ZmFsc2U7dGhpcy5hbGxvd0hhbGZPcGVuPXRydWU7aWYob3B0aW9ucyYmb3B0aW9ucy5hbGxvd0hhbGZPcGVuPT09ZmFsc2UpdGhpcy5hbGxvd0hhbGZPcGVuPWZhbHNlO3RoaXMub25jZShcImVuZFwiLG9uZW5kKX1mdW5jdGlvbiBvbmVuZCgpe2lmKHRoaXMuYWxsb3dIYWxmT3Blbnx8dGhpcy5fd3JpdGFibGVTdGF0ZS5lbmRlZClyZXR1cm47cHJvY2Vzc05leHRUaWNrKG9uRW5kTlQsdGhpcyl9ZnVuY3Rpb24gb25FbmROVChzZWxmKXtzZWxmLmVuZCgpfWZ1bmN0aW9uIGZvckVhY2goeHMsZil7Zm9yKHZhciBpPTAsbD14cy5sZW5ndGg7aTxsO2krKyl7Zih4c1tpXSxpKX19fSx7XCIuL19zdHJlYW1fcmVhZGFibGVcIjo0NixcIi4vX3N0cmVhbV93cml0YWJsZVwiOjQ4LFwiY29yZS11dGlsLWlzXCI6Nixpbmhlcml0czozOCxcInByb2Nlc3MtbmV4dGljay1hcmdzXCI6NDF9XSw0NTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XCJ1c2Ugc3RyaWN0XCI7bW9kdWxlLmV4cG9ydHM9UGFzc1Rocm91Z2g7dmFyIFRyYW5zZm9ybT1yZXF1aXJlKFwiLi9fc3RyZWFtX3RyYW5zZm9ybVwiKTt2YXIgdXRpbD1yZXF1aXJlKFwiY29yZS11dGlsLWlzXCIpO3V0aWwuaW5oZXJpdHM9cmVxdWlyZShcImluaGVyaXRzXCIpO3V0aWwuaW5oZXJpdHMoUGFzc1Rocm91Z2gsVHJhbnNmb3JtKTtmdW5jdGlvbiBQYXNzVGhyb3VnaChvcHRpb25zKXtpZighKHRoaXMgaW5zdGFuY2VvZiBQYXNzVGhyb3VnaCkpcmV0dXJuIG5ldyBQYXNzVGhyb3VnaChvcHRpb25zKTtUcmFuc2Zvcm0uY2FsbCh0aGlzLG9wdGlvbnMpfVBhc3NUaHJvdWdoLnByb3RvdHlwZS5fdHJhbnNmb3JtPWZ1bmN0aW9uKGNodW5rLGVuY29kaW5nLGNiKXtjYihudWxsLGNodW5rKX19LHtcIi4vX3N0cmVhbV90cmFuc2Zvcm1cIjo0NyxcImNvcmUtdXRpbC1pc1wiOjYsaW5oZXJpdHM6Mzh9XSw0NjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7KGZ1bmN0aW9uKHByb2Nlc3Mpe1widXNlIHN0cmljdFwiO21vZHVsZS5leHBvcnRzPVJlYWRhYmxlO3ZhciBwcm9jZXNzTmV4dFRpY2s9cmVxdWlyZShcInByb2Nlc3MtbmV4dGljay1hcmdzXCIpO3ZhciBpc0FycmF5PXJlcXVpcmUoXCJpc2FycmF5XCIpO1JlYWRhYmxlLlJlYWRhYmxlU3RhdGU9UmVhZGFibGVTdGF0ZTt2YXIgRUU9cmVxdWlyZShcImV2ZW50c1wiKS5FdmVudEVtaXR0ZXI7dmFyIEVFbGlzdGVuZXJDb3VudD1mdW5jdGlvbihlbWl0dGVyLHR5cGUpe3JldHVybiBlbWl0dGVyLmxpc3RlbmVycyh0eXBlKS5sZW5ndGh9O3ZhciBTdHJlYW07KGZ1bmN0aW9uKCl7dHJ5e1N0cmVhbT1yZXF1aXJlKFwic3RcIitcInJlYW1cIil9Y2F0Y2goXyl7fWZpbmFsbHl7aWYoIVN0cmVhbSlTdHJlYW09cmVxdWlyZShcImV2ZW50c1wiKS5FdmVudEVtaXR0ZXJ9fSkoKTt2YXIgQnVmZmVyPXJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyO3ZhciBidWZmZXJTaGltPXJlcXVpcmUoXCJidWZmZXItc2hpbXNcIik7dmFyIHV0aWw9cmVxdWlyZShcImNvcmUtdXRpbC1pc1wiKTt1dGlsLmluaGVyaXRzPXJlcXVpcmUoXCJpbmhlcml0c1wiKTt2YXIgZGVidWdVdGlsPXJlcXVpcmUoXCJ1dGlsXCIpO3ZhciBkZWJ1Zz12b2lkIDA7aWYoZGVidWdVdGlsJiZkZWJ1Z1V0aWwuZGVidWdsb2cpe2RlYnVnPWRlYnVnVXRpbC5kZWJ1Z2xvZyhcInN0cmVhbVwiKX1lbHNle2RlYnVnPWZ1bmN0aW9uKCl7fX12YXIgQnVmZmVyTGlzdD1yZXF1aXJlKFwiLi9pbnRlcm5hbC9zdHJlYW1zL0J1ZmZlckxpc3RcIik7dmFyIFN0cmluZ0RlY29kZXI7dXRpbC5pbmhlcml0cyhSZWFkYWJsZSxTdHJlYW0pO2Z1bmN0aW9uIHByZXBlbmRMaXN0ZW5lcihlbWl0dGVyLGV2ZW50LGZuKXtpZih0eXBlb2YgZW1pdHRlci5wcmVwZW5kTGlzdGVuZXI9PT1cImZ1bmN0aW9uXCIpe3JldHVybiBlbWl0dGVyLnByZXBlbmRMaXN0ZW5lcihldmVudCxmbil9ZWxzZXtpZighZW1pdHRlci5fZXZlbnRzfHwhZW1pdHRlci5fZXZlbnRzW2V2ZW50XSllbWl0dGVyLm9uKGV2ZW50LGZuKTtlbHNlIGlmKGlzQXJyYXkoZW1pdHRlci5fZXZlbnRzW2V2ZW50XSkpZW1pdHRlci5fZXZlbnRzW2V2ZW50XS51bnNoaWZ0KGZuKTtlbHNlIGVtaXR0ZXIuX2V2ZW50c1tldmVudF09W2ZuLGVtaXR0ZXIuX2V2ZW50c1tldmVudF1dfX12YXIgRHVwbGV4O2Z1bmN0aW9uIFJlYWRhYmxlU3RhdGUob3B0aW9ucyxzdHJlYW0pe0R1cGxleD1EdXBsZXh8fHJlcXVpcmUoXCIuL19zdHJlYW1fZHVwbGV4XCIpO29wdGlvbnM9b3B0aW9uc3x8e307dGhpcy5vYmplY3RNb2RlPSEhb3B0aW9ucy5vYmplY3RNb2RlO2lmKHN0cmVhbSBpbnN0YW5jZW9mIER1cGxleCl0aGlzLm9iamVjdE1vZGU9dGhpcy5vYmplY3RNb2RlfHwhIW9wdGlvbnMucmVhZGFibGVPYmplY3RNb2RlO3ZhciBod209b3B0aW9ucy5oaWdoV2F0ZXJNYXJrO3ZhciBkZWZhdWx0SHdtPXRoaXMub2JqZWN0TW9kZT8xNjoxNioxMDI0O3RoaXMuaGlnaFdhdGVyTWFyaz1od218fGh3bT09PTA/aHdtOmRlZmF1bHRId207dGhpcy5oaWdoV2F0ZXJNYXJrPX5+dGhpcy5oaWdoV2F0ZXJNYXJrO3RoaXMuYnVmZmVyPW5ldyBCdWZmZXJMaXN0O3RoaXMubGVuZ3RoPTA7dGhpcy5waXBlcz1udWxsO3RoaXMucGlwZXNDb3VudD0wO3RoaXMuZmxvd2luZz1udWxsO3RoaXMuZW5kZWQ9ZmFsc2U7dGhpcy5lbmRFbWl0dGVkPWZhbHNlO3RoaXMucmVhZGluZz1mYWxzZTt0aGlzLnN5bmM9dHJ1ZTt0aGlzLm5lZWRSZWFkYWJsZT1mYWxzZTt0aGlzLmVtaXR0ZWRSZWFkYWJsZT1mYWxzZTt0aGlzLnJlYWRhYmxlTGlzdGVuaW5nPWZhbHNlO3RoaXMucmVzdW1lU2NoZWR1bGVkPWZhbHNlO3RoaXMuZGVmYXVsdEVuY29kaW5nPW9wdGlvbnMuZGVmYXVsdEVuY29kaW5nfHxcInV0ZjhcIjt0aGlzLnJhbk91dD1mYWxzZTt0aGlzLmF3YWl0RHJhaW49MDt0aGlzLnJlYWRpbmdNb3JlPWZhbHNlO3RoaXMuZGVjb2Rlcj1udWxsO3RoaXMuZW5jb2Rpbmc9bnVsbDtpZihvcHRpb25zLmVuY29kaW5nKXtpZighU3RyaW5nRGVjb2RlcilTdHJpbmdEZWNvZGVyPXJlcXVpcmUoXCJzdHJpbmdfZGVjb2Rlci9cIikuU3RyaW5nRGVjb2Rlcjt0aGlzLmRlY29kZXI9bmV3IFN0cmluZ0RlY29kZXIob3B0aW9ucy5lbmNvZGluZyk7dGhpcy5lbmNvZGluZz1vcHRpb25zLmVuY29kaW5nfX12YXIgRHVwbGV4O2Z1bmN0aW9uIFJlYWRhYmxlKG9wdGlvbnMpe0R1cGxleD1EdXBsZXh8fHJlcXVpcmUoXCIuL19zdHJlYW1fZHVwbGV4XCIpO2lmKCEodGhpcyBpbnN0YW5jZW9mIFJlYWRhYmxlKSlyZXR1cm4gbmV3IFJlYWRhYmxlKG9wdGlvbnMpO3RoaXMuX3JlYWRhYmxlU3RhdGU9bmV3IFJlYWRhYmxlU3RhdGUob3B0aW9ucyx0aGlzKTt0aGlzLnJlYWRhYmxlPXRydWU7aWYob3B0aW9ucyYmdHlwZW9mIG9wdGlvbnMucmVhZD09PVwiZnVuY3Rpb25cIil0aGlzLl9yZWFkPW9wdGlvbnMucmVhZDtTdHJlYW0uY2FsbCh0aGlzKX1SZWFkYWJsZS5wcm90b3R5cGUucHVzaD1mdW5jdGlvbihjaHVuayxlbmNvZGluZyl7dmFyIHN0YXRlPXRoaXMuX3JlYWRhYmxlU3RhdGU7aWYoIXN0YXRlLm9iamVjdE1vZGUmJnR5cGVvZiBjaHVuaz09PVwic3RyaW5nXCIpe2VuY29kaW5nPWVuY29kaW5nfHxzdGF0ZS5kZWZhdWx0RW5jb2Rpbmc7aWYoZW5jb2RpbmchPT1zdGF0ZS5lbmNvZGluZyl7Y2h1bms9YnVmZmVyU2hpbS5mcm9tKGNodW5rLGVuY29kaW5nKTtlbmNvZGluZz1cIlwifX1yZXR1cm4gcmVhZGFibGVBZGRDaHVuayh0aGlzLHN0YXRlLGNodW5rLGVuY29kaW5nLGZhbHNlKX07UmVhZGFibGUucHJvdG90eXBlLnVuc2hpZnQ9ZnVuY3Rpb24oY2h1bmspe3ZhciBzdGF0ZT10aGlzLl9yZWFkYWJsZVN0YXRlO3JldHVybiByZWFkYWJsZUFkZENodW5rKHRoaXMsc3RhdGUsY2h1bmssXCJcIix0cnVlKX07UmVhZGFibGUucHJvdG90eXBlLmlzUGF1c2VkPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZz09PWZhbHNlfTtmdW5jdGlvbiByZWFkYWJsZUFkZENodW5rKHN0cmVhbSxzdGF0ZSxjaHVuayxlbmNvZGluZyxhZGRUb0Zyb250KXt2YXIgZXI9Y2h1bmtJbnZhbGlkKHN0YXRlLGNodW5rKTtpZihlcil7c3RyZWFtLmVtaXQoXCJlcnJvclwiLGVyKX1lbHNlIGlmKGNodW5rPT09bnVsbCl7c3RhdGUucmVhZGluZz1mYWxzZTtvbkVvZkNodW5rKHN0cmVhbSxzdGF0ZSl9ZWxzZSBpZihzdGF0ZS5vYmplY3RNb2RlfHxjaHVuayYmY2h1bmsubGVuZ3RoPjApe2lmKHN0YXRlLmVuZGVkJiYhYWRkVG9Gcm9udCl7dmFyIGU9bmV3IEVycm9yKFwic3RyZWFtLnB1c2goKSBhZnRlciBFT0ZcIik7c3RyZWFtLmVtaXQoXCJlcnJvclwiLGUpfWVsc2UgaWYoc3RhdGUuZW5kRW1pdHRlZCYmYWRkVG9Gcm9udCl7dmFyIF9lPW5ldyBFcnJvcihcInN0cmVhbS51bnNoaWZ0KCkgYWZ0ZXIgZW5kIGV2ZW50XCIpO3N0cmVhbS5lbWl0KFwiZXJyb3JcIixfZSl9ZWxzZXt2YXIgc2tpcEFkZDtpZihzdGF0ZS5kZWNvZGVyJiYhYWRkVG9Gcm9udCYmIWVuY29kaW5nKXtjaHVuaz1zdGF0ZS5kZWNvZGVyLndyaXRlKGNodW5rKTtza2lwQWRkPSFzdGF0ZS5vYmplY3RNb2RlJiZjaHVuay5sZW5ndGg9PT0wfWlmKCFhZGRUb0Zyb250KXN0YXRlLnJlYWRpbmc9ZmFsc2U7aWYoIXNraXBBZGQpe2lmKHN0YXRlLmZsb3dpbmcmJnN0YXRlLmxlbmd0aD09PTAmJiFzdGF0ZS5zeW5jKXtzdHJlYW0uZW1pdChcImRhdGFcIixjaHVuayk7c3RyZWFtLnJlYWQoMCl9ZWxzZXtzdGF0ZS5sZW5ndGgrPXN0YXRlLm9iamVjdE1vZGU/MTpjaHVuay5sZW5ndGg7aWYoYWRkVG9Gcm9udClzdGF0ZS5idWZmZXIudW5zaGlmdChjaHVuayk7ZWxzZSBzdGF0ZS5idWZmZXIucHVzaChjaHVuayk7aWYoc3RhdGUubmVlZFJlYWRhYmxlKWVtaXRSZWFkYWJsZShzdHJlYW0pfX1tYXliZVJlYWRNb3JlKHN0cmVhbSxzdGF0ZSl9fWVsc2UgaWYoIWFkZFRvRnJvbnQpe3N0YXRlLnJlYWRpbmc9ZmFsc2V9cmV0dXJuIG5lZWRNb3JlRGF0YShzdGF0ZSl9ZnVuY3Rpb24gbmVlZE1vcmVEYXRhKHN0YXRlKXtyZXR1cm4hc3RhdGUuZW5kZWQmJihzdGF0ZS5uZWVkUmVhZGFibGV8fHN0YXRlLmxlbmd0aDxzdGF0ZS5oaWdoV2F0ZXJNYXJrfHxzdGF0ZS5sZW5ndGg9PT0wKX1SZWFkYWJsZS5wcm90b3R5cGUuc2V0RW5jb2Rpbmc9ZnVuY3Rpb24oZW5jKXtpZighU3RyaW5nRGVjb2RlcilTdHJpbmdEZWNvZGVyPXJlcXVpcmUoXCJzdHJpbmdfZGVjb2Rlci9cIikuU3RyaW5nRGVjb2Rlcjt0aGlzLl9yZWFkYWJsZVN0YXRlLmRlY29kZXI9bmV3IFN0cmluZ0RlY29kZXIoZW5jKTt0aGlzLl9yZWFkYWJsZVN0YXRlLmVuY29kaW5nPWVuYztyZXR1cm4gdGhpc307dmFyIE1BWF9IV009ODM4ODYwODtmdW5jdGlvbiBjb21wdXRlTmV3SGlnaFdhdGVyTWFyayhuKXtpZihuPj1NQVhfSFdNKXtuPU1BWF9IV019ZWxzZXtuLS07bnw9bj4+PjE7bnw9bj4+PjI7bnw9bj4+PjQ7bnw9bj4+Pjg7bnw9bj4+PjE2O24rK31yZXR1cm4gbn1mdW5jdGlvbiBob3dNdWNoVG9SZWFkKG4sc3RhdGUpe2lmKG48PTB8fHN0YXRlLmxlbmd0aD09PTAmJnN0YXRlLmVuZGVkKXJldHVybiAwO2lmKHN0YXRlLm9iamVjdE1vZGUpcmV0dXJuIDE7aWYobiE9PW4pe2lmKHN0YXRlLmZsb3dpbmcmJnN0YXRlLmxlbmd0aClyZXR1cm4gc3RhdGUuYnVmZmVyLmhlYWQuZGF0YS5sZW5ndGg7ZWxzZSByZXR1cm4gc3RhdGUubGVuZ3RofWlmKG4+c3RhdGUuaGlnaFdhdGVyTWFyaylzdGF0ZS5oaWdoV2F0ZXJNYXJrPWNvbXB1dGVOZXdIaWdoV2F0ZXJNYXJrKG4pO2lmKG48PXN0YXRlLmxlbmd0aClyZXR1cm4gbjtpZighc3RhdGUuZW5kZWQpe3N0YXRlLm5lZWRSZWFkYWJsZT10cnVlO3JldHVybiAwfXJldHVybiBzdGF0ZS5sZW5ndGh9UmVhZGFibGUucHJvdG90eXBlLnJlYWQ9ZnVuY3Rpb24obil7ZGVidWcoXCJyZWFkXCIsbik7bj1wYXJzZUludChuLDEwKTt2YXIgc3RhdGU9dGhpcy5fcmVhZGFibGVTdGF0ZTt2YXIgbk9yaWc9bjtpZihuIT09MClzdGF0ZS5lbWl0dGVkUmVhZGFibGU9ZmFsc2U7aWYobj09PTAmJnN0YXRlLm5lZWRSZWFkYWJsZSYmKHN0YXRlLmxlbmd0aD49c3RhdGUuaGlnaFdhdGVyTWFya3x8c3RhdGUuZW5kZWQpKXtkZWJ1ZyhcInJlYWQ6IGVtaXRSZWFkYWJsZVwiLHN0YXRlLmxlbmd0aCxzdGF0ZS5lbmRlZCk7aWYoc3RhdGUubGVuZ3RoPT09MCYmc3RhdGUuZW5kZWQpZW5kUmVhZGFibGUodGhpcyk7ZWxzZSBlbWl0UmVhZGFibGUodGhpcyk7cmV0dXJuIG51bGx9bj1ob3dNdWNoVG9SZWFkKG4sc3RhdGUpO2lmKG49PT0wJiZzdGF0ZS5lbmRlZCl7aWYoc3RhdGUubGVuZ3RoPT09MCllbmRSZWFkYWJsZSh0aGlzKTtyZXR1cm4gbnVsbH12YXIgZG9SZWFkPXN0YXRlLm5lZWRSZWFkYWJsZTtkZWJ1ZyhcIm5lZWQgcmVhZGFibGVcIixkb1JlYWQpO2lmKHN0YXRlLmxlbmd0aD09PTB8fHN0YXRlLmxlbmd0aC1uPHN0YXRlLmhpZ2hXYXRlck1hcmspe2RvUmVhZD10cnVlO2RlYnVnKFwibGVuZ3RoIGxlc3MgdGhhbiB3YXRlcm1hcmtcIixkb1JlYWQpfWlmKHN0YXRlLmVuZGVkfHxzdGF0ZS5yZWFkaW5nKXtkb1JlYWQ9ZmFsc2U7ZGVidWcoXCJyZWFkaW5nIG9yIGVuZGVkXCIsZG9SZWFkKX1lbHNlIGlmKGRvUmVhZCl7ZGVidWcoXCJkbyByZWFkXCIpO3N0YXRlLnJlYWRpbmc9dHJ1ZTtzdGF0ZS5zeW5jPXRydWU7aWYoc3RhdGUubGVuZ3RoPT09MClzdGF0ZS5uZWVkUmVhZGFibGU9dHJ1ZTt0aGlzLl9yZWFkKHN0YXRlLmhpZ2hXYXRlck1hcmspO3N0YXRlLnN5bmM9ZmFsc2U7aWYoIXN0YXRlLnJlYWRpbmcpbj1ob3dNdWNoVG9SZWFkKG5PcmlnLHN0YXRlKX12YXIgcmV0O2lmKG4+MClyZXQ9ZnJvbUxpc3QobixzdGF0ZSk7ZWxzZSByZXQ9bnVsbDtpZihyZXQ9PT1udWxsKXtzdGF0ZS5uZWVkUmVhZGFibGU9dHJ1ZTtuPTB9ZWxzZXtzdGF0ZS5sZW5ndGgtPW59aWYoc3RhdGUubGVuZ3RoPT09MCl7aWYoIXN0YXRlLmVuZGVkKXN0YXRlLm5lZWRSZWFkYWJsZT10cnVlO2lmKG5PcmlnIT09biYmc3RhdGUuZW5kZWQpZW5kUmVhZGFibGUodGhpcyl9aWYocmV0IT09bnVsbCl0aGlzLmVtaXQoXCJkYXRhXCIscmV0KTtyZXR1cm4gcmV0fTtmdW5jdGlvbiBjaHVua0ludmFsaWQoc3RhdGUsY2h1bmspe3ZhciBlcj1udWxsO2lmKCFCdWZmZXIuaXNCdWZmZXIoY2h1bmspJiZ0eXBlb2YgY2h1bmshPT1cInN0cmluZ1wiJiZjaHVuayE9PW51bGwmJmNodW5rIT09dW5kZWZpbmVkJiYhc3RhdGUub2JqZWN0TW9kZSl7ZXI9bmV3IFR5cGVFcnJvcihcIkludmFsaWQgbm9uLXN0cmluZy9idWZmZXIgY2h1bmtcIil9cmV0dXJuIGVyfWZ1bmN0aW9uIG9uRW9mQ2h1bmsoc3RyZWFtLHN0YXRlKXtpZihzdGF0ZS5lbmRlZClyZXR1cm47aWYoc3RhdGUuZGVjb2Rlcil7dmFyIGNodW5rPXN0YXRlLmRlY29kZXIuZW5kKCk7aWYoY2h1bmsmJmNodW5rLmxlbmd0aCl7c3RhdGUuYnVmZmVyLnB1c2goY2h1bmspO3N0YXRlLmxlbmd0aCs9c3RhdGUub2JqZWN0TW9kZT8xOmNodW5rLmxlbmd0aH19c3RhdGUuZW5kZWQ9dHJ1ZTtlbWl0UmVhZGFibGUoc3RyZWFtKX1mdW5jdGlvbiBlbWl0UmVhZGFibGUoc3RyZWFtKXt2YXIgc3RhdGU9c3RyZWFtLl9yZWFkYWJsZVN0YXRlO3N0YXRlLm5lZWRSZWFkYWJsZT1mYWxzZTtpZighc3RhdGUuZW1pdHRlZFJlYWRhYmxlKXtkZWJ1ZyhcImVtaXRSZWFkYWJsZVwiLHN0YXRlLmZsb3dpbmcpO3N0YXRlLmVtaXR0ZWRSZWFkYWJsZT10cnVlO2lmKHN0YXRlLnN5bmMpcHJvY2Vzc05leHRUaWNrKGVtaXRSZWFkYWJsZV8sc3RyZWFtKTtlbHNlIGVtaXRSZWFkYWJsZV8oc3RyZWFtKX19ZnVuY3Rpb24gZW1pdFJlYWRhYmxlXyhzdHJlYW0pe2RlYnVnKFwiZW1pdCByZWFkYWJsZVwiKTtzdHJlYW0uZW1pdChcInJlYWRhYmxlXCIpO2Zsb3coc3RyZWFtKX1mdW5jdGlvbiBtYXliZVJlYWRNb3JlKHN0cmVhbSxzdGF0ZSl7aWYoIXN0YXRlLnJlYWRpbmdNb3JlKXtzdGF0ZS5yZWFkaW5nTW9yZT10cnVlO3Byb2Nlc3NOZXh0VGljayhtYXliZVJlYWRNb3JlXyxzdHJlYW0sc3RhdGUpfX1mdW5jdGlvbiBtYXliZVJlYWRNb3JlXyhzdHJlYW0sc3RhdGUpe3ZhciBsZW49c3RhdGUubGVuZ3RoO3doaWxlKCFzdGF0ZS5yZWFkaW5nJiYhc3RhdGUuZmxvd2luZyYmIXN0YXRlLmVuZGVkJiZzdGF0ZS5sZW5ndGg8c3RhdGUuaGlnaFdhdGVyTWFyayl7ZGVidWcoXCJtYXliZVJlYWRNb3JlIHJlYWQgMFwiKTtzdHJlYW0ucmVhZCgwKTtpZihsZW49PT1zdGF0ZS5sZW5ndGgpYnJlYWs7ZWxzZSBsZW49c3RhdGUubGVuZ3RofXN0YXRlLnJlYWRpbmdNb3JlPWZhbHNlfVJlYWRhYmxlLnByb3RvdHlwZS5fcmVhZD1mdW5jdGlvbihuKXt0aGlzLmVtaXQoXCJlcnJvclwiLG5ldyBFcnJvcihcIm5vdCBpbXBsZW1lbnRlZFwiKSl9O1JlYWRhYmxlLnByb3RvdHlwZS5waXBlPWZ1bmN0aW9uKGRlc3QscGlwZU9wdHMpe3ZhciBzcmM9dGhpczt2YXIgc3RhdGU9dGhpcy5fcmVhZGFibGVTdGF0ZTtzd2l0Y2goc3RhdGUucGlwZXNDb3VudCl7Y2FzZSAwOnN0YXRlLnBpcGVzPWRlc3Q7YnJlYWs7Y2FzZSAxOnN0YXRlLnBpcGVzPVtzdGF0ZS5waXBlcyxkZXN0XTticmVhaztkZWZhdWx0OnN0YXRlLnBpcGVzLnB1c2goZGVzdCk7YnJlYWt9c3RhdGUucGlwZXNDb3VudCs9MTtkZWJ1ZyhcInBpcGUgY291bnQ9JWQgb3B0cz0lalwiLHN0YXRlLnBpcGVzQ291bnQscGlwZU9wdHMpO3ZhciBkb0VuZD0oIXBpcGVPcHRzfHxwaXBlT3B0cy5lbmQhPT1mYWxzZSkmJmRlc3QhPT1wcm9jZXNzLnN0ZG91dCYmZGVzdCE9PXByb2Nlc3Muc3RkZXJyO3ZhciBlbmRGbj1kb0VuZD9vbmVuZDpjbGVhbnVwO2lmKHN0YXRlLmVuZEVtaXR0ZWQpcHJvY2Vzc05leHRUaWNrKGVuZEZuKTtlbHNlIHNyYy5vbmNlKFwiZW5kXCIsZW5kRm4pO2Rlc3Qub24oXCJ1bnBpcGVcIixvbnVucGlwZSk7ZnVuY3Rpb24gb251bnBpcGUocmVhZGFibGUpe2RlYnVnKFwib251bnBpcGVcIik7aWYocmVhZGFibGU9PT1zcmMpe2NsZWFudXAoKX19ZnVuY3Rpb24gb25lbmQoKXtkZWJ1ZyhcIm9uZW5kXCIpO2Rlc3QuZW5kKCl9dmFyIG9uZHJhaW49cGlwZU9uRHJhaW4oc3JjKTtkZXN0Lm9uKFwiZHJhaW5cIixvbmRyYWluKTt2YXIgY2xlYW5lZFVwPWZhbHNlO2Z1bmN0aW9uIGNsZWFudXAoKXtkZWJ1ZyhcImNsZWFudXBcIik7ZGVzdC5yZW1vdmVMaXN0ZW5lcihcImNsb3NlXCIsb25jbG9zZSk7ZGVzdC5yZW1vdmVMaXN0ZW5lcihcImZpbmlzaFwiLG9uZmluaXNoKTtkZXN0LnJlbW92ZUxpc3RlbmVyKFwiZHJhaW5cIixvbmRyYWluKTtkZXN0LnJlbW92ZUxpc3RlbmVyKFwiZXJyb3JcIixvbmVycm9yKTtkZXN0LnJlbW92ZUxpc3RlbmVyKFwidW5waXBlXCIsb251bnBpcGUpO3NyYy5yZW1vdmVMaXN0ZW5lcihcImVuZFwiLG9uZW5kKTtzcmMucmVtb3ZlTGlzdGVuZXIoXCJlbmRcIixjbGVhbnVwKTtzcmMucmVtb3ZlTGlzdGVuZXIoXCJkYXRhXCIsb25kYXRhKTtjbGVhbmVkVXA9dHJ1ZTtpZihzdGF0ZS5hd2FpdERyYWluJiYoIWRlc3QuX3dyaXRhYmxlU3RhdGV8fGRlc3QuX3dyaXRhYmxlU3RhdGUubmVlZERyYWluKSlvbmRyYWluKCl9dmFyIGluY3JlYXNlZEF3YWl0RHJhaW49ZmFsc2U7c3JjLm9uKFwiZGF0YVwiLG9uZGF0YSk7ZnVuY3Rpb24gb25kYXRhKGNodW5rKXtkZWJ1ZyhcIm9uZGF0YVwiKTtpbmNyZWFzZWRBd2FpdERyYWluPWZhbHNlO3ZhciByZXQ9ZGVzdC53cml0ZShjaHVuayk7aWYoZmFsc2U9PT1yZXQmJiFpbmNyZWFzZWRBd2FpdERyYWluKXtpZigoc3RhdGUucGlwZXNDb3VudD09PTEmJnN0YXRlLnBpcGVzPT09ZGVzdHx8c3RhdGUucGlwZXNDb3VudD4xJiZpbmRleE9mKHN0YXRlLnBpcGVzLGRlc3QpIT09LTEpJiYhY2xlYW5lZFVwKXtkZWJ1ZyhcImZhbHNlIHdyaXRlIHJlc3BvbnNlLCBwYXVzZVwiLHNyYy5fcmVhZGFibGVTdGF0ZS5hd2FpdERyYWluKTtzcmMuX3JlYWRhYmxlU3RhdGUuYXdhaXREcmFpbisrO2luY3JlYXNlZEF3YWl0RHJhaW49dHJ1ZX1zcmMucGF1c2UoKX19ZnVuY3Rpb24gb25lcnJvcihlcil7ZGVidWcoXCJvbmVycm9yXCIsZXIpO3VucGlwZSgpO2Rlc3QucmVtb3ZlTGlzdGVuZXIoXCJlcnJvclwiLG9uZXJyb3IpO2lmKEVFbGlzdGVuZXJDb3VudChkZXN0LFwiZXJyb3JcIik9PT0wKWRlc3QuZW1pdChcImVycm9yXCIsZXIpfXByZXBlbmRMaXN0ZW5lcihkZXN0LFwiZXJyb3JcIixvbmVycm9yKTtmdW5jdGlvbiBvbmNsb3NlKCl7ZGVzdC5yZW1vdmVMaXN0ZW5lcihcImZpbmlzaFwiLG9uZmluaXNoKTt1bnBpcGUoKX1kZXN0Lm9uY2UoXCJjbG9zZVwiLG9uY2xvc2UpO2Z1bmN0aW9uIG9uZmluaXNoKCl7ZGVidWcoXCJvbmZpbmlzaFwiKTtkZXN0LnJlbW92ZUxpc3RlbmVyKFwiY2xvc2VcIixvbmNsb3NlKTt1bnBpcGUoKX1kZXN0Lm9uY2UoXCJmaW5pc2hcIixvbmZpbmlzaCk7ZnVuY3Rpb24gdW5waXBlKCl7ZGVidWcoXCJ1bnBpcGVcIik7c3JjLnVucGlwZShkZXN0KX1kZXN0LmVtaXQoXCJwaXBlXCIsc3JjKTtpZighc3RhdGUuZmxvd2luZyl7ZGVidWcoXCJwaXBlIHJlc3VtZVwiKTtzcmMucmVzdW1lKCl9cmV0dXJuIGRlc3R9O2Z1bmN0aW9uIHBpcGVPbkRyYWluKHNyYyl7cmV0dXJuIGZ1bmN0aW9uKCl7dmFyIHN0YXRlPXNyYy5fcmVhZGFibGVTdGF0ZTtkZWJ1ZyhcInBpcGVPbkRyYWluXCIsc3RhdGUuYXdhaXREcmFpbik7aWYoc3RhdGUuYXdhaXREcmFpbilzdGF0ZS5hd2FpdERyYWluLS07aWYoc3RhdGUuYXdhaXREcmFpbj09PTAmJkVFbGlzdGVuZXJDb3VudChzcmMsXCJkYXRhXCIpKXtzdGF0ZS5mbG93aW5nPXRydWU7ZmxvdyhzcmMpfX19UmVhZGFibGUucHJvdG90eXBlLnVucGlwZT1mdW5jdGlvbihkZXN0KXt2YXIgc3RhdGU9dGhpcy5fcmVhZGFibGVTdGF0ZTtpZihzdGF0ZS5waXBlc0NvdW50PT09MClyZXR1cm4gdGhpcztpZihzdGF0ZS5waXBlc0NvdW50PT09MSl7aWYoZGVzdCYmZGVzdCE9PXN0YXRlLnBpcGVzKXJldHVybiB0aGlzO2lmKCFkZXN0KWRlc3Q9c3RhdGUucGlwZXM7c3RhdGUucGlwZXM9bnVsbDtzdGF0ZS5waXBlc0NvdW50PTA7c3RhdGUuZmxvd2luZz1mYWxzZTtpZihkZXN0KWRlc3QuZW1pdChcInVucGlwZVwiLHRoaXMpO3JldHVybiB0aGlzfWlmKCFkZXN0KXt2YXIgZGVzdHM9c3RhdGUucGlwZXM7dmFyIGxlbj1zdGF0ZS5waXBlc0NvdW50O3N0YXRlLnBpcGVzPW51bGw7c3RhdGUucGlwZXNDb3VudD0wO3N0YXRlLmZsb3dpbmc9ZmFsc2U7Zm9yKHZhciBfaT0wO19pPGxlbjtfaSsrKXtkZXN0c1tfaV0uZW1pdChcInVucGlwZVwiLHRoaXMpfXJldHVybiB0aGlzfXZhciBpPWluZGV4T2Yoc3RhdGUucGlwZXMsZGVzdCk7aWYoaT09PS0xKXJldHVybiB0aGlzO3N0YXRlLnBpcGVzLnNwbGljZShpLDEpO3N0YXRlLnBpcGVzQ291bnQtPTE7aWYoc3RhdGUucGlwZXNDb3VudD09PTEpc3RhdGUucGlwZXM9c3RhdGUucGlwZXNbMF07ZGVzdC5lbWl0KFwidW5waXBlXCIsdGhpcyk7cmV0dXJuIHRoaXN9O1JlYWRhYmxlLnByb3RvdHlwZS5vbj1mdW5jdGlvbihldixmbil7dmFyIHJlcz1TdHJlYW0ucHJvdG90eXBlLm9uLmNhbGwodGhpcyxldixmbik7aWYoZXY9PT1cImRhdGFcIil7aWYodGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nIT09ZmFsc2UpdGhpcy5yZXN1bWUoKX1lbHNlIGlmKGV2PT09XCJyZWFkYWJsZVwiKXt2YXIgc3RhdGU9dGhpcy5fcmVhZGFibGVTdGF0ZTtpZighc3RhdGUuZW5kRW1pdHRlZCYmIXN0YXRlLnJlYWRhYmxlTGlzdGVuaW5nKXtzdGF0ZS5yZWFkYWJsZUxpc3RlbmluZz1zdGF0ZS5uZWVkUmVhZGFibGU9dHJ1ZTtzdGF0ZS5lbWl0dGVkUmVhZGFibGU9ZmFsc2U7aWYoIXN0YXRlLnJlYWRpbmcpe3Byb2Nlc3NOZXh0VGljayhuUmVhZGluZ05leHRUaWNrLHRoaXMpfWVsc2UgaWYoc3RhdGUubGVuZ3RoKXtlbWl0UmVhZGFibGUodGhpcyxzdGF0ZSl9fX1yZXR1cm4gcmVzfTtSZWFkYWJsZS5wcm90b3R5cGUuYWRkTGlzdGVuZXI9UmVhZGFibGUucHJvdG90eXBlLm9uO2Z1bmN0aW9uIG5SZWFkaW5nTmV4dFRpY2soc2VsZil7ZGVidWcoXCJyZWFkYWJsZSBuZXh0dGljayByZWFkIDBcIik7c2VsZi5yZWFkKDApfVJlYWRhYmxlLnByb3RvdHlwZS5yZXN1bWU9ZnVuY3Rpb24oKXt2YXIgc3RhdGU9dGhpcy5fcmVhZGFibGVTdGF0ZTtpZighc3RhdGUuZmxvd2luZyl7ZGVidWcoXCJyZXN1bWVcIik7c3RhdGUuZmxvd2luZz10cnVlO3Jlc3VtZSh0aGlzLHN0YXRlKX1yZXR1cm4gdGhpc307ZnVuY3Rpb24gcmVzdW1lKHN0cmVhbSxzdGF0ZSl7aWYoIXN0YXRlLnJlc3VtZVNjaGVkdWxlZCl7c3RhdGUucmVzdW1lU2NoZWR1bGVkPXRydWU7cHJvY2Vzc05leHRUaWNrKHJlc3VtZV8sc3RyZWFtLHN0YXRlKX19ZnVuY3Rpb24gcmVzdW1lXyhzdHJlYW0sc3RhdGUpe2lmKCFzdGF0ZS5yZWFkaW5nKXtkZWJ1ZyhcInJlc3VtZSByZWFkIDBcIik7c3RyZWFtLnJlYWQoMCl9c3RhdGUucmVzdW1lU2NoZWR1bGVkPWZhbHNlO3N0YXRlLmF3YWl0RHJhaW49MDtzdHJlYW0uZW1pdChcInJlc3VtZVwiKTtmbG93KHN0cmVhbSk7aWYoc3RhdGUuZmxvd2luZyYmIXN0YXRlLnJlYWRpbmcpc3RyZWFtLnJlYWQoMCl9UmVhZGFibGUucHJvdG90eXBlLnBhdXNlPWZ1bmN0aW9uKCl7ZGVidWcoXCJjYWxsIHBhdXNlIGZsb3dpbmc9JWpcIix0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcpO2lmKGZhbHNlIT09dGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nKXtkZWJ1ZyhcInBhdXNlXCIpO3RoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZz1mYWxzZTt0aGlzLmVtaXQoXCJwYXVzZVwiKX1yZXR1cm4gdGhpc307ZnVuY3Rpb24gZmxvdyhzdHJlYW0pe3ZhciBzdGF0ZT1zdHJlYW0uX3JlYWRhYmxlU3RhdGU7ZGVidWcoXCJmbG93XCIsc3RhdGUuZmxvd2luZyk7d2hpbGUoc3RhdGUuZmxvd2luZyYmc3RyZWFtLnJlYWQoKSE9PW51bGwpe319UmVhZGFibGUucHJvdG90eXBlLndyYXA9ZnVuY3Rpb24oc3RyZWFtKXt2YXIgc3RhdGU9dGhpcy5fcmVhZGFibGVTdGF0ZTt2YXIgcGF1c2VkPWZhbHNlO3ZhciBzZWxmPXRoaXM7c3RyZWFtLm9uKFwiZW5kXCIsZnVuY3Rpb24oKXtkZWJ1ZyhcIndyYXBwZWQgZW5kXCIpO2lmKHN0YXRlLmRlY29kZXImJiFzdGF0ZS5lbmRlZCl7dmFyIGNodW5rPXN0YXRlLmRlY29kZXIuZW5kKCk7aWYoY2h1bmsmJmNodW5rLmxlbmd0aClzZWxmLnB1c2goY2h1bmspfXNlbGYucHVzaChudWxsKX0pO3N0cmVhbS5vbihcImRhdGFcIixmdW5jdGlvbihjaHVuayl7ZGVidWcoXCJ3cmFwcGVkIGRhdGFcIik7aWYoc3RhdGUuZGVjb2RlciljaHVuaz1zdGF0ZS5kZWNvZGVyLndyaXRlKGNodW5rKTtpZihzdGF0ZS5vYmplY3RNb2RlJiYoY2h1bms9PT1udWxsfHxjaHVuaz09PXVuZGVmaW5lZCkpcmV0dXJuO2Vsc2UgaWYoIXN0YXRlLm9iamVjdE1vZGUmJighY2h1bmt8fCFjaHVuay5sZW5ndGgpKXJldHVybjt2YXIgcmV0PXNlbGYucHVzaChjaHVuayk7aWYoIXJldCl7cGF1c2VkPXRydWU7c3RyZWFtLnBhdXNlKCl9fSk7Zm9yKHZhciBpIGluIHN0cmVhbSl7aWYodGhpc1tpXT09PXVuZGVmaW5lZCYmdHlwZW9mIHN0cmVhbVtpXT09PVwiZnVuY3Rpb25cIil7dGhpc1tpXT1mdW5jdGlvbihtZXRob2Qpe3JldHVybiBmdW5jdGlvbigpe3JldHVybiBzdHJlYW1bbWV0aG9kXS5hcHBseShzdHJlYW0sYXJndW1lbnRzKX19KGkpfX12YXIgZXZlbnRzPVtcImVycm9yXCIsXCJjbG9zZVwiLFwiZGVzdHJveVwiLFwicGF1c2VcIixcInJlc3VtZVwiXTtmb3JFYWNoKGV2ZW50cyxmdW5jdGlvbihldil7c3RyZWFtLm9uKGV2LHNlbGYuZW1pdC5iaW5kKHNlbGYsZXYpKX0pO3NlbGYuX3JlYWQ9ZnVuY3Rpb24obil7ZGVidWcoXCJ3cmFwcGVkIF9yZWFkXCIsbik7aWYocGF1c2VkKXtwYXVzZWQ9ZmFsc2U7c3RyZWFtLnJlc3VtZSgpfX07cmV0dXJuIHNlbGZ9O1JlYWRhYmxlLl9mcm9tTGlzdD1mcm9tTGlzdDtmdW5jdGlvbiBmcm9tTGlzdChuLHN0YXRlKXtpZihzdGF0ZS5sZW5ndGg9PT0wKXJldHVybiBudWxsO3ZhciByZXQ7aWYoc3RhdGUub2JqZWN0TW9kZSlyZXQ9c3RhdGUuYnVmZmVyLnNoaWZ0KCk7ZWxzZSBpZighbnx8bj49c3RhdGUubGVuZ3RoKXtpZihzdGF0ZS5kZWNvZGVyKXJldD1zdGF0ZS5idWZmZXIuam9pbihcIlwiKTtlbHNlIGlmKHN0YXRlLmJ1ZmZlci5sZW5ndGg9PT0xKXJldD1zdGF0ZS5idWZmZXIuaGVhZC5kYXRhO2Vsc2UgcmV0PXN0YXRlLmJ1ZmZlci5jb25jYXQoc3RhdGUubGVuZ3RoKTtzdGF0ZS5idWZmZXIuY2xlYXIoKX1lbHNle3JldD1mcm9tTGlzdFBhcnRpYWwobixzdGF0ZS5idWZmZXIsc3RhdGUuZGVjb2Rlcil9cmV0dXJuIHJldH1mdW5jdGlvbiBmcm9tTGlzdFBhcnRpYWwobixsaXN0LGhhc1N0cmluZ3Mpe3ZhciByZXQ7aWYobjxsaXN0LmhlYWQuZGF0YS5sZW5ndGgpe3JldD1saXN0LmhlYWQuZGF0YS5zbGljZSgwLG4pO2xpc3QuaGVhZC5kYXRhPWxpc3QuaGVhZC5kYXRhLnNsaWNlKG4pfWVsc2UgaWYobj09PWxpc3QuaGVhZC5kYXRhLmxlbmd0aCl7cmV0PWxpc3Quc2hpZnQoKX1lbHNle3JldD1oYXNTdHJpbmdzP2NvcHlGcm9tQnVmZmVyU3RyaW5nKG4sbGlzdCk6Y29weUZyb21CdWZmZXIobixsaXN0KX1yZXR1cm4gcmV0fWZ1bmN0aW9uIGNvcHlGcm9tQnVmZmVyU3RyaW5nKG4sbGlzdCl7dmFyIHA9bGlzdC5oZWFkO3ZhciBjPTE7dmFyIHJldD1wLmRhdGE7bi09cmV0Lmxlbmd0aDt3aGlsZShwPXAubmV4dCl7dmFyIHN0cj1wLmRhdGE7dmFyIG5iPW4+c3RyLmxlbmd0aD9zdHIubGVuZ3RoOm47aWYobmI9PT1zdHIubGVuZ3RoKXJldCs9c3RyO2Vsc2UgcmV0Kz1zdHIuc2xpY2UoMCxuKTtuLT1uYjtpZihuPT09MCl7aWYobmI9PT1zdHIubGVuZ3RoKXsrK2M7aWYocC5uZXh0KWxpc3QuaGVhZD1wLm5leHQ7ZWxzZSBsaXN0LmhlYWQ9bGlzdC50YWlsPW51bGx9ZWxzZXtsaXN0LmhlYWQ9cDtwLmRhdGE9c3RyLnNsaWNlKG5iKX1icmVha30rK2N9bGlzdC5sZW5ndGgtPWM7cmV0dXJuIHJldH1mdW5jdGlvbiBjb3B5RnJvbUJ1ZmZlcihuLGxpc3Qpe3ZhciByZXQ9YnVmZmVyU2hpbS5hbGxvY1Vuc2FmZShuKTt2YXIgcD1saXN0LmhlYWQ7dmFyIGM9MTtwLmRhdGEuY29weShyZXQpO24tPXAuZGF0YS5sZW5ndGg7d2hpbGUocD1wLm5leHQpe3ZhciBidWY9cC5kYXRhO3ZhciBuYj1uPmJ1Zi5sZW5ndGg/YnVmLmxlbmd0aDpuO2J1Zi5jb3B5KHJldCxyZXQubGVuZ3RoLW4sMCxuYik7bi09bmI7aWYobj09PTApe2lmKG5iPT09YnVmLmxlbmd0aCl7KytjO2lmKHAubmV4dClsaXN0LmhlYWQ9cC5uZXh0O2Vsc2UgbGlzdC5oZWFkPWxpc3QudGFpbD1udWxsfWVsc2V7bGlzdC5oZWFkPXA7cC5kYXRhPWJ1Zi5zbGljZShuYil9YnJlYWt9KytjfWxpc3QubGVuZ3RoLT1jO3JldHVybiByZXR9ZnVuY3Rpb24gZW5kUmVhZGFibGUoc3RyZWFtKXt2YXIgc3RhdGU9c3RyZWFtLl9yZWFkYWJsZVN0YXRlO2lmKHN0YXRlLmxlbmd0aD4wKXRocm93IG5ldyBFcnJvcignXCJlbmRSZWFkYWJsZSgpXCIgY2FsbGVkIG9uIG5vbi1lbXB0eSBzdHJlYW0nKTtpZighc3RhdGUuZW5kRW1pdHRlZCl7c3RhdGUuZW5kZWQ9dHJ1ZTtwcm9jZXNzTmV4dFRpY2soZW5kUmVhZGFibGVOVCxzdGF0ZSxzdHJlYW0pfX1mdW5jdGlvbiBlbmRSZWFkYWJsZU5UKHN0YXRlLHN0cmVhbSl7aWYoIXN0YXRlLmVuZEVtaXR0ZWQmJnN0YXRlLmxlbmd0aD09PTApe3N0YXRlLmVuZEVtaXR0ZWQ9dHJ1ZTtzdHJlYW0ucmVhZGFibGU9ZmFsc2U7c3RyZWFtLmVtaXQoXCJlbmRcIil9fWZ1bmN0aW9uIGZvckVhY2goeHMsZil7Zm9yKHZhciBpPTAsbD14cy5sZW5ndGg7aTxsO2krKyl7Zih4c1tpXSxpKX19ZnVuY3Rpb24gaW5kZXhPZih4cyx4KXtmb3IodmFyIGk9MCxsPXhzLmxlbmd0aDtpPGw7aSsrKXtpZih4c1tpXT09PXgpcmV0dXJuIGl9cmV0dXJuLTF9fSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJfcHJvY2Vzc1wiKSl9LHtcIi4vX3N0cmVhbV9kdXBsZXhcIjo0NCxcIi4vaW50ZXJuYWwvc3RyZWFtcy9CdWZmZXJMaXN0XCI6NDksX3Byb2Nlc3M6NDIsYnVmZmVyOjUsXCJidWZmZXItc2hpbXNcIjo0LFwiY29yZS11dGlsLWlzXCI6NixldmVudHM6MjgsaW5oZXJpdHM6MzgsaXNhcnJheTo0MCxcInByb2Nlc3MtbmV4dGljay1hcmdzXCI6NDEsXCJzdHJpbmdfZGVjb2Rlci9cIjo1Nix1dGlsOjN9XSw0NzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XCJ1c2Ugc3RyaWN0XCI7bW9kdWxlLmV4cG9ydHM9VHJhbnNmb3JtO3ZhciBEdXBsZXg9cmVxdWlyZShcIi4vX3N0cmVhbV9kdXBsZXhcIik7dmFyIHV0aWw9cmVxdWlyZShcImNvcmUtdXRpbC1pc1wiKTt1dGlsLmluaGVyaXRzPXJlcXVpcmUoXCJpbmhlcml0c1wiKTt1dGlsLmluaGVyaXRzKFRyYW5zZm9ybSxEdXBsZXgpO2Z1bmN0aW9uIFRyYW5zZm9ybVN0YXRlKHN0cmVhbSl7dGhpcy5hZnRlclRyYW5zZm9ybT1mdW5jdGlvbihlcixkYXRhKXtyZXR1cm4gYWZ0ZXJUcmFuc2Zvcm0oc3RyZWFtLGVyLGRhdGEpfTt0aGlzLm5lZWRUcmFuc2Zvcm09ZmFsc2U7dGhpcy50cmFuc2Zvcm1pbmc9ZmFsc2U7dGhpcy53cml0ZWNiPW51bGw7dGhpcy53cml0ZWNodW5rPW51bGw7dGhpcy53cml0ZWVuY29kaW5nPW51bGx9ZnVuY3Rpb24gYWZ0ZXJUcmFuc2Zvcm0oc3RyZWFtLGVyLGRhdGEpe3ZhciB0cz1zdHJlYW0uX3RyYW5zZm9ybVN0YXRlO3RzLnRyYW5zZm9ybWluZz1mYWxzZTt2YXIgY2I9dHMud3JpdGVjYjtpZighY2IpcmV0dXJuIHN0cmVhbS5lbWl0KFwiZXJyb3JcIixuZXcgRXJyb3IoXCJubyB3cml0ZWNiIGluIFRyYW5zZm9ybSBjbGFzc1wiKSk7dHMud3JpdGVjaHVuaz1udWxsO3RzLndyaXRlY2I9bnVsbDtpZihkYXRhIT09bnVsbCYmZGF0YSE9PXVuZGVmaW5lZClzdHJlYW0ucHVzaChkYXRhKTtjYihlcik7dmFyIHJzPXN0cmVhbS5fcmVhZGFibGVTdGF0ZTtycy5yZWFkaW5nPWZhbHNlO2lmKHJzLm5lZWRSZWFkYWJsZXx8cnMubGVuZ3RoPHJzLmhpZ2hXYXRlck1hcmspe3N0cmVhbS5fcmVhZChycy5oaWdoV2F0ZXJNYXJrKX19ZnVuY3Rpb24gVHJhbnNmb3JtKG9wdGlvbnMpe2lmKCEodGhpcyBpbnN0YW5jZW9mIFRyYW5zZm9ybSkpcmV0dXJuIG5ldyBUcmFuc2Zvcm0ob3B0aW9ucyk7RHVwbGV4LmNhbGwodGhpcyxvcHRpb25zKTt0aGlzLl90cmFuc2Zvcm1TdGF0ZT1uZXcgVHJhbnNmb3JtU3RhdGUodGhpcyk7dmFyIHN0cmVhbT10aGlzO3RoaXMuX3JlYWRhYmxlU3RhdGUubmVlZFJlYWRhYmxlPXRydWU7dGhpcy5fcmVhZGFibGVTdGF0ZS5zeW5jPWZhbHNlO2lmKG9wdGlvbnMpe2lmKHR5cGVvZiBvcHRpb25zLnRyYW5zZm9ybT09PVwiZnVuY3Rpb25cIil0aGlzLl90cmFuc2Zvcm09b3B0aW9ucy50cmFuc2Zvcm07aWYodHlwZW9mIG9wdGlvbnMuZmx1c2g9PT1cImZ1bmN0aW9uXCIpdGhpcy5fZmx1c2g9b3B0aW9ucy5mbHVzaH10aGlzLm9uY2UoXCJwcmVmaW5pc2hcIixmdW5jdGlvbigpe2lmKHR5cGVvZiB0aGlzLl9mbHVzaD09PVwiZnVuY3Rpb25cIil0aGlzLl9mbHVzaChmdW5jdGlvbihlcil7ZG9uZShzdHJlYW0sZXIpfSk7ZWxzZSBkb25lKHN0cmVhbSl9KX1UcmFuc2Zvcm0ucHJvdG90eXBlLnB1c2g9ZnVuY3Rpb24oY2h1bmssZW5jb2Rpbmcpe3RoaXMuX3RyYW5zZm9ybVN0YXRlLm5lZWRUcmFuc2Zvcm09ZmFsc2U7cmV0dXJuIER1cGxleC5wcm90b3R5cGUucHVzaC5jYWxsKHRoaXMsY2h1bmssZW5jb2RpbmcpfTtUcmFuc2Zvcm0ucHJvdG90eXBlLl90cmFuc2Zvcm09ZnVuY3Rpb24oY2h1bmssZW5jb2RpbmcsY2Ipe3Rocm93IG5ldyBFcnJvcihcIk5vdCBpbXBsZW1lbnRlZFwiKX07VHJhbnNmb3JtLnByb3RvdHlwZS5fd3JpdGU9ZnVuY3Rpb24oY2h1bmssZW5jb2RpbmcsY2Ipe3ZhciB0cz10aGlzLl90cmFuc2Zvcm1TdGF0ZTt0cy53cml0ZWNiPWNiO3RzLndyaXRlY2h1bms9Y2h1bms7dHMud3JpdGVlbmNvZGluZz1lbmNvZGluZztpZighdHMudHJhbnNmb3JtaW5nKXt2YXIgcnM9dGhpcy5fcmVhZGFibGVTdGF0ZTtpZih0cy5uZWVkVHJhbnNmb3JtfHxycy5uZWVkUmVhZGFibGV8fHJzLmxlbmd0aDxycy5oaWdoV2F0ZXJNYXJrKXRoaXMuX3JlYWQocnMuaGlnaFdhdGVyTWFyayl9fTtUcmFuc2Zvcm0ucHJvdG90eXBlLl9yZWFkPWZ1bmN0aW9uKG4pe3ZhciB0cz10aGlzLl90cmFuc2Zvcm1TdGF0ZTtpZih0cy53cml0ZWNodW5rIT09bnVsbCYmdHMud3JpdGVjYiYmIXRzLnRyYW5zZm9ybWluZyl7dHMudHJhbnNmb3JtaW5nPXRydWU7dGhpcy5fdHJhbnNmb3JtKHRzLndyaXRlY2h1bmssdHMud3JpdGVlbmNvZGluZyx0cy5hZnRlclRyYW5zZm9ybSl9ZWxzZXt0cy5uZWVkVHJhbnNmb3JtPXRydWV9fTtmdW5jdGlvbiBkb25lKHN0cmVhbSxlcil7aWYoZXIpcmV0dXJuIHN0cmVhbS5lbWl0KFwiZXJyb3JcIixlcik7dmFyIHdzPXN0cmVhbS5fd3JpdGFibGVTdGF0ZTt2YXIgdHM9c3RyZWFtLl90cmFuc2Zvcm1TdGF0ZTtpZih3cy5sZW5ndGgpdGhyb3cgbmV3IEVycm9yKFwiQ2FsbGluZyB0cmFuc2Zvcm0gZG9uZSB3aGVuIHdzLmxlbmd0aCAhPSAwXCIpO2lmKHRzLnRyYW5zZm9ybWluZyl0aHJvdyBuZXcgRXJyb3IoXCJDYWxsaW5nIHRyYW5zZm9ybSBkb25lIHdoZW4gc3RpbGwgdHJhbnNmb3JtaW5nXCIpO3JldHVybiBzdHJlYW0ucHVzaChudWxsKX19LHtcIi4vX3N0cmVhbV9kdXBsZXhcIjo0NCxcImNvcmUtdXRpbC1pc1wiOjYsaW5oZXJpdHM6Mzh9XSw0ODpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7KGZ1bmN0aW9uKHByb2Nlc3Mpe1widXNlIHN0cmljdFwiO21vZHVsZS5leHBvcnRzPVdyaXRhYmxlO3ZhciBwcm9jZXNzTmV4dFRpY2s9cmVxdWlyZShcInByb2Nlc3MtbmV4dGljay1hcmdzXCIpO3ZhciBhc3luY1dyaXRlPSFwcm9jZXNzLmJyb3dzZXImJltcInYwLjEwXCIsXCJ2MC45LlwiXS5pbmRleE9mKHByb2Nlc3MudmVyc2lvbi5zbGljZSgwLDUpKT4tMT9zZXRJbW1lZGlhdGU6cHJvY2Vzc05leHRUaWNrO1dyaXRhYmxlLldyaXRhYmxlU3RhdGU9V3JpdGFibGVTdGF0ZTt2YXIgdXRpbD1yZXF1aXJlKFwiY29yZS11dGlsLWlzXCIpO3V0aWwuaW5oZXJpdHM9cmVxdWlyZShcImluaGVyaXRzXCIpO3ZhciBpbnRlcm5hbFV0aWw9e2RlcHJlY2F0ZTpyZXF1aXJlKFwidXRpbC1kZXByZWNhdGVcIil9O3ZhciBTdHJlYW07KGZ1bmN0aW9uKCl7dHJ5e1N0cmVhbT1yZXF1aXJlKFwic3RcIitcInJlYW1cIil9Y2F0Y2goXyl7fWZpbmFsbHl7aWYoIVN0cmVhbSlTdHJlYW09cmVxdWlyZShcImV2ZW50c1wiKS5FdmVudEVtaXR0ZXJ9fSkoKTt2YXIgQnVmZmVyPXJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyO3ZhciBidWZmZXJTaGltPXJlcXVpcmUoXCJidWZmZXItc2hpbXNcIik7dXRpbC5pbmhlcml0cyhXcml0YWJsZSxTdHJlYW0pO2Z1bmN0aW9uIG5vcCgpe31mdW5jdGlvbiBXcml0ZVJlcShjaHVuayxlbmNvZGluZyxjYil7dGhpcy5jaHVuaz1jaHVuazt0aGlzLmVuY29kaW5nPWVuY29kaW5nO3RoaXMuY2FsbGJhY2s9Y2I7dGhpcy5uZXh0PW51bGx9dmFyIER1cGxleDtmdW5jdGlvbiBXcml0YWJsZVN0YXRlKG9wdGlvbnMsc3RyZWFtKXtEdXBsZXg9RHVwbGV4fHxyZXF1aXJlKFwiLi9fc3RyZWFtX2R1cGxleFwiKTtvcHRpb25zPW9wdGlvbnN8fHt9O3RoaXMub2JqZWN0TW9kZT0hIW9wdGlvbnMub2JqZWN0TW9kZTtpZihzdHJlYW0gaW5zdGFuY2VvZiBEdXBsZXgpdGhpcy5vYmplY3RNb2RlPXRoaXMub2JqZWN0TW9kZXx8ISFvcHRpb25zLndyaXRhYmxlT2JqZWN0TW9kZTt2YXIgaHdtPW9wdGlvbnMuaGlnaFdhdGVyTWFyazt2YXIgZGVmYXVsdEh3bT10aGlzLm9iamVjdE1vZGU/MTY6MTYqMTAyNDt0aGlzLmhpZ2hXYXRlck1hcms9aHdtfHxod209PT0wP2h3bTpkZWZhdWx0SHdtO3RoaXMuaGlnaFdhdGVyTWFyaz1+fnRoaXMuaGlnaFdhdGVyTWFyazt0aGlzLm5lZWREcmFpbj1mYWxzZTt0aGlzLmVuZGluZz1mYWxzZTt0aGlzLmVuZGVkPWZhbHNlO3RoaXMuZmluaXNoZWQ9ZmFsc2U7dmFyIG5vRGVjb2RlPW9wdGlvbnMuZGVjb2RlU3RyaW5ncz09PWZhbHNlO3RoaXMuZGVjb2RlU3RyaW5ncz0hbm9EZWNvZGU7dGhpcy5kZWZhdWx0RW5jb2Rpbmc9b3B0aW9ucy5kZWZhdWx0RW5jb2Rpbmd8fFwidXRmOFwiO3RoaXMubGVuZ3RoPTA7dGhpcy53cml0aW5nPWZhbHNlO3RoaXMuY29ya2VkPTA7dGhpcy5zeW5jPXRydWU7dGhpcy5idWZmZXJQcm9jZXNzaW5nPWZhbHNlO3RoaXMub253cml0ZT1mdW5jdGlvbihlcil7b253cml0ZShzdHJlYW0sZXIpfTt0aGlzLndyaXRlY2I9bnVsbDt0aGlzLndyaXRlbGVuPTA7dGhpcy5idWZmZXJlZFJlcXVlc3Q9bnVsbDt0aGlzLmxhc3RCdWZmZXJlZFJlcXVlc3Q9bnVsbDt0aGlzLnBlbmRpbmdjYj0wO3RoaXMucHJlZmluaXNoZWQ9ZmFsc2U7dGhpcy5lcnJvckVtaXR0ZWQ9ZmFsc2U7dGhpcy5idWZmZXJlZFJlcXVlc3RDb3VudD0wO3RoaXMuY29ya2VkUmVxdWVzdHNGcmVlPW5ldyBDb3JrZWRSZXF1ZXN0KHRoaXMpfVdyaXRhYmxlU3RhdGUucHJvdG90eXBlLmdldEJ1ZmZlcj1mdW5jdGlvbiB3cml0YWJsZVN0YXRlR2V0QnVmZmVyKCl7dmFyIGN1cnJlbnQ9dGhpcy5idWZmZXJlZFJlcXVlc3Q7dmFyIG91dD1bXTt3aGlsZShjdXJyZW50KXtvdXQucHVzaChjdXJyZW50KTtjdXJyZW50PWN1cnJlbnQubmV4dH1yZXR1cm4gb3V0fTsoZnVuY3Rpb24oKXt0cnl7T2JqZWN0LmRlZmluZVByb3BlcnR5KFdyaXRhYmxlU3RhdGUucHJvdG90eXBlLFwiYnVmZmVyXCIse2dldDppbnRlcm5hbFV0aWwuZGVwcmVjYXRlKGZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZ2V0QnVmZmVyKCl9LFwiX3dyaXRhYmxlU3RhdGUuYnVmZmVyIGlzIGRlcHJlY2F0ZWQuIFVzZSBfd3JpdGFibGVTdGF0ZS5nZXRCdWZmZXIgXCIrXCJpbnN0ZWFkLlwiKX0pfWNhdGNoKF8pe319KSgpO3ZhciBEdXBsZXg7ZnVuY3Rpb24gV3JpdGFibGUob3B0aW9ucyl7RHVwbGV4PUR1cGxleHx8cmVxdWlyZShcIi4vX3N0cmVhbV9kdXBsZXhcIik7aWYoISh0aGlzIGluc3RhbmNlb2YgV3JpdGFibGUpJiYhKHRoaXMgaW5zdGFuY2VvZiBEdXBsZXgpKXJldHVybiBuZXcgV3JpdGFibGUob3B0aW9ucyk7dGhpcy5fd3JpdGFibGVTdGF0ZT1uZXcgV3JpdGFibGVTdGF0ZShvcHRpb25zLHRoaXMpO3RoaXMud3JpdGFibGU9dHJ1ZTtpZihvcHRpb25zKXtpZih0eXBlb2Ygb3B0aW9ucy53cml0ZT09PVwiZnVuY3Rpb25cIil0aGlzLl93cml0ZT1vcHRpb25zLndyaXRlO2lmKHR5cGVvZiBvcHRpb25zLndyaXRldj09PVwiZnVuY3Rpb25cIil0aGlzLl93cml0ZXY9b3B0aW9ucy53cml0ZXZ9U3RyZWFtLmNhbGwodGhpcyl9V3JpdGFibGUucHJvdG90eXBlLnBpcGU9ZnVuY3Rpb24oKXt0aGlzLmVtaXQoXCJlcnJvclwiLG5ldyBFcnJvcihcIkNhbm5vdCBwaXBlLCBub3QgcmVhZGFibGVcIikpfTtmdW5jdGlvbiB3cml0ZUFmdGVyRW5kKHN0cmVhbSxjYil7dmFyIGVyPW5ldyBFcnJvcihcIndyaXRlIGFmdGVyIGVuZFwiKTtzdHJlYW0uZW1pdChcImVycm9yXCIsZXIpO3Byb2Nlc3NOZXh0VGljayhjYixlcil9ZnVuY3Rpb24gdmFsaWRDaHVuayhzdHJlYW0sc3RhdGUsY2h1bmssY2Ipe3ZhciB2YWxpZD10cnVlO3ZhciBlcj1mYWxzZTtpZihjaHVuaz09PW51bGwpe2VyPW5ldyBUeXBlRXJyb3IoXCJNYXkgbm90IHdyaXRlIG51bGwgdmFsdWVzIHRvIHN0cmVhbVwiKX1lbHNlIGlmKCFCdWZmZXIuaXNCdWZmZXIoY2h1bmspJiZ0eXBlb2YgY2h1bmshPT1cInN0cmluZ1wiJiZjaHVuayE9PXVuZGVmaW5lZCYmIXN0YXRlLm9iamVjdE1vZGUpe2VyPW5ldyBUeXBlRXJyb3IoXCJJbnZhbGlkIG5vbi1zdHJpbmcvYnVmZmVyIGNodW5rXCIpfWlmKGVyKXtzdHJlYW0uZW1pdChcImVycm9yXCIsZXIpO3Byb2Nlc3NOZXh0VGljayhjYixlcik7dmFsaWQ9ZmFsc2V9cmV0dXJuIHZhbGlkfVdyaXRhYmxlLnByb3RvdHlwZS53cml0ZT1mdW5jdGlvbihjaHVuayxlbmNvZGluZyxjYil7dmFyIHN0YXRlPXRoaXMuX3dyaXRhYmxlU3RhdGU7dmFyIHJldD1mYWxzZTtpZih0eXBlb2YgZW5jb2Rpbmc9PT1cImZ1bmN0aW9uXCIpe2NiPWVuY29kaW5nO2VuY29kaW5nPW51bGx9aWYoQnVmZmVyLmlzQnVmZmVyKGNodW5rKSllbmNvZGluZz1cImJ1ZmZlclwiO2Vsc2UgaWYoIWVuY29kaW5nKWVuY29kaW5nPXN0YXRlLmRlZmF1bHRFbmNvZGluZztpZih0eXBlb2YgY2IhPT1cImZ1bmN0aW9uXCIpY2I9bm9wO2lmKHN0YXRlLmVuZGVkKXdyaXRlQWZ0ZXJFbmQodGhpcyxjYik7ZWxzZSBpZih2YWxpZENodW5rKHRoaXMsc3RhdGUsY2h1bmssY2IpKXtcbnN0YXRlLnBlbmRpbmdjYisrO3JldD13cml0ZU9yQnVmZmVyKHRoaXMsc3RhdGUsY2h1bmssZW5jb2RpbmcsY2IpfXJldHVybiByZXR9O1dyaXRhYmxlLnByb3RvdHlwZS5jb3JrPWZ1bmN0aW9uKCl7dmFyIHN0YXRlPXRoaXMuX3dyaXRhYmxlU3RhdGU7c3RhdGUuY29ya2VkKyt9O1dyaXRhYmxlLnByb3RvdHlwZS51bmNvcms9ZnVuY3Rpb24oKXt2YXIgc3RhdGU9dGhpcy5fd3JpdGFibGVTdGF0ZTtpZihzdGF0ZS5jb3JrZWQpe3N0YXRlLmNvcmtlZC0tO2lmKCFzdGF0ZS53cml0aW5nJiYhc3RhdGUuY29ya2VkJiYhc3RhdGUuZmluaXNoZWQmJiFzdGF0ZS5idWZmZXJQcm9jZXNzaW5nJiZzdGF0ZS5idWZmZXJlZFJlcXVlc3QpY2xlYXJCdWZmZXIodGhpcyxzdGF0ZSl9fTtXcml0YWJsZS5wcm90b3R5cGUuc2V0RGVmYXVsdEVuY29kaW5nPWZ1bmN0aW9uIHNldERlZmF1bHRFbmNvZGluZyhlbmNvZGluZyl7aWYodHlwZW9mIGVuY29kaW5nPT09XCJzdHJpbmdcIillbmNvZGluZz1lbmNvZGluZy50b0xvd2VyQ2FzZSgpO2lmKCEoW1wiaGV4XCIsXCJ1dGY4XCIsXCJ1dGYtOFwiLFwiYXNjaWlcIixcImJpbmFyeVwiLFwiYmFzZTY0XCIsXCJ1Y3MyXCIsXCJ1Y3MtMlwiLFwidXRmMTZsZVwiLFwidXRmLTE2bGVcIixcInJhd1wiXS5pbmRleE9mKChlbmNvZGluZytcIlwiKS50b0xvd2VyQ2FzZSgpKT4tMSkpdGhyb3cgbmV3IFR5cGVFcnJvcihcIlVua25vd24gZW5jb2Rpbmc6IFwiK2VuY29kaW5nKTt0aGlzLl93cml0YWJsZVN0YXRlLmRlZmF1bHRFbmNvZGluZz1lbmNvZGluZztyZXR1cm4gdGhpc307ZnVuY3Rpb24gZGVjb2RlQ2h1bmsoc3RhdGUsY2h1bmssZW5jb2Rpbmcpe2lmKCFzdGF0ZS5vYmplY3RNb2RlJiZzdGF0ZS5kZWNvZGVTdHJpbmdzIT09ZmFsc2UmJnR5cGVvZiBjaHVuaz09PVwic3RyaW5nXCIpe2NodW5rPWJ1ZmZlclNoaW0uZnJvbShjaHVuayxlbmNvZGluZyl9cmV0dXJuIGNodW5rfWZ1bmN0aW9uIHdyaXRlT3JCdWZmZXIoc3RyZWFtLHN0YXRlLGNodW5rLGVuY29kaW5nLGNiKXtjaHVuaz1kZWNvZGVDaHVuayhzdGF0ZSxjaHVuayxlbmNvZGluZyk7aWYoQnVmZmVyLmlzQnVmZmVyKGNodW5rKSllbmNvZGluZz1cImJ1ZmZlclwiO3ZhciBsZW49c3RhdGUub2JqZWN0TW9kZT8xOmNodW5rLmxlbmd0aDtzdGF0ZS5sZW5ndGgrPWxlbjt2YXIgcmV0PXN0YXRlLmxlbmd0aDxzdGF0ZS5oaWdoV2F0ZXJNYXJrO2lmKCFyZXQpc3RhdGUubmVlZERyYWluPXRydWU7aWYoc3RhdGUud3JpdGluZ3x8c3RhdGUuY29ya2VkKXt2YXIgbGFzdD1zdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0O3N0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3Q9bmV3IFdyaXRlUmVxKGNodW5rLGVuY29kaW5nLGNiKTtpZihsYXN0KXtsYXN0Lm5leHQ9c3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdH1lbHNle3N0YXRlLmJ1ZmZlcmVkUmVxdWVzdD1zdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0fXN0YXRlLmJ1ZmZlcmVkUmVxdWVzdENvdW50Kz0xfWVsc2V7ZG9Xcml0ZShzdHJlYW0sc3RhdGUsZmFsc2UsbGVuLGNodW5rLGVuY29kaW5nLGNiKX1yZXR1cm4gcmV0fWZ1bmN0aW9uIGRvV3JpdGUoc3RyZWFtLHN0YXRlLHdyaXRldixsZW4sY2h1bmssZW5jb2RpbmcsY2Ipe3N0YXRlLndyaXRlbGVuPWxlbjtzdGF0ZS53cml0ZWNiPWNiO3N0YXRlLndyaXRpbmc9dHJ1ZTtzdGF0ZS5zeW5jPXRydWU7aWYod3JpdGV2KXN0cmVhbS5fd3JpdGV2KGNodW5rLHN0YXRlLm9ud3JpdGUpO2Vsc2Ugc3RyZWFtLl93cml0ZShjaHVuayxlbmNvZGluZyxzdGF0ZS5vbndyaXRlKTtzdGF0ZS5zeW5jPWZhbHNlfWZ1bmN0aW9uIG9ud3JpdGVFcnJvcihzdHJlYW0sc3RhdGUsc3luYyxlcixjYil7LS1zdGF0ZS5wZW5kaW5nY2I7aWYoc3luYylwcm9jZXNzTmV4dFRpY2soY2IsZXIpO2Vsc2UgY2IoZXIpO3N0cmVhbS5fd3JpdGFibGVTdGF0ZS5lcnJvckVtaXR0ZWQ9dHJ1ZTtzdHJlYW0uZW1pdChcImVycm9yXCIsZXIpfWZ1bmN0aW9uIG9ud3JpdGVTdGF0ZVVwZGF0ZShzdGF0ZSl7c3RhdGUud3JpdGluZz1mYWxzZTtzdGF0ZS53cml0ZWNiPW51bGw7c3RhdGUubGVuZ3RoLT1zdGF0ZS53cml0ZWxlbjtzdGF0ZS53cml0ZWxlbj0wfWZ1bmN0aW9uIG9ud3JpdGUoc3RyZWFtLGVyKXt2YXIgc3RhdGU9c3RyZWFtLl93cml0YWJsZVN0YXRlO3ZhciBzeW5jPXN0YXRlLnN5bmM7dmFyIGNiPXN0YXRlLndyaXRlY2I7b253cml0ZVN0YXRlVXBkYXRlKHN0YXRlKTtpZihlcilvbndyaXRlRXJyb3Ioc3RyZWFtLHN0YXRlLHN5bmMsZXIsY2IpO2Vsc2V7dmFyIGZpbmlzaGVkPW5lZWRGaW5pc2goc3RhdGUpO2lmKCFmaW5pc2hlZCYmIXN0YXRlLmNvcmtlZCYmIXN0YXRlLmJ1ZmZlclByb2Nlc3NpbmcmJnN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCl7Y2xlYXJCdWZmZXIoc3RyZWFtLHN0YXRlKX1pZihzeW5jKXthc3luY1dyaXRlKGFmdGVyV3JpdGUsc3RyZWFtLHN0YXRlLGZpbmlzaGVkLGNiKX1lbHNle2FmdGVyV3JpdGUoc3RyZWFtLHN0YXRlLGZpbmlzaGVkLGNiKX19fWZ1bmN0aW9uIGFmdGVyV3JpdGUoc3RyZWFtLHN0YXRlLGZpbmlzaGVkLGNiKXtpZighZmluaXNoZWQpb253cml0ZURyYWluKHN0cmVhbSxzdGF0ZSk7c3RhdGUucGVuZGluZ2NiLS07Y2IoKTtmaW5pc2hNYXliZShzdHJlYW0sc3RhdGUpfWZ1bmN0aW9uIG9ud3JpdGVEcmFpbihzdHJlYW0sc3RhdGUpe2lmKHN0YXRlLmxlbmd0aD09PTAmJnN0YXRlLm5lZWREcmFpbil7c3RhdGUubmVlZERyYWluPWZhbHNlO3N0cmVhbS5lbWl0KFwiZHJhaW5cIil9fWZ1bmN0aW9uIGNsZWFyQnVmZmVyKHN0cmVhbSxzdGF0ZSl7c3RhdGUuYnVmZmVyUHJvY2Vzc2luZz10cnVlO3ZhciBlbnRyeT1zdGF0ZS5idWZmZXJlZFJlcXVlc3Q7aWYoc3RyZWFtLl93cml0ZXYmJmVudHJ5JiZlbnRyeS5uZXh0KXt2YXIgbD1zdGF0ZS5idWZmZXJlZFJlcXVlc3RDb3VudDt2YXIgYnVmZmVyPW5ldyBBcnJheShsKTt2YXIgaG9sZGVyPXN0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZTtob2xkZXIuZW50cnk9ZW50cnk7dmFyIGNvdW50PTA7d2hpbGUoZW50cnkpe2J1ZmZlcltjb3VudF09ZW50cnk7ZW50cnk9ZW50cnkubmV4dDtjb3VudCs9MX1kb1dyaXRlKHN0cmVhbSxzdGF0ZSx0cnVlLHN0YXRlLmxlbmd0aCxidWZmZXIsXCJcIixob2xkZXIuZmluaXNoKTtzdGF0ZS5wZW5kaW5nY2IrKztzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0PW51bGw7aWYoaG9sZGVyLm5leHQpe3N0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZT1ob2xkZXIubmV4dDtob2xkZXIubmV4dD1udWxsfWVsc2V7c3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlPW5ldyBDb3JrZWRSZXF1ZXN0KHN0YXRlKX19ZWxzZXt3aGlsZShlbnRyeSl7dmFyIGNodW5rPWVudHJ5LmNodW5rO3ZhciBlbmNvZGluZz1lbnRyeS5lbmNvZGluZzt2YXIgY2I9ZW50cnkuY2FsbGJhY2s7dmFyIGxlbj1zdGF0ZS5vYmplY3RNb2RlPzE6Y2h1bmsubGVuZ3RoO2RvV3JpdGUoc3RyZWFtLHN0YXRlLGZhbHNlLGxlbixjaHVuayxlbmNvZGluZyxjYik7ZW50cnk9ZW50cnkubmV4dDtpZihzdGF0ZS53cml0aW5nKXticmVha319aWYoZW50cnk9PT1udWxsKXN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3Q9bnVsbH1zdGF0ZS5idWZmZXJlZFJlcXVlc3RDb3VudD0wO3N0YXRlLmJ1ZmZlcmVkUmVxdWVzdD1lbnRyeTtzdGF0ZS5idWZmZXJQcm9jZXNzaW5nPWZhbHNlfVdyaXRhYmxlLnByb3RvdHlwZS5fd3JpdGU9ZnVuY3Rpb24oY2h1bmssZW5jb2RpbmcsY2Ipe2NiKG5ldyBFcnJvcihcIm5vdCBpbXBsZW1lbnRlZFwiKSl9O1dyaXRhYmxlLnByb3RvdHlwZS5fd3JpdGV2PW51bGw7V3JpdGFibGUucHJvdG90eXBlLmVuZD1mdW5jdGlvbihjaHVuayxlbmNvZGluZyxjYil7dmFyIHN0YXRlPXRoaXMuX3dyaXRhYmxlU3RhdGU7aWYodHlwZW9mIGNodW5rPT09XCJmdW5jdGlvblwiKXtjYj1jaHVuaztjaHVuaz1udWxsO2VuY29kaW5nPW51bGx9ZWxzZSBpZih0eXBlb2YgZW5jb2Rpbmc9PT1cImZ1bmN0aW9uXCIpe2NiPWVuY29kaW5nO2VuY29kaW5nPW51bGx9aWYoY2h1bmshPT1udWxsJiZjaHVuayE9PXVuZGVmaW5lZCl0aGlzLndyaXRlKGNodW5rLGVuY29kaW5nKTtpZihzdGF0ZS5jb3JrZWQpe3N0YXRlLmNvcmtlZD0xO3RoaXMudW5jb3JrKCl9aWYoIXN0YXRlLmVuZGluZyYmIXN0YXRlLmZpbmlzaGVkKWVuZFdyaXRhYmxlKHRoaXMsc3RhdGUsY2IpfTtmdW5jdGlvbiBuZWVkRmluaXNoKHN0YXRlKXtyZXR1cm4gc3RhdGUuZW5kaW5nJiZzdGF0ZS5sZW5ndGg9PT0wJiZzdGF0ZS5idWZmZXJlZFJlcXVlc3Q9PT1udWxsJiYhc3RhdGUuZmluaXNoZWQmJiFzdGF0ZS53cml0aW5nfWZ1bmN0aW9uIHByZWZpbmlzaChzdHJlYW0sc3RhdGUpe2lmKCFzdGF0ZS5wcmVmaW5pc2hlZCl7c3RhdGUucHJlZmluaXNoZWQ9dHJ1ZTtzdHJlYW0uZW1pdChcInByZWZpbmlzaFwiKX19ZnVuY3Rpb24gZmluaXNoTWF5YmUoc3RyZWFtLHN0YXRlKXt2YXIgbmVlZD1uZWVkRmluaXNoKHN0YXRlKTtpZihuZWVkKXtpZihzdGF0ZS5wZW5kaW5nY2I9PT0wKXtwcmVmaW5pc2goc3RyZWFtLHN0YXRlKTtzdGF0ZS5maW5pc2hlZD10cnVlO3N0cmVhbS5lbWl0KFwiZmluaXNoXCIpfWVsc2V7cHJlZmluaXNoKHN0cmVhbSxzdGF0ZSl9fXJldHVybiBuZWVkfWZ1bmN0aW9uIGVuZFdyaXRhYmxlKHN0cmVhbSxzdGF0ZSxjYil7c3RhdGUuZW5kaW5nPXRydWU7ZmluaXNoTWF5YmUoc3RyZWFtLHN0YXRlKTtpZihjYil7aWYoc3RhdGUuZmluaXNoZWQpcHJvY2Vzc05leHRUaWNrKGNiKTtlbHNlIHN0cmVhbS5vbmNlKFwiZmluaXNoXCIsY2IpfXN0YXRlLmVuZGVkPXRydWU7c3RyZWFtLndyaXRhYmxlPWZhbHNlfWZ1bmN0aW9uIENvcmtlZFJlcXVlc3Qoc3RhdGUpe3ZhciBfdGhpcz10aGlzO3RoaXMubmV4dD1udWxsO3RoaXMuZW50cnk9bnVsbDt0aGlzLmZpbmlzaD1mdW5jdGlvbihlcnIpe3ZhciBlbnRyeT1fdGhpcy5lbnRyeTtfdGhpcy5lbnRyeT1udWxsO3doaWxlKGVudHJ5KXt2YXIgY2I9ZW50cnkuY2FsbGJhY2s7c3RhdGUucGVuZGluZ2NiLS07Y2IoZXJyKTtlbnRyeT1lbnRyeS5uZXh0fWlmKHN0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZSl7c3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlLm5leHQ9X3RoaXN9ZWxzZXtzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWU9X3RoaXN9fX19KS5jYWxsKHRoaXMscmVxdWlyZShcIl9wcm9jZXNzXCIpKX0se1wiLi9fc3RyZWFtX2R1cGxleFwiOjQ0LF9wcm9jZXNzOjQyLGJ1ZmZlcjo1LFwiYnVmZmVyLXNoaW1zXCI6NCxcImNvcmUtdXRpbC1pc1wiOjYsZXZlbnRzOjI4LGluaGVyaXRzOjM4LFwicHJvY2Vzcy1uZXh0aWNrLWFyZ3NcIjo0MSxcInV0aWwtZGVwcmVjYXRlXCI6NTd9XSw0OTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XCJ1c2Ugc3RyaWN0XCI7dmFyIEJ1ZmZlcj1yZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcjt2YXIgYnVmZmVyU2hpbT1yZXF1aXJlKFwiYnVmZmVyLXNoaW1zXCIpO21vZHVsZS5leHBvcnRzPUJ1ZmZlckxpc3Q7ZnVuY3Rpb24gQnVmZmVyTGlzdCgpe3RoaXMuaGVhZD1udWxsO3RoaXMudGFpbD1udWxsO3RoaXMubGVuZ3RoPTB9QnVmZmVyTGlzdC5wcm90b3R5cGUucHVzaD1mdW5jdGlvbih2KXt2YXIgZW50cnk9e2RhdGE6dixuZXh0Om51bGx9O2lmKHRoaXMubGVuZ3RoPjApdGhpcy50YWlsLm5leHQ9ZW50cnk7ZWxzZSB0aGlzLmhlYWQ9ZW50cnk7dGhpcy50YWlsPWVudHJ5OysrdGhpcy5sZW5ndGh9O0J1ZmZlckxpc3QucHJvdG90eXBlLnVuc2hpZnQ9ZnVuY3Rpb24odil7dmFyIGVudHJ5PXtkYXRhOnYsbmV4dDp0aGlzLmhlYWR9O2lmKHRoaXMubGVuZ3RoPT09MCl0aGlzLnRhaWw9ZW50cnk7dGhpcy5oZWFkPWVudHJ5OysrdGhpcy5sZW5ndGh9O0J1ZmZlckxpc3QucHJvdG90eXBlLnNoaWZ0PWZ1bmN0aW9uKCl7aWYodGhpcy5sZW5ndGg9PT0wKXJldHVybjt2YXIgcmV0PXRoaXMuaGVhZC5kYXRhO2lmKHRoaXMubGVuZ3RoPT09MSl0aGlzLmhlYWQ9dGhpcy50YWlsPW51bGw7ZWxzZSB0aGlzLmhlYWQ9dGhpcy5oZWFkLm5leHQ7LS10aGlzLmxlbmd0aDtyZXR1cm4gcmV0fTtCdWZmZXJMaXN0LnByb3RvdHlwZS5jbGVhcj1mdW5jdGlvbigpe3RoaXMuaGVhZD10aGlzLnRhaWw9bnVsbDt0aGlzLmxlbmd0aD0wfTtCdWZmZXJMaXN0LnByb3RvdHlwZS5qb2luPWZ1bmN0aW9uKHMpe2lmKHRoaXMubGVuZ3RoPT09MClyZXR1cm5cIlwiO3ZhciBwPXRoaXMuaGVhZDt2YXIgcmV0PVwiXCIrcC5kYXRhO3doaWxlKHA9cC5uZXh0KXtyZXQrPXMrcC5kYXRhfXJldHVybiByZXR9O0J1ZmZlckxpc3QucHJvdG90eXBlLmNvbmNhdD1mdW5jdGlvbihuKXtpZih0aGlzLmxlbmd0aD09PTApcmV0dXJuIGJ1ZmZlclNoaW0uYWxsb2MoMCk7aWYodGhpcy5sZW5ndGg9PT0xKXJldHVybiB0aGlzLmhlYWQuZGF0YTt2YXIgcmV0PWJ1ZmZlclNoaW0uYWxsb2NVbnNhZmUobj4+PjApO3ZhciBwPXRoaXMuaGVhZDt2YXIgaT0wO3doaWxlKHApe3AuZGF0YS5jb3B5KHJldCxpKTtpKz1wLmRhdGEubGVuZ3RoO3A9cC5uZXh0fXJldHVybiByZXR9fSx7YnVmZmVyOjUsXCJidWZmZXItc2hpbXNcIjo0fV0sNTA6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe21vZHVsZS5leHBvcnRzPXJlcXVpcmUoXCIuL2xpYi9fc3RyZWFtX3Bhc3N0aHJvdWdoLmpzXCIpfSx7XCIuL2xpYi9fc3RyZWFtX3Bhc3N0aHJvdWdoLmpzXCI6NDV9XSw1MTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7KGZ1bmN0aW9uKHByb2Nlc3Mpe3ZhciBTdHJlYW09ZnVuY3Rpb24oKXt0cnl7cmV0dXJuIHJlcXVpcmUoXCJzdFwiK1wicmVhbVwiKX1jYXRjaChfKXt9fSgpO2V4cG9ydHM9bW9kdWxlLmV4cG9ydHM9cmVxdWlyZShcIi4vbGliL19zdHJlYW1fcmVhZGFibGUuanNcIik7ZXhwb3J0cy5TdHJlYW09U3RyZWFtfHxleHBvcnRzO2V4cG9ydHMuUmVhZGFibGU9ZXhwb3J0cztleHBvcnRzLldyaXRhYmxlPXJlcXVpcmUoXCIuL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzXCIpO2V4cG9ydHMuRHVwbGV4PXJlcXVpcmUoXCIuL2xpYi9fc3RyZWFtX2R1cGxleC5qc1wiKTtleHBvcnRzLlRyYW5zZm9ybT1yZXF1aXJlKFwiLi9saWIvX3N0cmVhbV90cmFuc2Zvcm0uanNcIik7ZXhwb3J0cy5QYXNzVGhyb3VnaD1yZXF1aXJlKFwiLi9saWIvX3N0cmVhbV9wYXNzdGhyb3VnaC5qc1wiKTtpZighcHJvY2Vzcy5icm93c2VyJiZwcm9jZXNzLmVudi5SRUFEQUJMRV9TVFJFQU09PT1cImRpc2FibGVcIiYmU3RyZWFtKXttb2R1bGUuZXhwb3J0cz1TdHJlYW19fSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJfcHJvY2Vzc1wiKSl9LHtcIi4vbGliL19zdHJlYW1fZHVwbGV4LmpzXCI6NDQsXCIuL2xpYi9fc3RyZWFtX3Bhc3N0aHJvdWdoLmpzXCI6NDUsXCIuL2xpYi9fc3RyZWFtX3JlYWRhYmxlLmpzXCI6NDYsXCIuL2xpYi9fc3RyZWFtX3RyYW5zZm9ybS5qc1wiOjQ3LFwiLi9saWIvX3N0cmVhbV93cml0YWJsZS5qc1wiOjQ4LF9wcm9jZXNzOjQyfV0sNTI6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe21vZHVsZS5leHBvcnRzPXJlcXVpcmUoXCIuL2xpYi9fc3RyZWFtX3RyYW5zZm9ybS5qc1wiKX0se1wiLi9saWIvX3N0cmVhbV90cmFuc2Zvcm0uanNcIjo0N31dLDUzOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXttb2R1bGUuZXhwb3J0cz1yZXF1aXJlKFwiLi9saWIvX3N0cmVhbV93cml0YWJsZS5qc1wiKX0se1wiLi9saWIvX3N0cmVhbV93cml0YWJsZS5qc1wiOjQ4fV0sNTQ6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe21vZHVsZS5leHBvcnRzPWZ1bmN0aW9uKHN0cmluZyl7cmV0dXJuIHN0cmluZy5yZXBsYWNlKC9bLVxcXFxeJCorPy4oKXxbXFxde31dL2csXCJcXFxcJCZcIil9fSx7fV0sNTU6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe21vZHVsZS5leHBvcnRzPVN0cmVhbTt2YXIgRUU9cmVxdWlyZShcImV2ZW50c1wiKS5FdmVudEVtaXR0ZXI7dmFyIGluaGVyaXRzPXJlcXVpcmUoXCJpbmhlcml0c1wiKTtpbmhlcml0cyhTdHJlYW0sRUUpO1N0cmVhbS5SZWFkYWJsZT1yZXF1aXJlKFwicmVhZGFibGUtc3RyZWFtL3JlYWRhYmxlLmpzXCIpO1N0cmVhbS5Xcml0YWJsZT1yZXF1aXJlKFwicmVhZGFibGUtc3RyZWFtL3dyaXRhYmxlLmpzXCIpO1N0cmVhbS5EdXBsZXg9cmVxdWlyZShcInJlYWRhYmxlLXN0cmVhbS9kdXBsZXguanNcIik7U3RyZWFtLlRyYW5zZm9ybT1yZXF1aXJlKFwicmVhZGFibGUtc3RyZWFtL3RyYW5zZm9ybS5qc1wiKTtTdHJlYW0uUGFzc1Rocm91Z2g9cmVxdWlyZShcInJlYWRhYmxlLXN0cmVhbS9wYXNzdGhyb3VnaC5qc1wiKTtTdHJlYW0uU3RyZWFtPVN0cmVhbTtmdW5jdGlvbiBTdHJlYW0oKXtFRS5jYWxsKHRoaXMpfVN0cmVhbS5wcm90b3R5cGUucGlwZT1mdW5jdGlvbihkZXN0LG9wdGlvbnMpe3ZhciBzb3VyY2U9dGhpcztmdW5jdGlvbiBvbmRhdGEoY2h1bmspe2lmKGRlc3Qud3JpdGFibGUpe2lmKGZhbHNlPT09ZGVzdC53cml0ZShjaHVuaykmJnNvdXJjZS5wYXVzZSl7c291cmNlLnBhdXNlKCl9fX1zb3VyY2Uub24oXCJkYXRhXCIsb25kYXRhKTtmdW5jdGlvbiBvbmRyYWluKCl7aWYoc291cmNlLnJlYWRhYmxlJiZzb3VyY2UucmVzdW1lKXtzb3VyY2UucmVzdW1lKCl9fWRlc3Qub24oXCJkcmFpblwiLG9uZHJhaW4pO2lmKCFkZXN0Ll9pc1N0ZGlvJiYoIW9wdGlvbnN8fG9wdGlvbnMuZW5kIT09ZmFsc2UpKXtzb3VyY2Uub24oXCJlbmRcIixvbmVuZCk7c291cmNlLm9uKFwiY2xvc2VcIixvbmNsb3NlKX12YXIgZGlkT25FbmQ9ZmFsc2U7ZnVuY3Rpb24gb25lbmQoKXtpZihkaWRPbkVuZClyZXR1cm47ZGlkT25FbmQ9dHJ1ZTtkZXN0LmVuZCgpfWZ1bmN0aW9uIG9uY2xvc2UoKXtpZihkaWRPbkVuZClyZXR1cm47ZGlkT25FbmQ9dHJ1ZTtpZih0eXBlb2YgZGVzdC5kZXN0cm95PT09XCJmdW5jdGlvblwiKWRlc3QuZGVzdHJveSgpfWZ1bmN0aW9uIG9uZXJyb3IoZXIpe2NsZWFudXAoKTtpZihFRS5saXN0ZW5lckNvdW50KHRoaXMsXCJlcnJvclwiKT09PTApe3Rocm93IGVyfX1zb3VyY2Uub24oXCJlcnJvclwiLG9uZXJyb3IpO2Rlc3Qub24oXCJlcnJvclwiLG9uZXJyb3IpO2Z1bmN0aW9uIGNsZWFudXAoKXtzb3VyY2UucmVtb3ZlTGlzdGVuZXIoXCJkYXRhXCIsb25kYXRhKTtkZXN0LnJlbW92ZUxpc3RlbmVyKFwiZHJhaW5cIixvbmRyYWluKTtzb3VyY2UucmVtb3ZlTGlzdGVuZXIoXCJlbmRcIixvbmVuZCk7c291cmNlLnJlbW92ZUxpc3RlbmVyKFwiY2xvc2VcIixvbmNsb3NlKTtzb3VyY2UucmVtb3ZlTGlzdGVuZXIoXCJlcnJvclwiLG9uZXJyb3IpO2Rlc3QucmVtb3ZlTGlzdGVuZXIoXCJlcnJvclwiLG9uZXJyb3IpO3NvdXJjZS5yZW1vdmVMaXN0ZW5lcihcImVuZFwiLGNsZWFudXApO3NvdXJjZS5yZW1vdmVMaXN0ZW5lcihcImNsb3NlXCIsY2xlYW51cCk7ZGVzdC5yZW1vdmVMaXN0ZW5lcihcImNsb3NlXCIsY2xlYW51cCl9c291cmNlLm9uKFwiZW5kXCIsY2xlYW51cCk7c291cmNlLm9uKFwiY2xvc2VcIixjbGVhbnVwKTtkZXN0Lm9uKFwiY2xvc2VcIixjbGVhbnVwKTtkZXN0LmVtaXQoXCJwaXBlXCIsc291cmNlKTtyZXR1cm4gZGVzdH19LHtldmVudHM6MjgsaW5oZXJpdHM6MzgsXCJyZWFkYWJsZS1zdHJlYW0vZHVwbGV4LmpzXCI6NDMsXCJyZWFkYWJsZS1zdHJlYW0vcGFzc3Rocm91Z2guanNcIjo1MCxcInJlYWRhYmxlLXN0cmVhbS9yZWFkYWJsZS5qc1wiOjUxLFwicmVhZGFibGUtc3RyZWFtL3RyYW5zZm9ybS5qc1wiOjUyLFwicmVhZGFibGUtc3RyZWFtL3dyaXRhYmxlLmpzXCI6NTN9XSw1NjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIEJ1ZmZlcj1yZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcjt2YXIgaXNCdWZmZXJFbmNvZGluZz1CdWZmZXIuaXNFbmNvZGluZ3x8ZnVuY3Rpb24oZW5jb2Rpbmcpe3N3aXRjaChlbmNvZGluZyYmZW5jb2RpbmcudG9Mb3dlckNhc2UoKSl7Y2FzZVwiaGV4XCI6Y2FzZVwidXRmOFwiOmNhc2VcInV0Zi04XCI6Y2FzZVwiYXNjaWlcIjpjYXNlXCJiaW5hcnlcIjpjYXNlXCJiYXNlNjRcIjpjYXNlXCJ1Y3MyXCI6Y2FzZVwidWNzLTJcIjpjYXNlXCJ1dGYxNmxlXCI6Y2FzZVwidXRmLTE2bGVcIjpjYXNlXCJyYXdcIjpyZXR1cm4gdHJ1ZTtkZWZhdWx0OnJldHVybiBmYWxzZX19O2Z1bmN0aW9uIGFzc2VydEVuY29kaW5nKGVuY29kaW5nKXtpZihlbmNvZGluZyYmIWlzQnVmZmVyRW5jb2RpbmcoZW5jb2RpbmcpKXt0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIGVuY29kaW5nOiBcIitlbmNvZGluZyl9fXZhciBTdHJpbmdEZWNvZGVyPWV4cG9ydHMuU3RyaW5nRGVjb2Rlcj1mdW5jdGlvbihlbmNvZGluZyl7dGhpcy5lbmNvZGluZz0oZW5jb2Rpbmd8fFwidXRmOFwiKS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoL1stX10vLFwiXCIpO2Fzc2VydEVuY29kaW5nKGVuY29kaW5nKTtzd2l0Y2godGhpcy5lbmNvZGluZyl7Y2FzZVwidXRmOFwiOnRoaXMuc3Vycm9nYXRlU2l6ZT0zO2JyZWFrO2Nhc2VcInVjczJcIjpjYXNlXCJ1dGYxNmxlXCI6dGhpcy5zdXJyb2dhdGVTaXplPTI7dGhpcy5kZXRlY3RJbmNvbXBsZXRlQ2hhcj11dGYxNkRldGVjdEluY29tcGxldGVDaGFyO2JyZWFrO2Nhc2VcImJhc2U2NFwiOnRoaXMuc3Vycm9nYXRlU2l6ZT0zO3RoaXMuZGV0ZWN0SW5jb21wbGV0ZUNoYXI9YmFzZTY0RGV0ZWN0SW5jb21wbGV0ZUNoYXI7YnJlYWs7ZGVmYXVsdDp0aGlzLndyaXRlPXBhc3NUaHJvdWdoV3JpdGU7cmV0dXJufXRoaXMuY2hhckJ1ZmZlcj1uZXcgQnVmZmVyKDYpO3RoaXMuY2hhclJlY2VpdmVkPTA7dGhpcy5jaGFyTGVuZ3RoPTB9O1N0cmluZ0RlY29kZXIucHJvdG90eXBlLndyaXRlPWZ1bmN0aW9uKGJ1ZmZlcil7dmFyIGNoYXJTdHI9XCJcIjt3aGlsZSh0aGlzLmNoYXJMZW5ndGgpe3ZhciBhdmFpbGFibGU9YnVmZmVyLmxlbmd0aD49dGhpcy5jaGFyTGVuZ3RoLXRoaXMuY2hhclJlY2VpdmVkP3RoaXMuY2hhckxlbmd0aC10aGlzLmNoYXJSZWNlaXZlZDpidWZmZXIubGVuZ3RoO2J1ZmZlci5jb3B5KHRoaXMuY2hhckJ1ZmZlcix0aGlzLmNoYXJSZWNlaXZlZCwwLGF2YWlsYWJsZSk7dGhpcy5jaGFyUmVjZWl2ZWQrPWF2YWlsYWJsZTtpZih0aGlzLmNoYXJSZWNlaXZlZDx0aGlzLmNoYXJMZW5ndGgpe3JldHVyblwiXCJ9YnVmZmVyPWJ1ZmZlci5zbGljZShhdmFpbGFibGUsYnVmZmVyLmxlbmd0aCk7Y2hhclN0cj10aGlzLmNoYXJCdWZmZXIuc2xpY2UoMCx0aGlzLmNoYXJMZW5ndGgpLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcpO3ZhciBjaGFyQ29kZT1jaGFyU3RyLmNoYXJDb2RlQXQoY2hhclN0ci5sZW5ndGgtMSk7aWYoY2hhckNvZGU+PTU1Mjk2JiZjaGFyQ29kZTw9NTYzMTkpe3RoaXMuY2hhckxlbmd0aCs9dGhpcy5zdXJyb2dhdGVTaXplO2NoYXJTdHI9XCJcIjtjb250aW51ZX10aGlzLmNoYXJSZWNlaXZlZD10aGlzLmNoYXJMZW5ndGg9MDtpZihidWZmZXIubGVuZ3RoPT09MCl7cmV0dXJuIGNoYXJTdHJ9YnJlYWt9dGhpcy5kZXRlY3RJbmNvbXBsZXRlQ2hhcihidWZmZXIpO3ZhciBlbmQ9YnVmZmVyLmxlbmd0aDtpZih0aGlzLmNoYXJMZW5ndGgpe2J1ZmZlci5jb3B5KHRoaXMuY2hhckJ1ZmZlciwwLGJ1ZmZlci5sZW5ndGgtdGhpcy5jaGFyUmVjZWl2ZWQsZW5kKTtlbmQtPXRoaXMuY2hhclJlY2VpdmVkfWNoYXJTdHIrPWJ1ZmZlci50b1N0cmluZyh0aGlzLmVuY29kaW5nLDAsZW5kKTt2YXIgZW5kPWNoYXJTdHIubGVuZ3RoLTE7dmFyIGNoYXJDb2RlPWNoYXJTdHIuY2hhckNvZGVBdChlbmQpO2lmKGNoYXJDb2RlPj01NTI5NiYmY2hhckNvZGU8PTU2MzE5KXt2YXIgc2l6ZT10aGlzLnN1cnJvZ2F0ZVNpemU7dGhpcy5jaGFyTGVuZ3RoKz1zaXplO3RoaXMuY2hhclJlY2VpdmVkKz1zaXplO3RoaXMuY2hhckJ1ZmZlci5jb3B5KHRoaXMuY2hhckJ1ZmZlcixzaXplLDAsc2l6ZSk7YnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLDAsMCxzaXplKTtyZXR1cm4gY2hhclN0ci5zdWJzdHJpbmcoMCxlbmQpfXJldHVybiBjaGFyU3RyfTtTdHJpbmdEZWNvZGVyLnByb3RvdHlwZS5kZXRlY3RJbmNvbXBsZXRlQ2hhcj1mdW5jdGlvbihidWZmZXIpe3ZhciBpPWJ1ZmZlci5sZW5ndGg+PTM/MzpidWZmZXIubGVuZ3RoO2Zvcig7aT4wO2ktLSl7dmFyIGM9YnVmZmVyW2J1ZmZlci5sZW5ndGgtaV07aWYoaT09MSYmYz4+NT09Nil7dGhpcy5jaGFyTGVuZ3RoPTI7YnJlYWt9aWYoaTw9MiYmYz4+ND09MTQpe3RoaXMuY2hhckxlbmd0aD0zO2JyZWFrfWlmKGk8PTMmJmM+PjM9PTMwKXt0aGlzLmNoYXJMZW5ndGg9NDticmVha319dGhpcy5jaGFyUmVjZWl2ZWQ9aX07U3RyaW5nRGVjb2Rlci5wcm90b3R5cGUuZW5kPWZ1bmN0aW9uKGJ1ZmZlcil7dmFyIHJlcz1cIlwiO2lmKGJ1ZmZlciYmYnVmZmVyLmxlbmd0aClyZXM9dGhpcy53cml0ZShidWZmZXIpO2lmKHRoaXMuY2hhclJlY2VpdmVkKXt2YXIgY3I9dGhpcy5jaGFyUmVjZWl2ZWQ7dmFyIGJ1Zj10aGlzLmNoYXJCdWZmZXI7dmFyIGVuYz10aGlzLmVuY29kaW5nO3Jlcys9YnVmLnNsaWNlKDAsY3IpLnRvU3RyaW5nKGVuYyl9cmV0dXJuIHJlc307ZnVuY3Rpb24gcGFzc1Rocm91Z2hXcml0ZShidWZmZXIpe3JldHVybiBidWZmZXIudG9TdHJpbmcodGhpcy5lbmNvZGluZyl9ZnVuY3Rpb24gdXRmMTZEZXRlY3RJbmNvbXBsZXRlQ2hhcihidWZmZXIpe3RoaXMuY2hhclJlY2VpdmVkPWJ1ZmZlci5sZW5ndGglMjt0aGlzLmNoYXJMZW5ndGg9dGhpcy5jaGFyUmVjZWl2ZWQ/MjowfWZ1bmN0aW9uIGJhc2U2NERldGVjdEluY29tcGxldGVDaGFyKGJ1ZmZlcil7dGhpcy5jaGFyUmVjZWl2ZWQ9YnVmZmVyLmxlbmd0aCUzO3RoaXMuY2hhckxlbmd0aD10aGlzLmNoYXJSZWNlaXZlZD8zOjB9fSx7YnVmZmVyOjV9XSw1NzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7KGZ1bmN0aW9uKGdsb2JhbCl7bW9kdWxlLmV4cG9ydHM9ZGVwcmVjYXRlO2Z1bmN0aW9uIGRlcHJlY2F0ZShmbixtc2cpe2lmKGNvbmZpZyhcIm5vRGVwcmVjYXRpb25cIikpe3JldHVybiBmbn12YXIgd2FybmVkPWZhbHNlO2Z1bmN0aW9uIGRlcHJlY2F0ZWQoKXtpZighd2FybmVkKXtpZihjb25maWcoXCJ0aHJvd0RlcHJlY2F0aW9uXCIpKXt0aHJvdyBuZXcgRXJyb3IobXNnKX1lbHNlIGlmKGNvbmZpZyhcInRyYWNlRGVwcmVjYXRpb25cIikpe2NvbnNvbGUudHJhY2UobXNnKX1lbHNle2NvbnNvbGUud2Fybihtc2cpfXdhcm5lZD10cnVlfXJldHVybiBmbi5hcHBseSh0aGlzLGFyZ3VtZW50cyl9cmV0dXJuIGRlcHJlY2F0ZWR9ZnVuY3Rpb24gY29uZmlnKG5hbWUpe3RyeXtpZighZ2xvYmFsLmxvY2FsU3RvcmFnZSlyZXR1cm4gZmFsc2V9Y2F0Y2goXyl7cmV0dXJuIGZhbHNlfXZhciB2YWw9Z2xvYmFsLmxvY2FsU3RvcmFnZVtuYW1lXTtpZihudWxsPT12YWwpcmV0dXJuIGZhbHNlO3JldHVybiBTdHJpbmcodmFsKS50b0xvd2VyQ2FzZSgpPT09XCJ0cnVlXCJ9fSkuY2FsbCh0aGlzLHR5cGVvZiBnbG9iYWwhPT1cInVuZGVmaW5lZFwiP2dsb2JhbDp0eXBlb2Ygc2VsZiE9PVwidW5kZWZpbmVkXCI/c2VsZjp0eXBlb2Ygd2luZG93IT09XCJ1bmRlZmluZWRcIj93aW5kb3c6e30pfSx7fV0sNTg6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe21vZHVsZS5leHBvcnRzPWV4dGVuZDt2YXIgaGFzT3duUHJvcGVydHk9T2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtmdW5jdGlvbiBleHRlbmQoKXt2YXIgdGFyZ2V0PXt9O2Zvcih2YXIgaT0wO2k8YXJndW1lbnRzLmxlbmd0aDtpKyspe3ZhciBzb3VyY2U9YXJndW1lbnRzW2ldO2Zvcih2YXIga2V5IGluIHNvdXJjZSl7aWYoaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2Usa2V5KSl7dGFyZ2V0W2tleV09c291cmNlW2tleV19fX1yZXR1cm4gdGFyZ2V0fX0se31dfSx7fSxbMV0pKDEpfSk7XG4iLCIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIid1c2Ugc3RyaWN0JztcblxudmFyIGF1dGggPSByZXF1aXJlKCcuL2xpYi9hdXRoJyk7XG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4vbGliL2hlbHBlcnMnKTtcbnZhciBTd2FnZ2VyQ2xpZW50ID0gcmVxdWlyZSgnLi9saWIvY2xpZW50Jyk7XG52YXIgZGVwcmVjYXRpb25XcmFwcGVyID0gZnVuY3Rpb24gKHVybCwgb3B0aW9ucykge1xuICBoZWxwZXJzLmxvZygnVGhpcyBpcyBkZXByZWNhdGVkLCB1c2UgXCJuZXcgU3dhZ2dlckNsaWVudFwiIGluc3RlYWQuJyk7XG5cbiAgcmV0dXJuIG5ldyBTd2FnZ2VyQ2xpZW50KHVybCwgb3B0aW9ucyk7XG59O1xuXG4vKiBIZXJlIGZvciBJRTggU3VwcG9ydCAqL1xuaWYgKCFBcnJheS5wcm90b3R5cGUuaW5kZXhPZikge1xuICBBcnJheS5wcm90b3R5cGUuaW5kZXhPZiA9IGZ1bmN0aW9uKG9iaiwgc3RhcnQpIHtcbiAgICBmb3IgKHZhciBpID0gKHN0YXJ0IHx8IDApLCBqID0gdGhpcy5sZW5ndGg7IGkgPCBqOyBpKyspIHtcbiAgICAgIGlmICh0aGlzW2ldID09PSBvYmopIHsgcmV0dXJuIGk7IH1cbiAgICB9XG4gICAgcmV0dXJuIC0xO1xuICB9O1xufVxuXG4vKiBIZXJlIGZvciBJRTggU3VwcG9ydCAqL1xuaWYgKCFTdHJpbmcucHJvdG90eXBlLnRyaW0pIHtcbiAgU3RyaW5nLnByb3RvdHlwZS50cmltID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnJlcGxhY2UoL15cXHMrfFxccyskL2csICcnKTtcbiAgfTtcbn1cblxuLyogSGVyZSBmb3Igbm9kZSAxMC54IHN1cHBvcnQgKi9cbmlmICghU3RyaW5nLnByb3RvdHlwZS5lbmRzV2l0aCkge1xuICBTdHJpbmcucHJvdG90eXBlLmVuZHNXaXRoID0gZnVuY3Rpb24oc3VmZml4KSB7XG4gICAgcmV0dXJuIHRoaXMuaW5kZXhPZihzdWZmaXgsIHRoaXMubGVuZ3RoIC0gc3VmZml4Lmxlbmd0aCkgIT09IC0xO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFN3YWdnZXJDbGllbnQ7XG5cblN3YWdnZXJDbGllbnQuQXBpS2V5QXV0aG9yaXphdGlvbiA9IGF1dGguQXBpS2V5QXV0aG9yaXphdGlvbjtcblN3YWdnZXJDbGllbnQuUGFzc3dvcmRBdXRob3JpemF0aW9uID0gYXV0aC5QYXNzd29yZEF1dGhvcml6YXRpb247XG5Td2FnZ2VyQ2xpZW50LkNvb2tpZUF1dGhvcml6YXRpb24gPSBhdXRoLkNvb2tpZUF1dGhvcml6YXRpb247XG5Td2FnZ2VyQ2xpZW50LlN3YWdnZXJBcGkgPSBkZXByZWNhdGlvbldyYXBwZXI7XG5Td2FnZ2VyQ2xpZW50LlN3YWdnZXJDbGllbnQgPSBkZXByZWNhdGlvbldyYXBwZXI7XG5Td2FnZ2VyQ2xpZW50LlNjaGVtYU1hcmt1cCA9IHJlcXVpcmUoJy4vbGliL3NjaGVtYS1tYXJrdXAnKTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGhlbHBlcnMgPSByZXF1aXJlKCcuL2hlbHBlcnMnKTtcbnZhciBidG9hID0gcmVxdWlyZSgnYnRvYScpOyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbnZhciBDb29raWVKYXIgPSByZXF1aXJlKCdjb29raWVqYXInKS5Db29raWVKYXI7XG52YXIgXyA9IHtcbiAgZWFjaDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2VhY2gnKSxcbiAgaW5jbHVkZXM6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9pbmNsdWRlcycpLFxuICBpc09iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzT2JqZWN0JyksXG4gIGlzQXJyYXk6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc0FycmF5Jylcbn07XG5cbi8qKlxuICogU3dhZ2dlckF1dGhvcml6YXRpb25zIGFwcGxpZXMgdGhlIGNvcnJlY3QgYXV0aG9yaXphdGlvbiB0byBhbiBvcGVyYXRpb24gYmVpbmcgZXhlY3V0ZWRcbiAqL1xudmFyIFN3YWdnZXJBdXRob3JpemF0aW9ucyA9IG1vZHVsZS5leHBvcnRzLlN3YWdnZXJBdXRob3JpemF0aW9ucyA9IGZ1bmN0aW9uIChhdXRoeikge1xuICB0aGlzLmF1dGh6ID0gYXV0aHogfHwge307XG59O1xuXG4vKipcbiAqIEFkZCBhdXRocyB0byB0aGUgaGFzaFxuICogV2lsbCBvdmVyd3JpdGUgYW55IGV4aXN0aW5nXG4gKlxuICovXG5Td2FnZ2VyQXV0aG9yaXphdGlvbnMucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIChuYW1lLCBhdXRoKSB7XG4gIGlmKF8uaXNPYmplY3QobmFtZSkpIHtcbiAgICBmb3IgKHZhciBrZXkgaW4gbmFtZSkge1xuICAgICAgdGhpcy5hdXRoeltrZXldID0gbmFtZVtrZXldO1xuICAgIH1cbiAgfSBlbHNlIGlmKHR5cGVvZiBuYW1lID09PSAnc3RyaW5nJyApe1xuICAgIHRoaXMuYXV0aHpbbmFtZV0gPSBhdXRoO1xuICB9XG5cbiAgcmV0dXJuIGF1dGg7XG59O1xuXG5Td2FnZ2VyQXV0aG9yaXphdGlvbnMucHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIHJldHVybiBkZWxldGUgdGhpcy5hdXRoeltuYW1lXTtcbn07XG5cblN3YWdnZXJBdXRob3JpemF0aW9ucy5wcm90b3R5cGUuYXBwbHkgPSBmdW5jdGlvbiAob2JqLCBzZWN1cml0aWVzKSB7XG4gIHZhciBzdGF0dXMgPSB0cnVlO1xuICB2YXIgYXBwbHlBbGwgPSAhc2VjdXJpdGllcztcbiAgdmFyIGZsYXR0ZW5lZFNlY3VyaXRpZXMgPSBbXTtcblxuICAvLyBmYXZvciB0aGUgb2JqZWN0LWxldmVsIGF1dGhvcml6YXRpb25zIG92ZXIgZ2xvYmFsXG4gIHZhciBhdXRoeiA9IG9iai5jbGllbnRBdXRob3JpemF0aW9ucyB8fCB0aGlzLmF1dGh6O1xuXG4gIC8vIFNlY3VyaXRpZXMgY291bGQgYmUgWyB7fSBdXG4gIF8uZWFjaChzZWN1cml0aWVzLCBmdW5jdGlvbiAob2JqLCBrZXkpIHtcblxuICAgIC8vIE1ha2Ugc3VyZSB3ZSBhY2NvdW50IGZvciBzZWN1cml0aWVzIGJlaW5nIFsgc3RyIF1cbiAgICBpZih0eXBlb2Yga2V5ID09PSAnc3RyaW5nJykge1xuICAgICAgZmxhdHRlbmVkU2VjdXJpdGllcy5wdXNoKGtleSk7XG4gICAgfVxuXG4gICAgLy8gRmxhdHRlbiBrZXlzIGluIHRvIG91ciBhcnJheVxuICAgIF8uZWFjaChvYmosIGZ1bmN0aW9uICh2YWwsIGtleSkge1xuICAgICAgZmxhdHRlbmVkU2VjdXJpdGllcy5wdXNoKGtleSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIF8uZWFjaChhdXRoeiwgZnVuY3Rpb24gKGF1dGgsIGF1dGhOYW1lKSB7XG4gICAgaWYoYXBwbHlBbGwgfHwgXy5pbmNsdWRlcyhmbGF0dGVuZWRTZWN1cml0aWVzLCBhdXRoTmFtZSkpIHtcbiAgICAgIHZhciBuZXdTdGF0dXMgPSBhdXRoLmFwcGx5KG9iaik7XG4gICAgICBzdGF0dXMgPSBzdGF0dXMgJiYgISFuZXdTdGF0dXM7IC8vIGxvZ2ljYWwgT1JzIHJlZ2FyZGluZyBzdGF0dXNcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBzdGF0dXM7XG59O1xuXG4vKipcbiAqIEFwaUtleUF1dGhvcml6YXRpb24gYWxsb3dzIGEgcXVlcnkgcGFyYW0gb3IgaGVhZGVyIHRvIGJlIGluamVjdGVkXG4gKi9cbnZhciBBcGlLZXlBdXRob3JpemF0aW9uID0gbW9kdWxlLmV4cG9ydHMuQXBpS2V5QXV0aG9yaXphdGlvbiA9IGZ1bmN0aW9uIChuYW1lLCB2YWx1ZSwgdHlwZSkge1xuICB0aGlzLm5hbWUgPSBuYW1lO1xuICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gIHRoaXMudHlwZSA9IHR5cGU7XG59O1xuXG5BcGlLZXlBdXRob3JpemF0aW9uLnByb3RvdHlwZS5hcHBseSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgaWYgKHRoaXMudHlwZSA9PT0gJ3F1ZXJ5Jykge1xuICAgIC8vIHNlZSBpZiBhbHJlYWR5IGFwcGxpZWQuICBJZiBzbywgZG9uJ3QgZG8gaXQgYWdhaW5cblxuICAgIHZhciBxcDtcbiAgICBpZiAob2JqLnVybC5pbmRleE9mKCc/JykgPiAwKSB7XG4gICAgICBxcCA9IG9iai51cmwuc3Vic3RyaW5nKG9iai51cmwuaW5kZXhPZignPycpICsgMSk7XG4gICAgICB2YXIgcGFydHMgPSBxcC5zcGxpdCgnJicpO1xuICAgICAgaWYocGFydHMgJiYgcGFydHMubGVuZ3RoID4gMCkge1xuICAgICAgICBmb3IodmFyIGkgPSAwOyBpIDwgcGFydHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICB2YXIga3YgPSBwYXJ0c1tpXS5zcGxpdCgnPScpO1xuICAgICAgICAgIGlmKGt2ICYmIGt2Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGlmIChrdlswXSA9PT0gdGhpcy5uYW1lKSB7XG4gICAgICAgICAgICAgIC8vIHNraXAgaXRcbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChvYmoudXJsLmluZGV4T2YoJz8nKSA+IDApIHtcbiAgICAgIG9iai51cmwgPSBvYmoudXJsICsgJyYnICsgdGhpcy5uYW1lICsgJz0nICsgdGhpcy52YWx1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgb2JqLnVybCA9IG9iai51cmwgKyAnPycgKyB0aGlzLm5hbWUgKyAnPScgKyB0aGlzLnZhbHVlO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9IGVsc2UgaWYgKHRoaXMudHlwZSA9PT0gJ2hlYWRlcicpIHtcbiAgICBpZih0eXBlb2Ygb2JqLmhlYWRlcnNbdGhpcy5uYW1lXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIG9iai5oZWFkZXJzW3RoaXMubmFtZV0gPSB0aGlzLnZhbHVlO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG59O1xuXG52YXIgQ29va2llQXV0aG9yaXphdGlvbiA9IG1vZHVsZS5leHBvcnRzLkNvb2tpZUF1dGhvcml6YXRpb24gPSBmdW5jdGlvbiAoY29va2llKSB7XG4gIHRoaXMuY29va2llID0gY29va2llO1xufTtcblxuQ29va2llQXV0aG9yaXphdGlvbi5wcm90b3R5cGUuYXBwbHkgPSBmdW5jdGlvbiAob2JqKSB7XG4gIG9iai5jb29raWVKYXIgPSBvYmouY29va2llSmFyIHx8IG5ldyBDb29raWVKYXIoKTtcbiAgb2JqLmNvb2tpZUphci5zZXRDb29raWUodGhpcy5jb29raWUpO1xuXG4gIHJldHVybiB0cnVlO1xufTtcblxuLyoqXG4gKiBQYXNzd29yZCBBdXRob3JpemF0aW9uIGlzIGEgYmFzaWMgYXV0aCBpbXBsZW1lbnRhdGlvblxuICovXG52YXIgUGFzc3dvcmRBdXRob3JpemF0aW9uID0gbW9kdWxlLmV4cG9ydHMuUGFzc3dvcmRBdXRob3JpemF0aW9uID0gZnVuY3Rpb24gKHVzZXJuYW1lLCBwYXNzd29yZCkge1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMykge1xuICAgIGhlbHBlcnMubG9nKCdQYXNzd29yZEF1dGhvcml6YXRpb246IHRoZSBcXCduYW1lXFwnIGFyZ3VtZW50IGhhcyBiZWVuIHJlbW92ZWQsIHBhc3Mgb25seSB1c2VybmFtZSBhbmQgcGFzc3dvcmQnKTtcbiAgICB1c2VybmFtZSA9IGFyZ3VtZW50c1sxXTtcbiAgICBwYXNzd29yZCA9IGFyZ3VtZW50c1syXTtcbiAgfVxuICB0aGlzLnVzZXJuYW1lID0gdXNlcm5hbWU7XG4gIHRoaXMucGFzc3dvcmQgPSBwYXNzd29yZDtcbn07XG5cblBhc3N3b3JkQXV0aG9yaXphdGlvbi5wcm90b3R5cGUuYXBwbHkgPSBmdW5jdGlvbiAob2JqKSB7XG4gIGlmKHR5cGVvZiBvYmouaGVhZGVycy5BdXRob3JpemF0aW9uID09PSAndW5kZWZpbmVkJykge1xuICAgIG9iai5oZWFkZXJzLkF1dGhvcml6YXRpb24gPSAnQmFzaWMgJyArIGJ0b2EodGhpcy51c2VybmFtZSArICc6JyArIHRoaXMucGFzc3dvcmQpO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgXyA9IHtcbiAgYmluZDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9mdW5jdGlvbi9iaW5kJyksXG4gIGNsb25lRGVlcDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2Nsb25lRGVlcCcpLFxuICBmaW5kOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2NvbGxlY3Rpb24vZmluZCcpLFxuICBmb3JFYWNoOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2NvbGxlY3Rpb24vZm9yRWFjaCcpLFxuICBpbmRleE9mOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2FycmF5L2luZGV4T2YnKSxcbiAgaXNBcnJheTogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzQXJyYXknKSxcbiAgaXNPYmplY3Q6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc09iamVjdCcpLFxuICBpc0Z1bmN0aW9uOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNGdW5jdGlvbicpLFxuICBpc1BsYWluT2JqZWN0OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNQbGFpbk9iamVjdCcpLFxuICBpc1VuZGVmaW5lZDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzVW5kZWZpbmVkJylcbn07XG52YXIgYXV0aCA9IHJlcXVpcmUoJy4vYXV0aCcpO1xudmFyIGhlbHBlcnMgPSByZXF1aXJlKCcuL2hlbHBlcnMnKTtcbnZhciBNb2RlbCA9IHJlcXVpcmUoJy4vdHlwZXMvbW9kZWwnKTtcbnZhciBPcGVyYXRpb24gPSByZXF1aXJlKCcuL3R5cGVzL29wZXJhdGlvbicpO1xudmFyIE9wZXJhdGlvbkdyb3VwID0gcmVxdWlyZSgnLi90eXBlcy9vcGVyYXRpb25Hcm91cCcpO1xudmFyIFJlc29sdmVyID0gcmVxdWlyZSgnLi9yZXNvbHZlcicpO1xudmFyIFN3YWdnZXJIdHRwID0gcmVxdWlyZSgnLi9odHRwJyk7XG52YXIgU3dhZ2dlclNwZWNDb252ZXJ0ZXIgPSByZXF1aXJlKCcuL3NwZWMtY29udmVydGVyJyk7XG52YXIgUSA9IHJlcXVpcmUoJ3EnKTtcblxuLy8gV2UgaGF2ZSB0byBrZWVwIHRyYWNrIG9mIHRoZSBmdW5jdGlvbi9wcm9wZXJ0eSBuYW1lcyB0byBhdm9pZCBjb2xsaXNpb25zIGZvciB0YWcgbmFtZXMgd2hpY2ggYXJlIHVzZWQgdG8gYWxsb3cgdGhlXG4vLyBmb2xsb3dpbmcgdXNhZ2U6ICdjbGllbnQue3RhZ05hbWV9J1xudmFyIHJlc2VydmVkQ2xpZW50VGFncyA9IFtcbiAgJ2FwaXMnLFxuICAnYXV0aG9yaXphdGlvblNjaGVtZScsXG4gICdhdXRob3JpemF0aW9ucycsXG4gICdiYXNlUGF0aCcsXG4gICdidWlsZCcsXG4gICdidWlsZEZyb20xXzFTcGVjJyxcbiAgJ2J1aWxkRnJvbTFfMlNwZWMnLFxuICAnYnVpbGRGcm9tU3BlYycsXG4gICdjbGllbnRBdXRob3JpemF0aW9ucycsXG4gICdjb252ZXJ0SW5mbycsXG4gICdkZWJ1ZycsXG4gICdkZWZhdWx0RXJyb3JDYWxsYmFjaycsXG4gICdkZWZhdWx0U3VjY2Vzc0NhbGxiYWNrJyxcbiAgJ2VuYWJsZUNvb2tpZXMnLFxuICAnZmFpbCcsXG4gICdmYWlsdXJlJyxcbiAgJ2ZpbmlzaCcsXG4gICdoZWxwJyxcbiAgJ2hvc3QnLFxuICAnaWRGcm9tT3AnLFxuICAnaW5mbycsXG4gICdpbml0aWFsaXplJyxcbiAgJ2lzQnVpbHQnLFxuICAnaXNWYWxpZCcsXG4gICdtb2RlbFByb3BlcnR5TWFjcm8nLFxuICAnbW9kZWxzJyxcbiAgJ21vZGVsc0FycmF5JyxcbiAgJ29wdGlvbnMnLFxuICAncGFyYW1ldGVyTWFjcm8nLFxuICAncGFyc2VVcmknLFxuICAncHJvZ3Jlc3MnLFxuICAncmVzb3VyY2VDb3VudCcsXG4gICdzYW1wbGVNb2RlbHMnLFxuICAnc2VsZlJlZmxlY3QnLFxuICAnc2V0Q29uc29saWRhdGVkTW9kZWxzJyxcbiAgJ3NwZWMnLFxuICAnc3VwcG9ydGVkU3VibWl0TWV0aG9kcycsXG4gICdzd2FnZ2VyUmVxdWVzdEhlYWRlcnMnLFxuICAndGFnRnJvbUxhYmVsJyxcbiAgJ3RpdGxlJyxcbiAgJ3VybCcsXG4gICd1c2VKUXVlcnknLFxuICAnanF1ZXJ5QWpheENhY2hlJ1xuXTtcbi8vIFdlIGhhdmUgdG8ga2VlcCB0cmFjayBvZiB0aGUgZnVuY3Rpb24vcHJvcGVydHkgbmFtZXMgdG8gYXZvaWQgY29sbGlzaW9ucyBmb3IgdGFnIG5hbWVzIHdoaWNoIGFyZSB1c2VkIHRvIGFsbG93IHRoZVxuLy8gZm9sbG93aW5nIHVzYWdlOiAnY2xpZW50LmFwaXMue3RhZ05hbWV9J1xudmFyIHJlc2VydmVkQXBpVGFncyA9IFtcbiAgJ2FwaXMnLFxuICAnYXNDdXJsJyxcbiAgJ2Rlc2NyaXB0aW9uJyxcbiAgJ2V4dGVybmFsRG9jcycsXG4gICdoZWxwJyxcbiAgJ2xhYmVsJyxcbiAgJ25hbWUnLFxuICAnb3BlcmF0aW9uJyxcbiAgJ29wZXJhdGlvbnMnLFxuICAnb3BlcmF0aW9uc0FycmF5JyxcbiAgJ3BhdGgnLFxuICAndGFnJ1xuXTtcbnZhciBzdXBwb3J0ZWRPcGVyYXRpb25NZXRob2RzID0gWydkZWxldGUnLCAnZ2V0JywgJ2hlYWQnLCAnb3B0aW9ucycsICdwYXRjaCcsICdwb3N0JywgJ3B1dCddO1xudmFyIFN3YWdnZXJDbGllbnQgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICh1cmwsIG9wdGlvbnMpIHtcbiAgdGhpcy5hdXRob3JpemF0aW9ucyA9IG51bGw7XG4gIHRoaXMuYXV0aG9yaXphdGlvblNjaGVtZSA9IG51bGw7XG4gIHRoaXMuYmFzZVBhdGggPSBudWxsO1xuICB0aGlzLmRlYnVnID0gZmFsc2U7XG4gIHRoaXMuZW5hYmxlQ29va2llcyA9IGZhbHNlO1xuICB0aGlzLmluZm8gPSBudWxsO1xuICB0aGlzLmlzQnVpbHQgPSBmYWxzZTtcbiAgdGhpcy5pc1ZhbGlkID0gZmFsc2U7XG4gIHRoaXMubW9kZWxzQXJyYXkgPSBbXTtcbiAgdGhpcy5yZXNvdXJjZUNvdW50ID0gMDtcbiAgdGhpcy51cmwgPSBudWxsO1xuICB0aGlzLnVzZUpRdWVyeSA9IGZhbHNlO1xuICB0aGlzLmpxdWVyeUFqYXhDYWNoZSA9IGZhbHNlO1xuICB0aGlzLnN3YWdnZXJPYmplY3QgPSB7fTtcbiAgdGhpcy5kZWZlcnJlZENsaWVudCA9IHVuZGVmaW5lZDtcblxuICB0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zID0gbmV3IGF1dGguU3dhZ2dlckF1dGhvcml6YXRpb25zKCk7XG5cbiAgaWYgKHR5cGVvZiB1cmwgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgcmV0dXJuIHRoaXMuaW5pdGlhbGl6ZSh1cmwsIG9wdGlvbnMpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB0aGlzO1xuICB9XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5pbml0aWFsaXplID0gZnVuY3Rpb24gKHVybCwgb3B0aW9ucykge1xuICB0aGlzLm1vZGVscyA9IHt9O1xuICB0aGlzLnNhbXBsZU1vZGVscyA9IHt9O1xuXG4gIGlmICh0eXBlb2YgdXJsID09PSAnc3RyaW5nJykge1xuICAgIHRoaXMudXJsID0gdXJsO1xuICB9IGVsc2UgaWYgKF8uaXNPYmplY3QodXJsKSkge1xuICAgIG9wdGlvbnMgPSB1cmw7XG4gICAgdGhpcy51cmwgPSBvcHRpb25zLnVybDtcbiAgfVxuXG4gIGlmKHRoaXMudXJsICYmIHRoaXMudXJsLmluZGV4T2YoJ2h0dHA6JykgPT09IC0xICYmIHRoaXMudXJsLmluZGV4T2YoJ2h0dHBzOicpID09PSAtMSkge1xuICAgIC8vIG5vIHByb3RvY29sLCBzbyB3ZSBjYW4gb25seSB1c2Ugd2luZG93IGlmIGl0IGV4aXN0c1xuICAgIGlmKHR5cGVvZih3aW5kb3cpICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cgJiYgd2luZG93LmxvY2F0aW9uKSB7XG4gICAgICB0aGlzLnVybCA9IHdpbmRvdy5sb2NhdGlvbi5vcmlnaW4gKyB0aGlzLnVybDtcbiAgICB9XG4gIH1cblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgdGhpcy5jbGllbnRBdXRob3JpemF0aW9ucy5hZGQob3B0aW9ucy5hdXRob3JpemF0aW9ucyk7XG4gIHRoaXMuc3dhZ2dlclJlcXVlc3RIZWFkZXJzID0gb3B0aW9ucy5zd2FnZ2VyUmVxdWVzdEhlYWRlcnMgfHwgJ2FwcGxpY2F0aW9uL2pzb247Y2hhcnNldD11dGYtOCwqLyonO1xuICB0aGlzLmRlZmF1bHRTdWNjZXNzQ2FsbGJhY2sgPSBvcHRpb25zLmRlZmF1bHRTdWNjZXNzQ2FsbGJhY2sgfHwgbnVsbDtcbiAgdGhpcy5kZWZhdWx0RXJyb3JDYWxsYmFjayA9IG9wdGlvbnMuZGVmYXVsdEVycm9yQ2FsbGJhY2sgfHwgbnVsbDtcbiAgdGhpcy5tb2RlbFByb3BlcnR5TWFjcm8gPSBvcHRpb25zLm1vZGVsUHJvcGVydHlNYWNybyB8fCBudWxsO1xuICB0aGlzLmNvbm5lY3Rpb25BZ2VudCA9IG9wdGlvbnMuY29ubmVjdGlvbkFnZW50IHx8IG51bGw7XG4gIHRoaXMucGFyYW1ldGVyTWFjcm8gPSBvcHRpb25zLnBhcmFtZXRlck1hY3JvIHx8IG51bGw7XG4gIHRoaXMudXNlUHJvbWlzZSA9IG9wdGlvbnMudXNlUHJvbWlzZSB8fCBudWxsO1xuXG4gIC8vIG9wZXJhdGlvbiByZXF1ZXN0IHRpbWVvdXQgZGVmYXVsdFxuICB0aGlzLnRpbWVvdXQgPSBvcHRpb25zLnRpbWVvdXQgfHwgbnVsbDtcbiAgLy8gZGVmYXVsdCB0byByZXF1ZXN0IHRpbWVvdXQgd2hlbiBub3Qgc3BlY2lmaWVkXG4gIHRoaXMuZmV0Y2hTcGVjVGltZW91dCA9IHR5cGVvZiBvcHRpb25zLmZldGNoU3BlY1RpbWVvdXQgIT09ICd1bmRlZmluZWQnID9cbiAgICAgIG9wdGlvbnMuZmV0Y2hTcGVjVGltZW91dCA6IG9wdGlvbnMudGltZW91dCB8fCBudWxsO1xuXG4gIGlmKHRoaXMudXNlUHJvbWlzZSkge1xuICAgIHRoaXMuZGVmZXJyZWRDbGllbnQgPSBRLmRlZmVyKCk7XG4gIH1cblxuICBpZiAodHlwZW9mIG9wdGlvbnMuc3VjY2VzcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHRoaXMuc3VjY2VzcyA9IG9wdGlvbnMuc3VjY2VzcztcbiAgfVxuICBpZiAob3B0aW9ucy51c2VKUXVlcnkpIHtcbiAgICB0aGlzLnVzZUpRdWVyeSA9IG9wdGlvbnMudXNlSlF1ZXJ5O1xuICB9XG5cbiAgaWYgKG9wdGlvbnMuanF1ZXJ5QWpheENhY2hlKSB7XG4gICAgdGhpcy5qcXVlcnlBamF4Q2FjaGUgPSBvcHRpb25zLmpxdWVyeUFqYXhDYWNoZTtcbiAgfVxuXG4gIGlmIChvcHRpb25zLmVuYWJsZUNvb2tpZXMpIHtcbiAgICB0aGlzLmVuYWJsZUNvb2tpZXMgPSBvcHRpb25zLmVuYWJsZUNvb2tpZXM7XG4gIH1cblxuICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIC8vIG1heWJlIGRvbid0IG5lZWQgdGhpcz9cbiAgdGhpcy5vcHRpb25zLnRpbWVvdXQgPSB0aGlzLnRpbWVvdXQ7XG4gIHRoaXMub3B0aW9ucy5mZXRjaFNwZWNUaW1lb3V0ID0gdGhpcy5mZXRjaFNwZWNUaW1lb3V0O1xuXG4gIHRoaXMuc3VwcG9ydGVkU3VibWl0TWV0aG9kcyA9IG9wdGlvbnMuc3VwcG9ydGVkU3VibWl0TWV0aG9kcyB8fCBbXTtcbiAgdGhpcy5mYWlsdXJlID0gb3B0aW9ucy5mYWlsdXJlIHx8IGZ1bmN0aW9uIChlcnIpIHsgdGhyb3cgZXJyOyB9O1xuICB0aGlzLnByb2dyZXNzID0gb3B0aW9ucy5wcm9ncmVzcyB8fCBmdW5jdGlvbiAoKSB7fTtcbiAgdGhpcy5zcGVjID0gXy5jbG9uZURlZXAob3B0aW9ucy5zcGVjKTsgLy8gQ2xvbmUgc28gd2UgZG8gbm90IGFsdGVyIHRoZSBwcm92aWRlZCBkb2N1bWVudFxuXG4gIGlmIChvcHRpb25zLnNjaGVtZSkge1xuICAgIHRoaXMuc2NoZW1lID0gb3B0aW9ucy5zY2hlbWU7XG4gIH1cblxuICBpZiAodGhpcy51c2VQcm9taXNlIHx8IHR5cGVvZiBvcHRpb25zLnN1Y2Nlc3MgPT09ICdmdW5jdGlvbicpIHtcbiAgICB0aGlzLnJlYWR5ID0gdHJ1ZTtcbiAgICByZXR1cm4gdGhpcy5idWlsZCgpO1xuICB9XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5idWlsZCA9IGZ1bmN0aW9uIChtb2NrKSB7XG4gIGlmICh0aGlzLmlzQnVpbHQpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICBpZiAodGhpcy5zcGVjKSB7XG4gICAgdGhpcy5wcm9ncmVzcygnZmV0Y2hpbmcgcmVzb3VyY2UgbGlzdDsgUGxlYXNlIHdhaXQuJyk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5wcm9ncmVzcygnZmV0Y2hpbmcgcmVzb3VyY2UgbGlzdDogJyArIHRoaXMudXJsICsgJzsgUGxlYXNlIHdhaXQuJyk7XG4gIH1cblxuICB2YXIgb2JqID0ge1xuICAgIHVzZUpRdWVyeTogdGhpcy51c2VKUXVlcnksXG4gICAganF1ZXJ5QWpheENhY2hlOiB0aGlzLmpxdWVyeUFqYXhDYWNoZSxcbiAgICBjb25uZWN0aW9uQWdlbnQ6IHRoaXMuY29ubmVjdGlvbkFnZW50LFxuICAgIGVuYWJsZUNvb2tpZXM6IHRoaXMuZW5hYmxlQ29va2llcyxcbiAgICB1cmw6IHRoaXMudXJsLFxuICAgIG1ldGhvZDogJ2dldCcsXG4gICAgaGVhZGVyczoge1xuICAgICAgYWNjZXB0OiB0aGlzLnN3YWdnZXJSZXF1ZXN0SGVhZGVyc1xuICAgIH0sXG4gICAgb246IHtcbiAgICAgIGVycm9yOiBmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgICAgaWYgKHNlbGYudXJsLnN1YnN0cmluZygwLCA0KSAhPT0gJ2h0dHAnKSB7XG4gICAgICAgICAgcmV0dXJuIHNlbGYuZmFpbCgnUGxlYXNlIHNwZWNpZnkgdGhlIHByb3RvY29sIGZvciAnICsgc2VsZi51cmwpO1xuICAgICAgICB9IGVsc2UgaWYgKHJlc3BvbnNlLmVyck9iaiAmJiAocmVzcG9uc2UuZXJyT2JqLmNvZGUgPT09ICdFQ09OTkFCT1JURUQnIHx8IHJlc3BvbnNlLmVyck9iai5tZXNzYWdlLmluZGV4T2YoJ3RpbWVvdXQnKSAhPT0gLTEpKSB7XG4gICAgICAgICAgcmV0dXJuIHNlbGYuZmFpbCgnUmVxdWVzdCB0aW1lZCBvdXQgYWZ0ZXIgJyArIHNlbGYuZmV0Y2hTcGVjVGltZW91dCArICdtcycpO1xuICAgICAgICB9IGVsc2UgaWYgKHJlc3BvbnNlLnN0YXR1cyA9PT0gMCkge1xuICAgICAgICAgIHJldHVybiBzZWxmLmZhaWwoJ0NhblxcJ3QgcmVhZCBmcm9tIHNlcnZlci4gIEl0IG1heSBub3QgaGF2ZSB0aGUgYXBwcm9wcmlhdGUgYWNjZXNzLWNvbnRyb2wtb3JpZ2luIHNldHRpbmdzLicpO1xuICAgICAgICB9IGVsc2UgaWYgKHJlc3BvbnNlLnN0YXR1cyA9PT0gNDA0KSB7XG4gICAgICAgICAgcmV0dXJuIHNlbGYuZmFpbCgnQ2FuXFwndCByZWFkIHN3YWdnZXIgSlNPTiBmcm9tICcgKyBzZWxmLnVybCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHNlbGYuZmFpbChyZXNwb25zZS5zdGF0dXMgKyAnIDogJyArIHJlc3BvbnNlLnN0YXR1c1RleHQgKyAnICcgKyBzZWxmLnVybCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICByZXNwb25zZTogZnVuY3Rpb24gKHJlc3ApIHtcblxuICAgICAgICB2YXIgcmVzcG9uc2VPYmogPSByZXNwLm9iajtcbiAgICAgICAgaWYoIXJlc3BvbnNlT2JqKSB7XG4gICAgICAgICAgcmV0dXJuIHNlbGYuZmFpbCgnZmFpbGVkIHRvIHBhcnNlIEpTT04vWUFNTCByZXNwb25zZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgc2VsZi5zd2FnZ2VyVmVyc2lvbiA9IHJlc3BvbnNlT2JqLnN3YWdnZXJWZXJzaW9uO1xuICAgICAgICBzZWxmLnN3YWdnZXJPYmplY3QgPSByZXNwb25zZU9iajtcblxuICAgICAgICBpZiAocmVzcG9uc2VPYmouc3dhZ2dlciAmJiBwYXJzZUludChyZXNwb25zZU9iai5zd2FnZ2VyKSA9PT0gMikge1xuICAgICAgICAgIHNlbGYuc3dhZ2dlclZlcnNpb24gPSByZXNwb25zZU9iai5zd2FnZ2VyO1xuXG4gICAgICAgICAgbmV3IFJlc29sdmVyKCkucmVzb2x2ZShyZXNwb25zZU9iaiwgc2VsZi51cmwsIHNlbGYuYnVpbGRGcm9tU3BlYywgc2VsZik7XG5cbiAgICAgICAgICBzZWxmLmlzVmFsaWQgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciBjb252ZXJ0ZXIgPSBuZXcgU3dhZ2dlclNwZWNDb252ZXJ0ZXIoKTtcbiAgICAgICAgICBzZWxmLm9sZFN3YWdnZXJPYmplY3QgPSBzZWxmLnN3YWdnZXJPYmplY3Q7XG5cbiAgICAgICAgICBjb252ZXJ0ZXIuc2V0RG9jdW1lbnRhdGlvbkxvY2F0aW9uKHNlbGYudXJsKTtcbiAgICAgICAgICBjb252ZXJ0ZXIuY29udmVydChyZXNwb25zZU9iaiwgc2VsZi5jbGllbnRBdXRob3JpemF0aW9ucywgc2VsZi5vcHRpb25zLCBmdW5jdGlvbihzcGVjKSB7XG4gICAgICAgICAgICBzZWxmLnN3YWdnZXJPYmplY3QgPSBzcGVjO1xuICAgICAgICAgICAgbmV3IFJlc29sdmVyKCkucmVzb2x2ZShzcGVjLCBzZWxmLnVybCwgc2VsZi5idWlsZEZyb21TcGVjLCBzZWxmKTtcbiAgICAgICAgICAgIHNlbGYuaXNWYWxpZCA9IHRydWU7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgLy8gb25seSBzZXQgdGltZW91dCB3aGVuIHNwZWNpZmllZFxuICBpZiAodGhpcy5mZXRjaFNwZWNUaW1lb3V0KSB7XG4gICAgb2JqLnRpbWVvdXQgPSB0aGlzLmZldGNoU3BlY1RpbWVvdXQ7XG4gIH1cblxuICBpZiAodGhpcy5zcGVjKSB7XG4gICAgc2VsZi5zd2FnZ2VyT2JqZWN0ID0gdGhpcy5zcGVjO1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgbmV3IFJlc29sdmVyKCkucmVzb2x2ZShzZWxmLnNwZWMsIHNlbGYudXJsLCBzZWxmLmJ1aWxkRnJvbVNwZWMsIHNlbGYpO1xuICAgIH0sIDEwKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zLmFwcGx5KG9iaik7XG5cbiAgICBpZiAobW9jaykge1xuICAgICAgcmV0dXJuIG9iajtcbiAgICB9XG5cbiAgICBuZXcgU3dhZ2dlckh0dHAoKS5leGVjdXRlKG9iaiwgdGhpcy5vcHRpb25zKTtcbiAgfVxuXG4gIHJldHVybiAodGhpcy51c2VQcm9taXNlKSA/IHRoaXMuZGVmZXJyZWRDbGllbnQucHJvbWlzZSA6IHRoaXM7XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5idWlsZEZyb21TcGVjID0gZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gIGlmICh0aGlzLmlzQnVpbHQpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHRoaXMuYXBpcyA9IHt9O1xuICB0aGlzLmFwaXNBcnJheSA9IFtdO1xuICB0aGlzLmJhc2VQYXRoID0gcmVzcG9uc2UuYmFzZVBhdGggfHwgJyc7XG4gIHRoaXMuY29uc3VtZXMgPSByZXNwb25zZS5jb25zdW1lcztcbiAgdGhpcy5ob3N0ID0gcmVzcG9uc2UuaG9zdCB8fCAnJztcbiAgdGhpcy5pbmZvID0gcmVzcG9uc2UuaW5mbyB8fCB7fTtcbiAgdGhpcy5wcm9kdWNlcyA9IHJlc3BvbnNlLnByb2R1Y2VzO1xuICB0aGlzLnNjaGVtZXMgPSByZXNwb25zZS5zY2hlbWVzIHx8IFtdO1xuICB0aGlzLnNlY3VyaXR5RGVmaW5pdGlvbnMgPSBfLmNsb25lRGVlcChyZXNwb25zZS5zZWN1cml0eURlZmluaXRpb25zKTtcbiAgdGhpcy5zZWN1cml0eSA9IHJlc3BvbnNlLnNlY3VyaXR5O1xuICB0aGlzLnRpdGxlID0gcmVzcG9uc2UudGl0bGUgfHwgJyc7XG5cbiAgdmFyIGtleSwgZGVmaW5lZFRhZ3MgPSB7fSwgaywgbG9jYXRpb24sIHNlbGYgPSB0aGlzLCBpO1xuXG4gIGlmIChyZXNwb25zZS5leHRlcm5hbERvY3MpIHtcbiAgICB0aGlzLmV4dGVybmFsRG9jcyA9IHJlc3BvbnNlLmV4dGVybmFsRG9jcztcbiAgfVxuXG4gIC8vIGxlZ2FjeSBzdXBwb3J0XG4gIHRoaXMuYXV0aFNjaGVtZXMgPSB0aGlzLnNlY3VyaXR5RGVmaW5pdGlvbnM7XG5cbiAgaWYodGhpcy5zZWN1cml0eURlZmluaXRpb25zKSB7XG4gICAgZm9yKGtleSBpbiB0aGlzLnNlY3VyaXR5RGVmaW5pdGlvbnMpIHtcbiAgICAgIHZhciBzZWN1cml0eURlZmluaXRpb24gPSB0aGlzLnNlY3VyaXR5RGVmaW5pdGlvbnNba2V5XTtcbiAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi52ZW5kb3JFeHRlbnNpb25zID0ge307XG4gICAgICBmb3IodmFyIGV4dCBpbiBzZWN1cml0eURlZmluaXRpb24pIHtcbiAgICAgICAgaGVscGVycy5leHRyYWN0RXh0ZW5zaW9ucyhleHQsIHNlY3VyaXR5RGVmaW5pdGlvbik7XG4gICAgICAgIGlmIChleHQgPT09ICdzY29wZXMnKSB7XG4gICAgICAgICAgdmFyIHNjb3BlcyA9IHNlY3VyaXR5RGVmaW5pdGlvbltleHRdO1xuICAgICAgICAgIGlmKHR5cGVvZiBzY29wZXMgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICBzY29wZXMudmVuZG9yRXh0ZW5zaW9ucyA9IHt9O1xuICAgICAgICAgICAgZm9yICh2YXIgcyBpbiBzY29wZXMpIHtcbiAgICAgICAgICAgICAgaGVscGVycy5leHRyYWN0RXh0ZW5zaW9ucyhzLCBzY29wZXMpO1xuICAgICAgICAgICAgICBpZihzLmluZGV4T2YoJ3gtJykgPT09IDApIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgc2NvcGVzW3NdO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkocmVzcG9uc2UudGFncykpIHtcbiAgICBkZWZpbmVkVGFncyA9IHt9O1xuXG4gICAgZm9yIChrID0gMDsgayA8IHJlc3BvbnNlLnRhZ3MubGVuZ3RoOyBrKyspIHtcbiAgICAgIHZhciB0ID0gXy5jbG9uZURlZXAocmVzcG9uc2UudGFnc1trXSk7XG4gICAgICBkZWZpbmVkVGFnc1t0Lm5hbWVdID0gdDtcbiAgICAgIGZvcihpIGluIHQpIHtcbiAgICAgICAgaWYoaSA9PT0gJ2V4dGVybmFsRG9jcycgJiYgdHlwZW9mIHRbaV0gPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgZm9yKHZhciBqIGluIHRbaV0pIHtcbiAgICAgICAgICAgIGhlbHBlcnMuZXh0cmFjdEV4dGVuc2lvbnMoaiwgdFtpXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGhlbHBlcnMuZXh0cmFjdEV4dGVuc2lvbnMoaSwgdCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cblxuICBpZiAodHlwZW9mIHRoaXMudXJsID09PSAnc3RyaW5nJykge1xuICAgIGxvY2F0aW9uID0gdGhpcy5wYXJzZVVyaSh0aGlzLnVybCk7XG4gICAgaWYgKHR5cGVvZiB0aGlzLnNjaGVtZSA9PT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIHRoaXMuc2NoZW1lcyA9PT0gJ3VuZGVmaW5lZCcgfHwgdGhpcy5zY2hlbWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgaWYodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgLy8gdXNlIHRoZSB3aW5kb3cgc2NoZW1lXG4gICAgICAgIHRoaXMuc2NoZW1lID0gd2luZG93LmxvY2F0aW9uLnByb3RvY29sLnJlcGxhY2UoJzonLCcnKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICB0aGlzLnNjaGVtZSA9IGxvY2F0aW9uLnNjaGVtZSB8fCAnaHR0cCc7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cubG9jYXRpb24ucHJvdG9jb2wuaW5kZXhPZignY2hyb21lLWV4dGVuc2lvbicpID09PSAwKSB7XG5cdFx0Ly8gaWYgaXQgaXMgY2hyb21lIHN3YWdnZXIgdWkgZXh0ZW5zaW9uIHNjaGVtZSB0aGVuIGxldCBzd2FnZ2VyIGRvYyB1cmwgc2NoZW1lIGRlY2lkZSB0aGUgcHJvdG9jb2xcblx0XHR0aGlzLnNjaGVtZSA9IGxvY2F0aW9uLnNjaGVtZTtcblx0fSBlbHNlIGlmICh0eXBlb2YgdGhpcy5zY2hlbWUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBpZih0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICB2YXIgc2NoZW1lID0gd2luZG93LmxvY2F0aW9uLnByb3RvY29sLnJlcGxhY2UoJzonLCcnKTtcbiAgICAgICAgaWYoc2NoZW1lID09PSAnaHR0cHMnICYmIHRoaXMuc2NoZW1lcy5pbmRleE9mKHNjaGVtZSkgPT09IC0xKSB7XG4gICAgICAgICAgLy8gY2FuJ3QgY2FsbCBodHRwIGZyb20gaHR0cHMgc2VydmVkIHBhZ2UgaW4gYSBicm93c2VyIVxuICAgICAgICAgIGhlbHBlcnMubG9nKCdDYW5ub3QgY2FsbCBhIGh0dHAgc2VydmVyIGZyb20gaHR0cHMgaW5zaWRlIGEgYnJvd3NlciEnKTtcbiAgICAgICAgICB0aGlzLnNjaGVtZSA9ICdodHRwJztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmKHRoaXMuc2NoZW1lcy5pbmRleE9mKHNjaGVtZSkgIT09IC0xKSB7XG4gICAgICAgICAgdGhpcy5zY2hlbWUgPSBzY2hlbWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgaWYodGhpcy5zY2hlbWVzLmluZGV4T2YoJ2h0dHBzJykgIT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLnNjaGVtZSA9ICdodHRwcyc7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zY2hlbWUgPSAnaHR0cCc7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgdGhpcy5zY2hlbWUgPSB0aGlzLnNjaGVtZXNbMF0gfHwgbG9jYXRpb24uc2NoZW1lO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdGhpcy5ob3N0ID09PSAndW5kZWZpbmVkJyB8fCB0aGlzLmhvc3QgPT09ICcnKSB7XG4gICAgICB0aGlzLmhvc3QgPSBsb2NhdGlvbi5ob3N0O1xuXG4gICAgICBpZiAobG9jYXRpb24ucG9ydCkge1xuICAgICAgICB0aGlzLmhvc3QgPSB0aGlzLmhvc3QgKyAnOicgKyBsb2NhdGlvbi5wb3J0O1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBlbHNlIHtcbiAgICBpZiAodHlwZW9mIHRoaXMuc2NoZW1lcyA9PT0gJ3VuZGVmaW5lZCcgfHwgdGhpcy5zY2hlbWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5zY2hlbWUgPSAnaHR0cCc7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGVvZiB0aGlzLnNjaGVtZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRoaXMuc2NoZW1lID0gdGhpcy5zY2hlbWVzWzBdO1xuICAgIH1cbiAgfVxuXG4gIHRoaXMuZGVmaW5pdGlvbnMgPSByZXNwb25zZS5kZWZpbml0aW9ucztcblxuICBmb3IgKGtleSBpbiB0aGlzLmRlZmluaXRpb25zKSB7XG4gICAgdmFyIG1vZGVsID0gbmV3IE1vZGVsKGtleSwgdGhpcy5kZWZpbml0aW9uc1trZXldLCB0aGlzLm1vZGVscywgdGhpcy5tb2RlbFByb3BlcnR5TWFjcm8pO1xuXG4gICAgaWYgKG1vZGVsKSB7XG4gICAgICB0aGlzLm1vZGVsc1trZXldID0gbW9kZWw7XG4gICAgfVxuICB9XG5cbiAgLy8gZ2V0IHBhdGhzLCBjcmVhdGUgZnVuY3Rpb25zIGZvciBlYWNoIG9wZXJhdGlvbklkXG5cbiAgLy8gQmluZCBoZWxwIHRvICdjbGllbnQuYXBpcydcbiAgc2VsZi5hcGlzLmhlbHAgPSBfLmJpbmQoc2VsZi5oZWxwLCBzZWxmKTtcblxuICBfLmZvckVhY2gocmVzcG9uc2UucGF0aHMsIGZ1bmN0aW9uIChwYXRoT2JqLCBwYXRoKSB7XG4gICAgLy8gT25seSBwcm9jZXNzIGEgcGF0aCBpZiBpdCdzIGFuIG9iamVjdFxuICAgIGlmICghXy5pc1BsYWluT2JqZWN0KHBhdGhPYmopKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgXy5mb3JFYWNoKHN1cHBvcnRlZE9wZXJhdGlvbk1ldGhvZHMsIGZ1bmN0aW9uIChtZXRob2QpIHtcbiAgICAgIHZhciBvcGVyYXRpb24gPSBwYXRoT2JqW21ldGhvZF07XG5cbiAgICAgIGlmIChfLmlzVW5kZWZpbmVkKG9wZXJhdGlvbikpIHtcbiAgICAgICAgLy8gT3BlcmF0aW9uIGRvZXMgbm90IGV4aXN0XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gZWxzZSBpZiAoIV8uaXNQbGFpbk9iamVjdChvcGVyYXRpb24pKSB7XG4gICAgICAgIC8vIE9wZXJhdGlvbiBleGlzdHMgYnV0IGl0IGlzIG5vdCBhbiBPcGVyYXRpb24gT2JqZWN0LiAgU2luY2UgdGhpcyBpcyBpbnZhbGlkLCBsb2cgaXQuXG4gICAgICAgIGhlbHBlcnMubG9nKCdUaGUgXFwnJyArIG1ldGhvZCArICdcXCcgb3BlcmF0aW9uIGZvciBcXCcnICsgcGF0aCArICdcXCcgcGF0aCBpcyBub3QgYW4gT3BlcmF0aW9uIE9iamVjdCcpO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIHRhZ3MgPSBvcGVyYXRpb24udGFncztcblxuICAgICAgaWYgKF8uaXNVbmRlZmluZWQodGFncykgfHwgIV8uaXNBcnJheSh0YWdzKSB8fCB0YWdzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0YWdzID0gb3BlcmF0aW9uLnRhZ3MgPSBbICdkZWZhdWx0JyBdO1xuICAgICAgfVxuXG4gICAgICB2YXIgb3BlcmF0aW9uSWQgPSBzZWxmLmlkRnJvbU9wKHBhdGgsIG1ldGhvZCwgb3BlcmF0aW9uKTtcblxuICAgICAgdmFyIG9wZXJhdGlvbk9iamVjdCA9IG5ldyBPcGVyYXRpb24oc2VsZixcbiAgICAgICAgb3BlcmF0aW9uLnNjaGVtZSxcbiAgICAgICAgb3BlcmF0aW9uSWQsXG4gICAgICAgIG1ldGhvZCxcbiAgICAgICAgcGF0aCxcbiAgICAgICAgb3BlcmF0aW9uLFxuICAgICAgICBzZWxmLmRlZmluaXRpb25zLFxuICAgICAgICBzZWxmLm1vZGVscyxcbiAgICAgICAgc2VsZi5jbGllbnRBdXRob3JpemF0aW9ucyk7XG5cbiAgICAgIG9wZXJhdGlvbk9iamVjdC5jb25uZWN0aW9uQWdlbnQgPSBzZWxmLmNvbm5lY3Rpb25BZ2VudDtcbiAgICAgIG9wZXJhdGlvbk9iamVjdC52ZW5kb3JFeHRlbnNpb25zID0ge307XG4gICAgICBmb3IoaSBpbiBvcGVyYXRpb24pIHtcbiAgICAgICAgaGVscGVycy5leHRyYWN0RXh0ZW5zaW9ucyhpLCBvcGVyYXRpb25PYmplY3QsIG9wZXJhdGlvbltpXSk7XG4gICAgICB9XG4gICAgICBvcGVyYXRpb25PYmplY3QuZXh0ZXJuYWxEb2NzID0gb3BlcmF0aW9uLmV4dGVybmFsRG9jcztcbiAgICAgIGlmKG9wZXJhdGlvbk9iamVjdC5leHRlcm5hbERvY3MpIHtcbiAgICAgICAgb3BlcmF0aW9uT2JqZWN0LmV4dGVybmFsRG9jcyA9IF8uY2xvbmVEZWVwKG9wZXJhdGlvbk9iamVjdC5leHRlcm5hbERvY3MpO1xuICAgICAgICBvcGVyYXRpb25PYmplY3QuZXh0ZXJuYWxEb2NzLnZlbmRvckV4dGVuc2lvbnMgPSB7fTtcbiAgICAgICAgZm9yKGkgaW4gb3BlcmF0aW9uT2JqZWN0LmV4dGVybmFsRG9jcykge1xuICAgICAgICAgIGhlbHBlcnMuZXh0cmFjdEV4dGVuc2lvbnMoaSwgb3BlcmF0aW9uT2JqZWN0LmV4dGVybmFsRG9jcyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gYmluZCBzZWxmIG9wZXJhdGlvbidzIGV4ZWN1dGUgY29tbWFuZCB0byB0aGUgYXBpXG4gICAgICBfLmZvckVhY2godGFncywgZnVuY3Rpb24gKHRhZykge1xuICAgICAgICB2YXIgY2xpZW50UHJvcGVydHkgPSBfLmluZGV4T2YocmVzZXJ2ZWRDbGllbnRUYWdzLCB0YWcpID4gLTEgPyAnXycgKyB0YWcgOiB0YWc7XG4gICAgICAgIHZhciBhcGlQcm9wZXJ0eSA9IF8uaW5kZXhPZihyZXNlcnZlZEFwaVRhZ3MsIHRhZykgPiAtMSA/ICdfJyArIHRhZyA6IHRhZztcbiAgICAgICAgdmFyIG9wZXJhdGlvbkdyb3VwID0gc2VsZltjbGllbnRQcm9wZXJ0eV07XG5cbiAgICAgICAgaWYgKGNsaWVudFByb3BlcnR5ICE9PSB0YWcpIHtcbiAgICAgICAgICBoZWxwZXJzLmxvZygnVGhlIFxcJycgKyB0YWcgKyAnXFwnIHRhZyBjb25mbGljdHMgd2l0aCBhIFN3YWdnZXJDbGllbnQgZnVuY3Rpb24vcHJvcGVydHkgbmFtZS4gIFVzZSBcXCdjbGllbnQuJyArXG4gICAgICAgICAgICAgICAgICAgICAgY2xpZW50UHJvcGVydHkgKyAnXFwnIG9yIFxcJ2NsaWVudC5hcGlzLicgKyB0YWcgKyAnXFwnIGluc3RlYWQgb2YgXFwnY2xpZW50LicgKyB0YWcgKyAnXFwnLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGFwaVByb3BlcnR5ICE9PSB0YWcpIHtcbiAgICAgICAgICBoZWxwZXJzLmxvZygnVGhlIFxcJycgKyB0YWcgKyAnXFwnIHRhZyBjb25mbGljdHMgd2l0aCBhIFN3YWdnZXJDbGllbnQgb3BlcmF0aW9uIGZ1bmN0aW9uL3Byb3BlcnR5IG5hbWUuICBVc2UgJyArXG4gICAgICAgICAgICAgICAgICAgICAgJ1xcJ2NsaWVudC5hcGlzLicgKyBhcGlQcm9wZXJ0eSArICdcXCcgaW5zdGVhZCBvZiBcXCdjbGllbnQuYXBpcy4nICsgdGFnICsgJ1xcJy4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChfLmluZGV4T2YocmVzZXJ2ZWRBcGlUYWdzLCBvcGVyYXRpb25JZCkgPiAtMSkge1xuICAgICAgICAgIGhlbHBlcnMubG9nKCdUaGUgXFwnJyArIG9wZXJhdGlvbklkICsgJ1xcJyBvcGVyYXRpb25JZCBjb25mbGljdHMgd2l0aCBhIFN3YWdnZXJDbGllbnQgb3BlcmF0aW9uICcgK1xuICAgICAgICAgICAgICAgICAgICAgICdmdW5jdGlvbi9wcm9wZXJ0eSBuYW1lLiAgVXNlIFxcJ2NsaWVudC5hcGlzLicgKyBhcGlQcm9wZXJ0eSArICcuXycgKyBvcGVyYXRpb25JZCArXG4gICAgICAgICAgICAgICAgICAgICAgJ1xcJyBpbnN0ZWFkIG9mIFxcJ2NsaWVudC5hcGlzLicgKyBhcGlQcm9wZXJ0eSArICcuJyArIG9wZXJhdGlvbklkICsgJ1xcJy4nKTtcblxuICAgICAgICAgIG9wZXJhdGlvbklkID0gJ18nICsgb3BlcmF0aW9uSWQ7XG4gICAgICAgICAgb3BlcmF0aW9uT2JqZWN0Lm5pY2tuYW1lID0gb3BlcmF0aW9uSWQ7IC8vIFNvICdjbGllbnQuYXBpcy5bdGFnXS5vcGVyYXRpb25JZC5oZWxwKCkgd29ya3MgcHJvcGVybHlcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChfLmlzVW5kZWZpbmVkKG9wZXJhdGlvbkdyb3VwKSkge1xuICAgICAgICAgIG9wZXJhdGlvbkdyb3VwID0gc2VsZltjbGllbnRQcm9wZXJ0eV0gPSBzZWxmLmFwaXNbYXBpUHJvcGVydHldID0ge307XG5cbiAgICAgICAgICBvcGVyYXRpb25Hcm91cC5vcGVyYXRpb25zID0ge307XG4gICAgICAgICAgb3BlcmF0aW9uR3JvdXAubGFiZWwgPSBhcGlQcm9wZXJ0eTtcbiAgICAgICAgICBvcGVyYXRpb25Hcm91cC5hcGlzID0ge307XG5cbiAgICAgICAgICB2YXIgdGFnRGVmID0gZGVmaW5lZFRhZ3NbdGFnXTtcblxuICAgICAgICAgIGlmICghXy5pc1VuZGVmaW5lZCh0YWdEZWYpKSB7XG4gICAgICAgICAgICBvcGVyYXRpb25Hcm91cC5kZXNjcmlwdGlvbiA9IHRhZ0RlZi5kZXNjcmlwdGlvbjtcbiAgICAgICAgICAgIG9wZXJhdGlvbkdyb3VwLmV4dGVybmFsRG9jcyA9IHRhZ0RlZi5leHRlcm5hbERvY3M7XG4gICAgICAgICAgICBvcGVyYXRpb25Hcm91cC52ZW5kb3JFeHRlbnNpb25zID0gdGFnRGVmLnZlbmRvckV4dGVuc2lvbnM7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc2VsZltjbGllbnRQcm9wZXJ0eV0uaGVscCA9IF8uYmluZChzZWxmLmhlbHAsIG9wZXJhdGlvbkdyb3VwKTtcbiAgICAgICAgICBzZWxmLmFwaXNBcnJheS5wdXNoKG5ldyBPcGVyYXRpb25Hcm91cCh0YWcsIG9wZXJhdGlvbkdyb3VwLmRlc2NyaXB0aW9uLCBvcGVyYXRpb25Hcm91cC5leHRlcm5hbERvY3MsIG9wZXJhdGlvbk9iamVjdCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgb3BlcmF0aW9uSWQgPSBzZWxmLm1ha2VVbmlxdWVPcGVyYXRpb25JZChvcGVyYXRpb25JZCwgc2VsZi5hcGlzW2FwaVByb3BlcnR5XSk7XG5cbiAgICAgICAgLy8gQmluZCB0YWcgaGVscFxuICAgICAgICBpZiAoIV8uaXNGdW5jdGlvbihvcGVyYXRpb25Hcm91cC5oZWxwKSkge1xuICAgICAgICAgIG9wZXJhdGlvbkdyb3VwLmhlbHAgPSBfLmJpbmQoc2VsZi5oZWxwLCBvcGVyYXRpb25Hcm91cCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBiaW5kIHRvIHRoZSBhcGlzIG9iamVjdFxuICAgICAgICBzZWxmLmFwaXNbYXBpUHJvcGVydHldW29wZXJhdGlvbklkXSA9IG9wZXJhdGlvbkdyb3VwW29wZXJhdGlvbklkXSA9IF8uYmluZChvcGVyYXRpb25PYmplY3QuZXhlY3V0ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRpb25PYmplY3QpO1xuICAgICAgICBzZWxmLmFwaXNbYXBpUHJvcGVydHldW29wZXJhdGlvbklkXS5oZWxwID0gb3BlcmF0aW9uR3JvdXBbb3BlcmF0aW9uSWRdLmhlbHAgPSBfLmJpbmQob3BlcmF0aW9uT2JqZWN0LmhlbHAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRpb25PYmplY3QpO1xuICAgICAgICBzZWxmLmFwaXNbYXBpUHJvcGVydHldW29wZXJhdGlvbklkXS5hc0N1cmwgPSBvcGVyYXRpb25Hcm91cFtvcGVyYXRpb25JZF0uYXNDdXJsID0gXy5iaW5kKG9wZXJhdGlvbk9iamVjdC5hc0N1cmwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uT2JqZWN0KTtcblxuICAgICAgICBvcGVyYXRpb25Hcm91cC5hcGlzW29wZXJhdGlvbklkXSA9IG9wZXJhdGlvbkdyb3VwLm9wZXJhdGlvbnNbb3BlcmF0aW9uSWRdID0gb3BlcmF0aW9uT2JqZWN0O1xuXG4gICAgICAgIC8vIGxlZ2FjeSBVSSBmZWF0dXJlXG4gICAgICAgIHZhciBhcGkgPSBfLmZpbmQoc2VsZi5hcGlzQXJyYXksIGZ1bmN0aW9uIChhcGkpIHtcbiAgICAgICAgICByZXR1cm4gYXBpLnRhZyA9PT0gdGFnO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoYXBpKSB7XG4gICAgICAgICAgYXBpLm9wZXJhdGlvbnNBcnJheS5wdXNoKG9wZXJhdGlvbk9iamVjdCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICAvLyBzb3J0IHRoZSBhcGlzQXJyYXkgYWNjb3JkaW5nIHRvIHRoZSB0YWdzXG4gIHZhciBzb3J0ZWRBcGlzID0gW107XG4gIF8uZm9yRWFjaChPYmplY3Qua2V5cyhkZWZpbmVkVGFncyksIGZ1bmN0aW9uICh0YWcpIHtcbiAgICB2YXIgcG9zO1xuICAgIGZvcihwb3MgaW4gc2VsZi5hcGlzQXJyYXkpIHtcbiAgICAgIHZhciBfYXBpID0gc2VsZi5hcGlzQXJyYXlbcG9zXTtcbiAgICAgIGlmKF9hcGkgJiYgdGFnID09PSBfYXBpLm5hbWUpIHtcbiAgICAgICAgc29ydGVkQXBpcy5wdXNoKF9hcGkpO1xuICAgICAgICBzZWxmLmFwaXNBcnJheVtwb3NdID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuICAvLyBhZGQgYW55dGhpbmcgbGVmdFxuICBfLmZvckVhY2goc2VsZi5hcGlzQXJyYXksIGZ1bmN0aW9uIChhcGkpIHtcbiAgICBpZihhcGkpIHtcbiAgICAgIHNvcnRlZEFwaXMucHVzaChhcGkpO1xuICAgIH1cbiAgfSk7XG4gIHNlbGYuYXBpc0FycmF5ID0gc29ydGVkQXBpcztcblxuICBfLmZvckVhY2gocmVzcG9uc2UuZGVmaW5pdGlvbnMsIGZ1bmN0aW9uIChkZWZpbml0aW9uT2JqLCBkZWZpbml0aW9uKSB7XG4gICAgZGVmaW5pdGlvbk9iai5pZCA9IGRlZmluaXRpb24udG9Mb3dlckNhc2UoKTtcbiAgICBkZWZpbml0aW9uT2JqLm5hbWUgPSBkZWZpbml0aW9uO1xuICAgIHNlbGYubW9kZWxzQXJyYXkucHVzaChkZWZpbml0aW9uT2JqKTtcbiAgfSk7XG5cbiAgdGhpcy5pc0J1aWx0ID0gdHJ1ZTtcblxuICBpZiAodGhpcy51c2VQcm9taXNlKSB7XG4gICAgdGhpcy5pc1ZhbGlkID0gdHJ1ZTtcbiAgICB0aGlzLmlzQnVpbHQgPSB0cnVlO1xuICAgIHRoaXMuZGVmZXJyZWRDbGllbnQucmVzb2x2ZSh0aGlzKTtcblxuICAgIHJldHVybiB0aGlzLmRlZmVycmVkQ2xpZW50LnByb21pc2U7XG4gIH1cblxuICBpZiAodGhpcy5zdWNjZXNzKSB7XG4gICAgdGhpcy5zdWNjZXNzKCk7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLm1ha2VVbmlxdWVPcGVyYXRpb25JZCA9IGZ1bmN0aW9uKG9wZXJhdGlvbklkLCBhcGkpIHtcbiAgdmFyIGNvdW50ID0gMDtcbiAgdmFyIG5hbWUgPSBvcGVyYXRpb25JZDtcblxuICAvLyBtYWtlIHVuaXF1ZSBhY3Jvc3MgdGhpcyBvcGVyYXRpb24gZ3JvdXBcbiAgd2hpbGUodHJ1ZSkge1xuICAgIHZhciBtYXRjaGVkID0gZmFsc2U7XG4gICAgXy5mb3JFYWNoKGFwaS5vcGVyYXRpb25zLCBmdW5jdGlvbiAob3BlcmF0aW9uKSB7XG4gICAgICBpZihvcGVyYXRpb24ubmlja25hbWUgPT09IG5hbWUpIHtcbiAgICAgICAgbWF0Y2hlZCA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gICAgaWYoIW1hdGNoZWQpIHtcbiAgICAgIHJldHVybiBuYW1lO1xuICAgIH1cbiAgICBuYW1lID0gb3BlcmF0aW9uSWQgKyAnXycgKyBjb3VudDtcbiAgICBjb3VudCArKztcbiAgfVxuXG4gIHJldHVybiBvcGVyYXRpb25JZDtcbn07XG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLnBhcnNlVXJpID0gZnVuY3Rpb24gKHVyaSkge1xuICB2YXIgdXJsUGFyc2VSRSA9IC9eKCgoKFteOlxcLyNcXD9dKzopPyg/OihcXC9cXC8pKCg/OigoW146QFxcLyNcXD9dKykoPzpcXDooW146QFxcLyNcXD9dKykpPylAKT8oKFteOlxcLyNcXD9cXF1cXFtdK3xcXFtbXlxcL1xcXUAjP10rXFxdKSg/OlxcOihbMC05XSspKT8pKT8pPyk/KChcXC8/KD86W15cXC9cXD8jXStcXC8rKSopKFteXFw/I10qKSkpPyhcXD9bXiNdKyk/KSgjLiopPy87XG4gIHZhciBwYXJ0cyA9IHVybFBhcnNlUkUuZXhlYyh1cmkpO1xuXG4gIHJldHVybiB7XG4gICAgc2NoZW1lOiBwYXJ0c1s0XSA/IHBhcnRzWzRdLnJlcGxhY2UoJzonLCcnKSA6IHVuZGVmaW5lZCxcbiAgICBob3N0OiBwYXJ0c1sxMV0sXG4gICAgcG9ydDogcGFydHNbMTJdLFxuICAgIHBhdGg6IHBhcnRzWzE1XVxuICB9O1xufTtcblxuU3dhZ2dlckNsaWVudC5wcm90b3R5cGUuaGVscCA9IGZ1bmN0aW9uIChkb250UHJpbnQpIHtcbiAgdmFyIG91dHB1dCA9ICcnO1xuXG4gIGlmICh0aGlzIGluc3RhbmNlb2YgU3dhZ2dlckNsaWVudCkge1xuICAgIF8uZm9yRWFjaCh0aGlzLmFwaXMsIGZ1bmN0aW9uIChhcGksIG5hbWUpIHtcbiAgICAgIGlmIChfLmlzUGxhaW5PYmplY3QoYXBpKSkge1xuICAgICAgICBvdXRwdXQgKz0gJ29wZXJhdGlvbnMgZm9yIHRoZSBcXCcnICsgbmFtZSArICdcXCcgdGFnXFxuJztcblxuICAgICAgICBfLmZvckVhY2goYXBpLm9wZXJhdGlvbnMsIGZ1bmN0aW9uIChvcGVyYXRpb24sIG5hbWUpIHtcbiAgICAgICAgICBvdXRwdXQgKz0gJyAgKiAnICsgbmFtZSArICc6ICcgKyBvcGVyYXRpb24uc3VtbWFyeSArICdcXG4nO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSBlbHNlIGlmICh0aGlzIGluc3RhbmNlb2YgT3BlcmF0aW9uR3JvdXAgfHwgXy5pc1BsYWluT2JqZWN0KHRoaXMpKSB7XG4gICAgb3V0cHV0ICs9ICdvcGVyYXRpb25zIGZvciB0aGUgXFwnJyArIHRoaXMubGFiZWwgKyAnXFwnIHRhZ1xcbic7XG5cbiAgICBfLmZvckVhY2godGhpcy5hcGlzLCBmdW5jdGlvbiAob3BlcmF0aW9uLCBuYW1lKSB7XG4gICAgICBvdXRwdXQgKz0gJyAgKiAnICsgbmFtZSArICc6ICcgKyBvcGVyYXRpb24uc3VtbWFyeSArICdcXG4nO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKGRvbnRQcmludCkge1xuICAgIHJldHVybiBvdXRwdXQ7XG4gIH0gZWxzZSB7XG4gICAgaGVscGVycy5sb2cob3V0cHV0KTtcblxuICAgIHJldHVybiBvdXRwdXQ7XG4gIH1cbn07XG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLnRhZ0Zyb21MYWJlbCA9IGZ1bmN0aW9uIChsYWJlbCkge1xuICByZXR1cm4gbGFiZWw7XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5pZEZyb21PcCA9IGZ1bmN0aW9uIChwYXRoLCBodHRwTWV0aG9kLCBvcCkge1xuICBpZighb3AgfHwgIW9wLm9wZXJhdGlvbklkKSB7XG4gICAgb3AgPSBvcCB8fCB7fTtcbiAgICBvcC5vcGVyYXRpb25JZCA9IGh0dHBNZXRob2QgKyAnXycgKyBwYXRoO1xuICB9XG4gIHZhciBvcElkID0gb3Aub3BlcmF0aW9uSWQucmVwbGFjZSgvW1xccyFAIyQlXiYqKClfKz1cXFt7XFxdfTs6PD58LlxcLz8sXFxcXCdcIlwiLV0vZywgJ18nKSB8fCAocGF0aC5zdWJzdHJpbmcoMSkgKyAnXycgKyBodHRwTWV0aG9kKTtcblxuICBvcElkID0gb3BJZC5yZXBsYWNlKC8oKF8pezIsfSkvZywgJ18nKTtcbiAgb3BJZCA9IG9wSWQucmVwbGFjZSgvXihfKSovZywgJycpO1xuICBvcElkID0gb3BJZC5yZXBsYWNlKC8oW19dKSokL2csICcnKTtcblxuICByZXR1cm4gb3BJZDtcbn07XG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLnNldEhvc3QgPSBmdW5jdGlvbiAoaG9zdCkge1xuICB0aGlzLmhvc3QgPSBob3N0O1xuXG4gIGlmKHRoaXMuYXBpcykge1xuICAgIF8uZm9yRWFjaCh0aGlzLmFwaXMsIGZ1bmN0aW9uKGFwaSkge1xuICAgICAgaWYoYXBpLm9wZXJhdGlvbnMpIHtcbiAgICAgICAgXy5mb3JFYWNoKGFwaS5vcGVyYXRpb25zLCBmdW5jdGlvbihvcGVyYXRpb24pIHtcbiAgICAgICAgICBvcGVyYXRpb24uaG9zdCA9IGhvc3Q7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5zZXRCYXNlUGF0aCA9IGZ1bmN0aW9uIChiYXNlUGF0aCkge1xuICB0aGlzLmJhc2VQYXRoID0gYmFzZVBhdGg7XG5cbiAgaWYodGhpcy5hcGlzKSB7XG4gICAgXy5mb3JFYWNoKHRoaXMuYXBpcywgZnVuY3Rpb24oYXBpKSB7XG4gICAgICBpZihhcGkub3BlcmF0aW9ucykge1xuICAgICAgICBfLmZvckVhY2goYXBpLm9wZXJhdGlvbnMsIGZ1bmN0aW9uKG9wZXJhdGlvbikge1xuICAgICAgICAgIG9wZXJhdGlvbi5iYXNlUGF0aCA9IGJhc2VQYXRoO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufTtcblxuU3dhZ2dlckNsaWVudC5wcm90b3R5cGUuc2V0U2NoZW1lcyA9IGZ1bmN0aW9uIChzY2hlbWVzKSB7XG4gIHRoaXMuc2NoZW1lcyA9IHNjaGVtZXM7XG5cbiAgaWYoc2NoZW1lcyAmJiBzY2hlbWVzLmxlbmd0aCA+IDApIHtcbiAgICBpZih0aGlzLmFwaXMpIHtcbiAgICAgIF8uZm9yRWFjaCh0aGlzLmFwaXMsIGZ1bmN0aW9uIChhcGkpIHtcbiAgICAgICAgaWYgKGFwaS5vcGVyYXRpb25zKSB7XG4gICAgICAgICAgXy5mb3JFYWNoKGFwaS5vcGVyYXRpb25zLCBmdW5jdGlvbiAob3BlcmF0aW9uKSB7XG4gICAgICAgICAgICBvcGVyYXRpb24uc2NoZW1lID0gc2NoZW1lc1swXTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5mYWlsID0gZnVuY3Rpb24gKG1lc3NhZ2UpIHtcbiAgaWYgKHRoaXMudXNlUHJvbWlzZSkge1xuICAgIHRoaXMuZGVmZXJyZWRDbGllbnQucmVqZWN0KG1lc3NhZ2UpO1xuICAgIHJldHVybiB0aGlzLmRlZmVycmVkQ2xpZW50LnByb21pc2U7XG4gIH0gZWxzZSB7XG4gICAgaWYgKHRoaXMuZmFpbHVyZSkge1xuICAgICAgdGhpcy5mYWlsdXJlKG1lc3NhZ2UpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHRoaXMuZmFpbHVyZShtZXNzYWdlKTtcbiAgICB9XG4gIH1cbn07XG4iLCIoZnVuY3Rpb24gKHByb2Nlc3Mpe1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgXyA9IHtcbiAgaXNQbGFpbk9iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzUGxhaW5PYmplY3QnKSxcbiAgaW5kZXhPZjogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9hcnJheS9pbmRleE9mJylcbn07XG5cbm1vZHVsZS5leHBvcnRzLl9fYmluZCA9IGZ1bmN0aW9uIChmbiwgbWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCl7XG4gICAgcmV0dXJuIGZuLmFwcGx5KG1lLCBhcmd1bWVudHMpO1xuICB9O1xufTtcblxudmFyIGxvZyA9IG1vZHVsZS5leHBvcnRzLmxvZyA9IGZ1bmN0aW9uKCkge1xuICAvLyBPbmx5IGxvZyBpZiBhdmFpbGFibGUgYW5kIHdlJ3JlIG5vdCB0ZXN0aW5nXG4gIGlmIChjb25zb2xlICYmIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAndGVzdCcpIHtcbiAgICBjb25zb2xlLmxvZyhBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpWzBdKTtcbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMuZmFpbCA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gIGxvZyhtZXNzYWdlKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzLm9wdGlvbkh0bWwgPSBmdW5jdGlvbiAobGFiZWwsIHZhbHVlKSB7XG4gIHJldHVybiAnPHRyPjx0ZCBjbGFzcz1cIm9wdGlvbk5hbWVcIj4nICsgbGFiZWwgKyAnOjwvdGQ+PHRkPicgKyB2YWx1ZSArICc8L3RkPjwvdHI+Jztcbn07XG5cbnZhciByZXNvbHZlU2NoZW1hID0gbW9kdWxlLmV4cG9ydHMucmVzb2x2ZVNjaGVtYSA9IGZ1bmN0aW9uIChzY2hlbWEpIHtcbiAgaWYgKF8uaXNQbGFpbk9iamVjdChzY2hlbWEuc2NoZW1hKSkge1xuICAgIHNjaGVtYSA9IHJlc29sdmVTY2hlbWEoc2NoZW1hLnNjaGVtYSk7XG4gIH1cblxuICByZXR1cm4gc2NoZW1hO1xufTtcblxubW9kdWxlLmV4cG9ydHMuc2ltcGxlUmVmID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgaWYgKHR5cGVvZiBuYW1lID09PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKG5hbWUuaW5kZXhPZignIy9kZWZpbml0aW9ucy8nKSA9PT0gMCkge1xuICAgIHJldHVybiBuYW1lLnN1YnN0cmluZygnIy9kZWZpbml0aW9ucy8nLmxlbmd0aCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG5hbWU7XG4gIH1cbn07XG5cbi8qKlxuICogaGVscGVyIHRvIHJlbW92ZSBleHRlbnNpb25zIGFuZCBhZGQgdGhlbSB0byBhbiBvYmplY3RcbiAqXG4gKiBAcGFyYW0ga2V5bmFtZVxuICogQHBhcmFtIG9ialxuICovXG5tb2R1bGUuZXhwb3J0cy5leHRyYWN0RXh0ZW5zaW9ucyA9IGZ1bmN0aW9uIChrZXluYW1lLCBvYmosIHZhbHVlKSB7XG4gIGlmKCFrZXluYW1lIHx8ICFvYmopIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAodHlwZW9mIGtleW5hbWUgPT09ICdzdHJpbmcnICYmIGtleW5hbWUuaW5kZXhPZigneC0nKSA9PT0gMCkge1xuICAgIG9iai52ZW5kb3JFeHRlbnNpb25zID0gb2JqLnZlbmRvckV4dGVuc2lvbnMgfHwge307XG4gICAgaWYodmFsdWUpIHtcbiAgICAgIG9iai52ZW5kb3JFeHRlbnNpb25zW2tleW5hbWVdID0gdmFsdWU7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgb2JqLnZlbmRvckV4dGVuc2lvbnNba2V5bmFtZV0gPSBvYmpba2V5bmFtZV07XG4gICAgfVxuICB9XG59O1xufSkuY2FsbCh0aGlzLHJlcXVpcmUoJ19wcm9jZXNzJykpXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbXhwWWk5b1pXeHdaWEp6TG1weklsMHNJbTVoYldWeklqcGJYU3dpYldGd2NHbHVaM01pT2lJN1FVRkJRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRWlMQ0ptYVd4bElqb2laMlZ1WlhKaGRHVmtMbXB6SWl3aWMyOTFjbU5sVW05dmRDSTZJaUlzSW5OdmRYSmpaWE5EYjI1MFpXNTBJanBiSWlkMWMyVWdjM1J5YVdOMEp6dGNibHh1ZG1GeUlGOGdQU0I3WEc0Z0lHbHpVR3hoYVc1UFltcGxZM1E2SUhKbGNYVnBjbVVvSjJ4dlpHRnphQzFqYjIxd1lYUXZiR0Z1Wnk5cGMxQnNZV2x1VDJKcVpXTjBKeWtzWEc0Z0lHbHVaR1Y0VDJZNklISmxjWFZwY21Vb0oyeHZaR0Z6YUMxamIyMXdZWFF2WVhKeVlYa3ZhVzVrWlhoUFppY3BYRzU5TzF4dVhHNXRiMlIxYkdVdVpYaHdiM0owY3k1ZlgySnBibVFnUFNCbWRXNWpkR2x2YmlBb1ptNHNJRzFsS1NCN1hHNGdJSEpsZEhWeWJpQm1kVzVqZEdsdmJpZ3BlMXh1SUNBZ0lISmxkSFZ5YmlCbWJpNWhjSEJzZVNodFpTd2dZWEpuZFcxbGJuUnpLVHRjYmlBZ2ZUdGNibjA3WEc1Y2JuWmhjaUJzYjJjZ1BTQnRiMlIxYkdVdVpYaHdiM0owY3k1c2IyY2dQU0JtZFc1amRHbHZiaWdwSUh0Y2JpQWdMeThnVDI1c2VTQnNiMmNnYVdZZ1lYWmhhV3hoWW14bElHRnVaQ0IzWlNkeVpTQnViM1FnZEdWemRHbHVaMXh1SUNCcFppQW9ZMjl1YzI5c1pTQW1KaUJ3Y205alpYTnpMbVZ1ZGk1T1QwUkZYMFZPVmlBaFBUMGdKM1JsYzNRbktTQjdYRzRnSUNBZ1kyOXVjMjlzWlM1c2IyY29RWEp5WVhrdWNISnZkRzkwZVhCbExuTnNhV05sTG1OaGJHd29ZWEpuZFcxbGJuUnpLVnN3WFNrN1hHNGdJSDFjYm4wN1hHNWNibTF2WkhWc1pTNWxlSEJ2Y25SekxtWmhhV3dnUFNCbWRXNWpkR2x2YmlBb2JXVnpjMkZuWlNrZ2UxeHVJQ0JzYjJjb2JXVnpjMkZuWlNrN1hHNTlPMXh1WEc1dGIyUjFiR1V1Wlhod2IzSjBjeTV2Y0hScGIyNUlkRzFzSUQwZ1puVnVZM1JwYjI0Z0tHeGhZbVZzTENCMllXeDFaU2tnZTF4dUlDQnlaWFIxY200Z0p6eDBjajQ4ZEdRZ1kyeGhjM005WENKdmNIUnBiMjVPWVcxbFhDSStKeUFySUd4aFltVnNJQ3NnSnpvOEwzUmtQangwWkQ0bklDc2dkbUZzZFdVZ0t5QW5QQzkwWkQ0OEwzUnlQaWM3WEc1OU8xeHVYRzUyWVhJZ2NtVnpiMngyWlZOamFHVnRZU0E5SUcxdlpIVnNaUzVsZUhCdmNuUnpMbkpsYzI5c2RtVlRZMmhsYldFZ1BTQm1kVzVqZEdsdmJpQW9jMk5vWlcxaEtTQjdYRzRnSUdsbUlDaGZMbWx6VUd4aGFXNVBZbXBsWTNRb2MyTm9aVzFoTG5OamFHVnRZU2twSUh0Y2JpQWdJQ0J6WTJobGJXRWdQU0J5WlhOdmJIWmxVMk5vWlcxaEtITmphR1Z0WVM1elkyaGxiV0VwTzF4dUlDQjlYRzVjYmlBZ2NtVjBkWEp1SUhOamFHVnRZVHRjYm4wN1hHNWNibTF2WkhWc1pTNWxlSEJ2Y25SekxuTnBiWEJzWlZKbFppQTlJR1oxYm1OMGFXOXVJQ2h1WVcxbEtTQjdYRzRnSUdsbUlDaDBlWEJsYjJZZ2JtRnRaU0E5UFQwZ0ozVnVaR1ZtYVc1bFpDY3BJSHRjYmlBZ0lDQnlaWFIxY200Z2JuVnNiRHRjYmlBZ2ZWeHVYRzRnSUdsbUlDaHVZVzFsTG1sdVpHVjRUMllvSnlNdlpHVm1hVzVwZEdsdmJuTXZKeWtnUFQwOUlEQXBJSHRjYmlBZ0lDQnlaWFIxY200Z2JtRnRaUzV6ZFdKemRISnBibWNvSnlNdlpHVm1hVzVwZEdsdmJuTXZKeTVzWlc1bmRHZ3BPMXh1SUNCOUlHVnNjMlVnZTF4dUlDQWdJSEpsZEhWeWJpQnVZVzFsTzF4dUlDQjlYRzU5TzF4dVhHNHZLaXBjYmlBcUlHaGxiSEJsY2lCMGJ5QnlaVzF2ZG1VZ1pYaDBaVzV6YVc5dWN5QmhibVFnWVdSa0lIUm9aVzBnZEc4Z1lXNGdiMkpxWldOMFhHNGdLbHh1SUNvZ1FIQmhjbUZ0SUd0bGVXNWhiV1ZjYmlBcUlFQndZWEpoYlNCdlltcGNiaUFxTDF4dWJXOWtkV3hsTG1WNGNHOXlkSE11WlhoMGNtRmpkRVY0ZEdWdWMybHZibk1nUFNCbWRXNWpkR2x2YmlBb2EyVjVibUZ0WlN3Z2IySnFMQ0IyWVd4MVpTa2dlMXh1SUNCcFppZ2hhMlY1Ym1GdFpTQjhmQ0FoYjJKcUtTQjdYRzRnSUNBZ2NtVjBkWEp1TzF4dUlDQjlYRzVjYmlBZ2FXWWdLSFI1Y0dWdlppQnJaWGx1WVcxbElEMDlQU0FuYzNSeWFXNW5KeUFtSmlCclpYbHVZVzFsTG1sdVpHVjRUMllvSjNndEp5a2dQVDA5SURBcElIdGNiaUFnSUNCdlltb3VkbVZ1Wkc5eVJYaDBaVzV6YVc5dWN5QTlJRzlpYWk1MlpXNWtiM0pGZUhSbGJuTnBiMjV6SUh4OElIdDlPMXh1SUNBZ0lHbG1LSFpoYkhWbEtTQjdYRzRnSUNBZ0lDQnZZbW91ZG1WdVpHOXlSWGgwWlc1emFXOXVjMXRyWlhsdVlXMWxYU0E5SUhaaGJIVmxPMXh1SUNBZ0lIMWNiaUFnSUNCbGJITmxJSHRjYmlBZ0lDQWdJRzlpYWk1MlpXNWtiM0pGZUhSbGJuTnBiMjV6VzJ0bGVXNWhiV1ZkSUQwZ2IySnFXMnRsZVc1aGJXVmRPMXh1SUNBZ0lIMWNiaUFnZlZ4dWZUc2lYWDA9IiwiKGZ1bmN0aW9uIChCdWZmZXIpe1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4vaGVscGVycycpO1xudmFyIHJlcXVlc3QgPSByZXF1aXJlKCdzdXBlcmFnZW50Jyk7XG52YXIganN5YW1sID0gcmVxdWlyZSgnanMteWFtbCcpO1xudmFyIF8gPSB7XG4gIGlzT2JqZWN0OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNPYmplY3QnKSxcbiAga2V5czogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9vYmplY3Qva2V5cycpXG59O1xuXG4vKlxuICogSlF1ZXJ5SHR0cENsaWVudCBpcyBhIGxpZ2h0LXdlaWdodCwgbm9kZSBvciBicm93c2VyIEhUVFAgY2xpZW50XG4gKi9cbnZhciBKUXVlcnlIdHRwQ2xpZW50ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLnR5cGUgPSAnSlF1ZXJ5SHR0cENsaWVudCc7XG59O1xuXG4vKlxuICogU3VwZXJhZ2VudEh0dHBDbGllbnQgaXMgYSBsaWdodC13ZWlnaHQsIG5vZGUgb3IgYnJvd3NlciBIVFRQIGNsaWVudFxuICovXG52YXIgU3VwZXJhZ2VudEh0dHBDbGllbnQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMudHlwZSA9ICdTdXBlcmFnZW50SHR0cENsaWVudCc7XG59O1xuXG4vKipcbiAqIFN3YWdnZXJIdHRwIGlzIGEgd3JhcHBlciBmb3IgZXhlY3V0aW5nIHJlcXVlc3RzXG4gKi9cbnZhciBTd2FnZ2VySHR0cCA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge307XG5cblN3YWdnZXJIdHRwLnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24gKG9iaiwgb3B0cykge1xuICB2YXIgY2xpZW50O1xuXG4gIGlmKG9wdHMgJiYgb3B0cy5jbGllbnQpIHtcbiAgICBjbGllbnQgPSBvcHRzLmNsaWVudDtcbiAgfVxuICBlbHNlIHtcbiAgICBjbGllbnQgPSBuZXcgU3VwZXJhZ2VudEh0dHBDbGllbnQob3B0cyk7XG4gIH1cbiAgY2xpZW50Lm9wdHMgPSBvcHRzIHx8IHt9O1xuXG4gIGlmIChvcHRzICYmIG9wdHMucmVxdWVzdEFnZW50KSB7XG4gICAgcmVxdWVzdCA9IG9wdHMucmVxdWVzdEFnZW50O1xuICB9XG5cbiAgLy8gbGVnYWN5IHN1cHBvcnRcbiAgdmFyIGhhc0pRdWVyeSA9IGZhbHNlO1xuICBpZih0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuICAgIGlmKHR5cGVvZiB3aW5kb3cualF1ZXJ5ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgaGFzSlF1ZXJ5ID0gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgLy8gT1BUSU9OUyBzdXBwb3J0XG4gIGlmKG9iai5tZXRob2QudG9Mb3dlckNhc2UoKSA9PT0gJ29wdGlvbnMnICYmIGNsaWVudC50eXBlID09PSAnU3VwZXJhZ2VudEh0dHBDbGllbnQnKSB7XG4gICAgbG9nKCdmb3JjaW5nIGpRdWVyeSBhcyBPUFRJT05TIGFyZSBub3Qgc3VwcG9ydGVkIGJ5IFN1cGVyQWdlbnQnKTtcbiAgICBvYmoudXNlSlF1ZXJ5ID0gdHJ1ZTtcbiAgfVxuICBpZih0aGlzLmlzSW50ZXJuZXRFeHBsb3JlcigpICYmIChvYmoudXNlSlF1ZXJ5ID09PSBmYWxzZSB8fCAhaGFzSlF1ZXJ5ICkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIGNvbmZpZ3VyYXRpb24hIEpRdWVyeSBpcyByZXF1aXJlZCBidXQgbm90IGF2YWlsYWJsZScpO1xuICB9XG4gIGlmICgob2JqICYmIG9iai51c2VKUXVlcnkgPT09IHRydWUpIHx8IHRoaXMuaXNJbnRlcm5ldEV4cGxvcmVyKCkgJiYgaGFzSlF1ZXJ5KSB7XG4gICAgY2xpZW50ID0gbmV3IEpRdWVyeUh0dHBDbGllbnQob3B0cyk7XG4gIH1cblxuICB2YXIgc3VjY2VzcyA9IG9iai5vbi5yZXNwb25zZTtcbiAgdmFyIGVycm9yID0gb2JqLm9uLmVycm9yO1xuXG4gIHZhciByZXF1ZXN0SW50ZXJjZXB0b3IgPSBmdW5jdGlvbihkYXRhKSB7XG4gICAgaWYob3B0cyAmJiBvcHRzLnJlcXVlc3RJbnRlcmNlcHRvcikge1xuICAgICAgZGF0YSA9IG9wdHMucmVxdWVzdEludGVyY2VwdG9yLmFwcGx5KGRhdGEpO1xuICAgIH1cbiAgICByZXR1cm4gZGF0YTtcbiAgfTtcblxuICB2YXIgcmVzcG9uc2VJbnRlcmNlcHRvciA9IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICBpZihvcHRzICYmIG9wdHMucmVzcG9uc2VJbnRlcmNlcHRvcikge1xuICAgICAgZGF0YSA9IG9wdHMucmVzcG9uc2VJbnRlcmNlcHRvci5hcHBseShkYXRhLCBbb2JqXSk7XG4gICAgfVxuICAgIHJldHVybiBzdWNjZXNzKGRhdGEpO1xuICB9O1xuXG4gIHZhciBlcnJvckludGVyY2VwdG9yID0gZnVuY3Rpb24oZGF0YSkge1xuICAgIGlmKG9wdHMgJiYgb3B0cy5yZXNwb25zZUludGVyY2VwdG9yKSB7XG4gICAgICBkYXRhID0gb3B0cy5yZXNwb25zZUludGVyY2VwdG9yLmFwcGx5KGRhdGEsIFtvYmpdKTtcbiAgICB9XG4gICAgZXJyb3IoZGF0YSk7XG4gIH07XG5cbiAgb2JqLm9uLmVycm9yID0gZnVuY3Rpb24oZGF0YSkge1xuICAgIGVycm9ySW50ZXJjZXB0b3IoZGF0YSk7XG4gIH07XG5cbiAgb2JqLm9uLnJlc3BvbnNlID0gZnVuY3Rpb24oZGF0YSkge1xuICAgIGlmKGRhdGEgJiYgZGF0YS5zdGF0dXMgPj0gNDAwKSB7XG4gICAgICBlcnJvckludGVyY2VwdG9yKGRhdGEpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHJlc3BvbnNlSW50ZXJjZXB0b3IoZGF0YSk7XG4gICAgfVxuICB9O1xuXG4gIGlmIChfLmlzT2JqZWN0KG9iaikgJiYgXy5pc09iamVjdChvYmouYm9keSkpIHtcbiAgICAvLyBzcGVjaWFsIHByb2Nlc3NpbmcgZm9yIGZpbGUgdXBsb2FkcyB2aWEganF1ZXJ5XG4gICAgaWYgKG9iai5ib2R5LnR5cGUgJiYgb2JqLmJvZHkudHlwZSA9PT0gJ2Zvcm1EYXRhJyl7XG4gICAgICBpZihvcHRzLnVzZUpRdWVyeSkge1xuICAgICAgICBvYmouY29udGVudFR5cGUgPSBmYWxzZTtcbiAgICAgICAgb2JqLnByb2Nlc3NEYXRhID0gZmFsc2U7XG4gICAgICAgIGRlbGV0ZSBvYmouaGVhZGVyc1snQ29udGVudC1UeXBlJ107XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgb2JqID0gcmVxdWVzdEludGVyY2VwdG9yKG9iaikgfHwgb2JqO1xuICBpZiAob2JqLmJlZm9yZVNlbmQpIHtcbiAgICBvYmouYmVmb3JlU2VuZChmdW5jdGlvbihfb2JqKSB7XG4gICAgICBjbGllbnQuZXhlY3V0ZShfb2JqIHx8IG9iaik7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgY2xpZW50LmV4ZWN1dGUob2JqKTtcbiAgfVxuXG4gIHJldHVybiAob2JqLmRlZmVycmVkKSA/IG9iai5kZWZlcnJlZC5wcm9taXNlIDogb2JqO1xufTtcblxuU3dhZ2dlckh0dHAucHJvdG90eXBlLmlzSW50ZXJuZXRFeHBsb3JlciA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGRldGVjdGVkSUUgPSBmYWxzZTtcblxuICBpZiAodHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcgJiYgbmF2aWdhdG9yLnVzZXJBZ2VudCkge1xuICAgIHZhciBuYXYgPSBuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCk7XG5cbiAgICBpZiAobmF2LmluZGV4T2YoJ21zaWUnKSAhPT0gLTEpIHtcbiAgICAgIHZhciB2ZXJzaW9uID0gcGFyc2VJbnQobmF2LnNwbGl0KCdtc2llJylbMV0pO1xuXG4gICAgICBpZiAodmVyc2lvbiA8PSA4KSB7XG4gICAgICAgIGRldGVjdGVkSUUgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBkZXRlY3RlZElFO1xufTtcblxuSlF1ZXJ5SHR0cENsaWVudC5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgdmFyIGpxID0gdGhpcy5qUXVlcnkgfHwgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdy5qUXVlcnkpO1xuICB2YXIgY2IgPSBvYmoub247XG4gIHZhciByZXF1ZXN0ID0gb2JqO1xuXG4gIGlmKHR5cGVvZiBqcSA9PT0gJ3VuZGVmaW5lZCcgfHwganEgPT09IGZhbHNlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBjb25maWd1cmF0aW9uISBKUXVlcnkgaXMgcmVxdWlyZWQgYnV0IG5vdCBhdmFpbGFibGUnKTtcbiAgfVxuXG4gIG9iai50eXBlID0gb2JqLm1ldGhvZDtcbiAgb2JqLmNhY2hlID0gb2JqLmpxdWVyeUFqYXhDYWNoZTtcbiAgb2JqLmRhdGEgPSBvYmouYm9keTtcbiAgZGVsZXRlIG9iai5qcXVlcnlBamF4Q2FjaGU7XG4gIGRlbGV0ZSBvYmoudXNlSlF1ZXJ5O1xuICBkZWxldGUgb2JqLmJvZHk7XG5cbiAgb2JqLmNvbXBsZXRlID0gZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgdmFyIGhlYWRlcnMgPSB7fTtcbiAgICB2YXIgaGVhZGVyQXJyYXkgPSByZXNwb25zZS5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKS5zcGxpdCgnXFxuJyk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGhlYWRlckFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgdG9TcGxpdCA9IGhlYWRlckFycmF5W2ldLnRyaW0oKTtcblxuICAgICAgaWYgKHRvU3BsaXQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICB2YXIgc2VwYXJhdG9yID0gdG9TcGxpdC5pbmRleE9mKCc6Jyk7XG5cbiAgICAgIGlmIChzZXBhcmF0b3IgPT09IC0xKSB7XG4gICAgICAgIC8vIE5hbWUgYnV0IG5vIHZhbHVlIGluIHRoZSBoZWFkZXJcbiAgICAgICAgaGVhZGVyc1t0b1NwbGl0XSA9IG51bGw7XG5cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHZhciBuYW1lID0gdG9TcGxpdC5zdWJzdHJpbmcoMCwgc2VwYXJhdG9yKS50cmltKCk7XG4gICAgICB2YXIgdmFsdWUgPSB0b1NwbGl0LnN1YnN0cmluZyhzZXBhcmF0b3IgKyAxKS50cmltKCk7XG5cbiAgICAgIGhlYWRlcnNbbmFtZV0gPSB2YWx1ZTtcbiAgICB9XG5cbiAgICB2YXIgb3V0ID0ge1xuICAgICAgdXJsOiByZXF1ZXN0LnVybCxcbiAgICAgIG1ldGhvZDogcmVxdWVzdC5tZXRob2QsXG4gICAgICBzdGF0dXM6IHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgIHN0YXR1c1RleHQ6IHJlc3BvbnNlLnN0YXR1c1RleHQsXG4gICAgICBkYXRhOiByZXNwb25zZS5yZXNwb25zZVRleHQsXG4gICAgICBoZWFkZXJzOiBoZWFkZXJzXG4gICAgfTtcblxuICAgIHRyeSB7XG4gICAgICB2YXIgcG9zc2libGVPYmogPSAgcmVzcG9uc2UucmVzcG9uc2VKU09OIHx8IGpzeWFtbC5zYWZlTG9hZChyZXNwb25zZS5yZXNwb25zZVRleHQpO1xuICAgICAgb3V0Lm9iaiA9ICh0eXBlb2YgcG9zc2libGVPYmogPT09ICdzdHJpbmcnKSA/IHt9IDogcG9zc2libGVPYmo7XG4gICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgIC8vIGRvIG5vdCBzZXQgb3V0Lm9ialxuICAgICAgaGVscGVycy5sb2coJ3VuYWJsZSB0byBwYXJzZSBKU09OL1lBTUwgY29udGVudCcpO1xuICAgIH1cblxuICAgIC8vIEkgY2FuIHRocm93LCBvciBwYXJzZSBudWxsP1xuICAgIG91dC5vYmogPSBvdXQub2JqIHx8IG51bGw7XG5cbiAgICBpZiAocmVzcG9uc2Uuc3RhdHVzID49IDIwMCAmJiByZXNwb25zZS5zdGF0dXMgPCAzMDApIHtcbiAgICAgIGNiLnJlc3BvbnNlKG91dCk7XG4gICAgfSBlbHNlIGlmIChyZXNwb25zZS5zdGF0dXMgPT09IDAgfHwgKHJlc3BvbnNlLnN0YXR1cyA+PSA0MDAgJiYgcmVzcG9uc2Uuc3RhdHVzIDwgNTk5KSkge1xuICAgICAgY2IuZXJyb3Iob3V0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGNiLnJlc3BvbnNlKG91dCk7XG4gICAgfVxuICB9O1xuXG4gIGpxLnN1cHBvcnQuY29ycyA9IHRydWU7XG5cbiAgcmV0dXJuIGpxLmFqYXgob2JqKTtcbn07XG5cblN1cGVyYWdlbnRIdHRwQ2xpZW50LnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24gKG9iaikge1xuICB2YXIgbWV0aG9kID0gb2JqLm1ldGhvZC50b0xvd2VyQ2FzZSgpO1xuICB2YXIgdGltZW91dCA9IG9iai50aW1lb3V0O1xuXG4gIGlmIChtZXRob2QgPT09ICdkZWxldGUnKSB7XG4gICAgbWV0aG9kID0gJ2RlbCc7XG4gIH1cbiAgdmFyIGhlYWRlcnMgPSBvYmouaGVhZGVycyB8fCB7fTtcblxuICB2YXIgciA9IHJlcXVlc3RbbWV0aG9kXShvYmoudXJsKTtcblxuICBpZiAob2JqLmNvbm5lY3Rpb25BZ2VudCkge1xuICAgIHIuYWdlbnQob2JqLmNvbm5lY3Rpb25BZ2VudCk7XG4gIH1cblxuICBpZiAodGltZW91dCkge1xuICAgIHIudGltZW91dCh0aW1lb3V0KTtcbiAgfVxuXG4gIGlmIChvYmouZW5hYmxlQ29va2llcykge1xuICAgIHIud2l0aENyZWRlbnRpYWxzKCk7XG4gIH1cblxuICB2YXIgYWNjZXB0ID0gb2JqLmhlYWRlcnMuQWNjZXB0O1xuXG4gIGlmKHRoaXMuYmluYXJ5UmVxdWVzdChhY2NlcHQpKSB7XG4gICAgci5vbigncmVxdWVzdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmKHRoaXMueGhyKSB7XG4gICAgICAgIHRoaXMueGhyLnJlc3BvbnNlVHlwZSA9ICdibG9iJztcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGlmKG9iai5ib2R5KSB7XG4gICAgaWYoXy5pc09iamVjdChvYmouYm9keSkpIHtcbiAgICAgIHZhciBjb250ZW50VHlwZSA9IG9iai5oZWFkZXJzWydDb250ZW50LVR5cGUnXSB8fCAnJztcbiAgICAgIGlmIChjb250ZW50VHlwZS5pbmRleE9mKCdtdWx0aXBhcnQvZm9ybS1kYXRhJykgPT09IDApIHtcbiAgICAgICAgZGVsZXRlIGhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddO1xuICAgICAgICBpZih7fS50b1N0cmluZy5hcHBseShvYmouYm9keSkgPT09ICdbb2JqZWN0IEZvcm1EYXRhXScpIHtcbiAgICAgICAgICByLnNlbmQob2JqLmJvZHkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHZhciBrZXluYW1lLCB2YWx1ZSwgdjtcbiAgICAgICAgICBmb3IgKGtleW5hbWUgaW4gb2JqLmJvZHkpIHtcbiAgICAgICAgICAgIHZhbHVlID0gb2JqLmJvZHlba2V5bmFtZV07XG4gICAgICAgICAgICBpZihBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgICBmb3IodiBpbiB2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHIuZmllbGQoa2V5bmFtZSwgdik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICByLmZpZWxkKGtleW5hbWUsIHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKF8uaXNPYmplY3Qob2JqLmJvZHkpKSB7XG4gICAgICAgIC8vIG5vbiBtdWx0aXBhcnQvZm9ybS1kYXRhXG4gICAgICAgIG9iai5ib2R5ID0gSlNPTi5zdHJpbmdpZnkob2JqLmJvZHkpO1xuICAgICAgICByLnNlbmQob2JqLmJvZHkpO1xuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHIuc2VuZChvYmouYm9keSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIG5hbWU7XG4gIGZvciAobmFtZSBpbiBoZWFkZXJzKSB7XG4gICAgci5zZXQobmFtZSwgaGVhZGVyc1tuYW1lXSk7XG4gIH1cblxuICBpZih0eXBlb2Ygci5idWZmZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICByLmJ1ZmZlcigpOyAvLyBmb3JjZSBzdXBlcmFnZW50IHRvIHBvcHVsYXRlIHJlcy50ZXh0IHdpdGggdGhlIHJhdyByZXNwb25zZSBkYXRhXG4gIH1cblxuICByLmVuZChmdW5jdGlvbiAoZXJyLCByZXMpIHtcbiAgICByZXMgPSByZXMgfHwge1xuICAgICAgc3RhdHVzOiAwLFxuICAgICAgaGVhZGVyczoge2Vycm9yOiAnbm8gcmVzcG9uc2UgZnJvbSBzZXJ2ZXInfVxuICAgIH07XG4gICAgdmFyIHJlc3BvbnNlID0ge1xuICAgICAgdXJsOiBvYmoudXJsLFxuICAgICAgbWV0aG9kOiBvYmoubWV0aG9kLFxuICAgICAgaGVhZGVyczogcmVzLmhlYWRlcnNcbiAgICB9O1xuICAgIHZhciBjYjtcblxuICAgIGlmICghZXJyICYmIHJlcy5lcnJvcikge1xuICAgICAgZXJyID0gcmVzLmVycm9yO1xuICAgIH1cblxuICAgIGlmIChlcnIgJiYgb2JqLm9uICYmIG9iai5vbi5lcnJvcikge1xuICAgICAgcmVzcG9uc2UuZXJyT2JqID0gZXJyO1xuICAgICAgcmVzcG9uc2Uuc3RhdHVzID0gcmVzID8gcmVzLnN0YXR1cyA6IDUwMDtcbiAgICAgIHJlc3BvbnNlLnN0YXR1c1RleHQgPSByZXMgPyByZXMudGV4dCA6IGVyci5tZXNzYWdlO1xuICAgICAgaWYgKHJlcy5oZWFkZXJzICYmIHJlcy5oZWFkZXJzWydjb250ZW50LXR5cGUnXSkge1xuICAgICAgICBpZiAocmVzLmhlYWRlcnNbJ2NvbnRlbnQtdHlwZSddLmluZGV4T2YoJ2FwcGxpY2F0aW9uL2pzb24nKSA+PSAwKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJlc3BvbnNlLm9iaiA9IEpTT04ucGFyc2UocmVzcG9uc2Uuc3RhdHVzVGV4dCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICByZXNwb25zZS5vYmogPSBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY2IgPSBvYmoub24uZXJyb3I7XG4gICAgfSBlbHNlIGlmIChyZXMgJiYgb2JqLm9uICYmIG9iai5vbi5yZXNwb25zZSkge1xuICAgICAgdmFyIHBvc3NpYmxlT2JqO1xuXG4gICAgICAvLyBBbHJlYWR5IHBhcnNlZCBieSBieSBzdXBlcmFnZW50P1xuICAgICAgaWYgKHJlcy5ib2R5ICYmIF8ua2V5cyhyZXMuYm9keSkubGVuZ3RoID4gMCkge1xuICAgICAgICBwb3NzaWJsZU9iaiA9IHJlcy5ib2R5O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBwb3NzaWJsZU9iaiA9IGpzeWFtbC5zYWZlTG9hZChyZXMudGV4dCk7XG4gICAgICAgICAgLy8gY2FuIHBhcnNlIGludG8gYSBzdHJpbmcuLi4gd2hpY2ggd2UgZG9uJ3QgbmVlZCBydW5uaW5nIGFyb3VuZCBpbiB0aGUgc3lzdGVtXG4gICAgICAgICAgcG9zc2libGVPYmogPSAodHlwZW9mIHBvc3NpYmxlT2JqID09PSAnc3RyaW5nJykgPyBudWxsIDogcG9zc2libGVPYmo7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBoZWxwZXJzLmxvZygnY2Fubm90IHBhcnNlIEpTT04vWUFNTCBjb250ZW50Jyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gbnVsbCBtZWFucyB3ZSBjYW4ndCBwYXJzZSBpbnRvIG9iamVjdFxuICAgICAgaWYodHlwZW9mIEJ1ZmZlciA9PT0gJ2Z1bmN0aW9uJyAmJiBCdWZmZXIuaXNCdWZmZXIocG9zc2libGVPYmopKSB7XG4gICAgICAgIHJlc3BvbnNlLmRhdGEgPSBwb3NzaWJsZU9iajtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICByZXNwb25zZS5vYmogPSAodHlwZW9mIHBvc3NpYmxlT2JqID09PSAnb2JqZWN0JykgPyBwb3NzaWJsZU9iaiA6IG51bGw7XG4gICAgICB9XG5cbiAgICAgIHJlc3BvbnNlLnN0YXR1cyA9IHJlcy5zdGF0dXM7XG4gICAgICByZXNwb25zZS5zdGF0dXNUZXh0ID0gcmVzLnRleHQ7XG4gICAgICBjYiA9IG9iai5vbi5yZXNwb25zZTtcbiAgICB9XG4gICAgaWYgKHJlcy54aHIgJiYgcmVzLnhoci5yZXNwb25zZSkge1xuICAgICAgcmVzcG9uc2UuZGF0YSA9IHJlcy54aHIucmVzcG9uc2U7XG4gICAgfVxuICAgIGVsc2UgaWYoIXJlc3BvbnNlLmRhdGEpIHtcbiAgICAgIHJlc3BvbnNlLmRhdGEgPSByZXNwb25zZS5zdGF0dXNUZXh0O1xuICAgIH1cblxuICAgIGlmIChjYikge1xuICAgICAgY2IocmVzcG9uc2UpO1xuICAgIH1cbiAgfSk7XG59O1xuXG5TdXBlcmFnZW50SHR0cENsaWVudC5wcm90b3R5cGUuIGJpbmFyeVJlcXVlc3QgPSBmdW5jdGlvbiAoYWNjZXB0KSB7XG4gIGlmKCFhY2NlcHQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuICgvXmltYWdlL2kpLnRlc3QoYWNjZXB0KVxuICAgIHx8ICgvXmFwcGxpY2F0aW9uXFwvcGRmLykudGVzdChhY2NlcHQpXG4gICAgfHwgKC9eYXBwbGljYXRpb25cXC9vY3RldC1zdHJlYW0vKS50ZXN0KGFjY2VwdCk7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIpXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbXhwWWk5b2RIUndMbXB6SWwwc0ltNWhiV1Z6SWpwYlhTd2liV0Z3Y0dsdVozTWlPaUk3UVVGQlFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJJaXdpWm1sc1pTSTZJbWRsYm1WeVlYUmxaQzVxY3lJc0luTnZkWEpqWlZKdmIzUWlPaUlpTENKemIzVnlZMlZ6UTI5dWRHVnVkQ0k2V3lJbmRYTmxJSE4wY21samRDYzdYRzVjYm5aaGNpQm9aV3h3WlhKeklEMGdjbVZ4ZFdseVpTZ25MaTlvWld4d1pYSnpKeWs3WEc1MllYSWdjbVZ4ZFdWemRDQTlJSEpsY1hWcGNtVW9KM04xY0dWeVlXZGxiblFuS1R0Y2JuWmhjaUJxYzNsaGJXd2dQU0J5WlhGMWFYSmxLQ2RxY3kxNVlXMXNKeWs3WEc1MllYSWdYeUE5SUh0Y2JpQWdhWE5QWW1wbFkzUTZJSEpsY1hWcGNtVW9KMnh2WkdGemFDMWpiMjF3WVhRdmJHRnVaeTlwYzA5aWFtVmpkQ2NwTEZ4dUlDQnJaWGx6T2lCeVpYRjFhWEpsS0Nkc2IyUmhjMmd0WTI5dGNHRjBMMjlpYW1WamRDOXJaWGx6SnlsY2JuMDdYRzVjYmk4cVhHNGdLaUJLVVhWbGNubElkSFJ3UTJ4cFpXNTBJR2x6SUdFZ2JHbG5hSFF0ZDJWcFoyaDBMQ0J1YjJSbElHOXlJR0p5YjNkelpYSWdTRlJVVUNCamJHbGxiblJjYmlBcUwxeHVkbUZ5SUVwUmRXVnllVWgwZEhCRGJHbGxiblFnUFNCbWRXNWpkR2x2YmlBb0tTQjdYRzRnSUhSb2FYTXVkSGx3WlNBOUlDZEtVWFZsY25sSWRIUndRMnhwWlc1MEp6dGNibjA3WEc1Y2JpOHFYRzRnS2lCVGRYQmxjbUZuWlc1MFNIUjBjRU5zYVdWdWRDQnBjeUJoSUd4cFoyaDBMWGRsYVdkb2RDd2dibTlrWlNCdmNpQmljbTkzYzJWeUlFaFVWRkFnWTJ4cFpXNTBYRzRnS2k5Y2JuWmhjaUJUZFhCbGNtRm5aVzUwU0hSMGNFTnNhV1Z1ZENBOUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ2RHaHBjeTUwZVhCbElEMGdKMU4xY0dWeVlXZGxiblJJZEhSd1EyeHBaVzUwSnp0Y2JuMDdYRzVjYmk4cUtseHVJQ29nVTNkaFoyZGxja2gwZEhBZ2FYTWdZU0IzY21Gd2NHVnlJR1p2Y2lCbGVHVmpkWFJwYm1jZ2NtVnhkV1Z6ZEhOY2JpQXFMMXh1ZG1GeUlGTjNZV2RuWlhKSWRIUndJRDBnYlc5a2RXeGxMbVY0Y0c5eWRITWdQU0JtZFc1amRHbHZiaUFvS1NCN2ZUdGNibHh1VTNkaFoyZGxja2gwZEhBdWNISnZkRzkwZVhCbExtVjRaV04xZEdVZ1BTQm1kVzVqZEdsdmJpQW9iMkpxTENCdmNIUnpLU0I3WEc0Z0lIWmhjaUJqYkdsbGJuUTdYRzVjYmlBZ2FXWW9iM0IwY3lBbUppQnZjSFJ6TG1Oc2FXVnVkQ2tnZTF4dUlDQWdJR05zYVdWdWRDQTlJRzl3ZEhNdVkyeHBaVzUwTzF4dUlDQjlYRzRnSUdWc2MyVWdlMXh1SUNBZ0lHTnNhV1Z1ZENBOUlHNWxkeUJUZFhCbGNtRm5aVzUwU0hSMGNFTnNhV1Z1ZENodmNIUnpLVHRjYmlBZ2ZWeHVJQ0JqYkdsbGJuUXViM0IwY3lBOUlHOXdkSE1nZkh3Z2UzMDdYRzVjYmlBZ2FXWWdLRzl3ZEhNZ0ppWWdiM0IwY3k1eVpYRjFaWE4wUVdkbGJuUXBJSHRjYmlBZ0lDQnlaWEYxWlhOMElEMGdiM0IwY3k1eVpYRjFaWE4wUVdkbGJuUTdYRzRnSUgxY2JseHVJQ0F2THlCc1pXZGhZM2tnYzNWd2NHOXlkRnh1SUNCMllYSWdhR0Z6U2xGMVpYSjVJRDBnWm1Gc2MyVTdYRzRnSUdsbUtIUjVjR1Z2WmlCM2FXNWtiM2NnSVQwOUlDZDFibVJsWm1sdVpXUW5LU0I3WEc0Z0lDQWdhV1lvZEhsd1pXOW1JSGRwYm1SdmR5NXFVWFZsY25rZ0lUMDlJQ2QxYm1SbFptbHVaV1FuS1NCN1hHNGdJQ0FnSUNCb1lYTktVWFZsY25rZ1BTQjBjblZsTzF4dUlDQWdJSDFjYmlBZ2ZWeHVJQ0F2THlCUFVGUkpUMDVUSUhOMWNIQnZjblJjYmlBZ2FXWW9iMkpxTG0xbGRHaHZaQzUwYjB4dmQyVnlRMkZ6WlNncElEMDlQU0FuYjNCMGFXOXVjeWNnSmlZZ1kyeHBaVzUwTG5SNWNHVWdQVDA5SUNkVGRYQmxjbUZuWlc1MFNIUjBjRU5zYVdWdWRDY3BJSHRjYmlBZ0lDQnNiMmNvSjJadmNtTnBibWNnYWxGMVpYSjVJR0Z6SUU5UVZFbFBUbE1nWVhKbElHNXZkQ0J6ZFhCd2IzSjBaV1FnWW5rZ1UzVndaWEpCWjJWdWRDY3BPMXh1SUNBZ0lHOWlhaTUxYzJWS1VYVmxjbmtnUFNCMGNuVmxPMXh1SUNCOVhHNGdJR2xtS0hSb2FYTXVhWE5KYm5SbGNtNWxkRVY0Y0d4dmNtVnlLQ2tnSmlZZ0tHOWlhaTUxYzJWS1VYVmxjbmtnUFQwOUlHWmhiSE5sSUh4OElDRm9ZWE5LVVhWbGNua2dLU2tnZTF4dUlDQWdJSFJvY205M0lHNWxkeUJGY25KdmNpZ25WVzV6ZFhCd2IzSjBaV1FnWTI5dVptbG5kWEpoZEdsdmJpRWdTbEYxWlhKNUlHbHpJSEpsY1hWcGNtVmtJR0oxZENCdWIzUWdZWFpoYVd4aFlteGxKeWs3WEc0Z0lIMWNiaUFnYVdZZ0tDaHZZbW9nSmlZZ2IySnFMblZ6WlVwUmRXVnllU0E5UFQwZ2RISjFaU2tnZkh3Z2RHaHBjeTVwYzBsdWRHVnlibVYwUlhod2JHOXlaWElvS1NBbUppQm9ZWE5LVVhWbGNua3BJSHRjYmlBZ0lDQmpiR2xsYm5RZ1BTQnVaWGNnU2xGMVpYSjVTSFIwY0VOc2FXVnVkQ2h2Y0hSektUdGNiaUFnZlZ4dVhHNGdJSFpoY2lCemRXTmpaWE56SUQwZ2IySnFMbTl1TG5KbGMzQnZibk5sTzF4dUlDQjJZWElnWlhKeWIzSWdQU0J2WW1vdWIyNHVaWEp5YjNJN1hHNWNiaUFnZG1GeUlISmxjWFZsYzNSSmJuUmxjbU5sY0hSdmNpQTlJR1oxYm1OMGFXOXVLR1JoZEdFcElIdGNiaUFnSUNCcFppaHZjSFJ6SUNZbUlHOXdkSE11Y21WeGRXVnpkRWx1ZEdWeVkyVndkRzl5S1NCN1hHNGdJQ0FnSUNCa1lYUmhJRDBnYjNCMGN5NXlaWEYxWlhOMFNXNTBaWEpqWlhCMGIzSXVZWEJ3Ykhrb1pHRjBZU2s3WEc0Z0lDQWdmVnh1SUNBZ0lISmxkSFZ5YmlCa1lYUmhPMXh1SUNCOU8xeHVYRzRnSUhaaGNpQnlaWE53YjI1elpVbHVkR1Z5WTJWd2RHOXlJRDBnWm5WdVkzUnBiMjRvWkdGMFlTa2dlMXh1SUNBZ0lHbG1LRzl3ZEhNZ0ppWWdiM0IwY3k1eVpYTndiMjV6WlVsdWRHVnlZMlZ3ZEc5eUtTQjdYRzRnSUNBZ0lDQmtZWFJoSUQwZ2IzQjBjeTV5WlhOd2IyNXpaVWx1ZEdWeVkyVndkRzl5TG1Gd2NHeDVLR1JoZEdFc0lGdHZZbXBkS1R0Y2JpQWdJQ0I5WEc0Z0lDQWdjbVYwZFhKdUlITjFZMk5sYzNNb1pHRjBZU2s3WEc0Z0lIMDdYRzVjYmlBZ2RtRnlJR1Z5Y205eVNXNTBaWEpqWlhCMGIzSWdQU0JtZFc1amRHbHZiaWhrWVhSaEtTQjdYRzRnSUNBZ2FXWW9iM0IwY3lBbUppQnZjSFJ6TG5KbGMzQnZibk5sU1c1MFpYSmpaWEIwYjNJcElIdGNiaUFnSUNBZ0lHUmhkR0VnUFNCdmNIUnpMbkpsYzNCdmJuTmxTVzUwWlhKalpYQjBiM0l1WVhCd2JIa29aR0YwWVN3Z1cyOWlhbDBwTzF4dUlDQWdJSDFjYmlBZ0lDQmxjbkp2Y2loa1lYUmhLVHRjYmlBZ2ZUdGNibHh1SUNCdlltb3ViMjR1WlhKeWIzSWdQU0JtZFc1amRHbHZiaWhrWVhSaEtTQjdYRzRnSUNBZ1pYSnliM0pKYm5SbGNtTmxjSFJ2Y2loa1lYUmhLVHRjYmlBZ2ZUdGNibHh1SUNCdlltb3ViMjR1Y21WemNHOXVjMlVnUFNCbWRXNWpkR2x2Ymloa1lYUmhLU0I3WEc0Z0lDQWdhV1lvWkdGMFlTQW1KaUJrWVhSaExuTjBZWFIxY3lBK1BTQTBNREFwSUh0Y2JpQWdJQ0FnSUdWeWNtOXlTVzUwWlhKalpYQjBiM0lvWkdGMFlTazdYRzRnSUNBZ2ZWeHVJQ0FnSUdWc2MyVWdlMXh1SUNBZ0lDQWdjbVZ6Y0c5dWMyVkpiblJsY21ObGNIUnZjaWhrWVhSaEtUdGNiaUFnSUNCOVhHNGdJSDA3WEc1Y2JpQWdhV1lnS0Y4dWFYTlBZbXBsWTNRb2IySnFLU0FtSmlCZkxtbHpUMkpxWldOMEtHOWlhaTVpYjJSNUtTa2dlMXh1SUNBZ0lDOHZJSE53WldOcFlXd2djSEp2WTJWemMybHVaeUJtYjNJZ1ptbHNaU0IxY0d4dllXUnpJSFpwWVNCcWNYVmxjbmxjYmlBZ0lDQnBaaUFvYjJKcUxtSnZaSGt1ZEhsd1pTQW1KaUJ2WW1vdVltOWtlUzUwZVhCbElEMDlQU0FuWm05eWJVUmhkR0VuS1h0Y2JpQWdJQ0FnSUdsbUtHOXdkSE11ZFhObFNsRjFaWEo1S1NCN1hHNGdJQ0FnSUNBZ0lHOWlhaTVqYjI1MFpXNTBWSGx3WlNBOUlHWmhiSE5sTzF4dUlDQWdJQ0FnSUNCdlltb3VjSEp2WTJWemMwUmhkR0VnUFNCbVlXeHpaVHRjYmlBZ0lDQWdJQ0FnWkdWc1pYUmxJRzlpYWk1b1pXRmtaWEp6V3lkRGIyNTBaVzUwTFZSNWNHVW5YVHRjYmlBZ0lDQWdJSDFjYmlBZ0lDQjlYRzRnSUgxY2JseHVJQ0J2WW1vZ1BTQnlaWEYxWlhOMFNXNTBaWEpqWlhCMGIzSW9iMkpxS1NCOGZDQnZZbW83WEc0Z0lHbG1JQ2h2WW1vdVltVm1iM0psVTJWdVpDa2dlMXh1SUNBZ0lHOWlhaTVpWldadmNtVlRaVzVrS0daMWJtTjBhVzl1S0Y5dlltb3BJSHRjYmlBZ0lDQWdJR05zYVdWdWRDNWxlR1ZqZFhSbEtGOXZZbW9nZkh3Z2IySnFLVHRjYmlBZ0lDQjlLVHRjYmlBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0JqYkdsbGJuUXVaWGhsWTNWMFpTaHZZbW9wTzF4dUlDQjlYRzVjYmlBZ2NtVjBkWEp1SUNodlltb3VaR1ZtWlhKeVpXUXBJRDhnYjJKcUxtUmxabVZ5Y21Wa0xuQnliMjFwYzJVZ09pQnZZbW83WEc1OU8xeHVYRzVUZDJGbloyVnlTSFIwY0M1d2NtOTBiM1I1Y0dVdWFYTkpiblJsY201bGRFVjRjR3h2Y21WeUlEMGdablZ1WTNScGIyNGdLQ2tnZTF4dUlDQjJZWElnWkdWMFpXTjBaV1JKUlNBOUlHWmhiSE5sTzF4dVhHNGdJR2xtSUNoMGVYQmxiMllnYm1GMmFXZGhkRzl5SUNFOVBTQW5kVzVrWldacGJtVmtKeUFtSmlCdVlYWnBaMkYwYjNJdWRYTmxja0ZuWlc1MEtTQjdYRzRnSUNBZ2RtRnlJRzVoZGlBOUlHNWhkbWxuWVhSdmNpNTFjMlZ5UVdkbGJuUXVkRzlNYjNkbGNrTmhjMlVvS1R0Y2JseHVJQ0FnSUdsbUlDaHVZWFl1YVc1a1pYaFBaaWduYlhOcFpTY3BJQ0U5UFNBdE1Ta2dlMXh1SUNBZ0lDQWdkbUZ5SUhabGNuTnBiMjRnUFNCd1lYSnpaVWx1ZENodVlYWXVjM0JzYVhRb0oyMXphV1VuS1ZzeFhTazdYRzVjYmlBZ0lDQWdJR2xtSUNoMlpYSnphVzl1SUR3OUlEZ3BJSHRjYmlBZ0lDQWdJQ0FnWkdWMFpXTjBaV1JKUlNBOUlIUnlkV1U3WEc0Z0lDQWdJQ0I5WEc0Z0lDQWdmVnh1SUNCOVhHNWNiaUFnY21WMGRYSnVJR1JsZEdWamRHVmtTVVU3WEc1OU8xeHVYRzVLVVhWbGNubElkSFJ3UTJ4cFpXNTBMbkJ5YjNSdmRIbHdaUzVsZUdWamRYUmxJRDBnWm5WdVkzUnBiMjRnS0c5aWFpa2dlMXh1SUNCMllYSWdhbkVnUFNCMGFHbHpMbXBSZFdWeWVTQjhmQ0FvZEhsd1pXOW1JSGRwYm1SdmR5QWhQVDBnSjNWdVpHVm1hVzVsWkNjZ0ppWWdkMmx1Wkc5M0xtcFJkV1Z5ZVNrN1hHNGdJSFpoY2lCallpQTlJRzlpYWk1dmJqdGNiaUFnZG1GeUlISmxjWFZsYzNRZ1BTQnZZbW83WEc1Y2JpQWdhV1lvZEhsd1pXOW1JR3B4SUQwOVBTQW5kVzVrWldacGJtVmtKeUI4ZkNCcWNTQTlQVDBnWm1Gc2MyVXBJSHRjYmlBZ0lDQjBhSEp2ZHlCdVpYY2dSWEp5YjNJb0oxVnVjM1Z3Y0c5eWRHVmtJR052Ym1acFozVnlZWFJwYjI0aElFcFJkV1Z5ZVNCcGN5QnlaWEYxYVhKbFpDQmlkWFFnYm05MElHRjJZV2xzWVdKc1pTY3BPMXh1SUNCOVhHNWNiaUFnYjJKcUxuUjVjR1VnUFNCdlltb3ViV1YwYUc5a08xeHVJQ0J2WW1vdVkyRmphR1VnUFNCdlltb3VhbkYxWlhKNVFXcGhlRU5oWTJobE8xeHVJQ0J2WW1vdVpHRjBZU0E5SUc5aWFpNWliMlI1TzF4dUlDQmtaV3hsZEdVZ2IySnFMbXB4ZFdWeWVVRnFZWGhEWVdOb1pUdGNiaUFnWkdWc1pYUmxJRzlpYWk1MWMyVktVWFZsY25rN1hHNGdJR1JsYkdWMFpTQnZZbW91WW05a2VUdGNibHh1SUNCdlltb3VZMjl0Y0d4bGRHVWdQU0JtZFc1amRHbHZiaUFvY21WemNHOXVjMlVwSUh0Y2JpQWdJQ0IyWVhJZ2FHVmhaR1Z5Y3lBOUlIdDlPMXh1SUNBZ0lIWmhjaUJvWldGa1pYSkJjbkpoZVNBOUlISmxjM0J2Ym5ObExtZGxkRUZzYkZKbGMzQnZibk5sU0dWaFpHVnljeWdwTG5Od2JHbDBLQ2RjWEc0bktUdGNibHh1SUNBZ0lHWnZjaUFvZG1GeUlHa2dQU0F3T3lCcElEd2dhR1ZoWkdWeVFYSnlZWGt1YkdWdVozUm9PeUJwS3lzcElIdGNiaUFnSUNBZ0lIWmhjaUIwYjFOd2JHbDBJRDBnYUdWaFpHVnlRWEp5WVhsYmFWMHVkSEpwYlNncE8xeHVYRzRnSUNBZ0lDQnBaaUFvZEc5VGNHeHBkQzVzWlc1bmRHZ2dQVDA5SURBcElIdGNiaUFnSUNBZ0lDQWdZMjl1ZEdsdWRXVTdYRzRnSUNBZ0lDQjlYRzVjYmlBZ0lDQWdJSFpoY2lCelpYQmhjbUYwYjNJZ1BTQjBiMU53YkdsMExtbHVaR1Y0VDJZb0p6b25LVHRjYmx4dUlDQWdJQ0FnYVdZZ0tITmxjR0Z5WVhSdmNpQTlQVDBnTFRFcElIdGNiaUFnSUNBZ0lDQWdMeThnVG1GdFpTQmlkWFFnYm04Z2RtRnNkV1VnYVc0Z2RHaGxJR2hsWVdSbGNseHVJQ0FnSUNBZ0lDQm9aV0ZrWlhKelczUnZVM0JzYVhSZElEMGdiblZzYkR0Y2JseHVJQ0FnSUNBZ0lDQmpiMjUwYVc1MVpUdGNiaUFnSUNBZ0lIMWNibHh1SUNBZ0lDQWdkbUZ5SUc1aGJXVWdQU0IwYjFOd2JHbDBMbk4xWW5OMGNtbHVaeWd3TENCelpYQmhjbUYwYjNJcExuUnlhVzBvS1R0Y2JpQWdJQ0FnSUhaaGNpQjJZV3gxWlNBOUlIUnZVM0JzYVhRdWMzVmljM1J5YVc1bktITmxjR0Z5WVhSdmNpQXJJREVwTG5SeWFXMG9LVHRjYmx4dUlDQWdJQ0FnYUdWaFpHVnljMXR1WVcxbFhTQTlJSFpoYkhWbE8xeHVJQ0FnSUgxY2JseHVJQ0FnSUhaaGNpQnZkWFFnUFNCN1hHNGdJQ0FnSUNCMWNtdzZJSEpsY1hWbGMzUXVkWEpzTEZ4dUlDQWdJQ0FnYldWMGFHOWtPaUJ5WlhGMVpYTjBMbTFsZEdodlpDeGNiaUFnSUNBZ0lITjBZWFIxY3pvZ2NtVnpjRzl1YzJVdWMzUmhkSFZ6TEZ4dUlDQWdJQ0FnYzNSaGRIVnpWR1Y0ZERvZ2NtVnpjRzl1YzJVdWMzUmhkSFZ6VkdWNGRDeGNiaUFnSUNBZ0lHUmhkR0U2SUhKbGMzQnZibk5sTG5KbGMzQnZibk5sVkdWNGRDeGNiaUFnSUNBZ0lHaGxZV1JsY25NNklHaGxZV1JsY25OY2JpQWdJQ0I5TzF4dVhHNGdJQ0FnZEhKNUlIdGNiaUFnSUNBZ0lIWmhjaUJ3YjNOemFXSnNaVTlpYWlBOUlDQnlaWE53YjI1elpTNXlaWE53YjI1elpVcFRUMDRnZkh3Z2FuTjVZVzFzTG5OaFptVk1iMkZrS0hKbGMzQnZibk5sTG5KbGMzQnZibk5sVkdWNGRDazdYRzRnSUNBZ0lDQnZkWFF1YjJKcUlEMGdLSFI1Y0dWdlppQndiM056YVdKc1pVOWlhaUE5UFQwZ0ozTjBjbWx1WnljcElEOGdlMzBnT2lCd2IzTnphV0pzWlU5aWFqdGNiaUFnSUNCOUlHTmhkR05vSUNobGVDa2dlMXh1SUNBZ0lDQWdMeThnWkc4Z2JtOTBJSE5sZENCdmRYUXViMkpxWEc0Z0lDQWdJQ0JvWld4d1pYSnpMbXh2WnlnbmRXNWhZbXhsSUhSdklIQmhjbk5sSUVwVFQwNHZXVUZOVENCamIyNTBaVzUwSnlrN1hHNGdJQ0FnZlZ4dVhHNGdJQ0FnTHk4Z1NTQmpZVzRnZEdoeWIzY3NJRzl5SUhCaGNuTmxJRzUxYkd3L1hHNGdJQ0FnYjNWMExtOWlhaUE5SUc5MWRDNXZZbW9nZkh3Z2JuVnNiRHRjYmx4dUlDQWdJR2xtSUNoeVpYTndiMjV6WlM1emRHRjBkWE1nUGowZ01qQXdJQ1ltSUhKbGMzQnZibk5sTG5OMFlYUjFjeUE4SURNd01Da2dlMXh1SUNBZ0lDQWdZMkl1Y21WemNHOXVjMlVvYjNWMEtUdGNiaUFnSUNCOUlHVnNjMlVnYVdZZ0tISmxjM0J2Ym5ObExuTjBZWFIxY3lBOVBUMGdNQ0I4ZkNBb2NtVnpjRzl1YzJVdWMzUmhkSFZ6SUQ0OUlEUXdNQ0FtSmlCeVpYTndiMjV6WlM1emRHRjBkWE1nUENBMU9Ua3BLU0I3WEc0Z0lDQWdJQ0JqWWk1bGNuSnZjaWh2ZFhRcE8xeHVJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0J5WlhSMWNtNGdZMkl1Y21WemNHOXVjMlVvYjNWMEtUdGNiaUFnSUNCOVhHNGdJSDA3WEc1Y2JpQWdhbkV1YzNWd2NHOXlkQzVqYjNKeklEMGdkSEoxWlR0Y2JseHVJQ0J5WlhSMWNtNGdhbkV1WVdwaGVDaHZZbW9wTzF4dWZUdGNibHh1VTNWd1pYSmhaMlZ1ZEVoMGRIQkRiR2xsYm5RdWNISnZkRzkwZVhCbExtVjRaV04xZEdVZ1BTQm1kVzVqZEdsdmJpQW9iMkpxS1NCN1hHNGdJSFpoY2lCdFpYUm9iMlFnUFNCdlltb3ViV1YwYUc5a0xuUnZURzkzWlhKRFlYTmxLQ2s3WEc0Z0lIWmhjaUIwYVcxbGIzVjBJRDBnYjJKcUxuUnBiV1Z2ZFhRN1hHNWNiaUFnYVdZZ0tHMWxkR2h2WkNBOVBUMGdKMlJsYkdWMFpTY3BJSHRjYmlBZ0lDQnRaWFJvYjJRZ1BTQW5aR1ZzSnp0Y2JpQWdmVnh1SUNCMllYSWdhR1ZoWkdWeWN5QTlJRzlpYWk1b1pXRmtaWEp6SUh4OElIdDlPMXh1WEc0Z0lIWmhjaUJ5SUQwZ2NtVnhkV1Z6ZEZ0dFpYUm9iMlJkS0c5aWFpNTFjbXdwTzF4dVhHNGdJR2xtSUNodlltb3VZMjl1Ym1WamRHbHZia0ZuWlc1MEtTQjdYRzRnSUNBZ2NpNWhaMlZ1ZENodlltb3VZMjl1Ym1WamRHbHZia0ZuWlc1MEtUdGNiaUFnZlZ4dVhHNGdJR2xtSUNoMGFXMWxiM1YwS1NCN1hHNGdJQ0FnY2k1MGFXMWxiM1YwS0hScGJXVnZkWFFwTzF4dUlDQjlYRzVjYmlBZ2FXWWdLRzlpYWk1bGJtRmliR1ZEYjI5cmFXVnpLU0I3WEc0Z0lDQWdjaTUzYVhSb1EzSmxaR1Z1ZEdsaGJITW9LVHRjYmlBZ2ZWeHVYRzRnSUhaaGNpQmhZMk5sY0hRZ1BTQnZZbW91YUdWaFpHVnljeTVCWTJObGNIUTdYRzVjYmlBZ2FXWW9kR2hwY3k1aWFXNWhjbmxTWlhGMVpYTjBLR0ZqWTJWd2RDa3BJSHRjYmlBZ0lDQnlMbTl1S0NkeVpYRjFaWE4wSnl3Z1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdhV1lvZEdocGN5NTRhSElwSUh0Y2JpQWdJQ0FnSUNBZ2RHaHBjeTU0YUhJdWNtVnpjRzl1YzJWVWVYQmxJRDBnSjJKc2IySW5PMXh1SUNBZ0lDQWdmVnh1SUNBZ0lIMHBPMXh1SUNCOVhHNWNiaUFnYVdZb2IySnFMbUp2WkhrcElIdGNiaUFnSUNCcFppaGZMbWx6VDJKcVpXTjBLRzlpYWk1aWIyUjVLU2tnZTF4dUlDQWdJQ0FnZG1GeUlHTnZiblJsYm5SVWVYQmxJRDBnYjJKcUxtaGxZV1JsY25OYkowTnZiblJsYm5RdFZIbHdaU2RkSUh4OElDY25PMXh1SUNBZ0lDQWdhV1lnS0dOdmJuUmxiblJVZVhCbExtbHVaR1Y0VDJZb0oyMTFiSFJwY0dGeWRDOW1iM0p0TFdSaGRHRW5LU0E5UFQwZ01Da2dlMXh1SUNBZ0lDQWdJQ0JrWld4bGRHVWdhR1ZoWkdWeWMxc25RMjl1ZEdWdWRDMVVlWEJsSjEwN1hHNGdJQ0FnSUNBZ0lHbG1LSHQ5TG5SdlUzUnlhVzVuTG1Gd2NHeDVLRzlpYWk1aWIyUjVLU0E5UFQwZ0oxdHZZbXBsWTNRZ1JtOXliVVJoZEdGZEp5a2dlMXh1SUNBZ0lDQWdJQ0FnSUhJdWMyVnVaQ2h2WW1vdVltOWtlU2s3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ1pXeHpaU0I3WEc0Z0lDQWdJQ0FnSUNBZ2RtRnlJR3RsZVc1aGJXVXNJSFpoYkhWbExDQjJPMXh1SUNBZ0lDQWdJQ0FnSUdadmNpQW9hMlY1Ym1GdFpTQnBiaUJ2WW1vdVltOWtlU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdkbUZzZFdVZ1BTQnZZbW91WW05a2VWdHJaWGx1WVcxbFhUdGNiaUFnSUNBZ0lDQWdJQ0FnSUdsbUtFRnljbUY1TG1selFYSnlZWGtvZG1Gc2RXVXBLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJR1p2Y2loMklHbHVJSFpoYkhWbEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdjaTVtYVdWc1pDaHJaWGx1WVcxbExDQjJLVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQWdJQ0FnWld4elpTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lISXVabWxsYkdRb2EyVjVibUZ0WlN3Z2RtRnNkV1VwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ1pXeHpaU0JwWmlBb1h5NXBjMDlpYW1WamRDaHZZbW91WW05a2VTa3BJSHRjYmlBZ0lDQWdJQ0FnTHk4Z2JtOXVJRzExYkhScGNHRnlkQzltYjNKdExXUmhkR0ZjYmlBZ0lDQWdJQ0FnYjJKcUxtSnZaSGtnUFNCS1UwOU9Mbk4wY21sdVoybG1lU2h2WW1vdVltOWtlU2s3WEc0Z0lDQWdJQ0FnSUhJdWMyVnVaQ2h2WW1vdVltOWtlU2s3WEc0Z0lDQWdJQ0I5WEc0Z0lDQWdmVnh1SUNBZ0lHVnNjMlVnZTF4dUlDQWdJQ0FnY2k1elpXNWtLRzlpYWk1aWIyUjVLVHRjYmlBZ0lDQjlYRzRnSUgxY2JseHVJQ0IyWVhJZ2JtRnRaVHRjYmlBZ1ptOXlJQ2h1WVcxbElHbHVJR2hsWVdSbGNuTXBJSHRjYmlBZ0lDQnlMbk5sZENodVlXMWxMQ0JvWldGa1pYSnpXMjVoYldWZEtUdGNiaUFnZlZ4dVhHNGdJR2xtS0hSNWNHVnZaaUJ5TG1KMVptWmxjaUE5UFQwZ0oyWjFibU4wYVc5dUp5a2dlMXh1SUNBZ0lISXVZblZtWm1WeUtDazdJQzh2SUdadmNtTmxJSE4xY0dWeVlXZGxiblFnZEc4Z2NHOXdkV3hoZEdVZ2NtVnpMblJsZUhRZ2QybDBhQ0IwYUdVZ2NtRjNJSEpsYzNCdmJuTmxJR1JoZEdGY2JpQWdmVnh1WEc0Z0lISXVaVzVrS0daMWJtTjBhVzl1SUNobGNuSXNJSEpsY3lrZ2UxeHVJQ0FnSUhKbGN5QTlJSEpsY3lCOGZDQjdYRzRnSUNBZ0lDQnpkR0YwZFhNNklEQXNYRzRnSUNBZ0lDQm9aV0ZrWlhKek9pQjdaWEp5YjNJNklDZHVieUJ5WlhOd2IyNXpaU0JtY205dElITmxjblpsY2lkOVhHNGdJQ0FnZlR0Y2JpQWdJQ0IyWVhJZ2NtVnpjRzl1YzJVZ1BTQjdYRzRnSUNBZ0lDQjFjbXc2SUc5aWFpNTFjbXdzWEc0Z0lDQWdJQ0J0WlhSb2IyUTZJRzlpYWk1dFpYUm9iMlFzWEc0Z0lDQWdJQ0JvWldGa1pYSnpPaUJ5WlhNdWFHVmhaR1Z5YzF4dUlDQWdJSDA3WEc0Z0lDQWdkbUZ5SUdOaU8xeHVYRzRnSUNBZ2FXWWdLQ0ZsY25JZ0ppWWdjbVZ6TG1WeWNtOXlLU0I3WEc0Z0lDQWdJQ0JsY25JZ1BTQnlaWE11WlhKeWIzSTdYRzRnSUNBZ2ZWeHVYRzRnSUNBZ2FXWWdLR1Z5Y2lBbUppQnZZbW91YjI0Z0ppWWdiMkpxTG05dUxtVnljbTl5S1NCN1hHNGdJQ0FnSUNCeVpYTndiMjV6WlM1bGNuSlBZbW9nUFNCbGNuSTdYRzRnSUNBZ0lDQnlaWE53YjI1elpTNXpkR0YwZFhNZ1BTQnlaWE1nUHlCeVpYTXVjM1JoZEhWeklEb2dOVEF3TzF4dUlDQWdJQ0FnY21WemNHOXVjMlV1YzNSaGRIVnpWR1Y0ZENBOUlISmxjeUEvSUhKbGN5NTBaWGgwSURvZ1pYSnlMbTFsYzNOaFoyVTdYRzRnSUNBZ0lDQnBaaUFvY21WekxtaGxZV1JsY25NZ0ppWWdjbVZ6TG1obFlXUmxjbk5iSjJOdmJuUmxiblF0ZEhsd1pTZGRLU0I3WEc0Z0lDQWdJQ0FnSUdsbUlDaHlaWE11YUdWaFpHVnljMXNuWTI5dWRHVnVkQzEwZVhCbEoxMHVhVzVrWlhoUFppZ25ZWEJ3YkdsallYUnBiMjR2YW5OdmJpY3BJRDQ5SURBcElIdGNiaUFnSUNBZ0lDQWdJQ0IwY25rZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WemNHOXVjMlV1YjJKcUlEMGdTbE5QVGk1d1lYSnpaU2h5WlhOd2IyNXpaUzV6ZEdGMGRYTlVaWGgwS1R0Y2JpQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJQ0FnWTJGMFkyZ2dLR1VwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsYzNCdmJuTmxMbTlpYWlBOUlHNTFiR3c3WEc0Z0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQjlYRzRnSUNBZ0lDQmpZaUE5SUc5aWFpNXZiaTVsY25KdmNqdGNiaUFnSUNCOUlHVnNjMlVnYVdZZ0tISmxjeUFtSmlCdlltb3ViMjRnSmlZZ2IySnFMbTl1TG5KbGMzQnZibk5sS1NCN1hHNGdJQ0FnSUNCMllYSWdjRzl6YzJsaWJHVlBZbW83WEc1Y2JpQWdJQ0FnSUM4dklFRnNjbVZoWkhrZ2NHRnljMlZrSUdKNUlHSjVJSE4xY0dWeVlXZGxiblEvWEc0Z0lDQWdJQ0JwWmlBb2NtVnpMbUp2WkhrZ0ppWWdYeTVyWlhsektISmxjeTVpYjJSNUtTNXNaVzVuZEdnZ1BpQXdLU0I3WEc0Z0lDQWdJQ0FnSUhCdmMzTnBZbXhsVDJKcUlEMGdjbVZ6TG1KdlpIazdYRzRnSUNBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQjBjbmtnZTF4dUlDQWdJQ0FnSUNBZ0lIQnZjM05wWW14bFQySnFJRDBnYW5ONVlXMXNMbk5oWm1WTWIyRmtLSEpsY3k1MFpYaDBLVHRjYmlBZ0lDQWdJQ0FnSUNBdkx5QmpZVzRnY0dGeWMyVWdhVzUwYnlCaElITjBjbWx1Wnk0dUxpQjNhR2xqYUNCM1pTQmtiMjRuZENCdVpXVmtJSEoxYm01cGJtY2dZWEp2ZFc1a0lHbHVJSFJvWlNCemVYTjBaVzFjYmlBZ0lDQWdJQ0FnSUNCd2IzTnphV0pzWlU5aWFpQTlJQ2gwZVhCbGIyWWdjRzl6YzJsaWJHVlBZbW9nUFQwOUlDZHpkSEpwYm1jbktTQS9JRzUxYkd3Z09pQndiM056YVdKc1pVOWlhanRjYmlBZ0lDQWdJQ0FnZlNCallYUmphQ0FvWlNrZ2UxeHVJQ0FnSUNBZ0lDQWdJR2hsYkhCbGNuTXViRzluS0NkallXNXViM1FnY0dGeWMyVWdTbE5QVGk5WlFVMU1JR052Ym5SbGJuUW5LVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnZlZ4dVhHNGdJQ0FnSUNBdkx5QnVkV3hzSUcxbFlXNXpJSGRsSUdOaGJpZDBJSEJoY25ObElHbHVkRzhnYjJKcVpXTjBYRzRnSUNBZ0lDQnBaaWgwZVhCbGIyWWdRblZtWm1WeUlEMDlQU0FuWm5WdVkzUnBiMjRuSUNZbUlFSjFabVpsY2k1cGMwSjFabVpsY2lod2IzTnphV0pzWlU5aWFpa3BJSHRjYmlBZ0lDQWdJQ0FnY21WemNHOXVjMlV1WkdGMFlTQTlJSEJ2YzNOcFlteGxUMkpxTzF4dUlDQWdJQ0FnZlZ4dUlDQWdJQ0FnWld4elpTQjdYRzRnSUNBZ0lDQWdJSEpsYzNCdmJuTmxMbTlpYWlBOUlDaDBlWEJsYjJZZ2NHOXpjMmxpYkdWUFltb2dQVDA5SUNkdlltcGxZM1FuS1NBL0lIQnZjM05wWW14bFQySnFJRG9nYm5Wc2JEdGNiaUFnSUNBZ0lIMWNibHh1SUNBZ0lDQWdjbVZ6Y0c5dWMyVXVjM1JoZEhWeklEMGdjbVZ6TG5OMFlYUjFjenRjYmlBZ0lDQWdJSEpsYzNCdmJuTmxMbk4wWVhSMWMxUmxlSFFnUFNCeVpYTXVkR1Y0ZER0Y2JpQWdJQ0FnSUdOaUlEMGdiMkpxTG05dUxuSmxjM0J2Ym5ObE8xeHVJQ0FnSUgxY2JpQWdJQ0JwWmlBb2NtVnpMbmhvY2lBbUppQnlaWE11ZUdoeUxuSmxjM0J2Ym5ObEtTQjdYRzRnSUNBZ0lDQnlaWE53YjI1elpTNWtZWFJoSUQwZ2NtVnpMbmhvY2k1eVpYTndiMjV6WlR0Y2JpQWdJQ0I5WEc0Z0lDQWdaV3h6WlNCcFppZ2hjbVZ6Y0c5dWMyVXVaR0YwWVNrZ2UxeHVJQ0FnSUNBZ2NtVnpjRzl1YzJVdVpHRjBZU0E5SUhKbGMzQnZibk5sTG5OMFlYUjFjMVJsZUhRN1hHNGdJQ0FnZlZ4dVhHNGdJQ0FnYVdZZ0tHTmlLU0I3WEc0Z0lDQWdJQ0JqWWloeVpYTndiMjV6WlNrN1hHNGdJQ0FnZlZ4dUlDQjlLVHRjYm4wN1hHNWNibE4xY0dWeVlXZGxiblJJZEhSd1EyeHBaVzUwTG5CeWIzUnZkSGx3WlM0Z1ltbHVZWEo1VW1WeGRXVnpkQ0E5SUdaMWJtTjBhVzl1SUNoaFkyTmxjSFFwSUh0Y2JpQWdhV1lvSVdGalkyVndkQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQm1ZV3h6WlR0Y2JpQWdmVnh1SUNCeVpYUjFjbTRnS0M5ZWFXMWhaMlV2YVNrdWRHVnpkQ2hoWTJObGNIUXBYRzRnSUNBZ2ZId2dLQzllWVhCd2JHbGpZWFJwYjI1Y1hDOXdaR1l2S1M1MFpYTjBLR0ZqWTJWd2RDbGNiaUFnSUNCOGZDQW9MMTVoY0hCc2FXTmhkR2x2Ymx4Y0wyOWpkR1YwTFhOMGNtVmhiUzhwTG5SbGMzUW9ZV05qWlhCMEtUdGNibjA3WEc0aVhYMD0iLCIndXNlIHN0cmljdCc7XG5cbnZhciBTd2FnZ2VySHR0cCA9IHJlcXVpcmUoJy4vaHR0cCcpO1xudmFyIF8gPSB7XG4gIGlzT2JqZWN0OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNPYmplY3QnKSxcbiAgY2xvbmVEZWVwOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvY2xvbmVEZWVwJyksXG4gIGlzQXJyYXk6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc0FycmF5JyksXG4gIGlzU3RyaW5nOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNTdHJpbmcnKVxufTtcblxuXG4vKipcbiAqIFJlc29sdmVzIGEgc3BlYydzIHJlbW90ZSByZWZlcmVuY2VzXG4gKi9cbnZhciBSZXNvbHZlciA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmZhaWxlZFVybHMgPSBbXTtcbiAgdGhpcy5yZXNvbHZlckNhY2hlID0ge307XG4gIHRoaXMucGVuZGluZ1VybHMgPSB7fTtcbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS5wcm9jZXNzQWxsT2YgPSBmdW5jdGlvbihyb290LCBuYW1lLCBkZWZpbml0aW9uLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBzcGVjKSB7XG4gIHZhciBpLCBsb2NhdGlvbiwgcHJvcGVydHk7XG5cbiAgZGVmaW5pdGlvblsneC1yZXNvbHZlZC1mcm9tJ10gPSBbICcjL2RlZmluaXRpb25zLycgKyBuYW1lIF07XG4gIHZhciBhbGxPZiA9IGRlZmluaXRpb24uYWxsT2Y7XG4gIC8vIHRoZSByZWZzIGdvIGZpcnN0XG4gIGFsbE9mLnNvcnQoZnVuY3Rpb24oYSwgYikge1xuICAgIGlmKGEuJHJlZiAmJiBiLiRyZWYpIHsgcmV0dXJuIDA7IH1cbiAgICBlbHNlIGlmKGEuJHJlZikgeyByZXR1cm4gLTE7IH1cbiAgICBlbHNlIHsgcmV0dXJuIDE7IH1cbiAgfSk7XG4gIGZvciAoaSA9IDA7IGkgPCBhbGxPZi5sZW5ndGg7IGkrKykge1xuICAgIHByb3BlcnR5ID0gYWxsT2ZbaV07XG4gICAgbG9jYXRpb24gPSAnL2RlZmluaXRpb25zLycgKyBuYW1lICsgJy9hbGxPZic7XG4gICAgdGhpcy5yZXNvbHZlSW5saW5lKHJvb3QsIHNwZWMsIHByb3BlcnR5LCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBsb2NhdGlvbik7XG4gIH1cbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS5yZXNvbHZlID0gZnVuY3Rpb24gKHNwZWMsIGFyZzEsIGFyZzIsIGFyZzMpIHtcbiAgdGhpcy5zcGVjID0gc3BlYztcbiAgdmFyIHJvb3QgPSBhcmcxLCBjYWxsYmFjayA9IGFyZzIsIHNjb3BlID0gYXJnMywgb3B0cyA9IHt9LCBsb2NhdGlvbiwgaTtcbiAgaWYodHlwZW9mIGFyZzEgPT09ICdmdW5jdGlvbicpIHtcbiAgICByb290ID0gbnVsbDtcbiAgICBjYWxsYmFjayA9IGFyZzE7XG4gICAgc2NvcGUgPSBhcmcyO1xuICB9XG4gIHZhciBfcm9vdCA9IHJvb3QsIG1vZGVsTmFtZTtcbiAgdGhpcy5zY29wZSA9IChzY29wZSB8fCB0aGlzKTtcbiAgdGhpcy5pdGVyYXRpb24gPSB0aGlzLml0ZXJhdGlvbiB8fCAwO1xuXG4gIGlmKHRoaXMuc2NvcGUub3B0aW9ucyAmJiB0aGlzLnNjb3BlLm9wdGlvbnMucmVxdWVzdEludGVyY2VwdG9yKXtcbiAgICBvcHRzLnJlcXVlc3RJbnRlcmNlcHRvciA9IHRoaXMuc2NvcGUub3B0aW9ucy5yZXF1ZXN0SW50ZXJjZXB0b3I7XG4gIH1cblxuICBpZih0aGlzLnNjb3BlLm9wdGlvbnMgJiYgdGhpcy5zY29wZS5vcHRpb25zLnJlc3BvbnNlSW50ZXJjZXB0b3Ipe1xuICAgIG9wdHMucmVzcG9uc2VJbnRlcmNlcHRvciA9IHRoaXMuc2NvcGUub3B0aW9ucy5yZXNwb25zZUludGVyY2VwdG9yO1xuICB9XG5cbiAgdmFyIG5hbWUsIHBhdGgsIHByb3BlcnR5LCBwcm9wZXJ0eU5hbWUsIHBhcmFtZXRlciwgZG9uZSwgY291bnRlcjtcbiAgdmFyIHByb2Nlc3NlZENhbGxzID0gMCwgcmVzb2x2ZWRSZWZzID0ge30sIHVucmVzb2x2ZWRSZWZzID0ge307XG4gIHZhciByZXNvbHV0aW9uVGFibGUgPSBbXTsgLy8gc3RvcmUgb2JqZWN0cyBmb3IgZGVyZWZlcmVuY2luZ1xuXG4gIHNwZWMuZGVmaW5pdGlvbnMgPSBzcGVjLmRlZmluaXRpb25zIHx8IHt9O1xuICAvLyBkZWZpbml0aW9uc1xuICBmb3IgKG5hbWUgaW4gc3BlYy5kZWZpbml0aW9ucykge1xuICAgIHZhciBkZWZpbml0aW9uID0gc3BlYy5kZWZpbml0aW9uc1tuYW1lXTtcbiAgICBpZihkZWZpbml0aW9uLiRyZWYpIHtcbiAgICAgIHRoaXMucmVzb2x2ZUlubGluZShyb290LCBzcGVjLCBkZWZpbml0aW9uLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBkZWZpbml0aW9uKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBmb3IgKHByb3BlcnR5TmFtZSBpbiBkZWZpbml0aW9uLnByb3BlcnRpZXMpIHtcbiAgICAgICAgcHJvcGVydHkgPSBkZWZpbml0aW9uLnByb3BlcnRpZXNbcHJvcGVydHlOYW1lXTtcbiAgICAgICAgaWYgKF8uaXNBcnJheShwcm9wZXJ0eS5hbGxPZikpIHtcbiAgICAgICAgICB0aGlzLnByb2Nlc3NBbGxPZihyb290LCBuYW1lLCBwcm9wZXJ0eSwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgc3BlYyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgdGhpcy5yZXNvbHZlVG8ocm9vdCwgcHJvcGVydHksIHJlc29sdXRpb25UYWJsZSwgJy9kZWZpbml0aW9ucycpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChkZWZpbml0aW9uLmFsbE9mKSB7XG4gICAgICAgIHRoaXMucHJvY2Vzc0FsbE9mKHJvb3QsIG5hbWUsIGRlZmluaXRpb24sIHJlc29sdXRpb25UYWJsZSwgdW5yZXNvbHZlZFJlZnMsIHNwZWMpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIHNoYXJlZCBwYXJhbWV0ZXJzXG4gIHNwZWMucGFyYW1ldGVycyA9IHNwZWMucGFyYW1ldGVycyB8fCB7fTtcbiAgZm9yKG5hbWUgaW4gc3BlYy5wYXJhbWV0ZXJzKSB7XG4gICAgcGFyYW1ldGVyID0gc3BlYy5wYXJhbWV0ZXJzW25hbWVdO1xuICAgIGlmIChwYXJhbWV0ZXIuaW4gPT09ICdib2R5JyAmJiBwYXJhbWV0ZXIuc2NoZW1hKSB7XG4gICAgICBpZihfLmlzQXJyYXkocGFyYW1ldGVyLnNjaGVtYS5hbGxPZikpIHtcbiAgICAgICAgLy8gbW92ZSB0byBhIGRlZmluaXRpb25cbiAgICAgICAgbW9kZWxOYW1lID0gJ2lubGluZV9tb2RlbCc7XG4gICAgICAgIHZhciBfbmFtZSA9IG1vZGVsTmFtZTtcbiAgICAgICAgZG9uZSA9IGZhbHNlOyBjb3VudGVyID0gMDtcbiAgICAgICAgd2hpbGUoIWRvbmUpIHtcbiAgICAgICAgICBpZih0eXBlb2Ygc3BlYy5kZWZpbml0aW9uc1tfbmFtZV0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBkb25lID0gdHJ1ZTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBfbmFtZSA9IG1vZGVsTmFtZSArICdfJyArIGNvdW50ZXI7XG4gICAgICAgICAgY291bnRlciArKztcbiAgICAgICAgfVxuICAgICAgICBzcGVjLmRlZmluaXRpb25zW19uYW1lXSA9IHsgYWxsT2Y6IHBhcmFtZXRlci5zY2hlbWEuYWxsT2YgfTtcbiAgICAgICAgZGVsZXRlIHBhcmFtZXRlci5zY2hlbWEuYWxsT2Y7XG4gICAgICAgIHBhcmFtZXRlci5zY2hlbWEuJHJlZiA9ICcjL2RlZmluaXRpb25zLycgKyBfbmFtZTtcbiAgICAgICAgdGhpcy5wcm9jZXNzQWxsT2Yocm9vdCwgX25hbWUsIHNwZWMuZGVmaW5pdGlvbnNbX25hbWVdLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBzcGVjKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICB0aGlzLnJlc29sdmVUbyhyb290LCBwYXJhbWV0ZXIuc2NoZW1hLCByZXNvbHV0aW9uVGFibGUsIGxvY2F0aW9uKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocGFyYW1ldGVyLiRyZWYpIHtcbiAgICAgIC8vIHBhcmFtZXRlciByZWZlcmVuY2VcbiAgICAgIHRoaXMucmVzb2x2ZUlubGluZShyb290LCBzcGVjLCBwYXJhbWV0ZXIsIHJlc29sdXRpb25UYWJsZSwgdW5yZXNvbHZlZFJlZnMsIHBhcmFtZXRlci4kcmVmKTtcbiAgICB9XG4gIH1cblxuICAvLyBvcGVyYXRpb25zXG4gIGZvciAobmFtZSBpbiBzcGVjLnBhdGhzKSB7XG4gICAgdmFyIG1ldGhvZCwgb3BlcmF0aW9uLCByZXNwb25zZUNvZGU7XG4gICAgcGF0aCA9IHNwZWMucGF0aHNbbmFtZV07XG5cbiAgICBpZih0eXBlb2YgcGF0aCA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGZvciAobWV0aG9kIGluIHBhdGgpIHtcbiAgICAgICAgLy8gb3BlcmF0aW9uIHJlZmVyZW5jZVxuICAgICAgICBpZiAobWV0aG9kID09PSAnJHJlZicpIHtcbiAgICAgICAgICAvLyBsb2NhdGlvbiA9IHBhdGhbbWV0aG9kXTtcbiAgICAgICAgICBsb2NhdGlvbiA9ICcvcGF0aHMnICsgbmFtZTtcbiAgICAgICAgICB0aGlzLnJlc29sdmVJbmxpbmUocm9vdCwgc3BlYywgcGF0aCwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgbG9jYXRpb24pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIG9wZXJhdGlvbiA9IHBhdGhbbWV0aG9kXTtcbiAgICAgICAgICB2YXIgc2hhcmVkUGFyYW1ldGVycyA9IHBhdGgucGFyYW1ldGVycyB8fCBbXTtcbiAgICAgICAgICB2YXIgcGFyYW1ldGVycyA9IG9wZXJhdGlvbi5wYXJhbWV0ZXJzIHx8IFtdO1xuXG4gICAgICAgICAgc2hhcmVkUGFyYW1ldGVycy5mb3JFYWNoKGZ1bmN0aW9uKHBhcmFtZXRlcikge1xuICAgICAgICAgICAgcGFyYW1ldGVycy51bnNoaWZ0KHBhcmFtZXRlcik7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpZiAobWV0aG9kICE9PSAncGFyYW1ldGVycycgJiYgXy5pc09iamVjdChvcGVyYXRpb24pKSB7XG4gICAgICAgICAgICBvcGVyYXRpb24ucGFyYW1ldGVycyA9IG9wZXJhdGlvbi5wYXJhbWV0ZXJzIHx8IHBhcmFtZXRlcnM7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZm9yIChpIGluIHBhcmFtZXRlcnMpIHtcbiAgICAgICAgICAgIHBhcmFtZXRlciA9IHBhcmFtZXRlcnNbaV07XG4gICAgICAgICAgICBsb2NhdGlvbiA9ICcvcGF0aHMnICsgbmFtZSArICcvJyArIG1ldGhvZCArICcvcGFyYW1ldGVycyc7XG5cbiAgICAgICAgICAgIGlmIChwYXJhbWV0ZXIuaW4gPT09ICdib2R5JyAmJiBwYXJhbWV0ZXIuc2NoZW1hKSB7XG4gICAgICAgICAgICAgIGlmIChfLmlzQXJyYXkocGFyYW1ldGVyLnNjaGVtYS5hbGxPZikpIHtcbiAgICAgICAgICAgICAgICAvLyBtb3ZlIHRvIGEgZGVmaW5pdGlvblxuICAgICAgICAgICAgICAgIG1vZGVsTmFtZSA9ICdpbmxpbmVfbW9kZWwnO1xuICAgICAgICAgICAgICAgIG5hbWUgPSBtb2RlbE5hbWU7XG4gICAgICAgICAgICAgICAgZG9uZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGNvdW50ZXIgPSAwO1xuICAgICAgICAgICAgICAgIHdoaWxlICghZG9uZSkge1xuICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBzcGVjLmRlZmluaXRpb25zW25hbWVdID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBuYW1lID0gbW9kZWxOYW1lICsgJ18nICsgY291bnRlcjtcbiAgICAgICAgICAgICAgICAgIGNvdW50ZXIrKztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc3BlYy5kZWZpbml0aW9uc1tuYW1lXSA9IHthbGxPZjogcGFyYW1ldGVyLnNjaGVtYS5hbGxPZn07XG4gICAgICAgICAgICAgICAgZGVsZXRlIHBhcmFtZXRlci5zY2hlbWEuYWxsT2Y7XG4gICAgICAgICAgICAgICAgcGFyYW1ldGVyLnNjaGVtYS4kcmVmID0gJyMvZGVmaW5pdGlvbnMvJyArIG5hbWU7XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzQWxsT2Yocm9vdCwgbmFtZSwgc3BlYy5kZWZpbml0aW9uc1tuYW1lXSwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgc3BlYyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZXNvbHZlVG8ocm9vdCwgcGFyYW1ldGVyLnNjaGVtYSwgcmVzb2x1dGlvblRhYmxlLCBsb2NhdGlvbik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHBhcmFtZXRlci4kcmVmKSB7XG4gICAgICAgICAgICAgIC8vIHBhcmFtZXRlciByZWZlcmVuY2VcbiAgICAgICAgICAgICAgdGhpcy5yZXNvbHZlSW5saW5lKHJvb3QsIHNwZWMsIHBhcmFtZXRlciwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgcGFyYW1ldGVyLiRyZWYpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGZvciAocmVzcG9uc2VDb2RlIGluIG9wZXJhdGlvbi5yZXNwb25zZXMpIHtcbiAgICAgICAgICAgIHZhciByZXNwb25zZSA9IG9wZXJhdGlvbi5yZXNwb25zZXNbcmVzcG9uc2VDb2RlXTtcbiAgICAgICAgICAgIGxvY2F0aW9uID0gJy9wYXRocycgKyBuYW1lICsgJy8nICsgbWV0aG9kICsgJy9yZXNwb25zZXMvJyArIHJlc3BvbnNlQ29kZTtcblxuICAgICAgICAgICAgaWYgKF8uaXNPYmplY3QocmVzcG9uc2UpKSB7XG4gICAgICAgICAgICAgIGlmIChyZXNwb25zZS4kcmVmKSB7XG4gICAgICAgICAgICAgICAgLy8gcmVzcG9uc2UgcmVmZXJlbmNlXG4gICAgICAgICAgICAgICAgdGhpcy5yZXNvbHZlSW5saW5lKHJvb3QsIHNwZWMsIHJlc3BvbnNlLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBsb2NhdGlvbik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLnNjaGVtYSkge1xuICAgICAgICAgICAgICAgIHZhciByZXNwb25zZU9iaiA9IHJlc3BvbnNlO1xuICAgICAgICAgICAgICAgIGlmIChfLmlzQXJyYXkocmVzcG9uc2VPYmouc2NoZW1hLmFsbE9mKSkge1xuICAgICAgICAgICAgICAgICAgLy8gbW92ZSB0byBhIGRlZmluaXRpb25cbiAgICAgICAgICAgICAgICAgIG1vZGVsTmFtZSA9ICdpbmxpbmVfbW9kZWwnO1xuICAgICAgICAgICAgICAgICAgbmFtZSA9IG1vZGVsTmFtZTtcbiAgICAgICAgICAgICAgICAgIGRvbmUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgIGNvdW50ZXIgPSAwO1xuICAgICAgICAgICAgICAgICAgd2hpbGUgKCFkb25lKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygc3BlYy5kZWZpbml0aW9uc1tuYW1lXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBuYW1lID0gbW9kZWxOYW1lICsgJ18nICsgY291bnRlcjtcbiAgICAgICAgICAgICAgICAgICAgY291bnRlcisrO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgc3BlYy5kZWZpbml0aW9uc1tuYW1lXSA9IHthbGxPZjogcmVzcG9uc2VPYmouc2NoZW1hLmFsbE9mfTtcbiAgICAgICAgICAgICAgICAgIGRlbGV0ZSByZXNwb25zZU9iai5zY2hlbWEuYWxsT2Y7XG4gICAgICAgICAgICAgICAgICBkZWxldGUgcmVzcG9uc2VPYmouc2NoZW1hLnR5cGU7XG4gICAgICAgICAgICAgICAgICByZXNwb25zZU9iai5zY2hlbWEuJHJlZiA9ICcjL2RlZmluaXRpb25zLycgKyBuYW1lO1xuICAgICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzQWxsT2Yocm9vdCwgbmFtZSwgc3BlYy5kZWZpbml0aW9uc1tuYW1lXSwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgc3BlYyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKCdhcnJheScgPT09IHJlc3BvbnNlT2JqLnNjaGVtYS50eXBlKSB7XG4gICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2VPYmouc2NoZW1hLml0ZW1zICYmIHJlc3BvbnNlT2JqLnNjaGVtYS5pdGVtcy4kcmVmKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHJlc3BvbnNlIHJlZmVyZW5jZVxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc29sdmVJbmxpbmUocm9vdCwgc3BlYywgcmVzcG9uc2VPYmouc2NoZW1hLml0ZW1zLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBsb2NhdGlvbik7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgdGhpcy5yZXNvbHZlVG8ocm9vdCwgcmVzcG9uc2Uuc2NoZW1hLCByZXNvbHV0aW9uVGFibGUsIGxvY2F0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIGNsZWFyIHRoZW0gb3V0IHRvIGF2b2lkIG11bHRpcGxlIHJlc29sdXRpb25zXG4gICAgICBwYXRoLnBhcmFtZXRlcnMgPSBbXTtcbiAgICB9XG4gIH1cblxuICB2YXIgZXhwZWN0ZWRDYWxscyA9IDAsIHRvUmVzb2x2ZSA9IFtdO1xuICAvLyBpZiB0aGUgcm9vdCBpcyBzYW1lIGFzIG9ialtpXS5yb290IHdlIGNhbiByZXNvbHZlIGxvY2FsbHlcbiAgdmFyIGFsbCA9IHJlc29sdXRpb25UYWJsZTtcblxuICB2YXIgcGFydHM7XG4gIGZvcihpID0gMDsgaSA8IGFsbC5sZW5ndGg7IGkrKykge1xuICAgIHZhciBhID0gYWxsW2ldO1xuICAgIGlmKHJvb3QgPT09IGEucm9vdCkge1xuICAgICAgaWYoYS5yZXNvbHZlQXMgPT09ICdyZWYnKSB7XG4gICAgICAgIC8vIHJlc29sdmUgYW55IHBhdGggd2Fsa2luZ1xuICAgICAgICB2YXIgam9pbmVkID0gKChhLnJvb3QgfHwgJycpICsgJy8nICsgYS5rZXkpLnNwbGl0KCcvJyk7XG4gICAgICAgIHZhciBub3JtYWxpemVkID0gW107XG4gICAgICAgIHZhciB1cmwgPSAnJztcbiAgICAgICAgdmFyIGs7XG5cbiAgICAgICAgaWYoYS5rZXkuaW5kZXhPZignLi4vJykgPj0gMCkge1xuICAgICAgICAgIGZvcih2YXIgaiA9IDA7IGogPCBqb2luZWQubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgIGlmKGpvaW5lZFtqXSA9PT0gJy4uJykge1xuICAgICAgICAgICAgICBub3JtYWxpemVkID0gbm9ybWFsaXplZC5zbGljZSgwLCBub3JtYWxpemVkLmxlbmd0aC0xKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICBub3JtYWxpemVkLnB1c2goam9pbmVkW2pdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgZm9yKGsgPSAwOyBrIDwgbm9ybWFsaXplZC5sZW5ndGg7IGsgKyspIHtcbiAgICAgICAgICAgIGlmKGsgPiAwKSB7XG4gICAgICAgICAgICAgIHVybCArPSAnLyc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB1cmwgKz0gbm9ybWFsaXplZFtrXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gd2Ugbm93IGhhdmUgdG8gcmVtb3RlIHJlc29sdmUgdGhpcyBiZWNhdXNlIHRoZSBwYXRoIGhhcyBjaGFuZ2VkXG4gICAgICAgICAgYS5yb290ID0gdXJsO1xuICAgICAgICAgIHRvUmVzb2x2ZS5wdXNoKGEpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHBhcnRzID0gYS5rZXkuc3BsaXQoJyMnKTtcbiAgICAgICAgICBpZihwYXJ0cy5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgICAgIGlmKHBhcnRzWzBdLmluZGV4T2YoJ2h0dHA6JykgPT09IDAgfHwgcGFydHNbMF0uaW5kZXhPZignaHR0cHM6JykgPT09IDApIHtcbiAgICAgICAgICAgICAgYS5yb290ID0gcGFydHNbMF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsb2NhdGlvbiA9IHBhcnRzWzFdLnNwbGl0KCcvJyk7XG4gICAgICAgICAgICB2YXIgcjtcbiAgICAgICAgICAgIHZhciBzID0gc3BlYztcbiAgICAgICAgICAgIGZvcihrID0gMDsgayA8IGxvY2F0aW9uLmxlbmd0aDsgaysrKSB7XG4gICAgICAgICAgICAgIHZhciBwYXJ0ID0gbG9jYXRpb25ba107XG4gICAgICAgICAgICAgIGlmKHBhcnQgIT09ICcnKSB7XG4gICAgICAgICAgICAgICAgcyA9IHNbcGFydF07XG4gICAgICAgICAgICAgICAgaWYodHlwZW9mIHMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICByID0gcztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICByID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYociA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAvLyBtdXN0IHJlc29sdmUgdGhpcyB0b29cbiAgICAgICAgICAgICAgdG9SZXNvbHZlLnB1c2goYSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgaWYgKGEucmVzb2x2ZUFzID09PSAnaW5saW5lJykge1xuICAgICAgICAgIGlmKGEua2V5ICYmIGEua2V5LmluZGV4T2YoJyMnKSA9PT0gLTEgJiYgYS5rZXkuY2hhckF0KDApICE9PSAnLycpIHtcbiAgICAgICAgICAgIC8vIGhhbmRsZSByZWxhdGl2ZSBzY2hlbWFcbiAgICAgICAgICAgIHBhcnRzID0gYS5yb290LnNwbGl0KCcvJyk7XG4gICAgICAgICAgICBsb2NhdGlvbiA9ICcnO1xuICAgICAgICAgICAgZm9yKGkgPSAwOyBpIDwgcGFydHMubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgICAgICAgIGxvY2F0aW9uICs9IHBhcnRzW2ldICsgJy8nO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbG9jYXRpb24gKz0gYS5rZXk7XG4gICAgICAgICAgICBhLnJvb3QgPSBsb2NhdGlvbjtcbiAgICAgICAgICAgIGEubG9jYXRpb24gPSAnJztcbiAgICAgICAgICB9XG4gICAgICAgICAgdG9SZXNvbHZlLnB1c2goYSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB0b1Jlc29sdmUucHVzaChhKTtcbiAgICB9XG4gIH1cbiAgZXhwZWN0ZWRDYWxscyA9IHRvUmVzb2x2ZS5sZW5ndGg7XG5cbiAgLy8gcmVzb2x2ZSBhbnl0aGluZyB0aGF0IGlzIGxvY2FsXG5cbiAgdmFyIGxvY2sgPSB7fTtcbiAgZm9yKHZhciBpaSA9IDA7IGlpIDwgdG9SZXNvbHZlLmxlbmd0aDsgaWkrKykge1xuICAgIChmdW5jdGlvbihpdGVtLCBzcGVjLCBzZWxmLCBsb2NrLCBpaSkge1xuICAgICAgaWYoIWl0ZW0ucm9vdCB8fCBpdGVtLnJvb3QgPT09IHJvb3QpIHtcbiAgICAgICAgLy8gbG9jYWwgcmVzb2x2ZVxuICAgICAgICBzZWxmLnJlc29sdmVJdGVtKHNwZWMsIF9yb290LCByZXNvbHV0aW9uVGFibGUsIHJlc29sdmVkUmVmcywgdW5yZXNvbHZlZFJlZnMsIGl0ZW0pO1xuICAgICAgICBwcm9jZXNzZWRDYWxscyArPSAxO1xuXG4gICAgICAgIGlmKHByb2Nlc3NlZENhbGxzID09PSBleHBlY3RlZENhbGxzKSB7XG4gICAgICAgICAgc2VsZi5maW5pc2goc3BlYywgcm9vdCwgcmVzb2x1dGlvblRhYmxlLCByZXNvbHZlZFJlZnMsIHVucmVzb2x2ZWRSZWZzLCBjYWxsYmFjaywgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGVsc2UgaWYoc2VsZi5mYWlsZWRVcmxzLmluZGV4T2YoaXRlbS5yb290KSA9PT0gLTEpIHtcbiAgICAgICAgdmFyIG9iaiA9IHtcbiAgICAgICAgICB1c2VKUXVlcnk6IGZhbHNlLCAgLy8gVE9ET1xuICAgICAgICAgIHVybDogaXRlbS5yb290LFxuICAgICAgICAgIG1ldGhvZDogJ2dldCcsXG4gICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgYWNjZXB0OiBzZWxmLnNjb3BlLnN3YWdnZXJSZXF1ZXN0SGVhZGVycyB8fCAnYXBwbGljYXRpb24vanNvbidcbiAgICAgICAgICB9LFxuICAgICAgICAgIG9uOiB7XG4gICAgICAgICAgICBlcnJvcjogZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgICAgICAgIHByb2Nlc3NlZENhbGxzICs9IDE7XG4gICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdmYWlsZWQgdXJsOiAnICsgb2JqLnVybCk7XG4gICAgICAgICAgICAgIHNlbGYuZmFpbGVkVXJscy5wdXNoKG9iai51cmwpO1xuICAgICAgICAgICAgICBpZiAobG9jaykge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBsb2NrW2l0ZW0ucm9vdF07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdW5yZXNvbHZlZFJlZnNbaXRlbS5rZXldID0ge1xuICAgICAgICAgICAgICAgIHJvb3Q6IGl0ZW0ucm9vdCxcbiAgICAgICAgICAgICAgICBsb2NhdGlvbjogaXRlbS5sb2NhdGlvblxuICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgIGlmIChwcm9jZXNzZWRDYWxscyA9PT0gZXhwZWN0ZWRDYWxscykge1xuICAgICAgICAgICAgICAgIHNlbGYuZmluaXNoKHNwZWMsIF9yb290LCByZXNvbHV0aW9uVGFibGUsIHJlc29sdmVkUmVmcywgdW5yZXNvbHZlZFJlZnMsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgIC8vIGpzaGludCBpZ25vcmU6bGluZVxuICAgICAgICAgICAgcmVzcG9uc2U6IGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgICAgICAgICB2YXIgc3dhZ2dlciA9IHJlc3BvbnNlLm9iajtcbiAgICAgICAgICAgICAgaWYgKGxvY2spIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgbG9ja1tpdGVtLnJvb3RdO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChzZWxmLnJlc29sdmVyQ2FjaGUpIHtcbiAgICAgICAgICAgICAgICBzZWxmLnJlc29sdmVyQ2FjaGVbaXRlbS5yb290XSA9IHN3YWdnZXI7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgc2VsZi5yZXNvbHZlSXRlbShzd2FnZ2VyLCBpdGVtLnJvb3QsIHJlc29sdXRpb25UYWJsZSwgcmVzb2x2ZWRSZWZzLCB1bnJlc29sdmVkUmVmcywgaXRlbSk7XG4gICAgICAgICAgICAgIHByb2Nlc3NlZENhbGxzICs9IDE7XG5cbiAgICAgICAgICAgICAgaWYgKHByb2Nlc3NlZENhbGxzID09PSBleHBlY3RlZENhbGxzKSB7XG4gICAgICAgICAgICAgICAgc2VsZi5maW5pc2goc3BlYywgX3Jvb3QsIHJlc29sdXRpb25UYWJsZSwgcmVzb2x2ZWRSZWZzLCB1bnJlc29sdmVkUmVmcywgY2FsbGJhY2spO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBhcHBseSB0aW1lb3V0IG9ubHkgd2hlbiBzcGVjaWZpZWRcbiAgICAgICAgaWYgKHNjb3BlICYmIHNjb3BlLmZldGNoU3BlY1RpbWVvdXQpIHtcbiAgICAgICAgICBvYmoudGltZW91dCA9IHNjb3BlLmZldGNoU3BlY1RpbWVvdXQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc2NvcGUgJiYgc2NvcGUuY2xpZW50QXV0aG9yaXphdGlvbnMpIHtcbiAgICAgICAgICBzY29wZS5jbGllbnRBdXRob3JpemF0aW9ucy5hcHBseShvYmopO1xuICAgICAgICB9XG5cbiAgICAgICAgKGZ1bmN0aW9uIHdhaXRGb3JVbmxvY2soKSB7XG4gICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGlmIChsb2NrW29iai51cmxdKSB7XG4gICAgICAgICAgICAgIHdhaXRGb3JVbmxvY2soKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICB2YXIgY2FjaGVkID0gc2VsZi5yZXNvbHZlckNhY2hlW29iai51cmxdO1xuICAgICAgICAgICAgICBpZiAoXy5pc09iamVjdChjYWNoZWQpKSB7XG4gICAgICAgICAgICAgICAgb2JqLm9uLnJlc3BvbnNlKHtvYmo6IGNhY2hlZH0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGxvY2tbb2JqLnVybF0gPSB0cnVlO1xuICAgICAgICAgICAgICAgIG5ldyBTd2FnZ2VySHR0cCgpLmV4ZWN1dGUob2JqLCBvcHRzKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sIDApO1xuICAgICAgICB9KSgpO1xuICAgICAgfVxuXG4gICAgICBlbHNlIHtcbiAgICAgICAgcHJvY2Vzc2VkQ2FsbHMgKz0gMTtcbiAgICAgICAgdW5yZXNvbHZlZFJlZnNbaXRlbS5rZXldID0ge1xuICAgICAgICAgIHJvb3Q6IGl0ZW0ucm9vdCxcbiAgICAgICAgICBsb2NhdGlvbjogaXRlbS5sb2NhdGlvblxuICAgICAgICB9O1xuICAgICAgICBpZiAocHJvY2Vzc2VkQ2FsbHMgPT09IGV4cGVjdGVkQ2FsbHMpIHtcbiAgICAgICAgICBzZWxmLmZpbmlzaChzcGVjLCBfcm9vdCwgcmVzb2x1dGlvblRhYmxlLCByZXNvbHZlZFJlZnMsIHVucmVzb2x2ZWRSZWZzLCBjYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KHRvUmVzb2x2ZVtpaV0sIHNwZWMsIHRoaXMsIGxvY2ssIGlpKSk7XG4gIH1cblxuICBpZiAoT2JqZWN0LmtleXModG9SZXNvbHZlKS5sZW5ndGggPT09IDApIHtcbiAgICB0aGlzLmZpbmlzaChzcGVjLCBfcm9vdCwgcmVzb2x1dGlvblRhYmxlLCByZXNvbHZlZFJlZnMsIHVucmVzb2x2ZWRSZWZzLCBjYWxsYmFjayk7XG4gIH1cbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS5yZXNvbHZlSXRlbSA9IGZ1bmN0aW9uKHNwZWMsIHJvb3QsIHJlc29sdXRpb25UYWJsZSwgcmVzb2x2ZWRSZWZzLCB1bnJlc29sdmVkUmVmcywgaXRlbSkge1xuICB2YXIgcGF0aCA9IGl0ZW0ubG9jYXRpb247XG4gIHZhciBsb2NhdGlvbiA9IHNwZWMsIHBhcnRzID0gcGF0aC5zcGxpdCgnLycpO1xuICBpZihwYXRoICE9PSAnJykge1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgcGFydHMubGVuZ3RoOyBqKyspIHtcbiAgICAgIHZhciBzZWdtZW50ID0gcGFydHNbal07XG4gICAgICBpZiAoc2VnbWVudC5pbmRleE9mKCd+MScpICE9PSAtMSkge1xuICAgICAgICBzZWdtZW50ID0gcGFydHNbal0ucmVwbGFjZSgvfjAvZywgJ34nKS5yZXBsYWNlKC9+MS9nLCAnLycpO1xuICAgICAgICBpZiAoc2VnbWVudC5jaGFyQXQoMCkgIT09ICcvJykge1xuICAgICAgICAgIHNlZ21lbnQgPSAnLycgKyBzZWdtZW50O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIGxvY2F0aW9uID09PSAndW5kZWZpbmVkJyB8fCBsb2NhdGlvbiA9PT0gbnVsbCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmIChzZWdtZW50ID09PSAnJyAmJiBqID09PSAocGFydHMubGVuZ3RoIC0gMSkgJiYgcGFydHMubGVuZ3RoID4gMSkge1xuICAgICAgICBsb2NhdGlvbiA9IG51bGw7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgaWYgKHNlZ21lbnQubGVuZ3RoID4gMCkge1xuICAgICAgICBsb2NhdGlvbiA9IGxvY2F0aW9uW3NlZ21lbnRdO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICB2YXIgcmVzb2x2ZWQgPSBpdGVtLmtleTtcbiAgcGFydHMgPSBpdGVtLmtleS5zcGxpdCgnLycpO1xuICB2YXIgcmVzb2x2ZWROYW1lID0gcGFydHNbcGFydHMubGVuZ3RoLTFdO1xuXG4gIGlmKHJlc29sdmVkTmFtZS5pbmRleE9mKCcjJykgPj0gMCkge1xuICAgIHJlc29sdmVkTmFtZSA9IHJlc29sdmVkTmFtZS5zcGxpdCgnIycpWzFdO1xuICB9XG5cbiAgaWYgKGxvY2F0aW9uICE9PSBudWxsICYmIHR5cGVvZiBsb2NhdGlvbiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXNvbHZlZFJlZnNbcmVzb2x2ZWRdID0ge1xuICAgICAgbmFtZTogcmVzb2x2ZWROYW1lLFxuICAgICAgb2JqOiBsb2NhdGlvbixcbiAgICAgIGtleTogaXRlbS5rZXksXG4gICAgICByb290OiBpdGVtLnJvb3RcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIHVucmVzb2x2ZWRSZWZzW3Jlc29sdmVkXSA9IHtcbiAgICAgIHJvb3Q6IGl0ZW0ucm9vdCxcbiAgICAgIGxvY2F0aW9uOiBpdGVtLmxvY2F0aW9uXG4gICAgfTtcbiAgfVxufTtcblxuUmVzb2x2ZXIucHJvdG90eXBlLmZpbmlzaCA9IGZ1bmN0aW9uIChzcGVjLCByb290LCByZXNvbHV0aW9uVGFibGUsIHJlc29sdmVkUmVmcywgdW5yZXNvbHZlZFJlZnMsIGNhbGxiYWNrLCBsb2NhbFJlc29sdmUpIHtcbiAgLy8gd2FsayByZXNvbHV0aW9uIHRhYmxlIGFuZCByZXBsYWNlIHdpdGggcmVzb2x2ZWQgcmVmc1xuICB2YXIgcmVmLCBhYnM7XG4gIGZvciAocmVmIGluIHJlc29sdXRpb25UYWJsZSkge1xuICAgIHZhciBpdGVtID0gcmVzb2x1dGlvblRhYmxlW3JlZl07XG5cbiAgICB2YXIga2V5ID0gaXRlbS5rZXk7XG4gICAgdmFyIHJlc29sdmVkVG8gPSByZXNvbHZlZFJlZnNba2V5XTtcbiAgICBpZiAocmVzb2x2ZWRUbykge1xuICAgICAgc3BlYy5kZWZpbml0aW9ucyA9IHNwZWMuZGVmaW5pdGlvbnMgfHwge307XG4gICAgICBpZiAoaXRlbS5yZXNvbHZlQXMgPT09ICdyZWYnKSB7XG4gICAgICAgIGlmIChsb2NhbFJlc29sdmUgIT09IHRydWUpIHtcbiAgICAgICAgICAvLyBkb24ndCByZXRhaW4gcm9vdCBmb3IgbG9jYWwgZGVmaW5pdGlvbnNcbiAgICAgICAgICBmb3IgKGtleSBpbiByZXNvbHZlZFRvLm9iaikge1xuICAgICAgICAgICAgYWJzID0gdGhpcy5yZXRhaW5Sb290KGtleSwgcmVzb2x2ZWRUby5vYmpba2V5XSwgaXRlbS5yb290KTtcbiAgICAgICAgICAgIHJlc29sdmVkVG8ub2JqW2tleV0gPSBhYnM7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHNwZWMuZGVmaW5pdGlvbnNbcmVzb2x2ZWRUby5uYW1lXSA9IHJlc29sdmVkVG8ub2JqO1xuICAgICAgICBpdGVtLm9iai4kcmVmID0gJyMvZGVmaW5pdGlvbnMvJyArIHJlc29sdmVkVG8ubmFtZTtcbiAgICAgIH0gZWxzZSBpZiAoaXRlbS5yZXNvbHZlQXMgPT09ICdpbmxpbmUnKSB7XG4gICAgICAgIHZhciB0YXJnZXRPYmogPSBpdGVtLm9iajtcbiAgICAgICAgdGFyZ2V0T2JqWyd4LXJlc29sdmVkLWZyb20nXSA9IFsgaXRlbS5rZXkgXTtcbiAgICAgICAgZGVsZXRlIHRhcmdldE9iai4kcmVmO1xuXG4gICAgICAgIGZvciAoa2V5IGluIHJlc29sdmVkVG8ub2JqKSB7XG4gICAgICAgICAgYWJzID0gcmVzb2x2ZWRUby5vYmpba2V5XTtcblxuICAgICAgICAgIGlmIChsb2NhbFJlc29sdmUgIT09IHRydWUpIHtcbiAgICAgICAgICAgIC8vIGRvbid0IHJldGFpbiByb290IGZvciBsb2NhbCBkZWZpbml0aW9uc1xuICAgICAgICAgICAgYWJzID0gdGhpcy5yZXRhaW5Sb290KGtleSwgcmVzb2x2ZWRUby5vYmpba2V5XSwgaXRlbS5yb290KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGFyZ2V0T2JqW2tleV0gPSBhYnM7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgdmFyIGV4aXN0aW5nVW5yZXNvbHZlZCA9IHRoaXMuY291bnRVbnJlc29sdmVkUmVmcyhzcGVjKTtcblxuICBpZihleGlzdGluZ1VucmVzb2x2ZWQgPT09IDAgfHwgdGhpcy5pdGVyYXRpb24gPiA1KSB7XG4gICAgdGhpcy5yZXNvbHZlQWxsT2Yoc3BlYy5kZWZpbml0aW9ucyk7XG4gICAgdGhpcy5yZXNvbHZlckNhY2hlID0gbnVsbDtcbiAgICBjYWxsYmFjay5jYWxsKHRoaXMuc2NvcGUsIHNwZWMsIHVucmVzb2x2ZWRSZWZzKTtcbiAgfVxuICBlbHNlIHtcbiAgICB0aGlzLml0ZXJhdGlvbiArPSAxO1xuICAgIHRoaXMucmVzb2x2ZShzcGVjLCByb290LCBjYWxsYmFjaywgdGhpcy5zY29wZSk7XG4gIH1cbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS5jb3VudFVucmVzb2x2ZWRSZWZzID0gZnVuY3Rpb24oc3BlYykge1xuICB2YXIgaTtcbiAgdmFyIHJlZnMgPSB0aGlzLmdldFJlZnMoc3BlYyk7XG4gIHZhciBrZXlzID0gW107XG4gIHZhciB1bnJlc29sdmVkS2V5cyA9IFtdO1xuICBmb3IoaSBpbiByZWZzKSB7XG4gICAgaWYoaS5pbmRleE9mKCcjJykgPT09IDApIHtcbiAgICAgIGtleXMucHVzaChpLnN1YnN0cmluZygxKSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgdW5yZXNvbHZlZEtleXMucHVzaChpKTtcbiAgICB9XG4gIH1cblxuICAvLyB2ZXJpZnkgcG9zc2libGUga2V5c1xuICBmb3IgKGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwYXJ0ID0ga2V5c1tpXTtcbiAgICB2YXIgcGFydHMgPSBwYXJ0LnNwbGl0KCcvJyk7XG4gICAgdmFyIG9iaiA9IHNwZWM7XG5cbiAgICBmb3IgKHZhciBrID0gMDsgayA8IHBhcnRzLmxlbmd0aDsgaysrKSB7XG4gICAgICB2YXIga2V5ID0gcGFydHNba107XG4gICAgICBpZihrZXkgIT09ICcnKSB7XG4gICAgICAgIG9iaiA9IG9ialtrZXldO1xuICAgICAgICBpZih0eXBlb2Ygb2JqID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIHVucmVzb2x2ZWRLZXlzLnB1c2gocGFydCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHVucmVzb2x2ZWRLZXlzLmxlbmd0aDtcbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS5nZXRSZWZzID0gZnVuY3Rpb24oc3BlYywgb2JqKSB7XG4gIG9iaiA9IG9iaiB8fCBzcGVjO1xuICB2YXIgb3V0cHV0ID0ge307XG4gIGZvcih2YXIga2V5IGluIG9iaikge1xuICAgIGlmICghb2JqLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICB2YXIgaXRlbSA9IG9ialtrZXldO1xuICAgIGlmKGtleSA9PT0gJyRyZWYnICYmIHR5cGVvZiBpdGVtID09PSAnc3RyaW5nJykge1xuICAgICAgb3V0cHV0W2l0ZW1dID0gbnVsbDtcbiAgICB9XG4gICAgZWxzZSBpZihfLmlzT2JqZWN0KGl0ZW0pKSB7XG4gICAgICB2YXIgbyA9IHRoaXMuZ2V0UmVmcyhpdGVtKTtcbiAgICAgIGZvcih2YXIgayBpbiBvKSB7XG4gICAgICAgIG91dHB1dFtrXSA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBvdXRwdXQ7XG59O1xuXG5mdW5jdGlvbiBzcGxpdFVybCh1cmwpIHtcbiAgdmFyIHJlc3VsdCA9IHt9O1xuICB2YXIgcHJvdG8gPSAvW2Etel0rOlxcL1xcLy9pLmV4ZWModXJsKTtcbiAgaWYgKHByb3RvKSB7XG4gICAgcmVzdWx0LnByb3RvID0gcHJvdG9bMF0uc2xpY2UoMCwgLTMpO1xuICAgIHVybCA9IHVybC5zbGljZShyZXN1bHQucHJvdG8ubGVuZ3RoICsgMSk7XG4gIH1cbiAgaWYgKHVybC5zbGljZSgwLCAyKSA9PT0gJy8vJykge1xuICAgIHJlc3VsdC5kb21haW4gPSB1cmwuc2xpY2UoMikuc3BsaXQoJy8nKVswXTtcbiAgICB1cmwgPSB1cmwuc2xpY2UoMiArIHJlc3VsdC5kb21haW4ubGVuZ3RoKTtcbiAgfVxuICB2YXIgcCA9IHVybC5zcGxpdCgnIycpO1xuICBpZiAocFswXS5sZW5ndGgpIHtcbiAgICByZXN1bHQucGF0aCA9IHBbMF07XG4gIH1cbiAgaWYgKHAubGVuZ3RoID4gMSkge1xuICAgIHJlc3VsdC5mcmFnbWVudCA9IHAuc2xpY2UoMSkuam9pbignIycpO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIHVuc3BsaXRVcmwodXJsKSB7XG4gIHZhciByZXN1bHQgPSB1cmwucGF0aDtcbiAgaWYgKHJlc3VsdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmVzdWx0ID0gJyc7XG4gIH1cbiAgaWYgKHVybC5mcmFnbWVudCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmVzdWx0ICs9ICcjJyArIHVybC5mcmFnbWVudDtcbiAgfVxuICBpZiAodXJsLmRvbWFpbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKHJlc3VsdC5zbGljZSgwLCAxKSA9PT0gJy8nKSB7XG4gICAgICByZXN1bHQgPSByZXN1bHQuc2xpY2UoMSk7XG4gICAgfVxuICAgIHJlc3VsdCA9ICcvLycgKyB1cmwuZG9tYWluICsgJy8nICsgcmVzdWx0O1xuICAgIGlmICh1cmwucHJvdG8gIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmVzdWx0ID0gdXJsLnByb3RvICsgJzonICsgcmVzdWx0O1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBqb2luVXJsKGJhc2UsIHJlbCkge1xuICB2YXIgcmVsc3AgPSBzcGxpdFVybChyZWwpO1xuICBpZiAocmVsc3AuZG9tYWluICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gcmVsO1xuICB9XG4gIHZhciByZXN1bHQgPSBzcGxpdFVybChiYXNlKTtcbiAgaWYgKHJlbHNwLnBhdGggPT09IHVuZGVmaW5lZCkge1xuICAgIC8vIGNoYW5nZSBvbmx5IGZyYWdtZW50IHBhcnRcbiAgICByZXN1bHQuZnJhZ21lbnQgPSByZWxzcC5mcmFnbWVudDtcbiAgfSBlbHNlIGlmIChyZWxzcC5wYXRoLnNsaWNlKDAsIDEpID09PSAnLycpIHtcbiAgICAvLyByZWxhdGl2ZSB0byBkb21haW5cbiAgICByZXN1bHQucGF0aCA9IHJlbHNwLnBhdGg7XG4gICAgcmVzdWx0LmZyYWdtZW50ID0gcmVsc3AuZnJhZ21lbnQ7XG4gIH0gZWxzZSB7XG4gICAgLy8gcmVsYXRpdmUgdG8gcGF0aFxuICAgIHZhciBwYXRoID0gcmVzdWx0LnBhdGggPT09IHVuZGVmaW5lZCA/IFtdIDogcmVzdWx0LnBhdGguc3BsaXQoJy8nKTtcbiAgICB2YXIgcmVscGF0aCA9IHJlbHNwLnBhdGguc3BsaXQoJy8nKTtcbiAgICBpZiAocGF0aC5sZW5ndGgpIHtcbiAgICAgIHBhdGgucG9wKCk7XG4gICAgfVxuICAgIHdoaWxlIChyZWxwYXRoWzBdID09PSAnLi4nIHx8IHJlbHBhdGhbMF0gPT09ICcuJykge1xuICAgICAgaWYgKHJlbHBhdGhbMF0gPT09ICcuLicpIHtcbiAgICAgICAgcGF0aC5wb3AoKTtcbiAgICAgIH1cbiAgICAgIHJlbHBhdGguc2hpZnQoKTtcbiAgICB9XG4gICAgcmVzdWx0LnBhdGggPSBwYXRoLmNvbmNhdChyZWxwYXRoKS5qb2luKCcvJyk7XG4gICAgcmVzdWx0LmZyYWdtZW50ID0gcmVsc3AuZnJhZ21lbnQ7XG4gIH1cbiAgcmV0dXJuIHVuc3BsaXRVcmwocmVzdWx0KTtcbn1cblxuUmVzb2x2ZXIucHJvdG90eXBlLnJldGFpblJvb3QgPSBmdW5jdGlvbihvcmlnS2V5LCBvYmosIHJvb3QpIHtcbiAgLy8gd2FsayBvYmplY3QgYW5kIGxvb2sgZm9yIHJlbGF0aXZlICRyZWZzXG4gIGlmKF8uaXNPYmplY3Qob2JqKSkge1xuICAgIGZvcih2YXIga2V5IGluIG9iaikge1xuICAgICAgdmFyIGl0ZW0gPSBvYmpba2V5XTtcbiAgICAgIGlmIChrZXkgPT09ICckcmVmJyAmJiB0eXBlb2YgaXRlbSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgb2JqW2tleV0gPSBqb2luVXJsKHJvb3QsIGl0ZW0pO1xuICAgICAgfVxuICAgICAgZWxzZSBpZiAoXy5pc09iamVjdChpdGVtKSkge1xuICAgICAgICB0aGlzLnJldGFpblJvb3Qoa2V5LCBpdGVtLCByb290KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgZWxzZSBpZihfLmlzU3RyaW5nKG9iaikgJiYgb3JpZ0tleSA9PT0gJyRyZWYnKSB7XG4gICAgb2JqID0gam9pblVybChyb290LCBvYmopO1xuICB9XG4gIHJldHVybiBvYmo7XG59O1xuXG4vKipcbiAqIGltbWVkaWF0ZWx5IGluLWxpbmVzIGxvY2FsIHJlZnMsIHF1ZXVlcyByZW1vdGUgcmVmc1xuICogZm9yIGlubGluZSByZXNvbHV0aW9uXG4gKi9cblJlc29sdmVyLnByb3RvdHlwZS5yZXNvbHZlSW5saW5lID0gZnVuY3Rpb24gKHJvb3QsIHNwZWMsIHByb3BlcnR5LCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBsb2NhdGlvbikge1xuICB2YXIga2V5ID0gcHJvcGVydHkuJHJlZiwgcmVmID0gcHJvcGVydHkuJHJlZiwgaSwgcCwgcDIsIHJzO1xuICB2YXIgcm9vdFRyaW1tZWQgPSBmYWxzZTtcblxuICByb290ID0gcm9vdCB8fCAnJzsgLy8gR3VhcmQgYWdhaW5zdCAuc3BsaXQuIEBmZWhndXksIHlvdSdsbCBuZWVkIHRvIGNoZWNrIGlmIHRoaXMgbG9naWMgZml0c1xuICAvLyBNb3JlIGltcG9yYW50bHkgaXMgaG93IGRvIHdlIGdyYWNlZnVsbHkgaGFuZGxlIHJlbGF0aXZlIHVybHMsIHdoZW4gcHJvdmlkZWQganVzdCBhICdzcGVjJywgbm90IGEgJ3VybCcgP1xuXG4gIGlmIChyZWYpIHtcbiAgICBpZihyZWYuaW5kZXhPZignLi4vJykgPT09IDApIHtcbiAgICAgIC8vIHJlc2V0IHJvb3RcbiAgICAgIHAgPSByZWYuc3BsaXQoJy4uLycpO1xuICAgICAgcDIgPSByb290LnNwbGl0KCcvJyk7XG4gICAgICByZWYgPSAnJztcbiAgICAgIGZvcihpID0gMDsgaSA8IHAubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYocFtpXSA9PT0gJycpIHtcbiAgICAgICAgICBwMiA9IHAyLnNsaWNlKDAsIHAyLmxlbmd0aC0xKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICByZWYgKz0gcFtpXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcm9vdCA9ICcnO1xuICAgICAgZm9yKGkgPSAwOyBpIDwgcDIubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgIGlmKGkgPiAwKSB7IHJvb3QgKz0gJy8nOyB9XG4gICAgICAgIHJvb3QgKz0gcDJbaV07XG4gICAgICB9XG4gICAgICByb290VHJpbW1lZCA9IHRydWU7XG4gICAgfVxuICAgIGlmKHJlZi5pbmRleE9mKCcjJykgPj0gMCkge1xuICAgICAgaWYocmVmLmluZGV4T2YoJy8nKSA9PT0gMCkge1xuICAgICAgICBycyA9IHJlZi5zcGxpdCgnIycpO1xuICAgICAgICBwICA9IHJvb3Quc3BsaXQoJy8vJyk7XG4gICAgICAgIHAyID0gcFsxXS5zcGxpdCgnLycpO1xuICAgICAgICByb290ID0gcFswXSArICcvLycgKyBwMlswXSArIHJzWzBdO1xuICAgICAgICBsb2NhdGlvbiA9IHJzWzFdO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHJzID0gcmVmLnNwbGl0KCcjJyk7XG4gICAgICAgIGlmKHJzWzBdICE9PSAnJykge1xuICAgICAgICAgIHAyID0gcm9vdC5zcGxpdCgnLycpO1xuICAgICAgICAgIHAyID0gcDIuc2xpY2UoMCwgcDIubGVuZ3RoIC0gMSk7XG4gICAgICAgICAgaWYoIXJvb3RUcmltbWVkKSB7XG4gICAgICAgICAgICByb290ID0gJyc7XG4gICAgICAgICAgICBmb3IgKHZhciBrID0gMDsgayA8IHAyLmxlbmd0aDsgaysrKSB7XG4gICAgICAgICAgICAgIGlmKGsgPiAwKSB7IHJvb3QgKz0gJy8nOyB9XG4gICAgICAgICAgICAgIHJvb3QgKz0gcDJba107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHJvb3QgKz0gJy8nICsgcmVmLnNwbGl0KCcjJylbMF07XG4gICAgICAgIH1cbiAgICAgICAgbG9jYXRpb24gPSByc1sxXTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHJlZi5pbmRleE9mKCdodHRwOicpID09PSAwIHx8IHJlZi5pbmRleE9mKCdodHRwczonKSA9PT0gMCkge1xuICAgICAgaWYocmVmLmluZGV4T2YoJyMnKSA+PSAwKSB7XG4gICAgICAgIHJvb3QgPSByZWYuc3BsaXQoJyMnKVswXTtcbiAgICAgICAgbG9jYXRpb24gPSByZWYuc3BsaXQoJyMnKVsxXTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICByb290ID0gcmVmO1xuICAgICAgICBsb2NhdGlvbiA9ICcnO1xuICAgICAgfVxuICAgICAgcmVzb2x1dGlvblRhYmxlLnB1c2goe29iajogcHJvcGVydHksIHJlc29sdmVBczogJ2lubGluZScsIHJvb3Q6IHJvb3QsIGtleToga2V5LCBsb2NhdGlvbjogbG9jYXRpb259KTtcbiAgICB9IGVsc2UgaWYgKHJlZi5pbmRleE9mKCcjJykgPT09IDApIHtcbiAgICAgIGxvY2F0aW9uID0gcmVmLnNwbGl0KCcjJylbMV07XG4gICAgICByZXNvbHV0aW9uVGFibGUucHVzaCh7b2JqOiBwcm9wZXJ0eSwgcmVzb2x2ZUFzOiAnaW5saW5lJywgcm9vdDogcm9vdCwga2V5OiBrZXksIGxvY2F0aW9uOiBsb2NhdGlvbn0pO1xuICAgIH0gZWxzZSBpZiAocmVmLmluZGV4T2YoJy8nKSA9PT0gMCAmJiByZWYuaW5kZXhPZignIycpID09PSAtMSkge1xuICAgICAgbG9jYXRpb24gPSByZWY7XG4gICAgICB2YXIgbWF0Y2hlcyA9IHJvb3QubWF0Y2goL15odHRwcz9cXDpcXC9cXC8oW15cXC8/I10rKSg/OltcXC8/I118JCkvaSk7XG4gICAgICBpZihtYXRjaGVzKSB7XG4gICAgICAgIHJvb3QgPSBtYXRjaGVzWzBdICsgcmVmLnN1YnN0cmluZygxKTtcbiAgICAgICAgbG9jYXRpb24gPSAnJztcbiAgICAgIH1cbiAgICAgIHJlc29sdXRpb25UYWJsZS5wdXNoKHtvYmo6IHByb3BlcnR5LCByZXNvbHZlQXM6ICdpbmxpbmUnLCByb290OiByb290LCBrZXk6IGtleSwgbG9jYXRpb246IGxvY2F0aW9ufSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgcmVzb2x1dGlvblRhYmxlLnB1c2goe29iajogcHJvcGVydHksIHJlc29sdmVBczogJ2lubGluZScsIHJvb3Q6IHJvb3QsIGtleToga2V5LCBsb2NhdGlvbjogbG9jYXRpb259KTtcbiAgICB9XG4gIH1cbiAgZWxzZSBpZiAocHJvcGVydHkudHlwZSA9PT0gJ2FycmF5Jykge1xuICAgIHRoaXMucmVzb2x2ZVRvKHJvb3QsIHByb3BlcnR5Lml0ZW1zLCByZXNvbHV0aW9uVGFibGUsIGxvY2F0aW9uKTtcbiAgfVxufTtcblxuUmVzb2x2ZXIucHJvdG90eXBlLnJlc29sdmVUbyA9IGZ1bmN0aW9uIChyb290LCBwcm9wZXJ0eSwgcmVzb2x1dGlvblRhYmxlLCBsb2NhdGlvbikge1xuICB2YXIgc3AsIGk7XG4gIHZhciByZWYgPSBwcm9wZXJ0eS4kcmVmO1xuICB2YXIgbHJvb3QgPSByb290O1xuICBpZiAoKHR5cGVvZiByZWYgIT09ICd1bmRlZmluZWQnKSAmJiAocmVmICE9PSBudWxsKSkge1xuICAgIGlmKHJlZi5pbmRleE9mKCcjJykgPj0gMCkge1xuICAgICAgdmFyIHBhcnRzID0gcmVmLnNwbGl0KCcjJyk7XG5cbiAgICAgIC8vICMvZGVmaW5pdGlvbnMvZm9vXG4gICAgICAvLyBmb28uanNvbiMvYmFyXG4gICAgICBpZihwYXJ0c1swXSAmJiByZWYuaW5kZXhPZignLycpID09PSAwKSB7XG5cbiAgICAgIH1cbiAgICAgIGVsc2UgaWYocGFydHNbMF0gJiYgKHBhcnRzWzBdLmluZGV4T2YoJ2h0dHA6JykgPT09IDAgfHwgcGFydHNbMF0uaW5kZXhPZignaHR0cHM6JykgPT09IDApKSB7XG4gICAgICAgIGxyb290ID0gcGFydHNbMF07XG4gICAgICAgIHJlZiA9IHBhcnRzWzFdO1xuICAgICAgfVxuICAgICAgZWxzZSBpZihwYXJ0c1swXSAmJiBwYXJ0c1swXS5sZW5ndGggPiAwKSB7XG4gICAgICAgIC8vIHJlbGF0aXZlIGZpbGVcbiAgICAgICAgc3AgPSByb290LnNwbGl0KCcvJyk7XG4gICAgICAgIGxyb290ID0gJyc7XG4gICAgICAgIGZvcihpID0gMDsgaSA8IHNwLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgICAgIGxyb290ICs9IHNwW2ldICsgJy8nO1xuICAgICAgICB9XG4gICAgICAgIGxyb290ICs9IHBhcnRzWzBdO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG5cbiAgICAgIH1cblxuICAgICAgbG9jYXRpb24gPSBwYXJ0c1sxXTtcbiAgICB9XG4gICAgZWxzZSBpZiAocmVmLmluZGV4T2YoJ2h0dHA6JykgPT09IDAgfHwgcmVmLmluZGV4T2YoJ2h0dHBzOicpID09PSAwKSB7XG4gICAgICBscm9vdCA9IHJlZjtcbiAgICAgIGxvY2F0aW9uID0gJyc7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgLy8gcmVsYXRpdmUgZmlsZVxuICAgICAgc3AgPSByb290LnNwbGl0KCcvJyk7XG4gICAgICBscm9vdCA9ICcnO1xuICAgICAgZm9yKGkgPSAwOyBpIDwgc3AubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgIGxyb290ICs9IHNwW2ldICsgJy8nO1xuICAgICAgfVxuICAgICAgbHJvb3QgKz0gcmVmO1xuICAgICAgbG9jYXRpb24gPSAnJztcbiAgICB9XG4gICAgcmVzb2x1dGlvblRhYmxlLnB1c2goe1xuICAgICAgb2JqOiBwcm9wZXJ0eSwgcmVzb2x2ZUFzOiAncmVmJywgcm9vdDogbHJvb3QsIGtleTogcmVmLCBsb2NhdGlvbjogbG9jYXRpb25cbiAgICB9KTtcbiAgfSBlbHNlIGlmIChwcm9wZXJ0eS50eXBlID09PSAnYXJyYXknKSB7XG4gICAgdmFyIGl0ZW1zID0gcHJvcGVydHkuaXRlbXM7XG4gICAgdGhpcy5yZXNvbHZlVG8ocm9vdCwgaXRlbXMsIHJlc29sdXRpb25UYWJsZSwgbG9jYXRpb24pO1xuICB9IGVsc2Uge1xuICAgIGlmKHByb3BlcnR5ICYmIChwcm9wZXJ0eS5wcm9wZXJ0aWVzIHx8IHByb3BlcnR5LmFkZGl0aW9uYWxQcm9wZXJ0aWVzKSkge1xuICAgICAgdmFyIG5hbWUgPSB0aGlzLnVuaXF1ZU5hbWUoJ2lubGluZV9tb2RlbCcpO1xuICAgICAgaWYgKHByb3BlcnR5LnRpdGxlKSB7XG4gICAgICAgIG5hbWUgPSB0aGlzLnVuaXF1ZU5hbWUocHJvcGVydHkudGl0bGUpO1xuICAgICAgfVxuICAgICAgZGVsZXRlIHByb3BlcnR5LnRpdGxlO1xuICAgICAgdGhpcy5zcGVjLmRlZmluaXRpb25zW25hbWVdID0gXy5jbG9uZURlZXAocHJvcGVydHkpO1xuICAgICAgcHJvcGVydHkuJHJlZiA9ICcjL2RlZmluaXRpb25zLycgKyBuYW1lO1xuICAgICAgZGVsZXRlIHByb3BlcnR5LnR5cGU7XG4gICAgICBkZWxldGUgcHJvcGVydHkucHJvcGVydGllcztcbiAgICB9XG4gIH1cbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS51bmlxdWVOYW1lID0gZnVuY3Rpb24oYmFzZSkge1xuICB2YXIgbmFtZSA9IGJhc2U7XG4gIHZhciBjb3VudCA9IDA7XG4gIHdoaWxlKHRydWUpIHtcbiAgICBpZighXy5pc09iamVjdCh0aGlzLnNwZWMuZGVmaW5pdGlvbnNbbmFtZV0pKSB7XG4gICAgICByZXR1cm4gbmFtZTtcbiAgICB9XG4gICAgbmFtZSA9IGJhc2UgKyAnXycgKyBjb3VudDtcbiAgICBjb3VudCsrO1xuICB9XG59O1xuXG5SZXNvbHZlci5wcm90b3R5cGUucmVzb2x2ZUFsbE9mID0gZnVuY3Rpb24oc3BlYywgb2JqLCBkZXB0aCkge1xuICBkZXB0aCA9IGRlcHRoIHx8IDA7XG4gIG9iaiA9IG9iaiB8fCBzcGVjO1xuICB2YXIgbmFtZTtcbiAgZm9yKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgaWYgKCFvYmouaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIHZhciBpdGVtID0gb2JqW2tleV07XG4gICAgaWYoaXRlbSA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignU3dhZ2dlciAyLjAgZG9lcyBub3Qgc3VwcG9ydCBudWxsIHR5cGVzICgnICsgb2JqICsgJykuICBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3N3YWdnZXItYXBpL3N3YWdnZXItc3BlYy9pc3N1ZXMvMjI5LicpO1xuICAgIH1cbiAgICBpZih0eXBlb2YgaXRlbSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIHRoaXMucmVzb2x2ZUFsbE9mKHNwZWMsIGl0ZW0sIGRlcHRoICsgMSk7XG4gICAgfVxuICAgIGlmKGl0ZW0gJiYgdHlwZW9mIGl0ZW0uYWxsT2YgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB2YXIgYWxsT2YgPSBpdGVtLmFsbE9mO1xuICAgICAgaWYoXy5pc0FycmF5KGFsbE9mKSkge1xuICAgICAgICB2YXIgb3V0cHV0ID0gXy5jbG9uZURlZXAoaXRlbSk7XG4gICAgICAgIGRlbGV0ZSBvdXRwdXQuYWxsT2Y7XG5cbiAgICAgICAgb3V0cHV0Wyd4LWNvbXBvc2VkJ10gPSB0cnVlO1xuICAgICAgICBpZiAodHlwZW9mIGl0ZW1bJ3gtcmVzb2x2ZWQtZnJvbSddICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIG91dHB1dFsneC1yZXNvbHZlZC1mcm9tJ10gPSBpdGVtWyd4LXJlc29sdmVkLWZyb20nXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBhbGxPZi5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIHZhciBjb21wb25lbnQgPSBhbGxPZltpXTtcbiAgICAgICAgICB2YXIgc291cmNlID0gJ3NlbGYnO1xuICAgICAgICAgIGlmKHR5cGVvZiBjb21wb25lbnRbJ3gtcmVzb2x2ZWQtZnJvbSddICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgc291cmNlID0gY29tcG9uZW50Wyd4LXJlc29sdmVkLWZyb20nXVswXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBmb3IodmFyIHBhcnQgaW4gY29tcG9uZW50KSB7XG4gICAgICAgICAgICBpZighb3V0cHV0Lmhhc093blByb3BlcnR5KHBhcnQpKSB7XG4gICAgICAgICAgICAgIG91dHB1dFtwYXJ0XSA9IF8uY2xvbmVEZWVwKGNvbXBvbmVudFtwYXJ0XSk7XG4gICAgICAgICAgICAgIGlmKHBhcnQgPT09ICdwcm9wZXJ0aWVzJykge1xuICAgICAgICAgICAgICAgIGZvcihuYW1lIGluIG91dHB1dFtwYXJ0XSkge1xuICAgICAgICAgICAgICAgICAgb3V0cHV0W3BhcnRdW25hbWVdWyd4LXJlc29sdmVkLWZyb20nXSA9IHNvdXJjZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICBpZihwYXJ0ID09PSAncHJvcGVydGllcycpIHtcbiAgICAgICAgICAgICAgICB2YXIgcHJvcGVydGllcyA9IGNvbXBvbmVudFtwYXJ0XTtcbiAgICAgICAgICAgICAgICBmb3IobmFtZSBpbiBwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICAgICAgICBvdXRwdXQucHJvcGVydGllc1tuYW1lXSA9IF8uY2xvbmVEZWVwKHByb3BlcnRpZXNbbmFtZV0pO1xuICAgICAgICAgICAgICAgICAgdmFyIHJlc29sdmVkRnJvbSA9IHByb3BlcnRpZXNbbmFtZV1bJ3gtcmVzb2x2ZWQtZnJvbSddO1xuICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiByZXNvbHZlZEZyb20gPT09ICd1bmRlZmluZWQnIHx8IHJlc29sdmVkRnJvbSA9PT0gJ3NlbGYnKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmVkRnJvbSA9IHNvdXJjZTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIG91dHB1dC5wcm9wZXJ0aWVzW25hbWVdWyd4LXJlc29sdmVkLWZyb20nXSA9IHJlc29sdmVkRnJvbTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZWxzZSBpZihwYXJ0ID09PSAncmVxdWlyZWQnKSB7XG4gICAgICAgICAgICAgICAgLy8gbWVyZ2UgJiBkZWR1cCB0aGUgcmVxdWlyZWQgYXJyYXlcbiAgICAgICAgICAgICAgICB2YXIgYSA9IG91dHB1dC5yZXF1aXJlZC5jb25jYXQoY29tcG9uZW50W3BhcnRdKTtcbiAgICAgICAgICAgICAgICBmb3IodmFyIGsgPSAwOyBrIDwgYS5sZW5ndGg7ICsraykge1xuICAgICAgICAgICAgICAgICAgZm9yKHZhciBqID0gayArIDE7IGogPCBhLmxlbmd0aDsgKytqKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmKGFba10gPT09IGFbal0pIHsgYS5zcGxpY2Uoai0tLCAxKTsgfVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvdXRwdXQucmVxdWlyZWQgPSBhO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGVsc2UgaWYocGFydCA9PT0gJ3gtcmVzb2x2ZWQtZnJvbScpIHtcbiAgICAgICAgICAgICAgICBvdXRwdXRbJ3gtcmVzb2x2ZWQtZnJvbSddLnB1c2goc291cmNlKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBUT0RPOiBuZWVkIHRvIG1lcmdlIHRoaXMgcHJvcGVydHlcbiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZygnd2hhdCB0byBkbyB3aXRoICcgKyBwYXJ0KVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIG9ialtrZXldID0gb3V0cHV0O1xuICAgICAgfVxuICAgIH1cbiAgfVxufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIEhlbHBlcnMgPSByZXF1aXJlKCcuL2hlbHBlcnMnKTtcblxudmFyIF8gPSB7XG4gIGlzUGxhaW5PYmplY3Q6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc1BsYWluT2JqZWN0JyksXG4gIGlzVW5kZWZpbmVkOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNVbmRlZmluZWQnKSxcbiAgaXNBcnJheTogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzQXJyYXknKSxcbiAgaXNPYmplY3Q6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc09iamVjdCcpLFxuICBpc0VtcHR5OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNFbXB0eScpLFxuICBtYXA6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9tYXAnKSxcbiAgaW5kZXhPZjogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9hcnJheS9pbmRleE9mJyksXG4gIGNsb25lRGVlcDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2Nsb25lRGVlcCcpLFxuICBrZXlzOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L29iamVjdC9rZXlzJyksXG4gIGZvckVhY2g6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9mb3JFYWNoJylcbn07XG5cbnZhciBvcHRpb25IdG1sID0gbW9kdWxlLmV4cG9ydHMub3B0aW9uSHRtbCA9IGZ1bmN0aW9uICAobGFiZWwsIHZhbHVlKSB7XG4gIHJldHVybiAnPHRyPjx0ZCBjbGFzcz1cIm9wdGlvbk5hbWVcIj4nICsgbGFiZWwgKyAnOjwvdGQ+PHRkPicgKyB2YWx1ZSArICc8L3RkPjwvdHI+Jztcbn07XG5cbm1vZHVsZS5leHBvcnRzLnR5cGVGcm9tSnNvblNjaGVtYSA9IGZ1bmN0aW9uICh0eXBlLCBmb3JtYXQpIHtcbiAgdmFyIHN0cjtcblxuICBpZiAodHlwZSA9PT0gJ2ludGVnZXInICYmIGZvcm1hdCA9PT0gJ2ludDMyJykge1xuICAgIHN0ciA9ICdpbnRlZ2VyJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnaW50ZWdlcicgJiYgZm9ybWF0ID09PSAnaW50NjQnKSB7XG4gICAgc3RyID0gJ2xvbmcnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdpbnRlZ2VyJyAmJiB0eXBlb2YgZm9ybWF0ID09PSAndW5kZWZpbmVkJykge1xuICAgIHN0ciA9ICdsb25nJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnc3RyaW5nJyAmJiBmb3JtYXQgPT09ICdkYXRlLXRpbWUnKSB7XG4gICAgc3RyID0gJ2RhdGUtdGltZSc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3N0cmluZycgJiYgZm9ybWF0ID09PSAnZGF0ZScpIHtcbiAgICBzdHIgPSAnZGF0ZSc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ251bWJlcicgJiYgZm9ybWF0ID09PSAnZmxvYXQnKSB7XG4gICAgc3RyID0gJ2Zsb2F0JztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJyAmJiBmb3JtYXQgPT09ICdkb3VibGUnKSB7XG4gICAgc3RyID0gJ2RvdWJsZSc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ251bWJlcicgJiYgdHlwZW9mIGZvcm1hdCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBzdHIgPSAnZG91YmxlJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnYm9vbGVhbicpIHtcbiAgICBzdHIgPSAnYm9vbGVhbic7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICBzdHIgPSAnc3RyaW5nJztcbiAgfVxuXG4gIHJldHVybiBzdHI7XG59O1xuXG52YXIgZ2V0U3RyaW5nU2lnbmF0dXJlID0gbW9kdWxlLmV4cG9ydHMuZ2V0U3RyaW5nU2lnbmF0dXJlID0gZnVuY3Rpb24gKG9iaiwgYmFzZUNvbXBvbmVudCkge1xuICB2YXIgc3RyID0gJyc7XG5cbiAgaWYgKHR5cGVvZiBvYmouJHJlZiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBzdHIgKz0gSGVscGVycy5zaW1wbGVSZWYob2JqLiRyZWYpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBvYmoudHlwZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBzdHIgKz0gJ29iamVjdCc7XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdhcnJheScpIHtcbiAgICBpZiAoYmFzZUNvbXBvbmVudCkge1xuICAgICAgc3RyICs9IGdldFN0cmluZ1NpZ25hdHVyZSgob2JqLml0ZW1zIHx8IG9iai4kcmVmIHx8IHt9KSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ciArPSAnQXJyYXlbJztcbiAgICAgIHN0ciArPSBnZXRTdHJpbmdTaWduYXR1cmUoKG9iai5pdGVtcyB8fCBvYmouJHJlZiB8fCB7fSkpO1xuICAgICAgc3RyICs9ICddJztcbiAgICB9XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdpbnRlZ2VyJyAmJiBvYmouZm9ybWF0ID09PSAnaW50MzInKSB7XG4gICAgc3RyICs9ICdpbnRlZ2VyJztcbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ2ludGVnZXInICYmIG9iai5mb3JtYXQgPT09ICdpbnQ2NCcpIHtcbiAgICBzdHIgKz0gJ2xvbmcnO1xuICB9IGVsc2UgaWYgKG9iai50eXBlID09PSAnaW50ZWdlcicgJiYgdHlwZW9mIG9iai5mb3JtYXQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgc3RyICs9ICdsb25nJztcbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ3N0cmluZycgJiYgb2JqLmZvcm1hdCA9PT0gJ2RhdGUtdGltZScpIHtcbiAgICBzdHIgKz0gJ2RhdGUtdGltZSc7XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdzdHJpbmcnICYmIG9iai5mb3JtYXQgPT09ICdkYXRlJykge1xuICAgIHN0ciArPSAnZGF0ZSc7XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdzdHJpbmcnICYmIHR5cGVvZiBvYmouZm9ybWF0ID09PSAndW5kZWZpbmVkJykge1xuICAgIHN0ciArPSAnc3RyaW5nJztcbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ251bWJlcicgJiYgb2JqLmZvcm1hdCA9PT0gJ2Zsb2F0Jykge1xuICAgIHN0ciArPSAnZmxvYXQnO1xuICB9IGVsc2UgaWYgKG9iai50eXBlID09PSAnbnVtYmVyJyAmJiBvYmouZm9ybWF0ID09PSAnZG91YmxlJykge1xuICAgIHN0ciArPSAnZG91YmxlJztcbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ251bWJlcicgJiYgdHlwZW9mIG9iai5mb3JtYXQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgc3RyICs9ICdkb3VibGUnO1xuICB9IGVsc2UgaWYgKG9iai50eXBlID09PSAnYm9vbGVhbicpIHtcbiAgICBzdHIgKz0gJ2Jvb2xlYW4nO1xuICB9IGVsc2UgaWYgKG9iai4kcmVmKSB7XG4gICAgc3RyICs9IEhlbHBlcnMuc2ltcGxlUmVmKG9iai4kcmVmKTtcbiAgfSBlbHNlIHtcbiAgICBzdHIgKz0gb2JqLnR5cGU7XG4gIH1cblxuICByZXR1cm4gc3RyO1xufTtcblxudmFyIHNjaGVtYVRvSlNPTiA9IG1vZHVsZS5leHBvcnRzLnNjaGVtYVRvSlNPTiA9IGZ1bmN0aW9uIChzY2hlbWEsIG1vZGVscywgbW9kZWxzVG9JZ25vcmUsIG1vZGVsUHJvcGVydHlNYWNybykge1xuICAvLyBSZXNvbHZlIHRoZSBzY2hlbWEgKEhhbmRsZSBuZXN0ZWQgc2NoZW1hcylcbiAgc2NoZW1hID0gSGVscGVycy5yZXNvbHZlU2NoZW1hKHNjaGVtYSk7XG5cbiAgaWYodHlwZW9mIG1vZGVsUHJvcGVydHlNYWNybyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIG1vZGVsUHJvcGVydHlNYWNybyA9IGZ1bmN0aW9uKHByb3Ape1xuICAgICAgcmV0dXJuIChwcm9wIHx8IHt9KS5kZWZhdWx0O1xuICAgIH07XG4gIH1cblxuICBtb2RlbHNUb0lnbm9yZT0gbW9kZWxzVG9JZ25vcmUgfHwge307XG5cbiAgdmFyIHR5cGUgPSBzY2hlbWEudHlwZSB8fCAnb2JqZWN0JztcbiAgdmFyIGZvcm1hdCA9IHNjaGVtYS5mb3JtYXQ7XG4gIHZhciBtb2RlbDtcbiAgdmFyIG91dHB1dDtcblxuICBpZiAoIV8uaXNVbmRlZmluZWQoc2NoZW1hLmV4YW1wbGUpKSB7XG4gICAgb3V0cHV0ID0gc2NoZW1hLmV4YW1wbGU7XG4gIH0gZWxzZSBpZiAoXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMpICYmIF8uaXNBcnJheShzY2hlbWEuZW51bSkpIHtcbiAgICBvdXRwdXQgPSBzY2hlbWEuZW51bVswXTtcbiAgfVxuXG4gIGlmIChfLmlzVW5kZWZpbmVkKG91dHB1dCkpIHtcbiAgICBpZiAoc2NoZW1hLiRyZWYpIHtcbiAgICAgIG1vZGVsID0gbW9kZWxzW0hlbHBlcnMuc2ltcGxlUmVmKHNjaGVtYS4kcmVmKV07XG5cbiAgICAgIGlmICghXy5pc1VuZGVmaW5lZChtb2RlbCkpIHtcbiAgICAgICAgaWYgKF8uaXNVbmRlZmluZWQobW9kZWxzVG9JZ25vcmVbbW9kZWwubmFtZV0pKSB7XG4gICAgICAgICAgbW9kZWxzVG9JZ25vcmVbbW9kZWwubmFtZV0gPSBtb2RlbDtcbiAgICAgICAgICBvdXRwdXQgPSBzY2hlbWFUb0pTT04obW9kZWwuZGVmaW5pdGlvbiwgbW9kZWxzLCBtb2RlbHNUb0lnbm9yZSwgbW9kZWxQcm9wZXJ0eU1hY3JvKTtcbiAgICAgICAgICBkZWxldGUgbW9kZWxzVG9JZ25vcmVbbW9kZWwubmFtZV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKG1vZGVsLnR5cGUgPT09ICdhcnJheScpIHtcbiAgICAgICAgICAgIG91dHB1dCA9IFtdO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBvdXRwdXQgPSB7fTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKCFfLmlzVW5kZWZpbmVkKHNjaGVtYS5kZWZhdWx0KSkge1xuICAgICAgb3V0cHV0ID0gc2NoZW1hLmRlZmF1bHQ7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgaWYgKGZvcm1hdCA9PT0gJ2RhdGUtdGltZScpIHtcbiAgICAgICAgb3V0cHV0ID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpO1xuICAgICAgfSBlbHNlIGlmIChmb3JtYXQgPT09ICdkYXRlJykge1xuICAgICAgICBvdXRwdXQgPSBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCkuc3BsaXQoJ1QnKVswXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG91dHB1dCA9ICdzdHJpbmcnO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2ludGVnZXInKSB7XG4gICAgICBvdXRwdXQgPSAwO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ251bWJlcicpIHtcbiAgICAgIG91dHB1dCA9IDAuMDtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdib29sZWFuJykge1xuICAgICAgb3V0cHV0ID0gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgICBvdXRwdXQgPSB7fTtcblxuICAgICAgXy5mb3JFYWNoKHNjaGVtYS5wcm9wZXJ0aWVzLCBmdW5jdGlvbiAocHJvcGVydHksIG5hbWUpIHtcbiAgICAgICAgdmFyIGNQcm9wZXJ0eSA9IF8uY2xvbmVEZWVwKHByb3BlcnR5KTtcblxuICAgICAgICAvLyBBbGxvdyBtYWNybyB0byBzZXQgdGhlIGRlZmF1bHQgdmFsdWVcbiAgICAgICAgY1Byb3BlcnR5LmRlZmF1bHQgPSBtb2RlbFByb3BlcnR5TWFjcm8ocHJvcGVydHkpO1xuXG4gICAgICAgIG91dHB1dFtuYW1lXSA9IHNjaGVtYVRvSlNPTihjUHJvcGVydHksIG1vZGVscywgbW9kZWxzVG9JZ25vcmUsIG1vZGVsUHJvcGVydHlNYWNybyk7XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdhcnJheScpIHtcbiAgICAgIG91dHB1dCA9IFtdO1xuXG4gICAgICBpZiAoXy5pc0FycmF5KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgXy5mb3JFYWNoKHNjaGVtYS5pdGVtcywgZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICBvdXRwdXQucHVzaChzY2hlbWFUb0pTT04oaXRlbSwgbW9kZWxzLCBtb2RlbHNUb0lnbm9yZSwgbW9kZWxQcm9wZXJ0eU1hY3JvKSk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmIChfLmlzUGxhaW5PYmplY3Qoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICBvdXRwdXQucHVzaChzY2hlbWFUb0pTT04oc2NoZW1hLml0ZW1zLCBtb2RlbHMsIG1vZGVsc1RvSWdub3JlLCBtb2RlbFByb3BlcnR5TWFjcm8pKTtcbiAgICAgIH0gZWxzZSBpZiAoXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMpKSB7XG4gICAgICAgIG91dHB1dC5wdXNoKHt9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIEhlbHBlcnMubG9nKCdBcnJheSB0eXBlXFwncyBcXCdpdGVtc1xcJyBwcm9wZXJ0eSBpcyBub3QgYW4gYXJyYXkgb3IgYW4gb2JqZWN0LCBjYW5ub3QgcHJvY2VzcycpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvdXRwdXQ7XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5zY2hlbWFUb0hUTUwgPWZ1bmN0aW9uIChuYW1lLCBzY2hlbWEsIG1vZGVscywgbW9kZWxQcm9wZXJ0eU1hY3JvKSB7XG4gIHZhciBzdHJvbmdPcGVuID0gJzxzcGFuIGNsYXNzPVwic3Ryb25nXCI+JztcbiAgdmFyIHN0cm9uZ0Nsb3NlID0gJzwvc3Bhbj4nO1xuXG4gIC8vIEFsbG93IGZvciBpZ25vcmluZyB0aGUgJ25hbWUnIGFyZ3VtZW50Li4uLiBzaGlmdGluZyB0aGUgcmVzdFxuICBpZihfLmlzT2JqZWN0KGFyZ3VtZW50c1swXSkpIHtcbiAgICBuYW1lID0gdm9pZCAwO1xuICAgIHNjaGVtYSA9IGFyZ3VtZW50c1swXTtcbiAgICBtb2RlbHMgPSBhcmd1bWVudHNbMV07XG4gICAgbW9kZWxQcm9wZXJ0eU1hY3JvID0gYXJndW1lbnRzWzJdO1xuICB9XG5cbiAgbW9kZWxzID0gbW9kZWxzIHx8IHt9O1xuXG4gIC8vIFJlc29sdmUgdGhlIHNjaGVtYSAoSGFuZGxlIG5lc3RlZCBzY2hlbWFzKVxuICBzY2hlbWEgPSBIZWxwZXJzLnJlc29sdmVTY2hlbWEoc2NoZW1hKTtcblxuICAvLyBSZXR1cm4gZm9yIGVtcHR5IG9iamVjdFxuICBpZihfLmlzRW1wdHkoc2NoZW1hKSkge1xuICAgIHJldHVybiBzdHJvbmdPcGVuICsgJ0VtcHR5JyArIHN0cm9uZ0Nsb3NlO1xuICB9XG5cbiAgLy8gRGVyZWZlcmVuY2UgJHJlZiBmcm9tICdtb2RlbHMnXG4gIGlmKHR5cGVvZiBzY2hlbWEuJHJlZiA9PT0gJ3N0cmluZycpIHtcbiAgICBuYW1lID0gSGVscGVycy5zaW1wbGVSZWYoc2NoZW1hLiRyZWYpO1xuICAgIHNjaGVtYSA9IG1vZGVsc1tuYW1lXTtcbiAgICBpZih0eXBlb2Ygc2NoZW1hID09PSAndW5kZWZpbmVkJylcbiAgICB7XG4gICAgICByZXR1cm4gc3Ryb25nT3BlbiArIG5hbWUgKyAnIGlzIG5vdCBkZWZpbmVkIScgKyBzdHJvbmdDbG9zZTtcbiAgICB9XG4gIH1cblxuICBpZih0eXBlb2YgbmFtZSAhPT0gJ3N0cmluZycpIHtcbiAgICBuYW1lID0gc2NoZW1hLnRpdGxlIHx8ICdJbmxpbmUgTW9kZWwnO1xuICB9XG5cbiAgLy8gSWYgd2UgYXJlIGEgTW9kZWwgb2JqZWN0Li4uIGFkanVzdCBhY2NvcmRpbmdseVxuICBpZihzY2hlbWEuZGVmaW5pdGlvbikge1xuICAgIHNjaGVtYSA9IHNjaGVtYS5kZWZpbml0aW9uO1xuICB9XG5cbiAgaWYodHlwZW9mIG1vZGVsUHJvcGVydHlNYWNybyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIG1vZGVsUHJvcGVydHlNYWNybyA9IGZ1bmN0aW9uKHByb3Ape1xuICAgICAgcmV0dXJuIChwcm9wIHx8IHt9KS5kZWZhdWx0O1xuICAgIH07XG4gIH1cblxuICB2YXIgcmVmZXJlbmNlcyA9IHt9O1xuICB2YXIgc2Vlbk1vZGVscyA9IFtdO1xuICB2YXIgaW5saW5lTW9kZWxzID0gMDtcblxuXG5cbiAgLy8gR2VuZXJhdGUgY3VycmVudCBIVE1MXG4gIHZhciBodG1sID0gcHJvY2Vzc01vZGVsKHNjaGVtYSwgbmFtZSk7XG5cbiAgLy8gR2VuZXJhdGUgcmVmZXJlbmNlcyBIVE1MXG4gIHdoaWxlIChfLmtleXMocmVmZXJlbmNlcykubGVuZ3RoID4gMCkge1xuICAgIC8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cbiAgICBfLmZvckVhY2gocmVmZXJlbmNlcywgZnVuY3Rpb24gKHNjaGVtYSwgbmFtZSkge1xuICAgICAgdmFyIHNlZW5Nb2RlbCA9IF8uaW5kZXhPZihzZWVuTW9kZWxzLCBuYW1lKSA+IC0xO1xuXG4gICAgICBkZWxldGUgcmVmZXJlbmNlc1tuYW1lXTtcblxuICAgICAgaWYgKCFzZWVuTW9kZWwpIHtcbiAgICAgICAgc2Vlbk1vZGVscy5wdXNoKG5hbWUpO1xuXG4gICAgICAgIGh0bWwgKz0gJzxiciAvPicgKyBwcm9jZXNzTW9kZWwoc2NoZW1hLCBuYW1lKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICAvKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuICB9XG5cbiAgcmV0dXJuIGh0bWw7XG5cbiAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbiAgZnVuY3Rpb24gYWRkUmVmZXJlbmNlKHNjaGVtYSwgbmFtZSwgc2tpcFJlZikge1xuICAgIHZhciBtb2RlbE5hbWUgPSBuYW1lO1xuICAgIHZhciBtb2RlbDtcblxuICAgIGlmIChzY2hlbWEuJHJlZikge1xuICAgICAgbW9kZWxOYW1lID0gc2NoZW1hLnRpdGxlIHx8IEhlbHBlcnMuc2ltcGxlUmVmKHNjaGVtYS4kcmVmKTtcbiAgICAgIG1vZGVsID0gbW9kZWxzW21vZGVsTmFtZV07XG4gICAgfSBlbHNlIGlmIChfLmlzVW5kZWZpbmVkKG5hbWUpKSB7XG4gICAgICBtb2RlbE5hbWUgPSBzY2hlbWEudGl0bGUgfHwgJ0lubGluZSBNb2RlbCAnICsgKCsraW5saW5lTW9kZWxzKTtcbiAgICAgIG1vZGVsID0ge2RlZmluaXRpb246IHNjaGVtYX07XG4gICAgfVxuXG4gICAgaWYgKHNraXBSZWYgIT09IHRydWUpIHtcbiAgICAgIHJlZmVyZW5jZXNbbW9kZWxOYW1lXSA9IF8uaXNVbmRlZmluZWQobW9kZWwpID8ge30gOiBtb2RlbC5kZWZpbml0aW9uO1xuICAgIH1cblxuICAgIHJldHVybiBtb2RlbE5hbWU7XG4gIH1cblxuICBmdW5jdGlvbiBwcmltaXRpdmVUb0hUTUwoc2NoZW1hKSB7XG4gICAgdmFyIGh0bWwgPSAnPHNwYW4gY2xhc3M9XCJwcm9wVHlwZVwiPic7XG4gICAgdmFyIHR5cGUgPSBzY2hlbWEudHlwZSB8fCAnb2JqZWN0JztcblxuICAgIGlmIChzY2hlbWEuJHJlZikge1xuICAgICAgaHRtbCArPSBhZGRSZWZlcmVuY2Uoc2NoZW1hLCBIZWxwZXJzLnNpbXBsZVJlZihzY2hlbWEuJHJlZikpO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGlmICghXy5pc1VuZGVmaW5lZChzY2hlbWEucHJvcGVydGllcykpIHtcbiAgICAgICAgaHRtbCArPSBhZGRSZWZlcmVuY2Uoc2NoZW1hKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGh0bWwgKz0gJ29iamVjdCc7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnYXJyYXknKSB7XG4gICAgICBodG1sICs9ICdBcnJheVsnO1xuXG4gICAgICBpZiAoXy5pc0FycmF5KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgaHRtbCArPSBfLm1hcChzY2hlbWEuaXRlbXMsIGFkZFJlZmVyZW5jZSkuam9pbignLCcpO1xuICAgICAgfSBlbHNlIGlmIChfLmlzUGxhaW5PYmplY3Qoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICBpZiAoXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMuJHJlZikpIHtcbiAgICAgICAgICBpZiAoIV8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zLnR5cGUpICYmIF8uaW5kZXhPZihbJ2FycmF5JywgJ29iamVjdCddLCBzY2hlbWEuaXRlbXMudHlwZSkgPT09IC0xKSB7XG4gICAgICAgICAgICBodG1sICs9IHNjaGVtYS5pdGVtcy50eXBlO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBodG1sICs9IGFkZFJlZmVyZW5jZShzY2hlbWEuaXRlbXMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBodG1sICs9IGFkZFJlZmVyZW5jZShzY2hlbWEuaXRlbXMsIEhlbHBlcnMuc2ltcGxlUmVmKHNjaGVtYS5pdGVtcy4kcmVmKSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIEhlbHBlcnMubG9nKCdBcnJheSB0eXBlXFwncyBcXCdpdGVtc1xcJyBzY2hlbWEgaXMgbm90IGFuIGFycmF5IG9yIGFuIG9iamVjdCwgY2Fubm90IHByb2Nlc3MnKTtcbiAgICAgICAgaHRtbCArPSAnb2JqZWN0JztcbiAgICAgIH1cblxuICAgICAgaHRtbCArPSAnXSc7XG4gICAgfSBlbHNlIHtcbiAgICAgIGh0bWwgKz0gc2NoZW1hLnR5cGU7XG4gICAgfVxuXG4gICAgaHRtbCArPSAnPC9zcGFuPic7XG5cbiAgICByZXR1cm4gaHRtbDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHByaW1pdGl2ZVRvT3B0aW9uc0hUTUwoc2NoZW1hLCBodG1sKSB7XG4gICAgdmFyIG9wdGlvbnMgPSAnJztcbiAgICB2YXIgdHlwZSA9IHNjaGVtYS50eXBlIHx8ICdvYmplY3QnO1xuICAgIHZhciBpc0FycmF5ID0gdHlwZSA9PT0gJ2FycmF5JztcblxuICAgIGlmIChpc0FycmF5KSB7XG4gICAgICBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5pdGVtcykgJiYgIV8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zLnR5cGUpKSB7XG4gICAgICAgIHR5cGUgPSBzY2hlbWEuaXRlbXMudHlwZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHR5cGUgPSAnb2JqZWN0JztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIV8uaXNVbmRlZmluZWQoc2NoZW1hLmRlZmF1bHQpKSB7XG4gICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ0RlZmF1bHQnLCBzY2hlbWEuZGVmYXVsdCk7XG4gICAgfVxuXG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSAnc3RyaW5nJzpcbiAgICAgIGlmIChzY2hlbWEubWluTGVuZ3RoKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnTWluLiBMZW5ndGgnLCBzY2hlbWEubWluTGVuZ3RoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjaGVtYS5tYXhMZW5ndGgpIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdNYXguIExlbmd0aCcsIHNjaGVtYS5tYXhMZW5ndGgpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLnBhdHRlcm4pIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdSZWcuIEV4cC4nLCBzY2hlbWEucGF0dGVybik7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICBjYXNlICdpbnRlZ2VyJzpcbiAgICBjYXNlICdudW1iZXInOlxuICAgICAgaWYgKHNjaGVtYS5taW5pbXVtKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnTWluLiBWYWx1ZScsIHNjaGVtYS5taW5pbXVtKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjaGVtYS5leGNsdXNpdmVNaW5pbXVtKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnRXhjbHVzaXZlIE1pbi4nLCAndHJ1ZScpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLm1heGltdW0pIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdNYXguIFZhbHVlJywgc2NoZW1hLm1heGltdW0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLmV4Y2x1c2l2ZU1heGltdW0pIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdFeGNsdXNpdmUgTWF4LicsICd0cnVlJyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2hlbWEubXVsdGlwbGVPZikge1xuICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ011bHRpcGxlIE9mJywgc2NoZW1hLm11bHRpcGxlT2YpO1xuICAgICAgfVxuXG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBpZiAoaXNBcnJheSkge1xuICAgICAgaWYgKHNjaGVtYS5taW5JdGVtcykge1xuICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ01pbi4gSXRlbXMnLCBzY2hlbWEubWluSXRlbXMpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLm1heEl0ZW1zKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnTWF4LiBJdGVtcycsIHNjaGVtYS5tYXhJdGVtcyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2hlbWEudW5pcXVlSXRlbXMpIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdVbmlxdWUgSXRlbXMnLCAndHJ1ZScpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLmNvbGxlY3Rpb25Gb3JtYXQpIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdDb2xsLiBGb3JtYXQnLCBzY2hlbWEuY29sbGVjdGlvbkZvcm1hdCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgaWYgKF8uaXNBcnJheShzY2hlbWEuZW51bSkpIHtcbiAgICAgICAgdmFyIGVudW1TdHJpbmc7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdudW1iZXInIHx8IHR5cGUgPT09ICdpbnRlZ2VyJykge1xuICAgICAgICAgIGVudW1TdHJpbmcgPSBzY2hlbWEuZW51bS5qb2luKCcsICcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVudW1TdHJpbmcgPSAnXCInICsgc2NoZW1hLmVudW0uam9pbignXCIsIFwiJykgKyAnXCInO1xuICAgICAgICB9XG5cbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdFbnVtJywgZW51bVN0cmluZyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMubGVuZ3RoID4gMCkge1xuICAgICAgaHRtbCA9ICc8c3BhbiBjbGFzcz1cInByb3BXcmFwXCI+JyArIGh0bWwgKyAnPHRhYmxlIGNsYXNzPVwib3B0aW9uc1dyYXBwZXJcIj48dHI+PHRoIGNvbHNwYW49XCIyXCI+JyArIHR5cGUgKyAnPC90aD48L3RyPicgKyBvcHRpb25zICsgJzwvdGFibGU+PC9zcGFuPic7XG4gICAgfVxuXG4gICAgcmV0dXJuIGh0bWw7XG4gIH1cblxuICBmdW5jdGlvbiBwcm9jZXNzTW9kZWwoc2NoZW1hLCBuYW1lKSB7XG4gICAgdmFyIHR5cGUgPSBzY2hlbWEudHlwZSB8fCAnb2JqZWN0JztcbiAgICB2YXIgaXNBcnJheSA9IHNjaGVtYS50eXBlID09PSAnYXJyYXknO1xuICAgIHZhciBodG1sID0gc3Ryb25nT3BlbiArIG5hbWUgKyAnICcgKyAoaXNBcnJheSA/ICdbJyA6ICd7JykgKyBzdHJvbmdDbG9zZTtcblxuICAgIGlmIChuYW1lKSB7XG4gICAgICBzZWVuTW9kZWxzLnB1c2gobmFtZSk7XG4gICAgfVxuXG4gICAgaWYgKGlzQXJyYXkpIHtcbiAgICAgIGlmIChfLmlzQXJyYXkoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICBodG1sICs9ICc8ZGl2PicgKyBfLm1hcChzY2hlbWEuaXRlbXMsIGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgdmFyIHR5cGUgPSBpdGVtLnR5cGUgfHwgJ29iamVjdCc7XG5cbiAgICAgICAgICBpZiAoXy5pc1VuZGVmaW5lZChpdGVtLiRyZWYpKSB7XG4gICAgICAgICAgICBpZiAoXy5pbmRleE9mKFsnYXJyYXknLCAnb2JqZWN0J10sIHR5cGUpID4gLTEpIHtcbiAgICAgICAgICAgICAgaWYgKHR5cGUgPT09ICdvYmplY3QnICYmIF8uaXNVbmRlZmluZWQoaXRlbS5wcm9wZXJ0aWVzKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiAnb2JqZWN0JztcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYWRkUmVmZXJlbmNlKGl0ZW0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXR1cm4gcHJpbWl0aXZlVG9PcHRpb25zSFRNTChpdGVtLCB0eXBlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGFkZFJlZmVyZW5jZShpdGVtLCBIZWxwZXJzLnNpbXBsZVJlZihpdGVtLiRyZWYpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pLmpvaW4oJyw8L2Rpdj48ZGl2PicpO1xuICAgICAgfSBlbHNlIGlmIChfLmlzUGxhaW5PYmplY3Qoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICBpZiAoXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMuJHJlZikpIHtcbiAgICAgICAgICBpZiAoXy5pbmRleE9mKFsnYXJyYXknLCAnb2JqZWN0J10sIHNjaGVtYS5pdGVtcy50eXBlIHx8ICdvYmplY3QnKSA+IC0xKSB7XG4gICAgICAgICAgICBpZiAoKF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zLnR5cGUpIHx8IHNjaGVtYS5pdGVtcy50eXBlID09PSAnb2JqZWN0JykgJiYgXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMucHJvcGVydGllcykpIHtcbiAgICAgICAgICAgICAgaHRtbCArPSAnPGRpdj5vYmplY3Q8L2Rpdj4nO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgaHRtbCArPSAnPGRpdj4nICsgYWRkUmVmZXJlbmNlKHNjaGVtYS5pdGVtcykgKyAnPC9kaXY+JztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaHRtbCArPSAnPGRpdj4nICsgcHJpbWl0aXZlVG9PcHRpb25zSFRNTChzY2hlbWEuaXRlbXMsIHNjaGVtYS5pdGVtcy50eXBlKSArICc8L2Rpdj4nO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBodG1sICs9ICc8ZGl2PicgKyBhZGRSZWZlcmVuY2Uoc2NoZW1hLml0ZW1zLCBIZWxwZXJzLnNpbXBsZVJlZihzY2hlbWEuaXRlbXMuJHJlZikpICsgJzwvZGl2Pic7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIEhlbHBlcnMubG9nKCdBcnJheSB0eXBlXFwncyBcXCdpdGVtc1xcJyBwcm9wZXJ0eSBpcyBub3QgYW4gYXJyYXkgb3IgYW4gb2JqZWN0LCBjYW5ub3QgcHJvY2VzcycpO1xuICAgICAgICBodG1sICs9ICc8ZGl2Pm9iamVjdDwvZGl2Pic7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChzY2hlbWEuJHJlZikge1xuICAgICAgICBodG1sICs9ICc8ZGl2PicgKyBhZGRSZWZlcmVuY2Uoc2NoZW1hLCBuYW1lKSArICc8L2Rpdj4nO1xuICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnb2JqZWN0Jykge1xuICAgICAgICBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5wcm9wZXJ0aWVzKSkge1xuICAgICAgICAgIHZhciBjb250ZW50cyA9IF8ubWFwKHNjaGVtYS5wcm9wZXJ0aWVzLCBmdW5jdGlvbiAocHJvcGVydHksIG5hbWUpIHtcbiAgICAgICAgICAgIHZhciBwcm9wZXJ0eUlzUmVxdWlyZWQgPSAoXy5pbmRleE9mKHNjaGVtYS5yZXF1aXJlZCwgbmFtZSkgPj0gMCk7XG4gICAgICAgICAgICB2YXIgY1Byb3BlcnR5ID0gXy5jbG9uZURlZXAocHJvcGVydHkpO1xuXG4gICAgICAgICAgICB2YXIgcmVxdWlyZWRDbGFzcyA9IHByb3BlcnR5SXNSZXF1aXJlZCA/ICdyZXF1aXJlZCcgOiAnJztcbiAgICAgICAgICAgIHZhciBodG1sID0gJzxzcGFuIGNsYXNzPVwicHJvcE5hbWUgJyArIHJlcXVpcmVkQ2xhc3MgKyAnXCI+JyArIG5hbWUgKyAnPC9zcGFuPiAoJztcbiAgICAgICAgICAgIHZhciBtb2RlbDtcbiAgICAgICAgICAgIHZhciBwcm9wRGVzY3JpcHRpb247XG5cbiAgICAgICAgICAgIC8vIEFsbG93IG1hY3JvIHRvIHNldCB0aGUgZGVmYXVsdCB2YWx1ZVxuICAgICAgICAgICAgY1Byb3BlcnR5LmRlZmF1bHQgPSBtb2RlbFByb3BlcnR5TWFjcm8oY1Byb3BlcnR5KTtcblxuICAgICAgICAgICAgLy8gUmVzb2x2ZSB0aGUgc2NoZW1hIChIYW5kbGUgbmVzdGVkIHNjaGVtYXMpXG4gICAgICAgICAgICBjUHJvcGVydHkgPSBIZWxwZXJzLnJlc29sdmVTY2hlbWEoY1Byb3BlcnR5KTtcblxuICAgICAgICAgICAgcHJvcERlc2NyaXB0aW9uID0gcHJvcGVydHkuZGVzY3JpcHRpb24gfHwgY1Byb3BlcnR5LmRlc2NyaXB0aW9uO1xuXG4gICAgICAgICAgICAvLyBXZSBuZWVkIHRvIGhhbmRsZSBwcm9wZXJ0eSByZWZlcmVuY2VzIHRvIHByaW1pdGl2ZXMgKElzc3VlIDMzOSlcbiAgICAgICAgICAgIGlmICghXy5pc1VuZGVmaW5lZChjUHJvcGVydHkuJHJlZikpIHtcbiAgICAgICAgICAgICAgbW9kZWwgPSBtb2RlbHNbSGVscGVycy5zaW1wbGVSZWYoY1Byb3BlcnR5LiRyZWYpXTtcblxuICAgICAgICAgICAgICBpZiAoIV8uaXNVbmRlZmluZWQobW9kZWwpICYmIF8uaW5kZXhPZihbdW5kZWZpbmVkLCAnYXJyYXknLCAnb2JqZWN0J10sIG1vZGVsLmRlZmluaXRpb24udHlwZSkgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgLy8gVXNlIHJlZmVyZW5jZWQgc2NoZW1hXG4gICAgICAgICAgICAgICAgY1Byb3BlcnR5ID0gSGVscGVycy5yZXNvbHZlU2NoZW1hKG1vZGVsLmRlZmluaXRpb24pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGh0bWwgKz0gcHJpbWl0aXZlVG9IVE1MKGNQcm9wZXJ0eSk7XG5cbiAgICAgICAgICAgIGlmKCFwcm9wZXJ0eUlzUmVxdWlyZWQpIHtcbiAgICAgICAgICAgICAgaHRtbCArPSAnLCA8c3BhbiBjbGFzcz1cInByb3BPcHRLZXlcIj5vcHRpb25hbDwvc3Bhbj4nO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZihwcm9wZXJ0eS5yZWFkT25seSkge1xuICAgICAgICAgICAgICAgIGh0bWwgKz0gJywgPHNwYW4gY2xhc3M9XCJwcm9wUmVhZE9ubHlcIj5yZWFkIG9ubHk8L3NwYW4+JztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaHRtbCArPSAnKSc7XG5cbiAgICAgICAgICAgIGlmICghXy5pc1VuZGVmaW5lZChwcm9wRGVzY3JpcHRpb24pKSB7XG4gICAgICAgICAgICAgIGh0bWwgKz0gJzogJyArICc8c3BhbiBjbGFzcz1cInByb3BEZXNjXCI+JyArIHByb3BEZXNjcmlwdGlvbiArICc8L3NwYW4+JztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGNQcm9wZXJ0eS5lbnVtKSB7XG4gICAgICAgICAgICAgIGh0bWwgKz0gJyA9IDxzcGFuIGNsYXNzPVwicHJvcFZhbHNcIj5bXFwnJyArIGNQcm9wZXJ0eS5lbnVtLmpvaW4oJ1xcJywgXFwnJykgKyAnXFwnXTwvc3Bhbj4nO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gJzxkaXYnICsgKHByb3BlcnR5LnJlYWRPbmx5ID8gJyBjbGFzcz1cInJlYWRPbmx5XCInIDogJycpICsgJz4nICsgcHJpbWl0aXZlVG9PcHRpb25zSFRNTChjUHJvcGVydHksIGh0bWwpO1xuICAgICAgICAgIH0pLmpvaW4oJyw8L2Rpdj4nKTtcblxuICAgICAgICAgIGlmIChjb250ZW50cykge1xuICAgICAgICAgICAgaHRtbCArPSBjb250ZW50cyArICc8L2Rpdj4nO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaHRtbCArPSAnPGRpdj4nICsgcHJpbWl0aXZlVG9PcHRpb25zSFRNTChzY2hlbWEsIHR5cGUpICsgJzwvZGl2Pic7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGh0bWwgKyBzdHJvbmdPcGVuICsgKGlzQXJyYXkgPyAnXScgOiAnfScpICsgc3Ryb25nQ2xvc2U7XG4gIH1cbn07IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgU3dhZ2dlckh0dHAgPSByZXF1aXJlKCcuL2h0dHAnKTtcbnZhciBfID0ge1xuICBpc09iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzT2JqZWN0Jylcbn07XG5cbnZhciBTd2FnZ2VyU3BlY0NvbnZlcnRlciA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmVycm9ycyA9IFtdO1xuICB0aGlzLndhcm5pbmdzID0gW107XG4gIHRoaXMubW9kZWxNYXAgPSB7fTtcbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5zZXREb2N1bWVudGF0aW9uTG9jYXRpb24gPSBmdW5jdGlvbiAobG9jYXRpb24pIHtcbiAgdGhpcy5kb2NMb2NhdGlvbiA9IGxvY2F0aW9uO1xufTtcblxuLyoqXG4gKiBjb252ZXJ0cyBhIHJlc291cmNlIGxpc3RpbmcgT1IgYXBpIGRlY2xhcmF0aW9uXG4gKiovXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuY29udmVydCA9IGZ1bmN0aW9uIChvYmosIGNsaWVudEF1dGhvcml6YXRpb25zLCBvcHRzLCBjYWxsYmFjaykge1xuICAvLyBub3QgYSB2YWxpZCBzcGVjXG4gIGlmKCFvYmogfHwgIUFycmF5LmlzQXJyYXkob2JqLmFwaXMpKSB7XG4gICAgcmV0dXJuIHRoaXMuZmluaXNoKGNhbGxiYWNrLCBudWxsKTtcbiAgfVxuICB0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zID0gY2xpZW50QXV0aG9yaXphdGlvbnM7XG5cbiAgLy8gY3JlYXRlIGEgbmV3IHN3YWdnZXIgb2JqZWN0IHRvIHJldHVyblxuICB2YXIgc3dhZ2dlciA9IHsgc3dhZ2dlcjogJzIuMCcgfTtcblxuICBzd2FnZ2VyLm9yaWdpbmFsVmVyc2lvbiA9IG9iai5zd2FnZ2VyVmVyc2lvbjtcblxuICAvLyBhZGQgdGhlIGluZm9cbiAgdGhpcy5hcGlJbmZvKG9iaiwgc3dhZ2dlcik7XG5cbiAgLy8gYWRkIHNlY3VyaXR5IGRlZmluaXRpb25zXG4gIHRoaXMuc2VjdXJpdHlEZWZpbml0aW9ucyhvYmosIHN3YWdnZXIpO1xuXG4gIC8vIHRha2UgYmFzZVBhdGggaW50byBhY2NvdW50XG4gIGlmIChvYmouYmFzZVBhdGgpIHtcbiAgICB0aGlzLnNldERvY3VtZW50YXRpb25Mb2NhdGlvbihvYmouYmFzZVBhdGgpO1xuICB9XG5cbiAgLy8gc2VlIGlmIHRoaXMgaXMgYSBzaW5nbGUtZmlsZSBzd2FnZ2VyIGRlZmluaXRpb25cbiAgdmFyIGlzU2luZ2xlRmlsZVN3YWdnZXIgPSBmYWxzZTtcbiAgdmFyIGk7XG4gIGZvcihpID0gMDsgaSA8IG9iai5hcGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGFwaSA9IG9iai5hcGlzW2ldO1xuICAgIGlmKEFycmF5LmlzQXJyYXkoYXBpLm9wZXJhdGlvbnMpKSB7XG4gICAgICBpc1NpbmdsZUZpbGVTd2FnZ2VyID0gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgaWYoaXNTaW5nbGVGaWxlU3dhZ2dlcikge1xuICAgIHRoaXMuZGVjbGFyYXRpb24ob2JqLCBzd2FnZ2VyKTtcbiAgICB0aGlzLmZpbmlzaChjYWxsYmFjaywgc3dhZ2dlcik7XG4gIH1cbiAgZWxzZSB7XG4gICAgdGhpcy5yZXNvdXJjZUxpc3Rpbmcob2JqLCBzd2FnZ2VyLCBvcHRzLCBjYWxsYmFjayk7XG4gIH1cbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5kZWNsYXJhdGlvbiA9IGZ1bmN0aW9uKG9iaiwgc3dhZ2dlcikge1xuICB2YXIgbmFtZSwgaSwgcCwgcG9zO1xuICBpZighb2JqLmFwaXMpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAob2JqLmJhc2VQYXRoLmluZGV4T2YoJ2h0dHA6Ly8nKSA9PT0gMCkge1xuICAgIHAgPSBvYmouYmFzZVBhdGguc3Vic3RyaW5nKCdodHRwOi8vJy5sZW5ndGgpO1xuICAgIHBvcyA9IHAuaW5kZXhPZignLycpO1xuICAgIGlmIChwb3MgPiAwKSB7XG4gICAgICBzd2FnZ2VyLmhvc3QgPSBwLnN1YnN0cmluZygwLCBwb3MpO1xuICAgICAgc3dhZ2dlci5iYXNlUGF0aCA9IHAuc3Vic3RyaW5nKHBvcyk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgc3dhZ2dlci5ob3N0ID0gcDtcbiAgICAgIHN3YWdnZXIuYmFzZVBhdGggPSAnLyc7XG4gICAgfVxuICB9IGVsc2UgaWYgKG9iai5iYXNlUGF0aC5pbmRleE9mKCdodHRwczovLycpID09PSAwKSB7XG4gICAgcCA9IG9iai5iYXNlUGF0aC5zdWJzdHJpbmcoJ2h0dHBzOi8vJy5sZW5ndGgpO1xuICAgIHBvcyA9IHAuaW5kZXhPZignLycpO1xuICAgIGlmIChwb3MgPiAwKSB7XG4gICAgICBzd2FnZ2VyLmhvc3QgPSBwLnN1YnN0cmluZygwLCBwb3MpO1xuICAgICAgc3dhZ2dlci5iYXNlUGF0aCA9IHAuc3Vic3RyaW5nKHBvcyk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgc3dhZ2dlci5ob3N0ID0gcDtcbiAgICAgIHN3YWdnZXIuYmFzZVBhdGggPSAnLyc7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHN3YWdnZXIuYmFzZVBhdGggPSBvYmouYmFzZVBhdGg7XG4gIH1cblxuICB2YXIgcmVzb3VyY2VMZXZlbEF1dGg7XG4gIGlmKG9iai5hdXRob3JpemF0aW9ucykge1xuICAgIHJlc291cmNlTGV2ZWxBdXRoID0gb2JqLmF1dGhvcml6YXRpb25zO1xuICB9XG4gIGlmKG9iai5jb25zdW1lcykge1xuICAgIHN3YWdnZXIuY29uc3VtZXMgPSBvYmouY29uc3VtZXM7XG4gIH1cbiAgaWYob2JqLnByb2R1Y2VzKSB7XG4gICAgc3dhZ2dlci5wcm9kdWNlcyA9IG9iai5wcm9kdWNlcztcbiAgfVxuXG4gIC8vIGJ1aWxkIGEgbWFwcGluZyBvZiBpZCB0byBuYW1lIGZvciAxLjAgbW9kZWwgcmVzb2x1dGlvbnNcbiAgaWYoXy5pc09iamVjdChvYmopKSB7XG4gICAgZm9yKG5hbWUgaW4gb2JqLm1vZGVscykge1xuICAgICAgdmFyIGV4aXN0aW5nTW9kZWwgPSBvYmoubW9kZWxzW25hbWVdO1xuICAgICAgdmFyIGtleSA9IChleGlzdGluZ01vZGVsLmlkIHx8IG5hbWUpO1xuICAgICAgdGhpcy5tb2RlbE1hcFtrZXldID0gbmFtZTtcbiAgICB9XG4gIH1cblxuICBmb3IoaSA9IDA7IGkgPCBvYmouYXBpcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBhcGkgPSBvYmouYXBpc1tpXTtcbiAgICB2YXIgcGF0aCA9IGFwaS5wYXRoO1xuICAgIHZhciBvcGVyYXRpb25zID0gYXBpLm9wZXJhdGlvbnM7XG4gICAgdGhpcy5vcGVyYXRpb25zKHBhdGgsIG9iai5yZXNvdXJjZVBhdGgsIG9wZXJhdGlvbnMsIHJlc291cmNlTGV2ZWxBdXRoLCBzd2FnZ2VyKTtcbiAgfVxuXG4gIHZhciBtb2RlbHMgPSBvYmoubW9kZWxzIHx8IHt9O1xuICB0aGlzLm1vZGVscyhtb2RlbHMsIHN3YWdnZXIpO1xufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLm1vZGVscyA9IGZ1bmN0aW9uKG9iaiwgc3dhZ2dlcikge1xuICBpZighXy5pc09iamVjdChvYmopKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciBuYW1lO1xuXG4gIHN3YWdnZXIuZGVmaW5pdGlvbnMgPSBzd2FnZ2VyLmRlZmluaXRpb25zIHx8IHt9O1xuICBmb3IobmFtZSBpbiBvYmopIHtcbiAgICB2YXIgZXhpc3RpbmdNb2RlbCA9IG9ialtuYW1lXTtcbiAgICB2YXIgX3JlcXVpcmVkID0gW107XG4gICAgdmFyIHNjaGVtYSA9IHsgcHJvcGVydGllczoge319O1xuICAgIHZhciBwcm9wZXJ0eU5hbWU7XG4gICAgZm9yKHByb3BlcnR5TmFtZSBpbiBleGlzdGluZ01vZGVsLnByb3BlcnRpZXMpIHtcbiAgICAgIHZhciBleGlzdGluZ1Byb3BlcnR5ID0gZXhpc3RpbmdNb2RlbC5wcm9wZXJ0aWVzW3Byb3BlcnR5TmFtZV07XG4gICAgICB2YXIgcHJvcGVydHkgPSB7fTtcbiAgICAgIHRoaXMuZGF0YVR5cGUoZXhpc3RpbmdQcm9wZXJ0eSwgcHJvcGVydHkpO1xuICAgICAgaWYoZXhpc3RpbmdQcm9wZXJ0eS5kZXNjcmlwdGlvbikge1xuICAgICAgICBwcm9wZXJ0eS5kZXNjcmlwdGlvbiA9IGV4aXN0aW5nUHJvcGVydHkuZGVzY3JpcHRpb247XG4gICAgICB9XG4gICAgICBpZihleGlzdGluZ1Byb3BlcnR5WydlbnVtJ10pIHtcbiAgICAgICAgcHJvcGVydHlbJ2VudW0nXSA9IGV4aXN0aW5nUHJvcGVydHlbJ2VudW0nXTtcbiAgICAgIH1cbiAgICAgIGlmKHR5cGVvZiBleGlzdGluZ1Byb3BlcnR5LnJlcXVpcmVkID09PSAnYm9vbGVhbicgJiYgZXhpc3RpbmdQcm9wZXJ0eS5yZXF1aXJlZCA9PT0gdHJ1ZSkge1xuICAgICAgICBfcmVxdWlyZWQucHVzaChwcm9wZXJ0eU5hbWUpO1xuICAgICAgfVxuICAgICAgaWYodHlwZW9mIGV4aXN0aW5nUHJvcGVydHkucmVxdWlyZWQgPT09ICdzdHJpbmcnICYmIGV4aXN0aW5nUHJvcGVydHkucmVxdWlyZWQgPT09ICd0cnVlJykge1xuICAgICAgICBfcmVxdWlyZWQucHVzaChwcm9wZXJ0eU5hbWUpO1xuICAgICAgfVxuICAgICAgc2NoZW1hLnByb3BlcnRpZXNbcHJvcGVydHlOYW1lXSA9IHByb3BlcnR5O1xuICAgIH1cbiAgICBpZihfcmVxdWlyZWQubGVuZ3RoID4gMCkge1xuICAgICAgc2NoZW1hLnJlcXVpcmVkID0gX3JlcXVpcmVkO1xuICAgIH0gZWxzZSB7XG4gICAgICBzY2hlbWEucmVxdWlyZWQgPSBleGlzdGluZ01vZGVsLnJlcXVpcmVkO1xuICAgIH1cbiAgICBzd2FnZ2VyLmRlZmluaXRpb25zW25hbWVdID0gc2NoZW1hO1xuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuZXh0cmFjdFRhZyA9IGZ1bmN0aW9uKHJlc291cmNlUGF0aCkge1xuICB2YXIgcGF0aFN0cmluZyA9IHJlc291cmNlUGF0aCB8fCAnZGVmYXVsdCc7XG4gIGlmKHBhdGhTdHJpbmcuaW5kZXhPZignaHR0cDonKSA9PT0gMCB8fCBwYXRoU3RyaW5nLmluZGV4T2YoJ2h0dHBzOicpID09PSAwKSB7XG4gICAgcGF0aFN0cmluZyA9IHBhdGhTdHJpbmcuc3BsaXQoWycvJ10pO1xuICAgIHBhdGhTdHJpbmcgPSBwYXRoU3RyaW5nW3BhdGhTdHJpbmcubGVuZ3RoIC0xXS5zdWJzdHJpbmcoKTtcbiAgfVxuICBpZihwYXRoU3RyaW5nLmVuZHNXaXRoKCcuanNvbicpKSB7XG4gICAgcGF0aFN0cmluZyA9IHBhdGhTdHJpbmcuc3Vic3RyaW5nKDAsIHBhdGhTdHJpbmcubGVuZ3RoIC0gJy5qc29uJy5sZW5ndGgpO1xuICB9XG4gIHJldHVybiBwYXRoU3RyaW5nLnJlcGxhY2UoJy8nLCcnKTtcbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5vcGVyYXRpb25zID0gZnVuY3Rpb24ocGF0aCwgcmVzb3VyY2VQYXRoLCBvYmosIHJlc291cmNlTGV2ZWxBdXRoLCBzd2FnZ2VyKSB7XG4gIGlmKCFBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgdmFyIGk7XG5cbiAgaWYoIXN3YWdnZXIucGF0aHMpIHtcbiAgICBzd2FnZ2VyLnBhdGhzID0ge307XG4gIH1cblxuICB2YXIgcGF0aE9iaiA9IHN3YWdnZXIucGF0aHNbcGF0aF0gfHwge307XG4gIHZhciB0YWcgPSB0aGlzLmV4dHJhY3RUYWcocmVzb3VyY2VQYXRoKTtcbiAgc3dhZ2dlci50YWdzID0gc3dhZ2dlci50YWdzIHx8IFtdO1xuICB2YXIgbWF0Y2hlZCA9IGZhbHNlO1xuICBmb3IoaSA9IDA7IGkgPCBzd2FnZ2VyLnRhZ3MubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgdGFnT2JqZWN0ID0gc3dhZ2dlci50YWdzW2ldO1xuICAgIGlmKHRhZ09iamVjdC5uYW1lID09PSB0YWcpIHtcbiAgICAgIG1hdGNoZWQgPSB0cnVlO1xuICAgIH1cbiAgfVxuICBpZighbWF0Y2hlZCkge1xuICAgIHN3YWdnZXIudGFncy5wdXNoKHtuYW1lOiB0YWd9KTtcbiAgfVxuXG4gIGZvcihpID0gMDsgaSA8IG9iai5sZW5ndGg7IGkrKykge1xuICAgIHZhciBleGlzdGluZ09wZXJhdGlvbiA9IG9ialtpXTtcbiAgICB2YXIgbWV0aG9kID0gKGV4aXN0aW5nT3BlcmF0aW9uLm1ldGhvZCB8fCBleGlzdGluZ09wZXJhdGlvbi5odHRwTWV0aG9kKS50b0xvd2VyQ2FzZSgpO1xuICAgIHZhciBvcGVyYXRpb24gPSB7dGFnczogW3RhZ119O1xuICAgIHZhciBleGlzdGluZ0F1dGhvcml6YXRpb25zID0gZXhpc3RpbmdPcGVyYXRpb24uYXV0aG9yaXphdGlvbnM7XG5cbiAgICBpZihleGlzdGluZ0F1dGhvcml6YXRpb25zICYmIE9iamVjdC5rZXlzKGV4aXN0aW5nQXV0aG9yaXphdGlvbnMpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgZXhpc3RpbmdBdXRob3JpemF0aW9ucyA9IHJlc291cmNlTGV2ZWxBdXRoO1xuICAgIH1cblxuICAgIGlmKHR5cGVvZiBleGlzdGluZ0F1dGhvcml6YXRpb25zICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdmFyIHNjb3Blc09iamVjdDtcbiAgICAgIGZvcih2YXIga2V5IGluIGV4aXN0aW5nQXV0aG9yaXphdGlvbnMpIHtcbiAgICAgICAgb3BlcmF0aW9uLnNlY3VyaXR5ID0gb3BlcmF0aW9uLnNlY3VyaXR5IHx8IFtdO1xuICAgICAgICB2YXIgc2NvcGVzID0gZXhpc3RpbmdBdXRob3JpemF0aW9uc1trZXldO1xuICAgICAgICBpZihzY29wZXMpIHtcbiAgICAgICAgICB2YXIgc2VjdXJpdHlTY29wZXMgPSBbXTtcbiAgICAgICAgICBmb3IodmFyIGogaW4gc2NvcGVzKSB7XG4gICAgICAgICAgICBzZWN1cml0eVNjb3Blcy5wdXNoKHNjb3Blc1tqXS5zY29wZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHNjb3Blc09iamVjdCA9IHt9O1xuICAgICAgICAgIHNjb3Blc09iamVjdFtrZXldID0gc2VjdXJpdHlTY29wZXM7XG4gICAgICAgICAgb3BlcmF0aW9uLnNlY3VyaXR5LnB1c2goc2NvcGVzT2JqZWN0KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBzY29wZXNPYmplY3QgPSB7fTtcbiAgICAgICAgICBzY29wZXNPYmplY3Rba2V5XSA9IFtdO1xuICAgICAgICAgIG9wZXJhdGlvbi5zZWN1cml0eS5wdXNoKHNjb3Blc09iamVjdCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZihleGlzdGluZ09wZXJhdGlvbi5jb25zdW1lcykge1xuICAgICAgb3BlcmF0aW9uLmNvbnN1bWVzID0gZXhpc3RpbmdPcGVyYXRpb24uY29uc3VtZXM7XG4gICAgfVxuICAgIGVsc2UgaWYoc3dhZ2dlci5jb25zdW1lcykge1xuICAgICAgb3BlcmF0aW9uLmNvbnN1bWVzID0gc3dhZ2dlci5jb25zdW1lcztcbiAgICB9XG4gICAgaWYoZXhpc3RpbmdPcGVyYXRpb24ucHJvZHVjZXMpIHtcbiAgICAgIG9wZXJhdGlvbi5wcm9kdWNlcyA9IGV4aXN0aW5nT3BlcmF0aW9uLnByb2R1Y2VzO1xuICAgIH1cbiAgICBlbHNlIGlmKHN3YWdnZXIucHJvZHVjZXMpIHtcbiAgICAgIG9wZXJhdGlvbi5wcm9kdWNlcyA9IHN3YWdnZXIucHJvZHVjZXM7XG4gICAgfVxuICAgIGlmKGV4aXN0aW5nT3BlcmF0aW9uLnN1bW1hcnkpIHtcbiAgICAgIG9wZXJhdGlvbi5zdW1tYXJ5ID0gZXhpc3RpbmdPcGVyYXRpb24uc3VtbWFyeTtcbiAgICB9XG4gICAgaWYoZXhpc3RpbmdPcGVyYXRpb24ubm90ZXMpIHtcbiAgICAgIG9wZXJhdGlvbi5kZXNjcmlwdGlvbiA9IGV4aXN0aW5nT3BlcmF0aW9uLm5vdGVzO1xuICAgIH1cbiAgICBpZihleGlzdGluZ09wZXJhdGlvbi5uaWNrbmFtZSkge1xuICAgICAgb3BlcmF0aW9uLm9wZXJhdGlvbklkID0gZXhpc3RpbmdPcGVyYXRpb24ubmlja25hbWU7XG4gICAgfVxuICAgIGlmKGV4aXN0aW5nT3BlcmF0aW9uLmRlcHJlY2F0ZWQpIHtcbiAgICAgIG9wZXJhdGlvbi5kZXByZWNhdGVkID0gZXhpc3RpbmdPcGVyYXRpb24uZGVwcmVjYXRlZDtcbiAgICB9XG5cbiAgICB0aGlzLmF1dGhvcml6YXRpb25zKGV4aXN0aW5nQXV0aG9yaXphdGlvbnMsIHN3YWdnZXIpO1xuICAgIHRoaXMucGFyYW1ldGVycyhvcGVyYXRpb24sIGV4aXN0aW5nT3BlcmF0aW9uLnBhcmFtZXRlcnMsIHN3YWdnZXIpO1xuICAgIHRoaXMucmVzcG9uc2VNZXNzYWdlcyhvcGVyYXRpb24sIGV4aXN0aW5nT3BlcmF0aW9uLCBzd2FnZ2VyKTtcblxuICAgIHBhdGhPYmpbbWV0aG9kXSA9IG9wZXJhdGlvbjtcbiAgfVxuXG4gIHN3YWdnZXIucGF0aHNbcGF0aF0gPSBwYXRoT2JqO1xufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLnJlc3BvbnNlTWVzc2FnZXMgPSBmdW5jdGlvbihvcGVyYXRpb24sIGV4aXN0aW5nT3BlcmF0aW9uKSB7XG4gIGlmKCFfLmlzT2JqZWN0KGV4aXN0aW5nT3BlcmF0aW9uKSkge1xuICAgIHJldHVybjtcbiAgfVxuICAvLyBidWlsZCBkZWZhdWx0IHJlc3BvbnNlIGZyb20gdGhlIG9wZXJhdGlvbiAoMS54KVxuICB2YXIgZGVmYXVsdFJlc3BvbnNlID0ge307XG4gIHRoaXMuZGF0YVR5cGUoZXhpc3RpbmdPcGVyYXRpb24sIGRlZmF1bHRSZXNwb25zZSk7XG4gIC8vIFRPRE86IGxvb2sgaW50byB0aGUgcmVhbCBwcm9ibGVtIG9mIHJlbmRlcmluZyByZXNwb25zZXMgaW4gc3dhZ2dlci11aVxuICAvLyAuLi4uc2hvdWxkIHJlcG9uc2VUeXBlIGhhdmUgYW4gaW1wbGljaXQgc2NoZW1hP1xuICBpZighZGVmYXVsdFJlc3BvbnNlLnNjaGVtYSAmJiBkZWZhdWx0UmVzcG9uc2UudHlwZSkge1xuICAgIGRlZmF1bHRSZXNwb25zZSA9IHtzY2hlbWE6IGRlZmF1bHRSZXNwb25zZX07XG4gIH1cblxuICBvcGVyYXRpb24ucmVzcG9uc2VzID0gb3BlcmF0aW9uLnJlc3BvbnNlcyB8fCB7fTtcblxuICAvLyBncmFiIGZyb20gcmVzcG9uc2VNZXNzYWdlcyAoMS4yKVxuICB2YXIgaGFzMjAwID0gZmFsc2U7XG4gIGlmKEFycmF5LmlzQXJyYXkoZXhpc3RpbmdPcGVyYXRpb24ucmVzcG9uc2VNZXNzYWdlcykpIHtcbiAgICB2YXIgaTtcbiAgICB2YXIgZXhpc3RpbmdSZXNwb25zZXMgPSBleGlzdGluZ09wZXJhdGlvbi5yZXNwb25zZU1lc3NhZ2VzO1xuICAgIGZvcihpID0gMDsgaSA8IGV4aXN0aW5nUmVzcG9uc2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgZXhpc3RpbmdSZXNwb25zZSA9IGV4aXN0aW5nUmVzcG9uc2VzW2ldO1xuICAgICAgdmFyIHJlc3BvbnNlID0geyBkZXNjcmlwdGlvbjogZXhpc3RpbmdSZXNwb25zZS5tZXNzYWdlIH07XG4gICAgICBpZihleGlzdGluZ1Jlc3BvbnNlLmNvZGUgPT09IDIwMCkge1xuICAgICAgICBoYXMyMDAgPSB0cnVlO1xuICAgICAgfVxuICAgICAgLy8gQ29udmVydCByZXNwb25zZU1vZGVsIC0+IHNjaGVtYXskcmVmOiByZXNwb25zZU1vZGVsfVxuICAgICAgaWYoZXhpc3RpbmdSZXNwb25zZS5yZXNwb25zZU1vZGVsKSB7XG4gICAgICAgIHJlc3BvbnNlLnNjaGVtYSA9IHsnJHJlZic6ICcjL2RlZmluaXRpb25zLycgKyBleGlzdGluZ1Jlc3BvbnNlLnJlc3BvbnNlTW9kZWx9O1xuICAgICAgfVxuICAgICAgb3BlcmF0aW9uLnJlc3BvbnNlc1snJyArIGV4aXN0aW5nUmVzcG9uc2UuY29kZV0gPSByZXNwb25zZTtcbiAgICB9XG4gIH1cblxuICBpZihoYXMyMDApIHtcbiAgICBvcGVyYXRpb24ucmVzcG9uc2VzWydkZWZhdWx0J10gPSBkZWZhdWx0UmVzcG9uc2U7XG4gIH1cbiAgZWxzZSB7XG4gICAgb3BlcmF0aW9uLnJlc3BvbnNlc1snMjAwJ10gPSBkZWZhdWx0UmVzcG9uc2U7XG4gIH1cbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5hdXRob3JpemF0aW9ucyA9IGZ1bmN0aW9uKG9iaikge1xuICAvLyBUT0RPXG4gIGlmKCFfLmlzT2JqZWN0KG9iaikpIHtcbiAgICByZXR1cm47XG4gIH1cbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5wYXJhbWV0ZXJzID0gZnVuY3Rpb24ob3BlcmF0aW9uLCBvYmopIHtcbiAgaWYoIUFycmF5LmlzQXJyYXkob2JqKSkge1xuICAgIHJldHVybjtcbiAgfVxuICB2YXIgaTtcbiAgZm9yKGkgPSAwOyBpIDwgb2JqLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGV4aXN0aW5nUGFyYW1ldGVyID0gb2JqW2ldO1xuICAgIHZhciBwYXJhbWV0ZXIgPSB7fTtcbiAgICBwYXJhbWV0ZXIubmFtZSA9IGV4aXN0aW5nUGFyYW1ldGVyLm5hbWU7XG4gICAgcGFyYW1ldGVyLmRlc2NyaXB0aW9uID0gZXhpc3RpbmdQYXJhbWV0ZXIuZGVzY3JpcHRpb247XG4gICAgcGFyYW1ldGVyLnJlcXVpcmVkID0gZXhpc3RpbmdQYXJhbWV0ZXIucmVxdWlyZWQ7XG4gICAgcGFyYW1ldGVyLmluID0gZXhpc3RpbmdQYXJhbWV0ZXIucGFyYW1UeXBlO1xuXG4gICAgLy8gcGVyICMxNjhcbiAgICBpZihwYXJhbWV0ZXIuaW4gPT09ICdib2R5Jykge1xuICAgICAgcGFyYW1ldGVyLm5hbWUgPSAnYm9keSc7XG4gICAgfVxuICAgIGlmKHBhcmFtZXRlci5pbiA9PT0gJ2Zvcm0nKSB7XG4gICAgICBwYXJhbWV0ZXIuaW4gPSAnZm9ybURhdGEnO1xuICAgIH1cblxuICAgIGlmKGV4aXN0aW5nUGFyYW1ldGVyLmVudW0pIHtcbiAgICAgIHBhcmFtZXRlci5lbnVtID0gZXhpc3RpbmdQYXJhbWV0ZXIuZW51bTtcbiAgICB9XG5cbiAgICBpZihleGlzdGluZ1BhcmFtZXRlci5hbGxvd011bHRpcGxlID09PSB0cnVlIHx8IGV4aXN0aW5nUGFyYW1ldGVyLmFsbG93TXVsdGlwbGUgPT09ICd0cnVlJykge1xuICAgICAgdmFyIGlubmVyVHlwZSA9IHt9O1xuICAgICAgdGhpcy5kYXRhVHlwZShleGlzdGluZ1BhcmFtZXRlciwgaW5uZXJUeXBlKTtcbiAgICAgIHBhcmFtZXRlci50eXBlID0gJ2FycmF5JztcbiAgICAgIHBhcmFtZXRlci5pdGVtcyA9IGlubmVyVHlwZTtcblxuICAgICAgaWYoZXhpc3RpbmdQYXJhbWV0ZXIuYWxsb3dhYmxlVmFsdWVzKSB7XG4gICAgICAgIHZhciBhdiA9IGV4aXN0aW5nUGFyYW1ldGVyLmFsbG93YWJsZVZhbHVlcztcbiAgICAgICAgaWYoYXYudmFsdWVUeXBlID09PSAnTElTVCcpIHtcbiAgICAgICAgICBwYXJhbWV0ZXJbJ2VudW0nXSA9IGF2LnZhbHVlcztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHRoaXMuZGF0YVR5cGUoZXhpc3RpbmdQYXJhbWV0ZXIsIHBhcmFtZXRlcik7XG4gICAgfVxuICAgIGlmKHR5cGVvZiBleGlzdGluZ1BhcmFtZXRlci5kZWZhdWx0VmFsdWUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBwYXJhbWV0ZXIuZGVmYXVsdCA9IGV4aXN0aW5nUGFyYW1ldGVyLmRlZmF1bHRWYWx1ZTtcbiAgICB9XG5cbiAgICBvcGVyYXRpb24ucGFyYW1ldGVycyA9IG9wZXJhdGlvbi5wYXJhbWV0ZXJzIHx8IFtdO1xuICAgIG9wZXJhdGlvbi5wYXJhbWV0ZXJzLnB1c2gocGFyYW1ldGVyKTtcbiAgfVxufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLmRhdGFUeXBlID0gZnVuY3Rpb24oc291cmNlLCB0YXJnZXQpIHtcbiAgaWYoIV8uaXNPYmplY3Qoc291cmNlKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmKHNvdXJjZS5taW5pbXVtKSB7XG4gICAgdGFyZ2V0Lm1pbmltdW0gPSBzb3VyY2UubWluaW11bTtcbiAgfVxuICBpZihzb3VyY2UubWF4aW11bSkge1xuICAgIHRhcmdldC5tYXhpbXVtID0gc291cmNlLm1heGltdW07XG4gIH1cbiAgaWYgKHNvdXJjZS5mb3JtYXQpIHtcbiAgICB0YXJnZXQuZm9ybWF0ID0gc291cmNlLmZvcm1hdDtcbiAgfVxuXG4gIC8vIGRlZmF1bHQgY2FuIGJlICdmYWxzZSdcbiAgaWYodHlwZW9mIHNvdXJjZS5kZWZhdWx0VmFsdWUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgdGFyZ2V0LmRlZmF1bHQgPSBzb3VyY2UuZGVmYXVsdFZhbHVlO1xuICB9XG5cbiAgdmFyIGpzb25TY2hlbWFUeXBlID0gdGhpcy50b0pzb25TY2hlbWEoc291cmNlKTtcbiAgaWYoanNvblNjaGVtYVR5cGUpIHtcbiAgICB0YXJnZXQgPSB0YXJnZXQgfHwge307XG4gICAgaWYoanNvblNjaGVtYVR5cGUudHlwZSkge1xuICAgICAgdGFyZ2V0LnR5cGUgPSBqc29uU2NoZW1hVHlwZS50eXBlO1xuICAgIH1cbiAgICBpZihqc29uU2NoZW1hVHlwZS5mb3JtYXQpIHtcbiAgICAgIHRhcmdldC5mb3JtYXQgPSBqc29uU2NoZW1hVHlwZS5mb3JtYXQ7XG4gICAgfVxuICAgIGlmKGpzb25TY2hlbWFUeXBlLiRyZWYpIHtcbiAgICAgIHRhcmdldC5zY2hlbWEgPSB7JHJlZjoganNvblNjaGVtYVR5cGUuJHJlZn07XG4gICAgfVxuICAgIGlmKGpzb25TY2hlbWFUeXBlLml0ZW1zKSB7XG4gICAgICB0YXJnZXQuaXRlbXMgPSBqc29uU2NoZW1hVHlwZS5pdGVtcztcbiAgICB9XG4gIH1cbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS50b0pzb25TY2hlbWEgPSBmdW5jdGlvbihzb3VyY2UpIHtcbiAgaWYoIXNvdXJjZSkge1xuICAgIHJldHVybiAnb2JqZWN0JztcbiAgfVxuICB2YXIgZGV0ZWN0ZWRUeXBlID0gKHNvdXJjZS50eXBlIHx8IHNvdXJjZS5kYXRhVHlwZSB8fCBzb3VyY2UucmVzcG9uc2VDbGFzcyB8fCAnJyk7XG4gIHZhciBsY1R5cGUgPSBkZXRlY3RlZFR5cGUudG9Mb3dlckNhc2UoKTtcbiAgdmFyIGZvcm1hdCA9IChzb3VyY2UuZm9ybWF0IHx8ICcnKS50b0xvd2VyQ2FzZSgpO1xuXG4gIGlmKGxjVHlwZS5pbmRleE9mKCdsaXN0WycpID09PSAwKSB7XG4gICAgdmFyIGlubmVyVHlwZSA9IGRldGVjdGVkVHlwZS5zdWJzdHJpbmcoNSwgZGV0ZWN0ZWRUeXBlLmxlbmd0aCAtIDEpO1xuICAgIHZhciBqc29uVHlwZSA9IHRoaXMudG9Kc29uU2NoZW1hKHt0eXBlOiBpbm5lclR5cGV9KTtcbiAgICByZXR1cm4ge3R5cGU6ICdhcnJheScsIGl0ZW1zOiBqc29uVHlwZX07XG4gIH0gZWxzZSBpZihsY1R5cGUgPT09ICdpbnQnIHx8IChsY1R5cGUgPT09ICdpbnRlZ2VyJyAmJiBmb3JtYXQgPT09ICdpbnQzMicpKSB7XG4gICAge3JldHVybiB7dHlwZTogJ2ludGVnZXInLCBmb3JtYXQ6ICdpbnQzMid9O31cbiAgfSBlbHNlIGlmKGxjVHlwZSA9PT0gJ2xvbmcnIHx8IChsY1R5cGUgPT09ICdpbnRlZ2VyJyAmJiBmb3JtYXQgPT09ICdpbnQ2NCcpKSB7XG4gICAge3JldHVybiB7dHlwZTogJ2ludGVnZXInLCBmb3JtYXQ6ICdpbnQ2NCd9O31cbiAgfSBlbHNlIGlmKGxjVHlwZSA9PT0gJ2ludGVnZXInKSB7XG4gICAge3JldHVybiB7dHlwZTogJ2ludGVnZXInLCBmb3JtYXQ6ICdpbnQ2NCd9O31cbiAgfSBlbHNlIGlmKGxjVHlwZSA9PT0gJ2Zsb2F0JyB8fCAobGNUeXBlID09PSAnbnVtYmVyJyAmJiBmb3JtYXQgPT09ICdmbG9hdCcpKSB7XG4gICAge3JldHVybiB7dHlwZTogJ251bWJlcicsIGZvcm1hdDogJ2Zsb2F0J307fVxuICB9IGVsc2UgaWYobGNUeXBlID09PSAnZG91YmxlJyB8fCAobGNUeXBlID09PSAnbnVtYmVyJyAmJiBmb3JtYXQgPT09ICdkb3VibGUnKSkge1xuICAgIHtyZXR1cm4ge3R5cGU6ICdudW1iZXInLCBmb3JtYXQ6ICdkb3VibGUnfTt9XG4gIH0gZWxzZSBpZigobGNUeXBlID09PSAnc3RyaW5nJyAmJiBmb3JtYXQgPT09ICdkYXRlLXRpbWUnKSB8fCAobGNUeXBlID09PSAnZGF0ZScpKSB7XG4gICAge3JldHVybiB7dHlwZTogJ3N0cmluZycsIGZvcm1hdDogJ2RhdGUtdGltZSd9O31cbiAgfSBlbHNlIGlmKGxjVHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICB7cmV0dXJuIHt0eXBlOiAnc3RyaW5nJ307fVxuICB9IGVsc2UgaWYobGNUeXBlID09PSAnZmlsZScpIHtcbiAgICB7cmV0dXJuIHt0eXBlOiAnZmlsZSd9O31cbiAgfSBlbHNlIGlmKGxjVHlwZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAge3JldHVybiB7dHlwZTogJ2Jvb2xlYW4nfTt9XG4gIH0gZWxzZSBpZihsY1R5cGUgPT09ICdib29sZWFuJykge1xuICAgIHtyZXR1cm4ge3R5cGU6ICdib29sZWFuJ307fVxuICB9IGVsc2UgaWYobGNUeXBlID09PSAnYXJyYXknIHx8IGxjVHlwZSA9PT0gJ2xpc3QnKSB7XG4gICAgaWYoc291cmNlLml0ZW1zKSB7XG4gICAgICB2YXIgaXQgPSB0aGlzLnRvSnNvblNjaGVtYShzb3VyY2UuaXRlbXMpO1xuICAgICAgcmV0dXJuIHt0eXBlOiAnYXJyYXknLCBpdGVtczogaXR9O1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHJldHVybiB7dHlwZTogJ2FycmF5JywgaXRlbXM6IHt0eXBlOiAnb2JqZWN0J319O1xuICAgIH1cbiAgfSBlbHNlIGlmKHNvdXJjZS4kcmVmKSB7XG4gICAgcmV0dXJuIHskcmVmOiB0aGlzLm1vZGVsTWFwW3NvdXJjZS4kcmVmXSA/ICcjL2RlZmluaXRpb25zLycgKyB0aGlzLm1vZGVsTWFwW3NvdXJjZS4kcmVmXSA6IHNvdXJjZS4kcmVmfTtcbiAgfSBlbHNlIGlmKGxjVHlwZSA9PT0gJ3ZvaWQnIHx8IGxjVHlwZSA9PT0gJycpIHtcbiAgICB7cmV0dXJuIHt9O31cbiAgfSBlbHNlIGlmICh0aGlzLm1vZGVsTWFwW3NvdXJjZS50eXBlXSkge1xuICAgIC8vIElmIHRoaXMgYSBtb2RlbCB1c2luZyBgdHlwZWAgaW5zdGVhZCBvZiBgJHJlZmAsIHRoYXQncyBmaW5lLlxuICAgIHJldHVybiB7JHJlZjogJyMvZGVmaW5pdGlvbnMvJyArIHRoaXMubW9kZWxNYXBbc291cmNlLnR5cGVdfTtcbiAgfSBlbHNlIHtcbiAgICAvLyBVbmtub3duIG1vZGVsIHR5cGUgb3IgJ29iamVjdCcsIHBhc3MgaXQgYWxvbmcuXG4gICAgcmV0dXJuIHt0eXBlOiBzb3VyY2UudHlwZX07XG4gIH1cbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5yZXNvdXJjZUxpc3RpbmcgPSBmdW5jdGlvbihvYmosIHN3YWdnZXIsIG9wdHMsIGNhbGxiYWNrKSB7XG4gIHZhciBpO1xuICB2YXIgcHJvY2Vzc2VkQ291bnQgPSAwOyAgIC8vIGpzaGludCBpZ25vcmU6bGluZVxuICB2YXIgc2VsZiA9IHRoaXM7ICAgICAgICAgIC8vIGpzaGludCBpZ25vcmU6bGluZVxuICB2YXIgZXhwZWN0ZWRDb3VudCA9IG9iai5hcGlzLmxlbmd0aDtcbiAgdmFyIF9zd2FnZ2VyID0gc3dhZ2dlcjsgICAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbiAgdmFyIF9vcHRzID0ge307XG5cbiAgaWYob3B0cyAmJiBvcHRzLnJlcXVlc3RJbnRlcmNlcHRvcil7XG4gICAgX29wdHMucmVxdWVzdEludGVyY2VwdG9yID0gb3B0cy5yZXF1ZXN0SW50ZXJjZXB0b3I7XG4gIH1cblxuICBpZihvcHRzICYmIG9wdHMucmVzcG9uc2VJbnRlcmNlcHRvcil7XG4gICAgX29wdHMucmVzcG9uc2VJbnRlcmNlcHRvciA9IG9wdHMucmVzcG9uc2VJbnRlcmNlcHRvcjtcbiAgfVxuXG4gIHZhciBzd2FnZ2VyUmVxdWVzdEhlYWRlcnMgPSAnYXBwbGljYXRpb24vanNvbic7XG5cbiAgaWYob3B0cyAmJiBvcHRzLnN3YWdnZXJSZXF1ZXN0SGVhZGVycykge1xuICAgIHN3YWdnZXJSZXF1ZXN0SGVhZGVycyA9IG9wdHMuc3dhZ2dlclJlcXVlc3RIZWFkZXJzO1xuICB9XG5cbiAgaWYoZXhwZWN0ZWRDb3VudCA9PT0gMCkge1xuICAgIHRoaXMuZmluaXNoKGNhbGxiYWNrLCBzd2FnZ2VyKTtcbiAgfVxuXG4gIGZvcihpID0gMDsgaSA8IGV4cGVjdGVkQ291bnQ7IGkrKykge1xuICAgIHZhciBhcGkgPSBvYmouYXBpc1tpXTtcbiAgICB2YXIgcGF0aCA9IGFwaS5wYXRoO1xuICAgIHZhciBhYnNvbHV0ZVBhdGggPSB0aGlzLmdldEFic29sdXRlUGF0aChvYmouc3dhZ2dlclZlcnNpb24sIHRoaXMuZG9jTG9jYXRpb24sIHBhdGgpO1xuXG4gICAgaWYoYXBpLmRlc2NyaXB0aW9uKSB7XG4gICAgICBzd2FnZ2VyLnRhZ3MgPSBzd2FnZ2VyLnRhZ3MgfHwgW107XG4gICAgICBzd2FnZ2VyLnRhZ3MucHVzaCh7XG4gICAgICAgIG5hbWUgOiB0aGlzLmV4dHJhY3RUYWcoYXBpLnBhdGgpLFxuICAgICAgICBkZXNjcmlwdGlvbiA6IGFwaS5kZXNjcmlwdGlvbiB8fCAnJ1xuICAgICAgfSk7XG4gICAgfVxuICAgIHZhciBodHRwID0ge1xuICAgICAgdXJsOiBhYnNvbHV0ZVBhdGgsXG4gICAgICBoZWFkZXJzOiB7IGFjY2VwdDogc3dhZ2dlclJlcXVlc3RIZWFkZXJzIH0sXG4gICAgICBvbjoge30sXG4gICAgICBtZXRob2Q6ICdnZXQnLFxuICAgICAgdGltZW91dDogb3B0cy50aW1lb3V0XG4gICAgfTtcbiAgICAvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXG4gICAgaHR0cC5vbi5yZXNwb25zZSA9IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICAgIHByb2Nlc3NlZENvdW50ICs9IDE7XG4gICAgICB2YXIgb2JqID0gZGF0YS5vYmo7XG4gICAgICBpZihvYmopIHtcbiAgICAgICAgc2VsZi5kZWNsYXJhdGlvbihvYmosIF9zd2FnZ2VyKTtcbiAgICAgIH1cbiAgICAgIGlmKHByb2Nlc3NlZENvdW50ID09PSBleHBlY3RlZENvdW50KSB7XG4gICAgICAgIHNlbGYuZmluaXNoKGNhbGxiYWNrLCBfc3dhZ2dlcik7XG4gICAgICB9XG4gICAgfTtcbiAgICBodHRwLm9uLmVycm9yID0gZnVuY3Rpb24oZGF0YSkge1xuICAgICAgY29uc29sZS5lcnJvcihkYXRhKTtcbiAgICAgIHByb2Nlc3NlZENvdW50ICs9IDE7XG4gICAgICBpZihwcm9jZXNzZWRDb3VudCA9PT0gZXhwZWN0ZWRDb3VudCkge1xuICAgICAgICBzZWxmLmZpbmlzaChjYWxsYmFjaywgX3N3YWdnZXIpO1xuICAgICAgfVxuICAgIH07XG4gICAgLyoganNoaW50IGlnbm9yZTplbmQgKi9cblxuICAgIGlmKHRoaXMuY2xpZW50QXV0aG9yaXphdGlvbnMgJiYgdHlwZW9mIHRoaXMuY2xpZW50QXV0aG9yaXphdGlvbnMuYXBwbHkgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRoaXMuY2xpZW50QXV0aG9yaXphdGlvbnMuYXBwbHkoaHR0cCk7XG4gICAgfVxuXG4gICAgbmV3IFN3YWdnZXJIdHRwKCkuZXhlY3V0ZShodHRwLCBfb3B0cyk7XG4gIH1cbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5nZXRBYnNvbHV0ZVBhdGggPSBmdW5jdGlvbih2ZXJzaW9uLCBkb2NMb2NhdGlvbiwgcGF0aCkgIHtcbiAgaWYodmVyc2lvbiA9PT0gJzEuMCcpIHtcbiAgICBpZihkb2NMb2NhdGlvbi5lbmRzV2l0aCgnLmpzb24nKSkge1xuICAgICAgLy8gZ2V0IHJvb3QgcGF0aFxuICAgICAgdmFyIHBvcyA9IGRvY0xvY2F0aW9uLmxhc3RJbmRleE9mKCcvJyk7XG4gICAgICBpZihwb3MgPiAwKSB7XG4gICAgICAgIGRvY0xvY2F0aW9uID0gZG9jTG9jYXRpb24uc3Vic3RyaW5nKDAsIHBvcyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIGxvY2F0aW9uID0gZG9jTG9jYXRpb247XG4gIGlmKHBhdGguaW5kZXhPZignaHR0cDonKSA9PT0gMCB8fCBwYXRoLmluZGV4T2YoJ2h0dHBzOicpID09PSAwKSB7XG4gICAgbG9jYXRpb24gPSBwYXRoO1xuICB9XG4gIGVsc2Uge1xuICAgIGlmKGRvY0xvY2F0aW9uLmVuZHNXaXRoKCcvJykpIHtcbiAgICAgIGxvY2F0aW9uID0gZG9jTG9jYXRpb24uc3Vic3RyaW5nKDAsIGRvY0xvY2F0aW9uLmxlbmd0aCAtIDEpO1xuICAgIH1cbiAgICBsb2NhdGlvbiArPSBwYXRoO1xuICB9XG4gIGxvY2F0aW9uID0gbG9jYXRpb24ucmVwbGFjZSgne2Zvcm1hdH0nLCAnanNvbicpO1xuICByZXR1cm4gbG9jYXRpb247XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuc2VjdXJpdHlEZWZpbml0aW9ucyA9IGZ1bmN0aW9uKG9iaiwgc3dhZ2dlcikge1xuICBpZihvYmouYXV0aG9yaXphdGlvbnMpIHtcbiAgICB2YXIgbmFtZTtcbiAgICBmb3IobmFtZSBpbiBvYmouYXV0aG9yaXphdGlvbnMpIHtcbiAgICAgIHZhciBpc1ZhbGlkID0gZmFsc2U7XG4gICAgICB2YXIgc2VjdXJpdHlEZWZpbml0aW9uID0ge1xuICAgICAgICB2ZW5kb3JFeHRlbnNpb25zOiB7fVxuICAgICAgfTtcbiAgICAgIHZhciBkZWZpbml0aW9uID0gb2JqLmF1dGhvcml6YXRpb25zW25hbWVdO1xuICAgICAgaWYoZGVmaW5pdGlvbi50eXBlID09PSAnYXBpS2V5Jykge1xuICAgICAgICBzZWN1cml0eURlZmluaXRpb24udHlwZSA9ICdhcGlLZXknO1xuICAgICAgICBzZWN1cml0eURlZmluaXRpb24uaW4gPSBkZWZpbml0aW9uLnBhc3NBcztcbiAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLm5hbWUgPSBkZWZpbml0aW9uLmtleW5hbWUgfHwgbmFtZTtcbiAgICAgICAgaXNWYWxpZCA9IHRydWU7XG4gICAgICB9XG4gICAgICBlbHNlIGlmKGRlZmluaXRpb24udHlwZSA9PT0gJ2Jhc2ljQXV0aCcpIHtcbiAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLnR5cGUgPSAnYmFzaWNBdXRoJztcbiAgICAgICAgaXNWYWxpZCA9IHRydWU7XG4gICAgICB9XG4gICAgICBlbHNlIGlmKGRlZmluaXRpb24udHlwZSA9PT0gJ29hdXRoMicpIHtcbiAgICAgICAgdmFyIGV4aXN0aW5nU2NvcGVzID0gZGVmaW5pdGlvbi5zY29wZXMgfHwgW107XG4gICAgICAgIHZhciBzY29wZXMgPSB7fTtcbiAgICAgICAgdmFyIGk7XG4gICAgICAgIGZvcihpIGluIGV4aXN0aW5nU2NvcGVzKSB7XG4gICAgICAgICAgdmFyIHNjb3BlID0gZXhpc3RpbmdTY29wZXNbaV07XG4gICAgICAgICAgc2NvcGVzW3Njb3BlLnNjb3BlXSA9IHNjb3BlLmRlc2NyaXB0aW9uO1xuICAgICAgICB9XG4gICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi50eXBlID0gJ29hdXRoMic7XG4gICAgICAgIGlmKGkgPiAwKSB7XG4gICAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLnNjb3BlcyA9IHNjb3BlcztcbiAgICAgICAgfVxuICAgICAgICBpZihkZWZpbml0aW9uLmdyYW50VHlwZXMpIHtcbiAgICAgICAgICBpZihkZWZpbml0aW9uLmdyYW50VHlwZXMuaW1wbGljaXQpIHtcbiAgICAgICAgICAgIHZhciBpbXBsaWNpdCA9IGRlZmluaXRpb24uZ3JhbnRUeXBlcy5pbXBsaWNpdDtcbiAgICAgICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi5mbG93ID0gJ2ltcGxpY2l0JztcbiAgICAgICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi5hdXRob3JpemF0aW9uVXJsID0gaW1wbGljaXQubG9naW5FbmRwb2ludDtcbiAgICAgICAgICAgIGlzVmFsaWQgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXG4gICAgICAgICAgaWYoZGVmaW5pdGlvbi5ncmFudFR5cGVzWydhdXRob3JpemF0aW9uX2NvZGUnXSkge1xuICAgICAgICAgICAgaWYoIXNlY3VyaXR5RGVmaW5pdGlvbi5mbG93KSB7XG4gICAgICAgICAgICAgIC8vIGNhbm5vdCBzZXQgaWYgZmxvdyBpcyBhbHJlYWR5IGRlZmluZWRcbiAgICAgICAgICAgICAgdmFyIGF1dGhDb2RlID0gZGVmaW5pdGlvbi5ncmFudFR5cGVzWydhdXRob3JpemF0aW9uX2NvZGUnXTtcbiAgICAgICAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLmZsb3cgPSAnYWNjZXNzQ29kZSc7XG4gICAgICAgICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi5hdXRob3JpemF0aW9uVXJsID0gYXV0aENvZGUudG9rZW5SZXF1ZXN0RW5kcG9pbnQudXJsO1xuICAgICAgICAgICAgICBzZWN1cml0eURlZmluaXRpb24udG9rZW5VcmwgPSBhdXRoQ29kZS50b2tlbkVuZHBvaW50LnVybDtcbiAgICAgICAgICAgICAgaXNWYWxpZCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIC8qIGpzaGludCBpZ25vcmU6ZW5kICovXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmKGlzVmFsaWQpIHtcbiAgICAgICAgc3dhZ2dlci5zZWN1cml0eURlZmluaXRpb25zID0gc3dhZ2dlci5zZWN1cml0eURlZmluaXRpb25zIHx8IHt9O1xuICAgICAgICBzd2FnZ2VyLnNlY3VyaXR5RGVmaW5pdGlvbnNbbmFtZV0gPSBzZWN1cml0eURlZmluaXRpb247XG4gICAgICB9XG4gICAgfVxuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuYXBpSW5mbyA9IGZ1bmN0aW9uKG9iaiwgc3dhZ2dlcikge1xuICAvLyBpbmZvIHNlY3Rpb25cbiAgaWYob2JqLmluZm8pIHtcbiAgICB2YXIgaW5mbyA9IG9iai5pbmZvO1xuICAgIHN3YWdnZXIuaW5mbyA9IHt9O1xuXG4gICAgaWYoaW5mby5jb250YWN0KSB7XG4gICAgICBzd2FnZ2VyLmluZm8uY29udGFjdCA9IHt9O1xuICAgICAgc3dhZ2dlci5pbmZvLmNvbnRhY3QuZW1haWwgPSBpbmZvLmNvbnRhY3Q7XG4gICAgfVxuICAgIGlmKGluZm8uZGVzY3JpcHRpb24pIHtcbiAgICAgIHN3YWdnZXIuaW5mby5kZXNjcmlwdGlvbiA9IGluZm8uZGVzY3JpcHRpb247XG4gICAgfVxuICAgIGlmKGluZm8udGl0bGUpIHtcbiAgICAgIHN3YWdnZXIuaW5mby50aXRsZSA9IGluZm8udGl0bGU7XG4gICAgfVxuICAgIGlmKGluZm8udGVybXNPZlNlcnZpY2VVcmwpIHtcbiAgICAgIHN3YWdnZXIuaW5mby50ZXJtc09mU2VydmljZSA9IGluZm8udGVybXNPZlNlcnZpY2VVcmw7XG4gICAgfVxuICAgIGlmKGluZm8ubGljZW5zZSB8fCBpbmZvLmxpY2Vuc2VVcmwpIHtcbiAgICAgIHN3YWdnZXIubGljZW5zZSA9IHt9O1xuICAgICAgaWYoaW5mby5saWNlbnNlKSB7XG4gICAgICAgIHN3YWdnZXIubGljZW5zZS5uYW1lID0gaW5mby5saWNlbnNlO1xuICAgICAgfVxuICAgICAgaWYoaW5mby5saWNlbnNlVXJsKSB7XG4gICAgICAgIHN3YWdnZXIubGljZW5zZS51cmwgPSBpbmZvLmxpY2Vuc2VVcmw7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGVsc2Uge1xuICAgIHRoaXMud2FybmluZ3MucHVzaCgnbWlzc2luZyBpbmZvIHNlY3Rpb24nKTtcbiAgfVxufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLmZpbmlzaCA9IGZ1bmN0aW9uIChjYWxsYmFjaywgb2JqKSB7XG4gIGNhbGxiYWNrKG9iaik7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgbG9nID0gcmVxdWlyZSgnLi4vaGVscGVycycpLmxvZztcbnZhciBfID0ge1xuICBpc1BsYWluT2JqZWN0OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNQbGFpbk9iamVjdCcpLFxuICBpc1N0cmluZzogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzU3RyaW5nJyksXG59O1xuXG52YXIgU2NoZW1hTWFya3VwID0gcmVxdWlyZSgnLi4vc2NoZW1hLW1hcmt1cC5qcycpO1xudmFyIGpzeWFtbCA9IHJlcXVpcmUoJ2pzLXlhbWwnKTtcblxudmFyIE1vZGVsID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAobmFtZSwgZGVmaW5pdGlvbiwgbW9kZWxzLCBtb2RlbFByb3BlcnR5TWFjcm8pIHtcbiAgdGhpcy5kZWZpbml0aW9uID0gZGVmaW5pdGlvbiB8fCB7fTtcbiAgdGhpcy5pc0FycmF5ID0gZGVmaW5pdGlvbi50eXBlID09PSAnYXJyYXknO1xuICB0aGlzLm1vZGVscyA9IG1vZGVscyB8fCB7fTtcbiAgdGhpcy5uYW1lID0gbmFtZSB8fCBkZWZpbml0aW9uLnRpdGxlIHx8ICdJbmxpbmUgTW9kZWwnO1xuICB0aGlzLm1vZGVsUHJvcGVydHlNYWNybyA9IG1vZGVsUHJvcGVydHlNYWNybyB8fCBmdW5jdGlvbiAocHJvcGVydHkpIHtcbiAgICByZXR1cm4gcHJvcGVydHkuZGVmYXVsdDtcbiAgfTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIE5vdGUhICBUaGlzIGZ1bmN0aW9uIHdpbGwgYmUgcmVtb3ZlZCBpbiAyLjIueCFcbk1vZGVsLnByb3RvdHlwZS5jcmVhdGVKU09OU2FtcGxlID0gTW9kZWwucHJvdG90eXBlLmdldFNhbXBsZVZhbHVlID0gZnVuY3Rpb24gKG1vZGVsc1RvSWdub3JlKSB7XG4gIG1vZGVsc1RvSWdub3JlID0gbW9kZWxzVG9JZ25vcmUgfHwge307XG5cbiAgbW9kZWxzVG9JZ25vcmVbdGhpcy5uYW1lXSA9IHRoaXM7XG5cbiAgLy8gUmVzcG9uc2Ugc3VwcG9ydFxuICBpZiAodGhpcy5leGFtcGxlcyAmJiBfLmlzUGxhaW5PYmplY3QodGhpcy5leGFtcGxlcykgJiYgdGhpcy5leGFtcGxlc1snYXBwbGljYXRpb24vanNvbiddKSB7XG4gICAgdGhpcy5kZWZpbml0aW9uLmV4YW1wbGUgPSB0aGlzLmV4YW1wbGVzWydhcHBsaWNhdGlvbi9qc29uJ107XG5cbiAgICBpZiAoXy5pc1N0cmluZyh0aGlzLmRlZmluaXRpb24uZXhhbXBsZSkpIHtcbiAgICAgIHRoaXMuZGVmaW5pdGlvbi5leGFtcGxlID0ganN5YW1sLnNhZmVMb2FkKHRoaXMuZGVmaW5pdGlvbi5leGFtcGxlKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoIXRoaXMuZGVmaW5pdGlvbi5leGFtcGxlKSB7XG4gICAgdGhpcy5kZWZpbml0aW9uLmV4YW1wbGUgPSB0aGlzLmV4YW1wbGVzO1xuICB9XG5cbiAgcmV0dXJuIFNjaGVtYU1hcmt1cC5zY2hlbWFUb0pTT04odGhpcy5kZWZpbml0aW9uLCB0aGlzLm1vZGVscywgbW9kZWxzVG9JZ25vcmUsIHRoaXMubW9kZWxQcm9wZXJ0eU1hY3JvKTtcbn07XG5cbk1vZGVsLnByb3RvdHlwZS5nZXRNb2NrU2lnbmF0dXJlID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gU2NoZW1hTWFya3VwLnNjaGVtYVRvSFRNTCh0aGlzLm5hbWUsIHRoaXMuZGVmaW5pdGlvbiwgdGhpcy5tb2RlbHMsIHRoaXMubW9kZWxQcm9wZXJ0eU1hY3JvKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBfID0ge1xuICBjbG9uZURlZXA6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9jbG9uZURlZXAnKSxcbiAgaXNVbmRlZmluZWQ6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc1VuZGVmaW5lZCcpLFxuICBpc0VtcHR5OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNFbXB0eScpLFxuICBpc09iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzT2JqZWN0Jylcbn07XG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4uL2hlbHBlcnMnKTtcbnZhciBNb2RlbCA9IHJlcXVpcmUoJy4vbW9kZWwnKTtcbnZhciBTd2FnZ2VySHR0cCA9IHJlcXVpcmUoJy4uL2h0dHAnKTtcbnZhciBRID0gcmVxdWlyZSgncScpO1xuXG52YXIgT3BlcmF0aW9uID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAocGFyZW50LCBzY2hlbWUsIG9wZXJhdGlvbklkLCBodHRwTWV0aG9kLCBwYXRoLCBhcmdzLCBkZWZpbml0aW9ucywgbW9kZWxzLCBjbGllbnRBdXRob3JpemF0aW9ucykge1xuICB2YXIgZXJyb3JzID0gW107XG5cbiAgcGFyZW50ID0gcGFyZW50IHx8IHt9O1xuICBhcmdzID0gYXJncyB8fCB7fTtcblxuICBpZihwYXJlbnQgJiYgcGFyZW50Lm9wdGlvbnMpIHtcbiAgICB0aGlzLmNsaWVudCA9IHBhcmVudC5vcHRpb25zLmNsaWVudCB8fCBudWxsO1xuICAgIHRoaXMucmVxdWVzdEludGVyY2VwdG9yID0gcGFyZW50Lm9wdGlvbnMucmVxdWVzdEludGVyY2VwdG9yIHx8IG51bGw7XG4gICAgdGhpcy5yZXNwb25zZUludGVyY2VwdG9yID0gcGFyZW50Lm9wdGlvbnMucmVzcG9uc2VJbnRlcmNlcHRvciB8fCBudWxsO1xuICAgIHRoaXMucmVxdWVzdEFnZW50ID0gcGFyZW50Lm9wdGlvbnMucmVxdWVzdEFnZW50O1xuICB9XG4gIHRoaXMuYXV0aG9yaXphdGlvbnMgPSBhcmdzLnNlY3VyaXR5O1xuICB0aGlzLmJhc2VQYXRoID0gcGFyZW50LmJhc2VQYXRoIHx8ICcvJztcbiAgdGhpcy5jbGllbnRBdXRob3JpemF0aW9ucyA9IGNsaWVudEF1dGhvcml6YXRpb25zO1xuICB0aGlzLmNvbnN1bWVzID0gYXJncy5jb25zdW1lcyB8fCBwYXJlbnQuY29uc3VtZXMgfHwgWydhcHBsaWNhdGlvbi9qc29uJ107XG4gIHRoaXMucHJvZHVjZXMgPSBhcmdzLnByb2R1Y2VzIHx8IHBhcmVudC5wcm9kdWNlcyB8fCBbJ2FwcGxpY2F0aW9uL2pzb24nXTtcbiAgdGhpcy5kZXByZWNhdGVkID0gYXJncy5kZXByZWNhdGVkO1xuICB0aGlzLmRlc2NyaXB0aW9uID0gYXJncy5kZXNjcmlwdGlvbjtcbiAgdGhpcy5ob3N0ID0gcGFyZW50Lmhvc3Q7XG4gIHRoaXMubWV0aG9kID0gKGh0dHBNZXRob2QgfHwgZXJyb3JzLnB1c2goJ09wZXJhdGlvbiAnICsgb3BlcmF0aW9uSWQgKyAnIGlzIG1pc3NpbmcgbWV0aG9kLicpKTtcbiAgdGhpcy5tb2RlbHMgPSBtb2RlbHMgfHwge307XG4gIHRoaXMubmlja25hbWUgPSAob3BlcmF0aW9uSWQgfHwgZXJyb3JzLnB1c2goJ09wZXJhdGlvbnMgbXVzdCBoYXZlIGEgbmlja25hbWUuJykpO1xuICB0aGlzLm9wZXJhdGlvbiA9IGFyZ3M7XG4gIHRoaXMub3BlcmF0aW9ucyA9IHt9O1xuICB0aGlzLnBhcmFtZXRlcnMgPSBhcmdzICE9PSBudWxsID8gKGFyZ3MucGFyYW1ldGVycyB8fCBbXSkgOiB7fTtcbiAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7XG4gIHRoaXMucGF0aCA9IChwYXRoIHx8IGVycm9ycy5wdXNoKCdPcGVyYXRpb24gJyArIHRoaXMubmlja25hbWUgKyAnIGlzIG1pc3NpbmcgcGF0aC4nKSk7XG4gIHRoaXMucmVzcG9uc2VzID0gKGFyZ3MucmVzcG9uc2VzIHx8IHt9KTtcbiAgdGhpcy5zY2hlbWUgPSBzY2hlbWUgfHwgcGFyZW50LnNjaGVtZSB8fCAnaHR0cCc7XG4gIHRoaXMuc2NoZW1lcyA9IGFyZ3Muc2NoZW1lcyB8fCBwYXJlbnQuc2NoZW1lcztcbiAgdGhpcy5zZWN1cml0eSA9IGFyZ3Muc2VjdXJpdHkgfHwgcGFyZW50LnNlY3VyaXR5O1xuICB0aGlzLnN1bW1hcnkgPSBhcmdzLnN1bW1hcnkgfHwgJyc7XG4gIHRoaXMudGltZW91dCA9IHBhcmVudC50aW1lb3V0O1xuICB0aGlzLnR5cGUgPSBudWxsO1xuICB0aGlzLnVzZUpRdWVyeSA9IHBhcmVudC51c2VKUXVlcnk7XG4gIHRoaXMuanF1ZXJ5QWpheENhY2hlID0gcGFyZW50LmpxdWVyeUFqYXhDYWNoZTtcbiAgdGhpcy5lbmFibGVDb29raWVzID0gcGFyZW50LmVuYWJsZUNvb2tpZXM7XG5cbiAgdmFyIGtleTtcblxuICBpZighdGhpcy5ob3N0KSB7XG4gICAgaWYodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRoaXMuaG9zdCA9IHdpbmRvdy5sb2NhdGlvbi5ob3N0O1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHRoaXMuaG9zdCA9ICdsb2NhbGhvc3QnO1xuICAgIH1cbiAgfVxuICB0aGlzLnBhcmFtZXRlck1hY3JvID0gcGFyZW50LnBhcmFtZXRlck1hY3JvIHx8IGZ1bmN0aW9uIChvcGVyYXRpb24sIHBhcmFtZXRlcikge1xuICAgIHJldHVybiBwYXJhbWV0ZXIuZGVmYXVsdDtcbiAgfTtcblxuICB0aGlzLmlubGluZU1vZGVscyA9IFtdO1xuXG4gIGlmKHRoaXMuYmFzZVBhdGggIT09ICcvJyAmJiB0aGlzLmJhc2VQYXRoLnNsaWNlKC0xKSA9PT0gJy8nKSB7XG4gICAgdGhpcy5iYXNlUGF0aCA9IHRoaXMuYmFzZVBhdGguc2xpY2UoMCwgLTEpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiB0aGlzLmRlcHJlY2F0ZWQgPT09ICdzdHJpbmcnKSB7XG4gICAgc3dpdGNoKHRoaXMuZGVwcmVjYXRlZC50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICBjYXNlICd0cnVlJzogY2FzZSAneWVzJzogY2FzZSAnMSc6IHtcbiAgICAgICAgdGhpcy5kZXByZWNhdGVkID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGNhc2UgJ2ZhbHNlJzogY2FzZSAnbm8nOiBjYXNlICcwJzogY2FzZSBudWxsOiB7XG4gICAgICAgIHRoaXMuZGVwcmVjYXRlZCA9IGZhbHNlO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgZGVmYXVsdDogdGhpcy5kZXByZWNhdGVkID0gQm9vbGVhbih0aGlzLmRlcHJlY2F0ZWQpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBpLCBtb2RlbDtcblxuICBpZiAoZGVmaW5pdGlvbnMpIHtcbiAgICAvLyBhZGQgdG8gZ2xvYmFsIG1vZGVsc1xuICAgIGZvciAoa2V5IGluIGRlZmluaXRpb25zKSB7XG4gICAgICBtb2RlbCA9IG5ldyBNb2RlbChrZXksIGRlZmluaXRpb25zW2tleV0sIHRoaXMubW9kZWxzLCBwYXJlbnQubW9kZWxQcm9wZXJ0eU1hY3JvKTtcblxuICAgICAgaWYgKG1vZGVsKSB7XG4gICAgICAgIHRoaXMubW9kZWxzW2tleV0gPSBtb2RlbDtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgZWxzZSB7XG4gICAgZGVmaW5pdGlvbnMgPSB7fTtcbiAgfVxuXG4gIGZvciAoaSA9IDA7IGkgPCB0aGlzLnBhcmFtZXRlcnMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZCwgcGFyYW0gPSB0aGlzLnBhcmFtZXRlcnNbaV07XG5cbiAgICAvLyBBbGxvdyBtYWNybyB0byBzZXQgdGhlIGRlZmF1bHQgdmFsdWVcbiAgICBwYXJhbS5kZWZhdWx0ID0gdGhpcy5wYXJhbWV0ZXJNYWNybyh0aGlzLCBwYXJhbSk7XG5cbiAgICBpZiAocGFyYW0udHlwZSA9PT0gJ2FycmF5Jykge1xuICAgICAgcGFyYW0uaXNMaXN0ID0gdHJ1ZTtcbiAgICAgIHBhcmFtLmFsbG93TXVsdGlwbGUgPSB0cnVlO1xuICAgIH1cblxuICAgIHZhciBpbm5lclR5cGUgPSB0aGlzLmdldFR5cGUocGFyYW0pO1xuXG4gICAgaWYgKGlubmVyVHlwZSAmJiBpbm5lclR5cGUudG9TdHJpbmcoKS50b0xvd2VyQ2FzZSgpID09PSAnYm9vbGVhbicpIHtcbiAgICAgIHBhcmFtLmFsbG93YWJsZVZhbHVlcyA9IHt9O1xuICAgICAgcGFyYW0uaXNMaXN0ID0gdHJ1ZTtcbiAgICAgIHBhcmFtWydlbnVtJ10gPSBbdHJ1ZSwgZmFsc2VdOyAvLyB1c2UgYWN0dWFsIHByaW1pdGl2ZXNcbiAgICB9XG5cbiAgICBmb3Ioa2V5IGluIHBhcmFtKSB7XG4gICAgICBoZWxwZXJzLmV4dHJhY3RFeHRlbnNpb25zKGtleSwgcGFyYW0pO1xuICAgIH1cbiAgICBpZih0eXBlb2YgcGFyYW1bJ3gtZXhhbXBsZSddICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgZCA9IHBhcmFtWyd4LWV4YW1wbGUnXTtcbiAgICAgIHBhcmFtLmRlZmF1bHQgPSBkO1xuICAgIH1cbiAgICBpZihwYXJhbVsneC1leGFtcGxlcyddKSB7XG4gICAgICBkID0gcGFyYW1bJ3gtZXhhbXBsZXMnXS5kZWZhdWx0O1xuICAgICAgaWYodHlwZW9mIGQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHBhcmFtLmRlZmF1bHQgPSBkO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBlbnVtVmFsdWVzID0gcGFyYW1bJ2VudW0nXSB8fCAocGFyYW0uaXRlbXMgJiYgcGFyYW0uaXRlbXNbJ2VudW0nXSk7XG5cbiAgICBpZiAodHlwZW9mIGVudW1WYWx1ZXMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB2YXIgaWQ7XG5cbiAgICAgIHBhcmFtLmFsbG93YWJsZVZhbHVlcyA9IHt9O1xuICAgICAgcGFyYW0uYWxsb3dhYmxlVmFsdWVzLnZhbHVlcyA9IFtdO1xuICAgICAgcGFyYW0uYWxsb3dhYmxlVmFsdWVzLmRlc2NyaXB0aXZlVmFsdWVzID0gW107XG5cbiAgICAgIGZvciAoaWQgPSAwOyBpZCA8IGVudW1WYWx1ZXMubGVuZ3RoOyBpZCsrKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGVudW1WYWx1ZXNbaWRdO1xuICAgICAgICB2YXIgaXNEZWZhdWx0ID0gKHZhbHVlID09PSBwYXJhbS5kZWZhdWx0IHx8IHZhbHVlKycnID09PSBwYXJhbS5kZWZhdWx0KTtcblxuICAgICAgICBwYXJhbS5hbGxvd2FibGVWYWx1ZXMudmFsdWVzLnB1c2godmFsdWUpO1xuICAgICAgICAvLyBBbHdheXMgaGF2ZSBzdHJpbmcgZm9yIGRlc2NyaXB0aXZlIHZhbHVlcy4uLi5cbiAgICAgICAgcGFyYW0uYWxsb3dhYmxlVmFsdWVzLmRlc2NyaXB0aXZlVmFsdWVzLnB1c2goe3ZhbHVlIDogdmFsdWUrJycsIGlzRGVmYXVsdDogaXNEZWZhdWx0fSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtLnR5cGUgPT09ICdhcnJheScpIHtcbiAgICAgIGlubmVyVHlwZSA9IFtpbm5lclR5cGVdO1xuXG4gICAgICBpZiAodHlwZW9mIHBhcmFtLmFsbG93YWJsZVZhbHVlcyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgLy8gY2FuJ3Qgc2hvdyBhcyBhIGxpc3QgaWYgbm8gdmFsdWVzIHRvIHNlbGVjdCBmcm9tXG4gICAgICAgIGRlbGV0ZSBwYXJhbS5pc0xpc3Q7XG4gICAgICAgIGRlbGV0ZSBwYXJhbS5hbGxvd011bHRpcGxlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHBhcmFtLm1vZGVsU2lnbmF0dXJlID0ge3R5cGU6IGlubmVyVHlwZSwgZGVmaW5pdGlvbnM6IHRoaXMubW9kZWxzfTtcbiAgICBwYXJhbS5zaWduYXR1cmUgPSB0aGlzLmdldE1vZGVsU2lnbmF0dXJlKGlubmVyVHlwZSwgdGhpcy5tb2RlbHMpLnRvU3RyaW5nKCk7XG4gICAgcGFyYW0uc2FtcGxlSlNPTiA9IHRoaXMuZ2V0TW9kZWxTYW1wbGVKU09OKGlubmVyVHlwZSwgdGhpcy5tb2RlbHMpO1xuICAgIHBhcmFtLnJlc3BvbnNlQ2xhc3NTaWduYXR1cmUgPSBwYXJhbS5zaWduYXR1cmU7XG4gIH1cblxuICB2YXIga2V5bmFtZSwgZGVmYXVsdFJlc3BvbnNlQ29kZSwgcmVzcG9uc2UsIHJlc3BvbnNlcyA9IHRoaXMucmVzcG9uc2VzO1xuXG4gIGlmIChyZXNwb25zZXNbJzIwMCddKSB7XG4gICAgcmVzcG9uc2UgPSByZXNwb25zZXNbJzIwMCddO1xuICAgIGRlZmF1bHRSZXNwb25zZUNvZGUgPSAnMjAwJztcbiAgfSBlbHNlIGlmIChyZXNwb25zZXNbJzIwMSddKSB7XG4gICAgcmVzcG9uc2UgPSByZXNwb25zZXNbJzIwMSddO1xuICAgIGRlZmF1bHRSZXNwb25zZUNvZGUgPSAnMjAxJztcbiAgfSBlbHNlIGlmIChyZXNwb25zZXNbJzIwMiddKSB7XG4gICAgcmVzcG9uc2UgPSByZXNwb25zZXNbJzIwMiddO1xuICAgIGRlZmF1bHRSZXNwb25zZUNvZGUgPSAnMjAyJztcbiAgfSBlbHNlIGlmIChyZXNwb25zZXNbJzIwMyddKSB7XG4gICAgcmVzcG9uc2UgPSByZXNwb25zZXNbJzIwMyddO1xuICAgIGRlZmF1bHRSZXNwb25zZUNvZGUgPSAnMjAzJztcbiAgfSBlbHNlIGlmIChyZXNwb25zZXNbJzIwNCddKSB7XG4gICAgcmVzcG9uc2UgPSByZXNwb25zZXNbJzIwNCddO1xuICAgIGRlZmF1bHRSZXNwb25zZUNvZGUgPSAnMjA0JztcbiAgfSBlbHNlIGlmIChyZXNwb25zZXNbJzIwNSddKSB7XG4gICAgcmVzcG9uc2UgPSByZXNwb25zZXNbJzIwNSddO1xuICAgIGRlZmF1bHRSZXNwb25zZUNvZGUgPSAnMjA1JztcbiAgfSBlbHNlIGlmIChyZXNwb25zZXNbJzIwNiddKSB7XG4gICAgcmVzcG9uc2UgPSByZXNwb25zZXNbJzIwNiddO1xuICAgIGRlZmF1bHRSZXNwb25zZUNvZGUgPSAnMjA2JztcbiAgfSBlbHNlIGlmIChyZXNwb25zZXNbJ2RlZmF1bHQnXSkge1xuICAgIHJlc3BvbnNlID0gcmVzcG9uc2VzWydkZWZhdWx0J107XG4gICAgZGVmYXVsdFJlc3BvbnNlQ29kZSA9ICdkZWZhdWx0JztcbiAgfVxuXG4gIGZvcihrZXluYW1lIGluIHJlc3BvbnNlcykge1xuICAgIGhlbHBlcnMuZXh0cmFjdEV4dGVuc2lvbnMoa2V5bmFtZSwgcmVzcG9uc2VzKTtcbiAgICBpZih0eXBlb2Yga2V5bmFtZSA9PT0gJ3N0cmluZycgJiYga2V5bmFtZS5pbmRleE9mKCd4LScpID09PSAtMSkge1xuICAgICAgdmFyIHJlc3BvbnNlT2JqZWN0ID0gcmVzcG9uc2VzW2tleW5hbWVdO1xuICAgICAgaWYodHlwZW9mIHJlc3BvbnNlT2JqZWN0ID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgcmVzcG9uc2VPYmplY3QuaGVhZGVycyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgdmFyIGhlYWRlcnMgPSByZXNwb25zZU9iamVjdC5oZWFkZXJzO1xuICAgICAgICBmb3IodmFyIGhlYWRlck5hbWUgaW4gaGVhZGVycykge1xuICAgICAgICAgIHZhciBoZWFkZXIgPSBoZWFkZXJzW2hlYWRlck5hbWVdO1xuICAgICAgICAgIGlmKHR5cGVvZiBoZWFkZXIgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICBmb3IodmFyIGhlYWRlcktleSBpbiBoZWFkZXIpIHtcbiAgICAgICAgICAgICAgaGVscGVycy5leHRyYWN0RXh0ZW5zaW9ucyhoZWFkZXJLZXksIGhlYWRlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKHJlc3BvbnNlKSB7XG4gICAgZm9yKGtleW5hbWUgaW4gcmVzcG9uc2UpIHtcbiAgICAgIGhlbHBlcnMuZXh0cmFjdEV4dGVuc2lvbnMoa2V5bmFtZSwgcmVzcG9uc2UpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChyZXNwb25zZSAmJiByZXNwb25zZS5zY2hlbWEpIHtcbiAgICB2YXIgcmVzb2x2ZWRNb2RlbCA9IHRoaXMucmVzb2x2ZU1vZGVsKHJlc3BvbnNlLnNjaGVtYSwgZGVmaW5pdGlvbnMpO1xuICAgIHZhciBzdWNjZXNzUmVzcG9uc2U7XG5cbiAgICBkZWxldGUgcmVzcG9uc2VzW2RlZmF1bHRSZXNwb25zZUNvZGVdO1xuXG4gICAgaWYgKHJlc29sdmVkTW9kZWwpIHtcbiAgICAgIHRoaXMuc3VjY2Vzc1Jlc3BvbnNlID0ge307XG4gICAgICBzdWNjZXNzUmVzcG9uc2UgPSB0aGlzLnN1Y2Nlc3NSZXNwb25zZVtkZWZhdWx0UmVzcG9uc2VDb2RlXSA9IHJlc29sdmVkTW9kZWw7XG4gICAgfSBlbHNlIGlmICghcmVzcG9uc2Uuc2NoZW1hLnR5cGUgfHwgcmVzcG9uc2Uuc2NoZW1hLnR5cGUgPT09ICdvYmplY3QnIHx8IHJlc3BvbnNlLnNjaGVtYS50eXBlID09PSAnYXJyYXknKSB7XG4gICAgICAvLyBJbmxpbmUgbW9kZWxcbiAgICAgIHRoaXMuc3VjY2Vzc1Jlc3BvbnNlID0ge307XG4gICAgICBzdWNjZXNzUmVzcG9uc2UgPSB0aGlzLnN1Y2Nlc3NSZXNwb25zZVtkZWZhdWx0UmVzcG9uc2VDb2RlXSA9IG5ldyBNb2RlbCh1bmRlZmluZWQsIHJlc3BvbnNlLnNjaGVtYSB8fCB7fSwgdGhpcy5tb2RlbHMsIHBhcmVudC5tb2RlbFByb3BlcnR5TWFjcm8pO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBQcmltaXRpdmVcbiAgICAgIHRoaXMuc3VjY2Vzc1Jlc3BvbnNlID0ge307XG4gICAgICBzdWNjZXNzUmVzcG9uc2UgPSB0aGlzLnN1Y2Nlc3NSZXNwb25zZVtkZWZhdWx0UmVzcG9uc2VDb2RlXSA9IHJlc3BvbnNlLnNjaGVtYTtcbiAgICB9XG5cbiAgICBpZiAoc3VjY2Vzc1Jlc3BvbnNlKSB7XG4gICAgICBzdWNjZXNzUmVzcG9uc2UudmVuZG9yRXh0ZW5zaW9ucyA9IHJlc3BvbnNlLnZlbmRvckV4dGVuc2lvbnM7XG4gICAgICAvLyBBdHRhY2ggcmVzcG9uc2UgcHJvcGVydGllc1xuICAgICAgaWYgKHJlc3BvbnNlLmRlc2NyaXB0aW9uKSB7XG4gICAgICAgIHN1Y2Nlc3NSZXNwb25zZS5kZXNjcmlwdGlvbiA9IHJlc3BvbnNlLmRlc2NyaXB0aW9uO1xuICAgICAgfVxuXG4gICAgICBpZiAocmVzcG9uc2UuZXhhbXBsZXMpIHtcbiAgICAgICAgc3VjY2Vzc1Jlc3BvbnNlLmV4YW1wbGVzID0gcmVzcG9uc2UuZXhhbXBsZXM7XG4gICAgICB9XG5cbiAgICAgIGlmIChyZXNwb25zZS5oZWFkZXJzKSB7XG4gICAgICAgIHN1Y2Nlc3NSZXNwb25zZS5oZWFkZXJzID0gcmVzcG9uc2UuaGVhZGVycztcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnR5cGUgPSByZXNwb25zZTtcbiAgfVxuXG4gIGlmIChlcnJvcnMubGVuZ3RoID4gMCkge1xuICAgIGlmICh0aGlzLnJlc291cmNlICYmIHRoaXMucmVzb3VyY2UuYXBpICYmIHRoaXMucmVzb3VyY2UuYXBpLmZhaWwpIHtcbiAgICAgIHRoaXMucmVzb3VyY2UuYXBpLmZhaWwoZXJyb3JzKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuaXNEZWZhdWx0QXJyYXlJdGVtVmFsdWUgPSBmdW5jdGlvbih2YWx1ZSwgcGFyYW0pIHtcbiAgaWYgKHBhcmFtLmRlZmF1bHQgJiYgQXJyYXkuaXNBcnJheShwYXJhbS5kZWZhdWx0KSkge1xuICAgIHJldHVybiBwYXJhbS5kZWZhdWx0LmluZGV4T2YodmFsdWUpICE9PSAtMTtcbiAgfVxuICByZXR1cm4gdmFsdWUgPT09IHBhcmFtLmRlZmF1bHQ7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmdldFR5cGUgPSBmdW5jdGlvbiAocGFyYW0pIHtcbiAgdmFyIHR5cGUgPSBwYXJhbS50eXBlO1xuICB2YXIgZm9ybWF0ID0gcGFyYW0uZm9ybWF0O1xuICB2YXIgaXNBcnJheSA9IGZhbHNlO1xuICB2YXIgc3RyO1xuXG4gIGlmICh0eXBlID09PSAnaW50ZWdlcicgJiYgZm9ybWF0ID09PSAnaW50MzInKSB7XG4gICAgc3RyID0gJ2ludGVnZXInO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdpbnRlZ2VyJyAmJiBmb3JtYXQgPT09ICdpbnQ2NCcpIHtcbiAgICBzdHIgPSAnbG9uZyc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2ludGVnZXInKSB7XG4gICAgc3RyID0gJ2ludGVnZXInO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKGZvcm1hdCA9PT0gJ2RhdGUtdGltZScpIHtcbiAgICAgIHN0ciA9ICdkYXRlLXRpbWUnO1xuICAgIH0gZWxzZSBpZiAoZm9ybWF0ID09PSAnZGF0ZScpIHtcbiAgICAgIHN0ciA9ICdkYXRlJztcbiAgICB9IGVsc2Uge1xuICAgICAgc3RyID0gJ3N0cmluZyc7XG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdudW1iZXInICYmIGZvcm1hdCA9PT0gJ2Zsb2F0Jykge1xuICAgIHN0ciA9ICdmbG9hdCc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ251bWJlcicgJiYgZm9ybWF0ID09PSAnZG91YmxlJykge1xuICAgIHN0ciA9ICdkb3VibGUnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdudW1iZXInKSB7XG4gICAgc3RyID0gJ2RvdWJsZSc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgc3RyID0gJ2Jvb2xlYW4nO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdhcnJheScpIHtcbiAgICBpc0FycmF5ID0gdHJ1ZTtcblxuICAgIGlmIChwYXJhbS5pdGVtcykge1xuICAgICAgc3RyID0gdGhpcy5nZXRUeXBlKHBhcmFtLml0ZW1zKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2ZpbGUnKSB7XG4gICAgc3RyID0gJ2ZpbGUnO1xuICB9XG5cbiAgaWYgKHBhcmFtLiRyZWYpIHtcbiAgICBzdHIgPSBoZWxwZXJzLnNpbXBsZVJlZihwYXJhbS4kcmVmKTtcbiAgfVxuXG4gIHZhciBzY2hlbWEgPSBwYXJhbS5zY2hlbWE7XG5cbiAgaWYgKHNjaGVtYSkge1xuICAgIHZhciByZWYgPSBzY2hlbWEuJHJlZjtcblxuICAgIGlmIChyZWYpIHtcbiAgICAgIHJlZiA9IGhlbHBlcnMuc2ltcGxlUmVmKHJlZik7XG5cbiAgICAgIGlmIChpc0FycmF5KSB7XG4gICAgICAgIHJldHVybiBbIHJlZiBdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHJlZjtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSWYgaW5saW5lIHNjaGVtYSwgd2UgYWRkIGl0IG91ciBpbnRlcmFsIGhhc2ggLT4gd2hpY2ggZ2l2ZXMgdXMgaXQncyBJRCAoaW50KVxuICAgICAgaWYoc2NoZW1hLnR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFkZElubGluZU1vZGVsKHNjaGVtYSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5nZXRUeXBlKHNjaGVtYSk7XG4gICAgfVxuICB9XG4gIGlmIChpc0FycmF5KSB7XG4gICAgcmV0dXJuIFsgc3RyIF07XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHN0cjtcbiAgfVxufTtcblxuLyoqXG4gKiBhZGRzIGFuIGlubGluZSBzY2hlbWEgKG1vZGVsKSB0byBhIGhhc2gsIHdoZXJlIHdlIGNhbiByZWYgaXQgbGF0ZXJcbiAqIEBwYXJhbSB7b2JqZWN0fSBzY2hlbWEgYSBzY2hlbWFcbiAqIEByZXR1cm4ge251bWJlcn0gdGhlIElEIG9mIHRoZSBzY2hlbWEgYmVpbmcgYWRkZWQsIG9yIG51bGxcbiAqKi9cbk9wZXJhdGlvbi5wcm90b3R5cGUuYWRkSW5saW5lTW9kZWwgPSBmdW5jdGlvbiAoc2NoZW1hKSB7XG4gIHZhciBsZW4gPSB0aGlzLmlubGluZU1vZGVscy5sZW5ndGg7XG4gIHZhciBtb2RlbCA9IHRoaXMucmVzb2x2ZU1vZGVsKHNjaGVtYSwge30pO1xuICBpZihtb2RlbCkge1xuICAgIHRoaXMuaW5saW5lTW9kZWxzLnB1c2gobW9kZWwpO1xuICAgIHJldHVybiAnSW5saW5lIE1vZGVsICcrbGVuOyAvLyByZXR1cm4gc3RyaW5nIHJlZiBvZiB0aGUgaW5saW5lIG1vZGVsICh1c2VkIHdpdGggI2dldElubGluZU1vZGVsKVxuICB9XG4gIHJldHVybiBudWxsOyAvLyByZXBvcnQgZXJyb3JzP1xufTtcblxuLyoqXG4gKiBnZXRzIHRoZSBpbnRlcm5hbCByZWYgdG8gYW4gaW5saW5lIG1vZGVsXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5saW5lX3N0ciBhIHN0cmluZyByZWZlcmVuY2UgdG8gYW4gaW5saW5lIG1vZGVsXG4gKiBAcmV0dXJuIHtNb2RlbH0gdGhlIG1vZGVsIGJlaW5nIHJlZmVyZW5jZWQuIE9yIG51bGxcbiAqKi9cbk9wZXJhdGlvbi5wcm90b3R5cGUuZ2V0SW5saW5lTW9kZWwgPSBmdW5jdGlvbihpbmxpbmVTdHIpIHtcbiAgaWYoL15JbmxpbmUgTW9kZWwgXFxkKyQvLnRlc3QoaW5saW5lU3RyKSkge1xuICAgIHZhciBpZCA9IHBhcnNlSW50KGlubGluZVN0ci5zdWJzdHIoJ0lubGluZSBNb2RlbCcubGVuZ3RoKS50cmltKCksMTApOyAvL1xuICAgIHZhciBtb2RlbCA9IHRoaXMuaW5saW5lTW9kZWxzW2lkXTtcbiAgICByZXR1cm4gbW9kZWw7XG4gIH1cbiAgLy8gSSdtIHJldHVybmluZyBudWxsIGhlcmUsIHNob3VsZCBJIHJhdGhlciB0aHJvdyBhbiBlcnJvcj9cbiAgcmV0dXJuIG51bGw7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLnJlc29sdmVNb2RlbCA9IGZ1bmN0aW9uIChzY2hlbWEsIGRlZmluaXRpb25zKSB7XG4gIGlmICh0eXBlb2Ygc2NoZW1hLiRyZWYgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgdmFyIHJlZiA9IHNjaGVtYS4kcmVmO1xuXG4gICAgaWYgKHJlZi5pbmRleE9mKCcjL2RlZmluaXRpb25zLycpID09PSAwKSB7XG4gICAgICByZWYgPSByZWYuc3Vic3RyaW5nKCcjL2RlZmluaXRpb25zLycubGVuZ3RoKTtcbiAgICB9XG5cbiAgICBpZiAoZGVmaW5pdGlvbnNbcmVmXSkge1xuICAgICAgcmV0dXJuIG5ldyBNb2RlbChyZWYsIGRlZmluaXRpb25zW3JlZl0sIHRoaXMubW9kZWxzLCB0aGlzLnBhcmVudC5tb2RlbFByb3BlcnR5TWFjcm8pO1xuICAgIH1cbiAgLy8gc2NoZW1hIG11c3QgYXQgbGVhc3QgYmUgYW4gb2JqZWN0IHRvIGdldCByZXNvbHZlZCB0byBhbiBpbmxpbmUgTW9kZWxcbiAgfSBlbHNlIGlmIChzY2hlbWEgJiYgdHlwZW9mIHNjaGVtYSA9PT0gJ29iamVjdCcgJiZcbiAgICAgICAgICAgIChzY2hlbWEudHlwZSA9PT0gJ29iamVjdCcgfHwgXy5pc1VuZGVmaW5lZChzY2hlbWEudHlwZSkpKSB7XG4gICAgcmV0dXJuIG5ldyBNb2RlbCh1bmRlZmluZWQsIHNjaGVtYSwgdGhpcy5tb2RlbHMsIHRoaXMucGFyZW50Lm1vZGVsUHJvcGVydHlNYWNybyk7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuaGVscCA9IGZ1bmN0aW9uIChkb250UHJpbnQpIHtcbiAgdmFyIG91dCA9IHRoaXMubmlja25hbWUgKyAnOiAnICsgdGhpcy5zdW1tYXJ5ICsgJ1xcbic7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnBhcmFtZXRlcnMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcGFyYW0gPSB0aGlzLnBhcmFtZXRlcnNbaV07XG4gICAgdmFyIHR5cGVJbmZvID0gcGFyYW0uc2lnbmF0dXJlO1xuXG4gICAgb3V0ICs9ICdcXG4gICogJyArIHBhcmFtLm5hbWUgKyAnICgnICsgdHlwZUluZm8gKyAnKTogJyArIHBhcmFtLmRlc2NyaXB0aW9uO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBkb250UHJpbnQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgaGVscGVycy5sb2cob3V0KTtcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmdldE1vZGVsU2lnbmF0dXJlID0gZnVuY3Rpb24gKHR5cGUsIGRlZmluaXRpb25zKSB7XG4gIHZhciBpc1ByaW1pdGl2ZSwgbGlzdFR5cGU7XG5cbiAgaWYgKHR5cGUgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgIGxpc3RUeXBlID0gdHJ1ZTtcbiAgICB0eXBlID0gdHlwZVswXTtcbiAgfVxuXG4gIC8vIENvbnZlcnQgdW5kZWZpbmVkIHRvIHN0cmluZyBvZiAndW5kZWZpbmVkJ1xuICBpZiAodHlwZW9mIHR5cGUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgdHlwZSA9ICd1bmRlZmluZWQnO1xuICAgIGlzUHJpbWl0aXZlID0gdHJ1ZTtcblxuICB9IGVsc2UgaWYgKGRlZmluaXRpb25zW3R5cGVdKXtcbiAgICAvLyBhIG1vZGVsIGRlZiBleGlzdHM/XG4gICAgdHlwZSA9IGRlZmluaXRpb25zW3R5cGVdOyAvKiBNb2RlbCAqL1xuICAgIGlzUHJpbWl0aXZlID0gZmFsc2U7XG5cbiAgfSBlbHNlIGlmICh0aGlzLmdldElubGluZU1vZGVsKHR5cGUpKSB7XG4gICAgdHlwZSA9IHRoaXMuZ2V0SW5saW5lTW9kZWwodHlwZSk7IC8qIE1vZGVsICovXG4gICAgaXNQcmltaXRpdmUgPSBmYWxzZTtcblxuICB9IGVsc2Uge1xuICAgIC8vIFdlIGRlZmF1bHQgdG8gcHJpbWl0aXZlXG4gICAgaXNQcmltaXRpdmUgPSB0cnVlO1xuICB9XG5cbiAgaWYgKGlzUHJpbWl0aXZlKSB7XG4gICAgaWYgKGxpc3RUeXBlKSB7XG4gICAgICByZXR1cm4gJ0FycmF5WycgKyB0eXBlICsgJ10nO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdHlwZS50b1N0cmluZygpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAobGlzdFR5cGUpIHtcbiAgICAgIHJldHVybiAnQXJyYXlbJyArIHR5cGUuZ2V0TW9ja1NpZ25hdHVyZSgpICsgJ10nO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdHlwZS5nZXRNb2NrU2lnbmF0dXJlKCk7XG4gICAgfVxuICB9XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLnN1cHBvcnRIZWFkZXJQYXJhbXMgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB0cnVlO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5zdXBwb3J0ZWRTdWJtaXRNZXRob2RzID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5wYXJlbnQuc3VwcG9ydGVkU3VibWl0TWV0aG9kcztcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuZ2V0SGVhZGVyUGFyYW1zID0gZnVuY3Rpb24gKGFyZ3MpIHtcbiAgdmFyIGhlYWRlcnMgPSB0aGlzLnNldENvbnRlbnRUeXBlcyhhcmdzLCB7fSk7XG4gIHZhciBoZWFkZXJQYXJhbXNCeUxvd2VyQ2FzZSA9IHt9O1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5wYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcmFtID0gdGhpcy5wYXJhbWV0ZXJzW2ldO1xuXG4gICAgaWYgKHBhcmFtLmluID09PSAnaGVhZGVyJykge1xuICAgICAgaGVhZGVyUGFyYW1zQnlMb3dlckNhc2VbcGFyYW0ubmFtZS50b0xvd2VyQ2FzZSgpXSA9IHBhcmFtO1xuICAgIH1cbiAgfVxuXG4gIGZvciAodmFyIGFyZyBpbiBhcmdzKSB7XG4gICAgdmFyIGhlYWRlclBhcmFtID0gaGVhZGVyUGFyYW1zQnlMb3dlckNhc2VbYXJnLnRvTG93ZXJDYXNlKCldO1xuICAgIGlmICh0eXBlb2YgaGVhZGVyUGFyYW0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB2YXIgdmFsdWUgPSBhcmdzW2FyZ107XG5cbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICB2YWx1ZSA9IHZhbHVlLnRvU3RyaW5nKCk7XG4gICAgICB9XG5cbiAgICAgIGhlYWRlcnNbaGVhZGVyUGFyYW0ubmFtZV0gPSB2YWx1ZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gaGVhZGVycztcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUudXJsaWZ5ID0gZnVuY3Rpb24gKGFyZ3MsIG1hc2tQYXNzd29yZHMpIHtcbiAgdmFyIGZvcm1QYXJhbXMgPSB7fTtcbiAgdmFyIHJlcXVlc3RVcmwgPSB0aGlzLnBhdGgucmVwbGFjZSgvIy4qLywgJycpOyAvLyByZW1vdmUgVVJMIGZyYWdtZW50XG4gIHZhciBxdWVyeXN0cmluZyA9ICcnOyAvLyBncmFiIHBhcmFtcyBmcm9tIHRoZSBhcmdzLCBidWlsZCB0aGUgcXVlcnlzdHJpbmcgYWxvbmcgdGhlIHdheVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5wYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcmFtID0gdGhpcy5wYXJhbWV0ZXJzW2ldO1xuXG4gICAgaWYgKHR5cGVvZiBhcmdzW3BhcmFtLm5hbWVdICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdmFyIGlzUGFzc3dvcmQ7XG4gICAgICBpZihwYXJhbS50eXBlID09PSAnc3RyaW5nJyAmJiBwYXJhbS5mb3JtYXQgPT09ICdwYXNzd29yZCcgJiYgbWFza1Bhc3N3b3Jkcykge1xuICAgICAgICBpc1Bhc3N3b3JkID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHBhcmFtLmluID09PSAncGF0aCcpIHtcbiAgICAgICAgdmFyIHJlZyA9IG5ldyBSZWdFeHAoJ1xceycgKyBwYXJhbS5uYW1lICsgJ1xcfScsICdnaScpO1xuICAgICAgICB2YXIgdmFsdWUgPSBhcmdzW3BhcmFtLm5hbWVdO1xuXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgIHZhbHVlID0gdGhpcy5lbmNvZGVQYXRoQ29sbGVjdGlvbihwYXJhbS5jb2xsZWN0aW9uRm9ybWF0LCBwYXJhbS5uYW1lLCB2YWx1ZSwgaXNQYXNzd29yZCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFsdWUgPSB0aGlzLmVuY29kZVBhdGhQYXJhbSh2YWx1ZSwgaXNQYXNzd29yZCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXF1ZXN0VXJsID0gcmVxdWVzdFVybC5yZXBsYWNlKHJlZywgdmFsdWUpO1xuICAgICAgfSBlbHNlIGlmIChwYXJhbS5pbiA9PT0gJ3F1ZXJ5JyAmJiB0eXBlb2YgYXJnc1twYXJhbS5uYW1lXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgaWYgKHF1ZXJ5c3RyaW5nID09PSAnJyAmJiByZXF1ZXN0VXJsLmluZGV4T2YoJz8nKSA8IDApIHtcbiAgICAgICAgICBxdWVyeXN0cmluZyArPSAnPyc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcXVlcnlzdHJpbmcgKz0gJyYnO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBwYXJhbS5jb2xsZWN0aW9uRm9ybWF0ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIHZhciBxcCA9IGFyZ3NbcGFyYW0ubmFtZV07XG5cbiAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShxcCkpIHtcbiAgICAgICAgICAgIHF1ZXJ5c3RyaW5nICs9IHRoaXMuZW5jb2RlUXVlcnlDb2xsZWN0aW9uKHBhcmFtLmNvbGxlY3Rpb25Gb3JtYXQsIHBhcmFtLm5hbWUsIHFwLCBpc1Bhc3N3b3JkKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcXVlcnlzdHJpbmcgKz0gdGhpcy5lbmNvZGVRdWVyeUtleShwYXJhbS5uYW1lKSArICc9JyArIHRoaXMuZW5jb2RlUXVlcnlQYXJhbShhcmdzW3BhcmFtLm5hbWVdLCBpc1Bhc3N3b3JkKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcXVlcnlzdHJpbmcgKz0gdGhpcy5lbmNvZGVRdWVyeUtleShwYXJhbS5uYW1lKSArICc9JyArIHRoaXMuZW5jb2RlUXVlcnlQYXJhbShhcmdzW3BhcmFtLm5hbWVdLCBpc1Bhc3N3b3JkKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChwYXJhbS5pbiA9PT0gJ2Zvcm1EYXRhJykge1xuICAgICAgICBmb3JtUGFyYW1zW3BhcmFtLm5hbWVdID0gYXJnc1twYXJhbS5uYW1lXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgdmFyIHVybCA9IHRoaXMuc2NoZW1lICsgJzovLycgKyB0aGlzLmhvc3Q7XG5cbiAgaWYgKHRoaXMuYmFzZVBhdGggIT09ICcvJykge1xuICAgIHVybCArPSB0aGlzLmJhc2VQYXRoO1xuICB9XG4gIHJldHVybiB1cmwgKyByZXF1ZXN0VXJsICsgcXVlcnlzdHJpbmc7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmdldE1pc3NpbmdQYXJhbXMgPSBmdW5jdGlvbiAoYXJncykge1xuICB2YXIgbWlzc2luZ1BhcmFtcyA9IFtdOyAvLyBjaGVjayByZXF1aXJlZCBwYXJhbXMsIHRyYWNrIHRoZSBvbmVzIHRoYXQgYXJlIG1pc3NpbmdcbiAgdmFyIGk7XG5cbiAgZm9yIChpID0gMDsgaSA8IHRoaXMucGFyYW1ldGVycy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwYXJhbSA9IHRoaXMucGFyYW1ldGVyc1tpXTtcblxuICAgIGlmIChwYXJhbS5yZXF1aXJlZCA9PT0gdHJ1ZSkge1xuICAgICAgaWYgKHR5cGVvZiBhcmdzW3BhcmFtLm5hbWVdID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICBtaXNzaW5nUGFyYW1zID0gcGFyYW0ubmFtZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbWlzc2luZ1BhcmFtcztcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuZ2V0Qm9keSA9IGZ1bmN0aW9uIChoZWFkZXJzLCBhcmdzLCBvcHRzKSB7XG4gIHZhciBmb3JtUGFyYW1zID0ge30sIGhhc0Zvcm1QYXJhbXMsIHBhcmFtLCBib2R5LCBrZXksIHZhbHVlLCBoYXNCb2R5ID0gZmFsc2U7XG5cbiAgLy8gbG9vayBhdCBlYWNoIHBhcmFtIGFuZCBwdXQgZm9ybSBwYXJhbXMgaW4gYW4gb2JqZWN0XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5wYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgcGFyYW0gPSB0aGlzLnBhcmFtZXRlcnNbaV07XG4gICAgaWYgKHR5cGVvZiBhcmdzW3BhcmFtLm5hbWVdICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdmFyIGlzUGFzc3dvcmQ7XG4gICAgICBpZihwYXJhbS50eXBlID09PSAnc3RyaW5nJyAmJiBwYXJhbS5mb3JtYXQgPT09ICdwYXNzd29yZCcpIHtcbiAgICAgICAgaXNQYXNzd29yZCA9ICdwYXNzd29yZCc7XG4gICAgICB9XG4gICAgICBpZiAocGFyYW0uaW4gPT09ICdib2R5Jykge1xuICAgICAgICBib2R5ID0gYXJnc1twYXJhbS5uYW1lXTtcbiAgICAgIH0gZWxzZSBpZiAocGFyYW0uaW4gPT09ICdmb3JtRGF0YScpIHtcbiAgICAgICAgZm9ybVBhcmFtc1twYXJhbS5uYW1lXSA9IHtcbiAgICAgICAgICBwYXJhbTogcGFyYW0sXG4gICAgICAgICAgdmFsdWU6IGFyZ3NbcGFyYW0ubmFtZV0sXG4gICAgICAgICAgcGFzc3dvcmQ6IGlzUGFzc3dvcmRcbiAgICAgICAgfTtcbiAgICAgICAgaGFzRm9ybVBhcmFtcyA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgaWYocGFyYW0uaW4gPT09ICdib2R5Jykge1xuICAgICAgICBoYXNCb2R5ID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBpZiBib2R5IGlzIG51bGwgYW5kIGhhc0JvZHkgaXMgdHJ1ZSwgQU5EIGEgSlNPTiBib2R5IGlzIHJlcXVlc3RlZCwgc2VuZCBlbXB0eSB7fVxuICBpZihoYXNCb2R5ICYmIHR5cGVvZiBib2R5ID09PSAndW5kZWZpbmVkJykge1xuICAgIHZhciBjb250ZW50VHlwZSA9IGhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddO1xuICAgIGlmKGNvbnRlbnRUeXBlICYmIGNvbnRlbnRUeXBlLmluZGV4T2YoJ2FwcGxpY2F0aW9uL2pzb24nKSA9PT0gMCkge1xuICAgICAgYm9keSA9ICd7fSc7XG4gICAgfVxuICB9XG5cbiAgdmFyIGlzTXVsdGlQYXJ0ID0gZmFsc2U7XG4gIGlmKGhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddICYmIGhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddLmluZGV4T2YoJ211bHRpcGFydC9mb3JtLWRhdGEnKSA+PSAwKSB7XG4gICAgaXNNdWx0aVBhcnQgPSB0cnVlO1xuICB9XG5cbiAgLy8gaGFuZGxlIGZvcm0gcGFyYW1zXG4gIGlmIChoYXNGb3JtUGFyYW1zICYmICFpc011bHRpUGFydCkge1xuICAgIHZhciBlbmNvZGVkID0gJyc7XG5cbiAgICBmb3IgKGtleSBpbiBmb3JtUGFyYW1zKSB7XG4gICAgICBwYXJhbSA9IGZvcm1QYXJhbXNba2V5XS5wYXJhbTtcbiAgICAgIHZhbHVlID0gZm9ybVBhcmFtc1trZXldLnZhbHVlO1xuICAgICAgdmFyIHBhc3N3b3JkO1xuXG4gICAgICBpZihvcHRzICYmIG9wdHMubWFza1Bhc3N3b3Jkcykge1xuICAgICAgICBwYXNzd29yZCA9IGZvcm1QYXJhbXNba2V5XS5wYXNzd29yZDtcbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgaWYgKGVuY29kZWQgIT09ICcnKSB7XG4gICAgICAgICAgICBlbmNvZGVkICs9ICcmJztcbiAgICAgICAgICB9XG4gICAgICAgICAgZW5jb2RlZCArPSB0aGlzLmVuY29kZVF1ZXJ5Q29sbGVjdGlvbihwYXJhbS5jb2xsZWN0aW9uRm9ybWF0LCBrZXksIHZhbHVlLCBwYXNzd29yZCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgaWYgKGVuY29kZWQgIT09ICcnKSB7XG4gICAgICAgICAgICBlbmNvZGVkICs9ICcmJztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBlbmNvZGVkICs9IGVuY29kZVVSSUNvbXBvbmVudChrZXkpICsgJz0nICsgbWFzayhlbmNvZGVVUklDb21wb25lbnQodmFsdWUpLCBwYXNzd29yZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBib2R5ID0gZW5jb2RlZDtcbiAgfSBlbHNlIGlmIChpc011bHRpUGFydCkge1xuICAgIHZhciBib2R5UGFyYW07XG4gICAgaWYgKHR5cGVvZiBGb3JtRGF0YSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgYm9keVBhcmFtID0gbmV3IEZvcm1EYXRhKCk7XG5cbiAgICAgIGJvZHlQYXJhbS50eXBlID0gJ2Zvcm1EYXRhJztcblxuICAgICAgZm9yIChrZXkgaW4gZm9ybVBhcmFtcykge1xuICAgICAgICBwYXJhbSA9IGZvcm1QYXJhbXNba2V5XS5wYXJhbTtcbiAgICAgICAgdmFsdWUgPSBhcmdzW2tleV07XG5cbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICBpZih7fS50b1N0cmluZy5hcHBseSh2YWx1ZSkgPT09ICdbb2JqZWN0IEZpbGVdJykge1xuICAgICAgICAgICAgYm9keVBhcmFtLmFwcGVuZChrZXksIHZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSBpZiAodmFsdWUudHlwZSA9PT0gJ2ZpbGUnICYmIHZhbHVlLnZhbHVlKSB7XG4gICAgICAgICAgICBib2R5UGFyYW0uYXBwZW5kKGtleSwgdmFsdWUudmFsdWUpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgaWYocGFyYW0uY29sbGVjdGlvbkZvcm1hdCA9PT0gJ211bHRpJykge1xuICAgICAgICAgICAgICAgIGJvZHlQYXJhbS5kZWxldGUoa2V5KTtcbiAgICAgICAgICAgICAgICBmb3IodmFyIHYgaW4gdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgIGJvZHlQYXJhbS5hcHBlbmQoa2V5LCB2YWx1ZVt2XSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGJvZHlQYXJhbS5hcHBlbmQoa2V5LCB0aGlzLmVuY29kZVF1ZXJ5Q29sbGVjdGlvbihwYXJhbS5jb2xsZWN0aW9uRm9ybWF0LCBrZXksIHZhbHVlKS5zcGxpdCgnPScpLnNsaWNlKDEpLmpvaW4oJz0nKSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICBib2R5UGFyYW0uYXBwZW5kKGtleSwgdmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgYm9keSA9IGJvZHlQYXJhbTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBib2R5UGFyYW0gPSB7fTtcbiAgICAgIGZvciAoa2V5IGluIGZvcm1QYXJhbXMpIHtcbiAgICAgICAgdmFsdWUgPSBhcmdzW2tleV07XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgIHZhciBkZWxpbWV0ZXI7XG4gICAgICAgICAgdmFyIGZvcm1hdCA9IHBhcmFtLmNvbGxlY3Rpb25Gb3JtYXQgfHwgJ211bHRpJztcbiAgICAgICAgICBpZihmb3JtYXQgPT09ICdzc3YnKSB7XG4gICAgICAgICAgICBkZWxpbWV0ZXIgPSAnICc7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2UgaWYoZm9ybWF0ID09PSAncGlwZXMnKSB7XG4gICAgICAgICAgICBkZWxpbWV0ZXIgPSAnfCc7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2UgaWYoZm9ybWF0ID09PSAndHN2Jykge1xuICAgICAgICAgICAgZGVsaW1ldGVyID0gJ1xcdCc7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2UgaWYoZm9ybWF0ID09PSAnbXVsdGknKSB7XG4gICAgICAgICAgICBib2R5UGFyYW1ba2V5XSA9IHZhbHVlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZGVsaW1ldGVyID0gJywnO1xuICAgICAgICAgIH1cbiAgICAgICAgICB2YXIgZGF0YTtcbiAgICAgICAgICB2YWx1ZS5mb3JFYWNoKGZ1bmN0aW9uKHYpIHtcbiAgICAgICAgICAgIGlmKGRhdGEpIHtcbiAgICAgICAgICAgICAgZGF0YSArPSBkZWxpbWV0ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgZGF0YSA9ICcnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGF0YSArPSB2O1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIGJvZHlQYXJhbVtrZXldID0gZGF0YTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBib2R5UGFyYW1ba2V5XSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBib2R5ID0gYm9keVBhcmFtO1xuICAgIH1cbiAgICBoZWFkZXJzWydDb250ZW50LVR5cGUnXSA9ICdtdWx0aXBhcnQvZm9ybS1kYXRhJztcbiAgfVxuXG4gIHJldHVybiBib2R5O1xufTtcblxuLyoqXG4gKiBnZXRzIHNhbXBsZSByZXNwb25zZSBmb3IgYSBzaW5nbGUgb3BlcmF0aW9uXG4gKiovXG5PcGVyYXRpb24ucHJvdG90eXBlLmdldE1vZGVsU2FtcGxlSlNPTiA9IGZ1bmN0aW9uICh0eXBlLCBtb2RlbHMpIHtcbiAgdmFyIGxpc3RUeXBlLCBzYW1wbGVKc29uLCBpbm5lclR5cGU7XG4gIG1vZGVscyA9IG1vZGVscyB8fCB7fTtcblxuICBsaXN0VHlwZSA9ICh0eXBlIGluc3RhbmNlb2YgQXJyYXkpO1xuICBpbm5lclR5cGUgPSBsaXN0VHlwZSA/IHR5cGVbMF0gOiB0eXBlO1xuXG4gIGlmKG1vZGVsc1tpbm5lclR5cGVdKSB7XG4gICAgc2FtcGxlSnNvbiA9IG1vZGVsc1tpbm5lclR5cGVdLmNyZWF0ZUpTT05TYW1wbGUoKTtcbiAgfSBlbHNlIGlmICh0aGlzLmdldElubGluZU1vZGVsKGlubmVyVHlwZSkpe1xuICAgIHNhbXBsZUpzb24gPSB0aGlzLmdldElubGluZU1vZGVsKGlubmVyVHlwZSkuY3JlYXRlSlNPTlNhbXBsZSgpOyAvLyBtYXkgcmV0dXJuIG51bGwsIGlmIHR5cGUgaXNuJ3QgY29ycmVjdFxuICB9XG5cblxuICBpZiAoc2FtcGxlSnNvbikge1xuICAgIHNhbXBsZUpzb24gPSBsaXN0VHlwZSA/IFtzYW1wbGVKc29uXSA6IHNhbXBsZUpzb247XG5cbiAgICBpZiAodHlwZW9mIHNhbXBsZUpzb24gPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gc2FtcGxlSnNvbjtcbiAgICB9IGVsc2UgaWYgKF8uaXNPYmplY3Qoc2FtcGxlSnNvbikpIHtcbiAgICAgIHZhciB0ID0gc2FtcGxlSnNvbjtcblxuICAgICAgaWYgKHNhbXBsZUpzb24gaW5zdGFuY2VvZiBBcnJheSAmJiBzYW1wbGVKc29uLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdCA9IHNhbXBsZUpzb25bMF07XG4gICAgICB9XG5cbiAgICAgIGlmICh0Lm5vZGVOYW1lICYmIHR5cGVvZiB0ID09PSAnTm9kZScpIHtcbiAgICAgICAgdmFyIHhtbFN0cmluZyA9IG5ldyBYTUxTZXJpYWxpemVyKCkuc2VyaWFsaXplVG9TdHJpbmcodCk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0WG1sKHhtbFN0cmluZyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoc2FtcGxlSnNvbiwgbnVsbCwgMik7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBzYW1wbGVKc29uO1xuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBsZWdhY3kgYmluZGluZ1xuICoqL1xuT3BlcmF0aW9uLnByb3RvdHlwZS5kbyA9IGZ1bmN0aW9uIChhcmdzLCBvcHRzLCBjYWxsYmFjaywgZXJyb3IsIHBhcmVudCkge1xuICByZXR1cm4gdGhpcy5leGVjdXRlKGFyZ3MsIG9wdHMsIGNhbGxiYWNrLCBlcnJvciwgcGFyZW50KTtcbn07XG5cbi8qKlxuICogZXhlY3V0ZXMgYW4gb3BlcmF0aW9uXG4gKiovXG5PcGVyYXRpb24ucHJvdG90eXBlLmV4ZWN1dGUgPSBmdW5jdGlvbiAoYXJnMSwgYXJnMiwgYXJnMywgYXJnNCwgcGFyZW50KSB7XG4gIHZhciBhcmdzID0gYXJnMSB8fCB7fTtcbiAgdmFyIG9wdHMgPSB7fSwgc3VjY2VzcywgZXJyb3IsIGRlZmVycmVkLCB0aW1lb3V0O1xuXG4gIGlmIChfLmlzT2JqZWN0KGFyZzIpKSB7XG4gICAgb3B0cyA9IGFyZzI7XG4gICAgc3VjY2VzcyA9IGFyZzM7XG4gICAgZXJyb3IgPSBhcmc0O1xuICB9XG5cbiAgdGltZW91dCA9IHR5cGVvZiBvcHRzLnRpbWVvdXQgIT09ICd1bmRlZmluZWQnID8gb3B0cy50aW1lb3V0IDogdGhpcy50aW1lb3V0O1xuXG4gIGlmKHRoaXMuY2xpZW50KSB7XG4gICAgb3B0cy5jbGllbnQgPSB0aGlzLmNsaWVudDtcbiAgfVxuXG4gIGlmKHRoaXMucmVxdWVzdEFnZW50KSB7XG4gICAgb3B0cy5yZXF1ZXN0QWdlbnQgPSB0aGlzLnJlcXVlc3RBZ2VudDtcbiAgfVxuXG4gIC8vIGFkZCB0aGUgcmVxdWVzdCBpbnRlcmNlcHRvciBmcm9tIHBhcmVudCwgaWYgbm9uZSBzZW50IGZyb20gY2xpZW50XG4gIGlmKCFvcHRzLnJlcXVlc3RJbnRlcmNlcHRvciAmJiB0aGlzLnJlcXVlc3RJbnRlcmNlcHRvciApIHtcbiAgICBvcHRzLnJlcXVlc3RJbnRlcmNlcHRvciA9IHRoaXMucmVxdWVzdEludGVyY2VwdG9yIDtcbiAgfVxuXG4gIGlmKCFvcHRzLnJlc3BvbnNlSW50ZXJjZXB0b3IgJiYgdGhpcy5yZXNwb25zZUludGVyY2VwdG9yKSB7XG4gICAgb3B0cy5yZXNwb25zZUludGVyY2VwdG9yID0gdGhpcy5yZXNwb25zZUludGVyY2VwdG9yO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBhcmcyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgc3VjY2VzcyA9IGFyZzI7XG4gICAgZXJyb3IgPSBhcmczO1xuICB9XG5cbiAgaWYgKHRoaXMucGFyZW50LnVzZVByb21pc2UpIHtcbiAgICBkZWZlcnJlZCA9IFEuZGVmZXIoKTtcbiAgfSBlbHNlIHtcbiAgICBzdWNjZXNzID0gKHN1Y2Nlc3MgfHwgdGhpcy5wYXJlbnQuZGVmYXVsdFN1Y2Nlc3NDYWxsYmFjayB8fCBoZWxwZXJzLmxvZyk7XG4gICAgZXJyb3IgPSAoZXJyb3IgfHwgdGhpcy5wYXJlbnQuZGVmYXVsdEVycm9yQ2FsbGJhY2sgfHwgaGVscGVycy5sb2cpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBvcHRzLnVzZUpRdWVyeSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBvcHRzLnVzZUpRdWVyeSA9IHRoaXMudXNlSlF1ZXJ5O1xuICB9XG5cbiAgaWYgKHR5cGVvZiBvcHRzLmpxdWVyeUFqYXhDYWNoZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBvcHRzLmpxdWVyeUFqYXhDYWNoZSA9IHRoaXMuanF1ZXJ5QWpheENhY2hlO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBvcHRzLmVuYWJsZUNvb2tpZXMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgb3B0cy5lbmFibGVDb29raWVzID0gdGhpcy5lbmFibGVDb29raWVzO1xuICB9XG5cbiAgdmFyIG1pc3NpbmdQYXJhbXMgPSB0aGlzLmdldE1pc3NpbmdQYXJhbXMoYXJncyk7XG5cbiAgaWYgKG1pc3NpbmdQYXJhbXMubGVuZ3RoID4gMCkge1xuICAgIHZhciBtZXNzYWdlID0gJ21pc3NpbmcgcmVxdWlyZWQgcGFyYW1zOiAnICsgbWlzc2luZ1BhcmFtcztcblxuICAgIGhlbHBlcnMuZmFpbChtZXNzYWdlKTtcblxuICAgIGlmICh0aGlzLnBhcmVudC51c2VQcm9taXNlKSB7XG4gICAgICBkZWZlcnJlZC5yZWplY3QobWVzc2FnZSk7XG4gICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXJyb3IobWVzc2FnZSwgcGFyZW50KTtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gIH1cblxuICB2YXIgYWxsSGVhZGVycyA9IHRoaXMuZ2V0SGVhZGVyUGFyYW1zKGFyZ3MpO1xuICB2YXIgY29udGVudFR5cGVIZWFkZXJzID0gdGhpcy5zZXRDb250ZW50VHlwZXMoYXJncywgb3B0cyk7XG4gIHZhciBoZWFkZXJzID0ge30sIGF0dHJuYW1lO1xuXG4gIGZvciAoYXR0cm5hbWUgaW4gYWxsSGVhZGVycykgeyBoZWFkZXJzW2F0dHJuYW1lXSA9IGFsbEhlYWRlcnNbYXR0cm5hbWVdOyB9XG4gIGZvciAoYXR0cm5hbWUgaW4gY29udGVudFR5cGVIZWFkZXJzKSB7IGhlYWRlcnNbYXR0cm5hbWVdID0gY29udGVudFR5cGVIZWFkZXJzW2F0dHJuYW1lXTsgfVxuXG4gIHZhciBib2R5ID0gdGhpcy5nZXRCb2R5KGNvbnRlbnRUeXBlSGVhZGVycywgYXJncywgb3B0cyk7XG4gIHZhciB1cmwgPSB0aGlzLnVybGlmeShhcmdzLCBvcHRzLm1hc2tQYXNzd29yZHMpO1xuXG4gIGlmKHVybC5pbmRleE9mKCcue2Zvcm1hdH0nKSA+IDApIHtcbiAgICBpZihoZWFkZXJzKSB7XG4gICAgICB2YXIgZm9ybWF0ID0gaGVhZGVycy5BY2NlcHQgfHwgaGVhZGVycy5hY2NlcHQ7XG4gICAgICBpZihmb3JtYXQgJiYgZm9ybWF0LmluZGV4T2YoJ2pzb24nKSA+IDApIHtcbiAgICAgICAgdXJsID0gdXJsLnJlcGxhY2UoJy57Zm9ybWF0fScsICcuanNvbicpO1xuICAgICAgfVxuICAgICAgZWxzZSBpZihmb3JtYXQgJiYgZm9ybWF0LmluZGV4T2YoJ3htbCcpID4gMCkge1xuICAgICAgICB1cmwgPSB1cmwucmVwbGFjZSgnLntmb3JtYXR9JywgJy54bWwnKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB2YXIgb2JqID0ge1xuICAgIHVybDogdXJsLFxuICAgIG1ldGhvZDogdGhpcy5tZXRob2QudG9VcHBlckNhc2UoKSxcbiAgICBib2R5OiBib2R5LFxuICAgIGVuYWJsZUNvb2tpZXM6IG9wdHMuZW5hYmxlQ29va2llcyxcbiAgICB1c2VKUXVlcnk6IG9wdHMudXNlSlF1ZXJ5LFxuICAgIGpxdWVyeUFqYXhDYWNoZTogb3B0cy5qcXVlcnlBamF4Q2FjaGUsXG4gICAgZGVmZXJyZWQ6IGRlZmVycmVkLFxuICAgIGhlYWRlcnM6IGhlYWRlcnMsXG4gICAgY2xpZW50QXV0aG9yaXphdGlvbnM6IG9wdHMuY2xpZW50QXV0aG9yaXphdGlvbnMsXG4gICAgb3BlcmF0aW9uOiB0aGlzLFxuICAgIGNvbm5lY3Rpb25BZ2VudDogdGhpcy5jb25uZWN0aW9uQWdlbnQsXG4gICAgb246IHtcbiAgICAgIHJlc3BvbnNlOiBmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgICAgaWYgKGRlZmVycmVkKSB7XG4gICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZShyZXNwb25zZSk7XG4gICAgICAgICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHN1Y2Nlc3MocmVzcG9uc2UsIHBhcmVudCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBlcnJvcjogZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgIGlmIChkZWZlcnJlZCkge1xuICAgICAgICAgIGRlZmVycmVkLnJlamVjdChyZXNwb25zZSk7XG4gICAgICAgICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIGVycm9yKHJlc3BvbnNlLCBwYXJlbnQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIGlmICh0aW1lb3V0KSB7XG4gICAgb2JqLnRpbWVvdXQgPSB0aW1lb3V0O1xuICB9XG5cbiAgdGhpcy5jbGllbnRBdXRob3JpemF0aW9ucy5hcHBseShvYmosIHRoaXMub3BlcmF0aW9uLnNlY3VyaXR5KTtcbiAgaWYgKG9wdHMubW9jayA9PT0gdHJ1ZSkge1xuICAgIHJldHVybiBvYmo7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG5ldyBTd2FnZ2VySHR0cCgpLmV4ZWN1dGUob2JqLCBvcHRzKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gaXRlbUJ5UHJpb3JpdHkoY29sLCBpdGVtUHJpb3JpdHkpIHtcblxuICAvLyBObyBwcmlvcml0aWVzPyByZXR1cm4gZmlyc3QuLi5cbiAgaWYoXy5pc0VtcHR5KGl0ZW1Qcmlvcml0eSkpIHtcbiAgICByZXR1cm4gY29sWzBdO1xuICB9XG5cbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGl0ZW1Qcmlvcml0eS5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGlmKGNvbC5pbmRleE9mKGl0ZW1Qcmlvcml0eVtpXSkgPiAtMSkge1xuICAgICAgcmV0dXJuIGl0ZW1Qcmlvcml0eVtpXTtcbiAgICB9XG4gIH1cblxuICAvLyBPdGhlcndpc2UgcmV0dXJuIGZpcnN0XG4gIHJldHVybiBjb2xbMF07XG59XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuc2V0Q29udGVudFR5cGVzID0gZnVuY3Rpb24gKGFyZ3MsIG9wdHMpIHtcbiAgLy8gZGVmYXVsdCB0eXBlXG4gIHZhciBhbGxEZWZpbmVkUGFyYW1zID0gdGhpcy5wYXJhbWV0ZXJzO1xuICB2YXIgYm9keTtcbiAgdmFyIGNvbnN1bWVzID0gYXJncy5wYXJhbWV0ZXJDb250ZW50VHlwZSB8fCBpdGVtQnlQcmlvcml0eSh0aGlzLmNvbnN1bWVzLCBbJ2FwcGxpY2F0aW9uL2pzb24nLCAnYXBwbGljYXRpb24veWFtbCddKTtcbiAgdmFyIGFjY2VwdHMgPSBvcHRzLnJlc3BvbnNlQ29udGVudFR5cGUgfHwgaXRlbUJ5UHJpb3JpdHkodGhpcy5wcm9kdWNlcywgWydhcHBsaWNhdGlvbi9qc29uJywgJ2FwcGxpY2F0aW9uL3lhbWwnXSk7XG4gIHZhciBkZWZpbmVkRmlsZVBhcmFtcyA9IFtdO1xuICB2YXIgZGVmaW5lZEZvcm1QYXJhbXMgPSBbXTtcbiAgdmFyIGhlYWRlcnMgPSB7fTtcbiAgdmFyIGk7XG5cbiAgLy8gZ2V0IHBhcmFtcyBmcm9tIHRoZSBvcGVyYXRpb24gYW5kIHNldCB0aGVtIGluIGRlZmluZWRGaWxlUGFyYW1zLCBkZWZpbmVkRm9ybVBhcmFtcywgaGVhZGVyc1xuICBmb3IgKGkgPSAwOyBpIDwgYWxsRGVmaW5lZFBhcmFtcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwYXJhbSA9IGFsbERlZmluZWRQYXJhbXNbaV07XG5cbiAgICBpZiAocGFyYW0uaW4gPT09ICdmb3JtRGF0YScpIHtcbiAgICAgIGlmIChwYXJhbS50eXBlID09PSAnZmlsZScpIHtcbiAgICAgICAgZGVmaW5lZEZpbGVQYXJhbXMucHVzaChwYXJhbSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkZWZpbmVkRm9ybVBhcmFtcy5wdXNoKHBhcmFtKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHBhcmFtLmluID09PSAnaGVhZGVyJyAmJiBvcHRzKSB7XG4gICAgICB2YXIga2V5ID0gcGFyYW0ubmFtZTtcbiAgICAgIHZhciBoZWFkZXJWYWx1ZSA9IG9wdHNbcGFyYW0ubmFtZV07XG5cbiAgICAgIGlmICh0eXBlb2Ygb3B0c1twYXJhbS5uYW1lXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgaGVhZGVyc1trZXldID0gaGVhZGVyVmFsdWU7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChwYXJhbS5pbiA9PT0gJ2JvZHknICYmIHR5cGVvZiBhcmdzW3BhcmFtLm5hbWVdICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgYm9keSA9IGFyZ3NbcGFyYW0ubmFtZV07XG4gICAgfVxuICB9XG5cbiAgLy8gaWYgdGhlcmUncyBhIGJvZHksIG5lZWQgdG8gc2V0IHRoZSBjb25zdW1lcyBoZWFkZXIgdmlhIHJlcXVlc3RDb250ZW50VHlwZVxuICB2YXIgaGFzQm9keSA9IGJvZHkgfHwgZGVmaW5lZEZpbGVQYXJhbXMubGVuZ3RoIHx8IGRlZmluZWRGb3JtUGFyYW1zLmxlbmd0aDtcbiAgaWYgKHRoaXMubWV0aG9kID09PSAncG9zdCcgfHwgdGhpcy5tZXRob2QgPT09ICdwdXQnIHx8IHRoaXMubWV0aG9kID09PSAncGF0Y2gnIHx8XG4gICAgICAoKHRoaXMubWV0aG9kID09PSAnZGVsZXRlJyB8fCB0aGlzLm1ldGhvZCA9PT0gJ2dldCcpICYmIGhhc0JvZHkpKSB7XG4gICAgaWYgKG9wdHMucmVxdWVzdENvbnRlbnRUeXBlKSB7XG4gICAgICBjb25zdW1lcyA9IG9wdHMucmVxdWVzdENvbnRlbnRUeXBlO1xuICAgIH1cbiAgICAvLyBpZiBhbnkgZm9ybSBwYXJhbXMsIGNvbnRlbnQgdHlwZSBtdXN0IGJlIHNldFxuICAgIGlmIChkZWZpbmVkRm9ybVBhcmFtcy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdW1lcyA9IHVuZGVmaW5lZDtcbiAgICAgIGlmIChvcHRzLnJlcXVlc3RDb250ZW50VHlwZSkgeyAgICAgICAgICAgICAvLyBvdmVycmlkZSBpZiBzZXRcbiAgICAgICAgY29uc3VtZXMgPSBvcHRzLnJlcXVlc3RDb250ZW50VHlwZTtcbiAgICAgIH0gZWxzZSBpZiAoZGVmaW5lZEZpbGVQYXJhbXMubGVuZ3RoID4gMCkgeyAvLyBpZiBhIGZpbGUsIG11c3QgYmUgbXVsdGlwYXJ0L2Zvcm0tZGF0YVxuICAgICAgICBjb25zdW1lcyA9ICdtdWx0aXBhcnQvZm9ybS1kYXRhJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0aGlzLmNvbnN1bWVzICYmIHRoaXMuY29uc3VtZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIC8vIHVzZSB0aGUgY29uc3VtZXMgc2V0dGluZ1xuICAgICAgICAgIGZvcih2YXIgYyBpbiB0aGlzLmNvbnN1bWVzKSB7XG4gICAgICAgICAgICB2YXIgY2hrID0gdGhpcy5jb25zdW1lc1tjXTtcbiAgICAgICAgICAgIGlmKGNoay5pbmRleE9mKCdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnKSA9PT0gMCB8fCBjaGsuaW5kZXhPZignbXVsdGlwYXJ0L2Zvcm0tZGF0YScpID09PSAwKSB7XG4gICAgICAgICAgICAgIGNvbnN1bWVzID0gY2hrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYodHlwZW9mIGNvbnN1bWVzID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAvLyBkZWZhdWx0IHRvIHgtd3d3LWZyb20tdXJsZW5jb2RlZFxuICAgICAgICBjb25zdW1lcyA9ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBlbHNlIHtcbiAgICBjb25zdW1lcyA9IG51bGw7XG4gIH1cblxuICBpZiAoY29uc3VtZXMgJiYgdGhpcy5jb25zdW1lcykge1xuICAgIGlmICh0aGlzLmNvbnN1bWVzLmluZGV4T2YoY29uc3VtZXMpID09PSAtMSkge1xuICAgICAgaGVscGVycy5sb2coJ3NlcnZlciBkb2VzblxcJ3QgY29uc3VtZSAnICsgY29uc3VtZXMgKyAnLCB0cnkgJyArIEpTT04uc3RyaW5naWZ5KHRoaXMuY29uc3VtZXMpKTtcbiAgICB9XG4gIH1cblxuICBpZiAoIXRoaXMubWF0Y2hlc0FjY2VwdChhY2NlcHRzKSkge1xuICAgIGhlbHBlcnMubG9nKCdzZXJ2ZXIgY2FuXFwndCBwcm9kdWNlICcgKyBhY2NlcHRzKTtcbiAgfVxuXG4gIGlmICgoY29uc3VtZXMgJiYgYm9keSAhPT0gJycpIHx8IChjb25zdW1lcyA9PT0gJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcpKSB7XG4gICAgaGVhZGVyc1snQ29udGVudC1UeXBlJ10gPSBjb25zdW1lcztcbiAgfVxuICBlbHNlIGlmKHRoaXMuY29uc3VtZXMgJiYgdGhpcy5jb25zdW1lcy5sZW5ndGggPiAwICYmIHRoaXMuY29uc3VtZXNbMF0gPT09ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnKSB7XG4gICAgaGVhZGVyc1snQ29udGVudC1UeXBlJ10gPSB0aGlzLmNvbnN1bWVzWzBdO1xuICB9XG5cbiAgaWYgKGFjY2VwdHMpIHtcbiAgICBoZWFkZXJzLkFjY2VwdCA9IGFjY2VwdHM7XG4gIH1cblxuICByZXR1cm4gaGVhZGVycztcbn07XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSByZXF1ZXN0IGFjY2VwdHMgaGVhZGVyIG1hdGNoZXMgYW55dGhpbmcgaW4gdGhpcy5wcm9kdWNlcy5cbiAqICBJZiB0aGlzLnByb2R1Y2VzIGNvbnRhaW5zICogLyAqLCBpZ25vcmUgdGhlIGFjY2VwdCBoZWFkZXIuXG4gKiBAcGFyYW0ge3N0cmluZz19IGFjY2VwdHMgVGhlIGNsaWVudCByZXF1ZXN0IGFjY2VwdCBoZWFkZXIuXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5PcGVyYXRpb24ucHJvdG90eXBlLm1hdGNoZXNBY2NlcHQgPSBmdW5jdGlvbihhY2NlcHRzKSB7XG4gIC8vIG5vIGFjY2VwdHMgb3IgcHJvZHVjZXMsIG5vIHByb2JsZW0hXG4gIGlmICghYWNjZXB0cyB8fCAhdGhpcy5wcm9kdWNlcykge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiB0aGlzLnByb2R1Y2VzLmluZGV4T2YoYWNjZXB0cykgIT09IC0xIHx8IHRoaXMucHJvZHVjZXMuaW5kZXhPZignKi8qJykgIT09IC0xO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5hc0N1cmwgPSBmdW5jdGlvbiAoYXJnczEsIGFyZ3MyKSB7XG4gIHZhciBvcHRzID0ge21vY2s6IHRydWUsIG1hc2tQYXNzd29yZHM6IHRydWV9O1xuICBpZiAodHlwZW9mIGFyZ3MyID09PSAnb2JqZWN0Jykge1xuICAgIGZvciAodmFyIGFyZ0tleSBpbiBhcmdzMikge1xuICAgICAgb3B0c1thcmdLZXldID0gYXJnczJbYXJnS2V5XTtcbiAgICB9XG4gIH1cbiAgdmFyIG9iaiA9IHRoaXMuZXhlY3V0ZShhcmdzMSwgb3B0cyk7XG5cbiAgdGhpcy5jbGllbnRBdXRob3JpemF0aW9ucy5hcHBseShvYmosIHRoaXMub3BlcmF0aW9uLnNlY3VyaXR5KTtcblxuICB2YXIgcmVzdWx0cyA9IFtdO1xuXG4gIHJlc3VsdHMucHVzaCgnLVggJyArIHRoaXMubWV0aG9kLnRvVXBwZXJDYXNlKCkpO1xuXG4gIGlmICh0eXBlb2Ygb2JqLmhlYWRlcnMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgdmFyIGtleTtcblxuICAgIGZvciAoa2V5IGluIG9iai5oZWFkZXJzKSB7XG4gICAgICB2YXIgdmFsdWUgPSBvYmouaGVhZGVyc1trZXldO1xuICAgICAgaWYodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyl7XG4gICAgICAgIHZhbHVlID0gdmFsdWUucmVwbGFjZSgvXFwnL2csICdcXFxcdTAwMjcnKTtcbiAgICAgIH1cbiAgICAgIHJlc3VsdHMucHVzaCgnLS1oZWFkZXIgXFwnJyArIGtleSArICc6ICcgKyB2YWx1ZSArICdcXCcnKTtcbiAgICB9XG4gIH1cbiAgdmFyIGlzRm9ybURhdGEgPSBmYWxzZTtcbiAgdmFyIGlzTXVsdGlwYXJ0ID0gZmFsc2U7XG5cbiAgdmFyIHR5cGUgPSBvYmouaGVhZGVyc1snQ29udGVudC1UeXBlJ107XG4gIGlmKHR5cGUgJiYgdHlwZS5pbmRleE9mKCdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnKSA9PT0gMCkge1xuICAgIGlzRm9ybURhdGEgPSB0cnVlO1xuICB9XG4gIGVsc2UgaWYgKHR5cGUgJiYgdHlwZS5pbmRleE9mKCdtdWx0aXBhcnQvZm9ybS1kYXRhJykgPT09IDApIHtcbiAgICBpc0Zvcm1EYXRhID0gdHJ1ZTtcbiAgICBpc011bHRpcGFydCA9IHRydWU7XG4gIH1cblxuICBpZiAob2JqLmJvZHkpIHtcbiAgICB2YXIgYm9keTtcbiAgICBpZiAoXy5pc09iamVjdChvYmouYm9keSkpIHtcbiAgICAgIGlmKGlzTXVsdGlwYXJ0KSB7XG4gICAgICAgIGlzTXVsdGlwYXJ0ID0gdHJ1ZTtcbiAgICAgICAgLy8gYWRkIHRoZSBmb3JtIGRhdGFcbiAgICAgICAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMucGFyYW1ldGVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIHZhciBwYXJhbWV0ZXIgPSB0aGlzLnBhcmFtZXRlcnNbaV07XG4gICAgICAgICAgaWYocGFyYW1ldGVyLmluID09PSAnZm9ybURhdGEnKSB7XG4gICAgICAgICAgICBpZiAoIWJvZHkpIHtcbiAgICAgICAgICAgICAgYm9keSA9ICcnO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgcGFyYW1WYWx1ZTtcbiAgICAgICAgICAgIGlmKHR5cGVvZiBGb3JtRGF0YSA9PT0gJ2Z1bmN0aW9uJyAmJiBvYmouYm9keSBpbnN0YW5jZW9mIEZvcm1EYXRhKSB7XG4gICAgICAgICAgICAgIHBhcmFtVmFsdWUgPSBvYmouYm9keS5nZXRBbGwocGFyYW1ldGVyLm5hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgIHBhcmFtVmFsdWUgPSBvYmouYm9keVtwYXJhbWV0ZXIubmFtZV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocGFyYW1WYWx1ZSkge1xuICAgICAgICAgICAgICBpZiAocGFyYW1ldGVyLnR5cGUgPT09ICdmaWxlJykge1xuICAgICAgICAgICAgICAgIGlmKHBhcmFtVmFsdWUubmFtZSkge1xuICAgICAgICAgICAgICAgICAgYm9keSArPSAnLUYgJyArIHBhcmFtZXRlci5uYW1lICsgJz1AXCInICsgcGFyYW1WYWx1ZS5uYW1lICsgJ1wiICc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHBhcmFtVmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICBpZihwYXJhbWV0ZXIuY29sbGVjdGlvbkZvcm1hdCA9PT0gJ211bHRpJykge1xuICAgICAgICAgICAgICAgICAgICBmb3IodmFyIHYgaW4gcGFyYW1WYWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgIGJvZHkgKz0gJy1GICcgKyB0aGlzLmVuY29kZVF1ZXJ5S2V5KHBhcmFtZXRlci5uYW1lKSArICc9JyArIG1hc2socGFyYW1WYWx1ZVt2XSwgcGFyYW1ldGVyLmZvcm1hdCkgKyAnICc7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBib2R5ICs9ICctRiAnICsgdGhpcy5lbmNvZGVRdWVyeUNvbGxlY3Rpb24ocGFyYW1ldGVyLmNvbGxlY3Rpb25Gb3JtYXQsIHBhcmFtZXRlci5uYW1lLCBtYXNrKHBhcmFtVmFsdWUsIHBhcmFtZXRlci5mb3JtYXQpKSArICcgJztcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgYm9keSArPSAnLUYgJyArIHRoaXMuZW5jb2RlUXVlcnlLZXkocGFyYW1ldGVyLm5hbWUpICsgJz0nICsgbWFzayhwYXJhbVZhbHVlLCBwYXJhbWV0ZXIuZm9ybWF0KSArICcgJztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmKCFib2R5KSB7XG4gICAgICAgIGJvZHkgPSBKU09OLnN0cmluZ2lmeShvYmouYm9keSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGJvZHkgPSBvYmouYm9keTtcbiAgICB9XG4gICAgLy8gZXNjYXBlIEAgPT4gJTQwLCAnID0+ICUyN1xuICAgIGJvZHkgPSBib2R5LnJlcGxhY2UoL1xcJy9nLCAnJTI3JykucmVwbGFjZSgvXFxuL2csICcgXFxcXCBcXG4gJyk7XG5cbiAgICBpZighaXNGb3JtRGF0YSkge1xuICAgICAgLy8gZXNjYXBlICYgPT4gJTI2XG4gICAgICBib2R5ID0gYm9keS5yZXBsYWNlKC8mL2csICclMjYnKTtcbiAgICB9XG4gICAgaWYoaXNNdWx0aXBhcnQpIHtcbiAgICAgIHJlc3VsdHMucHVzaChib2R5KTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICByZXN1bHRzLnB1c2goJy1kIFxcJycgKyBib2R5LnJlcGxhY2UoL0AvZywgJyU0MCcpICsgJ1xcJycpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiAnY3VybCAnICsgKHJlc3VsdHMuam9pbignICcpKSArICcgXFwnJyArIG9iai51cmwgKyAnXFwnJztcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuZW5jb2RlUGF0aENvbGxlY3Rpb24gPSBmdW5jdGlvbiAodHlwZSwgbmFtZSwgdmFsdWUsIG1hc2tQYXNzd29yZHMpIHtcbiAgdmFyIGVuY29kZWQgPSAnJztcbiAgdmFyIGk7XG4gIHZhciBzZXBhcmF0b3IgPSAnJztcblxuICBpZiAodHlwZSA9PT0gJ3NzdicpIHtcbiAgICBzZXBhcmF0b3IgPSAnJTIwJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAndHN2Jykge1xuICAgIHNlcGFyYXRvciA9ICclMDknO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdwaXBlcycpIHtcbiAgICBzZXBhcmF0b3IgPSAnfCc7XG4gIH0gZWxzZSB7XG4gICAgc2VwYXJhdG9yID0gJywnO1xuICB9XG5cbiAgZm9yIChpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGkgPT09IDApIHtcbiAgICAgIGVuY29kZWQgPSB0aGlzLmVuY29kZVF1ZXJ5UGFyYW0odmFsdWVbaV0sIG1hc2tQYXNzd29yZHMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbmNvZGVkICs9IHNlcGFyYXRvciArIHRoaXMuZW5jb2RlUXVlcnlQYXJhbSh2YWx1ZVtpXSwgbWFza1Bhc3N3b3Jkcyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGVuY29kZWQ7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmVuY29kZVF1ZXJ5Q29sbGVjdGlvbiA9IGZ1bmN0aW9uICh0eXBlLCBuYW1lLCB2YWx1ZSwgbWFza1Bhc3N3b3Jkcykge1xuICB2YXIgZW5jb2RlZCA9ICcnO1xuICB2YXIgaTtcblxuICB0eXBlID0gdHlwZSB8fCAnZGVmYXVsdCc7XG4gIGlmICh0eXBlID09PSAnZGVmYXVsdCcgfHwgdHlwZSA9PT0gJ211bHRpJykge1xuICAgIGZvciAoaSA9IDA7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGkgPiAwKSB7ZW5jb2RlZCArPSAnJic7fVxuXG4gICAgICBlbmNvZGVkICs9IHRoaXMuZW5jb2RlUXVlcnlLZXkobmFtZSkgKyAnPScgKyBtYXNrKHRoaXMuZW5jb2RlUXVlcnlQYXJhbSh2YWx1ZVtpXSksIG1hc2tQYXNzd29yZHMpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgc2VwYXJhdG9yID0gJyc7XG5cbiAgICBpZiAodHlwZSA9PT0gJ2NzdicpIHtcbiAgICAgIHNlcGFyYXRvciA9ICcsJztcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdzc3YnKSB7XG4gICAgICBzZXBhcmF0b3IgPSAnJTIwJztcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICd0c3YnKSB7XG4gICAgICBzZXBhcmF0b3IgPSAnJTA5JztcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdwaXBlcycpIHtcbiAgICAgIHNlcGFyYXRvciA9ICd8JztcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdicmFja2V0cycpIHtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoaSAhPT0gMCkge1xuICAgICAgICAgIGVuY29kZWQgKz0gJyYnO1xuICAgICAgICB9XG4gICAgICAgIGVuY29kZWQgKz0gdGhpcy5lbmNvZGVRdWVyeUtleShuYW1lKSArICdbXT0nICsgbWFzayh0aGlzLmVuY29kZVF1ZXJ5UGFyYW0odmFsdWVbaV0pLCBtYXNrUGFzc3dvcmRzKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc2VwYXJhdG9yICE9PSAnJykge1xuICAgICAgZm9yIChpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChpID09PSAwKSB7XG4gICAgICAgICAgZW5jb2RlZCA9IHRoaXMuZW5jb2RlUXVlcnlLZXkobmFtZSkgKyAnPScgKyB0aGlzLmVuY29kZVF1ZXJ5UGFyYW0odmFsdWVbaV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVuY29kZWQgKz0gc2VwYXJhdG9yICsgdGhpcy5lbmNvZGVRdWVyeVBhcmFtKHZhbHVlW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBlbmNvZGVkO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5lbmNvZGVRdWVyeUtleSA9IGZ1bmN0aW9uIChhcmcpIHtcbiAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudChhcmcpXG4gICAgICAucmVwbGFjZSgnJTVCJywnWycpLnJlcGxhY2UoJyU1RCcsICddJykucmVwbGFjZSgnJTI0JywgJyQnKTtcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuZW5jb2RlUXVlcnlQYXJhbSA9IGZ1bmN0aW9uIChhcmcsIG1hc2tQYXNzd29yZHMpIHtcbiAgaWYobWFza1Bhc3N3b3Jkcykge1xuICAgIHJldHVybiBcIioqKioqKlwiO1xuICB9XG4gIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQoYXJnKTtcbn07XG5cbi8qKlxuICogVE9ETyByZXZpc2l0LCBtaWdodCBub3Qgd2FudCB0byBsZWF2ZSAnLydcbiAqKi9cbk9wZXJhdGlvbi5wcm90b3R5cGUuZW5jb2RlUGF0aFBhcmFtID0gZnVuY3Rpb24gKHBhdGhQYXJhbSwgbWFza1Bhc3N3b3Jkcykge1xuICByZXR1cm4gZW5jb2RlVVJJQ29tcG9uZW50KHBhdGhQYXJhbSwgbWFza1Bhc3N3b3Jkcyk7XG59O1xuXG52YXIgbWFzayA9IGZ1bmN0aW9uKHZhbHVlLCBmb3JtYXQpIHtcbiAgaWYodHlwZW9mIGZvcm1hdCA9PT0gJ3N0cmluZycgJiYgZm9ybWF0ID09PSAncGFzc3dvcmQnKSB7XG4gICAgcmV0dXJuICcqKioqKionO1xuICB9XG4gIHJldHVybiB2YWx1ZTtcbn0iLCIndXNlIHN0cmljdCc7XG5cbnZhciBPcGVyYXRpb25Hcm91cCA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHRhZywgZGVzY3JpcHRpb24sIGV4dGVybmFsRG9jcywgb3BlcmF0aW9uKSB7XG4gIHRoaXMuZGVzY3JpcHRpb24gPSBkZXNjcmlwdGlvbjtcbiAgdGhpcy5leHRlcm5hbERvY3MgPSBleHRlcm5hbERvY3M7XG4gIHRoaXMubmFtZSA9IHRhZztcbiAgdGhpcy5vcGVyYXRpb24gPSBvcGVyYXRpb247XG4gIHRoaXMub3BlcmF0aW9uc0FycmF5ID0gW107XG4gIHRoaXMucGF0aCA9IHRhZztcbiAgdGhpcy50YWcgPSB0YWc7XG59O1xuXG5PcGVyYXRpb25Hcm91cC5wcm90b3R5cGUuc29ydCA9IGZ1bmN0aW9uICgpIHtcblxufTtcblxuIiwiLy8gc2hpbSBmb3IgdXNpbmcgcHJvY2VzcyBpbiBicm93c2VyXG5cbnZhciBwcm9jZXNzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcbnZhciBxdWV1ZSA9IFtdO1xudmFyIGRyYWluaW5nID0gZmFsc2U7XG5cbmZ1bmN0aW9uIGRyYWluUXVldWUoKSB7XG4gICAgaWYgKGRyYWluaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZHJhaW5pbmcgPSB0cnVlO1xuICAgIHZhciBjdXJyZW50UXVldWU7XG4gICAgdmFyIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB3aGlsZShsZW4pIHtcbiAgICAgICAgY3VycmVudFF1ZXVlID0gcXVldWU7XG4gICAgICAgIHF1ZXVlID0gW107XG4gICAgICAgIHZhciBpID0gLTE7XG4gICAgICAgIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICAgICAgICAgIGN1cnJlbnRRdWV1ZVtpXSgpO1xuICAgICAgICB9XG4gICAgICAgIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB9XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbn1cbnByb2Nlc3MubmV4dFRpY2sgPSBmdW5jdGlvbiAoZnVuKSB7XG4gICAgcXVldWUucHVzaChmdW4pO1xuICAgIGlmICghZHJhaW5pbmcpIHtcbiAgICAgICAgc2V0VGltZW91dChkcmFpblF1ZXVlLCAwKTtcbiAgICB9XG59O1xuXG5wcm9jZXNzLnRpdGxlID0gJ2Jyb3dzZXInO1xucHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcbnByb2Nlc3MuZW52ID0ge307XG5wcm9jZXNzLmFyZ3YgPSBbXTtcbnByb2Nlc3MudmVyc2lvbiA9ICcnOyAvLyBlbXB0eSBzdHJpbmcgdG8gYXZvaWQgcmVnZXhwIGlzc3Vlc1xucHJvY2Vzcy52ZXJzaW9ucyA9IHt9O1xuXG5mdW5jdGlvbiBub29wKCkge31cblxucHJvY2Vzcy5vbiA9IG5vb3A7XG5wcm9jZXNzLmFkZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3Mub25jZSA9IG5vb3A7XG5wcm9jZXNzLm9mZiA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUxpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlQWxsTGlzdGVuZXJzID0gbm9vcDtcbnByb2Nlc3MuZW1pdCA9IG5vb3A7XG5cbnByb2Nlc3MuYmluZGluZyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmJpbmRpbmcgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcblxuLy8gVE9ETyhzaHR5bG1hbilcbnByb2Nlc3MuY3dkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gJy8nIH07XG5wcm9jZXNzLmNoZGlyID0gZnVuY3Rpb24gKGRpcikge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xucHJvY2Vzcy51bWFzayA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gMDsgfTtcbiIsIihmdW5jdGlvbiAoQnVmZmVyKXtcbihmdW5jdGlvbiAoKSB7XG4gIFwidXNlIHN0cmljdFwiO1xuXG4gIGZ1bmN0aW9uIGJ0b2Eoc3RyKSB7XG4gICAgdmFyIGJ1ZmZlclxuICAgICAgO1xuXG4gICAgaWYgKHN0ciBpbnN0YW5jZW9mIEJ1ZmZlcikge1xuICAgICAgYnVmZmVyID0gc3RyO1xuICAgIH0gZWxzZSB7XG4gICAgICBidWZmZXIgPSBuZXcgQnVmZmVyKHN0ci50b1N0cmluZygpLCAnYmluYXJ5Jyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGJ1ZmZlci50b1N0cmluZygnYmFzZTY0Jyk7XG4gIH1cblxuICBtb2R1bGUuZXhwb3J0cyA9IGJ0b2E7XG59KCkpO1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIpXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbTV2WkdWZmJXOWtkV3hsY3k5aWRHOWhMMmx1WkdWNExtcHpJbDBzSW01aGJXVnpJanBiWFN3aWJXRndjR2x1WjNNaU9pSTdRVUZCUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVNJc0ltWnBiR1VpT2lKblpXNWxjbUYwWldRdWFuTWlMQ0p6YjNWeVkyVlNiMjkwSWpvaUlpd2ljMjkxY21ObGMwTnZiblJsYm5RaU9sc2lLR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdYQ0oxYzJVZ2MzUnlhV04wWENJN1hHNWNiaUFnWm5WdVkzUnBiMjRnWW5SdllTaHpkSElwSUh0Y2JpQWdJQ0IyWVhJZ1luVm1abVZ5WEc0Z0lDQWdJQ0E3WEc1Y2JpQWdJQ0JwWmlBb2MzUnlJR2x1YzNSaGJtTmxiMllnUW5WbVptVnlLU0I3WEc0Z0lDQWdJQ0JpZFdabVpYSWdQU0J6ZEhJN1hHNGdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJR0oxWm1abGNpQTlJRzVsZHlCQ2RXWm1aWElvYzNSeUxuUnZVM1J5YVc1bktDa3NJQ2RpYVc1aGNua25LVHRjYmlBZ0lDQjlYRzVjYmlBZ0lDQnlaWFIxY200Z1luVm1abVZ5TG5SdlUzUnlhVzVuS0NkaVlYTmxOalFuS1R0Y2JpQWdmVnh1WEc0Z0lHMXZaSFZzWlM1bGVIQnZjblJ6SUQwZ1luUnZZVHRjYm4wb0tTazdYRzRpWFgwPSIsIi8qIVxuICogVGhlIGJ1ZmZlciBtb2R1bGUgZnJvbSBub2RlLmpzLCBmb3IgdGhlIGJyb3dzZXIuXG4gKlxuICogQGF1dGhvciAgIEZlcm9zcyBBYm91a2hhZGlqZWggPGZlcm9zc0BmZXJvc3Mub3JnPiA8aHR0cDovL2Zlcm9zcy5vcmc+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+Jyk7XG4gICAgICAgIHRoaXMuYXV0aFZpZXdzID0gW107XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmNvbGxlY3Rpb24uZWFjaChmdW5jdGlvbiAoYXV0aCkge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJPbmVBdXRoKGF1dGgpO1xuICAgICAgICB9LCB0aGlzKTtcblxuICAgICAgICB0aGlzLiRlbC5odG1sKHRoaXMuJGlubmVyRWwuaHRtbCgpID8gdGhpcy4kaW5uZXJFbCA6ICcnKTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgcmVuZGVyT25lQXV0aDogZnVuY3Rpb24gKGF1dGhNb2RlbCkge1xuICAgICAgICB2YXIgYXV0aFZpZXdFbCwgYXV0aFZpZXcsIGF1dGhWaWV3TmFtZTtcbiAgICAgICAgdmFyIHR5cGUgPSBhdXRoTW9kZWwuZ2V0KCd0eXBlJyk7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhcGlLZXknKSB7XG4gICAgICAgICAgICBhdXRoVmlld05hbWUgPSAnQXBpS2V5QXV0aFZpZXcnO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdiYXNpYycgJiYgdGhpcy4kaW5uZXJFbC5maW5kKCcuYmFzaWNfYXV0aF9jb250YWluZXInKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIGF1dGhWaWV3TmFtZSA9ICdCYXNpY0F1dGhWaWV3JztcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnb2F1dGgyJykge1xuICAgICAgICAgICAgYXV0aFZpZXdOYW1lID0gJ09hdXRoMlZpZXcnO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGF1dGhWaWV3TmFtZSkge1xuICAgICAgICAgICAgYXV0aFZpZXcgPSBuZXcgU3dhZ2dlclVpLlZpZXdzW2F1dGhWaWV3TmFtZV0oe21vZGVsOiBhdXRoTW9kZWwsIHJvdXRlcjogdGhpcy5yb3V0ZXJ9KTtcbiAgICAgICAgICAgIGF1dGhWaWV3RWwgPSBhdXRoVmlldy5yZW5kZXIoKS5lbDtcbiAgICAgICAgICAgIHRoaXMuYXV0aFZpZXdzLnB1c2goYXV0aFZpZXcpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy4kaW5uZXJFbC5hcHBlbmQoYXV0aFZpZXdFbCk7XG4gICAgfSxcblxuICAgIGhpZ2hsaWdodEludmFsaWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5hdXRoVmlld3MuZm9yRWFjaChmdW5jdGlvbiAodmlldykge1xuICAgICAgICAgICAgdmlldy5oaWdobGlnaHRJbnZhbGlkKCk7XG4gICAgICAgIH0sIHRoaXMpO1xuICAgIH1cblxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qIGdsb2JhbCByZWRpcmVjdF91cmk6dHJ1ZSAqL1xuLyogZ2xvYmFsIGNsaWVudElkICovXG4vKiBnbG9iYWwgc2NvcGVTZXBhcmF0b3IgKi9cbi8qIGdsb2JhbCBhZGRpdGlvbmFsUXVlcnlTdHJpbmdQYXJhbXMgKi9cbi8qIGdsb2JhbCBjbGllbnRTZWNyZXQgKi9cbi8qIGdsb2JhbCBvbk9BdXRoQ29tcGxldGUgKi9cbi8qIGdsb2JhbCByZWFsbSAqL1xuLypqc2hpbnQgdW51c2VkOmZhbHNlKi9cblxuU3dhZ2dlclVpLlZpZXdzLkF1dGhWaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoe1xuICAgIGV2ZW50czoge1xuICAgICAgICAnY2xpY2sgLmF1dGhfc3VibWl0X19idXR0b24nOiAnYXV0aG9yaXplQ2xpY2snLFxuICAgICAgICAnY2xpY2sgLmF1dGhfbG9nb3V0X19idXR0b24nOiAnbG9nb3V0Q2xpY2snXG4gICAgfSxcblxuICAgIHRwbHM6IHtcbiAgICAgICAgbWFpbjogSGFuZGxlYmFycy50ZW1wbGF0ZXMuYXV0aF92aWV3XG4gICAgfSxcblxuICAgIHNlbGVjdG9yczoge1xuICAgICAgICBpbm5lckVsOiAnLmF1dGhfaW5uZXInLFxuICAgICAgICBhdXRoQnRuOiAnLmF1dGhfc3VibWl0X19idXR0b24nXG4gICAgfSxcblxuICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uKG9wdHMpIHtcbiAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0cyB8fCB7fTtcbiAgICAgICAgb3B0cy5kYXRhID0gb3B0cy5kYXRhIHx8IHt9O1xuICAgICAgICB0aGlzLnJvdXRlciA9IHRoaXMub3B0aW9ucy5yb3V0ZXI7XG5cbiAgICAgICAgdGhpcy5hdXRoc0NvbGxlY3Rpb25WaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5BdXRoc0NvbGxlY3Rpb25WaWV3KHtkYXRhOiBvcHRzLmRhdGF9KTtcblxuICAgICAgICB0aGlzLiRlbC5odG1sKHRoaXMudHBscy5tYWluKHtcbiAgICAgICAgICAgIGlzTG9nb3V0OiB0aGlzLmF1dGhzQ29sbGVjdGlvblZpZXcuY29sbGVjdGlvbi5pc0F1dGhvcml6ZWQoKSxcbiAgICAgICAgICAgIGlzQXV0aG9yaXplZDogdGhpcy5hdXRoc0NvbGxlY3Rpb25WaWV3LmNvbGxlY3Rpb24uaXNQYXJ0aWFsbHlBdXRob3JpemVkKClcbiAgICAgICAgfSkpO1xuICAgICAgICB0aGlzLiRpbm5lckVsID0gdGhpcy4kKHRoaXMuc2VsZWN0b3JzLmlubmVyRWwpO1xuICAgICAgICB0aGlzLmlzTG9nb3V0ID0gdGhpcy5hdXRoc0NvbGxlY3Rpb25WaWV3LmNvbGxlY3Rpb24uaXNQYXJ0aWFsbHlBdXRob3JpemVkKCk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLiRpbm5lckVsLmh0bWwodGhpcy5hdXRoc0NvbGxlY3Rpb25WaWV3LnJlbmRlcigpLmVsKTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgYXV0aG9yaXplQ2xpY2s6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgICAgICBpZiAodGhpcy5hdXRoc0NvbGxlY3Rpb25WaWV3LmNvbGxlY3Rpb24uaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICB0aGlzLmF1dGhvcml6ZSgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5hdXRoc0NvbGxlY3Rpb25WaWV3LmhpZ2hsaWdodEludmFsaWQoKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBhdXRob3JpemU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5hdXRoc0NvbGxlY3Rpb25WaWV3LmNvbGxlY3Rpb24uZm9yRWFjaChmdW5jdGlvbiAoYXV0aCkge1xuICAgICAgICAgICAgdmFyIGtleUF1dGgsIGJhc2ljQXV0aDtcbiAgICAgICAgICAgIHZhciB0eXBlID0gYXV0aC5nZXQoJ3R5cGUnKTtcblxuICAgICAgICAgICAgaWYgKHR5cGUgPT09ICdhcGlLZXknKSB7XG4gICAgICAgICAgICAgICAga2V5QXV0aCA9IG5ldyBTd2FnZ2VyQ2xpZW50LkFwaUtleUF1dGhvcml6YXRpb24oXG4gICAgICAgICAgICAgICAgICAgIGF1dGguZ2V0KCduYW1lJyksXG4gICAgICAgICAgICAgICAgICAgIGF1dGguZ2V0KCd2YWx1ZScpLFxuICAgICAgICAgICAgICAgICAgICBhdXRoLmdldCgnaW4nKVxuICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgICB0aGlzLnJvdXRlci5hcGkuY2xpZW50QXV0aG9yaXphdGlvbnMuYWRkKGF1dGguZ2V0KCd0aXRsZScpLCBrZXlBdXRoKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2Jhc2ljJykge1xuICAgICAgICAgICAgICAgIGJhc2ljQXV0aCA9IG5ldyBTd2FnZ2VyQ2xpZW50LlBhc3N3b3JkQXV0aG9yaXphdGlvbihhdXRoLmdldCgndXNlcm5hbWUnKSwgYXV0aC5nZXQoJ3Bhc3N3b3JkJykpO1xuICAgICAgICAgICAgICAgIHRoaXMucm91dGVyLmFwaS5jbGllbnRBdXRob3JpemF0aW9ucy5hZGQoYXV0aC5nZXQoJ3RpdGxlJyksIGJhc2ljQXV0aCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdvYXV0aDInKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVPYXV0aDJMb2dpbihhdXRoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgdGhpcyk7XG5cbiAgICAgICAgdGhpcy5yb3V0ZXIubG9hZCgpO1xuICAgIH0sXG5cbiAgICBsb2dvdXRDbGljazogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgIHRoaXMuYXV0aHNDb2xsZWN0aW9uVmlldy5jb2xsZWN0aW9uLmZvckVhY2goZnVuY3Rpb24gKGF1dGgpIHtcbiAgICAgICAgICAgIHdpbmRvdy5zd2FnZ2VyVWkuYXBpLmNsaWVudEF1dGhvcml6YXRpb25zLnJlbW92ZShhdXRoLmdldCgndGl0bGUnKSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMucm91dGVyLmxvYWQoKTtcbiAgICB9LFxuXG4gICAgLy8gdGFrZW4gZnJvbSBsaWIvc3dhZ2dlci1vYXV0aC5qc1xuICAgIGhhbmRsZU9hdXRoMkxvZ2luOiBmdW5jdGlvbiAoYXV0aCkge1xuICAgICAgICB2YXIgaG9zdCA9IHdpbmRvdy5sb2NhdGlvbjtcbiAgICAgICAgdmFyIHBhdGhuYW1lID0gbG9jYXRpb24ucGF0aG5hbWUuc3Vic3RyaW5nKDAsIGxvY2F0aW9uLnBhdGhuYW1lLmxhc3RJbmRleE9mKCcvJykpO1xuICAgICAgICB2YXIgZGVmYXVsdFJlZGlyZWN0VXJsID0gaG9zdC5wcm90b2NvbCArICcvLycgKyBob3N0Lmhvc3QgKyBwYXRobmFtZSArICcvbzJjLmh0bWwnO1xuICAgICAgICB2YXIgcmVkaXJlY3RVcmwgPSB3aW5kb3cub0F1dGhSZWRpcmVjdFVybCB8fCBkZWZhdWx0UmVkaXJlY3RVcmw7XG4gICAgICAgIHZhciB1cmwgPSBudWxsO1xuICAgICAgICB2YXIgc2NvcGVzID0gXy5tYXAoYXV0aC5nZXQoJ3Njb3BlcycpLCBmdW5jdGlvbiAoc2NvcGUpIHtcbiAgICAgICAgICAgIGlmKHNjb3BlLmNoZWNrZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NvcGUuc2NvcGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgY29udGFpbmVyID0gd2luZG93LnN3YWdnZXJVaUF1dGggfHwgKHdpbmRvdy5zd2FnZ2VyVWlBdXRoID0ge30pO1xuICAgICAgICB2YXIgc3RhdGUsIGRldHMsIGVwO1xuICAgICAgICBjb250YWluZXIuT0F1dGhTY2hlbWVLZXkgPSBhdXRoLmdldCgndGl0bGUnKTtcblxuICAgICAgICB3aW5kb3cuZW5hYmxlZFNjb3BlcyA9IHNjb3BlcztcbiAgICAgICAgdmFyIGZsb3cgPSBhdXRoLmdldCgnZmxvdycpO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBhY2Nlc3MgdG9rZW4gcGFyYW1ldGVyIHJldHVybmVkIGJ5IHRoZSBzZXJ2ZXIuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSBkZXRzXG4gICAgICAgICAqICAgICBUaGUgYXV0aG9yaXNhdGlvbiBzY2hlbWUgY29uZmlndXJhdGlvbi5cbiAgICAgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGUgYWNjZXNzIHRva2VuIHBhcmFtZXRlclxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gZ2V0VG9rZW5OYW1lKGRldHMpIHtcbiAgICAgICAgICAgIHJldHVybiBkZXRzLnZlbmRvckV4dGVuc2lvbnNbJ3gtdG9rZW5OYW1lJ10gfHwgZGV0cy50b2tlbk5hbWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZihhdXRoLmdldCgndHlwZScpID09PSAnb2F1dGgyJyAmJiBmbG93ICYmIChmbG93ID09PSAnaW1wbGljaXQnIHx8IGZsb3cgPT09ICdhY2Nlc3NDb2RlJykpIHtcbiAgICAgICAgICAgIGRldHMgPSBhdXRoLmF0dHJpYnV0ZXM7XG4gICAgICAgICAgICB1cmwgPSBkZXRzLmF1dGhvcml6YXRpb25VcmwgKyAnP3Jlc3BvbnNlX3R5cGU9JyArIChmbG93ID09PSAnaW1wbGljaXQnID8gJ3Rva2VuJyA6ICdjb2RlJyk7XG4gICAgICAgICAgICBjb250YWluZXIudG9rZW5OYW1lID0gZ2V0VG9rZW5OYW1lKGRldHMpIHx8ICdhY2Nlc3NfdG9rZW4nO1xuICAgICAgICAgICAgY29udGFpbmVyLnRva2VuVXJsID0gKGZsb3cgPT09ICdhY2Nlc3NDb2RlJyA/IGRldHMudG9rZW5VcmwgOiBudWxsKTtcbiAgICAgICAgICAgIHN0YXRlID0gY29udGFpbmVyLk9BdXRoU2NoZW1lS2V5O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYoYXV0aC5nZXQoJ3R5cGUnKSA9PT0gJ29hdXRoMicgJiYgZmxvdyAmJiAoZmxvdyA9PT0gJ2FwcGxpY2F0aW9uJykpIHtcbiAgICAgICAgICAgIGRldHMgPSBhdXRoLmF0dHJpYnV0ZXM7XG4gICAgICAgICAgICBjb250YWluZXIudG9rZW5OYW1lID0gZ2V0VG9rZW5OYW1lKGRldHMpIHx8ICdhY2Nlc3NfdG9rZW4nO1xuICAgICAgICAgICAgdGhpcy5jbGllbnRDcmVkZW50aWFsc0Zsb3coc2NvcGVzLCBkZXRzLCBjb250YWluZXIuT0F1dGhTY2hlbWVLZXkpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYoYXV0aC5nZXQoJ3R5cGUnKSA9PT0gJ29hdXRoMicgJiYgZmxvdyAmJiAoZmxvdyA9PT0gJ3Bhc3N3b3JkJykpIHtcbiAgICAgICAgICAgIGRldHMgPSBhdXRoLmF0dHJpYnV0ZXM7XG4gICAgICAgICAgICBjb250YWluZXIudG9rZW5OYW1lID0gZ2V0VG9rZW5OYW1lKGRldHMpIHx8ICdhY2Nlc3NfdG9rZW4nO1xuICAgICAgICAgICAgdGhpcy5wYXNzd29yZEZsb3coc2NvcGVzLCBkZXRzLCBjb250YWluZXIuT0F1dGhTY2hlbWVLZXkpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYoYXV0aC5nZXQoJ2dyYW50VHlwZXMnKSkge1xuICAgICAgICAgICAgLy8gMS4yIHN1cHBvcnRcbiAgICAgICAgICAgIHZhciBvID0gYXV0aC5nZXQoJ2dyYW50VHlwZXMnKTtcbiAgICAgICAgICAgIGZvcih2YXIgdCBpbiBvKSB7XG4gICAgICAgICAgICAgICAgaWYoby5oYXNPd25Qcm9wZXJ0eSh0KSAmJiB0ID09PSAnaW1wbGljaXQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGRldHMgPSBvW3RdO1xuICAgICAgICAgICAgICAgICAgICBlcCA9IGRldHMubG9naW5FbmRwb2ludC51cmw7XG4gICAgICAgICAgICAgICAgICAgIHVybCA9IGRldHMubG9naW5FbmRwb2ludC51cmwgKyAnP3Jlc3BvbnNlX3R5cGU9dG9rZW4nO1xuICAgICAgICAgICAgICAgICAgICBjb250YWluZXIudG9rZW5OYW1lID0gZ2V0VG9rZW5OYW1lKGRldHMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChvLmhhc093blByb3BlcnR5KHQpICYmIHQgPT09ICdhY2Nlc3NDb2RlJykge1xuICAgICAgICAgICAgICAgICAgICBkZXRzID0gb1t0XTtcbiAgICAgICAgICAgICAgICAgICAgZXAgPSBkZXRzLnRva2VuUmVxdWVzdEVuZHBvaW50LnVybDtcbiAgICAgICAgICAgICAgICAgICAgdXJsID0gZGV0cy50b2tlblJlcXVlc3RFbmRwb2ludC51cmwgKyAnP3Jlc3BvbnNlX3R5cGU9Y29kZSc7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRhaW5lci50b2tlbk5hbWUgPSBnZXRUb2tlbk5hbWUoZGV0cyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmVkaXJlY3RfdXJpID0gcmVkaXJlY3RVcmw7XG5cbiAgICAgICAgdXJsICs9ICcmcmVkaXJlY3RfdXJpPScgKyBlbmNvZGVVUklDb21wb25lbnQocmVkaXJlY3RVcmwpO1xuICAgICAgICB1cmwgKz0gJyZyZWFsbT0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHJlYWxtKTtcbiAgICAgICAgdXJsICs9ICcmY2xpZW50X2lkPScgKyBlbmNvZGVVUklDb21wb25lbnQoY2xpZW50SWQpO1xuICAgICAgICB1cmwgKz0gJyZzY29wZT0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHNjb3Blcy5qb2luKHNjb3BlU2VwYXJhdG9yKSk7XG4gICAgICAgIHVybCArPSAnJnN0YXRlPScgKyBlbmNvZGVVUklDb21wb25lbnQoc3RhdGUpO1xuICAgICAgICBmb3IgKHZhciBrZXkgaW4gYWRkaXRpb25hbFF1ZXJ5U3RyaW5nUGFyYW1zKSB7XG4gICAgICAgICAgICB1cmwgKz0gJyYnICsga2V5ICsgJz0nICsgZW5jb2RlVVJJQ29tcG9uZW50KGFkZGl0aW9uYWxRdWVyeVN0cmluZ1BhcmFtc1trZXldKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHdpbmRvdy5vcGVuKHVybCk7XG4gICAgfSxcblxuICAgIC8vIHRha2VuIGZyb20gbGliL3N3YWdnZXItb2F1dGguanNcbiAgICBjbGllbnRDcmVkZW50aWFsc0Zsb3c6IGZ1bmN0aW9uIChzY29wZXMsIG9hdXRoLCBPQXV0aFNjaGVtZUtleSkge1xuICAgICAgICB0aGlzLmFjY2Vzc1Rva2VuUmVxdWVzdChzY29wZXMsIG9hdXRoLCBPQXV0aFNjaGVtZUtleSwgJ2NsaWVudF9jcmVkZW50aWFscycpO1xuICAgIH0sXG5cbiAgICBwYXNzd29yZEZsb3c6IGZ1bmN0aW9uIChzY29wZXMsIG9hdXRoLCBPQXV0aFNjaGVtZUtleSkge1xuICAgICAgICB0aGlzLmFjY2Vzc1Rva2VuUmVxdWVzdChzY29wZXMsIG9hdXRoLCBPQXV0aFNjaGVtZUtleSwgJ3Bhc3N3b3JkJywge1xuICAgICAgICAgICAgJ3VzZXJuYW1lJzogb2F1dGgudXNlcm5hbWUsXG4gICAgICAgICAgICAncGFzc3dvcmQnOiBvYXV0aC5wYXNzd29yZFxuICAgICAgICB9KTtcbiAgICB9LFxuXG4gICAgYWNjZXNzVG9rZW5SZXF1ZXN0OiBmdW5jdGlvbiAoc2NvcGVzLCBvYXV0aCwgT0F1dGhTY2hlbWVLZXksIGdyYW50VHlwZSwgcGFyYW1zKSB7XG4gICAgICAgIHBhcmFtcyA9ICQuZXh0ZW5kKHt9LCB7XG4gICAgICAgICAgICAnc2NvcGUnOiBzY29wZXMuam9pbignICcpLFxuICAgICAgICAgICAgJ2dyYW50X3R5cGUnOiBncmFudFR5cGVcbiAgICAgICAgfSwgcGFyYW1zKTtcblxuICAgICAgICB2YXIgaGVhZGVycz0ge307XG5cbiAgICAgICAgc3dpdGNoIChvYXV0aC5jbGllbnRBdXRoZW50aWNhdGlvblR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgJ2Jhc2ljJzpcbiAgICAgICAgICAgICAgICBoZWFkZXJzLkF1dGhvcml6YXRpb24gPSAnQmFzaWMgJyArIGJ0b2Eob2F1dGguY2xpZW50SWQgKyAnOicgKyBvYXV0aC5jbGllbnRTZWNyZXQpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAncmVxdWVzdC1ib2R5JzpcbiAgICAgICAgICAgICAgICBwYXJhbXMuY2xpZW50X2lkID0gb2F1dGguY2xpZW50SWQ7XG4gICAgICAgICAgICAgICAgcGFyYW1zLmNsaWVudF9zZWNyZXQgPSBvYXV0aC5jbGllbnRTZWNyZXQ7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICAkLmFqYXgoe1xuICAgICAgICAgICAgdXJsIDogb2F1dGgudG9rZW5VcmwsXG4gICAgICAgICAgICB0eXBlOiAnUE9TVCcsXG4gICAgICAgICAgICBkYXRhOiBwYXJhbXMsXG4gICAgICAgICAgICBoZWFkZXJzOiBoZWFkZXJzLFxuICAgICAgICAgICAgc3VjY2VzczogZnVuY3Rpb24gKGRhdGEpXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgb25PQXV0aENvbXBsZXRlKGRhdGEsIE9BdXRoU2NoZW1lS2V5KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlcnJvcjogZnVuY3Rpb24gKClcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBvbk9BdXRoQ29tcGxldGUoJycpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLk1vZGVscy5CYXNpY0F1dGhNb2RlbCA9IEJhY2tib25lLk1vZGVsLmV4dGVuZCh7XG4gICAgZGVmYXVsdHM6IHtcbiAgICAgICAgdXNlcm5hbWU6ICcnLFxuICAgICAgICBwYXNzd29yZDogJycsXG4gICAgICAgIHRpdGxlOiAnYmFzaWMnXG4gICAgfSxcblxuICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5vbignY2hhbmdlJywgdGhpcy52YWxpZGF0ZSk7XG4gICAgfSxcblxuICAgIHZhbGlkYXRlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB2YWxpZCA9ICEhdGhpcy5nZXQoJ3Bhc3N3b3JkJykgJiYgISF0aGlzLmdldCgndXNlcm5hbWUnKTtcblxuICAgICAgICB0aGlzLnNldCgndmFsaWQnLCB2YWxpZCk7XG5cbiAgICAgICAgcmV0dXJuIHZhbGlkO1xuICAgIH1cbn0pOyIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLlZpZXdzLkJhc2ljQXV0aFZpZXcgPSBCYWNrYm9uZS5WaWV3LmV4dGVuZCh7XG5cbiAgICBpbml0aWFsaXplOiBmdW5jdGlvbiAob3B0cykge1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSBvcHRzIHx8IHt9O1xuICAgICAgICB0aGlzLnJvdXRlciA9IHRoaXMub3B0aW9ucy5yb3V0ZXI7XG4gICAgfSxcblxuICAgIGV2ZW50czoge1xuICAgICAgICAnY2hhbmdlIC5hdXRoX2lucHV0JzogJ2lucHV0Q2hhbmdlJ1xuICAgIH0sXG5cbiAgICBzZWxlY3RvcnM6IHtcbiAgICAgICAgdXNlcm5hbWVJbnB1dDogJy5iYXNpY19hdXRoX191c2VybmFtZScsXG4gICAgICAgIHBhc3N3b3JkSW5wdXQ6ICcuYmFzaWNfYXV0aF9fcGFzc3dvcmQnXG4gICAgfSxcblxuICAgIGNsczoge1xuICAgICAgICBlcnJvcjogJ2Vycm9yJ1xuICAgIH0sXG5cbiAgICB0ZW1wbGF0ZTogSGFuZGxlYmFycy50ZW1wbGF0ZXMuYmFzaWNfYXV0aCxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24oKXtcbiAgICAgICAgJCh0aGlzLmVsKS5odG1sKHRoaXMudGVtcGxhdGUodGhpcy5tb2RlbC50b0pTT04oKSkpO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICBpbnB1dENoYW5nZTogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgdmFyICRlbCA9ICQoZS50YXJnZXQpO1xuICAgICAgICB2YXIgdmFsID0gJGVsLnZhbCgpO1xuICAgICAgICB2YXIgYXR0ciA9ICRlbC5wcm9wKCduYW1lJyk7XG5cbiAgICAgICAgaWYgKHZhbCkge1xuICAgICAgICAgICAgJGVsLnJlbW92ZUNsYXNzKHRoaXMuY2xzLmVycm9yKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMubW9kZWwuc2V0KGF0dHIsIHZhbCk7XG4gICAgfSxcblxuICAgIGlzVmFsaWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubW9kZWwudmFsaWRhdGUoKTtcbiAgICB9LFxuXG4gICAgaGlnaGxpZ2h0SW52YWxpZDogZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIXRoaXMubW9kZWwuZ2V0KCd1c2VybmFtZScpKSB7XG4gICAgICAgICAgICB0aGlzLiQodGhpcy5zZWxlY3RvcnMudXNlcm5hbWVJbnB1dCkuYWRkQ2xhc3ModGhpcy5jbHMuZXJyb3IpO1xuICAgICAgICB9XG4gICAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5Db250ZW50VHlwZVZpZXcgPSBCYWNrYm9uZS5WaWV3LmV4dGVuZCh7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uKCkge30sXG5cbiAgcmVuZGVyOiBmdW5jdGlvbigpe1xuICBcdHRoaXMubW9kZWwuY29udGVudFR5cGVJZCA9ICdjdCcgKyBNYXRoLnJhbmRvbSgpO1xuICAgICQodGhpcy5lbCkuaHRtbChIYW5kbGViYXJzLnRlbXBsYXRlcy5jb250ZW50X3R5cGUodGhpcy5tb2RlbCkpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG59KTsiLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5IZWFkZXJWaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoe1xuICBldmVudHM6IHtcbiAgICAnY2xpY2sgI3Nob3ctcGV0LXN0b3JlLWljb24nICAgIDogJ3Nob3dQZXRTdG9yZScsXG4gICAgJ2NsaWNrICNleHBsb3JlJyAgICAgICAgICAgICAgICA6ICdzaG93Q3VzdG9tJyxcbiAgICAnc3VibWl0ICNhcGlfc2VsZWN0b3InICAgICAgICAgIDogJ3Nob3dDdXN0b20nLFxuICAgICdrZXl1cCAjaW5wdXRfYmFzZVVybCcgICAgICAgICAgOiAnc2hvd0N1c3RvbU9uS2V5dXAnLFxuICAgICdrZXl1cCAjaW5wdXRfYXBpS2V5JyAgICAgICAgICAgOiAnc2hvd0N1c3RvbU9uS2V5dXAnXG4gIH0sXG5cbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oKXt9LFxuXG4gIHNob3dQZXRTdG9yZTogZnVuY3Rpb24oKXtcbiAgICB0aGlzLnRyaWdnZXIoJ3VwZGF0ZS1zd2FnZ2VyLXVpJywge1xuICAgICAgdXJsOidodHRwOi8vcGV0c3RvcmUuc3dhZ2dlci5pby92Mi9zd2FnZ2VyLmpzb24nXG4gICAgfSk7XG4gIH0sXG5cbiAgc2hvd0N1c3RvbU9uS2V5dXA6IGZ1bmN0aW9uKGUpe1xuICAgIGlmIChlLmtleUNvZGUgPT09IDEzKSB7XG4gICAgICB0aGlzLnNob3dDdXN0b20oKTtcbiAgICB9XG4gIH0sXG5cbiAgc2hvd0N1c3RvbTogZnVuY3Rpb24oZSl7XG4gICAgaWYgKGUpIHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG5cbiAgICB0aGlzLnRyaWdnZXIoJ3VwZGF0ZS1zd2FnZ2VyLXVpJywge1xuICAgICAgdXJsOiAkKCcjaW5wdXRfYmFzZVVybCcpLnZhbCgpXG4gICAgfSk7XG4gIH0sXG5cbiAgdXBkYXRlOiBmdW5jdGlvbih1cmwsIGFwaUtleSwgdHJpZ2dlcil7XG4gICAgaWYgKHRyaWdnZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdHJpZ2dlciA9IGZhbHNlO1xuICAgIH1cblxuICAgICQoJyNpbnB1dF9iYXNlVXJsJykudmFsKHVybCk7XG5cbiAgICBpZiAodHJpZ2dlcikge1xuICAgICAgdGhpcy50cmlnZ2VyKCd1cGRhdGUtc3dhZ2dlci11aScsIHt1cmw6dXJsfSk7XG4gICAgfVxuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLlZpZXdzLk1haW5WaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoe1xuICBhcGlzU29ydGVyIDoge1xuICAgIGFscGhhICAgOiBmdW5jdGlvbihhLGIpeyByZXR1cm4gYS5uYW1lLmxvY2FsZUNvbXBhcmUoYi5uYW1lKTsgfVxuICB9LFxuICBvcGVyYXRpb25zU29ydGVycyA6IHtcbiAgICBhbHBoYSAgIDogZnVuY3Rpb24oYSxiKXsgcmV0dXJuIGEucGF0aC5sb2NhbGVDb21wYXJlKGIucGF0aCk7IH0sXG4gICAgbWV0aG9kICA6IGZ1bmN0aW9uKGEsYil7IHJldHVybiBhLm1ldGhvZC5sb2NhbGVDb21wYXJlKGIubWV0aG9kKTsgfVxuICB9LFxuICBpbml0aWFsaXplOiBmdW5jdGlvbihvcHRzKXtcbiAgICB2YXIgc29ydGVyT3B0aW9uLCBzb3J0ZXJGbiwga2V5LCB2YWx1ZTtcbiAgICBvcHRzID0gb3B0cyB8fCB7fTtcblxuICAgIHRoaXMucm91dGVyID0gb3B0cy5yb3V0ZXI7XG5cbiAgICAvLyBTb3J0IEFQSXNcbiAgICBpZiAob3B0cy5zd2FnZ2VyT3B0aW9ucy5hcGlzU29ydGVyKSB7XG4gICAgICBzb3J0ZXJPcHRpb24gPSBvcHRzLnN3YWdnZXJPcHRpb25zLmFwaXNTb3J0ZXI7XG4gICAgICBpZiAoXy5pc0Z1bmN0aW9uKHNvcnRlck9wdGlvbikpIHtcbiAgICAgICAgc29ydGVyRm4gPSBzb3J0ZXJPcHRpb247XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzb3J0ZXJGbiA9IHRoaXMuYXBpc1NvcnRlcltzb3J0ZXJPcHRpb25dO1xuICAgICAgfVxuICAgICAgaWYgKF8uaXNGdW5jdGlvbihzb3J0ZXJGbikpIHtcbiAgICAgICAgdGhpcy5tb2RlbC5hcGlzQXJyYXkuc29ydChzb3J0ZXJGbik7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIFNvcnQgb3BlcmF0aW9ucyBvZiBlYWNoIEFQSVxuICAgIGlmIChvcHRzLnN3YWdnZXJPcHRpb25zLm9wZXJhdGlvbnNTb3J0ZXIpIHtcbiAgICAgIHNvcnRlck9wdGlvbiA9IG9wdHMuc3dhZ2dlck9wdGlvbnMub3BlcmF0aW9uc1NvcnRlcjtcbiAgICAgIGlmIChfLmlzRnVuY3Rpb24oc29ydGVyT3B0aW9uKSkge1xuICAgICAgICBzb3J0ZXJGbiA9IHNvcnRlck9wdGlvbjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNvcnRlckZuID0gdGhpcy5vcGVyYXRpb25zU29ydGVyc1tzb3J0ZXJPcHRpb25dO1xuICAgICAgfVxuICAgICAgaWYgKF8uaXNGdW5jdGlvbihzb3J0ZXJGbikpIHtcbiAgICAgICAgZm9yIChrZXkgaW4gdGhpcy5tb2RlbC5hcGlzQXJyYXkpIHtcbiAgICAgICAgICB0aGlzLm1vZGVsLmFwaXNBcnJheVtrZXldLm9wZXJhdGlvbnNBcnJheS5zb3J0KHNvcnRlckZuKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHNldCB1cCB0aGUgVUkgZm9yIGlucHV0XG4gICAgdGhpcy5tb2RlbC5hdXRocyA9IFtdO1xuXG4gICAgZm9yIChrZXkgaW4gdGhpcy5tb2RlbC5zZWN1cml0eURlZmluaXRpb25zKSB7XG4gICAgICB2YWx1ZSA9IHRoaXMubW9kZWwuc2VjdXJpdHlEZWZpbml0aW9uc1trZXldO1xuXG4gICAgICB0aGlzLm1vZGVsLmF1dGhzLnB1c2goe1xuICAgICAgICBuYW1lOiBrZXksXG4gICAgICAgIHR5cGU6IHZhbHVlLnR5cGUsXG4gICAgICAgIHZhbHVlOiB2YWx1ZVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKCd2YWxpZGF0b3JVcmwnIGluIG9wdHMuc3dhZ2dlck9wdGlvbnMpIHtcbiAgICAgIC8vIFZhbGlkYXRvciBVUkwgc3BlY2lmaWVkIGV4cGxpY2l0bHlcbiAgICAgIHRoaXMubW9kZWwudmFsaWRhdG9yVXJsID0gb3B0cy5zd2FnZ2VyT3B0aW9ucy52YWxpZGF0b3JVcmw7XG4gICAgfSBlbHNlIGlmICh0aGlzLm1vZGVsLnVybC5pbmRleE9mKCdsb2NhbGhvc3QnKSA+IDAgfHwgdGhpcy5tb2RlbC51cmwuaW5kZXhPZignMTI3LjAuMC4xJykgPiAwKSB7XG4gICAgICAvLyBMb2NhbGhvc3Qgb3ZlcnJpZGVcbiAgICAgIHRoaXMubW9kZWwudmFsaWRhdG9yVXJsID0gbnVsbDtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5tb2RlbC52YWxpZGF0b3JVcmwgPSAnLy9vbmxpbmUuc3dhZ2dlci5pby92YWxpZGF0b3InO1xuICAgIH1cblxuICAgIC8vIEpTb25FZGl0b3IgcmVxdWlyZXMgdHlwZT0nb2JqZWN0JyB0byBiZSBwcmVzZW50IG9uIGRlZmluZWQgdHlwZXMsIHdlIGFkZCBpdCBpZiBpdCdzIG1pc3NpbmdcbiAgICAvLyBpcyB0aGVyZSBhbnkgdmFsaWQgY2FzZSB3ZXJlIGl0IHNob3VsZCBub3QgYmUgYWRkZWQgP1xuICAgIHZhciBkZWY7XG4gICAgZm9yKGRlZiBpbiB0aGlzLm1vZGVsLmRlZmluaXRpb25zKXtcbiAgICAgIGlmICghdGhpcy5tb2RlbC5kZWZpbml0aW9uc1tkZWZdLnR5cGUpe1xuICAgICAgICB0aGlzLm1vZGVsLmRlZmluaXRpb25zW2RlZl0udHlwZSA9ICdvYmplY3QnO1xuICAgICAgfVxuICAgIH1cblxuICB9LFxuXG4gIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgICQodGhpcy5lbCkuaHRtbChIYW5kbGViYXJzLnRlbXBsYXRlcy5tYWluKHRoaXMubW9kZWwpKTtcbiAgICB0aGlzLmluZm8gPSB0aGlzLiQoJy5pbmZvJylbMF07XG5cbiAgICBpZiAodGhpcy5pbmZvKSB7XG4gICAgICB0aGlzLmluZm8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLm9uTGlua0NsaWNrLCB0cnVlKTtcbiAgICB9XG5cbiAgICB0aGlzLm1vZGVsLnNlY3VyaXR5RGVmaW5pdGlvbnMgPSB0aGlzLm1vZGVsLnNlY3VyaXR5RGVmaW5pdGlvbnMgfHwge307XG5cbiAgICAvLyBSZW5kZXIgZWFjaCByZXNvdXJjZVxuXG4gICAgdmFyIHJlc291cmNlcyA9IHt9O1xuICAgIHZhciBjb3VudGVyID0gMDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubW9kZWwuYXBpc0FycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgcmVzb3VyY2UgPSB0aGlzLm1vZGVsLmFwaXNBcnJheVtpXTtcbiAgICAgIHZhciBpZCA9IHJlc291cmNlLm5hbWU7XG4gICAgICB3aGlsZSAodHlwZW9mIHJlc291cmNlc1tpZF0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGlkID0gaWQgKyAnXycgKyBjb3VudGVyO1xuICAgICAgICBjb3VudGVyICs9IDE7XG4gICAgICB9XG4gICAgICByZXNvdXJjZS5pZCA9IHNhbml0aXplSHRtbChpZCk7XG4gICAgICByZXNvdXJjZXNbaWRdID0gcmVzb3VyY2U7XG4gICAgICB0aGlzLmFkZFJlc291cmNlKHJlc291cmNlLCB0aGlzLm1vZGVsLmF1dGhzKTtcbiAgICB9XG5cbiAgICAkKCcucHJvcFdyYXAnKS5ob3ZlcihmdW5jdGlvbiBvbkhvdmVyKCl7XG4gICAgICAkKCcub3B0aW9uc1dyYXBwZXInLCAkKHRoaXMpKS5zaG93KCk7XG4gICAgfSwgZnVuY3Rpb24gb2ZmaG92ZXIoKXtcbiAgICAgICQoJy5vcHRpb25zV3JhcHBlcicsICQodGhpcykpLmhpZGUoKTtcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfSxcblxuICBhZGRSZXNvdXJjZTogZnVuY3Rpb24ocmVzb3VyY2UsIGF1dGhzKXtcbiAgICAvLyBSZW5kZXIgYSByZXNvdXJjZSBhbmQgYWRkIGl0IHRvIHJlc291cmNlcyBsaVxuICAgIHJlc291cmNlLmlkID0gcmVzb3VyY2UuaWQucmVwbGFjZSgvW15hLXpBLVpcXGRdL2csIGZ1bmN0aW9uKHN0cikgeyByZXR1cm4gc3RyLmNoYXJDb2RlQXQoMCk7IH0pO1xuXG4gICAgLy8gTWFrZSBhbGwgZGVmaW5pdGlvbnMgYXZhaWxhYmxlIGF0IHRoZSByb290IG9mIHRoZSByZXNvdXJjZSBzbyB0aGF0IHRoZXkgY2FuXG4gICAgLy8gYmUgbG9hZGVkIGJ5IHRoZSBKU29uRWRpdG9yXG4gICAgcmVzb3VyY2UuZGVmaW5pdGlvbnMgPSB0aGlzLm1vZGVsLmRlZmluaXRpb25zO1xuXG4gICAgdmFyIHJlc291cmNlVmlldyA9IG5ldyBTd2FnZ2VyVWkuVmlld3MuUmVzb3VyY2VWaWV3KHtcbiAgICAgIG1vZGVsOiByZXNvdXJjZSxcbiAgICAgIHJvdXRlcjogdGhpcy5yb3V0ZXIsXG4gICAgICB0YWdOYW1lOiAnbGknLFxuICAgICAgaWQ6ICdyZXNvdXJjZV8nICsgcmVzb3VyY2UuaWQsXG4gICAgICBjbGFzc05hbWU6ICdyZXNvdXJjZScsXG4gICAgICBhdXRoczogYXV0aHMsXG4gICAgICBzd2FnZ2VyT3B0aW9uczogdGhpcy5vcHRpb25zLnN3YWdnZXJPcHRpb25zXG4gICAgfSk7XG4gICAgJCgnI3Jlc291cmNlcycsIHRoaXMuZWwpLmFwcGVuZChyZXNvdXJjZVZpZXcucmVuZGVyKCkuZWwpO1xuICB9LFxuXG4gIGNsZWFyOiBmdW5jdGlvbigpe1xuICAgICQodGhpcy5lbCkuaHRtbCgnJyk7XG4gIH0sXG5cbiAgb25MaW5rQ2xpY2s6IGZ1bmN0aW9uIChlKSB7XG4gICAgdmFyIGVsID0gZS50YXJnZXQ7XG5cbiAgICBpZiAoZWwudGFnTmFtZSA9PT0gJ0EnICYmIGVsLmhyZWYgJiYgIWVsLnRhcmdldCkge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHdpbmRvdy5vcGVuKGVsLmhyZWYsICdfYmxhbmsnKTtcbiAgICB9XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5Td2FnZ2VyVWkuTW9kZWxzLk9hdXRoMk1vZGVsID0gQmFja2JvbmUuTW9kZWwuZXh0ZW5kKHtcbiAgICBkZWZhdWx0czoge1xuICAgICAgICBzY29wZXM6IHt9LFxuICAgICAgICBpc1Bhc3N3b3JkRmxvdzogZmFsc2UsXG4gICAgICAgIGNsaWVudEF1dGhlbnRpY2F0aW9uVHlwZTogJ25vbmUnXG4gICAgfSxcblxuICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYodGhpcy5hdHRyaWJ1dGVzICYmIHRoaXMuYXR0cmlidXRlcy5zY29wZXMpIHtcbiAgICAgICAgICAgIHZhciBhdHRyaWJ1dGVzID0gXy5jbG9uZURlZXAodGhpcy5hdHRyaWJ1dGVzKTtcbiAgICAgICAgICAgIHZhciBpLCBzY29wZXMgPSBbXTtcbiAgICAgICAgICAgIGZvcihpIGluIGF0dHJpYnV0ZXMuc2NvcGVzKSB7XG4gICAgICAgICAgICAgICAgdmFyIHNjb3BlID0gYXR0cmlidXRlcy5zY29wZXNbaV07XG4gICAgICAgICAgICAgICAgaWYodHlwZW9mIHNjb3BlLmRlc2NyaXB0aW9uID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgICAgICBzY29wZXNbc2NvcGVdID0gYXR0cmlidXRlcy5zY29wZXNbaV07XG4gICAgICAgICAgICAgICAgICAgIHNjb3Blcy5wdXNoKGF0dHJpYnV0ZXMuc2NvcGVzW2ldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhdHRyaWJ1dGVzLnNjb3BlcyA9IHNjb3BlcztcbiAgICAgICAgICAgIHRoaXMuYXR0cmlidXRlcyA9IGF0dHJpYnV0ZXM7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hdHRyaWJ1dGVzICYmIHRoaXMuYXR0cmlidXRlcy5mbG93KSB7XG4gICAgICAgICAgICB2YXIgZmxvdyA9IHRoaXMuYXR0cmlidXRlcy5mbG93O1xuICAgICAgICAgICAgdGhpcy5zZXQoJ2lzUGFzc3dvcmRGbG93JywgZmxvdyA9PT0gJ3Bhc3N3b3JkJyk7XG4gICAgICAgICAgICB0aGlzLnNldCgncmVxdWlyZUNsaWVudEF1dGhlbnRpY2F0aW9uJywgZmxvdyA9PT0gJ2FwcGxpY2F0aW9uJyk7XG4gICAgICAgICAgICB0aGlzLnNldCgnY2xpZW50QXV0aGVudGljYXRpb24nLCBmbG93ID09PSAncGFzc3dvcmQnIHx8IGZsb3cgPT09ICdhcHBsaWNhdGlvbicpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub24oJ2NoYW5nZScsIHRoaXMudmFsaWRhdGUpO1xuICAgIH0sXG5cbiAgICBzZXRTY29wZXM6IGZ1bmN0aW9uIChuYW1lLCB2YWwpIHtcbiAgICAgICAgdmFyIGF1dGggPSBfLmV4dGVuZCh7fSwgdGhpcy5hdHRyaWJ1dGVzKTtcbiAgICAgICAgdmFyIGluZGV4ID0gXy5maW5kSW5kZXgoYXV0aC5zY29wZXMsIGZ1bmN0aW9uKG8pIHtcbiAgICAgICAgICAgIHJldHVybiBvLnNjb3BlID09PSBuYW1lO1xuICAgICAgICB9KTtcbiAgICAgICAgYXV0aC5zY29wZXNbaW5kZXhdLmNoZWNrZWQgPSB2YWw7XG5cbiAgICAgICAgdGhpcy5zZXQoYXV0aCk7XG4gICAgICAgIHRoaXMudmFsaWRhdGUoKTtcbiAgICB9LFxuXG4gICAgdmFsaWRhdGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciB2YWxpZCA9IGZhbHNlO1xuICAgICAgaWYgKHRoaXMuZ2V0KCdpc1Bhc3N3b3JkRmxvdycpICYmXG4gICAgICAgICAgKCF0aGlzLmdldCgndXNlcm5hbWUnKSkpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmdldCgnY2xpZW50QXV0aGVudGljYXRpb25UeXBlJykgaW4gWydiYXNpYycsICdyZXF1ZXN0LWJvZHknXSAmJlxuICAgICAgICAgICghdGhpcy5nZXQoJ2NsaWVudElkJykpKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICB2YXIgc2NwID0gdGhpcy5nZXQoJ3Njb3BlcycpO1xuICAgICAgdmFyIGlkeCA9ICBfLmZpbmRJbmRleChzY3AsIGZ1bmN0aW9uIChvKSB7XG4gICAgICAgICByZXR1cm4gby5jaGVja2VkID09PSB0cnVlO1xuICAgICAgfSk7XG5cbiAgICAgIGlmKHNjcC5sZW5ndGggPiAwICYmIGlkeCA+PSAwKSB7XG4gICAgICAgICAgdmFsaWQgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBpZihzY3AubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdmFsaWQgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnNldCgndmFsaWQnLCB2YWxpZCk7XG5cbiAgICAgIHJldHVybiB2YWxpZDtcbiAgICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLlZpZXdzLk9hdXRoMlZpZXcgPSBCYWNrYm9uZS5WaWV3LmV4dGVuZCh7XG4gICAgZXZlbnRzOiB7XG4gICAgICAgICdjaGFuZ2UgLm9hdXRoLXNjb3BlJzogJ3Njb3BlQ2hhbmdlJyxcbiAgICAgICAgJ2NoYW5nZSAub2F1dGgtdXNlcm5hbWUnOiAnc2V0VXNlcm5hbWUnLFxuICAgICAgICAnY2hhbmdlIC5vYXV0aC1wYXNzd29yZCc6ICdzZXRQYXNzd29yZCcsXG4gICAgICAgICdjaGFuZ2UgLm9hdXRoLWNsaWVudC1hdXRoZW50aWNhdGlvbi10eXBlJzogJ3NldENsaWVudEF1dGhlbnRpY2F0aW9uVHlwZScsXG4gICAgICAgICdjaGFuZ2UgLm9hdXRoLWNsaWVudC1pZCc6ICdzZXRDbGllbnRJZCcsXG4gICAgICAgICdjaGFuZ2UgLm9hdXRoLWNsaWVudC1zZWNyZXQnOiAnc2V0Q2xpZW50U2VjcmV0J1xuICAgIH0sXG5cbiAgICB0ZW1wbGF0ZTogSGFuZGxlYmFycy50ZW1wbGF0ZXMub2F1dGgyLFxuXG4gICAgY2xzOiB7XG4gICAgICAgIGVycm9yOiAnZXJyb3InXG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLiRlbC5odG1sKHRoaXMudGVtcGxhdGUodGhpcy5tb2RlbC50b0pTT04oKSkpO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICBzY29wZUNoYW5nZTogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgdmFyIHZhbCA9ICQoZS50YXJnZXQpLnByb3AoJ2NoZWNrZWQnKTtcbiAgICAgICAgdmFyIHNjb3BlID0gJChlLnRhcmdldCkuZGF0YSgnc2NvcGUnKTtcblxuICAgICAgICB0aGlzLm1vZGVsLnNldFNjb3BlcyhzY29wZSwgdmFsKTtcbiAgICB9LFxuXG4gICAgc2V0VXNlcm5hbWU6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIHZhciB2YWw9ICQoZS50YXJnZXQpLnZhbCgpO1xuICAgICAgICB0aGlzLm1vZGVsLnNldCgndXNlcm5hbWUnLCB2YWwpO1xuICAgICAgICBpZiAodmFsKSB7XG4gICAgICAgICAgICAkKGUudGFyZ2V0KS5yZW1vdmVDbGFzcyh0aGlzLmNscy5lcnJvcik7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgc2V0UGFzc3dvcmQ6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIHRoaXMubW9kZWwuc2V0KCdwYXNzd29yZCcsICQoZS50YXJnZXQpLnZhbCgpKTtcbiAgICB9LFxuXG4gICAgc2V0Q2xpZW50QXV0aGVudGljYXRpb25UeXBlOiBmdW5jdGlvbiAoZSkge1xuICAgICAgICB2YXIgdHlwZSA9ICQoZS50YXJnZXQpLnZhbCgpO1xuICAgICAgICB2YXIgJGVsID0gdGhpcy4kZWw7XG4gICAgICAgIHRoaXMubW9kZWwuc2V0KCdjbGllbnRBdXRoZW50aWNhdGlvblR5cGUnLCB0eXBlKTtcblxuICAgICAgICBzd2l0Y2godHlwZSkge1xuICAgICAgICAgICAgY2FzZSAnbm9uZSc6XG4gICAgICAgICAgICAgICAgJGVsLmZpbmQoJy5vYXV0aC1jbGllbnQtYXV0aGVudGljYXRpb24nKS5oaWRlKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdiYXNpYyc6XG4gICAgICAgICAgICBjYXNlICdyZXF1ZXN0LWJvZHknOlxuICAgICAgICAgICAgICAgICRlbC5maW5kKCcub2F1dGgtY2xpZW50LWlkJykucmVtb3ZlQ2xhc3ModGhpcy5jbHMuZXJyb3IpO1xuICAgICAgICAgICAgICAgICRlbC5maW5kKCcub2F1dGgtY2xpZW50LWF1dGhlbnRpY2F0aW9uJykuc2hvdygpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIHNldENsaWVudElkOiBmdW5jdGlvbiAoZSkge1xuICAgICAgICB2YXIgdmFsID0gJChlLnRhcmdldCkudmFsKCk7XG4gICAgICAgIHRoaXMubW9kZWwuc2V0KCdjbGllbnRJZCcsIHZhbCk7XG4gICAgICAgIGlmICh2YWwpIHtcbiAgICAgICAgICAgICQoZS50YXJnZXQpLnJlbW92ZUNsYXNzKHRoaXMuY2xzLmVycm9yKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBzZXRDbGllbnRTZWNyZXQ6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIHRoaXMubW9kZWwuc2V0KCdjbGllbnRTZWNyZXQnLCAkKGUudGFyZ2V0KS52YWwoKSk7XG4gICAgICAgICQoZS50YXJnZXQpLnJlbW92ZUNsYXNzKCdlcnJvcicpO1xuICAgIH0sXG5cbiAgICBoaWdobGlnaHRJbnZhbGlkOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghdGhpcy5tb2RlbC5nZXQoJ3VzZXJuYW1lJykpIHtcbiAgICAgICAgICAgIHRoaXMuJGVsLmZpbmQoJy5vYXV0aC11c2VybmFtZScpLmFkZENsYXNzKHRoaXMuY2xzLmVycm9yKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhpcy5tb2RlbC5nZXQoJ2NsaWVudElkJykpIHtcbiAgICAgICAgICAgIHRoaXMuJGVsLmZpbmQoJy5vYXV0aC1jbGllbnQtaWQnKS5hZGRDbGFzcyh0aGlzLmNscy5lcnJvcik7XG4gICAgICAgIH1cbiAgICB9XG59KTsiLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5PcGVyYXRpb25WaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoe1xuICBpbnZvY2F0aW9uVXJsOiBudWxsLFxuXG4gIGV2ZW50czoge1xuICAgICdzdWJtaXQgLnNhbmRib3gnICAgICAgICAgOiAnc3VibWl0T3BlcmF0aW9uJyxcbiAgICAnY2xpY2sgLnN1Ym1pdCcgICAgICAgICAgIDogJ3N1Ym1pdE9wZXJhdGlvbicsXG4gICAgJ2NsaWNrIC5yZXNwb25zZV9oaWRlcicgICA6ICdoaWRlUmVzcG9uc2UnLFxuICAgICdjbGljayAudG9nZ2xlT3BlcmF0aW9uJyAgOiAndG9nZ2xlT3BlcmF0aW9uQ29udGVudCcsXG4gICAgJ21vdXNlZW50ZXIgLmFwaS1pYycgICAgICA6ICdtb3VzZUVudGVyJyxcbiAgICAnZGJsY2xpY2sgLmN1cmwnICAgICAgICAgIDogJ3NlbGVjdFRleHQnLFxuICAgICdjaGFuZ2UgW25hbWU9cmVzcG9uc2VDb250ZW50VHlwZV0nIDogJ3Nob3dTbmlwcGV0J1xuICB9LFxuXG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uKG9wdHMpIHtcbiAgICBvcHRzID0gb3B0cyB8fCB7fTtcbiAgICB0aGlzLnJvdXRlciA9IG9wdHMucm91dGVyO1xuICAgIHRoaXMuYXV0aHMgPSBvcHRzLmF1dGhzO1xuICAgIHRoaXMucGFyZW50SWQgPSB0aGlzLm1vZGVsLnBhcmVudElkO1xuICAgIHRoaXMubmlja25hbWUgPSB0aGlzLm1vZGVsLm5pY2tuYW1lO1xuICAgIHRoaXMubW9kZWwuZW5jb2RlZFBhcmVudElkID0gZW5jb2RlVVJJQ29tcG9uZW50KHRoaXMucGFyZW50SWQpO1xuXG4gICAgaWYgKG9wdHMuc3dhZ2dlck9wdGlvbnMpIHtcbiAgICAgIHRoaXMubW9kZWwuZGVmYXVsdFJlbmRlcmluZyA9IG9wdHMuc3dhZ2dlck9wdGlvbnMuZGVmYXVsdE1vZGVsUmVuZGVyaW5nO1xuXG4gICAgICBpZiAob3B0cy5zd2FnZ2VyT3B0aW9ucy5zaG93UmVxdWVzdEhlYWRlcnMpIHtcbiAgICAgICAgdGhpcy5tb2RlbC5zaG93UmVxdWVzdEhlYWRlcnMgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAob3B0cy5zd2FnZ2VyT3B0aW9ucy5zaG93T3BlcmF0aW9uSWRzKSB7XG4gICAgICAgIHRoaXMubW9kZWwuc2hvd09wZXJhdGlvbklkcyA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9LFxuXG4gIHNlbGVjdFRleHQ6IGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGRvYyA9IGRvY3VtZW50LFxuICAgICAgICB0ZXh0ID0gZXZlbnQudGFyZ2V0LmZpcnN0Q2hpbGQsXG4gICAgICAgIHJhbmdlLFxuICAgICAgICBzZWxlY3Rpb247XG4gICAgaWYgKGRvYy5ib2R5LmNyZWF0ZVRleHRSYW5nZSkge1xuICAgICAgcmFuZ2UgPSBkb2N1bWVudC5ib2R5LmNyZWF0ZVRleHRSYW5nZSgpO1xuICAgICAgcmFuZ2UubW92ZVRvRWxlbWVudFRleHQodGV4dCk7XG4gICAgICByYW5nZS5zZWxlY3QoKTtcbiAgICB9IGVsc2UgaWYgKHdpbmRvdy5nZXRTZWxlY3Rpb24pIHtcbiAgICAgIHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICAgIHJhbmdlID0gZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKTtcbiAgICAgIHJhbmdlLnNlbGVjdE5vZGVDb250ZW50cyh0ZXh0KTtcbiAgICAgIHNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICAgIHNlbGVjdGlvbi5hZGRSYW5nZShyYW5nZSk7XG4gICAgfVxuICB9LFxuXG4gIG1vdXNlRW50ZXI6IGZ1bmN0aW9uKGUpIHtcbiAgICB2YXIgZWxlbSA9ICQodGhpcy5lbCkuZmluZCgnLmNvbnRlbnQnKTtcbiAgICB2YXIgeCA9IGUucGFnZVg7XG4gICAgdmFyIHkgPSBlLnBhZ2VZO1xuICAgIHZhciBzY1ggPSAkKHdpbmRvdykuc2Nyb2xsTGVmdCgpO1xuICAgIHZhciBzY1kgPSAkKHdpbmRvdykuc2Nyb2xsVG9wKCk7XG4gICAgdmFyIHNjTWF4WCA9IHNjWCArICQod2luZG93KS53aWR0aCgpO1xuICAgIHZhciBzY01heFkgPSBzY1kgKyAkKHdpbmRvdykuaGVpZ2h0KCk7XG4gICAgdmFyIHdkID0gZWxlbS53aWR0aCgpO1xuICAgIHZhciBoZ2ggPSBlbGVtLmhlaWdodCgpO1xuXG4gICAgaWYgKHggKyB3ZCA+IHNjTWF4WCkge1xuICAgICAgeCA9IHNjTWF4WCAtIHdkO1xuICAgIH1cblxuICAgIGlmICh4IDwgc2NYKSB7XG4gICAgICB4ID0gc2NYO1xuICAgIH1cblxuICAgIGlmICh5ICsgaGdoID4gc2NNYXhZKSB7XG4gICAgICB5ID0gc2NNYXhZIC0gaGdoO1xuICAgIH1cblxuICAgIGlmICh5IDwgc2NZKSB7XG4gICAgICB5ID0gc2NZO1xuICAgIH1cblxuICAgIHZhciBwb3MgPSB7fTtcbiAgICBwb3MudG9wID0geTtcbiAgICBwb3MubGVmdCA9IHg7XG4gICAgZWxlbS5jc3MocG9zKTtcbiAgfSxcblxuICAvLyBOb3RlOiBjb3BpZWQgZnJvbSBDb2ZmZWVTY3JpcHQgY29tcGlsZWQgZmlsZVxuICAvLyBUT0RPOiByZWZhY3RvclxuICByZW5kZXI6IGZ1bmN0aW9uKCkge1xuICAgIHZhciBhLCBhdXRoLCBhdXRocywgY29kZSwgY29udGVudFR5cGVNb2RlbCwgaXNNZXRob2RTdWJtaXNzaW9uU3VwcG9ydGVkLCBrLCBrZXksIGwsIGxlbiwgbGVuMSwgbGVuMiwgbGVuMywgbGVuNCwgbSwgbW9kZWxBdXRocywgbiwgbywgcCwgcGFyYW0sIHEsIHJlZiwgcmVmMSwgcmVmMiwgcmVmMywgcmVmNCwgcmVmNSwgcmVzcG9uc2VDb250ZW50VHlwZVZpZXcsIHJlc3BvbnNlU2lnbmF0dXJlVmlldywgc2NoZW1hLCBzY2hlbWFPYmosIHNjb3BlSW5kZXgsIHNpZ25hdHVyZU1vZGVsLCBzdGF0dXNDb2RlLCBzdWNjZXNzUmVzcG9uc2UsIHR5cGUsIHYsIHZhbHVlLCBwcm9kdWNlcywgaXNYTUwsIGlzSlNPTjtcbiAgICBpc01ldGhvZFN1Ym1pc3Npb25TdXBwb3J0ZWQgPSBqUXVlcnkuaW5BcnJheSh0aGlzLm1vZGVsLm1ldGhvZCwgdGhpcy5tb2RlbC5zdXBwb3J0ZWRTdWJtaXRNZXRob2RzKCkpID49IDA7XG4gICAgaWYgKCFpc01ldGhvZFN1Ym1pc3Npb25TdXBwb3J0ZWQpIHtcbiAgICAgIHRoaXMubW9kZWwuaXNSZWFkT25seSA9IHRydWU7XG4gICAgfVxuICAgIHRoaXMubW9kZWwuZGVzY3JpcHRpb24gPSB0aGlzLm1vZGVsLmRlc2NyaXB0aW9uIHx8IHRoaXMubW9kZWwubm90ZXM7XG4gICAgdGhpcy5tb2RlbC5vYXV0aCA9IG51bGw7XG4gICAgbW9kZWxBdXRocyA9IHRoaXMubW9kZWwuYXV0aG9yaXphdGlvbnMgfHwgdGhpcy5tb2RlbC5zZWN1cml0eTtcbiAgICBpZiAobW9kZWxBdXRocykge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkobW9kZWxBdXRocykpIHtcbiAgICAgICAgZm9yIChsID0gMCwgbGVuID0gbW9kZWxBdXRocy5sZW5ndGg7IGwgPCBsZW47IGwrKykge1xuICAgICAgICAgIGF1dGhzID0gbW9kZWxBdXRoc1tsXTtcbiAgICAgICAgICBmb3IgKGtleSBpbiBhdXRocykge1xuICAgICAgICAgICAgZm9yIChhIGluIHRoaXMuYXV0aHMpIHtcbiAgICAgICAgICAgICAgYXV0aCA9IHRoaXMuYXV0aHNbYV07XG4gICAgICAgICAgICAgIGlmIChrZXkgPT09IGF1dGgubmFtZSkge1xuICAgICAgICAgICAgICAgIGlmIChhdXRoLnR5cGUgPT09ICdvYXV0aDInKSB7XG4gICAgICAgICAgICAgICAgICB0aGlzLm1vZGVsLm9hdXRoID0ge307XG4gICAgICAgICAgICAgICAgICB0aGlzLm1vZGVsLm9hdXRoLnNjb3BlcyA9IFtdO1xuICAgICAgICAgICAgICAgICAgcmVmMSA9IGF1dGgudmFsdWUuc2NvcGVzO1xuICAgICAgICAgICAgICAgICAgZm9yIChrIGluIHJlZjEpIHtcbiAgICAgICAgICAgICAgICAgICAgdiA9IHJlZjFba107XG4gICAgICAgICAgICAgICAgICAgIHNjb3BlSW5kZXggPSBhdXRoc1trZXldLmluZGV4T2Yoayk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzY29wZUluZGV4ID49IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICBvID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2NvcGU6IGssXG4gICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogdlxuICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5tb2RlbC5vYXV0aC5zY29wZXMucHVzaChvKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm9yIChrIGluIG1vZGVsQXV0aHMpIHtcbiAgICAgICAgICB2ID0gbW9kZWxBdXRoc1trXTtcbiAgICAgICAgICBpZiAoayA9PT0gJ29hdXRoMicpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLm1vZGVsLm9hdXRoID09PSBudWxsKSB7XG4gICAgICAgICAgICAgIHRoaXMubW9kZWwub2F1dGggPSB7fTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLm1vZGVsLm9hdXRoLnNjb3BlcyA9PT0gdm9pZCAwKSB7XG4gICAgICAgICAgICAgIHRoaXMubW9kZWwub2F1dGguc2NvcGVzID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKG0gPSAwLCBsZW4xID0gdi5sZW5ndGg7IG0gPCBsZW4xOyBtKyspIHtcbiAgICAgICAgICAgICAgbyA9IHZbbV07XG4gICAgICAgICAgICAgIHRoaXMubW9kZWwub2F1dGguc2NvcGVzLnB1c2gobyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdGhpcy5tb2RlbC5yZXNwb25zZXMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB0aGlzLm1vZGVsLnJlc3BvbnNlTWVzc2FnZXMgPSBbXTtcbiAgICAgIHJlZjIgPSB0aGlzLm1vZGVsLnJlc3BvbnNlcztcbiAgICAgIGZvciAoY29kZSBpbiByZWYyKSB7XG4gICAgICAgIHZhbHVlID0gcmVmMltjb2RlXTtcbiAgICAgICAgc2NoZW1hID0gbnVsbDtcbiAgICAgICAgc2NoZW1hT2JqID0gdGhpcy5tb2RlbC5yZXNwb25zZXNbY29kZV0uc2NoZW1hO1xuICAgICAgICBpZiAoc2NoZW1hT2JqICYmIHNjaGVtYU9iai4kcmVmKSB7XG4gICAgICAgICAgc2NoZW1hID0gc2NoZW1hT2JqLiRyZWY7XG4gICAgICAgICAgaWYgKHNjaGVtYS5pbmRleE9mKCcjL2RlZmluaXRpb25zLycpICE9PSAtMSkge1xuICAgICAgICAgICAgc2NoZW1hID0gc2NoZW1hLnJlcGxhY2UoL14uKiNcXC9kZWZpbml0aW9uc1xcLy8sICcnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5tb2RlbC5yZXNwb25zZU1lc3NhZ2VzLnB1c2goe1xuICAgICAgICAgIGNvZGU6IGNvZGUsXG4gICAgICAgICAgbWVzc2FnZTogdmFsdWUuZGVzY3JpcHRpb24sXG4gICAgICAgICAgcmVzcG9uc2VNb2RlbDogc2NoZW1hLFxuICAgICAgICAgIGhlYWRlcnM6IHZhbHVlLmhlYWRlcnMsXG4gICAgICAgICAgc2NoZW1hOiBzY2hlbWFPYmpcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdGhpcy5tb2RlbC5yZXNwb25zZU1lc3NhZ2VzID09PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhpcy5tb2RlbC5yZXNwb25zZU1lc3NhZ2VzID0gW107XG4gICAgfVxuICAgIHNpZ25hdHVyZU1vZGVsID0gbnVsbDtcbiAgICBwcm9kdWNlcyA9IHRoaXMubW9kZWwucHJvZHVjZXM7XG4gICAgaXNYTUwgPSB0aGlzLmNvbnRhaW5zKHByb2R1Y2VzLCAneG1sJyk7XG4gICAgaXNKU09OID0gaXNYTUwgPyB0aGlzLmNvbnRhaW5zKHByb2R1Y2VzLCAnanNvbicpIDogdHJ1ZTtcblxuICAgIGlmICh0aGlzLm1vZGVsLnN1Y2Nlc3NSZXNwb25zZSkge1xuICAgICAgc3VjY2Vzc1Jlc3BvbnNlID0gdGhpcy5tb2RlbC5zdWNjZXNzUmVzcG9uc2U7XG4gICAgICBmb3IgKGtleSBpbiBzdWNjZXNzUmVzcG9uc2UpIHtcbiAgICAgICAgdmFsdWUgPSBzdWNjZXNzUmVzcG9uc2Vba2V5XTtcbiAgICAgICAgdGhpcy5tb2RlbC5zdWNjZXNzQ29kZSA9IGtleTtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIHZhbHVlLmNyZWF0ZUpTT05TYW1wbGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICB0aGlzLm1vZGVsLnN1Y2Nlc3NEZXNjcmlwdGlvbiA9IHZhbHVlLmRlc2NyaXB0aW9uO1xuICAgICAgICAgIHRoaXMubW9kZWwuaGVhZGVycyA9IHRoaXMucGFyc2VSZXNwb25zZUhlYWRlcnModmFsdWUuaGVhZGVycyk7XG4gICAgICAgICAgc2lnbmF0dXJlTW9kZWwgPSB7XG4gICAgICAgICAgICBzYW1wbGVKU09OOiBpc0pTT04gPyBKU09OLnN0cmluZ2lmeShTd2FnZ2VyVWkucGFydGlhbHMuc2lnbmF0dXJlLmNyZWF0ZUpTT05TYW1wbGUodmFsdWUpLCB2b2lkIDAsIDIpIDogZmFsc2UsXG4gICAgICAgICAgICBpc1BhcmFtOiBmYWxzZSxcbiAgICAgICAgICAgIHNhbXBsZVhNTDogaXNYTUwgPyBTd2FnZ2VyVWkucGFydGlhbHMuc2lnbmF0dXJlLmNyZWF0ZVhNTFNhbXBsZSh2YWx1ZS5uYW1lLCB2YWx1ZS5kZWZpbml0aW9uLCB2YWx1ZS5tb2RlbHMpIDogZmFsc2UsXG4gICAgICAgICAgICBzaWduYXR1cmU6IFN3YWdnZXJVaS5wYXJ0aWFscy5zaWduYXR1cmUuZ2V0TW9kZWxTaWduYXR1cmUodmFsdWUubmFtZSwgdmFsdWUuZGVmaW5pdGlvbiwgdmFsdWUubW9kZWxzLCB2YWx1ZS5tb2RlbFByb3BlcnR5TWFjcm8pXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzaWduYXR1cmVNb2RlbCA9IHtcbiAgICAgICAgICAgIHNpZ25hdHVyZTogU3dhZ2dlclVpLnBhcnRpYWxzLnNpZ25hdHVyZS5nZXRQcmltaXRpdmVTaWduYXR1cmUodmFsdWUpXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodGhpcy5tb2RlbC5yZXNwb25zZUNsYXNzU2lnbmF0dXJlICYmIHRoaXMubW9kZWwucmVzcG9uc2VDbGFzc1NpZ25hdHVyZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHNpZ25hdHVyZU1vZGVsID0ge1xuICAgICAgICBzYW1wbGVKU09OOiB0aGlzLm1vZGVsLnJlc3BvbnNlU2FtcGxlSlNPTixcbiAgICAgICAgaXNQYXJhbTogZmFsc2UsXG4gICAgICAgIHNpZ25hdHVyZTogdGhpcy5tb2RlbC5yZXNwb25zZUNsYXNzU2lnbmF0dXJlXG4gICAgICB9O1xuICAgIH1cbiAgICAkKHRoaXMuZWwpLmh0bWwoSGFuZGxlYmFycy50ZW1wbGF0ZXMub3BlcmF0aW9uKHRoaXMubW9kZWwpKTtcbiAgICBpZiAoc2lnbmF0dXJlTW9kZWwpIHtcbiAgICAgIHNpZ25hdHVyZU1vZGVsLmRlZmF1bHRSZW5kZXJpbmcgPSB0aGlzLm1vZGVsLmRlZmF1bHRSZW5kZXJpbmc7XG4gICAgICByZXNwb25zZVNpZ25hdHVyZVZpZXcgPSBuZXcgU3dhZ2dlclVpLlZpZXdzLlNpZ25hdHVyZVZpZXcoe1xuICAgICAgICBtb2RlbDogc2lnbmF0dXJlTW9kZWwsXG4gICAgICAgIHJvdXRlcjogdGhpcy5yb3V0ZXIsXG4gICAgICAgIHRhZ05hbWU6ICdkaXYnXG4gICAgICB9KTtcbiAgICAgICQoJy5tb2RlbC1zaWduYXR1cmUnLCAkKHRoaXMuZWwpKS5hcHBlbmQocmVzcG9uc2VTaWduYXR1cmVWaWV3LnJlbmRlcigpLmVsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5tb2RlbC5yZXNwb25zZUNsYXNzU2lnbmF0dXJlID0gJ3N0cmluZyc7XG4gICAgICAkKCcubW9kZWwtc2lnbmF0dXJlJywgJCh0aGlzLmVsKSkuaHRtbCh0aGlzLm1vZGVsLnR5cGUpO1xuICAgIH1cbiAgICBjb250ZW50VHlwZU1vZGVsID0ge1xuICAgICAgaXNQYXJhbTogZmFsc2VcbiAgICB9O1xuICAgIGNvbnRlbnRUeXBlTW9kZWwuY29uc3VtZXMgPSB0aGlzLm1vZGVsLmNvbnN1bWVzO1xuICAgIGNvbnRlbnRUeXBlTW9kZWwucHJvZHVjZXMgPSB0aGlzLm1vZGVsLnByb2R1Y2VzO1xuICAgIHJlZjMgPSB0aGlzLm1vZGVsLnBhcmFtZXRlcnM7XG4gICAgZm9yIChuID0gMCwgbGVuMiA9IHJlZjMubGVuZ3RoOyBuIDwgbGVuMjsgbisrKSB7XG4gICAgICBwYXJhbSA9IHJlZjNbbl07XG4gICAgICB0eXBlID0gcGFyYW0udHlwZSB8fCBwYXJhbS5kYXRhVHlwZSB8fCAnJztcbiAgICAgIGlmICh0eXBlb2YgdHlwZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgc2NoZW1hID0gcGFyYW0uc2NoZW1hO1xuICAgICAgICBpZiAoc2NoZW1hICYmIHNjaGVtYS4kcmVmKSB7XG4gICAgICAgICAgcmVmID0gc2NoZW1hLiRyZWY7XG4gICAgICAgICAgaWYgKHJlZi5pbmRleE9mKCcjL2RlZmluaXRpb25zLycpID09PSAwKSB7XG4gICAgICAgICAgICB0eXBlID0gcmVmLnN1YnN0cmluZygnIy9kZWZpbml0aW9ucy8nLmxlbmd0aCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHR5cGUgPSByZWY7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAodHlwZSAmJiB0eXBlLnRvTG93ZXJDYXNlKCkgPT09ICdmaWxlJykge1xuICAgICAgICBpZiAoIWNvbnRlbnRUeXBlTW9kZWwuY29uc3VtZXMpIHtcbiAgICAgICAgICBjb250ZW50VHlwZU1vZGVsLmNvbnN1bWVzID0gJ211bHRpcGFydC9mb3JtLWRhdGEnO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBwYXJhbS50eXBlID0gdHlwZTtcbiAgICB9XG4gICAgcmVzcG9uc2VDb250ZW50VHlwZVZpZXcgPSBuZXcgU3dhZ2dlclVpLlZpZXdzLlJlc3BvbnNlQ29udGVudFR5cGVWaWV3KHtcbiAgICAgIG1vZGVsOiBjb250ZW50VHlwZU1vZGVsLFxuICAgICAgcm91dGVyOiB0aGlzLnJvdXRlclxuICAgIH0pO1xuICAgICQoJy5yZXNwb25zZS1jb250ZW50LXR5cGUnLCAkKHRoaXMuZWwpKS5hcHBlbmQocmVzcG9uc2VDb250ZW50VHlwZVZpZXcucmVuZGVyKCkuZWwpO1xuICAgIHJlZjQgPSB0aGlzLm1vZGVsLnBhcmFtZXRlcnM7XG4gICAgZm9yIChwID0gMCwgbGVuMyA9IHJlZjQubGVuZ3RoOyBwIDwgbGVuMzsgcCsrKSB7XG4gICAgICBwYXJhbSA9IHJlZjRbcF07XG4gICAgICB0aGlzLmFkZFBhcmFtZXRlcihwYXJhbSwgY29udGVudFR5cGVNb2RlbC5jb25zdW1lcyk7XG4gICAgfVxuICAgIHJlZjUgPSB0aGlzLm1vZGVsLnJlc3BvbnNlTWVzc2FnZXM7XG4gICAgZm9yIChxID0gMCwgbGVuNCA9IHJlZjUubGVuZ3RoOyBxIDwgbGVuNDsgcSsrKSB7XG4gICAgICBzdGF0dXNDb2RlID0gcmVmNVtxXTtcbiAgICAgIHN0YXR1c0NvZGUuaXNYTUwgPSBpc1hNTDtcbiAgICAgIHN0YXR1c0NvZGUuaXNKU09OID0gaXNKU09OO1xuICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKHN0YXR1c0NvZGUuaGVhZGVycykpIHtcbiAgICAgICAgc3RhdHVzQ29kZS5oZWFkZXJzID0gdGhpcy5wYXJzZUhlYWRlcnNUeXBlKHN0YXR1c0NvZGUuaGVhZGVycyk7XG4gICAgICB9XG4gICAgICB0aGlzLmFkZFN0YXR1c0NvZGUoc3RhdHVzQ29kZSk7XG4gICAgfVxuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkodGhpcy5tb2RlbC5zZWN1cml0eSkpIHtcbiAgICAgIHZhciBhdXRoc01vZGVsID0gU3dhZ2dlclVpLnV0aWxzLnBhcnNlU2VjdXJpdHlEZWZpbml0aW9ucyh0aGlzLm1vZGVsLnNlY3VyaXR5LCB0aGlzLm1vZGVsLnBhcmVudC5zZWN1cml0eURlZmluaXRpb25zKTtcblxuICAgICAgYXV0aHNNb2RlbC5pc0xvZ291dCA9ICFfLmlzRW1wdHkodGhpcy5tb2RlbC5jbGllbnRBdXRob3JpemF0aW9ucy5hdXRoeik7XG4gICAgICB0aGlzLmF1dGhWaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5BdXRoQnV0dG9uVmlldyh7XG4gICAgICAgIGRhdGE6IGF1dGhzTW9kZWwsXG4gICAgICAgIHJvdXRlcjogdGhpcy5yb3V0ZXIsXG4gICAgICAgIGlzT3BlcmF0aW9uOiB0cnVlLFxuICAgICAgICBtb2RlbDoge1xuICAgICAgICAgIHNjb3BlczogYXV0aHNNb2RlbC5zY29wZXNcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICB0aGlzLiQoJy5hdXRob3JpemUtd3JhcHBlcicpLmFwcGVuZCh0aGlzLmF1dGhWaWV3LnJlbmRlcigpLmVsKTtcbiAgICB9XG5cbiAgICB0aGlzLnNob3dTbmlwcGV0KCk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG5cbiAgcGFyc2VIZWFkZXJzVHlwZTogZnVuY3Rpb24gKGhlYWRlcnMpIHtcbiAgICB2YXIgbWFwID0ge1xuICAgICAgJ3N0cmluZyc6IHtcbiAgICAgICAgJ2RhdGUtdGltZSc6ICdkYXRlVGltZScsXG4gICAgICAgICdkYXRlJyAgICAgOiAnZGF0ZSdcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgXy5mb3JFYWNoKGhlYWRlcnMsIGZ1bmN0aW9uIChoZWFkZXIpIHtcbiAgICAgIHZhciB2YWx1ZTtcbiAgICAgIGhlYWRlciA9IGhlYWRlciB8fCB7fTtcbiAgICAgIHZhbHVlID0gbWFwW2hlYWRlci50eXBlXSAmJiBtYXBbaGVhZGVyLnR5cGVdW2hlYWRlci5mb3JtYXRdO1xuICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKHZhbHVlKSkge1xuICAgICAgICBoZWFkZXIudHlwZSA9IHZhbHVlO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGhlYWRlcnM7XG4gIH0sXG5cbiAgY29udGFpbnM6IGZ1bmN0aW9uIChwcm9kdWNlcywgdHlwZSkge1xuICAgIHJldHVybiBwcm9kdWNlcy5maWx0ZXIoZnVuY3Rpb24gKHZhbCkge1xuICAgICAgaWYgKHZhbC5pbmRleE9mKHR5cGUpID4gLTEpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfSkubGVuZ3RoO1xuICB9LFxuXG4gIHBhcnNlUmVzcG9uc2VIZWFkZXJzOiBmdW5jdGlvbiAoZGF0YSkge1xuICAgIHZhciBIRUFERVJTX1NFUEFSQVRPUiA9ICc7ICc7XG4gICAgdmFyIGhlYWRlcnMgPSBfLmNsb25lKGRhdGEpO1xuXG4gICAgXy5mb3JFYWNoKGhlYWRlcnMsIGZ1bmN0aW9uIChoZWFkZXIpIHtcbiAgICAgIHZhciBvdGhlciA9IFtdO1xuICAgICAgXy5mb3JFYWNoKGhlYWRlciwgZnVuY3Rpb24gKHZhbHVlLCBrZXkpIHtcbiAgICAgICAgdmFyIHByb3BlcnRpZXMgPSBbJ3R5cGUnLCAnZGVzY3JpcHRpb24nXTtcbiAgICAgICAgaWYgKHByb3BlcnRpZXMuaW5kZXhPZihrZXkudG9Mb3dlckNhc2UoKSkgPT09IC0xKSB7XG4gICAgICAgICAgb3RoZXIucHVzaChrZXkgKyAnOiAnICsgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgb3RoZXIuam9pbihIRUFERVJTX1NFUEFSQVRPUik7XG4gICAgICBoZWFkZXIub3RoZXIgPSBvdGhlcjtcbiAgICB9KTtcblxuICAgIHJldHVybiBoZWFkZXJzO1xuICB9LFxuXG4gIGFkZFBhcmFtZXRlcjogZnVuY3Rpb24ocGFyYW0sIGNvbnN1bWVzKSB7XG4gICAgLy8gUmVuZGVyIGEgcGFyYW1ldGVyXG4gICAgcGFyYW0uY29uc3VtZXMgPSBjb25zdW1lcztcbiAgICBwYXJhbS5kZWZhdWx0UmVuZGVyaW5nID0gdGhpcy5tb2RlbC5kZWZhdWx0UmVuZGVyaW5nO1xuXG4gICAgLy8gQ29weSB0aGlzIHBhcmFtIEpTT04gc3BlYyBzbyB0aGF0IGl0IHdpbGwgYmUgYXZhaWxhYmxlIGZvciBKc29uRWRpdG9yXG4gICAgaWYocGFyYW0uc2NoZW1hKXtcbiAgICAgICQuZXh0ZW5kKHRydWUsIHBhcmFtLnNjaGVtYSwgdGhpcy5tb2RlbC5kZWZpbml0aW9uc1twYXJhbS50eXBlXSk7XG4gICAgICBwYXJhbS5zY2hlbWEuZGVmaW5pdGlvbnMgPSB0aGlzLm1vZGVsLmRlZmluaXRpb25zO1xuICAgICAgLy8gVGhpcyBpcyByZXF1aXJlZCBmb3IgSnNvbkVkaXRvciB0byBkaXNwbGF5IHRoZSByb290IHByb3Blcmx5XG4gICAgICBpZighcGFyYW0uc2NoZW1hLnR5cGUpe1xuICAgICAgICBwYXJhbS5zY2hlbWEudHlwZSA9ICdvYmplY3QnO1xuICAgICAgfVxuICAgICAgLy8gVGhpcyBpcyB0aGUgdGl0bGUgdGhhdCB3aWxsIGJlIHVzZWQgYnkgSnNvbkVkaXRvciBmb3IgdGhlIHJvb3RcbiAgICAgIC8vIFNpbmNlIHdlIGFscmVhZHkgZGlzcGxheSB0aGUgcGFyYW1ldGVyJ3MgbmFtZSBpbiB0aGUgUGFyYW1ldGVyIGNvbHVtblxuICAgICAgLy8gV2Ugc2V0IHRoaXMgdG8gc3BhY2UsIHdlIGNhbid0IHNldCBpdCB0byBudWxsIG9yIHNwYWNlIG90aGVyd2lzZSBKc29uRWRpdG9yXG4gICAgICAvLyB3aWxsIHJlcGxhY2UgaXQgd2l0aCB0aGUgdGV4dCBcInJvb3RcIiB3aGljaCB3b24ndCBsb29rIGdvb2Qgb24gc2NyZWVuXG4gICAgICBpZighcGFyYW0uc2NoZW1hLnRpdGxlKXtcbiAgICAgICAgcGFyYW0uc2NoZW1hLnRpdGxlID0gJyAnO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBwYXJhbVZpZXcgPSBuZXcgU3dhZ2dlclVpLlZpZXdzLlBhcmFtZXRlclZpZXcoe1xuICAgICAgbW9kZWw6IHBhcmFtLFxuICAgICAgdGFnTmFtZTogJ3RyJyxcbiAgICAgIHJlYWRPbmx5OiB0aGlzLm1vZGVsLmlzUmVhZE9ubHksXG4gICAgICBzd2FnZ2VyT3B0aW9uczogdGhpcy5vcHRpb25zLnN3YWdnZXJPcHRpb25zXG4gICAgfSk7XG4gICAgJCgnLm9wZXJhdGlvbi1wYXJhbXMnLCAkKHRoaXMuZWwpKS5hcHBlbmQocGFyYW1WaWV3LnJlbmRlcigpLmVsKTtcbiAgfSxcblxuICBhZGRTdGF0dXNDb2RlOiBmdW5jdGlvbihzdGF0dXNDb2RlKSB7XG4gICAgLy8gUmVuZGVyIHN0YXR1cyBjb2Rlc1xuICAgIHN0YXR1c0NvZGUuZGVmYXVsdFJlbmRlcmluZyA9IHRoaXMubW9kZWwuZGVmYXVsdFJlbmRlcmluZztcbiAgICB2YXIgc3RhdHVzQ29kZVZpZXcgPSBuZXcgU3dhZ2dlclVpLlZpZXdzLlN0YXR1c0NvZGVWaWV3KHtcbiAgICAgIG1vZGVsOiBzdGF0dXNDb2RlLFxuICAgICAgdGFnTmFtZTogJ3RyJyxcbiAgICAgIHJvdXRlcjogdGhpcy5yb3V0ZXJcbiAgICB9KTtcbiAgICAkKCcub3BlcmF0aW9uLXN0YXR1cycsICQodGhpcy5lbCkpLmFwcGVuZChzdGF0dXNDb2RlVmlldy5yZW5kZXIoKS5lbCk7XG4gIH0sXG5cbiAgLy8gTm90ZTogY29waWVkIGZyb20gQ29mZmVlU2NyaXB0IGNvbXBpbGVkIGZpbGVcbiAgLy8gVE9ETzogcmVkYWN0b3JcbiAgc3VibWl0T3BlcmF0aW9uOiBmdW5jdGlvbihlKSB7XG4gICAgdmFyIGVycm9yX2ZyZWUsIGZvcm0sIGlzRmlsZVVwbG9hZCwgbWFwLCBvcHRzO1xuICAgIGlmIChlICE9PSBudWxsKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICAgIGZvcm0gPSAkKCcuc2FuZGJveCcsICQodGhpcy5lbCkpO1xuICAgIGVycm9yX2ZyZWUgPSB0cnVlO1xuICAgIGZvcm0uZmluZCgnaW5wdXQucmVxdWlyZWQnKS5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgJCh0aGlzKS5yZW1vdmVDbGFzcygnZXJyb3InKTtcbiAgICAgIGlmIChqUXVlcnkudHJpbSgkKHRoaXMpLnZhbCgpKSA9PT0gJycpIHtcbiAgICAgICAgJCh0aGlzKS5hZGRDbGFzcygnZXJyb3InKTtcbiAgICAgICAgJCh0aGlzKS53aWdnbGUoe1xuICAgICAgICAgIGNhbGxiYWNrOiAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgJChfdGhpcykuZm9jdXMoKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSkodGhpcylcbiAgICAgICAgfSk7XG4gICAgICAgIGVycm9yX2ZyZWUgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBmb3JtLmZpbmQoJ3RleHRhcmVhLnJlcXVpcmVkOnZpc2libGUnKS5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgJCh0aGlzKS5yZW1vdmVDbGFzcygnZXJyb3InKTtcbiAgICAgIGlmIChqUXVlcnkudHJpbSgkKHRoaXMpLnZhbCgpKSA9PT0gJycpIHtcbiAgICAgICAgJCh0aGlzKS5hZGRDbGFzcygnZXJyb3InKTtcbiAgICAgICAgJCh0aGlzKS53aWdnbGUoe1xuICAgICAgICAgIGNhbGxiYWNrOiAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgcmV0dXJuICQoX3RoaXMpLmZvY3VzKCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pKHRoaXMpXG4gICAgICAgIH0pO1xuICAgICAgICBlcnJvcl9mcmVlID0gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gICAgZm9ybS5maW5kKCdzZWxlY3QucmVxdWlyZWQnKS5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgJCh0aGlzKS5yZW1vdmVDbGFzcygnZXJyb3InKTtcbiAgICAgIGlmICh0aGlzLnNlbGVjdGVkSW5kZXggPT09IC0xKSB7XG4gICAgICAgICQodGhpcykuYWRkQ2xhc3MoJ2Vycm9yJyk7XG4gICAgICAgICQodGhpcykud2lnZ2xlKHtcbiAgICAgICAgICBjYWxsYmFjazogKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICQoX3RoaXMpLmZvY3VzKCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pKHRoaXMpXG4gICAgICAgIH0pO1xuICAgICAgICBlcnJvcl9mcmVlID0gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gICAgaWYgKGVycm9yX2ZyZWUpIHtcbiAgICAgIG1hcCA9IHRoaXMuZ2V0SW5wdXRNYXAoZm9ybSk7XG4gICAgICBpc0ZpbGVVcGxvYWQgPSB0aGlzLmlzRmlsZVVwbG9hZChmb3JtKTtcbiAgICAgIG9wdHMgPSB7XG4gICAgICAgIHBhcmVudDogdGhpc1xuICAgICAgfTtcbiAgICAgIGlmICh0aGlzLm9wdGlvbnMuc3dhZ2dlck9wdGlvbnMpIHtcbiAgICAgICAgZm9yKHZhciBrZXkgaW4gdGhpcy5vcHRpb25zLnN3YWdnZXJPcHRpb25zKSB7XG4gICAgICAgICAgb3B0c1trZXldID0gdGhpcy5vcHRpb25zLnN3YWdnZXJPcHRpb25zW2tleV07XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdmFyIHBpO1xuICAgICAgZm9yKHBpID0gMDsgcGkgPCB0aGlzLm1vZGVsLnBhcmFtZXRlcnMubGVuZ3RoOyBwaSsrKXtcbiAgICAgICAgdmFyIHAgPSB0aGlzLm1vZGVsLnBhcmFtZXRlcnNbcGldO1xuICAgICAgICBpZiggcC5qc29uRWRpdG9yICYmIHAuanNvbkVkaXRvci5pc0VuYWJsZWQoKSl7XG4gICAgICAgICAgdmFyIGpzb24gPSBwLmpzb25FZGl0b3IuZ2V0VmFsdWUoKTtcbiAgICAgICAgICBtYXBbcC5uYW1lXSA9IEpTT04uc3RyaW5naWZ5KGpzb24pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIG9wdHMucmVzcG9uc2VDb250ZW50VHlwZSA9ICQoJ2RpdiBzZWxlY3RbbmFtZT1yZXNwb25zZUNvbnRlbnRUeXBlXScsICQodGhpcy5lbCkpLnZhbCgpO1xuICAgICAgb3B0cy5yZXF1ZXN0Q29udGVudFR5cGUgPSAkKCdkaXYgc2VsZWN0W25hbWU9cGFyYW1ldGVyQ29udGVudFR5cGVdJywgJCh0aGlzLmVsKSkudmFsKCk7XG4gICAgICAkKCcucmVzcG9uc2VfdGhyb2JiZXInLCAkKHRoaXMuZWwpKS5zaG93KCk7XG4gICAgICBpZiAoaXNGaWxlVXBsb2FkKSB7XG4gICAgICAgICQoJy5yZXF1ZXN0X3VybCcsICQodGhpcy5lbCkpLmh0bWwoJzxwcmU+PC9wcmU+Jyk7XG4gICAgICAgICQoJy5yZXF1ZXN0X3VybCBwcmUnLCAkKHRoaXMuZWwpKS50ZXh0KHRoaXMuaW52b2NhdGlvblVybCk7XG5cbiAgICAgICAgb3B0cy51c2VKUXVlcnkgPSB0cnVlO1xuICAgICAgICBtYXAucGFyYW1ldGVyQ29udGVudFR5cGUgPSAnbXVsdGlwYXJ0L2Zvcm0tZGF0YSc7XG4gICAgICAgIHRoaXMubWFwID0gbWFwO1xuICAgICAgICByZXR1cm4gdGhpcy5tb2RlbC5leGVjdXRlKG1hcCwgb3B0cywgdGhpcy5zaG93Q29tcGxldGVTdGF0dXMsIHRoaXMuc2hvd0Vycm9yU3RhdHVzLCB0aGlzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubWFwID0gbWFwO1xuICAgICAgICByZXR1cm4gdGhpcy5tb2RlbC5leGVjdXRlKG1hcCwgb3B0cywgdGhpcy5zaG93Q29tcGxldGVTdGF0dXMsIHRoaXMuc2hvd0Vycm9yU3RhdHVzLCB0aGlzKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgZ2V0SW5wdXRNYXA6IGZ1bmN0aW9uIChmb3JtKSB7XG4gICAgdmFyIG1hcCwgcmVmMSwgbCwgbGVuLCBvLCByZWYyLCBtLCBsZW4xLCB2YWwsIHJlZjMsIG4sIGxlbjI7XG4gICAgbWFwID0ge307XG4gICAgcmVmMSA9IGZvcm0uZmluZCgnaW5wdXQnKTtcbiAgICBmb3IgKGwgPSAwLCBsZW4gPSByZWYxLmxlbmd0aDsgbCA8IGxlbjsgbCsrKSB7XG4gICAgICBvID0gcmVmMVtsXTtcbiAgICAgIGlmICgoby52YWx1ZSAhPT0gbnVsbCkgJiYgalF1ZXJ5LnRyaW0oby52YWx1ZSkubGVuZ3RoID4gMCkge1xuICAgICAgICBtYXBbby5uYW1lXSA9IG8udmFsdWU7XG4gICAgICB9XG4gICAgICBpZiAoby50eXBlID09PSAnZmlsZScpIHtcbiAgICAgICAgbWFwW28ubmFtZV0gPSBvLmZpbGVzWzBdO1xuICAgICAgfVxuICAgIH1cbiAgICByZWYyID0gZm9ybS5maW5kKCd0ZXh0YXJlYScpO1xuICAgIGZvciAobSA9IDAsIGxlbjEgPSByZWYyLmxlbmd0aDsgbSA8IGxlbjE7IG0rKykge1xuICAgICAgbyA9IHJlZjJbbV07XG4gICAgICB2YWwgPSB0aGlzLmdldFRleHRBcmVhVmFsdWUobyk7XG4gICAgICBpZiAoKHZhbCAhPT0gbnVsbCkgJiYgalF1ZXJ5LnRyaW0odmFsKS5sZW5ndGggPiAwKSB7XG4gICAgICAgIG1hcFtvLm5hbWVdID0gdmFsO1xuICAgICAgfVxuICAgIH1cbiAgICByZWYzID0gZm9ybS5maW5kKCdzZWxlY3QnKTtcbiAgICBmb3IgKG4gPSAwLCBsZW4yID0gcmVmMy5sZW5ndGg7IG4gPCBsZW4yOyBuKyspIHtcbiAgICAgIG8gPSByZWYzW25dO1xuICAgICAgdmFsID0gdGhpcy5nZXRTZWxlY3RlZFZhbHVlKG8pO1xuICAgICAgaWYgKCh2YWwgIT09IG51bGwpICYmIGpRdWVyeS50cmltKHZhbCkubGVuZ3RoID4gMCkge1xuICAgICAgICBtYXBbby5uYW1lXSA9IHZhbDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1hcDtcbiAgfSxcblxuICBpc0ZpbGVVcGxvYWQ6IGZ1bmN0aW9uIChmb3JtKSB7XG4gICAgdmFyIHJlZjEsIGwsIGxlbiwgbztcbiAgICB2YXIgaXNGaWxlVXBsb2FkID0gZmFsc2U7XG4gICAgcmVmMSA9IGZvcm0uZmluZCgnaW5wdXQnKTtcbiAgICBmb3IgKGwgPSAwLCBsZW4gPSByZWYxLmxlbmd0aDsgbCA8IGxlbjsgbCsrKSB7XG4gICAgICBvID0gcmVmMVtsXTtcbiAgICAgIGlmIChvLnR5cGUgPT09ICdmaWxlJykge1xuICAgICAgICBpc0ZpbGVVcGxvYWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gaXNGaWxlVXBsb2FkO1xuICB9LFxuXG4gIHN1Y2Nlc3M6IGZ1bmN0aW9uKHJlc3BvbnNlLCBwYXJlbnQpIHtcbiAgICBwYXJlbnQuc2hvd0NvbXBsZXRlU3RhdHVzKHJlc3BvbnNlKTtcbiAgfSxcblxuICAvLyB3cmFwcyBhIGpxdWVyeSByZXNwb25zZSBhcyBhIHNocmVkIHJlc3BvbnNlXG4gIHdyYXA6IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICB2YXIgaCwgaGVhZGVyQXJyYXksIGhlYWRlcnMsIGksIGwsIGxlbiwgbztcbiAgICBoZWFkZXJzID0ge307XG4gICAgaGVhZGVyQXJyYXkgPSBkYXRhLmdldEFsbFJlc3BvbnNlSGVhZGVycygpLnNwbGl0KCdcXHInKTtcbiAgICBmb3IgKGwgPSAwLCBsZW4gPSBoZWFkZXJBcnJheS5sZW5ndGg7IGwgPCBsZW47IGwrKykge1xuICAgICAgaSA9IGhlYWRlckFycmF5W2xdO1xuICAgICAgaCA9IGkubWF0Y2goL14oW146XSo/KTooLiopJC8pO1xuICAgICAgaWYgKCFoKSB7XG4gICAgICAgIGggPSBbXTtcbiAgICAgIH1cbiAgICAgIGguc2hpZnQoKTtcbiAgICAgIGlmIChoWzBdICE9PSB2b2lkIDAgJiYgaFsxXSAhPT0gdm9pZCAwKSB7XG4gICAgICAgIGhlYWRlcnNbaFswXS50cmltKCldID0gaFsxXS50cmltKCk7XG4gICAgICB9XG4gICAgfVxuICAgIG8gPSB7fTtcbiAgICBvLmNvbnRlbnQgPSB7fTtcbiAgICBvLmNvbnRlbnQuZGF0YSA9IGRhdGEucmVzcG9uc2VUZXh0O1xuICAgIG8uaGVhZGVycyA9IGhlYWRlcnM7XG4gICAgby5yZXF1ZXN0ID0ge307XG4gICAgby5yZXF1ZXN0LnVybCA9IHRoaXMuaW52b2NhdGlvblVybDtcbiAgICBvLnN0YXR1cyA9IGRhdGEuc3RhdHVzO1xuICAgIHJldHVybiBvO1xuICB9LFxuXG4gIGdldFNlbGVjdGVkVmFsdWU6IGZ1bmN0aW9uKHNlbGVjdCkge1xuICAgIGlmICghc2VsZWN0Lm11bHRpcGxlKSB7XG4gICAgICByZXR1cm4gc2VsZWN0LnZhbHVlO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgb3B0aW9ucyA9IFtdO1xuICAgICAgZm9yICh2YXIgbCA9IDAsIGxlbiA9IHNlbGVjdC5vcHRpb25zLmxlbmd0aDsgbCA8IGxlbjsgbCsrKSB7XG4gICAgICAgIHZhciBvcHQgPSBzZWxlY3Qub3B0aW9uc1tsXTtcbiAgICAgICAgaWYgKG9wdC5zZWxlY3RlZCkge1xuICAgICAgICAgIG9wdGlvbnMucHVzaChvcHQudmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAob3B0aW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJldHVybiBvcHRpb25zO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIC8vIGhhbmRsZXIgZm9yIGhpZGUgcmVzcG9uc2UgbGlua1xuICBoaWRlUmVzcG9uc2U6IGZ1bmN0aW9uKGUpIHtcbiAgICBpZiAoZSkgeyBlLnByZXZlbnREZWZhdWx0KCk7IH1cbiAgICAkKCcucmVzcG9uc2UnLCAkKHRoaXMuZWwpKS5zbGlkZVVwKCk7XG4gICAgJCgnLnJlc3BvbnNlX2hpZGVyJywgJCh0aGlzLmVsKSkuZmFkZU91dCgpO1xuICB9LFxuXG4gIC8vIFNob3cgcmVzcG9uc2UgZnJvbSBzZXJ2ZXJcbiAgc2hvd1Jlc3BvbnNlOiBmdW5jdGlvbihyZXNwb25zZSkge1xuICAgIHZhciBwcmV0dHlKc29uID0gSlNPTi5zdHJpbmdpZnkocmVzcG9uc2UsIG51bGwsICdcXHQnKS5yZXBsYWNlKC9cXG4vZywgJzxicj4nKTtcbiAgICAkKCcucmVzcG9uc2VfYm9keScsICQodGhpcy5lbCkpLmh0bWwoXy5lc2NhcGUocHJldHR5SnNvbikpO1xuICB9LFxuXG4gIC8vIFNob3cgZXJyb3IgZnJvbSBzZXJ2ZXJcbiAgc2hvd0Vycm9yU3RhdHVzOiBmdW5jdGlvbihkYXRhLCBwYXJlbnQpIHtcbiAgICBwYXJlbnQuc2hvd1N0YXR1cyhkYXRhKTtcbiAgfSxcblxuICAvLyBzaG93IHRoZSBzdGF0dXMgY29kZXNcbiAgc2hvd0NvbXBsZXRlU3RhdHVzOiBmdW5jdGlvbihkYXRhLCBwYXJlbnQpe1xuICAgIHBhcmVudC5zaG93U3RhdHVzKGRhdGEpO1xuICB9LFxuXG4gIC8vIEFkYXB0ZWQgZnJvbSBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8yODkzMjU5LzQ1NDAwNFxuICAvLyBOb3RlOiBkaXJlY3RseSBwb3J0ZWQgZnJvbSBDb2ZmZWVTY3JpcHRcbiAgLy8gVE9ETzogQ2xlYW51cCBDb2ZmZWVTY3JpcHQgYXJ0aWZhY3RzXG4gIGZvcm1hdFhtbDogZnVuY3Rpb24oeG1sKSB7XG4gICAgdmFyIGNvbnRleHAsIGZuLCBmb3JtYXR0ZWQsIGluZGVudCwgbCwgbGFzdFR5cGUsIGxlbiwgbGluZXMsIGxuLCBwYWQsIHJlZywgdHJhbnNpdGlvbnMsIHdzZXhwO1xuICAgIHJlZyA9IC8oPikoPCkoXFwvKikvZztcbiAgICB3c2V4cCA9IC9bIF0qKC4qKVsgXStcXG4vZztcbiAgICBjb250ZXhwID0gLyg8Lis+KSguK1xcbikvZztcbiAgICB4bWwgPSB4bWwucmVwbGFjZSgvXFxyXFxuL2csICdcXG4nKS5yZXBsYWNlKHJlZywgJyQxXFxuJDIkMycpLnJlcGxhY2Uod3NleHAsICckMVxcbicpLnJlcGxhY2UoY29udGV4cCwgJyQxXFxuJDInKTtcbiAgICBwYWQgPSAwO1xuICAgIGZvcm1hdHRlZCA9ICcnO1xuICAgIGxpbmVzID0geG1sLnNwbGl0KCdcXG4nKTtcbiAgICBpbmRlbnQgPSAwO1xuICAgIGxhc3RUeXBlID0gJ290aGVyJztcbiAgICB0cmFuc2l0aW9ucyA9IHtcbiAgICAgICdzaW5nbGUtPnNpbmdsZSc6IDAsXG4gICAgICAnc2luZ2xlLT5jbG9zaW5nJzogLTEsXG4gICAgICAnc2luZ2xlLT5vcGVuaW5nJzogMCxcbiAgICAgICdzaW5nbGUtPm90aGVyJzogMCxcbiAgICAgICdjbG9zaW5nLT5zaW5nbGUnOiAwLFxuICAgICAgJ2Nsb3NpbmctPmNsb3NpbmcnOiAtMSxcbiAgICAgICdjbG9zaW5nLT5vcGVuaW5nJzogMCxcbiAgICAgICdjbG9zaW5nLT5vdGhlcic6IDAsXG4gICAgICAnb3BlbmluZy0+c2luZ2xlJzogMSxcbiAgICAgICdvcGVuaW5nLT5jbG9zaW5nJzogMCxcbiAgICAgICdvcGVuaW5nLT5vcGVuaW5nJzogMSxcbiAgICAgICdvcGVuaW5nLT5vdGhlcic6IDEsXG4gICAgICAnb3RoZXItPnNpbmdsZSc6IDAsXG4gICAgICAnb3RoZXItPmNsb3NpbmcnOiAtMSxcbiAgICAgICdvdGhlci0+b3BlbmluZyc6IDAsXG4gICAgICAnb3RoZXItPm90aGVyJzogMFxuICAgIH07XG4gICAgZm4gPSBmdW5jdGlvbihsbikge1xuICAgICAgdmFyIGZyb21Ubywgaiwga2V5LCBwYWRkaW5nLCB0eXBlLCB0eXBlcywgdmFsdWU7XG4gICAgICB0eXBlcyA9IHtcbiAgICAgICAgc2luZ2xlOiBCb29sZWFuKGxuLm1hdGNoKC88LitcXC8+LykpLFxuICAgICAgICBjbG9zaW5nOiBCb29sZWFuKGxuLm1hdGNoKC88XFwvLis+LykpLFxuICAgICAgICBvcGVuaW5nOiBCb29sZWFuKGxuLm1hdGNoKC88W14hP10uKj4vKSlcbiAgICAgIH07XG4gICAgICB0eXBlID0gKChmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIHJlc3VsdHM7XG4gICAgICAgIHJlc3VsdHMgPSBbXTtcbiAgICAgICAgZm9yIChrZXkgaW4gdHlwZXMpIHtcbiAgICAgICAgICB2YWx1ZSA9IHR5cGVzW2tleV07XG4gICAgICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgICAgICByZXN1bHRzLnB1c2goa2V5KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgICB9KSgpKVswXTtcbiAgICAgIHR5cGUgPSB0eXBlID09PSB2b2lkIDAgPyAnb3RoZXInIDogdHlwZTtcbiAgICAgIGZyb21UbyA9IGxhc3RUeXBlICsgJy0+JyArIHR5cGU7XG4gICAgICBsYXN0VHlwZSA9IHR5cGU7XG4gICAgICBwYWRkaW5nID0gJyc7XG4gICAgICBpbmRlbnQgKz0gdHJhbnNpdGlvbnNbZnJvbVRvXTtcbiAgICAgIHBhZGRpbmcgPSAoKGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgbSwgcmVmMSwgcmVzdWx0cztcbiAgICAgICAgcmVzdWx0cyA9IFtdO1xuICAgICAgICBmb3IgKGogPSBtID0gMCwgcmVmMSA9IGluZGVudDsgMCA8PSByZWYxID8gbSA8IHJlZjEgOiBtID4gcmVmMTsgaiA9IDAgPD0gcmVmMSA/ICsrbSA6IC0tbSkge1xuICAgICAgICAgIHJlc3VsdHMucHVzaCgnICAnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0cztcbiAgICAgIH0pKCkpLmpvaW4oJycpO1xuICAgICAgaWYgKGZyb21UbyA9PT0gJ29wZW5pbmctPmNsb3NpbmcnKSB7XG4gICAgICAgIGZvcm1hdHRlZCA9IGZvcm1hdHRlZC5zdWJzdHIoMCwgZm9ybWF0dGVkLmxlbmd0aCAtIDEpICsgbG4gKyAnXFxuJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZvcm1hdHRlZCArPSBwYWRkaW5nICsgbG4gKyAnXFxuJztcbiAgICAgIH1cbiAgICB9O1xuICAgIGZvciAobCA9IDAsIGxlbiA9IGxpbmVzLmxlbmd0aDsgbCA8IGxlbjsgbCsrKSB7XG4gICAgICBsbiA9IGxpbmVzW2xdO1xuICAgICAgZm4obG4pO1xuICAgIH1cbiAgICByZXR1cm4gZm9ybWF0dGVkO1xuICB9LFxuXG4gIC8vIHB1dHMgdGhlIHJlc3BvbnNlIGRhdGEgaW4gVUlcbiAgc2hvd1N0YXR1czogZnVuY3Rpb24ocmVzcG9uc2UpIHtcbiAgICB2YXIgdXJsLCBjb250ZW50O1xuICAgIGlmIChyZXNwb25zZS5jb250ZW50ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnRlbnQgPSByZXNwb25zZS5kYXRhO1xuICAgICAgdXJsID0gcmVzcG9uc2UudXJsO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb250ZW50ID0gcmVzcG9uc2UuY29udGVudC5kYXRhO1xuICAgICAgdXJsID0gcmVzcG9uc2UucmVxdWVzdC51cmw7XG4gICAgfVxuICAgIHZhciBoZWFkZXJzID0gcmVzcG9uc2UuaGVhZGVycztcbiAgICBpZih0eXBlb2YgY29udGVudCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGNvbnRlbnQgPSBqUXVlcnkudHJpbShjb250ZW50KTtcbiAgICB9XG5cbiAgICAvLyBpZiBzZXJ2ZXIgaXMgbmljZSwgYW5kIHNlbmRzIGNvbnRlbnQtdHlwZSBiYWNrLCB3ZSBjYW4gdXNlIGl0XG4gICAgdmFyIGNvbnRlbnRUeXBlID0gbnVsbDtcbiAgICBpZiAoaGVhZGVycykge1xuICAgICAgY29udGVudFR5cGUgPSBoZWFkZXJzWydDb250ZW50LVR5cGUnXSB8fCBoZWFkZXJzWydjb250ZW50LXR5cGUnXTtcbiAgICAgIGlmIChjb250ZW50VHlwZSkge1xuICAgICAgICBjb250ZW50VHlwZSA9IGNvbnRlbnRUeXBlLnNwbGl0KCc7JylbMF0udHJpbSgpO1xuICAgICAgfVxuICAgIH1cblxuICAgICQoJy5yZXNwb25zZV9ib2R5JywgJCh0aGlzLmVsKSkucmVtb3ZlQ2xhc3MoJ2pzb24nKTtcbiAgICAkKCcucmVzcG9uc2VfYm9keScsICQodGhpcy5lbCkpLnJlbW92ZUNsYXNzKCd4bWwnKTtcblxuICAgIHZhciBzdXBwb3J0c0F1ZGlvUGxheWJhY2sgPSBmdW5jdGlvbihjb250ZW50VHlwZSl7XG4gICAgICB2YXIgYXVkaW9FbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYXVkaW8nKTtcbiAgICAgIHJldHVybiAhIShhdWRpb0VsZW1lbnQuY2FuUGxheVR5cGUgJiYgYXVkaW9FbGVtZW50LmNhblBsYXlUeXBlKGNvbnRlbnRUeXBlKS5yZXBsYWNlKC9uby8sICcnKSk7XG4gICAgfTtcblxuICAgIHZhciBwcmU7XG4gICAgdmFyIGNvZGU7XG4gICAgdmFyIHNraXBIaWdobGlnaHQgPSBmYWxzZTtcbiAgICBpZiAoIWNvbnRlbnQpIHtcbiAgICAgIGNvZGUgPSAkKCc8Y29kZSAvPicpLnRleHQoJ25vIGNvbnRlbnQnKTtcbiAgICAgIHByZSA9ICQoJzxwcmUgY2xhc3M9XCJqc29uXCIgLz4nKS5hcHBlbmQoY29kZSk7XG5cbiAgICAgIC8vIEpTT05cbiAgICB9IGVsc2UgaWYgKFxuICAgICAgICBjb250ZW50VHlwZSA9PT0gJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbScgfHxcbiAgICAgICAgaGVhZGVyc1snQ29udGVudC1EaXNwb3NpdGlvbiddICYmICgvYXR0YWNobWVudC8pLnRlc3QoaGVhZGVyc1snQ29udGVudC1EaXNwb3NpdGlvbiddKSB8fFxuICAgICAgICBoZWFkZXJzWydjb250ZW50LWRpc3Bvc2l0aW9uJ10gJiYgKC9hdHRhY2htZW50LykudGVzdChoZWFkZXJzWydjb250ZW50LWRpc3Bvc2l0aW9uJ10pIHx8XG4gICAgICAgIGhlYWRlcnNbJ0NvbnRlbnQtRGVzY3JpcHRpb24nXSAmJiAoL0ZpbGUgVHJhbnNmZXIvKS50ZXN0KGhlYWRlcnNbJ0NvbnRlbnQtRGVzY3JpcHRpb24nXSkgfHxcbiAgICAgICAgaGVhZGVyc1snY29udGVudC1kZXNjcmlwdGlvbiddICYmICgvRmlsZSBUcmFuc2Zlci8pLnRlc3QoaGVhZGVyc1snY29udGVudC1kZXNjcmlwdGlvbiddKSkge1xuXG4gICAgICBpZiAoJ0Jsb2InIGluIHdpbmRvdykge1xuICAgICAgICB2YXIgdHlwZSA9IGNvbnRlbnRUeXBlIHx8ICd0ZXh0L2h0bWwnO1xuICAgICAgICB2YXIgYSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICAgICAgdmFyIGhyZWY7XG5cbiAgICAgICAgaWYoe30udG9TdHJpbmcuYXBwbHkoY29udGVudCkgPT09ICdbb2JqZWN0IEJsb2JdJykge1xuICAgICAgICAgIGhyZWYgPSB3aW5kb3cuVVJMLmNyZWF0ZU9iamVjdFVSTChjb250ZW50KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICB2YXIgYmluYXJ5RGF0YSA9IFtdO1xuICAgICAgICAgIGJpbmFyeURhdGEucHVzaChjb250ZW50KTtcbiAgICAgICAgICBocmVmID0gd2luZG93LlVSTC5jcmVhdGVPYmplY3RVUkwobmV3IEJsb2IoYmluYXJ5RGF0YSwge3R5cGU6IHR5cGV9KSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGZpbGVOYW1lID0gcmVzcG9uc2UudXJsLnN1YnN0cihyZXNwb25zZS51cmwubGFzdEluZGV4T2YoJy8nKSArIDEpO1xuICAgICAgICB2YXIgZG93bmxvYWQgPSBbdHlwZSwgZmlsZU5hbWUsIGhyZWZdLmpvaW4oJzonKTtcblxuICAgICAgICAvLyBVc2UgZmlsZW5hbWUgZnJvbSByZXNwb25zZSBoZWFkZXJcbiAgICAgICAgdmFyIGRpc3Bvc2l0aW9uID0gaGVhZGVyc1snY29udGVudC1kaXNwb3NpdGlvbiddIHx8IGhlYWRlcnNbJ0NvbnRlbnQtRGlzcG9zaXRpb24nXTtcbiAgICAgICAgaWYodHlwZW9mIGRpc3Bvc2l0aW9uICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIHZhciByZXNwb25zZUZpbGVuYW1lID0gL2ZpbGVuYW1lPShbXjtdKik7Py8uZXhlYyhkaXNwb3NpdGlvbik7XG4gICAgICAgICAgaWYocmVzcG9uc2VGaWxlbmFtZSAhPT0gbnVsbCAmJiByZXNwb25zZUZpbGVuYW1lLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgIGRvd25sb2FkID0gcmVzcG9uc2VGaWxlbmFtZVsxXTtcbiAgICAgICAgICAgIGZpbGVOYW1lID0gZG93bmxvYWQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgYS5zZXRBdHRyaWJ1dGUoJ2hyZWYnLCBocmVmKTtcbiAgICAgICAgYS5zZXRBdHRyaWJ1dGUoJ2Rvd25sb2FkJywgZG93bmxvYWQpO1xuICAgICAgICBhLmlubmVyVGV4dCA9ICdEb3dubG9hZCAnICsgZmlsZU5hbWU7XG5cbiAgICAgICAgcHJlID0gJCgnPGRpdi8+JykuYXBwZW5kKGEpO1xuICAgICAgICBza2lwSGlnaGxpZ2h0ID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHByZSA9ICQoJzxwcmUgY2xhc3M9XCJqc29uXCIgLz4nKS5hcHBlbmQoJ0Rvd25sb2FkIGhlYWRlcnMgZGV0ZWN0ZWQgYnV0IHlvdXIgYnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IGRvd25sb2FkaW5nIGJpbmFyeSB2aWEgWEhSIChCbG9iKS4nKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGNvbnRlbnRUeXBlID09PSAnYXBwbGljYXRpb24vanNvbicgfHwgL1xcK2pzb24kLy50ZXN0KGNvbnRlbnRUeXBlKSkge1xuICAgICAgdmFyIGpzb24gPSBudWxsO1xuICAgICAgdHJ5IHtcbiAgICAgICAganNvbiA9IEpTT04uc3RyaW5naWZ5KEpTT04ucGFyc2UoY29udGVudCksIG51bGwsICcgICcpO1xuICAgICAgfSBjYXRjaCAoX2Vycm9yKSB7XG4gICAgICAgIGpzb24gPSAnY2FuXFwndCBwYXJzZSBKU09OLiAgUmF3IHJlc3VsdDpcXG5cXG4nICsgY29udGVudDtcbiAgICAgIH1cbiAgICAgIGNvZGUgPSAkKCc8Y29kZSAvPicpLnRleHQoanNvbik7XG4gICAgICBwcmUgPSAkKCc8cHJlIGNsYXNzPVwianNvblwiIC8+JykuYXBwZW5kKGNvZGUpO1xuXG4gICAgICAvLyBYTUxcbiAgICB9IGVsc2UgaWYgKGNvbnRlbnRUeXBlID09PSAnYXBwbGljYXRpb24veG1sJyB8fCAvXFwreG1sJC8udGVzdChjb250ZW50VHlwZSkpIHtcbiAgICAgIGNvZGUgPSAkKCc8Y29kZSAvPicpLnRleHQodGhpcy5mb3JtYXRYbWwoY29udGVudCkpO1xuICAgICAgcHJlID0gJCgnPHByZSBjbGFzcz1cInhtbFwiIC8+JykuYXBwZW5kKGNvZGUpO1xuXG4gICAgICAvLyBIVE1MXG4gICAgfSBlbHNlIGlmIChjb250ZW50VHlwZSA9PT0gJ3RleHQvaHRtbCcpIHtcbiAgICAgIGNvZGUgPSAkKCc8Y29kZSAvPicpLmh0bWwoXy5lc2NhcGUoY29udGVudCkpO1xuICAgICAgcHJlID0gJCgnPHByZSBjbGFzcz1cInhtbFwiIC8+JykuYXBwZW5kKGNvZGUpO1xuXG4gICAgICAvLyBQbGFpbiBUZXh0XG4gICAgfSBlbHNlIGlmICgvdGV4dFxcL3BsYWluLy50ZXN0KGNvbnRlbnRUeXBlKSkge1xuICAgICAgY29kZSA9ICQoJzxjb2RlIC8+JykudGV4dChjb250ZW50KTtcbiAgICAgIHByZSA9ICQoJzxwcmUgY2xhc3M9XCJwbGFpblwiIC8+JykuYXBwZW5kKGNvZGUpO1xuXG4gICAgICAvLyBJbWFnZVxuICAgIH0gZWxzZSBpZiAoL15pbWFnZVxcLy8udGVzdChjb250ZW50VHlwZSkpIHtcbiAgICAgIHZhciB1cmxDcmVhdG9yID0gd2luZG93LlVSTCB8fCB3aW5kb3cud2Via2l0VVJMO1xuICAgICAgdmFyIGltYWdlVXJsID0gdXJsQ3JlYXRvci5jcmVhdGVPYmplY3RVUkwoY29udGVudCk7XG5cbiAgICAgIHByZSA9ICQoJzxpbWc+JykuYXR0ciggJ3NyYycsIGltYWdlVXJsKTtcbiAgICAgIC8vIEF1ZGlvXG4gICAgfSBlbHNlIGlmICgvXmF1ZGlvXFwvLy50ZXN0KGNvbnRlbnRUeXBlKSAmJiBzdXBwb3J0c0F1ZGlvUGxheWJhY2soY29udGVudFR5cGUpKSB7XG4gICAgICBwcmUgPSAkKCc8YXVkaW8gY29udHJvbHM+JykuYXBwZW5kKCQoJzxzb3VyY2U+JykuYXR0cignc3JjJywgdXJsKS5hdHRyKCd0eXBlJywgY29udGVudFR5cGUpKTtcbiAgICB9IGVsc2UgaWYoaGVhZGVycy5sb2NhdGlvbiB8fCBoZWFkZXJzLkxvY2F0aW9uKSB7XG4gICAgICAvLyBMb2NhdGlvbiBoZWFkZXIgYmFzZWQgcmVkaXJlY3QgZG93bmxvYWRcbiAgICAgIHdpbmRvdy5sb2NhdGlvbiA9IHJlc3BvbnNlLnVybDtcblxuICAgICAgLy8gQW55dGhpbmcgZWxzZSAoQ09SUylcbiAgICB9IGVsc2Uge1xuICAgICAgY29kZSA9ICQoJzxjb2RlIC8+JykudGV4dChjb250ZW50KTtcbiAgICAgIHByZSA9ICQoJzxwcmUgY2xhc3M9XCJqc29uXCIgLz4nKS5hcHBlbmQoY29kZSk7XG4gICAgfVxuICAgIHZhciByZXNwb25zZV9ib2R5ID0gcHJlO1xuICAgICQoJy5yZXF1ZXN0X3VybCcsICQodGhpcy5lbCkpLmh0bWwoJzxwcmU+PC9wcmU+Jyk7XG4gICAgJCgnLnJlcXVlc3RfdXJsIHByZScsICQodGhpcy5lbCkpLnRleHQodXJsKTtcbiAgICAkKCcucmVzcG9uc2VfY29kZScsICQodGhpcy5lbCkpLmh0bWwoJzxwcmU+JyArIHJlc3BvbnNlLnN0YXR1cyArICc8L3ByZT4nKTtcbiAgICAkKCcucmVzcG9uc2VfYm9keScsICQodGhpcy5lbCkpLmh0bWwocmVzcG9uc2VfYm9keSk7XG4gICAgJCgnLnJlc3BvbnNlX2hlYWRlcnMnLCAkKHRoaXMuZWwpKS5odG1sKCc8cHJlPicgKyBfLmVzY2FwZShKU09OLnN0cmluZ2lmeShyZXNwb25zZS5oZWFkZXJzLCBudWxsLCAnICAnKSkucmVwbGFjZSgvXFxuL2csICc8YnI+JykgKyAnPC9wcmU+Jyk7XG4gICAgJCgnLnJlc3BvbnNlJywgJCh0aGlzLmVsKSkuc2xpZGVEb3duKCk7XG4gICAgJCgnLnJlc3BvbnNlX2hpZGVyJywgJCh0aGlzLmVsKSkuc2hvdygpO1xuICAgICQoJy5yZXNwb25zZV90aHJvYmJlcicsICQodGhpcy5lbCkpLmhpZGUoKTtcblxuXG4gICAgLy8gYWRkcyBjdXJsIG91dHB1dFxuICAgIHZhciBjdXJsQ29tbWFuZCA9IHRoaXMubW9kZWwuYXNDdXJsKHRoaXMubWFwLCB7cmVzcG9uc2VDb250ZW50VHlwZTogY29udGVudFR5cGV9KTtcbiAgICBjdXJsQ29tbWFuZCA9IGN1cmxDb21tYW5kLnJlcGxhY2UoJyEnLCAnJiMzMzsnKTtcbiAgICAkKCAnZGl2LmN1cmwnLCAkKHRoaXMuZWwpKS5odG1sKCc8cHJlPicgKyBfLmVzY2FwZShjdXJsQ29tbWFuZCkgKyAnPC9wcmU+Jyk7XG5cbiAgICAvLyBvbmx5IGhpZ2hsaWdodCB0aGUgcmVzcG9uc2UgaWYgcmVzcG9uc2UgaXMgbGVzcyB0aGFuIHRocmVzaG9sZCwgZGVmYXVsdCBzdGF0ZSBpcyBoaWdobGlnaHQgcmVzcG9uc2VcbiAgICB2YXIgb3B0cyA9IHRoaXMub3B0aW9ucy5zd2FnZ2VyT3B0aW9ucztcblxuICAgIGlmIChvcHRzLnNob3dSZXF1ZXN0SGVhZGVycykge1xuICAgICAgdmFyIGZvcm0gPSAkKCcuc2FuZGJveCcsICQodGhpcy5lbCkpLFxuICAgICAgICAgIG1hcCA9IHRoaXMuZ2V0SW5wdXRNYXAoZm9ybSksXG4gICAgICAgICAgcmVxdWVzdEhlYWRlcnMgPSB0aGlzLm1vZGVsLmdldEhlYWRlclBhcmFtcyhtYXApO1xuICAgICAgZGVsZXRlIHJlcXVlc3RIZWFkZXJzWydDb250ZW50LVR5cGUnXTtcbiAgICAgICQoJy5yZXF1ZXN0X2hlYWRlcnMnLCAkKHRoaXMuZWwpKS5odG1sKCc8cHJlPicgKyBfLmVzY2FwZShKU09OLnN0cmluZ2lmeShyZXF1ZXN0SGVhZGVycywgbnVsbCwgJyAgJykpLnJlcGxhY2UoL1xcbi9nLCAnPGJyPicpICsgJzwvcHJlPicpO1xuICAgIH1cblxuICAgIC8vIENhbGwgdXNlci1kZWZpbmVkIGhvb2tcbiAgICBpZiAob3B0cy5yZXNwb25zZUhvb2tzICYmIG9wdHMucmVzcG9uc2VIb29rc1t0aGlzLm5pY2tuYW1lXSkge1xuICAgICAgb3B0cy5yZXNwb25zZUhvb2tzW3RoaXMubmlja25hbWVdKHJlc3BvbnNlLCB0aGlzKTtcbiAgICB9XG5cbiAgICB2YXIgcmVzcG9uc2VfYm9keV9lbCA9ICQoJy5yZXNwb25zZV9ib2R5JywgJCh0aGlzLmVsKSlbMF07XG4gICAgLy8gb25seSBoaWdobGlnaHQgdGhlIHJlc3BvbnNlIGlmIHJlc3BvbnNlIGlzIGxlc3MgdGhhbiB0aHJlc2hvbGQsIGRlZmF1bHQgc3RhdGUgaXMgaGlnaGxpZ2h0IHJlc3BvbnNlXG4gICAgaWYgKG9wdHMuaGlnaGxpZ2h0U2l6ZVRocmVzaG9sZCAmJiB0eXBlb2YgcmVzcG9uc2UuZGF0YSAhPT0gJ3VuZGVmaW5lZCcgJiYgcmVzcG9uc2UuZGF0YS5sZW5ndGggPiBvcHRzLmhpZ2hsaWdodFNpemVUaHJlc2hvbGQgfHwgc2tpcEhpZ2hsaWdodCkge1xuICAgICAgcmV0dXJuIHJlc3BvbnNlX2JvZHlfZWw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBobGpzLmhpZ2hsaWdodEJsb2NrKHJlc3BvbnNlX2JvZHlfZWwpO1xuICAgIH1cbiAgfSxcblxuICB0b2dnbGVPcGVyYXRpb25Db250ZW50OiBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICB2YXIgZWxlbSA9ICQoJyMnICsgRG9jcy5lc2NhcGVSZXNvdXJjZU5hbWUodGhpcy5wYXJlbnRJZCArICdfJyArIHRoaXMubmlja25hbWUgKyAnX2NvbnRlbnQnKSk7XG4gICAgaWYgKGVsZW0uaXMoJzp2aXNpYmxlJykpe1xuICAgICAgJC5iYnEucHVzaFN0YXRlKCcjLycsIDIpO1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIERvY3MuY29sbGFwc2VPcGVyYXRpb24oZWxlbSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIERvY3MuZXhwYW5kT3BlcmF0aW9uKGVsZW0pO1xuICAgIH1cbiAgfSxcblxuICBnZXRUZXh0QXJlYVZhbHVlOiBmdW5jdGlvbih0ZXh0QXJlYSkge1xuICAgIHZhciBwYXJhbSwgcGFyc2VkLCByZXN1bHQsIGk7XG4gICAgaWYgKHRleHRBcmVhLnZhbHVlID09PSBudWxsIHx8IGpRdWVyeS50cmltKHRleHRBcmVhLnZhbHVlKS5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBwYXJhbSA9IHRoaXMuZ2V0UGFyYW1CeU5hbWUodGV4dEFyZWEubmFtZSk7XG4gICAgaWYgKHBhcmFtICYmIHBhcmFtLnR5cGUgJiYgcGFyYW0udHlwZS50b0xvd2VyQ2FzZSgpID09PSAnYXJyYXknKSB7XG4gICAgICBwYXJzZWQgPSB0ZXh0QXJlYS52YWx1ZS5zcGxpdCgnXFxuJyk7XG4gICAgICByZXN1bHQgPSBbXTtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCBwYXJzZWQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKHBhcnNlZFtpXSAhPT0gbnVsbCAmJiBqUXVlcnkudHJpbShwYXJzZWRbaV0pLmxlbmd0aCA+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+JyxcbiAgICAgIHZhbHVlLFxuICAgICAgJzwvJywgbmFtZSwgJz4nXG4gICAgXTtcblxuICAgIHJldHVybiBzdHIuam9pbignJyk7XG4gIH07XG5cbiAgLy8gQ29tbWVudGluZyB0aGlzIGZ1bnRpb24gYXMgdGhlIG5hbWVzIGFyZSBub3cgZGV0ZXJtaW5lZCBiZWZvcmVoYW5kIGFuZCB0aGUgcHJlZml4IHBhcnQgaXMgZXhwb3NlZCBhcyBhIHNlcGFyYXRlIGZ1bmN0aW9uIHwgaHR0cHM6Ly9naXRodWIuY29tL3N3YWdnZXItYXBpL3N3YWdnZXItdWkvaXNzdWVzLzI1NzdcbiAvKiogdmFyIGdldE5hbWUgPSBmdW5jdGlvbiAobmFtZSwgeG1sKSB7XG4gICAgdmFyIHJlc3VsdCA9IG5hbWUgfHwgJyc7XG5cbiAgICB4bWwgPSB4bWwgfHwge307XG5cbiAgICBpZiAoeG1sLm5hbWUpIHtcbiAgICAgIHJlc3VsdCA9IHhtbC5uYW1lO1xuICAgIH1cblxuICAgIGlmICh4bWwucHJlZml4KSB7XG4gICAgICByZXN1bHQgPSB4bWwucHJlZml4ICsgJzonICsgcmVzdWx0O1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG4gICovXG4gIFxuICB2YXIgZ2V0UHJlZml4ID0gZnVuY3Rpb24gKG5hbWUsIHhtbCkge1xuICAgIHZhciByZXN1bHQgPSBuYW1lIHx8ICcnO1xuXG4gICAgeG1sID0geG1sIHx8IHt9O1xuXG4gICAgaWYgKHhtbC5wcmVmaXgpIHtcbiAgICAgIHJlc3VsdCA9IHhtbC5wcmVmaXggKyAnOicgKyByZXN1bHQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICB2YXIgZ2V0TmFtZXNwYWNlID0gZnVuY3Rpb24gKHhtbCkge1xuICAgIHZhciBuYW1lc3BhY2UgPSAnJztcbiAgICB2YXIgbmFtZSA9ICd4bWxucyc7XG5cbiAgICB4bWwgPSB4bWwgfHwge307XG5cbiAgICBpZiAoeG1sLm5hbWVzcGFjZSkge1xuICAgICAgbmFtZXNwYWNlID0geG1sLm5hbWVzcGFjZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG5hbWVzcGFjZTtcbiAgICB9XG5cbiAgICBpZiAoeG1sLnByZWZpeCkge1xuICAgICAgbmFtZSArPSAnOicgKyB4bWwucHJlZml4O1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBuYW1lOiBuYW1lLFxuICAgICAgdmFsdWU6IG5hbWVzcGFjZVxuICAgIH07XG4gIH07XG5cbiAgdmFyIGNyZWF0ZUFycmF5WE1MID0gZnVuY3Rpb24gKGRlc2NyaXB0b3IpIHtcbiAgICB2YXIgbmFtZSA9IGRlc2NyaXB0b3IubmFtZTtcbiAgICB2YXIgY29uZmlnID0gZGVzY3JpcHRvci5jb25maWc7XG4gICAgdmFyIGRlZmluaXRpb24gPSBkZXNjcmlwdG9yLmRlZmluaXRpb247XG4gICAgdmFyIG1vZGVscyA9IGRlc2NyaXB0b3IubW9kZWxzO1xuICAgIHZhciB2YWx1ZTtcbiAgICB2YXIgaXRlbXMgPSBkZWZpbml0aW9uLml0ZW1zO1xuICAgIHZhciB4bWwgPSBkZWZpbml0aW9uLnhtbCB8fCB7fTtcbiAgICB2YXIgbmFtZXNwYWNlID0gZ2V0TmFtZXNwYWNlKHhtbCk7XG4gICAgdmFyIGF0dHJpYnV0ZXMgPSBbXTtcblxuICAgIGlmICghaXRlbXMpIHsgcmV0dXJuIGdldEVycm9yTWVzc2FnZSgpOyB9XG4gICAgdmFyIGtleSA9IG5hbWU7XG4gICAgLy8gSWYgdGhlcmUgaXMgYSBuYW1lIHNwZWNpZmllZCBmb3IgdGhlIGFycmF5IGVsZW1lbnRzLCB1c2UgdGhhdCBmb3IgdGhlIGFycmF5IGVsZW1lbnRzIG5hbWUgfCBodHRwczovL2dpdGh1Yi5jb20vc3dhZ2dlci1hcGkvc3dhZ2dlci11aS9pc3N1ZXMvMjU3N1xuICAgIGlmKGl0ZW1zLnhtbCAmJiBpdGVtcy54bWwubmFtZSkge1xuICAgICAgICBrZXkgPSBpdGVtcy54bWwubmFtZTtcbiAgICB9XG4gICAgdmFsdWUgPSBjcmVhdGVTY2hlbWFYTUwoa2V5LCBpdGVtcywgbW9kZWxzLCBjb25maWcpO1xuICAgIGlmIChuYW1lc3BhY2UpIHtcbiAgICAgIGF0dHJpYnV0ZXMucHVzaChuYW1lc3BhY2UpO1xuICAgIH1cblxuICAgIGlmICh4bWwud3JhcHBlZCkge1xuICAgICAgdmFsdWUgPSB3cmFwVGFnKG5hbWUsIHZhbHVlLCBhdHRyaWJ1dGVzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWU7XG4gIH07XG5cbiAgdmFyIGdldFByaW1pdGl2ZVNpZ25hdHVyZSA9IGZ1bmN0aW9uIChzY2hlbWEpIHtcbiAgICB2YXIgdHlwZSwgaXRlbXM7XG5cbiAgICBzY2hlbWEgPSBzY2hlbWEgfHwge307XG4gICAgaXRlbXMgPSBzY2hlbWEuaXRlbXMgfHwge307XG4gICAgdHlwZSA9IHNjaGVtYS50eXBlIHx8ICcnO1xuXG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICBjYXNlICdvYmplY3QnOiByZXR1cm4gJ09iamVjdCBpcyBub3QgYSBwcmltaXRpdmUnO1xuICAgICAgY2FzZSAnYXJyYXknIDogcmV0dXJuICdBcnJheVsnICsgKGl0ZW1zLmZvcm1hdCB8fCBpdGVtcy50eXBlKSArICddJztcbiAgICAgIGRlZmF1bHQ6IHJldHVybiBzY2hlbWEuZm9ybWF0IHx8IHR5cGU7XG4gICAgfVxuICB9O1xuXG4gIHZhciBjcmVhdGVQcmltaXRpdmVYTUwgPSBmdW5jdGlvbiAoZGVzY3JpcHRvcikge1xuICAgIHZhciBuYW1lID0gZGVzY3JpcHRvci5uYW1lO1xuICAgIHZhciBkZWZpbml0aW9uID0gZGVzY3JpcHRvci5kZWZpbml0aW9uO1xuICAgIHZhciBwcmltaXRpdmVzTWFwID0ge1xuICAgICAgJ3N0cmluZyc6IHtcbiAgICAgICAgJ2RhdGUnOiBuZXcgRGF0ZSgxKS50b0lTT1N0cmluZygpLnNwbGl0KCdUJylbMF0sXG4gICAgICAgICdkYXRlLXRpbWUnIDogbmV3IERhdGUoMSkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgJ2RlZmF1bHQnOiAnc3RyaW5nJ1xuICAgICAgfSxcbiAgICAgICdpbnRlZ2VyJzoge1xuICAgICAgICAnZGVmYXVsdCc6IDFcbiAgICAgIH0sXG4gICAgICAnbnVtYmVyJzoge1xuICAgICAgICAnZGVmYXVsdCc6IDEuMVxuICAgICAgfSxcbiAgICAgICdib29sZWFuJzoge1xuICAgICAgICAnZGVmYXVsdCc6IHRydWVcbiAgICAgIH1cbiAgICB9O1xuICAgIHZhciB0eXBlID0gZGVmaW5pdGlvbi50eXBlO1xuICAgIHZhciBmb3JtYXQgPSBkZWZpbml0aW9uLmZvcm1hdDtcbiAgICB2YXIgeG1sID0gZGVmaW5pdGlvbi54bWwgfHwge307XG4gICAgdmFyIG5hbWVzcGFjZSA9IGdldE5hbWVzcGFjZSh4bWwpO1xuICAgIHZhciBhdHRyaWJ1dGVzID0gW107XG4gICAgdmFyIHZhbHVlO1xuXG4gICAgaWYgKF8ua2V5cyhwcmltaXRpdmVzTWFwKS5pbmRleE9mKHR5cGUpIDwgMCkgeyByZXR1cm4gZ2V0RXJyb3JNZXNzYWdlKCk7IH1cblxuICAgIGlmIChfLmlzQXJyYXkoZGVmaW5pdGlvbi5lbnVtKSl7XG4gICAgICB2YWx1ZSA9IGRlZmluaXRpb24uZW51bVswXTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWUgPSBkZWZpbml0aW9uLmV4YW1wbGUgfHwgcHJpbWl0aXZlc01hcFt0eXBlXVtmb3JtYXRdIHx8IHByaW1pdGl2ZXNNYXBbdHlwZV0uZGVmYXVsdDtcbiAgICB9XG5cbiAgICBpZiAoeG1sLmF0dHJpYnV0ZSkge1xuICAgICAgcmV0dXJuIHtuYW1lOiBuYW1lLCB2YWx1ZTogdmFsdWV9O1xuICAgIH1cblxuICAgIGlmIChuYW1lc3BhY2UpIHtcbiAgICAgIGF0dHJpYnV0ZXMucHVzaChuYW1lc3BhY2UpO1xuICAgIH1cblxuICAgIHJldHVybiB3cmFwVGFnKG5hbWUsIHZhbHVlLCBhdHRyaWJ1dGVzKTtcbiAgfTtcblxuICBmdW5jdGlvbiBjcmVhdGVPYmplY3RYTUwgKGRlc2NyaXB0b3IpIHtcbiAgICB2YXIgbmFtZSA9IGRlc2NyaXB0b3IubmFtZTtcbiAgICB2YXIgZGVmaW5pdGlvbiA9IGRlc2NyaXB0b3IuZGVmaW5pdGlvbjtcbiAgICB2YXIgY29uZmlnID0gZGVzY3JpcHRvci5jb25maWc7XG4gICAgdmFyIG1vZGVscyA9IGRlc2NyaXB0b3IubW9kZWxzO1xuICAgIHZhciBpc1BhcmFtID0gZGVzY3JpcHRvci5jb25maWcuaXNQYXJhbTtcbiAgICB2YXIgc2VyaWFsaXplZFByb3BlcnRpZXM7XG4gICAgdmFyIGF0dHJzID0gW107XG4gICAgdmFyIHByb3BlcnRpZXMgPSBkZWZpbml0aW9uLnByb3BlcnRpZXM7XG4gICAgdmFyIGFkZGl0aW9uYWxQcm9wZXJ0aWVzID0gZGVmaW5pdGlvbi5hZGRpdGlvbmFsUHJvcGVydGllcztcbiAgICB2YXIgeG1sID0gZGVmaW5pdGlvbi54bWw7XG4gICAgdmFyIG5hbWVzcGFjZSA9IGdldE5hbWVzcGFjZSh4bWwpO1xuXG4gICAgaWYgKG5hbWVzcGFjZSkge1xuICAgICAgYXR0cnMucHVzaChuYW1lc3BhY2UpO1xuICAgIH0gICBcblxuICAgIGlmICghcHJvcGVydGllcyAmJiAhYWRkaXRpb25hbFByb3BlcnRpZXMpIHsgcmV0dXJuIGdldEVycm9yTWVzc2FnZSgpOyB9XG5cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyB8fCB7fTtcblxuICAgIHNlcmlhbGl6ZWRQcm9wZXJ0aWVzID0gXy5tYXAocHJvcGVydGllcywgZnVuY3Rpb24gKHByb3AsIGtleSkge1xuICAgICAgdmFyIHhtbCwgcmVzdWx0O1xuXG4gICAgICBpZiAoaXNQYXJhbSAmJiBwcm9wLnJlYWRPbmx5KSB7XG4gICAgICAgIHJldHVybiAnJztcbiAgICAgIH1cblxuICAgICAgeG1sID0gcHJvcC54bWwgfHwge307XG4gICAgICByZXN1bHQgPSBjcmVhdGVTY2hlbWFYTUwoa2V5LCBwcm9wLCBtb2RlbHMsIGNvbmZpZyk7XG5cbiAgICAgIGlmICh4bWwuYXR0cmlidXRlKSB7XG4gICAgICAgIGF0dHJzLnB1c2gocmVzdWx0KTtcbiAgICAgICAgcmV0dXJuICcnO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pLmpvaW4oJycpO1xuXG4gICAgaWYgKGFkZGl0aW9uYWxQcm9wZXJ0aWVzKSB7XG4gICAgICBzZXJpYWxpemVkUHJvcGVydGllcyArPSAnPCEtLSBhZGRpdGlvbmFsIGVsZW1lbnRzIGFsbG93ZWQgLS0+JztcbiAgICB9XG5cbiAgICByZXR1cm4gd3JhcFRhZyhuYW1lLCBzZXJpYWxpemVkUHJvcGVydGllcywgYXR0cnMpO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0SW5maW5pdGVMb29wTWVzc2FnZSAobmFtZSwgbG9vcFRvKSB7XG4gICAgcmV0dXJuIHdyYXBUYWcobmFtZSwgJzwhLS0gSW5maW5pdGUgbG9vcCAkcmVmOicgKyBsb29wVG8gKyAnIC0tPicpO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0RXJyb3JNZXNzYWdlIChkZXRhaWxzKSB7XG4gICAgZGV0YWlscyA9IGRldGFpbHMgPyAnOiAnICsgZGV0YWlscyA6ICcnO1xuICAgIHJldHVybiAnPCEtLSBpbnZhbGlkIFhNTCcgKyBkZXRhaWxzICsgJyAtLT4nO1xuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlU2NoZW1hWE1MIChuYW1lLCBkZWZpbml0aW9uLCBtb2RlbHMsIGNvbmZpZykge1xuICAgIHZhciAkcmVmID0gXy5pc09iamVjdChkZWZpbml0aW9uKSA/IGRlZmluaXRpb24uJHJlZiA6IG51bGw7XG4gICAgdmFyIG91dHB1dCwgaW5kZXg7XG4gICAgY29uZmlnID0gY29uZmlnIHx8IHt9O1xuICAgIGNvbmZpZy5tb2RlbHNUb0lnbm9yZSA9IGNvbmZpZy5tb2RlbHNUb0lnbm9yZSB8fCBbXTtcbiAgIFxuICAgIHZhciBkZXNjcmlwdG9yID0gXy5pc1N0cmluZygkcmVmKSA/IGdldERlc2NyaXB0b3JCeVJlZigkcmVmLCBuYW1lLCBtb2RlbHMsIGNvbmZpZylcbiAgICAgICAgOiBnZXREZXNjcmlwdG9yKG5hbWUsIGRlZmluaXRpb24sIG1vZGVscywgY29uZmlnKTtcbiAgICBcbiAgICBpZiAoIWRlc2NyaXB0b3IpIHtcbiAgICAgIHJldHVybiBnZXRFcnJvck1lc3NhZ2UoKTtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKGRlc2NyaXB0b3IudHlwZSkge1xuICAgICAgY2FzZSAnYXJyYXknOlxuICAgICAgICBvdXRwdXQgPSBjcmVhdGVBcnJheVhNTChkZXNjcmlwdG9yKTsgYnJlYWs7XG4gICAgICBjYXNlICdvYmplY3QnOlxuICAgICAgICBvdXRwdXQgPSBjcmVhdGVPYmplY3RYTUwoZGVzY3JpcHRvcik7IGJyZWFrO1xuICAgICAgY2FzZSAnbG9vcCc6XG4gICAgICAgIG91dHB1dCA9IGdldEluZmluaXRlTG9vcE1lc3NhZ2UoZGVzY3JpcHRvci5uYW1lLCBkZXNjcmlwdG9yLmNvbmZpZy5sb29wVG8pOyBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIG91dHB1dCA9IGNyZWF0ZVByaW1pdGl2ZVhNTChkZXNjcmlwdG9yKTtcbiAgICB9XG5cbiAgICBpZiAoJHJlZiAmJiBkZXNjcmlwdG9yLnR5cGUgIT09ICdsb29wJykge1xuICAgICAgaW5kZXggPSBjb25maWcubW9kZWxzVG9JZ25vcmUuaW5kZXhPZigkcmVmKTtcbiAgICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICAgIGNvbmZpZy5tb2RlbHNUb0lnbm9yZS5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBvdXRwdXQ7XG4gIH1cblxuICBmdW5jdGlvbiBEZXNjcmlwdG9yIChuYW1lLCB0eXBlLCBkZWZpbml0aW9uLCBtb2RlbHMsIGNvbmZpZykge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgNCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCk7XG4gICAgfVxuICAgIHRoaXMuY29uZmlnID0gY29uZmlnIHx8IHt9O1xuICAgIHRoaXMuY29uZmlnLm1vZGVsc1RvSWdub3JlID0gdGhpcy5jb25maWcubW9kZWxzVG9JZ25vcmUgfHwgW107XG4gICAgLy8gbmFtZSBpcyBhbHJlYWR5IHNldCBieSBnZXREZXNjcmlwdG9yQnlSZWYgb3IgZ2V0RGVzY3JpcHRvciBmdW5jdGlvbiBkZXBlbmRpbmcgb24gdGhlIHR5cGUuIE9ubHkgcHJlZml4LCBpZiBwcmVzZW50IGlzIG5lZWRlZCB0byBiZSBzZXQgaGVyZSB8IGh0dHBzOi8vZ2l0aHViLmNvbS9zd2FnZ2VyLWFwaS9zd2FnZ2VyLXVpL2lzc3Vlcy8yNTc3XG4gICAgdGhpcy5uYW1lID0gZ2V0UHJlZml4KG5hbWUsIGRlZmluaXRpb24ueG1sKTtcbiAgICB0aGlzLmRlZmluaXRpb24gPSBkZWZpbml0aW9uO1xuICAgIHRoaXMubW9kZWxzID0gbW9kZWxzO1xuICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gIH1cblxuICBmdW5jdGlvbiBnZXREZXNjcmlwdG9yQnlSZWYoJHJlZiwgbmFtZSwgbW9kZWxzLCBjb25maWcpIHtcbiAgICB2YXIgbW9kZWxUeXBlID0gc2ltcGxlUmVmKCRyZWYpO1xuICAgIHZhciBtb2RlbCA9IG1vZGVsc1ttb2RlbFR5cGVdIHx8IHt9O1xuICAgIHZhciB0eXBlID0gbW9kZWwuZGVmaW5pdGlvbiAmJiBtb2RlbC5kZWZpbml0aW9uLnR5cGUgPyBtb2RlbC5kZWZpbml0aW9uLnR5cGUgOiAnb2JqZWN0JztcbiAgICAvLyBJZiBtb2RlbCBkZWZpbml0aW9uIHhtbCBuYW1lIGlzIHByZXNlbnQsIHRoZW4gdGhhdCB3aWxsIGJlIHByZWZlcnJlZCBvdmVyIG1vZGVsIG5hbWUuIFRoaXMgaXMgdGhlIGNhc2Ugb2YgcHJlZmVycmluZyBYbWxFbGVtZW50IG5hbWUgb3ZlciBYbWxSb290RWxlbWVudCBuYW1lIGlmIFhtbEVsZW1lbnQgbmFtZSBpcyBwcm92aWRlZCB8IGh0dHBzOi8vZ2l0aHViLmNvbS9zd2FnZ2VyLWFwaS9zd2FnZ2VyLXVpL2lzc3Vlcy8yNTc3XG4gICAgaWYobW9kZWwuZGVmaW5pdGlvbiAmJiBtb2RlbC5kZWZpbml0aW9uLnhtbCAmJiBtb2RlbC5kZWZpbml0aW9uLnhtbC5uYW1lKSB7XG4gICAgICAgIG5hbWUgPSBuYW1lIHx8IG1vZGVsLmRlZmluaXRpb24ueG1sLm5hbWUgfHwgbW9kZWwubmFtZTtcbiAgICB9XG4gICAgLy8gZWxzZSBvbmx5IG1vZGVsIG5hbWUgd2lsbCBiZSBjb25zaWRlcmVkIGZvciBkZXRlcm1pbmF0aW9uIHwgaHR0cHM6Ly9naXRodWIuY29tL3N3YWdnZXItYXBpL3N3YWdnZXItdWkvaXNzdWVzLzI1NzdcbiAgICBlbHNlIHtcbiAgICAgICAgbmFtZSA9IG5hbWUgfHwgbW9kZWwubmFtZTtcbiAgICB9XG4gICAgXG4gICAgaWYgKGNvbmZpZy5tb2RlbHNUb0lnbm9yZS5pbmRleE9mKCRyZWYpID4gLTEpIHtcbiAgICAgIHR5cGUgPSAnbG9vcCc7XG4gICAgICBjb25maWcubG9vcFRvID0gbW9kZWxUeXBlO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25maWcubW9kZWxzVG9JZ25vcmUucHVzaCgkcmVmKTtcbiAgICB9XG5cbiAgICBpZiAoIW1vZGVsLmRlZmluaXRpb24pIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IERlc2NyaXB0b3IobmFtZSwgdHlwZSwgbW9kZWwuZGVmaW5pdGlvbiwgbW9kZWxzLCBjb25maWcpOyAgICBcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldERlc2NyaXB0b3IgKG5hbWUsIGRlZmluaXRpb24sIG1vZGVscywgY29uZmlnKXtcbiAgICB2YXIgdHlwZSA9IGRlZmluaXRpb24udHlwZSB8fCAnb2JqZWN0JztcbiAgICAvLyBJZiBkZWZpbml0aW9uIHhtbCBuYW1lIGlzIHByZXNlbnQsIHRoZW4gdGhhdCB3aWxsIGJlIHByZWZlcnJlZCBvdmVyIG5hbWUgfCBodHRwczovL2dpdGh1Yi5jb20vc3dhZ2dlci1hcGkvc3dhZ2dlci11aS9pc3N1ZXMvMjU3N1xuICAgIGlmKGRlZmluaXRpb24ueG1sICYmIGRlZmluaXRpb24ueG1sLm5hbWUpIHtcbiAgICAgICAgbmFtZSA9IGRlZmluaXRpb24ueG1sLm5hbWUgfHwgbmFtZTtcbiAgICB9XG4gICAgaWYgKCFkZWZpbml0aW9uKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IERlc2NyaXB0b3IobmFtZSwgdHlwZSwgZGVmaW5pdGlvbiwgbW9kZWxzLCBjb25maWcpO1xuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlWE1MU2FtcGxlIChuYW1lLCBkZWZpbml0aW9uLCBtb2RlbHMsIGlzUGFyYW0pIHtcbiAgICB2YXIgcHJvbG9nID0gJzw/eG1sIHZlcnNpb249XCIxLjBcIj8+JztcblxuICAgIHJldHVybiBmb3JtYXRYbWwocHJvbG9nICsgY3JlYXRlU2NoZW1hWE1MKG5hbWUsIGRlZmluaXRpb24sIG1vZGVscywgeyBpc1BhcmFtOiBpc1BhcmFtIH0gKSk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgICAgZ2V0TW9kZWxTaWduYXR1cmU6IGdldE1vZGVsU2lnbmF0dXJlLFxuICAgICAgY3JlYXRlSlNPTlNhbXBsZTogY3JlYXRlSlNPTlNhbXBsZSxcbiAgICAgIGdldFBhcmFtZXRlck1vZGVsU2lnbmF0dXJlOiBnZXRQYXJhbWV0ZXJNb2RlbFNpZ25hdHVyZSxcbiAgICAgIGNyZWF0ZVBhcmFtZXRlckpTT05TYW1wbGU6IGNyZWF0ZVBhcmFtZXRlckpTT05TYW1wbGUsXG4gICAgICBjcmVhdGVTY2hlbWFYTUw6IGNyZWF0ZVNjaGVtYVhNTCxcbiAgICAgIGNyZWF0ZVhNTFNhbXBsZTogY3JlYXRlWE1MU2FtcGxlLFxuICAgICAgZ2V0UHJpbWl0aXZlU2lnbmF0dXJlOiBnZXRQcmltaXRpdmVTaWduYXR1cmVcbiAgfTtcblxufSkoKTtcbiIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLlZpZXdzLlBvcHVwVmlldyA9IEJhY2tib25lLlZpZXcuZXh0ZW5kKHtcbiAgICBldmVudHM6IHtcbiAgICAgICAgJ2NsaWNrIC5hcGktcG9wdXAtY2FuY2VsJzogJ2NhbmNlbENsaWNrJ1xuICAgIH0sXG5cbiAgICB0ZW1wbGF0ZTogSGFuZGxlYmFycy50ZW1wbGF0ZXMucG9wdXAsXG4gICAgY2xhc3NOYW1lOiAnYXBpLXBvcHVwLWRpYWxvZycsXG5cbiAgICBzZWxlY3RvcnM6IHtcbiAgICAgICAgY29udGVudDogJy5hcGktcG9wdXAtY29udGVudCcsXG4gICAgICAgIG1haW4gICA6ICcjc3dhZ2dlci11aS1jb250YWluZXInXG4gICAgfSxcblxuICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uKCl7XG4gICAgICAgIHRoaXMuJGVsLmh0bWwodGhpcy50ZW1wbGF0ZSh0aGlzLm1vZGVsKSk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLiQodGhpcy5zZWxlY3RvcnMuY29udGVudCkuYXBwZW5kKHRoaXMubW9kZWwuY29udGVudCk7XG4gICAgICAgICQodGhpcy5zZWxlY3RvcnMubWFpbikuZmlyc3QoKS5hcHBlbmQodGhpcy5lbCk7XG4gICAgICAgIHRoaXMuc2hvd1BvcHVwKCk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIHNob3dQb3B1cDogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLiRlbC5zaG93KCk7XG4gICAgfSxcblxuICAgIGNhbmNlbENsaWNrOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMucmVtb3ZlKCk7XG4gICAgfVxuXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLlZpZXdzLlJlc291cmNlVmlldyA9IEJhY2tib25lLlZpZXcuZXh0ZW5kKHtcbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24ob3B0cykge1xuICAgIG9wdHMgPSBvcHRzIHx8IHt9O1xuICAgIHRoaXMucm91dGVyID0gb3B0cy5yb3V0ZXI7XG4gICAgdGhpcy5hdXRocyA9IG9wdHMuYXV0aHM7XG4gICAgaWYgKCcnID09PSB0aGlzLm1vZGVsLmRlc2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLm1vZGVsLmRlc2NyaXB0aW9uID0gbnVsbDtcbiAgICB9XG4gICAgaWYgKHRoaXMubW9kZWwuZGVzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMubW9kZWwuc3VtbWFyeSA9IHRoaXMubW9kZWwuZGVzY3JpcHRpb247XG4gICAgfVxuICAgIHRoaXMubnVtYmVyID0gMDtcbiAgfSxcblxuICByZW5kZXI6IGZ1bmN0aW9uKCl7XG4gICAgdmFyIG1ldGhvZHMgPSB7fTtcblxuXG4gICAgJCh0aGlzLmVsKS5odG1sKEhhbmRsZWJhcnMudGVtcGxhdGVzLnJlc291cmNlKHRoaXMubW9kZWwpKTtcblxuICAgIC8vIFJlbmRlciBlYWNoIG9wZXJhdGlvblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5tb2RlbC5vcGVyYXRpb25zQXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBvcGVyYXRpb24gPSB0aGlzLm1vZGVsLm9wZXJhdGlvbnNBcnJheVtpXTtcbiAgICAgIHZhciBjb3VudGVyID0gMDtcbiAgICAgIHZhciBpZCA9IG9wZXJhdGlvbi5uaWNrbmFtZTtcblxuICAgICAgd2hpbGUgKHR5cGVvZiBtZXRob2RzW2lkXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgaWQgPSBpZCArICdfJyArIGNvdW50ZXI7XG4gICAgICAgIGNvdW50ZXIgKz0gMTtcbiAgICAgIH1cblxuICAgICAgbWV0aG9kc1tpZF0gPSBvcGVyYXRpb247XG5cbiAgICAgIG9wZXJhdGlvbi5uaWNrbmFtZSA9IGlkO1xuICAgICAgb3BlcmF0aW9uLnBhcmVudElkID0gdGhpcy5tb2RlbC5pZDtcbiAgICAgIG9wZXJhdGlvbi5kZWZpbml0aW9ucyA9IHRoaXMubW9kZWwuZGVmaW5pdGlvbnM7IC8vIG1ha2UgSnNvbiBTY2hlbWEgYXZhaWxhYmxlIGZvciBKU29uRWRpdG9yIGluIHRoaXMgb3BlcmF0aW9uXG4gICAgICB0aGlzLmFkZE9wZXJhdGlvbihvcGVyYXRpb24pO1xuICAgIH1cblxuICAgICQoJy50b2dnbGVFbmRwb2ludExpc3QnLCB0aGlzLmVsKS5jbGljayh0aGlzLmNhbGxEb2NzLmJpbmQodGhpcywgJ3RvZ2dsZUVuZHBvaW50TGlzdEZvclJlc291cmNlJykpO1xuICAgICQoJy5jb2xsYXBzZVJlc291cmNlJywgdGhpcy5lbCkuY2xpY2sodGhpcy5jYWxsRG9jcy5iaW5kKHRoaXMsICdjb2xsYXBzZU9wZXJhdGlvbnNGb3JSZXNvdXJjZScpKTtcbiAgICAkKCcuZXhwYW5kUmVzb3VyY2UnLCB0aGlzLmVsKS5jbGljayh0aGlzLmNhbGxEb2NzLmJpbmQodGhpcywgJ2V4cGFuZE9wZXJhdGlvbnNGb3JSZXNvdXJjZScpKTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9LFxuXG4gIGFkZE9wZXJhdGlvbjogZnVuY3Rpb24ob3BlcmF0aW9uKSB7XG5cbiAgICBvcGVyYXRpb24ubnVtYmVyID0gdGhpcy5udW1iZXI7XG5cbiAgICAvLyBSZW5kZXIgYW4gb3BlcmF0aW9uIGFuZCBhZGQgaXQgdG8gb3BlcmF0aW9ucyBsaVxuICAgIHZhciBvcGVyYXRpb25WaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5PcGVyYXRpb25WaWV3KHtcbiAgICAgIG1vZGVsOiBvcGVyYXRpb24sXG4gICAgICByb3V0ZXI6IHRoaXMucm91dGVyLFxuICAgICAgdGFnTmFtZTogJ2xpJyxcbiAgICAgIGNsYXNzTmFtZTogJ2VuZHBvaW50JyxcbiAgICAgIHN3YWdnZXJPcHRpb25zOiB0aGlzLm9wdGlvbnMuc3dhZ2dlck9wdGlvbnMsXG4gICAgICBhdXRoczogdGhpcy5hdXRoc1xuICAgIH0pO1xuXG4gICAgJCgnLmVuZHBvaW50cycsICQodGhpcy5lbCkpLmFwcGVuZChvcGVyYXRpb25WaWV3LnJlbmRlcigpLmVsKTtcblxuICAgIHRoaXMubnVtYmVyKys7XG5cbiAgfSxcbiAgLy8gR2VuZXJpYyBFdmVudCBoYW5kbGVyIChgRG9jc2AgaXMgZ2xvYmFsKVxuXG5cbiAgY2FsbERvY3M6IGZ1bmN0aW9uKGZuTmFtZSwgZSkge1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBEb2NzW2ZuTmFtZV0oZS5jdXJyZW50VGFyZ2V0LmdldEF0dHJpYnV0ZSgnZGF0YS1pZCcpKTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5SZXNwb25zZUNvbnRlbnRUeXBlVmlldyA9IEJhY2tib25lLlZpZXcuZXh0ZW5kKHtcbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oKXt9LFxuXG4gIHJlbmRlcjogZnVuY3Rpb24oKXtcbiAgICB0aGlzLm1vZGVsLnJlc3BvbnNlQ29udGVudFR5cGVJZCA9ICdyY3QnICsgTWF0aC5yYW5kb20oKTtcbiAgICAkKHRoaXMuZWwpLmh0bWwoSGFuZGxlYmFycy50ZW1wbGF0ZXMucmVzcG9uc2VfY29udGVudF90eXBlKHRoaXMubW9kZWwpKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxufSk7IiwiJ3VzZSBzdHJpY3QnO1xuXG5Td2FnZ2VyVWkuVmlld3MuU2lnbmF0dXJlVmlldyA9IEJhY2tib25lLlZpZXcuZXh0ZW5kKHtcbiAgZXZlbnRzOiB7XG4gICAgJ2NsaWNrIGEuZGVzY3JpcHRpb24tbGluaycgICAgICAgOiAnc3dpdGNoVG9EZXNjcmlwdGlvbicsXG4gICAgJ2NsaWNrIGEuc25pcHBldC1saW5rJyAgICAgICAgICAgOiAnc3dpdGNoVG9TbmlwcGV0JyxcbiAgICAnbW91c2Vkb3duIC5zbmlwcGV0X2pzb24nICAgICAgICAgIDogJ2pzb25TbmlwcGV0TW91c2VEb3duJyxcbiAgICAnbW91c2Vkb3duIC5zbmlwcGV0X3htbCcgICAgICAgICAgOiAneG1sU25pcHBldE1vdXNlRG93bidcbiAgfSxcblxuICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7XG4gIH0sXG5cbiAgcmVuZGVyOiBmdW5jdGlvbigpe1xuXG4gICAgJCh0aGlzLmVsKS5odG1sKEhhbmRsZWJhcnMudGVtcGxhdGVzLnNpZ25hdHVyZSh0aGlzLm1vZGVsKSk7XG5cbiAgICBpZiAodGhpcy5tb2RlbC5kZWZhdWx0UmVuZGVyaW5nID09PSAnbW9kZWwnKSB7XG4gICAgICB0aGlzLnN3aXRjaFRvRGVzY3JpcHRpb24oKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zd2l0Y2hUb1NuaXBwZXQoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfSxcblxuICAvLyBoYW5kbGVyIGZvciBzaG93IHNpZ25hdHVyZVxuICBzd2l0Y2hUb0Rlc2NyaXB0aW9uOiBmdW5jdGlvbihlKXtcbiAgICBpZiAoZSkgeyBlLnByZXZlbnREZWZhdWx0KCk7IH1cblxuICAgICQoJy5zbmlwcGV0JywgJCh0aGlzLmVsKSkuaGlkZSgpO1xuICAgICQoJy5kZXNjcmlwdGlvbicsICQodGhpcy5lbCkpLnNob3coKTtcbiAgICAkKCcuZGVzY3JpcHRpb24tbGluaycsICQodGhpcy5lbCkpLmFkZENsYXNzKCdzZWxlY3RlZCcpO1xuICAgICQoJy5zbmlwcGV0LWxpbmsnLCAkKHRoaXMuZWwpKS5yZW1vdmVDbGFzcygnc2VsZWN0ZWQnKTtcbiAgfSxcblxuICAvLyBoYW5kbGVyIGZvciBzaG93IHNhbXBsZVxuICBzd2l0Y2hUb1NuaXBwZXQ6IGZ1bmN0aW9uKGUpe1xuICAgIGlmIChlKSB7IGUucHJldmVudERlZmF1bHQoKTsgfVxuXG4gICAgJCgnLnNuaXBwZXQnLCAkKHRoaXMuZWwpKS5zaG93KCk7XG4gICAgJCgnLmRlc2NyaXB0aW9uJywgJCh0aGlzLmVsKSkuaGlkZSgpO1xuICAgICQoJy5zbmlwcGV0LWxpbmsnLCAkKHRoaXMuZWwpKS5hZGRDbGFzcygnc2VsZWN0ZWQnKTtcbiAgICAkKCcuZGVzY3JpcHRpb24tbGluaycsICQodGhpcy5lbCkpLnJlbW92ZUNsYXNzKCdzZWxlY3RlZCcpO1xuICB9LFxuXG4gIC8vIGhhbmRsZXIgZm9yIHNuaXBwZXQgdG8gdGV4dCBhcmVhXG4gIHNuaXBwZXRUb1RleHRBcmVhOiBmdW5jdGlvbih2YWwpIHtcbiAgICB2YXIgdGV4dEFyZWEgPSAkKCd0ZXh0YXJlYScsICQodGhpcy5lbC5wYXJlbnROb2RlLnBhcmVudE5vZGUucGFyZW50Tm9kZSkpO1xuXG4gICAgLy8gRml4IGZvciBidWcgaW4gSUUgMTAvMTEgd2hpY2ggY2F1c2VzIHBsYWNlaG9sZGVyIHRleHQgdG8gYmUgY29waWVkIHRvIFwidmFsdWVcIlxuICAgIGlmICgkLnRyaW0odGV4dEFyZWEudmFsKCkpID09PSAnJyB8fCB0ZXh0QXJlYS5wcm9wKCdwbGFjZWhvbGRlcicpID09PSB0ZXh0QXJlYS52YWwoKSkge1xuICAgICAgdGV4dEFyZWEudmFsKHZhbCk7XG4gICAgICAvLyBUT0RPIG1vdmUgdGhpcyBjb2RlIG91dHNpZGUgb2YgdGhlIHZpZXcgYW5kIGV4cG9zZSBhbiBldmVudCBpbnN0ZWFkXG4gICAgICBpZiggdGhpcy5tb2RlbC5qc29uRWRpdG9yICYmIHRoaXMubW9kZWwuanNvbkVkaXRvci5pc0VuYWJsZWQoKSl7XG4gICAgICAgIHRoaXMubW9kZWwuanNvbkVkaXRvci5zZXRWYWx1ZShKU09OLnBhcnNlKHRoaXMubW9kZWwuc2FtcGxlSlNPTikpO1xuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICBqc29uU25pcHBldE1vdXNlRG93bjogZnVuY3Rpb24gKGUpIHtcbiAgICBpZiAodGhpcy5tb2RlbC5pc1BhcmFtKSB7XG4gICAgICBpZiAoZSkgeyBlLnByZXZlbnREZWZhdWx0KCk7IH1cblxuICAgICAgdGhpcy5zbmlwcGV0VG9UZXh0QXJlYSh0aGlzLm1vZGVsLnNhbXBsZUpTT04pO1xuICAgIH1cbiAgfSxcblxuICB4bWxTbmlwcGV0TW91c2VEb3duOiBmdW5jdGlvbiAoZSkge1xuICAgIGlmICh0aGlzLm1vZGVsLmlzUGFyYW0pIHtcbiAgICAgIGlmIChlKSB7IGUucHJldmVudERlZmF1bHQoKTsgfVxuXG4gICAgICB0aGlzLnNuaXBwZXRUb1RleHRBcmVhKHRoaXMubW9kZWwuc2FtcGxlWE1MKTtcbiAgICB9XG4gIH1cbn0pOyIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLlZpZXdzLlN0YXR1c0NvZGVWaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoe1xuICBpbml0aWFsaXplOiBmdW5jdGlvbiAob3B0cykge1xuICAgIHRoaXMub3B0aW9ucyA9IG9wdHMgfHwge307XG4gICAgdGhpcy5yb3V0ZXIgPSB0aGlzLm9wdGlvbnMucm91dGVyO1xuICB9LFxuXG4gIHJlbmRlcjogZnVuY3Rpb24oKXtcbiAgICB2YXIgcmVzcG9uc2VNb2RlbCwgcmVzcG9uc2VNb2RlbFZpZXc7XG4gICAgdmFyIHZhbHVlID0gdGhpcy5yb3V0ZXIuYXBpLm1vZGVsc1t0aGlzLm1vZGVsLnJlc3BvbnNlTW9kZWxdO1xuICAgICQodGhpcy5lbCkuaHRtbChIYW5kbGViYXJzLnRlbXBsYXRlcy5zdGF0dXNfY29kZSh0aGlzLm1vZGVsKSk7XG5cbiAgICBpZiAodGhpcy5yb3V0ZXIuYXBpLm1vZGVscy5oYXNPd25Qcm9wZXJ0eSh0aGlzLm1vZGVsLnJlc3BvbnNlTW9kZWwpKSB7XG4gICAgICByZXNwb25zZU1vZGVsID0ge1xuICAgICAgICBzYW1wbGVKU09OOiBKU09OLnN0cmluZ2lmeShTd2FnZ2VyVWkucGFydGlhbHMuc2lnbmF0dXJlLmNyZWF0ZUpTT05TYW1wbGUodmFsdWUpLCB2b2lkIDAsIDIpLFxuICAgICAgICBzYW1wbGVYTUw6IHRoaXMubW9kZWwuaXNYTUwgPyBTd2FnZ2VyVWkucGFydGlhbHMuc2lnbmF0dXJlLmNyZWF0ZVhNTFNhbXBsZSgnJywgdGhpcy5tb2RlbC5zY2hlbWEsIHRoaXMucm91dGVyLmFwaS5tb2RlbHMpIDogZmFsc2UsXG4gICAgICAgIGlzUGFyYW06IGZhbHNlLFxuICAgICAgICBzaWduYXR1cmU6IFN3YWdnZXJVaS5wYXJ0aWFscy5zaWduYXR1cmUuZ2V0TW9kZWxTaWduYXR1cmUodGhpcy5tb2RlbC5yZXNwb25zZU1vZGVsLCB2YWx1ZSwgdGhpcy5yb3V0ZXIuYXBpLm1vZGVscyksXG4gICAgICAgIGRlZmF1bHRSZW5kZXJpbmc6IHRoaXMubW9kZWwuZGVmYXVsdFJlbmRlcmluZ1xuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzcG9uc2VNb2RlbCA9IHtcbiAgICAgICAgc2lnbmF0dXJlOiBTd2FnZ2VyVWkucGFydGlhbHMuc2lnbmF0dXJlLmdldFByaW1pdGl2ZVNpZ25hdHVyZSh0aGlzLm1vZGVsLnNjaGVtYSlcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmVzcG9uc2VNb2RlbFZpZXcgPSBuZXcgU3dhZ2dlclVpLlZpZXdzLlNpZ25hdHVyZVZpZXcoe21vZGVsOiByZXNwb25zZU1vZGVsLCB0YWdOYW1lOiAnZGl2J30pO1xuICAgICQoJy5tb2RlbC1zaWduYXR1cmUnLCB0aGlzLiRlbCkuYXBwZW5kKHJlc3BvbnNlTW9kZWxWaWV3LnJlbmRlcigpLmVsKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxufSk7Il19