aboutsummaryrefslogtreecommitdiffstats
path: root/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/swagger-ui.js
diff options
context:
space:
mode:
Diffstat (limited to 'ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/swagger-ui.js')
-rw-r--r--ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/swagger-ui.js25378
1 files changed, 0 insertions, 25378 deletions
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/swagger-ui.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/swagger-ui.js
deleted file mode 100644
index c76ffb75f..000000000
--- a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/swagger-ui.js
+++ /dev/null
@@ -1,25378 +0,0 @@
-/**
- * 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=\"#\" data-sw-translate>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.schema) ? param.type || param.schema.type || '' : param.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.32
- * @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' && typeof(window.location) !== 'undefined') {
- 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 && self.url && 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 && typeof this.spec === 'object') {
- 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 location !== 'undefined' && typeof(location.scheme) !== 'undefined') {
- this.scheme = location.scheme;
- }
- if(typeof window !== 'undefined' && typeof(window.location) !== 'undefined') {
- // use the window scheme
- this.scheme = window.location.protocol.replace(':','');
- }
- else {
- this.scheme = location.scheme || 'http';
- }
- } else if (typeof window !== 'undefined' && typeof(window.location) !== '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' && typeof(window.location) !== '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 {
- if((typeof(param['x-escape']) === 'undefined') || (param['x-escape'] === true)) {
- 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];
- }
- } else if(param.in === 'query' && typeof args[param.name] === 'undefined' && param.allowEmptyValue === true) {
- if (querystring === '' && requestUrl.indexOf('?') < 0) {
- querystring += '?';
- } else {
- querystring += '&';
- }
-
- if (typeof param.collectionFormat !== 'undefined' || param.type === 'array') {
- var qp;
- var collectionFormat = param.collectionFormat || 'multi';
-
- if (Array.isArray(qp)) {
- querystring += this.encodeQueryCollection(collectionFormat, param.name, qp, isPassword);
- } else {
- querystring += this.encodeQueryCollection(collectionFormat, param.name, [qp], isPassword);
- }
- } else {
- querystring += this.encodeQueryKey(param.name) + '=' + this.encodeQueryParam('', isPassword);
- }
-
- }
- }
- 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) {
- if(opts.requestInterceptor) {
- opts.requestInterceptor.apply(obj);
- }
- 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 "******";
- }
- if(arg !== undefined && arg !== null) {
- return encodeURIComponent(arg);
- }
- else {
- return '';
- }
-};
-
-/**
- * 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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlbXBsYXRlcy5qcyIsImRvYy5qcyIsImVzNS1zaGltLmpzIiwiaGVscGVycy9oYW5kbGViYXJzLmpzIiwic2FuaXRpemUtaHRtbC5taW4uanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1wYWNrL19wcmVsdWRlLmpzIiwiaW5kZXguanMiLCJsaWIvYXV0aC5qcyIsImxpYi9jbGllbnQuanMiLCJsaWIvaGVscGVycy5qcyIsImxpYi9odHRwLmpzIiwibGliL3Jlc29sdmVyLmpzIiwibGliL3NjaGVtYS1tYXJrdXAuanMiLCJsaWIvc3BlYy1jb252ZXJ0ZXIuanMiLCJsaWIvdHlwZXMvbW9kZWwuanMiLCJsaWIvdHlwZXMvb3BlcmF0aW9uLmpzIiwibGliL3R5cGVzL29wZXJhdGlvbkdyb3VwLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9idG9hL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2J1ZmZlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9idWZmZXIvbm9kZV9tb2R1bGVzL2Jhc2U2NC1qcy9saWIvYjY0LmpzIiwibm9kZV9tb2R1bGVzL2J1ZmZlci9ub2RlX21vZHVsZXMvaWVlZTc1NC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9idWZmZXIvbm9kZV9tb2R1bGVzL2lzLWFycmF5L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Nvb2tpZWphci9jb29raWVqYXIuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvY29tbW9uLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvZHVtcGVyLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvZXhjZXB0aW9uLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvbG9hZGVyLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvbWFyay5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3NjaGVtYS5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3NjaGVtYS9jb3JlLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvc2NoZW1hL2RlZmF1bHRfZnVsbC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3NjaGVtYS9kZWZhdWx0X3NhZmUuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC9zY2hlbWEvZmFpbHNhZmUuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC9zY2hlbWEvanNvbi5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL2JpbmFyeS5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvYm9vbC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvZmxvYXQuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL2ludC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvanMvZnVuY3Rpb24uanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL2pzL3JlZ2V4cC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvanMvdW5kZWZpbmVkLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9tYXAuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL21lcmdlLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9udWxsLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9vbWFwLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9wYWlycy5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvc2VxLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9zZXQuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL3N0ci5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvdGltZXN0YW1wLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvYXJyYXkvaW5kZXhPZi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2FycmF5L2xhc3QuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jaGFpbi9sb2Rhc2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2VhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2ZpbmQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2ZvckVhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2luY2x1ZGVzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9tYXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9kYXRlL25vdy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2Z1bmN0aW9uL2JpbmQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9mdW5jdGlvbi9yZXN0UGFyYW0uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9MYXp5V3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL0xvZGFzaFdyYXBwZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9hcnJheUNvcHkuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9hcnJheUVhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9hcnJheU1hcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2FycmF5U29tZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VBc3NpZ24uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlQ2FsbGJhY2suanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlQ2xvbmUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlQ29weS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VDcmVhdGUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlRWFjaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VGaW5kLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUZpbmRJbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VGb3IuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlRm9ySW4uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlRm9yT3duLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUdldC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VJbmRleE9mLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUlzRXF1YWwuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlSXNFcXVhbERlZXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlSXNNYXRjaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VMb2Rhc2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlTWFwLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZU1hdGNoZXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlTWF0Y2hlc1Byb3BlcnR5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVByb3BlcnR5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVByb3BlcnR5RGVlcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VTZXREYXRhLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVNsaWNlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVRvU3RyaW5nLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVZhbHVlcy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2JpbmFyeUluZGV4LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmluYXJ5SW5kZXhCeS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2JpbmRDYWxsYmFjay5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2J1ZmZlckNsb25lLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY29tcG9zZUFyZ3MuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jb21wb3NlQXJnc1JpZ2h0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlQmFzZUVhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jcmVhdGVCYXNlRm9yLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlQmluZFdyYXBwZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jcmVhdGVDdG9yV3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NyZWF0ZUZpbmQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jcmVhdGVGb3JFYWNoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlSHlicmlkV3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NyZWF0ZVBhcnRpYWxXcmFwcGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlV3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2VxdWFsQXJyYXlzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvZXF1YWxCeVRhZy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2VxdWFsT2JqZWN0cy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldERhdGEuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9nZXRGdW5jTmFtZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldExlbmd0aC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldE1hdGNoRGF0YS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldE5hdGl2ZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2luZGV4T2ZOYU4uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pbml0Q2xvbmVBcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2luaXRDbG9uZUJ5VGFnLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaW5pdENsb25lT2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaXNBcnJheUxpa2UuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0hvc3RPYmplY3QuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaXNJdGVyYXRlZUNhbGwuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0tleS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2lzTGF6aWFibGUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0xlbmd0aC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2lzT2JqZWN0TGlrZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2lzU3RyaWN0Q29tcGFyYWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL21lcmdlRGF0YS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL21ldGFNYXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9yZWFsTmFtZXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9yZW9yZGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvcmVwbGFjZUhvbGRlcnMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9zZXREYXRhLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvc2hpbUtleXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC90b09iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL3RvUGF0aC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL3dyYXBwZXJDbG9uZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvY2xvbmVEZWVwLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc0FyZ3VtZW50cy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNBcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNFbXB0eS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNGdW5jdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNOYXRpdmUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9sYW5nL2lzT2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc1BsYWluT2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc1N0cmluZy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNUeXBlZEFycmF5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc1VuZGVmaW5lZC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L29iamVjdC9rZXlzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvb2JqZWN0L2tleXNJbi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L29iamVjdC9wYWlycy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L29iamVjdC92YWx1ZXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9zdXBwb3J0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvdXRpbGl0eS9pZGVudGl0eS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L3V0aWxpdHkvbm9vcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L3V0aWxpdHkvcHJvcGVydHkuanMiLCJub2RlX21vZHVsZXMvcS9xLmpzIiwibm9kZV9tb2R1bGVzL3N1cGVyYWdlbnQvbGliL2NsaWVudC5qcyIsIm5vZGVfbW9kdWxlcy9zdXBlcmFnZW50L2xpYi9pcy1vYmplY3QuanMiLCJub2RlX21vZHVsZXMvc3VwZXJhZ2VudC9saWIvcmVxdWVzdC1iYXNlLmpzIiwibm9kZV9tb2R1bGVzL3N1cGVyYWdlbnQvbGliL3JlcXVlc3QuanMiLCJub2RlX21vZHVsZXMvc3VwZXJhZ2VudC9ub2RlX21vZHVsZXMvY29tcG9uZW50LWVtaXR0ZXIvaW5kZXguanMiLCJTd2FnZ2VyVWkuanMiLCJ1dGlscy91dGlscy5qcyIsInZpZXcvQXBpS2V5QXV0aE1vZGVsLmpzIiwidmlldy9BcGlLZXlBdXRoVmlldy5qcyIsInZpZXcvQXV0aEJ1dHRvblZpZXcuanMiLCJ2aWV3L0F1dGhzQ29sbGVjdGlvbi5qcyIsInZpZXcvQXV0aHNDb2xsZWN0aW9uVmlldy5qcyIsInZpZXcvQXV0aFZpZXcuanMiLCJ2aWV3L0Jhc2ljQXV0aE1vZGVsLmpzIiwidmlldy9CYXNpY0F1dGhWaWV3LmpzIiwidmlldy9Db250ZW50VHlwZVZpZXcuanMiLCJ2aWV3L0hlYWRlclZpZXcuanMiLCJ2aWV3L01haW5WaWV3LmpzIiwidmlldy9PYXV0aDJNb2RlbC5qcyIsInZpZXcvT2F1dGgyVmlldy5qcyIsInZpZXcvT3BlcmF0aW9uVmlldy5qcyIsInZpZXcvUGFyYW1ldGVyQ29udGVudFR5cGVWaWV3LmpzIiwidmlldy9QYXJhbWV0ZXJWaWV3LmpzIiwidmlldy9wYXJ0aWFscy9zaWduYXR1cmUuanMiLCJ2aWV3L1BvcHVwVmlldy5qcyIsInZpZXcvUmVzb3VyY2VWaWV3LmpzIiwidmlldy9SZXNwb25zZUNvbnRlbnRUeXBlVmlldy5qcyIsInZpZXcvU2lnbmF0dXJlVmlldy5qcyIsInZpZXcvU3RhdHVzQ29kZVZpZXcuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDMXhCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUN4TUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ2poRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNuR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNOQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNySkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4WEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5NEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdnQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM29CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDanZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNy9DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbHlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbGpEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4S0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3SEE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbmdFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2g5QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNiQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNuS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNsVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQy9FQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUM1Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDcEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUM5RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDckRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUM1TkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNwREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQy9DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ2hKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUMxRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ2xGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDbjNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQzdMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUM3OUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDcENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDM0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQzNFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6InN3YWdnZXItdWkuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovIFxuIHsoZnVuY3Rpb24oKSB7XG4gIHZhciB0ZW1wbGF0ZSA9IEhhbmRsZWJhcnMudGVtcGxhdGUsIHRlbXBsYXRlcyA9IEhhbmRsZWJhcnMudGVtcGxhdGVzID0gSGFuZGxlYmFycy50ZW1wbGF0ZXMgfHwge307XG50ZW1wbGF0ZXNbJ2FwaWtleV9hdXRoJ10gPSB0ZW1wbGF0ZSh7XCIxXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiBcIiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cXFwia2V5X2F1dGhfX3ZhbHVlXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbHVlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvc3Bhbj5cXG5cIjtcbn0sXCIzXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgICAgICAgICAgICAgICAgPGlucHV0IHBsYWNlaG9sZGVyPVxcXCJhcGlfa2V5XFxcIiBjbGFzcz1cXFwiYXV0aF9pbnB1dCBpbnB1dF9hcGlLZXlfZW50cnlcXFwiIG5hbWU9XFxcImFwaUtleVxcXCIgdHlwZT1cXFwidGV4dFxcXCIvPlxcblwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIjxkaXYgY2xhc3M9XFxcImtleV9pbnB1dF9jb250YWluZXJcXFwiPlxcbiAgICA8aDMgY2xhc3M9XFxcImF1dGhfX3RpdGxlXFxcIj5BcGkga2V5IGF1dGhvcml6YXRpb248L2gzPlxcbiAgICA8ZGl2IGNsYXNzPVxcXCJhdXRoX19kZXNjcmlwdGlvblxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmRlc2NyaXB0aW9uIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvZGl2PlxcbiAgICA8ZGl2PlxcbiAgICAgICAgPGRpdiBjbGFzcz1cXFwia2V5X2F1dGhfX2ZpZWxkXFxcIj5cXG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cXFwia2V5X2F1dGhfX2xhYmVsXFxcIj5uYW1lOjwvc3Bhbj5cXG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cXFwia2V5X2F1dGhfX3ZhbHVlXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3NwYW4+XFxuICAgICAgICA8L2Rpdj5cXG4gICAgICAgIDxkaXYgY2xhc3M9XFxcImtleV9hdXRoX19maWVsZFxcXCI+XFxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XFxcImtleV9hdXRoX19sYWJlbFxcXCI+aW46PC9zcGFuPlxcbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVxcXCJrZXlfYXV0aF9fdmFsdWVcXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwW1wiaW5cIl0gOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvc3Bhbj5cXG4gICAgICAgIDwvZGl2PlxcbiAgICAgICAgPGRpdiBjbGFzcz1cXFwia2V5X2F1dGhfX2ZpZWxkXFxcIj5cXG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cXFwia2V5X2F1dGhfX2xhYmVsXFxcIj52YWx1ZTo8L3NwYW4+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc0xvZ291dCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oMywgZGF0YSwgMCksXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiICAgICAgICA8L2Rpdj5cXG4gICAgPC9kaXY+XFxuPC9kaXY+XFxuXCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1snYXV0aF9idXR0b24nXSA9IHRlbXBsYXRlKHtcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIjxhIGNsYXNzPSdhdXRob3JpemVfX2J0bicgaHJlZj1cXFwiI1xcXCI+QXV0aG9yaXplPC9hPlxcblwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ2F1dGhfYnV0dG9uX29wZXJhdGlvbiddID0gdGVtcGxhdGUoe1wiMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiICAgICAgICBhdXRob3JpemVfX2J0bl9vcGVyYXRpb25fbG9naW5cXG5cIjtcbn0sXCIzXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgICAgICAgIGF1dGhvcml6ZV9fYnRuX29wZXJhdGlvbl9sb2dvdXRcXG5cIjtcbn0sXCI1XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiBcIiAgICAgICAgPHVsIGNsYXNzPVxcXCJhdXRob3JpemUtc2NvcGVzXFxcIj5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzLmVhY2guY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zY29wZXMgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVhY2hcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oNiwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiICAgICAgICA8L3VsPlxcblwiO1xufSxcIjZcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIiAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XFxcImF1dGhvcml6ZV9fc2NvcGVcXFwiIHRpdGxlPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5kZXNjcmlwdGlvbiA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zY29wZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9saT5cXG5cIjtcbn0sXCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fTtcblxuICByZXR1cm4gXCI8ZGl2IGNsYXNzPVxcXCJhdXRob3JpemVfX2J0biBhdXRob3JpemVfX2J0bl9vcGVyYXRpb25cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzTG9nb3V0IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSgzLCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiPlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc2NvcGVzIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSg1LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2Rpdj5cXG5cIjtcbn0sXCJ1c2VEYXRhXCI6dHJ1ZX0pO1xudGVtcGxhdGVzWydhdXRoX3ZpZXcnXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cXFwiYnV0dG9uXFxcIiBjbGFzcz1cXFwiYXV0aF9fYnV0dG9uIGF1dGhfc3VibWl0X19idXR0b25cXFwiIGRhdGEtc3ctdHJhbnNsYXRlPkF1dGhvcml6ZTwvYnV0dG9uPlxcblwiO1xufSxcIjNcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cXFwiYnV0dG9uXFxcIiBjbGFzcz1cXFwiYXV0aF9fYnV0dG9uIGF1dGhfbG9nb3V0X19idXR0b25cXFwiIGRhdGEtc3ctdHJhbnNsYXRlPkxvZ291dDwvYnV0dG9uPlxcblwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9O1xuXG4gIHJldHVybiBcIjxkaXYgY2xhc3M9XFxcImF1dGhfY29udGFpbmVyXFxcIj5cXG5cXG4gICAgPGRpdiBjbGFzcz1cXFwiYXV0aF9pbm5lclxcXCI+PC9kaXY+XFxuICAgIDxkaXYgY2xhc3M9XFxcImF1dGhfc3VibWl0XFxcIj5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzLnVubGVzcy5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaXNMb2dvdXQgOiBkZXB0aDApLHtcIm5hbWVcIjpcInVubGVzc1wiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzQXV0aG9yaXplZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMywgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiICAgIDwvZGl2PlxcblxcbjwvZGl2PlxcblwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ2Jhc2ljX2F1dGgnXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAtIGF1dGhvcml6ZWRcIjtcbn0sXCIzXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiBcIiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cXFwiYmFzaWNfYXV0aF9fdmFsdWVcXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC51c2VybmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9zcGFuPlxcblwiO1xufSxcIjVcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgICAgICAgICAgICAgICA8aW5wdXQgcmVxdWlyZWQgcGxhY2Vob2xkZXI9XFxcInVzZXJuYW1lXFxcIiBjbGFzcz1cXFwiYmFzaWNfYXV0aF9fdXNlcm5hbWUgYXV0aF9pbnB1dFxcXCIgbmFtZT1cXFwidXNlcm5hbWVcXFwiIHR5cGU9XFxcInRleHRcXFwiLz5cXG5cIjtcbn0sXCI3XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJhdXRoX2xhYmVsXFxcIj5cXG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XFxcImJhc2ljX2F1dGhfX2xhYmVsXFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5wYXNzd29yZDo8L3NwYW4+XFxuICAgICAgICAgICAgICAgIDxpbnB1dCByZXF1aXJlZCBwbGFjZWhvbGRlcj1cXFwicGFzc3dvcmRcXFwiIGNsYXNzPVxcXCJiYXNpY19hdXRoX19wYXNzd29yZCBhdXRoX2lucHV0XFxcIiBuYW1lPVxcXCJwYXNzd29yZFxcXCIgdHlwZT1cXFwicGFzc3dvcmRcXFwiLz48L2xhYmVsPlxcbiAgICAgICAgICAgIDwvZGl2PlxcblwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9O1xuXG4gIHJldHVybiBcIjxkaXYgY2xhc3M9J2Jhc2ljX2F1dGhfY29udGFpbmVyJz5cXG4gICAgPGgzIGNsYXNzPVxcXCJhdXRoX190aXRsZVxcXCI+QmFzaWMgYXV0aGVudGljYXRpb25cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzTG9nb3V0IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2gzPlxcbiAgICA8Zm9ybSBjbGFzcz1cXFwiYmFzaWNfaW5wdXRfY29udGFpbmVyXFxcIj5cXG4gICAgICAgIDxkaXYgY2xhc3M9XFxcImF1dGhfX2Rlc2NyaXB0aW9uXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZGVzY3JpcHRpb24gOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9kaXY+XFxuICAgICAgICA8ZGl2IGNsYXNzPVxcXCJhdXRoX2xhYmVsXFxcIj5cXG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cXFwiYmFzaWNfYXV0aF9fbGFiZWxcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPnVzZXJuYW1lOjwvc3Bhbj5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzTG9nb3V0IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgzLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSg1LCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgICAgICAgIDwvZGl2PlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnMudW5sZXNzLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc0xvZ291dCA6IGRlcHRoMCkse1wibmFtZVwiOlwidW5sZXNzXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDcsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgICA8L2Zvcm0+XFxuPC9kaXY+XFxuXCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1snY29udGVudF90eXBlJ10gPSB0ZW1wbGF0ZSh7XCIxXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiAoKHN0YWNrMSA9IGhlbHBlcnMuZWFjaC5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnByb2R1Y2VzIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlYWNoXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDIsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpO1xufSxcIjJcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIlx0PG9wdGlvbiB2YWx1ZT1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsZGVwdGgwLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSxkZXB0aDAse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L29wdGlvbj5cXG5cIjtcbn0sXCI0XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgIDxvcHRpb24gdmFsdWU9XFxcImFwcGxpY2F0aW9uL2pzb25cXFwiPmFwcGxpY2F0aW9uL2pzb248L29wdGlvbj5cXG5cIjtcbn0sXCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCI8bGFiZWwgZGF0YS1zdy10cmFuc2xhdGUgZm9yPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5jb250ZW50VHlwZUlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiPlJlc3BvbnNlIENvbnRlbnQgVHlwZTwvbGFiZWw+XFxuPHNlbGVjdCBuYW1lPVxcXCJjb250ZW50VHlwZVxcXCIgaWQ9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmNvbnRlbnRUeXBlSWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCI+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5wcm9kdWNlcyA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oNCwgZGF0YSwgMCksXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9zZWxlY3Q+XFxuXCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1snbWFpbiddID0gdGVtcGxhdGUoe1wiMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiICA8ZGl2IGNsYXNzPVxcXCJpbmZvX3RpdGxlXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS50aXRsZSA6IHN0YWNrMSkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2Rpdj5cXG4gIDxkaXYgY2xhc3M9XFxcImluZm9fZGVzY3JpcHRpb24gbWFya2Rvd25cXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmluZm8gOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLmRlc2NyaXB0aW9uIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvZGl2PlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZXh0ZXJuYWxEb2NzIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgyLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgIFwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS50ZXJtc09mU2VydmljZVVybCA6IHN0YWNrMSkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oNCwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuICBcIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKChzdGFjazEgPSAoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS5jb250YWN0IDogc3RhY2sxKSkgIT0gbnVsbCA/IHN0YWNrMS5uYW1lIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSg2LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG4gIFwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9ICgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmluZm8gOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLmNvbnRhY3QgOiBzdGFjazEpKSAhPSBudWxsID8gc3RhY2sxLnVybCA6IHN0YWNrMSkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oOCwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuICBcIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKChzdGFjazEgPSAoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS5jb250YWN0IDogc3RhY2sxKSkgIT0gbnVsbCA/IHN0YWNrMS5lbWFpbCA6IHN0YWNrMSkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTAsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcbiAgXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmluZm8gOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLmxpY2Vuc2UgOiBzdGFjazEpLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEyLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG5cIjtcbn0sXCIyXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCIgIDxwPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmV4dGVybmFsRG9jcyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEuZGVzY3JpcHRpb24gOiBzdGFjazEpLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9wPlxcbiAgPGEgaHJlZj1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5leHRlcm5hbERvY3MgOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLnVybCA6IHN0YWNrMSkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIiB0YXJnZXQ9XFxcIl9ibGFua1xcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5leHRlcm5hbERvY3MgOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLnVybCA6IHN0YWNrMSkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9hPlxcblwiO1xufSxcIjRcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuIFwiPGRpdiBjbGFzcz1cXFwiaW5mb190b3NcXFwiPjxhIHRhcmdldD1cXFwiX2JsYW5rXFxcIiBocmVmPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS50ZXJtc09mU2VydmljZVVybCA6IHN0YWNrMSkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5UZXJtcyBvZiBzZXJ2aWNlPC9hPjwvZGl2PlwiO1xufSxcIjZcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuIFwiPGRpdj48ZGl2IGNsYXNzPSdpbmZvX25hbWUnIHN0eWxlPVxcXCJkaXNwbGF5OiBpbmxpbmVcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPkNyZWF0ZWQgYnkgPC9kaXY+IFwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCgoc3RhY2sxID0gKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEuY29udGFjdCA6IHN0YWNrMSkpICE9IG51bGwgPyBzdGFjazEubmFtZSA6IHN0YWNrMSkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9kaXY+XCI7XG59LFwiOFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiPGRpdiBjbGFzcz0naW5mb191cmwnIGRhdGEtc3ctdHJhbnNsYXRlPlNlZSBtb3JlIGF0IDxhIGhyZWY9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKChzdGFjazEgPSAoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS5jb250YWN0IDogc3RhY2sxKSkgIT0gbnVsbCA/IHN0YWNrMS51cmwgOiBzdGFjazEpLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9ICgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmluZm8gOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLmNvbnRhY3QgOiBzdGFjazEpKSAhPSBudWxsID8gc3RhY2sxLnVybCA6IHN0YWNrMSkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9hPjwvZGl2PlwiO1xufSxcIjEwXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCI8ZGl2IGNsYXNzPSdpbmZvX2VtYWlsJz48YSB0YXJnZXQ9XFxcIl9wYXJlbnRcXFwiIGhyZWY9XFxcIm1haWx0bzpcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEuY29udGFjdCA6IHN0YWNrMSkpICE9IG51bGwgPyBzdGFjazEuZW1haWwgOiBzdGFjazEpLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIj9zdWJqZWN0PVwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEudGl0bGUgOiBzdGFjazEpLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCIgZGF0YS1zdy10cmFuc2xhdGU+Q29udGFjdCB0aGUgZGV2ZWxvcGVyPC9hPjwvZGl2PlwiO1xufSxcIjEyXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCI8ZGl2IGNsYXNzPSdpbmZvX2xpY2Vuc2UnPjxhIHRhcmdldD1cXFwiX2JsYW5rXFxcIiBocmVmPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEubGljZW5zZSA6IHN0YWNrMSkpICE9IG51bGwgPyBzdGFjazEudXJsIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKChzdGFjazEgPSAoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS5saWNlbnNlIDogc3RhY2sxKSkgIT0gbnVsbCA/IHN0YWNrMS5uYW1lIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2E+PC9kaXY+XCI7XG59LFwiMTRcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuIFwiICAsIDxzcGFuIHN0eWxlPVxcXCJmb250LXZhcmlhbnQ6IHNtYWxsLWNhcHNcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPmFwaSB2ZXJzaW9uPC9zcGFuPjogXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEudmVyc2lvbiA6IHN0YWNrMSkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuICAgIFwiO1xufSxcIjE2XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCIgICAgPHNwYW4gc3R5bGU9XFxcImZsb2F0OnJpZ2h0XFxcIj48YSB0YXJnZXQ9XFxcIl9ibGFua1xcXCIgaHJlZj1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsaWRhdG9yVXJsIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIvZGVidWc/dXJsPVwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnVybCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIj48aW1nIGlkPVxcXCJ2YWxpZGF0b3JcXFwiIHNyYz1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsaWRhdG9yVXJsIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI/dXJsPVwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnVybCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIj48L2E+XFxuICAgIDwvc3Bhbj5cXG5cIjtcbn0sXCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fTtcblxuICByZXR1cm4gXCI8ZGl2IGNsYXNzPSdpbmZvJyBpZD0nYXBpX2luZm8nPlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9kaXY+XFxuPGRpdiBjbGFzcz0nY29udGFpbmVyJyBpZD0ncmVzb3VyY2VzX2NvbnRhaW5lcic+XFxuICA8ZGl2IGNsYXNzPSdhdXRob3JpemUtd3JhcHBlcic+PC9kaXY+XFxuXFxuICA8dWwgaWQ9J3Jlc291cmNlcyc+PC91bD5cXG5cXG4gIDxkaXYgY2xhc3M9XFxcImZvb3RlclxcXCI+XFxuICAgIDxoNCBzdHlsZT1cXFwiY29sb3I6ICM5OTlcXFwiPlsgPHNwYW4gc3R5bGU9XFxcImZvbnQtdmFyaWFudDogc21hbGwtY2Fwc1xcXCI+YmFzZSB1cmw8L3NwYW4+OiBcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5iYXNlUGF0aCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmluZm8gOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLnZlcnNpb24gOiBzdGFjazEpLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDE0LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJdXFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWxpZGF0b3JVcmwgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDE2LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgICAgPC9oND5cXG4gICAgPC9kaXY+XFxuPC9kaXY+XFxuXCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1snb2F1dGgyJ10gPSB0ZW1wbGF0ZSh7XCIxXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiBcIjxwPkF1dGhvcml6YXRpb24gVVJMOiBcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmF1dGhvcml6YXRpb25VcmwgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9wPlwiO1xufSxcIjNcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuIFwiPHA+VG9rZW4gVVJMOiBcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnRva2VuVXJsIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvcD5cIjtcbn0sXCI1XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgICAgICAgIDxwPlBsZWFzZSBpbnB1dCB1c2VybmFtZSBhbmQgcGFzc3dvcmQgZm9yIHBhc3N3b3JkIGZsb3cgYXV0aG9yaXphdGlvbjwvcD5cXG4gICAgICAgIDxmaWVsZHNldD5cXG4gICAgICAgICAgICA8ZGl2PjxsYWJlbD5Vc2VybmFtZTogPGlucHV0IGNsYXNzPVxcXCJvYXV0aC11c2VybmFtZVxcXCIgdHlwZT1cXFwidGV4dFxcXCIgbmFtZT1cXFwidXNlcm5hbWVcXFwiPjwvbGFiZWw+PC9kaXY+XFxuICAgICAgICAgICAgPGRpdj48bGFiZWw+UGFzc3dvcmQ6IDxpbnB1dCBjbGFzcz1cXFwib2F1dGgtcGFzc3dvcmRcXFwiIHR5cGU9XFxcInBhc3N3b3JkXFxcIiBuYW1lPVxcXCJwYXNzd29yZFxcXCI+PC9sYWJlbD48L2Rpdj5cXG4gICAgICAgIDwvZmllbGRzZXQ+XFxuXCI7XG59LFwiN1wiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gXCIgICAgICAgIDxwPlNldHVwIGNsaWVudCBhdXRoZW50aWNhdGlvbi5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5yZXF1aXJlQ2xpZW50QXV0aGVudGljYWl0b24gOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDgsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvcD5cXG4gICAgICAgIDxmaWVsZHNldD5cXG4gICAgICAgICAgICA8ZGl2PjxsYWJlbD5UeXBlOlxcbiAgICAgICAgICAgICAgICA8c2VsZWN0IGNsYXNzPVxcXCJvYXV0aC1jbGllbnQtYXV0aGVudGljYXRpb24tdHlwZVxcXCIgbmFtZT1cXFwiY2xpZW50LWF1dGhlbnRpY2F0aW9uLXR5cGVcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cXFwibm9uZVxcXCIgc2VsZWN0ZWQ+Tm9uZSBvciBvdGhlcjwvb3B0aW9uPlxcbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cXFwiYmFzaWNcXFwiPkJhc2ljIGF1dGg8L29wdGlvbj5cXG4gICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XFxcInJlcXVlc3QtYm9keVxcXCI+UmVxdWVzdCBib2R5PC9vcHRpb24+XFxuICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxcbiAgICAgICAgICAgIDwvbGFiZWw+PC9kaXY+XFxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwib2F1dGgtY2xpZW50LWF1dGhlbnRpY2F0aW9uXFxcIiBoaWRkZW4+XFxuICAgICAgICAgICAgICAgIDxkaXY+PGxhYmVsPkNsaWVudElkOiA8aW5wdXQgY2xhc3M9XFxcIm9hdXRoLWNsaWVudC1pZFxcXCIgdHlwZT1cXFwidGV4dFxcXCIgbmFtZT1cXFwiY2xpZW50LWlkXFxcIj48L2xhYmVsPjwvZGl2PlxcbiAgICAgICAgICAgICAgICA8ZGl2PjxsYWJlbD5TZWNyZXQ6IDxpbnB1dCBjbGFzcz1cXFwib2F1dGgtY2xpZW50LXNlY3JldFxcXCIgdHlwZT1cXFwidGV4dFxcXCIgbmFtZT1cXFwiY2xpZW50LXNlY3JldFxcXCI+PC9sYWJlbD48L2Rpdj5cXG4gICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgIDwvZmllbGRzZXQ+XFxuXCI7XG59LFwiOFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiKFJlcXVpcmVkKVwiO1xufSxcIjEwXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCIgICAgICAgICAgICA8bGk+XFxuICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cXFwib2F1dGgtc2NvcGVcXFwiIHR5cGU9XFxcImNoZWNrYm94XFxcIiBkYXRhLXNjb3BlPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zY29wZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIiBvYXV0aHR5cGU9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLk9BdXRoU2NoZW1lS2V5IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiLz5cXG4gICAgICAgICAgICAgICAgPGxhYmVsPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnNjb3BlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2xhYmVsPjxici8+XFxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVxcXCJhcGktc2NvcGUtZGVzY1xcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZGVzY3JpcHRpb24gOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuT0F1dGhTY2hlbWVLZXkgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDExLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgICAgICAgICAgICAgICAgPC9zcGFuPlxcbiAgICAgICAgICAgIDwvbGk+XFxuXCI7XG59LFwiMTFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuIFwiICAgICAgICAgICAgICAgICAgICAgICAgKFwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5PQXV0aFNjaGVtZUtleSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiKVxcblwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIjxkaXY+XFxuICAgIDxoMyBjbGFzcz1cXFwiYXV0aF9fdGl0bGVcXFwiPk9BdXRoMi4wPC9oMz5cXG4gICAgPHA+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmRlc2NyaXB0aW9uIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvcD5cXG4gICAgXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5hdXRob3JpemF0aW9uVXJsIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG4gICAgXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC50b2tlblVybCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMywgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuICAgIDxwPmZsb3c6IFwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmZsb3cgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvcD5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzUGFzc3dvcmRGbG93IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSg1LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmNsaWVudEF1dGhlbnRpY2F0aW9uIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSg3LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgICAgPHA+PHN0cm9uZz4gXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuYXBwTmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiIDwvc3Ryb25nPiBBUEkgcmVxdWlyZXMgdGhlIGZvbGxvd2luZyBzY29wZXMuIFNlbGVjdCB3aGljaCBvbmVzIHlvdSB3YW50IHRvIGdyYW50IHRvIFN3YWdnZXIgVUkuPC9wPlxcbiAgICA8cD5TY29wZXMgYXJlIHVzZWQgdG8gZ3JhbnQgYW4gYXBwbGljYXRpb24gZGlmZmVyZW50IGxldmVscyBvZiBhY2Nlc3MgdG8gZGF0YSBvbiBiZWhhbGYgb2YgdGhlIGVuZCB1c2VyLiBFYWNoIEFQSSBtYXkgZGVjbGFyZSBvbmUgb3IgbW9yZSBzY29wZXMuXFxuICAgICAgICA8YSBocmVmPVxcXCIjXFxcIj5MZWFybiBob3cgdG8gdXNlPC9hPlxcbiAgICA8L3A+XFxuICAgIDx1bCBjbGFzcz1cXFwiYXBpLXBvcHVwLXNjb3Blc1xcXCI+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVycy5lYWNoLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zY29wZXMgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVhY2hcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTAsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgICA8L3VsPlxcbjwvZGl2PlwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ29wZXJhdGlvbiddID0gdGVtcGxhdGUoe1wiMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiZGVwcmVjYXRlZFwiO1xufSxcIjNcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgICAgICAgICAgIDxoND48c3BhbiBkYXRhLXN3LXRyYW5zbGF0ZT5XYXJuaW5nOiBEZXByZWNhdGVkPC9zcGFuPjwvaDQ+XFxuXCI7XG59LFwiNVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gXCIgICAgICAgIDxoND48c3BhbiBkYXRhLXN3LXRyYW5zbGF0ZT5JbXBsZW1lbnRhdGlvbiBOb3Rlczwvc3Bhbj48L2g0PlxcbiAgICAgICAgPGRpdiBjbGFzcz1cXFwibWFya2Rvd25cXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZGVzY3JpcHRpb24gOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9kaXY+XFxuXCI7XG59LFwiN1wiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiICAgICAgICAgICAgPGRpdiBjbGFzcz0nYXV0aG9yaXplLXdyYXBwZXIgYXV0aG9yaXplLXdyYXBwZXJfb3BlcmF0aW9uJz48L2Rpdj5cXG5cIjtcbn0sXCI5XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fTtcblxuICByZXR1cm4gXCIgICAgICAgICAgPGRpdiBjbGFzcz1cXFwicmVzcG9uc2UtY2xhc3NcXFwiPlxcbiAgICAgICAgICAgIDxoND48c3BhbiBkYXRhLXN3LXRyYW5zbGF0ZT5SZXNwb25zZSBDbGFzczwvc3Bhbj4gKDxzcGFuIGRhdGEtc3ctdHJhbnNsYXRlPlN0YXR1czwvc3Bhbj4gXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc3VjY2Vzc0NvZGUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIik8L2g0PlxcbiAgICAgICAgICAgICAgXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zdWNjZXNzRGVzY3JpcHRpb24gOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEwLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG4gICAgICAgICAgICA8cD48c3BhbiBjbGFzcz1cXFwibW9kZWwtc2lnbmF0dXJlXFxcIiAvPjwvcD5cXG4gICAgICAgICAgICA8YnIvPlxcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcInJlc3BvbnNlLWNvbnRlbnQtdHlwZVxcXCIgLz5cXG4gICAgICAgICAgICA8L2Rpdj5cXG5cIjtcbn0sXCIxMFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gXCI8ZGl2IGNsYXNzPVxcXCJtYXJrZG93blxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zdWNjZXNzRGVzY3JpcHRpb24gOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9kaXY+XCI7XG59LFwiMTJcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuIFwiICAgICAgICAgIDxoNCBkYXRhLXN3LXRyYW5zbGF0ZT5IZWFkZXJzPC9oND5cXG4gICAgICAgICAgPHRhYmxlIGNsYXNzPVxcXCJoZWFkZXJzXFxcIj5cXG4gICAgICAgICAgICA8dGhlYWQ+XFxuICAgICAgICAgICAgICA8dHI+XFxuICAgICAgICAgICAgICAgIDx0aCBzdHlsZT1cXFwid2lkdGg6IDEwMHB4OyBtYXgtd2lkdGg6IDEwMHB4XFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5IZWFkZXI8L3RoPlxcbiAgICAgICAgICAgICAgICA8dGggc3R5bGU9XFxcIndpZHRoOiAzMTBweDsgbWF4LXdpZHRoOiAzMTBweFxcXCIgZGF0YS1zdy10cmFuc2xhdGU+RGVzY3JpcHRpb248L3RoPlxcbiAgICAgICAgICAgICAgICA8dGggc3R5bGU9XFxcIndpZHRoOiAyMDBweDsgbWF4LXdpZHRoOiAyMDBweFxcXCIgZGF0YS1zdy10cmFuc2xhdGU+VHlwZTwvdGg+XFxuICAgICAgICAgICAgICAgIDx0aCBzdHlsZT1cXFwid2lkdGg6IDMyMHB4OyBtYXgtd2lkdGg6IDMyMHB4XFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5PdGhlcjwvdGg+XFxuICAgICAgICAgICAgICA8L3RyPlxcbiAgICAgICAgICAgIDwvdGhlYWQ+XFxuICAgICAgICAgICAgPHRib2R5PlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnMuZWFjaC5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmhlYWRlcnMgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVhY2hcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTMsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgICAgICAgICAgIDwvdGJvZHk+XFxuICAgICAgICAgIDwvdGFibGU+XFxuXCI7XG59LFwiMTNcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGhlbHBlciwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiICAgICAgICAgICAgICA8dHI+XFxuICAgICAgICAgICAgICAgIDx0ZD5cIlxuICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5rZXkgfHwgKGRhdGEgJiYgZGF0YS5rZXkpKSAhPSBudWxsID8gaGVscGVyIDogYWxpYXMyKSwodHlwZW9mIGhlbHBlciA9PT0gXCJmdW5jdGlvblwiID8gaGVscGVyLmNhbGwoYWxpYXMxLHtcIm5hbWVcIjpcImtleVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSA6IGhlbHBlcikpKVxuICAgICsgXCI8L3RkPlxcbiAgICAgICAgICAgICAgICA8dGQ+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmRlc2NyaXB0aW9uIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGQ+XFxuICAgICAgICAgICAgICAgIDx0ZD5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC50eXBlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RkPlxcbiAgICAgICAgICAgICAgICA8dGQ+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAub3RoZXIgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGQ+XFxuICAgICAgICAgICAgICA8L3RyPlxcblwiO1xufSxcIjE1XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgICAgICAgICAgPGg0IGRhdGEtc3ctdHJhbnNsYXRlPlBhcmFtZXRlcnM8L2g0PlxcbiAgICAgICAgICA8dGFibGUgY2xhc3M9J2Z1bGx3aWR0aCBwYXJhbWV0ZXJzJz5cXG4gICAgICAgICAgPHRoZWFkPlxcbiAgICAgICAgICAgIDx0cj5cXG4gICAgICAgICAgICA8dGggc3R5bGU9XFxcIndpZHRoOiAxMDBweDsgbWF4LXdpZHRoOiAxMDBweFxcXCIgZGF0YS1zdy10cmFuc2xhdGU+UGFyYW1ldGVyPC90aD5cXG4gICAgICAgICAgICA8dGggc3R5bGU9XFxcIndpZHRoOiAzMTBweDsgbWF4LXdpZHRoOiAzMTBweFxcXCIgZGF0YS1zdy10cmFuc2xhdGU+VmFsdWU8L3RoPlxcbiAgICAgICAgICAgIDx0aCBzdHlsZT1cXFwid2lkdGg6IDIwMHB4OyBtYXgtd2lkdGg6IDIwMHB4XFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5EZXNjcmlwdGlvbjwvdGg+XFxuICAgICAgICAgICAgPHRoIHN0eWxlPVxcXCJ3aWR0aDogMTAwcHg7IG1heC13aWR0aDogMTAwcHhcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPlBhcmFtZXRlciBUeXBlPC90aD5cXG4gICAgICAgICAgICA8dGggc3R5bGU9XFxcIndpZHRoOiAyMjBweDsgbWF4LXdpZHRoOiAyMzBweFxcXCIgZGF0YS1zdy10cmFuc2xhdGU+RGF0YSBUeXBlPC90aD5cXG4gICAgICAgICAgICA8L3RyPlxcbiAgICAgICAgICA8L3RoZWFkPlxcbiAgICAgICAgICA8dGJvZHkgY2xhc3M9XFxcIm9wZXJhdGlvbi1wYXJhbXNcXFwiPlxcblxcbiAgICAgICAgICA8L3Rib2R5PlxcbiAgICAgICAgICA8L3RhYmxlPlxcblwiO1xufSxcIjE3XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgICAgICAgICAgPGRpdiBzdHlsZT0nbWFyZ2luOjA7cGFkZGluZzowO2Rpc3BsYXk6aW5saW5lJz48L2Rpdj5cXG4gICAgICAgICAgPGg0IGRhdGEtc3ctdHJhbnNsYXRlPlJlc3BvbnNlIE1lc3NhZ2VzPC9oND5cXG4gICAgICAgICAgPHRhYmxlIGNsYXNzPSdmdWxsd2lkdGggcmVzcG9uc2UtbWVzc2FnZXMnPlxcbiAgICAgICAgICAgIDx0aGVhZD5cXG4gICAgICAgICAgICA8dHI+XFxuICAgICAgICAgICAgICA8dGggZGF0YS1zdy10cmFuc2xhdGU+SFRUUCBTdGF0dXMgQ29kZTwvdGg+XFxuICAgICAgICAgICAgICA8dGggZGF0YS1zdy10cmFuc2xhdGU+UmVhc29uPC90aD5cXG4gICAgICAgICAgICAgIDx0aCBkYXRhLXN3LXRyYW5zbGF0ZT5SZXNwb25zZSBNb2RlbDwvdGg+XFxuICAgICAgICAgICAgICA8dGggZGF0YS1zdy10cmFuc2xhdGU+SGVhZGVyczwvdGg+XFxuICAgICAgICAgICAgPC90cj5cXG4gICAgICAgICAgICA8L3RoZWFkPlxcbiAgICAgICAgICAgIDx0Ym9keSBjbGFzcz1cXFwib3BlcmF0aW9uLXN0YXR1c1xcXCI+XFxuICAgICAgICAgICAgPC90Ym9keT5cXG4gICAgICAgICAgPC90YWJsZT5cXG5cIjtcbn0sXCIxOVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiXCI7XG59LFwiMjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgICAgICAgICA8ZGl2IGNsYXNzPSdzYW5kYm94X2hlYWRlcic+XFxuICAgICAgICAgICAgPGlucHV0IGNsYXNzPSdzdWJtaXQnIHR5cGU9J3N1Ym1pdCcgdmFsdWU9J1RyeSBpdCBvdXQhJyBkYXRhLXN3LXRyYW5zbGF0ZS8+XFxuICAgICAgICAgICAgPGEgaHJlZj0nIycgY2xhc3M9J3Jlc3BvbnNlX2hpZGVyJyBzdHlsZT0nZGlzcGxheTpub25lJyBkYXRhLXN3LXRyYW5zbGF0ZT5IaWRlIFJlc3BvbnNlPC9hPlxcbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPSdyZXNwb25zZV90aHJvYmJlcicgc3R5bGU9J2Rpc3BsYXk6bm9uZSc+PC9zcGFuPlxcbiAgICAgICAgICA8L2Rpdj5cXG5cIjtcbn0sXCIyM1wiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiICAgICAgICAgIDxoNCBkYXRhLXN3LXRyYW5zbGF0ZT5SZXF1ZXN0IEhlYWRlcnM8L2g0PlxcbiAgICAgICAgICA8ZGl2IGNsYXNzPSdibG9jayByZXF1ZXN0X2hlYWRlcnMnPjwvZGl2PlxcblwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nLCBhbGlhczM9Y29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb247XG5cbiAgcmV0dXJuIFwiICA8dWwgY2xhc3M9J29wZXJhdGlvbnMnID5cXG4gICAgPGxpIGNsYXNzPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5tZXRob2QgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiBvcGVyYXRpb24nIGlkPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5wYXJlbnRJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiX1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm5pY2tuYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInPlxcbiAgICAgIDxkaXYgY2xhc3M9J2hlYWRpbmcnPlxcbiAgICAgICAgPGgzPlxcbiAgICAgICAgICA8c3BhbiBjbGFzcz0naHR0cF9tZXRob2QnPlxcbiAgICAgICAgICA8YSBocmVmPScjIS9cIlxuICAgICsgYWxpYXMzKChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5lbmNvZGVkUGFyZW50SWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKVxuICAgICsgXCIvXCJcbiAgICArIGFsaWFzMygoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubmlja25hbWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKVxuICAgICsgXCInIGNsYXNzPVxcXCJ0b2dnbGVPcGVyYXRpb25cXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm1ldGhvZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9hPlxcbiAgICAgICAgICA8L3NwYW4+XFxuICAgICAgICAgIDxzcGFuIGNsYXNzPSdwYXRoJz5cXG4gICAgICAgICAgPGEgaHJlZj0nIyEvXCJcbiAgICArIGFsaWFzMygoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZW5jb2RlZFBhcmVudElkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSlcbiAgICArIFwiL1wiXG4gICAgKyBhbGlhczMoKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm5pY2tuYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSlcbiAgICArIFwiJyBjbGFzcz1cXFwidG9nZ2xlT3BlcmF0aW9uIFwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZGVwcmVjYXRlZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5wYXRoIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2E+XFxuICAgICAgICAgIDwvc3Bhbj5cXG4gICAgICAgIDwvaDM+XFxuICAgICAgICA8dWwgY2xhc3M9J29wdGlvbnMnPlxcbiAgICAgICAgICA8bGk+XFxuICAgICAgICAgIDxhIGhyZWY9JyMhL1wiXG4gICAgKyBhbGlhczMoKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmVuY29kZWRQYXJlbnRJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpXG4gICAgKyBcIi9cIlxuICAgICsgYWxpYXMzKChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uaWNrbmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpXG4gICAgKyBcIicgY2xhc3M9XFxcInRvZ2dsZU9wZXJhdGlvblxcXCI+PHNwYW4gY2xhc3M9XFxcIm1hcmtkb3duXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zdW1tYXJ5IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3NwYW4+PC9hPlxcbiAgICAgICAgICA8L2xpPlxcbiAgICAgICAgPC91bD5cXG4gICAgICA8L2Rpdj5cXG4gICAgICA8ZGl2IGNsYXNzPSdjb250ZW50JyBpZD0nXCJcbiAgICArIGFsaWFzMygoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZW5jb2RlZFBhcmVudElkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSlcbiAgICArIFwiX1wiXG4gICAgKyBhbGlhczMoKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm5pY2tuYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSlcbiAgICArIFwiX2NvbnRlbnQnIHN0eWxlPSdkaXNwbGF5Om5vbmUnPlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZGVwcmVjYXRlZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMywgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5kZXNjcmlwdGlvbiA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oNSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zZWN1cml0eSA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oNywgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC50eXBlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSg5LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmhlYWRlcnMgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEyLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG4gICAgICAgIDxmb3JtIGFjY2VwdC1jaGFyc2V0PSdVVEYtOCcgY2xhc3M9J3NhbmRib3gnPlxcbiAgICAgICAgICA8ZGl2IHN0eWxlPSdtYXJnaW46MDtwYWRkaW5nOjA7ZGlzcGxheTppbmxpbmUnPjwvZGl2PlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucGFyYW1ldGVycyA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTUsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucmVzcG9uc2VNZXNzYWdlcyA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTcsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaXNSZWFkT25seSA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTksIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5wcm9ncmFtKDIxLCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgICAgICAgIDwvZm9ybT5cXG4gICAgICAgIDxkaXYgY2xhc3M9J3Jlc3BvbnNlJyBzdHlsZT0nZGlzcGxheTpub25lJz5cXG4gICAgICAgICAgPGg0IGNsYXNzPSdjdXJsJz5DdXJsPC9oND5cXG4gICAgICAgICAgPGRpdiBjbGFzcz0nYmxvY2sgY3VybCc+PC9kaXY+XFxuICAgICAgICAgIDxoNCBkYXRhLXN3LXRyYW5zbGF0ZT5SZXF1ZXN0IFVSTDwvaDQ+XFxuICAgICAgICAgIDxkaXYgY2xhc3M9J2Jsb2NrIHJlcXVlc3RfdXJsJz48L2Rpdj5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnNob3dSZXF1ZXN0SGVhZGVycyA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMjMsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgICAgICAgICA8aDQgZGF0YS1zdy10cmFuc2xhdGU+UmVzcG9uc2UgQm9keTwvaDQ+XFxuICAgICAgICAgIDxkaXYgY2xhc3M9J2Jsb2NrIHJlc3BvbnNlX2JvZHknPjwvZGl2PlxcbiAgICAgICAgICA8aDQgZGF0YS1zdy10cmFuc2xhdGU+UmVzcG9uc2UgQ29kZTwvaDQ+XFxuICAgICAgICAgIDxkaXYgY2xhc3M9J2Jsb2NrIHJlc3BvbnNlX2NvZGUnPjwvZGl2PlxcbiAgICAgICAgICA8aDQgZGF0YS1zdy10cmFuc2xhdGU+UmVzcG9uc2UgSGVhZGVyczwvaDQ+XFxuICAgICAgICAgIDxkaXYgY2xhc3M9J2Jsb2NrIHJlc3BvbnNlX2hlYWRlcnMnPjwvZGl2PlxcbiAgICAgICAgPC9kaXY+XFxuICAgICAgPC9kaXY+XFxuICAgIDwvbGk+XFxuICA8L3VsPlxcblwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ3BhcmFtJ10gPSB0ZW1wbGF0ZSh7XCIxXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzRmlsZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMiwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oNCwgZGF0YSwgMCksXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIik7XG59LFwiMlwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiXHRcdFx0PGlucHV0IHR5cGU9XFxcImZpbGVcXFwiIG5hbWU9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm5hbWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIicgaWQ9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbHVlSWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIicvPlxcblx0XHRcdDxkaXYgY2xhc3M9XFxcInBhcmFtZXRlci1jb250ZW50LXR5cGVcXFwiIC8+XFxuXCI7XG59LFwiNFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMFtcImRlZmF1bHRcIl0gOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDUsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5wcm9ncmFtKDcsIGRhdGEsIDApLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpO1xufSxcIjVcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIlx0XHRcdFx0PGRpdiBjbGFzcz1cXFwiZWRpdG9yX2hvbGRlclxcXCI+PC9kaXY+XFxuXHRcdFx0XHQ8dGV4dGFyZWEgY2xhc3M9J2JvZHktdGV4dGFyZWEnIG5hbWU9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm5hbWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIicgaWQ9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbHVlSWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIic+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDBbXCJkZWZhdWx0XCJdIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RleHRhcmVhPlxcbiAgICAgICAgPGJyIC8+XFxuICAgICAgICA8ZGl2IGNsYXNzPVxcXCJwYXJhbWV0ZXItY29udGVudC10eXBlXFxcIiAvPlxcblwiO1xufSxcIjdcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIlx0XHRcdFx0PHRleHRhcmVhIGNsYXNzPSdib2R5LXRleHRhcmVhJyBuYW1lPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInIGlkPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWx1ZUlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInPjwvdGV4dGFyZWE+XFxuXHRcdFx0XHQ8ZGl2IGNsYXNzPVxcXCJlZGl0b3JfaG9sZGVyXFxcIj48L2Rpdj5cXG5cdFx0XHRcdDxiciAvPlxcblx0XHRcdFx0PGRpdiBjbGFzcz1cXFwicGFyYW1ldGVyLWNvbnRlbnQtdHlwZVxcXCIgLz5cXG5cIjtcbn0sXCI5XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzRmlsZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMiwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oMTAsIGRhdGEsIDApLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpO1xufSxcIjEwXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiAoKHN0YWNrMSA9IChoZWxwZXJzLnJlbmRlclRleHRQYXJhbSB8fCAoZGVwdGgwICYmIGRlcHRoMC5yZW5kZXJUZXh0UGFyYW0pIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LGRlcHRoMCx7XCJuYW1lXCI6XCJyZW5kZXJUZXh0UGFyYW1cIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpO1xufSxcIjExXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCJcIjtcbn0sXCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCI8dGQgY2xhc3M9J2NvZGUnPjxsYWJlbCBmb3I9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbHVlSWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIic+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9sYWJlbD48L3RkPlxcbjx0ZD5cXG5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzQm9keSA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oOSwgZGF0YSwgMCksXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuPC90ZD5cXG48dGQgY2xhc3M9XFxcIm1hcmtkb3duXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZGVzY3JpcHRpb24gOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZD5cXG48dGQ+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucGFyYW1UeXBlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RkPlxcbjx0ZD5cXG5cdDxzcGFuIGNsYXNzPVxcXCJtb2RlbC1zaWduYXR1cmVcXFwiPjwvc3Bhbj5cXG48L3RkPlxcblwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ3BhcmFtX2xpc3QnXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiByZXF1aXJlZFwiO1xufSxcIjNcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiBtdWx0aXBsZT1cXFwibXVsdGlwbGVcXFwiXCI7XG59LFwiNVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiIHJlcXVpcmVkIFwiO1xufSxcIjdcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuIFwiICAgICAgPG9wdGlvbiBcIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzLnVubGVzcy5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmhhc0RlZmF1bHQgOiBkZXB0aDApLHtcIm5hbWVcIjpcInVubGVzc1wiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSg4LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgdmFsdWU9Jyc+PC9vcHRpb24+XFxuXCI7XG59LFwiOFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiICBzZWxlY3RlZD1cXFwiXFxcIiBcIjtcbn0sXCIxMFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiXFxuICAgICAgPG9wdGlvbiBcIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzRGVmYXVsdCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgdmFsdWU9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWx1ZSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInPiBcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsdWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiIFwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaXNEZWZhdWx0IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxMywgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiIDwvb3B0aW9uPlxcblxcblwiO1xufSxcIjExXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgc2VsZWN0ZWQ9XFxcIlxcXCIgIFwiO1xufSxcIjEzXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgKGRlZmF1bHQpIFwiO1xufSxcIjE1XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCI8c3Ryb25nPlwiO1xufSxcIjE3XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCI8L3N0cm9uZz5cIjtcbn0sXCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBoZWxwZXIsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIjx0ZCBjbGFzcz0nY29kZVwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucmVxdWlyZWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIic+PGxhYmVsIGZvcj0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsdWVJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJz5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2xhYmVsPjwvdGQ+XFxuPHRkPlxcbiAgPHNlbGVjdCBcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5pc0FycmF5IHx8IChkZXB0aDAgJiYgZGVwdGgwLmlzQXJyYXkpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsZGVwdGgwLHtcIm5hbWVcIjpcImlzQXJyYXlcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMywgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiIGNsYXNzPVxcXCJwYXJhbWV0ZXIgXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5yZXF1aXJlZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oNSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIiBuYW1lPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiIGlkPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWx1ZUlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiPlxcblxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnMudW5sZXNzLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5yZXF1aXJlZCA6IGRlcHRoMCkse1wibmFtZVwiOlwidW5sZXNzXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDcsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnMuZWFjaC5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5hbGxvd2FibGVWYWx1ZXMgOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLmRlc2NyaXB0aXZlVmFsdWVzIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJlYWNoXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEwLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG4gIDwvc2VsZWN0PlxcbjwvdGQ+XFxuPHRkIGNsYXNzPVxcXCJtYXJrZG93blxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5yZXF1aXJlZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTUsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyAoKHN0YWNrMSA9ICgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMuZGVzY3JpcHRpb24gfHwgKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmRlc2NyaXB0aW9uIDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGFsaWFzMiksKHR5cGVvZiBoZWxwZXIgPT09IFwiZnVuY3Rpb25cIiA/IGhlbHBlci5jYWxsKGFsaWFzMSx7XCJuYW1lXCI6XCJkZXNjcmlwdGlvblwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSA6IGhlbHBlcikpKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5yZXF1aXJlZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTcsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGQ+XFxuPHRkPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnBhcmFtVHlwZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZD5cXG48dGQ+PHNwYW4gY2xhc3M9XFxcIm1vZGVsLXNpZ25hdHVyZVxcXCI+PC9zcGFuPjwvdGQ+XFxuXCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1sncGFyYW1fcmVhZG9ubHknXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIiAgICAgICAgPHRleHRhcmVhIGNsYXNzPSdib2R5LXRleHRhcmVhJyByZWFkb25seT0ncmVhZG9ubHknIG5hbWU9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIicgaWQ9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbHVlSWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIic+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwW1wiZGVmYXVsdFwiXSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RleHRhcmVhPlxcbiAgICAgICAgPGRpdiBjbGFzcz1cXFwicGFyYW1ldGVyLWNvbnRlbnQtdHlwZVxcXCIgLz5cXG5cIjtcbn0sXCIzXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwW1wiZGVmYXVsdFwiXSA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oNCwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oNiwgZGF0YSwgMCksXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIik7XG59LFwiNFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gXCIgICAgICAgICAgICBcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwW1wiZGVmYXVsdFwiXSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG5cIjtcbn0sXCI2XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgICAgICAgICAgICAoZW1wdHkpXFxuXCI7XG59LFwiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiPHRkIGNsYXNzPSdjb2RlJz48bGFiZWwgZm9yPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWx1ZUlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvbGFiZWw+PC90ZD5cXG48dGQ+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc0JvZHkgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5wcm9ncmFtKDMsIGRhdGEsIDApLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGQ+XFxuPHRkIGNsYXNzPVxcXCJtYXJrZG93blxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmRlc2NyaXB0aW9uIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGQ+XFxuPHRkPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnBhcmFtVHlwZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZD5cXG48dGQ+PHNwYW4gY2xhc3M9XFxcIm1vZGVsLXNpZ25hdHVyZVxcXCI+PC9zcGFuPjwvdGQ+XFxuXCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1sncGFyYW1fcmVhZG9ubHlfcmVxdWlyZWQnXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIiAgICAgICAgPHRleHRhcmVhIGNsYXNzPSdib2R5LXRleHRhcmVhJyByZWFkb25seT0ncmVhZG9ubHknIHBsYWNlaG9sZGVyPScocmVxdWlyZWQpJyBuYW1lPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInIGlkPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWx1ZUlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMFtcImRlZmF1bHRcIl0gOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZXh0YXJlYT5cXG5cIjtcbn0sXCIzXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwW1wiZGVmYXVsdFwiXSA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oNCwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oNiwgZGF0YSwgMCksXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIik7XG59LFwiNFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gXCIgICAgICAgICAgICBcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwW1wiZGVmYXVsdFwiXSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG5cIjtcbn0sXCI2XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgICAgICAgICAgICAoZW1wdHkpXFxuXCI7XG59LFwiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiPHRkIGNsYXNzPSdjb2RlIHJlcXVpcmVkJz48bGFiZWwgZm9yPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWx1ZUlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvbGFiZWw+PC90ZD5cXG48dGQ+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc0JvZHkgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5wcm9ncmFtKDMsIGRhdGEsIDApLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGQ+XFxuPHRkIGNsYXNzPVxcXCJtYXJrZG93blxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmRlc2NyaXB0aW9uIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGQ+XFxuPHRkPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnBhcmFtVHlwZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZD5cXG48dGQ+PHNwYW4gY2xhc3M9XFxcIm1vZGVsLXNpZ25hdHVyZVxcXCI+PC9zcGFuPjwvdGQ+XFxuXCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1sncGFyYW1fcmVxdWlyZWQnXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaXNGaWxlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgyLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSg0LCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKTtcbn0sXCIyXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCJcdFx0XHQ8aW5wdXQgdHlwZT1cXFwiZmlsZVxcXCIgbmFtZT0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJyBpZD0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsdWVJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJy8+XFxuXCI7XG59LFwiNFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMFtcImRlZmF1bHRcIl0gOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDUsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5wcm9ncmFtKDcsIGRhdGEsIDApLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpO1xufSxcIjVcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIlx0XHRcdFx0PGRpdiBjbGFzcz1cXFwiZWRpdG9yX2hvbGRlclxcXCI+PC9kaXY+XFxuXHRcdFx0XHQ8dGV4dGFyZWEgY2xhc3M9J2JvZHktdGV4dGFyZWEgcmVxdWlyZWQnIHBsYWNlaG9sZGVyPScocmVxdWlyZWQpJyBuYW1lPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInIGlkPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWx1ZUlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMFtcImRlZmF1bHRcIl0gOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZXh0YXJlYT5cXG4gICAgICAgIDxiciAvPlxcbiAgICAgICAgPGRpdiBjbGFzcz1cXFwicGFyYW1ldGVyLWNvbnRlbnQtdHlwZVxcXCIgLz5cXG5cIjtcbn0sXCI3XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCJcdFx0XHRcdDx0ZXh0YXJlYSBjbGFzcz0nYm9keS10ZXh0YXJlYSByZXF1aXJlZCcgcGxhY2Vob2xkZXI9JyhyZXF1aXJlZCknIG5hbWU9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIicgaWQ9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbHVlSWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIic+PC90ZXh0YXJlYT5cXG5cdFx0XHRcdDxkaXYgY2xhc3M9XFxcImVkaXRvcl9ob2xkZXJcXFwiPjwvZGl2Plxcblx0XHRcdFx0PGJyIC8+XFxuXHRcdFx0XHQ8ZGl2IGNsYXNzPVxcXCJwYXJhbWV0ZXItY29udGVudC10eXBlXFxcIiAvPlxcblwiO1xufSxcIjlcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaXNGaWxlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxMCwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oMTIsIGRhdGEsIDApLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpO1xufSxcIjEwXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCJcdFx0XHQ8aW5wdXQgY2xhc3M9J3BhcmFtZXRlciByZXF1aXJlZCcgdHlwZT0nZmlsZScgbmFtZT0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm5hbWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJyBpZD0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsdWVJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJy8+XFxuXCI7XG59LFwiMTJcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuICgoc3RhY2sxID0gKGhlbHBlcnMucmVuZGVyVGV4dFBhcmFtIHx8IChkZXB0aDAgJiYgZGVwdGgwLnJlbmRlclRleHRQYXJhbSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sZGVwdGgwLHtcIm5hbWVcIjpcInJlbmRlclRleHRQYXJhbVwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxMywgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIik7XG59LFwiMTNcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIlwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIjx0ZCBjbGFzcz0nY29kZSByZXF1aXJlZCc+PGxhYmVsIGZvcj0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsdWVJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJz5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2xhYmVsPjwvdGQ+XFxuPHRkPlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaXNCb2R5IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSg5LCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RkPlxcbjx0ZD5cXG5cdDxzdHJvbmc+PHNwYW4gY2xhc3M9XFxcIm1hcmtkb3duXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZGVzY3JpcHRpb24gOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9zcGFuPjwvc3Ryb25nPlxcbjwvdGQ+XFxuPHRkPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnBhcmFtVHlwZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZD5cXG48dGQ+PHNwYW4gY2xhc3M9XFxcIm1vZGVsLXNpZ25hdHVyZVxcXCI+PC9zcGFuPjwvdGQ+XFxuXCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1sncGFyYW1ldGVyX2NvbnRlbnRfdHlwZSddID0gdGVtcGxhdGUoe1wiMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gKChzdGFjazEgPSBoZWxwZXJzLmVhY2guY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5jb25zdW1lcyA6IGRlcHRoMCkse1wibmFtZVwiOlwiZWFjaFwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgyLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKTtcbn0sXCIyXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCIgIDxvcHRpb24gdmFsdWU9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLGRlcHRoMCx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsZGVwdGgwLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9vcHRpb24+XFxuXCI7XG59LFwiNFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiICA8b3B0aW9uIHZhbHVlPVxcXCJhcHBsaWNhdGlvbi9qc29uXFxcIj5hcHBsaWNhdGlvbi9qc29uPC9vcHRpb24+XFxuXCI7XG59LFwiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgaGVscGVyLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCI8bGFiZWwgZm9yPVxcXCJcIlxuICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5wYXJhbWV0ZXJDb250ZW50VHlwZUlkIHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5wYXJhbWV0ZXJDb250ZW50VHlwZUlkIDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGFsaWFzMiksKHR5cGVvZiBoZWxwZXIgPT09IFwiZnVuY3Rpb25cIiA/IGhlbHBlci5jYWxsKGFsaWFzMSx7XCJuYW1lXCI6XCJwYXJhbWV0ZXJDb250ZW50VHlwZUlkXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pIDogaGVscGVyKSkpXG4gICAgKyBcIlxcXCIgZGF0YS1zdy10cmFuc2xhdGU+UGFyYW1ldGVyIGNvbnRlbnQgdHlwZTo8L2xhYmVsPlxcbjxzZWxlY3QgbmFtZT1cXFwicGFyYW1ldGVyQ29udGVudFR5cGVcXFwiIGlkPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucGFyYW1ldGVyQ29udGVudFR5cGVJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiPlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuY29uc3VtZXMgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5wcm9ncmFtKDQsIGRhdGEsIDApLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvc2VsZWN0PlxcblwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ3BvcHVwJ10gPSB0ZW1wbGF0ZSh7XCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgaGVscGVyO1xuXG4gIHJldHVybiBcIjxkaXYgY2xhc3M9XFxcImFwaS1wb3B1cC1kaWFsb2ctd3JhcHBlclxcXCI+XFxuICAgIDxkaXYgY2xhc3M9XFxcImFwaS1wb3B1cC10aXRsZVxcXCI+XCJcbiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMudGl0bGUgfHwgKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnRpdGxlIDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGhlbHBlcnMuaGVscGVyTWlzc2luZyksKHR5cGVvZiBoZWxwZXIgPT09IFwiZnVuY3Rpb25cIiA/IGhlbHBlci5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30se1wibmFtZVwiOlwidGl0bGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkgOiBoZWxwZXIpKSlcbiAgICArIFwiPC9kaXY+XFxuICAgIDxkaXYgY2xhc3M9XFxcImFwaS1wb3B1cC1jb250ZW50XFxcIj48L2Rpdj5cXG4gICAgPHAgY2xhc3M9XFxcImVycm9yLW1zZ1xcXCI+PC9wPlxcbiAgICA8ZGl2IGNsYXNzPVxcXCJhcGktcG9wdXAtYWN0aW9uc1xcXCI+XFxuICAgICAgICA8YnV0dG9uIGNsYXNzPVxcXCJhcGktcG9wdXAtY2FuY2VsIGFwaS1idXR0b24gZ3JheVxcXCIgdHlwZT1cXFwiYnV0dG9uXFxcIj5DYW5jZWw8L2J1dHRvbj5cXG4gICAgPC9kaXY+XFxuPC9kaXY+XFxuPGRpdiBjbGFzcz1cXFwiYXBpLXBvcHVwLWRpYWxvZy1zaGFkb3dcXFwiPjwvZGl2PlwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ3Jlc291cmNlJ10gPSB0ZW1wbGF0ZSh7XCIxXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgOiBcIjtcbn0sXCIzXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiBcIiAgICA8bGk+XFxuICAgICAgPGEgaHJlZj0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC51cmwgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJyBkYXRhLXN3LXRyYW5zbGF0ZT5SYXc8L2E+XFxuICAgIDwvbGk+XFxuXCI7XG59LFwiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgaGVscGVyLCBvcHRpb25zLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZywgYnVmZmVyID0gXG4gIFwiPGRpdiBjbGFzcz0naGVhZGluZyc+XFxuICA8aDI+XFxuICAgIDxhIGhyZWY9JyMhL1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pZCA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInIGNsYXNzPVxcXCJ0b2dnbGVFbmRwb2ludExpc3RcXFwiIGRhdGEtaWQ9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pZCA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvYT4gXCI7XG4gIHN0YWNrMSA9ICgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMuc3VtbWFyeSB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc3VtbWFyeSA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBhbGlhczIpLChvcHRpb25zPXtcIm5hbWVcIjpcInN1bW1hcnlcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pLCh0eXBlb2YgaGVscGVyID09PSBcImZ1bmN0aW9uXCIgPyBoZWxwZXIuY2FsbChhbGlhczEsb3B0aW9ucykgOiBoZWxwZXIpKTtcbiAgaWYgKCFoZWxwZXJzLnN1bW1hcnkpIHsgc3RhY2sxID0gaGVscGVycy5ibG9ja0hlbHBlck1pc3NpbmcuY2FsbChkZXB0aDAsc3RhY2sxLG9wdGlvbnMpfVxuICBpZiAoc3RhY2sxICE9IG51bGwpIHsgYnVmZmVyICs9IHN0YWNrMTsgfVxuICByZXR1cm4gYnVmZmVyICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc3VtbWFyeSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG4gIDwvaDI+XFxuICA8dWwgY2xhc3M9J29wdGlvbnMnPlxcbiAgICA8bGk+XFxuICAgICAgPGEgaHJlZj0nIyEvXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIicgaWQ9J2VuZHBvaW50TGlzdFRvZ2dlcl9cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJyBjbGFzcz1cXFwidG9nZ2xlRW5kcG9pbnRMaXN0XFxcIiBkYXRhLWlkPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5TaG93L0hpZGU8L2E+XFxuICAgIDwvbGk+XFxuICAgIDxsaT5cXG4gICAgICA8YSBocmVmPScjJyBjbGFzcz1cXFwiY29sbGFwc2VSZXNvdXJjZVxcXCIgZGF0YS1pZD1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCIgZGF0YS1zdy10cmFuc2xhdGU+XFxuICAgICAgICBMaXN0IE9wZXJhdGlvbnNcXG4gICAgICA8L2E+XFxuICAgIDwvbGk+XFxuICAgIDxsaT5cXG4gICAgICA8YSBocmVmPScjJyBjbGFzcz1cXFwiZXhwYW5kUmVzb3VyY2VcXFwiIGRhdGEtaWQ9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pZCA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPlxcbiAgICAgICAgRXhwYW5kIE9wZXJhdGlvbnNcXG4gICAgICA8L2E+XFxuICAgIDwvbGk+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC51cmwgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDMsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgPC91bD5cXG48L2Rpdj5cXG48dWwgY2xhc3M9J2VuZHBvaW50cycgaWQ9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pZCA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJfZW5kcG9pbnRfbGlzdCcgc3R5bGU9J2Rpc3BsYXk6bm9uZSc+XFxuXFxuPC91bD5cXG5cIjtcbn0sXCJ1c2VEYXRhXCI6dHJ1ZX0pO1xudGVtcGxhdGVzWydyZXNwb25zZV9jb250ZW50X3R5cGUnXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuICgoc3RhY2sxID0gaGVscGVycy5lYWNoLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucHJvZHVjZXMgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVhY2hcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMiwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIik7XG59LFwiMlwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiICA8b3B0aW9uIHZhbHVlPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSxkZXB0aDAse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLGRlcHRoMCx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvb3B0aW9uPlxcblwiO1xufSxcIjRcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgPG9wdGlvbiB2YWx1ZT1cXFwiYXBwbGljYXRpb24vanNvblxcXCI+YXBwbGljYXRpb24vanNvbjwvb3B0aW9uPlxcblwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGhlbHBlciwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3NpbmcsIGFsaWFzMz1cImZ1bmN0aW9uXCIsIGFsaWFzND1jb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbjtcblxuICByZXR1cm4gXCI8bGFiZWwgZGF0YS1zdy10cmFuc2xhdGUgZm9yPVxcXCJcIlxuICAgICsgYWxpYXM0KCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMucmVzcG9uc2VDb250ZW50VHlwZUlkIHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5yZXNwb25zZUNvbnRlbnRUeXBlSWQgOiBkZXB0aDApKSAhPSBudWxsID8gaGVscGVyIDogYWxpYXMyKSwodHlwZW9mIGhlbHBlciA9PT0gYWxpYXMzID8gaGVscGVyLmNhbGwoYWxpYXMxLHtcIm5hbWVcIjpcInJlc3BvbnNlQ29udGVudFR5cGVJZFwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSA6IGhlbHBlcikpKVxuICAgICsgXCJcXFwiPlJlc3BvbnNlIENvbnRlbnQgVHlwZTwvbGFiZWw+XFxuPHNlbGVjdCBuYW1lPVxcXCJyZXNwb25zZUNvbnRlbnRUeXBlXFxcIiBpZD1cXFwiXCJcbiAgICArIGFsaWFzNCgoKGhlbHBlciA9IChoZWxwZXIgPSBoZWxwZXJzLnJlc3BvbnNlQ29udGVudFR5cGVJZCB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucmVzcG9uc2VDb250ZW50VHlwZUlkIDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGFsaWFzMiksKHR5cGVvZiBoZWxwZXIgPT09IGFsaWFzMyA/IGhlbHBlci5jYWxsKGFsaWFzMSx7XCJuYW1lXCI6XCJyZXNwb25zZUNvbnRlbnRUeXBlSWRcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkgOiBoZWxwZXIpKSlcbiAgICArIFwiXFxcIj5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnByb2R1Y2VzIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSg0LCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3NlbGVjdD5cXG5cIjtcbn0sXCJ1c2VEYXRhXCI6dHJ1ZX0pO1xudGVtcGxhdGVzWydzaWduYXR1cmUnXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9O1xuXG4gIHJldHVybiBcIlxcbjxkaXY+XFxuPHVsIGNsYXNzPVxcXCJzaWduYXR1cmUtbmF2XFxcIj5cXG4gIDxsaT48YSBjbGFzcz1cXFwiZGVzY3JpcHRpb24tbGlua1xcXCIgaHJlZj1cXFwiI1xcXCIgZGF0YS1zdy10cmFuc2xhdGU+TW9kZWw8L2E+PC9saT5cXG4gIDxsaT48YSBjbGFzcz1cXFwic25pcHBldC1saW5rXFxcIiBocmVmPVxcXCIjXFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5FeGFtcGxlIFZhbHVlPC9hPjwvbGk+XFxuPC91bD5cXG48ZGl2PlxcblxcbjxkaXYgY2xhc3M9XFxcInNpZ25hdHVyZS1jb250YWluZXJcXFwiPlxcbiAgPGRpdiBjbGFzcz1cXFwiZGVzY3JpcHRpb25cXFwiPlxcbiAgICAgIFwiXG4gICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc2lnbmF0dXJlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSlcbiAgICArIFwiXFxuICA8L2Rpdj5cXG5cXG4gIDxkaXYgY2xhc3M9XFxcInNuaXBwZXRcXFwiPlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc2FtcGxlSlNPTiA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMiwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zYW1wbGVYTUwgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDUsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgPC9kaXY+XFxuPC9kaXY+XFxuXCI7XG59LFwiMlwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge307XG5cbiAgcmV0dXJuIFwiICAgICAgPGRpdiBjbGFzcz1cXFwic25pcHBldF9qc29uXFxcIj5cXG4gICAgICAgIDxwcmU+PGNvZGU+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc2FtcGxlSlNPTiA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9jb2RlPjwvcHJlPlxcbiAgICAgICAgXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc1BhcmFtIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgzLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG4gICAgICA8L2Rpdj5cXG5cIjtcbn0sXCIzXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCI8c21hbGwgY2xhc3M9XFxcIm5vdGljZVxcXCIgZGF0YS1zdy10cmFuc2xhdGU+PC9zbWFsbD5cIjtcbn0sXCI1XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fTtcblxuICByZXR1cm4gXCIgICAgPGRpdiBjbGFzcz1cXFwic25pcHBldF94bWxcXFwiPlxcbiAgICAgIDxwcmU+PGNvZGU+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc2FtcGxlWE1MIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2NvZGU+PC9wcmU+XFxuICAgICAgXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc1BhcmFtIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgzLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG4gICAgPC9kaXY+XFxuXCI7XG59LFwiN1wiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gXCIgICAgXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnNpZ25hdHVyZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuXCI7XG59LFwiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gKChzdGFjazEgPSAoaGVscGVycy5pZkNvbmQgfHwgKGRlcHRoMCAmJiBkZXB0aDAuaWZDb25kKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc2FtcGxlSlNPTiA6IGRlcHRoMCksXCJ8fFwiLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zYW1wbGVYTUwgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmQ29uZFwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSg3LCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKTtcbn0sXCJ1c2VEYXRhXCI6dHJ1ZX0pO1xudGVtcGxhdGVzWydzdGF0dXNfY29kZSddID0gdGVtcGxhdGUoe1wiMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgaGVscGVyLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCIgICAgICA8dHI+XFxuICAgICAgICA8dGQ+XCJcbiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMua2V5IHx8IChkYXRhICYmIGRhdGEua2V5KSkgIT0gbnVsbCA/IGhlbHBlciA6IGFsaWFzMiksKHR5cGVvZiBoZWxwZXIgPT09IFwiZnVuY3Rpb25cIiA/IGhlbHBlci5jYWxsKGFsaWFzMSx7XCJuYW1lXCI6XCJrZXlcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkgOiBoZWxwZXIpKSlcbiAgICArIFwiPC90ZD5cXG4gICAgICAgIDx0ZD5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZGVzY3JpcHRpb24gOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZD5cXG4gICAgICAgIDx0ZD5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC50eXBlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RkPlxcbiAgICAgIDwvdHI+XFxuXCI7XG59LFwiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiPHRkIHdpZHRoPScxNSUnIGNsYXNzPSdjb2RlJz5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5jb2RlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RkPlxcbjx0ZCBjbGFzcz1cXFwibWFya2Rvd25cXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm1lc3NhZ2UgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGQ+XFxuPHRkIHdpZHRoPSc1MCUnPjxzcGFuIGNsYXNzPVxcXCJtb2RlbC1zaWduYXR1cmVcXFwiIC8+PC90ZD5cXG48dGQgY2xhc3M9XFxcImhlYWRlcnNcXFwiPlxcbiAgPHRhYmxlPlxcbiAgICA8dGJvZHk+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVycy5lYWNoLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5oZWFkZXJzIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlYWNoXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgICA8L3Rib2R5PlxcbiAgPC90YWJsZT5cXG48L3RkPlwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG59KSgpO30gXG4gLyoganNoaW50IGlnbm9yZTplbmQgKi8iLCIndXNlIHN0cmljdCc7XG5cblxuJChmdW5jdGlvbigpIHtcblxuXHQvLyBIZWxwZXIgZnVuY3Rpb24gZm9yIHZlcnRpY2FsbHkgYWxpZ25pbmcgRE9NIGVsZW1lbnRzXG5cdC8vIGh0dHA6Ly93d3cuc2VvZGVudmVyLmNvbS9zaW1wbGUtdmVydGljYWwtYWxpZ24tcGx1Z2luLWZvci1qcXVlcnkvXG5cdCQuZm4udkFsaWduID0gZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpe1xuXHRcdFx0dmFyIGFoID0gJCh0aGlzKS5oZWlnaHQoKTtcblx0XHRcdHZhciBwaCA9ICQodGhpcykucGFyZW50KCkuaGVpZ2h0KCk7XG5cdFx0XHR2YXIgbWggPSAocGggLSBhaCkgLyAyO1xuXHRcdFx0JCh0aGlzKS5jc3MoJ21hcmdpbi10b3AnLCBtaCk7XG5cdFx0fSk7XG5cdH07XG5cblx0JC5mbi5zdHJldGNoRm9ybXRhc3RpY0lucHV0V2lkdGhUb1BhcmVudCA9IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKXtcblx0XHRcdHZhciBwX3dpZHRoID0gJCh0aGlzKS5jbG9zZXN0KFwiZm9ybVwiKS5pbm5lcldpZHRoKCk7XG5cdFx0XHR2YXIgcF9wYWRkaW5nID0gcGFyc2VJbnQoJCh0aGlzKS5jbG9zZXN0KFwiZm9ybVwiKS5jc3MoJ3BhZGRpbmctbGVmdCcpICwxMCkgKyBwYXJzZUludCgkKHRoaXMpLmNsb3Nlc3QoJ2Zvcm0nKS5jc3MoJ3BhZGRpbmctcmlnaHQnKSwgMTApO1xuXHRcdFx0dmFyIHRoaXNfcGFkZGluZyA9IHBhcnNlSW50KCQodGhpcykuY3NzKCdwYWRkaW5nLWxlZnQnKSwgMTApICsgcGFyc2VJbnQoJCh0aGlzKS5jc3MoJ3BhZGRpbmctcmlnaHQnKSwgMTApO1xuXHRcdFx0JCh0aGlzKS5jc3MoJ3dpZHRoJywgcF93aWR0aCAtIHBfcGFkZGluZyAtIHRoaXNfcGFkZGluZyk7XG5cdFx0fSk7XG5cdH07XG5cblx0JCgnZm9ybS5mb3JtdGFzdGljIGxpLnN0cmluZyBpbnB1dCwgZm9ybS5mb3JtdGFzdGljIHRleHRhcmVhJykuc3RyZXRjaEZvcm10YXN0aWNJbnB1dFdpZHRoVG9QYXJlbnQoKTtcblxuXHQvLyBWZXJ0aWNhbGx5IGNlbnRlciB0aGVzZSBwYXJhZ3JhcGhzXG5cdC8vIFBhcmVudCBtYXkgbmVlZCBhIG1pbi1oZWlnaHQgZm9yIHRoaXMgdG8gd29yay4uXG5cdCQoJ3VsLmRvd25wbGF5ZWQgbGkgZGl2LmNvbnRlbnQgcCcpLnZBbGlnbigpO1xuXG5cdC8vIFdoZW4gYSBzYW5kYm94IGZvcm0gaXMgc3VibWl0dGVkLi5cblx0JChcImZvcm0uc2FuZGJveFwiKS5zdWJtaXQoZnVuY3Rpb24oKXtcblxuXHRcdHZhciBlcnJvcl9mcmVlID0gdHJ1ZTtcblxuXHRcdC8vIEN5Y2xlIHRocm91Z2ggdGhlIGZvcm1zIHJlcXVpcmVkIGlucHV0c1xuIFx0XHQkKHRoaXMpLmZpbmQoXCJpbnB1dC5yZXF1aXJlZFwiKS5lYWNoKGZ1bmN0aW9uKCkge1xuXG5cdFx0XHQvLyBSZW1vdmUgYW55IGV4aXN0aW5nIGVycm9yIHN0eWxlcyBmcm9tIHRoZSBpbnB1dFxuXHRcdFx0JCh0aGlzKS5yZW1vdmVDbGFzcygnZXJyb3InKTtcblxuXHRcdFx0Ly8gVGFjayB0aGUgZXJyb3Igc3R5bGUgb24gaWYgdGhlIGlucHV0IGlzIGVtcHR5Li5cblx0XHRcdGlmICgkKHRoaXMpLnZhbCgpID09PSAnJykge1xuXHRcdFx0XHQkKHRoaXMpLmFkZENsYXNzKCdlcnJvcicpO1xuXHRcdFx0XHQkKHRoaXMpLndpZ2dsZSgpO1xuXHRcdFx0XHRlcnJvcl9mcmVlID0gZmFsc2U7XG5cdFx0XHR9XG5cblx0XHR9KTtcblxuXHRcdHJldHVybiBlcnJvcl9mcmVlO1xuXHR9KTtcblxufSk7XG5cbmZ1bmN0aW9uIGNsaXBweUNvcGllZENhbGxiYWNrKCkge1xuICAkKCcjYXBpX2tleV9jb3BpZWQnKS5mYWRlSW4oKS5kZWxheSgxMDAwKS5mYWRlT3V0KCk7XG5cbiAgLy8gdmFyIGIgPSAkKFwiI2NsaXBweV90b29sdGlwX1wiICsgYSk7XG4gIC8vIGIubGVuZ3RoICE9IDAgJiYgKGIuYXR0cihcInRpdGxlXCIsIFwiY29waWVkIVwiKS50cmlnZ2VyKFwidGlwc3kucmVsb2FkXCIpLCBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAvLyAgIGIuYXR0cihcInRpdGxlXCIsIFwiY29weSB0byBjbGlwYm9hcmRcIilcbiAgLy8gfSxcbiAgLy8gNTAwKSlcbn1cblxuLy8gTG9nZ2luZyBmdW5jdGlvbiB0aGF0IGFjY291bnRzIGZvciBicm93c2VycyB0aGF0IGRvbid0IGhhdmUgd2luZG93LmNvbnNvbGVcbmZ1bmN0aW9uIGxvZygpe1xuICBsb2cuaGlzdG9yeSA9IGxvZy5oaXN0b3J5IHx8IFtdO1xuICBsb2cuaGlzdG9yeS5wdXNoKGFyZ3VtZW50cyk7XG4gIGlmKHRoaXMuY29uc29sZSl7XG4gICAgY29uc29sZS5sb2coIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cylbMF0gKTtcbiAgfVxufVxuXG4vLyBIYW5kbGUgYnJvd3NlcnMgdGhhdCBkbyBjb25zb2xlIGluY29ycmVjdGx5IChJRTkgYW5kIGJlbG93LCBzZWUgaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvNTUzOTM3OC83OTEzKVxuaWYgKEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kICYmIGNvbnNvbGUgJiYgdHlwZW9mIGNvbnNvbGUubG9nID09PSBcIm9iamVjdFwiKSB7XG4gICAgW1xuICAgICAgXCJsb2dcIixcImluZm9cIixcIndhcm5cIixcImVycm9yXCIsXCJhc3NlcnRcIixcImRpclwiLFwiY2xlYXJcIixcInByb2ZpbGVcIixcInByb2ZpbGVFbmRcIlxuICAgIF0uZm9yRWFjaChmdW5jdGlvbiAobWV0aG9kKSB7XG4gICAgICAgIGNvbnNvbGVbbWV0aG9kXSA9IHRoaXMuYmluZChjb25zb2xlW21ldGhvZF0sIGNvbnNvbGUpO1xuICAgIH0sIEZ1bmN0aW9uLnByb3RvdHlwZS5jYWxsKTtcbn1cblxud2luZG93LkRvY3MgPSB7XG5cblx0c2hlYmFuZzogZnVuY3Rpb24oKSB7XG5cblx0XHQvLyBJZiBzaGViYW5nIGhhcyBhbiBvcGVyYXRpb24gbmlja25hbWUgaW4gaXQuLlxuXHRcdC8vIGUuZy4gL2RvY3MvIyEvd29yZHMvZ2V0X3NlYXJjaFxuXHRcdHZhciBmcmFnbWVudHMgPSAkLnBhcmFtLmZyYWdtZW50KCkuc3BsaXQoJy8nKTtcblx0XHRmcmFnbWVudHMuc2hpZnQoKTsgLy8gZ2V0IHJpZCBvZiB0aGUgYmFuZ1xuXG5cdFx0c3dpdGNoIChmcmFnbWVudHMubGVuZ3RoKSB7XG5cdFx0XHRjYXNlIDE6XG4gICAgICAgIGlmIChmcmFnbWVudHNbMF0ubGVuZ3RoID4gMCkgeyAvLyBwcmV2ZW50IG1hdGNoaW5nIFwiIy9cIlxuICAgICAgICAgIC8vIEV4cGFuZCBhbGwgb3BlcmF0aW9ucyBmb3IgdGhlIHJlc291cmNlIGFuZCBzY3JvbGwgdG8gaXRcbiAgICAgICAgICB2YXIgZG9tX2lkID0gJ3Jlc291cmNlXycgKyBmcmFnbWVudHNbMF07XG5cbiAgICAgICAgICBEb2NzLmV4cGFuZEVuZHBvaW50TGlzdEZvclJlc291cmNlKGZyYWdtZW50c1swXSk7XG4gICAgICAgICAgJChcIiNcIitkb21faWQpLnNsaWRldG8oe2hpZ2hsaWdodDogZmFsc2V9KTtcbiAgICAgICAgfVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgMjpcblx0XHRcdFx0Ly8gUmVmZXIgdG8gdGhlIGVuZHBvaW50IERPTSBlbGVtZW50LCBlLmcuICN3b3Jkc19nZXRfc2VhcmNoXG5cbiAgICAgICAgLy8gRXhwYW5kIFJlc291cmNlXG4gICAgICAgIERvY3MuZXhwYW5kRW5kcG9pbnRMaXN0Rm9yUmVzb3VyY2UoZnJhZ21lbnRzWzBdKTtcbiAgICAgICAgJChcIiNcIitkb21faWQpLnNsaWRldG8oe2hpZ2hsaWdodDogZmFsc2V9KTtcblxuICAgICAgICAgICAgLy8gRXhwYW5kIG9wZXJhdGlvblxuICAgICAgICAgICAgdmFyIGxpX2RvbV9pZCA9IGZyYWdtZW50cy5qb2luKCdfJyk7XG4gICAgICAgICAgICB2YXIgbGlfY29udGVudF9kb21faWQgPSBsaV9kb21faWQgKyBcIl9jb250ZW50XCI7XG5cblxuICAgICAgICAgICAgRG9jcy5leHBhbmRPcGVyYXRpb24oJCgnIycrbGlfY29udGVudF9kb21faWQpKTtcbiAgICAgICAgICAgICQoJyMnK2xpX2RvbV9pZCkuc2xpZGV0byh7aGlnaGxpZ2h0OiBmYWxzZX0pO1xuICAgICAgICAgICAgYnJlYWs7XG5cdFx0fVxuXHR9LFxuXG5cdHRvZ2dsZUVuZHBvaW50TGlzdEZvclJlc291cmNlOiBmdW5jdGlvbihyZXNvdXJjZSkge1xuXHRcdHZhciBlbGVtID0gJCgnbGkjcmVzb3VyY2VfJyArIERvY3MuZXNjYXBlUmVzb3VyY2VOYW1lKHJlc291cmNlKSArICcgdWwuZW5kcG9pbnRzJyk7XG5cdFx0aWYgKGVsZW0uaXMoJzp2aXNpYmxlJykpIHtcblx0XHRcdCQuYmJxLnB1c2hTdGF0ZSgnIy8nLCAyKTtcblx0XHRcdERvY3MuY29sbGFwc2VFbmRwb2ludExpc3RGb3JSZXNvdXJjZShyZXNvdXJjZSk7XG5cdFx0fSBlbHNlIHtcbiAgICAgICAgICAgICQuYmJxLnB1c2hTdGF0ZSgnIy8nICsgcmVzb3VyY2UsIDIpO1xuXHRcdFx0RG9jcy5leHBhbmRFbmRwb2ludExpc3RGb3JSZXNvdXJjZShyZXNvdXJjZSk7XG5cdFx0fVxuXHR9LFxuXG5cdC8vIEV4cGFuZCByZXNvdXJjZVxuXHRleHBhbmRFbmRwb2ludExpc3RGb3JSZXNvdXJjZTogZnVuY3Rpb24ocmVzb3VyY2UpIHtcblx0XHR2YXIgcmVzb3VyY2UgPSBEb2NzLmVzY2FwZVJlc291cmNlTmFtZShyZXNvdXJjZSk7XG5cdFx0aWYgKHJlc291cmNlID09ICcnKSB7XG5cdFx0XHQkKCcucmVzb3VyY2UgdWwuZW5kcG9pbnRzJykuc2xpZGVEb3duKCk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0JCgnbGkjcmVzb3VyY2VfJyArIHJlc291cmNlKS5hZGRDbGFzcygnYWN0aXZlJyk7XG5cblx0XHR2YXIgZWxlbSA9ICQoJ2xpI3Jlc291cmNlXycgKyByZXNvdXJjZSArICcgdWwuZW5kcG9pbnRzJyk7XG5cdFx0ZWxlbS5zbGlkZURvd24oKTtcblx0fSxcblxuXHQvLyBDb2xsYXBzZSByZXNvdXJjZSBhbmQgbWFyayBhcyBleHBsaWNpdGx5IGNsb3NlZFxuXHRjb2xsYXBzZUVuZHBvaW50TGlzdEZvclJlc291cmNlOiBmdW5jdGlvbihyZXNvdXJjZSkge1xuXHRcdHZhciByZXNvdXJjZSA9IERvY3MuZXNjYXBlUmVzb3VyY2VOYW1lKHJlc291cmNlKTtcblx0XHRpZiAocmVzb3VyY2UgPT0gJycpIHtcblx0XHRcdCQoJy5yZXNvdXJjZSB1bC5lbmRwb2ludHMnKS5zbGlkZVVwKCk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0JCgnbGkjcmVzb3VyY2VfJyArIHJlc291cmNlKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG5cblx0XHR2YXIgZWxlbSA9ICQoJ2xpI3Jlc291cmNlXycgKyByZXNvdXJjZSArICcgdWwuZW5kcG9pbnRzJyk7XG5cdFx0ZWxlbS5zbGlkZVVwKCk7XG5cdH0sXG5cblx0ZXhwYW5kT3BlcmF0aW9uc0ZvclJlc291cmNlOiBmdW5jdGlvbihyZXNvdXJjZSkge1xuXHRcdC8vIE1ha2Ugc3VyZSB0aGUgcmVzb3VyY2UgY29udGFpbmVyIGlzIG9wZW4uLlxuXHRcdERvY3MuZXhwYW5kRW5kcG9pbnRMaXN0Rm9yUmVzb3VyY2UocmVzb3VyY2UpO1xuXG5cdFx0aWYgKHJlc291cmNlID09ICcnKSB7XG5cdFx0XHQkKCcucmVzb3VyY2UgdWwuZW5kcG9pbnRzIGxpLm9wZXJhdGlvbiBkaXYuY29udGVudCcpLnNsaWRlRG93bigpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdCQoJ2xpI3Jlc291cmNlXycgKyBEb2NzLmVzY2FwZVJlc291cmNlTmFtZShyZXNvdXJjZSkgKyAnIGxpLm9wZXJhdGlvbiBkaXYuY29udGVudCcpLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHREb2NzLmV4cGFuZE9wZXJhdGlvbigkKHRoaXMpKTtcblx0XHR9KTtcblx0fSxcblxuXHRjb2xsYXBzZU9wZXJhdGlvbnNGb3JSZXNvdXJjZTogZnVuY3Rpb24ocmVzb3VyY2UpIHtcblx0XHQvLyBNYWtlIHN1cmUgdGhlIHJlc291cmNlIGNvbnRhaW5lciBpcyBvcGVuLi5cblx0XHREb2NzLmV4cGFuZEVuZHBvaW50TGlzdEZvclJlc291cmNlKHJlc291cmNlKTtcblxuXHRcdGlmIChyZXNvdXJjZSA9PSAnJykge1xuXHRcdFx0JCgnLnJlc291cmNlIHVsLmVuZHBvaW50cyBsaS5vcGVyYXRpb24gZGl2LmNvbnRlbnQnKS5zbGlkZVVwKCk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0JCgnbGkjcmVzb3VyY2VfJyArIERvY3MuZXNjYXBlUmVzb3VyY2VOYW1lKHJlc291cmNlKSArICcgbGkub3BlcmF0aW9uIGRpdi5jb250ZW50JykuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdERvY3MuY29sbGFwc2VPcGVyYXRpb24oJCh0aGlzKSk7XG5cdFx0fSk7XG5cdH0sXG5cblx0ZXNjYXBlUmVzb3VyY2VOYW1lOiBmdW5jdGlvbihyZXNvdXJjZSkge1xuXHRcdHJldHVybiByZXNvdXJjZS5yZXBsYWNlKC9bIVwiIyQlJicoKSorLC5cXC86Ozw9Pj9AXFxbXFxcXFxcXVxcXmB7fH1+XS9nLCBcIlxcXFwkJlwiKTtcblx0fSxcblxuXHRleHBhbmRPcGVyYXRpb246IGZ1bmN0aW9uKGVsZW0pIHtcblx0XHRlbGVtLnNsaWRlRG93bigpO1xuXHR9LFxuXG5cdGNvbGxhcHNlT3BlcmF0aW9uOiBmdW5jdGlvbihlbGVtKSB7XG5cdFx0ZWxlbS5zbGlkZVVwKCk7XG5cdH1cbn07XG4iLCIvKiFcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9lcy1zaGltcy9lczUtc2hpbVxuICogQGxpY2Vuc2UgZXM1LXNoaW0gQ29weXJpZ2h0IDIwMDktMjAxNSBieSBjb250cmlidXRvcnMsIE1JVCBMaWNlbnNlXG4gKiBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2VzLXNoaW1zL2VzNS1zaGltL2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAqL1xuXG4vLyB2aW06IHRzPTQgc3RzPTQgc3c9NCBleHBhbmR0YWJcblxuLy8gQWRkIHNlbWljb2xvbiB0byBwcmV2ZW50IElJRkUgZnJvbSBiZWluZyBwYXNzZWQgYXMgYXJndW1lbnQgdG8gY29uY2F0ZW5hdGVkIGNvZGUuXG47XG5cbi8vIFVNRCAoVW5pdmVyc2FsIE1vZHVsZSBEZWZpbml0aW9uKVxuLy8gc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS91bWRqcy91bWQvYmxvYi9tYXN0ZXIvdGVtcGxhdGVzL3JldHVybkV4cG9ydHMuanNcbihmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSkge1xuICAgICd1c2Ugc3RyaWN0JztcblxuICAgIC8qIGdsb2JhbCBkZWZpbmUsIGV4cG9ydHMsIG1vZHVsZSAqL1xuICAgIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpIHtcbiAgICAgICAgLy8gQU1ELiBSZWdpc3RlciBhcyBhbiBhbm9ueW1vdXMgbW9kdWxlLlxuICAgICAgICBkZWZpbmUoZmFjdG9yeSk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgLy8gTm9kZS4gRG9lcyBub3Qgd29yayB3aXRoIHN0cmljdCBDb21tb25KUywgYnV0XG4gICAgICAgIC8vIG9ubHkgQ29tbW9uSlMtbGlrZSBlbnZpcm9tZW50cyB0aGF0IHN1cHBvcnQgbW9kdWxlLmV4cG9ydHMsXG4gICAgICAgIC8vIGxpa2UgTm9kZS5cbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQnJvd3NlciBnbG9iYWxzIChyb290IGlzIHdpbmRvdylcbiAgICAgICAgcm9vdC5yZXR1cm5FeHBvcnRzID0gZmFjdG9yeSgpO1xuICAgIH1cbn0odGhpcywgZnVuY3Rpb24gKCkge1xuICAgIC8qKlxuICAgICAqIEJyaW5ncyBhbiBlbnZpcm9ubWVudCBhcyBjbG9zZSB0byBFQ01BU2NyaXB0IDUgY29tcGxpYW5jZVxuICAgICAqIGFzIGlzIHBvc3NpYmxlIHdpdGggdGhlIGZhY2lsaXRpZXMgb2YgZXJzdHdoaWxlIGVuZ2luZXMuXG4gICAgICpcbiAgICAgKiBBbm5vdGF0ZWQgRVM1OiBodHRwOi8vZXM1LmdpdGh1Yi5jb20vIChzcGVjaWZpYyBsaW5rcyBiZWxvdylcbiAgICAgKiBFUzUgU3BlYzogaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL3B1YmxpY2F0aW9ucy9maWxlcy9FQ01BLVNUL0VjbWEtMjYyLnBkZlxuICAgICAqIFJlcXVpcmVkIHJlYWRpbmc6IGh0dHA6Ly9qYXZhc2NyaXB0d2VibG9nLndvcmRwcmVzcy5jb20vMjAxMS8xMi8wNS9leHRlbmRpbmctamF2YXNjcmlwdC1uYXRpdmVzL1xuICAgICAqL1xuXG4gICAgLy8gU2hvcnRjdXQgdG8gYW4gb2Z0ZW4gYWNjZXNzZWQgcHJvcGVydGllcywgaW4gb3JkZXIgdG8gYXZvaWQgbXVsdGlwbGVcbiAgICAvLyBkZXJlZmVyZW5jZSB0aGF0IGNvc3RzIHVuaXZlcnNhbGx5LiBUaGlzIGFsc28gaG9sZHMgYSByZWZlcmVuY2UgdG8ga25vd24tZ29vZFxuICAgIC8vIGZ1bmN0aW9ucy5cbiAgICB2YXIgJEFycmF5ID0gQXJyYXk7XG4gICAgdmFyIEFycmF5UHJvdG90eXBlID0gJEFycmF5LnByb3RvdHlwZTtcbiAgICB2YXIgJE9iamVjdCA9IE9iamVjdDtcbiAgICB2YXIgT2JqZWN0UHJvdG90eXBlID0gJE9iamVjdC5wcm90b3R5cGU7XG4gICAgdmFyICRGdW5jdGlvbiA9IEZ1bmN0aW9uO1xuICAgIHZhciBGdW5jdGlvblByb3RvdHlwZSA9ICRGdW5jdGlvbi5wcm90b3R5cGU7XG4gICAgdmFyICRTdHJpbmcgPSBTdHJpbmc7XG4gICAgdmFyIFN0cmluZ1Byb3RvdHlwZSA9ICRTdHJpbmcucHJvdG90eXBlO1xuICAgIHZhciAkTnVtYmVyID0gTnVtYmVyO1xuICAgIHZhciBOdW1iZXJQcm90b3R5cGUgPSAkTnVtYmVyLnByb3RvdHlwZTtcbiAgICB2YXIgYXJyYXlfc2xpY2UgPSBBcnJheVByb3RvdHlwZS5zbGljZTtcbiAgICB2YXIgYXJyYXlfc3BsaWNlID0gQXJyYXlQcm90b3R5cGUuc3BsaWNlO1xuICAgIHZhciBhcnJheV9wdXNoID0gQXJyYXlQcm90b3R5cGUucHVzaDtcbiAgICB2YXIgYXJyYXlfdW5zaGlmdCA9IEFycmF5UHJvdG90eXBlLnVuc2hpZnQ7XG4gICAgdmFyIGFycmF5X2NvbmNhdCA9IEFycmF5UHJvdG90eXBlLmNvbmNhdDtcbiAgICB2YXIgYXJyYXlfam9pbiA9IEFycmF5UHJvdG90eXBlLmpvaW47XG4gICAgdmFyIGNhbGwgPSBGdW5jdGlvblByb3RvdHlwZS5jYWxsO1xuICAgIHZhciBhcHBseSA9IEZ1bmN0aW9uUHJvdG90eXBlLmFwcGx5O1xuICAgIHZhciBtYXggPSBNYXRoLm1heDtcbiAgICB2YXIgbWluID0gTWF0aC5taW47XG5cbiAgICAvLyBIYXZpbmcgYSB0b1N0cmluZyBsb2NhbCB2YXJpYWJsZSBuYW1lIGJyZWFrcyBpbiBPcGVyYSBzbyB1c2UgdG9fc3RyaW5nLlxuICAgIHZhciB0b19zdHJpbmcgPSBPYmplY3RQcm90b3R5cGUudG9TdHJpbmc7XG5cbiAgICAvKiBnbG9iYWwgU3ltYm9sICovXG4gICAgLyogZXNsaW50LWRpc2FibGUgb25lLXZhci1kZWNsYXJhdGlvbi1wZXItbGluZSwgbm8tcmVkZWNsYXJlLCBtYXgtc3RhdGVtZW50cy1wZXItbGluZSAqL1xuICAgIHZhciBoYXNUb1N0cmluZ1RhZyA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIFN5bWJvbC50b1N0cmluZ1RhZyA9PT0gJ3N5bWJvbCc7XG4gICAgdmFyIGlzQ2FsbGFibGU7IC8qIGlubGluZWQgZnJvbSBodHRwczovL25wbWpzLmNvbS9pcy1jYWxsYWJsZSAqLyB2YXIgZm5Ub1N0ciA9IEZ1bmN0aW9uLnByb3RvdHlwZS50b1N0cmluZywgY29uc3RydWN0b3JSZWdleCA9IC9eXFxzKmNsYXNzIC8sIGlzRVM2Q2xhc3NGbiA9IGZ1bmN0aW9uIGlzRVM2Q2xhc3NGbih2YWx1ZSkgeyB0cnkgeyB2YXIgZm5TdHIgPSBmblRvU3RyLmNhbGwodmFsdWUpOyB2YXIgc2luZ2xlU3RyaXBwZWQgPSBmblN0ci5yZXBsYWNlKC9cXC9cXC8uKlxcbi9nLCAnJyk7IHZhciBtdWx0aVN0cmlwcGVkID0gc2luZ2xlU3RyaXBwZWQucmVwbGFjZSgvXFwvXFwqWy5cXHNcXFNdKlxcKlxcLy9nLCAnJyk7IHZhciBzcGFjZVN0cmlwcGVkID0gbXVsdGlTdHJpcHBlZC5yZXBsYWNlKC9cXG4vbWcsICcgJykucmVwbGFjZSgvIHsyfS9nLCAnICcpOyByZXR1cm4gY29uc3RydWN0b3JSZWdleC50ZXN0KHNwYWNlU3RyaXBwZWQpOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgLyogbm90IGEgZnVuY3Rpb24gKi8gfSB9LCB0cnlGdW5jdGlvbk9iamVjdCA9IGZ1bmN0aW9uIHRyeUZ1bmN0aW9uT2JqZWN0KHZhbHVlKSB7IHRyeSB7IGlmIChpc0VTNkNsYXNzRm4odmFsdWUpKSB7IHJldHVybiBmYWxzZTsgfSBmblRvU3RyLmNhbGwodmFsdWUpOyByZXR1cm4gdHJ1ZTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0gfSwgZm5DbGFzcyA9ICdbb2JqZWN0IEZ1bmN0aW9uXScsIGdlbkNsYXNzID0gJ1tvYmplY3QgR2VuZXJhdG9yRnVuY3Rpb25dJywgaXNDYWxsYWJsZSA9IGZ1bmN0aW9uIGlzQ2FsbGFibGUodmFsdWUpIHsgaWYgKCF2YWx1ZSkgeyByZXR1cm4gZmFsc2U7IH0gaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnKSB7IHJldHVybiBmYWxzZTsgfSBpZiAoaGFzVG9TdHJpbmdUYWcpIHsgcmV0dXJuIHRyeUZ1bmN0aW9uT2JqZWN0KHZhbHVlKTsgfSBpZiAoaXNFUzZDbGFzc0ZuKHZhbHVlKSkgeyByZXR1cm4gZmFsc2U7IH0gdmFyIHN0ckNsYXNzID0gdG9fc3RyaW5nLmNhbGwodmFsdWUpOyByZXR1cm4gc3RyQ2xhc3MgPT09IGZuQ2xhc3MgfHwgc3RyQ2xhc3MgPT09IGdlbkNsYXNzOyB9O1xuXG4gICAgdmFyIGlzUmVnZXg7IC8qIGlubGluZWQgZnJvbSBodHRwczovL25wbWpzLmNvbS9pcy1yZWdleCAqLyB2YXIgcmVnZXhFeGVjID0gUmVnRXhwLnByb3RvdHlwZS5leGVjLCB0cnlSZWdleEV4ZWMgPSBmdW5jdGlvbiB0cnlSZWdleEV4ZWModmFsdWUpIHsgdHJ5IHsgcmVnZXhFeGVjLmNhbGwodmFsdWUpOyByZXR1cm4gdHJ1ZTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0gfSwgcmVnZXhDbGFzcyA9ICdbb2JqZWN0IFJlZ0V4cF0nOyBpc1JlZ2V4ID0gZnVuY3Rpb24gaXNSZWdleCh2YWx1ZSkgeyBpZiAodHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JykgeyByZXR1cm4gZmFsc2U7IH0gcmV0dXJuIGhhc1RvU3RyaW5nVGFnID8gdHJ5UmVnZXhFeGVjKHZhbHVlKSA6IHRvX3N0cmluZy5jYWxsKHZhbHVlKSA9PT0gcmVnZXhDbGFzczsgfTtcbiAgICB2YXIgaXNTdHJpbmc7IC8qIGlubGluZWQgZnJvbSBodHRwczovL25wbWpzLmNvbS9pcy1zdHJpbmcgKi8gdmFyIHN0clZhbHVlID0gU3RyaW5nLnByb3RvdHlwZS52YWx1ZU9mLCB0cnlTdHJpbmdPYmplY3QgPSBmdW5jdGlvbiB0cnlTdHJpbmdPYmplY3QodmFsdWUpIHsgdHJ5IHsgc3RyVmFsdWUuY2FsbCh2YWx1ZSk7IHJldHVybiB0cnVlOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgfSB9LCBzdHJpbmdDbGFzcyA9ICdbb2JqZWN0IFN0cmluZ10nOyBpc1N0cmluZyA9IGZ1bmN0aW9uIGlzU3RyaW5nKHZhbHVlKSB7IGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7IHJldHVybiB0cnVlOyB9IGlmICh0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnKSB7IHJldHVybiBmYWxzZTsgfSByZXR1cm4gaGFzVG9TdHJpbmdUYWcgPyB0cnlTdHJpbmdPYmplY3QodmFsdWUpIDogdG9fc3RyaW5nLmNhbGwodmFsdWUpID09PSBzdHJpbmdDbGFzczsgfTtcbiAgICAvKiBlc2xpbnQtZW5hYmxlIG9uZS12YXItZGVjbGFyYXRpb24tcGVyLWxpbmUsIG5vLXJlZGVjbGFyZSwgbWF4LXN0YXRlbWVudHMtcGVyLWxpbmUgKi9cblxuICAgIC8qIGlubGluZWQgZnJvbSBodHRwOi8vbnBtanMuY29tL2RlZmluZS1wcm9wZXJ0aWVzICovXG4gICAgdmFyIHN1cHBvcnRzRGVzY3JpcHRvcnMgPSAkT2JqZWN0LmRlZmluZVByb3BlcnR5ICYmIChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB2YXIgb2JqID0ge307XG4gICAgICAgICAgICAkT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwgJ3gnLCB7IGVudW1lcmFibGU6IGZhbHNlLCB2YWx1ZTogb2JqIH0pO1xuICAgICAgICAgICAgZm9yICh2YXIgXyBpbiBvYmopIHsgLy8ganNjczppZ25vcmUgZGlzYWxsb3dVbnVzZWRWYXJpYWJsZXNcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gb2JqLnggPT09IG9iajtcbiAgICAgICAgfSBjYXRjaCAoZSkgeyAvKiB0aGlzIGlzIEVTMyAqL1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfSgpKTtcbiAgICB2YXIgZGVmaW5lUHJvcGVydGllcyA9IChmdW5jdGlvbiAoaGFzKSB7XG4gICAgICAgIC8vIERlZmluZSBjb25maWd1cmFibGUsIHdyaXRhYmxlLCBhbmQgbm9uLWVudW1lcmFibGUgcHJvcHNcbiAgICAgICAgLy8gaWYgdGhleSBkb24ndCBleGlzdC5cbiAgICAgICAgdmFyIGRlZmluZVByb3BlcnR5O1xuICAgICAgICBpZiAoc3VwcG9ydHNEZXNjcmlwdG9ycykge1xuICAgICAgICAgICAgZGVmaW5lUHJvcGVydHkgPSBmdW5jdGlvbiAob2JqZWN0LCBuYW1lLCBtZXRob2QsIGZvcmNlQXNzaWduKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFmb3JjZUFzc2lnbiAmJiAobmFtZSBpbiBvYmplY3QpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgJE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmplY3QsIG5hbWUsIHtcbiAgICAgICAgICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiBtZXRob2RcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkZWZpbmVQcm9wZXJ0eSA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWUsIG1ldGhvZCwgZm9yY2VBc3NpZ24pIHtcbiAgICAgICAgICAgICAgICBpZiAoIWZvcmNlQXNzaWduICYmIChuYW1lIGluIG9iamVjdCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvYmplY3RbbmFtZV0gPSBtZXRob2Q7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKG9iamVjdCwgbWFwLCBmb3JjZUFzc2lnbikge1xuICAgICAgICAgICAgZm9yICh2YXIgbmFtZSBpbiBtYXApIHtcbiAgICAgICAgICAgICAgICBpZiAoaGFzLmNhbGwobWFwLCBuYW1lKSkge1xuICAgICAgICAgICAgICAgICAgICBkZWZpbmVQcm9wZXJ0eShvYmplY3QsIG5hbWUsIG1hcFtuYW1lXSwgZm9yY2VBc3NpZ24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9KE9iamVjdFByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eSkpO1xuXG4gICAgLy9cbiAgICAvLyBVdGlsXG4gICAgLy8gPT09PT09XG4gICAgLy9cblxuICAgIC8qIHJlcGxhY2VhYmxlIHdpdGggaHR0cHM6Ly9ucG1qcy5jb20vcGFja2FnZS9lcy1hYnN0cmFjdCAvaGVscGVycy9pc1ByaW1pdGl2ZSAqL1xuICAgIHZhciBpc1ByaW1pdGl2ZSA9IGZ1bmN0aW9uIGlzUHJpbWl0aXZlKGlucHV0KSB7XG4gICAgICAgIHZhciB0eXBlID0gdHlwZW9mIGlucHV0O1xuICAgICAgICByZXR1cm4gaW5wdXQgPT09IG51bGwgfHwgKHR5cGUgIT09ICdvYmplY3QnICYmIHR5cGUgIT09ICdmdW5jdGlvbicpO1xuICAgIH07XG5cbiAgICB2YXIgaXNBY3R1YWxOYU4gPSAkTnVtYmVyLmlzTmFOIHx8IGZ1bmN0aW9uIGlzQWN0dWFsTmFOKHgpIHtcbiAgICAgICAgcmV0dXJuIHggIT09IHg7XG4gICAgfTtcblxuICAgIHZhciBFUyA9IHtcbiAgICAgICAgLy8gRVM1IDkuNFxuICAgICAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3g5LjRcbiAgICAgICAgLy8gaHR0cDovL2pzcGVyZi5jb20vdG8taW50ZWdlclxuICAgICAgICAvKiByZXBsYWNlYWJsZSB3aXRoIGh0dHBzOi8vbnBtanMuY29tL3BhY2thZ2UvZXMtYWJzdHJhY3QgRVM1LlRvSW50ZWdlciAqL1xuICAgICAgICBUb0ludGVnZXI6IGZ1bmN0aW9uIFRvSW50ZWdlcihudW0pIHtcbiAgICAgICAgICAgIHZhciBuID0gK251bTtcbiAgICAgICAgICAgIGlmIChpc0FjdHVhbE5hTihuKSkge1xuICAgICAgICAgICAgICAgIG4gPSAwO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChuICE9PSAwICYmIG4gIT09ICgxIC8gMCkgJiYgbiAhPT0gLSgxIC8gMCkpIHtcbiAgICAgICAgICAgICAgICBuID0gKG4gPiAwIHx8IC0xKSAqIE1hdGguZmxvb3IoTWF0aC5hYnMobikpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG47XG4gICAgICAgIH0sXG5cbiAgICAgICAgLyogcmVwbGFjZWFibGUgd2l0aCBodHRwczovL25wbWpzLmNvbS9wYWNrYWdlL2VzLWFic3RyYWN0IEVTNS5Ub1ByaW1pdGl2ZSAqL1xuICAgICAgICBUb1ByaW1pdGl2ZTogZnVuY3Rpb24gVG9QcmltaXRpdmUoaW5wdXQpIHtcbiAgICAgICAgICAgIHZhciB2YWwsIHZhbHVlT2YsIHRvU3RyO1xuICAgICAgICAgICAgaWYgKGlzUHJpbWl0aXZlKGlucHV0KSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhbHVlT2YgPSBpbnB1dC52YWx1ZU9mO1xuICAgICAgICAgICAgaWYgKGlzQ2FsbGFibGUodmFsdWVPZikpIHtcbiAgICAgICAgICAgICAgICB2YWwgPSB2YWx1ZU9mLmNhbGwoaW5wdXQpO1xuICAgICAgICAgICAgICAgIGlmIChpc1ByaW1pdGl2ZSh2YWwpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdG9TdHIgPSBpbnB1dC50b1N0cmluZztcbiAgICAgICAgICAgIGlmIChpc0NhbGxhYmxlKHRvU3RyKSkge1xuICAgICAgICAgICAgICAgIHZhbCA9IHRvU3RyLmNhbGwoaW5wdXQpO1xuICAgICAgICAgICAgICAgIGlmIChpc1ByaW1pdGl2ZSh2YWwpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICB9LFxuXG4gICAgICAgIC8vIEVTNSA5LjlcbiAgICAgICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4OS45XG4gICAgICAgIC8qIHJlcGxhY2VhYmxlIHdpdGggaHR0cHM6Ly9ucG1qcy5jb20vcGFja2FnZS9lcy1hYnN0cmFjdCBFUzUuVG9PYmplY3QgKi9cbiAgICAgICAgVG9PYmplY3Q6IGZ1bmN0aW9uIChvKSB7XG4gICAgICAgICAgICBpZiAobyA9PSBudWxsKSB7IC8vIHRoaXMgbWF0Y2hlcyBib3RoIG51bGwgYW5kIHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJjYW4ndCBjb252ZXJ0IFwiICsgbyArICcgdG8gb2JqZWN0Jyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gJE9iamVjdChvKTtcbiAgICAgICAgfSxcblxuICAgICAgICAvKiByZXBsYWNlYWJsZSB3aXRoIGh0dHBzOi8vbnBtanMuY29tL3BhY2thZ2UvZXMtYWJzdHJhY3QgRVM1LlRvVWludDMyICovXG4gICAgICAgIFRvVWludDMyOiBmdW5jdGlvbiBUb1VpbnQzMih4KSB7XG4gICAgICAgICAgICByZXR1cm4geCA+Pj4gMDtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvL1xuICAgIC8vIEZ1bmN0aW9uXG4gICAgLy8gPT09PT09PT1cbiAgICAvL1xuXG4gICAgLy8gRVMtNSAxNS4zLjQuNVxuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjMuNC41XG5cbiAgICB2YXIgRW1wdHkgPSBmdW5jdGlvbiBFbXB0eSgpIHt9O1xuXG4gICAgZGVmaW5lUHJvcGVydGllcyhGdW5jdGlvblByb3RvdHlwZSwge1xuICAgICAgICBiaW5kOiBmdW5jdGlvbiBiaW5kKHRoYXQpIHsgLy8gLmxlbmd0aCBpcyAxXG4gICAgICAgICAgICAvLyAxLiBMZXQgVGFyZ2V0IGJlIHRoZSB0aGlzIHZhbHVlLlxuICAgICAgICAgICAgdmFyIHRhcmdldCA9IHRoaXM7XG4gICAgICAgICAgICAvLyAyLiBJZiBJc0NhbGxhYmxlKFRhcmdldCkgaXMgZmFsc2UsIHRocm93IGEgVHlwZUVycm9yIGV4Y2VwdGlvbi5cbiAgICAgICAgICAgIGlmICghaXNDYWxsYWJsZSh0YXJnZXQpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgY2FsbGVkIG9uIGluY29tcGF0aWJsZSAnICsgdGFyZ2V0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIDMuIExldCBBIGJlIGEgbmV3IChwb3NzaWJseSBlbXB0eSkgaW50ZXJuYWwgbGlzdCBvZiBhbGwgb2YgdGhlXG4gICAgICAgICAgICAvLyAgIGFyZ3VtZW50IHZhbHVlcyBwcm92aWRlZCBhZnRlciB0aGlzQXJnIChhcmcxLCBhcmcyIGV0YyksIGluIG9yZGVyLlxuICAgICAgICAgICAgLy8gWFhYIHNsaWNlZEFyZ3Mgd2lsbCBzdGFuZCBpbiBmb3IgXCJBXCIgaWYgdXNlZFxuICAgICAgICAgICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7IC8vIGZvciBub3JtYWwgY2FsbFxuICAgICAgICAgICAgLy8gNC4gTGV0IEYgYmUgYSBuZXcgbmF0aXZlIEVDTUFTY3JpcHQgb2JqZWN0LlxuICAgICAgICAgICAgLy8gMTEuIFNldCB0aGUgW1tQcm90b3R5cGVdXSBpbnRlcm5hbCBwcm9wZXJ0eSBvZiBGIHRvIHRoZSBzdGFuZGFyZFxuICAgICAgICAgICAgLy8gICBidWlsdC1pbiBGdW5jdGlvbiBwcm90b3R5cGUgb2JqZWN0IGFzIHNwZWNpZmllZCBpbiAxNS4zLjMuMS5cbiAgICAgICAgICAgIC8vIDEyLiBTZXQgdGhlIFtbQ2FsbF1dIGludGVybmFsIHByb3BlcnR5IG9mIEYgYXMgZGVzY3JpYmVkIGluXG4gICAgICAgICAgICAvLyAgIDE1LjMuNC41LjEuXG4gICAgICAgICAgICAvLyAxMy4gU2V0IHRoZSBbW0NvbnN0cnVjdF1dIGludGVybmFsIHByb3BlcnR5IG9mIEYgYXMgZGVzY3JpYmVkIGluXG4gICAgICAgICAgICAvLyAgIDE1LjMuNC41LjIuXG4gICAgICAgICAgICAvLyAxNC4gU2V0IHRoZSBbW0hhc0luc3RhbmNlXV0gaW50ZXJuYWwgcHJvcGVydHkgb2YgRiBhcyBkZXNjcmliZWQgaW5cbiAgICAgICAgICAgIC8vICAgMTUuMy40LjUuMy5cbiAgICAgICAgICAgIHZhciBib3VuZDtcbiAgICAgICAgICAgIHZhciBiaW5kZXIgPSBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIGJvdW5kKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIDE1LjMuNC41LjIgW1tDb25zdHJ1Y3RdXVxuICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIHRoZSBbW0NvbnN0cnVjdF1dIGludGVybmFsIG1ldGhvZCBvZiBhIGZ1bmN0aW9uIG9iamVjdCxcbiAgICAgICAgICAgICAgICAgICAgLy8gRiB0aGF0IHdhcyBjcmVhdGVkIHVzaW5nIHRoZSBiaW5kIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aXRoIGFcbiAgICAgICAgICAgICAgICAgICAgLy8gbGlzdCBvZiBhcmd1bWVudHMgRXh0cmFBcmdzLCB0aGUgZm9sbG93aW5nIHN0ZXBzIGFyZSB0YWtlbjpcbiAgICAgICAgICAgICAgICAgICAgLy8gMS4gTGV0IHRhcmdldCBiZSB0aGUgdmFsdWUgb2YgRidzIFtbVGFyZ2V0RnVuY3Rpb25dXVxuICAgICAgICAgICAgICAgICAgICAvLyAgIGludGVybmFsIHByb3BlcnR5LlxuICAgICAgICAgICAgICAgICAgICAvLyAyLiBJZiB0YXJnZXQgaGFzIG5vIFtbQ29uc3RydWN0XV0gaW50ZXJuYWwgbWV0aG9kLCBhXG4gICAgICAgICAgICAgICAgICAgIC8vICAgVHlwZUVycm9yIGV4Y2VwdGlvbiBpcyB0aHJvd24uXG4gICAgICAgICAgICAgICAgICAgIC8vIDMuIExldCBib3VuZEFyZ3MgYmUgdGhlIHZhbHVlIG9mIEYncyBbW0JvdW5kQXJnc11dIGludGVybmFsXG4gICAgICAgICAgICAgICAgICAgIC8vICAgcHJvcGVydHkuXG4gICAgICAgICAgICAgICAgICAgIC8vIDQuIExldCBhcmdzIGJlIGEgbmV3IGxpc3QgY29udGFpbmluZyB0aGUgc2FtZSB2YWx1ZXMgYXMgdGhlXG4gICAgICAgICAgICAgICAgICAgIC8vICAgbGlzdCBib3VuZEFyZ3MgaW4gdGhlIHNhbWUgb3JkZXIgZm9sbG93ZWQgYnkgdGhlIHNhbWVcbiAgICAgICAgICAgICAgICAgICAgLy8gICB2YWx1ZXMgYXMgdGhlIGxpc3QgRXh0cmFBcmdzIGluIHRoZSBzYW1lIG9yZGVyLlxuICAgICAgICAgICAgICAgICAgICAvLyA1LiBSZXR1cm4gdGhlIHJlc3VsdCBvZiBjYWxsaW5nIHRoZSBbW0NvbnN0cnVjdF1dIGludGVybmFsXG4gICAgICAgICAgICAgICAgICAgIC8vICAgbWV0aG9kIG9mIHRhcmdldCBwcm92aWRpbmcgYXJncyBhcyB0aGUgYXJndW1lbnRzLlxuXG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSBhcHBseS5jYWxsKFxuICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5X2NvbmNhdC5jYWxsKGFyZ3MsIGFycmF5X3NsaWNlLmNhbGwoYXJndW1lbnRzKSlcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCRPYmplY3QocmVzdWx0KSA9PT0gcmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gMTUuMy40LjUuMSBbW0NhbGxdXVxuICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIHRoZSBbW0NhbGxdXSBpbnRlcm5hbCBtZXRob2Qgb2YgYSBmdW5jdGlvbiBvYmplY3QsIEYsXG4gICAgICAgICAgICAgICAgICAgIC8vIHdoaWNoIHdhcyBjcmVhdGVkIHVzaW5nIHRoZSBiaW5kIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aXRoIGFcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhpcyB2YWx1ZSBhbmQgYSBsaXN0IG9mIGFyZ3VtZW50cyBFeHRyYUFyZ3MsIHRoZSBmb2xsb3dpbmdcbiAgICAgICAgICAgICAgICAgICAgLy8gc3RlcHMgYXJlIHRha2VuOlxuICAgICAgICAgICAgICAgICAgICAvLyAxLiBMZXQgYm91bmRBcmdzIGJlIHRoZSB2YWx1ZSBvZiBGJ3MgW1tCb3VuZEFyZ3NdXSBpbnRlcm5hbFxuICAgICAgICAgICAgICAgICAgICAvLyAgIHByb3BlcnR5LlxuICAgICAgICAgICAgICAgICAgICAvLyAyLiBMZXQgYm91bmRUaGlzIGJlIHRoZSB2YWx1ZSBvZiBGJ3MgW1tCb3VuZFRoaXNdXSBpbnRlcm5hbFxuICAgICAgICAgICAgICAgICAgICAvLyAgIHByb3BlcnR5LlxuICAgICAgICAgICAgICAgICAgICAvLyAzLiBMZXQgdGFyZ2V0IGJlIHRoZSB2YWx1ZSBvZiBGJ3MgW1tUYXJnZXRGdW5jdGlvbl1dIGludGVybmFsXG4gICAgICAgICAgICAgICAgICAgIC8vICAgcHJvcGVydHkuXG4gICAgICAgICAgICAgICAgICAgIC8vIDQuIExldCBhcmdzIGJlIGEgbmV3IGxpc3QgY29udGFpbmluZyB0aGUgc2FtZSB2YWx1ZXMgYXMgdGhlXG4gICAgICAgICAgICAgICAgICAgIC8vICAgbGlzdCBib3VuZEFyZ3MgaW4gdGhlIHNhbWUgb3JkZXIgZm9sbG93ZWQgYnkgdGhlIHNhbWVcbiAgICAgICAgICAgICAgICAgICAgLy8gICB2YWx1ZXMgYXMgdGhlIGxpc3QgRXh0cmFBcmdzIGluIHRoZSBzYW1lIG9yZGVyLlxuICAgICAgICAgICAgICAgICAgICAvLyA1LiBSZXR1cm4gdGhlIHJlc3VsdCBvZiBjYWxsaW5nIHRoZSBbW0NhbGxdXSBpbnRlcm5hbCBtZXRob2RcbiAgICAgICAgICAgICAgICAgICAgLy8gICBvZiB0YXJnZXQgcHJvdmlkaW5nIGJvdW5kVGhpcyBhcyB0aGUgdGhpcyB2YWx1ZSBhbmRcbiAgICAgICAgICAgICAgICAgICAgLy8gICBwcm92aWRpbmcgYXJncyBhcyB0aGUgYXJndW1lbnRzLlxuXG4gICAgICAgICAgICAgICAgICAgIC8vIGVxdWl2OiB0YXJnZXQuY2FsbCh0aGlzLCAuLi5ib3VuZEFyZ3MsIC4uLmFyZ3MpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhcHBseS5jYWxsKFxuICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhhdCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5X2NvbmNhdC5jYWxsKGFyZ3MsIGFycmF5X3NsaWNlLmNhbGwoYXJndW1lbnRzKSlcbiAgICAgICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLy8gMTUuIElmIHRoZSBbW0NsYXNzXV0gaW50ZXJuYWwgcHJvcGVydHkgb2YgVGFyZ2V0IGlzIFwiRnVuY3Rpb25cIiwgdGhlblxuICAgICAgICAgICAgLy8gICAgIGEuIExldCBMIGJlIHRoZSBsZW5ndGggcHJvcGVydHkgb2YgVGFyZ2V0IG1pbnVzIHRoZSBsZW5ndGggb2YgQS5cbiAgICAgICAgICAgIC8vICAgICBiLiBTZXQgdGhlIGxlbmd0aCBvd24gcHJvcGVydHkgb2YgRiB0byBlaXRoZXIgMCBvciBMLCB3aGljaGV2ZXIgaXNcbiAgICAgICAgICAgIC8vICAgICAgIGxhcmdlci5cbiAgICAgICAgICAgIC8vIDE2LiBFbHNlIHNldCB0aGUgbGVuZ3RoIG93biBwcm9wZXJ0eSBvZiBGIHRvIDAuXG5cbiAgICAgICAgICAgIHZhciBib3VuZExlbmd0aCA9IG1heCgwLCB0YXJnZXQubGVuZ3RoIC0gYXJncy5sZW5ndGgpO1xuXG4gICAgICAgICAgICAvLyAxNy4gU2V0IHRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBsZW5ndGggb3duIHByb3BlcnR5IG9mIEYgdG8gdGhlIHZhbHVlc1xuICAgICAgICAgICAgLy8gICBzcGVjaWZpZWQgaW4gMTUuMy41LjEuXG4gICAgICAgICAgICB2YXIgYm91bmRBcmdzID0gW107XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJvdW5kTGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBhcnJheV9wdXNoLmNhbGwoYm91bmRBcmdzLCAnJCcgKyBpKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gWFhYIEJ1aWxkIGEgZHluYW1pYyBmdW5jdGlvbiB3aXRoIGRlc2lyZWQgYW1vdW50IG9mIGFyZ3VtZW50cyBpcyB0aGUgb25seVxuICAgICAgICAgICAgLy8gd2F5IHRvIHNldCB0aGUgbGVuZ3RoIHByb3BlcnR5IG9mIGEgZnVuY3Rpb24uXG4gICAgICAgICAgICAvLyBJbiBlbnZpcm9ubWVudHMgd2hlcmUgQ29udGVudCBTZWN1cml0eSBQb2xpY2llcyBlbmFibGVkIChDaHJvbWUgZXh0ZW5zaW9ucyxcbiAgICAgICAgICAgIC8vIGZvciBleC4pIGFsbCB1c2Ugb2YgZXZhbCBvciBGdW5jdGlvbiBjb3N0cnVjdG9yIHRocm93cyBhbiBleGNlcHRpb24uXG4gICAgICAgICAgICAvLyBIb3dldmVyIGluIGFsbCBvZiB0aGVzZSBlbnZpcm9ubWVudHMgRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgZXhpc3RzXG4gICAgICAgICAgICAvLyBhbmQgc28gdGhpcyBjb2RlIHdpbGwgbmV2ZXIgYmUgZXhlY3V0ZWQuXG4gICAgICAgICAgICBib3VuZCA9ICRGdW5jdGlvbignYmluZGVyJywgJ3JldHVybiBmdW5jdGlvbiAoJyArIGFycmF5X2pvaW4uY2FsbChib3VuZEFyZ3MsICcsJykgKyAnKXsgcmV0dXJuIGJpbmRlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9JykoYmluZGVyKTtcblxuICAgICAgICAgICAgaWYgKHRhcmdldC5wcm90b3R5cGUpIHtcbiAgICAgICAgICAgICAgICBFbXB0eS5wcm90b3R5cGUgPSB0YXJnZXQucHJvdG90eXBlO1xuICAgICAgICAgICAgICAgIGJvdW5kLnByb3RvdHlwZSA9IG5ldyBFbXB0eSgpO1xuICAgICAgICAgICAgICAgIC8vIENsZWFuIHVwIGRhbmdsaW5nIHJlZmVyZW5jZXMuXG4gICAgICAgICAgICAgICAgRW1wdHkucHJvdG90eXBlID0gbnVsbDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gVE9ET1xuICAgICAgICAgICAgLy8gMTguIFNldCB0aGUgW1tFeHRlbnNpYmxlXV0gaW50ZXJuYWwgcHJvcGVydHkgb2YgRiB0byB0cnVlLlxuXG4gICAgICAgICAgICAvLyBUT0RPXG4gICAgICAgICAgICAvLyAxOS4gTGV0IHRocm93ZXIgYmUgdGhlIFtbVGhyb3dUeXBlRXJyb3JdXSBmdW5jdGlvbiBPYmplY3QgKDEzLjIuMykuXG4gICAgICAgICAgICAvLyAyMC4gQ2FsbCB0aGUgW1tEZWZpbmVPd25Qcm9wZXJ0eV1dIGludGVybmFsIG1ldGhvZCBvZiBGIHdpdGhcbiAgICAgICAgICAgIC8vICAgYXJndW1lbnRzIFwiY2FsbGVyXCIsIFByb3BlcnR5RGVzY3JpcHRvciB7W1tHZXRdXTogdGhyb3dlciwgW1tTZXRdXTpcbiAgICAgICAgICAgIC8vICAgdGhyb3dlciwgW1tFbnVtZXJhYmxlXV06IGZhbHNlLCBbW0NvbmZpZ3VyYWJsZV1dOiBmYWxzZX0sIGFuZFxuICAgICAgICAgICAgLy8gICBmYWxzZS5cbiAgICAgICAgICAgIC8vIDIxLiBDYWxsIHRoZSBbW0RlZmluZU93blByb3BlcnR5XV0gaW50ZXJuYWwgbWV0aG9kIG9mIEYgd2l0aFxuICAgICAgICAgICAgLy8gICBhcmd1bWVudHMgXCJhcmd1bWVudHNcIiwgUHJvcGVydHlEZXNjcmlwdG9yIHtbW0dldF1dOiB0aHJvd2VyLFxuICAgICAgICAgICAgLy8gICBbW1NldF1dOiB0aHJvd2VyLCBbW0VudW1lcmFibGVdXTogZmFsc2UsIFtbQ29uZmlndXJhYmxlXV06IGZhbHNlfSxcbiAgICAgICAgICAgIC8vICAgYW5kIGZhbHNlLlxuXG4gICAgICAgICAgICAvLyBUT0RPXG4gICAgICAgICAgICAvLyBOT1RFIEZ1bmN0aW9uIG9iamVjdHMgY3JlYXRlZCB1c2luZyBGdW5jdGlvbi5wcm90b3R5cGUuYmluZCBkbyBub3RcbiAgICAgICAgICAgIC8vIGhhdmUgYSBwcm90b3R5cGUgcHJvcGVydHkgb3IgdGhlIFtbQ29kZV1dLCBbW0Zvcm1hbFBhcmFtZXRlcnNdXSwgYW5kXG4gICAgICAgICAgICAvLyBbW1Njb3BlXV0gaW50ZXJuYWwgcHJvcGVydGllcy5cbiAgICAgICAgICAgIC8vIFhYWCBjYW4ndCBkZWxldGUgcHJvdG90eXBlIGluIHB1cmUtanMuXG5cbiAgICAgICAgICAgIC8vIDIyLiBSZXR1cm4gRi5cbiAgICAgICAgICAgIHJldHVybiBib3VuZDtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gX1BsZWFzZSBub3RlOiBTaG9ydGN1dHMgYXJlIGRlZmluZWQgYWZ0ZXIgYEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kYCBhcyB3ZVxuICAgIC8vIHVzZSBpdCBpbiBkZWZpbmluZyBzaG9ydGN1dHMuXG4gICAgdmFyIG93bnMgPSBjYWxsLmJpbmQoT2JqZWN0UHJvdG90eXBlLmhhc093blByb3BlcnR5KTtcbiAgICB2YXIgdG9TdHIgPSBjYWxsLmJpbmQoT2JqZWN0UHJvdG90eXBlLnRvU3RyaW5nKTtcbiAgICB2YXIgYXJyYXlTbGljZSA9IGNhbGwuYmluZChhcnJheV9zbGljZSk7XG4gICAgdmFyIGFycmF5U2xpY2VBcHBseSA9IGFwcGx5LmJpbmQoYXJyYXlfc2xpY2UpO1xuICAgIHZhciBzdHJTbGljZSA9IGNhbGwuYmluZChTdHJpbmdQcm90b3R5cGUuc2xpY2UpO1xuICAgIHZhciBzdHJTcGxpdCA9IGNhbGwuYmluZChTdHJpbmdQcm90b3R5cGUuc3BsaXQpO1xuICAgIHZhciBzdHJJbmRleE9mID0gY2FsbC5iaW5kKFN0cmluZ1Byb3RvdHlwZS5pbmRleE9mKTtcbiAgICB2YXIgcHVzaENhbGwgPSBjYWxsLmJpbmQoYXJyYXlfcHVzaCk7XG4gICAgdmFyIGlzRW51bSA9IGNhbGwuYmluZChPYmplY3RQcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUpO1xuICAgIHZhciBhcnJheVNvcnQgPSBjYWxsLmJpbmQoQXJyYXlQcm90b3R5cGUuc29ydCk7XG5cbiAgICAvL1xuICAgIC8vIEFycmF5XG4gICAgLy8gPT09PT1cbiAgICAvL1xuXG4gICAgdmFyIGlzQXJyYXkgPSAkQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiBpc0FycmF5KG9iaikge1xuICAgICAgICByZXR1cm4gdG9TdHIob2JqKSA9PT0gJ1tvYmplY3QgQXJyYXldJztcbiAgICB9O1xuXG4gICAgLy8gRVM1IDE1LjQuNC4xMlxuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjQuNC4xM1xuICAgIC8vIFJldHVybiBsZW4rYXJnQ291bnQuXG4gICAgLy8gW2J1Z2ZpeCwgaWVsdDhdXG4gICAgLy8gSUUgPCA4IGJ1ZzogW10udW5zaGlmdCgwKSA9PT0gdW5kZWZpbmVkIGJ1dCBzaG91bGQgYmUgXCIxXCJcbiAgICB2YXIgaGFzVW5zaGlmdFJldHVyblZhbHVlQnVnID0gW10udW5zaGlmdCgwKSAhPT0gMTtcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIHVuc2hpZnQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGFycmF5X3Vuc2hpZnQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxlbmd0aDtcbiAgICAgICAgfVxuICAgIH0sIGhhc1Vuc2hpZnRSZXR1cm5WYWx1ZUJ1Zyk7XG5cbiAgICAvLyBFUzUgMTUuNC4zLjJcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS40LjMuMlxuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0FycmF5L2lzQXJyYXlcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKCRBcnJheSwgeyBpc0FycmF5OiBpc0FycmF5IH0pO1xuXG4gICAgLy8gVGhlIElzQ2FsbGFibGUoKSBjaGVjayBpbiB0aGUgQXJyYXkgZnVuY3Rpb25zXG4gICAgLy8gaGFzIGJlZW4gcmVwbGFjZWQgd2l0aCBhIHN0cmljdCBjaGVjayBvbiB0aGVcbiAgICAvLyBpbnRlcm5hbCBjbGFzcyBvZiB0aGUgb2JqZWN0IHRvIHRyYXAgY2FzZXMgd2hlcmVcbiAgICAvLyB0aGUgcHJvdmlkZWQgZnVuY3Rpb24gd2FzIGFjdHVhbGx5IGEgcmVndWxhclxuICAgIC8vIGV4cHJlc3Npb24gbGl0ZXJhbCwgd2hpY2ggaW4gVjggYW5kXG4gICAgLy8gSmF2YVNjcmlwdENvcmUgaXMgYSB0eXBlb2YgXCJmdW5jdGlvblwiLiAgT25seSBpblxuICAgIC8vIFY4IGFyZSByZWd1bGFyIGV4cHJlc3Npb24gbGl0ZXJhbHMgcGVybWl0dGVkIGFzXG4gICAgLy8gcmVkdWNlIHBhcmFtZXRlcnMsIHNvIGl0IGlzIGRlc2lyYWJsZSBpbiB0aGVcbiAgICAvLyBnZW5lcmFsIGNhc2UgZm9yIHRoZSBzaGltIHRvIG1hdGNoIHRoZSBtb3JlXG4gICAgLy8gc3RyaWN0IGFuZCBjb21tb24gYmVoYXZpb3Igb2YgcmVqZWN0aW5nIHJlZ3VsYXJcbiAgICAvLyBleHByZXNzaW9ucy5cblxuICAgIC8vIEVTNSAxNS40LjQuMThcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS40LjQuMThcbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9hcnJheS9mb3JFYWNoXG5cbiAgICAvLyBDaGVjayBmYWlsdXJlIG9mIGJ5LWluZGV4IGFjY2VzcyBvZiBzdHJpbmcgY2hhcmFjdGVycyAoSUUgPCA5KVxuICAgIC8vIGFuZCBmYWlsdXJlIG9mIGAwIGluIGJveGVkU3RyaW5nYCAoUmhpbm8pXG4gICAgdmFyIGJveGVkU3RyaW5nID0gJE9iamVjdCgnYScpO1xuICAgIHZhciBzcGxpdFN0cmluZyA9IGJveGVkU3RyaW5nWzBdICE9PSAnYScgfHwgISgwIGluIGJveGVkU3RyaW5nKTtcblxuICAgIHZhciBwcm9wZXJseUJveGVzQ29udGV4dCA9IGZ1bmN0aW9uIHByb3Blcmx5Qm94ZWQobWV0aG9kKSB7XG4gICAgICAgIC8vIENoZWNrIG5vZGUgMC42LjIxIGJ1ZyB3aGVyZSB0aGlyZCBwYXJhbWV0ZXIgaXMgbm90IGJveGVkXG4gICAgICAgIHZhciBwcm9wZXJseUJveGVzTm9uU3RyaWN0ID0gdHJ1ZTtcbiAgICAgICAgdmFyIHByb3Blcmx5Qm94ZXNTdHJpY3QgPSB0cnVlO1xuICAgICAgICB2YXIgdGhyZXdFeGNlcHRpb24gPSBmYWxzZTtcbiAgICAgICAgaWYgKG1ldGhvZCkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBtZXRob2QuY2FsbCgnZm9vJywgZnVuY3Rpb24gKF8sIF9fLCBjb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgY29udGV4dCAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb3Blcmx5Qm94ZXNOb25TdHJpY3QgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgbWV0aG9kLmNhbGwoWzFdLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICd1c2Ugc3RyaWN0JztcblxuICAgICAgICAgICAgICAgICAgICBwcm9wZXJseUJveGVzU3RyaWN0ID0gdHlwZW9mIHRoaXMgPT09ICdzdHJpbmcnO1xuICAgICAgICAgICAgICAgIH0sICd4Jyk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgdGhyZXdFeGNlcHRpb24gPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiAhIW1ldGhvZCAmJiAhdGhyZXdFeGNlcHRpb24gJiYgcHJvcGVybHlCb3hlc05vblN0cmljdCAmJiBwcm9wZXJseUJveGVzU3RyaWN0O1xuICAgIH07XG5cbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIGZvckVhY2g6IGZ1bmN0aW9uIGZvckVhY2goY2FsbGJhY2tmbi8qLCB0aGlzQXJnKi8pIHtcbiAgICAgICAgICAgIHZhciBvYmplY3QgPSBFUy5Ub09iamVjdCh0aGlzKTtcbiAgICAgICAgICAgIHZhciBzZWxmID0gc3BsaXRTdHJpbmcgJiYgaXNTdHJpbmcodGhpcykgPyBzdHJTcGxpdCh0aGlzLCAnJykgOiBvYmplY3Q7XG4gICAgICAgICAgICB2YXIgaSA9IC0xO1xuICAgICAgICAgICAgdmFyIGxlbmd0aCA9IEVTLlRvVWludDMyKHNlbGYubGVuZ3RoKTtcbiAgICAgICAgICAgIHZhciBUO1xuICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgVCA9IGFyZ3VtZW50c1sxXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gSWYgbm8gY2FsbGJhY2sgZnVuY3Rpb24gb3IgaWYgY2FsbGJhY2sgaXMgbm90IGEgY2FsbGFibGUgZnVuY3Rpb25cbiAgICAgICAgICAgIGlmICghaXNDYWxsYWJsZShjYWxsYmFja2ZuKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FycmF5LnByb3RvdHlwZS5mb3JFYWNoIGNhbGxiYWNrIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB3aGlsZSAoKytpIDwgbGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgaWYgKGkgaW4gc2VsZikge1xuICAgICAgICAgICAgICAgICAgICAvLyBJbnZva2UgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uIHdpdGggY2FsbCwgcGFzc2luZyBhcmd1bWVudHM6XG4gICAgICAgICAgICAgICAgICAgIC8vIGNvbnRleHQsIHByb3BlcnR5IHZhbHVlLCBwcm9wZXJ0eSBrZXksIHRoaXNBcmcgb2JqZWN0XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgVCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrZm4oc2VsZltpXSwgaSwgb2JqZWN0KTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrZm4uY2FsbChULCBzZWxmW2ldLCBpLCBvYmplY3QpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSwgIXByb3Blcmx5Qm94ZXNDb250ZXh0KEFycmF5UHJvdG90eXBlLmZvckVhY2gpKTtcblxuICAgIC8vIEVTNSAxNS40LjQuMTlcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS40LjQuMTlcbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9Db3JlX0phdmFTY3JpcHRfMS41X1JlZmVyZW5jZS9PYmplY3RzL0FycmF5L21hcFxuICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgbWFwOiBmdW5jdGlvbiBtYXAoY2FsbGJhY2tmbi8qLCB0aGlzQXJnKi8pIHtcbiAgICAgICAgICAgIHZhciBvYmplY3QgPSBFUy5Ub09iamVjdCh0aGlzKTtcbiAgICAgICAgICAgIHZhciBzZWxmID0gc3BsaXRTdHJpbmcgJiYgaXNTdHJpbmcodGhpcykgPyBzdHJTcGxpdCh0aGlzLCAnJykgOiBvYmplY3Q7XG4gICAgICAgICAgICB2YXIgbGVuZ3RoID0gRVMuVG9VaW50MzIoc2VsZi5sZW5ndGgpO1xuICAgICAgICAgICAgdmFyIHJlc3VsdCA9ICRBcnJheShsZW5ndGgpO1xuICAgICAgICAgICAgdmFyIFQ7XG4gICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgICAgICBUID0gYXJndW1lbnRzWzFdO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBJZiBubyBjYWxsYmFjayBmdW5jdGlvbiBvciBpZiBjYWxsYmFjayBpcyBub3QgYSBjYWxsYWJsZSBmdW5jdGlvblxuICAgICAgICAgICAgaWYgKCFpc0NhbGxhYmxlKGNhbGxiYWNrZm4pKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJyYXkucHJvdG90eXBlLm1hcCBjYWxsYmFjayBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmIChpIGluIHNlbGYpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBUID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0W2ldID0gY2FsbGJhY2tmbihzZWxmW2ldLCBpLCBvYmplY3QpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0W2ldID0gY2FsbGJhY2tmbi5jYWxsKFQsIHNlbGZbaV0sIGksIG9iamVjdCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgfSwgIXByb3Blcmx5Qm94ZXNDb250ZXh0KEFycmF5UHJvdG90eXBlLm1hcCkpO1xuXG4gICAgLy8gRVM1IDE1LjQuNC4yMFxuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjQuNC4yMFxuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0NvcmVfSmF2YVNjcmlwdF8xLjVfUmVmZXJlbmNlL09iamVjdHMvQXJyYXkvZmlsdGVyXG4gICAgZGVmaW5lUHJvcGVydGllcyhBcnJheVByb3RvdHlwZSwge1xuICAgICAgICBmaWx0ZXI6IGZ1bmN0aW9uIGZpbHRlcihjYWxsYmFja2ZuLyosIHRoaXNBcmcqLykge1xuICAgICAgICAgICAgdmFyIG9iamVjdCA9IEVTLlRvT2JqZWN0KHRoaXMpO1xuICAgICAgICAgICAgdmFyIHNlbGYgPSBzcGxpdFN0cmluZyAmJiBpc1N0cmluZyh0aGlzKSA/IHN0clNwbGl0KHRoaXMsICcnKSA6IG9iamVjdDtcbiAgICAgICAgICAgIHZhciBsZW5ndGggPSBFUy5Ub1VpbnQzMihzZWxmLmxlbmd0aCk7XG4gICAgICAgICAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgICAgICAgICB2YXIgdmFsdWU7XG4gICAgICAgICAgICB2YXIgVDtcbiAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICAgIFQgPSBhcmd1bWVudHNbMV07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIElmIG5vIGNhbGxiYWNrIGZ1bmN0aW9uIG9yIGlmIGNhbGxiYWNrIGlzIG5vdCBhIGNhbGxhYmxlIGZ1bmN0aW9uXG4gICAgICAgICAgICBpZiAoIWlzQ2FsbGFibGUoY2FsbGJhY2tmbikpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcnJheS5wcm90b3R5cGUuZmlsdGVyIGNhbGxiYWNrIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGkgaW4gc2VsZikge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHNlbGZbaV07XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgVCA9PT0gJ3VuZGVmaW5lZCcgPyBjYWxsYmFja2ZuKHZhbHVlLCBpLCBvYmplY3QpIDogY2FsbGJhY2tmbi5jYWxsKFQsIHZhbHVlLCBpLCBvYmplY3QpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwdXNoQ2FsbChyZXN1bHQsIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cbiAgICB9LCAhcHJvcGVybHlCb3hlc0NvbnRleHQoQXJyYXlQcm90b3R5cGUuZmlsdGVyKSk7XG5cbiAgICAvLyBFUzUgMTUuNC40LjE2XG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuNC40LjE2XG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4vSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvQXJyYXkvZXZlcnlcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIGV2ZXJ5OiBmdW5jdGlvbiBldmVyeShjYWxsYmFja2ZuLyosIHRoaXNBcmcqLykge1xuICAgICAgICAgICAgdmFyIG9iamVjdCA9IEVTLlRvT2JqZWN0KHRoaXMpO1xuICAgICAgICAgICAgdmFyIHNlbGYgPSBzcGxpdFN0cmluZyAmJiBpc1N0cmluZyh0aGlzKSA/IHN0clNwbGl0KHRoaXMsICcnKSA6IG9iamVjdDtcbiAgICAgICAgICAgIHZhciBsZW5ndGggPSBFUy5Ub1VpbnQzMihzZWxmLmxlbmd0aCk7XG4gICAgICAgICAgICB2YXIgVDtcbiAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICAgIFQgPSBhcmd1bWVudHNbMV07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIElmIG5vIGNhbGxiYWNrIGZ1bmN0aW9uIG9yIGlmIGNhbGxiYWNrIGlzIG5vdCBhIGNhbGxhYmxlIGZ1bmN0aW9uXG4gICAgICAgICAgICBpZiAoIWlzQ2FsbGFibGUoY2FsbGJhY2tmbikpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcnJheS5wcm90b3R5cGUuZXZlcnkgY2FsbGJhY2sgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoaSBpbiBzZWxmICYmICEodHlwZW9mIFQgPT09ICd1bmRlZmluZWQnID8gY2FsbGJhY2tmbihzZWxmW2ldLCBpLCBvYmplY3QpIDogY2FsbGJhY2tmbi5jYWxsKFQsIHNlbGZbaV0sIGksIG9iamVjdCkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH0sICFwcm9wZXJseUJveGVzQ29udGV4dChBcnJheVByb3RvdHlwZS5ldmVyeSkpO1xuXG4gICAgLy8gRVM1IDE1LjQuNC4xN1xuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjQuNC4xN1xuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0FycmF5L3NvbWVcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIHNvbWU6IGZ1bmN0aW9uIHNvbWUoY2FsbGJhY2tmbi8qLCB0aGlzQXJnICovKSB7XG4gICAgICAgICAgICB2YXIgb2JqZWN0ID0gRVMuVG9PYmplY3QodGhpcyk7XG4gICAgICAgICAgICB2YXIgc2VsZiA9IHNwbGl0U3RyaW5nICYmIGlzU3RyaW5nKHRoaXMpID8gc3RyU3BsaXQodGhpcywgJycpIDogb2JqZWN0O1xuICAgICAgICAgICAgdmFyIGxlbmd0aCA9IEVTLlRvVWludDMyKHNlbGYubGVuZ3RoKTtcbiAgICAgICAgICAgIHZhciBUO1xuICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgVCA9IGFyZ3VtZW50c1sxXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gSWYgbm8gY2FsbGJhY2sgZnVuY3Rpb24gb3IgaWYgY2FsbGJhY2sgaXMgbm90IGEgY2FsbGFibGUgZnVuY3Rpb25cbiAgICAgICAgICAgIGlmICghaXNDYWxsYWJsZShjYWxsYmFja2ZuKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FycmF5LnByb3RvdHlwZS5zb21lIGNhbGxiYWNrIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGkgaW4gc2VsZiAmJiAodHlwZW9mIFQgPT09ICd1bmRlZmluZWQnID8gY2FsbGJhY2tmbihzZWxmW2ldLCBpLCBvYmplY3QpIDogY2FsbGJhY2tmbi5jYWxsKFQsIHNlbGZbaV0sIGksIG9iamVjdCkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH0sICFwcm9wZXJseUJveGVzQ29udGV4dChBcnJheVByb3RvdHlwZS5zb21lKSk7XG5cbiAgICAvLyBFUzUgMTUuNC40LjIxXG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuNC40LjIxXG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4vQ29yZV9KYXZhU2NyaXB0XzEuNV9SZWZlcmVuY2UvT2JqZWN0cy9BcnJheS9yZWR1Y2VcbiAgICB2YXIgcmVkdWNlQ29lcmNlc1RvT2JqZWN0ID0gZmFsc2U7XG4gICAgaWYgKEFycmF5UHJvdG90eXBlLnJlZHVjZSkge1xuICAgICAgICByZWR1Y2VDb2VyY2VzVG9PYmplY3QgPSB0eXBlb2YgQXJyYXlQcm90b3R5cGUucmVkdWNlLmNhbGwoJ2VzNScsIGZ1bmN0aW9uIChfLCBfXywgX19fLCBsaXN0KSB7XG4gICAgICAgICAgICByZXR1cm4gbGlzdDtcbiAgICAgICAgfSkgPT09ICdvYmplY3QnO1xuICAgIH1cbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIHJlZHVjZTogZnVuY3Rpb24gcmVkdWNlKGNhbGxiYWNrZm4vKiwgaW5pdGlhbFZhbHVlKi8pIHtcbiAgICAgICAgICAgIHZhciBvYmplY3QgPSBFUy5Ub09iamVjdCh0aGlzKTtcbiAgICAgICAgICAgIHZhciBzZWxmID0gc3BsaXRTdHJpbmcgJiYgaXNTdHJpbmcodGhpcykgPyBzdHJTcGxpdCh0aGlzLCAnJykgOiBvYmplY3Q7XG4gICAgICAgICAgICB2YXIgbGVuZ3RoID0gRVMuVG9VaW50MzIoc2VsZi5sZW5ndGgpO1xuXG4gICAgICAgICAgICAvLyBJZiBubyBjYWxsYmFjayBmdW5jdGlvbiBvciBpZiBjYWxsYmFjayBpcyBub3QgYSBjYWxsYWJsZSBmdW5jdGlvblxuICAgICAgICAgICAgaWYgKCFpc0NhbGxhYmxlKGNhbGxiYWNrZm4pKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJyYXkucHJvdG90eXBlLnJlZHVjZSBjYWxsYmFjayBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gbm8gdmFsdWUgdG8gcmV0dXJuIGlmIG5vIGluaXRpYWwgdmFsdWUgYW5kIGFuIGVtcHR5IGFycmF5XG4gICAgICAgICAgICBpZiAobGVuZ3RoID09PSAwICYmIGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdyZWR1Y2Ugb2YgZW1wdHkgYXJyYXkgd2l0aCBubyBpbml0aWFsIHZhbHVlJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBpID0gMDtcbiAgICAgICAgICAgIHZhciByZXN1bHQ7XG4gICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSAyKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gYXJndW1lbnRzWzFdO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpIGluIHNlbGYpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHNlbGZbaSsrXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gaWYgYXJyYXkgY29udGFpbnMgbm8gdmFsdWVzLCBubyBpbml0aWFsIHZhbHVlIHRvIHJldHVyblxuICAgICAgICAgICAgICAgICAgICBpZiAoKytpID49IGxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigncmVkdWNlIG9mIGVtcHR5IGFycmF5IHdpdGggbm8gaW5pdGlhbCB2YWx1ZScpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSB3aGlsZSAodHJ1ZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZvciAoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoaSBpbiBzZWxmKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGNhbGxiYWNrZm4ocmVzdWx0LCBzZWxmW2ldLCBpLCBvYmplY3QpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuICAgIH0sICFyZWR1Y2VDb2VyY2VzVG9PYmplY3QpO1xuXG4gICAgLy8gRVM1IDE1LjQuNC4yMlxuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjQuNC4yMlxuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0NvcmVfSmF2YVNjcmlwdF8xLjVfUmVmZXJlbmNlL09iamVjdHMvQXJyYXkvcmVkdWNlUmlnaHRcbiAgICB2YXIgcmVkdWNlUmlnaHRDb2VyY2VzVG9PYmplY3QgPSBmYWxzZTtcbiAgICBpZiAoQXJyYXlQcm90b3R5cGUucmVkdWNlUmlnaHQpIHtcbiAgICAgICAgcmVkdWNlUmlnaHRDb2VyY2VzVG9PYmplY3QgPSB0eXBlb2YgQXJyYXlQcm90b3R5cGUucmVkdWNlUmlnaHQuY2FsbCgnZXM1JywgZnVuY3Rpb24gKF8sIF9fLCBfX18sIGxpc3QpIHtcbiAgICAgICAgICAgIHJldHVybiBsaXN0O1xuICAgICAgICB9KSA9PT0gJ29iamVjdCc7XG4gICAgfVxuICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgcmVkdWNlUmlnaHQ6IGZ1bmN0aW9uIHJlZHVjZVJpZ2h0KGNhbGxiYWNrZm4vKiwgaW5pdGlhbCovKSB7XG4gICAgICAgICAgICB2YXIgb2JqZWN0ID0gRVMuVG9PYmplY3QodGhpcyk7XG4gICAgICAgICAgICB2YXIgc2VsZiA9IHNwbGl0U3RyaW5nICYmIGlzU3RyaW5nKHRoaXMpID8gc3RyU3BsaXQodGhpcywgJycpIDogb2JqZWN0O1xuICAgICAgICAgICAgdmFyIGxlbmd0aCA9IEVTLlRvVWludDMyKHNlbGYubGVuZ3RoKTtcblxuICAgICAgICAgICAgLy8gSWYgbm8gY2FsbGJhY2sgZnVuY3Rpb24gb3IgaWYgY2FsbGJhY2sgaXMgbm90IGEgY2FsbGFibGUgZnVuY3Rpb25cbiAgICAgICAgICAgIGlmICghaXNDYWxsYWJsZShjYWxsYmFja2ZuKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FycmF5LnByb3RvdHlwZS5yZWR1Y2VSaWdodCBjYWxsYmFjayBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gbm8gdmFsdWUgdG8gcmV0dXJuIGlmIG5vIGluaXRpYWwgdmFsdWUsIGVtcHR5IGFycmF5XG4gICAgICAgICAgICBpZiAobGVuZ3RoID09PSAwICYmIGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdyZWR1Y2VSaWdodCBvZiBlbXB0eSBhcnJheSB3aXRoIG5vIGluaXRpYWwgdmFsdWUnKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIHJlc3VsdDtcbiAgICAgICAgICAgIHZhciBpID0gbGVuZ3RoIC0gMTtcbiAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDIpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBhcmd1bWVudHNbMV07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGkgaW4gc2VsZikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gc2VsZltpLS1dO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBpZiBhcnJheSBjb250YWlucyBubyB2YWx1ZXMsIG5vIGluaXRpYWwgdmFsdWUgdG8gcmV0dXJuXG4gICAgICAgICAgICAgICAgICAgIGlmICgtLWkgPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdyZWR1Y2VSaWdodCBvZiBlbXB0eSBhcnJheSB3aXRoIG5vIGluaXRpYWwgdmFsdWUnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gd2hpbGUgKHRydWUpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoaSA8IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAgICAgaWYgKGkgaW4gc2VsZikge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBjYWxsYmFja2ZuKHJlc3VsdCwgc2VsZltpXSwgaSwgb2JqZWN0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IHdoaWxlIChpLS0pO1xuXG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgfSwgIXJlZHVjZVJpZ2h0Q29lcmNlc1RvT2JqZWN0KTtcblxuICAgIC8vIEVTNSAxNS40LjQuMTRcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS40LjQuMTRcbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9BcnJheS9pbmRleE9mXG4gICAgdmFyIGhhc0ZpcmVmb3gySW5kZXhPZkJ1ZyA9IEFycmF5UHJvdG90eXBlLmluZGV4T2YgJiYgWzAsIDFdLmluZGV4T2YoMSwgMikgIT09IC0xO1xuICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgaW5kZXhPZjogZnVuY3Rpb24gaW5kZXhPZihzZWFyY2hFbGVtZW50LyosIGZyb21JbmRleCAqLykge1xuICAgICAgICAgICAgdmFyIHNlbGYgPSBzcGxpdFN0cmluZyAmJiBpc1N0cmluZyh0aGlzKSA/IHN0clNwbGl0KHRoaXMsICcnKSA6IEVTLlRvT2JqZWN0KHRoaXMpO1xuICAgICAgICAgICAgdmFyIGxlbmd0aCA9IEVTLlRvVWludDMyKHNlbGYubGVuZ3RoKTtcblxuICAgICAgICAgICAgaWYgKGxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIGkgPSAwO1xuICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgaSA9IEVTLlRvSW50ZWdlcihhcmd1bWVudHNbMV0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBoYW5kbGUgbmVnYXRpdmUgaW5kaWNlc1xuICAgICAgICAgICAgaSA9IGkgPj0gMCA/IGkgOiBtYXgoMCwgbGVuZ3RoICsgaSk7XG4gICAgICAgICAgICBmb3IgKDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGkgaW4gc2VsZiAmJiBzZWxmW2ldID09PSBzZWFyY2hFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgfVxuICAgIH0sIGhhc0ZpcmVmb3gySW5kZXhPZkJ1Zyk7XG5cbiAgICAvLyBFUzUgMTUuNC40LjE1XG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuNC40LjE1XG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4vSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvQXJyYXkvbGFzdEluZGV4T2ZcbiAgICB2YXIgaGFzRmlyZWZveDJMYXN0SW5kZXhPZkJ1ZyA9IEFycmF5UHJvdG90eXBlLmxhc3RJbmRleE9mICYmIFswLCAxXS5sYXN0SW5kZXhPZigwLCAtMykgIT09IC0xO1xuICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgbGFzdEluZGV4T2Y6IGZ1bmN0aW9uIGxhc3RJbmRleE9mKHNlYXJjaEVsZW1lbnQvKiwgZnJvbUluZGV4ICovKSB7XG4gICAgICAgICAgICB2YXIgc2VsZiA9IHNwbGl0U3RyaW5nICYmIGlzU3RyaW5nKHRoaXMpID8gc3RyU3BsaXQodGhpcywgJycpIDogRVMuVG9PYmplY3QodGhpcyk7XG4gICAgICAgICAgICB2YXIgbGVuZ3RoID0gRVMuVG9VaW50MzIoc2VsZi5sZW5ndGgpO1xuXG4gICAgICAgICAgICBpZiAobGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGkgPSBsZW5ndGggLSAxO1xuICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgaSA9IG1pbihpLCBFUy5Ub0ludGVnZXIoYXJndW1lbnRzWzFdKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBoYW5kbGUgbmVnYXRpdmUgaW5kaWNlc1xuICAgICAgICAgICAgaSA9IGkgPj0gMCA/IGkgOiBsZW5ndGggLSBNYXRoLmFicyhpKTtcbiAgICAgICAgICAgIGZvciAoOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgICAgIGlmIChpIGluIHNlbGYgJiYgc2VhcmNoRWxlbWVudCA9PT0gc2VsZltpXSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH1cbiAgICB9LCBoYXNGaXJlZm94Mkxhc3RJbmRleE9mQnVnKTtcblxuICAgIC8vIEVTNSAxNS40LjQuMTJcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS40LjQuMTJcbiAgICB2YXIgc3BsaWNlTm9vcFJldHVybnNFbXB0eUFycmF5ID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGEgPSBbMSwgMl07XG4gICAgICAgIHZhciByZXN1bHQgPSBhLnNwbGljZSgpO1xuICAgICAgICByZXR1cm4gYS5sZW5ndGggPT09IDIgJiYgaXNBcnJheShyZXN1bHQpICYmIHJlc3VsdC5sZW5ndGggPT09IDA7XG4gICAgfSgpKTtcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIC8vIFNhZmFyaSA1LjAgYnVnIHdoZXJlIC5zcGxpY2UoKSByZXR1cm5zIHVuZGVmaW5lZFxuICAgICAgICBzcGxpY2U6IGZ1bmN0aW9uIHNwbGljZShzdGFydCwgZGVsZXRlQ291bnQpIHtcbiAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXlfc3BsaWNlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LCAhc3BsaWNlTm9vcFJldHVybnNFbXB0eUFycmF5KTtcblxuICAgIHZhciBzcGxpY2VXb3Jrc1dpdGhFbXB0eU9iamVjdCA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBvYmogPSB7fTtcbiAgICAgICAgQXJyYXlQcm90b3R5cGUuc3BsaWNlLmNhbGwob2JqLCAwLCAwLCAxKTtcbiAgICAgICAgcmV0dXJuIG9iai5sZW5ndGggPT09IDE7XG4gICAgfSgpKTtcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIHNwbGljZTogZnVuY3Rpb24gc3BsaWNlKHN0YXJ0LCBkZWxldGVDb3VudCkge1xuICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgYXJncyA9IGFyZ3VtZW50cztcbiAgICAgICAgICAgIHRoaXMubGVuZ3RoID0gbWF4KEVTLlRvSW50ZWdlcih0aGlzLmxlbmd0aCksIDApO1xuICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIHR5cGVvZiBkZWxldGVDb3VudCAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICBhcmdzID0gYXJyYXlTbGljZShhcmd1bWVudHMpO1xuICAgICAgICAgICAgICAgIGlmIChhcmdzLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgcHVzaENhbGwoYXJncywgdGhpcy5sZW5ndGggLSBzdGFydCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYXJnc1sxXSA9IEVTLlRvSW50ZWdlcihkZWxldGVDb3VudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGFycmF5X3NwbGljZS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgfVxuICAgIH0sICFzcGxpY2VXb3Jrc1dpdGhFbXB0eU9iamVjdCk7XG4gICAgdmFyIHNwbGljZVdvcmtzV2l0aExhcmdlU3BhcnNlQXJyYXlzID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gUGVyIGh0dHBzOi8vZ2l0aHViLmNvbS9lcy1zaGltcy9lczUtc2hpbS9pc3N1ZXMvMjk1XG4gICAgICAgIC8vIFNhZmFyaSA3LzggYnJlYWtzIHdpdGggc3BhcnNlIGFycmF5cyBvZiBzaXplIDFlNSBvciBncmVhdGVyXG4gICAgICAgIHZhciBhcnIgPSBuZXcgJEFycmF5KDFlNSk7XG4gICAgICAgIC8vIG5vdGU6IHRoZSBpbmRleCBNVVNUIGJlIDggb3IgbGFyZ2VyIG9yIHRoZSB0ZXN0IHdpbGwgZmFsc2UgcGFzc1xuICAgICAgICBhcnJbOF0gPSAneCc7XG4gICAgICAgIGFyci5zcGxpY2UoMSwgMSk7XG4gICAgICAgIC8vIG5vdGU6IHRoaXMgdGVzdCBtdXN0IGJlIGRlZmluZWQgKmFmdGVyKiB0aGUgaW5kZXhPZiBzaGltXG4gICAgICAgIC8vIHBlciBodHRwczovL2dpdGh1Yi5jb20vZXMtc2hpbXMvZXM1LXNoaW0vaXNzdWVzLzMxM1xuICAgICAgICByZXR1cm4gYXJyLmluZGV4T2YoJ3gnKSA9PT0gNztcbiAgICB9KCkpO1xuICAgIHZhciBzcGxpY2VXb3Jrc1dpdGhTbWFsbFNwYXJzZUFycmF5cyA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIFBlciBodHRwczovL2dpdGh1Yi5jb20vZXMtc2hpbXMvZXM1LXNoaW0vaXNzdWVzLzI5NVxuICAgICAgICAvLyBPcGVyYSAxMi4xNSBicmVha3Mgb24gdGhpcywgbm8gaWRlYSB3aHkuXG4gICAgICAgIHZhciBuID0gMjU2O1xuICAgICAgICB2YXIgYXJyID0gW107XG4gICAgICAgIGFycltuXSA9ICdhJztcbiAgICAgICAgYXJyLnNwbGljZShuICsgMSwgMCwgJ2InKTtcbiAgICAgICAgcmV0dXJuIGFycltuXSA9PT0gJ2EnO1xuICAgIH0oKSk7XG4gICAgZGVmaW5lUHJvcGVydGllcyhBcnJheVByb3RvdHlwZSwge1xuICAgICAgICBzcGxpY2U6IGZ1bmN0aW9uIHNwbGljZShzdGFydCwgZGVsZXRlQ291bnQpIHtcbiAgICAgICAgICAgIHZhciBPID0gRVMuVG9PYmplY3QodGhpcyk7XG4gICAgICAgICAgICB2YXIgQSA9IFtdO1xuICAgICAgICAgICAgdmFyIGxlbiA9IEVTLlRvVWludDMyKE8ubGVuZ3RoKTtcbiAgICAgICAgICAgIHZhciByZWxhdGl2ZVN0YXJ0ID0gRVMuVG9JbnRlZ2VyKHN0YXJ0KTtcbiAgICAgICAgICAgIHZhciBhY3R1YWxTdGFydCA9IHJlbGF0aXZlU3RhcnQgPCAwID8gbWF4KChsZW4gKyByZWxhdGl2ZVN0YXJ0KSwgMCkgOiBtaW4ocmVsYXRpdmVTdGFydCwgbGVuKTtcbiAgICAgICAgICAgIHZhciBhY3R1YWxEZWxldGVDb3VudCA9IG1pbihtYXgoRVMuVG9JbnRlZ2VyKGRlbGV0ZUNvdW50KSwgMCksIGxlbiAtIGFjdHVhbFN0YXJ0KTtcblxuICAgICAgICAgICAgdmFyIGsgPSAwO1xuICAgICAgICAgICAgdmFyIGZyb207XG4gICAgICAgICAgICB3aGlsZSAoayA8IGFjdHVhbERlbGV0ZUNvdW50KSB7XG4gICAgICAgICAgICAgICAgZnJvbSA9ICRTdHJpbmcoYWN0dWFsU3RhcnQgKyBrKTtcbiAgICAgICAgICAgICAgICBpZiAob3ducyhPLCBmcm9tKSkge1xuICAgICAgICAgICAgICAgICAgICBBW2tdID0gT1tmcm9tXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgayArPSAxO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgaXRlbXMgPSBhcnJheVNsaWNlKGFyZ3VtZW50cywgMik7XG4gICAgICAgICAgICB2YXIgaXRlbUNvdW50ID0gaXRlbXMubGVuZ3RoO1xuICAgICAgICAgICAgdmFyIHRvO1xuICAgICAgICAgICAgaWYgKGl0ZW1Db3VudCA8IGFjdHVhbERlbGV0ZUNvdW50KSB7XG4gICAgICAgICAgICAgICAgayA9IGFjdHVhbFN0YXJ0O1xuICAgICAgICAgICAgICAgIHZhciBtYXhLID0gbGVuIC0gYWN0dWFsRGVsZXRlQ291bnQ7XG4gICAgICAgICAgICAgICAgd2hpbGUgKGsgPCBtYXhLKSB7XG4gICAgICAgICAgICAgICAgICAgIGZyb20gPSAkU3RyaW5nKGsgKyBhY3R1YWxEZWxldGVDb3VudCk7XG4gICAgICAgICAgICAgICAgICAgIHRvID0gJFN0cmluZyhrICsgaXRlbUNvdW50KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG93bnMoTywgZnJvbSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIE9bdG9dID0gT1tmcm9tXTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBPW3RvXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBrICs9IDE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGsgPSBsZW47XG4gICAgICAgICAgICAgICAgdmFyIG1pbksgPSBsZW4gLSBhY3R1YWxEZWxldGVDb3VudCArIGl0ZW1Db3VudDtcbiAgICAgICAgICAgICAgICB3aGlsZSAoayA+IG1pbkspIHtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIE9bayAtIDFdO1xuICAgICAgICAgICAgICAgICAgICBrIC09IDE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChpdGVtQ291bnQgPiBhY3R1YWxEZWxldGVDb3VudCkge1xuICAgICAgICAgICAgICAgIGsgPSBsZW4gLSBhY3R1YWxEZWxldGVDb3VudDtcbiAgICAgICAgICAgICAgICB3aGlsZSAoayA+IGFjdHVhbFN0YXJ0KSB7XG4gICAgICAgICAgICAgICAgICAgIGZyb20gPSAkU3RyaW5nKGsgKyBhY3R1YWxEZWxldGVDb3VudCAtIDEpO1xuICAgICAgICAgICAgICAgICAgICB0byA9ICRTdHJpbmcoayArIGl0ZW1Db3VudCAtIDEpO1xuICAgICAgICAgICAgICAgICAgICBpZiAob3ducyhPLCBmcm9tKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgT1t0b10gPSBPW2Zyb21dO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIE9bdG9dO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGsgLT0gMTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBrID0gYWN0dWFsU3RhcnQ7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGl0ZW1zLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgT1trXSA9IGl0ZW1zW2ldO1xuICAgICAgICAgICAgICAgIGsgKz0gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIE8ubGVuZ3RoID0gbGVuIC0gYWN0dWFsRGVsZXRlQ291bnQgKyBpdGVtQ291bnQ7XG5cbiAgICAgICAgICAgIHJldHVybiBBO1xuICAgICAgICB9XG4gICAgfSwgIXNwbGljZVdvcmtzV2l0aExhcmdlU3BhcnNlQXJyYXlzIHx8ICFzcGxpY2VXb3Jrc1dpdGhTbWFsbFNwYXJzZUFycmF5cyk7XG5cbiAgICB2YXIgb3JpZ2luYWxKb2luID0gQXJyYXlQcm90b3R5cGUuam9pbjtcbiAgICB2YXIgaGFzU3RyaW5nSm9pbkJ1ZztcbiAgICB0cnkge1xuICAgICAgICBoYXNTdHJpbmdKb2luQnVnID0gQXJyYXkucHJvdG90eXBlLmpvaW4uY2FsbCgnMTIzJywgJywnKSAhPT0gJzEsMiwzJztcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGhhc1N0cmluZ0pvaW5CdWcgPSB0cnVlO1xuICAgIH1cbiAgICBpZiAoaGFzU3RyaW5nSm9pbkJ1Zykge1xuICAgICAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgICAgICBqb2luOiBmdW5jdGlvbiBqb2luKHNlcGFyYXRvcikge1xuICAgICAgICAgICAgICAgIHZhciBzZXAgPSB0eXBlb2Ygc2VwYXJhdG9yID09PSAndW5kZWZpbmVkJyA/ICcsJyA6IHNlcGFyYXRvcjtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3JpZ2luYWxKb2luLmNhbGwoaXNTdHJpbmcodGhpcykgPyBzdHJTcGxpdCh0aGlzLCAnJykgOiB0aGlzLCBzZXApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCBoYXNTdHJpbmdKb2luQnVnKTtcbiAgICB9XG5cbiAgICB2YXIgaGFzSm9pblVuZGVmaW5lZEJ1ZyA9IFsxLCAyXS5qb2luKHVuZGVmaW5lZCkgIT09ICcxLDInO1xuICAgIGlmIChoYXNKb2luVW5kZWZpbmVkQnVnKSB7XG4gICAgICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgICAgIGpvaW46IGZ1bmN0aW9uIGpvaW4oc2VwYXJhdG9yKSB7XG4gICAgICAgICAgICAgICAgdmFyIHNlcCA9IHR5cGVvZiBzZXBhcmF0b3IgPT09ICd1bmRlZmluZWQnID8gJywnIDogc2VwYXJhdG9yO1xuICAgICAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbEpvaW4uY2FsbCh0aGlzLCBzZXApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCBoYXNKb2luVW5kZWZpbmVkQnVnKTtcbiAgICB9XG5cbiAgICB2YXIgcHVzaFNoaW0gPSBmdW5jdGlvbiBwdXNoKGl0ZW0pIHtcbiAgICAgICAgdmFyIE8gPSBFUy5Ub09iamVjdCh0aGlzKTtcbiAgICAgICAgdmFyIG4gPSBFUy5Ub1VpbnQzMihPLmxlbmd0aCk7XG4gICAgICAgIHZhciBpID0gMDtcbiAgICAgICAgd2hpbGUgKGkgPCBhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICAgICAgICBPW24gKyBpXSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgICAgICAgIGkgKz0gMTtcbiAgICAgICAgfVxuICAgICAgICBPLmxlbmd0aCA9IG4gKyBpO1xuICAgICAgICByZXR1cm4gbiArIGk7XG4gICAgfTtcblxuICAgIHZhciBwdXNoSXNOb3RHZW5lcmljID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG9iaiA9IHt9O1xuICAgICAgICB2YXIgcmVzdWx0ID0gQXJyYXkucHJvdG90eXBlLnB1c2guY2FsbChvYmosIHVuZGVmaW5lZCk7XG4gICAgICAgIHJldHVybiByZXN1bHQgIT09IDEgfHwgb2JqLmxlbmd0aCAhPT0gMSB8fCB0eXBlb2Ygb2JqWzBdICE9PSAndW5kZWZpbmVkJyB8fCAhb3ducyhvYmosIDApO1xuICAgIH0oKSk7XG4gICAgZGVmaW5lUHJvcGVydGllcyhBcnJheVByb3RvdHlwZSwge1xuICAgICAgICBwdXNoOiBmdW5jdGlvbiBwdXNoKGl0ZW0pIHtcbiAgICAgICAgICAgIGlmIChpc0FycmF5KHRoaXMpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5X3B1c2guYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBwdXNoU2hpbS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgfSwgcHVzaElzTm90R2VuZXJpYyk7XG5cbiAgICAvLyBUaGlzIGZpeGVzIGEgdmVyeSB3ZWlyZCBidWcgaW4gT3BlcmEgMTAuNiB3aGVuIHB1c2hpbmcgYHVuZGVmaW5lZFxuICAgIHZhciBwdXNoVW5kZWZpbmVkSXNXZWlyZCA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBhcnIgPSBbXTtcbiAgICAgICAgdmFyIHJlc3VsdCA9IGFyci5wdXNoKHVuZGVmaW5lZCk7XG4gICAgICAgIHJldHVybiByZXN1bHQgIT09IDEgfHwgYXJyLmxlbmd0aCAhPT0gMSB8fCB0eXBlb2YgYXJyWzBdICE9PSAndW5kZWZpbmVkJyB8fCAhb3ducyhhcnIsIDApO1xuICAgIH0oKSk7XG4gICAgZGVmaW5lUHJvcGVydGllcyhBcnJheVByb3RvdHlwZSwgeyBwdXNoOiBwdXNoU2hpbSB9LCBwdXNoVW5kZWZpbmVkSXNXZWlyZCk7XG5cbiAgICAvLyBFUzUgMTUuMi4zLjE0XG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuaW8vI3gxNS40LjQuMTBcbiAgICAvLyBGaXggYm94ZWQgc3RyaW5nIGJ1Z1xuICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgc2xpY2U6IGZ1bmN0aW9uIChzdGFydCwgZW5kKSB7XG4gICAgICAgICAgICB2YXIgYXJyID0gaXNTdHJpbmcodGhpcykgPyBzdHJTcGxpdCh0aGlzLCAnJykgOiB0aGlzO1xuICAgICAgICAgICAgcmV0dXJuIGFycmF5U2xpY2VBcHBseShhcnIsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICB9LCBzcGxpdFN0cmluZyk7XG5cbiAgICB2YXIgc29ydElnbm9yZXNOb25GdW5jdGlvbnMgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgWzEsIDJdLnNvcnQobnVsbCk7XG4gICAgICAgICAgICBbMSwgMl0uc29ydCh7fSk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0oKSk7XG4gICAgdmFyIHNvcnRUaHJvd3NPblJlZ2V4ID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gdGhpcyBpcyBhIHByb2JsZW0gaW4gRmlyZWZveCA0LCBpbiB3aGljaCBgdHlwZW9mIC9hLyA9PT0gJ2Z1bmN0aW9uJ2BcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIFsxLCAyXS5zb3J0KC9hLyk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH0oKSk7XG4gICAgdmFyIHNvcnRJZ25vcmVzVW5kZWZpbmVkID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gYXBwbGllcyBpbiBJRSA4LCBmb3Igb25lLlxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgWzEsIDJdLnNvcnQodW5kZWZpbmVkKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9IGNhdGNoIChlKSB7fVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSgpKTtcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIHNvcnQ6IGZ1bmN0aW9uIHNvcnQoY29tcGFyZUZuKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGNvbXBhcmVGbiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXlTb3J0KHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFpc0NhbGxhYmxlKGNvbXBhcmVGbikpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcnJheS5wcm90b3R5cGUuc29ydCBjYWxsYmFjayBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBhcnJheVNvcnQodGhpcywgY29tcGFyZUZuKTtcbiAgICAgICAgfVxuICAgIH0sIHNvcnRJZ25vcmVzTm9uRnVuY3Rpb25zIHx8ICFzb3J0SWdub3Jlc1VuZGVmaW5lZCB8fCAhc29ydFRocm93c09uUmVnZXgpO1xuXG4gICAgLy9cbiAgICAvLyBPYmplY3RcbiAgICAvLyA9PT09PT1cbiAgICAvL1xuXG4gICAgLy8gRVM1IDE1LjIuMy4xNFxuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjIuMy4xNFxuXG4gICAgLy8gaHR0cDovL3doYXR0aGVoZWFkc2FpZC5jb20vMjAxMC8xMC9hLXNhZmVyLW9iamVjdC1rZXlzLWNvbXBhdGliaWxpdHktaW1wbGVtZW50YXRpb25cbiAgICB2YXIgaGFzRG9udEVudW1CdWcgPSAhaXNFbnVtKHsgJ3RvU3RyaW5nJzogbnVsbCB9LCAndG9TdHJpbmcnKTtcbiAgICB2YXIgaGFzUHJvdG9FbnVtQnVnID0gaXNFbnVtKGZ1bmN0aW9uICgpIHt9LCAncHJvdG90eXBlJyk7XG4gICAgdmFyIGhhc1N0cmluZ0VudW1CdWcgPSAhb3ducygneCcsICcwJyk7XG4gICAgdmFyIGVxdWFsc0NvbnN0cnVjdG9yUHJvdG90eXBlID0gZnVuY3Rpb24gKG8pIHtcbiAgICAgICAgdmFyIGN0b3IgPSBvLmNvbnN0cnVjdG9yO1xuICAgICAgICByZXR1cm4gY3RvciAmJiBjdG9yLnByb3RvdHlwZSA9PT0gbztcbiAgICB9O1xuICAgIHZhciBibGFja2xpc3RlZEtleXMgPSB7XG4gICAgICAgICR3aW5kb3c6IHRydWUsXG4gICAgICAgICRjb25zb2xlOiB0cnVlLFxuICAgICAgICAkcGFyZW50OiB0cnVlLFxuICAgICAgICAkc2VsZjogdHJ1ZSxcbiAgICAgICAgJGZyYW1lOiB0cnVlLFxuICAgICAgICAkZnJhbWVzOiB0cnVlLFxuICAgICAgICAkZnJhbWVFbGVtZW50OiB0cnVlLFxuICAgICAgICAkd2Via2l0SW5kZXhlZERCOiB0cnVlLFxuICAgICAgICAkd2Via2l0U3RvcmFnZUluZm86IHRydWUsXG4gICAgICAgICRleHRlcm5hbDogdHJ1ZVxuICAgIH07XG4gICAgdmFyIGhhc0F1dG9tYXRpb25FcXVhbGl0eUJ1ZyA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8qIGdsb2JhbHMgd2luZG93ICovXG4gICAgICAgIGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGZvciAodmFyIGsgaW4gd2luZG93KSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICghYmxhY2tsaXN0ZWRLZXlzWyckJyArIGtdICYmIG93bnMod2luZG93LCBrKSAmJiB3aW5kb3dba10gIT09IG51bGwgJiYgdHlwZW9mIHdpbmRvd1trXSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUod2luZG93W2tdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0oKSk7XG4gICAgdmFyIGVxdWFsc0NvbnN0cnVjdG9yUHJvdG90eXBlSWZOb3RCdWdneSA9IGZ1bmN0aW9uIChvYmplY3QpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnIHx8ICFoYXNBdXRvbWF0aW9uRXF1YWxpdHlCdWcpIHtcbiAgICAgICAgICAgIHJldHVybiBlcXVhbHNDb25zdHJ1Y3RvclByb3RvdHlwZShvYmplY3QpO1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUob2JqZWN0KTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfTtcbiAgICB2YXIgZG9udEVudW1zID0gW1xuICAgICAgICAndG9TdHJpbmcnLFxuICAgICAgICAndG9Mb2NhbGVTdHJpbmcnLFxuICAgICAgICAndmFsdWVPZicsXG4gICAgICAgICdoYXNPd25Qcm9wZXJ0eScsXG4gICAgICAgICdpc1Byb3RvdHlwZU9mJyxcbiAgICAgICAgJ3Byb3BlcnR5SXNFbnVtZXJhYmxlJyxcbiAgICAgICAgJ2NvbnN0cnVjdG9yJ1xuICAgIF07XG4gICAgdmFyIGRvbnRFbnVtc0xlbmd0aCA9IGRvbnRFbnVtcy5sZW5ndGg7XG5cbiAgICAvLyB0YWtlbiBkaXJlY3RseSBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9samhhcmIvaXMtYXJndW1lbnRzL2Jsb2IvbWFzdGVyL2luZGV4LmpzXG4gICAgLy8gY2FuIGJlIHJlcGxhY2VkIHdpdGggcmVxdWlyZSgnaXMtYXJndW1lbnRzJykgaWYgd2UgZXZlciB1c2UgYSBidWlsZCBwcm9jZXNzIGluc3RlYWRcbiAgICB2YXIgaXNTdGFuZGFyZEFyZ3VtZW50cyA9IGZ1bmN0aW9uIGlzQXJndW1lbnRzKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0b1N0cih2YWx1ZSkgPT09ICdbb2JqZWN0IEFyZ3VtZW50c10nO1xuICAgIH07XG4gICAgdmFyIGlzTGVnYWN5QXJndW1lbnRzID0gZnVuY3Rpb24gaXNBcmd1bWVudHModmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlICE9PSBudWxsICYmXG4gICAgICAgICAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgICAgICAgICB0eXBlb2YgdmFsdWUubGVuZ3RoID09PSAnbnVtYmVyJyAmJlxuICAgICAgICAgICAgdmFsdWUubGVuZ3RoID49IDAgJiZcbiAgICAgICAgICAgICFpc0FycmF5KHZhbHVlKSAmJlxuICAgICAgICAgICAgaXNDYWxsYWJsZSh2YWx1ZS5jYWxsZWUpO1xuICAgIH07XG4gICAgdmFyIGlzQXJndW1lbnRzID0gaXNTdGFuZGFyZEFyZ3VtZW50cyhhcmd1bWVudHMpID8gaXNTdGFuZGFyZEFyZ3VtZW50cyA6IGlzTGVnYWN5QXJndW1lbnRzO1xuXG4gICAgZGVmaW5lUHJvcGVydGllcygkT2JqZWN0LCB7XG4gICAgICAgIGtleXM6IGZ1bmN0aW9uIGtleXMob2JqZWN0KSB7XG4gICAgICAgICAgICB2YXIgaXNGbiA9IGlzQ2FsbGFibGUob2JqZWN0KTtcbiAgICAgICAgICAgIHZhciBpc0FyZ3MgPSBpc0FyZ3VtZW50cyhvYmplY3QpO1xuICAgICAgICAgICAgdmFyIGlzT2JqZWN0ID0gb2JqZWN0ICE9PSBudWxsICYmIHR5cGVvZiBvYmplY3QgPT09ICdvYmplY3QnO1xuICAgICAgICAgICAgdmFyIGlzU3RyID0gaXNPYmplY3QgJiYgaXNTdHJpbmcob2JqZWN0KTtcblxuICAgICAgICAgICAgaWYgKCFpc09iamVjdCAmJiAhaXNGbiAmJiAhaXNBcmdzKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignT2JqZWN0LmtleXMgY2FsbGVkIG9uIGEgbm9uLW9iamVjdCcpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgdGhlS2V5cyA9IFtdO1xuICAgICAgICAgICAgdmFyIHNraXBQcm90byA9IGhhc1Byb3RvRW51bUJ1ZyAmJiBpc0ZuO1xuICAgICAgICAgICAgaWYgKChpc1N0ciAmJiBoYXNTdHJpbmdFbnVtQnVnKSB8fCBpc0FyZ3MpIHtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICBwdXNoQ2FsbCh0aGVLZXlzLCAkU3RyaW5nKGkpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghaXNBcmdzKSB7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgbmFtZSBpbiBvYmplY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEoc2tpcFByb3RvICYmIG5hbWUgPT09ICdwcm90b3R5cGUnKSAmJiBvd25zKG9iamVjdCwgbmFtZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1c2hDYWxsKHRoZUtleXMsICRTdHJpbmcobmFtZSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoaGFzRG9udEVudW1CdWcpIHtcbiAgICAgICAgICAgICAgICB2YXIgc2tpcENvbnN0cnVjdG9yID0gZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGVJZk5vdEJ1Z2d5KG9iamVjdCk7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBkb250RW51bXNMZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZG9udEVudW0gPSBkb250RW51bXNbal07XG4gICAgICAgICAgICAgICAgICAgIGlmICghKHNraXBDb25zdHJ1Y3RvciAmJiBkb250RW51bSA9PT0gJ2NvbnN0cnVjdG9yJykgJiYgb3ducyhvYmplY3QsIGRvbnRFbnVtKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcHVzaENhbGwodGhlS2V5cywgZG9udEVudW0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoZUtleXM7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIHZhciBrZXlzV29ya3NXaXRoQXJndW1lbnRzID0gJE9iamVjdC5rZXlzICYmIChmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIFNhZmFyaSA1LjAgYnVnXG4gICAgICAgIHJldHVybiAkT2JqZWN0LmtleXMoYXJndW1lbnRzKS5sZW5ndGggPT09IDI7XG4gICAgfSgxLCAyKSk7XG4gICAgdmFyIGtleXNIYXNBcmd1bWVudHNMZW5ndGhCdWcgPSAkT2JqZWN0LmtleXMgJiYgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGFyZ0tleXMgPSAkT2JqZWN0LmtleXMoYXJndW1lbnRzKTtcbiAgICAgICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggIT09IDEgfHwgYXJnS2V5cy5sZW5ndGggIT09IDEgfHwgYXJnS2V5c1swXSAhPT0gMTtcbiAgICB9KDEpKTtcbiAgICB2YXIgb3JpZ2luYWxLZXlzID0gJE9iamVjdC5rZXlzO1xuICAgIGRlZmluZVByb3BlcnRpZXMoJE9iamVjdCwge1xuICAgICAgICBrZXlzOiBmdW5jdGlvbiBrZXlzKG9iamVjdCkge1xuICAgICAgICAgICAgaWYgKGlzQXJndW1lbnRzKG9iamVjdCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3JpZ2luYWxLZXlzKGFycmF5U2xpY2Uob2JqZWN0KSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbEtleXMob2JqZWN0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0sICFrZXlzV29ya3NXaXRoQXJndW1lbnRzIHx8IGtleXNIYXNBcmd1bWVudHNMZW5ndGhCdWcpO1xuXG4gICAgLy9cbiAgICAvLyBEYXRlXG4gICAgLy8gPT09PVxuICAgIC8vXG5cbiAgICB2YXIgaGFzTmVnYXRpdmVNb250aFllYXJCdWcgPSBuZXcgRGF0ZSgtMzUwOTgyNzMyOTYwMDI5MikuZ2V0VVRDTW9udGgoKSAhPT0gMDtcbiAgICB2YXIgYU5lZ2F0aXZlVGVzdERhdGUgPSBuZXcgRGF0ZSgtMTUwOTg0MjI4OTYwMDI5Mik7XG4gICAgdmFyIGFQb3NpdGl2ZVRlc3REYXRlID0gbmV3IERhdGUoMTQ0OTY2MjQwMDAwMCk7XG4gICAgdmFyIGhhc1RvVVRDU3RyaW5nRm9ybWF0QnVnID0gYU5lZ2F0aXZlVGVzdERhdGUudG9VVENTdHJpbmcoKSAhPT0gJ01vbiwgMDEgSmFuIC00NTg3NSAxMTo1OTo1OSBHTVQnO1xuICAgIHZhciBoYXNUb0RhdGVTdHJpbmdGb3JtYXRCdWc7XG4gICAgdmFyIGhhc1RvU3RyaW5nRm9ybWF0QnVnO1xuICAgIHZhciB0aW1lWm9uZU9mZnNldCA9IGFOZWdhdGl2ZVRlc3REYXRlLmdldFRpbWV6b25lT2Zmc2V0KCk7XG4gICAgaWYgKHRpbWVab25lT2Zmc2V0IDwgLTcyMCkge1xuICAgICAgICBoYXNUb0RhdGVTdHJpbmdGb3JtYXRCdWcgPSBhTmVnYXRpdmVUZXN0RGF0ZS50b0RhdGVTdHJpbmcoKSAhPT0gJ1R1ZSBKYW4gMDIgLTQ1ODc1JztcbiAgICAgICAgaGFzVG9TdHJpbmdGb3JtYXRCdWcgPSAhKC9eVGh1IERlYyAxMCAyMDE1IFxcZFxcZDpcXGRcXGQ6XFxkXFxkIEdNVFstXFwrXVxcZFxcZFxcZFxcZCg/OiB8JCkvKS50ZXN0KGFQb3NpdGl2ZVRlc3REYXRlLnRvU3RyaW5nKCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGhhc1RvRGF0ZVN0cmluZ0Zvcm1hdEJ1ZyA9IGFOZWdhdGl2ZVRlc3REYXRlLnRvRGF0ZVN0cmluZygpICE9PSAnTW9uIEphbiAwMSAtNDU4NzUnO1xuICAgICAgICBoYXNUb1N0cmluZ0Zvcm1hdEJ1ZyA9ICEoL15XZWQgRGVjIDA5IDIwMTUgXFxkXFxkOlxcZFxcZDpcXGRcXGQgR01UWy1cXCtdXFxkXFxkXFxkXFxkKD86IHwkKS8pLnRlc3QoYVBvc2l0aXZlVGVzdERhdGUudG9TdHJpbmcoKSk7XG4gICAgfVxuXG4gICAgdmFyIG9yaWdpbmFsR2V0RnVsbFllYXIgPSBjYWxsLmJpbmQoRGF0ZS5wcm90b3R5cGUuZ2V0RnVsbFllYXIpO1xuICAgIHZhciBvcmlnaW5hbEdldE1vbnRoID0gY2FsbC5iaW5kKERhdGUucHJvdG90eXBlLmdldE1vbnRoKTtcbiAgICB2YXIgb3JpZ2luYWxHZXREYXRlID0gY2FsbC5iaW5kKERhdGUucHJvdG90eXBlLmdldERhdGUpO1xuICAgIHZhciBvcmlnaW5hbEdldFVUQ0Z1bGxZZWFyID0gY2FsbC5iaW5kKERhdGUucHJvdG90eXBlLmdldFVUQ0Z1bGxZZWFyKTtcbiAgICB2YXIgb3JpZ2luYWxHZXRVVENNb250aCA9IGNhbGwuYmluZChEYXRlLnByb3RvdHlwZS5nZXRVVENNb250aCk7XG4gICAgdmFyIG9yaWdpbmFsR2V0VVRDRGF0ZSA9IGNhbGwuYmluZChEYXRlLnByb3RvdHlwZS5nZXRVVENEYXRlKTtcbiAgICB2YXIgb3JpZ2luYWxHZXRVVENEYXkgPSBjYWxsLmJpbmQoRGF0ZS5wcm90b3R5cGUuZ2V0VVRDRGF5KTtcbiAgICB2YXIgb3JpZ2luYWxHZXRVVENIb3VycyA9IGNhbGwuYmluZChEYXRlLnByb3RvdHlwZS5nZXRVVENIb3Vycyk7XG4gICAgdmFyIG9yaWdpbmFsR2V0VVRDTWludXRlcyA9IGNhbGwuYmluZChEYXRlLnByb3RvdHlwZS5nZXRVVENNaW51dGVzKTtcbiAgICB2YXIgb3JpZ2luYWxHZXRVVENTZWNvbmRzID0gY2FsbC5iaW5kKERhdGUucHJvdG90eXBlLmdldFVUQ1NlY29uZHMpO1xuICAgIHZhciBvcmlnaW5hbEdldFVUQ01pbGxpc2Vjb25kcyA9IGNhbGwuYmluZChEYXRlLnByb3RvdHlwZS5nZXRVVENNaWxsaXNlY29uZHMpO1xuICAgIHZhciBkYXlOYW1lID0gWydTdW4nLCAnTW9uJywgJ1R1ZScsICdXZWQnLCAnVGh1JywgJ0ZyaScsICdTYXQnXTtcbiAgICB2YXIgbW9udGhOYW1lID0gWydKYW4nLCAnRmViJywgJ01hcicsICdBcHInLCAnTWF5JywgJ0p1bicsICdKdWwnLCAnQXVnJywgJ1NlcCcsICdPY3QnLCAnTm92JywgJ0RlYyddO1xuICAgIHZhciBkYXlzSW5Nb250aCA9IGZ1bmN0aW9uIGRheXNJbk1vbnRoKG1vbnRoLCB5ZWFyKSB7XG4gICAgICAgIHJldHVybiBvcmlnaW5hbEdldERhdGUobmV3IERhdGUoeWVhciwgbW9udGgsIDApKTtcbiAgICB9O1xuXG4gICAgZGVmaW5lUHJvcGVydGllcyhEYXRlLnByb3RvdHlwZSwge1xuICAgICAgICBnZXRGdWxsWWVhcjogZnVuY3Rpb24gZ2V0RnVsbFllYXIoKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMgfHwgISh0aGlzIGluc3RhbmNlb2YgRGF0ZSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd0aGlzIGlzIG5vdCBhIERhdGUgb2JqZWN0LicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHllYXIgPSBvcmlnaW5hbEdldEZ1bGxZZWFyKHRoaXMpO1xuICAgICAgICAgICAgaWYgKHllYXIgPCAwICYmIG9yaWdpbmFsR2V0TW9udGgodGhpcykgPiAxMSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB5ZWFyICsgMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB5ZWFyO1xuICAgICAgICB9LFxuICAgICAgICBnZXRNb250aDogZnVuY3Rpb24gZ2V0TW9udGgoKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMgfHwgISh0aGlzIGluc3RhbmNlb2YgRGF0ZSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd0aGlzIGlzIG5vdCBhIERhdGUgb2JqZWN0LicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHllYXIgPSBvcmlnaW5hbEdldEZ1bGxZZWFyKHRoaXMpO1xuICAgICAgICAgICAgdmFyIG1vbnRoID0gb3JpZ2luYWxHZXRNb250aCh0aGlzKTtcbiAgICAgICAgICAgIGlmICh5ZWFyIDwgMCAmJiBtb250aCA+IDExKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbW9udGg7XG4gICAgICAgIH0sXG4gICAgICAgIGdldERhdGU6IGZ1bmN0aW9uIGdldERhdGUoKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMgfHwgISh0aGlzIGluc3RhbmNlb2YgRGF0ZSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd0aGlzIGlzIG5vdCBhIERhdGUgb2JqZWN0LicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHllYXIgPSBvcmlnaW5hbEdldEZ1bGxZZWFyKHRoaXMpO1xuICAgICAgICAgICAgdmFyIG1vbnRoID0gb3JpZ2luYWxHZXRNb250aCh0aGlzKTtcbiAgICAgICAgICAgIHZhciBkYXRlID0gb3JpZ2luYWxHZXREYXRlKHRoaXMpO1xuICAgICAgICAgICAgaWYgKHllYXIgPCAwICYmIG1vbnRoID4gMTEpIHtcbiAgICAgICAgICAgICAgICBpZiAobW9udGggPT09IDEyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2YXIgZGF5cyA9IGRheXNJbk1vbnRoKDAsIHllYXIgKyAxKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gKGRheXMgLSBkYXRlKSArIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZGF0ZTtcbiAgICAgICAgfSxcbiAgICAgICAgZ2V0VVRDRnVsbFllYXI6IGZ1bmN0aW9uIGdldFVUQ0Z1bGxZZWFyKCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzIHx8ICEodGhpcyBpbnN0YW5jZW9mIERhdGUpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndGhpcyBpcyBub3QgYSBEYXRlIG9iamVjdC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciB5ZWFyID0gb3JpZ2luYWxHZXRVVENGdWxsWWVhcih0aGlzKTtcbiAgICAgICAgICAgIGlmICh5ZWFyIDwgMCAmJiBvcmlnaW5hbEdldFVUQ01vbnRoKHRoaXMpID4gMTEpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4geWVhciArIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4geWVhcjtcbiAgICAgICAgfSxcbiAgICAgICAgZ2V0VVRDTW9udGg6IGZ1bmN0aW9uIGdldFVUQ01vbnRoKCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzIHx8ICEodGhpcyBpbnN0YW5jZW9mIERhdGUpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndGhpcyBpcyBub3QgYSBEYXRlIG9iamVjdC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciB5ZWFyID0gb3JpZ2luYWxHZXRVVENGdWxsWWVhcih0aGlzKTtcbiAgICAgICAgICAgIHZhciBtb250aCA9IG9yaWdpbmFsR2V0VVRDTW9udGgodGhpcyk7XG4gICAgICAgICAgICBpZiAoeWVhciA8IDAgJiYgbW9udGggPiAxMSkge1xuICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG1vbnRoO1xuICAgICAgICB9LFxuICAgICAgICBnZXRVVENEYXRlOiBmdW5jdGlvbiBnZXRVVENEYXRlKCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzIHx8ICEodGhpcyBpbnN0YW5jZW9mIERhdGUpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndGhpcyBpcyBub3QgYSBEYXRlIG9iamVjdC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciB5ZWFyID0gb3JpZ2luYWxHZXRVVENGdWxsWWVhcih0aGlzKTtcbiAgICAgICAgICAgIHZhciBtb250aCA9IG9yaWdpbmFsR2V0VVRDTW9udGgodGhpcyk7XG4gICAgICAgICAgICB2YXIgZGF0ZSA9IG9yaWdpbmFsR2V0VVRDRGF0ZSh0aGlzKTtcbiAgICAgICAgICAgIGlmICh5ZWFyIDwgMCAmJiBtb250aCA+IDExKSB7XG4gICAgICAgICAgICAgICAgaWYgKG1vbnRoID09PSAxMikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFyIGRheXMgPSBkYXlzSW5Nb250aCgwLCB5ZWFyICsgMSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChkYXlzIC0gZGF0ZSkgKyAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGRhdGU7XG4gICAgICAgIH1cbiAgICB9LCBoYXNOZWdhdGl2ZU1vbnRoWWVhckJ1Zyk7XG5cbiAgICBkZWZpbmVQcm9wZXJ0aWVzKERhdGUucHJvdG90eXBlLCB7XG4gICAgICAgIHRvVVRDU3RyaW5nOiBmdW5jdGlvbiB0b1VUQ1N0cmluZygpIHtcbiAgICAgICAgICAgIGlmICghdGhpcyB8fCAhKHRoaXMgaW5zdGFuY2VvZiBEYXRlKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3RoaXMgaXMgbm90IGEgRGF0ZSBvYmplY3QuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgZGF5ID0gb3JpZ2luYWxHZXRVVENEYXkodGhpcyk7XG4gICAgICAgICAgICB2YXIgZGF0ZSA9IG9yaWdpbmFsR2V0VVRDRGF0ZSh0aGlzKTtcbiAgICAgICAgICAgIHZhciBtb250aCA9IG9yaWdpbmFsR2V0VVRDTW9udGgodGhpcyk7XG4gICAgICAgICAgICB2YXIgeWVhciA9IG9yaWdpbmFsR2V0VVRDRnVsbFllYXIodGhpcyk7XG4gICAgICAgICAgICB2YXIgaG91ciA9IG9yaWdpbmFsR2V0VVRDSG91cnModGhpcyk7XG4gICAgICAgICAgICB2YXIgbWludXRlID0gb3JpZ2luYWxHZXRVVENNaW51dGVzKHRoaXMpO1xuICAgICAgICAgICAgdmFyIHNlY29uZCA9IG9yaWdpbmFsR2V0VVRDU2Vjb25kcyh0aGlzKTtcbiAgICAgICAgICAgIHJldHVybiBkYXlOYW1lW2RheV0gKyAnLCAnICtcbiAgICAgICAgICAgICAgICAoZGF0ZSA8IDEwID8gJzAnICsgZGF0ZSA6IGRhdGUpICsgJyAnICtcbiAgICAgICAgICAgICAgICBtb250aE5hbWVbbW9udGhdICsgJyAnICtcbiAgICAgICAgICAgICAgICB5ZWFyICsgJyAnICtcbiAgICAgICAgICAgICAgICAoaG91ciA8IDEwID8gJzAnICsgaG91ciA6IGhvdXIpICsgJzonICtcbiAgICAgICAgICAgICAgICAobWludXRlIDwgMTAgPyAnMCcgKyBtaW51dGUgOiBtaW51dGUpICsgJzonICtcbiAgICAgICAgICAgICAgICAoc2Vjb25kIDwgMTAgPyAnMCcgKyBzZWNvbmQgOiBzZWNvbmQpICsgJyBHTVQnO1xuICAgICAgICB9XG4gICAgfSwgaGFzTmVnYXRpdmVNb250aFllYXJCdWcgfHwgaGFzVG9VVENTdHJpbmdGb3JtYXRCdWcpO1xuXG4gICAgLy8gT3BlcmEgMTIgaGFzIGAsYFxuICAgIGRlZmluZVByb3BlcnRpZXMoRGF0ZS5wcm90b3R5cGUsIHtcbiAgICAgICAgdG9EYXRlU3RyaW5nOiBmdW5jdGlvbiB0b0RhdGVTdHJpbmcoKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMgfHwgISh0aGlzIGluc3RhbmNlb2YgRGF0ZSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd0aGlzIGlzIG5vdCBhIERhdGUgb2JqZWN0LicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGRheSA9IHRoaXMuZ2V0RGF5KCk7XG4gICAgICAgICAgICB2YXIgZGF0ZSA9IHRoaXMuZ2V0RGF0ZSgpO1xuICAgICAgICAgICAgdmFyIG1vbnRoID0gdGhpcy5nZXRNb250aCgpO1xuICAgICAgICAgICAgdmFyIHllYXIgPSB0aGlzLmdldEZ1bGxZZWFyKCk7XG4gICAgICAgICAgICByZXR1cm4gZGF5TmFtZVtkYXldICsgJyAnICtcbiAgICAgICAgICAgICAgICBtb250aE5hbWVbbW9udGhdICsgJyAnICtcbiAgICAgICAgICAgICAgICAoZGF0ZSA8IDEwID8gJzAnICsgZGF0ZSA6IGRhdGUpICsgJyAnICtcbiAgICAgICAgICAgICAgICB5ZWFyO1xuICAgICAgICB9XG4gICAgfSwgaGFzTmVnYXRpdmVNb250aFllYXJCdWcgfHwgaGFzVG9EYXRlU3RyaW5nRm9ybWF0QnVnKTtcblxuICAgIC8vIGNhbid0IHVzZSBkZWZpbmVQcm9wZXJ0aWVzIGhlcmUgYmVjYXVzZSBvZiB0b1N0cmluZyBlbnVtZXJhdGlvbiBpc3N1ZSBpbiBJRSA8PSA4XG4gICAgaWYgKGhhc05lZ2F0aXZlTW9udGhZZWFyQnVnIHx8IGhhc1RvU3RyaW5nRm9ybWF0QnVnKSB7XG4gICAgICAgIERhdGUucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMgfHwgISh0aGlzIGluc3RhbmNlb2YgRGF0ZSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd0aGlzIGlzIG5vdCBhIERhdGUgb2JqZWN0LicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGRheSA9IHRoaXMuZ2V0RGF5KCk7XG4gICAgICAgICAgICB2YXIgZGF0ZSA9IHRoaXMuZ2V0RGF0ZSgpO1xuICAgICAgICAgICAgdmFyIG1vbnRoID0gdGhpcy5nZXRNb250aCgpO1xuICAgICAgICAgICAgdmFyIHllYXIgPSB0aGlzLmdldEZ1bGxZZWFyKCk7XG4gICAgICAgICAgICB2YXIgaG91ciA9IHRoaXMuZ2V0SG91cnMoKTtcbiAgICAgICAgICAgIHZhciBtaW51dGUgPSB0aGlzLmdldE1pbnV0ZXMoKTtcbiAgICAgICAgICAgIHZhciBzZWNvbmQgPSB0aGlzLmdldFNlY29uZHMoKTtcbiAgICAgICAgICAgIHZhciB0aW1lem9uZU9mZnNldCA9IHRoaXMuZ2V0VGltZXpvbmVPZmZzZXQoKTtcbiAgICAgICAgICAgIHZhciBob3Vyc09mZnNldCA9IE1hdGguZmxvb3IoTWF0aC5hYnModGltZXpvbmVPZmZzZXQpIC8gNjApO1xuICAgICAgICAgICAgdmFyIG1pbnV0ZXNPZmZzZXQgPSBNYXRoLmZsb29yKE1hdGguYWJzKHRpbWV6b25lT2Zmc2V0KSAlIDYwKTtcbiAgICAgICAgICAgIHJldHVybiBkYXlOYW1lW2RheV0gKyAnICcgK1xuICAgICAgICAgICAgICAgIG1vbnRoTmFtZVttb250aF0gKyAnICcgK1xuICAgICAgICAgICAgICAgIChkYXRlIDwgMTAgPyAnMCcgKyBkYXRlIDogZGF0ZSkgKyAnICcgK1xuICAgICAgICAgICAgICAgIHllYXIgKyAnICcgK1xuICAgICAgICAgICAgICAgIChob3VyIDwgMTAgPyAnMCcgKyBob3VyIDogaG91cikgKyAnOicgK1xuICAgICAgICAgICAgICAgIChtaW51dGUgPCAxMCA/ICcwJyArIG1pbnV0ZSA6IG1pbnV0ZSkgKyAnOicgK1xuICAgICAgICAgICAgICAgIChzZWNvbmQgPCAxMCA/ICcwJyArIHNlY29uZCA6IHNlY29uZCkgKyAnIEdNVCcgK1xuICAgICAgICAgICAgICAgICh0aW1lem9uZU9mZnNldCA+IDAgPyAnLScgOiAnKycpICtcbiAgICAgICAgICAgICAgICAoaG91cnNPZmZzZXQgPCAxMCA/ICcwJyArIGhvdXJzT2Zmc2V0IDogaG91cnNPZmZzZXQpICtcbiAgICAgICAgICAgICAgICAobWludXRlc09mZnNldCA8IDEwID8gJzAnICsgbWludXRlc09mZnNldCA6IG1pbnV0ZXNPZmZzZXQpO1xuICAgICAgICB9O1xuICAgICAgICBpZiAoc3VwcG9ydHNEZXNjcmlwdG9ycykge1xuICAgICAgICAgICAgJE9iamVjdC5kZWZpbmVQcm9wZXJ0eShEYXRlLnByb3RvdHlwZSwgJ3RvU3RyaW5nJywge1xuICAgICAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB3cml0YWJsZTogdHJ1ZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBFUzUgMTUuOS41LjQzXG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuOS41LjQzXG4gICAgLy8gVGhpcyBmdW5jdGlvbiByZXR1cm5zIGEgU3RyaW5nIHZhbHVlIHJlcHJlc2VudCB0aGUgaW5zdGFuY2UgaW4gdGltZVxuICAgIC8vIHJlcHJlc2VudGVkIGJ5IHRoaXMgRGF0ZSBvYmplY3QuIFRoZSBmb3JtYXQgb2YgdGhlIFN0cmluZyBpcyB0aGUgRGF0ZSBUaW1lXG4gICAgLy8gc3RyaW5nIGZvcm1hdCBkZWZpbmVkIGluIDE1LjkuMS4xNS4gQWxsIGZpZWxkcyBhcmUgcHJlc2VudCBpbiB0aGUgU3RyaW5nLlxuICAgIC8vIFRoZSB0aW1lIHpvbmUgaXMgYWx3YXlzIFVUQywgZGVub3RlZCBieSB0aGUgc3VmZml4IFouIElmIHRoZSB0aW1lIHZhbHVlIG9mXG4gICAgLy8gdGhpcyBvYmplY3QgaXMgbm90IGEgZmluaXRlIE51bWJlciBhIFJhbmdlRXJyb3IgZXhjZXB0aW9uIGlzIHRocm93bi5cbiAgICB2YXIgbmVnYXRpdmVEYXRlID0gLTYyMTk4NzU1MjAwMDAwO1xuICAgIHZhciBuZWdhdGl2ZVllYXJTdHJpbmcgPSAnLTAwMDAwMSc7XG4gICAgdmFyIGhhc05lZ2F0aXZlRGF0ZUJ1ZyA9IERhdGUucHJvdG90eXBlLnRvSVNPU3RyaW5nICYmIG5ldyBEYXRlKG5lZ2F0aXZlRGF0ZSkudG9JU09TdHJpbmcoKS5pbmRleE9mKG5lZ2F0aXZlWWVhclN0cmluZykgPT09IC0xO1xuICAgIHZhciBoYXNTYWZhcmk1MURhdGVCdWcgPSBEYXRlLnByb3RvdHlwZS50b0lTT1N0cmluZyAmJiBuZXcgRGF0ZSgtMSkudG9JU09TdHJpbmcoKSAhPT0gJzE5NjktMTItMzFUMjM6NTk6NTkuOTk5Wic7XG5cbiAgICB2YXIgZ2V0VGltZSA9IGNhbGwuYmluZChEYXRlLnByb3RvdHlwZS5nZXRUaW1lKTtcblxuICAgIGRlZmluZVByb3BlcnRpZXMoRGF0ZS5wcm90b3R5cGUsIHtcbiAgICAgICAgdG9JU09TdHJpbmc6IGZ1bmN0aW9uIHRvSVNPU3RyaW5nKCkge1xuICAgICAgICAgICAgaWYgKCFpc0Zpbml0ZSh0aGlzKSB8fCAhaXNGaW5pdGUoZ2V0VGltZSh0aGlzKSkpIHtcbiAgICAgICAgICAgICAgICAvLyBBZG9wZSBQaG90b3Nob3AgcmVxdWlyZXMgdGhlIHNlY29uZCBjaGVjay5cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignRGF0ZS5wcm90b3R5cGUudG9JU09TdHJpbmcgY2FsbGVkIG9uIG5vbi1maW5pdGUgdmFsdWUuJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciB5ZWFyID0gb3JpZ2luYWxHZXRVVENGdWxsWWVhcih0aGlzKTtcblxuICAgICAgICAgICAgdmFyIG1vbnRoID0gb3JpZ2luYWxHZXRVVENNb250aCh0aGlzKTtcbiAgICAgICAgICAgIC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vZXMtc2hpbXMvZXM1LXNoaW0vaXNzdWVzLzExMVxuICAgICAgICAgICAgeWVhciArPSBNYXRoLmZsb29yKG1vbnRoIC8gMTIpO1xuICAgICAgICAgICAgbW9udGggPSAobW9udGggJSAxMiArIDEyKSAlIDEyO1xuXG4gICAgICAgICAgICAvLyB0aGUgZGF0ZSB0aW1lIHN0cmluZyBmb3JtYXQgaXMgc3BlY2lmaWVkIGluIDE1LjkuMS4xNS5cbiAgICAgICAgICAgIHZhciByZXN1bHQgPSBbbW9udGggKyAxLCBvcmlnaW5hbEdldFVUQ0RhdGUodGhpcyksIG9yaWdpbmFsR2V0VVRDSG91cnModGhpcyksIG9yaWdpbmFsR2V0VVRDTWludXRlcyh0aGlzKSwgb3JpZ2luYWxHZXRVVENTZWNvbmRzKHRoaXMpXTtcbiAgICAgICAgICAgIHllYXIgPSAoXG4gICAgICAgICAgICAgICAgKHllYXIgPCAwID8gJy0nIDogKHllYXIgPiA5OTk5ID8gJysnIDogJycpKSArXG4gICAgICAgICAgICAgICAgc3RyU2xpY2UoJzAwMDAwJyArIE1hdGguYWJzKHllYXIpLCAoMCA8PSB5ZWFyICYmIHllYXIgPD0gOTk5OSkgPyAtNCA6IC02KVxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZXN1bHQubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAvLyBwYWQgbW9udGhzLCBkYXlzLCBob3VycywgbWludXRlcywgYW5kIHNlY29uZHMgdG8gaGF2ZSB0d28gZGlnaXRzLlxuICAgICAgICAgICAgICAgIHJlc3VsdFtpXSA9IHN0clNsaWNlKCcwMCcgKyByZXN1bHRbaV0sIC0yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHBhZCBtaWxsaXNlY29uZHMgdG8gaGF2ZSB0aHJlZSBkaWdpdHMuXG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIHllYXIgKyAnLScgKyBhcnJheVNsaWNlKHJlc3VsdCwgMCwgMikuam9pbignLScpICtcbiAgICAgICAgICAgICAgICAnVCcgKyBhcnJheVNsaWNlKHJlc3VsdCwgMikuam9pbignOicpICsgJy4nICtcbiAgICAgICAgICAgICAgICBzdHJTbGljZSgnMDAwJyArIG9yaWdpbmFsR2V0VVRDTWlsbGlzZWNvbmRzKHRoaXMpLCAtMykgKyAnWidcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9LCBoYXNOZWdhdGl2ZURhdGVCdWcgfHwgaGFzU2FmYXJpNTFEYXRlQnVnKTtcblxuICAgIC8vIEVTNSAxNS45LjUuNDRcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS45LjUuNDRcbiAgICAvLyBUaGlzIGZ1bmN0aW9uIHByb3ZpZGVzIGEgU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgRGF0ZSBvYmplY3QgZm9yIHVzZSBieVxuICAgIC8vIEpTT04uc3RyaW5naWZ5ICgxNS4xMi4zKS5cbiAgICB2YXIgZGF0ZVRvSlNPTklzU3VwcG9ydGVkID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBEYXRlLnByb3RvdHlwZS50b0pTT04gJiZcbiAgICAgICAgICAgICAgICBuZXcgRGF0ZShOYU4pLnRvSlNPTigpID09PSBudWxsICYmXG4gICAgICAgICAgICAgICAgbmV3IERhdGUobmVnYXRpdmVEYXRlKS50b0pTT04oKS5pbmRleE9mKG5lZ2F0aXZlWWVhclN0cmluZykgIT09IC0xICYmXG4gICAgICAgICAgICAgICAgRGF0ZS5wcm90b3R5cGUudG9KU09OLmNhbGwoeyAvLyBnZW5lcmljXG4gICAgICAgICAgICAgICAgICAgIHRvSVNPU3RyaW5nOiBmdW5jdGlvbiAoKSB7IHJldHVybiB0cnVlOyB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH0oKSk7XG4gICAgaWYgKCFkYXRlVG9KU09OSXNTdXBwb3J0ZWQpIHtcbiAgICAgICAgRGF0ZS5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKGtleSkge1xuICAgICAgICAgICAgLy8gV2hlbiB0aGUgdG9KU09OIG1ldGhvZCBpcyBjYWxsZWQgd2l0aCBhcmd1bWVudCBrZXksIHRoZSBmb2xsb3dpbmdcbiAgICAgICAgICAgIC8vIHN0ZXBzIGFyZSB0YWtlbjpcblxuICAgICAgICAgICAgLy8gMS4gIExldCBPIGJlIHRoZSByZXN1bHQgb2YgY2FsbGluZyBUb09iamVjdCwgZ2l2aW5nIGl0IHRoZSB0aGlzXG4gICAgICAgICAgICAvLyB2YWx1ZSBhcyBpdHMgYXJndW1lbnQuXG4gICAgICAgICAgICAvLyAyLiBMZXQgdHYgYmUgRVMuVG9QcmltaXRpdmUoTywgaGludCBOdW1iZXIpLlxuICAgICAgICAgICAgdmFyIE8gPSAkT2JqZWN0KHRoaXMpO1xuICAgICAgICAgICAgdmFyIHR2ID0gRVMuVG9QcmltaXRpdmUoTyk7XG4gICAgICAgICAgICAvLyAzLiBJZiB0diBpcyBhIE51bWJlciBhbmQgaXMgbm90IGZpbml0ZSwgcmV0dXJuIG51bGwuXG4gICAgICAgICAgICBpZiAodHlwZW9mIHR2ID09PSAnbnVtYmVyJyAmJiAhaXNGaW5pdGUodHYpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyA0LiBMZXQgdG9JU08gYmUgdGhlIHJlc3VsdCBvZiBjYWxsaW5nIHRoZSBbW0dldF1dIGludGVybmFsIG1ldGhvZCBvZlxuICAgICAgICAgICAgLy8gTyB3aXRoIGFyZ3VtZW50IFwidG9JU09TdHJpbmdcIi5cbiAgICAgICAgICAgIHZhciB0b0lTTyA9IE8udG9JU09TdHJpbmc7XG4gICAgICAgICAgICAvLyA1LiBJZiBJc0NhbGxhYmxlKHRvSVNPKSBpcyBmYWxzZSwgdGhyb3cgYSBUeXBlRXJyb3IgZXhjZXB0aW9uLlxuICAgICAgICAgICAgaWYgKCFpc0NhbGxhYmxlKHRvSVNPKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3RvSVNPU3RyaW5nIHByb3BlcnR5IGlzIG5vdCBjYWxsYWJsZScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gNi4gUmV0dXJuIHRoZSByZXN1bHQgb2YgY2FsbGluZyB0aGUgW1tDYWxsXV0gaW50ZXJuYWwgbWV0aG9kIG9mXG4gICAgICAgICAgICAvLyAgdG9JU08gd2l0aCBPIGFzIHRoZSB0aGlzIHZhbHVlIGFuZCBhbiBlbXB0eSBhcmd1bWVudCBsaXN0LlxuICAgICAgICAgICAgcmV0dXJuIHRvSVNPLmNhbGwoTyk7XG5cbiAgICAgICAgICAgIC8vIE5PVEUgMSBUaGUgYXJndW1lbnQgaXMgaWdub3JlZC5cblxuICAgICAgICAgICAgLy8gTk9URSAyIFRoZSB0b0pTT04gZnVuY3Rpb24gaXMgaW50ZW50aW9uYWxseSBnZW5lcmljOyBpdCBkb2VzIG5vdFxuICAgICAgICAgICAgLy8gcmVxdWlyZSB0aGF0IGl0cyB0aGlzIHZhbHVlIGJlIGEgRGF0ZSBvYmplY3QuIFRoZXJlZm9yZSwgaXQgY2FuIGJlXG4gICAgICAgICAgICAvLyB0cmFuc2ZlcnJlZCB0byBvdGhlciBraW5kcyBvZiBvYmplY3RzIGZvciB1c2UgYXMgYSBtZXRob2QuIEhvd2V2ZXIsXG4gICAgICAgICAgICAvLyBpdCBkb2VzIHJlcXVpcmUgdGhhdCBhbnkgc3VjaCBvYmplY3QgaGF2ZSBhIHRvSVNPU3RyaW5nIG1ldGhvZC4gQW5cbiAgICAgICAgICAgIC8vIG9iamVjdCBpcyBmcmVlIHRvIHVzZSB0aGUgYXJndW1lbnQga2V5IHRvIGZpbHRlciBpdHNcbiAgICAgICAgICAgIC8vIHN0cmluZ2lmaWNhdGlvbi5cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBFUzUgMTUuOS40LjJcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS45LjQuMlxuICAgIC8vIGJhc2VkIG9uIHdvcmsgc2hhcmVkIGJ5IERhbmllbCBGcmllc2VuIChkYW50bWFuKVxuICAgIC8vIGh0dHA6Ly9naXN0LmdpdGh1Yi5jb20vMzAzMjQ5XG4gICAgdmFyIHN1cHBvcnRzRXh0ZW5kZWRZZWFycyA9IERhdGUucGFyc2UoJyswMzM2NTgtMDktMjdUMDE6NDY6NDAuMDAwWicpID09PSAxZTE1O1xuICAgIHZhciBhY2NlcHRzSW52YWxpZERhdGVzID0gIWlzTmFOKERhdGUucGFyc2UoJzIwMTItMDQtMDRUMjQ6MDA6MDAuNTAwWicpKSB8fCAhaXNOYU4oRGF0ZS5wYXJzZSgnMjAxMi0xMS0zMVQyMzo1OTo1OS4wMDBaJykpIHx8ICFpc05hTihEYXRlLnBhcnNlKCcyMDEyLTEyLTMxVDIzOjU5OjYwLjAwMFonKSk7XG4gICAgdmFyIGRvZXNOb3RQYXJzZVkyS05ld1llYXIgPSBpc05hTihEYXRlLnBhcnNlKCcyMDAwLTAxLTAxVDAwOjAwOjAwLjAwMFonKSk7XG4gICAgaWYgKGRvZXNOb3RQYXJzZVkyS05ld1llYXIgfHwgYWNjZXB0c0ludmFsaWREYXRlcyB8fCAhc3VwcG9ydHNFeHRlbmRlZFllYXJzKSB7XG4gICAgICAgIC8vIFhYWCBnbG9iYWwgYXNzaWdubWVudCB3b24ndCB3b3JrIGluIGVtYmVkZGluZ3MgdGhhdCB1c2VcbiAgICAgICAgLy8gYW4gYWx0ZXJuYXRlIG9iamVjdCBmb3IgdGhlIGNvbnRleHQuXG4gICAgICAgIC8qIGdsb2JhbCBEYXRlOiB0cnVlICovXG4gICAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLXVuZGVmICovXG4gICAgICAgIHZhciBtYXhTYWZlVW5zaWduZWQzMkJpdCA9IE1hdGgucG93KDIsIDMxKSAtIDE7XG4gICAgICAgIHZhciBoYXNTYWZhcmlTaWduZWRJbnRCdWcgPSBpc0FjdHVhbE5hTihuZXcgRGF0ZSgxOTcwLCAwLCAxLCAwLCAwLCAwLCBtYXhTYWZlVW5zaWduZWQzMkJpdCArIDEpLmdldFRpbWUoKSk7XG4gICAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLWltcGxpY2l0LWdsb2JhbHMgKi9cbiAgICAgICAgRGF0ZSA9IChmdW5jdGlvbiAoTmF0aXZlRGF0ZSkge1xuICAgICAgICAvKiBlc2xpbnQtZW5hYmxlIG5vLWltcGxpY2l0LWdsb2JhbHMgKi9cbiAgICAgICAgLyogZXNsaW50LWVuYWJsZSBuby11bmRlZiAqL1xuICAgICAgICAgICAgLy8gRGF0ZS5sZW5ndGggPT09IDdcbiAgICAgICAgICAgIHZhciBEYXRlU2hpbSA9IGZ1bmN0aW9uIERhdGUoWSwgTSwgRCwgaCwgbSwgcywgbXMpIHtcbiAgICAgICAgICAgICAgICB2YXIgbGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICAgICAgICAgICAgICB2YXIgZGF0ZTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIE5hdGl2ZURhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNlY29uZHMgPSBzO1xuICAgICAgICAgICAgICAgICAgICB2YXIgbWlsbGlzID0gbXM7XG4gICAgICAgICAgICAgICAgICAgIGlmIChoYXNTYWZhcmlTaWduZWRJbnRCdWcgJiYgbGVuZ3RoID49IDcgJiYgbXMgPiBtYXhTYWZlVW5zaWduZWQzMkJpdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gd29yayBhcm91bmQgYSBTYWZhcmkgOC85IGJ1ZyB3aGVyZSBpdCB0cmVhdHMgdGhlIHNlY29uZHMgYXMgc2lnbmVkXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbXNUb1NoaWZ0ID0gTWF0aC5mbG9vcihtcyAvIG1heFNhZmVVbnNpZ25lZDMyQml0KSAqIG1heFNhZmVVbnNpZ25lZDMyQml0O1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNUb1NoaWZ0ID0gTWF0aC5mbG9vcihtc1RvU2hpZnQgLyAxZTMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2Vjb25kcyArPSBzVG9TaGlmdDtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1pbGxpcyAtPSBzVG9TaGlmdCAqIDFlMztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBkYXRlID0gbGVuZ3RoID09PSAxICYmICRTdHJpbmcoWSkgPT09IFkgPyAvLyBpc1N0cmluZyhZKVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2UgZXhwbGljaXRseSBwYXNzIGl0IHRocm91Z2ggcGFyc2U6XG4gICAgICAgICAgICAgICAgICAgICAgICBuZXcgTmF0aXZlRGF0ZShEYXRlU2hpbS5wYXJzZShZKSkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2UgaGF2ZSB0byBtYW51YWxseSBtYWtlIGNhbGxzIGRlcGVuZGluZyBvbiBhcmd1bWVudFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gbGVuZ3RoIGhlcmVcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCA+PSA3ID8gbmV3IE5hdGl2ZURhdGUoWSwgTSwgRCwgaCwgbSwgc2Vjb25kcywgbWlsbGlzKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGggPj0gNiA/IG5ldyBOYXRpdmVEYXRlKFksIE0sIEQsIGgsIG0sIHNlY29uZHMpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCA+PSA1ID8gbmV3IE5hdGl2ZURhdGUoWSwgTSwgRCwgaCwgbSkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoID49IDQgPyBuZXcgTmF0aXZlRGF0ZShZLCBNLCBELCBoKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGggPj0gMyA/IG5ldyBOYXRpdmVEYXRlKFksIE0sIEQpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCA+PSAyID8gbmV3IE5hdGl2ZURhdGUoWSwgTSkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoID49IDEgPyBuZXcgTmF0aXZlRGF0ZShZIGluc3RhbmNlb2YgTmF0aXZlRGF0ZSA/ICtZIDogWSkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgTmF0aXZlRGF0ZSgpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGRhdGUgPSBOYXRpdmVEYXRlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghaXNQcmltaXRpdmUoZGF0ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUHJldmVudCBtaXh1cHMgd2l0aCB1bmZpeGVkIERhdGUgb2JqZWN0XG4gICAgICAgICAgICAgICAgICAgIGRlZmluZVByb3BlcnRpZXMoZGF0ZSwgeyBjb25zdHJ1Y3RvcjogRGF0ZVNoaW0gfSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBkYXRlO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLy8gMTUuOS4xLjE1IERhdGUgVGltZSBTdHJpbmcgRm9ybWF0LlxuICAgICAgICAgICAgdmFyIGlzb0RhdGVFeHByZXNzaW9uID0gbmV3IFJlZ0V4cCgnXicgK1xuICAgICAgICAgICAgICAgICcoXFxcXGR7NH18WystXVxcXFxkezZ9KScgKyAvLyBmb3VyLWRpZ2l0IHllYXIgY2FwdHVyZSBvciBzaWduICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDYtZGlnaXQgZXh0ZW5kZWQgeWVhclxuICAgICAgICAgICAgICAgICcoPzotKFxcXFxkezJ9KScgKyAvLyBvcHRpb25hbCBtb250aCBjYXB0dXJlXG4gICAgICAgICAgICAgICAgJyg/Oi0oXFxcXGR7Mn0pJyArIC8vIG9wdGlvbmFsIGRheSBjYXB0dXJlXG4gICAgICAgICAgICAgICAgJyg/OicgKyAvLyBjYXB0dXJlIGhvdXJzOm1pbnV0ZXM6c2Vjb25kcy5taWxsaXNlY29uZHNcbiAgICAgICAgICAgICAgICAgICAgJ1QoXFxcXGR7Mn0pJyArIC8vIGhvdXJzIGNhcHR1cmVcbiAgICAgICAgICAgICAgICAgICAgJzooXFxcXGR7Mn0pJyArIC8vIG1pbnV0ZXMgY2FwdHVyZVxuICAgICAgICAgICAgICAgICAgICAnKD86JyArIC8vIG9wdGlvbmFsIDpzZWNvbmRzLm1pbGxpc2Vjb25kc1xuICAgICAgICAgICAgICAgICAgICAgICAgJzooXFxcXGR7Mn0pJyArIC8vIHNlY29uZHMgY2FwdHVyZVxuICAgICAgICAgICAgICAgICAgICAgICAgJyg/OihcXFxcLlxcXFxkezEsfSkpPycgKyAvLyBtaWxsaXNlY29uZHMgY2FwdHVyZVxuICAgICAgICAgICAgICAgICAgICAnKT8nICtcbiAgICAgICAgICAgICAgICAnKCcgKyAvLyBjYXB0dXJlIFVUQyBvZmZzZXQgY29tcG9uZW50XG4gICAgICAgICAgICAgICAgICAgICdafCcgKyAvLyBVVEMgY2FwdHVyZVxuICAgICAgICAgICAgICAgICAgICAnKD86JyArIC8vIG9mZnNldCBzcGVjaWZpZXIgKy8taG91cnM6bWludXRlc1xuICAgICAgICAgICAgICAgICAgICAgICAgJyhbLStdKScgKyAvLyBzaWduIGNhcHR1cmVcbiAgICAgICAgICAgICAgICAgICAgICAgICcoXFxcXGR7Mn0pJyArIC8vIGhvdXJzIG9mZnNldCBjYXB0dXJlXG4gICAgICAgICAgICAgICAgICAgICAgICAnOihcXFxcZHsyfSknICsgLy8gbWludXRlcyBvZmZzZXQgY2FwdHVyZVxuICAgICAgICAgICAgICAgICAgICAnKScgK1xuICAgICAgICAgICAgICAgICcpPyk/KT8pPycgK1xuICAgICAgICAgICAgJyQnKTtcblxuICAgICAgICAgICAgdmFyIG1vbnRocyA9IFswLCAzMSwgNTksIDkwLCAxMjAsIDE1MSwgMTgxLCAyMTIsIDI0MywgMjczLCAzMDQsIDMzNCwgMzY1XTtcblxuICAgICAgICAgICAgdmFyIGRheUZyb21Nb250aCA9IGZ1bmN0aW9uIGRheUZyb21Nb250aCh5ZWFyLCBtb250aCkge1xuICAgICAgICAgICAgICAgIHZhciB0ID0gbW9udGggPiAxID8gMSA6IDA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICAgICAgbW9udGhzW21vbnRoXSArXG4gICAgICAgICAgICAgICAgICAgIE1hdGguZmxvb3IoKHllYXIgLSAxOTY5ICsgdCkgLyA0KSAtXG4gICAgICAgICAgICAgICAgICAgIE1hdGguZmxvb3IoKHllYXIgLSAxOTAxICsgdCkgLyAxMDApICtcbiAgICAgICAgICAgICAgICAgICAgTWF0aC5mbG9vcigoeWVhciAtIDE2MDEgKyB0KSAvIDQwMCkgK1xuICAgICAgICAgICAgICAgICAgICAzNjUgKiAoeWVhciAtIDE5NzApXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHZhciB0b1VUQyA9IGZ1bmN0aW9uIHRvVVRDKHQpIHtcbiAgICAgICAgICAgICAgICB2YXIgcyA9IDA7XG4gICAgICAgICAgICAgICAgdmFyIG1zID0gdDtcbiAgICAgICAgICAgICAgICBpZiAoaGFzU2FmYXJpU2lnbmVkSW50QnVnICYmIG1zID4gbWF4U2FmZVVuc2lnbmVkMzJCaXQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gd29yayBhcm91bmQgYSBTYWZhcmkgOC85IGJ1ZyB3aGVyZSBpdCB0cmVhdHMgdGhlIHNlY29uZHMgYXMgc2lnbmVkXG4gICAgICAgICAgICAgICAgICAgIHZhciBtc1RvU2hpZnQgPSBNYXRoLmZsb29yKG1zIC8gbWF4U2FmZVVuc2lnbmVkMzJCaXQpICogbWF4U2FmZVVuc2lnbmVkMzJCaXQ7XG4gICAgICAgICAgICAgICAgICAgIHZhciBzVG9TaGlmdCA9IE1hdGguZmxvb3IobXNUb1NoaWZ0IC8gMWUzKTtcbiAgICAgICAgICAgICAgICAgICAgcyArPSBzVG9TaGlmdDtcbiAgICAgICAgICAgICAgICAgICAgbXMgLT0gc1RvU2hpZnQgKiAxZTM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiAkTnVtYmVyKG5ldyBOYXRpdmVEYXRlKDE5NzAsIDAsIDEsIDAsIDAsIHMsIG1zKSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvLyBDb3B5IGFueSBjdXN0b20gbWV0aG9kcyBhIDNyZCBwYXJ0eSBsaWJyYXJ5IG1heSBoYXZlIGFkZGVkXG4gICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gTmF0aXZlRGF0ZSkge1xuICAgICAgICAgICAgICAgIGlmIChvd25zKE5hdGl2ZURhdGUsIGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgRGF0ZVNoaW1ba2V5XSA9IE5hdGl2ZURhdGVba2V5XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENvcHkgXCJuYXRpdmVcIiBtZXRob2RzIGV4cGxpY2l0bHk7IHRoZXkgbWF5IGJlIG5vbi1lbnVtZXJhYmxlXG4gICAgICAgICAgICBkZWZpbmVQcm9wZXJ0aWVzKERhdGVTaGltLCB7XG4gICAgICAgICAgICAgICAgbm93OiBOYXRpdmVEYXRlLm5vdyxcbiAgICAgICAgICAgICAgICBVVEM6IE5hdGl2ZURhdGUuVVRDXG4gICAgICAgICAgICB9LCB0cnVlKTtcbiAgICAgICAgICAgIERhdGVTaGltLnByb3RvdHlwZSA9IE5hdGl2ZURhdGUucHJvdG90eXBlO1xuICAgICAgICAgICAgZGVmaW5lUHJvcGVydGllcyhEYXRlU2hpbS5wcm90b3R5cGUsIHtcbiAgICAgICAgICAgICAgICBjb25zdHJ1Y3RvcjogRGF0ZVNoaW1cbiAgICAgICAgICAgIH0sIHRydWUpO1xuXG4gICAgICAgICAgICAvLyBVcGdyYWRlIERhdGUucGFyc2UgdG8gaGFuZGxlIHNpbXBsaWZpZWQgSVNPIDg2MDEgc3RyaW5nc1xuICAgICAgICAgICAgdmFyIHBhcnNlU2hpbSA9IGZ1bmN0aW9uIHBhcnNlKHN0cmluZykge1xuICAgICAgICAgICAgICAgIHZhciBtYXRjaCA9IGlzb0RhdGVFeHByZXNzaW9uLmV4ZWMoc3RyaW5nKTtcbiAgICAgICAgICAgICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gcGFyc2UgbW9udGhzLCBkYXlzLCBob3VycywgbWludXRlcywgc2Vjb25kcywgYW5kIG1pbGxpc2Vjb25kc1xuICAgICAgICAgICAgICAgICAgICAvLyBwcm92aWRlIGRlZmF1bHQgdmFsdWVzIGlmIG5lY2Vzc2FyeVxuICAgICAgICAgICAgICAgICAgICAvLyBwYXJzZSB0aGUgVVRDIG9mZnNldCBjb21wb25lbnRcbiAgICAgICAgICAgICAgICAgICAgdmFyIHllYXIgPSAkTnVtYmVyKG1hdGNoWzFdKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1vbnRoID0gJE51bWJlcihtYXRjaFsyXSB8fCAxKSAtIDEsXG4gICAgICAgICAgICAgICAgICAgICAgICBkYXkgPSAkTnVtYmVyKG1hdGNoWzNdIHx8IDEpIC0gMSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGhvdXIgPSAkTnVtYmVyKG1hdGNoWzRdIHx8IDApLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWludXRlID0gJE51bWJlcihtYXRjaFs1XSB8fCAwKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlY29uZCA9ICROdW1iZXIobWF0Y2hbNl0gfHwgMCksXG4gICAgICAgICAgICAgICAgICAgICAgICBtaWxsaXNlY29uZCA9IE1hdGguZmxvb3IoJE51bWJlcihtYXRjaFs3XSB8fCAwKSAqIDEwMDApLFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2hlbiB0aW1lIHpvbmUgaXMgbWlzc2VkLCBsb2NhbCBvZmZzZXQgc2hvdWxkIGJlIHVzZWRcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIChFUyA1LjEgYnVnKVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2VlIGh0dHBzOi8vYnVncy5lY21hc2NyaXB0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTEyXG4gICAgICAgICAgICAgICAgICAgICAgICBpc0xvY2FsVGltZSA9IEJvb2xlYW4obWF0Y2hbNF0gJiYgIW1hdGNoWzhdKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpZ25PZmZzZXQgPSBtYXRjaFs5XSA9PT0gJy0nID8gMSA6IC0xLFxuICAgICAgICAgICAgICAgICAgICAgICAgaG91ck9mZnNldCA9ICROdW1iZXIobWF0Y2hbMTBdIHx8IDApLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWludXRlT2Zmc2V0ID0gJE51bWJlcihtYXRjaFsxMV0gfHwgMCksXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQ7XG4gICAgICAgICAgICAgICAgICAgIHZhciBoYXNNaW51dGVzT3JTZWNvbmRzT3JNaWxsaXNlY29uZHMgPSBtaW51dGUgPiAwIHx8IHNlY29uZCA+IDAgfHwgbWlsbGlzZWNvbmQgPiAwO1xuICAgICAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgICAgICBob3VyIDwgKGhhc01pbnV0ZXNPclNlY29uZHNPck1pbGxpc2Vjb25kcyA/IDI0IDogMjUpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBtaW51dGUgPCA2MCAmJiBzZWNvbmQgPCA2MCAmJiBtaWxsaXNlY29uZCA8IDEwMDAgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIG1vbnRoID4gLTEgJiYgbW9udGggPCAxMiAmJiBob3VyT2Zmc2V0IDwgMjQgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIG1pbnV0ZU9mZnNldCA8IDYwICYmIC8vIGRldGVjdCBpbnZhbGlkIG9mZnNldHNcbiAgICAgICAgICAgICAgICAgICAgICAgIGRheSA+IC0xICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBkYXkgPCAoZGF5RnJvbU1vbnRoKHllYXIsIG1vbnRoICsgMSkgLSBkYXlGcm9tTW9udGgoeWVhciwgbW9udGgpKVxuICAgICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZGF5RnJvbU1vbnRoKHllYXIsIG1vbnRoKSArIGRheSkgKiAyNCArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaG91ciArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaG91ck9mZnNldCAqIHNpZ25PZmZzZXRcbiAgICAgICAgICAgICAgICAgICAgICAgICkgKiA2MDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVzdWx0ICsgbWludXRlICsgbWludXRlT2Zmc2V0ICogc2lnbk9mZnNldCkgKiA2MCArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vjb25kXG4gICAgICAgICAgICAgICAgICAgICAgICApICogMTAwMCArIG1pbGxpc2Vjb25kO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzTG9jYWxUaW1lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gdG9VVEMocmVzdWx0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgtOC42NGUxNSA8PSByZXN1bHQgJiYgcmVzdWx0IDw9IDguNjRlMTUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOYU47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBOYXRpdmVEYXRlLnBhcnNlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgZGVmaW5lUHJvcGVydGllcyhEYXRlU2hpbSwgeyBwYXJzZTogcGFyc2VTaGltIH0pO1xuXG4gICAgICAgICAgICByZXR1cm4gRGF0ZVNoaW07XG4gICAgICAgIH0oRGF0ZSkpO1xuICAgICAgICAvKiBnbG9iYWwgRGF0ZTogZmFsc2UgKi9cbiAgICB9XG5cbiAgICAvLyBFUzUgMTUuOS40LjRcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS45LjQuNFxuICAgIGlmICghRGF0ZS5ub3cpIHtcbiAgICAgICAgRGF0ZS5ub3cgPSBmdW5jdGlvbiBub3coKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLy9cbiAgICAvLyBOdW1iZXJcbiAgICAvLyA9PT09PT1cbiAgICAvL1xuXG4gICAgLy8gRVM1LjEgMTUuNy40LjVcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS43LjQuNVxuICAgIHZhciBoYXNUb0ZpeGVkQnVncyA9IE51bWJlclByb3RvdHlwZS50b0ZpeGVkICYmIChcbiAgICAgICgwLjAwMDA4KS50b0ZpeGVkKDMpICE9PSAnMC4wMDAnIHx8XG4gICAgICAoMC45KS50b0ZpeGVkKDApICE9PSAnMScgfHxcbiAgICAgICgxLjI1NSkudG9GaXhlZCgyKSAhPT0gJzEuMjUnIHx8XG4gICAgICAoMTAwMDAwMDAwMDAwMDAwMDEyOCkudG9GaXhlZCgwKSAhPT0gJzEwMDAwMDAwMDAwMDAwMDAxMjgnXG4gICAgKTtcblxuICAgIHZhciB0b0ZpeGVkSGVscGVycyA9IHtcbiAgICAgICAgYmFzZTogMWU3LFxuICAgICAgICBzaXplOiA2LFxuICAgICAgICBkYXRhOiBbMCwgMCwgMCwgMCwgMCwgMF0sXG4gICAgICAgIG11bHRpcGx5OiBmdW5jdGlvbiBtdWx0aXBseShuLCBjKSB7XG4gICAgICAgICAgICB2YXIgaSA9IC0xO1xuICAgICAgICAgICAgdmFyIGMyID0gYztcbiAgICAgICAgICAgIHdoaWxlICgrK2kgPCB0b0ZpeGVkSGVscGVycy5zaXplKSB7XG4gICAgICAgICAgICAgICAgYzIgKz0gbiAqIHRvRml4ZWRIZWxwZXJzLmRhdGFbaV07XG4gICAgICAgICAgICAgICAgdG9GaXhlZEhlbHBlcnMuZGF0YVtpXSA9IGMyICUgdG9GaXhlZEhlbHBlcnMuYmFzZTtcbiAgICAgICAgICAgICAgICBjMiA9IE1hdGguZmxvb3IoYzIgLyB0b0ZpeGVkSGVscGVycy5iYXNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZGl2aWRlOiBmdW5jdGlvbiBkaXZpZGUobikge1xuICAgICAgICAgICAgdmFyIGkgPSB0b0ZpeGVkSGVscGVycy5zaXplO1xuICAgICAgICAgICAgdmFyIGMgPSAwO1xuICAgICAgICAgICAgd2hpbGUgKC0taSA+PSAwKSB7XG4gICAgICAgICAgICAgICAgYyArPSB0b0ZpeGVkSGVscGVycy5kYXRhW2ldO1xuICAgICAgICAgICAgICAgIHRvRml4ZWRIZWxwZXJzLmRhdGFbaV0gPSBNYXRoLmZsb29yKGMgLyBuKTtcbiAgICAgICAgICAgICAgICBjID0gKGMgJSBuKSAqIHRvRml4ZWRIZWxwZXJzLmJhc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIG51bVRvU3RyaW5nOiBmdW5jdGlvbiBudW1Ub1N0cmluZygpIHtcbiAgICAgICAgICAgIHZhciBpID0gdG9GaXhlZEhlbHBlcnMuc2l6ZTtcbiAgICAgICAgICAgIHZhciBzID0gJyc7XG4gICAgICAgICAgICB3aGlsZSAoLS1pID49IDApIHtcbiAgICAgICAgICAgICAgICBpZiAocyAhPT0gJycgfHwgaSA9PT0gMCB8fCB0b0ZpeGVkSGVscGVycy5kYXRhW2ldICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciB0ID0gJFN0cmluZyh0b0ZpeGVkSGVscGVycy5kYXRhW2ldKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHMgPT09ICcnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzID0gdDtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHMgKz0gc3RyU2xpY2UoJzAwMDAwMDAnLCAwLCA3IC0gdC5sZW5ndGgpICsgdDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzO1xuICAgICAgICB9LFxuICAgICAgICBwb3c6IGZ1bmN0aW9uIHBvdyh4LCBuLCBhY2MpIHtcbiAgICAgICAgICAgIHJldHVybiAobiA9PT0gMCA/IGFjYyA6IChuICUgMiA9PT0gMSA/IHBvdyh4LCBuIC0gMSwgYWNjICogeCkgOiBwb3coeCAqIHgsIG4gLyAyLCBhY2MpKSk7XG4gICAgICAgIH0sXG4gICAgICAgIGxvZzogZnVuY3Rpb24gbG9nKHgpIHtcbiAgICAgICAgICAgIHZhciBuID0gMDtcbiAgICAgICAgICAgIHZhciB4MiA9IHg7XG4gICAgICAgICAgICB3aGlsZSAoeDIgPj0gNDA5Nikge1xuICAgICAgICAgICAgICAgIG4gKz0gMTI7XG4gICAgICAgICAgICAgICAgeDIgLz0gNDA5NjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHdoaWxlICh4MiA+PSAyKSB7XG4gICAgICAgICAgICAgICAgbiArPSAxO1xuICAgICAgICAgICAgICAgIHgyIC89IDI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbjtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB2YXIgdG9GaXhlZFNoaW0gPSBmdW5jdGlvbiB0b0ZpeGVkKGZyYWN0aW9uRGlnaXRzKSB7XG4gICAgICAgIHZhciBmLCB4LCBzLCBtLCBlLCB6LCBqLCBrO1xuXG4gICAgICAgIC8vIFRlc3QgZm9yIE5hTiBhbmQgcm91bmQgZnJhY3Rpb25EaWdpdHMgZG93blxuICAgICAgICBmID0gJE51bWJlcihmcmFjdGlvbkRpZ2l0cyk7XG4gICAgICAgIGYgPSBpc0FjdHVhbE5hTihmKSA/IDAgOiBNYXRoLmZsb29yKGYpO1xuXG4gICAgICAgIGlmIChmIDwgMCB8fCBmID4gMjApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdOdW1iZXIudG9GaXhlZCBjYWxsZWQgd2l0aCBpbnZhbGlkIG51bWJlciBvZiBkZWNpbWFscycpO1xuICAgICAgICB9XG5cbiAgICAgICAgeCA9ICROdW1iZXIodGhpcyk7XG5cbiAgICAgICAgaWYgKGlzQWN0dWFsTmFOKHgpKSB7XG4gICAgICAgICAgICByZXR1cm4gJ05hTic7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiBpdCBpcyB0b28gYmlnIG9yIHNtYWxsLCByZXR1cm4gdGhlIHN0cmluZyB2YWx1ZSBvZiB0aGUgbnVtYmVyXG4gICAgICAgIGlmICh4IDw9IC0xZTIxIHx8IHggPj0gMWUyMSkge1xuICAgICAgICAgICAgcmV0dXJuICRTdHJpbmcoeCk7XG4gICAgICAgIH1cblxuICAgICAgICBzID0gJyc7XG5cbiAgICAgICAgaWYgKHggPCAwKSB7XG4gICAgICAgICAgICBzID0gJy0nO1xuICAgICAgICAgICAgeCA9IC14O1xuICAgICAgICB9XG5cbiAgICAgICAgbSA9ICcwJztcblxuICAgICAgICBpZiAoeCA+IDFlLTIxKSB7XG4gICAgICAgICAgICAvLyAxZS0yMSA8IHggPCAxZTIxXG4gICAgICAgICAgICAvLyAtNzAgPCBsb2cyKHgpIDwgNzBcbiAgICAgICAgICAgIGUgPSB0b0ZpeGVkSGVscGVycy5sb2coeCAqIHRvRml4ZWRIZWxwZXJzLnBvdygyLCA2OSwgMSkpIC0gNjk7XG4gICAgICAgICAgICB6ID0gKGUgPCAwID8geCAqIHRvRml4ZWRIZWxwZXJzLnBvdygyLCAtZSwgMSkgOiB4IC8gdG9GaXhlZEhlbHBlcnMucG93KDIsIGUsIDEpKTtcbiAgICAgICAgICAgIHogKj0gMHgxMDAwMDAwMDAwMDAwMDsgLy8gTWF0aC5wb3coMiwgNTIpO1xuICAgICAgICAgICAgZSA9IDUyIC0gZTtcblxuICAgICAgICAgICAgLy8gLTE4IDwgZSA8IDEyMlxuICAgICAgICAgICAgLy8geCA9IHogLyAyIF4gZVxuICAgICAgICAgICAgaWYgKGUgPiAwKSB7XG4gICAgICAgICAgICAgICAgdG9GaXhlZEhlbHBlcnMubXVsdGlwbHkoMCwgeik7XG4gICAgICAgICAgICAgICAgaiA9IGY7XG5cbiAgICAgICAgICAgICAgICB3aGlsZSAoaiA+PSA3KSB7XG4gICAgICAgICAgICAgICAgICAgIHRvRml4ZWRIZWxwZXJzLm11bHRpcGx5KDFlNywgMCk7XG4gICAgICAgICAgICAgICAgICAgIGogLT0gNztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0b0ZpeGVkSGVscGVycy5tdWx0aXBseSh0b0ZpeGVkSGVscGVycy5wb3coMTAsIGosIDEpLCAwKTtcbiAgICAgICAgICAgICAgICBqID0gZSAtIDE7XG5cbiAgICAgICAgICAgICAgICB3aGlsZSAoaiA+PSAyMykge1xuICAgICAgICAgICAgICAgICAgICB0b0ZpeGVkSGVscGVycy5kaXZpZGUoMSA8PCAyMyk7XG4gICAgICAgICAgICAgICAgICAgIGogLT0gMjM7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdG9GaXhlZEhlbHBlcnMuZGl2aWRlKDEgPDwgaik7XG4gICAgICAgICAgICAgICAgdG9GaXhlZEhlbHBlcnMubXVsdGlwbHkoMSwgMSk7XG4gICAgICAgICAgICAgICAgdG9GaXhlZEhlbHBlcnMuZGl2aWRlKDIpO1xuICAgICAgICAgICAgICAgIG0gPSB0b0ZpeGVkSGVscGVycy5udW1Ub1N0cmluZygpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0b0ZpeGVkSGVscGVycy5tdWx0aXBseSgwLCB6KTtcbiAgICAgICAgICAgICAgICB0b0ZpeGVkSGVscGVycy5tdWx0aXBseSgxIDw8ICgtZSksIDApO1xuICAgICAgICAgICAgICAgIG0gPSB0b0ZpeGVkSGVscGVycy5udW1Ub1N0cmluZygpICsgc3RyU2xpY2UoJzAuMDAwMDAwMDAwMDAwMDAwMDAwMDAnLCAyLCAyICsgZik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZiA+IDApIHtcbiAgICAgICAgICAgIGsgPSBtLmxlbmd0aDtcblxuICAgICAgICAgICAgaWYgKGsgPD0gZikge1xuICAgICAgICAgICAgICAgIG0gPSBzICsgc3RyU2xpY2UoJzAuMDAwMDAwMDAwMDAwMDAwMDAwMCcsIDAsIGYgLSBrICsgMikgKyBtO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBtID0gcyArIHN0clNsaWNlKG0sIDAsIGsgLSBmKSArICcuJyArIHN0clNsaWNlKG0sIGsgLSBmKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG0gPSBzICsgbTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBtO1xuICAgIH07XG4gICAgZGVmaW5lUHJvcGVydGllcyhOdW1iZXJQcm90b3R5cGUsIHsgdG9GaXhlZDogdG9GaXhlZFNoaW0gfSwgaGFzVG9GaXhlZEJ1Z3MpO1xuXG4gICAgdmFyIGhhc1RvUHJlY2lzaW9uVW5kZWZpbmVkQnVnID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiAxLjAudG9QcmVjaXNpb24odW5kZWZpbmVkKSA9PT0gJzEnO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH0oKSk7XG4gICAgdmFyIG9yaWdpbmFsVG9QcmVjaXNpb24gPSBOdW1iZXJQcm90b3R5cGUudG9QcmVjaXNpb247XG4gICAgZGVmaW5lUHJvcGVydGllcyhOdW1iZXJQcm90b3R5cGUsIHtcbiAgICAgICAgdG9QcmVjaXNpb246IGZ1bmN0aW9uIHRvUHJlY2lzaW9uKHByZWNpc2lvbikge1xuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiBwcmVjaXNpb24gPT09ICd1bmRlZmluZWQnID8gb3JpZ2luYWxUb1ByZWNpc2lvbi5jYWxsKHRoaXMpIDogb3JpZ2luYWxUb1ByZWNpc2lvbi5jYWxsKHRoaXMsIHByZWNpc2lvbik7XG4gICAgICAgIH1cbiAgICB9LCBoYXNUb1ByZWNpc2lvblVuZGVmaW5lZEJ1Zyk7XG5cbiAgICAvL1xuICAgIC8vIFN0cmluZ1xuICAgIC8vID09PT09PVxuICAgIC8vXG5cbiAgICAvLyBFUzUgMTUuNS40LjE0XG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuNS40LjE0XG5cbiAgICAvLyBbYnVnZml4LCBJRSBsdCA5LCBmaXJlZm94IDQsIEtvbnF1ZXJvciwgT3BlcmEsIG9ic2N1cmUgYnJvd3NlcnNdXG4gICAgLy8gTWFueSBicm93c2VycyBkbyBub3Qgc3BsaXQgcHJvcGVybHkgd2l0aCByZWd1bGFyIGV4cHJlc3Npb25zIG9yIHRoZXlcbiAgICAvLyBkbyBub3QgcGVyZm9ybSB0aGUgc3BsaXQgY29ycmVjdGx5IHVuZGVyIG9ic2N1cmUgY29uZGl0aW9ucy5cbiAgICAvLyBTZWUgaHR0cDovL2Jsb2cuc3RldmVubGV2aXRoYW4uY29tL2FyY2hpdmVzL2Nyb3NzLWJyb3dzZXItc3BsaXRcbiAgICAvLyBJJ3ZlIHRlc3RlZCBpbiBtYW55IGJyb3dzZXJzIGFuZCB0aGlzIHNlZW1zIHRvIGNvdmVyIHRoZSBkZXZpYW50IG9uZXM6XG4gICAgLy8gICAgJ2FiJy5zcGxpdCgvKD86YWIpKi8pIHNob3VsZCBiZSBbXCJcIiwgXCJcIl0sIG5vdCBbXCJcIl1cbiAgICAvLyAgICAnLicuc3BsaXQoLyguPykoLj8pLykgc2hvdWxkIGJlIFtcIlwiLCBcIi5cIiwgXCJcIiwgXCJcIl0sIG5vdCBbXCJcIiwgXCJcIl1cbiAgICAvLyAgICAndGVzc3QnLnNwbGl0KC8ocykqLykgc2hvdWxkIGJlIFtcInRcIiwgdW5kZWZpbmVkLCBcImVcIiwgXCJzXCIsIFwidFwiXSwgbm90XG4gICAgLy8gICAgICAgW3VuZGVmaW5lZCwgXCJ0XCIsIHVuZGVmaW5lZCwgXCJlXCIsIC4uLl1cbiAgICAvLyAgICAnJy5zcGxpdCgvLj8vKSBzaG91bGQgYmUgW10sIG5vdCBbXCJcIl1cbiAgICAvLyAgICAnLicuc3BsaXQoLygpKCkvKSBzaG91bGQgYmUgW1wiLlwiXSwgbm90IFtcIlwiLCBcIlwiLCBcIi5cIl1cblxuICAgIGlmIChcbiAgICAgICAgJ2FiJy5zcGxpdCgvKD86YWIpKi8pLmxlbmd0aCAhPT0gMiB8fFxuICAgICAgICAnLicuc3BsaXQoLyguPykoLj8pLykubGVuZ3RoICE9PSA0IHx8XG4gICAgICAgICd0ZXNzdCcuc3BsaXQoLyhzKSovKVsxXSA9PT0gJ3QnIHx8XG4gICAgICAgICd0ZXN0Jy5zcGxpdCgvKD86KS8sIC0xKS5sZW5ndGggIT09IDQgfHxcbiAgICAgICAgJycuc3BsaXQoLy4/LykubGVuZ3RoIHx8XG4gICAgICAgICcuJy5zcGxpdCgvKCkoKS8pLmxlbmd0aCA+IDFcbiAgICApIHtcbiAgICAgICAgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBjb21wbGlhbnRFeGVjTnBjZyA9IHR5cGVvZiAoLygpPz8vKS5leGVjKCcnKVsxXSA9PT0gJ3VuZGVmaW5lZCc7IC8vIE5QQ0c6IG5vbnBhcnRpY2lwYXRpbmcgY2FwdHVyaW5nIGdyb3VwXG4gICAgICAgICAgICB2YXIgbWF4U2FmZTMyQml0SW50ID0gTWF0aC5wb3coMiwgMzIpIC0gMTtcblxuICAgICAgICAgICAgU3RyaW5nUHJvdG90eXBlLnNwbGl0ID0gZnVuY3Rpb24gKHNlcGFyYXRvciwgbGltaXQpIHtcbiAgICAgICAgICAgICAgICB2YXIgc3RyaW5nID0gU3RyaW5nKHRoaXMpO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygc2VwYXJhdG9yID09PSAndW5kZWZpbmVkJyAmJiBsaW1pdCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gSWYgYHNlcGFyYXRvcmAgaXMgbm90IGEgcmVnZXgsIHVzZSBuYXRpdmUgc3BsaXRcbiAgICAgICAgICAgICAgICBpZiAoIWlzUmVnZXgoc2VwYXJhdG9yKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RyU3BsaXQodGhpcywgc2VwYXJhdG9yLCBsaW1pdCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdmFyIG91dHB1dCA9IFtdO1xuICAgICAgICAgICAgICAgIHZhciBmbGFncyA9IChzZXBhcmF0b3IuaWdub3JlQ2FzZSA/ICdpJyA6ICcnKSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKHNlcGFyYXRvci5tdWx0aWxpbmUgPyAnbScgOiAnJykgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzZXBhcmF0b3IudW5pY29kZSA/ICd1JyA6ICcnKSArIC8vIGluIEVTNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzZXBhcmF0b3Iuc3RpY2t5ID8gJ3knIDogJycpLCAvLyBGaXJlZm94IDMrIGFuZCBFUzZcbiAgICAgICAgICAgICAgICAgICAgbGFzdExhc3RJbmRleCA9IDAsXG4gICAgICAgICAgICAgICAgICAgIC8vIE1ha2UgYGdsb2JhbGAgYW5kIGF2b2lkIGBsYXN0SW5kZXhgIGlzc3VlcyBieSB3b3JraW5nIHdpdGggYSBjb3B5XG4gICAgICAgICAgICAgICAgICAgIHNlcGFyYXRvcjIsIG1hdGNoLCBsYXN0SW5kZXgsIGxhc3RMZW5ndGg7XG4gICAgICAgICAgICAgICAgdmFyIHNlcGFyYXRvckNvcHkgPSBuZXcgUmVnRXhwKHNlcGFyYXRvci5zb3VyY2UsIGZsYWdzICsgJ2cnKTtcbiAgICAgICAgICAgICAgICBpZiAoIWNvbXBsaWFudEV4ZWNOcGNnKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIERvZXNuJ3QgbmVlZCBmbGFncyBneSwgYnV0IHRoZXkgZG9uJ3QgaHVydFxuICAgICAgICAgICAgICAgICAgICBzZXBhcmF0b3IyID0gbmV3IFJlZ0V4cCgnXicgKyBzZXBhcmF0b3JDb3B5LnNvdXJjZSArICckKD8hXFxcXHMpJywgZmxhZ3MpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvKiBWYWx1ZXMgZm9yIGBsaW1pdGAsIHBlciB0aGUgc3BlYzpcbiAgICAgICAgICAgICAgICAgKiBJZiB1bmRlZmluZWQ6IDQyOTQ5NjcyOTUgLy8gbWF4U2FmZTMyQml0SW50XG4gICAgICAgICAgICAgICAgICogSWYgMCwgSW5maW5pdHksIG9yIE5hTjogMFxuICAgICAgICAgICAgICAgICAqIElmIHBvc2l0aXZlIG51bWJlcjogbGltaXQgPSBNYXRoLmZsb29yKGxpbWl0KTsgaWYgKGxpbWl0ID4gNDI5NDk2NzI5NSkgbGltaXQgLT0gNDI5NDk2NzI5NjtcbiAgICAgICAgICAgICAgICAgKiBJZiBuZWdhdGl2ZSBudW1iZXI6IDQyOTQ5NjcyOTYgLSBNYXRoLmZsb29yKE1hdGguYWJzKGxpbWl0KSlcbiAgICAgICAgICAgICAgICAgKiBJZiBvdGhlcjogVHlwZS1jb252ZXJ0LCB0aGVuIHVzZSB0aGUgYWJvdmUgcnVsZXNcbiAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICB2YXIgc3BsaXRMaW1pdCA9IHR5cGVvZiBsaW1pdCA9PT0gJ3VuZGVmaW5lZCcgPyBtYXhTYWZlMzJCaXRJbnQgOiBFUy5Ub1VpbnQzMihsaW1pdCk7XG4gICAgICAgICAgICAgICAgbWF0Y2ggPSBzZXBhcmF0b3JDb3B5LmV4ZWMoc3RyaW5nKTtcbiAgICAgICAgICAgICAgICB3aGlsZSAobWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gYHNlcGFyYXRvckNvcHkubGFzdEluZGV4YCBpcyBub3QgcmVsaWFibGUgY3Jvc3MtYnJvd3NlclxuICAgICAgICAgICAgICAgICAgICBsYXN0SW5kZXggPSBtYXRjaC5pbmRleCArIG1hdGNoWzBdLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxhc3RJbmRleCA+IGxhc3RMYXN0SW5kZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1c2hDYWxsKG91dHB1dCwgc3RyU2xpY2Uoc3RyaW5nLCBsYXN0TGFzdEluZGV4LCBtYXRjaC5pbmRleCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gRml4IGJyb3dzZXJzIHdob3NlIGBleGVjYCBtZXRob2RzIGRvbid0IGNvbnNpc3RlbnRseSByZXR1cm4gYHVuZGVmaW5lZGAgZm9yXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBub25wYXJ0aWNpcGF0aW5nIGNhcHR1cmluZyBncm91cHNcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY29tcGxpYW50RXhlY05wY2cgJiYgbWF0Y2gubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLWxvb3AtZnVuYyAqL1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoWzBdLnJlcGxhY2Uoc2VwYXJhdG9yMiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGggLSAyOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgYXJndW1lbnRzW2ldID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoW2ldID0gdm9pZCAwO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZXNsaW50LWVuYWJsZSBuby1sb29wLWZ1bmMgKi9cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtYXRjaC5sZW5ndGggPiAxICYmIG1hdGNoLmluZGV4IDwgc3RyaW5nLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5X3B1c2guYXBwbHkob3V0cHV0LCBhcnJheVNsaWNlKG1hdGNoLCAxKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBsYXN0TGVuZ3RoID0gbWF0Y2hbMF0ubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICAgICAgbGFzdExhc3RJbmRleCA9IGxhc3RJbmRleDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvdXRwdXQubGVuZ3RoID49IHNwbGl0TGltaXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VwYXJhdG9yQ29weS5sYXN0SW5kZXggPT09IG1hdGNoLmluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXBhcmF0b3JDb3B5Lmxhc3RJbmRleCsrOyAvLyBBdm9pZCBhbiBpbmZpbml0ZSBsb29wXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgbWF0Y2ggPSBzZXBhcmF0b3JDb3B5LmV4ZWMoc3RyaW5nKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGxhc3RMYXN0SW5kZXggPT09IHN0cmluZy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxhc3RMZW5ndGggfHwgIXNlcGFyYXRvckNvcHkudGVzdCgnJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1c2hDYWxsKG91dHB1dCwgJycpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcHVzaENhbGwob3V0cHV0LCBzdHJTbGljZShzdHJpbmcsIGxhc3RMYXN0SW5kZXgpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG91dHB1dC5sZW5ndGggPiBzcGxpdExpbWl0ID8gYXJyYXlTbGljZShvdXRwdXQsIDAsIHNwbGl0TGltaXQpIDogb3V0cHV0O1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSgpKTtcblxuICAgIC8vIFtidWdmaXgsIGNocm9tZV1cbiAgICAvLyBJZiBzZXBhcmF0b3IgaXMgdW5kZWZpbmVkLCB0aGVuIHRoZSByZXN1bHQgYXJyYXkgY29udGFpbnMganVzdCBvbmUgU3RyaW5nLFxuICAgIC8vIHdoaWNoIGlzIHRoZSB0aGlzIHZhbHVlIChjb252ZXJ0ZWQgdG8gYSBTdHJpbmcpLiBJZiBsaW1pdCBpcyBub3QgdW5kZWZpbmVkLFxuICAgIC8vIHRoZW4gdGhlIG91dHB1dCBhcnJheSBpcyB0cnVuY2F0ZWQgc28gdGhhdCBpdCBjb250YWlucyBubyBtb3JlIHRoYW4gbGltaXRcbiAgICAvLyBlbGVtZW50cy5cbiAgICAvLyBcIjBcIi5zcGxpdCh1bmRlZmluZWQsIDApIC0+IFtdXG4gICAgfSBlbHNlIGlmICgnMCcuc3BsaXQodm9pZCAwLCAwKS5sZW5ndGgpIHtcbiAgICAgICAgU3RyaW5nUHJvdG90eXBlLnNwbGl0ID0gZnVuY3Rpb24gc3BsaXQoc2VwYXJhdG9yLCBsaW1pdCkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBzZXBhcmF0b3IgPT09ICd1bmRlZmluZWQnICYmIGxpbWl0ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHN0clNwbGl0KHRoaXMsIHNlcGFyYXRvciwgbGltaXQpO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHZhciBzdHJfcmVwbGFjZSA9IFN0cmluZ1Byb3RvdHlwZS5yZXBsYWNlO1xuICAgIHZhciByZXBsYWNlUmVwb3J0c0dyb3Vwc0NvcnJlY3RseSA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBncm91cHMgPSBbXTtcbiAgICAgICAgJ3gnLnJlcGxhY2UoL3goLik/L2csIGZ1bmN0aW9uIChtYXRjaCwgZ3JvdXApIHtcbiAgICAgICAgICAgIHB1c2hDYWxsKGdyb3VwcywgZ3JvdXApO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGdyb3Vwcy5sZW5ndGggPT09IDEgJiYgdHlwZW9mIGdyb3Vwc1swXSA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgfSgpKTtcblxuICAgIGlmICghcmVwbGFjZVJlcG9ydHNHcm91cHNDb3JyZWN0bHkpIHtcbiAgICAgICAgU3RyaW5nUHJvdG90eXBlLnJlcGxhY2UgPSBmdW5jdGlvbiByZXBsYWNlKHNlYXJjaFZhbHVlLCByZXBsYWNlVmFsdWUpIHtcbiAgICAgICAgICAgIHZhciBpc0ZuID0gaXNDYWxsYWJsZShyZXBsYWNlVmFsdWUpO1xuICAgICAgICAgICAgdmFyIGhhc0NhcHR1cmluZ0dyb3VwcyA9IGlzUmVnZXgoc2VhcmNoVmFsdWUpICYmICgvXFwpWyo/XS8pLnRlc3Qoc2VhcmNoVmFsdWUuc291cmNlKTtcbiAgICAgICAgICAgIGlmICghaXNGbiB8fCAhaGFzQ2FwdHVyaW5nR3JvdXBzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHN0cl9yZXBsYWNlLmNhbGwodGhpcywgc2VhcmNoVmFsdWUsIHJlcGxhY2VWYWx1ZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciB3cmFwcGVkUmVwbGFjZVZhbHVlID0gZnVuY3Rpb24gKG1hdGNoKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICB2YXIgb3JpZ2luYWxMYXN0SW5kZXggPSBzZWFyY2hWYWx1ZS5sYXN0SW5kZXg7XG4gICAgICAgICAgICAgICAgICAgIHNlYXJjaFZhbHVlLmxhc3RJbmRleCA9IDA7XG4gICAgICAgICAgICAgICAgICAgIHZhciBhcmdzID0gc2VhcmNoVmFsdWUuZXhlYyhtYXRjaCkgfHwgW107XG4gICAgICAgICAgICAgICAgICAgIHNlYXJjaFZhbHVlLmxhc3RJbmRleCA9IG9yaWdpbmFsTGFzdEluZGV4O1xuICAgICAgICAgICAgICAgICAgICBwdXNoQ2FsbChhcmdzLCBhcmd1bWVudHNbbGVuZ3RoIC0gMl0sIGFyZ3VtZW50c1tsZW5ndGggLSAxXSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXBsYWNlVmFsdWUuYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICByZXR1cm4gc3RyX3JlcGxhY2UuY2FsbCh0aGlzLCBzZWFyY2hWYWx1ZSwgd3JhcHBlZFJlcGxhY2VWYWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gRUNNQS0yNjIsIDNyZCBCLjIuM1xuICAgIC8vIE5vdCBhbiBFQ01BU2NyaXB0IHN0YW5kYXJkLCBhbHRob3VnaCBFQ01BU2NyaXB0IDNyZCBFZGl0aW9uIGhhcyBhXG4gICAgLy8gbm9uLW5vcm1hdGl2ZSBzZWN0aW9uIHN1Z2dlc3RpbmcgdW5pZm9ybSBzZW1hbnRpY3MgYW5kIGl0IHNob3VsZCBiZVxuICAgIC8vIG5vcm1hbGl6ZWQgYWNyb3NzIGFsbCBicm93c2Vyc1xuICAgIC8vIFtidWdmaXgsIElFIGx0IDldIElFIDwgOSBzdWJzdHIoKSB3aXRoIG5lZ2F0aXZlIHZhbHVlIG5vdCB3b3JraW5nIGluIElFXG4gICAgdmFyIHN0cmluZ19zdWJzdHIgPSBTdHJpbmdQcm90b3R5cGUuc3Vic3RyO1xuICAgIHZhciBoYXNOZWdhdGl2ZVN1YnN0ckJ1ZyA9ICcnLnN1YnN0ciAmJiAnMGInLnN1YnN0cigtMSkgIT09ICdiJztcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKFN0cmluZ1Byb3RvdHlwZSwge1xuICAgICAgICBzdWJzdHI6IGZ1bmN0aW9uIHN1YnN0cihzdGFydCwgbGVuZ3RoKSB7XG4gICAgICAgICAgICB2YXIgbm9ybWFsaXplZFN0YXJ0ID0gc3RhcnQ7XG4gICAgICAgICAgICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgICAgICAgICAgICAgbm9ybWFsaXplZFN0YXJ0ID0gbWF4KHRoaXMubGVuZ3RoICsgc3RhcnQsIDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHN0cmluZ19zdWJzdHIuY2FsbCh0aGlzLCBub3JtYWxpemVkU3RhcnQsIGxlbmd0aCk7XG4gICAgICAgIH1cbiAgICB9LCBoYXNOZWdhdGl2ZVN1YnN0ckJ1Zyk7XG5cbiAgICAvLyBFUzUgMTUuNS40LjIwXG4gICAgLy8gd2hpdGVzcGFjZSBmcm9tOiBodHRwOi8vZXM1LmdpdGh1Yi5pby8jeDE1LjUuNC4yMFxuICAgIHZhciB3cyA9ICdcXHgwOVxceDBBXFx4MEJcXHgwQ1xceDBEXFx4MjBcXHhBMFxcdTE2ODBcXHUxODBFXFx1MjAwMFxcdTIwMDFcXHUyMDAyXFx1MjAwMycgK1xuICAgICAgICAnXFx1MjAwNFxcdTIwMDVcXHUyMDA2XFx1MjAwN1xcdTIwMDhcXHUyMDA5XFx1MjAwQVxcdTIwMkZcXHUyMDVGXFx1MzAwMFxcdTIwMjgnICtcbiAgICAgICAgJ1xcdTIwMjlcXHVGRUZGJztcbiAgICB2YXIgemVyb1dpZHRoID0gJ1xcdTIwMGInO1xuICAgIHZhciB3c1JlZ2V4Q2hhcnMgPSAnWycgKyB3cyArICddJztcbiAgICB2YXIgdHJpbUJlZ2luUmVnZXhwID0gbmV3IFJlZ0V4cCgnXicgKyB3c1JlZ2V4Q2hhcnMgKyB3c1JlZ2V4Q2hhcnMgKyAnKicpO1xuICAgIHZhciB0cmltRW5kUmVnZXhwID0gbmV3IFJlZ0V4cCh3c1JlZ2V4Q2hhcnMgKyB3c1JlZ2V4Q2hhcnMgKyAnKiQnKTtcbiAgICB2YXIgaGFzVHJpbVdoaXRlc3BhY2VCdWcgPSBTdHJpbmdQcm90b3R5cGUudHJpbSAmJiAod3MudHJpbSgpIHx8ICF6ZXJvV2lkdGgudHJpbSgpKTtcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKFN0cmluZ1Byb3RvdHlwZSwge1xuICAgICAgICAvLyBodHRwOi8vYmxvZy5zdGV2ZW5sZXZpdGhhbi5jb20vYXJjaGl2ZXMvZmFzdGVyLXRyaW0tamF2YXNjcmlwdFxuICAgICAgICAvLyBodHRwOi8vcGVyZmVjdGlvbmtpbGxzLmNvbS93aGl0ZXNwYWNlLWRldmlhdGlvbnMvXG4gICAgICAgIHRyaW06IGZ1bmN0aW9uIHRyaW0oKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHRoaXMgPT09ICd1bmRlZmluZWQnIHx8IHRoaXMgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiY2FuJ3QgY29udmVydCBcIiArIHRoaXMgKyAnIHRvIG9iamVjdCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuICRTdHJpbmcodGhpcykucmVwbGFjZSh0cmltQmVnaW5SZWdleHAsICcnKS5yZXBsYWNlKHRyaW1FbmRSZWdleHAsICcnKTtcbiAgICAgICAgfVxuICAgIH0sIGhhc1RyaW1XaGl0ZXNwYWNlQnVnKTtcbiAgICB2YXIgdHJpbSA9IGNhbGwuYmluZChTdHJpbmcucHJvdG90eXBlLnRyaW0pO1xuXG4gICAgdmFyIGhhc0xhc3RJbmRleEJ1ZyA9IFN0cmluZ1Byb3RvdHlwZS5sYXN0SW5kZXhPZiAmJiAnYWJj44GC44GEJy5sYXN0SW5kZXhPZign44GC44GEJywgMikgIT09IC0xO1xuICAgIGRlZmluZVByb3BlcnRpZXMoU3RyaW5nUHJvdG90eXBlLCB7XG4gICAgICAgIGxhc3RJbmRleE9mOiBmdW5jdGlvbiBsYXN0SW5kZXhPZihzZWFyY2hTdHJpbmcpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdGhpcyA9PT0gJ3VuZGVmaW5lZCcgfHwgdGhpcyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJjYW4ndCBjb252ZXJ0IFwiICsgdGhpcyArICcgdG8gb2JqZWN0Jyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgUyA9ICRTdHJpbmcodGhpcyk7XG4gICAgICAgICAgICB2YXIgc2VhcmNoU3RyID0gJFN0cmluZyhzZWFyY2hTdHJpbmcpO1xuICAgICAgICAgICAgdmFyIG51bVBvcyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxID8gJE51bWJlcihhcmd1bWVudHNbMV0pIDogTmFOO1xuICAgICAgICAgICAgdmFyIHBvcyA9IGlzQWN0dWFsTmFOKG51bVBvcykgPyBJbmZpbml0eSA6IEVTLlRvSW50ZWdlcihudW1Qb3MpO1xuICAgICAgICAgICAgdmFyIHN0YXJ0ID0gbWluKG1heChwb3MsIDApLCBTLmxlbmd0aCk7XG4gICAgICAgICAgICB2YXIgc2VhcmNoTGVuID0gc2VhcmNoU3RyLmxlbmd0aDtcbiAgICAgICAgICAgIHZhciBrID0gc3RhcnQgKyBzZWFyY2hMZW47XG4gICAgICAgICAgICB3aGlsZSAoayA+IDApIHtcbiAgICAgICAgICAgICAgICBrID0gbWF4KDAsIGsgLSBzZWFyY2hMZW4pO1xuICAgICAgICAgICAgICAgIHZhciBpbmRleCA9IHN0ckluZGV4T2Yoc3RyU2xpY2UoUywgaywgc3RhcnQgKyBzZWFyY2hMZW4pLCBzZWFyY2hTdHIpO1xuICAgICAgICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGsgKyBpbmRleDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH1cbiAgICB9LCBoYXNMYXN0SW5kZXhCdWcpO1xuXG4gICAgdmFyIG9yaWdpbmFsTGFzdEluZGV4T2YgPSBTdHJpbmdQcm90b3R5cGUubGFzdEluZGV4T2Y7XG4gICAgZGVmaW5lUHJvcGVydGllcyhTdHJpbmdQcm90b3R5cGUsIHtcbiAgICAgICAgbGFzdEluZGV4T2Y6IGZ1bmN0aW9uIGxhc3RJbmRleE9mKHNlYXJjaFN0cmluZykge1xuICAgICAgICAgICAgcmV0dXJuIG9yaWdpbmFsTGFzdEluZGV4T2YuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfVxuICAgIH0sIFN0cmluZ1Byb3RvdHlwZS5sYXN0SW5kZXhPZi5sZW5ndGggIT09IDEpO1xuXG4gICAgLy8gRVMtNSAxNS4xLjIuMlxuICAgIC8qIGVzbGludC1kaXNhYmxlIHJhZGl4ICovXG4gICAgaWYgKHBhcnNlSW50KHdzICsgJzA4JykgIT09IDggfHwgcGFyc2VJbnQod3MgKyAnMHgxNicpICE9PSAyMikge1xuICAgIC8qIGVzbGludC1lbmFibGUgcmFkaXggKi9cbiAgICAgICAgLyogZ2xvYmFsIHBhcnNlSW50OiB0cnVlICovXG4gICAgICAgIHBhcnNlSW50ID0gKGZ1bmN0aW9uIChvcmlnUGFyc2VJbnQpIHtcbiAgICAgICAgICAgIHZhciBoZXhSZWdleCA9IC9eW1xcLStdPzBbeFhdLztcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiBwYXJzZUludChzdHIsIHJhZGl4KSB7XG4gICAgICAgICAgICAgICAgdmFyIHN0cmluZyA9IHRyaW0oU3RyaW5nKHN0cikpO1xuICAgICAgICAgICAgICAgIHZhciBkZWZhdWx0ZWRSYWRpeCA9ICROdW1iZXIocmFkaXgpIHx8IChoZXhSZWdleC50ZXN0KHN0cmluZykgPyAxNiA6IDEwKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3JpZ1BhcnNlSW50KHN0cmluZywgZGVmYXVsdGVkUmFkaXgpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfShwYXJzZUludCkpO1xuICAgIH1cblxuICAgIC8vIGh0dHBzOi8vZXM1LmdpdGh1Yi5pby8jeDE1LjEuMi4zXG4gICAgaWYgKDEgLyBwYXJzZUZsb2F0KCctMCcpICE9PSAtSW5maW5pdHkpIHtcbiAgICAgICAgLyogZ2xvYmFsIHBhcnNlRmxvYXQ6IHRydWUgKi9cbiAgICAgICAgcGFyc2VGbG9hdCA9IChmdW5jdGlvbiAob3JpZ1BhcnNlRmxvYXQpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiBwYXJzZUZsb2F0KHN0cmluZykge1xuICAgICAgICAgICAgICAgIHZhciBpbnB1dFN0cmluZyA9IHRyaW0oU3RyaW5nKHN0cmluZykpO1xuICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSBvcmlnUGFyc2VGbG9hdChpbnB1dFN0cmluZyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCA9PT0gMCAmJiBzdHJTbGljZShpbnB1dFN0cmluZywgMCwgMSkgPT09ICctJyA/IC0wIDogcmVzdWx0O1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfShwYXJzZUZsb2F0KSk7XG4gICAgfVxuXG4gICAgaWYgKFN0cmluZyhuZXcgUmFuZ2VFcnJvcigndGVzdCcpKSAhPT0gJ1JhbmdlRXJyb3I6IHRlc3QnKSB7XG4gICAgICAgIHZhciBlcnJvclRvU3RyaW5nU2hpbSA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB0aGlzID09PSAndW5kZWZpbmVkJyB8fCB0aGlzID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImNhbid0IGNvbnZlcnQgXCIgKyB0aGlzICsgJyB0byBvYmplY3QnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBuYW1lID0gdGhpcy5uYW1lO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBuYW1lID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgIG5hbWUgPSAnRXJyb3InO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgbmFtZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICBuYW1lID0gJFN0cmluZyhuYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBtc2cgPSB0aGlzLm1lc3NhZ2U7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG1zZyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICBtc2cgPSAnJztcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIG1zZyAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICBtc2cgPSAkU3RyaW5nKG1zZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbXNnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFtc2cpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmFtZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBuYW1lICsgJzogJyArIG1zZztcbiAgICAgICAgfTtcbiAgICAgICAgLy8gY2FuJ3QgdXNlIGRlZmluZVByb3BlcnRpZXMgaGVyZSBiZWNhdXNlIG9mIHRvU3RyaW5nIGVudW1lcmF0aW9uIGlzc3VlIGluIElFIDw9IDhcbiAgICAgICAgRXJyb3IucHJvdG90eXBlLnRvU3RyaW5nID0gZXJyb3JUb1N0cmluZ1NoaW07XG4gICAgfVxuXG4gICAgaWYgKHN1cHBvcnRzRGVzY3JpcHRvcnMpIHtcbiAgICAgICAgdmFyIGVuc3VyZU5vbkVudW1lcmFibGUgPSBmdW5jdGlvbiAob2JqLCBwcm9wKSB7XG4gICAgICAgICAgICBpZiAoaXNFbnVtKG9iaiwgcHJvcCkpIHtcbiAgICAgICAgICAgICAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqLCBwcm9wKTtcbiAgICAgICAgICAgICAgICBpZiAoZGVzYy5jb25maWd1cmFibGUpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVzYy5lbnVtZXJhYmxlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIHByb3AsIGRlc2MpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgZW5zdXJlTm9uRW51bWVyYWJsZShFcnJvci5wcm90b3R5cGUsICdtZXNzYWdlJyk7XG4gICAgICAgIGlmIChFcnJvci5wcm90b3R5cGUubWVzc2FnZSAhPT0gJycpIHtcbiAgICAgICAgICAgIEVycm9yLnByb3RvdHlwZS5tZXNzYWdlID0gJyc7XG4gICAgICAgIH1cbiAgICAgICAgZW5zdXJlTm9uRW51bWVyYWJsZShFcnJvci5wcm90b3R5cGUsICduYW1lJyk7XG4gICAgfVxuXG4gICAgaWYgKFN0cmluZygvYS9taWcpICE9PSAnL2EvZ2ltJykge1xuICAgICAgICB2YXIgcmVnZXhUb1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgICAgICAgICAgdmFyIHN0ciA9ICcvJyArIHRoaXMuc291cmNlICsgJy8nO1xuICAgICAgICAgICAgaWYgKHRoaXMuZ2xvYmFsKSB7XG4gICAgICAgICAgICAgICAgc3RyICs9ICdnJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLmlnbm9yZUNhc2UpIHtcbiAgICAgICAgICAgICAgICBzdHIgKz0gJ2knO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMubXVsdGlsaW5lKSB7XG4gICAgICAgICAgICAgICAgc3RyICs9ICdtJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzdHI7XG4gICAgICAgIH07XG4gICAgICAgIC8vIGNhbid0IHVzZSBkZWZpbmVQcm9wZXJ0aWVzIGhlcmUgYmVjYXVzZSBvZiB0b1N0cmluZyBlbnVtZXJhdGlvbiBpc3N1ZSBpbiBJRSA8PSA4XG4gICAgICAgIFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcgPSByZWdleFRvU3RyaW5nO1xuICAgIH1cbn0pKTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8qanNsaW50IGVxZXE6IHRydWUqL1xuXG5IYW5kbGViYXJzLnJlZ2lzdGVySGVscGVyKCdzYW5pdGl6ZScsIGZ1bmN0aW9uICh0ZXh0KSB7XG4gICAgdmFyIHJlc3VsdDtcblxuICAgIGlmICh0ZXh0ID09PSB1bmRlZmluZWQpIHsgcmV0dXJuICcnOyB9XG5cbiAgICByZXN1bHQgPSBzYW5pdGl6ZUh0bWwodGV4dCwge1xuICAgICAgICBhbGxvd2VkVGFnczogWyAnZGl2JywgJ3NwYW4nLCAnYicsICdpJywgJ2VtJywgJ3N0cm9uZycsICdhJywgJ2JyJywgJ3RhYmxlJywgJ3Rib2R5JywgJ3RyJywgJ3RoJywgJ3RkJyBdLFxuICAgICAgICBhbGxvd2VkQXR0cmlidXRlczoge1xuICAgICAgICAgICAgJ2Rpdic6IFsgJ2NsYXNzJyBdLFxuICAgICAgICAgICAgJ3NwYW4nOiBbICdjbGFzcycgXSxcbiAgICAgICAgICAgICd0YWJsZSc6IFsgJ2NsYXNzJyBdLFxuICAgICAgICAgICAgJ3RkJzogWyAnY2xhc3MnIF0sXG4gICAgICAgICAgICAndGgnOiBbICdjb2xzcGFuJyBdLFxuICAgICAgICAgICAgJ2EnOiBbICdocmVmJyBdXG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiBuZXcgSGFuZGxlYmFycy5TYWZlU3RyaW5nKHJlc3VsdCk7XG59KTtcblxuSGFuZGxlYmFycy5yZWdpc3RlckhlbHBlcigncmVuZGVyVGV4dFBhcmFtJywgZnVuY3Rpb24ocGFyYW0pIHtcbiAgICB2YXIgcmVzdWx0LCB0eXBlID0gJ3RleHQnLCBpZEF0dCA9ICcnO1xuICAgIHZhciBwYXJhbVR5cGUgPSBwYXJhbS50eXBlIHx8IHBhcmFtLnNjaGVtYSAmJiBwYXJhbS5zY2hlbWEudHlwZSB8fCAnJztcbiAgICB2YXIgaXNBcnJheSA9IHBhcmFtVHlwZS50b0xvd2VyQ2FzZSgpID09PSAnYXJyYXknIHx8IHBhcmFtLmFsbG93TXVsdGlwbGU7XG4gICAgdmFyIGRlZmF1bHRWYWx1ZSA9IGlzQXJyYXkgJiYgQXJyYXkuaXNBcnJheShwYXJhbS5kZWZhdWx0KSA/IHBhcmFtLmRlZmF1bHQuam9pbignXFxuJykgOiBwYXJhbS5kZWZhdWx0O1xuICAgIHZhciBuYW1lID0gSGFuZGxlYmFycy5VdGlscy5lc2NhcGVFeHByZXNzaW9uKHBhcmFtLm5hbWUpO1xuICAgIHZhciB2YWx1ZUlkID0gSGFuZGxlYmFycy5VdGlscy5lc2NhcGVFeHByZXNzaW9uKHBhcmFtLnZhbHVlSWQpO1xuICAgIHBhcmFtVHlwZSA9IEhhbmRsZWJhcnMuVXRpbHMuZXNjYXBlRXhwcmVzc2lvbihwYXJhbVR5cGUpO1xuXG4gICAgdmFyIGRhdGFWZW5kb3JFeHRlbnNpb25zID0gT2JqZWN0LmtleXMocGFyYW0pLmZpbHRlcihmdW5jdGlvbihwcm9wZXJ0eSkge1xuICAgICAgICAvLyBmaWx0ZXIgWC1kYXRhLSBwcm9wZXJ0aWVzXG4gICAgICAgIHJldHVybiBwcm9wZXJ0eS5tYXRjaCgvXlgtZGF0YS0vaSkgIT09IG51bGw7XG4gICAgfSkucmVkdWNlKGZ1bmN0aW9uKHJlc3VsdCwgcHJvcGVydHkpIHtcbiAgICAgICAgLy8gcmVtb3ZlIFgtIGZyb20gcHJvcGVydHkgbmFtZSwgc28gaXQgcmVzdWx0cyBpbiBodG1sIGF0dHJpYnV0ZXMgbGlrZSBkYXRhLWZvbz0nYmFyJ1xuICAgICAgICByZXR1cm4gcmVzdWx0ICs9ICcgJyArIHByb3BlcnR5LnN1YnN0cmluZygyLCBwcm9wZXJ0eS5sZW5ndGgpICsgJz1cXCcnICsgcGFyYW1bcHJvcGVydHldICsgJ1xcJyc7XG4gICAgfSwgJycpO1xuXG4gICAgaWYocGFyYW0uZm9ybWF0ICYmIHBhcmFtLmZvcm1hdCA9PT0gJ3Bhc3N3b3JkJykge1xuICAgICAgICB0eXBlID0gJ3Bhc3N3b3JkJztcbiAgICB9XG5cbiAgICBpZih2YWx1ZUlkKSB7XG4gICAgICAgIGlkQXR0ID0gJyBpZD1cXCcnICsgdmFsdWVJZCArICdcXCcnO1xuICAgIH1cblxuICAgIGlmIChkZWZhdWx0VmFsdWUpIHtcbiAgICAgIGRlZmF1bHRWYWx1ZSA9IHNhbml0aXplSHRtbChkZWZhdWx0VmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWZhdWx0VmFsdWUgPSAnJztcbiAgICB9XG5cbiAgICBpZihpc0FycmF5KSB7XG4gICAgICAgIHJlc3VsdCA9ICc8dGV4dGFyZWEgY2xhc3M9XFwnYm9keS10ZXh0YXJlYScgKyAocGFyYW0ucmVxdWlyZWQgPyAnIHJlcXVpcmVkJyA6ICcnKSArICdcXCcgbmFtZT1cXCcnICsgbmFtZSArICdcXCcnICsgaWRBdHQgKyBkYXRhVmVuZG9yRXh0ZW5zaW9ucztcbiAgICAgICAgcmVzdWx0ICs9ICcgcGxhY2Vob2xkZXI9XFwnUHJvdmlkZSBtdWx0aXBsZSB2YWx1ZXMgaW4gbmV3IGxpbmVzJyArIChwYXJhbS5yZXF1aXJlZCA/ICcgKGF0IGxlYXN0IG9uZSByZXF1aXJlZCkuJyA6ICcuJykgKyAnXFwnPic7XG4gICAgICAgIHJlc3VsdCArPSBkZWZhdWx0VmFsdWUgKyAnPC90ZXh0YXJlYT4nO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBwYXJhbWV0ZXJDbGFzcyA9ICdwYXJhbWV0ZXInO1xuICAgICAgICBpZihwYXJhbS5yZXF1aXJlZCkge1xuICAgICAgICAgIHBhcmFtZXRlckNsYXNzICs9ICcgcmVxdWlyZWQnO1xuICAgICAgICB9XG4gICAgICAgIHJlc3VsdCA9ICc8aW5wdXQgY2xhc3M9XFwnJyArIHBhcmFtZXRlckNsYXNzICsgJ1xcJyBtaW5sZW5ndGg9XFwnJyArIChwYXJhbS5yZXF1aXJlZCA/IDEgOiAwKSArICdcXCcnO1xuICAgICAgICByZXN1bHQgKz0gJyBuYW1lPVxcJycgKyBuYW1lICsnXFwnIHBsYWNlaG9sZGVyPVxcJycgKyAocGFyYW0ucmVxdWlyZWQgPyAnKHJlcXVpcmVkKScgOiAnJykgKyAnXFwnJyArIGlkQXR0ICsgZGF0YVZlbmRvckV4dGVuc2lvbnM7XG4gICAgICAgIHJlc3VsdCArPSAnIHR5cGU9XFwnJyArIHR5cGUgKyAnXFwnIHZhbHVlPVxcJycgKyBkZWZhdWx0VmFsdWUgKyAnXFwnLz4nO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IEhhbmRsZWJhcnMuU2FmZVN0cmluZyhyZXN1bHQpO1xufSk7XG5cbkhhbmRsZWJhcnMucmVnaXN0ZXJIZWxwZXIoJ2lmQ29uZCcsIGZ1bmN0aW9uICh2MSwgb3BlcmF0b3IsIHYyLCBvcHRpb25zKSB7XG5cbiAgICBzd2l0Y2ggKG9wZXJhdG9yKSB7XG4gICAgICAgIGNhc2UgJz09JzpcbiAgICAgICAgICAgIHJldHVybiAodjEgPT0gdjIpID8gb3B0aW9ucy5mbih0aGlzKSA6IG9wdGlvbnMuaW52ZXJzZSh0aGlzKTtcbiAgICAgICAgY2FzZSAnPT09JzpcbiAgICAgICAgICAgIHJldHVybiAodjEgPT09IHYyKSA/IG9wdGlvbnMuZm4odGhpcykgOiBvcHRpb25zLmludmVyc2UodGhpcyk7XG4gICAgICAgIGNhc2UgJzwnOlxuICAgICAgICAgICAgcmV0dXJuICh2MSA8IHYyKSA/IG9wdGlvbnMuZm4odGhpcykgOiBvcHRpb25zLmludmVyc2UodGhpcyk7XG4gICAgICAgIGNhc2UgJzw9JzpcbiAgICAgICAgICAgIHJldHVybiAodjEgPD0gdjIpID8gb3B0aW9ucy5mbih0aGlzKSA6IG9wdGlvbnMuaW52ZXJzZSh0aGlzKTtcbiAgICAgICAgY2FzZSAnPic6XG4gICAgICAgICAgICByZXR1cm4gKHYxID4gdjIpID8gb3B0aW9ucy5mbih0aGlzKSA6IG9wdGlvbnMuaW52ZXJzZSh0aGlzKTtcbiAgICAgICAgY2FzZSAnPj0nOlxuICAgICAgICAgICAgcmV0dXJuICh2MSA+PSB2MikgPyBvcHRpb25zLmZuKHRoaXMpIDogb3B0aW9ucy5pbnZlcnNlKHRoaXMpO1xuICAgICAgICBjYXNlICcmJic6XG4gICAgICAgICAgICByZXR1cm4gKHYxICYmIHYyKSA/IG9wdGlvbnMuZm4odGhpcykgOiBvcHRpb25zLmludmVyc2UodGhpcyk7XG4gICAgICAgIGNhc2UgJ3x8JzpcbiAgICAgICAgICAgIHJldHVybiAodjEgfHwgdjIpID8gb3B0aW9ucy5mbih0aGlzKSA6IG9wdGlvbnMuaW52ZXJzZSh0aGlzKTtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJldHVybiBvcHRpb25zLmludmVyc2UodGhpcyk7XG4gICAgfVxufSk7XG5cbkhhbmRsZWJhcnMucmVnaXN0ZXJIZWxwZXIoJ2VzY2FwZScsIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHZhciB0ZXh0ID0gSGFuZGxlYmFycy5VdGlscy5lc2NhcGVFeHByZXNzaW9uKHZhbHVlKTtcblxuICAgIHJldHVybiBuZXcgSGFuZGxlYmFycy5TYWZlU3RyaW5nKHRleHQpO1xufSk7XG4iLCIoZnVuY3Rpb24oZil7aWYodHlwZW9mIGV4cG9ydHM9PT1cIm9iamVjdFwiJiZ0eXBlb2YgbW9kdWxlIT09XCJ1bmRlZmluZWRcIil7bW9kdWxlLmV4cG9ydHM9ZigpfWVsc2UgaWYodHlwZW9mIGRlZmluZT09PVwiZnVuY3Rpb25cIiYmZGVmaW5lLmFtZCl7ZGVmaW5lKFtdLGYpfWVsc2V7dmFyIGc7aWYodHlwZW9mIHdpbmRvdyE9PVwidW5kZWZpbmVkXCIpe2c9d2luZG93fWVsc2UgaWYodHlwZW9mIGdsb2JhbCE9PVwidW5kZWZpbmVkXCIpe2c9Z2xvYmFsfWVsc2UgaWYodHlwZW9mIHNlbGYhPT1cInVuZGVmaW5lZFwiKXtnPXNlbGZ9ZWxzZXtnPXRoaXN9Zy5zYW5pdGl6ZUh0bWw9ZigpfX0pKGZ1bmN0aW9uKCl7dmFyIGRlZmluZSxtb2R1bGUsZXhwb3J0cztyZXR1cm4gZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KHsxOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgaHRtbHBhcnNlcj1yZXF1aXJlKFwiaHRtbHBhcnNlcjJcIik7dmFyIGV4dGVuZD1yZXF1aXJlKFwieHRlbmRcIik7dmFyIHF1b3RlUmVnZXhwPXJlcXVpcmUoXCJyZWdleHAtcXVvdGVcIik7ZnVuY3Rpb24gZWFjaChvYmosY2Ipe2lmKG9iailPYmplY3Qua2V5cyhvYmopLmZvckVhY2goZnVuY3Rpb24oa2V5KXtjYihvYmpba2V5XSxrZXkpfSl9ZnVuY3Rpb24gaGFzKG9iaixrZXkpe3JldHVybnt9Lmhhc093blByb3BlcnR5LmNhbGwob2JqLGtleSl9bW9kdWxlLmV4cG9ydHM9c2FuaXRpemVIdG1sO2Z1bmN0aW9uIHNhbml0aXplSHRtbChodG1sLG9wdGlvbnMsX3JlY3Vyc2luZyl7dmFyIHJlc3VsdD1cIlwiO2Z1bmN0aW9uIEZyYW1lKHRhZyxhdHRyaWJzKXt2YXIgdGhhdD10aGlzO3RoaXMudGFnPXRhZzt0aGlzLmF0dHJpYnM9YXR0cmlic3x8e307dGhpcy50YWdQb3NpdGlvbj1yZXN1bHQubGVuZ3RoO3RoaXMudGV4dD1cIlwiO3RoaXMudXBkYXRlUGFyZW50Tm9kZVRleHQ9ZnVuY3Rpb24oKXtpZihzdGFjay5sZW5ndGgpe3ZhciBwYXJlbnRGcmFtZT1zdGFja1tzdGFjay5sZW5ndGgtMV07cGFyZW50RnJhbWUudGV4dCs9dGhhdC50ZXh0fX19aWYoIW9wdGlvbnMpe29wdGlvbnM9c2FuaXRpemVIdG1sLmRlZmF1bHRzO29wdGlvbnMucGFyc2VyPWh0bWxQYXJzZXJEZWZhdWx0c31lbHNle29wdGlvbnM9ZXh0ZW5kKHNhbml0aXplSHRtbC5kZWZhdWx0cyxvcHRpb25zKTtpZihvcHRpb25zLnBhcnNlcil7b3B0aW9ucy5wYXJzZXI9ZXh0ZW5kKGh0bWxQYXJzZXJEZWZhdWx0cyxvcHRpb25zLnBhcnNlcil9ZWxzZXtvcHRpb25zLnBhcnNlcj1odG1sUGFyc2VyRGVmYXVsdHN9fXZhciBub25UZXh0VGFnc0FycmF5PW9wdGlvbnMubm9uVGV4dFRhZ3N8fFtcInNjcmlwdFwiLFwic3R5bGVcIixcInRleHRhcmVhXCJdO3ZhciBhbGxvd2VkQXR0cmlidXRlc01hcDt2YXIgYWxsb3dlZEF0dHJpYnV0ZXNHbG9iTWFwO2lmKG9wdGlvbnMuYWxsb3dlZEF0dHJpYnV0ZXMpe2FsbG93ZWRBdHRyaWJ1dGVzTWFwPXt9O2FsbG93ZWRBdHRyaWJ1dGVzR2xvYk1hcD17fTtlYWNoKG9wdGlvbnMuYWxsb3dlZEF0dHJpYnV0ZXMsZnVuY3Rpb24oYXR0cmlidXRlcyx0YWcpe2FsbG93ZWRBdHRyaWJ1dGVzTWFwW3RhZ109W107dmFyIGdsb2JSZWdleD1bXTthdHRyaWJ1dGVzLmZvckVhY2goZnVuY3Rpb24obmFtZSl7aWYobmFtZS5pbmRleE9mKFwiKlwiKT49MCl7Z2xvYlJlZ2V4LnB1c2gocXVvdGVSZWdleHAobmFtZSkucmVwbGFjZSgvXFxcXFxcKi9nLFwiLipcIikpfWVsc2V7YWxsb3dlZEF0dHJpYnV0ZXNNYXBbdGFnXS5wdXNoKG5hbWUpfX0pO2FsbG93ZWRBdHRyaWJ1dGVzR2xvYk1hcFt0YWddPW5ldyBSZWdFeHAoXCJeKFwiK2dsb2JSZWdleC5qb2luKFwifFwiKStcIikkXCIpfSl9dmFyIGFsbG93ZWRDbGFzc2VzTWFwPXt9O2VhY2gob3B0aW9ucy5hbGxvd2VkQ2xhc3NlcyxmdW5jdGlvbihjbGFzc2VzLHRhZyl7aWYoYWxsb3dlZEF0dHJpYnV0ZXNNYXApe2lmKCFoYXMoYWxsb3dlZEF0dHJpYnV0ZXNNYXAsdGFnKSl7YWxsb3dlZEF0dHJpYnV0ZXNNYXBbdGFnXT1bXX1hbGxvd2VkQXR0cmlidXRlc01hcFt0YWddLnB1c2goXCJjbGFzc1wiKX1hbGxvd2VkQ2xhc3Nlc01hcFt0YWddPWNsYXNzZXN9KTt2YXIgdHJhbnNmb3JtVGFnc01hcD17fTt2YXIgdHJhbnNmb3JtVGFnc0FsbDtlYWNoKG9wdGlvbnMudHJhbnNmb3JtVGFncyxmdW5jdGlvbih0cmFuc2Zvcm0sdGFnKXt2YXIgdHJhbnNGdW47aWYodHlwZW9mIHRyYW5zZm9ybT09PVwiZnVuY3Rpb25cIil7dHJhbnNGdW49dHJhbnNmb3JtfWVsc2UgaWYodHlwZW9mIHRyYW5zZm9ybT09PVwic3RyaW5nXCIpe3RyYW5zRnVuPXNhbml0aXplSHRtbC5zaW1wbGVUcmFuc2Zvcm0odHJhbnNmb3JtKX1pZih0YWc9PT1cIipcIil7dHJhbnNmb3JtVGFnc0FsbD10cmFuc0Z1bn1lbHNle3RyYW5zZm9ybVRhZ3NNYXBbdGFnXT10cmFuc0Z1bn19KTt2YXIgZGVwdGg9MDt2YXIgc3RhY2s9W107dmFyIHNraXBNYXA9e307dmFyIHRyYW5zZm9ybU1hcD17fTt2YXIgc2tpcFRleHQ9ZmFsc2U7dmFyIHNraXBUZXh0RGVwdGg9MDt2YXIgcGFyc2VyPW5ldyBodG1scGFyc2VyLlBhcnNlcih7b25vcGVudGFnOmZ1bmN0aW9uKG5hbWUsYXR0cmlicyl7aWYoc2tpcFRleHQpe3NraXBUZXh0RGVwdGgrKztyZXR1cm59dmFyIGZyYW1lPW5ldyBGcmFtZShuYW1lLGF0dHJpYnMpO3N0YWNrLnB1c2goZnJhbWUpO3ZhciBza2lwPWZhbHNlO3ZhciBoYXNUZXh0PWZyYW1lLnRleHQ/dHJ1ZTpmYWxzZTt2YXIgdHJhbnNmb3JtZWRUYWc7aWYoaGFzKHRyYW5zZm9ybVRhZ3NNYXAsbmFtZSkpe3RyYW5zZm9ybWVkVGFnPXRyYW5zZm9ybVRhZ3NNYXBbbmFtZV0obmFtZSxhdHRyaWJzKTtmcmFtZS5hdHRyaWJzPWF0dHJpYnM9dHJhbnNmb3JtZWRUYWcuYXR0cmlicztpZih0cmFuc2Zvcm1lZFRhZy50ZXh0IT09dW5kZWZpbmVkKXtmcmFtZS5pbm5lclRleHQ9dHJhbnNmb3JtZWRUYWcudGV4dH1pZihuYW1lIT09dHJhbnNmb3JtZWRUYWcudGFnTmFtZSl7ZnJhbWUubmFtZT1uYW1lPXRyYW5zZm9ybWVkVGFnLnRhZ05hbWU7dHJhbnNmb3JtTWFwW2RlcHRoXT10cmFuc2Zvcm1lZFRhZy50YWdOYW1lfX1pZih0cmFuc2Zvcm1UYWdzQWxsKXt0cmFuc2Zvcm1lZFRhZz10cmFuc2Zvcm1UYWdzQWxsKG5hbWUsYXR0cmlicyk7ZnJhbWUuYXR0cmlicz1hdHRyaWJzPXRyYW5zZm9ybWVkVGFnLmF0dHJpYnM7aWYobmFtZSE9PXRyYW5zZm9ybWVkVGFnLnRhZ05hbWUpe2ZyYW1lLm5hbWU9bmFtZT10cmFuc2Zvcm1lZFRhZy50YWdOYW1lO3RyYW5zZm9ybU1hcFtkZXB0aF09dHJhbnNmb3JtZWRUYWcudGFnTmFtZX19aWYob3B0aW9ucy5hbGxvd2VkVGFncyYmb3B0aW9ucy5hbGxvd2VkVGFncy5pbmRleE9mKG5hbWUpPT09LTEpe3NraXA9dHJ1ZTtpZihub25UZXh0VGFnc0FycmF5LmluZGV4T2YobmFtZSkhPT0tMSl7c2tpcFRleHQ9dHJ1ZTtza2lwVGV4dERlcHRoPTF9c2tpcE1hcFtkZXB0aF09dHJ1ZX1kZXB0aCsrO2lmKHNraXApe3JldHVybn1yZXN1bHQrPVwiPFwiK25hbWU7aWYoIWFsbG93ZWRBdHRyaWJ1dGVzTWFwfHxoYXMoYWxsb3dlZEF0dHJpYnV0ZXNNYXAsbmFtZSl8fGFsbG93ZWRBdHRyaWJ1dGVzTWFwW1wiKlwiXSl7ZWFjaChhdHRyaWJzLGZ1bmN0aW9uKHZhbHVlLGEpe2lmKCFhbGxvd2VkQXR0cmlidXRlc01hcHx8aGFzKGFsbG93ZWRBdHRyaWJ1dGVzTWFwLG5hbWUpJiZhbGxvd2VkQXR0cmlidXRlc01hcFtuYW1lXS5pbmRleE9mKGEpIT09LTF8fGFsbG93ZWRBdHRyaWJ1dGVzTWFwW1wiKlwiXSYmYWxsb3dlZEF0dHJpYnV0ZXNNYXBbXCIqXCJdLmluZGV4T2YoYSkhPT0tMXx8aGFzKGFsbG93ZWRBdHRyaWJ1dGVzR2xvYk1hcCxuYW1lKSYmYWxsb3dlZEF0dHJpYnV0ZXNHbG9iTWFwW25hbWVdLnRlc3QoYSl8fGFsbG93ZWRBdHRyaWJ1dGVzR2xvYk1hcFtcIipcIl0mJmFsbG93ZWRBdHRyaWJ1dGVzR2xvYk1hcFtcIipcIl0udGVzdChhKSl7aWYoYT09PVwiaHJlZlwifHxhPT09XCJzcmNcIil7aWYobmF1Z2h0eUhyZWYobmFtZSx2YWx1ZSkpe2RlbGV0ZSBmcmFtZS5hdHRyaWJzW2FdO3JldHVybn19aWYoYT09PVwiY2xhc3NcIil7dmFsdWU9ZmlsdGVyQ2xhc3Nlcyh2YWx1ZSxhbGxvd2VkQ2xhc3Nlc01hcFtuYW1lXSk7aWYoIXZhbHVlLmxlbmd0aCl7ZGVsZXRlIGZyYW1lLmF0dHJpYnNbYV07cmV0dXJufX1yZXN1bHQrPVwiIFwiK2E7aWYodmFsdWUubGVuZ3RoKXtyZXN1bHQrPSc9XCInK2VzY2FwZUh0bWwodmFsdWUpKydcIid9fWVsc2V7ZGVsZXRlIGZyYW1lLmF0dHJpYnNbYV19fSl9aWYob3B0aW9ucy5zZWxmQ2xvc2luZy5pbmRleE9mKG5hbWUpIT09LTEpe3Jlc3VsdCs9XCIgLz5cIn1lbHNle3Jlc3VsdCs9XCI+XCI7aWYoZnJhbWUuaW5uZXJUZXh0JiYhaGFzVGV4dCYmIW9wdGlvbnMudGV4dEZpbHRlcil7cmVzdWx0Kz1mcmFtZS5pbm5lclRleHR9fX0sb250ZXh0OmZ1bmN0aW9uKHRleHQpe2lmKHNraXBUZXh0KXtyZXR1cm59dmFyIGxhc3RGcmFtZT1zdGFja1tzdGFjay5sZW5ndGgtMV07dmFyIHRhZztpZihsYXN0RnJhbWUpe3RhZz1sYXN0RnJhbWUudGFnO3RleHQ9bGFzdEZyYW1lLmlubmVyVGV4dCE9PXVuZGVmaW5lZD9sYXN0RnJhbWUuaW5uZXJUZXh0OnRleHR9aWYodGFnPT09XCJzY3JpcHRcInx8dGFnPT09XCJzdHlsZVwiKXtyZXN1bHQrPXRleHR9ZWxzZXt2YXIgZXNjYXBlZD1lc2NhcGVIdG1sKHRleHQpO2lmKG9wdGlvbnMudGV4dEZpbHRlcil7cmVzdWx0Kz1vcHRpb25zLnRleHRGaWx0ZXIoZXNjYXBlZCl9ZWxzZXtyZXN1bHQrPWVzY2FwZWR9fWlmKHN0YWNrLmxlbmd0aCl7dmFyIGZyYW1lPXN0YWNrW3N0YWNrLmxlbmd0aC0xXTtmcmFtZS50ZXh0Kz10ZXh0fX0sb25jbG9zZXRhZzpmdW5jdGlvbihuYW1lKXtpZihza2lwVGV4dCl7c2tpcFRleHREZXB0aC0tO2lmKCFza2lwVGV4dERlcHRoKXtza2lwVGV4dD1mYWxzZX1lbHNle3JldHVybn19dmFyIGZyYW1lPXN0YWNrLnBvcCgpO2lmKCFmcmFtZSl7cmV0dXJufXNraXBUZXh0PWZhbHNlO2RlcHRoLS07aWYoc2tpcE1hcFtkZXB0aF0pe2RlbGV0ZSBza2lwTWFwW2RlcHRoXTtmcmFtZS51cGRhdGVQYXJlbnROb2RlVGV4dCgpO3JldHVybn1pZih0cmFuc2Zvcm1NYXBbZGVwdGhdKXtuYW1lPXRyYW5zZm9ybU1hcFtkZXB0aF07ZGVsZXRlIHRyYW5zZm9ybU1hcFtkZXB0aF19aWYob3B0aW9ucy5leGNsdXNpdmVGaWx0ZXImJm9wdGlvbnMuZXhjbHVzaXZlRmlsdGVyKGZyYW1lKSl7cmVzdWx0PXJlc3VsdC5zdWJzdHIoMCxmcmFtZS50YWdQb3NpdGlvbik7cmV0dXJufWZyYW1lLnVwZGF0ZVBhcmVudE5vZGVUZXh0KCk7aWYob3B0aW9ucy5zZWxmQ2xvc2luZy5pbmRleE9mKG5hbWUpIT09LTEpe3JldHVybn1yZXN1bHQrPVwiPC9cIituYW1lK1wiPlwifX0sb3B0aW9ucy5wYXJzZXIpO3BhcnNlci53cml0ZShodG1sKTtwYXJzZXIuZW5kKCk7cmV0dXJuIHJlc3VsdDtmdW5jdGlvbiBlc2NhcGVIdG1sKHMpe2lmKHR5cGVvZiBzIT09XCJzdHJpbmdcIil7cz1zK1wiXCJ9cmV0dXJuIHMucmVwbGFjZSgvXFwmL2csXCImYW1wO1wiKS5yZXBsYWNlKC88L2csXCImbHQ7XCIpLnJlcGxhY2UoL1xcPi9nLFwiJmd0O1wiKS5yZXBsYWNlKC9cXFwiL2csXCImcXVvdDtcIil9ZnVuY3Rpb24gbmF1Z2h0eUhyZWYobmFtZSxocmVmKXtocmVmPWhyZWYucmVwbGFjZSgvW1xceDAwLVxceDIwXSsvZyxcIlwiKTtocmVmPWhyZWYucmVwbGFjZSgvPFxcIVxcLVxcLS4qP1xcLVxcLVxcPi9nLFwiXCIpO3ZhciBtYXRjaGVzPWhyZWYubWF0Y2goL14oW2EtekEtWl0rKVxcOi8pO2lmKCFtYXRjaGVzKXtyZXR1cm4gZmFsc2V9dmFyIHNjaGVtZT1tYXRjaGVzWzFdLnRvTG93ZXJDYXNlKCk7aWYoaGFzKG9wdGlvbnMuYWxsb3dlZFNjaGVtZXNCeVRhZyxuYW1lKSl7cmV0dXJuIG9wdGlvbnMuYWxsb3dlZFNjaGVtZXNCeVRhZ1tuYW1lXS5pbmRleE9mKHNjaGVtZSk9PT0tMX1yZXR1cm4hb3B0aW9ucy5hbGxvd2VkU2NoZW1lc3x8b3B0aW9ucy5hbGxvd2VkU2NoZW1lcy5pbmRleE9mKHNjaGVtZSk9PT0tMX1mdW5jdGlvbiBmaWx0ZXJDbGFzc2VzKGNsYXNzZXMsYWxsb3dlZCl7aWYoIWFsbG93ZWQpe3JldHVybiBjbGFzc2VzfWNsYXNzZXM9Y2xhc3Nlcy5zcGxpdCgvXFxzKy8pO3JldHVybiBjbGFzc2VzLmZpbHRlcihmdW5jdGlvbihjbHNzKXtyZXR1cm4gYWxsb3dlZC5pbmRleE9mKGNsc3MpIT09LTF9KS5qb2luKFwiIFwiKX19dmFyIGh0bWxQYXJzZXJEZWZhdWx0cz17ZGVjb2RlRW50aXRpZXM6dHJ1ZX07c2FuaXRpemVIdG1sLmRlZmF1bHRzPXthbGxvd2VkVGFnczpbXCJoM1wiLFwiaDRcIixcImg1XCIsXCJoNlwiLFwiYmxvY2txdW90ZVwiLFwicFwiLFwiYVwiLFwidWxcIixcIm9sXCIsXCJubFwiLFwibGlcIixcImJcIixcImlcIixcInN0cm9uZ1wiLFwiZW1cIixcInN0cmlrZVwiLFwiY29kZVwiLFwiaHJcIixcImJyXCIsXCJkaXZcIixcInRhYmxlXCIsXCJ0aGVhZFwiLFwiY2FwdGlvblwiLFwidGJvZHlcIixcInRyXCIsXCJ0aFwiLFwidGRcIixcInByZVwiXSxhbGxvd2VkQXR0cmlidXRlczp7YTpbXCJocmVmXCIsXCJuYW1lXCIsXCJ0YXJnZXRcIl0saW1nOltcInNyY1wiXX0sc2VsZkNsb3Npbmc6W1wiaW1nXCIsXCJiclwiLFwiaHJcIixcImFyZWFcIixcImJhc2VcIixcImJhc2Vmb250XCIsXCJpbnB1dFwiLFwibGlua1wiLFwibWV0YVwiXSxhbGxvd2VkU2NoZW1lczpbXCJodHRwXCIsXCJodHRwc1wiLFwiZnRwXCIsXCJtYWlsdG9cIl0sYWxsb3dlZFNjaGVtZXNCeVRhZzp7fX07c2FuaXRpemVIdG1sLnNpbXBsZVRyYW5zZm9ybT1mdW5jdGlvbihuZXdUYWdOYW1lLG5ld0F0dHJpYnMsbWVyZ2Upe21lcmdlPW1lcmdlPT09dW5kZWZpbmVkP3RydWU6bWVyZ2U7bmV3QXR0cmlicz1uZXdBdHRyaWJzfHx7fTtyZXR1cm4gZnVuY3Rpb24odGFnTmFtZSxhdHRyaWJzKXt2YXIgYXR0cmliO2lmKG1lcmdlKXtmb3IoYXR0cmliIGluIG5ld0F0dHJpYnMpe2F0dHJpYnNbYXR0cmliXT1uZXdBdHRyaWJzW2F0dHJpYl19fWVsc2V7YXR0cmlicz1uZXdBdHRyaWJzfXJldHVybnt0YWdOYW1lOm5ld1RhZ05hbWUsYXR0cmliczphdHRyaWJzfX19fSx7aHRtbHBhcnNlcjI6MzYsXCJyZWdleHAtcXVvdGVcIjo1NCx4dGVuZDo1OH1dLDI6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1widXNlIHN0cmljdFwiO2V4cG9ydHMudG9CeXRlQXJyYXk9dG9CeXRlQXJyYXk7ZXhwb3J0cy5mcm9tQnl0ZUFycmF5PWZyb21CeXRlQXJyYXk7dmFyIGxvb2t1cD1bXTt2YXIgcmV2TG9va3VwPVtdO3ZhciBBcnI9dHlwZW9mIFVpbnQ4QXJyYXkhPT1cInVuZGVmaW5lZFwiP1VpbnQ4QXJyYXk6QXJyYXk7ZnVuY3Rpb24gaW5pdCgpe3ZhciBjb2RlPVwiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrL1wiO2Zvcih2YXIgaT0wLGxlbj1jb2RlLmxlbmd0aDtpPGxlbjsrK2kpe2xvb2t1cFtpXT1jb2RlW2ldO3Jldkxvb2t1cFtjb2RlLmNoYXJDb2RlQXQoaSldPWl9cmV2TG9va3VwW1wiLVwiLmNoYXJDb2RlQXQoMCldPTYyO3Jldkxvb2t1cFtcIl9cIi5jaGFyQ29kZUF0KDApXT02M31pbml0KCk7ZnVuY3Rpb24gdG9CeXRlQXJyYXkoYjY0KXt2YXIgaSxqLGwsdG1wLHBsYWNlSG9sZGVycyxhcnI7dmFyIGxlbj1iNjQubGVuZ3RoO2lmKGxlbiU0PjApe3Rocm93IG5ldyBFcnJvcihcIkludmFsaWQgc3RyaW5nLiBMZW5ndGggbXVzdCBiZSBhIG11bHRpcGxlIG9mIDRcIil9cGxhY2VIb2xkZXJzPWI2NFtsZW4tMl09PT1cIj1cIj8yOmI2NFtsZW4tMV09PT1cIj1cIj8xOjA7YXJyPW5ldyBBcnIobGVuKjMvNC1wbGFjZUhvbGRlcnMpO2w9cGxhY2VIb2xkZXJzPjA/bGVuLTQ6bGVuO3ZhciBMPTA7Zm9yKGk9MCxqPTA7aTxsO2krPTQsais9Myl7dG1wPXJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV08PDE4fHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKzEpXTw8MTJ8cmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkrMildPDw2fHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKzMpXTthcnJbTCsrXT10bXA+PjE2JjI1NTthcnJbTCsrXT10bXA+PjgmMjU1O2FycltMKytdPXRtcCYyNTV9aWYocGxhY2VIb2xkZXJzPT09Mil7dG1wPXJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV08PDJ8cmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkrMSldPj40O2FycltMKytdPXRtcCYyNTV9ZWxzZSBpZihwbGFjZUhvbGRlcnM9PT0xKXt0bXA9cmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXTw8MTB8cmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkrMSldPDw0fHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKzIpXT4+MjthcnJbTCsrXT10bXA+PjgmMjU1O2FycltMKytdPXRtcCYyNTV9cmV0dXJuIGFycn1mdW5jdGlvbiB0cmlwbGV0VG9CYXNlNjQobnVtKXtyZXR1cm4gbG9va3VwW251bT4+MTgmNjNdK2xvb2t1cFtudW0+PjEyJjYzXStsb29rdXBbbnVtPj42JjYzXStsb29rdXBbbnVtJjYzXX1mdW5jdGlvbiBlbmNvZGVDaHVuayh1aW50OCxzdGFydCxlbmQpe3ZhciB0bXA7dmFyIG91dHB1dD1bXTtmb3IodmFyIGk9c3RhcnQ7aTxlbmQ7aSs9Myl7dG1wPSh1aW50OFtpXTw8MTYpKyh1aW50OFtpKzFdPDw4KSt1aW50OFtpKzJdO291dHB1dC5wdXNoKHRyaXBsZXRUb0Jhc2U2NCh0bXApKX1yZXR1cm4gb3V0cHV0LmpvaW4oXCJcIil9ZnVuY3Rpb24gZnJvbUJ5dGVBcnJheSh1aW50OCl7dmFyIHRtcDt2YXIgbGVuPXVpbnQ4Lmxlbmd0aDt2YXIgZXh0cmFCeXRlcz1sZW4lMzt2YXIgb3V0cHV0PVwiXCI7dmFyIHBhcnRzPVtdO3ZhciBtYXhDaHVua0xlbmd0aD0xNjM4Mztmb3IodmFyIGk9MCxsZW4yPWxlbi1leHRyYUJ5dGVzO2k8bGVuMjtpKz1tYXhDaHVua0xlbmd0aCl7cGFydHMucHVzaChlbmNvZGVDaHVuayh1aW50OCxpLGkrbWF4Q2h1bmtMZW5ndGg+bGVuMj9sZW4yOmkrbWF4Q2h1bmtMZW5ndGgpKX1pZihleHRyYUJ5dGVzPT09MSl7dG1wPXVpbnQ4W2xlbi0xXTtvdXRwdXQrPWxvb2t1cFt0bXA+PjJdO291dHB1dCs9bG9va3VwW3RtcDw8NCY2M107b3V0cHV0Kz1cIj09XCJ9ZWxzZSBpZihleHRyYUJ5dGVzPT09Mil7dG1wPSh1aW50OFtsZW4tMl08PDgpK3VpbnQ4W2xlbi0xXTtvdXRwdXQrPWxvb2t1cFt0bXA+PjEwXTtvdXRwdXQrPWxvb2t1cFt0bXA+PjQmNjNdO291dHB1dCs9bG9va3VwW3RtcDw8MiY2M107b3V0cHV0Kz1cIj1cIn1wYXJ0cy5wdXNoKG91dHB1dCk7cmV0dXJuIHBhcnRzLmpvaW4oXCJcIil9fSx7fV0sMzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7fSx7fV0sNDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7KGZ1bmN0aW9uKGdsb2JhbCl7XCJ1c2Ugc3RyaWN0XCI7dmFyIGJ1ZmZlcj1yZXF1aXJlKFwiYnVmZmVyXCIpO3ZhciBCdWZmZXI9YnVmZmVyLkJ1ZmZlcjt2YXIgU2xvd0J1ZmZlcj1idWZmZXIuU2xvd0J1ZmZlcjt2YXIgTUFYX0xFTj1idWZmZXIua01heExlbmd0aHx8MjE0NzQ4MzY0NztleHBvcnRzLmFsbG9jPWZ1bmN0aW9uIGFsbG9jKHNpemUsZmlsbCxlbmNvZGluZyl7aWYodHlwZW9mIEJ1ZmZlci5hbGxvYz09PVwiZnVuY3Rpb25cIil7cmV0dXJuIEJ1ZmZlci5hbGxvYyhzaXplLGZpbGwsZW5jb2RpbmcpfWlmKHR5cGVvZiBlbmNvZGluZz09PVwibnVtYmVyXCIpe3Rocm93IG5ldyBUeXBlRXJyb3IoXCJlbmNvZGluZyBtdXN0IG5vdCBiZSBudW1iZXJcIil9aWYodHlwZW9mIHNpemUhPT1cIm51bWJlclwiKXt0aHJvdyBuZXcgVHlwZUVycm9yKFwic2l6ZSBtdXN0IGJlIGEgbnVtYmVyXCIpfWlmKHNpemU+TUFYX0xFTil7dGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJzaXplIGlzIHRvbyBsYXJnZVwiKX12YXIgZW5jPWVuY29kaW5nO3ZhciBfZmlsbD1maWxsO2lmKF9maWxsPT09dW5kZWZpbmVkKXtlbmM9dW5kZWZpbmVkO19maWxsPTB9dmFyIGJ1Zj1uZXcgQnVmZmVyKHNpemUpO2lmKHR5cGVvZiBfZmlsbD09PVwic3RyaW5nXCIpe3ZhciBmaWxsQnVmPW5ldyBCdWZmZXIoX2ZpbGwsZW5jKTt2YXIgZmxlbj1maWxsQnVmLmxlbmd0aDt2YXIgaT0tMTt3aGlsZSgrK2k8c2l6ZSl7YnVmW2ldPWZpbGxCdWZbaSVmbGVuXX19ZWxzZXtidWYuZmlsbChfZmlsbCl9cmV0dXJuIGJ1Zn07ZXhwb3J0cy5hbGxvY1Vuc2FmZT1mdW5jdGlvbiBhbGxvY1Vuc2FmZShzaXplKXtpZih0eXBlb2YgQnVmZmVyLmFsbG9jVW5zYWZlPT09XCJmdW5jdGlvblwiKXtyZXR1cm4gQnVmZmVyLmFsbG9jVW5zYWZlKHNpemUpfWlmKHR5cGVvZiBzaXplIT09XCJudW1iZXJcIil7dGhyb3cgbmV3IFR5cGVFcnJvcihcInNpemUgbXVzdCBiZSBhIG51bWJlclwiKX1pZihzaXplPk1BWF9MRU4pe3Rocm93IG5ldyBSYW5nZUVycm9yKFwic2l6ZSBpcyB0b28gbGFyZ2VcIil9cmV0dXJuIG5ldyBCdWZmZXIoc2l6ZSl9O2V4cG9ydHMuZnJvbT1mdW5jdGlvbiBmcm9tKHZhbHVlLGVuY29kaW5nT3JPZmZzZXQsbGVuZ3RoKXtpZih0eXBlb2YgQnVmZmVyLmZyb209PT1cImZ1bmN0aW9uXCImJighZ2xvYmFsLlVpbnQ4QXJyYXl8fFVpbnQ4QXJyYXkuZnJvbSE9PUJ1ZmZlci5mcm9tKSl7cmV0dXJuIEJ1ZmZlci5mcm9tKHZhbHVlLGVuY29kaW5nT3JPZmZzZXQsbGVuZ3RoKX1pZih0eXBlb2YgdmFsdWU9PT1cIm51bWJlclwiKXt0aHJvdyBuZXcgVHlwZUVycm9yKCdcInZhbHVlXCIgYXJndW1lbnQgbXVzdCBub3QgYmUgYSBudW1iZXInKX1pZih0eXBlb2YgdmFsdWU9PT1cInN0cmluZ1wiKXtyZXR1cm4gbmV3IEJ1ZmZlcih2YWx1ZSxlbmNvZGluZ09yT2Zmc2V0KX1pZih0eXBlb2YgQXJyYXlCdWZmZXIhPT1cInVuZGVmaW5lZFwiJiZ2YWx1ZSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKXt2YXIgb2Zmc2V0PWVuY29kaW5nT3JPZmZzZXQ7aWYoYXJndW1lbnRzLmxlbmd0aD09PTEpe3JldHVybiBuZXcgQnVmZmVyKHZhbHVlKX1pZih0eXBlb2Ygb2Zmc2V0PT09XCJ1bmRlZmluZWRcIil7b2Zmc2V0PTB9dmFyIGxlbj1sZW5ndGg7aWYodHlwZW9mIGxlbj09PVwidW5kZWZpbmVkXCIpe2xlbj12YWx1ZS5ieXRlTGVuZ3RoLW9mZnNldH1pZihvZmZzZXQ+PXZhbHVlLmJ5dGVMZW5ndGgpe3Rocm93IG5ldyBSYW5nZUVycm9yKFwiJ29mZnNldCcgaXMgb3V0IG9mIGJvdW5kc1wiKX1pZihsZW4+dmFsdWUuYnl0ZUxlbmd0aC1vZmZzZXQpe3Rocm93IG5ldyBSYW5nZUVycm9yKFwiJ2xlbmd0aCcgaXMgb3V0IG9mIGJvdW5kc1wiKX1yZXR1cm4gbmV3IEJ1ZmZlcih2YWx1ZS5zbGljZShvZmZzZXQsb2Zmc2V0K2xlbikpfWlmKEJ1ZmZlci5pc0J1ZmZlcih2YWx1ZSkpe3ZhciBvdXQ9bmV3IEJ1ZmZlcih2YWx1ZS5sZW5ndGgpO3ZhbHVlLmNvcHkob3V0LDAsMCx2YWx1ZS5sZW5ndGgpO3JldHVybiBvdXR9aWYodmFsdWUpe2lmKEFycmF5LmlzQXJyYXkodmFsdWUpfHx0eXBlb2YgQXJyYXlCdWZmZXIhPT1cInVuZGVmaW5lZFwiJiZ2YWx1ZS5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcnx8XCJsZW5ndGhcImluIHZhbHVlKXtyZXR1cm4gbmV3IEJ1ZmZlcih2YWx1ZSl9aWYodmFsdWUudHlwZT09PVwiQnVmZmVyXCImJkFycmF5LmlzQXJyYXkodmFsdWUuZGF0YSkpe3JldHVybiBuZXcgQnVmZmVyKHZhbHVlLmRhdGEpfX10aHJvdyBuZXcgVHlwZUVycm9yKFwiRmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZywgQnVmZmVyLCBcIitcIkFycmF5QnVmZmVyLCBBcnJheSwgb3IgYXJyYXktbGlrZSBvYmplY3QuXCIpfTtleHBvcnRzLmFsbG9jVW5zYWZlU2xvdz1mdW5jdGlvbiBhbGxvY1Vuc2FmZVNsb3coc2l6ZSl7aWYodHlwZW9mIEJ1ZmZlci5hbGxvY1Vuc2FmZVNsb3c9PT1cImZ1bmN0aW9uXCIpe3JldHVybiBCdWZmZXIuYWxsb2NVbnNhZmVTbG93KHNpemUpfWlmKHR5cGVvZiBzaXplIT09XCJudW1iZXJcIil7dGhyb3cgbmV3IFR5cGVFcnJvcihcInNpemUgbXVzdCBiZSBhIG51bWJlclwiKX1pZihzaXplPj1NQVhfTEVOKXt0aHJvdyBuZXcgUmFuZ2VFcnJvcihcInNpemUgaXMgdG9vIGxhcmdlXCIpfXJldHVybiBuZXcgU2xvd0J1ZmZlcihzaXplKX19KS5jYWxsKHRoaXMsdHlwZW9mIGdsb2JhbCE9PVwidW5kZWZpbmVkXCI/Z2xvYmFsOnR5cGVvZiBzZWxmIT09XCJ1bmRlZmluZWRcIj9zZWxmOnR5cGVvZiB3aW5kb3chPT1cInVuZGVmaW5lZFwiP3dpbmRvdzp7fSl9LHtidWZmZXI6NX1dLDU6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpeyhmdW5jdGlvbihnbG9iYWwpe1widXNlIHN0cmljdFwiO3ZhciBiYXNlNjQ9cmVxdWlyZShcImJhc2U2NC1qc1wiKTt2YXIgaWVlZTc1ND1yZXF1aXJlKFwiaWVlZTc1NFwiKTt2YXIgaXNBcnJheT1yZXF1aXJlKFwiaXNhcnJheVwiKTtleHBvcnRzLkJ1ZmZlcj1CdWZmZXI7ZXhwb3J0cy5TbG93QnVmZmVyPVNsb3dCdWZmZXI7ZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUz01MDtCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVD1nbG9iYWwuVFlQRURfQVJSQVlfU1VQUE9SVCE9PXVuZGVmaW5lZD9nbG9iYWwuVFlQRURfQVJSQVlfU1VQUE9SVDp0eXBlZEFycmF5U3VwcG9ydCgpO2V4cG9ydHMua01heExlbmd0aD1rTWF4TGVuZ3RoKCk7ZnVuY3Rpb24gdHlwZWRBcnJheVN1cHBvcnQoKXt0cnl7dmFyIGFycj1uZXcgVWludDhBcnJheSgxKTthcnIuX19wcm90b19fPXtfX3Byb3RvX186VWludDhBcnJheS5wcm90b3R5cGUsZm9vOmZ1bmN0aW9uKCl7cmV0dXJuIDQyfX07cmV0dXJuIGFyci5mb28oKT09PTQyJiZ0eXBlb2YgYXJyLnN1YmFycmF5PT09XCJmdW5jdGlvblwiJiZhcnIuc3ViYXJyYXkoMSwxKS5ieXRlTGVuZ3RoPT09MH1jYXRjaChlKXtyZXR1cm4gZmFsc2V9fWZ1bmN0aW9uIGtNYXhMZW5ndGgoKXtyZXR1cm4gQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQ/MjE0NzQ4MzY0NzoxMDczNzQxODIzfWZ1bmN0aW9uIGNyZWF0ZUJ1ZmZlcih0aGF0LGxlbmd0aCl7aWYoa01heExlbmd0aCgpPGxlbmd0aCl7dGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIHR5cGVkIGFycmF5IGxlbmd0aFwiKX1pZihCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCl7dGhhdD1uZXcgVWludDhBcnJheShsZW5ndGgpO3RoYXQuX19wcm90b19fPUJ1ZmZlci5wcm90b3R5cGV9ZWxzZXtpZih0aGF0PT09bnVsbCl7dGhhdD1uZXcgQnVmZmVyKGxlbmd0aCl9dGhhdC5sZW5ndGg9bGVuZ3RofXJldHVybiB0aGF0fWZ1bmN0aW9uIEJ1ZmZlcihhcmcsZW5jb2RpbmdPck9mZnNldCxsZW5ndGgpe2lmKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCYmISh0aGlzIGluc3RhbmNlb2YgQnVmZmVyKSl7cmV0dXJuIG5ldyBCdWZmZXIoYXJnLGVuY29kaW5nT3JPZmZzZXQsbGVuZ3RoKX1pZih0eXBlb2YgYXJnPT09XCJudW1iZXJcIil7aWYodHlwZW9mIGVuY29kaW5nT3JPZmZzZXQ9PT1cInN0cmluZ1wiKXt0aHJvdyBuZXcgRXJyb3IoXCJJZiBlbmNvZGluZyBpcyBzcGVjaWZpZWQgdGhlbiB0aGUgZmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZ1wiKX1yZXR1cm4gYWxsb2NVbnNhZmUodGhpcyxhcmcpfXJldHVybiBmcm9tKHRoaXMsYXJnLGVuY29kaW5nT3JPZmZzZXQsbGVuZ3RoKX1CdWZmZXIucG9vbFNpemU9ODE5MjtCdWZmZXIuX2F1Z21lbnQ9ZnVuY3Rpb24oYXJyKXthcnIuX19wcm90b19fPUJ1ZmZlci5wcm90b3R5cGU7cmV0dXJuIGFycn07ZnVuY3Rpb24gZnJvbSh0aGF0LHZhbHVlLGVuY29kaW5nT3JPZmZzZXQsbGVuZ3RoKXtpZih0eXBlb2YgdmFsdWU9PT1cIm51bWJlclwiKXt0aHJvdyBuZXcgVHlwZUVycm9yKCdcInZhbHVlXCIgYXJndW1lbnQgbXVzdCBub3QgYmUgYSBudW1iZXInKX1pZih0eXBlb2YgQXJyYXlCdWZmZXIhPT1cInVuZGVmaW5lZFwiJiZ2YWx1ZSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKXtyZXR1cm4gZnJvbUFycmF5QnVmZmVyKHRoYXQsdmFsdWUsZW5jb2RpbmdPck9mZnNldCxsZW5ndGgpfWlmKHR5cGVvZiB2YWx1ZT09PVwic3RyaW5nXCIpe3JldHVybiBmcm9tU3RyaW5nKHRoYXQsdmFsdWUsZW5jb2RpbmdPck9mZnNldCl9cmV0dXJuIGZyb21PYmplY3QodGhhdCx2YWx1ZSl9QnVmZmVyLmZyb209ZnVuY3Rpb24odmFsdWUsZW5jb2RpbmdPck9mZnNldCxsZW5ndGgpe3JldHVybiBmcm9tKG51bGwsdmFsdWUsZW5jb2RpbmdPck9mZnNldCxsZW5ndGgpfTtpZihCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCl7QnVmZmVyLnByb3RvdHlwZS5fX3Byb3RvX189VWludDhBcnJheS5wcm90b3R5cGU7QnVmZmVyLl9fcHJvdG9fXz1VaW50OEFycmF5O2lmKHR5cGVvZiBTeW1ib2whPT1cInVuZGVmaW5lZFwiJiZTeW1ib2wuc3BlY2llcyYmQnVmZmVyW1N5bWJvbC5zcGVjaWVzXT09PUJ1ZmZlcil7T2JqZWN0LmRlZmluZVByb3BlcnR5KEJ1ZmZlcixTeW1ib2wuc3BlY2llcyx7dmFsdWU6bnVsbCxjb25maWd1cmFibGU6dHJ1ZX0pfX1mdW5jdGlvbiBhc3NlcnRTaXplKHNpemUpe2lmKHR5cGVvZiBzaXplIT09XCJudW1iZXJcIil7dGhyb3cgbmV3IFR5cGVFcnJvcignXCJzaXplXCIgYXJndW1lbnQgbXVzdCBiZSBhIG51bWJlcicpfWVsc2UgaWYoc2l6ZTwwKXt0aHJvdyBuZXcgUmFuZ2VFcnJvcignXCJzaXplXCIgYXJndW1lbnQgbXVzdCBub3QgYmUgbmVnYXRpdmUnKX19ZnVuY3Rpb24gYWxsb2ModGhhdCxzaXplLGZpbGwsZW5jb2Rpbmcpe2Fzc2VydFNpemUoc2l6ZSk7aWYoc2l6ZTw9MCl7cmV0dXJuIGNyZWF0ZUJ1ZmZlcih0aGF0LHNpemUpfWlmKGZpbGwhPT11bmRlZmluZWQpe3JldHVybiB0eXBlb2YgZW5jb2Rpbmc9PT1cInN0cmluZ1wiP2NyZWF0ZUJ1ZmZlcih0aGF0LHNpemUpLmZpbGwoZmlsbCxlbmNvZGluZyk6Y3JlYXRlQnVmZmVyKHRoYXQsc2l6ZSkuZmlsbChmaWxsKX1yZXR1cm4gY3JlYXRlQnVmZmVyKHRoYXQsc2l6ZSl9QnVmZmVyLmFsbG9jPWZ1bmN0aW9uKHNpemUsZmlsbCxlbmNvZGluZyl7cmV0dXJuIGFsbG9jKG51bGwsc2l6ZSxmaWxsLGVuY29kaW5nKX07ZnVuY3Rpb24gYWxsb2NVbnNhZmUodGhhdCxzaXplKXthc3NlcnRTaXplKHNpemUpO3RoYXQ9Y3JlYXRlQnVmZmVyKHRoYXQsc2l6ZTwwPzA6Y2hlY2tlZChzaXplKXwwKTtpZighQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpe2Zvcih2YXIgaT0wO2k8c2l6ZTsrK2kpe3RoYXRbaV09MH19cmV0dXJuIHRoYXR9QnVmZmVyLmFsbG9jVW5zYWZlPWZ1bmN0aW9uKHNpemUpe3JldHVybiBhbGxvY1Vuc2FmZShudWxsLHNpemUpfTtCdWZmZXIuYWxsb2NVbnNhZmVTbG93PWZ1bmN0aW9uKHNpemUpe3JldHVybiBhbGxvY1Vuc2FmZShudWxsLHNpemUpfTtmdW5jdGlvbiBmcm9tU3RyaW5nKHRoYXQsc3RyaW5nLGVuY29kaW5nKXtpZih0eXBlb2YgZW5jb2RpbmchPT1cInN0cmluZ1wifHxlbmNvZGluZz09PVwiXCIpe2VuY29kaW5nPVwidXRmOFwifWlmKCFCdWZmZXIuaXNFbmNvZGluZyhlbmNvZGluZykpe3Rocm93IG5ldyBUeXBlRXJyb3IoJ1wiZW5jb2RpbmdcIiBtdXN0IGJlIGEgdmFsaWQgc3RyaW5nIGVuY29kaW5nJyl9dmFyIGxlbmd0aD1ieXRlTGVuZ3RoKHN0cmluZyxlbmNvZGluZyl8MDt0aGF0PWNyZWF0ZUJ1ZmZlcih0aGF0LGxlbmd0aCk7dmFyIGFjdHVhbD10aGF0LndyaXRlKHN0cmluZyxlbmNvZGluZyk7aWYoYWN0dWFsIT09bGVuZ3RoKXt0aGF0PXRoYXQuc2xpY2UoMCxhY3R1YWwpfXJldHVybiB0aGF0fWZ1bmN0aW9uIGZyb21BcnJheUxpa2UodGhhdCxhcnJheSl7dmFyIGxlbmd0aD1hcnJheS5sZW5ndGg8MD8wOmNoZWNrZWQoYXJyYXkubGVuZ3RoKXwwO3RoYXQ9Y3JlYXRlQnVmZmVyKHRoYXQsbGVuZ3RoKTtmb3IodmFyIGk9MDtpPGxlbmd0aDtpKz0xKXt0aGF0W2ldPWFycmF5W2ldJjI1NX1yZXR1cm4gdGhhdH1mdW5jdGlvbiBmcm9tQXJyYXlCdWZmZXIodGhhdCxhcnJheSxieXRlT2Zmc2V0LGxlbmd0aCl7YXJyYXkuYnl0ZUxlbmd0aDtpZihieXRlT2Zmc2V0PDB8fGFycmF5LmJ5dGVMZW5ndGg8Ynl0ZU9mZnNldCl7dGhyb3cgbmV3IFJhbmdlRXJyb3IoXCInb2Zmc2V0JyBpcyBvdXQgb2YgYm91bmRzXCIpfWlmKGFycmF5LmJ5dGVMZW5ndGg8Ynl0ZU9mZnNldCsobGVuZ3RofHwwKSl7dGhyb3cgbmV3IFJhbmdlRXJyb3IoXCInbGVuZ3RoJyBpcyBvdXQgb2YgYm91bmRzXCIpfWlmKGJ5dGVPZmZzZXQ9PT11bmRlZmluZWQmJmxlbmd0aD09PXVuZGVmaW5lZCl7YXJyYXk9bmV3IFVpbnQ4QXJyYXkoYXJyYXkpfWVsc2UgaWYobGVuZ3RoPT09dW5kZWZpbmVkKXthcnJheT1uZXcgVWludDhBcnJheShhcnJheSxieXRlT2Zmc2V0KX1lbHNle2FycmF5PW5ldyBVaW50OEFycmF5KGFycmF5LGJ5dGVPZmZzZXQsbGVuZ3RoKX1pZihCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCl7dGhhdD1hcnJheTt0aGF0Ll9fcHJvdG9fXz1CdWZmZXIucHJvdG90eXBlfWVsc2V7dGhhdD1mcm9tQXJyYXlMaWtlKHRoYXQsYXJyYXkpfXJldHVybiB0aGF0fWZ1bmN0aW9uIGZyb21PYmplY3QodGhhdCxvYmope2lmKEJ1ZmZlci5pc0J1ZmZlcihvYmopKXt2YXIgbGVuPWNoZWNrZWQob2JqLmxlbmd0aCl8MDt0aGF0PWNyZWF0ZUJ1ZmZlcih0aGF0LGxlbik7aWYodGhhdC5sZW5ndGg9PT0wKXtyZXR1cm4gdGhhdH1vYmouY29weSh0aGF0LDAsMCxsZW4pO3JldHVybiB0aGF0fWlmKG9iail7aWYodHlwZW9mIEFycmF5QnVmZmVyIT09XCJ1bmRlZmluZWRcIiYmb2JqLmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyfHxcImxlbmd0aFwiaW4gb2JqKXtpZih0eXBlb2Ygb2JqLmxlbmd0aCE9PVwibnVtYmVyXCJ8fGlzbmFuKG9iai5sZW5ndGgpKXtyZXR1cm4gY3JlYXRlQnVmZmVyKHRoYXQsMCl9cmV0dXJuIGZyb21BcnJheUxpa2UodGhhdCxvYmopfWlmKG9iai50eXBlPT09XCJCdWZmZXJcIiYmaXNBcnJheShvYmouZGF0YSkpe3JldHVybiBmcm9tQXJyYXlMaWtlKHRoYXQsb2JqLmRhdGEpfX10aHJvdyBuZXcgVHlwZUVycm9yKFwiRmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZywgQnVmZmVyLCBBcnJheUJ1ZmZlciwgQXJyYXksIG9yIGFycmF5LWxpa2Ugb2JqZWN0LlwiKX1mdW5jdGlvbiBjaGVja2VkKGxlbmd0aCl7aWYobGVuZ3RoPj1rTWF4TGVuZ3RoKCkpe3Rocm93IG5ldyBSYW5nZUVycm9yKFwiQXR0ZW1wdCB0byBhbGxvY2F0ZSBCdWZmZXIgbGFyZ2VyIHRoYW4gbWF4aW11bSBcIitcInNpemU6IDB4XCIra01heExlbmd0aCgpLnRvU3RyaW5nKDE2KStcIiBieXRlc1wiKX1yZXR1cm4gbGVuZ3RofDB9ZnVuY3Rpb24gU2xvd0J1ZmZlcihsZW5ndGgpe2lmKCtsZW5ndGghPWxlbmd0aCl7bGVuZ3RoPTB9cmV0dXJuIEJ1ZmZlci5hbGxvYygrbGVuZ3RoKX1CdWZmZXIuaXNCdWZmZXI9ZnVuY3Rpb24gaXNCdWZmZXIoYil7cmV0dXJuISEoYiE9bnVsbCYmYi5faXNCdWZmZXIpfTtCdWZmZXIuY29tcGFyZT1mdW5jdGlvbiBjb21wYXJlKGEsYil7aWYoIUJ1ZmZlci5pc0J1ZmZlcihhKXx8IUJ1ZmZlci5pc0J1ZmZlcihiKSl7dGhyb3cgbmV3IFR5cGVFcnJvcihcIkFyZ3VtZW50cyBtdXN0IGJlIEJ1ZmZlcnNcIil9aWYoYT09PWIpcmV0dXJuIDA7dmFyIHg9YS5sZW5ndGg7dmFyIHk9Yi5sZW5ndGg7Zm9yKHZhciBpPTAsbGVuPU1hdGgubWluKHgseSk7aTxsZW47KytpKXtpZihhW2ldIT09YltpXSl7eD1hW2ldO3k9YltpXTticmVha319aWYoeDx5KXJldHVybi0xO2lmKHk8eClyZXR1cm4gMTtyZXR1cm4gMH07QnVmZmVyLmlzRW5jb2Rpbmc9ZnVuY3Rpb24gaXNFbmNvZGluZyhlbmNvZGluZyl7c3dpdGNoKFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKSl7Y2FzZVwiaGV4XCI6Y2FzZVwidXRmOFwiOmNhc2VcInV0Zi04XCI6Y2FzZVwiYXNjaWlcIjpjYXNlXCJsYXRpbjFcIjpjYXNlXCJiaW5hcnlcIjpjYXNlXCJiYXNlNjRcIjpjYXNlXCJ1Y3MyXCI6Y2FzZVwidWNzLTJcIjpjYXNlXCJ1dGYxNmxlXCI6Y2FzZVwidXRmLTE2bGVcIjpyZXR1cm4gdHJ1ZTtkZWZhdWx0OnJldHVybiBmYWxzZX19O0J1ZmZlci5jb25jYXQ9ZnVuY3Rpb24gY29uY2F0KGxpc3QsbGVuZ3RoKXtpZighaXNBcnJheShsaXN0KSl7dGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0XCIgYXJndW1lbnQgbXVzdCBiZSBhbiBBcnJheSBvZiBCdWZmZXJzJyl9aWYobGlzdC5sZW5ndGg9PT0wKXtyZXR1cm4gQnVmZmVyLmFsbG9jKDApfXZhciBpO2lmKGxlbmd0aD09PXVuZGVmaW5lZCl7bGVuZ3RoPTA7Zm9yKGk9MDtpPGxpc3QubGVuZ3RoOysraSl7bGVuZ3RoKz1saXN0W2ldLmxlbmd0aH19dmFyIGJ1ZmZlcj1CdWZmZXIuYWxsb2NVbnNhZmUobGVuZ3RoKTt2YXIgcG9zPTA7Zm9yKGk9MDtpPGxpc3QubGVuZ3RoOysraSl7dmFyIGJ1Zj1saXN0W2ldO2lmKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSl7dGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0XCIgYXJndW1lbnQgbXVzdCBiZSBhbiBBcnJheSBvZiBCdWZmZXJzJyl9YnVmLmNvcHkoYnVmZmVyLHBvcyk7cG9zKz1idWYubGVuZ3RofXJldHVybiBidWZmZXJ9O2Z1bmN0aW9uIGJ5dGVMZW5ndGgoc3RyaW5nLGVuY29kaW5nKXtpZihCdWZmZXIuaXNCdWZmZXIoc3RyaW5nKSl7cmV0dXJuIHN0cmluZy5sZW5ndGh9aWYodHlwZW9mIEFycmF5QnVmZmVyIT09XCJ1bmRlZmluZWRcIiYmdHlwZW9mIEFycmF5QnVmZmVyLmlzVmlldz09PVwiZnVuY3Rpb25cIiYmKEFycmF5QnVmZmVyLmlzVmlldyhzdHJpbmcpfHxzdHJpbmcgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikpe3JldHVybiBzdHJpbmcuYnl0ZUxlbmd0aH1pZih0eXBlb2Ygc3RyaW5nIT09XCJzdHJpbmdcIil7c3RyaW5nPVwiXCIrc3RyaW5nfXZhciBsZW49c3RyaW5nLmxlbmd0aDtpZihsZW49PT0wKXJldHVybiAwO3ZhciBsb3dlcmVkQ2FzZT1mYWxzZTtmb3IoOzspe3N3aXRjaChlbmNvZGluZyl7Y2FzZVwiYXNjaWlcIjpjYXNlXCJsYXRpbjFcIjpjYXNlXCJiaW5hcnlcIjpyZXR1cm4gbGVuO2Nhc2VcInV0ZjhcIjpjYXNlXCJ1dGYtOFwiOmNhc2UgdW5kZWZpbmVkOnJldHVybiB1dGY4VG9CeXRlcyhzdHJpbmcpLmxlbmd0aDtjYXNlXCJ1Y3MyXCI6Y2FzZVwidWNzLTJcIjpjYXNlXCJ1dGYxNmxlXCI6Y2FzZVwidXRmLTE2bGVcIjpyZXR1cm4gbGVuKjI7Y2FzZVwiaGV4XCI6cmV0dXJuIGxlbj4+PjE7Y2FzZVwiYmFzZTY0XCI6cmV0dXJuIGJhc2U2NFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGg7ZGVmYXVsdDppZihsb3dlcmVkQ2FzZSlyZXR1cm4gdXRmOFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGg7ZW5jb2Rpbmc9KFwiXCIrZW5jb2RpbmcpLnRvTG93ZXJDYXNlKCk7bG93ZXJlZENhc2U9dHJ1ZX19fUJ1ZmZlci5ieXRlTGVuZ3RoPWJ5dGVMZW5ndGg7ZnVuY3Rpb24gc2xvd1RvU3RyaW5nKGVuY29kaW5nLHN0YXJ0LGVuZCl7dmFyIGxvd2VyZWRDYXNlPWZhbHNlO2lmKHN0YXJ0PT09dW5kZWZpbmVkfHxzdGFydDwwKXtzdGFydD0wfWlmKHN0YXJ0PnRoaXMubGVuZ3RoKXtyZXR1cm5cIlwifWlmKGVuZD09PXVuZGVmaW5lZHx8ZW5kPnRoaXMubGVuZ3RoKXtlbmQ9dGhpcy5sZW5ndGh9aWYoZW5kPD0wKXtyZXR1cm5cIlwifWVuZD4+Pj0wO3N0YXJ0Pj4+PTA7aWYoZW5kPD1zdGFydCl7cmV0dXJuXCJcIn1pZighZW5jb2RpbmcpZW5jb2Rpbmc9XCJ1dGY4XCI7d2hpbGUodHJ1ZSl7c3dpdGNoKGVuY29kaW5nKXtjYXNlXCJoZXhcIjpyZXR1cm4gaGV4U2xpY2UodGhpcyxzdGFydCxlbmQpO2Nhc2VcInV0ZjhcIjpjYXNlXCJ1dGYtOFwiOnJldHVybiB1dGY4U2xpY2UodGhpcyxzdGFydCxlbmQpO2Nhc2VcImFzY2lpXCI6cmV0dXJuIGFzY2lpU2xpY2UodGhpcyxzdGFydCxlbmQpO2Nhc2VcImxhdGluMVwiOmNhc2VcImJpbmFyeVwiOnJldHVybiBsYXRpbjFTbGljZSh0aGlzLHN0YXJ0LGVuZCk7Y2FzZVwiYmFzZTY0XCI6cmV0dXJuIGJhc2U2NFNsaWNlKHRoaXMsc3RhcnQsZW5kKTtjYXNlXCJ1Y3MyXCI6Y2FzZVwidWNzLTJcIjpjYXNlXCJ1dGYxNmxlXCI6Y2FzZVwidXRmLTE2bGVcIjpyZXR1cm4gdXRmMTZsZVNsaWNlKHRoaXMsc3RhcnQsZW5kKTtkZWZhdWx0OmlmKGxvd2VyZWRDYXNlKXRocm93IG5ldyBUeXBlRXJyb3IoXCJVbmtub3duIGVuY29kaW5nOiBcIitlbmNvZGluZyk7ZW5jb2Rpbmc9KGVuY29kaW5nK1wiXCIpLnRvTG93ZXJDYXNlKCk7bG93ZXJlZENhc2U9dHJ1ZX19fUJ1ZmZlci5wcm90b3R5cGUuX2lzQnVmZmVyPXRydWU7ZnVuY3Rpb24gc3dhcChiLG4sbSl7dmFyIGk9YltuXTtiW25dPWJbbV07YlttXT1pfUJ1ZmZlci5wcm90b3R5cGUuc3dhcDE2PWZ1bmN0aW9uIHN3YXAxNigpe3ZhciBsZW49dGhpcy5sZW5ndGg7aWYobGVuJTIhPT0wKXt0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkJ1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiAxNi1iaXRzXCIpfWZvcih2YXIgaT0wO2k8bGVuO2krPTIpe3N3YXAodGhpcyxpLGkrMSl9cmV0dXJuIHRoaXN9O0J1ZmZlci5wcm90b3R5cGUuc3dhcDMyPWZ1bmN0aW9uIHN3YXAzMigpe3ZhciBsZW49dGhpcy5sZW5ndGg7aWYobGVuJTQhPT0wKXt0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkJ1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiAzMi1iaXRzXCIpfWZvcih2YXIgaT0wO2k8bGVuO2krPTQpe3N3YXAodGhpcyxpLGkrMyk7c3dhcCh0aGlzLGkrMSxpKzIpfXJldHVybiB0aGlzfTtCdWZmZXIucHJvdG90eXBlLnN3YXA2ND1mdW5jdGlvbiBzd2FwNjQoKXt2YXIgbGVuPXRoaXMubGVuZ3RoO2lmKGxlbiU4IT09MCl7dGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNjQtYml0c1wiKX1mb3IodmFyIGk9MDtpPGxlbjtpKz04KXtzd2FwKHRoaXMsaSxpKzcpO3N3YXAodGhpcyxpKzEsaSs2KTtzd2FwKHRoaXMsaSsyLGkrNSk7c3dhcCh0aGlzLGkrMyxpKzQpfXJldHVybiB0aGlzfTtCdWZmZXIucHJvdG90eXBlLnRvU3RyaW5nPWZ1bmN0aW9uIHRvU3RyaW5nKCl7dmFyIGxlbmd0aD10aGlzLmxlbmd0aHwwO2lmKGxlbmd0aD09PTApcmV0dXJuXCJcIjtpZihhcmd1bWVudHMubGVuZ3RoPT09MClyZXR1cm4gdXRmOFNsaWNlKHRoaXMsMCxsZW5ndGgpO3JldHVybiBzbG93VG9TdHJpbmcuYXBwbHkodGhpcyxhcmd1bWVudHMpfTtCdWZmZXIucHJvdG90eXBlLmVxdWFscz1mdW5jdGlvbiBlcXVhbHMoYil7aWYoIUJ1ZmZlci5pc0J1ZmZlcihiKSl0aHJvdyBuZXcgVHlwZUVycm9yKFwiQXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlclwiKTtpZih0aGlzPT09YilyZXR1cm4gdHJ1ZTtyZXR1cm4gQnVmZmVyLmNvbXBhcmUodGhpcyxiKT09PTB9O0J1ZmZlci5wcm90b3R5cGUuaW5zcGVjdD1mdW5jdGlvbiBpbnNwZWN0KCl7dmFyIHN0cj1cIlwiO3ZhciBtYXg9ZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUztpZih0aGlzLmxlbmd0aD4wKXtzdHI9dGhpcy50b1N0cmluZyhcImhleFwiLDAsbWF4KS5tYXRjaCgvLnsyfS9nKS5qb2luKFwiIFwiKTtpZih0aGlzLmxlbmd0aD5tYXgpc3RyKz1cIiAuLi4gXCJ9cmV0dXJuXCI8QnVmZmVyIFwiK3N0citcIj5cIn07QnVmZmVyLnByb3RvdHlwZS5jb21wYXJlPWZ1bmN0aW9uIGNvbXBhcmUodGFyZ2V0LHN0YXJ0LGVuZCx0aGlzU3RhcnQsdGhpc0VuZCl7aWYoIUJ1ZmZlci5pc0J1ZmZlcih0YXJnZXQpKXt0aHJvdyBuZXcgVHlwZUVycm9yKFwiQXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlclwiKX1pZihzdGFydD09PXVuZGVmaW5lZCl7c3RhcnQ9MH1pZihlbmQ9PT11bmRlZmluZWQpe2VuZD10YXJnZXQ/dGFyZ2V0Lmxlbmd0aDowfWlmKHRoaXNTdGFydD09PXVuZGVmaW5lZCl7dGhpc1N0YXJ0PTB9aWYodGhpc0VuZD09PXVuZGVmaW5lZCl7dGhpc0VuZD10aGlzLmxlbmd0aH1pZihzdGFydDwwfHxlbmQ+dGFyZ2V0Lmxlbmd0aHx8dGhpc1N0YXJ0PDB8fHRoaXNFbmQ+dGhpcy5sZW5ndGgpe3Rocm93IG5ldyBSYW5nZUVycm9yKFwib3V0IG9mIHJhbmdlIGluZGV4XCIpfWlmKHRoaXNTdGFydD49dGhpc0VuZCYmc3RhcnQ+PWVuZCl7cmV0dXJuIDB9aWYodGhpc1N0YXJ0Pj10aGlzRW5kKXtyZXR1cm4tMX1pZihzdGFydD49ZW5kKXtyZXR1cm4gMX1zdGFydD4+Pj0wO2VuZD4+Pj0wO3RoaXNTdGFydD4+Pj0wO3RoaXNFbmQ+Pj49MDtpZih0aGlzPT09dGFyZ2V0KXJldHVybiAwO3ZhciB4PXRoaXNFbmQtdGhpc1N0YXJ0O3ZhciB5PWVuZC1zdGFydDt2YXIgbGVuPU1hdGgubWluKHgseSk7dmFyIHRoaXNDb3B5PXRoaXMuc2xpY2UodGhpc1N0YXJ0LHRoaXNFbmQpO3ZhciB0YXJnZXRDb3B5PXRhcmdldC5zbGljZShzdGFydCxlbmQpO2Zvcih2YXIgaT0wO2k8bGVuOysraSl7aWYodGhpc0NvcHlbaV0hPT10YXJnZXRDb3B5W2ldKXt4PXRoaXNDb3B5W2ldO3k9dGFyZ2V0Q29weVtpXTticmVha319aWYoeDx5KXJldHVybi0xO2lmKHk8eClyZXR1cm4gMTtyZXR1cm4gMH07ZnVuY3Rpb24gYmlkaXJlY3Rpb25hbEluZGV4T2YoYnVmZmVyLHZhbCxieXRlT2Zmc2V0LGVuY29kaW5nLGRpcil7aWYoYnVmZmVyLmxlbmd0aD09PTApcmV0dXJuLTE7aWYodHlwZW9mIGJ5dGVPZmZzZXQ9PT1cInN0cmluZ1wiKXtlbmNvZGluZz1ieXRlT2Zmc2V0O2J5dGVPZmZzZXQ9MH1lbHNlIGlmKGJ5dGVPZmZzZXQ+MjE0NzQ4MzY0Nyl7Ynl0ZU9mZnNldD0yMTQ3NDgzNjQ3fWVsc2UgaWYoYnl0ZU9mZnNldDwtMjE0NzQ4MzY0OCl7Ynl0ZU9mZnNldD0tMjE0NzQ4MzY0OH1ieXRlT2Zmc2V0PStieXRlT2Zmc2V0O2lmKGlzTmFOKGJ5dGVPZmZzZXQpKXtieXRlT2Zmc2V0PWRpcj8wOmJ1ZmZlci5sZW5ndGgtMX1pZihieXRlT2Zmc2V0PDApYnl0ZU9mZnNldD1idWZmZXIubGVuZ3RoK2J5dGVPZmZzZXQ7aWYoYnl0ZU9mZnNldD49YnVmZmVyLmxlbmd0aCl7aWYoZGlyKXJldHVybi0xO2Vsc2UgYnl0ZU9mZnNldD1idWZmZXIubGVuZ3RoLTF9ZWxzZSBpZihieXRlT2Zmc2V0PDApe2lmKGRpcilieXRlT2Zmc2V0PTA7ZWxzZSByZXR1cm4tMX1pZih0eXBlb2YgdmFsPT09XCJzdHJpbmdcIil7dmFsPUJ1ZmZlci5mcm9tKHZhbCxlbmNvZGluZyl9aWYoQnVmZmVyLmlzQnVmZmVyKHZhbCkpe2lmKHZhbC5sZW5ndGg9PT0wKXtyZXR1cm4tMX1yZXR1cm4gYXJyYXlJbmRleE9mKGJ1ZmZlcix2YWwsYnl0ZU9mZnNldCxlbmNvZGluZyxkaXIpfWVsc2UgaWYodHlwZW9mIHZhbD09PVwibnVtYmVyXCIpe3ZhbD12YWwmMjU1O2lmKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUJiZ0eXBlb2YgVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZj09PVwiZnVuY3Rpb25cIil7aWYoZGlyKXtyZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKGJ1ZmZlcix2YWwsYnl0ZU9mZnNldCl9ZWxzZXtyZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUubGFzdEluZGV4T2YuY2FsbChidWZmZXIsdmFsLGJ5dGVPZmZzZXQpfX1yZXR1cm4gYXJyYXlJbmRleE9mKGJ1ZmZlcixbdmFsXSxieXRlT2Zmc2V0LGVuY29kaW5nLGRpcil9dGhyb3cgbmV3IFR5cGVFcnJvcihcInZhbCBtdXN0IGJlIHN0cmluZywgbnVtYmVyIG9yIEJ1ZmZlclwiKX1mdW5jdGlvbiBhcnJheUluZGV4T2YoYXJyLHZhbCxieXRlT2Zmc2V0LGVuY29kaW5nLGRpcil7dmFyIGluZGV4U2l6ZT0xO3ZhciBhcnJMZW5ndGg9YXJyLmxlbmd0aDt2YXIgdmFsTGVuZ3RoPXZhbC5sZW5ndGg7aWYoZW5jb2RpbmchPT11bmRlZmluZWQpe2VuY29kaW5nPVN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKTtpZihlbmNvZGluZz09PVwidWNzMlwifHxlbmNvZGluZz09PVwidWNzLTJcInx8ZW5jb2Rpbmc9PT1cInV0ZjE2bGVcInx8ZW5jb2Rpbmc9PT1cInV0Zi0xNmxlXCIpe2lmKGFyci5sZW5ndGg8Mnx8dmFsLmxlbmd0aDwyKXtyZXR1cm4tMX1pbmRleFNpemU9MjthcnJMZW5ndGgvPTI7dmFsTGVuZ3RoLz0yO2J5dGVPZmZzZXQvPTJ9fWZ1bmN0aW9uIHJlYWQoYnVmLGkpe2lmKGluZGV4U2l6ZT09PTEpe3JldHVybiBidWZbaV19ZWxzZXtyZXR1cm4gYnVmLnJlYWRVSW50MTZCRShpKmluZGV4U2l6ZSl9fXZhciBpO2lmKGRpcil7dmFyIGZvdW5kSW5kZXg9LTE7Zm9yKGk9Ynl0ZU9mZnNldDtpPGFyckxlbmd0aDtpKyspe2lmKHJlYWQoYXJyLGkpPT09cmVhZCh2YWwsZm91bmRJbmRleD09PS0xPzA6aS1mb3VuZEluZGV4KSl7aWYoZm91bmRJbmRleD09PS0xKWZvdW5kSW5kZXg9aTtpZihpLWZvdW5kSW5kZXgrMT09PXZhbExlbmd0aClyZXR1cm4gZm91bmRJbmRleCppbmRleFNpemV9ZWxzZXtpZihmb3VuZEluZGV4IT09LTEpaS09aS1mb3VuZEluZGV4O2ZvdW5kSW5kZXg9LTF9fX1lbHNle2lmKGJ5dGVPZmZzZXQrdmFsTGVuZ3RoPmFyckxlbmd0aClieXRlT2Zmc2V0PWFyckxlbmd0aC12YWxMZW5ndGg7Zm9yKGk9Ynl0ZU9mZnNldDtpPj0wO2ktLSl7dmFyIGZvdW5kPXRydWU7Zm9yKHZhciBqPTA7ajx2YWxMZW5ndGg7aisrKXtpZihyZWFkKGFycixpK2opIT09cmVhZCh2YWwsaikpe2ZvdW5kPWZhbHNlO2JyZWFrfX1pZihmb3VuZClyZXR1cm4gaX19cmV0dXJuLTF9QnVmZmVyLnByb3RvdHlwZS5pbmNsdWRlcz1mdW5jdGlvbiBpbmNsdWRlcyh2YWwsYnl0ZU9mZnNldCxlbmNvZGluZyl7cmV0dXJuIHRoaXMuaW5kZXhPZih2YWwsYnl0ZU9mZnNldCxlbmNvZGluZykhPT0tMX07QnVmZmVyLnByb3RvdHlwZS5pbmRleE9mPWZ1bmN0aW9uIGluZGV4T2YodmFsLGJ5dGVPZmZzZXQsZW5jb2Rpbmcpe3JldHVybiBiaWRpcmVjdGlvbmFsSW5kZXhPZih0aGlzLHZhbCxieXRlT2Zmc2V0LGVuY29kaW5nLHRydWUpfTtCdWZmZXIucHJvdG90eXBlLmxhc3RJbmRleE9mPWZ1bmN0aW9uIGxhc3RJbmRleE9mKHZhbCxieXRlT2Zmc2V0LGVuY29kaW5nKXtyZXR1cm4gYmlkaXJlY3Rpb25hbEluZGV4T2YodGhpcyx2YWwsYnl0ZU9mZnNldCxlbmNvZGluZyxmYWxzZSl9O2Z1bmN0aW9uIGhleFdyaXRlKGJ1ZixzdHJpbmcsb2Zmc2V0LGxlbmd0aCl7b2Zmc2V0PU51bWJlcihvZmZzZXQpfHwwO3ZhciByZW1haW5pbmc9YnVmLmxlbmd0aC1vZmZzZXQ7aWYoIWxlbmd0aCl7bGVuZ3RoPXJlbWFpbmluZ31lbHNle2xlbmd0aD1OdW1iZXIobGVuZ3RoKTtpZihsZW5ndGg+cmVtYWluaW5nKXtsZW5ndGg9cmVtYWluaW5nfX12YXIgc3RyTGVuPXN0cmluZy5sZW5ndGg7aWYoc3RyTGVuJTIhPT0wKXRocm93IG5ldyBUeXBlRXJyb3IoXCJJbnZhbGlkIGhleCBzdHJpbmdcIik7aWYobGVuZ3RoPnN0ckxlbi8yKXtsZW5ndGg9c3RyTGVuLzJ9Zm9yKHZhciBpPTA7aTxsZW5ndGg7KytpKXt2YXIgcGFyc2VkPXBhcnNlSW50KHN0cmluZy5zdWJzdHIoaSoyLDIpLDE2KTtpZihpc05hTihwYXJzZWQpKXJldHVybiBpO2J1ZltvZmZzZXQraV09cGFyc2VkfXJldHVybiBpfWZ1bmN0aW9uIHV0ZjhXcml0ZShidWYsc3RyaW5nLG9mZnNldCxsZW5ndGgpe3JldHVybiBibGl0QnVmZmVyKHV0ZjhUb0J5dGVzKHN0cmluZyxidWYubGVuZ3RoLW9mZnNldCksYnVmLG9mZnNldCxsZW5ndGgpfWZ1bmN0aW9uIGFzY2lpV3JpdGUoYnVmLHN0cmluZyxvZmZzZXQsbGVuZ3RoKXtyZXR1cm4gYmxpdEJ1ZmZlcihhc2NpaVRvQnl0ZXMoc3RyaW5nKSxidWYsb2Zmc2V0LGxlbmd0aCl9ZnVuY3Rpb24gbGF0aW4xV3JpdGUoYnVmLHN0cmluZyxvZmZzZXQsbGVuZ3RoKXtyZXR1cm4gYXNjaWlXcml0ZShidWYsc3RyaW5nLG9mZnNldCxsZW5ndGgpfWZ1bmN0aW9uIGJhc2U2NFdyaXRlKGJ1ZixzdHJpbmcsb2Zmc2V0LGxlbmd0aCl7cmV0dXJuIGJsaXRCdWZmZXIoYmFzZTY0VG9CeXRlcyhzdHJpbmcpLGJ1ZixvZmZzZXQsbGVuZ3RoKX1mdW5jdGlvbiB1Y3MyV3JpdGUoYnVmLHN0cmluZyxvZmZzZXQsbGVuZ3RoKXtyZXR1cm4gYmxpdEJ1ZmZlcih1dGYxNmxlVG9CeXRlcyhzdHJpbmcsYnVmLmxlbmd0aC1vZmZzZXQpLGJ1ZixvZmZzZXQsbGVuZ3RoKX1CdWZmZXIucHJvdG90eXBlLndyaXRlPWZ1bmN0aW9uIHdyaXRlKHN0cmluZyxvZmZzZXQsbGVuZ3RoLGVuY29kaW5nKXtpZihvZmZzZXQ9PT11bmRlZmluZWQpe2VuY29kaW5nPVwidXRmOFwiO2xlbmd0aD10aGlzLmxlbmd0aDtvZmZzZXQ9MH1lbHNlIGlmKGxlbmd0aD09PXVuZGVmaW5lZCYmdHlwZW9mIG9mZnNldD09PVwic3RyaW5nXCIpe2VuY29kaW5nPW9mZnNldDtsZW5ndGg9dGhpcy5sZW5ndGg7b2Zmc2V0PTB9ZWxzZSBpZihpc0Zpbml0ZShvZmZzZXQpKXtvZmZzZXQ9b2Zmc2V0fDA7aWYoaXNGaW5pdGUobGVuZ3RoKSl7bGVuZ3RoPWxlbmd0aHwwO2lmKGVuY29kaW5nPT09dW5kZWZpbmVkKWVuY29kaW5nPVwidXRmOFwifWVsc2V7ZW5jb2Rpbmc9bGVuZ3RoO2xlbmd0aD11bmRlZmluZWR9fWVsc2V7dGhyb3cgbmV3IEVycm9yKFwiQnVmZmVyLndyaXRlKHN0cmluZywgZW5jb2RpbmcsIG9mZnNldFssIGxlbmd0aF0pIGlzIG5vIGxvbmdlciBzdXBwb3J0ZWRcIil9dmFyIHJlbWFpbmluZz10aGlzLmxlbmd0aC1vZmZzZXQ7aWYobGVuZ3RoPT09dW5kZWZpbmVkfHxsZW5ndGg+cmVtYWluaW5nKWxlbmd0aD1yZW1haW5pbmc7aWYoc3RyaW5nLmxlbmd0aD4wJiYobGVuZ3RoPDB8fG9mZnNldDwwKXx8b2Zmc2V0PnRoaXMubGVuZ3RoKXt0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkF0dGVtcHQgdG8gd3JpdGUgb3V0c2lkZSBidWZmZXIgYm91bmRzXCIpfWlmKCFlbmNvZGluZyllbmNvZGluZz1cInV0ZjhcIjt2YXIgbG93ZXJlZENhc2U9ZmFsc2U7Zm9yKDs7KXtzd2l0Y2goZW5jb2Rpbmcpe2Nhc2VcImhleFwiOnJldHVybiBoZXhXcml0ZSh0aGlzLHN0cmluZyxvZmZzZXQsbGVuZ3RoKTtjYXNlXCJ1dGY4XCI6Y2FzZVwidXRmLThcIjpyZXR1cm4gdXRmOFdyaXRlKHRoaXMsc3RyaW5nLG9mZnNldCxsZW5ndGgpO2Nhc2VcImFzY2lpXCI6cmV0dXJuIGFzY2lpV3JpdGUodGhpcyxzdHJpbmcsb2Zmc2V0LGxlbmd0aCk7Y2FzZVwibGF0aW4xXCI6Y2FzZVwiYmluYXJ5XCI6cmV0dXJuIGxhdGluMVdyaXRlKHRoaXMsc3RyaW5nLG9mZnNldCxsZW5ndGgpO2Nhc2VcImJhc2U2NFwiOnJldHVybiBiYXNlNjRXcml0ZSh0aGlzLHN0cmluZyxvZmZzZXQsbGVuZ3RoKTtjYXNlXCJ1Y3MyXCI6Y2FzZVwidWNzLTJcIjpjYXNlXCJ1dGYxNmxlXCI6Y2FzZVwidXRmLTE2bGVcIjpyZXR1cm4gdWNzMldyaXRlKHRoaXMsc3RyaW5nLG9mZnNldCxsZW5ndGgpO2RlZmF1bHQ6aWYobG93ZXJlZENhc2UpdGhyb3cgbmV3IFR5cGVFcnJvcihcIlVua25vd24gZW5jb2Rpbmc6IFwiK2VuY29kaW5nKTtlbmNvZGluZz0oXCJcIitlbmNvZGluZykudG9Mb3dlckNhc2UoKTtsb3dlcmVkQ2FzZT10cnVlfX19O0J1ZmZlci5wcm90b3R5cGUudG9KU09OPWZ1bmN0aW9uIHRvSlNPTigpe3JldHVybnt0eXBlOlwiQnVmZmVyXCIsZGF0YTpBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCh0aGlzLl9hcnJ8fHRoaXMsMCl9fTtmdW5jdGlvbiBiYXNlNjRTbGljZShidWYsc3RhcnQsZW5kKXtpZihzdGFydD09PTAmJmVuZD09PWJ1Zi5sZW5ndGgpe3JldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYpfWVsc2V7cmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1Zi5zbGljZShzdGFydCxlbmQpKX19ZnVuY3Rpb24gdXRmOFNsaWNlKGJ1ZixzdGFydCxlbmQpe2VuZD1NYXRoLm1pbihidWYubGVuZ3RoLGVuZCk7dmFyIHJlcz1bXTt2YXIgaT1zdGFydDt3aGlsZShpPGVuZCl7dmFyIGZpcnN0Qnl0ZT1idWZbaV07dmFyIGNvZGVQb2ludD1udWxsO3ZhciBieXRlc1BlclNlcXVlbmNlPWZpcnN0Qnl0ZT4yMzk/NDpmaXJzdEJ5dGU+MjIzPzM6Zmlyc3RCeXRlPjE5MT8yOjE7aWYoaStieXRlc1BlclNlcXVlbmNlPD1lbmQpe3ZhciBzZWNvbmRCeXRlLHRoaXJkQnl0ZSxmb3VydGhCeXRlLHRlbXBDb2RlUG9pbnQ7c3dpdGNoKGJ5dGVzUGVyU2VxdWVuY2Upe2Nhc2UgMTppZihmaXJzdEJ5dGU8MTI4KXtjb2RlUG9pbnQ9Zmlyc3RCeXRlfWJyZWFrO2Nhc2UgMjpzZWNvbmRCeXRlPWJ1ZltpKzFdO2lmKChzZWNvbmRCeXRlJjE5Mik9PT0xMjgpe3RlbXBDb2RlUG9pbnQ9KGZpcnN0Qnl0ZSYzMSk8PDZ8c2Vjb25kQnl0ZSY2MztpZih0ZW1wQ29kZVBvaW50PjEyNyl7Y29kZVBvaW50PXRlbXBDb2RlUG9pbnR9fWJyZWFrO2Nhc2UgMzpzZWNvbmRCeXRlPWJ1ZltpKzFdO3RoaXJkQnl0ZT1idWZbaSsyXTtpZigoc2Vjb25kQnl0ZSYxOTIpPT09MTI4JiYodGhpcmRCeXRlJjE5Mik9PT0xMjgpe3RlbXBDb2RlUG9pbnQ9KGZpcnN0Qnl0ZSYxNSk8PDEyfChzZWNvbmRCeXRlJjYzKTw8Nnx0aGlyZEJ5dGUmNjM7aWYodGVtcENvZGVQb2ludD4yMDQ3JiYodGVtcENvZGVQb2ludDw1NTI5Nnx8dGVtcENvZGVQb2ludD41NzM0Mykpe2NvZGVQb2ludD10ZW1wQ29kZVBvaW50fX1icmVhaztjYXNlIDQ6c2Vjb25kQnl0ZT1idWZbaSsxXTt0aGlyZEJ5dGU9YnVmW2krMl07Zm91cnRoQnl0ZT1idWZbaSszXTtpZigoc2Vjb25kQnl0ZSYxOTIpPT09MTI4JiYodGhpcmRCeXRlJjE5Mik9PT0xMjgmJihmb3VydGhCeXRlJjE5Mik9PT0xMjgpe3RlbXBDb2RlUG9pbnQ9KGZpcnN0Qnl0ZSYxNSk8PDE4fChzZWNvbmRCeXRlJjYzKTw8MTJ8KHRoaXJkQnl0ZSY2Myk8PDZ8Zm91cnRoQnl0ZSY2MztpZih0ZW1wQ29kZVBvaW50PjY1NTM1JiZ0ZW1wQ29kZVBvaW50PDExMTQxMTIpe2NvZGVQb2ludD10ZW1wQ29kZVBvaW50fX19fWlmKGNvZGVQb2ludD09PW51bGwpe2NvZGVQb2ludD02NTUzMztieXRlc1BlclNlcXVlbmNlPTF9ZWxzZSBpZihjb2RlUG9pbnQ+NjU1MzUpe2NvZGVQb2ludC09NjU1MzY7cmVzLnB1c2goY29kZVBvaW50Pj4+MTAmMTAyM3w1NTI5Nik7Y29kZVBvaW50PTU2MzIwfGNvZGVQb2ludCYxMDIzfXJlcy5wdXNoKGNvZGVQb2ludCk7aSs9Ynl0ZXNQZXJTZXF1ZW5jZX1yZXR1cm4gZGVjb2RlQ29kZVBvaW50c0FycmF5KHJlcyl9dmFyIE1BWF9BUkdVTUVOVFNfTEVOR1RIPTQwOTY7ZnVuY3Rpb24gZGVjb2RlQ29kZVBvaW50c0FycmF5KGNvZGVQb2ludHMpe3ZhciBsZW49Y29kZVBvaW50cy5sZW5ndGg7aWYobGVuPD1NQVhfQVJHVU1FTlRTX0xFTkdUSCl7cmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLGNvZGVQb2ludHMpfXZhciByZXM9XCJcIjt2YXIgaT0wO3doaWxlKGk8bGVuKXtyZXMrPVN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLGNvZGVQb2ludHMuc2xpY2UoaSxpKz1NQVhfQVJHVU1FTlRTX0xFTkdUSCkpfXJldHVybiByZXN9ZnVuY3Rpb24gYXNjaWlTbGljZShidWYsc3RhcnQsZW5kKXt2YXIgcmV0PVwiXCI7ZW5kPU1hdGgubWluKGJ1Zi5sZW5ndGgsZW5kKTtmb3IodmFyIGk9c3RhcnQ7aTxlbmQ7KytpKXtyZXQrPVN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldJjEyNyl9cmV0dXJuIHJldH1mdW5jdGlvbiBsYXRpbjFTbGljZShidWYsc3RhcnQsZW5kKXt2YXIgcmV0PVwiXCI7ZW5kPU1hdGgubWluKGJ1Zi5sZW5ndGgsZW5kKTtmb3IodmFyIGk9c3RhcnQ7aTxlbmQ7KytpKXtyZXQrPVN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldKX1yZXR1cm4gcmV0fWZ1bmN0aW9uIGhleFNsaWNlKGJ1ZixzdGFydCxlbmQpe3ZhciBsZW49YnVmLmxlbmd0aDtpZighc3RhcnR8fHN0YXJ0PDApc3RhcnQ9MDtpZighZW5kfHxlbmQ8MHx8ZW5kPmxlbillbmQ9bGVuO3ZhciBvdXQ9XCJcIjtmb3IodmFyIGk9c3RhcnQ7aTxlbmQ7KytpKXtvdXQrPXRvSGV4KGJ1ZltpXSl9cmV0dXJuIG91dH1mdW5jdGlvbiB1dGYxNmxlU2xpY2UoYnVmLHN0YXJ0LGVuZCl7dmFyIGJ5dGVzPWJ1Zi5zbGljZShzdGFydCxlbmQpO3ZhciByZXM9XCJcIjtmb3IodmFyIGk9MDtpPGJ5dGVzLmxlbmd0aDtpKz0yKXtyZXMrPVN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZXNbaV0rYnl0ZXNbaSsxXSoyNTYpfXJldHVybiByZXN9QnVmZmVyLnByb3RvdHlwZS5zbGljZT1mdW5jdGlvbiBzbGljZShzdGFydCxlbmQpe3ZhciBsZW49dGhpcy5sZW5ndGg7c3RhcnQ9fn5zdGFydDtlbmQ9ZW5kPT09dW5kZWZpbmVkP2xlbjp+fmVuZDtpZihzdGFydDwwKXtzdGFydCs9bGVuO2lmKHN0YXJ0PDApc3RhcnQ9MH1lbHNlIGlmKHN0YXJ0Pmxlbil7c3RhcnQ9bGVufWlmKGVuZDwwKXtlbmQrPWxlbjtpZihlbmQ8MCllbmQ9MH1lbHNlIGlmKGVuZD5sZW4pe2VuZD1sZW59aWYoZW5kPHN0YXJ0KWVuZD1zdGFydDt2YXIgbmV3QnVmO2lmKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKXtuZXdCdWY9dGhpcy5zdWJhcnJheShzdGFydCxlbmQpO25ld0J1Zi5fX3Byb3RvX189QnVmZmVyLnByb3RvdHlwZX1lbHNle3ZhciBzbGljZUxlbj1lbmQtc3RhcnQ7bmV3QnVmPW5ldyBCdWZmZXIoc2xpY2VMZW4sdW5kZWZpbmVkKTtmb3IodmFyIGk9MDtpPHNsaWNlTGVuOysraSl7bmV3QnVmW2ldPXRoaXNbaStzdGFydF19fXJldHVybiBuZXdCdWZ9O2Z1bmN0aW9uIGNoZWNrT2Zmc2V0KG9mZnNldCxleHQsbGVuZ3RoKXtpZihvZmZzZXQlMSE9PTB8fG9mZnNldDwwKXRocm93IG5ldyBSYW5nZUVycm9yKFwib2Zmc2V0IGlzIG5vdCB1aW50XCIpO2lmKG9mZnNldCtleHQ+bGVuZ3RoKXRocm93IG5ldyBSYW5nZUVycm9yKFwiVHJ5aW5nIHRvIGFjY2VzcyBiZXlvbmQgYnVmZmVyIGxlbmd0aFwiKX1CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50TEU9ZnVuY3Rpb24gcmVhZFVJbnRMRShvZmZzZXQsYnl0ZUxlbmd0aCxub0Fzc2VydCl7b2Zmc2V0PW9mZnNldHwwO2J5dGVMZW5ndGg9Ynl0ZUxlbmd0aHwwO2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsYnl0ZUxlbmd0aCx0aGlzLmxlbmd0aCk7dmFyIHZhbD10aGlzW29mZnNldF07dmFyIG11bD0xO3ZhciBpPTA7d2hpbGUoKytpPGJ5dGVMZW5ndGgmJihtdWwqPTI1Nikpe3ZhbCs9dGhpc1tvZmZzZXQraV0qbXVsfXJldHVybiB2YWx9O0J1ZmZlci5wcm90b3R5cGUucmVhZFVJbnRCRT1mdW5jdGlvbiByZWFkVUludEJFKG9mZnNldCxieXRlTGVuZ3RoLG5vQXNzZXJ0KXtvZmZzZXQ9b2Zmc2V0fDA7Ynl0ZUxlbmd0aD1ieXRlTGVuZ3RofDA7aWYoIW5vQXNzZXJ0KXtjaGVja09mZnNldChvZmZzZXQsYnl0ZUxlbmd0aCx0aGlzLmxlbmd0aCl9dmFyIHZhbD10aGlzW29mZnNldCstLWJ5dGVMZW5ndGhdO3ZhciBtdWw9MTt3aGlsZShieXRlTGVuZ3RoPjAmJihtdWwqPTI1Nikpe3ZhbCs9dGhpc1tvZmZzZXQrLS1ieXRlTGVuZ3RoXSptdWx9cmV0dXJuIHZhbH07QnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDg9ZnVuY3Rpb24gcmVhZFVJbnQ4KG9mZnNldCxub0Fzc2VydCl7aWYoIW5vQXNzZXJ0KWNoZWNrT2Zmc2V0KG9mZnNldCwxLHRoaXMubGVuZ3RoKTtyZXR1cm4gdGhpc1tvZmZzZXRdfTtCdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZMRT1mdW5jdGlvbiByZWFkVUludDE2TEUob2Zmc2V0LG5vQXNzZXJ0KXtpZighbm9Bc3NlcnQpY2hlY2tPZmZzZXQob2Zmc2V0LDIsdGhpcy5sZW5ndGgpO3JldHVybiB0aGlzW29mZnNldF18dGhpc1tvZmZzZXQrMV08PDh9O0J1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkJFPWZ1bmN0aW9uIHJlYWRVSW50MTZCRShvZmZzZXQsbm9Bc3NlcnQpe2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsMix0aGlzLmxlbmd0aCk7cmV0dXJuIHRoaXNbb2Zmc2V0XTw8OHx0aGlzW29mZnNldCsxXX07QnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyTEU9ZnVuY3Rpb24gcmVhZFVJbnQzMkxFKG9mZnNldCxub0Fzc2VydCl7aWYoIW5vQXNzZXJ0KWNoZWNrT2Zmc2V0KG9mZnNldCw0LHRoaXMubGVuZ3RoKTtyZXR1cm4odGhpc1tvZmZzZXRdfHRoaXNbb2Zmc2V0KzFdPDw4fHRoaXNbb2Zmc2V0KzJdPDwxNikrdGhpc1tvZmZzZXQrM10qMTY3NzcyMTZ9O0J1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkJFPWZ1bmN0aW9uIHJlYWRVSW50MzJCRShvZmZzZXQsbm9Bc3NlcnQpe2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsNCx0aGlzLmxlbmd0aCk7cmV0dXJuIHRoaXNbb2Zmc2V0XSoxNjc3NzIxNisodGhpc1tvZmZzZXQrMV08PDE2fHRoaXNbb2Zmc2V0KzJdPDw4fHRoaXNbb2Zmc2V0KzNdKX07QnVmZmVyLnByb3RvdHlwZS5yZWFkSW50TEU9ZnVuY3Rpb24gcmVhZEludExFKG9mZnNldCxieXRlTGVuZ3RoLG5vQXNzZXJ0KXtvZmZzZXQ9b2Zmc2V0fDA7Ynl0ZUxlbmd0aD1ieXRlTGVuZ3RofDA7aWYoIW5vQXNzZXJ0KWNoZWNrT2Zmc2V0KG9mZnNldCxieXRlTGVuZ3RoLHRoaXMubGVuZ3RoKTt2YXIgdmFsPXRoaXNbb2Zmc2V0XTt2YXIgbXVsPTE7dmFyIGk9MDt3aGlsZSgrK2k8Ynl0ZUxlbmd0aCYmKG11bCo9MjU2KSl7dmFsKz10aGlzW29mZnNldCtpXSptdWx9bXVsKj0xMjg7aWYodmFsPj1tdWwpdmFsLT1NYXRoLnBvdygyLDgqYnl0ZUxlbmd0aCk7cmV0dXJuIHZhbH07QnVmZmVyLnByb3RvdHlwZS5yZWFkSW50QkU9ZnVuY3Rpb24gcmVhZEludEJFKG9mZnNldCxieXRlTGVuZ3RoLG5vQXNzZXJ0KXtvZmZzZXQ9b2Zmc2V0fDA7Ynl0ZUxlbmd0aD1ieXRlTGVuZ3RofDA7aWYoIW5vQXNzZXJ0KWNoZWNrT2Zmc2V0KG9mZnNldCxieXRlTGVuZ3RoLHRoaXMubGVuZ3RoKTtcbnZhciBpPWJ5dGVMZW5ndGg7dmFyIG11bD0xO3ZhciB2YWw9dGhpc1tvZmZzZXQrLS1pXTt3aGlsZShpPjAmJihtdWwqPTI1Nikpe3ZhbCs9dGhpc1tvZmZzZXQrLS1pXSptdWx9bXVsKj0xMjg7aWYodmFsPj1tdWwpdmFsLT1NYXRoLnBvdygyLDgqYnl0ZUxlbmd0aCk7cmV0dXJuIHZhbH07QnVmZmVyLnByb3RvdHlwZS5yZWFkSW50OD1mdW5jdGlvbiByZWFkSW50OChvZmZzZXQsbm9Bc3NlcnQpe2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsMSx0aGlzLmxlbmd0aCk7aWYoISh0aGlzW29mZnNldF0mMTI4KSlyZXR1cm4gdGhpc1tvZmZzZXRdO3JldHVybigyNTUtdGhpc1tvZmZzZXRdKzEpKi0xfTtCdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkxFPWZ1bmN0aW9uIHJlYWRJbnQxNkxFKG9mZnNldCxub0Fzc2VydCl7aWYoIW5vQXNzZXJ0KWNoZWNrT2Zmc2V0KG9mZnNldCwyLHRoaXMubGVuZ3RoKTt2YXIgdmFsPXRoaXNbb2Zmc2V0XXx0aGlzW29mZnNldCsxXTw8ODtyZXR1cm4gdmFsJjMyNzY4P3ZhbHw0Mjk0OTAxNzYwOnZhbH07QnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZCRT1mdW5jdGlvbiByZWFkSW50MTZCRShvZmZzZXQsbm9Bc3NlcnQpe2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsMix0aGlzLmxlbmd0aCk7dmFyIHZhbD10aGlzW29mZnNldCsxXXx0aGlzW29mZnNldF08PDg7cmV0dXJuIHZhbCYzMjc2OD92YWx8NDI5NDkwMTc2MDp2YWx9O0J1ZmZlci5wcm90b3R5cGUucmVhZEludDMyTEU9ZnVuY3Rpb24gcmVhZEludDMyTEUob2Zmc2V0LG5vQXNzZXJ0KXtpZighbm9Bc3NlcnQpY2hlY2tPZmZzZXQob2Zmc2V0LDQsdGhpcy5sZW5ndGgpO3JldHVybiB0aGlzW29mZnNldF18dGhpc1tvZmZzZXQrMV08PDh8dGhpc1tvZmZzZXQrMl08PDE2fHRoaXNbb2Zmc2V0KzNdPDwyNH07QnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJCRT1mdW5jdGlvbiByZWFkSW50MzJCRShvZmZzZXQsbm9Bc3NlcnQpe2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsNCx0aGlzLmxlbmd0aCk7cmV0dXJuIHRoaXNbb2Zmc2V0XTw8MjR8dGhpc1tvZmZzZXQrMV08PDE2fHRoaXNbb2Zmc2V0KzJdPDw4fHRoaXNbb2Zmc2V0KzNdfTtCdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdExFPWZ1bmN0aW9uIHJlYWRGbG9hdExFKG9mZnNldCxub0Fzc2VydCl7aWYoIW5vQXNzZXJ0KWNoZWNrT2Zmc2V0KG9mZnNldCw0LHRoaXMubGVuZ3RoKTtyZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsb2Zmc2V0LHRydWUsMjMsNCl9O0J1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0QkU9ZnVuY3Rpb24gcmVhZEZsb2F0QkUob2Zmc2V0LG5vQXNzZXJ0KXtpZighbm9Bc3NlcnQpY2hlY2tPZmZzZXQob2Zmc2V0LDQsdGhpcy5sZW5ndGgpO3JldHVybiBpZWVlNzU0LnJlYWQodGhpcyxvZmZzZXQsZmFsc2UsMjMsNCl9O0J1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUxFPWZ1bmN0aW9uIHJlYWREb3VibGVMRShvZmZzZXQsbm9Bc3NlcnQpe2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsOCx0aGlzLmxlbmd0aCk7cmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLG9mZnNldCx0cnVlLDUyLDgpfTtCdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVCRT1mdW5jdGlvbiByZWFkRG91YmxlQkUob2Zmc2V0LG5vQXNzZXJ0KXtpZighbm9Bc3NlcnQpY2hlY2tPZmZzZXQob2Zmc2V0LDgsdGhpcy5sZW5ndGgpO3JldHVybiBpZWVlNzU0LnJlYWQodGhpcyxvZmZzZXQsZmFsc2UsNTIsOCl9O2Z1bmN0aW9uIGNoZWNrSW50KGJ1Zix2YWx1ZSxvZmZzZXQsZXh0LG1heCxtaW4pe2lmKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSl0aHJvdyBuZXcgVHlwZUVycm9yKCdcImJ1ZmZlclwiIGFyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXIgaW5zdGFuY2UnKTtpZih2YWx1ZT5tYXh8fHZhbHVlPG1pbil0aHJvdyBuZXcgUmFuZ2VFcnJvcignXCJ2YWx1ZVwiIGFyZ3VtZW50IGlzIG91dCBvZiBib3VuZHMnKTtpZihvZmZzZXQrZXh0PmJ1Zi5sZW5ndGgpdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbmRleCBvdXQgb2YgcmFuZ2VcIil9QnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRMRT1mdW5jdGlvbiB3cml0ZVVJbnRMRSh2YWx1ZSxvZmZzZXQsYnl0ZUxlbmd0aCxub0Fzc2VydCl7dmFsdWU9K3ZhbHVlO29mZnNldD1vZmZzZXR8MDtieXRlTGVuZ3RoPWJ5dGVMZW5ndGh8MDtpZighbm9Bc3NlcnQpe3ZhciBtYXhCeXRlcz1NYXRoLnBvdygyLDgqYnl0ZUxlbmd0aCktMTtjaGVja0ludCh0aGlzLHZhbHVlLG9mZnNldCxieXRlTGVuZ3RoLG1heEJ5dGVzLDApfXZhciBtdWw9MTt2YXIgaT0wO3RoaXNbb2Zmc2V0XT12YWx1ZSYyNTU7d2hpbGUoKytpPGJ5dGVMZW5ndGgmJihtdWwqPTI1Nikpe3RoaXNbb2Zmc2V0K2ldPXZhbHVlL211bCYyNTV9cmV0dXJuIG9mZnNldCtieXRlTGVuZ3RofTtCdWZmZXIucHJvdG90eXBlLndyaXRlVUludEJFPWZ1bmN0aW9uIHdyaXRlVUludEJFKHZhbHVlLG9mZnNldCxieXRlTGVuZ3RoLG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2J5dGVMZW5ndGg9Ynl0ZUxlbmd0aHwwO2lmKCFub0Fzc2VydCl7dmFyIG1heEJ5dGVzPU1hdGgucG93KDIsOCpieXRlTGVuZ3RoKS0xO2NoZWNrSW50KHRoaXMsdmFsdWUsb2Zmc2V0LGJ5dGVMZW5ndGgsbWF4Qnl0ZXMsMCl9dmFyIGk9Ynl0ZUxlbmd0aC0xO3ZhciBtdWw9MTt0aGlzW29mZnNldCtpXT12YWx1ZSYyNTU7d2hpbGUoLS1pPj0wJiYobXVsKj0yNTYpKXt0aGlzW29mZnNldCtpXT12YWx1ZS9tdWwmMjU1fXJldHVybiBvZmZzZXQrYnl0ZUxlbmd0aH07QnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQ4PWZ1bmN0aW9uIHdyaXRlVUludDgodmFsdWUsb2Zmc2V0LG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2lmKCFub0Fzc2VydCljaGVja0ludCh0aGlzLHZhbHVlLG9mZnNldCwxLDI1NSwwKTtpZighQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpdmFsdWU9TWF0aC5mbG9vcih2YWx1ZSk7dGhpc1tvZmZzZXRdPXZhbHVlJjI1NTtyZXR1cm4gb2Zmc2V0KzF9O2Z1bmN0aW9uIG9iamVjdFdyaXRlVUludDE2KGJ1Zix2YWx1ZSxvZmZzZXQsbGl0dGxlRW5kaWFuKXtpZih2YWx1ZTwwKXZhbHVlPTY1NTM1K3ZhbHVlKzE7Zm9yKHZhciBpPTAsaj1NYXRoLm1pbihidWYubGVuZ3RoLW9mZnNldCwyKTtpPGo7KytpKXtidWZbb2Zmc2V0K2ldPSh2YWx1ZSYyNTU8PDgqKGxpdHRsZUVuZGlhbj9pOjEtaSkpPj4+KGxpdHRsZUVuZGlhbj9pOjEtaSkqOH19QnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkxFPWZ1bmN0aW9uIHdyaXRlVUludDE2TEUodmFsdWUsb2Zmc2V0LG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2lmKCFub0Fzc2VydCljaGVja0ludCh0aGlzLHZhbHVlLG9mZnNldCwyLDY1NTM1LDApO2lmKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKXt0aGlzW29mZnNldF09dmFsdWUmMjU1O3RoaXNbb2Zmc2V0KzFdPXZhbHVlPj4+OH1lbHNle29iamVjdFdyaXRlVUludDE2KHRoaXMsdmFsdWUsb2Zmc2V0LHRydWUpfXJldHVybiBvZmZzZXQrMn07QnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkJFPWZ1bmN0aW9uIHdyaXRlVUludDE2QkUodmFsdWUsb2Zmc2V0LG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2lmKCFub0Fzc2VydCljaGVja0ludCh0aGlzLHZhbHVlLG9mZnNldCwyLDY1NTM1LDApO2lmKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKXt0aGlzW29mZnNldF09dmFsdWU+Pj44O3RoaXNbb2Zmc2V0KzFdPXZhbHVlJjI1NX1lbHNle29iamVjdFdyaXRlVUludDE2KHRoaXMsdmFsdWUsb2Zmc2V0LGZhbHNlKX1yZXR1cm4gb2Zmc2V0KzJ9O2Z1bmN0aW9uIG9iamVjdFdyaXRlVUludDMyKGJ1Zix2YWx1ZSxvZmZzZXQsbGl0dGxlRW5kaWFuKXtpZih2YWx1ZTwwKXZhbHVlPTQyOTQ5NjcyOTUrdmFsdWUrMTtmb3IodmFyIGk9MCxqPU1hdGgubWluKGJ1Zi5sZW5ndGgtb2Zmc2V0LDQpO2k8ajsrK2kpe2J1ZltvZmZzZXQraV09dmFsdWU+Pj4obGl0dGxlRW5kaWFuP2k6My1pKSo4JjI1NX19QnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkxFPWZ1bmN0aW9uIHdyaXRlVUludDMyTEUodmFsdWUsb2Zmc2V0LG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2lmKCFub0Fzc2VydCljaGVja0ludCh0aGlzLHZhbHVlLG9mZnNldCw0LDQyOTQ5NjcyOTUsMCk7aWYoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpe3RoaXNbb2Zmc2V0KzNdPXZhbHVlPj4+MjQ7dGhpc1tvZmZzZXQrMl09dmFsdWU+Pj4xNjt0aGlzW29mZnNldCsxXT12YWx1ZT4+Pjg7dGhpc1tvZmZzZXRdPXZhbHVlJjI1NX1lbHNle29iamVjdFdyaXRlVUludDMyKHRoaXMsdmFsdWUsb2Zmc2V0LHRydWUpfXJldHVybiBvZmZzZXQrNH07QnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkJFPWZ1bmN0aW9uIHdyaXRlVUludDMyQkUodmFsdWUsb2Zmc2V0LG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2lmKCFub0Fzc2VydCljaGVja0ludCh0aGlzLHZhbHVlLG9mZnNldCw0LDQyOTQ5NjcyOTUsMCk7aWYoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpe3RoaXNbb2Zmc2V0XT12YWx1ZT4+PjI0O3RoaXNbb2Zmc2V0KzFdPXZhbHVlPj4+MTY7dGhpc1tvZmZzZXQrMl09dmFsdWU+Pj44O3RoaXNbb2Zmc2V0KzNdPXZhbHVlJjI1NX1lbHNle29iamVjdFdyaXRlVUludDMyKHRoaXMsdmFsdWUsb2Zmc2V0LGZhbHNlKX1yZXR1cm4gb2Zmc2V0KzR9O0J1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRMRT1mdW5jdGlvbiB3cml0ZUludExFKHZhbHVlLG9mZnNldCxieXRlTGVuZ3RoLG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2lmKCFub0Fzc2VydCl7dmFyIGxpbWl0PU1hdGgucG93KDIsOCpieXRlTGVuZ3RoLTEpO2NoZWNrSW50KHRoaXMsdmFsdWUsb2Zmc2V0LGJ5dGVMZW5ndGgsbGltaXQtMSwtbGltaXQpfXZhciBpPTA7dmFyIG11bD0xO3ZhciBzdWI9MDt0aGlzW29mZnNldF09dmFsdWUmMjU1O3doaWxlKCsraTxieXRlTGVuZ3RoJiYobXVsKj0yNTYpKXtpZih2YWx1ZTwwJiZzdWI9PT0wJiZ0aGlzW29mZnNldCtpLTFdIT09MCl7c3ViPTF9dGhpc1tvZmZzZXQraV09KHZhbHVlL211bD4+MCktc3ViJjI1NX1yZXR1cm4gb2Zmc2V0K2J5dGVMZW5ndGh9O0J1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRCRT1mdW5jdGlvbiB3cml0ZUludEJFKHZhbHVlLG9mZnNldCxieXRlTGVuZ3RoLG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2lmKCFub0Fzc2VydCl7dmFyIGxpbWl0PU1hdGgucG93KDIsOCpieXRlTGVuZ3RoLTEpO2NoZWNrSW50KHRoaXMsdmFsdWUsb2Zmc2V0LGJ5dGVMZW5ndGgsbGltaXQtMSwtbGltaXQpfXZhciBpPWJ5dGVMZW5ndGgtMTt2YXIgbXVsPTE7dmFyIHN1Yj0wO3RoaXNbb2Zmc2V0K2ldPXZhbHVlJjI1NTt3aGlsZSgtLWk+PTAmJihtdWwqPTI1Nikpe2lmKHZhbHVlPDAmJnN1Yj09PTAmJnRoaXNbb2Zmc2V0K2krMV0hPT0wKXtzdWI9MX10aGlzW29mZnNldCtpXT0odmFsdWUvbXVsPj4wKS1zdWImMjU1fXJldHVybiBvZmZzZXQrYnl0ZUxlbmd0aH07QnVmZmVyLnByb3RvdHlwZS53cml0ZUludDg9ZnVuY3Rpb24gd3JpdGVJbnQ4KHZhbHVlLG9mZnNldCxub0Fzc2VydCl7dmFsdWU9K3ZhbHVlO29mZnNldD1vZmZzZXR8MDtpZighbm9Bc3NlcnQpY2hlY2tJbnQodGhpcyx2YWx1ZSxvZmZzZXQsMSwxMjcsLTEyOCk7aWYoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKXZhbHVlPU1hdGguZmxvb3IodmFsdWUpO2lmKHZhbHVlPDApdmFsdWU9MjU1K3ZhbHVlKzE7dGhpc1tvZmZzZXRdPXZhbHVlJjI1NTtyZXR1cm4gb2Zmc2V0KzF9O0J1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkxFPWZ1bmN0aW9uIHdyaXRlSW50MTZMRSh2YWx1ZSxvZmZzZXQsbm9Bc3NlcnQpe3ZhbHVlPSt2YWx1ZTtvZmZzZXQ9b2Zmc2V0fDA7aWYoIW5vQXNzZXJ0KWNoZWNrSW50KHRoaXMsdmFsdWUsb2Zmc2V0LDIsMzI3NjcsLTMyNzY4KTtpZihCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCl7dGhpc1tvZmZzZXRdPXZhbHVlJjI1NTt0aGlzW29mZnNldCsxXT12YWx1ZT4+Pjh9ZWxzZXtvYmplY3RXcml0ZVVJbnQxNih0aGlzLHZhbHVlLG9mZnNldCx0cnVlKX1yZXR1cm4gb2Zmc2V0KzJ9O0J1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkJFPWZ1bmN0aW9uIHdyaXRlSW50MTZCRSh2YWx1ZSxvZmZzZXQsbm9Bc3NlcnQpe3ZhbHVlPSt2YWx1ZTtvZmZzZXQ9b2Zmc2V0fDA7aWYoIW5vQXNzZXJ0KWNoZWNrSW50KHRoaXMsdmFsdWUsb2Zmc2V0LDIsMzI3NjcsLTMyNzY4KTtpZihCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCl7dGhpc1tvZmZzZXRdPXZhbHVlPj4+ODt0aGlzW29mZnNldCsxXT12YWx1ZSYyNTV9ZWxzZXtvYmplY3RXcml0ZVVJbnQxNih0aGlzLHZhbHVlLG9mZnNldCxmYWxzZSl9cmV0dXJuIG9mZnNldCsyfTtCdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJMRT1mdW5jdGlvbiB3cml0ZUludDMyTEUodmFsdWUsb2Zmc2V0LG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2lmKCFub0Fzc2VydCljaGVja0ludCh0aGlzLHZhbHVlLG9mZnNldCw0LDIxNDc0ODM2NDcsLTIxNDc0ODM2NDgpO2lmKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKXt0aGlzW29mZnNldF09dmFsdWUmMjU1O3RoaXNbb2Zmc2V0KzFdPXZhbHVlPj4+ODt0aGlzW29mZnNldCsyXT12YWx1ZT4+PjE2O3RoaXNbb2Zmc2V0KzNdPXZhbHVlPj4+MjR9ZWxzZXtvYmplY3RXcml0ZVVJbnQzMih0aGlzLHZhbHVlLG9mZnNldCx0cnVlKX1yZXR1cm4gb2Zmc2V0KzR9O0J1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkJFPWZ1bmN0aW9uIHdyaXRlSW50MzJCRSh2YWx1ZSxvZmZzZXQsbm9Bc3NlcnQpe3ZhbHVlPSt2YWx1ZTtvZmZzZXQ9b2Zmc2V0fDA7aWYoIW5vQXNzZXJ0KWNoZWNrSW50KHRoaXMsdmFsdWUsb2Zmc2V0LDQsMjE0NzQ4MzY0NywtMjE0NzQ4MzY0OCk7aWYodmFsdWU8MCl2YWx1ZT00Mjk0OTY3Mjk1K3ZhbHVlKzE7aWYoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpe3RoaXNbb2Zmc2V0XT12YWx1ZT4+PjI0O3RoaXNbb2Zmc2V0KzFdPXZhbHVlPj4+MTY7dGhpc1tvZmZzZXQrMl09dmFsdWU+Pj44O3RoaXNbb2Zmc2V0KzNdPXZhbHVlJjI1NX1lbHNle29iamVjdFdyaXRlVUludDMyKHRoaXMsdmFsdWUsb2Zmc2V0LGZhbHNlKX1yZXR1cm4gb2Zmc2V0KzR9O2Z1bmN0aW9uIGNoZWNrSUVFRTc1NChidWYsdmFsdWUsb2Zmc2V0LGV4dCxtYXgsbWluKXtpZihvZmZzZXQrZXh0PmJ1Zi5sZW5ndGgpdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbmRleCBvdXQgb2YgcmFuZ2VcIik7aWYob2Zmc2V0PDApdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbmRleCBvdXQgb2YgcmFuZ2VcIil9ZnVuY3Rpb24gd3JpdGVGbG9hdChidWYsdmFsdWUsb2Zmc2V0LGxpdHRsZUVuZGlhbixub0Fzc2VydCl7aWYoIW5vQXNzZXJ0KXtjaGVja0lFRUU3NTQoYnVmLHZhbHVlLG9mZnNldCw0LDMuNDAyODIzNDY2Mzg1Mjg4NmUzOCwtMy40MDI4MjM0NjYzODUyODg2ZTM4KX1pZWVlNzU0LndyaXRlKGJ1Zix2YWx1ZSxvZmZzZXQsbGl0dGxlRW5kaWFuLDIzLDQpO3JldHVybiBvZmZzZXQrNH1CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRMRT1mdW5jdGlvbiB3cml0ZUZsb2F0TEUodmFsdWUsb2Zmc2V0LG5vQXNzZXJ0KXtyZXR1cm4gd3JpdGVGbG9hdCh0aGlzLHZhbHVlLG9mZnNldCx0cnVlLG5vQXNzZXJ0KX07QnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0QkU9ZnVuY3Rpb24gd3JpdGVGbG9hdEJFKHZhbHVlLG9mZnNldCxub0Fzc2VydCl7cmV0dXJuIHdyaXRlRmxvYXQodGhpcyx2YWx1ZSxvZmZzZXQsZmFsc2Usbm9Bc3NlcnQpfTtmdW5jdGlvbiB3cml0ZURvdWJsZShidWYsdmFsdWUsb2Zmc2V0LGxpdHRsZUVuZGlhbixub0Fzc2VydCl7aWYoIW5vQXNzZXJ0KXtjaGVja0lFRUU3NTQoYnVmLHZhbHVlLG9mZnNldCw4LDEuNzk3NjkzMTM0ODYyMzE1N2UzMDgsLTEuNzk3NjkzMTM0ODYyMzE1N2UzMDgpfWllZWU3NTQud3JpdGUoYnVmLHZhbHVlLG9mZnNldCxsaXR0bGVFbmRpYW4sNTIsOCk7cmV0dXJuIG9mZnNldCs4fUJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVMRT1mdW5jdGlvbiB3cml0ZURvdWJsZUxFKHZhbHVlLG9mZnNldCxub0Fzc2VydCl7cmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsdmFsdWUsb2Zmc2V0LHRydWUsbm9Bc3NlcnQpfTtCdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlQkU9ZnVuY3Rpb24gd3JpdGVEb3VibGVCRSh2YWx1ZSxvZmZzZXQsbm9Bc3NlcnQpe3JldHVybiB3cml0ZURvdWJsZSh0aGlzLHZhbHVlLG9mZnNldCxmYWxzZSxub0Fzc2VydCl9O0J1ZmZlci5wcm90b3R5cGUuY29weT1mdW5jdGlvbiBjb3B5KHRhcmdldCx0YXJnZXRTdGFydCxzdGFydCxlbmQpe2lmKCFzdGFydClzdGFydD0wO2lmKCFlbmQmJmVuZCE9PTApZW5kPXRoaXMubGVuZ3RoO2lmKHRhcmdldFN0YXJ0Pj10YXJnZXQubGVuZ3RoKXRhcmdldFN0YXJ0PXRhcmdldC5sZW5ndGg7aWYoIXRhcmdldFN0YXJ0KXRhcmdldFN0YXJ0PTA7aWYoZW5kPjAmJmVuZDxzdGFydCllbmQ9c3RhcnQ7aWYoZW5kPT09c3RhcnQpcmV0dXJuIDA7aWYodGFyZ2V0Lmxlbmd0aD09PTB8fHRoaXMubGVuZ3RoPT09MClyZXR1cm4gMDtpZih0YXJnZXRTdGFydDwwKXt0aHJvdyBuZXcgUmFuZ2VFcnJvcihcInRhcmdldFN0YXJ0IG91dCBvZiBib3VuZHNcIil9aWYoc3RhcnQ8MHx8c3RhcnQ+PXRoaXMubGVuZ3RoKXRocm93IG5ldyBSYW5nZUVycm9yKFwic291cmNlU3RhcnQgb3V0IG9mIGJvdW5kc1wiKTtpZihlbmQ8MCl0aHJvdyBuZXcgUmFuZ2VFcnJvcihcInNvdXJjZUVuZCBvdXQgb2YgYm91bmRzXCIpO2lmKGVuZD50aGlzLmxlbmd0aCllbmQ9dGhpcy5sZW5ndGg7aWYodGFyZ2V0Lmxlbmd0aC10YXJnZXRTdGFydDxlbmQtc3RhcnQpe2VuZD10YXJnZXQubGVuZ3RoLXRhcmdldFN0YXJ0K3N0YXJ0fXZhciBsZW49ZW5kLXN0YXJ0O3ZhciBpO2lmKHRoaXM9PT10YXJnZXQmJnN0YXJ0PHRhcmdldFN0YXJ0JiZ0YXJnZXRTdGFydDxlbmQpe2ZvcihpPWxlbi0xO2k+PTA7LS1pKXt0YXJnZXRbaSt0YXJnZXRTdGFydF09dGhpc1tpK3N0YXJ0XX19ZWxzZSBpZihsZW48MWUzfHwhQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpe2ZvcihpPTA7aTxsZW47KytpKXt0YXJnZXRbaSt0YXJnZXRTdGFydF09dGhpc1tpK3N0YXJ0XX19ZWxzZXtVaW50OEFycmF5LnByb3RvdHlwZS5zZXQuY2FsbCh0YXJnZXQsdGhpcy5zdWJhcnJheShzdGFydCxzdGFydCtsZW4pLHRhcmdldFN0YXJ0KX1yZXR1cm4gbGVufTtCdWZmZXIucHJvdG90eXBlLmZpbGw9ZnVuY3Rpb24gZmlsbCh2YWwsc3RhcnQsZW5kLGVuY29kaW5nKXtpZih0eXBlb2YgdmFsPT09XCJzdHJpbmdcIil7aWYodHlwZW9mIHN0YXJ0PT09XCJzdHJpbmdcIil7ZW5jb2Rpbmc9c3RhcnQ7c3RhcnQ9MDtlbmQ9dGhpcy5sZW5ndGh9ZWxzZSBpZih0eXBlb2YgZW5kPT09XCJzdHJpbmdcIil7ZW5jb2Rpbmc9ZW5kO2VuZD10aGlzLmxlbmd0aH1pZih2YWwubGVuZ3RoPT09MSl7dmFyIGNvZGU9dmFsLmNoYXJDb2RlQXQoMCk7aWYoY29kZTwyNTYpe3ZhbD1jb2RlfX1pZihlbmNvZGluZyE9PXVuZGVmaW5lZCYmdHlwZW9mIGVuY29kaW5nIT09XCJzdHJpbmdcIil7dGhyb3cgbmV3IFR5cGVFcnJvcihcImVuY29kaW5nIG11c3QgYmUgYSBzdHJpbmdcIil9aWYodHlwZW9mIGVuY29kaW5nPT09XCJzdHJpbmdcIiYmIUJ1ZmZlci5pc0VuY29kaW5nKGVuY29kaW5nKSl7dGhyb3cgbmV3IFR5cGVFcnJvcihcIlVua25vd24gZW5jb2Rpbmc6IFwiK2VuY29kaW5nKX19ZWxzZSBpZih0eXBlb2YgdmFsPT09XCJudW1iZXJcIil7dmFsPXZhbCYyNTV9aWYoc3RhcnQ8MHx8dGhpcy5sZW5ndGg8c3RhcnR8fHRoaXMubGVuZ3RoPGVuZCl7dGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJPdXQgb2YgcmFuZ2UgaW5kZXhcIil9aWYoZW5kPD1zdGFydCl7cmV0dXJuIHRoaXN9c3RhcnQ9c3RhcnQ+Pj4wO2VuZD1lbmQ9PT11bmRlZmluZWQ/dGhpcy5sZW5ndGg6ZW5kPj4+MDtpZighdmFsKXZhbD0wO3ZhciBpO2lmKHR5cGVvZiB2YWw9PT1cIm51bWJlclwiKXtmb3IoaT1zdGFydDtpPGVuZDsrK2kpe3RoaXNbaV09dmFsfX1lbHNle3ZhciBieXRlcz1CdWZmZXIuaXNCdWZmZXIodmFsKT92YWw6dXRmOFRvQnl0ZXMobmV3IEJ1ZmZlcih2YWwsZW5jb2RpbmcpLnRvU3RyaW5nKCkpO3ZhciBsZW49Ynl0ZXMubGVuZ3RoO2ZvcihpPTA7aTxlbmQtc3RhcnQ7KytpKXt0aGlzW2krc3RhcnRdPWJ5dGVzW2klbGVuXX19cmV0dXJuIHRoaXN9O3ZhciBJTlZBTElEX0JBU0U2NF9SRT0vW14rXFwvMC05QS1aYS16LV9dL2c7ZnVuY3Rpb24gYmFzZTY0Y2xlYW4oc3RyKXtzdHI9c3RyaW5ndHJpbShzdHIpLnJlcGxhY2UoSU5WQUxJRF9CQVNFNjRfUkUsXCJcIik7aWYoc3RyLmxlbmd0aDwyKXJldHVyblwiXCI7d2hpbGUoc3RyLmxlbmd0aCU0IT09MCl7c3RyPXN0citcIj1cIn1yZXR1cm4gc3RyfWZ1bmN0aW9uIHN0cmluZ3RyaW0oc3RyKXtpZihzdHIudHJpbSlyZXR1cm4gc3RyLnRyaW0oKTtyZXR1cm4gc3RyLnJlcGxhY2UoL15cXHMrfFxccyskL2csXCJcIil9ZnVuY3Rpb24gdG9IZXgobil7aWYobjwxNilyZXR1cm5cIjBcIituLnRvU3RyaW5nKDE2KTtyZXR1cm4gbi50b1N0cmluZygxNil9ZnVuY3Rpb24gdXRmOFRvQnl0ZXMoc3RyaW5nLHVuaXRzKXt1bml0cz11bml0c3x8SW5maW5pdHk7dmFyIGNvZGVQb2ludDt2YXIgbGVuZ3RoPXN0cmluZy5sZW5ndGg7dmFyIGxlYWRTdXJyb2dhdGU9bnVsbDt2YXIgYnl0ZXM9W107Zm9yKHZhciBpPTA7aTxsZW5ndGg7KytpKXtjb2RlUG9pbnQ9c3RyaW5nLmNoYXJDb2RlQXQoaSk7aWYoY29kZVBvaW50PjU1Mjk1JiZjb2RlUG9pbnQ8NTczNDQpe2lmKCFsZWFkU3Vycm9nYXRlKXtpZihjb2RlUG9pbnQ+NTYzMTkpe2lmKCh1bml0cy09Myk+LTEpYnl0ZXMucHVzaCgyMzksMTkxLDE4OSk7Y29udGludWV9ZWxzZSBpZihpKzE9PT1sZW5ndGgpe2lmKCh1bml0cy09Myk+LTEpYnl0ZXMucHVzaCgyMzksMTkxLDE4OSk7Y29udGludWV9bGVhZFN1cnJvZ2F0ZT1jb2RlUG9pbnQ7Y29udGludWV9aWYoY29kZVBvaW50PDU2MzIwKXtpZigodW5pdHMtPTMpPi0xKWJ5dGVzLnB1c2goMjM5LDE5MSwxODkpO2xlYWRTdXJyb2dhdGU9Y29kZVBvaW50O2NvbnRpbnVlfWNvZGVQb2ludD0obGVhZFN1cnJvZ2F0ZS01NTI5Njw8MTB8Y29kZVBvaW50LTU2MzIwKSs2NTUzNn1lbHNlIGlmKGxlYWRTdXJyb2dhdGUpe2lmKCh1bml0cy09Myk+LTEpYnl0ZXMucHVzaCgyMzksMTkxLDE4OSl9bGVhZFN1cnJvZ2F0ZT1udWxsO2lmKGNvZGVQb2ludDwxMjgpe2lmKCh1bml0cy09MSk8MClicmVhaztieXRlcy5wdXNoKGNvZGVQb2ludCl9ZWxzZSBpZihjb2RlUG9pbnQ8MjA0OCl7aWYoKHVuaXRzLT0yKTwwKWJyZWFrO2J5dGVzLnB1c2goY29kZVBvaW50Pj42fDE5Mixjb2RlUG9pbnQmNjN8MTI4KX1lbHNlIGlmKGNvZGVQb2ludDw2NTUzNil7aWYoKHVuaXRzLT0zKTwwKWJyZWFrO2J5dGVzLnB1c2goY29kZVBvaW50Pj4xMnwyMjQsY29kZVBvaW50Pj42JjYzfDEyOCxjb2RlUG9pbnQmNjN8MTI4KX1lbHNlIGlmKGNvZGVQb2ludDwxMTE0MTEyKXtpZigodW5pdHMtPTQpPDApYnJlYWs7Ynl0ZXMucHVzaChjb2RlUG9pbnQ+PjE4fDI0MCxjb2RlUG9pbnQ+PjEyJjYzfDEyOCxjb2RlUG9pbnQ+PjYmNjN8MTI4LGNvZGVQb2ludCY2M3wxMjgpfWVsc2V7dGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBjb2RlIHBvaW50XCIpfX1yZXR1cm4gYnl0ZXN9ZnVuY3Rpb24gYXNjaWlUb0J5dGVzKHN0cil7dmFyIGJ5dGVBcnJheT1bXTtmb3IodmFyIGk9MDtpPHN0ci5sZW5ndGg7KytpKXtieXRlQXJyYXkucHVzaChzdHIuY2hhckNvZGVBdChpKSYyNTUpfXJldHVybiBieXRlQXJyYXl9ZnVuY3Rpb24gdXRmMTZsZVRvQnl0ZXMoc3RyLHVuaXRzKXt2YXIgYyxoaSxsbzt2YXIgYnl0ZUFycmF5PVtdO2Zvcih2YXIgaT0wO2k8c3RyLmxlbmd0aDsrK2kpe2lmKCh1bml0cy09Mik8MClicmVhaztjPXN0ci5jaGFyQ29kZUF0KGkpO2hpPWM+Pjg7bG89YyUyNTY7Ynl0ZUFycmF5LnB1c2gobG8pO2J5dGVBcnJheS5wdXNoKGhpKX1yZXR1cm4gYnl0ZUFycmF5fWZ1bmN0aW9uIGJhc2U2NFRvQnl0ZXMoc3RyKXtyZXR1cm4gYmFzZTY0LnRvQnl0ZUFycmF5KGJhc2U2NGNsZWFuKHN0cikpfWZ1bmN0aW9uIGJsaXRCdWZmZXIoc3JjLGRzdCxvZmZzZXQsbGVuZ3RoKXtmb3IodmFyIGk9MDtpPGxlbmd0aDsrK2kpe2lmKGkrb2Zmc2V0Pj1kc3QubGVuZ3RofHxpPj1zcmMubGVuZ3RoKWJyZWFrO2RzdFtpK29mZnNldF09c3JjW2ldfXJldHVybiBpfWZ1bmN0aW9uIGlzbmFuKHZhbCl7cmV0dXJuIHZhbCE9PXZhbH19KS5jYWxsKHRoaXMsdHlwZW9mIGdsb2JhbCE9PVwidW5kZWZpbmVkXCI/Z2xvYmFsOnR5cGVvZiBzZWxmIT09XCJ1bmRlZmluZWRcIj9zZWxmOnR5cGVvZiB3aW5kb3chPT1cInVuZGVmaW5lZFwiP3dpbmRvdzp7fSl9LHtcImJhc2U2NC1qc1wiOjIsaWVlZTc1NDozNyxpc2FycmF5OjQwfV0sNjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7KGZ1bmN0aW9uKEJ1ZmZlcil7ZnVuY3Rpb24gaXNBcnJheShhcmcpe2lmKEFycmF5LmlzQXJyYXkpe3JldHVybiBBcnJheS5pc0FycmF5KGFyZyl9cmV0dXJuIG9iamVjdFRvU3RyaW5nKGFyZyk9PT1cIltvYmplY3QgQXJyYXldXCJ9ZXhwb3J0cy5pc0FycmF5PWlzQXJyYXk7ZnVuY3Rpb24gaXNCb29sZWFuKGFyZyl7cmV0dXJuIHR5cGVvZiBhcmc9PT1cImJvb2xlYW5cIn1leHBvcnRzLmlzQm9vbGVhbj1pc0Jvb2xlYW47ZnVuY3Rpb24gaXNOdWxsKGFyZyl7cmV0dXJuIGFyZz09PW51bGx9ZXhwb3J0cy5pc051bGw9aXNOdWxsO2Z1bmN0aW9uIGlzTnVsbE9yVW5kZWZpbmVkKGFyZyl7cmV0dXJuIGFyZz09bnVsbH1leHBvcnRzLmlzTnVsbE9yVW5kZWZpbmVkPWlzTnVsbE9yVW5kZWZpbmVkO2Z1bmN0aW9uIGlzTnVtYmVyKGFyZyl7cmV0dXJuIHR5cGVvZiBhcmc9PT1cIm51bWJlclwifWV4cG9ydHMuaXNOdW1iZXI9aXNOdW1iZXI7ZnVuY3Rpb24gaXNTdHJpbmcoYXJnKXtyZXR1cm4gdHlwZW9mIGFyZz09PVwic3RyaW5nXCJ9ZXhwb3J0cy5pc1N0cmluZz1pc1N0cmluZztmdW5jdGlvbiBpc1N5bWJvbChhcmcpe3JldHVybiB0eXBlb2YgYXJnPT09XCJzeW1ib2xcIn1leHBvcnRzLmlzU3ltYm9sPWlzU3ltYm9sO2Z1bmN0aW9uIGlzVW5kZWZpbmVkKGFyZyl7cmV0dXJuIGFyZz09PXZvaWQgMH1leHBvcnRzLmlzVW5kZWZpbmVkPWlzVW5kZWZpbmVkO2Z1bmN0aW9uIGlzUmVnRXhwKHJlKXtyZXR1cm4gb2JqZWN0VG9TdHJpbmcocmUpPT09XCJbb2JqZWN0IFJlZ0V4cF1cIn1leHBvcnRzLmlzUmVnRXhwPWlzUmVnRXhwO2Z1bmN0aW9uIGlzT2JqZWN0KGFyZyl7cmV0dXJuIHR5cGVvZiBhcmc9PT1cIm9iamVjdFwiJiZhcmchPT1udWxsfWV4cG9ydHMuaXNPYmplY3Q9aXNPYmplY3Q7ZnVuY3Rpb24gaXNEYXRlKGQpe3JldHVybiBvYmplY3RUb1N0cmluZyhkKT09PVwiW29iamVjdCBEYXRlXVwifWV4cG9ydHMuaXNEYXRlPWlzRGF0ZTtmdW5jdGlvbiBpc0Vycm9yKGUpe3JldHVybiBvYmplY3RUb1N0cmluZyhlKT09PVwiW29iamVjdCBFcnJvcl1cInx8ZSBpbnN0YW5jZW9mIEVycm9yfWV4cG9ydHMuaXNFcnJvcj1pc0Vycm9yO2Z1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKXtyZXR1cm4gdHlwZW9mIGFyZz09PVwiZnVuY3Rpb25cIn1leHBvcnRzLmlzRnVuY3Rpb249aXNGdW5jdGlvbjtmdW5jdGlvbiBpc1ByaW1pdGl2ZShhcmcpe3JldHVybiBhcmc9PT1udWxsfHx0eXBlb2YgYXJnPT09XCJib29sZWFuXCJ8fHR5cGVvZiBhcmc9PT1cIm51bWJlclwifHx0eXBlb2YgYXJnPT09XCJzdHJpbmdcInx8dHlwZW9mIGFyZz09PVwic3ltYm9sXCJ8fHR5cGVvZiBhcmc9PT1cInVuZGVmaW5lZFwifWV4cG9ydHMuaXNQcmltaXRpdmU9aXNQcmltaXRpdmU7ZXhwb3J0cy5pc0J1ZmZlcj1CdWZmZXIuaXNCdWZmZXI7ZnVuY3Rpb24gb2JqZWN0VG9TdHJpbmcobyl7cmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKX19KS5jYWxsKHRoaXMse2lzQnVmZmVyOnJlcXVpcmUoXCIuLi8uLi9pcy1idWZmZXIvaW5kZXguanNcIil9KX0se1wiLi4vLi4vaXMtYnVmZmVyL2luZGV4LmpzXCI6Mzl9XSw3OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgRWxlbWVudFR5cGU9cmVxdWlyZShcImRvbWVsZW1lbnR0eXBlXCIpO3ZhciBlbnRpdGllcz1yZXF1aXJlKFwiZW50aXRpZXNcIik7dmFyIGJvb2xlYW5BdHRyaWJ1dGVzPXtfX3Byb3RvX186bnVsbCxhbGxvd2Z1bGxzY3JlZW46dHJ1ZSxhc3luYzp0cnVlLGF1dG9mb2N1czp0cnVlLGF1dG9wbGF5OnRydWUsY2hlY2tlZDp0cnVlLGNvbnRyb2xzOnRydWUsZGVmYXVsdDp0cnVlLGRlZmVyOnRydWUsZGlzYWJsZWQ6dHJ1ZSxoaWRkZW46dHJ1ZSxpc21hcDp0cnVlLGxvb3A6dHJ1ZSxtdWx0aXBsZTp0cnVlLG11dGVkOnRydWUsb3Blbjp0cnVlLHJlYWRvbmx5OnRydWUscmVxdWlyZWQ6dHJ1ZSxyZXZlcnNlZDp0cnVlLHNjb3BlZDp0cnVlLHNlYW1sZXNzOnRydWUsc2VsZWN0ZWQ6dHJ1ZSx0eXBlbXVzdG1hdGNoOnRydWV9O3ZhciB1bmVuY29kZWRFbGVtZW50cz17X19wcm90b19fOm51bGwsc3R5bGU6dHJ1ZSxzY3JpcHQ6dHJ1ZSx4bXA6dHJ1ZSxpZnJhbWU6dHJ1ZSxub2VtYmVkOnRydWUsbm9mcmFtZXM6dHJ1ZSxwbGFpbnRleHQ6dHJ1ZSxub3NjcmlwdDp0cnVlfTtmdW5jdGlvbiBmb3JtYXRBdHRycyhhdHRyaWJ1dGVzLG9wdHMpe2lmKCFhdHRyaWJ1dGVzKXJldHVybjt2YXIgb3V0cHV0PVwiXCIsdmFsdWU7Zm9yKHZhciBrZXkgaW4gYXR0cmlidXRlcyl7dmFsdWU9YXR0cmlidXRlc1trZXldO2lmKG91dHB1dCl7b3V0cHV0Kz1cIiBcIn1pZighdmFsdWUmJmJvb2xlYW5BdHRyaWJ1dGVzW2tleV0pe291dHB1dCs9a2V5fWVsc2V7b3V0cHV0Kz1rZXkrJz1cIicrKG9wdHMuZGVjb2RlRW50aXRpZXM/ZW50aXRpZXMuZW5jb2RlWE1MKHZhbHVlKTp2YWx1ZSkrJ1wiJ319cmV0dXJuIG91dHB1dH12YXIgc2luZ2xlVGFnPXtfX3Byb3RvX186bnVsbCxhcmVhOnRydWUsYmFzZTp0cnVlLGJhc2Vmb250OnRydWUsYnI6dHJ1ZSxjb2w6dHJ1ZSxjb21tYW5kOnRydWUsZW1iZWQ6dHJ1ZSxmcmFtZTp0cnVlLGhyOnRydWUsaW1nOnRydWUsaW5wdXQ6dHJ1ZSxpc2luZGV4OnRydWUsa2V5Z2VuOnRydWUsbGluazp0cnVlLG1ldGE6dHJ1ZSxwYXJhbTp0cnVlLHNvdXJjZTp0cnVlLHRyYWNrOnRydWUsd2JyOnRydWV9O3ZhciByZW5kZXI9bW9kdWxlLmV4cG9ydHM9ZnVuY3Rpb24oZG9tLG9wdHMpe2lmKCFBcnJheS5pc0FycmF5KGRvbSkmJiFkb20uY2hlZXJpbylkb209W2RvbV07b3B0cz1vcHRzfHx7fTt2YXIgb3V0cHV0PVwiXCI7Zm9yKHZhciBpPTA7aTxkb20ubGVuZ3RoO2krKyl7dmFyIGVsZW09ZG9tW2ldO2lmKGVsZW0udHlwZT09PVwicm9vdFwiKW91dHB1dCs9cmVuZGVyKGVsZW0uY2hpbGRyZW4sb3B0cyk7ZWxzZSBpZihFbGVtZW50VHlwZS5pc1RhZyhlbGVtKSlvdXRwdXQrPXJlbmRlclRhZyhlbGVtLG9wdHMpO2Vsc2UgaWYoZWxlbS50eXBlPT09RWxlbWVudFR5cGUuRGlyZWN0aXZlKW91dHB1dCs9cmVuZGVyRGlyZWN0aXZlKGVsZW0pO2Vsc2UgaWYoZWxlbS50eXBlPT09RWxlbWVudFR5cGUuQ29tbWVudClvdXRwdXQrPXJlbmRlckNvbW1lbnQoZWxlbSk7ZWxzZSBpZihlbGVtLnR5cGU9PT1FbGVtZW50VHlwZS5DREFUQSlvdXRwdXQrPXJlbmRlckNkYXRhKGVsZW0pO2Vsc2Ugb3V0cHV0Kz1yZW5kZXJUZXh0KGVsZW0sb3B0cyl9cmV0dXJuIG91dHB1dH07ZnVuY3Rpb24gcmVuZGVyVGFnKGVsZW0sb3B0cyl7aWYoZWxlbS5uYW1lPT09XCJzdmdcIilvcHRzPXtkZWNvZGVFbnRpdGllczpvcHRzLmRlY29kZUVudGl0aWVzLHhtbE1vZGU6dHJ1ZX07dmFyIHRhZz1cIjxcIitlbGVtLm5hbWUsYXR0cmlicz1mb3JtYXRBdHRycyhlbGVtLmF0dHJpYnMsb3B0cyk7aWYoYXR0cmlicyl7dGFnKz1cIiBcIithdHRyaWJzfWlmKG9wdHMueG1sTW9kZSYmKCFlbGVtLmNoaWxkcmVufHxlbGVtLmNoaWxkcmVuLmxlbmd0aD09PTApKXt0YWcrPVwiLz5cIn1lbHNle3RhZys9XCI+XCI7aWYoZWxlbS5jaGlsZHJlbil7dGFnKz1yZW5kZXIoZWxlbS5jaGlsZHJlbixvcHRzKX1pZighc2luZ2xlVGFnW2VsZW0ubmFtZV18fG9wdHMueG1sTW9kZSl7dGFnKz1cIjwvXCIrZWxlbS5uYW1lK1wiPlwifX1yZXR1cm4gdGFnfWZ1bmN0aW9uIHJlbmRlckRpcmVjdGl2ZShlbGVtKXtyZXR1cm5cIjxcIitlbGVtLmRhdGErXCI+XCJ9ZnVuY3Rpb24gcmVuZGVyVGV4dChlbGVtLG9wdHMpe3ZhciBkYXRhPWVsZW0uZGF0YXx8XCJcIjtpZihvcHRzLmRlY29kZUVudGl0aWVzJiYhKGVsZW0ucGFyZW50JiZlbGVtLnBhcmVudC5uYW1lIGluIHVuZW5jb2RlZEVsZW1lbnRzKSl7ZGF0YT1lbnRpdGllcy5lbmNvZGVYTUwoZGF0YSl9cmV0dXJuIGRhdGF9ZnVuY3Rpb24gcmVuZGVyQ2RhdGEoZWxlbSl7cmV0dXJuXCI8IVtDREFUQVtcIitlbGVtLmNoaWxkcmVuWzBdLmRhdGErXCJdXT5cIn1mdW5jdGlvbiByZW5kZXJDb21tZW50KGVsZW0pe3JldHVyblwiPCEtLVwiK2VsZW0uZGF0YStcIi0tPlwifX0se2RvbWVsZW1lbnR0eXBlOjgsZW50aXRpZXM6MjB9XSw4OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXttb2R1bGUuZXhwb3J0cz17VGV4dDpcInRleHRcIixEaXJlY3RpdmU6XCJkaXJlY3RpdmVcIixDb21tZW50OlwiY29tbWVudFwiLFNjcmlwdDpcInNjcmlwdFwiLFN0eWxlOlwic3R5bGVcIixUYWc6XCJ0YWdcIixDREFUQTpcImNkYXRhXCIsaXNUYWc6ZnVuY3Rpb24oZWxlbSl7cmV0dXJuIGVsZW0udHlwZT09PVwidGFnXCJ8fGVsZW0udHlwZT09PVwic2NyaXB0XCJ8fGVsZW0udHlwZT09PVwic3R5bGVcIn19fSx7fV0sOTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9e1RleHQ6XCJ0ZXh0XCIsRGlyZWN0aXZlOlwiZGlyZWN0aXZlXCIsQ29tbWVudDpcImNvbW1lbnRcIixTY3JpcHQ6XCJzY3JpcHRcIixTdHlsZTpcInN0eWxlXCIsVGFnOlwidGFnXCIsQ0RBVEE6XCJjZGF0YVwiLERvY3R5cGU6XCJkb2N0eXBlXCIsaXNUYWc6ZnVuY3Rpb24oZWxlbSl7cmV0dXJuIGVsZW0udHlwZT09PVwidGFnXCJ8fGVsZW0udHlwZT09PVwic2NyaXB0XCJ8fGVsZW0udHlwZT09PVwic3R5bGVcIn19fSx7fV0sMTA6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciBFbGVtZW50VHlwZT1yZXF1aXJlKFwiZG9tZWxlbWVudHR5cGVcIik7dmFyIHJlX3doaXRlc3BhY2U9L1xccysvZzt2YXIgTm9kZVByb3RvdHlwZT1yZXF1aXJlKFwiLi9saWIvbm9kZVwiKTt2YXIgRWxlbWVudFByb3RvdHlwZT1yZXF1aXJlKFwiLi9saWIvZWxlbWVudFwiKTtmdW5jdGlvbiBEb21IYW5kbGVyKGNhbGxiYWNrLG9wdGlvbnMsZWxlbWVudENCKXtpZih0eXBlb2YgY2FsbGJhY2s9PT1cIm9iamVjdFwiKXtlbGVtZW50Q0I9b3B0aW9ucztvcHRpb25zPWNhbGxiYWNrO2NhbGxiYWNrPW51bGx9ZWxzZSBpZih0eXBlb2Ygb3B0aW9ucz09PVwiZnVuY3Rpb25cIil7ZWxlbWVudENCPW9wdGlvbnM7b3B0aW9ucz1kZWZhdWx0T3B0c310aGlzLl9jYWxsYmFjaz1jYWxsYmFjazt0aGlzLl9vcHRpb25zPW9wdGlvbnN8fGRlZmF1bHRPcHRzO3RoaXMuX2VsZW1lbnRDQj1lbGVtZW50Q0I7dGhpcy5kb209W107dGhpcy5fZG9uZT1mYWxzZTt0aGlzLl90YWdTdGFjaz1bXTt0aGlzLl9wYXJzZXI9dGhpcy5fcGFyc2VyfHxudWxsfXZhciBkZWZhdWx0T3B0cz17bm9ybWFsaXplV2hpdGVzcGFjZTpmYWxzZSx3aXRoU3RhcnRJbmRpY2VzOmZhbHNlfTtEb21IYW5kbGVyLnByb3RvdHlwZS5vbnBhcnNlcmluaXQ9ZnVuY3Rpb24ocGFyc2VyKXt0aGlzLl9wYXJzZXI9cGFyc2VyfTtEb21IYW5kbGVyLnByb3RvdHlwZS5vbnJlc2V0PWZ1bmN0aW9uKCl7RG9tSGFuZGxlci5jYWxsKHRoaXMsdGhpcy5fY2FsbGJhY2ssdGhpcy5fb3B0aW9ucyx0aGlzLl9lbGVtZW50Q0IpfTtEb21IYW5kbGVyLnByb3RvdHlwZS5vbmVuZD1mdW5jdGlvbigpe2lmKHRoaXMuX2RvbmUpcmV0dXJuO3RoaXMuX2RvbmU9dHJ1ZTt0aGlzLl9wYXJzZXI9bnVsbDt0aGlzLl9oYW5kbGVDYWxsYmFjayhudWxsKX07RG9tSGFuZGxlci5wcm90b3R5cGUuX2hhbmRsZUNhbGxiYWNrPURvbUhhbmRsZXIucHJvdG90eXBlLm9uZXJyb3I9ZnVuY3Rpb24oZXJyb3Ipe2lmKHR5cGVvZiB0aGlzLl9jYWxsYmFjaz09PVwiZnVuY3Rpb25cIil7dGhpcy5fY2FsbGJhY2soZXJyb3IsdGhpcy5kb20pfWVsc2V7aWYoZXJyb3IpdGhyb3cgZXJyb3J9fTtEb21IYW5kbGVyLnByb3RvdHlwZS5vbmNsb3NldGFnPWZ1bmN0aW9uKCl7dmFyIGVsZW09dGhpcy5fdGFnU3RhY2sucG9wKCk7aWYodGhpcy5fZWxlbWVudENCKXRoaXMuX2VsZW1lbnRDQihlbGVtKX07RG9tSGFuZGxlci5wcm90b3R5cGUuX2FkZERvbUVsZW1lbnQ9ZnVuY3Rpb24oZWxlbWVudCl7dmFyIHBhcmVudD10aGlzLl90YWdTdGFja1t0aGlzLl90YWdTdGFjay5sZW5ndGgtMV07dmFyIHNpYmxpbmdzPXBhcmVudD9wYXJlbnQuY2hpbGRyZW46dGhpcy5kb207dmFyIHByZXZpb3VzU2libGluZz1zaWJsaW5nc1tzaWJsaW5ncy5sZW5ndGgtMV07ZWxlbWVudC5uZXh0PW51bGw7aWYodGhpcy5fb3B0aW9ucy53aXRoU3RhcnRJbmRpY2VzKXtlbGVtZW50LnN0YXJ0SW5kZXg9dGhpcy5fcGFyc2VyLnN0YXJ0SW5kZXh9aWYodGhpcy5fb3B0aW9ucy53aXRoRG9tTHZsMSl7ZWxlbWVudC5fX3Byb3RvX189ZWxlbWVudC50eXBlPT09XCJ0YWdcIj9FbGVtZW50UHJvdG90eXBlOk5vZGVQcm90b3R5cGV9aWYocHJldmlvdXNTaWJsaW5nKXtlbGVtZW50LnByZXY9cHJldmlvdXNTaWJsaW5nO3ByZXZpb3VzU2libGluZy5uZXh0PWVsZW1lbnR9ZWxzZXtlbGVtZW50LnByZXY9bnVsbH1zaWJsaW5ncy5wdXNoKGVsZW1lbnQpO2VsZW1lbnQucGFyZW50PXBhcmVudHx8bnVsbH07RG9tSGFuZGxlci5wcm90b3R5cGUub25vcGVudGFnPWZ1bmN0aW9uKG5hbWUsYXR0cmlicyl7dmFyIGVsZW1lbnQ9e3R5cGU6bmFtZT09PVwic2NyaXB0XCI/RWxlbWVudFR5cGUuU2NyaXB0Om5hbWU9PT1cInN0eWxlXCI/RWxlbWVudFR5cGUuU3R5bGU6RWxlbWVudFR5cGUuVGFnLG5hbWU6bmFtZSxhdHRyaWJzOmF0dHJpYnMsY2hpbGRyZW46W119O3RoaXMuX2FkZERvbUVsZW1lbnQoZWxlbWVudCk7dGhpcy5fdGFnU3RhY2sucHVzaChlbGVtZW50KX07RG9tSGFuZGxlci5wcm90b3R5cGUub250ZXh0PWZ1bmN0aW9uKGRhdGEpe3ZhciBub3JtYWxpemU9dGhpcy5fb3B0aW9ucy5ub3JtYWxpemVXaGl0ZXNwYWNlfHx0aGlzLl9vcHRpb25zLmlnbm9yZVdoaXRlc3BhY2U7dmFyIGxhc3RUYWc7aWYoIXRoaXMuX3RhZ1N0YWNrLmxlbmd0aCYmdGhpcy5kb20ubGVuZ3RoJiYobGFzdFRhZz10aGlzLmRvbVt0aGlzLmRvbS5sZW5ndGgtMV0pLnR5cGU9PT1FbGVtZW50VHlwZS5UZXh0KXtpZihub3JtYWxpemUpe2xhc3RUYWcuZGF0YT0obGFzdFRhZy5kYXRhK2RhdGEpLnJlcGxhY2UocmVfd2hpdGVzcGFjZSxcIiBcIil9ZWxzZXtsYXN0VGFnLmRhdGErPWRhdGF9fWVsc2V7aWYodGhpcy5fdGFnU3RhY2subGVuZ3RoJiYobGFzdFRhZz10aGlzLl90YWdTdGFja1t0aGlzLl90YWdTdGFjay5sZW5ndGgtMV0pJiYobGFzdFRhZz1sYXN0VGFnLmNoaWxkcmVuW2xhc3RUYWcuY2hpbGRyZW4ubGVuZ3RoLTFdKSYmbGFzdFRhZy50eXBlPT09RWxlbWVudFR5cGUuVGV4dCl7aWYobm9ybWFsaXplKXtsYXN0VGFnLmRhdGE9KGxhc3RUYWcuZGF0YStkYXRhKS5yZXBsYWNlKHJlX3doaXRlc3BhY2UsXCIgXCIpfWVsc2V7bGFzdFRhZy5kYXRhKz1kYXRhfX1lbHNle2lmKG5vcm1hbGl6ZSl7ZGF0YT1kYXRhLnJlcGxhY2UocmVfd2hpdGVzcGFjZSxcIiBcIil9dGhpcy5fYWRkRG9tRWxlbWVudCh7ZGF0YTpkYXRhLHR5cGU6RWxlbWVudFR5cGUuVGV4dH0pfX19O0RvbUhhbmRsZXIucHJvdG90eXBlLm9uY29tbWVudD1mdW5jdGlvbihkYXRhKXt2YXIgbGFzdFRhZz10aGlzLl90YWdTdGFja1t0aGlzLl90YWdTdGFjay5sZW5ndGgtMV07aWYobGFzdFRhZyYmbGFzdFRhZy50eXBlPT09RWxlbWVudFR5cGUuQ29tbWVudCl7bGFzdFRhZy5kYXRhKz1kYXRhO3JldHVybn12YXIgZWxlbWVudD17ZGF0YTpkYXRhLHR5cGU6RWxlbWVudFR5cGUuQ29tbWVudH07dGhpcy5fYWRkRG9tRWxlbWVudChlbGVtZW50KTt0aGlzLl90YWdTdGFjay5wdXNoKGVsZW1lbnQpfTtEb21IYW5kbGVyLnByb3RvdHlwZS5vbmNkYXRhc3RhcnQ9ZnVuY3Rpb24oKXt2YXIgZWxlbWVudD17Y2hpbGRyZW46W3tkYXRhOlwiXCIsdHlwZTpFbGVtZW50VHlwZS5UZXh0fV0sdHlwZTpFbGVtZW50VHlwZS5DREFUQX07dGhpcy5fYWRkRG9tRWxlbWVudChlbGVtZW50KTt0aGlzLl90YWdTdGFjay5wdXNoKGVsZW1lbnQpfTtEb21IYW5kbGVyLnByb3RvdHlwZS5vbmNvbW1lbnRlbmQ9RG9tSGFuZGxlci5wcm90b3R5cGUub25jZGF0YWVuZD1mdW5jdGlvbigpe3RoaXMuX3RhZ1N0YWNrLnBvcCgpfTtEb21IYW5kbGVyLnByb3RvdHlwZS5vbnByb2Nlc3NpbmdpbnN0cnVjdGlvbj1mdW5jdGlvbihuYW1lLGRhdGEpe3RoaXMuX2FkZERvbUVsZW1lbnQoe25hbWU6bmFtZSxkYXRhOmRhdGEsdHlwZTpFbGVtZW50VHlwZS5EaXJlY3RpdmV9KX07bW9kdWxlLmV4cG9ydHM9RG9tSGFuZGxlcn0se1wiLi9saWIvZWxlbWVudFwiOjExLFwiLi9saWIvbm9kZVwiOjEyLGRvbWVsZW1lbnR0eXBlOjl9XSwxMTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIE5vZGVQcm90b3R5cGU9cmVxdWlyZShcIi4vbm9kZVwiKTt2YXIgRWxlbWVudFByb3RvdHlwZT1tb2R1bGUuZXhwb3J0cz1PYmplY3QuY3JlYXRlKE5vZGVQcm90b3R5cGUpO3ZhciBkb21MdmwxPXt0YWdOYW1lOlwibmFtZVwifTtPYmplY3Qua2V5cyhkb21MdmwxKS5mb3JFYWNoKGZ1bmN0aW9uKGtleSl7dmFyIHNob3J0aGFuZD1kb21MdmwxW2tleV07T2JqZWN0LmRlZmluZVByb3BlcnR5KEVsZW1lbnRQcm90b3R5cGUsa2V5LHtnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpc1tzaG9ydGhhbmRdfHxudWxsfSxzZXQ6ZnVuY3Rpb24odmFsKXt0aGlzW3Nob3J0aGFuZF09dmFsO3JldHVybiB2YWx9fSl9KX0se1wiLi9ub2RlXCI6MTJ9XSwxMjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIE5vZGVQcm90b3R5cGU9bW9kdWxlLmV4cG9ydHM9e2dldCBmaXJzdENoaWxkKCl7dmFyIGNoaWxkcmVuPXRoaXMuY2hpbGRyZW47cmV0dXJuIGNoaWxkcmVuJiZjaGlsZHJlblswXXx8bnVsbH0sZ2V0IGxhc3RDaGlsZCgpe3ZhciBjaGlsZHJlbj10aGlzLmNoaWxkcmVuO3JldHVybiBjaGlsZHJlbiYmY2hpbGRyZW5bY2hpbGRyZW4ubGVuZ3RoLTFdfHxudWxsfSxnZXQgbm9kZVR5cGUoKXtyZXR1cm4gbm9kZVR5cGVzW3RoaXMudHlwZV18fG5vZGVUeXBlcy5lbGVtZW50fX07dmFyIGRvbUx2bDE9e3RhZ05hbWU6XCJuYW1lXCIsY2hpbGROb2RlczpcImNoaWxkcmVuXCIscGFyZW50Tm9kZTpcInBhcmVudFwiLHByZXZpb3VzU2libGluZzpcInByZXZcIixuZXh0U2libGluZzpcIm5leHRcIixub2RlVmFsdWU6XCJkYXRhXCJ9O3ZhciBub2RlVHlwZXM9e2VsZW1lbnQ6MSx0ZXh0OjMsY2RhdGE6NCxjb21tZW50Ojh9O09iamVjdC5rZXlzKGRvbUx2bDEpLmZvckVhY2goZnVuY3Rpb24oa2V5KXt2YXIgc2hvcnRoYW5kPWRvbUx2bDFba2V5XTtPYmplY3QuZGVmaW5lUHJvcGVydHkoTm9kZVByb3RvdHlwZSxrZXkse2dldDpmdW5jdGlvbigpe3JldHVybiB0aGlzW3Nob3J0aGFuZF18fG51bGx9LHNldDpmdW5jdGlvbih2YWwpe3RoaXNbc2hvcnRoYW5kXT12YWw7cmV0dXJuIHZhbH19KX0pfSx7fV0sMTM6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciBEb21VdGlscz1tb2R1bGUuZXhwb3J0cztbcmVxdWlyZShcIi4vbGliL3N0cmluZ2lmeVwiKSxyZXF1aXJlKFwiLi9saWIvdHJhdmVyc2FsXCIpLHJlcXVpcmUoXCIuL2xpYi9tYW5pcHVsYXRpb25cIikscmVxdWlyZShcIi4vbGliL3F1ZXJ5aW5nXCIpLHJlcXVpcmUoXCIuL2xpYi9sZWdhY3lcIikscmVxdWlyZShcIi4vbGliL2hlbHBlcnNcIildLmZvckVhY2goZnVuY3Rpb24oZXh0KXtPYmplY3Qua2V5cyhleHQpLmZvckVhY2goZnVuY3Rpb24oa2V5KXtEb21VdGlsc1trZXldPWV4dFtrZXldLmJpbmQoRG9tVXRpbHMpfSl9KX0se1wiLi9saWIvaGVscGVyc1wiOjE0LFwiLi9saWIvbGVnYWN5XCI6MTUsXCIuL2xpYi9tYW5pcHVsYXRpb25cIjoxNixcIi4vbGliL3F1ZXJ5aW5nXCI6MTcsXCIuL2xpYi9zdHJpbmdpZnlcIjoxOCxcIi4vbGliL3RyYXZlcnNhbFwiOjE5fV0sMTQ6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe2V4cG9ydHMucmVtb3ZlU3Vic2V0cz1mdW5jdGlvbihub2Rlcyl7dmFyIGlkeD1ub2Rlcy5sZW5ndGgsbm9kZSxhbmNlc3RvcixyZXBsYWNlO3doaWxlKC0taWR4Pi0xKXtub2RlPWFuY2VzdG9yPW5vZGVzW2lkeF07bm9kZXNbaWR4XT1udWxsO3JlcGxhY2U9dHJ1ZTt3aGlsZShhbmNlc3Rvcil7aWYobm9kZXMuaW5kZXhPZihhbmNlc3Rvcik+LTEpe3JlcGxhY2U9ZmFsc2U7bm9kZXMuc3BsaWNlKGlkeCwxKTticmVha31hbmNlc3Rvcj1hbmNlc3Rvci5wYXJlbnR9aWYocmVwbGFjZSl7bm9kZXNbaWR4XT1ub2RlfX1yZXR1cm4gbm9kZXN9O3ZhciBQT1NJVElPTj17RElTQ09OTkVDVEVEOjEsUFJFQ0VESU5HOjIsRk9MTE9XSU5HOjQsQ09OVEFJTlM6OCxDT05UQUlORURfQlk6MTZ9O3ZhciBjb21wYXJlUG9zPWV4cG9ydHMuY29tcGFyZURvY3VtZW50UG9zaXRpb249ZnVuY3Rpb24obm9kZUEsbm9kZUIpe3ZhciBhUGFyZW50cz1bXTt2YXIgYlBhcmVudHM9W107dmFyIGN1cnJlbnQsc2hhcmVkUGFyZW50LHNpYmxpbmdzLGFTaWJsaW5nLGJTaWJsaW5nLGlkeDtpZihub2RlQT09PW5vZGVCKXtyZXR1cm4gMH1jdXJyZW50PW5vZGVBO3doaWxlKGN1cnJlbnQpe2FQYXJlbnRzLnVuc2hpZnQoY3VycmVudCk7Y3VycmVudD1jdXJyZW50LnBhcmVudH1jdXJyZW50PW5vZGVCO3doaWxlKGN1cnJlbnQpe2JQYXJlbnRzLnVuc2hpZnQoY3VycmVudCk7Y3VycmVudD1jdXJyZW50LnBhcmVudH1pZHg9MDt3aGlsZShhUGFyZW50c1tpZHhdPT09YlBhcmVudHNbaWR4XSl7aWR4Kyt9aWYoaWR4PT09MCl7cmV0dXJuIFBPU0lUSU9OLkRJU0NPTk5FQ1RFRH1zaGFyZWRQYXJlbnQ9YVBhcmVudHNbaWR4LTFdO3NpYmxpbmdzPXNoYXJlZFBhcmVudC5jaGlsZHJlbjthU2libGluZz1hUGFyZW50c1tpZHhdO2JTaWJsaW5nPWJQYXJlbnRzW2lkeF07aWYoc2libGluZ3MuaW5kZXhPZihhU2libGluZyk+c2libGluZ3MuaW5kZXhPZihiU2libGluZykpe2lmKHNoYXJlZFBhcmVudD09PW5vZGVCKXtyZXR1cm4gUE9TSVRJT04uRk9MTE9XSU5HfFBPU0lUSU9OLkNPTlRBSU5FRF9CWX1yZXR1cm4gUE9TSVRJT04uRk9MTE9XSU5HfWVsc2V7aWYoc2hhcmVkUGFyZW50PT09bm9kZUEpe3JldHVybiBQT1NJVElPTi5QUkVDRURJTkd8UE9TSVRJT04uQ09OVEFJTlN9cmV0dXJuIFBPU0lUSU9OLlBSRUNFRElOR319O2V4cG9ydHMudW5pcXVlU29ydD1mdW5jdGlvbihub2Rlcyl7dmFyIGlkeD1ub2Rlcy5sZW5ndGgsbm9kZSxwb3NpdGlvbjtub2Rlcz1ub2Rlcy5zbGljZSgpO3doaWxlKC0taWR4Pi0xKXtub2RlPW5vZGVzW2lkeF07cG9zaXRpb249bm9kZXMuaW5kZXhPZihub2RlKTtpZihwb3NpdGlvbj4tMSYmcG9zaXRpb248aWR4KXtub2Rlcy5zcGxpY2UoaWR4LDEpfX1ub2Rlcy5zb3J0KGZ1bmN0aW9uKGEsYil7dmFyIHJlbGF0aXZlPWNvbXBhcmVQb3MoYSxiKTtpZihyZWxhdGl2ZSZQT1NJVElPTi5QUkVDRURJTkcpe3JldHVybi0xfWVsc2UgaWYocmVsYXRpdmUmUE9TSVRJT04uRk9MTE9XSU5HKXtyZXR1cm4gMX1yZXR1cm4gMH0pO3JldHVybiBub2Rlc319LHt9XSwxNTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIEVsZW1lbnRUeXBlPXJlcXVpcmUoXCJkb21lbGVtZW50dHlwZVwiKTt2YXIgaXNUYWc9ZXhwb3J0cy5pc1RhZz1FbGVtZW50VHlwZS5pc1RhZztleHBvcnRzLnRlc3RFbGVtZW50PWZ1bmN0aW9uKG9wdGlvbnMsZWxlbWVudCl7Zm9yKHZhciBrZXkgaW4gb3B0aW9ucyl7aWYoIW9wdGlvbnMuaGFzT3duUHJvcGVydHkoa2V5KSk7ZWxzZSBpZihrZXk9PT1cInRhZ19uYW1lXCIpe2lmKCFpc1RhZyhlbGVtZW50KXx8IW9wdGlvbnMudGFnX25hbWUoZWxlbWVudC5uYW1lKSl7cmV0dXJuIGZhbHNlfX1lbHNlIGlmKGtleT09PVwidGFnX3R5cGVcIil7aWYoIW9wdGlvbnMudGFnX3R5cGUoZWxlbWVudC50eXBlKSlyZXR1cm4gZmFsc2V9ZWxzZSBpZihrZXk9PT1cInRhZ19jb250YWluc1wiKXtpZihpc1RhZyhlbGVtZW50KXx8IW9wdGlvbnMudGFnX2NvbnRhaW5zKGVsZW1lbnQuZGF0YSkpe3JldHVybiBmYWxzZX19ZWxzZSBpZighZWxlbWVudC5hdHRyaWJzfHwhb3B0aW9uc1trZXldKGVsZW1lbnQuYXR0cmlic1trZXldKSl7cmV0dXJuIGZhbHNlfX1yZXR1cm4gdHJ1ZX07dmFyIENoZWNrcz17dGFnX25hbWU6ZnVuY3Rpb24obmFtZSl7aWYodHlwZW9mIG5hbWU9PT1cImZ1bmN0aW9uXCIpe3JldHVybiBmdW5jdGlvbihlbGVtKXtyZXR1cm4gaXNUYWcoZWxlbSkmJm5hbWUoZWxlbS5uYW1lKX19ZWxzZSBpZihuYW1lPT09XCIqXCIpe3JldHVybiBpc1RhZ31lbHNle3JldHVybiBmdW5jdGlvbihlbGVtKXtyZXR1cm4gaXNUYWcoZWxlbSkmJmVsZW0ubmFtZT09PW5hbWV9fX0sdGFnX3R5cGU6ZnVuY3Rpb24odHlwZSl7aWYodHlwZW9mIHR5cGU9PT1cImZ1bmN0aW9uXCIpe3JldHVybiBmdW5jdGlvbihlbGVtKXtyZXR1cm4gdHlwZShlbGVtLnR5cGUpfX1lbHNle3JldHVybiBmdW5jdGlvbihlbGVtKXtyZXR1cm4gZWxlbS50eXBlPT09dHlwZX19fSx0YWdfY29udGFpbnM6ZnVuY3Rpb24oZGF0YSl7aWYodHlwZW9mIGRhdGE9PT1cImZ1bmN0aW9uXCIpe3JldHVybiBmdW5jdGlvbihlbGVtKXtyZXR1cm4haXNUYWcoZWxlbSkmJmRhdGEoZWxlbS5kYXRhKX19ZWxzZXtyZXR1cm4gZnVuY3Rpb24oZWxlbSl7cmV0dXJuIWlzVGFnKGVsZW0pJiZlbGVtLmRhdGE9PT1kYXRhfX19fTtmdW5jdGlvbiBnZXRBdHRyaWJDaGVjayhhdHRyaWIsdmFsdWUpe2lmKHR5cGVvZiB2YWx1ZT09PVwiZnVuY3Rpb25cIil7cmV0dXJuIGZ1bmN0aW9uKGVsZW0pe3JldHVybiBlbGVtLmF0dHJpYnMmJnZhbHVlKGVsZW0uYXR0cmlic1thdHRyaWJdKX19ZWxzZXtyZXR1cm4gZnVuY3Rpb24oZWxlbSl7cmV0dXJuIGVsZW0uYXR0cmlicyYmZWxlbS5hdHRyaWJzW2F0dHJpYl09PT12YWx1ZX19fWZ1bmN0aW9uIGNvbWJpbmVGdW5jcyhhLGIpe3JldHVybiBmdW5jdGlvbihlbGVtKXtyZXR1cm4gYShlbGVtKXx8YihlbGVtKX19ZXhwb3J0cy5nZXRFbGVtZW50cz1mdW5jdGlvbihvcHRpb25zLGVsZW1lbnQscmVjdXJzZSxsaW1pdCl7dmFyIGZ1bmNzPU9iamVjdC5rZXlzKG9wdGlvbnMpLm1hcChmdW5jdGlvbihrZXkpe3ZhciB2YWx1ZT1vcHRpb25zW2tleV07cmV0dXJuIGtleSBpbiBDaGVja3M/Q2hlY2tzW2tleV0odmFsdWUpOmdldEF0dHJpYkNoZWNrKGtleSx2YWx1ZSl9KTtyZXR1cm4gZnVuY3MubGVuZ3RoPT09MD9bXTp0aGlzLmZpbHRlcihmdW5jcy5yZWR1Y2UoY29tYmluZUZ1bmNzKSxlbGVtZW50LHJlY3Vyc2UsbGltaXQpfTtleHBvcnRzLmdldEVsZW1lbnRCeUlkPWZ1bmN0aW9uKGlkLGVsZW1lbnQscmVjdXJzZSl7aWYoIUFycmF5LmlzQXJyYXkoZWxlbWVudCkpZWxlbWVudD1bZWxlbWVudF07cmV0dXJuIHRoaXMuZmluZE9uZShnZXRBdHRyaWJDaGVjayhcImlkXCIsaWQpLGVsZW1lbnQscmVjdXJzZSE9PWZhbHNlKX07ZXhwb3J0cy5nZXRFbGVtZW50c0J5VGFnTmFtZT1mdW5jdGlvbihuYW1lLGVsZW1lbnQscmVjdXJzZSxsaW1pdCl7cmV0dXJuIHRoaXMuZmlsdGVyKENoZWNrcy50YWdfbmFtZShuYW1lKSxlbGVtZW50LHJlY3Vyc2UsbGltaXQpfTtleHBvcnRzLmdldEVsZW1lbnRzQnlUYWdUeXBlPWZ1bmN0aW9uKHR5cGUsZWxlbWVudCxyZWN1cnNlLGxpbWl0KXtyZXR1cm4gdGhpcy5maWx0ZXIoQ2hlY2tzLnRhZ190eXBlKHR5cGUpLGVsZW1lbnQscmVjdXJzZSxsaW1pdCl9fSx7ZG9tZWxlbWVudHR5cGU6OX1dLDE2OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtleHBvcnRzLnJlbW92ZUVsZW1lbnQ9ZnVuY3Rpb24oZWxlbSl7aWYoZWxlbS5wcmV2KWVsZW0ucHJldi5uZXh0PWVsZW0ubmV4dDtpZihlbGVtLm5leHQpZWxlbS5uZXh0LnByZXY9ZWxlbS5wcmV2O2lmKGVsZW0ucGFyZW50KXt2YXIgY2hpbGRzPWVsZW0ucGFyZW50LmNoaWxkcmVuO2NoaWxkcy5zcGxpY2UoY2hpbGRzLmxhc3RJbmRleE9mKGVsZW0pLDEpfX07ZXhwb3J0cy5yZXBsYWNlRWxlbWVudD1mdW5jdGlvbihlbGVtLHJlcGxhY2VtZW50KXt2YXIgcHJldj1yZXBsYWNlbWVudC5wcmV2PWVsZW0ucHJldjtpZihwcmV2KXtwcmV2Lm5leHQ9cmVwbGFjZW1lbnR9dmFyIG5leHQ9cmVwbGFjZW1lbnQubmV4dD1lbGVtLm5leHQ7aWYobmV4dCl7bmV4dC5wcmV2PXJlcGxhY2VtZW50fXZhciBwYXJlbnQ9cmVwbGFjZW1lbnQucGFyZW50PWVsZW0ucGFyZW50O2lmKHBhcmVudCl7dmFyIGNoaWxkcz1wYXJlbnQuY2hpbGRyZW47Y2hpbGRzW2NoaWxkcy5sYXN0SW5kZXhPZihlbGVtKV09cmVwbGFjZW1lbnR9fTtleHBvcnRzLmFwcGVuZENoaWxkPWZ1bmN0aW9uKGVsZW0sY2hpbGQpe2NoaWxkLnBhcmVudD1lbGVtO2lmKGVsZW0uY2hpbGRyZW4ucHVzaChjaGlsZCkhPT0xKXt2YXIgc2libGluZz1lbGVtLmNoaWxkcmVuW2VsZW0uY2hpbGRyZW4ubGVuZ3RoLTJdO3NpYmxpbmcubmV4dD1jaGlsZDtjaGlsZC5wcmV2PXNpYmxpbmc7Y2hpbGQubmV4dD1udWxsfX07ZXhwb3J0cy5hcHBlbmQ9ZnVuY3Rpb24oZWxlbSxuZXh0KXt2YXIgcGFyZW50PWVsZW0ucGFyZW50LGN1cnJOZXh0PWVsZW0ubmV4dDtuZXh0Lm5leHQ9Y3Vyck5leHQ7bmV4dC5wcmV2PWVsZW07ZWxlbS5uZXh0PW5leHQ7bmV4dC5wYXJlbnQ9cGFyZW50O2lmKGN1cnJOZXh0KXtjdXJyTmV4dC5wcmV2PW5leHQ7aWYocGFyZW50KXt2YXIgY2hpbGRzPXBhcmVudC5jaGlsZHJlbjtjaGlsZHMuc3BsaWNlKGNoaWxkcy5sYXN0SW5kZXhPZihjdXJyTmV4dCksMCxuZXh0KX19ZWxzZSBpZihwYXJlbnQpe3BhcmVudC5jaGlsZHJlbi5wdXNoKG5leHQpfX07ZXhwb3J0cy5wcmVwZW5kPWZ1bmN0aW9uKGVsZW0scHJldil7dmFyIHBhcmVudD1lbGVtLnBhcmVudDtpZihwYXJlbnQpe3ZhciBjaGlsZHM9cGFyZW50LmNoaWxkcmVuO2NoaWxkcy5zcGxpY2UoY2hpbGRzLmxhc3RJbmRleE9mKGVsZW0pLDAscHJldil9aWYoZWxlbS5wcmV2KXtlbGVtLnByZXYubmV4dD1wcmV2fXByZXYucGFyZW50PXBhcmVudDtwcmV2LnByZXY9ZWxlbS5wcmV2O3ByZXYubmV4dD1lbGVtO2VsZW0ucHJldj1wcmV2fX0se31dLDE3OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgaXNUYWc9cmVxdWlyZShcImRvbWVsZW1lbnR0eXBlXCIpLmlzVGFnO21vZHVsZS5leHBvcnRzPXtmaWx0ZXI6ZmlsdGVyLGZpbmQ6ZmluZCxmaW5kT25lQ2hpbGQ6ZmluZE9uZUNoaWxkLGZpbmRPbmU6ZmluZE9uZSxleGlzdHNPbmU6ZXhpc3RzT25lLGZpbmRBbGw6ZmluZEFsbH07ZnVuY3Rpb24gZmlsdGVyKHRlc3QsZWxlbWVudCxyZWN1cnNlLGxpbWl0KXtpZighQXJyYXkuaXNBcnJheShlbGVtZW50KSllbGVtZW50PVtlbGVtZW50XTtpZih0eXBlb2YgbGltaXQhPT1cIm51bWJlclwifHwhaXNGaW5pdGUobGltaXQpKXtsaW1pdD1JbmZpbml0eX1yZXR1cm4gZmluZCh0ZXN0LGVsZW1lbnQscmVjdXJzZSE9PWZhbHNlLGxpbWl0KX1mdW5jdGlvbiBmaW5kKHRlc3QsZWxlbXMscmVjdXJzZSxsaW1pdCl7dmFyIHJlc3VsdD1bXSxjaGlsZHM7Zm9yKHZhciBpPTAsaj1lbGVtcy5sZW5ndGg7aTxqO2krKyl7aWYodGVzdChlbGVtc1tpXSkpe3Jlc3VsdC5wdXNoKGVsZW1zW2ldKTtpZigtLWxpbWl0PD0wKWJyZWFrfWNoaWxkcz1lbGVtc1tpXS5jaGlsZHJlbjtpZihyZWN1cnNlJiZjaGlsZHMmJmNoaWxkcy5sZW5ndGg+MCl7Y2hpbGRzPWZpbmQodGVzdCxjaGlsZHMscmVjdXJzZSxsaW1pdCk7cmVzdWx0PXJlc3VsdC5jb25jYXQoY2hpbGRzKTtsaW1pdC09Y2hpbGRzLmxlbmd0aDtpZihsaW1pdDw9MClicmVha319cmV0dXJuIHJlc3VsdH1mdW5jdGlvbiBmaW5kT25lQ2hpbGQodGVzdCxlbGVtcyl7Zm9yKHZhciBpPTAsbD1lbGVtcy5sZW5ndGg7aTxsO2krKyl7aWYodGVzdChlbGVtc1tpXSkpcmV0dXJuIGVsZW1zW2ldfXJldHVybiBudWxsfWZ1bmN0aW9uIGZpbmRPbmUodGVzdCxlbGVtcyl7dmFyIGVsZW09bnVsbDtmb3IodmFyIGk9MCxsPWVsZW1zLmxlbmd0aDtpPGwmJiFlbGVtO2krKyl7aWYoIWlzVGFnKGVsZW1zW2ldKSl7Y29udGludWV9ZWxzZSBpZih0ZXN0KGVsZW1zW2ldKSl7ZWxlbT1lbGVtc1tpXX1lbHNlIGlmKGVsZW1zW2ldLmNoaWxkcmVuLmxlbmd0aD4wKXtlbGVtPWZpbmRPbmUodGVzdCxlbGVtc1tpXS5jaGlsZHJlbil9fXJldHVybiBlbGVtfWZ1bmN0aW9uIGV4aXN0c09uZSh0ZXN0LGVsZW1zKXtmb3IodmFyIGk9MCxsPWVsZW1zLmxlbmd0aDtpPGw7aSsrKXtpZihpc1RhZyhlbGVtc1tpXSkmJih0ZXN0KGVsZW1zW2ldKXx8ZWxlbXNbaV0uY2hpbGRyZW4ubGVuZ3RoPjAmJmV4aXN0c09uZSh0ZXN0LGVsZW1zW2ldLmNoaWxkcmVuKSkpe3JldHVybiB0cnVlfX1yZXR1cm4gZmFsc2V9ZnVuY3Rpb24gZmluZEFsbCh0ZXN0LGVsZW1zKXt2YXIgcmVzdWx0PVtdO2Zvcih2YXIgaT0wLGo9ZWxlbXMubGVuZ3RoO2k8ajtpKyspe2lmKCFpc1RhZyhlbGVtc1tpXSkpY29udGludWU7aWYodGVzdChlbGVtc1tpXSkpcmVzdWx0LnB1c2goZWxlbXNbaV0pO2lmKGVsZW1zW2ldLmNoaWxkcmVuLmxlbmd0aD4wKXtyZXN1bHQ9cmVzdWx0LmNvbmNhdChmaW5kQWxsKHRlc3QsZWxlbXNbaV0uY2hpbGRyZW4pKX19cmV0dXJuIHJlc3VsdH19LHtkb21lbGVtZW50dHlwZTo5fV0sMTg6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciBFbGVtZW50VHlwZT1yZXF1aXJlKFwiZG9tZWxlbWVudHR5cGVcIiksZ2V0T3V0ZXJIVE1MPXJlcXVpcmUoXCJkb20tc2VyaWFsaXplclwiKSxpc1RhZz1FbGVtZW50VHlwZS5pc1RhZzttb2R1bGUuZXhwb3J0cz17Z2V0SW5uZXJIVE1MOmdldElubmVySFRNTCxnZXRPdXRlckhUTUw6Z2V0T3V0ZXJIVE1MLGdldFRleHQ6Z2V0VGV4dH07ZnVuY3Rpb24gZ2V0SW5uZXJIVE1MKGVsZW0sb3B0cyl7cmV0dXJuIGVsZW0uY2hpbGRyZW4/ZWxlbS5jaGlsZHJlbi5tYXAoZnVuY3Rpb24oZWxlbSl7cmV0dXJuIGdldE91dGVySFRNTChlbGVtLG9wdHMpfSkuam9pbihcIlwiKTpcIlwifWZ1bmN0aW9uIGdldFRleHQoZWxlbSl7aWYoQXJyYXkuaXNBcnJheShlbGVtKSlyZXR1cm4gZWxlbS5tYXAoZ2V0VGV4dCkuam9pbihcIlwiKTtpZihpc1RhZyhlbGVtKXx8ZWxlbS50eXBlPT09RWxlbWVudFR5cGUuQ0RBVEEpcmV0dXJuIGdldFRleHQoZWxlbS5jaGlsZHJlbik7aWYoZWxlbS50eXBlPT09RWxlbWVudFR5cGUuVGV4dClyZXR1cm4gZWxlbS5kYXRhO3JldHVyblwiXCJ9fSx7XCJkb20tc2VyaWFsaXplclwiOjcsZG9tZWxlbWVudHR5cGU6OX1dLDE5OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgZ2V0Q2hpbGRyZW49ZXhwb3J0cy5nZXRDaGlsZHJlbj1mdW5jdGlvbihlbGVtKXtyZXR1cm4gZWxlbS5jaGlsZHJlbn07dmFyIGdldFBhcmVudD1leHBvcnRzLmdldFBhcmVudD1mdW5jdGlvbihlbGVtKXtyZXR1cm4gZWxlbS5wYXJlbnR9O2V4cG9ydHMuZ2V0U2libGluZ3M9ZnVuY3Rpb24oZWxlbSl7dmFyIHBhcmVudD1nZXRQYXJlbnQoZWxlbSk7cmV0dXJuIHBhcmVudD9nZXRDaGlsZHJlbihwYXJlbnQpOltlbGVtXX07ZXhwb3J0cy5nZXRBdHRyaWJ1dGVWYWx1ZT1mdW5jdGlvbihlbGVtLG5hbWUpe3JldHVybiBlbGVtLmF0dHJpYnMmJmVsZW0uYXR0cmlic1tuYW1lXX07ZXhwb3J0cy5oYXNBdHRyaWI9ZnVuY3Rpb24oZWxlbSxuYW1lKXtyZXR1cm4hIWVsZW0uYXR0cmlicyYmaGFzT3duUHJvcGVydHkuY2FsbChlbGVtLmF0dHJpYnMsbmFtZSl9O2V4cG9ydHMuZ2V0TmFtZT1mdW5jdGlvbihlbGVtKXtyZXR1cm4gZWxlbS5uYW1lfX0se31dLDIwOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgZW5jb2RlPXJlcXVpcmUoXCIuL2xpYi9lbmNvZGUuanNcIiksZGVjb2RlPXJlcXVpcmUoXCIuL2xpYi9kZWNvZGUuanNcIik7ZXhwb3J0cy5kZWNvZGU9ZnVuY3Rpb24oZGF0YSxsZXZlbCl7cmV0dXJuKCFsZXZlbHx8bGV2ZWw8PTA/ZGVjb2RlLlhNTDpkZWNvZGUuSFRNTCkoZGF0YSl9O2V4cG9ydHMuZGVjb2RlU3RyaWN0PWZ1bmN0aW9uKGRhdGEsbGV2ZWwpe3JldHVybighbGV2ZWx8fGxldmVsPD0wP2RlY29kZS5YTUw6ZGVjb2RlLkhUTUxTdHJpY3QpKGRhdGEpfTtleHBvcnRzLmVuY29kZT1mdW5jdGlvbihkYXRhLGxldmVsKXtyZXR1cm4oIWxldmVsfHxsZXZlbDw9MD9lbmNvZGUuWE1MOmVuY29kZS5IVE1MKShkYXRhKX07ZXhwb3J0cy5lbmNvZGVYTUw9ZW5jb2RlLlhNTDtleHBvcnRzLmVuY29kZUhUTUw0PWV4cG9ydHMuZW5jb2RlSFRNTDU9ZXhwb3J0cy5lbmNvZGVIVE1MPWVuY29kZS5IVE1MO2V4cG9ydHMuZGVjb2RlWE1MPWV4cG9ydHMuZGVjb2RlWE1MU3RyaWN0PWRlY29kZS5YTUw7ZXhwb3J0cy5kZWNvZGVIVE1MND1leHBvcnRzLmRlY29kZUhUTUw1PWV4cG9ydHMuZGVjb2RlSFRNTD1kZWNvZGUuSFRNTDtleHBvcnRzLmRlY29kZUhUTUw0U3RyaWN0PWV4cG9ydHMuZGVjb2RlSFRNTDVTdHJpY3Q9ZXhwb3J0cy5kZWNvZGVIVE1MU3RyaWN0PWRlY29kZS5IVE1MU3RyaWN0O2V4cG9ydHMuZXNjYXBlPWVuY29kZS5lc2NhcGV9LHtcIi4vbGliL2RlY29kZS5qc1wiOjIxLFwiLi9saWIvZW5jb2RlLmpzXCI6MjN9XSwyMTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIGVudGl0eU1hcD1yZXF1aXJlKFwiLi4vbWFwcy9lbnRpdGllcy5qc29uXCIpLGxlZ2FjeU1hcD1yZXF1aXJlKFwiLi4vbWFwcy9sZWdhY3kuanNvblwiKSx4bWxNYXA9cmVxdWlyZShcIi4uL21hcHMveG1sLmpzb25cIiksZGVjb2RlQ29kZVBvaW50PXJlcXVpcmUoXCIuL2RlY29kZV9jb2RlcG9pbnQuanNcIik7dmFyIGRlY29kZVhNTFN0cmljdD1nZXRTdHJpY3REZWNvZGVyKHhtbE1hcCksZGVjb2RlSFRNTFN0cmljdD1nZXRTdHJpY3REZWNvZGVyKGVudGl0eU1hcCk7ZnVuY3Rpb24gZ2V0U3RyaWN0RGVjb2RlcihtYXApe3ZhciBrZXlzPU9iamVjdC5rZXlzKG1hcCkuam9pbihcInxcIikscmVwbGFjZT1nZXRSZXBsYWNlcihtYXApO2tleXMrPVwifCNbeFhdW1xcXFxkYS1mQS1GXSt8I1xcXFxkK1wiO3ZhciByZT1uZXcgUmVnRXhwKFwiJig/OlwiK2tleXMrXCIpO1wiLFwiZ1wiKTtyZXR1cm4gZnVuY3Rpb24oc3RyKXtyZXR1cm4gU3RyaW5nKHN0cikucmVwbGFjZShyZSxyZXBsYWNlKX19dmFyIGRlY29kZUhUTUw9ZnVuY3Rpb24oKXt2YXIgbGVnYWN5PU9iamVjdC5rZXlzKGxlZ2FjeU1hcCkuc29ydChzb3J0ZXIpO3ZhciBrZXlzPU9iamVjdC5rZXlzKGVudGl0eU1hcCkuc29ydChzb3J0ZXIpO2Zvcih2YXIgaT0wLGo9MDtpPGtleXMubGVuZ3RoO2krKyl7aWYobGVnYWN5W2pdPT09a2V5c1tpXSl7a2V5c1tpXSs9XCI7P1wiO2orK31lbHNle2tleXNbaV0rPVwiO1wifX12YXIgcmU9bmV3IFJlZ0V4cChcIiYoPzpcIitrZXlzLmpvaW4oXCJ8XCIpK1wifCNbeFhdW1xcXFxkYS1mQS1GXSs7P3wjXFxcXGQrOz8pXCIsXCJnXCIpLHJlcGxhY2U9Z2V0UmVwbGFjZXIoZW50aXR5TWFwKTtmdW5jdGlvbiByZXBsYWNlcihzdHIpe2lmKHN0ci5zdWJzdHIoLTEpIT09XCI7XCIpc3RyKz1cIjtcIjtyZXR1cm4gcmVwbGFjZShzdHIpfXJldHVybiBmdW5jdGlvbihzdHIpe3JldHVybiBTdHJpbmcoc3RyKS5yZXBsYWNlKHJlLHJlcGxhY2VyKX19KCk7ZnVuY3Rpb24gc29ydGVyKGEsYil7cmV0dXJuIGE8Yj8xOi0xfWZ1bmN0aW9uIGdldFJlcGxhY2VyKG1hcCl7cmV0dXJuIGZ1bmN0aW9uIHJlcGxhY2Uoc3RyKXtpZihzdHIuY2hhckF0KDEpPT09XCIjXCIpe2lmKHN0ci5jaGFyQXQoMik9PT1cIlhcInx8c3RyLmNoYXJBdCgyKT09PVwieFwiKXtyZXR1cm4gZGVjb2RlQ29kZVBvaW50KHBhcnNlSW50KHN0ci5zdWJzdHIoMyksMTYpKX1yZXR1cm4gZGVjb2RlQ29kZVBvaW50KHBhcnNlSW50KHN0ci5zdWJzdHIoMiksMTApKX1yZXR1cm4gbWFwW3N0ci5zbGljZSgxLC0xKV07XG59fW1vZHVsZS5leHBvcnRzPXtYTUw6ZGVjb2RlWE1MU3RyaWN0LEhUTUw6ZGVjb2RlSFRNTCxIVE1MU3RyaWN0OmRlY29kZUhUTUxTdHJpY3R9fSx7XCIuLi9tYXBzL2VudGl0aWVzLmpzb25cIjoyNSxcIi4uL21hcHMvbGVnYWN5Lmpzb25cIjoyNixcIi4uL21hcHMveG1sLmpzb25cIjoyNyxcIi4vZGVjb2RlX2NvZGVwb2ludC5qc1wiOjIyfV0sMjI6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciBkZWNvZGVNYXA9cmVxdWlyZShcIi4uL21hcHMvZGVjb2RlLmpzb25cIik7bW9kdWxlLmV4cG9ydHM9ZGVjb2RlQ29kZVBvaW50O2Z1bmN0aW9uIGRlY29kZUNvZGVQb2ludChjb2RlUG9pbnQpe2lmKGNvZGVQb2ludD49NTUyOTYmJmNvZGVQb2ludDw9NTczNDN8fGNvZGVQb2ludD4xMTE0MTExKXtyZXR1cm5cIu+/vVwifWlmKGNvZGVQb2ludCBpbiBkZWNvZGVNYXApe2NvZGVQb2ludD1kZWNvZGVNYXBbY29kZVBvaW50XX12YXIgb3V0cHV0PVwiXCI7aWYoY29kZVBvaW50PjY1NTM1KXtjb2RlUG9pbnQtPTY1NTM2O291dHB1dCs9U3RyaW5nLmZyb21DaGFyQ29kZShjb2RlUG9pbnQ+Pj4xMCYxMDIzfDU1Mjk2KTtjb2RlUG9pbnQ9NTYzMjB8Y29kZVBvaW50JjEwMjN9b3V0cHV0Kz1TdHJpbmcuZnJvbUNoYXJDb2RlKGNvZGVQb2ludCk7cmV0dXJuIG91dHB1dH19LHtcIi4uL21hcHMvZGVjb2RlLmpzb25cIjoyNH1dLDIzOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgaW52ZXJzZVhNTD1nZXRJbnZlcnNlT2JqKHJlcXVpcmUoXCIuLi9tYXBzL3htbC5qc29uXCIpKSx4bWxSZXBsYWNlcj1nZXRJbnZlcnNlUmVwbGFjZXIoaW52ZXJzZVhNTCk7ZXhwb3J0cy5YTUw9Z2V0SW52ZXJzZShpbnZlcnNlWE1MLHhtbFJlcGxhY2VyKTt2YXIgaW52ZXJzZUhUTUw9Z2V0SW52ZXJzZU9iaihyZXF1aXJlKFwiLi4vbWFwcy9lbnRpdGllcy5qc29uXCIpKSxodG1sUmVwbGFjZXI9Z2V0SW52ZXJzZVJlcGxhY2VyKGludmVyc2VIVE1MKTtleHBvcnRzLkhUTUw9Z2V0SW52ZXJzZShpbnZlcnNlSFRNTCxodG1sUmVwbGFjZXIpO2Z1bmN0aW9uIGdldEludmVyc2VPYmoob2JqKXtyZXR1cm4gT2JqZWN0LmtleXMob2JqKS5zb3J0KCkucmVkdWNlKGZ1bmN0aW9uKGludmVyc2UsbmFtZSl7aW52ZXJzZVtvYmpbbmFtZV1dPVwiJlwiK25hbWUrXCI7XCI7cmV0dXJuIGludmVyc2V9LHt9KX1mdW5jdGlvbiBnZXRJbnZlcnNlUmVwbGFjZXIoaW52ZXJzZSl7dmFyIHNpbmdsZT1bXSxtdWx0aXBsZT1bXTtPYmplY3Qua2V5cyhpbnZlcnNlKS5mb3JFYWNoKGZ1bmN0aW9uKGspe2lmKGsubGVuZ3RoPT09MSl7c2luZ2xlLnB1c2goXCJcXFxcXCIrayl9ZWxzZXttdWx0aXBsZS5wdXNoKGspfX0pO211bHRpcGxlLnVuc2hpZnQoXCJbXCIrc2luZ2xlLmpvaW4oXCJcIikrXCJdXCIpO3JldHVybiBuZXcgUmVnRXhwKG11bHRpcGxlLmpvaW4oXCJ8XCIpLFwiZ1wiKX12YXIgcmVfbm9uQVNDSUk9L1teXFwwLVxceDdGXS9nLHJlX2FzdHJhbFN5bWJvbHM9L1tcXHVEODAwLVxcdURCRkZdW1xcdURDMDAtXFx1REZGRl0vZztmdW5jdGlvbiBzaW5nbGVDaGFyUmVwbGFjZXIoYyl7cmV0dXJuXCImI3hcIitjLmNoYXJDb2RlQXQoMCkudG9TdHJpbmcoMTYpLnRvVXBwZXJDYXNlKCkrXCI7XCJ9ZnVuY3Rpb24gYXN0cmFsUmVwbGFjZXIoYyl7dmFyIGhpZ2g9Yy5jaGFyQ29kZUF0KDApO3ZhciBsb3c9Yy5jaGFyQ29kZUF0KDEpO3ZhciBjb2RlUG9pbnQ9KGhpZ2gtNTUyOTYpKjEwMjQrbG93LTU2MzIwKzY1NTM2O3JldHVyblwiJiN4XCIrY29kZVBvaW50LnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpK1wiO1wifWZ1bmN0aW9uIGdldEludmVyc2UoaW52ZXJzZSxyZSl7ZnVuY3Rpb24gZnVuYyhuYW1lKXtyZXR1cm4gaW52ZXJzZVtuYW1lXX1yZXR1cm4gZnVuY3Rpb24oZGF0YSl7cmV0dXJuIGRhdGEucmVwbGFjZShyZSxmdW5jKS5yZXBsYWNlKHJlX2FzdHJhbFN5bWJvbHMsYXN0cmFsUmVwbGFjZXIpLnJlcGxhY2UocmVfbm9uQVNDSUksc2luZ2xlQ2hhclJlcGxhY2VyKX19dmFyIHJlX3htbENoYXJzPWdldEludmVyc2VSZXBsYWNlcihpbnZlcnNlWE1MKTtmdW5jdGlvbiBlc2NhcGVYTUwoZGF0YSl7cmV0dXJuIGRhdGEucmVwbGFjZShyZV94bWxDaGFycyxzaW5nbGVDaGFyUmVwbGFjZXIpLnJlcGxhY2UocmVfYXN0cmFsU3ltYm9scyxhc3RyYWxSZXBsYWNlcikucmVwbGFjZShyZV9ub25BU0NJSSxzaW5nbGVDaGFyUmVwbGFjZXIpfWV4cG9ydHMuZXNjYXBlPWVzY2FwZVhNTH0se1wiLi4vbWFwcy9lbnRpdGllcy5qc29uXCI6MjUsXCIuLi9tYXBzL3htbC5qc29uXCI6Mjd9XSwyNDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9ezA6NjU1MzMsMTI4OjgzNjQsMTMwOjgyMTgsMTMxOjQwMiwxMzI6ODIyMiwxMzM6ODIzMCwxMzQ6ODIyNCwxMzU6ODIyNSwxMzY6NzEwLDEzNzo4MjQwLDEzODozNTIsMTM5OjgyNDksMTQwOjMzOCwxNDI6MzgxLDE0NTo4MjE2LDE0Njo4MjE3LDE0Nzo4MjIwLDE0ODo4MjIxLDE0OTo4MjI2LDE1MDo4MjExLDE1MTo4MjEyLDE1Mjo3MzIsMTUzOjg0ODIsMTU0OjM1MywxNTU6ODI1MCwxNTY6MzM5LDE1ODozODIsMTU5OjM3Nn19LHt9XSwyNTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9e0FhY3V0ZTpcIsOBXCIsYWFjdXRlOlwiw6FcIixBYnJldmU6XCLEglwiLGFicmV2ZTpcIsSDXCIsYWM6XCLiiL5cIixhY2Q6XCLiiL9cIixhY0U6XCLiiL7Ms1wiLEFjaXJjOlwiw4JcIixhY2lyYzpcIsOiXCIsYWN1dGU6XCLCtFwiLEFjeTpcItCQXCIsYWN5Olwi0LBcIixBRWxpZzpcIsOGXCIsYWVsaWc6XCLDplwiLGFmOlwi4oGhXCIsQWZyOlwi8J2UhFwiLGFmcjpcIvCdlJ5cIixBZ3JhdmU6XCLDgFwiLGFncmF2ZTpcIsOgXCIsYWxlZnN5bTpcIuKEtVwiLGFsZXBoOlwi4oS1XCIsQWxwaGE6XCLOkVwiLGFscGhhOlwizrFcIixBbWFjcjpcIsSAXCIsYW1hY3I6XCLEgVwiLGFtYWxnOlwi4qi/XCIsYW1wOlwiJlwiLEFNUDpcIiZcIixhbmRhbmQ6XCLiqZVcIixBbmQ6XCLiqZNcIixhbmQ6XCLiiKdcIixhbmRkOlwi4qmcXCIsYW5kc2xvcGU6XCLiqZhcIixhbmR2Olwi4qmaXCIsYW5nOlwi4oigXCIsYW5nZTpcIuKmpFwiLGFuZ2xlOlwi4oigXCIsYW5nbXNkYWE6XCLipqhcIixhbmdtc2RhYjpcIuKmqVwiLGFuZ21zZGFjOlwi4qaqXCIsYW5nbXNkYWQ6XCLipqtcIixhbmdtc2RhZTpcIuKmrFwiLGFuZ21zZGFmOlwi4qatXCIsYW5nbXNkYWc6XCLipq5cIixhbmdtc2RhaDpcIuKmr1wiLGFuZ21zZDpcIuKIoVwiLGFuZ3J0Olwi4oifXCIsYW5ncnR2YjpcIuKKvlwiLGFuZ3J0dmJkOlwi4qadXCIsYW5nc3BoOlwi4oiiXCIsYW5nc3Q6XCLDhVwiLGFuZ3phcnI6XCLijbxcIixBb2dvbjpcIsSEXCIsYW9nb246XCLEhVwiLEFvcGY6XCLwnZS4XCIsYW9wZjpcIvCdlZJcIixhcGFjaXI6XCLiqa9cIixhcDpcIuKJiFwiLGFwRTpcIuKpsFwiLGFwZTpcIuKJilwiLGFwaWQ6XCLiiYtcIixhcG9zOlwiJ1wiLEFwcGx5RnVuY3Rpb246XCLigaFcIixhcHByb3g6XCLiiYhcIixhcHByb3hlcTpcIuKJilwiLEFyaW5nOlwiw4VcIixhcmluZzpcIsOlXCIsQXNjcjpcIvCdkpxcIixhc2NyOlwi8J2StlwiLEFzc2lnbjpcIuKJlFwiLGFzdDpcIipcIixhc3ltcDpcIuKJiFwiLGFzeW1wZXE6XCLiiY1cIixBdGlsZGU6XCLDg1wiLGF0aWxkZTpcIsOjXCIsQXVtbDpcIsOEXCIsYXVtbDpcIsOkXCIsYXdjb25pbnQ6XCLiiLNcIixhd2ludDpcIuKokVwiLGJhY2tjb25nOlwi4omMXCIsYmFja2Vwc2lsb246XCLPtlwiLGJhY2twcmltZTpcIuKAtVwiLGJhY2tzaW06XCLiiL1cIixiYWNrc2ltZXE6XCLii41cIixCYWNrc2xhc2g6XCLiiJZcIixCYXJ2Olwi4qunXCIsYmFydmVlOlwi4oq9XCIsYmFyd2VkOlwi4oyFXCIsQmFyd2VkOlwi4oyGXCIsYmFyd2VkZ2U6XCLijIVcIixiYnJrOlwi4o61XCIsYmJya3Ricms6XCLijrZcIixiY29uZzpcIuKJjFwiLEJjeTpcItCRXCIsYmN5Olwi0LFcIixiZHF1bzpcIuKAnlwiLGJlY2F1czpcIuKItVwiLGJlY2F1c2U6XCLiiLVcIixCZWNhdXNlOlwi4oi1XCIsYmVtcHR5djpcIuKmsFwiLGJlcHNpOlwiz7ZcIixiZXJub3U6XCLihKxcIixCZXJub3VsbGlzOlwi4oSsXCIsQmV0YTpcIs6SXCIsYmV0YTpcIs6yXCIsYmV0aDpcIuKEtlwiLGJldHdlZW46XCLiiaxcIixCZnI6XCLwnZSFXCIsYmZyOlwi8J2Un1wiLGJpZ2NhcDpcIuKLglwiLGJpZ2NpcmM6XCLil69cIixiaWdjdXA6XCLii4NcIixiaWdvZG90Olwi4qiAXCIsYmlnb3BsdXM6XCLiqIFcIixiaWdvdGltZXM6XCLiqIJcIixiaWdzcWN1cDpcIuKohlwiLGJpZ3N0YXI6XCLimIVcIixiaWd0cmlhbmdsZWRvd246XCLilr1cIixiaWd0cmlhbmdsZXVwOlwi4pazXCIsYmlndXBsdXM6XCLiqIRcIixiaWd2ZWU6XCLii4FcIixiaWd3ZWRnZTpcIuKLgFwiLGJrYXJvdzpcIuKkjVwiLGJsYWNrbG96ZW5nZTpcIuKnq1wiLGJsYWNrc3F1YXJlOlwi4paqXCIsYmxhY2t0cmlhbmdsZTpcIuKWtFwiLGJsYWNrdHJpYW5nbGVkb3duOlwi4pa+XCIsYmxhY2t0cmlhbmdsZWxlZnQ6XCLil4JcIixibGFja3RyaWFuZ2xlcmlnaHQ6XCLilrhcIixibGFuazpcIuKQo1wiLGJsazEyOlwi4paSXCIsYmxrMTQ6XCLilpFcIixibGszNDpcIuKWk1wiLGJsb2NrOlwi4paIXCIsYm5lOlwiPeKDpVwiLGJuZXF1aXY6XCLiiaHig6VcIixiTm90Olwi4qutXCIsYm5vdDpcIuKMkFwiLEJvcGY6XCLwnZS5XCIsYm9wZjpcIvCdlZNcIixib3Q6XCLiiqVcIixib3R0b206XCLiiqVcIixib3d0aWU6XCLii4hcIixib3hib3g6XCLip4lcIixib3hkbDpcIuKUkFwiLGJveGRMOlwi4pWVXCIsYm94RGw6XCLilZZcIixib3hETDpcIuKVl1wiLGJveGRyOlwi4pSMXCIsYm94ZFI6XCLilZJcIixib3hEcjpcIuKVk1wiLGJveERSOlwi4pWUXCIsYm94aDpcIuKUgFwiLGJveEg6XCLilZBcIixib3hoZDpcIuKUrFwiLGJveEhkOlwi4pWkXCIsYm94aEQ6XCLilaVcIixib3hIRDpcIuKVplwiLGJveGh1Olwi4pS0XCIsYm94SHU6XCLiladcIixib3hoVTpcIuKVqFwiLGJveEhVOlwi4pWpXCIsYm94bWludXM6XCLiip9cIixib3hwbHVzOlwi4oqeXCIsYm94dGltZXM6XCLiiqBcIixib3h1bDpcIuKUmFwiLGJveHVMOlwi4pWbXCIsYm94VWw6XCLilZxcIixib3hVTDpcIuKVnVwiLGJveHVyOlwi4pSUXCIsYm94dVI6XCLilZhcIixib3hVcjpcIuKVmVwiLGJveFVSOlwi4pWaXCIsYm94djpcIuKUglwiLGJveFY6XCLilZFcIixib3h2aDpcIuKUvFwiLGJveHZIOlwi4pWqXCIsYm94Vmg6XCLilatcIixib3hWSDpcIuKVrFwiLGJveHZsOlwi4pSkXCIsYm94dkw6XCLilaFcIixib3hWbDpcIuKVolwiLGJveFZMOlwi4pWjXCIsYm94dnI6XCLilJxcIixib3h2UjpcIuKVnlwiLGJveFZyOlwi4pWfXCIsYm94VlI6XCLilaBcIixicHJpbWU6XCLigLVcIixicmV2ZTpcIsuYXCIsQnJldmU6XCLLmFwiLGJydmJhcjpcIsKmXCIsYnNjcjpcIvCdkrdcIixCc2NyOlwi4oSsXCIsYnNlbWk6XCLigY9cIixic2ltOlwi4oi9XCIsYnNpbWU6XCLii41cIixic29sYjpcIuKnhVwiLGJzb2w6XCJcXFxcXCIsYnNvbGhzdWI6XCLin4hcIixidWxsOlwi4oCiXCIsYnVsbGV0Olwi4oCiXCIsYnVtcDpcIuKJjlwiLGJ1bXBFOlwi4qquXCIsYnVtcGU6XCLiiY9cIixCdW1wZXE6XCLiiY5cIixidW1wZXE6XCLiiY9cIixDYWN1dGU6XCLEhlwiLGNhY3V0ZTpcIsSHXCIsY2FwYW5kOlwi4qmEXCIsY2FwYnJjdXA6XCLiqYlcIixjYXBjYXA6XCLiqYtcIixjYXA6XCLiiKlcIixDYXA6XCLii5JcIixjYXBjdXA6XCLiqYdcIixjYXBkb3Q6XCLiqYBcIixDYXBpdGFsRGlmZmVyZW50aWFsRDpcIuKFhVwiLGNhcHM6XCLiiKnvuIBcIixjYXJldDpcIuKBgVwiLGNhcm9uOlwiy4dcIixDYXlsZXlzOlwi4oStXCIsY2NhcHM6XCLiqY1cIixDY2Fyb246XCLEjFwiLGNjYXJvbjpcIsSNXCIsQ2NlZGlsOlwiw4dcIixjY2VkaWw6XCLDp1wiLENjaXJjOlwixIhcIixjY2lyYzpcIsSJXCIsQ2NvbmludDpcIuKIsFwiLGNjdXBzOlwi4qmMXCIsY2N1cHNzbTpcIuKpkFwiLENkb3Q6XCLEilwiLGNkb3Q6XCLEi1wiLGNlZGlsOlwiwrhcIixDZWRpbGxhOlwiwrhcIixjZW1wdHl2Olwi4qayXCIsY2VudDpcIsKiXCIsY2VudGVyZG90OlwiwrdcIixDZW50ZXJEb3Q6XCLCt1wiLGNmcjpcIvCdlKBcIixDZnI6XCLihK1cIixDSGN5Olwi0KdcIixjaGN5Olwi0YdcIixjaGVjazpcIuKck1wiLGNoZWNrbWFyazpcIuKck1wiLENoaTpcIs6nXCIsY2hpOlwiz4dcIixjaXJjOlwiy4ZcIixjaXJjZXE6XCLiiZdcIixjaXJjbGVhcnJvd2xlZnQ6XCLihrpcIixjaXJjbGVhcnJvd3JpZ2h0Olwi4oa7XCIsY2lyY2xlZGFzdDpcIuKKm1wiLGNpcmNsZWRjaXJjOlwi4oqaXCIsY2lyY2xlZGRhc2g6XCLiip1cIixDaXJjbGVEb3Q6XCLiiplcIixjaXJjbGVkUjpcIsKuXCIsY2lyY2xlZFM6XCLik4hcIixDaXJjbGVNaW51czpcIuKKllwiLENpcmNsZVBsdXM6XCLiipVcIixDaXJjbGVUaW1lczpcIuKKl1wiLGNpcjpcIuKXi1wiLGNpckU6XCLip4NcIixjaXJlOlwi4omXXCIsY2lyZm5pbnQ6XCLiqJBcIixjaXJtaWQ6XCLiq69cIixjaXJzY2lyOlwi4qeCXCIsQ2xvY2t3aXNlQ29udG91ckludGVncmFsOlwi4oiyXCIsQ2xvc2VDdXJseURvdWJsZVF1b3RlOlwi4oCdXCIsQ2xvc2VDdXJseVF1b3RlOlwi4oCZXCIsY2x1YnM6XCLimaNcIixjbHVic3VpdDpcIuKZo1wiLGNvbG9uOlwiOlwiLENvbG9uOlwi4oi3XCIsQ29sb25lOlwi4qm0XCIsY29sb25lOlwi4omUXCIsY29sb25lcTpcIuKJlFwiLGNvbW1hOlwiLFwiLGNvbW1hdDpcIkBcIixjb21wOlwi4oiBXCIsY29tcGZuOlwi4oiYXCIsY29tcGxlbWVudDpcIuKIgVwiLGNvbXBsZXhlczpcIuKEglwiLGNvbmc6XCLiiYVcIixjb25nZG90Olwi4qmtXCIsQ29uZ3J1ZW50Olwi4omhXCIsY29uaW50Olwi4oiuXCIsQ29uaW50Olwi4oivXCIsQ29udG91ckludGVncmFsOlwi4oiuXCIsY29wZjpcIvCdlZRcIixDb3BmOlwi4oSCXCIsY29wcm9kOlwi4oiQXCIsQ29wcm9kdWN0Olwi4oiQXCIsY29weTpcIsKpXCIsQ09QWTpcIsKpXCIsY29weXNyOlwi4oSXXCIsQ291bnRlckNsb2Nrd2lzZUNvbnRvdXJJbnRlZ3JhbDpcIuKIs1wiLGNyYXJyOlwi4oa1XCIsY3Jvc3M6XCLinJdcIixDcm9zczpcIuKor1wiLENzY3I6XCLwnZKeXCIsY3NjcjpcIvCdkrhcIixjc3ViOlwi4quPXCIsY3N1YmU6XCLiq5FcIixjc3VwOlwi4quQXCIsY3N1cGU6XCLiq5JcIixjdGRvdDpcIuKLr1wiLGN1ZGFycmw6XCLipLhcIixjdWRhcnJyOlwi4qS1XCIsY3VlcHI6XCLii55cIixjdWVzYzpcIuKLn1wiLGN1bGFycjpcIuKGtlwiLGN1bGFycnA6XCLipL1cIixjdXBicmNhcDpcIuKpiFwiLGN1cGNhcDpcIuKphlwiLEN1cENhcDpcIuKJjVwiLGN1cDpcIuKIqlwiLEN1cDpcIuKLk1wiLGN1cGN1cDpcIuKpilwiLGN1cGRvdDpcIuKKjVwiLGN1cG9yOlwi4qmFXCIsY3VwczpcIuKIqu+4gFwiLGN1cmFycjpcIuKGt1wiLGN1cmFycm06XCLipLxcIixjdXJseWVxcHJlYzpcIuKLnlwiLGN1cmx5ZXFzdWNjOlwi4oufXCIsY3VybHl2ZWU6XCLii45cIixjdXJseXdlZGdlOlwi4ouPXCIsY3VycmVuOlwiwqRcIixjdXJ2ZWFycm93bGVmdDpcIuKGtlwiLGN1cnZlYXJyb3dyaWdodDpcIuKGt1wiLGN1dmVlOlwi4ouOXCIsY3V3ZWQ6XCLii49cIixjd2NvbmludDpcIuKIslwiLGN3aW50Olwi4oixXCIsY3lsY3R5Olwi4oytXCIsZGFnZ2VyOlwi4oCgXCIsRGFnZ2VyOlwi4oChXCIsZGFsZXRoOlwi4oS4XCIsZGFycjpcIuKGk1wiLERhcnI6XCLihqFcIixkQXJyOlwi4oeTXCIsZGFzaDpcIuKAkFwiLERhc2h2Olwi4qukXCIsZGFzaHY6XCLiiqNcIixkYmthcm93Olwi4qSPXCIsZGJsYWM6XCLLnVwiLERjYXJvbjpcIsSOXCIsZGNhcm9uOlwixI9cIixEY3k6XCLQlFwiLGRjeTpcItC0XCIsZGRhZ2dlcjpcIuKAoVwiLGRkYXJyOlwi4oeKXCIsREQ6XCLihYVcIixkZDpcIuKFhlwiLEREb3RyYWhkOlwi4qSRXCIsZGRvdHNlcTpcIuKpt1wiLGRlZzpcIsKwXCIsRGVsOlwi4oiHXCIsRGVsdGE6XCLOlFwiLGRlbHRhOlwizrRcIixkZW1wdHl2Olwi4qaxXCIsZGZpc2h0Olwi4qW/XCIsRGZyOlwi8J2Uh1wiLGRmcjpcIvCdlKFcIixkSGFyOlwi4qWlXCIsZGhhcmw6XCLih4NcIixkaGFycjpcIuKHglwiLERpYWNyaXRpY2FsQWN1dGU6XCLCtFwiLERpYWNyaXRpY2FsRG90Olwiy5lcIixEaWFjcml0aWNhbERvdWJsZUFjdXRlOlwiy51cIixEaWFjcml0aWNhbEdyYXZlOlwiYFwiLERpYWNyaXRpY2FsVGlsZGU6XCLLnFwiLGRpYW06XCLii4RcIixkaWFtb25kOlwi4ouEXCIsRGlhbW9uZDpcIuKLhFwiLGRpYW1vbmRzdWl0Olwi4pmmXCIsZGlhbXM6XCLimaZcIixkaWU6XCLCqFwiLERpZmZlcmVudGlhbEQ6XCLihYZcIixkaWdhbW1hOlwiz51cIixkaXNpbjpcIuKLslwiLGRpdjpcIsO3XCIsZGl2aWRlOlwiw7dcIixkaXZpZGVvbnRpbWVzOlwi4ouHXCIsZGl2b254Olwi4ouHXCIsREpjeTpcItCCXCIsZGpjeTpcItGSXCIsZGxjb3JuOlwi4oyeXCIsZGxjcm9wOlwi4oyNXCIsZG9sbGFyOlwiJFwiLERvcGY6XCLwnZS7XCIsZG9wZjpcIvCdlZVcIixEb3Q6XCLCqFwiLGRvdDpcIsuZXCIsRG90RG90Olwi4oOcXCIsZG90ZXE6XCLiiZBcIixkb3RlcWRvdDpcIuKJkVwiLERvdEVxdWFsOlwi4omQXCIsZG90bWludXM6XCLiiLhcIixkb3RwbHVzOlwi4oiUXCIsZG90c3F1YXJlOlwi4oqhXCIsZG91YmxlYmFyd2VkZ2U6XCLijIZcIixEb3VibGVDb250b3VySW50ZWdyYWw6XCLiiK9cIixEb3VibGVEb3Q6XCLCqFwiLERvdWJsZURvd25BcnJvdzpcIuKHk1wiLERvdWJsZUxlZnRBcnJvdzpcIuKHkFwiLERvdWJsZUxlZnRSaWdodEFycm93Olwi4oeUXCIsRG91YmxlTGVmdFRlZTpcIuKrpFwiLERvdWJsZUxvbmdMZWZ0QXJyb3c6XCLin7hcIixEb3VibGVMb25nTGVmdFJpZ2h0QXJyb3c6XCLin7pcIixEb3VibGVMb25nUmlnaHRBcnJvdzpcIuKfuVwiLERvdWJsZVJpZ2h0QXJyb3c6XCLih5JcIixEb3VibGVSaWdodFRlZTpcIuKKqFwiLERvdWJsZVVwQXJyb3c6XCLih5FcIixEb3VibGVVcERvd25BcnJvdzpcIuKHlVwiLERvdWJsZVZlcnRpY2FsQmFyOlwi4oilXCIsRG93bkFycm93QmFyOlwi4qSTXCIsZG93bmFycm93Olwi4oaTXCIsRG93bkFycm93Olwi4oaTXCIsRG93bmFycm93Olwi4oeTXCIsRG93bkFycm93VXBBcnJvdzpcIuKHtVwiLERvd25CcmV2ZTpcIsyRXCIsZG93bmRvd25hcnJvd3M6XCLih4pcIixkb3duaGFycG9vbmxlZnQ6XCLih4NcIixkb3duaGFycG9vbnJpZ2h0Olwi4oeCXCIsRG93bkxlZnRSaWdodFZlY3RvcjpcIuKlkFwiLERvd25MZWZ0VGVlVmVjdG9yOlwi4qWeXCIsRG93bkxlZnRWZWN0b3JCYXI6XCLipZZcIixEb3duTGVmdFZlY3RvcjpcIuKGvVwiLERvd25SaWdodFRlZVZlY3RvcjpcIuKln1wiLERvd25SaWdodFZlY3RvckJhcjpcIuKll1wiLERvd25SaWdodFZlY3RvcjpcIuKHgVwiLERvd25UZWVBcnJvdzpcIuKGp1wiLERvd25UZWU6XCLiiqRcIixkcmJrYXJvdzpcIuKkkFwiLGRyY29ybjpcIuKMn1wiLGRyY3JvcDpcIuKMjFwiLERzY3I6XCLwnZKfXCIsZHNjcjpcIvCdkrlcIixEU2N5Olwi0IVcIixkc2N5Olwi0ZVcIixkc29sOlwi4qe2XCIsRHN0cm9rOlwixJBcIixkc3Ryb2s6XCLEkVwiLGR0ZG90Olwi4ouxXCIsZHRyaTpcIuKWv1wiLGR0cmlmOlwi4pa+XCIsZHVhcnI6XCLih7VcIixkdWhhcjpcIuKlr1wiLGR3YW5nbGU6XCLipqZcIixEWmN5Olwi0I9cIixkemN5Olwi0Z9cIixkemlncmFycjpcIuKfv1wiLEVhY3V0ZTpcIsOJXCIsZWFjdXRlOlwiw6lcIixlYXN0ZXI6XCLiqa5cIixFY2Fyb246XCLEmlwiLGVjYXJvbjpcIsSbXCIsRWNpcmM6XCLDilwiLGVjaXJjOlwiw6pcIixlY2lyOlwi4omWXCIsZWNvbG9uOlwi4omVXCIsRWN5Olwi0K1cIixlY3k6XCLRjVwiLGVERG90Olwi4qm3XCIsRWRvdDpcIsSWXCIsZWRvdDpcIsSXXCIsZURvdDpcIuKJkVwiLGVlOlwi4oWHXCIsZWZEb3Q6XCLiiZJcIixFZnI6XCLwnZSIXCIsZWZyOlwi8J2UolwiLGVnOlwi4qqaXCIsRWdyYXZlOlwiw4hcIixlZ3JhdmU6XCLDqFwiLGVnczpcIuKqllwiLGVnc2RvdDpcIuKqmFwiLGVsOlwi4qqZXCIsRWxlbWVudDpcIuKIiFwiLGVsaW50ZXJzOlwi4o+nXCIsZWxsOlwi4oSTXCIsZWxzOlwi4qqVXCIsZWxzZG90Olwi4qqXXCIsRW1hY3I6XCLEklwiLGVtYWNyOlwixJNcIixlbXB0eTpcIuKIhVwiLGVtcHR5c2V0Olwi4oiFXCIsRW1wdHlTbWFsbFNxdWFyZTpcIuKXu1wiLGVtcHR5djpcIuKIhVwiLEVtcHR5VmVyeVNtYWxsU3F1YXJlOlwi4parXCIsZW1zcDEzOlwi4oCEXCIsZW1zcDE0Olwi4oCFXCIsZW1zcDpcIuKAg1wiLEVORzpcIsWKXCIsZW5nOlwixYtcIixlbnNwOlwi4oCCXCIsRW9nb246XCLEmFwiLGVvZ29uOlwixJlcIixFb3BmOlwi8J2UvFwiLGVvcGY6XCLwnZWWXCIsZXBhcjpcIuKLlVwiLGVwYXJzbDpcIuKno1wiLGVwbHVzOlwi4qmxXCIsZXBzaTpcIs61XCIsRXBzaWxvbjpcIs6VXCIsZXBzaWxvbjpcIs61XCIsZXBzaXY6XCLPtVwiLGVxY2lyYzpcIuKJllwiLGVxY29sb246XCLiiZVcIixlcXNpbTpcIuKJglwiLGVxc2xhbnRndHI6XCLiqpZcIixlcXNsYW50bGVzczpcIuKqlVwiLEVxdWFsOlwi4qm1XCIsZXF1YWxzOlwiPVwiLEVxdWFsVGlsZGU6XCLiiYJcIixlcXVlc3Q6XCLiiZ9cIixFcXVpbGlicml1bTpcIuKHjFwiLGVxdWl2Olwi4omhXCIsZXF1aXZERDpcIuKpuFwiLGVxdnBhcnNsOlwi4qelXCIsZXJhcnI6XCLipbFcIixlckRvdDpcIuKJk1wiLGVzY3I6XCLihK9cIixFc2NyOlwi4oSwXCIsZXNkb3Q6XCLiiZBcIixFc2ltOlwi4qmzXCIsZXNpbTpcIuKJglwiLEV0YTpcIs6XXCIsZXRhOlwizrdcIixFVEg6XCLDkFwiLGV0aDpcIsOwXCIsRXVtbDpcIsOLXCIsZXVtbDpcIsOrXCIsZXVybzpcIuKCrFwiLGV4Y2w6XCIhXCIsZXhpc3Q6XCLiiINcIixFeGlzdHM6XCLiiINcIixleHBlY3RhdGlvbjpcIuKEsFwiLGV4cG9uZW50aWFsZTpcIuKFh1wiLEV4cG9uZW50aWFsRTpcIuKFh1wiLGZhbGxpbmdkb3RzZXE6XCLiiZJcIixGY3k6XCLQpFwiLGZjeTpcItGEXCIsZmVtYWxlOlwi4pmAXCIsZmZpbGlnOlwi76yDXCIsZmZsaWc6XCLvrIBcIixmZmxsaWc6XCLvrIRcIixGZnI6XCLwnZSJXCIsZmZyOlwi8J2Uo1wiLGZpbGlnOlwi76yBXCIsRmlsbGVkU21hbGxTcXVhcmU6XCLil7xcIixGaWxsZWRWZXJ5U21hbGxTcXVhcmU6XCLilqpcIixmamxpZzpcImZqXCIsZmxhdDpcIuKZrVwiLGZsbGlnOlwi76yCXCIsZmx0bnM6XCLilrFcIixmbm9mOlwixpJcIixGb3BmOlwi8J2UvVwiLGZvcGY6XCLwnZWXXCIsZm9yYWxsOlwi4oiAXCIsRm9yQWxsOlwi4oiAXCIsZm9yazpcIuKLlFwiLGZvcmt2Olwi4quZXCIsRm91cmllcnRyZjpcIuKEsVwiLGZwYXJ0aW50Olwi4qiNXCIsZnJhYzEyOlwiwr1cIixmcmFjMTM6XCLihZNcIixmcmFjMTQ6XCLCvFwiLGZyYWMxNTpcIuKFlVwiLGZyYWMxNjpcIuKFmVwiLGZyYWMxODpcIuKFm1wiLGZyYWMyMzpcIuKFlFwiLGZyYWMyNTpcIuKFllwiLGZyYWMzNDpcIsK+XCIsZnJhYzM1Olwi4oWXXCIsZnJhYzM4Olwi4oWcXCIsZnJhYzQ1Olwi4oWYXCIsZnJhYzU2Olwi4oWaXCIsZnJhYzU4Olwi4oWdXCIsZnJhYzc4Olwi4oWeXCIsZnJhc2w6XCLigYRcIixmcm93bjpcIuKMolwiLGZzY3I6XCLwnZK7XCIsRnNjcjpcIuKEsVwiLGdhY3V0ZTpcIse1XCIsR2FtbWE6XCLOk1wiLGdhbW1hOlwizrNcIixHYW1tYWQ6XCLPnFwiLGdhbW1hZDpcIs+dXCIsZ2FwOlwi4qqGXCIsR2JyZXZlOlwixJ5cIixnYnJldmU6XCLEn1wiLEdjZWRpbDpcIsSiXCIsR2NpcmM6XCLEnFwiLGdjaXJjOlwixJ1cIixHY3k6XCLQk1wiLGdjeTpcItCzXCIsR2RvdDpcIsSgXCIsZ2RvdDpcIsShXCIsZ2U6XCLiiaVcIixnRTpcIuKJp1wiLGdFbDpcIuKqjFwiLGdlbDpcIuKLm1wiLGdlcTpcIuKJpVwiLGdlcXE6XCLiiadcIixnZXFzbGFudDpcIuKpvlwiLGdlc2NjOlwi4qqpXCIsZ2VzOlwi4qm+XCIsZ2VzZG90Olwi4qqAXCIsZ2VzZG90bzpcIuKqglwiLGdlc2RvdG9sOlwi4qqEXCIsZ2VzbDpcIuKLm++4gFwiLGdlc2xlczpcIuKqlFwiLEdmcjpcIvCdlIpcIixnZnI6XCLwnZSkXCIsZ2c6XCLiiatcIixHZzpcIuKLmVwiLGdnZzpcIuKLmVwiLGdpbWVsOlwi4oS3XCIsR0pjeTpcItCDXCIsZ2pjeTpcItGTXCIsZ2xhOlwi4qqlXCIsZ2w6XCLiibdcIixnbEU6XCLiqpJcIixnbGo6XCLiqqRcIixnbmFwOlwi4qqKXCIsZ25hcHByb3g6XCLiqopcIixnbmU6XCLiqohcIixnbkU6XCLiialcIixnbmVxOlwi4qqIXCIsZ25lcXE6XCLiialcIixnbnNpbTpcIuKLp1wiLEdvcGY6XCLwnZS+XCIsZ29wZjpcIvCdlZhcIixncmF2ZTpcImBcIixHcmVhdGVyRXF1YWw6XCLiiaVcIixHcmVhdGVyRXF1YWxMZXNzOlwi4oubXCIsR3JlYXRlckZ1bGxFcXVhbDpcIuKJp1wiLEdyZWF0ZXJHcmVhdGVyOlwi4qqiXCIsR3JlYXRlckxlc3M6XCLiibdcIixHcmVhdGVyU2xhbnRFcXVhbDpcIuKpvlwiLEdyZWF0ZXJUaWxkZTpcIuKJs1wiLEdzY3I6XCLwnZKiXCIsZ3NjcjpcIuKEilwiLGdzaW06XCLiibNcIixnc2ltZTpcIuKqjlwiLGdzaW1sOlwi4qqQXCIsZ3RjYzpcIuKqp1wiLGd0Y2lyOlwi4qm6XCIsZ3Q6XCI+XCIsR1Q6XCI+XCIsR3Q6XCLiiatcIixndGRvdDpcIuKLl1wiLGd0bFBhcjpcIuKmlVwiLGd0cXVlc3Q6XCLiqbxcIixndHJhcHByb3g6XCLiqoZcIixndHJhcnI6XCLipbhcIixndHJkb3Q6XCLii5dcIixndHJlcWxlc3M6XCLii5tcIixndHJlcXFsZXNzOlwi4qqMXCIsZ3RybGVzczpcIuKJt1wiLGd0cnNpbTpcIuKJs1wiLGd2ZXJ0bmVxcTpcIuKJqe+4gFwiLGd2bkU6XCLiianvuIBcIixIYWNlazpcIsuHXCIsaGFpcnNwOlwi4oCKXCIsaGFsZjpcIsK9XCIsaGFtaWx0Olwi4oSLXCIsSEFSRGN5Olwi0KpcIixoYXJkY3k6XCLRilwiLGhhcnJjaXI6XCLipYhcIixoYXJyOlwi4oaUXCIsaEFycjpcIuKHlFwiLGhhcnJ3Olwi4oatXCIsSGF0OlwiXlwiLGhiYXI6XCLihI9cIixIY2lyYzpcIsSkXCIsaGNpcmM6XCLEpVwiLGhlYXJ0czpcIuKZpVwiLGhlYXJ0c3VpdDpcIuKZpVwiLGhlbGxpcDpcIuKAplwiLGhlcmNvbjpcIuKKuVwiLGhmcjpcIvCdlKVcIixIZnI6XCLihIxcIixIaWxiZXJ0U3BhY2U6XCLihItcIixoa3NlYXJvdzpcIuKkpVwiLGhrc3dhcm93Olwi4qSmXCIsaG9hcnI6XCLih79cIixob210aHQ6XCLiiLtcIixob29rbGVmdGFycm93Olwi4oapXCIsaG9va3JpZ2h0YXJyb3c6XCLihqpcIixob3BmOlwi8J2VmVwiLEhvcGY6XCLihI1cIixob3JiYXI6XCLigJVcIixIb3Jpem9udGFsTGluZTpcIuKUgFwiLGhzY3I6XCLwnZK9XCIsSHNjcjpcIuKEi1wiLGhzbGFzaDpcIuKEj1wiLEhzdHJvazpcIsSmXCIsaHN0cm9rOlwixKdcIixIdW1wRG93bkh1bXA6XCLiiY5cIixIdW1wRXF1YWw6XCLiiY9cIixoeWJ1bGw6XCLigYNcIixoeXBoZW46XCLigJBcIixJYWN1dGU6XCLDjVwiLGlhY3V0ZTpcIsOtXCIsaWM6XCLigaNcIixJY2lyYzpcIsOOXCIsaWNpcmM6XCLDrlwiLEljeTpcItCYXCIsaWN5Olwi0LhcIixJZG90OlwixLBcIixJRWN5Olwi0JVcIixpZWN5Olwi0LVcIixpZXhjbDpcIsKhXCIsaWZmOlwi4oeUXCIsaWZyOlwi8J2UplwiLElmcjpcIuKEkVwiLElncmF2ZTpcIsOMXCIsaWdyYXZlOlwiw6xcIixpaTpcIuKFiFwiLGlpaWludDpcIuKojFwiLGlpaW50Olwi4oitXCIsaWluZmluOlwi4qecXCIsaWlvdGE6XCLihKlcIixJSmxpZzpcIsSyXCIsaWpsaWc6XCLEs1wiLEltYWNyOlwixKpcIixpbWFjcjpcIsSrXCIsaW1hZ2U6XCLihJFcIixJbWFnaW5hcnlJOlwi4oWIXCIsaW1hZ2xpbmU6XCLihJBcIixpbWFncGFydDpcIuKEkVwiLGltYXRoOlwixLFcIixJbTpcIuKEkVwiLGltb2Y6XCLiirdcIixpbXBlZDpcIsa1XCIsSW1wbGllczpcIuKHklwiLGluY2FyZTpcIuKEhVwiLGluOlwi4oiIXCIsaW5maW46XCLiiJ5cIixpbmZpbnRpZTpcIuKnnVwiLGlub2RvdDpcIsSxXCIsaW50Y2FsOlwi4oq6XCIsaW50Olwi4oirXCIsSW50Olwi4oisXCIsaW50ZWdlcnM6XCLihKRcIixJbnRlZ3JhbDpcIuKIq1wiLGludGVyY2FsOlwi4oq6XCIsSW50ZXJzZWN0aW9uOlwi4ouCXCIsaW50bGFyaGs6XCLiqJdcIixpbnRwcm9kOlwi4qi8XCIsSW52aXNpYmxlQ29tbWE6XCLigaNcIixJbnZpc2libGVUaW1lczpcIuKBolwiLElPY3k6XCLQgVwiLGlvY3k6XCLRkVwiLElvZ29uOlwixK5cIixpb2dvbjpcIsSvXCIsSW9wZjpcIvCdlYBcIixpb3BmOlwi8J2VmlwiLElvdGE6XCLOmVwiLGlvdGE6XCLOuVwiLGlwcm9kOlwi4qi8XCIsaXF1ZXN0Olwiwr9cIixpc2NyOlwi8J2SvlwiLElzY3I6XCLihJBcIixpc2luOlwi4oiIXCIsaXNpbmRvdDpcIuKLtVwiLGlzaW5FOlwi4ou5XCIsaXNpbnM6XCLii7RcIixpc2luc3Y6XCLii7NcIixpc2ludjpcIuKIiFwiLGl0Olwi4oGiXCIsSXRpbGRlOlwixKhcIixpdGlsZGU6XCLEqVwiLEl1a2N5Olwi0IZcIixpdWtjeTpcItGWXCIsSXVtbDpcIsOPXCIsaXVtbDpcIsOvXCIsSmNpcmM6XCLEtFwiLGpjaXJjOlwixLVcIixKY3k6XCLQmVwiLGpjeTpcItC5XCIsSmZyOlwi8J2UjVwiLGpmcjpcIvCdlKdcIixqbWF0aDpcIsi3XCIsSm9wZjpcIvCdlYFcIixqb3BmOlwi8J2Vm1wiLEpzY3I6XCLwnZKlXCIsanNjcjpcIvCdkr9cIixKc2VyY3k6XCLQiFwiLGpzZXJjeTpcItGYXCIsSnVrY3k6XCLQhFwiLGp1a2N5Olwi0ZRcIixLYXBwYTpcIs6aXCIsa2FwcGE6XCLOulwiLGthcHBhdjpcIs+wXCIsS2NlZGlsOlwixLZcIixrY2VkaWw6XCLEt1wiLEtjeTpcItCaXCIsa2N5Olwi0LpcIixLZnI6XCLwnZSOXCIsa2ZyOlwi8J2UqFwiLGtncmVlbjpcIsS4XCIsS0hjeTpcItClXCIsa2hjeTpcItGFXCIsS0pjeTpcItCMXCIsa2pjeTpcItGcXCIsS29wZjpcIvCdlYJcIixrb3BmOlwi8J2VnFwiLEtzY3I6XCLwnZKmXCIsa3NjcjpcIvCdk4BcIixsQWFycjpcIuKHmlwiLExhY3V0ZTpcIsS5XCIsbGFjdXRlOlwixLpcIixsYWVtcHR5djpcIuKmtFwiLGxhZ3JhbjpcIuKEklwiLExhbWJkYTpcIs6bXCIsbGFtYmRhOlwizrtcIixsYW5nOlwi4p+oXCIsTGFuZzpcIuKfqlwiLGxhbmdkOlwi4qaRXCIsbGFuZ2xlOlwi4p+oXCIsbGFwOlwi4qqFXCIsTGFwbGFjZXRyZjpcIuKEklwiLGxhcXVvOlwiwqtcIixsYXJyYjpcIuKHpFwiLGxhcnJiZnM6XCLipJ9cIixsYXJyOlwi4oaQXCIsTGFycjpcIuKGnlwiLGxBcnI6XCLih5BcIixsYXJyZnM6XCLipJ1cIixsYXJyaGs6XCLihqlcIixsYXJybHA6XCLihqtcIixsYXJycGw6XCLipLlcIixsYXJyc2ltOlwi4qWzXCIsbGFycnRsOlwi4oaiXCIsbGF0YWlsOlwi4qSZXCIsbEF0YWlsOlwi4qSbXCIsbGF0Olwi4qqrXCIsbGF0ZTpcIuKqrVwiLGxhdGVzOlwi4qqt77iAXCIsbGJhcnI6XCLipIxcIixsQmFycjpcIuKkjlwiLGxiYnJrOlwi4p2yXCIsbGJyYWNlOlwie1wiLGxicmFjazpcIltcIixsYnJrZTpcIuKmi1wiLGxicmtzbGQ6XCLipo9cIixsYnJrc2x1Olwi4qaNXCIsTGNhcm9uOlwixL1cIixsY2Fyb246XCLEvlwiLExjZWRpbDpcIsS7XCIsbGNlZGlsOlwixLxcIixsY2VpbDpcIuKMiFwiLGxjdWI6XCJ7XCIsTGN5Olwi0JtcIixsY3k6XCLQu1wiLGxkY2E6XCLipLZcIixsZHF1bzpcIuKAnFwiLGxkcXVvcjpcIuKAnlwiLGxkcmRoYXI6XCLipadcIixsZHJ1c2hhcjpcIuKli1wiLGxkc2g6XCLihrJcIixsZTpcIuKJpFwiLGxFOlwi4ommXCIsTGVmdEFuZ2xlQnJhY2tldDpcIuKfqFwiLExlZnRBcnJvd0JhcjpcIuKHpFwiLGxlZnRhcnJvdzpcIuKGkFwiLExlZnRBcnJvdzpcIuKGkFwiLExlZnRhcnJvdzpcIuKHkFwiLExlZnRBcnJvd1JpZ2h0QXJyb3c6XCLih4ZcIixsZWZ0YXJyb3d0YWlsOlwi4oaiXCIsTGVmdENlaWxpbmc6XCLijIhcIixMZWZ0RG91YmxlQnJhY2tldDpcIuKfplwiLExlZnREb3duVGVlVmVjdG9yOlwi4qWhXCIsTGVmdERvd25WZWN0b3JCYXI6XCLipZlcIixMZWZ0RG93blZlY3RvcjpcIuKHg1wiLExlZnRGbG9vcjpcIuKMilwiLGxlZnRoYXJwb29uZG93bjpcIuKGvVwiLGxlZnRoYXJwb29udXA6XCLihrxcIixsZWZ0bGVmdGFycm93czpcIuKHh1wiLGxlZnRyaWdodGFycm93Olwi4oaUXCIsTGVmdFJpZ2h0QXJyb3c6XCLihpRcIixMZWZ0cmlnaHRhcnJvdzpcIuKHlFwiLGxlZnRyaWdodGFycm93czpcIuKHhlwiLGxlZnRyaWdodGhhcnBvb25zOlwi4oeLXCIsbGVmdHJpZ2h0c3F1aWdhcnJvdzpcIuKGrVwiLExlZnRSaWdodFZlY3RvcjpcIuKljlwiLExlZnRUZWVBcnJvdzpcIuKGpFwiLExlZnRUZWU6XCLiiqNcIixMZWZ0VGVlVmVjdG9yOlwi4qWaXCIsbGVmdHRocmVldGltZXM6XCLii4tcIixMZWZ0VHJpYW5nbGVCYXI6XCLip49cIixMZWZ0VHJpYW5nbGU6XCLiirJcIixMZWZ0VHJpYW5nbGVFcXVhbDpcIuKKtFwiLExlZnRVcERvd25WZWN0b3I6XCLipZFcIixMZWZ0VXBUZWVWZWN0b3I6XCLipaBcIixMZWZ0VXBWZWN0b3JCYXI6XCLipZhcIixMZWZ0VXBWZWN0b3I6XCLihr9cIixMZWZ0VmVjdG9yQmFyOlwi4qWSXCIsTGVmdFZlY3RvcjpcIuKGvFwiLGxFZzpcIuKqi1wiLGxlZzpcIuKLmlwiLGxlcTpcIuKJpFwiLGxlcXE6XCLiiaZcIixsZXFzbGFudDpcIuKpvVwiLGxlc2NjOlwi4qqoXCIsbGVzOlwi4qm9XCIsbGVzZG90Olwi4qm/XCIsbGVzZG90bzpcIuKqgVwiLGxlc2RvdG9yOlwi4qqDXCIsbGVzZzpcIuKLmu+4gFwiLGxlc2dlczpcIuKqk1wiLGxlc3NhcHByb3g6XCLiqoVcIixsZXNzZG90Olwi4ouWXCIsbGVzc2VxZ3RyOlwi4ouaXCIsbGVzc2VxcWd0cjpcIuKqi1wiLExlc3NFcXVhbEdyZWF0ZXI6XCLii5pcIixMZXNzRnVsbEVxdWFsOlwi4ommXCIsTGVzc0dyZWF0ZXI6XCLiibZcIixsZXNzZ3RyOlwi4om2XCIsTGVzc0xlc3M6XCLiqqFcIixsZXNzc2ltOlwi4omyXCIsTGVzc1NsYW50RXF1YWw6XCLiqb1cIixMZXNzVGlsZGU6XCLiibJcIixsZmlzaHQ6XCLipbxcIixsZmxvb3I6XCLijIpcIixMZnI6XCLwnZSPXCIsbGZyOlwi8J2UqVwiLGxnOlwi4om2XCIsbGdFOlwi4qqRXCIsbEhhcjpcIuKlolwiLGxoYXJkOlwi4oa9XCIsbGhhcnU6XCLihrxcIixsaGFydWw6XCLipapcIixsaGJsazpcIuKWhFwiLExKY3k6XCLQiVwiLGxqY3k6XCLRmVwiLGxsYXJyOlwi4oeHXCIsbGw6XCLiiapcIixMbDpcIuKLmFwiLGxsY29ybmVyOlwi4oyeXCIsTGxlZnRhcnJvdzpcIuKHmlwiLGxsaGFyZDpcIuKlq1wiLGxsdHJpOlwi4pe6XCIsTG1pZG90OlwixL9cIixsbWlkb3Q6XCLFgFwiLGxtb3VzdGFjaGU6XCLijrBcIixsbW91c3Q6XCLijrBcIixsbmFwOlwi4qqJXCIsbG5hcHByb3g6XCLiqolcIixsbmU6XCLiqodcIixsbkU6XCLiiahcIixsbmVxOlwi4qqHXCIsbG5lcXE6XCLiiahcIixsbnNpbTpcIuKLplwiLGxvYW5nOlwi4p+sXCIsbG9hcnI6XCLih71cIixsb2JyazpcIuKfplwiLGxvbmdsZWZ0YXJyb3c6XCLin7VcIixMb25nTGVmdEFycm93Olwi4p+1XCIsTG9uZ2xlZnRhcnJvdzpcIuKfuFwiLGxvbmdsZWZ0cmlnaHRhcnJvdzpcIuKft1wiLExvbmdMZWZ0UmlnaHRBcnJvdzpcIuKft1wiLExvbmdsZWZ0cmlnaHRhcnJvdzpcIuKfulwiLGxvbmdtYXBzdG86XCLin7xcIixsb25ncmlnaHRhcnJvdzpcIuKftlwiLExvbmdSaWdodEFycm93Olwi4p+2XCIsTG9uZ3JpZ2h0YXJyb3c6XCLin7lcIixsb29wYXJyb3dsZWZ0Olwi4oarXCIsbG9vcGFycm93cmlnaHQ6XCLihqxcIixsb3BhcjpcIuKmhVwiLExvcGY6XCLwnZWDXCIsbG9wZjpcIvCdlZ1cIixsb3BsdXM6XCLiqK1cIixsb3RpbWVzOlwi4qi0XCIsbG93YXN0Olwi4oiXXCIsbG93YmFyOlwiX1wiLExvd2VyTGVmdEFycm93Olwi4oaZXCIsTG93ZXJSaWdodEFycm93Olwi4oaYXCIsbG96Olwi4peKXCIsbG96ZW5nZTpcIuKXilwiLGxvemY6XCLip6tcIixscGFyOlwiKFwiLGxwYXJsdDpcIuKmk1wiLGxyYXJyOlwi4oeGXCIsbHJjb3JuZXI6XCLijJ9cIixscmhhcjpcIuKHi1wiLGxyaGFyZDpcIuKlrVwiLGxybTpcIuKAjlwiLGxydHJpOlwi4oq/XCIsbHNhcXVvOlwi4oC5XCIsbHNjcjpcIvCdk4FcIixMc2NyOlwi4oSSXCIsbHNoOlwi4oawXCIsTHNoOlwi4oawXCIsbHNpbTpcIuKJslwiLGxzaW1lOlwi4qqNXCIsbHNpbWc6XCLiqo9cIixsc3FiOlwiW1wiLGxzcXVvOlwi4oCYXCIsbHNxdW9yOlwi4oCaXCIsTHN0cm9rOlwixYFcIixsc3Ryb2s6XCLFglwiLGx0Y2M6XCLiqqZcIixsdGNpcjpcIuKpuVwiLGx0OlwiPFwiLExUOlwiPFwiLEx0Olwi4omqXCIsbHRkb3Q6XCLii5ZcIixsdGhyZWU6XCLii4tcIixsdGltZXM6XCLii4lcIixsdGxhcnI6XCLipbZcIixsdHF1ZXN0Olwi4qm7XCIsbHRyaTpcIuKXg1wiLGx0cmllOlwi4oq0XCIsbHRyaWY6XCLil4JcIixsdHJQYXI6XCLippZcIixsdXJkc2hhcjpcIuKlilwiLGx1cnVoYXI6XCLipaZcIixsdmVydG5lcXE6XCLiiajvuIBcIixsdm5FOlwi4omo77iAXCIsbWFjcjpcIsKvXCIsbWFsZTpcIuKZglwiLG1hbHQ6XCLinKBcIixtYWx0ZXNlOlwi4pygXCIsTWFwOlwi4qSFXCIsbWFwOlwi4oamXCIsbWFwc3RvOlwi4oamXCIsbWFwc3RvZG93bjpcIuKGp1wiLG1hcHN0b2xlZnQ6XCLihqRcIixtYXBzdG91cDpcIuKGpVwiLG1hcmtlcjpcIuKWrlwiLG1jb21tYTpcIuKoqVwiLE1jeTpcItCcXCIsbWN5Olwi0LxcIixtZGFzaDpcIuKAlFwiLG1ERG90Olwi4oi6XCIsbWVhc3VyZWRhbmdsZTpcIuKIoVwiLE1lZGl1bVNwYWNlOlwi4oGfXCIsTWVsbGludHJmOlwi4oSzXCIsTWZyOlwi8J2UkFwiLG1mcjpcIvCdlKpcIixtaG86XCLihKdcIixtaWNybzpcIsK1XCIsbWlkYXN0OlwiKlwiLG1pZGNpcjpcIuKrsFwiLG1pZDpcIuKIo1wiLG1pZGRvdDpcIsK3XCIsbWludXNiOlwi4oqfXCIsbWludXM6XCLiiJJcIixtaW51c2Q6XCLiiLhcIixtaW51c2R1Olwi4qiqXCIsTWludXNQbHVzOlwi4oiTXCIsbWxjcDpcIuKrm1wiLG1sZHI6XCLigKZcIixtbnBsdXM6XCLiiJNcIixtb2RlbHM6XCLiiqdcIixNb3BmOlwi8J2VhFwiLG1vcGY6XCLwnZWeXCIsbXA6XCLiiJNcIixtc2NyOlwi8J2TglwiLE1zY3I6XCLihLNcIixtc3Rwb3M6XCLiiL5cIixNdTpcIs6cXCIsbXU6XCLOvFwiLG11bHRpbWFwOlwi4oq4XCIsbXVtYXA6XCLiirhcIixuYWJsYTpcIuKIh1wiLE5hY3V0ZTpcIsWDXCIsbmFjdXRlOlwixYRcIixuYW5nOlwi4oig4oOSXCIsbmFwOlwi4omJXCIsbmFwRTpcIuKpsMy4XCIsbmFwaWQ6XCLiiYvMuFwiLG5hcG9zOlwixYlcIixuYXBwcm94Olwi4omJXCIsbmF0dXJhbDpcIuKZrlwiLG5hdHVyYWxzOlwi4oSVXCIsbmF0dXI6XCLima5cIixuYnNwOlwiwqBcIixuYnVtcDpcIuKJjsy4XCIsbmJ1bXBlOlwi4omPzLhcIixuY2FwOlwi4qmDXCIsTmNhcm9uOlwixYdcIixuY2Fyb246XCLFiFwiLE5jZWRpbDpcIsWFXCIsbmNlZGlsOlwixYZcIixuY29uZzpcIuKJh1wiLG5jb25nZG90Olwi4qmtzLhcIixuY3VwOlwi4qmCXCIsTmN5Olwi0J1cIixuY3k6XCLQvVwiLG5kYXNoOlwi4oCTXCIsbmVhcmhrOlwi4qSkXCIsbmVhcnI6XCLihpdcIixuZUFycjpcIuKHl1wiLG5lYXJyb3c6XCLihpdcIixuZTpcIuKJoFwiLG5lZG90Olwi4omQzLhcIixOZWdhdGl2ZU1lZGl1bVNwYWNlOlwi4oCLXCIsTmVnYXRpdmVUaGlja1NwYWNlOlwi4oCLXCIsTmVnYXRpdmVUaGluU3BhY2U6XCLigItcIixOZWdhdGl2ZVZlcnlUaGluU3BhY2U6XCLigItcIixuZXF1aXY6XCLiiaJcIixuZXNlYXI6XCLipKhcIixuZXNpbTpcIuKJgsy4XCIsTmVzdGVkR3JlYXRlckdyZWF0ZXI6XCLiiatcIixOZXN0ZWRMZXNzTGVzczpcIuKJqlwiLE5ld0xpbmU6XCJcXG5cIixuZXhpc3Q6XCLiiIRcIixuZXhpc3RzOlwi4oiEXCIsTmZyOlwi8J2UkVwiLG5mcjpcIvCdlKtcIixuZ0U6XCLiiafMuFwiLG5nZTpcIuKJsVwiLG5nZXE6XCLiibFcIixuZ2VxcTpcIuKJp8y4XCIsbmdlcXNsYW50Olwi4qm+zLhcIixuZ2VzOlwi4qm+zLhcIixuR2c6XCLii5nMuFwiLG5nc2ltOlwi4om1XCIsbkd0Olwi4omr4oOSXCIsbmd0Olwi4omvXCIsbmd0cjpcIuKJr1wiLG5HdHY6XCLiiavMuFwiLG5oYXJyOlwi4oauXCIsbmhBcnI6XCLih45cIixuaHBhcjpcIuKrslwiLG5pOlwi4oiLXCIsbmlzOlwi4ou8XCIsbmlzZDpcIuKLulwiLG5pdjpcIuKIi1wiLE5KY3k6XCLQilwiLG5qY3k6XCLRmlwiLG5sYXJyOlwi4oaaXCIsbmxBcnI6XCLih41cIixubGRyOlwi4oClXCIsbmxFOlwi4ommzLhcIixubGU6XCLiibBcIixubGVmdGFycm93Olwi4oaaXCIsbkxlZnRhcnJvdzpcIuKHjVwiLG5sZWZ0cmlnaHRhcnJvdzpcIuKGrlwiLG5MZWZ0cmlnaHRhcnJvdzpcIuKHjlwiLG5sZXE6XCLiibBcIixubGVxcTpcIuKJpsy4XCIsbmxlcXNsYW50Olwi4qm9zLhcIixubGVzOlwi4qm9zLhcIixubGVzczpcIuKJrlwiLG5MbDpcIuKLmMy4XCIsbmxzaW06XCLiibRcIixuTHQ6XCLiiarig5JcIixubHQ6XCLiia5cIixubHRyaTpcIuKLqlwiLG5sdHJpZTpcIuKLrFwiLG5MdHY6XCLiiarMuFwiLG5taWQ6XCLiiKRcIixOb0JyZWFrOlwi4oGgXCIsTm9uQnJlYWtpbmdTcGFjZTpcIsKgXCIsbm9wZjpcIvCdlZ9cIixOb3BmOlwi4oSVXCIsTm90Olwi4qusXCIsbm90OlwiwqxcIixOb3RDb25ncnVlbnQ6XCLiiaJcIixOb3RDdXBDYXA6XCLiia1cIixOb3REb3VibGVWZXJ0aWNhbEJhcjpcIuKIplwiLE5vdEVsZW1lbnQ6XCLiiIlcIixOb3RFcXVhbDpcIuKJoFwiLE5vdEVxdWFsVGlsZGU6XCLiiYLMuFwiLE5vdEV4aXN0czpcIuKIhFwiLE5vdEdyZWF0ZXI6XCLiia9cIixOb3RHcmVhdGVyRXF1YWw6XCLiibFcIixOb3RHcmVhdGVyRnVsbEVxdWFsOlwi4omnzLhcIixOb3RHcmVhdGVyR3JlYXRlcjpcIuKJq8y4XCIsTm90R3JlYXRlckxlc3M6XCLiiblcIixOb3RHcmVhdGVyU2xhbnRFcXVhbDpcIuKpvsy4XCIsTm90R3JlYXRlclRpbGRlOlwi4om1XCIsTm90SHVtcERvd25IdW1wOlwi4omOzLhcIixOb3RIdW1wRXF1YWw6XCLiiY/MuFwiLG5vdGluOlwi4oiJXCIsbm90aW5kb3Q6XCLii7XMuFwiLG5vdGluRTpcIuKLucy4XCIsbm90aW52YTpcIuKIiVwiLG5vdGludmI6XCLii7dcIixub3RpbnZjOlwi4ou2XCIsTm90TGVmdFRyaWFuZ2xlQmFyOlwi4qePzLhcIixOb3RMZWZ0VHJpYW5nbGU6XCLii6pcIixOb3RMZWZ0VHJpYW5nbGVFcXVhbDpcIuKLrFwiLE5vdExlc3M6XCLiia5cIixOb3RMZXNzRXF1YWw6XCLiibBcIixOb3RMZXNzR3JlYXRlcjpcIuKJuFwiLE5vdExlc3NMZXNzOlwi4omqzLhcIixOb3RMZXNzU2xhbnRFcXVhbDpcIuKpvcy4XCIsTm90TGVzc1RpbGRlOlwi4om0XCIsTm90TmVzdGVkR3JlYXRlckdyZWF0ZXI6XCLiqqLMuFwiLE5vdE5lc3RlZExlc3NMZXNzOlwi4qqhzLhcIixub3RuaTpcIuKIjFwiLG5vdG5pdmE6XCLiiIxcIixub3RuaXZiOlwi4ou+XCIsbm90bml2YzpcIuKLvVwiLE5vdFByZWNlZGVzOlwi4oqAXCIsTm90UHJlY2VkZXNFcXVhbDpcIuKqr8y4XCIsTm90UHJlY2VkZXNTbGFudEVxdWFsOlwi4ougXCIsTm90UmV2ZXJzZUVsZW1lbnQ6XCLiiIxcIixOb3RSaWdodFRyaWFuZ2xlQmFyOlwi4qeQzLhcIixOb3RSaWdodFRyaWFuZ2xlOlwi4ourXCIsTm90UmlnaHRUcmlhbmdsZUVxdWFsOlwi4outXCIsTm90U3F1YXJlU3Vic2V0Olwi4oqPzLhcIixOb3RTcXVhcmVTdWJzZXRFcXVhbDpcIuKLolwiLE5vdFNxdWFyZVN1cGVyc2V0Olwi4oqQzLhcIixOb3RTcXVhcmVTdXBlcnNldEVxdWFsOlwi4oujXCIsTm90U3Vic2V0Olwi4oqC4oOSXCIsTm90U3Vic2V0RXF1YWw6XCLiiohcIixOb3RTdWNjZWVkczpcIuKKgVwiLE5vdFN1Y2NlZWRzRXF1YWw6XCLiqrDMuFwiLE5vdFN1Y2NlZWRzU2xhbnRFcXVhbDpcIuKLoVwiLE5vdFN1Y2NlZWRzVGlsZGU6XCLiib/MuFwiLE5vdFN1cGVyc2V0Olwi4oqD4oOSXCIsTm90U3VwZXJzZXRFcXVhbDpcIuKKiVwiLE5vdFRpbGRlOlwi4omBXCIsTm90VGlsZGVFcXVhbDpcIuKJhFwiLE5vdFRpbGRlRnVsbEVxdWFsOlwi4omHXCIsTm90VGlsZGVUaWxkZTpcIuKJiVwiLE5vdFZlcnRpY2FsQmFyOlwi4oikXCIsbnBhcmFsbGVsOlwi4oimXCIsbnBhcjpcIuKIplwiLG5wYXJzbDpcIuKrveKDpVwiLG5wYXJ0Olwi4oiCzLhcIixucG9saW50Olwi4qiUXCIsbnByOlwi4oqAXCIsbnByY3VlOlwi4ougXCIsbnByZWM6XCLiioBcIixucHJlY2VxOlwi4qqvzLhcIixucHJlOlwi4qqvzLhcIixucmFycmM6XCLipLPMuFwiLG5yYXJyOlwi4oabXCIsbnJBcnI6XCLih49cIixucmFycnc6XCLihp3MuFwiLG5yaWdodGFycm93Olwi4oabXCIsblJpZ2h0YXJyb3c6XCLih49cIixucnRyaTpcIuKLq1wiLG5ydHJpZTpcIuKLrVwiLG5zYzpcIuKKgVwiLG5zY2N1ZTpcIuKLoVwiLG5zY2U6XCLiqrDMuFwiLE5zY3I6XCLwnZKpXCIsbnNjcjpcIvCdk4NcIixuc2hvcnRtaWQ6XCLiiKRcIixuc2hvcnRwYXJhbGxlbDpcIuKIplwiLG5zaW06XCLiiYFcIixuc2ltZTpcIuKJhFwiLG5zaW1lcTpcIuKJhFwiLG5zbWlkOlwi4oikXCIsbnNwYXI6XCLiiKZcIixuc3FzdWJlOlwi4ouiXCIsbnNxc3VwZTpcIuKLo1wiLG5zdWI6XCLiioRcIixuc3ViRTpcIuKrhcy4XCIsbnN1YmU6XCLiiohcIixuc3Vic2V0Olwi4oqC4oOSXCIsbnN1YnNldGVxOlwi4oqIXCIsbnN1YnNldGVxcTpcIuKrhcy4XCIsbnN1Y2M6XCLiioFcIixuc3VjY2VxOlwi4qqwzLhcIixuc3VwOlwi4oqFXCIsbnN1cEU6XCLiq4bMuFwiLG5zdXBlOlwi4oqJXCIsbnN1cHNldDpcIuKKg+KDklwiLG5zdXBzZXRlcTpcIuKKiVwiLG5zdXBzZXRlcXE6XCLiq4bMuFwiLG50Z2w6XCLiiblcIixOdGlsZGU6XCLDkVwiLG50aWxkZTpcIsOxXCIsbnRsZzpcIuKJuFwiLG50cmlhbmdsZWxlZnQ6XCLii6pcIixudHJpYW5nbGVsZWZ0ZXE6XCLii6xcIixudHJpYW5nbGVyaWdodDpcIuKLq1wiLG50cmlhbmdsZXJpZ2h0ZXE6XCLii61cIixOdTpcIs6dXCIsbnU6XCLOvVwiLG51bTpcIiNcIixudW1lcm86XCLihJZcIixudW1zcDpcIuKAh1wiLG52YXA6XCLiiY3ig5JcIixudmRhc2g6XCLiiqxcIixudkRhc2g6XCLiiq1cIixuVmRhc2g6XCLiiq5cIixuVkRhc2g6XCLiiq9cIixudmdlOlwi4oml4oOSXCIsbnZndDpcIj7ig5JcIixudkhhcnI6XCLipIRcIixudmluZmluOlwi4qeeXCIsbnZsQXJyOlwi4qSCXCIsbnZsZTpcIuKJpOKDklwiLG52bHQ6XCI84oOSXCIsbnZsdHJpZTpcIuKKtOKDklwiLG52ckFycjpcIuKkg1wiLG52cnRyaWU6XCLiirXig5JcIixudnNpbTpcIuKIvOKDklwiLG53YXJoazpcIuKko1wiLG53YXJyOlwi4oaWXCIsbndBcnI6XCLih5ZcIixud2Fycm93Olwi4oaWXCIsbnduZWFyOlwi4qSnXCIsT2FjdXRlOlwiw5NcIixvYWN1dGU6XCLDs1wiLG9hc3Q6XCLiiptcIixPY2lyYzpcIsOUXCIsb2NpcmM6XCLDtFwiLG9jaXI6XCLiippcIixPY3k6XCLQnlwiLG9jeTpcItC+XCIsb2Rhc2g6XCLiip1cIixPZGJsYWM6XCLFkFwiLG9kYmxhYzpcIsWRXCIsb2RpdjpcIuKouFwiLG9kb3Q6XCLiiplcIixvZHNvbGQ6XCLiprxcIixPRWxpZzpcIsWSXCIsb2VsaWc6XCLFk1wiLG9mY2lyOlwi4qa/XCIsT2ZyOlwi8J2UklwiLG9mcjpcIvCdlKxcIixvZ29uOlwiy5tcIixPZ3JhdmU6XCLDklwiLG9ncmF2ZTpcIsOyXCIsb2d0Olwi4qeBXCIsb2hiYXI6XCLiprVcIixvaG06XCLOqVwiLG9pbnQ6XCLiiK5cIixvbGFycjpcIuKGulwiLG9sY2lyOlwi4qa+XCIsb2xjcm9zczpcIuKmu1wiLG9saW5lOlwi4oC+XCIsb2x0Olwi4qeAXCIsT21hY3I6XCLFjFwiLG9tYWNyOlwixY1cIixPbWVnYTpcIs6pXCIsb21lZ2E6XCLPiVwiLE9taWNyb246XCLOn1wiLG9taWNyb246XCLOv1wiLG9taWQ6XCLiprZcIixvbWludXM6XCLiipZcIixPb3BmOlwi8J2VhlwiLG9vcGY6XCLwnZWgXCIsb3BhcjpcIuKmt1wiLE9wZW5DdXJseURvdWJsZVF1b3RlOlwi4oCcXCIsT3BlbkN1cmx5UXVvdGU6XCLigJhcIixvcGVycDpcIuKmuVwiLG9wbHVzOlwi4oqVXCIsb3JhcnI6XCLihrtcIixPcjpcIuKplFwiLG9yOlwi4oioXCIsb3JkOlwi4qmdXCIsb3JkZXI6XCLihLRcIixvcmRlcm9mOlwi4oS0XCIsb3JkZjpcIsKqXCIsb3JkbTpcIsK6XCIsb3JpZ29mOlwi4oq2XCIsb3JvcjpcIuKpllwiLG9yc2xvcGU6XCLiqZdcIixvcnY6XCLiqZtcIixvUzpcIuKTiFwiLE9zY3I6XCLwnZKqXCIsb3NjcjpcIuKEtFwiLE9zbGFzaDpcIsOYXCIsb3NsYXNoOlwiw7hcIixvc29sOlwi4oqYXCIsT3RpbGRlOlwiw5VcIixvdGlsZGU6XCLDtVwiLG90aW1lc2FzOlwi4qi2XCIsT3RpbWVzOlwi4qi3XCIsb3RpbWVzOlwi4oqXXCIsT3VtbDpcIsOWXCIsb3VtbDpcIsO2XCIsb3ZiYXI6XCLijL1cIixPdmVyQmFyOlwi4oC+XCIsT3ZlckJyYWNlOlwi4o+eXCIsT3ZlckJyYWNrZXQ6XCLijrRcIixPdmVyUGFyZW50aGVzaXM6XCLij5xcIixwYXJhOlwiwrZcIixwYXJhbGxlbDpcIuKIpVwiLHBhcjpcIuKIpVwiLHBhcnNpbTpcIuKrs1wiLHBhcnNsOlwi4qu9XCIscGFydDpcIuKIglwiLFBhcnRpYWxEOlwi4oiCXCIsUGN5Olwi0J9cIixwY3k6XCLQv1wiLHBlcmNudDpcIiVcIixwZXJpb2Q6XCIuXCIscGVybWlsOlwi4oCwXCIscGVycDpcIuKKpVwiLHBlcnRlbms6XCLigLFcIixQZnI6XCLwnZSTXCIscGZyOlwi8J2UrVwiLFBoaTpcIs6mXCIscGhpOlwiz4ZcIixwaGl2Olwiz5VcIixwaG1tYXQ6XCLihLNcIixwaG9uZTpcIuKYjlwiLFBpOlwizqBcIixwaTpcIs+AXCIscGl0Y2hmb3JrOlwi4ouUXCIscGl2Olwiz5ZcIixwbGFuY2s6XCLihI9cIixwbGFuY2toOlwi4oSOXCIscGxhbmt2Olwi4oSPXCIscGx1c2FjaXI6XCLiqKNcIixwbHVzYjpcIuKKnlwiLHBsdXNjaXI6XCLiqKJcIixwbHVzOlwiK1wiLHBsdXNkbzpcIuKIlFwiLHBsdXNkdTpcIuKopVwiLHBsdXNlOlwi4qmyXCIsUGx1c01pbnVzOlwiwrFcIixwbHVzbW46XCLCsVwiLHBsdXNzaW06XCLiqKZcIixwbHVzdHdvOlwi4qinXCIscG06XCLCsVwiLFBvaW5jYXJlcGxhbmU6XCLihIxcIixwb2ludGludDpcIuKolVwiLHBvcGY6XCLwnZWhXCIsUG9wZjpcIuKEmVwiLHBvdW5kOlwiwqNcIixwcmFwOlwi4qq3XCIsUHI6XCLiqrtcIixwcjpcIuKJulwiLHByY3VlOlwi4om8XCIscHJlY2FwcHJveDpcIuKqt1wiLHByZWM6XCLiibpcIixwcmVjY3VybHllcTpcIuKJvFwiLFByZWNlZGVzOlwi4om6XCIsUHJlY2VkZXNFcXVhbDpcIuKqr1wiLFByZWNlZGVzU2xhbnRFcXVhbDpcIuKJvFwiLFByZWNlZGVzVGlsZGU6XCLiib5cIixwcmVjZXE6XCLiqq9cIixwcmVjbmFwcHJveDpcIuKquVwiLHByZWNuZXFxOlwi4qq1XCIscHJlY25zaW06XCLii6hcIixwcmU6XCLiqq9cIixwckU6XCLiqrNcIixwcmVjc2ltOlwi4om+XCIscHJpbWU6XCLigLJcIixQcmltZTpcIuKAs1wiLHByaW1lczpcIuKEmVwiLHBybmFwOlwi4qq5XCIscHJuRTpcIuKqtVwiLHBybnNpbTpcIuKLqFwiLHByb2Q6XCLiiI9cIixQcm9kdWN0Olwi4oiPXCIscHJvZmFsYXI6XCLijK5cIixwcm9mbGluZTpcIuKMklwiLHByb2ZzdXJmOlwi4oyTXCIscHJvcDpcIuKInVwiLFByb3BvcnRpb25hbDpcIuKInVwiLFByb3BvcnRpb246XCLiiLdcIixwcm9wdG86XCLiiJ1cIixwcnNpbTpcIuKJvlwiLHBydXJlbDpcIuKKsFwiLFBzY3I6XCLwnZKrXCIscHNjcjpcIvCdk4VcIixQc2k6XCLOqFwiLHBzaTpcIs+IXCIscHVuY3NwOlwi4oCIXCIsUWZyOlwi8J2UlFwiLHFmcjpcIvCdlK5cIixxaW50Olwi4qiMXCIscW9wZjpcIvCdlaJcIixRb3BmOlwi4oSaXCIscXByaW1lOlwi4oGXXCIsUXNjcjpcIvCdkqxcIixxc2NyOlwi8J2ThlwiLHF1YXRlcm5pb25zOlwi4oSNXCIscXVhdGludDpcIuKollwiLHF1ZXN0OlwiP1wiLHF1ZXN0ZXE6XCLiiZ9cIixxdW90OidcIicsUVVPVDonXCInLHJBYXJyOlwi4oebXCIscmFjZTpcIuKIvcyxXCIsUmFjdXRlOlwixZRcIixyYWN1dGU6XCLFlVwiLHJhZGljOlwi4oiaXCIscmFlbXB0eXY6XCLiprNcIixyYW5nOlwi4p+pXCIsUmFuZzpcIuKfq1wiLHJhbmdkOlwi4qaSXCIscmFuZ2U6XCLipqVcIixyYW5nbGU6XCLin6lcIixyYXF1bzpcIsK7XCIscmFycmFwOlwi4qW1XCIscmFycmI6XCLih6VcIixyYXJyYmZzOlwi4qSgXCIscmFycmM6XCLipLNcIixyYXJyOlwi4oaSXCIsUmFycjpcIuKGoFwiLHJBcnI6XCLih5JcIixyYXJyZnM6XCLipJ5cIixyYXJyaGs6XCLihqpcIixyYXJybHA6XCLihqxcIixyYXJycGw6XCLipYVcIixyYXJyc2ltOlwi4qW0XCIsUmFycnRsOlwi4qSWXCIscmFycnRsOlwi4oajXCIscmFycnc6XCLihp1cIixyYXRhaWw6XCLipJpcIixyQXRhaWw6XCLipJxcIixyYXRpbzpcIuKItlwiLHJhdGlvbmFsczpcIuKEmlwiLHJiYXJyOlwi4qSNXCIsckJhcnI6XCLipI9cIixSQmFycjpcIuKkkFwiLHJiYnJrOlwi4p2zXCIscmJyYWNlOlwifVwiLHJicmFjazpcIl1cIixyYnJrZTpcIuKmjFwiLHJicmtzbGQ6XCLipo5cIixyYnJrc2x1Olwi4qaQXCIsUmNhcm9uOlwixZhcIixyY2Fyb246XCLFmVwiLFJjZWRpbDpcIsWWXCIscmNlZGlsOlwixZdcIixyY2VpbDpcIuKMiVwiLHJjdWI6XCJ9XCIsUmN5Olwi0KBcIixyY3k6XCLRgFwiLHJkY2E6XCLipLdcIixyZGxkaGFyOlwi4qWpXCIscmRxdW86XCLigJ1cIixyZHF1b3I6XCLigJ1cIixyZHNoOlwi4oazXCIscmVhbDpcIuKEnFwiLHJlYWxpbmU6XCLihJtcIixyZWFscGFydDpcIuKEnFwiLHJlYWxzOlwi4oSdXCIsUmU6XCLihJxcIixyZWN0Olwi4patXCIscmVnOlwiwq5cIixSRUc6XCLCrlwiLFJldmVyc2VFbGVtZW50Olwi4oiLXCIsUmV2ZXJzZUVxdWlsaWJyaXVtOlwi4oeLXCIsUmV2ZXJzZVVwRXF1aWxpYnJpdW06XCLipa9cIixyZmlzaHQ6XCLipb1cIixyZmxvb3I6XCLijItcIixyZnI6XCLwnZSvXCIsUmZyOlwi4oScXCIsckhhcjpcIuKlpFwiLHJoYXJkOlwi4oeBXCIscmhhcnU6XCLih4BcIixyaGFydWw6XCLipaxcIixSaG86XCLOoVwiLHJobzpcIs+BXCIscmhvdjpcIs+xXCIsUmlnaHRBbmdsZUJyYWNrZXQ6XCLin6lcIixSaWdodEFycm93QmFyOlwi4oelXCIscmlnaHRhcnJvdzpcIuKGklwiLFJpZ2h0QXJyb3c6XCLihpJcIixSaWdodGFycm93Olwi4oeSXCIsUmlnaHRBcnJvd0xlZnRBcnJvdzpcIuKHhFwiLHJpZ2h0YXJyb3d0YWlsOlwi4oajXCIsUmlnaHRDZWlsaW5nOlwi4oyJXCIsUmlnaHREb3VibGVCcmFja2V0Olwi4p+nXCIsUmlnaHREb3duVGVlVmVjdG9yOlwi4qWdXCIsUmlnaHREb3duVmVjdG9yQmFyOlwi4qWVXCIsUmlnaHREb3duVmVjdG9yOlwi4oeCXCIsUmlnaHRGbG9vcjpcIuKMi1wiLHJpZ2h0aGFycG9vbmRvd246XCLih4FcIixyaWdodGhhcnBvb251cDpcIuKHgFwiLHJpZ2h0bGVmdGFycm93czpcIuKHhFwiLHJpZ2h0bGVmdGhhcnBvb25zOlwi4oeMXCIscmlnaHRyaWdodGFycm93czpcIuKHiVwiLHJpZ2h0c3F1aWdhcnJvdzpcIuKGnVwiLFJpZ2h0VGVlQXJyb3c6XCLihqZcIixSaWdodFRlZTpcIuKKolwiLFJpZ2h0VGVlVmVjdG9yOlwi4qWbXCIscmlnaHR0aHJlZXRpbWVzOlwi4ouMXCIsUmlnaHRUcmlhbmdsZUJhcjpcIuKnkFwiLFJpZ2h0VHJpYW5nbGU6XCLiirNcIixSaWdodFRyaWFuZ2xlRXF1YWw6XCLiirVcIixSaWdodFVwRG93blZlY3RvcjpcIuKlj1wiLFJpZ2h0VXBUZWVWZWN0b3I6XCLipZxcIixSaWdodFVwVmVjdG9yQmFyOlwi4qWUXCIsUmlnaHRVcFZlY3RvcjpcIuKGvlwiLFJpZ2h0VmVjdG9yQmFyOlwi4qWTXCIsUmlnaHRWZWN0b3I6XCLih4BcIixyaW5nOlwiy5pcIixyaXNpbmdkb3RzZXE6XCLiiZNcIixybGFycjpcIuKHhFwiLHJsaGFyOlwi4oeMXCIscmxtOlwi4oCPXCIscm1vdXN0YWNoZTpcIuKOsVwiLHJtb3VzdDpcIuKOsVwiLHJubWlkOlwi4quuXCIscm9hbmc6XCLin61cIixyb2FycjpcIuKHvlwiLHJvYnJrOlwi4p+nXCIscm9wYXI6XCLipoZcIixyb3BmOlwi8J2Vo1wiLFJvcGY6XCLihJ1cIixyb3BsdXM6XCLiqK5cIixyb3RpbWVzOlwi4qi1XCIsUm91bmRJbXBsaWVzOlwi4qWwXCIscnBhcjpcIilcIixycGFyZ3Q6XCLippRcIixycHBvbGludDpcIuKoklwiLHJyYXJyOlwi4oeJXCIsUnJpZ2h0YXJyb3c6XCLih5tcIixyc2FxdW86XCLigLpcIixyc2NyOlwi8J2Th1wiLFJzY3I6XCLihJtcIixyc2g6XCLihrFcIixSc2g6XCLihrFcIixyc3FiOlwiXVwiLHJzcXVvOlwi4oCZXCIscnNxdW9yOlwi4oCZXCIscnRocmVlOlwi4ouMXCIscnRpbWVzOlwi4ouKXCIscnRyaTpcIuKWuVwiLHJ0cmllOlwi4oq1XCIscnRyaWY6XCLilrhcIixydHJpbHRyaTpcIuKnjlwiLFJ1bGVEZWxheWVkOlwi4qe0XCIscnVsdWhhcjpcIuKlqFwiLHJ4Olwi4oSeXCIsU2FjdXRlOlwixZpcIixzYWN1dGU6XCLFm1wiLHNicXVvOlwi4oCaXCIsc2NhcDpcIuKquFwiLFNjYXJvbjpcIsWgXCIsc2Nhcm9uOlwixaFcIixTYzpcIuKqvFwiLHNjOlwi4om7XCIsc2NjdWU6XCLiib1cIixzY2U6XCLiqrBcIixzY0U6XCLiqrRcIixTY2VkaWw6XCLFnlwiLHNjZWRpbDpcIsWfXCIsU2NpcmM6XCLFnFwiLHNjaXJjOlwixZ1cIixzY25hcDpcIuKqulwiLHNjbkU6XCLiqrZcIixzY25zaW06XCLii6lcIixzY3BvbGludDpcIuKok1wiLHNjc2ltOlwi4om/XCIsU2N5Olwi0KFcIixzY3k6XCLRgVwiLHNkb3RiOlwi4oqhXCIsc2RvdDpcIuKLhVwiLHNkb3RlOlwi4qmmXCIsc2VhcmhrOlwi4qSlXCIsc2VhcnI6XCLihphcIixzZUFycjpcIuKHmFwiLHNlYXJyb3c6XCLihphcIixzZWN0OlwiwqdcIixzZW1pOlwiO1wiLHNlc3dhcjpcIuKkqVwiLHNldG1pbnVzOlwi4oiWXCIsc2V0bW46XCLiiJZcIixzZXh0Olwi4py2XCIsU2ZyOlwi8J2UllwiLHNmcjpcIvCdlLBcIixzZnJvd246XCLijKJcIixzaGFycDpcIuKZr1wiLFNIQ0hjeTpcItCpXCIsc2hjaGN5Olwi0YlcIixTSGN5Olwi0KhcIixzaGN5Olwi0YhcIixTaG9ydERvd25BcnJvdzpcIuKGk1wiLFNob3J0TGVmdEFycm93Olwi4oaQXCIsc2hvcnRtaWQ6XCLiiKNcIixzaG9ydHBhcmFsbGVsOlwi4oilXCIsU2hvcnRSaWdodEFycm93Olwi4oaSXCIsU2hvcnRVcEFycm93Olwi4oaRXCIsc2h5Olwiwq1cIixTaWdtYTpcIs6jXCIsc2lnbWE6XCLPg1wiLHNpZ21hZjpcIs+CXCIsc2lnbWF2Olwiz4JcIixzaW06XCLiiLxcIixzaW1kb3Q6XCLiqapcIixzaW1lOlwi4omDXCIsc2ltZXE6XCLiiYNcIixzaW1nOlwi4qqeXCIsc2ltZ0U6XCLiqqBcIixzaW1sOlwi4qqdXCIsc2ltbEU6XCLiqp9cIixzaW1uZTpcIuKJhlwiLHNpbXBsdXM6XCLiqKRcIixzaW1yYXJyOlwi4qWyXCIsc2xhcnI6XCLihpBcIixTbWFsbENpcmNsZTpcIuKImFwiLHNtYWxsc2V0bWludXM6XCLiiJZcIixzbWFzaHA6XCLiqLNcIixzbWVwYXJzbDpcIuKnpFwiLHNtaWQ6XCLiiKNcIixzbWlsZTpcIuKMo1wiLHNtdDpcIuKqqlwiLHNtdGU6XCLiqqxcIixzbXRlczpcIuKqrO+4gFwiLFNPRlRjeTpcItCsXCIsc29mdGN5Olwi0YxcIixzb2xiYXI6XCLijL9cIixzb2xiOlwi4qeEXCIsc29sOlwiL1wiLFNvcGY6XCLwnZWKXCIsc29wZjpcIvCdlaRcIixzcGFkZXM6XCLimaBcIixzcGFkZXN1aXQ6XCLimaBcIixzcGFyOlwi4oilXCIsc3FjYXA6XCLiipNcIixzcWNhcHM6XCLiipPvuIBcIixzcWN1cDpcIuKKlFwiLHNxY3VwczpcIuKKlO+4gFwiLFNxcnQ6XCLiiJpcIixzcXN1YjpcIuKKj1wiLHNxc3ViZTpcIuKKkVwiLHNxc3Vic2V0Olwi4oqPXCIsc3FzdWJzZXRlcTpcIuKKkVwiLHNxc3VwOlwi4oqQXCIsc3FzdXBlOlwi4oqSXCIsc3FzdXBzZXQ6XCLiipBcIixzcXN1cHNldGVxOlwi4oqSXCIsc3F1YXJlOlwi4pahXCIsU3F1YXJlOlwi4pahXCIsU3F1YXJlSW50ZXJzZWN0aW9uOlwi4oqTXCIsU3F1YXJlU3Vic2V0Olwi4oqPXCIsU3F1YXJlU3Vic2V0RXF1YWw6XCLiipFcIixTcXVhcmVTdXBlcnNldDpcIuKKkFwiLFNxdWFyZVN1cGVyc2V0RXF1YWw6XCLiipJcIixTcXVhcmVVbmlvbjpcIuKKlFwiLHNxdWFyZjpcIuKWqlwiLHNxdTpcIuKWoVwiLHNxdWY6XCLilqpcIixzcmFycjpcIuKGklwiLFNzY3I6XCLwnZKuXCIsc3NjcjpcIvCdk4hcIixzc2V0bW46XCLiiJZcIixzc21pbGU6XCLijKNcIixzc3RhcmY6XCLii4ZcIixTdGFyOlwi4ouGXCIsc3RhcjpcIuKYhlwiLHN0YXJmOlwi4piFXCIsc3RyYWlnaHRlcHNpbG9uOlwiz7VcIixzdHJhaWdodHBoaTpcIs+VXCIsc3RybnM6XCLCr1wiLHN1YjpcIuKKglwiLFN1YjpcIuKLkFwiLHN1YmRvdDpcIuKqvVwiLHN1YkU6XCLiq4VcIixzdWJlOlwi4oqGXCIsc3ViZWRvdDpcIuKrg1wiLHN1Ym11bHQ6XCLiq4FcIixzdWJuRTpcIuKri1wiLHN1Ym5lOlwi4oqKXCIsc3VicGx1czpcIuKqv1wiLHN1YnJhcnI6XCLipblcIixzdWJzZXQ6XCLiioJcIixTdWJzZXQ6XCLii5BcIixzdWJzZXRlcTpcIuKKhlwiLHN1YnNldGVxcTpcIuKrhVwiLFN1YnNldEVxdWFsOlwi4oqGXCIsc3Vic2V0bmVxOlwi4oqKXCIsc3Vic2V0bmVxcTpcIuKri1wiLHN1YnNpbTpcIuKrh1wiLHN1YnN1YjpcIuKrlVwiLHN1YnN1cDpcIuKrk1wiLHN1Y2NhcHByb3g6XCLiqrhcIixzdWNjOlwi4om7XCIsc3VjY2N1cmx5ZXE6XCLiib1cIixTdWNjZWVkczpcIuKJu1wiLFN1Y2NlZWRzRXF1YWw6XCLiqrBcIixTdWNjZWVkc1NsYW50RXF1YWw6XCLiib1cIixTdWNjZWVkc1RpbGRlOlwi4om/XCIsc3VjY2VxOlwi4qqwXCIsc3VjY25hcHByb3g6XCLiqrpcIixzdWNjbmVxcTpcIuKqtlwiLHN1Y2Nuc2ltOlwi4oupXCIsc3VjY3NpbTpcIuKJv1wiLFN1Y2hUaGF0Olwi4oiLXCIsc3VtOlwi4oiRXCIsU3VtOlwi4oiRXCIsc3VuZzpcIuKZqlwiLHN1cDE6XCLCuVwiLHN1cDI6XCLCslwiLHN1cDM6XCLCs1wiLHN1cDpcIuKKg1wiLFN1cDpcIuKLkVwiLHN1cGRvdDpcIuKqvlwiLHN1cGRzdWI6XCLiq5hcIixzdXBFOlwi4quGXCIsc3VwZTpcIuKKh1wiLHN1cGVkb3Q6XCLiq4RcIixTdXBlcnNldDpcIuKKg1wiLFN1cGVyc2V0RXF1YWw6XCLiiodcIixzdXBoc29sOlwi4p+JXCIsc3VwaHN1YjpcIuKrl1wiLHN1cGxhcnI6XCLipbtcIixzdXBtdWx0Olwi4quCXCIsc3VwbkU6XCLiq4xcIixzdXBuZTpcIuKKi1wiLHN1cHBsdXM6XCLiq4BcIixzdXBzZXQ6XCLiioNcIixTdXBzZXQ6XCLii5FcIixzdXBzZXRlcTpcIuKKh1wiLHN1cHNldGVxcTpcIuKrhlwiLHN1cHNldG5lcTpcIuKKi1wiLHN1cHNldG5lcXE6XCLiq4xcIixzdXBzaW06XCLiq4hcIixzdXBzdWI6XCLiq5RcIixzdXBzdXA6XCLiq5ZcIixzd2FyaGs6XCLipKZcIixzd2FycjpcIuKGmVwiLHN3QXJyOlwi4oeZXCIsc3dhcnJvdzpcIuKGmVwiLHN3bndhcjpcIuKkqlwiLHN6bGlnOlwiw59cIixUYWI6XCJcXHRcIix0YXJnZXQ6XCLijJZcIixUYXU6XCLOpFwiLHRhdTpcIs+EXCIsdGJyazpcIuKOtFwiLFRjYXJvbjpcIsWkXCIsdGNhcm9uOlwixaVcIixUY2VkaWw6XCLFolwiLHRjZWRpbDpcIsWjXCIsVGN5Olwi0KJcIix0Y3k6XCLRglwiLHRkb3Q6XCLig5tcIix0ZWxyZWM6XCLijJVcIixUZnI6XCLwnZSXXCIsdGZyOlwi8J2UsVwiLHRoZXJlNDpcIuKItFwiLHRoZXJlZm9yZTpcIuKItFwiLFRoZXJlZm9yZTpcIuKItFwiLFRoZXRhOlwizphcIix0aGV0YTpcIs64XCIsdGhldGFzeW06XCLPkVwiLHRoZXRhdjpcIs+RXCIsdGhpY2thcHByb3g6XCLiiYhcIix0aGlja3NpbTpcIuKIvFwiLFRoaWNrU3BhY2U6XCLigZ/igIpcIixUaGluU3BhY2U6XCLigIlcIix0aGluc3A6XCLigIlcIix0aGthcDpcIuKJiFwiLHRoa3NpbTpcIuKIvFwiLFRIT1JOOlwiw55cIix0aG9ybjpcIsO+XCIsdGlsZGU6XCLLnFwiLFRpbGRlOlwi4oi8XCIsVGlsZGVFcXVhbDpcIuKJg1wiLFRpbGRlRnVsbEVxdWFsOlwi4omFXCIsVGlsZGVUaWxkZTpcIuKJiFwiLHRpbWVzYmFyOlwi4qixXCIsdGltZXNiOlwi4oqgXCIsdGltZXM6XCLDl1wiLHRpbWVzZDpcIuKosFwiLHRpbnQ6XCLiiK1cIix0b2VhOlwi4qSoXCIsdG9wYm90Olwi4oy2XCIsdG9wY2lyOlwi4quxXCIsdG9wOlwi4oqkXCIsVG9wZjpcIvCdlYtcIix0b3BmOlwi8J2VpVwiLHRvcGZvcms6XCLiq5pcIix0b3NhOlwi4qSpXCIsdHByaW1lOlwi4oC0XCIsdHJhZGU6XCLihKJcIixUUkFERTpcIuKEolwiLHRyaWFuZ2xlOlwi4pa1XCIsdHJpYW5nbGVkb3duOlwi4pa/XCIsdHJpYW5nbGVsZWZ0Olwi4peDXCIsdHJpYW5nbGVsZWZ0ZXE6XCLiirRcIix0cmlhbmdsZXE6XCLiiZxcIix0cmlhbmdsZXJpZ2h0Olwi4pa5XCIsdHJpYW5nbGVyaWdodGVxOlwi4oq1XCIsdHJpZG90Olwi4pesXCIsdHJpZTpcIuKJnFwiLHRyaW1pbnVzOlwi4qi6XCIsVHJpcGxlRG90Olwi4oObXCIsdHJpcGx1czpcIuKouVwiLHRyaXNiOlwi4qeNXCIsdHJpdGltZTpcIuKou1wiLHRycGV6aXVtOlwi4o+iXCIsVHNjcjpcIvCdkq9cIix0c2NyOlwi8J2TiVwiLFRTY3k6XCLQplwiLHRzY3k6XCLRhlwiLFRTSGN5Olwi0ItcIix0c2hjeTpcItGbXCIsVHN0cm9rOlwixaZcIix0c3Ryb2s6XCLFp1wiLHR3aXh0Olwi4omsXCIsdHdvaGVhZGxlZnRhcnJvdzpcIuKGnlwiLHR3b2hlYWRyaWdodGFycm93Olwi4oagXCIsVWFjdXRlOlwiw5pcIix1YWN1dGU6XCLDulwiLHVhcnI6XCLihpFcIixVYXJyOlwi4oafXCIsdUFycjpcIuKHkVwiLFVhcnJvY2lyOlwi4qWJXCIsVWJyY3k6XCLQjlwiLHVicmN5Olwi0Z5cIixVYnJldmU6XCLFrFwiLHVicmV2ZTpcIsWtXCIsVWNpcmM6XCLDm1wiLHVjaXJjOlwiw7tcIixVY3k6XCLQo1wiLHVjeTpcItGDXCIsdWRhcnI6XCLih4VcIixVZGJsYWM6XCLFsFwiLHVkYmxhYzpcIsWxXCIsdWRoYXI6XCLipa5cIix1ZmlzaHQ6XCLipb5cIixVZnI6XCLwnZSYXCIsdWZyOlwi8J2UslwiLFVncmF2ZTpcIsOZXCIsdWdyYXZlOlwiw7lcIix1SGFyOlwi4qWjXCIsdWhhcmw6XCLihr9cIix1aGFycjpcIuKGvlwiLHVoYmxrOlwi4paAXCIsdWxjb3JuOlwi4oycXCIsdWxjb3JuZXI6XCLijJxcIix1bGNyb3A6XCLijI9cIix1bHRyaTpcIuKXuFwiLFVtYWNyOlwixapcIix1bWFjcjpcIsWrXCIsdW1sOlwiwqhcIixVbmRlckJhcjpcIl9cIixVbmRlckJyYWNlOlwi4o+fXCIsVW5kZXJCcmFja2V0Olwi4o61XCIsVW5kZXJQYXJlbnRoZXNpczpcIuKPnVwiLFVuaW9uOlwi4ouDXCIsVW5pb25QbHVzOlwi4oqOXCIsVW9nb246XCLFslwiLHVvZ29uOlwixbNcIixVb3BmOlwi8J2VjFwiLHVvcGY6XCLwnZWmXCIsVXBBcnJvd0JhcjpcIuKkklwiLHVwYXJyb3c6XCLihpFcIixVcEFycm93Olwi4oaRXCIsVXBhcnJvdzpcIuKHkVwiLFVwQXJyb3dEb3duQXJyb3c6XCLih4VcIix1cGRvd25hcnJvdzpcIuKGlVwiLFVwRG93bkFycm93Olwi4oaVXCIsVXBkb3duYXJyb3c6XCLih5VcIixVcEVxdWlsaWJyaXVtOlwi4qWuXCIsdXBoYXJwb29ubGVmdDpcIuKGv1wiLHVwaGFycG9vbnJpZ2h0Olwi4oa+XCIsdXBsdXM6XCLiio5cIixVcHBlckxlZnRBcnJvdzpcIuKGllwiLFVwcGVyUmlnaHRBcnJvdzpcIuKGl1wiLHVwc2k6XCLPhVwiLFVwc2k6XCLPklwiLHVwc2loOlwiz5JcIixVcHNpbG9uOlwizqVcIix1cHNpbG9uOlwiz4VcIixVcFRlZUFycm93Olwi4oalXCIsVXBUZWU6XCLiiqVcIix1cHVwYXJyb3dzOlwi4oeIXCIsdXJjb3JuOlwi4oydXCIsdXJjb3JuZXI6XCLijJ1cIix1cmNyb3A6XCLijI5cIixVcmluZzpcIsWuXCIsdXJpbmc6XCLFr1wiLHVydHJpOlwi4pe5XCIsVXNjcjpcIvCdkrBcIix1c2NyOlwi8J2TilwiLHV0ZG90Olwi4ouwXCIsVXRpbGRlOlwixahcIix1dGlsZGU6XCLFqVwiLHV0cmk6XCLilrVcIix1dHJpZjpcIuKWtFwiLHV1YXJyOlwi4oeIXCIsVXVtbDpcIsOcXCIsdXVtbDpcIsO8XCIsdXdhbmdsZTpcIuKmp1wiLHZhbmdydDpcIuKmnFwiLHZhcmVwc2lsb246XCLPtVwiLHZhcmthcHBhOlwiz7BcIix2YXJub3RoaW5nOlwi4oiFXCIsdmFycGhpOlwiz5VcIix2YXJwaTpcIs+WXCIsdmFycHJvcHRvOlwi4oidXCIsdmFycjpcIuKGlVwiLHZBcnI6XCLih5VcIix2YXJyaG86XCLPsVwiLHZhcnNpZ21hOlwiz4JcIix2YXJzdWJzZXRuZXE6XCLiiorvuIBcIix2YXJzdWJzZXRuZXFxOlwi4quL77iAXCIsdmFyc3Vwc2V0bmVxOlwi4oqL77iAXCIsdmFyc3Vwc2V0bmVxcTpcIuKrjO+4gFwiLHZhcnRoZXRhOlwiz5FcIix2YXJ0cmlhbmdsZWxlZnQ6XCLiirJcIix2YXJ0cmlhbmdsZXJpZ2h0Olwi4oqzXCIsdkJhcjpcIuKrqFwiLFZiYXI6XCLiq6tcIix2QmFydjpcIuKrqVwiLFZjeTpcItCSXCIsdmN5Olwi0LJcIix2ZGFzaDpcIuKKolwiLHZEYXNoOlwi4oqoXCIsVmRhc2g6XCLiiqlcIixWRGFzaDpcIuKKq1wiLFZkYXNobDpcIuKrplwiLHZlZWJhcjpcIuKKu1wiLHZlZTpcIuKIqFwiLFZlZTpcIuKLgVwiLHZlZWVxOlwi4omaXCIsdmVsbGlwOlwi4ouuXCIsdmVyYmFyOlwifFwiLFZlcmJhcjpcIuKAllwiLHZlcnQ6XCJ8XCIsVmVydDpcIuKAllwiLFZlcnRpY2FsQmFyOlwi4oijXCIsVmVydGljYWxMaW5lOlwifFwiLFZlcnRpY2FsU2VwYXJhdG9yOlwi4p2YXCIsVmVydGljYWxUaWxkZTpcIuKJgFwiLFZlcnlUaGluU3BhY2U6XCLigIpcIixWZnI6XCLwnZSZXCIsdmZyOlwi8J2Us1wiLHZsdHJpOlwi4oqyXCIsdm5zdWI6XCLiioLig5JcIix2bnN1cDpcIuKKg+KDklwiLFZvcGY6XCLwnZWNXCIsdm9wZjpcIvCdladcIix2cHJvcDpcIuKInVwiLHZydHJpOlwi4oqzXCIsVnNjcjpcIvCdkrFcIix2c2NyOlwi8J2Ti1wiLHZzdWJuRTpcIuKri++4gFwiLHZzdWJuZTpcIuKKiu+4gFwiLHZzdXBuRTpcIuKrjO+4gFwiLHZzdXBuZTpcIuKKi++4gFwiLFZ2ZGFzaDpcIuKKqlwiLHZ6aWd6YWc6XCLipppcIixXY2lyYzpcIsW0XCIsd2NpcmM6XCLFtVwiLHdlZGJhcjpcIuKpn1wiLHdlZGdlOlwi4oinXCIsV2VkZ2U6XCLii4BcIix3ZWRnZXE6XCLiiZlcIix3ZWllcnA6XCLihJhcIixXZnI6XCLwnZSaXCIsd2ZyOlwi8J2UtFwiLFdvcGY6XCLwnZWOXCIsd29wZjpcIvCdlahcIix3cDpcIuKEmFwiLHdyOlwi4omAXCIsd3JlYXRoOlwi4omAXCIsV3NjcjpcIvCdkrJcIix3c2NyOlwi8J2TjFwiLHhjYXA6XCLii4JcIix4Y2lyYzpcIuKXr1wiLHhjdXA6XCLii4NcIix4ZHRyaTpcIuKWvVwiLFhmcjpcIvCdlJtcIix4ZnI6XCLwnZS1XCIseGhhcnI6XCLin7dcIix4aEFycjpcIuKfulwiLFhpOlwizp5cIix4aTpcIs6+XCIseGxhcnI6XCLin7VcIix4bEFycjpcIuKfuFwiLHhtYXA6XCLin7xcIix4bmlzOlwi4ou7XCIseG9kb3Q6XCLiqIBcIixYb3BmOlwi8J2Vj1wiLHhvcGY6XCLwnZWpXCIseG9wbHVzOlwi4qiBXCIseG90aW1lOlwi4qiCXCIseHJhcnI6XCLin7ZcIix4ckFycjpcIuKfuVwiLFhzY3I6XCLwnZKzXCIseHNjcjpcIvCdk41cIix4c3FjdXA6XCLiqIZcIix4dXBsdXM6XCLiqIRcIix4dXRyaTpcIuKWs1wiLHh2ZWU6XCLii4FcIix4d2VkZ2U6XCLii4BcIixZYWN1dGU6XCLDnVwiLHlhY3V0ZTpcIsO9XCIsWUFjeTpcItCvXCIseWFjeTpcItGPXCIsWWNpcmM6XCLFtlwiLHljaXJjOlwixbdcIixZY3k6XCLQq1wiLHljeTpcItGLXCIseWVuOlwiwqVcIixZZnI6XCLwnZScXCIseWZyOlwi8J2UtlwiLFlJY3k6XCLQh1wiLHlpY3k6XCLRl1wiLFlvcGY6XCLwnZWQXCIseW9wZjpcIvCdlapcIixZc2NyOlwi8J2StFwiLHlzY3I6XCLwnZOOXCIsWVVjeTpcItCuXCIseXVjeTpcItGOXCIseXVtbDpcIsO/XCIsWXVtbDpcIsW4XCIsWmFjdXRlOlwixblcIix6YWN1dGU6XCLFulwiLFpjYXJvbjpcIsW9XCIsemNhcm9uOlwixb5cIixaY3k6XCLQl1wiLHpjeTpcItC3XCIsWmRvdDpcIsW7XCIsemRvdDpcIsW8XCIsemVldHJmOlwi4oSoXCIsWmVyb1dpZHRoU3BhY2U6XCLigItcIixaZXRhOlwizpZcIix6ZXRhOlwizrZcIix6ZnI6XCLwnZS3XCIsWmZyOlwi4oSoXCIsWkhjeTpcItCWXCIsemhjeTpcItC2XCIsemlncmFycjpcIuKHnVwiLHpvcGY6XCLwnZWrXCIsWm9wZjpcIuKEpFwiLFpzY3I6XCLwnZK1XCIsenNjcjpcIvCdk49cIix6d2o6XCLigI1cIix6d25qOlwi4oCMXCJ9fSx7fV0sMjY6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe21vZHVsZS5leHBvcnRzPXtBYWN1dGU6XCLDgVwiLGFhY3V0ZTpcIsOhXCIsQWNpcmM6XCLDglwiLGFjaXJjOlwiw6JcIixhY3V0ZTpcIsK0XCIsQUVsaWc6XCLDhlwiLGFlbGlnOlwiw6ZcIixBZ3JhdmU6XCLDgFwiLGFncmF2ZTpcIsOgXCIsYW1wOlwiJlwiLEFNUDpcIiZcIixBcmluZzpcIsOFXCIsYXJpbmc6XCLDpVwiLEF0aWxkZTpcIsODXCIsYXRpbGRlOlwiw6NcIixBdW1sOlwiw4RcIixhdW1sOlwiw6RcIixicnZiYXI6XCLCplwiLENjZWRpbDpcIsOHXCIsY2NlZGlsOlwiw6dcIixjZWRpbDpcIsK4XCIsY2VudDpcIsKiXCIsY29weTpcIsKpXCIsQ09QWTpcIsKpXCIsY3VycmVuOlwiwqRcIixkZWc6XCLCsFwiLGRpdmlkZTpcIsO3XCIsRWFjdXRlOlwiw4lcIixlYWN1dGU6XCLDqVwiLEVjaXJjOlwiw4pcIixlY2lyYzpcIsOqXCIsRWdyYXZlOlwiw4hcIixlZ3JhdmU6XCLDqFwiLEVUSDpcIsOQXCIsZXRoOlwiw7BcIixFdW1sOlwiw4tcIixldW1sOlwiw6tcIixmcmFjMTI6XCLCvVwiLGZyYWMxNDpcIsK8XCIsZnJhYzM0Olwiwr5cIixndDpcIj5cIixHVDpcIj5cIixJYWN1dGU6XCLDjVwiLGlhY3V0ZTpcIsOtXCIsSWNpcmM6XCLDjlwiLGljaXJjOlwiw65cIixpZXhjbDpcIsKhXCIsSWdyYXZlOlwiw4xcIixpZ3JhdmU6XCLDrFwiLGlxdWVzdDpcIsK/XCIsSXVtbDpcIsOPXCIsaXVtbDpcIsOvXCIsbGFxdW86XCLCq1wiLGx0OlwiPFwiLExUOlwiPFwiLG1hY3I6XCLCr1wiLG1pY3JvOlwiwrVcIixtaWRkb3Q6XCLCt1wiLG5ic3A6XCLCoFwiLG5vdDpcIsKsXCIsTnRpbGRlOlwiw5FcIixudGlsZGU6XCLDsVwiLE9hY3V0ZTpcIsOTXCIsb2FjdXRlOlwiw7NcIixPY2lyYzpcIsOUXCIsb2NpcmM6XCLDtFwiLE9ncmF2ZTpcIsOSXCIsb2dyYXZlOlwiw7JcIixvcmRmOlwiwqpcIixvcmRtOlwiwrpcIixPc2xhc2g6XCLDmFwiLG9zbGFzaDpcIsO4XCIsT3RpbGRlOlwiw5VcIixvdGlsZGU6XCLDtVwiLE91bWw6XCLDllwiLG91bWw6XCLDtlwiLHBhcmE6XCLCtlwiLHBsdXNtbjpcIsKxXCIscG91bmQ6XCLCo1wiLHF1b3Q6J1wiJyxRVU9UOidcIicscmFxdW86XCLCu1wiLHJlZzpcIsKuXCIsUkVHOlwiwq5cIixzZWN0OlwiwqdcIixzaHk6XCLCrVwiLHN1cDE6XCLCuVwiLHN1cDI6XCLCslwiLHN1cDM6XCLCs1wiLHN6bGlnOlwiw59cIixUSE9STjpcIsOeXCIsdGhvcm46XCLDvlwiLHRpbWVzOlwiw5dcIixVYWN1dGU6XCLDmlwiLHVhY3V0ZTpcIsO6XCIsVWNpcmM6XCLDm1wiLHVjaXJjOlwiw7tcIixVZ3JhdmU6XCLDmVwiLHVncmF2ZTpcIsO5XCIsdW1sOlwiwqhcIixVdW1sOlwiw5xcIix1dW1sOlwiw7xcIixZYWN1dGU6XCLDnVwiLHlhY3V0ZTpcIsO9XCIseWVuOlwiwqVcIix5dW1sOlwiw79cIn19LHt9XSwyNzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9e2FtcDpcIiZcIixhcG9zOlwiJ1wiLGd0OlwiPlwiLGx0OlwiPFwiLHF1b3Q6J1wiJ319LHt9XSwyODpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7ZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCl7dGhpcy5fZXZlbnRzPXRoaXMuX2V2ZW50c3x8e307dGhpcy5fbWF4TGlzdGVuZXJzPXRoaXMuX21heExpc3RlbmVyc3x8dW5kZWZpbmVkfW1vZHVsZS5leHBvcnRzPUV2ZW50RW1pdHRlcjtFdmVudEVtaXR0ZXIuRXZlbnRFbWl0dGVyPUV2ZW50RW1pdHRlcjtFdmVudEVtaXR0ZXIucHJvdG90eXBlLl9ldmVudHM9dW5kZWZpbmVkO0V2ZW50RW1pdHRlci5wcm90b3R5cGUuX21heExpc3RlbmVycz11bmRlZmluZWQ7RXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnM9MTA7RXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnM9ZnVuY3Rpb24obil7aWYoIWlzTnVtYmVyKG4pfHxuPDB8fGlzTmFOKG4pKXRocm93IFR5cGVFcnJvcihcIm4gbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlclwiKTt0aGlzLl9tYXhMaXN0ZW5lcnM9bjtyZXR1cm4gdGhpc307RXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0PWZ1bmN0aW9uKHR5cGUpe3ZhciBlcixoYW5kbGVyLGxlbixhcmdzLGksbGlzdGVuZXJzO2lmKCF0aGlzLl9ldmVudHMpdGhpcy5fZXZlbnRzPXt9O2lmKHR5cGU9PT1cImVycm9yXCIpe2lmKCF0aGlzLl9ldmVudHMuZXJyb3J8fGlzT2JqZWN0KHRoaXMuX2V2ZW50cy5lcnJvcikmJiF0aGlzLl9ldmVudHMuZXJyb3IubGVuZ3RoKXtlcj1hcmd1bWVudHNbMV07aWYoZXIgaW5zdGFuY2VvZiBFcnJvcil7dGhyb3cgZXJ9ZWxzZXt2YXIgZXJyPW5ldyBFcnJvcignVW5jYXVnaHQsIHVuc3BlY2lmaWVkIFwiZXJyb3JcIiBldmVudC4gKCcrZXIrXCIpXCIpO2Vyci5jb250ZXh0PWVyO3Rocm93IGVycn19fWhhbmRsZXI9dGhpcy5fZXZlbnRzW3R5cGVdO2lmKGlzVW5kZWZpbmVkKGhhbmRsZXIpKXJldHVybiBmYWxzZTtpZihpc0Z1bmN0aW9uKGhhbmRsZXIpKXtzd2l0Y2goYXJndW1lbnRzLmxlbmd0aCl7Y2FzZSAxOmhhbmRsZXIuY2FsbCh0aGlzKTticmVhaztjYXNlIDI6aGFuZGxlci5jYWxsKHRoaXMsYXJndW1lbnRzWzFdKTticmVhaztjYXNlIDM6aGFuZGxlci5jYWxsKHRoaXMsYXJndW1lbnRzWzFdLGFyZ3VtZW50c1syXSk7YnJlYWs7ZGVmYXVsdDphcmdzPUFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywxKTtoYW5kbGVyLmFwcGx5KHRoaXMsYXJncyl9fWVsc2UgaWYoaXNPYmplY3QoaGFuZGxlcikpe2FyZ3M9QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLDEpO2xpc3RlbmVycz1oYW5kbGVyLnNsaWNlKCk7bGVuPWxpc3RlbmVycy5sZW5ndGg7Zm9yKGk9MDtpPGxlbjtpKyspbGlzdGVuZXJzW2ldLmFwcGx5KHRoaXMsYXJncyl9cmV0dXJuIHRydWV9O0V2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI9ZnVuY3Rpb24odHlwZSxsaXN0ZW5lcil7dmFyIG07aWYoIWlzRnVuY3Rpb24obGlzdGVuZXIpKXRocm93IFR5cGVFcnJvcihcImxpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvblwiKTtpZighdGhpcy5fZXZlbnRzKXRoaXMuX2V2ZW50cz17fTtpZih0aGlzLl9ldmVudHMubmV3TGlzdGVuZXIpdGhpcy5lbWl0KFwibmV3TGlzdGVuZXJcIix0eXBlLGlzRnVuY3Rpb24obGlzdGVuZXIubGlzdGVuZXIpP2xpc3RlbmVyLmxpc3RlbmVyOmxpc3RlbmVyKTtpZighdGhpcy5fZXZlbnRzW3R5cGVdKXRoaXMuX2V2ZW50c1t0eXBlXT1saXN0ZW5lcjtlbHNlIGlmKGlzT2JqZWN0KHRoaXMuX2V2ZW50c1t0eXBlXSkpdGhpcy5fZXZlbnRzW3R5cGVdLnB1c2gobGlzdGVuZXIpO2Vsc2UgdGhpcy5fZXZlbnRzW3R5cGVdPVt0aGlzLl9ldmVudHNbdHlwZV0sbGlzdGVuZXJdO2lmKGlzT2JqZWN0KHRoaXMuX2V2ZW50c1t0eXBlXSkmJiF0aGlzLl9ldmVudHNbdHlwZV0ud2FybmVkKXtpZighaXNVbmRlZmluZWQodGhpcy5fbWF4TGlzdGVuZXJzKSl7bT10aGlzLl9tYXhMaXN0ZW5lcnN9ZWxzZXttPUV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzfWlmKG0mJm0+MCYmdGhpcy5fZXZlbnRzW3R5cGVdLmxlbmd0aD5tKXt0aGlzLl9ldmVudHNbdHlwZV0ud2FybmVkPXRydWU7Y29uc29sZS5lcnJvcihcIihub2RlKSB3YXJuaW5nOiBwb3NzaWJsZSBFdmVudEVtaXR0ZXIgbWVtb3J5IFwiK1wibGVhayBkZXRlY3RlZC4gJWQgbGlzdGVuZXJzIGFkZGVkLiBcIitcIlVzZSBlbWl0dGVyLnNldE1heExpc3RlbmVycygpIHRvIGluY3JlYXNlIGxpbWl0LlwiLHRoaXMuX2V2ZW50c1t0eXBlXS5sZW5ndGgpO2lmKHR5cGVvZiBjb25zb2xlLnRyYWNlPT09XCJmdW5jdGlvblwiKXtjb25zb2xlLnRyYWNlKCl9fX1yZXR1cm4gdGhpc307RXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbj1FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyO0V2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZT1mdW5jdGlvbih0eXBlLGxpc3RlbmVyKXtpZighaXNGdW5jdGlvbihsaXN0ZW5lcikpdGhyb3cgVHlwZUVycm9yKFwibGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uXCIpO3ZhciBmaXJlZD1mYWxzZTtmdW5jdGlvbiBnKCl7dGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLGcpO2lmKCFmaXJlZCl7ZmlyZWQ9dHJ1ZTtsaXN0ZW5lci5hcHBseSh0aGlzLGFyZ3VtZW50cyl9fWcubGlzdGVuZXI9bGlzdGVuZXI7dGhpcy5vbih0eXBlLGcpO3JldHVybiB0aGlzfTtFdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyPWZ1bmN0aW9uKHR5cGUsbGlzdGVuZXIpe3ZhciBsaXN0LHBvc2l0aW9uLGxlbmd0aCxpO2lmKCFpc0Z1bmN0aW9uKGxpc3RlbmVyKSl0aHJvdyBUeXBlRXJyb3IoXCJsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb25cIik7aWYoIXRoaXMuX2V2ZW50c3x8IXRoaXMuX2V2ZW50c1t0eXBlXSlyZXR1cm4gdGhpcztsaXN0PXRoaXMuX2V2ZW50c1t0eXBlXTtsZW5ndGg9bGlzdC5sZW5ndGg7cG9zaXRpb249LTE7aWYobGlzdD09PWxpc3RlbmVyfHxpc0Z1bmN0aW9uKGxpc3QubGlzdGVuZXIpJiZsaXN0Lmxpc3RlbmVyPT09bGlzdGVuZXIpe2RlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07aWYodGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKXRoaXMuZW1pdChcInJlbW92ZUxpc3RlbmVyXCIsdHlwZSxsaXN0ZW5lcil9ZWxzZSBpZihpc09iamVjdChsaXN0KSl7Zm9yKGk9bGVuZ3RoO2ktLSA+MDspe2lmKGxpc3RbaV09PT1saXN0ZW5lcnx8bGlzdFtpXS5saXN0ZW5lciYmbGlzdFtpXS5saXN0ZW5lcj09PWxpc3RlbmVyKXtwb3NpdGlvbj1pO2JyZWFrfX1pZihwb3NpdGlvbjwwKXJldHVybiB0aGlzO2lmKGxpc3QubGVuZ3RoPT09MSl7bGlzdC5sZW5ndGg9MDtkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdfWVsc2V7bGlzdC5zcGxpY2UocG9zaXRpb24sMSk7XG59aWYodGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKXRoaXMuZW1pdChcInJlbW92ZUxpc3RlbmVyXCIsdHlwZSxsaXN0ZW5lcil9cmV0dXJuIHRoaXN9O0V2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlQWxsTGlzdGVuZXJzPWZ1bmN0aW9uKHR5cGUpe3ZhciBrZXksbGlzdGVuZXJzO2lmKCF0aGlzLl9ldmVudHMpcmV0dXJuIHRoaXM7aWYoIXRoaXMuX2V2ZW50cy5yZW1vdmVMaXN0ZW5lcil7aWYoYXJndW1lbnRzLmxlbmd0aD09PTApdGhpcy5fZXZlbnRzPXt9O2Vsc2UgaWYodGhpcy5fZXZlbnRzW3R5cGVdKWRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07cmV0dXJuIHRoaXN9aWYoYXJndW1lbnRzLmxlbmd0aD09PTApe2ZvcihrZXkgaW4gdGhpcy5fZXZlbnRzKXtpZihrZXk9PT1cInJlbW92ZUxpc3RlbmVyXCIpY29udGludWU7dGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoa2V5KX10aGlzLnJlbW92ZUFsbExpc3RlbmVycyhcInJlbW92ZUxpc3RlbmVyXCIpO3RoaXMuX2V2ZW50cz17fTtyZXR1cm4gdGhpc31saXN0ZW5lcnM9dGhpcy5fZXZlbnRzW3R5cGVdO2lmKGlzRnVuY3Rpb24obGlzdGVuZXJzKSl7dGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLGxpc3RlbmVycyl9ZWxzZSBpZihsaXN0ZW5lcnMpe3doaWxlKGxpc3RlbmVycy5sZW5ndGgpdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLGxpc3RlbmVyc1tsaXN0ZW5lcnMubGVuZ3RoLTFdKX1kZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO3JldHVybiB0aGlzfTtFdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycz1mdW5jdGlvbih0eXBlKXt2YXIgcmV0O2lmKCF0aGlzLl9ldmVudHN8fCF0aGlzLl9ldmVudHNbdHlwZV0pcmV0PVtdO2Vsc2UgaWYoaXNGdW5jdGlvbih0aGlzLl9ldmVudHNbdHlwZV0pKXJldD1bdGhpcy5fZXZlbnRzW3R5cGVdXTtlbHNlIHJldD10aGlzLl9ldmVudHNbdHlwZV0uc2xpY2UoKTtyZXR1cm4gcmV0fTtFdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVyQ291bnQ9ZnVuY3Rpb24odHlwZSl7aWYodGhpcy5fZXZlbnRzKXt2YXIgZXZsaXN0ZW5lcj10aGlzLl9ldmVudHNbdHlwZV07aWYoaXNGdW5jdGlvbihldmxpc3RlbmVyKSlyZXR1cm4gMTtlbHNlIGlmKGV2bGlzdGVuZXIpcmV0dXJuIGV2bGlzdGVuZXIubGVuZ3RofXJldHVybiAwfTtFdmVudEVtaXR0ZXIubGlzdGVuZXJDb3VudD1mdW5jdGlvbihlbWl0dGVyLHR5cGUpe3JldHVybiBlbWl0dGVyLmxpc3RlbmVyQ291bnQodHlwZSl9O2Z1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKXtyZXR1cm4gdHlwZW9mIGFyZz09PVwiZnVuY3Rpb25cIn1mdW5jdGlvbiBpc051bWJlcihhcmcpe3JldHVybiB0eXBlb2YgYXJnPT09XCJudW1iZXJcIn1mdW5jdGlvbiBpc09iamVjdChhcmcpe3JldHVybiB0eXBlb2YgYXJnPT09XCJvYmplY3RcIiYmYXJnIT09bnVsbH1mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpe3JldHVybiBhcmc9PT12b2lkIDB9fSx7fV0sMjk6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe21vZHVsZS5leHBvcnRzPUNvbGxlY3RpbmdIYW5kbGVyO2Z1bmN0aW9uIENvbGxlY3RpbmdIYW5kbGVyKGNicyl7dGhpcy5fY2JzPWNic3x8e307dGhpcy5ldmVudHM9W119dmFyIEVWRU5UUz1yZXF1aXJlKFwiLi9cIikuRVZFTlRTO09iamVjdC5rZXlzKEVWRU5UUykuZm9yRWFjaChmdW5jdGlvbihuYW1lKXtpZihFVkVOVFNbbmFtZV09PT0wKXtuYW1lPVwib25cIituYW1lO0NvbGxlY3RpbmdIYW5kbGVyLnByb3RvdHlwZVtuYW1lXT1mdW5jdGlvbigpe3RoaXMuZXZlbnRzLnB1c2goW25hbWVdKTtpZih0aGlzLl9jYnNbbmFtZV0pdGhpcy5fY2JzW25hbWVdKCl9fWVsc2UgaWYoRVZFTlRTW25hbWVdPT09MSl7bmFtZT1cIm9uXCIrbmFtZTtDb2xsZWN0aW5nSGFuZGxlci5wcm90b3R5cGVbbmFtZV09ZnVuY3Rpb24oYSl7dGhpcy5ldmVudHMucHVzaChbbmFtZSxhXSk7aWYodGhpcy5fY2JzW25hbWVdKXRoaXMuX2Nic1tuYW1lXShhKX19ZWxzZSBpZihFVkVOVFNbbmFtZV09PT0yKXtuYW1lPVwib25cIituYW1lO0NvbGxlY3RpbmdIYW5kbGVyLnByb3RvdHlwZVtuYW1lXT1mdW5jdGlvbihhLGIpe3RoaXMuZXZlbnRzLnB1c2goW25hbWUsYSxiXSk7aWYodGhpcy5fY2JzW25hbWVdKXRoaXMuX2Nic1tuYW1lXShhLGIpfX1lbHNle3Rocm93IEVycm9yKFwid3JvbmcgbnVtYmVyIG9mIGFyZ3VtZW50c1wiKX19KTtDb2xsZWN0aW5nSGFuZGxlci5wcm90b3R5cGUub25yZXNldD1mdW5jdGlvbigpe3RoaXMuZXZlbnRzPVtdO2lmKHRoaXMuX2Nicy5vbnJlc2V0KXRoaXMuX2Nicy5vbnJlc2V0KCl9O0NvbGxlY3RpbmdIYW5kbGVyLnByb3RvdHlwZS5yZXN0YXJ0PWZ1bmN0aW9uKCl7aWYodGhpcy5fY2JzLm9ucmVzZXQpdGhpcy5fY2JzLm9ucmVzZXQoKTtmb3IodmFyIGk9MCxsZW49dGhpcy5ldmVudHMubGVuZ3RoO2k8bGVuO2krKyl7aWYodGhpcy5fY2JzW3RoaXMuZXZlbnRzW2ldWzBdXSl7dmFyIG51bT10aGlzLmV2ZW50c1tpXS5sZW5ndGg7aWYobnVtPT09MSl7dGhpcy5fY2JzW3RoaXMuZXZlbnRzW2ldWzBdXSgpfWVsc2UgaWYobnVtPT09Mil7dGhpcy5fY2JzW3RoaXMuZXZlbnRzW2ldWzBdXSh0aGlzLmV2ZW50c1tpXVsxXSl9ZWxzZXt0aGlzLl9jYnNbdGhpcy5ldmVudHNbaV1bMF1dKHRoaXMuZXZlbnRzW2ldWzFdLHRoaXMuZXZlbnRzW2ldWzJdKX19fX19LHtcIi4vXCI6MzZ9XSwzMDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIGluZGV4PXJlcXVpcmUoXCIuL2luZGV4LmpzXCIpLERvbUhhbmRsZXI9aW5kZXguRG9tSGFuZGxlcixEb21VdGlscz1pbmRleC5Eb21VdGlscztmdW5jdGlvbiBGZWVkSGFuZGxlcihjYWxsYmFjayxvcHRpb25zKXt0aGlzLmluaXQoY2FsbGJhY2ssb3B0aW9ucyl9cmVxdWlyZShcImluaGVyaXRzXCIpKEZlZWRIYW5kbGVyLERvbUhhbmRsZXIpO0ZlZWRIYW5kbGVyLnByb3RvdHlwZS5pbml0PURvbUhhbmRsZXI7ZnVuY3Rpb24gZ2V0RWxlbWVudHMod2hhdCx3aGVyZSl7cmV0dXJuIERvbVV0aWxzLmdldEVsZW1lbnRzQnlUYWdOYW1lKHdoYXQsd2hlcmUsdHJ1ZSl9ZnVuY3Rpb24gZ2V0T25lRWxlbWVudCh3aGF0LHdoZXJlKXtyZXR1cm4gRG9tVXRpbHMuZ2V0RWxlbWVudHNCeVRhZ05hbWUod2hhdCx3aGVyZSx0cnVlLDEpWzBdfWZ1bmN0aW9uIGZldGNoKHdoYXQsd2hlcmUscmVjdXJzZSl7cmV0dXJuIERvbVV0aWxzLmdldFRleHQoRG9tVXRpbHMuZ2V0RWxlbWVudHNCeVRhZ05hbWUod2hhdCx3aGVyZSxyZWN1cnNlLDEpKS50cmltKCl9ZnVuY3Rpb24gYWRkQ29uZGl0aW9uYWxseShvYmoscHJvcCx3aGF0LHdoZXJlLHJlY3Vyc2Upe3ZhciB0bXA9ZmV0Y2god2hhdCx3aGVyZSxyZWN1cnNlKTtpZih0bXApb2JqW3Byb3BdPXRtcH12YXIgaXNWYWxpZEZlZWQ9ZnVuY3Rpb24odmFsdWUpe3JldHVybiB2YWx1ZT09PVwicnNzXCJ8fHZhbHVlPT09XCJmZWVkXCJ8fHZhbHVlPT09XCJyZGY6UkRGXCJ9O0ZlZWRIYW5kbGVyLnByb3RvdHlwZS5vbmVuZD1mdW5jdGlvbigpe3ZhciBmZWVkPXt9LGZlZWRSb290PWdldE9uZUVsZW1lbnQoaXNWYWxpZEZlZWQsdGhpcy5kb20pLHRtcCxjaGlsZHM7aWYoZmVlZFJvb3Qpe2lmKGZlZWRSb290Lm5hbWU9PT1cImZlZWRcIil7Y2hpbGRzPWZlZWRSb290LmNoaWxkcmVuO2ZlZWQudHlwZT1cImF0b21cIjthZGRDb25kaXRpb25hbGx5KGZlZWQsXCJpZFwiLFwiaWRcIixjaGlsZHMpO2FkZENvbmRpdGlvbmFsbHkoZmVlZCxcInRpdGxlXCIsXCJ0aXRsZVwiLGNoaWxkcyk7aWYoKHRtcD1nZXRPbmVFbGVtZW50KFwibGlua1wiLGNoaWxkcykpJiYodG1wPXRtcC5hdHRyaWJzKSYmKHRtcD10bXAuaHJlZikpZmVlZC5saW5rPXRtcDthZGRDb25kaXRpb25hbGx5KGZlZWQsXCJkZXNjcmlwdGlvblwiLFwic3VidGl0bGVcIixjaGlsZHMpO2lmKHRtcD1mZXRjaChcInVwZGF0ZWRcIixjaGlsZHMpKWZlZWQudXBkYXRlZD1uZXcgRGF0ZSh0bXApO2FkZENvbmRpdGlvbmFsbHkoZmVlZCxcImF1dGhvclwiLFwiZW1haWxcIixjaGlsZHMsdHJ1ZSk7ZmVlZC5pdGVtcz1nZXRFbGVtZW50cyhcImVudHJ5XCIsY2hpbGRzKS5tYXAoZnVuY3Rpb24oaXRlbSl7dmFyIGVudHJ5PXt9LHRtcDtpdGVtPWl0ZW0uY2hpbGRyZW47YWRkQ29uZGl0aW9uYWxseShlbnRyeSxcImlkXCIsXCJpZFwiLGl0ZW0pO2FkZENvbmRpdGlvbmFsbHkoZW50cnksXCJ0aXRsZVwiLFwidGl0bGVcIixpdGVtKTtpZigodG1wPWdldE9uZUVsZW1lbnQoXCJsaW5rXCIsaXRlbSkpJiYodG1wPXRtcC5hdHRyaWJzKSYmKHRtcD10bXAuaHJlZikpZW50cnkubGluaz10bXA7aWYodG1wPWZldGNoKFwic3VtbWFyeVwiLGl0ZW0pfHxmZXRjaChcImNvbnRlbnRcIixpdGVtKSllbnRyeS5kZXNjcmlwdGlvbj10bXA7aWYodG1wPWZldGNoKFwidXBkYXRlZFwiLGl0ZW0pKWVudHJ5LnB1YkRhdGU9bmV3IERhdGUodG1wKTtyZXR1cm4gZW50cnl9KX1lbHNle2NoaWxkcz1nZXRPbmVFbGVtZW50KFwiY2hhbm5lbFwiLGZlZWRSb290LmNoaWxkcmVuKS5jaGlsZHJlbjtmZWVkLnR5cGU9ZmVlZFJvb3QubmFtZS5zdWJzdHIoMCwzKTtmZWVkLmlkPVwiXCI7YWRkQ29uZGl0aW9uYWxseShmZWVkLFwidGl0bGVcIixcInRpdGxlXCIsY2hpbGRzKTthZGRDb25kaXRpb25hbGx5KGZlZWQsXCJsaW5rXCIsXCJsaW5rXCIsY2hpbGRzKTthZGRDb25kaXRpb25hbGx5KGZlZWQsXCJkZXNjcmlwdGlvblwiLFwiZGVzY3JpcHRpb25cIixjaGlsZHMpO2lmKHRtcD1mZXRjaChcImxhc3RCdWlsZERhdGVcIixjaGlsZHMpKWZlZWQudXBkYXRlZD1uZXcgRGF0ZSh0bXApO2FkZENvbmRpdGlvbmFsbHkoZmVlZCxcImF1dGhvclwiLFwibWFuYWdpbmdFZGl0b3JcIixjaGlsZHMsdHJ1ZSk7ZmVlZC5pdGVtcz1nZXRFbGVtZW50cyhcIml0ZW1cIixmZWVkUm9vdC5jaGlsZHJlbikubWFwKGZ1bmN0aW9uKGl0ZW0pe3ZhciBlbnRyeT17fSx0bXA7aXRlbT1pdGVtLmNoaWxkcmVuO2FkZENvbmRpdGlvbmFsbHkoZW50cnksXCJpZFwiLFwiZ3VpZFwiLGl0ZW0pO2FkZENvbmRpdGlvbmFsbHkoZW50cnksXCJ0aXRsZVwiLFwidGl0bGVcIixpdGVtKTthZGRDb25kaXRpb25hbGx5KGVudHJ5LFwibGlua1wiLFwibGlua1wiLGl0ZW0pO2FkZENvbmRpdGlvbmFsbHkoZW50cnksXCJkZXNjcmlwdGlvblwiLFwiZGVzY3JpcHRpb25cIixpdGVtKTtpZih0bXA9ZmV0Y2goXCJwdWJEYXRlXCIsaXRlbSkpZW50cnkucHViRGF0ZT1uZXcgRGF0ZSh0bXApO3JldHVybiBlbnRyeX0pfX10aGlzLmRvbT1mZWVkO0RvbUhhbmRsZXIucHJvdG90eXBlLl9oYW5kbGVDYWxsYmFjay5jYWxsKHRoaXMsZmVlZFJvb3Q/bnVsbDpFcnJvcihcImNvdWxkbid0IGZpbmQgcm9vdCBvZiBmZWVkXCIpKX07bW9kdWxlLmV4cG9ydHM9RmVlZEhhbmRsZXJ9LHtcIi4vaW5kZXguanNcIjozNixpbmhlcml0czozOH1dLDMxOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgVG9rZW5pemVyPXJlcXVpcmUoXCIuL1Rva2VuaXplci5qc1wiKTt2YXIgZm9ybVRhZ3M9e2lucHV0OnRydWUsb3B0aW9uOnRydWUsb3B0Z3JvdXA6dHJ1ZSxzZWxlY3Q6dHJ1ZSxidXR0b246dHJ1ZSxkYXRhbGlzdDp0cnVlLHRleHRhcmVhOnRydWV9O3ZhciBvcGVuSW1wbGllc0Nsb3NlPXt0cjp7dHI6dHJ1ZSx0aDp0cnVlLHRkOnRydWV9LHRoOnt0aDp0cnVlfSx0ZDp7dGhlYWQ6dHJ1ZSx0aDp0cnVlLHRkOnRydWV9LGJvZHk6e2hlYWQ6dHJ1ZSxsaW5rOnRydWUsc2NyaXB0OnRydWV9LGxpOntsaTp0cnVlfSxwOntwOnRydWV9LGgxOntwOnRydWV9LGgyOntwOnRydWV9LGgzOntwOnRydWV9LGg0OntwOnRydWV9LGg1OntwOnRydWV9LGg2OntwOnRydWV9LHNlbGVjdDpmb3JtVGFncyxpbnB1dDpmb3JtVGFncyxvdXRwdXQ6Zm9ybVRhZ3MsYnV0dG9uOmZvcm1UYWdzLGRhdGFsaXN0OmZvcm1UYWdzLHRleHRhcmVhOmZvcm1UYWdzLG9wdGlvbjp7b3B0aW9uOnRydWV9LG9wdGdyb3VwOntvcHRncm91cDp0cnVlfX07dmFyIHZvaWRFbGVtZW50cz17X19wcm90b19fOm51bGwsYXJlYTp0cnVlLGJhc2U6dHJ1ZSxiYXNlZm9udDp0cnVlLGJyOnRydWUsY29sOnRydWUsY29tbWFuZDp0cnVlLGVtYmVkOnRydWUsZnJhbWU6dHJ1ZSxocjp0cnVlLGltZzp0cnVlLGlucHV0OnRydWUsaXNpbmRleDp0cnVlLGtleWdlbjp0cnVlLGxpbms6dHJ1ZSxtZXRhOnRydWUscGFyYW06dHJ1ZSxzb3VyY2U6dHJ1ZSx0cmFjazp0cnVlLHdicjp0cnVlLHBhdGg6dHJ1ZSxjaXJjbGU6dHJ1ZSxlbGxpcHNlOnRydWUsbGluZTp0cnVlLHJlY3Q6dHJ1ZSx1c2U6dHJ1ZSxzdG9wOnRydWUscG9seWxpbmU6dHJ1ZSxwb2x5Z29uOnRydWV9O3ZhciByZV9uYW1lRW5kPS9cXHN8XFwvLztmdW5jdGlvbiBQYXJzZXIoY2JzLG9wdGlvbnMpe3RoaXMuX29wdGlvbnM9b3B0aW9uc3x8e307dGhpcy5fY2JzPWNic3x8e307dGhpcy5fdGFnbmFtZT1cIlwiO3RoaXMuX2F0dHJpYm5hbWU9XCJcIjt0aGlzLl9hdHRyaWJ2YWx1ZT1cIlwiO3RoaXMuX2F0dHJpYnM9bnVsbDt0aGlzLl9zdGFjaz1bXTt0aGlzLnN0YXJ0SW5kZXg9MDt0aGlzLmVuZEluZGV4PW51bGw7dGhpcy5fbG93ZXJDYXNlVGFnTmFtZXM9XCJsb3dlckNhc2VUYWdzXCJpbiB0aGlzLl9vcHRpb25zPyEhdGhpcy5fb3B0aW9ucy5sb3dlckNhc2VUYWdzOiF0aGlzLl9vcHRpb25zLnhtbE1vZGU7dGhpcy5fbG93ZXJDYXNlQXR0cmlidXRlTmFtZXM9XCJsb3dlckNhc2VBdHRyaWJ1dGVOYW1lc1wiaW4gdGhpcy5fb3B0aW9ucz8hIXRoaXMuX29wdGlvbnMubG93ZXJDYXNlQXR0cmlidXRlTmFtZXM6IXRoaXMuX29wdGlvbnMueG1sTW9kZTtpZih0aGlzLl9vcHRpb25zLlRva2VuaXplcil7VG9rZW5pemVyPXRoaXMuX29wdGlvbnMuVG9rZW5pemVyfXRoaXMuX3Rva2VuaXplcj1uZXcgVG9rZW5pemVyKHRoaXMuX29wdGlvbnMsdGhpcyk7aWYodGhpcy5fY2JzLm9ucGFyc2VyaW5pdCl0aGlzLl9jYnMub25wYXJzZXJpbml0KHRoaXMpfXJlcXVpcmUoXCJpbmhlcml0c1wiKShQYXJzZXIscmVxdWlyZShcImV2ZW50c1wiKS5FdmVudEVtaXR0ZXIpO1BhcnNlci5wcm90b3R5cGUuX3VwZGF0ZVBvc2l0aW9uPWZ1bmN0aW9uKGluaXRpYWxPZmZzZXQpe2lmKHRoaXMuZW5kSW5kZXg9PT1udWxsKXtpZih0aGlzLl90b2tlbml6ZXIuX3NlY3Rpb25TdGFydDw9aW5pdGlhbE9mZnNldCl7dGhpcy5zdGFydEluZGV4PTB9ZWxzZXt0aGlzLnN0YXJ0SW5kZXg9dGhpcy5fdG9rZW5pemVyLl9zZWN0aW9uU3RhcnQtaW5pdGlhbE9mZnNldH19ZWxzZSB0aGlzLnN0YXJ0SW5kZXg9dGhpcy5lbmRJbmRleCsxO3RoaXMuZW5kSW5kZXg9dGhpcy5fdG9rZW5pemVyLmdldEFic29sdXRlSW5kZXgoKX07UGFyc2VyLnByb3RvdHlwZS5vbnRleHQ9ZnVuY3Rpb24oZGF0YSl7dGhpcy5fdXBkYXRlUG9zaXRpb24oMSk7dGhpcy5lbmRJbmRleC0tO2lmKHRoaXMuX2Nicy5vbnRleHQpdGhpcy5fY2JzLm9udGV4dChkYXRhKX07UGFyc2VyLnByb3RvdHlwZS5vbm9wZW50YWduYW1lPWZ1bmN0aW9uKG5hbWUpe2lmKHRoaXMuX2xvd2VyQ2FzZVRhZ05hbWVzKXtuYW1lPW5hbWUudG9Mb3dlckNhc2UoKX10aGlzLl90YWduYW1lPW5hbWU7aWYoIXRoaXMuX29wdGlvbnMueG1sTW9kZSYmbmFtZSBpbiBvcGVuSW1wbGllc0Nsb3NlKXtmb3IodmFyIGVsOyhlbD10aGlzLl9zdGFja1t0aGlzLl9zdGFjay5sZW5ndGgtMV0paW4gb3BlbkltcGxpZXNDbG9zZVtuYW1lXTt0aGlzLm9uY2xvc2V0YWcoZWwpKTt9aWYodGhpcy5fb3B0aW9ucy54bWxNb2RlfHwhKG5hbWUgaW4gdm9pZEVsZW1lbnRzKSl7dGhpcy5fc3RhY2sucHVzaChuYW1lKX1pZih0aGlzLl9jYnMub25vcGVudGFnbmFtZSl0aGlzLl9jYnMub25vcGVudGFnbmFtZShuYW1lKTtpZih0aGlzLl9jYnMub25vcGVudGFnKXRoaXMuX2F0dHJpYnM9e319O1BhcnNlci5wcm90b3R5cGUub25vcGVudGFnZW5kPWZ1bmN0aW9uKCl7dGhpcy5fdXBkYXRlUG9zaXRpb24oMSk7aWYodGhpcy5fYXR0cmlicyl7aWYodGhpcy5fY2JzLm9ub3BlbnRhZyl0aGlzLl9jYnMub25vcGVudGFnKHRoaXMuX3RhZ25hbWUsdGhpcy5fYXR0cmlicyk7dGhpcy5fYXR0cmlicz1udWxsfWlmKCF0aGlzLl9vcHRpb25zLnhtbE1vZGUmJnRoaXMuX2Nicy5vbmNsb3NldGFnJiZ0aGlzLl90YWduYW1lIGluIHZvaWRFbGVtZW50cyl7dGhpcy5fY2JzLm9uY2xvc2V0YWcodGhpcy5fdGFnbmFtZSl9dGhpcy5fdGFnbmFtZT1cIlwifTtQYXJzZXIucHJvdG90eXBlLm9uY2xvc2V0YWc9ZnVuY3Rpb24obmFtZSl7dGhpcy5fdXBkYXRlUG9zaXRpb24oMSk7aWYodGhpcy5fbG93ZXJDYXNlVGFnTmFtZXMpe25hbWU9bmFtZS50b0xvd2VyQ2FzZSgpfWlmKHRoaXMuX3N0YWNrLmxlbmd0aCYmKCEobmFtZSBpbiB2b2lkRWxlbWVudHMpfHx0aGlzLl9vcHRpb25zLnhtbE1vZGUpKXt2YXIgcG9zPXRoaXMuX3N0YWNrLmxhc3RJbmRleE9mKG5hbWUpO2lmKHBvcyE9PS0xKXtpZih0aGlzLl9jYnMub25jbG9zZXRhZyl7cG9zPXRoaXMuX3N0YWNrLmxlbmd0aC1wb3M7d2hpbGUocG9zLS0pdGhpcy5fY2JzLm9uY2xvc2V0YWcodGhpcy5fc3RhY2sucG9wKCkpfWVsc2UgdGhpcy5fc3RhY2subGVuZ3RoPXBvc31lbHNlIGlmKG5hbWU9PT1cInBcIiYmIXRoaXMuX29wdGlvbnMueG1sTW9kZSl7dGhpcy5vbm9wZW50YWduYW1lKG5hbWUpO3RoaXMuX2Nsb3NlQ3VycmVudFRhZygpfX1lbHNlIGlmKCF0aGlzLl9vcHRpb25zLnhtbE1vZGUmJihuYW1lPT09XCJiclwifHxuYW1lPT09XCJwXCIpKXt0aGlzLm9ub3BlbnRhZ25hbWUobmFtZSk7dGhpcy5fY2xvc2VDdXJyZW50VGFnKCl9fTtQYXJzZXIucHJvdG90eXBlLm9uc2VsZmNsb3Npbmd0YWc9ZnVuY3Rpb24oKXtpZih0aGlzLl9vcHRpb25zLnhtbE1vZGV8fHRoaXMuX29wdGlvbnMucmVjb2duaXplU2VsZkNsb3Npbmcpe3RoaXMuX2Nsb3NlQ3VycmVudFRhZygpfWVsc2V7dGhpcy5vbm9wZW50YWdlbmQoKX19O1BhcnNlci5wcm90b3R5cGUuX2Nsb3NlQ3VycmVudFRhZz1mdW5jdGlvbigpe3ZhciBuYW1lPXRoaXMuX3RhZ25hbWU7dGhpcy5vbm9wZW50YWdlbmQoKTtpZih0aGlzLl9zdGFja1t0aGlzLl9zdGFjay5sZW5ndGgtMV09PT1uYW1lKXtpZih0aGlzLl9jYnMub25jbG9zZXRhZyl7dGhpcy5fY2JzLm9uY2xvc2V0YWcobmFtZSl9dGhpcy5fc3RhY2sucG9wKCl9fTtQYXJzZXIucHJvdG90eXBlLm9uYXR0cmlibmFtZT1mdW5jdGlvbihuYW1lKXtpZih0aGlzLl9sb3dlckNhc2VBdHRyaWJ1dGVOYW1lcyl7bmFtZT1uYW1lLnRvTG93ZXJDYXNlKCl9dGhpcy5fYXR0cmlibmFtZT1uYW1lfTtQYXJzZXIucHJvdG90eXBlLm9uYXR0cmliZGF0YT1mdW5jdGlvbih2YWx1ZSl7dGhpcy5fYXR0cmlidmFsdWUrPXZhbHVlfTtQYXJzZXIucHJvdG90eXBlLm9uYXR0cmliZW5kPWZ1bmN0aW9uKCl7aWYodGhpcy5fY2JzLm9uYXR0cmlidXRlKXRoaXMuX2Nicy5vbmF0dHJpYnV0ZSh0aGlzLl9hdHRyaWJuYW1lLHRoaXMuX2F0dHJpYnZhbHVlKTtpZih0aGlzLl9hdHRyaWJzJiYhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMuX2F0dHJpYnMsdGhpcy5fYXR0cmlibmFtZSkpe3RoaXMuX2F0dHJpYnNbdGhpcy5fYXR0cmlibmFtZV09dGhpcy5fYXR0cmlidmFsdWV9dGhpcy5fYXR0cmlibmFtZT1cIlwiO3RoaXMuX2F0dHJpYnZhbHVlPVwiXCJ9O1BhcnNlci5wcm90b3R5cGUuX2dldEluc3RydWN0aW9uTmFtZT1mdW5jdGlvbih2YWx1ZSl7dmFyIGlkeD12YWx1ZS5zZWFyY2gocmVfbmFtZUVuZCksbmFtZT1pZHg8MD92YWx1ZTp2YWx1ZS5zdWJzdHIoMCxpZHgpO2lmKHRoaXMuX2xvd2VyQ2FzZVRhZ05hbWVzKXtuYW1lPW5hbWUudG9Mb3dlckNhc2UoKX1yZXR1cm4gbmFtZX07UGFyc2VyLnByb3RvdHlwZS5vbmRlY2xhcmF0aW9uPWZ1bmN0aW9uKHZhbHVlKXtpZih0aGlzLl9jYnMub25wcm9jZXNzaW5naW5zdHJ1Y3Rpb24pe3ZhciBuYW1lPXRoaXMuX2dldEluc3RydWN0aW9uTmFtZSh2YWx1ZSk7dGhpcy5fY2JzLm9ucHJvY2Vzc2luZ2luc3RydWN0aW9uKFwiIVwiK25hbWUsXCIhXCIrdmFsdWUpfX07UGFyc2VyLnByb3RvdHlwZS5vbnByb2Nlc3NpbmdpbnN0cnVjdGlvbj1mdW5jdGlvbih2YWx1ZSl7aWYodGhpcy5fY2JzLm9ucHJvY2Vzc2luZ2luc3RydWN0aW9uKXt2YXIgbmFtZT10aGlzLl9nZXRJbnN0cnVjdGlvbk5hbWUodmFsdWUpO3RoaXMuX2Nicy5vbnByb2Nlc3NpbmdpbnN0cnVjdGlvbihcIj9cIituYW1lLFwiP1wiK3ZhbHVlKX19O1BhcnNlci5wcm90b3R5cGUub25jb21tZW50PWZ1bmN0aW9uKHZhbHVlKXt0aGlzLl91cGRhdGVQb3NpdGlvbig0KTtpZih0aGlzLl9jYnMub25jb21tZW50KXRoaXMuX2Nicy5vbmNvbW1lbnQodmFsdWUpO2lmKHRoaXMuX2Nicy5vbmNvbW1lbnRlbmQpdGhpcy5fY2JzLm9uY29tbWVudGVuZCgpfTtQYXJzZXIucHJvdG90eXBlLm9uY2RhdGE9ZnVuY3Rpb24odmFsdWUpe3RoaXMuX3VwZGF0ZVBvc2l0aW9uKDEpO2lmKHRoaXMuX29wdGlvbnMueG1sTW9kZXx8dGhpcy5fb3B0aW9ucy5yZWNvZ25pemVDREFUQSl7aWYodGhpcy5fY2JzLm9uY2RhdGFzdGFydCl0aGlzLl9jYnMub25jZGF0YXN0YXJ0KCk7aWYodGhpcy5fY2JzLm9udGV4dCl0aGlzLl9jYnMub250ZXh0KHZhbHVlKTtpZih0aGlzLl9jYnMub25jZGF0YWVuZCl0aGlzLl9jYnMub25jZGF0YWVuZCgpfWVsc2V7dGhpcy5vbmNvbW1lbnQoXCJbQ0RBVEFbXCIrdmFsdWUrXCJdXVwiKX19O1BhcnNlci5wcm90b3R5cGUub25lcnJvcj1mdW5jdGlvbihlcnIpe2lmKHRoaXMuX2Nicy5vbmVycm9yKXRoaXMuX2Nicy5vbmVycm9yKGVycil9O1BhcnNlci5wcm90b3R5cGUub25lbmQ9ZnVuY3Rpb24oKXtpZih0aGlzLl9jYnMub25jbG9zZXRhZyl7Zm9yKHZhciBpPXRoaXMuX3N0YWNrLmxlbmd0aDtpPjA7dGhpcy5fY2JzLm9uY2xvc2V0YWcodGhpcy5fc3RhY2tbLS1pXSkpO31pZih0aGlzLl9jYnMub25lbmQpdGhpcy5fY2JzLm9uZW5kKCl9O1BhcnNlci5wcm90b3R5cGUucmVzZXQ9ZnVuY3Rpb24oKXtpZih0aGlzLl9jYnMub25yZXNldCl0aGlzLl9jYnMub25yZXNldCgpO3RoaXMuX3Rva2VuaXplci5yZXNldCgpO3RoaXMuX3RhZ25hbWU9XCJcIjt0aGlzLl9hdHRyaWJuYW1lPVwiXCI7dGhpcy5fYXR0cmlicz1udWxsO3RoaXMuX3N0YWNrPVtdO2lmKHRoaXMuX2Nicy5vbnBhcnNlcmluaXQpdGhpcy5fY2JzLm9ucGFyc2VyaW5pdCh0aGlzKX07UGFyc2VyLnByb3RvdHlwZS5wYXJzZUNvbXBsZXRlPWZ1bmN0aW9uKGRhdGEpe3RoaXMucmVzZXQoKTt0aGlzLmVuZChkYXRhKX07UGFyc2VyLnByb3RvdHlwZS53cml0ZT1mdW5jdGlvbihjaHVuayl7dGhpcy5fdG9rZW5pemVyLndyaXRlKGNodW5rKX07UGFyc2VyLnByb3RvdHlwZS5lbmQ9ZnVuY3Rpb24oY2h1bmspe3RoaXMuX3Rva2VuaXplci5lbmQoY2h1bmspfTtQYXJzZXIucHJvdG90eXBlLnBhdXNlPWZ1bmN0aW9uKCl7dGhpcy5fdG9rZW5pemVyLnBhdXNlKCl9O1BhcnNlci5wcm90b3R5cGUucmVzdW1lPWZ1bmN0aW9uKCl7dGhpcy5fdG9rZW5pemVyLnJlc3VtZSgpfTtQYXJzZXIucHJvdG90eXBlLnBhcnNlQ2h1bms9UGFyc2VyLnByb3RvdHlwZS53cml0ZTtQYXJzZXIucHJvdG90eXBlLmRvbmU9UGFyc2VyLnByb3RvdHlwZS5lbmQ7bW9kdWxlLmV4cG9ydHM9UGFyc2VyfSx7XCIuL1Rva2VuaXplci5qc1wiOjM0LGV2ZW50czoyOCxpbmhlcml0czozOH1dLDMyOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXttb2R1bGUuZXhwb3J0cz1Qcm94eUhhbmRsZXI7ZnVuY3Rpb24gUHJveHlIYW5kbGVyKGNicyl7dGhpcy5fY2JzPWNic3x8e319dmFyIEVWRU5UUz1yZXF1aXJlKFwiLi9cIikuRVZFTlRTO09iamVjdC5rZXlzKEVWRU5UUykuZm9yRWFjaChmdW5jdGlvbihuYW1lKXtpZihFVkVOVFNbbmFtZV09PT0wKXtuYW1lPVwib25cIituYW1lO1Byb3h5SGFuZGxlci5wcm90b3R5cGVbbmFtZV09ZnVuY3Rpb24oKXtpZih0aGlzLl9jYnNbbmFtZV0pdGhpcy5fY2JzW25hbWVdKCl9fWVsc2UgaWYoRVZFTlRTW25hbWVdPT09MSl7bmFtZT1cIm9uXCIrbmFtZTtQcm94eUhhbmRsZXIucHJvdG90eXBlW25hbWVdPWZ1bmN0aW9uKGEpe2lmKHRoaXMuX2Nic1tuYW1lXSl0aGlzLl9jYnNbbmFtZV0oYSl9fWVsc2UgaWYoRVZFTlRTW25hbWVdPT09Mil7bmFtZT1cIm9uXCIrbmFtZTtQcm94eUhhbmRsZXIucHJvdG90eXBlW25hbWVdPWZ1bmN0aW9uKGEsYil7aWYodGhpcy5fY2JzW25hbWVdKXRoaXMuX2Nic1tuYW1lXShhLGIpfX1lbHNle3Rocm93IEVycm9yKFwid3JvbmcgbnVtYmVyIG9mIGFyZ3VtZW50c1wiKX19KX0se1wiLi9cIjozNn1dLDMzOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXttb2R1bGUuZXhwb3J0cz1TdHJlYW07dmFyIFBhcnNlcj1yZXF1aXJlKFwiLi9Xcml0YWJsZVN0cmVhbS5qc1wiKTtmdW5jdGlvbiBTdHJlYW0ob3B0aW9ucyl7UGFyc2VyLmNhbGwodGhpcyxuZXcgQ2JzKHRoaXMpLG9wdGlvbnMpfXJlcXVpcmUoXCJpbmhlcml0c1wiKShTdHJlYW0sUGFyc2VyKTtTdHJlYW0ucHJvdG90eXBlLnJlYWRhYmxlPXRydWU7ZnVuY3Rpb24gQ2JzKHNjb3BlKXt0aGlzLnNjb3BlPXNjb3BlfXZhciBFVkVOVFM9cmVxdWlyZShcIi4uL1wiKS5FVkVOVFM7T2JqZWN0LmtleXMoRVZFTlRTKS5mb3JFYWNoKGZ1bmN0aW9uKG5hbWUpe2lmKEVWRU5UU1tuYW1lXT09PTApe0Nicy5wcm90b3R5cGVbXCJvblwiK25hbWVdPWZ1bmN0aW9uKCl7dGhpcy5zY29wZS5lbWl0KG5hbWUpfX1lbHNlIGlmKEVWRU5UU1tuYW1lXT09PTEpe0Nicy5wcm90b3R5cGVbXCJvblwiK25hbWVdPWZ1bmN0aW9uKGEpe3RoaXMuc2NvcGUuZW1pdChuYW1lLGEpfX1lbHNlIGlmKEVWRU5UU1tuYW1lXT09PTIpe0Nicy5wcm90b3R5cGVbXCJvblwiK25hbWVdPWZ1bmN0aW9uKGEsYil7dGhpcy5zY29wZS5lbWl0KG5hbWUsYSxiKX19ZWxzZXt0aHJvdyBFcnJvcihcIndyb25nIG51bWJlciBvZiBhcmd1bWVudHMhXCIpfX0pfSx7XCIuLi9cIjozNixcIi4vV3JpdGFibGVTdHJlYW0uanNcIjozNSxpbmhlcml0czozOH1dLDM0OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXttb2R1bGUuZXhwb3J0cz1Ub2tlbml6ZXI7dmFyIGRlY29kZUNvZGVQb2ludD1yZXF1aXJlKFwiZW50aXRpZXMvbGliL2RlY29kZV9jb2RlcG9pbnQuanNcIiksZW50aXR5TWFwPXJlcXVpcmUoXCJlbnRpdGllcy9tYXBzL2VudGl0aWVzLmpzb25cIiksbGVnYWN5TWFwPXJlcXVpcmUoXCJlbnRpdGllcy9tYXBzL2xlZ2FjeS5qc29uXCIpLHhtbE1hcD1yZXF1aXJlKFwiZW50aXRpZXMvbWFwcy94bWwuanNvblwiKSxpPTAsVEVYVD1pKyssQkVGT1JFX1RBR19OQU1FPWkrKyxJTl9UQUdfTkFNRT1pKyssSU5fU0VMRl9DTE9TSU5HX1RBRz1pKyssQkVGT1JFX0NMT1NJTkdfVEFHX05BTUU9aSsrLElOX0NMT1NJTkdfVEFHX05BTUU9aSsrLEFGVEVSX0NMT1NJTkdfVEFHX05BTUU9aSsrLEJFRk9SRV9BVFRSSUJVVEVfTkFNRT1pKyssSU5fQVRUUklCVVRFX05BTUU9aSsrLEFGVEVSX0FUVFJJQlVURV9OQU1FPWkrKyxCRUZPUkVfQVRUUklCVVRFX1ZBTFVFPWkrKyxJTl9BVFRSSUJVVEVfVkFMVUVfRFE9aSsrLElOX0FUVFJJQlVURV9WQUxVRV9TUT1pKyssSU5fQVRUUklCVVRFX1ZBTFVFX05RPWkrKyxCRUZPUkVfREVDTEFSQVRJT049aSsrLElOX0RFQ0xBUkFUSU9OPWkrKyxJTl9QUk9DRVNTSU5HX0lOU1RSVUNUSU9OPWkrKyxCRUZPUkVfQ09NTUVOVD1pKyssSU5fQ09NTUVOVD1pKyssQUZURVJfQ09NTUVOVF8xPWkrKyxBRlRFUl9DT01NRU5UXzI9aSsrLEJFRk9SRV9DREFUQV8xPWkrKyxCRUZPUkVfQ0RBVEFfMj1pKyssQkVGT1JFX0NEQVRBXzM9aSsrLEJFRk9SRV9DREFUQV80PWkrKyxCRUZPUkVfQ0RBVEFfNT1pKyssQkVGT1JFX0NEQVRBXzY9aSsrLElOX0NEQVRBPWkrKyxBRlRFUl9DREFUQV8xPWkrKyxBRlRFUl9DREFUQV8yPWkrKyxCRUZPUkVfU1BFQ0lBTD1pKyssQkVGT1JFX1NQRUNJQUxfRU5EPWkrKyxCRUZPUkVfU0NSSVBUXzE9aSsrLEJFRk9SRV9TQ1JJUFRfMj1pKyssQkVGT1JFX1NDUklQVF8zPWkrKyxCRUZPUkVfU0NSSVBUXzQ9aSsrLEJFRk9SRV9TQ1JJUFRfNT1pKyssQUZURVJfU0NSSVBUXzE9aSsrLEFGVEVSX1NDUklQVF8yPWkrKyxBRlRFUl9TQ1JJUFRfMz1pKyssQUZURVJfU0NSSVBUXzQ9aSsrLEFGVEVSX1NDUklQVF81PWkrKyxCRUZPUkVfU1RZTEVfMT1pKyssQkVGT1JFX1NUWUxFXzI9aSsrLEJFRk9SRV9TVFlMRV8zPWkrKyxCRUZPUkVfU1RZTEVfND1pKyssQUZURVJfU1RZTEVfMT1pKyssQUZURVJfU1RZTEVfMj1pKyssQUZURVJfU1RZTEVfMz1pKyssQUZURVJfU1RZTEVfND1pKyssQkVGT1JFX0VOVElUWT1pKyssQkVGT1JFX05VTUVSSUNfRU5USVRZPWkrKyxJTl9OQU1FRF9FTlRJVFk9aSsrLElOX05VTUVSSUNfRU5USVRZPWkrKyxJTl9IRVhfRU5USVRZPWkrKyxqPTAsU1BFQ0lBTF9OT05FPWorKyxTUEVDSUFMX1NDUklQVD1qKyssU1BFQ0lBTF9TVFlMRT1qKys7ZnVuY3Rpb24gd2hpdGVzcGFjZShjKXtyZXR1cm4gYz09PVwiIFwifHxjPT09XCJcXG5cInx8Yz09PVwiXFx0XCJ8fGM9PT1cIlxcZlwifHxjPT09XCJcXHJcIn1mdW5jdGlvbiBjaGFyYWN0ZXJTdGF0ZShjaGFyLFNVQ0NFU1Mpe3JldHVybiBmdW5jdGlvbihjKXtpZihjPT09Y2hhcil0aGlzLl9zdGF0ZT1TVUNDRVNTfX1mdW5jdGlvbiBpZkVsc2VTdGF0ZSh1cHBlcixTVUNDRVNTLEZBSUxVUkUpe3ZhciBsb3dlcj11cHBlci50b0xvd2VyQ2FzZSgpO2lmKHVwcGVyPT09bG93ZXIpe3JldHVybiBmdW5jdGlvbihjKXtpZihjPT09bG93ZXIpe3RoaXMuX3N0YXRlPVNVQ0NFU1N9ZWxzZXt0aGlzLl9zdGF0ZT1GQUlMVVJFO3RoaXMuX2luZGV4LS19fX1lbHNle3JldHVybiBmdW5jdGlvbihjKXtpZihjPT09bG93ZXJ8fGM9PT11cHBlcil7dGhpcy5fc3RhdGU9U1VDQ0VTU31lbHNle3RoaXMuX3N0YXRlPUZBSUxVUkU7dGhpcy5faW5kZXgtLX19fX1mdW5jdGlvbiBjb25zdW1lU3BlY2lhbE5hbWVDaGFyKHVwcGVyLE5FWFRfU1RBVEUpe3ZhciBsb3dlcj11cHBlci50b0xvd2VyQ2FzZSgpO3JldHVybiBmdW5jdGlvbihjKXtpZihjPT09bG93ZXJ8fGM9PT11cHBlcil7dGhpcy5fc3RhdGU9TkVYVF9TVEFURX1lbHNle3RoaXMuX3N0YXRlPUlOX1RBR19OQU1FO3RoaXMuX2luZGV4LS19fX1mdW5jdGlvbiBUb2tlbml6ZXIob3B0aW9ucyxjYnMpe3RoaXMuX3N0YXRlPVRFWFQ7dGhpcy5fYnVmZmVyPVwiXCI7dGhpcy5fc2VjdGlvblN0YXJ0PTA7dGhpcy5faW5kZXg9MDt0aGlzLl9idWZmZXJPZmZzZXQ9MDt0aGlzLl9iYXNlU3RhdGU9VEVYVDt0aGlzLl9zcGVjaWFsPVNQRUNJQUxfTk9ORTt0aGlzLl9jYnM9Y2JzO3RoaXMuX3J1bm5pbmc9dHJ1ZTt0aGlzLl9lbmRlZD1mYWxzZTt0aGlzLl94bWxNb2RlPSEhKG9wdGlvbnMmJm9wdGlvbnMueG1sTW9kZSk7dGhpcy5fZGVjb2RlRW50aXRpZXM9ISEob3B0aW9ucyYmb3B0aW9ucy5kZWNvZGVFbnRpdGllcyl9VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVUZXh0PWZ1bmN0aW9uKGMpe2lmKGM9PT1cIjxcIil7aWYodGhpcy5faW5kZXg+dGhpcy5fc2VjdGlvblN0YXJ0KXt0aGlzLl9jYnMub250ZXh0KHRoaXMuX2dldFNlY3Rpb24oKSl9dGhpcy5fc3RhdGU9QkVGT1JFX1RBR19OQU1FO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleH1lbHNlIGlmKHRoaXMuX2RlY29kZUVudGl0aWVzJiZ0aGlzLl9zcGVjaWFsPT09U1BFQ0lBTF9OT05FJiZjPT09XCImXCIpe2lmKHRoaXMuX2luZGV4PnRoaXMuX3NlY3Rpb25TdGFydCl7dGhpcy5fY2JzLm9udGV4dCh0aGlzLl9nZXRTZWN0aW9uKCkpfXRoaXMuX2Jhc2VTdGF0ZT1URVhUO3RoaXMuX3N0YXRlPUJFRk9SRV9FTlRJVFk7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4fX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVUYWdOYW1lPWZ1bmN0aW9uKGMpe2lmKGM9PT1cIi9cIil7dGhpcy5fc3RhdGU9QkVGT1JFX0NMT1NJTkdfVEFHX05BTUV9ZWxzZSBpZihjPT09XCI8XCIpe3RoaXMuX2Nicy5vbnRleHQodGhpcy5fZ2V0U2VjdGlvbigpKTt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXh9ZWxzZSBpZihjPT09XCI+XCJ8fHRoaXMuX3NwZWNpYWwhPT1TUEVDSUFMX05PTkV8fHdoaXRlc3BhY2UoYykpe3RoaXMuX3N0YXRlPVRFWFR9ZWxzZSBpZihjPT09XCIhXCIpe3RoaXMuX3N0YXRlPUJFRk9SRV9ERUNMQVJBVElPTjt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXgrMX1lbHNlIGlmKGM9PT1cIj9cIil7dGhpcy5fc3RhdGU9SU5fUFJPQ0VTU0lOR19JTlNUUlVDVElPTjt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXgrMX1lbHNle3RoaXMuX3N0YXRlPSF0aGlzLl94bWxNb2RlJiYoYz09PVwic1wifHxjPT09XCJTXCIpP0JFRk9SRV9TUEVDSUFMOklOX1RBR19OQU1FO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleH19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5UYWdOYW1lPWZ1bmN0aW9uKGMpe2lmKGM9PT1cIi9cInx8Yz09PVwiPlwifHx3aGl0ZXNwYWNlKGMpKXt0aGlzLl9lbWl0VG9rZW4oXCJvbm9wZW50YWduYW1lXCIpO3RoaXMuX3N0YXRlPUJFRk9SRV9BVFRSSUJVVEVfTkFNRTt0aGlzLl9pbmRleC0tfX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVDbG9zZWluZ1RhZ05hbWU9ZnVuY3Rpb24oYyl7aWYod2hpdGVzcGFjZShjKSk7ZWxzZSBpZihjPT09XCI+XCIpe3RoaXMuX3N0YXRlPVRFWFR9ZWxzZSBpZih0aGlzLl9zcGVjaWFsIT09U1BFQ0lBTF9OT05FKXtpZihjPT09XCJzXCJ8fGM9PT1cIlNcIil7dGhpcy5fc3RhdGU9QkVGT1JFX1NQRUNJQUxfRU5EfWVsc2V7dGhpcy5fc3RhdGU9VEVYVDt0aGlzLl9pbmRleC0tfX1lbHNle3RoaXMuX3N0YXRlPUlOX0NMT1NJTkdfVEFHX05BTUU7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4fX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJbkNsb3NlaW5nVGFnTmFtZT1mdW5jdGlvbihjKXtpZihjPT09XCI+XCJ8fHdoaXRlc3BhY2UoYykpe3RoaXMuX2VtaXRUb2tlbihcIm9uY2xvc2V0YWdcIik7dGhpcy5fc3RhdGU9QUZURVJfQ0xPU0lOR19UQUdfTkFNRTt0aGlzLl9pbmRleC0tfX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlckNsb3NlaW5nVGFnTmFtZT1mdW5jdGlvbihjKXtpZihjPT09XCI+XCIpe3RoaXMuX3N0YXRlPVRFWFQ7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4KzF9fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZUF0dHJpYnV0ZU5hbWU9ZnVuY3Rpb24oYyl7aWYoYz09PVwiPlwiKXt0aGlzLl9jYnMub25vcGVudGFnZW5kKCk7dGhpcy5fc3RhdGU9VEVYVDt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXgrMX1lbHNlIGlmKGM9PT1cIi9cIil7dGhpcy5fc3RhdGU9SU5fU0VMRl9DTE9TSU5HX1RBR31lbHNlIGlmKCF3aGl0ZXNwYWNlKGMpKXt0aGlzLl9zdGF0ZT1JTl9BVFRSSUJVVEVfTkFNRTt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXh9fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUluU2VsZkNsb3NpbmdUYWc9ZnVuY3Rpb24oYyl7aWYoYz09PVwiPlwiKXt0aGlzLl9jYnMub25zZWxmY2xvc2luZ3RhZygpO3RoaXMuX3N0YXRlPVRFWFQ7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4KzF9ZWxzZSBpZighd2hpdGVzcGFjZShjKSl7dGhpcy5fc3RhdGU9QkVGT1JFX0FUVFJJQlVURV9OQU1FO3RoaXMuX2luZGV4LS19fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUluQXR0cmlidXRlTmFtZT1mdW5jdGlvbihjKXtpZihjPT09XCI9XCJ8fGM9PT1cIi9cInx8Yz09PVwiPlwifHx3aGl0ZXNwYWNlKGMpKXt0aGlzLl9jYnMub25hdHRyaWJuYW1lKHRoaXMuX2dldFNlY3Rpb24oKSk7dGhpcy5fc2VjdGlvblN0YXJ0PS0xO3RoaXMuX3N0YXRlPUFGVEVSX0FUVFJJQlVURV9OQU1FO3RoaXMuX2luZGV4LS19fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUFmdGVyQXR0cmlidXRlTmFtZT1mdW5jdGlvbihjKXtpZihjPT09XCI9XCIpe3RoaXMuX3N0YXRlPUJFRk9SRV9BVFRSSUJVVEVfVkFMVUV9ZWxzZSBpZihjPT09XCIvXCJ8fGM9PT1cIj5cIil7dGhpcy5fY2JzLm9uYXR0cmliZW5kKCk7dGhpcy5fc3RhdGU9QkVGT1JFX0FUVFJJQlVURV9OQU1FO3RoaXMuX2luZGV4LS19ZWxzZSBpZighd2hpdGVzcGFjZShjKSl7dGhpcy5fY2JzLm9uYXR0cmliZW5kKCk7dGhpcy5fc3RhdGU9SU5fQVRUUklCVVRFX05BTUU7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4fX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVBdHRyaWJ1dGVWYWx1ZT1mdW5jdGlvbihjKXtpZihjPT09J1wiJyl7dGhpcy5fc3RhdGU9SU5fQVRUUklCVVRFX1ZBTFVFX0RRO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleCsxfWVsc2UgaWYoYz09PVwiJ1wiKXt0aGlzLl9zdGF0ZT1JTl9BVFRSSUJVVEVfVkFMVUVfU1E7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4KzF9ZWxzZSBpZighd2hpdGVzcGFjZShjKSl7dGhpcy5fc3RhdGU9SU5fQVRUUklCVVRFX1ZBTFVFX05RO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleDt0aGlzLl9pbmRleC0tfX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJbkF0dHJpYnV0ZVZhbHVlRG91YmxlUXVvdGVzPWZ1bmN0aW9uKGMpe2lmKGM9PT0nXCInKXt0aGlzLl9lbWl0VG9rZW4oXCJvbmF0dHJpYmRhdGFcIik7dGhpcy5fY2JzLm9uYXR0cmliZW5kKCk7dGhpcy5fc3RhdGU9QkVGT1JFX0FUVFJJQlVURV9OQU1FfWVsc2UgaWYodGhpcy5fZGVjb2RlRW50aXRpZXMmJmM9PT1cIiZcIil7dGhpcy5fZW1pdFRva2VuKFwib25hdHRyaWJkYXRhXCIpO3RoaXMuX2Jhc2VTdGF0ZT10aGlzLl9zdGF0ZTt0aGlzLl9zdGF0ZT1CRUZPUkVfRU5USVRZO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleH19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5BdHRyaWJ1dGVWYWx1ZVNpbmdsZVF1b3Rlcz1mdW5jdGlvbihjKXtpZihjPT09XCInXCIpe3RoaXMuX2VtaXRUb2tlbihcIm9uYXR0cmliZGF0YVwiKTt0aGlzLl9jYnMub25hdHRyaWJlbmQoKTt0aGlzLl9zdGF0ZT1CRUZPUkVfQVRUUklCVVRFX05BTUV9ZWxzZSBpZih0aGlzLl9kZWNvZGVFbnRpdGllcyYmYz09PVwiJlwiKXt0aGlzLl9lbWl0VG9rZW4oXCJvbmF0dHJpYmRhdGFcIik7dGhpcy5fYmFzZVN0YXRlPXRoaXMuX3N0YXRlO3RoaXMuX3N0YXRlPUJFRk9SRV9FTlRJVFk7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4fX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJbkF0dHJpYnV0ZVZhbHVlTm9RdW90ZXM9ZnVuY3Rpb24oYyl7aWYod2hpdGVzcGFjZShjKXx8Yz09PVwiPlwiKXt0aGlzLl9lbWl0VG9rZW4oXCJvbmF0dHJpYmRhdGFcIik7dGhpcy5fY2JzLm9uYXR0cmliZW5kKCk7dGhpcy5fc3RhdGU9QkVGT1JFX0FUVFJJQlVURV9OQU1FO3RoaXMuX2luZGV4LS19ZWxzZSBpZih0aGlzLl9kZWNvZGVFbnRpdGllcyYmYz09PVwiJlwiKXt0aGlzLl9lbWl0VG9rZW4oXCJvbmF0dHJpYmRhdGFcIik7dGhpcy5fYmFzZVN0YXRlPXRoaXMuX3N0YXRlO3RoaXMuX3N0YXRlPUJFRk9SRV9FTlRJVFk7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4fX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVEZWNsYXJhdGlvbj1mdW5jdGlvbihjKXt0aGlzLl9zdGF0ZT1jPT09XCJbXCI/QkVGT1JFX0NEQVRBXzE6Yz09PVwiLVwiP0JFRk9SRV9DT01NRU5UOklOX0RFQ0xBUkFUSU9OfTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUluRGVjbGFyYXRpb249ZnVuY3Rpb24oYyl7aWYoYz09PVwiPlwiKXt0aGlzLl9jYnMub25kZWNsYXJhdGlvbih0aGlzLl9nZXRTZWN0aW9uKCkpO3RoaXMuX3N0YXRlPVRFWFQ7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4KzF9fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUluUHJvY2Vzc2luZ0luc3RydWN0aW9uPWZ1bmN0aW9uKGMpe2lmKGM9PT1cIj5cIil7dGhpcy5fY2JzLm9ucHJvY2Vzc2luZ2luc3RydWN0aW9uKHRoaXMuX2dldFNlY3Rpb24oKSk7dGhpcy5fc3RhdGU9VEVYVDt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXgrMX19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlQ29tbWVudD1mdW5jdGlvbihjKXtpZihjPT09XCItXCIpe3RoaXMuX3N0YXRlPUlOX0NPTU1FTlQ7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4KzF9ZWxzZXt0aGlzLl9zdGF0ZT1JTl9ERUNMQVJBVElPTn19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5Db21tZW50PWZ1bmN0aW9uKGMpe2lmKGM9PT1cIi1cIil0aGlzLl9zdGF0ZT1BRlRFUl9DT01NRU5UXzF9O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJDb21tZW50MT1mdW5jdGlvbihjKXtpZihjPT09XCItXCIpe3RoaXMuX3N0YXRlPUFGVEVSX0NPTU1FTlRfMn1lbHNle3RoaXMuX3N0YXRlPUlOX0NPTU1FTlR9fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUFmdGVyQ29tbWVudDI9ZnVuY3Rpb24oYyl7aWYoYz09PVwiPlwiKXt0aGlzLl9jYnMub25jb21tZW50KHRoaXMuX2J1ZmZlci5zdWJzdHJpbmcodGhpcy5fc2VjdGlvblN0YXJ0LHRoaXMuX2luZGV4LTIpKTt0aGlzLl9zdGF0ZT1URVhUO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleCsxfWVsc2UgaWYoYyE9PVwiLVwiKXt0aGlzLl9zdGF0ZT1JTl9DT01NRU5UfX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVDZGF0YTE9aWZFbHNlU3RhdGUoXCJDXCIsQkVGT1JFX0NEQVRBXzIsSU5fREVDTEFSQVRJT04pO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlQ2RhdGEyPWlmRWxzZVN0YXRlKFwiRFwiLEJFRk9SRV9DREFUQV8zLElOX0RFQ0xBUkFUSU9OKTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZUNkYXRhMz1pZkVsc2VTdGF0ZShcIkFcIixCRUZPUkVfQ0RBVEFfNCxJTl9ERUNMQVJBVElPTik7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVDZGF0YTQ9aWZFbHNlU3RhdGUoXCJUXCIsQkVGT1JFX0NEQVRBXzUsSU5fREVDTEFSQVRJT04pO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlQ2RhdGE1PWlmRWxzZVN0YXRlKFwiQVwiLEJFRk9SRV9DREFUQV82LElOX0RFQ0xBUkFUSU9OKTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZUNkYXRhNj1mdW5jdGlvbihjKXtpZihjPT09XCJbXCIpe3RoaXMuX3N0YXRlPUlOX0NEQVRBO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleCsxfWVsc2V7dGhpcy5fc3RhdGU9SU5fREVDTEFSQVRJT047dGhpcy5faW5kZXgtLX19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5DZGF0YT1mdW5jdGlvbihjKXtpZihjPT09XCJdXCIpdGhpcy5fc3RhdGU9QUZURVJfQ0RBVEFfMX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlckNkYXRhMT1jaGFyYWN0ZXJTdGF0ZShcIl1cIixBRlRFUl9DREFUQV8yKTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUFmdGVyQ2RhdGEyPWZ1bmN0aW9uKGMpe2lmKGM9PT1cIj5cIil7dGhpcy5fY2JzLm9uY2RhdGEodGhpcy5fYnVmZmVyLnN1YnN0cmluZyh0aGlzLl9zZWN0aW9uU3RhcnQsdGhpcy5faW5kZXgtMikpO3RoaXMuX3N0YXRlPVRFWFQ7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4KzF9ZWxzZSBpZihjIT09XCJdXCIpe3RoaXMuX3N0YXRlPUlOX0NEQVRBfX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTcGVjaWFsPWZ1bmN0aW9uKGMpe2lmKGM9PT1cImNcInx8Yz09PVwiQ1wiKXt0aGlzLl9zdGF0ZT1CRUZPUkVfU0NSSVBUXzF9ZWxzZSBpZihjPT09XCJ0XCJ8fGM9PT1cIlRcIil7dGhpcy5fc3RhdGU9QkVGT1JFX1NUWUxFXzF9ZWxzZXt0aGlzLl9zdGF0ZT1JTl9UQUdfTkFNRTt0aGlzLl9pbmRleC0tfX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTcGVjaWFsRW5kPWZ1bmN0aW9uKGMpe2lmKHRoaXMuX3NwZWNpYWw9PT1TUEVDSUFMX1NDUklQVCYmKGM9PT1cImNcInx8Yz09PVwiQ1wiKSl7dGhpcy5fc3RhdGU9QUZURVJfU0NSSVBUXzF9ZWxzZSBpZih0aGlzLl9zcGVjaWFsPT09U1BFQ0lBTF9TVFlMRSYmKGM9PT1cInRcInx8Yz09PVwiVFwiKSl7dGhpcy5fc3RhdGU9QUZURVJfU1RZTEVfMX1lbHNlIHRoaXMuX3N0YXRlPVRFWFR9O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlU2NyaXB0MT1jb25zdW1lU3BlY2lhbE5hbWVDaGFyKFwiUlwiLEJFRk9SRV9TQ1JJUFRfMik7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTY3JpcHQyPWNvbnN1bWVTcGVjaWFsTmFtZUNoYXIoXCJJXCIsQkVGT1JFX1NDUklQVF8zKTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZVNjcmlwdDM9Y29uc3VtZVNwZWNpYWxOYW1lQ2hhcihcIlBcIixCRUZPUkVfU0NSSVBUXzQpO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlU2NyaXB0ND1jb25zdW1lU3BlY2lhbE5hbWVDaGFyKFwiVFwiLEJFRk9SRV9TQ1JJUFRfNSk7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTY3JpcHQ1PWZ1bmN0aW9uKGMpe2lmKGM9PT1cIi9cInx8Yz09PVwiPlwifHx3aGl0ZXNwYWNlKGMpKXt0aGlzLl9zcGVjaWFsPVNQRUNJQUxfU0NSSVBUfXRoaXMuX3N0YXRlPUlOX1RBR19OQU1FO3RoaXMuX2luZGV4LS19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTY3JpcHQxPWlmRWxzZVN0YXRlKFwiUlwiLEFGVEVSX1NDUklQVF8yLFRFWFQpO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTY3JpcHQyPWlmRWxzZVN0YXRlKFwiSVwiLEFGVEVSX1NDUklQVF8zLFRFWFQpO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTY3JpcHQzPWlmRWxzZVN0YXRlKFwiUFwiLEFGVEVSX1NDUklQVF80LFRFWFQpO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTY3JpcHQ0PWlmRWxzZVN0YXRlKFwiVFwiLEFGVEVSX1NDUklQVF81LFRFWFQpO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTY3JpcHQ1PWZ1bmN0aW9uKGMpe2lmKGM9PT1cIj5cInx8d2hpdGVzcGFjZShjKSl7dGhpcy5fc3BlY2lhbD1TUEVDSUFMX05PTkU7dGhpcy5fc3RhdGU9SU5fQ0xPU0lOR19UQUdfTkFNRTt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXgtNjt0aGlzLl9pbmRleC0tfWVsc2UgdGhpcy5fc3RhdGU9VEVYVH07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTdHlsZTE9Y29uc3VtZVNwZWNpYWxOYW1lQ2hhcihcIllcIixCRUZPUkVfU1RZTEVfMik7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTdHlsZTI9Y29uc3VtZVNwZWNpYWxOYW1lQ2hhcihcIkxcIixCRUZPUkVfU1RZTEVfMyk7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTdHlsZTM9Y29uc3VtZVNwZWNpYWxOYW1lQ2hhcihcIkVcIixCRUZPUkVfU1RZTEVfNCk7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTdHlsZTQ9ZnVuY3Rpb24oYyl7aWYoYz09PVwiL1wifHxjPT09XCI+XCJ8fHdoaXRlc3BhY2UoYykpe3RoaXMuX3NwZWNpYWw9U1BFQ0lBTF9TVFlMRX10aGlzLl9zdGF0ZT1JTl9UQUdfTkFNRTt0aGlzLl9pbmRleC0tfTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUFmdGVyU3R5bGUxPWlmRWxzZVN0YXRlKFwiWVwiLEFGVEVSX1NUWUxFXzIsVEVYVCk7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlclN0eWxlMj1pZkVsc2VTdGF0ZShcIkxcIixBRlRFUl9TVFlMRV8zLFRFWFQpO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTdHlsZTM9aWZFbHNlU3RhdGUoXCJFXCIsQUZURVJfU1RZTEVfNCxURVhUKTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUFmdGVyU3R5bGU0PWZ1bmN0aW9uKGMpe2lmKGM9PT1cIj5cInx8d2hpdGVzcGFjZShjKSl7dGhpcy5fc3BlY2lhbD1TUEVDSUFMX05PTkU7dGhpcy5fc3RhdGU9SU5fQ0xPU0lOR19UQUdfTkFNRTt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXgtNTt0aGlzLl9pbmRleC0tfWVsc2UgdGhpcy5fc3RhdGU9VEVYVH07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVFbnRpdHk9aWZFbHNlU3RhdGUoXCIjXCIsQkVGT1JFX05VTUVSSUNfRU5USVRZLElOX05BTUVEX0VOVElUWSk7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVOdW1lcmljRW50aXR5PWlmRWxzZVN0YXRlKFwiWFwiLElOX0hFWF9FTlRJVFksSU5fTlVNRVJJQ19FTlRJVFkpO1Rva2VuaXplci5wcm90b3R5cGUuX3BhcnNlTmFtZWRFbnRpdHlTdHJpY3Q9ZnVuY3Rpb24oKXtpZih0aGlzLl9zZWN0aW9uU3RhcnQrMTx0aGlzLl9pbmRleCl7dmFyIGVudGl0eT10aGlzLl9idWZmZXIuc3Vic3RyaW5nKHRoaXMuX3NlY3Rpb25TdGFydCsxLHRoaXMuX2luZGV4KSxtYXA9dGhpcy5feG1sTW9kZT94bWxNYXA6ZW50aXR5TWFwO2lmKG1hcC5oYXNPd25Qcm9wZXJ0eShlbnRpdHkpKXt0aGlzLl9lbWl0UGFydGlhbChtYXBbZW50aXR5XSk7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4KzF9fX07VG9rZW5pemVyLnByb3RvdHlwZS5fcGFyc2VMZWdhY3lFbnRpdHk9ZnVuY3Rpb24oKXt2YXIgc3RhcnQ9dGhpcy5fc2VjdGlvblN0YXJ0KzEsbGltaXQ9dGhpcy5faW5kZXgtc3RhcnQ7aWYobGltaXQ+NilsaW1pdD02O3doaWxlKGxpbWl0Pj0yKXt2YXIgZW50aXR5PXRoaXMuX2J1ZmZlci5zdWJzdHIoc3RhcnQsbGltaXQpO2lmKGxlZ2FjeU1hcC5oYXNPd25Qcm9wZXJ0eShlbnRpdHkpKXt0aGlzLl9lbWl0UGFydGlhbChsZWdhY3lNYXBbZW50aXR5XSk7dGhpcy5fc2VjdGlvblN0YXJ0Kz1saW1pdCsxO3JldHVybn1lbHNle2xpbWl0LS19fX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJbk5hbWVkRW50aXR5PWZ1bmN0aW9uKGMpe2lmKGM9PT1cIjtcIil7dGhpcy5fcGFyc2VOYW1lZEVudGl0eVN0cmljdCgpO2lmKHRoaXMuX3NlY3Rpb25TdGFydCsxPHRoaXMuX2luZGV4JiYhdGhpcy5feG1sTW9kZSl7dGhpcy5fcGFyc2VMZWdhY3lFbnRpdHkoKX10aGlzLl9zdGF0ZT10aGlzLl9iYXNlU3RhdGV9ZWxzZSBpZigoYzxcImFcInx8Yz5cInpcIikmJihjPFwiQVwifHxjPlwiWlwiKSYmKGM8XCIwXCJ8fGM+XCI5XCIpKXtpZih0aGlzLl94bWxNb2RlKTtlbHNlIGlmKHRoaXMuX3NlY3Rpb25TdGFydCsxPT09dGhpcy5faW5kZXgpO2Vsc2UgaWYodGhpcy5fYmFzZVN0YXRlIT09VEVYVCl7aWYoYyE9PVwiPVwiKXt0aGlzLl9wYXJzZU5hbWVkRW50aXR5U3RyaWN0KCl9fWVsc2V7dGhpcy5fcGFyc2VMZWdhY3lFbnRpdHkoKX10aGlzLl9zdGF0ZT10aGlzLl9iYXNlU3RhdGU7dGhpcy5faW5kZXgtLX19O1Rva2VuaXplci5wcm90b3R5cGUuX2RlY29kZU51bWVyaWNFbnRpdHk9ZnVuY3Rpb24ob2Zmc2V0LGJhc2Upe3ZhciBzZWN0aW9uU3RhcnQ9dGhpcy5fc2VjdGlvblN0YXJ0K29mZnNldDtpZihzZWN0aW9uU3RhcnQhPT10aGlzLl9pbmRleCl7dmFyIGVudGl0eT10aGlzLl9idWZmZXIuc3Vic3RyaW5nKHNlY3Rpb25TdGFydCx0aGlzLl9pbmRleCk7dmFyIHBhcnNlZD1wYXJzZUludChlbnRpdHksYmFzZSk7dGhpcy5fZW1pdFBhcnRpYWwoZGVjb2RlQ29kZVBvaW50KHBhcnNlZCkpO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleH1lbHNle3RoaXMuX3NlY3Rpb25TdGFydC0tfXRoaXMuX3N0YXRlPXRoaXMuX2Jhc2VTdGF0ZX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJbk51bWVyaWNFbnRpdHk9ZnVuY3Rpb24oYyl7aWYoYz09PVwiO1wiKXt0aGlzLl9kZWNvZGVOdW1lcmljRW50aXR5KDIsMTApO3RoaXMuX3NlY3Rpb25TdGFydCsrfWVsc2UgaWYoYzxcIjBcInx8Yz5cIjlcIil7aWYoIXRoaXMuX3htbE1vZGUpe3RoaXMuX2RlY29kZU51bWVyaWNFbnRpdHkoMiwxMCl9ZWxzZXt0aGlzLl9zdGF0ZT10aGlzLl9iYXNlU3RhdGV9dGhpcy5faW5kZXgtLX19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5IZXhFbnRpdHk9ZnVuY3Rpb24oYyl7aWYoYz09PVwiO1wiKXt0aGlzLl9kZWNvZGVOdW1lcmljRW50aXR5KDMsMTYpO3RoaXMuX3NlY3Rpb25TdGFydCsrfWVsc2UgaWYoKGM8XCJhXCJ8fGM+XCJmXCIpJiYoYzxcIkFcInx8Yz5cIkZcIikmJihjPFwiMFwifHxjPlwiOVwiKSl7aWYoIXRoaXMuX3htbE1vZGUpe3RoaXMuX2RlY29kZU51bWVyaWNFbnRpdHkoMywxNil9ZWxzZXt0aGlzLl9zdGF0ZT10aGlzLl9iYXNlU3RhdGV9dGhpcy5faW5kZXgtLX19O1Rva2VuaXplci5wcm90b3R5cGUuX2NsZWFudXA9ZnVuY3Rpb24oKXtpZih0aGlzLl9zZWN0aW9uU3RhcnQ8MCl7dGhpcy5fYnVmZmVyPVwiXCI7dGhpcy5faW5kZXg9MDt0aGlzLl9idWZmZXJPZmZzZXQrPXRoaXMuX2luZGV4fWVsc2UgaWYodGhpcy5fcnVubmluZyl7aWYodGhpcy5fc3RhdGU9PT1URVhUKXtpZih0aGlzLl9zZWN0aW9uU3RhcnQhPT10aGlzLl9pbmRleCl7dGhpcy5fY2JzLm9udGV4dCh0aGlzLl9idWZmZXIuc3Vic3RyKHRoaXMuX3NlY3Rpb25TdGFydCkpfXRoaXMuX2J1ZmZlcj1cIlwiO3RoaXMuX2J1ZmZlck9mZnNldCs9dGhpcy5faW5kZXg7dGhpcy5faW5kZXg9MH1lbHNlIGlmKHRoaXMuX3NlY3Rpb25TdGFydD09PXRoaXMuX2luZGV4KXt0aGlzLl9idWZmZXI9XCJcIjt0aGlzLl9idWZmZXJPZmZzZXQrPXRoaXMuX2luZGV4O3RoaXMuX2luZGV4PTB9ZWxzZXt0aGlzLl9idWZmZXI9dGhpcy5fYnVmZmVyLnN1YnN0cih0aGlzLl9zZWN0aW9uU3RhcnQpO3RoaXMuX2luZGV4LT10aGlzLl9zZWN0aW9uU3RhcnQ7dGhpcy5fYnVmZmVyT2Zmc2V0Kz10aGlzLl9zZWN0aW9uU3RhcnR9dGhpcy5fc2VjdGlvblN0YXJ0PTB9fTtUb2tlbml6ZXIucHJvdG90eXBlLndyaXRlPWZ1bmN0aW9uKGNodW5rKXtpZih0aGlzLl9lbmRlZCl0aGlzLl9jYnMub25lcnJvcihFcnJvcihcIi53cml0ZSgpIGFmdGVyIGRvbmUhXCIpKTt0aGlzLl9idWZmZXIrPWNodW5rO3RoaXMuX3BhcnNlKCl9O1Rva2VuaXplci5wcm90b3R5cGUuX3BhcnNlPWZ1bmN0aW9uKCl7d2hpbGUodGhpcy5faW5kZXg8dGhpcy5fYnVmZmVyLmxlbmd0aCYmdGhpcy5fcnVubmluZyl7dmFyIGM9dGhpcy5fYnVmZmVyLmNoYXJBdCh0aGlzLl9pbmRleCk7aWYodGhpcy5fc3RhdGU9PT1URVhUKXt0aGlzLl9zdGF0ZVRleHQoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9UQUdfTkFNRSl7dGhpcy5fc3RhdGVCZWZvcmVUYWdOYW1lKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9UQUdfTkFNRSl7dGhpcy5fc3RhdGVJblRhZ05hbWUoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9DTE9TSU5HX1RBR19OQU1FKXt0aGlzLl9zdGF0ZUJlZm9yZUNsb3NlaW5nVGFnTmFtZShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09SU5fQ0xPU0lOR19UQUdfTkFNRSl7dGhpcy5fc3RhdGVJbkNsb3NlaW5nVGFnTmFtZShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QUZURVJfQ0xPU0lOR19UQUdfTkFNRSl7dGhpcy5fc3RhdGVBZnRlckNsb3NlaW5nVGFnTmFtZShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09SU5fU0VMRl9DTE9TSU5HX1RBRyl7dGhpcy5fc3RhdGVJblNlbGZDbG9zaW5nVGFnKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfQVRUUklCVVRFX05BTUUpe3RoaXMuX3N0YXRlQmVmb3JlQXR0cmlidXRlTmFtZShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09SU5fQVRUUklCVVRFX05BTUUpe3RoaXMuX3N0YXRlSW5BdHRyaWJ1dGVOYW1lKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9BVFRSSUJVVEVfTkFNRSl7dGhpcy5fc3RhdGVBZnRlckF0dHJpYnV0ZU5hbWUoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9BVFRSSUJVVEVfVkFMVUUpe3RoaXMuX3N0YXRlQmVmb3JlQXR0cmlidXRlVmFsdWUoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX0FUVFJJQlVURV9WQUxVRV9EUSl7dGhpcy5fc3RhdGVJbkF0dHJpYnV0ZVZhbHVlRG91YmxlUXVvdGVzKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9BVFRSSUJVVEVfVkFMVUVfU1Epe3RoaXMuX3N0YXRlSW5BdHRyaWJ1dGVWYWx1ZVNpbmdsZVF1b3RlcyhjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09SU5fQVRUUklCVVRFX1ZBTFVFX05RKXt0aGlzLl9zdGF0ZUluQXR0cmlidXRlVmFsdWVOb1F1b3RlcyhjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX0RFQ0xBUkFUSU9OKXt0aGlzLl9zdGF0ZUJlZm9yZURlY2xhcmF0aW9uKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9ERUNMQVJBVElPTil7dGhpcy5fc3RhdGVJbkRlY2xhcmF0aW9uKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9QUk9DRVNTSU5HX0lOU1RSVUNUSU9OKXt0aGlzLl9zdGF0ZUluUHJvY2Vzc2luZ0luc3RydWN0aW9uKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfQ09NTUVOVCl7dGhpcy5fc3RhdGVCZWZvcmVDb21tZW50KGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9DT01NRU5UKXt0aGlzLl9zdGF0ZUluQ29tbWVudChjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QUZURVJfQ09NTUVOVF8xKXt0aGlzLl9zdGF0ZUFmdGVyQ29tbWVudDEoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUFGVEVSX0NPTU1FTlRfMil7dGhpcy5fc3RhdGVBZnRlckNvbW1lbnQyKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfQ0RBVEFfMSl7dGhpcy5fc3RhdGVCZWZvcmVDZGF0YTEoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9DREFUQV8yKXt0aGlzLl9zdGF0ZUJlZm9yZUNkYXRhMihjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX0NEQVRBXzMpe3RoaXMuX3N0YXRlQmVmb3JlQ2RhdGEzKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfQ0RBVEFfNCl7dGhpcy5fc3RhdGVCZWZvcmVDZGF0YTQoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9DREFUQV81KXt0aGlzLl9zdGF0ZUJlZm9yZUNkYXRhNShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX0NEQVRBXzYpe3RoaXMuX3N0YXRlQmVmb3JlQ2RhdGE2KGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9DREFUQSl7dGhpcy5fc3RhdGVJbkNkYXRhKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9DREFUQV8xKXt0aGlzLl9zdGF0ZUFmdGVyQ2RhdGExKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9DREFUQV8yKXt0aGlzLl9zdGF0ZUFmdGVyQ2RhdGEyKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfU1BFQ0lBTCl7dGhpcy5fc3RhdGVCZWZvcmVTcGVjaWFsKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfU1BFQ0lBTF9FTkQpe3RoaXMuX3N0YXRlQmVmb3JlU3BlY2lhbEVuZChjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX1NDUklQVF8xKXt0aGlzLl9zdGF0ZUJlZm9yZVNjcmlwdDEoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9TQ1JJUFRfMil7dGhpcy5fc3RhdGVCZWZvcmVTY3JpcHQyKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfU0NSSVBUXzMpe3RoaXMuX3N0YXRlQmVmb3JlU2NyaXB0MyhjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX1NDUklQVF80KXt0aGlzLl9zdGF0ZUJlZm9yZVNjcmlwdDQoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9TQ1JJUFRfNSl7dGhpcy5fc3RhdGVCZWZvcmVTY3JpcHQ1KGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9TQ1JJUFRfMSl7dGhpcy5fc3RhdGVBZnRlclNjcmlwdDEoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUFGVEVSX1NDUklQVF8yKXt0aGlzLl9zdGF0ZUFmdGVyU2NyaXB0MihjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QUZURVJfU0NSSVBUXzMpe3RoaXMuX3N0YXRlQWZ0ZXJTY3JpcHQzKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9TQ1JJUFRfNCl7dGhpcy5fc3RhdGVBZnRlclNjcmlwdDQoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUFGVEVSX1NDUklQVF81KXt0aGlzLl9zdGF0ZUFmdGVyU2NyaXB0NShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX1NUWUxFXzEpe3RoaXMuX3N0YXRlQmVmb3JlU3R5bGUxKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfU1RZTEVfMil7dGhpcy5fc3RhdGVCZWZvcmVTdHlsZTIoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9TVFlMRV8zKXt0aGlzLl9zdGF0ZUJlZm9yZVN0eWxlMyhjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX1NUWUxFXzQpe3RoaXMuX3N0YXRlQmVmb3JlU3R5bGU0KGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9TVFlMRV8xKXt0aGlzLl9zdGF0ZUFmdGVyU3R5bGUxKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9TVFlMRV8yKXt0aGlzLl9zdGF0ZUFmdGVyU3R5bGUyKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9TVFlMRV8zKXt0aGlzLl9zdGF0ZUFmdGVyU3R5bGUzKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9TVFlMRV80KXt0aGlzLl9zdGF0ZUFmdGVyU3R5bGU0KGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfRU5USVRZKXt0aGlzLl9zdGF0ZUJlZm9yZUVudGl0eShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX05VTUVSSUNfRU5USVRZKXt0aGlzLl9zdGF0ZUJlZm9yZU51bWVyaWNFbnRpdHkoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX05BTUVEX0VOVElUWSl7dGhpcy5fc3RhdGVJbk5hbWVkRW50aXR5KGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9OVU1FUklDX0VOVElUWSl7dGhpcy5fc3RhdGVJbk51bWVyaWNFbnRpdHkoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX0hFWF9FTlRJVFkpe3RoaXMuX3N0YXRlSW5IZXhFbnRpdHkoYyl9ZWxzZXt0aGlzLl9jYnMub25lcnJvcihFcnJvcihcInVua25vd24gX3N0YXRlXCIpLHRoaXMuX3N0YXRlKX10aGlzLl9pbmRleCsrfXRoaXMuX2NsZWFudXAoKX07VG9rZW5pemVyLnByb3RvdHlwZS5wYXVzZT1mdW5jdGlvbigpe3RoaXMuX3J1bm5pbmc9ZmFsc2V9O1Rva2VuaXplci5wcm90b3R5cGUucmVzdW1lPWZ1bmN0aW9uKCl7dGhpcy5fcnVubmluZz10cnVlO2lmKHRoaXMuX2luZGV4PHRoaXMuX2J1ZmZlci5sZW5ndGgpe3RoaXMuX3BhcnNlKCl9aWYodGhpcy5fZW5kZWQpe3RoaXMuX2ZpbmlzaCgpfX07VG9rZW5pemVyLnByb3RvdHlwZS5lbmQ9ZnVuY3Rpb24oY2h1bmspe2lmKHRoaXMuX2VuZGVkKXRoaXMuX2Nicy5vbmVycm9yKEVycm9yKFwiLmVuZCgpIGFmdGVyIGRvbmUhXCIpKTtpZihjaHVuayl0aGlzLndyaXRlKGNodW5rKTt0aGlzLl9lbmRlZD10cnVlO2lmKHRoaXMuX3J1bm5pbmcpdGhpcy5fZmluaXNoKCl9O1Rva2VuaXplci5wcm90b3R5cGUuX2ZpbmlzaD1mdW5jdGlvbigpe2lmKHRoaXMuX3NlY3Rpb25TdGFydDx0aGlzLl9pbmRleCl7dGhpcy5faGFuZGxlVHJhaWxpbmdEYXRhKCl9dGhpcy5fY2JzLm9uZW5kKCl9O1Rva2VuaXplci5wcm90b3R5cGUuX2hhbmRsZVRyYWlsaW5nRGF0YT1mdW5jdGlvbigpe3ZhciBkYXRhPXRoaXMuX2J1ZmZlci5zdWJzdHIodGhpcy5fc2VjdGlvblN0YXJ0KTtpZih0aGlzLl9zdGF0ZT09PUlOX0NEQVRBfHx0aGlzLl9zdGF0ZT09PUFGVEVSX0NEQVRBXzF8fHRoaXMuX3N0YXRlPT09QUZURVJfQ0RBVEFfMil7dGhpcy5fY2JzLm9uY2RhdGEoZGF0YSl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX0NPTU1FTlR8fHRoaXMuX3N0YXRlPT09QUZURVJfQ09NTUVOVF8xfHx0aGlzLl9zdGF0ZT09PUFGVEVSX0NPTU1FTlRfMil7dGhpcy5fY2JzLm9uY29tbWVudChkYXRhKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09SU5fTkFNRURfRU5USVRZJiYhdGhpcy5feG1sTW9kZSl7dGhpcy5fcGFyc2VMZWdhY3lFbnRpdHkoKTtpZih0aGlzLl9zZWN0aW9uU3RhcnQ8dGhpcy5faW5kZXgpe3RoaXMuX3N0YXRlPXRoaXMuX2Jhc2VTdGF0ZTt0aGlzLl9oYW5kbGVUcmFpbGluZ0RhdGEoKX19ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX05VTUVSSUNfRU5USVRZJiYhdGhpcy5feG1sTW9kZSl7dGhpcy5fZGVjb2RlTnVtZXJpY0VudGl0eSgyLDEwKTtpZih0aGlzLl9zZWN0aW9uU3RhcnQ8dGhpcy5faW5kZXgpe3RoaXMuX3N0YXRlPXRoaXMuX2Jhc2VTdGF0ZTt0aGlzLl9oYW5kbGVUcmFpbGluZ0RhdGEoKX19ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX0hFWF9FTlRJVFkmJiF0aGlzLl94bWxNb2RlKXt0aGlzLl9kZWNvZGVOdW1lcmljRW50aXR5KDMsMTYpO2lmKHRoaXMuX3NlY3Rpb25TdGFydDx0aGlzLl9pbmRleCl7dGhpcy5fc3RhdGU9dGhpcy5fYmFzZVN0YXRlO3RoaXMuX2hhbmRsZVRyYWlsaW5nRGF0YSgpfX1lbHNlIGlmKHRoaXMuX3N0YXRlIT09SU5fVEFHX05BTUUmJnRoaXMuX3N0YXRlIT09QkVGT1JFX0FUVFJJQlVURV9OQU1FJiZ0aGlzLl9zdGF0ZSE9PUJFRk9SRV9BVFRSSUJVVEVfVkFMVUUmJnRoaXMuX3N0YXRlIT09QUZURVJfQVRUUklCVVRFX05BTUUmJnRoaXMuX3N0YXRlIT09SU5fQVRUUklCVVRFX05BTUUmJnRoaXMuX3N0YXRlIT09SU5fQVRUUklCVVRFX1ZBTFVFX1NRJiZ0aGlzLl9zdGF0ZSE9PUlOX0FUVFJJQlVURV9WQUxVRV9EUSYmdGhpcy5fc3RhdGUhPT1JTl9BVFRSSUJVVEVfVkFMVUVfTlEmJnRoaXMuX3N0YXRlIT09SU5fQ0xPU0lOR19UQUdfTkFNRSl7XG50aGlzLl9jYnMub250ZXh0KGRhdGEpfX07VG9rZW5pemVyLnByb3RvdHlwZS5yZXNldD1mdW5jdGlvbigpe1Rva2VuaXplci5jYWxsKHRoaXMse3htbE1vZGU6dGhpcy5feG1sTW9kZSxkZWNvZGVFbnRpdGllczp0aGlzLl9kZWNvZGVFbnRpdGllc30sdGhpcy5fY2JzKX07VG9rZW5pemVyLnByb3RvdHlwZS5nZXRBYnNvbHV0ZUluZGV4PWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuX2J1ZmZlck9mZnNldCt0aGlzLl9pbmRleH07VG9rZW5pemVyLnByb3RvdHlwZS5fZ2V0U2VjdGlvbj1mdW5jdGlvbigpe3JldHVybiB0aGlzLl9idWZmZXIuc3Vic3RyaW5nKHRoaXMuX3NlY3Rpb25TdGFydCx0aGlzLl9pbmRleCl9O1Rva2VuaXplci5wcm90b3R5cGUuX2VtaXRUb2tlbj1mdW5jdGlvbihuYW1lKXt0aGlzLl9jYnNbbmFtZV0odGhpcy5fZ2V0U2VjdGlvbigpKTt0aGlzLl9zZWN0aW9uU3RhcnQ9LTF9O1Rva2VuaXplci5wcm90b3R5cGUuX2VtaXRQYXJ0aWFsPWZ1bmN0aW9uKHZhbHVlKXtpZih0aGlzLl9iYXNlU3RhdGUhPT1URVhUKXt0aGlzLl9jYnMub25hdHRyaWJkYXRhKHZhbHVlKX1lbHNle3RoaXMuX2Nicy5vbnRleHQodmFsdWUpfX19LHtcImVudGl0aWVzL2xpYi9kZWNvZGVfY29kZXBvaW50LmpzXCI6MjIsXCJlbnRpdGllcy9tYXBzL2VudGl0aWVzLmpzb25cIjoyNSxcImVudGl0aWVzL21hcHMvbGVnYWN5Lmpzb25cIjoyNixcImVudGl0aWVzL21hcHMveG1sLmpzb25cIjoyN31dLDM1OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXttb2R1bGUuZXhwb3J0cz1TdHJlYW07dmFyIFBhcnNlcj1yZXF1aXJlKFwiLi9QYXJzZXIuanNcIiksV3JpdGFibGVTdHJlYW09cmVxdWlyZShcInN0cmVhbVwiKS5Xcml0YWJsZXx8cmVxdWlyZShcInJlYWRhYmxlLXN0cmVhbVwiKS5Xcml0YWJsZSxTdHJpbmdEZWNvZGVyPXJlcXVpcmUoXCJzdHJpbmdfZGVjb2RlclwiKS5TdHJpbmdEZWNvZGVyLEJ1ZmZlcj1yZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcjtmdW5jdGlvbiBTdHJlYW0oY2JzLG9wdGlvbnMpe3ZhciBwYXJzZXI9dGhpcy5fcGFyc2VyPW5ldyBQYXJzZXIoY2JzLG9wdGlvbnMpO3ZhciBkZWNvZGVyPXRoaXMuX2RlY29kZXI9bmV3IFN0cmluZ0RlY29kZXI7V3JpdGFibGVTdHJlYW0uY2FsbCh0aGlzLHtkZWNvZGVTdHJpbmdzOmZhbHNlfSk7dGhpcy5vbmNlKFwiZmluaXNoXCIsZnVuY3Rpb24oKXtwYXJzZXIuZW5kKGRlY29kZXIuZW5kKCkpfSl9cmVxdWlyZShcImluaGVyaXRzXCIpKFN0cmVhbSxXcml0YWJsZVN0cmVhbSk7V3JpdGFibGVTdHJlYW0ucHJvdG90eXBlLl93cml0ZT1mdW5jdGlvbihjaHVuayxlbmNvZGluZyxjYil7aWYoY2h1bmsgaW5zdGFuY2VvZiBCdWZmZXIpY2h1bms9dGhpcy5fZGVjb2Rlci53cml0ZShjaHVuayk7dGhpcy5fcGFyc2VyLndyaXRlKGNodW5rKTtjYigpfX0se1wiLi9QYXJzZXIuanNcIjozMSxidWZmZXI6NSxpbmhlcml0czozOCxcInJlYWRhYmxlLXN0cmVhbVwiOjMsc3RyZWFtOjU1LHN0cmluZ19kZWNvZGVyOjU2fV0sMzY6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciBQYXJzZXI9cmVxdWlyZShcIi4vUGFyc2VyLmpzXCIpLERvbUhhbmRsZXI9cmVxdWlyZShcImRvbWhhbmRsZXJcIik7ZnVuY3Rpb24gZGVmaW5lUHJvcChuYW1lLHZhbHVlKXtkZWxldGUgbW9kdWxlLmV4cG9ydHNbbmFtZV07bW9kdWxlLmV4cG9ydHNbbmFtZV09dmFsdWU7cmV0dXJuIHZhbHVlfW1vZHVsZS5leHBvcnRzPXtQYXJzZXI6UGFyc2VyLFRva2VuaXplcjpyZXF1aXJlKFwiLi9Ub2tlbml6ZXIuanNcIiksRWxlbWVudFR5cGU6cmVxdWlyZShcImRvbWVsZW1lbnR0eXBlXCIpLERvbUhhbmRsZXI6RG9tSGFuZGxlcixnZXQgRmVlZEhhbmRsZXIoKXtyZXR1cm4gZGVmaW5lUHJvcChcIkZlZWRIYW5kbGVyXCIscmVxdWlyZShcIi4vRmVlZEhhbmRsZXIuanNcIikpfSxnZXQgU3RyZWFtKCl7cmV0dXJuIGRlZmluZVByb3AoXCJTdHJlYW1cIixyZXF1aXJlKFwiLi9TdHJlYW0uanNcIikpfSxnZXQgV3JpdGFibGVTdHJlYW0oKXtyZXR1cm4gZGVmaW5lUHJvcChcIldyaXRhYmxlU3RyZWFtXCIscmVxdWlyZShcIi4vV3JpdGFibGVTdHJlYW0uanNcIikpfSxnZXQgUHJveHlIYW5kbGVyKCl7cmV0dXJuIGRlZmluZVByb3AoXCJQcm94eUhhbmRsZXJcIixyZXF1aXJlKFwiLi9Qcm94eUhhbmRsZXIuanNcIikpfSxnZXQgRG9tVXRpbHMoKXtyZXR1cm4gZGVmaW5lUHJvcChcIkRvbVV0aWxzXCIscmVxdWlyZShcImRvbXV0aWxzXCIpKX0sZ2V0IENvbGxlY3RpbmdIYW5kbGVyKCl7cmV0dXJuIGRlZmluZVByb3AoXCJDb2xsZWN0aW5nSGFuZGxlclwiLHJlcXVpcmUoXCIuL0NvbGxlY3RpbmdIYW5kbGVyLmpzXCIpKX0sRGVmYXVsdEhhbmRsZXI6RG9tSGFuZGxlcixnZXQgUnNzSGFuZGxlcigpe3JldHVybiBkZWZpbmVQcm9wKFwiUnNzSGFuZGxlclwiLHRoaXMuRmVlZEhhbmRsZXIpfSxwYXJzZURPTTpmdW5jdGlvbihkYXRhLG9wdGlvbnMpe3ZhciBoYW5kbGVyPW5ldyBEb21IYW5kbGVyKG9wdGlvbnMpO25ldyBQYXJzZXIoaGFuZGxlcixvcHRpb25zKS5lbmQoZGF0YSk7cmV0dXJuIGhhbmRsZXIuZG9tfSxwYXJzZUZlZWQ6ZnVuY3Rpb24oZmVlZCxvcHRpb25zKXt2YXIgaGFuZGxlcj1uZXcgbW9kdWxlLmV4cG9ydHMuRmVlZEhhbmRsZXIob3B0aW9ucyk7bmV3IFBhcnNlcihoYW5kbGVyLG9wdGlvbnMpLmVuZChmZWVkKTtyZXR1cm4gaGFuZGxlci5kb219LGNyZWF0ZURvbVN0cmVhbTpmdW5jdGlvbihjYixvcHRpb25zLGVsZW1lbnRDYil7dmFyIGhhbmRsZXI9bmV3IERvbUhhbmRsZXIoY2Isb3B0aW9ucyxlbGVtZW50Q2IpO3JldHVybiBuZXcgUGFyc2VyKGhhbmRsZXIsb3B0aW9ucyl9LEVWRU5UUzp7YXR0cmlidXRlOjIsY2RhdGFzdGFydDowLGNkYXRhZW5kOjAsdGV4dDoxLHByb2Nlc3NpbmdpbnN0cnVjdGlvbjoyLGNvbW1lbnQ6MSxjb21tZW50ZW5kOjAsY2xvc2V0YWc6MSxvcGVudGFnOjIsb3BlbnRhZ25hbWU6MSxlcnJvcjoxLGVuZDowfX19LHtcIi4vQ29sbGVjdGluZ0hhbmRsZXIuanNcIjoyOSxcIi4vRmVlZEhhbmRsZXIuanNcIjozMCxcIi4vUGFyc2VyLmpzXCI6MzEsXCIuL1Byb3h5SGFuZGxlci5qc1wiOjMyLFwiLi9TdHJlYW0uanNcIjozMyxcIi4vVG9rZW5pemVyLmpzXCI6MzQsXCIuL1dyaXRhYmxlU3RyZWFtLmpzXCI6MzUsZG9tZWxlbWVudHR5cGU6OSxkb21oYW5kbGVyOjEwLGRvbXV0aWxzOjEzfV0sMzc6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe2V4cG9ydHMucmVhZD1mdW5jdGlvbihidWZmZXIsb2Zmc2V0LGlzTEUsbUxlbixuQnl0ZXMpe3ZhciBlLG07dmFyIGVMZW49bkJ5dGVzKjgtbUxlbi0xO3ZhciBlTWF4PSgxPDxlTGVuKS0xO3ZhciBlQmlhcz1lTWF4Pj4xO3ZhciBuQml0cz0tNzt2YXIgaT1pc0xFP25CeXRlcy0xOjA7dmFyIGQ9aXNMRT8tMToxO3ZhciBzPWJ1ZmZlcltvZmZzZXQraV07aSs9ZDtlPXMmKDE8PC1uQml0cyktMTtzPj49LW5CaXRzO25CaXRzKz1lTGVuO2Zvcig7bkJpdHM+MDtlPWUqMjU2K2J1ZmZlcltvZmZzZXQraV0saSs9ZCxuQml0cy09OCl7fW09ZSYoMTw8LW5CaXRzKS0xO2U+Pj0tbkJpdHM7bkJpdHMrPW1MZW47Zm9yKDtuQml0cz4wO209bSoyNTYrYnVmZmVyW29mZnNldCtpXSxpKz1kLG5CaXRzLT04KXt9aWYoZT09PTApe2U9MS1lQmlhc31lbHNlIGlmKGU9PT1lTWF4KXtyZXR1cm4gbT9OYU46KHM/LTE6MSkqSW5maW5pdHl9ZWxzZXttPW0rTWF0aC5wb3coMixtTGVuKTtlPWUtZUJpYXN9cmV0dXJuKHM/LTE6MSkqbSpNYXRoLnBvdygyLGUtbUxlbil9O2V4cG9ydHMud3JpdGU9ZnVuY3Rpb24oYnVmZmVyLHZhbHVlLG9mZnNldCxpc0xFLG1MZW4sbkJ5dGVzKXt2YXIgZSxtLGM7dmFyIGVMZW49bkJ5dGVzKjgtbUxlbi0xO3ZhciBlTWF4PSgxPDxlTGVuKS0xO3ZhciBlQmlhcz1lTWF4Pj4xO3ZhciBydD1tTGVuPT09MjM/TWF0aC5wb3coMiwtMjQpLU1hdGgucG93KDIsLTc3KTowO3ZhciBpPWlzTEU/MDpuQnl0ZXMtMTt2YXIgZD1pc0xFPzE6LTE7dmFyIHM9dmFsdWU8MHx8dmFsdWU9PT0wJiYxL3ZhbHVlPDA/MTowO3ZhbHVlPU1hdGguYWJzKHZhbHVlKTtpZihpc05hTih2YWx1ZSl8fHZhbHVlPT09SW5maW5pdHkpe209aXNOYU4odmFsdWUpPzE6MDtlPWVNYXh9ZWxzZXtlPU1hdGguZmxvb3IoTWF0aC5sb2codmFsdWUpL01hdGguTE4yKTtpZih2YWx1ZSooYz1NYXRoLnBvdygyLC1lKSk8MSl7ZS0tO2MqPTJ9aWYoZStlQmlhcz49MSl7dmFsdWUrPXJ0L2N9ZWxzZXt2YWx1ZSs9cnQqTWF0aC5wb3coMiwxLWVCaWFzKX1pZih2YWx1ZSpjPj0yKXtlKys7Yy89Mn1pZihlK2VCaWFzPj1lTWF4KXttPTA7ZT1lTWF4fWVsc2UgaWYoZStlQmlhcz49MSl7bT0odmFsdWUqYy0xKSpNYXRoLnBvdygyLG1MZW4pO2U9ZStlQmlhc31lbHNle209dmFsdWUqTWF0aC5wb3coMixlQmlhcy0xKSpNYXRoLnBvdygyLG1MZW4pO2U9MH19Zm9yKDttTGVuPj04O2J1ZmZlcltvZmZzZXQraV09bSYyNTUsaSs9ZCxtLz0yNTYsbUxlbi09OCl7fWU9ZTw8bUxlbnxtO2VMZW4rPW1MZW47Zm9yKDtlTGVuPjA7YnVmZmVyW29mZnNldCtpXT1lJjI1NSxpKz1kLGUvPTI1NixlTGVuLT04KXt9YnVmZmVyW29mZnNldCtpLWRdfD1zKjEyOH19LHt9XSwzODpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7aWYodHlwZW9mIE9iamVjdC5jcmVhdGU9PT1cImZ1bmN0aW9uXCIpe21vZHVsZS5leHBvcnRzPWZ1bmN0aW9uIGluaGVyaXRzKGN0b3Isc3VwZXJDdG9yKXtjdG9yLnN1cGVyXz1zdXBlckN0b3I7Y3Rvci5wcm90b3R5cGU9T2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLHtjb25zdHJ1Y3Rvcjp7dmFsdWU6Y3RvcixlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRydWV9fSl9fWVsc2V7bW9kdWxlLmV4cG9ydHM9ZnVuY3Rpb24gaW5oZXJpdHMoY3RvcixzdXBlckN0b3Ipe2N0b3Iuc3VwZXJfPXN1cGVyQ3Rvcjt2YXIgVGVtcEN0b3I9ZnVuY3Rpb24oKXt9O1RlbXBDdG9yLnByb3RvdHlwZT1zdXBlckN0b3IucHJvdG90eXBlO2N0b3IucHJvdG90eXBlPW5ldyBUZW1wQ3RvcjtjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3Rvcj1jdG9yfX19LHt9XSwzOTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9ZnVuY3Rpb24ob2JqKXtyZXR1cm4gb2JqIT1udWxsJiYoaXNCdWZmZXIob2JqKXx8aXNTbG93QnVmZmVyKG9iail8fCEhb2JqLl9pc0J1ZmZlcil9O2Z1bmN0aW9uIGlzQnVmZmVyKG9iail7cmV0dXJuISFvYmouY29uc3RydWN0b3ImJnR5cGVvZiBvYmouY29uc3RydWN0b3IuaXNCdWZmZXI9PT1cImZ1bmN0aW9uXCImJm9iai5jb25zdHJ1Y3Rvci5pc0J1ZmZlcihvYmopfWZ1bmN0aW9uIGlzU2xvd0J1ZmZlcihvYmope3JldHVybiB0eXBlb2Ygb2JqLnJlYWRGbG9hdExFPT09XCJmdW5jdGlvblwiJiZ0eXBlb2Ygb2JqLnNsaWNlPT09XCJmdW5jdGlvblwiJiZpc0J1ZmZlcihvYmouc2xpY2UoMCwwKSl9fSx7fV0sNDA6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciB0b1N0cmluZz17fS50b1N0cmluZzttb2R1bGUuZXhwb3J0cz1BcnJheS5pc0FycmF5fHxmdW5jdGlvbihhcnIpe3JldHVybiB0b1N0cmluZy5jYWxsKGFycik9PVwiW29iamVjdCBBcnJheV1cIn19LHt9XSw0MTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7KGZ1bmN0aW9uKHByb2Nlc3Mpe1widXNlIHN0cmljdFwiO2lmKCFwcm9jZXNzLnZlcnNpb258fHByb2Nlc3MudmVyc2lvbi5pbmRleE9mKFwidjAuXCIpPT09MHx8cHJvY2Vzcy52ZXJzaW9uLmluZGV4T2YoXCJ2MS5cIik9PT0wJiZwcm9jZXNzLnZlcnNpb24uaW5kZXhPZihcInYxLjguXCIpIT09MCl7bW9kdWxlLmV4cG9ydHM9bmV4dFRpY2t9ZWxzZXttb2R1bGUuZXhwb3J0cz1wcm9jZXNzLm5leHRUaWNrfWZ1bmN0aW9uIG5leHRUaWNrKGZuLGFyZzEsYXJnMixhcmczKXtpZih0eXBlb2YgZm4hPT1cImZ1bmN0aW9uXCIpe3Rocm93IG5ldyBUeXBlRXJyb3IoJ1wiY2FsbGJhY2tcIiBhcmd1bWVudCBtdXN0IGJlIGEgZnVuY3Rpb24nKX12YXIgbGVuPWFyZ3VtZW50cy5sZW5ndGg7dmFyIGFyZ3MsaTtzd2l0Y2gobGVuKXtjYXNlIDA6Y2FzZSAxOnJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZuKTtjYXNlIDI6cmV0dXJuIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gYWZ0ZXJUaWNrT25lKCl7Zm4uY2FsbChudWxsLGFyZzEpfSk7Y2FzZSAzOnJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uIGFmdGVyVGlja1R3bygpe2ZuLmNhbGwobnVsbCxhcmcxLGFyZzIpfSk7Y2FzZSA0OnJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uIGFmdGVyVGlja1RocmVlKCl7Zm4uY2FsbChudWxsLGFyZzEsYXJnMixhcmczKX0pO2RlZmF1bHQ6YXJncz1uZXcgQXJyYXkobGVuLTEpO2k9MDt3aGlsZShpPGFyZ3MubGVuZ3RoKXthcmdzW2krK109YXJndW1lbnRzW2ldfXJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uIGFmdGVyVGljaygpe2ZuLmFwcGx5KG51bGwsYXJncyl9KX19fSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJfcHJvY2Vzc1wiKSl9LHtfcHJvY2Vzczo0Mn1dLDQyOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgcHJvY2Vzcz1tb2R1bGUuZXhwb3J0cz17fTt2YXIgY2FjaGVkU2V0VGltZW91dDt2YXIgY2FjaGVkQ2xlYXJUaW1lb3V0O2Z1bmN0aW9uIGRlZmF1bHRTZXRUaW1vdXQoKXt0aHJvdyBuZXcgRXJyb3IoXCJzZXRUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkXCIpfWZ1bmN0aW9uIGRlZmF1bHRDbGVhclRpbWVvdXQoKXt0aHJvdyBuZXcgRXJyb3IoXCJjbGVhclRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWRcIil9KGZ1bmN0aW9uKCl7dHJ5e2lmKHR5cGVvZiBzZXRUaW1lb3V0PT09XCJmdW5jdGlvblwiKXtjYWNoZWRTZXRUaW1lb3V0PXNldFRpbWVvdXR9ZWxzZXtjYWNoZWRTZXRUaW1lb3V0PWRlZmF1bHRTZXRUaW1vdXR9fWNhdGNoKGUpe2NhY2hlZFNldFRpbWVvdXQ9ZGVmYXVsdFNldFRpbW91dH10cnl7aWYodHlwZW9mIGNsZWFyVGltZW91dD09PVwiZnVuY3Rpb25cIil7Y2FjaGVkQ2xlYXJUaW1lb3V0PWNsZWFyVGltZW91dH1lbHNle2NhY2hlZENsZWFyVGltZW91dD1kZWZhdWx0Q2xlYXJUaW1lb3V0fX1jYXRjaChlKXtjYWNoZWRDbGVhclRpbWVvdXQ9ZGVmYXVsdENsZWFyVGltZW91dH19KSgpO2Z1bmN0aW9uIHJ1blRpbWVvdXQoZnVuKXtpZihjYWNoZWRTZXRUaW1lb3V0PT09c2V0VGltZW91dCl7cmV0dXJuIHNldFRpbWVvdXQoZnVuLDApfWlmKChjYWNoZWRTZXRUaW1lb3V0PT09ZGVmYXVsdFNldFRpbW91dHx8IWNhY2hlZFNldFRpbWVvdXQpJiZzZXRUaW1lb3V0KXtjYWNoZWRTZXRUaW1lb3V0PXNldFRpbWVvdXQ7cmV0dXJuIHNldFRpbWVvdXQoZnVuLDApfXRyeXtyZXR1cm4gY2FjaGVkU2V0VGltZW91dChmdW4sMCl9Y2F0Y2goZSl7dHJ5e3JldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwobnVsbCxmdW4sMCl9Y2F0Y2goZSl7cmV0dXJuIGNhY2hlZFNldFRpbWVvdXQuY2FsbCh0aGlzLGZ1biwwKX19fWZ1bmN0aW9uIHJ1bkNsZWFyVGltZW91dChtYXJrZXIpe2lmKGNhY2hlZENsZWFyVGltZW91dD09PWNsZWFyVGltZW91dCl7cmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpfWlmKChjYWNoZWRDbGVhclRpbWVvdXQ9PT1kZWZhdWx0Q2xlYXJUaW1lb3V0fHwhY2FjaGVkQ2xlYXJUaW1lb3V0KSYmY2xlYXJUaW1lb3V0KXtjYWNoZWRDbGVhclRpbWVvdXQ9Y2xlYXJUaW1lb3V0O3JldHVybiBjbGVhclRpbWVvdXQobWFya2VyKX10cnl7cmV0dXJuIGNhY2hlZENsZWFyVGltZW91dChtYXJrZXIpfWNhdGNoKGUpe3RyeXtyZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0LmNhbGwobnVsbCxtYXJrZXIpfWNhdGNoKGUpe3JldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbCh0aGlzLG1hcmtlcil9fX12YXIgcXVldWU9W107dmFyIGRyYWluaW5nPWZhbHNlO3ZhciBjdXJyZW50UXVldWU7dmFyIHF1ZXVlSW5kZXg9LTE7ZnVuY3Rpb24gY2xlYW5VcE5leHRUaWNrKCl7aWYoIWRyYWluaW5nfHwhY3VycmVudFF1ZXVlKXtyZXR1cm59ZHJhaW5pbmc9ZmFsc2U7aWYoY3VycmVudFF1ZXVlLmxlbmd0aCl7cXVldWU9Y3VycmVudFF1ZXVlLmNvbmNhdChxdWV1ZSl9ZWxzZXtxdWV1ZUluZGV4PS0xfWlmKHF1ZXVlLmxlbmd0aCl7ZHJhaW5RdWV1ZSgpfX1mdW5jdGlvbiBkcmFpblF1ZXVlKCl7aWYoZHJhaW5pbmcpe3JldHVybn12YXIgdGltZW91dD1ydW5UaW1lb3V0KGNsZWFuVXBOZXh0VGljayk7ZHJhaW5pbmc9dHJ1ZTt2YXIgbGVuPXF1ZXVlLmxlbmd0aDt3aGlsZShsZW4pe2N1cnJlbnRRdWV1ZT1xdWV1ZTtxdWV1ZT1bXTt3aGlsZSgrK3F1ZXVlSW5kZXg8bGVuKXtpZihjdXJyZW50UXVldWUpe2N1cnJlbnRRdWV1ZVtxdWV1ZUluZGV4XS5ydW4oKX19cXVldWVJbmRleD0tMTtsZW49cXVldWUubGVuZ3RofWN1cnJlbnRRdWV1ZT1udWxsO2RyYWluaW5nPWZhbHNlO3J1bkNsZWFyVGltZW91dCh0aW1lb3V0KX1wcm9jZXNzLm5leHRUaWNrPWZ1bmN0aW9uKGZ1bil7dmFyIGFyZ3M9bmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGgtMSk7aWYoYXJndW1lbnRzLmxlbmd0aD4xKXtmb3IodmFyIGk9MTtpPGFyZ3VtZW50cy5sZW5ndGg7aSsrKXthcmdzW2ktMV09YXJndW1lbnRzW2ldfX1xdWV1ZS5wdXNoKG5ldyBJdGVtKGZ1bixhcmdzKSk7aWYocXVldWUubGVuZ3RoPT09MSYmIWRyYWluaW5nKXtydW5UaW1lb3V0KGRyYWluUXVldWUpfX07ZnVuY3Rpb24gSXRlbShmdW4sYXJyYXkpe3RoaXMuZnVuPWZ1bjt0aGlzLmFycmF5PWFycmF5fUl0ZW0ucHJvdG90eXBlLnJ1bj1mdW5jdGlvbigpe3RoaXMuZnVuLmFwcGx5KG51bGwsdGhpcy5hcnJheSl9O3Byb2Nlc3MudGl0bGU9XCJicm93c2VyXCI7cHJvY2Vzcy5icm93c2VyPXRydWU7cHJvY2Vzcy5lbnY9e307cHJvY2Vzcy5hcmd2PVtdO3Byb2Nlc3MudmVyc2lvbj1cIlwiO3Byb2Nlc3MudmVyc2lvbnM9e307ZnVuY3Rpb24gbm9vcCgpe31wcm9jZXNzLm9uPW5vb3A7cHJvY2Vzcy5hZGRMaXN0ZW5lcj1ub29wO3Byb2Nlc3Mub25jZT1ub29wO3Byb2Nlc3Mub2ZmPW5vb3A7cHJvY2Vzcy5yZW1vdmVMaXN0ZW5lcj1ub29wO3Byb2Nlc3MucmVtb3ZlQWxsTGlzdGVuZXJzPW5vb3A7cHJvY2Vzcy5lbWl0PW5vb3A7cHJvY2Vzcy5iaW5kaW5nPWZ1bmN0aW9uKG5hbWUpe3Rocm93IG5ldyBFcnJvcihcInByb2Nlc3MuYmluZGluZyBpcyBub3Qgc3VwcG9ydGVkXCIpfTtwcm9jZXNzLmN3ZD1mdW5jdGlvbigpe3JldHVyblwiL1wifTtwcm9jZXNzLmNoZGlyPWZ1bmN0aW9uKGRpcil7dGhyb3cgbmV3IEVycm9yKFwicHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkXCIpfTtwcm9jZXNzLnVtYXNrPWZ1bmN0aW9uKCl7cmV0dXJuIDB9fSx7fV0sNDM6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe21vZHVsZS5leHBvcnRzPXJlcXVpcmUoXCIuL2xpYi9fc3RyZWFtX2R1cGxleC5qc1wiKX0se1wiLi9saWIvX3N0cmVhbV9kdXBsZXguanNcIjo0NH1dLDQ0OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcInVzZSBzdHJpY3RcIjt2YXIgb2JqZWN0S2V5cz1PYmplY3Qua2V5c3x8ZnVuY3Rpb24ob2JqKXt2YXIga2V5cz1bXTtmb3IodmFyIGtleSBpbiBvYmope2tleXMucHVzaChrZXkpfXJldHVybiBrZXlzfTttb2R1bGUuZXhwb3J0cz1EdXBsZXg7dmFyIHByb2Nlc3NOZXh0VGljaz1yZXF1aXJlKFwicHJvY2Vzcy1uZXh0aWNrLWFyZ3NcIik7dmFyIHV0aWw9cmVxdWlyZShcImNvcmUtdXRpbC1pc1wiKTt1dGlsLmluaGVyaXRzPXJlcXVpcmUoXCJpbmhlcml0c1wiKTt2YXIgUmVhZGFibGU9cmVxdWlyZShcIi4vX3N0cmVhbV9yZWFkYWJsZVwiKTt2YXIgV3JpdGFibGU9cmVxdWlyZShcIi4vX3N0cmVhbV93cml0YWJsZVwiKTt1dGlsLmluaGVyaXRzKER1cGxleCxSZWFkYWJsZSk7dmFyIGtleXM9b2JqZWN0S2V5cyhXcml0YWJsZS5wcm90b3R5cGUpO2Zvcih2YXIgdj0wO3Y8a2V5cy5sZW5ndGg7disrKXt2YXIgbWV0aG9kPWtleXNbdl07aWYoIUR1cGxleC5wcm90b3R5cGVbbWV0aG9kXSlEdXBsZXgucHJvdG90eXBlW21ldGhvZF09V3JpdGFibGUucHJvdG90eXBlW21ldGhvZF19ZnVuY3Rpb24gRHVwbGV4KG9wdGlvbnMpe2lmKCEodGhpcyBpbnN0YW5jZW9mIER1cGxleCkpcmV0dXJuIG5ldyBEdXBsZXgob3B0aW9ucyk7UmVhZGFibGUuY2FsbCh0aGlzLG9wdGlvbnMpO1dyaXRhYmxlLmNhbGwodGhpcyxvcHRpb25zKTtpZihvcHRpb25zJiZvcHRpb25zLnJlYWRhYmxlPT09ZmFsc2UpdGhpcy5yZWFkYWJsZT1mYWxzZTtpZihvcHRpb25zJiZvcHRpb25zLndyaXRhYmxlPT09ZmFsc2UpdGhpcy53cml0YWJsZT1mYWxzZTt0aGlzLmFsbG93SGFsZk9wZW49dHJ1ZTtpZihvcHRpb25zJiZvcHRpb25zLmFsbG93SGFsZk9wZW49PT1mYWxzZSl0aGlzLmFsbG93SGFsZk9wZW49ZmFsc2U7dGhpcy5vbmNlKFwiZW5kXCIsb25lbmQpfWZ1bmN0aW9uIG9uZW5kKCl7aWYodGhpcy5hbGxvd0hhbGZPcGVufHx0aGlzLl93cml0YWJsZVN0YXRlLmVuZGVkKXJldHVybjtwcm9jZXNzTmV4dFRpY2sob25FbmROVCx0aGlzKX1mdW5jdGlvbiBvbkVuZE5UKHNlbGYpe3NlbGYuZW5kKCl9ZnVuY3Rpb24gZm9yRWFjaCh4cyxmKXtmb3IodmFyIGk9MCxsPXhzLmxlbmd0aDtpPGw7aSsrKXtmKHhzW2ldLGkpfX19LHtcIi4vX3N0cmVhbV9yZWFkYWJsZVwiOjQ2LFwiLi9fc3RyZWFtX3dyaXRhYmxlXCI6NDgsXCJjb3JlLXV0aWwtaXNcIjo2LGluaGVyaXRzOjM4LFwicHJvY2Vzcy1uZXh0aWNrLWFyZ3NcIjo0MX1dLDQ1OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcInVzZSBzdHJpY3RcIjttb2R1bGUuZXhwb3J0cz1QYXNzVGhyb3VnaDt2YXIgVHJhbnNmb3JtPXJlcXVpcmUoXCIuL19zdHJlYW1fdHJhbnNmb3JtXCIpO3ZhciB1dGlsPXJlcXVpcmUoXCJjb3JlLXV0aWwtaXNcIik7dXRpbC5pbmhlcml0cz1yZXF1aXJlKFwiaW5oZXJpdHNcIik7dXRpbC5pbmhlcml0cyhQYXNzVGhyb3VnaCxUcmFuc2Zvcm0pO2Z1bmN0aW9uIFBhc3NUaHJvdWdoKG9wdGlvbnMpe2lmKCEodGhpcyBpbnN0YW5jZW9mIFBhc3NUaHJvdWdoKSlyZXR1cm4gbmV3IFBhc3NUaHJvdWdoKG9wdGlvbnMpO1RyYW5zZm9ybS5jYWxsKHRoaXMsb3B0aW9ucyl9UGFzc1Rocm91Z2gucHJvdG90eXBlLl90cmFuc2Zvcm09ZnVuY3Rpb24oY2h1bmssZW5jb2RpbmcsY2Ipe2NiKG51bGwsY2h1bmspfX0se1wiLi9fc3RyZWFtX3RyYW5zZm9ybVwiOjQ3LFwiY29yZS11dGlsLWlzXCI6Nixpbmhlcml0czozOH1dLDQ2OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsoZnVuY3Rpb24ocHJvY2Vzcyl7XCJ1c2Ugc3RyaWN0XCI7bW9kdWxlLmV4cG9ydHM9UmVhZGFibGU7dmFyIHByb2Nlc3NOZXh0VGljaz1yZXF1aXJlKFwicHJvY2Vzcy1uZXh0aWNrLWFyZ3NcIik7dmFyIGlzQXJyYXk9cmVxdWlyZShcImlzYXJyYXlcIik7UmVhZGFibGUuUmVhZGFibGVTdGF0ZT1SZWFkYWJsZVN0YXRlO3ZhciBFRT1yZXF1aXJlKFwiZXZlbnRzXCIpLkV2ZW50RW1pdHRlcjt2YXIgRUVsaXN0ZW5lckNvdW50PWZ1bmN0aW9uKGVtaXR0ZXIsdHlwZSl7cmV0dXJuIGVtaXR0ZXIubGlzdGVuZXJzKHR5cGUpLmxlbmd0aH07dmFyIFN0cmVhbTsoZnVuY3Rpb24oKXt0cnl7U3RyZWFtPXJlcXVpcmUoXCJzdFwiK1wicmVhbVwiKX1jYXRjaChfKXt9ZmluYWxseXtpZighU3RyZWFtKVN0cmVhbT1yZXF1aXJlKFwiZXZlbnRzXCIpLkV2ZW50RW1pdHRlcn19KSgpO3ZhciBCdWZmZXI9cmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXI7dmFyIGJ1ZmZlclNoaW09cmVxdWlyZShcImJ1ZmZlci1zaGltc1wiKTt2YXIgdXRpbD1yZXF1aXJlKFwiY29yZS11dGlsLWlzXCIpO3V0aWwuaW5oZXJpdHM9cmVxdWlyZShcImluaGVyaXRzXCIpO3ZhciBkZWJ1Z1V0aWw9cmVxdWlyZShcInV0aWxcIik7dmFyIGRlYnVnPXZvaWQgMDtpZihkZWJ1Z1V0aWwmJmRlYnVnVXRpbC5kZWJ1Z2xvZyl7ZGVidWc9ZGVidWdVdGlsLmRlYnVnbG9nKFwic3RyZWFtXCIpfWVsc2V7ZGVidWc9ZnVuY3Rpb24oKXt9fXZhciBCdWZmZXJMaXN0PXJlcXVpcmUoXCIuL2ludGVybmFsL3N0cmVhbXMvQnVmZmVyTGlzdFwiKTt2YXIgU3RyaW5nRGVjb2Rlcjt1dGlsLmluaGVyaXRzKFJlYWRhYmxlLFN0cmVhbSk7ZnVuY3Rpb24gcHJlcGVuZExpc3RlbmVyKGVtaXR0ZXIsZXZlbnQsZm4pe2lmKHR5cGVvZiBlbWl0dGVyLnByZXBlbmRMaXN0ZW5lcj09PVwiZnVuY3Rpb25cIil7cmV0dXJuIGVtaXR0ZXIucHJlcGVuZExpc3RlbmVyKGV2ZW50LGZuKX1lbHNle2lmKCFlbWl0dGVyLl9ldmVudHN8fCFlbWl0dGVyLl9ldmVudHNbZXZlbnRdKWVtaXR0ZXIub24oZXZlbnQsZm4pO2Vsc2UgaWYoaXNBcnJheShlbWl0dGVyLl9ldmVudHNbZXZlbnRdKSllbWl0dGVyLl9ldmVudHNbZXZlbnRdLnVuc2hpZnQoZm4pO2Vsc2UgZW1pdHRlci5fZXZlbnRzW2V2ZW50XT1bZm4sZW1pdHRlci5fZXZlbnRzW2V2ZW50XV19fXZhciBEdXBsZXg7ZnVuY3Rpb24gUmVhZGFibGVTdGF0ZShvcHRpb25zLHN0cmVhbSl7RHVwbGV4PUR1cGxleHx8cmVxdWlyZShcIi4vX3N0cmVhbV9kdXBsZXhcIik7b3B0aW9ucz1vcHRpb25zfHx7fTt0aGlzLm9iamVjdE1vZGU9ISFvcHRpb25zLm9iamVjdE1vZGU7aWYoc3RyZWFtIGluc3RhbmNlb2YgRHVwbGV4KXRoaXMub2JqZWN0TW9kZT10aGlzLm9iamVjdE1vZGV8fCEhb3B0aW9ucy5yZWFkYWJsZU9iamVjdE1vZGU7dmFyIGh3bT1vcHRpb25zLmhpZ2hXYXRlck1hcms7dmFyIGRlZmF1bHRId209dGhpcy5vYmplY3RNb2RlPzE2OjE2KjEwMjQ7dGhpcy5oaWdoV2F0ZXJNYXJrPWh3bXx8aHdtPT09MD9od206ZGVmYXVsdEh3bTt0aGlzLmhpZ2hXYXRlck1hcms9fn50aGlzLmhpZ2hXYXRlck1hcms7dGhpcy5idWZmZXI9bmV3IEJ1ZmZlckxpc3Q7dGhpcy5sZW5ndGg9MDt0aGlzLnBpcGVzPW51bGw7dGhpcy5waXBlc0NvdW50PTA7dGhpcy5mbG93aW5nPW51bGw7dGhpcy5lbmRlZD1mYWxzZTt0aGlzLmVuZEVtaXR0ZWQ9ZmFsc2U7dGhpcy5yZWFkaW5nPWZhbHNlO3RoaXMuc3luYz10cnVlO3RoaXMubmVlZFJlYWRhYmxlPWZhbHNlO3RoaXMuZW1pdHRlZFJlYWRhYmxlPWZhbHNlO3RoaXMucmVhZGFibGVMaXN0ZW5pbmc9ZmFsc2U7dGhpcy5yZXN1bWVTY2hlZHVsZWQ9ZmFsc2U7dGhpcy5kZWZhdWx0RW5jb2Rpbmc9b3B0aW9ucy5kZWZhdWx0RW5jb2Rpbmd8fFwidXRmOFwiO3RoaXMucmFuT3V0PWZhbHNlO3RoaXMuYXdhaXREcmFpbj0wO3RoaXMucmVhZGluZ01vcmU9ZmFsc2U7dGhpcy5kZWNvZGVyPW51bGw7dGhpcy5lbmNvZGluZz1udWxsO2lmKG9wdGlvbnMuZW5jb2Rpbmcpe2lmKCFTdHJpbmdEZWNvZGVyKVN0cmluZ0RlY29kZXI9cmVxdWlyZShcInN0cmluZ19kZWNvZGVyL1wiKS5TdHJpbmdEZWNvZGVyO3RoaXMuZGVjb2Rlcj1uZXcgU3RyaW5nRGVjb2RlcihvcHRpb25zLmVuY29kaW5nKTt0aGlzLmVuY29kaW5nPW9wdGlvbnMuZW5jb2Rpbmd9fXZhciBEdXBsZXg7ZnVuY3Rpb24gUmVhZGFibGUob3B0aW9ucyl7RHVwbGV4PUR1cGxleHx8cmVxdWlyZShcIi4vX3N0cmVhbV9kdXBsZXhcIik7aWYoISh0aGlzIGluc3RhbmNlb2YgUmVhZGFibGUpKXJldHVybiBuZXcgUmVhZGFibGUob3B0aW9ucyk7dGhpcy5fcmVhZGFibGVTdGF0ZT1uZXcgUmVhZGFibGVTdGF0ZShvcHRpb25zLHRoaXMpO3RoaXMucmVhZGFibGU9dHJ1ZTtpZihvcHRpb25zJiZ0eXBlb2Ygb3B0aW9ucy5yZWFkPT09XCJmdW5jdGlvblwiKXRoaXMuX3JlYWQ9b3B0aW9ucy5yZWFkO1N0cmVhbS5jYWxsKHRoaXMpfVJlYWRhYmxlLnByb3RvdHlwZS5wdXNoPWZ1bmN0aW9uKGNodW5rLGVuY29kaW5nKXt2YXIgc3RhdGU9dGhpcy5fcmVhZGFibGVTdGF0ZTtpZighc3RhdGUub2JqZWN0TW9kZSYmdHlwZW9mIGNodW5rPT09XCJzdHJpbmdcIil7ZW5jb2Rpbmc9ZW5jb2Rpbmd8fHN0YXRlLmRlZmF1bHRFbmNvZGluZztpZihlbmNvZGluZyE9PXN0YXRlLmVuY29kaW5nKXtjaHVuaz1idWZmZXJTaGltLmZyb20oY2h1bmssZW5jb2RpbmcpO2VuY29kaW5nPVwiXCJ9fXJldHVybiByZWFkYWJsZUFkZENodW5rKHRoaXMsc3RhdGUsY2h1bmssZW5jb2RpbmcsZmFsc2UpfTtSZWFkYWJsZS5wcm90b3R5cGUudW5zaGlmdD1mdW5jdGlvbihjaHVuayl7dmFyIHN0YXRlPXRoaXMuX3JlYWRhYmxlU3RhdGU7cmV0dXJuIHJlYWRhYmxlQWRkQ2h1bmsodGhpcyxzdGF0ZSxjaHVuayxcIlwiLHRydWUpfTtSZWFkYWJsZS5wcm90b3R5cGUuaXNQYXVzZWQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nPT09ZmFsc2V9O2Z1bmN0aW9uIHJlYWRhYmxlQWRkQ2h1bmsoc3RyZWFtLHN0YXRlLGNodW5rLGVuY29kaW5nLGFkZFRvRnJvbnQpe3ZhciBlcj1jaHVua0ludmFsaWQoc3RhdGUsY2h1bmspO2lmKGVyKXtzdHJlYW0uZW1pdChcImVycm9yXCIsZXIpfWVsc2UgaWYoY2h1bms9PT1udWxsKXtzdGF0ZS5yZWFkaW5nPWZhbHNlO29uRW9mQ2h1bmsoc3RyZWFtLHN0YXRlKX1lbHNlIGlmKHN0YXRlLm9iamVjdE1vZGV8fGNodW5rJiZjaHVuay5sZW5ndGg+MCl7aWYoc3RhdGUuZW5kZWQmJiFhZGRUb0Zyb250KXt2YXIgZT1uZXcgRXJyb3IoXCJzdHJlYW0ucHVzaCgpIGFmdGVyIEVPRlwiKTtzdHJlYW0uZW1pdChcImVycm9yXCIsZSl9ZWxzZSBpZihzdGF0ZS5lbmRFbWl0dGVkJiZhZGRUb0Zyb250KXt2YXIgX2U9bmV3IEVycm9yKFwic3RyZWFtLnVuc2hpZnQoKSBhZnRlciBlbmQgZXZlbnRcIik7c3RyZWFtLmVtaXQoXCJlcnJvclwiLF9lKX1lbHNle3ZhciBza2lwQWRkO2lmKHN0YXRlLmRlY29kZXImJiFhZGRUb0Zyb250JiYhZW5jb2Rpbmcpe2NodW5rPXN0YXRlLmRlY29kZXIud3JpdGUoY2h1bmspO3NraXBBZGQ9IXN0YXRlLm9iamVjdE1vZGUmJmNodW5rLmxlbmd0aD09PTB9aWYoIWFkZFRvRnJvbnQpc3RhdGUucmVhZGluZz1mYWxzZTtpZighc2tpcEFkZCl7aWYoc3RhdGUuZmxvd2luZyYmc3RhdGUubGVuZ3RoPT09MCYmIXN0YXRlLnN5bmMpe3N0cmVhbS5lbWl0KFwiZGF0YVwiLGNodW5rKTtzdHJlYW0ucmVhZCgwKX1lbHNle3N0YXRlLmxlbmd0aCs9c3RhdGUub2JqZWN0TW9kZT8xOmNodW5rLmxlbmd0aDtpZihhZGRUb0Zyb250KXN0YXRlLmJ1ZmZlci51bnNoaWZ0KGNodW5rKTtlbHNlIHN0YXRlLmJ1ZmZlci5wdXNoKGNodW5rKTtpZihzdGF0ZS5uZWVkUmVhZGFibGUpZW1pdFJlYWRhYmxlKHN0cmVhbSl9fW1heWJlUmVhZE1vcmUoc3RyZWFtLHN0YXRlKX19ZWxzZSBpZighYWRkVG9Gcm9udCl7c3RhdGUucmVhZGluZz1mYWxzZX1yZXR1cm4gbmVlZE1vcmVEYXRhKHN0YXRlKX1mdW5jdGlvbiBuZWVkTW9yZURhdGEoc3RhdGUpe3JldHVybiFzdGF0ZS5lbmRlZCYmKHN0YXRlLm5lZWRSZWFkYWJsZXx8c3RhdGUubGVuZ3RoPHN0YXRlLmhpZ2hXYXRlck1hcmt8fHN0YXRlLmxlbmd0aD09PTApfVJlYWRhYmxlLnByb3RvdHlwZS5zZXRFbmNvZGluZz1mdW5jdGlvbihlbmMpe2lmKCFTdHJpbmdEZWNvZGVyKVN0cmluZ0RlY29kZXI9cmVxdWlyZShcInN0cmluZ19kZWNvZGVyL1wiKS5TdHJpbmdEZWNvZGVyO3RoaXMuX3JlYWRhYmxlU3RhdGUuZGVjb2Rlcj1uZXcgU3RyaW5nRGVjb2RlcihlbmMpO3RoaXMuX3JlYWRhYmxlU3RhdGUuZW5jb2Rpbmc9ZW5jO3JldHVybiB0aGlzfTt2YXIgTUFYX0hXTT04Mzg4NjA4O2Z1bmN0aW9uIGNvbXB1dGVOZXdIaWdoV2F0ZXJNYXJrKG4pe2lmKG4+PU1BWF9IV00pe249TUFYX0hXTX1lbHNle24tLTtufD1uPj4+MTtufD1uPj4+MjtufD1uPj4+NDtufD1uPj4+ODtufD1uPj4+MTY7bisrfXJldHVybiBufWZ1bmN0aW9uIGhvd011Y2hUb1JlYWQobixzdGF0ZSl7aWYobjw9MHx8c3RhdGUubGVuZ3RoPT09MCYmc3RhdGUuZW5kZWQpcmV0dXJuIDA7aWYoc3RhdGUub2JqZWN0TW9kZSlyZXR1cm4gMTtpZihuIT09bil7aWYoc3RhdGUuZmxvd2luZyYmc3RhdGUubGVuZ3RoKXJldHVybiBzdGF0ZS5idWZmZXIuaGVhZC5kYXRhLmxlbmd0aDtlbHNlIHJldHVybiBzdGF0ZS5sZW5ndGh9aWYobj5zdGF0ZS5oaWdoV2F0ZXJNYXJrKXN0YXRlLmhpZ2hXYXRlck1hcms9Y29tcHV0ZU5ld0hpZ2hXYXRlck1hcmsobik7aWYobjw9c3RhdGUubGVuZ3RoKXJldHVybiBuO2lmKCFzdGF0ZS5lbmRlZCl7c3RhdGUubmVlZFJlYWRhYmxlPXRydWU7cmV0dXJuIDB9cmV0dXJuIHN0YXRlLmxlbmd0aH1SZWFkYWJsZS5wcm90b3R5cGUucmVhZD1mdW5jdGlvbihuKXtkZWJ1ZyhcInJlYWRcIixuKTtuPXBhcnNlSW50KG4sMTApO3ZhciBzdGF0ZT10aGlzLl9yZWFkYWJsZVN0YXRlO3ZhciBuT3JpZz1uO2lmKG4hPT0wKXN0YXRlLmVtaXR0ZWRSZWFkYWJsZT1mYWxzZTtpZihuPT09MCYmc3RhdGUubmVlZFJlYWRhYmxlJiYoc3RhdGUubGVuZ3RoPj1zdGF0ZS5oaWdoV2F0ZXJNYXJrfHxzdGF0ZS5lbmRlZCkpe2RlYnVnKFwicmVhZDogZW1pdFJlYWRhYmxlXCIsc3RhdGUubGVuZ3RoLHN0YXRlLmVuZGVkKTtpZihzdGF0ZS5sZW5ndGg9PT0wJiZzdGF0ZS5lbmRlZCllbmRSZWFkYWJsZSh0aGlzKTtlbHNlIGVtaXRSZWFkYWJsZSh0aGlzKTtyZXR1cm4gbnVsbH1uPWhvd011Y2hUb1JlYWQobixzdGF0ZSk7aWYobj09PTAmJnN0YXRlLmVuZGVkKXtpZihzdGF0ZS5sZW5ndGg9PT0wKWVuZFJlYWRhYmxlKHRoaXMpO3JldHVybiBudWxsfXZhciBkb1JlYWQ9c3RhdGUubmVlZFJlYWRhYmxlO2RlYnVnKFwibmVlZCByZWFkYWJsZVwiLGRvUmVhZCk7aWYoc3RhdGUubGVuZ3RoPT09MHx8c3RhdGUubGVuZ3RoLW48c3RhdGUuaGlnaFdhdGVyTWFyayl7ZG9SZWFkPXRydWU7ZGVidWcoXCJsZW5ndGggbGVzcyB0aGFuIHdhdGVybWFya1wiLGRvUmVhZCl9aWYoc3RhdGUuZW5kZWR8fHN0YXRlLnJlYWRpbmcpe2RvUmVhZD1mYWxzZTtkZWJ1ZyhcInJlYWRpbmcgb3IgZW5kZWRcIixkb1JlYWQpfWVsc2UgaWYoZG9SZWFkKXtkZWJ1ZyhcImRvIHJlYWRcIik7c3RhdGUucmVhZGluZz10cnVlO3N0YXRlLnN5bmM9dHJ1ZTtpZihzdGF0ZS5sZW5ndGg9PT0wKXN0YXRlLm5lZWRSZWFkYWJsZT10cnVlO3RoaXMuX3JlYWQoc3RhdGUuaGlnaFdhdGVyTWFyayk7c3RhdGUuc3luYz1mYWxzZTtpZighc3RhdGUucmVhZGluZyluPWhvd011Y2hUb1JlYWQobk9yaWcsc3RhdGUpfXZhciByZXQ7aWYobj4wKXJldD1mcm9tTGlzdChuLHN0YXRlKTtlbHNlIHJldD1udWxsO2lmKHJldD09PW51bGwpe3N0YXRlLm5lZWRSZWFkYWJsZT10cnVlO249MH1lbHNle3N0YXRlLmxlbmd0aC09bn1pZihzdGF0ZS5sZW5ndGg9PT0wKXtpZighc3RhdGUuZW5kZWQpc3RhdGUubmVlZFJlYWRhYmxlPXRydWU7aWYobk9yaWchPT1uJiZzdGF0ZS5lbmRlZCllbmRSZWFkYWJsZSh0aGlzKX1pZihyZXQhPT1udWxsKXRoaXMuZW1pdChcImRhdGFcIixyZXQpO3JldHVybiByZXR9O2Z1bmN0aW9uIGNodW5rSW52YWxpZChzdGF0ZSxjaHVuayl7dmFyIGVyPW51bGw7aWYoIUJ1ZmZlci5pc0J1ZmZlcihjaHVuaykmJnR5cGVvZiBjaHVuayE9PVwic3RyaW5nXCImJmNodW5rIT09bnVsbCYmY2h1bmshPT11bmRlZmluZWQmJiFzdGF0ZS5vYmplY3RNb2RlKXtlcj1uZXcgVHlwZUVycm9yKFwiSW52YWxpZCBub24tc3RyaW5nL2J1ZmZlciBjaHVua1wiKX1yZXR1cm4gZXJ9ZnVuY3Rpb24gb25Fb2ZDaHVuayhzdHJlYW0sc3RhdGUpe2lmKHN0YXRlLmVuZGVkKXJldHVybjtpZihzdGF0ZS5kZWNvZGVyKXt2YXIgY2h1bms9c3RhdGUuZGVjb2Rlci5lbmQoKTtpZihjaHVuayYmY2h1bmsubGVuZ3RoKXtzdGF0ZS5idWZmZXIucHVzaChjaHVuayk7c3RhdGUubGVuZ3RoKz1zdGF0ZS5vYmplY3RNb2RlPzE6Y2h1bmsubGVuZ3RofX1zdGF0ZS5lbmRlZD10cnVlO2VtaXRSZWFkYWJsZShzdHJlYW0pfWZ1bmN0aW9uIGVtaXRSZWFkYWJsZShzdHJlYW0pe3ZhciBzdGF0ZT1zdHJlYW0uX3JlYWRhYmxlU3RhdGU7c3RhdGUubmVlZFJlYWRhYmxlPWZhbHNlO2lmKCFzdGF0ZS5lbWl0dGVkUmVhZGFibGUpe2RlYnVnKFwiZW1pdFJlYWRhYmxlXCIsc3RhdGUuZmxvd2luZyk7c3RhdGUuZW1pdHRlZFJlYWRhYmxlPXRydWU7aWYoc3RhdGUuc3luYylwcm9jZXNzTmV4dFRpY2soZW1pdFJlYWRhYmxlXyxzdHJlYW0pO2Vsc2UgZW1pdFJlYWRhYmxlXyhzdHJlYW0pfX1mdW5jdGlvbiBlbWl0UmVhZGFibGVfKHN0cmVhbSl7ZGVidWcoXCJlbWl0IHJlYWRhYmxlXCIpO3N0cmVhbS5lbWl0KFwicmVhZGFibGVcIik7ZmxvdyhzdHJlYW0pfWZ1bmN0aW9uIG1heWJlUmVhZE1vcmUoc3RyZWFtLHN0YXRlKXtpZighc3RhdGUucmVhZGluZ01vcmUpe3N0YXRlLnJlYWRpbmdNb3JlPXRydWU7cHJvY2Vzc05leHRUaWNrKG1heWJlUmVhZE1vcmVfLHN0cmVhbSxzdGF0ZSl9fWZ1bmN0aW9uIG1heWJlUmVhZE1vcmVfKHN0cmVhbSxzdGF0ZSl7dmFyIGxlbj1zdGF0ZS5sZW5ndGg7d2hpbGUoIXN0YXRlLnJlYWRpbmcmJiFzdGF0ZS5mbG93aW5nJiYhc3RhdGUuZW5kZWQmJnN0YXRlLmxlbmd0aDxzdGF0ZS5oaWdoV2F0ZXJNYXJrKXtkZWJ1ZyhcIm1heWJlUmVhZE1vcmUgcmVhZCAwXCIpO3N0cmVhbS5yZWFkKDApO2lmKGxlbj09PXN0YXRlLmxlbmd0aClicmVhaztlbHNlIGxlbj1zdGF0ZS5sZW5ndGh9c3RhdGUucmVhZGluZ01vcmU9ZmFsc2V9UmVhZGFibGUucHJvdG90eXBlLl9yZWFkPWZ1bmN0aW9uKG4pe3RoaXMuZW1pdChcImVycm9yXCIsbmV3IEVycm9yKFwibm90IGltcGxlbWVudGVkXCIpKX07UmVhZGFibGUucHJvdG90eXBlLnBpcGU9ZnVuY3Rpb24oZGVzdCxwaXBlT3B0cyl7dmFyIHNyYz10aGlzO3ZhciBzdGF0ZT10aGlzLl9yZWFkYWJsZVN0YXRlO3N3aXRjaChzdGF0ZS5waXBlc0NvdW50KXtjYXNlIDA6c3RhdGUucGlwZXM9ZGVzdDticmVhaztjYXNlIDE6c3RhdGUucGlwZXM9W3N0YXRlLnBpcGVzLGRlc3RdO2JyZWFrO2RlZmF1bHQ6c3RhdGUucGlwZXMucHVzaChkZXN0KTticmVha31zdGF0ZS5waXBlc0NvdW50Kz0xO2RlYnVnKFwicGlwZSBjb3VudD0lZCBvcHRzPSVqXCIsc3RhdGUucGlwZXNDb3VudCxwaXBlT3B0cyk7dmFyIGRvRW5kPSghcGlwZU9wdHN8fHBpcGVPcHRzLmVuZCE9PWZhbHNlKSYmZGVzdCE9PXByb2Nlc3Muc3Rkb3V0JiZkZXN0IT09cHJvY2Vzcy5zdGRlcnI7dmFyIGVuZEZuPWRvRW5kP29uZW5kOmNsZWFudXA7aWYoc3RhdGUuZW5kRW1pdHRlZClwcm9jZXNzTmV4dFRpY2soZW5kRm4pO2Vsc2Ugc3JjLm9uY2UoXCJlbmRcIixlbmRGbik7ZGVzdC5vbihcInVucGlwZVwiLG9udW5waXBlKTtmdW5jdGlvbiBvbnVucGlwZShyZWFkYWJsZSl7ZGVidWcoXCJvbnVucGlwZVwiKTtpZihyZWFkYWJsZT09PXNyYyl7Y2xlYW51cCgpfX1mdW5jdGlvbiBvbmVuZCgpe2RlYnVnKFwib25lbmRcIik7ZGVzdC5lbmQoKX12YXIgb25kcmFpbj1waXBlT25EcmFpbihzcmMpO2Rlc3Qub24oXCJkcmFpblwiLG9uZHJhaW4pO3ZhciBjbGVhbmVkVXA9ZmFsc2U7ZnVuY3Rpb24gY2xlYW51cCgpe2RlYnVnKFwiY2xlYW51cFwiKTtkZXN0LnJlbW92ZUxpc3RlbmVyKFwiY2xvc2VcIixvbmNsb3NlKTtkZXN0LnJlbW92ZUxpc3RlbmVyKFwiZmluaXNoXCIsb25maW5pc2gpO2Rlc3QucmVtb3ZlTGlzdGVuZXIoXCJkcmFpblwiLG9uZHJhaW4pO2Rlc3QucmVtb3ZlTGlzdGVuZXIoXCJlcnJvclwiLG9uZXJyb3IpO2Rlc3QucmVtb3ZlTGlzdGVuZXIoXCJ1bnBpcGVcIixvbnVucGlwZSk7c3JjLnJlbW92ZUxpc3RlbmVyKFwiZW5kXCIsb25lbmQpO3NyYy5yZW1vdmVMaXN0ZW5lcihcImVuZFwiLGNsZWFudXApO3NyYy5yZW1vdmVMaXN0ZW5lcihcImRhdGFcIixvbmRhdGEpO2NsZWFuZWRVcD10cnVlO2lmKHN0YXRlLmF3YWl0RHJhaW4mJighZGVzdC5fd3JpdGFibGVTdGF0ZXx8ZGVzdC5fd3JpdGFibGVTdGF0ZS5uZWVkRHJhaW4pKW9uZHJhaW4oKX12YXIgaW5jcmVhc2VkQXdhaXREcmFpbj1mYWxzZTtzcmMub24oXCJkYXRhXCIsb25kYXRhKTtmdW5jdGlvbiBvbmRhdGEoY2h1bmspe2RlYnVnKFwib25kYXRhXCIpO2luY3JlYXNlZEF3YWl0RHJhaW49ZmFsc2U7dmFyIHJldD1kZXN0LndyaXRlKGNodW5rKTtpZihmYWxzZT09PXJldCYmIWluY3JlYXNlZEF3YWl0RHJhaW4pe2lmKChzdGF0ZS5waXBlc0NvdW50PT09MSYmc3RhdGUucGlwZXM9PT1kZXN0fHxzdGF0ZS5waXBlc0NvdW50PjEmJmluZGV4T2Yoc3RhdGUucGlwZXMsZGVzdCkhPT0tMSkmJiFjbGVhbmVkVXApe2RlYnVnKFwiZmFsc2Ugd3JpdGUgcmVzcG9uc2UsIHBhdXNlXCIsc3JjLl9yZWFkYWJsZVN0YXRlLmF3YWl0RHJhaW4pO3NyYy5fcmVhZGFibGVTdGF0ZS5hd2FpdERyYWluKys7aW5jcmVhc2VkQXdhaXREcmFpbj10cnVlfXNyYy5wYXVzZSgpfX1mdW5jdGlvbiBvbmVycm9yKGVyKXtkZWJ1ZyhcIm9uZXJyb3JcIixlcik7dW5waXBlKCk7ZGVzdC5yZW1vdmVMaXN0ZW5lcihcImVycm9yXCIsb25lcnJvcik7aWYoRUVsaXN0ZW5lckNvdW50KGRlc3QsXCJlcnJvclwiKT09PTApZGVzdC5lbWl0KFwiZXJyb3JcIixlcil9cHJlcGVuZExpc3RlbmVyKGRlc3QsXCJlcnJvclwiLG9uZXJyb3IpO2Z1bmN0aW9uIG9uY2xvc2UoKXtkZXN0LnJlbW92ZUxpc3RlbmVyKFwiZmluaXNoXCIsb25maW5pc2gpO3VucGlwZSgpfWRlc3Qub25jZShcImNsb3NlXCIsb25jbG9zZSk7ZnVuY3Rpb24gb25maW5pc2goKXtkZWJ1ZyhcIm9uZmluaXNoXCIpO2Rlc3QucmVtb3ZlTGlzdGVuZXIoXCJjbG9zZVwiLG9uY2xvc2UpO3VucGlwZSgpfWRlc3Qub25jZShcImZpbmlzaFwiLG9uZmluaXNoKTtmdW5jdGlvbiB1bnBpcGUoKXtkZWJ1ZyhcInVucGlwZVwiKTtzcmMudW5waXBlKGRlc3QpfWRlc3QuZW1pdChcInBpcGVcIixzcmMpO2lmKCFzdGF0ZS5mbG93aW5nKXtkZWJ1ZyhcInBpcGUgcmVzdW1lXCIpO3NyYy5yZXN1bWUoKX1yZXR1cm4gZGVzdH07ZnVuY3Rpb24gcGlwZU9uRHJhaW4oc3JjKXtyZXR1cm4gZnVuY3Rpb24oKXt2YXIgc3RhdGU9c3JjLl9yZWFkYWJsZVN0YXRlO2RlYnVnKFwicGlwZU9uRHJhaW5cIixzdGF0ZS5hd2FpdERyYWluKTtpZihzdGF0ZS5hd2FpdERyYWluKXN0YXRlLmF3YWl0RHJhaW4tLTtpZihzdGF0ZS5hd2FpdERyYWluPT09MCYmRUVsaXN0ZW5lckNvdW50KHNyYyxcImRhdGFcIikpe3N0YXRlLmZsb3dpbmc9dHJ1ZTtmbG93KHNyYyl9fX1SZWFkYWJsZS5wcm90b3R5cGUudW5waXBlPWZ1bmN0aW9uKGRlc3Qpe3ZhciBzdGF0ZT10aGlzLl9yZWFkYWJsZVN0YXRlO2lmKHN0YXRlLnBpcGVzQ291bnQ9PT0wKXJldHVybiB0aGlzO2lmKHN0YXRlLnBpcGVzQ291bnQ9PT0xKXtpZihkZXN0JiZkZXN0IT09c3RhdGUucGlwZXMpcmV0dXJuIHRoaXM7aWYoIWRlc3QpZGVzdD1zdGF0ZS5waXBlcztzdGF0ZS5waXBlcz1udWxsO3N0YXRlLnBpcGVzQ291bnQ9MDtzdGF0ZS5mbG93aW5nPWZhbHNlO2lmKGRlc3QpZGVzdC5lbWl0KFwidW5waXBlXCIsdGhpcyk7cmV0dXJuIHRoaXN9aWYoIWRlc3Qpe3ZhciBkZXN0cz1zdGF0ZS5waXBlczt2YXIgbGVuPXN0YXRlLnBpcGVzQ291bnQ7c3RhdGUucGlwZXM9bnVsbDtzdGF0ZS5waXBlc0NvdW50PTA7c3RhdGUuZmxvd2luZz1mYWxzZTtmb3IodmFyIF9pPTA7X2k8bGVuO19pKyspe2Rlc3RzW19pXS5lbWl0KFwidW5waXBlXCIsdGhpcyl9cmV0dXJuIHRoaXN9dmFyIGk9aW5kZXhPZihzdGF0ZS5waXBlcyxkZXN0KTtpZihpPT09LTEpcmV0dXJuIHRoaXM7c3RhdGUucGlwZXMuc3BsaWNlKGksMSk7c3RhdGUucGlwZXNDb3VudC09MTtpZihzdGF0ZS5waXBlc0NvdW50PT09MSlzdGF0ZS5waXBlcz1zdGF0ZS5waXBlc1swXTtkZXN0LmVtaXQoXCJ1bnBpcGVcIix0aGlzKTtyZXR1cm4gdGhpc307UmVhZGFibGUucHJvdG90eXBlLm9uPWZ1bmN0aW9uKGV2LGZuKXt2YXIgcmVzPVN0cmVhbS5wcm90b3R5cGUub24uY2FsbCh0aGlzLGV2LGZuKTtpZihldj09PVwiZGF0YVwiKXtpZih0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmchPT1mYWxzZSl0aGlzLnJlc3VtZSgpfWVsc2UgaWYoZXY9PT1cInJlYWRhYmxlXCIpe3ZhciBzdGF0ZT10aGlzLl9yZWFkYWJsZVN0YXRlO2lmKCFzdGF0ZS5lbmRFbWl0dGVkJiYhc3RhdGUucmVhZGFibGVMaXN0ZW5pbmcpe3N0YXRlLnJlYWRhYmxlTGlzdGVuaW5nPXN0YXRlLm5lZWRSZWFkYWJsZT10cnVlO3N0YXRlLmVtaXR0ZWRSZWFkYWJsZT1mYWxzZTtpZighc3RhdGUucmVhZGluZyl7cHJvY2Vzc05leHRUaWNrKG5SZWFkaW5nTmV4dFRpY2ssdGhpcyl9ZWxzZSBpZihzdGF0ZS5sZW5ndGgpe2VtaXRSZWFkYWJsZSh0aGlzLHN0YXRlKX19fXJldHVybiByZXN9O1JlYWRhYmxlLnByb3RvdHlwZS5hZGRMaXN0ZW5lcj1SZWFkYWJsZS5wcm90b3R5cGUub247ZnVuY3Rpb24gblJlYWRpbmdOZXh0VGljayhzZWxmKXtkZWJ1ZyhcInJlYWRhYmxlIG5leHR0aWNrIHJlYWQgMFwiKTtzZWxmLnJlYWQoMCl9UmVhZGFibGUucHJvdG90eXBlLnJlc3VtZT1mdW5jdGlvbigpe3ZhciBzdGF0ZT10aGlzLl9yZWFkYWJsZVN0YXRlO2lmKCFzdGF0ZS5mbG93aW5nKXtkZWJ1ZyhcInJlc3VtZVwiKTtzdGF0ZS5mbG93aW5nPXRydWU7cmVzdW1lKHRoaXMsc3RhdGUpfXJldHVybiB0aGlzfTtmdW5jdGlvbiByZXN1bWUoc3RyZWFtLHN0YXRlKXtpZighc3RhdGUucmVzdW1lU2NoZWR1bGVkKXtzdGF0ZS5yZXN1bWVTY2hlZHVsZWQ9dHJ1ZTtwcm9jZXNzTmV4dFRpY2socmVzdW1lXyxzdHJlYW0sc3RhdGUpfX1mdW5jdGlvbiByZXN1bWVfKHN0cmVhbSxzdGF0ZSl7aWYoIXN0YXRlLnJlYWRpbmcpe2RlYnVnKFwicmVzdW1lIHJlYWQgMFwiKTtzdHJlYW0ucmVhZCgwKX1zdGF0ZS5yZXN1bWVTY2hlZHVsZWQ9ZmFsc2U7c3RhdGUuYXdhaXREcmFpbj0wO3N0cmVhbS5lbWl0KFwicmVzdW1lXCIpO2Zsb3coc3RyZWFtKTtpZihzdGF0ZS5mbG93aW5nJiYhc3RhdGUucmVhZGluZylzdHJlYW0ucmVhZCgwKX1SZWFkYWJsZS5wcm90b3R5cGUucGF1c2U9ZnVuY3Rpb24oKXtkZWJ1ZyhcImNhbGwgcGF1c2UgZmxvd2luZz0lalwiLHRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZyk7aWYoZmFsc2UhPT10aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcpe2RlYnVnKFwicGF1c2VcIik7dGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nPWZhbHNlO3RoaXMuZW1pdChcInBhdXNlXCIpfXJldHVybiB0aGlzfTtmdW5jdGlvbiBmbG93KHN0cmVhbSl7dmFyIHN0YXRlPXN0cmVhbS5fcmVhZGFibGVTdGF0ZTtkZWJ1ZyhcImZsb3dcIixzdGF0ZS5mbG93aW5nKTt3aGlsZShzdGF0ZS5mbG93aW5nJiZzdHJlYW0ucmVhZCgpIT09bnVsbCl7fX1SZWFkYWJsZS5wcm90b3R5cGUud3JhcD1mdW5jdGlvbihzdHJlYW0pe3ZhciBzdGF0ZT10aGlzLl9yZWFkYWJsZVN0YXRlO3ZhciBwYXVzZWQ9ZmFsc2U7dmFyIHNlbGY9dGhpcztzdHJlYW0ub24oXCJlbmRcIixmdW5jdGlvbigpe2RlYnVnKFwid3JhcHBlZCBlbmRcIik7aWYoc3RhdGUuZGVjb2RlciYmIXN0YXRlLmVuZGVkKXt2YXIgY2h1bms9c3RhdGUuZGVjb2Rlci5lbmQoKTtpZihjaHVuayYmY2h1bmsubGVuZ3RoKXNlbGYucHVzaChjaHVuayl9c2VsZi5wdXNoKG51bGwpfSk7c3RyZWFtLm9uKFwiZGF0YVwiLGZ1bmN0aW9uKGNodW5rKXtkZWJ1ZyhcIndyYXBwZWQgZGF0YVwiKTtpZihzdGF0ZS5kZWNvZGVyKWNodW5rPXN0YXRlLmRlY29kZXIud3JpdGUoY2h1bmspO2lmKHN0YXRlLm9iamVjdE1vZGUmJihjaHVuaz09PW51bGx8fGNodW5rPT09dW5kZWZpbmVkKSlyZXR1cm47ZWxzZSBpZighc3RhdGUub2JqZWN0TW9kZSYmKCFjaHVua3x8IWNodW5rLmxlbmd0aCkpcmV0dXJuO3ZhciByZXQ9c2VsZi5wdXNoKGNodW5rKTtpZighcmV0KXtwYXVzZWQ9dHJ1ZTtzdHJlYW0ucGF1c2UoKX19KTtmb3IodmFyIGkgaW4gc3RyZWFtKXtpZih0aGlzW2ldPT09dW5kZWZpbmVkJiZ0eXBlb2Ygc3RyZWFtW2ldPT09XCJmdW5jdGlvblwiKXt0aGlzW2ldPWZ1bmN0aW9uKG1ldGhvZCl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIHN0cmVhbVttZXRob2RdLmFwcGx5KHN0cmVhbSxhcmd1bWVudHMpfX0oaSl9fXZhciBldmVudHM9W1wiZXJyb3JcIixcImNsb3NlXCIsXCJkZXN0cm95XCIsXCJwYXVzZVwiLFwicmVzdW1lXCJdO2ZvckVhY2goZXZlbnRzLGZ1bmN0aW9uKGV2KXtzdHJlYW0ub24oZXYsc2VsZi5lbWl0LmJpbmQoc2VsZixldikpfSk7c2VsZi5fcmVhZD1mdW5jdGlvbihuKXtkZWJ1ZyhcIndyYXBwZWQgX3JlYWRcIixuKTtpZihwYXVzZWQpe3BhdXNlZD1mYWxzZTtzdHJlYW0ucmVzdW1lKCl9fTtyZXR1cm4gc2VsZn07UmVhZGFibGUuX2Zyb21MaXN0PWZyb21MaXN0O2Z1bmN0aW9uIGZyb21MaXN0KG4sc3RhdGUpe2lmKHN0YXRlLmxlbmd0aD09PTApcmV0dXJuIG51bGw7dmFyIHJldDtpZihzdGF0ZS5vYmplY3RNb2RlKXJldD1zdGF0ZS5idWZmZXIuc2hpZnQoKTtlbHNlIGlmKCFufHxuPj1zdGF0ZS5sZW5ndGgpe2lmKHN0YXRlLmRlY29kZXIpcmV0PXN0YXRlLmJ1ZmZlci5qb2luKFwiXCIpO2Vsc2UgaWYoc3RhdGUuYnVmZmVyLmxlbmd0aD09PTEpcmV0PXN0YXRlLmJ1ZmZlci5oZWFkLmRhdGE7ZWxzZSByZXQ9c3RhdGUuYnVmZmVyLmNvbmNhdChzdGF0ZS5sZW5ndGgpO3N0YXRlLmJ1ZmZlci5jbGVhcigpfWVsc2V7cmV0PWZyb21MaXN0UGFydGlhbChuLHN0YXRlLmJ1ZmZlcixzdGF0ZS5kZWNvZGVyKX1yZXR1cm4gcmV0fWZ1bmN0aW9uIGZyb21MaXN0UGFydGlhbChuLGxpc3QsaGFzU3RyaW5ncyl7dmFyIHJldDtpZihuPGxpc3QuaGVhZC5kYXRhLmxlbmd0aCl7cmV0PWxpc3QuaGVhZC5kYXRhLnNsaWNlKDAsbik7bGlzdC5oZWFkLmRhdGE9bGlzdC5oZWFkLmRhdGEuc2xpY2Uobil9ZWxzZSBpZihuPT09bGlzdC5oZWFkLmRhdGEubGVuZ3RoKXtyZXQ9bGlzdC5zaGlmdCgpfWVsc2V7cmV0PWhhc1N0cmluZ3M/Y29weUZyb21CdWZmZXJTdHJpbmcobixsaXN0KTpjb3B5RnJvbUJ1ZmZlcihuLGxpc3QpfXJldHVybiByZXR9ZnVuY3Rpb24gY29weUZyb21CdWZmZXJTdHJpbmcobixsaXN0KXt2YXIgcD1saXN0LmhlYWQ7dmFyIGM9MTt2YXIgcmV0PXAuZGF0YTtuLT1yZXQubGVuZ3RoO3doaWxlKHA9cC5uZXh0KXt2YXIgc3RyPXAuZGF0YTt2YXIgbmI9bj5zdHIubGVuZ3RoP3N0ci5sZW5ndGg6bjtpZihuYj09PXN0ci5sZW5ndGgpcmV0Kz1zdHI7ZWxzZSByZXQrPXN0ci5zbGljZSgwLG4pO24tPW5iO2lmKG49PT0wKXtpZihuYj09PXN0ci5sZW5ndGgpeysrYztpZihwLm5leHQpbGlzdC5oZWFkPXAubmV4dDtlbHNlIGxpc3QuaGVhZD1saXN0LnRhaWw9bnVsbH1lbHNle2xpc3QuaGVhZD1wO3AuZGF0YT1zdHIuc2xpY2UobmIpfWJyZWFrfSsrY31saXN0Lmxlbmd0aC09YztyZXR1cm4gcmV0fWZ1bmN0aW9uIGNvcHlGcm9tQnVmZmVyKG4sbGlzdCl7dmFyIHJldD1idWZmZXJTaGltLmFsbG9jVW5zYWZlKG4pO3ZhciBwPWxpc3QuaGVhZDt2YXIgYz0xO3AuZGF0YS5jb3B5KHJldCk7bi09cC5kYXRhLmxlbmd0aDt3aGlsZShwPXAubmV4dCl7dmFyIGJ1Zj1wLmRhdGE7dmFyIG5iPW4+YnVmLmxlbmd0aD9idWYubGVuZ3RoOm47YnVmLmNvcHkocmV0LHJldC5sZW5ndGgtbiwwLG5iKTtuLT1uYjtpZihuPT09MCl7aWYobmI9PT1idWYubGVuZ3RoKXsrK2M7aWYocC5uZXh0KWxpc3QuaGVhZD1wLm5leHQ7ZWxzZSBsaXN0LmhlYWQ9bGlzdC50YWlsPW51bGx9ZWxzZXtsaXN0LmhlYWQ9cDtwLmRhdGE9YnVmLnNsaWNlKG5iKX1icmVha30rK2N9bGlzdC5sZW5ndGgtPWM7cmV0dXJuIHJldH1mdW5jdGlvbiBlbmRSZWFkYWJsZShzdHJlYW0pe3ZhciBzdGF0ZT1zdHJlYW0uX3JlYWRhYmxlU3RhdGU7aWYoc3RhdGUubGVuZ3RoPjApdGhyb3cgbmV3IEVycm9yKCdcImVuZFJlYWRhYmxlKClcIiBjYWxsZWQgb24gbm9uLWVtcHR5IHN0cmVhbScpO2lmKCFzdGF0ZS5lbmRFbWl0dGVkKXtzdGF0ZS5lbmRlZD10cnVlO3Byb2Nlc3NOZXh0VGljayhlbmRSZWFkYWJsZU5ULHN0YXRlLHN0cmVhbSl9fWZ1bmN0aW9uIGVuZFJlYWRhYmxlTlQoc3RhdGUsc3RyZWFtKXtpZighc3RhdGUuZW5kRW1pdHRlZCYmc3RhdGUubGVuZ3RoPT09MCl7c3RhdGUuZW5kRW1pdHRlZD10cnVlO3N0cmVhbS5yZWFkYWJsZT1mYWxzZTtzdHJlYW0uZW1pdChcImVuZFwiKX19ZnVuY3Rpb24gZm9yRWFjaCh4cyxmKXtmb3IodmFyIGk9MCxsPXhzLmxlbmd0aDtpPGw7aSsrKXtmKHhzW2ldLGkpfX1mdW5jdGlvbiBpbmRleE9mKHhzLHgpe2Zvcih2YXIgaT0wLGw9eHMubGVuZ3RoO2k8bDtpKyspe2lmKHhzW2ldPT09eClyZXR1cm4gaX1yZXR1cm4tMX19KS5jYWxsKHRoaXMscmVxdWlyZShcIl9wcm9jZXNzXCIpKX0se1wiLi9fc3RyZWFtX2R1cGxleFwiOjQ0LFwiLi9pbnRlcm5hbC9zdHJlYW1zL0J1ZmZlckxpc3RcIjo0OSxfcHJvY2Vzczo0MixidWZmZXI6NSxcImJ1ZmZlci1zaGltc1wiOjQsXCJjb3JlLXV0aWwtaXNcIjo2LGV2ZW50czoyOCxpbmhlcml0czozOCxpc2FycmF5OjQwLFwicHJvY2Vzcy1uZXh0aWNrLWFyZ3NcIjo0MSxcInN0cmluZ19kZWNvZGVyL1wiOjU2LHV0aWw6M31dLDQ3OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcInVzZSBzdHJpY3RcIjttb2R1bGUuZXhwb3J0cz1UcmFuc2Zvcm07dmFyIER1cGxleD1yZXF1aXJlKFwiLi9fc3RyZWFtX2R1cGxleFwiKTt2YXIgdXRpbD1yZXF1aXJlKFwiY29yZS11dGlsLWlzXCIpO3V0aWwuaW5oZXJpdHM9cmVxdWlyZShcImluaGVyaXRzXCIpO3V0aWwuaW5oZXJpdHMoVHJhbnNmb3JtLER1cGxleCk7ZnVuY3Rpb24gVHJhbnNmb3JtU3RhdGUoc3RyZWFtKXt0aGlzLmFmdGVyVHJhbnNmb3JtPWZ1bmN0aW9uKGVyLGRhdGEpe3JldHVybiBhZnRlclRyYW5zZm9ybShzdHJlYW0sZXIsZGF0YSl9O3RoaXMubmVlZFRyYW5zZm9ybT1mYWxzZTt0aGlzLnRyYW5zZm9ybWluZz1mYWxzZTt0aGlzLndyaXRlY2I9bnVsbDt0aGlzLndyaXRlY2h1bms9bnVsbDt0aGlzLndyaXRlZW5jb2Rpbmc9bnVsbH1mdW5jdGlvbiBhZnRlclRyYW5zZm9ybShzdHJlYW0sZXIsZGF0YSl7dmFyIHRzPXN0cmVhbS5fdHJhbnNmb3JtU3RhdGU7dHMudHJhbnNmb3JtaW5nPWZhbHNlO3ZhciBjYj10cy53cml0ZWNiO2lmKCFjYilyZXR1cm4gc3RyZWFtLmVtaXQoXCJlcnJvclwiLG5ldyBFcnJvcihcIm5vIHdyaXRlY2IgaW4gVHJhbnNmb3JtIGNsYXNzXCIpKTt0cy53cml0ZWNodW5rPW51bGw7dHMud3JpdGVjYj1udWxsO2lmKGRhdGEhPT1udWxsJiZkYXRhIT09dW5kZWZpbmVkKXN0cmVhbS5wdXNoKGRhdGEpO2NiKGVyKTt2YXIgcnM9c3RyZWFtLl9yZWFkYWJsZVN0YXRlO3JzLnJlYWRpbmc9ZmFsc2U7aWYocnMubmVlZFJlYWRhYmxlfHxycy5sZW5ndGg8cnMuaGlnaFdhdGVyTWFyayl7c3RyZWFtLl9yZWFkKHJzLmhpZ2hXYXRlck1hcmspfX1mdW5jdGlvbiBUcmFuc2Zvcm0ob3B0aW9ucyl7aWYoISh0aGlzIGluc3RhbmNlb2YgVHJhbnNmb3JtKSlyZXR1cm4gbmV3IFRyYW5zZm9ybShvcHRpb25zKTtEdXBsZXguY2FsbCh0aGlzLG9wdGlvbnMpO3RoaXMuX3RyYW5zZm9ybVN0YXRlPW5ldyBUcmFuc2Zvcm1TdGF0ZSh0aGlzKTt2YXIgc3RyZWFtPXRoaXM7dGhpcy5fcmVhZGFibGVTdGF0ZS5uZWVkUmVhZGFibGU9dHJ1ZTt0aGlzLl9yZWFkYWJsZVN0YXRlLnN5bmM9ZmFsc2U7aWYob3B0aW9ucyl7aWYodHlwZW9mIG9wdGlvbnMudHJhbnNmb3JtPT09XCJmdW5jdGlvblwiKXRoaXMuX3RyYW5zZm9ybT1vcHRpb25zLnRyYW5zZm9ybTtpZih0eXBlb2Ygb3B0aW9ucy5mbHVzaD09PVwiZnVuY3Rpb25cIil0aGlzLl9mbHVzaD1vcHRpb25zLmZsdXNofXRoaXMub25jZShcInByZWZpbmlzaFwiLGZ1bmN0aW9uKCl7aWYodHlwZW9mIHRoaXMuX2ZsdXNoPT09XCJmdW5jdGlvblwiKXRoaXMuX2ZsdXNoKGZ1bmN0aW9uKGVyKXtkb25lKHN0cmVhbSxlcil9KTtlbHNlIGRvbmUoc3RyZWFtKX0pfVRyYW5zZm9ybS5wcm90b3R5cGUucHVzaD1mdW5jdGlvbihjaHVuayxlbmNvZGluZyl7dGhpcy5fdHJhbnNmb3JtU3RhdGUubmVlZFRyYW5zZm9ybT1mYWxzZTtyZXR1cm4gRHVwbGV4LnByb3RvdHlwZS5wdXNoLmNhbGwodGhpcyxjaHVuayxlbmNvZGluZyl9O1RyYW5zZm9ybS5wcm90b3R5cGUuX3RyYW5zZm9ybT1mdW5jdGlvbihjaHVuayxlbmNvZGluZyxjYil7dGhyb3cgbmV3IEVycm9yKFwiTm90IGltcGxlbWVudGVkXCIpfTtUcmFuc2Zvcm0ucHJvdG90eXBlLl93cml0ZT1mdW5jdGlvbihjaHVuayxlbmNvZGluZyxjYil7dmFyIHRzPXRoaXMuX3RyYW5zZm9ybVN0YXRlO3RzLndyaXRlY2I9Y2I7dHMud3JpdGVjaHVuaz1jaHVuazt0cy53cml0ZWVuY29kaW5nPWVuY29kaW5nO2lmKCF0cy50cmFuc2Zvcm1pbmcpe3ZhciBycz10aGlzLl9yZWFkYWJsZVN0YXRlO2lmKHRzLm5lZWRUcmFuc2Zvcm18fHJzLm5lZWRSZWFkYWJsZXx8cnMubGVuZ3RoPHJzLmhpZ2hXYXRlck1hcmspdGhpcy5fcmVhZChycy5oaWdoV2F0ZXJNYXJrKX19O1RyYW5zZm9ybS5wcm90b3R5cGUuX3JlYWQ9ZnVuY3Rpb24obil7dmFyIHRzPXRoaXMuX3RyYW5zZm9ybVN0YXRlO2lmKHRzLndyaXRlY2h1bmshPT1udWxsJiZ0cy53cml0ZWNiJiYhdHMudHJhbnNmb3JtaW5nKXt0cy50cmFuc2Zvcm1pbmc9dHJ1ZTt0aGlzLl90cmFuc2Zvcm0odHMud3JpdGVjaHVuayx0cy53cml0ZWVuY29kaW5nLHRzLmFmdGVyVHJhbnNmb3JtKX1lbHNle3RzLm5lZWRUcmFuc2Zvcm09dHJ1ZX19O2Z1bmN0aW9uIGRvbmUoc3RyZWFtLGVyKXtpZihlcilyZXR1cm4gc3RyZWFtLmVtaXQoXCJlcnJvclwiLGVyKTt2YXIgd3M9c3RyZWFtLl93cml0YWJsZVN0YXRlO3ZhciB0cz1zdHJlYW0uX3RyYW5zZm9ybVN0YXRlO2lmKHdzLmxlbmd0aCl0aHJvdyBuZXcgRXJyb3IoXCJDYWxsaW5nIHRyYW5zZm9ybSBkb25lIHdoZW4gd3MubGVuZ3RoICE9IDBcIik7aWYodHMudHJhbnNmb3JtaW5nKXRocm93IG5ldyBFcnJvcihcIkNhbGxpbmcgdHJhbnNmb3JtIGRvbmUgd2hlbiBzdGlsbCB0cmFuc2Zvcm1pbmdcIik7cmV0dXJuIHN0cmVhbS5wdXNoKG51bGwpfX0se1wiLi9fc3RyZWFtX2R1cGxleFwiOjQ0LFwiY29yZS11dGlsLWlzXCI6Nixpbmhlcml0czozOH1dLDQ4OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsoZnVuY3Rpb24ocHJvY2Vzcyl7XCJ1c2Ugc3RyaWN0XCI7bW9kdWxlLmV4cG9ydHM9V3JpdGFibGU7dmFyIHByb2Nlc3NOZXh0VGljaz1yZXF1aXJlKFwicHJvY2Vzcy1uZXh0aWNrLWFyZ3NcIik7dmFyIGFzeW5jV3JpdGU9IXByb2Nlc3MuYnJvd3NlciYmW1widjAuMTBcIixcInYwLjkuXCJdLmluZGV4T2YocHJvY2Vzcy52ZXJzaW9uLnNsaWNlKDAsNSkpPi0xP3NldEltbWVkaWF0ZTpwcm9jZXNzTmV4dFRpY2s7V3JpdGFibGUuV3JpdGFibGVTdGF0ZT1Xcml0YWJsZVN0YXRlO3ZhciB1dGlsPXJlcXVpcmUoXCJjb3JlLXV0aWwtaXNcIik7dXRpbC5pbmhlcml0cz1yZXF1aXJlKFwiaW5oZXJpdHNcIik7dmFyIGludGVybmFsVXRpbD17ZGVwcmVjYXRlOnJlcXVpcmUoXCJ1dGlsLWRlcHJlY2F0ZVwiKX07dmFyIFN0cmVhbTsoZnVuY3Rpb24oKXt0cnl7U3RyZWFtPXJlcXVpcmUoXCJzdFwiK1wicmVhbVwiKX1jYXRjaChfKXt9ZmluYWxseXtpZighU3RyZWFtKVN0cmVhbT1yZXF1aXJlKFwiZXZlbnRzXCIpLkV2ZW50RW1pdHRlcn19KSgpO3ZhciBCdWZmZXI9cmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXI7dmFyIGJ1ZmZlclNoaW09cmVxdWlyZShcImJ1ZmZlci1zaGltc1wiKTt1dGlsLmluaGVyaXRzKFdyaXRhYmxlLFN0cmVhbSk7ZnVuY3Rpb24gbm9wKCl7fWZ1bmN0aW9uIFdyaXRlUmVxKGNodW5rLGVuY29kaW5nLGNiKXt0aGlzLmNodW5rPWNodW5rO3RoaXMuZW5jb2Rpbmc9ZW5jb2Rpbmc7dGhpcy5jYWxsYmFjaz1jYjt0aGlzLm5leHQ9bnVsbH12YXIgRHVwbGV4O2Z1bmN0aW9uIFdyaXRhYmxlU3RhdGUob3B0aW9ucyxzdHJlYW0pe0R1cGxleD1EdXBsZXh8fHJlcXVpcmUoXCIuL19zdHJlYW1fZHVwbGV4XCIpO29wdGlvbnM9b3B0aW9uc3x8e307dGhpcy5vYmplY3RNb2RlPSEhb3B0aW9ucy5vYmplY3RNb2RlO2lmKHN0cmVhbSBpbnN0YW5jZW9mIER1cGxleCl0aGlzLm9iamVjdE1vZGU9dGhpcy5vYmplY3RNb2RlfHwhIW9wdGlvbnMud3JpdGFibGVPYmplY3RNb2RlO3ZhciBod209b3B0aW9ucy5oaWdoV2F0ZXJNYXJrO3ZhciBkZWZhdWx0SHdtPXRoaXMub2JqZWN0TW9kZT8xNjoxNioxMDI0O3RoaXMuaGlnaFdhdGVyTWFyaz1od218fGh3bT09PTA/aHdtOmRlZmF1bHRId207dGhpcy5oaWdoV2F0ZXJNYXJrPX5+dGhpcy5oaWdoV2F0ZXJNYXJrO3RoaXMubmVlZERyYWluPWZhbHNlO3RoaXMuZW5kaW5nPWZhbHNlO3RoaXMuZW5kZWQ9ZmFsc2U7dGhpcy5maW5pc2hlZD1mYWxzZTt2YXIgbm9EZWNvZGU9b3B0aW9ucy5kZWNvZGVTdHJpbmdzPT09ZmFsc2U7dGhpcy5kZWNvZGVTdHJpbmdzPSFub0RlY29kZTt0aGlzLmRlZmF1bHRFbmNvZGluZz1vcHRpb25zLmRlZmF1bHRFbmNvZGluZ3x8XCJ1dGY4XCI7dGhpcy5sZW5ndGg9MDt0aGlzLndyaXRpbmc9ZmFsc2U7dGhpcy5jb3JrZWQ9MDt0aGlzLnN5bmM9dHJ1ZTt0aGlzLmJ1ZmZlclByb2Nlc3Npbmc9ZmFsc2U7dGhpcy5vbndyaXRlPWZ1bmN0aW9uKGVyKXtvbndyaXRlKHN0cmVhbSxlcil9O3RoaXMud3JpdGVjYj1udWxsO3RoaXMud3JpdGVsZW49MDt0aGlzLmJ1ZmZlcmVkUmVxdWVzdD1udWxsO3RoaXMubGFzdEJ1ZmZlcmVkUmVxdWVzdD1udWxsO3RoaXMucGVuZGluZ2NiPTA7dGhpcy5wcmVmaW5pc2hlZD1mYWxzZTt0aGlzLmVycm9yRW1pdHRlZD1mYWxzZTt0aGlzLmJ1ZmZlcmVkUmVxdWVzdENvdW50PTA7dGhpcy5jb3JrZWRSZXF1ZXN0c0ZyZWU9bmV3IENvcmtlZFJlcXVlc3QodGhpcyl9V3JpdGFibGVTdGF0ZS5wcm90b3R5cGUuZ2V0QnVmZmVyPWZ1bmN0aW9uIHdyaXRhYmxlU3RhdGVHZXRCdWZmZXIoKXt2YXIgY3VycmVudD10aGlzLmJ1ZmZlcmVkUmVxdWVzdDt2YXIgb3V0PVtdO3doaWxlKGN1cnJlbnQpe291dC5wdXNoKGN1cnJlbnQpO2N1cnJlbnQ9Y3VycmVudC5uZXh0fXJldHVybiBvdXR9OyhmdW5jdGlvbigpe3RyeXtPYmplY3QuZGVmaW5lUHJvcGVydHkoV3JpdGFibGVTdGF0ZS5wcm90b3R5cGUsXCJidWZmZXJcIix7Z2V0OmludGVybmFsVXRpbC5kZXByZWNhdGUoZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5nZXRCdWZmZXIoKX0sXCJfd3JpdGFibGVTdGF0ZS5idWZmZXIgaXMgZGVwcmVjYXRlZC4gVXNlIF93cml0YWJsZVN0YXRlLmdldEJ1ZmZlciBcIitcImluc3RlYWQuXCIpfSl9Y2F0Y2goXyl7fX0pKCk7dmFyIER1cGxleDtmdW5jdGlvbiBXcml0YWJsZShvcHRpb25zKXtEdXBsZXg9RHVwbGV4fHxyZXF1aXJlKFwiLi9fc3RyZWFtX2R1cGxleFwiKTtpZighKHRoaXMgaW5zdGFuY2VvZiBXcml0YWJsZSkmJiEodGhpcyBpbnN0YW5jZW9mIER1cGxleCkpcmV0dXJuIG5ldyBXcml0YWJsZShvcHRpb25zKTt0aGlzLl93cml0YWJsZVN0YXRlPW5ldyBXcml0YWJsZVN0YXRlKG9wdGlvbnMsdGhpcyk7dGhpcy53cml0YWJsZT10cnVlO2lmKG9wdGlvbnMpe2lmKHR5cGVvZiBvcHRpb25zLndyaXRlPT09XCJmdW5jdGlvblwiKXRoaXMuX3dyaXRlPW9wdGlvbnMud3JpdGU7aWYodHlwZW9mIG9wdGlvbnMud3JpdGV2PT09XCJmdW5jdGlvblwiKXRoaXMuX3dyaXRldj1vcHRpb25zLndyaXRldn1TdHJlYW0uY2FsbCh0aGlzKX1Xcml0YWJsZS5wcm90b3R5cGUucGlwZT1mdW5jdGlvbigpe3RoaXMuZW1pdChcImVycm9yXCIsbmV3IEVycm9yKFwiQ2Fubm90IHBpcGUsIG5vdCByZWFkYWJsZVwiKSl9O2Z1bmN0aW9uIHdyaXRlQWZ0ZXJFbmQoc3RyZWFtLGNiKXt2YXIgZXI9bmV3IEVycm9yKFwid3JpdGUgYWZ0ZXIgZW5kXCIpO3N0cmVhbS5lbWl0KFwiZXJyb3JcIixlcik7cHJvY2Vzc05leHRUaWNrKGNiLGVyKX1mdW5jdGlvbiB2YWxpZENodW5rKHN0cmVhbSxzdGF0ZSxjaHVuayxjYil7dmFyIHZhbGlkPXRydWU7dmFyIGVyPWZhbHNlO2lmKGNodW5rPT09bnVsbCl7ZXI9bmV3IFR5cGVFcnJvcihcIk1heSBub3Qgd3JpdGUgbnVsbCB2YWx1ZXMgdG8gc3RyZWFtXCIpfWVsc2UgaWYoIUJ1ZmZlci5pc0J1ZmZlcihjaHVuaykmJnR5cGVvZiBjaHVuayE9PVwic3RyaW5nXCImJmNodW5rIT09dW5kZWZpbmVkJiYhc3RhdGUub2JqZWN0TW9kZSl7ZXI9bmV3IFR5cGVFcnJvcihcIkludmFsaWQgbm9uLXN0cmluZy9idWZmZXIgY2h1bmtcIil9aWYoZXIpe3N0cmVhbS5lbWl0KFwiZXJyb3JcIixlcik7cHJvY2Vzc05leHRUaWNrKGNiLGVyKTt2YWxpZD1mYWxzZX1yZXR1cm4gdmFsaWR9V3JpdGFibGUucHJvdG90eXBlLndyaXRlPWZ1bmN0aW9uKGNodW5rLGVuY29kaW5nLGNiKXt2YXIgc3RhdGU9dGhpcy5fd3JpdGFibGVTdGF0ZTt2YXIgcmV0PWZhbHNlO2lmKHR5cGVvZiBlbmNvZGluZz09PVwiZnVuY3Rpb25cIil7Y2I9ZW5jb2Rpbmc7ZW5jb2Rpbmc9bnVsbH1pZihCdWZmZXIuaXNCdWZmZXIoY2h1bmspKWVuY29kaW5nPVwiYnVmZmVyXCI7ZWxzZSBpZighZW5jb2RpbmcpZW5jb2Rpbmc9c3RhdGUuZGVmYXVsdEVuY29kaW5nO2lmKHR5cGVvZiBjYiE9PVwiZnVuY3Rpb25cIiljYj1ub3A7aWYoc3RhdGUuZW5kZWQpd3JpdGVBZnRlckVuZCh0aGlzLGNiKTtlbHNlIGlmKHZhbGlkQ2h1bmsodGhpcyxzdGF0ZSxjaHVuayxjYikpe1xuc3RhdGUucGVuZGluZ2NiKys7cmV0PXdyaXRlT3JCdWZmZXIodGhpcyxzdGF0ZSxjaHVuayxlbmNvZGluZyxjYil9cmV0dXJuIHJldH07V3JpdGFibGUucHJvdG90eXBlLmNvcms9ZnVuY3Rpb24oKXt2YXIgc3RhdGU9dGhpcy5fd3JpdGFibGVTdGF0ZTtzdGF0ZS5jb3JrZWQrK307V3JpdGFibGUucHJvdG90eXBlLnVuY29yaz1mdW5jdGlvbigpe3ZhciBzdGF0ZT10aGlzLl93cml0YWJsZVN0YXRlO2lmKHN0YXRlLmNvcmtlZCl7c3RhdGUuY29ya2VkLS07aWYoIXN0YXRlLndyaXRpbmcmJiFzdGF0ZS5jb3JrZWQmJiFzdGF0ZS5maW5pc2hlZCYmIXN0YXRlLmJ1ZmZlclByb2Nlc3NpbmcmJnN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCljbGVhckJ1ZmZlcih0aGlzLHN0YXRlKX19O1dyaXRhYmxlLnByb3RvdHlwZS5zZXREZWZhdWx0RW5jb2Rpbmc9ZnVuY3Rpb24gc2V0RGVmYXVsdEVuY29kaW5nKGVuY29kaW5nKXtpZih0eXBlb2YgZW5jb2Rpbmc9PT1cInN0cmluZ1wiKWVuY29kaW5nPWVuY29kaW5nLnRvTG93ZXJDYXNlKCk7aWYoIShbXCJoZXhcIixcInV0ZjhcIixcInV0Zi04XCIsXCJhc2NpaVwiLFwiYmluYXJ5XCIsXCJiYXNlNjRcIixcInVjczJcIixcInVjcy0yXCIsXCJ1dGYxNmxlXCIsXCJ1dGYtMTZsZVwiLFwicmF3XCJdLmluZGV4T2YoKGVuY29kaW5nK1wiXCIpLnRvTG93ZXJDYXNlKCkpPi0xKSl0aHJvdyBuZXcgVHlwZUVycm9yKFwiVW5rbm93biBlbmNvZGluZzogXCIrZW5jb2RpbmcpO3RoaXMuX3dyaXRhYmxlU3RhdGUuZGVmYXVsdEVuY29kaW5nPWVuY29kaW5nO3JldHVybiB0aGlzfTtmdW5jdGlvbiBkZWNvZGVDaHVuayhzdGF0ZSxjaHVuayxlbmNvZGluZyl7aWYoIXN0YXRlLm9iamVjdE1vZGUmJnN0YXRlLmRlY29kZVN0cmluZ3MhPT1mYWxzZSYmdHlwZW9mIGNodW5rPT09XCJzdHJpbmdcIil7Y2h1bms9YnVmZmVyU2hpbS5mcm9tKGNodW5rLGVuY29kaW5nKX1yZXR1cm4gY2h1bmt9ZnVuY3Rpb24gd3JpdGVPckJ1ZmZlcihzdHJlYW0sc3RhdGUsY2h1bmssZW5jb2RpbmcsY2Ipe2NodW5rPWRlY29kZUNodW5rKHN0YXRlLGNodW5rLGVuY29kaW5nKTtpZihCdWZmZXIuaXNCdWZmZXIoY2h1bmspKWVuY29kaW5nPVwiYnVmZmVyXCI7dmFyIGxlbj1zdGF0ZS5vYmplY3RNb2RlPzE6Y2h1bmsubGVuZ3RoO3N0YXRlLmxlbmd0aCs9bGVuO3ZhciByZXQ9c3RhdGUubGVuZ3RoPHN0YXRlLmhpZ2hXYXRlck1hcms7aWYoIXJldClzdGF0ZS5uZWVkRHJhaW49dHJ1ZTtpZihzdGF0ZS53cml0aW5nfHxzdGF0ZS5jb3JrZWQpe3ZhciBsYXN0PXN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3Q7c3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdD1uZXcgV3JpdGVSZXEoY2h1bmssZW5jb2RpbmcsY2IpO2lmKGxhc3Qpe2xhc3QubmV4dD1zdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0fWVsc2V7c3RhdGUuYnVmZmVyZWRSZXF1ZXN0PXN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3R9c3RhdGUuYnVmZmVyZWRSZXF1ZXN0Q291bnQrPTF9ZWxzZXtkb1dyaXRlKHN0cmVhbSxzdGF0ZSxmYWxzZSxsZW4sY2h1bmssZW5jb2RpbmcsY2IpfXJldHVybiByZXR9ZnVuY3Rpb24gZG9Xcml0ZShzdHJlYW0sc3RhdGUsd3JpdGV2LGxlbixjaHVuayxlbmNvZGluZyxjYil7c3RhdGUud3JpdGVsZW49bGVuO3N0YXRlLndyaXRlY2I9Y2I7c3RhdGUud3JpdGluZz10cnVlO3N0YXRlLnN5bmM9dHJ1ZTtpZih3cml0ZXYpc3RyZWFtLl93cml0ZXYoY2h1bmssc3RhdGUub253cml0ZSk7ZWxzZSBzdHJlYW0uX3dyaXRlKGNodW5rLGVuY29kaW5nLHN0YXRlLm9ud3JpdGUpO3N0YXRlLnN5bmM9ZmFsc2V9ZnVuY3Rpb24gb253cml0ZUVycm9yKHN0cmVhbSxzdGF0ZSxzeW5jLGVyLGNiKXstLXN0YXRlLnBlbmRpbmdjYjtpZihzeW5jKXByb2Nlc3NOZXh0VGljayhjYixlcik7ZWxzZSBjYihlcik7c3RyZWFtLl93cml0YWJsZVN0YXRlLmVycm9yRW1pdHRlZD10cnVlO3N0cmVhbS5lbWl0KFwiZXJyb3JcIixlcil9ZnVuY3Rpb24gb253cml0ZVN0YXRlVXBkYXRlKHN0YXRlKXtzdGF0ZS53cml0aW5nPWZhbHNlO3N0YXRlLndyaXRlY2I9bnVsbDtzdGF0ZS5sZW5ndGgtPXN0YXRlLndyaXRlbGVuO3N0YXRlLndyaXRlbGVuPTB9ZnVuY3Rpb24gb253cml0ZShzdHJlYW0sZXIpe3ZhciBzdGF0ZT1zdHJlYW0uX3dyaXRhYmxlU3RhdGU7dmFyIHN5bmM9c3RhdGUuc3luYzt2YXIgY2I9c3RhdGUud3JpdGVjYjtvbndyaXRlU3RhdGVVcGRhdGUoc3RhdGUpO2lmKGVyKW9ud3JpdGVFcnJvcihzdHJlYW0sc3RhdGUsc3luYyxlcixjYik7ZWxzZXt2YXIgZmluaXNoZWQ9bmVlZEZpbmlzaChzdGF0ZSk7aWYoIWZpbmlzaGVkJiYhc3RhdGUuY29ya2VkJiYhc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyYmc3RhdGUuYnVmZmVyZWRSZXF1ZXN0KXtjbGVhckJ1ZmZlcihzdHJlYW0sc3RhdGUpfWlmKHN5bmMpe2FzeW5jV3JpdGUoYWZ0ZXJXcml0ZSxzdHJlYW0sc3RhdGUsZmluaXNoZWQsY2IpfWVsc2V7YWZ0ZXJXcml0ZShzdHJlYW0sc3RhdGUsZmluaXNoZWQsY2IpfX19ZnVuY3Rpb24gYWZ0ZXJXcml0ZShzdHJlYW0sc3RhdGUsZmluaXNoZWQsY2Ipe2lmKCFmaW5pc2hlZClvbndyaXRlRHJhaW4oc3RyZWFtLHN0YXRlKTtzdGF0ZS5wZW5kaW5nY2ItLTtjYigpO2ZpbmlzaE1heWJlKHN0cmVhbSxzdGF0ZSl9ZnVuY3Rpb24gb253cml0ZURyYWluKHN0cmVhbSxzdGF0ZSl7aWYoc3RhdGUubGVuZ3RoPT09MCYmc3RhdGUubmVlZERyYWluKXtzdGF0ZS5uZWVkRHJhaW49ZmFsc2U7c3RyZWFtLmVtaXQoXCJkcmFpblwiKX19ZnVuY3Rpb24gY2xlYXJCdWZmZXIoc3RyZWFtLHN0YXRlKXtzdGF0ZS5idWZmZXJQcm9jZXNzaW5nPXRydWU7dmFyIGVudHJ5PXN0YXRlLmJ1ZmZlcmVkUmVxdWVzdDtpZihzdHJlYW0uX3dyaXRldiYmZW50cnkmJmVudHJ5Lm5leHQpe3ZhciBsPXN0YXRlLmJ1ZmZlcmVkUmVxdWVzdENvdW50O3ZhciBidWZmZXI9bmV3IEFycmF5KGwpO3ZhciBob2xkZXI9c3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlO2hvbGRlci5lbnRyeT1lbnRyeTt2YXIgY291bnQ9MDt3aGlsZShlbnRyeSl7YnVmZmVyW2NvdW50XT1lbnRyeTtlbnRyeT1lbnRyeS5uZXh0O2NvdW50Kz0xfWRvV3JpdGUoc3RyZWFtLHN0YXRlLHRydWUsc3RhdGUubGVuZ3RoLGJ1ZmZlcixcIlwiLGhvbGRlci5maW5pc2gpO3N0YXRlLnBlbmRpbmdjYisrO3N0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3Q9bnVsbDtpZihob2xkZXIubmV4dCl7c3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlPWhvbGRlci5uZXh0O2hvbGRlci5uZXh0PW51bGx9ZWxzZXtzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWU9bmV3IENvcmtlZFJlcXVlc3Qoc3RhdGUpfX1lbHNle3doaWxlKGVudHJ5KXt2YXIgY2h1bms9ZW50cnkuY2h1bms7dmFyIGVuY29kaW5nPWVudHJ5LmVuY29kaW5nO3ZhciBjYj1lbnRyeS5jYWxsYmFjazt2YXIgbGVuPXN0YXRlLm9iamVjdE1vZGU/MTpjaHVuay5sZW5ndGg7ZG9Xcml0ZShzdHJlYW0sc3RhdGUsZmFsc2UsbGVuLGNodW5rLGVuY29kaW5nLGNiKTtlbnRyeT1lbnRyeS5uZXh0O2lmKHN0YXRlLndyaXRpbmcpe2JyZWFrfX1pZihlbnRyeT09PW51bGwpc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdD1udWxsfXN0YXRlLmJ1ZmZlcmVkUmVxdWVzdENvdW50PTA7c3RhdGUuYnVmZmVyZWRSZXF1ZXN0PWVudHJ5O3N0YXRlLmJ1ZmZlclByb2Nlc3Npbmc9ZmFsc2V9V3JpdGFibGUucHJvdG90eXBlLl93cml0ZT1mdW5jdGlvbihjaHVuayxlbmNvZGluZyxjYil7Y2IobmV3IEVycm9yKFwibm90IGltcGxlbWVudGVkXCIpKX07V3JpdGFibGUucHJvdG90eXBlLl93cml0ZXY9bnVsbDtXcml0YWJsZS5wcm90b3R5cGUuZW5kPWZ1bmN0aW9uKGNodW5rLGVuY29kaW5nLGNiKXt2YXIgc3RhdGU9dGhpcy5fd3JpdGFibGVTdGF0ZTtpZih0eXBlb2YgY2h1bms9PT1cImZ1bmN0aW9uXCIpe2NiPWNodW5rO2NodW5rPW51bGw7ZW5jb2Rpbmc9bnVsbH1lbHNlIGlmKHR5cGVvZiBlbmNvZGluZz09PVwiZnVuY3Rpb25cIil7Y2I9ZW5jb2Rpbmc7ZW5jb2Rpbmc9bnVsbH1pZihjaHVuayE9PW51bGwmJmNodW5rIT09dW5kZWZpbmVkKXRoaXMud3JpdGUoY2h1bmssZW5jb2RpbmcpO2lmKHN0YXRlLmNvcmtlZCl7c3RhdGUuY29ya2VkPTE7dGhpcy51bmNvcmsoKX1pZighc3RhdGUuZW5kaW5nJiYhc3RhdGUuZmluaXNoZWQpZW5kV3JpdGFibGUodGhpcyxzdGF0ZSxjYil9O2Z1bmN0aW9uIG5lZWRGaW5pc2goc3RhdGUpe3JldHVybiBzdGF0ZS5lbmRpbmcmJnN0YXRlLmxlbmd0aD09PTAmJnN0YXRlLmJ1ZmZlcmVkUmVxdWVzdD09PW51bGwmJiFzdGF0ZS5maW5pc2hlZCYmIXN0YXRlLndyaXRpbmd9ZnVuY3Rpb24gcHJlZmluaXNoKHN0cmVhbSxzdGF0ZSl7aWYoIXN0YXRlLnByZWZpbmlzaGVkKXtzdGF0ZS5wcmVmaW5pc2hlZD10cnVlO3N0cmVhbS5lbWl0KFwicHJlZmluaXNoXCIpfX1mdW5jdGlvbiBmaW5pc2hNYXliZShzdHJlYW0sc3RhdGUpe3ZhciBuZWVkPW5lZWRGaW5pc2goc3RhdGUpO2lmKG5lZWQpe2lmKHN0YXRlLnBlbmRpbmdjYj09PTApe3ByZWZpbmlzaChzdHJlYW0sc3RhdGUpO3N0YXRlLmZpbmlzaGVkPXRydWU7c3RyZWFtLmVtaXQoXCJmaW5pc2hcIil9ZWxzZXtwcmVmaW5pc2goc3RyZWFtLHN0YXRlKX19cmV0dXJuIG5lZWR9ZnVuY3Rpb24gZW5kV3JpdGFibGUoc3RyZWFtLHN0YXRlLGNiKXtzdGF0ZS5lbmRpbmc9dHJ1ZTtmaW5pc2hNYXliZShzdHJlYW0sc3RhdGUpO2lmKGNiKXtpZihzdGF0ZS5maW5pc2hlZClwcm9jZXNzTmV4dFRpY2soY2IpO2Vsc2Ugc3RyZWFtLm9uY2UoXCJmaW5pc2hcIixjYil9c3RhdGUuZW5kZWQ9dHJ1ZTtzdHJlYW0ud3JpdGFibGU9ZmFsc2V9ZnVuY3Rpb24gQ29ya2VkUmVxdWVzdChzdGF0ZSl7dmFyIF90aGlzPXRoaXM7dGhpcy5uZXh0PW51bGw7dGhpcy5lbnRyeT1udWxsO3RoaXMuZmluaXNoPWZ1bmN0aW9uKGVycil7dmFyIGVudHJ5PV90aGlzLmVudHJ5O190aGlzLmVudHJ5PW51bGw7d2hpbGUoZW50cnkpe3ZhciBjYj1lbnRyeS5jYWxsYmFjaztzdGF0ZS5wZW5kaW5nY2ItLTtjYihlcnIpO2VudHJ5PWVudHJ5Lm5leHR9aWYoc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlKXtzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWUubmV4dD1fdGhpc31lbHNle3N0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZT1fdGhpc319fX0pLmNhbGwodGhpcyxyZXF1aXJlKFwiX3Byb2Nlc3NcIikpfSx7XCIuL19zdHJlYW1fZHVwbGV4XCI6NDQsX3Byb2Nlc3M6NDIsYnVmZmVyOjUsXCJidWZmZXItc2hpbXNcIjo0LFwiY29yZS11dGlsLWlzXCI6NixldmVudHM6MjgsaW5oZXJpdHM6MzgsXCJwcm9jZXNzLW5leHRpY2stYXJnc1wiOjQxLFwidXRpbC1kZXByZWNhdGVcIjo1N31dLDQ5OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcInVzZSBzdHJpY3RcIjt2YXIgQnVmZmVyPXJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyO3ZhciBidWZmZXJTaGltPXJlcXVpcmUoXCJidWZmZXItc2hpbXNcIik7bW9kdWxlLmV4cG9ydHM9QnVmZmVyTGlzdDtmdW5jdGlvbiBCdWZmZXJMaXN0KCl7dGhpcy5oZWFkPW51bGw7dGhpcy50YWlsPW51bGw7dGhpcy5sZW5ndGg9MH1CdWZmZXJMaXN0LnByb3RvdHlwZS5wdXNoPWZ1bmN0aW9uKHYpe3ZhciBlbnRyeT17ZGF0YTp2LG5leHQ6bnVsbH07aWYodGhpcy5sZW5ndGg+MCl0aGlzLnRhaWwubmV4dD1lbnRyeTtlbHNlIHRoaXMuaGVhZD1lbnRyeTt0aGlzLnRhaWw9ZW50cnk7Kyt0aGlzLmxlbmd0aH07QnVmZmVyTGlzdC5wcm90b3R5cGUudW5zaGlmdD1mdW5jdGlvbih2KXt2YXIgZW50cnk9e2RhdGE6dixuZXh0OnRoaXMuaGVhZH07aWYodGhpcy5sZW5ndGg9PT0wKXRoaXMudGFpbD1lbnRyeTt0aGlzLmhlYWQ9ZW50cnk7Kyt0aGlzLmxlbmd0aH07QnVmZmVyTGlzdC5wcm90b3R5cGUuc2hpZnQ9ZnVuY3Rpb24oKXtpZih0aGlzLmxlbmd0aD09PTApcmV0dXJuO3ZhciByZXQ9dGhpcy5oZWFkLmRhdGE7aWYodGhpcy5sZW5ndGg9PT0xKXRoaXMuaGVhZD10aGlzLnRhaWw9bnVsbDtlbHNlIHRoaXMuaGVhZD10aGlzLmhlYWQubmV4dDstLXRoaXMubGVuZ3RoO3JldHVybiByZXR9O0J1ZmZlckxpc3QucHJvdG90eXBlLmNsZWFyPWZ1bmN0aW9uKCl7dGhpcy5oZWFkPXRoaXMudGFpbD1udWxsO3RoaXMubGVuZ3RoPTB9O0J1ZmZlckxpc3QucHJvdG90eXBlLmpvaW49ZnVuY3Rpb24ocyl7aWYodGhpcy5sZW5ndGg9PT0wKXJldHVyblwiXCI7dmFyIHA9dGhpcy5oZWFkO3ZhciByZXQ9XCJcIitwLmRhdGE7d2hpbGUocD1wLm5leHQpe3JldCs9cytwLmRhdGF9cmV0dXJuIHJldH07QnVmZmVyTGlzdC5wcm90b3R5cGUuY29uY2F0PWZ1bmN0aW9uKG4pe2lmKHRoaXMubGVuZ3RoPT09MClyZXR1cm4gYnVmZmVyU2hpbS5hbGxvYygwKTtpZih0aGlzLmxlbmd0aD09PTEpcmV0dXJuIHRoaXMuaGVhZC5kYXRhO3ZhciByZXQ9YnVmZmVyU2hpbS5hbGxvY1Vuc2FmZShuPj4+MCk7dmFyIHA9dGhpcy5oZWFkO3ZhciBpPTA7d2hpbGUocCl7cC5kYXRhLmNvcHkocmV0LGkpO2krPXAuZGF0YS5sZW5ndGg7cD1wLm5leHR9cmV0dXJuIHJldH19LHtidWZmZXI6NSxcImJ1ZmZlci1zaGltc1wiOjR9XSw1MDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9cmVxdWlyZShcIi4vbGliL19zdHJlYW1fcGFzc3Rocm91Z2guanNcIil9LHtcIi4vbGliL19zdHJlYW1fcGFzc3Rocm91Z2guanNcIjo0NX1dLDUxOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsoZnVuY3Rpb24ocHJvY2Vzcyl7dmFyIFN0cmVhbT1mdW5jdGlvbigpe3RyeXtyZXR1cm4gcmVxdWlyZShcInN0XCIrXCJyZWFtXCIpfWNhdGNoKF8pe319KCk7ZXhwb3J0cz1tb2R1bGUuZXhwb3J0cz1yZXF1aXJlKFwiLi9saWIvX3N0cmVhbV9yZWFkYWJsZS5qc1wiKTtleHBvcnRzLlN0cmVhbT1TdHJlYW18fGV4cG9ydHM7ZXhwb3J0cy5SZWFkYWJsZT1leHBvcnRzO2V4cG9ydHMuV3JpdGFibGU9cmVxdWlyZShcIi4vbGliL19zdHJlYW1fd3JpdGFibGUuanNcIik7ZXhwb3J0cy5EdXBsZXg9cmVxdWlyZShcIi4vbGliL19zdHJlYW1fZHVwbGV4LmpzXCIpO2V4cG9ydHMuVHJhbnNmb3JtPXJlcXVpcmUoXCIuL2xpYi9fc3RyZWFtX3RyYW5zZm9ybS5qc1wiKTtleHBvcnRzLlBhc3NUaHJvdWdoPXJlcXVpcmUoXCIuL2xpYi9fc3RyZWFtX3Bhc3N0aHJvdWdoLmpzXCIpO2lmKCFwcm9jZXNzLmJyb3dzZXImJnByb2Nlc3MuZW52LlJFQURBQkxFX1NUUkVBTT09PVwiZGlzYWJsZVwiJiZTdHJlYW0pe21vZHVsZS5leHBvcnRzPVN0cmVhbX19KS5jYWxsKHRoaXMscmVxdWlyZShcIl9wcm9jZXNzXCIpKX0se1wiLi9saWIvX3N0cmVhbV9kdXBsZXguanNcIjo0NCxcIi4vbGliL19zdHJlYW1fcGFzc3Rocm91Z2guanNcIjo0NSxcIi4vbGliL19zdHJlYW1fcmVhZGFibGUuanNcIjo0NixcIi4vbGliL19zdHJlYW1fdHJhbnNmb3JtLmpzXCI6NDcsXCIuL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzXCI6NDgsX3Byb2Nlc3M6NDJ9XSw1MjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9cmVxdWlyZShcIi4vbGliL19zdHJlYW1fdHJhbnNmb3JtLmpzXCIpfSx7XCIuL2xpYi9fc3RyZWFtX3RyYW5zZm9ybS5qc1wiOjQ3fV0sNTM6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe21vZHVsZS5leHBvcnRzPXJlcXVpcmUoXCIuL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzXCIpfSx7XCIuL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzXCI6NDh9XSw1NDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9ZnVuY3Rpb24oc3RyaW5nKXtyZXR1cm4gc3RyaW5nLnJlcGxhY2UoL1stXFxcXF4kKis/LigpfFtcXF17fV0vZyxcIlxcXFwkJlwiKX19LHt9XSw1NTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9U3RyZWFtO3ZhciBFRT1yZXF1aXJlKFwiZXZlbnRzXCIpLkV2ZW50RW1pdHRlcjt2YXIgaW5oZXJpdHM9cmVxdWlyZShcImluaGVyaXRzXCIpO2luaGVyaXRzKFN0cmVhbSxFRSk7U3RyZWFtLlJlYWRhYmxlPXJlcXVpcmUoXCJyZWFkYWJsZS1zdHJlYW0vcmVhZGFibGUuanNcIik7U3RyZWFtLldyaXRhYmxlPXJlcXVpcmUoXCJyZWFkYWJsZS1zdHJlYW0vd3JpdGFibGUuanNcIik7U3RyZWFtLkR1cGxleD1yZXF1aXJlKFwicmVhZGFibGUtc3RyZWFtL2R1cGxleC5qc1wiKTtTdHJlYW0uVHJhbnNmb3JtPXJlcXVpcmUoXCJyZWFkYWJsZS1zdHJlYW0vdHJhbnNmb3JtLmpzXCIpO1N0cmVhbS5QYXNzVGhyb3VnaD1yZXF1aXJlKFwicmVhZGFibGUtc3RyZWFtL3Bhc3N0aHJvdWdoLmpzXCIpO1N0cmVhbS5TdHJlYW09U3RyZWFtO2Z1bmN0aW9uIFN0cmVhbSgpe0VFLmNhbGwodGhpcyl9U3RyZWFtLnByb3RvdHlwZS5waXBlPWZ1bmN0aW9uKGRlc3Qsb3B0aW9ucyl7dmFyIHNvdXJjZT10aGlzO2Z1bmN0aW9uIG9uZGF0YShjaHVuayl7aWYoZGVzdC53cml0YWJsZSl7aWYoZmFsc2U9PT1kZXN0LndyaXRlKGNodW5rKSYmc291cmNlLnBhdXNlKXtzb3VyY2UucGF1c2UoKX19fXNvdXJjZS5vbihcImRhdGFcIixvbmRhdGEpO2Z1bmN0aW9uIG9uZHJhaW4oKXtpZihzb3VyY2UucmVhZGFibGUmJnNvdXJjZS5yZXN1bWUpe3NvdXJjZS5yZXN1bWUoKX19ZGVzdC5vbihcImRyYWluXCIsb25kcmFpbik7aWYoIWRlc3QuX2lzU3RkaW8mJighb3B0aW9uc3x8b3B0aW9ucy5lbmQhPT1mYWxzZSkpe3NvdXJjZS5vbihcImVuZFwiLG9uZW5kKTtzb3VyY2Uub24oXCJjbG9zZVwiLG9uY2xvc2UpfXZhciBkaWRPbkVuZD1mYWxzZTtmdW5jdGlvbiBvbmVuZCgpe2lmKGRpZE9uRW5kKXJldHVybjtkaWRPbkVuZD10cnVlO2Rlc3QuZW5kKCl9ZnVuY3Rpb24gb25jbG9zZSgpe2lmKGRpZE9uRW5kKXJldHVybjtkaWRPbkVuZD10cnVlO2lmKHR5cGVvZiBkZXN0LmRlc3Ryb3k9PT1cImZ1bmN0aW9uXCIpZGVzdC5kZXN0cm95KCl9ZnVuY3Rpb24gb25lcnJvcihlcil7Y2xlYW51cCgpO2lmKEVFLmxpc3RlbmVyQ291bnQodGhpcyxcImVycm9yXCIpPT09MCl7dGhyb3cgZXJ9fXNvdXJjZS5vbihcImVycm9yXCIsb25lcnJvcik7ZGVzdC5vbihcImVycm9yXCIsb25lcnJvcik7ZnVuY3Rpb24gY2xlYW51cCgpe3NvdXJjZS5yZW1vdmVMaXN0ZW5lcihcImRhdGFcIixvbmRhdGEpO2Rlc3QucmVtb3ZlTGlzdGVuZXIoXCJkcmFpblwiLG9uZHJhaW4pO3NvdXJjZS5yZW1vdmVMaXN0ZW5lcihcImVuZFwiLG9uZW5kKTtzb3VyY2UucmVtb3ZlTGlzdGVuZXIoXCJjbG9zZVwiLG9uY2xvc2UpO3NvdXJjZS5yZW1vdmVMaXN0ZW5lcihcImVycm9yXCIsb25lcnJvcik7ZGVzdC5yZW1vdmVMaXN0ZW5lcihcImVycm9yXCIsb25lcnJvcik7c291cmNlLnJlbW92ZUxpc3RlbmVyKFwiZW5kXCIsY2xlYW51cCk7c291cmNlLnJlbW92ZUxpc3RlbmVyKFwiY2xvc2VcIixjbGVhbnVwKTtkZXN0LnJlbW92ZUxpc3RlbmVyKFwiY2xvc2VcIixjbGVhbnVwKX1zb3VyY2Uub24oXCJlbmRcIixjbGVhbnVwKTtzb3VyY2Uub24oXCJjbG9zZVwiLGNsZWFudXApO2Rlc3Qub24oXCJjbG9zZVwiLGNsZWFudXApO2Rlc3QuZW1pdChcInBpcGVcIixzb3VyY2UpO3JldHVybiBkZXN0fX0se2V2ZW50czoyOCxpbmhlcml0czozOCxcInJlYWRhYmxlLXN0cmVhbS9kdXBsZXguanNcIjo0MyxcInJlYWRhYmxlLXN0cmVhbS9wYXNzdGhyb3VnaC5qc1wiOjUwLFwicmVhZGFibGUtc3RyZWFtL3JlYWRhYmxlLmpzXCI6NTEsXCJyZWFkYWJsZS1zdHJlYW0vdHJhbnNmb3JtLmpzXCI6NTIsXCJyZWFkYWJsZS1zdHJlYW0vd3JpdGFibGUuanNcIjo1M31dLDU2OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgQnVmZmVyPXJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyO3ZhciBpc0J1ZmZlckVuY29kaW5nPUJ1ZmZlci5pc0VuY29kaW5nfHxmdW5jdGlvbihlbmNvZGluZyl7c3dpdGNoKGVuY29kaW5nJiZlbmNvZGluZy50b0xvd2VyQ2FzZSgpKXtjYXNlXCJoZXhcIjpjYXNlXCJ1dGY4XCI6Y2FzZVwidXRmLThcIjpjYXNlXCJhc2NpaVwiOmNhc2VcImJpbmFyeVwiOmNhc2VcImJhc2U2NFwiOmNhc2VcInVjczJcIjpjYXNlXCJ1Y3MtMlwiOmNhc2VcInV0ZjE2bGVcIjpjYXNlXCJ1dGYtMTZsZVwiOmNhc2VcInJhd1wiOnJldHVybiB0cnVlO2RlZmF1bHQ6cmV0dXJuIGZhbHNlfX07ZnVuY3Rpb24gYXNzZXJ0RW5jb2RpbmcoZW5jb2Rpbmcpe2lmKGVuY29kaW5nJiYhaXNCdWZmZXJFbmNvZGluZyhlbmNvZGluZykpe3Rocm93IG5ldyBFcnJvcihcIlVua25vd24gZW5jb2Rpbmc6IFwiK2VuY29kaW5nKX19dmFyIFN0cmluZ0RlY29kZXI9ZXhwb3J0cy5TdHJpbmdEZWNvZGVyPWZ1bmN0aW9uKGVuY29kaW5nKXt0aGlzLmVuY29kaW5nPShlbmNvZGluZ3x8XCJ1dGY4XCIpLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvWy1fXS8sXCJcIik7YXNzZXJ0RW5jb2RpbmcoZW5jb2RpbmcpO3N3aXRjaCh0aGlzLmVuY29kaW5nKXtjYXNlXCJ1dGY4XCI6dGhpcy5zdXJyb2dhdGVTaXplPTM7YnJlYWs7Y2FzZVwidWNzMlwiOmNhc2VcInV0ZjE2bGVcIjp0aGlzLnN1cnJvZ2F0ZVNpemU9Mjt0aGlzLmRldGVjdEluY29tcGxldGVDaGFyPXV0ZjE2RGV0ZWN0SW5jb21wbGV0ZUNoYXI7YnJlYWs7Y2FzZVwiYmFzZTY0XCI6dGhpcy5zdXJyb2dhdGVTaXplPTM7dGhpcy5kZXRlY3RJbmNvbXBsZXRlQ2hhcj1iYXNlNjREZXRlY3RJbmNvbXBsZXRlQ2hhcjticmVhaztkZWZhdWx0OnRoaXMud3JpdGU9cGFzc1Rocm91Z2hXcml0ZTtyZXR1cm59dGhpcy5jaGFyQnVmZmVyPW5ldyBCdWZmZXIoNik7dGhpcy5jaGFyUmVjZWl2ZWQ9MDt0aGlzLmNoYXJMZW5ndGg9MH07U3RyaW5nRGVjb2Rlci5wcm90b3R5cGUud3JpdGU9ZnVuY3Rpb24oYnVmZmVyKXt2YXIgY2hhclN0cj1cIlwiO3doaWxlKHRoaXMuY2hhckxlbmd0aCl7dmFyIGF2YWlsYWJsZT1idWZmZXIubGVuZ3RoPj10aGlzLmNoYXJMZW5ndGgtdGhpcy5jaGFyUmVjZWl2ZWQ/dGhpcy5jaGFyTGVuZ3RoLXRoaXMuY2hhclJlY2VpdmVkOmJ1ZmZlci5sZW5ndGg7YnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLHRoaXMuY2hhclJlY2VpdmVkLDAsYXZhaWxhYmxlKTt0aGlzLmNoYXJSZWNlaXZlZCs9YXZhaWxhYmxlO2lmKHRoaXMuY2hhclJlY2VpdmVkPHRoaXMuY2hhckxlbmd0aCl7cmV0dXJuXCJcIn1idWZmZXI9YnVmZmVyLnNsaWNlKGF2YWlsYWJsZSxidWZmZXIubGVuZ3RoKTtjaGFyU3RyPXRoaXMuY2hhckJ1ZmZlci5zbGljZSgwLHRoaXMuY2hhckxlbmd0aCkudG9TdHJpbmcodGhpcy5lbmNvZGluZyk7dmFyIGNoYXJDb2RlPWNoYXJTdHIuY2hhckNvZGVBdChjaGFyU3RyLmxlbmd0aC0xKTtpZihjaGFyQ29kZT49NTUyOTYmJmNoYXJDb2RlPD01NjMxOSl7dGhpcy5jaGFyTGVuZ3RoKz10aGlzLnN1cnJvZ2F0ZVNpemU7Y2hhclN0cj1cIlwiO2NvbnRpbnVlfXRoaXMuY2hhclJlY2VpdmVkPXRoaXMuY2hhckxlbmd0aD0wO2lmKGJ1ZmZlci5sZW5ndGg9PT0wKXtyZXR1cm4gY2hhclN0cn1icmVha310aGlzLmRldGVjdEluY29tcGxldGVDaGFyKGJ1ZmZlcik7dmFyIGVuZD1idWZmZXIubGVuZ3RoO2lmKHRoaXMuY2hhckxlbmd0aCl7YnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLDAsYnVmZmVyLmxlbmd0aC10aGlzLmNoYXJSZWNlaXZlZCxlbmQpO2VuZC09dGhpcy5jaGFyUmVjZWl2ZWR9Y2hhclN0cis9YnVmZmVyLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcsMCxlbmQpO3ZhciBlbmQ9Y2hhclN0ci5sZW5ndGgtMTt2YXIgY2hhckNvZGU9Y2hhclN0ci5jaGFyQ29kZUF0KGVuZCk7aWYoY2hhckNvZGU+PTU1Mjk2JiZjaGFyQ29kZTw9NTYzMTkpe3ZhciBzaXplPXRoaXMuc3Vycm9nYXRlU2l6ZTt0aGlzLmNoYXJMZW5ndGgrPXNpemU7dGhpcy5jaGFyUmVjZWl2ZWQrPXNpemU7dGhpcy5jaGFyQnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLHNpemUsMCxzaXplKTtidWZmZXIuY29weSh0aGlzLmNoYXJCdWZmZXIsMCwwLHNpemUpO3JldHVybiBjaGFyU3RyLnN1YnN0cmluZygwLGVuZCl9cmV0dXJuIGNoYXJTdHJ9O1N0cmluZ0RlY29kZXIucHJvdG90eXBlLmRldGVjdEluY29tcGxldGVDaGFyPWZ1bmN0aW9uKGJ1ZmZlcil7dmFyIGk9YnVmZmVyLmxlbmd0aD49Mz8zOmJ1ZmZlci5sZW5ndGg7Zm9yKDtpPjA7aS0tKXt2YXIgYz1idWZmZXJbYnVmZmVyLmxlbmd0aC1pXTtpZihpPT0xJiZjPj41PT02KXt0aGlzLmNoYXJMZW5ndGg9MjticmVha31pZihpPD0yJiZjPj40PT0xNCl7dGhpcy5jaGFyTGVuZ3RoPTM7YnJlYWt9aWYoaTw9MyYmYz4+Mz09MzApe3RoaXMuY2hhckxlbmd0aD00O2JyZWFrfX10aGlzLmNoYXJSZWNlaXZlZD1pfTtTdHJpbmdEZWNvZGVyLnByb3RvdHlwZS5lbmQ9ZnVuY3Rpb24oYnVmZmVyKXt2YXIgcmVzPVwiXCI7aWYoYnVmZmVyJiZidWZmZXIubGVuZ3RoKXJlcz10aGlzLndyaXRlKGJ1ZmZlcik7aWYodGhpcy5jaGFyUmVjZWl2ZWQpe3ZhciBjcj10aGlzLmNoYXJSZWNlaXZlZDt2YXIgYnVmPXRoaXMuY2hhckJ1ZmZlcjt2YXIgZW5jPXRoaXMuZW5jb2Rpbmc7cmVzKz1idWYuc2xpY2UoMCxjcikudG9TdHJpbmcoZW5jKX1yZXR1cm4gcmVzfTtmdW5jdGlvbiBwYXNzVGhyb3VnaFdyaXRlKGJ1ZmZlcil7cmV0dXJuIGJ1ZmZlci50b1N0cmluZyh0aGlzLmVuY29kaW5nKX1mdW5jdGlvbiB1dGYxNkRldGVjdEluY29tcGxldGVDaGFyKGJ1ZmZlcil7dGhpcy5jaGFyUmVjZWl2ZWQ9YnVmZmVyLmxlbmd0aCUyO3RoaXMuY2hhckxlbmd0aD10aGlzLmNoYXJSZWNlaXZlZD8yOjB9ZnVuY3Rpb24gYmFzZTY0RGV0ZWN0SW5jb21wbGV0ZUNoYXIoYnVmZmVyKXt0aGlzLmNoYXJSZWNlaXZlZD1idWZmZXIubGVuZ3RoJTM7dGhpcy5jaGFyTGVuZ3RoPXRoaXMuY2hhclJlY2VpdmVkPzM6MH19LHtidWZmZXI6NX1dLDU3OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsoZnVuY3Rpb24oZ2xvYmFsKXttb2R1bGUuZXhwb3J0cz1kZXByZWNhdGU7ZnVuY3Rpb24gZGVwcmVjYXRlKGZuLG1zZyl7aWYoY29uZmlnKFwibm9EZXByZWNhdGlvblwiKSl7cmV0dXJuIGZufXZhciB3YXJuZWQ9ZmFsc2U7ZnVuY3Rpb24gZGVwcmVjYXRlZCgpe2lmKCF3YXJuZWQpe2lmKGNvbmZpZyhcInRocm93RGVwcmVjYXRpb25cIikpe3Rocm93IG5ldyBFcnJvcihtc2cpfWVsc2UgaWYoY29uZmlnKFwidHJhY2VEZXByZWNhdGlvblwiKSl7Y29uc29sZS50cmFjZShtc2cpfWVsc2V7Y29uc29sZS53YXJuKG1zZyl9d2FybmVkPXRydWV9cmV0dXJuIGZuLmFwcGx5KHRoaXMsYXJndW1lbnRzKX1yZXR1cm4gZGVwcmVjYXRlZH1mdW5jdGlvbiBjb25maWcobmFtZSl7dHJ5e2lmKCFnbG9iYWwubG9jYWxTdG9yYWdlKXJldHVybiBmYWxzZX1jYXRjaChfKXtyZXR1cm4gZmFsc2V9dmFyIHZhbD1nbG9iYWwubG9jYWxTdG9yYWdlW25hbWVdO2lmKG51bGw9PXZhbClyZXR1cm4gZmFsc2U7cmV0dXJuIFN0cmluZyh2YWwpLnRvTG93ZXJDYXNlKCk9PT1cInRydWVcIn19KS5jYWxsKHRoaXMsdHlwZW9mIGdsb2JhbCE9PVwidW5kZWZpbmVkXCI/Z2xvYmFsOnR5cGVvZiBzZWxmIT09XCJ1bmRlZmluZWRcIj9zZWxmOnR5cGVvZiB3aW5kb3chPT1cInVuZGVmaW5lZFwiP3dpbmRvdzp7fSl9LHt9XSw1ODpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9ZXh0ZW5kO3ZhciBoYXNPd25Qcm9wZXJ0eT1PYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O2Z1bmN0aW9uIGV4dGVuZCgpe3ZhciB0YXJnZXQ9e307Zm9yKHZhciBpPTA7aTxhcmd1bWVudHMubGVuZ3RoO2krKyl7dmFyIHNvdXJjZT1hcmd1bWVudHNbaV07Zm9yKHZhciBrZXkgaW4gc291cmNlKXtpZihoYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSxrZXkpKXt0YXJnZXRba2V5XT1zb3VyY2Vba2V5XX19fXJldHVybiB0YXJnZXR9fSx7fV19LHt9LFsxXSkoMSl9KTtcbiIsIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXV0aCA9IHJlcXVpcmUoJy4vbGliL2F1dGgnKTtcbnZhciBoZWxwZXJzID0gcmVxdWlyZSgnLi9saWIvaGVscGVycycpO1xudmFyIFN3YWdnZXJDbGllbnQgPSByZXF1aXJlKCcuL2xpYi9jbGllbnQnKTtcbnZhciBkZXByZWNhdGlvbldyYXBwZXIgPSBmdW5jdGlvbiAodXJsLCBvcHRpb25zKSB7XG4gIGhlbHBlcnMubG9nKCdUaGlzIGlzIGRlcHJlY2F0ZWQsIHVzZSBcIm5ldyBTd2FnZ2VyQ2xpZW50XCIgaW5zdGVhZC4nKTtcblxuICByZXR1cm4gbmV3IFN3YWdnZXJDbGllbnQodXJsLCBvcHRpb25zKTtcbn07XG5cbi8qIEhlcmUgZm9yIElFOCBTdXBwb3J0ICovXG5pZiAoIUFycmF5LnByb3RvdHlwZS5pbmRleE9mKSB7XG4gIEFycmF5LnByb3RvdHlwZS5pbmRleE9mID0gZnVuY3Rpb24ob2JqLCBzdGFydCkge1xuICAgIGZvciAodmFyIGkgPSAoc3RhcnQgfHwgMCksIGogPSB0aGlzLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuICAgICAgaWYgKHRoaXNbaV0gPT09IG9iaikgeyByZXR1cm4gaTsgfVxuICAgIH1cbiAgICByZXR1cm4gLTE7XG4gIH07XG59XG5cbi8qIEhlcmUgZm9yIElFOCBTdXBwb3J0ICovXG5pZiAoIVN0cmluZy5wcm90b3R5cGUudHJpbSkge1xuICBTdHJpbmcucHJvdG90eXBlLnRyaW0gPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgJycpO1xuICB9O1xufVxuXG4vKiBIZXJlIGZvciBub2RlIDEwLnggc3VwcG9ydCAqL1xuaWYgKCFTdHJpbmcucHJvdG90eXBlLmVuZHNXaXRoKSB7XG4gIFN0cmluZy5wcm90b3R5cGUuZW5kc1dpdGggPSBmdW5jdGlvbihzdWZmaXgpIHtcbiAgICByZXR1cm4gdGhpcy5pbmRleE9mKHN1ZmZpeCwgdGhpcy5sZW5ndGggLSBzdWZmaXgubGVuZ3RoKSAhPT0gLTE7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gU3dhZ2dlckNsaWVudDtcblxuU3dhZ2dlckNsaWVudC5BcGlLZXlBdXRob3JpemF0aW9uID0gYXV0aC5BcGlLZXlBdXRob3JpemF0aW9uO1xuU3dhZ2dlckNsaWVudC5QYXNzd29yZEF1dGhvcml6YXRpb24gPSBhdXRoLlBhc3N3b3JkQXV0aG9yaXphdGlvbjtcblN3YWdnZXJDbGllbnQuQ29va2llQXV0aG9yaXphdGlvbiA9IGF1dGguQ29va2llQXV0aG9yaXphdGlvbjtcblN3YWdnZXJDbGllbnQuU3dhZ2dlckFwaSA9IGRlcHJlY2F0aW9uV3JhcHBlcjtcblN3YWdnZXJDbGllbnQuU3dhZ2dlckNsaWVudCA9IGRlcHJlY2F0aW9uV3JhcHBlcjtcblN3YWdnZXJDbGllbnQuU2NoZW1hTWFya3VwID0gcmVxdWlyZSgnLi9saWIvc2NoZW1hLW1hcmt1cCcpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4vaGVscGVycycpO1xudmFyIGJ0b2EgPSByZXF1aXJlKCdidG9hJyk7IC8vIGpzaGludCBpZ25vcmU6bGluZVxudmFyIENvb2tpZUphciA9IHJlcXVpcmUoJ2Nvb2tpZWphcicpLkNvb2tpZUphcjtcbnZhciBfID0ge1xuICBlYWNoOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2NvbGxlY3Rpb24vZWFjaCcpLFxuICBpbmNsdWRlczogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2luY2x1ZGVzJyksXG4gIGlzT2JqZWN0OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNPYmplY3QnKSxcbiAgaXNBcnJheTogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzQXJyYXknKVxufTtcblxuLyoqXG4gKiBTd2FnZ2VyQXV0aG9yaXphdGlvbnMgYXBwbGllcyB0aGUgY29ycmVjdCBhdXRob3JpemF0aW9uIHRvIGFuIG9wZXJhdGlvbiBiZWluZyBleGVjdXRlZFxuICovXG52YXIgU3dhZ2dlckF1dGhvcml6YXRpb25zID0gbW9kdWxlLmV4cG9ydHMuU3dhZ2dlckF1dGhvcml6YXRpb25zID0gZnVuY3Rpb24gKGF1dGh6KSB7XG4gIHRoaXMuYXV0aHogPSBhdXRoeiB8fCB7fTtcbn07XG5cbi8qKlxuICogQWRkIGF1dGhzIHRvIHRoZSBoYXNoXG4gKiBXaWxsIG92ZXJ3cml0ZSBhbnkgZXhpc3RpbmdcbiAqXG4gKi9cblN3YWdnZXJBdXRob3JpemF0aW9ucy5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gKG5hbWUsIGF1dGgpIHtcbiAgaWYoXy5pc09iamVjdChuYW1lKSkge1xuICAgIGZvciAodmFyIGtleSBpbiBuYW1lKSB7XG4gICAgICB0aGlzLmF1dGh6W2tleV0gPSBuYW1lW2tleV07XG4gICAgfVxuICB9IGVsc2UgaWYodHlwZW9mIG5hbWUgPT09ICdzdHJpbmcnICl7XG4gICAgdGhpcy5hdXRoeltuYW1lXSA9IGF1dGg7XG4gIH1cblxuICByZXR1cm4gYXV0aDtcbn07XG5cblN3YWdnZXJBdXRob3JpemF0aW9ucy5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgcmV0dXJuIGRlbGV0ZSB0aGlzLmF1dGh6W25hbWVdO1xufTtcblxuU3dhZ2dlckF1dGhvcml6YXRpb25zLnByb3RvdHlwZS5hcHBseSA9IGZ1bmN0aW9uIChvYmosIHNlY3VyaXRpZXMpIHtcbiAgdmFyIHN0YXR1cyA9IHRydWU7XG4gIHZhciBhcHBseUFsbCA9ICFzZWN1cml0aWVzO1xuICB2YXIgZmxhdHRlbmVkU2VjdXJpdGllcyA9IFtdO1xuXG4gIC8vIGZhdm9yIHRoZSBvYmplY3QtbGV2ZWwgYXV0aG9yaXphdGlvbnMgb3ZlciBnbG9iYWxcbiAgdmFyIGF1dGh6ID0gb2JqLmNsaWVudEF1dGhvcml6YXRpb25zIHx8IHRoaXMuYXV0aHo7XG5cbiAgLy8gU2VjdXJpdGllcyBjb3VsZCBiZSBbIHt9IF1cbiAgXy5lYWNoKHNlY3VyaXRpZXMsIGZ1bmN0aW9uIChvYmosIGtleSkge1xuXG4gICAgLy8gTWFrZSBzdXJlIHdlIGFjY291bnQgZm9yIHNlY3VyaXRpZXMgYmVpbmcgWyBzdHIgXVxuICAgIGlmKHR5cGVvZiBrZXkgPT09ICdzdHJpbmcnKSB7XG4gICAgICBmbGF0dGVuZWRTZWN1cml0aWVzLnB1c2goa2V5KTtcbiAgICB9XG5cbiAgICAvLyBGbGF0dGVuIGtleXMgaW4gdG8gb3VyIGFycmF5XG4gICAgXy5lYWNoKG9iaiwgZnVuY3Rpb24gKHZhbCwga2V5KSB7XG4gICAgICBmbGF0dGVuZWRTZWN1cml0aWVzLnB1c2goa2V5KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgXy5lYWNoKGF1dGh6LCBmdW5jdGlvbiAoYXV0aCwgYXV0aE5hbWUpIHtcbiAgICBpZihhcHBseUFsbCB8fCBfLmluY2x1ZGVzKGZsYXR0ZW5lZFNlY3VyaXRpZXMsIGF1dGhOYW1lKSkge1xuICAgICAgdmFyIG5ld1N0YXR1cyA9IGF1dGguYXBwbHkob2JqKTtcbiAgICAgIHN0YXR1cyA9IHN0YXR1cyAmJiAhIW5ld1N0YXR1czsgLy8gbG9naWNhbCBPUnMgcmVnYXJkaW5nIHN0YXR1c1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHN0YXR1cztcbn07XG5cbi8qKlxuICogQXBpS2V5QXV0aG9yaXphdGlvbiBhbGxvd3MgYSBxdWVyeSBwYXJhbSBvciBoZWFkZXIgdG8gYmUgaW5qZWN0ZWRcbiAqL1xudmFyIEFwaUtleUF1dGhvcml6YXRpb24gPSBtb2R1bGUuZXhwb3J0cy5BcGlLZXlBdXRob3JpemF0aW9uID0gZnVuY3Rpb24gKG5hbWUsIHZhbHVlLCB0eXBlKSB7XG4gIHRoaXMubmFtZSA9IG5hbWU7XG4gIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgdGhpcy50eXBlID0gdHlwZTtcbn07XG5cbkFwaUtleUF1dGhvcml6YXRpb24ucHJvdG90eXBlLmFwcGx5ID0gZnVuY3Rpb24gKG9iaikge1xuICBpZiAodGhpcy50eXBlID09PSAncXVlcnknKSB7XG4gICAgLy8gc2VlIGlmIGFscmVhZHkgYXBwbGllZC4gIElmIHNvLCBkb24ndCBkbyBpdCBhZ2FpblxuXG4gICAgdmFyIHFwO1xuICAgIGlmIChvYmoudXJsLmluZGV4T2YoJz8nKSA+IDApIHtcbiAgICAgIHFwID0gb2JqLnVybC5zdWJzdHJpbmcob2JqLnVybC5pbmRleE9mKCc/JykgKyAxKTtcbiAgICAgIHZhciBwYXJ0cyA9IHFwLnNwbGl0KCcmJyk7XG4gICAgICBpZihwYXJ0cyAmJiBwYXJ0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBwYXJ0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIHZhciBrdiA9IHBhcnRzW2ldLnNwbGl0KCc9Jyk7XG4gICAgICAgICAgaWYoa3YgJiYga3YubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgaWYgKGt2WzBdID09PSB0aGlzLm5hbWUpIHtcbiAgICAgICAgICAgICAgLy8gc2tpcCBpdFxuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG9iai51cmwuaW5kZXhPZignPycpID4gMCkge1xuICAgICAgb2JqLnVybCA9IG9iai51cmwgKyAnJicgKyB0aGlzLm5hbWUgKyAnPScgKyB0aGlzLnZhbHVlO1xuICAgIH0gZWxzZSB7XG4gICAgICBvYmoudXJsID0gb2JqLnVybCArICc/JyArIHRoaXMubmFtZSArICc9JyArIHRoaXMudmFsdWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH0gZWxzZSBpZiAodGhpcy50eXBlID09PSAnaGVhZGVyJykge1xuICAgIGlmKHR5cGVvZiBvYmouaGVhZGVyc1t0aGlzLm5hbWVdID09PSAndW5kZWZpbmVkJykge1xuICAgICAgb2JqLmhlYWRlcnNbdGhpcy5uYW1lXSA9IHRoaXMudmFsdWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbn07XG5cbnZhciBDb29raWVBdXRob3JpemF0aW9uID0gbW9kdWxlLmV4cG9ydHMuQ29va2llQXV0aG9yaXphdGlvbiA9IGZ1bmN0aW9uIChjb29raWUpIHtcbiAgdGhpcy5jb29raWUgPSBjb29raWU7XG59O1xuXG5Db29raWVBdXRob3JpemF0aW9uLnByb3RvdHlwZS5hcHBseSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgb2JqLmNvb2tpZUphciA9IG9iai5jb29raWVKYXIgfHwgbmV3IENvb2tpZUphcigpO1xuICBvYmouY29va2llSmFyLnNldENvb2tpZSh0aGlzLmNvb2tpZSk7XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG4vKipcbiAqIFBhc3N3b3JkIEF1dGhvcml6YXRpb24gaXMgYSBiYXNpYyBhdXRoIGltcGxlbWVudGF0aW9uXG4gKi9cbnZhciBQYXNzd29yZEF1dGhvcml6YXRpb24gPSBtb2R1bGUuZXhwb3J0cy5QYXNzd29yZEF1dGhvcml6YXRpb24gPSBmdW5jdGlvbiAodXNlcm5hbWUsIHBhc3N3b3JkKSB7XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAzKSB7XG4gICAgaGVscGVycy5sb2coJ1Bhc3N3b3JkQXV0aG9yaXphdGlvbjogdGhlIFxcJ25hbWVcXCcgYXJndW1lbnQgaGFzIGJlZW4gcmVtb3ZlZCwgcGFzcyBvbmx5IHVzZXJuYW1lIGFuZCBwYXNzd29yZCcpO1xuICAgIHVzZXJuYW1lID0gYXJndW1lbnRzWzFdO1xuICAgIHBhc3N3b3JkID0gYXJndW1lbnRzWzJdO1xuICB9XG4gIHRoaXMudXNlcm5hbWUgPSB1c2VybmFtZTtcbiAgdGhpcy5wYXNzd29yZCA9IHBhc3N3b3JkO1xufTtcblxuUGFzc3dvcmRBdXRob3JpemF0aW9uLnByb3RvdHlwZS5hcHBseSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgaWYodHlwZW9mIG9iai5oZWFkZXJzLkF1dGhvcml6YXRpb24gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgb2JqLmhlYWRlcnMuQXV0aG9yaXphdGlvbiA9ICdCYXNpYyAnICsgYnRvYSh0aGlzLnVzZXJuYW1lICsgJzonICsgdGhpcy5wYXNzd29yZCk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBfID0ge1xuICBiaW5kOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2Z1bmN0aW9uL2JpbmQnKSxcbiAgY2xvbmVEZWVwOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvY2xvbmVEZWVwJyksXG4gIGZpbmQ6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9maW5kJyksXG4gIGZvckVhY2g6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9mb3JFYWNoJyksXG4gIGluZGV4T2Y6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvYXJyYXkvaW5kZXhPZicpLFxuICBpc0FycmF5OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNBcnJheScpLFxuICBpc09iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzT2JqZWN0JyksXG4gIGlzRnVuY3Rpb246IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc0Z1bmN0aW9uJyksXG4gIGlzUGxhaW5PYmplY3Q6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc1BsYWluT2JqZWN0JyksXG4gIGlzVW5kZWZpbmVkOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNVbmRlZmluZWQnKVxufTtcbnZhciBhdXRoID0gcmVxdWlyZSgnLi9hdXRoJyk7XG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4vaGVscGVycycpO1xudmFyIE1vZGVsID0gcmVxdWlyZSgnLi90eXBlcy9tb2RlbCcpO1xudmFyIE9wZXJhdGlvbiA9IHJlcXVpcmUoJy4vdHlwZXMvb3BlcmF0aW9uJyk7XG52YXIgT3BlcmF0aW9uR3JvdXAgPSByZXF1aXJlKCcuL3R5cGVzL29wZXJhdGlvbkdyb3VwJyk7XG52YXIgUmVzb2x2ZXIgPSByZXF1aXJlKCcuL3Jlc29sdmVyJyk7XG52YXIgU3dhZ2dlckh0dHAgPSByZXF1aXJlKCcuL2h0dHAnKTtcbnZhciBTd2FnZ2VyU3BlY0NvbnZlcnRlciA9IHJlcXVpcmUoJy4vc3BlYy1jb252ZXJ0ZXInKTtcbnZhciBRID0gcmVxdWlyZSgncScpO1xuXG4vLyBXZSBoYXZlIHRvIGtlZXAgdHJhY2sgb2YgdGhlIGZ1bmN0aW9uL3Byb3BlcnR5IG5hbWVzIHRvIGF2b2lkIGNvbGxpc2lvbnMgZm9yIHRhZyBuYW1lcyB3aGljaCBhcmUgdXNlZCB0byBhbGxvdyB0aGVcbi8vIGZvbGxvd2luZyB1c2FnZTogJ2NsaWVudC57dGFnTmFtZX0nXG52YXIgcmVzZXJ2ZWRDbGllbnRUYWdzID0gW1xuICAnYXBpcycsXG4gICdhdXRob3JpemF0aW9uU2NoZW1lJyxcbiAgJ2F1dGhvcml6YXRpb25zJyxcbiAgJ2Jhc2VQYXRoJyxcbiAgJ2J1aWxkJyxcbiAgJ2J1aWxkRnJvbTFfMVNwZWMnLFxuICAnYnVpbGRGcm9tMV8yU3BlYycsXG4gICdidWlsZEZyb21TcGVjJyxcbiAgJ2NsaWVudEF1dGhvcml6YXRpb25zJyxcbiAgJ2NvbnZlcnRJbmZvJyxcbiAgJ2RlYnVnJyxcbiAgJ2RlZmF1bHRFcnJvckNhbGxiYWNrJyxcbiAgJ2RlZmF1bHRTdWNjZXNzQ2FsbGJhY2snLFxuICAnZW5hYmxlQ29va2llcycsXG4gICdmYWlsJyxcbiAgJ2ZhaWx1cmUnLFxuICAnZmluaXNoJyxcbiAgJ2hlbHAnLFxuICAnaG9zdCcsXG4gICdpZEZyb21PcCcsXG4gICdpbmZvJyxcbiAgJ2luaXRpYWxpemUnLFxuICAnaXNCdWlsdCcsXG4gICdpc1ZhbGlkJyxcbiAgJ21vZGVsUHJvcGVydHlNYWNybycsXG4gICdtb2RlbHMnLFxuICAnbW9kZWxzQXJyYXknLFxuICAnb3B0aW9ucycsXG4gICdwYXJhbWV0ZXJNYWNybycsXG4gICdwYXJzZVVyaScsXG4gICdwcm9ncmVzcycsXG4gICdyZXNvdXJjZUNvdW50JyxcbiAgJ3NhbXBsZU1vZGVscycsXG4gICdzZWxmUmVmbGVjdCcsXG4gICdzZXRDb25zb2xpZGF0ZWRNb2RlbHMnLFxuICAnc3BlYycsXG4gICdzdXBwb3J0ZWRTdWJtaXRNZXRob2RzJyxcbiAgJ3N3YWdnZXJSZXF1ZXN0SGVhZGVycycsXG4gICd0YWdGcm9tTGFiZWwnLFxuICAndGl0bGUnLFxuICAndXJsJyxcbiAgJ3VzZUpRdWVyeScsXG4gICdqcXVlcnlBamF4Q2FjaGUnXG5dO1xuLy8gV2UgaGF2ZSB0byBrZWVwIHRyYWNrIG9mIHRoZSBmdW5jdGlvbi9wcm9wZXJ0eSBuYW1lcyB0byBhdm9pZCBjb2xsaXNpb25zIGZvciB0YWcgbmFtZXMgd2hpY2ggYXJlIHVzZWQgdG8gYWxsb3cgdGhlXG4vLyBmb2xsb3dpbmcgdXNhZ2U6ICdjbGllbnQuYXBpcy57dGFnTmFtZX0nXG52YXIgcmVzZXJ2ZWRBcGlUYWdzID0gW1xuICAnYXBpcycsXG4gICdhc0N1cmwnLFxuICAnZGVzY3JpcHRpb24nLFxuICAnZXh0ZXJuYWxEb2NzJyxcbiAgJ2hlbHAnLFxuICAnbGFiZWwnLFxuICAnbmFtZScsXG4gICdvcGVyYXRpb24nLFxuICAnb3BlcmF0aW9ucycsXG4gICdvcGVyYXRpb25zQXJyYXknLFxuICAncGF0aCcsXG4gICd0YWcnXG5dO1xudmFyIHN1cHBvcnRlZE9wZXJhdGlvbk1ldGhvZHMgPSBbJ2RlbGV0ZScsICdnZXQnLCAnaGVhZCcsICdvcHRpb25zJywgJ3BhdGNoJywgJ3Bvc3QnLCAncHV0J107XG52YXIgU3dhZ2dlckNsaWVudCA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHVybCwgb3B0aW9ucykge1xuICB0aGlzLmF1dGhvcml6YXRpb25zID0gbnVsbDtcbiAgdGhpcy5hdXRob3JpemF0aW9uU2NoZW1lID0gbnVsbDtcbiAgdGhpcy5iYXNlUGF0aCA9IG51bGw7XG4gIHRoaXMuZGVidWcgPSBmYWxzZTtcbiAgdGhpcy5lbmFibGVDb29raWVzID0gZmFsc2U7XG4gIHRoaXMuaW5mbyA9IG51bGw7XG4gIHRoaXMuaXNCdWlsdCA9IGZhbHNlO1xuICB0aGlzLmlzVmFsaWQgPSBmYWxzZTtcbiAgdGhpcy5tb2RlbHNBcnJheSA9IFtdO1xuICB0aGlzLnJlc291cmNlQ291bnQgPSAwO1xuICB0aGlzLnVybCA9IG51bGw7XG4gIHRoaXMudXNlSlF1ZXJ5ID0gZmFsc2U7XG4gIHRoaXMuanF1ZXJ5QWpheENhY2hlID0gZmFsc2U7XG4gIHRoaXMuc3dhZ2dlck9iamVjdCA9IHt9O1xuICB0aGlzLmRlZmVycmVkQ2xpZW50ID0gdW5kZWZpbmVkO1xuXG4gIHRoaXMuY2xpZW50QXV0aG9yaXphdGlvbnMgPSBuZXcgYXV0aC5Td2FnZ2VyQXV0aG9yaXphdGlvbnMoKTtcblxuICBpZiAodHlwZW9mIHVybCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gdGhpcy5pbml0aWFsaXplKHVybCwgb3B0aW9ucyk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbn07XG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLmluaXRpYWxpemUgPSBmdW5jdGlvbiAodXJsLCBvcHRpb25zKSB7XG4gIHRoaXMubW9kZWxzID0ge307XG4gIHRoaXMuc2FtcGxlTW9kZWxzID0ge307XG5cbiAgaWYgKHR5cGVvZiB1cmwgPT09ICdzdHJpbmcnKSB7XG4gICAgdGhpcy51cmwgPSB1cmw7XG4gIH0gZWxzZSBpZiAoXy5pc09iamVjdCh1cmwpKSB7XG4gICAgb3B0aW9ucyA9IHVybDtcbiAgICB0aGlzLnVybCA9IG9wdGlvbnMudXJsO1xuICB9XG5cbiAgaWYodGhpcy51cmwgJiYgdGhpcy51cmwuaW5kZXhPZignaHR0cDonKSA9PT0gLTEgJiYgdGhpcy51cmwuaW5kZXhPZignaHR0cHM6JykgPT09IC0xKSB7XG4gICAgLy8gbm8gcHJvdG9jb2wsIHNvIHdlIGNhbiBvbmx5IHVzZSB3aW5kb3cgaWYgaXQgZXhpc3RzXG4gICAgaWYodHlwZW9mKHdpbmRvdykgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZih3aW5kb3cubG9jYXRpb24pICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhpcy51cmwgPSB3aW5kb3cubG9jYXRpb24ub3JpZ2luICsgdGhpcy51cmw7XG4gICAgfVxuICB9XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHRoaXMuY2xpZW50QXV0aG9yaXphdGlvbnMuYWRkKG9wdGlvbnMuYXV0aG9yaXphdGlvbnMpO1xuICB0aGlzLnN3YWdnZXJSZXF1ZXN0SGVhZGVycyA9IG9wdGlvbnMuc3dhZ2dlclJlcXVlc3RIZWFkZXJzIHx8ICdhcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTgsKi8qJztcbiAgdGhpcy5kZWZhdWx0U3VjY2Vzc0NhbGxiYWNrID0gb3B0aW9ucy5kZWZhdWx0U3VjY2Vzc0NhbGxiYWNrIHx8IG51bGw7XG4gIHRoaXMuZGVmYXVsdEVycm9yQ2FsbGJhY2sgPSBvcHRpb25zLmRlZmF1bHRFcnJvckNhbGxiYWNrIHx8IG51bGw7XG4gIHRoaXMubW9kZWxQcm9wZXJ0eU1hY3JvID0gb3B0aW9ucy5tb2RlbFByb3BlcnR5TWFjcm8gfHwgbnVsbDtcbiAgdGhpcy5jb25uZWN0aW9uQWdlbnQgPSBvcHRpb25zLmNvbm5lY3Rpb25BZ2VudCB8fCBudWxsO1xuICB0aGlzLnBhcmFtZXRlck1hY3JvID0gb3B0aW9ucy5wYXJhbWV0ZXJNYWNybyB8fCBudWxsO1xuICB0aGlzLnVzZVByb21pc2UgPSBvcHRpb25zLnVzZVByb21pc2UgfHwgbnVsbDtcblxuICAvLyBvcGVyYXRpb24gcmVxdWVzdCB0aW1lb3V0IGRlZmF1bHRcbiAgdGhpcy50aW1lb3V0ID0gb3B0aW9ucy50aW1lb3V0IHx8IG51bGw7XG4gIC8vIGRlZmF1bHQgdG8gcmVxdWVzdCB0aW1lb3V0IHdoZW4gbm90IHNwZWNpZmllZFxuICB0aGlzLmZldGNoU3BlY1RpbWVvdXQgPSB0eXBlb2Ygb3B0aW9ucy5mZXRjaFNwZWNUaW1lb3V0ICE9PSAndW5kZWZpbmVkJyA/XG4gICAgICBvcHRpb25zLmZldGNoU3BlY1RpbWVvdXQgOiBvcHRpb25zLnRpbWVvdXQgfHwgbnVsbDtcblxuICBpZih0aGlzLnVzZVByb21pc2UpIHtcbiAgICB0aGlzLmRlZmVycmVkQ2xpZW50ID0gUS5kZWZlcigpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBvcHRpb25zLnN1Y2Nlc3MgPT09ICdmdW5jdGlvbicpIHtcbiAgICB0aGlzLnN1Y2Nlc3MgPSBvcHRpb25zLnN1Y2Nlc3M7XG4gIH1cbiAgaWYgKG9wdGlvbnMudXNlSlF1ZXJ5KSB7XG4gICAgdGhpcy51c2VKUXVlcnkgPSBvcHRpb25zLnVzZUpRdWVyeTtcbiAgfVxuXG4gIGlmIChvcHRpb25zLmpxdWVyeUFqYXhDYWNoZSkge1xuICAgIHRoaXMuanF1ZXJ5QWpheENhY2hlID0gb3B0aW9ucy5qcXVlcnlBamF4Q2FjaGU7XG4gIH1cblxuICBpZiAob3B0aW9ucy5lbmFibGVDb29raWVzKSB7XG4gICAgdGhpcy5lbmFibGVDb29raWVzID0gb3B0aW9ucy5lbmFibGVDb29raWVzO1xuICB9XG5cbiAgdGhpcy5vcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAvLyBtYXliZSBkb24ndCBuZWVkIHRoaXM/XG4gIHRoaXMub3B0aW9ucy50aW1lb3V0ID0gdGhpcy50aW1lb3V0O1xuICB0aGlzLm9wdGlvbnMuZmV0Y2hTcGVjVGltZW91dCA9IHRoaXMuZmV0Y2hTcGVjVGltZW91dDtcblxuICB0aGlzLnN1cHBvcnRlZFN1Ym1pdE1ldGhvZHMgPSBvcHRpb25zLnN1cHBvcnRlZFN1Ym1pdE1ldGhvZHMgfHwgW107XG4gIHRoaXMuZmFpbHVyZSA9IG9wdGlvbnMuZmFpbHVyZSB8fCBmdW5jdGlvbiAoZXJyKSB7IHRocm93IGVycjsgfTtcbiAgdGhpcy5wcm9ncmVzcyA9IG9wdGlvbnMucHJvZ3Jlc3MgfHwgZnVuY3Rpb24gKCkge307XG4gIHRoaXMuc3BlYyA9IF8uY2xvbmVEZWVwKG9wdGlvbnMuc3BlYyk7IC8vIENsb25lIHNvIHdlIGRvIG5vdCBhbHRlciB0aGUgcHJvdmlkZWQgZG9jdW1lbnRcblxuICBpZiAob3B0aW9ucy5zY2hlbWUpIHtcbiAgICB0aGlzLnNjaGVtZSA9IG9wdGlvbnMuc2NoZW1lO1xuICB9XG5cbiAgaWYgKHRoaXMudXNlUHJvbWlzZSB8fCB0eXBlb2Ygb3B0aW9ucy5zdWNjZXNzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhpcy5yZWFkeSA9IHRydWU7XG4gICAgcmV0dXJuIHRoaXMuYnVpbGQoKTtcbiAgfVxufTtcblxuU3dhZ2dlckNsaWVudC5wcm90b3R5cGUuYnVpbGQgPSBmdW5jdGlvbiAobW9jaykge1xuICBpZiAodGhpcy5pc0J1aWx0KSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgaWYgKHRoaXMuc3BlYykge1xuICAgIHRoaXMucHJvZ3Jlc3MoJ2ZldGNoaW5nIHJlc291cmNlIGxpc3Q7IFBsZWFzZSB3YWl0LicpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMucHJvZ3Jlc3MoJ2ZldGNoaW5nIHJlc291cmNlIGxpc3Q6ICcgKyB0aGlzLnVybCArICc7IFBsZWFzZSB3YWl0LicpO1xuICB9XG5cbiAgdmFyIG9iaiA9IHtcbiAgICB1c2VKUXVlcnk6IHRoaXMudXNlSlF1ZXJ5LFxuICAgIGpxdWVyeUFqYXhDYWNoZTogdGhpcy5qcXVlcnlBamF4Q2FjaGUsXG4gICAgY29ubmVjdGlvbkFnZW50OiB0aGlzLmNvbm5lY3Rpb25BZ2VudCxcbiAgICBlbmFibGVDb29raWVzOiB0aGlzLmVuYWJsZUNvb2tpZXMsXG4gICAgdXJsOiB0aGlzLnVybCxcbiAgICBtZXRob2Q6ICdnZXQnLFxuICAgIGhlYWRlcnM6IHtcbiAgICAgIGFjY2VwdDogdGhpcy5zd2FnZ2VyUmVxdWVzdEhlYWRlcnNcbiAgICB9LFxuICAgIG9uOiB7XG4gICAgICBlcnJvcjogZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgIGlmIChzZWxmICYmIHNlbGYudXJsICYmIHNlbGYudXJsLnN1YnN0cmluZygwLCA0KSAhPT0gJ2h0dHAnKSB7XG4gICAgICAgICAgcmV0dXJuIHNlbGYuZmFpbCgnUGxlYXNlIHNwZWNpZnkgdGhlIHByb3RvY29sIGZvciAnICsgc2VsZi51cmwpO1xuICAgICAgICB9IGVsc2UgaWYgKHJlc3BvbnNlLmVyck9iaiAmJiAocmVzcG9uc2UuZXJyT2JqLmNvZGUgPT09ICdFQ09OTkFCT1JURUQnIHx8IHJlc3BvbnNlLmVyck9iai5tZXNzYWdlLmluZGV4T2YoJ3RpbWVvdXQnKSAhPT0gLTEpKSB7XG4gICAgICAgICAgcmV0dXJuIHNlbGYuZmFpbCgnUmVxdWVzdCB0aW1lZCBvdXQgYWZ0ZXIgJyArIHNlbGYuZmV0Y2hTcGVjVGltZW91dCArICdtcycpO1xuICAgICAgICB9IGVsc2UgaWYgKHJlc3BvbnNlLnN0YXR1cyA9PT0gMCkge1xuICAgICAgICAgIHJldHVybiBzZWxmLmZhaWwoJ0NhblxcJ3QgcmVhZCBmcm9tIHNlcnZlci4gIEl0IG1heSBub3QgaGF2ZSB0aGUgYXBwcm9wcmlhdGUgYWNjZXNzLWNvbnRyb2wtb3JpZ2luIHNldHRpbmdzLicpO1xuICAgICAgICB9IGVsc2UgaWYgKHJlc3BvbnNlLnN0YXR1cyA9PT0gNDA0KSB7XG4gICAgICAgICAgcmV0dXJuIHNlbGYuZmFpbCgnQ2FuXFwndCByZWFkIHN3YWdnZXIgSlNPTiBmcm9tICcgKyBzZWxmLnVybCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHNlbGYuZmFpbChyZXNwb25zZS5zdGF0dXMgKyAnIDogJyArIHJlc3BvbnNlLnN0YXR1c1RleHQgKyAnICcgKyBzZWxmLnVybCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICByZXNwb25zZTogZnVuY3Rpb24gKHJlc3ApIHtcblxuICAgICAgICB2YXIgcmVzcG9uc2VPYmogPSByZXNwLm9iajtcbiAgICAgICAgaWYoIXJlc3BvbnNlT2JqKSB7XG4gICAgICAgICAgcmV0dXJuIHNlbGYuZmFpbCgnZmFpbGVkIHRvIHBhcnNlIEpTT04vWUFNTCByZXNwb25zZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgc2VsZi5zd2FnZ2VyVmVyc2lvbiA9IHJlc3BvbnNlT2JqLnN3YWdnZXJWZXJzaW9uO1xuICAgICAgICBzZWxmLnN3YWdnZXJPYmplY3QgPSByZXNwb25zZU9iajtcblxuICAgICAgICBpZiAocmVzcG9uc2VPYmouc3dhZ2dlciAmJiBwYXJzZUludChyZXNwb25zZU9iai5zd2FnZ2VyKSA9PT0gMikge1xuICAgICAgICAgIHNlbGYuc3dhZ2dlclZlcnNpb24gPSByZXNwb25zZU9iai5zd2FnZ2VyO1xuXG4gICAgICAgICAgbmV3IFJlc29sdmVyKCkucmVzb2x2ZShyZXNwb25zZU9iaiwgc2VsZi51cmwsIHNlbGYuYnVpbGRGcm9tU3BlYywgc2VsZik7XG5cbiAgICAgICAgICBzZWxmLmlzVmFsaWQgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciBjb252ZXJ0ZXIgPSBuZXcgU3dhZ2dlclNwZWNDb252ZXJ0ZXIoKTtcbiAgICAgICAgICBzZWxmLm9sZFN3YWdnZXJPYmplY3QgPSBzZWxmLnN3YWdnZXJPYmplY3Q7XG5cbiAgICAgICAgICBjb252ZXJ0ZXIuc2V0RG9jdW1lbnRhdGlvbkxvY2F0aW9uKHNlbGYudXJsKTtcbiAgICAgICAgICBjb252ZXJ0ZXIuY29udmVydChyZXNwb25zZU9iaiwgc2VsZi5jbGllbnRBdXRob3JpemF0aW9ucywgc2VsZi5vcHRpb25zLCBmdW5jdGlvbihzcGVjKSB7XG4gICAgICAgICAgICBzZWxmLnN3YWdnZXJPYmplY3QgPSBzcGVjO1xuICAgICAgICAgICAgbmV3IFJlc29sdmVyKCkucmVzb2x2ZShzcGVjLCBzZWxmLnVybCwgc2VsZi5idWlsZEZyb21TcGVjLCBzZWxmKTtcbiAgICAgICAgICAgIHNlbGYuaXNWYWxpZCA9IHRydWU7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgLy8gb25seSBzZXQgdGltZW91dCB3aGVuIHNwZWNpZmllZFxuICBpZiAodGhpcy5mZXRjaFNwZWNUaW1lb3V0KSB7XG4gICAgb2JqLnRpbWVvdXQgPSB0aGlzLmZldGNoU3BlY1RpbWVvdXQ7XG4gIH1cblxuICBpZiAodGhpcy5zcGVjICYmIHR5cGVvZiB0aGlzLnNwZWMgPT09ICdvYmplY3QnKSB7XG4gICAgc2VsZi5zd2FnZ2VyT2JqZWN0ID0gdGhpcy5zcGVjO1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgbmV3IFJlc29sdmVyKCkucmVzb2x2ZShzZWxmLnNwZWMsIHNlbGYudXJsLCBzZWxmLmJ1aWxkRnJvbVNwZWMsIHNlbGYpO1xuICAgIH0sIDEwKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zLmFwcGx5KG9iaik7XG5cbiAgICBpZiAobW9jaykge1xuICAgICAgcmV0dXJuIG9iajtcbiAgICB9XG5cbiAgICBuZXcgU3dhZ2dlckh0dHAoKS5leGVjdXRlKG9iaiwgdGhpcy5vcHRpb25zKTtcbiAgfVxuXG4gIHJldHVybiAodGhpcy51c2VQcm9taXNlKSA/IHRoaXMuZGVmZXJyZWRDbGllbnQucHJvbWlzZSA6IHRoaXM7XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5idWlsZEZyb21TcGVjID0gZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gIGlmICh0aGlzLmlzQnVpbHQpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHRoaXMuYXBpcyA9IHt9O1xuICB0aGlzLmFwaXNBcnJheSA9IFtdO1xuICB0aGlzLmJhc2VQYXRoID0gcmVzcG9uc2UuYmFzZVBhdGggfHwgJyc7XG4gIHRoaXMuY29uc3VtZXMgPSByZXNwb25zZS5jb25zdW1lcztcbiAgdGhpcy5ob3N0ID0gcmVzcG9uc2UuaG9zdCB8fCAnJztcbiAgdGhpcy5pbmZvID0gcmVzcG9uc2UuaW5mbyB8fCB7fTtcbiAgdGhpcy5wcm9kdWNlcyA9IHJlc3BvbnNlLnByb2R1Y2VzO1xuICB0aGlzLnNjaGVtZXMgPSByZXNwb25zZS5zY2hlbWVzIHx8IFtdO1xuICB0aGlzLnNlY3VyaXR5RGVmaW5pdGlvbnMgPSBfLmNsb25lRGVlcChyZXNwb25zZS5zZWN1cml0eURlZmluaXRpb25zKTtcbiAgdGhpcy5zZWN1cml0eSA9IHJlc3BvbnNlLnNlY3VyaXR5O1xuICB0aGlzLnRpdGxlID0gcmVzcG9uc2UudGl0bGUgfHwgJyc7XG5cbiAgdmFyIGtleSwgZGVmaW5lZFRhZ3MgPSB7fSwgaywgbG9jYXRpb24sIHNlbGYgPSB0aGlzLCBpO1xuXG4gIGlmIChyZXNwb25zZS5leHRlcm5hbERvY3MpIHtcbiAgICB0aGlzLmV4dGVybmFsRG9jcyA9IHJlc3BvbnNlLmV4dGVybmFsRG9jcztcbiAgfVxuXG4gIC8vIGxlZ2FjeSBzdXBwb3J0XG4gIHRoaXMuYXV0aFNjaGVtZXMgPSB0aGlzLnNlY3VyaXR5RGVmaW5pdGlvbnM7XG5cbiAgaWYodGhpcy5zZWN1cml0eURlZmluaXRpb25zKSB7XG4gICAgZm9yKGtleSBpbiB0aGlzLnNlY3VyaXR5RGVmaW5pdGlvbnMpIHtcbiAgICAgIHZhciBzZWN1cml0eURlZmluaXRpb24gPSB0aGlzLnNlY3VyaXR5RGVmaW5pdGlvbnNba2V5XTtcbiAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi52ZW5kb3JFeHRlbnNpb25zID0ge307XG4gICAgICBmb3IodmFyIGV4dCBpbiBzZWN1cml0eURlZmluaXRpb24pIHtcbiAgICAgICAgaGVscGVycy5leHRyYWN0RXh0ZW5zaW9ucyhleHQsIHNlY3VyaXR5RGVmaW5pdGlvbik7XG4gICAgICAgIGlmIChleHQgPT09ICdzY29wZXMnKSB7XG4gICAgICAgICAgdmFyIHNjb3BlcyA9IHNlY3VyaXR5RGVmaW5pdGlvbltleHRdO1xuICAgICAgICAgIGlmKHR5cGVvZiBzY29wZXMgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICBzY29wZXMudmVuZG9yRXh0ZW5zaW9ucyA9IHt9O1xuICAgICAgICAgICAgZm9yICh2YXIgcyBpbiBzY29wZXMpIHtcbiAgICAgICAgICAgICAgaGVscGVycy5leHRyYWN0RXh0ZW5zaW9ucyhzLCBzY29wZXMpO1xuICAgICAgICAgICAgICBpZihzLmluZGV4T2YoJ3gtJykgPT09IDApIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgc2NvcGVzW3NdO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkocmVzcG9uc2UudGFncykpIHtcbiAgICBkZWZpbmVkVGFncyA9IHt9O1xuXG4gICAgZm9yIChrID0gMDsgayA8IHJlc3BvbnNlLnRhZ3MubGVuZ3RoOyBrKyspIHtcbiAgICAgIHZhciB0ID0gXy5jbG9uZURlZXAocmVzcG9uc2UudGFnc1trXSk7XG4gICAgICBkZWZpbmVkVGFnc1t0Lm5hbWVdID0gdDtcbiAgICAgIGZvcihpIGluIHQpIHtcbiAgICAgICAgaWYoaSA9PT0gJ2V4dGVybmFsRG9jcycgJiYgdHlwZW9mIHRbaV0gPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgZm9yKHZhciBqIGluIHRbaV0pIHtcbiAgICAgICAgICAgIGhlbHBlcnMuZXh0cmFjdEV4dGVuc2lvbnMoaiwgdFtpXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGhlbHBlcnMuZXh0cmFjdEV4dGVuc2lvbnMoaSwgdCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cblxuICBpZiAodHlwZW9mIHRoaXMudXJsID09PSAnc3RyaW5nJykge1xuICAgIGxvY2F0aW9uID0gdGhpcy5wYXJzZVVyaSh0aGlzLnVybCk7XG4gICAgaWYgKHR5cGVvZiB0aGlzLnNjaGVtZSA9PT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIHRoaXMuc2NoZW1lcyA9PT0gJ3VuZGVmaW5lZCcgfHwgdGhpcy5zY2hlbWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgaWYgKHR5cGVvZiBsb2NhdGlvbiAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mKGxvY2F0aW9uLnNjaGVtZSkgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHRoaXMuc2NoZW1lID0gbG9jYXRpb24uc2NoZW1lO1xuICAgICAgfVxuICAgICAgaWYodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mKHdpbmRvdy5sb2NhdGlvbikgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIC8vIHVzZSB0aGUgd2luZG93IHNjaGVtZVxuICAgICAgICB0aGlzLnNjaGVtZSA9IHdpbmRvdy5sb2NhdGlvbi5wcm90b2NvbC5yZXBsYWNlKCc6JywnJyk7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgdGhpcy5zY2hlbWUgPSBsb2NhdGlvbi5zY2hlbWUgfHwgJ2h0dHAnO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mKHdpbmRvdy5sb2NhdGlvbikgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdy5sb2NhdGlvbi5wcm90b2NvbC5pbmRleE9mKCdjaHJvbWUtZXh0ZW5zaW9uJykgPT09IDApIHtcblx0XHQvLyBpZiBpdCBpcyBjaHJvbWUgc3dhZ2dlciB1aSBleHRlbnNpb24gc2NoZW1lIHRoZW4gbGV0IHN3YWdnZXIgZG9jIHVybCBzY2hlbWUgZGVjaWRlIHRoZSBwcm90b2NvbFxuXHRcdHRoaXMuc2NoZW1lID0gbG9jYXRpb24uc2NoZW1lO1xuXHR9IGVsc2UgaWYgKHR5cGVvZiB0aGlzLnNjaGVtZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGlmKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZih3aW5kb3cubG9jYXRpb24pICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICB2YXIgc2NoZW1lID0gd2luZG93LmxvY2F0aW9uLnByb3RvY29sLnJlcGxhY2UoJzonLCcnKTtcbiAgICAgICAgaWYoc2NoZW1lID09PSAnaHR0cHMnICYmIHRoaXMuc2NoZW1lcy5pbmRleE9mKHNjaGVtZSkgPT09IC0xKSB7XG4gICAgICAgICAgLy8gY2FuJ3QgY2FsbCBodHRwIGZyb20gaHR0cHMgc2VydmVkIHBhZ2UgaW4gYSBicm93c2VyIVxuICAgICAgICAgIGhlbHBlcnMubG9nKCdDYW5ub3QgY2FsbCBhIGh0dHAgc2VydmVyIGZyb20gaHR0cHMgaW5zaWRlIGEgYnJvd3NlciEnKTtcbiAgICAgICAgICB0aGlzLnNjaGVtZSA9ICdodHRwJztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmKHRoaXMuc2NoZW1lcy5pbmRleE9mKHNjaGVtZSkgIT09IC0xKSB7XG4gICAgICAgICAgdGhpcy5zY2hlbWUgPSBzY2hlbWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgaWYodGhpcy5zY2hlbWVzLmluZGV4T2YoJ2h0dHBzJykgIT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLnNjaGVtZSA9ICdodHRwcyc7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zY2hlbWUgPSAnaHR0cCc7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgdGhpcy5zY2hlbWUgPSB0aGlzLnNjaGVtZXNbMF0gfHwgbG9jYXRpb24uc2NoZW1lO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdGhpcy5ob3N0ID09PSAndW5kZWZpbmVkJyB8fCB0aGlzLmhvc3QgPT09ICcnKSB7XG4gICAgICB0aGlzLmhvc3QgPSBsb2NhdGlvbi5ob3N0O1xuXG4gICAgICBpZiAobG9jYXRpb24ucG9ydCkge1xuICAgICAgICB0aGlzLmhvc3QgPSB0aGlzLmhvc3QgKyAnOicgKyBsb2NhdGlvbi5wb3J0O1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBlbHNlIHtcbiAgICBpZiAodHlwZW9mIHRoaXMuc2NoZW1lcyA9PT0gJ3VuZGVmaW5lZCcgfHwgdGhpcy5zY2hlbWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5zY2hlbWUgPSAnaHR0cCc7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGVvZiB0aGlzLnNjaGVtZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRoaXMuc2NoZW1lID0gdGhpcy5zY2hlbWVzWzBdO1xuICAgIH1cbiAgfVxuXG4gIHRoaXMuZGVmaW5pdGlvbnMgPSByZXNwb25zZS5kZWZpbml0aW9ucztcblxuICBmb3IgKGtleSBpbiB0aGlzLmRlZmluaXRpb25zKSB7XG4gICAgdmFyIG1vZGVsID0gbmV3IE1vZGVsKGtleSwgdGhpcy5kZWZpbml0aW9uc1trZXldLCB0aGlzLm1vZGVscywgdGhpcy5tb2RlbFByb3BlcnR5TWFjcm8pO1xuXG4gICAgaWYgKG1vZGVsKSB7XG4gICAgICB0aGlzLm1vZGVsc1trZXldID0gbW9kZWw7XG4gICAgfVxuICB9XG5cbiAgLy8gZ2V0IHBhdGhzLCBjcmVhdGUgZnVuY3Rpb25zIGZvciBlYWNoIG9wZXJhdGlvbklkXG5cbiAgLy8gQmluZCBoZWxwIHRvICdjbGllbnQuYXBpcydcbiAgc2VsZi5hcGlzLmhlbHAgPSBfLmJpbmQoc2VsZi5oZWxwLCBzZWxmKTtcblxuICBfLmZvckVhY2gocmVzcG9uc2UucGF0aHMsIGZ1bmN0aW9uIChwYXRoT2JqLCBwYXRoKSB7XG4gICAgLy8gT25seSBwcm9jZXNzIGEgcGF0aCBpZiBpdCdzIGFuIG9iamVjdFxuICAgIGlmICghXy5pc1BsYWluT2JqZWN0KHBhdGhPYmopKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgXy5mb3JFYWNoKHN1cHBvcnRlZE9wZXJhdGlvbk1ldGhvZHMsIGZ1bmN0aW9uIChtZXRob2QpIHtcbiAgICAgIHZhciBvcGVyYXRpb24gPSBwYXRoT2JqW21ldGhvZF07XG5cbiAgICAgIGlmIChfLmlzVW5kZWZpbmVkKG9wZXJhdGlvbikpIHtcbiAgICAgICAgLy8gT3BlcmF0aW9uIGRvZXMgbm90IGV4aXN0XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gZWxzZSBpZiAoIV8uaXNQbGFpbk9iamVjdChvcGVyYXRpb24pKSB7XG4gICAgICAgIC8vIE9wZXJhdGlvbiBleGlzdHMgYnV0IGl0IGlzIG5vdCBhbiBPcGVyYXRpb24gT2JqZWN0LiAgU2luY2UgdGhpcyBpcyBpbnZhbGlkLCBsb2cgaXQuXG4gICAgICAgIGhlbHBlcnMubG9nKCdUaGUgXFwnJyArIG1ldGhvZCArICdcXCcgb3BlcmF0aW9uIGZvciBcXCcnICsgcGF0aCArICdcXCcgcGF0aCBpcyBub3QgYW4gT3BlcmF0aW9uIE9iamVjdCcpO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIHRhZ3MgPSBvcGVyYXRpb24udGFncztcblxuICAgICAgaWYgKF8uaXNVbmRlZmluZWQodGFncykgfHwgIV8uaXNBcnJheSh0YWdzKSB8fCB0YWdzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0YWdzID0gb3BlcmF0aW9uLnRhZ3MgPSBbICdkZWZhdWx0JyBdO1xuICAgICAgfVxuXG4gICAgICB2YXIgb3BlcmF0aW9uSWQgPSBzZWxmLmlkRnJvbU9wKHBhdGgsIG1ldGhvZCwgb3BlcmF0aW9uKTtcblxuICAgICAgdmFyIG9wZXJhdGlvbk9iamVjdCA9IG5ldyBPcGVyYXRpb24oc2VsZixcbiAgICAgICAgb3BlcmF0aW9uLnNjaGVtZSxcbiAgICAgICAgb3BlcmF0aW9uSWQsXG4gICAgICAgIG1ldGhvZCxcbiAgICAgICAgcGF0aCxcbiAgICAgICAgb3BlcmF0aW9uLFxuICAgICAgICBzZWxmLmRlZmluaXRpb25zLFxuICAgICAgICBzZWxmLm1vZGVscyxcbiAgICAgICAgc2VsZi5jbGllbnRBdXRob3JpemF0aW9ucyk7XG5cbiAgICAgIG9wZXJhdGlvbk9iamVjdC5jb25uZWN0aW9uQWdlbnQgPSBzZWxmLmNvbm5lY3Rpb25BZ2VudDtcbiAgICAgIG9wZXJhdGlvbk9iamVjdC52ZW5kb3JFeHRlbnNpb25zID0ge307XG4gICAgICBmb3IoaSBpbiBvcGVyYXRpb24pIHtcbiAgICAgICAgaGVscGVycy5leHRyYWN0RXh0ZW5zaW9ucyhpLCBvcGVyYXRpb25PYmplY3QsIG9wZXJhdGlvbltpXSk7XG4gICAgICB9XG4gICAgICBvcGVyYXRpb25PYmplY3QuZXh0ZXJuYWxEb2NzID0gb3BlcmF0aW9uLmV4dGVybmFsRG9jcztcbiAgICAgIGlmKG9wZXJhdGlvbk9iamVjdC5leHRlcm5hbERvY3MpIHtcbiAgICAgICAgb3BlcmF0aW9uT2JqZWN0LmV4dGVybmFsRG9jcyA9IF8uY2xvbmVEZWVwKG9wZXJhdGlvbk9iamVjdC5leHRlcm5hbERvY3MpO1xuICAgICAgICBvcGVyYXRpb25PYmplY3QuZXh0ZXJuYWxEb2NzLnZlbmRvckV4dGVuc2lvbnMgPSB7fTtcbiAgICAgICAgZm9yKGkgaW4gb3BlcmF0aW9uT2JqZWN0LmV4dGVybmFsRG9jcykge1xuICAgICAgICAgIGhlbHBlcnMuZXh0cmFjdEV4dGVuc2lvbnMoaSwgb3BlcmF0aW9uT2JqZWN0LmV4dGVybmFsRG9jcyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gYmluZCBzZWxmIG9wZXJhdGlvbidzIGV4ZWN1dGUgY29tbWFuZCB0byB0aGUgYXBpXG4gICAgICBfLmZvckVhY2godGFncywgZnVuY3Rpb24gKHRhZykge1xuICAgICAgICB2YXIgY2xpZW50UHJvcGVydHkgPSBfLmluZGV4T2YocmVzZXJ2ZWRDbGllbnRUYWdzLCB0YWcpID4gLTEgPyAnXycgKyB0YWcgOiB0YWc7XG4gICAgICAgIHZhciBhcGlQcm9wZXJ0eSA9IF8uaW5kZXhPZihyZXNlcnZlZEFwaVRhZ3MsIHRhZykgPiAtMSA/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/XG4gICAgdHlwZSA9IGRlZmluaXRpb25zW3R5cGVdOyAvKiBNb2RlbCAqL1xuICAgIGlzUHJpbWl0aXZlID0gZmFsc2U7XG5cbiAgfSBlbHNlIGlmICh0aGlzLmdldElubGluZU1vZGVsKHR5cGUpKSB7XG4gICAgdHlwZSA9IHRoaXMuZ2V0SW5saW5lTW9kZWwodHlwZSk7IC8qIE1vZGVsICovXG4gICAgaXNQcmltaXRpdmUgPSBmYWxzZTtcblxuICB9IGVsc2Uge1xuICAgIC8vIFdlIGRlZmF1bHQgdG8gcHJpbWl0aXZlXG4gICAgaXNQcmltaXRpdmUgPSB0cnVlO1xuICB9XG5cbiAgaWYgKGlzUHJpbWl0aXZlKSB7XG4gICAgaWYgKGxpc3RUeXBlKSB7XG4gICAgICByZXR1cm4gJ0FycmF5WycgKyB0eXBlICsgJ10nO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdHlwZS50b1N0cmluZygpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAobGlzdFR5cGUpIHtcbiAgICAgIHJldHVybiAnQXJyYXlbJyArIHR5cGUuZ2V0TW9ja1NpZ25hdHVyZSgpICsgJ10nO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdHlwZS5nZXRNb2NrU2lnbmF0dXJlKCk7XG4gICAgfVxuICB9XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLnN1cHBvcnRIZWFkZXJQYXJhbXMgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB0cnVlO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5zdXBwb3J0ZWRTdWJtaXRNZXRob2RzID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5wYXJlbnQuc3VwcG9ydGVkU3VibWl0TWV0aG9kcztcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuZ2V0SGVhZGVyUGFyYW1zID0gZnVuY3Rpb24gKGFyZ3MpIHtcbiAgdmFyIGhlYWRlcnMgPSB0aGlzLnNldENvbnRlbnRUeXBlcyhhcmdzLCB7fSk7XG4gIHZhciBoZWFkZXJQYXJhbXNCeUxvd2VyQ2FzZSA9IHt9O1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5wYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcmFtID0gdGhpcy5wYXJhbWV0ZXJzW2ldO1xuXG4gICAgaWYgKHBhcmFtLmluID09PSAnaGVhZGVyJykge1xuICAgICAgaGVhZGVyUGFyYW1zQnlMb3dlckNhc2VbcGFyYW0ubmFtZS50b0xvd2VyQ2FzZSgpXSA9IHBhcmFtO1xuICAgIH1cbiAgfVxuXG4gIGZvciAodmFyIGFyZyBpbiBhcmdzKSB7XG4gICAgdmFyIGhlYWRlclBhcmFtID0gaGVhZGVyUGFyYW1zQnlMb3dlckNhc2VbYXJnLnRvTG93ZXJDYXNlKCldO1xuICAgIGlmICh0eXBlb2YgaGVhZGVyUGFyYW0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB2YXIgdmFsdWUgPSBhcmdzW2FyZ107XG5cbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICB2YWx1ZSA9IHZhbHVlLnRvU3RyaW5nKCk7XG4gICAgICB9XG5cbiAgICAgIGhlYWRlcnNbaGVhZGVyUGFyYW0ubmFtZV0gPSB2YWx1ZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gaGVhZGVycztcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUudXJsaWZ5ID0gZnVuY3Rpb24gKGFyZ3MsIG1hc2tQYXNzd29yZHMpIHtcbiAgdmFyIGZvcm1QYXJhbXMgPSB7fTtcbiAgdmFyIHJlcXVlc3RVcmwgPSB0aGlzLnBhdGgucmVwbGFjZSgvIy4qLywgJycpOyAvLyByZW1vdmUgVVJMIGZyYWdtZW50XG4gIHZhciBxdWVyeXN0cmluZyA9ICcnOyAvLyBncmFiIHBhcmFtcyBmcm9tIHRoZSBhcmdzLCBidWlsZCB0aGUgcXVlcnlzdHJpbmcgYWxvbmcgdGhlIHdheVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5wYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcmFtID0gdGhpcy5wYXJhbWV0ZXJzW2ldO1xuXG4gICAgaWYgKHR5cGVvZiBhcmdzW3BhcmFtLm5hbWVdICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdmFyIGlzUGFzc3dvcmQ7XG4gICAgICBpZihwYXJhbS50eXBlID09PSAnc3RyaW5nJyAmJiBwYXJhbS5mb3JtYXQgPT09ICdwYXNzd29yZCcgJiYgbWFza1Bhc3N3b3Jkcykge1xuICAgICAgICBpc1Bhc3N3b3JkID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHBhcmFtLmluID09PSAncGF0aCcpIHtcbiAgICAgICAgdmFyIHJlZyA9IG5ldyBSZWdFeHAoJ1xceycgKyBwYXJhbS5uYW1lICsgJ1xcfScsICdnaScpO1xuICAgICAgICB2YXIgdmFsdWUgPSBhcmdzW3BhcmFtLm5hbWVdO1xuXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgIHZhbHVlID0gdGhpcy5lbmNvZGVQYXRoQ29sbGVjdGlvbihwYXJhbS5jb2xsZWN0aW9uRm9ybWF0LCBwYXJhbS5uYW1lLCB2YWx1ZSwgaXNQYXNzd29yZCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYoKHR5cGVvZihwYXJhbVsneC1lc2NhcGUnXSkgPT09ICd1bmRlZmluZWQnKSB8fCAocGFyYW1bJ3gtZXNjYXBlJ10gPT09IHRydWUpKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IHRoaXMuZW5jb2RlUGF0aFBhcmFtKHZhbHVlLCBpc1Bhc3N3b3JkKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXF1ZXN0VXJsID0gcmVxdWVzdFVybC5yZXBsYWNlKHJlZywgdmFsdWUpO1xuICAgICAgfSBlbHNlIGlmIChwYXJhbS5pbiA9PT0gJ3F1ZXJ5JyAmJiB0eXBlb2YgYXJnc1twYXJhbS5uYW1lXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgaWYgKHF1ZXJ5c3RyaW5nID09PSAnJyAmJiByZXF1ZXN0VXJsLmluZGV4T2YoJz8nKSA8IDApIHtcbiAgICAgICAgICBxdWVyeXN0cmluZyArPSAnPyc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcXVlcnlzdHJpbmcgKz0gJyYnO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBwYXJhbS5jb2xsZWN0aW9uRm9ybWF0ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIHZhciBxcCA9IGFyZ3NbcGFyYW0ubmFtZV07XG5cbiAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShxcCkpIHtcbiAgICAgICAgICAgIHF1ZXJ5c3RyaW5nICs9IHRoaXMuZW5jb2RlUXVlcnlDb2xsZWN0aW9uKHBhcmFtLmNvbGxlY3Rpb25Gb3JtYXQsIHBhcmFtLm5hbWUsIHFwLCBpc1Bhc3N3b3JkKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcXVlcnlzdHJpbmcgKz0gdGhpcy5lbmNvZGVRdWVyeUtleShwYXJhbS5uYW1lKSArICc9JyArIHRoaXMuZW5jb2RlUXVlcnlQYXJhbShhcmdzW3BhcmFtLm5hbWVdLCBpc1Bhc3N3b3JkKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcXVlcnlzdHJpbmcgKz0gdGhpcy5lbmNvZGVRdWVyeUtleShwYXJhbS5uYW1lKSArICc9JyArIHRoaXMuZW5jb2RlUXVlcnlQYXJhbShhcmdzW3BhcmFtLm5hbWVdLCBpc1Bhc3N3b3JkKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChwYXJhbS5pbiA9PT0gJ2Zvcm1EYXRhJykge1xuICAgICAgICBmb3JtUGFyYW1zW3BhcmFtLm5hbWVdID0gYXJnc1twYXJhbS5uYW1lXTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYocGFyYW0uaW4gPT09ICdxdWVyeScgJiYgdHlwZW9mIGFyZ3NbcGFyYW0ubmFtZV0gPT09ICd1bmRlZmluZWQnICYmIHBhcmFtLmFsbG93RW1wdHlWYWx1ZSA9PT0gdHJ1ZSkge1xuICAgICAgaWYgKHF1ZXJ5c3RyaW5nID09PSAnJyAmJiByZXF1ZXN0VXJsLmluZGV4T2YoJz8nKSA8IDApIHtcbiAgICAgICAgcXVlcnlzdHJpbmcgKz0gJz8nO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcXVlcnlzdHJpbmcgKz0gJyYnO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIHBhcmFtLmNvbGxlY3Rpb25Gb3JtYXQgIT09ICd1bmRlZmluZWQnIHx8IHBhcmFtLnR5cGUgPT09ICdhcnJheScpIHtcbiAgICAgICAgdmFyIHFwO1xuICAgICAgICB2YXIgY29sbGVjdGlvbkZvcm1hdCA9IHBhcmFtLmNvbGxlY3Rpb25Gb3JtYXQgfHwgJ211bHRpJztcblxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShxcCkpIHtcbiAgICAgICAgICBxdWVyeXN0cmluZyArPSB0aGlzLmVuY29kZVF1ZXJ5Q29sbGVjdGlvbihjb2xsZWN0aW9uRm9ybWF0LCBwYXJhbS5uYW1lLCBxcCwgaXNQYXNzd29yZCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcXVlcnlzdHJpbmcgKz0gdGhpcy5lbmNvZGVRdWVyeUNvbGxlY3Rpb24oY29sbGVjdGlvbkZvcm1hdCwgcGFyYW0ubmFtZSwgW3FwXSwgaXNQYXNzd29yZCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHF1ZXJ5c3RyaW5nICs9IHRoaXMuZW5jb2RlUXVlcnlLZXkocGFyYW0ubmFtZSkgKyAnPScgKyB0aGlzLmVuY29kZVF1ZXJ5UGFyYW0oJycsIGlzUGFzc3dvcmQpO1xuICAgICAgfVxuXG4gICAgfVxuICB9XG4gIHZhciB1cmwgPSB0aGlzLnNjaGVtZSArICc6Ly8nICsgdGhpcy5ob3N0O1xuXG4gIGlmICh0aGlzLmJhc2VQYXRoICE9PSAnLycpIHtcbiAgICB1cmwgKz0gdGhpcy5iYXNlUGF0aDtcbiAgfVxuICByZXR1cm4gdXJsICsgcmVxdWVzdFVybCArIHF1ZXJ5c3RyaW5nO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5nZXRNaXNzaW5nUGFyYW1zID0gZnVuY3Rpb24gKGFyZ3MpIHtcbiAgdmFyIG1pc3NpbmdQYXJhbXMgPSBbXTsgLy8gY2hlY2sgcmVxdWlyZWQgcGFyYW1zLCB0cmFjayB0aGUgb25lcyB0aGF0IGFyZSBtaXNzaW5nXG4gIHZhciBpO1xuXG4gIGZvciAoaSA9IDA7IGkgPCB0aGlzLnBhcmFtZXRlcnMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcGFyYW0gPSB0aGlzLnBhcmFtZXRlcnNbaV07XG5cbiAgICBpZiAocGFyYW0ucmVxdWlyZWQgPT09IHRydWUpIHtcbiAgICAgIGlmICh0eXBlb2YgYXJnc1twYXJhbS5uYW1lXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgbWlzc2luZ1BhcmFtcyA9IHBhcmFtLm5hbWU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG1pc3NpbmdQYXJhbXM7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmdldEJvZHkgPSBmdW5jdGlvbiAoaGVhZGVycywgYXJncywgb3B0cykge1xuICB2YXIgZm9ybVBhcmFtcyA9IHt9LCBoYXNGb3JtUGFyYW1zLCBwYXJhbSwgYm9keSwga2V5LCB2YWx1ZSwgaGFzQm9keSA9IGZhbHNlO1xuXG4gIC8vIGxvb2sgYXQgZWFjaCBwYXJhbSBhbmQgcHV0IGZvcm0gcGFyYW1zIGluIGFuIG9iamVjdFxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMucGFyYW1ldGVycy5sZW5ndGg7IGkrKykge1xuICAgIHBhcmFtID0gdGhpcy5wYXJhbWV0ZXJzW2ldO1xuICAgIGlmICh0eXBlb2YgYXJnc1twYXJhbS5uYW1lXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHZhciBpc1Bhc3N3b3JkO1xuICAgICAgaWYocGFyYW0udHlwZSA9PT0gJ3N0cmluZycgJiYgcGFyYW0uZm9ybWF0ID09PSAncGFzc3dvcmQnKSB7XG4gICAgICAgIGlzUGFzc3dvcmQgPSAncGFzc3dvcmQnO1xuICAgICAgfVxuICAgICAgaWYgKHBhcmFtLmluID09PSAnYm9keScpIHtcbiAgICAgICAgYm9keSA9IGFyZ3NbcGFyYW0ubmFtZV07XG4gICAgICB9IGVsc2UgaWYgKHBhcmFtLmluID09PSAnZm9ybURhdGEnKSB7XG4gICAgICAgIGZvcm1QYXJhbXNbcGFyYW0ubmFtZV0gPSB7XG4gICAgICAgICAgcGFyYW06IHBhcmFtLFxuICAgICAgICAgIHZhbHVlOiBhcmdzW3BhcmFtLm5hbWVdLFxuICAgICAgICAgIHBhc3N3b3JkOiBpc1Bhc3N3b3JkXG4gICAgICAgIH07XG4gICAgICAgIGhhc0Zvcm1QYXJhbXMgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGlmKHBhcmFtLmluID09PSAnYm9keScpIHtcbiAgICAgICAgaGFzQm9keSA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gaWYgYm9keSBpcyBudWxsIGFuZCBoYXNCb2R5IGlzIHRydWUsIEFORCBhIEpTT04gYm9keSBpcyByZXF1ZXN0ZWQsIHNlbmQgZW1wdHkge31cbiAgaWYoaGFzQm9keSAmJiB0eXBlb2YgYm9keSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB2YXIgY29udGVudFR5cGUgPSBoZWFkZXJzWydDb250ZW50LVR5cGUnXTtcbiAgICBpZihjb250ZW50VHlwZSAmJiBjb250ZW50VHlwZS5pbmRleE9mKCdhcHBsaWNhdGlvbi9qc29uJykgPT09IDApIHtcbiAgICAgIGJvZHkgPSAne30nO1xuICAgIH1cbiAgfVxuXG4gIHZhciBpc011bHRpUGFydCA9IGZhbHNlO1xuICBpZihoZWFkZXJzWydDb250ZW50LVR5cGUnXSAmJiBoZWFkZXJzWydDb250ZW50LVR5cGUnXS5pbmRleE9mKCdtdWx0aXBhcnQvZm9ybS1kYXRhJykgPj0gMCkge1xuICAgIGlzTXVsdGlQYXJ0ID0gdHJ1ZTtcbiAgfVxuXG4gIC8vIGhhbmRsZSBmb3JtIHBhcmFtc1xuICBpZiAoaGFzRm9ybVBhcmFtcyAmJiAhaXNNdWx0aVBhcnQpIHtcbiAgICB2YXIgZW5jb2RlZCA9ICcnO1xuXG4gICAgZm9yIChrZXkgaW4gZm9ybVBhcmFtcykge1xuICAgICAgcGFyYW0gPSBmb3JtUGFyYW1zW2tleV0ucGFyYW07XG4gICAgICB2YWx1ZSA9IGZvcm1QYXJhbXNba2V5XS52YWx1ZTtcbiAgICAgIHZhciBwYXNzd29yZDtcblxuICAgICAgaWYob3B0cyAmJiBvcHRzLm1hc2tQYXNzd29yZHMpIHtcbiAgICAgICAgcGFzc3dvcmQgPSBmb3JtUGFyYW1zW2tleV0ucGFzc3dvcmQ7XG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgIGlmIChlbmNvZGVkICE9PSAnJykge1xuICAgICAgICAgICAgZW5jb2RlZCArPSAnJic7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVuY29kZWQgKz0gdGhpcy5lbmNvZGVRdWVyeUNvbGxlY3Rpb24ocGFyYW0uY29sbGVjdGlvbkZvcm1hdCwga2V5LCB2YWx1ZSwgcGFzc3dvcmQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGlmIChlbmNvZGVkICE9PSAnJykge1xuICAgICAgICAgICAgZW5jb2RlZCArPSAnJic7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZW5jb2RlZCArPSBlbmNvZGVVUklDb21wb25lbnQoa2V5KSArICc9JyArIG1hc2soZW5jb2RlVVJJQ29tcG9uZW50KHZhbHVlKSwgcGFzc3dvcmQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgYm9keSA9IGVuY29kZWQ7XG4gIH0gZWxzZSBpZiAoaXNNdWx0aVBhcnQpIHtcbiAgICB2YXIgYm9keVBhcmFtO1xuICAgIGlmICh0eXBlb2YgRm9ybURhdGEgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGJvZHlQYXJhbSA9IG5ldyBGb3JtRGF0YSgpO1xuXG4gICAgICBib2R5UGFyYW0udHlwZSA9ICdmb3JtRGF0YSc7XG5cbiAgICAgIGZvciAoa2V5IGluIGZvcm1QYXJhbXMpIHtcbiAgICAgICAgcGFyYW0gPSBmb3JtUGFyYW1zW2tleV0ucGFyYW07XG4gICAgICAgIHZhbHVlID0gYXJnc1trZXldO1xuXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgaWYoe30udG9TdHJpbmcuYXBwbHkodmFsdWUpID09PSAnW29iamVjdCBGaWxlXScpIHtcbiAgICAgICAgICAgIGJvZHlQYXJhbS5hcHBlbmQoa2V5LCB2YWx1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2UgaWYgKHZhbHVlLnR5cGUgPT09ICdmaWxlJyAmJiB2YWx1ZS52YWx1ZSkge1xuICAgICAgICAgICAgYm9keVBhcmFtLmFwcGVuZChrZXksIHZhbHVlLnZhbHVlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICAgIGlmKHBhcmFtLmNvbGxlY3Rpb25Gb3JtYXQgPT09ICdtdWx0aScpIHtcbiAgICAgICAgICAgICAgICBib2R5UGFyYW0uZGVsZXRlKGtleSk7XG4gICAgICAgICAgICAgICAgZm9yKHZhciB2IGluIHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICBib2R5UGFyYW0uYXBwZW5kKGtleSwgdmFsdWVbdl0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBib2R5UGFyYW0uYXBwZW5kKGtleSwgdGhpcy5lbmNvZGVRdWVyeUNvbGxlY3Rpb24ocGFyYW0uY29sbGVjdGlvbkZvcm1hdCwga2V5LCB2YWx1ZSkuc3BsaXQoJz0nKS5zbGljZSgxKS5qb2luKCc9JykpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgYm9keVBhcmFtLmFwcGVuZChrZXksIHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGJvZHkgPSBib2R5UGFyYW07XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgYm9keVBhcmFtID0ge307XG4gICAgICBmb3IgKGtleSBpbiBmb3JtUGFyYW1zKSB7XG4gICAgICAgIHZhbHVlID0gYXJnc1trZXldO1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICB2YXIgZGVsaW1ldGVyO1xuICAgICAgICAgIHZhciBmb3JtYXQgPSBwYXJhbS5jb2xsZWN0aW9uRm9ybWF0IHx8ICdtdWx0aSc7XG4gICAgICAgICAgaWYoZm9ybWF0ID09PSAnc3N2Jykge1xuICAgICAgICAgICAgZGVsaW1ldGVyID0gJyAnO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIGlmKGZvcm1hdCA9PT0gJ3BpcGVzJykge1xuICAgICAgICAgICAgZGVsaW1ldGVyID0gJ3wnO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIGlmKGZvcm1hdCA9PT0gJ3RzdicpIHtcbiAgICAgICAgICAgIGRlbGltZXRlciA9ICdcXHQnO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIGlmKGZvcm1hdCA9PT0gJ211bHRpJykge1xuICAgICAgICAgICAgYm9keVBhcmFtW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGRlbGltZXRlciA9ICcsJztcbiAgICAgICAgICB9XG4gICAgICAgICAgdmFyIGRhdGE7XG4gICAgICAgICAgdmFsdWUuZm9yRWFjaChmdW5jdGlvbih2KSB7XG4gICAgICAgICAgICBpZihkYXRhKSB7XG4gICAgICAgICAgICAgIGRhdGEgKz0gZGVsaW1ldGVyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgIGRhdGEgPSAnJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRhdGEgKz0gdjtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBib2R5UGFyYW1ba2V5XSA9IGRhdGE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgYm9keVBhcmFtW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgYm9keSA9IGJvZHlQYXJhbTtcbiAgICB9XG4gICAgaGVhZGVyc1snQ29udGVudC1UeXBlJ10gPSAnbXVsdGlwYXJ0L2Zvcm0tZGF0YSc7XG4gIH1cblxuICByZXR1cm4gYm9keTtcbn07XG5cbi8qKlxuICogZ2V0cyBzYW1wbGUgcmVzcG9uc2UgZm9yIGEgc2luZ2xlIG9wZXJhdGlvblxuICoqL1xuT3BlcmF0aW9uLnByb3RvdHlwZS5nZXRNb2RlbFNhbXBsZUpTT04gPSBmdW5jdGlvbiAodHlwZSwgbW9kZWxzKSB7XG4gIHZhciBsaXN0VHlwZSwgc2FtcGxlSnNvbiwgaW5uZXJUeXBlO1xuICBtb2RlbHMgPSBtb2RlbHMgfHwge307XG5cbiAgbGlzdFR5cGUgPSAodHlwZSBpbnN0YW5jZW9mIEFycmF5KTtcbiAgaW5uZXJUeXBlID0gbGlzdFR5cGUgPyB0eXBlWzBdIDogdHlwZTtcblxuICBpZihtb2RlbHNbaW5uZXJUeXBlXSkge1xuICAgIHNhbXBsZUpzb24gPSBtb2RlbHNbaW5uZXJUeXBlXS5jcmVhdGVKU09OU2FtcGxlKCk7XG4gIH0gZWxzZSBpZiAodGhpcy5nZXRJbmxpbmVNb2RlbChpbm5lclR5cGUpKXtcbiAgICBzYW1wbGVKc29uID0gdGhpcy5nZXRJbmxpbmVNb2RlbChpbm5lclR5cGUpLmNyZWF0ZUpTT05TYW1wbGUoKTsgLy8gbWF5IHJldHVybiBudWxsLCBpZiB0eXBlIGlzbid0IGNvcnJlY3RcbiAgfVxuXG5cbiAgaWYgKHNhbXBsZUpzb24pIHtcbiAgICBzYW1wbGVKc29uID0gbGlzdFR5cGUgPyBbc2FtcGxlSnNvbl0gOiBzYW1wbGVKc29uO1xuXG4gICAgaWYgKHR5cGVvZiBzYW1wbGVKc29uID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIHNhbXBsZUpzb247XG4gICAgfSBlbHNlIGlmIChfLmlzT2JqZWN0KHNhbXBsZUpzb24pKSB7XG4gICAgICB2YXIgdCA9IHNhbXBsZUpzb247XG5cbiAgICAgIGlmIChzYW1wbGVKc29uIGluc3RhbmNlb2YgQXJyYXkgJiYgc2FtcGxlSnNvbi5sZW5ndGggPiAwKSB7XG4gICAgICAgIHQgPSBzYW1wbGVKc29uWzBdO1xuICAgICAgfVxuXG4gICAgICBpZiAodC5ub2RlTmFtZSAmJiB0eXBlb2YgdCA9PT0gJ05vZGUnKSB7XG4gICAgICAgIHZhciB4bWxTdHJpbmcgPSBuZXcgWE1MU2VyaWFsaXplcigpLnNlcmlhbGl6ZVRvU3RyaW5nKHQpO1xuXG4gICAgICAgIHJldHVybiB0aGlzLmZvcm1hdFhtbCh4bWxTdHJpbmcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHNhbXBsZUpzb24sIG51bGwsIDIpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gc2FtcGxlSnNvbjtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogbGVnYWN5IGJpbmRpbmdcbiAqKi9cbk9wZXJhdGlvbi5wcm90b3R5cGUuZG8gPSBmdW5jdGlvbiAoYXJncywgb3B0cywgY2FsbGJhY2ssIGVycm9yLCBwYXJlbnQpIHtcbiAgcmV0dXJuIHRoaXMuZXhlY3V0ZShhcmdzLCBvcHRzLCBjYWxsYmFjaywgZXJyb3IsIHBhcmVudCk7XG59O1xuXG4vKipcbiAqIGV4ZWN1dGVzIGFuIG9wZXJhdGlvblxuICoqL1xuT3BlcmF0aW9uLnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24gKGFyZzEsIGFyZzIsIGFyZzMsIGFyZzQsIHBhcmVudCkge1xuICB2YXIgYXJncyA9IGFyZzEgfHwge307XG4gIHZhciBvcHRzID0ge30sIHN1Y2Nlc3MsIGVycm9yLCBkZWZlcnJlZCwgdGltZW91dDtcblxuICBpZiAoXy5pc09iamVjdChhcmcyKSkge1xuICAgIG9wdHMgPSBhcmcyO1xuICAgIHN1Y2Nlc3MgPSBhcmczO1xuICAgIGVycm9yID0gYXJnNDtcbiAgfVxuXG4gIHRpbWVvdXQgPSB0eXBlb2Ygb3B0cy50aW1lb3V0ICE9PSAndW5kZWZpbmVkJyA/IG9wdHMudGltZW91dCA6IHRoaXMudGltZW91dDtcblxuICBpZih0aGlzLmNsaWVudCkge1xuICAgIG9wdHMuY2xpZW50ID0gdGhpcy5jbGllbnQ7XG4gIH1cblxuICBpZih0aGlzLnJlcXVlc3RBZ2VudCkge1xuICAgIG9wdHMucmVxdWVzdEFnZW50ID0gdGhpcy5yZXF1ZXN0QWdlbnQ7XG4gIH1cblxuICAvLyBhZGQgdGhlIHJlcXVlc3QgaW50ZXJjZXB0b3IgZnJvbSBwYXJlbnQsIGlmIG5vbmUgc2VudCBmcm9tIGNsaWVudFxuICBpZighb3B0cy5yZXF1ZXN0SW50ZXJjZXB0b3IgJiYgdGhpcy5yZXF1ZXN0SW50ZXJjZXB0b3IgKSB7XG4gICAgb3B0cy5yZXF1ZXN0SW50ZXJjZXB0b3IgPSB0aGlzLnJlcXVlc3RJbnRlcmNlcHRvciA7XG4gIH1cblxuICBpZighb3B0cy5yZXNwb25zZUludGVyY2VwdG9yICYmIHRoaXMucmVzcG9uc2VJbnRlcmNlcHRvcikge1xuICAgIG9wdHMucmVzcG9uc2VJbnRlcmNlcHRvciA9IHRoaXMucmVzcG9uc2VJbnRlcmNlcHRvcjtcbiAgfVxuXG4gIGlmICh0eXBlb2YgYXJnMiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHN1Y2Nlc3MgPSBhcmcyO1xuICAgIGVycm9yID0gYXJnMztcbiAgfVxuXG4gIGlmICh0aGlzLnBhcmVudC51c2VQcm9taXNlKSB7XG4gICAgZGVmZXJyZWQgPSBRLmRlZmVyKCk7XG4gIH0gZWxzZSB7XG4gICAgc3VjY2VzcyA9IChzdWNjZXNzIHx8IHRoaXMucGFyZW50LmRlZmF1bHRTdWNjZXNzQ2FsbGJhY2sgfHwgaGVscGVycy5sb2cpO1xuICAgIGVycm9yID0gKGVycm9yIHx8IHRoaXMucGFyZW50LmRlZmF1bHRFcnJvckNhbGxiYWNrIHx8IGhlbHBlcnMubG9nKTtcbiAgfVxuXG4gIGlmICh0eXBlb2Ygb3B0cy51c2VKUXVlcnkgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgb3B0cy51c2VKUXVlcnkgPSB0aGlzLnVzZUpRdWVyeTtcbiAgfVxuXG4gIGlmICh0eXBlb2Ygb3B0cy5qcXVlcnlBamF4Q2FjaGUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgb3B0cy5qcXVlcnlBamF4Q2FjaGUgPSB0aGlzLmpxdWVyeUFqYXhDYWNoZTtcbiAgfVxuXG4gIGlmICh0eXBlb2Ygb3B0cy5lbmFibGVDb29raWVzID09PSAndW5kZWZpbmVkJykge1xuICAgIG9wdHMuZW5hYmxlQ29va2llcyA9IHRoaXMuZW5hYmxlQ29va2llcztcbiAgfVxuXG4gIHZhciBtaXNzaW5nUGFyYW1zID0gdGhpcy5nZXRNaXNzaW5nUGFyYW1zKGFyZ3MpO1xuXG4gIGlmIChtaXNzaW5nUGFyYW1zLmxlbmd0aCA+IDApIHtcbiAgICB2YXIgbWVzc2FnZSA9ICdtaXNzaW5nIHJlcXVpcmVkIHBhcmFtczogJyArIG1pc3NpbmdQYXJhbXM7XG5cbiAgICBoZWxwZXJzLmZhaWwobWVzc2FnZSk7XG5cbiAgICBpZiAodGhpcy5wYXJlbnQudXNlUHJvbWlzZSkge1xuICAgICAgZGVmZXJyZWQucmVqZWN0KG1lc3NhZ2UpO1xuICAgICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVycm9yKG1lc3NhZ2UsIHBhcmVudCk7XG4gICAgICByZXR1cm4ge307XG4gICAgfVxuICB9XG5cbiAgdmFyIGFsbEhlYWRlcnMgPSB0aGlzLmdldEhlYWRlclBhcmFtcyhhcmdzKTtcbiAgdmFyIGNvbnRlbnRUeXBlSGVhZGVycyA9IHRoaXMuc2V0Q29udGVudFR5cGVzKGFyZ3MsIG9wdHMpO1xuICB2YXIgaGVhZGVycyA9IHt9LCBhdHRybmFtZTtcblxuICBmb3IgKGF0dHJuYW1lIGluIGFsbEhlYWRlcnMpIHsgaGVhZGVyc1thdHRybmFtZV0gPSBhbGxIZWFkZXJzW2F0dHJuYW1lXTsgfVxuICBmb3IgKGF0dHJuYW1lIGluIGNvbnRlbnRUeXBlSGVhZGVycykgeyBoZWFkZXJzW2F0dHJuYW1lXSA9IGNvbnRlbnRUeXBlSGVhZGVyc1thdHRybmFtZV07IH1cblxuICB2YXIgYm9keSA9IHRoaXMuZ2V0Qm9keShjb250ZW50VHlwZUhlYWRlcnMsIGFyZ3MsIG9wdHMpO1xuICB2YXIgdXJsID0gdGhpcy51cmxpZnkoYXJncywgb3B0cy5tYXNrUGFzc3dvcmRzKTtcblxuICBpZih1cmwuaW5kZXhPZignLntmb3JtYXR9JykgPiAwKSB7XG4gICAgaWYoaGVhZGVycykge1xuICAgICAgdmFyIGZvcm1hdCA9IGhlYWRlcnMuQWNjZXB0IHx8IGhlYWRlcnMuYWNjZXB0O1xuICAgICAgaWYoZm9ybWF0ICYmIGZvcm1hdC5pbmRleE9mKCdqc29uJykgPiAwKSB7XG4gICAgICAgIHVybCA9IHVybC5yZXBsYWNlKCcue2Zvcm1hdH0nLCAnLmpzb24nKTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYoZm9ybWF0ICYmIGZvcm1hdC5pbmRleE9mKCd4bWwnKSA+IDApIHtcbiAgICAgICAgdXJsID0gdXJsLnJlcGxhY2UoJy57Zm9ybWF0fScsICcueG1sJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIG9iaiA9IHtcbiAgICB1cmw6IHVybCxcbiAgICBtZXRob2Q6IHRoaXMubWV0aG9kLnRvVXBwZXJDYXNlKCksXG4gICAgYm9keTogYm9keSxcbiAgICBlbmFibGVDb29raWVzOiBvcHRzLmVuYWJsZUNvb2tpZXMsXG4gICAgdXNlSlF1ZXJ5OiBvcHRzLnVzZUpRdWVyeSxcbiAgICBqcXVlcnlBamF4Q2FjaGU6IG9wdHMuanF1ZXJ5QWpheENhY2hlLFxuICAgIGRlZmVycmVkOiBkZWZlcnJlZCxcbiAgICBoZWFkZXJzOiBoZWFkZXJzLFxuICAgIGNsaWVudEF1dGhvcml6YXRpb25zOiBvcHRzLmNsaWVudEF1dGhvcml6YXRpb25zLFxuICAgIG9wZXJhdGlvbjogdGhpcyxcbiAgICBjb25uZWN0aW9uQWdlbnQ6IHRoaXMuY29ubmVjdGlvbkFnZW50LFxuICAgIG9uOiB7XG4gICAgICByZXNwb25zZTogZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgIGlmIChkZWZlcnJlZCkge1xuICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUocmVzcG9uc2UpO1xuICAgICAgICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBzdWNjZXNzKHJlc3BvbnNlLCBwYXJlbnQpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgZXJyb3I6IGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgICBpZiAoZGVmZXJyZWQpIHtcbiAgICAgICAgICBkZWZlcnJlZC5yZWplY3QocmVzcG9uc2UpO1xuICAgICAgICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBlcnJvcihyZXNwb25zZSwgcGFyZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBpZiAodGltZW91dCkge1xuICAgIG9iai50aW1lb3V0ID0gdGltZW91dDtcbiAgfVxuXG4gIHRoaXMuY2xpZW50QXV0aG9yaXphdGlvbnMuYXBwbHkob2JqLCB0aGlzLm9wZXJhdGlvbi5zZWN1cml0eSk7XG4gIGlmIChvcHRzLm1vY2sgPT09IHRydWUpIHtcbiAgICBpZihvcHRzLnJlcXVlc3RJbnRlcmNlcHRvcikge1xuICAgICAgb3B0cy5yZXF1ZXN0SW50ZXJjZXB0b3IuYXBwbHkob2JqKTtcbiAgICB9XG4gICAgcmV0dXJuIG9iajtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbmV3IFN3YWdnZXJIdHRwKCkuZXhlY3V0ZShvYmosIG9wdHMpO1xuICB9XG59O1xuXG5mdW5jdGlvbiBpdGVtQnlQcmlvcml0eShjb2wsIGl0ZW1Qcmlvcml0eSkge1xuXG4gIC8vIE5vIHByaW9yaXRpZXM/IHJldHVybiBmaXJzdC4uLlxuICBpZihfLmlzRW1wdHkoaXRlbVByaW9yaXR5KSkge1xuICAgIHJldHVybiBjb2xbMF07XG4gIH1cblxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gaXRlbVByaW9yaXR5Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgaWYoY29sLmluZGV4T2YoaXRlbVByaW9yaXR5W2ldKSA+IC0xKSB7XG4gICAgICByZXR1cm4gaXRlbVByaW9yaXR5W2ldO1xuICAgIH1cbiAgfVxuXG4gIC8vIE90aGVyd2lzZSByZXR1cm4gZmlyc3RcbiAgcmV0dXJuIGNvbFswXTtcbn1cblxuT3BlcmF0aW9uLnByb3RvdHlwZS5zZXRDb250ZW50VHlwZXMgPSBmdW5jdGlvbiAoYXJncywgb3B0cykge1xuICAvLyBkZWZhdWx0IHR5cGVcbiAgdmFyIGFsbERlZmluZWRQYXJhbXMgPSB0aGlzLnBhcmFtZXRlcnM7XG4gIHZhciBib2R5O1xuICB2YXIgY29uc3VtZXMgPSBhcmdzLnBhcmFtZXRlckNvbnRlbnRUeXBlIHx8IGl0ZW1CeVByaW9yaXR5KHRoaXMuY29uc3VtZXMsIFsnYXBwbGljYXRpb24vanNvbicsICdhcHBsaWNhdGlvbi95YW1sJ10pO1xuICB2YXIgYWNjZXB0cyA9IG9wdHMucmVzcG9uc2VDb250ZW50VHlwZSB8fCBpdGVtQnlQcmlvcml0eSh0aGlzLnByb2R1Y2VzLCBbJ2FwcGxpY2F0aW9uL2pzb24nLCAnYXBwbGljYXRpb24veWFtbCddKTtcbiAgdmFyIGRlZmluZWRGaWxlUGFyYW1zID0gW107XG4gIHZhciBkZWZpbmVkRm9ybVBhcmFtcyA9IFtdO1xuICB2YXIgaGVhZGVycyA9IHt9O1xuICB2YXIgaTtcblxuICAvLyBnZXQgcGFyYW1zIGZyb20gdGhlIG9wZXJhdGlvbiBhbmQgc2V0IHRoZW0gaW4gZGVmaW5lZEZpbGVQYXJhbXMsIGRlZmluZWRGb3JtUGFyYW1zLCBoZWFkZXJzXG4gIGZvciAoaSA9IDA7IGkgPCBhbGxEZWZpbmVkUGFyYW1zLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcmFtID0gYWxsRGVmaW5lZFBhcmFtc1tpXTtcblxuICAgIGlmIChwYXJhbS5pbiA9PT0gJ2Zvcm1EYXRhJykge1xuICAgICAgaWYgKHBhcmFtLnR5cGUgPT09ICdmaWxlJykge1xuICAgICAgICBkZWZpbmVkRmlsZVBhcmFtcy5wdXNoKHBhcmFtKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlZmluZWRGb3JtUGFyYW1zLnB1c2gocGFyYW0pO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAocGFyYW0uaW4gPT09ICdoZWFkZXInICYmIG9wdHMpIHtcbiAgICAgIHZhciBrZXkgPSBwYXJhbS5uYW1lO1xuICAgICAgdmFyIGhlYWRlclZhbHVlID0gb3B0c1twYXJhbS5uYW1lXTtcblxuICAgICAgaWYgKHR5cGVvZiBvcHRzW3BhcmFtLm5hbWVdICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBoZWFkZXJzW2tleV0gPSBoZWFkZXJWYWx1ZTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHBhcmFtLmluID09PSAnYm9keScgJiYgdHlwZW9mIGFyZ3NbcGFyYW0ubmFtZV0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBib2R5ID0gYXJnc1twYXJhbS5uYW1lXTtcbiAgICB9XG4gIH1cblxuICAvLyBpZiB0aGVyZSdzIGEgYm9keSwgbmVlZCB0byBzZXQgdGhlIGNvbnN1bWVzIGhlYWRlciB2aWEgcmVxdWVzdENvbnRlbnRUeXBlXG4gIHZhciBoYXNCb2R5ID0gYm9keSB8fCBkZWZpbmVkRmlsZVBhcmFtcy5sZW5ndGggfHwgZGVmaW5lZEZvcm1QYXJhbXMubGVuZ3RoO1xuICBpZiAodGhpcy5tZXRob2QgPT09ICdwb3N0JyB8fCB0aGlzLm1ldGhvZCA9PT0gJ3B1dCcgfHwgdGhpcy5tZXRob2QgPT09ICdwYXRjaCcgfHxcbiAgICAgICgodGhpcy5tZXRob2QgPT09ICdkZWxldGUnIHx8IHRoaXMubWV0aG9kID09PSAnZ2V0JykgJiYgaGFzQm9keSkpIHtcbiAgICBpZiAob3B0cy5yZXF1ZXN0Q29udGVudFR5cGUpIHtcbiAgICAgIGNvbnN1bWVzID0gb3B0cy5yZXF1ZXN0Q29udGVudFR5cGU7XG4gICAgfVxuICAgIC8vIGlmIGFueSBmb3JtIHBhcmFtcywgY29udGVudCB0eXBlIG11c3QgYmUgc2V0XG4gICAgaWYgKGRlZmluZWRGb3JtUGFyYW1zLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN1bWVzID0gdW5kZWZpbmVkO1xuICAgICAgaWYgKG9wdHMucmVxdWVzdENvbnRlbnRUeXBlKSB7ICAgICAgICAgICAgIC8vIG92ZXJyaWRlIGlmIHNldFxuICAgICAgICBjb25zdW1lcyA9IG9wdHMucmVxdWVzdENvbnRlbnRUeXBlO1xuICAgICAgfSBlbHNlIGlmIChkZWZpbmVkRmlsZVBhcmFtcy5sZW5ndGggPiAwKSB7IC8vIGlmIGEgZmlsZSwgbXVzdCBiZSBtdWx0aXBhcnQvZm9ybS1kYXRhXG4gICAgICAgIGNvbnN1bWVzID0gJ211bHRpcGFydC9mb3JtLWRhdGEnO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHRoaXMuY29uc3VtZXMgJiYgdGhpcy5jb25zdW1lcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgLy8gdXNlIHRoZSBjb25zdW1lcyBzZXR0aW5nXG4gICAgICAgICAgZm9yKHZhciBjIGluIHRoaXMuY29uc3VtZXMpIHtcbiAgICAgICAgICAgIHZhciBjaGsgPSB0aGlzLmNvbnN1bWVzW2NdO1xuICAgICAgICAgICAgaWYoY2hrLmluZGV4T2YoJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcpID09PSAwIHx8IGNoay5pbmRleE9mKCdtdWx0aXBhcnQvZm9ybS1kYXRhJykgPT09IDApIHtcbiAgICAgICAgICAgICAgY29uc3VtZXMgPSBjaGs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZih0eXBlb2YgY29uc3VtZXMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIC8vIGRlZmF1bHQgdG8geC13d3ctZnJvbS11cmxlbmNvZGVkXG4gICAgICAgIGNvbnN1bWVzID0gJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCc7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGVsc2Uge1xuICAgIGNvbnN1bWVzID0gbnVsbDtcbiAgfVxuXG4gIGlmIChjb25zdW1lcyAmJiB0aGlzLmNvbnN1bWVzKSB7XG4gICAgaWYgKHRoaXMuY29uc3VtZXMuaW5kZXhPZihjb25zdW1lcykgPT09IC0xKSB7XG4gICAgICBoZWxwZXJzLmxvZygnc2VydmVyIGRvZXNuXFwndCBjb25zdW1lICcgKyBjb25zdW1lcyArICcsIHRyeSAnICsgSlNPTi5zdHJpbmdpZnkodGhpcy5jb25zdW1lcykpO1xuICAgIH1cbiAgfVxuXG4gIGlmICghdGhpcy5tYXRjaGVzQWNjZXB0KGFjY2VwdHMpKSB7XG4gICAgaGVscGVycy5sb2coJ3NlcnZlciBjYW5cXCd0IHByb2R1Y2UgJyArIGFjY2VwdHMpO1xuICB9XG5cbiAgaWYgKChjb25zdW1lcyAmJiBib2R5ICE9PSAnJykgfHwgKGNvbnN1bWVzID09PSAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJykpIHtcbiAgICBoZWFkZXJzWydDb250ZW50LVR5cGUnXSA9IGNvbnN1bWVzO1xuICB9XG4gIGVsc2UgaWYodGhpcy5jb25zdW1lcyAmJiB0aGlzLmNvbnN1bWVzLmxlbmd0aCA+IDAgJiYgdGhpcy5jb25zdW1lc1swXSA9PT0gJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcpIHtcbiAgICBoZWFkZXJzWydDb250ZW50LVR5cGUnXSA9IHRoaXMuY29uc3VtZXNbMF07XG4gIH1cblxuICBpZiAoYWNjZXB0cykge1xuICAgIGhlYWRlcnMuQWNjZXB0ID0gYWNjZXB0cztcbiAgfVxuXG4gIHJldHVybiBoZWFkZXJzO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHJlcXVlc3QgYWNjZXB0cyBoZWFkZXIgbWF0Y2hlcyBhbnl0aGluZyBpbiB0aGlzLnByb2R1Y2VzLlxuICogIElmIHRoaXMucHJvZHVjZXMgY29udGFpbnMgKiAvICosIGlnbm9yZSB0aGUgYWNjZXB0IGhlYWRlci5cbiAqIEBwYXJhbSB7c3RyaW5nPX0gYWNjZXB0cyBUaGUgY2xpZW50IHJlcXVlc3QgYWNjZXB0IGhlYWRlci5cbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbk9wZXJhdGlvbi5wcm90b3R5cGUubWF0Y2hlc0FjY2VwdCA9IGZ1bmN0aW9uKGFjY2VwdHMpIHtcbiAgLy8gbm8gYWNjZXB0cyBvciBwcm9kdWNlcywgbm8gcHJvYmxlbSFcbiAgaWYgKCFhY2NlcHRzIHx8ICF0aGlzLnByb2R1Y2VzKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIHRoaXMucHJvZHVjZXMuaW5kZXhPZihhY2NlcHRzKSAhPT0gLTEgfHwgdGhpcy5wcm9kdWNlcy5pbmRleE9mKCcqLyonKSAhPT0gLTE7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmFzQ3VybCA9IGZ1bmN0aW9uIChhcmdzMSwgYXJnczIpIHtcbiAgdmFyIG9wdHMgPSB7bW9jazogdHJ1ZSwgbWFza1Bhc3N3b3JkczogdHJ1ZX07XG4gIGlmICh0eXBlb2YgYXJnczIgPT09ICdvYmplY3QnKSB7XG4gICAgZm9yICh2YXIgYXJnS2V5IGluIGFyZ3MyKSB7XG4gICAgICBvcHRzW2FyZ0tleV0gPSBhcmdzMlthcmdLZXldO1xuICAgIH1cbiAgfVxuICB2YXIgb2JqID0gdGhpcy5leGVjdXRlKGFyZ3MxLCBvcHRzKTtcblxuICB0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zLmFwcGx5KG9iaiwgdGhpcy5vcGVyYXRpb24uc2VjdXJpdHkpO1xuXG4gIHZhciByZXN1bHRzID0gW107XG5cbiAgcmVzdWx0cy5wdXNoKCctWCAnICsgdGhpcy5tZXRob2QudG9VcHBlckNhc2UoKSk7XG5cbiAgaWYgKHR5cGVvZiBvYmouaGVhZGVycyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB2YXIga2V5O1xuXG4gICAgZm9yIChrZXkgaW4gb2JqLmhlYWRlcnMpIHtcbiAgICAgIHZhciB2YWx1ZSA9IG9iai5oZWFkZXJzW2tleV07XG4gICAgICBpZih0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKXtcbiAgICAgICAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKC9cXCcvZywgJ1xcXFx1MDAyNycpO1xuICAgICAgfVxuICAgICAgcmVzdWx0cy5wdXNoKCctLWhlYWRlciBcXCcnICsga2V5ICsgJzogJyArIHZhbHVlICsgJ1xcJycpO1xuICAgIH1cbiAgfVxuICB2YXIgaXNGb3JtRGF0YSA9IGZhbHNlO1xuICB2YXIgaXNNdWx0aXBhcnQgPSBmYWxzZTtcblxuICB2YXIgdHlwZSA9IG9iai5oZWFkZXJzWydDb250ZW50LVR5cGUnXTtcbiAgaWYodHlwZSAmJiB0eXBlLmluZGV4T2YoJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcpID09PSAwKSB7XG4gICAgaXNGb3JtRGF0YSA9IHRydWU7XG4gIH1cbiAgZWxzZSBpZiAodHlwZSAmJiB0eXBlLmluZGV4T2YoJ211bHRpcGFydC9mb3JtLWRhdGEnKSA9PT0gMCkge1xuICAgIGlzRm9ybURhdGEgPSB0cnVlO1xuICAgIGlzTXVsdGlwYXJ0ID0gdHJ1ZTtcbiAgfVxuXG4gIGlmIChvYmouYm9keSkge1xuICAgIHZhciBib2R5O1xuICAgIGlmIChfLmlzT2JqZWN0KG9iai5ib2R5KSkge1xuICAgICAgaWYoaXNNdWx0aXBhcnQpIHtcbiAgICAgICAgaXNNdWx0aXBhcnQgPSB0cnVlO1xuICAgICAgICAvLyBhZGQgdGhlIGZvcm0gZGF0YVxuICAgICAgICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5wYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdmFyIHBhcmFtZXRlciA9IHRoaXMucGFyYW1ldGVyc1tpXTtcbiAgICAgICAgICBpZihwYXJhbWV0ZXIuaW4gPT09ICdmb3JtRGF0YScpIHtcbiAgICAgICAgICAgIGlmICghYm9keSkge1xuICAgICAgICAgICAgICBib2R5ID0gJyc7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBwYXJhbVZhbHVlO1xuICAgICAgICAgICAgaWYodHlwZW9mIEZvcm1EYXRhID09PSAnZnVuY3Rpb24nICYmIG9iai5ib2R5IGluc3RhbmNlb2YgRm9ybURhdGEpIHtcbiAgICAgICAgICAgICAgcGFyYW1WYWx1ZSA9IG9iai5ib2R5LmdldEFsbChwYXJhbWV0ZXIubmFtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgcGFyYW1WYWx1ZSA9IG9iai5ib2R5W3BhcmFtZXRlci5uYW1lXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwYXJhbVZhbHVlKSB7XG4gICAgICAgICAgICAgIGlmIChwYXJhbWV0ZXIudHlwZSA9PT0gJ2ZpbGUnKSB7XG4gICAgICAgICAgICAgICAgaWYocGFyYW1WYWx1ZS5uYW1lKSB7XG4gICAgICAgICAgICAgICAgICBib2R5ICs9ICctRiAnICsgcGFyYW1ldGVyLm5hbWUgKyAnPUBcIicgKyBwYXJhbVZhbHVlLm5hbWUgKyAnXCIgJztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocGFyYW1WYWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAgIGlmKHBhcmFtZXRlci5jb2xsZWN0aW9uRm9ybWF0ID09PSAnbXVsdGknKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvcih2YXIgdiBpbiBwYXJhbVZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgYm9keSArPSAnLUYgJyArIHRoaXMuZW5jb2RlUXVlcnlLZXkocGFyYW1ldGVyLm5hbWUpICsgJz0nICsgbWFzayhwYXJhbVZhbHVlW3ZdLCBwYXJhbWV0ZXIuZm9ybWF0KSArICcgJztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGJvZHkgKz0gJy1GICcgKyB0aGlzLmVuY29kZVF1ZXJ5Q29sbGVjdGlvbihwYXJhbWV0ZXIuY29sbGVjdGlvbkZvcm1hdCwgcGFyYW1ldGVyLm5hbWUsIG1hc2socGFyYW1WYWx1ZSwgcGFyYW1ldGVyLmZvcm1hdCkpICsgJyAnO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBib2R5ICs9ICctRiAnICsgdGhpcy5lbmNvZGVRdWVyeUtleShwYXJhbWV0ZXIubmFtZSkgKyAnPScgKyBtYXNrKHBhcmFtVmFsdWUsIHBhcmFtZXRlci5mb3JtYXQpICsgJyAnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYoIWJvZHkpIHtcbiAgICAgICAgYm9keSA9IEpTT04uc3RyaW5naWZ5KG9iai5ib2R5KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgYm9keSA9IG9iai5ib2R5O1xuICAgIH1cbiAgICAvLyBlc2NhcGUgQCA9PiAlNDAsICcgPT4gJTI3XG4gICAgYm9keSA9IGJvZHkucmVwbGFjZSgvXFwnL2csICclMjcnKS5yZXBsYWNlKC9cXG4vZywgJyBcXFxcIFxcbiAnKTtcblxuICAgIGlmKCFpc0Zvcm1EYXRhKSB7XG4gICAgICAvLyBlc2NhcGUgJiA9PiAlMjZcbiAgICAgIGJvZHkgPSBib2R5LnJlcGxhY2UoLyYvZywgJyUyNicpO1xuICAgIH1cbiAgICBpZihpc011bHRpcGFydCkge1xuICAgICAgcmVzdWx0cy5wdXNoKGJvZHkpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHJlc3VsdHMucHVzaCgnLWQgXFwnJyArIGJvZHkucmVwbGFjZSgvQC9nLCAnJTQwJykgKyAnXFwnJyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuICdjdXJsICcgKyAocmVzdWx0cy5qb2luKCcgJykpICsgJyBcXCcnICsgb2JqLnVybCArICdcXCcnO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5lbmNvZGVQYXRoQ29sbGVjdGlvbiA9IGZ1bmN0aW9uICh0eXBlLCBuYW1lLCB2YWx1ZSwgbWFza1Bhc3N3b3Jkcykge1xuICB2YXIgZW5jb2RlZCA9ICcnO1xuICB2YXIgaTtcbiAgdmFyIHNlcGFyYXRvciA9ICcnO1xuXG4gIGlmICh0eXBlID09PSAnc3N2Jykge1xuICAgIHNlcGFyYXRvciA9ICclMjAnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICd0c3YnKSB7XG4gICAgc2VwYXJhdG9yID0gJyUwOSc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3BpcGVzJykge1xuICAgIHNlcGFyYXRvciA9ICd8JztcbiAgfSBlbHNlIHtcbiAgICBzZXBhcmF0b3IgPSAnLCc7XG4gIH1cblxuICBmb3IgKGkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoaSA9PT0gMCkge1xuICAgICAgZW5jb2RlZCA9IHRoaXMuZW5jb2RlUXVlcnlQYXJhbSh2YWx1ZVtpXSwgbWFza1Bhc3N3b3Jkcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVuY29kZWQgKz0gc2VwYXJhdG9yICsgdGhpcy5lbmNvZGVRdWVyeVBhcmFtKHZhbHVlW2ldLCBtYXNrUGFzc3dvcmRzKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZW5jb2RlZDtcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuZW5jb2RlUXVlcnlDb2xsZWN0aW9uID0gZnVuY3Rpb24gKHR5cGUsIG5hbWUsIHZhbHVlLCBtYXNrUGFzc3dvcmRzKSB7XG4gIHZhciBlbmNvZGVkID0gJyc7XG4gIHZhciBpO1xuXG4gIHR5cGUgPSB0eXBlIHx8ICdkZWZhdWx0JztcbiAgaWYgKHR5cGUgPT09ICdkZWZhdWx0JyB8fCB0eXBlID09PSAnbXVsdGknKSB7XG4gICAgZm9yIChpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoaSA+IDApIHtlbmNvZGVkICs9ICcmJzt9XG5cbiAgICAgIGVuY29kZWQgKz0gdGhpcy5lbmNvZGVRdWVyeUtleShuYW1lKSArICc9JyArIG1hc2sodGhpcy5lbmNvZGVRdWVyeVBhcmFtKHZhbHVlW2ldKSwgbWFza1Bhc3N3b3Jkcyk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHZhciBzZXBhcmF0b3IgPSAnJztcblxuICAgIGlmICh0eXBlID09PSAnY3N2Jykge1xuICAgICAgc2VwYXJhdG9yID0gJywnO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3NzdicpIHtcbiAgICAgIHNlcGFyYXRvciA9ICclMjAnO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3RzdicpIHtcbiAgICAgIHNlcGFyYXRvciA9ICclMDknO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3BpcGVzJykge1xuICAgICAgc2VwYXJhdG9yID0gJ3wnO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2JyYWNrZXRzJykge1xuICAgICAgZm9yIChpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChpICE9PSAwKSB7XG4gICAgICAgICAgZW5jb2RlZCArPSAnJic7XG4gICAgICAgIH1cbiAgICAgICAgZW5jb2RlZCArPSB0aGlzLmVuY29kZVF1ZXJ5S2V5KG5hbWUpICsgJ1tdPScgKyBtYXNrKHRoaXMuZW5jb2RlUXVlcnlQYXJhbSh2YWx1ZVtpXSksIG1hc2tQYXNzd29yZHMpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzZXBhcmF0b3IgIT09ICcnKSB7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGkgPT09IDApIHtcbiAgICAgICAgICBlbmNvZGVkID0gdGhpcy5lbmNvZGVRdWVyeUtleShuYW1lKSArICc9JyArIHRoaXMuZW5jb2RlUXVlcnlQYXJhbSh2YWx1ZVtpXSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZW5jb2RlZCArPSBzZXBhcmF0b3IgKyB0aGlzLmVuY29kZVF1ZXJ5UGFyYW0odmFsdWVbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGVuY29kZWQ7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmVuY29kZVF1ZXJ5S2V5ID0gZnVuY3Rpb24gKGFyZykge1xuICByZXR1cm4gZW5jb2RlVVJJQ29tcG9uZW50KGFyZylcbiAgICAgIC5yZXBsYWNlKCclNUInLCdbJykucmVwbGFjZSgnJTVEJywgJ10nKS5yZXBsYWNlKCclMjQnLCAnJCcpO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5lbmNvZGVRdWVyeVBhcmFtID0gZnVuY3Rpb24gKGFyZywgbWFza1Bhc3N3b3Jkcykge1xuICBpZihtYXNrUGFzc3dvcmRzKSB7XG4gICAgcmV0dXJuIFwiKioqKioqXCI7XG4gIH1cbiAgaWYoYXJnICE9PSB1bmRlZmluZWQgJiYgYXJnICE9PSBudWxsKSB7XG4gICAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudChhcmcpO1xuICB9XG4gIGVsc2Uge1xuICAgIHJldHVybiAnJztcbiAgfVxufTtcblxuLyoqXG4gKiBUT0RPIHJldmlzaXQsIG1pZ2h0IG5vdCB3YW50IHRvIGxlYXZlICcvJ1xuICoqL1xuT3BlcmF0aW9uLnByb3RvdHlwZS5lbmNvZGVQYXRoUGFyYW0gPSBmdW5jdGlvbiAocGF0aFBhcmFtLCBtYXNrUGFzc3dvcmRzKSB7XG4gIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQocGF0aFBhcmFtLCBtYXNrUGFzc3dvcmRzKTtcbn07XG5cbnZhciBtYXNrID0gZnVuY3Rpb24odmFsdWUsIGZvcm1hdCkge1xuICBpZih0eXBlb2YgZm9ybWF0ID09PSAnc3RyaW5nJyAmJiBmb3JtYXQgPT09ICdwYXNzd29yZCcpIHtcbiAgICByZXR1cm4gJyoqKioqKic7XG4gIH1cbiAgcmV0dXJuIHZhbHVlO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgT3BlcmF0aW9uR3JvdXAgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICh0YWcsIGRlc2NyaXB0aW9uLCBleHRlcm5hbERvY3MsIG9wZXJhdGlvbikge1xuICB0aGlzLmRlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247XG4gIHRoaXMuZXh0ZXJuYWxEb2NzID0gZXh0ZXJuYWxEb2NzO1xuICB0aGlzLm5hbWUgPSB0YWc7XG4gIHRoaXMub3BlcmF0aW9uID0gb3BlcmF0aW9uO1xuICB0aGlzLm9wZXJhdGlvbnNBcnJheSA9IFtdO1xuICB0aGlzLnBhdGggPSB0YWc7XG4gIHRoaXMudGFnID0gdGFnO1xufTtcblxuT3BlcmF0aW9uR3JvdXAucHJvdG90eXBlLnNvcnQgPSBmdW5jdGlvbiAoKSB7XG5cbn07XG5cbiIsIi8vIHNoaW0gZm9yIHVzaW5nIHByb2Nlc3MgaW4gYnJvd3NlclxuXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG52YXIgcXVldWUgPSBbXTtcbnZhciBkcmFpbmluZyA9IGZhbHNlO1xuXG5mdW5jdGlvbiBkcmFpblF1ZXVlKCkge1xuICAgIGlmIChkcmFpbmluZykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGRyYWluaW5nID0gdHJ1ZTtcbiAgICB2YXIgY3VycmVudFF1ZXVlO1xuICAgIHZhciBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgd2hpbGUobGVuKSB7XG4gICAgICAgIGN1cnJlbnRRdWV1ZSA9IHF1ZXVlO1xuICAgICAgICBxdWV1ZSA9IFtdO1xuICAgICAgICB2YXIgaSA9IC0xO1xuICAgICAgICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgICAgICAgICBjdXJyZW50UXVldWVbaV0oKTtcbiAgICAgICAgfVxuICAgICAgICBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgfVxuICAgIGRyYWluaW5nID0gZmFsc2U7XG59XG5wcm9jZXNzLm5leHRUaWNrID0gZnVuY3Rpb24gKGZ1bikge1xuICAgIHF1ZXVlLnB1c2goZnVuKTtcbiAgICBpZiAoIWRyYWluaW5nKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZHJhaW5RdWV1ZSwgMCk7XG4gICAgfVxufTtcblxucHJvY2Vzcy50aXRsZSA9ICdicm93c2VyJztcbnByb2Nlc3MuYnJvd3NlciA9IHRydWU7XG5wcm9jZXNzLmVudiA9IHt9O1xucHJvY2Vzcy5hcmd2ID0gW107XG5wcm9jZXNzLnZlcnNpb24gPSAnJzsgLy8gZW1wdHkgc3RyaW5nIHRvIGF2b2lkIHJlZ2V4cCBpc3N1ZXNcbnByb2Nlc3MudmVyc2lvbnMgPSB7fTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnByb2Nlc3Mub24gPSBub29wO1xucHJvY2Vzcy5hZGRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLm9uY2UgPSBub29wO1xucHJvY2Vzcy5vZmYgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUFsbExpc3RlbmVycyA9IG5vb3A7XG5wcm9jZXNzLmVtaXQgPSBub29wO1xuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5cbi8vIFRPRE8oc2h0eWxtYW4pXG5wcm9jZXNzLmN3ZCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuICcvJyB9O1xucHJvY2Vzcy5jaGRpciA9IGZ1bmN0aW9uIChkaXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuY2hkaXIgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcbnByb2Nlc3MudW1hc2sgPSBmdW5jdGlvbigpIHsgcmV0dXJuIDA7IH07XG4iLCIoZnVuY3Rpb24gKEJ1ZmZlcil7XG4oZnVuY3Rpb24gKCkge1xuICBcInVzZSBzdHJpY3RcIjtcblxuICBmdW5jdGlvbiBidG9hKHN0cikge1xuICAgIHZhciBidWZmZXJcbiAgICAgIDtcblxuICAgIGlmIChzdHIgaW5zdGFuY2VvZiBCdWZmZXIpIHtcbiAgICAgIGJ1ZmZlciA9IHN0cjtcbiAgICB9IGVsc2Uge1xuICAgICAgYnVmZmVyID0gbmV3IEJ1ZmZlcihzdHIudG9TdHJpbmcoKSwgJ2JpbmFyeScpO1xuICAgIH1cblxuICAgIHJldHVybiBidWZmZXIudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICB9XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBidG9hO1xufSgpKTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyKVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ6dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiSW01dlpHVmZiVzlrZFd4bGN5OWlkRzloTDJsdVpHVjRMbXB6SWwwc0ltNWhiV1Z6SWpwYlhTd2liV0Z3Y0dsdVozTWlPaUk3UVVGQlFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFTSXNJbVpwYkdVaU9pSm5aVzVsY21GMFpXUXVhbk1pTENKemIzVnlZMlZTYjI5MElqb2lJaXdpYzI5MWNtTmxjME52Ym5SbGJuUWlPbHNpS0daMWJtTjBhVzl1SUNncElIdGNiaUFnWENKMWMyVWdjM1J5YVdOMFhDSTdYRzVjYmlBZ1puVnVZM1JwYjI0Z1luUnZZU2h6ZEhJcElIdGNiaUFnSUNCMllYSWdZblZtWm1WeVhHNGdJQ0FnSUNBN1hHNWNiaUFnSUNCcFppQW9jM1J5SUdsdWMzUmhibU5sYjJZZ1FuVm1abVZ5S1NCN1hHNGdJQ0FnSUNCaWRXWm1aWElnUFNCemRISTdYRzRnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUdKMVptWmxjaUE5SUc1bGR5QkNkV1ptWlhJb2MzUnlMblJ2VTNSeWFXNW5LQ2tzSUNkaWFXNWhjbmtuS1R0Y2JpQWdJQ0I5WEc1Y2JpQWdJQ0J5WlhSMWNtNGdZblZtWm1WeUxuUnZVM1J5YVc1bktDZGlZWE5sTmpRbktUdGNiaUFnZlZ4dVhHNGdJRzF2WkhWc1pTNWxlSEJ2Y25SeklEMGdZblJ2WVR0Y2JuMG9LU2s3WEc0aVhYMD0iLCIvKiFcbiAqIFRoZSBidWZmZXIgbW9kdWxlIGZyb20gbm9kZS5qcywgZm9yIHRoZSBicm93c2VyLlxuICpcbiAqIEBhdXRob3IgICBGZXJvc3MgQWJvdWtoYWRpamVoIDxmZXJvc3NAZmVyb3NzLm9yZz4gPGh0dHA6Ly9mZXJvc3Mub3JnPlxuICogQGxpY2Vuc2UgIE1JVFxuICovXG5cbnZhciBiYXNlNjQgPSByZXF1aXJlKCdiYXNlNjQtanMnKVxudmFyIGllZWU3NTQgPSByZXF1aXJlKCdpZWVlNzU0JylcbnZhciBpc0FycmF5ID0gcmVxdWlyZSgnaXMtYXJyYXknKVxuXG5leHBvcnRzLkJ1ZmZlciA9IEJ1ZmZlclxuZXhwb3J0cy5TbG93QnVmZmVyID0gU2xvd0J1ZmZlclxuZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUyA9IDUwXG5CdWZmZXIucG9vbFNpemUgPSA4MTkyIC8vIG5vdCB1c2VkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb25cblxudmFyIHJvb3RQYXJlbnQgPSB7fVxuXG4vKipcbiAqIElmIGBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVGA6XG4gKiAgID09PSB0cnVlICAgIFVzZSBVaW50OEFycmF5IGltcGxlbWVudGF0aW9uIChmYXN0ZXN0KVxuICogICA9PT0gZmFsc2UgICBVc2UgT2JqZWN0IGltcGxlbWVudGF0aW9uIChtb3N0IGNvbXBhdGlibGUsIGV2ZW4gSUU2KVxuICpcbiAqIEJyb3dzZXJzIHRoYXQgc3VwcG9ydCB0eXBlZCBhcnJheXMgYXJlIElFIDEwKywgRmlyZWZveCA0KywgQ2hyb21lIDcrLCBTYWZhcmkgNS4xKyxcbiAqIE9wZXJhIDExLjYrLCBpT1MgNC4yKy5cbiAqXG4gKiBEdWUgdG8gdmFyaW91cyBicm93c2VyIGJ1Z3MsIHNvbWV0aW1lcyB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uIHdpbGwgYmUgdXNlZCBldmVuXG4gKiB3aGVuIHRoZSBicm93c2VyIHN1cHBvcnRzIHR5cGVkIGFycmF5cy5cbiAqXG4gKiBOb3RlOlxuICpcbiAqICAgLSBGaXJlZm94IDQtMjkgbGFja3Mgc3VwcG9ydCBmb3IgYWRkaW5nIG5ldyBwcm9wZXJ0aWVzIHRvIGBVaW50OEFycmF5YCBpbnN0YW5jZXMsXG4gKiAgICAgU2VlOiBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD02OTU0MzguXG4gKlxuICogICAtIFNhZmFyaSA1LTcgbGFja3Mgc3VwcG9ydCBmb3IgY2hhbmdpbmcgdGhlIGBPYmplY3QucHJvdG90eXBlLmNvbnN0cnVjdG9yYCBwcm9wZXJ0eVxuICogICAgIG9uIG9iamVjdHMuXG4gKlxuICogICAtIENocm9tZSA5LTEwIGlzIG1pc3NpbmcgdGhlIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24uXG4gKlxuICogICAtIElFMTAgaGFzIGEgYnJva2VuIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyBhcnJheXMgb2ZcbiAqICAgICBpbmNvcnJlY3QgbGVuZ3RoIGluIHNvbWUgc2l0dWF0aW9ucy5cblxuICogV2UgZGV0ZWN0IHRoZXNlIGJ1Z2d5IGJyb3dzZXJzIGFuZCBzZXQgYEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUYCB0byBgZmFsc2VgIHNvIHRoZXlcbiAqIGdldCB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uLCB3aGljaCBpcyBzbG93ZXIgYnV0IGJlaGF2ZXMgY29ycmVjdGx5LlxuICovXG5CdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCA9IChmdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIEJhciAoKSB7fVxuICB0cnkge1xuICAgIHZhciBhcnIgPSBuZXcgVWludDhBcnJheSgxKVxuICAgIGFyci5mb28gPSBmdW5jdGlvbiAoKSB7IHJldHVybiA0MiB9XG4gICAgYXJyLmNvbnN0cnVjdG9yID0gQmFyXG4gICAgcmV0dXJuIGFyci5mb28oKSA9PT0gNDIgJiYgLy8gdHlwZWQgYXJyYXkgaW5zdGFuY2VzIGNhbiBiZSBhdWdtZW50ZWRcbiAgICAgICAgYXJyLmNvbnN0cnVjdG9yID09PSBCYXIgJiYgLy8gY29uc3RydWN0b3IgY2FuIGJlIHNldFxuICAgICAgICB0eXBlb2YgYXJyLnN1YmFycmF5ID09PSAnZnVuY3Rpb24nICYmIC8vIGNocm9tZSA5LTEwIGxhY2sgYHN1YmFycmF5YFxuICAgICAgICBhcnIuc3ViYXJyYXkoMSwgMSkuYnl0ZUxlbmd0aCA9PT0gMCAvLyBpZTEwIGhhcyBicm9rZW4gYHN1YmFycmF5YFxuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbn0pKClcblxuZnVuY3Rpb24ga01heExlbmd0aCAoKSB7XG4gIHJldHVybiBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVFxuICAgID8gMHg3ZmZmZmZmZlxuICAgIDogMHgzZmZmZmZmZlxufVxuXG4vKipcbiAqIENsYXNzOiBCdWZmZXJcbiAqID09PT09PT09PT09PT1cbiAqXG4gKiBUaGUgQnVmZmVyIGNvbnN0cnVjdG9yIHJldHVybnMgaW5zdGFuY2VzIG9mIGBVaW50OEFycmF5YCB0aGF0IGFyZSBhdWdtZW50ZWRcbiAqIHdpdGggZnVuY3Rpb24gcHJvcGVydGllcyBmb3IgYWxsIHRoZSBub2RlIGBCdWZmZXJgIEFQSSBmdW5jdGlvbnMuIFdlIHVzZVxuICogYFVpbnQ4QXJyYXlgIHNvIHRoYXQgc3F1YXJlIGJyYWNrZXQgbm90YXRpb24gd29ya3MgYXMgZXhwZWN0ZWQgLS0gaXQgcmV0dXJuc1xuICogYSBzaW5nbGUgb2N0ZXQuXG4gKlxuICogQnkgYXVnbWVudGluZyB0aGUgaW5zdGFuY2VzLCB3ZSBjYW4gYXZvaWQgbW9kaWZ5aW5nIHRoZSBgVWludDhBcnJheWBcbiAqIHByb3RvdHlwZS5cbiAqL1xuZnVuY3Rpb24gQnVmZmVyIChhcmcpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEJ1ZmZlcikpIHtcbiAgICAvLyBBdm9pZCBnb2luZyB0aHJvdWdoIGFuIEFyZ3VtZW50c0FkYXB0b3JUcmFtcG9saW5lIGluIHRoZSBjb21tb24gY2FzZS5cbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHJldHVybiBuZXcgQnVmZmVyKGFyZywgYXJndW1lbnRzWzFdKVxuICAgIHJldHVybiBuZXcgQnVmZmVyKGFyZylcbiAgfVxuXG4gIHRoaXMubGVuZ3RoID0gMFxuICB0aGlzLnBhcmVudCA9IHVuZGVmaW5lZFxuXG4gIC8vIENvbW1vbiBjYXNlLlxuICBpZiAodHlwZW9mIGFyZyA9PT0gJ251bWJlcicpIHtcbiAgICByZXR1cm4gZnJvbU51bWJlcih0aGlzLCBhcmcpXG4gIH1cblxuICAvLyBTbGlnaHRseSBsZXNzIGNvbW1vbiBjYXNlLlxuICBpZiAodHlwZW9mIGFyZyA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZnJvbVN0cmluZyh0aGlzLCBhcmcsIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogJ3V0ZjgnKVxuICB9XG5cbiAgLy8gVW51c3VhbC5cbiAgcmV0dXJuIGZyb21PYmplY3QodGhpcywgYXJnKVxufVxuXG5mdW5jdGlvbiBmcm9tTnVtYmVyICh0aGF0LCBsZW5ndGgpIHtcbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aCA8IDAgPyAwIDogY2hlY2tlZChsZW5ndGgpIHwgMClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoYXRbaV0gPSAwXG4gICAgfVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21TdHJpbmcgKHRoYXQsIHN0cmluZywgZW5jb2RpbmcpIHtcbiAgaWYgKHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycgfHwgZW5jb2RpbmcgPT09ICcnKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIC8vIEFzc3VtcHRpb246IGJ5dGVMZW5ndGgoKSByZXR1cm4gdmFsdWUgaXMgYWx3YXlzIDwga01heExlbmd0aC5cbiAgdmFyIGxlbmd0aCA9IGJ5dGVMZW5ndGgoc3RyaW5nLCBlbmNvZGluZykgfCAwXG4gIHRoYXQgPSBhbGxvY2F0ZSh0aGF0LCBsZW5ndGgpXG5cbiAgdGhhdC53cml0ZShzdHJpbmcsIGVuY29kaW5nKVxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tT2JqZWN0ICh0aGF0LCBvYmplY3QpIHtcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihvYmplY3QpKSByZXR1cm4gZnJvbUJ1ZmZlcih0aGF0LCBvYmplY3QpXG5cbiAgaWYgKGlzQXJyYXkob2JqZWN0KSkgcmV0dXJuIGZyb21BcnJheSh0aGF0LCBvYmplY3QpXG5cbiAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignbXVzdCBzdGFydCB3aXRoIG51bWJlciwgYnVmZmVyLCBhcnJheSBvciBzdHJpbmcnKVxuICB9XG5cbiAgaWYgKHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBpZiAob2JqZWN0LmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgICByZXR1cm4gZnJvbVR5cGVkQXJyYXkodGhhdCwgb2JqZWN0KVxuICAgIH1cbiAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICAgIHJldHVybiBmcm9tQXJyYXlCdWZmZXIodGhhdCwgb2JqZWN0KVxuICAgIH1cbiAgfVxuXG4gIGlmIChvYmplY3QubGVuZ3RoKSByZXR1cm4gZnJvbUFycmF5TGlrZSh0aGF0LCBvYmplY3QpXG5cbiAgcmV0dXJuIGZyb21Kc29uT2JqZWN0KHRoYXQsIG9iamVjdClcbn1cblxuZnVuY3Rpb24gZnJvbUJ1ZmZlciAodGhhdCwgYnVmZmVyKSB7XG4gIHZhciBsZW5ndGggPSBjaGVja2VkKGJ1ZmZlci5sZW5ndGgpIHwgMFxuICB0aGF0ID0gYWxsb2NhdGUodGhhdCwgbGVuZ3RoKVxuICBidWZmZXIuY29weSh0aGF0LCAwLCAwLCBsZW5ndGgpXG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheSAodGhhdCwgYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGNoZWNrZWQoYXJyYXkubGVuZ3RoKSB8IDBcbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aClcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgIHRoYXRbaV0gPSBhcnJheVtpXSAmIDI1NVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbi8vIER1cGxpY2F0ZSBvZiBmcm9tQXJyYXkoKSB0byBrZWVwIGZyb21BcnJheSgpIG1vbm9tb3JwaGljLlxuZnVuY3Rpb24gZnJvbVR5cGVkQXJyYXkgKHRoYXQsIGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIHRoYXQgPSBhbGxvY2F0ZSh0aGF0LCBsZW5ndGgpXG4gIC8vIFRydW5jYXRpbmcgdGhlIGVsZW1lbnRzIGlzIHByb2JhYmx5IG5vdCB3aGF0IHBlb3BsZSBleHBlY3QgZnJvbSB0eXBlZFxuICAvLyBhcnJheXMgd2l0aCBCWVRFU19QRVJfRUxFTUVOVCA+IDEgYnV0IGl0J3MgY29tcGF0aWJsZSB3aXRoIHRoZSBiZWhhdmlvclxuICAvLyBvZiB0aGUgb2xkIEJ1ZmZlciBjb25zdHJ1Y3Rvci5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgIHRoYXRbaV0gPSBhcnJheVtpXSAmIDI1NVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUJ1ZmZlciAodGhhdCwgYXJyYXkpIHtcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2UsIGZvciBiZXN0IHBlcmZvcm1hbmNlXG4gICAgYXJyYXkuYnl0ZUxlbmd0aFxuICAgIHRoYXQgPSBCdWZmZXIuX2F1Z21lbnQobmV3IFVpbnQ4QXJyYXkoYXJyYXkpKVxuICB9IGVsc2Uge1xuICAgIC8vIEZhbGxiYWNrOiBSZXR1cm4gYW4gb2JqZWN0IGluc3RhbmNlIG9mIHRoZSBCdWZmZXIgY2xhc3NcbiAgICB0aGF0ID0gZnJvbVR5cGVkQXJyYXkodGhhdCwgbmV3IFVpbnQ4QXJyYXkoYXJyYXkpKVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUxpa2UgKHRoYXQsIGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIHRoYXQgPSBhbGxvY2F0ZSh0aGF0LCBsZW5ndGgpXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICB0aGF0W2ldID0gYXJyYXlbaV0gJiAyNTVcbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG4vLyBEZXNlcmlhbGl6ZSB7IHR5cGU6ICdCdWZmZXInLCBkYXRhOiBbMSwyLDMsLi4uXSB9IGludG8gYSBCdWZmZXIgb2JqZWN0LlxuLy8gUmV0dXJucyBhIHplcm8tbGVuZ3RoIGJ1ZmZlciBmb3IgaW5wdXRzIHRoYXQgZG9uJ3QgY29uZm9ybSB0byB0aGUgc3BlYy5cbmZ1bmN0aW9uIGZyb21Kc29uT2JqZWN0ICh0aGF0LCBvYmplY3QpIHtcbiAgdmFyIGFycmF5XG4gIHZhciBsZW5ndGggPSAwXG5cbiAgaWYgKG9iamVjdC50eXBlID09PSAnQnVmZmVyJyAmJiBpc0FycmF5KG9iamVjdC5kYXRhKSkge1xuICAgIGFycmF5ID0gb2JqZWN0LmRhdGFcbiAgICBsZW5ndGggPSBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIH1cbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aClcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgdGhhdFtpXSA9IGFycmF5W2ldICYgMjU1XG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gYWxsb2NhdGUgKHRoYXQsIGxlbmd0aCkge1xuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZSwgZm9yIGJlc3QgcGVyZm9ybWFuY2VcbiAgICB0aGF0ID0gQnVmZmVyLl9hdWdtZW50KG5ldyBVaW50OEFycmF5KGxlbmd0aCkpXG4gIH0gZWxzZSB7XG4gICAgLy8gRmFsbGJhY2s6IFJldHVybiBhbiBvYmplY3QgaW5zdGFuY2Ugb2YgdGhlIEJ1ZmZlciBjbGFzc1xuICAgIHRoYXQubGVuZ3RoID0gbGVuZ3RoXG4gICAgdGhhdC5faXNCdWZmZXIgPSB0cnVlXG4gIH1cblxuICB2YXIgZnJvbVBvb2wgPSBsZW5ndGggIT09IDAgJiYgbGVuZ3RoIDw9IEJ1ZmZlci5wb29sU2l6ZSA+Pj4gMVxuICBpZiAoZnJvbVBvb2wpIHRoYXQucGFyZW50ID0gcm9vdFBhcmVudFxuXG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGNoZWNrZWQgKGxlbmd0aCkge1xuICAvLyBOb3RlOiBjYW5ub3QgdXNlIGBsZW5ndGggPCBrTWF4TGVuZ3RoYCBoZXJlIGJlY2F1c2UgdGhhdCBmYWlscyB3aGVuXG4gIC8vIGxlbmd0aCBpcyBOYU4gKHdoaWNoIGlzIG90aGVyd2lzZSBjb2VyY2VkIHRvIHplcm8uKVxuICBpZiAobGVuZ3RoID49IGtNYXhMZW5ndGgoKSkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdBdHRlbXB0IHRvIGFsbG9jYXRlIEJ1ZmZlciBsYXJnZXIgdGhhbiBtYXhpbXVtICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICdzaXplOiAweCcgKyBrTWF4TGVuZ3RoKCkudG9TdHJpbmcoMTYpICsgJyBieXRlcycpXG4gIH1cbiAgcmV0dXJuIGxlbmd0aCB8IDBcbn1cblxuZnVuY3Rpb24gU2xvd0J1ZmZlciAoc3ViamVjdCwgZW5jb2RpbmcpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFNsb3dCdWZmZXIpKSByZXR1cm4gbmV3IFNsb3dCdWZmZXIoc3ViamVjdCwgZW5jb2RpbmcpXG5cbiAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIoc3ViamVjdCwgZW5jb2RpbmcpXG4gIGRlbGV0ZSBidWYucGFyZW50XG4gIHJldHVybiBidWZcbn1cblxuQnVmZmVyLmlzQnVmZmVyID0gZnVuY3Rpb24gaXNCdWZmZXIgKGIpIHtcbiAgcmV0dXJuICEhKGIgIT0gbnVsbCAmJiBiLl9pc0J1ZmZlcilcbn1cblxuQnVmZmVyLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlIChhLCBiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGEpIHx8ICFCdWZmZXIuaXNCdWZmZXIoYikpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudHMgbXVzdCBiZSBCdWZmZXJzJylcbiAgfVxuXG4gIGlmIChhID09PSBiKSByZXR1cm4gMFxuXG4gIHZhciB4ID0gYS5sZW5ndGhcbiAgdmFyIHkgPSBiLmxlbmd0aFxuXG4gIHZhciBpID0gMFxuICB2YXIgbGVuID0gTWF0aC5taW4oeCwgeSlcbiAgd2hpbGUgKGkgPCBsZW4pIHtcbiAgICBpZiAoYVtpXSAhPT0gYltpXSkgYnJlYWtcblxuICAgICsraVxuICB9XG5cbiAgaWYgKGkgIT09IGxlbikge1xuICAgIHggPSBhW2ldXG4gICAgeSA9IGJbaV1cbiAgfVxuXG4gIGlmICh4IDwgeSkgcmV0dXJuIC0xXG4gIGlmICh5IDwgeCkgcmV0dXJuIDFcbiAgcmV0dXJuIDBcbn1cblxuQnVmZmVyLmlzRW5jb2RpbmcgPSBmdW5jdGlvbiBpc0VuY29kaW5nIChlbmNvZGluZykge1xuICBzd2l0Y2ggKFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKSkge1xuICAgIGNhc2UgJ2hleCc6XG4gICAgY2FzZSAndXRmOCc6XG4gICAgY2FzZSAndXRmLTgnOlxuICAgIGNhc2UgJ2FzY2lpJzpcbiAgICBjYXNlICdiaW5hcnknOlxuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgY2FzZSAncmF3JzpcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgcmV0dXJuIHRydWVcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuQnVmZmVyLmNvbmNhdCA9IGZ1bmN0aW9uIGNvbmNhdCAobGlzdCwgbGVuZ3RoKSB7XG4gIGlmICghaXNBcnJheShsaXN0KSkgdGhyb3cgbmV3IFR5cGVFcnJvcignbGlzdCBhcmd1bWVudCBtdXN0IGJlIGFuIEFycmF5IG9mIEJ1ZmZlcnMuJylcblxuICBpZiAobGlzdC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gbmV3IEJ1ZmZlcigwKVxuICB9XG5cbiAgdmFyIGlcbiAgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbGVuZ3RoID0gMFxuICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBsZW5ndGggKz0gbGlzdFtpXS5sZW5ndGhcbiAgICB9XG4gIH1cblxuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcihsZW5ndGgpXG4gIHZhciBwb3MgPSAwXG4gIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGl0ZW0gPSBsaXN0W2ldXG4gICAgaXRlbS5jb3B5KGJ1ZiwgcG9zKVxuICAgIHBvcyArPSBpdGVtLmxlbmd0aFxuICB9XG4gIHJldHVybiBidWZcbn1cblxuZnVuY3Rpb24gYnl0ZUxlbmd0aCAoc3RyaW5nLCBlbmNvZGluZykge1xuICBpZiAodHlwZW9mIHN0cmluZyAhPT0gJ3N0cmluZycpIHN0cmluZyA9ICcnICsgc3RyaW5nXG5cbiAgdmFyIGxlbiA9IHN0cmluZy5sZW5ndGhcbiAgaWYgKGxlbiA9PT0gMCkgcmV0dXJuIDBcblxuICAvLyBVc2UgYSBmb3IgbG9vcCB0byBhdm9pZCByZWN1cnNpb25cbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcbiAgZm9yICg7Oykge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAvLyBEZXByZWNhdGVkXG4gICAgICBjYXNlICdyYXcnOlxuICAgICAgY2FzZSAncmF3cyc6XG4gICAgICAgIHJldHVybiBsZW5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGhcbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiBsZW4gKiAyXG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gbGVuID4+PiAxXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICByZXR1cm4gYmFzZTY0VG9CeXRlcyhzdHJpbmcpLmxlbmd0aFxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSByZXR1cm4gdXRmOFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGggLy8gYXNzdW1lIHV0ZjhcbiAgICAgICAgZW5jb2RpbmcgPSAoJycgKyBlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cbkJ1ZmZlci5ieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aFxuXG4vLyBwcmUtc2V0IGZvciB2YWx1ZXMgdGhhdCBtYXkgZXhpc3QgaW4gdGhlIGZ1dHVyZVxuQnVmZmVyLnByb3RvdHlwZS5sZW5ndGggPSB1bmRlZmluZWRcbkJ1ZmZlci5wcm90b3R5cGUucGFyZW50ID0gdW5kZWZpbmVkXG5cbmZ1bmN0aW9uIHNsb3dUb1N0cmluZyAoZW5jb2RpbmcsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcblxuICBzdGFydCA9IHN0YXJ0IHwgMFxuICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCB8fCBlbmQgPT09IEluZmluaXR5ID8gdGhpcy5sZW5ndGggOiBlbmQgfCAwXG5cbiAgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSAndXRmOCdcbiAgaWYgKHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIGlmIChlbmQgPiB0aGlzLmxlbmd0aCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKGVuZCA8PSBzdGFydCkgcmV0dXJuICcnXG5cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gaGV4U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgICByZXR1cm4gYXNjaWlTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gYmluYXJ5U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgcmV0dXJuIGJhc2U2NFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiB1dGYxNmxlU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgICAgIGVuY29kaW5nID0gKGVuY29kaW5nICsgJycpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZyAoKSB7XG4gIHZhciBsZW5ndGggPSB0aGlzLmxlbmd0aCB8IDBcbiAgaWYgKGxlbmd0aCA9PT0gMCkgcmV0dXJuICcnXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSByZXR1cm4gdXRmOFNsaWNlKHRoaXMsIDAsIGxlbmd0aClcbiAgcmV0dXJuIHNsb3dUb1N0cmluZy5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gZXF1YWxzIChiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyJylcbiAgaWYgKHRoaXMgPT09IGIpIHJldHVybiB0cnVlXG4gIHJldHVybiBCdWZmZXIuY29tcGFyZSh0aGlzLCBiKSA9PT0gMFxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluc3BlY3QgPSBmdW5jdGlvbiBpbnNwZWN0ICgpIHtcbiAgdmFyIHN0ciA9ICcnXG4gIHZhciBtYXggPSBleHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTXG4gIGlmICh0aGlzLmxlbmd0aCA+IDApIHtcbiAgICBzdHIgPSB0aGlzLnRvU3RyaW5nKCdoZXgnLCAwLCBtYXgpLm1hdGNoKC8uezJ9L2cpLmpvaW4oJyAnKVxuICAgIGlmICh0aGlzLmxlbmd0aCA+IG1heCkgc3RyICs9ICcgLi4uICdcbiAgfVxuICByZXR1cm4gJzxCdWZmZXIgJyArIHN0ciArICc+J1xufVxuXG5CdWZmZXIucHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlIChiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyJylcbiAgaWYgKHRoaXMgPT09IGIpIHJldHVybiAwXG4gIHJldHVybiBCdWZmZXIuY29tcGFyZSh0aGlzLCBiKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluZGV4T2YgPSBmdW5jdGlvbiBpbmRleE9mICh2YWwsIGJ5dGVPZmZzZXQpIHtcbiAgaWYgKGJ5dGVPZmZzZXQgPiAweDdmZmZmZmZmKSBieXRlT2Zmc2V0ID0gMHg3ZmZmZmZmZlxuICBlbHNlIGlmIChieXRlT2Zmc2V0IDwgLTB4ODAwMDAwMDApIGJ5dGVPZmZzZXQgPSAtMHg4MDAwMDAwMFxuICBieXRlT2Zmc2V0ID4+PSAwXG5cbiAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gLTFcbiAgaWYgKGJ5dGVPZmZzZXQgPj0gdGhpcy5sZW5ndGgpIHJldHVybiAtMVxuXG4gIC8vIE5lZ2F0aXZlIG9mZnNldHMgc3RhcnQgZnJvbSB0aGUgZW5kIG9mIHRoZSBidWZmZXJcbiAgaWYgKGJ5dGVPZmZzZXQgPCAwKSBieXRlT2Zmc2V0ID0gTWF0aC5tYXgodGhpcy5sZW5ndGggKyBieXRlT2Zmc2V0LCAwKVxuXG4gIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgIGlmICh2YWwubGVuZ3RoID09PSAwKSByZXR1cm4gLTEgLy8gc3BlY2lhbCBjYXNlOiBsb29raW5nIGZvciBlbXB0eSBzdHJpbmcgYWx3YXlzIGZhaWxzXG4gICAgcmV0dXJuIFN0cmluZy5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKHRoaXMsIHZhbCwgYnl0ZU9mZnNldClcbiAgfVxuICBpZiAoQnVmZmVyLmlzQnVmZmVyKHZhbCkpIHtcbiAgICByZXR1cm4gYXJyYXlJbmRleE9mKHRoaXMsIHZhbCwgYnl0ZU9mZnNldClcbiAgfVxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgJiYgVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIFVpbnQ4QXJyYXkucHJvdG90eXBlLmluZGV4T2YuY2FsbCh0aGlzLCB2YWwsIGJ5dGVPZmZzZXQpXG4gICAgfVxuICAgIHJldHVybiBhcnJheUluZGV4T2YodGhpcywgWyB2YWwgXSwgYnl0ZU9mZnNldClcbiAgfVxuXG4gIGZ1bmN0aW9uIGFycmF5SW5kZXhPZiAoYXJyLCB2YWwsIGJ5dGVPZmZzZXQpIHtcbiAgICB2YXIgZm91bmRJbmRleCA9IC0xXG4gICAgZm9yICh2YXIgaSA9IDA7IGJ5dGVPZmZzZXQgKyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoYXJyW2J5dGVPZmZzZXQgKyBpXSA9PT0gdmFsW2ZvdW5kSW5kZXggPT09IC0xID8gMCA6IGkgLSBmb3VuZEluZGV4XSkge1xuICAgICAgICBpZiAoZm91bmRJbmRleCA9PT0gLTEpIGZvdW5kSW5kZXggPSBpXG4gICAgICAgIGlmIChpIC0gZm91bmRJbmRleCArIDEgPT09IHZhbC5sZW5ndGgpIHJldHVybiBieXRlT2Zmc2V0ICsgZm91bmRJbmRleFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm91bmRJbmRleCA9IC0xXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiAtMVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcigndmFsIG11c3QgYmUgc3RyaW5nLCBudW1iZXIgb3IgQnVmZmVyJylcbn1cblxuLy8gYGdldGAgaXMgZGVwcmVjYXRlZFxuQnVmZmVyLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiBnZXQgKG9mZnNldCkge1xuICBjb25zb2xlLmxvZygnLmdldCgpIGlzIGRlcHJlY2F0ZWQuIEFjY2VzcyB1c2luZyBhcnJheSBpbmRleGVzIGluc3RlYWQuJylcbiAgcmV0dXJuIHRoaXMucmVhZFVJbnQ4KG9mZnNldClcbn1cblxuLy8gYHNldGAgaXMgZGVwcmVjYXRlZFxuQnVmZmVyLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiBzZXQgKHYsIG9mZnNldCkge1xuICBjb25zb2xlLmxvZygnLnNldCgpIGlzIGRlcHJlY2F0ZWQuIEFjY2VzcyB1c2luZyBhcnJheSBpbmRleGVzIGluc3RlYWQuJylcbiAgcmV0dXJuIHRoaXMud3JpdGVVSW50OCh2LCBvZmZzZXQpXG59XG5cbmZ1bmN0aW9uIGhleFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgb2Zmc2V0ID0gTnVtYmVyKG9mZnNldCkgfHwgMFxuICB2YXIgcmVtYWluaW5nID0gYnVmLmxlbmd0aCAtIG9mZnNldFxuICBpZiAoIWxlbmd0aCkge1xuICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICB9IGVsc2Uge1xuICAgIGxlbmd0aCA9IE51bWJlcihsZW5ndGgpXG4gICAgaWYgKGxlbmd0aCA+IHJlbWFpbmluZykge1xuICAgICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gICAgfVxuICB9XG5cbiAgLy8gbXVzdCBiZSBhbiBldmVuIG51bWJlciBvZiBkaWdpdHNcbiAgdmFyIHN0ckxlbiA9IHN0cmluZy5sZW5ndGhcbiAgaWYgKHN0ckxlbiAlIDIgIT09IDApIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBoZXggc3RyaW5nJylcblxuICBpZiAobGVuZ3RoID4gc3RyTGVuIC8gMikge1xuICAgIGxlbmd0aCA9IHN0ckxlbiAvIDJcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcnNlZCA9IHBhcnNlSW50KHN0cmluZy5zdWJzdHIoaSAqIDIsIDIpLCAxNilcbiAgICBpZiAoaXNOYU4ocGFyc2VkKSkgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGhleCBzdHJpbmcnKVxuICAgIGJ1ZltvZmZzZXQgKyBpXSA9IHBhcnNlZFxuICB9XG4gIHJldHVybiBpXG59XG5cbmZ1bmN0aW9uIHV0ZjhXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKHV0ZjhUb0J5dGVzKHN0cmluZywgYnVmLmxlbmd0aCAtIG9mZnNldCksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGFzY2lpV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcihhc2NpaVRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYmluYXJ5V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYXNjaWlXcml0ZShidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGJhc2U2NFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIoYmFzZTY0VG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiB1Y3MyV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcih1dGYxNmxlVG9CeXRlcyhzdHJpbmcsIGJ1Zi5sZW5ndGggLSBvZmZzZXQpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gd3JpdGUgKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgsIGVuY29kaW5nKSB7XG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcpXG4gIGlmIChvZmZzZXQgPT09IHVuZGVmaW5lZCkge1xuICAgIGVuY29kaW5nID0gJ3V0ZjgnXG4gICAgbGVuZ3RoID0gdGhpcy5sZW5ndGhcbiAgICBvZmZzZXQgPSAwXG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcsIGVuY29kaW5nKVxuICB9IGVsc2UgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkICYmIHR5cGVvZiBvZmZzZXQgPT09ICdzdHJpbmcnKSB7XG4gICAgZW5jb2RpbmcgPSBvZmZzZXRcbiAgICBsZW5ndGggPSB0aGlzLmxlbmd0aFxuICAgIG9mZnNldCA9IDBcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZywgb2Zmc2V0WywgbGVuZ3RoXVssIGVuY29kaW5nXSlcbiAgfSBlbHNlIGlmIChpc0Zpbml0ZShvZmZzZXQpKSB7XG4gICAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICAgIGlmIChpc0Zpbml0ZShsZW5ndGgpKSB7XG4gICAgICBsZW5ndGggPSBsZW5ndGggfCAwXG4gICAgICBpZiAoZW5jb2RpbmcgPT09IHVuZGVmaW5lZCkgZW5jb2RpbmcgPSAndXRmOCdcbiAgICB9IGVsc2Uge1xuICAgICAgZW5jb2RpbmcgPSBsZW5ndGhcbiAgICAgIGxlbmd0aCA9IHVuZGVmaW5lZFxuICAgIH1cbiAgLy8gbGVnYWN5IHdyaXRlKHN0cmluZywgZW5jb2RpbmcsIG9mZnNldCwgbGVuZ3RoKSAtIHJlbW92ZSBpbiB2MC4xM1xuICB9IGVsc2Uge1xuICAgIHZhciBzd2FwID0gZW5jb2RpbmdcbiAgICBlbmNvZGluZyA9IG9mZnNldFxuICAgIG9mZnNldCA9IGxlbmd0aCB8IDBcbiAgICBsZW5ndGggPSBzd2FwXG4gIH1cblxuICB2YXIgcmVtYWluaW5nID0gdGhpcy5sZW5ndGggLSBvZmZzZXRcbiAgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkIHx8IGxlbmd0aCA+IHJlbWFpbmluZykgbGVuZ3RoID0gcmVtYWluaW5nXG5cbiAgaWYgKChzdHJpbmcubGVuZ3RoID4gMCAmJiAobGVuZ3RoIDwgMCB8fCBvZmZzZXQgPCAwKSkgfHwgb2Zmc2V0ID4gdGhpcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignYXR0ZW1wdCB0byB3cml0ZSBvdXRzaWRlIGJ1ZmZlciBib3VuZHMnKVxuICB9XG5cbiAgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSAndXRmOCdcblxuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuICBmb3IgKDs7KSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGhleFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgICAgcmV0dXJuIGFzY2lpV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGJpbmFyeVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIC8vIFdhcm5pbmc6IG1heExlbmd0aCBub3QgdGFrZW4gaW50byBhY2NvdW50IGluIGJhc2U2NFdyaXRlXG4gICAgICAgIHJldHVybiBiYXNlNjRXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gdWNzMldyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgICAgICBlbmNvZGluZyA9ICgnJyArIGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTiAoKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogJ0J1ZmZlcicsXG4gICAgZGF0YTogQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwodGhpcy5fYXJyIHx8IHRoaXMsIDApXG4gIH1cbn1cblxuZnVuY3Rpb24gYmFzZTY0U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICBpZiAoc3RhcnQgPT09IDAgJiYgZW5kID09PSBidWYubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1ZilcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmLnNsaWNlKHN0YXJ0LCBlbmQpKVxuICB9XG59XG5cbmZ1bmN0aW9uIHV0ZjhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcbiAgdmFyIHJlcyA9IFtdXG5cbiAgdmFyIGkgPSBzdGFydFxuICB3aGlsZSAoaSA8IGVuZCkge1xuICAgIHZhciBmaXJzdEJ5dGUgPSBidWZbaV1cbiAgICB2YXIgY29kZVBvaW50ID0gbnVsbFxuICAgIHZhciBieXRlc1BlclNlcXVlbmNlID0gKGZpcnN0Qnl0ZSA+IDB4RUYpID8gNFxuICAgICAgOiAoZmlyc3RCeXRlID4gMHhERikgPyAzXG4gICAgICA6IChmaXJzdEJ5dGUgPiAweEJGKSA/IDJcbiAgICAgIDogMVxuXG4gICAgaWYgKGkgKyBieXRlc1BlclNlcXVlbmNlIDw9IGVuZCkge1xuICAgICAgdmFyIHNlY29uZEJ5dGUsIHRoaXJkQnl0ZSwgZm91cnRoQnl0ZSwgdGVtcENvZGVQb2ludFxuXG4gICAgICBzd2l0Y2ggKGJ5dGVzUGVyU2VxdWVuY2UpIHtcbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgIGlmIChmaXJzdEJ5dGUgPCAweDgwKSB7XG4gICAgICAgICAgICBjb2RlUG9pbnQgPSBmaXJzdEJ5dGVcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHgxRikgPDwgMHg2IHwgKHNlY29uZEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweDdGKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgdGhpcmRCeXRlID0gYnVmW2kgKyAyXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwICYmICh0aGlyZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweEYpIDw8IDB4QyB8IChzZWNvbmRCeXRlICYgMHgzRikgPDwgMHg2IHwgKHRoaXJkQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4N0ZGICYmICh0ZW1wQ29kZVBvaW50IDwgMHhEODAwIHx8IHRlbXBDb2RlUG9pbnQgPiAweERGRkYpKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSA0OlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgdGhpcmRCeXRlID0gYnVmW2kgKyAyXVxuICAgICAgICAgIGZvdXJ0aEJ5dGUgPSBidWZbaSArIDNdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKHRoaXJkQnl0ZSAmIDB4QzApID09PSAweDgwICYmIChmb3VydGhCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHhGKSA8PCAweDEyIHwgKHNlY29uZEJ5dGUgJiAweDNGKSA8PCAweEMgfCAodGhpcmRCeXRlICYgMHgzRikgPDwgMHg2IHwgKGZvdXJ0aEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweEZGRkYgJiYgdGVtcENvZGVQb2ludCA8IDB4MTEwMDAwKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNvZGVQb2ludCA9PT0gbnVsbCkge1xuICAgICAgLy8gd2UgZGlkIG5vdCBnZW5lcmF0ZSBhIHZhbGlkIGNvZGVQb2ludCBzbyBpbnNlcnQgYVxuICAgICAgLy8gcmVwbGFjZW1lbnQgY2hhciAoVStGRkZEKSBhbmQgYWR2YW5jZSBvbmx5IDEgYnl0ZVxuICAgICAgY29kZVBvaW50ID0gMHhGRkZEXG4gICAgICBieXRlc1BlclNlcXVlbmNlID0gMVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50ID4gMHhGRkZGKSB7XG4gICAgICAvLyBlbmNvZGUgdG8gdXRmMTYgKHN1cnJvZ2F0ZSBwYWlyIGRhbmNlKVxuICAgICAgY29kZVBvaW50IC09IDB4MTAwMDBcbiAgICAgIHJlcy5wdXNoKGNvZGVQb2ludCA+Pj4gMTAgJiAweDNGRiB8IDB4RDgwMClcbiAgICAgIGNvZGVQb2ludCA9IDB4REMwMCB8IGNvZGVQb2ludCAmIDB4M0ZGXG4gICAgfVxuXG4gICAgcmVzLnB1c2goY29kZVBvaW50KVxuICAgIGkgKz0gYnl0ZXNQZXJTZXF1ZW5jZVxuICB9XG5cbiAgcmV0dXJuIGRlY29kZUNvZGVQb2ludHNBcnJheShyZXMpXG59XG5cbi8vIEJhc2VkIG9uIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzIyNzQ3MjcyLzY4MDc0MiwgdGhlIGJyb3dzZXIgd2l0aFxuLy8gdGhlIGxvd2VzdCBsaW1pdCBpcyBDaHJvbWUsIHdpdGggMHgxMDAwMCBhcmdzLlxuLy8gV2UgZ28gMSBtYWduaXR1ZGUgbGVzcywgZm9yIHNhZmV0eVxudmFyIE1BWF9BUkdVTUVOVFNfTEVOR1RIID0gMHgxMDAwXG5cbmZ1bmN0aW9uIGRlY29kZUNvZGVQb2ludHNBcnJheSAoY29kZVBvaW50cykge1xuICB2YXIgbGVuID0gY29kZVBvaW50cy5sZW5ndGhcbiAgaWYgKGxlbiA8PSBNQVhfQVJHVU1FTlRTX0xFTkdUSCkge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZywgY29kZVBvaW50cykgLy8gYXZvaWQgZXh0cmEgc2xpY2UoKVxuICB9XG5cbiAgLy8gRGVjb2RlIGluIGNodW5rcyB0byBhdm9pZCBcImNhbGwgc3RhY2sgc2l6ZSBleGNlZWRlZFwiLlxuICB2YXIgcmVzID0gJydcbiAgdmFyIGkgPSAwXG4gIHdoaWxlIChpIDwgbGVuKSB7XG4gICAgcmVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoXG4gICAgICBTdHJpbmcsXG4gICAgICBjb2RlUG9pbnRzLnNsaWNlKGksIGkgKz0gTUFYX0FSR1VNRU5UU19MRU5HVEgpXG4gICAgKVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuZnVuY3Rpb24gYXNjaWlTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0gJiAweDdGKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gYmluYXJ5U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgcmV0ID0gJydcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gaGV4U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuXG4gIGlmICghc3RhcnQgfHwgc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgaWYgKCFlbmQgfHwgZW5kIDwgMCB8fCBlbmQgPiBsZW4pIGVuZCA9IGxlblxuXG4gIHZhciBvdXQgPSAnJ1xuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgIG91dCArPSB0b0hleChidWZbaV0pXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuXG5mdW5jdGlvbiB1dGYxNmxlU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgYnl0ZXMgPSBidWYuc2xpY2Uoc3RhcnQsIGVuZClcbiAgdmFyIHJlcyA9ICcnXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpICs9IDIpIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSArIGJ5dGVzW2kgKyAxXSAqIDI1NilcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc2xpY2UgPSBmdW5jdGlvbiBzbGljZSAoc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgc3RhcnQgPSB+fnN0YXJ0XG4gIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkID8gbGVuIDogfn5lbmRcblxuICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgc3RhcnQgKz0gbGVuXG4gICAgaWYgKHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIH0gZWxzZSBpZiAoc3RhcnQgPiBsZW4pIHtcbiAgICBzdGFydCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IDApIHtcbiAgICBlbmQgKz0gbGVuXG4gICAgaWYgKGVuZCA8IDApIGVuZCA9IDBcbiAgfSBlbHNlIGlmIChlbmQgPiBsZW4pIHtcbiAgICBlbmQgPSBsZW5cbiAgfVxuXG4gIGlmIChlbmQgPCBzdGFydCkgZW5kID0gc3RhcnRcblxuICB2YXIgbmV3QnVmXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIG5ld0J1ZiA9IEJ1ZmZlci5fYXVnbWVudCh0aGlzLnN1YmFycmF5KHN0YXJ0LCBlbmQpKVxuICB9IGVsc2Uge1xuICAgIHZhciBzbGljZUxlbiA9IGVuZCAtIHN0YXJ0XG4gICAgbmV3QnVmID0gbmV3IEJ1ZmZlcihzbGljZUxlbiwgdW5kZWZpbmVkKVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2xpY2VMZW47IGkrKykge1xuICAgICAgbmV3QnVmW2ldID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9XG5cbiAgaWYgKG5ld0J1Zi5sZW5ndGgpIG5ld0J1Zi5wYXJlbnQgPSB0aGlzLnBhcmVudCB8fCB0aGlzXG5cbiAgcmV0dXJuIG5ld0J1ZlxufVxuXG4vKlxuICogTmVlZCB0byBtYWtlIHN1cmUgdGhhdCBidWZmZXIgaXNuJ3QgdHJ5aW5nIHRvIHdyaXRlIG91dCBvZiBib3VuZHMuXG4gKi9cbmZ1bmN0aW9uIGNoZWNrT2Zmc2V0IChvZmZzZXQsIGV4dCwgbGVuZ3RoKSB7XG4gIGlmICgob2Zmc2V0ICUgMSkgIT09IDAgfHwgb2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ29mZnNldCBpcyBub3QgdWludCcpXG4gIGlmIChvZmZzZXQgKyBleHQgPiBsZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdUcnlpbmcgdG8gYWNjZXNzIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludExFID0gZnVuY3Rpb24gcmVhZFVJbnRMRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludEJFID0gZnVuY3Rpb24gcmVhZFVJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcbiAgfVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIC0tYnl0ZUxlbmd0aF1cbiAgdmFyIG11bCA9IDFcbiAgd2hpbGUgKGJ5dGVMZW5ndGggPiAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXSAqIG11bFxuICB9XG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50OCA9IGZ1bmN0aW9uIHJlYWRVSW50OCAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDEsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gdGhpc1tvZmZzZXRdXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkxFID0gZnVuY3Rpb24gcmVhZFVJbnQxNkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiB0aGlzW29mZnNldF0gfCAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZCRSA9IGZ1bmN0aW9uIHJlYWRVSW50MTZCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSA8PCA4KSB8IHRoaXNbb2Zmc2V0ICsgMV1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyTEUgPSBmdW5jdGlvbiByZWFkVUludDMyTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKCh0aGlzW29mZnNldF0pIHxcbiAgICAgICh0aGlzW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAgICh0aGlzW29mZnNldCArIDJdIDw8IDE2KSkgK1xuICAgICAgKHRoaXNbb2Zmc2V0ICsgM10gKiAweDEwMDAwMDApXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkJFID0gZnVuY3Rpb24gcmVhZFVJbnQzMkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0gKiAweDEwMDAwMDApICtcbiAgICAoKHRoaXNbb2Zmc2V0ICsgMV0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCA4KSB8XG4gICAgdGhpc1tvZmZzZXQgKyAzXSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50TEUgPSBmdW5jdGlvbiByZWFkSW50TEUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIGldICogbXVsXG4gIH1cbiAgbXVsICo9IDB4ODBcblxuICBpZiAodmFsID49IG11bCkgdmFsIC09IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50QkUgPSBmdW5jdGlvbiByZWFkSW50QkUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgaSA9IGJ5dGVMZW5ndGhcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1pXVxuICB3aGlsZSAoaSA+IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyAtLWldICogbXVsXG4gIH1cbiAgbXVsICo9IDB4ODBcblxuICBpZiAodmFsID49IG11bCkgdmFsIC09IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50OCA9IGZ1bmN0aW9uIHJlYWRJbnQ4IChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIGlmICghKHRoaXNbb2Zmc2V0XSAmIDB4ODApKSByZXR1cm4gKHRoaXNbb2Zmc2V0XSlcbiAgcmV0dXJuICgoMHhmZiAtIHRoaXNbb2Zmc2V0XSArIDEpICogLTEpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2TEUgPSBmdW5jdGlvbiByZWFkSW50MTZMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdIHwgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOClcbiAgcmV0dXJuICh2YWwgJiAweDgwMDApID8gdmFsIHwgMHhGRkZGMDAwMCA6IHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkJFID0gZnVuY3Rpb24gcmVhZEludDE2QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgMV0gfCAodGhpc1tvZmZzZXRdIDw8IDgpXG4gIHJldHVybiAodmFsICYgMHg4MDAwKSA/IHZhbCB8IDB4RkZGRjAwMDAgOiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJMRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0pIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSA8PCAyNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJCRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0gPDwgMjQpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRMRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdExFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRCRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdEJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCBmYWxzZSwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUxFID0gZnVuY3Rpb24gcmVhZERvdWJsZUxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgOCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCA1MiwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlQkUgPSBmdW5jdGlvbiByZWFkRG91YmxlQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA4LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCA1MiwgOClcbn1cblxuZnVuY3Rpb24gY2hlY2tJbnQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihidWYpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdidWZmZXIgbXVzdCBiZSBhIEJ1ZmZlciBpbnN0YW5jZScpXG4gIGlmICh2YWx1ZSA+IG1heCB8fCB2YWx1ZSA8IG1pbikgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3ZhbHVlIGlzIG91dCBvZiBib3VuZHMnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnRMRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpLCAwKVxuXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50QkUgPSBmdW5jdGlvbiB3cml0ZVVJbnRCRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpLCAwKVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdGhpc1tvZmZzZXQgKyBpXSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoLS1pID49IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50OCA9IGZ1bmN0aW9uIHdyaXRlVUludDggKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMSwgMHhmZiwgMClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkgdmFsdWUgPSBNYXRoLmZsb29yKHZhbHVlKVxuICB0aGlzW29mZnNldF0gPSB2YWx1ZVxuICByZXR1cm4gb2Zmc2V0ICsgMVxufVxuXG5mdW5jdGlvbiBvYmplY3RXcml0ZVVJbnQxNiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmYgKyB2YWx1ZSArIDFcbiAgZm9yICh2YXIgaSA9IDAsIGogPSBNYXRoLm1pbihidWYubGVuZ3RoIC0gb2Zmc2V0LCAyKTsgaSA8IGo7IGkrKykge1xuICAgIGJ1ZltvZmZzZXQgKyBpXSA9ICh2YWx1ZSAmICgweGZmIDw8ICg4ICogKGxpdHRsZUVuZGlhbiA/IGkgOiAxIC0gaSkpKSkgPj4+XG4gICAgICAobGl0dGxlRW5kaWFuID8gaSA6IDEgLSBpKSAqIDhcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQxNkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gdmFsdWVcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVVSW50MTZCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweGZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDFdID0gdmFsdWVcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5mdW5jdGlvbiBvYmplY3RXcml0ZVVJbnQzMiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmZmZmZmICsgdmFsdWUgKyAxXG4gIGZvciAodmFyIGkgPSAwLCBqID0gTWF0aC5taW4oYnVmLmxlbmd0aCAtIG9mZnNldCwgNCk7IGkgPCBqOyBpKyspIHtcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSAodmFsdWUgPj4+IChsaXR0bGVFbmRpYW4gPyBpIDogMyAtIGkpICogOCkgJiAweGZmXG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkxFID0gZnVuY3Rpb24gd3JpdGVVSW50MzJMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweGZmZmZmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0XSA9IHZhbHVlXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDNdID0gdmFsdWVcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50TEUgPSBmdW5jdGlvbiB3cml0ZUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gMFxuICB2YXIgbXVsID0gMVxuICB2YXIgc3ViID0gdmFsdWUgPCAwID8gMSA6IDBcbiAgdGhpc1tvZmZzZXRdID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICgodmFsdWUgLyBtdWwpID4+IDApIC0gc3ViICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludEJFID0gZnVuY3Rpb24gd3JpdGVJbnRCRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIGxpbWl0ID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGggLSAxKVxuXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbGltaXQgLSAxLCAtbGltaXQpXG4gIH1cblxuICB2YXIgaSA9IGJ5dGVMZW5ndGggLSAxXG4gIHZhciBtdWwgPSAxXG4gIHZhciBzdWIgPSB2YWx1ZSA8IDAgPyAxIDogMFxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAoKHZhbHVlIC8gbXVsKSA+PiAwKSAtIHN1YiAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQ4ID0gZnVuY3Rpb24gd3JpdGVJbnQ4ICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDEsIDB4N2YsIC0weDgwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB2YWx1ZSA9IE1hdGguZmxvb3IodmFsdWUpXG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZiArIHZhbHVlICsgMVxuICB0aGlzW29mZnNldF0gPSB2YWx1ZVxuICByZXR1cm4gb2Zmc2V0ICsgMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZMRSA9IGZ1bmN0aW9uIHdyaXRlSW50MTZMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweDdmZmYsIC0weDgwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9IHZhbHVlXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVJbnQxNkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4N2ZmZiwgLTB4ODAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSB2YWx1ZVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkxFID0gZnVuY3Rpb24gd3JpdGVJbnQzMkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSB2YWx1ZVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSA+Pj4gMjQpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJCRSA9IGZ1bmN0aW9uIHdyaXRlSW50MzJCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmZmZmZmICsgdmFsdWUgKyAxXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDNdID0gdmFsdWVcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5mdW5jdGlvbiBjaGVja0lFRUU3NTQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAodmFsdWUgPiBtYXggfHwgdmFsdWUgPCBtaW4pIHRocm93IG5ldyBSYW5nZUVycm9yKCd2YWx1ZSBpcyBvdXQgb2YgYm91bmRzJylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGJ1Zi5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdpbmRleCBvdXQgb2YgcmFuZ2UnKVxuICBpZiAob2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbmZ1bmN0aW9uIHdyaXRlRmxvYXQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgNCwgMy40MDI4MjM0NjYzODUyODg2ZSszOCwgLTMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgpXG4gIH1cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgMjMsIDQpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdExFID0gZnVuY3Rpb24gd3JpdGVGbG9hdExFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0QkUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gd3JpdGVEb3VibGUgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgOCwgMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgsIC0xLjc5NzY5MzEzNDg2MjMxNTdFKzMwOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCA1MiwgOClcbiAgcmV0dXJuIG9mZnNldCArIDhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUxFID0gZnVuY3Rpb24gd3JpdGVEb3VibGVMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlQkUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG4vLyBjb3B5KHRhcmdldEJ1ZmZlciwgdGFyZ2V0U3RhcnQ9MCwgc291cmNlU3RhcnQ9MCwgc291cmNlRW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbiBjb3B5ICh0YXJnZXQsIHRhcmdldFN0YXJ0LCBzdGFydCwgZW5kKSB7XG4gIGlmICghc3RhcnQpIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCAmJiBlbmQgIT09IDApIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXRTdGFydCA+PSB0YXJnZXQubGVuZ3RoKSB0YXJnZXRTdGFydCA9IHRhcmdldC5sZW5ndGhcbiAgaWYgKCF0YXJnZXRTdGFydCkgdGFyZ2V0U3RhcnQgPSAwXG4gIGlmIChlbmQgPiAwICYmIGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIC8vIENvcHkgMCBieXRlczsgd2UncmUgZG9uZVxuICBpZiAoZW5kID09PSBzdGFydCkgcmV0dXJuIDBcbiAgaWYgKHRhcmdldC5sZW5ndGggPT09IDAgfHwgdGhpcy5sZW5ndGggPT09IDApIHJldHVybiAwXG5cbiAgLy8gRmF0YWwgZXJyb3IgY29uZGl0aW9uc1xuICBpZiAodGFyZ2V0U3RhcnQgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3RhcmdldFN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICB9XG4gIGlmIChzdGFydCA8IDAgfHwgc3RhcnQgPj0gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgaWYgKGVuZCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VFbmQgb3V0IG9mIGJvdW5kcycpXG5cbiAgLy8gQXJlIHdlIG9vYj9cbiAgaWYgKGVuZCA+IHRoaXMubGVuZ3RoKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0Lmxlbmd0aCAtIHRhcmdldFN0YXJ0IDwgZW5kIC0gc3RhcnQpIHtcbiAgICBlbmQgPSB0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0U3RhcnQgKyBzdGFydFxuICB9XG5cbiAgdmFyIGxlbiA9IGVuZCAtIHN0YXJ0XG4gIHZhciBpXG5cbiAgaWYgKHRoaXMgPT09IHRhcmdldCAmJiBzdGFydCA8IHRhcmdldFN0YXJ0ICYmIHRhcmdldFN0YXJ0IDwgZW5kKSB7XG4gICAgLy8gZGVzY2VuZGluZyBjb3B5IGZyb20gZW5kXG4gICAgZm9yIChpID0gbGVuIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIHRhcmdldFtpICsgdGFyZ2V0U3RhcnRdID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9IGVsc2UgaWYgKGxlbiA8IDEwMDAgfHwgIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gYXNjZW5kaW5nIGNvcHkgZnJvbSBzdGFydFxuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRTdGFydF0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGFyZ2V0Ll9zZXQodGhpcy5zdWJhcnJheShzdGFydCwgc3RhcnQgKyBsZW4pLCB0YXJnZXRTdGFydClcbiAgfVxuXG4gIHJldHVybiBsZW5cbn1cblxuLy8gZmlsbCh2YWx1ZSwgc3RhcnQ9MCwgZW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLmZpbGwgPSBmdW5jdGlvbiBmaWxsICh2YWx1ZSwgc3RhcnQsIGVuZCkge1xuICBpZiAoIXZhbHVlKSB2YWx1ZSA9IDBcbiAgaWYgKCFzdGFydCkgc3RhcnQgPSAwXG4gIGlmICghZW5kKSBlbmQgPSB0aGlzLmxlbmd0aFxuXG4gIGlmIChlbmQgPCBzdGFydCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2VuZCA8IHN0YXJ0JylcblxuICAvLyBGaWxsIDAgYnl0ZXM7IHdlJ3JlIGRvbmVcbiAgaWYgKGVuZCA9PT0gc3RhcnQpIHJldHVyblxuICBpZiAodGhpcy5sZW5ndGggPT09IDApIHJldHVyblxuXG4gIGlmIChzdGFydCA8IDAgfHwgc3RhcnQgPj0gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdzdGFydCBvdXQgb2YgYm91bmRzJylcbiAgaWYgKGVuZCA8IDAgfHwgZW5kID4gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdlbmQgb3V0IG9mIGJvdW5kcycpXG5cbiAgdmFyIGlcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgICB0aGlzW2ldID0gdmFsdWVcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIGJ5dGVzID0gdXRmOFRvQnl0ZXModmFsdWUudG9TdHJpbmcoKSlcbiAgICB2YXIgbGVuID0gYnl0ZXMubGVuZ3RoXG4gICAgZm9yIChpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgICAgdGhpc1tpXSA9IGJ5dGVzW2kgJSBsZW5dXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGBBcnJheUJ1ZmZlcmAgd2l0aCB0aGUgKmNvcGllZCogbWVtb3J5IG9mIHRoZSBidWZmZXIgaW5zdGFuY2UuXG4gKiBBZGRlZCBpbiBOb2RlIDAuMTIuIE9ubHkgYXZhaWxhYmxlIGluIGJyb3dzZXJzIHRoYXQgc3VwcG9ydCBBcnJheUJ1ZmZlci5cbiAqL1xuQnVmZmVyLnByb3RvdHlwZS50b0FycmF5QnVmZmVyID0gZnVuY3Rpb24gdG9BcnJheUJ1ZmZlciAoKSB7XG4gIGlmICh0eXBlb2YgVWludDhBcnJheSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAgIHJldHVybiAobmV3IEJ1ZmZlcih0aGlzKSkuYnVmZmVyXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBidWYgPSBuZXcgVWludDhBcnJheSh0aGlzLmxlbmd0aClcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBidWYubGVuZ3RoOyBpIDwgbGVuOyBpICs9IDEpIHtcbiAgICAgICAgYnVmW2ldID0gdGhpc1tpXVxuICAgICAgfVxuICAgICAgcmV0dXJuIGJ1Zi5idWZmZXJcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQnVmZmVyLnRvQXJyYXlCdWZmZXIgbm90IHN1cHBvcnRlZCBpbiB0aGlzIGJyb3dzZXInKVxuICB9XG59XG5cbi8vIEhFTFBFUiBGVU5DVElPTlNcbi8vID09PT09PT09PT09PT09PT1cblxudmFyIEJQID0gQnVmZmVyLnByb3RvdHlwZVxuXG4vKipcbiAqIEF1Z21lbnQgYSBVaW50OEFycmF5ICppbnN0YW5jZSogKG5vdCB0aGUgVWludDhBcnJheSBjbGFzcyEpIHdpdGggQnVmZmVyIG1ldGhvZHNcbiAqL1xuQnVmZmVyLl9hdWdtZW50ID0gZnVuY3Rpb24gX2F1Z21lbnQgKGFycikge1xuICBhcnIuY29uc3RydWN0b3IgPSBCdWZmZXJcbiAgYXJyLl9pc0J1ZmZlciA9IHRydWVcblxuICAvLyBzYXZlIHJlZmVyZW5jZSB0byBvcmlnaW5hbCBVaW50OEFycmF5IHNldCBtZXRob2QgYmVmb3JlIG92ZXJ3cml0aW5nXG4gIGFyci5fc2V0ID0gYXJyLnNldFxuXG4gIC8vIGRlcHJlY2F0ZWRcbiAgYXJyLmdldCA9IEJQLmdldFxuICBhcnIuc2V0ID0gQlAuc2V0XG5cbiAgYXJyLndyaXRlID0gQlAud3JpdGVcbiAgYXJyLnRvU3RyaW5nID0gQlAudG9TdHJpbmdcbiAgYXJyLnRvTG9jYWxlU3RyaW5nID0gQlAudG9TdHJpbmdcbiAgYXJyLnRvSlNPTiA9IEJQLnRvSlNPTlxuICBhcnIuZXF1YWxzID0gQlAuZXF1YWxzXG4gIGFyci5jb21wYXJlID0gQlAuY29tcGFyZVxuICBhcnIuaW5kZXhPZiA9IEJQLmluZGV4T2ZcbiAgYXJyLmNvcHkgPSBCUC5jb3B5XG4gIGFyci5zbGljZSA9IEJQLnNsaWNlXG4gIGFyci5yZWFkVUludExFID0gQlAucmVhZFVJbnRMRVxuICBhcnIucmVhZFVJbnRCRSA9IEJQLnJlYWRVSW50QkVcbiAgYXJyLnJlYWRVSW50OCA9IEJQLnJlYWRVSW50OFxuICBhcnIucmVhZFVJbnQxNkxFID0gQlAucmVhZFVJbnQxNkxFXG4gIGFyci5yZWFkVUludDE2QkUgPSBCUC5yZWFkVUludDE2QkVcbiAgYXJyLnJlYWRVSW50MzJMRSA9IEJQLnJlYWRVSW50MzJMRVxuICBhcnIucmVhZFVJbnQzMkJFID0gQlAucmVhZFVJbnQzMkJFXG4gIGFyci5yZWFkSW50TEUgPSBCUC5yZWFkSW50TEVcbiAgYXJyLnJlYWRJbnRCRSA9IEJQLnJlYWRJbnRCRVxuICBhcnIucmVhZEludDggPSBCUC5yZWFkSW50OFxuICBhcnIucmVhZEludDE2TEUgPSBCUC5yZWFkSW50MTZMRVxuICBhcnIucmVhZEludDE2QkUgPSBCUC5yZWFkSW50MTZCRVxuICBhcnIucmVhZEludDMyTEUgPSBCUC5yZWFkSW50MzJMRVxuICBhcnIucmVhZEludDMyQkUgPSBCUC5yZWFkSW50MzJCRVxuICBhcnIucmVhZEZsb2F0TEUgPSBCUC5yZWFkRmxvYXRMRVxuICBhcnIucmVhZEZsb2F0QkUgPSBCUC5yZWFkRmxvYXRCRVxuICBhcnIucmVhZERvdWJsZUxFID0gQlAucmVhZERvdWJsZUxFXG4gIGFyci5yZWFkRG91YmxlQkUgPSBCUC5yZWFkRG91YmxlQkVcbiAgYXJyLndyaXRlVUludDggPSBCUC53cml0ZVVJbnQ4XG4gIGFyci53cml0ZVVJbnRMRSA9IEJQLndyaXRlVUludExFXG4gIGFyci53cml0ZVVJbnRCRSA9IEJQLndyaXRlVUludEJFXG4gIGFyci53cml0ZVVJbnQxNkxFID0gQlAud3JpdGVVSW50MTZMRVxuICBhcnIud3JpdGVVSW50MTZCRSA9IEJQLndyaXRlVUludDE2QkVcbiAgYXJyLndyaXRlVUludDMyTEUgPSBCUC53cml0ZVVJbnQzMkxFXG4gIGFyci53cml0ZVVJbnQzMkJFID0gQlAud3JpdGVVSW50MzJCRVxuICBhcnIud3JpdGVJbnRMRSA9IEJQLndyaXRlSW50TEVcbiAgYXJyLndyaXRlSW50QkUgPSBCUC53cml0ZUludEJFXG4gIGFyci53cml0ZUludDggPSBCUC53cml0ZUludDhcbiAgYXJyLndyaXRlSW50MTZMRSA9IEJQLndyaXRlSW50MTZMRVxuICBhcnIud3JpdGVJbnQxNkJFID0gQlAud3JpdGVJbnQxNkJFXG4gIGFyci53cml0ZUludDMyTEUgPSBCUC53cml0ZUludDMyTEVcbiAgYXJyLndyaXRlSW50MzJCRSA9IEJQLndyaXRlSW50MzJCRVxuICBhcnIud3JpdGVGbG9hdExFID0gQlAud3JpdGVGbG9hdExFXG4gIGFyci53cml0ZUZsb2F0QkUgPSBCUC53cml0ZUZsb2F0QkVcbiAgYXJyLndyaXRlRG91YmxlTEUgPSBCUC53cml0ZURvdWJsZUxFXG4gIGFyci53cml0ZURvdWJsZUJFID0gQlAud3JpdGVEb3VibGVCRVxuICBhcnIuZmlsbCA9IEJQLmZpbGxcbiAgYXJyLmluc3BlY3QgPSBCUC5pbnNwZWN0XG4gIGFyci50b0FycmF5QnVmZmVyID0gQlAudG9BcnJheUJ1ZmZlclxuXG4gIHJldHVybiBhcnJcbn1cblxudmFyIElOVkFMSURfQkFTRTY0X1JFID0gL1teK1xcLzAtOUEtWmEtei1fXS9nXG5cbmZ1bmN0aW9uIGJhc2U2NGNsZWFuIChzdHIpIHtcbiAgLy8gTm9kZSBzdHJpcHMgb3V0IGludmFsaWQgY2hhcmFjdGVycyBsaWtlIFxcbiBhbmQgXFx0IGZyb20gdGhlIHN0cmluZywgYmFzZTY0LWpzIGRvZXMgbm90XG4gIHN0ciA9IHN0cmluZ3RyaW0oc3RyKS5yZXBsYWNlKElOVkFMSURfQkFTRTY0X1JFLCAnJylcbiAgLy8gTm9kZSBjb252ZXJ0cyBzdHJpbmdzIHdpdGggbGVuZ3RoIDwgMiB0byAnJ1xuICBpZiAoc3RyLmxlbmd0aCA8IDIpIHJldHVybiAnJ1xuICAvLyBOb2RlIGFsbG93cyBmb3Igbm9uLXBhZGRlZCBiYXNlNjQgc3RyaW5ncyAobWlzc2luZyB0cmFpbGluZyA9PT0pLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgd2hpbGUgKHN0ci5sZW5ndGggJSA0ICE9PSAwKSB7XG4gICAgc3RyID0gc3RyICsgJz0nXG4gIH1cbiAgcmV0dXJuIHN0clxufVxuXG5mdW5jdGlvbiBzdHJpbmd0cmltIChzdHIpIHtcbiAgaWYgKHN0ci50cmltKSByZXR1cm4gc3RyLnRyaW0oKVxuICByZXR1cm4gc3RyLnJlcGxhY2UoL15cXHMrfFxccyskL2csICcnKVxufVxuXG5mdW5jdGlvbiB0b0hleCAobikge1xuICBpZiAobiA8IDE2KSByZXR1cm4gJzAnICsgbi50b1N0cmluZygxNilcbiAgcmV0dXJuIG4udG9TdHJpbmcoMTYpXG59XG5cbmZ1bmN0aW9uIHV0ZjhUb0J5dGVzIChzdHJpbmcsIHVuaXRzKSB7XG4gIHVuaXRzID0gdW5pdHMgfHwgSW5maW5pdHlcbiAgdmFyIGNvZGVQb2ludFxuICB2YXIgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aFxuICB2YXIgbGVhZFN1cnJvZ2F0ZSA9IG51bGxcbiAgdmFyIGJ5dGVzID0gW11cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgY29kZVBvaW50ID0gc3RyaW5nLmNoYXJDb2RlQXQoaSlcblxuICAgIC8vIGlzIHN1cnJvZ2F0ZSBjb21wb25lbnRcbiAgICBpZiAoY29kZVBvaW50ID4gMHhEN0ZGICYmIGNvZGVQb2ludCA8IDB4RTAwMCkge1xuICAgICAgLy8gbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICghbGVhZFN1cnJvZ2F0ZSkge1xuICAgICAgICAvLyBubyBsZWFkIHlldFxuICAgICAgICBpZiAoY29kZVBvaW50ID4gMHhEQkZGKSB7XG4gICAgICAgICAgLy8gdW5leHBlY3RlZCB0cmFpbFxuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH0gZWxzZSBpZiAoaSArIDEgPT09IGxlbmd0aCkge1xuICAgICAgICAgIC8vIHVucGFpcmVkIGxlYWRcbiAgICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gdmFsaWQgbGVhZFxuICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG5cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgLy8gMiBsZWFkcyBpbiBhIHJvd1xuICAgICAgaWYgKGNvZGVQb2ludCA8IDB4REMwMCkge1xuICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgbGVhZFN1cnJvZ2F0ZSA9IGNvZGVQb2ludFxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvLyB2YWxpZCBzdXJyb2dhdGUgcGFpclxuICAgICAgY29kZVBvaW50ID0gbGVhZFN1cnJvZ2F0ZSAtIDB4RDgwMCA8PCAxMCB8IGNvZGVQb2ludCAtIDB4REMwMCB8IDB4MTAwMDBcbiAgICB9IGVsc2UgaWYgKGxlYWRTdXJyb2dhdGUpIHtcbiAgICAgIC8vIHZhbGlkIGJtcCBjaGFyLCBidXQgbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgIH1cblxuICAgIGxlYWRTdXJyb2dhdGUgPSBudWxsXG5cbiAgICAvLyBlbmNvZGUgdXRmOFxuICAgIGlmIChjb2RlUG9pbnQgPCAweDgwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDEpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goY29kZVBvaW50KVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHg4MDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMikgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiB8IDB4QzAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDEwMDAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDMpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgfCAweEUwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2ICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDExMDAwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSA0KSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHgxMiB8IDB4RjAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY29kZSBwb2ludCcpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVzXG59XG5cbmZ1bmN0aW9uIGFzY2lpVG9CeXRlcyAoc3RyKSB7XG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykge1xuICAgIC8vIE5vZGUncyBjb2RlIHNlZW1zIHRvIGJlIGRvaW5nIHRoaXMgYW5kIG5vdCAmIDB4N0YuLlxuICAgIGJ5dGVBcnJheS5wdXNoKHN0ci5jaGFyQ29kZUF0KGkpICYgMHhGRilcbiAgfVxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVUb0J5dGVzIChzdHIsIHVuaXRzKSB7XG4gIHZhciBjLCBoaSwgbG9cbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKCh1bml0cyAtPSAyKSA8IDApIGJyZWFrXG5cbiAgICBjID0gc3RyLmNoYXJDb2RlQXQoaSlcbiAgICBoaSA9IGMgPj4gOFxuICAgIGxvID0gYyAlIDI1NlxuICAgIGJ5dGVBcnJheS5wdXNoKGxvKVxuICAgIGJ5dGVBcnJheS5wdXNoKGhpKVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiBiYXNlNjRUb0J5dGVzIChzdHIpIHtcbiAgcmV0dXJuIGJhc2U2NC50b0J5dGVBcnJheShiYXNlNjRjbGVhbihzdHIpKVxufVxuXG5mdW5jdGlvbiBibGl0QnVmZmVyIChzcmMsIGRzdCwgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgIGlmICgoaSArIG9mZnNldCA+PSBkc3QubGVuZ3RoKSB8fCAoaSA+PSBzcmMubGVuZ3RoKSkgYnJlYWtcbiAgICBkc3RbaSArIG9mZnNldF0gPSBzcmNbaV1cbiAgfVxuICByZXR1cm4gaVxufVxuIiwidmFyIGxvb2t1cCA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvJztcblxuOyhmdW5jdGlvbiAoZXhwb3J0cykge1xuXHQndXNlIHN0cmljdCc7XG5cbiAgdmFyIEFyciA9ICh0eXBlb2YgVWludDhBcnJheSAhPT0gJ3VuZGVmaW5lZCcpXG4gICAgPyBVaW50OEFycmF5XG4gICAgOiBBcnJheVxuXG5cdHZhciBQTFVTICAgPSAnKycuY2hhckNvZGVBdCgwKVxuXHR2YXIgU0xBU0ggID0gJy8nLmNoYXJDb2RlQXQoMClcblx0dmFyIE5VTUJFUiA9ICcwJy5jaGFyQ29kZUF0KDApXG5cdHZhciBMT1dFUiAgPSAnYScuY2hhckNvZGVBdCgwKVxuXHR2YXIgVVBQRVIgID0gJ0EnLmNoYXJDb2RlQXQoMClcblx0dmFyIFBMVVNfVVJMX1NBRkUgPSAnLScuY2hhckNvZGVBdCgwKVxuXHR2YXIgU0xBU0hfVVJMX1NBRkUgPSAnXycuY2hhckNvZGVBdCgwKVxuXG5cdGZ1bmN0aW9uIGRlY29kZSAoZWx0KSB7XG5cdFx0dmFyIGNvZGUgPSBlbHQuY2hhckNvZGVBdCgwKVxuXHRcdGlmIChjb2RlID09PSBQTFVTIHx8XG5cdFx0ICAgIGNvZGUgPT09IFBMVVNfVVJMX1NBRkUpXG5cdFx0XHRyZXR1cm4gNjIgLy8gJysnXG5cdFx0aWYgKGNvZGUgPT09IFNMQVNIIHx8XG5cdFx0ICAgIGNvZGUgPT09IFNMQVNIX1VSTF9TQUZFKVxuXHRcdFx0cmV0dXJuIDYzIC8vICcvJ1xuXHRcdGlmIChjb2RlIDwgTlVNQkVSKVxuXHRcdFx0cmV0dXJuIC0xIC8vbm8gbWF0Y2hcblx0XHRpZiAoY29kZSA8IE5VTUJFUiArIDEwKVxuXHRcdFx0cmV0dXJuIGNvZGUgLSBOVU1CRVIgKyAyNiArIDI2XG5cdFx0aWYgKGNvZGUgPCBVUFBFUiArIDI2KVxuXHRcdFx0cmV0dXJuIGNvZGUgLSBVUFBFUlxuXHRcdGlmIChjb2RlIDwgTE9XRVIgKyAyNilcblx0XHRcdHJldHVybiBjb2RlIC0gTE9XRVIgKyAyNlxuXHR9XG5cblx0ZnVuY3Rpb24gYjY0VG9CeXRlQXJyYXkgKGI2NCkge1xuXHRcdHZhciBpLCBqLCBsLCB0bXAsIHBsYWNlSG9sZGVycywgYXJyXG5cblx0XHRpZiAoYjY0Lmxlbmd0aCAlIDQgPiAwKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc3RyaW5nLiBMZW5ndGggbXVzdCBiZSBhIG11bHRpcGxlIG9mIDQnKVxuXHRcdH1cblxuXHRcdC8vIHRoZSBudW1iZXIgb2YgZXF1YWwgc2lnbnMgKHBsYWNlIGhvbGRlcnMpXG5cdFx0Ly8gaWYgdGhlcmUgYXJlIHR3byBwbGFjZWhvbGRlcnMsIHRoYW4gdGhlIHR3byBjaGFyYWN0ZXJzIGJlZm9yZSBpdFxuXHRcdC8vIHJlcHJlc2VudCBvbmUgYnl0ZVxuXHRcdC8vIGlmIHRoZXJlIGlzIG9ubHkgb25lLCB0aGVuIHRoZSB0aHJlZSBjaGFyYWN0ZXJzIGJlZm9yZSBpdCByZXByZXNlbnQgMiBieXRlc1xuXHRcdC8vIHRoaXMgaXMganVzdCBhIGNoZWFwIGhhY2sgdG8gbm90IGRvIGluZGV4T2YgdHdpY2Vcblx0XHR2YXIgbGVuID0gYjY0Lmxlbmd0aFxuXHRcdHBsYWNlSG9sZGVycyA9ICc9JyA9PT0gYjY0LmNoYXJBdChsZW4gLSAyKSA/IDIgOiAnPScgPT09IGI2NC5jaGFyQXQobGVuIC0gMSkgPyAxIDogMFxuXG5cdFx0Ly8gYmFzZTY0IGlzIDQvMyArIHVwIHRvIHR3byBjaGFyYWN0ZXJzIG9mIHRoZSBvcmlnaW5hbCBkYXRhXG5cdFx0YXJyID0gbmV3IEFycihiNjQubGVuZ3RoICogMyAvIDQgLSBwbGFjZUhvbGRlcnMpXG5cblx0XHQvLyBpZiB0aGVyZSBhcmUgcGxhY2Vob2xkZXJzLCBvbmx5IGdldCB1cCB0byB0aGUgbGFzdCBjb21wbGV0ZSA0IGNoYXJzXG5cdFx0bCA9IHBsYWNlSG9sZGVycyA+IDAgPyBiNjQubGVuZ3RoIC0gNCA6IGI2NC5sZW5ndGhcblxuXHRcdHZhciBMID0gMFxuXG5cdFx0ZnVuY3Rpb24gcHVzaCAodikge1xuXHRcdFx0YXJyW0wrK10gPSB2XG5cdFx0fVxuXG5cdFx0Zm9yIChpID0gMCwgaiA9IDA7IGkgPCBsOyBpICs9IDQsIGogKz0gMykge1xuXHRcdFx0dG1wID0gKGRlY29kZShiNjQuY2hhckF0KGkpKSA8PCAxOCkgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDEpKSA8PCAxMikgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDIpKSA8PCA2KSB8IGRlY29kZShiNjQuY2hhckF0KGkgKyAzKSlcblx0XHRcdHB1c2goKHRtcCAmIDB4RkYwMDAwKSA+PiAxNilcblx0XHRcdHB1c2goKHRtcCAmIDB4RkYwMCkgPj4gOClcblx0XHRcdHB1c2godG1wICYgMHhGRilcblx0XHR9XG5cblx0XHRpZiAocGxhY2VIb2xkZXJzID09PSAyKSB7XG5cdFx0XHR0bXAgPSAoZGVjb2RlKGI2NC5jaGFyQXQoaSkpIDw8IDIpIHwgKGRlY29kZShiNjQuY2hhckF0KGkgKyAxKSkgPj4gNClcblx0XHRcdHB1c2godG1wICYgMHhGRilcblx0XHR9IGVsc2UgaWYgKHBsYWNlSG9sZGVycyA9PT0gMSkge1xuXHRcdFx0dG1wID0gKGRlY29kZShiNjQuY2hhckF0KGkpKSA8PCAxMCkgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDEpKSA8PCA0KSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMikpID4+IDIpXG5cdFx0XHRwdXNoKCh0bXAgPj4gOCkgJiAweEZGKVxuXHRcdFx0cHVzaCh0bXAgJiAweEZGKVxuXHRcdH1cblxuXHRcdHJldHVybiBhcnJcblx0fVxuXG5cdGZ1bmN0aW9uIHVpbnQ4VG9CYXNlNjQgKHVpbnQ4KSB7XG5cdFx0dmFyIGksXG5cdFx0XHRleHRyYUJ5dGVzID0gdWludDgubGVuZ3RoICUgMywgLy8gaWYgd2UgaGF2ZSAxIGJ5dGUgbGVmdCwgcGFkIDIgYnl0ZXNcblx0XHRcdG91dHB1dCA9IFwiXCIsXG5cdFx0XHR0ZW1wLCBsZW5ndGhcblxuXHRcdGZ1bmN0aW9uIGVuY29kZSAobnVtKSB7XG5cdFx0XHRyZXR1cm4gbG9va3VwLmNoYXJBdChudW0pXG5cdFx0fVxuXG5cdFx0ZnVuY3Rpb24gdHJpcGxldFRvQmFzZTY0IChudW0pIHtcblx0XHRcdHJldHVybiBlbmNvZGUobnVtID4+IDE4ICYgMHgzRikgKyBlbmNvZGUobnVtID4+IDEyICYgMHgzRikgKyBlbmNvZGUobnVtID4+IDYgJiAweDNGKSArIGVuY29kZShudW0gJiAweDNGKVxuXHRcdH1cblxuXHRcdC8vIGdvIHRocm91Z2ggdGhlIGFycmF5IGV2ZXJ5IHRocmVlIGJ5dGVzLCB3ZSdsbCBkZWFsIHdpdGggdHJhaWxpbmcgc3R1ZmYgbGF0ZXJcblx0XHRmb3IgKGkgPSAwLCBsZW5ndGggPSB1aW50OC5sZW5ndGggLSBleHRyYUJ5dGVzOyBpIDwgbGVuZ3RoOyBpICs9IDMpIHtcblx0XHRcdHRlbXAgPSAodWludDhbaV0gPDwgMTYpICsgKHVpbnQ4W2kgKyAxXSA8PCA4KSArICh1aW50OFtpICsgMl0pXG5cdFx0XHRvdXRwdXQgKz0gdHJpcGxldFRvQmFzZTY0KHRlbXApXG5cdFx0fVxuXG5cdFx0Ly8gcGFkIHRoZSBlbmQgd2l0aCB6ZXJvcywgYnV0IG1ha2Ugc3VyZSB0byBub3QgZm9yZ2V0IHRoZSBleHRyYSBieXRlc1xuXHRcdHN3aXRjaCAoZXh0cmFCeXRlcykge1xuXHRcdFx0Y2FzZSAxOlxuXHRcdFx0XHR0ZW1wID0gdWludDhbdWludDgubGVuZ3RoIC0gMV1cblx0XHRcdFx0b3V0cHV0ICs9IGVuY29kZSh0ZW1wID4+IDIpXG5cdFx0XHRcdG91dHB1dCArPSBlbmNvZGUoKHRlbXAgPDwgNCkgJiAweDNGKVxuXHRcdFx0XHRvdXRwdXQgKz0gJz09J1xuXHRcdFx0XHRicmVha1xuXHRcdFx0Y2FzZSAyOlxuXHRcdFx0XHR0ZW1wID0gKHVpbnQ4W3VpbnQ4Lmxlbmd0aCAtIDJdIDw8IDgpICsgKHVpbnQ4W3VpbnQ4Lmxlbmd0aCAtIDFdKVxuXHRcdFx0XHRvdXRwdXQgKz0gZW5jb2RlKHRlbXAgPj4gMTApXG5cdFx0XHRcdG91dHB1dCArPSBlbmNvZGUoKHRlbXAgPj4gNCkgJiAweDNGKVxuXHRcdFx0XHRvdXRwdXQgKz0gZW5jb2RlKCh0ZW1wIDw8IDIpICYgMHgzRilcblx0XHRcdFx0b3V0cHV0ICs9ICc9J1xuXHRcdFx0XHRicmVha1xuXHRcdH1cblxuXHRcdHJldHVybiBvdXRwdXRcblx0fVxuXG5cdGV4cG9ydHMudG9CeXRlQXJyYXkgPSBiNjRUb0J5dGVBcnJheVxuXHRleHBvcnRzLmZyb21CeXRlQXJyYXkgPSB1aW50OFRvQmFzZTY0XG59KHR5cGVvZiBleHBvcnRzID09PSAndW5kZWZpbmVkJyA/ICh0aGlzLmJhc2U2NGpzID0ge30pIDogZXhwb3J0cykpXG4iLCJleHBvcnRzLnJlYWQgPSBmdW5jdGlvbiAoYnVmZmVyLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbVxuICB2YXIgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIG5CaXRzID0gLTdcbiAgdmFyIGkgPSBpc0xFID8gKG5CeXRlcyAtIDEpIDogMFxuICB2YXIgZCA9IGlzTEUgPyAtMSA6IDFcbiAgdmFyIHMgPSBidWZmZXJbb2Zmc2V0ICsgaV1cblxuICBpICs9IGRcblxuICBlID0gcyAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBzID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBlTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IGUgPSBlICogMjU2ICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XG5cbiAgbSA9IGUgJiAoKDEgPDwgKC1uQml0cykpIC0gMSlcbiAgZSA+Pj0gKC1uQml0cylcbiAgbkJpdHMgKz0gbUxlblxuICBmb3IgKDsgbkJpdHMgPiAwOyBtID0gbSAqIDI1NiArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIGlmIChlID09PSAwKSB7XG4gICAgZSA9IDEgLSBlQmlhc1xuICB9IGVsc2UgaWYgKGUgPT09IGVNYXgpIHtcbiAgICByZXR1cm4gbSA/IE5hTiA6ICgocyA/IC0xIDogMSkgKiBJbmZpbml0eSlcbiAgfSBlbHNlIHtcbiAgICBtID0gbSArIE1hdGgucG93KDIsIG1MZW4pXG4gICAgZSA9IGUgLSBlQmlhc1xuICB9XG4gIHJldHVybiAocyA/IC0xIDogMSkgKiBtICogTWF0aC5wb3coMiwgZSAtIG1MZW4pXG59XG5cbmV4cG9ydHMud3JpdGUgPSBmdW5jdGlvbiAoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG0sIGNcbiAgdmFyIGVMZW4gPSBuQnl0ZXMgKiA4IC0gbUxlbiAtIDFcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDFcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxXG4gIHZhciBydCA9IChtTGVuID09PSAyMyA/IE1hdGgucG93KDIsIC0yNCkgLSBNYXRoLnBvdygyLCAtNzcpIDogMClcbiAgdmFyIGkgPSBpc0xFID8gMCA6IChuQnl0ZXMgLSAxKVxuICB2YXIgZCA9IGlzTEUgPyAxIDogLTFcbiAgdmFyIHMgPSB2YWx1ZSA8IDAgfHwgKHZhbHVlID09PSAwICYmIDEgLyB2YWx1ZSA8IDApID8gMSA6IDBcblxuICB2YWx1ZSA9IE1hdGguYWJzKHZhbHVlKVxuXG4gIGlmIChpc05hTih2YWx1ZSkgfHwgdmFsdWUgPT09IEluZmluaXR5KSB7XG4gICAgbSA9IGlzTmFOKHZhbHVlKSA/IDEgOiAwXG4gICAgZSA9IGVNYXhcbiAgfSBlbHNlIHtcbiAgICBlID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMilcbiAgICBpZiAodmFsdWUgKiAoYyA9IE1hdGgucG93KDIsIC1lKSkgPCAxKSB7XG4gICAgICBlLS1cbiAgICAgIGMgKj0gMlxuICAgIH1cbiAgICBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIHZhbHVlICs9IHJ0IC8gY1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSArPSBydCAqIE1hdGgucG93KDIsIDEgLSBlQmlhcylcbiAgICB9XG4gICAgaWYgKHZhbHVlICogYyA+PSAyKSB7XG4gICAgICBlKytcbiAgICAgIGMgLz0gMlxuICAgIH1cblxuICAgIGlmIChlICsgZUJpYXMgPj0gZU1heCkge1xuICAgICAgbSA9IDBcbiAgICAgIGUgPSBlTWF4XG4gICAgfSBlbHNlIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgbSA9ICh2YWx1ZSAqIGMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gZSArIGVCaWFzXG4gICAgfSBlbHNlIHtcbiAgICAgIG0gPSB2YWx1ZSAqIE1hdGgucG93KDIsIGVCaWFzIC0gMSkgKiBNYXRoLnBvdygyLCBtTGVuKVxuICAgICAgZSA9IDBcbiAgICB9XG4gIH1cblxuICBmb3IgKDsgbUxlbiA+PSA4OyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBtICYgMHhmZiwgaSArPSBkLCBtIC89IDI1NiwgbUxlbiAtPSA4KSB7fVxuXG4gIGUgPSAoZSA8PCBtTGVuKSB8IG1cbiAgZUxlbiArPSBtTGVuXG4gIGZvciAoOyBlTGVuID4gMDsgYnVmZmVyW29mZnNldCArIGldID0gZSAmIDB4ZmYsIGkgKz0gZCwgZSAvPSAyNTYsIGVMZW4gLT0gOCkge31cblxuICBidWZmZXJbb2Zmc2V0ICsgaSAtIGRdIHw9IHMgKiAxMjhcbn1cbiIsIlxuLyoqXG4gKiBpc0FycmF5XG4gKi9cblxudmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5O1xuXG4vKipcbiAqIHRvU3RyaW5nXG4gKi9cblxudmFyIHN0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbi8qKlxuICogV2hldGhlciBvciBub3QgdGhlIGdpdmVuIGB2YWxgXG4gKiBpcyBhbiBhcnJheS5cbiAqXG4gKiBleGFtcGxlOlxuICpcbiAqICAgICAgICBpc0FycmF5KFtdKTtcbiAqICAgICAgICAvLyA+IHRydWVcbiAqICAgICAgICBpc0FycmF5KGFyZ3VtZW50cyk7XG4gKiAgICAgICAgLy8gPiBmYWxzZVxuICogICAgICAgIGlzQXJyYXkoJycpO1xuICogICAgICAgIC8vID4gZmFsc2VcbiAqXG4gKiBAcGFyYW0ge21peGVkfSB2YWxcbiAqIEByZXR1cm4ge2Jvb2x9XG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBpc0FycmF5IHx8IGZ1bmN0aW9uICh2YWwpIHtcbiAgcmV0dXJuICEhIHZhbCAmJiAnW29iamVjdCBBcnJheV0nID09IHN0ci5jYWxsKHZhbCk7XG59O1xuIiwiLyoganNoaW50IG5vZGU6IHRydWUgKi9cbihmdW5jdGlvbiAoKSB7XG4gICAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgICBmdW5jdGlvbiBDb29raWVBY2Nlc3NJbmZvKGRvbWFpbiwgcGF0aCwgc2VjdXJlLCBzY3JpcHQpIHtcbiAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBDb29raWVBY2Nlc3NJbmZvKSB7XG4gICAgICAgICAgICB0aGlzLmRvbWFpbiA9IGRvbWFpbiB8fCB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0aGlzLnBhdGggPSBwYXRoIHx8IFwiL1wiO1xuICAgICAgICAgICAgdGhpcy5zZWN1cmUgPSAhIXNlY3VyZTtcbiAgICAgICAgICAgIHRoaXMuc2NyaXB0ID0gISFzY3JpcHQ7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IENvb2tpZUFjY2Vzc0luZm8oZG9tYWluLCBwYXRoLCBzZWN1cmUsIHNjcmlwdCk7XG4gICAgfVxuICAgIGV4cG9ydHMuQ29va2llQWNjZXNzSW5mbyA9IENvb2tpZUFjY2Vzc0luZm87XG5cbiAgICBmdW5jdGlvbiBDb29raWUoY29va2llc3RyLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKSB7XG4gICAgICAgIGlmIChjb29raWVzdHIgaW5zdGFuY2VvZiBDb29raWUpIHtcbiAgICAgICAgICAgIHJldHVybiBjb29raWVzdHI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBDb29raWUpIHtcbiAgICAgICAgICAgIHRoaXMubmFtZSA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLnZhbHVlID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuZXhwaXJhdGlvbl9kYXRlID0gSW5maW5pdHk7XG4gICAgICAgICAgICB0aGlzLnBhdGggPSBTdHJpbmcocmVxdWVzdF9wYXRoIHx8IFwiL1wiKTtcbiAgICAgICAgICAgIHRoaXMuZXhwbGljaXRfcGF0aCA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5kb21haW4gPSByZXF1ZXN0X2RvbWFpbiB8fCBudWxsO1xuICAgICAgICAgICAgdGhpcy5leHBsaWNpdF9kb21haW4gPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuc2VjdXJlID0gZmFsc2U7IC8vaG93IHRvIGRlZmluZSBkZWZhdWx0P1xuICAgICAgICAgICAgdGhpcy5ub3NjcmlwdCA9IGZhbHNlOyAvL2h0dHBvbmx5XG4gICAgICAgICAgICBpZiAoY29va2llc3RyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wYXJzZShjb29raWVzdHIsIHJlcXVlc3RfZG9tYWluLCByZXF1ZXN0X3BhdGgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBDb29raWUoY29va2llc3RyLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKTtcbiAgICB9XG4gICAgZXhwb3J0cy5Db29raWUgPSBDb29raWU7XG5cbiAgICBDb29raWUucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gICAgICAgIHZhciBzdHIgPSBbdGhpcy5uYW1lICsgXCI9XCIgKyB0aGlzLnZhbHVlXTtcbiAgICAgICAgaWYgKHRoaXMuZXhwaXJhdGlvbl9kYXRlICE9PSBJbmZpbml0eSkge1xuICAgICAgICAgICAgc3RyLnB1c2goXCJleHBpcmVzPVwiICsgKG5ldyBEYXRlKHRoaXMuZXhwaXJhdGlvbl9kYXRlKSkudG9HTVRTdHJpbmcoKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuZG9tYWluKSB7XG4gICAgICAgICAgICBzdHIucHVzaChcImRvbWFpbj1cIiArIHRoaXMuZG9tYWluKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5wYXRoKSB7XG4gICAgICAgICAgICBzdHIucHVzaChcInBhdGg9XCIgKyB0aGlzLnBhdGgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnNlY3VyZSkge1xuICAgICAgICAgICAgc3RyLnB1c2goXCJzZWN1cmVcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMubm9zY3JpcHQpIHtcbiAgICAgICAgICAgIHN0ci5wdXNoKFwiaHR0cG9ubHlcIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHN0ci5qb2luKFwiOyBcIik7XG4gICAgfTtcblxuICAgIENvb2tpZS5wcm90b3R5cGUudG9WYWx1ZVN0cmluZyA9IGZ1bmN0aW9uIHRvVmFsdWVTdHJpbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm5hbWUgKyBcIj1cIiArIHRoaXMudmFsdWU7XG4gICAgfTtcblxuICAgIHZhciBjb29raWVfc3RyX3NwbGl0dGVyID0gL1s6XSg/PVxccypbYS16QS1aMC05X1xcLV0rXFxzKls9XSkvZztcbiAgICBDb29raWUucHJvdG90eXBlLnBhcnNlID0gZnVuY3Rpb24gcGFyc2Uoc3RyLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKSB7XG4gICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgQ29va2llKSB7XG4gICAgICAgICAgICB2YXIgcGFydHMgPSBzdHIuc3BsaXQoXCI7XCIpLmZpbHRlcihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICEhdmFsdWU7XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgcGFpciA9IHBhcnRzWzBdLm1hdGNoKC8oW149XSspPShbXFxzXFxTXSopLyksXG4gICAgICAgICAgICAgICAga2V5ID0gcGFpclsxXSxcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHBhaXJbMl0sXG4gICAgICAgICAgICAgICAgaTtcbiAgICAgICAgICAgIHRoaXMubmFtZSA9IGtleTtcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcblxuICAgICAgICAgICAgZm9yIChpID0gMTsgaSA8IHBhcnRzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgcGFpciA9IHBhcnRzW2ldLm1hdGNoKC8oW149XSspKD86PShbXFxzXFxTXSopKT8vKTtcbiAgICAgICAgICAgICAgICBrZXkgPSBwYWlyWzFdLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgICAgICAgIHZhbHVlID0gcGFpclsyXTtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGtleSkge1xuICAgICAgICAgICAgICAgIGNhc2UgXCJodHRwb25seVwiOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLm5vc2NyaXB0ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcImV4cGlyZXNcIjpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5leHBpcmF0aW9uX2RhdGUgPSB2YWx1ZSA/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgTnVtYmVyKERhdGUucGFyc2UodmFsdWUpKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5maW5pdHk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJwYXRoXCI6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGF0aCA9IHZhbHVlID9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZS50cmltKCkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiXCI7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXhwbGljaXRfcGF0aCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJkb21haW5cIjpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kb21haW4gPSB2YWx1ZSA/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUudHJpbSgpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIlwiO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmV4cGxpY2l0X2RvbWFpbiA9ICEhdGhpcy5kb21haW47XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJzZWN1cmVcIjpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWN1cmUgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5leHBsaWNpdF9wYXRoKSB7XG4gICAgICAgICAgICAgICB0aGlzLnBhdGggPSByZXF1ZXN0X3BhdGggfHwgXCIvXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRoaXMuZXhwbGljaXRfZG9tYWluKSB7XG4gICAgICAgICAgICAgICB0aGlzLmRvbWFpbiA9IHJlcXVlc3RfZG9tYWluO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IENvb2tpZSgpLnBhcnNlKHN0ciwgcmVxdWVzdF9kb21haW4sIHJlcXVlc3RfcGF0aCk7XG4gICAgfTtcblxuICAgIENvb2tpZS5wcm90b3R5cGUubWF0Y2hlcyA9IGZ1bmN0aW9uIG1hdGNoZXMoYWNjZXNzX2luZm8pIHtcbiAgICAgICAgaWYgKHRoaXMubm9zY3JpcHQgJiYgYWNjZXNzX2luZm8uc2NyaXB0IHx8XG4gICAgICAgICAgICAgICAgdGhpcy5zZWN1cmUgJiYgIWFjY2Vzc19pbmZvLnNlY3VyZSB8fFxuICAgICAgICAgICAgICAgICF0aGlzLmNvbGxpZGVzV2l0aChhY2Nlc3NfaW5mbykpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuXG4gICAgQ29va2llLnByb3RvdHlwZS5jb2xsaWRlc1dpdGggPSBmdW5jdGlvbiBjb2xsaWRlc1dpdGgoYWNjZXNzX2luZm8pIHtcbiAgICAgICAgaWYgKCh0aGlzLnBhdGggJiYgIWFjY2Vzc19pbmZvLnBhdGgpIHx8ICh0aGlzLmRvbWFpbiAmJiAhYWNjZXNzX2luZm8uZG9tYWluKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnBhdGggJiYgYWNjZXNzX2luZm8ucGF0aC5pbmRleE9mKHRoaXMucGF0aCkgIT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5leHBsaWNpdF9wYXRoICYmIGFjY2Vzc19pbmZvLnBhdGguaW5kZXhPZiggdGhpcy5wYXRoICkgIT09IDApIHtcbiAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBhY2Nlc3NfZG9tYWluID0gYWNjZXNzX2luZm8uZG9tYWluICYmIGFjY2Vzc19pbmZvLmRvbWFpbi5yZXBsYWNlKC9eW1xcLl0vLCcnKTtcbiAgICAgICAgdmFyIGNvb2tpZV9kb21haW4gPSB0aGlzLmRvbWFpbiAmJiB0aGlzLmRvbWFpbi5yZXBsYWNlKC9eW1xcLl0vLCcnKTtcbiAgICAgICAgaWYgKGNvb2tpZV9kb21haW4gPT09IGFjY2Vzc19kb21haW4pIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb29raWVfZG9tYWluKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuZXhwbGljaXRfZG9tYWluKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyB3ZSBhbHJlYWR5IGNoZWNrZWQgaWYgdGhlIGRvbWFpbnMgd2VyZSBleGFjdGx5IHRoZSBzYW1lXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgd2lsZGNhcmQgPSBhY2Nlc3NfZG9tYWluLmluZGV4T2YoY29va2llX2RvbWFpbik7XG4gICAgICAgICAgICBpZiAod2lsZGNhcmQgPT09IC0xIHx8IHdpbGRjYXJkICE9PSBhY2Nlc3NfZG9tYWluLmxlbmd0aCAtIGNvb2tpZV9kb21haW4ubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIENvb2tpZUphcigpIHtcbiAgICAgICAgdmFyIGNvb2tpZXMsIGNvb2tpZXNfbGlzdCwgY29sbGlkYWJsZV9jb29raWU7XG4gICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgQ29va2llSmFyKSB7XG4gICAgICAgICAgICBjb29raWVzID0gT2JqZWN0LmNyZWF0ZShudWxsKTsgLy9uYW1lOiBbQ29va2llXVxuXG4gICAgICAgICAgICB0aGlzLnNldENvb2tpZSA9IGZ1bmN0aW9uIHNldENvb2tpZShjb29raWUsIHJlcXVlc3RfZG9tYWluLCByZXF1ZXN0X3BhdGgpIHtcbiAgICAgICAgICAgICAgICB2YXIgcmVtb3ZlLCBpO1xuICAgICAgICAgICAgICAgIGNvb2tpZSA9IG5ldyBDb29raWUoY29va2llLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKTtcbiAgICAgICAgICAgICAgICAvL0RlbGV0ZSB0aGUgY29va2llIGlmIHRoZSBzZXQgaXMgcGFzdCB0aGUgY3VycmVudCB0aW1lXG4gICAgICAgICAgICAgICAgcmVtb3ZlID0gY29va2llLmV4cGlyYXRpb25fZGF0ZSA8PSBEYXRlLm5vdygpO1xuICAgICAgICAgICAgICAgIGlmIChjb29raWVzW2Nvb2tpZS5uYW1lXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvb2tpZXNfbGlzdCA9IGNvb2tpZXNbY29va2llLm5hbWVdO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY29va2llc19saXN0Lmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2xsaWRhYmxlX2Nvb2tpZSA9IGNvb2tpZXNfbGlzdFtpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb2xsaWRhYmxlX2Nvb2tpZS5jb2xsaWRlc1dpdGgoY29va2llKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZW1vdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29va2llc19saXN0LnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvb2tpZXNfbGlzdC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBjb29raWVzW2Nvb2tpZS5uYW1lXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvb2tpZXNfbGlzdFtpXSA9IGNvb2tpZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29va2llO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZW1vdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb29raWVzX2xpc3QucHVzaChjb29raWUpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29va2llO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAocmVtb3ZlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29va2llc1tjb29raWUubmFtZV0gPSBbY29va2llXTtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29va2llc1tjb29raWUubmFtZV07XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgLy9yZXR1cm5zIGEgY29va2llXG4gICAgICAgICAgICB0aGlzLmdldENvb2tpZSA9IGZ1bmN0aW9uIGdldENvb2tpZShjb29raWVfbmFtZSwgYWNjZXNzX2luZm8pIHtcbiAgICAgICAgICAgICAgICB2YXIgY29va2llLCBpO1xuICAgICAgICAgICAgICAgIGNvb2tpZXNfbGlzdCA9IGNvb2tpZXNbY29va2llX25hbWVdO1xuICAgICAgICAgICAgICAgIGlmICghY29va2llc19saXN0KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvb2tpZXNfbGlzdC5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICBjb29raWUgPSBjb29raWVzX2xpc3RbaV07XG4gICAgICAgICAgICAgICAgICAgIGlmIChjb29raWUuZXhwaXJhdGlvbl9kYXRlIDw9IERhdGUubm93KCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb29raWVzX2xpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGNvb2tpZXNbY29va2llLm5hbWVdO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoY29va2llLm1hdGNoZXMoYWNjZXNzX2luZm8pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29va2llO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vcmV0dXJucyBhIGxpc3Qgb2YgY29va2llc1xuICAgICAgICAgICAgdGhpcy5nZXRDb29raWVzID0gZnVuY3Rpb24gZ2V0Q29va2llcyhhY2Nlc3NfaW5mbykge1xuICAgICAgICAgICAgICAgIHZhciBtYXRjaGVzID0gW10sIGNvb2tpZV9uYW1lLCBjb29raWU7XG4gICAgICAgICAgICAgICAgZm9yIChjb29raWVfbmFtZSBpbiBjb29raWVzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvb2tpZSA9IHRoaXMuZ2V0Q29va2llKGNvb2tpZV9uYW1lLCBhY2Nlc3NfaW5mbyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjb29raWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoZXMucHVzaChjb29raWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG1hdGNoZXMudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoZXMuam9pbihcIjpcIik7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBtYXRjaGVzLnRvVmFsdWVTdHJpbmcgPSBmdW5jdGlvbiB0b1ZhbHVlU3RyaW5nKCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbWF0Y2hlcy5tYXAoZnVuY3Rpb24gKGMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjLnRvVmFsdWVTdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgfSkuam9pbignOycpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoZXM7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IENvb2tpZUphcigpO1xuICAgIH1cbiAgICBleHBvcnRzLkNvb2tpZUphciA9IENvb2tpZUphcjtcblxuICAgIC8vcmV0dXJucyBsaXN0IG9mIGNvb2tpZXMgdGhhdCB3ZXJlIHNldCBjb3JyZWN0bHkuIENvb2tpZXMgdGhhdCBhcmUgZXhwaXJlZCBhbmQgcmVtb3ZlZCBhcmUgbm90IHJldHVybmVkLlxuICAgIENvb2tpZUphci5wcm90b3R5cGUuc2V0Q29va2llcyA9IGZ1bmN0aW9uIHNldENvb2tpZXMoY29va2llcywgcmVxdWVzdF9kb21haW4sIHJlcXVlc3RfcGF0aCkge1xuICAgICAgICBjb29raWVzID0gQXJyYXkuaXNBcnJheShjb29raWVzKSA/XG4gICAgICAgICAgICAgICAgY29va2llcyA6XG4gICAgICAgICAgICAgICAgY29va2llcy5zcGxpdChjb29raWVfc3RyX3NwbGl0dGVyKTtcbiAgICAgICAgdmFyIHN1Y2Nlc3NmdWwgPSBbXSxcbiAgICAgICAgICAgIGksXG4gICAgICAgICAgICBjb29raWU7XG4gICAgICAgIGNvb2tpZXMgPSBjb29raWVzLm1hcChmdW5jdGlvbihpdGVtKXtcbiAgICAgICAgICAgIHJldHVybiBuZXcgQ29va2llKGl0ZW0sIHJlcXVlc3RfZG9tYWluLCByZXF1ZXN0X3BhdGgpO1xuICAgICAgICB9KTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvb2tpZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGNvb2tpZSA9IGNvb2tpZXNbaV07XG4gICAgICAgICAgICBpZiAodGhpcy5zZXRDb29raWUoY29va2llLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKSkge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3NmdWwucHVzaChjb29raWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdWNjZXNzZnVsO1xuICAgIH07XG59KCkpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciB5YW1sID0gcmVxdWlyZSgnLi9saWIvanMteWFtbC5qcycpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0geWFtbDtcbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgbG9hZGVyID0gcmVxdWlyZSgnLi9qcy15YW1sL2xvYWRlcicpO1xudmFyIGR1bXBlciA9IHJlcXVpcmUoJy4vanMteWFtbC9kdW1wZXInKTtcblxuXG5mdW5jdGlvbiBkZXByZWNhdGVkKG5hbWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0Z1bmN0aW9uICcgKyBuYW1lICsgJyBpcyBkZXByZWNhdGVkIGFuZCBjYW5ub3QgYmUgdXNlZC4nKTtcbiAgfTtcbn1cblxuXG5tb2R1bGUuZXhwb3J0cy5UeXBlICAgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9qcy15YW1sL3R5cGUnKTtcbm1vZHVsZS5leHBvcnRzLlNjaGVtYSAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL2pzLXlhbWwvc2NoZW1hJyk7XG5tb2R1bGUuZXhwb3J0cy5GQUlMU0FGRV9TQ0hFTUEgICAgID0gcmVxdWlyZSgnLi9qcy15YW1sL3NjaGVtYS9mYWlsc2FmZScpO1xubW9kdWxlLmV4cG9ydHMuSlNPTl9TQ0hFTUEgICAgICAgICA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvanNvbicpO1xubW9kdWxlLmV4cG9ydHMuQ09SRV9TQ0hFTUEgICAgICAgICA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvY29yZScpO1xubW9kdWxlLmV4cG9ydHMuREVGQVVMVF9TQUZFX1NDSEVNQSA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvZGVmYXVsdF9zYWZlJyk7XG5tb2R1bGUuZXhwb3J0cy5ERUZBVUxUX0ZVTExfU0NIRU1BID0gcmVxdWlyZSgnLi9qcy15YW1sL3NjaGVtYS9kZWZhdWx0X2Z1bGwnKTtcbm1vZHVsZS5leHBvcnRzLmxvYWQgICAgICAgICAgICAgICAgPSBsb2FkZXIubG9hZDtcbm1vZHVsZS5leHBvcnRzLmxvYWRBbGwgICAgICAgICAgICAgPSBsb2FkZXIubG9hZEFsbDtcbm1vZHVsZS5leHBvcnRzLnNhZmVMb2FkICAgICAgICAgICAgPSBsb2FkZXIuc2FmZUxvYWQ7XG5tb2R1bGUuZXhwb3J0cy5zYWZlTG9hZEFsbCAgICAgICAgID0gbG9hZGVyLnNhZmVMb2FkQWxsO1xubW9kdWxlLmV4cG9ydHMuZHVtcCAgICAgICAgICAgICAgICA9IGR1bXBlci5kdW1wO1xubW9kdWxlLmV4cG9ydHMuc2FmZUR1bXAgICAgICAgICAgICA9IGR1bXBlci5zYWZlRHVtcDtcbm1vZHVsZS5leHBvcnRzLllBTUxFeGNlcHRpb24gICAgICAgPSByZXF1aXJlKCcuL2pzLXlhbWwvZXhjZXB0aW9uJyk7XG5cbi8vIERlcHJlY2F0ZWQgc2NoZW1hIG5hbWVzIGZyb20gSlMtWUFNTCAyLjAueFxubW9kdWxlLmV4cG9ydHMuTUlOSU1BTF9TQ0hFTUEgPSByZXF1aXJlKCcuL2pzLXlhbWwvc2NoZW1hL2ZhaWxzYWZlJyk7XG5tb2R1bGUuZXhwb3J0cy5TQUZFX1NDSEVNQSAgICA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvZGVmYXVsdF9zYWZlJyk7XG5tb2R1bGUuZXhwb3J0cy5ERUZBVUxUX1NDSEVNQSA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvZGVmYXVsdF9mdWxsJyk7XG5cbi8vIERlcHJlY2F0ZWQgZnVuY3Rpb25zIGZyb20gSlMtWUFNTCAxLngueFxubW9kdWxlLmV4cG9ydHMuc2NhbiAgICAgICAgICAgPSBkZXByZWNhdGVkKCdzY2FuJyk7XG5tb2R1bGUuZXhwb3J0cy5wYXJzZSAgICAgICAgICA9IGRlcHJlY2F0ZWQoJ3BhcnNlJyk7XG5tb2R1bGUuZXhwb3J0cy5jb21wb3NlICAgICAgICA9IGRlcHJlY2F0ZWQoJ2NvbXBvc2UnKTtcbm1vZHVsZS5leHBvcnRzLmFkZENvbnN0cnVjdG9yID0gZGVwcmVjYXRlZCgnYWRkQ29uc3RydWN0b3InKTtcbiIsIid1c2Ugc3RyaWN0JztcblxuXG5mdW5jdGlvbiBpc05vdGhpbmcoc3ViamVjdCkge1xuICByZXR1cm4gKHR5cGVvZiBzdWJqZWN0ID09PSAndW5kZWZpbmVkJykgfHwgKHN1YmplY3QgPT09IG51bGwpO1xufVxuXG5cbmZ1bmN0aW9uIGlzT2JqZWN0KHN1YmplY3QpIHtcbiAgcmV0dXJuICh0eXBlb2Ygc3ViamVjdCA9PT0gJ29iamVjdCcpICYmIChzdWJqZWN0ICE9PSBudWxsKTtcbn1cblxuXG5mdW5jdGlvbiB0b0FycmF5KHNlcXVlbmNlKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KHNlcXVlbmNlKSkgcmV0dXJuIHNlcXVlbmNlO1xuICBlbHNlIGlmIChpc05vdGhpbmcoc2VxdWVuY2UpKSByZXR1cm4gW107XG5cbiAgcmV0dXJuIFsgc2VxdWVuY2UgXTtcbn1cblxuXG5mdW5jdGlvbiBleHRlbmQodGFyZ2V0LCBzb3VyY2UpIHtcbiAgdmFyIGluZGV4LCBsZW5ndGgsIGtleSwgc291cmNlS2V5cztcblxuICBpZiAoc291cmNlKSB7XG4gICAgc291cmNlS2V5cyA9IE9iamVjdC5rZXlzKHNvdXJjZSk7XG5cbiAgICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gc291cmNlS2V5cy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgICBrZXkgPSBzb3VyY2VLZXlzW2luZGV4XTtcbiAgICAgIHRhcmdldFtrZXldID0gc291cmNlW2tleV07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRhcmdldDtcbn1cblxuXG5mdW5jdGlvbiByZXBlYXQoc3RyaW5nLCBjb3VudCkge1xuICB2YXIgcmVzdWx0ID0gJycsIGN5Y2xlO1xuXG4gIGZvciAoY3ljbGUgPSAwOyBjeWNsZSA8IGNvdW50OyBjeWNsZSArPSAxKSB7XG4gICAgcmVzdWx0ICs9IHN0cmluZztcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cblxuZnVuY3Rpb24gaXNOZWdhdGl2ZVplcm8obnVtYmVyKSB7XG4gIHJldHVybiAobnVtYmVyID09PSAwKSAmJiAoTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZID09PSAxIC8gbnVtYmVyKTtcbn1cblxuXG5tb2R1bGUuZXhwb3J0cy5pc05vdGhpbmcgICAgICA9IGlzTm90aGluZztcbm1vZHVsZS5leHBvcnRzLmlzT2JqZWN0ICAgICAgID0gaXNPYmplY3Q7XG5tb2R1bGUuZXhwb3J0cy50b0FycmF5ICAgICAgICA9IHRvQXJyYXk7XG5tb2R1bGUuZXhwb3J0cy5yZXBlYXQgICAgICAgICA9IHJlcGVhdDtcbm1vZHVsZS5leHBvcnRzLmlzTmVnYXRpdmVaZXJvID0gaXNOZWdhdGl2ZVplcm87XG5tb2R1bGUuZXhwb3J0cy5leHRlbmQgICAgICAgICA9IGV4dGVuZDtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyplc2xpbnQtZGlzYWJsZSBuby11c2UtYmVmb3JlLWRlZmluZSovXG5cbnZhciBjb21tb24gICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9jb21tb24nKTtcbnZhciBZQU1MRXhjZXB0aW9uICAgICAgID0gcmVxdWlyZSgnLi9leGNlcHRpb24nKTtcbnZhciBERUZBVUxUX0ZVTExfU0NIRU1BID0gcmVxdWlyZSgnLi9zY2hlbWEvZGVmYXVsdF9mdWxsJyk7XG52YXIgREVGQVVMVF9TQUZFX1NDSEVNQSA9IHJlcXVpcmUoJy4vc2NoZW1hL2RlZmF1bHRfc2FmZScpO1xuXG52YXIgX3RvU3RyaW5nICAgICAgID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcbnZhciBfaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG52YXIgQ0hBUl9UQUIgICAgICAgICAgICAgICAgICA9IDB4MDk7IC8qIFRhYiAqL1xudmFyIENIQVJfTElORV9GRUVEICAgICAgICAgICAgPSAweDBBOyAvKiBMRiAqL1xudmFyIENIQVJfU1BBQ0UgICAgICAgICAgICAgICAgPSAweDIwOyAvKiBTcGFjZSAqL1xudmFyIENIQVJfRVhDTEFNQVRJT04gICAgICAgICAgPSAweDIxOyAvKiAhICovXG52YXIgQ0hBUl9ET1VCTEVfUVVPVEUgICAgICAgICA9IDB4MjI7IC8qIFwiICovXG52YXIgQ0hBUl9TSEFSUCAgICAgICAgICAgICAgICA9IDB4MjM7IC8qICMgKi9cbnZhciBDSEFSX1BFUkNFTlQgICAgICAgICAgICAgID0gMHgyNTsgLyogJSAqL1xudmFyIENIQVJfQU1QRVJTQU5EICAgICAgICAgICAgPSAweDI2OyAvKiAmICovXG52YXIgQ0hBUl9TSU5HTEVfUVVPVEUgICAgICAgICA9IDB4Mjc7IC8qICcgKi9cbnZhciBDSEFSX0FTVEVSSVNLICAgICAgICAgICAgID0gMHgyQTsgLyogKiAqL1xudmFyIENIQVJfQ09NTUEgICAgICAgICAgICAgICAgPSAweDJDOyAvKiAsICovXG52YXIgQ0hBUl9NSU5VUyAgICAgICAgICAgICAgICA9IDB4MkQ7IC8qIC0gKi9cbnZhciBDSEFSX0NPTE9OICAgICAgICAgICAgICAgID0gMHgzQTsgLyogOiAqL1xudmFyIENIQVJfR1JFQVRFUl9USEFOICAgICAgICAgPSAweDNFOyAvKiA+ICovXG52YXIgQ0hBUl9RVUVTVElPTiAgICAgICAgICAgICA9IDB4M0Y7IC8qID8gKi9cbnZhciBDSEFSX0NPTU1FUkNJQUxfQVQgICAgICAgID0gMHg0MDsgLyogQCAqL1xudmFyIENIQVJfTEVGVF9TUVVBUkVfQlJBQ0tFVCAgPSAweDVCOyAvKiBbICovXG52YXIgQ0hBUl9SSUdIVF9TUVVBUkVfQlJBQ0tFVCA9IDB4NUQ7IC8qIF0gKi9cbnZhciBDSEFSX0dSQVZFX0FDQ0VOVCAgICAgICAgID0gMHg2MDsgLyogYCAqL1xudmFyIENIQVJfTEVGVF9DVVJMWV9CUkFDS0VUICAgPSAweDdCOyAvKiB7ICovXG52YXIgQ0hBUl9WRVJUSUNBTF9MSU5FICAgICAgICA9IDB4N0M7IC8qIHwgKi9cbnZhciBDSEFSX1JJR0hUX0NVUkxZX0JSQUNLRVQgID0gMHg3RDsgLyogfSAqL1xuXG52YXIgRVNDQVBFX1NFUVVFTkNFUyA9IHt9O1xuXG5FU0NBUEVfU0VRVUVOQ0VTWzB4MDBdICAgPSAnXFxcXDAnO1xuRVNDQVBFX1NFUVVFTkNFU1sweDA3XSAgID0gJ1xcXFxhJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgwOF0gICA9ICdcXFxcYic7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MDldICAgPSAnXFxcXHQnO1xuRVNDQVBFX1NFUVVFTkNFU1sweDBBXSAgID0gJ1xcXFxuJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgwQl0gICA9ICdcXFxcdic7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MENdICAgPSAnXFxcXGYnO1xuRVNDQVBFX1NFUVVFTkNFU1sweDBEXSAgID0gJ1xcXFxyJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgxQl0gICA9ICdcXFxcZSc7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MjJdICAgPSAnXFxcXFwiJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHg1Q10gICA9ICdcXFxcXFxcXCc7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4ODVdICAgPSAnXFxcXE4nO1xuRVNDQVBFX1NFUVVFTkNFU1sweEEwXSAgID0gJ1xcXFxfJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgyMDI4XSA9ICdcXFxcTCc7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MjAyOV0gPSAnXFxcXFAnO1xuXG52YXIgREVQUkVDQVRFRF9CT09MRUFOU19TWU5UQVggPSBbXG4gICd5JywgJ1knLCAneWVzJywgJ1llcycsICdZRVMnLCAnb24nLCAnT24nLCAnT04nLFxuICAnbicsICdOJywgJ25vJywgJ05vJywgJ05PJywgJ29mZicsICdPZmYnLCAnT0ZGJ1xuXTtcblxuZnVuY3Rpb24gY29tcGlsZVN0eWxlTWFwKHNjaGVtYSwgbWFwKSB7XG4gIHZhciByZXN1bHQsIGtleXMsIGluZGV4LCBsZW5ndGgsIHRhZywgc3R5bGUsIHR5cGU7XG5cbiAgaWYgKG1hcCA9PT0gbnVsbCkgcmV0dXJuIHt9O1xuXG4gIHJlc3VsdCA9IHt9O1xuICBrZXlzID0gT2JqZWN0LmtleXMobWFwKTtcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0ga2V5cy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgdGFnID0ga2V5c1tpbmRleF07XG4gICAgc3R5bGUgPSBTdHJpbmcobWFwW3RhZ10pO1xuXG4gICAgaWYgKHRhZy5zbGljZSgwLCAyKSA9PT0gJyEhJykge1xuICAgICAgdGFnID0gJ3RhZzp5YW1sLm9yZywyMDAyOicgKyB0YWcuc2xpY2UoMik7XG4gICAgfVxuXG4gICAgdHlwZSA9IHNjaGVtYS5jb21waWxlZFR5cGVNYXBbdGFnXTtcblxuICAgIGlmICh0eXBlICYmIF9oYXNPd25Qcm9wZXJ0eS5jYWxsKHR5cGUuc3R5bGVBbGlhc2VzLCBzdHlsZSkpIHtcbiAgICAgIHN0eWxlID0gdHlwZS5zdHlsZUFsaWFzZXNbc3R5bGVdO1xuICAgIH1cblxuICAgIHJlc3VsdFt0YWddID0gc3R5bGU7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBlbmNvZGVIZXgoY2hhcmFjdGVyKSB7XG4gIHZhciBzdHJpbmcsIGhhbmRsZSwgbGVuZ3RoO1xuXG4gIHN0cmluZyA9IGNoYXJhY3Rlci50b1N0cmluZygxNikudG9VcHBlckNhc2UoKTtcblxuICBpZiAoY2hhcmFjdGVyIDw9IDB4RkYpIHtcbiAgICBoYW5kbGUgPSAneCc7XG4gICAgbGVuZ3RoID0gMjtcbiAgfSBlbHNlIGlmIChjaGFyYWN0ZXIgPD0gMHhGRkZGKSB7XG4gICAgaGFuZGxlID0gJ3UnO1xuICAgIGxlbmd0aCA9IDQ7XG4gIH0gZWxzZSBpZiAoY2hhcmFjdGVyIDw9IDB4RkZGRkZGRkYpIHtcbiAgICBoYW5kbGUgPSAnVSc7XG4gICAgbGVuZ3RoID0gODtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignY29kZSBwb2ludCB3aXRoaW4gYSBzdHJpbmcgbWF5IG5vdCBiZSBncmVhdGVyIHRoYW4gMHhGRkZGRkZGRicpO1xuICB9XG5cbiAgcmV0dXJuICdcXFxcJyArIGhhbmRsZSArIGNvbW1vbi5yZXBlYXQoJzAnLCBsZW5ndGggLSBzdHJpbmcubGVuZ3RoKSArIHN0cmluZztcbn1cblxuZnVuY3Rpb24gU3RhdGUob3B0aW9ucykge1xuICB0aGlzLnNjaGVtYSAgICAgICA9IG9wdGlvbnNbJ3NjaGVtYSddIHx8IERFRkFVTFRfRlVMTF9TQ0hFTUE7XG4gIHRoaXMuaW5kZW50ICAgICAgID0gTWF0aC5tYXgoMSwgKG9wdGlvbnNbJ2luZGVudCddIHx8IDIpKTtcbiAgdGhpcy5za2lwSW52YWxpZCAgPSBvcHRpb25zWydza2lwSW52YWxpZCddIHx8IGZhbHNlO1xuICB0aGlzLmZsb3dMZXZlbCAgICA9IChjb21tb24uaXNOb3RoaW5nKG9wdGlvbnNbJ2Zsb3dMZXZlbCddKSA/IC0xIDogb3B0aW9uc1snZmxvd0xldmVsJ10pO1xuICB0aGlzLnN0eWxlTWFwICAgICA9IGNvbXBpbGVTdHlsZU1hcCh0aGlzLnNjaGVtYSwgb3B0aW9uc1snc3R5bGVzJ10gfHwgbnVsbCk7XG4gIHRoaXMuc29ydEtleXMgICAgID0gb3B0aW9uc1snc29ydEtleXMnXSB8fCBmYWxzZTtcbiAgdGhpcy5saW5lV2lkdGggICAgPSBvcHRpb25zWydsaW5lV2lkdGgnXSB8fCA4MDtcbiAgdGhpcy5ub1JlZnMgICAgICAgPSBvcHRpb25zWydub1JlZnMnXSB8fCBmYWxzZTtcbiAgdGhpcy5ub0NvbXBhdE1vZGUgPSBvcHRpb25zWydub0NvbXBhdE1vZGUnXSB8fCBmYWxzZTtcblxuICB0aGlzLmltcGxpY2l0VHlwZXMgPSB0aGlzLnNjaGVtYS5jb21waWxlZEltcGxpY2l0O1xuICB0aGlzLmV4cGxpY2l0VHlwZXMgPSB0aGlzLnNjaGVtYS5jb21waWxlZEV4cGxpY2l0O1xuXG4gIHRoaXMudGFnID0gbnVsbDtcbiAgdGhpcy5yZXN1bHQgPSAnJztcblxuICB0aGlzLmR1cGxpY2F0ZXMgPSBbXTtcbiAgdGhpcy51c2VkRHVwbGljYXRlcyA9IG51bGw7XG59XG5cbi8vIEluZGVudHMgZXZlcnkgbGluZSBpbiBhIHN0cmluZy4gRW1wdHkgbGluZXMgKFxcbiBvbmx5KSBhcmUgbm90IGluZGVudGVkLlxuZnVuY3Rpb24gaW5kZW50U3RyaW5nKHN0cmluZywgc3BhY2VzKSB7XG4gIHZhciBpbmQgPSBjb21tb24ucmVwZWF0KCcgJywgc3BhY2VzKSxcbiAgICAgIHBvc2l0aW9uID0gMCxcbiAgICAgIG5leHQgPSAtMSxcbiAgICAgIHJlc3VsdCA9ICcnLFxuICAgICAgbGluZSxcbiAgICAgIGxlbmd0aCA9IHN0cmluZy5sZW5ndGg7XG5cbiAgd2hpbGUgKHBvc2l0aW9uIDwgbGVuZ3RoKSB7XG4gICAgbmV4dCA9IHN0cmluZy5pbmRleE9mKCdcXG4nLCBwb3NpdGlvbik7XG4gICAgaWYgKG5leHQgPT09IC0xKSB7XG4gICAgICBsaW5lID0gc3RyaW5nLnNsaWNlKHBvc2l0aW9uKTtcbiAgICAgIHBvc2l0aW9uID0gbGVuZ3RoO1xuICAgIH0gZWxzZSB7XG4gICAgICBsaW5lID0gc3RyaW5nLnNsaWNlKHBvc2l0aW9uLCBuZXh0ICsgMSk7XG4gICAgICBwb3NpdGlvbiA9IG5leHQgKyAxO1xuICAgIH1cblxuICAgIGlmIChsaW5lLmxlbmd0aCAmJiBsaW5lICE9PSAnXFxuJykgcmVzdWx0ICs9IGluZDtcblxuICAgIHJlc3VsdCArPSBsaW5lO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gZ2VuZXJhdGVOZXh0TGluZShzdGF0ZSwgbGV2ZWwpIHtcbiAgcmV0dXJuICdcXG4nICsgY29tbW9uLnJlcGVhdCgnICcsIHN0YXRlLmluZGVudCAqIGxldmVsKTtcbn1cblxuZnVuY3Rpb24gdGVzdEltcGxpY2l0UmVzb2x2aW5nKHN0YXRlLCBzdHIpIHtcbiAgdmFyIGluZGV4LCBsZW5ndGgsIHR5cGU7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IHN0YXRlLmltcGxpY2l0VHlwZXMubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIHR5cGUgPSBzdGF0ZS5pbXBsaWNpdFR5cGVzW2luZGV4XTtcblxuICAgIGlmICh0eXBlLnJlc29sdmUoc3RyKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vLyBbMzNdIHMtd2hpdGUgOjo9IHMtc3BhY2UgfCBzLXRhYlxuZnVuY3Rpb24gaXNXaGl0ZXNwYWNlKGMpIHtcbiAgcmV0dXJuIGMgPT09IENIQVJfU1BBQ0UgfHwgYyA9PT0gQ0hBUl9UQUI7XG59XG5cbi8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgY2hhcmFjdGVyIGNhbiBiZSBwcmludGVkIHdpdGhvdXQgZXNjYXBpbmcuXG4vLyBGcm9tIFlBTUwgMS4yOiBcImFueSBhbGxvd2VkIGNoYXJhY3RlcnMga25vd24gdG8gYmUgbm9uLXByaW50YWJsZVxuLy8gc2hvdWxkIGFsc28gYmUgZXNjYXBlZC4gW0hvd2V2ZXIsXSBUaGlzIGlzbuKAmXQgbWFuZGF0b3J5XCJcbi8vIERlcml2ZWQgZnJvbSBuYi1jaGFyIC0gXFx0IC0gI3g4NSAtICN4QTAgLSAjeDIwMjggLSAjeDIwMjkuXG5mdW5jdGlvbiBpc1ByaW50YWJsZShjKSB7XG4gIHJldHVybiAgKDB4MDAwMjAgPD0gYyAmJiBjIDw9IDB4MDAwMDdFKVxuICAgICAgfHwgKCgweDAwMEExIDw9IGMgJiYgYyA8PSAweDAwRDdGRikgJiYgYyAhPT0gMHgyMDI4ICYmIGMgIT09IDB4MjAyOSlcbiAgICAgIHx8ICgoMHgwRTAwMCA8PSBjICYmIGMgPD0gMHgwMEZGRkQpICYmIGMgIT09IDB4RkVGRiAvKiBCT00gKi8pXG4gICAgICB8fCAgKDB4MTAwMDAgPD0gYyAmJiBjIDw9IDB4MTBGRkZGKTtcbn1cblxuLy8gU2ltcGxpZmllZCB0ZXN0IGZvciB2YWx1ZXMgYWxsb3dlZCBhZnRlciB0aGUgZmlyc3QgY2hhcmFjdGVyIGluIHBsYWluIHN0eWxlLlxuZnVuY3Rpb24gaXNQbGFpblNhZmUoYykge1xuICAvLyBVc2VzIGEgc3Vic2V0IG9mIG5iLWNoYXIgLSBjLWZsb3ctaW5kaWNhdG9yIC0gXCI6XCIgLSBcIiNcIlxuICAvLyB3aGVyZSBuYi1jaGFyIDo6PSBjLXByaW50YWJsZSAtIGItY2hhciAtIGMtYnl0ZS1vcmRlci1tYXJrLlxuICByZXR1cm4gaXNQcmludGFibGUoYykgJiYgYyAhPT0gMHhGRUZGXG4gICAgLy8gLSBjLWZsb3ctaW5kaWNhdG9yXG4gICAgJiYgYyAhPT0gQ0hBUl9DT01NQVxuICAgICYmIGMgIT09IENIQVJfTEVGVF9TUVVBUkVfQlJBQ0tFVFxuICAgICYmIGMgIT09IENIQVJfUklHSFRfU1FVQVJFX0JSQUNLRVRcbiAgICAmJiBjICE9PSBDSEFSX0xFRlRfQ1VSTFlfQlJBQ0tFVFxuICAgICYmIGMgIT09IENIQVJfUklHSFRfQ1VSTFlfQlJBQ0tFVFxuICAgIC8vIC0gXCI6XCIgLSBcIiNcIlxuICAgICYmIGMgIT09IENIQVJfQ09MT05cbiAgICAmJiBjICE9PSBDSEFSX1NIQVJQO1xufVxuXG4vLyBTaW1wbGlmaWVkIHRlc3QgZm9yIHZhbHVlcyBhbGxvd2VkIGFzIHRoZSBmaXJzdCBjaGFyYWN0ZXIgaW4gcGxhaW4gc3R5bGUuXG5mdW5jdGlvbiBpc1BsYWluU2FmZUZpcnN0KGMpIHtcbiAgLy8gVXNlcyBhIHN1YnNldCBvZiBucy1jaGFyIC0gYy1pbmRpY2F0b3JcbiAgLy8gd2hlcmUgbnMtY2hhciA9IG5iLWNoYXIgLSBzLXdoaXRlLlxuICByZXR1cm4gaXNQcmludGFibGUoYykgJiYgYyAhPT0gMHhGRUZGXG4gICAgJiYgIWlzV2hpdGVzcGFjZShjKSAvLyAtIHMtd2hpdGVcbiAgICAvLyAtIChjLWluZGljYXRvciA6Oj1cbiAgICAvLyDigJwt4oCdIHwg4oCcP+KAnSB8IOKAnDrigJ0gfCDigJws4oCdIHwg4oCcW+KAnSB8IOKAnF3igJ0gfCDigJx74oCdIHwg4oCcfeKAnVxuICAgICYmIGMgIT09IENIQVJfTUlOVVNcbiAgICAmJiBjICE9PSBDSEFSX1FVRVNUSU9OXG4gICAgJiYgYyAhPT0gQ0hBUl9DT0xPTlxuICAgICYmIGMgIT09IENIQVJfQ09NTUFcbiAgICAmJiBjICE9PSBDSEFSX0xFRlRfU1FVQVJFX0JSQUNLRVRcbiAgICAmJiBjICE9PSBDSEFSX1JJR0hUX1NRVUFSRV9CUkFDS0VUXG4gICAgJiYgYyAhPT0gQ0hBUl9MRUZUX0NVUkxZX0JSQUNLRVRcbiAgICAmJiBjICE9PSBDSEFSX1JJR0hUX0NVUkxZX0JSQUNLRVRcbiAgICAvLyB8IOKAnCPigJ0gfCDigJwm4oCdIHwg4oCcKuKAnSB8IOKAnCHigJ0gfCDigJx84oCdIHwg4oCcPuKAnSB8IOKAnCfigJ0gfCDigJxcIuKAnVxuICAgICYmIGMgIT09IENIQVJfU0hBUlBcbiAgICAmJiBjICE9PSBDSEFSX0FNUEVSU0FORFxuICAgICYmIGMgIT09IENIQVJfQVNURVJJU0tcbiAgICAmJiBjICE9PSBDSEFSX0VYQ0xBTUFUSU9OXG4gICAgJiYgYyAhPT0gQ0hBUl9WRVJUSUNBTF9MSU5FXG4gICAgJiYgYyAhPT0gQ0hBUl9HUkVBVEVSX1RIQU5cbiAgICAmJiBjICE9PSBDSEFSX1NJTkdMRV9RVU9URVxuICAgICYmIGMgIT09IENIQVJfRE9VQkxFX1FVT1RFXG4gICAgLy8gfCDigJwl4oCdIHwg4oCcQOKAnSB8IOKAnGDigJ0pXG4gICAgJiYgYyAhPT0gQ0hBUl9QRVJDRU5UXG4gICAgJiYgYyAhPT0gQ0hBUl9DT01NRVJDSUFMX0FUXG4gICAgJiYgYyAhPT0gQ0hBUl9HUkFWRV9BQ0NFTlQ7XG59XG5cbnZhciBTVFlMRV9QTEFJTiAgID0gMSxcbiAgICBTVFlMRV9TSU5HTEUgID0gMixcbiAgICBTVFlMRV9MSVRFUkFMID0gMyxcbiAgICBTVFlMRV9GT0xERUQgID0gNCxcbiAgICBTVFlMRV9ET1VCTEUgID0gNTtcblxuLy8gRGV0ZXJtaW5lcyB3aGljaCBzY2FsYXIgc3R5bGVzIGFyZSBwb3NzaWJsZSBhbmQgcmV0dXJucyB0aGUgcHJlZmVycmVkIHN0eWxlLlxuLy8gbGluZVdpZHRoID0gLTEgPT4gbm8gbGltaXQuXG4vLyBQcmUtY29uZGl0aW9uczogc3RyLmxlbmd0aCA+IDAuXG4vLyBQb3N0LWNvbmRpdGlvbnM6XG4vLyAgICBTVFlMRV9QTEFJTiBvciBTVFlMRV9TSU5HTEUgPT4gbm8gXFxuIGFyZSBpbiB0aGUgc3RyaW5nLlxuLy8gICAgU1RZTEVfTElURVJBTCA9PiBubyBsaW5lcyBhcmUgc3VpdGFibGUgZm9yIGZvbGRpbmcgKG9yIGxpbmVXaWR0aCBpcyAtMSkuXG4vLyAgICBTVFlMRV9GT0xERUQgPT4gYSBsaW5lID4gbGluZVdpZHRoIGFuZCBjYW4gYmUgZm9sZGVkIChhbmQgbGluZVdpZHRoICE9IC0xKS5cbmZ1bmN0aW9uIGNob29zZVNjYWxhclN0eWxlKHN0cmluZywgc2luZ2xlTGluZU9ubHksIGluZGVudFBlckxldmVsLCBsaW5lV2lkdGgsIHRlc3RBbWJpZ3VvdXNUeXBlKSB7XG4gIHZhciBpO1xuICB2YXIgY2hhcjtcbiAgdmFyIGhhc0xpbmVCcmVhayA9IGZhbHNlO1xuICB2YXIgaGFzRm9sZGFibGVMaW5lID0gZmFsc2U7IC8vIG9ubHkgY2hlY2tlZCBpZiBzaG91bGRUcmFja1dpZHRoXG4gIHZhciBzaG91bGRUcmFja1dpZHRoID0gbGluZVdpZHRoICE9PSAtMTtcbiAgdmFyIHByZXZpb3VzTGluZUJyZWFrID0gLTE7IC8vIGNvdW50IHRoZSBmaXJzdCBsaW5lIGNvcnJlY3RseVxuICB2YXIgcGxhaW4gPSBpc1BsYWluU2FmZUZpcnN0KHN0cmluZy5jaGFyQ29kZUF0KDApKVxuICAgICAgICAgICYmICFpc1doaXRlc3BhY2Uoc3RyaW5nLmNoYXJDb2RlQXQoc3RyaW5nLmxlbmd0aCAtIDEpKTtcblxuICBpZiAoc2luZ2xlTGluZU9ubHkpIHtcbiAgICAvLyBDYXNlOiBubyBibG9jayBzdHlsZXMuXG4gICAgLy8gQ2hlY2sgZm9yIGRpc2FsbG93ZWQgY2hhcmFjdGVycyB0byBydWxlIG91dCBwbGFpbiBhbmQgc2luZ2xlLlxuICAgIGZvciAoaSA9IDA7IGkgPCBzdHJpbmcubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNoYXIgPSBzdHJpbmcuY2hhckNvZGVBdChpKTtcbiAgICAgIGlmICghaXNQcmludGFibGUoY2hhcikpIHtcbiAgICAgICAgcmV0dXJuIFNUWUxFX0RPVUJMRTtcbiAgICAgIH1cbiAgICAgIHBsYWluID0gcGxhaW4gJiYgaXNQbGFpblNhZmUoY2hhcik7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIENhc2U6IGJsb2NrIHN0eWxlcyBwZXJtaXR0ZWQuXG4gICAgZm9yIChpID0gMDsgaSA8IHN0cmluZy5sZW5ndGg7IGkrKykge1xuICAgICAgY2hhciA9IHN0cmluZy5jaGFyQ29kZUF0KGkpO1xuICAgICAgaWYgKGNoYXIgPT09IENIQVJfTElORV9GRUVEKSB7XG4gICAgICAgIGhhc0xpbmVCcmVhayA9IHRydWU7XG4gICAgICAgIC8vIENoZWNrIGlmIGFueSBsaW5lIGNhbiBiZSBmb2xkZWQuXG4gICAgICAgIGlmIChzaG91bGRUcmFja1dpZHRoKSB7XG4gICAgICAgICAgaGFzRm9sZGFibGVMaW5lID0gaGFzRm9sZGFibGVMaW5lIHx8XG4gICAgICAgICAgICAvLyBGb2xkYWJsZSBsaW5lID0gdG9vIGxvbmcsIGFuZCBub3QgbW9yZS1pbmRlbnRlZC5cbiAgICAgICAgICAgIChpIC0gcHJldmlvdXNMaW5lQnJlYWsgLSAxID4gbGluZVdpZHRoICYmXG4gICAgICAgICAgICAgc3RyaW5nW3ByZXZpb3VzTGluZUJyZWFrICsgMV0gIT09ICcgJyk7XG4gICAgICAgICAgcHJldmlvdXNMaW5lQnJlYWsgPSBpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKCFpc1ByaW50YWJsZShjaGFyKSkge1xuICAgICAgICByZXR1cm4gU1RZTEVfRE9VQkxFO1xuICAgICAgfVxuICAgICAgcGxhaW4gPSBwbGFpbiAmJiBpc1BsYWluU2FmZShjaGFyKTtcbiAgICB9XG4gICAgLy8gaW4gY2FzZSB0aGUgZW5kIGlzIG1pc3NpbmcgYSBcXG5cbiAgICBoYXNGb2xkYWJsZUxpbmUgPSBoYXNGb2xkYWJsZUxpbmUgfHwgKHNob3VsZFRyYWNrV2lkdGggJiZcbiAgICAgIChpIC0gcHJldmlvdXNMaW5lQnJlYWsgLSAxID4gbGluZVdpZHRoICYmXG4gICAgICAgc3RyaW5nW3ByZXZpb3VzTGluZUJyZWFrICsgMV0gIT09ICcgJykpO1xuICB9XG4gIC8vIEFsdGhvdWdoIGV2ZXJ5IHN0eWxlIGNhbiByZXByZXNlbnQgXFxuIHdpdGhvdXQgZXNjYXBpbmcsIHByZWZlciBibG9jayBzdHlsZXNcbiAgLy8gZm9yIG11bHRpbGluZSwgc2luY2UgdGhleSdyZSBtb3JlIHJlYWRhYmxlIGFuZCB0aGV5IGRvbid0IGFkZCBlbXB0eSBsaW5lcy5cbiAgLy8gQWxzbyBwcmVmZXIgZm9sZGluZyBhIHN1cGVyLWxvbmcgbGluZS5cbiAgaWYgKCFoYXNMaW5lQnJlYWsgJiYgIWhhc0ZvbGRhYmxlTGluZSkge1xuICAgIC8vIFN0cmluZ3MgaW50ZXJwcmV0YWJsZSBhcyBhbm90aGVyIHR5cGUgaGF2ZSB0byBiZSBxdW90ZWQ7XG4gICAgLy8gZS5nLiB0aGUgc3RyaW5nICd0cnVlJyB2cy4gdGhlIGJvb2xlYW4gdHJ1ZS5cbiAgICByZXR1cm4gcGxhaW4gJiYgIXRlc3RBbWJpZ3VvdXNUeXBlKHN0cmluZylcbiAgICAgID8gU1RZTEVfUExBSU4gOiBTVFlMRV9TSU5HTEU7XG4gIH1cbiAgLy8gRWRnZSBjYXNlOiBibG9jayBpbmRlbnRhdGlvbiBpbmRpY2F0b3IgY2FuIG9ubHkgaGF2ZSBvbmUgZGlnaXQuXG4gIGlmIChzdHJpbmdbMF0gPT09ICcgJyAmJiBpbmRlbnRQZXJMZXZlbCA+IDkpIHtcbiAgICByZXR1cm4gU1RZTEVfRE9VQkxFO1xuICB9XG4gIC8vIEF0IHRoaXMgcG9pbnQgd2Uga25vdyBibG9jayBzdHlsZXMgYXJlIHZhbGlkLlxuICAvLyBQcmVmZXIgbGl0ZXJhbCBzdHlsZSB1bmxlc3Mgd2Ugd2FudCB0byBmb2xkLlxuICByZXR1cm4gaGFzRm9sZGFibGVMaW5lID8gU1RZTEVfRk9MREVEIDogU1RZTEVfTElURVJBTDtcbn1cblxuLy8gTm90ZTogbGluZSBicmVha2luZy9mb2xkaW5nIGlzIGltcGxlbWVudGVkIGZvciBvbmx5IHRoZSBmb2xkZWQgc3R5bGUuXG4vLyBOQi4gV2UgZHJvcCB0aGUgbGFzdCB0cmFpbGluZyBuZXdsaW5lIChpZiBhbnkpIG9mIGEgcmV0dXJuZWQgYmxvY2sgc2NhbGFyXG4vLyAgc2luY2UgdGhlIGR1bXBlciBhZGRzIGl0cyBvd24gbmV3bGluZS4gVGhpcyBhbHdheXMgd29ya3M6XG4vLyAgICDigKIgTm8gZW5kaW5nIG5ld2xpbmUgPT4gdW5hZmZlY3RlZDsgYWxyZWFkeSB1c2luZyBzdHJpcCBcIi1cIiBjaG9tcGluZy5cbi8vICAgIOKAoiBFbmRpbmcgbmV3bGluZSAgICA9PiByZW1vdmVkIHRoZW4gcmVzdG9yZWQuXG4vLyAgSW1wb3J0YW50bHksIHRoaXMga2VlcHMgdGhlIFwiK1wiIGNob21wIGluZGljYXRvciBmcm9tIGdhaW5pbmcgYW4gZXh0cmEgbGluZS5cbmZ1bmN0aW9uIHdyaXRlU2NhbGFyKHN0YXRlLCBzdHJpbmcsIGxldmVsLCBpc2tleSkge1xuICBzdGF0ZS5kdW1wID0gKGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoc3RyaW5nLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIFwiJydcIjtcbiAgICB9XG4gICAgaWYgKCFzdGF0ZS5ub0NvbXBhdE1vZGUgJiZcbiAgICAgICAgREVQUkVDQVRFRF9CT09MRUFOU19TWU5UQVguaW5kZXhPZihzdHJpbmcpICE9PSAtMSkge1xuICAgICAgcmV0dXJuIFwiJ1wiICsgc3RyaW5nICsgXCInXCI7XG4gICAgfVxuXG4gICAgdmFyIGluZGVudCA9IHN0YXRlLmluZGVudCAqIE1hdGgubWF4KDEsIGxldmVsKTsgLy8gbm8gMC1pbmRlbnQgc2NhbGFyc1xuICAgIC8vIEFzIGluZGVudGF0aW9uIGdldHMgZGVlcGVyLCBsZXQgdGhlIHdpZHRoIGRlY3JlYXNlIG1vbm90b25pY2FsbHlcbiAgICAvLyB0byB0aGUgbG93ZXIgYm91bmQgbWluKHN0YXRlLmxpbmVXaWR0aCwgNDApLlxuICAgIC8vIE5vdGUgdGhhdCB0aGlzIGltcGxpZXNcbiAgICAvLyAgc3RhdGUubGluZVdpZHRoIOKJpCA0MCArIHN0YXRlLmluZGVudDogd2lkdGggaXMgZml4ZWQgYXQgdGhlIGxvd2VyIGJvdW5kLlxuICAgIC8vICBzdGF0ZS5saW5lV2lkdGggPiA0MCArIHN0YXRlLmluZGVudDogd2lkdGggZGVjcmVhc2VzIHVudGlsIHRoZSBsb3dlciBib3VuZC5cbiAgICAvLyBUaGlzIGJlaGF2ZXMgYmV0dGVyIHRoYW4gYSBjb25zdGFudCBtaW5pbXVtIHdpZHRoIHdoaWNoIGRpc2FsbG93cyBuYXJyb3dlciBvcHRpb25zLFxuICAgIC8vIG9yIGFuIGluZGVudCB0aHJlc2hvbGQgd2hpY2ggY2F1c2VzIHRoZSB3aWR0aCB0byBzdWRkZW5seSBpbmNyZWFzZS5cbiAgICB2YXIgbGluZVdpZHRoID0gc3RhdGUubGluZVdpZHRoID09PSAtMVxuICAgICAgPyAtMSA6IE1hdGgubWF4KE1hdGgubWluKHN0YXRlLmxpbmVXaWR0aCwgNDApLCBzdGF0ZS5saW5lV2lkdGggLSBpbmRlbnQpO1xuXG4gICAgLy8gV2l0aG91dCBrbm93aW5nIGlmIGtleXMgYXJlIGltcGxpY2l0L2V4cGxpY2l0LCBhc3N1bWUgaW1wbGljaXQgZm9yIHNhZmV0eS5cbiAgICB2YXIgc2luZ2xlTGluZU9ubHkgPSBpc2tleVxuICAgICAgLy8gTm8gYmxvY2sgc3R5bGVzIGluIGZsb3cgbW9kZS5cbiAgICAgIHx8IChzdGF0ZS5mbG93TGV2ZWwgPiAtMSAmJiBsZXZlbCA+PSBzdGF0ZS5mbG93TGV2ZWwpO1xuICAgIGZ1bmN0aW9uIHRlc3RBbWJpZ3VpdHkoc3RyaW5nKSB7XG4gICAgICByZXR1cm4gdGVzdEltcGxpY2l0UmVzb2x2aW5nKHN0YXRlLCBzdHJpbmcpO1xuICAgIH1cblxuICAgIHN3aXRjaCAoY2hvb3NlU2NhbGFyU3R5bGUoc3RyaW5nLCBzaW5nbGVMaW5lT25seSwgc3RhdGUuaW5kZW50LCBsaW5lV2lkdGgsIHRlc3RBbWJpZ3VpdHkpKSB7XG4gICAgICBjYXNlIFNUWUxFX1BMQUlOOlxuICAgICAgICByZXR1cm4gc3RyaW5nO1xuICAgICAgY2FzZSBTVFlMRV9TSU5HTEU6XG4gICAgICAgIHJldHVybiBcIidcIiArIHN0cmluZy5yZXBsYWNlKC8nL2csIFwiJydcIikgKyBcIidcIjtcbiAgICAgIGNhc2UgU1RZTEVfTElURVJBTDpcbiAgICAgICAgcmV0dXJuICd8JyArIGJsb2NrSGVhZGVyKHN0cmluZywgc3RhdGUuaW5kZW50KVxuICAgICAgICAgICsgZHJvcEVuZGluZ05ld2xpbmUoaW5kZW50U3RyaW5nKHN0cmluZywgaW5kZW50KSk7XG4gICAgICBjYXNlIFNUWUxFX0ZPTERFRDpcbiAgICAgICAgcmV0dXJuICc+JyArIGJsb2NrSGVhZGVyKHN0cmluZywgc3RhdGUuaW5kZW50KVxuICAgICAgICAgICsgZHJvcEVuZGluZ05ld2xpbmUoaW5kZW50U3RyaW5nKGZvbGRTdHJpbmcoc3RyaW5nLCBsaW5lV2lkdGgpLCBpbmRlbnQpKTtcbiAgICAgIGNhc2UgU1RZTEVfRE9VQkxFOlxuICAgICAgICByZXR1cm4gJ1wiJyArIGVzY2FwZVN0cmluZyhzdHJpbmcsIGxpbmVXaWR0aCkgKyAnXCInO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ2ltcG9zc2libGUgZXJyb3I6IGludmFsaWQgc2NhbGFyIHN0eWxlJyk7XG4gICAgfVxuICB9KCkpO1xufVxuXG4vLyBQcmUtY29uZGl0aW9uczogc3RyaW5nIGlzIHZhbGlkIGZvciBhIGJsb2NrIHNjYWxhciwgMSA8PSBpbmRlbnRQZXJMZXZlbCA8PSA5LlxuZnVuY3Rpb24gYmxvY2tIZWFkZXIoc3RyaW5nLCBpbmRlbnRQZXJMZXZlbCkge1xuICB2YXIgaW5kZW50SW5kaWNhdG9yID0gKHN0cmluZ1swXSA9PT0gJyAnKSA/IFN0cmluZyhpbmRlbnRQZXJMZXZlbCkgOiAnJztcblxuICAvLyBub3RlIHRoZSBzcGVjaWFsIGNhc2U6IHRoZSBzdHJpbmcgJ1xcbicgY291bnRzIGFzIGEgXCJ0cmFpbGluZ1wiIGVtcHR5IGxpbmUuXG4gIHZhciBjbGlwID0gICAgICAgICAgc3RyaW5nW3N0cmluZy5sZW5ndGggLSAxXSA9PT0gJ1xcbic7XG4gIHZhciBrZWVwID0gY2xpcCAmJiAoc3RyaW5nW3N0cmluZy5sZW5ndGggLSAyXSA9PT0gJ1xcbicgfHwgc3RyaW5nID09PSAnXFxuJyk7XG4gIHZhciBjaG9tcCA9IGtlZXAgPyAnKycgOiAoY2xpcCA/ICcnIDogJy0nKTtcblxuICByZXR1cm4gaW5kZW50SW5kaWNhdG9yICsgY2hvbXAgKyAnXFxuJztcbn1cblxuLy8gKFNlZSB0aGUgbm90ZSBmb3Igd3JpdGVTY2FsYXIuKVxuZnVuY3Rpb24gZHJvcEVuZGluZ05ld2xpbmUoc3RyaW5nKSB7XG4gIHJldHVybiBzdHJpbmdbc3RyaW5nLmxlbmd0aCAtIDFdID09PSAnXFxuJyA/IHN0cmluZy5zbGljZSgwLCAtMSkgOiBzdHJpbmc7XG59XG5cbi8vIE5vdGU6IGEgbG9uZyBsaW5lIHdpdGhvdXQgYSBzdWl0YWJsZSBicmVhayBwb2ludCB3aWxsIGV4Y2VlZCB0aGUgd2lkdGggbGltaXQuXG4vLyBQcmUtY29uZGl0aW9uczogZXZlcnkgY2hhciBpbiBzdHIgaXNQcmludGFibGUsIHN0ci5sZW5ndGggPiAwLCB3aWR0aCA+IDAuXG5mdW5jdGlvbiBmb2xkU3RyaW5nKHN0cmluZywgd2lkdGgpIHtcbiAgLy8gSW4gZm9sZGVkIHN0eWxlLCAkayQgY29uc2VjdXRpdmUgbmV3bGluZXMgb3V0cHV0IGFzICRrKzEkIG5ld2xpbmVz4oCUXG4gIC8vIHVubGVzcyB0aGV5J3JlIGJlZm9yZSBvciBhZnRlciBhIG1vcmUtaW5kZW50ZWQgbGluZSwgb3IgYXQgdGhlIHZlcnlcbiAgLy8gYmVnaW5uaW5nIG9yIGVuZCwgaW4gd2hpY2ggY2FzZSAkayQgbWFwcyB0byAkayQuXG4gIC8vIFRoZXJlZm9yZSwgcGFyc2UgZWFjaCBjaHVuayBhcyBuZXdsaW5lKHMpIGZvbGxvd2VkIGJ5IGEgY29udGVudCBsaW5lLlxuICB2YXIgbGluZVJlID0gLyhcXG4rKShbXlxcbl0qKS9nO1xuXG4gIC8vIGZpcnN0IGxpbmUgKHBvc3NpYmx5IGFuIGVtcHR5IGxpbmUpXG4gIHZhciByZXN1bHQgPSAoZnVuY3Rpb24gKCkge1xuICAgIHZhciBuZXh0TEYgPSBzdHJpbmcuaW5kZXhPZignXFxuJyk7XG4gICAgbmV4dExGID0gbmV4dExGICE9PSAtMSA/IG5leHRMRiA6IHN0cmluZy5sZW5ndGg7XG4gICAgbGluZVJlLmxhc3RJbmRleCA9IG5leHRMRjtcbiAgICByZXR1cm4gZm9sZExpbmUoc3RyaW5nLnNsaWNlKDAsIG5leHRMRiksIHdpZHRoKTtcbiAgfSgpKTtcbiAgLy8gSWYgd2UgaGF2ZW4ndCByZWFjaGVkIHRoZSBmaXJzdCBjb250ZW50IGxpbmUgeWV0LCBkb24ndCBhZGQgYW4gZXh0cmEgXFxuLlxuICB2YXIgcHJldk1vcmVJbmRlbnRlZCA9IHN0cmluZ1swXSA9PT0gJ1xcbicgfHwgc3RyaW5nWzBdID09PSAnICc7XG4gIHZhciBtb3JlSW5kZW50ZWQ7XG5cbiAgLy8gcmVzdCBvZiB0aGUgbGluZXNcbiAgdmFyIG1hdGNoO1xuICB3aGlsZSAoKG1hdGNoID0gbGluZVJlLmV4ZWMoc3RyaW5nKSkpIHtcbiAgICB2YXIgcHJlZml4ID0gbWF0Y2hbMV0sIGxpbmUgPSBtYXRjaFsyXTtcbiAgICBtb3JlSW5kZW50ZWQgPSAobGluZVswXSA9PT0gJyAnKTtcbiAgICByZXN1bHQgKz0gcHJlZml4XG4gICAgICArICghcHJldk1vcmVJbmRlbnRlZCAmJiAhbW9yZUluZGVudGVkICYmIGxpbmUgIT09ICcnXG4gICAgICAgID8gJ1xcbicgOiAnJylcbiAgICAgICsgZm9sZExpbmUobGluZSwgd2lkdGgpO1xuICAgIHByZXZNb3JlSW5kZW50ZWQgPSBtb3JlSW5kZW50ZWQ7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vLyBHcmVlZHkgbGluZSBicmVha2luZy5cbi8vIFBpY2tzIHRoZSBsb25nZXN0IGxpbmUgdW5kZXIgdGhlIGxpbWl0IGVhY2ggdGltZSxcbi8vIG90aGVyd2lzZSBzZXR0bGVzIGZvciB0aGUgc2hvcnRlc3QgbGluZSBvdmVyIHRoZSBsaW1pdC5cbi8vIE5CLiBNb3JlLWluZGVudGVkIGxpbmVzICpjYW5ub3QqIGJlIGZvbGRlZCwgYXMgdGhhdCB3b3VsZCBhZGQgYW4gZXh0cmEgXFxuLlxuZnVuY3Rpb24gZm9sZExpbmUobGluZSwgd2lkdGgpIHtcbiAgaWYgKGxpbmUgPT09ICcnIHx8IGxpbmVbMF0gPT09ICcgJykgcmV0dXJuIGxpbmU7XG5cbiAgLy8gU2luY2UgYSBtb3JlLWluZGVudGVkIGxpbmUgYWRkcyBhIFxcbiwgYnJlYWtzIGNhbid0IGJlIGZvbGxvd2VkIGJ5IGEgc3BhY2UuXG4gIHZhciBicmVha1JlID0gLyBbXiBdL2c7IC8vIG5vdGU6IHRoZSBtYXRjaCBpbmRleCB3aWxsIGFsd2F5cyBiZSA8PSBsZW5ndGgtMi5cbiAgdmFyIG1hdGNoO1xuICAvLyBzdGFydCBpcyBhbiBpbmNsdXNpdmUgaW5kZXguIGVuZCwgY3VyciwgYW5kIG5leHQgYXJlIGV4Y2x1c2l2ZS5cbiAgdmFyIHN0YXJ0ID0gMCwgZW5kLCBjdXJyID0gMCwgbmV4dCA9IDA7XG4gIHZhciByZXN1bHQgPSAnJztcblxuICAvLyBJbnZhcmlhbnRzOiAwIDw9IHN0YXJ0IDw9IGxlbmd0aC0xLlxuICAvLyAgIDAgPD0gY3VyciA8PSBuZXh0IDw9IG1heCgwLCBsZW5ndGgtMikuIGN1cnIgLSBzdGFydCA8PSB3aWR0aC5cbiAgLy8gSW5zaWRlIHRoZSBsb29wOlxuICAvLyAgIEEgbWF0Y2ggaW1wbGllcyBsZW5ndGggPj0gMiwgc28gY3VyciBhbmQgbmV4dCBhcmUgPD0gbGVuZ3RoLTIuXG4gIHdoaWxlICgobWF0Y2ggPSBicmVha1JlLmV4ZWMobGluZSkpKSB7XG4gICAgbmV4dCA9IG1hdGNoLmluZGV4O1xuICAgIC8vIG1haW50YWluIGludmFyaWFudDogY3VyciAtIHN0YXJ0IDw9IHdpZHRoXG4gICAgaWYgKG5leHQgLSBzdGFydCA+IHdpZHRoKSB7XG4gICAgICBlbmQgPSAoY3VyciA+IHN0YXJ0KSA/IGN1cnIgOiBuZXh0OyAvLyBkZXJpdmUgZW5kIDw9IGxlbmd0aC0yXG4gICAgICByZXN1bHQgKz0gJ1xcbicgKyBsaW5lLnNsaWNlKHN0YXJ0LCBlbmQpO1xuICAgICAgLy8gc2tpcCB0aGUgc3BhY2UgdGhhdCB3YXMgb3V0cHV0IGFzIFxcblxuICAgICAgc3RhcnQgPSBlbmQgKyAxOyAgICAgICAgICAgICAgICAgICAgLy8gZGVyaXZlIHN0YXJ0IDw9IGxlbmd0aC0xXG4gICAgfVxuICAgIGN1cnIgPSBuZXh0O1xuICB9XG5cbiAgLy8gQnkgdGhlIGludmFyaWFudHMsIHN0YXJ0IDw9IGxlbmd0aC0xLCBzbyB0aGVyZSBpcyBzb21ldGhpbmcgbGVmdCBvdmVyLlxuICAvLyBJdCBpcyBlaXRoZXIgdGhlIHdob2xlIHN0cmluZyBvciBhIHBhcnQgc3RhcnRpbmcgZnJvbSBub24td2hpdGVzcGFjZS5cbiAgcmVzdWx0ICs9ICdcXG4nO1xuICAvLyBJbnNlcnQgYSBicmVhayBpZiB0aGUgcmVtYWluZGVyIGlzIHRvbyBsb25nIGFuZCB0aGVyZSBpcyBhIGJyZWFrIGF2YWlsYWJsZS5cbiAgaWYgKGxpbmUubGVuZ3RoIC0gc3RhcnQgPiB3aWR0aCAmJiBjdXJyID4gc3RhcnQpIHtcbiAgICByZXN1bHQgKz0gbGluZS5zbGljZShzdGFydCwgY3VycikgKyAnXFxuJyArIGxpbmUuc2xpY2UoY3VyciArIDEpO1xuICB9IGVsc2Uge1xuICAgIHJlc3VsdCArPSBsaW5lLnNsaWNlKHN0YXJ0KTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQuc2xpY2UoMSk7IC8vIGRyb3AgZXh0cmEgXFxuIGpvaW5lclxufVxuXG4vLyBFc2NhcGVzIGEgZG91YmxlLXF1b3RlZCBzdHJpbmcuXG5mdW5jdGlvbiBlc2NhcGVTdHJpbmcoc3RyaW5nKSB7XG4gIHZhciByZXN1bHQgPSAnJztcbiAgdmFyIGNoYXI7XG4gIHZhciBlc2NhcGVTZXE7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHJpbmcubGVuZ3RoOyBpKyspIHtcbiAgICBjaGFyID0gc3RyaW5nLmNoYXJDb2RlQXQoaSk7XG4gICAgZXNjYXBlU2VxID0gRVNDQVBFX1NFUVVFTkNFU1tjaGFyXTtcbiAgICByZXN1bHQgKz0gIWVzY2FwZVNlcSAmJiBpc1ByaW50YWJsZShjaGFyKVxuICAgICAgPyBzdHJpbmdbaV1cbiAgICAgIDogZXNjYXBlU2VxIHx8IGVuY29kZUhleChjaGFyKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIHdyaXRlRmxvd1NlcXVlbmNlKHN0YXRlLCBsZXZlbCwgb2JqZWN0KSB7XG4gIHZhciBfcmVzdWx0ID0gJycsXG4gICAgICBfdGFnICAgID0gc3RhdGUudGFnLFxuICAgICAgaW5kZXgsXG4gICAgICBsZW5ndGg7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IG9iamVjdC5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgLy8gV3JpdGUgb25seSB2YWxpZCBlbGVtZW50cy5cbiAgICBpZiAod3JpdGVOb2RlKHN0YXRlLCBsZXZlbCwgb2JqZWN0W2luZGV4XSwgZmFsc2UsIGZhbHNlKSkge1xuICAgICAgaWYgKGluZGV4ICE9PSAwKSBfcmVzdWx0ICs9ICcsICc7XG4gICAgICBfcmVzdWx0ICs9IHN0YXRlLmR1bXA7XG4gICAgfVxuICB9XG5cbiAgc3RhdGUudGFnID0gX3RhZztcbiAgc3RhdGUuZHVtcCA9ICdbJyArIF9yZXN1bHQgKyAnXSc7XG59XG5cbmZ1bmN0aW9uIHdyaXRlQmxvY2tTZXF1ZW5jZShzdGF0ZSwgbGV2ZWwsIG9iamVjdCwgY29tcGFjdCkge1xuICB2YXIgX3Jlc3VsdCA9ICcnLFxuICAgICAgX3RhZyAgICA9IHN0YXRlLnRhZyxcbiAgICAgIGluZGV4LFxuICAgICAgbGVuZ3RoO1xuXG4gIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIC8vIFdyaXRlIG9ubHkgdmFsaWQgZWxlbWVudHMuXG4gICAgaWYgKHdyaXRlTm9kZShzdGF0ZSwgbGV2ZWwgKyAxLCBvYmplY3RbaW5kZXhdLCB0cnVlLCB0cnVlKSkge1xuICAgICAgaWYgKCFjb21wYWN0IHx8IGluZGV4ICE9PSAwKSB7XG4gICAgICAgIF9yZXN1bHQgKz0gZ2VuZXJhdGVOZXh0TGluZShzdGF0ZSwgbGV2ZWwpO1xuICAgICAgfVxuICAgICAgX3Jlc3VsdCArPSAnLSAnICsgc3RhdGUuZHVtcDtcbiAgICB9XG4gIH1cblxuICBzdGF0ZS50YWcgPSBfdGFnO1xuICBzdGF0ZS5kdW1wID0gX3Jlc3VsdCB8fCAnW10nOyAvLyBFbXB0eSBzZXF1ZW5jZSBpZiBubyB2YWxpZCB2YWx1ZXMuXG59XG5cbmZ1bmN0aW9uIHdyaXRlRmxvd01hcHBpbmcoc3RhdGUsIGxldmVsLCBvYmplY3QpIHtcbiAgdmFyIF9yZXN1bHQgICAgICAgPSAnJyxcbiAgICAgIF90YWcgICAgICAgICAgPSBzdGF0ZS50YWcsXG4gICAgICBvYmplY3RLZXlMaXN0ID0gT2JqZWN0LmtleXMob2JqZWN0KSxcbiAgICAgIGluZGV4LFxuICAgICAgbGVuZ3RoLFxuICAgICAgb2JqZWN0S2V5LFxuICAgICAgb2JqZWN0VmFsdWUsXG4gICAgICBwYWlyQnVmZmVyO1xuXG4gIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3RLZXlMaXN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICBwYWlyQnVmZmVyID0gJyc7XG5cbiAgICBpZiAoaW5kZXggIT09IDApIHBhaXJCdWZmZXIgKz0gJywgJztcblxuICAgIG9iamVjdEtleSA9IG9iamVjdEtleUxpc3RbaW5kZXhdO1xuICAgIG9iamVjdFZhbHVlID0gb2JqZWN0W29iamVjdEtleV07XG5cbiAgICBpZiAoIXdyaXRlTm9kZShzdGF0ZSwgbGV2ZWwsIG9iamVjdEtleSwgZmFsc2UsIGZhbHNlKSkge1xuICAgICAgY29udGludWU7IC8vIFNraXAgdGhpcyBwYWlyIGJlY2F1c2Ugb2YgaW52YWxpZCBrZXk7XG4gICAgfVxuXG4gICAgaWYgKHN0YXRlLmR1bXAubGVuZ3RoID4gMTAyNCkgcGFpckJ1ZmZlciArPSAnPyAnO1xuXG4gICAgcGFpckJ1ZmZlciArPSBzdGF0ZS5kdW1wICsgJzogJztcblxuICAgIGlmICghd3JpdGVOb2RlKHN0YXRlLCBsZXZlbCwgb2JqZWN0VmFsdWUsIGZhbHNlLCBmYWxzZSkpIHtcbiAgICAgIGNvbnRpbnVlOyAvLyBTa2lwIHRoaXMgcGFpciBiZWNhdXNlIG9mIGludmFsaWQgdmFsdWUuXG4gICAgfVxuXG4gICAgcGFpckJ1ZmZlciArPSBzdGF0ZS5kdW1wO1xuXG4gICAgLy8gQm90aCBrZXkgYW5kIHZhbHVlIGFyZSB2YWxpZC5cbiAgICBfcmVzdWx0ICs9IHBhaXJCdWZmZXI7XG4gIH1cblxuICBzdGF0ZS50YWcgPSBfdGFnO1xuICBzdGF0ZS5kdW1wID0gJ3snICsgX3Jlc3VsdCArICd9Jztcbn1cblxuZnVuY3Rpb24gd3JpdGVCbG9ja01hcHBpbmcoc3RhdGUsIGxldmVsLCBvYmplY3QsIGNvbXBhY3QpIHtcbiAgdmFyIF9yZXN1bHQgICAgICAgPSAnJyxcbiAgICAgIF90YWcgICAgICAgICAgPSBzdGF0ZS50YWcsXG4gICAgICBvYmplY3RLZXlMaXN0ID0gT2JqZWN0LmtleXMob2JqZWN0KSxcbiAgICAgIGluZGV4LFxuICAgICAgbGVuZ3RoLFxuICAgICAgb2JqZWN0S2V5LFxuICAgICAgb2JqZWN0VmFsdWUsXG4gICAgICBleHBsaWNpdFBhaXIsXG4gICAgICBwYWlyQnVmZmVyO1xuXG4gIC8vIEFsbG93IHNvcnRpbmcga2V5cyBzbyB0aGF0IHRoZSBvdXRwdXQgZmlsZSBpcyBkZXRlcm1pbmlzdGljXG4gIGlmIChzdGF0ZS5zb3J0S2V5cyA9PT0gdHJ1ZSkge1xuICAgIC8vIERlZmF1bHQgc29ydGluZ1xuICAgIG9iamVjdEtleUxpc3Quc29ydCgpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBzdGF0ZS5zb3J0S2V5cyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIC8vIEN1c3RvbSBzb3J0IGZ1bmN0aW9uXG4gICAgb2JqZWN0S2V5TGlzdC5zb3J0KHN0YXRlLnNvcnRLZXlzKTtcbiAgfSBlbHNlIGlmIChzdGF0ZS5zb3J0S2V5cykge1xuICAgIC8vIFNvbWV0aGluZyBpcyB3cm9uZ1xuICAgIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdzb3J0S2V5cyBtdXN0IGJlIGEgYm9vbGVhbiBvciBhIGZ1bmN0aW9uJyk7XG4gIH1cblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gb2JqZWN0S2V5TGlzdC5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgcGFpckJ1ZmZlciA9ICcnO1xuXG4gICAgaWYgKCFjb21wYWN0IHx8IGluZGV4ICE9PSAwKSB7XG4gICAgICBwYWlyQnVmZmVyICs9IGdlbmVyYXRlTmV4dExpbmUoc3RhdGUsIGxldmVsKTtcbiAgICB9XG5cbiAgICBvYmplY3RLZXkgPSBvYmplY3RLZXlMaXN0W2luZGV4XTtcbiAgICBvYmplY3RWYWx1ZSA9IG9iamVjdFtvYmplY3RLZXldO1xuXG4gICAgaWYgKCF3cml0ZU5vZGUoc3RhdGUsIGxldmVsICsgMSwgb2JqZWN0S2V5LCB0cnVlLCB0cnVlLCB0cnVlKSkge1xuICAgICAgY29udGludWU7IC8vIFNraXAgdGhpcyBwYWlyIGJlY2F1c2Ugb2YgaW52YWxpZCBrZXkuXG4gICAgfVxuXG4gICAgZXhwbGljaXRQYWlyID0gKHN0YXRlLnRhZyAhPT0gbnVsbCAmJiBzdGF0ZS50YWcgIT09ICc/JykgfHxcbiAgICAgICAgICAgICAgICAgICAoc3RhdGUuZHVtcCAmJiBzdGF0ZS5kdW1wLmxlbmd0aCA+IDEwMjQpO1xuXG4gICAgaWYgKGV4cGxpY2l0UGFpcikge1xuICAgICAgaWYgKHN0YXRlLmR1bXAgJiYgQ0hBUl9MSU5FX0ZFRUQgPT09IHN0YXRlLmR1bXAuY2hhckNvZGVBdCgwKSkge1xuICAgICAgICBwYWlyQnVmZmVyICs9ICc/JztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBhaXJCdWZmZXIgKz0gJz8gJztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBwYWlyQnVmZmVyICs9IHN0YXRlLmR1bXA7XG5cbiAgICBpZiAoZXhwbGljaXRQYWlyKSB7XG4gICAgICBwYWlyQnVmZmVyICs9IGdlbmVyYXRlTmV4dExpbmUoc3RhdGUsIGxldmVsKTtcbiAgICB9XG5cbiAgICBpZiAoIXdyaXRlTm9kZShzdGF0ZSwgbGV2ZWwgKyAxLCBvYmplY3RWYWx1ZSwgdHJ1ZSwgZXhwbGljaXRQYWlyKSkge1xuICAgICAgY29udGludWU7IC8vIFNraXAgdGhpcyBwYWlyIGJlY2F1c2Ugb2YgaW52YWxpZCB2YWx1ZS5cbiAgICB9XG5cbiAgICBpZiAoc3RhdGUuZHVtcCAmJiBDSEFSX0xJTkVfRkVFRCA9PT0gc3RhdGUuZHVtcC5jaGFyQ29kZUF0KDApKSB7XG4gICAgICBwYWlyQnVmZmVyICs9ICc6JztcbiAgICB9IGVsc2Uge1xuICAgICAgcGFpckJ1ZmZlciArPSAnOiAnO1xuICAgIH1cblxuICAgIHBhaXJCdWZmZXIgKz0gc3RhdGUuZHVtcDtcblxuICAgIC8vIEJvdGgga2V5IGFuZCB2YWx1ZSBhcmUgdmFsaWQuXG4gICAgX3Jlc3VsdCArPSBwYWlyQnVmZmVyO1xuICB9XG5cbiAgc3RhdGUudGFnID0gX3RhZztcbiAgc3RhdGUuZHVtcCA9IF9yZXN1bHQgfHwgJ3t9JzsgLy8gRW1wdHkgbWFwcGluZyBpZiBubyB2YWxpZCBwYWlycy5cbn1cblxuZnVuY3Rpb24gZGV0ZWN0VHlwZShzdGF0ZSwgb2JqZWN0LCBleHBsaWNpdCkge1xuICB2YXIgX3Jlc3VsdCwgdHlwZUxpc3QsIGluZGV4LCBsZW5ndGgsIHR5cGUsIHN0eWxlO1xuXG4gIHR5cGVMaXN0ID0gZXhwbGljaXQgPyBzdGF0ZS5leHBsaWNpdFR5cGVzIDogc3RhdGUuaW1wbGljaXRUeXBlcztcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gdHlwZUxpc3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIHR5cGUgPSB0eXBlTGlzdFtpbmRleF07XG5cbiAgICBpZiAoKHR5cGUuaW5zdGFuY2VPZiAgfHwgdHlwZS5wcmVkaWNhdGUpICYmXG4gICAgICAgICghdHlwZS5pbnN0YW5jZU9mIHx8ICgodHlwZW9mIG9iamVjdCA9PT0gJ29iamVjdCcpICYmIChvYmplY3QgaW5zdGFuY2VvZiB0eXBlLmluc3RhbmNlT2YpKSkgJiZcbiAgICAgICAgKCF0eXBlLnByZWRpY2F0ZSAgfHwgdHlwZS5wcmVkaWNhdGUob2JqZWN0KSkpIHtcblxuICAgICAgc3RhdGUudGFnID0gZXhwbGljaXQgPyB0eXBlLnRhZyA6ICc/JztcblxuICAgICAgaWYgKHR5cGUucmVwcmVzZW50KSB7XG4gICAgICAgIHN0eWxlID0gc3RhdGUuc3R5bGVNYXBbdHlwZS50YWddIHx8IHR5cGUuZGVmYXVsdFN0eWxlO1xuXG4gICAgICAgIGlmIChfdG9TdHJpbmcuY2FsbCh0eXBlLnJlcHJlc2VudCkgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXScpIHtcbiAgICAgICAgICBfcmVzdWx0ID0gdHlwZS5yZXByZXNlbnQob2JqZWN0LCBzdHlsZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoX2hhc093blByb3BlcnR5LmNhbGwodHlwZS5yZXByZXNlbnQsIHN0eWxlKSkge1xuICAgICAgICAgIF9yZXN1bHQgPSB0eXBlLnJlcHJlc2VudFtzdHlsZV0ob2JqZWN0LCBzdHlsZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJyE8JyArIHR5cGUudGFnICsgJz4gdGFnIHJlc29sdmVyIGFjY2VwdHMgbm90IFwiJyArIHN0eWxlICsgJ1wiIHN0eWxlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBzdGF0ZS5kdW1wID0gX3Jlc3VsdDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vLyBTZXJpYWxpemVzIGBvYmplY3RgIGFuZCB3cml0ZXMgaXQgdG8gZ2xvYmFsIGByZXN1bHRgLlxuLy8gUmV0dXJucyB0cnVlIG9uIHN1Y2Nlc3MsIG9yIGZhbHNlIG9uIGludmFsaWQgb2JqZWN0LlxuLy9cbmZ1bmN0aW9uIHdyaXRlTm9kZShzdGF0ZSwgbGV2ZWwsIG9iamVjdCwgYmxvY2ssIGNvbXBhY3QsIGlza2V5KSB7XG4gIHN0YXRlLnRhZyA9IG51bGw7XG4gIHN0YXRlLmR1bXAgPSBvYmplY3Q7XG5cbiAgaWYgKCFkZXRlY3RUeXBlKHN0YXRlLCBvYmplY3QsIGZhbHNlKSkge1xuICAgIGRldGVjdFR5cGUoc3RhdGUsIG9iamVjdCwgdHJ1ZSk7XG4gIH1cblxuICB2YXIgdHlwZSA9IF90b1N0cmluZy5jYWxsKHN0YXRlLmR1bXApO1xuXG4gIGlmIChibG9jaykge1xuICAgIGJsb2NrID0gKHN0YXRlLmZsb3dMZXZlbCA8IDAgfHwgc3RhdGUuZmxvd0xldmVsID4gbGV2ZWwpO1xuICB9XG5cbiAgdmFyIG9iamVjdE9yQXJyYXkgPSB0eXBlID09PSAnW29iamVjdCBPYmplY3RdJyB8fCB0eXBlID09PSAnW29iamVjdCBBcnJheV0nLFxuICAgICAgZHVwbGljYXRlSW5kZXgsXG4gICAgICBkdXBsaWNhdGU7XG5cbiAgaWYgKG9iamVjdE9yQXJyYXkpIHtcbiAgICBkdXBsaWNhdGVJbmRleCA9IHN0YXRlLmR1cGxpY2F0ZXMuaW5kZXhPZihvYmplY3QpO1xuICAgIGR1cGxpY2F0ZSA9IGR1cGxpY2F0ZUluZGV4ICE9PSAtMTtcbiAgfVxuXG4gIGlmICgoc3RhdGUudGFnICE9PSBudWxsICYmIHN0YXRlLnRhZyAhPT0gJz8nKSB8fCBkdXBsaWNhdGUgfHwgKHN0YXRlLmluZGVudCAhPT0gMiAmJiBsZXZlbCA+IDApKSB7XG4gICAgY29tcGFjdCA9IGZhbHNlO1xuICB9XG5cbiAgaWYgKGR1cGxpY2F0ZSAmJiBzdGF0ZS51c2VkRHVwbGljYXRlc1tkdXBsaWNhdGVJbmRleF0pIHtcbiAgICBzdGF0ZS5kdW1wID0gJypyZWZfJyArIGR1cGxpY2F0ZUluZGV4O1xuICB9IGVsc2Uge1xuICAgIGlmIChvYmplY3RPckFycmF5ICYmIGR1cGxpY2F0ZSAmJiAhc3RhdGUudXNlZER1cGxpY2F0ZXNbZHVwbGljYXRlSW5kZXhdKSB7XG4gICAgICBzdGF0ZS51c2VkRHVwbGljYXRlc1tkdXBsaWNhdGVJbmRleF0gPSB0cnVlO1xuICAgIH1cbiAgICBpZiAodHlwZSA9PT0gJ1tvYmplY3QgT2JqZWN0XScpIHtcbiAgICAgIGlmIChibG9jayAmJiAoT2JqZWN0LmtleXMoc3RhdGUuZHVtcCkubGVuZ3RoICE9PSAwKSkge1xuICAgICAgICB3cml0ZUJsb2NrTWFwcGluZyhzdGF0ZSwgbGV2ZWwsIHN0YXRlLmR1bXAsIGNvbXBhY3QpO1xuICAgICAgICBpZiAoZHVwbGljYXRlKSB7XG4gICAgICAgICAgc3RhdGUuZHVtcCA9ICcmcmVmXycgKyBkdXBsaWNhdGVJbmRleCArIHN0YXRlLmR1bXA7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHdyaXRlRmxvd01hcHBpbmcoc3RhdGUsIGxldmVsLCBzdGF0ZS5kdW1wKTtcbiAgICAgICAgaWYgKGR1cGxpY2F0ZSkge1xuICAgICAgICAgIHN0YXRlLmR1bXAgPSAnJnJlZl8nICsgZHVwbGljYXRlSW5kZXggKyAnICcgKyBzdGF0ZS5kdW1wO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnW29iamVjdCBBcnJheV0nKSB7XG4gICAgICBpZiAoYmxvY2sgJiYgKHN0YXRlLmR1bXAubGVuZ3RoICE9PSAwKSkge1xuICAgICAgICB3cml0ZUJsb2NrU2VxdWVuY2Uoc3RhdGUsIGxldmVsLCBzdGF0ZS5kdW1wLCBjb21wYWN0KTtcbiAgICAgICAgaWYgKGR1cGxpY2F0ZSkge1xuICAgICAgICAgIHN0YXRlLmR1bXAgPSAnJnJlZl8nICsgZHVwbGljYXRlSW5kZXggKyBzdGF0ZS5kdW1wO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB3cml0ZUZsb3dTZXF1ZW5jZShzdGF0ZSwgbGV2ZWwsIHN0YXRlLmR1bXApO1xuICAgICAgICBpZiAoZHVwbGljYXRlKSB7XG4gICAgICAgICAgc3RhdGUuZHVtcCA9ICcmcmVmXycgKyBkdXBsaWNhdGVJbmRleCArICcgJyArIHN0YXRlLmR1bXA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdbb2JqZWN0IFN0cmluZ10nKSB7XG4gICAgICBpZiAoc3RhdGUudGFnICE9PSAnPycpIHtcbiAgICAgICAgd3JpdGVTY2FsYXIoc3RhdGUsIHN0YXRlLmR1bXAsIGxldmVsLCBpc2tleSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChzdGF0ZS5za2lwSW52YWxpZCkgcmV0dXJuIGZhbHNlO1xuICAgICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ3VuYWNjZXB0YWJsZSBraW5kIG9mIGFuIG9iamVjdCB0byBkdW1wICcgKyB0eXBlKTtcbiAgICB9XG5cbiAgICBpZiAoc3RhdGUudGFnICE9PSBudWxsICYmIHN0YXRlLnRhZyAhPT0gJz8nKSB7XG4gICAgICBzdGF0ZS5kdW1wID0gJyE8JyArIHN0YXRlLnRhZyArICc+ICcgKyBzdGF0ZS5kdW1wO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBnZXREdXBsaWNhdGVSZWZlcmVuY2VzKG9iamVjdCwgc3RhdGUpIHtcbiAgdmFyIG9iamVjdHMgPSBbXSxcbiAgICAgIGR1cGxpY2F0ZXNJbmRleGVzID0gW10sXG4gICAgICBpbmRleCxcbiAgICAgIGxlbmd0aDtcblxuICBpbnNwZWN0Tm9kZShvYmplY3QsIG9iamVjdHMsIGR1cGxpY2F0ZXNJbmRleGVzKTtcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gZHVwbGljYXRlc0luZGV4ZXMubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIHN0YXRlLmR1cGxpY2F0ZXMucHVzaChvYmplY3RzW2R1cGxpY2F0ZXNJbmRleGVzW2luZGV4XV0pO1xuICB9XG4gIHN0YXRlLnVzZWREdXBsaWNhdGVzID0gbmV3IEFycmF5KGxlbmd0aCk7XG59XG5cbmZ1bmN0aW9uIGluc3BlY3ROb2RlKG9iamVjdCwgb2JqZWN0cywgZHVwbGljYXRlc0luZGV4ZXMpIHtcbiAgdmFyIG9iamVjdEtleUxpc3QsXG4gICAgICBpbmRleCxcbiAgICAgIGxlbmd0aDtcblxuICBpZiAob2JqZWN0ICE9PSBudWxsICYmIHR5cGVvZiBvYmplY3QgPT09ICdvYmplY3QnKSB7XG4gICAgaW5kZXggPSBvYmplY3RzLmluZGV4T2Yob2JqZWN0KTtcbiAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICBpZiAoZHVwbGljYXRlc0luZGV4ZXMuaW5kZXhPZihpbmRleCkgPT09IC0xKSB7XG4gICAgICAgIGR1cGxpY2F0ZXNJbmRleGVzLnB1c2goaW5kZXgpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBvYmplY3RzLnB1c2gob2JqZWN0KTtcblxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkob2JqZWN0KSkge1xuICAgICAgICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gb2JqZWN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICAgICAgICBpbnNwZWN0Tm9kZShvYmplY3RbaW5kZXhdLCBvYmplY3RzLCBkdXBsaWNhdGVzSW5kZXhlcyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9iamVjdEtleUxpc3QgPSBPYmplY3Qua2V5cyhvYmplY3QpO1xuXG4gICAgICAgIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3RLZXlMaXN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICAgICAgICBpbnNwZWN0Tm9kZShvYmplY3Rbb2JqZWN0S2V5TGlzdFtpbmRleF1dLCBvYmplY3RzLCBkdXBsaWNhdGVzSW5kZXhlcyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZHVtcChpbnB1dCwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgc3RhdGUgPSBuZXcgU3RhdGUob3B0aW9ucyk7XG5cbiAgaWYgKCFzdGF0ZS5ub1JlZnMpIGdldER1cGxpY2F0ZVJlZmVyZW5jZXMoaW5wdXQsIHN0YXRlKTtcblxuICBpZiAod3JpdGVOb2RlKHN0YXRlLCAwLCBpbnB1dCwgdHJ1ZSwgdHJ1ZSkpIHJldHVybiBzdGF0ZS5kdW1wICsgJ1xcbic7XG5cbiAgcmV0dXJuICcnO1xufVxuXG5mdW5jdGlvbiBzYWZlRHVtcChpbnB1dCwgb3B0aW9ucykge1xuICByZXR1cm4gZHVtcChpbnB1dCwgY29tbW9uLmV4dGVuZCh7IHNjaGVtYTogREVGQVVMVF9TQUZFX1NDSEVNQSB9LCBvcHRpb25zKSk7XG59XG5cbm1vZHVsZS5leHBvcnRzLmR1bXAgICAgID0gZHVtcDtcbm1vZHVsZS5leHBvcnRzLnNhZmVEdW1wID0gc2FmZUR1bXA7XG4iLCIvLyBZQU1MIGVycm9yIGNsYXNzLiBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzg0NTg5ODRcbi8vXG4ndXNlIHN0cmljdCc7XG5cbmZ1bmN0aW9uIFlBTUxFeGNlcHRpb24ocmVhc29uLCBtYXJrKSB7XG4gIC8vIFN1cGVyIGNvbnN0cnVjdG9yXG4gIEVycm9yLmNhbGwodGhpcyk7XG5cbiAgLy8gSW5jbHVkZSBzdGFjayB0cmFjZSBpbiBlcnJvciBvYmplY3RcbiAgaWYgKEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKSB7XG4gICAgLy8gQ2hyb21lIGFuZCBOb2RlSlNcbiAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCB0aGlzLmNvbnN0cnVjdG9yKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBGRiwgSUUgMTArIGFuZCBTYWZhcmkgNisuIEZhbGxiYWNrIGZvciBvdGhlcnNcbiAgICB0aGlzLnN0YWNrID0gKG5ldyBFcnJvcigpKS5zdGFjayB8fCAnJztcbiAgfVxuXG4gIHRoaXMubmFtZSA9ICdZQU1MRXhjZXB0aW9uJztcbiAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gIHRoaXMubWFyayA9IG1hcms7XG4gIHRoaXMubWVzc2FnZSA9ICh0aGlzLnJlYXNvbiB8fCAnKHVua25vd24gcmVhc29uKScpICsgKHRoaXMubWFyayA/ICcgJyArIHRoaXMubWFyay50b1N0cmluZygpIDogJycpO1xufVxuXG5cbi8vIEluaGVyaXQgZnJvbSBFcnJvclxuWUFNTEV4Y2VwdGlvbi5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEVycm9yLnByb3RvdHlwZSk7XG5ZQU1MRXhjZXB0aW9uLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFlBTUxFeGNlcHRpb247XG5cblxuWUFNTEV4Y2VwdGlvbi5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZyhjb21wYWN0KSB7XG4gIHZhciByZXN1bHQgPSB0aGlzLm5hbWUgKyAnOiAnO1xuXG4gIHJlc3VsdCArPSB0aGlzLnJlYXNvbiB8fCAnKHVua25vd24gcmVhc29uKSc7XG5cbiAgaWYgKCFjb21wYWN0ICYmIHRoaXMubWFyaykge1xuICAgIHJlc3VsdCArPSAnICcgKyB0aGlzLm1hcmsudG9TdHJpbmcoKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gWUFNTEV4Y2VwdGlvbjtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyplc2xpbnQtZGlzYWJsZSBtYXgtbGVuLG5vLXVzZS1iZWZvcmUtZGVmaW5lKi9cblxudmFyIGNvbW1vbiAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIFlBTUxFeGNlcHRpb24gICAgICAgPSByZXF1aXJlKCcuL2V4Y2VwdGlvbicpO1xudmFyIE1hcmsgICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL21hcmsnKTtcbnZhciBERUZBVUxUX1NBRkVfU0NIRU1BID0gcmVxdWlyZSgnLi9zY2hlbWEvZGVmYXVsdF9zYWZlJyk7XG52YXIgREVGQVVMVF9GVUxMX1NDSEVNQSA9IHJlcXVpcmUoJy4vc2NoZW1hL2RlZmF1bHRfZnVsbCcpO1xuXG5cbnZhciBfaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG5cbnZhciBDT05URVhUX0ZMT1dfSU4gICA9IDE7XG52YXIgQ09OVEVYVF9GTE9XX09VVCAgPSAyO1xudmFyIENPTlRFWFRfQkxPQ0tfSU4gID0gMztcbnZhciBDT05URVhUX0JMT0NLX09VVCA9IDQ7XG5cblxudmFyIENIT01QSU5HX0NMSVAgID0gMTtcbnZhciBDSE9NUElOR19TVFJJUCA9IDI7XG52YXIgQ0hPTVBJTkdfS0VFUCAgPSAzO1xuXG5cbnZhciBQQVRURVJOX05PTl9QUklOVEFCTEUgICAgICAgICA9IC9bXFx4MDAtXFx4MDhcXHgwQlxceDBDXFx4MEUtXFx4MUZcXHg3Ri1cXHg4NFxceDg2LVxceDlGXFx1RkZGRVxcdUZGRkZdfFtcXHVEODAwLVxcdURCRkZdKD8hW1xcdURDMDAtXFx1REZGRl0pfCg/OlteXFx1RDgwMC1cXHVEQkZGXXxeKVtcXHVEQzAwLVxcdURGRkZdLztcbnZhciBQQVRURVJOX05PTl9BU0NJSV9MSU5FX0JSRUFLUyA9IC9bXFx4ODVcXHUyMDI4XFx1MjAyOV0vO1xudmFyIFBBVFRFUk5fRkxPV19JTkRJQ0FUT1JTICAgICAgID0gL1ssXFxbXFxdXFx7XFx9XS87XG52YXIgUEFUVEVSTl9UQUdfSEFORExFICAgICAgICAgICAgPSAvXig/OiF8ISF8IVthLXpcXC1dKyEpJC9pO1xudmFyIFBBVFRFUk5fVEFHX1VSSSAgICAgICAgICAgICAgID0gL14oPzohfFteLFxcW1xcXVxce1xcfV0pKD86JVswLTlhLWZdezJ9fFswLTlhLXpcXC0jO1xcL1xcPzpAJj1cXCtcXCQsX1xcLiF+XFwqJ1xcKFxcKVxcW1xcXV0pKiQvaTtcblxuXG5mdW5jdGlvbiBpc19FT0woYykge1xuICByZXR1cm4gKGMgPT09IDB4MEEvKiBMRiAqLykgfHwgKGMgPT09IDB4MEQvKiBDUiAqLyk7XG59XG5cbmZ1bmN0aW9uIGlzX1dISVRFX1NQQUNFKGMpIHtcbiAgcmV0dXJuIChjID09PSAweDA5LyogVGFiICovKSB8fCAoYyA9PT0gMHgyMC8qIFNwYWNlICovKTtcbn1cblxuZnVuY3Rpb24gaXNfV1NfT1JfRU9MKGMpIHtcbiAgcmV0dXJuIChjID09PSAweDA5LyogVGFiICovKSB8fFxuICAgICAgICAgKGMgPT09IDB4MjAvKiBTcGFjZSAqLykgfHxcbiAgICAgICAgIChjID09PSAweDBBLyogTEYgKi8pIHx8XG4gICAgICAgICAoYyA9PT0gMHgwRC8qIENSICovKTtcbn1cblxuZnVuY3Rpb24gaXNfRkxPV19JTkRJQ0FUT1IoYykge1xuICByZXR1cm4gYyA9PT0gMHgyQy8qICwgKi8gfHxcbiAgICAgICAgIGMgPT09IDB4NUIvKiBbICovIHx8XG4gICAgICAgICBjID09PSAweDVELyogXSAqLyB8fFxuICAgICAgICAgYyA9PT0gMHg3Qi8qIHsgKi8gfHxcbiAgICAgICAgIGMgPT09IDB4N0QvKiB9ICovO1xufVxuXG5mdW5jdGlvbiBmcm9tSGV4Q29kZShjKSB7XG4gIHZhciBsYztcblxuICBpZiAoKDB4MzAvKiAwICovIDw9IGMpICYmIChjIDw9IDB4MzkvKiA5ICovKSkge1xuICAgIHJldHVybiBjIC0gMHgzMDtcbiAgfVxuXG4gIC8qZXNsaW50LWRpc2FibGUgbm8tYml0d2lzZSovXG4gIGxjID0gYyB8IDB4MjA7XG5cbiAgaWYgKCgweDYxLyogYSAqLyA8PSBsYykgJiYgKGxjIDw9IDB4NjYvKiBmICovKSkge1xuICAgIHJldHVybiBsYyAtIDB4NjEgKyAxMDtcbiAgfVxuXG4gIHJldHVybiAtMTtcbn1cblxuZnVuY3Rpb24gZXNjYXBlZEhleExlbihjKSB7XG4gIGlmIChjID09PSAweDc4LyogeCAqLykgeyByZXR1cm4gMjsgfVxuICBpZiAoYyA9PT0gMHg3NS8qIHUgKi8pIHsgcmV0dXJuIDQ7IH1cbiAgaWYgKGMgPT09IDB4NTUvKiBVICovKSB7IHJldHVybiA4OyB9XG4gIHJldHVybiAwO1xufVxuXG5mdW5jdGlvbiBmcm9tRGVjaW1hbENvZGUoYykge1xuICBpZiAoKDB4MzAvKiAwICovIDw9IGMpICYmIChjIDw9IDB4MzkvKiA5ICovKSkge1xuICAgIHJldHVybiBjIC0gMHgzMDtcbiAgfVxuXG4gIHJldHVybiAtMTtcbn1cblxuZnVuY3Rpb24gc2ltcGxlRXNjYXBlU2VxdWVuY2UoYykge1xuICByZXR1cm4gKGMgPT09IDB4MzAvKiAwICovKSA/ICdcXHgwMCcgOlxuICAgICAgICAoYyA9PT0gMHg2MS8qIGEgKi8pID8gJ1xceDA3JyA6XG4gICAgICAgIChjID09PSAweDYyLyogYiAqLykgPyAnXFx4MDgnIDpcbiAgICAgICAgKGMgPT09IDB4NzQvKiB0ICovKSA/ICdcXHgwOScgOlxuICAgICAgICAoYyA9PT0gMHgwOS8qIFRhYiAqLykgPyAnXFx4MDknIDpcbiAgICAgICAgKGMgPT09IDB4NkUvKiBuICovKSA/ICdcXHgwQScgOlxuICAgICAgICAoYyA9PT0gMHg3Ni8qIHYgKi8pID8gJ1xceDBCJyA6XG4gICAgICAgIChjID09PSAweDY2LyogZiAqLykgPyAnXFx4MEMnIDpcbiAgICAgICAgKGMgPT09IDB4NzIvKiByICovKSA/ICdcXHgwRCcgOlxuICAgICAgICAoYyA9PT0gMHg2NS8qIGUgKi8pID8gJ1xceDFCJyA6XG4gICAgICAgIChjID09PSAweDIwLyogU3BhY2UgKi8pID8gJyAnIDpcbiAgICAgICAgKGMgPT09IDB4MjIvKiBcIiAqLykgPyAnXFx4MjInIDpcbiAgICAgICAgKGMgPT09IDB4MkYvKiAvICovKSA/ICcvJyA6XG4gICAgICAgIChjID09PSAweDVDLyogXFwgKi8pID8gJ1xceDVDJyA6XG4gICAgICAgIChjID09PSAweDRFLyogTiAqLykgPyAnXFx4ODUnIDpcbiAgICAgICAgKGMgPT09IDB4NUYvKiBfICovKSA/ICdcXHhBMCcgOlxuICAgICAgICAoYyA9PT0gMHg0Qy8qIEwgKi8pID8gJ1xcdTIwMjgnIDpcbiAgICAgICAgKGMgPT09IDB4NTAvKiBQICovKSA/ICdcXHUyMDI5JyA6ICcnO1xufVxuXG5mdW5jdGlvbiBjaGFyRnJvbUNvZGVwb2ludChjKSB7XG4gIGlmIChjIDw9IDB4RkZGRikge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKGMpO1xuICB9XG4gIC8vIEVuY29kZSBVVEYtMTYgc3Vycm9nYXRlIHBhaXJcbiAgLy8gaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvVVRGLTE2I0NvZGVfcG9pbnRzX1UuMkIwMTAwMDBfdG9fVS4yQjEwRkZGRlxuICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZSgoKGMgLSAweDAxMDAwMCkgPj4gMTApICsgMHhEODAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKGMgLSAweDAxMDAwMCkgJiAweDAzRkYpICsgMHhEQzAwKTtcbn1cblxudmFyIHNpbXBsZUVzY2FwZUNoZWNrID0gbmV3IEFycmF5KDI1Nik7IC8vIGludGVnZXIsIGZvciBmYXN0IGFjY2Vzc1xudmFyIHNpbXBsZUVzY2FwZU1hcCA9IG5ldyBBcnJheSgyNTYpO1xuZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7IGkrKykge1xuICBzaW1wbGVFc2NhcGVDaGVja1tpXSA9IHNpbXBsZUVzY2FwZVNlcXVlbmNlKGkpID8gMSA6IDA7XG4gIHNpbXBsZUVzY2FwZU1hcFtpXSA9IHNpbXBsZUVzY2FwZVNlcXVlbmNlKGkpO1xufVxuXG5cbmZ1bmN0aW9uIFN0YXRlKGlucHV0LCBvcHRpb25zKSB7XG4gIHRoaXMuaW5wdXQgPSBpbnB1dDtcblxuICB0aGlzLmZpbGVuYW1lICA9IG9wdGlvbnNbJ2ZpbGVuYW1lJ10gIHx8IG51bGw7XG4gIHRoaXMuc2NoZW1hICAgID0gb3B0aW9uc1snc2NoZW1hJ10gICAgfHwgREVGQVVMVF9GVUxMX1NDSEVNQTtcbiAgdGhpcy5vbldhcm5pbmcgPSBvcHRpb25zWydvbldhcm5pbmcnXSB8fCBudWxsO1xuICB0aGlzLmxlZ2FjeSAgICA9IG9wdGlvbnNbJ2xlZ2FjeSddICAgIHx8IGZhbHNlO1xuICB0aGlzLmpzb24gICAgICA9IG9wdGlvbnNbJ2pzb24nXSAgICAgIHx8IGZhbHNlO1xuICB0aGlzLmxpc3RlbmVyICA9IG9wdGlvbnNbJ2xpc3RlbmVyJ10gIHx8IG51bGw7XG5cbiAgdGhpcy5pbXBsaWNpdFR5cGVzID0gdGhpcy5zY2hlbWEuY29tcGlsZWRJbXBsaWNpdDtcbiAgdGhpcy50eXBlTWFwICAgICAgID0gdGhpcy5zY2hlbWEuY29tcGlsZWRUeXBlTWFwO1xuXG4gIHRoaXMubGVuZ3RoICAgICA9IGlucHV0Lmxlbmd0aDtcbiAgdGhpcy5wb3NpdGlvbiAgID0gMDtcbiAgdGhpcy5saW5lICAgICAgID0gMDtcbiAgdGhpcy5saW5lU3RhcnQgID0gMDtcbiAgdGhpcy5saW5lSW5kZW50ID0gMDtcblxuICB0aGlzLmRvY3VtZW50cyA9IFtdO1xuXG4gIC8qXG4gIHRoaXMudmVyc2lvbjtcbiAgdGhpcy5jaGVja0xpbmVCcmVha3M7XG4gIHRoaXMudGFnTWFwO1xuICB0aGlzLmFuY2hvck1hcDtcbiAgdGhpcy50YWc7XG4gIHRoaXMuYW5jaG9yO1xuICB0aGlzLmtpbmQ7XG4gIHRoaXMucmVzdWx0OyovXG5cbn1cblxuXG5mdW5jdGlvbiBnZW5lcmF0ZUVycm9yKHN0YXRlLCBtZXNzYWdlKSB7XG4gIHJldHVybiBuZXcgWUFNTEV4Y2VwdGlvbihcbiAgICBtZXNzYWdlLFxuICAgIG5ldyBNYXJrKHN0YXRlLmZpbGVuYW1lLCBzdGF0ZS5pbnB1dCwgc3RhdGUucG9zaXRpb24sIHN0YXRlLmxpbmUsIChzdGF0ZS5wb3NpdGlvbiAtIHN0YXRlLmxpbmVTdGFydCkpKTtcbn1cblxuZnVuY3Rpb24gdGhyb3dFcnJvcihzdGF0ZSwgbWVzc2FnZSkge1xuICB0aHJvdyBnZW5lcmF0ZUVycm9yKHN0YXRlLCBtZXNzYWdlKTtcbn1cblxuZnVuY3Rpb24gdGhyb3dXYXJuaW5nKHN0YXRlLCBtZXNzYWdlKSB7XG4gIGlmIChzdGF0ZS5vbldhcm5pbmcpIHtcbiAgICBzdGF0ZS5vbldhcm5pbmcuY2FsbChudWxsLCBnZW5lcmF0ZUVycm9yKHN0YXRlLCBtZXNzYWdlKSk7XG4gIH1cbn1cblxuXG52YXIgZGlyZWN0aXZlSGFuZGxlcnMgPSB7XG5cbiAgWUFNTDogZnVuY3Rpb24gaGFuZGxlWWFtbERpcmVjdGl2ZShzdGF0ZSwgbmFtZSwgYXJncykge1xuXG4gICAgdmFyIG1hdGNoLCBtYWpvciwgbWlub3I7XG5cbiAgICBpZiAoc3RhdGUudmVyc2lvbiAhPT0gbnVsbCkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2R1cGxpY2F0aW9uIG9mICVZQU1MIGRpcmVjdGl2ZScpO1xuICAgIH1cblxuICAgIGlmIChhcmdzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ1lBTUwgZGlyZWN0aXZlIGFjY2VwdHMgZXhhY3RseSBvbmUgYXJndW1lbnQnKTtcbiAgICB9XG5cbiAgICBtYXRjaCA9IC9eKFswLTldKylcXC4oWzAtOV0rKSQvLmV4ZWMoYXJnc1swXSk7XG5cbiAgICBpZiAobWF0Y2ggPT09IG51bGwpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdpbGwtZm9ybWVkIGFyZ3VtZW50IG9mIHRoZSBZQU1MIGRpcmVjdGl2ZScpO1xuICAgIH1cblxuICAgIG1ham9yID0gcGFyc2VJbnQobWF0Y2hbMV0sIDEwKTtcbiAgICBtaW5vciA9IHBhcnNlSW50KG1hdGNoWzJdLCAxMCk7XG5cbiAgICBpZiAobWFqb3IgIT09IDEpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd1bmFjY2VwdGFibGUgWUFNTCB2ZXJzaW9uIG9mIHRoZSBkb2N1bWVudCcpO1xuICAgIH1cblxuICAgIHN0YXRlLnZlcnNpb24gPSBhcmdzWzBdO1xuICAgIHN0YXRlLmNoZWNrTGluZUJyZWFrcyA9IChtaW5vciA8IDIpO1xuXG4gICAgaWYgKG1pbm9yICE9PSAxICYmIG1pbm9yICE9PSAyKSB7XG4gICAgICB0aHJvd1dhcm5pbmcoc3RhdGUsICd1bnN1cHBvcnRlZCBZQU1MIHZlcnNpb24gb2YgdGhlIGRvY3VtZW50Jyk7XG4gICAgfVxuICB9LFxuXG4gIFRBRzogZnVuY3Rpb24gaGFuZGxlVGFnRGlyZWN0aXZlKHN0YXRlLCBuYW1lLCBhcmdzKSB7XG5cbiAgICB2YXIgaGFuZGxlLCBwcmVmaXg7XG5cbiAgICBpZiAoYXJncy5sZW5ndGggIT09IDIpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdUQUcgZGlyZWN0aXZlIGFjY2VwdHMgZXhhY3RseSB0d28gYXJndW1lbnRzJyk7XG4gICAgfVxuXG4gICAgaGFuZGxlID0gYXJnc1swXTtcbiAgICBwcmVmaXggPSBhcmdzWzFdO1xuXG4gICAgaWYgKCFQQVRURVJOX1RBR19IQU5ETEUudGVzdChoYW5kbGUpKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnaWxsLWZvcm1lZCB0YWcgaGFuZGxlIChmaXJzdCBhcmd1bWVudCkgb2YgdGhlIFRBRyBkaXJlY3RpdmUnKTtcbiAgICB9XG5cbiAgICBpZiAoX2hhc093blByb3BlcnR5LmNhbGwoc3RhdGUudGFnTWFwLCBoYW5kbGUpKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndGhlcmUgaXMgYSBwcmV2aW91c2x5IGRlY2xhcmVkIHN1ZmZpeCBmb3IgXCInICsgaGFuZGxlICsgJ1wiIHRhZyBoYW5kbGUnKTtcbiAgICB9XG5cbiAgICBpZiAoIVBBVFRFUk5fVEFHX1VSSS50ZXN0KHByZWZpeCkpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdpbGwtZm9ybWVkIHRhZyBwcmVmaXggKHNlY29uZCBhcmd1bWVudCkgb2YgdGhlIFRBRyBkaXJlY3RpdmUnKTtcbiAgICB9XG5cbiAgICBzdGF0ZS50YWdNYXBbaGFuZGxlXSA9IHByZWZpeDtcbiAgfVxufTtcblxuXG5mdW5jdGlvbiBjYXB0dXJlU2VnbWVudChzdGF0ZSwgc3RhcnQsIGVuZCwgY2hlY2tKc29uKSB7XG4gIHZhciBfcG9zaXRpb24sIF9sZW5ndGgsIF9jaGFyYWN0ZXIsIF9yZXN1bHQ7XG5cbiAgaWYgKHN0YXJ0IDwgZW5kKSB7XG4gICAgX3Jlc3VsdCA9IHN0YXRlLmlucHV0LnNsaWNlKHN0YXJ0LCBlbmQpO1xuXG4gICAgaWYgKGNoZWNrSnNvbikge1xuICAgICAgZm9yIChfcG9zaXRpb24gPSAwLCBfbGVuZ3RoID0gX3Jlc3VsdC5sZW5ndGg7XG4gICAgICAgICAgIF9wb3NpdGlvbiA8IF9sZW5ndGg7XG4gICAgICAgICAgIF9wb3NpdGlvbiArPSAxKSB7XG4gICAgICAgIF9jaGFyYWN0ZXIgPSBfcmVzdWx0LmNoYXJDb2RlQXQoX3Bvc2l0aW9uKTtcbiAgICAgICAgaWYgKCEoX2NoYXJhY3RlciA9PT0gMHgwOSB8fFxuICAgICAgICAgICAgICAoMHgyMCA8PSBfY2hhcmFjdGVyICYmIF9jaGFyYWN0ZXIgPD0gMHgxMEZGRkYpKSkge1xuICAgICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdleHBlY3RlZCB2YWxpZCBKU09OIGNoYXJhY3RlcicpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChQQVRURVJOX05PTl9QUklOVEFCTEUudGVzdChfcmVzdWx0KSkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3RoZSBzdHJlYW0gY29udGFpbnMgbm9uLXByaW50YWJsZSBjaGFyYWN0ZXJzJyk7XG4gICAgfVxuXG4gICAgc3RhdGUucmVzdWx0ICs9IF9yZXN1bHQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gbWVyZ2VNYXBwaW5ncyhzdGF0ZSwgZGVzdGluYXRpb24sIHNvdXJjZSwgb3ZlcnJpZGFibGVLZXlzKSB7XG4gIHZhciBzb3VyY2VLZXlzLCBrZXksIGluZGV4LCBxdWFudGl0eTtcblxuICBpZiAoIWNvbW1vbi5pc09iamVjdChzb3VyY2UpKSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2Nhbm5vdCBtZXJnZSBtYXBwaW5nczsgdGhlIHByb3ZpZGVkIHNvdXJjZSBvYmplY3QgaXMgdW5hY2NlcHRhYmxlJyk7XG4gIH1cblxuICBzb3VyY2VLZXlzID0gT2JqZWN0LmtleXMoc291cmNlKTtcblxuICBmb3IgKGluZGV4ID0gMCwgcXVhbnRpdHkgPSBzb3VyY2VLZXlzLmxlbmd0aDsgaW5kZXggPCBxdWFudGl0eTsgaW5kZXggKz0gMSkge1xuICAgIGtleSA9IHNvdXJjZUtleXNbaW5kZXhdO1xuXG4gICAgaWYgKCFfaGFzT3duUHJvcGVydHkuY2FsbChkZXN0aW5hdGlvbiwga2V5KSkge1xuICAgICAgZGVzdGluYXRpb25ba2V5XSA9IHNvdXJjZVtrZXldO1xuICAgICAgb3ZlcnJpZGFibGVLZXlzW2tleV0gPSB0cnVlO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBzdG9yZU1hcHBpbmdQYWlyKHN0YXRlLCBfcmVzdWx0LCBvdmVycmlkYWJsZUtleXMsIGtleVRhZywga2V5Tm9kZSwgdmFsdWVOb2RlKSB7XG4gIHZhciBpbmRleCwgcXVhbnRpdHk7XG5cbiAga2V5Tm9kZSA9IFN0cmluZyhrZXlOb2RlKTtcblxuICBpZiAoX3Jlc3VsdCA9PT0gbnVsbCkge1xuICAgIF9yZXN1bHQgPSB7fTtcbiAgfVxuXG4gIGlmIChrZXlUYWcgPT09ICd0YWc6eWFtbC5vcmcsMjAwMjptZXJnZScpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZU5vZGUpKSB7XG4gICAgICBmb3IgKGluZGV4ID0gMCwgcXVhbnRpdHkgPSB2YWx1ZU5vZGUubGVuZ3RoOyBpbmRleCA8IHF1YW50aXR5OyBpbmRleCArPSAxKSB7XG4gICAgICAgIG1lcmdlTWFwcGluZ3Moc3RhdGUsIF9yZXN1bHQsIHZhbHVlTm9kZVtpbmRleF0sIG92ZXJyaWRhYmxlS2V5cyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIG1lcmdlTWFwcGluZ3Moc3RhdGUsIF9yZXN1bHQsIHZhbHVlTm9kZSwgb3ZlcnJpZGFibGVLZXlzKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKCFzdGF0ZS5qc29uICYmXG4gICAgICAgICFfaGFzT3duUHJvcGVydHkuY2FsbChvdmVycmlkYWJsZUtleXMsIGtleU5vZGUpICYmXG4gICAgICAgIF9oYXNPd25Qcm9wZXJ0eS5jYWxsKF9yZXN1bHQsIGtleU5vZGUpKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZHVwbGljYXRlZCBtYXBwaW5nIGtleScpO1xuICAgIH1cbiAgICBfcmVzdWx0W2tleU5vZGVdID0gdmFsdWVOb2RlO1xuICAgIGRlbGV0ZSBvdmVycmlkYWJsZUtleXNba2V5Tm9kZV07XG4gIH1cblxuICByZXR1cm4gX3Jlc3VsdDtcbn1cblxuZnVuY3Rpb24gcmVhZExpbmVCcmVhayhzdGF0ZSkge1xuICB2YXIgY2g7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoY2ggPT09IDB4MEEvKiBMRiAqLykge1xuICAgIHN0YXRlLnBvc2l0aW9uKys7XG4gIH0gZWxzZSBpZiAoY2ggPT09IDB4MEQvKiBDUiAqLykge1xuICAgIHN0YXRlLnBvc2l0aW9uKys7XG4gICAgaWYgKHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pID09PSAweDBBLyogTEYgKi8pIHtcbiAgICAgIHN0YXRlLnBvc2l0aW9uKys7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICdhIGxpbmUgYnJlYWsgaXMgZXhwZWN0ZWQnKTtcbiAgfVxuXG4gIHN0YXRlLmxpbmUgKz0gMTtcbiAgc3RhdGUubGluZVN0YXJ0ID0gc3RhdGUucG9zaXRpb247XG59XG5cbmZ1bmN0aW9uIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIGFsbG93Q29tbWVudHMsIGNoZWNrSW5kZW50KSB7XG4gIHZhciBsaW5lQnJlYWtzID0gMCxcbiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgd2hpbGUgKGNoICE9PSAwKSB7XG4gICAgd2hpbGUgKGlzX1dISVRFX1NQQUNFKGNoKSkge1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgIH1cblxuICAgIGlmIChhbGxvd0NvbW1lbnRzICYmIGNoID09PSAweDIzLyogIyAqLykge1xuICAgICAgZG8ge1xuICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgICB9IHdoaWxlIChjaCAhPT0gMHgwQS8qIExGICovICYmIGNoICE9PSAweDBELyogQ1IgKi8gJiYgY2ggIT09IDApO1xuICAgIH1cblxuICAgIGlmIChpc19FT0woY2gpKSB7XG4gICAgICByZWFkTGluZUJyZWFrKHN0YXRlKTtcblxuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcbiAgICAgIGxpbmVCcmVha3MrKztcbiAgICAgIHN0YXRlLmxpbmVJbmRlbnQgPSAwO1xuXG4gICAgICB3aGlsZSAoY2ggPT09IDB4MjAvKiBTcGFjZSAqLykge1xuICAgICAgICBzdGF0ZS5saW5lSW5kZW50Kys7XG4gICAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgaWYgKGNoZWNrSW5kZW50ICE9PSAtMSAmJiBsaW5lQnJlYWtzICE9PSAwICYmIHN0YXRlLmxpbmVJbmRlbnQgPCBjaGVja0luZGVudCkge1xuICAgIHRocm93V2FybmluZyhzdGF0ZSwgJ2RlZmljaWVudCBpbmRlbnRhdGlvbicpO1xuICB9XG5cbiAgcmV0dXJuIGxpbmVCcmVha3M7XG59XG5cbmZ1bmN0aW9uIHRlc3REb2N1bWVudFNlcGFyYXRvcihzdGF0ZSkge1xuICB2YXIgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb24sXG4gICAgICBjaDtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoX3Bvc2l0aW9uKTtcblxuICAvLyBDb25kaXRpb24gc3RhdGUucG9zaXRpb24gPT09IHN0YXRlLmxpbmVTdGFydCBpcyB0ZXN0ZWRcbiAgLy8gaW4gcGFyZW50IG9uIGVhY2ggY2FsbCwgZm9yIGVmZmljaWVuY3kuIE5vIG5lZWRzIHRvIHRlc3QgaGVyZSBhZ2Fpbi5cbiAgaWYgKChjaCA9PT0gMHgyRC8qIC0gKi8gfHwgY2ggPT09IDB4MkUvKiAuICovKSAmJlxuICAgICAgY2ggPT09IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoX3Bvc2l0aW9uICsgMSkgJiZcbiAgICAgIGNoID09PSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KF9wb3NpdGlvbiArIDIpKSB7XG5cbiAgICBfcG9zaXRpb24gKz0gMztcblxuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChfcG9zaXRpb24pO1xuXG4gICAgaWYgKGNoID09PSAwIHx8IGlzX1dTX09SX0VPTChjaCkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gd3JpdGVGb2xkZWRMaW5lcyhzdGF0ZSwgY291bnQpIHtcbiAgaWYgKGNvdW50ID09PSAxKSB7XG4gICAgc3RhdGUucmVzdWx0ICs9ICcgJztcbiAgfSBlbHNlIGlmIChjb3VudCA+IDEpIHtcbiAgICBzdGF0ZS5yZXN1bHQgKz0gY29tbW9uLnJlcGVhdCgnXFxuJywgY291bnQgLSAxKTtcbiAgfVxufVxuXG5cbmZ1bmN0aW9uIHJlYWRQbGFpblNjYWxhcihzdGF0ZSwgbm9kZUluZGVudCwgd2l0aGluRmxvd0NvbGxlY3Rpb24pIHtcbiAgdmFyIHByZWNlZGluZyxcbiAgICAgIGZvbGxvd2luZyxcbiAgICAgIGNhcHR1cmVTdGFydCxcbiAgICAgIGNhcHR1cmVFbmQsXG4gICAgICBoYXNQZW5kaW5nQ29udGVudCxcbiAgICAgIF9saW5lLFxuICAgICAgX2xpbmVTdGFydCxcbiAgICAgIF9saW5lSW5kZW50LFxuICAgICAgX2tpbmQgPSBzdGF0ZS5raW5kLFxuICAgICAgX3Jlc3VsdCA9IHN0YXRlLnJlc3VsdCxcbiAgICAgIGNoO1xuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgaWYgKGlzX1dTX09SX0VPTChjaCkgICAgICB8fFxuICAgICAgaXNfRkxPV19JTkRJQ0FUT1IoY2gpIHx8XG4gICAgICBjaCA9PT0gMHgyMy8qICMgKi8gICAgfHxcbiAgICAgIGNoID09PSAweDI2LyogJiAqLyAgICB8fFxuICAgICAgY2ggPT09IDB4MkEvKiAqICovICAgIHx8XG4gICAgICBjaCA9PT0gMHgyMS8qICEgKi8gICAgfHxcbiAgICAgIGNoID09PSAweDdDLyogfCAqLyAgICB8fFxuICAgICAgY2ggPT09IDB4M0UvKiA+ICovICAgIHx8XG4gICAgICBjaCA9PT0gMHgyNy8qICcgKi8gICAgfHxcbiAgICAgIGNoID09PSAweDIyLyogXCIgKi8gICAgfHxcbiAgICAgIGNoID09PSAweDI1LyogJSAqLyAgICB8fFxuICAgICAgY2ggPT09IDB4NDAvKiBAICovICAgIHx8XG4gICAgICBjaCA9PT0gMHg2MC8qIGAgKi8pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAoY2ggPT09IDB4M0YvKiA/ICovIHx8IGNoID09PSAweDJELyogLSAqLykge1xuICAgIGZvbGxvd2luZyA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24gKyAxKTtcblxuICAgIGlmIChpc19XU19PUl9FT0woZm9sbG93aW5nKSB8fFxuICAgICAgICB3aXRoaW5GbG93Q29sbGVjdGlvbiAmJiBpc19GTE9XX0lORElDQVRPUihmb2xsb3dpbmcpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgc3RhdGUua2luZCA9ICdzY2FsYXInO1xuICBzdGF0ZS5yZXN1bHQgPSAnJztcbiAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuICBoYXNQZW5kaW5nQ29udGVudCA9IGZhbHNlO1xuXG4gIHdoaWxlIChjaCAhPT0gMCkge1xuICAgIGlmIChjaCA9PT0gMHgzQS8qIDogKi8pIHtcbiAgICAgIGZvbGxvd2luZyA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24gKyAxKTtcblxuICAgICAgaWYgKGlzX1dTX09SX0VPTChmb2xsb3dpbmcpIHx8XG4gICAgICAgICAgd2l0aGluRmxvd0NvbGxlY3Rpb24gJiYgaXNfRkxPV19JTkRJQ0FUT1IoZm9sbG93aW5nKSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIH0gZWxzZSBpZiAoY2ggPT09IDB4MjMvKiAjICovKSB7XG4gICAgICBwcmVjZWRpbmcgPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uIC0gMSk7XG5cbiAgICAgIGlmIChpc19XU19PUl9FT0wocHJlY2VkaW5nKSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIH0gZWxzZSBpZiAoKHN0YXRlLnBvc2l0aW9uID09PSBzdGF0ZS5saW5lU3RhcnQgJiYgdGVzdERvY3VtZW50U2VwYXJhdG9yKHN0YXRlKSkgfHxcbiAgICAgICAgICAgICAgIHdpdGhpbkZsb3dDb2xsZWN0aW9uICYmIGlzX0ZMT1dfSU5ESUNBVE9SKGNoKSkge1xuICAgICAgYnJlYWs7XG5cbiAgICB9IGVsc2UgaWYgKGlzX0VPTChjaCkpIHtcbiAgICAgIF9saW5lID0gc3RhdGUubGluZTtcbiAgICAgIF9saW5lU3RhcnQgPSBzdGF0ZS5saW5lU3RhcnQ7XG4gICAgICBfbGluZUluZGVudCA9IHN0YXRlLmxpbmVJbmRlbnQ7XG4gICAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCBmYWxzZSwgLTEpO1xuXG4gICAgICBpZiAoc3RhdGUubGluZUluZGVudCA+PSBub2RlSW5kZW50KSB7XG4gICAgICAgIGhhc1BlbmRpbmdDb250ZW50ID0gdHJ1ZTtcbiAgICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdGF0ZS5wb3NpdGlvbiA9IGNhcHR1cmVFbmQ7XG4gICAgICAgIHN0YXRlLmxpbmUgPSBfbGluZTtcbiAgICAgICAgc3RhdGUubGluZVN0YXJ0ID0gX2xpbmVTdGFydDtcbiAgICAgICAgc3RhdGUubGluZUluZGVudCA9IF9saW5lSW5kZW50O1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaGFzUGVuZGluZ0NvbnRlbnQpIHtcbiAgICAgIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIGNhcHR1cmVFbmQsIGZhbHNlKTtcbiAgICAgIHdyaXRlRm9sZGVkTGluZXMoc3RhdGUsIHN0YXRlLmxpbmUgLSBfbGluZSk7XG4gICAgICBjYXB0dXJlU3RhcnQgPSBjYXB0dXJlRW5kID0gc3RhdGUucG9zaXRpb247XG4gICAgICBoYXNQZW5kaW5nQ29udGVudCA9IGZhbHNlO1xuICAgIH1cblxuICAgIGlmICghaXNfV0hJVEVfU1BBQ0UoY2gpKSB7XG4gICAgICBjYXB0dXJlRW5kID0gc3RhdGUucG9zaXRpb24gKyAxO1xuICAgIH1cblxuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgfVxuXG4gIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIGNhcHR1cmVFbmQsIGZhbHNlKTtcblxuICBpZiAoc3RhdGUucmVzdWx0KSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBzdGF0ZS5raW5kID0gX2tpbmQ7XG4gIHN0YXRlLnJlc3VsdCA9IF9yZXN1bHQ7XG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gcmVhZFNpbmdsZVF1b3RlZFNjYWxhcihzdGF0ZSwgbm9kZUluZGVudCkge1xuICB2YXIgY2gsXG4gICAgICBjYXB0dXJlU3RhcnQsIGNhcHR1cmVFbmQ7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoY2ggIT09IDB4MjcvKiAnICovKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgc3RhdGUua2luZCA9ICdzY2FsYXInO1xuICBzdGF0ZS5yZXN1bHQgPSAnJztcbiAgc3RhdGUucG9zaXRpb24rKztcbiAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gIHdoaWxlICgoY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKSkgIT09IDApIHtcbiAgICBpZiAoY2ggPT09IDB4MjcvKiAnICovKSB7XG4gICAgICBjYXB0dXJlU2VnbWVudChzdGF0ZSwgY2FwdHVyZVN0YXJ0LCBzdGF0ZS5wb3NpdGlvbiwgdHJ1ZSk7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICAgIGlmIChjaCA9PT0gMHgyNy8qICcgKi8pIHtcbiAgICAgICAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuICAgICAgICBzdGF0ZS5wb3NpdGlvbisrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICB9IGVsc2UgaWYgKGlzX0VPTChjaCkpIHtcbiAgICAgIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIGNhcHR1cmVFbmQsIHRydWUpO1xuICAgICAgd3JpdGVGb2xkZWRMaW5lcyhzdGF0ZSwgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgZmFsc2UsIG5vZGVJbmRlbnQpKTtcbiAgICAgIGNhcHR1cmVTdGFydCA9IGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbjtcblxuICAgIH0gZWxzZSBpZiAoc3RhdGUucG9zaXRpb24gPT09IHN0YXRlLmxpbmVTdGFydCAmJiB0ZXN0RG9jdW1lbnRTZXBhcmF0b3Ioc3RhdGUpKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndW5leHBlY3RlZCBlbmQgb2YgdGhlIGRvY3VtZW50IHdpdGhpbiBhIHNpbmdsZSBxdW90ZWQgc2NhbGFyJyk7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgc3RhdGUucG9zaXRpb24rKztcbiAgICAgIGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbjtcbiAgICB9XG4gIH1cblxuICB0aHJvd0Vycm9yKHN0YXRlLCAndW5leHBlY3RlZCBlbmQgb2YgdGhlIHN0cmVhbSB3aXRoaW4gYSBzaW5nbGUgcXVvdGVkIHNjYWxhcicpO1xufVxuXG5mdW5jdGlvbiByZWFkRG91YmxlUXVvdGVkU2NhbGFyKHN0YXRlLCBub2RlSW5kZW50KSB7XG4gIHZhciBjYXB0dXJlU3RhcnQsXG4gICAgICBjYXB0dXJlRW5kLFxuICAgICAgaGV4TGVuZ3RoLFxuICAgICAgaGV4UmVzdWx0LFxuICAgICAgdG1wLFxuICAgICAgY2g7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoY2ggIT09IDB4MjIvKiBcIiAqLykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHN0YXRlLmtpbmQgPSAnc2NhbGFyJztcbiAgc3RhdGUucmVzdWx0ID0gJyc7XG4gIHN0YXRlLnBvc2l0aW9uKys7XG4gIGNhcHR1cmVTdGFydCA9IGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbjtcblxuICB3aGlsZSAoKGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbikpICE9PSAwKSB7XG4gICAgaWYgKGNoID09PSAweDIyLyogXCIgKi8pIHtcbiAgICAgIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIHN0YXRlLnBvc2l0aW9uLCB0cnVlKTtcbiAgICAgIHN0YXRlLnBvc2l0aW9uKys7XG4gICAgICByZXR1cm4gdHJ1ZTtcblxuICAgIH0gZWxzZSBpZiAoY2ggPT09IDB4NUMvKiBcXCAqLykge1xuICAgICAgY2FwdHVyZVNlZ21lbnQoc3RhdGUsIGNhcHR1cmVTdGFydCwgc3RhdGUucG9zaXRpb24sIHRydWUpO1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuXG4gICAgICBpZiAoaXNfRU9MKGNoKSkge1xuICAgICAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCBmYWxzZSwgbm9kZUluZGVudCk7XG5cbiAgICAgICAgLy8gVE9ETzogcmV3b3JrIHRvIGlubGluZSBmbiB3aXRoIG5vIHR5cGUgY2FzdD9cbiAgICAgIH0gZWxzZSBpZiAoY2ggPCAyNTYgJiYgc2ltcGxlRXNjYXBlQ2hlY2tbY2hdKSB7XG4gICAgICAgIHN0YXRlLnJlc3VsdCArPSBzaW1wbGVFc2NhcGVNYXBbY2hdO1xuICAgICAgICBzdGF0ZS5wb3NpdGlvbisrO1xuXG4gICAgICB9IGVsc2UgaWYgKCh0bXAgPSBlc2NhcGVkSGV4TGVuKGNoKSkgPiAwKSB7XG4gICAgICAgIGhleExlbmd0aCA9IHRtcDtcbiAgICAgICAgaGV4UmVzdWx0ID0gMDtcblxuICAgICAgICBmb3IgKDsgaGV4TGVuZ3RoID4gMDsgaGV4TGVuZ3RoLS0pIHtcbiAgICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICAgICAgICBpZiAoKHRtcCA9IGZyb21IZXhDb2RlKGNoKSkgPj0gMCkge1xuICAgICAgICAgICAgaGV4UmVzdWx0ID0gKGhleFJlc3VsdCA8PCA0KSArIHRtcDtcblxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZXhwZWN0ZWQgaGV4YWRlY2ltYWwgY2hhcmFjdGVyJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgc3RhdGUucmVzdWx0ICs9IGNoYXJGcm9tQ29kZXBvaW50KGhleFJlc3VsdCk7XG5cbiAgICAgICAgc3RhdGUucG9zaXRpb24rKztcblxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3Vua25vd24gZXNjYXBlIHNlcXVlbmNlJyk7XG4gICAgICB9XG5cbiAgICAgIGNhcHR1cmVTdGFydCA9IGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbjtcblxuICAgIH0gZWxzZSBpZiAoaXNfRU9MKGNoKSkge1xuICAgICAgY2FwdHVyZVNlZ21lbnQoc3RhdGUsIGNhcHR1cmVTdGFydCwgY2FwdHVyZUVuZCwgdHJ1ZSk7XG4gICAgICB3cml0ZUZvbGRlZExpbmVzKHN0YXRlLCBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCBmYWxzZSwgbm9kZUluZGVudCkpO1xuICAgICAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gICAgfSBlbHNlIGlmIChzdGF0ZS5wb3NpdGlvbiA9PT0gc3RhdGUubGluZVN0YXJ0ICYmIHRlc3REb2N1bWVudFNlcGFyYXRvcihzdGF0ZSkpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd1bmV4cGVjdGVkIGVuZCBvZiB0aGUgZG9jdW1lbnQgd2l0aGluIGEgZG91YmxlIHF1b3RlZCBzY2FsYXInKTtcblxuICAgIH0gZWxzZSB7XG4gICAgICBzdGF0ZS5wb3NpdGlvbisrO1xuICAgICAgY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuICAgIH1cbiAgfVxuXG4gIHRocm93RXJyb3Ioc3RhdGUsICd1bmV4cGVjdGVkIGVuZCBvZiB0aGUgc3RyZWFtIHdpdGhpbiBhIGRvdWJsZSBxdW90ZWQgc2NhbGFyJyk7XG59XG5cbmZ1bmN0aW9uIHJlYWRGbG93Q29sbGVjdGlvbihzdGF0ZSwgbm9kZUluZGVudCkge1xuICB2YXIgcmVhZE5leHQgPSB0cnVlLFxuICAgICAgX2xpbmUsXG4gICAgICBfdGFnICAgICA9IHN0YXRlLnRhZyxcbiAgICAgIF9yZXN1bHQsXG4gICAgICBfYW5jaG9yICA9IHN0YXRlLmFuY2hvcixcbiAgICAgIGZvbGxvd2luZyxcbiAgICAgIHRlcm1pbmF0b3IsXG4gICAgICBpc1BhaXIsXG4gICAgICBpc0V4cGxpY2l0UGFpcixcbiAgICAgIGlzTWFwcGluZyxcbiAgICAgIG92ZXJyaWRhYmxlS2V5cyA9IHt9LFxuICAgICAga2V5Tm9kZSxcbiAgICAgIGtleVRhZyxcbiAgICAgIHZhbHVlTm9kZSxcbiAgICAgIGNoO1xuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgaWYgKGNoID09PSAweDVCLyogWyAqLykge1xuICAgIHRlcm1pbmF0b3IgPSAweDVEOy8qIF0gKi9cbiAgICBpc01hcHBpbmcgPSBmYWxzZTtcbiAgICBfcmVzdWx0ID0gW107XG4gIH0gZWxzZSBpZiAoY2ggPT09IDB4N0IvKiB7ICovKSB7XG4gICAgdGVybWluYXRvciA9IDB4N0Q7LyogfSAqL1xuICAgIGlzTWFwcGluZyA9IHRydWU7XG4gICAgX3Jlc3VsdCA9IHt9O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChzdGF0ZS5hbmNob3IgIT09IG51bGwpIHtcbiAgICBzdGF0ZS5hbmNob3JNYXBbc3RhdGUuYW5jaG9yXSA9IF9yZXN1bHQ7XG4gIH1cblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgd2hpbGUgKGNoICE9PSAwKSB7XG4gICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgbm9kZUluZGVudCk7XG5cbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gICAgaWYgKGNoID09PSB0ZXJtaW5hdG9yKSB7XG4gICAgICBzdGF0ZS5wb3NpdGlvbisrO1xuICAgICAgc3RhdGUudGFnID0gX3RhZztcbiAgICAgIHN0YXRlLmFuY2hvciA9IF9hbmNob3I7XG4gICAgICBzdGF0ZS5raW5kID0gaXNNYXBwaW5nID8gJ21hcHBpbmcnIDogJ3NlcXVlbmNlJztcbiAgICAgIHN0YXRlLnJlc3VsdCA9IF9yZXN1bHQ7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKCFyZWFkTmV4dCkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ21pc3NlZCBjb21tYSBiZXR3ZWVuIGZsb3cgY29sbGVjdGlvbiBlbnRyaWVzJyk7XG4gICAgfVxuXG4gICAga2V5VGFnID0ga2V5Tm9kZSA9IHZhbHVlTm9kZSA9IG51bGw7XG4gICAgaXNQYWlyID0gaXNFeHBsaWNpdFBhaXIgPSBmYWxzZTtcblxuICAgIGlmIChjaCA9PT0gMHgzRi8qID8gKi8pIHtcbiAgICAgIGZvbGxvd2luZyA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24gKyAxKTtcblxuICAgICAgaWYgKGlzX1dTX09SX0VPTChmb2xsb3dpbmcpKSB7XG4gICAgICAgIGlzUGFpciA9IGlzRXhwbGljaXRQYWlyID0gdHJ1ZTtcbiAgICAgICAgc3RhdGUucG9zaXRpb24rKztcbiAgICAgICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgbm9kZUluZGVudCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgX2xpbmUgPSBzdGF0ZS5saW5lO1xuICAgIGNvbXBvc2VOb2RlKHN0YXRlLCBub2RlSW5kZW50LCBDT05URVhUX0ZMT1dfSU4sIGZhbHNlLCB0cnVlKTtcbiAgICBrZXlUYWcgPSBzdGF0ZS50YWc7XG4gICAga2V5Tm9kZSA9IHN0YXRlLnJlc3VsdDtcbiAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCBub2RlSW5kZW50KTtcblxuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICBpZiAoKGlzRXhwbGljaXRQYWlyIHx8IHN0YXRlLmxpbmUgPT09IF9saW5lKSAmJiBjaCA9PT0gMHgzQS8qIDogKi8pIHtcbiAgICAgIGlzUGFpciA9IHRydWU7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCBub2RlSW5kZW50KTtcbiAgICAgIGNvbXBvc2VOb2RlKHN0YXRlLCBub2RlSW5kZW50LCBDT05URVhUX0ZMT1dfSU4sIGZhbHNlLCB0cnVlKTtcbiAgICAgIHZhbHVlTm9kZSA9IHN0YXRlLnJlc3VsdDtcbiAgICB9XG5cbiAgICBpZiAoaXNNYXBwaW5nKSB7XG4gICAgICBzdG9yZU1hcHBpbmdQYWlyKHN0YXRlLCBfcmVzdWx0LCBvdmVycmlkYWJsZUtleXMsIGtleVRhZywga2V5Tm9kZSwgdmFsdWVOb2RlKTtcbiAgICB9IGVsc2UgaWYgKGlzUGFpcikge1xuICAgICAgX3Jlc3VsdC5wdXNoKHN0b3JlTWFwcGluZ1BhaXIoc3RhdGUsIG51bGwsIG92ZXJyaWRhYmxlS2V5cywga2V5VGFnLCBrZXlOb2RlLCB2YWx1ZU5vZGUpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgX3Jlc3VsdC5wdXNoKGtleU5vZGUpO1xuICAgIH1cblxuICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIG5vZGVJbmRlbnQpO1xuXG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICAgIGlmIChjaCA9PT0gMHgyQy8qICwgKi8pIHtcbiAgICAgIHJlYWROZXh0ID0gdHJ1ZTtcbiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVhZE5leHQgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICB0aHJvd0Vycm9yKHN0YXRlLCAndW5leHBlY3RlZCBlbmQgb2YgdGhlIHN0cmVhbSB3aXRoaW4gYSBmbG93IGNvbGxlY3Rpb24nKTtcbn1cblxuZnVuY3Rpb24gcmVhZEJsb2NrU2NhbGFyKHN0YXRlLCBub2RlSW5kZW50KSB7XG4gIHZhciBjYXB0dXJlU3RhcnQsXG4gICAgICBmb2xkaW5nLFxuICAgICAgY2hvbXBpbmcgICAgICAgPSBDSE9NUElOR19DTElQLFxuICAgICAgZGlkUmVhZENvbnRlbnQgPSBmYWxzZSxcbiAgICAgIGRldGVjdGVkSW5kZW50ID0gZmFsc2UsXG4gICAgICB0ZXh0SW5kZW50ICAgICA9IG5vZGVJbmRlbnQsXG4gICAgICBlbXB0eUxpbmVzICAgICA9IDAsXG4gICAgICBhdE1vcmVJbmRlbnRlZCA9IGZhbHNlLFxuICAgICAgdG1wLFxuICAgICAgY2g7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoY2ggPT09IDB4N0MvKiB8ICovKSB7XG4gICAgZm9sZGluZyA9IGZhbHNlO1xuICB9IGVsc2UgaWYgKGNoID09PSAweDNFLyogPiAqLykge1xuICAgIGZvbGRpbmcgPSB0cnVlO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHN0YXRlLmtpbmQgPSAnc2NhbGFyJztcbiAgc3RhdGUucmVzdWx0ID0gJyc7XG5cbiAgd2hpbGUgKGNoICE9PSAwKSB7XG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuXG4gICAgaWYgKGNoID09PSAweDJCLyogKyAqLyB8fCBjaCA9PT0gMHgyRC8qIC0gKi8pIHtcbiAgICAgIGlmIChDSE9NUElOR19DTElQID09PSBjaG9tcGluZykge1xuICAgICAgICBjaG9tcGluZyA9IChjaCA9PT0gMHgyQi8qICsgKi8pID8gQ0hPTVBJTkdfS0VFUCA6IENIT01QSU5HX1NUUklQO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3JlcGVhdCBvZiBhIGNob21waW5nIG1vZGUgaWRlbnRpZmllcicpO1xuICAgICAgfVxuXG4gICAgfSBlbHNlIGlmICgodG1wID0gZnJvbURlY2ltYWxDb2RlKGNoKSkgPj0gMCkge1xuICAgICAgaWYgKHRtcCA9PT0gMCkge1xuICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnYmFkIGV4cGxpY2l0IGluZGVudGF0aW9uIHdpZHRoIG9mIGEgYmxvY2sgc2NhbGFyOyBpdCBjYW5ub3QgYmUgbGVzcyB0aGFuIG9uZScpO1xuICAgICAgfSBlbHNlIGlmICghZGV0ZWN0ZWRJbmRlbnQpIHtcbiAgICAgICAgdGV4dEluZGVudCA9IG5vZGVJbmRlbnQgKyB0bXAgLSAxO1xuICAgICAgICBkZXRlY3RlZEluZGVudCA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAncmVwZWF0IG9mIGFuIGluZGVudGF0aW9uIHdpZHRoIGlkZW50aWZpZXInKTtcbiAgICAgIH1cblxuICAgIH0gZWxzZSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBpZiAoaXNfV0hJVEVfU1BBQ0UoY2gpKSB7XG4gICAgZG8geyBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7IH1cbiAgICB3aGlsZSAoaXNfV0hJVEVfU1BBQ0UoY2gpKTtcblxuICAgIGlmIChjaCA9PT0gMHgyMy8qICMgKi8pIHtcbiAgICAgIGRvIHsgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pOyB9XG4gICAgICB3aGlsZSAoIWlzX0VPTChjaCkgJiYgKGNoICE9PSAwKSk7XG4gICAgfVxuICB9XG5cbiAgd2hpbGUgKGNoICE9PSAwKSB7XG4gICAgcmVhZExpbmVCcmVhayhzdGF0ZSk7XG4gICAgc3RhdGUubGluZUluZGVudCA9IDA7XG5cbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gICAgd2hpbGUgKCghZGV0ZWN0ZWRJbmRlbnQgfHwgc3RhdGUubGluZUluZGVudCA8IHRleHRJbmRlbnQpICYmXG4gICAgICAgICAgIChjaCA9PT0gMHgyMC8qIFNwYWNlICovKSkge1xuICAgICAgc3RhdGUubGluZUluZGVudCsrO1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgIH1cblxuICAgIGlmICghZGV0ZWN0ZWRJbmRlbnQgJiYgc3RhdGUubGluZUluZGVudCA+IHRleHRJbmRlbnQpIHtcbiAgICAgIHRleHRJbmRlbnQgPSBzdGF0ZS5saW5lSW5kZW50O1xuICAgIH1cblxuICAgIGlmIChpc19FT0woY2gpKSB7XG4gICAgICBlbXB0eUxpbmVzKys7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICAvLyBFbmQgb2YgdGhlIHNjYWxhci5cbiAgICBpZiAoc3RhdGUubGluZUluZGVudCA8IHRleHRJbmRlbnQpIHtcblxuICAgICAgLy8gUGVyZm9ybSB0aGUgY2hvbXBpbmcuXG4gICAgICBpZiAoY2hvbXBpbmcgPT09IENIT01QSU5HX0tFRVApIHtcbiAgICAgICAgc3RhdGUucmVzdWx0ICs9IGNvbW1vbi5yZXBlYXQoJ1xcbicsIGRpZFJlYWRDb250ZW50ID8gMSArIGVtcHR5TGluZXMgOiBlbXB0eUxpbmVzKTtcbiAgICAgIH0gZWxzZSBpZiAoY2hvbXBpbmcgPT09IENIT01QSU5HX0NMSVApIHtcbiAgICAgICAgaWYgKGRpZFJlYWRDb250ZW50KSB7IC8vIGkuZS4gb25seSBpZiB0aGUgc2NhbGFyIGlzIG5vdCBlbXB0eS5cbiAgICAgICAgICBzdGF0ZS5yZXN1bHQgKz0gJ1xcbic7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gQnJlYWsgdGhpcyBgd2hpbGVgIGN5Y2xlIGFuZCBnbyB0byB0aGUgZnVuY2l0b24ncyBlcGlsb2d1ZS5cbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIC8vIEZvbGRlZCBzdHlsZTogdXNlIGZhbmN5IHJ1bGVzIHRvIGhhbmRsZSBsaW5lIGJyZWFrcy5cbiAgICBpZiAoZm9sZGluZykge1xuXG4gICAgICAvLyBMaW5lcyBzdGFydGluZyB3aXRoIHdoaXRlIHNwYWNlIGNoYXJhY3RlcnMgKG1vcmUtaW5kZW50ZWQgbGluZXMpIGFyZSBub3QgZm9sZGVkLlxuICAgICAgaWYgKGlzX1dISVRFX1NQQUNFKGNoKSkge1xuICAgICAgICBhdE1vcmVJbmRlbnRlZCA9IHRydWU7XG4gICAgICAgIC8vIGV4Y2VwdCBmb3IgdGhlIGZpcnN0IGNvbnRlbnQgbGluZSAoY2YuIEV4YW1wbGUgOC4xKVxuICAgICAgICBzdGF0ZS5yZXN1bHQgKz0gY29tbW9uLnJlcGVhdCgnXFxuJywgZGlkUmVhZENvbnRlbnQgPyAxICsgZW1wdHlMaW5lcyA6IGVtcHR5TGluZXMpO1xuXG4gICAgICAvLyBFbmQgb2YgbW9yZS1pbmRlbnRlZCBibG9jay5cbiAgICAgIH0gZWxzZSBpZiAoYXRNb3JlSW5kZW50ZWQpIHtcbiAgICAgICAgYXRNb3JlSW5kZW50ZWQgPSBmYWxzZTtcbiAgICAgICAgc3RhdGUucmVzdWx0ICs9IGNvbW1vbi5yZXBlYXQoJ1xcbicsIGVtcHR5TGluZXMgKyAxKTtcblxuICAgICAgLy8gSnVzdCBvbmUgbGluZSBicmVhayAtIHBlcmNlaXZlIGFzIHRoZSBzYW1lIGxpbmUuXG4gICAgICB9IGVsc2UgaWYgKGVtcHR5TGluZXMgPT09IDApIHtcbiAgICAgICAgaWYgKGRpZFJlYWRDb250ZW50KSB7IC8vIGkuZS4gb25seSBpZiB3ZSBoYXZlIGFscmVhZHkgcmVhZCBzb21lIHNjYWxhciBjb250ZW50LlxuICAgICAgICAgIHN0YXRlLnJlc3VsdCArPSAnICc7XG4gICAgICAgIH1cblxuICAgICAgLy8gU2V2ZXJhbCBsaW5lIGJyZWFrcyAtIHBlcmNlaXZlIGFzIGRpZmZlcmVudCBsaW5lcy5cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXRlLnJlc3VsdCArPSBjb21tb24ucmVwZWF0KCdcXG4nLCBlbXB0eUxpbmVzKTtcbiAgICAgIH1cblxuICAgIC8vIExpdGVyYWwgc3R5bGU6IGp1c3QgYWRkIGV4YWN0IG51bWJlciBvZiBsaW5lIGJyZWFrcyBiZXR3ZWVuIGNvbnRlbnQgbGluZXMuXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEtlZXAgYWxsIGxpbmUgYnJlYWtzIGV4Y2VwdCB0aGUgaGVhZGVyIGxpbmUgYnJlYWsuXG4gICAgICBzdGF0ZS5yZXN1bHQgKz0gY29tbW9uLnJlcGVhdCgnXFxuJywgZGlkUmVhZENvbnRlbnQgPyAxICsgZW1wdHlMaW5lcyA6IGVtcHR5TGluZXMpO1xuICAgIH1cblxuICAgIGRpZFJlYWRDb250ZW50ID0gdHJ1ZTtcbiAgICBkZXRlY3RlZEluZGVudCA9IHRydWU7XG4gICAgZW1wdHlMaW5lcyA9IDA7XG4gICAgY2FwdHVyZVN0YXJ0ID0gc3RhdGUucG9zaXRpb247XG5cbiAgICB3aGlsZSAoIWlzX0VPTChjaCkgJiYgKGNoICE9PSAwKSkge1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgIH1cblxuICAgIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIHN0YXRlLnBvc2l0aW9uLCBmYWxzZSk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gcmVhZEJsb2NrU2VxdWVuY2Uoc3RhdGUsIG5vZGVJbmRlbnQpIHtcbiAgdmFyIF9saW5lLFxuICAgICAgX3RhZyAgICAgID0gc3RhdGUudGFnLFxuICAgICAgX2FuY2hvciAgID0gc3RhdGUuYW5jaG9yLFxuICAgICAgX3Jlc3VsdCAgID0gW10sXG4gICAgICBmb2xsb3dpbmcsXG4gICAgICBkZXRlY3RlZCAgPSBmYWxzZSxcbiAgICAgIGNoO1xuXG4gIGlmIChzdGF0ZS5hbmNob3IgIT09IG51bGwpIHtcbiAgICBzdGF0ZS5hbmNob3JNYXBbc3RhdGUuYW5jaG9yXSA9IF9yZXN1bHQ7XG4gIH1cblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gIHdoaWxlIChjaCAhPT0gMCkge1xuXG4gICAgaWYgKGNoICE9PSAweDJELyogLSAqLykge1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgZm9sbG93aW5nID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbiArIDEpO1xuXG4gICAgaWYgKCFpc19XU19PUl9FT0woZm9sbG93aW5nKSkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgZGV0ZWN0ZWQgPSB0cnVlO1xuICAgIHN0YXRlLnBvc2l0aW9uKys7XG5cbiAgICBpZiAoc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpKSB7XG4gICAgICBpZiAoc3RhdGUubGluZUluZGVudCA8PSBub2RlSW5kZW50KSB7XG4gICAgICAgIF9yZXN1bHQucHVzaChudWxsKTtcbiAgICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgX2xpbmUgPSBzdGF0ZS5saW5lO1xuICAgIGNvbXBvc2VOb2RlKHN0YXRlLCBub2RlSW5kZW50LCBDT05URVhUX0JMT0NLX0lOLCBmYWxzZSwgdHJ1ZSk7XG4gICAgX3Jlc3VsdC5wdXNoKHN0YXRlLnJlc3VsdCk7XG4gICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpO1xuXG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICAgIGlmICgoc3RhdGUubGluZSA9PT0gX2xpbmUgfHwgc3RhdGUubGluZUluZGVudCA+IG5vZGVJbmRlbnQpICYmIChjaCAhPT0gMCkpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdiYWQgaW5kZW50YXRpb24gb2YgYSBzZXF1ZW5jZSBlbnRyeScpO1xuICAgIH0gZWxzZSBpZiAoc3RhdGUubGluZUluZGVudCA8IG5vZGVJbmRlbnQpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIGlmIChkZXRlY3RlZCkge1xuICAgIHN0YXRlLnRhZyA9IF90YWc7XG4gICAgc3RhdGUuYW5jaG9yID0gX2FuY2hvcjtcbiAgICBzdGF0ZS5raW5kID0gJ3NlcXVlbmNlJztcbiAgICBzdGF0ZS5yZXN1bHQgPSBfcmVzdWx0O1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gcmVhZEJsb2NrTWFwcGluZyhzdGF0ZSwgbm9kZUluZGVudCwgZmxvd0luZGVudCkge1xuICB2YXIgZm9sbG93aW5nLFxuICAgICAgYWxsb3dDb21wYWN0LFxuICAgICAgX2xpbmUsXG4gICAgICBfdGFnICAgICAgICAgID0gc3RhdGUudGFnLFxuICAgICAgX2FuY2hvciAgICAgICA9IHN0YXRlLmFuY2hvcixcbiAgICAgIF9yZXN1bHQgICAgICAgPSB7fSxcbiAgICAgIG92ZXJyaWRhYmxlS2V5cyA9IHt9LFxuICAgICAga2V5VGFnICAgICAgICA9IG51bGwsXG4gICAgICBrZXlOb2RlICAgICAgID0gbnVsbCxcbiAgICAgIHZhbHVlTm9kZSAgICAgPSBudWxsLFxuICAgICAgYXRFeHBsaWNpdEtleSA9IGZhbHNlLFxuICAgICAgZGV0ZWN0ZWQgICAgICA9IGZhbHNlLFxuICAgICAgY2g7XG5cbiAgaWYgKHN0YXRlLmFuY2hvciAhPT0gbnVsbCkge1xuICAgIHN0YXRlLmFuY2hvck1hcFtzdGF0ZS5hbmNob3JdID0gX3Jlc3VsdDtcbiAgfVxuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgd2hpbGUgKGNoICE9PSAwKSB7XG4gICAgZm9sbG93aW5nID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbiArIDEpO1xuICAgIF9saW5lID0gc3RhdGUubGluZTsgLy8gU2F2ZSB0aGUgY3VycmVudCBsaW5lLlxuXG4gICAgLy9cbiAgICAvLyBFeHBsaWNpdCBub3RhdGlvbiBjYXNlLiBUaGVyZSBhcmUgdHdvIHNlcGFyYXRlIGJsb2NrczpcbiAgICAvLyBmaXJzdCBmb3IgdGhlIGtleSAoZGVub3RlZCBieSBcIj9cIikgYW5kIHNlY29uZCBmb3IgdGhlIHZhbHVlIChkZW5vdGVkIGJ5IFwiOlwiKVxuICAgIC8vXG4gICAgaWYgKChjaCA9PT0gMHgzRi8qID8gKi8gfHwgY2ggPT09IDB4M0EvKiA6ICovKSAmJiBpc19XU19PUl9FT0woZm9sbG93aW5nKSkge1xuXG4gICAgICBpZiAoY2ggPT09IDB4M0YvKiA/ICovKSB7XG4gICAgICAgIGlmIChhdEV4cGxpY2l0S2V5KSB7XG4gICAgICAgICAgc3RvcmVNYXBwaW5nUGFpcihzdGF0ZSwgX3Jlc3VsdCwgb3ZlcnJpZGFibGVLZXlzLCBrZXlUYWcsIGtleU5vZGUsIG51bGwpO1xuICAgICAgICAgIGtleVRhZyA9IGtleU5vZGUgPSB2YWx1ZU5vZGUgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgZGV0ZWN0ZWQgPSB0cnVlO1xuICAgICAgICBhdEV4cGxpY2l0S2V5ID0gdHJ1ZTtcbiAgICAgICAgYWxsb3dDb21wYWN0ID0gdHJ1ZTtcblxuICAgICAgfSBlbHNlIGlmIChhdEV4cGxpY2l0S2V5KSB7XG4gICAgICAgIC8vIGkuZS4gMHgzQS8qIDogKi8gPT09IGNoYXJhY3RlciBhZnRlciB0aGUgZXhwbGljaXQga2V5LlxuICAgICAgICBhdEV4cGxpY2l0S2V5ID0gZmFsc2U7XG4gICAgICAgIGFsbG93Q29tcGFjdCA9IHRydWU7XG5cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdpbmNvbXBsZXRlIGV4cGxpY2l0IG1hcHBpbmcgcGFpcjsgYSBrZXkgbm9kZSBpcyBtaXNzZWQnKTtcbiAgICAgIH1cblxuICAgICAgc3RhdGUucG9zaXRpb24gKz0gMTtcbiAgICAgIGNoID0gZm9sbG93aW5nO1xuXG4gICAgLy9cbiAgICAvLyBJbXBsaWNpdCBub3RhdGlvbiBjYXNlLiBGbG93LXN0eWxlIG5vZGUgYXMgdGhlIGtleSBmaXJzdCwgdGhlbiBcIjpcIiwgYW5kIHRoZSB2YWx1ZS5cbiAgICAvL1xuICAgIH0gZWxzZSBpZiAoY29tcG9zZU5vZGUoc3RhdGUsIGZsb3dJbmRlbnQsIENPTlRFWFRfRkxPV19PVVQsIGZhbHNlLCB0cnVlKSkge1xuXG4gICAgICBpZiAoc3RhdGUubGluZSA9PT0gX2xpbmUpIHtcbiAgICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICAgICAgICB3aGlsZSAoaXNfV0hJVEVfU1BBQ0UoY2gpKSB7XG4gICAgICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNoID09PSAweDNBLyogOiAqLykge1xuICAgICAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcblxuICAgICAgICAgIGlmICghaXNfV1NfT1JfRU9MKGNoKSkge1xuICAgICAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2Egd2hpdGVzcGFjZSBjaGFyYWN0ZXIgaXMgZXhwZWN0ZWQgYWZ0ZXIgdGhlIGtleS12YWx1ZSBzZXBhcmF0b3Igd2l0aGluIGEgYmxvY2sgbWFwcGluZycpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChhdEV4cGxpY2l0S2V5KSB7XG4gICAgICAgICAgICBzdG9yZU1hcHBpbmdQYWlyKHN0YXRlLCBfcmVzdWx0LCBvdmVycmlkYWJsZUtleXMsIGtleVRhZywga2V5Tm9kZSwgbnVsbCk7XG4gICAgICAgICAgICBrZXlUYWcgPSBrZXlOb2RlID0gdmFsdWVOb2RlID0gbnVsbDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBkZXRlY3RlZCA9IHRydWU7XG4gICAgICAgICAgYXRFeHBsaWNpdEtleSA9IGZhbHNlO1xuICAgICAgICAgIGFsbG93Q29tcGFjdCA9IGZhbHNlO1xuICAgICAgICAgIGtleVRhZyA9IHN0YXRlLnRhZztcbiAgICAgICAgICBrZXlOb2RlID0gc3RhdGUucmVzdWx0O1xuXG4gICAgICAgIH0gZWxzZSBpZiAoZGV0ZWN0ZWQpIHtcbiAgICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnY2FuIG5vdCByZWFkIGFuIGltcGxpY2l0IG1hcHBpbmcgcGFpcjsgYSBjb2xvbiBpcyBtaXNzZWQnKTtcblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN0YXRlLnRhZyA9IF90YWc7XG4gICAgICAgICAgc3RhdGUuYW5jaG9yID0gX2FuY2hvcjtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTsgLy8gS2VlcCB0aGUgcmVzdWx0IG9mIGBjb21wb3NlTm9kZWAuXG4gICAgICAgIH1cblxuICAgICAgfSBlbHNlIGlmIChkZXRlY3RlZCkge1xuICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnY2FuIG5vdCByZWFkIGEgYmxvY2sgbWFwcGluZyBlbnRyeTsgYSBtdWx0aWxpbmUga2V5IG1heSBub3QgYmUgYW4gaW1wbGljaXQga2V5Jyk7XG5cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXRlLnRhZyA9IF90YWc7XG4gICAgICAgIHN0YXRlLmFuY2hvciA9IF9hbmNob3I7XG4gICAgICAgIHJldHVybiB0cnVlOyAvLyBLZWVwIHRoZSByZXN1bHQgb2YgYGNvbXBvc2VOb2RlYC5cbiAgICAgIH1cblxuICAgIH0gZWxzZSB7XG4gICAgICBicmVhazsgLy8gUmVhZGluZyBpcyBkb25lLiBHbyB0byB0aGUgZXBpbG9ndWUuXG4gICAgfVxuXG4gICAgLy9cbiAgICAvLyBDb21tb24gcmVhZGluZyBjb2RlIGZvciBib3RoIGV4cGxpY2l0IGFuZCBpbXBsaWNpdCBub3RhdGlvbnMuXG4gICAgLy9cbiAgICBpZiAoc3RhdGUubGluZSA9PT0gX2xpbmUgfHwgc3RhdGUubGluZUluZGVudCA+IG5vZGVJbmRlbnQpIHtcbiAgICAgIGlmIChjb21wb3NlTm9kZShzdGF0ZSwgbm9kZUluZGVudCwgQ09OVEVYVF9CTE9DS19PVVQsIHRydWUsIGFsbG93Q29tcGFjdCkpIHtcbiAgICAgICAgaWYgKGF0RXhwbGljaXRLZXkpIHtcbiAgICAgICAgICBrZXlOb2RlID0gc3RhdGUucmVzdWx0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhbHVlTm9kZSA9IHN0YXRlLnJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoIWF0RXhwbGljaXRLZXkpIHtcbiAgICAgICAgc3RvcmVNYXBwaW5nUGFpcihzdGF0ZSwgX3Jlc3VsdCwgb3ZlcnJpZGFibGVLZXlzLCBrZXlUYWcsIGtleU5vZGUsIHZhbHVlTm9kZSk7XG4gICAgICAgIGtleVRhZyA9IGtleU5vZGUgPSB2YWx1ZU5vZGUgPSBudWxsO1xuICAgICAgfVxuXG4gICAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCAtMSk7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuICAgIH1cblxuICAgIGlmIChzdGF0ZS5saW5lSW5kZW50ID4gbm9kZUluZGVudCAmJiAoY2ggIT09IDApKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnYmFkIGluZGVudGF0aW9uIG9mIGEgbWFwcGluZyBlbnRyeScpO1xuICAgIH0gZWxzZSBpZiAoc3RhdGUubGluZUluZGVudCA8IG5vZGVJbmRlbnQpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIC8vXG4gIC8vIEVwaWxvZ3VlLlxuICAvL1xuXG4gIC8vIFNwZWNpYWwgY2FzZTogbGFzdCBtYXBwaW5nJ3Mgbm9kZSBjb250YWlucyBvbmx5IHRoZSBrZXkgaW4gZXhwbGljaXQgbm90YXRpb24uXG4gIGlmIChhdEV4cGxpY2l0S2V5KSB7XG4gICAgc3RvcmVNYXBwaW5nUGFpcihzdGF0ZSwgX3Jlc3VsdCwgb3ZlcnJpZGFibGVLZXlzLCBrZXlUYWcsIGtleU5vZGUsIG51bGwpO1xuICB9XG5cbiAgLy8gRXhwb3NlIHRoZSByZXN1bHRpbmcgbWFwcGluZy5cbiAgaWYgKGRldGVjdGVkKSB7XG4gICAgc3RhdGUudGFnID0gX3RhZztcbiAgICBzdGF0ZS5hbmNob3IgPSBfYW5jaG9yO1xuICAgIHN0YXRlLmtpbmQgPSAnbWFwcGluZyc7XG4gICAgc3RhdGUucmVzdWx0ID0gX3Jlc3VsdDtcbiAgfVxuXG4gIHJldHVybiBkZXRlY3RlZDtcbn1cblxuZnVuY3Rpb24gcmVhZFRhZ1Byb3BlcnR5KHN0YXRlKSB7XG4gIHZhciBfcG9zaXRpb24sXG4gICAgICBpc1ZlcmJhdGltID0gZmFsc2UsXG4gICAgICBpc05hbWVkICAgID0gZmFsc2UsXG4gICAgICB0YWdIYW5kbGUsXG4gICAgICB0YWdOYW1lLFxuICAgICAgY2g7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoY2ggIT09IDB4MjEvKiAhICovKSByZXR1cm4gZmFsc2U7XG5cbiAgaWYgKHN0YXRlLnRhZyAhPT0gbnVsbCkge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICdkdXBsaWNhdGlvbiBvZiBhIHRhZyBwcm9wZXJ0eScpO1xuICB9XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmIChjaCA9PT0gMHgzQy8qIDwgKi8pIHtcbiAgICBpc1ZlcmJhdGltID0gdHJ1ZTtcbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgfSBlbHNlIGlmIChjaCA9PT0gMHgyMS8qICEgKi8pIHtcbiAgICBpc05hbWVkID0gdHJ1ZTtcbiAgICB0YWdIYW5kbGUgPSAnISEnO1xuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcblxuICB9IGVsc2Uge1xuICAgIHRhZ0hhbmRsZSA9ICchJztcbiAgfVxuXG4gIF9wb3NpdGlvbiA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gIGlmIChpc1ZlcmJhdGltKSB7XG4gICAgZG8geyBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7IH1cbiAgICB3aGlsZSAoY2ggIT09IDAgJiYgY2ggIT09IDB4M0UvKiA+ICovKTtcblxuICAgIGlmIChzdGF0ZS5wb3NpdGlvbiA8IHN0YXRlLmxlbmd0aCkge1xuICAgICAgdGFnTmFtZSA9IHN0YXRlLmlucHV0LnNsaWNlKF9wb3NpdGlvbiwgc3RhdGUucG9zaXRpb24pO1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndW5leHBlY3RlZCBlbmQgb2YgdGhlIHN0cmVhbSB3aXRoaW4gYSB2ZXJiYXRpbSB0YWcnKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgd2hpbGUgKGNoICE9PSAwICYmICFpc19XU19PUl9FT0woY2gpKSB7XG5cbiAgICAgIGlmIChjaCA9PT0gMHgyMS8qICEgKi8pIHtcbiAgICAgICAgaWYgKCFpc05hbWVkKSB7XG4gICAgICAgICAgdGFnSGFuZGxlID0gc3RhdGUuaW5wdXQuc2xpY2UoX3Bvc2l0aW9uIC0gMSwgc3RhdGUucG9zaXRpb24gKyAxKTtcblxuICAgICAgICAgIGlmICghUEFUVEVSTl9UQUdfSEFORExFLnRlc3QodGFnSGFuZGxlKSkge1xuICAgICAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ25hbWVkIHRhZyBoYW5kbGUgY2Fubm90IGNvbnRhaW4gc3VjaCBjaGFyYWN0ZXJzJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaXNOYW1lZCA9IHRydWU7XG4gICAgICAgICAgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb24gKyAxO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd0YWcgc3VmZml4IGNhbm5vdCBjb250YWluIGV4Y2xhbWF0aW9uIG1hcmtzJyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgIH1cblxuICAgIHRhZ05hbWUgPSBzdGF0ZS5pbnB1dC5zbGljZShfcG9zaXRpb24sIHN0YXRlLnBvc2l0aW9uKTtcblxuICAgIGlmIChQQVRURVJOX0ZMT1dfSU5ESUNBVE9SUy50ZXN0KHRhZ05hbWUpKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndGFnIHN1ZmZpeCBjYW5ub3QgY29udGFpbiBmbG93IGluZGljYXRvciBjaGFyYWN0ZXJzJyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHRhZ05hbWUgJiYgIVBBVFRFUk5fVEFHX1VSSS50ZXN0KHRhZ05hbWUpKSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3RhZyBuYW1lIGNhbm5vdCBjb250YWluIHN1Y2ggY2hhcmFjdGVyczogJyArIHRhZ05hbWUpO1xuICB9XG5cbiAgaWYgKGlzVmVyYmF0aW0pIHtcbiAgICBzdGF0ZS50YWcgPSB0YWdOYW1lO1xuXG4gIH0gZWxzZSBpZiAoX2hhc093blByb3BlcnR5LmNhbGwoc3RhdGUudGFnTWFwLCB0YWdIYW5kbGUpKSB7XG4gICAgc3RhdGUudGFnID0gc3RhdGUudGFnTWFwW3RhZ0hhbmRsZV0gKyB0YWdOYW1lO1xuXG4gIH0gZWxzZSBpZiAodGFnSGFuZGxlID09PSAnIScpIHtcbiAgICBzdGF0ZS50YWcgPSAnIScgKyB0YWdOYW1lO1xuXG4gIH0gZWxzZSBpZiAodGFnSGFuZGxlID09PSAnISEnKSB7XG4gICAgc3RhdGUudGFnID0gJ3RhZzp5YW1sLm9yZywyMDAyOicgKyB0YWdOYW1lO1xuXG4gIH0gZWxzZSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3VuZGVjbGFyZWQgdGFnIGhhbmRsZSBcIicgKyB0YWdIYW5kbGUgKyAnXCInKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiByZWFkQW5jaG9yUHJvcGVydHkoc3RhdGUpIHtcbiAgdmFyIF9wb3NpdGlvbixcbiAgICAgIGNoO1xuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgaWYgKGNoICE9PSAweDI2LyogJiAqLykgcmV0dXJuIGZhbHNlO1xuXG4gIGlmIChzdGF0ZS5hbmNob3IgIT09IG51bGwpIHtcbiAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZHVwbGljYXRpb24gb2YgYW4gYW5jaG9yIHByb3BlcnR5Jyk7XG4gIH1cblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gIF9wb3NpdGlvbiA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gIHdoaWxlIChjaCAhPT0gMCAmJiAhaXNfV1NfT1JfRU9MKGNoKSAmJiAhaXNfRkxPV19JTkRJQ0FUT1IoY2gpKSB7XG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICB9XG5cbiAgaWYgKHN0YXRlLnBvc2l0aW9uID09PSBfcG9zaXRpb24pIHtcbiAgICB0aHJvd0Vycm9yKHN0YXRlLCAnbmFtZSBvZiBhbiBhbmNob3Igbm9kZSBtdXN0IGNvbnRhaW4gYXQgbGVhc3Qgb25lIGNoYXJhY3RlcicpO1xuICB9XG5cbiAgc3RhdGUuYW5jaG9yID0gc3RhdGUuaW5wdXQuc2xpY2UoX3Bvc2l0aW9uLCBzdGF0ZS5wb3NpdGlvbik7XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiByZWFkQWxpYXMoc3RhdGUpIHtcbiAgdmFyIF9wb3NpdGlvbiwgYWxpYXMsXG4gICAgICBjaDtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmIChjaCAhPT0gMHgyQS8qICogKi8pIHJldHVybiBmYWxzZTtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gIF9wb3NpdGlvbiA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gIHdoaWxlIChjaCAhPT0gMCAmJiAhaXNfV1NfT1JfRU9MKGNoKSAmJiAhaXNfRkxPV19JTkRJQ0FUT1IoY2gpKSB7XG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICB9XG5cbiAgaWYgKHN0YXRlLnBvc2l0aW9uID09PSBfcG9zaXRpb24pIHtcbiAgICB0aHJvd0Vycm9yKHN0YXRlLCAnbmFtZSBvZiBhbiBhbGlhcyBub2RlIG11c3QgY29udGFpbiBhdCBsZWFzdCBvbmUgY2hhcmFjdGVyJyk7XG4gIH1cblxuICBhbGlhcyA9IHN0YXRlLmlucHV0LnNsaWNlKF9wb3NpdGlvbiwgc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmICghc3RhdGUuYW5jaG9yTWFwLmhhc093blByb3BlcnR5KGFsaWFzKSkge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICd1bmlkZW50aWZpZWQgYWxpYXMgXCInICsgYWxpYXMgKyAnXCInKTtcbiAgfVxuXG4gIHN0YXRlLnJlc3VsdCA9IHN0YXRlLmFuY2hvck1hcFthbGlhc107XG4gIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTtcbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGNvbXBvc2VOb2RlKHN0YXRlLCBwYXJlbnRJbmRlbnQsIG5vZGVDb250ZXh0LCBhbGxvd1RvU2VlaywgYWxsb3dDb21wYWN0KSB7XG4gIHZhciBhbGxvd0Jsb2NrU3R5bGVzLFxuICAgICAgYWxsb3dCbG9ja1NjYWxhcnMsXG4gICAgICBhbGxvd0Jsb2NrQ29sbGVjdGlvbnMsXG4gICAgICBpbmRlbnRTdGF0dXMgPSAxLCAvLyAxOiB0aGlzPnBhcmVudCwgMDogdGhpcz1wYXJlbnQsIC0xOiB0aGlzPHBhcmVudFxuICAgICAgYXROZXdMaW5lICA9IGZhbHNlLFxuICAgICAgaGFzQ29udGVudCA9IGZhbHNlLFxuICAgICAgdHlwZUluZGV4LFxuICAgICAgdHlwZVF1YW50aXR5LFxuICAgICAgdHlwZSxcbiAgICAgIGZsb3dJbmRlbnQsXG4gICAgICBibG9ja0luZGVudDtcblxuICBpZiAoc3RhdGUubGlzdGVuZXIgIT09IG51bGwpIHtcbiAgICBzdGF0ZS5saXN0ZW5lcignb3BlbicsIHN0YXRlKTtcbiAgfVxuXG4gIHN0YXRlLnRhZyAgICA9IG51bGw7XG4gIHN0YXRlLmFuY2hvciA9IG51bGw7XG4gIHN0YXRlLmtpbmQgICA9IG51bGw7XG4gIHN0YXRlLnJlc3VsdCA9IG51bGw7XG5cbiAgYWxsb3dCbG9ja1N0eWxlcyA9IGFsbG93QmxvY2tTY2FsYXJzID0gYWxsb3dCbG9ja0NvbGxlY3Rpb25zID1cbiAgICBDT05URVhUX0JMT0NLX09VVCA9PT0gbm9kZUNvbnRleHQgfHxcbiAgICBDT05URVhUX0JMT0NLX0lOICA9PT0gbm9kZUNvbnRleHQ7XG5cbiAgaWYgKGFsbG93VG9TZWVrKSB7XG4gICAgaWYgKHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKSkge1xuICAgICAgYXROZXdMaW5lID0gdHJ1ZTtcblxuICAgICAgaWYgKHN0YXRlLmxpbmVJbmRlbnQgPiBwYXJlbnRJbmRlbnQpIHtcbiAgICAgICAgaW5kZW50U3RhdHVzID0gMTtcbiAgICAgIH0gZWxzZSBpZiAoc3RhdGUubGluZUluZGVudCA9PT0gcGFyZW50SW5kZW50KSB7XG4gICAgICAgIGluZGVudFN0YXR1cyA9IDA7XG4gICAgICB9IGVsc2UgaWYgKHN0YXRlLmxpbmVJbmRlbnQgPCBwYXJlbnRJbmRlbnQpIHtcbiAgICAgICAgaW5kZW50U3RhdHVzID0gLTE7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKGluZGVudFN0YXR1cyA9PT0gMSkge1xuICAgIHdoaWxlIChyZWFkVGFnUHJvcGVydHkoc3RhdGUpIHx8IHJlYWRBbmNob3JQcm9wZXJ0eShzdGF0ZSkpIHtcbiAgICAgIGlmIChza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCAtMSkpIHtcbiAgICAgICAgYXROZXdMaW5lID0gdHJ1ZTtcbiAgICAgICAgYWxsb3dCbG9ja0NvbGxlY3Rpb25zID0gYWxsb3dCbG9ja1N0eWxlcztcblxuICAgICAgICBpZiAoc3RhdGUubGluZUluZGVudCA+IHBhcmVudEluZGVudCkge1xuICAgICAgICAgIGluZGVudFN0YXR1cyA9IDE7XG4gICAgICAgIH0gZWxzZSBpZiAoc3RhdGUubGluZUluZGVudCA9PT0gcGFyZW50SW5kZW50KSB7XG4gICAgICAgICAgaW5kZW50U3RhdHVzID0gMDtcbiAgICAgICAgfSBlbHNlIGlmIChzdGF0ZS5saW5lSW5kZW50IDwgcGFyZW50SW5kZW50KSB7XG4gICAgICAgICAgaW5kZW50U3RhdHVzID0gLTE7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFsbG93QmxvY2tDb2xsZWN0aW9ucyA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChhbGxvd0Jsb2NrQ29sbGVjdGlvbnMpIHtcbiAgICBhbGxvd0Jsb2NrQ29sbGVjdGlvbnMgPSBhdE5ld0xpbmUgfHwgYWxsb3dDb21wYWN0O1xuICB9XG5cbiAgaWYgKGluZGVudFN0YXR1cyA9PT0gMSB8fCBDT05URVhUX0JMT0NLX09VVCA9PT0gbm9kZUNvbnRleHQpIHtcbiAgICBpZiAoQ09OVEVYVF9GTE9XX0lOID09PSBub2RlQ29udGV4dCB8fCBDT05URVhUX0ZMT1dfT1VUID09PSBub2RlQ29udGV4dCkge1xuICAgICAgZmxvd0luZGVudCA9IHBhcmVudEluZGVudDtcbiAgICB9IGVsc2Uge1xuICAgICAgZmxvd0luZGVudCA9IHBhcmVudEluZGVudCArIDE7XG4gICAgfVxuXG4gICAgYmxvY2tJbmRlbnQgPSBzdGF0ZS5wb3NpdGlvbiAtIHN0YXRlLmxpbmVTdGFydDtcblxuICAgIGlmIChpbmRlbnRTdGF0dXMgPT09IDEpIHtcbiAgICAgIGlmIChhbGxvd0Jsb2NrQ29sbGVjdGlvbnMgJiZcbiAgICAgICAgICAocmVhZEJsb2NrU2VxdWVuY2Uoc3RhdGUsIGJsb2NrSW5kZW50KSB8fFxuICAgICAgICAgICByZWFkQmxvY2tNYXBwaW5nKHN0YXRlLCBibG9ja0luZGVudCwgZmxvd0luZGVudCkpIHx8XG4gICAgICAgICAgcmVhZEZsb3dDb2xsZWN0aW9uKHN0YXRlLCBmbG93SW5kZW50KSkge1xuICAgICAgICBoYXNDb250ZW50ID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICgoYWxsb3dCbG9ja1NjYWxhcnMgJiYgcmVhZEJsb2NrU2NhbGFyKHN0YXRlLCBmbG93SW5kZW50KSkgfHxcbiAgICAgICAgICAgIHJlYWRTaW5nbGVRdW90ZWRTY2FsYXIoc3RhdGUsIGZsb3dJbmRlbnQpIHx8XG4gICAgICAgICAgICByZWFkRG91YmxlUXVvdGVkU2NhbGFyKHN0YXRlLCBmbG93SW5kZW50KSkge1xuICAgICAgICAgIGhhc0NvbnRlbnQgPSB0cnVlO1xuXG4gICAgICAgIH0gZWxzZSBpZiAocmVhZEFsaWFzKHN0YXRlKSkge1xuICAgICAgICAgIGhhc0NvbnRlbnQgPSB0cnVlO1xuXG4gICAgICAgICAgaWYgKHN0YXRlLnRhZyAhPT0gbnVsbCB8fCBzdGF0ZS5hbmNob3IgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdhbGlhcyBub2RlIHNob3VsZCBub3QgaGF2ZSBhbnkgcHJvcGVydGllcycpO1xuICAgICAgICAgIH1cblxuICAgICAgICB9IGVsc2UgaWYgKHJlYWRQbGFpblNjYWxhcihzdGF0ZSwgZmxvd0luZGVudCwgQ09OVEVYVF9GTE9XX0lOID09PSBub2RlQ29udGV4dCkpIHtcbiAgICAgICAgICBoYXNDb250ZW50ID0gdHJ1ZTtcblxuICAgICAgICAgIGlmIChzdGF0ZS50YWcgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHN0YXRlLnRhZyA9ICc/JztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc3RhdGUuYW5jaG9yICE9PSBudWxsKSB7XG4gICAgICAgICAgc3RhdGUuYW5jaG9yTWFwW3N0YXRlLmFuY2hvcl0gPSBzdGF0ZS5yZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGluZGVudFN0YXR1cyA9PT0gMCkge1xuICAgICAgLy8gU3BlY2lhbCBjYXNlOiBibG9jayBzZXF1ZW5jZXMgYXJlIGFsbG93ZWQgdG8gaGF2ZSBzYW1lIGluZGVudGF0aW9uIGxldmVsIGFzIHRoZSBwYXJlbnQuXG4gICAgICAvLyBodHRwOi8vd3d3LnlhbWwub3JnL3NwZWMvMS4yL3NwZWMuaHRtbCNpZDI3OTk3ODRcbiAgICAgIGhhc0NvbnRlbnQgPSBhbGxvd0Jsb2NrQ29sbGVjdGlvbnMgJiYgcmVhZEJsb2NrU2VxdWVuY2Uoc3RhdGUsIGJsb2NrSW5kZW50KTtcbiAgICB9XG4gIH1cblxuICBpZiAoc3RhdGUudGFnICE9PSBudWxsICYmIHN0YXRlLnRhZyAhPT0gJyEnKSB7XG4gICAgaWYgKHN0YXRlLnRhZyA9PT0gJz8nKSB7XG4gICAgICBmb3IgKHR5cGVJbmRleCA9IDAsIHR5cGVRdWFudGl0eSA9IHN0YXRlLmltcGxpY2l0VHlwZXMubGVuZ3RoO1xuICAgICAgICAgICB0eXBlSW5kZXggPCB0eXBlUXVhbnRpdHk7XG4gICAgICAgICAgIHR5cGVJbmRleCArPSAxKSB7XG4gICAgICAgIHR5cGUgPSBzdGF0ZS5pbXBsaWNpdFR5cGVzW3R5cGVJbmRleF07XG5cbiAgICAgICAgLy8gSW1wbGljaXQgcmVzb2x2aW5nIGlzIG5vdCBhbGxvd2VkIGZvciBub24tc2NhbGFyIHR5cGVzLCBhbmQgJz8nXG4gICAgICAgIC8vIG5vbi1zcGVjaWZpYyB0YWcgaXMgb25seSBhc3NpZ25lZCB0byBwbGFpbiBzY2FsYXJzLiBTbywgaXQgaXNuJ3RcbiAgICAgICAgLy8gbmVlZGVkIHRvIGNoZWNrIGZvciAna2luZCcgY29uZm9ybWl0eS5cblxuICAgICAgICBpZiAodHlwZS5yZXNvbHZlKHN0YXRlLnJlc3VsdCkpIHsgLy8gYHN0YXRlLnJlc3VsdGAgdXBkYXRlZCBpbiByZXNvbHZlciBpZiBtYXRjaGVkXG4gICAgICAgICAgc3RhdGUucmVzdWx0ID0gdHlwZS5jb25zdHJ1Y3Qoc3RhdGUucmVzdWx0KTtcbiAgICAgICAgICBzdGF0ZS50YWcgPSB0eXBlLnRhZztcbiAgICAgICAgICBpZiAoc3RhdGUuYW5jaG9yICE9PSBudWxsKSB7XG4gICAgICAgICAgICBzdGF0ZS5hbmNob3JNYXBbc3RhdGUuYW5jaG9yXSA9IHN0YXRlLnJlc3VsdDtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKF9oYXNPd25Qcm9wZXJ0eS5jYWxsKHN0YXRlLnR5cGVNYXAsIHN0YXRlLnRhZykpIHtcbiAgICAgIHR5cGUgPSBzdGF0ZS50eXBlTWFwW3N0YXRlLnRhZ107XG5cbiAgICAgIGlmIChzdGF0ZS5yZXN1bHQgIT09IG51bGwgJiYgdHlwZS5raW5kICE9PSBzdGF0ZS5raW5kKSB7XG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd1bmFjY2VwdGFibGUgbm9kZSBraW5kIGZvciAhPCcgKyBzdGF0ZS50YWcgKyAnPiB0YWc7IGl0IHNob3VsZCBiZSBcIicgKyB0eXBlLmtpbmQgKyAnXCIsIG5vdCBcIicgKyBzdGF0ZS5raW5kICsgJ1wiJyk7XG4gICAgICB9XG5cbiAgICAgIGlmICghdHlwZS5yZXNvbHZlKHN0YXRlLnJlc3VsdCkpIHsgLy8gYHN0YXRlLnJlc3VsdGAgdXBkYXRlZCBpbiByZXNvbHZlciBpZiBtYXRjaGVkXG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdjYW5ub3QgcmVzb2x2ZSBhIG5vZGUgd2l0aCAhPCcgKyBzdGF0ZS50YWcgKyAnPiBleHBsaWNpdCB0YWcnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXRlLnJlc3VsdCA9IHR5cGUuY29uc3RydWN0KHN0YXRlLnJlc3VsdCk7XG4gICAgICAgIGlmIChzdGF0ZS5hbmNob3IgIT09IG51bGwpIHtcbiAgICAgICAgICBzdGF0ZS5hbmNob3JNYXBbc3RhdGUuYW5jaG9yXSA9IHN0YXRlLnJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndW5rbm93biB0YWcgITwnICsgc3RhdGUudGFnICsgJz4nKTtcbiAgICB9XG4gIH1cblxuICBpZiAoc3RhdGUubGlzdGVuZXIgIT09IG51bGwpIHtcbiAgICBzdGF0ZS5saXN0ZW5lcignY2xvc2UnLCBzdGF0ZSk7XG4gIH1cbiAgcmV0dXJuIHN0YXRlLnRhZyAhPT0gbnVsbCB8fCAgc3RhdGUuYW5jaG9yICE9PSBudWxsIHx8IGhhc0NvbnRlbnQ7XG59XG5cbmZ1bmN0aW9uIHJlYWREb2N1bWVudChzdGF0ZSkge1xuICB2YXIgZG9jdW1lbnRTdGFydCA9IHN0YXRlLnBvc2l0aW9uLFxuICAgICAgX3Bvc2l0aW9uLFxuICAgICAgZGlyZWN0aXZlTmFtZSxcbiAgICAgIGRpcmVjdGl2ZUFyZ3MsXG4gICAgICBoYXNEaXJlY3RpdmVzID0gZmFsc2UsXG4gICAgICBjaDtcblxuICBzdGF0ZS52ZXJzaW9uID0gbnVsbDtcbiAgc3RhdGUuY2hlY2tMaW5lQnJlYWtzID0gc3RhdGUubGVnYWN5O1xuICBzdGF0ZS50YWdNYXAgPSB7fTtcbiAgc3RhdGUuYW5jaG9yTWFwID0ge307XG5cbiAgd2hpbGUgKChjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pKSAhPT0gMCkge1xuICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTtcblxuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICBpZiAoc3RhdGUubGluZUluZGVudCA+IDAgfHwgY2ggIT09IDB4MjUvKiAlICovKSB7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBoYXNEaXJlY3RpdmVzID0gdHJ1ZTtcbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb247XG5cbiAgICB3aGlsZSAoY2ggIT09IDAgJiYgIWlzX1dTX09SX0VPTChjaCkpIHtcbiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgICB9XG5cbiAgICBkaXJlY3RpdmVOYW1lID0gc3RhdGUuaW5wdXQuc2xpY2UoX3Bvc2l0aW9uLCBzdGF0ZS5wb3NpdGlvbik7XG4gICAgZGlyZWN0aXZlQXJncyA9IFtdO1xuXG4gICAgaWYgKGRpcmVjdGl2ZU5hbWUubGVuZ3RoIDwgMSkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2RpcmVjdGl2ZSBuYW1lIG11c3Qgbm90IGJlIGxlc3MgdGhhbiBvbmUgY2hhcmFjdGVyIGluIGxlbmd0aCcpO1xuICAgIH1cblxuICAgIHdoaWxlIChjaCAhPT0gMCkge1xuICAgICAgd2hpbGUgKGlzX1dISVRFX1NQQUNFKGNoKSkge1xuICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgICB9XG5cbiAgICAgIGlmIChjaCA9PT0gMHgyMy8qICMgKi8pIHtcbiAgICAgICAgZG8geyBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7IH1cbiAgICAgICAgd2hpbGUgKGNoICE9PSAwICYmICFpc19FT0woY2gpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc19FT0woY2gpKSBicmVhaztcblxuICAgICAgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb247XG5cbiAgICAgIHdoaWxlIChjaCAhPT0gMCAmJiAhaXNfV1NfT1JfRU9MKGNoKSkge1xuICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgICB9XG5cbiAgICAgIGRpcmVjdGl2ZUFyZ3MucHVzaChzdGF0ZS5pbnB1dC5zbGljZShfcG9zaXRpb24sIHN0YXRlLnBvc2l0aW9uKSk7XG4gICAgfVxuXG4gICAgaWYgKGNoICE9PSAwKSByZWFkTGluZUJyZWFrKHN0YXRlKTtcblxuICAgIGlmIChfaGFzT3duUHJvcGVydHkuY2FsbChkaXJlY3RpdmVIYW5kbGVycywgZGlyZWN0aXZlTmFtZSkpIHtcbiAgICAgIGRpcmVjdGl2ZUhhbmRsZXJzW2RpcmVjdGl2ZU5hbWVdKHN0YXRlLCBkaXJlY3RpdmVOYW1lLCBkaXJlY3RpdmVBcmdzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3dXYXJuaW5nKHN0YXRlLCAndW5rbm93biBkb2N1bWVudCBkaXJlY3RpdmUgXCInICsgZGlyZWN0aXZlTmFtZSArICdcIicpO1xuICAgIH1cbiAgfVxuXG4gIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTtcblxuICBpZiAoc3RhdGUubGluZUluZGVudCA9PT0gMCAmJlxuICAgICAgc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbikgICAgID09PSAweDJELyogLSAqLyAmJlxuICAgICAgc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbiArIDEpID09PSAweDJELyogLSAqLyAmJlxuICAgICAgc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbiArIDIpID09PSAweDJELyogLSAqLykge1xuICAgIHN0YXRlLnBvc2l0aW9uICs9IDM7XG4gICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpO1xuXG4gIH0gZWxzZSBpZiAoaGFzRGlyZWN0aXZlcykge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICdkaXJlY3RpdmVzIGVuZCBtYXJrIGlzIGV4cGVjdGVkJyk7XG4gIH1cblxuICBjb21wb3NlTm9kZShzdGF0ZSwgc3RhdGUubGluZUluZGVudCAtIDEsIENPTlRFWFRfQkxPQ0tfT1VULCBmYWxzZSwgdHJ1ZSk7XG4gIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTtcblxuICBpZiAoc3RhdGUuY2hlY2tMaW5lQnJlYWtzICYmXG4gICAgICBQQVRURVJOX05PTl9BU0NJSV9MSU5FX0JSRUFLUy50ZXN0KHN0YXRlLmlucHV0LnNsaWNlKGRvY3VtZW50U3RhcnQsIHN0YXRlLnBvc2l0aW9uKSkpIHtcbiAgICB0aHJvd1dhcm5pbmcoc3RhdGUsICdub24tQVNDSUkgbGluZSBicmVha3MgYXJlIGludGVycHJldGVkIGFzIGNvbnRlbnQnKTtcbiAgfVxuXG4gIHN0YXRlLmRvY3VtZW50cy5wdXNoKHN0YXRlLnJlc3VsdCk7XG5cbiAgaWYgKHN0YXRlLnBvc2l0aW9uID09PSBzdGF0ZS5saW5lU3RhcnQgJiYgdGVzdERvY3VtZW50U2VwYXJhdG9yKHN0YXRlKSkge1xuXG4gICAgaWYgKHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pID09PSAweDJFLyogLiAqLykge1xuICAgICAgc3RhdGUucG9zaXRpb24gKz0gMztcbiAgICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTtcbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKHN0YXRlLnBvc2l0aW9uIDwgKHN0YXRlLmxlbmd0aCAtIDEpKSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2VuZCBvZiB0aGUgc3RyZWFtIG9yIGEgZG9jdW1lbnQgc2VwYXJhdG9yIGlzIGV4cGVjdGVkJyk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuO1xuICB9XG59XG5cblxuZnVuY3Rpb24gbG9hZERvY3VtZW50cyhpbnB1dCwgb3B0aW9ucykge1xuICBpbnB1dCA9IFN0cmluZyhpbnB1dCk7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIGlmIChpbnB1dC5sZW5ndGggIT09IDApIHtcblxuICAgIC8vIEFkZCB0YWlsaW5nIGBcXG5gIGlmIG5vdCBleGlzdHNcbiAgICBpZiAoaW5wdXQuY2hhckNvZGVBdChpbnB1dC5sZW5ndGggLSAxKSAhPT0gMHgwQS8qIExGICovICYmXG4gICAgICAgIGlucHV0LmNoYXJDb2RlQXQoaW5wdXQubGVuZ3RoIC0gMSkgIT09IDB4MEQvKiBDUiAqLykge1xuICAgICAgaW5wdXQgKz0gJ1xcbic7XG4gICAgfVxuXG4gICAgLy8gU3RyaXAgQk9NXG4gICAgaWYgKGlucHV0LmNoYXJDb2RlQXQoMCkgPT09IDB4RkVGRikge1xuICAgICAgaW5wdXQgPSBpbnB1dC5zbGljZSgxKTtcbiAgICB9XG4gIH1cblxuICB2YXIgc3RhdGUgPSBuZXcgU3RhdGUoaW5wdXQsIG9wdGlvbnMpO1xuXG4gIC8vIFVzZSAwIGFzIHN0cmluZyB0ZXJtaW5hdG9yLiBUaGF0IHNpZ25pZmljYW50bHkgc2ltcGxpZmllcyBib3VuZHMgY2hlY2suXG4gIHN0YXRlLmlucHV0ICs9ICdcXDAnO1xuXG4gIHdoaWxlIChzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKSA9PT0gMHgyMC8qIFNwYWNlICovKSB7XG4gICAgc3RhdGUubGluZUluZGVudCArPSAxO1xuICAgIHN0YXRlLnBvc2l0aW9uICs9IDE7XG4gIH1cblxuICB3aGlsZSAoc3RhdGUucG9zaXRpb24gPCAoc3RhdGUubGVuZ3RoIC0gMSkpIHtcbiAgICByZWFkRG9jdW1lbnQoc3RhdGUpO1xuICB9XG5cbiAgcmV0dXJuIHN0YXRlLmRvY3VtZW50cztcbn1cblxuXG5mdW5jdGlvbiBsb2FkQWxsKGlucHV0LCBpdGVyYXRvciwgb3B0aW9ucykge1xuICB2YXIgZG9jdW1lbnRzID0gbG9hZERvY3VtZW50cyhpbnB1dCwgb3B0aW9ucyksIGluZGV4LCBsZW5ndGg7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IGRvY3VtZW50cy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgaXRlcmF0b3IoZG9jdW1lbnRzW2luZGV4XSk7XG4gIH1cbn1cblxuXG5mdW5jdGlvbiBsb2FkKGlucHV0LCBvcHRpb25zKSB7XG4gIHZhciBkb2N1bWVudHMgPSBsb2FkRG9jdW1lbnRzKGlucHV0LCBvcHRpb25zKTtcblxuICBpZiAoZG9jdW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgIC8qZXNsaW50LWRpc2FibGUgbm8tdW5kZWZpbmVkKi9cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9IGVsc2UgaWYgKGRvY3VtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICByZXR1cm4gZG9jdW1lbnRzWzBdO1xuICB9XG4gIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdleHBlY3RlZCBhIHNpbmdsZSBkb2N1bWVudCBpbiB0aGUgc3RyZWFtLCBidXQgZm91bmQgbW9yZScpO1xufVxuXG5cbmZ1bmN0aW9uIHNhZmVMb2FkQWxsKGlucHV0LCBvdXRwdXQsIG9wdGlvbnMpIHtcbiAgbG9hZEFsbChpbnB1dCwgb3V0cHV0LCBjb21tb24uZXh0ZW5kKHsgc2NoZW1hOiBERUZBVUxUX1NBRkVfU0NIRU1BIH0sIG9wdGlvbnMpKTtcbn1cblxuXG5mdW5jdGlvbiBzYWZlTG9hZChpbnB1dCwgb3B0aW9ucykge1xuICByZXR1cm4gbG9hZChpbnB1dCwgY29tbW9uLmV4dGVuZCh7IHNjaGVtYTogREVGQVVMVF9TQUZFX1NDSEVNQSB9LCBvcHRpb25zKSk7XG59XG5cblxubW9kdWxlLmV4cG9ydHMubG9hZEFsbCAgICAgPSBsb2FkQWxsO1xubW9kdWxlLmV4cG9ydHMubG9hZCAgICAgICAgPSBsb2FkO1xubW9kdWxlLmV4cG9ydHMuc2FmZUxvYWRBbGwgPSBzYWZlTG9hZEFsbDtcbm1vZHVsZS5leHBvcnRzLnNhZmVMb2FkICAgID0gc2FmZUxvYWQ7XG4iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG5cblxuZnVuY3Rpb24gTWFyayhuYW1lLCBidWZmZXIsIHBvc2l0aW9uLCBsaW5lLCBjb2x1bW4pIHtcbiAgdGhpcy5uYW1lICAgICA9IG5hbWU7XG4gIHRoaXMuYnVmZmVyICAgPSBidWZmZXI7XG4gIHRoaXMucG9zaXRpb24gPSBwb3NpdGlvbjtcbiAgdGhpcy5saW5lICAgICA9IGxpbmU7XG4gIHRoaXMuY29sdW1uICAgPSBjb2x1bW47XG59XG5cblxuTWFyay5wcm90b3R5cGUuZ2V0U25pcHBldCA9IGZ1bmN0aW9uIGdldFNuaXBwZXQoaW5kZW50LCBtYXhMZW5ndGgpIHtcbiAgdmFyIGhlYWQsIHN0YXJ0LCB0YWlsLCBlbmQsIHNuaXBwZXQ7XG5cbiAgaWYgKCF0aGlzLmJ1ZmZlcikgcmV0dXJuIG51bGw7XG5cbiAgaW5kZW50ID0gaW5kZW50IHx8IDQ7XG4gIG1heExlbmd0aCA9IG1heExlbmd0aCB8fCA3NTtcblxuICBoZWFkID0gJyc7XG4gIHN0YXJ0ID0gdGhpcy5wb3NpdGlvbjtcblxuICB3aGlsZSAoc3RhcnQgPiAwICYmICdcXHgwMFxcclxcblxceDg1XFx1MjAyOFxcdTIwMjknLmluZGV4T2YodGhpcy5idWZmZXIuY2hhckF0KHN0YXJ0IC0gMSkpID09PSAtMSkge1xuICAgIHN0YXJ0IC09IDE7XG4gICAgaWYgKHRoaXMucG9zaXRpb24gLSBzdGFydCA+IChtYXhMZW5ndGggLyAyIC0gMSkpIHtcbiAgICAgIGhlYWQgPSAnIC4uLiAnO1xuICAgICAgc3RhcnQgKz0gNTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHRhaWwgPSAnJztcbiAgZW5kID0gdGhpcy5wb3NpdGlvbjtcblxuICB3aGlsZSAoZW5kIDwgdGhpcy5idWZmZXIubGVuZ3RoICYmICdcXHgwMFxcclxcblxceDg1XFx1MjAyOFxcdTIwMjknLmluZGV4T2YodGhpcy5idWZmZXIuY2hhckF0KGVuZCkpID09PSAtMSkge1xuICAgIGVuZCArPSAxO1xuICAgIGlmIChlbmQgLSB0aGlzLnBvc2l0aW9uID4gKG1heExlbmd0aCAvIDIgLSAxKSkge1xuICAgICAgdGFpbCA9ICcgLi4uICc7XG4gICAgICBlbmQgLT0gNTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHNuaXBwZXQgPSB0aGlzLmJ1ZmZlci5zbGljZShzdGFydCwgZW5kKTtcblxuICByZXR1cm4gY29tbW9uLnJlcGVhdCgnICcsIGluZGVudCkgKyBoZWFkICsgc25pcHBldCArIHRhaWwgKyAnXFxuJyArXG4gICAgICAgICBjb21tb24ucmVwZWF0KCcgJywgaW5kZW50ICsgdGhpcy5wb3NpdGlvbiAtIHN0YXJ0ICsgaGVhZC5sZW5ndGgpICsgJ14nO1xufTtcblxuXG5NYXJrLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKGNvbXBhY3QpIHtcbiAgdmFyIHNuaXBwZXQsIHdoZXJlID0gJyc7XG5cbiAgaWYgKHRoaXMubmFtZSkge1xuICAgIHdoZXJlICs9ICdpbiBcIicgKyB0aGlzLm5hbWUgKyAnXCIgJztcbiAgfVxuXG4gIHdoZXJlICs9ICdhdCBsaW5lICcgKyAodGhpcy5saW5lICsgMSkgKyAnLCBjb2x1bW4gJyArICh0aGlzLmNvbHVtbiArIDEpO1xuXG4gIGlmICghY29tcGFjdCkge1xuICAgIHNuaXBwZXQgPSB0aGlzLmdldFNuaXBwZXQoKTtcblxuICAgIGlmIChzbmlwcGV0KSB7XG4gICAgICB3aGVyZSArPSAnOlxcbicgKyBzbmlwcGV0O1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB3aGVyZTtcbn07XG5cblxubW9kdWxlLmV4cG9ydHMgPSBNYXJrO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKmVzbGludC1kaXNhYmxlIG1heC1sZW4qL1xuXG52YXIgY29tbW9uICAgICAgICA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgWUFNTEV4Y2VwdGlvbiA9IHJlcXVpcmUoJy4vZXhjZXB0aW9uJyk7XG52YXIgVHlwZSAgICAgICAgICA9IHJlcXVpcmUoJy4vdHlwZScpO1xuXG5cbmZ1bmN0aW9uIGNvbXBpbGVMaXN0KHNjaGVtYSwgbmFtZSwgcmVzdWx0KSB7XG4gIHZhciBleGNsdWRlID0gW107XG5cbiAgc2NoZW1hLmluY2x1ZGUuZm9yRWFjaChmdW5jdGlvbiAoaW5jbHVkZWRTY2hlbWEpIHtcbiAgICByZXN1bHQgPSBjb21waWxlTGlzdChpbmNsdWRlZFNjaGVtYSwgbmFtZSwgcmVzdWx0KTtcbiAgfSk7XG5cbiAgc2NoZW1hW25hbWVdLmZvckVhY2goZnVuY3Rpb24gKGN1cnJlbnRUeXBlKSB7XG4gICAgcmVzdWx0LmZvckVhY2goZnVuY3Rpb24gKHByZXZpb3VzVHlwZSwgcHJldmlvdXNJbmRleCkge1xuICAgICAgaWYgKHByZXZpb3VzVHlwZS50YWcgPT09IGN1cnJlbnRUeXBlLnRhZykge1xuICAgICAgICBleGNsdWRlLnB1c2gocHJldmlvdXNJbmRleCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXN1bHQucHVzaChjdXJyZW50VHlwZSk7XG4gIH0pO1xuXG4gIHJldHVybiByZXN1bHQuZmlsdGVyKGZ1bmN0aW9uICh0eXBlLCBpbmRleCkge1xuICAgIHJldHVybiBleGNsdWRlLmluZGV4T2YoaW5kZXgpID09PSAtMTtcbiAgfSk7XG59XG5cblxuZnVuY3Rpb24gY29tcGlsZU1hcCgvKiBsaXN0cy4uLiAqLykge1xuICB2YXIgcmVzdWx0ID0ge30sIGluZGV4LCBsZW5ndGg7XG5cbiAgZnVuY3Rpb24gY29sbGVjdFR5cGUodHlwZSkge1xuICAgIHJlc3VsdFt0eXBlLnRhZ10gPSB0eXBlO1xuICB9XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgYXJndW1lbnRzW2luZGV4XS5mb3JFYWNoKGNvbGxlY3RUeXBlKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cblxuZnVuY3Rpb24gU2NoZW1hKGRlZmluaXRpb24pIHtcbiAgdGhpcy5pbmNsdWRlICA9IGRlZmluaXRpb24uaW5jbHVkZSAgfHwgW107XG4gIHRoaXMuaW1wbGljaXQgPSBkZWZpbml0aW9uLmltcGxpY2l0IHx8IFtdO1xuICB0aGlzLmV4cGxpY2l0ID0gZGVmaW5pdGlvbi5leHBsaWNpdCB8fCBbXTtcblxuICB0aGlzLmltcGxpY2l0LmZvckVhY2goZnVuY3Rpb24gKHR5cGUpIHtcbiAgICBpZiAodHlwZS5sb2FkS2luZCAmJiB0eXBlLmxvYWRLaW5kICE9PSAnc2NhbGFyJykge1xuICAgICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ1RoZXJlIGlzIGEgbm9uLXNjYWxhciB0eXBlIGluIHRoZSBpbXBsaWNpdCBsaXN0IG9mIGEgc2NoZW1hLiBJbXBsaWNpdCByZXNvbHZpbmcgb2Ygc3VjaCB0eXBlcyBpcyBub3Qgc3VwcG9ydGVkLicpO1xuICAgIH1cbiAgfSk7XG5cbiAgdGhpcy5jb21waWxlZEltcGxpY2l0ID0gY29tcGlsZUxpc3QodGhpcywgJ2ltcGxpY2l0JywgW10pO1xuICB0aGlzLmNvbXBpbGVkRXhwbGljaXQgPSBjb21waWxlTGlzdCh0aGlzLCAnZXhwbGljaXQnLCBbXSk7XG4gIHRoaXMuY29tcGlsZWRUeXBlTWFwICA9IGNvbXBpbGVNYXAodGhpcy5jb21waWxlZEltcGxpY2l0LCB0aGlzLmNvbXBpbGVkRXhwbGljaXQpO1xufVxuXG5cblNjaGVtYS5ERUZBVUxUID0gbnVsbDtcblxuXG5TY2hlbWEuY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlU2NoZW1hKCkge1xuICB2YXIgc2NoZW1hcywgdHlwZXM7XG5cbiAgc3dpdGNoIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgY2FzZSAxOlxuICAgICAgc2NoZW1hcyA9IFNjaGVtYS5ERUZBVUxUO1xuICAgICAgdHlwZXMgPSBhcmd1bWVudHNbMF07XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgMjpcbiAgICAgIHNjaGVtYXMgPSBhcmd1bWVudHNbMF07XG4gICAgICB0eXBlcyA9IGFyZ3VtZW50c1sxXTtcbiAgICAgIGJyZWFrO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdXcm9uZyBudW1iZXIgb2YgYXJndW1lbnRzIGZvciBTY2hlbWEuY3JlYXRlIGZ1bmN0aW9uJyk7XG4gIH1cblxuICBzY2hlbWFzID0gY29tbW9uLnRvQXJyYXkoc2NoZW1hcyk7XG4gIHR5cGVzID0gY29tbW9uLnRvQXJyYXkodHlwZXMpO1xuXG4gIGlmICghc2NoZW1hcy5ldmVyeShmdW5jdGlvbiAoc2NoZW1hKSB7IHJldHVybiBzY2hlbWEgaW5zdGFuY2VvZiBTY2hlbWE7IH0pKSB7XG4gICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ1NwZWNpZmllZCBsaXN0IG9mIHN1cGVyIHNjaGVtYXMgKG9yIGEgc2luZ2xlIFNjaGVtYSBvYmplY3QpIGNvbnRhaW5zIGEgbm9uLVNjaGVtYSBvYmplY3QuJyk7XG4gIH1cblxuICBpZiAoIXR5cGVzLmV2ZXJ5KGZ1bmN0aW9uICh0eXBlKSB7IHJldHVybiB0eXBlIGluc3RhbmNlb2YgVHlwZTsgfSkpIHtcbiAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignU3BlY2lmaWVkIGxpc3Qgb2YgWUFNTCB0eXBlcyAob3IgYSBzaW5nbGUgVHlwZSBvYmplY3QpIGNvbnRhaW5zIGEgbm9uLVR5cGUgb2JqZWN0LicpO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBTY2hlbWEoe1xuICAgIGluY2x1ZGU6IHNjaGVtYXMsXG4gICAgZXhwbGljaXQ6IHR5cGVzXG4gIH0pO1xufTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IFNjaGVtYTtcbiIsIi8vIFN0YW5kYXJkIFlBTUwncyBDb3JlIHNjaGVtYS5cbi8vIGh0dHA6Ly93d3cueWFtbC5vcmcvc3BlYy8xLjIvc3BlYy5odG1sI2lkMjgwNDkyM1xuLy9cbi8vIE5PVEU6IEpTLVlBTUwgZG9lcyBub3Qgc3VwcG9ydCBzY2hlbWEtc3BlY2lmaWMgdGFnIHJlc29sdXRpb24gcmVzdHJpY3Rpb25zLlxuLy8gU28sIENvcmUgc2NoZW1hIGhhcyBubyBkaXN0aW5jdGlvbnMgZnJvbSBKU09OIHNjaGVtYSBpcyBKUy1ZQU1MLlxuXG5cbid1c2Ugc3RyaWN0JztcblxuXG52YXIgU2NoZW1hID0gcmVxdWlyZSgnLi4vc2NoZW1hJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgU2NoZW1hKHtcbiAgaW5jbHVkZTogW1xuICAgIHJlcXVpcmUoJy4vanNvbicpXG4gIF1cbn0pO1xuIiwiLy8gSlMtWUFNTCdzIGRlZmF1bHQgc2NoZW1hIGZvciBgbG9hZGAgZnVuY3Rpb24uXG4vLyBJdCBpcyBub3QgZGVzY3JpYmVkIGluIHRoZSBZQU1MIHNwZWNpZmljYXRpb24uXG4vL1xuLy8gVGhpcyBzY2hlbWEgaXMgYmFzZWQgb24gSlMtWUFNTCdzIGRlZmF1bHQgc2FmZSBzY2hlbWEgYW5kIGluY2x1ZGVzXG4vLyBKYXZhU2NyaXB0LXNwZWNpZmljIHR5cGVzOiAhIWpzL3VuZGVmaW5lZCwgISFqcy9yZWdleHAgYW5kICEhanMvZnVuY3Rpb24uXG4vL1xuLy8gQWxzbyB0aGlzIHNjaGVtYSBpcyB1c2VkIGFzIGRlZmF1bHQgYmFzZSBzY2hlbWEgYXQgYFNjaGVtYS5jcmVhdGVgIGZ1bmN0aW9uLlxuXG5cbid1c2Ugc3RyaWN0JztcblxuXG52YXIgU2NoZW1hID0gcmVxdWlyZSgnLi4vc2NoZW1hJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBTY2hlbWEuREVGQVVMVCA9IG5ldyBTY2hlbWEoe1xuICBpbmNsdWRlOiBbXG4gICAgcmVxdWlyZSgnLi9kZWZhdWx0X3NhZmUnKVxuICBdLFxuICBleHBsaWNpdDogW1xuICAgIHJlcXVpcmUoJy4uL3R5cGUvanMvdW5kZWZpbmVkJyksXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9qcy9yZWdleHAnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL2pzL2Z1bmN0aW9uJylcbiAgXVxufSk7XG4iLCIvLyBKUy1ZQU1MJ3MgZGVmYXVsdCBzY2hlbWEgZm9yIGBzYWZlTG9hZGAgZnVuY3Rpb24uXG4vLyBJdCBpcyBub3QgZGVzY3JpYmVkIGluIHRoZSBZQU1MIHNwZWNpZmljYXRpb24uXG4vL1xuLy8gVGhpcyBzY2hlbWEgaXMgYmFzZWQgb24gc3RhbmRhcmQgWUFNTCdzIENvcmUgc2NoZW1hIGFuZCBpbmNsdWRlcyBtb3N0IG9mXG4vLyBleHRyYSB0eXBlcyBkZXNjcmliZWQgYXQgWUFNTCB0YWcgcmVwb3NpdG9yeS4gKGh0dHA6Ly95YW1sLm9yZy90eXBlLylcblxuXG4ndXNlIHN0cmljdCc7XG5cblxudmFyIFNjaGVtYSA9IHJlcXVpcmUoJy4uL3NjaGVtYScpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFNjaGVtYSh7XG4gIGluY2x1ZGU6IFtcbiAgICByZXF1aXJlKCcuL2NvcmUnKVxuICBdLFxuICBpbXBsaWNpdDogW1xuICAgIHJlcXVpcmUoJy4uL3R5cGUvdGltZXN0YW1wJyksXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9tZXJnZScpXG4gIF0sXG4gIGV4cGxpY2l0OiBbXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9iaW5hcnknKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL29tYXAnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL3BhaXJzJyksXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9zZXQnKVxuICBdXG59KTtcbiIsIi8vIFN0YW5kYXJkIFlBTUwncyBGYWlsc2FmZSBzY2hlbWEuXG4vLyBodHRwOi8vd3d3LnlhbWwub3JnL3NwZWMvMS4yL3NwZWMuaHRtbCNpZDI4MDIzNDZcblxuXG4ndXNlIHN0cmljdCc7XG5cblxudmFyIFNjaGVtYSA9IHJlcXVpcmUoJy4uL3NjaGVtYScpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFNjaGVtYSh7XG4gIGV4cGxpY2l0OiBbXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9zdHInKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL3NlcScpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvbWFwJylcbiAgXVxufSk7XG4iLCIvLyBTdGFuZGFyZCBZQU1MJ3MgSlNPTiBzY2hlbWEuXG4vLyBodHRwOi8vd3d3LnlhbWwub3JnL3NwZWMvMS4yL3NwZWMuaHRtbCNpZDI4MDMyMzFcbi8vXG4vLyBOT1RFOiBKUy1ZQU1MIGRvZXMgbm90IHN1cHBvcnQgc2NoZW1hLXNwZWNpZmljIHRhZyByZXNvbHV0aW9uIHJlc3RyaWN0aW9ucy5cbi8vIFNvLCB0aGlzIHNjaGVtYSBpcyBub3Qgc3VjaCBzdHJpY3QgYXMgZGVmaW5lZCBpbiB0aGUgWUFNTCBzcGVjaWZpY2F0aW9uLlxuLy8gSXQgYWxsb3dzIG51bWJlcnMgaW4gYmluYXJ5IG5vdGFpb24sIHVzZSBgTnVsbGAgYW5kIGBOVUxMYCBhcyBgbnVsbGAsIGV0Yy5cblxuXG4ndXNlIHN0cmljdCc7XG5cblxudmFyIFNjaGVtYSA9IHJlcXVpcmUoJy4uL3NjaGVtYScpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFNjaGVtYSh7XG4gIGluY2x1ZGU6IFtcbiAgICByZXF1aXJlKCcuL2ZhaWxzYWZlJylcbiAgXSxcbiAgaW1wbGljaXQ6IFtcbiAgICByZXF1aXJlKCcuLi90eXBlL251bGwnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL2Jvb2wnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL2ludCcpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvZmxvYXQnKVxuICBdXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFlBTUxFeGNlcHRpb24gPSByZXF1aXJlKCcuL2V4Y2VwdGlvbicpO1xuXG52YXIgVFlQRV9DT05TVFJVQ1RPUl9PUFRJT05TID0gW1xuICAna2luZCcsXG4gICdyZXNvbHZlJyxcbiAgJ2NvbnN0cnVjdCcsXG4gICdpbnN0YW5jZU9mJyxcbiAgJ3ByZWRpY2F0ZScsXG4gICdyZXByZXNlbnQnLFxuICAnZGVmYXVsdFN0eWxlJyxcbiAgJ3N0eWxlQWxpYXNlcydcbl07XG5cbnZhciBZQU1MX05PREVfS0lORFMgPSBbXG4gICdzY2FsYXInLFxuICAnc2VxdWVuY2UnLFxuICAnbWFwcGluZydcbl07XG5cbmZ1bmN0aW9uIGNvbXBpbGVTdHlsZUFsaWFzZXMobWFwKSB7XG4gIHZhciByZXN1bHQgPSB7fTtcblxuICBpZiAobWFwICE9PSBudWxsKSB7XG4gICAgT2JqZWN0LmtleXMobWFwKS5mb3JFYWNoKGZ1bmN0aW9uIChzdHlsZSkge1xuICAgICAgbWFwW3N0eWxlXS5mb3JFYWNoKGZ1bmN0aW9uIChhbGlhcykge1xuICAgICAgICByZXN1bHRbU3RyaW5nKGFsaWFzKV0gPSBzdHlsZTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gVHlwZSh0YWcsIG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgT2JqZWN0LmtleXMob3B0aW9ucykuZm9yRWFjaChmdW5jdGlvbiAobmFtZSkge1xuICAgIGlmIChUWVBFX0NPTlNUUlVDVE9SX09QVElPTlMuaW5kZXhPZihuYW1lKSA9PT0gLTEpIHtcbiAgICAgIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdVbmtub3duIG9wdGlvbiBcIicgKyBuYW1lICsgJ1wiIGlzIG1ldCBpbiBkZWZpbml0aW9uIG9mIFwiJyArIHRhZyArICdcIiBZQU1MIHR5cGUuJyk7XG4gICAgfVxuICB9KTtcblxuICAvLyBUT0RPOiBBZGQgdGFnIGZvcm1hdCBjaGVjay5cbiAgdGhpcy50YWcgICAgICAgICAgPSB0YWc7XG4gIHRoaXMua2luZCAgICAgICAgID0gb3B0aW9uc1sna2luZCddICAgICAgICAgfHwgbnVsbDtcbiAgdGhpcy5yZXNvbHZlICAgICAgPSBvcHRpb25zWydyZXNvbHZlJ10gICAgICB8fCBmdW5jdGlvbiAoKSB7IHJldHVybiB0cnVlOyB9O1xuICB0aGlzLmNvbnN0cnVjdCAgICA9IG9wdGlvbnNbJ2NvbnN0cnVjdCddICAgIHx8IGZ1bmN0aW9uIChkYXRhKSB7IHJldHVybiBkYXRhOyB9O1xuICB0aGlzLmluc3RhbmNlT2YgICA9IG9wdGlvbnNbJ2luc3RhbmNlT2YnXSAgIHx8IG51bGw7XG4gIHRoaXMucHJlZGljYXRlICAgID0gb3B0aW9uc1sncHJlZGljYXRlJ10gICAgfHwgbnVsbDtcbiAgdGhpcy5yZXByZXNlbnQgICAgPSBvcHRpb25zWydyZXByZXNlbnQnXSAgICB8fCBudWxsO1xuICB0aGlzLmRlZmF1bHRTdHlsZSA9IG9wdGlvbnNbJ2RlZmF1bHRTdHlsZSddIHx8IG51bGw7XG4gIHRoaXMuc3R5bGVBbGlhc2VzID0gY29tcGlsZVN0eWxlQWxpYXNlcyhvcHRpb25zWydzdHlsZUFsaWFzZXMnXSB8fCBudWxsKTtcblxuICBpZiAoWUFNTF9OT0RFX0tJTkRTLmluZGV4T2YodGhpcy5raW5kKSA9PT0gLTEpIHtcbiAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignVW5rbm93biBraW5kIFwiJyArIHRoaXMua2luZCArICdcIiBpcyBzcGVjaWZpZWQgZm9yIFwiJyArIHRhZyArICdcIiBZQU1MIHR5cGUuJyk7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBUeXBlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKmVzbGludC1kaXNhYmxlIG5vLWJpdHdpc2UqL1xuXG52YXIgTm9kZUJ1ZmZlcjtcblxudHJ5IHtcbiAgLy8gQSB0cmljayBmb3IgYnJvd3NlcmlmaWVkIHZlcnNpb24sIHRvIG5vdCBpbmNsdWRlIGBCdWZmZXJgIHNoaW1cbiAgdmFyIF9yZXF1aXJlID0gcmVxdWlyZTtcbiAgTm9kZUJ1ZmZlciA9IF9yZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG59IGNhdGNoIChfXykge31cblxudmFyIFR5cGUgICAgICAgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cblxuLy8gWyA2NCwgNjUsIDY2IF0gLT4gWyBwYWRkaW5nLCBDUiwgTEYgXVxudmFyIEJBU0U2NF9NQVAgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLz1cXG5cXHInO1xuXG5cbmZ1bmN0aW9uIHJlc29sdmVZYW1sQmluYXJ5KGRhdGEpIHtcbiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiBmYWxzZTtcblxuICB2YXIgY29kZSwgaWR4LCBiaXRsZW4gPSAwLCBtYXggPSBkYXRhLmxlbmd0aCwgbWFwID0gQkFTRTY0X01BUDtcblxuICAvLyBDb252ZXJ0IG9uZSBieSBvbmUuXG4gIGZvciAoaWR4ID0gMDsgaWR4IDwgbWF4OyBpZHgrKykge1xuICAgIGNvZGUgPSBtYXAuaW5kZXhPZihkYXRhLmNoYXJBdChpZHgpKTtcblxuICAgIC8vIFNraXAgQ1IvTEZcbiAgICBpZiAoY29kZSA+IDY0KSBjb250aW51ZTtcblxuICAgIC8vIEZhaWwgb24gaWxsZWdhbCBjaGFyYWN0ZXJzXG4gICAgaWYgKGNvZGUgPCAwKSByZXR1cm4gZmFsc2U7XG5cbiAgICBiaXRsZW4gKz0gNjtcbiAgfVxuXG4gIC8vIElmIHRoZXJlIGFyZSBhbnkgYml0cyBsZWZ0LCBzb3VyY2Ugd2FzIGNvcnJ1cHRlZFxuICByZXR1cm4gKGJpdGxlbiAlIDgpID09PSAwO1xufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RZYW1sQmluYXJ5KGRhdGEpIHtcbiAgdmFyIGlkeCwgdGFpbGJpdHMsXG4gICAgICBpbnB1dCA9IGRhdGEucmVwbGFjZSgvW1xcclxcbj1dL2csICcnKSwgLy8gcmVtb3ZlIENSL0xGICYgcGFkZGluZyB0byBzaW1wbGlmeSBzY2FuXG4gICAgICBtYXggPSBpbnB1dC5sZW5ndGgsXG4gICAgICBtYXAgPSBCQVNFNjRfTUFQLFxuICAgICAgYml0cyA9IDAsXG4gICAgICByZXN1bHQgPSBbXTtcblxuICAvLyBDb2xsZWN0IGJ5IDYqNCBiaXRzICgzIGJ5dGVzKVxuXG4gIGZvciAoaWR4ID0gMDsgaWR4IDwgbWF4OyBpZHgrKykge1xuICAgIGlmICgoaWR4ICUgNCA9PT0gMCkgJiYgaWR4KSB7XG4gICAgICByZXN1bHQucHVzaCgoYml0cyA+PiAxNikgJiAweEZGKTtcbiAgICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDgpICYgMHhGRik7XG4gICAgICByZXN1bHQucHVzaChiaXRzICYgMHhGRik7XG4gICAgfVxuXG4gICAgYml0cyA9IChiaXRzIDw8IDYpIHwgbWFwLmluZGV4T2YoaW5wdXQuY2hhckF0KGlkeCkpO1xuICB9XG5cbiAgLy8gRHVtcCB0YWlsXG5cbiAgdGFpbGJpdHMgPSAobWF4ICUgNCkgKiA2O1xuXG4gIGlmICh0YWlsYml0cyA9PT0gMCkge1xuICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDE2KSAmIDB4RkYpO1xuICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDgpICYgMHhGRik7XG4gICAgcmVzdWx0LnB1c2goYml0cyAmIDB4RkYpO1xuICB9IGVsc2UgaWYgKHRhaWxiaXRzID09PSAxOCkge1xuICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDEwKSAmIDB4RkYpO1xuICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDIpICYgMHhGRik7XG4gIH0gZWxzZSBpZiAodGFpbGJpdHMgPT09IDEyKSB7XG4gICAgcmVzdWx0LnB1c2goKGJpdHMgPj4gNCkgJiAweEZGKTtcbiAgfVxuXG4gIC8vIFdyYXAgaW50byBCdWZmZXIgZm9yIE5vZGVKUyBhbmQgbGVhdmUgQXJyYXkgZm9yIGJyb3dzZXJcbiAgaWYgKE5vZGVCdWZmZXIpIHJldHVybiBuZXcgTm9kZUJ1ZmZlcihyZXN1bHQpO1xuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIHJlcHJlc2VudFlhbWxCaW5hcnkob2JqZWN0IC8qLCBzdHlsZSovKSB7XG4gIHZhciByZXN1bHQgPSAnJywgYml0cyA9IDAsIGlkeCwgdGFpbCxcbiAgICAgIG1heCA9IG9iamVjdC5sZW5ndGgsXG4gICAgICBtYXAgPSBCQVNFNjRfTUFQO1xuXG4gIC8vIENvbnZlcnQgZXZlcnkgdGhyZWUgYnl0ZXMgdG8gNCBBU0NJSSBjaGFyYWN0ZXJzLlxuXG4gIGZvciAoaWR4ID0gMDsgaWR4IDwgbWF4OyBpZHgrKykge1xuICAgIGlmICgoaWR4ICUgMyA9PT0gMCkgJiYgaWR4KSB7XG4gICAgICByZXN1bHQgKz0gbWFwWyhiaXRzID4+IDE4KSAmIDB4M0ZdO1xuICAgICAgcmVzdWx0ICs9IG1hcFsoYml0cyA+PiAxMikgJiAweDNGXTtcbiAgICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gNikgJiAweDNGXTtcbiAgICAgIHJlc3VsdCArPSBtYXBbYml0cyAmIDB4M0ZdO1xuICAgIH1cblxuICAgIGJpdHMgPSAoYml0cyA8PCA4KSArIG9iamVjdFtpZHhdO1xuICB9XG5cbiAgLy8gRHVtcCB0YWlsXG5cbiAgdGFpbCA9IG1heCAlIDM7XG5cbiAgaWYgKHRhaWwgPT09IDApIHtcbiAgICByZXN1bHQgKz0gbWFwWyhiaXRzID4+IDE4KSAmIDB4M0ZdO1xuICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gMTIpICYgMHgzRl07XG4gICAgcmVzdWx0ICs9IG1hcFsoYml0cyA+PiA2KSAmIDB4M0ZdO1xuICAgIHJlc3VsdCArPSBtYXBbYml0cyAmIDB4M0ZdO1xuICB9IGVsc2UgaWYgKHRhaWwgPT09IDIpIHtcbiAgICByZXN1bHQgKz0gbWFwWyhiaXRzID4+IDEwKSAmIDB4M0ZdO1xuICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gNCkgJiAweDNGXTtcbiAgICByZXN1bHQgKz0gbWFwWyhiaXRzIDw8IDIpICYgMHgzRl07XG4gICAgcmVzdWx0ICs9IG1hcFs2NF07XG4gIH0gZWxzZSBpZiAodGFpbCA9PT0gMSkge1xuICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gMikgJiAweDNGXTtcbiAgICByZXN1bHQgKz0gbWFwWyhiaXRzIDw8IDQpICYgMHgzRl07XG4gICAgcmVzdWx0ICs9IG1hcFs2NF07XG4gICAgcmVzdWx0ICs9IG1hcFs2NF07XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBpc0JpbmFyeShvYmplY3QpIHtcbiAgcmV0dXJuIE5vZGVCdWZmZXIgJiYgTm9kZUJ1ZmZlci5pc0J1ZmZlcihvYmplY3QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpiaW5hcnknLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICByZXNvbHZlOiByZXNvbHZlWWFtbEJpbmFyeSxcbiAgY29uc3RydWN0OiBjb25zdHJ1Y3RZYW1sQmluYXJ5LFxuICBwcmVkaWNhdGU6IGlzQmluYXJ5LFxuICByZXByZXNlbnQ6IHJlcHJlc2VudFlhbWxCaW5hcnlcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxCb29sZWFuKGRhdGEpIHtcbiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiBmYWxzZTtcblxuICB2YXIgbWF4ID0gZGF0YS5sZW5ndGg7XG5cbiAgcmV0dXJuIChtYXggPT09IDQgJiYgKGRhdGEgPT09ICd0cnVlJyB8fCBkYXRhID09PSAnVHJ1ZScgfHwgZGF0YSA9PT0gJ1RSVUUnKSkgfHxcbiAgICAgICAgIChtYXggPT09IDUgJiYgKGRhdGEgPT09ICdmYWxzZScgfHwgZGF0YSA9PT0gJ0ZhbHNlJyB8fCBkYXRhID09PSAnRkFMU0UnKSk7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxCb29sZWFuKGRhdGEpIHtcbiAgcmV0dXJuIGRhdGEgPT09ICd0cnVlJyB8fFxuICAgICAgICAgZGF0YSA9PT0gJ1RydWUnIHx8XG4gICAgICAgICBkYXRhID09PSAnVFJVRSc7XG59XG5cbmZ1bmN0aW9uIGlzQm9vbGVhbihvYmplY3QpIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmplY3QpID09PSAnW29iamVjdCBCb29sZWFuXSc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOmJvb2wnLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICByZXNvbHZlOiByZXNvbHZlWWFtbEJvb2xlYW4sXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbEJvb2xlYW4sXG4gIHByZWRpY2F0ZTogaXNCb29sZWFuLFxuICByZXByZXNlbnQ6IHtcbiAgICBsb3dlcmNhc2U6IGZ1bmN0aW9uIChvYmplY3QpIHsgcmV0dXJuIG9iamVjdCA/ICd0cnVlJyA6ICdmYWxzZSc7IH0sXG4gICAgdXBwZXJjYXNlOiBmdW5jdGlvbiAob2JqZWN0KSB7IHJldHVybiBvYmplY3QgPyAnVFJVRScgOiAnRkFMU0UnOyB9LFxuICAgIGNhbWVsY2FzZTogZnVuY3Rpb24gKG9iamVjdCkgeyByZXR1cm4gb2JqZWN0ID8gJ1RydWUnIDogJ0ZhbHNlJzsgfVxuICB9LFxuICBkZWZhdWx0U3R5bGU6ICdsb3dlcmNhc2UnXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4uL2NvbW1vbicpO1xudmFyIFR5cGUgICA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxudmFyIFlBTUxfRkxPQVRfUEFUVEVSTiA9IG5ldyBSZWdFeHAoXG4gICdeKD86Wy0rXT8oPzpbMC05XVswLTlfXSopXFxcXC5bMC05X10qKD86W2VFXVstK11bMC05XSspPycgK1xuICAnfFxcXFwuWzAtOV9dKyg/OltlRV1bLStdWzAtOV0rKT8nICtcbiAgJ3xbLStdP1swLTldWzAtOV9dKig/OjpbMC01XT9bMC05XSkrXFxcXC5bMC05X10qJyArXG4gICd8Wy0rXT9cXFxcLig/OmluZnxJbmZ8SU5GKScgK1xuICAnfFxcXFwuKD86bmFufE5hTnxOQU4pKSQnKTtcblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxGbG9hdChkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gZmFsc2U7XG5cbiAgaWYgKCFZQU1MX0ZMT0FUX1BBVFRFUk4udGVzdChkYXRhKSkgcmV0dXJuIGZhbHNlO1xuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RZYW1sRmxvYXQoZGF0YSkge1xuICB2YXIgdmFsdWUsIHNpZ24sIGJhc2UsIGRpZ2l0cztcblxuICB2YWx1ZSAgPSBkYXRhLnJlcGxhY2UoL18vZywgJycpLnRvTG93ZXJDYXNlKCk7XG4gIHNpZ24gICA9IHZhbHVlWzBdID09PSAnLScgPyAtMSA6IDE7XG4gIGRpZ2l0cyA9IFtdO1xuXG4gIGlmICgnKy0nLmluZGV4T2YodmFsdWVbMF0pID49IDApIHtcbiAgICB2YWx1ZSA9IHZhbHVlLnNsaWNlKDEpO1xuICB9XG5cbiAgaWYgKHZhbHVlID09PSAnLmluZicpIHtcbiAgICByZXR1cm4gKHNpZ24gPT09IDEpID8gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZIDogTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZO1xuXG4gIH0gZWxzZSBpZiAodmFsdWUgPT09ICcubmFuJykge1xuICAgIHJldHVybiBOYU47XG5cbiAgfSBlbHNlIGlmICh2YWx1ZS5pbmRleE9mKCc6JykgPj0gMCkge1xuICAgIHZhbHVlLnNwbGl0KCc6JykuZm9yRWFjaChmdW5jdGlvbiAodikge1xuICAgICAgZGlnaXRzLnVuc2hpZnQocGFyc2VGbG9hdCh2LCAxMCkpO1xuICAgIH0pO1xuXG4gICAgdmFsdWUgPSAwLjA7XG4gICAgYmFzZSA9IDE7XG5cbiAgICBkaWdpdHMuZm9yRWFjaChmdW5jdGlvbiAoZCkge1xuICAgICAgdmFsdWUgKz0gZCAqIGJhc2U7XG4gICAgICBiYXNlICo9IDYwO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHNpZ24gKiB2YWx1ZTtcblxuICB9XG4gIHJldHVybiBzaWduICogcGFyc2VGbG9hdCh2YWx1ZSwgMTApO1xufVxuXG5cbnZhciBTQ0lFTlRJRklDX1dJVEhPVVRfRE9UID0gL15bLStdP1swLTldK2UvO1xuXG5mdW5jdGlvbiByZXByZXNlbnRZYW1sRmxvYXQob2JqZWN0LCBzdHlsZSkge1xuICB2YXIgcmVzO1xuXG4gIGlmIChpc05hTihvYmplY3QpKSB7XG4gICAgc3dpdGNoIChzdHlsZSkge1xuICAgICAgY2FzZSAnbG93ZXJjYXNlJzogcmV0dXJuICcubmFuJztcbiAgICAgIGNhc2UgJ3VwcGVyY2FzZSc6IHJldHVybiAnLk5BTic7XG4gICAgICBjYXNlICdjYW1lbGNhc2UnOiByZXR1cm4gJy5OYU4nO1xuICAgIH1cbiAgfSBlbHNlIGlmIChOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkgPT09IG9iamVjdCkge1xuICAgIHN3aXRjaCAoc3R5bGUpIHtcbiAgICAgIGNhc2UgJ2xvd2VyY2FzZSc6IHJldHVybiAnLmluZic7XG4gICAgICBjYXNlICd1cHBlcmNhc2UnOiByZXR1cm4gJy5JTkYnO1xuICAgICAgY2FzZSAnY2FtZWxjYXNlJzogcmV0dXJuICcuSW5mJztcbiAgICB9XG4gIH0gZWxzZSBpZiAoTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZID09PSBvYmplY3QpIHtcbiAgICBzd2l0Y2ggKHN0eWxlKSB7XG4gICAgICBjYXNlICdsb3dlcmNhc2UnOiByZXR1cm4gJy0uaW5mJztcbiAgICAgIGNhc2UgJ3VwcGVyY2FzZSc6IHJldHVybiAnLS5JTkYnO1xuICAgICAgY2FzZSAnY2FtZWxjYXNlJzogcmV0dXJuICctLkluZic7XG4gICAgfVxuICB9IGVsc2UgaWYgKGNvbW1vbi5pc05lZ2F0aXZlWmVybyhvYmplY3QpKSB7XG4gICAgcmV0dXJuICctMC4wJztcbiAgfVxuXG4gIHJlcyA9IG9iamVjdC50b1N0cmluZygxMCk7XG5cbiAgLy8gSlMgc3RyaW5naWZpZXIgY2FuIGJ1aWxkIHNjaWVudGlmaWMgZm9ybWF0IHdpdGhvdXQgZG90czogNWUtMTAwLFxuICAvLyB3aGlsZSBZQU1MIHJlcXVyZXMgZG90OiA1LmUtMTAwLiBGaXggaXQgd2l0aCBzaW1wbGUgaGFja1xuXG4gIHJldHVybiBTQ0lFTlRJRklDX1dJVEhPVVRfRE9ULnRlc3QocmVzKSA/IHJlcy5yZXBsYWNlKCdlJywgJy5lJykgOiByZXM7XG59XG5cbmZ1bmN0aW9uIGlzRmxvYXQob2JqZWN0KSB7XG4gIHJldHVybiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iamVjdCkgPT09ICdbb2JqZWN0IE51bWJlcl0nKSAmJlxuICAgICAgICAgKG9iamVjdCAlIDEgIT09IDAgfHwgY29tbW9uLmlzTmVnYXRpdmVaZXJvKG9iamVjdCkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpmbG9hdCcsIHtcbiAga2luZDogJ3NjYWxhcicsXG4gIHJlc29sdmU6IHJlc29sdmVZYW1sRmxvYXQsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbEZsb2F0LFxuICBwcmVkaWNhdGU6IGlzRmxvYXQsXG4gIHJlcHJlc2VudDogcmVwcmVzZW50WWFtbEZsb2F0LFxuICBkZWZhdWx0U3R5bGU6ICdsb3dlcmNhc2UnXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4uL2NvbW1vbicpO1xudmFyIFR5cGUgICA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxuZnVuY3Rpb24gaXNIZXhDb2RlKGMpIHtcbiAgcmV0dXJuICgoMHgzMC8qIDAgKi8gPD0gYykgJiYgKGMgPD0gMHgzOS8qIDkgKi8pKSB8fFxuICAgICAgICAgKCgweDQxLyogQSAqLyA8PSBjKSAmJiAoYyA8PSAweDQ2LyogRiAqLykpIHx8XG4gICAgICAgICAoKDB4NjEvKiBhICovIDw9IGMpICYmIChjIDw9IDB4NjYvKiBmICovKSk7XG59XG5cbmZ1bmN0aW9uIGlzT2N0Q29kZShjKSB7XG4gIHJldHVybiAoKDB4MzAvKiAwICovIDw9IGMpICYmIChjIDw9IDB4MzcvKiA3ICovKSk7XG59XG5cbmZ1bmN0aW9uIGlzRGVjQ29kZShjKSB7XG4gIHJldHVybiAoKDB4MzAvKiAwICovIDw9IGMpICYmIChjIDw9IDB4MzkvKiA5ICovKSk7XG59XG5cbmZ1bmN0aW9uIHJlc29sdmVZYW1sSW50ZWdlcihkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gZmFsc2U7XG5cbiAgdmFyIG1heCA9IGRhdGEubGVuZ3RoLFxuICAgICAgaW5kZXggPSAwLFxuICAgICAgaGFzRGlnaXRzID0gZmFsc2UsXG4gICAgICBjaDtcblxuICBpZiAoIW1heCkgcmV0dXJuIGZhbHNlO1xuXG4gIGNoID0gZGF0YVtpbmRleF07XG5cbiAgLy8gc2lnblxuICBpZiAoY2ggPT09ICctJyB8fCBjaCA9PT0gJysnKSB7XG4gICAgY2ggPSBkYXRhWysraW5kZXhdO1xuICB9XG5cbiAgaWYgKGNoID09PSAnMCcpIHtcbiAgICAvLyAwXG4gICAgaWYgKGluZGV4ICsgMSA9PT0gbWF4KSByZXR1cm4gdHJ1ZTtcbiAgICBjaCA9IGRhdGFbKytpbmRleF07XG5cbiAgICAvLyBiYXNlIDIsIGJhc2UgOCwgYmFzZSAxNlxuXG4gICAgaWYgKGNoID09PSAnYicpIHtcbiAgICAgIC8vIGJhc2UgMlxuICAgICAgaW5kZXgrKztcblxuICAgICAgZm9yICg7IGluZGV4IDwgbWF4OyBpbmRleCsrKSB7XG4gICAgICAgIGNoID0gZGF0YVtpbmRleF07XG4gICAgICAgIGlmIChjaCA9PT0gJ18nKSBjb250aW51ZTtcbiAgICAgICAgaWYgKGNoICE9PSAnMCcgJiYgY2ggIT09ICcxJykgcmV0dXJuIGZhbHNlO1xuICAgICAgICBoYXNEaWdpdHMgPSB0cnVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGhhc0RpZ2l0cztcbiAgICB9XG5cblxuICAgIGlmIChjaCA9PT0gJ3gnKSB7XG4gICAgICAvLyBiYXNlIDE2XG4gICAgICBpbmRleCsrO1xuXG4gICAgICBmb3IgKDsgaW5kZXggPCBtYXg7IGluZGV4KyspIHtcbiAgICAgICAgY2ggPSBkYXRhW2luZGV4XTtcbiAgICAgICAgaWYgKGNoID09PSAnXycpIGNvbnRpbnVlO1xuICAgICAgICBpZiAoIWlzSGV4Q29kZShkYXRhLmNoYXJDb2RlQXQoaW5kZXgpKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICBoYXNEaWdpdHMgPSB0cnVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGhhc0RpZ2l0cztcbiAgICB9XG5cbiAgICAvLyBiYXNlIDhcbiAgICBmb3IgKDsgaW5kZXggPCBtYXg7IGluZGV4KyspIHtcbiAgICAgIGNoID0gZGF0YVtpbmRleF07XG4gICAgICBpZiAoY2ggPT09ICdfJykgY29udGludWU7XG4gICAgICBpZiAoIWlzT2N0Q29kZShkYXRhLmNoYXJDb2RlQXQoaW5kZXgpKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgaGFzRGlnaXRzID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGhhc0RpZ2l0cztcbiAgfVxuXG4gIC8vIGJhc2UgMTAgKGV4Y2VwdCAwKSBvciBiYXNlIDYwXG5cbiAgZm9yICg7IGluZGV4IDwgbWF4OyBpbmRleCsrKSB7XG4gICAgY2ggPSBkYXRhW2luZGV4XTtcbiAgICBpZiAoY2ggPT09ICdfJykgY29udGludWU7XG4gICAgaWYgKGNoID09PSAnOicpIGJyZWFrO1xuICAgIGlmICghaXNEZWNDb2RlKGRhdGEuY2hhckNvZGVBdChpbmRleCkpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGhhc0RpZ2l0cyA9IHRydWU7XG4gIH1cblxuICBpZiAoIWhhc0RpZ2l0cykgcmV0dXJuIGZhbHNlO1xuXG4gIC8vIGlmICFiYXNlNjAgLSBkb25lO1xuICBpZiAoY2ggIT09ICc6JykgcmV0dXJuIHRydWU7XG5cbiAgLy8gYmFzZTYwIGFsbW9zdCBub3QgdXNlZCwgbm8gbmVlZHMgdG8gb3B0aW1pemVcbiAgcmV0dXJuIC9eKDpbMC01XT9bMC05XSkrJC8udGVzdChkYXRhLnNsaWNlKGluZGV4KSk7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxJbnRlZ2VyKGRhdGEpIHtcbiAgdmFyIHZhbHVlID0gZGF0YSwgc2lnbiA9IDEsIGNoLCBiYXNlLCBkaWdpdHMgPSBbXTtcblxuICBpZiAodmFsdWUuaW5kZXhPZignXycpICE9PSAtMSkge1xuICAgIHZhbHVlID0gdmFsdWUucmVwbGFjZSgvXy9nLCAnJyk7XG4gIH1cblxuICBjaCA9IHZhbHVlWzBdO1xuXG4gIGlmIChjaCA9PT0gJy0nIHx8IGNoID09PSAnKycpIHtcbiAgICBpZiAoY2ggPT09ICctJykgc2lnbiA9IC0xO1xuICAgIHZhbHVlID0gdmFsdWUuc2xpY2UoMSk7XG4gICAgY2ggPSB2YWx1ZVswXTtcbiAgfVxuXG4gIGlmICh2YWx1ZSA9PT0gJzAnKSByZXR1cm4gMDtcblxuICBpZiAoY2ggPT09ICcwJykge1xuICAgIGlmICh2YWx1ZVsxXSA9PT0gJ2InKSByZXR1cm4gc2lnbiAqIHBhcnNlSW50KHZhbHVlLnNsaWNlKDIpLCAyKTtcbiAgICBpZiAodmFsdWVbMV0gPT09ICd4JykgcmV0dXJuIHNpZ24gKiBwYXJzZUludCh2YWx1ZSwgMTYpO1xuICAgIHJldHVybiBzaWduICogcGFyc2VJbnQodmFsdWUsIDgpO1xuICB9XG5cbiAgaWYgKHZhbHVlLmluZGV4T2YoJzonKSAhPT0gLTEpIHtcbiAgICB2YWx1ZS5zcGxpdCgnOicpLmZvckVhY2goZnVuY3Rpb24gKHYpIHtcbiAgICAgIGRpZ2l0cy51bnNoaWZ0KHBhcnNlSW50KHYsIDEwKSk7XG4gICAgfSk7XG5cbiAgICB2YWx1ZSA9IDA7XG4gICAgYmFzZSA9IDE7XG5cbiAgICBkaWdpdHMuZm9yRWFjaChmdW5jdGlvbiAoZCkge1xuICAgICAgdmFsdWUgKz0gKGQgKiBiYXNlKTtcbiAgICAgIGJhc2UgKj0gNjA7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gc2lnbiAqIHZhbHVlO1xuXG4gIH1cblxuICByZXR1cm4gc2lnbiAqIHBhcnNlSW50KHZhbHVlLCAxMCk7XG59XG5cbmZ1bmN0aW9uIGlzSW50ZWdlcihvYmplY3QpIHtcbiAgcmV0dXJuIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqZWN0KSkgPT09ICdbb2JqZWN0IE51bWJlcl0nICYmXG4gICAgICAgICAob2JqZWN0ICUgMSA9PT0gMCAmJiAhY29tbW9uLmlzTmVnYXRpdmVaZXJvKG9iamVjdCkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjppbnQnLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICByZXNvbHZlOiByZXNvbHZlWWFtbEludGVnZXIsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbEludGVnZXIsXG4gIHByZWRpY2F0ZTogaXNJbnRlZ2VyLFxuICByZXByZXNlbnQ6IHtcbiAgICBiaW5hcnk6ICAgICAgZnVuY3Rpb24gKG9iamVjdCkgeyByZXR1cm4gJzBiJyArIG9iamVjdC50b1N0cmluZygyKTsgfSxcbiAgICBvY3RhbDogICAgICAgZnVuY3Rpb24gKG9iamVjdCkgeyByZXR1cm4gJzAnICArIG9iamVjdC50b1N0cmluZyg4KTsgfSxcbiAgICBkZWNpbWFsOiAgICAgZnVuY3Rpb24gKG9iamVjdCkgeyByZXR1cm4gICAgICAgIG9iamVjdC50b1N0cmluZygxMCk7IH0sXG4gICAgaGV4YWRlY2ltYWw6IGZ1bmN0aW9uIChvYmplY3QpIHsgcmV0dXJuICcweCcgKyBvYmplY3QudG9TdHJpbmcoMTYpLnRvVXBwZXJDYXNlKCk7IH1cbiAgfSxcbiAgZGVmYXVsdFN0eWxlOiAnZGVjaW1hbCcsXG4gIHN0eWxlQWxpYXNlczoge1xuICAgIGJpbmFyeTogICAgICBbIDIsICAnYmluJyBdLFxuICAgIG9jdGFsOiAgICAgICBbIDgsICAnb2N0JyBdLFxuICAgIGRlY2ltYWw6ICAgICBbIDEwLCAnZGVjJyBdLFxuICAgIGhleGFkZWNpbWFsOiBbIDE2LCAnaGV4JyBdXG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZXNwcmltYTtcblxuLy8gQnJvd3NlcmlmaWVkIHZlcnNpb24gZG9lcyBub3QgaGF2ZSBlc3ByaW1hXG4vL1xuLy8gMS4gRm9yIG5vZGUuanMganVzdCByZXF1aXJlIG1vZHVsZSBhcyBkZXBzXG4vLyAyLiBGb3IgYnJvd3NlciB0cnkgdG8gcmVxdWlyZSBtdWR1bGUgdmlhIGV4dGVybmFsIEFNRCBzeXN0ZW0uXG4vLyAgICBJZiBub3QgZm91bmQgLSB0cnkgdG8gZmFsbGJhY2sgdG8gd2luZG93LmVzcHJpbWEuIElmIG5vdFxuLy8gICAgZm91bmQgdG9vIC0gdGhlbiBmYWlsIHRvIHBhcnNlLlxuLy9cbnRyeSB7XG4gIC8vIHdvcmthcm91bmQgdG8gZXhjbHVkZSBwYWNrYWdlIGZyb20gYnJvd3NlcmlmeSBsaXN0LlxuICB2YXIgX3JlcXVpcmUgPSByZXF1aXJlO1xuICBlc3ByaW1hID0gX3JlcXVpcmUoJ2VzcHJpbWEnKTtcbn0gY2F0Y2ggKF8pIHtcbiAgLypnbG9iYWwgd2luZG93ICovXG4gIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykgZXNwcmltYSA9IHdpbmRvdy5lc3ByaW1hO1xufVxuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uLy4uL3R5cGUnKTtcblxuZnVuY3Rpb24gcmVzb2x2ZUphdmFzY3JpcHRGdW5jdGlvbihkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gZmFsc2U7XG5cbiAgdHJ5IHtcbiAgICB2YXIgc291cmNlID0gJygnICsgZGF0YSArICcpJyxcbiAgICAgICAgYXN0ICAgID0gZXNwcmltYS5wYXJzZShzb3VyY2UsIHsgcmFuZ2U6IHRydWUgfSk7XG5cbiAgICBpZiAoYXN0LnR5cGUgICAgICAgICAgICAgICAgICAgICE9PSAnUHJvZ3JhbScgICAgICAgICAgICAgfHxcbiAgICAgICAgYXN0LmJvZHkubGVuZ3RoICAgICAgICAgICAgICE9PSAxICAgICAgICAgICAgICAgICAgICAgfHxcbiAgICAgICAgYXN0LmJvZHlbMF0udHlwZSAgICAgICAgICAgICE9PSAnRXhwcmVzc2lvblN0YXRlbWVudCcgfHxcbiAgICAgICAgYXN0LmJvZHlbMF0uZXhwcmVzc2lvbi50eXBlICE9PSAnRnVuY3Rpb25FeHByZXNzaW9uJykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29uc3RydWN0SmF2YXNjcmlwdEZ1bmN0aW9uKGRhdGEpIHtcbiAgLypqc2xpbnQgZXZpbDp0cnVlKi9cblxuICB2YXIgc291cmNlID0gJygnICsgZGF0YSArICcpJyxcbiAgICAgIGFzdCAgICA9IGVzcHJpbWEucGFyc2Uoc291cmNlLCB7IHJhbmdlOiB0cnVlIH0pLFxuICAgICAgcGFyYW1zID0gW10sXG4gICAgICBib2R5O1xuXG4gIGlmIChhc3QudHlwZSAgICAgICAgICAgICAgICAgICAgIT09ICdQcm9ncmFtJyAgICAgICAgICAgICB8fFxuICAgICAgYXN0LmJvZHkubGVuZ3RoICAgICAgICAgICAgICE9PSAxICAgICAgICAgICAgICAgICAgICAgfHxcbiAgICAgIGFzdC5ib2R5WzBdLnR5cGUgICAgICAgICAgICAhPT0gJ0V4cHJlc3Npb25TdGF0ZW1lbnQnIHx8XG4gICAgICBhc3QuYm9keVswXS5leHByZXNzaW9uLnR5cGUgIT09ICdGdW5jdGlvbkV4cHJlc3Npb24nKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gcmVzb2x2ZSBmdW5jdGlvbicpO1xuICB9XG5cbiAgYXN0LmJvZHlbMF0uZXhwcmVzc2lvbi5wYXJhbXMuZm9yRWFjaChmdW5jdGlvbiAocGFyYW0pIHtcbiAgICBwYXJhbXMucHVzaChwYXJhbS5uYW1lKTtcbiAgfSk7XG5cbiAgYm9keSA9IGFzdC5ib2R5WzBdLmV4cHJlc3Npb24uYm9keS5yYW5nZTtcblxuICAvLyBFc3ByaW1hJ3MgcmFuZ2VzIGluY2x1ZGUgdGhlIGZpcnN0ICd7JyBhbmQgdGhlIGxhc3QgJ30nIGNoYXJhY3RlcnMgb25cbiAgLy8gZnVuY3Rpb24gZXhwcmVzc2lvbnMuIFNvIGN1dCB0aGVtIG91dC5cbiAgLyplc2xpbnQtZGlzYWJsZSBuby1uZXctZnVuYyovXG4gIHJldHVybiBuZXcgRnVuY3Rpb24ocGFyYW1zLCBzb3VyY2Uuc2xpY2UoYm9keVswXSArIDEsIGJvZHlbMV0gLSAxKSk7XG59XG5cbmZ1bmN0aW9uIHJlcHJlc2VudEphdmFzY3JpcHRGdW5jdGlvbihvYmplY3QgLyosIHN0eWxlKi8pIHtcbiAgcmV0dXJuIG9iamVjdC50b1N0cmluZygpO1xufVxuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKG9iamVjdCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iamVjdCkgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOmpzL2Z1bmN0aW9uJywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZUphdmFzY3JpcHRGdW5jdGlvbixcbiAgY29uc3RydWN0OiBjb25zdHJ1Y3RKYXZhc2NyaXB0RnVuY3Rpb24sXG4gIHByZWRpY2F0ZTogaXNGdW5jdGlvbixcbiAgcmVwcmVzZW50OiByZXByZXNlbnRKYXZhc2NyaXB0RnVuY3Rpb25cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uLy4uL3R5cGUnKTtcblxuZnVuY3Rpb24gcmVzb2x2ZUphdmFzY3JpcHRSZWdFeHAoZGF0YSkge1xuICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuICBpZiAoZGF0YS5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTtcblxuICB2YXIgcmVnZXhwID0gZGF0YSxcbiAgICAgIHRhaWwgICA9IC9cXC8oW2dpbV0qKSQvLmV4ZWMoZGF0YSksXG4gICAgICBtb2RpZmllcnMgPSAnJztcblxuICAvLyBpZiByZWdleHAgc3RhcnRzIHdpdGggJy8nIGl0IGNhbiBoYXZlIG1vZGlmaWVycyBhbmQgbXVzdCBiZSBwcm9wZXJseSBjbG9zZWRcbiAgLy8gYC9mb28vZ2ltYCAtIG1vZGlmaWVycyB0YWlsIGNhbiBiZSBtYXhpbXVtIDMgY2hhcnNcbiAgaWYgKHJlZ2V4cFswXSA9PT0gJy8nKSB7XG4gICAgaWYgKHRhaWwpIG1vZGlmaWVycyA9IHRhaWxbMV07XG5cbiAgICBpZiAobW9kaWZpZXJzLmxlbmd0aCA+IDMpIHJldHVybiBmYWxzZTtcbiAgICAvLyBpZiBleHByZXNzaW9uIHN0YXJ0cyB3aXRoIC8sIGlzIHNob3VsZCBiZSBwcm9wZXJseSB0ZXJtaW5hdGVkXG4gICAgaWYgKHJlZ2V4cFtyZWdleHAubGVuZ3RoIC0gbW9kaWZpZXJzLmxlbmd0aCAtIDFdICE9PSAnLycpIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RKYXZhc2NyaXB0UmVnRXhwKGRhdGEpIHtcbiAgdmFyIHJlZ2V4cCA9IGRhdGEsXG4gICAgICB0YWlsICAgPSAvXFwvKFtnaW1dKikkLy5leGVjKGRhdGEpLFxuICAgICAgbW9kaWZpZXJzID0gJyc7XG5cbiAgLy8gYC9mb28vZ2ltYCAtIHRhaWwgY2FuIGJlIG1heGltdW0gNCBjaGFyc1xuICBpZiAocmVnZXhwWzBdID09PSAnLycpIHtcbiAgICBpZiAodGFpbCkgbW9kaWZpZXJzID0gdGFpbFsxXTtcbiAgICByZWdleHAgPSByZWdleHAuc2xpY2UoMSwgcmVnZXhwLmxlbmd0aCAtIG1vZGlmaWVycy5sZW5ndGggLSAxKTtcbiAgfVxuXG4gIHJldHVybiBuZXcgUmVnRXhwKHJlZ2V4cCwgbW9kaWZpZXJzKTtcbn1cblxuZnVuY3Rpb24gcmVwcmVzZW50SmF2YXNjcmlwdFJlZ0V4cChvYmplY3QgLyosIHN0eWxlKi8pIHtcbiAgdmFyIHJlc3VsdCA9ICcvJyArIG9iamVjdC5zb3VyY2UgKyAnLyc7XG5cbiAgaWYgKG9iamVjdC5nbG9iYWwpIHJlc3VsdCArPSAnZyc7XG4gIGlmIChvYmplY3QubXVsdGlsaW5lKSByZXN1bHQgKz0gJ20nO1xuICBpZiAob2JqZWN0Lmlnbm9yZUNhc2UpIHJlc3VsdCArPSAnaSc7XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gaXNSZWdFeHAob2JqZWN0KSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqZWN0KSA9PT0gJ1tvYmplY3QgUmVnRXhwXSc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOmpzL3JlZ2V4cCcsIHtcbiAga2luZDogJ3NjYWxhcicsXG4gIHJlc29sdmU6IHJlc29sdmVKYXZhc2NyaXB0UmVnRXhwLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdEphdmFzY3JpcHRSZWdFeHAsXG4gIHByZWRpY2F0ZTogaXNSZWdFeHAsXG4gIHJlcHJlc2VudDogcmVwcmVzZW50SmF2YXNjcmlwdFJlZ0V4cFxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vLi4vdHlwZScpO1xuXG5mdW5jdGlvbiByZXNvbHZlSmF2YXNjcmlwdFVuZGVmaW5lZCgpIHtcbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdEphdmFzY3JpcHRVbmRlZmluZWQoKSB7XG4gIC8qZXNsaW50LWRpc2FibGUgbm8tdW5kZWZpbmVkKi9cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gcmVwcmVzZW50SmF2YXNjcmlwdFVuZGVmaW5lZCgpIHtcbiAgcmV0dXJuICcnO1xufVxuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChvYmplY3QpIHtcbiAgcmV0dXJuIHR5cGVvZiBvYmplY3QgPT09ICd1bmRlZmluZWQnO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpqcy91bmRlZmluZWQnLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICByZXNvbHZlOiByZXNvbHZlSmF2YXNjcmlwdFVuZGVmaW5lZCxcbiAgY29uc3RydWN0OiBjb25zdHJ1Y3RKYXZhc2NyaXB0VW5kZWZpbmVkLFxuICBwcmVkaWNhdGU6IGlzVW5kZWZpbmVkLFxuICByZXByZXNlbnQ6IHJlcHJlc2VudEphdmFzY3JpcHRVbmRlZmluZWRcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6bWFwJywge1xuICBraW5kOiAnbWFwcGluZycsXG4gIGNvbnN0cnVjdDogZnVuY3Rpb24gKGRhdGEpIHsgcmV0dXJuIGRhdGEgIT09IG51bGwgPyBkYXRhIDoge307IH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxNZXJnZShkYXRhKSB7XG4gIHJldHVybiBkYXRhID09PSAnPDwnIHx8IGRhdGEgPT09IG51bGw7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOm1lcmdlJywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxNZXJnZVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG5mdW5jdGlvbiByZXNvbHZlWWFtbE51bGwoZGF0YSkge1xuICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIHRydWU7XG5cbiAgdmFyIG1heCA9IGRhdGEubGVuZ3RoO1xuXG4gIHJldHVybiAobWF4ID09PSAxICYmIGRhdGEgPT09ICd+JykgfHxcbiAgICAgICAgIChtYXggPT09IDQgJiYgKGRhdGEgPT09ICdudWxsJyB8fCBkYXRhID09PSAnTnVsbCcgfHwgZGF0YSA9PT0gJ05VTEwnKSk7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxOdWxsKCkge1xuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gaXNOdWxsKG9iamVjdCkge1xuICByZXR1cm4gb2JqZWN0ID09PSBudWxsO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpudWxsJywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxOdWxsLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdFlhbWxOdWxsLFxuICBwcmVkaWNhdGU6IGlzTnVsbCxcbiAgcmVwcmVzZW50OiB7XG4gICAgY2Fub25pY2FsOiBmdW5jdGlvbiAoKSB7IHJldHVybiAnfic7ICAgIH0sXG4gICAgbG93ZXJjYXNlOiBmdW5jdGlvbiAoKSB7IHJldHVybiAnbnVsbCc7IH0sXG4gICAgdXBwZXJjYXNlOiBmdW5jdGlvbiAoKSB7IHJldHVybiAnTlVMTCc7IH0sXG4gICAgY2FtZWxjYXNlOiBmdW5jdGlvbiAoKSB7IHJldHVybiAnTnVsbCc7IH1cbiAgfSxcbiAgZGVmYXVsdFN0eWxlOiAnbG93ZXJjYXNlJ1xufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG52YXIgX2hhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbnZhciBfdG9TdHJpbmcgICAgICAgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG5mdW5jdGlvbiByZXNvbHZlWWFtbE9tYXAoZGF0YSkge1xuICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIHRydWU7XG5cbiAgdmFyIG9iamVjdEtleXMgPSBbXSwgaW5kZXgsIGxlbmd0aCwgcGFpciwgcGFpcktleSwgcGFpckhhc0tleSxcbiAgICAgIG9iamVjdCA9IGRhdGE7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IG9iamVjdC5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgcGFpciA9IG9iamVjdFtpbmRleF07XG4gICAgcGFpckhhc0tleSA9IGZhbHNlO1xuXG4gICAgaWYgKF90b1N0cmluZy5jYWxsKHBhaXIpICE9PSAnW29iamVjdCBPYmplY3RdJykgcmV0dXJuIGZhbHNlO1xuXG4gICAgZm9yIChwYWlyS2V5IGluIHBhaXIpIHtcbiAgICAgIGlmIChfaGFzT3duUHJvcGVydHkuY2FsbChwYWlyLCBwYWlyS2V5KSkge1xuICAgICAgICBpZiAoIXBhaXJIYXNLZXkpIHBhaXJIYXNLZXkgPSB0cnVlO1xuICAgICAgICBlbHNlIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXBhaXJIYXNLZXkpIHJldHVybiBmYWxzZTtcblxuICAgIGlmIChvYmplY3RLZXlzLmluZGV4T2YocGFpcktleSkgPT09IC0xKSBvYmplY3RLZXlzLnB1c2gocGFpcktleSk7XG4gICAgZWxzZSByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0WWFtbE9tYXAoZGF0YSkge1xuICByZXR1cm4gZGF0YSAhPT0gbnVsbCA/IGRhdGEgOiBbXTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6b21hcCcsIHtcbiAga2luZDogJ3NlcXVlbmNlJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxPbWFwLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdFlhbWxPbWFwXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbnZhciBfdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG5mdW5jdGlvbiByZXNvbHZlWWFtbFBhaXJzKGRhdGEpIHtcbiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiB0cnVlO1xuXG4gIHZhciBpbmRleCwgbGVuZ3RoLCBwYWlyLCBrZXlzLCByZXN1bHQsXG4gICAgICBvYmplY3QgPSBkYXRhO1xuXG4gIHJlc3VsdCA9IG5ldyBBcnJheShvYmplY3QubGVuZ3RoKTtcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gb2JqZWN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICBwYWlyID0gb2JqZWN0W2luZGV4XTtcblxuICAgIGlmIChfdG9TdHJpbmcuY2FsbChwYWlyKSAhPT0gJ1tvYmplY3QgT2JqZWN0XScpIHJldHVybiBmYWxzZTtcblxuICAgIGtleXMgPSBPYmplY3Qua2V5cyhwYWlyKTtcblxuICAgIGlmIChrZXlzLmxlbmd0aCAhPT0gMSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgcmVzdWx0W2luZGV4XSA9IFsga2V5c1swXSwgcGFpcltrZXlzWzBdXSBdO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxQYWlycyhkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gW107XG5cbiAgdmFyIGluZGV4LCBsZW5ndGgsIHBhaXIsIGtleXMsIHJlc3VsdCxcbiAgICAgIG9iamVjdCA9IGRhdGE7XG5cbiAgcmVzdWx0ID0gbmV3IEFycmF5KG9iamVjdC5sZW5ndGgpO1xuXG4gIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIHBhaXIgPSBvYmplY3RbaW5kZXhdO1xuXG4gICAga2V5cyA9IE9iamVjdC5rZXlzKHBhaXIpO1xuXG4gICAgcmVzdWx0W2luZGV4XSA9IFsga2V5c1swXSwgcGFpcltrZXlzWzBdXSBdO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6cGFpcnMnLCB7XG4gIGtpbmQ6ICdzZXF1ZW5jZScsXG4gIHJlc29sdmU6IHJlc29sdmVZYW1sUGFpcnMsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbFBhaXJzXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOnNlcScsIHtcbiAga2luZDogJ3NlcXVlbmNlJyxcbiAgY29uc3RydWN0OiBmdW5jdGlvbiAoZGF0YSkgeyByZXR1cm4gZGF0YSAhPT0gbnVsbCA/IGRhdGEgOiBbXTsgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG52YXIgX2hhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxTZXQoZGF0YSkge1xuICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIHRydWU7XG5cbiAgdmFyIGtleSwgb2JqZWN0ID0gZGF0YTtcblxuICBmb3IgKGtleSBpbiBvYmplY3QpIHtcbiAgICBpZiAoX2hhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSB7XG4gICAgICBpZiAob2JqZWN0W2tleV0gIT09IG51bGwpIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0WWFtbFNldChkYXRhKSB7XG4gIHJldHVybiBkYXRhICE9PSBudWxsID8gZGF0YSA6IHt9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpzZXQnLCB7XG4gIGtpbmQ6ICdtYXBwaW5nJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxTZXQsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbFNldFxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpzdHInLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICBjb25zdHJ1Y3Q6IGZ1bmN0aW9uIChkYXRhKSB7IHJldHVybiBkYXRhICE9PSBudWxsID8gZGF0YSA6ICcnOyB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbnZhciBZQU1MX0RBVEVfUkVHRVhQID0gbmV3IFJlZ0V4cChcbiAgJ14oWzAtOV1bMC05XVswLTldWzAtOV0pJyAgICAgICAgICArIC8vIFsxXSB5ZWFyXG4gICctKFswLTldWzAtOV0pJyAgICAgICAgICAgICAgICAgICAgKyAvLyBbMl0gbW9udGhcbiAgJy0oWzAtOV1bMC05XSkkJyk7ICAgICAgICAgICAgICAgICAgIC8vIFszXSBkYXlcblxudmFyIFlBTUxfVElNRVNUQU1QX1JFR0VYUCA9IG5ldyBSZWdFeHAoXG4gICdeKFswLTldWzAtOV1bMC05XVswLTldKScgICAgICAgICAgKyAvLyBbMV0geWVhclxuICAnLShbMC05XVswLTldPyknICAgICAgICAgICAgICAgICAgICsgLy8gWzJdIG1vbnRoXG4gICctKFswLTldWzAtOV0/KScgICAgICAgICAgICAgICAgICAgKyAvLyBbM10gZGF5XG4gICcoPzpbVHRdfFsgXFxcXHRdKyknICAgICAgICAgICAgICAgICArIC8vIC4uLlxuICAnKFswLTldWzAtOV0/KScgICAgICAgICAgICAgICAgICAgICsgLy8gWzRdIGhvdXJcbiAgJzooWzAtOV1bMC05XSknICAgICAgICAgICAgICAgICAgICArIC8vIFs1XSBtaW51dGVcbiAgJzooWzAtOV1bMC05XSknICAgICAgICAgICAgICAgICAgICArIC8vIFs2XSBzZWNvbmRcbiAgJyg/OlxcXFwuKFswLTldKikpPycgICAgICAgICAgICAgICAgICsgLy8gWzddIGZyYWN0aW9uXG4gICcoPzpbIFxcXFx0XSooWnwoWy0rXSkoWzAtOV1bMC05XT8pJyArIC8vIFs4XSB0eiBbOV0gdHpfc2lnbiBbMTBdIHR6X2hvdXJcbiAgJyg/OjooWzAtOV1bMC05XSkpPykpPyQnKTsgICAgICAgICAgIC8vIFsxMV0gdHpfbWludXRlXG5cbmZ1bmN0aW9uIHJlc29sdmVZYW1sVGltZXN0YW1wKGRhdGEpIHtcbiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiBmYWxzZTtcbiAgaWYgKFlBTUxfREFURV9SRUdFWFAuZXhlYyhkYXRhKSAhPT0gbnVsbCkgcmV0dXJuIHRydWU7XG4gIGlmIChZQU1MX1RJTUVTVEFNUF9SRUdFWFAuZXhlYyhkYXRhKSAhPT0gbnVsbCkgcmV0dXJuIHRydWU7XG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0WWFtbFRpbWVzdGFtcChkYXRhKSB7XG4gIHZhciBtYXRjaCwgeWVhciwgbW9udGgsIGRheSwgaG91ciwgbWludXRlLCBzZWNvbmQsIGZyYWN0aW9uID0gMCxcbiAgICAgIGRlbHRhID0gbnVsbCwgdHpfaG91ciwgdHpfbWludXRlLCBkYXRlO1xuXG4gIG1hdGNoID0gWUFNTF9EQVRFX1JFR0VYUC5leGVjKGRhdGEpO1xuICBpZiAobWF0Y2ggPT09IG51bGwpIG1hdGNoID0gWUFNTF9USU1FU1RBTVBfUkVHRVhQLmV4ZWMoZGF0YSk7XG5cbiAgaWYgKG1hdGNoID09PSBudWxsKSB0aHJvdyBuZXcgRXJyb3IoJ0RhdGUgcmVzb2x2ZSBlcnJvcicpO1xuXG4gIC8vIG1hdGNoOiBbMV0geWVhciBbMl0gbW9udGggWzNdIGRheVxuXG4gIHllYXIgPSArKG1hdGNoWzFdKTtcbiAgbW9udGggPSArKG1hdGNoWzJdKSAtIDE7IC8vIEpTIG1vbnRoIHN0YXJ0cyB3aXRoIDBcbiAgZGF5ID0gKyhtYXRjaFszXSk7XG5cbiAgaWYgKCFtYXRjaFs0XSkgeyAvLyBubyBob3VyXG4gICAgcmV0dXJuIG5ldyBEYXRlKERhdGUuVVRDKHllYXIsIG1vbnRoLCBkYXkpKTtcbiAgfVxuXG4gIC8vIG1hdGNoOiBbNF0gaG91ciBbNV0gbWludXRlIFs2XSBzZWNvbmQgWzddIGZyYWN0aW9uXG5cbiAgaG91ciA9ICsobWF0Y2hbNF0pO1xuICBtaW51dGUgPSArKG1hdGNoWzVdKTtcbiAgc2Vjb25kID0gKyhtYXRjaFs2XSk7XG5cbiAgaWYgKG1hdGNoWzddKSB7XG4gICAgZnJhY3Rpb24gPSBtYXRjaFs3XS5zbGljZSgwLCAzKTtcbiAgICB3aGlsZSAoZnJhY3Rpb24ubGVuZ3RoIDwgMykgeyAvLyBtaWxsaS1zZWNvbmRzXG4gICAgICBmcmFjdGlvbiArPSAnMCc7XG4gICAgfVxuICAgIGZyYWN0aW9uID0gK2ZyYWN0aW9uO1xuICB9XG5cbiAgLy8gbWF0Y2g6IFs4XSB0eiBbOV0gdHpfc2lnbiBbMTBdIHR6X2hvdXIgWzExXSB0el9taW51dGVcblxuICBpZiAobWF0Y2hbOV0pIHtcbiAgICB0el9ob3VyID0gKyhtYXRjaFsxMF0pO1xuICAgIHR6X21pbnV0ZSA9ICsobWF0Y2hbMTFdIHx8IDApO1xuICAgIGRlbHRhID0gKHR6X2hvdXIgKiA2MCArIHR6X21pbnV0ZSkgKiA2MDAwMDsgLy8gZGVsdGEgaW4gbWlsaS1zZWNvbmRzXG4gICAgaWYgKG1hdGNoWzldID09PSAnLScpIGRlbHRhID0gLWRlbHRhO1xuICB9XG5cbiAgZGF0ZSA9IG5ldyBEYXRlKERhdGUuVVRDKHllYXIsIG1vbnRoLCBkYXksIGhvdXIsIG1pbnV0ZSwgc2Vjb25kLCBmcmFjdGlvbikpO1xuXG4gIGlmIChkZWx0YSkgZGF0ZS5zZXRUaW1lKGRhdGUuZ2V0VGltZSgpIC0gZGVsdGEpO1xuXG4gIHJldHVybiBkYXRlO1xufVxuXG5mdW5jdGlvbiByZXByZXNlbnRZYW1sVGltZXN0YW1wKG9iamVjdCAvKiwgc3R5bGUqLykge1xuICByZXR1cm4gb2JqZWN0LnRvSVNPU3RyaW5nKCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOnRpbWVzdGFtcCcsIHtcbiAga2luZDogJ3NjYWxhcicsXG4gIHJlc29sdmU6IHJlc29sdmVZYW1sVGltZXN0YW1wLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdFlhbWxUaW1lc3RhbXAsXG4gIGluc3RhbmNlT2Y6IERhdGUsXG4gIHJlcHJlc2VudDogcmVwcmVzZW50WWFtbFRpbWVzdGFtcFxufSk7XG4iLCJ2YXIgYmFzZUluZGV4T2YgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlSW5kZXhPZicpLFxuICAgIGJpbmFyeUluZGV4ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmluYXJ5SW5kZXgnKTtcblxuLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heDtcblxuLyoqXG4gKiBHZXRzIHRoZSBpbmRleCBhdCB3aGljaCB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiBgdmFsdWVgIGlzIGZvdW5kIGluIGBhcnJheWBcbiAqIHVzaW5nIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXNhbWV2YWx1ZXplcm8pXG4gKiBmb3IgZXF1YWxpdHkgY29tcGFyaXNvbnMuIElmIGBmcm9tSW5kZXhgIGlzIG5lZ2F0aXZlLCBpdCdzIHVzZWQgYXMgdGhlIG9mZnNldFxuICogZnJvbSB0aGUgZW5kIG9mIGBhcnJheWAuIElmIGBhcnJheWAgaXMgc29ydGVkIHByb3ZpZGluZyBgdHJ1ZWAgZm9yIGBmcm9tSW5kZXhgXG4gKiBwZXJmb3JtcyBhIGZhc3RlciBiaW5hcnkgc2VhcmNoLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgQXJyYXlcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzZWFyY2guXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICogQHBhcmFtIHtib29sZWFufG51bWJlcn0gW2Zyb21JbmRleD0wXSBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20gb3IgYHRydWVgXG4gKiAgdG8gcGVyZm9ybSBhIGJpbmFyeSBzZWFyY2ggb24gYSBzb3J0ZWQgYXJyYXkuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmluZGV4T2YoWzEsIDIsIDEsIDJdLCAyKTtcbiAqIC8vID0+IDFcbiAqXG4gKiAvLyB1c2luZyBgZnJvbUluZGV4YFxuICogXy5pbmRleE9mKFsxLCAyLCAxLCAyXSwgMiwgMik7XG4gKiAvLyA9PiAzXG4gKlxuICogLy8gcGVyZm9ybWluZyBhIGJpbmFyeSBzZWFyY2hcbiAqIF8uaW5kZXhPZihbMSwgMSwgMiwgMl0sIDIsIHRydWUpO1xuICogLy8gPT4gMlxuICovXG5mdW5jdGlvbiBpbmRleE9mKGFycmF5LCB2YWx1ZSwgZnJvbUluZGV4KSB7XG4gIHZhciBsZW5ndGggPSBhcnJheSA/IGFycmF5Lmxlbmd0aCA6IDA7XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgcmV0dXJuIC0xO1xuICB9XG4gIGlmICh0eXBlb2YgZnJvbUluZGV4ID09ICdudW1iZXInKSB7XG4gICAgZnJvbUluZGV4ID0gZnJvbUluZGV4IDwgMCA/IG5hdGl2ZU1heChsZW5ndGggKyBmcm9tSW5kZXgsIDApIDogZnJvbUluZGV4O1xuICB9IGVsc2UgaWYgKGZyb21JbmRleCkge1xuICAgIHZhciBpbmRleCA9IGJpbmFyeUluZGV4KGFycmF5LCB2YWx1ZSk7XG4gICAgaWYgKGluZGV4IDwgbGVuZ3RoICYmXG4gICAgICAgICh2YWx1ZSA9PT0gdmFsdWUgPyAodmFsdWUgPT09IGFycmF5W2luZGV4XSkgOiAoYXJyYXlbaW5kZXhdICE9PSBhcnJheVtpbmRleF0pKSkge1xuICAgICAgcmV0dXJuIGluZGV4O1xuICAgIH1cbiAgICByZXR1cm4gLTE7XG4gIH1cbiAgcmV0dXJuIGJhc2VJbmRleE9mKGFycmF5LCB2YWx1ZSwgZnJvbUluZGV4IHx8IDApO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGluZGV4T2Y7XG4iLCIvKipcbiAqIEdldHMgdGhlIGxhc3QgZWxlbWVudCBvZiBgYXJyYXlgLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgQXJyYXlcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBsYXN0IGVsZW1lbnQgb2YgYGFycmF5YC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5sYXN0KFsxLCAyLCAzXSk7XG4gKiAvLyA9PiAzXG4gKi9cbmZ1bmN0aW9uIGxhc3QoYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5ID8gYXJyYXkubGVuZ3RoIDogMDtcbiAgcmV0dXJuIGxlbmd0aCA/IGFycmF5W2xlbmd0aCAtIDFdIDogdW5kZWZpbmVkO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGxhc3Q7XG4iLCJ2YXIgTGF6eVdyYXBwZXIgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9MYXp5V3JhcHBlcicpLFxuICAgIExvZGFzaFdyYXBwZXIgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9Mb2Rhc2hXcmFwcGVyJyksXG4gICAgYmFzZUxvZGFzaCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2Jhc2VMb2Rhc2gnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FycmF5JyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNPYmplY3RMaWtlJyksXG4gICAgd3JhcHBlckNsb25lID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvd3JhcHBlckNsb25lJyk7XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBgbG9kYXNoYCBvYmplY3Qgd2hpY2ggd3JhcHMgYHZhbHVlYCB0byBlbmFibGUgaW1wbGljaXQgY2hhaW5pbmcuXG4gKiBNZXRob2RzIHRoYXQgb3BlcmF0ZSBvbiBhbmQgcmV0dXJuIGFycmF5cywgY29sbGVjdGlvbnMsIGFuZCBmdW5jdGlvbnMgY2FuXG4gKiBiZSBjaGFpbmVkIHRvZ2V0aGVyLiBNZXRob2RzIHRoYXQgcmV0cmlldmUgYSBzaW5nbGUgdmFsdWUgb3IgbWF5IHJldHVybiBhXG4gKiBwcmltaXRpdmUgdmFsdWUgd2lsbCBhdXRvbWF0aWNhbGx5IGVuZCB0aGUgY2hhaW4gcmV0dXJuaW5nIHRoZSB1bndyYXBwZWRcbiAqIHZhbHVlLiBFeHBsaWNpdCBjaGFpbmluZyBtYXkgYmUgZW5hYmxlZCB1c2luZyBgXy5jaGFpbmAuIFRoZSBleGVjdXRpb24gb2ZcbiAqIGNoYWluZWQgbWV0aG9kcyBpcyBsYXp5LCB0aGF0IGlzLCBleGVjdXRpb24gaXMgZGVmZXJyZWQgdW50aWwgYF8jdmFsdWVgXG4gKiBpcyBpbXBsaWNpdGx5IG9yIGV4cGxpY2l0bHkgY2FsbGVkLlxuICpcbiAqIExhenkgZXZhbHVhdGlvbiBhbGxvd3Mgc2V2ZXJhbCBtZXRob2RzIHRvIHN1cHBvcnQgc2hvcnRjdXQgZnVzaW9uLiBTaG9ydGN1dFxuICogZnVzaW9uIGlzIGFuIG9wdGltaXphdGlvbiBzdHJhdGVneSB3aGljaCBtZXJnZSBpdGVyYXRlZSBjYWxsczsgdGhpcyBjYW4gaGVscFxuICogdG8gYXZvaWQgdGhlIGNyZWF0aW9uIG9mIGludGVybWVkaWF0ZSBkYXRhIHN0cnVjdHVyZXMgYW5kIGdyZWF0bHkgcmVkdWNlIHRoZVxuICogbnVtYmVyIG9mIGl0ZXJhdGVlIGV4ZWN1dGlvbnMuXG4gKlxuICogQ2hhaW5pbmcgaXMgc3VwcG9ydGVkIGluIGN1c3RvbSBidWlsZHMgYXMgbG9uZyBhcyB0aGUgYF8jdmFsdWVgIG1ldGhvZCBpc1xuICogZGlyZWN0bHkgb3IgaW5kaXJlY3RseSBpbmNsdWRlZCBpbiB0aGUgYnVpbGQuXG4gKlxuICogSW4gYWRkaXRpb24gdG8gbG9kYXNoIG1ldGhvZHMsIHdyYXBwZXJzIGhhdmUgYEFycmF5YCBhbmQgYFN0cmluZ2AgbWV0aG9kcy5cbiAqXG4gKiBUaGUgd3JhcHBlciBgQXJyYXlgIG1ldGhvZHMgYXJlOlxuICogYGNvbmNhdGAsIGBqb2luYCwgYHBvcGAsIGBwdXNoYCwgYHJldmVyc2VgLCBgc2hpZnRgLCBgc2xpY2VgLCBgc29ydGAsXG4gKiBgc3BsaWNlYCwgYW5kIGB1bnNoaWZ0YFxuICpcbiAqIFRoZSB3cmFwcGVyIGBTdHJpbmdgIG1ldGhvZHMgYXJlOlxuICogYHJlcGxhY2VgIGFuZCBgc3BsaXRgXG4gKlxuICogVGhlIHdyYXBwZXIgbWV0aG9kcyB0aGF0IHN1cHBvcnQgc2hvcnRjdXQgZnVzaW9uIGFyZTpcbiAqIGBjb21wYWN0YCwgYGRyb3BgLCBgZHJvcFJpZ2h0YCwgYGRyb3BSaWdodFdoaWxlYCwgYGRyb3BXaGlsZWAsIGBmaWx0ZXJgLFxuICogYGZpcnN0YCwgYGluaXRpYWxgLCBgbGFzdGAsIGBtYXBgLCBgcGx1Y2tgLCBgcmVqZWN0YCwgYHJlc3RgLCBgcmV2ZXJzZWAsXG4gKiBgc2xpY2VgLCBgdGFrZWAsIGB0YWtlUmlnaHRgLCBgdGFrZVJpZ2h0V2hpbGVgLCBgdGFrZVdoaWxlYCwgYHRvQXJyYXlgLFxuICogYW5kIGB3aGVyZWBcbiAqXG4gKiBUaGUgY2hhaW5hYmxlIHdyYXBwZXIgbWV0aG9kcyBhcmU6XG4gKiBgYWZ0ZXJgLCBgYXJ5YCwgYGFzc2lnbmAsIGBhdGAsIGBiZWZvcmVgLCBgYmluZGAsIGBiaW5kQWxsYCwgYGJpbmRLZXlgLFxuICogYGNhbGxiYWNrYCwgYGNoYWluYCwgYGNodW5rYCwgYGNvbW1pdGAsIGBjb21wYWN0YCwgYGNvbmNhdGAsIGBjb25zdGFudGAsXG4gKiBgY291bnRCeWAsIGBjcmVhdGVgLCBgY3VycnlgLCBgZGVib3VuY2VgLCBgZGVmYXVsdHNgLCBgZGVmYXVsdHNEZWVwYCxcbiAqIGBkZWZlcmAsIGBkZWxheWAsIGBkaWZmZXJlbmNlYCwgYGRyb3BgLCBgZHJvcFJpZ2h0YCwgYGRyb3BSaWdodFdoaWxlYCxcbiAqIGBkcm9wV2hpbGVgLCBgZmlsbGAsIGBmaWx0ZXJgLCBgZmxhdHRlbmAsIGBmbGF0dGVuRGVlcGAsIGBmbG93YCwgYGZsb3dSaWdodGAsXG4gKiBgZm9yRWFjaGAsIGBmb3JFYWNoUmlnaHRgLCBgZm9ySW5gLCBgZm9ySW5SaWdodGAsIGBmb3JPd25gLCBgZm9yT3duUmlnaHRgLFxuICogYGZ1bmN0aW9uc2AsIGBncm91cEJ5YCwgYGluZGV4QnlgLCBgaW5pdGlhbGAsIGBpbnRlcnNlY3Rpb25gLCBgaW52ZXJ0YCxcbiAqIGBpbnZva2VgLCBga2V5c2AsIGBrZXlzSW5gLCBgbWFwYCwgYG1hcEtleXNgLCBgbWFwVmFsdWVzYCwgYG1hdGNoZXNgLFxuICogYG1hdGNoZXNQcm9wZXJ0eWAsIGBtZW1vaXplYCwgYG1lcmdlYCwgYG1ldGhvZGAsIGBtZXRob2RPZmAsIGBtaXhpbmAsXG4gKiBgbW9kQXJnc2AsIGBuZWdhdGVgLCBgb21pdGAsIGBvbmNlYCwgYHBhaXJzYCwgYHBhcnRpYWxgLCBgcGFydGlhbFJpZ2h0YCxcbiAqIGBwYXJ0aXRpb25gLCBgcGlja2AsIGBwbGFudGAsIGBwbHVja2AsIGBwcm9wZXJ0eWAsIGBwcm9wZXJ0eU9mYCwgYHB1bGxgLFxuICogYHB1bGxBdGAsIGBwdXNoYCwgYHJhbmdlYCwgYHJlYXJnYCwgYHJlamVjdGAsIGByZW1vdmVgLCBgcmVzdGAsIGByZXN0UGFyYW1gLFxuICogYHJldmVyc2VgLCBgc2V0YCwgYHNodWZmbGVgLCBgc2xpY2VgLCBgc29ydGAsIGBzb3J0QnlgLCBgc29ydEJ5QWxsYCxcbiAqIGBzb3J0QnlPcmRlcmAsIGBzcGxpY2VgLCBgc3ByZWFkYCwgYHRha2VgLCBgdGFrZVJpZ2h0YCwgYHRha2VSaWdodFdoaWxlYCxcbiAqIGB0YWtlV2hpbGVgLCBgdGFwYCwgYHRocm90dGxlYCwgYHRocnVgLCBgdGltZXNgLCBgdG9BcnJheWAsIGB0b1BsYWluT2JqZWN0YCxcbiAqIGB0cmFuc2Zvcm1gLCBgdW5pb25gLCBgdW5pcWAsIGB1bnNoaWZ0YCwgYHVuemlwYCwgYHVuemlwV2l0aGAsIGB2YWx1ZXNgLFxuICogYHZhbHVlc0luYCwgYHdoZXJlYCwgYHdpdGhvdXRgLCBgd3JhcGAsIGB4b3JgLCBgemlwYCwgYHppcE9iamVjdGAsIGB6aXBXaXRoYFxuICpcbiAqIFRoZSB3cmFwcGVyIG1ldGhvZHMgdGhhdCBhcmUgKipub3QqKiBjaGFpbmFibGUgYnkgZGVmYXVsdCBhcmU6XG4gKiBgYWRkYCwgYGF0dGVtcHRgLCBgY2FtZWxDYXNlYCwgYGNhcGl0YWxpemVgLCBgY2VpbGAsIGBjbG9uZWAsIGBjbG9uZURlZXBgLFxuICogYGRlYnVycmAsIGBlbmRzV2l0aGAsIGBlc2NhcGVgLCBgZXNjYXBlUmVnRXhwYCwgYGV2ZXJ5YCwgYGZpbmRgLCBgZmluZEluZGV4YCxcbiAqIGBmaW5kS2V5YCwgYGZpbmRMYXN0YCwgYGZpbmRMYXN0SW5kZXhgLCBgZmluZExhc3RLZXlgLCBgZmluZFdoZXJlYCwgYGZpcnN0YCxcbiAqIGBmbG9vcmAsIGBnZXRgLCBgZ3RgLCBgZ3RlYCwgYGhhc2AsIGBpZGVudGl0eWAsIGBpbmNsdWRlc2AsIGBpbmRleE9mYCxcbiAqIGBpblJhbmdlYCwgYGlzQXJndW1lbnRzYCwgYGlzQXJyYXlgLCBgaXNCb29sZWFuYCwgYGlzRGF0ZWAsIGBpc0VsZW1lbnRgLFxuICogYGlzRW1wdHlgLCBgaXNFcXVhbGAsIGBpc0Vycm9yYCwgYGlzRmluaXRlYCBgaXNGdW5jdGlvbmAsIGBpc01hdGNoYCxcbiAqIGBpc05hdGl2ZWAsIGBpc05hTmAsIGBpc051bGxgLCBgaXNOdW1iZXJgLCBgaXNPYmplY3RgLCBgaXNQbGFpbk9iamVjdGAsXG4gKiBgaXNSZWdFeHBgLCBgaXNTdHJpbmdgLCBgaXNVbmRlZmluZWRgLCBgaXNUeXBlZEFycmF5YCwgYGpvaW5gLCBga2ViYWJDYXNlYCxcbiAqIGBsYXN0YCwgYGxhc3RJbmRleE9mYCwgYGx0YCwgYGx0ZWAsIGBtYXhgLCBgbWluYCwgYG5vQ29uZmxpY3RgLCBgbm9vcGAsXG4gKiBgbm93YCwgYHBhZGAsIGBwYWRMZWZ0YCwgYHBhZFJpZ2h0YCwgYHBhcnNlSW50YCwgYHBvcGAsIGByYW5kb21gLCBgcmVkdWNlYCxcbiAqIGByZWR1Y2VSaWdodGAsIGByZXBlYXRgLCBgcmVzdWx0YCwgYHJvdW5kYCwgYHJ1bkluQ29udGV4dGAsIGBzaGlmdGAsIGBzaXplYCxcbiAqIGBzbmFrZUNhc2VgLCBgc29tZWAsIGBzb3J0ZWRJbmRleGAsIGBzb3J0ZWRMYXN0SW5kZXhgLCBgc3RhcnRDYXNlYCxcbiAqIGBzdGFydHNXaXRoYCwgYHN1bWAsIGB0ZW1wbGF0ZWAsIGB0cmltYCwgYHRyaW1MZWZ0YCwgYHRyaW1SaWdodGAsIGB0cnVuY2AsXG4gKiBgdW5lc2NhcGVgLCBgdW5pcXVlSWRgLCBgdmFsdWVgLCBhbmQgYHdvcmRzYFxuICpcbiAqIFRoZSB3cmFwcGVyIG1ldGhvZCBgc2FtcGxlYCB3aWxsIHJldHVybiBhIHdyYXBwZWQgdmFsdWUgd2hlbiBgbmAgaXMgcHJvdmlkZWQsXG4gKiBvdGhlcndpc2UgYW4gdW53cmFwcGVkIHZhbHVlIGlzIHJldHVybmVkLlxuICpcbiAqIEBuYW1lIF9cbiAqIEBjb25zdHJ1Y3RvclxuICogQGNhdGVnb3J5IENoYWluXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB3cmFwIGluIGEgYGxvZGFzaGAgaW5zdGFuY2UuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgYGxvZGFzaGAgd3JhcHBlciBpbnN0YW5jZS5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIHdyYXBwZWQgPSBfKFsxLCAyLCAzXSk7XG4gKlxuICogLy8gcmV0dXJucyBhbiB1bndyYXBwZWQgdmFsdWVcbiAqIHdyYXBwZWQucmVkdWNlKGZ1bmN0aW9uKHRvdGFsLCBuKSB7XG4gKiAgIHJldHVybiB0b3RhbCArIG47XG4gKiB9KTtcbiAqIC8vID0+IDZcbiAqXG4gKiAvLyByZXR1cm5zIGEgd3JhcHBlZCB2YWx1ZVxuICogdmFyIHNxdWFyZXMgPSB3cmFwcGVkLm1hcChmdW5jdGlvbihuKSB7XG4gKiAgIHJldHVybiBuICogbjtcbiAqIH0pO1xuICpcbiAqIF8uaXNBcnJheShzcXVhcmVzKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc0FycmF5KHNxdWFyZXMudmFsdWUoKSk7XG4gKiAvLyA9PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGxvZGFzaCh2YWx1ZSkge1xuICBpZiAoaXNPYmplY3RMaWtlKHZhbHVlKSAmJiAhaXNBcnJheSh2YWx1ZSkgJiYgISh2YWx1ZSBpbnN0YW5jZW9mIExhenlXcmFwcGVyKSkge1xuICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIExvZGFzaFdyYXBwZXIpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsICdfX2NoYWluX18nKSAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCAnX193cmFwcGVkX18nKSkge1xuICAgICAgcmV0dXJuIHdyYXBwZXJDbG9uZSh2YWx1ZSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBuZXcgTG9kYXNoV3JhcHBlcih2YWx1ZSk7XG59XG5cbi8vIEVuc3VyZSB3cmFwcGVycyBhcmUgaW5zdGFuY2VzIG9mIGBiYXNlTG9kYXNoYC5cbmxvZGFzaC5wcm90b3R5cGUgPSBiYXNlTG9kYXNoLnByb3RvdHlwZTtcblxubW9kdWxlLmV4cG9ydHMgPSBsb2Rhc2g7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vZm9yRWFjaCcpO1xuIiwidmFyIGJhc2VFYWNoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZUVhY2gnKSxcbiAgICBjcmVhdGVGaW5kID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvY3JlYXRlRmluZCcpO1xuXG4vKipcbiAqIEl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2YgYGNvbGxlY3Rpb25gLCByZXR1cm5pbmcgdGhlIGZpcnN0IGVsZW1lbnRcbiAqIGBwcmVkaWNhdGVgIHJldHVybnMgdHJ1dGh5IGZvci4gVGhlIHByZWRpY2F0ZSBpcyBib3VuZCB0byBgdGhpc0FyZ2AgYW5kXG4gKiBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuXG4gKlxuICogSWYgYSBwcm9wZXJ0eSBuYW1lIGlzIHByb3ZpZGVkIGZvciBgcHJlZGljYXRlYCB0aGUgY3JlYXRlZCBgXy5wcm9wZXJ0eWBcbiAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlIG9mIHRoZSBnaXZlbiBlbGVtZW50LlxuICpcbiAqIElmIGEgdmFsdWUgaXMgYWxzbyBwcm92aWRlZCBmb3IgYHRoaXNBcmdgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNQcm9wZXJ0eWBcbiAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgYSBtYXRjaGluZyBwcm9wZXJ0eVxuICogdmFsdWUsIGVsc2UgYGZhbHNlYC5cbiAqXG4gKiBJZiBhbiBvYmplY3QgaXMgcHJvdmlkZWQgZm9yIGBwcmVkaWNhdGVgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNgIHN0eWxlXG4gKiBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBoYXZlIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBnaXZlblxuICogb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBhbGlhcyBkZXRlY3RcbiAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gc2VhcmNoLlxuICogQHBhcmFtIHtGdW5jdGlvbnxPYmplY3R8c3RyaW5nfSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkXG4gKiAgcGVyIGl0ZXJhdGlvbi5cbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgcHJlZGljYXRlYC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBtYXRjaGVkIGVsZW1lbnQsIGVsc2UgYHVuZGVmaW5lZGAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciB1c2VycyA9IFtcbiAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FnZSc6IDM2LCAnYWN0aXZlJzogdHJ1ZSB9LFxuICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICAnYWdlJzogNDAsICdhY3RpdmUnOiBmYWxzZSB9LFxuICogICB7ICd1c2VyJzogJ3BlYmJsZXMnLCAnYWdlJzogMSwgICdhY3RpdmUnOiB0cnVlIH1cbiAqIF07XG4gKlxuICogXy5yZXN1bHQoXy5maW5kKHVzZXJzLCBmdW5jdGlvbihjaHIpIHtcbiAqICAgcmV0dXJuIGNoci5hZ2UgPCA0MDtcbiAqIH0pLCAndXNlcicpO1xuICogLy8gPT4gJ2Jhcm5leSdcbiAqXG4gKiAvLyB1c2luZyB0aGUgYF8ubWF0Y2hlc2AgY2FsbGJhY2sgc2hvcnRoYW5kXG4gKiBfLnJlc3VsdChfLmZpbmQodXNlcnMsIHsgJ2FnZSc6IDEsICdhY3RpdmUnOiB0cnVlIH0pLCAndXNlcicpO1xuICogLy8gPT4gJ3BlYmJsZXMnXG4gKlxuICogLy8gdXNpbmcgdGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgY2FsbGJhY2sgc2hvcnRoYW5kXG4gKiBfLnJlc3VsdChfLmZpbmQodXNlcnMsICdhY3RpdmUnLCBmYWxzZSksICd1c2VyJyk7XG4gKiAvLyA9PiAnZnJlZCdcbiAqXG4gKiAvLyB1c2luZyB0aGUgYF8ucHJvcGVydHlgIGNhbGxiYWNrIHNob3J0aGFuZFxuICogXy5yZXN1bHQoXy5maW5kKHVzZXJzLCAnYWN0aXZlJyksICd1c2VyJyk7XG4gKiAvLyA9PiAnYmFybmV5J1xuICovXG52YXIgZmluZCA9IGNyZWF0ZUZpbmQoYmFzZUVhY2gpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZpbmQ7XG4iLCJ2YXIgYXJyYXlFYWNoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYXJyYXlFYWNoJyksXG4gICAgYmFzZUVhY2ggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlRWFjaCcpLFxuICAgIGNyZWF0ZUZvckVhY2ggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9jcmVhdGVGb3JFYWNoJyk7XG5cbi8qKlxuICogSXRlcmF0ZXMgb3ZlciBlbGVtZW50cyBvZiBgY29sbGVjdGlvbmAgaW52b2tpbmcgYGl0ZXJhdGVlYCBmb3IgZWFjaCBlbGVtZW50LlxuICogVGhlIGBpdGVyYXRlZWAgaXMgYm91bmQgdG8gYHRoaXNBcmdgIGFuZCBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOlxuICogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLiBJdGVyYXRlZSBmdW5jdGlvbnMgbWF5IGV4aXQgaXRlcmF0aW9uIGVhcmx5XG4gKiBieSBleHBsaWNpdGx5IHJldHVybmluZyBgZmFsc2VgLlxuICpcbiAqICoqTm90ZToqKiBBcyB3aXRoIG90aGVyIFwiQ29sbGVjdGlvbnNcIiBtZXRob2RzLCBvYmplY3RzIHdpdGggYSBcImxlbmd0aFwiIHByb3BlcnR5XG4gKiBhcmUgaXRlcmF0ZWQgbGlrZSBhcnJheXMuIFRvIGF2b2lkIHRoaXMgYmVoYXZpb3IgYF8uZm9ySW5gIG9yIGBfLmZvck93bmBcbiAqIG1heSBiZSB1c2VkIGZvciBvYmplY3QgaXRlcmF0aW9uLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAYWxpYXMgZWFjaFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgaXRlcmF0ZWVgLlxuICogQHJldHVybnMge0FycmF5fE9iamVjdHxzdHJpbmd9IFJldHVybnMgYGNvbGxlY3Rpb25gLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfKFsxLCAyXSkuZm9yRWFjaChmdW5jdGlvbihuKSB7XG4gKiAgIGNvbnNvbGUubG9nKG4pO1xuICogfSkudmFsdWUoKTtcbiAqIC8vID0+IGxvZ3MgZWFjaCB2YWx1ZSBmcm9tIGxlZnQgdG8gcmlnaHQgYW5kIHJldHVybnMgdGhlIGFycmF5XG4gKlxuICogXy5mb3JFYWNoKHsgJ2EnOiAxLCAnYic6IDIgfSwgZnVuY3Rpb24obiwga2V5KSB7XG4gKiAgIGNvbnNvbGUubG9nKG4sIGtleSk7XG4gKiB9KTtcbiAqIC8vID0+IGxvZ3MgZWFjaCB2YWx1ZS1rZXkgcGFpciBhbmQgcmV0dXJucyB0aGUgb2JqZWN0IChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gKi9cbnZhciBmb3JFYWNoID0gY3JlYXRlRm9yRWFjaChhcnJheUVhY2gsIGJhc2VFYWNoKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmb3JFYWNoO1xuIiwidmFyIGJhc2VJbmRleE9mID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZUluZGV4T2YnKSxcbiAgICBnZXRMZW5ndGggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9nZXRMZW5ndGgnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FycmF5JyksXG4gICAgaXNJdGVyYXRlZUNhbGwgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0l0ZXJhdGVlQ2FsbCcpLFxuICAgIGlzTGVuZ3RoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNMZW5ndGgnKSxcbiAgICBpc1N0cmluZyA9IHJlcXVpcmUoJy4uL2xhbmcvaXNTdHJpbmcnKSxcbiAgICB2YWx1ZXMgPSByZXF1aXJlKCcuLi9vYmplY3QvdmFsdWVzJyk7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlTWF4ID0gTWF0aC5tYXg7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB0YXJnZXRgIGlzIGluIGBjb2xsZWN0aW9uYCB1c2luZ1xuICogW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAqIGZvciBlcXVhbGl0eSBjb21wYXJpc29ucy4gSWYgYGZyb21JbmRleGAgaXMgbmVnYXRpdmUsIGl0J3MgdXNlZCBhcyB0aGUgb2Zmc2V0XG4gKiBmcm9tIHRoZSBlbmQgb2YgYGNvbGxlY3Rpb25gLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAYWxpYXMgY29udGFpbnMsIGluY2x1ZGVcbiAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gc2VhcmNoLlxuICogQHBhcmFtIHsqfSB0YXJnZXQgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gKiBAcGFyYW0ge251bWJlcn0gW2Zyb21JbmRleD0wXSBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYSBjYWxsYmFjayBmb3IgZnVuY3Rpb25zIGxpa2UgYF8ucmVkdWNlYC5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhIG1hdGNoaW5nIGVsZW1lbnQgaXMgZm91bmQsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pbmNsdWRlcyhbMSwgMiwgM10sIDEpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaW5jbHVkZXMoWzEsIDIsIDNdLCAxLCAyKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pbmNsdWRlcyh7ICd1c2VyJzogJ2ZyZWQnLCAnYWdlJzogNDAgfSwgJ2ZyZWQnKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmluY2x1ZGVzKCdwZWJibGVzJywgJ2ViJyk7XG4gKiAvLyA9PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGluY2x1ZGVzKGNvbGxlY3Rpb24sIHRhcmdldCwgZnJvbUluZGV4LCBndWFyZCkge1xuICB2YXIgbGVuZ3RoID0gY29sbGVjdGlvbiA/IGdldExlbmd0aChjb2xsZWN0aW9uKSA6IDA7XG4gIGlmICghaXNMZW5ndGgobGVuZ3RoKSkge1xuICAgIGNvbGxlY3Rpb24gPSB2YWx1ZXMoY29sbGVjdGlvbik7XG4gICAgbGVuZ3RoID0gY29sbGVjdGlvbi5sZW5ndGg7XG4gIH1cbiAgaWYgKHR5cGVvZiBmcm9tSW5kZXggIT0gJ251bWJlcicgfHwgKGd1YXJkICYmIGlzSXRlcmF0ZWVDYWxsKHRhcmdldCwgZnJvbUluZGV4LCBndWFyZCkpKSB7XG4gICAgZnJvbUluZGV4ID0gMDtcbiAgfSBlbHNlIHtcbiAgICBmcm9tSW5kZXggPSBmcm9tSW5kZXggPCAwID8gbmF0aXZlTWF4KGxlbmd0aCArIGZyb21JbmRleCwgMCkgOiAoZnJvbUluZGV4IHx8IDApO1xuICB9XG4gIHJldHVybiAodHlwZW9mIGNvbGxlY3Rpb24gPT0gJ3N0cmluZycgfHwgIWlzQXJyYXkoY29sbGVjdGlvbikgJiYgaXNTdHJpbmcoY29sbGVjdGlvbikpXG4gICAgPyAoZnJvbUluZGV4IDw9IGxlbmd0aCAmJiBjb2xsZWN0aW9uLmluZGV4T2YodGFyZ2V0LCBmcm9tSW5kZXgpID4gLTEpXG4gICAgOiAoISFsZW5ndGggJiYgYmFzZUluZGV4T2YoY29sbGVjdGlvbiwgdGFyZ2V0LCBmcm9tSW5kZXgpID4gLTEpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGluY2x1ZGVzO1xuIiwidmFyIGFycmF5TWFwID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYXJyYXlNYXAnKSxcbiAgICBiYXNlQ2FsbGJhY2sgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlQ2FsbGJhY2snKSxcbiAgICBiYXNlTWFwID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZU1hcCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IG9mIHZhbHVlcyBieSBydW5uaW5nIGVhY2ggZWxlbWVudCBpbiBgY29sbGVjdGlvbmAgdGhyb3VnaFxuICogYGl0ZXJhdGVlYC4gVGhlIGBpdGVyYXRlZWAgaXMgYm91bmQgdG8gYHRoaXNBcmdgIGFuZCBpbnZva2VkIHdpdGggdGhyZWVcbiAqIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLlxuICpcbiAqIElmIGEgcHJvcGVydHkgbmFtZSBpcyBwcm92aWRlZCBmb3IgYGl0ZXJhdGVlYCB0aGUgY3JlYXRlZCBgXy5wcm9wZXJ0eWBcbiAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlIG9mIHRoZSBnaXZlbiBlbGVtZW50LlxuICpcbiAqIElmIGEgdmFsdWUgaXMgYWxzbyBwcm92aWRlZCBmb3IgYHRoaXNBcmdgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNQcm9wZXJ0eWBcbiAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgYSBtYXRjaGluZyBwcm9wZXJ0eVxuICogdmFsdWUsIGVsc2UgYGZhbHNlYC5cbiAqXG4gKiBJZiBhbiBvYmplY3QgaXMgcHJvdmlkZWQgZm9yIGBpdGVyYXRlZWAgdGhlIGNyZWF0ZWQgYF8ubWF0Y2hlc2Agc3R5bGVcbiAqIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgdGhlIHByb3BlcnRpZXMgb2YgdGhlIGdpdmVuXG4gKiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqXG4gKiBNYW55IGxvZGFzaCBtZXRob2RzIGFyZSBndWFyZGVkIHRvIHdvcmsgYXMgaXRlcmF0ZWVzIGZvciBtZXRob2RzIGxpa2VcbiAqIGBfLmV2ZXJ5YCwgYF8uZmlsdGVyYCwgYF8ubWFwYCwgYF8ubWFwVmFsdWVzYCwgYF8ucmVqZWN0YCwgYW5kIGBfLnNvbWVgLlxuICpcbiAqIFRoZSBndWFyZGVkIG1ldGhvZHMgYXJlOlxuICogYGFyeWAsIGBjYWxsYmFja2AsIGBjaHVua2AsIGBjbG9uZWAsIGBjcmVhdGVgLCBgY3VycnlgLCBgY3VycnlSaWdodGAsXG4gKiBgZHJvcGAsIGBkcm9wUmlnaHRgLCBgZXZlcnlgLCBgZmlsbGAsIGBmbGF0dGVuYCwgYGludmVydGAsIGBtYXhgLCBgbWluYCxcbiAqIGBwYXJzZUludGAsIGBzbGljZWAsIGBzb3J0QnlgLCBgdGFrZWAsIGB0YWtlUmlnaHRgLCBgdGVtcGxhdGVgLCBgdHJpbWAsXG4gKiBgdHJpbUxlZnRgLCBgdHJpbVJpZ2h0YCwgYHRydW5jYCwgYHJhbmRvbWAsIGByYW5nZWAsIGBzYW1wbGVgLCBgc29tZWAsXG4gKiBgc3VtYCwgYHVuaXFgLCBhbmQgYHdvcmRzYFxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAYWxpYXMgY29sbGVjdFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdHxzdHJpbmd9IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZFxuICogIHBlciBpdGVyYXRpb24uXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGl0ZXJhdGVlYC5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IG1hcHBlZCBhcnJheS5cbiAqIEBleGFtcGxlXG4gKlxuICogZnVuY3Rpb24gdGltZXNUaHJlZShuKSB7XG4gKiAgIHJldHVybiBuICogMztcbiAqIH1cbiAqXG4gKiBfLm1hcChbMSwgMl0sIHRpbWVzVGhyZWUpO1xuICogLy8gPT4gWzMsIDZdXG4gKlxuICogXy5tYXAoeyAnYSc6IDEsICdiJzogMiB9LCB0aW1lc1RocmVlKTtcbiAqIC8vID0+IFszLCA2XSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICpcbiAqIHZhciB1c2VycyA9IFtcbiAqICAgeyAndXNlcic6ICdiYXJuZXknIH0sXG4gKiAgIHsgJ3VzZXInOiAnZnJlZCcgfVxuICogXTtcbiAqXG4gKiAvLyB1c2luZyB0aGUgYF8ucHJvcGVydHlgIGNhbGxiYWNrIHNob3J0aGFuZFxuICogXy5tYXAodXNlcnMsICd1c2VyJyk7XG4gKiAvLyA9PiBbJ2Jhcm5leScsICdmcmVkJ11cbiAqL1xuZnVuY3Rpb24gbWFwKGNvbGxlY3Rpb24sIGl0ZXJhdGVlLCB0aGlzQXJnKSB7XG4gIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5TWFwIDogYmFzZU1hcDtcbiAgaXRlcmF0ZWUgPSBiYXNlQ2FsbGJhY2soaXRlcmF0ZWUsIHRoaXNBcmcsIDMpO1xuICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBpdGVyYXRlZSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWFwO1xuIiwidmFyIGdldE5hdGl2ZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2dldE5hdGl2ZScpO1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU5vdyA9IGdldE5hdGl2ZShEYXRlLCAnbm93Jyk7XG5cbi8qKlxuICogR2V0cyB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0aGF0IGhhdmUgZWxhcHNlZCBzaW5jZSB0aGUgVW5peCBlcG9jaFxuICogKDEgSmFudWFyeSAxOTcwIDAwOjAwOjAwIFVUQykuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBEYXRlXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uZGVmZXIoZnVuY3Rpb24oc3RhbXApIHtcbiAqICAgY29uc29sZS5sb2coXy5ub3coKSAtIHN0YW1wKTtcbiAqIH0sIF8ubm93KCkpO1xuICogLy8gPT4gbG9ncyB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBpdCB0b29rIGZvciB0aGUgZGVmZXJyZWQgZnVuY3Rpb24gdG8gYmUgaW52b2tlZFxuICovXG52YXIgbm93ID0gbmF0aXZlTm93IHx8IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5vdztcbiIsInZhciBjcmVhdGVXcmFwcGVyID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvY3JlYXRlV3JhcHBlcicpLFxuICAgIHJlcGxhY2VIb2xkZXJzID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvcmVwbGFjZUhvbGRlcnMnKSxcbiAgICByZXN0UGFyYW0gPSByZXF1aXJlKCcuL3Jlc3RQYXJhbScpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB3cmFwcGVyIG1ldGFkYXRhLiAqL1xudmFyIEJJTkRfRkxBRyA9IDEsXG4gICAgUEFSVElBTF9GTEFHID0gMzI7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgYHRoaXNBcmdgXG4gKiBhbmQgcHJlcGVuZHMgYW55IGFkZGl0aW9uYWwgYF8uYmluZGAgYXJndW1lbnRzIHRvIHRob3NlIHByb3ZpZGVkIHRvIHRoZVxuICogYm91bmQgZnVuY3Rpb24uXG4gKlxuICogVGhlIGBfLmJpbmQucGxhY2Vob2xkZXJgIHZhbHVlLCB3aGljaCBkZWZhdWx0cyB0byBgX2AgaW4gbW9ub2xpdGhpYyBidWlsZHMsXG4gKiBtYXkgYmUgdXNlZCBhcyBhIHBsYWNlaG9sZGVyIGZvciBwYXJ0aWFsbHkgYXBwbGllZCBhcmd1bWVudHMuXG4gKlxuICogKipOb3RlOioqIFVubGlrZSBuYXRpdmUgYEZ1bmN0aW9uI2JpbmRgIHRoaXMgbWV0aG9kIGRvZXMgbm90IHNldCB0aGUgXCJsZW5ndGhcIlxuICogcHJvcGVydHkgb2YgYm91bmQgZnVuY3Rpb25zLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGJpbmQuXG4gKiBAcGFyYW0geyp9IHRoaXNBcmcgVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7Li4uKn0gW3BhcnRpYWxzXSBUaGUgYXJndW1lbnRzIHRvIGJlIHBhcnRpYWxseSBhcHBsaWVkLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYm91bmQgZnVuY3Rpb24uXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBncmVldCA9IGZ1bmN0aW9uKGdyZWV0aW5nLCBwdW5jdHVhdGlvbikge1xuICogICByZXR1cm4gZ3JlZXRpbmcgKyAnICcgKyB0aGlzLnVzZXIgKyBwdW5jdHVhdGlvbjtcbiAqIH07XG4gKlxuICogdmFyIG9iamVjdCA9IHsgJ3VzZXInOiAnZnJlZCcgfTtcbiAqXG4gKiB2YXIgYm91bmQgPSBfLmJpbmQoZ3JlZXQsIG9iamVjdCwgJ2hpJyk7XG4gKiBib3VuZCgnIScpO1xuICogLy8gPT4gJ2hpIGZyZWQhJ1xuICpcbiAqIC8vIHVzaW5nIHBsYWNlaG9sZGVyc1xuICogdmFyIGJvdW5kID0gXy5iaW5kKGdyZWV0LCBvYmplY3QsIF8sICchJyk7XG4gKiBib3VuZCgnaGknKTtcbiAqIC8vID0+ICdoaSBmcmVkISdcbiAqL1xudmFyIGJpbmQgPSByZXN0UGFyYW0oZnVuY3Rpb24oZnVuYywgdGhpc0FyZywgcGFydGlhbHMpIHtcbiAgdmFyIGJpdG1hc2sgPSBCSU5EX0ZMQUc7XG4gIGlmIChwYXJ0aWFscy5sZW5ndGgpIHtcbiAgICB2YXIgaG9sZGVycyA9IHJlcGxhY2VIb2xkZXJzKHBhcnRpYWxzLCBiaW5kLnBsYWNlaG9sZGVyKTtcbiAgICBiaXRtYXNrIHw9IFBBUlRJQUxfRkxBRztcbiAgfVxuICByZXR1cm4gY3JlYXRlV3JhcHBlcihmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscywgaG9sZGVycyk7XG59KTtcblxuLy8gQXNzaWduIGRlZmF1bHQgcGxhY2Vob2xkZXJzLlxuYmluZC5wbGFjZWhvbGRlciA9IHt9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJpbmQ7XG4iLCIvKiogVXNlZCBhcyB0aGUgYFR5cGVFcnJvcmAgbWVzc2FnZSBmb3IgXCJGdW5jdGlvbnNcIiBtZXRob2RzLiAqL1xudmFyIEZVTkNfRVJST1JfVEVYVCA9ICdFeHBlY3RlZCBhIGZ1bmN0aW9uJztcblxuLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heDtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBmdW5jYCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBvZiB0aGVcbiAqIGNyZWF0ZWQgZnVuY3Rpb24gYW5kIGFyZ3VtZW50cyBmcm9tIGBzdGFydGAgYW5kIGJleW9uZCBwcm92aWRlZCBhcyBhbiBhcnJheS5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgYmFzZWQgb24gdGhlIFtyZXN0IHBhcmFtZXRlcl0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0Z1bmN0aW9ucy9yZXN0X3BhcmFtZXRlcnMpLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFwcGx5IGEgcmVzdCBwYXJhbWV0ZXIgdG8uXG4gKiBAcGFyYW0ge251bWJlcn0gW3N0YXJ0PWZ1bmMubGVuZ3RoLTFdIFRoZSBzdGFydCBwb3NpdGlvbiBvZiB0aGUgcmVzdCBwYXJhbWV0ZXIuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIHNheSA9IF8ucmVzdFBhcmFtKGZ1bmN0aW9uKHdoYXQsIG5hbWVzKSB7XG4gKiAgIHJldHVybiB3aGF0ICsgJyAnICsgXy5pbml0aWFsKG5hbWVzKS5qb2luKCcsICcpICtcbiAqICAgICAoXy5zaXplKG5hbWVzKSA+IDEgPyAnLCAmICcgOiAnJykgKyBfLmxhc3QobmFtZXMpO1xuICogfSk7XG4gKlxuICogc2F5KCdoZWxsbycsICdmcmVkJywgJ2Jhcm5leScsICdwZWJibGVzJyk7XG4gKiAvLyA9PiAnaGVsbG8gZnJlZCwgYmFybmV5LCAmIHBlYmJsZXMnXG4gKi9cbmZ1bmN0aW9uIHJlc3RQYXJhbShmdW5jLCBzdGFydCkge1xuICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgfVxuICBzdGFydCA9IG5hdGl2ZU1heChzdGFydCA9PT0gdW5kZWZpbmVkID8gKGZ1bmMubGVuZ3RoIC0gMSkgOiAoK3N0YXJ0IHx8IDApLCAwKTtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciBhcmdzID0gYXJndW1lbnRzLFxuICAgICAgICBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSBuYXRpdmVNYXgoYXJncy5sZW5ndGggLSBzdGFydCwgMCksXG4gICAgICAgIHJlc3QgPSBBcnJheShsZW5ndGgpO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIHJlc3RbaW5kZXhdID0gYXJnc1tzdGFydCArIGluZGV4XTtcbiAgICB9XG4gICAgc3dpdGNoIChzdGFydCkge1xuICAgICAgY2FzZSAwOiByZXR1cm4gZnVuYy5jYWxsKHRoaXMsIHJlc3QpO1xuICAgICAgY2FzZSAxOiByZXR1cm4gZnVuYy5jYWxsKHRoaXMsIGFyZ3NbMF0sIHJlc3QpO1xuICAgICAgY2FzZSAyOiByZXR1cm4gZnVuYy5jYWxsKHRoaXMsIGFyZ3NbMF0sIGFyZ3NbMV0sIHJlc3QpO1xuICAgIH1cbiAgICB2YXIgb3RoZXJBcmdzID0gQXJyYXkoc3RhcnQgKyAxKTtcbiAgICBpbmRleCA9IC0xO1xuICAgIHdoaWxlICgrK2luZGV4IDwgc3RhcnQpIHtcbiAgICAgIG90aGVyQXJnc1tpbmRleF0gPSBhcmdzW2luZGV4XTtcbiAgICB9XG4gICAgb3RoZXJBcmdzW3N0YXJ0XSA9IHJlc3Q7XG4gICAgcmV0dXJuIGZ1bmMuYXBwbHkodGhpcywgb3RoZXJBcmdzKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSByZXN0UGFyYW07XG4iLCJ2YXIgYmFzZUNyZWF0ZSA9IHJlcXVpcmUoJy4vYmFzZUNyZWF0ZScpLFxuICAgIGJhc2VMb2Rhc2ggPSByZXF1aXJlKCcuL2Jhc2VMb2Rhc2gnKTtcblxuLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgYC1JbmZpbml0eWAgYW5kIGBJbmZpbml0eWAuICovXG52YXIgUE9TSVRJVkVfSU5GSU5JVFkgPSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGxhenkgd3JhcHBlciBvYmplY3Qgd2hpY2ggd3JhcHMgYHZhbHVlYCB0byBlbmFibGUgbGF6eSBldmFsdWF0aW9uLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB3cmFwLlxuICovXG5mdW5jdGlvbiBMYXp5V3JhcHBlcih2YWx1ZSkge1xuICB0aGlzLl9fd3JhcHBlZF9fID0gdmFsdWU7XG4gIHRoaXMuX19hY3Rpb25zX18gPSBbXTtcbiAgdGhpcy5fX2Rpcl9fID0gMTtcbiAgdGhpcy5fX2ZpbHRlcmVkX18gPSBmYWxzZTtcbiAgdGhpcy5fX2l0ZXJhdGVlc19fID0gW107XG4gIHRoaXMuX190YWtlQ291bnRfXyA9IFBPU0lUSVZFX0lORklOSVRZO1xuICB0aGlzLl9fdmlld3NfXyA9IFtdO1xufVxuXG5MYXp5V3JhcHBlci5wcm90b3R5cGUgPSBiYXNlQ3JlYXRlKGJhc2VMb2Rhc2gucHJvdG90eXBlKTtcbkxhenlXcmFwcGVyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IExhenlXcmFwcGVyO1xuXG5tb2R1bGUuZXhwb3J0cyA9IExhenlXcmFwcGVyO1xuIiwidmFyIGJhc2VDcmVhdGUgPSByZXF1aXJlKCcuL2Jhc2VDcmVhdGUnKSxcbiAgICBiYXNlTG9kYXNoID0gcmVxdWlyZSgnLi9iYXNlTG9kYXNoJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgY29uc3RydWN0b3IgZm9yIGNyZWF0aW5nIGBsb2Rhc2hgIHdyYXBwZXIgb2JqZWN0cy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gd3JhcC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2NoYWluQWxsXSBFbmFibGUgY2hhaW5pbmcgZm9yIGFsbCB3cmFwcGVyIG1ldGhvZHMuXG4gKiBAcGFyYW0ge0FycmF5fSBbYWN0aW9ucz1bXV0gQWN0aW9ucyB0byBwZWZvcm0gdG8gcmVzb2x2ZSB0aGUgdW53cmFwcGVkIHZhbHVlLlxuICovXG5mdW5jdGlvbiBMb2Rhc2hXcmFwcGVyKHZhbHVlLCBjaGFpbkFsbCwgYWN0aW9ucykge1xuICB0aGlzLl9fd3JhcHBlZF9fID0gdmFsdWU7XG4gIHRoaXMuX19hY3Rpb25zX18gPSBhY3Rpb25zIHx8IFtdO1xuICB0aGlzLl9fY2hhaW5fXyA9ICEhY2hhaW5BbGw7XG59XG5cbkxvZGFzaFdyYXBwZXIucHJvdG90eXBlID0gYmFzZUNyZWF0ZShiYXNlTG9kYXNoLnByb3RvdHlwZSk7XG5Mb2Rhc2hXcmFwcGVyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IExvZGFzaFdyYXBwZXI7XG5cbm1vZHVsZS5leHBvcnRzID0gTG9kYXNoV3JhcHBlcjtcbiIsIi8qKlxuICogQ29waWVzIHRoZSB2YWx1ZXMgb2YgYHNvdXJjZWAgdG8gYGFycmF5YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gc291cmNlIFRoZSBhcnJheSB0byBjb3B5IHZhbHVlcyBmcm9tLlxuICogQHBhcmFtIHtBcnJheX0gW2FycmF5PVtdXSBUaGUgYXJyYXkgdG8gY29weSB2YWx1ZXMgdG8uXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAqL1xuZnVuY3Rpb24gYXJyYXlDb3B5KHNvdXJjZSwgYXJyYXkpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBzb3VyY2UubGVuZ3RoO1xuXG4gIGFycmF5IHx8IChhcnJheSA9IEFycmF5KGxlbmd0aCkpO1xuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGFycmF5W2luZGV4XSA9IHNvdXJjZVtpbmRleF07XG4gIH1cbiAgcmV0dXJuIGFycmF5O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFycmF5Q29weTtcbiIsIi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmZvckVhY2hgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGFycmF5RWFjaChhcnJheSwgaXRlcmF0ZWUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBpZiAoaXRlcmF0ZWUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpID09PSBmYWxzZSkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHJldHVybiBhcnJheTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcnJheUVhY2g7XG4iLCIvKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5tYXBgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgbWFwcGVkIGFycmF5LlxuICovXG5mdW5jdGlvbiBhcnJheU1hcChhcnJheSwgaXRlcmF0ZWUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBBcnJheShsZW5ndGgpO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgcmVzdWx0W2luZGV4XSA9IGl0ZXJhdGVlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFycmF5TWFwO1xuIiwiLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uc29tZWAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gKiBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFueSBlbGVtZW50IHBhc3NlcyB0aGUgcHJlZGljYXRlIGNoZWNrLFxuICogIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYXJyYXlTb21lKGFycmF5LCBwcmVkaWNhdGUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBpZiAocHJlZGljYXRlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcnJheVNvbWU7XG4iLCJ2YXIgYmFzZUNvcHkgPSByZXF1aXJlKCcuL2Jhc2VDb3B5JyksXG4gICAga2V5cyA9IHJlcXVpcmUoJy4uL29iamVjdC9rZXlzJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uYXNzaWduYCB3aXRob3V0IHN1cHBvcnQgZm9yIGFyZ3VtZW50IGp1Z2dsaW5nLFxuICogbXVsdGlwbGUgc291cmNlcywgYW5kIGBjdXN0b21pemVyYCBmdW5jdGlvbnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIHNvdXJjZSBvYmplY3QuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICovXG5mdW5jdGlvbiBiYXNlQXNzaWduKG9iamVjdCwgc291cmNlKSB7XG4gIHJldHVybiBzb3VyY2UgPT0gbnVsbFxuICAgID8gb2JqZWN0XG4gICAgOiBiYXNlQ29weShzb3VyY2UsIGtleXMoc291cmNlKSwgb2JqZWN0KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlQXNzaWduO1xuIiwidmFyIGJhc2VNYXRjaGVzID0gcmVxdWlyZSgnLi9iYXNlTWF0Y2hlcycpLFxuICAgIGJhc2VNYXRjaGVzUHJvcGVydHkgPSByZXF1aXJlKCcuL2Jhc2VNYXRjaGVzUHJvcGVydHknKSxcbiAgICBiaW5kQ2FsbGJhY2sgPSByZXF1aXJlKCcuL2JpbmRDYWxsYmFjaycpLFxuICAgIGlkZW50aXR5ID0gcmVxdWlyZSgnLi4vdXRpbGl0eS9pZGVudGl0eScpLFxuICAgIHByb3BlcnR5ID0gcmVxdWlyZSgnLi4vdXRpbGl0eS9wcm9wZXJ0eScpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmNhbGxiYWNrYCB3aGljaCBzdXBwb3J0cyBzcGVjaWZ5aW5nIHRoZVxuICogbnVtYmVyIG9mIGFyZ3VtZW50cyB0byBwcm92aWRlIHRvIGBmdW5jYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSBbZnVuYz1fLmlkZW50aXR5XSBUaGUgdmFsdWUgdG8gY29udmVydCB0byBhIGNhbGxiYWNrLlxuICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJnQ291bnRdIFRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHRvIHByb3ZpZGUgdG8gYGZ1bmNgLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBjYWxsYmFjay5cbiAqL1xuZnVuY3Rpb24gYmFzZUNhbGxiYWNrKGZ1bmMsIHRoaXNBcmcsIGFyZ0NvdW50KSB7XG4gIHZhciB0eXBlID0gdHlwZW9mIGZ1bmM7XG4gIGlmICh0eXBlID09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gdGhpc0FyZyA9PT0gdW5kZWZpbmVkXG4gICAgICA/IGZ1bmNcbiAgICAgIDogYmluZENhbGxiYWNrKGZ1bmMsIHRoaXNBcmcsIGFyZ0NvdW50KTtcbiAgfVxuICBpZiAoZnVuYyA9PSBudWxsKSB7XG4gICAgcmV0dXJuIGlkZW50aXR5O1xuICB9XG4gIGlmICh0eXBlID09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIGJhc2VNYXRjaGVzKGZ1bmMpO1xuICB9XG4gIHJldHVybiB0aGlzQXJnID09PSB1bmRlZmluZWRcbiAgICA/IHByb3BlcnR5KGZ1bmMpXG4gICAgOiBiYXNlTWF0Y2hlc1Byb3BlcnR5KGZ1bmMsIHRoaXNBcmcpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VDYWxsYmFjaztcbiIsInZhciBhcnJheUNvcHkgPSByZXF1aXJlKCcuL2FycmF5Q29weScpLFxuICAgIGFycmF5RWFjaCA9IHJlcXVpcmUoJy4vYXJyYXlFYWNoJyksXG4gICAgYmFzZUFzc2lnbiA9IHJlcXVpcmUoJy4vYmFzZUFzc2lnbicpLFxuICAgIGJhc2VGb3JPd24gPSByZXF1aXJlKCcuL2Jhc2VGb3JPd24nKSxcbiAgICBpbml0Q2xvbmVBcnJheSA9IHJlcXVpcmUoJy4vaW5pdENsb25lQXJyYXknKSxcbiAgICBpbml0Q2xvbmVCeVRhZyA9IHJlcXVpcmUoJy4vaW5pdENsb25lQnlUYWcnKSxcbiAgICBpbml0Q2xvbmVPYmplY3QgPSByZXF1aXJlKCcuL2luaXRDbG9uZU9iamVjdCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICBpc0hvc3RPYmplY3QgPSByZXF1aXJlKCcuL2lzSG9zdE9iamVjdCcpLFxuICAgIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vbGFuZy9pc09iamVjdCcpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYXJnc1RhZyA9ICdbb2JqZWN0IEFyZ3VtZW50c10nLFxuICAgIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJyxcbiAgICBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgZXJyb3JUYWcgPSAnW29iamVjdCBFcnJvcl0nLFxuICAgIGZ1bmNUYWcgPSAnW29iamVjdCBGdW5jdGlvbl0nLFxuICAgIG1hcFRhZyA9ICdbb2JqZWN0IE1hcF0nLFxuICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nLFxuICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLFxuICAgIHNldFRhZyA9ICdbb2JqZWN0IFNldF0nLFxuICAgIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nLFxuICAgIHdlYWtNYXBUYWcgPSAnW29iamVjdCBXZWFrTWFwXSc7XG5cbnZhciBhcnJheUJ1ZmZlclRhZyA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsXG4gICAgZmxvYXQzMlRhZyA9ICdbb2JqZWN0IEZsb2F0MzJBcnJheV0nLFxuICAgIGZsb2F0NjRUYWcgPSAnW29iamVjdCBGbG9hdDY0QXJyYXldJyxcbiAgICBpbnQ4VGFnID0gJ1tvYmplY3QgSW50OEFycmF5XScsXG4gICAgaW50MTZUYWcgPSAnW29iamVjdCBJbnQxNkFycmF5XScsXG4gICAgaW50MzJUYWcgPSAnW29iamVjdCBJbnQzMkFycmF5XScsXG4gICAgdWludDhUYWcgPSAnW29iamVjdCBVaW50OEFycmF5XScsXG4gICAgdWludDhDbGFtcGVkVGFnID0gJ1tvYmplY3QgVWludDhDbGFtcGVkQXJyYXldJyxcbiAgICB1aW50MTZUYWcgPSAnW29iamVjdCBVaW50MTZBcnJheV0nLFxuICAgIHVpbnQzMlRhZyA9ICdbb2JqZWN0IFVpbnQzMkFycmF5XSc7XG5cbi8qKiBVc2VkIHRvIGlkZW50aWZ5IGB0b1N0cmluZ1RhZ2AgdmFsdWVzIHN1cHBvcnRlZCBieSBgXy5jbG9uZWAuICovXG52YXIgY2xvbmVhYmxlVGFncyA9IHt9O1xuY2xvbmVhYmxlVGFnc1thcmdzVGFnXSA9IGNsb25lYWJsZVRhZ3NbYXJyYXlUYWddID1cbmNsb25lYWJsZVRhZ3NbYXJyYXlCdWZmZXJUYWddID0gY2xvbmVhYmxlVGFnc1tib29sVGFnXSA9XG5jbG9uZWFibGVUYWdzW2RhdGVUYWddID0gY2xvbmVhYmxlVGFnc1tmbG9hdDMyVGFnXSA9XG5jbG9uZWFibGVUYWdzW2Zsb2F0NjRUYWddID0gY2xvbmVhYmxlVGFnc1tpbnQ4VGFnXSA9XG5jbG9uZWFibGVUYWdzW2ludDE2VGFnXSA9IGNsb25lYWJsZVRhZ3NbaW50MzJUYWddID1cbmNsb25lYWJsZVRhZ3NbbnVtYmVyVGFnXSA9IGNsb25lYWJsZVRhZ3Nbb2JqZWN0VGFnXSA9XG5jbG9uZWFibGVUYWdzW3JlZ2V4cFRhZ10gPSBjbG9uZWFibGVUYWdzW3N0cmluZ1RhZ10gPVxuY2xvbmVhYmxlVGFnc1t1aW50OFRhZ10gPSBjbG9uZWFibGVUYWdzW3VpbnQ4Q2xhbXBlZFRhZ10gPVxuY2xvbmVhYmxlVGFnc1t1aW50MTZUYWddID0gY2xvbmVhYmxlVGFnc1t1aW50MzJUYWddID0gdHJ1ZTtcbmNsb25lYWJsZVRhZ3NbZXJyb3JUYWddID0gY2xvbmVhYmxlVGFnc1tmdW5jVGFnXSA9XG5jbG9uZWFibGVUYWdzW21hcFRhZ10gPSBjbG9uZWFibGVUYWdzW3NldFRhZ10gPVxuY2xvbmVhYmxlVGFnc1t3ZWFrTWFwVGFnXSA9IGZhbHNlO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5jbG9uZWAgd2l0aG91dCBzdXBwb3J0IGZvciBhcmd1bWVudCBqdWdnbGluZ1xuICogYW5kIGB0aGlzYCBiaW5kaW5nIGBjdXN0b21pemVyYCBmdW5jdGlvbnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNsb25lLlxuICogQHBhcmFtIHtib29sZWFufSBbaXNEZWVwXSBTcGVjaWZ5IGEgZGVlcCBjbG9uZS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNsb25pbmcgdmFsdWVzLlxuICogQHBhcmFtIHtzdHJpbmd9IFtrZXldIFRoZSBrZXkgb2YgYHZhbHVlYC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0XSBUaGUgb2JqZWN0IGB2YWx1ZWAgYmVsb25ncyB0by5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0E9W11dIFRyYWNrcyB0cmF2ZXJzZWQgc291cmNlIG9iamVjdHMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tCPVtdXSBBc3NvY2lhdGVzIGNsb25lcyB3aXRoIHNvdXJjZSBjb3VudGVycGFydHMuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgY2xvbmVkIHZhbHVlLlxuICovXG5mdW5jdGlvbiBiYXNlQ2xvbmUodmFsdWUsIGlzRGVlcCwgY3VzdG9taXplciwga2V5LCBvYmplY3QsIHN0YWNrQSwgc3RhY2tCKSB7XG4gIHZhciByZXN1bHQ7XG4gIGlmIChjdXN0b21pemVyKSB7XG4gICAgcmVzdWx0ID0gb2JqZWN0ID8gY3VzdG9taXplcih2YWx1ZSwga2V5LCBvYmplY3QpIDogY3VzdG9taXplcih2YWx1ZSk7XG4gIH1cbiAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICBpZiAoIWlzT2JqZWN0KHZhbHVlKSkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuICB2YXIgaXNBcnIgPSBpc0FycmF5KHZhbHVlKTtcbiAgaWYgKGlzQXJyKSB7XG4gICAgcmVzdWx0ID0gaW5pdENsb25lQXJyYXkodmFsdWUpO1xuICAgIGlmICghaXNEZWVwKSB7XG4gICAgICByZXR1cm4gYXJyYXlDb3B5KHZhbHVlLCByZXN1bHQpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgdGFnID0gb2JqVG9TdHJpbmcuY2FsbCh2YWx1ZSksXG4gICAgICAgIGlzRnVuYyA9IHRhZyA9PSBmdW5jVGFnO1xuXG4gICAgaWYgKHRhZyA9PSBvYmplY3RUYWcgfHwgdGFnID09IGFyZ3NUYWcgfHwgKGlzRnVuYyAmJiAhb2JqZWN0KSkge1xuICAgICAgaWYgKGlzSG9zdE9iamVjdCh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIG9iamVjdCA/IHZhbHVlIDoge307XG4gICAgICB9XG4gICAgICByZXN1bHQgPSBpbml0Q2xvbmVPYmplY3QoaXNGdW5jID8ge30gOiB2YWx1ZSk7XG4gICAgICBpZiAoIWlzRGVlcCkge1xuICAgICAgICByZXR1cm4gYmFzZUFzc2lnbihyZXN1bHQsIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGNsb25lYWJsZVRhZ3NbdGFnXVxuICAgICAgICA/IGluaXRDbG9uZUJ5VGFnKHZhbHVlLCB0YWcsIGlzRGVlcClcbiAgICAgICAgOiAob2JqZWN0ID8gdmFsdWUgOiB7fSk7XG4gICAgfVxuICB9XG4gIC8vIENoZWNrIGZvciBjaXJjdWxhciByZWZlcmVuY2VzIGFuZCByZXR1cm4gaXRzIGNvcnJlc3BvbmRpbmcgY2xvbmUuXG4gIHN0YWNrQSB8fCAoc3RhY2tBID0gW10pO1xuICBzdGFja0IgfHwgKHN0YWNrQiA9IFtdKTtcblxuICB2YXIgbGVuZ3RoID0gc3RhY2tBLmxlbmd0aDtcbiAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgaWYgKHN0YWNrQVtsZW5ndGhdID09IHZhbHVlKSB7XG4gICAgICByZXR1cm4gc3RhY2tCW2xlbmd0aF07XG4gICAgfVxuICB9XG4gIC8vIEFkZCB0aGUgc291cmNlIHZhbHVlIHRvIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgb2JqZWN0cyBhbmQgYXNzb2NpYXRlIGl0IHdpdGggaXRzIGNsb25lLlxuICBzdGFja0EucHVzaCh2YWx1ZSk7XG4gIHN0YWNrQi5wdXNoKHJlc3VsdCk7XG5cbiAgLy8gUmVjdXJzaXZlbHkgcG9wdWxhdGUgY2xvbmUgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgKGlzQXJyID8gYXJyYXlFYWNoIDogYmFzZUZvck93bikodmFsdWUsIGZ1bmN0aW9uKHN1YlZhbHVlLCBrZXkpIHtcbiAgICByZXN1bHRba2V5XSA9IGJhc2VDbG9uZShzdWJWYWx1ZSwgaXNEZWVwLCBjdXN0b21pemVyLCBrZXksIHZhbHVlLCBzdGFja0EsIHN0YWNrQik7XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VDbG9uZTtcbiIsIi8qKlxuICogQ29waWVzIHByb3BlcnRpZXMgb2YgYHNvdXJjZWAgdG8gYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCB0byBjb3B5IHByb3BlcnRpZXMgZnJvbS5cbiAqIEBwYXJhbSB7QXJyYXl9IHByb3BzIFRoZSBwcm9wZXJ0eSBuYW1lcyB0byBjb3B5LlxuICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3Q9e31dIFRoZSBvYmplY3QgdG8gY29weSBwcm9wZXJ0aWVzIHRvLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gYmFzZUNvcHkoc291cmNlLCBwcm9wcywgb2JqZWN0KSB7XG4gIG9iamVjdCB8fCAob2JqZWN0ID0ge30pO1xuXG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gcHJvcHMubGVuZ3RoO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgdmFyIGtleSA9IHByb3BzW2luZGV4XTtcbiAgICBvYmplY3Rba2V5XSA9IHNvdXJjZVtrZXldO1xuICB9XG4gIHJldHVybiBvYmplY3Q7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUNvcHk7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uY3JlYXRlYCB3aXRob3V0IHN1cHBvcnQgZm9yIGFzc2lnbmluZ1xuICogcHJvcGVydGllcyB0byB0aGUgY3JlYXRlZCBvYmplY3QuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBwcm90b3R5cGUgVGhlIG9iamVjdCB0byBpbmhlcml0IGZyb20uXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICovXG52YXIgYmFzZUNyZWF0ZSA9IChmdW5jdGlvbigpIHtcbiAgZnVuY3Rpb24gb2JqZWN0KCkge31cbiAgcmV0dXJuIGZ1bmN0aW9uKHByb3RvdHlwZSkge1xuICAgIGlmIChpc09iamVjdChwcm90b3R5cGUpKSB7XG4gICAgICBvYmplY3QucHJvdG90eXBlID0gcHJvdG90eXBlO1xuICAgICAgdmFyIHJlc3VsdCA9IG5ldyBvYmplY3Q7XG4gICAgICBvYmplY3QucHJvdG90eXBlID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0IHx8IHt9O1xuICB9O1xufSgpKTtcblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlQ3JlYXRlO1xuIiwidmFyIGJhc2VGb3JPd24gPSByZXF1aXJlKCcuL2Jhc2VGb3JPd24nKSxcbiAgICBjcmVhdGVCYXNlRWFjaCA9IHJlcXVpcmUoJy4vY3JlYXRlQmFzZUVhY2gnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mb3JFYWNoYCB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gKiBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fHN0cmluZ30gUmV0dXJucyBgY29sbGVjdGlvbmAuXG4gKi9cbnZhciBiYXNlRWFjaCA9IGNyZWF0ZUJhc2VFYWNoKGJhc2VGb3JPd24pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VFYWNoO1xuIiwiLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5maW5kYCwgYF8uZmluZExhc3RgLCBgXy5maW5kS2V5YCwgYW5kIGBfLmZpbmRMYXN0S2V5YCxcbiAqIHdpdGhvdXQgc3VwcG9ydCBmb3IgY2FsbGJhY2sgc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcsIHdoaWNoIGl0ZXJhdGVzXG4gKiBvdmVyIGBjb2xsZWN0aW9uYCB1c2luZyB0aGUgcHJvdmlkZWQgYGVhY2hGdW5jYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHNlYXJjaC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZWFjaEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBgY29sbGVjdGlvbmAuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtyZXRLZXldIFNwZWNpZnkgcmV0dXJuaW5nIHRoZSBrZXkgb2YgdGhlIGZvdW5kIGVsZW1lbnRcbiAqICBpbnN0ZWFkIG9mIHRoZSBlbGVtZW50IGl0c2VsZi5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBmb3VuZCBlbGVtZW50IG9yIGl0cyBrZXksIGVsc2UgYHVuZGVmaW5lZGAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VGaW5kKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgZWFjaEZ1bmMsIHJldEtleSkge1xuICB2YXIgcmVzdWx0O1xuICBlYWNoRnVuYyhjb2xsZWN0aW9uLCBmdW5jdGlvbih2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKSB7XG4gICAgaWYgKHByZWRpY2F0ZSh2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKSkge1xuICAgICAgcmVzdWx0ID0gcmV0S2V5ID8ga2V5IDogdmFsdWU7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlRmluZDtcbiIsIi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZmluZEluZGV4YCBhbmQgYF8uZmluZExhc3RJbmRleGAgd2l0aG91dFxuICogc3VwcG9ydCBmb3IgY2FsbGJhY2sgc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzZWFyY2guXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIG1hdGNoZWQgdmFsdWUsIGVsc2UgYC0xYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUZpbmRJbmRleChhcnJheSwgcHJlZGljYXRlLCBmcm9tUmlnaHQpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIGluZGV4ID0gZnJvbVJpZ2h0ID8gbGVuZ3RoIDogLTE7XG5cbiAgd2hpbGUgKChmcm9tUmlnaHQgPyBpbmRleC0tIDogKytpbmRleCA8IGxlbmd0aCkpIHtcbiAgICBpZiAocHJlZGljYXRlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KSkge1xuICAgICAgcmV0dXJuIGluZGV4O1xuICAgIH1cbiAgfVxuICByZXR1cm4gLTE7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUZpbmRJbmRleDtcbiIsInZhciBjcmVhdGVCYXNlRm9yID0gcmVxdWlyZSgnLi9jcmVhdGVCYXNlRm9yJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGJhc2VGb3JJbmAgYW5kIGBiYXNlRm9yT3duYCB3aGljaCBpdGVyYXRlc1xuICogb3ZlciBgb2JqZWN0YCBwcm9wZXJ0aWVzIHJldHVybmVkIGJ5IGBrZXlzRnVuY2AgaW52b2tpbmcgYGl0ZXJhdGVlYCBmb3JcbiAqIGVhY2ggcHJvcGVydHkuIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdCBpdGVyYXRpb24gZWFybHkgYnkgZXhwbGljaXRseVxuICogcmV0dXJuaW5nIGBmYWxzZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHtGdW5jdGlvbn0ga2V5c0Z1bmMgVGhlIGZ1bmN0aW9uIHRvIGdldCB0aGUga2V5cyBvZiBgb2JqZWN0YC5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gKi9cbnZhciBiYXNlRm9yID0gY3JlYXRlQmFzZUZvcigpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VGb3I7XG4iLCJ2YXIgYmFzZUZvciA9IHJlcXVpcmUoJy4vYmFzZUZvcicpLFxuICAgIGtleXNJbiA9IHJlcXVpcmUoJy4uL29iamVjdC9rZXlzSW4nKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mb3JJbmAgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gYmFzZUZvckluKG9iamVjdCwgaXRlcmF0ZWUpIHtcbiAgcmV0dXJuIGJhc2VGb3Iob2JqZWN0LCBpdGVyYXRlZSwga2V5c0luKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlRm9ySW47XG4iLCJ2YXIgYmFzZUZvciA9IHJlcXVpcmUoJy4vYmFzZUZvcicpLFxuICAgIGtleXMgPSByZXF1aXJlKCcuLi9vYmplY3Qva2V5cycpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZvck93bmAgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gYmFzZUZvck93bihvYmplY3QsIGl0ZXJhdGVlKSB7XG4gIHJldHVybiBiYXNlRm9yKG9iamVjdCwgaXRlcmF0ZWUsIGtleXMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VGb3JPd247XG4iLCJ2YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL3RvT2JqZWN0Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGdldGAgd2l0aG91dCBzdXBwb3J0IGZvciBzdHJpbmcgcGF0aHNcbiAqIGFuZCBkZWZhdWx0IHZhbHVlcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtBcnJheX0gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHBhcmFtIHtzdHJpbmd9IFtwYXRoS2V5XSBUaGUga2V5IHJlcHJlc2VudGF0aW9uIG9mIHBhdGguXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmVzb2x2ZWQgdmFsdWUuXG4gKi9cbmZ1bmN0aW9uIGJhc2VHZXQob2JqZWN0LCBwYXRoLCBwYXRoS2V5KSB7XG4gIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgIHJldHVybjtcbiAgfVxuICBvYmplY3QgPSB0b09iamVjdChvYmplY3QpO1xuICBpZiAocGF0aEtleSAhPT0gdW5kZWZpbmVkICYmIHBhdGhLZXkgaW4gb2JqZWN0KSB7XG4gICAgcGF0aCA9IFtwYXRoS2V5XTtcbiAgfVxuICB2YXIgaW5kZXggPSAwLFxuICAgICAgbGVuZ3RoID0gcGF0aC5sZW5ndGg7XG5cbiAgd2hpbGUgKG9iamVjdCAhPSBudWxsICYmIGluZGV4IDwgbGVuZ3RoKSB7XG4gICAgb2JqZWN0ID0gdG9PYmplY3Qob2JqZWN0KVtwYXRoW2luZGV4KytdXTtcbiAgfVxuICByZXR1cm4gKGluZGV4ICYmIGluZGV4ID09IGxlbmd0aCkgPyBvYmplY3QgOiB1bmRlZmluZWQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUdldDtcbiIsInZhciBpbmRleE9mTmFOID0gcmVxdWlyZSgnLi9pbmRleE9mTmFOJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaW5kZXhPZmAgd2l0aG91dCBzdXBwb3J0IGZvciBiaW5hcnkgc2VhcmNoZXMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzZWFyY2guXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICogQHBhcmFtIHtudW1iZXJ9IGZyb21JbmRleCBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICovXG5mdW5jdGlvbiBiYXNlSW5kZXhPZihhcnJheSwgdmFsdWUsIGZyb21JbmRleCkge1xuICBpZiAodmFsdWUgIT09IHZhbHVlKSB7XG4gICAgcmV0dXJuIGluZGV4T2ZOYU4oYXJyYXksIGZyb21JbmRleCk7XG4gIH1cbiAgdmFyIGluZGV4ID0gZnJvbUluZGV4IC0gMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGlmIChhcnJheVtpbmRleF0gPT09IHZhbHVlKSB7XG4gICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuICB9XG4gIHJldHVybiAtMTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSW5kZXhPZjtcbiIsInZhciBiYXNlSXNFcXVhbERlZXAgPSByZXF1aXJlKCcuL2Jhc2VJc0VxdWFsRGVlcCcpLFxuICAgIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vbGFuZy9pc09iamVjdCcpLFxuICAgIGlzT2JqZWN0TGlrZSA9IHJlcXVpcmUoJy4vaXNPYmplY3RMaWtlJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNFcXVhbGAgd2l0aG91dCBzdXBwb3J0IGZvciBgdGhpc2AgYmluZGluZ1xuICogYGN1c3RvbWl6ZXJgIGZ1bmN0aW9ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpbmcgdmFsdWVzLlxuICogQHBhcmFtIHtib29sZWFufSBbaXNMb29zZV0gU3BlY2lmeSBwZXJmb3JtaW5nIHBhcnRpYWwgY29tcGFyaXNvbnMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tBXSBUcmFja3MgdHJhdmVyc2VkIGB2YWx1ZWAgb2JqZWN0cy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0JdIFRyYWNrcyB0cmF2ZXJzZWQgYG90aGVyYCBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUlzRXF1YWwodmFsdWUsIG90aGVyLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQikge1xuICBpZiAodmFsdWUgPT09IG90aGVyKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKHZhbHVlID09IG51bGwgfHwgb3RoZXIgPT0gbnVsbCB8fCAoIWlzT2JqZWN0KHZhbHVlKSAmJiAhaXNPYmplY3RMaWtlKG90aGVyKSkpIHtcbiAgICByZXR1cm4gdmFsdWUgIT09IHZhbHVlICYmIG90aGVyICE9PSBvdGhlcjtcbiAgfVxuICByZXR1cm4gYmFzZUlzRXF1YWxEZWVwKHZhbHVlLCBvdGhlciwgYmFzZUlzRXF1YWwsIGN1c3RvbWl6ZXIsIGlzTG9vc2UsIHN0YWNrQSwgc3RhY2tCKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNFcXVhbDtcbiIsInZhciBlcXVhbEFycmF5cyA9IHJlcXVpcmUoJy4vZXF1YWxBcnJheXMnKSxcbiAgICBlcXVhbEJ5VGFnID0gcmVxdWlyZSgnLi9lcXVhbEJ5VGFnJyksXG4gICAgZXF1YWxPYmplY3RzID0gcmVxdWlyZSgnLi9lcXVhbE9iamVjdHMnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FycmF5JyksXG4gICAgaXNIb3N0T2JqZWN0ID0gcmVxdWlyZSgnLi9pc0hvc3RPYmplY3QnKSxcbiAgICBpc1R5cGVkQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzVHlwZWRBcnJheScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYXJnc1RhZyA9ICdbb2JqZWN0IEFyZ3VtZW50c10nLFxuICAgIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJyxcbiAgICBvYmplY3RUYWcgPSAnW29iamVjdCBPYmplY3RdJztcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbGAgZm9yIGFycmF5cyBhbmQgb2JqZWN0cyB3aGljaCBwZXJmb3Jtc1xuICogZGVlcCBjb21wYXJpc29ucyBhbmQgdHJhY2tzIHRyYXZlcnNlZCBvYmplY3RzIGVuYWJsaW5nIG9iamVjdHMgd2l0aCBjaXJjdWxhclxuICogcmVmZXJlbmNlcyB0byBiZSBjb21wYXJlZC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge09iamVjdH0gb3RoZXIgVGhlIG90aGVyIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaW5nIG9iamVjdHMuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0xvb3NlXSBTcGVjaWZ5IHBlcmZvcm1pbmcgcGFydGlhbCBjb21wYXJpc29ucy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0E9W11dIFRyYWNrcyB0cmF2ZXJzZWQgYHZhbHVlYCBvYmplY3RzLlxuICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQj1bXV0gVHJhY2tzIHRyYXZlcnNlZCBgb3RoZXJgIG9iamVjdHMuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUlzRXF1YWxEZWVwKG9iamVjdCwgb3RoZXIsIGVxdWFsRnVuYywgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpIHtcbiAgdmFyIG9iaklzQXJyID0gaXNBcnJheShvYmplY3QpLFxuICAgICAgb3RoSXNBcnIgPSBpc0FycmF5KG90aGVyKSxcbiAgICAgIG9ialRhZyA9IGFycmF5VGFnLFxuICAgICAgb3RoVGFnID0gYXJyYXlUYWc7XG5cbiAgaWYgKCFvYmpJc0Fycikge1xuICAgIG9ialRhZyA9IG9ialRvU3RyaW5nLmNhbGwob2JqZWN0KTtcbiAgICBpZiAob2JqVGFnID09IGFyZ3NUYWcpIHtcbiAgICAgIG9ialRhZyA9IG9iamVjdFRhZztcbiAgICB9IGVsc2UgaWYgKG9ialRhZyAhPSBvYmplY3RUYWcpIHtcbiAgICAgIG9iaklzQXJyID0gaXNUeXBlZEFycmF5KG9iamVjdCk7XG4gICAgfVxuICB9XG4gIGlmICghb3RoSXNBcnIpIHtcbiAgICBvdGhUYWcgPSBvYmpUb1N0cmluZy5jYWxsKG90aGVyKTtcbiAgICBpZiAob3RoVGFnID09IGFyZ3NUYWcpIHtcbiAgICAgIG90aFRhZyA9IG9iamVjdFRhZztcbiAgICB9IGVsc2UgaWYgKG90aFRhZyAhPSBvYmplY3RUYWcpIHtcbiAgICAgIG90aElzQXJyID0gaXNUeXBlZEFycmF5KG90aGVyKTtcbiAgICB9XG4gIH1cbiAgdmFyIG9iaklzT2JqID0gb2JqVGFnID09IG9iamVjdFRhZyAmJiAhaXNIb3N0T2JqZWN0KG9iamVjdCksXG4gICAgICBvdGhJc09iaiA9IG90aFRhZyA9PSBvYmplY3RUYWcgJiYgIWlzSG9zdE9iamVjdChvdGhlciksXG4gICAgICBpc1NhbWVUYWcgPSBvYmpUYWcgPT0gb3RoVGFnO1xuXG4gIGlmIChpc1NhbWVUYWcgJiYgIShvYmpJc0FyciB8fCBvYmpJc09iaikpIHtcbiAgICByZXR1cm4gZXF1YWxCeVRhZyhvYmplY3QsIG90aGVyLCBvYmpUYWcpO1xuICB9XG4gIGlmICghaXNMb29zZSkge1xuICAgIHZhciBvYmpJc1dyYXBwZWQgPSBvYmpJc09iaiAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgJ19fd3JhcHBlZF9fJyksXG4gICAgICAgIG90aElzV3JhcHBlZCA9IG90aElzT2JqICYmIGhhc093blByb3BlcnR5LmNhbGwob3RoZXIsICdfX3dyYXBwZWRfXycpO1xuXG4gICAgaWYgKG9iaklzV3JhcHBlZCB8fCBvdGhJc1dyYXBwZWQpIHtcbiAgICAgIHJldHVybiBlcXVhbEZ1bmMob2JqSXNXcmFwcGVkID8gb2JqZWN0LnZhbHVlKCkgOiBvYmplY3QsIG90aElzV3JhcHBlZCA/IG90aGVyLnZhbHVlKCkgOiBvdGhlciwgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpO1xuICAgIH1cbiAgfVxuICBpZiAoIWlzU2FtZVRhZykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvLyBBc3N1bWUgY3ljbGljIHZhbHVlcyBhcmUgZXF1YWwuXG4gIC8vIEZvciBtb3JlIGluZm9ybWF0aW9uIG9uIGRldGVjdGluZyBjaXJjdWxhciByZWZlcmVuY2VzIHNlZSBodHRwczovL2VzNS5naXRodWIuaW8vI0pPLlxuICBzdGFja0EgfHwgKHN0YWNrQSA9IFtdKTtcbiAgc3RhY2tCIHx8IChzdGFja0IgPSBbXSk7XG5cbiAgdmFyIGxlbmd0aCA9IHN0YWNrQS5sZW5ndGg7XG4gIHdoaWxlIChsZW5ndGgtLSkge1xuICAgIGlmIChzdGFja0FbbGVuZ3RoXSA9PSBvYmplY3QpIHtcbiAgICAgIHJldHVybiBzdGFja0JbbGVuZ3RoXSA9PSBvdGhlcjtcbiAgICB9XG4gIH1cbiAgLy8gQWRkIGBvYmplY3RgIGFuZCBgb3RoZXJgIHRvIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgb2JqZWN0cy5cbiAgc3RhY2tBLnB1c2gob2JqZWN0KTtcbiAgc3RhY2tCLnB1c2gob3RoZXIpO1xuXG4gIHZhciByZXN1bHQgPSAob2JqSXNBcnIgPyBlcXVhbEFycmF5cyA6IGVxdWFsT2JqZWN0cykob2JqZWN0LCBvdGhlciwgZXF1YWxGdW5jLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQik7XG5cbiAgc3RhY2tBLnBvcCgpO1xuICBzdGFja0IucG9wKCk7XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNFcXVhbERlZXA7XG4iLCJ2YXIgYmFzZUlzRXF1YWwgPSByZXF1aXJlKCcuL2Jhc2VJc0VxdWFsJyksXG4gICAgdG9PYmplY3QgPSByZXF1aXJlKCcuL3RvT2JqZWN0Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNNYXRjaGAgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICogQHBhcmFtIHtBcnJheX0gbWF0Y2hEYXRhIFRoZSBwcm9wZXJ5IG5hbWVzLCB2YWx1ZXMsIGFuZCBjb21wYXJlIGZsYWdzIHRvIG1hdGNoLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaW5nIG9iamVjdHMuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYG9iamVjdGAgaXMgYSBtYXRjaCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBiYXNlSXNNYXRjaChvYmplY3QsIG1hdGNoRGF0YSwgY3VzdG9taXplcikge1xuICB2YXIgaW5kZXggPSBtYXRjaERhdGEubGVuZ3RoLFxuICAgICAgbGVuZ3RoID0gaW5kZXgsXG4gICAgICBub0N1c3RvbWl6ZXIgPSAhY3VzdG9taXplcjtcblxuICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICByZXR1cm4gIWxlbmd0aDtcbiAgfVxuICBvYmplY3QgPSB0b09iamVjdChvYmplY3QpO1xuICB3aGlsZSAoaW5kZXgtLSkge1xuICAgIHZhciBkYXRhID0gbWF0Y2hEYXRhW2luZGV4XTtcbiAgICBpZiAoKG5vQ3VzdG9taXplciAmJiBkYXRhWzJdKVxuICAgICAgICAgID8gZGF0YVsxXSAhPT0gb2JqZWN0W2RhdGFbMF1dXG4gICAgICAgICAgOiAhKGRhdGFbMF0gaW4gb2JqZWN0KVxuICAgICAgICApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBkYXRhID0gbWF0Y2hEYXRhW2luZGV4XTtcbiAgICB2YXIga2V5ID0gZGF0YVswXSxcbiAgICAgICAgb2JqVmFsdWUgPSBvYmplY3Rba2V5XSxcbiAgICAgICAgc3JjVmFsdWUgPSBkYXRhWzFdO1xuXG4gICAgaWYgKG5vQ3VzdG9taXplciAmJiBkYXRhWzJdKSB7XG4gICAgICBpZiAob2JqVmFsdWUgPT09IHVuZGVmaW5lZCAmJiAhKGtleSBpbiBvYmplY3QpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHJlc3VsdCA9IGN1c3RvbWl6ZXIgPyBjdXN0b21pemVyKG9ialZhbHVlLCBzcmNWYWx1ZSwga2V5KSA6IHVuZGVmaW5lZDtcbiAgICAgIGlmICghKHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gYmFzZUlzRXF1YWwoc3JjVmFsdWUsIG9ialZhbHVlLCBjdXN0b21pemVyLCB0cnVlKSA6IHJlc3VsdCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNNYXRjaDtcbiIsIi8qKlxuICogVGhlIGZ1bmN0aW9uIHdob3NlIHByb3RvdHlwZSBhbGwgY2hhaW5pbmcgd3JhcHBlcnMgaW5oZXJpdCBmcm9tLlxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGJhc2VMb2Rhc2goKSB7XG4gIC8vIE5vIG9wZXJhdGlvbiBwZXJmb3JtZWQuXG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUxvZGFzaDtcbiIsInZhciBiYXNlRWFjaCA9IHJlcXVpcmUoJy4vYmFzZUVhY2gnKSxcbiAgICBpc0FycmF5TGlrZSA9IHJlcXVpcmUoJy4vaXNBcnJheUxpa2UnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5tYXBgIHdpdGhvdXQgc3VwcG9ydCBmb3IgY2FsbGJhY2sgc2hvcnRoYW5kc1xuICogYW5kIGB0aGlzYCBiaW5kaW5nLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IG1hcHBlZCBhcnJheS5cbiAqL1xuZnVuY3Rpb24gYmFzZU1hcChjb2xsZWN0aW9uLCBpdGVyYXRlZSkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIHJlc3VsdCA9IGlzQXJyYXlMaWtlKGNvbGxlY3Rpb24pID8gQXJyYXkoY29sbGVjdGlvbi5sZW5ndGgpIDogW107XG5cbiAgYmFzZUVhY2goY29sbGVjdGlvbiwgZnVuY3Rpb24odmFsdWUsIGtleSwgY29sbGVjdGlvbikge1xuICAgIHJlc3VsdFsrK2luZGV4XSA9IGl0ZXJhdGVlKHZhbHVlLCBrZXksIGNvbGxlY3Rpb24pO1xuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlTWFwO1xuIiwidmFyIGJhc2VJc01hdGNoID0gcmVxdWlyZSgnLi9iYXNlSXNNYXRjaCcpLFxuICAgIGdldE1hdGNoRGF0YSA9IHJlcXVpcmUoJy4vZ2V0TWF0Y2hEYXRhJyksXG4gICAgdG9PYmplY3QgPSByZXF1aXJlKCcuL3RvT2JqZWN0Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ubWF0Y2hlc2Agd2hpY2ggZG9lcyBub3QgY2xvbmUgYHNvdXJjZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBwcm9wZXJ0eSB2YWx1ZXMgdG8gbWF0Y2guXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gYmFzZU1hdGNoZXMoc291cmNlKSB7XG4gIHZhciBtYXRjaERhdGEgPSBnZXRNYXRjaERhdGEoc291cmNlKTtcbiAgaWYgKG1hdGNoRGF0YS5sZW5ndGggPT0gMSAmJiBtYXRjaERhdGFbMF1bMl0pIHtcbiAgICB2YXIga2V5ID0gbWF0Y2hEYXRhWzBdWzBdLFxuICAgICAgICB2YWx1ZSA9IG1hdGNoRGF0YVswXVsxXTtcblxuICAgIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBvYmplY3QgPSB0b09iamVjdChvYmplY3QpO1xuICAgICAgcmV0dXJuIG9iamVjdFtrZXldID09PSB2YWx1ZSAmJiAodmFsdWUgIT09IHVuZGVmaW5lZCB8fCAoa2V5IGluIG9iamVjdCkpO1xuICAgIH07XG4gIH1cbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIHJldHVybiBiYXNlSXNNYXRjaChvYmplY3QsIG1hdGNoRGF0YSk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZU1hdGNoZXM7XG4iLCJ2YXIgYmFzZUdldCA9IHJlcXVpcmUoJy4vYmFzZUdldCcpLFxuICAgIGJhc2VJc0VxdWFsID0gcmVxdWlyZSgnLi9iYXNlSXNFcXVhbCcpLFxuICAgIGJhc2VTbGljZSA9IHJlcXVpcmUoJy4vYmFzZVNsaWNlJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcnJheScpLFxuICAgIGlzS2V5ID0gcmVxdWlyZSgnLi9pc0tleScpLFxuICAgIGlzU3RyaWN0Q29tcGFyYWJsZSA9IHJlcXVpcmUoJy4vaXNTdHJpY3RDb21wYXJhYmxlJyksXG4gICAgbGFzdCA9IHJlcXVpcmUoJy4uL2FycmF5L2xhc3QnKSxcbiAgICB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKSxcbiAgICB0b1BhdGggPSByZXF1aXJlKCcuL3RvUGF0aCcpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm1hdGNoZXNQcm9wZXJ0eWAgd2hpY2ggZG9lcyBub3QgY2xvbmUgYHNyY1ZhbHVlYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIGdldC5cbiAqIEBwYXJhbSB7Kn0gc3JjVmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gYmFzZU1hdGNoZXNQcm9wZXJ0eShwYXRoLCBzcmNWYWx1ZSkge1xuICB2YXIgaXNBcnIgPSBpc0FycmF5KHBhdGgpLFxuICAgICAgaXNDb21tb24gPSBpc0tleShwYXRoKSAmJiBpc1N0cmljdENvbXBhcmFibGUoc3JjVmFsdWUpLFxuICAgICAgcGF0aEtleSA9IChwYXRoICsgJycpO1xuXG4gIHBhdGggPSB0b1BhdGgocGF0aCk7XG4gIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdmFyIGtleSA9IHBhdGhLZXk7XG4gICAgb2JqZWN0ID0gdG9PYmplY3Qob2JqZWN0KTtcbiAgICBpZiAoKGlzQXJyIHx8ICFpc0NvbW1vbikgJiYgIShrZXkgaW4gb2JqZWN0KSkge1xuICAgICAgb2JqZWN0ID0gcGF0aC5sZW5ndGggPT0gMSA/IG9iamVjdCA6IGJhc2VHZXQob2JqZWN0LCBiYXNlU2xpY2UocGF0aCwgMCwgLTEpKTtcbiAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBrZXkgPSBsYXN0KHBhdGgpO1xuICAgICAgb2JqZWN0ID0gdG9PYmplY3Qob2JqZWN0KTtcbiAgICB9XG4gICAgcmV0dXJuIG9iamVjdFtrZXldID09PSBzcmNWYWx1ZVxuICAgICAgPyAoc3JjVmFsdWUgIT09IHVuZGVmaW5lZCB8fCAoa2V5IGluIG9iamVjdCkpXG4gICAgICA6IGJhc2VJc0VxdWFsKHNyY1ZhbHVlLCBvYmplY3Rba2V5XSwgdW5kZWZpbmVkLCB0cnVlKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlTWF0Y2hlc1Byb3BlcnR5O1xuIiwidmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi90b09iamVjdCcpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnByb3BlcnR5YCB3aXRob3V0IHN1cHBvcnQgZm9yIGRlZXAgcGF0aHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGJhc2VQcm9wZXJ0eShrZXkpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IHRvT2JqZWN0KG9iamVjdClba2V5XTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlUHJvcGVydHk7XG4iLCJ2YXIgYmFzZUdldCA9IHJlcXVpcmUoJy4vYmFzZUdldCcpLFxuICAgIHRvUGF0aCA9IHJlcXVpcmUoJy4vdG9QYXRoJyk7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlUHJvcGVydHlgIHdoaWNoIHN1cHBvcnRzIGRlZXAgcGF0aHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gYmFzZVByb3BlcnR5RGVlcChwYXRoKSB7XG4gIHZhciBwYXRoS2V5ID0gKHBhdGggKyAnJyk7XG4gIHBhdGggPSB0b1BhdGgocGF0aCk7XG4gIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICByZXR1cm4gYmFzZUdldChvYmplY3QsIHBhdGgsIHBhdGhLZXkpO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VQcm9wZXJ0eURlZXA7XG4iLCJ2YXIgaWRlbnRpdHkgPSByZXF1aXJlKCcuLi91dGlsaXR5L2lkZW50aXR5JyksXG4gICAgbWV0YU1hcCA9IHJlcXVpcmUoJy4vbWV0YU1hcCcpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBzZXREYXRhYCB3aXRob3V0IHN1cHBvcnQgZm9yIGhvdCBsb29wIGRldGVjdGlvbi5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYXNzb2NpYXRlIG1ldGFkYXRhIHdpdGguXG4gKiBAcGFyYW0geyp9IGRhdGEgVGhlIG1ldGFkYXRhLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGBmdW5jYC5cbiAqL1xudmFyIGJhc2VTZXREYXRhID0gIW1ldGFNYXAgPyBpZGVudGl0eSA6IGZ1bmN0aW9uKGZ1bmMsIGRhdGEpIHtcbiAgbWV0YU1hcC5zZXQoZnVuYywgZGF0YSk7XG4gIHJldHVybiBmdW5jO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlU2V0RGF0YTtcbiIsIi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uc2xpY2VgIHdpdGhvdXQgYW4gaXRlcmF0ZWUgY2FsbCBndWFyZC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNsaWNlLlxuICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD0wXSBUaGUgc3RhcnQgcG9zaXRpb24uXG4gKiBAcGFyYW0ge251bWJlcn0gW2VuZD1hcnJheS5sZW5ndGhdIFRoZSBlbmQgcG9zaXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VTbGljZShhcnJheSwgc3RhcnQsIGVuZCkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICBzdGFydCA9IHN0YXJ0ID09IG51bGwgPyAwIDogKCtzdGFydCB8fCAwKTtcbiAgaWYgKHN0YXJ0IDwgMCkge1xuICAgIHN0YXJ0ID0gLXN0YXJ0ID4gbGVuZ3RoID8gMCA6IChsZW5ndGggKyBzdGFydCk7XG4gIH1cbiAgZW5kID0gKGVuZCA9PT0gdW5kZWZpbmVkIHx8IGVuZCA+IGxlbmd0aCkgPyBsZW5ndGggOiAoK2VuZCB8fCAwKTtcbiAgaWYgKGVuZCA8IDApIHtcbiAgICBlbmQgKz0gbGVuZ3RoO1xuICB9XG4gIGxlbmd0aCA9IHN0YXJ0ID4gZW5kID8gMCA6ICgoZW5kIC0gc3RhcnQpID4+PiAwKTtcbiAgc3RhcnQgPj4+PSAwO1xuXG4gIHZhciByZXN1bHQgPSBBcnJheShsZW5ndGgpO1xuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHJlc3VsdFtpbmRleF0gPSBhcnJheVtpbmRleCArIHN0YXJ0XTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VTbGljZTtcbiIsIi8qKlxuICogQ29udmVydHMgYHZhbHVlYCB0byBhIHN0cmluZyBpZiBpdCdzIG5vdCBvbmUuIEFuIGVtcHR5IHN0cmluZyBpcyByZXR1cm5lZFxuICogZm9yIGBudWxsYCBvciBgdW5kZWZpbmVkYCB2YWx1ZXMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb2Nlc3MuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIGJhc2VUb1N0cmluZyh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgPT0gbnVsbCA/ICcnIDogKHZhbHVlICsgJycpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VUb1N0cmluZztcbiIsIi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8udmFsdWVzYCBhbmQgYF8udmFsdWVzSW5gIHdoaWNoIGNyZWF0ZXMgYW5cbiAqIGFycmF5IG9mIGBvYmplY3RgIHByb3BlcnR5IHZhbHVlcyBjb3JyZXNwb25kaW5nIHRvIHRoZSBwcm9wZXJ0eSBuYW1lc1xuICogb2YgYHByb3BzYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtBcnJheX0gcHJvcHMgVGhlIHByb3BlcnR5IG5hbWVzIHRvIGdldCB2YWx1ZXMgZm9yLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgdmFsdWVzLlxuICovXG5mdW5jdGlvbiBiYXNlVmFsdWVzKG9iamVjdCwgcHJvcHMpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBwcm9wcy5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBBcnJheShsZW5ndGgpO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgcmVzdWx0W2luZGV4XSA9IG9iamVjdFtwcm9wc1tpbmRleF1dO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZVZhbHVlcztcbiIsInZhciBiaW5hcnlJbmRleEJ5ID0gcmVxdWlyZSgnLi9iaW5hcnlJbmRleEJ5JyksXG4gICAgaWRlbnRpdHkgPSByZXF1aXJlKCcuLi91dGlsaXR5L2lkZW50aXR5Jyk7XG5cbi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHRoZSBtYXhpbXVtIGxlbmd0aCBhbmQgaW5kZXggb2YgYW4gYXJyYXkuICovXG52YXIgTUFYX0FSUkFZX0xFTkdUSCA9IDQyOTQ5NjcyOTUsXG4gICAgSEFMRl9NQVhfQVJSQVlfTEVOR1RIID0gTUFYX0FSUkFZX0xFTkdUSCA+Pj4gMTtcblxuLyoqXG4gKiBQZXJmb3JtcyBhIGJpbmFyeSBzZWFyY2ggb2YgYGFycmF5YCB0byBkZXRlcm1pbmUgdGhlIGluZGV4IGF0IHdoaWNoIGB2YWx1ZWBcbiAqIHNob3VsZCBiZSBpbnNlcnRlZCBpbnRvIGBhcnJheWAgaW4gb3JkZXIgdG8gbWFpbnRhaW4gaXRzIHNvcnQgb3JkZXIuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBzb3J0ZWQgYXJyYXkgdG8gaW5zcGVjdC5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGV2YWx1YXRlLlxuICogQHBhcmFtIHtib29sZWFufSBbcmV0SGlnaGVzdF0gU3BlY2lmeSByZXR1cm5pbmcgdGhlIGhpZ2hlc3QgcXVhbGlmaWVkIGluZGV4LlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggYXQgd2hpY2ggYHZhbHVlYCBzaG91bGQgYmUgaW5zZXJ0ZWRcbiAqICBpbnRvIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGJpbmFyeUluZGV4KGFycmF5LCB2YWx1ZSwgcmV0SGlnaGVzdCkge1xuICB2YXIgbG93ID0gMCxcbiAgICAgIGhpZ2ggPSBhcnJheSA/IGFycmF5Lmxlbmd0aCA6IGxvdztcblxuICBpZiAodHlwZW9mIHZhbHVlID09ICdudW1iZXInICYmIHZhbHVlID09PSB2YWx1ZSAmJiBoaWdoIDw9IEhBTEZfTUFYX0FSUkFZX0xFTkdUSCkge1xuICAgIHdoaWxlIChsb3cgPCBoaWdoKSB7XG4gICAgICB2YXIgbWlkID0gKGxvdyArIGhpZ2gpID4+PiAxLFxuICAgICAgICAgIGNvbXB1dGVkID0gYXJyYXlbbWlkXTtcblxuICAgICAgaWYgKChyZXRIaWdoZXN0ID8gKGNvbXB1dGVkIDw9IHZhbHVlKSA6IChjb21wdXRlZCA8IHZhbHVlKSkgJiYgY29tcHV0ZWQgIT09IG51bGwpIHtcbiAgICAgICAgbG93ID0gbWlkICsgMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGhpZ2ggPSBtaWQ7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBoaWdoO1xuICB9XG4gIHJldHVybiBiaW5hcnlJbmRleEJ5KGFycmF5LCB2YWx1ZSwgaWRlbnRpdHksIHJldEhpZ2hlc3QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJpbmFyeUluZGV4O1xuIiwiLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVGbG9vciA9IE1hdGguZmxvb3IsXG4gICAgbmF0aXZlTWluID0gTWF0aC5taW47XG5cbi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHRoZSBtYXhpbXVtIGxlbmd0aCBhbmQgaW5kZXggb2YgYW4gYXJyYXkuICovXG52YXIgTUFYX0FSUkFZX0xFTkdUSCA9IDQyOTQ5NjcyOTUsXG4gICAgTUFYX0FSUkFZX0lOREVYID0gTUFYX0FSUkFZX0xFTkdUSCAtIDE7XG5cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBpcyBsaWtlIGBiaW5hcnlJbmRleGAgZXhjZXB0IHRoYXQgaXQgaW52b2tlcyBgaXRlcmF0ZWVgIGZvclxuICogYHZhbHVlYCBhbmQgZWFjaCBlbGVtZW50IG9mIGBhcnJheWAgdG8gY29tcHV0ZSB0aGVpciBzb3J0IHJhbmtpbmcuIFRoZVxuICogaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDsgKHZhbHVlKS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIHNvcnRlZCBhcnJheSB0byBpbnNwZWN0LlxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gZXZhbHVhdGUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHtib29sZWFufSBbcmV0SGlnaGVzdF0gU3BlY2lmeSByZXR1cm5pbmcgdGhlIGhpZ2hlc3QgcXVhbGlmaWVkIGluZGV4LlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggYXQgd2hpY2ggYHZhbHVlYCBzaG91bGQgYmUgaW5zZXJ0ZWRcbiAqICBpbnRvIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGJpbmFyeUluZGV4QnkoYXJyYXksIHZhbHVlLCBpdGVyYXRlZSwgcmV0SGlnaGVzdCkge1xuICB2YWx1ZSA9IGl0ZXJhdGVlKHZhbHVlKTtcblxuICB2YXIgbG93ID0gMCxcbiAgICAgIGhpZ2ggPSBhcnJheSA/IGFycmF5Lmxlbmd0aCA6IDAsXG4gICAgICB2YWxJc05hTiA9IHZhbHVlICE9PSB2YWx1ZSxcbiAgICAgIHZhbElzTnVsbCA9IHZhbHVlID09PSBudWxsLFxuICAgICAgdmFsSXNVbmRlZiA9IHZhbHVlID09PSB1bmRlZmluZWQ7XG5cbiAgd2hpbGUgKGxvdyA8IGhpZ2gpIHtcbiAgICB2YXIgbWlkID0gbmF0aXZlRmxvb3IoKGxvdyArIGhpZ2gpIC8gMiksXG4gICAgICAgIGNvbXB1dGVkID0gaXRlcmF0ZWUoYXJyYXlbbWlkXSksXG4gICAgICAgIGlzRGVmID0gY29tcHV0ZWQgIT09IHVuZGVmaW5lZCxcbiAgICAgICAgaXNSZWZsZXhpdmUgPSBjb21wdXRlZCA9PT0gY29tcHV0ZWQ7XG5cbiAgICBpZiAodmFsSXNOYU4pIHtcbiAgICAgIHZhciBzZXRMb3cgPSBpc1JlZmxleGl2ZSB8fCByZXRIaWdoZXN0O1xuICAgIH0gZWxzZSBpZiAodmFsSXNOdWxsKSB7XG4gICAgICBzZXRMb3cgPSBpc1JlZmxleGl2ZSAmJiBpc0RlZiAmJiAocmV0SGlnaGVzdCB8fCBjb21wdXRlZCAhPSBudWxsKTtcbiAgICB9IGVsc2UgaWYgKHZhbElzVW5kZWYpIHtcbiAgICAgIHNldExvdyA9IGlzUmVmbGV4aXZlICYmIChyZXRIaWdoZXN0IHx8IGlzRGVmKTtcbiAgICB9IGVsc2UgaWYgKGNvbXB1dGVkID09IG51bGwpIHtcbiAgICAgIHNldExvdyA9IGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICBzZXRMb3cgPSByZXRIaWdoZXN0ID8gKGNvbXB1dGVkIDw9IHZhbHVlKSA6IChjb21wdXRlZCA8IHZhbHVlKTtcbiAgICB9XG4gICAgaWYgKHNldExvdykge1xuICAgICAgbG93ID0gbWlkICsgMTtcbiAgICB9IGVsc2Uge1xuICAgICAgaGlnaCA9IG1pZDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG5hdGl2ZU1pbihoaWdoLCBNQVhfQVJSQVlfSU5ERVgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJpbmFyeUluZGV4Qnk7XG4iLCJ2YXIgaWRlbnRpdHkgPSByZXF1aXJlKCcuLi91dGlsaXR5L2lkZW50aXR5Jyk7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlQ2FsbGJhY2tgIHdoaWNoIG9ubHkgc3VwcG9ydHMgYHRoaXNgIGJpbmRpbmdcbiAqIGFuZCBzcGVjaWZ5aW5nIHRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHRvIHByb3ZpZGUgdG8gYGZ1bmNgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBiaW5kLlxuICogQHBhcmFtIHsqfSB0aGlzQXJnIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge251bWJlcn0gW2FyZ0NvdW50XSBUaGUgbnVtYmVyIG9mIGFyZ3VtZW50cyB0byBwcm92aWRlIHRvIGBmdW5jYC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgY2FsbGJhY2suXG4gKi9cbmZ1bmN0aW9uIGJpbmRDYWxsYmFjayhmdW5jLCB0aGlzQXJnLCBhcmdDb3VudCkge1xuICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBpZGVudGl0eTtcbiAgfVxuICBpZiAodGhpc0FyZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGZ1bmM7XG4gIH1cbiAgc3dpdGNoIChhcmdDb3VudCkge1xuICAgIGNhc2UgMTogcmV0dXJuIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIHZhbHVlKTtcbiAgICB9O1xuICAgIGNhc2UgMzogcmV0dXJuIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikge1xuICAgICAgcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnLCB2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pO1xuICAgIH07XG4gICAgY2FzZSA0OiByZXR1cm4gZnVuY3Rpb24oYWNjdW11bGF0b3IsIHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikge1xuICAgICAgcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnLCBhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKTtcbiAgICB9O1xuICAgIGNhc2UgNTogcmV0dXJuIGZ1bmN0aW9uKHZhbHVlLCBvdGhlciwga2V5LCBvYmplY3QsIHNvdXJjZSkge1xuICAgICAgcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnLCB2YWx1ZSwgb3RoZXIsIGtleSwgb2JqZWN0LCBzb3VyY2UpO1xuICAgIH07XG4gIH1cbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBmdW5jLmFwcGx5KHRoaXNBcmcsIGFyZ3VtZW50cyk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmluZENhbGxiYWNrO1xuIiwiKGZ1bmN0aW9uIChnbG9iYWwpe1xuLyoqIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBBcnJheUJ1ZmZlciA9IGdsb2JhbC5BcnJheUJ1ZmZlcixcbiAgICBVaW50OEFycmF5ID0gZ2xvYmFsLlVpbnQ4QXJyYXk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGNsb25lIG9mIHRoZSBnaXZlbiBhcnJheSBidWZmZXIuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXlCdWZmZXJ9IGJ1ZmZlciBUaGUgYXJyYXkgYnVmZmVyIHRvIGNsb25lLlxuICogQHJldHVybnMge0FycmF5QnVmZmVyfSBSZXR1cm5zIHRoZSBjbG9uZWQgYXJyYXkgYnVmZmVyLlxuICovXG5mdW5jdGlvbiBidWZmZXJDbG9uZShidWZmZXIpIHtcbiAgdmFyIHJlc3VsdCA9IG5ldyBBcnJheUJ1ZmZlcihidWZmZXIuYnl0ZUxlbmd0aCksXG4gICAgICB2aWV3ID0gbmV3IFVpbnQ4QXJyYXkocmVzdWx0KTtcblxuICB2aWV3LnNldChuZXcgVWludDhBcnJheShidWZmZXIpKTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBidWZmZXJDbG9uZTtcblxufSkuY2FsbCh0aGlzLHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30pXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbTV2WkdWZmJXOWtkV3hsY3k5c2IyUmhjMmd0WTI5dGNHRjBMMmx1ZEdWeWJtRnNMMkoxWm1abGNrTnNiMjVsTG1weklsMHNJbTVoYldWeklqcGJYU3dpYldGd2NHbHVaM01pT2lJN1FVRkJRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEVpTENKbWFXeGxJam9pWjJWdVpYSmhkR1ZrTG1weklpd2ljMjkxY21ObFVtOXZkQ0k2SWlJc0luTnZkWEpqWlhORGIyNTBaVzUwSWpwYklpOHFLaUJPWVhScGRtVWdiV1YwYUc5a0lISmxabVZ5Wlc1alpYTXVJQ292WEc1MllYSWdRWEp5WVhsQ2RXWm1aWElnUFNCbmJHOWlZV3d1UVhKeVlYbENkV1ptWlhJc1hHNGdJQ0FnVldsdWREaEJjbkpoZVNBOUlHZHNiMkpoYkM1VmFXNTBPRUZ5Y21GNU8xeHVYRzR2S2lwY2JpQXFJRU55WldGMFpYTWdZU0JqYkc5dVpTQnZaaUIwYUdVZ1oybDJaVzRnWVhKeVlYa2dZblZtWm1WeUxseHVJQ3BjYmlBcUlFQndjbWwyWVhSbFhHNGdLaUJBY0dGeVlXMGdlMEZ5Y21GNVFuVm1abVZ5ZlNCaWRXWm1aWElnVkdobElHRnljbUY1SUdKMVptWmxjaUIwYnlCamJHOXVaUzVjYmlBcUlFQnlaWFIxY201eklIdEJjbkpoZVVKMVptWmxjbjBnVW1WMGRYSnVjeUIwYUdVZ1kyeHZibVZrSUdGeWNtRjVJR0oxWm1abGNpNWNiaUFxTDF4dVpuVnVZM1JwYjI0Z1luVm1abVZ5UTJ4dmJtVW9ZblZtWm1WeUtTQjdYRzRnSUhaaGNpQnlaWE4xYkhRZ1BTQnVaWGNnUVhKeVlYbENkV1ptWlhJb1luVm1abVZ5TG1KNWRHVk1aVzVuZEdncExGeHVJQ0FnSUNBZ2RtbGxkeUE5SUc1bGR5QlZhVzUwT0VGeWNtRjVLSEpsYzNWc2RDazdYRzVjYmlBZ2RtbGxkeTV6WlhRb2JtVjNJRlZwYm5RNFFYSnlZWGtvWW5WbVptVnlLU2s3WEc0Z0lISmxkSFZ5YmlCeVpYTjFiSFE3WEc1OVhHNWNibTF2WkhWc1pTNWxlSEJ2Y25SeklEMGdZblZtWm1WeVEyeHZibVU3WEc0aVhYMD0iLCIvKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4O1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgdGhhdCBpcyB0aGUgY29tcG9zaXRpb24gb2YgcGFydGlhbGx5IGFwcGxpZWQgYXJndW1lbnRzLFxuICogcGxhY2Vob2xkZXJzLCBhbmQgcHJvdmlkZWQgYXJndW1lbnRzIGludG8gYSBzaW5nbGUgYXJyYXkgb2YgYXJndW1lbnRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gYXJncyBUaGUgcHJvdmlkZWQgYXJndW1lbnRzLlxuICogQHBhcmFtIHtBcnJheX0gcGFydGlhbHMgVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkLlxuICogQHBhcmFtIHtBcnJheX0gaG9sZGVycyBUaGUgYHBhcnRpYWxzYCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgY29tcG9zZWQgYXJndW1lbnRzLlxuICovXG5mdW5jdGlvbiBjb21wb3NlQXJncyhhcmdzLCBwYXJ0aWFscywgaG9sZGVycykge1xuICB2YXIgaG9sZGVyc0xlbmd0aCA9IGhvbGRlcnMubGVuZ3RoLFxuICAgICAgYXJnc0luZGV4ID0gLTEsXG4gICAgICBhcmdzTGVuZ3RoID0gbmF0aXZlTWF4KGFyZ3MubGVuZ3RoIC0gaG9sZGVyc0xlbmd0aCwgMCksXG4gICAgICBsZWZ0SW5kZXggPSAtMSxcbiAgICAgIGxlZnRMZW5ndGggPSBwYXJ0aWFscy5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBBcnJheShsZWZ0TGVuZ3RoICsgYXJnc0xlbmd0aCk7XG5cbiAgd2hpbGUgKCsrbGVmdEluZGV4IDwgbGVmdExlbmd0aCkge1xuICAgIHJlc3VsdFtsZWZ0SW5kZXhdID0gcGFydGlhbHNbbGVmdEluZGV4XTtcbiAgfVxuICB3aGlsZSAoKythcmdzSW5kZXggPCBob2xkZXJzTGVuZ3RoKSB7XG4gICAgcmVzdWx0W2hvbGRlcnNbYXJnc0luZGV4XV0gPSBhcmdzW2FyZ3NJbmRleF07XG4gIH1cbiAgd2hpbGUgKGFyZ3NMZW5ndGgtLSkge1xuICAgIHJlc3VsdFtsZWZ0SW5kZXgrK10gPSBhcmdzW2FyZ3NJbmRleCsrXTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvbXBvc2VBcmdzO1xuIiwiLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heDtcblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2UgYGNvbXBvc2VBcmdzYCBleGNlcHQgdGhhdCB0aGUgYXJndW1lbnRzIGNvbXBvc2l0aW9uXG4gKiBpcyB0YWlsb3JlZCBmb3IgYF8ucGFydGlhbFJpZ2h0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGFyZ3MgVGhlIHByb3ZpZGVkIGFyZ3VtZW50cy5cbiAqIEBwYXJhbSB7QXJyYXl9IHBhcnRpYWxzIFRoZSBhcmd1bWVudHMgdG8gYXBwZW5kIHRvIHRob3NlIHByb3ZpZGVkLlxuICogQHBhcmFtIHtBcnJheX0gaG9sZGVycyBUaGUgYHBhcnRpYWxzYCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgY29tcG9zZWQgYXJndW1lbnRzLlxuICovXG5mdW5jdGlvbiBjb21wb3NlQXJnc1JpZ2h0KGFyZ3MsIHBhcnRpYWxzLCBob2xkZXJzKSB7XG4gIHZhciBob2xkZXJzSW5kZXggPSAtMSxcbiAgICAgIGhvbGRlcnNMZW5ndGggPSBob2xkZXJzLmxlbmd0aCxcbiAgICAgIGFyZ3NJbmRleCA9IC0xLFxuICAgICAgYXJnc0xlbmd0aCA9IG5hdGl2ZU1heChhcmdzLmxlbmd0aCAtIGhvbGRlcnNMZW5ndGgsIDApLFxuICAgICAgcmlnaHRJbmRleCA9IC0xLFxuICAgICAgcmlnaHRMZW5ndGggPSBwYXJ0aWFscy5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBBcnJheShhcmdzTGVuZ3RoICsgcmlnaHRMZW5ndGgpO1xuXG4gIHdoaWxlICgrK2FyZ3NJbmRleCA8IGFyZ3NMZW5ndGgpIHtcbiAgICByZXN1bHRbYXJnc0luZGV4XSA9IGFyZ3NbYXJnc0luZGV4XTtcbiAgfVxuICB2YXIgb2Zmc2V0ID0gYXJnc0luZGV4O1xuICB3aGlsZSAoKytyaWdodEluZGV4IDwgcmlnaHRMZW5ndGgpIHtcbiAgICByZXN1bHRbb2Zmc2V0ICsgcmlnaHRJbmRleF0gPSBwYXJ0aWFsc1tyaWdodEluZGV4XTtcbiAgfVxuICB3aGlsZSAoKytob2xkZXJzSW5kZXggPCBob2xkZXJzTGVuZ3RoKSB7XG4gICAgcmVzdWx0W29mZnNldCArIGhvbGRlcnNbaG9sZGVyc0luZGV4XV0gPSBhcmdzW2FyZ3NJbmRleCsrXTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvbXBvc2VBcmdzUmlnaHQ7XG4iLCJ2YXIgZ2V0TGVuZ3RoID0gcmVxdWlyZSgnLi9nZXRMZW5ndGgnKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4vaXNMZW5ndGgnKSxcbiAgICB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgYGJhc2VFYWNoYCBvciBgYmFzZUVhY2hSaWdodGAgZnVuY3Rpb24uXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGVhY2hGdW5jIFRoZSBmdW5jdGlvbiB0byBpdGVyYXRlIG92ZXIgYSBjb2xsZWN0aW9uLlxuICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBiYXNlIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVCYXNlRWFjaChlYWNoRnVuYywgZnJvbVJpZ2h0KSB7XG4gIHJldHVybiBmdW5jdGlvbihjb2xsZWN0aW9uLCBpdGVyYXRlZSkge1xuICAgIHZhciBsZW5ndGggPSBjb2xsZWN0aW9uID8gZ2V0TGVuZ3RoKGNvbGxlY3Rpb24pIDogMDtcbiAgICBpZiAoIWlzTGVuZ3RoKGxlbmd0aCkpIHtcbiAgICAgIHJldHVybiBlYWNoRnVuYyhjb2xsZWN0aW9uLCBpdGVyYXRlZSk7XG4gICAgfVxuICAgIHZhciBpbmRleCA9IGZyb21SaWdodCA/IGxlbmd0aCA6IC0xLFxuICAgICAgICBpdGVyYWJsZSA9IHRvT2JqZWN0KGNvbGxlY3Rpb24pO1xuXG4gICAgd2hpbGUgKChmcm9tUmlnaHQgPyBpbmRleC0tIDogKytpbmRleCA8IGxlbmd0aCkpIHtcbiAgICAgIGlmIChpdGVyYXRlZShpdGVyYWJsZVtpbmRleF0sIGluZGV4LCBpdGVyYWJsZSkgPT09IGZhbHNlKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gY29sbGVjdGlvbjtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVCYXNlRWFjaDtcbiIsInZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgYmFzZSBmdW5jdGlvbiBmb3IgYF8uZm9ySW5gIG9yIGBfLmZvckluUmlnaHRgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtmcm9tUmlnaHRdIFNwZWNpZnkgaXRlcmF0aW5nIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGJhc2UgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJhc2VGb3IoZnJvbVJpZ2h0KSB7XG4gIHJldHVybiBmdW5jdGlvbihvYmplY3QsIGl0ZXJhdGVlLCBrZXlzRnVuYykge1xuICAgIHZhciBpdGVyYWJsZSA9IHRvT2JqZWN0KG9iamVjdCksXG4gICAgICAgIHByb3BzID0ga2V5c0Z1bmMob2JqZWN0KSxcbiAgICAgICAgbGVuZ3RoID0gcHJvcHMubGVuZ3RoLFxuICAgICAgICBpbmRleCA9IGZyb21SaWdodCA/IGxlbmd0aCA6IC0xO1xuXG4gICAgd2hpbGUgKChmcm9tUmlnaHQgPyBpbmRleC0tIDogKytpbmRleCA8IGxlbmd0aCkpIHtcbiAgICAgIHZhciBrZXkgPSBwcm9wc1tpbmRleF07XG4gICAgICBpZiAoaXRlcmF0ZWUoaXRlcmFibGVba2V5XSwga2V5LCBpdGVyYWJsZSkgPT09IGZhbHNlKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0O1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUJhc2VGb3I7XG4iLCIoZnVuY3Rpb24gKGdsb2JhbCl7XG52YXIgY3JlYXRlQ3RvcldyYXBwZXIgPSByZXF1aXJlKCcuL2NyZWF0ZUN0b3JXcmFwcGVyJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYGZ1bmNgIGFuZCBpbnZva2VzIGl0IHdpdGggdGhlIGB0aGlzYFxuICogYmluZGluZyBvZiBgdGhpc0FyZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGJpbmQuXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYm91bmQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJpbmRXcmFwcGVyKGZ1bmMsIHRoaXNBcmcpIHtcbiAgdmFyIEN0b3IgPSBjcmVhdGVDdG9yV3JhcHBlcihmdW5jKTtcblxuICBmdW5jdGlvbiB3cmFwcGVyKCkge1xuICAgIHZhciBmbiA9ICh0aGlzICYmIHRoaXMgIT09IGdsb2JhbCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikgPyBDdG9yIDogZnVuYztcbiAgICByZXR1cm4gZm4uYXBwbHkodGhpc0FyZywgYXJndW1lbnRzKTtcbiAgfVxuICByZXR1cm4gd3JhcHBlcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVCaW5kV3JhcHBlcjtcblxufSkuY2FsbCh0aGlzLHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30pXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbTV2WkdWZmJXOWtkV3hsY3k5c2IyUmhjMmd0WTI5dGNHRjBMMmx1ZEdWeWJtRnNMMk55WldGMFpVSnBibVJYY21Gd2NHVnlMbXB6SWwwc0ltNWhiV1Z6SWpwYlhTd2liV0Z3Y0dsdVozTWlPaUk3UVVGQlFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJJaXdpWm1sc1pTSTZJbWRsYm1WeVlYUmxaQzVxY3lJc0luTnZkWEpqWlZKdmIzUWlPaUlpTENKemIzVnlZMlZ6UTI5dWRHVnVkQ0k2V3lKMllYSWdZM0psWVhSbFEzUnZjbGR5WVhCd1pYSWdQU0J5WlhGMWFYSmxLQ2N1TDJOeVpXRjBaVU4wYjNKWGNtRndjR1Z5SnlrN1hHNWNiaThxS2x4dUlDb2dRM0psWVhSbGN5QmhJR1oxYm1OMGFXOXVJSFJvWVhRZ2QzSmhjSE1nWUdaMWJtTmdJR0Z1WkNCcGJuWnZhMlZ6SUdsMElIZHBkR2dnZEdobElHQjBhR2x6WUZ4dUlDb2dZbWx1WkdsdVp5QnZaaUJnZEdocGMwRnlaMkF1WEc0Z0tseHVJQ29nUUhCeWFYWmhkR1ZjYmlBcUlFQndZWEpoYlNCN1JuVnVZM1JwYjI1OUlHWjFibU1nVkdobElHWjFibU4wYVc5dUlIUnZJR0pwYm1RdVhHNGdLaUJBY0dGeVlXMGdleXA5SUZ0MGFHbHpRWEpuWFNCVWFHVWdZSFJvYVhOZ0lHSnBibVJwYm1jZ2IyWWdZR1oxYm1OZ0xseHVJQ29nUUhKbGRIVnlibk1nZTBaMWJtTjBhVzl1ZlNCU1pYUjFjbTV6SUhSb1pTQnVaWGNnWW05MWJtUWdablZ1WTNScGIyNHVYRzRnS2k5Y2JtWjFibU4wYVc5dUlHTnlaV0YwWlVKcGJtUlhjbUZ3Y0dWeUtHWjFibU1zSUhSb2FYTkJjbWNwSUh0Y2JpQWdkbUZ5SUVOMGIzSWdQU0JqY21WaGRHVkRkRzl5VjNKaGNIQmxjaWhtZFc1aktUdGNibHh1SUNCbWRXNWpkR2x2YmlCM2NtRndjR1Z5S0NrZ2UxeHVJQ0FnSUhaaGNpQm1iaUE5SUNoMGFHbHpJQ1ltSUhSb2FYTWdJVDA5SUdkc2IySmhiQ0FtSmlCMGFHbHpJR2x1YzNSaGJtTmxiMllnZDNKaGNIQmxjaWtnUHlCRGRHOXlJRG9nWm5WdVl6dGNiaUFnSUNCeVpYUjFjbTRnWm00dVlYQndiSGtvZEdocGMwRnlaeXdnWVhKbmRXMWxiblJ6S1R0Y2JpQWdmVnh1SUNCeVpYUjFjbTRnZDNKaGNIQmxjanRjYm4xY2JseHViVzlrZFd4bExtVjRjRzl5ZEhNZ1BTQmpjbVZoZEdWQ2FXNWtWM0poY0hCbGNqdGNiaUpkZlE9PSIsInZhciBiYXNlQ3JlYXRlID0gcmVxdWlyZSgnLi9iYXNlQ3JlYXRlJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcHJvZHVjZXMgYW4gaW5zdGFuY2Ugb2YgYEN0b3JgIHJlZ2FyZGxlc3Mgb2ZcbiAqIHdoZXRoZXIgaXQgd2FzIGludm9rZWQgYXMgcGFydCBvZiBhIGBuZXdgIGV4cHJlc3Npb24gb3IgYnkgYGNhbGxgIG9yIGBhcHBseWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IEN0b3IgVGhlIGNvbnN0cnVjdG9yIHRvIHdyYXAuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVDdG9yV3JhcHBlcihDdG9yKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAvLyBVc2UgYSBgc3dpdGNoYCBzdGF0ZW1lbnQgdG8gd29yayB3aXRoIGNsYXNzIGNvbnN0cnVjdG9ycy5cbiAgICAvLyBTZWUgaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtZWNtYXNjcmlwdC1mdW5jdGlvbi1vYmplY3RzLWNhbGwtdGhpc2FyZ3VtZW50LWFyZ3VtZW50c2xpc3RcbiAgICAvLyBmb3IgbW9yZSBkZXRhaWxzLlxuICAgIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICAgIHN3aXRjaCAoYXJncy5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDogcmV0dXJuIG5ldyBDdG9yO1xuICAgICAgY2FzZSAxOiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSk7XG4gICAgICBjYXNlIDI6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdKTtcbiAgICAgIGNhc2UgMzogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgY2FzZSA0OiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSk7XG4gICAgICBjYXNlIDU6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdLCBhcmdzWzRdKTtcbiAgICAgIGNhc2UgNjogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10sIGFyZ3NbNF0sIGFyZ3NbNV0pO1xuICAgICAgY2FzZSA3OiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSwgYXJnc1s0XSwgYXJnc1s1XSwgYXJnc1s2XSk7XG4gICAgfVxuICAgIHZhciB0aGlzQmluZGluZyA9IGJhc2VDcmVhdGUoQ3Rvci5wcm90b3R5cGUpLFxuICAgICAgICByZXN1bHQgPSBDdG9yLmFwcGx5KHRoaXNCaW5kaW5nLCBhcmdzKTtcblxuICAgIC8vIE1pbWljIHRoZSBjb25zdHJ1Y3RvcidzIGByZXR1cm5gIGJlaGF2aW9yLlxuICAgIC8vIFNlZSBodHRwczovL2VzNS5naXRodWIuaW8vI3gxMy4yLjIgZm9yIG1vcmUgZGV0YWlscy5cbiAgICByZXR1cm4gaXNPYmplY3QocmVzdWx0KSA/IHJlc3VsdCA6IHRoaXNCaW5kaW5nO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUN0b3JXcmFwcGVyO1xuIiwidmFyIGJhc2VDYWxsYmFjayA9IHJlcXVpcmUoJy4vYmFzZUNhbGxiYWNrJyksXG4gICAgYmFzZUZpbmQgPSByZXF1aXJlKCcuL2Jhc2VGaW5kJyksXG4gICAgYmFzZUZpbmRJbmRleCA9IHJlcXVpcmUoJy4vYmFzZUZpbmRJbmRleCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgYF8uZmluZGAgb3IgYF8uZmluZExhc3RgIGZ1bmN0aW9uLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBlYWNoRnVuYyBUaGUgZnVuY3Rpb24gdG8gaXRlcmF0ZSBvdmVyIGEgY29sbGVjdGlvbi5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZmluZCBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlRmluZChlYWNoRnVuYywgZnJvbVJpZ2h0KSB7XG4gIHJldHVybiBmdW5jdGlvbihjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIHRoaXNBcmcpIHtcbiAgICBwcmVkaWNhdGUgPSBiYXNlQ2FsbGJhY2socHJlZGljYXRlLCB0aGlzQXJnLCAzKTtcbiAgICBpZiAoaXNBcnJheShjb2xsZWN0aW9uKSkge1xuICAgICAgdmFyIGluZGV4ID0gYmFzZUZpbmRJbmRleChjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIGZyb21SaWdodCk7XG4gICAgICByZXR1cm4gaW5kZXggPiAtMSA/IGNvbGxlY3Rpb25baW5kZXhdIDogdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4gYmFzZUZpbmQoY29sbGVjdGlvbiwgcHJlZGljYXRlLCBlYWNoRnVuYyk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlRmluZDtcbiIsInZhciBiaW5kQ2FsbGJhY2sgPSByZXF1aXJlKCcuL2JpbmRDYWxsYmFjaycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gZm9yIGBfLmZvckVhY2hgIG9yIGBfLmZvckVhY2hSaWdodGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGFycmF5RnVuYyBUaGUgZnVuY3Rpb24gdG8gaXRlcmF0ZSBvdmVyIGFuIGFycmF5LlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZWFjaEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBhIGNvbGxlY3Rpb24uXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBlYWNoIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVGb3JFYWNoKGFycmF5RnVuYywgZWFjaEZ1bmMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGNvbGxlY3Rpb24sIGl0ZXJhdGVlLCB0aGlzQXJnKSB7XG4gICAgcmV0dXJuICh0eXBlb2YgaXRlcmF0ZWUgPT0gJ2Z1bmN0aW9uJyAmJiB0aGlzQXJnID09PSB1bmRlZmluZWQgJiYgaXNBcnJheShjb2xsZWN0aW9uKSlcbiAgICAgID8gYXJyYXlGdW5jKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKVxuICAgICAgOiBlYWNoRnVuYyhjb2xsZWN0aW9uLCBiaW5kQ2FsbGJhY2soaXRlcmF0ZWUsIHRoaXNBcmcsIDMpKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVGb3JFYWNoO1xuIiwiKGZ1bmN0aW9uIChnbG9iYWwpe1xudmFyIGFycmF5Q29weSA9IHJlcXVpcmUoJy4vYXJyYXlDb3B5JyksXG4gICAgY29tcG9zZUFyZ3MgPSByZXF1aXJlKCcuL2NvbXBvc2VBcmdzJyksXG4gICAgY29tcG9zZUFyZ3NSaWdodCA9IHJlcXVpcmUoJy4vY29tcG9zZUFyZ3NSaWdodCcpLFxuICAgIGNyZWF0ZUN0b3JXcmFwcGVyID0gcmVxdWlyZSgnLi9jcmVhdGVDdG9yV3JhcHBlcicpLFxuICAgIGlzTGF6aWFibGUgPSByZXF1aXJlKCcuL2lzTGF6aWFibGUnKSxcbiAgICByZW9yZGVyID0gcmVxdWlyZSgnLi9yZW9yZGVyJyksXG4gICAgcmVwbGFjZUhvbGRlcnMgPSByZXF1aXJlKCcuL3JlcGxhY2VIb2xkZXJzJyksXG4gICAgc2V0RGF0YSA9IHJlcXVpcmUoJy4vc2V0RGF0YScpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB3cmFwcGVyIG1ldGFkYXRhLiAqL1xudmFyIEJJTkRfRkxBRyA9IDEsXG4gICAgQklORF9LRVlfRkxBRyA9IDIsXG4gICAgQ1VSUllfQk9VTkRfRkxBRyA9IDQsXG4gICAgQ1VSUllfRkxBRyA9IDgsXG4gICAgQ1VSUllfUklHSFRfRkxBRyA9IDE2LFxuICAgIFBBUlRJQUxfRkxBRyA9IDMyLFxuICAgIFBBUlRJQUxfUklHSFRfRkxBRyA9IDY0LFxuICAgIEFSWV9GTEFHID0gMTI4O1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHdyYXBzIGBmdW5jYCBhbmQgaW52b2tlcyBpdCB3aXRoIG9wdGlvbmFsIGB0aGlzYFxuICogYmluZGluZyBvZiwgcGFydGlhbCBhcHBsaWNhdGlvbiwgYW5kIGN1cnJ5aW5nLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufHN0cmluZ30gZnVuYyBUaGUgZnVuY3Rpb24gb3IgbWV0aG9kIG5hbWUgdG8gcmVmZXJlbmNlLlxuICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgb2YgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcHBlcmAgZm9yIG1vcmUgZGV0YWlscy5cbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge0FycmF5fSBbcGFydGlhbHNdIFRoZSBhcmd1bWVudHMgdG8gcHJlcGVuZCB0byB0aG9zZSBwcm92aWRlZCB0byB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNdIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gKiBAcGFyYW0ge0FycmF5fSBbcGFydGlhbHNSaWdodF0gVGhlIGFyZ3VtZW50cyB0byBhcHBlbmQgdG8gdGhvc2UgcHJvdmlkZWQgdG8gdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7QXJyYXl9IFtob2xkZXJzUmlnaHRdIFRoZSBgcGFydGlhbHNSaWdodGAgcGxhY2Vob2xkZXIgaW5kZXhlcy5cbiAqIEBwYXJhbSB7QXJyYXl9IFthcmdQb3NdIFRoZSBhcmd1bWVudCBwb3NpdGlvbnMgb2YgdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJ5XSBUaGUgYXJpdHkgY2FwIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJpdHldIFRoZSBhcml0eSBvZiBgZnVuY2AuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVIeWJyaWRXcmFwcGVyKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzLCBwYXJ0aWFsc1JpZ2h0LCBob2xkZXJzUmlnaHQsIGFyZ1BvcywgYXJ5LCBhcml0eSkge1xuICB2YXIgaXNBcnkgPSBiaXRtYXNrICYgQVJZX0ZMQUcsXG4gICAgICBpc0JpbmQgPSBiaXRtYXNrICYgQklORF9GTEFHLFxuICAgICAgaXNCaW5kS2V5ID0gYml0bWFzayAmIEJJTkRfS0VZX0ZMQUcsXG4gICAgICBpc0N1cnJ5ID0gYml0bWFzayAmIENVUlJZX0ZMQUcsXG4gICAgICBpc0N1cnJ5Qm91bmQgPSBiaXRtYXNrICYgQ1VSUllfQk9VTkRfRkxBRyxcbiAgICAgIGlzQ3VycnlSaWdodCA9IGJpdG1hc2sgJiBDVVJSWV9SSUdIVF9GTEFHLFxuICAgICAgQ3RvciA9IGlzQmluZEtleSA/IHVuZGVmaW5lZCA6IGNyZWF0ZUN0b3JXcmFwcGVyKGZ1bmMpO1xuXG4gIGZ1bmN0aW9uIHdyYXBwZXIoKSB7XG4gICAgLy8gQXZvaWQgYGFyZ3VtZW50c2Agb2JqZWN0IHVzZSBkaXNxdWFsaWZ5aW5nIG9wdGltaXphdGlvbnMgYnlcbiAgICAvLyBjb252ZXJ0aW5nIGl0IHRvIGFuIGFycmF5IGJlZm9yZSBwcm92aWRpbmcgaXQgdG8gb3RoZXIgZnVuY3Rpb25zLlxuICAgIHZhciBsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoLFxuICAgICAgICBpbmRleCA9IGxlbmd0aCxcbiAgICAgICAgYXJncyA9IEFycmF5KGxlbmd0aCk7XG5cbiAgICB3aGlsZSAoaW5kZXgtLSkge1xuICAgICAgYXJnc1tpbmRleF0gPSBhcmd1bWVudHNbaW5kZXhdO1xuICAgIH1cbiAgICBpZiAocGFydGlhbHMpIHtcbiAgICAgIGFyZ3MgPSBjb21wb3NlQXJncyhhcmdzLCBwYXJ0aWFscywgaG9sZGVycyk7XG4gICAgfVxuICAgIGlmIChwYXJ0aWFsc1JpZ2h0KSB7XG4gICAgICBhcmdzID0gY29tcG9zZUFyZ3NSaWdodChhcmdzLCBwYXJ0aWFsc1JpZ2h0LCBob2xkZXJzUmlnaHQpO1xuICAgIH1cbiAgICBpZiAoaXNDdXJyeSB8fCBpc0N1cnJ5UmlnaHQpIHtcbiAgICAgIHZhciBwbGFjZWhvbGRlciA9IHdyYXBwZXIucGxhY2Vob2xkZXIsXG4gICAgICAgICAgYXJnc0hvbGRlcnMgPSByZXBsYWNlSG9sZGVycyhhcmdzLCBwbGFjZWhvbGRlcik7XG5cbiAgICAgIGxlbmd0aCAtPSBhcmdzSG9sZGVycy5sZW5ndGg7XG4gICAgICBpZiAobGVuZ3RoIDwgYXJpdHkpIHtcbiAgICAgICAgdmFyIG5ld0FyZ1BvcyA9IGFyZ1BvcyA/IGFycmF5Q29weShhcmdQb3MpIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgbmV3QXJpdHkgPSBuYXRpdmVNYXgoYXJpdHkgLSBsZW5ndGgsIDApLFxuICAgICAgICAgICAgbmV3c0hvbGRlcnMgPSBpc0N1cnJ5ID8gYXJnc0hvbGRlcnMgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBuZXdIb2xkZXJzUmlnaHQgPSBpc0N1cnJ5ID8gdW5kZWZpbmVkIDogYXJnc0hvbGRlcnMsXG4gICAgICAgICAgICBuZXdQYXJ0aWFscyA9IGlzQ3VycnkgPyBhcmdzIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgbmV3UGFydGlhbHNSaWdodCA9IGlzQ3VycnkgPyB1bmRlZmluZWQgOiBhcmdzO1xuXG4gICAgICAgIGJpdG1hc2sgfD0gKGlzQ3VycnkgPyBQQVJUSUFMX0ZMQUcgOiBQQVJUSUFMX1JJR0hUX0ZMQUcpO1xuICAgICAgICBiaXRtYXNrICY9IH4oaXNDdXJyeSA/IFBBUlRJQUxfUklHSFRfRkxBRyA6IFBBUlRJQUxfRkxBRyk7XG5cbiAgICAgICAgaWYgKCFpc0N1cnJ5Qm91bmQpIHtcbiAgICAgICAgICBiaXRtYXNrICY9IH4oQklORF9GTEFHIHwgQklORF9LRVlfRkxBRyk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIG5ld0RhdGEgPSBbZnVuYywgYml0bWFzaywgdGhpc0FyZywgbmV3UGFydGlhbHMsIG5ld3NIb2xkZXJzLCBuZXdQYXJ0aWFsc1JpZ2h0LCBuZXdIb2xkZXJzUmlnaHQsIG5ld0FyZ1BvcywgYXJ5LCBuZXdBcml0eV0sXG4gICAgICAgICAgICByZXN1bHQgPSBjcmVhdGVIeWJyaWRXcmFwcGVyLmFwcGx5KHVuZGVmaW5lZCwgbmV3RGF0YSk7XG5cbiAgICAgICAgaWYgKGlzTGF6aWFibGUoZnVuYykpIHtcbiAgICAgICAgICBzZXREYXRhKHJlc3VsdCwgbmV3RGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzdWx0LnBsYWNlaG9sZGVyID0gcGxhY2Vob2xkZXI7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgfVxuICAgIHZhciB0aGlzQmluZGluZyA9IGlzQmluZCA/IHRoaXNBcmcgOiB0aGlzLFxuICAgICAgICBmbiA9IGlzQmluZEtleSA/IHRoaXNCaW5kaW5nW2Z1bmNdIDogZnVuYztcblxuICAgIGlmIChhcmdQb3MpIHtcbiAgICAgIGFyZ3MgPSByZW9yZGVyKGFyZ3MsIGFyZ1Bvcyk7XG4gICAgfVxuICAgIGlmIChpc0FyeSAmJiBhcnkgPCBhcmdzLmxlbmd0aCkge1xuICAgICAgYXJncy5sZW5ndGggPSBhcnk7XG4gICAgfVxuICAgIGlmICh0aGlzICYmIHRoaXMgIT09IGdsb2JhbCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikge1xuICAgICAgZm4gPSBDdG9yIHx8IGNyZWF0ZUN0b3JXcmFwcGVyKGZ1bmMpO1xuICAgIH1cbiAgICByZXR1cm4gZm4uYXBwbHkodGhpc0JpbmRpbmcsIGFyZ3MpO1xuICB9XG4gIHJldHVybiB3cmFwcGVyO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUh5YnJpZFdyYXBwZXI7XG5cbn0pLmNhbGwodGhpcyx0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDogdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9KVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ6dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiSW01dlpHVmZiVzlrZFd4bGN5OXNiMlJoYzJndFkyOXRjR0YwTDJsdWRHVnlibUZzTDJOeVpXRjBaVWg1WW5KcFpGZHlZWEJ3WlhJdWFuTWlYU3dpYm1GdFpYTWlPbHRkTENKdFlYQndhVzVuY3lJNklqdEJRVUZCTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJJaXdpWm1sc1pTSTZJbWRsYm1WeVlYUmxaQzVxY3lJc0luTnZkWEpqWlZKdmIzUWlPaUlpTENKemIzVnlZMlZ6UTI5dWRHVnVkQ0k2V3lKMllYSWdZWEp5WVhsRGIzQjVJRDBnY21WeGRXbHlaU2duTGk5aGNuSmhlVU52Y0hrbktTeGNiaUFnSUNCamIyMXdiM05sUVhKbmN5QTlJSEpsY1hWcGNtVW9KeTR2WTI5dGNHOXpaVUZ5WjNNbktTeGNiaUFnSUNCamIyMXdiM05sUVhKbmMxSnBaMmgwSUQwZ2NtVnhkV2x5WlNnbkxpOWpiMjF3YjNObFFYSm5jMUpwWjJoMEp5a3NYRzRnSUNBZ1kzSmxZWFJsUTNSdmNsZHlZWEJ3WlhJZ1BTQnlaWEYxYVhKbEtDY3VMMk55WldGMFpVTjBiM0pYY21Gd2NHVnlKeWtzWEc0Z0lDQWdhWE5NWVhwcFlXSnNaU0E5SUhKbGNYVnBjbVVvSnk0dmFYTk1ZWHBwWVdKc1pTY3BMRnh1SUNBZ0lISmxiM0prWlhJZ1BTQnlaWEYxYVhKbEtDY3VMM0psYjNKa1pYSW5LU3hjYmlBZ0lDQnlaWEJzWVdObFNHOXNaR1Z5Y3lBOUlISmxjWFZwY21Vb0p5NHZjbVZ3YkdGalpVaHZiR1JsY25NbktTeGNiaUFnSUNCelpYUkVZWFJoSUQwZ2NtVnhkV2x5WlNnbkxpOXpaWFJFWVhSaEp5azdYRzVjYmk4cUtpQlZjMlZrSUhSdklHTnZiWEJ2YzJVZ1ltbDBiV0Z6YTNNZ1ptOXlJSGR5WVhCd1pYSWdiV1YwWVdSaGRHRXVJQ292WEc1MllYSWdRa2xPUkY5R1RFRkhJRDBnTVN4Y2JpQWdJQ0JDU1U1RVgwdEZXVjlHVEVGSElEMGdNaXhjYmlBZ0lDQkRWVkpTV1Y5Q1QxVk9SRjlHVEVGSElEMGdOQ3hjYmlBZ0lDQkRWVkpTV1Y5R1RFRkhJRDBnT0N4Y2JpQWdJQ0JEVlZKU1dWOVNTVWRJVkY5R1RFRkhJRDBnTVRZc1hHNGdJQ0FnVUVGU1ZFbEJURjlHVEVGSElEMGdNeklzWEc0Z0lDQWdVRUZTVkVsQlRGOVNTVWRJVkY5R1RFRkhJRDBnTmpRc1hHNGdJQ0FnUVZKWlgwWk1RVWNnUFNBeE1qZzdYRzVjYmk4cUlFNWhkR2wyWlNCdFpYUm9iMlFnY21WbVpYSmxibU5sY3lCbWIzSWdkR2h2YzJVZ2QybDBhQ0IwYUdVZ2MyRnRaU0J1WVcxbElHRnpJRzkwYUdWeUlHQnNiMlJoYzJoZ0lHMWxkR2h2WkhNdUlDb3ZYRzUyWVhJZ2JtRjBhWFpsVFdGNElEMGdUV0YwYUM1dFlYZzdYRzVjYmk4cUtseHVJQ29nUTNKbFlYUmxjeUJoSUdaMWJtTjBhVzl1SUhSb1lYUWdkM0poY0hNZ1lHWjFibU5nSUdGdVpDQnBiblp2YTJWeklHbDBJSGRwZEdnZ2IzQjBhVzl1WVd3Z1lIUm9hWE5nWEc0Z0tpQmlhVzVrYVc1bklHOW1MQ0J3WVhKMGFXRnNJR0Z3Y0d4cFkyRjBhVzl1TENCaGJtUWdZM1Z5Y25scGJtY3VYRzRnS2x4dUlDb2dRSEJ5YVhaaGRHVmNiaUFxSUVCd1lYSmhiU0I3Um5WdVkzUnBiMjU4YzNSeWFXNW5mU0JtZFc1aklGUm9aU0JtZFc1amRHbHZiaUJ2Y2lCdFpYUm9iMlFnYm1GdFpTQjBieUJ5WldabGNtVnVZMlV1WEc0Z0tpQkFjR0Z5WVcwZ2UyNTFiV0psY24wZ1ltbDBiV0Z6YXlCVWFHVWdZbWwwYldGemF5QnZaaUJtYkdGbmN5NGdVMlZsSUdCamNtVmhkR1ZYY21Gd2NHVnlZQ0JtYjNJZ2JXOXlaU0JrWlhSaGFXeHpMbHh1SUNvZ1FIQmhjbUZ0SUhzcWZTQmJkR2hwYzBGeVoxMGdWR2hsSUdCMGFHbHpZQ0JpYVc1a2FXNW5JRzltSUdCbWRXNWpZQzVjYmlBcUlFQndZWEpoYlNCN1FYSnlZWGw5SUZ0d1lYSjBhV0ZzYzEwZ1ZHaGxJR0Z5WjNWdFpXNTBjeUIwYnlCd2NtVndaVzVrSUhSdklIUm9iM05sSUhCeWIzWnBaR1ZrSUhSdklIUm9aU0J1WlhjZ1puVnVZM1JwYjI0dVhHNGdLaUJBY0dGeVlXMGdlMEZ5Y21GNWZTQmJhRzlzWkdWeWMxMGdWR2hsSUdCd1lYSjBhV0ZzYzJBZ2NHeGhZMlZvYjJ4a1pYSWdhVzVrWlhobGN5NWNiaUFxSUVCd1lYSmhiU0I3UVhKeVlYbDlJRnR3WVhKMGFXRnNjMUpwWjJoMFhTQlVhR1VnWVhKbmRXMWxiblJ6SUhSdklHRndjR1Z1WkNCMGJ5QjBhRzl6WlNCd2NtOTJhV1JsWkNCMGJ5QjBhR1VnYm1WM0lHWjFibU4wYVc5dUxseHVJQ29nUUhCaGNtRnRJSHRCY25KaGVYMGdXMmh2YkdSbGNuTlNhV2RvZEYwZ1ZHaGxJR0J3WVhKMGFXRnNjMUpwWjJoMFlDQndiR0ZqWldodmJHUmxjaUJwYm1SbGVHVnpMbHh1SUNvZ1FIQmhjbUZ0SUh0QmNuSmhlWDBnVzJGeVoxQnZjMTBnVkdobElHRnlaM1Z0Wlc1MElIQnZjMmwwYVc5dWN5QnZaaUIwYUdVZ2JtVjNJR1oxYm1OMGFXOXVMbHh1SUNvZ1FIQmhjbUZ0SUh0dWRXMWlaWEo5SUZ0aGNubGRJRlJvWlNCaGNtbDBlU0JqWVhBZ2IyWWdZR1oxYm1OZ0xseHVJQ29nUUhCaGNtRnRJSHR1ZFcxaVpYSjlJRnRoY21sMGVWMGdWR2hsSUdGeWFYUjVJRzltSUdCbWRXNWpZQzVjYmlBcUlFQnlaWFIxY201eklIdEdkVzVqZEdsdmJuMGdVbVYwZFhKdWN5QjBhR1VnYm1WM0lIZHlZWEJ3WldRZ1puVnVZM1JwYjI0dVhHNGdLaTljYm1aMWJtTjBhVzl1SUdOeVpXRjBaVWg1WW5KcFpGZHlZWEJ3WlhJb1puVnVZeXdnWW1sMGJXRnpheXdnZEdocGMwRnlaeXdnY0dGeWRHbGhiSE1zSUdodmJHUmxjbk1zSUhCaGNuUnBZV3h6VW1sbmFIUXNJR2h2YkdSbGNuTlNhV2RvZEN3Z1lYSm5VRzl6TENCaGNua3NJR0Z5YVhSNUtTQjdYRzRnSUhaaGNpQnBjMEZ5ZVNBOUlHSnBkRzFoYzJzZ0ppQkJVbGxmUmt4QlJ5eGNiaUFnSUNBZ0lHbHpRbWx1WkNBOUlHSnBkRzFoYzJzZ0ppQkNTVTVFWDBaTVFVY3NYRzRnSUNBZ0lDQnBjMEpwYm1STFpYa2dQU0JpYVhSdFlYTnJJQ1lnUWtsT1JGOUxSVmxmUmt4QlJ5eGNiaUFnSUNBZ0lHbHpRM1Z5Y25rZ1BTQmlhWFJ0WVhOcklDWWdRMVZTVWxsZlJreEJSeXhjYmlBZ0lDQWdJR2x6UTNWeWNubENiM1Z1WkNBOUlHSnBkRzFoYzJzZ0ppQkRWVkpTV1Y5Q1QxVk9SRjlHVEVGSExGeHVJQ0FnSUNBZ2FYTkRkWEp5ZVZKcFoyaDBJRDBnWW1sMGJXRnpheUFtSUVOVlVsSlpYMUpKUjBoVVgwWk1RVWNzWEc0Z0lDQWdJQ0JEZEc5eUlEMGdhWE5DYVc1a1MyVjVJRDhnZFc1a1pXWnBibVZrSURvZ1kzSmxZWFJsUTNSdmNsZHlZWEJ3WlhJb1puVnVZeWs3WEc1Y2JpQWdablZ1WTNScGIyNGdkM0poY0hCbGNpZ3BJSHRjYmlBZ0lDQXZMeUJCZG05cFpDQmdZWEpuZFcxbGJuUnpZQ0J2WW1wbFkzUWdkWE5sSUdScGMzRjFZV3hwWm5scGJtY2diM0IwYVcxcGVtRjBhVzl1Y3lCaWVWeHVJQ0FnSUM4dklHTnZiblpsY25ScGJtY2dhWFFnZEc4Z1lXNGdZWEp5WVhrZ1ltVm1iM0psSUhCeWIzWnBaR2x1WnlCcGRDQjBieUJ2ZEdobGNpQm1kVzVqZEdsdmJuTXVYRzRnSUNBZ2RtRnlJR3hsYm1kMGFDQTlJR0Z5WjNWdFpXNTBjeTVzWlc1bmRHZ3NYRzRnSUNBZ0lDQWdJR2x1WkdWNElEMGdiR1Z1WjNSb0xGeHVJQ0FnSUNBZ0lDQmhjbWR6SUQwZ1FYSnlZWGtvYkdWdVozUm9LVHRjYmx4dUlDQWdJSGRvYVd4bElDaHBibVJsZUMwdEtTQjdYRzRnSUNBZ0lDQmhjbWR6VzJsdVpHVjRYU0E5SUdGeVozVnRaVzUwYzF0cGJtUmxlRjA3WEc0Z0lDQWdmVnh1SUNBZ0lHbG1JQ2h3WVhKMGFXRnNjeWtnZTF4dUlDQWdJQ0FnWVhKbmN5QTlJR052YlhCdmMyVkJjbWR6S0dGeVozTXNJSEJoY25ScFlXeHpMQ0JvYjJ4a1pYSnpLVHRjYmlBZ0lDQjlYRzRnSUNBZ2FXWWdLSEJoY25ScFlXeHpVbWxuYUhRcElIdGNiaUFnSUNBZ0lHRnlaM01nUFNCamIyMXdiM05sUVhKbmMxSnBaMmgwS0dGeVozTXNJSEJoY25ScFlXeHpVbWxuYUhRc0lHaHZiR1JsY25OU2FXZG9kQ2s3WEc0Z0lDQWdmVnh1SUNBZ0lHbG1JQ2hwYzBOMWNuSjVJSHg4SUdselEzVnljbmxTYVdkb2RDa2dlMXh1SUNBZ0lDQWdkbUZ5SUhCc1lXTmxhRzlzWkdWeUlEMGdkM0poY0hCbGNpNXdiR0ZqWldodmJHUmxjaXhjYmlBZ0lDQWdJQ0FnSUNCaGNtZHpTRzlzWkdWeWN5QTlJSEpsY0d4aFkyVkliMnhrWlhKektHRnlaM01zSUhCc1lXTmxhRzlzWkdWeUtUdGNibHh1SUNBZ0lDQWdiR1Z1WjNSb0lDMDlJR0Z5WjNOSWIyeGtaWEp6TG14bGJtZDBhRHRjYmlBZ0lDQWdJR2xtSUNoc1pXNW5kR2dnUENCaGNtbDBlU2tnZTF4dUlDQWdJQ0FnSUNCMllYSWdibVYzUVhKblVHOXpJRDBnWVhKblVHOXpJRDhnWVhKeVlYbERiM0I1S0dGeVoxQnZjeWtnT2lCMWJtUmxabWx1WldRc1hHNGdJQ0FnSUNBZ0lDQWdJQ0J1WlhkQmNtbDBlU0E5SUc1aGRHbDJaVTFoZUNoaGNtbDBlU0F0SUd4bGJtZDBhQ3dnTUNrc1hHNGdJQ0FnSUNBZ0lDQWdJQ0J1WlhkelNHOXNaR1Z5Y3lBOUlHbHpRM1Z5Y25rZ1B5QmhjbWR6U0c5c1pHVnljeUE2SUhWdVpHVm1hVzVsWkN4Y2JpQWdJQ0FnSUNBZ0lDQWdJRzVsZDBodmJHUmxjbk5TYVdkb2RDQTlJR2x6UTNWeWNua2dQeUIxYm1SbFptbHVaV1FnT2lCaGNtZHpTRzlzWkdWeWN5eGNiaUFnSUNBZ0lDQWdJQ0FnSUc1bGQxQmhjblJwWVd4eklEMGdhWE5EZFhKeWVTQS9JR0Z5WjNNZ09pQjFibVJsWm1sdVpXUXNYRzRnSUNBZ0lDQWdJQ0FnSUNCdVpYZFFZWEowYVdGc2MxSnBaMmgwSUQwZ2FYTkRkWEp5ZVNBL0lIVnVaR1ZtYVc1bFpDQTZJR0Z5WjNNN1hHNWNiaUFnSUNBZ0lDQWdZbWwwYldGemF5QjhQU0FvYVhORGRYSnllU0EvSUZCQlVsUkpRVXhmUmt4QlJ5QTZJRkJCVWxSSlFVeGZVa2xIU0ZSZlJreEJSeWs3WEc0Z0lDQWdJQ0FnSUdKcGRHMWhjMnNnSmowZ2ZpaHBjME4xY25KNUlEOGdVRUZTVkVsQlRGOVNTVWRJVkY5R1RFRkhJRG9nVUVGU1ZFbEJURjlHVEVGSEtUdGNibHh1SUNBZ0lDQWdJQ0JwWmlBb0lXbHpRM1Z5Y25sQ2IzVnVaQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lHSnBkRzFoYzJzZ0pqMGdmaWhDU1U1RVgwWk1RVWNnZkNCQ1NVNUVYMHRGV1Y5R1RFRkhLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCMllYSWdibVYzUkdGMFlTQTlJRnRtZFc1akxDQmlhWFJ0WVhOckxDQjBhR2x6UVhKbkxDQnVaWGRRWVhKMGFXRnNjeXdnYm1WM2MwaHZiR1JsY25Nc0lHNWxkMUJoY25ScFlXeHpVbWxuYUhRc0lHNWxkMGh2YkdSbGNuTlNhV2RvZEN3Z2JtVjNRWEpuVUc5ekxDQmhjbmtzSUc1bGQwRnlhWFI1WFN4Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsYzNWc2RDQTlJR055WldGMFpVaDVZbkpwWkZkeVlYQndaWEl1WVhCd2JIa29kVzVrWldacGJtVmtMQ0J1WlhkRVlYUmhLVHRjYmx4dUlDQWdJQ0FnSUNCcFppQW9hWE5NWVhwcFlXSnNaU2htZFc1aktTa2dlMXh1SUNBZ0lDQWdJQ0FnSUhObGRFUmhkR0VvY21WemRXeDBMQ0J1WlhkRVlYUmhLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCeVpYTjFiSFF1Y0d4aFkyVm9iMnhrWlhJZ1BTQndiR0ZqWldodmJHUmxjanRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJSEpsYzNWc2REdGNiaUFnSUNBZ0lIMWNiaUFnSUNCOVhHNGdJQ0FnZG1GeUlIUm9hWE5DYVc1a2FXNW5JRDBnYVhOQ2FXNWtJRDhnZEdocGMwRnlaeUE2SUhSb2FYTXNYRzRnSUNBZ0lDQWdJR1p1SUQwZ2FYTkNhVzVrUzJWNUlEOGdkR2hwYzBKcGJtUnBibWRiWm5WdVkxMGdPaUJtZFc1ak8xeHVYRzRnSUNBZ2FXWWdLR0Z5WjFCdmN5a2dlMXh1SUNBZ0lDQWdZWEpuY3lBOUlISmxiM0prWlhJb1lYSm5jeXdnWVhKblVHOXpLVHRjYmlBZ0lDQjlYRzRnSUNBZ2FXWWdLR2x6UVhKNUlDWW1JR0Z5ZVNBOElHRnlaM011YkdWdVozUm9LU0I3WEc0Z0lDQWdJQ0JoY21kekxteGxibWQwYUNBOUlHRnllVHRjYmlBZ0lDQjlYRzRnSUNBZ2FXWWdLSFJvYVhNZ0ppWWdkR2hwY3lBaFBUMGdaMnh2WW1Gc0lDWW1JSFJvYVhNZ2FXNXpkR0Z1WTJWdlppQjNjbUZ3Y0dWeUtTQjdYRzRnSUNBZ0lDQm1iaUE5SUVOMGIzSWdmSHdnWTNKbFlYUmxRM1J2Y2xkeVlYQndaWElvWm5WdVl5azdYRzRnSUNBZ2ZWeHVJQ0FnSUhKbGRIVnliaUJtYmk1aGNIQnNlU2gwYUdselFtbHVaR2x1Wnl3Z1lYSm5jeWs3WEc0Z0lIMWNiaUFnY21WMGRYSnVJSGR5WVhCd1pYSTdYRzU5WEc1Y2JtMXZaSFZzWlM1bGVIQnZjblJ6SUQwZ1kzSmxZWFJsU0hsaWNtbGtWM0poY0hCbGNqdGNiaUpkZlE9PSIsIihmdW5jdGlvbiAoZ2xvYmFsKXtcbnZhciBjcmVhdGVDdG9yV3JhcHBlciA9IHJlcXVpcmUoJy4vY3JlYXRlQ3RvcldyYXBwZXInKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3Igd3JhcHBlciBtZXRhZGF0YS4gKi9cbnZhciBCSU5EX0ZMQUcgPSAxO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHdyYXBzIGBmdW5jYCBhbmQgaW52b2tlcyBpdCB3aXRoIHRoZSBvcHRpb25hbCBgdGhpc2BcbiAqIGJpbmRpbmcgb2YgYHRoaXNBcmdgIGFuZCB0aGUgYHBhcnRpYWxzYCBwcmVwZW5kZWQgdG8gdGhvc2UgcHJvdmlkZWQgdG9cbiAqIHRoZSB3cmFwcGVyLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBwYXJ0aWFsbHkgYXBwbHkgYXJndW1lbnRzIHRvLlxuICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgb2YgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcHBlcmAgZm9yIG1vcmUgZGV0YWlscy5cbiAqIEBwYXJhbSB7Kn0gdGhpc0FyZyBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHBhcmFtIHtBcnJheX0gcGFydGlhbHMgVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkIHRvIHRoZSBuZXcgZnVuY3Rpb24uXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBib3VuZCBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlUGFydGlhbFdyYXBwZXIoZnVuYywgYml0bWFzaywgdGhpc0FyZywgcGFydGlhbHMpIHtcbiAgdmFyIGlzQmluZCA9IGJpdG1hc2sgJiBCSU5EX0ZMQUcsXG4gICAgICBDdG9yID0gY3JlYXRlQ3RvcldyYXBwZXIoZnVuYyk7XG5cbiAgZnVuY3Rpb24gd3JhcHBlcigpIHtcbiAgICAvLyBBdm9pZCBgYXJndW1lbnRzYCBvYmplY3QgdXNlIGRpc3F1YWxpZnlpbmcgb3B0aW1pemF0aW9ucyBieVxuICAgIC8vIGNvbnZlcnRpbmcgaXQgdG8gYW4gYXJyYXkgYmVmb3JlIHByb3ZpZGluZyBpdCBgZnVuY2AuXG4gICAgdmFyIGFyZ3NJbmRleCA9IC0xLFxuICAgICAgICBhcmdzTGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aCxcbiAgICAgICAgbGVmdEluZGV4ID0gLTEsXG4gICAgICAgIGxlZnRMZW5ndGggPSBwYXJ0aWFscy5sZW5ndGgsXG4gICAgICAgIGFyZ3MgPSBBcnJheShsZWZ0TGVuZ3RoICsgYXJnc0xlbmd0aCk7XG5cbiAgICB3aGlsZSAoKytsZWZ0SW5kZXggPCBsZWZ0TGVuZ3RoKSB7XG4gICAgICBhcmdzW2xlZnRJbmRleF0gPSBwYXJ0aWFsc1tsZWZ0SW5kZXhdO1xuICAgIH1cbiAgICB3aGlsZSAoYXJnc0xlbmd0aC0tKSB7XG4gICAgICBhcmdzW2xlZnRJbmRleCsrXSA9IGFyZ3VtZW50c1srK2FyZ3NJbmRleF07XG4gICAgfVxuICAgIHZhciBmbiA9ICh0aGlzICYmIHRoaXMgIT09IGdsb2JhbCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikgPyBDdG9yIDogZnVuYztcbiAgICByZXR1cm4gZm4uYXBwbHkoaXNCaW5kID8gdGhpc0FyZyA6IHRoaXMsIGFyZ3MpO1xuICB9XG4gIHJldHVybiB3cmFwcGVyO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZVBhcnRpYWxXcmFwcGVyO1xuXG59KS5jYWxsKHRoaXMsdHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIiA/IGdsb2JhbCA6IHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSlcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0OnV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKemIzVnlZMlZ6SWpwYkltNXZaR1ZmYlc5a2RXeGxjeTlzYjJSaGMyZ3RZMjl0Y0dGMEwybHVkR1Z5Ym1Gc0wyTnlaV0YwWlZCaGNuUnBZV3hYY21Gd2NHVnlMbXB6SWwwc0ltNWhiV1Z6SWpwYlhTd2liV0Z3Y0dsdVozTWlPaUk3UVVGQlFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQklpd2labWxzWlNJNkltZGxibVZ5WVhSbFpDNXFjeUlzSW5OdmRYSmpaVkp2YjNRaU9pSWlMQ0p6YjNWeVkyVnpRMjl1ZEdWdWRDSTZXeUoyWVhJZ1kzSmxZWFJsUTNSdmNsZHlZWEJ3WlhJZ1BTQnlaWEYxYVhKbEtDY3VMMk55WldGMFpVTjBiM0pYY21Gd2NHVnlKeWs3WEc1Y2JpOHFLaUJWYzJWa0lIUnZJR052YlhCdmMyVWdZbWwwYldGemEzTWdabTl5SUhkeVlYQndaWElnYldWMFlXUmhkR0V1SUNvdlhHNTJZWElnUWtsT1JGOUdURUZISUQwZ01UdGNibHh1THlvcVhHNGdLaUJEY21WaGRHVnpJR0VnWm5WdVkzUnBiMjRnZEdoaGRDQjNjbUZ3Y3lCZ1puVnVZMkFnWVc1a0lHbHVkbTlyWlhNZ2FYUWdkMmwwYUNCMGFHVWdiM0IwYVc5dVlXd2dZSFJvYVhOZ1hHNGdLaUJpYVc1a2FXNW5JRzltSUdCMGFHbHpRWEpuWUNCaGJtUWdkR2hsSUdCd1lYSjBhV0ZzYzJBZ2NISmxjR1Z1WkdWa0lIUnZJSFJvYjNObElIQnliM1pwWkdWa0lIUnZYRzRnS2lCMGFHVWdkM0poY0hCbGNpNWNiaUFxWEc0Z0tpQkFjSEpwZG1GMFpWeHVJQ29nUUhCaGNtRnRJSHRHZFc1amRHbHZibjBnWm5WdVl5QlVhR1VnWm5WdVkzUnBiMjRnZEc4Z2NHRnlkR2xoYkd4NUlHRndjR3g1SUdGeVozVnRaVzUwY3lCMGJ5NWNiaUFxSUVCd1lYSmhiU0I3Ym5WdFltVnlmU0JpYVhSdFlYTnJJRlJvWlNCaWFYUnRZWE5ySUc5bUlHWnNZV2R6TGlCVFpXVWdZR055WldGMFpWZHlZWEJ3WlhKZ0lHWnZjaUJ0YjNKbElHUmxkR0ZwYkhNdVhHNGdLaUJBY0dGeVlXMGdleXA5SUhSb2FYTkJjbWNnVkdobElHQjBhR2x6WUNCaWFXNWthVzVuSUc5bUlHQm1kVzVqWUM1Y2JpQXFJRUJ3WVhKaGJTQjdRWEp5WVhsOUlIQmhjblJwWVd4eklGUm9aU0JoY21kMWJXVnVkSE1nZEc4Z2NISmxjR1Z1WkNCMGJ5QjBhRzl6WlNCd2NtOTJhV1JsWkNCMGJ5QjBhR1VnYm1WM0lHWjFibU4wYVc5dUxseHVJQ29nUUhKbGRIVnlibk1nZTBaMWJtTjBhVzl1ZlNCU1pYUjFjbTV6SUhSb1pTQnVaWGNnWW05MWJtUWdablZ1WTNScGIyNHVYRzRnS2k5Y2JtWjFibU4wYVc5dUlHTnlaV0YwWlZCaGNuUnBZV3hYY21Gd2NHVnlLR1oxYm1Nc0lHSnBkRzFoYzJzc0lIUm9hWE5CY21jc0lIQmhjblJwWVd4ektTQjdYRzRnSUhaaGNpQnBjMEpwYm1RZ1BTQmlhWFJ0WVhOcklDWWdRa2xPUkY5R1RFRkhMRnh1SUNBZ0lDQWdRM1J2Y2lBOUlHTnlaV0YwWlVOMGIzSlhjbUZ3Y0dWeUtHWjFibU1wTzF4dVhHNGdJR1oxYm1OMGFXOXVJSGR5WVhCd1pYSW9LU0I3WEc0Z0lDQWdMeThnUVhadmFXUWdZR0Z5WjNWdFpXNTBjMkFnYjJKcVpXTjBJSFZ6WlNCa2FYTnhkV0ZzYVdaNWFXNW5JRzl3ZEdsdGFYcGhkR2x2Ym5NZ1lubGNiaUFnSUNBdkx5QmpiMjUyWlhKMGFXNW5JR2wwSUhSdklHRnVJR0Z5Y21GNUlHSmxabTl5WlNCd2NtOTJhV1JwYm1jZ2FYUWdZR1oxYm1OZ0xseHVJQ0FnSUhaaGNpQmhjbWR6U1c1a1pYZ2dQU0F0TVN4Y2JpQWdJQ0FnSUNBZ1lYSm5jMHhsYm1kMGFDQTlJR0Z5WjNWdFpXNTBjeTVzWlc1bmRHZ3NYRzRnSUNBZ0lDQWdJR3hsWm5SSmJtUmxlQ0E5SUMweExGeHVJQ0FnSUNBZ0lDQnNaV1owVEdWdVozUm9JRDBnY0dGeWRHbGhiSE11YkdWdVozUm9MRnh1SUNBZ0lDQWdJQ0JoY21keklEMGdRWEp5WVhrb2JHVm1kRXhsYm1kMGFDQXJJR0Z5WjNOTVpXNW5kR2dwTzF4dVhHNGdJQ0FnZDJocGJHVWdLQ3NyYkdWbWRFbHVaR1Y0SUR3Z2JHVm1kRXhsYm1kMGFDa2dlMXh1SUNBZ0lDQWdZWEpuYzF0c1pXWjBTVzVrWlhoZElEMGdjR0Z5ZEdsaGJITmJiR1ZtZEVsdVpHVjRYVHRjYmlBZ0lDQjlYRzRnSUNBZ2QyaHBiR1VnS0dGeVozTk1aVzVuZEdndExTa2dlMXh1SUNBZ0lDQWdZWEpuYzF0c1pXWjBTVzVrWlhncksxMGdQU0JoY21kMWJXVnVkSE5iS3l0aGNtZHpTVzVrWlhoZE8xeHVJQ0FnSUgxY2JpQWdJQ0IyWVhJZ1ptNGdQU0FvZEdocGN5QW1KaUIwYUdseklDRTlQU0JuYkc5aVlXd2dKaVlnZEdocGN5QnBibk4wWVc1alpXOW1JSGR5WVhCd1pYSXBJRDhnUTNSdmNpQTZJR1oxYm1NN1hHNGdJQ0FnY21WMGRYSnVJR1p1TG1Gd2NHeDVLR2x6UW1sdVpDQS9JSFJvYVhOQmNtY2dPaUIwYUdsekxDQmhjbWR6S1R0Y2JpQWdmVnh1SUNCeVpYUjFjbTRnZDNKaGNIQmxjanRjYm4xY2JseHViVzlrZFd4bExtVjRjRzl5ZEhNZ1BTQmpjbVZoZEdWUVlYSjBhV0ZzVjNKaGNIQmxjanRjYmlKZGZRPT0iLCJ2YXIgYmFzZVNldERhdGEgPSByZXF1aXJlKCcuL2Jhc2VTZXREYXRhJyksXG4gICAgY3JlYXRlQmluZFdyYXBwZXIgPSByZXF1aXJlKCcuL2NyZWF0ZUJpbmRXcmFwcGVyJyksXG4gICAgY3JlYXRlSHlicmlkV3JhcHBlciA9IHJlcXVpcmUoJy4vY3JlYXRlSHlicmlkV3JhcHBlcicpLFxuICAgIGNyZWF0ZVBhcnRpYWxXcmFwcGVyID0gcmVxdWlyZSgnLi9jcmVhdGVQYXJ0aWFsV3JhcHBlcicpLFxuICAgIGdldERhdGEgPSByZXF1aXJlKCcuL2dldERhdGEnKSxcbiAgICBtZXJnZURhdGEgPSByZXF1aXJlKCcuL21lcmdlRGF0YScpLFxuICAgIHNldERhdGEgPSByZXF1aXJlKCcuL3NldERhdGEnKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3Igd3JhcHBlciBtZXRhZGF0YS4gKi9cbnZhciBCSU5EX0ZMQUcgPSAxLFxuICAgIEJJTkRfS0VZX0ZMQUcgPSAyLFxuICAgIFBBUlRJQUxfRkxBRyA9IDMyLFxuICAgIFBBUlRJQUxfUklHSFRfRkxBRyA9IDY0O1xuXG4vKiogVXNlZCBhcyB0aGUgYFR5cGVFcnJvcmAgbWVzc2FnZSBmb3IgXCJGdW5jdGlvbnNcIiBtZXRob2RzLiAqL1xudmFyIEZVTkNfRVJST1JfVEVYVCA9ICdFeHBlY3RlZCBhIGZ1bmN0aW9uJztcblxuLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heDtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBlaXRoZXIgY3VycmllcyBvciBpbnZva2VzIGBmdW5jYCB3aXRoIG9wdGlvbmFsXG4gKiBgdGhpc2AgYmluZGluZyBhbmQgcGFydGlhbGx5IGFwcGxpZWQgYXJndW1lbnRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufHN0cmluZ30gZnVuYyBUaGUgZnVuY3Rpb24gb3IgbWV0aG9kIG5hbWUgdG8gcmVmZXJlbmNlLlxuICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgb2YgZmxhZ3MuXG4gKiAgVGhlIGJpdG1hc2sgbWF5IGJlIGNvbXBvc2VkIG9mIHRoZSBmb2xsb3dpbmcgZmxhZ3M6XG4gKiAgICAgMSAtIGBfLmJpbmRgXG4gKiAgICAgMiAtIGBfLmJpbmRLZXlgXG4gKiAgICAgNCAtIGBfLmN1cnJ5YCBvciBgXy5jdXJyeVJpZ2h0YCBvZiBhIGJvdW5kIGZ1bmN0aW9uXG4gKiAgICAgOCAtIGBfLmN1cnJ5YFxuICogICAgMTYgLSBgXy5jdXJyeVJpZ2h0YFxuICogICAgMzIgLSBgXy5wYXJ0aWFsYFxuICogICAgNjQgLSBgXy5wYXJ0aWFsUmlnaHRgXG4gKiAgIDEyOCAtIGBfLnJlYXJnYFxuICogICAyNTYgLSBgXy5hcnlgXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHBhcmFtIHtBcnJheX0gW3BhcnRpYWxzXSBUaGUgYXJndW1lbnRzIHRvIGJlIHBhcnRpYWxseSBhcHBsaWVkLlxuICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNdIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gKiBAcGFyYW0ge0FycmF5fSBbYXJnUG9zXSBUaGUgYXJndW1lbnQgcG9zaXRpb25zIG9mIHRoZSBuZXcgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge251bWJlcn0gW2FyeV0gVGhlIGFyaXR5IGNhcCBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge251bWJlcn0gW2FyaXR5XSBUaGUgYXJpdHkgb2YgYGZ1bmNgLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgd3JhcHBlZCBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlV3JhcHBlcihmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscywgaG9sZGVycywgYXJnUG9zLCBhcnksIGFyaXR5KSB7XG4gIHZhciBpc0JpbmRLZXkgPSBiaXRtYXNrICYgQklORF9LRVlfRkxBRztcbiAgaWYgKCFpc0JpbmRLZXkgJiYgdHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgfVxuICB2YXIgbGVuZ3RoID0gcGFydGlhbHMgPyBwYXJ0aWFscy5sZW5ndGggOiAwO1xuICBpZiAoIWxlbmd0aCkge1xuICAgIGJpdG1hc2sgJj0gfihQQVJUSUFMX0ZMQUcgfCBQQVJUSUFMX1JJR0hUX0ZMQUcpO1xuICAgIHBhcnRpYWxzID0gaG9sZGVycyA9IHVuZGVmaW5lZDtcbiAgfVxuICBsZW5ndGggLT0gKGhvbGRlcnMgPyBob2xkZXJzLmxlbmd0aCA6IDApO1xuICBpZiAoYml0bWFzayAmIFBBUlRJQUxfUklHSFRfRkxBRykge1xuICAgIHZhciBwYXJ0aWFsc1JpZ2h0ID0gcGFydGlhbHMsXG4gICAgICAgIGhvbGRlcnNSaWdodCA9IGhvbGRlcnM7XG5cbiAgICBwYXJ0aWFscyA9IGhvbGRlcnMgPSB1bmRlZmluZWQ7XG4gIH1cbiAgdmFyIGRhdGEgPSBpc0JpbmRLZXkgPyB1bmRlZmluZWQgOiBnZXREYXRhKGZ1bmMpLFxuICAgICAgbmV3RGF0YSA9IFtmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscywgaG9sZGVycywgcGFydGlhbHNSaWdodCwgaG9sZGVyc1JpZ2h0LCBhcmdQb3MsIGFyeSwgYXJpdHldO1xuXG4gIGlmIChkYXRhKSB7XG4gICAgbWVyZ2VEYXRhKG5ld0RhdGEsIGRhdGEpO1xuICAgIGJpdG1hc2sgPSBuZXdEYXRhWzFdO1xuICAgIGFyaXR5ID0gbmV3RGF0YVs5XTtcbiAgfVxuICBuZXdEYXRhWzldID0gYXJpdHkgPT0gbnVsbFxuICAgID8gKGlzQmluZEtleSA/IDAgOiBmdW5jLmxlbmd0aClcbiAgICA6IChuYXRpdmVNYXgoYXJpdHkgLSBsZW5ndGgsIDApIHx8IDApO1xuXG4gIGlmIChiaXRtYXNrID09IEJJTkRfRkxBRykge1xuICAgIHZhciByZXN1bHQgPSBjcmVhdGVCaW5kV3JhcHBlcihuZXdEYXRhWzBdLCBuZXdEYXRhWzJdKTtcbiAgfSBlbHNlIGlmICgoYml0bWFzayA9PSBQQVJUSUFMX0ZMQUcgfHwgYml0bWFzayA9PSAoQklORF9GTEFHIHwgUEFSVElBTF9GTEFHKSkgJiYgIW5ld0RhdGFbNF0ubGVuZ3RoKSB7XG4gICAgcmVzdWx0ID0gY3JlYXRlUGFydGlhbFdyYXBwZXIuYXBwbHkodW5kZWZpbmVkLCBuZXdEYXRhKTtcbiAgfSBlbHNlIHtcbiAgICByZXN1bHQgPSBjcmVhdGVIeWJyaWRXcmFwcGVyLmFwcGx5KHVuZGVmaW5lZCwgbmV3RGF0YSk7XG4gIH1cbiAgdmFyIHNldHRlciA9IGRhdGEgPyBiYXNlU2V0RGF0YSA6IHNldERhdGE7XG4gIHJldHVybiBzZXR0ZXIocmVzdWx0LCBuZXdEYXRhKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVXcmFwcGVyO1xuIiwidmFyIGFycmF5U29tZSA9IHJlcXVpcmUoJy4vYXJyYXlTb21lJyk7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbERlZXBgIGZvciBhcnJheXMgd2l0aCBzdXBwb3J0IGZvclxuICogcGFydGlhbCBkZWVwIGNvbXBhcmlzb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7QXJyYXl9IG90aGVyIFRoZSBvdGhlciBhcnJheSB0byBjb21wYXJlLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaW5nIGFycmF5cy5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzTG9vc2VdIFNwZWNpZnkgcGVyZm9ybWluZyBwYXJ0aWFsIGNvbXBhcmlzb25zLlxuICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQV0gVHJhY2tzIHRyYXZlcnNlZCBgdmFsdWVgIG9iamVjdHMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tCXSBUcmFja3MgdHJhdmVyc2VkIGBvdGhlcmAgb2JqZWN0cy5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgYXJyYXlzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGVxdWFsQXJyYXlzKGFycmF5LCBvdGhlciwgZXF1YWxGdW5jLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQikge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGFyckxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIG90aExlbmd0aCA9IG90aGVyLmxlbmd0aDtcblxuICBpZiAoYXJyTGVuZ3RoICE9IG90aExlbmd0aCAmJiAhKGlzTG9vc2UgJiYgb3RoTGVuZ3RoID4gYXJyTGVuZ3RoKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvLyBJZ25vcmUgbm9uLWluZGV4IHByb3BlcnRpZXMuXG4gIHdoaWxlICgrK2luZGV4IDwgYXJyTGVuZ3RoKSB7XG4gICAgdmFyIGFyclZhbHVlID0gYXJyYXlbaW5kZXhdLFxuICAgICAgICBvdGhWYWx1ZSA9IG90aGVyW2luZGV4XSxcbiAgICAgICAgcmVzdWx0ID0gY3VzdG9taXplciA/IGN1c3RvbWl6ZXIoaXNMb29zZSA/IG90aFZhbHVlIDogYXJyVmFsdWUsIGlzTG9vc2UgPyBhcnJWYWx1ZSA6IG90aFZhbHVlLCBpbmRleCkgOiB1bmRlZmluZWQ7XG5cbiAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIC8vIFJlY3Vyc2l2ZWx5IGNvbXBhcmUgYXJyYXlzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgaWYgKGlzTG9vc2UpIHtcbiAgICAgIGlmICghYXJyYXlTb21lKG90aGVyLCBmdW5jdGlvbihvdGhWYWx1ZSkge1xuICAgICAgICAgICAgcmV0dXJuIGFyclZhbHVlID09PSBvdGhWYWx1ZSB8fCBlcXVhbEZ1bmMoYXJyVmFsdWUsIG90aFZhbHVlLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQik7XG4gICAgICAgICAgfSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIShhcnJWYWx1ZSA9PT0gb3RoVmFsdWUgfHwgZXF1YWxGdW5jKGFyclZhbHVlLCBvdGhWYWx1ZSwgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlcXVhbEFycmF5cztcbiIsIi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgZXJyb3JUYWcgPSAnW29iamVjdCBFcnJvcl0nLFxuICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLFxuICAgIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nO1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxEZWVwYCBmb3IgY29tcGFyaW5nIG9iamVjdHMgb2ZcbiAqIHRoZSBzYW1lIGB0b1N0cmluZ1RhZ2AuXG4gKlxuICogKipOb3RlOioqIFRoaXMgZnVuY3Rpb24gb25seSBzdXBwb3J0cyBjb21wYXJpbmcgdmFsdWVzIHdpdGggdGFncyBvZlxuICogYEJvb2xlYW5gLCBgRGF0ZWAsIGBFcnJvcmAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgb3IgYFN0cmluZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtPYmplY3R9IG90aGVyIFRoZSBvdGhlciBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0YWcgVGhlIGB0b1N0cmluZ1RhZ2Agb2YgdGhlIG9iamVjdHMgdG8gY29tcGFyZS5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBlcXVhbEJ5VGFnKG9iamVjdCwgb3RoZXIsIHRhZykge1xuICBzd2l0Y2ggKHRhZykge1xuICAgIGNhc2UgYm9vbFRhZzpcbiAgICBjYXNlIGRhdGVUYWc6XG4gICAgICAvLyBDb2VyY2UgZGF0ZXMgYW5kIGJvb2xlYW5zIHRvIG51bWJlcnMsIGRhdGVzIHRvIG1pbGxpc2Vjb25kcyBhbmQgYm9vbGVhbnNcbiAgICAgIC8vIHRvIGAxYCBvciBgMGAgdHJlYXRpbmcgaW52YWxpZCBkYXRlcyBjb2VyY2VkIHRvIGBOYU5gIGFzIG5vdCBlcXVhbC5cbiAgICAgIHJldHVybiArb2JqZWN0ID09ICtvdGhlcjtcblxuICAgIGNhc2UgZXJyb3JUYWc6XG4gICAgICByZXR1cm4gb2JqZWN0Lm5hbWUgPT0gb3RoZXIubmFtZSAmJiBvYmplY3QubWVzc2FnZSA9PSBvdGhlci5tZXNzYWdlO1xuXG4gICAgY2FzZSBudW1iZXJUYWc6XG4gICAgICAvLyBUcmVhdCBgTmFOYCB2cy4gYE5hTmAgYXMgZXF1YWwuXG4gICAgICByZXR1cm4gKG9iamVjdCAhPSArb2JqZWN0KVxuICAgICAgICA/IG90aGVyICE9ICtvdGhlclxuICAgICAgICA6IG9iamVjdCA9PSArb3RoZXI7XG5cbiAgICBjYXNlIHJlZ2V4cFRhZzpcbiAgICBjYXNlIHN0cmluZ1RhZzpcbiAgICAgIC8vIENvZXJjZSByZWdleGVzIHRvIHN0cmluZ3MgYW5kIHRyZWF0IHN0cmluZ3MgcHJpbWl0aXZlcyBhbmQgc3RyaW5nXG4gICAgICAvLyBvYmplY3RzIGFzIGVxdWFsLiBTZWUgaHR0cHM6Ly9lczUuZ2l0aHViLmlvLyN4MTUuMTAuNi40IGZvciBtb3JlIGRldGFpbHMuXG4gICAgICByZXR1cm4gb2JqZWN0ID09IChvdGhlciArICcnKTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZXF1YWxCeVRhZztcbiIsInZhciBrZXlzID0gcmVxdWlyZSgnLi4vb2JqZWN0L2tleXMnKTtcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbERlZXBgIGZvciBvYmplY3RzIHdpdGggc3VwcG9ydCBmb3JcbiAqIHBhcnRpYWwgZGVlcCBjb21wYXJpc29ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge09iamVjdH0gb3RoZXIgVGhlIG90aGVyIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaW5nIHZhbHVlcy5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzTG9vc2VdIFNwZWNpZnkgcGVyZm9ybWluZyBwYXJ0aWFsIGNvbXBhcmlzb25zLlxuICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQV0gVHJhY2tzIHRyYXZlcnNlZCBgdmFsdWVgIG9iamVjdHMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tCXSBUcmFja3MgdHJhdmVyc2VkIGBvdGhlcmAgb2JqZWN0cy5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBlcXVhbE9iamVjdHMob2JqZWN0LCBvdGhlciwgZXF1YWxGdW5jLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQikge1xuICB2YXIgb2JqUHJvcHMgPSBrZXlzKG9iamVjdCksXG4gICAgICBvYmpMZW5ndGggPSBvYmpQcm9wcy5sZW5ndGgsXG4gICAgICBvdGhQcm9wcyA9IGtleXMob3RoZXIpLFxuICAgICAgb3RoTGVuZ3RoID0gb3RoUHJvcHMubGVuZ3RoO1xuXG4gIGlmIChvYmpMZW5ndGggIT0gb3RoTGVuZ3RoICYmICFpc0xvb3NlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciBpbmRleCA9IG9iakxlbmd0aDtcbiAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICB2YXIga2V5ID0gb2JqUHJvcHNbaW5kZXhdO1xuICAgIGlmICghKGlzTG9vc2UgPyBrZXkgaW4gb3RoZXIgOiBoYXNPd25Qcm9wZXJ0eS5jYWxsKG90aGVyLCBrZXkpKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICB2YXIgc2tpcEN0b3IgPSBpc0xvb3NlO1xuICB3aGlsZSAoKytpbmRleCA8IG9iakxlbmd0aCkge1xuICAgIGtleSA9IG9ialByb3BzW2luZGV4XTtcbiAgICB2YXIgb2JqVmFsdWUgPSBvYmplY3Rba2V5XSxcbiAgICAgICAgb3RoVmFsdWUgPSBvdGhlcltrZXldLFxuICAgICAgICByZXN1bHQgPSBjdXN0b21pemVyID8gY3VzdG9taXplcihpc0xvb3NlID8gb3RoVmFsdWUgOiBvYmpWYWx1ZSwgaXNMb29zZT8gb2JqVmFsdWUgOiBvdGhWYWx1ZSwga2V5KSA6IHVuZGVmaW5lZDtcblxuICAgIC8vIFJlY3Vyc2l2ZWx5IGNvbXBhcmUgb2JqZWN0cyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAgIGlmICghKHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gZXF1YWxGdW5jKG9ialZhbHVlLCBvdGhWYWx1ZSwgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpIDogcmVzdWx0KSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBza2lwQ3RvciB8fCAoc2tpcEN0b3IgPSBrZXkgPT0gJ2NvbnN0cnVjdG9yJyk7XG4gIH1cbiAgaWYgKCFza2lwQ3Rvcikge1xuICAgIHZhciBvYmpDdG9yID0gb2JqZWN0LmNvbnN0cnVjdG9yLFxuICAgICAgICBvdGhDdG9yID0gb3RoZXIuY29uc3RydWN0b3I7XG5cbiAgICAvLyBOb24gYE9iamVjdGAgb2JqZWN0IGluc3RhbmNlcyB3aXRoIGRpZmZlcmVudCBjb25zdHJ1Y3RvcnMgYXJlIG5vdCBlcXVhbC5cbiAgICBpZiAob2JqQ3RvciAhPSBvdGhDdG9yICYmXG4gICAgICAgICgnY29uc3RydWN0b3InIGluIG9iamVjdCAmJiAnY29uc3RydWN0b3InIGluIG90aGVyKSAmJlxuICAgICAgICAhKHR5cGVvZiBvYmpDdG9yID09ICdmdW5jdGlvbicgJiYgb2JqQ3RvciBpbnN0YW5jZW9mIG9iakN0b3IgJiZcbiAgICAgICAgICB0eXBlb2Ygb3RoQ3RvciA9PSAnZnVuY3Rpb24nICYmIG90aEN0b3IgaW5zdGFuY2VvZiBvdGhDdG9yKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlcXVhbE9iamVjdHM7XG4iLCJ2YXIgbWV0YU1hcCA9IHJlcXVpcmUoJy4vbWV0YU1hcCcpLFxuICAgIG5vb3AgPSByZXF1aXJlKCcuLi91dGlsaXR5L25vb3AnKTtcblxuLyoqXG4gKiBHZXRzIG1ldGFkYXRhIGZvciBgZnVuY2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHF1ZXJ5LlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1ldGFkYXRhIGZvciBgZnVuY2AuXG4gKi9cbnZhciBnZXREYXRhID0gIW1ldGFNYXAgPyBub29wIDogZnVuY3Rpb24oZnVuYykge1xuICByZXR1cm4gbWV0YU1hcC5nZXQoZnVuYyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGdldERhdGE7XG4iLCJ2YXIgcmVhbE5hbWVzID0gcmVxdWlyZSgnLi9yZWFsTmFtZXMnKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBuYW1lIG9mIGBmdW5jYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBmdW5jdGlvbiBuYW1lLlxuICovXG5mdW5jdGlvbiBnZXRGdW5jTmFtZShmdW5jKSB7XG4gIHZhciByZXN1bHQgPSAoZnVuYy5uYW1lICsgJycpLFxuICAgICAgYXJyYXkgPSByZWFsTmFtZXNbcmVzdWx0XSxcbiAgICAgIGxlbmd0aCA9IGFycmF5ID8gYXJyYXkubGVuZ3RoIDogMDtcblxuICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICB2YXIgZGF0YSA9IGFycmF5W2xlbmd0aF0sXG4gICAgICAgIG90aGVyRnVuYyA9IGRhdGEuZnVuYztcbiAgICBpZiAob3RoZXJGdW5jID09IG51bGwgfHwgb3RoZXJGdW5jID09IGZ1bmMpIHtcbiAgICAgIHJldHVybiBkYXRhLm5hbWU7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0RnVuY05hbWU7XG4iLCJ2YXIgYmFzZVByb3BlcnR5ID0gcmVxdWlyZSgnLi9iYXNlUHJvcGVydHknKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBcImxlbmd0aFwiIHByb3BlcnR5IHZhbHVlIG9mIGBvYmplY3RgLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gYXZvaWQgYSBbSklUIGJ1Z10oaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTE0Mjc5MilcbiAqIHRoYXQgYWZmZWN0cyBTYWZhcmkgb24gYXQgbGVhc3QgaU9TIDguMS04LjMgQVJNNjQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBcImxlbmd0aFwiIHZhbHVlLlxuICovXG52YXIgZ2V0TGVuZ3RoID0gYmFzZVByb3BlcnR5KCdsZW5ndGgnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBnZXRMZW5ndGg7XG4iLCJ2YXIgaXNTdHJpY3RDb21wYXJhYmxlID0gcmVxdWlyZSgnLi9pc1N0cmljdENvbXBhcmFibGUnKSxcbiAgICBwYWlycyA9IHJlcXVpcmUoJy4uL29iamVjdC9wYWlycycpO1xuXG4vKipcbiAqIEdldHMgdGhlIHByb3BlcnkgbmFtZXMsIHZhbHVlcywgYW5kIGNvbXBhcmUgZmxhZ3Mgb2YgYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbWF0Y2ggZGF0YSBvZiBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gZ2V0TWF0Y2hEYXRhKG9iamVjdCkge1xuICB2YXIgcmVzdWx0ID0gcGFpcnMob2JqZWN0KSxcbiAgICAgIGxlbmd0aCA9IHJlc3VsdC5sZW5ndGg7XG5cbiAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgcmVzdWx0W2xlbmd0aF1bMl0gPSBpc1N0cmljdENvbXBhcmFibGUocmVzdWx0W2xlbmd0aF1bMV0pO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0TWF0Y2hEYXRhO1xuIiwidmFyIGlzTmF0aXZlID0gcmVxdWlyZSgnLi4vbGFuZy9pc05hdGl2ZScpO1xuXG4vKipcbiAqIEdldHMgdGhlIG5hdGl2ZSBmdW5jdGlvbiBhdCBga2V5YCBvZiBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBtZXRob2QgdG8gZ2V0LlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGZ1bmN0aW9uIGlmIGl0J3MgbmF0aXZlLCBlbHNlIGB1bmRlZmluZWRgLlxuICovXG5mdW5jdGlvbiBnZXROYXRpdmUob2JqZWN0LCBrZXkpIHtcbiAgdmFyIHZhbHVlID0gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBvYmplY3Rba2V5XTtcbiAgcmV0dXJuIGlzTmF0aXZlKHZhbHVlKSA/IHZhbHVlIDogdW5kZWZpbmVkO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldE5hdGl2ZTtcbiIsIi8qKlxuICogR2V0cyB0aGUgaW5kZXggYXQgd2hpY2ggdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgYE5hTmAgaXMgZm91bmQgaW4gYGFycmF5YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNlYXJjaC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBmcm9tSW5kZXggVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCBgTmFOYCwgZWxzZSBgLTFgLlxuICovXG5mdW5jdGlvbiBpbmRleE9mTmFOKGFycmF5LCBmcm9tSW5kZXgsIGZyb21SaWdodCkge1xuICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgaW5kZXggPSBmcm9tSW5kZXggKyAoZnJvbVJpZ2h0ID8gMCA6IC0xKTtcblxuICB3aGlsZSAoKGZyb21SaWdodCA/IGluZGV4LS0gOiArK2luZGV4IDwgbGVuZ3RoKSkge1xuICAgIHZhciBvdGhlciA9IGFycmF5W2luZGV4XTtcbiAgICBpZiAob3RoZXIgIT09IG90aGVyKSB7XG4gICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuICB9XG4gIHJldHVybiAtMTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpbmRleE9mTmFOO1xuIiwiLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogSW5pdGlhbGl6ZXMgYW4gYXJyYXkgY2xvbmUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBjbG9uZS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgaW5pdGlhbGl6ZWQgY2xvbmUuXG4gKi9cbmZ1bmN0aW9uIGluaXRDbG9uZUFycmF5KGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBuZXcgYXJyYXkuY29uc3RydWN0b3IobGVuZ3RoKTtcblxuICAvLyBBZGQgYXJyYXkgcHJvcGVydGllcyBhc3NpZ25lZCBieSBgUmVnRXhwI2V4ZWNgLlxuICBpZiAobGVuZ3RoICYmIHR5cGVvZiBhcnJheVswXSA9PSAnc3RyaW5nJyAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKGFycmF5LCAnaW5kZXgnKSkge1xuICAgIHJlc3VsdC5pbmRleCA9IGFycmF5LmluZGV4O1xuICAgIHJlc3VsdC5pbnB1dCA9IGFycmF5LmlucHV0O1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaW5pdENsb25lQXJyYXk7XG4iLCIoZnVuY3Rpb24gKGdsb2JhbCl7XG52YXIgYnVmZmVyQ2xvbmUgPSByZXF1aXJlKCcuL2J1ZmZlckNsb25lJyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgbnVtYmVyVGFnID0gJ1tvYmplY3QgTnVtYmVyXScsXG4gICAgcmVnZXhwVGFnID0gJ1tvYmplY3QgUmVnRXhwXScsXG4gICAgc3RyaW5nVGFnID0gJ1tvYmplY3QgU3RyaW5nXSc7XG5cbnZhciBhcnJheUJ1ZmZlclRhZyA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsXG4gICAgZmxvYXQzMlRhZyA9ICdbb2JqZWN0IEZsb2F0MzJBcnJheV0nLFxuICAgIGZsb2F0NjRUYWcgPSAnW29iamVjdCBGbG9hdDY0QXJyYXldJyxcbiAgICBpbnQ4VGFnID0gJ1tvYmplY3QgSW50OEFycmF5XScsXG4gICAgaW50MTZUYWcgPSAnW29iamVjdCBJbnQxNkFycmF5XScsXG4gICAgaW50MzJUYWcgPSAnW29iamVjdCBJbnQzMkFycmF5XScsXG4gICAgdWludDhUYWcgPSAnW29iamVjdCBVaW50OEFycmF5XScsXG4gICAgdWludDhDbGFtcGVkVGFnID0gJ1tvYmplY3QgVWludDhDbGFtcGVkQXJyYXldJyxcbiAgICB1aW50MTZUYWcgPSAnW29iamVjdCBVaW50MTZBcnJheV0nLFxuICAgIHVpbnQzMlRhZyA9ICdbb2JqZWN0IFVpbnQzMkFycmF5XSc7XG5cbi8qKiBVc2VkIHRvIG1hdGNoIGBSZWdFeHBgIGZsYWdzIGZyb20gdGhlaXIgY29lcmNlZCBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlRmxhZ3MgPSAvXFx3KiQvO1xuXG4vKiogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIFVpbnQ4QXJyYXkgPSBnbG9iYWwuVWludDhBcnJheTtcblxuLyoqIFVzZWQgdG8gbG9va3VwIGEgdHlwZSBhcnJheSBjb25zdHJ1Y3RvcnMgYnkgYHRvU3RyaW5nVGFnYC4gKi9cbnZhciBjdG9yQnlUYWcgPSB7fTtcbmN0b3JCeVRhZ1tmbG9hdDMyVGFnXSA9IGdsb2JhbC5GbG9hdDMyQXJyYXk7XG5jdG9yQnlUYWdbZmxvYXQ2NFRhZ10gPSBnbG9iYWwuRmxvYXQ2NEFycmF5O1xuY3RvckJ5VGFnW2ludDhUYWddID0gZ2xvYmFsLkludDhBcnJheTtcbmN0b3JCeVRhZ1tpbnQxNlRhZ10gPSBnbG9iYWwuSW50MTZBcnJheTtcbmN0b3JCeVRhZ1tpbnQzMlRhZ10gPSBnbG9iYWwuSW50MzJBcnJheTtcbmN0b3JCeVRhZ1t1aW50OFRhZ10gPSBVaW50OEFycmF5O1xuY3RvckJ5VGFnW3VpbnQ4Q2xhbXBlZFRhZ10gPSBnbG9iYWwuVWludDhDbGFtcGVkQXJyYXk7XG5jdG9yQnlUYWdbdWludDE2VGFnXSA9IGdsb2JhbC5VaW50MTZBcnJheTtcbmN0b3JCeVRhZ1t1aW50MzJUYWddID0gZ2xvYmFsLlVpbnQzMkFycmF5O1xuXG4vKipcbiAqIEluaXRpYWxpemVzIGFuIG9iamVjdCBjbG9uZSBiYXNlZCBvbiBpdHMgYHRvU3RyaW5nVGFnYC5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBvbmx5IHN1cHBvcnRzIGNsb25pbmcgdmFsdWVzIHdpdGggdGFncyBvZlxuICogYEJvb2xlYW5gLCBgRGF0ZWAsIGBFcnJvcmAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgb3IgYFN0cmluZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjbG9uZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0YWcgVGhlIGB0b1N0cmluZ1RhZ2Agb2YgdGhlIG9iamVjdCB0byBjbG9uZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzRGVlcF0gU3BlY2lmeSBhIGRlZXAgY2xvbmUuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAqL1xuZnVuY3Rpb24gaW5pdENsb25lQnlUYWcob2JqZWN0LCB0YWcsIGlzRGVlcCkge1xuICB2YXIgQ3RvciA9IG9iamVjdC5jb25zdHJ1Y3RvcjtcbiAgc3dpdGNoICh0YWcpIHtcbiAgICBjYXNlIGFycmF5QnVmZmVyVGFnOlxuICAgICAgcmV0dXJuIGJ1ZmZlckNsb25lKG9iamVjdCk7XG5cbiAgICBjYXNlIGJvb2xUYWc6XG4gICAgY2FzZSBkYXRlVGFnOlxuICAgICAgcmV0dXJuIG5ldyBDdG9yKCtvYmplY3QpO1xuXG4gICAgY2FzZSBmbG9hdDMyVGFnOiBjYXNlIGZsb2F0NjRUYWc6XG4gICAgY2FzZSBpbnQ4VGFnOiBjYXNlIGludDE2VGFnOiBjYXNlIGludDMyVGFnOlxuICAgIGNhc2UgdWludDhUYWc6IGNhc2UgdWludDhDbGFtcGVkVGFnOiBjYXNlIHVpbnQxNlRhZzogY2FzZSB1aW50MzJUYWc6XG4gICAgICAvLyBTYWZhcmkgNSBtb2JpbGUgaW5jb3JyZWN0bHkgaGFzIGBPYmplY3RgIGFzIHRoZSBjb25zdHJ1Y3RvciBvZiB0eXBlZCBhcnJheXMuXG4gICAgICBpZiAoQ3RvciBpbnN0YW5jZW9mIEN0b3IpIHtcbiAgICAgICAgQ3RvciA9IGN0b3JCeVRhZ1t0YWddO1xuICAgICAgfVxuICAgICAgdmFyIGJ1ZmZlciA9IG9iamVjdC5idWZmZXI7XG4gICAgICByZXR1cm4gbmV3IEN0b3IoaXNEZWVwID8gYnVmZmVyQ2xvbmUoYnVmZmVyKSA6IGJ1ZmZlciwgb2JqZWN0LmJ5dGVPZmZzZXQsIG9iamVjdC5sZW5ndGgpO1xuXG4gICAgY2FzZSBudW1iZXJUYWc6XG4gICAgY2FzZSBzdHJpbmdUYWc6XG4gICAgICByZXR1cm4gbmV3IEN0b3Iob2JqZWN0KTtcblxuICAgIGNhc2UgcmVnZXhwVGFnOlxuICAgICAgdmFyIHJlc3VsdCA9IG5ldyBDdG9yKG9iamVjdC5zb3VyY2UsIHJlRmxhZ3MuZXhlYyhvYmplY3QpKTtcbiAgICAgIHJlc3VsdC5sYXN0SW5kZXggPSBvYmplY3QubGFzdEluZGV4O1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaW5pdENsb25lQnlUYWc7XG5cbn0pLmNhbGwodGhpcyx0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDogdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9KVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ6dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiSW01dlpHVmZiVzlrZFd4bGN5OXNiMlJoYzJndFkyOXRjR0YwTDJsdWRHVnlibUZzTDJsdWFYUkRiRzl1WlVKNVZHRm5MbXB6SWwwc0ltNWhiV1Z6SWpwYlhTd2liV0Z3Y0dsdVozTWlPaUk3UVVGQlFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CSWl3aVptbHNaU0k2SW1kbGJtVnlZWFJsWkM1cWN5SXNJbk52ZFhKalpWSnZiM1FpT2lJaUxDSnpiM1Z5WTJWelEyOXVkR1Z1ZENJNld5SjJZWElnWW5WbVptVnlRMnh2Ym1VZ1BTQnlaWEYxYVhKbEtDY3VMMkoxWm1abGNrTnNiMjVsSnlrN1hHNWNiaThxS2lCZ1QySnFaV04wSTNSdlUzUnlhVzVuWUNCeVpYTjFiSFFnY21WbVpYSmxibU5sY3k0Z0tpOWNiblpoY2lCaWIyOXNWR0ZuSUQwZ0oxdHZZbXBsWTNRZ1FtOXZiR1ZoYmwwbkxGeHVJQ0FnSUdSaGRHVlVZV2NnUFNBblcyOWlhbVZqZENCRVlYUmxYU2NzWEc0Z0lDQWdiblZ0WW1WeVZHRm5JRDBnSjF0dlltcGxZM1FnVG5WdFltVnlYU2NzWEc0Z0lDQWdjbVZuWlhod1ZHRm5JRDBnSjF0dlltcGxZM1FnVW1WblJYaHdYU2NzWEc0Z0lDQWdjM1J5YVc1blZHRm5JRDBnSjF0dlltcGxZM1FnVTNSeWFXNW5YU2M3WEc1Y2JuWmhjaUJoY25KaGVVSjFabVpsY2xSaFp5QTlJQ2RiYjJKcVpXTjBJRUZ5Y21GNVFuVm1abVZ5WFNjc1hHNGdJQ0FnWm14dllYUXpNbFJoWnlBOUlDZGJiMkpxWldOMElFWnNiMkYwTXpKQmNuSmhlVjBuTEZ4dUlDQWdJR1pzYjJGME5qUlVZV2NnUFNBblcyOWlhbVZqZENCR2JHOWhkRFkwUVhKeVlYbGRKeXhjYmlBZ0lDQnBiblE0VkdGbklEMGdKMXR2WW1wbFkzUWdTVzUwT0VGeWNtRjVYU2NzWEc0Z0lDQWdhVzUwTVRaVVlXY2dQU0FuVzI5aWFtVmpkQ0JKYm5ReE5rRnljbUY1WFNjc1hHNGdJQ0FnYVc1ME16SlVZV2NnUFNBblcyOWlhbVZqZENCSmJuUXpNa0Z5Y21GNVhTY3NYRzRnSUNBZ2RXbHVkRGhVWVdjZ1BTQW5XMjlpYW1WamRDQlZhVzUwT0VGeWNtRjVYU2NzWEc0Z0lDQWdkV2x1ZERoRGJHRnRjR1ZrVkdGbklEMGdKMXR2WW1wbFkzUWdWV2x1ZERoRGJHRnRjR1ZrUVhKeVlYbGRKeXhjYmlBZ0lDQjFhVzUwTVRaVVlXY2dQU0FuVzI5aWFtVmpkQ0JWYVc1ME1UWkJjbkpoZVYwbkxGeHVJQ0FnSUhWcGJuUXpNbFJoWnlBOUlDZGJiMkpxWldOMElGVnBiblF6TWtGeWNtRjVYU2M3WEc1Y2JpOHFLaUJWYzJWa0lIUnZJRzFoZEdOb0lHQlNaV2RGZUhCZ0lHWnNZV2R6SUdaeWIyMGdkR2hsYVhJZ1kyOWxjbU5sWkNCemRISnBibWNnZG1Gc2RXVnpMaUFxTDF4dWRtRnlJSEpsUm14aFozTWdQU0F2WEZ4M0tpUXZPMXh1WEc0dktpb2dUbUYwYVhabElHMWxkR2h2WkNCeVpXWmxjbVZ1WTJWekxpQXFMMXh1ZG1GeUlGVnBiblE0UVhKeVlYa2dQU0JuYkc5aVlXd3VWV2x1ZERoQmNuSmhlVHRjYmx4dUx5b3FJRlZ6WldRZ2RHOGdiRzl2YTNWd0lHRWdkSGx3WlNCaGNuSmhlU0JqYjI1emRISjFZM1J2Y25NZ1lua2dZSFJ2VTNSeWFXNW5WR0ZuWUM0Z0tpOWNiblpoY2lCamRHOXlRbmxVWVdjZ1BTQjdmVHRjYm1OMGIzSkNlVlJoWjF0bWJHOWhkRE15VkdGblhTQTlJR2RzYjJKaGJDNUdiRzloZERNeVFYSnlZWGs3WEc1amRHOXlRbmxVWVdkYlpteHZZWFEyTkZSaFoxMGdQU0JuYkc5aVlXd3VSbXh2WVhRMk5FRnljbUY1TzF4dVkzUnZja0o1VkdGblcybHVkRGhVWVdkZElEMGdaMnh2WW1Gc0xrbHVkRGhCY25KaGVUdGNibU4wYjNKQ2VWUmhaMXRwYm5ReE5sUmhaMTBnUFNCbmJHOWlZV3d1U1c1ME1UWkJjbkpoZVR0Y2JtTjBiM0pDZVZSaFoxdHBiblF6TWxSaFoxMGdQU0JuYkc5aVlXd3VTVzUwTXpKQmNuSmhlVHRjYm1OMGIzSkNlVlJoWjF0MWFXNTBPRlJoWjEwZ1BTQlZhVzUwT0VGeWNtRjVPMXh1WTNSdmNrSjVWR0ZuVzNWcGJuUTRRMnhoYlhCbFpGUmhaMTBnUFNCbmJHOWlZV3d1VldsdWREaERiR0Z0Y0dWa1FYSnlZWGs3WEc1amRHOXlRbmxVWVdkYmRXbHVkREUyVkdGblhTQTlJR2RzYjJKaGJDNVZhVzUwTVRaQmNuSmhlVHRjYm1OMGIzSkNlVlJoWjF0MWFXNTBNekpVWVdkZElEMGdaMnh2WW1Gc0xsVnBiblF6TWtGeWNtRjVPMXh1WEc0dktpcGNiaUFxSUVsdWFYUnBZV3hwZW1WeklHRnVJRzlpYW1WamRDQmpiRzl1WlNCaVlYTmxaQ0J2YmlCcGRITWdZSFJ2VTNSeWFXNW5WR0ZuWUM1Y2JpQXFYRzRnS2lBcUtrNXZkR1U2S2lvZ1ZHaHBjeUJtZFc1amRHbHZiaUJ2Ym14NUlITjFjSEJ2Y25SeklHTnNiMjVwYm1jZ2RtRnNkV1Z6SUhkcGRHZ2dkR0ZuY3lCdlpseHVJQ29nWUVKdmIyeGxZVzVnTENCZ1JHRjBaV0FzSUdCRmNuSnZjbUFzSUdCT2RXMWlaWEpnTENCZ1VtVm5SWGh3WUN3Z2IzSWdZRk4wY21sdVoyQXVYRzRnS2x4dUlDb2dRSEJ5YVhaaGRHVmNiaUFxSUVCd1lYSmhiU0I3VDJKcVpXTjBmU0J2WW1wbFkzUWdWR2hsSUc5aWFtVmpkQ0IwYnlCamJHOXVaUzVjYmlBcUlFQndZWEpoYlNCN2MzUnlhVzVuZlNCMFlXY2dWR2hsSUdCMGIxTjBjbWx1WjFSaFoyQWdiMllnZEdobElHOWlhbVZqZENCMGJ5QmpiRzl1WlM1Y2JpQXFJRUJ3WVhKaGJTQjdZbTl2YkdWaGJuMGdXMmx6UkdWbGNGMGdVM0JsWTJsbWVTQmhJR1JsWlhBZ1kyeHZibVV1WEc0Z0tpQkFjbVYwZFhKdWN5QjdUMkpxWldOMGZTQlNaWFIxY201eklIUm9aU0JwYm1sMGFXRnNhWHBsWkNCamJHOXVaUzVjYmlBcUwxeHVablZ1WTNScGIyNGdhVzVwZEVOc2IyNWxRbmxVWVdjb2IySnFaV04wTENCMFlXY3NJR2x6UkdWbGNDa2dlMXh1SUNCMllYSWdRM1J2Y2lBOUlHOWlhbVZqZEM1amIyNXpkSEoxWTNSdmNqdGNiaUFnYzNkcGRHTm9JQ2gwWVdjcElIdGNiaUFnSUNCallYTmxJR0Z5Y21GNVFuVm1abVZ5VkdGbk9seHVJQ0FnSUNBZ2NtVjBkWEp1SUdKMVptWmxja05zYjI1bEtHOWlhbVZqZENrN1hHNWNiaUFnSUNCallYTmxJR0p2YjJ4VVlXYzZYRzRnSUNBZ1kyRnpaU0JrWVhSbFZHRm5PbHh1SUNBZ0lDQWdjbVYwZFhKdUlHNWxkeUJEZEc5eUtDdHZZbXBsWTNRcE8xeHVYRzRnSUNBZ1kyRnpaU0JtYkc5aGRETXlWR0ZuT2lCallYTmxJR1pzYjJGME5qUlVZV2M2WEc0Z0lDQWdZMkZ6WlNCcGJuUTRWR0ZuT2lCallYTmxJR2x1ZERFMlZHRm5PaUJqWVhObElHbHVkRE15VkdGbk9seHVJQ0FnSUdOaGMyVWdkV2x1ZERoVVlXYzZJR05oYzJVZ2RXbHVkRGhEYkdGdGNHVmtWR0ZuT2lCallYTmxJSFZwYm5ReE5sUmhaem9nWTJGelpTQjFhVzUwTXpKVVlXYzZYRzRnSUNBZ0lDQXZMeUJUWVdaaGNta2dOU0J0YjJKcGJHVWdhVzVqYjNKeVpXTjBiSGtnYUdGeklHQlBZbXBsWTNSZ0lHRnpJSFJvWlNCamIyNXpkSEoxWTNSdmNpQnZaaUIwZVhCbFpDQmhjbkpoZVhNdVhHNGdJQ0FnSUNCcFppQW9RM1J2Y2lCcGJuTjBZVzVqWlc5bUlFTjBiM0lwSUh0Y2JpQWdJQ0FnSUNBZ1EzUnZjaUE5SUdOMGIzSkNlVlJoWjF0MFlXZGRPMXh1SUNBZ0lDQWdmVnh1SUNBZ0lDQWdkbUZ5SUdKMVptWmxjaUE5SUc5aWFtVmpkQzVpZFdabVpYSTdYRzRnSUNBZ0lDQnlaWFIxY200Z2JtVjNJRU4wYjNJb2FYTkVaV1Z3SUQ4Z1luVm1abVZ5UTJ4dmJtVW9ZblZtWm1WeUtTQTZJR0oxWm1abGNpd2diMkpxWldOMExtSjVkR1ZQWm1aelpYUXNJRzlpYW1WamRDNXNaVzVuZEdncE8xeHVYRzRnSUNBZ1kyRnpaU0J1ZFcxaVpYSlVZV2M2WEc0Z0lDQWdZMkZ6WlNCemRISnBibWRVWVdjNlhHNGdJQ0FnSUNCeVpYUjFjbTRnYm1WM0lFTjBiM0lvYjJKcVpXTjBLVHRjYmx4dUlDQWdJR05oYzJVZ2NtVm5aWGh3VkdGbk9seHVJQ0FnSUNBZ2RtRnlJSEpsYzNWc2RDQTlJRzVsZHlCRGRHOXlLRzlpYW1WamRDNXpiM1Z5WTJVc0lISmxSbXhoWjNNdVpYaGxZeWh2WW1wbFkzUXBLVHRjYmlBZ0lDQWdJSEpsYzNWc2RDNXNZWE4wU1c1a1pYZ2dQU0J2WW1wbFkzUXViR0Z6ZEVsdVpHVjRPMXh1SUNCOVhHNGdJSEpsZEhWeWJpQnlaWE4xYkhRN1hHNTlYRzVjYm0xdlpIVnNaUzVsZUhCdmNuUnpJRDBnYVc1cGRFTnNiMjVsUW5sVVlXYzdYRzRpWFgwPSIsIi8qKlxuICogSW5pdGlhbGl6ZXMgYW4gb2JqZWN0IGNsb25lLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY2xvbmUuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAqL1xuZnVuY3Rpb24gaW5pdENsb25lT2JqZWN0KG9iamVjdCkge1xuICB2YXIgQ3RvciA9IG9iamVjdC5jb25zdHJ1Y3RvcjtcbiAgaWYgKCEodHlwZW9mIEN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBDdG9yIGluc3RhbmNlb2YgQ3RvcikpIHtcbiAgICBDdG9yID0gT2JqZWN0O1xuICB9XG4gIHJldHVybiBuZXcgQ3Rvcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpbml0Q2xvbmVPYmplY3Q7XG4iLCJ2YXIgZ2V0TGVuZ3RoID0gcmVxdWlyZSgnLi9nZXRMZW5ndGgnKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4vaXNMZW5ndGgnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhcnJheS1saWtlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFycmF5LWxpa2UsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNBcnJheUxpa2UodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlICE9IG51bGwgJiYgaXNMZW5ndGgoZ2V0TGVuZ3RoKHZhbHVlKSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNBcnJheUxpa2U7XG4iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgaG9zdCBvYmplY3QgaW4gSUUgPCA5LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgaG9zdCBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqL1xudmFyIGlzSG9zdE9iamVjdCA9IChmdW5jdGlvbigpIHtcbiAgdHJ5IHtcbiAgICBPYmplY3QoeyAndG9TdHJpbmcnOiAwIH0gKyAnJyk7XG4gIH0gY2F0Y2goZSkge1xuICAgIHJldHVybiBmdW5jdGlvbigpIHsgcmV0dXJuIGZhbHNlOyB9O1xuICB9XG4gIHJldHVybiBmdW5jdGlvbih2YWx1ZSkge1xuICAgIC8vIElFIDwgOSBwcmVzZW50cyBtYW55IGhvc3Qgb2JqZWN0cyBhcyBgT2JqZWN0YCBvYmplY3RzIHRoYXQgY2FuIGNvZXJjZVxuICAgIC8vIHRvIHN0cmluZ3MgZGVzcGl0ZSBoYXZpbmcgaW1wcm9wZXJseSBkZWZpbmVkIGB0b1N0cmluZ2AgbWV0aG9kcy5cbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlLnRvU3RyaW5nICE9ICdmdW5jdGlvbicgJiYgdHlwZW9mICh2YWx1ZSArICcnKSA9PSAnc3RyaW5nJztcbiAgfTtcbn0oKSk7XG5cbm1vZHVsZS5leHBvcnRzID0gaXNIb3N0T2JqZWN0O1xuIiwiLyoqIFVzZWQgdG8gZGV0ZWN0IHVuc2lnbmVkIGludGVnZXIgdmFsdWVzLiAqL1xudmFyIHJlSXNVaW50ID0gL15cXGQrJC87XG5cbi8qKlxuICogVXNlZCBhcyB0aGUgW21heGltdW0gbGVuZ3RoXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1udW1iZXIubWF4X3NhZmVfaW50ZWdlcilcbiAqIG9mIGFuIGFycmF5LWxpa2UgdmFsdWUuXG4gKi9cbnZhciBNQVhfU0FGRV9JTlRFR0VSID0gOTAwNzE5OTI1NDc0MDk5MTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgaW5kZXguXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGg9TUFYX1NBRkVfSU5URUdFUl0gVGhlIHVwcGVyIGJvdW5kcyBvZiBhIHZhbGlkIGluZGV4LlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBpbmRleCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0luZGV4KHZhbHVlLCBsZW5ndGgpIHtcbiAgdmFsdWUgPSAodHlwZW9mIHZhbHVlID09ICdudW1iZXInIHx8IHJlSXNVaW50LnRlc3QodmFsdWUpKSA/ICt2YWx1ZSA6IC0xO1xuICBsZW5ndGggPSBsZW5ndGggPT0gbnVsbCA/IE1BWF9TQUZFX0lOVEVHRVIgOiBsZW5ndGg7XG4gIHJldHVybiB2YWx1ZSA+IC0xICYmIHZhbHVlICUgMSA9PSAwICYmIHZhbHVlIDwgbGVuZ3RoO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzSW5kZXg7XG4iLCJ2YXIgaXNBcnJheUxpa2UgPSByZXF1aXJlKCcuL2lzQXJyYXlMaWtlJyksXG4gICAgaXNJbmRleCA9IHJlcXVpcmUoJy4vaXNJbmRleCcpLFxuICAgIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vbGFuZy9pc09iamVjdCcpO1xuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgcHJvdmlkZWQgYXJndW1lbnRzIGFyZSBmcm9tIGFuIGl0ZXJhdGVlIGNhbGwuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHBvdGVudGlhbCBpdGVyYXRlZSB2YWx1ZSBhcmd1bWVudC5cbiAqIEBwYXJhbSB7Kn0gaW5kZXggVGhlIHBvdGVudGlhbCBpdGVyYXRlZSBpbmRleCBvciBrZXkgYXJndW1lbnQuXG4gKiBAcGFyYW0geyp9IG9iamVjdCBUaGUgcG90ZW50aWFsIGl0ZXJhdGVlIG9iamVjdCBhcmd1bWVudC5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgYXJndW1lbnRzIGFyZSBmcm9tIGFuIGl0ZXJhdGVlIGNhbGwsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNJdGVyYXRlZUNhbGwodmFsdWUsIGluZGV4LCBvYmplY3QpIHtcbiAgaWYgKCFpc09iamVjdChvYmplY3QpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciB0eXBlID0gdHlwZW9mIGluZGV4O1xuICBpZiAodHlwZSA9PSAnbnVtYmVyJ1xuICAgICAgPyAoaXNBcnJheUxpa2Uob2JqZWN0KSAmJiBpc0luZGV4KGluZGV4LCBvYmplY3QubGVuZ3RoKSlcbiAgICAgIDogKHR5cGUgPT0gJ3N0cmluZycgJiYgaW5kZXggaW4gb2JqZWN0KSkge1xuICAgIHZhciBvdGhlciA9IG9iamVjdFtpbmRleF07XG4gICAgcmV0dXJuIHZhbHVlID09PSB2YWx1ZSA/ICh2YWx1ZSA9PT0gb3RoZXIpIDogKG90aGVyICE9PSBvdGhlcik7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzSXRlcmF0ZWVDYWxsO1xuIiwidmFyIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKTtcblxuLyoqIFVzZWQgdG8gbWF0Y2ggcHJvcGVydHkgbmFtZXMgd2l0aGluIHByb3BlcnR5IHBhdGhzLiAqL1xudmFyIHJlSXNEZWVwUHJvcCA9IC9cXC58XFxbKD86W15bXFxdXSp8KFtcIiddKSg/Oig/IVxcMSlbXlxcblxcXFxdfFxcXFwuKSo/XFwxKVxcXS8sXG4gICAgcmVJc1BsYWluUHJvcCA9IC9eXFx3KiQvO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgcHJvcGVydHkgbmFtZSBhbmQgbm90IGEgcHJvcGVydHkgcGF0aC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIG9iamVjdCB0byBxdWVyeSBrZXlzIG9uLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBwcm9wZXJ0eSBuYW1lLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzS2V5KHZhbHVlLCBvYmplY3QpIHtcbiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gIGlmICgodHlwZSA9PSAnc3RyaW5nJyAmJiByZUlzUGxhaW5Qcm9wLnRlc3QodmFsdWUpKSB8fCB0eXBlID09ICdudW1iZXInKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciByZXN1bHQgPSAhcmVJc0RlZXBQcm9wLnRlc3QodmFsdWUpO1xuICByZXR1cm4gcmVzdWx0IHx8IChvYmplY3QgIT0gbnVsbCAmJiB2YWx1ZSBpbiB0b09iamVjdChvYmplY3QpKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0tleTtcbiIsInZhciBMYXp5V3JhcHBlciA9IHJlcXVpcmUoJy4vTGF6eVdyYXBwZXInKSxcbiAgICBnZXREYXRhID0gcmVxdWlyZSgnLi9nZXREYXRhJyksXG4gICAgZ2V0RnVuY05hbWUgPSByZXF1aXJlKCcuL2dldEZ1bmNOYW1lJyksXG4gICAgbG9kYXNoID0gcmVxdWlyZSgnLi4vY2hhaW4vbG9kYXNoJyk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGBmdW5jYCBoYXMgYSBsYXp5IGNvdW50ZXJwYXJ0LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgZnVuY2AgaGFzIGEgbGF6eSBjb3VudGVycGFydCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0xhemlhYmxlKGZ1bmMpIHtcbiAgdmFyIGZ1bmNOYW1lID0gZ2V0RnVuY05hbWUoZnVuYyksXG4gICAgICBvdGhlciA9IGxvZGFzaFtmdW5jTmFtZV07XG5cbiAgaWYgKHR5cGVvZiBvdGhlciAhPSAnZnVuY3Rpb24nIHx8ICEoZnVuY05hbWUgaW4gTGF6eVdyYXBwZXIucHJvdG90eXBlKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoZnVuYyA9PT0gb3RoZXIpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICB2YXIgZGF0YSA9IGdldERhdGEob3RoZXIpO1xuICByZXR1cm4gISFkYXRhICYmIGZ1bmMgPT09IGRhdGFbMF07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNMYXppYWJsZTtcbiIsIi8qKlxuICogVXNlZCBhcyB0aGUgW21heGltdW0gbGVuZ3RoXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1udW1iZXIubWF4X3NhZmVfaW50ZWdlcilcbiAqIG9mIGFuIGFycmF5LWxpa2UgdmFsdWUuXG4gKi9cbnZhciBNQVhfU0FGRV9JTlRFR0VSID0gOTAwNzE5OTI1NDc0MDk5MTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgbGVuZ3RoLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIGZ1bmN0aW9uIGlzIGJhc2VkIG9uIFtgVG9MZW5ndGhgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy10b2xlbmd0aCkuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBsZW5ndGgsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNMZW5ndGgodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyAmJiB2YWx1ZSA+IC0xICYmIHZhbHVlICUgMSA9PSAwICYmIHZhbHVlIDw9IE1BWF9TQUZFX0lOVEVHRVI7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNMZW5ndGg7XG4iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0TGlrZSh2YWx1ZSkge1xuICByZXR1cm4gISF2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNPYmplY3RMaWtlO1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vbGFuZy9pc09iamVjdCcpO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHN1aXRhYmxlIGZvciBzdHJpY3QgZXF1YWxpdHkgY29tcGFyaXNvbnMsIGkuZS4gYD09PWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaWYgc3VpdGFibGUgZm9yIHN0cmljdFxuICogIGVxdWFsaXR5IGNvbXBhcmlzb25zLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzU3RyaWN0Q29tcGFyYWJsZSh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgPT09IHZhbHVlICYmICFpc09iamVjdCh2YWx1ZSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNTdHJpY3RDb21wYXJhYmxlO1xuIiwidmFyIGFycmF5Q29weSA9IHJlcXVpcmUoJy4vYXJyYXlDb3B5JyksXG4gICAgY29tcG9zZUFyZ3MgPSByZXF1aXJlKCcuL2NvbXBvc2VBcmdzJyksXG4gICAgY29tcG9zZUFyZ3NSaWdodCA9IHJlcXVpcmUoJy4vY29tcG9zZUFyZ3NSaWdodCcpLFxuICAgIHJlcGxhY2VIb2xkZXJzID0gcmVxdWlyZSgnLi9yZXBsYWNlSG9sZGVycycpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB3cmFwcGVyIG1ldGFkYXRhLiAqL1xudmFyIEJJTkRfRkxBRyA9IDEsXG4gICAgQ1VSUllfQk9VTkRfRkxBRyA9IDQsXG4gICAgQ1VSUllfRkxBRyA9IDgsXG4gICAgQVJZX0ZMQUcgPSAxMjgsXG4gICAgUkVBUkdfRkxBRyA9IDI1NjtcblxuLyoqIFVzZWQgYXMgdGhlIGludGVybmFsIGFyZ3VtZW50IHBsYWNlaG9sZGVyLiAqL1xudmFyIFBMQUNFSE9MREVSID0gJ19fbG9kYXNoX3BsYWNlaG9sZGVyX18nO1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1pbiA9IE1hdGgubWluO1xuXG4vKipcbiAqIE1lcmdlcyB0aGUgZnVuY3Rpb24gbWV0YWRhdGEgb2YgYHNvdXJjZWAgaW50byBgZGF0YWAuXG4gKlxuICogTWVyZ2luZyBtZXRhZGF0YSByZWR1Y2VzIHRoZSBudW1iZXIgb2Ygd3JhcHBlcnMgcmVxdWlyZWQgdG8gaW52b2tlIGEgZnVuY3Rpb24uXG4gKiBUaGlzIGlzIHBvc3NpYmxlIGJlY2F1c2UgbWV0aG9kcyBsaWtlIGBfLmJpbmRgLCBgXy5jdXJyeWAsIGFuZCBgXy5wYXJ0aWFsYFxuICogbWF5IGJlIGFwcGxpZWQgcmVnYXJkbGVzcyBvZiBleGVjdXRpb24gb3JkZXIuIE1ldGhvZHMgbGlrZSBgXy5hcnlgIGFuZCBgXy5yZWFyZ2BcbiAqIGF1Z21lbnQgZnVuY3Rpb24gYXJndW1lbnRzLCBtYWtpbmcgdGhlIG9yZGVyIGluIHdoaWNoIHRoZXkgYXJlIGV4ZWN1dGVkIGltcG9ydGFudCxcbiAqIHByZXZlbnRpbmcgdGhlIG1lcmdpbmcgb2YgbWV0YWRhdGEuIEhvd2V2ZXIsIHdlIG1ha2UgYW4gZXhjZXB0aW9uIGZvciBhIHNhZmVcbiAqIGNvbW1vbiBjYXNlIHdoZXJlIGN1cnJpZWQgZnVuY3Rpb25zIGhhdmUgYF8uYXJ5YCBhbmQgb3IgYF8ucmVhcmdgIGFwcGxpZWQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGRhdGEgVGhlIGRlc3RpbmF0aW9uIG1ldGFkYXRhLlxuICogQHBhcmFtIHtBcnJheX0gc291cmNlIFRoZSBzb3VyY2UgbWV0YWRhdGEuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGRhdGFgLlxuICovXG5mdW5jdGlvbiBtZXJnZURhdGEoZGF0YSwgc291cmNlKSB7XG4gIHZhciBiaXRtYXNrID0gZGF0YVsxXSxcbiAgICAgIHNyY0JpdG1hc2sgPSBzb3VyY2VbMV0sXG4gICAgICBuZXdCaXRtYXNrID0gYml0bWFzayB8IHNyY0JpdG1hc2ssXG4gICAgICBpc0NvbW1vbiA9IG5ld0JpdG1hc2sgPCBBUllfRkxBRztcblxuICB2YXIgaXNDb21ibyA9XG4gICAgKHNyY0JpdG1hc2sgPT0gQVJZX0ZMQUcgJiYgYml0bWFzayA9PSBDVVJSWV9GTEFHKSB8fFxuICAgIChzcmNCaXRtYXNrID09IEFSWV9GTEFHICYmIGJpdG1hc2sgPT0gUkVBUkdfRkxBRyAmJiBkYXRhWzddLmxlbmd0aCA8PSBzb3VyY2VbOF0pIHx8XG4gICAgKHNyY0JpdG1hc2sgPT0gKEFSWV9GTEFHIHwgUkVBUkdfRkxBRykgJiYgYml0bWFzayA9PSBDVVJSWV9GTEFHKTtcblxuICAvLyBFeGl0IGVhcmx5IGlmIG1ldGFkYXRhIGNhbid0IGJlIG1lcmdlZC5cbiAgaWYgKCEoaXNDb21tb24gfHwgaXNDb21ibykpIHtcbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuICAvLyBVc2Ugc291cmNlIGB0aGlzQXJnYCBpZiBhdmFpbGFibGUuXG4gIGlmIChzcmNCaXRtYXNrICYgQklORF9GTEFHKSB7XG4gICAgZGF0YVsyXSA9IHNvdXJjZVsyXTtcbiAgICAvLyBTZXQgd2hlbiBjdXJyeWluZyBhIGJvdW5kIGZ1bmN0aW9uLlxuICAgIG5ld0JpdG1hc2sgfD0gKGJpdG1hc2sgJiBCSU5EX0ZMQUcpID8gMCA6IENVUlJZX0JPVU5EX0ZMQUc7XG4gIH1cbiAgLy8gQ29tcG9zZSBwYXJ0aWFsIGFyZ3VtZW50cy5cbiAgdmFyIHZhbHVlID0gc291cmNlWzNdO1xuICBpZiAodmFsdWUpIHtcbiAgICB2YXIgcGFydGlhbHMgPSBkYXRhWzNdO1xuICAgIGRhdGFbM10gPSBwYXJ0aWFscyA/IGNvbXBvc2VBcmdzKHBhcnRpYWxzLCB2YWx1ZSwgc291cmNlWzRdKSA6IGFycmF5Q29weSh2YWx1ZSk7XG4gICAgZGF0YVs0XSA9IHBhcnRpYWxzID8gcmVwbGFjZUhvbGRlcnMoZGF0YVszXSwgUExBQ0VIT0xERVIpIDogYXJyYXlDb3B5KHNvdXJjZVs0XSk7XG4gIH1cbiAgLy8gQ29tcG9zZSBwYXJ0aWFsIHJpZ2h0IGFyZ3VtZW50cy5cbiAgdmFsdWUgPSBzb3VyY2VbNV07XG4gIGlmICh2YWx1ZSkge1xuICAgIHBhcnRpYWxzID0gZGF0YVs1XTtcbiAgICBkYXRhWzVdID0gcGFydGlhbHMgPyBjb21wb3NlQXJnc1JpZ2h0KHBhcnRpYWxzLCB2YWx1ZSwgc291cmNlWzZdKSA6IGFycmF5Q29weSh2YWx1ZSk7XG4gICAgZGF0YVs2XSA9IHBhcnRpYWxzID8gcmVwbGFjZUhvbGRlcnMoZGF0YVs1XSwgUExBQ0VIT0xERVIpIDogYXJyYXlDb3B5KHNvdXJjZVs2XSk7XG4gIH1cbiAgLy8gVXNlIHNvdXJjZSBgYXJnUG9zYCBpZiBhdmFpbGFibGUuXG4gIHZhbHVlID0gc291cmNlWzddO1xuICBpZiAodmFsdWUpIHtcbiAgICBkYXRhWzddID0gYXJyYXlDb3B5KHZhbHVlKTtcbiAgfVxuICAvLyBVc2Ugc291cmNlIGBhcnlgIGlmIGl0J3Mgc21hbGxlci5cbiAgaWYgKHNyY0JpdG1hc2sgJiBBUllfRkxBRykge1xuICAgIGRhdGFbOF0gPSBkYXRhWzhdID09IG51bGwgPyBzb3VyY2VbOF0gOiBuYXRpdmVNaW4oZGF0YVs4XSwgc291cmNlWzhdKTtcbiAgfVxuICAvLyBVc2Ugc291cmNlIGBhcml0eWAgaWYgb25lIGlzIG5vdCBwcm92aWRlZC5cbiAgaWYgKGRhdGFbOV0gPT0gbnVsbCkge1xuICAgIGRhdGFbOV0gPSBzb3VyY2VbOV07XG4gIH1cbiAgLy8gVXNlIHNvdXJjZSBgZnVuY2AgYW5kIG1lcmdlIGJpdG1hc2tzLlxuICBkYXRhWzBdID0gc291cmNlWzBdO1xuICBkYXRhWzFdID0gbmV3Qml0bWFzaztcblxuICByZXR1cm4gZGF0YTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBtZXJnZURhdGE7XG4iLCIoZnVuY3Rpb24gKGdsb2JhbCl7XG52YXIgZ2V0TmF0aXZlID0gcmVxdWlyZSgnLi9nZXROYXRpdmUnKTtcblxuLyoqIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBXZWFrTWFwID0gZ2V0TmF0aXZlKGdsb2JhbCwgJ1dlYWtNYXAnKTtcblxuLyoqIFVzZWQgdG8gc3RvcmUgZnVuY3Rpb24gbWV0YWRhdGEuICovXG52YXIgbWV0YU1hcCA9IFdlYWtNYXAgJiYgbmV3IFdlYWtNYXA7XG5cbm1vZHVsZS5leHBvcnRzID0gbWV0YU1hcDtcblxufSkuY2FsbCh0aGlzLHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30pXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbTV2WkdWZmJXOWtkV3hsY3k5c2IyUmhjMmd0WTI5dGNHRjBMMmx1ZEdWeWJtRnNMMjFsZEdGTllYQXVhbk1pWFN3aWJtRnRaWE1pT2x0ZExDSnRZWEJ3YVc1bmN5STZJanRCUVVGQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQklpd2labWxzWlNJNkltZGxibVZ5WVhSbFpDNXFjeUlzSW5OdmRYSmpaVkp2YjNRaU9pSWlMQ0p6YjNWeVkyVnpRMjl1ZEdWdWRDSTZXeUoyWVhJZ1oyVjBUbUYwYVhabElEMGdjbVZ4ZFdseVpTZ25MaTluWlhST1lYUnBkbVVuS1R0Y2JseHVMeW9xSUU1aGRHbDJaU0J0WlhSb2IyUWdjbVZtWlhKbGJtTmxjeTRnS2k5Y2JuWmhjaUJYWldGclRXRndJRDBnWjJWMFRtRjBhWFpsS0dkc2IySmhiQ3dnSjFkbFlXdE5ZWEFuS1R0Y2JseHVMeW9xSUZWelpXUWdkRzhnYzNSdmNtVWdablZ1WTNScGIyNGdiV1YwWVdSaGRHRXVJQ292WEc1MllYSWdiV1YwWVUxaGNDQTlJRmRsWVd0TllYQWdKaVlnYm1WM0lGZGxZV3ROWVhBN1hHNWNibTF2WkhWc1pTNWxlSEJ2Y25SeklEMGdiV1YwWVUxaGNEdGNiaUpkZlE9PSIsIi8qKiBVc2VkIHRvIGxvb2t1cCB1bm1pbmlmaWVkIGZ1bmN0aW9uIG5hbWVzLiAqL1xudmFyIHJlYWxOYW1lcyA9IHt9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlYWxOYW1lcztcbiIsInZhciBhcnJheUNvcHkgPSByZXF1aXJlKCcuL2FycmF5Q29weScpLFxuICAgIGlzSW5kZXggPSByZXF1aXJlKCcuL2lzSW5kZXgnKTtcblxuLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNaW4gPSBNYXRoLm1pbjtcblxuLyoqXG4gKiBSZW9yZGVyIGBhcnJheWAgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpZWQgaW5kZXhlcyB3aGVyZSB0aGUgZWxlbWVudCBhdFxuICogdGhlIGZpcnN0IGluZGV4IGlzIGFzc2lnbmVkIGFzIHRoZSBmaXJzdCBlbGVtZW50LCB0aGUgZWxlbWVudCBhdFxuICogdGhlIHNlY29uZCBpbmRleCBpcyBhc3NpZ25lZCBhcyB0aGUgc2Vjb25kIGVsZW1lbnQsIGFuZCBzbyBvbi5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHJlb3JkZXIuXG4gKiBAcGFyYW0ge0FycmF5fSBpbmRleGVzIFRoZSBhcnJhbmdlZCBhcnJheSBpbmRleGVzLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIHJlb3JkZXIoYXJyYXksIGluZGV4ZXMpIHtcbiAgdmFyIGFyckxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIGxlbmd0aCA9IG5hdGl2ZU1pbihpbmRleGVzLmxlbmd0aCwgYXJyTGVuZ3RoKSxcbiAgICAgIG9sZEFycmF5ID0gYXJyYXlDb3B5KGFycmF5KTtcblxuICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICB2YXIgaW5kZXggPSBpbmRleGVzW2xlbmd0aF07XG4gICAgYXJyYXlbbGVuZ3RoXSA9IGlzSW5kZXgoaW5kZXgsIGFyckxlbmd0aCkgPyBvbGRBcnJheVtpbmRleF0gOiB1bmRlZmluZWQ7XG4gIH1cbiAgcmV0dXJuIGFycmF5O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlb3JkZXI7XG4iLCIvKiogVXNlZCBhcyB0aGUgaW50ZXJuYWwgYXJndW1lbnQgcGxhY2Vob2xkZXIuICovXG52YXIgUExBQ0VIT0xERVIgPSAnX19sb2Rhc2hfcGxhY2Vob2xkZXJfXyc7XG5cbi8qKlxuICogUmVwbGFjZXMgYWxsIGBwbGFjZWhvbGRlcmAgZWxlbWVudHMgaW4gYGFycmF5YCB3aXRoIGFuIGludGVybmFsIHBsYWNlaG9sZGVyXG4gKiBhbmQgcmV0dXJucyBhbiBhcnJheSBvZiB0aGVpciBpbmRleGVzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gbW9kaWZ5LlxuICogQHBhcmFtIHsqfSBwbGFjZWhvbGRlciBUaGUgcGxhY2Vob2xkZXIgdG8gcmVwbGFjZS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gKi9cbmZ1bmN0aW9uIHJlcGxhY2VIb2xkZXJzKGFycmF5LCBwbGFjZWhvbGRlcikge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIHJlc0luZGV4ID0gLTEsXG4gICAgICByZXN1bHQgPSBbXTtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGlmIChhcnJheVtpbmRleF0gPT09IHBsYWNlaG9sZGVyKSB7XG4gICAgICBhcnJheVtpbmRleF0gPSBQTEFDRUhPTERFUjtcbiAgICAgIHJlc3VsdFsrK3Jlc0luZGV4XSA9IGluZGV4O1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcGxhY2VIb2xkZXJzO1xuIiwidmFyIGJhc2VTZXREYXRhID0gcmVxdWlyZSgnLi9iYXNlU2V0RGF0YScpLFxuICAgIG5vdyA9IHJlcXVpcmUoJy4uL2RhdGUvbm93Jyk7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCB3aGVuIGEgZnVuY3Rpb24gYmVjb21lcyBob3QuICovXG52YXIgSE9UX0NPVU5UID0gMTUwLFxuICAgIEhPVF9TUEFOID0gMTY7XG5cbi8qKlxuICogU2V0cyBtZXRhZGF0YSBmb3IgYGZ1bmNgLlxuICpcbiAqICoqTm90ZToqKiBJZiB0aGlzIGZ1bmN0aW9uIGJlY29tZXMgaG90LCBpLmUuIGlzIGludm9rZWQgYSBsb3QgaW4gYSBzaG9ydFxuICogcGVyaW9kIG9mIHRpbWUsIGl0IHdpbGwgdHJpcCBpdHMgYnJlYWtlciBhbmQgdHJhbnNpdGlvbiB0byBhbiBpZGVudGl0eSBmdW5jdGlvblxuICogdG8gYXZvaWQgZ2FyYmFnZSBjb2xsZWN0aW9uIHBhdXNlcyBpbiBWOC4gU2VlIFtWOCBpc3N1ZSAyMDcwXShodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MjA3MClcbiAqIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFzc29jaWF0ZSBtZXRhZGF0YSB3aXRoLlxuICogQHBhcmFtIHsqfSBkYXRhIFRoZSBtZXRhZGF0YS5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBgZnVuY2AuXG4gKi9cbnZhciBzZXREYXRhID0gKGZ1bmN0aW9uKCkge1xuICB2YXIgY291bnQgPSAwLFxuICAgICAgbGFzdENhbGxlZCA9IDA7XG5cbiAgcmV0dXJuIGZ1bmN0aW9uKGtleSwgdmFsdWUpIHtcbiAgICB2YXIgc3RhbXAgPSBub3coKSxcbiAgICAgICAgcmVtYWluaW5nID0gSE9UX1NQQU4gLSAoc3RhbXAgLSBsYXN0Q2FsbGVkKTtcblxuICAgIGxhc3RDYWxsZWQgPSBzdGFtcDtcbiAgICBpZiAocmVtYWluaW5nID4gMCkge1xuICAgICAgaWYgKCsrY291bnQgPj0gSE9UX0NPVU5UKSB7XG4gICAgICAgIHJldHVybiBrZXk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvdW50ID0gMDtcbiAgICB9XG4gICAgcmV0dXJuIGJhc2VTZXREYXRhKGtleSwgdmFsdWUpO1xuICB9O1xufSgpKTtcblxubW9kdWxlLmV4cG9ydHMgPSBzZXREYXRhO1xuIiwidmFyIGlzQXJndW1lbnRzID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FyZ3VtZW50cycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICBpc0luZGV4ID0gcmVxdWlyZSgnLi9pc0luZGV4JyksXG4gICAgaXNMZW5ndGggPSByZXF1aXJlKCcuL2lzTGVuZ3RoJyksXG4gICAgaXNTdHJpbmcgPSByZXF1aXJlKCcuLi9sYW5nL2lzU3RyaW5nJyksXG4gICAga2V5c0luID0gcmVxdWlyZSgnLi4vb2JqZWN0L2tleXNJbicpO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBBIGZhbGxiYWNrIGltcGxlbWVudGF0aW9uIG9mIGBPYmplY3Qua2V5c2Agd2hpY2ggY3JlYXRlcyBhbiBhcnJheSBvZiB0aGVcbiAqIG93biBlbnVtZXJhYmxlIHByb3BlcnR5IG5hbWVzIG9mIGBvYmplY3RgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICovXG5mdW5jdGlvbiBzaGltS2V5cyhvYmplY3QpIHtcbiAgdmFyIHByb3BzID0ga2V5c0luKG9iamVjdCksXG4gICAgICBwcm9wc0xlbmd0aCA9IHByb3BzLmxlbmd0aCxcbiAgICAgIGxlbmd0aCA9IHByb3BzTGVuZ3RoICYmIG9iamVjdC5sZW5ndGg7XG5cbiAgdmFyIGFsbG93SW5kZXhlcyA9ICEhbGVuZ3RoICYmIGlzTGVuZ3RoKGxlbmd0aCkgJiZcbiAgICAoaXNBcnJheShvYmplY3QpIHx8IGlzQXJndW1lbnRzKG9iamVjdCkgfHwgaXNTdHJpbmcob2JqZWN0KSk7XG5cbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICByZXN1bHQgPSBbXTtcblxuICB3aGlsZSAoKytpbmRleCA8IHByb3BzTGVuZ3RoKSB7XG4gICAgdmFyIGtleSA9IHByb3BzW2luZGV4XTtcbiAgICBpZiAoKGFsbG93SW5kZXhlcyAmJiBpc0luZGV4KGtleSwgbGVuZ3RoKSkgfHwgaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkpIHtcbiAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc2hpbUtleXM7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0JyksXG4gICAgaXNTdHJpbmcgPSByZXF1aXJlKCcuLi9sYW5nL2lzU3RyaW5nJyksXG4gICAgc3VwcG9ydCA9IHJlcXVpcmUoJy4uL3N1cHBvcnQnKTtcblxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGFuIG9iamVjdCBpZiBpdCdzIG5vdCBvbmUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb2Nlc3MuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBvYmplY3QuXG4gKi9cbmZ1bmN0aW9uIHRvT2JqZWN0KHZhbHVlKSB7XG4gIGlmIChzdXBwb3J0LnVuaW5kZXhlZENoYXJzICYmIGlzU3RyaW5nKHZhbHVlKSkge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSB2YWx1ZS5sZW5ndGgsXG4gICAgICAgIHJlc3VsdCA9IE9iamVjdCh2YWx1ZSk7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgcmVzdWx0W2luZGV4XSA9IHZhbHVlLmNoYXJBdChpbmRleCk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgcmV0dXJuIGlzT2JqZWN0KHZhbHVlKSA/IHZhbHVlIDogT2JqZWN0KHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0b09iamVjdDtcbiIsInZhciBiYXNlVG9TdHJpbmcgPSByZXF1aXJlKCcuL2Jhc2VUb1N0cmluZycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKTtcblxuLyoqIFVzZWQgdG8gbWF0Y2ggcHJvcGVydHkgbmFtZXMgd2l0aGluIHByb3BlcnR5IHBhdGhzLiAqL1xudmFyIHJlUHJvcE5hbWUgPSAvW14uW1xcXV0rfFxcWyg/OigtP1xcZCsoPzpcXC5cXGQrKT8pfChbXCInXSkoKD86KD8hXFwyKVteXFxuXFxcXF18XFxcXC4pKj8pXFwyKVxcXS9nO1xuXG4vKiogVXNlZCB0byBtYXRjaCBiYWNrc2xhc2hlcyBpbiBwcm9wZXJ0eSBwYXRocy4gKi9cbnZhciByZUVzY2FwZUNoYXIgPSAvXFxcXChcXFxcKT8vZztcblxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIHByb3BlcnR5IHBhdGggYXJyYXkgaWYgaXQncyBub3Qgb25lLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm9jZXNzLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBwcm9wZXJ0eSBwYXRoIGFycmF5LlxuICovXG5mdW5jdGlvbiB0b1BhdGgodmFsdWUpIHtcbiAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgYmFzZVRvU3RyaW5nKHZhbHVlKS5yZXBsYWNlKHJlUHJvcE5hbWUsIGZ1bmN0aW9uKG1hdGNoLCBudW1iZXIsIHF1b3RlLCBzdHJpbmcpIHtcbiAgICByZXN1bHQucHVzaChxdW90ZSA/IHN0cmluZy5yZXBsYWNlKHJlRXNjYXBlQ2hhciwgJyQxJykgOiAobnVtYmVyIHx8IG1hdGNoKSk7XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHRvUGF0aDtcbiIsInZhciBMYXp5V3JhcHBlciA9IHJlcXVpcmUoJy4vTGF6eVdyYXBwZXInKSxcbiAgICBMb2Rhc2hXcmFwcGVyID0gcmVxdWlyZSgnLi9Mb2Rhc2hXcmFwcGVyJyksXG4gICAgYXJyYXlDb3B5ID0gcmVxdWlyZSgnLi9hcnJheUNvcHknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgY2xvbmUgb2YgYHdyYXBwZXJgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gd3JhcHBlciBUaGUgd3JhcHBlciB0byBjbG9uZS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNsb25lZCB3cmFwcGVyLlxuICovXG5mdW5jdGlvbiB3cmFwcGVyQ2xvbmUod3JhcHBlcikge1xuICByZXR1cm4gd3JhcHBlciBpbnN0YW5jZW9mIExhenlXcmFwcGVyXG4gICAgPyB3cmFwcGVyLmNsb25lKClcbiAgICA6IG5ldyBMb2Rhc2hXcmFwcGVyKHdyYXBwZXIuX193cmFwcGVkX18sIHdyYXBwZXIuX19jaGFpbl9fLCBhcnJheUNvcHkod3JhcHBlci5fX2FjdGlvbnNfXykpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHdyYXBwZXJDbG9uZTtcbiIsInZhciBiYXNlQ2xvbmUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlQ2xvbmUnKSxcbiAgICBiaW5kQ2FsbGJhY2sgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iaW5kQ2FsbGJhY2snKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZGVlcCBjbG9uZSBvZiBgdmFsdWVgLiBJZiBgY3VzdG9taXplcmAgaXMgcHJvdmlkZWQgaXQncyBpbnZva2VkXG4gKiB0byBwcm9kdWNlIHRoZSBjbG9uZWQgdmFsdWVzLiBJZiBgY3VzdG9taXplcmAgcmV0dXJucyBgdW5kZWZpbmVkYCBjbG9uaW5nXG4gKiBpcyBoYW5kbGVkIGJ5IHRoZSBtZXRob2QgaW5zdGVhZC4gVGhlIGBjdXN0b21pemVyYCBpcyBib3VuZCB0byBgdGhpc0FyZ2BcbiAqIGFuZCBpbnZva2VkIHdpdGggdXAgdG8gdGhyZWUgYXJndW1lbnQ7ICh2YWx1ZSBbLCBpbmRleHxrZXksIG9iamVjdF0pLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBsb29zZWx5IGJhc2VkIG9uIHRoZVxuICogW3N0cnVjdHVyZWQgY2xvbmUgYWxnb3JpdGhtXShodHRwOi8vd3d3LnczLm9yZy9UUi9odG1sNS9pbmZyYXN0cnVjdHVyZS5odG1sI2ludGVybmFsLXN0cnVjdHVyZWQtY2xvbmluZy1hbGdvcml0aG0pLlxuICogVGhlIGVudW1lcmFibGUgcHJvcGVydGllcyBvZiBgYXJndW1lbnRzYCBvYmplY3RzIGFuZCBvYmplY3RzIGNyZWF0ZWQgYnlcbiAqIGNvbnN0cnVjdG9ycyBvdGhlciB0aGFuIGBPYmplY3RgIGFyZSBjbG9uZWQgdG8gcGxhaW4gYE9iamVjdGAgb2JqZWN0cy4gQW5cbiAqIGVtcHR5IG9iamVjdCBpcyByZXR1cm5lZCBmb3IgdW5jbG9uZWFibGUgdmFsdWVzIHN1Y2ggYXMgZnVuY3Rpb25zLCBET00gbm9kZXMsXG4gKiBNYXBzLCBTZXRzLCBhbmQgV2Vha01hcHMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBkZWVwIGNsb25lLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY2xvbmluZyB2YWx1ZXMuXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGN1c3RvbWl6ZXJgLlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGRlZXAgY2xvbmVkIHZhbHVlLlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgdXNlcnMgPSBbXG4gKiAgIHsgJ3VzZXInOiAnYmFybmV5JyB9LFxuICogICB7ICd1c2VyJzogJ2ZyZWQnIH1cbiAqIF07XG4gKlxuICogdmFyIGRlZXAgPSBfLmNsb25lRGVlcCh1c2Vycyk7XG4gKiBkZWVwWzBdID09PSB1c2Vyc1swXTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogLy8gdXNpbmcgYSBjdXN0b21pemVyIGNhbGxiYWNrXG4gKiB2YXIgZWwgPSBfLmNsb25lRGVlcChkb2N1bWVudC5ib2R5LCBmdW5jdGlvbih2YWx1ZSkge1xuICogICBpZiAoXy5pc0VsZW1lbnQodmFsdWUpKSB7XG4gKiAgICAgcmV0dXJuIHZhbHVlLmNsb25lTm9kZSh0cnVlKTtcbiAqICAgfVxuICogfSk7XG4gKlxuICogZWwgPT09IGRvY3VtZW50LmJvZHlcbiAqIC8vID0+IGZhbHNlXG4gKiBlbC5ub2RlTmFtZVxuICogLy8gPT4gQk9EWVxuICogZWwuY2hpbGROb2Rlcy5sZW5ndGg7XG4gKiAvLyA9PiAyMFxuICovXG5mdW5jdGlvbiBjbG9uZURlZXAodmFsdWUsIGN1c3RvbWl6ZXIsIHRoaXNBcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBjdXN0b21pemVyID09ICdmdW5jdGlvbidcbiAgICA/IGJhc2VDbG9uZSh2YWx1ZSwgdHJ1ZSwgYmluZENhbGxiYWNrKGN1c3RvbWl6ZXIsIHRoaXNBcmcsIDMpKVxuICAgIDogYmFzZUNsb25lKHZhbHVlLCB0cnVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjbG9uZURlZXA7XG4iLCJ2YXIgaXNBcnJheUxpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0FycmF5TGlrZScpLFxuICAgIGlzT2JqZWN0TGlrZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzT2JqZWN0TGlrZScpO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBwcm9wZXJ0eUlzRW51bWVyYWJsZSA9IG9iamVjdFByb3RvLnByb3BlcnR5SXNFbnVtZXJhYmxlO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYW4gYGFyZ3VtZW50c2Agb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzQXJndW1lbnRzKGZ1bmN0aW9uKCkgeyByZXR1cm4gYXJndW1lbnRzOyB9KCkpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNBcmd1bWVudHMoWzEsIDIsIDNdKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzQXJndW1lbnRzKHZhbHVlKSB7XG4gIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGlzQXJyYXlMaWtlKHZhbHVlKSAmJlxuICAgIGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsICdjYWxsZWUnKSAmJiAhcHJvcGVydHlJc0VudW1lcmFibGUuY2FsbCh2YWx1ZSwgJ2NhbGxlZScpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzQXJndW1lbnRzO1xuIiwidmFyIGdldE5hdGl2ZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2dldE5hdGl2ZScpLFxuICAgIGlzTGVuZ3RoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNMZW5ndGgnKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc09iamVjdExpa2UnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJztcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlSXNBcnJheSA9IGdldE5hdGl2ZShBcnJheSwgJ2lzQXJyYXknKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGFuIGBBcnJheWAgb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzQXJyYXkoWzEsIDIsIDNdKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzQXJyYXkoZnVuY3Rpb24oKSB7IHJldHVybiBhcmd1bWVudHM7IH0oKSk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG52YXIgaXNBcnJheSA9IG5hdGl2ZUlzQXJyYXkgfHwgZnVuY3Rpb24odmFsdWUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaXNMZW5ndGgodmFsdWUubGVuZ3RoKSAmJiBvYmpUb1N0cmluZy5jYWxsKHZhbHVlKSA9PSBhcnJheVRhZztcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gaXNBcnJheTtcbiIsInZhciBpc0FyZ3VtZW50cyA9IHJlcXVpcmUoJy4vaXNBcmd1bWVudHMnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi9pc0FycmF5JyksXG4gICAgaXNBcnJheUxpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0FycmF5TGlrZScpLFxuICAgIGlzRnVuY3Rpb24gPSByZXF1aXJlKCcuL2lzRnVuY3Rpb24nKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc09iamVjdExpa2UnKSxcbiAgICBpc1N0cmluZyA9IHJlcXVpcmUoJy4vaXNTdHJpbmcnKSxcbiAgICBrZXlzID0gcmVxdWlyZSgnLi4vb2JqZWN0L2tleXMnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBlbXB0eS4gQSB2YWx1ZSBpcyBjb25zaWRlcmVkIGVtcHR5IHVubGVzcyBpdCdzIGFuXG4gKiBgYXJndW1lbnRzYCBvYmplY3QsIGFycmF5LCBzdHJpbmcsIG9yIGpRdWVyeS1saWtlIGNvbGxlY3Rpb24gd2l0aCBhIGxlbmd0aFxuICogZ3JlYXRlciB0aGFuIGAwYCBvciBhbiBvYmplY3Qgd2l0aCBvd24gZW51bWVyYWJsZSBwcm9wZXJ0aWVzLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSB2YWx1ZSBUaGUgdmFsdWUgdG8gaW5zcGVjdC5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGVtcHR5LCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNFbXB0eShudWxsKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzRW1wdHkodHJ1ZSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0VtcHR5KDEpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNFbXB0eShbMSwgMiwgM10pO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzRW1wdHkoeyAnYSc6IDEgfSk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0VtcHR5KHZhbHVlKSB7XG4gIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKGlzQXJyYXlMaWtlKHZhbHVlKSAmJiAoaXNBcnJheSh2YWx1ZSkgfHwgaXNTdHJpbmcodmFsdWUpIHx8IGlzQXJndW1lbnRzKHZhbHVlKSB8fFxuICAgICAgKGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaXNGdW5jdGlvbih2YWx1ZS5zcGxpY2UpKSkpIHtcbiAgICByZXR1cm4gIXZhbHVlLmxlbmd0aDtcbiAgfVxuICByZXR1cm4gIWtleXModmFsdWUpLmxlbmd0aDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0VtcHR5O1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9pc09iamVjdCcpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgZnVuY1RhZyA9ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgW2B0b1N0cmluZ1RhZ2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW9iamVjdC5wcm90b3R5cGUudG9zdHJpbmcpXG4gKiBvZiB2YWx1ZXMuXG4gKi9cbnZhciBvYmpUb1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgRnVuY3Rpb25gIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgY29ycmVjdGx5IGNsYXNzaWZpZWQsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc0Z1bmN0aW9uKF8pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNGdW5jdGlvbigvYWJjLyk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKHZhbHVlKSB7XG4gIC8vIFRoZSB1c2Ugb2YgYE9iamVjdCN0b1N0cmluZ2AgYXZvaWRzIGlzc3VlcyB3aXRoIHRoZSBgdHlwZW9mYCBvcGVyYXRvclxuICAvLyBpbiBvbGRlciB2ZXJzaW9ucyBvZiBDaHJvbWUgYW5kIFNhZmFyaSB3aGljaCByZXR1cm4gJ2Z1bmN0aW9uJyBmb3IgcmVnZXhlc1xuICAvLyBhbmQgU2FmYXJpIDggd2hpY2ggcmV0dXJucyAnb2JqZWN0JyBmb3IgdHlwZWQgYXJyYXkgY29uc3RydWN0b3JzLlxuICByZXR1cm4gaXNPYmplY3QodmFsdWUpICYmIG9ialRvU3RyaW5nLmNhbGwodmFsdWUpID09IGZ1bmNUYWc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNGdW5jdGlvbjtcbiIsInZhciBpc0Z1bmN0aW9uID0gcmVxdWlyZSgnLi9pc0Z1bmN0aW9uJyksXG4gICAgaXNIb3N0T2JqZWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNIb3N0T2JqZWN0JyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNPYmplY3RMaWtlJyk7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBob3N0IGNvbnN0cnVjdG9ycyAoU2FmYXJpID4gNSkuICovXG52YXIgcmVJc0hvc3RDdG9yID0gL15cXFtvYmplY3QgLis/Q29uc3RydWN0b3JcXF0kLztcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIHJlc29sdmUgdGhlIGRlY29tcGlsZWQgc291cmNlIG9mIGZ1bmN0aW9ucy4gKi9cbnZhciBmblRvU3RyaW5nID0gRnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKiogVXNlZCB0byBkZXRlY3QgaWYgYSBtZXRob2QgaXMgbmF0aXZlLiAqL1xudmFyIHJlSXNOYXRpdmUgPSBSZWdFeHAoJ14nICtcbiAgZm5Ub1N0cmluZy5jYWxsKGhhc093blByb3BlcnR5KS5yZXBsYWNlKC9bXFxcXF4kLiorPygpW1xcXXt9fF0vZywgJ1xcXFwkJicpXG4gIC5yZXBsYWNlKC9oYXNPd25Qcm9wZXJ0eXwoZnVuY3Rpb24pLio/KD89XFxcXFxcKCl8IGZvciAuKz8oPz1cXFxcXFxdKS9nLCAnJDEuKj8nKSArICckJ1xuKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIG5hdGl2ZSBmdW5jdGlvbi5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBuYXRpdmUgZnVuY3Rpb24sIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc05hdGl2ZShBcnJheS5wcm90b3R5cGUucHVzaCk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc05hdGl2ZShfKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzTmF0aXZlKHZhbHVlKSB7XG4gIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgIHJldHVybiByZUlzTmF0aXZlLnRlc3QoZm5Ub1N0cmluZy5jYWxsKHZhbHVlKSk7XG4gIH1cbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgKGlzSG9zdE9iamVjdCh2YWx1ZSkgPyByZUlzTmF0aXZlIDogcmVJc0hvc3RDdG9yKS50ZXN0KHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc05hdGl2ZTtcbiIsIi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgdGhlIFtsYW5ndWFnZSB0eXBlXShodHRwczovL2VzNS5naXRodWIuaW8vI3g4KSBvZiBgT2JqZWN0YC5cbiAqIChlLmcuIGFycmF5cywgZnVuY3Rpb25zLCBvYmplY3RzLCByZWdleGVzLCBgbmV3IE51bWJlcigwKWAsIGFuZCBgbmV3IFN0cmluZygnJylgKVxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc09iamVjdCh7fSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdChbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3QoMSk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc09iamVjdCh2YWx1ZSkge1xuICAvLyBBdm9pZCBhIFY4IEpJVCBidWcgaW4gQ2hyb21lIDE5LTIwLlxuICAvLyBTZWUgaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC92OC9pc3N1ZXMvZGV0YWlsP2lkPTIyOTEgZm9yIG1vcmUgZGV0YWlscy5cbiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gIHJldHVybiAhIXZhbHVlICYmICh0eXBlID09ICdvYmplY3QnIHx8IHR5cGUgPT0gJ2Z1bmN0aW9uJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNPYmplY3Q7XG4iLCJ2YXIgYmFzZUZvckluID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZUZvckluJyksXG4gICAgaXNBcmd1bWVudHMgPSByZXF1aXJlKCcuL2lzQXJndW1lbnRzJyksXG4gICAgaXNIb3N0T2JqZWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNIb3N0T2JqZWN0JyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNPYmplY3RMaWtlJyksXG4gICAgc3VwcG9ydCA9IHJlcXVpcmUoJy4uL3N1cHBvcnQnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHBsYWluIG9iamVjdCwgdGhhdCBpcywgYW4gb2JqZWN0IGNyZWF0ZWQgYnkgdGhlXG4gKiBgT2JqZWN0YCBjb25zdHJ1Y3RvciBvciBvbmUgd2l0aCBhIGBbW1Byb3RvdHlwZV1dYCBvZiBgbnVsbGAuXG4gKlxuICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGFzc3VtZXMgb2JqZWN0cyBjcmVhdGVkIGJ5IHRoZSBgT2JqZWN0YCBjb25zdHJ1Y3RvclxuICogaGF2ZSBubyBpbmhlcml0ZWQgZW51bWVyYWJsZSBwcm9wZXJ0aWVzLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHBsYWluIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBmdW5jdGlvbiBGb28oKSB7XG4gKiAgIHRoaXMuYSA9IDE7XG4gKiB9XG4gKlxuICogXy5pc1BsYWluT2JqZWN0KG5ldyBGb28pO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzUGxhaW5PYmplY3QoWzEsIDIsIDNdKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc1BsYWluT2JqZWN0KHsgJ3gnOiAwLCAneSc6IDAgfSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1BsYWluT2JqZWN0KE9iamVjdC5jcmVhdGUobnVsbCkpO1xuICogLy8gPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBpc1BsYWluT2JqZWN0KHZhbHVlKSB7XG4gIHZhciBDdG9yO1xuXG4gIC8vIEV4aXQgZWFybHkgZm9yIG5vbiBgT2JqZWN0YCBvYmplY3RzLlxuICBpZiAoIShpc09iamVjdExpa2UodmFsdWUpICYmIG9ialRvU3RyaW5nLmNhbGwodmFsdWUpID09IG9iamVjdFRhZyAmJiAhaXNIb3N0T2JqZWN0KHZhbHVlKSAmJiAhaXNBcmd1bWVudHModmFsdWUpKSB8fFxuICAgICAgKCFoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCAnY29uc3RydWN0b3InKSAmJiAoQ3RvciA9IHZhbHVlLmNvbnN0cnVjdG9yLCB0eXBlb2YgQ3RvciA9PSAnZnVuY3Rpb24nICYmICEoQ3RvciBpbnN0YW5jZW9mIEN0b3IpKSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy8gSUUgPCA5IGl0ZXJhdGVzIGluaGVyaXRlZCBwcm9wZXJ0aWVzIGJlZm9yZSBvd24gcHJvcGVydGllcy4gSWYgdGhlIGZpcnN0XG4gIC8vIGl0ZXJhdGVkIHByb3BlcnR5IGlzIGFuIG9iamVjdCdzIG93biBwcm9wZXJ0eSB0aGVuIHRoZXJlIGFyZSBubyBpbmhlcml0ZWRcbiAgLy8gZW51bWVyYWJsZSBwcm9wZXJ0aWVzLlxuICB2YXIgcmVzdWx0O1xuICBpZiAoc3VwcG9ydC5vd25MYXN0KSB7XG4gICAgYmFzZUZvckluKHZhbHVlLCBmdW5jdGlvbihzdWJWYWx1ZSwga2V5LCBvYmplY3QpIHtcbiAgICAgIHJlc3VsdCA9IGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQgIT09IGZhbHNlO1xuICB9XG4gIC8vIEluIG1vc3QgZW52aXJvbm1lbnRzIGFuIG9iamVjdCdzIG93biBwcm9wZXJ0aWVzIGFyZSBpdGVyYXRlZCBiZWZvcmVcbiAgLy8gaXRzIGluaGVyaXRlZCBwcm9wZXJ0aWVzLiBJZiB0aGUgbGFzdCBpdGVyYXRlZCBwcm9wZXJ0eSBpcyBhbiBvYmplY3Qnc1xuICAvLyBvd24gcHJvcGVydHkgdGhlbiB0aGVyZSBhcmUgbm8gaW5oZXJpdGVkIGVudW1lcmFibGUgcHJvcGVydGllcy5cbiAgYmFzZUZvckluKHZhbHVlLCBmdW5jdGlvbihzdWJWYWx1ZSwga2V5KSB7XG4gICAgcmVzdWx0ID0ga2V5O1xuICB9KTtcbiAgcmV0dXJuIHJlc3VsdCA9PT0gdW5kZWZpbmVkIHx8IGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsIHJlc3VsdCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNQbGFpbk9iamVjdDtcbiIsInZhciBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc09iamVjdExpa2UnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFN0cmluZ2AgcHJpbWl0aXZlIG9yIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgY29ycmVjdGx5IGNsYXNzaWZpZWQsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc1N0cmluZygnYWJjJyk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1N0cmluZygxKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzU3RyaW5nKHZhbHVlKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycgfHwgKGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgb2JqVG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT0gc3RyaW5nVGFnKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1N0cmluZztcbiIsInZhciBpc0xlbmd0aCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzTGVuZ3RoJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNPYmplY3RMaWtlJyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBhcmdzVGFnID0gJ1tvYmplY3QgQXJndW1lbnRzXScsXG4gICAgYXJyYXlUYWcgPSAnW29iamVjdCBBcnJheV0nLFxuICAgIGJvb2xUYWcgPSAnW29iamVjdCBCb29sZWFuXScsXG4gICAgZGF0ZVRhZyA9ICdbb2JqZWN0IERhdGVdJyxcbiAgICBlcnJvclRhZyA9ICdbb2JqZWN0IEVycm9yXScsXG4gICAgZnVuY1RhZyA9ICdbb2JqZWN0IEZ1bmN0aW9uXScsXG4gICAgbWFwVGFnID0gJ1tvYmplY3QgTWFwXScsXG4gICAgbnVtYmVyVGFnID0gJ1tvYmplY3QgTnVtYmVyXScsXG4gICAgb2JqZWN0VGFnID0gJ1tvYmplY3QgT2JqZWN0XScsXG4gICAgcmVnZXhwVGFnID0gJ1tvYmplY3QgUmVnRXhwXScsXG4gICAgc2V0VGFnID0gJ1tvYmplY3QgU2V0XScsXG4gICAgc3RyaW5nVGFnID0gJ1tvYmplY3QgU3RyaW5nXScsXG4gICAgd2Vha01hcFRhZyA9ICdbb2JqZWN0IFdlYWtNYXBdJztcblxudmFyIGFycmF5QnVmZmVyVGFnID0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJyxcbiAgICBmbG9hdDMyVGFnID0gJ1tvYmplY3QgRmxvYXQzMkFycmF5XScsXG4gICAgZmxvYXQ2NFRhZyA9ICdbb2JqZWN0IEZsb2F0NjRBcnJheV0nLFxuICAgIGludDhUYWcgPSAnW29iamVjdCBJbnQ4QXJyYXldJyxcbiAgICBpbnQxNlRhZyA9ICdbb2JqZWN0IEludDE2QXJyYXldJyxcbiAgICBpbnQzMlRhZyA9ICdbb2JqZWN0IEludDMyQXJyYXldJyxcbiAgICB1aW50OFRhZyA9ICdbb2JqZWN0IFVpbnQ4QXJyYXldJyxcbiAgICB1aW50OENsYW1wZWRUYWcgPSAnW29iamVjdCBVaW50OENsYW1wZWRBcnJheV0nLFxuICAgIHVpbnQxNlRhZyA9ICdbb2JqZWN0IFVpbnQxNkFycmF5XScsXG4gICAgdWludDMyVGFnID0gJ1tvYmplY3QgVWludDMyQXJyYXldJztcblxuLyoqIFVzZWQgdG8gaWRlbnRpZnkgYHRvU3RyaW5nVGFnYCB2YWx1ZXMgb2YgdHlwZWQgYXJyYXlzLiAqL1xudmFyIHR5cGVkQXJyYXlUYWdzID0ge307XG50eXBlZEFycmF5VGFnc1tmbG9hdDMyVGFnXSA9IHR5cGVkQXJyYXlUYWdzW2Zsb2F0NjRUYWddID1cbnR5cGVkQXJyYXlUYWdzW2ludDhUYWddID0gdHlwZWRBcnJheVRhZ3NbaW50MTZUYWddID1cbnR5cGVkQXJyYXlUYWdzW2ludDMyVGFnXSA9IHR5cGVkQXJyYXlUYWdzW3VpbnQ4VGFnXSA9XG50eXBlZEFycmF5VGFnc1t1aW50OENsYW1wZWRUYWddID0gdHlwZWRBcnJheVRhZ3NbdWludDE2VGFnXSA9XG50eXBlZEFycmF5VGFnc1t1aW50MzJUYWddID0gdHJ1ZTtcbnR5cGVkQXJyYXlUYWdzW2FyZ3NUYWddID0gdHlwZWRBcnJheVRhZ3NbYXJyYXlUYWddID1cbnR5cGVkQXJyYXlUYWdzW2FycmF5QnVmZmVyVGFnXSA9IHR5cGVkQXJyYXlUYWdzW2Jvb2xUYWddID1cbnR5cGVkQXJyYXlUYWdzW2RhdGVUYWddID0gdHlwZWRBcnJheVRhZ3NbZXJyb3JUYWddID1cbnR5cGVkQXJyYXlUYWdzW2Z1bmNUYWddID0gdHlwZWRBcnJheVRhZ3NbbWFwVGFnXSA9XG50eXBlZEFycmF5VGFnc1tudW1iZXJUYWddID0gdHlwZWRBcnJheVRhZ3Nbb2JqZWN0VGFnXSA9XG50eXBlZEFycmF5VGFnc1tyZWdleHBUYWddID0gdHlwZWRBcnJheVRhZ3Nbc2V0VGFnXSA9XG50eXBlZEFycmF5VGFnc1tzdHJpbmdUYWddID0gdHlwZWRBcnJheVRhZ3Nbd2Vha01hcFRhZ10gPSBmYWxzZTtcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIHR5cGVkIGFycmF5LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzVHlwZWRBcnJheShuZXcgVWludDhBcnJheSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1R5cGVkQXJyYXkoW10pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNUeXBlZEFycmF5KHZhbHVlKSB7XG4gIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGlzTGVuZ3RoKHZhbHVlLmxlbmd0aCkgJiYgISF0eXBlZEFycmF5VGFnc1tvYmpUb1N0cmluZy5jYWxsKHZhbHVlKV07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNUeXBlZEFycmF5O1xuIiwiLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBgdW5kZWZpbmVkYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYHVuZGVmaW5lZGAsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc1VuZGVmaW5lZCh2b2lkIDApO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNVbmRlZmluZWQobnVsbCk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc1VuZGVmaW5lZCh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1VuZGVmaW5lZDtcbiIsInZhciBnZXROYXRpdmUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9nZXROYXRpdmUnKSxcbiAgICBpc0FycmF5TGlrZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzQXJyYXlMaWtlJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0JyksXG4gICAgc2hpbUtleXMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9zaGltS2V5cycpLFxuICAgIHN1cHBvcnQgPSByZXF1aXJlKCcuLi9zdXBwb3J0Jyk7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlS2V5cyA9IGdldE5hdGl2ZShPYmplY3QsICdrZXlzJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgYG9iamVjdGAuXG4gKlxuICogKipOb3RlOioqIE5vbi1vYmplY3QgdmFsdWVzIGFyZSBjb2VyY2VkIHRvIG9iamVjdHMuIFNlZSB0aGVcbiAqIFtFUyBzcGVjXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3Qua2V5cylcbiAqIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBPYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gKiBAZXhhbXBsZVxuICpcbiAqIGZ1bmN0aW9uIEZvbygpIHtcbiAqICAgdGhpcy5hID0gMTtcbiAqICAgdGhpcy5iID0gMjtcbiAqIH1cbiAqXG4gKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICpcbiAqIF8ua2V5cyhuZXcgRm9vKTtcbiAqIC8vID0+IFsnYScsICdiJ10gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAqXG4gKiBfLmtleXMoJ2hpJyk7XG4gKiAvLyA9PiBbJzAnLCAnMSddXG4gKi9cbnZhciBrZXlzID0gIW5hdGl2ZUtleXMgPyBzaGltS2V5cyA6IGZ1bmN0aW9uKG9iamVjdCkge1xuICB2YXIgQ3RvciA9IG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogb2JqZWN0LmNvbnN0cnVjdG9yO1xuICBpZiAoKHR5cGVvZiBDdG9yID09ICdmdW5jdGlvbicgJiYgQ3Rvci5wcm90b3R5cGUgPT09IG9iamVjdCkgfHxcbiAgICAgICh0eXBlb2Ygb2JqZWN0ID09ICdmdW5jdGlvbicgPyBzdXBwb3J0LmVudW1Qcm90b3R5cGVzIDogaXNBcnJheUxpa2Uob2JqZWN0KSkpIHtcbiAgICByZXR1cm4gc2hpbUtleXMob2JqZWN0KTtcbiAgfVxuICByZXR1cm4gaXNPYmplY3Qob2JqZWN0KSA/IG5hdGl2ZUtleXMob2JqZWN0KSA6IFtdO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBrZXlzO1xuIiwidmFyIGFycmF5RWFjaCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2FycmF5RWFjaCcpLFxuICAgIGlzQXJndW1lbnRzID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FyZ3VtZW50cycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICBpc0Z1bmN0aW9uID0gcmVxdWlyZSgnLi4vbGFuZy9pc0Z1bmN0aW9uJyksXG4gICAgaXNJbmRleCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzSW5kZXgnKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzTGVuZ3RoJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0JyksXG4gICAgaXNTdHJpbmcgPSByZXF1aXJlKCcuLi9sYW5nL2lzU3RyaW5nJyksXG4gICAgc3VwcG9ydCA9IHJlcXVpcmUoJy4uL3N1cHBvcnQnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJyxcbiAgICBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgZXJyb3JUYWcgPSAnW29iamVjdCBFcnJvcl0nLFxuICAgIGZ1bmNUYWcgPSAnW29iamVjdCBGdW5jdGlvbl0nLFxuICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nLFxuICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLFxuICAgIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nO1xuXG4vKiogVXNlZCB0byBmaXggdGhlIEpTY3JpcHQgYFtbRG9udEVudW1dXWAgYnVnLiAqL1xudmFyIHNoYWRvd1Byb3BzID0gW1xuICAnY29uc3RydWN0b3InLCAnaGFzT3duUHJvcGVydHknLCAnaXNQcm90b3R5cGVPZicsICdwcm9wZXJ0eUlzRW51bWVyYWJsZScsXG4gICd0b0xvY2FsZVN0cmluZycsICd0b1N0cmluZycsICd2YWx1ZU9mJ1xuXTtcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBlcnJvclByb3RvID0gRXJyb3IucHJvdG90eXBlLFxuICAgIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZSxcbiAgICBzdHJpbmdQcm90byA9IFN0cmluZy5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKiBVc2VkIHRvIGF2b2lkIGl0ZXJhdGluZyBvdmVyIG5vbi1lbnVtZXJhYmxlIHByb3BlcnRpZXMgaW4gSUUgPCA5LiAqL1xudmFyIG5vbkVudW1Qcm9wcyA9IHt9O1xubm9uRW51bVByb3BzW2FycmF5VGFnXSA9IG5vbkVudW1Qcm9wc1tkYXRlVGFnXSA9IG5vbkVudW1Qcm9wc1tudW1iZXJUYWddID0geyAnY29uc3RydWN0b3InOiB0cnVlLCAndG9Mb2NhbGVTdHJpbmcnOiB0cnVlLCAndG9TdHJpbmcnOiB0cnVlLCAndmFsdWVPZic6IHRydWUgfTtcbm5vbkVudW1Qcm9wc1tib29sVGFnXSA9IG5vbkVudW1Qcm9wc1tzdHJpbmdUYWddID0geyAnY29uc3RydWN0b3InOiB0cnVlLCAndG9TdHJpbmcnOiB0cnVlLCAndmFsdWVPZic6IHRydWUgfTtcbm5vbkVudW1Qcm9wc1tlcnJvclRhZ10gPSBub25FbnVtUHJvcHNbZnVuY1RhZ10gPSBub25FbnVtUHJvcHNbcmVnZXhwVGFnXSA9IHsgJ2NvbnN0cnVjdG9yJzogdHJ1ZSwgJ3RvU3RyaW5nJzogdHJ1ZSB9O1xubm9uRW51bVByb3BzW29iamVjdFRhZ10gPSB7ICdjb25zdHJ1Y3Rvcic6IHRydWUgfTtcblxuYXJyYXlFYWNoKHNoYWRvd1Byb3BzLCBmdW5jdGlvbihrZXkpIHtcbiAgZm9yICh2YXIgdGFnIGluIG5vbkVudW1Qcm9wcykge1xuICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKG5vbkVudW1Qcm9wcywgdGFnKSkge1xuICAgICAgdmFyIHByb3BzID0gbm9uRW51bVByb3BzW3RhZ107XG4gICAgICBwcm9wc1trZXldID0gaGFzT3duUHJvcGVydHkuY2FsbChwcm9wcywga2V5KTtcbiAgICB9XG4gIH1cbn0pO1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgYG9iamVjdGAuXG4gKlxuICogKipOb3RlOioqIE5vbi1vYmplY3QgdmFsdWVzIGFyZSBjb2VyY2VkIHRvIG9iamVjdHMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBPYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gKiBAZXhhbXBsZVxuICpcbiAqIGZ1bmN0aW9uIEZvbygpIHtcbiAqICAgdGhpcy5hID0gMTtcbiAqICAgdGhpcy5iID0gMjtcbiAqIH1cbiAqXG4gKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICpcbiAqIF8ua2V5c0luKG5ldyBGb28pO1xuICogLy8gPT4gWydhJywgJ2InLCAnYyddIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gKi9cbmZ1bmN0aW9uIGtleXNJbihvYmplY3QpIHtcbiAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG4gIGlmICghaXNPYmplY3Qob2JqZWN0KSkge1xuICAgIG9iamVjdCA9IE9iamVjdChvYmplY3QpO1xuICB9XG4gIHZhciBsZW5ndGggPSBvYmplY3QubGVuZ3RoO1xuXG4gIGxlbmd0aCA9IChsZW5ndGggJiYgaXNMZW5ndGgobGVuZ3RoKSAmJlxuICAgIChpc0FycmF5KG9iamVjdCkgfHwgaXNBcmd1bWVudHMob2JqZWN0KSB8fCBpc1N0cmluZyhvYmplY3QpKSAmJiBsZW5ndGgpIHx8IDA7XG5cbiAgdmFyIEN0b3IgPSBvYmplY3QuY29uc3RydWN0b3IsXG4gICAgICBpbmRleCA9IC0xLFxuICAgICAgcHJvdG8gPSAoaXNGdW5jdGlvbihDdG9yKSAmJiBDdG9yLnByb3RvdHlwZSkgfHwgb2JqZWN0UHJvdG8sXG4gICAgICBpc1Byb3RvID0gcHJvdG8gPT09IG9iamVjdCxcbiAgICAgIHJlc3VsdCA9IEFycmF5KGxlbmd0aCksXG4gICAgICBza2lwSW5kZXhlcyA9IGxlbmd0aCA+IDAsXG4gICAgICBza2lwRXJyb3JQcm9wcyA9IHN1cHBvcnQuZW51bUVycm9yUHJvcHMgJiYgKG9iamVjdCA9PT0gZXJyb3JQcm90byB8fCBvYmplY3QgaW5zdGFuY2VvZiBFcnJvciksXG4gICAgICBza2lwUHJvdG8gPSBzdXBwb3J0LmVudW1Qcm90b3R5cGVzICYmIGlzRnVuY3Rpb24ob2JqZWN0KTtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHJlc3VsdFtpbmRleF0gPSAoaW5kZXggKyAnJyk7XG4gIH1cbiAgLy8gbG9kYXNoIHNraXBzIHRoZSBgY29uc3RydWN0b3JgIHByb3BlcnR5IHdoZW4gaXQgaW5mZXJzIGl0J3MgaXRlcmF0aW5nXG4gIC8vIG92ZXIgYSBgcHJvdG90eXBlYCBvYmplY3QgYmVjYXVzZSBJRSA8IDkgY2FuJ3Qgc2V0IHRoZSBgW1tFbnVtZXJhYmxlXV1gXG4gIC8vIGF0dHJpYnV0ZSBvZiBhbiBleGlzdGluZyBwcm9wZXJ0eSBhbmQgdGhlIGBjb25zdHJ1Y3RvcmAgcHJvcGVydHkgb2YgYVxuICAvLyBwcm90b3R5cGUgZGVmYXVsdHMgdG8gbm9uLWVudW1lcmFibGUuXG4gIGZvciAodmFyIGtleSBpbiBvYmplY3QpIHtcbiAgICBpZiAoIShza2lwUHJvdG8gJiYga2V5ID09ICdwcm90b3R5cGUnKSAmJlxuICAgICAgICAhKHNraXBFcnJvclByb3BzICYmIChrZXkgPT0gJ21lc3NhZ2UnIHx8IGtleSA9PSAnbmFtZScpKSAmJlxuICAgICAgICAhKHNraXBJbmRleGVzICYmIGlzSW5kZXgoa2V5LCBsZW5ndGgpKSAmJlxuICAgICAgICAhKGtleSA9PSAnY29uc3RydWN0b3InICYmIChpc1Byb3RvIHx8ICFoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSkpKSB7XG4gICAgICByZXN1bHQucHVzaChrZXkpO1xuICAgIH1cbiAgfVxuICBpZiAoc3VwcG9ydC5ub25FbnVtU2hhZG93cyAmJiBvYmplY3QgIT09IG9iamVjdFByb3RvKSB7XG4gICAgdmFyIHRhZyA9IG9iamVjdCA9PT0gc3RyaW5nUHJvdG8gPyBzdHJpbmdUYWcgOiAob2JqZWN0ID09PSBlcnJvclByb3RvID8gZXJyb3JUYWcgOiBvYmpUb1N0cmluZy5jYWxsKG9iamVjdCkpLFxuICAgICAgICBub25FbnVtcyA9IG5vbkVudW1Qcm9wc1t0YWddIHx8IG5vbkVudW1Qcm9wc1tvYmplY3RUYWddO1xuXG4gICAgaWYgKHRhZyA9PSBvYmplY3RUYWcpIHtcbiAgICAgIHByb3RvID0gb2JqZWN0UHJvdG87XG4gICAgfVxuICAgIGxlbmd0aCA9IHNoYWRvd1Byb3BzLmxlbmd0aDtcbiAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgIGtleSA9IHNoYWRvd1Byb3BzW2xlbmd0aF07XG4gICAgICB2YXIgbm9uRW51bSA9IG5vbkVudW1zW2tleV07XG4gICAgICBpZiAoIShpc1Byb3RvICYmIG5vbkVudW0pICYmXG4gICAgICAgICAgKG5vbkVudW0gPyBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSA6IG9iamVjdFtrZXldICE9PSBwcm90b1trZXldKSkge1xuICAgICAgICByZXN1bHQucHVzaChrZXkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGtleXNJbjtcbiIsInZhciBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyksXG4gICAgdG9PYmplY3QgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC90b09iamVjdCcpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSB0d28gZGltZW5zaW9uYWwgYXJyYXkgb2YgdGhlIGtleS12YWx1ZSBwYWlycyBmb3IgYG9iamVjdGAsXG4gKiBlLmcuIGBbW2tleTEsIHZhbHVlMV0sIFtrZXkyLCB2YWx1ZTJdXWAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBPYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGtleS12YWx1ZSBwYWlycy5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5wYWlycyh7ICdiYXJuZXknOiAzNiwgJ2ZyZWQnOiA0MCB9KTtcbiAqIC8vID0+IFtbJ2Jhcm5leScsIDM2XSwgWydmcmVkJywgNDBdXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICovXG5mdW5jdGlvbiBwYWlycyhvYmplY3QpIHtcbiAgb2JqZWN0ID0gdG9PYmplY3Qob2JqZWN0KTtcblxuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIHByb3BzID0ga2V5cyhvYmplY3QpLFxuICAgICAgbGVuZ3RoID0gcHJvcHMubGVuZ3RoLFxuICAgICAgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKTtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHZhciBrZXkgPSBwcm9wc1tpbmRleF07XG4gICAgcmVzdWx0W2luZGV4XSA9IFtrZXksIG9iamVjdFtrZXldXTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHBhaXJzO1xuIiwidmFyIGJhc2VWYWx1ZXMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlVmFsdWVzJyksXG4gICAga2V5cyA9IHJlcXVpcmUoJy4va2V5cycpO1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBlbnVtZXJhYmxlIHByb3BlcnR5IHZhbHVlcyBvZiBgb2JqZWN0YC5cbiAqXG4gKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IE9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSB2YWx1ZXMuXG4gKiBAZXhhbXBsZVxuICpcbiAqIGZ1bmN0aW9uIEZvbygpIHtcbiAqICAgdGhpcy5hID0gMTtcbiAqICAgdGhpcy5iID0gMjtcbiAqIH1cbiAqXG4gKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICpcbiAqIF8udmFsdWVzKG5ldyBGb28pO1xuICogLy8gPT4gWzEsIDJdIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gKlxuICogXy52YWx1ZXMoJ2hpJyk7XG4gKiAvLyA9PiBbJ2gnLCAnaSddXG4gKi9cbmZ1bmN0aW9uIHZhbHVlcyhvYmplY3QpIHtcbiAgcmV0dXJuIGJhc2VWYWx1ZXMob2JqZWN0LCBrZXlzKG9iamVjdCkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHZhbHVlcztcbiIsIi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgYXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZSxcbiAgICBlcnJvclByb3RvID0gRXJyb3IucHJvdG90eXBlLFxuICAgIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBwcm9wZXJ0eUlzRW51bWVyYWJsZSA9IG9iamVjdFByb3RvLnByb3BlcnR5SXNFbnVtZXJhYmxlLFxuICAgIHNwbGljZSA9IGFycmF5UHJvdG8uc3BsaWNlO1xuXG4vKipcbiAqIEFuIG9iamVjdCBlbnZpcm9ubWVudCBmZWF0dXJlIGZsYWdzLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAdHlwZSBPYmplY3RcbiAqL1xudmFyIHN1cHBvcnQgPSB7fTtcblxuKGZ1bmN0aW9uKHgpIHtcbiAgdmFyIEN0b3IgPSBmdW5jdGlvbigpIHsgdGhpcy54ID0geDsgfSxcbiAgICAgIG9iamVjdCA9IHsgJzAnOiB4LCAnbGVuZ3RoJzogeCB9LFxuICAgICAgcHJvcHMgPSBbXTtcblxuICBDdG9yLnByb3RvdHlwZSA9IHsgJ3ZhbHVlT2YnOiB4LCAneSc6IHggfTtcbiAgZm9yICh2YXIga2V5IGluIG5ldyBDdG9yKSB7IHByb3BzLnB1c2goa2V5KTsgfVxuXG4gIC8qKlxuICAgKiBEZXRlY3QgaWYgYG5hbWVgIG9yIGBtZXNzYWdlYCBwcm9wZXJ0aWVzIG9mIGBFcnJvci5wcm90b3R5cGVgIGFyZVxuICAgKiBlbnVtZXJhYmxlIGJ5IGRlZmF1bHQgKElFIDwgOSwgU2FmYXJpIDwgNS4xKS5cbiAgICpcbiAgICogQG1lbWJlck9mIF8uc3VwcG9ydFxuICAgKiBAdHlwZSBib29sZWFuXG4gICAqL1xuICBzdXBwb3J0LmVudW1FcnJvclByb3BzID0gcHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChlcnJvclByb3RvLCAnbWVzc2FnZScpIHx8XG4gICAgcHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChlcnJvclByb3RvLCAnbmFtZScpO1xuXG4gIC8qKlxuICAgKiBEZXRlY3QgaWYgYHByb3RvdHlwZWAgcHJvcGVydGllcyBhcmUgZW51bWVyYWJsZSBieSBkZWZhdWx0LlxuICAgKlxuICAgKiBGaXJlZm94IDwgMy42LCBPcGVyYSA+IDkuNTAgLSBPcGVyYSA8IDExLjYwLCBhbmQgU2FmYXJpIDwgNS4xXG4gICAqIChpZiB0aGUgcHJvdG90eXBlIG9yIGEgcHJvcGVydHkgb24gdGhlIHByb3RvdHlwZSBoYXMgYmVlbiBzZXQpXG4gICAqIGluY29ycmVjdGx5IHNldCB0aGUgYFtbRW51bWVyYWJsZV1dYCB2YWx1ZSBvZiBhIGZ1bmN0aW9uJ3MgYHByb3RvdHlwZWBcbiAgICogcHJvcGVydHkgdG8gYHRydWVgLlxuICAgKlxuICAgKiBAbWVtYmVyT2YgXy5zdXBwb3J0XG4gICAqIEB0eXBlIGJvb2xlYW5cbiAgICovXG4gIHN1cHBvcnQuZW51bVByb3RvdHlwZXMgPSBwcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKEN0b3IsICdwcm90b3R5cGUnKTtcblxuICAvKipcbiAgICogRGV0ZWN0IGlmIHByb3BlcnRpZXMgc2hhZG93aW5nIHRob3NlIG9uIGBPYmplY3QucHJvdG90eXBlYCBhcmUgbm9uLWVudW1lcmFibGUuXG4gICAqXG4gICAqIEluIElFIDwgOSBhbiBvYmplY3QncyBvd24gcHJvcGVydGllcywgc2hhZG93aW5nIG5vbi1lbnVtZXJhYmxlIG9uZXMsXG4gICAqIGFyZSBtYWRlIG5vbi1lbnVtZXJhYmxlIGFzIHdlbGwgKGEuay5hIHRoZSBKU2NyaXB0IGBbW0RvbnRFbnVtXV1gIGJ1ZykuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBfLnN1cHBvcnRcbiAgICogQHR5cGUgYm9vbGVhblxuICAgKi9cbiAgc3VwcG9ydC5ub25FbnVtU2hhZG93cyA9ICEvdmFsdWVPZi8udGVzdChwcm9wcyk7XG5cbiAgLyoqXG4gICAqIERldGVjdCBpZiBvd24gcHJvcGVydGllcyBhcmUgaXRlcmF0ZWQgYWZ0ZXIgaW5oZXJpdGVkIHByb3BlcnRpZXMgKElFIDwgOSkuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBfLnN1cHBvcnRcbiAgICogQHR5cGUgYm9vbGVhblxuICAgKi9cbiAgc3VwcG9ydC5vd25MYXN0ID0gcHJvcHNbMF0gIT0gJ3gnO1xuXG4gIC8qKlxuICAgKiBEZXRlY3QgaWYgYEFycmF5I3NoaWZ0YCBhbmQgYEFycmF5I3NwbGljZWAgYXVnbWVudCBhcnJheS1saWtlIG9iamVjdHNcbiAgICogY29ycmVjdGx5LlxuICAgKlxuICAgKiBGaXJlZm94IDwgMTAsIGNvbXBhdGliaWxpdHkgbW9kZXMgb2YgSUUgOCwgYW5kIElFIDwgOSBoYXZlIGJ1Z2d5IEFycmF5XG4gICAqIGBzaGlmdCgpYCBhbmQgYHNwbGljZSgpYCBmdW5jdGlvbnMgdGhhdCBmYWlsIHRvIHJlbW92ZSB0aGUgbGFzdCBlbGVtZW50LFxuICAgKiBgdmFsdWVbMF1gLCBvZiBhcnJheS1saWtlIG9iamVjdHMgZXZlbiB0aG91Z2ggdGhlIFwibGVuZ3RoXCIgcHJvcGVydHkgaXNcbiAgICogc2V0IHRvIGAwYC4gVGhlIGBzaGlmdCgpYCBtZXRob2QgaXMgYnVnZ3kgaW4gY29tcGF0aWJpbGl0eSBtb2RlcyBvZiBJRSA4LFxuICAgKiB3aGlsZSBgc3BsaWNlKClgIGlzIGJ1Z2d5IHJlZ2FyZGxlc3Mgb2YgbW9kZSBpbiBJRSA8IDkuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBfLnN1cHBvcnRcbiAgICogQHR5cGUgYm9vbGVhblxuICAgKi9cbiAgc3VwcG9ydC5zcGxpY2VPYmplY3RzID0gKHNwbGljZS5jYWxsKG9iamVjdCwgMCwgMSksICFvYmplY3RbMF0pO1xuXG4gIC8qKlxuICAgKiBEZXRlY3QgbGFjayBvZiBzdXBwb3J0IGZvciBhY2Nlc3Npbmcgc3RyaW5nIGNoYXJhY3RlcnMgYnkgaW5kZXguXG4gICAqXG4gICAqIElFIDwgOCBjYW4ndCBhY2Nlc3MgY2hhcmFjdGVycyBieSBpbmRleC4gSUUgOCBjYW4gb25seSBhY2Nlc3MgY2hhcmFjdGVyc1xuICAgKiBieSBpbmRleCBvbiBzdHJpbmcgbGl0ZXJhbHMsIG5vdCBzdHJpbmcgb2JqZWN0cy5cbiAgICpcbiAgICogQG1lbWJlck9mIF8uc3VwcG9ydFxuICAgKiBAdHlwZSBib29sZWFuXG4gICAqL1xuICBzdXBwb3J0LnVuaW5kZXhlZENoYXJzID0gKCd4J1swXSArIE9iamVjdCgneCcpWzBdKSAhPSAneHgnO1xufSgxLCAwKSk7XG5cbm1vZHVsZS5leHBvcnRzID0gc3VwcG9ydDtcbiIsIi8qKlxuICogVGhpcyBtZXRob2QgcmV0dXJucyB0aGUgZmlyc3QgYXJndW1lbnQgcHJvdmlkZWQgdG8gaXQuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBVdGlsaXR5XG4gKiBAcGFyYW0geyp9IHZhbHVlIEFueSB2YWx1ZS5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIGB2YWx1ZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBvYmplY3QgPSB7ICd1c2VyJzogJ2ZyZWQnIH07XG4gKlxuICogXy5pZGVudGl0eShvYmplY3QpID09PSBvYmplY3Q7XG4gKiAvLyA9PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGlkZW50aXR5KHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpZGVudGl0eTtcbiIsIi8qKlxuICogQSBuby1vcGVyYXRpb24gZnVuY3Rpb24gdGhhdCByZXR1cm5zIGB1bmRlZmluZWRgIHJlZ2FyZGxlc3Mgb2YgdGhlXG4gKiBhcmd1bWVudHMgaXQgcmVjZWl2ZXMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBVdGlsaXR5XG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBvYmplY3QgPSB7ICd1c2VyJzogJ2ZyZWQnIH07XG4gKlxuICogXy5ub29wKG9iamVjdCkgPT09IHVuZGVmaW5lZDtcbiAqIC8vID0+IHRydWVcbiAqL1xuZnVuY3Rpb24gbm9vcCgpIHtcbiAgLy8gTm8gb3BlcmF0aW9uIHBlcmZvcm1lZC5cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBub29wO1xuIiwidmFyIGJhc2VQcm9wZXJ0eSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2Jhc2VQcm9wZXJ0eScpLFxuICAgIGJhc2VQcm9wZXJ0eURlZXAgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlUHJvcGVydHlEZWVwJyksXG4gICAgaXNLZXkgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0tleScpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlIGF0IGBwYXRoYCBvbiBhXG4gKiBnaXZlbiBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBVdGlsaXR5XG4gKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBvYmplY3RzID0gW1xuICogICB7ICdhJzogeyAnYic6IHsgJ2MnOiAyIH0gfSB9LFxuICogICB7ICdhJzogeyAnYic6IHsgJ2MnOiAxIH0gfSB9XG4gKiBdO1xuICpcbiAqIF8ubWFwKG9iamVjdHMsIF8ucHJvcGVydHkoJ2EuYi5jJykpO1xuICogLy8gPT4gWzIsIDFdXG4gKlxuICogXy5wbHVjayhfLnNvcnRCeShvYmplY3RzLCBfLnByb3BlcnR5KFsnYScsICdiJywgJ2MnXSkpLCAnYS5iLmMnKTtcbiAqIC8vID0+IFsxLCAyXVxuICovXG5mdW5jdGlvbiBwcm9wZXJ0eShwYXRoKSB7XG4gIHJldHVybiBpc0tleShwYXRoKSA/IGJhc2VQcm9wZXJ0eShwYXRoKSA6IGJhc2VQcm9wZXJ0eURlZXAocGF0aCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcHJvcGVydHk7XG4iLCIoZnVuY3Rpb24gKHByb2Nlc3Mpe1xuLy8gdmltOnRzPTQ6c3RzPTQ6c3c9NDpcbi8qIVxuICpcbiAqIENvcHlyaWdodCAyMDA5LTIwMTIgS3JpcyBLb3dhbCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIE1JVFxuICogbGljZW5zZSBmb3VuZCBhdCBodHRwOi8vZ2l0aHViLmNvbS9rcmlza293YWwvcS9yYXcvbWFzdGVyL0xJQ0VOU0VcbiAqXG4gKiBXaXRoIHBhcnRzIGJ5IFR5bGVyIENsb3NlXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDA5IFR5bGVyIENsb3NlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgTUlUIFggbGljZW5zZSBmb3VuZFxuICogYXQgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5odG1sXG4gKiBGb3JrZWQgYXQgcmVmX3NlbmQuanMgdmVyc2lvbjogMjAwOS0wNS0xMVxuICpcbiAqIFdpdGggcGFydHMgYnkgTWFyayBNaWxsZXJcbiAqIENvcHlyaWdodCAoQykgMjAxMSBHb29nbGUgSW5jLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4oZnVuY3Rpb24gKGRlZmluaXRpb24pIHtcbiAgICBcInVzZSBzdHJpY3RcIjtcblxuICAgIC8vIFRoaXMgZmlsZSB3aWxsIGZ1bmN0aW9uIHByb3Blcmx5IGFzIGEgPHNjcmlwdD4gdGFnLCBvciBhIG1vZHVsZVxuICAgIC8vIHVzaW5nIENvbW1vbkpTIGFuZCBOb2RlSlMgb3IgUmVxdWlyZUpTIG1vZHVsZSBmb3JtYXRzLiAgSW5cbiAgICAvLyBDb21tb24vTm9kZS9SZXF1aXJlSlMsIHRoZSBtb2R1bGUgZXhwb3J0cyB0aGUgUSBBUEkgYW5kIHdoZW5cbiAgICAvLyBleGVjdXRlZCBhcyBhIHNpbXBsZSA8c2NyaXB0PiwgaXQgY3JlYXRlcyBhIFEgZ2xvYmFsIGluc3RlYWQuXG5cbiAgICAvLyBNb250YWdlIFJlcXVpcmVcbiAgICBpZiAodHlwZW9mIGJvb3RzdHJhcCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGJvb3RzdHJhcChcInByb21pc2VcIiwgZGVmaW5pdGlvbik7XG5cbiAgICAvLyBDb21tb25KU1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG1vZHVsZSA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGRlZmluaXRpb24oKTtcblxuICAgIC8vIFJlcXVpcmVKU1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcbiAgICAgICAgZGVmaW5lKGRlZmluaXRpb24pO1xuXG4gICAgLy8gU0VTIChTZWN1cmUgRWNtYVNjcmlwdClcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBzZXMgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgaWYgKCFzZXMub2soKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VzLm1ha2VRID0gZGVmaW5pdGlvbjtcbiAgICAgICAgfVxuXG4gICAgLy8gPHNjcmlwdD5cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgfHwgdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgLy8gUHJlZmVyIHdpbmRvdyBvdmVyIHNlbGYgZm9yIGFkZC1vbiBzY3JpcHRzLiBVc2Ugc2VsZiBmb3JcbiAgICAgICAgLy8gbm9uLXdpbmRvd2VkIGNvbnRleHRzLlxuICAgICAgICB2YXIgZ2xvYmFsID0gdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHNlbGY7XG5cbiAgICAgICAgLy8gR2V0IHRoZSBgd2luZG93YCBvYmplY3QsIHNhdmUgdGhlIHByZXZpb3VzIFEgZ2xvYmFsXG4gICAgICAgIC8vIGFuZCBpbml0aWFsaXplIFEgYXMgYSBnbG9iYWwuXG4gICAgICAgIHZhciBwcmV2aW91c1EgPSBnbG9iYWwuUTtcbiAgICAgICAgZ2xvYmFsLlEgPSBkZWZpbml0aW9uKCk7XG5cbiAgICAgICAgLy8gQWRkIGEgbm9Db25mbGljdCBmdW5jdGlvbiBzbyBRIGNhbiBiZSByZW1vdmVkIGZyb20gdGhlXG4gICAgICAgIC8vIGdsb2JhbCBuYW1lc3BhY2UuXG4gICAgICAgIGdsb2JhbC5RLm5vQ29uZmxpY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBnbG9iYWwuUSA9IHByZXZpb3VzUTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9O1xuXG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBlbnZpcm9ubWVudCB3YXMgbm90IGFudGljaXBhdGVkIGJ5IFEuIFBsZWFzZSBmaWxlIGEgYnVnLlwiKTtcbiAgICB9XG5cbn0pKGZ1bmN0aW9uICgpIHtcblwidXNlIHN0cmljdFwiO1xuXG52YXIgaGFzU3RhY2tzID0gZmFsc2U7XG50cnkge1xuICAgIHRocm93IG5ldyBFcnJvcigpO1xufSBjYXRjaCAoZSkge1xuICAgIGhhc1N0YWNrcyA9ICEhZS5zdGFjaztcbn1cblxuLy8gQWxsIGNvZGUgYWZ0ZXIgdGhpcyBwb2ludCB3aWxsIGJlIGZpbHRlcmVkIGZyb20gc3RhY2sgdHJhY2VzIHJlcG9ydGVkXG4vLyBieSBRLlxudmFyIHFTdGFydGluZ0xpbmUgPSBjYXB0dXJlTGluZSgpO1xudmFyIHFGaWxlTmFtZTtcblxuLy8gc2hpbXNcblxuLy8gdXNlZCBmb3IgZmFsbGJhY2sgaW4gXCJhbGxSZXNvbHZlZFwiXG52YXIgbm9vcCA9IGZ1bmN0aW9uICgpIHt9O1xuXG4vLyBVc2UgdGhlIGZhc3Rlc3QgcG9zc2libGUgbWVhbnMgdG8gZXhlY3V0ZSBhIHRhc2sgaW4gYSBmdXR1cmUgdHVyblxuLy8gb2YgdGhlIGV2ZW50IGxvb3AuXG52YXIgbmV4dFRpY2sgPShmdW5jdGlvbiAoKSB7XG4gICAgLy8gbGlua2VkIGxpc3Qgb2YgdGFza3MgKHNpbmdsZSwgd2l0aCBoZWFkIG5vZGUpXG4gICAgdmFyIGhlYWQgPSB7dGFzazogdm9pZCAwLCBuZXh0OiBudWxsfTtcbiAgICB2YXIgdGFpbCA9IGhlYWQ7XG4gICAgdmFyIGZsdXNoaW5nID0gZmFsc2U7XG4gICAgdmFyIHJlcXVlc3RUaWNrID0gdm9pZCAwO1xuICAgIHZhciBpc05vZGVKUyA9IGZhbHNlO1xuICAgIC8vIHF1ZXVlIGZvciBsYXRlIHRhc2tzLCB1c2VkIGJ5IHVuaGFuZGxlZCByZWplY3Rpb24gdHJhY2tpbmdcbiAgICB2YXIgbGF0ZXJRdWV1ZSA9IFtdO1xuXG4gICAgZnVuY3Rpb24gZmx1c2goKSB7XG4gICAgICAgIC8qIGpzaGludCBsb29wZnVuYzogdHJ1ZSAqL1xuICAgICAgICB2YXIgdGFzaywgZG9tYWluO1xuXG4gICAgICAgIHdoaWxlIChoZWFkLm5leHQpIHtcbiAgICAgICAgICAgIGhlYWQgPSBoZWFkLm5leHQ7XG4gICAgICAgICAgICB0YXNrID0gaGVhZC50YXNrO1xuICAgICAgICAgICAgaGVhZC50YXNrID0gdm9pZCAwO1xuICAgICAgICAgICAgZG9tYWluID0gaGVhZC5kb21haW47XG5cbiAgICAgICAgICAgIGlmIChkb21haW4pIHtcbiAgICAgICAgICAgICAgICBoZWFkLmRvbWFpbiA9IHZvaWQgMDtcbiAgICAgICAgICAgICAgICBkb21haW4uZW50ZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJ1blNpbmdsZSh0YXNrLCBkb21haW4pO1xuXG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKGxhdGVyUXVldWUubGVuZ3RoKSB7XG4gICAgICAgICAgICB0YXNrID0gbGF0ZXJRdWV1ZS5wb3AoKTtcbiAgICAgICAgICAgIHJ1blNpbmdsZSh0YXNrKTtcbiAgICAgICAgfVxuICAgICAgICBmbHVzaGluZyA9IGZhbHNlO1xuICAgIH1cbiAgICAvLyBydW5zIGEgc2luZ2xlIGZ1bmN0aW9uIGluIHRoZSBhc3luYyBxdWV1ZVxuICAgIGZ1bmN0aW9uIHJ1blNpbmdsZSh0YXNrLCBkb21haW4pIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRhc2soKTtcblxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBpZiAoaXNOb2RlSlMpIHtcbiAgICAgICAgICAgICAgICAvLyBJbiBub2RlLCB1bmNhdWdodCBleGNlcHRpb25zIGFyZSBjb25zaWRlcmVkIGZhdGFsIGVycm9ycy5cbiAgICAgICAgICAgICAgICAvLyBSZS10aHJvdyB0aGVtIHN5bmNocm9ub3VzbHkgdG8gaW50ZXJydXB0IGZsdXNoaW5nIVxuXG4gICAgICAgICAgICAgICAgLy8gRW5zdXJlIGNvbnRpbnVhdGlvbiBpZiB0aGUgdW5jYXVnaHQgZXhjZXB0aW9uIGlzIHN1cHByZXNzZWRcbiAgICAgICAgICAgICAgICAvLyBsaXN0ZW5pbmcgXCJ1bmNhdWdodEV4Y2VwdGlvblwiIGV2ZW50cyAoYXMgZG9tYWlucyBkb2VzKS5cbiAgICAgICAgICAgICAgICAvLyBDb250aW51ZSBpbiBuZXh0IGV2ZW50IHRvIGF2b2lkIHRpY2sgcmVjdXJzaW9uLlxuICAgICAgICAgICAgICAgIGlmIChkb21haW4pIHtcbiAgICAgICAgICAgICAgICAgICAgZG9tYWluLmV4aXQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dChmbHVzaCwgMCk7XG4gICAgICAgICAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgICAgICAgICBkb21haW4uZW50ZXIoKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBlO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIEluIGJyb3dzZXJzLCB1bmNhdWdodCBleGNlcHRpb25zIGFyZSBub3QgZmF0YWwuXG4gICAgICAgICAgICAgICAgLy8gUmUtdGhyb3cgdGhlbSBhc3luY2hyb25vdXNseSB0byBhdm9pZCBzbG93LWRvd25zLlxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgICAgICAgIH0sIDApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgZG9tYWluLmV4aXQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5leHRUaWNrID0gZnVuY3Rpb24gKHRhc2spIHtcbiAgICAgICAgdGFpbCA9IHRhaWwubmV4dCA9IHtcbiAgICAgICAgICAgIHRhc2s6IHRhc2ssXG4gICAgICAgICAgICBkb21haW46IGlzTm9kZUpTICYmIHByb2Nlc3MuZG9tYWluLFxuICAgICAgICAgICAgbmV4dDogbnVsbFxuICAgICAgICB9O1xuXG4gICAgICAgIGlmICghZmx1c2hpbmcpIHtcbiAgICAgICAgICAgIGZsdXNoaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIHJlcXVlc3RUaWNrKCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgIHByb2Nlc3MudG9TdHJpbmcoKSA9PT0gXCJbb2JqZWN0IHByb2Nlc3NdXCIgJiYgcHJvY2Vzcy5uZXh0VGljaykge1xuICAgICAgICAvLyBFbnN1cmUgUSBpcyBpbiBhIHJlYWwgTm9kZSBlbnZpcm9ubWVudCwgd2l0aCBhIGBwcm9jZXNzLm5leHRUaWNrYC5cbiAgICAgICAgLy8gVG8gc2VlIHRocm91Z2ggZmFrZSBOb2RlIGVudmlyb25tZW50czpcbiAgICAgICAgLy8gKiBNb2NoYSB0ZXN0IHJ1bm5lciAtIGV4cG9zZXMgYSBgcHJvY2Vzc2AgZ2xvYmFsIHdpdGhvdXQgYSBgbmV4dFRpY2tgXG4gICAgICAgIC8vICogQnJvd3NlcmlmeSAtIGV4cG9zZXMgYSBgcHJvY2Vzcy5uZXhUaWNrYCBmdW5jdGlvbiB0aGF0IHVzZXNcbiAgICAgICAgLy8gICBgc2V0VGltZW91dGAuIEluIHRoaXMgY2FzZSBgc2V0SW1tZWRpYXRlYCBpcyBwcmVmZXJyZWQgYmVjYXVzZVxuICAgICAgICAvLyAgICBpdCBpcyBmYXN0ZXIuIEJyb3dzZXJpZnkncyBgcHJvY2Vzcy50b1N0cmluZygpYCB5aWVsZHNcbiAgICAgICAgLy8gICBcIltvYmplY3QgT2JqZWN0XVwiLCB3aGlsZSBpbiBhIHJlYWwgTm9kZSBlbnZpcm9ubWVudFxuICAgICAgICAvLyAgIGBwcm9jZXNzLm5leHRUaWNrKClgIHlpZWxkcyBcIltvYmplY3QgcHJvY2Vzc11cIi5cbiAgICAgICAgaXNOb2RlSlMgPSB0cnVlO1xuXG4gICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcHJvY2Vzcy5uZXh0VGljayhmbHVzaCk7XG4gICAgICAgIH07XG5cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBzZXRJbW1lZGlhdGUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAvLyBJbiBJRTEwLCBOb2RlLmpzIDAuOSssIG9yIGh0dHBzOi8vZ2l0aHViLmNvbS9Ob2JsZUpTL3NldEltbWVkaWF0ZVxuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgcmVxdWVzdFRpY2sgPSBzZXRJbW1lZGlhdGUuYmluZCh3aW5kb3csIGZsdXNoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHNldEltbWVkaWF0ZShmbHVzaCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBNZXNzYWdlQ2hhbm5lbCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAvLyBtb2Rlcm4gYnJvd3NlcnNcbiAgICAgICAgLy8gaHR0cDovL3d3dy5ub25ibG9ja2luZy5pby8yMDExLzA2L3dpbmRvd25leHR0aWNrLmh0bWxcbiAgICAgICAgdmFyIGNoYW5uZWwgPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcbiAgICAgICAgLy8gQXQgbGVhc3QgU2FmYXJpIFZlcnNpb24gNi4wLjUgKDg1MzYuMzAuMSkgaW50ZXJtaXR0ZW50bHkgY2Fubm90IGNyZWF0ZVxuICAgICAgICAvLyB3b3JraW5nIG1lc3NhZ2UgcG9ydHMgdGhlIGZpcnN0IHRpbWUgYSBwYWdlIGxvYWRzLlxuICAgICAgICBjaGFubmVsLnBvcnQxLm9ubWVzc2FnZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJlcXVlc3RUaWNrID0gcmVxdWVzdFBvcnRUaWNrO1xuICAgICAgICAgICAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSBmbHVzaDtcbiAgICAgICAgICAgIGZsdXNoKCk7XG4gICAgICAgIH07XG4gICAgICAgIHZhciByZXF1ZXN0UG9ydFRpY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAvLyBPcGVyYSByZXF1aXJlcyB1cyB0byBwcm92aWRlIGEgbWVzc2FnZSBwYXlsb2FkLCByZWdhcmRsZXNzIG9mXG4gICAgICAgICAgICAvLyB3aGV0aGVyIHdlIHVzZSBpdC5cbiAgICAgICAgICAgIGNoYW5uZWwucG9ydDIucG9zdE1lc3NhZ2UoMCk7XG4gICAgICAgIH07XG4gICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgc2V0VGltZW91dChmbHVzaCwgMCk7XG4gICAgICAgICAgICByZXF1ZXN0UG9ydFRpY2soKTtcbiAgICAgICAgfTtcblxuICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG9sZCBicm93c2Vyc1xuICAgICAgICByZXF1ZXN0VGljayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoZmx1c2gsIDApO1xuICAgICAgICB9O1xuICAgIH1cbiAgICAvLyBydW5zIGEgdGFzayBhZnRlciBhbGwgb3RoZXIgdGFza3MgaGF2ZSBiZWVuIHJ1blxuICAgIC8vIHRoaXMgaXMgdXNlZnVsIGZvciB1bmhhbmRsZWQgcmVqZWN0aW9uIHRyYWNraW5nIHRoYXQgbmVlZHMgdG8gaGFwcGVuXG4gICAgLy8gYWZ0ZXIgYWxsIGB0aGVuYGQgdGFza3MgaGF2ZSBiZWVuIHJ1bi5cbiAgICBuZXh0VGljay5ydW5BZnRlciA9IGZ1bmN0aW9uICh0YXNrKSB7XG4gICAgICAgIGxhdGVyUXVldWUucHVzaCh0YXNrKTtcbiAgICAgICAgaWYgKCFmbHVzaGluZykge1xuICAgICAgICAgICAgZmx1c2hpbmcgPSB0cnVlO1xuICAgICAgICAgICAgcmVxdWVzdFRpY2soKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIG5leHRUaWNrO1xufSkoKTtcblxuLy8gQXR0ZW1wdCB0byBtYWtlIGdlbmVyaWNzIHNhZmUgaW4gdGhlIGZhY2Ugb2YgZG93bnN0cmVhbVxuLy8gbW9kaWZpY2F0aW9ucy5cbi8vIFRoZXJlIGlzIG5vIHNpdHVhdGlvbiB3aGVyZSB0aGlzIGlzIG5lY2Vzc2FyeS5cbi8vIElmIHlvdSBuZWVkIGEgc2VjdXJpdHkgZ3VhcmFudGVlLCB0aGVzZSBwcmltb3JkaWFscyBuZWVkIHRvIGJlXG4vLyBkZWVwbHkgZnJvemVuIGFueXdheSwgYW5kIGlmIHlvdSBkb27igJl0IG5lZWQgYSBzZWN1cml0eSBndWFyYW50ZWUsXG4vLyB0aGlzIGlzIGp1c3QgcGxhaW4gcGFyYW5vaWQuXG4vLyBIb3dldmVyLCB0aGlzICoqbWlnaHQqKiBoYXZlIHRoZSBuaWNlIHNpZGUtZWZmZWN0IG9mIHJlZHVjaW5nIHRoZSBzaXplIG9mXG4vLyB0aGUgbWluaWZpZWQgY29kZSBieSByZWR1Y2luZyB4LmNhbGwoKSB0byBtZXJlbHkgeCgpXG4vLyBTZWUgTWFyayBNaWxsZXLigJlzIGV4cGxhbmF0aW9uIG9mIHdoYXQgdGhpcyBkb2VzLlxuLy8gaHR0cDovL3dpa2kuZWNtYXNjcmlwdC5vcmcvZG9rdS5waHA/aWQ9Y29udmVudGlvbnM6c2FmZV9tZXRhX3Byb2dyYW1taW5nXG52YXIgY2FsbCA9IEZ1bmN0aW9uLmNhbGw7XG5mdW5jdGlvbiB1bmN1cnJ5VGhpcyhmKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGNhbGwuYXBwbHkoZiwgYXJndW1lbnRzKTtcbiAgICB9O1xufVxuLy8gVGhpcyBpcyBlcXVpdmFsZW50LCBidXQgc2xvd2VyOlxuLy8gdW5jdXJyeVRoaXMgPSBGdW5jdGlvbl9iaW5kLmJpbmQoRnVuY3Rpb25fYmluZC5jYWxsKTtcbi8vIGh0dHA6Ly9qc3BlcmYuY29tL3VuY3Vycnl0aGlzXG5cbnZhciBhcnJheV9zbGljZSA9IHVuY3VycnlUaGlzKEFycmF5LnByb3RvdHlwZS5zbGljZSk7XG5cbnZhciBhcnJheV9yZWR1Y2UgPSB1bmN1cnJ5VGhpcyhcbiAgICBBcnJheS5wcm90b3R5cGUucmVkdWNlIHx8IGZ1bmN0aW9uIChjYWxsYmFjaywgYmFzaXMpIHtcbiAgICAgICAgdmFyIGluZGV4ID0gMCxcbiAgICAgICAgICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoO1xuICAgICAgICAvLyBjb25jZXJuaW5nIHRoZSBpbml0aWFsIHZhbHVlLCBpZiBvbmUgaXMgbm90IHByb3ZpZGVkXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAvLyBzZWVrIHRvIHRoZSBmaXJzdCB2YWx1ZSBpbiB0aGUgYXJyYXksIGFjY291bnRpbmdcbiAgICAgICAgICAgIC8vIGZvciB0aGUgcG9zc2liaWxpdHkgdGhhdCBpcyBpcyBhIHNwYXJzZSBhcnJheVxuICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICAgIGlmIChpbmRleCBpbiB0aGlzKSB7XG4gICAgICAgICAgICAgICAgICAgIGJhc2lzID0gdGhpc1tpbmRleCsrXTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICgrK2luZGV4ID49IGxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSB3aGlsZSAoMSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gcmVkdWNlXG4gICAgICAgIGZvciAoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgICAgLy8gYWNjb3VudCBmb3IgdGhlIHBvc3NpYmlsaXR5IHRoYXQgdGhlIGFycmF5IGlzIHNwYXJzZVxuICAgICAgICAgICAgaWYgKGluZGV4IGluIHRoaXMpIHtcbiAgICAgICAgICAgICAgICBiYXNpcyA9IGNhbGxiYWNrKGJhc2lzLCB0aGlzW2luZGV4XSwgaW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBiYXNpcztcbiAgICB9XG4pO1xuXG52YXIgYXJyYXlfaW5kZXhPZiA9IHVuY3VycnlUaGlzKFxuICAgIEFycmF5LnByb3RvdHlwZS5pbmRleE9mIHx8IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAvLyBub3QgYSB2ZXJ5IGdvb2Qgc2hpbSwgYnV0IGdvb2QgZW5vdWdoIGZvciBvdXIgb25lIHVzZSBvZiBpdFxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0aGlzW2ldID09PSB2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiAtMTtcbiAgICB9XG4pO1xuXG52YXIgYXJyYXlfbWFwID0gdW5jdXJyeVRoaXMoXG4gICAgQXJyYXkucHJvdG90eXBlLm1hcCB8fCBmdW5jdGlvbiAoY2FsbGJhY2ssIHRoaXNwKSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgdmFyIGNvbGxlY3QgPSBbXTtcbiAgICAgICAgYXJyYXlfcmVkdWNlKHNlbGYsIGZ1bmN0aW9uICh1bmRlZmluZWQsIHZhbHVlLCBpbmRleCkge1xuICAgICAgICAgICAgY29sbGVjdC5wdXNoKGNhbGxiYWNrLmNhbGwodGhpc3AsIHZhbHVlLCBpbmRleCwgc2VsZikpO1xuICAgICAgICB9LCB2b2lkIDApO1xuICAgICAgICByZXR1cm4gY29sbGVjdDtcbiAgICB9XG4pO1xuXG52YXIgb2JqZWN0X2NyZWF0ZSA9IE9iamVjdC5jcmVhdGUgfHwgZnVuY3Rpb24gKHByb3RvdHlwZSkge1xuICAgIGZ1bmN0aW9uIFR5cGUoKSB7IH1cbiAgICBUeXBlLnByb3RvdHlwZSA9IHByb3RvdHlwZTtcbiAgICByZXR1cm4gbmV3IFR5cGUoKTtcbn07XG5cbnZhciBvYmplY3RfaGFzT3duUHJvcGVydHkgPSB1bmN1cnJ5VGhpcyhPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5KTtcblxudmFyIG9iamVjdF9rZXlzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24gKG9iamVjdCkge1xuICAgIHZhciBrZXlzID0gW107XG4gICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAgICBpZiAob2JqZWN0X2hhc093blByb3BlcnR5KG9iamVjdCwga2V5KSkge1xuICAgICAgICAgICAga2V5cy5wdXNoKGtleSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGtleXM7XG59O1xuXG52YXIgb2JqZWN0X3RvU3RyaW5nID0gdW5jdXJyeVRoaXMoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZyk7XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSBPYmplY3QodmFsdWUpO1xufVxuXG4vLyBnZW5lcmF0b3IgcmVsYXRlZCBzaGltc1xuXG4vLyBGSVhNRTogUmVtb3ZlIHRoaXMgZnVuY3Rpb24gb25jZSBFUzYgZ2VuZXJhdG9ycyBhcmUgaW4gU3BpZGVyTW9ua2V5LlxuZnVuY3Rpb24gaXNTdG9wSXRlcmF0aW9uKGV4Y2VwdGlvbikge1xuICAgIHJldHVybiAoXG4gICAgICAgIG9iamVjdF90b1N0cmluZyhleGNlcHRpb24pID09PSBcIltvYmplY3QgU3RvcEl0ZXJhdGlvbl1cIiB8fFxuICAgICAgICBleGNlcHRpb24gaW5zdGFuY2VvZiBRUmV0dXJuVmFsdWVcbiAgICApO1xufVxuXG4vLyBGSVhNRTogUmVtb3ZlIHRoaXMgaGVscGVyIGFuZCBRLnJldHVybiBvbmNlIEVTNiBnZW5lcmF0b3JzIGFyZSBpblxuLy8gU3BpZGVyTW9ua2V5LlxudmFyIFFSZXR1cm5WYWx1ZTtcbmlmICh0eXBlb2YgUmV0dXJuVmFsdWUgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICBRUmV0dXJuVmFsdWUgPSBSZXR1cm5WYWx1ZTtcbn0gZWxzZSB7XG4gICAgUVJldHVyblZhbHVlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB9O1xufVxuXG4vLyBsb25nIHN0YWNrIHRyYWNlc1xuXG52YXIgU1RBQ0tfSlVNUF9TRVBBUkFUT1IgPSBcIkZyb20gcHJldmlvdXMgZXZlbnQ6XCI7XG5cbmZ1bmN0aW9uIG1ha2VTdGFja1RyYWNlTG9uZyhlcnJvciwgcHJvbWlzZSkge1xuICAgIC8vIElmIHBvc3NpYmxlLCB0cmFuc2Zvcm0gdGhlIGVycm9yIHN0YWNrIHRyYWNlIGJ5IHJlbW92aW5nIE5vZGUgYW5kIFFcbiAgICAvLyBjcnVmdCwgdGhlbiBjb25jYXRlbmF0aW5nIHdpdGggdGhlIHN0YWNrIHRyYWNlIG9mIGBwcm9taXNlYC4gU2VlICM1Ny5cbiAgICBpZiAoaGFzU3RhY2tzICYmXG4gICAgICAgIHByb21pc2Uuc3RhY2sgJiZcbiAgICAgICAgdHlwZW9mIGVycm9yID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgIGVycm9yICE9PSBudWxsICYmXG4gICAgICAgIGVycm9yLnN0YWNrICYmXG4gICAgICAgIGVycm9yLnN0YWNrLmluZGV4T2YoU1RBQ0tfSlVNUF9TRVBBUkFUT1IpID09PSAtMVxuICAgICkge1xuICAgICAgICB2YXIgc3RhY2tzID0gW107XG4gICAgICAgIGZvciAodmFyIHAgPSBwcm9taXNlOyAhIXA7IHAgPSBwLnNvdXJjZSkge1xuICAgICAgICAgICAgaWYgKHAuc3RhY2spIHtcbiAgICAgICAgICAgICAgICBzdGFja3MudW5zaGlmdChwLnN0YWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzdGFja3MudW5zaGlmdChlcnJvci5zdGFjayk7XG5cbiAgICAgICAgdmFyIGNvbmNhdGVkU3RhY2tzID0gc3RhY2tzLmpvaW4oXCJcXG5cIiArIFNUQUNLX0pVTVBfU0VQQVJBVE9SICsgXCJcXG5cIik7XG4gICAgICAgIGVycm9yLnN0YWNrID0gZmlsdGVyU3RhY2tTdHJpbmcoY29uY2F0ZWRTdGFja3MpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZmlsdGVyU3RhY2tTdHJpbmcoc3RhY2tTdHJpbmcpIHtcbiAgICB2YXIgbGluZXMgPSBzdGFja1N0cmluZy5zcGxpdChcIlxcblwiKTtcbiAgICB2YXIgZGVzaXJlZExpbmVzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgbGluZSA9IGxpbmVzW2ldO1xuXG4gICAgICAgIGlmICghaXNJbnRlcm5hbEZyYW1lKGxpbmUpICYmICFpc05vZGVGcmFtZShsaW5lKSAmJiBsaW5lKSB7XG4gICAgICAgICAgICBkZXNpcmVkTGluZXMucHVzaChsaW5lKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGVzaXJlZExpbmVzLmpvaW4oXCJcXG5cIik7XG59XG5cbmZ1bmN0aW9uIGlzTm9kZUZyYW1lKHN0YWNrTGluZSkge1xuICAgIHJldHVybiBzdGFja0xpbmUuaW5kZXhPZihcIihtb2R1bGUuanM6XCIpICE9PSAtMSB8fFxuICAgICAgICAgICBzdGFja0xpbmUuaW5kZXhPZihcIihub2RlLmpzOlwiKSAhPT0gLTE7XG59XG5cbmZ1bmN0aW9uIGdldEZpbGVOYW1lQW5kTGluZU51bWJlcihzdGFja0xpbmUpIHtcbiAgICAvLyBOYW1lZCBmdW5jdGlvbnM6IFwiYXQgZnVuY3Rpb25OYW1lIChmaWxlbmFtZTpsaW5lTnVtYmVyOmNvbHVtbk51bWJlcilcIlxuICAgIC8vIEluIElFMTAgZnVuY3Rpb24gbmFtZSBjYW4gaGF2ZSBzcGFjZXMgKFwiQW5vbnltb3VzIGZ1bmN0aW9uXCIpIE9fb1xuICAgIHZhciBhdHRlbXB0MSA9IC9hdCAuKyBcXCgoLispOihcXGQrKTooPzpcXGQrKVxcKSQvLmV4ZWMoc3RhY2tMaW5lKTtcbiAgICBpZiAoYXR0ZW1wdDEpIHtcbiAgICAgICAgcmV0dXJuIFthdHRlbXB0MVsxXSwgTnVtYmVyKGF0dGVtcHQxWzJdKV07XG4gICAgfVxuXG4gICAgLy8gQW5vbnltb3VzIGZ1bmN0aW9uczogXCJhdCBmaWxlbmFtZTpsaW5lTnVtYmVyOmNvbHVtbk51bWJlclwiXG4gICAgdmFyIGF0dGVtcHQyID0gL2F0IChbXiBdKyk6KFxcZCspOig/OlxcZCspJC8uZXhlYyhzdGFja0xpbmUpO1xuICAgIGlmIChhdHRlbXB0Mikge1xuICAgICAgICByZXR1cm4gW2F0dGVtcHQyWzFdLCBOdW1iZXIoYXR0ZW1wdDJbMl0pXTtcbiAgICB9XG5cbiAgICAvLyBGaXJlZm94IHN0eWxlOiBcImZ1bmN0aW9uQGZpbGVuYW1lOmxpbmVOdW1iZXIgb3IgQGZpbGVuYW1lOmxpbmVOdW1iZXJcIlxuICAgIHZhciBhdHRlbXB0MyA9IC8uKkAoLispOihcXGQrKSQvLmV4ZWMoc3RhY2tMaW5lKTtcbiAgICBpZiAoYXR0ZW1wdDMpIHtcbiAgICAgICAgcmV0dXJuIFthdHRlbXB0M1sxXSwgTnVtYmVyKGF0dGVtcHQzWzJdKV07XG4gICAgfVxufVxuXG5mdW5jdGlvbiBpc0ludGVybmFsRnJhbWUoc3RhY2tMaW5lKSB7XG4gICAgdmFyIGZpbGVOYW1lQW5kTGluZU51bWJlciA9IGdldEZpbGVOYW1lQW5kTGluZU51bWJlcihzdGFja0xpbmUpO1xuXG4gICAgaWYgKCFmaWxlTmFtZUFuZExpbmVOdW1iZXIpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHZhciBmaWxlTmFtZSA9IGZpbGVOYW1lQW5kTGluZU51bWJlclswXTtcbiAgICB2YXIgbGluZU51bWJlciA9IGZpbGVOYW1lQW5kTGluZU51bWJlclsxXTtcblxuICAgIHJldHVybiBmaWxlTmFtZSA9PT0gcUZpbGVOYW1lICYmXG4gICAgICAgIGxpbmVOdW1iZXIgPj0gcVN0YXJ0aW5nTGluZSAmJlxuICAgICAgICBsaW5lTnVtYmVyIDw9IHFFbmRpbmdMaW5lO1xufVxuXG4vLyBkaXNjb3ZlciBvd24gZmlsZSBuYW1lIGFuZCBsaW5lIG51bWJlciByYW5nZSBmb3IgZmlsdGVyaW5nIHN0YWNrXG4vLyB0cmFjZXNcbmZ1bmN0aW9uIGNhcHR1cmVMaW5lKCkge1xuICAgIGlmICghaGFzU3RhY2tzKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHZhciBsaW5lcyA9IGUuc3RhY2suc3BsaXQoXCJcXG5cIik7XG4gICAgICAgIHZhciBmaXJzdExpbmUgPSBsaW5lc1swXS5pbmRleE9mKFwiQFwiKSA+IDAgPyBsaW5lc1sxXSA6IGxpbmVzWzJdO1xuICAgICAgICB2YXIgZmlsZU5hbWVBbmRMaW5lTnVtYmVyID0gZ2V0RmlsZU5hbWVBbmRMaW5lTnVtYmVyKGZpcnN0TGluZSk7XG4gICAgICAgIGlmICghZmlsZU5hbWVBbmRMaW5lTnVtYmVyKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBxRmlsZU5hbWUgPSBmaWxlTmFtZUFuZExpbmVOdW1iZXJbMF07XG4gICAgICAgIHJldHVybiBmaWxlTmFtZUFuZExpbmVOdW1iZXJbMV07XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkZXByZWNhdGUoY2FsbGJhY2ssIG5hbWUsIGFsdGVybmF0aXZlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjb25zb2xlICE9PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgICB0eXBlb2YgY29uc29sZS53YXJuID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihuYW1lICsgXCIgaXMgZGVwcmVjYXRlZCwgdXNlIFwiICsgYWx0ZXJuYXRpdmUgK1xuICAgICAgICAgICAgICAgICAgICAgICAgIFwiIGluc3RlYWQuXCIsIG5ldyBFcnJvcihcIlwiKS5zdGFjayk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KGNhbGxiYWNrLCBhcmd1bWVudHMpO1xuICAgIH07XG59XG5cbi8vIGVuZCBvZiBzaGltc1xuLy8gYmVnaW5uaW5nIG9mIHJlYWwgd29ya1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBwcm9taXNlIGZvciBhbiBpbW1lZGlhdGUgcmVmZXJlbmNlLCBwYXNzZXMgcHJvbWlzZXMgdGhyb3VnaCwgb3JcbiAqIGNvZXJjZXMgcHJvbWlzZXMgZnJvbSBkaWZmZXJlbnQgc3lzdGVtcy5cbiAqIEBwYXJhbSB2YWx1ZSBpbW1lZGlhdGUgcmVmZXJlbmNlIG9yIHByb21pc2VcbiAqL1xuZnVuY3Rpb24gUSh2YWx1ZSkge1xuICAgIC8vIElmIHRoZSBvYmplY3QgaXMgYWxyZWFkeSBhIFByb21pc2UsIHJldHVybiBpdCBkaXJlY3RseS4gIFRoaXMgZW5hYmxlc1xuICAgIC8vIHRoZSByZXNvbHZlIGZ1bmN0aW9uIHRvIGJvdGggYmUgdXNlZCB0byBjcmVhdGVkIHJlZmVyZW5jZXMgZnJvbSBvYmplY3RzLFxuICAgIC8vIGJ1dCB0byB0b2xlcmFibHkgY29lcmNlIG5vbi1wcm9taXNlcyB0byBwcm9taXNlcy5cbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICAvLyBhc3NpbWlsYXRlIHRoZW5hYmxlc1xuICAgIGlmIChpc1Byb21pc2VBbGlrZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGNvZXJjZSh2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZ1bGZpbGwodmFsdWUpO1xuICAgIH1cbn1cblEucmVzb2x2ZSA9IFE7XG5cbi8qKlxuICogUGVyZm9ybXMgYSB0YXNrIGluIGEgZnV0dXJlIHR1cm4gb2YgdGhlIGV2ZW50IGxvb3AuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB0YXNrXG4gKi9cblEubmV4dFRpY2sgPSBuZXh0VGljaztcblxuLyoqXG4gKiBDb250cm9scyB3aGV0aGVyIG9yIG5vdCBsb25nIHN0YWNrIHRyYWNlcyB3aWxsIGJlIG9uXG4gKi9cblEubG9uZ1N0YWNrU3VwcG9ydCA9IGZhbHNlO1xuXG4vLyBlbmFibGUgbG9uZyBzdGFja3MgaWYgUV9ERUJVRyBpcyBzZXRcbmlmICh0eXBlb2YgcHJvY2VzcyA9PT0gXCJvYmplY3RcIiAmJiBwcm9jZXNzICYmIHByb2Nlc3MuZW52ICYmIHByb2Nlc3MuZW52LlFfREVCVUcpIHtcbiAgICBRLmxvbmdTdGFja1N1cHBvcnQgPSB0cnVlO1xufVxuXG4vKipcbiAqIENvbnN0cnVjdHMgYSB7cHJvbWlzZSwgcmVzb2x2ZSwgcmVqZWN0fSBvYmplY3QuXG4gKlxuICogYHJlc29sdmVgIGlzIGEgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggYSBtb3JlIHJlc29sdmVkIHZhbHVlIGZvciB0aGVcbiAqIHByb21pc2UuIFRvIGZ1bGZpbGwgdGhlIHByb21pc2UsIGludm9rZSBgcmVzb2x2ZWAgd2l0aCBhbnkgdmFsdWUgdGhhdCBpc1xuICogbm90IGEgdGhlbmFibGUuIFRvIHJlamVjdCB0aGUgcHJvbWlzZSwgaW52b2tlIGByZXNvbHZlYCB3aXRoIGEgcmVqZWN0ZWRcbiAqIHRoZW5hYmxlLCBvciBpbnZva2UgYHJlamVjdGAgd2l0aCB0aGUgcmVhc29uIGRpcmVjdGx5LiBUbyByZXNvbHZlIHRoZVxuICogcHJvbWlzZSB0byBhbm90aGVyIHRoZW5hYmxlLCB0aHVzIHB1dHRpbmcgaXQgaW4gdGhlIHNhbWUgc3RhdGUsIGludm9rZVxuICogYHJlc29sdmVgIHdpdGggdGhhdCBvdGhlciB0aGVuYWJsZS5cbiAqL1xuUS5kZWZlciA9IGRlZmVyO1xuZnVuY3Rpb24gZGVmZXIoKSB7XG4gICAgLy8gaWYgXCJtZXNzYWdlc1wiIGlzIGFuIFwiQXJyYXlcIiwgdGhhdCBpbmRpY2F0ZXMgdGhhdCB0aGUgcHJvbWlzZSBoYXMgbm90IHlldFxuICAgIC8vIGJlZW4gcmVzb2x2ZWQuICBJZiBpdCBpcyBcInVuZGVmaW5lZFwiLCBpdCBoYXMgYmVlbiByZXNvbHZlZC4gIEVhY2hcbiAgICAvLyBlbGVtZW50IG9mIHRoZSBtZXNzYWdlcyBhcnJheSBpcyBpdHNlbGYgYW4gYXJyYXkgb2YgY29tcGxldGUgYXJndW1lbnRzIHRvXG4gICAgLy8gZm9yd2FyZCB0byB0aGUgcmVzb2x2ZWQgcHJvbWlzZS4gIFdlIGNvZXJjZSB0aGUgcmVzb2x1dGlvbiB2YWx1ZSB0byBhXG4gICAgLy8gcHJvbWlzZSB1c2luZyB0aGUgYHJlc29sdmVgIGZ1bmN0aW9uIGJlY2F1c2UgaXQgaGFuZGxlcyBib3RoIGZ1bGx5XG4gICAgLy8gbm9uLXRoZW5hYmxlIHZhbHVlcyBhbmQgb3RoZXIgdGhlbmFibGVzIGdyYWNlZnVsbHkuXG4gICAgdmFyIG1lc3NhZ2VzID0gW10sIHByb2dyZXNzTGlzdGVuZXJzID0gW10sIHJlc29sdmVkUHJvbWlzZTtcblxuICAgIHZhciBkZWZlcnJlZCA9IG9iamVjdF9jcmVhdGUoZGVmZXIucHJvdG90eXBlKTtcbiAgICB2YXIgcHJvbWlzZSA9IG9iamVjdF9jcmVhdGUoUHJvbWlzZS5wcm90b3R5cGUpO1xuXG4gICAgcHJvbWlzZS5wcm9taXNlRGlzcGF0Y2ggPSBmdW5jdGlvbiAocmVzb2x2ZSwgb3AsIG9wZXJhbmRzKSB7XG4gICAgICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICAgICAgaWYgKG1lc3NhZ2VzKSB7XG4gICAgICAgICAgICBtZXNzYWdlcy5wdXNoKGFyZ3MpO1xuICAgICAgICAgICAgaWYgKG9wID09PSBcIndoZW5cIiAmJiBvcGVyYW5kc1sxXSkgeyAvLyBwcm9ncmVzcyBvcGVyYW5kXG4gICAgICAgICAgICAgICAgcHJvZ3Jlc3NMaXN0ZW5lcnMucHVzaChvcGVyYW5kc1sxXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBRLm5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlZFByb21pc2UucHJvbWlzZURpc3BhdGNoLmFwcGx5KHJlc29sdmVkUHJvbWlzZSwgYXJncyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvLyBYWFggZGVwcmVjYXRlZFxuICAgIHByb21pc2UudmFsdWVPZiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKG1lc3NhZ2VzKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbmVhcmVyVmFsdWUgPSBuZWFyZXIocmVzb2x2ZWRQcm9taXNlKTtcbiAgICAgICAgaWYgKGlzUHJvbWlzZShuZWFyZXJWYWx1ZSkpIHtcbiAgICAgICAgICAgIHJlc29sdmVkUHJvbWlzZSA9IG5lYXJlclZhbHVlOyAvLyBzaG9ydGVuIGNoYWluXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5lYXJlclZhbHVlO1xuICAgIH07XG5cbiAgICBwcm9taXNlLmluc3BlY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghcmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm4geyBzdGF0ZTogXCJwZW5kaW5nXCIgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzb2x2ZWRQcm9taXNlLmluc3BlY3QoKTtcbiAgICB9O1xuXG4gICAgaWYgKFEubG9uZ1N0YWNrU3VwcG9ydCAmJiBoYXNTdGFja3MpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBOT1RFOiBkb24ndCB0cnkgdG8gdXNlIGBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZWAgb3IgdHJhbnNmZXIgdGhlXG4gICAgICAgICAgICAvLyBhY2Nlc3NvciBhcm91bmQ7IHRoYXQgY2F1c2VzIG1lbW9yeSBsZWFrcyBhcyBwZXIgR0gtMTExLiBKdXN0XG4gICAgICAgICAgICAvLyByZWlmeSB0aGUgc3RhY2sgdHJhY2UgYXMgYSBzdHJpbmcgQVNBUC5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBBdCB0aGUgc2FtZSB0aW1lLCBjdXQgb2ZmIHRoZSBmaXJzdCBsaW5lOyBpdCdzIGFsd2F5cyBqdXN0XG4gICAgICAgICAgICAvLyBcIltvYmplY3QgUHJvbWlzZV1cXG5cIiwgYXMgcGVyIHRoZSBgdG9TdHJpbmdgLlxuICAgICAgICAgICAgcHJvbWlzZS5zdGFjayA9IGUuc3RhY2suc3Vic3RyaW5nKGUuc3RhY2suaW5kZXhPZihcIlxcblwiKSArIDEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gTk9URTogd2UgZG8gdGhlIGNoZWNrcyBmb3IgYHJlc29sdmVkUHJvbWlzZWAgaW4gZWFjaCBtZXRob2QsIGluc3RlYWQgb2ZcbiAgICAvLyBjb25zb2xpZGF0aW5nIHRoZW0gaW50byBgYmVjb21lYCwgc2luY2Ugb3RoZXJ3aXNlIHdlJ2QgY3JlYXRlIG5ld1xuICAgIC8vIHByb21pc2VzIHdpdGggdGhlIGxpbmVzIGBiZWNvbWUod2hhdGV2ZXIodmFsdWUpKWAuIFNlZSBlLmcuIEdILTI1Mi5cblxuICAgIGZ1bmN0aW9uIGJlY29tZShuZXdQcm9taXNlKSB7XG4gICAgICAgIHJlc29sdmVkUHJvbWlzZSA9IG5ld1Byb21pc2U7XG4gICAgICAgIHByb21pc2Uuc291cmNlID0gbmV3UHJvbWlzZTtcblxuICAgICAgICBhcnJheV9yZWR1Y2UobWVzc2FnZXMsIGZ1bmN0aW9uICh1bmRlZmluZWQsIG1lc3NhZ2UpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIG5ld1Byb21pc2UucHJvbWlzZURpc3BhdGNoLmFwcGx5KG5ld1Byb21pc2UsIG1lc3NhZ2UpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sIHZvaWQgMCk7XG5cbiAgICAgICAgbWVzc2FnZXMgPSB2b2lkIDA7XG4gICAgICAgIHByb2dyZXNzTGlzdGVuZXJzID0gdm9pZCAwO1xuICAgIH1cblxuICAgIGRlZmVycmVkLnByb21pc2UgPSBwcm9taXNlO1xuICAgIGRlZmVycmVkLnJlc29sdmUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgaWYgKHJlc29sdmVkUHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgYmVjb21lKFEodmFsdWUpKTtcbiAgICB9O1xuXG4gICAgZGVmZXJyZWQuZnVsZmlsbCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICBpZiAocmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBiZWNvbWUoZnVsZmlsbCh2YWx1ZSkpO1xuICAgIH07XG4gICAgZGVmZXJyZWQucmVqZWN0ID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgICBpZiAocmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBiZWNvbWUocmVqZWN0KHJlYXNvbikpO1xuICAgIH07XG4gICAgZGVmZXJyZWQubm90aWZ5ID0gZnVuY3Rpb24gKHByb2dyZXNzKSB7XG4gICAgICAgIGlmIChyZXNvbHZlZFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGFycmF5X3JlZHVjZShwcm9ncmVzc0xpc3RlbmVycywgZnVuY3Rpb24gKHVuZGVmaW5lZCwgcHJvZ3Jlc3NMaXN0ZW5lcikge1xuICAgICAgICAgICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcHJvZ3Jlc3NMaXN0ZW5lcihwcm9ncmVzcyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSwgdm9pZCAwKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIGRlZmVycmVkO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBOb2RlLXN0eWxlIGNhbGxiYWNrIHRoYXQgd2lsbCByZXNvbHZlIG9yIHJlamVjdCB0aGUgZGVmZXJyZWRcbiAqIHByb21pc2UuXG4gKiBAcmV0dXJucyBhIG5vZGViYWNrXG4gKi9cbmRlZmVyLnByb3RvdHlwZS5tYWtlTm9kZVJlc29sdmVyID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICByZXR1cm4gZnVuY3Rpb24gKGVycm9yLCB2YWx1ZSkge1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgIHNlbGYucmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMikge1xuICAgICAgICAgICAgc2VsZi5yZXNvbHZlKGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VsZi5yZXNvbHZlKHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuXG4vKipcbiAqIEBwYXJhbSByZXNvbHZlciB7RnVuY3Rpb259IGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIG5vdGhpbmcgYW5kIGFjY2VwdHNcbiAqIHRoZSByZXNvbHZlLCByZWplY3QsIGFuZCBub3RpZnkgZnVuY3Rpb25zIGZvciBhIGRlZmVycmVkLlxuICogQHJldHVybnMgYSBwcm9taXNlIHRoYXQgbWF5IGJlIHJlc29sdmVkIHdpdGggdGhlIGdpdmVuIHJlc29sdmUgYW5kIHJlamVjdFxuICogZnVuY3Rpb25zLCBvciByZWplY3RlZCBieSBhIHRocm93biBleGNlcHRpb24gaW4gcmVzb2x2ZXJcbiAqL1xuUS5Qcm9taXNlID0gcHJvbWlzZTsgLy8gRVM2XG5RLnByb21pc2UgPSBwcm9taXNlO1xuZnVuY3Rpb24gcHJvbWlzZShyZXNvbHZlcikge1xuICAgIGlmICh0eXBlb2YgcmVzb2x2ZXIgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwicmVzb2x2ZXIgbXVzdCBiZSBhIGZ1bmN0aW9uLlwiKTtcbiAgICB9XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB0cnkge1xuICAgICAgICByZXNvbHZlcihkZWZlcnJlZC5yZXNvbHZlLCBkZWZlcnJlZC5yZWplY3QsIGRlZmVycmVkLm5vdGlmeSk7XG4gICAgfSBjYXRjaCAocmVhc29uKSB7XG4gICAgICAgIGRlZmVycmVkLnJlamVjdChyZWFzb24pO1xuICAgIH1cbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn1cblxucHJvbWlzZS5yYWNlID0gcmFjZTsgLy8gRVM2XG5wcm9taXNlLmFsbCA9IGFsbDsgLy8gRVM2XG5wcm9taXNlLnJlamVjdCA9IHJlamVjdDsgLy8gRVM2XG5wcm9taXNlLnJlc29sdmUgPSBROyAvLyBFUzZcblxuLy8gWFhYIGV4cGVyaW1lbnRhbC4gIFRoaXMgbWV0aG9kIGlzIGEgd2F5IHRvIGRlbm90ZSB0aGF0IGEgbG9jYWwgdmFsdWUgaXNcbi8vIHNlcmlhbGl6YWJsZSBhbmQgc2hvdWxkIGJlIGltbWVkaWF0ZWx5IGRpc3BhdGNoZWQgdG8gYSByZW1vdGUgdXBvbiByZXF1ZXN0LFxuLy8gaW5zdGVhZCBvZiBwYXNzaW5nIGEgcmVmZXJlbmNlLlxuUS5wYXNzQnlDb3B5ID0gZnVuY3Rpb24gKG9iamVjdCkge1xuICAgIC8vZnJlZXplKG9iamVjdCk7XG4gICAgLy9wYXNzQnlDb3BpZXMuc2V0KG9iamVjdCwgdHJ1ZSk7XG4gICAgcmV0dXJuIG9iamVjdDtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnBhc3NCeUNvcHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgLy9mcmVlemUob2JqZWN0KTtcbiAgICAvL3Bhc3NCeUNvcGllcy5zZXQob2JqZWN0LCB0cnVlKTtcbiAgICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogSWYgdHdvIHByb21pc2VzIGV2ZW50dWFsbHkgZnVsZmlsbCB0byB0aGUgc2FtZSB2YWx1ZSwgcHJvbWlzZXMgdGhhdCB2YWx1ZSxcbiAqIGJ1dCBvdGhlcndpc2UgcmVqZWN0cy5cbiAqIEBwYXJhbSB4IHtBbnkqfVxuICogQHBhcmFtIHkge0FueSp9XG4gKiBAcmV0dXJucyB7QW55Kn0gYSBwcm9taXNlIGZvciB4IGFuZCB5IGlmIHRoZXkgYXJlIHRoZSBzYW1lLCBidXQgYSByZWplY3Rpb25cbiAqIG90aGVyd2lzZS5cbiAqXG4gKi9cblEuam9pbiA9IGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgcmV0dXJuIFEoeCkuam9pbih5KTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmpvaW4gPSBmdW5jdGlvbiAodGhhdCkge1xuICAgIHJldHVybiBRKFt0aGlzLCB0aGF0XSkuc3ByZWFkKGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgICAgIGlmICh4ID09PSB5KSB7XG4gICAgICAgICAgICAvLyBUT0RPOiBcIj09PVwiIHNob3VsZCBiZSBPYmplY3QuaXMgb3IgZXF1aXZcbiAgICAgICAgICAgIHJldHVybiB4O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FuJ3Qgam9pbjogbm90IHRoZSBzYW1lOiBcIiArIHggKyBcIiBcIiArIHkpO1xuICAgICAgICB9XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgZmlyc3Qgb2YgYW4gYXJyYXkgb2YgcHJvbWlzZXMgdG8gYmVjb21lIHNldHRsZWQuXG4gKiBAcGFyYW0gYW5zd2VycyB7QXJyYXlbQW55Kl19IHByb21pc2VzIHRvIHJhY2VcbiAqIEByZXR1cm5zIHtBbnkqfSB0aGUgZmlyc3QgcHJvbWlzZSB0byBiZSBzZXR0bGVkXG4gKi9cblEucmFjZSA9IHJhY2U7XG5mdW5jdGlvbiByYWNlKGFuc3dlclBzKSB7XG4gICAgcmV0dXJuIHByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAvLyBTd2l0Y2ggdG8gdGhpcyBvbmNlIHdlIGNhbiBhc3N1bWUgYXQgbGVhc3QgRVM1XG4gICAgICAgIC8vIGFuc3dlclBzLmZvckVhY2goZnVuY3Rpb24gKGFuc3dlclApIHtcbiAgICAgICAgLy8gICAgIFEoYW5zd2VyUCkudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAvLyB9KTtcbiAgICAgICAgLy8gVXNlIHRoaXMgaW4gdGhlIG1lYW50aW1lXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBhbnN3ZXJQcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgUShhbnN3ZXJQc1tpXSkudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5cblByb21pc2UucHJvdG90eXBlLnJhY2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbihRLnJhY2UpO1xufTtcblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgUHJvbWlzZSB3aXRoIGEgcHJvbWlzZSBkZXNjcmlwdG9yIG9iamVjdCBhbmQgb3B0aW9uYWwgZmFsbGJhY2tcbiAqIGZ1bmN0aW9uLiAgVGhlIGRlc2NyaXB0b3IgY29udGFpbnMgbWV0aG9kcyBsaWtlIHdoZW4ocmVqZWN0ZWQpLCBnZXQobmFtZSksXG4gKiBzZXQobmFtZSwgdmFsdWUpLCBwb3N0KG5hbWUsIGFyZ3MpLCBhbmQgZGVsZXRlKG5hbWUpLCB3aGljaCBhbGxcbiAqIHJldHVybiBlaXRoZXIgYSB2YWx1ZSwgYSBwcm9taXNlIGZvciBhIHZhbHVlLCBvciBhIHJlamVjdGlvbi4gIFRoZSBmYWxsYmFja1xuICogYWNjZXB0cyB0aGUgb3BlcmF0aW9uIG5hbWUsIGEgcmVzb2x2ZXIsIGFuZCBhbnkgZnVydGhlciBhcmd1bWVudHMgdGhhdCB3b3VsZFxuICogaGF2ZSBiZWVuIGZvcndhcmRlZCB0byB0aGUgYXBwcm9wcmlhdGUgbWV0aG9kIGFib3ZlIGhhZCBhIG1ldGhvZCBiZWVuXG4gKiBwcm92aWRlZCB3aXRoIHRoZSBwcm9wZXIgbmFtZS4gIFRoZSBBUEkgbWFrZXMgbm8gZ3VhcmFudGVlcyBhYm91dCB0aGUgbmF0dXJlXG4gKiBvZiB0aGUgcmV0dXJuZWQgb2JqZWN0LCBhcGFydCBmcm9tIHRoYXQgaXQgaXMgdXNhYmxlIHdoZXJlZXZlciBwcm9taXNlcyBhcmVcbiAqIGJvdWdodCBhbmQgc29sZC5cbiAqL1xuUS5tYWtlUHJvbWlzZSA9IFByb21pc2U7XG5mdW5jdGlvbiBQcm9taXNlKGRlc2NyaXB0b3IsIGZhbGxiYWNrLCBpbnNwZWN0KSB7XG4gICAgaWYgKGZhbGxiYWNrID09PSB2b2lkIDApIHtcbiAgICAgICAgZmFsbGJhY2sgPSBmdW5jdGlvbiAob3ApIHtcbiAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKFxuICAgICAgICAgICAgICAgIFwiUHJvbWlzZSBkb2VzIG5vdCBzdXBwb3J0IG9wZXJhdGlvbjogXCIgKyBvcFxuICAgICAgICAgICAgKSk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIGlmIChpbnNwZWN0ID09PSB2b2lkIDApIHtcbiAgICAgICAgaW5zcGVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB7c3RhdGU6IFwidW5rbm93blwifTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICB2YXIgcHJvbWlzZSA9IG9iamVjdF9jcmVhdGUoUHJvbWlzZS5wcm90b3R5cGUpO1xuXG4gICAgcHJvbWlzZS5wcm9taXNlRGlzcGF0Y2ggPSBmdW5jdGlvbiAocmVzb2x2ZSwgb3AsIGFyZ3MpIHtcbiAgICAgICAgdmFyIHJlc3VsdDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmIChkZXNjcmlwdG9yW29wXSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGRlc2NyaXB0b3Jbb3BdLmFwcGx5KHByb21pc2UsIGFyZ3MpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBmYWxsYmFjay5jYWxsKHByb21pc2UsIG9wLCBhcmdzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICByZXN1bHQgPSByZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVzb2x2ZSkge1xuICAgICAgICAgICAgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHByb21pc2UuaW5zcGVjdCA9IGluc3BlY3Q7XG5cbiAgICAvLyBYWFggZGVwcmVjYXRlZCBgdmFsdWVPZmAgYW5kIGBleGNlcHRpb25gIHN1cHBvcnRcbiAgICBpZiAoaW5zcGVjdCkge1xuICAgICAgICB2YXIgaW5zcGVjdGVkID0gaW5zcGVjdCgpO1xuICAgICAgICBpZiAoaW5zcGVjdGVkLnN0YXRlID09PSBcInJlamVjdGVkXCIpIHtcbiAgICAgICAgICAgIHByb21pc2UuZXhjZXB0aW9uID0gaW5zcGVjdGVkLnJlYXNvbjtcbiAgICAgICAgfVxuXG4gICAgICAgIHByb21pc2UudmFsdWVPZiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBpbnNwZWN0ZWQgPSBpbnNwZWN0KCk7XG4gICAgICAgICAgICBpZiAoaW5zcGVjdGVkLnN0YXRlID09PSBcInBlbmRpbmdcIiB8fFxuICAgICAgICAgICAgICAgIGluc3BlY3RlZC5zdGF0ZSA9PT0gXCJyZWplY3RlZFwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gaW5zcGVjdGVkLnZhbHVlO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiBwcm9taXNlO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gXCJbb2JqZWN0IFByb21pc2VdXCI7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50aGVuID0gZnVuY3Rpb24gKGZ1bGZpbGxlZCwgcmVqZWN0ZWQsIHByb2dyZXNzZWQpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB2YXIgZG9uZSA9IGZhbHNlOyAgIC8vIGVuc3VyZSB0aGUgdW50cnVzdGVkIHByb21pc2UgbWFrZXMgYXQgbW9zdCBhXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBzaW5nbGUgY2FsbCB0byBvbmUgb2YgdGhlIGNhbGxiYWNrc1xuXG4gICAgZnVuY3Rpb24gX2Z1bGZpbGxlZCh2YWx1ZSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiBmdWxmaWxsZWQgPT09IFwiZnVuY3Rpb25cIiA/IGZ1bGZpbGxlZCh2YWx1ZSkgOiB2YWx1ZTtcbiAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVqZWN0KGV4Y2VwdGlvbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfcmVqZWN0ZWQoZXhjZXB0aW9uKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcmVqZWN0ZWQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgbWFrZVN0YWNrVHJhY2VMb25nKGV4Y2VwdGlvbiwgc2VsZik7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3RlZChleGNlcHRpb24pO1xuICAgICAgICAgICAgfSBjYXRjaCAobmV3RXhjZXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXdFeGNlcHRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZWplY3QoZXhjZXB0aW9uKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfcHJvZ3Jlc3NlZCh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdHlwZW9mIHByb2dyZXNzZWQgPT09IFwiZnVuY3Rpb25cIiA/IHByb2dyZXNzZWQodmFsdWUpIDogdmFsdWU7XG4gICAgfVxuXG4gICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlbGYucHJvbWlzZURpc3BhdGNoKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkb25lID0gdHJ1ZTtcblxuICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZShfZnVsZmlsbGVkKHZhbHVlKSk7XG4gICAgICAgIH0sIFwid2hlblwiLCBbZnVuY3Rpb24gKGV4Y2VwdGlvbikge1xuICAgICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkb25lID0gdHJ1ZTtcblxuICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZShfcmVqZWN0ZWQoZXhjZXB0aW9uKSk7XG4gICAgICAgIH1dKTtcbiAgICB9KTtcblxuICAgIC8vIFByb2dyZXNzIHByb3BhZ2F0b3IgbmVlZCB0byBiZSBhdHRhY2hlZCBpbiB0aGUgY3VycmVudCB0aWNrLlxuICAgIHNlbGYucHJvbWlzZURpc3BhdGNoKHZvaWQgMCwgXCJ3aGVuXCIsIFt2b2lkIDAsIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgbmV3VmFsdWU7XG4gICAgICAgIHZhciB0aHJldyA9IGZhbHNlO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbmV3VmFsdWUgPSBfcHJvZ3Jlc3NlZCh2YWx1ZSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHRocmV3ID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChRLm9uZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBRLm9uZXJyb3IoZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRocmV3KSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5ub3RpZnkobmV3VmFsdWUpO1xuICAgICAgICB9XG4gICAgfV0pO1xuXG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG5RLnRhcCA9IGZ1bmN0aW9uIChwcm9taXNlLCBjYWxsYmFjaykge1xuICAgIHJldHVybiBRKHByb21pc2UpLnRhcChjYWxsYmFjayk7XG59O1xuXG4vKipcbiAqIFdvcmtzIGFsbW9zdCBsaWtlIFwiZmluYWxseVwiLCBidXQgbm90IGNhbGxlZCBmb3IgcmVqZWN0aW9ucy5cbiAqIE9yaWdpbmFsIHJlc29sdXRpb24gdmFsdWUgaXMgcGFzc2VkIHRocm91Z2ggY2FsbGJhY2sgdW5hZmZlY3RlZC5cbiAqIENhbGxiYWNrIG1heSByZXR1cm4gYSBwcm9taXNlIHRoYXQgd2lsbCBiZSBhd2FpdGVkIGZvci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gKiBAcmV0dXJucyB7US5Qcm9taXNlfVxuICogQGV4YW1wbGVcbiAqIGRvU29tZXRoaW5nKClcbiAqICAgLnRoZW4oLi4uKVxuICogICAudGFwKGNvbnNvbGUubG9nKVxuICogICAudGhlbiguLi4pO1xuICovXG5Qcm9taXNlLnByb3RvdHlwZS50YXAgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjayA9IFEoY2FsbGJhY2spO1xuXG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmZjYWxsKHZhbHVlKS50aGVuUmVzb2x2ZSh2YWx1ZSk7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhbiBvYnNlcnZlciBvbiBhIHByb21pc2UuXG4gKlxuICogR3VhcmFudGVlczpcbiAqXG4gKiAxLiB0aGF0IGZ1bGZpbGxlZCBhbmQgcmVqZWN0ZWQgd2lsbCBiZSBjYWxsZWQgb25seSBvbmNlLlxuICogMi4gdGhhdCBlaXRoZXIgdGhlIGZ1bGZpbGxlZCBjYWxsYmFjayBvciB0aGUgcmVqZWN0ZWQgY2FsbGJhY2sgd2lsbCBiZVxuICogICAgY2FsbGVkLCBidXQgbm90IGJvdGguXG4gKiAzLiB0aGF0IGZ1bGZpbGxlZCBhbmQgcmVqZWN0ZWQgd2lsbCBub3QgYmUgY2FsbGVkIGluIHRoaXMgdHVybi5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgICAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgdG8gb2JzZXJ2ZVxuICogQHBhcmFtIGZ1bGZpbGxlZCAgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdpdGggdGhlIGZ1bGZpbGxlZCB2YWx1ZVxuICogQHBhcmFtIHJlamVjdGVkICAgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdpdGggdGhlIHJlamVjdGlvbiBleGNlcHRpb25cbiAqIEBwYXJhbSBwcm9ncmVzc2VkIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCBvbiBhbnkgcHJvZ3Jlc3Mgbm90aWZpY2F0aW9uc1xuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlIGZyb20gdGhlIGludm9rZWQgY2FsbGJhY2tcbiAqL1xuUS53aGVuID0gd2hlbjtcbmZ1bmN0aW9uIHdoZW4odmFsdWUsIGZ1bGZpbGxlZCwgcmVqZWN0ZWQsIHByb2dyZXNzZWQpIHtcbiAgICByZXR1cm4gUSh2YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzc2VkKTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUudGhlblJlc29sdmUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHZhbHVlOyB9KTtcbn07XG5cblEudGhlblJlc29sdmUgPSBmdW5jdGlvbiAocHJvbWlzZSwgdmFsdWUpIHtcbiAgICByZXR1cm4gUShwcm9taXNlKS50aGVuUmVzb2x2ZSh2YWx1ZSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50aGVuUmVqZWN0ID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICAgIHJldHVybiB0aGlzLnRoZW4oZnVuY3Rpb24gKCkgeyB0aHJvdyByZWFzb247IH0pO1xufTtcblxuUS50aGVuUmVqZWN0ID0gZnVuY3Rpb24gKHByb21pc2UsIHJlYXNvbikge1xuICAgIHJldHVybiBRKHByb21pc2UpLnRoZW5SZWplY3QocmVhc29uKTtcbn07XG5cbi8qKlxuICogSWYgYW4gb2JqZWN0IGlzIG5vdCBhIHByb21pc2UsIGl0IGlzIGFzIFwibmVhclwiIGFzIHBvc3NpYmxlLlxuICogSWYgYSBwcm9taXNlIGlzIHJlamVjdGVkLCBpdCBpcyBhcyBcIm5lYXJcIiBhcyBwb3NzaWJsZSB0b28uXG4gKiBJZiBpdOKAmXMgYSBmdWxmaWxsZWQgcHJvbWlzZSwgdGhlIGZ1bGZpbGxtZW50IHZhbHVlIGlzIG5lYXJlci5cbiAqIElmIGl04oCZcyBhIGRlZmVycmVkIHByb21pc2UgYW5kIHRoZSBkZWZlcnJlZCBoYXMgYmVlbiByZXNvbHZlZCwgdGhlXG4gKiByZXNvbHV0aW9uIGlzIFwibmVhcmVyXCIuXG4gKiBAcGFyYW0gb2JqZWN0XG4gKiBAcmV0dXJucyBtb3N0IHJlc29sdmVkIChuZWFyZXN0KSBmb3JtIG9mIHRoZSBvYmplY3RcbiAqL1xuXG4vLyBYWFggc2hvdWxkIHdlIHJlLWRvIHRoaXM/XG5RLm5lYXJlciA9IG5lYXJlcjtcbmZ1bmN0aW9uIG5lYXJlcih2YWx1ZSkge1xuICAgIGlmIChpc1Byb21pc2UodmFsdWUpKSB7XG4gICAgICAgIHZhciBpbnNwZWN0ZWQgPSB2YWx1ZS5pbnNwZWN0KCk7XG4gICAgICAgIGlmIChpbnNwZWN0ZWQuc3RhdGUgPT09IFwiZnVsZmlsbGVkXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBpbnNwZWN0ZWQudmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xufVxuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHByb21pc2UuXG4gKiBPdGhlcndpc2UgaXQgaXMgYSBmdWxmaWxsZWQgdmFsdWUuXG4gKi9cblEuaXNQcm9taXNlID0gaXNQcm9taXNlO1xuZnVuY3Rpb24gaXNQcm9taXNlKG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgaW5zdGFuY2VvZiBQcm9taXNlO1xufVxuXG5RLmlzUHJvbWlzZUFsaWtlID0gaXNQcm9taXNlQWxpa2U7XG5mdW5jdGlvbiBpc1Byb21pc2VBbGlrZShvYmplY3QpIHtcbiAgICByZXR1cm4gaXNPYmplY3Qob2JqZWN0KSAmJiB0eXBlb2Ygb2JqZWN0LnRoZW4gPT09IFwiZnVuY3Rpb25cIjtcbn1cblxuLyoqXG4gKiBAcmV0dXJucyB3aGV0aGVyIHRoZSBnaXZlbiBvYmplY3QgaXMgYSBwZW5kaW5nIHByb21pc2UsIG1lYW5pbmcgbm90XG4gKiBmdWxmaWxsZWQgb3IgcmVqZWN0ZWQuXG4gKi9cblEuaXNQZW5kaW5nID0gaXNQZW5kaW5nO1xuZnVuY3Rpb24gaXNQZW5kaW5nKG9iamVjdCkge1xuICAgIHJldHVybiBpc1Byb21pc2Uob2JqZWN0KSAmJiBvYmplY3QuaW5zcGVjdCgpLnN0YXRlID09PSBcInBlbmRpbmdcIjtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuaXNQZW5kaW5nID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmluc3BlY3QoKS5zdGF0ZSA9PT0gXCJwZW5kaW5nXCI7XG59O1xuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHZhbHVlIG9yIGZ1bGZpbGxlZFxuICogcHJvbWlzZS5cbiAqL1xuUS5pc0Z1bGZpbGxlZCA9IGlzRnVsZmlsbGVkO1xuZnVuY3Rpb24gaXNGdWxmaWxsZWQob2JqZWN0KSB7XG4gICAgcmV0dXJuICFpc1Byb21pc2Uob2JqZWN0KSB8fCBvYmplY3QuaW5zcGVjdCgpLnN0YXRlID09PSBcImZ1bGZpbGxlZFwiO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5pc0Z1bGZpbGxlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5pbnNwZWN0KCkuc3RhdGUgPT09IFwiZnVsZmlsbGVkXCI7XG59O1xuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHJlamVjdGVkIHByb21pc2UuXG4gKi9cblEuaXNSZWplY3RlZCA9IGlzUmVqZWN0ZWQ7XG5mdW5jdGlvbiBpc1JlamVjdGVkKG9iamVjdCkge1xuICAgIHJldHVybiBpc1Byb21pc2Uob2JqZWN0KSAmJiBvYmplY3QuaW5zcGVjdCgpLnN0YXRlID09PSBcInJlamVjdGVkXCI7XG59XG5cblByb21pc2UucHJvdG90eXBlLmlzUmVqZWN0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuaW5zcGVjdCgpLnN0YXRlID09PSBcInJlamVjdGVkXCI7XG59O1xuXG4vLy8vIEJFR0lOIFVOSEFORExFRCBSRUpFQ1RJT04gVFJBQ0tJTkdcblxuLy8gVGhpcyBwcm9taXNlIGxpYnJhcnkgY29uc3VtZXMgZXhjZXB0aW9ucyB0aHJvd24gaW4gaGFuZGxlcnMgc28gdGhleSBjYW4gYmVcbi8vIGhhbmRsZWQgYnkgYSBzdWJzZXF1ZW50IHByb21pc2UuICBUaGUgZXhjZXB0aW9ucyBnZXQgYWRkZWQgdG8gdGhpcyBhcnJheSB3aGVuXG4vLyB0aGV5IGFyZSBjcmVhdGVkLCBhbmQgcmVtb3ZlZCB3aGVuIHRoZXkgYXJlIGhhbmRsZWQuICBOb3RlIHRoYXQgaW4gRVM2IG9yXG4vLyBzaGltbWVkIGVudmlyb25tZW50cywgdGhpcyB3b3VsZCBuYXR1cmFsbHkgYmUgYSBgU2V0YC5cbnZhciB1bmhhbmRsZWRSZWFzb25zID0gW107XG52YXIgdW5oYW5kbGVkUmVqZWN0aW9ucyA9IFtdO1xudmFyIHJlcG9ydGVkVW5oYW5kbGVkUmVqZWN0aW9ucyA9IFtdO1xudmFyIHRyYWNrVW5oYW5kbGVkUmVqZWN0aW9ucyA9IHRydWU7XG5cbmZ1bmN0aW9uIHJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucygpIHtcbiAgICB1bmhhbmRsZWRSZWFzb25zLmxlbmd0aCA9IDA7XG4gICAgdW5oYW5kbGVkUmVqZWN0aW9ucy5sZW5ndGggPSAwO1xuXG4gICAgaWYgKCF0cmFja1VuaGFuZGxlZFJlamVjdGlvbnMpIHtcbiAgICAgICAgdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zID0gdHJ1ZTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHRyYWNrUmVqZWN0aW9uKHByb21pc2UsIHJlYXNvbikge1xuICAgIGlmICghdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBwcm9jZXNzLmVtaXQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBRLm5leHRUaWNrLnJ1bkFmdGVyKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChhcnJheV9pbmRleE9mKHVuaGFuZGxlZFJlamVjdGlvbnMsIHByb21pc2UpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIHByb2Nlc3MuZW1pdChcInVuaGFuZGxlZFJlamVjdGlvblwiLCByZWFzb24sIHByb21pc2UpO1xuICAgICAgICAgICAgICAgIHJlcG9ydGVkVW5oYW5kbGVkUmVqZWN0aW9ucy5wdXNoKHByb21pc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICB1bmhhbmRsZWRSZWplY3Rpb25zLnB1c2gocHJvbWlzZSk7XG4gICAgaWYgKHJlYXNvbiAmJiB0eXBlb2YgcmVhc29uLnN0YWNrICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIHVuaGFuZGxlZFJlYXNvbnMucHVzaChyZWFzb24uc3RhY2spO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHVuaGFuZGxlZFJlYXNvbnMucHVzaChcIihubyBzdGFjaykgXCIgKyByZWFzb24pO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gdW50cmFja1JlamVjdGlvbihwcm9taXNlKSB7XG4gICAgaWYgKCF0cmFja1VuaGFuZGxlZFJlamVjdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBhdCA9IGFycmF5X2luZGV4T2YodW5oYW5kbGVkUmVqZWN0aW9ucywgcHJvbWlzZSk7XG4gICAgaWYgKGF0ICE9PSAtMSkge1xuICAgICAgICBpZiAodHlwZW9mIHByb2Nlc3MgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHByb2Nlc3MuZW1pdCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICBRLm5leHRUaWNrLnJ1bkFmdGVyKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgYXRSZXBvcnQgPSBhcnJheV9pbmRleE9mKHJlcG9ydGVkVW5oYW5kbGVkUmVqZWN0aW9ucywgcHJvbWlzZSk7XG4gICAgICAgICAgICAgICAgaWYgKGF0UmVwb3J0ICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICBwcm9jZXNzLmVtaXQoXCJyZWplY3Rpb25IYW5kbGVkXCIsIHVuaGFuZGxlZFJlYXNvbnNbYXRdLCBwcm9taXNlKTtcbiAgICAgICAgICAgICAgICAgICAgcmVwb3J0ZWRVbmhhbmRsZWRSZWplY3Rpb25zLnNwbGljZShhdFJlcG9ydCwgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdW5oYW5kbGVkUmVqZWN0aW9ucy5zcGxpY2UoYXQsIDEpO1xuICAgICAgICB1bmhhbmRsZWRSZWFzb25zLnNwbGljZShhdCwgMSk7XG4gICAgfVxufVxuXG5RLnJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucyA9IHJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucztcblxuUS5nZXRVbmhhbmRsZWRSZWFzb25zID0gZnVuY3Rpb24gKCkge1xuICAgIC8vIE1ha2UgYSBjb3B5IHNvIHRoYXQgY29uc3VtZXJzIGNhbid0IGludGVyZmVyZSB3aXRoIG91ciBpbnRlcm5hbCBzdGF0ZS5cbiAgICByZXR1cm4gdW5oYW5kbGVkUmVhc29ucy5zbGljZSgpO1xufTtcblxuUS5zdG9wVW5oYW5kbGVkUmVqZWN0aW9uVHJhY2tpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmVzZXRVbmhhbmRsZWRSZWplY3Rpb25zKCk7XG4gICAgdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zID0gZmFsc2U7XG59O1xuXG5yZXNldFVuaGFuZGxlZFJlamVjdGlvbnMoKTtcblxuLy8vLyBFTkQgVU5IQU5ETEVEIFJFSkVDVElPTiBUUkFDS0lOR1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSByZWplY3RlZCBwcm9taXNlLlxuICogQHBhcmFtIHJlYXNvbiB2YWx1ZSBkZXNjcmliaW5nIHRoZSBmYWlsdXJlXG4gKi9cblEucmVqZWN0ID0gcmVqZWN0O1xuZnVuY3Rpb24gcmVqZWN0KHJlYXNvbikge1xuICAgIHZhciByZWplY3Rpb24gPSBQcm9taXNlKHtcbiAgICAgICAgXCJ3aGVuXCI6IGZ1bmN0aW9uIChyZWplY3RlZCkge1xuICAgICAgICAgICAgLy8gbm90ZSB0aGF0IHRoZSBlcnJvciBoYXMgYmVlbiBoYW5kbGVkXG4gICAgICAgICAgICBpZiAocmVqZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICB1bnRyYWNrUmVqZWN0aW9uKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlamVjdGVkID8gcmVqZWN0ZWQocmVhc29uKSA6IHRoaXM7XG4gICAgICAgIH1cbiAgICB9LCBmdW5jdGlvbiBmYWxsYmFjaygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSwgZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgICAgICAgcmV0dXJuIHsgc3RhdGU6IFwicmVqZWN0ZWRcIiwgcmVhc29uOiByZWFzb24gfTtcbiAgICB9KTtcblxuICAgIC8vIE5vdGUgdGhhdCB0aGUgcmVhc29uIGhhcyBub3QgYmVlbiBoYW5kbGVkLlxuICAgIHRyYWNrUmVqZWN0aW9uKHJlamVjdGlvbiwgcmVhc29uKTtcblxuICAgIHJldHVybiByZWplY3Rpb247XG59XG5cbi8qKlxuICogQ29uc3RydWN0cyBhIGZ1bGZpbGxlZCBwcm9taXNlIGZvciBhbiBpbW1lZGlhdGUgcmVmZXJlbmNlLlxuICogQHBhcmFtIHZhbHVlIGltbWVkaWF0ZSByZWZlcmVuY2VcbiAqL1xuUS5mdWxmaWxsID0gZnVsZmlsbDtcbmZ1bmN0aW9uIGZ1bGZpbGwodmFsdWUpIHtcbiAgICByZXR1cm4gUHJvbWlzZSh7XG4gICAgICAgIFwid2hlblwiOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH0sXG4gICAgICAgIFwiZ2V0XCI6IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWVbbmFtZV07XG4gICAgICAgIH0sXG4gICAgICAgIFwic2V0XCI6IGZ1bmN0aW9uIChuYW1lLCByaHMpIHtcbiAgICAgICAgICAgIHZhbHVlW25hbWVdID0gcmhzO1xuICAgICAgICB9LFxuICAgICAgICBcImRlbGV0ZVwiOiBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICAgICAgZGVsZXRlIHZhbHVlW25hbWVdO1xuICAgICAgICB9LFxuICAgICAgICBcInBvc3RcIjogZnVuY3Rpb24gKG5hbWUsIGFyZ3MpIHtcbiAgICAgICAgICAgIC8vIE1hcmsgTWlsbGVyIHByb3Bvc2VzIHRoYXQgcG9zdCB3aXRoIG5vIG5hbWUgc2hvdWxkIGFwcGx5IGFcbiAgICAgICAgICAgIC8vIHByb21pc2VkIGZ1bmN0aW9uLlxuICAgICAgICAgICAgaWYgKG5hbWUgPT09IG51bGwgfHwgbmFtZSA9PT0gdm9pZCAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLmFwcGx5KHZvaWQgMCwgYXJncyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZVtuYW1lXS5hcHBseSh2YWx1ZSwgYXJncyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIFwiYXBwbHlcIjogZnVuY3Rpb24gKHRoaXNwLCBhcmdzKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWUuYXBwbHkodGhpc3AsIGFyZ3MpO1xuICAgICAgICB9LFxuICAgICAgICBcImtleXNcIjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIG9iamVjdF9rZXlzKHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH0sIHZvaWQgMCwgZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgICAgICAgcmV0dXJuIHsgc3RhdGU6IFwiZnVsZmlsbGVkXCIsIHZhbHVlOiB2YWx1ZSB9O1xuICAgIH0pO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIHRoZW5hYmxlcyB0byBRIHByb21pc2VzLlxuICogQHBhcmFtIHByb21pc2UgdGhlbmFibGUgcHJvbWlzZVxuICogQHJldHVybnMgYSBRIHByb21pc2VcbiAqL1xuZnVuY3Rpb24gY29lcmNlKHByb21pc2UpIHtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcHJvbWlzZS50aGVuKGRlZmVycmVkLnJlc29sdmUsIGRlZmVycmVkLnJlamVjdCwgZGVmZXJyZWQubm90aWZ5KTtcbiAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufVxuXG4vKipcbiAqIEFubm90YXRlcyBhbiBvYmplY3Qgc3VjaCB0aGF0IGl0IHdpbGwgbmV2ZXIgYmVcbiAqIHRyYW5zZmVycmVkIGF3YXkgZnJvbSB0aGlzIHByb2Nlc3Mgb3ZlciBhbnkgcHJvbWlzZVxuICogY29tbXVuaWNhdGlvbiBjaGFubmVsLlxuICogQHBhcmFtIG9iamVjdFxuICogQHJldHVybnMgcHJvbWlzZSBhIHdyYXBwaW5nIG9mIHRoYXQgb2JqZWN0IHRoYXRcbiAqIGFkZGl0aW9uYWxseSByZXNwb25kcyB0byB0aGUgXCJpc0RlZlwiIG1lc3NhZ2VcbiAqIHdpdGhvdXQgYSByZWplY3Rpb24uXG4gKi9cblEubWFzdGVyID0gbWFzdGVyO1xuZnVuY3Rpb24gbWFzdGVyKG9iamVjdCkge1xuICAgIHJldHVybiBQcm9taXNlKHtcbiAgICAgICAgXCJpc0RlZlwiOiBmdW5jdGlvbiAoKSB7fVxuICAgIH0sIGZ1bmN0aW9uIGZhbGxiYWNrKG9wLCBhcmdzKSB7XG4gICAgICAgIHJldHVybiBkaXNwYXRjaChvYmplY3QsIG9wLCBhcmdzKTtcbiAgICB9LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBRKG9iamVjdCkuaW5zcGVjdCgpO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIFNwcmVhZHMgdGhlIHZhbHVlcyBvZiBhIHByb21pc2VkIGFycmF5IG9mIGFyZ3VtZW50cyBpbnRvIHRoZVxuICogZnVsZmlsbG1lbnQgY2FsbGJhY2suXG4gKiBAcGFyYW0gZnVsZmlsbGVkIGNhbGxiYWNrIHRoYXQgcmVjZWl2ZXMgdmFyaWFkaWMgYXJndW1lbnRzIGZyb20gdGhlXG4gKiBwcm9taXNlZCBhcnJheVxuICogQHBhcmFtIHJlamVjdGVkIGNhbGxiYWNrIHRoYXQgcmVjZWl2ZXMgdGhlIGV4Y2VwdGlvbiBpZiB0aGUgcHJvbWlzZVxuICogaXMgcmVqZWN0ZWQuXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWUgb3IgdGhyb3duIGV4Y2VwdGlvbiBvZlxuICogZWl0aGVyIGNhbGxiYWNrLlxuICovXG5RLnNwcmVhZCA9IHNwcmVhZDtcbmZ1bmN0aW9uIHNwcmVhZCh2YWx1ZSwgZnVsZmlsbGVkLCByZWplY3RlZCkge1xuICAgIHJldHVybiBRKHZhbHVlKS5zcHJlYWQoZnVsZmlsbGVkLCByZWplY3RlZCk7XG59XG5cblByb21pc2UucHJvdG90eXBlLnNwcmVhZCA9IGZ1bmN0aW9uIChmdWxmaWxsZWQsIHJlamVjdGVkKSB7XG4gICAgcmV0dXJuIHRoaXMuYWxsKCkudGhlbihmdW5jdGlvbiAoYXJyYXkpIHtcbiAgICAgICAgcmV0dXJuIGZ1bGZpbGxlZC5hcHBseSh2b2lkIDAsIGFycmF5KTtcbiAgICB9LCByZWplY3RlZCk7XG59O1xuXG4vKipcbiAqIFRoZSBhc3luYyBmdW5jdGlvbiBpcyBhIGRlY29yYXRvciBmb3IgZ2VuZXJhdG9yIGZ1bmN0aW9ucywgdHVybmluZ1xuICogdGhlbSBpbnRvIGFzeW5jaHJvbm91cyBnZW5lcmF0b3JzLiAgQWx0aG91Z2ggZ2VuZXJhdG9ycyBhcmUgb25seSBwYXJ0XG4gKiBvZiB0aGUgbmV3ZXN0IEVDTUFTY3JpcHQgNiBkcmFmdHMsIHRoaXMgY29kZSBkb2VzIG5vdCBjYXVzZSBzeW50YXhcbiAqIGVycm9ycyBpbiBvbGRlciBlbmdpbmVzLiAgVGhpcyBjb2RlIHNob3VsZCBjb250aW51ZSB0byB3b3JrIGFuZCB3aWxsXG4gKiBpbiBmYWN0IGltcHJvdmUgb3ZlciB0aW1lIGFzIHRoZSBsYW5ndWFnZSBpbXByb3Zlcy5cbiAqXG4gKiBFUzYgZ2VuZXJhdG9ycyBhcmUgY3VycmVudGx5IHBhcnQgb2YgVjggdmVyc2lvbiAzLjE5IHdpdGggdGhlXG4gKiAtLWhhcm1vbnktZ2VuZXJhdG9ycyBydW50aW1lIGZsYWcgZW5hYmxlZC4gIFNwaWRlck1vbmtleSBoYXMgaGFkIHRoZW1cbiAqIGZvciBsb25nZXIsIGJ1dCB1bmRlciBhbiBvbGRlciBQeXRob24taW5zcGlyZWQgZm9ybS4gIFRoaXMgZnVuY3Rpb25cbiAqIHdvcmtzIG9uIGJvdGgga2luZHMgb2YgZ2VuZXJhdG9ycy5cbiAqXG4gKiBEZWNvcmF0ZXMgYSBnZW5lcmF0b3IgZnVuY3Rpb24gc3VjaCB0aGF0OlxuICogIC0gaXQgbWF5IHlpZWxkIHByb21pc2VzXG4gKiAgLSBleGVjdXRpb24gd2lsbCBjb250aW51ZSB3aGVuIHRoYXQgcHJvbWlzZSBpcyBmdWxmaWxsZWRcbiAqICAtIHRoZSB2YWx1ZSBvZiB0aGUgeWllbGQgZXhwcmVzc2lvbiB3aWxsIGJlIHRoZSBmdWxmaWxsZWQgdmFsdWVcbiAqICAtIGl0IHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlICh3aGVuIHRoZSBnZW5lcmF0b3JcbiAqICAgIHN0b3BzIGl0ZXJhdGluZylcbiAqICAtIHRoZSBkZWNvcmF0ZWQgZnVuY3Rpb24gcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqICAgIG9mIHRoZSBnZW5lcmF0b3Igb3IgdGhlIGZpcnN0IHJlamVjdGVkIHByb21pc2UgYW1vbmcgdGhvc2VcbiAqICAgIHlpZWxkZWQuXG4gKiAgLSBpZiBhbiBlcnJvciBpcyB0aHJvd24gaW4gdGhlIGdlbmVyYXRvciwgaXQgcHJvcGFnYXRlcyB0aHJvdWdoXG4gKiAgICBldmVyeSBmb2xsb3dpbmcgeWllbGQgdW50aWwgaXQgaXMgY2F1Z2h0LCBvciB1bnRpbCBpdCBlc2NhcGVzXG4gKiAgICB0aGUgZ2VuZXJhdG9yIGZ1bmN0aW9uIGFsdG9nZXRoZXIsIGFuZCBpcyB0cmFuc2xhdGVkIGludG8gYVxuICogICAgcmVqZWN0aW9uIGZvciB0aGUgcHJvbWlzZSByZXR1cm5lZCBieSB0aGUgZGVjb3JhdGVkIGdlbmVyYXRvci5cbiAqL1xuUS5hc3luYyA9IGFzeW5jO1xuZnVuY3Rpb24gYXN5bmMobWFrZUdlbmVyYXRvcikge1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIHdoZW4gdmVyYiBpcyBcInNlbmRcIiwgYXJnIGlzIGEgdmFsdWVcbiAgICAgICAgLy8gd2hlbiB2ZXJiIGlzIFwidGhyb3dcIiwgYXJnIGlzIGFuIGV4Y2VwdGlvblxuICAgICAgICBmdW5jdGlvbiBjb250aW51ZXIodmVyYiwgYXJnKSB7XG4gICAgICAgICAgICB2YXIgcmVzdWx0O1xuXG4gICAgICAgICAgICAvLyBVbnRpbCBWOCAzLjE5IC8gQ2hyb21pdW0gMjkgaXMgcmVsZWFzZWQsIFNwaWRlck1vbmtleSBpcyB0aGUgb25seVxuICAgICAgICAgICAgLy8gZW5naW5lIHRoYXQgaGFzIGEgZGVwbG95ZWQgYmFzZSBvZiBicm93c2VycyB0aGF0IHN1cHBvcnQgZ2VuZXJhdG9ycy5cbiAgICAgICAgICAgIC8vIEhvd2V2ZXIsIFNNJ3MgZ2VuZXJhdG9ycyB1c2UgdGhlIFB5dGhvbi1pbnNwaXJlZCBzZW1hbnRpY3Mgb2ZcbiAgICAgICAgICAgIC8vIG91dGRhdGVkIEVTNiBkcmFmdHMuICBXZSB3b3VsZCBsaWtlIHRvIHN1cHBvcnQgRVM2LCBidXQgd2UnZCBhbHNvXG4gICAgICAgICAgICAvLyBsaWtlIHRvIG1ha2UgaXQgcG9zc2libGUgdG8gdXNlIGdlbmVyYXRvcnMgaW4gZGVwbG95ZWQgYnJvd3NlcnMsIHNvXG4gICAgICAgICAgICAvLyB3ZSBhbHNvIHN1cHBvcnQgUHl0aG9uLXN0eWxlIGdlbmVyYXRvcnMuICBBdCBzb21lIHBvaW50IHdlIGNhbiByZW1vdmVcbiAgICAgICAgICAgIC8vIHRoaXMgYmxvY2suXG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgU3RvcEl0ZXJhdGlvbiA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgICAgIC8vIEVTNiBHZW5lcmF0b3JzXG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gZ2VuZXJhdG9yW3ZlcmJdKGFyZyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5kb25lKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBRKHJlc3VsdC52YWx1ZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHdoZW4ocmVzdWx0LnZhbHVlLCBjYWxsYmFjaywgZXJyYmFjayk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBTcGlkZXJNb25rZXkgR2VuZXJhdG9yc1xuICAgICAgICAgICAgICAgIC8vIEZJWE1FOiBSZW1vdmUgdGhpcyBjYXNlIHdoZW4gU00gZG9lcyBFUzYgZ2VuZXJhdG9ycy5cbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBnZW5lcmF0b3JbdmVyYl0oYXJnKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzU3RvcEl0ZXJhdGlvbihleGNlcHRpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUShleGNlcHRpb24udmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChleGNlcHRpb24pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB3aGVuKHJlc3VsdCwgY2FsbGJhY2ssIGVycmJhY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHZhciBnZW5lcmF0b3IgPSBtYWtlR2VuZXJhdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIHZhciBjYWxsYmFjayA9IGNvbnRpbnVlci5iaW5kKGNvbnRpbnVlciwgXCJuZXh0XCIpO1xuICAgICAgICB2YXIgZXJyYmFjayA9IGNvbnRpbnVlci5iaW5kKGNvbnRpbnVlciwgXCJ0aHJvd1wiKTtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgfTtcbn1cblxuLyoqXG4gKiBUaGUgc3Bhd24gZnVuY3Rpb24gaXMgYSBzbWFsbCB3cmFwcGVyIGFyb3VuZCBhc3luYyB0aGF0IGltbWVkaWF0ZWx5XG4gKiBjYWxscyB0aGUgZ2VuZXJhdG9yIGFuZCBhbHNvIGVuZHMgdGhlIHByb21pc2UgY2hhaW4sIHNvIHRoYXQgYW55XG4gKiB1bmhhbmRsZWQgZXJyb3JzIGFyZSB0aHJvd24gaW5zdGVhZCBvZiBmb3J3YXJkZWQgdG8gdGhlIGVycm9yXG4gKiBoYW5kbGVyLiBUaGlzIGlzIHVzZWZ1bCBiZWNhdXNlIGl0J3MgZXh0cmVtZWx5IGNvbW1vbiB0byBydW5cbiAqIGdlbmVyYXRvcnMgYXQgdGhlIHRvcC1sZXZlbCB0byB3b3JrIHdpdGggbGlicmFyaWVzLlxuICovXG5RLnNwYXduID0gc3Bhd247XG5mdW5jdGlvbiBzcGF3bihtYWtlR2VuZXJhdG9yKSB7XG4gICAgUS5kb25lKFEuYXN5bmMobWFrZUdlbmVyYXRvcikoKSk7XG59XG5cbi8vIEZJWE1FOiBSZW1vdmUgdGhpcyBpbnRlcmZhY2Ugb25jZSBFUzYgZ2VuZXJhdG9ycyBhcmUgaW4gU3BpZGVyTW9ua2V5LlxuLyoqXG4gKiBUaHJvd3MgYSBSZXR1cm5WYWx1ZSBleGNlcHRpb24gdG8gc3RvcCBhbiBhc3luY2hyb25vdXMgZ2VuZXJhdG9yLlxuICpcbiAqIFRoaXMgaW50ZXJmYWNlIGlzIGEgc3RvcC1nYXAgbWVhc3VyZSB0byBzdXBwb3J0IGdlbmVyYXRvciByZXR1cm5cbiAqIHZhbHVlcyBpbiBvbGRlciBGaXJlZm94L1NwaWRlck1vbmtleS4gIEluIGJyb3dzZXJzIHRoYXQgc3VwcG9ydCBFUzZcbiAqIGdlbmVyYXRvcnMgbGlrZSBDaHJvbWl1bSAyOSwganVzdCB1c2UgXCJyZXR1cm5cIiBpbiB5b3VyIGdlbmVyYXRvclxuICogZnVuY3Rpb25zLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSB0aGUgcmV0dXJuIHZhbHVlIGZvciB0aGUgc3Vycm91bmRpbmcgZ2VuZXJhdG9yXG4gKiBAdGhyb3dzIFJldHVyblZhbHVlIGV4Y2VwdGlvbiB3aXRoIHRoZSB2YWx1ZS5cbiAqIEBleGFtcGxlXG4gKiAvLyBFUzYgc3R5bGVcbiAqIFEuYXN5bmMoZnVuY3Rpb24qICgpIHtcbiAqICAgICAgdmFyIGZvbyA9IHlpZWxkIGdldEZvb1Byb21pc2UoKTtcbiAqICAgICAgdmFyIGJhciA9IHlpZWxkIGdldEJhclByb21pc2UoKTtcbiAqICAgICAgcmV0dXJuIGZvbyArIGJhcjtcbiAqIH0pXG4gKiAvLyBPbGRlciBTcGlkZXJNb25rZXkgc3R5bGVcbiAqIFEuYXN5bmMoZnVuY3Rpb24gKCkge1xuICogICAgICB2YXIgZm9vID0geWllbGQgZ2V0Rm9vUHJvbWlzZSgpO1xuICogICAgICB2YXIgYmFyID0geWllbGQgZ2V0QmFyUHJvbWlzZSgpO1xuICogICAgICBRLnJldHVybihmb28gKyBiYXIpO1xuICogfSlcbiAqL1xuUVtcInJldHVyblwiXSA9IF9yZXR1cm47XG5mdW5jdGlvbiBfcmV0dXJuKHZhbHVlKSB7XG4gICAgdGhyb3cgbmV3IFFSZXR1cm5WYWx1ZSh2YWx1ZSk7XG59XG5cbi8qKlxuICogVGhlIHByb21pc2VkIGZ1bmN0aW9uIGRlY29yYXRvciBlbnN1cmVzIHRoYXQgYW55IHByb21pc2UgYXJndW1lbnRzXG4gKiBhcmUgc2V0dGxlZCBhbmQgcGFzc2VkIGFzIHZhbHVlcyAoYHRoaXNgIGlzIGFsc28gc2V0dGxlZCBhbmQgcGFzc2VkXG4gKiBhcyBhIHZhbHVlKS4gIEl0IHdpbGwgYWxzbyBlbnN1cmUgdGhhdCB0aGUgcmVzdWx0IG9mIGEgZnVuY3Rpb24gaXNcbiAqIGFsd2F5cyBhIHByb21pc2UuXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBhZGQgPSBRLnByb21pc2VkKGZ1bmN0aW9uIChhLCBiKSB7XG4gKiAgICAgcmV0dXJuIGEgKyBiO1xuICogfSk7XG4gKiBhZGQoUShhKSwgUShCKSk7XG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIHRvIGRlY29yYXRlXG4gKiBAcmV0dXJucyB7ZnVuY3Rpb259IGEgZnVuY3Rpb24gdGhhdCBoYXMgYmVlbiBkZWNvcmF0ZWQuXG4gKi9cblEucHJvbWlzZWQgPSBwcm9taXNlZDtcbmZ1bmN0aW9uIHByb21pc2VkKGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHNwcmVhZChbdGhpcywgYWxsKGFyZ3VtZW50cyldLCBmdW5jdGlvbiAoc2VsZiwgYXJncykge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KHNlbGYsIGFyZ3MpO1xuICAgICAgICB9KTtcbiAgICB9O1xufVxuXG4vKipcbiAqIHNlbmRzIGEgbWVzc2FnZSB0byBhIHZhbHVlIGluIGEgZnV0dXJlIHR1cm5cbiAqIEBwYXJhbSBvYmplY3QqIHRoZSByZWNpcGllbnRcbiAqIEBwYXJhbSBvcCB0aGUgbmFtZSBvZiB0aGUgbWVzc2FnZSBvcGVyYXRpb24sIGUuZy4sIFwid2hlblwiLFxuICogQHBhcmFtIGFyZ3MgZnVydGhlciBhcmd1bWVudHMgdG8gYmUgZm9yd2FyZGVkIHRvIHRoZSBvcGVyYXRpb25cbiAqIEByZXR1cm5zIHJlc3VsdCB7UHJvbWlzZX0gYSBwcm9taXNlIGZvciB0aGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb25cbiAqL1xuUS5kaXNwYXRjaCA9IGRpc3BhdGNoO1xuZnVuY3Rpb24gZGlzcGF0Y2gob2JqZWN0LCBvcCwgYXJncykge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2gob3AsIGFyZ3MpO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5kaXNwYXRjaCA9IGZ1bmN0aW9uIChvcCwgYXJncykge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICBzZWxmLnByb21pc2VEaXNwYXRjaChkZWZlcnJlZC5yZXNvbHZlLCBvcCwgYXJncyk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIEdldHMgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgcHJvcGVydHkgdG8gZ2V0XG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSBwcm9wZXJ0eSB2YWx1ZVxuICovXG5RLmdldCA9IGZ1bmN0aW9uIChvYmplY3QsIGtleSkge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2goXCJnZXRcIiwgW2tleV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKGtleSkge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwiZ2V0XCIsIFtrZXldKTtcbn07XG5cbi8qKlxuICogU2V0cyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eSBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIG9iamVjdCBvYmplY3RcbiAqIEBwYXJhbSBuYW1lICAgICAgbmFtZSBvZiBwcm9wZXJ0eSB0byBzZXRcbiAqIEBwYXJhbSB2YWx1ZSAgICAgbmV3IHZhbHVlIG9mIHByb3BlcnR5XG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqL1xuUS5zZXQgPSBmdW5jdGlvbiAob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcInNldFwiLCBba2V5LCB2YWx1ZV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcInNldFwiLCBba2V5LCB2YWx1ZV0pO1xufTtcblxuLyoqXG4gKiBEZWxldGVzIGEgcHJvcGVydHkgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgcHJvcGVydHkgdG8gZGVsZXRlXG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqL1xuUS5kZWwgPSAvLyBYWFggbGVnYWN5XG5RW1wiZGVsZXRlXCJdID0gZnVuY3Rpb24gKG9iamVjdCwga2V5KSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImRlbGV0ZVwiLCBba2V5XSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5kZWwgPSAvLyBYWFggbGVnYWN5XG5Qcm9taXNlLnByb3RvdHlwZVtcImRlbGV0ZVwiXSA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImRlbGV0ZVwiLCBba2V5XSk7XG59O1xuXG4vKipcbiAqIEludm9rZXMgYSBtZXRob2QgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgbWV0aG9kIHRvIGludm9rZVxuICogQHBhcmFtIHZhbHVlICAgICBhIHZhbHVlIHRvIHBvc3QsIHR5cGljYWxseSBhbiBhcnJheSBvZlxuICogICAgICAgICAgICAgICAgICBpbnZvY2F0aW9uIGFyZ3VtZW50cyBmb3IgcHJvbWlzZXMgdGhhdFxuICogICAgICAgICAgICAgICAgICBhcmUgdWx0aW1hdGVseSBiYWNrZWQgd2l0aCBgcmVzb2x2ZWAgdmFsdWVzLFxuICogICAgICAgICAgICAgICAgICBhcyBvcHBvc2VkIHRvIHRob3NlIGJhY2tlZCB3aXRoIFVSTHNcbiAqICAgICAgICAgICAgICAgICAgd2hlcmVpbiB0aGUgcG9zdGVkIHZhbHVlIGNhbiBiZSBhbnlcbiAqICAgICAgICAgICAgICAgICAgSlNPTiBzZXJpYWxpemFibGUgb2JqZWN0LlxuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlXG4gKi9cbi8vIGJvdW5kIGxvY2FsbHkgYmVjYXVzZSBpdCBpcyB1c2VkIGJ5IG90aGVyIG1ldGhvZHNcblEubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblEucG9zdCA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWUsIGFyZ3MpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJnc10pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblByb21pc2UucHJvdG90eXBlLnBvc3QgPSBmdW5jdGlvbiAobmFtZSwgYXJncykge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJnc10pO1xufTtcblxuLyoqXG4gKiBJbnZva2VzIGEgbWV0aG9kIGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IG9iamVjdFxuICogQHBhcmFtIG5hbWUgICAgICBuYW1lIG9mIG1ldGhvZCB0byBpbnZva2VcbiAqIEBwYXJhbSAuLi5hcmdzICAgYXJyYXkgb2YgaW52b2NhdGlvbiBhcmd1bWVudHNcbiAqIEByZXR1cm4gcHJvbWlzZSBmb3IgdGhlIHJldHVybiB2YWx1ZVxuICovXG5RLnNlbmQgPSAvLyBYWFggTWFyayBNaWxsZXIncyBwcm9wb3NlZCBwYXJsYW5jZVxuUS5tY2FsbCA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5RLmludm9rZSA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWUgLyouLi5hcmdzKi8pIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAyKV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuc2VuZCA9IC8vIFhYWCBNYXJrIE1pbGxlcidzIHByb3Bvc2VkIHBhcmxhbmNlXG5Qcm9taXNlLnByb3RvdHlwZS5tY2FsbCA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5Qcm9taXNlLnByb3RvdHlwZS5pbnZva2UgPSBmdW5jdGlvbiAobmFtZSAvKi4uLmFyZ3MqLykge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKV0pO1xufTtcblxuLyoqXG4gKiBBcHBsaWVzIHRoZSBwcm9taXNlZCBmdW5jdGlvbiBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBmdW5jdGlvblxuICogQHBhcmFtIGFyZ3MgICAgICBhcnJheSBvZiBhcHBsaWNhdGlvbiBhcmd1bWVudHNcbiAqL1xuUS5mYXBwbHkgPSBmdW5jdGlvbiAob2JqZWN0LCBhcmdzKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImFwcGx5XCIsIFt2b2lkIDAsIGFyZ3NdKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmZhcHBseSA9IGZ1bmN0aW9uIChhcmdzKSB7XG4gICAgcmV0dXJuIHRoaXMuZGlzcGF0Y2goXCJhcHBseVwiLCBbdm9pZCAwLCBhcmdzXSk7XG59O1xuXG4vKipcbiAqIENhbGxzIHRoZSBwcm9taXNlZCBmdW5jdGlvbiBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBmdW5jdGlvblxuICogQHBhcmFtIC4uLmFyZ3MgICBhcnJheSBvZiBhcHBsaWNhdGlvbiBhcmd1bWVudHNcbiAqL1xuUVtcInRyeVwiXSA9XG5RLmZjYWxsID0gZnVuY3Rpb24gKG9iamVjdCAvKiAuLi5hcmdzKi8pIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwiYXBwbHlcIiwgW3ZvaWQgMCwgYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZmNhbGwgPSBmdW5jdGlvbiAoLyouLi5hcmdzKi8pIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImFwcGx5XCIsIFt2b2lkIDAsIGFycmF5X3NsaWNlKGFyZ3VtZW50cyldKTtcbn07XG5cbi8qKlxuICogQmluZHMgdGhlIHByb21pc2VkIGZ1bmN0aW9uLCB0cmFuc2Zvcm1pbmcgcmV0dXJuIHZhbHVlcyBpbnRvIGEgZnVsZmlsbGVkXG4gKiBwcm9taXNlIGFuZCB0aHJvd24gZXJyb3JzIGludG8gYSByZWplY3RlZCBvbmUuXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IGZ1bmN0aW9uXG4gKiBAcGFyYW0gLi4uYXJncyAgIGFycmF5IG9mIGFwcGxpY2F0aW9uIGFyZ3VtZW50c1xuICovXG5RLmZiaW5kID0gZnVuY3Rpb24gKG9iamVjdCAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBwcm9taXNlID0gUShvYmplY3QpO1xuICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gZmJvdW5kKCkge1xuICAgICAgICByZXR1cm4gcHJvbWlzZS5kaXNwYXRjaChcImFwcGx5XCIsIFtcbiAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICBhcmdzLmNvbmNhdChhcnJheV9zbGljZShhcmd1bWVudHMpKVxuICAgICAgICBdKTtcbiAgICB9O1xufTtcblByb21pc2UucHJvdG90eXBlLmZiaW5kID0gZnVuY3Rpb24gKC8qLi4uYXJncyovKSB7XG4gICAgdmFyIHByb21pc2UgPSB0aGlzO1xuICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gZmJvdW5kKCkge1xuICAgICAgICByZXR1cm4gcHJvbWlzZS5kaXNwYXRjaChcImFwcGx5XCIsIFtcbiAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICBhcmdzLmNvbmNhdChhcnJheV9zbGljZShhcmd1bWVudHMpKVxuICAgICAgICBdKTtcbiAgICB9O1xufTtcblxuLyoqXG4gKiBSZXF1ZXN0cyB0aGUgbmFtZXMgb2YgdGhlIG93bmVkIHByb3BlcnRpZXMgb2YgYSBwcm9taXNlZFxuICogb2JqZWN0IGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IG9iamVjdFxuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUga2V5cyBvZiB0aGUgZXZlbnR1YWxseSBzZXR0bGVkIG9iamVjdFxuICovXG5RLmtleXMgPSBmdW5jdGlvbiAob2JqZWN0KSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImtleXNcIiwgW10pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUua2V5cyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImtleXNcIiwgW10pO1xufTtcblxuLyoqXG4gKiBUdXJucyBhbiBhcnJheSBvZiBwcm9taXNlcyBpbnRvIGEgcHJvbWlzZSBmb3IgYW4gYXJyYXkuICBJZiBhbnkgb2ZcbiAqIHRoZSBwcm9taXNlcyBnZXRzIHJlamVjdGVkLCB0aGUgd2hvbGUgYXJyYXkgaXMgcmVqZWN0ZWQgaW1tZWRpYXRlbHkuXG4gKiBAcGFyYW0ge0FycmF5Kn0gYW4gYXJyYXkgKG9yIHByb21pc2UgZm9yIGFuIGFycmF5KSBvZiB2YWx1ZXMgKG9yXG4gKiBwcm9taXNlcyBmb3IgdmFsdWVzKVxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciBhbiBhcnJheSBvZiB0aGUgY29ycmVzcG9uZGluZyB2YWx1ZXNcbiAqL1xuLy8gQnkgTWFyayBNaWxsZXJcbi8vIGh0dHA6Ly93aWtpLmVjbWFzY3JpcHQub3JnL2Rva3UucGhwP2lkPXN0cmF3bWFuOmNvbmN1cnJlbmN5JnJldj0xMzA4Nzc2NTIxI2FsbGZ1bGZpbGxlZFxuUS5hbGwgPSBhbGw7XG5mdW5jdGlvbiBhbGwocHJvbWlzZXMpIHtcbiAgICByZXR1cm4gd2hlbihwcm9taXNlcywgZnVuY3Rpb24gKHByb21pc2VzKSB7XG4gICAgICAgIHZhciBwZW5kaW5nQ291bnQgPSAwO1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBhcnJheV9yZWR1Y2UocHJvbWlzZXMsIGZ1bmN0aW9uICh1bmRlZmluZWQsIHByb21pc2UsIGluZGV4KSB7XG4gICAgICAgICAgICB2YXIgc25hcHNob3Q7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgaXNQcm9taXNlKHByb21pc2UpICYmXG4gICAgICAgICAgICAgICAgKHNuYXBzaG90ID0gcHJvbWlzZS5pbnNwZWN0KCkpLnN0YXRlID09PSBcImZ1bGZpbGxlZFwiXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBwcm9taXNlc1tpbmRleF0gPSBzbmFwc2hvdC52YWx1ZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgKytwZW5kaW5nQ291bnQ7XG4gICAgICAgICAgICAgICAgd2hlbihcbiAgICAgICAgICAgICAgICAgICAgcHJvbWlzZSxcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9taXNlc1tpbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgtLXBlbmRpbmdDb3VudCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUocHJvbWlzZXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBkZWZlcnJlZC5yZWplY3QsXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIChwcm9ncmVzcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVmZXJyZWQubm90aWZ5KHsgaW5kZXg6IGluZGV4LCB2YWx1ZTogcHJvZ3Jlc3MgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCB2b2lkIDApO1xuICAgICAgICBpZiAocGVuZGluZ0NvdW50ID09PSAwKSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHByb21pc2VzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9KTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuYWxsID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBhbGwodGhpcyk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGZpcnN0IHJlc29sdmVkIHByb21pc2Ugb2YgYW4gYXJyYXkuIFByaW9yIHJlamVjdGVkIHByb21pc2VzIGFyZVxuICogaWdub3JlZC4gIFJlamVjdHMgb25seSBpZiBhbGwgcHJvbWlzZXMgYXJlIHJlamVjdGVkLlxuICogQHBhcmFtIHtBcnJheSp9IGFuIGFycmF5IGNvbnRhaW5pbmcgdmFsdWVzIG9yIHByb21pc2VzIGZvciB2YWx1ZXNcbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmdWxmaWxsZWQgd2l0aCB0aGUgdmFsdWUgb2YgdGhlIGZpcnN0IHJlc29sdmVkIHByb21pc2UsXG4gKiBvciBhIHJlamVjdGVkIHByb21pc2UgaWYgYWxsIHByb21pc2VzIGFyZSByZWplY3RlZC5cbiAqL1xuUS5hbnkgPSBhbnk7XG5cbmZ1bmN0aW9uIGFueShwcm9taXNlcykge1xuICAgIGlmIChwcm9taXNlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIFEucmVzb2x2ZSgpO1xuICAgIH1cblxuICAgIHZhciBkZWZlcnJlZCA9IFEuZGVmZXIoKTtcbiAgICB2YXIgcGVuZGluZ0NvdW50ID0gMDtcbiAgICBhcnJheV9yZWR1Y2UocHJvbWlzZXMsIGZ1bmN0aW9uIChwcmV2LCBjdXJyZW50LCBpbmRleCkge1xuICAgICAgICB2YXIgcHJvbWlzZSA9IHByb21pc2VzW2luZGV4XTtcblxuICAgICAgICBwZW5kaW5nQ291bnQrKztcblxuICAgICAgICB3aGVuKHByb21pc2UsIG9uRnVsZmlsbGVkLCBvblJlamVjdGVkLCBvblByb2dyZXNzKTtcbiAgICAgICAgZnVuY3Rpb24gb25GdWxmaWxsZWQocmVzdWx0KSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gb25SZWplY3RlZCgpIHtcbiAgICAgICAgICAgIHBlbmRpbmdDb3VudC0tO1xuICAgICAgICAgICAgaWYgKHBlbmRpbmdDb3VudCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlamVjdChuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIFwiQ2FuJ3QgZ2V0IGZ1bGZpbGxtZW50IHZhbHVlIGZyb20gYW55IHByb21pc2UsIGFsbCBcIiArXG4gICAgICAgICAgICAgICAgICAgIFwicHJvbWlzZXMgd2VyZSByZWplY3RlZC5cIlxuICAgICAgICAgICAgICAgICkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIG9uUHJvZ3Jlc3MocHJvZ3Jlc3MpIHtcbiAgICAgICAgICAgIGRlZmVycmVkLm5vdGlmeSh7XG4gICAgICAgICAgICAgICAgaW5kZXg6IGluZGV4LFxuICAgICAgICAgICAgICAgIHZhbHVlOiBwcm9ncmVzc1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9LCB1bmRlZmluZWQpO1xuXG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59XG5cblByb21pc2UucHJvdG90eXBlLmFueSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYW55KHRoaXMpO1xufTtcblxuLyoqXG4gKiBXYWl0cyBmb3IgYWxsIHByb21pc2VzIHRvIGJlIHNldHRsZWQsIGVpdGhlciBmdWxmaWxsZWQgb3JcbiAqIHJlamVjdGVkLiAgVGhpcyBpcyBkaXN0aW5jdCBmcm9tIGBhbGxgIHNpbmNlIHRoYXQgd291bGQgc3RvcFxuICogd2FpdGluZyBhdCB0aGUgZmlyc3QgcmVqZWN0aW9uLiAgVGhlIHByb21pc2UgcmV0dXJuZWQgYnlcbiAqIGBhbGxSZXNvbHZlZGAgd2lsbCBuZXZlciBiZSByZWplY3RlZC5cbiAqIEBwYXJhbSBwcm9taXNlcyBhIHByb21pc2UgZm9yIGFuIGFycmF5IChvciBhbiBhcnJheSkgb2YgcHJvbWlzZXNcbiAqIChvciB2YWx1ZXMpXG4gKiBAcmV0dXJuIGEgcHJvbWlzZSBmb3IgYW4gYXJyYXkgb2YgcHJvbWlzZXNcbiAqL1xuUS5hbGxSZXNvbHZlZCA9IGRlcHJlY2F0ZShhbGxSZXNvbHZlZCwgXCJhbGxSZXNvbHZlZFwiLCBcImFsbFNldHRsZWRcIik7XG5mdW5jdGlvbiBhbGxSZXNvbHZlZChwcm9taXNlcykge1xuICAgIHJldHVybiB3aGVuKHByb21pc2VzLCBmdW5jdGlvbiAocHJvbWlzZXMpIHtcbiAgICAgICAgcHJvbWlzZXMgPSBhcnJheV9tYXAocHJvbWlzZXMsIFEpO1xuICAgICAgICByZXR1cm4gd2hlbihhbGwoYXJyYXlfbWFwKHByb21pc2VzLCBmdW5jdGlvbiAocHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuIHdoZW4ocHJvbWlzZSwgbm9vcCwgbm9vcCk7XG4gICAgICAgIH0pKSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VzO1xuICAgICAgICB9KTtcbiAgICB9KTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuYWxsUmVzb2x2ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGFsbFJlc29sdmVkKHRoaXMpO1xufTtcblxuLyoqXG4gKiBAc2VlIFByb21pc2UjYWxsU2V0dGxlZFxuICovXG5RLmFsbFNldHRsZWQgPSBhbGxTZXR0bGVkO1xuZnVuY3Rpb24gYWxsU2V0dGxlZChwcm9taXNlcykge1xuICAgIHJldHVybiBRKHByb21pc2VzKS5hbGxTZXR0bGVkKCk7XG59XG5cbi8qKlxuICogVHVybnMgYW4gYXJyYXkgb2YgcHJvbWlzZXMgaW50byBhIHByb21pc2UgZm9yIGFuIGFycmF5IG9mIHRoZWlyIHN0YXRlcyAoYXNcbiAqIHJldHVybmVkIGJ5IGBpbnNwZWN0YCkgd2hlbiB0aGV5IGhhdmUgYWxsIHNldHRsZWQuXG4gKiBAcGFyYW0ge0FycmF5W0FueSpdfSB2YWx1ZXMgYW4gYXJyYXkgKG9yIHByb21pc2UgZm9yIGFuIGFycmF5KSBvZiB2YWx1ZXMgKG9yXG4gKiBwcm9taXNlcyBmb3IgdmFsdWVzKVxuICogQHJldHVybnMge0FycmF5W1N0YXRlXX0gYW4gYXJyYXkgb2Ygc3RhdGVzIGZvciB0aGUgcmVzcGVjdGl2ZSB2YWx1ZXMuXG4gKi9cblByb21pc2UucHJvdG90eXBlLmFsbFNldHRsZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAocHJvbWlzZXMpIHtcbiAgICAgICAgcmV0dXJuIGFsbChhcnJheV9tYXAocHJvbWlzZXMsIGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gICAgICAgICAgICBwcm9taXNlID0gUShwcm9taXNlKTtcbiAgICAgICAgICAgIGZ1bmN0aW9uIHJlZ2FyZGxlc3MoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2UuaW5zcGVjdCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHByb21pc2UudGhlbihyZWdhcmRsZXNzLCByZWdhcmRsZXNzKTtcbiAgICAgICAgfSkpO1xuICAgIH0pO1xufTtcblxuLyoqXG4gKiBDYXB0dXJlcyB0aGUgZmFpbHVyZSBvZiBhIHByb21pc2UsIGdpdmluZyBhbiBvcG9ydHVuaXR5IHRvIHJlY292ZXJcbiAqIHdpdGggYSBjYWxsYmFjay4gIElmIHRoZSBnaXZlbiBwcm9taXNlIGlzIGZ1bGZpbGxlZCwgdGhlIHJldHVybmVkXG4gKiBwcm9taXNlIGlzIGZ1bGZpbGxlZC5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZSBmb3Igc29tZXRoaW5nXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayB0byBmdWxmaWxsIHRoZSByZXR1cm5lZCBwcm9taXNlIGlmIHRoZVxuICogZ2l2ZW4gcHJvbWlzZSBpcyByZWplY3RlZFxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBjYWxsYmFja1xuICovXG5RLmZhaWwgPSAvLyBYWFggbGVnYWN5XG5RW1wiY2F0Y2hcIl0gPSBmdW5jdGlvbiAob2JqZWN0LCByZWplY3RlZCkge1xuICAgIHJldHVybiBRKG9iamVjdCkudGhlbih2b2lkIDAsIHJlamVjdGVkKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmZhaWwgPSAvLyBYWFggbGVnYWN5XG5Qcm9taXNlLnByb3RvdHlwZVtcImNhdGNoXCJdID0gZnVuY3Rpb24gKHJlamVjdGVkKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbih2b2lkIDAsIHJlamVjdGVkKTtcbn07XG5cbi8qKlxuICogQXR0YWNoZXMgYSBsaXN0ZW5lciB0aGF0IGNhbiByZXNwb25kIHRvIHByb2dyZXNzIG5vdGlmaWNhdGlvbnMgZnJvbSBhXG4gKiBwcm9taXNlJ3Mgb3JpZ2luYXRpbmcgZGVmZXJyZWQuIFRoaXMgbGlzdGVuZXIgcmVjZWl2ZXMgdGhlIGV4YWN0IGFyZ3VtZW50c1xuICogcGFzc2VkIHRvIGBgZGVmZXJyZWQubm90aWZ5YGAuXG4gKiBAcGFyYW0ge0FueSp9IHByb21pc2UgZm9yIHNvbWV0aGluZ1xuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgdG8gcmVjZWl2ZSBhbnkgcHJvZ3Jlc3Mgbm90aWZpY2F0aW9uc1xuICogQHJldHVybnMgdGhlIGdpdmVuIHByb21pc2UsIHVuY2hhbmdlZFxuICovXG5RLnByb2dyZXNzID0gcHJvZ3Jlc3M7XG5mdW5jdGlvbiBwcm9ncmVzcyhvYmplY3QsIHByb2dyZXNzZWQpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLnRoZW4odm9pZCAwLCB2b2lkIDAsIHByb2dyZXNzZWQpO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5wcm9ncmVzcyA9IGZ1bmN0aW9uIChwcm9ncmVzc2VkKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbih2b2lkIDAsIHZvaWQgMCwgcHJvZ3Jlc3NlZCk7XG59O1xuXG4vKipcbiAqIFByb3ZpZGVzIGFuIG9wcG9ydHVuaXR5IHRvIG9ic2VydmUgdGhlIHNldHRsaW5nIG9mIGEgcHJvbWlzZSxcbiAqIHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciB0aGUgcHJvbWlzZSBpcyBmdWxmaWxsZWQgb3IgcmVqZWN0ZWQuICBGb3J3YXJkc1xuICogdGhlIHJlc29sdXRpb24gdG8gdGhlIHJldHVybmVkIHByb21pc2Ugd2hlbiB0aGUgY2FsbGJhY2sgaXMgZG9uZS5cbiAqIFRoZSBjYWxsYmFjayBjYW4gcmV0dXJuIGEgcHJvbWlzZSB0byBkZWZlciBjb21wbGV0aW9uLlxuICogQHBhcmFtIHtBbnkqfSBwcm9taXNlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayB0byBvYnNlcnZlIHRoZSByZXNvbHV0aW9uIG9mIHRoZSBnaXZlblxuICogcHJvbWlzZSwgdGFrZXMgbm8gYXJndW1lbnRzLlxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmVzb2x1dGlvbiBvZiB0aGUgZ2l2ZW4gcHJvbWlzZSB3aGVuXG4gKiBgYGZpbmBgIGlzIGRvbmUuXG4gKi9cblEuZmluID0gLy8gWFhYIGxlZ2FjeVxuUVtcImZpbmFsbHlcIl0gPSBmdW5jdGlvbiAob2JqZWN0LCBjYWxsYmFjaykge1xuICAgIHJldHVybiBRKG9iamVjdClbXCJmaW5hbGx5XCJdKGNhbGxiYWNrKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmZpbiA9IC8vIFhYWCBsZWdhY3lcblByb21pc2UucHJvdG90eXBlW1wiZmluYWxseVwiXSA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gUShjYWxsYmFjayk7XG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmZjYWxsKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH0pO1xuICAgIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgICAgLy8gVE9ETyBhdHRlbXB0IHRvIHJlY3ljbGUgdGhlIHJlamVjdGlvbiB3aXRoIFwidGhpc1wiLlxuICAgICAgICByZXR1cm4gY2FsbGJhY2suZmNhbGwoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRocm93IHJlYXNvbjtcbiAgICAgICAgfSk7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFRlcm1pbmF0ZXMgYSBjaGFpbiBvZiBwcm9taXNlcywgZm9yY2luZyByZWplY3Rpb25zIHRvIGJlXG4gKiB0aHJvd24gYXMgZXhjZXB0aW9ucy5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZSBhdCB0aGUgZW5kIG9mIGEgY2hhaW4gb2YgcHJvbWlzZXNcbiAqIEByZXR1cm5zIG5vdGhpbmdcbiAqL1xuUS5kb25lID0gZnVuY3Rpb24gKG9iamVjdCwgZnVsZmlsbGVkLCByZWplY3RlZCwgcHJvZ3Jlc3MpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRvbmUoZnVsZmlsbGVkLCByZWplY3RlZCwgcHJvZ3Jlc3MpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZG9uZSA9IGZ1bmN0aW9uIChmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzcykge1xuICAgIHZhciBvblVuaGFuZGxlZEVycm9yID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgIC8vIGZvcndhcmQgdG8gYSBmdXR1cmUgdHVybiBzbyB0aGF0IGBgd2hlbmBgXG4gICAgICAgIC8vIGRvZXMgbm90IGNhdGNoIGl0IGFuZCB0dXJuIGl0IGludG8gYSByZWplY3Rpb24uXG4gICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbWFrZVN0YWNrVHJhY2VMb25nKGVycm9yLCBwcm9taXNlKTtcbiAgICAgICAgICAgIGlmIChRLm9uZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBRLm9uZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8vIEF2b2lkIHVubmVjZXNzYXJ5IGBuZXh0VGlja2BpbmcgdmlhIGFuIHVubmVjZXNzYXJ5IGB3aGVuYC5cbiAgICB2YXIgcHJvbWlzZSA9IGZ1bGZpbGxlZCB8fCByZWplY3RlZCB8fCBwcm9ncmVzcyA/XG4gICAgICAgIHRoaXMudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzcykgOlxuICAgICAgICB0aGlzO1xuXG4gICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmIHByb2Nlc3MgJiYgcHJvY2Vzcy5kb21haW4pIHtcbiAgICAgICAgb25VbmhhbmRsZWRFcnJvciA9IHByb2Nlc3MuZG9tYWluLmJpbmQob25VbmhhbmRsZWRFcnJvcik7XG4gICAgfVxuXG4gICAgcHJvbWlzZS50aGVuKHZvaWQgMCwgb25VbmhhbmRsZWRFcnJvcik7XG59O1xuXG4vKipcbiAqIENhdXNlcyBhIHByb21pc2UgdG8gYmUgcmVqZWN0ZWQgaWYgaXQgZG9lcyBub3QgZ2V0IGZ1bGZpbGxlZCBiZWZvcmVcbiAqIHNvbWUgbWlsbGlzZWNvbmRzIHRpbWUgb3V0LlxuICogQHBhcmFtIHtBbnkqfSBwcm9taXNlXG4gKiBAcGFyYW0ge051bWJlcn0gbWlsbGlzZWNvbmRzIHRpbWVvdXRcbiAqIEBwYXJhbSB7QW55Kn0gY3VzdG9tIGVycm9yIG1lc3NhZ2Ugb3IgRXJyb3Igb2JqZWN0IChvcHRpb25hbClcbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHJlc29sdXRpb24gb2YgdGhlIGdpdmVuIHByb21pc2UgaWYgaXQgaXNcbiAqIGZ1bGZpbGxlZCBiZWZvcmUgdGhlIHRpbWVvdXQsIG90aGVyd2lzZSByZWplY3RlZC5cbiAqL1xuUS50aW1lb3V0ID0gZnVuY3Rpb24gKG9iamVjdCwgbXMsIGVycm9yKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS50aW1lb3V0KG1zLCBlcnJvcik7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50aW1lb3V0ID0gZnVuY3Rpb24gKG1zLCBlcnJvcikge1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgdmFyIHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIWVycm9yIHx8IFwic3RyaW5nXCIgPT09IHR5cGVvZiBlcnJvcikge1xuICAgICAgICAgICAgZXJyb3IgPSBuZXcgRXJyb3IoZXJyb3IgfHwgXCJUaW1lZCBvdXQgYWZ0ZXIgXCIgKyBtcyArIFwiIG1zXCIpO1xuICAgICAgICAgICAgZXJyb3IuY29kZSA9IFwiRVRJTUVET1VUXCI7XG4gICAgICAgIH1cbiAgICAgICAgZGVmZXJyZWQucmVqZWN0KGVycm9yKTtcbiAgICB9LCBtcyk7XG5cbiAgICB0aGlzLnRoZW4oZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHZhbHVlKTtcbiAgICB9LCBmdW5jdGlvbiAoZXhjZXB0aW9uKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgICBkZWZlcnJlZC5yZWplY3QoZXhjZXB0aW9uKTtcbiAgICB9LCBkZWZlcnJlZC5ub3RpZnkpO1xuXG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIFJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgZ2l2ZW4gdmFsdWUgKG9yIHByb21pc2VkIHZhbHVlKSwgc29tZVxuICogbWlsbGlzZWNvbmRzIGFmdGVyIGl0IHJlc29sdmVkLiBQYXNzZXMgcmVqZWN0aW9ucyBpbW1lZGlhdGVseS5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZVxuICogQHBhcmFtIHtOdW1iZXJ9IG1pbGxpc2Vjb25kc1xuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmVzb2x1dGlvbiBvZiB0aGUgZ2l2ZW4gcHJvbWlzZSBhZnRlciBtaWxsaXNlY29uZHNcbiAqIHRpbWUgaGFzIGVsYXBzZWQgc2luY2UgdGhlIHJlc29sdXRpb24gb2YgdGhlIGdpdmVuIHByb21pc2UuXG4gKiBJZiB0aGUgZ2l2ZW4gcHJvbWlzZSByZWplY3RzLCB0aGF0IGlzIHBhc3NlZCBpbW1lZGlhdGVseS5cbiAqL1xuUS5kZWxheSA9IGZ1bmN0aW9uIChvYmplY3QsIHRpbWVvdXQpIHtcbiAgICBpZiAodGltZW91dCA9PT0gdm9pZCAwKSB7XG4gICAgICAgIHRpbWVvdXQgPSBvYmplY3Q7XG4gICAgICAgIG9iamVjdCA9IHZvaWQgMDtcbiAgICB9XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kZWxheSh0aW1lb3V0KTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmRlbGF5ID0gZnVuY3Rpb24gKHRpbWVvdXQpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUodmFsdWUpO1xuICAgICAgICB9LCB0aW1lb3V0KTtcbiAgICAgICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFBhc3NlcyBhIGNvbnRpbnVhdGlvbiB0byBhIE5vZGUgZnVuY3Rpb24sIHdoaWNoIGlzIGNhbGxlZCB3aXRoIHRoZSBnaXZlblxuICogYXJndW1lbnRzIHByb3ZpZGVkIGFzIGFuIGFycmF5LCBhbmQgcmV0dXJucyBhIHByb21pc2UuXG4gKlxuICogICAgICBRLm5mYXBwbHkoRlMucmVhZEZpbGUsIFtfX2ZpbGVuYW1lXSlcbiAqICAgICAgLnRoZW4oZnVuY3Rpb24gKGNvbnRlbnQpIHtcbiAqICAgICAgfSlcbiAqXG4gKi9cblEubmZhcHBseSA9IGZ1bmN0aW9uIChjYWxsYmFjaywgYXJncykge1xuICAgIHJldHVybiBRKGNhbGxiYWNrKS5uZmFwcGx5KGFyZ3MpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmZhcHBseSA9IGZ1bmN0aW9uIChhcmdzKSB7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmdzKTtcbiAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgdGhpcy5mYXBwbHkobm9kZUFyZ3MpLmZhaWwoZGVmZXJyZWQucmVqZWN0KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cbi8qKlxuICogUGFzc2VzIGEgY29udGludWF0aW9uIHRvIGEgTm9kZSBmdW5jdGlvbiwgd2hpY2ggaXMgY2FsbGVkIHdpdGggdGhlIGdpdmVuXG4gKiBhcmd1bWVudHMgcHJvdmlkZWQgaW5kaXZpZHVhbGx5LCBhbmQgcmV0dXJucyBhIHByb21pc2UuXG4gKiBAZXhhbXBsZVxuICogUS5uZmNhbGwoRlMucmVhZEZpbGUsIF9fZmlsZW5hbWUpXG4gKiAudGhlbihmdW5jdGlvbiAoY29udGVudCkge1xuICogfSlcbiAqXG4gKi9cblEubmZjYWxsID0gZnVuY3Rpb24gKGNhbGxiYWNrIC8qLi4uYXJncyovKSB7XG4gICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDEpO1xuICAgIHJldHVybiBRKGNhbGxiYWNrKS5uZmFwcGx5KGFyZ3MpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmZjYWxsID0gZnVuY3Rpb24gKC8qLi4uYXJncyovKSB7XG4gICAgdmFyIG5vZGVBcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICB0aGlzLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufTtcblxuLyoqXG4gKiBXcmFwcyBhIE5vZGVKUyBjb250aW51YXRpb24gcGFzc2luZyBmdW5jdGlvbiBhbmQgcmV0dXJucyBhbiBlcXVpdmFsZW50XG4gKiB2ZXJzaW9uIHRoYXQgcmV0dXJucyBhIHByb21pc2UuXG4gKiBAZXhhbXBsZVxuICogUS5uZmJpbmQoRlMucmVhZEZpbGUsIF9fZmlsZW5hbWUpKFwidXRmLThcIilcbiAqIC50aGVuKGNvbnNvbGUubG9nKVxuICogLmRvbmUoKVxuICovXG5RLm5mYmluZCA9XG5RLmRlbm9kZWlmeSA9IGZ1bmN0aW9uIChjYWxsYmFjayAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBiYXNlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMSk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG5vZGVBcmdzID0gYmFzZUFyZ3MuY29uY2F0KGFycmF5X3NsaWNlKGFyZ3VtZW50cykpO1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgICAgIFEoY2FsbGJhY2spLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmZiaW5kID1cblByb21pc2UucHJvdG90eXBlLmRlbm9kZWlmeSA9IGZ1bmN0aW9uICgvKi4uLmFyZ3MqLykge1xuICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICBhcmdzLnVuc2hpZnQodGhpcyk7XG4gICAgcmV0dXJuIFEuZGVub2RlaWZ5LmFwcGx5KHZvaWQgMCwgYXJncyk7XG59O1xuXG5RLm5iaW5kID0gZnVuY3Rpb24gKGNhbGxiYWNrLCB0aGlzcCAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBiYXNlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMik7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG5vZGVBcmdzID0gYmFzZUFyZ3MuY29uY2F0KGFycmF5X3NsaWNlKGFyZ3VtZW50cykpO1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgICAgIGZ1bmN0aW9uIGJvdW5kKCkge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KHRoaXNwLCBhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgICAgIFEoYm91bmQpLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmJpbmQgPSBmdW5jdGlvbiAoLyp0aGlzcCwgLi4uYXJncyovKSB7XG4gICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDApO1xuICAgIGFyZ3MudW5zaGlmdCh0aGlzKTtcbiAgICByZXR1cm4gUS5uYmluZC5hcHBseSh2b2lkIDAsIGFyZ3MpO1xufTtcblxuLyoqXG4gKiBDYWxscyBhIG1ldGhvZCBvZiBhIE5vZGUtc3R5bGUgb2JqZWN0IHRoYXQgYWNjZXB0cyBhIE5vZGUtc3R5bGVcbiAqIGNhbGxiYWNrIHdpdGggYSBnaXZlbiBhcnJheSBvZiBhcmd1bWVudHMsIHBsdXMgYSBwcm92aWRlZCBjYWxsYmFjay5cbiAqIEBwYXJhbSBvYmplY3QgYW4gb2JqZWN0IHRoYXQgaGFzIHRoZSBuYW1lZCBtZXRob2RcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG5hbWUgb2YgdGhlIG1ldGhvZCBvZiBvYmplY3RcbiAqIEBwYXJhbSB7QXJyYXl9IGFyZ3MgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIG1ldGhvZDsgdGhlIGNhbGxiYWNrXG4gKiB3aWxsIGJlIHByb3ZpZGVkIGJ5IFEgYW5kIGFwcGVuZGVkIHRvIHRoZXNlIGFyZ3VtZW50cy5cbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHZhbHVlIG9yIGVycm9yXG4gKi9cblEubm1hcHBseSA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5RLm5wb3N0ID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSwgYXJncykge1xuICAgIHJldHVybiBRKG9iamVjdCkubnBvc3QobmFtZSwgYXJncyk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5ubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblByb21pc2UucHJvdG90eXBlLm5wb3N0ID0gZnVuY3Rpb24gKG5hbWUsIGFyZ3MpIHtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmdzIHx8IFtdKTtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICB0aGlzLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgbm9kZUFyZ3NdKS5mYWlsKGRlZmVycmVkLnJlamVjdCk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIENhbGxzIGEgbWV0aG9kIG9mIGEgTm9kZS1zdHlsZSBvYmplY3QgdGhhdCBhY2NlcHRzIGEgTm9kZS1zdHlsZVxuICogY2FsbGJhY2ssIGZvcndhcmRpbmcgdGhlIGdpdmVuIHZhcmlhZGljIGFyZ3VtZW50cywgcGx1cyBhIHByb3ZpZGVkXG4gKiBjYWxsYmFjayBhcmd1bWVudC5cbiAqIEBwYXJhbSBvYmplY3QgYW4gb2JqZWN0IHRoYXQgaGFzIHRoZSBuYW1lZCBtZXRob2RcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG5hbWUgb2YgdGhlIG1ldGhvZCBvZiBvYmplY3RcbiAqIEBwYXJhbSAuLi5hcmdzIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBtZXRob2Q7IHRoZSBjYWxsYmFjayB3aWxsXG4gKiBiZSBwcm92aWRlZCBieSBRIGFuZCBhcHBlbmRlZCB0byB0aGVzZSBhcmd1bWVudHMuXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSB2YWx1ZSBvciBlcnJvclxuICovXG5RLm5zZW5kID0gLy8gWFhYIEJhc2VkIG9uIE1hcmsgTWlsbGVyJ3MgcHJvcG9zZWQgXCJzZW5kXCJcblEubm1jYWxsID0gLy8gWFhYIEJhc2VkIG9uIFwiUmVkc2FuZHJvJ3NcIiBwcm9wb3NhbFxuUS5uaW52b2tlID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBub2RlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMik7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgUShvYmplY3QpLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgbm9kZUFyZ3NdKS5mYWlsKGRlZmVycmVkLnJlamVjdCk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5uc2VuZCA9IC8vIFhYWCBCYXNlZCBvbiBNYXJrIE1pbGxlcidzIHByb3Bvc2VkIFwic2VuZFwiXG5Qcm9taXNlLnByb3RvdHlwZS5ubWNhbGwgPSAvLyBYWFggQmFzZWQgb24gXCJSZWRzYW5kcm8nc1wiIHByb3Bvc2FsXG5Qcm9taXNlLnByb3RvdHlwZS5uaW52b2tlID0gZnVuY3Rpb24gKG5hbWUgLyouLi5hcmdzKi8pIHtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDEpO1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgbm9kZUFyZ3MucHVzaChkZWZlcnJlZC5tYWtlTm9kZVJlc29sdmVyKCkpO1xuICAgIHRoaXMuZGlzcGF0Y2goXCJwb3N0XCIsIFtuYW1lLCBub2RlQXJnc10pLmZhaWwoZGVmZXJyZWQucmVqZWN0KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cbi8qKlxuICogSWYgYSBmdW5jdGlvbiB3b3VsZCBsaWtlIHRvIHN1cHBvcnQgYm90aCBOb2RlIGNvbnRpbnVhdGlvbi1wYXNzaW5nLXN0eWxlIGFuZFxuICogcHJvbWlzZS1yZXR1cm5pbmctc3R5bGUsIGl0IGNhbiBlbmQgaXRzIGludGVybmFsIHByb21pc2UgY2hhaW4gd2l0aFxuICogYG5vZGVpZnkobm9kZWJhY2spYCwgZm9yd2FyZGluZyB0aGUgb3B0aW9uYWwgbm9kZWJhY2sgYXJndW1lbnQuICBJZiB0aGUgdXNlclxuICogZWxlY3RzIHRvIHVzZSBhIG5vZGViYWNrLCB0aGUgcmVzdWx0IHdpbGwgYmUgc2VudCB0aGVyZS4gIElmIHRoZXkgZG8gbm90XG4gKiBwYXNzIGEgbm9kZWJhY2ssIHRoZXkgd2lsbCByZWNlaXZlIHRoZSByZXN1bHQgcHJvbWlzZS5cbiAqIEBwYXJhbSBvYmplY3QgYSByZXN1bHQgKG9yIGEgcHJvbWlzZSBmb3IgYSByZXN1bHQpXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBub2RlYmFjayBhIE5vZGUuanMtc3R5bGUgY2FsbGJhY2tcbiAqIEByZXR1cm5zIGVpdGhlciB0aGUgcHJvbWlzZSBvciBub3RoaW5nXG4gKi9cblEubm9kZWlmeSA9IG5vZGVpZnk7XG5mdW5jdGlvbiBub2RlaWZ5KG9iamVjdCwgbm9kZWJhY2spIHtcbiAgICByZXR1cm4gUShvYmplY3QpLm5vZGVpZnkobm9kZWJhY2spO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5ub2RlaWZ5ID0gZnVuY3Rpb24gKG5vZGViYWNrKSB7XG4gICAgaWYgKG5vZGViYWNrKSB7XG4gICAgICAgIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIG5vZGViYWNrKG51bGwsIHZhbHVlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIG5vZGViYWNrKGVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59O1xuXG5RLm5vQ29uZmxpY3QgPSBmdW5jdGlvbigpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJRLm5vQ29uZmxpY3Qgb25seSB3b3JrcyB3aGVuIFEgaXMgdXNlZCBhcyBhIGdsb2JhbFwiKTtcbn07XG5cbi8vIEFsbCBjb2RlIGJlZm9yZSB0aGlzIHBvaW50IHdpbGwgYmUgZmlsdGVyZWQgZnJvbSBzdGFjayB0cmFjZXMuXG52YXIgcUVuZGluZ0xpbmUgPSBjYXB0dXJlTGluZSgpO1xuXG5yZXR1cm4gUTtcblxufSk7XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKCdfcHJvY2VzcycpKVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ6dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiSW01dlpHVmZiVzlrZFd4bGN5OXhMM0V1YW5NaVhTd2libUZ0WlhNaU9sdGRMQ0p0WVhCd2FXNW5jeUk2SWp0QlFVRkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFTSXNJbVpwYkdVaU9pSm5aVzVsY21GMFpXUXVhbk1pTENKemIzVnlZMlZTYjI5MElqb2lJaXdpYzI5MWNtTmxjME52Ym5SbGJuUWlPbHNpTHk4Z2RtbHRPblJ6UFRRNmMzUnpQVFE2YzNjOU5EcGNiaThxSVZ4dUlDcGNiaUFxSUVOdmNIbHlhV2RvZENBeU1EQTVMVEl3TVRJZ1MzSnBjeUJMYjNkaGJDQjFibVJsY2lCMGFHVWdkR1Z5YlhNZ2IyWWdkR2hsSUUxSlZGeHVJQ29nYkdsalpXNXpaU0JtYjNWdVpDQmhkQ0JvZEhSd09pOHZaMmwwYUhWaUxtTnZiUzlyY21semEyOTNZV3d2Y1M5eVlYY3ZiV0Z6ZEdWeUwweEpRMFZPVTBWY2JpQXFYRzRnS2lCWGFYUm9JSEJoY25SeklHSjVJRlI1YkdWeUlFTnNiM05sWEc0Z0tpQkRiM0I1Y21sbmFIUWdNakF3TnkweU1EQTVJRlI1YkdWeUlFTnNiM05sSUhWdVpHVnlJSFJvWlNCMFpYSnRjeUJ2WmlCMGFHVWdUVWxVSUZnZ2JHbGpaVzV6WlNCbWIzVnVaRnh1SUNvZ1lYUWdhSFIwY0RvdkwzZDNkeTV2Y0dWdWMyOTFjbU5sTG05eVp5OXNhV05sYm5ObGN5OXRhWFF0YkdsalpXNXpaUzVvZEcxc1hHNGdLaUJHYjNKclpXUWdZWFFnY21WbVgzTmxibVF1YW5NZ2RtVnljMmx2YmpvZ01qQXdPUzB3TlMweE1WeHVJQ3BjYmlBcUlGZHBkR2dnY0dGeWRITWdZbmtnVFdGeWF5Qk5hV3hzWlhKY2JpQXFJRU52Y0hseWFXZG9kQ0FvUXlrZ01qQXhNU0JIYjI5bmJHVWdTVzVqTGx4dUlDcGNiaUFxSUV4cFkyVnVjMlZrSUhWdVpHVnlJSFJvWlNCQmNHRmphR1VnVEdsalpXNXpaU3dnVm1WeWMybHZiaUF5TGpBZ0tIUm9aU0JjSWt4cFkyVnVjMlZjSWlrN1hHNGdLaUI1YjNVZ2JXRjVJRzV2ZENCMWMyVWdkR2hwY3lCbWFXeGxJR1Y0WTJWd2RDQnBiaUJqYjIxd2JHbGhibU5sSUhkcGRHZ2dkR2hsSUV4cFkyVnVjMlV1WEc0Z0tpQlpiM1VnYldGNUlHOWlkR0ZwYmlCaElHTnZjSGtnYjJZZ2RHaGxJRXhwWTJWdWMyVWdZWFJjYmlBcVhHNGdLaUJvZEhSd09pOHZkM2QzTG1Gd1lXTm9aUzV2Y21jdmJHbGpaVzV6WlhNdlRFbERSVTVUUlMweUxqQmNiaUFxWEc0Z0tpQlZibXhsYzNNZ2NtVnhkV2x5WldRZ1lua2dZWEJ3YkdsallXSnNaU0JzWVhjZ2IzSWdZV2R5WldWa0lIUnZJR2x1SUhkeWFYUnBibWNzSUhOdlpuUjNZWEpsWEc0Z0tpQmthWE4wY21saWRYUmxaQ0IxYm1SbGNpQjBhR1VnVEdsalpXNXpaU0JwY3lCa2FYTjBjbWxpZFhSbFpDQnZiaUJoYmlCY0lrRlRJRWxUWENJZ1FrRlRTVk1zWEc0Z0tpQlhTVlJJVDFWVUlGZEJVbEpCVGxSSlJWTWdUMUlnUTA5T1JFbFVTVTlPVXlCUFJpQkJUbGtnUzBsT1JDd2daV2wwYUdWeUlHVjRjSEpsYzNNZ2IzSWdhVzF3YkdsbFpDNWNiaUFxSUZObFpTQjBhR1VnVEdsalpXNXpaU0JtYjNJZ2RHaGxJSE53WldOcFptbGpJR3hoYm1kMVlXZGxJR2R2ZG1WeWJtbHVaeUJ3WlhKdGFYTnphVzl1Y3lCaGJtUmNiaUFxSUd4cGJXbDBZWFJwYjI1eklIVnVaR1Z5SUhSb1pTQk1hV05sYm5ObExseHVJQ3BjYmlBcUwxeHVYRzRvWm5WdVkzUnBiMjRnS0dSbFptbHVhWFJwYjI0cElIdGNiaUFnSUNCY0luVnpaU0J6ZEhKcFkzUmNJanRjYmx4dUlDQWdJQzh2SUZSb2FYTWdabWxzWlNCM2FXeHNJR1oxYm1OMGFXOXVJSEJ5YjNCbGNteDVJR0Z6SUdFZ1BITmpjbWx3ZEQ0Z2RHRm5MQ0J2Y2lCaElHMXZaSFZzWlZ4dUlDQWdJQzh2SUhWemFXNW5JRU52YlcxdmJrcFRJR0Z1WkNCT2IyUmxTbE1nYjNJZ1VtVnhkV2x5WlVwVElHMXZaSFZzWlNCbWIzSnRZWFJ6TGlBZ1NXNWNiaUFnSUNBdkx5QkRiMjF0YjI0dlRtOWtaUzlTWlhGMWFYSmxTbE1zSUhSb1pTQnRiMlIxYkdVZ1pYaHdiM0owY3lCMGFHVWdVU0JCVUVrZ1lXNWtJSGRvWlc1Y2JpQWdJQ0F2THlCbGVHVmpkWFJsWkNCaGN5QmhJSE5wYlhCc1pTQThjMk55YVhCMFBpd2dhWFFnWTNKbFlYUmxjeUJoSUZFZ1oyeHZZbUZzSUdsdWMzUmxZV1F1WEc1Y2JpQWdJQ0F2THlCTmIyNTBZV2RsSUZKbGNYVnBjbVZjYmlBZ0lDQnBaaUFvZEhsd1pXOW1JR0p2YjNSemRISmhjQ0E5UFQwZ1hDSm1kVzVqZEdsdmJsd2lLU0I3WEc0Z0lDQWdJQ0FnSUdKdmIzUnpkSEpoY0NoY0luQnliMjFwYzJWY0lpd2daR1ZtYVc1cGRHbHZiaWs3WEc1Y2JpQWdJQ0F2THlCRGIyMXRiMjVLVTF4dUlDQWdJSDBnWld4elpTQnBaaUFvZEhsd1pXOW1JR1Y0Y0c5eWRITWdQVDA5SUZ3aWIySnFaV04wWENJZ0ppWWdkSGx3Wlc5bUlHMXZaSFZzWlNBOVBUMGdYQ0p2WW1wbFkzUmNJaWtnZTF4dUlDQWdJQ0FnSUNCdGIyUjFiR1V1Wlhod2IzSjBjeUE5SUdSbFptbHVhWFJwYjI0b0tUdGNibHh1SUNBZ0lDOHZJRkpsY1hWcGNtVktVMXh1SUNBZ0lIMGdaV3h6WlNCcFppQW9kSGx3Wlc5bUlHUmxabWx1WlNBOVBUMGdYQ0ptZFc1amRHbHZibHdpSUNZbUlHUmxabWx1WlM1aGJXUXBJSHRjYmlBZ0lDQWdJQ0FnWkdWbWFXNWxLR1JsWm1sdWFYUnBiMjRwTzF4dVhHNGdJQ0FnTHk4Z1UwVlRJQ2hUWldOMWNtVWdSV050WVZOamNtbHdkQ2xjYmlBZ0lDQjlJR1ZzYzJVZ2FXWWdLSFI1Y0dWdlppQnpaWE1nSVQwOUlGd2lkVzVrWldacGJtVmtYQ0lwSUh0Y2JpQWdJQ0FnSUNBZ2FXWWdLQ0Z6WlhNdWIyc29LU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjbVYwZFhKdU8xeHVJQ0FnSUNBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYzJWekxtMWhhMlZSSUQwZ1pHVm1hVzVwZEdsdmJqdGNiaUFnSUNBZ0lDQWdmVnh1WEc0Z0lDQWdMeThnUEhOamNtbHdkRDVjYmlBZ0lDQjlJR1ZzYzJVZ2FXWWdLSFI1Y0dWdlppQjNhVzVrYjNjZ0lUMDlJRndpZFc1a1pXWnBibVZrWENJZ2ZId2dkSGx3Wlc5bUlITmxiR1lnSVQwOUlGd2lkVzVrWldacGJtVmtYQ0lwSUh0Y2JpQWdJQ0FnSUNBZ0x5OGdVSEpsWm1WeUlIZHBibVJ2ZHlCdmRtVnlJSE5sYkdZZ1ptOXlJR0ZrWkMxdmJpQnpZM0pwY0hSekxpQlZjMlVnYzJWc1ppQm1iM0pjYmlBZ0lDQWdJQ0FnTHk4Z2JtOXVMWGRwYm1SdmQyVmtJR052Ym5SbGVIUnpMbHh1SUNBZ0lDQWdJQ0IyWVhJZ1oyeHZZbUZzSUQwZ2RIbHdaVzltSUhkcGJtUnZkeUFoUFQwZ1hDSjFibVJsWm1sdVpXUmNJaUEvSUhkcGJtUnZkeUE2SUhObGJHWTdYRzVjYmlBZ0lDQWdJQ0FnTHk4Z1IyVjBJSFJvWlNCZ2QybHVaRzkzWUNCdlltcGxZM1FzSUhOaGRtVWdkR2hsSUhCeVpYWnBiM1Z6SUZFZ1oyeHZZbUZzWEc0Z0lDQWdJQ0FnSUM4dklHRnVaQ0JwYm1sMGFXRnNhWHBsSUZFZ1lYTWdZU0JuYkc5aVlXd3VYRzRnSUNBZ0lDQWdJSFpoY2lCd2NtVjJhVzkxYzFFZ1BTQm5iRzlpWVd3dVVUdGNiaUFnSUNBZ0lDQWdaMnh2WW1Gc0xsRWdQU0JrWldacGJtbDBhVzl1S0NrN1hHNWNiaUFnSUNBZ0lDQWdMeThnUVdSa0lHRWdibTlEYjI1bWJHbGpkQ0JtZFc1amRHbHZiaUJ6YnlCUklHTmhiaUJpWlNCeVpXMXZkbVZrSUdaeWIyMGdkR2hsWEc0Z0lDQWdJQ0FnSUM4dklHZHNiMkpoYkNCdVlXMWxjM0JoWTJVdVhHNGdJQ0FnSUNBZ0lHZHNiMkpoYkM1UkxtNXZRMjl1Wm14cFkzUWdQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JuYkc5aVlXd3VVU0E5SUhCeVpYWnBiM1Z6VVR0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQjBhR2x6TzF4dUlDQWdJQ0FnSUNCOU8xeHVYRzRnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUNBZ2RHaHliM2NnYm1WM0lFVnljbTl5S0Z3aVZHaHBjeUJsYm5acGNtOXViV1Z1ZENCM1lYTWdibTkwSUdGdWRHbGphWEJoZEdWa0lHSjVJRkV1SUZCc1pXRnpaU0JtYVd4bElHRWdZblZuTGx3aUtUdGNiaUFnSUNCOVhHNWNibjBwS0daMWJtTjBhVzl1SUNncElIdGNibHdpZFhObElITjBjbWxqZEZ3aU8xeHVYRzUyWVhJZ2FHRnpVM1JoWTJ0eklEMGdabUZzYzJVN1hHNTBjbmtnZTF4dUlDQWdJSFJvY205M0lHNWxkeUJGY25KdmNpZ3BPMXh1ZlNCallYUmphQ0FvWlNrZ2UxeHVJQ0FnSUdoaGMxTjBZV05yY3lBOUlDRWhaUzV6ZEdGamF6dGNibjFjYmx4dUx5OGdRV3hzSUdOdlpHVWdZV1owWlhJZ2RHaHBjeUJ3YjJsdWRDQjNhV3hzSUdKbElHWnBiSFJsY21Wa0lHWnliMjBnYzNSaFkyc2dkSEpoWTJWeklISmxjRzl5ZEdWa1hHNHZMeUJpZVNCUkxseHVkbUZ5SUhGVGRHRnlkR2x1WjB4cGJtVWdQU0JqWVhCMGRYSmxUR2x1WlNncE8xeHVkbUZ5SUhGR2FXeGxUbUZ0WlR0Y2JseHVMeThnYzJocGJYTmNibHh1THk4Z2RYTmxaQ0JtYjNJZ1ptRnNiR0poWTJzZ2FXNGdYQ0poYkd4U1pYTnZiSFpsWkZ3aVhHNTJZWElnYm05dmNDQTlJR1oxYm1OMGFXOXVJQ2dwSUh0OU8xeHVYRzR2THlCVmMyVWdkR2hsSUdaaGMzUmxjM1FnY0c5emMybGliR1VnYldWaGJuTWdkRzhnWlhobFkzVjBaU0JoSUhSaGMyc2dhVzRnWVNCbWRYUjFjbVVnZEhWeWJseHVMeThnYjJZZ2RHaGxJR1YyWlc1MElHeHZiM0F1WEc1MllYSWdibVY0ZEZScFkyc2dQU2htZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnTHk4Z2JHbHVhMlZrSUd4cGMzUWdiMllnZEdGemEzTWdLSE5wYm1kc1pTd2dkMmwwYUNCb1pXRmtJRzV2WkdVcFhHNGdJQ0FnZG1GeUlHaGxZV1FnUFNCN2RHRnphem9nZG05cFpDQXdMQ0J1WlhoME9pQnVkV3hzZlR0Y2JpQWdJQ0IyWVhJZ2RHRnBiQ0E5SUdobFlXUTdYRzRnSUNBZ2RtRnlJR1pzZFhOb2FXNW5JRDBnWm1Gc2MyVTdYRzRnSUNBZ2RtRnlJSEpsY1hWbGMzUlVhV05ySUQwZ2RtOXBaQ0F3TzF4dUlDQWdJSFpoY2lCcGMwNXZaR1ZLVXlBOUlHWmhiSE5sTzF4dUlDQWdJQzh2SUhGMVpYVmxJR1p2Y2lCc1lYUmxJSFJoYzJ0ekxDQjFjMlZrSUdKNUlIVnVhR0Z1Wkd4bFpDQnlaV3BsWTNScGIyNGdkSEpoWTJ0cGJtZGNiaUFnSUNCMllYSWdiR0YwWlhKUmRXVjFaU0E5SUZ0ZE8xeHVYRzRnSUNBZ1puVnVZM1JwYjI0Z1pteDFjMmdvS1NCN1hHNGdJQ0FnSUNBZ0lDOHFJR3B6YUdsdWRDQnNiMjl3Wm5WdVl6b2dkSEoxWlNBcUwxeHVJQ0FnSUNBZ0lDQjJZWElnZEdGemF5d2daRzl0WVdsdU8xeHVYRzRnSUNBZ0lDQWdJSGRvYVd4bElDaG9aV0ZrTG01bGVIUXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHaGxZV1FnUFNCb1pXRmtMbTVsZUhRN1hHNGdJQ0FnSUNBZ0lDQWdJQ0IwWVhOcklEMGdhR1ZoWkM1MFlYTnJPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2FHVmhaQzUwWVhOcklEMGdkbTlwWkNBd08xeHVJQ0FnSUNBZ0lDQWdJQ0FnWkc5dFlXbHVJRDBnYUdWaFpDNWtiMjFoYVc0N1hHNWNiaUFnSUNBZ0lDQWdJQ0FnSUdsbUlDaGtiMjFoYVc0cElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQm9aV0ZrTG1SdmJXRnBiaUE5SUhadmFXUWdNRHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JrYjIxaGFXNHVaVzUwWlhJb0tUdGNiaUFnSUNBZ0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ0lDQWdJSEoxYmxOcGJtZHNaU2gwWVhOckxDQmtiMjFoYVc0cE8xeHVYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnZDJocGJHVWdLR3hoZEdWeVVYVmxkV1V1YkdWdVozUm9LU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjBZWE5ySUQwZ2JHRjBaWEpSZFdWMVpTNXdiM0FvS1R0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEoxYmxOcGJtZHNaU2gwWVhOcktUdGNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0JtYkhWemFHbHVaeUE5SUdaaGJITmxPMXh1SUNBZ0lIMWNiaUFnSUNBdkx5QnlkVzV6SUdFZ2MybHVaMnhsSUdaMWJtTjBhVzl1SUdsdUlIUm9aU0JoYzNsdVl5QnhkV1YxWlZ4dUlDQWdJR1oxYm1OMGFXOXVJSEoxYmxOcGJtZHNaU2gwWVhOckxDQmtiMjFoYVc0cElIdGNiaUFnSUNBZ0lDQWdkSEo1SUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFJoYzJzb0tUdGNibHh1SUNBZ0lDQWdJQ0I5SUdOaGRHTm9JQ2hsS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JwWmlBb2FYTk9iMlJsU2xNcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQXZMeUJKYmlCdWIyUmxMQ0IxYm1OaGRXZG9kQ0JsZUdObGNIUnBiMjV6SUdGeVpTQmpiMjV6YVdSbGNtVmtJR1poZEdGc0lHVnljbTl5Y3k1Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBdkx5QlNaUzEwYUhKdmR5QjBhR1Z0SUhONWJtTm9jbTl1YjNWemJIa2dkRzhnYVc1MFpYSnlkWEIwSUdac2RYTm9hVzVuSVZ4dVhHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0x5OGdSVzV6ZFhKbElHTnZiblJwYm5WaGRHbHZiaUJwWmlCMGFHVWdkVzVqWVhWbmFIUWdaWGhqWlhCMGFXOXVJR2x6SUhOMWNIQnlaWE56WldSY2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBdkx5QnNhWE4wWlc1cGJtY2dYQ0oxYm1OaGRXZG9kRVY0WTJWd2RHbHZibHdpSUdWMlpXNTBjeUFvWVhNZ1pHOXRZV2x1Y3lCa2IyVnpLUzVjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0F2THlCRGIyNTBhVzUxWlNCcGJpQnVaWGgwSUdWMlpXNTBJSFJ2SUdGMmIybGtJSFJwWTJzZ2NtVmpkWEp6YVc5dUxseHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHbG1JQ2hrYjIxaGFXNHBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ1pHOXRZV2x1TG1WNGFYUW9LVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnYzJWMFZHbHRaVzkxZENobWJIVnphQ3dnTUNrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLR1J2YldGcGJpa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCa2IyMWhhVzR1Wlc1MFpYSW9LVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0I5WEc1Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCMGFISnZkeUJsTzF4dVhHNGdJQ0FnSUNBZ0lDQWdJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQzh2SUVsdUlHSnliM2R6WlhKekxDQjFibU5oZFdkb2RDQmxlR05sY0hScGIyNXpJR0Z5WlNCdWIzUWdabUYwWVd3dVhHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0x5OGdVbVV0ZEdoeWIzY2dkR2hsYlNCaGMzbHVZMmh5YjI1dmRYTnNlU0IwYnlCaGRtOXBaQ0J6Ykc5M0xXUnZkMjV6TGx4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhObGRGUnBiV1Z2ZFhRb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCMGFISnZkeUJsTzF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUgwc0lEQXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQjlYRzVjYmlBZ0lDQWdJQ0FnYVdZZ0tHUnZiV0ZwYmlrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnWkc5dFlXbHVMbVY0YVhRb0tUdGNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lIMWNibHh1SUNBZ0lHNWxlSFJVYVdOcklEMGdablZ1WTNScGIyNGdLSFJoYzJzcElIdGNiaUFnSUNBZ0lDQWdkR0ZwYkNBOUlIUmhhV3d1Ym1WNGRDQTlJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIUmhjMnM2SUhSaGMyc3NYRzRnSUNBZ0lDQWdJQ0FnSUNCa2IyMWhhVzQ2SUdselRtOWtaVXBUSUNZbUlIQnliMk5sYzNNdVpHOXRZV2x1TEZ4dUlDQWdJQ0FnSUNBZ0lDQWdibVY0ZERvZ2JuVnNiRnh1SUNBZ0lDQWdJQ0I5TzF4dVhHNGdJQ0FnSUNBZ0lHbG1JQ2doWm14MWMyaHBibWNwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJR1pzZFhOb2FXNW5JRDBnZEhKMVpUdGNiaUFnSUNBZ0lDQWdJQ0FnSUhKbGNYVmxjM1JVYVdOcktDazdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQjlPMXh1WEc0Z0lDQWdhV1lnS0hSNWNHVnZaaUJ3Y205alpYTnpJRDA5UFNCY0ltOWlhbVZqZEZ3aUlDWW1YRzRnSUNBZ0lDQWdJSEJ5YjJObGMzTXVkRzlUZEhKcGJtY29LU0E5UFQwZ1hDSmJiMkpxWldOMElIQnliMk5sYzNOZFhDSWdKaVlnY0hKdlkyVnpjeTV1WlhoMFZHbGpheWtnZTF4dUlDQWdJQ0FnSUNBdkx5QkZibk4xY21VZ1VTQnBjeUJwYmlCaElISmxZV3dnVG05a1pTQmxiblpwY205dWJXVnVkQ3dnZDJsMGFDQmhJR0J3Y205alpYTnpMbTVsZUhSVWFXTnJZQzVjYmlBZ0lDQWdJQ0FnTHk4Z1ZHOGdjMlZsSUhSb2NtOTFaMmdnWm1GclpTQk9iMlJsSUdWdWRtbHliMjV0Wlc1MGN6cGNiaUFnSUNBZ0lDQWdMeThnS2lCTmIyTm9ZU0IwWlhOMElISjFibTVsY2lBdElHVjRjRzl6WlhNZ1lTQmdjSEp2WTJWemMyQWdaMnh2WW1Gc0lIZHBkR2h2ZFhRZ1lTQmdibVY0ZEZScFkydGdYRzRnSUNBZ0lDQWdJQzh2SUNvZ1FuSnZkM05sY21sbWVTQXRJR1Y0Y0c5elpYTWdZU0JnY0hKdlkyVnpjeTV1WlhoVWFXTnJZQ0JtZFc1amRHbHZiaUIwYUdGMElIVnpaWE5jYmlBZ0lDQWdJQ0FnTHk4Z0lDQmdjMlYwVkdsdFpXOTFkR0F1SUVsdUlIUm9hWE1nWTJGelpTQmdjMlYwU1cxdFpXUnBZWFJsWUNCcGN5QndjbVZtWlhKeVpXUWdZbVZqWVhWelpWeHVJQ0FnSUNBZ0lDQXZMeUFnSUNCcGRDQnBjeUJtWVhOMFpYSXVJRUp5YjNkelpYSnBabmtuY3lCZ2NISnZZMlZ6Y3k1MGIxTjBjbWx1WnlncFlDQjVhV1ZzWkhOY2JpQWdJQ0FnSUNBZ0x5OGdJQ0JjSWx0dlltcGxZM1FnVDJKcVpXTjBYVndpTENCM2FHbHNaU0JwYmlCaElISmxZV3dnVG05a1pTQmxiblpwY205dWJXVnVkRnh1SUNBZ0lDQWdJQ0F2THlBZ0lHQndjbTlqWlhOekxtNWxlSFJVYVdOcktDbGdJSGxwWld4a2N5QmNJbHR2WW1wbFkzUWdjSEp2WTJWemMxMWNJaTVjYmlBZ0lDQWdJQ0FnYVhOT2IyUmxTbE1nUFNCMGNuVmxPMXh1WEc0Z0lDQWdJQ0FnSUhKbGNYVmxjM1JVYVdOcklEMGdablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjSEp2WTJWemN5NXVaWGgwVkdsamF5aG1iSFZ6YUNrN1hHNGdJQ0FnSUNBZ0lIMDdYRzVjYmlBZ0lDQjlJR1ZzYzJVZ2FXWWdLSFI1Y0dWdlppQnpaWFJKYlcxbFpHbGhkR1VnUFQwOUlGd2lablZ1WTNScGIyNWNJaWtnZTF4dUlDQWdJQ0FnSUNBdkx5QkpiaUJKUlRFd0xDQk9iMlJsTG1weklEQXVPU3NzSUc5eUlHaDBkSEJ6T2k4dloybDBhSFZpTG1OdmJTOU9iMkpzWlVwVEwzTmxkRWx0YldWa2FXRjBaVnh1SUNBZ0lDQWdJQ0JwWmlBb2RIbHdaVzltSUhkcGJtUnZkeUFoUFQwZ1hDSjFibVJsWm1sdVpXUmNJaWtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjbVZ4ZFdWemRGUnBZMnNnUFNCelpYUkpiVzFsWkdsaGRHVXVZbWx1WkNoM2FXNWtiM2NzSUdac2RYTm9LVHRjYmlBZ0lDQWdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lISmxjWFZsYzNSVWFXTnJJRDBnWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lITmxkRWx0YldWa2FXRjBaU2htYkhWemFDazdYRzRnSUNBZ0lDQWdJQ0FnSUNCOU8xeHVJQ0FnSUNBZ0lDQjlYRzVjYmlBZ0lDQjlJR1ZzYzJVZ2FXWWdLSFI1Y0dWdlppQk5aWE56WVdkbFEyaGhibTVsYkNBaFBUMGdYQ0oxYm1SbFptbHVaV1JjSWlrZ2UxeHVJQ0FnSUNBZ0lDQXZMeUJ0YjJSbGNtNGdZbkp2ZDNObGNuTmNiaUFnSUNBZ0lDQWdMeThnYUhSMGNEb3ZMM2QzZHk1dWIyNWliRzlqYTJsdVp5NXBieTh5TURFeEx6QTJMM2RwYm1SdmQyNWxlSFIwYVdOckxtaDBiV3hjYmlBZ0lDQWdJQ0FnZG1GeUlHTm9ZVzV1Wld3Z1BTQnVaWGNnVFdWemMyRm5aVU5vWVc1dVpXd29LVHRjYmlBZ0lDQWdJQ0FnTHk4Z1FYUWdiR1ZoYzNRZ1UyRm1ZWEpwSUZabGNuTnBiMjRnTmk0d0xqVWdLRGcxTXpZdU16QXVNU2tnYVc1MFpYSnRhWFIwWlc1MGJIa2dZMkZ1Ym05MElHTnlaV0YwWlZ4dUlDQWdJQ0FnSUNBdkx5QjNiM0pyYVc1bklHMWxjM05oWjJVZ2NHOXlkSE1nZEdobElHWnBjbk4wSUhScGJXVWdZU0J3WVdkbElHeHZZV1J6TGx4dUlDQWdJQ0FnSUNCamFHRnVibVZzTG5CdmNuUXhMbTl1YldWemMyRm5aU0E5SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhKbGNYVmxjM1JVYVdOcklEMGdjbVZ4ZFdWemRGQnZjblJVYVdOck8xeHVJQ0FnSUNBZ0lDQWdJQ0FnWTJoaGJtNWxiQzV3YjNKME1TNXZibTFsYzNOaFoyVWdQU0JtYkhWemFEdGNiaUFnSUNBZ0lDQWdJQ0FnSUdac2RYTm9LQ2s3WEc0Z0lDQWdJQ0FnSUgwN1hHNGdJQ0FnSUNBZ0lIWmhjaUJ5WlhGMVpYTjBVRzl5ZEZScFkyc2dQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0F2THlCUGNHVnlZU0J5WlhGMWFYSmxjeUIxY3lCMGJ5QndjbTkyYVdSbElHRWdiV1Z6YzJGblpTQndZWGxzYjJGa0xDQnlaV2RoY21Sc1pYTnpJRzltWEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUIzYUdWMGFHVnlJSGRsSUhWelpTQnBkQzVjYmlBZ0lDQWdJQ0FnSUNBZ0lHTm9ZVzV1Wld3dWNHOXlkREl1Y0c5emRFMWxjM05oWjJVb01DazdYRzRnSUNBZ0lDQWdJSDA3WEc0Z0lDQWdJQ0FnSUhKbGNYVmxjM1JVYVdOcklEMGdablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjMlYwVkdsdFpXOTFkQ2htYkhWemFDd2dNQ2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnlaWEYxWlhOMFVHOXlkRlJwWTJzb0tUdGNiaUFnSUNBZ0lDQWdmVHRjYmx4dUlDQWdJSDBnWld4elpTQjdYRzRnSUNBZ0lDQWdJQzh2SUc5c1pDQmljbTkzYzJWeWMxeHVJQ0FnSUNBZ0lDQnlaWEYxWlhOMFZHbGpheUE5SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhObGRGUnBiV1Z2ZFhRb1pteDFjMmdzSURBcE8xeHVJQ0FnSUNBZ0lDQjlPMXh1SUNBZ0lIMWNiaUFnSUNBdkx5QnlkVzV6SUdFZ2RHRnpheUJoWm5SbGNpQmhiR3dnYjNSb1pYSWdkR0Z6YTNNZ2FHRjJaU0JpWldWdUlISjFibHh1SUNBZ0lDOHZJSFJvYVhNZ2FYTWdkWE5sWm5Wc0lHWnZjaUIxYm1oaGJtUnNaV1FnY21WcVpXTjBhVzl1SUhSeVlXTnJhVzVuSUhSb1lYUWdibVZsWkhNZ2RHOGdhR0Z3Y0dWdVhHNGdJQ0FnTHk4Z1lXWjBaWElnWVd4c0lHQjBhR1Z1WUdRZ2RHRnphM01nYUdGMlpTQmlaV1Z1SUhKMWJpNWNiaUFnSUNCdVpYaDBWR2xqYXk1eWRXNUJablJsY2lBOUlHWjFibU4wYVc5dUlDaDBZWE5yS1NCN1hHNGdJQ0FnSUNBZ0lHeGhkR1Z5VVhWbGRXVXVjSFZ6YUNoMFlYTnJLVHRjYmlBZ0lDQWdJQ0FnYVdZZ0tDRm1iSFZ6YUdsdVp5a2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ1pteDFjMmhwYm1jZ1BTQjBjblZsTzF4dUlDQWdJQ0FnSUNBZ0lDQWdjbVZ4ZFdWemRGUnBZMnNvS1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUgwN1hHNGdJQ0FnY21WMGRYSnVJRzVsZUhSVWFXTnJPMXh1ZlNrb0tUdGNibHh1THk4Z1FYUjBaVzF3ZENCMGJ5QnRZV3RsSUdkbGJtVnlhV056SUhOaFptVWdhVzRnZEdobElHWmhZMlVnYjJZZ1pHOTNibk4wY21WaGJWeHVMeThnYlc5a2FXWnBZMkYwYVc5dWN5NWNiaTh2SUZSb1pYSmxJR2x6SUc1dklITnBkSFZoZEdsdmJpQjNhR1Z5WlNCMGFHbHpJR2x6SUc1bFkyVnpjMkZ5ZVM1Y2JpOHZJRWxtSUhsdmRTQnVaV1ZrSUdFZ2MyVmpkWEpwZEhrZ1ozVmhjbUZ1ZEdWbExDQjBhR1Z6WlNCd2NtbHRiM0prYVdGc2N5QnVaV1ZrSUhSdklHSmxYRzR2THlCa1pXVndiSGtnWm5KdmVtVnVJR0Z1ZVhkaGVTd2dZVzVrSUdsbUlIbHZkU0JrYjI3aWdKbDBJRzVsWldRZ1lTQnpaV04xY21sMGVTQm5kV0Z5WVc1MFpXVXNYRzR2THlCMGFHbHpJR2x6SUdwMWMzUWdjR3hoYVc0Z2NHRnlZVzV2YVdRdVhHNHZMeUJJYjNkbGRtVnlMQ0IwYUdseklDb3FiV2xuYUhRcUtpQm9ZWFpsSUhSb1pTQnVhV05sSUhOcFpHVXRaV1ptWldOMElHOW1JSEpsWkhWamFXNW5JSFJvWlNCemFYcGxJRzltWEc0dkx5QjBhR1VnYldsdWFXWnBaV1FnWTI5a1pTQmllU0J5WldSMVkybHVaeUI0TG1OaGJHd29LU0IwYnlCdFpYSmxiSGtnZUNncFhHNHZMeUJUWldVZ1RXRnlheUJOYVd4c1pYTGlnSmx6SUdWNGNHeGhibUYwYVc5dUlHOW1JSGRvWVhRZ2RHaHBjeUJrYjJWekxseHVMeThnYUhSMGNEb3ZMM2RwYTJrdVpXTnRZWE5qY21sd2RDNXZjbWN2Wkc5cmRTNXdhSEEvYVdROVkyOXVkbVZ1ZEdsdmJuTTZjMkZtWlY5dFpYUmhYM0J5YjJkeVlXMXRhVzVuWEc1MllYSWdZMkZzYkNBOUlFWjFibU4wYVc5dUxtTmhiR3c3WEc1bWRXNWpkR2x2YmlCMWJtTjFjbko1VkdocGN5aG1LU0I3WEc0Z0lDQWdjbVYwZFhKdUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR05oYkd3dVlYQndiSGtvWml3Z1lYSm5kVzFsYm5SektUdGNiaUFnSUNCOU8xeHVmVnh1THk4Z1ZHaHBjeUJwY3lCbGNYVnBkbUZzWlc1MExDQmlkWFFnYzJ4dmQyVnlPbHh1THk4Z2RXNWpkWEp5ZVZSb2FYTWdQU0JHZFc1amRHbHZibDlpYVc1a0xtSnBibVFvUm5WdVkzUnBiMjVmWW1sdVpDNWpZV3hzS1R0Y2JpOHZJR2gwZEhBNkx5OXFjM0JsY21ZdVkyOXRMM1Z1WTNWeWNubDBhR2x6WEc1Y2JuWmhjaUJoY25KaGVWOXpiR2xqWlNBOUlIVnVZM1Z5Y25sVWFHbHpLRUZ5Y21GNUxuQnliM1J2ZEhsd1pTNXpiR2xqWlNrN1hHNWNiblpoY2lCaGNuSmhlVjl5WldSMVkyVWdQU0IxYm1OMWNuSjVWR2hwY3loY2JpQWdJQ0JCY25KaGVTNXdjbTkwYjNSNWNHVXVjbVZrZFdObElIeDhJR1oxYm1OMGFXOXVJQ2hqWVd4c1ltRmpheXdnWW1GemFYTXBJSHRjYmlBZ0lDQWdJQ0FnZG1GeUlHbHVaR1Y0SUQwZ01DeGNiaUFnSUNBZ0lDQWdJQ0FnSUd4bGJtZDBhQ0E5SUhSb2FYTXViR1Z1WjNSb08xeHVJQ0FnSUNBZ0lDQXZMeUJqYjI1alpYSnVhVzVuSUhSb1pTQnBibWwwYVdGc0lIWmhiSFZsTENCcFppQnZibVVnYVhNZ2JtOTBJSEJ5YjNacFpHVmtYRzRnSUNBZ0lDQWdJR2xtSUNoaGNtZDFiV1Z1ZEhNdWJHVnVaM1JvSUQwOVBTQXhLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUJ6WldWcklIUnZJSFJvWlNCbWFYSnpkQ0IyWVd4MVpTQnBiaUIwYUdVZ1lYSnlZWGtzSUdGalkyOTFiblJwYm1kY2JpQWdJQ0FnSUNBZ0lDQWdJQzh2SUdadmNpQjBhR1VnY0c5emMybGlhV3hwZEhrZ2RHaGhkQ0JwY3lCcGN5QmhJSE53WVhKelpTQmhjbkpoZVZ4dUlDQWdJQ0FnSUNBZ0lDQWdaRzhnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUdsbUlDaHBibVJsZUNCcGJpQjBhR2x6S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJR0poYzJseklEMGdkR2hwYzF0cGJtUmxlQ3NyWFR0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdZbkpsWVdzN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHbG1JQ2dySzJsdVpHVjRJRDQ5SUd4bGJtZDBhQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjBhSEp2ZHlCdVpYY2dWSGx3WlVWeWNtOXlLQ2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNBZ0lDQWdmU0IzYUdsc1pTQW9NU2s3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ0x5OGdjbVZrZFdObFhHNGdJQ0FnSUNBZ0lHWnZjaUFvT3lCcGJtUmxlQ0E4SUd4bGJtZDBhRHNnYVc1a1pYZ3JLeWtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdMeThnWVdOamIzVnVkQ0JtYjNJZ2RHaGxJSEJ2YzNOcFltbHNhWFI1SUhSb1lYUWdkR2hsSUdGeWNtRjVJR2x6SUhOd1lYSnpaVnh1SUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLR2x1WkdWNElHbHVJSFJvYVhNcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQmlZWE5wY3lBOUlHTmhiR3hpWVdOcktHSmhjMmx6TENCMGFHbHpXMmx1WkdWNFhTd2dhVzVrWlhncE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCaVlYTnBjenRjYmlBZ0lDQjlYRzRwTzF4dVhHNTJZWElnWVhKeVlYbGZhVzVrWlhoUFppQTlJSFZ1WTNWeWNubFVhR2x6S0Z4dUlDQWdJRUZ5Y21GNUxuQnliM1J2ZEhsd1pTNXBibVJsZUU5bUlIeDhJR1oxYm1OMGFXOXVJQ2gyWVd4MVpTa2dlMXh1SUNBZ0lDQWdJQ0F2THlCdWIzUWdZU0IyWlhKNUlHZHZiMlFnYzJocGJTd2dZblYwSUdkdmIyUWdaVzV2ZFdkb0lHWnZjaUJ2ZFhJZ2IyNWxJSFZ6WlNCdlppQnBkRnh1SUNBZ0lDQWdJQ0JtYjNJZ0tIWmhjaUJwSUQwZ01Ec2dhU0E4SUhSb2FYTXViR1Z1WjNSb095QnBLeXNwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJR2xtSUNoMGFHbHpXMmxkSUQwOVBTQjJZV3gxWlNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lISmxkSFZ5YmlCcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlBdE1UdGNiaUFnSUNCOVhHNHBPMXh1WEc1MllYSWdZWEp5WVhsZmJXRndJRDBnZFc1amRYSnllVlJvYVhNb1hHNGdJQ0FnUVhKeVlYa3VjSEp2ZEc5MGVYQmxMbTFoY0NCOGZDQm1kVzVqZEdsdmJpQW9ZMkZzYkdKaFkyc3NJSFJvYVhOd0tTQjdYRzRnSUNBZ0lDQWdJSFpoY2lCelpXeG1JRDBnZEdocGN6dGNiaUFnSUNBZ0lDQWdkbUZ5SUdOdmJHeGxZM1FnUFNCYlhUdGNiaUFnSUNBZ0lDQWdZWEp5WVhsZmNtVmtkV05sS0hObGJHWXNJR1oxYm1OMGFXOXVJQ2gxYm1SbFptbHVaV1FzSUhaaGJIVmxMQ0JwYm1SbGVDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ1kyOXNiR1ZqZEM1d2RYTm9LR05oYkd4aVlXTnJMbU5oYkd3b2RHaHBjM0FzSUhaaGJIVmxMQ0JwYm1SbGVDd2djMlZzWmlrcE8xeHVJQ0FnSUNBZ0lDQjlMQ0IyYjJsa0lEQXBPMXh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdZMjlzYkdWamREdGNiaUFnSUNCOVhHNHBPMXh1WEc1MllYSWdiMkpxWldOMFgyTnlaV0YwWlNBOUlFOWlhbVZqZEM1amNtVmhkR1VnZkh3Z1puVnVZM1JwYjI0Z0tIQnliM1J2ZEhsd1pTa2dlMXh1SUNBZ0lHWjFibU4wYVc5dUlGUjVjR1VvS1NCN0lIMWNiaUFnSUNCVWVYQmxMbkJ5YjNSdmRIbHdaU0E5SUhCeWIzUnZkSGx3WlR0Y2JpQWdJQ0J5WlhSMWNtNGdibVYzSUZSNWNHVW9LVHRjYm4wN1hHNWNiblpoY2lCdlltcGxZM1JmYUdGelQzZHVVSEp2Y0dWeWRIa2dQU0IxYm1OMWNuSjVWR2hwY3loUFltcGxZM1F1Y0hKdmRHOTBlWEJsTG1oaGMwOTNibEJ5YjNCbGNuUjVLVHRjYmx4dWRtRnlJRzlpYW1WamRGOXJaWGx6SUQwZ1QySnFaV04wTG10bGVYTWdmSHdnWm5WdVkzUnBiMjRnS0c5aWFtVmpkQ2tnZTF4dUlDQWdJSFpoY2lCclpYbHpJRDBnVzEwN1hHNGdJQ0FnWm05eUlDaDJZWElnYTJWNUlHbHVJRzlpYW1WamRDa2dlMXh1SUNBZ0lDQWdJQ0JwWmlBb2IySnFaV04wWDJoaGMwOTNibEJ5YjNCbGNuUjVLRzlpYW1WamRDd2dhMlY1S1NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYTJWNWN5NXdkWE5vS0d0bGVTazdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQjlYRzRnSUNBZ2NtVjBkWEp1SUd0bGVYTTdYRzU5TzF4dVhHNTJZWElnYjJKcVpXTjBYM1J2VTNSeWFXNW5JRDBnZFc1amRYSnllVlJvYVhNb1QySnFaV04wTG5CeWIzUnZkSGx3WlM1MGIxTjBjbWx1WnlrN1hHNWNibVoxYm1OMGFXOXVJR2x6VDJKcVpXTjBLSFpoYkhWbEtTQjdYRzRnSUNBZ2NtVjBkWEp1SUhaaGJIVmxJRDA5UFNCUFltcGxZM1FvZG1Gc2RXVXBPMXh1ZlZ4dVhHNHZMeUJuWlc1bGNtRjBiM0lnY21Wc1lYUmxaQ0J6YUdsdGMxeHVYRzR2THlCR1NWaE5SVG9nVW1WdGIzWmxJSFJvYVhNZ1puVnVZM1JwYjI0Z2IyNWpaU0JGVXpZZ1oyVnVaWEpoZEc5eWN5QmhjbVVnYVc0Z1UzQnBaR1Z5VFc5dWEyVjVMbHh1Wm5WdVkzUnBiMjRnYVhOVGRHOXdTWFJsY21GMGFXOXVLR1Y0WTJWd2RHbHZiaWtnZTF4dUlDQWdJSEpsZEhWeWJpQW9YRzRnSUNBZ0lDQWdJRzlpYW1WamRGOTBiMU4wY21sdVp5aGxlR05sY0hScGIyNHBJRDA5UFNCY0lsdHZZbXBsWTNRZ1UzUnZjRWwwWlhKaGRHbHZibDFjSWlCOGZGeHVJQ0FnSUNBZ0lDQmxlR05sY0hScGIyNGdhVzV6ZEdGdVkyVnZaaUJSVW1WMGRYSnVWbUZzZFdWY2JpQWdJQ0FwTzF4dWZWeHVYRzR2THlCR1NWaE5SVG9nVW1WdGIzWmxJSFJvYVhNZ2FHVnNjR1Z5SUdGdVpDQlJMbkpsZEhWeWJpQnZibU5sSUVWVE5pQm5aVzVsY21GMGIzSnpJR0Z5WlNCcGJseHVMeThnVTNCcFpHVnlUVzl1YTJWNUxseHVkbUZ5SUZGU1pYUjFjbTVXWVd4MVpUdGNibWxtSUNoMGVYQmxiMllnVW1WMGRYSnVWbUZzZFdVZ0lUMDlJRndpZFc1a1pXWnBibVZrWENJcElIdGNiaUFnSUNCUlVtVjBkWEp1Vm1Gc2RXVWdQU0JTWlhSMWNtNVdZV3gxWlR0Y2JuMGdaV3h6WlNCN1hHNGdJQ0FnVVZKbGRIVnlibFpoYkhWbElEMGdablZ1WTNScGIyNGdLSFpoYkhWbEtTQjdYRzRnSUNBZ0lDQWdJSFJvYVhNdWRtRnNkV1VnUFNCMllXeDFaVHRjYmlBZ0lDQjlPMXh1ZlZ4dVhHNHZMeUJzYjI1bklITjBZV05ySUhSeVlXTmxjMXh1WEc1MllYSWdVMVJCUTB0ZlNsVk5VRjlUUlZCQlVrRlVUMUlnUFNCY0lrWnliMjBnY0hKbGRtbHZkWE1nWlhabGJuUTZYQ0k3WEc1Y2JtWjFibU4wYVc5dUlHMWhhMlZUZEdGamExUnlZV05sVEc5dVp5aGxjbkp2Y2l3Z2NISnZiV2x6WlNrZ2UxeHVJQ0FnSUM4dklFbG1JSEJ2YzNOcFlteGxMQ0IwY21GdWMyWnZjbTBnZEdobElHVnljbTl5SUhOMFlXTnJJSFJ5WVdObElHSjVJSEpsYlc5MmFXNW5JRTV2WkdVZ1lXNWtJRkZjYmlBZ0lDQXZMeUJqY25WbWRDd2dkR2hsYmlCamIyNWpZWFJsYm1GMGFXNW5JSGRwZEdnZ2RHaGxJSE4wWVdOcklIUnlZV05sSUc5bUlHQndjbTl0YVhObFlDNGdVMlZsSUNNMU55NWNiaUFnSUNCcFppQW9hR0Z6VTNSaFkydHpJQ1ltWEc0Z0lDQWdJQ0FnSUhCeWIyMXBjMlV1YzNSaFkyc2dKaVpjYmlBZ0lDQWdJQ0FnZEhsd1pXOW1JR1Z5Y205eUlEMDlQU0JjSW05aWFtVmpkRndpSUNZbVhHNGdJQ0FnSUNBZ0lHVnljbTl5SUNFOVBTQnVkV3hzSUNZbVhHNGdJQ0FnSUNBZ0lHVnljbTl5TG5OMFlXTnJJQ1ltWEc0Z0lDQWdJQ0FnSUdWeWNtOXlMbk4wWVdOckxtbHVaR1Y0VDJZb1UxUkJRMHRmU2xWTlVGOVRSVkJCVWtGVVQxSXBJRDA5UFNBdE1WeHVJQ0FnSUNrZ2UxeHVJQ0FnSUNBZ0lDQjJZWElnYzNSaFkydHpJRDBnVzEwN1hHNGdJQ0FnSUNBZ0lHWnZjaUFvZG1GeUlIQWdQU0J3Y205dGFYTmxPeUFoSVhBN0lIQWdQU0J3TG5OdmRYSmpaU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdhV1lnS0hBdWMzUmhZMnNwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCemRHRmphM011ZFc1emFHbG1kQ2h3TG5OMFlXTnJLVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0J6ZEdGamEzTXVkVzV6YUdsbWRDaGxjbkp2Y2k1emRHRmpheWs3WEc1Y2JpQWdJQ0FnSUNBZ2RtRnlJR052Ym1OaGRHVmtVM1JoWTJ0eklEMGdjM1JoWTJ0ekxtcHZhVzRvWENKY1hHNWNJaUFySUZOVVFVTkxYMHBWVFZCZlUwVlFRVkpCVkU5U0lDc2dYQ0pjWEc1Y0lpazdYRzRnSUNBZ0lDQWdJR1Z5Y205eUxuTjBZV05ySUQwZ1ptbHNkR1Z5VTNSaFkydFRkSEpwYm1jb1kyOXVZMkYwWldSVGRHRmphM01wTzF4dUlDQWdJSDFjYm4xY2JseHVablZ1WTNScGIyNGdabWxzZEdWeVUzUmhZMnRUZEhKcGJtY29jM1JoWTJ0VGRISnBibWNwSUh0Y2JpQWdJQ0IyWVhJZ2JHbHVaWE1nUFNCemRHRmphMU4wY21sdVp5NXpjR3hwZENoY0lseGNibHdpS1R0Y2JpQWdJQ0IyWVhJZ1pHVnphWEpsWkV4cGJtVnpJRDBnVzEwN1hHNGdJQ0FnWm05eUlDaDJZWElnYVNBOUlEQTdJR2tnUENCc2FXNWxjeTVzWlc1bmRHZzdJQ3NyYVNrZ2UxeHVJQ0FnSUNBZ0lDQjJZWElnYkdsdVpTQTlJR3hwYm1WelcybGRPMXh1WEc0Z0lDQWdJQ0FnSUdsbUlDZ2hhWE5KYm5SbGNtNWhiRVp5WVcxbEtHeHBibVVwSUNZbUlDRnBjMDV2WkdWR2NtRnRaU2hzYVc1bEtTQW1KaUJzYVc1bEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCa1pYTnBjbVZrVEdsdVpYTXVjSFZ6YUNoc2FXNWxLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJSDFjYmlBZ0lDQnlaWFIxY200Z1pHVnphWEpsWkV4cGJtVnpMbXB2YVc0b1hDSmNYRzVjSWlrN1hHNTlYRzVjYm1aMWJtTjBhVzl1SUdselRtOWtaVVp5WVcxbEtITjBZV05yVEdsdVpTa2dlMXh1SUNBZ0lISmxkSFZ5YmlCemRHRmphMHhwYm1VdWFXNWtaWGhQWmloY0lpaHRiMlIxYkdVdWFuTTZYQ0lwSUNFOVBTQXRNU0I4ZkZ4dUlDQWdJQ0FnSUNBZ0lDQnpkR0ZqYTB4cGJtVXVhVzVrWlhoUFppaGNJaWh1YjJSbExtcHpPbHdpS1NBaFBUMGdMVEU3WEc1OVhHNWNibVoxYm1OMGFXOXVJR2RsZEVacGJHVk9ZVzFsUVc1a1RHbHVaVTUxYldKbGNpaHpkR0ZqYTB4cGJtVXBJSHRjYmlBZ0lDQXZMeUJPWVcxbFpDQm1kVzVqZEdsdmJuTTZJRndpWVhRZ1puVnVZM1JwYjI1T1lXMWxJQ2htYVd4bGJtRnRaVHBzYVc1bFRuVnRZbVZ5T21OdmJIVnRiazUxYldKbGNpbGNJbHh1SUNBZ0lDOHZJRWx1SUVsRk1UQWdablZ1WTNScGIyNGdibUZ0WlNCallXNGdhR0YyWlNCemNHRmpaWE1nS0Z3aVFXNXZibmx0YjNWeklHWjFibU4wYVc5dVhDSXBJRTlmYjF4dUlDQWdJSFpoY2lCaGRIUmxiWEIwTVNBOUlDOWhkQ0F1S3lCY1hDZ29MaXNwT2loY1hHUXJLVG9vUHpwY1hHUXJLVnhjS1NRdkxtVjRaV01vYzNSaFkydE1hVzVsS1R0Y2JpQWdJQ0JwWmlBb1lYUjBaVzF3ZERFcElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlGdGhkSFJsYlhCME1Wc3hYU3dnVG5WdFltVnlLR0YwZEdWdGNIUXhXekpkS1YwN1hHNGdJQ0FnZlZ4dVhHNGdJQ0FnTHk4Z1FXNXZibmx0YjNWeklHWjFibU4wYVc5dWN6b2dYQ0poZENCbWFXeGxibUZ0WlRwc2FXNWxUblZ0WW1WeU9tTnZiSFZ0Yms1MWJXSmxjbHdpWEc0Z0lDQWdkbUZ5SUdGMGRHVnRjSFF5SUQwZ0wyRjBJQ2hiWGlCZEt5azZLRnhjWkNzcE9pZy9PbHhjWkNzcEpDOHVaWGhsWXloemRHRmphMHhwYm1VcE8xeHVJQ0FnSUdsbUlDaGhkSFJsYlhCME1pa2dlMXh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdXMkYwZEdWdGNIUXlXekZkTENCT2RXMWlaWElvWVhSMFpXMXdkREpiTWwwcFhUdGNiaUFnSUNCOVhHNWNiaUFnSUNBdkx5QkdhWEpsWm05NElITjBlV3hsT2lCY0ltWjFibU4wYVc5dVFHWnBiR1Z1WVcxbE9teHBibVZPZFcxaVpYSWdiM0lnUUdacGJHVnVZVzFsT214cGJtVk9kVzFpWlhKY0lseHVJQ0FnSUhaaGNpQmhkSFJsYlhCME15QTlJQzh1S2tBb0xpc3BPaWhjWEdRcktTUXZMbVY0WldNb2MzUmhZMnRNYVc1bEtUdGNiaUFnSUNCcFppQW9ZWFIwWlcxd2RETXBJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJRnRoZEhSbGJYQjBNMXN4WFN3Z1RuVnRZbVZ5S0dGMGRHVnRjSFF6V3pKZEtWMDdYRzRnSUNBZ2ZWeHVmVnh1WEc1bWRXNWpkR2x2YmlCcGMwbHVkR1Z5Ym1Gc1JuSmhiV1VvYzNSaFkydE1hVzVsS1NCN1hHNGdJQ0FnZG1GeUlHWnBiR1ZPWVcxbFFXNWtUR2x1WlU1MWJXSmxjaUE5SUdkbGRFWnBiR1ZPWVcxbFFXNWtUR2x1WlU1MWJXSmxjaWh6ZEdGamEweHBibVVwTzF4dVhHNGdJQ0FnYVdZZ0tDRm1hV3hsVG1GdFpVRnVaRXhwYm1WT2RXMWlaWElwSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUdaaGJITmxPMXh1SUNBZ0lIMWNibHh1SUNBZ0lIWmhjaUJtYVd4bFRtRnRaU0E5SUdacGJHVk9ZVzFsUVc1a1RHbHVaVTUxYldKbGNsc3dYVHRjYmlBZ0lDQjJZWElnYkdsdVpVNTFiV0psY2lBOUlHWnBiR1ZPWVcxbFFXNWtUR2x1WlU1MWJXSmxjbHN4WFR0Y2JseHVJQ0FnSUhKbGRIVnliaUJtYVd4bFRtRnRaU0E5UFQwZ2NVWnBiR1ZPWVcxbElDWW1YRzRnSUNBZ0lDQWdJR3hwYm1WT2RXMWlaWElnUGowZ2NWTjBZWEowYVc1blRHbHVaU0FtSmx4dUlDQWdJQ0FnSUNCc2FXNWxUblZ0WW1WeUlEdzlJSEZGYm1ScGJtZE1hVzVsTzF4dWZWeHVYRzR2THlCa2FYTmpiM1psY2lCdmQyNGdabWxzWlNCdVlXMWxJR0Z1WkNCc2FXNWxJRzUxYldKbGNpQnlZVzVuWlNCbWIzSWdabWxzZEdWeWFXNW5JSE4wWVdOclhHNHZMeUIwY21GalpYTmNibVoxYm1OMGFXOXVJR05oY0hSMWNtVk1hVzVsS0NrZ2UxeHVJQ0FnSUdsbUlDZ2hhR0Z6VTNSaFkydHpLU0I3WEc0Z0lDQWdJQ0FnSUhKbGRIVnlianRjYmlBZ0lDQjlYRzVjYmlBZ0lDQjBjbmtnZTF4dUlDQWdJQ0FnSUNCMGFISnZkeUJ1WlhjZ1JYSnliM0lvS1R0Y2JpQWdJQ0I5SUdOaGRHTm9JQ2hsS1NCN1hHNGdJQ0FnSUNBZ0lIWmhjaUJzYVc1bGN5QTlJR1V1YzNSaFkyc3VjM0JzYVhRb1hDSmNYRzVjSWlrN1hHNGdJQ0FnSUNBZ0lIWmhjaUJtYVhKemRFeHBibVVnUFNCc2FXNWxjMXN3WFM1cGJtUmxlRTltS0Z3aVFGd2lLU0ErSURBZ1B5QnNhVzVsYzFzeFhTQTZJR3hwYm1Weld6SmRPMXh1SUNBZ0lDQWdJQ0IyWVhJZ1ptbHNaVTVoYldWQmJtUk1hVzVsVG5WdFltVnlJRDBnWjJWMFJtbHNaVTVoYldWQmJtUk1hVzVsVG5WdFltVnlLR1pwY25OMFRHbHVaU2s3WEc0Z0lDQWdJQ0FnSUdsbUlDZ2habWxzWlU1aGJXVkJibVJNYVc1bFRuVnRZbVZ5S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNDdYRzRnSUNBZ0lDQWdJSDFjYmx4dUlDQWdJQ0FnSUNCeFJtbHNaVTVoYldVZ1BTQm1hV3hsVG1GdFpVRnVaRXhwYm1WT2RXMWlaWEpiTUYwN1hHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCbWFXeGxUbUZ0WlVGdVpFeHBibVZPZFcxaVpYSmJNVjA3WEc0Z0lDQWdmVnh1ZlZ4dVhHNW1kVzVqZEdsdmJpQmtaWEJ5WldOaGRHVW9ZMkZzYkdKaFkyc3NJRzVoYldVc0lHRnNkR1Z5Ym1GMGFYWmxLU0I3WEc0Z0lDQWdjbVYwZFhKdUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnYVdZZ0tIUjVjR1Z2WmlCamIyNXpiMnhsSUNFOVBTQmNJblZ1WkdWbWFXNWxaRndpSUNZbVhHNGdJQ0FnSUNBZ0lDQWdJQ0IwZVhCbGIyWWdZMjl1YzI5c1pTNTNZWEp1SUQwOVBTQmNJbVoxYm1OMGFXOXVYQ0lwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJR052Ym5OdmJHVXVkMkZ5YmlodVlXMWxJQ3NnWENJZ2FYTWdaR1Z3Y21WallYUmxaQ3dnZFhObElGd2lJQ3NnWVd4MFpYSnVZWFJwZG1VZ0sxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lGd2lJR2x1YzNSbFlXUXVYQ0lzSUc1bGR5QkZjbkp2Y2loY0lsd2lLUzV6ZEdGamF5azdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR05oYkd4aVlXTnJMbUZ3Y0d4NUtHTmhiR3hpWVdOckxDQmhjbWQxYldWdWRITXBPMXh1SUNBZ0lIMDdYRzU5WEc1Y2JpOHZJR1Z1WkNCdlppQnphR2x0YzF4dUx5OGdZbVZuYVc1dWFXNW5JRzltSUhKbFlXd2dkMjl5YTF4dVhHNHZLaXBjYmlBcUlFTnZibk4wY25WamRITWdZU0J3Y205dGFYTmxJR1p2Y2lCaGJpQnBiVzFsWkdsaGRHVWdjbVZtWlhKbGJtTmxMQ0J3WVhOelpYTWdjSEp2YldselpYTWdkR2h5YjNWbmFDd2diM0pjYmlBcUlHTnZaWEpqWlhNZ2NISnZiV2x6WlhNZ1puSnZiU0JrYVdabVpYSmxiblFnYzNsemRHVnRjeTVjYmlBcUlFQndZWEpoYlNCMllXeDFaU0JwYlcxbFpHbGhkR1VnY21WbVpYSmxibU5sSUc5eUlIQnliMjFwYzJWY2JpQXFMMXh1Wm5WdVkzUnBiMjRnVVNoMllXeDFaU2tnZTF4dUlDQWdJQzh2SUVsbUlIUm9aU0J2WW1wbFkzUWdhWE1nWVd4eVpXRmtlU0JoSUZCeWIyMXBjMlVzSUhKbGRIVnliaUJwZENCa2FYSmxZM1JzZVM0Z0lGUm9hWE1nWlc1aFlteGxjMXh1SUNBZ0lDOHZJSFJvWlNCeVpYTnZiSFpsSUdaMWJtTjBhVzl1SUhSdklHSnZkR2dnWW1VZ2RYTmxaQ0IwYnlCamNtVmhkR1ZrSUhKbFptVnlaVzVqWlhNZ1puSnZiU0J2WW1wbFkzUnpMRnh1SUNBZ0lDOHZJR0oxZENCMGJ5QjBiMnhsY21GaWJIa2dZMjlsY21ObElHNXZiaTF3Y205dGFYTmxjeUIwYnlCd2NtOXRhWE5sY3k1Y2JpQWdJQ0JwWmlBb2RtRnNkV1VnYVc1emRHRnVZMlZ2WmlCUWNtOXRhWE5sS1NCN1hHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCMllXeDFaVHRjYmlBZ0lDQjlYRzVjYmlBZ0lDQXZMeUJoYzNOcGJXbHNZWFJsSUhSb1pXNWhZbXhsYzF4dUlDQWdJR2xtSUNocGMxQnliMjFwYzJWQmJHbHJaU2gyWVd4MVpTa3BJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR052WlhKalpTaDJZV3gxWlNrN1hHNGdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR1oxYkdacGJHd29kbUZzZFdVcE8xeHVJQ0FnSUgxY2JuMWNibEV1Y21WemIyeDJaU0E5SUZFN1hHNWNiaThxS2x4dUlDb2dVR1Z5Wm05eWJYTWdZU0IwWVhOcklHbHVJR0VnWm5WMGRYSmxJSFIxY200Z2IyWWdkR2hsSUdWMlpXNTBJR3h2YjNBdVhHNGdLaUJBY0dGeVlXMGdlMFoxYm1OMGFXOXVmU0IwWVhOclhHNGdLaTljYmxFdWJtVjRkRlJwWTJzZ1BTQnVaWGgwVkdsamF6dGNibHh1THlvcVhHNGdLaUJEYjI1MGNtOXNjeUIzYUdWMGFHVnlJRzl5SUc1dmRDQnNiMjVuSUhOMFlXTnJJSFJ5WVdObGN5QjNhV3hzSUdKbElHOXVYRzRnS2k5Y2JsRXViRzl1WjFOMFlXTnJVM1Z3Y0c5eWRDQTlJR1poYkhObE8xeHVYRzR2THlCbGJtRmliR1VnYkc5dVp5QnpkR0ZqYTNNZ2FXWWdVVjlFUlVKVlJ5QnBjeUJ6WlhSY2JtbG1JQ2gwZVhCbGIyWWdjSEp2WTJWemN5QTlQVDBnWENKdlltcGxZM1JjSWlBbUppQndjbTlqWlhOeklDWW1JSEJ5YjJObGMzTXVaVzUySUNZbUlIQnliMk5sYzNNdVpXNTJMbEZmUkVWQ1ZVY3BJSHRjYmlBZ0lDQlJMbXh2Ym1kVGRHRmphMU4xY0hCdmNuUWdQU0IwY25WbE8xeHVmVnh1WEc0dktpcGNiaUFxSUVOdmJuTjBjblZqZEhNZ1lTQjdjSEp2YldselpTd2djbVZ6YjJ4MlpTd2djbVZxWldOMGZTQnZZbXBsWTNRdVhHNGdLbHh1SUNvZ1lISmxjMjlzZG1WZ0lHbHpJR0VnWTJGc2JHSmhZMnNnZEc4Z2FXNTJiMnRsSUhkcGRHZ2dZU0J0YjNKbElISmxjMjlzZG1Wa0lIWmhiSFZsSUdadmNpQjBhR1ZjYmlBcUlIQnliMjFwYzJVdUlGUnZJR1oxYkdacGJHd2dkR2hsSUhCeWIyMXBjMlVzSUdsdWRtOXJaU0JnY21WemIyeDJaV0FnZDJsMGFDQmhibmtnZG1Gc2RXVWdkR2hoZENCcGMxeHVJQ29nYm05MElHRWdkR2hsYm1GaWJHVXVJRlJ2SUhKbGFtVmpkQ0IwYUdVZ2NISnZiV2x6WlN3Z2FXNTJiMnRsSUdCeVpYTnZiSFpsWUNCM2FYUm9JR0VnY21WcVpXTjBaV1JjYmlBcUlIUm9aVzVoWW14bExDQnZjaUJwYm5admEyVWdZSEpsYW1WamRHQWdkMmwwYUNCMGFHVWdjbVZoYzI5dUlHUnBjbVZqZEd4NUxpQlVieUJ5WlhOdmJIWmxJSFJvWlZ4dUlDb2djSEp2YldselpTQjBieUJoYm05MGFHVnlJSFJvWlc1aFlteGxMQ0IwYUhWeklIQjFkSFJwYm1jZ2FYUWdhVzRnZEdobElITmhiV1VnYzNSaGRHVXNJR2x1ZG05clpWeHVJQ29nWUhKbGMyOXNkbVZnSUhkcGRHZ2dkR2hoZENCdmRHaGxjaUIwYUdWdVlXSnNaUzVjYmlBcUwxeHVVUzVrWldabGNpQTlJR1JsWm1WeU8xeHVablZ1WTNScGIyNGdaR1ZtWlhJb0tTQjdYRzRnSUNBZ0x5OGdhV1lnWENKdFpYTnpZV2RsYzF3aUlHbHpJR0Z1SUZ3aVFYSnlZWGxjSWl3Z2RHaGhkQ0JwYm1ScFkyRjBaWE1nZEdoaGRDQjBhR1VnY0hKdmJXbHpaU0JvWVhNZ2JtOTBJSGxsZEZ4dUlDQWdJQzh2SUdKbFpXNGdjbVZ6YjJ4MlpXUXVJQ0JKWmlCcGRDQnBjeUJjSW5WdVpHVm1hVzVsWkZ3aUxDQnBkQ0JvWVhNZ1ltVmxiaUJ5WlhOdmJIWmxaQzRnSUVWaFkyaGNiaUFnSUNBdkx5QmxiR1Z0Wlc1MElHOW1JSFJvWlNCdFpYTnpZV2RsY3lCaGNuSmhlU0JwY3lCcGRITmxiR1lnWVc0Z1lYSnlZWGtnYjJZZ1kyOXRjR3hsZEdVZ1lYSm5kVzFsYm5SeklIUnZYRzRnSUNBZ0x5OGdabTl5ZDJGeVpDQjBieUIwYUdVZ2NtVnpiMngyWldRZ2NISnZiV2x6WlM0Z0lGZGxJR052WlhKalpTQjBhR1VnY21WemIyeDFkR2x2YmlCMllXeDFaU0IwYnlCaFhHNGdJQ0FnTHk4Z2NISnZiV2x6WlNCMWMybHVaeUIwYUdVZ1lISmxjMjlzZG1WZ0lHWjFibU4wYVc5dUlHSmxZMkYxYzJVZ2FYUWdhR0Z1Wkd4bGN5QmliM1JvSUdaMWJHeDVYRzRnSUNBZ0x5OGdibTl1TFhSb1pXNWhZbXhsSUhaaGJIVmxjeUJoYm1RZ2IzUm9aWElnZEdobGJtRmliR1Z6SUdkeVlXTmxablZzYkhrdVhHNGdJQ0FnZG1GeUlHMWxjM05oWjJWeklEMGdXMTBzSUhCeWIyZHlaWE56VEdsemRHVnVaWEp6SUQwZ1cxMHNJSEpsYzI5c2RtVmtVSEp2YldselpUdGNibHh1SUNBZ0lIWmhjaUJrWldabGNuSmxaQ0E5SUc5aWFtVmpkRjlqY21WaGRHVW9aR1ZtWlhJdWNISnZkRzkwZVhCbEtUdGNiaUFnSUNCMllYSWdjSEp2YldselpTQTlJRzlpYW1WamRGOWpjbVZoZEdVb1VISnZiV2x6WlM1d2NtOTBiM1I1Y0dVcE8xeHVYRzRnSUNBZ2NISnZiV2x6WlM1d2NtOXRhWE5sUkdsemNHRjBZMmdnUFNCbWRXNWpkR2x2YmlBb2NtVnpiMngyWlN3Z2IzQXNJRzl3WlhKaGJtUnpLU0I3WEc0Z0lDQWdJQ0FnSUhaaGNpQmhjbWR6SUQwZ1lYSnlZWGxmYzJ4cFkyVW9ZWEpuZFcxbGJuUnpLVHRjYmlBZ0lDQWdJQ0FnYVdZZ0tHMWxjM05oWjJWektTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCdFpYTnpZV2RsY3k1d2RYTm9LR0Z5WjNNcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnYVdZZ0tHOXdJRDA5UFNCY0luZG9aVzVjSWlBbUppQnZjR1Z5WVc1a2Mxc3hYU2tnZXlBdkx5QndjbTluY21WemN5QnZjR1Z5WVc1a1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NISnZaM0psYzNOTWFYTjBaVzVsY25NdWNIVnphQ2h2Y0dWeVlXNWtjMXN4WFNrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQlJMbTVsZUhSVWFXTnJLR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCeVpYTnZiSFpsWkZCeWIyMXBjMlV1Y0hKdmJXbHpaVVJwYzNCaGRHTm9MbUZ3Y0d4NUtISmxjMjlzZG1Wa1VISnZiV2x6WlN3Z1lYSm5jeWs3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJSDA3WEc1Y2JpQWdJQ0F2THlCWVdGZ2daR1Z3Y21WallYUmxaRnh1SUNBZ0lIQnliMjFwYzJVdWRtRnNkV1ZQWmlBOUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnYVdZZ0tHMWxjM05oWjJWektTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCeVpYUjFjbTRnY0hKdmJXbHpaVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCMllYSWdibVZoY21WeVZtRnNkV1VnUFNCdVpXRnlaWElvY21WemIyeDJaV1JRY205dGFYTmxLVHRjYmlBZ0lDQWdJQ0FnYVdZZ0tHbHpVSEp2YldselpTaHVaV0Z5WlhKV1lXeDFaU2twSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsYzI5c2RtVmtVSEp2YldselpTQTlJRzVsWVhKbGNsWmhiSFZsT3lBdkx5QnphRzl5ZEdWdUlHTm9ZV2x1WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUc1bFlYSmxjbFpoYkhWbE8xeHVJQ0FnSUgwN1hHNWNiaUFnSUNCd2NtOXRhWE5sTG1sdWMzQmxZM1FnUFNCbWRXNWpkR2x2YmlBb0tTQjdYRzRnSUNBZ0lDQWdJR2xtSUNnaGNtVnpiMngyWldSUWNtOXRhWE5sS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdleUJ6ZEdGMFpUb2dYQ0p3Wlc1a2FXNW5YQ0lnZlR0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQnlaWFIxY200Z2NtVnpiMngyWldSUWNtOXRhWE5sTG1sdWMzQmxZM1FvS1R0Y2JpQWdJQ0I5TzF4dVhHNGdJQ0FnYVdZZ0tGRXViRzl1WjFOMFlXTnJVM1Z3Y0c5eWRDQW1KaUJvWVhOVGRHRmphM01wSUh0Y2JpQWdJQ0FnSUNBZ2RISjVJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIUm9jbTkzSUc1bGR5QkZjbkp2Y2lncE8xeHVJQ0FnSUNBZ0lDQjlJR05oZEdOb0lDaGxLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUJPVDFSRk9pQmtiMjRuZENCMGNua2dkRzhnZFhObElHQkZjbkp2Y2k1allYQjBkWEpsVTNSaFkydFVjbUZqWldBZ2IzSWdkSEpoYm5ObVpYSWdkR2hsWEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUJoWTJObGMzTnZjaUJoY205MWJtUTdJSFJvWVhRZ1kyRjFjMlZ6SUcxbGJXOXllU0JzWldGcmN5QmhjeUJ3WlhJZ1IwZ3RNVEV4TGlCS2RYTjBYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QnlaV2xtZVNCMGFHVWdjM1JoWTJzZ2RISmhZMlVnWVhNZ1lTQnpkSEpwYm1jZ1FWTkJVQzVjYmlBZ0lDQWdJQ0FnSUNBZ0lDOHZYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QkJkQ0IwYUdVZ2MyRnRaU0IwYVcxbExDQmpkWFFnYjJabUlIUm9aU0JtYVhKemRDQnNhVzVsT3lCcGRDZHpJR0ZzZDJGNWN5QnFkWE4wWEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUJjSWx0dlltcGxZM1FnVUhKdmJXbHpaVjFjWEc1Y0lpd2dZWE1nY0dWeUlIUm9aU0JnZEc5VGRISnBibWRnTGx4dUlDQWdJQ0FnSUNBZ0lDQWdjSEp2YldselpTNXpkR0ZqYXlBOUlHVXVjM1JoWTJzdWMzVmljM1J5YVc1bktHVXVjM1JoWTJzdWFXNWtaWGhQWmloY0lseGNibHdpS1NBcklERXBPMXh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdmVnh1WEc0Z0lDQWdMeThnVGs5VVJUb2dkMlVnWkc4Z2RHaGxJR05vWldOcmN5Qm1iM0lnWUhKbGMyOXNkbVZrVUhKdmJXbHpaV0FnYVc0Z1pXRmphQ0J0WlhSb2IyUXNJR2x1YzNSbFlXUWdiMlpjYmlBZ0lDQXZMeUJqYjI1emIyeHBaR0YwYVc1bklIUm9aVzBnYVc1MGJ5QmdZbVZqYjIxbFlDd2djMmx1WTJVZ2IzUm9aWEozYVhObElIZGxKMlFnWTNKbFlYUmxJRzVsZDF4dUlDQWdJQzh2SUhCeWIyMXBjMlZ6SUhkcGRHZ2dkR2hsSUd4cGJtVnpJR0JpWldOdmJXVW9kMmhoZEdWMlpYSW9kbUZzZFdVcEtXQXVJRk5sWlNCbExtY3VJRWRJTFRJMU1pNWNibHh1SUNBZ0lHWjFibU4wYVc5dUlHSmxZMjl0WlNodVpYZFFjbTl0YVhObEtTQjdYRzRnSUNBZ0lDQWdJSEpsYzI5c2RtVmtVSEp2YldselpTQTlJRzVsZDFCeWIyMXBjMlU3WEc0Z0lDQWdJQ0FnSUhCeWIyMXBjMlV1YzI5MWNtTmxJRDBnYm1WM1VISnZiV2x6WlR0Y2JseHVJQ0FnSUNBZ0lDQmhjbkpoZVY5eVpXUjFZMlVvYldWemMyRm5aWE1zSUdaMWJtTjBhVzl1SUNoMWJtUmxabWx1WldRc0lHMWxjM05oWjJVcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUZFdWJtVjRkRlJwWTJzb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJRzVsZDFCeWIyMXBjMlV1Y0hKdmJXbHpaVVJwYzNCaGRHTm9MbUZ3Y0d4NUtHNWxkMUJ5YjIxcGMyVXNJRzFsYzNOaFoyVXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZTazdYRzRnSUNBZ0lDQWdJSDBzSUhadmFXUWdNQ2s3WEc1Y2JpQWdJQ0FnSUNBZ2JXVnpjMkZuWlhNZ1BTQjJiMmxrSURBN1hHNGdJQ0FnSUNBZ0lIQnliMmR5WlhOelRHbHpkR1Z1WlhKeklEMGdkbTlwWkNBd08xeHVJQ0FnSUgxY2JseHVJQ0FnSUdSbFptVnljbVZrTG5CeWIyMXBjMlVnUFNCd2NtOXRhWE5sTzF4dUlDQWdJR1JsWm1WeWNtVmtMbkpsYzI5c2RtVWdQU0JtZFc1amRHbHZiaUFvZG1Gc2RXVXBJSHRjYmlBZ0lDQWdJQ0FnYVdZZ0tISmxjMjlzZG1Wa1VISnZiV2x6WlNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVPMXh1SUNBZ0lDQWdJQ0I5WEc1Y2JpQWdJQ0FnSUNBZ1ltVmpiMjFsS0ZFb2RtRnNkV1VwS1R0Y2JpQWdJQ0I5TzF4dVhHNGdJQ0FnWkdWbVpYSnlaV1F1Wm5Wc1ptbHNiQ0E5SUdaMWJtTjBhVzl1SUNoMllXeDFaU2tnZTF4dUlDQWdJQ0FnSUNCcFppQW9jbVZ6YjJ4MlpXUlFjbTl0YVhObEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCeVpYUjFjbTQ3WEc0Z0lDQWdJQ0FnSUgxY2JseHVJQ0FnSUNBZ0lDQmlaV052YldVb1puVnNabWxzYkNoMllXeDFaU2twTzF4dUlDQWdJSDA3WEc0Z0lDQWdaR1ZtWlhKeVpXUXVjbVZxWldOMElEMGdablZ1WTNScGIyNGdLSEpsWVhOdmJpa2dlMXh1SUNBZ0lDQWdJQ0JwWmlBb2NtVnpiMngyWldSUWNtOXRhWE5sS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNDdYRzRnSUNBZ0lDQWdJSDFjYmx4dUlDQWdJQ0FnSUNCaVpXTnZiV1VvY21WcVpXTjBLSEpsWVhOdmJpa3BPMXh1SUNBZ0lIMDdYRzRnSUNBZ1pHVm1aWEp5WldRdWJtOTBhV1o1SUQwZ1puVnVZM1JwYjI0Z0tIQnliMmR5WlhOektTQjdYRzRnSUNBZ0lDQWdJR2xtSUNoeVpYTnZiSFpsWkZCeWIyMXBjMlVwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJqdGNiaUFnSUNBZ0lDQWdmVnh1WEc0Z0lDQWdJQ0FnSUdGeWNtRjVYM0psWkhWalpTaHdjbTluY21WemMweHBjM1JsYm1WeWN5d2dablZ1WTNScGIyNGdLSFZ1WkdWbWFXNWxaQ3dnY0hKdlozSmxjM05NYVhOMFpXNWxjaWtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdVUzV1WlhoMFZHbGpheWhtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NISnZaM0psYzNOTWFYTjBaVzVsY2lod2NtOW5jbVZ6Y3lrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5S1R0Y2JpQWdJQ0FnSUNBZ2ZTd2dkbTlwWkNBd0tUdGNiaUFnSUNCOU8xeHVYRzRnSUNBZ2NtVjBkWEp1SUdSbFptVnljbVZrTzF4dWZWeHVYRzR2S2lwY2JpQXFJRU55WldGMFpYTWdZU0JPYjJSbExYTjBlV3hsSUdOaGJHeGlZV05ySUhSb1lYUWdkMmxzYkNCeVpYTnZiSFpsSUc5eUlISmxhbVZqZENCMGFHVWdaR1ZtWlhKeVpXUmNiaUFxSUhCeWIyMXBjMlV1WEc0Z0tpQkFjbVYwZFhKdWN5QmhJRzV2WkdWaVlXTnJYRzRnS2k5Y2JtUmxabVZ5TG5CeWIzUnZkSGx3WlM1dFlXdGxUbTlrWlZKbGMyOXNkbVZ5SUQwZ1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lIWmhjaUJ6Wld4bUlEMGdkR2hwY3p0Y2JpQWdJQ0J5WlhSMWNtNGdablZ1WTNScGIyNGdLR1Z5Y205eUxDQjJZV3gxWlNrZ2UxeHVJQ0FnSUNBZ0lDQnBaaUFvWlhKeWIzSXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lITmxiR1l1Y21WcVpXTjBLR1Z5Y205eUtUdGNiaUFnSUNBZ0lDQWdmU0JsYkhObElHbG1JQ2hoY21kMWJXVnVkSE11YkdWdVozUm9JRDRnTWlrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYzJWc1ppNXlaWE52YkhabEtHRnljbUY1WDNOc2FXTmxLR0Z5WjNWdFpXNTBjeXdnTVNrcE8xeHVJQ0FnSUNBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYzJWc1ppNXlaWE52YkhabEtIWmhiSFZsS1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUgwN1hHNTlPMXh1WEc0dktpcGNiaUFxSUVCd1lYSmhiU0J5WlhOdmJIWmxjaUI3Um5WdVkzUnBiMjU5SUdFZ1puVnVZM1JwYjI0Z2RHaGhkQ0J5WlhSMWNtNXpJRzV2ZEdocGJtY2dZVzVrSUdGalkyVndkSE5jYmlBcUlIUm9aU0J5WlhOdmJIWmxMQ0J5WldwbFkzUXNJR0Z1WkNCdWIzUnBabmtnWm5WdVkzUnBiMjV6SUdadmNpQmhJR1JsWm1WeWNtVmtMbHh1SUNvZ1FISmxkSFZ5Ym5NZ1lTQndjbTl0YVhObElIUm9ZWFFnYldGNUlHSmxJSEpsYzI5c2RtVmtJSGRwZEdnZ2RHaGxJR2RwZG1WdUlISmxjMjlzZG1VZ1lXNWtJSEpsYW1WamRGeHVJQ29nWm5WdVkzUnBiMjV6TENCdmNpQnlaV3BsWTNSbFpDQmllU0JoSUhSb2NtOTNiaUJsZUdObGNIUnBiMjRnYVc0Z2NtVnpiMngyWlhKY2JpQXFMMXh1VVM1UWNtOXRhWE5sSUQwZ2NISnZiV2x6WlRzZ0x5OGdSVk0yWEc1UkxuQnliMjFwYzJVZ1BTQndjbTl0YVhObE8xeHVablZ1WTNScGIyNGdjSEp2YldselpTaHlaWE52YkhabGNpa2dlMXh1SUNBZ0lHbG1JQ2gwZVhCbGIyWWdjbVZ6YjJ4MlpYSWdJVDA5SUZ3aVpuVnVZM1JwYjI1Y0lpa2dlMXh1SUNBZ0lDQWdJQ0IwYUhKdmR5QnVaWGNnVkhsd1pVVnljbTl5S0Z3aWNtVnpiMngyWlhJZ2JYVnpkQ0JpWlNCaElHWjFibU4wYVc5dUxsd2lLVHRjYmlBZ0lDQjlYRzRnSUNBZ2RtRnlJR1JsWm1WeWNtVmtJRDBnWkdWbVpYSW9LVHRjYmlBZ0lDQjBjbmtnZTF4dUlDQWdJQ0FnSUNCeVpYTnZiSFpsY2loa1pXWmxjbkpsWkM1eVpYTnZiSFpsTENCa1pXWmxjbkpsWkM1eVpXcGxZM1FzSUdSbFptVnljbVZrTG01dmRHbG1lU2s3WEc0Z0lDQWdmU0JqWVhSamFDQW9jbVZoYzI5dUtTQjdYRzRnSUNBZ0lDQWdJR1JsWm1WeWNtVmtMbkpsYW1WamRDaHlaV0Z6YjI0cE8xeHVJQ0FnSUgxY2JpQWdJQ0J5WlhSMWNtNGdaR1ZtWlhKeVpXUXVjSEp2YldselpUdGNibjFjYmx4dWNISnZiV2x6WlM1eVlXTmxJRDBnY21GalpUc2dMeThnUlZNMlhHNXdjbTl0YVhObExtRnNiQ0E5SUdGc2JEc2dMeThnUlZNMlhHNXdjbTl0YVhObExuSmxhbVZqZENBOUlISmxhbVZqZERzZ0x5OGdSVk0yWEc1d2NtOXRhWE5sTG5KbGMyOXNkbVVnUFNCUk95QXZMeUJGVXpaY2JseHVMeThnV0ZoWUlHVjRjR1Z5YVcxbGJuUmhiQzRnSUZSb2FYTWdiV1YwYUc5a0lHbHpJR0VnZDJGNUlIUnZJR1JsYm05MFpTQjBhR0YwSUdFZ2JHOWpZV3dnZG1Gc2RXVWdhWE5jYmk4dklITmxjbWxoYkdsNllXSnNaU0JoYm1RZ2MyaHZkV3hrSUdKbElHbHRiV1ZrYVdGMFpXeDVJR1JwYzNCaGRHTm9aV1FnZEc4Z1lTQnlaVzF2ZEdVZ2RYQnZiaUJ5WlhGMVpYTjBMRnh1THk4Z2FXNXpkR1ZoWkNCdlppQndZWE56YVc1bklHRWdjbVZtWlhKbGJtTmxMbHh1VVM1d1lYTnpRbmxEYjNCNUlEMGdablZ1WTNScGIyNGdLRzlpYW1WamRDa2dlMXh1SUNBZ0lDOHZabkpsWlhwbEtHOWlhbVZqZENrN1hHNGdJQ0FnTHk5d1lYTnpRbmxEYjNCcFpYTXVjMlYwS0c5aWFtVmpkQ3dnZEhKMVpTazdYRzRnSUNBZ2NtVjBkWEp1SUc5aWFtVmpkRHRjYm4wN1hHNWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbkJoYzNOQ2VVTnZjSGtnUFNCbWRXNWpkR2x2YmlBb0tTQjdYRzRnSUNBZ0x5OW1jbVZsZW1Vb2IySnFaV04wS1R0Y2JpQWdJQ0F2TDNCaGMzTkNlVU52Y0dsbGN5NXpaWFFvYjJKcVpXTjBMQ0IwY25WbEtUdGNiaUFnSUNCeVpYUjFjbTRnZEdocGN6dGNibjA3WEc1Y2JpOHFLbHh1SUNvZ1NXWWdkSGR2SUhCeWIyMXBjMlZ6SUdWMlpXNTBkV0ZzYkhrZ1puVnNabWxzYkNCMGJ5QjBhR1VnYzJGdFpTQjJZV3gxWlN3Z2NISnZiV2x6WlhNZ2RHaGhkQ0IyWVd4MVpTeGNiaUFxSUdKMWRDQnZkR2hsY25kcGMyVWdjbVZxWldOMGN5NWNiaUFxSUVCd1lYSmhiU0I0SUh0QmJua3FmVnh1SUNvZ1FIQmhjbUZ0SUhrZ2UwRnVlU3A5WEc0Z0tpQkFjbVYwZFhKdWN5QjdRVzU1S24wZ1lTQndjbTl0YVhObElHWnZjaUI0SUdGdVpDQjVJR2xtSUhSb1pYa2dZWEpsSUhSb1pTQnpZVzFsTENCaWRYUWdZU0J5WldwbFkzUnBiMjVjYmlBcUlHOTBhR1Z5ZDJselpTNWNiaUFxWEc0Z0tpOWNibEV1YW05cGJpQTlJR1oxYm1OMGFXOXVJQ2g0TENCNUtTQjdYRzRnSUNBZ2NtVjBkWEp1SUZFb2VDa3VhbTlwYmloNUtUdGNibjA3WEc1Y2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExtcHZhVzRnUFNCbWRXNWpkR2x2YmlBb2RHaGhkQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQlJLRnQwYUdsekxDQjBhR0YwWFNrdWMzQnlaV0ZrS0daMWJtTjBhVzl1SUNoNExDQjVLU0I3WEc0Z0lDQWdJQ0FnSUdsbUlDaDRJRDA5UFNCNUtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QlVUMFJQT2lCY0lqMDlQVndpSUhOb2IzVnNaQ0JpWlNCUFltcGxZM1F1YVhNZ2IzSWdaWEYxYVhaY2JpQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQjRPMXh1SUNBZ0lDQWdJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2RHaHliM2NnYm1WM0lFVnljbTl5S0Z3aVEyRnVKM1FnYW05cGJqb2dibTkwSUhSb1pTQnpZVzFsT2lCY0lpQXJJSGdnS3lCY0lpQmNJaUFySUhrcE8xeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ2ZTazdYRzU5TzF4dVhHNHZLaXBjYmlBcUlGSmxkSFZ5Ym5NZ1lTQndjbTl0YVhObElHWnZjaUIwYUdVZ1ptbHljM1FnYjJZZ1lXNGdZWEp5WVhrZ2IyWWdjSEp2YldselpYTWdkRzhnWW1WamIyMWxJSE5sZEhSc1pXUXVYRzRnS2lCQWNHRnlZVzBnWVc1emQyVnljeUI3UVhKeVlYbGJRVzU1S2wxOUlIQnliMjFwYzJWeklIUnZJSEpoWTJWY2JpQXFJRUJ5WlhSMWNtNXpJSHRCYm5rcWZTQjBhR1VnWm1seWMzUWdjSEp2YldselpTQjBieUJpWlNCelpYUjBiR1ZrWEc0Z0tpOWNibEV1Y21GalpTQTlJSEpoWTJVN1hHNW1kVzVqZEdsdmJpQnlZV05sS0dGdWMzZGxjbEJ6S1NCN1hHNGdJQ0FnY21WMGRYSnVJSEJ5YjIxcGMyVW9ablZ1WTNScGIyNGdLSEpsYzI5c2RtVXNJSEpsYW1WamRDa2dlMXh1SUNBZ0lDQWdJQ0F2THlCVGQybDBZMmdnZEc4Z2RHaHBjeUJ2Ym1ObElIZGxJR05oYmlCaGMzTjFiV1VnWVhRZ2JHVmhjM1FnUlZNMVhHNGdJQ0FnSUNBZ0lDOHZJR0Z1YzNkbGNsQnpMbVp2Y2tWaFkyZ29ablZ1WTNScGIyNGdLR0Z1YzNkbGNsQXBJSHRjYmlBZ0lDQWdJQ0FnTHk4Z0lDQWdJRkVvWVc1emQyVnlVQ2t1ZEdobGJpaHlaWE52YkhabExDQnlaV3BsWTNRcE8xeHVJQ0FnSUNBZ0lDQXZMeUI5S1R0Y2JpQWdJQ0FnSUNBZ0x5OGdWWE5sSUhSb2FYTWdhVzRnZEdobElHMWxZVzUwYVcxbFhHNGdJQ0FnSUNBZ0lHWnZjaUFvZG1GeUlHa2dQU0F3TENCc1pXNGdQU0JoYm5OM1pYSlFjeTVzWlc1bmRHZzdJR2tnUENCc1pXNDdJR2tyS3lrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnVVNoaGJuTjNaWEpRYzF0cFhTa3VkR2hsYmloeVpYTnZiSFpsTENCeVpXcGxZM1FwTzF4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnZlNrN1hHNTlYRzVjYmxCeWIyMXBjMlV1Y0hKdmRHOTBlWEJsTG5KaFkyVWdQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnY21WMGRYSnVJSFJvYVhNdWRHaGxiaWhSTG5KaFkyVXBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQkRiMjV6ZEhKMVkzUnpJR0VnVUhKdmJXbHpaU0IzYVhSb0lHRWdjSEp2YldselpTQmtaWE5qY21sd2RHOXlJRzlpYW1WamRDQmhibVFnYjNCMGFXOXVZV3dnWm1Gc2JHSmhZMnRjYmlBcUlHWjFibU4wYVc5dUxpQWdWR2hsSUdSbGMyTnlhWEIwYjNJZ1kyOXVkR0ZwYm5NZ2JXVjBhRzlrY3lCc2FXdGxJSGRvWlc0b2NtVnFaV04wWldRcExDQm5aWFFvYm1GdFpTa3NYRzRnS2lCelpYUW9ibUZ0WlN3Z2RtRnNkV1VwTENCd2IzTjBLRzVoYldVc0lHRnlaM01wTENCaGJtUWdaR1ZzWlhSbEtHNWhiV1VwTENCM2FHbGphQ0JoYkd4Y2JpQXFJSEpsZEhWeWJpQmxhWFJvWlhJZ1lTQjJZV3gxWlN3Z1lTQndjbTl0YVhObElHWnZjaUJoSUhaaGJIVmxMQ0J2Y2lCaElISmxhbVZqZEdsdmJpNGdJRlJvWlNCbVlXeHNZbUZqYTF4dUlDb2dZV05qWlhCMGN5QjBhR1VnYjNCbGNtRjBhVzl1SUc1aGJXVXNJR0VnY21WemIyeDJaWElzSUdGdVpDQmhibmtnWm5WeWRHaGxjaUJoY21kMWJXVnVkSE1nZEdoaGRDQjNiM1ZzWkZ4dUlDb2dhR0YyWlNCaVpXVnVJR1p2Y25kaGNtUmxaQ0IwYnlCMGFHVWdZWEJ3Y205d2NtbGhkR1VnYldWMGFHOWtJR0ZpYjNabElHaGhaQ0JoSUcxbGRHaHZaQ0JpWldWdVhHNGdLaUJ3Y205MmFXUmxaQ0IzYVhSb0lIUm9aU0J3Y205d1pYSWdibUZ0WlM0Z0lGUm9aU0JCVUVrZ2JXRnJaWE1nYm04Z1ozVmhjbUZ1ZEdWbGN5QmhZbTkxZENCMGFHVWdibUYwZFhKbFhHNGdLaUJ2WmlCMGFHVWdjbVYwZFhKdVpXUWdiMkpxWldOMExDQmhjR0Z5ZENCbWNtOXRJSFJvWVhRZ2FYUWdhWE1nZFhOaFlteGxJSGRvWlhKbFpYWmxjaUJ3Y205dGFYTmxjeUJoY21WY2JpQXFJR0p2ZFdkb2RDQmhibVFnYzI5c1pDNWNiaUFxTDF4dVVTNXRZV3RsVUhKdmJXbHpaU0E5SUZCeWIyMXBjMlU3WEc1bWRXNWpkR2x2YmlCUWNtOXRhWE5sS0dSbGMyTnlhWEIwYjNJc0lHWmhiR3hpWVdOckxDQnBibk53WldOMEtTQjdYRzRnSUNBZ2FXWWdLR1poYkd4aVlXTnJJRDA5UFNCMmIybGtJREFwSUh0Y2JpQWdJQ0FnSUNBZ1ptRnNiR0poWTJzZ1BTQm1kVzVqZEdsdmJpQW9iM0FwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQnlaV3BsWTNRb2JtVjNJRVZ5Y205eUtGeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lGd2lVSEp2YldselpTQmtiMlZ6SUc1dmRDQnpkWEJ3YjNKMElHOXdaWEpoZEdsdmJqb2dYQ0lnS3lCdmNGeHVJQ0FnSUNBZ0lDQWdJQ0FnS1NrN1hHNGdJQ0FnSUNBZ0lIMDdYRzRnSUNBZ2ZWeHVJQ0FnSUdsbUlDaHBibk53WldOMElEMDlQU0IyYjJsa0lEQXBJSHRjYmlBZ0lDQWdJQ0FnYVc1emNHVmpkQ0E5SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhKbGRIVnliaUI3YzNSaGRHVTZJRndpZFc1cmJtOTNibHdpZlR0Y2JpQWdJQ0FnSUNBZ2ZUdGNiaUFnSUNCOVhHNWNiaUFnSUNCMllYSWdjSEp2YldselpTQTlJRzlpYW1WamRGOWpjbVZoZEdVb1VISnZiV2x6WlM1d2NtOTBiM1I1Y0dVcE8xeHVYRzRnSUNBZ2NISnZiV2x6WlM1d2NtOXRhWE5sUkdsemNHRjBZMmdnUFNCbWRXNWpkR2x2YmlBb2NtVnpiMngyWlN3Z2IzQXNJR0Z5WjNNcElIdGNiaUFnSUNBZ0lDQWdkbUZ5SUhKbGMzVnNkRHRjYmlBZ0lDQWdJQ0FnZEhKNUlIdGNiaUFnSUNBZ0lDQWdJQ0FnSUdsbUlDaGtaWE5qY21sd2RHOXlXMjl3WFNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lISmxjM1ZzZENBOUlHUmxjMk55YVhCMGIzSmJiM0JkTG1Gd2NHeDVLSEJ5YjIxcGMyVXNJR0Z5WjNNcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0J5WlhOMWJIUWdQU0JtWVd4c1ltRmpheTVqWVd4c0tIQnliMjFwYzJVc0lHOXdMQ0JoY21kektUdGNiaUFnSUNBZ0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ2ZTQmpZWFJqYUNBb1pYaGpaWEIwYVc5dUtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCeVpYTjFiSFFnUFNCeVpXcGxZM1FvWlhoalpYQjBhVzl1S1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQnBaaUFvY21WemIyeDJaU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjbVZ6YjJ4MlpTaHlaWE4xYkhRcE8xeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ2ZUdGNibHh1SUNBZ0lIQnliMjFwYzJVdWFXNXpjR1ZqZENBOUlHbHVjM0JsWTNRN1hHNWNiaUFnSUNBdkx5QllXRmdnWkdWd2NtVmpZWFJsWkNCZ2RtRnNkV1ZQWm1BZ1lXNWtJR0JsZUdObGNIUnBiMjVnSUhOMWNIQnZjblJjYmlBZ0lDQnBaaUFvYVc1emNHVmpkQ2tnZTF4dUlDQWdJQ0FnSUNCMllYSWdhVzV6Y0dWamRHVmtJRDBnYVc1emNHVmpkQ2dwTzF4dUlDQWdJQ0FnSUNCcFppQW9hVzV6Y0dWamRHVmtMbk4wWVhSbElEMDlQU0JjSW5KbGFtVmpkR1ZrWENJcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhCeWIyMXBjMlV1WlhoalpYQjBhVzl1SUQwZ2FXNXpjR1ZqZEdWa0xuSmxZWE52Ymp0Y2JpQWdJQ0FnSUNBZ2ZWeHVYRzRnSUNBZ0lDQWdJSEJ5YjIxcGMyVXVkbUZzZFdWUFppQTlJR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFpoY2lCcGJuTndaV04wWldRZ1BTQnBibk53WldOMEtDazdYRzRnSUNBZ0lDQWdJQ0FnSUNCcFppQW9hVzV6Y0dWamRHVmtMbk4wWVhSbElEMDlQU0JjSW5CbGJtUnBibWRjSWlCOGZGeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHbHVjM0JsWTNSbFpDNXpkR0YwWlNBOVBUMGdYQ0p5WldwbFkzUmxaRndpS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhCeWIyMXBjMlU3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJQ0FnSUNCeVpYUjFjbTRnYVc1emNHVmpkR1ZrTG5aaGJIVmxPMXh1SUNBZ0lDQWdJQ0I5TzF4dUlDQWdJSDFjYmx4dUlDQWdJSEpsZEhWeWJpQndjbTl0YVhObE8xeHVmVnh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1MGIxTjBjbWx1WnlBOUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQnlaWFIxY200Z1hDSmJiMkpxWldOMElGQnliMjFwYzJWZFhDSTdYRzU5TzF4dVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNTBhR1Z1SUQwZ1puVnVZM1JwYjI0Z0tHWjFiR1pwYkd4bFpDd2djbVZxWldOMFpXUXNJSEJ5YjJkeVpYTnpaV1FwSUh0Y2JpQWdJQ0IyWVhJZ2MyVnNaaUE5SUhSb2FYTTdYRzRnSUNBZ2RtRnlJR1JsWm1WeWNtVmtJRDBnWkdWbVpYSW9LVHRjYmlBZ0lDQjJZWElnWkc5dVpTQTlJR1poYkhObE95QWdJQzh2SUdWdWMzVnlaU0IwYUdVZ2RXNTBjblZ6ZEdWa0lIQnliMjFwYzJVZ2JXRnJaWE1nWVhRZ2JXOXpkQ0JoWEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0F2THlCemFXNW5iR1VnWTJGc2JDQjBieUJ2Ym1VZ2IyWWdkR2hsSUdOaGJHeGlZV05yYzF4dVhHNGdJQ0FnWm5WdVkzUnBiMjRnWDJaMWJHWnBiR3hsWkNoMllXeDFaU2tnZTF4dUlDQWdJQ0FnSUNCMGNua2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhSNWNHVnZaaUJtZFd4bWFXeHNaV1FnUFQwOUlGd2lablZ1WTNScGIyNWNJaUEvSUdaMWJHWnBiR3hsWkNoMllXeDFaU2tnT2lCMllXeDFaVHRjYmlBZ0lDQWdJQ0FnZlNCallYUmphQ0FvWlhoalpYQjBhVzl1S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdjbVZxWldOMEtHVjRZMlZ3ZEdsdmJpazdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQjlYRzVjYmlBZ0lDQm1kVzVqZEdsdmJpQmZjbVZxWldOMFpXUW9aWGhqWlhCMGFXOXVLU0I3WEc0Z0lDQWdJQ0FnSUdsbUlDaDBlWEJsYjJZZ2NtVnFaV04wWldRZ1BUMDlJRndpWm5WdVkzUnBiMjVjSWlrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYldGclpWTjBZV05yVkhKaFkyVk1iMjVuS0dWNFkyVndkR2x2Yml3Z2MyVnNaaWs3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjBjbmtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhKbGRIVnliaUJ5WldwbFkzUmxaQ2hsZUdObGNIUnBiMjRwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmU0JqWVhSamFDQW9ibVYzUlhoalpYQjBhVzl1S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhKbGFtVmpkQ2h1WlhkRmVHTmxjSFJwYjI0cE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCeVpXcGxZM1FvWlhoalpYQjBhVzl1S1R0Y2JpQWdJQ0I5WEc1Y2JpQWdJQ0JtZFc1amRHbHZiaUJmY0hKdlozSmxjM05sWkNoMllXeDFaU2tnZTF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnZEhsd1pXOW1JSEJ5YjJkeVpYTnpaV1FnUFQwOUlGd2lablZ1WTNScGIyNWNJaUEvSUhCeWIyZHlaWE56WldRb2RtRnNkV1VwSURvZ2RtRnNkV1U3WEc0Z0lDQWdmVnh1WEc0Z0lDQWdVUzV1WlhoMFZHbGpheWhtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lITmxiR1l1Y0hKdmJXbHpaVVJwYzNCaGRHTm9LR1oxYm1OMGFXOXVJQ2gyWVd4MVpTa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLR1J2Ym1VcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200N1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUNBZ0lDQmtiMjVsSUQwZ2RISjFaVHRjYmx4dUlDQWdJQ0FnSUNBZ0lDQWdaR1ZtWlhKeVpXUXVjbVZ6YjJ4MlpTaGZablZzWm1sc2JHVmtLSFpoYkhWbEtTazdYRzRnSUNBZ0lDQWdJSDBzSUZ3aWQyaGxibHdpTENCYlpuVnVZM1JwYjI0Z0tHVjRZMlZ3ZEdsdmJpa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLR1J2Ym1VcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200N1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUNBZ0lDQmtiMjVsSUQwZ2RISjFaVHRjYmx4dUlDQWdJQ0FnSUNBZ0lDQWdaR1ZtWlhKeVpXUXVjbVZ6YjJ4MlpTaGZjbVZxWldOMFpXUW9aWGhqWlhCMGFXOXVLU2s3WEc0Z0lDQWdJQ0FnSUgxZEtUdGNiaUFnSUNCOUtUdGNibHh1SUNBZ0lDOHZJRkJ5YjJkeVpYTnpJSEJ5YjNCaFoyRjBiM0lnYm1WbFpDQjBieUJpWlNCaGRIUmhZMmhsWkNCcGJpQjBhR1VnWTNWeWNtVnVkQ0IwYVdOckxseHVJQ0FnSUhObGJHWXVjSEp2YldselpVUnBjM0JoZEdOb0tIWnZhV1FnTUN3Z1hDSjNhR1Z1WENJc0lGdDJiMmxrSURBc0lHWjFibU4wYVc5dUlDaDJZV3gxWlNrZ2UxeHVJQ0FnSUNBZ0lDQjJZWElnYm1WM1ZtRnNkV1U3WEc0Z0lDQWdJQ0FnSUhaaGNpQjBhSEpsZHlBOUlHWmhiSE5sTzF4dUlDQWdJQ0FnSUNCMGNua2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2JtVjNWbUZzZFdVZ1BTQmZjSEp2WjNKbGMzTmxaQ2gyWVd4MVpTazdYRzRnSUNBZ0lDQWdJSDBnWTJGMFkyZ2dLR1VwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFJvY21WM0lEMGdkSEoxWlR0Y2JpQWdJQ0FnSUNBZ0lDQWdJR2xtSUNoUkxtOXVaWEp5YjNJcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQlJMbTl1WlhKeWIzSW9aU2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lIUm9jbTkzSUdVN1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUgxY2JseHVJQ0FnSUNBZ0lDQnBaaUFvSVhSb2NtVjNLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQmtaV1psY25KbFpDNXViM1JwWm5rb2JtVjNWbUZzZFdVcE8xeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ2ZWMHBPMXh1WEc0Z0lDQWdjbVYwZFhKdUlHUmxabVZ5Y21Wa0xuQnliMjFwYzJVN1hHNTlPMXh1WEc1UkxuUmhjQ0E5SUdaMWJtTjBhVzl1SUNod2NtOXRhWE5sTENCallXeHNZbUZqYXlrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0hCeWIyMXBjMlVwTG5SaGNDaGpZV3hzWW1GamF5azdYRzU5TzF4dVhHNHZLaXBjYmlBcUlGZHZjbXR6SUdGc2JXOXpkQ0JzYVd0bElGd2labWx1WVd4c2VWd2lMQ0JpZFhRZ2JtOTBJR05oYkd4bFpDQm1iM0lnY21WcVpXTjBhVzl1Y3k1Y2JpQXFJRTl5YVdkcGJtRnNJSEpsYzI5c2RYUnBiMjRnZG1Gc2RXVWdhWE1nY0dGemMyVmtJSFJvY205MVoyZ2dZMkZzYkdKaFkyc2dkVzVoWm1abFkzUmxaQzVjYmlBcUlFTmhiR3hpWVdOcklHMWhlU0J5WlhSMWNtNGdZU0J3Y205dGFYTmxJSFJvWVhRZ2QybHNiQ0JpWlNCaGQyRnBkR1ZrSUdadmNpNWNiaUFxSUVCd1lYSmhiU0I3Um5WdVkzUnBiMjU5SUdOaGJHeGlZV05yWEc0Z0tpQkFjbVYwZFhKdWN5QjdVUzVRY205dGFYTmxmVnh1SUNvZ1FHVjRZVzF3YkdWY2JpQXFJR1J2VTI5dFpYUm9hVzVuS0NsY2JpQXFJQ0FnTG5Sb1pXNG9MaTR1S1Z4dUlDb2dJQ0F1ZEdGd0tHTnZibk52YkdVdWJHOW5LVnh1SUNvZ0lDQXVkR2hsYmlndUxpNHBPMXh1SUNvdlhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNTBZWEFnUFNCbWRXNWpkR2x2YmlBb1kyRnNiR0poWTJzcElIdGNiaUFnSUNCallXeHNZbUZqYXlBOUlGRW9ZMkZzYkdKaFkyc3BPMXh1WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11ZEdobGJpaG1kVzVqZEdsdmJpQW9kbUZzZFdVcElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHTmhiR3hpWVdOckxtWmpZV3hzS0haaGJIVmxLUzUwYUdWdVVtVnpiMngyWlNoMllXeDFaU2s3WEc0Z0lDQWdmU2s3WEc1OU8xeHVYRzR2S2lwY2JpQXFJRkpsWjJsemRHVnljeUJoYmlCdlluTmxjblpsY2lCdmJpQmhJSEJ5YjIxcGMyVXVYRzRnS2x4dUlDb2dSM1ZoY21GdWRHVmxjenBjYmlBcVhHNGdLaUF4TGlCMGFHRjBJR1oxYkdacGJHeGxaQ0JoYm1RZ2NtVnFaV04wWldRZ2QybHNiQ0JpWlNCallXeHNaV1FnYjI1c2VTQnZibU5sTGx4dUlDb2dNaTRnZEdoaGRDQmxhWFJvWlhJZ2RHaGxJR1oxYkdacGJHeGxaQ0JqWVd4c1ltRmpheUJ2Y2lCMGFHVWdjbVZxWldOMFpXUWdZMkZzYkdKaFkyc2dkMmxzYkNCaVpWeHVJQ29nSUNBZ1kyRnNiR1ZrTENCaWRYUWdibTkwSUdKdmRHZ3VYRzRnS2lBekxpQjBhR0YwSUdaMWJHWnBiR3hsWkNCaGJtUWdjbVZxWldOMFpXUWdkMmxzYkNCdWIzUWdZbVVnWTJGc2JHVmtJR2x1SUhSb2FYTWdkSFZ5Ymk1Y2JpQXFYRzRnS2lCQWNHRnlZVzBnZG1Gc2RXVWdJQ0FnSUNCd2NtOXRhWE5sSUc5eUlHbHRiV1ZrYVdGMFpTQnlaV1psY21WdVkyVWdkRzhnYjJKelpYSjJaVnh1SUNvZ1FIQmhjbUZ0SUdaMWJHWnBiR3hsWkNBZ1puVnVZM1JwYjI0Z2RHOGdZbVVnWTJGc2JHVmtJSGRwZEdnZ2RHaGxJR1oxYkdacGJHeGxaQ0IyWVd4MVpWeHVJQ29nUUhCaGNtRnRJSEpsYW1WamRHVmtJQ0FnWm5WdVkzUnBiMjRnZEc4Z1ltVWdZMkZzYkdWa0lIZHBkR2dnZEdobElISmxhbVZqZEdsdmJpQmxlR05sY0hScGIyNWNiaUFxSUVCd1lYSmhiU0J3Y205bmNtVnpjMlZrSUdaMWJtTjBhVzl1SUhSdklHSmxJR05oYkd4bFpDQnZiaUJoYm5rZ2NISnZaM0psYzNNZ2JtOTBhV1pwWTJGMGFXOXVjMXh1SUNvZ1FISmxkSFZ5YmlCd2NtOXRhWE5sSUdadmNpQjBhR1VnY21WMGRYSnVJSFpoYkhWbElHWnliMjBnZEdobElHbHVkbTlyWldRZ1kyRnNiR0poWTJ0Y2JpQXFMMXh1VVM1M2FHVnVJRDBnZDJobGJqdGNibVoxYm1OMGFXOXVJSGRvWlc0b2RtRnNkV1VzSUdaMWJHWnBiR3hsWkN3Z2NtVnFaV04wWldRc0lIQnliMmR5WlhOelpXUXBJSHRjYmlBZ0lDQnlaWFIxY200Z1VTaDJZV3gxWlNrdWRHaGxiaWhtZFd4bWFXeHNaV1FzSUhKbGFtVmpkR1ZrTENCd2NtOW5jbVZ6YzJWa0tUdGNibjFjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWRHaGxibEpsYzI5c2RtVWdQU0JtZFc1amRHbHZiaUFvZG1Gc2RXVXBJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTUwYUdWdUtHWjFibU4wYVc5dUlDZ3BJSHNnY21WMGRYSnVJSFpoYkhWbE95QjlLVHRjYm4wN1hHNWNibEV1ZEdobGJsSmxjMjlzZG1VZ1BTQm1kVzVqZEdsdmJpQW9jSEp2YldselpTd2dkbUZzZFdVcElIdGNiaUFnSUNCeVpYUjFjbTRnVVNod2NtOXRhWE5sS1M1MGFHVnVVbVZ6YjJ4MlpTaDJZV3gxWlNrN1hHNTlPMXh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1MGFHVnVVbVZxWldOMElEMGdablZ1WTNScGIyNGdLSEpsWVhOdmJpa2dlMXh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpMblJvWlc0b1puVnVZM1JwYjI0Z0tDa2dleUIwYUhKdmR5QnlaV0Z6YjI0N0lIMHBPMXh1ZlR0Y2JseHVVUzUwYUdWdVVtVnFaV04wSUQwZ1puVnVZM1JwYjI0Z0tIQnliMjFwYzJVc0lISmxZWE52YmlrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0hCeWIyMXBjMlVwTG5Sb1pXNVNaV3BsWTNRb2NtVmhjMjl1S1R0Y2JuMDdYRzVjYmk4cUtseHVJQ29nU1dZZ1lXNGdiMkpxWldOMElHbHpJRzV2ZENCaElIQnliMjFwYzJVc0lHbDBJR2x6SUdGeklGd2libVZoY2x3aUlHRnpJSEJ2YzNOcFlteGxMbHh1SUNvZ1NXWWdZU0J3Y205dGFYTmxJR2x6SUhKbGFtVmpkR1ZrTENCcGRDQnBjeUJoY3lCY0ltNWxZWEpjSWlCaGN5QndiM056YVdKc1pTQjBiMjh1WEc0Z0tpQkpaaUJwZE9LQW1YTWdZU0JtZFd4bWFXeHNaV1FnY0hKdmJXbHpaU3dnZEdobElHWjFiR1pwYkd4dFpXNTBJSFpoYkhWbElHbHpJRzVsWVhKbGNpNWNiaUFxSUVsbUlHbDA0b0NaY3lCaElHUmxabVZ5Y21Wa0lIQnliMjFwYzJVZ1lXNWtJSFJvWlNCa1pXWmxjbkpsWkNCb1lYTWdZbVZsYmlCeVpYTnZiSFpsWkN3Z2RHaGxYRzRnS2lCeVpYTnZiSFYwYVc5dUlHbHpJRndpYm1WaGNtVnlYQ0l1WEc0Z0tpQkFjR0Z5WVcwZ2IySnFaV04wWEc0Z0tpQkFjbVYwZFhKdWN5QnRiM04wSUhKbGMyOXNkbVZrSUNodVpXRnlaWE4wS1NCbWIzSnRJRzltSUhSb1pTQnZZbXBsWTNSY2JpQXFMMXh1WEc0dkx5QllXRmdnYzJodmRXeGtJSGRsSUhKbExXUnZJSFJvYVhNL1hHNVJMbTVsWVhKbGNpQTlJRzVsWVhKbGNqdGNibVoxYm1OMGFXOXVJRzVsWVhKbGNpaDJZV3gxWlNrZ2UxeHVJQ0FnSUdsbUlDaHBjMUJ5YjIxcGMyVW9kbUZzZFdVcEtTQjdYRzRnSUNBZ0lDQWdJSFpoY2lCcGJuTndaV04wWldRZ1BTQjJZV3gxWlM1cGJuTndaV04wS0NrN1hHNGdJQ0FnSUNBZ0lHbG1JQ2hwYm5Od1pXTjBaV1F1YzNSaGRHVWdQVDA5SUZ3aVpuVnNabWxzYkdWa1hDSXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lISmxkSFZ5YmlCcGJuTndaV04wWldRdWRtRnNkV1U3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0I5WEc0Z0lDQWdjbVYwZFhKdUlIWmhiSFZsTzF4dWZWeHVYRzR2S2lwY2JpQXFJRUJ5WlhSMWNtNXpJSGRvWlhSb1pYSWdkR2hsSUdkcGRtVnVJRzlpYW1WamRDQnBjeUJoSUhCeWIyMXBjMlV1WEc0Z0tpQlBkR2hsY25kcGMyVWdhWFFnYVhNZ1lTQm1kV3htYVd4c1pXUWdkbUZzZFdVdVhHNGdLaTljYmxFdWFYTlFjbTl0YVhObElEMGdhWE5RY205dGFYTmxPMXh1Wm5WdVkzUnBiMjRnYVhOUWNtOXRhWE5sS0c5aWFtVmpkQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQnZZbXBsWTNRZ2FXNXpkR0Z1WTJWdlppQlFjbTl0YVhObE8xeHVmVnh1WEc1UkxtbHpVSEp2YldselpVRnNhV3RsSUQwZ2FYTlFjbTl0YVhObFFXeHBhMlU3WEc1bWRXNWpkR2x2YmlCcGMxQnliMjFwYzJWQmJHbHJaU2h2WW1wbFkzUXBJSHRjYmlBZ0lDQnlaWFIxY200Z2FYTlBZbXBsWTNRb2IySnFaV04wS1NBbUppQjBlWEJsYjJZZ2IySnFaV04wTG5Sb1pXNGdQVDA5SUZ3aVpuVnVZM1JwYjI1Y0lqdGNibjFjYmx4dUx5b3FYRzRnS2lCQWNtVjBkWEp1Y3lCM2FHVjBhR1Z5SUhSb1pTQm5hWFpsYmlCdlltcGxZM1FnYVhNZ1lTQndaVzVrYVc1bklIQnliMjFwYzJVc0lHMWxZVzVwYm1jZ2JtOTBYRzRnS2lCbWRXeG1hV3hzWldRZ2IzSWdjbVZxWldOMFpXUXVYRzRnS2k5Y2JsRXVhWE5RWlc1a2FXNW5JRDBnYVhOUVpXNWthVzVuTzF4dVpuVnVZM1JwYjI0Z2FYTlFaVzVrYVc1bktHOWlhbVZqZENrZ2UxeHVJQ0FnSUhKbGRIVnliaUJwYzFCeWIyMXBjMlVvYjJKcVpXTjBLU0FtSmlCdlltcGxZM1F1YVc1emNHVmpkQ2dwTG5OMFlYUmxJRDA5UFNCY0luQmxibVJwYm1kY0lqdGNibjFjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWFYTlFaVzVrYVc1bklEMGdablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TG1sdWMzQmxZM1FvS1M1emRHRjBaU0E5UFQwZ1hDSndaVzVrYVc1blhDSTdYRzU5TzF4dVhHNHZLaXBjYmlBcUlFQnlaWFIxY201eklIZG9aWFJvWlhJZ2RHaGxJR2RwZG1WdUlHOWlhbVZqZENCcGN5QmhJSFpoYkhWbElHOXlJR1oxYkdacGJHeGxaRnh1SUNvZ2NISnZiV2x6WlM1Y2JpQXFMMXh1VVM1cGMwWjFiR1pwYkd4bFpDQTlJR2x6Um5Wc1ptbHNiR1ZrTzF4dVpuVnVZM1JwYjI0Z2FYTkdkV3htYVd4c1pXUW9iMkpxWldOMEtTQjdYRzRnSUNBZ2NtVjBkWEp1SUNGcGMxQnliMjFwYzJVb2IySnFaV04wS1NCOGZDQnZZbXBsWTNRdWFXNXpjR1ZqZENncExuTjBZWFJsSUQwOVBTQmNJbVoxYkdacGJHeGxaRndpTzF4dWZWeHVYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzVwYzBaMWJHWnBiR3hsWkNBOUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTVwYm5Od1pXTjBLQ2t1YzNSaGRHVWdQVDA5SUZ3aVpuVnNabWxzYkdWa1hDSTdYRzU5TzF4dVhHNHZLaXBjYmlBcUlFQnlaWFIxY201eklIZG9aWFJvWlhJZ2RHaGxJR2RwZG1WdUlHOWlhbVZqZENCcGN5QmhJSEpsYW1WamRHVmtJSEJ5YjIxcGMyVXVYRzRnS2k5Y2JsRXVhWE5TWldwbFkzUmxaQ0E5SUdselVtVnFaV04wWldRN1hHNW1kVzVqZEdsdmJpQnBjMUpsYW1WamRHVmtLRzlpYW1WamRDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCcGMxQnliMjFwYzJVb2IySnFaV04wS1NBbUppQnZZbXBsWTNRdWFXNXpjR1ZqZENncExuTjBZWFJsSUQwOVBTQmNJbkpsYW1WamRHVmtYQ0k3WEc1OVhHNWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbWx6VW1WcVpXTjBaV1FnUFNCbWRXNWpkR2x2YmlBb0tTQjdYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTXVhVzV6Y0dWamRDZ3BMbk4wWVhSbElEMDlQU0JjSW5KbGFtVmpkR1ZrWENJN1hHNTlPMXh1WEc0dkx5OHZJRUpGUjBsT0lGVk9TRUZPUkV4RlJDQlNSVXBGUTFSSlQwNGdWRkpCUTB0SlRrZGNibHh1THk4Z1ZHaHBjeUJ3Y205dGFYTmxJR3hwWW5KaGNua2dZMjl1YzNWdFpYTWdaWGhqWlhCMGFXOXVjeUIwYUhKdmQyNGdhVzRnYUdGdVpHeGxjbk1nYzI4Z2RHaGxlU0JqWVc0Z1ltVmNiaTh2SUdoaGJtUnNaV1FnWW5rZ1lTQnpkV0p6WlhGMVpXNTBJSEJ5YjIxcGMyVXVJQ0JVYUdVZ1pYaGpaWEIwYVc5dWN5Qm5aWFFnWVdSa1pXUWdkRzhnZEdocGN5QmhjbkpoZVNCM2FHVnVYRzR2THlCMGFHVjVJR0Z5WlNCamNtVmhkR1ZrTENCaGJtUWdjbVZ0YjNabFpDQjNhR1Z1SUhSb1pYa2dZWEpsSUdoaGJtUnNaV1F1SUNCT2IzUmxJSFJvWVhRZ2FXNGdSVk0ySUc5eVhHNHZMeUJ6YUdsdGJXVmtJR1Z1ZG1seWIyNXRaVzUwY3l3Z2RHaHBjeUIzYjNWc1pDQnVZWFIxY21Gc2JIa2dZbVVnWVNCZ1UyVjBZQzVjYm5aaGNpQjFibWhoYm1Sc1pXUlNaV0Z6YjI1eklEMGdXMTA3WEc1MllYSWdkVzVvWVc1a2JHVmtVbVZxWldOMGFXOXVjeUE5SUZ0ZE8xeHVkbUZ5SUhKbGNHOXlkR1ZrVlc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3lBOUlGdGRPMXh1ZG1GeUlIUnlZV05yVlc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3lBOUlIUnlkV1U3WEc1Y2JtWjFibU4wYVc5dUlISmxjMlYwVlc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3lncElIdGNiaUFnSUNCMWJtaGhibVJzWldSU1pXRnpiMjV6TG14bGJtZDBhQ0E5SURBN1hHNGdJQ0FnZFc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3k1c1pXNW5kR2dnUFNBd08xeHVYRzRnSUNBZ2FXWWdLQ0YwY21GamExVnVhR0Z1Wkd4bFpGSmxhbVZqZEdsdmJuTXBJSHRjYmlBZ0lDQWdJQ0FnZEhKaFkydFZibWhoYm1Sc1pXUlNaV3BsWTNScGIyNXpJRDBnZEhKMVpUdGNiaUFnSUNCOVhHNTlYRzVjYm1aMWJtTjBhVzl1SUhSeVlXTnJVbVZxWldOMGFXOXVLSEJ5YjIxcGMyVXNJSEpsWVhOdmJpa2dlMXh1SUNBZ0lHbG1JQ2doZEhKaFkydFZibWhoYm1Sc1pXUlNaV3BsWTNScGIyNXpLU0I3WEc0Z0lDQWdJQ0FnSUhKbGRIVnlianRjYmlBZ0lDQjlYRzRnSUNBZ2FXWWdLSFI1Y0dWdlppQndjbTlqWlhOeklEMDlQU0JjSW05aWFtVmpkRndpSUNZbUlIUjVjR1Z2WmlCd2NtOWpaWE56TG1WdGFYUWdQVDA5SUZ3aVpuVnVZM1JwYjI1Y0lpa2dlMXh1SUNBZ0lDQWdJQ0JSTG01bGVIUlVhV05yTG5KMWJrRm1kR1Z5S0daMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUdsbUlDaGhjbkpoZVY5cGJtUmxlRTltS0hWdWFHRnVaR3hsWkZKbGFtVmpkR2x2Ym5Nc0lIQnliMjFwYzJVcElDRTlQU0F0TVNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lIQnliMk5sYzNNdVpXMXBkQ2hjSW5WdWFHRnVaR3hsWkZKbGFtVmpkR2x2Ymx3aUxDQnlaV0Z6YjI0c0lIQnliMjFwYzJVcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lISmxjRzl5ZEdWa1ZXNW9ZVzVrYkdWa1VtVnFaV04wYVc5dWN5NXdkWE5vS0hCeWIyMXBjMlVwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0I5S1R0Y2JpQWdJQ0I5WEc1Y2JpQWdJQ0IxYm1oaGJtUnNaV1JTWldwbFkzUnBiMjV6TG5CMWMyZ29jSEp2YldselpTazdYRzRnSUNBZ2FXWWdLSEpsWVhOdmJpQW1KaUIwZVhCbGIyWWdjbVZoYzI5dUxuTjBZV05ySUNFOVBTQmNJblZ1WkdWbWFXNWxaRndpS1NCN1hHNGdJQ0FnSUNBZ0lIVnVhR0Z1Wkd4bFpGSmxZWE52Ym5NdWNIVnphQ2h5WldGemIyNHVjM1JoWTJzcE8xeHVJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0FnSUhWdWFHRnVaR3hsWkZKbFlYTnZibk11Y0hWemFDaGNJaWh1YnlCemRHRmpheWtnWENJZ0t5QnlaV0Z6YjI0cE8xeHVJQ0FnSUgxY2JuMWNibHh1Wm5WdVkzUnBiMjRnZFc1MGNtRmphMUpsYW1WamRHbHZiaWh3Y205dGFYTmxLU0I3WEc0Z0lDQWdhV1lnS0NGMGNtRmphMVZ1YUdGdVpHeGxaRkpsYW1WamRHbHZibk1wSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1TzF4dUlDQWdJSDFjYmx4dUlDQWdJSFpoY2lCaGRDQTlJR0Z5Y21GNVgybHVaR1Y0VDJZb2RXNW9ZVzVrYkdWa1VtVnFaV04wYVc5dWN5d2djSEp2YldselpTazdYRzRnSUNBZ2FXWWdLR0YwSUNFOVBTQXRNU2tnZTF4dUlDQWdJQ0FnSUNCcFppQW9kSGx3Wlc5bUlIQnliMk5sYzNNZ1BUMDlJRndpYjJKcVpXTjBYQ0lnSmlZZ2RIbHdaVzltSUhCeWIyTmxjM011WlcxcGRDQTlQVDBnWENKbWRXNWpkR2x2Ymx3aUtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCUkxtNWxlSFJVYVdOckxuSjFia0ZtZEdWeUtHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0IyWVhJZ1lYUlNaWEJ2Y25RZ1BTQmhjbkpoZVY5cGJtUmxlRTltS0hKbGNHOXlkR1ZrVlc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3l3Z2NISnZiV2x6WlNrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLR0YwVW1Wd2IzSjBJQ0U5UFNBdE1Ta2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCd2NtOWpaWE56TG1WdGFYUW9YQ0p5WldwbFkzUnBiMjVJWVc1a2JHVmtYQ0lzSUhWdWFHRnVaR3hsWkZKbFlYTnZibk5iWVhSZExDQndjbTl0YVhObEtUdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY21Wd2IzSjBaV1JWYm1oaGJtUnNaV1JTWldwbFkzUnBiMjV6TG5Od2JHbGpaU2hoZEZKbGNHOXlkQ3dnTVNrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQWdJQ0FnZlNrN1hHNGdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lDQWdkVzVvWVc1a2JHVmtVbVZxWldOMGFXOXVjeTV6Y0d4cFkyVW9ZWFFzSURFcE8xeHVJQ0FnSUNBZ0lDQjFibWhoYm1Sc1pXUlNaV0Z6YjI1ekxuTndiR2xqWlNoaGRDd2dNU2s3WEc0Z0lDQWdmVnh1ZlZ4dVhHNVJMbkpsYzJWMFZXNW9ZVzVrYkdWa1VtVnFaV04wYVc5dWN5QTlJSEpsYzJWMFZXNW9ZVzVrYkdWa1VtVnFaV04wYVc5dWN6dGNibHh1VVM1blpYUlZibWhoYm1Sc1pXUlNaV0Z6YjI1eklEMGdablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJQzh2SUUxaGEyVWdZU0JqYjNCNUlITnZJSFJvWVhRZ1kyOXVjM1Z0WlhKeklHTmhiaWQwSUdsdWRHVnlabVZ5WlNCM2FYUm9JRzkxY2lCcGJuUmxjbTVoYkNCemRHRjBaUzVjYmlBZ0lDQnlaWFIxY200Z2RXNW9ZVzVrYkdWa1VtVmhjMjl1Y3k1emJHbGpaU2dwTzF4dWZUdGNibHh1VVM1emRHOXdWVzVvWVc1a2JHVmtVbVZxWldOMGFXOXVWSEpoWTJ0cGJtY2dQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnY21WelpYUlZibWhoYm1Sc1pXUlNaV3BsWTNScGIyNXpLQ2s3WEc0Z0lDQWdkSEpoWTJ0VmJtaGhibVJzWldSU1pXcGxZM1JwYjI1eklEMGdabUZzYzJVN1hHNTlPMXh1WEc1eVpYTmxkRlZ1YUdGdVpHeGxaRkpsYW1WamRHbHZibk1vS1R0Y2JseHVMeTh2THlCRlRrUWdWVTVJUVU1RVRFVkVJRkpGU2tWRFZFbFBUaUJVVWtGRFMwbE9SMXh1WEc0dktpcGNiaUFxSUVOdmJuTjBjblZqZEhNZ1lTQnlaV3BsWTNSbFpDQndjbTl0YVhObExseHVJQ29nUUhCaGNtRnRJSEpsWVhOdmJpQjJZV3gxWlNCa1pYTmpjbWxpYVc1bklIUm9aU0JtWVdsc2RYSmxYRzRnS2k5Y2JsRXVjbVZxWldOMElEMGdjbVZxWldOME8xeHVablZ1WTNScGIyNGdjbVZxWldOMEtISmxZWE52YmlrZ2UxeHVJQ0FnSUhaaGNpQnlaV3BsWTNScGIyNGdQU0JRY205dGFYTmxLSHRjYmlBZ0lDQWdJQ0FnWENKM2FHVnVYQ0k2SUdaMWJtTjBhVzl1SUNoeVpXcGxZM1JsWkNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnTHk4Z2JtOTBaU0IwYUdGMElIUm9aU0JsY25KdmNpQm9ZWE1nWW1WbGJpQm9ZVzVrYkdWa1hHNGdJQ0FnSUNBZ0lDQWdJQ0JwWmlBb2NtVnFaV04wWldRcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjFiblJ5WVdOclVtVnFaV04wYVc5dUtIUm9hWE1wTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhKbGFtVmpkR1ZrSUQ4Z2NtVnFaV04wWldRb2NtVmhjMjl1S1NBNklIUm9hWE03WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0I5TENCbWRXNWpkR2x2YmlCbVlXeHNZbUZqYXlncElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlIUm9hWE03WEc0Z0lDQWdmU3dnWm5WdVkzUnBiMjRnYVc1emNHVmpkQ2dwSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUhzZ2MzUmhkR1U2SUZ3aWNtVnFaV04wWldSY0lpd2djbVZoYzI5dU9pQnlaV0Z6YjI0Z2ZUdGNiaUFnSUNCOUtUdGNibHh1SUNBZ0lDOHZJRTV2ZEdVZ2RHaGhkQ0IwYUdVZ2NtVmhjMjl1SUdoaGN5QnViM1FnWW1WbGJpQm9ZVzVrYkdWa0xseHVJQ0FnSUhSeVlXTnJVbVZxWldOMGFXOXVLSEpsYW1WamRHbHZiaXdnY21WaGMyOXVLVHRjYmx4dUlDQWdJSEpsZEhWeWJpQnlaV3BsWTNScGIyNDdYRzU5WEc1Y2JpOHFLbHh1SUNvZ1EyOXVjM1J5ZFdOMGN5QmhJR1oxYkdacGJHeGxaQ0J3Y205dGFYTmxJR1p2Y2lCaGJpQnBiVzFsWkdsaGRHVWdjbVZtWlhKbGJtTmxMbHh1SUNvZ1FIQmhjbUZ0SUhaaGJIVmxJR2x0YldWa2FXRjBaU0J5WldabGNtVnVZMlZjYmlBcUwxeHVVUzVtZFd4bWFXeHNJRDBnWm5Wc1ptbHNiRHRjYm1aMWJtTjBhVzl1SUdaMWJHWnBiR3dvZG1Gc2RXVXBJSHRjYmlBZ0lDQnlaWFIxY200Z1VISnZiV2x6WlNoN1hHNGdJQ0FnSUNBZ0lGd2lkMmhsYmx3aU9pQm1kVzVqZEdsdmJpQW9LU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200Z2RtRnNkV1U3WEc0Z0lDQWdJQ0FnSUgwc1hHNGdJQ0FnSUNBZ0lGd2laMlYwWENJNklHWjFibU4wYVc5dUlDaHVZVzFsS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdkbUZzZFdWYmJtRnRaVjA3WEc0Z0lDQWdJQ0FnSUgwc1hHNGdJQ0FnSUNBZ0lGd2ljMlYwWENJNklHWjFibU4wYVc5dUlDaHVZVzFsTENCeWFITXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIWmhiSFZsVzI1aGJXVmRJRDBnY21oek8xeHVJQ0FnSUNBZ0lDQjlMRnh1SUNBZ0lDQWdJQ0JjSW1SbGJHVjBaVndpT2lCbWRXNWpkR2x2YmlBb2JtRnRaU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdaR1ZzWlhSbElIWmhiSFZsVzI1aGJXVmRPMXh1SUNBZ0lDQWdJQ0I5TEZ4dUlDQWdJQ0FnSUNCY0luQnZjM1JjSWpvZ1puVnVZM1JwYjI0Z0tHNWhiV1VzSUdGeVozTXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDOHZJRTFoY21zZ1RXbHNiR1Z5SUhCeWIzQnZjMlZ6SUhSb1lYUWdjRzl6ZENCM2FYUm9JRzV2SUc1aGJXVWdjMmh2ZFd4a0lHRndjR3g1SUdGY2JpQWdJQ0FnSUNBZ0lDQWdJQzh2SUhCeWIyMXBjMlZrSUdaMWJtTjBhVzl1TGx4dUlDQWdJQ0FnSUNBZ0lDQWdhV1lnS0c1aGJXVWdQVDA5SUc1MWJHd2dmSHdnYm1GdFpTQTlQVDBnZG05cFpDQXdLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSFpoYkhWbExtRndjR3g1S0hadmFXUWdNQ3dnWVhKbmN5azdYRzRnSUNBZ0lDQWdJQ0FnSUNCOUlHVnNjMlVnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhKbGRIVnliaUIyWVd4MVpWdHVZVzFsWFM1aGNIQnNlU2gyWVd4MVpTd2dZWEpuY3lrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUgwc1hHNGdJQ0FnSUNBZ0lGd2lZWEJ3YkhsY0lqb2dablZ1WTNScGIyNGdLSFJvYVhOd0xDQmhjbWR6S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdkbUZzZFdVdVlYQndiSGtvZEdocGMzQXNJR0Z5WjNNcE8xeHVJQ0FnSUNBZ0lDQjlMRnh1SUNBZ0lDQWdJQ0JjSW10bGVYTmNJam9nWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJRzlpYW1WamRGOXJaWGx6S0haaGJIVmxLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJSDBzSUhadmFXUWdNQ3dnWm5WdVkzUnBiMjRnYVc1emNHVmpkQ2dwSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUhzZ2MzUmhkR1U2SUZ3aVpuVnNabWxzYkdWa1hDSXNJSFpoYkhWbE9pQjJZV3gxWlNCOU8xeHVJQ0FnSUgwcE8xeHVmVnh1WEc0dktpcGNiaUFxSUVOdmJuWmxjblJ6SUhSb1pXNWhZbXhsY3lCMGJ5QlJJSEJ5YjIxcGMyVnpMbHh1SUNvZ1FIQmhjbUZ0SUhCeWIyMXBjMlVnZEdobGJtRmliR1VnY0hKdmJXbHpaVnh1SUNvZ1FISmxkSFZ5Ym5NZ1lTQlJJSEJ5YjIxcGMyVmNiaUFxTDF4dVpuVnVZM1JwYjI0Z1kyOWxjbU5sS0hCeWIyMXBjMlVwSUh0Y2JpQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUZFdWJtVjRkRlJwWTJzb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0IwY25rZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY0hKdmJXbHpaUzUwYUdWdUtHUmxabVZ5Y21Wa0xuSmxjMjlzZG1Vc0lHUmxabVZ5Y21Wa0xuSmxhbVZqZEN3Z1pHVm1aWEp5WldRdWJtOTBhV1o1S1R0Y2JpQWdJQ0FnSUNBZ2ZTQmpZWFJqYUNBb1pYaGpaWEIwYVc5dUtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCa1pXWmxjbkpsWkM1eVpXcGxZM1FvWlhoalpYQjBhVzl1S1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUgwcE8xeHVJQ0FnSUhKbGRIVnliaUJrWldabGNuSmxaQzV3Y205dGFYTmxPMXh1ZlZ4dVhHNHZLaXBjYmlBcUlFRnVibTkwWVhSbGN5QmhiaUJ2WW1wbFkzUWdjM1ZqYUNCMGFHRjBJR2wwSUhkcGJHd2dibVYyWlhJZ1ltVmNiaUFxSUhSeVlXNXpabVZ5Y21Wa0lHRjNZWGtnWm5KdmJTQjBhR2x6SUhCeWIyTmxjM01nYjNabGNpQmhibmtnY0hKdmJXbHpaVnh1SUNvZ1kyOXRiWFZ1YVdOaGRHbHZiaUJqYUdGdWJtVnNMbHh1SUNvZ1FIQmhjbUZ0SUc5aWFtVmpkRnh1SUNvZ1FISmxkSFZ5Ym5NZ2NISnZiV2x6WlNCaElIZHlZWEJ3YVc1bklHOW1JSFJvWVhRZ2IySnFaV04wSUhSb1lYUmNiaUFxSUdGa1pHbDBhVzl1WVd4c2VTQnlaWE53YjI1a2N5QjBieUIwYUdVZ1hDSnBjMFJsWmx3aUlHMWxjM05oWjJWY2JpQXFJSGRwZEdodmRYUWdZU0J5WldwbFkzUnBiMjR1WEc0Z0tpOWNibEV1YldGemRHVnlJRDBnYldGemRHVnlPMXh1Wm5WdVkzUnBiMjRnYldGemRHVnlLRzlpYW1WamRDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCUWNtOXRhWE5sS0h0Y2JpQWdJQ0FnSUNBZ1hDSnBjMFJsWmx3aU9pQm1kVzVqZEdsdmJpQW9LU0I3ZlZ4dUlDQWdJSDBzSUdaMWJtTjBhVzl1SUdaaGJHeGlZV05yS0c5d0xDQmhjbWR6S1NCN1hHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCa2FYTndZWFJqYUNodlltcGxZM1FzSUc5d0xDQmhjbWR6S1R0Y2JpQWdJQ0I5TENCbWRXNWpkR2x2YmlBb0tTQjdYRzRnSUNBZ0lDQWdJSEpsZEhWeWJpQlJLRzlpYW1WamRDa3VhVzV6Y0dWamRDZ3BPMXh1SUNBZ0lIMHBPMXh1ZlZ4dVhHNHZLaXBjYmlBcUlGTndjbVZoWkhNZ2RHaGxJSFpoYkhWbGN5QnZaaUJoSUhCeWIyMXBjMlZrSUdGeWNtRjVJRzltSUdGeVozVnRaVzUwY3lCcGJuUnZJSFJvWlZ4dUlDb2dablZzWm1sc2JHMWxiblFnWTJGc2JHSmhZMnN1WEc0Z0tpQkFjR0Z5WVcwZ1puVnNabWxzYkdWa0lHTmhiR3hpWVdOcklIUm9ZWFFnY21WalpXbDJaWE1nZG1GeWFXRmthV01nWVhKbmRXMWxiblJ6SUdaeWIyMGdkR2hsWEc0Z0tpQndjbTl0YVhObFpDQmhjbkpoZVZ4dUlDb2dRSEJoY21GdElISmxhbVZqZEdWa0lHTmhiR3hpWVdOcklIUm9ZWFFnY21WalpXbDJaWE1nZEdobElHVjRZMlZ3ZEdsdmJpQnBaaUIwYUdVZ2NISnZiV2x6WlZ4dUlDb2dhWE1nY21WcVpXTjBaV1F1WEc0Z0tpQkFjbVYwZFhKdWN5QmhJSEJ5YjIxcGMyVWdabTl5SUhSb1pTQnlaWFIxY200Z2RtRnNkV1VnYjNJZ2RHaHliM2R1SUdWNFkyVndkR2x2YmlCdlpseHVJQ29nWldsMGFHVnlJR05oYkd4aVlXTnJMbHh1SUNvdlhHNVJMbk53Y21WaFpDQTlJSE53Y21WaFpEdGNibVoxYm1OMGFXOXVJSE53Y21WaFpDaDJZV3gxWlN3Z1puVnNabWxzYkdWa0xDQnlaV3BsWTNSbFpDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCUktIWmhiSFZsS1M1emNISmxZV1FvWm5Wc1ptbHNiR1ZrTENCeVpXcGxZM1JsWkNrN1hHNTlYRzVjYmxCeWIyMXBjMlV1Y0hKdmRHOTBlWEJsTG5Od2NtVmhaQ0E5SUdaMWJtTjBhVzl1SUNobWRXeG1hV3hzWldRc0lISmxhbVZqZEdWa0tTQjdYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTXVZV3hzS0NrdWRHaGxiaWhtZFc1amRHbHZiaUFvWVhKeVlYa3BJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR1oxYkdacGJHeGxaQzVoY0hCc2VTaDJiMmxrSURBc0lHRnljbUY1S1R0Y2JpQWdJQ0I5TENCeVpXcGxZM1JsWkNrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUZSb1pTQmhjM2x1WXlCbWRXNWpkR2x2YmlCcGN5QmhJR1JsWTI5eVlYUnZjaUJtYjNJZ1oyVnVaWEpoZEc5eUlHWjFibU4wYVc5dWN5d2dkSFZ5Ym1sdVoxeHVJQ29nZEdobGJTQnBiblJ2SUdGemVXNWphSEp2Ym05MWN5Qm5aVzVsY21GMGIzSnpMaUFnUVd4MGFHOTFaMmdnWjJWdVpYSmhkRzl5Y3lCaGNtVWdiMjVzZVNCd1lYSjBYRzRnS2lCdlppQjBhR1VnYm1WM1pYTjBJRVZEVFVGVFkzSnBjSFFnTmlCa2NtRm1kSE1zSUhSb2FYTWdZMjlrWlNCa2IyVnpJRzV2ZENCallYVnpaU0J6ZVc1MFlYaGNiaUFxSUdWeWNtOXljeUJwYmlCdmJHUmxjaUJsYm1kcGJtVnpMaUFnVkdocGN5QmpiMlJsSUhOb2IzVnNaQ0JqYjI1MGFXNTFaU0IwYnlCM2IzSnJJR0Z1WkNCM2FXeHNYRzRnS2lCcGJpQm1ZV04wSUdsdGNISnZkbVVnYjNabGNpQjBhVzFsSUdGeklIUm9aU0JzWVc1bmRXRm5aU0JwYlhCeWIzWmxjeTVjYmlBcVhHNGdLaUJGVXpZZ1oyVnVaWEpoZEc5eWN5QmhjbVVnWTNWeWNtVnVkR3g1SUhCaGNuUWdiMllnVmpnZ2RtVnljMmx2YmlBekxqRTVJSGRwZEdnZ2RHaGxYRzRnS2lBdExXaGhjbTF2Ym5rdFoyVnVaWEpoZEc5eWN5QnlkVzUwYVcxbElHWnNZV2NnWlc1aFlteGxaQzRnSUZOd2FXUmxjazF2Ym10bGVTQm9ZWE1nYUdGa0lIUm9aVzFjYmlBcUlHWnZjaUJzYjI1blpYSXNJR0oxZENCMWJtUmxjaUJoYmlCdmJHUmxjaUJRZVhSb2IyNHRhVzV6Y0dseVpXUWdabTl5YlM0Z0lGUm9hWE1nWm5WdVkzUnBiMjVjYmlBcUlIZHZjbXR6SUc5dUlHSnZkR2dnYTJsdVpITWdiMllnWjJWdVpYSmhkRzl5Y3k1Y2JpQXFYRzRnS2lCRVpXTnZjbUYwWlhNZ1lTQm5aVzVsY21GMGIzSWdablZ1WTNScGIyNGdjM1ZqYUNCMGFHRjBPbHh1SUNvZ0lDMGdhWFFnYldGNUlIbHBaV3hrSUhCeWIyMXBjMlZ6WEc0Z0tpQWdMU0JsZUdWamRYUnBiMjRnZDJsc2JDQmpiMjUwYVc1MVpTQjNhR1Z1SUhSb1lYUWdjSEp2YldselpTQnBjeUJtZFd4bWFXeHNaV1JjYmlBcUlDQXRJSFJvWlNCMllXeDFaU0J2WmlCMGFHVWdlV2xsYkdRZ1pYaHdjbVZ6YzJsdmJpQjNhV3hzSUdKbElIUm9aU0JtZFd4bWFXeHNaV1FnZG1Gc2RXVmNiaUFxSUNBdElHbDBJSEpsZEhWeWJuTWdZU0J3Y205dGFYTmxJR1p2Y2lCMGFHVWdjbVYwZFhKdUlIWmhiSFZsSUNoM2FHVnVJSFJvWlNCblpXNWxjbUYwYjNKY2JpQXFJQ0FnSUhOMGIzQnpJR2wwWlhKaGRHbHVaeWxjYmlBcUlDQXRJSFJvWlNCa1pXTnZjbUYwWldRZ1puVnVZM1JwYjI0Z2NtVjBkWEp1Y3lCaElIQnliMjFwYzJVZ1ptOXlJSFJvWlNCeVpYUjFjbTRnZG1Gc2RXVmNiaUFxSUNBZ0lHOW1JSFJvWlNCblpXNWxjbUYwYjNJZ2IzSWdkR2hsSUdacGNuTjBJSEpsYW1WamRHVmtJSEJ5YjIxcGMyVWdZVzF2Ym1jZ2RHaHZjMlZjYmlBcUlDQWdJSGxwWld4a1pXUXVYRzRnS2lBZ0xTQnBaaUJoYmlCbGNuSnZjaUJwY3lCMGFISnZkMjRnYVc0Z2RHaGxJR2RsYm1WeVlYUnZjaXdnYVhRZ2NISnZjR0ZuWVhSbGN5QjBhSEp2ZFdkb1hHNGdLaUFnSUNCbGRtVnllU0JtYjJ4c2IzZHBibWNnZVdsbGJHUWdkVzUwYVd3Z2FYUWdhWE1nWTJGMVoyaDBMQ0J2Y2lCMWJuUnBiQ0JwZENCbGMyTmhjR1Z6WEc0Z0tpQWdJQ0IwYUdVZ1oyVnVaWEpoZEc5eUlHWjFibU4wYVc5dUlHRnNkRzluWlhSb1pYSXNJR0Z1WkNCcGN5QjBjbUZ1YzJ4aGRHVmtJR2x1ZEc4Z1lWeHVJQ29nSUNBZ2NtVnFaV04wYVc5dUlHWnZjaUIwYUdVZ2NISnZiV2x6WlNCeVpYUjFjbTVsWkNCaWVTQjBhR1VnWkdWamIzSmhkR1ZrSUdkbGJtVnlZWFJ2Y2k1Y2JpQXFMMXh1VVM1aGMzbHVZeUE5SUdGemVXNWpPMXh1Wm5WdVkzUnBiMjRnWVhONWJtTW9iV0ZyWlVkbGJtVnlZWFJ2Y2lrZ2UxeHVJQ0FnSUhKbGRIVnliaUJtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lDOHZJSGRvWlc0Z2RtVnlZaUJwY3lCY0luTmxibVJjSWl3Z1lYSm5JR2x6SUdFZ2RtRnNkV1ZjYmlBZ0lDQWdJQ0FnTHk4Z2QyaGxiaUIyWlhKaUlHbHpJRndpZEdoeWIzZGNJaXdnWVhKbklHbHpJR0Z1SUdWNFkyVndkR2x2Ymx4dUlDQWdJQ0FnSUNCbWRXNWpkR2x2YmlCamIyNTBhVzUxWlhJb2RtVnlZaXdnWVhKbktTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCMllYSWdjbVZ6ZFd4ME8xeHVYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QlZiblJwYkNCV09DQXpMakU1SUM4Z1EyaHliMjFwZFcwZ01qa2dhWE1nY21Wc1pXRnpaV1FzSUZOd2FXUmxjazF2Ym10bGVTQnBjeUIwYUdVZ2IyNXNlVnh1SUNBZ0lDQWdJQ0FnSUNBZ0x5OGdaVzVuYVc1bElIUm9ZWFFnYUdGeklHRWdaR1Z3Ykc5NVpXUWdZbUZ6WlNCdlppQmljbTkzYzJWeWN5QjBhR0YwSUhOMWNIQnZjblFnWjJWdVpYSmhkRzl5Y3k1Y2JpQWdJQ0FnSUNBZ0lDQWdJQzh2SUVodmQyVjJaWElzSUZOTkozTWdaMlZ1WlhKaGRHOXljeUIxYzJVZ2RHaGxJRkI1ZEdodmJpMXBibk53YVhKbFpDQnpaVzFoYm5ScFkzTWdiMlpjYmlBZ0lDQWdJQ0FnSUNBZ0lDOHZJRzkxZEdSaGRHVmtJRVZUTmlCa2NtRm1kSE11SUNCWFpTQjNiM1ZzWkNCc2FXdGxJSFJ2SUhOMWNIQnZjblFnUlZNMkxDQmlkWFFnZDJVblpDQmhiSE52WEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUJzYVd0bElIUnZJRzFoYTJVZ2FYUWdjRzl6YzJsaWJHVWdkRzhnZFhObElHZGxibVZ5WVhSdmNuTWdhVzRnWkdWd2JHOTVaV1FnWW5KdmQzTmxjbk1zSUhOdlhHNGdJQ0FnSUNBZ0lDQWdJQ0F2THlCM1pTQmhiSE52SUhOMWNIQnZjblFnVUhsMGFHOXVMWE4wZVd4bElHZGxibVZ5WVhSdmNuTXVJQ0JCZENCemIyMWxJSEJ2YVc1MElIZGxJR05oYmlCeVpXMXZkbVZjYmlBZ0lDQWdJQ0FnSUNBZ0lDOHZJSFJvYVhNZ1lteHZZMnN1WEc1Y2JpQWdJQ0FnSUNBZ0lDQWdJR2xtSUNoMGVYQmxiMllnVTNSdmNFbDBaWEpoZEdsdmJpQTlQVDBnWENKMWJtUmxabWx1WldSY0lpa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQzh2SUVWVE5pQkhaVzVsY21GMGIzSnpYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdkSEo1SUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdjbVZ6ZFd4MElEMGdaMlZ1WlhKaGRHOXlXM1psY21KZEtHRnlaeWs3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnZlNCallYUmphQ0FvWlhoalpYQjBhVzl1S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQnlaV3BsWTNRb1pYaGpaWEIwYVc5dUtUdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdhV1lnS0hKbGMzVnNkQzVrYjI1bEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhKbGRIVnliaUJSS0hKbGMzVnNkQzUyWVd4MVpTazdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdmU0JsYkhObElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSGRvWlc0b2NtVnpkV3gwTG5aaGJIVmxMQ0JqWVd4c1ltRmpheXdnWlhKeVltRmpheWs3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNBZ0lDQWdmU0JsYkhObElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQXZMeUJUY0dsa1pYSk5iMjVyWlhrZ1IyVnVaWEpoZEc5eWMxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDOHZJRVpKV0UxRk9pQlNaVzF2ZG1VZ2RHaHBjeUJqWVhObElIZG9aVzRnVTAwZ1pHOWxjeUJGVXpZZ1oyVnVaWEpoZEc5eWN5NWNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjBjbmtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQnlaWE4xYkhRZ1BTQm5aVzVsY21GMGIzSmJkbVZ5WWwwb1lYSm5LVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0I5SUdOaGRHTm9JQ2hsZUdObGNIUnBiMjRwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdhV1lnS0dselUzUnZjRWwwWlhKaGRHbHZiaWhsZUdObGNIUnBiMjRwS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCeVpYUjFjbTRnVVNobGVHTmxjSFJwYjI0dWRtRnNkV1VwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhKbGFtVmpkQ2hsZUdObGNIUnBiMjRwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQjNhR1Z1S0hKbGMzVnNkQ3dnWTJGc2JHSmhZMnNzSUdWeWNtSmhZMnNwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUhaaGNpQm5aVzVsY21GMGIzSWdQU0J0WVd0bFIyVnVaWEpoZEc5eUxtRndjR3g1S0hSb2FYTXNJR0Z5WjNWdFpXNTBjeWs3WEc0Z0lDQWdJQ0FnSUhaaGNpQmpZV3hzWW1GamF5QTlJR052Ym5ScGJuVmxjaTVpYVc1a0tHTnZiblJwYm5WbGNpd2dYQ0p1WlhoMFhDSXBPMXh1SUNBZ0lDQWdJQ0IyWVhJZ1pYSnlZbUZqYXlBOUlHTnZiblJwYm5WbGNpNWlhVzVrS0dOdmJuUnBiblZsY2l3Z1hDSjBhSEp2ZDF3aUtUdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHTmhiR3hpWVdOcktDazdYRzRnSUNBZ2ZUdGNibjFjYmx4dUx5b3FYRzRnS2lCVWFHVWdjM0JoZDI0Z1puVnVZM1JwYjI0Z2FYTWdZU0J6YldGc2JDQjNjbUZ3Y0dWeUlHRnliM1Z1WkNCaGMzbHVZeUIwYUdGMElHbHRiV1ZrYVdGMFpXeDVYRzRnS2lCallXeHNjeUIwYUdVZ1oyVnVaWEpoZEc5eUlHRnVaQ0JoYkhOdklHVnVaSE1nZEdobElIQnliMjFwYzJVZ1kyaGhhVzRzSUhOdklIUm9ZWFFnWVc1NVhHNGdLaUIxYm1oaGJtUnNaV1FnWlhKeWIzSnpJR0Z5WlNCMGFISnZkMjRnYVc1emRHVmhaQ0J2WmlCbWIzSjNZWEprWldRZ2RHOGdkR2hsSUdWeWNtOXlYRzRnS2lCb1lXNWtiR1Z5TGlCVWFHbHpJR2x6SUhWelpXWjFiQ0JpWldOaGRYTmxJR2wwSjNNZ1pYaDBjbVZ0Wld4NUlHTnZiVzF2YmlCMGJ5QnlkVzVjYmlBcUlHZGxibVZ5WVhSdmNuTWdZWFFnZEdobElIUnZjQzFzWlhabGJDQjBieUIzYjNKcklIZHBkR2dnYkdsaWNtRnlhV1Z6TGx4dUlDb3ZYRzVSTG5Od1lYZHVJRDBnYzNCaGQyNDdYRzVtZFc1amRHbHZiaUJ6Y0dGM2JpaHRZV3RsUjJWdVpYSmhkRzl5S1NCN1hHNGdJQ0FnVVM1a2IyNWxLRkV1WVhONWJtTW9iV0ZyWlVkbGJtVnlZWFJ2Y2lrb0tTazdYRzU5WEc1Y2JpOHZJRVpKV0UxRk9pQlNaVzF2ZG1VZ2RHaHBjeUJwYm5SbGNtWmhZMlVnYjI1alpTQkZVellnWjJWdVpYSmhkRzl5Y3lCaGNtVWdhVzRnVTNCcFpHVnlUVzl1YTJWNUxseHVMeW9xWEc0Z0tpQlVhSEp2ZDNNZ1lTQlNaWFIxY201V1lXeDFaU0JsZUdObGNIUnBiMjRnZEc4Z2MzUnZjQ0JoYmlCaGMzbHVZMmh5YjI1dmRYTWdaMlZ1WlhKaGRHOXlMbHh1SUNwY2JpQXFJRlJvYVhNZ2FXNTBaWEptWVdObElHbHpJR0VnYzNSdmNDMW5ZWEFnYldWaGMzVnlaU0IwYnlCemRYQndiM0owSUdkbGJtVnlZWFJ2Y2lCeVpYUjFjbTVjYmlBcUlIWmhiSFZsY3lCcGJpQnZiR1JsY2lCR2FYSmxabTk0TDFOd2FXUmxjazF2Ym10bGVTNGdJRWx1SUdKeWIzZHpaWEp6SUhSb1lYUWdjM1Z3Y0c5eWRDQkZVelpjYmlBcUlHZGxibVZ5WVhSdmNuTWdiR2xyWlNCRGFISnZiV2wxYlNBeU9Td2dhblZ6ZENCMWMyVWdYQ0p5WlhSMWNtNWNJaUJwYmlCNWIzVnlJR2RsYm1WeVlYUnZjbHh1SUNvZ1puVnVZM1JwYjI1ekxseHVJQ3BjYmlBcUlFQndZWEpoYlNCMllXeDFaU0IwYUdVZ2NtVjBkWEp1SUhaaGJIVmxJR1p2Y2lCMGFHVWdjM1Z5Y205MWJtUnBibWNnWjJWdVpYSmhkRzl5WEc0Z0tpQkFkR2h5YjNkeklGSmxkSFZ5YmxaaGJIVmxJR1Y0WTJWd2RHbHZiaUIzYVhSb0lIUm9aU0IyWVd4MVpTNWNiaUFxSUVCbGVHRnRjR3hsWEc0Z0tpQXZMeUJGVXpZZ2MzUjViR1ZjYmlBcUlGRXVZWE41Ym1Nb1puVnVZM1JwYjI0cUlDZ3BJSHRjYmlBcUlDQWdJQ0FnZG1GeUlHWnZieUE5SUhscFpXeGtJR2RsZEVadmIxQnliMjFwYzJVb0tUdGNiaUFxSUNBZ0lDQWdkbUZ5SUdKaGNpQTlJSGxwWld4a0lHZGxkRUpoY2xCeWIyMXBjMlVvS1R0Y2JpQXFJQ0FnSUNBZ2NtVjBkWEp1SUdadmJ5QXJJR0poY2p0Y2JpQXFJSDBwWEc0Z0tpQXZMeUJQYkdSbGNpQlRjR2xrWlhKTmIyNXJaWGtnYzNSNWJHVmNiaUFxSUZFdVlYTjVibU1vWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ29nSUNBZ0lDQjJZWElnWm05dklEMGdlV2xsYkdRZ1oyVjBSbTl2VUhKdmJXbHpaU2dwTzF4dUlDb2dJQ0FnSUNCMllYSWdZbUZ5SUQwZ2VXbGxiR1FnWjJWMFFtRnlVSEp2YldselpTZ3BPMXh1SUNvZ0lDQWdJQ0JSTG5KbGRIVnliaWhtYjI4Z0t5QmlZWElwTzF4dUlDb2dmU2xjYmlBcUwxeHVVVnRjSW5KbGRIVnlibHdpWFNBOUlGOXlaWFIxY200N1hHNW1kVzVqZEdsdmJpQmZjbVYwZFhKdUtIWmhiSFZsS1NCN1hHNGdJQ0FnZEdoeWIzY2dibVYzSUZGU1pYUjFjbTVXWVd4MVpTaDJZV3gxWlNrN1hHNTlYRzVjYmk4cUtseHVJQ29nVkdobElIQnliMjFwYzJWa0lHWjFibU4wYVc5dUlHUmxZMjl5WVhSdmNpQmxibk4xY21WeklIUm9ZWFFnWVc1NUlIQnliMjFwYzJVZ1lYSm5kVzFsYm5SelhHNGdLaUJoY21VZ2MyVjBkR3hsWkNCaGJtUWdjR0Z6YzJWa0lHRnpJSFpoYkhWbGN5QW9ZSFJvYVhOZ0lHbHpJR0ZzYzI4Z2MyVjBkR3hsWkNCaGJtUWdjR0Z6YzJWa1hHNGdLaUJoY3lCaElIWmhiSFZsS1M0Z0lFbDBJSGRwYkd3Z1lXeHpieUJsYm5OMWNtVWdkR2hoZENCMGFHVWdjbVZ6ZFd4MElHOW1JR0VnWm5WdVkzUnBiMjRnYVhOY2JpQXFJR0ZzZDJGNWN5QmhJSEJ5YjIxcGMyVXVYRzRnS2x4dUlDb2dRR1Y0WVcxd2JHVmNiaUFxSUhaaGNpQmhaR1FnUFNCUkxuQnliMjFwYzJWa0tHWjFibU4wYVc5dUlDaGhMQ0JpS1NCN1hHNGdLaUFnSUNBZ2NtVjBkWEp1SUdFZ0t5QmlPMXh1SUNvZ2ZTazdYRzRnS2lCaFpHUW9VU2hoS1N3Z1VTaENLU2s3WEc0Z0tseHVJQ29nUUhCaGNtRnRJSHRtZFc1amRHbHZibjBnWTJGc2JHSmhZMnNnVkdobElHWjFibU4wYVc5dUlIUnZJR1JsWTI5eVlYUmxYRzRnS2lCQWNtVjBkWEp1Y3lCN1puVnVZM1JwYjI1OUlHRWdablZ1WTNScGIyNGdkR2hoZENCb1lYTWdZbVZsYmlCa1pXTnZjbUYwWldRdVhHNGdLaTljYmxFdWNISnZiV2x6WldRZ1BTQndjbTl0YVhObFpEdGNibVoxYm1OMGFXOXVJSEJ5YjIxcGMyVmtLR05oYkd4aVlXTnJLU0I3WEc0Z0lDQWdjbVYwZFhKdUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJSE53Y21WaFpDaGJkR2hwY3l3Z1lXeHNLR0Z5WjNWdFpXNTBjeWxkTENCbWRXNWpkR2x2YmlBb2MyVnNaaXdnWVhKbmN5a2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUdOaGJHeGlZV05yTG1Gd2NHeDVLSE5sYkdZc0lHRnlaM01wTzF4dUlDQWdJQ0FnSUNCOUtUdGNiaUFnSUNCOU8xeHVmVnh1WEc0dktpcGNiaUFxSUhObGJtUnpJR0VnYldWemMyRm5aU0IwYnlCaElIWmhiSFZsSUdsdUlHRWdablYwZFhKbElIUjFjbTVjYmlBcUlFQndZWEpoYlNCdlltcGxZM1FxSUhSb1pTQnlaV05wY0dsbGJuUmNiaUFxSUVCd1lYSmhiU0J2Y0NCMGFHVWdibUZ0WlNCdlppQjBhR1VnYldWemMyRm5aU0J2Y0dWeVlYUnBiMjRzSUdVdVp5NHNJRndpZDJobGJsd2lMRnh1SUNvZ1FIQmhjbUZ0SUdGeVozTWdablZ5ZEdobGNpQmhjbWQxYldWdWRITWdkRzhnWW1VZ1ptOXlkMkZ5WkdWa0lIUnZJSFJvWlNCdmNHVnlZWFJwYjI1Y2JpQXFJRUJ5WlhSMWNtNXpJSEpsYzNWc2RDQjdVSEp2YldselpYMGdZU0J3Y205dGFYTmxJR1p2Y2lCMGFHVWdjbVZ6ZFd4MElHOW1JSFJvWlNCdmNHVnlZWFJwYjI1Y2JpQXFMMXh1VVM1a2FYTndZWFJqYUNBOUlHUnBjM0JoZEdOb08xeHVablZ1WTNScGIyNGdaR2x6Y0dGMFkyZ29iMkpxWldOMExDQnZjQ3dnWVhKbmN5a2dlMXh1SUNBZ0lISmxkSFZ5YmlCUktHOWlhbVZqZENrdVpHbHpjR0YwWTJnb2IzQXNJR0Z5WjNNcE8xeHVmVnh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1a2FYTndZWFJqYUNBOUlHWjFibU4wYVc5dUlDaHZjQ3dnWVhKbmN5a2dlMXh1SUNBZ0lIWmhjaUJ6Wld4bUlEMGdkR2hwY3p0Y2JpQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUZFdWJtVjRkRlJwWTJzb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0J6Wld4bUxuQnliMjFwYzJWRWFYTndZWFJqYUNoa1pXWmxjbkpsWkM1eVpYTnZiSFpsTENCdmNDd2dZWEpuY3lrN1hHNGdJQ0FnZlNrN1hHNGdJQ0FnY21WMGRYSnVJR1JsWm1WeWNtVmtMbkJ5YjIxcGMyVTdYRzU5TzF4dVhHNHZLaXBjYmlBcUlFZGxkSE1nZEdobElIWmhiSFZsSUc5bUlHRWdjSEp2Y0dWeWRIa2dhVzRnWVNCbWRYUjFjbVVnZEhWeWJpNWNiaUFxSUVCd1lYSmhiU0J2WW1wbFkzUWdJQ0FnY0hKdmJXbHpaU0J2Y2lCcGJXMWxaR2xoZEdVZ2NtVm1aWEpsYm1ObElHWnZjaUIwWVhKblpYUWdiMkpxWldOMFhHNGdLaUJBY0dGeVlXMGdibUZ0WlNBZ0lDQWdJRzVoYldVZ2IyWWdjSEp2Y0dWeWRIa2dkRzhnWjJWMFhHNGdLaUJBY21WMGRYSnVJSEJ5YjIxcGMyVWdabTl5SUhSb1pTQndjbTl3WlhKMGVTQjJZV3gxWlZ4dUlDb3ZYRzVSTG1kbGRDQTlJR1oxYm1OMGFXOXVJQ2h2WW1wbFkzUXNJR3RsZVNrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0c5aWFtVmpkQ2t1WkdsemNHRjBZMmdvWENKblpYUmNJaXdnVzJ0bGVWMHBPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVaMlYwSUQwZ1puVnVZM1JwYjI0Z0tHdGxlU2tnZTF4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TG1ScGMzQmhkR05vS0Z3aVoyVjBYQ0lzSUZ0clpYbGRLVHRjYm4wN1hHNWNiaThxS2x4dUlDb2dVMlYwY3lCMGFHVWdkbUZzZFdVZ2IyWWdZU0J3Y205d1pYSjBlU0JwYmlCaElHWjFkSFZ5WlNCMGRYSnVMbHh1SUNvZ1FIQmhjbUZ0SUc5aWFtVmpkQ0FnSUNCd2NtOXRhWE5sSUc5eUlHbHRiV1ZrYVdGMFpTQnlaV1psY21WdVkyVWdabTl5SUc5aWFtVmpkQ0J2WW1wbFkzUmNiaUFxSUVCd1lYSmhiU0J1WVcxbElDQWdJQ0FnYm1GdFpTQnZaaUJ3Y205d1pYSjBlU0IwYnlCelpYUmNiaUFxSUVCd1lYSmhiU0IyWVd4MVpTQWdJQ0FnYm1WM0lIWmhiSFZsSUc5bUlIQnliM0JsY25SNVhHNGdLaUJBY21WMGRYSnVJSEJ5YjIxcGMyVWdabTl5SUhSb1pTQnlaWFIxY200Z2RtRnNkV1ZjYmlBcUwxeHVVUzV6WlhRZ1BTQm1kVzVqZEdsdmJpQW9iMkpxWldOMExDQnJaWGtzSUhaaGJIVmxLU0I3WEc0Z0lDQWdjbVYwZFhKdUlGRW9iMkpxWldOMEtTNWthWE53WVhSamFDaGNJbk5sZEZ3aUxDQmJhMlY1TENCMllXeDFaVjBwTzF4dWZUdGNibHh1VUhKdmJXbHpaUzV3Y205MGIzUjVjR1V1YzJWMElEMGdablZ1WTNScGIyNGdLR3RsZVN3Z2RtRnNkV1VwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdkR2hwY3k1a2FYTndZWFJqYUNoY0luTmxkRndpTENCYmEyVjVMQ0IyWVd4MVpWMHBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQkVaV3hsZEdWeklHRWdjSEp2Y0dWeWRIa2dhVzRnWVNCbWRYUjFjbVVnZEhWeWJpNWNiaUFxSUVCd1lYSmhiU0J2WW1wbFkzUWdJQ0FnY0hKdmJXbHpaU0J2Y2lCcGJXMWxaR2xoZEdVZ2NtVm1aWEpsYm1ObElHWnZjaUIwWVhKblpYUWdiMkpxWldOMFhHNGdLaUJBY0dGeVlXMGdibUZ0WlNBZ0lDQWdJRzVoYldVZ2IyWWdjSEp2Y0dWeWRIa2dkRzhnWkdWc1pYUmxYRzRnS2lCQWNtVjBkWEp1SUhCeWIyMXBjMlVnWm05eUlIUm9aU0J5WlhSMWNtNGdkbUZzZFdWY2JpQXFMMXh1VVM1a1pXd2dQU0F2THlCWVdGZ2diR1ZuWVdONVhHNVJXMXdpWkdWc1pYUmxYQ0pkSUQwZ1puVnVZM1JwYjI0Z0tHOWlhbVZqZEN3Z2EyVjVLU0I3WEc0Z0lDQWdjbVYwZFhKdUlGRW9iMkpxWldOMEtTNWthWE53WVhSamFDaGNJbVJsYkdWMFpWd2lMQ0JiYTJWNVhTazdYRzU5TzF4dVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNWtaV3dnUFNBdkx5QllXRmdnYkdWbllXTjVYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaVnRjSW1SbGJHVjBaVndpWFNBOUlHWjFibU4wYVc5dUlDaHJaWGtwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdkR2hwY3k1a2FYTndZWFJqYUNoY0ltUmxiR1YwWlZ3aUxDQmJhMlY1WFNrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUVsdWRtOXJaWE1nWVNCdFpYUm9iMlFnYVc0Z1lTQm1kWFIxY21VZ2RIVnliaTVjYmlBcUlFQndZWEpoYlNCdlltcGxZM1FnSUNBZ2NISnZiV2x6WlNCdmNpQnBiVzFsWkdsaGRHVWdjbVZtWlhKbGJtTmxJR1p2Y2lCMFlYSm5aWFFnYjJKcVpXTjBYRzRnS2lCQWNHRnlZVzBnYm1GdFpTQWdJQ0FnSUc1aGJXVWdiMllnYldWMGFHOWtJSFJ2SUdsdWRtOXJaVnh1SUNvZ1FIQmhjbUZ0SUhaaGJIVmxJQ0FnSUNCaElIWmhiSFZsSUhSdklIQnZjM1FzSUhSNWNHbGpZV3hzZVNCaGJpQmhjbkpoZVNCdlpseHVJQ29nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JwYm5adlkyRjBhVzl1SUdGeVozVnRaVzUwY3lCbWIzSWdjSEp2YldselpYTWdkR2hoZEZ4dUlDb2dJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQmhjbVVnZFd4MGFXMWhkR1ZzZVNCaVlXTnJaV1FnZDJsMGFDQmdjbVZ6YjJ4MlpXQWdkbUZzZFdWekxGeHVJQ29nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JoY3lCdmNIQnZjMlZrSUhSdklIUm9iM05sSUdKaFkydGxaQ0IzYVhSb0lGVlNUSE5jYmlBcUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2QyaGxjbVZwYmlCMGFHVWdjRzl6ZEdWa0lIWmhiSFZsSUdOaGJpQmlaU0JoYm5sY2JpQXFJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdTbE5QVGlCelpYSnBZV3hwZW1GaWJHVWdiMkpxWldOMExseHVJQ29nUUhKbGRIVnliaUJ3Y205dGFYTmxJR1p2Y2lCMGFHVWdjbVYwZFhKdUlIWmhiSFZsWEc0Z0tpOWNiaTh2SUdKdmRXNWtJR3h2WTJGc2JIa2dZbVZqWVhWelpTQnBkQ0JwY3lCMWMyVmtJR0o1SUc5MGFHVnlJRzFsZEdodlpITmNibEV1YldGd2NHeDVJRDBnTHk4Z1dGaFlJRUZ6SUhCeWIzQnZjMlZrSUdKNUlGd2lVbVZrYzJGdVpISnZYQ0pjYmxFdWNHOXpkQ0E5SUdaMWJtTjBhVzl1SUNodlltcGxZM1FzSUc1aGJXVXNJR0Z5WjNNcElIdGNiaUFnSUNCeVpYUjFjbTRnVVNodlltcGxZM1FwTG1ScGMzQmhkR05vS0Z3aWNHOXpkRndpTENCYmJtRnRaU3dnWVhKbmMxMHBPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXViV0Z3Y0d4NUlEMGdMeThnV0ZoWUlFRnpJSEJ5YjNCdmMyVmtJR0o1SUZ3aVVtVmtjMkZ1WkhKdlhDSmNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbkJ2YzNRZ1BTQm1kVzVqZEdsdmJpQW9ibUZ0WlN3Z1lYSm5jeWtnZTF4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TG1ScGMzQmhkR05vS0Z3aWNHOXpkRndpTENCYmJtRnRaU3dnWVhKbmMxMHBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQkpiblp2YTJWeklHRWdiV1YwYUc5a0lHbHVJR0VnWm5WMGRYSmxJSFIxY200dVhHNGdLaUJBY0dGeVlXMGdiMkpxWldOMElDQWdJSEJ5YjIxcGMyVWdiM0lnYVcxdFpXUnBZWFJsSUhKbFptVnlaVzVqWlNCbWIzSWdkR0Z5WjJWMElHOWlhbVZqZEZ4dUlDb2dRSEJoY21GdElHNWhiV1VnSUNBZ0lDQnVZVzFsSUc5bUlHMWxkR2h2WkNCMGJ5QnBiblp2YTJWY2JpQXFJRUJ3WVhKaGJTQXVMaTVoY21keklDQWdZWEp5WVhrZ2IyWWdhVzUyYjJOaGRHbHZiaUJoY21kMWJXVnVkSE5jYmlBcUlFQnlaWFIxY200Z2NISnZiV2x6WlNCbWIzSWdkR2hsSUhKbGRIVnliaUIyWVd4MVpWeHVJQ292WEc1UkxuTmxibVFnUFNBdkx5QllXRmdnVFdGeWF5Qk5hV3hzWlhJbmN5QndjbTl3YjNObFpDQndZWEpzWVc1alpWeHVVUzV0WTJGc2JDQTlJQzh2SUZoWVdDQkJjeUJ3Y205d2IzTmxaQ0JpZVNCY0lsSmxaSE5oYm1SeWIxd2lYRzVSTG1sdWRtOXJaU0E5SUdaMWJtTjBhVzl1SUNodlltcGxZM1FzSUc1aGJXVWdMeW91TGk1aGNtZHpLaThwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdVU2h2WW1wbFkzUXBMbVJwYzNCaGRHTm9LRndpY0c5emRGd2lMQ0JiYm1GdFpTd2dZWEp5WVhsZmMyeHBZMlVvWVhKbmRXMWxiblJ6TENBeUtWMHBPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVjMlZ1WkNBOUlDOHZJRmhZV0NCTllYSnJJRTFwYkd4bGNpZHpJSEJ5YjNCdmMyVmtJSEJoY214aGJtTmxYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzV0WTJGc2JDQTlJQzh2SUZoWVdDQkJjeUJ3Y205d2IzTmxaQ0JpZVNCY0lsSmxaSE5oYm1SeWIxd2lYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzVwYm5admEyVWdQU0JtZFc1amRHbHZiaUFvYm1GdFpTQXZLaTR1TG1GeVozTXFMeWtnZTF4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TG1ScGMzQmhkR05vS0Z3aWNHOXpkRndpTENCYmJtRnRaU3dnWVhKeVlYbGZjMnhwWTJVb1lYSm5kVzFsYm5SekxDQXhLVjBwTzF4dWZUdGNibHh1THlvcVhHNGdLaUJCY0hCc2FXVnpJSFJvWlNCd2NtOXRhWE5sWkNCbWRXNWpkR2x2YmlCcGJpQmhJR1oxZEhWeVpTQjBkWEp1TGx4dUlDb2dRSEJoY21GdElHOWlhbVZqZENBZ0lDQndjbTl0YVhObElHOXlJR2x0YldWa2FXRjBaU0J5WldabGNtVnVZMlVnWm05eUlIUmhjbWRsZENCbWRXNWpkR2x2Ymx4dUlDb2dRSEJoY21GdElHRnlaM01nSUNBZ0lDQmhjbkpoZVNCdlppQmhjSEJzYVdOaGRHbHZiaUJoY21kMWJXVnVkSE5jYmlBcUwxeHVVUzVtWVhCd2JIa2dQU0JtZFc1amRHbHZiaUFvYjJKcVpXTjBMQ0JoY21kektTQjdYRzRnSUNBZ2NtVjBkWEp1SUZFb2IySnFaV04wS1M1a2FYTndZWFJqYUNoY0ltRndjR3g1WENJc0lGdDJiMmxrSURBc0lHRnlaM05kS1R0Y2JuMDdYRzVjYmxCeWIyMXBjMlV1Y0hKdmRHOTBlWEJsTG1aaGNIQnNlU0E5SUdaMWJtTjBhVzl1SUNoaGNtZHpLU0I3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11WkdsemNHRjBZMmdvWENKaGNIQnNlVndpTENCYmRtOXBaQ0F3TENCaGNtZHpYU2s3WEc1OU8xeHVYRzR2S2lwY2JpQXFJRU5oYkd4eklIUm9aU0J3Y205dGFYTmxaQ0JtZFc1amRHbHZiaUJwYmlCaElHWjFkSFZ5WlNCMGRYSnVMbHh1SUNvZ1FIQmhjbUZ0SUc5aWFtVmpkQ0FnSUNCd2NtOXRhWE5sSUc5eUlHbHRiV1ZrYVdGMFpTQnlaV1psY21WdVkyVWdabTl5SUhSaGNtZGxkQ0JtZFc1amRHbHZibHh1SUNvZ1FIQmhjbUZ0SUM0dUxtRnlaM01nSUNCaGNuSmhlU0J2WmlCaGNIQnNhV05oZEdsdmJpQmhjbWQxYldWdWRITmNiaUFxTDF4dVVWdGNJblJ5ZVZ3aVhTQTlYRzVSTG1aallXeHNJRDBnWm5WdVkzUnBiMjRnS0c5aWFtVmpkQ0F2S2lBdUxpNWhjbWR6S2k4cElIdGNiaUFnSUNCeVpYUjFjbTRnVVNodlltcGxZM1FwTG1ScGMzQmhkR05vS0Z3aVlYQndiSGxjSWl3Z1czWnZhV1FnTUN3Z1lYSnlZWGxmYzJ4cFkyVW9ZWEpuZFcxbGJuUnpMQ0F4S1YwcE8xeHVmVHRjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdVptTmhiR3dnUFNCbWRXNWpkR2x2YmlBb0x5b3VMaTVoY21kektpOHBJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTVrYVhOd1lYUmphQ2hjSW1Gd2NHeDVYQ0lzSUZ0MmIybGtJREFzSUdGeWNtRjVYM05zYVdObEtHRnlaM1Z0Wlc1MGN5bGRLVHRjYm4wN1hHNWNiaThxS2x4dUlDb2dRbWx1WkhNZ2RHaGxJSEJ5YjIxcGMyVmtJR1oxYm1OMGFXOXVMQ0IwY21GdWMyWnZjbTFwYm1jZ2NtVjBkWEp1SUhaaGJIVmxjeUJwYm5SdklHRWdablZzWm1sc2JHVmtYRzRnS2lCd2NtOXRhWE5sSUdGdVpDQjBhSEp2ZDI0Z1pYSnliM0p6SUdsdWRHOGdZU0J5WldwbFkzUmxaQ0J2Ym1VdVhHNGdLaUJBY0dGeVlXMGdiMkpxWldOMElDQWdJSEJ5YjIxcGMyVWdiM0lnYVcxdFpXUnBZWFJsSUhKbFptVnlaVzVqWlNCbWIzSWdkR0Z5WjJWMElHWjFibU4wYVc5dVhHNGdLaUJBY0dGeVlXMGdMaTR1WVhKbmN5QWdJR0Z5Y21GNUlHOW1JR0Z3Y0d4cFkyRjBhVzl1SUdGeVozVnRaVzUwYzF4dUlDb3ZYRzVSTG1aaWFXNWtJRDBnWm5WdVkzUnBiMjRnS0c5aWFtVmpkQ0F2S2k0dUxtRnlaM01xTHlrZ2UxeHVJQ0FnSUhaaGNpQndjbTl0YVhObElEMGdVU2h2WW1wbFkzUXBPMXh1SUNBZ0lIWmhjaUJoY21keklEMGdZWEp5WVhsZmMyeHBZMlVvWVhKbmRXMWxiblJ6TENBeEtUdGNiaUFnSUNCeVpYUjFjbTRnWm5WdVkzUnBiMjRnWm1KdmRXNWtLQ2tnZTF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnY0hKdmJXbHpaUzVrYVhOd1lYUmphQ2hjSW1Gd2NHeDVYQ0lzSUZ0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFJvYVhNc1hHNGdJQ0FnSUNBZ0lDQWdJQ0JoY21kekxtTnZibU5oZENoaGNuSmhlVjl6YkdsalpTaGhjbWQxYldWdWRITXBLVnh1SUNBZ0lDQWdJQ0JkS1R0Y2JpQWdJQ0I5TzF4dWZUdGNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbVppYVc1a0lEMGdablZ1WTNScGIyNGdLQzhxTGk0dVlYSm5jeW92S1NCN1hHNGdJQ0FnZG1GeUlIQnliMjFwYzJVZ1BTQjBhR2x6TzF4dUlDQWdJSFpoY2lCaGNtZHpJRDBnWVhKeVlYbGZjMnhwWTJVb1lYSm5kVzFsYm5SektUdGNiaUFnSUNCeVpYUjFjbTRnWm5WdVkzUnBiMjRnWm1KdmRXNWtLQ2tnZTF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnY0hKdmJXbHpaUzVrYVhOd1lYUmphQ2hjSW1Gd2NHeDVYQ0lzSUZ0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFJvYVhNc1hHNGdJQ0FnSUNBZ0lDQWdJQ0JoY21kekxtTnZibU5oZENoaGNuSmhlVjl6YkdsalpTaGhjbWQxYldWdWRITXBLVnh1SUNBZ0lDQWdJQ0JkS1R0Y2JpQWdJQ0I5TzF4dWZUdGNibHh1THlvcVhHNGdLaUJTWlhGMVpYTjBjeUIwYUdVZ2JtRnRaWE1nYjJZZ2RHaGxJRzkzYm1Wa0lIQnliM0JsY25ScFpYTWdiMllnWVNCd2NtOXRhWE5sWkZ4dUlDb2diMkpxWldOMElHbHVJR0VnWm5WMGRYSmxJSFIxY200dVhHNGdLaUJBY0dGeVlXMGdiMkpxWldOMElDQWdJSEJ5YjIxcGMyVWdiM0lnYVcxdFpXUnBZWFJsSUhKbFptVnlaVzVqWlNCbWIzSWdkR0Z5WjJWMElHOWlhbVZqZEZ4dUlDb2dRSEpsZEhWeWJpQndjbTl0YVhObElHWnZjaUIwYUdVZ2EyVjVjeUJ2WmlCMGFHVWdaWFpsYm5SMVlXeHNlU0J6WlhSMGJHVmtJRzlpYW1WamRGeHVJQ292WEc1UkxtdGxlWE1nUFNCbWRXNWpkR2x2YmlBb2IySnFaV04wS1NCN1hHNGdJQ0FnY21WMGRYSnVJRkVvYjJKcVpXTjBLUzVrYVhOd1lYUmphQ2hjSW10bGVYTmNJaXdnVzEwcE8xeHVmVHRjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWEyVjVjeUE5SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNCeVpYUjFjbTRnZEdocGN5NWthWE53WVhSamFDaGNJbXRsZVhOY0lpd2dXMTBwTzF4dWZUdGNibHh1THlvcVhHNGdLaUJVZFhKdWN5QmhiaUJoY25KaGVTQnZaaUJ3Y205dGFYTmxjeUJwYm5SdklHRWdjSEp2YldselpTQm1iM0lnWVc0Z1lYSnlZWGt1SUNCSlppQmhibmtnYjJaY2JpQXFJSFJvWlNCd2NtOXRhWE5sY3lCblpYUnpJSEpsYW1WamRHVmtMQ0IwYUdVZ2QyaHZiR1VnWVhKeVlYa2dhWE1nY21WcVpXTjBaV1FnYVcxdFpXUnBZWFJsYkhrdVhHNGdLaUJBY0dGeVlXMGdlMEZ5Y21GNUtuMGdZVzRnWVhKeVlYa2dLRzl5SUhCeWIyMXBjMlVnWm05eUlHRnVJR0Z5Y21GNUtTQnZaaUIyWVd4MVpYTWdLRzl5WEc0Z0tpQndjbTl0YVhObGN5Qm1iM0lnZG1Gc2RXVnpLVnh1SUNvZ1FISmxkSFZ5Ym5NZ1lTQndjbTl0YVhObElHWnZjaUJoYmlCaGNuSmhlU0J2WmlCMGFHVWdZMjl5Y21WemNHOXVaR2x1WnlCMllXeDFaWE5jYmlBcUwxeHVMeThnUW5rZ1RXRnlheUJOYVd4c1pYSmNiaTh2SUdoMGRIQTZMeTkzYVd0cExtVmpiV0Z6WTNKcGNIUXViM0puTDJSdmEzVXVjR2h3UDJsa1BYTjBjbUYzYldGdU9tTnZibU4xY25KbGJtTjVKbkpsZGoweE16QTROemMyTlRJeEkyRnNiR1oxYkdacGJHeGxaRnh1VVM1aGJHd2dQU0JoYkd3N1hHNW1kVzVqZEdsdmJpQmhiR3dvY0hKdmJXbHpaWE1wSUh0Y2JpQWdJQ0J5WlhSMWNtNGdkMmhsYmlod2NtOXRhWE5sY3l3Z1puVnVZM1JwYjI0Z0tIQnliMjFwYzJWektTQjdYRzRnSUNBZ0lDQWdJSFpoY2lCd1pXNWthVzVuUTI5MWJuUWdQU0F3TzF4dUlDQWdJQ0FnSUNCMllYSWdaR1ZtWlhKeVpXUWdQU0JrWldabGNpZ3BPMXh1SUNBZ0lDQWdJQ0JoY25KaGVWOXlaV1IxWTJVb2NISnZiV2x6WlhNc0lHWjFibU4wYVc5dUlDaDFibVJsWm1sdVpXUXNJSEJ5YjIxcGMyVXNJR2x1WkdWNEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCMllYSWdjMjVoY0hOb2IzUTdYRzRnSUNBZ0lDQWdJQ0FnSUNCcFppQW9YRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdhWE5RY205dGFYTmxLSEJ5YjIxcGMyVXBJQ1ltWEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnS0hOdVlYQnphRzkwSUQwZ2NISnZiV2x6WlM1cGJuTndaV04wS0NrcExuTjBZWFJsSUQwOVBTQmNJbVoxYkdacGJHeGxaRndpWEc0Z0lDQWdJQ0FnSUNBZ0lDQXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0J3Y205dGFYTmxjMXRwYm1SbGVGMGdQU0J6Ym1Gd2MyaHZkQzUyWVd4MVpUdGNiaUFnSUNBZ0lDQWdJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnS3l0d1pXNWthVzVuUTI5MWJuUTdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdkMmhsYmloY2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdjSEp2YldselpTeGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnWm5WdVkzUnBiMjRnS0haaGJIVmxLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0J3Y205dGFYTmxjMXRwYm1SbGVGMGdQU0IyWVd4MVpUdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHbG1JQ2d0TFhCbGJtUnBibWREYjNWdWRDQTlQVDBnTUNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJR1JsWm1WeWNtVmtMbkpsYzI5c2RtVW9jSEp2YldselpYTXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCOUxGeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JrWldabGNuSmxaQzV5WldwbFkzUXNYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUdaMWJtTjBhVzl1SUNod2NtOW5jbVZ6Y3lrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ1pHVm1aWEp5WldRdWJtOTBhV1o1S0hzZ2FXNWtaWGc2SUdsdVpHVjRMQ0IyWVd4MVpUb2djSEp2WjNKbGMzTWdmU2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQjlMQ0IyYjJsa0lEQXBPMXh1SUNBZ0lDQWdJQ0JwWmlBb2NHVnVaR2x1WjBOdmRXNTBJRDA5UFNBd0tTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCa1pXWmxjbkpsWkM1eVpYTnZiSFpsS0hCeWIyMXBjMlZ6S1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQnlaWFIxY200Z1pHVm1aWEp5WldRdWNISnZiV2x6WlR0Y2JpQWdJQ0I5S1R0Y2JuMWNibHh1VUhKdmJXbHpaUzV3Y205MGIzUjVjR1V1WVd4c0lEMGdablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQmhiR3dvZEdocGN5azdYRzU5TzF4dVhHNHZLaXBjYmlBcUlGSmxkSFZ5Ym5NZ2RHaGxJR1pwY25OMElISmxjMjlzZG1Wa0lIQnliMjFwYzJVZ2IyWWdZVzRnWVhKeVlYa3VJRkJ5YVc5eUlISmxhbVZqZEdWa0lIQnliMjFwYzJWeklHRnlaVnh1SUNvZ2FXZHViM0psWkM0Z0lGSmxhbVZqZEhNZ2IyNXNlU0JwWmlCaGJHd2djSEp2YldselpYTWdZWEpsSUhKbGFtVmpkR1ZrTGx4dUlDb2dRSEJoY21GdElIdEJjbkpoZVNwOUlHRnVJR0Z5Y21GNUlHTnZiblJoYVc1cGJtY2dkbUZzZFdWeklHOXlJSEJ5YjIxcGMyVnpJR1p2Y2lCMllXeDFaWE5jYmlBcUlFQnlaWFIxY201eklHRWdjSEp2YldselpTQm1kV3htYVd4c1pXUWdkMmwwYUNCMGFHVWdkbUZzZFdVZ2IyWWdkR2hsSUdacGNuTjBJSEpsYzI5c2RtVmtJSEJ5YjIxcGMyVXNYRzRnS2lCdmNpQmhJSEpsYW1WamRHVmtJSEJ5YjIxcGMyVWdhV1lnWVd4c0lIQnliMjFwYzJWeklHRnlaU0J5WldwbFkzUmxaQzVjYmlBcUwxeHVVUzVoYm5rZ1BTQmhibms3WEc1Y2JtWjFibU4wYVc5dUlHRnVlU2h3Y205dGFYTmxjeWtnZTF4dUlDQWdJR2xtSUNod2NtOXRhWE5sY3k1c1pXNW5kR2dnUFQwOUlEQXBJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJRkV1Y21WemIyeDJaU2dwTzF4dUlDQWdJSDFjYmx4dUlDQWdJSFpoY2lCa1pXWmxjbkpsWkNBOUlGRXVaR1ZtWlhJb0tUdGNiaUFnSUNCMllYSWdjR1Z1WkdsdVowTnZkVzUwSUQwZ01EdGNiaUFnSUNCaGNuSmhlVjl5WldSMVkyVW9jSEp2YldselpYTXNJR1oxYm1OMGFXOXVJQ2h3Y21WMkxDQmpkWEp5Wlc1MExDQnBibVJsZUNrZ2UxeHVJQ0FnSUNBZ0lDQjJZWElnY0hKdmJXbHpaU0E5SUhCeWIyMXBjMlZ6VzJsdVpHVjRYVHRjYmx4dUlDQWdJQ0FnSUNCd1pXNWthVzVuUTI5MWJuUXJLenRjYmx4dUlDQWdJQ0FnSUNCM2FHVnVLSEJ5YjIxcGMyVXNJRzl1Um5Wc1ptbHNiR1ZrTENCdmJsSmxhbVZqZEdWa0xDQnZibEJ5YjJkeVpYTnpLVHRjYmlBZ0lDQWdJQ0FnWm5WdVkzUnBiMjRnYjI1R2RXeG1hV3hzWldRb2NtVnpkV3gwS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JrWldabGNuSmxaQzV5WlhOdmJIWmxLSEpsYzNWc2RDazdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnWm5WdVkzUnBiMjRnYjI1U1pXcGxZM1JsWkNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhCbGJtUnBibWREYjNWdWRDMHRPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLSEJsYm1ScGJtZERiM1Z1ZENBOVBUMGdNQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUdSbFptVnljbVZrTG5KbGFtVmpkQ2h1WlhjZ1JYSnliM0lvWEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lGd2lRMkZ1SjNRZ1oyVjBJR1oxYkdacGJHeHRaVzUwSUhaaGJIVmxJR1p5YjIwZ1lXNTVJSEJ5YjIxcGMyVXNJR0ZzYkNCY0lpQXJYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUZ3aWNISnZiV2x6WlhNZ2QyVnlaU0J5WldwbFkzUmxaQzVjSWx4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNrcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lHWjFibU4wYVc5dUlHOXVVSEp2WjNKbGMzTW9jSEp2WjNKbGMzTXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHUmxabVZ5Y21Wa0xtNXZkR2xtZVNoN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2FXNWtaWGc2SUdsdVpHVjRMRnh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSFpoYkhWbE9pQndjbTluY21WemMxeHVJQ0FnSUNBZ0lDQWdJQ0FnZlNrN1hHNGdJQ0FnSUNBZ0lIMWNiaUFnSUNCOUxDQjFibVJsWm1sdVpXUXBPMXh1WEc0Z0lDQWdjbVYwZFhKdUlHUmxabVZ5Y21Wa0xuQnliMjFwYzJVN1hHNTlYRzVjYmxCeWIyMXBjMlV1Y0hKdmRHOTBlWEJsTG1GdWVTQTlJR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdZVzU1S0hSb2FYTXBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQlhZV2wwY3lCbWIzSWdZV3hzSUhCeWIyMXBjMlZ6SUhSdklHSmxJSE5sZEhSc1pXUXNJR1ZwZEdobGNpQm1kV3htYVd4c1pXUWdiM0pjYmlBcUlISmxhbVZqZEdWa0xpQWdWR2hwY3lCcGN5QmthWE4wYVc1amRDQm1jbTl0SUdCaGJHeGdJSE5wYm1ObElIUm9ZWFFnZDI5MWJHUWdjM1J2Y0Z4dUlDb2dkMkZwZEdsdVp5QmhkQ0IwYUdVZ1ptbHljM1FnY21WcVpXTjBhVzl1TGlBZ1ZHaGxJSEJ5YjIxcGMyVWdjbVYwZFhKdVpXUWdZbmxjYmlBcUlHQmhiR3hTWlhOdmJIWmxaR0FnZDJsc2JDQnVaWFpsY2lCaVpTQnlaV3BsWTNSbFpDNWNiaUFxSUVCd1lYSmhiU0J3Y205dGFYTmxjeUJoSUhCeWIyMXBjMlVnWm05eUlHRnVJR0Z5Y21GNUlDaHZjaUJoYmlCaGNuSmhlU2tnYjJZZ2NISnZiV2x6WlhOY2JpQXFJQ2h2Y2lCMllXeDFaWE1wWEc0Z0tpQkFjbVYwZFhKdUlHRWdjSEp2YldselpTQm1iM0lnWVc0Z1lYSnlZWGtnYjJZZ2NISnZiV2x6WlhOY2JpQXFMMXh1VVM1aGJHeFNaWE52YkhabFpDQTlJR1JsY0hKbFkyRjBaU2hoYkd4U1pYTnZiSFpsWkN3Z1hDSmhiR3hTWlhOdmJIWmxaRndpTENCY0ltRnNiRk5sZEhSc1pXUmNJaWs3WEc1bWRXNWpkR2x2YmlCaGJHeFNaWE52YkhabFpDaHdjbTl0YVhObGN5a2dlMXh1SUNBZ0lISmxkSFZ5YmlCM2FHVnVLSEJ5YjIxcGMyVnpMQ0JtZFc1amRHbHZiaUFvY0hKdmJXbHpaWE1wSUh0Y2JpQWdJQ0FnSUNBZ2NISnZiV2x6WlhNZ1BTQmhjbkpoZVY5dFlYQW9jSEp2YldselpYTXNJRkVwTzF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnZDJobGJpaGhiR3dvWVhKeVlYbGZiV0Z3S0hCeWIyMXBjMlZ6TENCbWRXNWpkR2x2YmlBb2NISnZiV2x6WlNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSGRvWlc0b2NISnZiV2x6WlN3Z2JtOXZjQ3dnYm05dmNDazdYRzRnSUNBZ0lDQWdJSDBwS1N3Z1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhCeWIyMXBjMlZ6TzF4dUlDQWdJQ0FnSUNCOUtUdGNiaUFnSUNCOUtUdGNibjFjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdVlXeHNVbVZ6YjJ4MlpXUWdQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnY21WMGRYSnVJR0ZzYkZKbGMyOXNkbVZrS0hSb2FYTXBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQkFjMlZsSUZCeWIyMXBjMlVqWVd4c1UyVjBkR3hsWkZ4dUlDb3ZYRzVSTG1Gc2JGTmxkSFJzWldRZ1BTQmhiR3hUWlhSMGJHVmtPMXh1Wm5WdVkzUnBiMjRnWVd4c1UyVjBkR3hsWkNod2NtOXRhWE5sY3lrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0hCeWIyMXBjMlZ6S1M1aGJHeFRaWFIwYkdWa0tDazdYRzU5WEc1Y2JpOHFLbHh1SUNvZ1ZIVnlibk1nWVc0Z1lYSnlZWGtnYjJZZ2NISnZiV2x6WlhNZ2FXNTBieUJoSUhCeWIyMXBjMlVnWm05eUlHRnVJR0Z5Y21GNUlHOW1JSFJvWldseUlITjBZWFJsY3lBb1lYTmNiaUFxSUhKbGRIVnlibVZrSUdKNUlHQnBibk53WldOMFlDa2dkMmhsYmlCMGFHVjVJR2hoZG1VZ1lXeHNJSE5sZEhSc1pXUXVYRzRnS2lCQWNHRnlZVzBnZTBGeWNtRjVXMEZ1ZVNwZGZTQjJZV3gxWlhNZ1lXNGdZWEp5WVhrZ0tHOXlJSEJ5YjIxcGMyVWdabTl5SUdGdUlHRnljbUY1S1NCdlppQjJZV3gxWlhNZ0tHOXlYRzRnS2lCd2NtOXRhWE5sY3lCbWIzSWdkbUZzZFdWektWeHVJQ29nUUhKbGRIVnlibk1nZTBGeWNtRjVXMU4wWVhSbFhYMGdZVzRnWVhKeVlYa2diMllnYzNSaGRHVnpJR1p2Y2lCMGFHVWdjbVZ6Y0dWamRHbDJaU0IyWVd4MVpYTXVYRzRnS2k5Y2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExtRnNiRk5sZEhSc1pXUWdQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnY21WMGRYSnVJSFJvYVhNdWRHaGxiaWhtZFc1amRHbHZiaUFvY0hKdmJXbHpaWE1wSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUdGc2JDaGhjbkpoZVY5dFlYQW9jSEp2YldselpYTXNJR1oxYm1OMGFXOXVJQ2h3Y205dGFYTmxLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQndjbTl0YVhObElEMGdVU2h3Y205dGFYTmxLVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHWjFibU4wYVc5dUlISmxaMkZ5Wkd4bGMzTW9LU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSEJ5YjIxcGMyVXVhVzV6Y0dWamRDZ3BPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSEJ5YjIxcGMyVXVkR2hsYmloeVpXZGhjbVJzWlhOekxDQnlaV2RoY21Sc1pYTnpLVHRjYmlBZ0lDQWdJQ0FnZlNrcE8xeHVJQ0FnSUgwcE8xeHVmVHRjYmx4dUx5b3FYRzRnS2lCRFlYQjBkWEpsY3lCMGFHVWdabUZwYkhWeVpTQnZaaUJoSUhCeWIyMXBjMlVzSUdkcGRtbHVaeUJoYmlCdmNHOXlkSFZ1YVhSNUlIUnZJSEpsWTI5MlpYSmNiaUFxSUhkcGRHZ2dZU0JqWVd4c1ltRmpheTRnSUVsbUlIUm9aU0JuYVhabGJpQndjbTl0YVhObElHbHpJR1oxYkdacGJHeGxaQ3dnZEdobElISmxkSFZ5Ym1Wa1hHNGdLaUJ3Y205dGFYTmxJR2x6SUdaMWJHWnBiR3hsWkM1Y2JpQXFJRUJ3WVhKaGJTQjdRVzU1S24wZ2NISnZiV2x6WlNCbWIzSWdjMjl0WlhSb2FXNW5YRzRnS2lCQWNHRnlZVzBnZTBaMWJtTjBhVzl1ZlNCallXeHNZbUZqYXlCMGJ5Qm1kV3htYVd4c0lIUm9aU0J5WlhSMWNtNWxaQ0J3Y205dGFYTmxJR2xtSUhSb1pWeHVJQ29nWjJsMlpXNGdjSEp2YldselpTQnBjeUJ5WldwbFkzUmxaRnh1SUNvZ1FISmxkSFZ5Ym5NZ1lTQndjbTl0YVhObElHWnZjaUIwYUdVZ2NtVjBkWEp1SUhaaGJIVmxJRzltSUhSb1pTQmpZV3hzWW1GamExeHVJQ292WEc1UkxtWmhhV3dnUFNBdkx5QllXRmdnYkdWbllXTjVYRzVSVzF3aVkyRjBZMmhjSWwwZ1BTQm1kVzVqZEdsdmJpQW9iMkpxWldOMExDQnlaV3BsWTNSbFpDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCUktHOWlhbVZqZENrdWRHaGxiaWgyYjJsa0lEQXNJSEpsYW1WamRHVmtLVHRjYm4wN1hHNWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbVpoYVd3Z1BTQXZMeUJZV0ZnZ2JHVm5ZV041WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlZ0Y0ltTmhkR05vWENKZElEMGdablZ1WTNScGIyNGdLSEpsYW1WamRHVmtLU0I3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11ZEdobGJpaDJiMmxrSURBc0lISmxhbVZqZEdWa0tUdGNibjA3WEc1Y2JpOHFLbHh1SUNvZ1FYUjBZV05vWlhNZ1lTQnNhWE4wWlc1bGNpQjBhR0YwSUdOaGJpQnlaWE53YjI1a0lIUnZJSEJ5YjJkeVpYTnpJRzV2ZEdsbWFXTmhkR2x2Ym5NZ1puSnZiU0JoWEc0Z0tpQndjbTl0YVhObEozTWdiM0pwWjJsdVlYUnBibWNnWkdWbVpYSnlaV1F1SUZSb2FYTWdiR2x6ZEdWdVpYSWdjbVZqWldsMlpYTWdkR2hsSUdWNFlXTjBJR0Z5WjNWdFpXNTBjMXh1SUNvZ2NHRnpjMlZrSUhSdklHQmdaR1ZtWlhKeVpXUXVibTkwYVdaNVlHQXVYRzRnS2lCQWNHRnlZVzBnZTBGdWVTcDlJSEJ5YjIxcGMyVWdabTl5SUhOdmJXVjBhR2x1WjF4dUlDb2dRSEJoY21GdElIdEdkVzVqZEdsdmJuMGdZMkZzYkdKaFkyc2dkRzhnY21WalpXbDJaU0JoYm5rZ2NISnZaM0psYzNNZ2JtOTBhV1pwWTJGMGFXOXVjMXh1SUNvZ1FISmxkSFZ5Ym5NZ2RHaGxJR2RwZG1WdUlIQnliMjFwYzJVc0lIVnVZMmhoYm1kbFpGeHVJQ292WEc1UkxuQnliMmR5WlhOeklEMGdjSEp2WjNKbGMzTTdYRzVtZFc1amRHbHZiaUJ3Y205bmNtVnpjeWh2WW1wbFkzUXNJSEJ5YjJkeVpYTnpaV1FwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdVU2h2WW1wbFkzUXBMblJvWlc0b2RtOXBaQ0F3TENCMmIybGtJREFzSUhCeWIyZHlaWE56WldRcE8xeHVmVnh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1d2NtOW5jbVZ6Y3lBOUlHWjFibU4wYVc5dUlDaHdjbTluY21WemMyVmtLU0I3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11ZEdobGJpaDJiMmxrSURBc0lIWnZhV1FnTUN3Z2NISnZaM0psYzNObFpDazdYRzU5TzF4dVhHNHZLaXBjYmlBcUlGQnliM1pwWkdWeklHRnVJRzl3Y0c5eWRIVnVhWFI1SUhSdklHOWljMlZ5ZG1VZ2RHaGxJSE5sZEhSc2FXNW5JRzltSUdFZ2NISnZiV2x6WlN4Y2JpQXFJSEpsWjJGeVpHeGxjM01nYjJZZ2QyaGxkR2hsY2lCMGFHVWdjSEp2YldselpTQnBjeUJtZFd4bWFXeHNaV1FnYjNJZ2NtVnFaV04wWldRdUlDQkdiM0ozWVhKa2MxeHVJQ29nZEdobElISmxjMjlzZFhScGIyNGdkRzhnZEdobElISmxkSFZ5Ym1Wa0lIQnliMjFwYzJVZ2QyaGxiaUIwYUdVZ1kyRnNiR0poWTJzZ2FYTWdaRzl1WlM1Y2JpQXFJRlJvWlNCallXeHNZbUZqYXlCallXNGdjbVYwZFhKdUlHRWdjSEp2YldselpTQjBieUJrWldabGNpQmpiMjF3YkdWMGFXOXVMbHh1SUNvZ1FIQmhjbUZ0SUh0QmJua3FmU0J3Y205dGFYTmxYRzRnS2lCQWNHRnlZVzBnZTBaMWJtTjBhVzl1ZlNCallXeHNZbUZqYXlCMGJ5QnZZbk5sY25abElIUm9aU0J5WlhOdmJIVjBhVzl1SUc5bUlIUm9aU0JuYVhabGJseHVJQ29nY0hKdmJXbHpaU3dnZEdGclpYTWdibThnWVhKbmRXMWxiblJ6TGx4dUlDb2dRSEpsZEhWeWJuTWdZU0J3Y205dGFYTmxJR1p2Y2lCMGFHVWdjbVZ6YjJ4MWRHbHZiaUJ2WmlCMGFHVWdaMmwyWlc0Z2NISnZiV2x6WlNCM2FHVnVYRzRnS2lCZ1lHWnBibUJnSUdseklHUnZibVV1WEc0Z0tpOWNibEV1Wm1sdUlEMGdMeThnV0ZoWUlHeGxaMkZqZVZ4dVVWdGNJbVpwYm1Gc2JIbGNJbDBnUFNCbWRXNWpkR2x2YmlBb2IySnFaV04wTENCallXeHNZbUZqYXlrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0c5aWFtVmpkQ2xiWENKbWFXNWhiR3g1WENKZEtHTmhiR3hpWVdOcktUdGNibjA3WEc1Y2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExtWnBiaUE5SUM4dklGaFlXQ0JzWldkaFkzbGNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxXMXdpWm1sdVlXeHNlVndpWFNBOUlHWjFibU4wYVc5dUlDaGpZV3hzWW1GamF5a2dlMXh1SUNBZ0lHTmhiR3hpWVdOcklEMGdVU2hqWVd4c1ltRmpheWs3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11ZEdobGJpaG1kVzVqZEdsdmJpQW9kbUZzZFdVcElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHTmhiR3hpWVdOckxtWmpZV3hzS0NrdWRHaGxiaWhtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdkbUZzZFdVN1hHNGdJQ0FnSUNBZ0lIMHBPMXh1SUNBZ0lIMHNJR1oxYm1OMGFXOXVJQ2h5WldGemIyNHBJSHRjYmlBZ0lDQWdJQ0FnTHk4Z1ZFOUVUeUJoZEhSbGJYQjBJSFJ2SUhKbFkzbGpiR1VnZEdobElISmxhbVZqZEdsdmJpQjNhWFJvSUZ3aWRHaHBjMXdpTGx4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnWTJGc2JHSmhZMnN1Wm1OaGJHd29LUzUwYUdWdUtHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIUm9jbTkzSUhKbFlYTnZianRjYmlBZ0lDQWdJQ0FnZlNrN1hHNGdJQ0FnZlNrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUZSbGNtMXBibUYwWlhNZ1lTQmphR0ZwYmlCdlppQndjbTl0YVhObGN5d2dabTl5WTJsdVp5QnlaV3BsWTNScGIyNXpJSFJ2SUdKbFhHNGdLaUIwYUhKdmQyNGdZWE1nWlhoalpYQjBhVzl1Y3k1Y2JpQXFJRUJ3WVhKaGJTQjdRVzU1S24wZ2NISnZiV2x6WlNCaGRDQjBhR1VnWlc1a0lHOW1JR0VnWTJoaGFXNGdiMllnY0hKdmJXbHpaWE5jYmlBcUlFQnlaWFIxY201eklHNXZkR2hwYm1kY2JpQXFMMXh1VVM1a2IyNWxJRDBnWm5WdVkzUnBiMjRnS0c5aWFtVmpkQ3dnWm5Wc1ptbHNiR1ZrTENCeVpXcGxZM1JsWkN3Z2NISnZaM0psYzNNcElIdGNiaUFnSUNCeVpYUjFjbTRnVVNodlltcGxZM1FwTG1SdmJtVW9ablZzWm1sc2JHVmtMQ0J5WldwbFkzUmxaQ3dnY0hKdlozSmxjM01wTzF4dWZUdGNibHh1VUhKdmJXbHpaUzV3Y205MGIzUjVjR1V1Wkc5dVpTQTlJR1oxYm1OMGFXOXVJQ2htZFd4bWFXeHNaV1FzSUhKbGFtVmpkR1ZrTENCd2NtOW5jbVZ6Y3lrZ2UxeHVJQ0FnSUhaaGNpQnZibFZ1YUdGdVpHeGxaRVZ5Y205eUlEMGdablZ1WTNScGIyNGdLR1Z5Y205eUtTQjdYRzRnSUNBZ0lDQWdJQzh2SUdadmNuZGhjbVFnZEc4Z1lTQm1kWFIxY21VZ2RIVnliaUJ6YnlCMGFHRjBJR0JnZDJobGJtQmdYRzRnSUNBZ0lDQWdJQzh2SUdSdlpYTWdibTkwSUdOaGRHTm9JR2wwSUdGdVpDQjBkWEp1SUdsMElHbHVkRzhnWVNCeVpXcGxZM1JwYjI0dVhHNGdJQ0FnSUNBZ0lGRXVibVY0ZEZScFkyc29ablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdiV0ZyWlZOMFlXTnJWSEpoWTJWTWIyNW5LR1Z5Y205eUxDQndjbTl0YVhObEtUdGNiaUFnSUNBZ0lDQWdJQ0FnSUdsbUlDaFJMbTl1WlhKeWIzSXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JSTG05dVpYSnliM0lvWlhKeWIzSXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCMGFISnZkeUJsY25KdmNqdGNiaUFnSUNBZ0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ2ZTazdYRzRnSUNBZ2ZUdGNibHh1SUNBZ0lDOHZJRUYyYjJsa0lIVnVibVZqWlhOellYSjVJR0J1WlhoMFZHbGphMkJwYm1jZ2RtbGhJR0Z1SUhWdWJtVmpaWE56WVhKNUlHQjNhR1Z1WUM1Y2JpQWdJQ0IyWVhJZ2NISnZiV2x6WlNBOUlHWjFiR1pwYkd4bFpDQjhmQ0J5WldwbFkzUmxaQ0I4ZkNCd2NtOW5jbVZ6Y3lBL1hHNGdJQ0FnSUNBZ0lIUm9hWE11ZEdobGJpaG1kV3htYVd4c1pXUXNJSEpsYW1WamRHVmtMQ0J3Y205bmNtVnpjeWtnT2x4dUlDQWdJQ0FnSUNCMGFHbHpPMXh1WEc0Z0lDQWdhV1lnS0hSNWNHVnZaaUJ3Y205alpYTnpJRDA5UFNCY0ltOWlhbVZqZEZ3aUlDWW1JSEJ5YjJObGMzTWdKaVlnY0hKdlkyVnpjeTVrYjIxaGFXNHBJSHRjYmlBZ0lDQWdJQ0FnYjI1VmJtaGhibVJzWldSRmNuSnZjaUE5SUhCeWIyTmxjM011Wkc5dFlXbHVMbUpwYm1Rb2IyNVZibWhoYm1Sc1pXUkZjbkp2Y2lrN1hHNGdJQ0FnZlZ4dVhHNGdJQ0FnY0hKdmJXbHpaUzUwYUdWdUtIWnZhV1FnTUN3Z2IyNVZibWhoYm1Sc1pXUkZjbkp2Y2lrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUVOaGRYTmxjeUJoSUhCeWIyMXBjMlVnZEc4Z1ltVWdjbVZxWldOMFpXUWdhV1lnYVhRZ1pHOWxjeUJ1YjNRZ1oyVjBJR1oxYkdacGJHeGxaQ0JpWldadmNtVmNiaUFxSUhOdmJXVWdiV2xzYkdselpXTnZibVJ6SUhScGJXVWdiM1YwTGx4dUlDb2dRSEJoY21GdElIdEJibmtxZlNCd2NtOXRhWE5sWEc0Z0tpQkFjR0Z5WVcwZ2UwNTFiV0psY24wZ2JXbHNiR2x6WldOdmJtUnpJSFJwYldWdmRYUmNiaUFxSUVCd1lYSmhiU0I3UVc1NUtuMGdZM1Z6ZEc5dElHVnljbTl5SUcxbGMzTmhaMlVnYjNJZ1JYSnliM0lnYjJKcVpXTjBJQ2h2Y0hScGIyNWhiQ2xjYmlBcUlFQnlaWFIxY201eklHRWdjSEp2YldselpTQm1iM0lnZEdobElISmxjMjlzZFhScGIyNGdiMllnZEdobElHZHBkbVZ1SUhCeWIyMXBjMlVnYVdZZ2FYUWdhWE5jYmlBcUlHWjFiR1pwYkd4bFpDQmlaV1p2Y21VZ2RHaGxJSFJwYldWdmRYUXNJRzkwYUdWeWQybHpaU0J5WldwbFkzUmxaQzVjYmlBcUwxeHVVUzUwYVcxbGIzVjBJRDBnWm5WdVkzUnBiMjRnS0c5aWFtVmpkQ3dnYlhNc0lHVnljbTl5S1NCN1hHNGdJQ0FnY21WMGRYSnVJRkVvYjJKcVpXTjBLUzUwYVcxbGIzVjBLRzF6TENCbGNuSnZjaWs3WEc1OU8xeHVYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzUwYVcxbGIzVjBJRDBnWm5WdVkzUnBiMjRnS0cxekxDQmxjbkp2Y2lrZ2UxeHVJQ0FnSUhaaGNpQmtaV1psY25KbFpDQTlJR1JsWm1WeUtDazdYRzRnSUNBZ2RtRnlJSFJwYldWdmRYUkpaQ0E5SUhObGRGUnBiV1Z2ZFhRb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0JwWmlBb0lXVnljbTl5SUh4OElGd2ljM1J5YVc1blhDSWdQVDA5SUhSNWNHVnZaaUJsY25KdmNpa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ1pYSnliM0lnUFNCdVpYY2dSWEp5YjNJb1pYSnliM0lnZkh3Z1hDSlVhVzFsWkNCdmRYUWdZV1owWlhJZ1hDSWdLeUJ0Y3lBcklGd2lJRzF6WENJcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnWlhKeWIzSXVZMjlrWlNBOUlGd2lSVlJKVFVWRVQxVlVYQ0k3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ1pHVm1aWEp5WldRdWNtVnFaV04wS0dWeWNtOXlLVHRjYmlBZ0lDQjlMQ0J0Y3lrN1hHNWNiaUFnSUNCMGFHbHpMblJvWlc0b1puVnVZM1JwYjI0Z0tIWmhiSFZsS1NCN1hHNGdJQ0FnSUNBZ0lHTnNaV0Z5VkdsdFpXOTFkQ2gwYVcxbGIzVjBTV1FwTzF4dUlDQWdJQ0FnSUNCa1pXWmxjbkpsWkM1eVpYTnZiSFpsS0haaGJIVmxLVHRjYmlBZ0lDQjlMQ0JtZFc1amRHbHZiaUFvWlhoalpYQjBhVzl1S1NCN1hHNGdJQ0FnSUNBZ0lHTnNaV0Z5VkdsdFpXOTFkQ2gwYVcxbGIzVjBTV1FwTzF4dUlDQWdJQ0FnSUNCa1pXWmxjbkpsWkM1eVpXcGxZM1FvWlhoalpYQjBhVzl1S1R0Y2JpQWdJQ0I5TENCa1pXWmxjbkpsWkM1dWIzUnBabmtwTzF4dVhHNGdJQ0FnY21WMGRYSnVJR1JsWm1WeWNtVmtMbkJ5YjIxcGMyVTdYRzU5TzF4dVhHNHZLaXBjYmlBcUlGSmxkSFZ5Ym5NZ1lTQndjbTl0YVhObElHWnZjaUIwYUdVZ1oybDJaVzRnZG1Gc2RXVWdLRzl5SUhCeWIyMXBjMlZrSUhaaGJIVmxLU3dnYzI5dFpWeHVJQ29nYldsc2JHbHpaV052Ym1SeklHRm1kR1Z5SUdsMElISmxjMjlzZG1Wa0xpQlFZWE56WlhNZ2NtVnFaV04wYVc5dWN5QnBiVzFsWkdsaGRHVnNlUzVjYmlBcUlFQndZWEpoYlNCN1FXNTVLbjBnY0hKdmJXbHpaVnh1SUNvZ1FIQmhjbUZ0SUh0T2RXMWlaWEo5SUcxcGJHeHBjMlZqYjI1a2MxeHVJQ29nUUhKbGRIVnlibk1nWVNCd2NtOXRhWE5sSUdadmNpQjBhR1VnY21WemIyeDFkR2x2YmlCdlppQjBhR1VnWjJsMlpXNGdjSEp2YldselpTQmhablJsY2lCdGFXeHNhWE5sWTI5dVpITmNiaUFxSUhScGJXVWdhR0Z6SUdWc1lYQnpaV1FnYzJsdVkyVWdkR2hsSUhKbGMyOXNkWFJwYjI0Z2IyWWdkR2hsSUdkcGRtVnVJSEJ5YjIxcGMyVXVYRzRnS2lCSlppQjBhR1VnWjJsMlpXNGdjSEp2YldselpTQnlaV3BsWTNSekxDQjBhR0YwSUdseklIQmhjM05sWkNCcGJXMWxaR2xoZEdWc2VTNWNiaUFxTDF4dVVTNWtaV3hoZVNBOUlHWjFibU4wYVc5dUlDaHZZbXBsWTNRc0lIUnBiV1Z2ZFhRcElIdGNiaUFnSUNCcFppQW9kR2x0Wlc5MWRDQTlQVDBnZG05cFpDQXdLU0I3WEc0Z0lDQWdJQ0FnSUhScGJXVnZkWFFnUFNCdlltcGxZM1E3WEc0Z0lDQWdJQ0FnSUc5aWFtVmpkQ0E5SUhadmFXUWdNRHRjYmlBZ0lDQjlYRzRnSUNBZ2NtVjBkWEp1SUZFb2IySnFaV04wS1M1a1pXeGhlU2gwYVcxbGIzVjBLVHRjYm4wN1hHNWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbVJsYkdGNUlEMGdablZ1WTNScGIyNGdLSFJwYldWdmRYUXBJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTUwYUdWdUtHWjFibU4wYVc5dUlDaDJZV3gxWlNrZ2UxeHVJQ0FnSUNBZ0lDQjJZWElnWkdWbVpYSnlaV1FnUFNCa1pXWmxjaWdwTzF4dUlDQWdJQ0FnSUNCelpYUlVhVzFsYjNWMEtHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHUmxabVZ5Y21Wa0xuSmxjMjlzZG1Vb2RtRnNkV1VwTzF4dUlDQWdJQ0FnSUNCOUxDQjBhVzFsYjNWMEtUdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHUmxabVZ5Y21Wa0xuQnliMjFwYzJVN1hHNGdJQ0FnZlNrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUZCaGMzTmxjeUJoSUdOdmJuUnBiblZoZEdsdmJpQjBieUJoSUU1dlpHVWdablZ1WTNScGIyNHNJSGRvYVdOb0lHbHpJR05oYkd4bFpDQjNhWFJvSUhSb1pTQm5hWFpsYmx4dUlDb2dZWEpuZFcxbGJuUnpJSEJ5YjNacFpHVmtJR0Z6SUdGdUlHRnljbUY1TENCaGJtUWdjbVYwZFhKdWN5QmhJSEJ5YjIxcGMyVXVYRzRnS2x4dUlDb2dJQ0FnSUNCUkxtNW1ZWEJ3Ykhrb1JsTXVjbVZoWkVacGJHVXNJRnRmWDJacGJHVnVZVzFsWFNsY2JpQXFJQ0FnSUNBZ0xuUm9aVzRvWm5WdVkzUnBiMjRnS0dOdmJuUmxiblFwSUh0Y2JpQXFJQ0FnSUNBZ2ZTbGNiaUFxWEc0Z0tpOWNibEV1Ym1aaGNIQnNlU0E5SUdaMWJtTjBhVzl1SUNoallXeHNZbUZqYXl3Z1lYSm5jeWtnZTF4dUlDQWdJSEpsZEhWeWJpQlJLR05oYkd4aVlXTnJLUzV1Wm1Gd2NHeDVLR0Z5WjNNcE8xeHVmVHRjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWJtWmhjSEJzZVNBOUlHWjFibU4wYVc5dUlDaGhjbWR6S1NCN1hHNGdJQ0FnZG1GeUlHUmxabVZ5Y21Wa0lEMGdaR1ZtWlhJb0tUdGNiaUFnSUNCMllYSWdibTlrWlVGeVozTWdQU0JoY25KaGVWOXpiR2xqWlNoaGNtZHpLVHRjYmlBZ0lDQnViMlJsUVhKbmN5NXdkWE5vS0dSbFptVnljbVZrTG0xaGEyVk9iMlJsVW1WemIyeDJaWElvS1NrN1hHNGdJQ0FnZEdocGN5NW1ZWEJ3Ykhrb2JtOWtaVUZ5WjNNcExtWmhhV3dvWkdWbVpYSnlaV1F1Y21WcVpXTjBLVHRjYmlBZ0lDQnlaWFIxY200Z1pHVm1aWEp5WldRdWNISnZiV2x6WlR0Y2JuMDdYRzVjYmk4cUtseHVJQ29nVUdGemMyVnpJR0VnWTI5dWRHbHVkV0YwYVc5dUlIUnZJR0VnVG05a1pTQm1kVzVqZEdsdmJpd2dkMmhwWTJnZ2FYTWdZMkZzYkdWa0lIZHBkR2dnZEdobElHZHBkbVZ1WEc0Z0tpQmhjbWQxYldWdWRITWdjSEp2ZG1sa1pXUWdhVzVrYVhacFpIVmhiR3g1TENCaGJtUWdjbVYwZFhKdWN5QmhJSEJ5YjIxcGMyVXVYRzRnS2lCQVpYaGhiWEJzWlZ4dUlDb2dVUzV1Wm1OaGJHd29SbE11Y21WaFpFWnBiR1VzSUY5ZlptbHNaVzVoYldVcFhHNGdLaUF1ZEdobGJpaG1kVzVqZEdsdmJpQW9ZMjl1ZEdWdWRDa2dlMXh1SUNvZ2ZTbGNiaUFxWEc0Z0tpOWNibEV1Ym1aallXeHNJRDBnWm5WdVkzUnBiMjRnS0dOaGJHeGlZV05ySUM4cUxpNHVZWEpuY3lvdktTQjdYRzRnSUNBZ2RtRnlJR0Z5WjNNZ1BTQmhjbkpoZVY5emJHbGpaU2hoY21kMWJXVnVkSE1zSURFcE8xeHVJQ0FnSUhKbGRIVnliaUJSS0dOaGJHeGlZV05yS1M1dVptRndjR3g1S0dGeVozTXBPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVibVpqWVd4c0lEMGdablZ1WTNScGIyNGdLQzhxTGk0dVlYSm5jeW92S1NCN1hHNGdJQ0FnZG1GeUlHNXZaR1ZCY21keklEMGdZWEp5WVhsZmMyeHBZMlVvWVhKbmRXMWxiblJ6S1R0Y2JpQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUc1dlpHVkJjbWR6TG5CMWMyZ29aR1ZtWlhKeVpXUXViV0ZyWlU1dlpHVlNaWE52YkhabGNpZ3BLVHRjYmlBZ0lDQjBhR2x6TG1aaGNIQnNlU2h1YjJSbFFYSm5jeWt1Wm1GcGJDaGtaV1psY25KbFpDNXlaV3BsWTNRcE8xeHVJQ0FnSUhKbGRIVnliaUJrWldabGNuSmxaQzV3Y205dGFYTmxPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQlhjbUZ3Y3lCaElFNXZaR1ZLVXlCamIyNTBhVzUxWVhScGIyNGdjR0Z6YzJsdVp5Qm1kVzVqZEdsdmJpQmhibVFnY21WMGRYSnVjeUJoYmlCbGNYVnBkbUZzWlc1MFhHNGdLaUIyWlhKemFXOXVJSFJvWVhRZ2NtVjBkWEp1Y3lCaElIQnliMjFwYzJVdVhHNGdLaUJBWlhoaGJYQnNaVnh1SUNvZ1VTNXVabUpwYm1Rb1JsTXVjbVZoWkVacGJHVXNJRjlmWm1sc1pXNWhiV1VwS0Z3aWRYUm1MVGhjSWlsY2JpQXFJQzUwYUdWdUtHTnZibk52YkdVdWJHOW5LVnh1SUNvZ0xtUnZibVVvS1Z4dUlDb3ZYRzVSTG01bVltbHVaQ0E5WEc1UkxtUmxibTlrWldsbWVTQTlJR1oxYm1OMGFXOXVJQ2hqWVd4c1ltRmpheUF2S2k0dUxtRnlaM01xTHlrZ2UxeHVJQ0FnSUhaaGNpQmlZWE5sUVhKbmN5QTlJR0Z5Y21GNVgzTnNhV05sS0dGeVozVnRaVzUwY3l3Z01TazdYRzRnSUNBZ2NtVjBkWEp1SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdkbUZ5SUc1dlpHVkJjbWR6SUQwZ1ltRnpaVUZ5WjNNdVkyOXVZMkYwS0dGeWNtRjVYM05zYVdObEtHRnlaM1Z0Wlc1MGN5a3BPMXh1SUNBZ0lDQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUNBZ0lDQnViMlJsUVhKbmN5NXdkWE5vS0dSbFptVnljbVZrTG0xaGEyVk9iMlJsVW1WemIyeDJaWElvS1NrN1hHNGdJQ0FnSUNBZ0lGRW9ZMkZzYkdKaFkyc3BMbVpoY0hCc2VTaHViMlJsUVhKbmN5a3VabUZwYkNoa1pXWmxjbkpsWkM1eVpXcGxZM1FwTzF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnWkdWbVpYSnlaV1F1Y0hKdmJXbHpaVHRjYmlBZ0lDQjlPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVibVppYVc1a0lEMWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbVJsYm05a1pXbG1lU0E5SUdaMWJtTjBhVzl1SUNndktpNHVMbUZ5WjNNcUx5a2dlMXh1SUNBZ0lIWmhjaUJoY21keklEMGdZWEp5WVhsZmMyeHBZMlVvWVhKbmRXMWxiblJ6S1R0Y2JpQWdJQ0JoY21kekxuVnVjMmhwWm5Rb2RHaHBjeWs3WEc0Z0lDQWdjbVYwZFhKdUlGRXVaR1Z1YjJSbGFXWjVMbUZ3Y0d4NUtIWnZhV1FnTUN3Z1lYSm5jeWs3WEc1OU8xeHVYRzVSTG01aWFXNWtJRDBnWm5WdVkzUnBiMjRnS0dOaGJHeGlZV05yTENCMGFHbHpjQ0F2S2k0dUxtRnlaM01xTHlrZ2UxeHVJQ0FnSUhaaGNpQmlZWE5sUVhKbmN5QTlJR0Z5Y21GNVgzTnNhV05sS0dGeVozVnRaVzUwY3l3Z01pazdYRzRnSUNBZ2NtVjBkWEp1SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdkbUZ5SUc1dlpHVkJjbWR6SUQwZ1ltRnpaVUZ5WjNNdVkyOXVZMkYwS0dGeWNtRjVYM05zYVdObEtHRnlaM1Z0Wlc1MGN5a3BPMXh1SUNBZ0lDQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUNBZ0lDQnViMlJsUVhKbmN5NXdkWE5vS0dSbFptVnljbVZrTG0xaGEyVk9iMlJsVW1WemIyeDJaWElvS1NrN1hHNGdJQ0FnSUNBZ0lHWjFibU4wYVc5dUlHSnZkVzVrS0NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJR05oYkd4aVlXTnJMbUZ3Y0d4NUtIUm9hWE53TENCaGNtZDFiV1Z1ZEhNcE8xeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJRkVvWW05MWJtUXBMbVpoY0hCc2VTaHViMlJsUVhKbmN5a3VabUZwYkNoa1pXWmxjbkpsWkM1eVpXcGxZM1FwTzF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnWkdWbVpYSnlaV1F1Y0hKdmJXbHpaVHRjYmlBZ0lDQjlPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVibUpwYm1RZ1BTQm1kVzVqZEdsdmJpQW9MeXAwYUdsemNDd2dMaTR1WVhKbmN5b3ZLU0I3WEc0Z0lDQWdkbUZ5SUdGeVozTWdQU0JoY25KaGVWOXpiR2xqWlNoaGNtZDFiV1Z1ZEhNc0lEQXBPMXh1SUNBZ0lHRnlaM011ZFc1emFHbG1kQ2gwYUdsektUdGNiaUFnSUNCeVpYUjFjbTRnVVM1dVltbHVaQzVoY0hCc2VTaDJiMmxrSURBc0lHRnlaM01wTzF4dWZUdGNibHh1THlvcVhHNGdLaUJEWVd4c2N5QmhJRzFsZEdodlpDQnZaaUJoSUU1dlpHVXRjM1I1YkdVZ2IySnFaV04wSUhSb1lYUWdZV05qWlhCMGN5QmhJRTV2WkdVdGMzUjViR1ZjYmlBcUlHTmhiR3hpWVdOcklIZHBkR2dnWVNCbmFYWmxiaUJoY25KaGVTQnZaaUJoY21kMWJXVnVkSE1zSUhCc2RYTWdZU0J3Y205MmFXUmxaQ0JqWVd4c1ltRmpheTVjYmlBcUlFQndZWEpoYlNCdlltcGxZM1FnWVc0Z2IySnFaV04wSUhSb1lYUWdhR0Z6SUhSb1pTQnVZVzFsWkNCdFpYUm9iMlJjYmlBcUlFQndZWEpoYlNCN1UzUnlhVzVuZlNCdVlXMWxJRzVoYldVZ2IyWWdkR2hsSUcxbGRHaHZaQ0J2WmlCdlltcGxZM1JjYmlBcUlFQndZWEpoYlNCN1FYSnlZWGw5SUdGeVozTWdZWEpuZFcxbGJuUnpJSFJ2SUhCaGMzTWdkRzhnZEdobElHMWxkR2h2WkRzZ2RHaGxJR05oYkd4aVlXTnJYRzRnS2lCM2FXeHNJR0psSUhCeWIzWnBaR1ZrSUdKNUlGRWdZVzVrSUdGd2NHVnVaR1ZrSUhSdklIUm9aWE5sSUdGeVozVnRaVzUwY3k1Y2JpQXFJRUJ5WlhSMWNtNXpJR0VnY0hKdmJXbHpaU0JtYjNJZ2RHaGxJSFpoYkhWbElHOXlJR1Z5Y205eVhHNGdLaTljYmxFdWJtMWhjSEJzZVNBOUlDOHZJRmhZV0NCQmN5QndjbTl3YjNObFpDQmllU0JjSWxKbFpITmhibVJ5YjF3aVhHNVJMbTV3YjNOMElEMGdablZ1WTNScGIyNGdLRzlpYW1WamRDd2dibUZ0WlN3Z1lYSm5jeWtnZTF4dUlDQWdJSEpsZEhWeWJpQlJLRzlpYW1WamRDa3VibkJ2YzNRb2JtRnRaU3dnWVhKbmN5azdYRzU5TzF4dVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNXViV0Z3Y0d4NUlEMGdMeThnV0ZoWUlFRnpJSEJ5YjNCdmMyVmtJR0o1SUZ3aVVtVmtjMkZ1WkhKdlhDSmNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbTV3YjNOMElEMGdablZ1WTNScGIyNGdLRzVoYldVc0lHRnlaM01wSUh0Y2JpQWdJQ0IyWVhJZ2JtOWtaVUZ5WjNNZ1BTQmhjbkpoZVY5emJHbGpaU2hoY21keklIeDhJRnRkS1R0Y2JpQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUc1dlpHVkJjbWR6TG5CMWMyZ29aR1ZtWlhKeVpXUXViV0ZyWlU1dlpHVlNaWE52YkhabGNpZ3BLVHRjYmlBZ0lDQjBhR2x6TG1ScGMzQmhkR05vS0Z3aWNHOXpkRndpTENCYmJtRnRaU3dnYm05a1pVRnlaM05kS1M1bVlXbHNLR1JsWm1WeWNtVmtMbkpsYW1WamRDazdYRzRnSUNBZ2NtVjBkWEp1SUdSbFptVnljbVZrTG5CeWIyMXBjMlU3WEc1OU8xeHVYRzR2S2lwY2JpQXFJRU5oYkd4eklHRWdiV1YwYUc5a0lHOW1JR0VnVG05a1pTMXpkSGxzWlNCdlltcGxZM1FnZEdoaGRDQmhZMk5sY0hSeklHRWdUbTlrWlMxemRIbHNaVnh1SUNvZ1kyRnNiR0poWTJzc0lHWnZjbmRoY21ScGJtY2dkR2hsSUdkcGRtVnVJSFpoY21saFpHbGpJR0Z5WjNWdFpXNTBjeXdnY0d4MWN5QmhJSEJ5YjNacFpHVmtYRzRnS2lCallXeHNZbUZqYXlCaGNtZDFiV1Z1ZEM1Y2JpQXFJRUJ3WVhKaGJTQnZZbXBsWTNRZ1lXNGdiMkpxWldOMElIUm9ZWFFnYUdGeklIUm9aU0J1WVcxbFpDQnRaWFJvYjJSY2JpQXFJRUJ3WVhKaGJTQjdVM1J5YVc1bmZTQnVZVzFsSUc1aGJXVWdiMllnZEdobElHMWxkR2h2WkNCdlppQnZZbXBsWTNSY2JpQXFJRUJ3WVhKaGJTQXVMaTVoY21keklHRnlaM1Z0Wlc1MGN5QjBieUJ3WVhOeklIUnZJSFJvWlNCdFpYUm9iMlE3SUhSb1pTQmpZV3hzWW1GamF5QjNhV3hzWEc0Z0tpQmlaU0J3Y205MmFXUmxaQ0JpZVNCUklHRnVaQ0JoY0hCbGJtUmxaQ0IwYnlCMGFHVnpaU0JoY21kMWJXVnVkSE11WEc0Z0tpQkFjbVYwZFhKdWN5QmhJSEJ5YjIxcGMyVWdabTl5SUhSb1pTQjJZV3gxWlNCdmNpQmxjbkp2Y2x4dUlDb3ZYRzVSTG01elpXNWtJRDBnTHk4Z1dGaFlJRUpoYzJWa0lHOXVJRTFoY21zZ1RXbHNiR1Z5SjNNZ2NISnZjRzl6WldRZ1hDSnpaVzVrWENKY2JsRXVibTFqWVd4c0lEMGdMeThnV0ZoWUlFSmhjMlZrSUc5dUlGd2lVbVZrYzJGdVpISnZKM05jSWlCd2NtOXdiM05oYkZ4dVVTNXVhVzUyYjJ0bElEMGdablZ1WTNScGIyNGdLRzlpYW1WamRDd2dibUZ0WlNBdktpNHVMbUZ5WjNNcUx5a2dlMXh1SUNBZ0lIWmhjaUJ1YjJSbFFYSm5jeUE5SUdGeWNtRjVYM05zYVdObEtHRnlaM1Z0Wlc1MGN5d2dNaWs3WEc0Z0lDQWdkbUZ5SUdSbFptVnljbVZrSUQwZ1pHVm1aWElvS1R0Y2JpQWdJQ0J1YjJSbFFYSm5jeTV3ZFhOb0tHUmxabVZ5Y21Wa0xtMWhhMlZPYjJSbFVtVnpiMngyWlhJb0tTazdYRzRnSUNBZ1VTaHZZbXBsWTNRcExtUnBjM0JoZEdOb0tGd2ljRzl6ZEZ3aUxDQmJibUZ0WlN3Z2JtOWtaVUZ5WjNOZEtTNW1ZV2xzS0dSbFptVnljbVZrTG5KbGFtVmpkQ2s3WEc0Z0lDQWdjbVYwZFhKdUlHUmxabVZ5Y21Wa0xuQnliMjFwYzJVN1hHNTlPMXh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1dWMyVnVaQ0E5SUM4dklGaFlXQ0JDWVhObFpDQnZiaUJOWVhKcklFMXBiR3hsY2lkeklIQnliM0J2YzJWa0lGd2ljMlZ1WkZ3aVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNXViV05oYkd3Z1BTQXZMeUJZV0ZnZ1FtRnpaV1FnYjI0Z1hDSlNaV1J6WVc1a2NtOG5jMXdpSUhCeWIzQnZjMkZzWEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1dWFXNTJiMnRsSUQwZ1puVnVZM1JwYjI0Z0tHNWhiV1VnTHlvdUxpNWhjbWR6S2k4cElIdGNiaUFnSUNCMllYSWdibTlrWlVGeVozTWdQU0JoY25KaGVWOXpiR2xqWlNoaGNtZDFiV1Z1ZEhNc0lERXBPMXh1SUNBZ0lIWmhjaUJrWldabGNuSmxaQ0E5SUdSbFptVnlLQ2s3WEc0Z0lDQWdibTlrWlVGeVozTXVjSFZ6YUNoa1pXWmxjbkpsWkM1dFlXdGxUbTlrWlZKbGMyOXNkbVZ5S0NrcE8xeHVJQ0FnSUhSb2FYTXVaR2x6Y0dGMFkyZ29YQ0p3YjNOMFhDSXNJRnR1WVcxbExDQnViMlJsUVhKbmMxMHBMbVpoYVd3b1pHVm1aWEp5WldRdWNtVnFaV04wS1R0Y2JpQWdJQ0J5WlhSMWNtNGdaR1ZtWlhKeVpXUXVjSEp2YldselpUdGNibjA3WEc1Y2JpOHFLbHh1SUNvZ1NXWWdZU0JtZFc1amRHbHZiaUIzYjNWc1pDQnNhV3RsSUhSdklITjFjSEJ2Y25RZ1ltOTBhQ0JPYjJSbElHTnZiblJwYm5WaGRHbHZiaTF3WVhOemFXNW5MWE4wZVd4bElHRnVaRnh1SUNvZ2NISnZiV2x6WlMxeVpYUjFjbTVwYm1jdGMzUjViR1VzSUdsMElHTmhiaUJsYm1RZ2FYUnpJR2x1ZEdWeWJtRnNJSEJ5YjIxcGMyVWdZMmhoYVc0Z2QybDBhRnh1SUNvZ1lHNXZaR1ZwWm5rb2JtOWtaV0poWTJzcFlDd2dabTl5ZDJGeVpHbHVaeUIwYUdVZ2IzQjBhVzl1WVd3Z2JtOWtaV0poWTJzZ1lYSm5kVzFsYm5RdUlDQkpaaUIwYUdVZ2RYTmxjbHh1SUNvZ1pXeGxZM1J6SUhSdklIVnpaU0JoSUc1dlpHVmlZV05yTENCMGFHVWdjbVZ6ZFd4MElIZHBiR3dnWW1VZ2MyVnVkQ0IwYUdWeVpTNGdJRWxtSUhSb1pYa2daRzhnYm05MFhHNGdLaUJ3WVhOeklHRWdibTlrWldKaFkyc3NJSFJvWlhrZ2QybHNiQ0J5WldObGFYWmxJSFJvWlNCeVpYTjFiSFFnY0hKdmJXbHpaUzVjYmlBcUlFQndZWEpoYlNCdlltcGxZM1FnWVNCeVpYTjFiSFFnS0c5eUlHRWdjSEp2YldselpTQm1iM0lnWVNCeVpYTjFiSFFwWEc0Z0tpQkFjR0Z5WVcwZ2UwWjFibU4wYVc5dWZTQnViMlJsWW1GamF5QmhJRTV2WkdVdWFuTXRjM1I1YkdVZ1kyRnNiR0poWTJ0Y2JpQXFJRUJ5WlhSMWNtNXpJR1ZwZEdobGNpQjBhR1VnY0hKdmJXbHpaU0J2Y2lCdWIzUm9hVzVuWEc0Z0tpOWNibEV1Ym05a1pXbG1lU0E5SUc1dlpHVnBabms3WEc1bWRXNWpkR2x2YmlCdWIyUmxhV1o1S0c5aWFtVmpkQ3dnYm05a1pXSmhZMnNwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdVU2h2WW1wbFkzUXBMbTV2WkdWcFpua29ibTlrWldKaFkyc3BPMXh1ZlZ4dVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNXViMlJsYVdaNUlEMGdablZ1WTNScGIyNGdLRzV2WkdWaVlXTnJLU0I3WEc0Z0lDQWdhV1lnS0c1dlpHVmlZV05yS1NCN1hHNGdJQ0FnSUNBZ0lIUm9hWE11ZEdobGJpaG1kVzVqZEdsdmJpQW9kbUZzZFdVcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUZFdWJtVjRkRlJwWTJzb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJRzV2WkdWaVlXTnJLRzUxYkd3c0lIWmhiSFZsS1R0Y2JpQWdJQ0FnSUNBZ0lDQWdJSDBwTzF4dUlDQWdJQ0FnSUNCOUxDQm1kVzVqZEdsdmJpQW9aWEp5YjNJcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUZFdWJtVjRkRlJwWTJzb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJRzV2WkdWaVlXTnJLR1Z5Y205eUtUdGNiaUFnSUNBZ0lDQWdJQ0FnSUgwcE8xeHVJQ0FnSUNBZ0lDQjlLVHRjYmlBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQnlaWFIxY200Z2RHaHBjenRjYmlBZ0lDQjlYRzU5TzF4dVhHNVJMbTV2UTI5dVpteHBZM1FnUFNCbWRXNWpkR2x2YmlncElIdGNiaUFnSUNCMGFISnZkeUJ1WlhjZ1JYSnliM0lvWENKUkxtNXZRMjl1Wm14cFkzUWdiMjVzZVNCM2IzSnJjeUIzYUdWdUlGRWdhWE1nZFhObFpDQmhjeUJoSUdkc2IySmhiRndpS1R0Y2JuMDdYRzVjYmk4dklFRnNiQ0JqYjJSbElHSmxabTl5WlNCMGFHbHpJSEJ2YVc1MElIZHBiR3dnWW1VZ1ptbHNkR1Z5WldRZ1puSnZiU0J6ZEdGamF5QjBjbUZqWlhNdVhHNTJZWElnY1VWdVpHbHVaMHhwYm1VZ1BTQmpZWEIwZFhKbFRHbHVaU2dwTzF4dVhHNXlaWFIxY200Z1VUdGNibHh1ZlNrN1hHNGlYWDA9IiwiLyoqXG4gKiBSb290IHJlZmVyZW5jZSBmb3IgaWZyYW1lcy5cbiAqL1xuXG52YXIgcm9vdDtcbmlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykgeyAvLyBCcm93c2VyIHdpbmRvd1xuICByb290ID0gd2luZG93O1xufSBlbHNlIGlmICh0eXBlb2Ygc2VsZiAhPT0gJ3VuZGVmaW5lZCcpIHsgLy8gV2ViIFdvcmtlclxuICByb290ID0gc2VsZjtcbn0gZWxzZSB7IC8vIE90aGVyIGVudmlyb25tZW50c1xuICBjb25zb2xlLndhcm4oXCJVc2luZyBicm93c2VyLW9ubHkgdmVyc2lvbiBvZiBzdXBlcmFnZW50IGluIG5vbi1icm93c2VyIGVudmlyb25tZW50XCIpO1xuICByb290ID0gdGhpcztcbn1cblxudmFyIEVtaXR0ZXIgPSByZXF1aXJlKCdlbWl0dGVyJyk7XG52YXIgcmVxdWVzdEJhc2UgPSByZXF1aXJlKCcuL3JlcXVlc3QtYmFzZScpO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9pcy1vYmplY3QnKTtcblxuLyoqXG4gKiBOb29wLlxuICovXG5cbmZ1bmN0aW9uIG5vb3AoKXt9O1xuXG4vKipcbiAqIEV4cG9zZSBgcmVxdWVzdGAuXG4gKi9cblxudmFyIHJlcXVlc3QgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vcmVxdWVzdCcpLmJpbmQobnVsbCwgUmVxdWVzdCk7XG5cbi8qKlxuICogRGV0ZXJtaW5lIFhIUi5cbiAqL1xuXG5yZXF1ZXN0LmdldFhIUiA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHJvb3QuWE1MSHR0cFJlcXVlc3RcbiAgICAgICYmICghcm9vdC5sb2NhdGlvbiB8fCAnZmlsZTonICE9IHJvb3QubG9jYXRpb24ucHJvdG9jb2xcbiAgICAgICAgICB8fCAhcm9vdC5BY3RpdmVYT2JqZWN0KSkge1xuICAgIHJldHVybiBuZXcgWE1MSHR0cFJlcXVlc3Q7XG4gIH0gZWxzZSB7XG4gICAgdHJ5IHsgcmV0dXJuIG5ldyBBY3RpdmVYT2JqZWN0KCdNaWNyb3NvZnQuWE1MSFRUUCcpOyB9IGNhdGNoKGUpIHt9XG4gICAgdHJ5IHsgcmV0dXJuIG5ldyBBY3RpdmVYT2JqZWN0KCdNc3htbDIuWE1MSFRUUC42LjAnKTsgfSBjYXRjaChlKSB7fVxuICAgIHRyeSB7IHJldHVybiBuZXcgQWN0aXZlWE9iamVjdCgnTXN4bWwyLlhNTEhUVFAuMy4wJyk7IH0gY2F0Y2goZSkge31cbiAgICB0cnkgeyByZXR1cm4gbmV3IEFjdGl2ZVhPYmplY3QoJ01zeG1sMi5YTUxIVFRQJyk7IH0gY2F0Y2goZSkge31cbiAgfVxuICB0aHJvdyBFcnJvcihcIkJyb3dzZXItb25seSB2ZXJpc29uIG9mIHN1cGVyYWdlbnQgY291bGQgbm90IGZpbmQgWEhSXCIpO1xufTtcblxuLyoqXG4gKiBSZW1vdmVzIGxlYWRpbmcgYW5kIHRyYWlsaW5nIHdoaXRlc3BhY2UsIGFkZGVkIHRvIHN1cHBvcnQgSUUuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHNcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbnZhciB0cmltID0gJycudHJpbVxuICA/IGZ1bmN0aW9uKHMpIHsgcmV0dXJuIHMudHJpbSgpOyB9XG4gIDogZnVuY3Rpb24ocykgeyByZXR1cm4gcy5yZXBsYWNlKC8oXlxccyp8XFxzKiQpL2csICcnKTsgfTtcblxuLyoqXG4gKiBTZXJpYWxpemUgdGhlIGdpdmVuIGBvYmpgLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHNlcmlhbGl6ZShvYmopIHtcbiAgaWYgKCFpc09iamVjdChvYmopKSByZXR1cm4gb2JqO1xuICB2YXIgcGFpcnMgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgIHB1c2hFbmNvZGVkS2V5VmFsdWVQYWlyKHBhaXJzLCBrZXksIG9ialtrZXldKTtcbiAgfVxuICByZXR1cm4gcGFpcnMuam9pbignJicpO1xufVxuXG4vKipcbiAqIEhlbHBzICdzZXJpYWxpemUnIHdpdGggc2VyaWFsaXppbmcgYXJyYXlzLlxuICogTXV0YXRlcyB0aGUgcGFpcnMgYXJyYXkuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gcGFpcnNcbiAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcbiAqIEBwYXJhbSB7TWl4ZWR9IHZhbFxuICovXG5cbmZ1bmN0aW9uIHB1c2hFbmNvZGVkS2V5VmFsdWVQYWlyKHBhaXJzLCBrZXksIHZhbCkge1xuICBpZiAodmFsICE9IG51bGwpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWwpKSB7XG4gICAgICB2YWwuZm9yRWFjaChmdW5jdGlvbih2KSB7XG4gICAgICAgIHB1c2hFbmNvZGVkS2V5VmFsdWVQYWlyKHBhaXJzLCBrZXksIHYpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChpc09iamVjdCh2YWwpKSB7XG4gICAgICBmb3IodmFyIHN1YmtleSBpbiB2YWwpIHtcbiAgICAgICAgcHVzaEVuY29kZWRLZXlWYWx1ZVBhaXIocGFpcnMsIGtleSArICdbJyArIHN1YmtleSArICddJywgdmFsW3N1YmtleV0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBwYWlycy5wdXNoKGVuY29kZVVSSUNvbXBvbmVudChrZXkpXG4gICAgICAgICsgJz0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHZhbCkpO1xuICAgIH1cbiAgfSBlbHNlIGlmICh2YWwgPT09IG51bGwpIHtcbiAgICBwYWlycy5wdXNoKGVuY29kZVVSSUNvbXBvbmVudChrZXkpKTtcbiAgfVxufVxuXG4vKipcbiAqIEV4cG9zZSBzZXJpYWxpemF0aW9uIG1ldGhvZC5cbiAqL1xuXG4gcmVxdWVzdC5zZXJpYWxpemVPYmplY3QgPSBzZXJpYWxpemU7XG5cbiAvKipcbiAgKiBQYXJzZSB0aGUgZ2l2ZW4geC13d3ctZm9ybS11cmxlbmNvZGVkIGBzdHJgLlxuICAqXG4gICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICAqIEByZXR1cm4ge09iamVjdH1cbiAgKiBAYXBpIHByaXZhdGVcbiAgKi9cblxuZnVuY3Rpb24gcGFyc2VTdHJpbmcoc3RyKSB7XG4gIHZhciBvYmogPSB7fTtcbiAgdmFyIHBhaXJzID0gc3RyLnNwbGl0KCcmJyk7XG4gIHZhciBwYWlyO1xuICB2YXIgcG9zO1xuXG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBwYWlycy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgIHBhaXIgPSBwYWlyc1tpXTtcbiAgICBwb3MgPSBwYWlyLmluZGV4T2YoJz0nKTtcbiAgICBpZiAocG9zID09IC0xKSB7XG4gICAgICBvYmpbZGVjb2RlVVJJQ29tcG9uZW50KHBhaXIpXSA9ICcnO1xuICAgIH0gZWxzZSB7XG4gICAgICBvYmpbZGVjb2RlVVJJQ29tcG9uZW50KHBhaXIuc2xpY2UoMCwgcG9zKSldID1cbiAgICAgICAgZGVjb2RlVVJJQ29tcG9uZW50KHBhaXIuc2xpY2UocG9zICsgMSkpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvYmo7XG59XG5cbi8qKlxuICogRXhwb3NlIHBhcnNlci5cbiAqL1xuXG5yZXF1ZXN0LnBhcnNlU3RyaW5nID0gcGFyc2VTdHJpbmc7XG5cbi8qKlxuICogRGVmYXVsdCBNSU1FIHR5cGUgbWFwLlxuICpcbiAqICAgICBzdXBlcmFnZW50LnR5cGVzLnhtbCA9ICdhcHBsaWNhdGlvbi94bWwnO1xuICpcbiAqL1xuXG5yZXF1ZXN0LnR5cGVzID0ge1xuICBodG1sOiAndGV4dC9odG1sJyxcbiAganNvbjogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICB4bWw6ICdhcHBsaWNhdGlvbi94bWwnLFxuICB1cmxlbmNvZGVkOiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyxcbiAgJ2Zvcm0nOiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyxcbiAgJ2Zvcm0tZGF0YSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnXG59O1xuXG4vKipcbiAqIERlZmF1bHQgc2VyaWFsaXphdGlvbiBtYXAuXG4gKlxuICogICAgIHN1cGVyYWdlbnQuc2VyaWFsaXplWydhcHBsaWNhdGlvbi94bWwnXSA9IGZ1bmN0aW9uKG9iail7XG4gKiAgICAgICByZXR1cm4gJ2dlbmVyYXRlZCB4bWwgaGVyZSc7XG4gKiAgICAgfTtcbiAqXG4gKi9cblxuIHJlcXVlc3Quc2VyaWFsaXplID0ge1xuICAgJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCc6IHNlcmlhbGl6ZSxcbiAgICdhcHBsaWNhdGlvbi9qc29uJzogSlNPTi5zdHJpbmdpZnlcbiB9O1xuXG4gLyoqXG4gICogRGVmYXVsdCBwYXJzZXJzLlxuICAqXG4gICogICAgIHN1cGVyYWdlbnQucGFyc2VbJ2FwcGxpY2F0aW9uL3htbCddID0gZnVuY3Rpb24oc3RyKXtcbiAgKiAgICAgICByZXR1cm4geyBvYmplY3QgcGFyc2VkIGZyb20gc3RyIH07XG4gICogICAgIH07XG4gICpcbiAgKi9cblxucmVxdWVzdC5wYXJzZSA9IHtcbiAgJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCc6IHBhcnNlU3RyaW5nLFxuICAnYXBwbGljYXRpb24vanNvbic6IEpTT04ucGFyc2Vcbn07XG5cbi8qKlxuICogUGFyc2UgdGhlIGdpdmVuIGhlYWRlciBgc3RyYCBpbnRvXG4gKiBhbiBvYmplY3QgY29udGFpbmluZyB0aGUgbWFwcGVkIGZpZWxkcy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBwYXJzZUhlYWRlcihzdHIpIHtcbiAgdmFyIGxpbmVzID0gc3RyLnNwbGl0KC9cXHI/XFxuLyk7XG4gIHZhciBmaWVsZHMgPSB7fTtcbiAgdmFyIGluZGV4O1xuICB2YXIgbGluZTtcbiAgdmFyIGZpZWxkO1xuICB2YXIgdmFsO1xuXG4gIGxpbmVzLnBvcCgpOyAvLyB0cmFpbGluZyBDUkxGXG5cbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGxpbmVzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgbGluZSA9IGxpbmVzW2ldO1xuICAgIGluZGV4ID0gbGluZS5pbmRleE9mKCc6Jyk7XG4gICAgZmllbGQgPSBsaW5lLnNsaWNlKDAsIGluZGV4KS50b0xvd2VyQ2FzZSgpO1xuICAgIHZhbCA9IHRyaW0obGluZS5zbGljZShpbmRleCArIDEpKTtcbiAgICBmaWVsZHNbZmllbGRdID0gdmFsO1xuICB9XG5cbiAgcmV0dXJuIGZpZWxkcztcbn1cblxuLyoqXG4gKiBDaGVjayBpZiBgbWltZWAgaXMganNvbiBvciBoYXMgK2pzb24gc3RydWN0dXJlZCBzeW50YXggc3VmZml4LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtaW1lXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gaXNKU09OKG1pbWUpIHtcbiAgcmV0dXJuIC9bXFwvK11qc29uXFxiLy50ZXN0KG1pbWUpO1xufVxuXG4vKipcbiAqIFJldHVybiB0aGUgbWltZSB0eXBlIGZvciB0aGUgZ2l2ZW4gYHN0cmAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gdHlwZShzdHIpe1xuICByZXR1cm4gc3RyLnNwbGl0KC8gKjsgKi8pLnNoaWZ0KCk7XG59O1xuXG4vKipcbiAqIFJldHVybiBoZWFkZXIgZmllbGQgcGFyYW1ldGVycy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBwYXJhbXMoc3RyKXtcbiAgcmV0dXJuIHN0ci5zcGxpdCgvICo7ICovKS5yZWR1Y2UoZnVuY3Rpb24ob2JqLCBzdHIpe1xuICAgIHZhciBwYXJ0cyA9IHN0ci5zcGxpdCgvICo9ICovKSxcbiAgICAgICAga2V5ID0gcGFydHMuc2hpZnQoKSxcbiAgICAgICAgdmFsID0gcGFydHMuc2hpZnQoKTtcblxuICAgIGlmIChrZXkgJiYgdmFsKSBvYmpba2V5XSA9IHZhbDtcbiAgICByZXR1cm4gb2JqO1xuICB9LCB7fSk7XG59O1xuXG4vKipcbiAqIEluaXRpYWxpemUgYSBuZXcgYFJlc3BvbnNlYCB3aXRoIHRoZSBnaXZlbiBgeGhyYC5cbiAqXG4gKiAgLSBzZXQgZmxhZ3MgKC5vaywgLmVycm9yLCBldGMpXG4gKiAgLSBwYXJzZSBoZWFkZXJcbiAqXG4gKiBFeGFtcGxlczpcbiAqXG4gKiAgQWxpYXNpbmcgYHN1cGVyYWdlbnRgIGFzIGByZXF1ZXN0YCBpcyBuaWNlOlxuICpcbiAqICAgICAgcmVxdWVzdCA9IHN1cGVyYWdlbnQ7XG4gKlxuICogIFdlIGNhbiB1c2UgdGhlIHByb21pc2UtbGlrZSBBUEksIG9yIHBhc3MgY2FsbGJhY2tzOlxuICpcbiAqICAgICAgcmVxdWVzdC5nZXQoJy8nKS5lbmQoZnVuY3Rpb24ocmVzKXt9KTtcbiAqICAgICAgcmVxdWVzdC5nZXQoJy8nLCBmdW5jdGlvbihyZXMpe30pO1xuICpcbiAqICBTZW5kaW5nIGRhdGEgY2FuIGJlIGNoYWluZWQ6XG4gKlxuICogICAgICByZXF1ZXN0XG4gKiAgICAgICAgLnBvc3QoJy91c2VyJylcbiAqICAgICAgICAuc2VuZCh7IG5hbWU6ICd0aicgfSlcbiAqICAgICAgICAuZW5kKGZ1bmN0aW9uKHJlcyl7fSk7XG4gKlxuICogIE9yIHBhc3NlZCB0byBgLnNlbmQoKWA6XG4gKlxuICogICAgICByZXF1ZXN0XG4gKiAgICAgICAgLnBvc3QoJy91c2VyJylcbiAqICAgICAgICAuc2VuZCh7IG5hbWU6ICd0aicgfSwgZnVuY3Rpb24ocmVzKXt9KTtcbiAqXG4gKiAgT3IgcGFzc2VkIHRvIGAucG9zdCgpYDpcbiAqXG4gKiAgICAgIHJlcXVlc3RcbiAqICAgICAgICAucG9zdCgnL3VzZXInLCB7IG5hbWU6ICd0aicgfSlcbiAqICAgICAgICAuZW5kKGZ1bmN0aW9uKHJlcyl7fSk7XG4gKlxuICogT3IgZnVydGhlciByZWR1Y2VkIHRvIGEgc2luZ2xlIGNhbGwgZm9yIHNpbXBsZSBjYXNlczpcbiAqXG4gKiAgICAgIHJlcXVlc3RcbiAqICAgICAgICAucG9zdCgnL3VzZXInLCB7IG5hbWU6ICd0aicgfSwgZnVuY3Rpb24ocmVzKXt9KTtcbiAqXG4gKiBAcGFyYW0ge1hNTEhUVFBSZXF1ZXN0fSB4aHJcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBSZXNwb25zZShyZXEsIG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHRoaXMucmVxID0gcmVxO1xuICB0aGlzLnhociA9IHRoaXMucmVxLnhocjtcbiAgLy8gcmVzcG9uc2VUZXh0IGlzIGFjY2Vzc2libGUgb25seSBpZiByZXNwb25zZVR5cGUgaXMgJycgb3IgJ3RleHQnIGFuZCBvbiBvbGRlciBicm93c2Vyc1xuICB0aGlzLnRleHQgPSAoKHRoaXMucmVxLm1ldGhvZCAhPSdIRUFEJyAmJiAodGhpcy54aHIucmVzcG9uc2VUeXBlID09PSAnJyB8fCB0aGlzLnhoci5yZXNwb25zZVR5cGUgPT09ICd0ZXh0JykpIHx8IHR5cGVvZiB0aGlzLnhoci5yZXNwb25zZVR5cGUgPT09ICd1bmRlZmluZWQnKVxuICAgICA/IHRoaXMueGhyLnJlc3BvbnNlVGV4dFxuICAgICA6IG51bGw7XG4gIHRoaXMuc3RhdHVzVGV4dCA9IHRoaXMucmVxLnhoci5zdGF0dXNUZXh0O1xuICB0aGlzLl9zZXRTdGF0dXNQcm9wZXJ0aWVzKHRoaXMueGhyLnN0YXR1cyk7XG4gIHRoaXMuaGVhZGVyID0gdGhpcy5oZWFkZXJzID0gcGFyc2VIZWFkZXIodGhpcy54aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCkpO1xuICAvLyBnZXRBbGxSZXNwb25zZUhlYWRlcnMgc29tZXRpbWVzIGZhbHNlbHkgcmV0dXJucyBcIlwiIGZvciBDT1JTIHJlcXVlc3RzLCBidXRcbiAgLy8gZ2V0UmVzcG9uc2VIZWFkZXIgc3RpbGwgd29ya3MuIHNvIHdlIGdldCBjb250ZW50LXR5cGUgZXZlbiBpZiBnZXR0aW5nXG4gIC8vIG90aGVyIGhlYWRlcnMgZmFpbHMuXG4gIHRoaXMuaGVhZGVyWydjb250ZW50LXR5cGUnXSA9IHRoaXMueGhyLmdldFJlc3BvbnNlSGVhZGVyKCdjb250ZW50LXR5cGUnKTtcbiAgdGhpcy5fc2V0SGVhZGVyUHJvcGVydGllcyh0aGlzLmhlYWRlcik7XG4gIHRoaXMuYm9keSA9IHRoaXMucmVxLm1ldGhvZCAhPSAnSEVBRCdcbiAgICA/IHRoaXMuX3BhcnNlQm9keSh0aGlzLnRleHQgPyB0aGlzLnRleHQgOiB0aGlzLnhoci5yZXNwb25zZSlcbiAgICA6IG51bGw7XG59XG5cbi8qKlxuICogR2V0IGNhc2UtaW5zZW5zaXRpdmUgYGZpZWxkYCB2YWx1ZS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZmllbGRcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVzcG9uc2UucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKGZpZWxkKXtcbiAgcmV0dXJuIHRoaXMuaGVhZGVyW2ZpZWxkLnRvTG93ZXJDYXNlKCldO1xufTtcblxuLyoqXG4gKiBTZXQgaGVhZGVyIHJlbGF0ZWQgcHJvcGVydGllczpcbiAqXG4gKiAgIC0gYC50eXBlYCB0aGUgY29udGVudCB0eXBlIHdpdGhvdXQgcGFyYW1zXG4gKlxuICogQSByZXNwb25zZSBvZiBcIkNvbnRlbnQtVHlwZTogdGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOFwiXG4gKiB3aWxsIHByb3ZpZGUgeW91IHdpdGggYSBgLnR5cGVgIG9mIFwidGV4dC9wbGFpblwiLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBoZWFkZXJcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlc3BvbnNlLnByb3RvdHlwZS5fc2V0SGVhZGVyUHJvcGVydGllcyA9IGZ1bmN0aW9uKGhlYWRlcil7XG4gIC8vIGNvbnRlbnQtdHlwZVxuICB2YXIgY3QgPSB0aGlzLmhlYWRlclsnY29udGVudC10eXBlJ10gfHwgJyc7XG4gIHRoaXMudHlwZSA9IHR5cGUoY3QpO1xuXG4gIC8vIHBhcmFtc1xuICB2YXIgb2JqID0gcGFyYW1zKGN0KTtcbiAgZm9yICh2YXIga2V5IGluIG9iaikgdGhpc1trZXldID0gb2JqW2tleV07XG59O1xuXG4vKipcbiAqIFBhcnNlIHRoZSBnaXZlbiBib2R5IGBzdHJgLlxuICpcbiAqIFVzZWQgZm9yIGF1dG8tcGFyc2luZyBvZiBib2RpZXMuIFBhcnNlcnNcbiAqIGFyZSBkZWZpbmVkIG9uIHRoZSBgc3VwZXJhZ2VudC5wYXJzZWAgb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge01peGVkfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVzcG9uc2UucHJvdG90eXBlLl9wYXJzZUJvZHkgPSBmdW5jdGlvbihzdHIpe1xuICB2YXIgcGFyc2UgPSByZXF1ZXN0LnBhcnNlW3RoaXMudHlwZV07XG4gIGlmICghcGFyc2UgJiYgaXNKU09OKHRoaXMudHlwZSkpIHtcbiAgICBwYXJzZSA9IHJlcXVlc3QucGFyc2VbJ2FwcGxpY2F0aW9uL2pzb24nXTtcbiAgfVxuICByZXR1cm4gcGFyc2UgJiYgc3RyICYmIChzdHIubGVuZ3RoIHx8IHN0ciBpbnN0YW5jZW9mIE9iamVjdClcbiAgICA/IHBhcnNlKHN0cilcbiAgICA6IG51bGw7XG59O1xuXG4vKipcbiAqIFNldCBmbGFncyBzdWNoIGFzIGAub2tgIGJhc2VkIG9uIGBzdGF0dXNgLlxuICpcbiAqIEZvciBleGFtcGxlIGEgMnh4IHJlc3BvbnNlIHdpbGwgZ2l2ZSB5b3UgYSBgLm9rYCBvZiBfX3RydWVfX1xuICogd2hlcmVhcyA1eHggd2lsbCBiZSBfX2ZhbHNlX18gYW5kIGAuZXJyb3JgIHdpbGwgYmUgX190cnVlX18uIFRoZVxuICogYC5jbGllbnRFcnJvcmAgYW5kIGAuc2VydmVyRXJyb3JgIGFyZSBhbHNvIGF2YWlsYWJsZSB0byBiZSBtb3JlXG4gKiBzcGVjaWZpYywgYW5kIGAuc3RhdHVzVHlwZWAgaXMgdGhlIGNsYXNzIG9mIGVycm9yIHJhbmdpbmcgZnJvbSAxLi41XG4gKiBzb21ldGltZXMgdXNlZnVsIGZvciBtYXBwaW5nIHJlc3BvbmQgY29sb3JzIGV0Yy5cbiAqXG4gKiBcInN1Z2FyXCIgcHJvcGVydGllcyBhcmUgYWxzbyBkZWZpbmVkIGZvciBjb21tb24gY2FzZXMuIEN1cnJlbnRseSBwcm92aWRpbmc6XG4gKlxuICogICAtIC5ub0NvbnRlbnRcbiAqICAgLSAuYmFkUmVxdWVzdFxuICogICAtIC51bmF1dGhvcml6ZWRcbiAqICAgLSAubm90QWNjZXB0YWJsZVxuICogICAtIC5ub3RGb3VuZFxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSBzdGF0dXNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlc3BvbnNlLnByb3RvdHlwZS5fc2V0U3RhdHVzUHJvcGVydGllcyA9IGZ1bmN0aW9uKHN0YXR1cyl7XG4gIC8vIGhhbmRsZSBJRTkgYnVnOiBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzEwMDQ2OTcyL21zaWUtcmV0dXJucy1zdGF0dXMtY29kZS1vZi0xMjIzLWZvci1hamF4LXJlcXVlc3RcbiAgaWYgKHN0YXR1cyA9PT0gMTIyMykge1xuICAgIHN0YXR1cyA9IDIwNDtcbiAgfVxuXG4gIHZhciB0eXBlID0gc3RhdHVzIC8gMTAwIHwgMDtcblxuICAvLyBzdGF0dXMgLyBjbGFzc1xuICB0aGlzLnN0YXR1cyA9IHRoaXMuc3RhdHVzQ29kZSA9IHN0YXR1cztcbiAgdGhpcy5zdGF0dXNUeXBlID0gdHlwZTtcblxuICAvLyBiYXNpY3NcbiAgdGhpcy5pbmZvID0gMSA9PSB0eXBlO1xuICB0aGlzLm9rID0gMiA9PSB0eXBlO1xuICB0aGlzLmNsaWVudEVycm9yID0gNCA9PSB0eXBlO1xuICB0aGlzLnNlcnZlckVycm9yID0gNSA9PSB0eXBlO1xuICB0aGlzLmVycm9yID0gKDQgPT0gdHlwZSB8fCA1ID09IHR5cGUpXG4gICAgPyB0aGlzLnRvRXJyb3IoKVxuICAgIDogZmFsc2U7XG5cbiAgLy8gc3VnYXJcbiAgdGhpcy5hY2NlcHRlZCA9IDIwMiA9PSBzdGF0dXM7XG4gIHRoaXMubm9Db250ZW50ID0gMjA0ID09IHN0YXR1cztcbiAgdGhpcy5iYWRSZXF1ZXN0ID0gNDAwID09IHN0YXR1cztcbiAgdGhpcy51bmF1dGhvcml6ZWQgPSA0MDEgPT0gc3RhdHVzO1xuICB0aGlzLm5vdEFjY2VwdGFibGUgPSA0MDYgPT0gc3RhdHVzO1xuICB0aGlzLm5vdEZvdW5kID0gNDA0ID09IHN0YXR1cztcbiAgdGhpcy5mb3JiaWRkZW4gPSA0MDMgPT0gc3RhdHVzO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gYW4gYEVycm9yYCByZXByZXNlbnRhdGl2ZSBvZiB0aGlzIHJlc3BvbnNlLlxuICpcbiAqIEByZXR1cm4ge0Vycm9yfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXNwb25zZS5wcm90b3R5cGUudG9FcnJvciA9IGZ1bmN0aW9uKCl7XG4gIHZhciByZXEgPSB0aGlzLnJlcTtcbiAgdmFyIG1ldGhvZCA9IHJlcS5tZXRob2Q7XG4gIHZhciB1cmwgPSByZXEudXJsO1xuXG4gIHZhciBtc2cgPSAnY2Fubm90ICcgKyBtZXRob2QgKyAnICcgKyB1cmwgKyAnICgnICsgdGhpcy5zdGF0dXMgKyAnKSc7XG4gIHZhciBlcnIgPSBuZXcgRXJyb3IobXNnKTtcbiAgZXJyLnN0YXR1cyA9IHRoaXMuc3RhdHVzO1xuICBlcnIubWV0aG9kID0gbWV0aG9kO1xuICBlcnIudXJsID0gdXJsO1xuXG4gIHJldHVybiBlcnI7XG59O1xuXG4vKipcbiAqIEV4cG9zZSBgUmVzcG9uc2VgLlxuICovXG5cbnJlcXVlc3QuUmVzcG9uc2UgPSBSZXNwb25zZTtcblxuLyoqXG4gKiBJbml0aWFsaXplIGEgbmV3IGBSZXF1ZXN0YCB3aXRoIHRoZSBnaXZlbiBgbWV0aG9kYCBhbmQgYHVybGAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZFxuICogQHBhcmFtIHtTdHJpbmd9IHVybFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBSZXF1ZXN0KG1ldGhvZCwgdXJsKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdGhpcy5fcXVlcnkgPSB0aGlzLl9xdWVyeSB8fCBbXTtcbiAgdGhpcy5tZXRob2QgPSBtZXRob2Q7XG4gIHRoaXMudXJsID0gdXJsO1xuICB0aGlzLmhlYWRlciA9IHt9OyAvLyBwcmVzZXJ2ZXMgaGVhZGVyIG5hbWUgY2FzZVxuICB0aGlzLl9oZWFkZXIgPSB7fTsgLy8gY29lcmNlcyBoZWFkZXIgbmFtZXMgdG8gbG93ZXJjYXNlXG4gIHRoaXMub24oJ2VuZCcsIGZ1bmN0aW9uKCl7XG4gICAgdmFyIGVyciA9IG51bGw7XG4gICAgdmFyIHJlcyA9IG51bGw7XG5cbiAgICB0cnkge1xuICAgICAgcmVzID0gbmV3IFJlc3BvbnNlKHNlbGYpO1xuICAgIH0gY2F0Y2goZSkge1xuICAgICAgZXJyID0gbmV3IEVycm9yKCdQYXJzZXIgaXMgdW5hYmxlIHRvIHBhcnNlIHRoZSByZXNwb25zZScpO1xuICAgICAgZXJyLnBhcnNlID0gdHJ1ZTtcbiAgICAgIGVyci5vcmlnaW5hbCA9IGU7XG4gICAgICAvLyBpc3N1ZSAjNjc1OiByZXR1cm4gdGhlIHJhdyByZXNwb25zZSBpZiB0aGUgcmVzcG9uc2UgcGFyc2luZyBmYWlsc1xuICAgICAgZXJyLnJhd1Jlc3BvbnNlID0gc2VsZi54aHIgJiYgc2VsZi54aHIucmVzcG9uc2VUZXh0ID8gc2VsZi54aHIucmVzcG9uc2VUZXh0IDogbnVsbDtcbiAgICAgIC8vIGlzc3VlICM4NzY6IHJldHVybiB0aGUgaHR0cCBzdGF0dXMgY29kZSBpZiB0aGUgcmVzcG9uc2UgcGFyc2luZyBmYWlsc1xuICAgICAgZXJyLnN0YXR1c0NvZGUgPSBzZWxmLnhociAmJiBzZWxmLnhoci5zdGF0dXMgPyBzZWxmLnhoci5zdGF0dXMgOiBudWxsO1xuICAgICAgcmV0dXJuIHNlbGYuY2FsbGJhY2soZXJyKTtcbiAgICB9XG5cbiAgICBzZWxmLmVtaXQoJ3Jlc3BvbnNlJywgcmVzKTtcblxuICAgIHZhciBuZXdfZXJyO1xuICAgIHRyeSB7XG4gICAgICBpZiAocmVzLnN0YXR1cyA8IDIwMCB8fCByZXMuc3RhdHVzID49IDMwMCkge1xuICAgICAgICBuZXdfZXJyID0gbmV3IEVycm9yKHJlcy5zdGF0dXNUZXh0IHx8ICdVbnN1Y2Nlc3NmdWwgSFRUUCByZXNwb25zZScpO1xuICAgICAgICBuZXdfZXJyLm9yaWdpbmFsID0gZXJyO1xuICAgICAgICBuZXdfZXJyLnJlc3BvbnNlID0gcmVzO1xuICAgICAgICBuZXdfZXJyLnN0YXR1cyA9IHJlcy5zdGF0dXM7XG4gICAgICB9XG4gICAgfSBjYXRjaChlKSB7XG4gICAgICBuZXdfZXJyID0gZTsgLy8gIzk4NSB0b3VjaGluZyByZXMgbWF5IGNhdXNlIElOVkFMSURfU1RBVEVfRVJSIG9uIG9sZCBBbmRyb2lkXG4gICAgfVxuXG4gICAgLy8gIzEwMDAgZG9uJ3QgY2F0Y2ggZXJyb3JzIGZyb20gdGhlIGNhbGxiYWNrIHRvIGF2b2lkIGRvdWJsZSBjYWxsaW5nIGl0XG4gICAgaWYgKG5ld19lcnIpIHtcbiAgICAgIHNlbGYuY2FsbGJhY2sobmV3X2VyciwgcmVzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2VsZi5jYWxsYmFjayhudWxsLCByZXMpO1xuICAgIH1cbiAgfSk7XG59XG5cbi8qKlxuICogTWl4aW4gYEVtaXR0ZXJgIGFuZCBgcmVxdWVzdEJhc2VgLlxuICovXG5cbkVtaXR0ZXIoUmVxdWVzdC5wcm90b3R5cGUpO1xuZm9yICh2YXIga2V5IGluIHJlcXVlc3RCYXNlKSB7XG4gIFJlcXVlc3QucHJvdG90eXBlW2tleV0gPSByZXF1ZXN0QmFzZVtrZXldO1xufVxuXG4vKipcbiAqIFNldCBDb250ZW50LVR5cGUgdG8gYHR5cGVgLCBtYXBwaW5nIHZhbHVlcyBmcm9tIGByZXF1ZXN0LnR5cGVzYC5cbiAqXG4gKiBFeGFtcGxlczpcbiAqXG4gKiAgICAgIHN1cGVyYWdlbnQudHlwZXMueG1sID0gJ2FwcGxpY2F0aW9uL3htbCc7XG4gKlxuICogICAgICByZXF1ZXN0LnBvc3QoJy8nKVxuICogICAgICAgIC50eXBlKCd4bWwnKVxuICogICAgICAgIC5zZW5kKHhtbHN0cmluZylcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiAgICAgIHJlcXVlc3QucG9zdCgnLycpXG4gKiAgICAgICAgLnR5cGUoJ2FwcGxpY2F0aW9uL3htbCcpXG4gKiAgICAgICAgLnNlbmQoeG1sc3RyaW5nKVxuICogICAgICAgIC5lbmQoY2FsbGJhY2spO1xuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUudHlwZSA9IGZ1bmN0aW9uKHR5cGUpe1xuICB0aGlzLnNldCgnQ29udGVudC1UeXBlJywgcmVxdWVzdC50eXBlc1t0eXBlXSB8fCB0eXBlKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldCByZXNwb25zZVR5cGUgdG8gYHZhbGAuIFByZXNlbnRseSB2YWxpZCByZXNwb25zZVR5cGVzIGFyZSAnYmxvYicgYW5kXG4gKiAnYXJyYXlidWZmZXInLlxuICpcbiAqIEV4YW1wbGVzOlxuICpcbiAqICAgICAgcmVxLmdldCgnLycpXG4gKiAgICAgICAgLnJlc3BvbnNlVHlwZSgnYmxvYicpXG4gKiAgICAgICAgLmVuZChjYWxsYmFjayk7XG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHZhbFxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLnJlc3BvbnNlVHlwZSA9IGZ1bmN0aW9uKHZhbCl7XG4gIHRoaXMuX3Jlc3BvbnNlVHlwZSA9IHZhbDtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldCBBY2NlcHQgdG8gYHR5cGVgLCBtYXBwaW5nIHZhbHVlcyBmcm9tIGByZXF1ZXN0LnR5cGVzYC5cbiAqXG4gKiBFeGFtcGxlczpcbiAqXG4gKiAgICAgIHN1cGVyYWdlbnQudHlwZXMuanNvbiA9ICdhcHBsaWNhdGlvbi9qc29uJztcbiAqXG4gKiAgICAgIHJlcXVlc3QuZ2V0KCcvYWdlbnQnKVxuICogICAgICAgIC5hY2NlcHQoJ2pzb24nKVxuICogICAgICAgIC5lbmQoY2FsbGJhY2spO1xuICpcbiAqICAgICAgcmVxdWVzdC5nZXQoJy9hZ2VudCcpXG4gKiAgICAgICAgLmFjY2VwdCgnYXBwbGljYXRpb24vanNvbicpXG4gKiAgICAgICAgLmVuZChjYWxsYmFjayk7XG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGFjY2VwdFxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmFjY2VwdCA9IGZ1bmN0aW9uKHR5cGUpe1xuICB0aGlzLnNldCgnQWNjZXB0JywgcmVxdWVzdC50eXBlc1t0eXBlXSB8fCB0eXBlKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldCBBdXRob3JpemF0aW9uIGZpZWxkIHZhbHVlIHdpdGggYHVzZXJgIGFuZCBgcGFzc2AuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHVzZXJcbiAqIEBwYXJhbSB7U3RyaW5nfSBwYXNzXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyB3aXRoICd0eXBlJyBwcm9wZXJ0eSAnYXV0bycgb3IgJ2Jhc2ljJyAoZGVmYXVsdCAnYmFzaWMnKVxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmF1dGggPSBmdW5jdGlvbih1c2VyLCBwYXNzLCBvcHRpb25zKXtcbiAgaWYgKCFvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IHtcbiAgICAgIHR5cGU6ICdiYXNpYydcbiAgICB9XG4gIH1cblxuICBzd2l0Y2ggKG9wdGlvbnMudHlwZSkge1xuICAgIGNhc2UgJ2Jhc2ljJzpcbiAgICAgIHZhciBzdHIgPSBidG9hKHVzZXIgKyAnOicgKyBwYXNzKTtcbiAgICAgIHRoaXMuc2V0KCdBdXRob3JpemF0aW9uJywgJ0Jhc2ljICcgKyBzdHIpO1xuICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnYXV0byc6XG4gICAgICB0aGlzLnVzZXJuYW1lID0gdXNlcjtcbiAgICAgIHRoaXMucGFzc3dvcmQgPSBwYXNzO1xuICAgIGJyZWFrO1xuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4qIEFkZCBxdWVyeS1zdHJpbmcgYHZhbGAuXG4qXG4qIEV4YW1wbGVzOlxuKlxuKiAgIHJlcXVlc3QuZ2V0KCcvc2hvZXMnKVxuKiAgICAgLnF1ZXJ5KCdzaXplPTEwJylcbiogICAgIC5xdWVyeSh7IGNvbG9yOiAnYmx1ZScgfSlcbipcbiogQHBhcmFtIHtPYmplY3R8U3RyaW5nfSB2YWxcbiogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4qIEBhcGkgcHVibGljXG4qL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5xdWVyeSA9IGZ1bmN0aW9uKHZhbCl7XG4gIGlmICgnc3RyaW5nJyAhPSB0eXBlb2YgdmFsKSB2YWwgPSBzZXJpYWxpemUodmFsKTtcbiAgaWYgKHZhbCkgdGhpcy5fcXVlcnkucHVzaCh2YWwpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogUXVldWUgdGhlIGdpdmVuIGBmaWxlYCBhcyBhbiBhdHRhY2htZW50IHRvIHRoZSBzcGVjaWZpZWQgYGZpZWxkYCxcbiAqIHdpdGggb3B0aW9uYWwgYGZpbGVuYW1lYC5cbiAqXG4gKiBgYGAganNcbiAqIHJlcXVlc3QucG9zdCgnL3VwbG9hZCcpXG4gKiAgIC5hdHRhY2goJ2NvbnRlbnQnLCBuZXcgQmxvYihbJzxhIGlkPVwiYVwiPjxiIGlkPVwiYlwiPmhleSE8L2I+PC9hPiddLCB7IHR5cGU6IFwidGV4dC9odG1sXCJ9KSlcbiAqICAgLmVuZChjYWxsYmFjayk7XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZmllbGRcbiAqIEBwYXJhbSB7QmxvYnxGaWxlfSBmaWxlXG4gKiBAcGFyYW0ge1N0cmluZ30gZmlsZW5hbWVcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5hdHRhY2ggPSBmdW5jdGlvbihmaWVsZCwgZmlsZSwgZmlsZW5hbWUpe1xuICB0aGlzLl9nZXRGb3JtRGF0YSgpLmFwcGVuZChmaWVsZCwgZmlsZSwgZmlsZW5hbWUgfHwgZmlsZS5uYW1lKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5fZ2V0Rm9ybURhdGEgPSBmdW5jdGlvbigpe1xuICBpZiAoIXRoaXMuX2Zvcm1EYXRhKSB7XG4gICAgdGhpcy5fZm9ybURhdGEgPSBuZXcgcm9vdC5Gb3JtRGF0YSgpO1xuICB9XG4gIHJldHVybiB0aGlzLl9mb3JtRGF0YTtcbn07XG5cbi8qKlxuICogSW52b2tlIHRoZSBjYWxsYmFjayB3aXRoIGBlcnJgIGFuZCBgcmVzYFxuICogYW5kIGhhbmRsZSBhcml0eSBjaGVjay5cbiAqXG4gKiBAcGFyYW0ge0Vycm9yfSBlcnJcbiAqIEBwYXJhbSB7UmVzcG9uc2V9IHJlc1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuY2FsbGJhY2sgPSBmdW5jdGlvbihlcnIsIHJlcyl7XG4gIHZhciBmbiA9IHRoaXMuX2NhbGxiYWNrO1xuICB0aGlzLmNsZWFyVGltZW91dCgpO1xuICBmbihlcnIsIHJlcyk7XG59O1xuXG4vKipcbiAqIEludm9rZSBjYWxsYmFjayB3aXRoIHgtZG9tYWluIGVycm9yLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmNyb3NzRG9tYWluRXJyb3IgPSBmdW5jdGlvbigpe1xuICB2YXIgZXJyID0gbmV3IEVycm9yKCdSZXF1ZXN0IGhhcyBiZWVuIHRlcm1pbmF0ZWRcXG5Qb3NzaWJsZSBjYXVzZXM6IHRoZSBuZXR3b3JrIGlzIG9mZmxpbmUsIE9yaWdpbiBpcyBub3QgYWxsb3dlZCBieSBBY2Nlc3MtQ29udHJvbC1BbGxvdy1PcmlnaW4sIHRoZSBwYWdlIGlzIGJlaW5nIHVubG9hZGVkLCBldGMuJyk7XG4gIGVyci5jcm9zc0RvbWFpbiA9IHRydWU7XG5cbiAgZXJyLnN0YXR1cyA9IHRoaXMuc3RhdHVzO1xuICBlcnIubWV0aG9kID0gdGhpcy5tZXRob2Q7XG4gIGVyci51cmwgPSB0aGlzLnVybDtcblxuICB0aGlzLmNhbGxiYWNrKGVycik7XG59O1xuXG4vKipcbiAqIEludm9rZSBjYWxsYmFjayB3aXRoIHRpbWVvdXQgZXJyb3IuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuX3RpbWVvdXRFcnJvciA9IGZ1bmN0aW9uKCl7XG4gIHZhciB0aW1lb3V0ID0gdGhpcy5fdGltZW91dDtcbiAgdmFyIGVyciA9IG5ldyBFcnJvcigndGltZW91dCBvZiAnICsgdGltZW91dCArICdtcyBleGNlZWRlZCcpO1xuICBlcnIudGltZW91dCA9IHRpbWVvdXQ7XG4gIHRoaXMuY2FsbGJhY2soZXJyKTtcbn07XG5cbi8qKlxuICogQ29tcG9zZSBxdWVyeXN0cmluZyB0byBhcHBlbmQgdG8gcmVxLnVybFxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlcXVlc3QucHJvdG90eXBlLl9hcHBlbmRRdWVyeVN0cmluZyA9IGZ1bmN0aW9uKCl7XG4gIHZhciBxdWVyeSA9IHRoaXMuX3F1ZXJ5LmpvaW4oJyYnKTtcbiAgaWYgKHF1ZXJ5KSB7XG4gICAgdGhpcy51cmwgKz0gfnRoaXMudXJsLmluZGV4T2YoJz8nKVxuICAgICAgPyAnJicgKyBxdWVyeVxuICAgICAgOiAnPycgKyBxdWVyeTtcbiAgfVxufTtcblxuLyoqXG4gKiBJbml0aWF0ZSByZXF1ZXN0LCBpbnZva2luZyBjYWxsYmFjayBgZm4ocmVzKWBcbiAqIHdpdGggYW4gaW5zdGFuY2VvZiBgUmVzcG9uc2VgLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24oZm4pe1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHZhciB4aHIgPSB0aGlzLnhociA9IHJlcXVlc3QuZ2V0WEhSKCk7XG4gIHZhciB0aW1lb3V0ID0gdGhpcy5fdGltZW91dDtcbiAgdmFyIGRhdGEgPSB0aGlzLl9mb3JtRGF0YSB8fCB0aGlzLl9kYXRhO1xuXG4gIC8vIHN0b3JlIGNhbGxiYWNrXG4gIHRoaXMuX2NhbGxiYWNrID0gZm4gfHwgbm9vcDtcblxuICAvLyBzdGF0ZSBjaGFuZ2VcbiAgeGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCl7XG4gICAgaWYgKDQgIT0geGhyLnJlYWR5U3RhdGUpIHJldHVybjtcblxuICAgIC8vIEluIElFOSwgcmVhZHMgdG8gYW55IHByb3BlcnR5IChlLmcuIHN0YXR1cykgb2ZmIG9mIGFuIGFib3J0ZWQgWEhSIHdpbGxcbiAgICAvLyByZXN1bHQgaW4gdGhlIGVycm9yIFwiQ291bGQgbm90IGNvbXBsZXRlIHRoZSBvcGVyYXRpb24gZHVlIHRvIGVycm9yIGMwMGMwMjNmXCJcbiAgICB2YXIgc3RhdHVzO1xuICAgIHRyeSB7IHN0YXR1cyA9IHhoci5zdGF0dXMgfSBjYXRjaChlKSB7IHN0YXR1cyA9IDA7IH1cblxuICAgIGlmICgwID09IHN0YXR1cykge1xuICAgICAgaWYgKHNlbGYudGltZWRvdXQpIHJldHVybiBzZWxmLl90aW1lb3V0RXJyb3IoKTtcbiAgICAgIGlmIChzZWxmLl9hYm9ydGVkKSByZXR1cm47XG4gICAgICByZXR1cm4gc2VsZi5jcm9zc0RvbWFpbkVycm9yKCk7XG4gICAgfVxuICAgIHNlbGYuZW1pdCgnZW5kJyk7XG4gIH07XG5cbiAgLy8gcHJvZ3Jlc3NcbiAgdmFyIGhhbmRsZVByb2dyZXNzID0gZnVuY3Rpb24oZSl7XG4gICAgaWYgKGUudG90YWwgPiAwKSB7XG4gICAgICBlLnBlcmNlbnQgPSBlLmxvYWRlZCAvIGUudG90YWwgKiAxMDA7XG4gICAgfVxuICAgIGUuZGlyZWN0aW9uID0gJ2Rvd25sb2FkJztcbiAgICBzZWxmLmVtaXQoJ3Byb2dyZXNzJywgZSk7XG4gIH07XG4gIGlmICh0aGlzLmhhc0xpc3RlbmVycygncHJvZ3Jlc3MnKSkge1xuICAgIHhoci5vbnByb2dyZXNzID0gaGFuZGxlUHJvZ3Jlc3M7XG4gIH1cbiAgdHJ5IHtcbiAgICBpZiAoeGhyLnVwbG9hZCAmJiB0aGlzLmhhc0xpc3RlbmVycygncHJvZ3Jlc3MnKSkge1xuICAgICAgeGhyLnVwbG9hZC5vbnByb2dyZXNzID0gaGFuZGxlUHJvZ3Jlc3M7XG4gICAgfVxuICB9IGNhdGNoKGUpIHtcbiAgICAvLyBBY2Nlc3NpbmcgeGhyLnVwbG9hZCBmYWlscyBpbiBJRSBmcm9tIGEgd2ViIHdvcmtlciwgc28ganVzdCBwcmV0ZW5kIGl0IGRvZXNuJ3QgZXhpc3QuXG4gICAgLy8gUmVwb3J0ZWQgaGVyZTpcbiAgICAvLyBodHRwczovL2Nvbm5lY3QubWljcm9zb2Z0LmNvbS9JRS9mZWVkYmFjay9kZXRhaWxzLzgzNzI0NS94bWxodHRwcmVxdWVzdC11cGxvYWQtdGhyb3dzLWludmFsaWQtYXJndW1lbnQtd2hlbi11c2VkLWZyb20td2ViLXdvcmtlci1jb250ZXh0XG4gIH1cblxuICAvLyB0aW1lb3V0XG4gIGlmICh0aW1lb3V0ICYmICF0aGlzLl90aW1lcikge1xuICAgIHRoaXMuX3RpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbigpe1xuICAgICAgc2VsZi50aW1lZG91dCA9IHRydWU7XG4gICAgICBzZWxmLmFib3J0KCk7XG4gICAgfSwgdGltZW91dCk7XG4gIH1cblxuICAvLyBxdWVyeXN0cmluZ1xuICB0aGlzLl9hcHBlbmRRdWVyeVN0cmluZygpO1xuXG4gIC8vIGluaXRpYXRlIHJlcXVlc3RcbiAgaWYgKHRoaXMudXNlcm5hbWUgJiYgdGhpcy5wYXNzd29yZCkge1xuICAgIHhoci5vcGVuKHRoaXMubWV0aG9kLCB0aGlzLnVybCwgdHJ1ZSwgdGhpcy51c2VybmFtZSwgdGhpcy5wYXNzd29yZCk7XG4gIH0gZWxzZSB7XG4gICAgeGhyLm9wZW4odGhpcy5tZXRob2QsIHRoaXMudXJsLCB0cnVlKTtcbiAgfVxuXG4gIC8vIENPUlNcbiAgaWYgKHRoaXMuX3dpdGhDcmVkZW50aWFscykgeGhyLndpdGhDcmVkZW50aWFscyA9IHRydWU7XG5cbiAgLy8gYm9keVxuICBpZiAoJ0dFVCcgIT0gdGhpcy5tZXRob2QgJiYgJ0hFQUQnICE9IHRoaXMubWV0aG9kICYmICdzdHJpbmcnICE9IHR5cGVvZiBkYXRhICYmICF0aGlzLl9pc0hvc3QoZGF0YSkpIHtcbiAgICAvLyBzZXJpYWxpemUgc3R1ZmZcbiAgICB2YXIgY29udGVudFR5cGUgPSB0aGlzLl9oZWFkZXJbJ2NvbnRlbnQtdHlwZSddO1xuICAgIHZhciBzZXJpYWxpemUgPSB0aGlzLl9zZXJpYWxpemVyIHx8IHJlcXVlc3Quc2VyaWFsaXplW2NvbnRlbnRUeXBlID8gY29udGVudFR5cGUuc3BsaXQoJzsnKVswXSA6ICcnXTtcbiAgICBpZiAoIXNlcmlhbGl6ZSAmJiBpc0pTT04oY29udGVudFR5cGUpKSBzZXJpYWxpemUgPSByZXF1ZXN0LnNlcmlhbGl6ZVsnYXBwbGljYXRpb24vanNvbiddO1xuICAgIGlmIChzZXJpYWxpemUpIGRhdGEgPSBzZXJpYWxpemUoZGF0YSk7XG4gIH1cblxuICAvLyBzZXQgaGVhZGVyIGZpZWxkc1xuICBmb3IgKHZhciBmaWVsZCBpbiB0aGlzLmhlYWRlcikge1xuICAgIGlmIChudWxsID09IHRoaXMuaGVhZGVyW2ZpZWxkXSkgY29udGludWU7XG4gICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoZmllbGQsIHRoaXMuaGVhZGVyW2ZpZWxkXSk7XG4gIH1cblxuICBpZiAodGhpcy5fcmVzcG9uc2VUeXBlKSB7XG4gICAgeGhyLnJlc3BvbnNlVHlwZSA9IHRoaXMuX3Jlc3BvbnNlVHlwZTtcbiAgfVxuXG4gIC8vIHNlbmQgc3R1ZmZcbiAgdGhpcy5lbWl0KCdyZXF1ZXN0JywgdGhpcyk7XG5cbiAgLy8gSUUxMSB4aHIuc2VuZCh1bmRlZmluZWQpIHNlbmRzICd1bmRlZmluZWQnIHN0cmluZyBhcyBQT1NUIHBheWxvYWQgKGluc3RlYWQgb2Ygbm90aGluZylcbiAgLy8gV2UgbmVlZCBudWxsIGhlcmUgaWYgZGF0YSBpcyB1bmRlZmluZWRcbiAgeGhyLnNlbmQodHlwZW9mIGRhdGEgIT09ICd1bmRlZmluZWQnID8gZGF0YSA6IG51bGwpO1xuICByZXR1cm4gdGhpcztcbn07XG5cblxuLyoqXG4gKiBFeHBvc2UgYFJlcXVlc3RgLlxuICovXG5cbnJlcXVlc3QuUmVxdWVzdCA9IFJlcXVlc3Q7XG5cbi8qKlxuICogR0VUIGB1cmxgIHdpdGggb3B0aW9uYWwgY2FsbGJhY2sgYGZuKHJlcylgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmxcbiAqIEBwYXJhbSB7TWl4ZWR8RnVuY3Rpb259IFtkYXRhXSBvciBmblxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2ZuXVxuICogQHJldHVybiB7UmVxdWVzdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxucmVxdWVzdC5nZXQgPSBmdW5jdGlvbih1cmwsIGRhdGEsIGZuKXtcbiAgdmFyIHJlcSA9IHJlcXVlc3QoJ0dFVCcsIHVybCk7XG4gIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiBkYXRhKSBmbiA9IGRhdGEsIGRhdGEgPSBudWxsO1xuICBpZiAoZGF0YSkgcmVxLnF1ZXJ5KGRhdGEpO1xuICBpZiAoZm4pIHJlcS5lbmQoZm4pO1xuICByZXR1cm4gcmVxO1xufTtcblxuLyoqXG4gKiBIRUFEIGB1cmxgIHdpdGggb3B0aW9uYWwgY2FsbGJhY2sgYGZuKHJlcylgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmxcbiAqIEBwYXJhbSB7TWl4ZWR8RnVuY3Rpb259IFtkYXRhXSBvciBmblxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2ZuXVxuICogQHJldHVybiB7UmVxdWVzdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxucmVxdWVzdC5oZWFkID0gZnVuY3Rpb24odXJsLCBkYXRhLCBmbil7XG4gIHZhciByZXEgPSByZXF1ZXN0KCdIRUFEJywgdXJsKTtcbiAgaWYgKCdmdW5jdGlvbicgPT0gdHlwZW9mIGRhdGEpIGZuID0gZGF0YSwgZGF0YSA9IG51bGw7XG4gIGlmIChkYXRhKSByZXEuc2VuZChkYXRhKTtcbiAgaWYgKGZuKSByZXEuZW5kKGZuKTtcbiAgcmV0dXJuIHJlcTtcbn07XG5cbi8qKlxuICogT1BUSU9OUyBxdWVyeSB0byBgdXJsYCB3aXRoIG9wdGlvbmFsIGNhbGxiYWNrIGBmbihyZXMpYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJsXG4gKiBAcGFyYW0ge01peGVkfEZ1bmN0aW9ufSBbZGF0YV0gb3IgZm5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtmbl1cbiAqIEByZXR1cm4ge1JlcXVlc3R9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbnJlcXVlc3Qub3B0aW9ucyA9IGZ1bmN0aW9uKHVybCwgZGF0YSwgZm4pe1xuICB2YXIgcmVxID0gcmVxdWVzdCgnT1BUSU9OUycsIHVybCk7XG4gIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiBkYXRhKSBmbiA9IGRhdGEsIGRhdGEgPSBudWxsO1xuICBpZiAoZGF0YSkgcmVxLnNlbmQoZGF0YSk7XG4gIGlmIChmbikgcmVxLmVuZChmbik7XG4gIHJldHVybiByZXE7XG59O1xuXG4vKipcbiAqIERFTEVURSBgdXJsYCB3aXRoIG9wdGlvbmFsIGNhbGxiYWNrIGBmbihyZXMpYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJsXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbZm5dXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBkZWwodXJsLCBmbil7XG4gIHZhciByZXEgPSByZXF1ZXN0KCdERUxFVEUnLCB1cmwpO1xuICBpZiAoZm4pIHJlcS5lbmQoZm4pO1xuICByZXR1cm4gcmVxO1xufTtcblxucmVxdWVzdFsnZGVsJ10gPSBkZWw7XG5yZXF1ZXN0WydkZWxldGUnXSA9IGRlbDtcblxuLyoqXG4gKiBQQVRDSCBgdXJsYCB3aXRoIG9wdGlvbmFsIGBkYXRhYCBhbmQgY2FsbGJhY2sgYGZuKHJlcylgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmxcbiAqIEBwYXJhbSB7TWl4ZWR9IFtkYXRhXVxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2ZuXVxuICogQHJldHVybiB7UmVxdWVzdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxucmVxdWVzdC5wYXRjaCA9IGZ1bmN0aW9uKHVybCwgZGF0YSwgZm4pe1xuICB2YXIgcmVxID0gcmVxdWVzdCgnUEFUQ0gnLCB1cmwpO1xuICBpZiAoJ2Z1bmN0aW9uJyA9PSB0eXBlb2YgZGF0YSkgZm4gPSBkYXRhLCBkYXRhID0gbnVsbDtcbiAgaWYgKGRhdGEpIHJlcS5zZW5kKGRhdGEpO1xuICBpZiAoZm4pIHJlcS5lbmQoZm4pO1xuICByZXR1cm4gcmVxO1xufTtcblxuLyoqXG4gKiBQT1NUIGB1cmxgIHdpdGggb3B0aW9uYWwgYGRhdGFgIGFuZCBjYWxsYmFjayBgZm4ocmVzKWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHVybFxuICogQHBhcmFtIHtNaXhlZH0gW2RhdGFdXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbZm5dXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5yZXF1ZXN0LnBvc3QgPSBmdW5jdGlvbih1cmwsIGRhdGEsIGZuKXtcbiAgdmFyIHJlcSA9IHJlcXVlc3QoJ1BPU1QnLCB1cmwpO1xuICBpZiAoJ2Z1bmN0aW9uJyA9PSB0eXBlb2YgZGF0YSkgZm4gPSBkYXRhLCBkYXRhID0gbnVsbDtcbiAgaWYgKGRhdGEpIHJlcS5zZW5kKGRhdGEpO1xuICBpZiAoZm4pIHJlcS5lbmQoZm4pO1xuICByZXR1cm4gcmVxO1xufTtcblxuLyoqXG4gKiBQVVQgYHVybGAgd2l0aCBvcHRpb25hbCBgZGF0YWAgYW5kIGNhbGxiYWNrIGBmbihyZXMpYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJsXG4gKiBAcGFyYW0ge01peGVkfEZ1bmN0aW9ufSBbZGF0YV0gb3IgZm5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtmbl1cbiAqIEByZXR1cm4ge1JlcXVlc3R9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbnJlcXVlc3QucHV0ID0gZnVuY3Rpb24odXJsLCBkYXRhLCBmbil7XG4gIHZhciByZXEgPSByZXF1ZXN0KCdQVVQnLCB1cmwpO1xuICBpZiAoJ2Z1bmN0aW9uJyA9PSB0eXBlb2YgZGF0YSkgZm4gPSBkYXRhLCBkYXRhID0gbnVsbDtcbiAgaWYgKGRhdGEpIHJlcS5zZW5kKGRhdGEpO1xuICBpZiAoZm4pIHJlcS5lbmQoZm4pO1xuICByZXR1cm4gcmVxO1xufTtcbiIsIi8qKlxuICogQ2hlY2sgaWYgYG9iamAgaXMgYW4gb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBpc09iamVjdChvYmopIHtcbiAgcmV0dXJuIG51bGwgIT09IG9iaiAmJiAnb2JqZWN0JyA9PT0gdHlwZW9mIG9iajtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc09iamVjdDtcbiIsIi8qKlxuICogTW9kdWxlIG9mIG1peGVkLWluIGZ1bmN0aW9ucyBzaGFyZWQgYmV0d2VlbiBub2RlIGFuZCBjbGllbnQgY29kZVxuICovXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL2lzLW9iamVjdCcpO1xuXG4vKipcbiAqIENsZWFyIHByZXZpb3VzIHRpbWVvdXQuXG4gKlxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuY2xlYXJUaW1lb3V0ID0gZnVuY3Rpb24gX2NsZWFyVGltZW91dCgpe1xuICB0aGlzLl90aW1lb3V0ID0gMDtcbiAgY2xlYXJUaW1lb3V0KHRoaXMuX3RpbWVyKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIE92ZXJyaWRlIGRlZmF1bHQgcmVzcG9uc2UgYm9keSBwYXJzZXJcbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIHdpbGwgYmUgY2FsbGVkIHRvIGNvbnZlcnQgaW5jb21pbmcgZGF0YSBpbnRvIHJlcXVlc3QuYm9keVxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMucGFyc2UgPSBmdW5jdGlvbiBwYXJzZShmbil7XG4gIHRoaXMuX3BhcnNlciA9IGZuO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogT3ZlcnJpZGUgZGVmYXVsdCByZXF1ZXN0IGJvZHkgc2VyaWFsaXplclxuICpcbiAqIFRoaXMgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWQgdG8gY29udmVydCBkYXRhIHNldCB2aWEgLnNlbmQgb3IgLmF0dGFjaCBpbnRvIHBheWxvYWQgdG8gc2VuZFxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuc2VyaWFsaXplID0gZnVuY3Rpb24gc2VyaWFsaXplKGZuKXtcbiAgdGhpcy5fc2VyaWFsaXplciA9IGZuO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0IHRpbWVvdXQgdG8gYG1zYC5cbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gbXNcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLnRpbWVvdXQgPSBmdW5jdGlvbiB0aW1lb3V0KG1zKXtcbiAgdGhpcy5fdGltZW91dCA9IG1zO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogUHJvbWlzZSBzdXBwb3J0XG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gcmVzb2x2ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gcmVqZWN0XG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICovXG5cbmV4cG9ydHMudGhlbiA9IGZ1bmN0aW9uIHRoZW4ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gIGlmICghdGhpcy5fZnVsbGZpbGxlZFByb21pc2UpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdGhpcy5fZnVsbGZpbGxlZFByb21pc2UgPSBuZXcgUHJvbWlzZShmdW5jdGlvbihpbm5lclJlc29sdmUsIGlubmVyUmVqZWN0KXtcbiAgICAgIHNlbGYuZW5kKGZ1bmN0aW9uKGVyciwgcmVzKXtcbiAgICAgICAgaWYgKGVycikgaW5uZXJSZWplY3QoZXJyKTsgZWxzZSBpbm5lclJlc29sdmUocmVzKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG4gIHJldHVybiB0aGlzLl9mdWxsZmlsbGVkUHJvbWlzZS50aGVuKHJlc29sdmUsIHJlamVjdCk7XG59XG5cbi8qKlxuICogQWxsb3cgZm9yIGV4dGVuc2lvblxuICovXG5cbmV4cG9ydHMudXNlID0gZnVuY3Rpb24gdXNlKGZuKSB7XG4gIGZuKHRoaXMpO1xuICByZXR1cm4gdGhpcztcbn1cblxuXG4vKipcbiAqIEdldCByZXF1ZXN0IGhlYWRlciBgZmllbGRgLlxuICogQ2FzZS1pbnNlbnNpdGl2ZS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZmllbGRcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5nZXQgPSBmdW5jdGlvbihmaWVsZCl7XG4gIHJldHVybiB0aGlzLl9oZWFkZXJbZmllbGQudG9Mb3dlckNhc2UoKV07XG59O1xuXG4vKipcbiAqIEdldCBjYXNlLWluc2Vuc2l0aXZlIGhlYWRlciBgZmllbGRgIHZhbHVlLlxuICogVGhpcyBpcyBhIGRlcHJlY2F0ZWQgaW50ZXJuYWwgQVBJLiBVc2UgYC5nZXQoZmllbGQpYCBpbnN0ZWFkLlxuICpcbiAqIChnZXRIZWFkZXIgaXMgbm8gbG9uZ2VyIHVzZWQgaW50ZXJuYWxseSBieSB0aGUgc3VwZXJhZ2VudCBjb2RlIGJhc2UpXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGZpZWxkXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqIEBkZXByZWNhdGVkXG4gKi9cblxuZXhwb3J0cy5nZXRIZWFkZXIgPSBleHBvcnRzLmdldDtcblxuLyoqXG4gKiBTZXQgaGVhZGVyIGBmaWVsZGAgdG8gYHZhbGAsIG9yIG11bHRpcGxlIGZpZWxkcyB3aXRoIG9uZSBvYmplY3QuXG4gKiBDYXNlLWluc2Vuc2l0aXZlLlxuICpcbiAqIEV4YW1wbGVzOlxuICpcbiAqICAgICAgcmVxLmdldCgnLycpXG4gKiAgICAgICAgLnNldCgnQWNjZXB0JywgJ2FwcGxpY2F0aW9uL2pzb24nKVxuICogICAgICAgIC5zZXQoJ1gtQVBJLUtleScsICdmb29iYXInKVxuICogICAgICAgIC5lbmQoY2FsbGJhY2spO1xuICpcbiAqICAgICAgcmVxLmdldCgnLycpXG4gKiAgICAgICAgLnNldCh7IEFjY2VwdDogJ2FwcGxpY2F0aW9uL2pzb24nLCAnWC1BUEktS2V5JzogJ2Zvb2JhcicgfSlcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xPYmplY3R9IGZpZWxkXG4gKiBAcGFyYW0ge1N0cmluZ30gdmFsXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5zZXQgPSBmdW5jdGlvbihmaWVsZCwgdmFsKXtcbiAgaWYgKGlzT2JqZWN0KGZpZWxkKSkge1xuICAgIGZvciAodmFyIGtleSBpbiBmaWVsZCkge1xuICAgICAgdGhpcy5zZXQoa2V5LCBmaWVsZFtrZXldKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgdGhpcy5faGVhZGVyW2ZpZWxkLnRvTG93ZXJDYXNlKCldID0gdmFsO1xuICB0aGlzLmhlYWRlcltmaWVsZF0gPSB2YWw7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZW1vdmUgaGVhZGVyIGBmaWVsZGAuXG4gKiBDYXNlLWluc2Vuc2l0aXZlLlxuICpcbiAqIEV4YW1wbGU6XG4gKlxuICogICAgICByZXEuZ2V0KCcvJylcbiAqICAgICAgICAudW5zZXQoJ1VzZXItQWdlbnQnKVxuICogICAgICAgIC5lbmQoY2FsbGJhY2spO1xuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBmaWVsZFxuICovXG5leHBvcnRzLnVuc2V0ID0gZnVuY3Rpb24oZmllbGQpe1xuICBkZWxldGUgdGhpcy5faGVhZGVyW2ZpZWxkLnRvTG93ZXJDYXNlKCldO1xuICBkZWxldGUgdGhpcy5oZWFkZXJbZmllbGRdO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogV3JpdGUgdGhlIGZpZWxkIGBuYW1lYCBhbmQgYHZhbGAgZm9yIFwibXVsdGlwYXJ0L2Zvcm0tZGF0YVwiXG4gKiByZXF1ZXN0IGJvZGllcy5cbiAqXG4gKiBgYGAganNcbiAqIHJlcXVlc3QucG9zdCgnL3VwbG9hZCcpXG4gKiAgIC5maWVsZCgnZm9vJywgJ2JhcicpXG4gKiAgIC5lbmQoY2FsbGJhY2spO1xuICogYGBgXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcbiAqIEBwYXJhbSB7U3RyaW5nfEJsb2J8RmlsZXxCdWZmZXJ8ZnMuUmVhZFN0cmVhbX0gdmFsXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cbmV4cG9ydHMuZmllbGQgPSBmdW5jdGlvbihuYW1lLCB2YWwpIHtcbiAgdGhpcy5fZ2V0Rm9ybURhdGEoKS5hcHBlbmQobmFtZSwgdmFsKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEFib3J0IHRoZSByZXF1ZXN0LCBhbmQgY2xlYXIgcG90ZW50aWFsIHRpbWVvdXQuXG4gKlxuICogQHJldHVybiB7UmVxdWVzdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cbmV4cG9ydHMuYWJvcnQgPSBmdW5jdGlvbigpe1xuICBpZiAodGhpcy5fYWJvcnRlZCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9XG4gIHRoaXMuX2Fib3J0ZWQgPSB0cnVlO1xuICB0aGlzLnhociAmJiB0aGlzLnhoci5hYm9ydCgpOyAvLyBicm93c2VyXG4gIHRoaXMucmVxICYmIHRoaXMucmVxLmFib3J0KCk7IC8vIG5vZGVcbiAgdGhpcy5jbGVhclRpbWVvdXQoKTtcbiAgdGhpcy5lbWl0KCdhYm9ydCcpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogRW5hYmxlIHRyYW5zbWlzc2lvbiBvZiBjb29raWVzIHdpdGggeC1kb21haW4gcmVxdWVzdHMuXG4gKlxuICogTm90ZSB0aGF0IGZvciB0aGlzIHRvIHdvcmsgdGhlIG9yaWdpbiBtdXN0IG5vdCBiZVxuICogdXNpbmcgXCJBY2Nlc3MtQ29udHJvbC1BbGxvdy1PcmlnaW5cIiB3aXRoIGEgd2lsZGNhcmQsXG4gKiBhbmQgYWxzbyBtdXN0IHNldCBcIkFjY2Vzcy1Db250cm9sLUFsbG93LUNyZWRlbnRpYWxzXCJcbiAqIHRvIFwidHJ1ZVwiLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy53aXRoQ3JlZGVudGlhbHMgPSBmdW5jdGlvbigpe1xuICAvLyBUaGlzIGlzIGJyb3dzZXItb25seSBmdW5jdGlvbmFsaXR5LiBOb2RlIHNpZGUgaXMgbm8tb3AuXG4gIHRoaXMuX3dpdGhDcmVkZW50aWFscyA9IHRydWU7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZXQgdGhlIG1heCByZWRpcmVjdHMgdG8gYG5gLiBEb2VzIG5vdGluZyBpbiBicm93c2VyIFhIUiBpbXBsZW1lbnRhdGlvbi5cbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gblxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMucmVkaXJlY3RzID0gZnVuY3Rpb24obil7XG4gIHRoaXMuX21heFJlZGlyZWN0cyA9IG47XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBDb252ZXJ0IHRvIGEgcGxhaW4gamF2YXNjcmlwdCBvYmplY3QgKG5vdCBKU09OIHN0cmluZykgb2Ygc2NhbGFyIHByb3BlcnRpZXMuXG4gKiBOb3RlIGFzIHRoaXMgbWV0aG9kIGlzIGRlc2lnbmVkIHRvIHJldHVybiBhIHVzZWZ1bCBub24tdGhpcyB2YWx1ZSxcbiAqIGl0IGNhbm5vdCBiZSBjaGFpbmVkLlxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gZGVzY3JpYmluZyBtZXRob2QsIHVybCwgYW5kIGRhdGEgb2YgdGhpcyByZXF1ZXN0XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMudG9KU09OID0gZnVuY3Rpb24oKXtcbiAgcmV0dXJuIHtcbiAgICBtZXRob2Q6IHRoaXMubWV0aG9kLFxuICAgIHVybDogdGhpcy51cmwsXG4gICAgZGF0YTogdGhpcy5fZGF0YSxcbiAgICBoZWFkZXJzOiB0aGlzLl9oZWFkZXJcbiAgfTtcbn07XG5cbi8qKlxuICogQ2hlY2sgaWYgYG9iamAgaXMgYSBob3N0IG9iamVjdCxcbiAqIHdlIGRvbid0IHdhbnQgdG8gc2VyaWFsaXplIHRoZXNlIDopXG4gKlxuICogVE9ETzogZnV0dXJlIHByb29mLCBtb3ZlIHRvIGNvbXBvZW50IGxhbmRcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZXhwb3J0cy5faXNIb3N0ID0gZnVuY3Rpb24gX2lzSG9zdChvYmopIHtcbiAgdmFyIHN0ciA9IHt9LnRvU3RyaW5nLmNhbGwob2JqKTtcblxuICBzd2l0Y2ggKHN0cikge1xuICAgIGNhc2UgJ1tvYmplY3QgRmlsZV0nOlxuICAgIGNhc2UgJ1tvYmplY3QgQmxvYl0nOlxuICAgIGNhc2UgJ1tvYmplY3QgRm9ybURhdGFdJzpcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuLyoqXG4gKiBTZW5kIGBkYXRhYCBhcyB0aGUgcmVxdWVzdCBib2R5LCBkZWZhdWx0aW5nIHRoZSBgLnR5cGUoKWAgdG8gXCJqc29uXCIgd2hlblxuICogYW4gb2JqZWN0IGlzIGdpdmVuLlxuICpcbiAqIEV4YW1wbGVzOlxuICpcbiAqICAgICAgIC8vIG1hbnVhbCBqc29uXG4gKiAgICAgICByZXF1ZXN0LnBvc3QoJy91c2VyJylcbiAqICAgICAgICAgLnR5cGUoJ2pzb24nKVxuICogICAgICAgICAuc2VuZCgne1wibmFtZVwiOlwidGpcIn0nKVxuICogICAgICAgICAuZW5kKGNhbGxiYWNrKVxuICpcbiAqICAgICAgIC8vIGF1dG8ganNvblxuICogICAgICAgcmVxdWVzdC5wb3N0KCcvdXNlcicpXG4gKiAgICAgICAgIC5zZW5kKHsgbmFtZTogJ3RqJyB9KVxuICogICAgICAgICAuZW5kKGNhbGxiYWNrKVxuICpcbiAqICAgICAgIC8vIG1hbnVhbCB4LXd3dy1mb3JtLXVybGVuY29kZWRcbiAqICAgICAgIHJlcXVlc3QucG9zdCgnL3VzZXInKVxuICogICAgICAgICAudHlwZSgnZm9ybScpXG4gKiAgICAgICAgIC5zZW5kKCduYW1lPXRqJylcbiAqICAgICAgICAgLmVuZChjYWxsYmFjaylcbiAqXG4gKiAgICAgICAvLyBhdXRvIHgtd3d3LWZvcm0tdXJsZW5jb2RlZFxuICogICAgICAgcmVxdWVzdC5wb3N0KCcvdXNlcicpXG4gKiAgICAgICAgIC50eXBlKCdmb3JtJylcbiAqICAgICAgICAgLnNlbmQoeyBuYW1lOiAndGonIH0pXG4gKiAgICAgICAgIC5lbmQoY2FsbGJhY2spXG4gKlxuICogICAgICAgLy8gZGVmYXVsdHMgdG8geC13d3ctZm9ybS11cmxlbmNvZGVkXG4gKiAgICAgIHJlcXVlc3QucG9zdCgnL3VzZXInKVxuICogICAgICAgIC5zZW5kKCduYW1lPXRvYmknKVxuICogICAgICAgIC5zZW5kKCdzcGVjaWVzPWZlcnJldCcpXG4gKiAgICAgICAgLmVuZChjYWxsYmFjaylcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xPYmplY3R9IGRhdGFcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLnNlbmQgPSBmdW5jdGlvbihkYXRhKXtcbiAgdmFyIG9iaiA9IGlzT2JqZWN0KGRhdGEpO1xuICB2YXIgdHlwZSA9IHRoaXMuX2hlYWRlclsnY29udGVudC10eXBlJ107XG5cbiAgLy8gbWVyZ2VcbiAgaWYgKG9iaiAmJiBpc09iamVjdCh0aGlzLl9kYXRhKSkge1xuICAgIGZvciAodmFyIGtleSBpbiBkYXRhKSB7XG4gICAgICB0aGlzLl9kYXRhW2tleV0gPSBkYXRhW2tleV07XG4gICAgfVxuICB9IGVsc2UgaWYgKCdzdHJpbmcnID09IHR5cGVvZiBkYXRhKSB7XG4gICAgLy8gZGVmYXVsdCB0byB4LXd3dy1mb3JtLXVybGVuY29kZWRcbiAgICBpZiAoIXR5cGUpIHRoaXMudHlwZSgnZm9ybScpO1xuICAgIHR5cGUgPSB0aGlzLl9oZWFkZXJbJ2NvbnRlbnQtdHlwZSddO1xuICAgIGlmICgnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyA9PSB0eXBlKSB7XG4gICAgICB0aGlzLl9kYXRhID0gdGhpcy5fZGF0YVxuICAgICAgICA/IHRoaXMuX2RhdGEgKyAnJicgKyBkYXRhXG4gICAgICAgIDogZGF0YTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fZGF0YSA9ICh0aGlzLl9kYXRhIHx8ICcnKSArIGRhdGE7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRoaXMuX2RhdGEgPSBkYXRhO1xuICB9XG5cbiAgaWYgKCFvYmogfHwgdGhpcy5faXNIb3N0KGRhdGEpKSByZXR1cm4gdGhpcztcblxuICAvLyBkZWZhdWx0IHRvIGpzb25cbiAgaWYgKCF0eXBlKSB0aGlzLnR5cGUoJ2pzb24nKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuIiwiLy8gVGhlIG5vZGUgYW5kIGJyb3dzZXIgbW9kdWxlcyBleHBvc2UgdmVyc2lvbnMgb2YgdGhpcyB3aXRoIHRoZVxuLy8gYXBwcm9wcmlhdGUgY29uc3RydWN0b3IgZnVuY3Rpb24gYm91bmQgYXMgZmlyc3QgYXJndW1lbnRcbi8qKlxuICogSXNzdWUgYSByZXF1ZXN0OlxuICpcbiAqIEV4YW1wbGVzOlxuICpcbiAqICAgIHJlcXVlc3QoJ0dFVCcsICcvdXNlcnMnKS5lbmQoY2FsbGJhY2spXG4gKiAgICByZXF1ZXN0KCcvdXNlcnMnKS5lbmQoY2FsbGJhY2spXG4gKiAgICByZXF1ZXN0KCcvdXNlcnMnLCBjYWxsYmFjaylcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kXG4gKiBAcGFyYW0ge1N0cmluZ3xGdW5jdGlvbn0gdXJsIG9yIGNhbGxiYWNrXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiByZXF1ZXN0KFJlcXVlc3RDb25zdHJ1Y3RvciwgbWV0aG9kLCB1cmwpIHtcbiAgLy8gY2FsbGJhY2tcbiAgaWYgKCdmdW5jdGlvbicgPT0gdHlwZW9mIHVybCkge1xuICAgIHJldHVybiBuZXcgUmVxdWVzdENvbnN0cnVjdG9yKCdHRVQnLCBtZXRob2QpLmVuZCh1cmwpO1xuICB9XG5cbiAgLy8gdXJsIGZpcnN0XG4gIGlmICgyID09IGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICByZXR1cm4gbmV3IFJlcXVlc3RDb25zdHJ1Y3RvcignR0VUJywgbWV0aG9kKTtcbiAgfVxuXG4gIHJldHVybiBuZXcgUmVxdWVzdENvbnN0cnVjdG9yKG1ldGhvZCwgdXJsKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSByZXF1ZXN0O1xuIiwiXHJcbi8qKlxyXG4gKiBFeHBvc2UgYEVtaXR0ZXJgLlxyXG4gKi9cclxuXHJcbmlmICh0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJykge1xyXG4gIG1vZHVsZS5leHBvcnRzID0gRW1pdHRlcjtcclxufVxyXG5cclxuLyoqXHJcbiAqIEluaXRpYWxpemUgYSBuZXcgYEVtaXR0ZXJgLlxyXG4gKlxyXG4gKiBAYXBpIHB1YmxpY1xyXG4gKi9cclxuXHJcbmZ1bmN0aW9uIEVtaXR0ZXIob2JqKSB7XHJcbiAgaWYgKG9iaikgcmV0dXJuIG1peGluKG9iaik7XHJcbn07XHJcblxyXG4vKipcclxuICogTWl4aW4gdGhlIGVtaXR0ZXIgcHJvcGVydGllcy5cclxuICpcclxuICogQHBhcmFtIHtPYmplY3R9IG9ialxyXG4gKiBAcmV0dXJuIHtPYmplY3R9XHJcbiAqIEBhcGkgcHJpdmF0ZVxyXG4gKi9cclxuXHJcbmZ1bmN0aW9uIG1peGluKG9iaikge1xyXG4gIGZvciAodmFyIGtleSBpbiBFbWl0dGVyLnByb3RvdHlwZSkge1xyXG4gICAgb2JqW2tleV0gPSBFbWl0dGVyLnByb3RvdHlwZVtrZXldO1xyXG4gIH1cclxuICByZXR1cm4gb2JqO1xyXG59XHJcblxyXG4vKipcclxuICogTGlzdGVuIG9uIHRoZSBnaXZlbiBgZXZlbnRgIHdpdGggYGZuYC5cclxuICpcclxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XHJcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXHJcbiAqIEByZXR1cm4ge0VtaXR0ZXJ9XHJcbiAqIEBhcGkgcHVibGljXHJcbiAqL1xyXG5cclxuRW1pdHRlci5wcm90b3R5cGUub24gPVxyXG5FbWl0dGVyLnByb3RvdHlwZS5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24oZXZlbnQsIGZuKXtcclxuICB0aGlzLl9jYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3MgfHwge307XHJcbiAgKHRoaXMuX2NhbGxiYWNrc1snJCcgKyBldmVudF0gPSB0aGlzLl9jYWxsYmFja3NbJyQnICsgZXZlbnRdIHx8IFtdKVxyXG4gICAgLnB1c2goZm4pO1xyXG4gIHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIEFkZHMgYW4gYGV2ZW50YCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBhIHNpbmdsZVxyXG4gKiB0aW1lIHRoZW4gYXV0b21hdGljYWxseSByZW1vdmVkLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcclxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cclxuICogQHJldHVybiB7RW1pdHRlcn1cclxuICogQGFwaSBwdWJsaWNcclxuICovXHJcblxyXG5FbWl0dGVyLnByb3RvdHlwZS5vbmNlID0gZnVuY3Rpb24oZXZlbnQsIGZuKXtcclxuICBmdW5jdGlvbiBvbigpIHtcclxuICAgIHRoaXMub2ZmKGV2ZW50LCBvbik7XHJcbiAgICBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG4gIH1cclxuXHJcbiAgb24uZm4gPSBmbjtcclxuICB0aGlzLm9uKGV2ZW50LCBvbik7XHJcbiAgcmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG4vKipcclxuICogUmVtb3ZlIHRoZSBnaXZlbiBjYWxsYmFjayBmb3IgYGV2ZW50YCBvciBhbGxcclxuICogcmVnaXN0ZXJlZCBjYWxsYmFja3MuXHJcbiAqXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxyXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxyXG4gKiBAcmV0dXJuIHtFbWl0dGVyfVxyXG4gKiBAYXBpIHB1YmxpY1xyXG4gKi9cclxuXHJcbkVtaXR0ZXIucHJvdG90eXBlLm9mZiA9XHJcbkVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID1cclxuRW1pdHRlci5wcm90b3R5cGUucmVtb3ZlQWxsTGlzdGVuZXJzID1cclxuRW1pdHRlci5wcm90b3R5cGUucmVtb3ZlRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50LCBmbil7XHJcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xyXG5cclxuICAvLyBhbGxcclxuICBpZiAoMCA9PSBhcmd1bWVudHMubGVuZ3RoKSB7XHJcbiAgICB0aGlzLl9jYWxsYmFja3MgPSB7fTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLy8gc3BlY2lmaWMgZXZlbnRcclxuICB2YXIgY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzWyckJyArIGV2ZW50XTtcclxuICBpZiAoIWNhbGxiYWNrcykgcmV0dXJuIHRoaXM7XHJcblxyXG4gIC8vIHJlbW92ZSBhbGwgaGFuZGxlcnNcclxuICBpZiAoMSA9PSBhcmd1bWVudHMubGVuZ3RoKSB7XHJcbiAgICBkZWxldGUgdGhpcy5fY2FsbGJhY2tzWyckJyArIGV2ZW50XTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLy8gcmVtb3ZlIHNwZWNpZmljIGhhbmRsZXJcclxuICB2YXIgY2I7XHJcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBjYWxsYmFja3MubGVuZ3RoOyBpKyspIHtcclxuICAgIGNiID0gY2FsbGJhY2tzW2ldO1xyXG4gICAgaWYgKGNiID09PSBmbiB8fCBjYi5mbiA9PT0gZm4pIHtcclxuICAgICAgY2FsbGJhY2tzLnNwbGljZShpLCAxKTtcclxuICAgICAgYnJlYWs7XHJcbiAgICB9XHJcbiAgfVxyXG4gIHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIEVtaXQgYGV2ZW50YCB3aXRoIHRoZSBnaXZlbiBhcmdzLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcclxuICogQHBhcmFtIHtNaXhlZH0gLi4uXHJcbiAqIEByZXR1cm4ge0VtaXR0ZXJ9XHJcbiAqL1xyXG5cclxuRW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uKGV2ZW50KXtcclxuICB0aGlzLl9jYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3MgfHwge307XHJcbiAgdmFyIGFyZ3MgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSlcclxuICAgICwgY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzWyckJyArIGV2ZW50XTtcclxuXHJcbiAgaWYgKGNhbGxiYWNrcykge1xyXG4gICAgY2FsbGJhY2tzID0gY2FsbGJhY2tzLnNsaWNlKDApO1xyXG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGNhbGxiYWNrcy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xyXG4gICAgICBjYWxsYmFja3NbaV0uYXBwbHkodGhpcywgYXJncyk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZXR1cm4gdGhpcztcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm4gYXJyYXkgb2YgY2FsbGJhY2tzIGZvciBgZXZlbnRgLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcclxuICogQHJldHVybiB7QXJyYXl9XHJcbiAqIEBhcGkgcHVibGljXHJcbiAqL1xyXG5cclxuRW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24oZXZlbnQpe1xyXG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcclxuICByZXR1cm4gdGhpcy5fY2FsbGJhY2tzWyckJyArIGV2ZW50XSB8fCBbXTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBDaGVjayBpZiB0aGlzIGVtaXR0ZXIgaGFzIGBldmVudGAgaGFuZGxlcnMuXHJcbiAqXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxyXG4gKiBAcmV0dXJuIHtCb29sZWFufVxyXG4gKiBAYXBpIHB1YmxpY1xyXG4gKi9cclxuXHJcbkVtaXR0ZXIucHJvdG90eXBlLmhhc0xpc3RlbmVycyA9IGZ1bmN0aW9uKGV2ZW50KXtcclxuICByZXR1cm4gISEgdGhpcy5saXN0ZW5lcnMoZXZlbnQpLmxlbmd0aDtcclxufTtcclxuIiwiIC8qZ2xvYmFsIEpTT05FZGl0b3IqL1xuJ3VzZSBzdHJpY3QnO1xuXG53aW5kb3cuU3dhZ2dlclVpID0gQmFja2JvbmUuUm91dGVyLmV4dGVuZCh7XG5cbiAgZG9tX2lkOiAnc3dhZ2dlcl91aScsXG5cbiAgLy8gQXR0cmlidXRlc1xuICBvcHRpb25zOiBudWxsLFxuICBhcGk6IG51bGwsXG4gIGhlYWRlclZpZXc6IG51bGwsXG4gIG1haW5WaWV3OiBudWxsLFxuXG4gIC8vIFN3YWdnZXJVaSBhY2NlcHRzIGFsbCB0aGUgc2FtZSBvcHRpb25zIGFzIFN3YWdnZXJBcGlcbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24ob3B0aW9ucykge1xuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gICAgaWYgKG9wdGlvbnMuZGVmYXVsdE1vZGVsUmVuZGVyaW5nICE9PSAnbW9kZWwnKSB7XG4gICAgICBvcHRpb25zLmRlZmF1bHRNb2RlbFJlbmRlcmluZyA9ICdzY2hlbWEnO1xuICAgIH1cblxuICAgIGlmICghb3B0aW9ucy5oaWdobGlnaHRTaXplVGhyZXNob2xkKSB7XG4gICAgICBvcHRpb25zLmhpZ2hsaWdodFNpemVUaHJlc2hvbGQgPSAxMDAwMDA7XG4gICAgfVxuXG4gICAgLy8gQWxsb3cgZG9tX2lkIHRvIGJlIG92ZXJyaWRkZW5cbiAgICBpZiAob3B0aW9ucy5kb21faWQpIHtcbiAgICAgIHRoaXMuZG9tX2lkID0gb3B0aW9ucy5kb21faWQ7XG4gICAgICBkZWxldGUgb3B0aW9ucy5kb21faWQ7XG4gICAgfVxuXG4gICAgaWYgKCFvcHRpb25zLnN1cHBvcnRlZFN1Ym1pdE1ldGhvZHMpe1xuICAgICAgb3B0aW9ucy5zdXBwb3J0ZWRTdWJtaXRNZXRob2RzID0gW1xuICAgICAgICAnZ2V0JyxcbiAgICAgICAgJ3B1dCcsXG4gICAgICAgICdwb3N0JyxcbiAgICAgICAgJ2RlbGV0ZScsXG4gICAgICAgICdoZWFkJyxcbiAgICAgICAgJ29wdGlvbnMnLFxuICAgICAgICAncGF0Y2gnXG4gICAgICBdO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5vYXV0aDJSZWRpcmVjdFVybCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHdpbmRvdy5vQXV0aFJlZGlyZWN0VXJsID0gb3B0aW9ucy5vYXV0aDJSZWRpcmVjdFVybDtcbiAgICB9XG5cbiAgICAvLyBDcmVhdGUgYW4gZW1wdHkgZGl2IHdoaWNoIGNvbnRhaW5zIHRoZSBkb21faWRcbiAgICBpZiAoISAkKCcjJyArIHRoaXMuZG9tX2lkKS5sZW5ndGgpe1xuICAgICAgJCgnYm9keScpLmFwcGVuZCgnPGRpdiBpZD1cIicgKyB0aGlzLmRvbV9pZCArICdcIj48L2Rpdj4nKSA7XG4gICAgfVxuXG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcblxuICAgIC8vIHNldCBtYXJrZWQgb3B0aW9uc1xuICAgIG1hcmtlZC5zZXRPcHRpb25zKHtnZm06IHRydWV9KTtcblxuICAgIC8vIFNldCB0aGUgY2FsbGJhY2tzXG4gICAgdmFyIHRoYXQgPSB0aGlzO1xuICAgIHRoaXMub3B0aW9ucy5zdWNjZXNzID0gZnVuY3Rpb24oKSB7IHJldHVybiB0aGF0LnJlbmRlcigpOyB9O1xuICAgIHRoaXMub3B0aW9ucy5wcm9ncmVzcyA9IGZ1bmN0aW9uKGQpIHsgcmV0dXJuIHRoYXQuc2hvd01lc3NhZ2UoZCk7IH07XG4gICAgdGhpcy5vcHRpb25zLmZhaWx1cmUgPSBmdW5jdGlvbihkKSB7IHJldHVybiB0aGF0Lm9uTG9hZEZhaWx1cmUoZCk7IH07XG5cbiAgICAvLyBDcmVhdGUgdmlldyB0byBoYW5kbGUgdGhlIGhlYWRlciBpbnB1dHNcbiAgICB0aGlzLmhlYWRlclZpZXcgPSBuZXcgU3dhZ2dlclVpLlZpZXdzLkhlYWRlclZpZXcoe2VsOiAkKCcjaGVhZGVyJyl9KTtcblxuICAgIC8vIEV2ZW50IGhhbmRsZXIgZm9yIHdoZW4gdGhlIGJhc2VVcmwvYXBpS2V5IGlzIGVudGVyZWQgYnkgdXNlclxuICAgIHRoaXMuaGVhZGVyVmlldy5vbigndXBkYXRlLXN3YWdnZXItdWknLCBmdW5jdGlvbihkYXRhKSB7XG4gICAgICByZXR1cm4gdGhhdC51cGRhdGVTd2FnZ2VyVWkoZGF0YSk7XG4gICAgfSk7XG5cbiAgICAvLyBKU29uIEVkaXRvciBjdXN0b20gdGhlbWluZ1xuICAgICBKU09ORWRpdG9yLmRlZmF1bHRzLmljb25saWJzLnN3YWdnZXIgPSBKU09ORWRpdG9yLkFic3RyYWN0SWNvbkxpYi5leHRlbmQoe1xuICAgICAgbWFwcGluZzoge1xuICAgICAgICBjb2xsYXBzZTogJ2NvbGxhcHNlJyxcbiAgICAgICAgZXhwYW5kOiAnZXhwYW5kJ1xuICAgICAgICB9LFxuICAgICAgaWNvbl9wcmVmaXg6ICdzd2FnZ2VyLSdcbiAgICAgIH0pO1xuXG4gIH0sXG5cbiAgLy8gU2V0IGFuIG9wdGlvbiBhZnRlciBpbml0aWFsaXppbmdcbiAgc2V0T3B0aW9uOiBmdW5jdGlvbihvcHRpb24sIHZhbHVlKSB7XG4gICAgdGhpcy5vcHRpb25zW29wdGlvbl0gPSB2YWx1ZTtcbiAgfSxcblxuICAvLyBHZXQgdGhlIHZhbHVlIG9mIGEgcHJldmlvdXNseSBzZXQgb3B0aW9uXG4gIGdldE9wdGlvbjogZnVuY3Rpb24ob3B0aW9uKSB7XG4gICAgcmV0dXJuIHRoaXMub3B0aW9uc1tvcHRpb25dO1xuICB9LFxuXG4gIC8vIEV2ZW50IGhhbmRsZXIgZm9yIHdoZW4gdXJsL2tleSBpcyByZWNlaXZlZCBmcm9tIHVzZXJcbiAgdXBkYXRlU3dhZ2dlclVpOiBmdW5jdGlvbihkYXRhKXtcbiAgICB0aGlzLm9wdGlvbnMudXJsID0gZGF0YS51cmw7XG4gICAgdGhpcy5sb2FkKCk7XG4gIH0sXG5cbiAgLy8gQ3JlYXRlIGFuIGFwaSBhbmQgcmVuZGVyXG4gIGxvYWQ6IGZ1bmN0aW9uKCl7XG4gICAgLy8gSW5pdGlhbGl6ZSB0aGUgQVBJIG9iamVjdFxuICAgIGlmICh0aGlzLm1haW5WaWV3KSB7XG4gICAgICB0aGlzLm1haW5WaWV3LmNsZWFyKCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuYXV0aFZpZXcpIHtcbiAgICAgIHRoaXMuYXV0aFZpZXcucmVtb3ZlKCk7XG4gICAgfVxuICAgIHZhciB1cmwgPSB0aGlzLm9wdGlvbnMudXJsO1xuICAgIGlmICh1cmwgJiYgdXJsLmluZGV4T2YoJ2h0dHAnKSAhPT0gMCkge1xuICAgICAgdXJsID0gdGhpcy5idWlsZFVybCh3aW5kb3cubG9jYXRpb24uaHJlZi50b1N0cmluZygpLCB1cmwpO1xuICAgIH1cbiAgICBpZih0aGlzLmFwaSkge1xuICAgICAgdGhpcy5vcHRpb25zLmF1dGhvcml6YXRpb25zID0gdGhpcy5hcGkuY2xpZW50QXV0aG9yaXphdGlvbnMuYXV0aHo7XG4gICAgfVxuICAgIHRoaXMub3B0aW9ucy51cmwgPSB1cmw7XG4gICAgdGhpcy5oZWFkZXJWaWV3LnVwZGF0ZSh1cmwpO1xuXG4gICAgdGhpcy5hcGkgPSBuZXcgU3dhZ2dlckNsaWVudCh0aGlzLm9wdGlvbnMpO1xuICB9LFxuXG4gIC8vIGNvbGxhcHNlIGFsbCBzZWN0aW9uc1xuICBjb2xsYXBzZUFsbDogZnVuY3Rpb24oKXtcbiAgICBEb2NzLmNvbGxhcHNlRW5kcG9pbnRMaXN0Rm9yUmVzb3VyY2UoJycpO1xuICB9LFxuXG4gIC8vIGxpc3Qgb3BlcmF0aW9ucyBmb3IgYWxsIHNlY3Rpb25zXG4gIGxpc3RBbGw6IGZ1bmN0aW9uKCl7XG4gICAgRG9jcy5jb2xsYXBzZU9wZXJhdGlvbnNGb3JSZXNvdXJjZSgnJyk7XG4gIH0sXG5cbiAgLy8gZXhwYW5kIG9wZXJhdGlvbnMgZm9yIGFsbCBzZWN0aW9uc1xuICBleHBhbmRBbGw6IGZ1bmN0aW9uKCl7XG4gICAgRG9jcy5leHBhbmRPcGVyYXRpb25zRm9yUmVzb3VyY2UoJycpO1xuICB9LFxuXG4gIC8vIFRoaXMgaXMgYm91bmQgdG8gc3VjY2VzcyBoYW5kbGVyIGZvciBTd2FnZ2VyQXBpXG4gIC8vICBzbyBpdCBnZXRzIGNhbGxlZCB3aGVuIFN3YWdnZXJBcGkgY29tcGxldGVzIGxvYWRpbmdcbiAgcmVuZGVyOiBmdW5jdGlvbigpe1xuICAgIHZhciBhdXRoc01vZGVsO1xuICAgIHRoaXMuc2hvd01lc3NhZ2UoJ0ZpbmlzaGVkIExvYWRpbmcgUmVzb3VyY2UgSW5mb3JtYXRpb24uIFJlbmRlcmluZyBTd2FnZ2VyIFVJLi4uJyk7XG4gICAgdGhpcy5tYWluVmlldyA9IG5ldyBTd2FnZ2VyVWkuVmlld3MuTWFpblZpZXcoe1xuICAgICAgbW9kZWw6IHRoaXMuYXBpLFxuICAgICAgZWw6ICQoJyMnICsgdGhpcy5kb21faWQpLFxuICAgICAgc3dhZ2dlck9wdGlvbnM6IHRoaXMub3B0aW9ucyxcbiAgICAgIHJvdXRlcjogdGhpc1xuICAgIH0pLnJlbmRlcigpO1xuICAgIGlmICghXy5pc0VtcHR5KHRoaXMuYXBpLnNlY3VyaXR5RGVmaW5pdGlvbnMpKXtcbiAgICAgIGF1dGhzTW9kZWwgPSBfLm1hcCh0aGlzLmFwaS5zZWN1cml0eURlZmluaXRpb25zLCBmdW5jdGlvbiAoYXV0aCwgbmFtZSkge1xuICAgICAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgICAgIHJlc3VsdFtuYW1lXSA9IGF1dGg7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KTtcbiAgICAgIHRoaXMuYXV0aFZpZXcgPSBuZXcgU3dhZ2dlclVpLlZpZXdzLkF1dGhCdXR0b25WaWV3KHtcbiAgICAgICAgZGF0YTogU3dhZ2dlclVpLnV0aWxzLnBhcnNlU2VjdXJpdHlEZWZpbml0aW9ucyhhdXRoc01vZGVsKSxcbiAgICAgICAgcm91dGVyOiB0aGlzXG4gICAgICB9KTtcbiAgICAgICQoJyNhdXRoX2NvbnRhaW5lcicpLmFwcGVuZCh0aGlzLmF1dGhWaWV3LnJlbmRlcigpLmVsKTtcbiAgICB9XG4gICAgdGhpcy5zaG93TWVzc2FnZSgpO1xuICAgIHN3aXRjaCAodGhpcy5vcHRpb25zLmRvY0V4cGFuc2lvbikge1xuICAgICAgY2FzZSAnZnVsbCc6XG4gICAgICAgIHRoaXMuZXhwYW5kQWxsKCk7IGJyZWFrO1xuICAgICAgY2FzZSAnbGlzdCc6XG4gICAgICAgIHRoaXMubGlzdEFsbCgpOyBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICB0aGlzLnJlbmRlckdGTSgpO1xuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5vbkNvbXBsZXRlKXtcbiAgICAgIHRoaXMub3B0aW9ucy5vbkNvbXBsZXRlKHRoaXMuYXBpLCB0aGlzKTtcbiAgICB9XG5cbiAgICBzZXRUaW1lb3V0KERvY3Muc2hlYmFuZy5iaW5kKHRoaXMpLCAxMDApO1xuICB9LFxuXG4gIGJ1aWxkVXJsOiBmdW5jdGlvbihiYXNlLCB1cmwpe1xuICAgIGlmICh1cmwuaW5kZXhPZignLycpID09PSAwKSB7XG4gICAgICB2YXIgcGFydHMgPSBiYXNlLnNwbGl0KCcvJyk7XG4gICAgICBiYXNlID0gcGFydHNbMF0gKyAnLy8nICsgcGFydHNbMl07XG4gICAgICByZXR1cm4gYmFzZSArIHVybDtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGVuZE9mUGF0aCA9IGJhc2UubGVuZ3RoO1xuXG4gICAgICBpZiAoYmFzZS5pbmRleE9mKCc/JykgPiAtMSl7XG4gICAgICAgIGVuZE9mUGF0aCA9IE1hdGgubWluKGVuZE9mUGF0aCwgYmFzZS5pbmRleE9mKCc/JykpO1xuICAgICAgfVxuXG4gICAgICBpZiAoYmFzZS5pbmRleE9mKCcjJykgPiAtMSl7XG4gICAgICAgIGVuZE9mUGF0aCA9IE1hdGgubWluKGVuZE9mUGF0aCwgYmFzZS5pbmRleE9mKCcjJykpO1xuICAgICAgfVxuXG4gICAgICBiYXNlID0gYmFzZS5zdWJzdHJpbmcoMCwgZW5kT2ZQYXRoKTtcblxuICAgICAgaWYgKGJhc2UuaW5kZXhPZignLycsIGJhc2UubGVuZ3RoIC0gMSApICE9PSAtMSl7XG4gICAgICAgIHJldHVybiBiYXNlICsgdXJsO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYmFzZSArICcvJyArIHVybDtcbiAgICB9XG4gIH0sXG5cbiAgLy8gU2hvd3MgbWVzc2FnZSBvbiB0b3BiYXIgb2YgdGhlIHVpXG4gIHNob3dNZXNzYWdlOiBmdW5jdGlvbihkYXRhKXtcbiAgICBpZiAoZGF0YSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBkYXRhID0gJyc7XG4gICAgfVxuICAgIHZhciAkbXNnYmFyID0gJCgnI21lc3NhZ2UtYmFyJyk7XG4gICAgJG1zZ2Jhci5yZW1vdmVDbGFzcygnbWVzc2FnZS1mYWlsJyk7XG4gICAgJG1zZ2Jhci5hZGRDbGFzcygnbWVzc2FnZS1zdWNjZXNzJyk7XG4gICAgJG1zZ2Jhci50ZXh0KGRhdGEpO1xuICAgIGlmKHdpbmRvdy5Td2FnZ2VyVHJhbnNsYXRvcikge1xuICAgICAgd2luZG93LlN3YWdnZXJUcmFuc2xhdG9yLnRyYW5zbGF0ZSgkbXNnYmFyKTtcbiAgICB9XG4gIH0sXG5cbiAgLy8gc2hvd3MgbWVzc2FnZSBpbiByZWRcbiAgb25Mb2FkRmFpbHVyZTogZnVuY3Rpb24oZGF0YSl7XG4gICAgaWYgKGRhdGEgPT09IHVuZGVmaW5lZCkge1xuICAgICAgZGF0YSA9ICcnO1xuICAgIH1cbiAgICAkKCcjbWVzc2FnZS1iYXInKS5yZW1vdmVDbGFzcygnbWVzc2FnZS1zdWNjZXNzJyk7XG4gICAgJCgnI21lc3NhZ2UtYmFyJykuYWRkQ2xhc3MoJ21lc3NhZ2UtZmFpbCcpO1xuXG4gICAgdmFyIHZhbCA9ICQoJyNtZXNzYWdlLWJhcicpLnRleHQoZGF0YSk7XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLm9uRmFpbHVyZSkge1xuICAgICAgdGhpcy5vcHRpb25zLm9uRmFpbHVyZShkYXRhKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsO1xuICB9LFxuXG4gIC8vIFJlbmRlcnMgR0ZNIGZvciBlbGVtZW50cyB3aXRoICdtYXJrZG93bicgY2xhc3NcbiAgcmVuZGVyR0ZNOiBmdW5jdGlvbigpe1xuICAgICQoJy5tYXJrZG93bicpLmVhY2goZnVuY3Rpb24oKXtcbiAgICAgICQodGhpcykuaHRtbChtYXJrZWQoJCh0aGlzKS5odG1sKCkpKTtcbiAgICB9KTtcblxuICAgICQoJy5wcm9wRGVzYycsICcubW9kZWwtc2lnbmF0dXJlIC5kZXNjcmlwdGlvbicpLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgJCh0aGlzKS5odG1sKG1hcmtlZCgkKHRoaXMpLmh0bWwoKSkpLmFkZENsYXNzKCdtYXJrZG93bicpO1xuICAgIH0pO1xuICB9XG5cbn0pO1xuXG53aW5kb3cuU3dhZ2dlclVpLlZpZXdzID0ge307XG53aW5kb3cuU3dhZ2dlclVpLk1vZGVscyA9IHt9O1xud2luZG93LlN3YWdnZXJVaS5Db2xsZWN0aW9ucyA9IHt9O1xud2luZG93LlN3YWdnZXJVaS5wYXJ0aWFscyA9IHt9O1xud2luZG93LlN3YWdnZXJVaS51dGlscyA9IHt9O1xuXG4vLyBkb24ndCBicmVhayBiYWNrd2FyZCBjb21wYXRpYmlsaXR5IHdpdGggcHJldmlvdXMgdmVyc2lvbnMgYW5kIHdhcm4gdXNlcnMgdG8gdXBncmFkZSB0aGVpciBjb2RlXG4oZnVuY3Rpb24oKXtcbiAgd2luZG93LmF1dGhvcml6YXRpb25zID0ge1xuICAgIGFkZDogZnVuY3Rpb24oKSB7XG4gICAgICB3YXJuKCdVc2luZyB3aW5kb3cuYXV0aG9yaXphdGlvbnMgaXMgZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSBTd2FnZ2VyVWkuYXBpLmNsaWVudEF1dGhvcml6YXRpb25zLmFkZCgpLicpO1xuXG4gICAgICBpZiAodHlwZW9mIHdpbmRvdy5zd2FnZ2VyVWkgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3dpbmRvdy5zd2FnZ2VyVWkgaXMgbm90IGRlZmluZWQnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHdpbmRvdy5zd2FnZ2VyVWkgaW5zdGFuY2VvZiBTd2FnZ2VyVWkpIHtcbiAgICAgICAgd2luZG93LnN3YWdnZXJVaS5hcGkuY2xpZW50QXV0aG9yaXphdGlvbnMuYWRkLmFwcGx5KHdpbmRvdy5zd2FnZ2VyVWkuYXBpLmNsaWVudEF1dGhvcml6YXRpb25zLCBhcmd1bWVudHMpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICB3aW5kb3cuQXBpS2V5QXV0aG9yaXphdGlvbiA9IGZ1bmN0aW9uKCkge1xuICAgIHdhcm4oJ3dpbmRvdy5BcGlLZXlBdXRob3JpemF0aW9uIGlzIGRlcHJlY2F0ZWQuIFBsZWFzZSB1c2UgU3dhZ2dlckNsaWVudC5BcGlLZXlBdXRob3JpemF0aW9uLicpO1xuICAgIFN3YWdnZXJDbGllbnQuQXBpS2V5QXV0aG9yaXphdGlvbi5hcHBseSh3aW5kb3csIGFyZ3VtZW50cyk7XG4gIH07XG5cbiAgd2luZG93LlBhc3N3b3JkQXV0aG9yaXphdGlvbiA9IGZ1bmN0aW9uKCkge1xuICAgIHdhcm4oJ3dpbmRvdy5QYXNzd29yZEF1dGhvcml6YXRpb24gaXMgZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSBTd2FnZ2VyQ2xpZW50LlBhc3N3b3JkQXV0aG9yaXphdGlvbi4nKTtcbiAgICBTd2FnZ2VyQ2xpZW50LlBhc3N3b3JkQXV0aG9yaXphdGlvbi5hcHBseSh3aW5kb3csIGFyZ3VtZW50cyk7XG4gIH07XG5cbiAgZnVuY3Rpb24gd2FybihtZXNzYWdlKSB7XG4gICAgaWYgKCdjb25zb2xlJyBpbiB3aW5kb3cgJiYgdHlwZW9mIHdpbmRvdy5jb25zb2xlLndhcm4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGNvbnNvbGUud2FybihtZXNzYWdlKTtcbiAgICB9XG4gIH1cbn0pKCk7XG5cblxuLy8gVU1EXG4oZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnkpIHtcbiAgICBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XG4gICAgICAgIC8vIEFNRC4gUmVnaXN0ZXIgYXMgYW4gYW5vbnltb3VzIG1vZHVsZS5cbiAgICAgICAgZGVmaW5lKFsnYiddLCBmdW5jdGlvbiAoYikge1xuICAgICAgICAgICAgcmV0dXJuIChyb290LlN3YWdnZXJVaSA9IGZhY3RvcnkoYikpO1xuICAgICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jykge1xuICAgICAgICAvLyBOb2RlLiBEb2VzIG5vdCB3b3JrIHdpdGggc3RyaWN0IENvbW1vbkpTLCBidXRcbiAgICAgICAgLy8gb25seSBDb21tb25KUy1saWtlIGVudmlyb25tZW50cyB0aGF0IHN1cHBvcnQgbW9kdWxlLmV4cG9ydHMsXG4gICAgICAgIC8vIGxpa2UgTm9kZS5cbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoJ2InKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQnJvd3NlciBnbG9iYWxzXG4gICAgICAgIHJvb3QuU3dhZ2dlclVpID0gZmFjdG9yeShyb290LmIpO1xuICAgIH1cbn0odGhpcywgZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBTd2FnZ2VyVWk7XG59KSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbndpbmRvdy5Td2FnZ2VyVWkudXRpbHMgPSB7XG4gICAgcGFyc2VTZWN1cml0eURlZmluaXRpb25zOiBmdW5jdGlvbiAoc2VjdXJpdHksIHNlY3VyaXR5RGVmaW5pdGlvbnMpIHtcbiAgICAgICAgdmFyIGF1dGhzID0gT2JqZWN0LmFzc2lnbih7fSwgc2VjdXJpdHlEZWZpbml0aW9ucyk7XG4gICAgICAgIHZhciBvYXV0aDJBcnIgPSBbXTtcbiAgICAgICAgdmFyIGF1dGhzQXJyID0gW107XG4gICAgICAgIHZhciBzY29wZXMgPSBbXTtcbiAgICAgICAgdmFyIHV0aWxzID0gd2luZG93LlN3YWdnZXJVaS51dGlscztcblxuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkoc2VjdXJpdHkpKSB7IHJldHVybiBudWxsOyB9XG5cbiAgICAgICAgc2VjdXJpdHkuZm9yRWFjaChmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgICAgdmFyIHNpbmdsZVNlY3VyaXR5ID0ge307XG4gICAgICAgICAgICB2YXIgc2luZ2xlT2F1dGgyU2VjdXJpdHkgPSB7fTtcblxuICAgICAgICAgICAgZm9yICh2YXIga2V5IGluIGl0ZW0pIHtcbiAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShpdGVtW2tleV0pKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghYXV0aHNba2V5XSkgeyBjb250aW51ZTsgfVxuICAgICAgICAgICAgICAgICAgICBhdXRoc1trZXldID0gYXV0aHNba2V5XSB8fCB7fTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGF1dGhzW2tleV0udHlwZSA9PT0gJ29hdXRoMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpbmdsZU9hdXRoMlNlY3VyaXR5W2tleV0gPSBPYmplY3QuYXNzaWduKHt9LCBhdXRoc1trZXldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpbmdsZU9hdXRoMlNlY3VyaXR5W2tleV0uc2NvcGVzID0gT2JqZWN0LmFzc2lnbih7fSwgYXV0aHNba2V5XS5zY29wZXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBzaW5nbGVPYXV0aDJTZWN1cml0eVtrZXldLnNjb3Blcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpdGVtW2tleV0uaW5kZXhPZihpKSA8IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHNpbmdsZU9hdXRoMlNlY3VyaXR5W2tleV0uc2NvcGVzW2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHNpbmdsZU9hdXRoMlNlY3VyaXR5W2tleV0uc2NvcGVzID0gdXRpbHMucGFyc2VPYXV0aDJTY29wZXMoc2luZ2xlT2F1dGgyU2VjdXJpdHlba2V5XS5zY29wZXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2NvcGVzID0gXy5tZXJnZShzY29wZXMsIHNpbmdsZU9hdXRoMlNlY3VyaXR5W2tleV0uc2NvcGVzKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpbmdsZVNlY3VyaXR5W2tleV0gPSBPYmplY3QuYXNzaWduKHt9LCBhdXRoc1trZXldKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpdGVtW2tleV0udHlwZSA9PT0gJ29hdXRoMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpbmdsZU9hdXRoMlNlY3VyaXR5W2tleV0gPSBPYmplY3QuYXNzaWduKHt9LCBpdGVtW2tleV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2luZ2xlT2F1dGgyU2VjdXJpdHlba2V5XS5zY29wZXMgPSB1dGlscy5wYXJzZU9hdXRoMlNjb3BlcyhzaW5nbGVPYXV0aDJTZWN1cml0eVtrZXldLnNjb3Blcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzY29wZXMgPSBfLm1lcmdlKHNjb3Blcywgc2luZ2xlT2F1dGgyU2VjdXJpdHlba2V5XS5zY29wZXMpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2luZ2xlU2VjdXJpdHlba2V5XSA9IGl0ZW1ba2V5XTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCFfLmlzRW1wdHkoc2luZ2xlU2VjdXJpdHkpKSB7XG4gICAgICAgICAgICAgICAgYXV0aHNBcnIucHVzaChzaW5nbGVTZWN1cml0eSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghXy5pc0VtcHR5KHNpbmdsZU9hdXRoMlNlY3VyaXR5KSl7XG4gICAgICAgICAgICAgICAgb2F1dGgyQXJyLnB1c2goc2luZ2xlT2F1dGgyU2VjdXJpdHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgYXV0aHMgOiBhdXRoc0FycixcbiAgICAgICAgICAgIG9hdXRoMjogb2F1dGgyQXJyLFxuICAgICAgICAgICAgc2NvcGVzOiBzY29wZXNcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgcGFyc2VPYXV0aDJTY29wZXM6IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgIHZhciBzY29wZXMgPSBPYmplY3QuYXNzaWduKHt9LCBkYXRhKTtcbiAgICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgICB2YXIga2V5O1xuXG4gICAgICAgIGZvciAoa2V5IGluIHNjb3Blcykge1xuICAgICAgICAgICAgcmVzdWx0LnB1c2goe3Njb3BlOiBrZXksIGRlc2NyaXB0aW9uOiBzY29wZXNba2V5XX0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9LFxuXG4gICAgc2FuaXRpemU6IGZ1bmN0aW9uKGh0bWwpIHtcbiAgICAgICAgLy8gU3RyaXAgdGhlIHNjcmlwdCB0YWdzIGZyb20gdGhlIGh0bWwgYW5kIGlubGluZSBldmVuaGFuZGxlcnNcbiAgICAgICAgaHRtbCA9IGh0bWwucmVwbGFjZSgvPHNjcmlwdFxcYltePF0qKD86KD8hPFxcL3NjcmlwdD4pPFtePF0qKSo8XFwvc2NyaXB0Pi9naSwgJycpO1xuICAgICAgICBodG1sID0gaHRtbC5yZXBsYWNlKC8ob25cXHcrPVwiW15cIl0qXCIpKihvblxcdys9J1teJ10qJykqKG9uXFx3Kz1cXHcqXFwoXFx3KlxcKSkqL2dpLCAnJyk7XG5cbiAgICAgICAgcmV0dXJuIGh0bWw7XG4gICAgfVxufTsiLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5Nb2RlbHMuQXBpS2V5QXV0aE1vZGVsID0gQmFja2JvbmUuTW9kZWwuZXh0ZW5kKHtcbiAgICBkZWZhdWx0czoge1xuICAgICAgICAnaW4nOiAnJyxcbiAgICAgICAgbmFtZTogJycsXG4gICAgICAgIHRpdGxlOiAnJyxcbiAgICAgICAgdmFsdWU6ICcnXG4gICAgfSxcblxuICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5vbignY2hhbmdlJywgdGhpcy52YWxpZGF0ZSk7XG4gICAgfSxcblxuICAgIHZhbGlkYXRlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB2YWxpZCA9ICEhdGhpcy5nZXQoJ3ZhbHVlJyk7XG5cbiAgICAgICAgdGhpcy5zZXQoJ3ZhbGlkJywgdmFsaWQpO1xuXG4gICAgICAgIHJldHVybiB2YWxpZDtcbiAgICB9XG59KTsiLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5BcGlLZXlBdXRoVmlldyA9IEJhY2tib25lLlZpZXcuZXh0ZW5kKHsgLy8gVE9ETzogYXBwZW5kIHRoaXMgdG8gZ2xvYmFsIFN3YWdnZXJVaVxuXG4gICAgZXZlbnRzOiB7XG4gICAgICAgICdjaGFuZ2UgLmlucHV0X2FwaUtleV9lbnRyeSc6ICdhcGlLZXlDaGFuZ2UnXG4gICAgfSxcblxuICAgIHNlbGVjdG9yczoge1xuICAgICAgICBhcGlrZXlJbnB1dDogJy5pbnB1dF9hcGlLZXlfZW50cnknXG4gICAgfSxcblxuICAgIHRlbXBsYXRlOiBIYW5kbGViYXJzLnRlbXBsYXRlcy5hcGlrZXlfYXV0aCxcblxuICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uKG9wdHMpIHtcbiAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0cyB8fCB7fTtcbiAgICAgICAgdGhpcy5yb3V0ZXIgPSB0aGlzLm9wdGlvbnMucm91dGVyO1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uICgpe1xuICAgICAgICB0aGlzLiRlbC5odG1sKHRoaXMudGVtcGxhdGUodGhpcy5tb2RlbC50b0pTT04oKSkpO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICBhcGlLZXlDaGFuZ2U6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIHZhciB2YWwgPSAkKGUudGFyZ2V0KS52YWwoKTtcbiAgICAgICAgaWYgKHZhbCkge1xuICAgICAgICAgICAgdGhpcy4kKHRoaXMuc2VsZWN0b3JzLmFwaWtleUlucHV0KS5yZW1vdmVDbGFzcygnZXJyb3InKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMubW9kZWwuc2V0KCd2YWx1ZScsIHZhbCk7XG4gICAgfSxcblxuICAgIGlzVmFsaWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubW9kZWwudmFsaWRhdGUoKTtcbiAgICB9LFxuXG4gICAgaGlnaGxpZ2h0SW52YWxpZDogZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIXRoaXMuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICB0aGlzLiQodGhpcy5zZWxlY3RvcnMuYXBpa2V5SW5wdXQpLmFkZENsYXNzKCdlcnJvcicpO1xuICAgICAgICB9XG4gICAgfVxuXG59KTsiLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5BdXRoQnV0dG9uVmlldyA9IEJhY2tib25lLlZpZXcuZXh0ZW5kKHtcbiAgICBldmVudHM6IHtcbiAgICAgICAgJ2NsaWNrIC5hdXRob3JpemVfX2J0bic6ICdhdXRob3JpemVCdG5DbGljaydcbiAgICB9LFxuXG4gICAgdHBsczoge1xuICAgICAgICBwb3B1cDogSGFuZGxlYmFycy50ZW1wbGF0ZXMucG9wdXAsXG4gICAgICAgIGF1dGhCdG46IEhhbmRsZWJhcnMudGVtcGxhdGVzLmF1dGhfYnV0dG9uLFxuICAgICAgICBhdXRoQnRuT3BlcmF0aW9uOiBIYW5kbGViYXJzLnRlbXBsYXRlcy5hdXRoX2J1dHRvbl9vcGVyYXRpb25cbiAgICB9LFxuXG4gICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24ob3B0cykge1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSBvcHRzIHx8IHt9O1xuICAgICAgICB0aGlzLm9wdGlvbnMuZGF0YSA9IHRoaXMub3B0aW9ucy5kYXRhIHx8IHt9O1xuICAgICAgICB0aGlzLmlzT3BlcmF0aW9uID0gdGhpcy5vcHRpb25zLmlzT3BlcmF0aW9uO1xuICAgICAgICB0aGlzLm1vZGVsID0gdGhpcy5tb2RlbCB8fCB7fTtcbiAgICAgICAgdGhpcy5yb3V0ZXIgPSB0aGlzLm9wdGlvbnMucm91dGVyO1xuICAgICAgICB0aGlzLmF1dGhzID0gdGhpcy5vcHRpb25zLmRhdGEub2F1dGgyLmNvbmNhdCh0aGlzLm9wdGlvbnMuZGF0YS5hdXRocyk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdHBsTmFtZSA9IHRoaXMuaXNPcGVyYXRpb24gPyAnYXV0aEJ0bk9wZXJhdGlvbicgOiAnYXV0aEJ0bic7XG5cbiAgICAgICAgdGhpcy4kYXV0aEVsID0gdGhpcy5yZW5kZXJBdXRocyh0aGlzLmF1dGhzKTtcbiAgICAgICAgdGhpcy4kZWwuaHRtbCh0aGlzLnRwbHNbdHBsTmFtZV0odGhpcy5tb2RlbCkpO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICBhdXRob3JpemVCdG5DbGljazogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgdmFyIGF1dGhzTW9kZWw7XG5cbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgIGF1dGhzTW9kZWwgPSB7XG4gICAgICAgICAgICB0aXRsZTogJ0F2YWlsYWJsZSBhdXRob3JpemF0aW9ucycsXG4gICAgICAgICAgICBjb250ZW50OiB0aGlzLiRhdXRoRWxcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBUaGUgY29udGVudCBvZiB0aGUgcG9wdXAgaXMgcmVtb3ZlZCBhbmQgYWxsIGV2ZW50cyB1bmJvdW5kIGFmdGVyIGNsaWNraW5nIHRoZSAnQ2FuY2VsJyBidXR0b24gb2YgdGhlIHBvcHVwLlxuICAgICAgICAvLyBXZSdsbCBoYXZlIHRvIHJlLXJlbmRlciB0aGUgY29udGVudHMgYmVmb3JlIGNyZWF0aW5nIGEgbmV3IHBvcHVwIHZpZXcuXG4gICAgICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgICAgICAgdGhpcy5wb3B1cCA9IG5ldyBTd2FnZ2VyVWkuVmlld3MuUG9wdXBWaWV3KHttb2RlbDogYXV0aHNNb2RlbH0pO1xuICAgICAgICB0aGlzLnBvcHVwLnJlbmRlcigpO1xuICAgIH0sXG5cbiAgICByZW5kZXJBdXRoczogZnVuY3Rpb24gKGF1dGhzKSB7XG4gICAgICAgIHZhciAkZWwgPSAkKCc8ZGl2PicpO1xuICAgICAgICB2YXIgaXNMb2dvdXQgPSBmYWxzZTtcblxuICAgICAgICBhdXRocy5mb3JFYWNoKGZ1bmN0aW9uIChhdXRoKSB7XG4gICAgICAgICAgICB2YXIgYXV0aFZpZXcgPSBuZXcgU3dhZ2dlclVpLlZpZXdzLkF1dGhWaWV3KHtkYXRhOiBhdXRoLCByb3V0ZXI6IHRoaXMucm91dGVyfSk7XG4gICAgICAgICAgICB2YXIgYXV0aEVsID0gYXV0aFZpZXcucmVuZGVyKCkuZWw7XG4gICAgICAgICAgICAkZWwuYXBwZW5kKGF1dGhFbCk7XG4gICAgICAgICAgICBpZiAoYXV0aFZpZXcuaXNMb2dvdXQpIHtcbiAgICAgICAgICAgICAgICBpc0xvZ291dCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIHRoaXMpO1xuXG4gICAgICAgIHRoaXMubW9kZWwuaXNMb2dvdXQgPSBpc0xvZ291dDtcblxuICAgICAgICByZXR1cm4gJGVsO1xuICAgIH1cblxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5Db2xsZWN0aW9ucy5BdXRoc0NvbGxlY3Rpb24gPSBCYWNrYm9uZS5Db2xsZWN0aW9uLmV4dGVuZCh7XG4gICAgY29uc3RydWN0b3I6IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG5cbiAgICAgICAgYXJnc1swXSA9IHRoaXMucGFyc2UoYXJnc1swXSk7XG5cbiAgICAgICAgQmFja2JvbmUuQ29sbGVjdGlvbi5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9LFxuXG4gICAgYWRkOiBmdW5jdGlvbiAobW9kZWwpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KG1vZGVsKSkge1xuICAgICAgICAgICAgYXJnc1swXSA9IF8ubWFwKG1vZGVsLCBmdW5jdGlvbih2YWwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5oYW5kbGVPbmUodmFsKTtcbiAgICAgICAgICAgIH0sIHRoaXMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYXJnc1swXSA9IHRoaXMuaGFuZGxlT25lKG1vZGVsKTtcbiAgICAgICAgfVxuXG4gICAgICAgIEJhY2tib25lLkNvbGxlY3Rpb24ucHJvdG90eXBlLmFkZC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9LFxuXG4gICAgaGFuZGxlT25lOiBmdW5jdGlvbiAobW9kZWwpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IG1vZGVsO1xuXG4gICAgICAgIGlmICghIChtb2RlbCBpbnN0YW5jZW9mIEJhY2tib25lLk1vZGVsKSApIHtcbiAgICAgICAgICAgIHN3aXRjaCAobW9kZWwudHlwZSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ29hdXRoMic6XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBTd2FnZ2VyVWkuTW9kZWxzLk9hdXRoMk1vZGVsKG1vZGVsKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnYmFzaWMnOlxuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBuZXcgU3dhZ2dlclVpLk1vZGVscy5CYXNpY0F1dGhNb2RlbChtb2RlbCk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ2FwaUtleSc6XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBTd2FnZ2VyVWkuTW9kZWxzLkFwaUtleUF1dGhNb2RlbChtb2RlbCk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBCYWNrYm9uZS5Nb2RlbChtb2RlbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0sXG5cbiAgICBpc1ZhbGlkOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB2YWxpZCA9IHRydWU7XG5cbiAgICAgICAgdGhpcy5tb2RlbHMuZm9yRWFjaChmdW5jdGlvbihtb2RlbCkge1xuICAgICAgICAgICAgaWYgKCFtb2RlbC52YWxpZGF0ZSgpKSB7XG4gICAgICAgICAgICAgICAgdmFsaWQgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHZhbGlkO1xuICAgIH0sXG5cbiAgICBpc0F1dGhvcml6ZWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubGVuZ3RoID09PSB0aGlzLndoZXJlKHsgaXNMb2dvdXQ6IHRydWUgfSkubGVuZ3RoO1xuICAgIH0sXG5cbiAgICBpc1BhcnRpYWxseUF1dGhvcml6ZWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2hlcmUoeyBpc0xvZ291dDogdHJ1ZSB9KS5sZW5ndGggPiAwO1xuICAgIH0sXG5cbiAgICBwYXJzZTogZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgdmFyIGF1dGh6ID0ge307XG5cbiAgICAgICAgaWYodHlwZW9mIHdpbmRvdy5zd2FnZ2VyVWkgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBhdXRoeiA9IE9iamVjdC5hc3NpZ24oe30sIHdpbmRvdy5zd2FnZ2VyVWkuYXBpLmNsaWVudEF1dGhvcml6YXRpb25zLmF1dGh6KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBfLm1hcChkYXRhLCBmdW5jdGlvbiAoYXV0aCwgbmFtZSkge1xuICAgICAgICAgICAgdmFyIGlzQmFzaWMgPSBhdXRoeltuYW1lXSAmJiBhdXRoLnR5cGUgPT09ICdiYXNpYycgJiYgYXV0aHpbbmFtZV0udXNlcm5hbWUgJiYgYXV0aHpbbmFtZV0ucGFzc3dvcmQ7XG5cbiAgICAgICAgICAgIF8uZXh0ZW5kKGF1dGgsIHtcbiAgICAgICAgICAgICAgICB0aXRsZTogbmFtZVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGlmIChhdXRoeltuYW1lXSB8fCBpc0Jhc2ljKSB7XG4gICAgICAgICAgICAgICAgXy5leHRlbmQoYXV0aCwge1xuICAgICAgICAgICAgICAgICAgICBpc0xvZ291dDogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGlzQmFzaWMgPyB1bmRlZmluZWQgOiBhdXRoeltuYW1lXS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgdXNlcm5hbWU6IGlzQmFzaWMgPyBhdXRoeltuYW1lXS51c2VybmFtZSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgcGFzc3dvcmQ6IGlzQmFzaWMgPyBhdXRoeltuYW1lXS5wYXNzd29yZCA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgdmFsaWQ6IHRydWVcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGF1dGg7XG4gICAgICAgIH0pO1xuICAgIH1cbn0pOyIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLlZpZXdzLkF1dGhzQ29sbGVjdGlvblZpZXcgPSBCYWNrYm9uZS5WaWV3LmV4dGVuZCh7XG5cbiAgICBpbml0aWFsaXplOiBmdW5jdGlvbihvcHRzKSB7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdHMgfHwge307XG4gICAgICAgIHRoaXMub3B0aW9ucy5kYXRhID0gdGhpcy5vcHRpb25zLmRhdGEgfHwge307XG4gICAgICAgIHRoaXMucm91dGVyID0gdGhpcy5vcHRpb25zLnJvdXRlcjtcblxuICAgICAgICB0aGlzLmNvbGxlY3Rpb24gPSBuZXcgU3dhZ2dlclVpLkNvbGxlY3Rpb25zLkF1dGhzQ29sbGVjdGlvbihvcHRzLmRhdGEpO1xuXG4gICAgICAgIHRoaXMuJGlubmVyRWwgPSAkKCc8ZGl2PicpO1xuICAgICAgICB0aGlzLmF1dGhWaWV3cyA9IFtdO1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5jb2xsZWN0aW9uLmVhY2goZnVuY3Rpb24gKGF1dGgpIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyT25lQXV0aChhdXRoKTtcbiAgICAgICAgfSwgdGhpcyk7XG5cbiAgICAgICAgdGhpcy4kZWwuaHRtbCh0aGlzLiRpbm5lckVsLmh0bWwoKSA/IHRoaXMuJGlubmVyRWwgOiAnJyk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIHJlbmRlck9uZUF1dGg6IGZ1bmN0aW9uIChhdXRoTW9kZWwpIHtcbiAgICAgICAgdmFyIGF1dGhWaWV3RWwsIGF1dGhWaWV3LCBhdXRoVmlld05hbWU7XG4gICAgICAgIHZhciB0eXBlID0gYXV0aE1vZGVsLmdldCgndHlwZScpO1xuXG4gICAgICAgIGlmICh0eXBlID09PSAnYXBpS2V5Jykge1xuICAgICAgICAgICAgYXV0aFZpZXdOYW1lID0gJ0FwaUtleUF1dGhWaWV3JztcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnYmFzaWMnICYmIHRoaXMuJGlubmVyRWwuZmluZCgnLmJhc2ljX2F1dGhfY29udGFpbmVyJykubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICBhdXRoVmlld05hbWUgPSAnQmFzaWNBdXRoVmlldyc7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ29hdXRoMicpIHtcbiAgICAgICAgICAgIGF1dGhWaWV3TmFtZSA9ICdPYXV0aDJWaWV3JztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChhdXRoVmlld05hbWUpIHtcbiAgICAgICAgICAgIGF1dGhWaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3c1thdXRoVmlld05hbWVdKHttb2RlbDogYXV0aE1vZGVsLCByb3V0ZXI6IHRoaXMucm91dGVyfSk7XG4gICAgICAgICAgICBhdXRoVmlld0VsID0gYXV0aFZpZXcucmVuZGVyKCkuZWw7XG4gICAgICAgICAgICB0aGlzLmF1dGhWaWV3cy5wdXNoKGF1dGhWaWV3KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuJGlubmVyRWwuYXBwZW5kKGF1dGhWaWV3RWwpO1xuICAgIH0sXG5cbiAgICBoaWdobGlnaHRJbnZhbGlkOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuYXV0aFZpZXdzLmZvckVhY2goZnVuY3Rpb24gKHZpZXcpIHtcbiAgICAgICAgICAgIHZpZXcuaGlnaGxpZ2h0SW52YWxpZCgpO1xuICAgICAgICB9LCB0aGlzKTtcbiAgICB9XG5cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiBnbG9iYWwgcmVkaXJlY3RfdXJpOnRydWUgKi9cbi8qIGdsb2JhbCBjbGllbnRJZCAqL1xuLyogZ2xvYmFsIHNjb3BlU2VwYXJhdG9yICovXG4vKiBnbG9iYWwgYWRkaXRpb25hbFF1ZXJ5U3RyaW5nUGFyYW1zICovXG4vKiBnbG9iYWwgY2xpZW50U2VjcmV0ICovXG4vKiBnbG9iYWwgb25PQXV0aENvbXBsZXRlICovXG4vKiBnbG9iYWwgcmVhbG0gKi9cbi8qanNoaW50IHVudXNlZDpmYWxzZSovXG5cblN3YWdnZXJVaS5WaWV3cy5BdXRoVmlldyA9IEJhY2tib25lLlZpZXcuZXh0ZW5kKHtcbiAgICBldmVudHM6IHtcbiAgICAgICAgJ2NsaWNrIC5hdXRoX3N1Ym1pdF9fYnV0dG9uJzogJ2F1dGhvcml6ZUNsaWNrJyxcbiAgICAgICAgJ2NsaWNrIC5hdXRoX2xvZ291dF9fYnV0dG9uJzogJ2xvZ291dENsaWNrJ1xuICAgIH0sXG5cbiAgICB0cGxzOiB7XG4gICAgICAgIG1haW46IEhhbmRsZWJhcnMudGVtcGxhdGVzLmF1dGhfdmlld1xuICAgIH0sXG5cbiAgICBzZWxlY3RvcnM6IHtcbiAgICAgICAgaW5uZXJFbDogJy5hdXRoX2lubmVyJyxcbiAgICAgICAgYXV0aEJ0bjogJy5hdXRoX3N1Ym1pdF9fYnV0dG9uJ1xuICAgIH0sXG5cbiAgICBpbml0aWFsaXplOiBmdW5jdGlvbihvcHRzKSB7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdHMgfHwge307XG4gICAgICAgIG9wdHMuZGF0YSA9IG9wdHMuZGF0YSB8fCB7fTtcbiAgICAgICAgdGhpcy5yb3V0ZXIgPSB0aGlzLm9wdGlvbnMucm91dGVyO1xuXG4gICAgICAgIHRoaXMuYXV0aHNDb2xsZWN0aW9uVmlldyA9IG5ldyBTd2FnZ2VyVWkuVmlld3MuQXV0aHNDb2xsZWN0aW9uVmlldyh7ZGF0YTogb3B0cy5kYXRhfSk7XG5cbiAgICAgICAgdGhpcy4kZWwuaHRtbCh0aGlzLnRwbHMubWFpbih7XG4gICAgICAgICAgICBpc0xvZ291dDogdGhpcy5hdXRoc0NvbGxlY3Rpb25WaWV3LmNvbGxlY3Rpb24uaXNBdXRob3JpemVkKCksXG4gICAgICAgICAgICBpc0F1dGhvcml6ZWQ6IHRoaXMuYXV0aHNDb2xsZWN0aW9uVmlldy5jb2xsZWN0aW9uLmlzUGFydGlhbGx5QXV0aG9yaXplZCgpXG4gICAgICAgIH0pKTtcbiAgICAgICAgdGhpcy4kaW5uZXJFbCA9IHRoaXMuJCh0aGlzLnNlbGVjdG9ycy5pbm5lckVsKTtcbiAgICAgICAgdGhpcy5pc0xvZ291dCA9IHRoaXMuYXV0aHNDb2xsZWN0aW9uVmlldy5jb2xsZWN0aW9uLmlzUGFydGlhbGx5QXV0aG9yaXplZCgpO1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy4kaW5uZXJFbC5odG1sKHRoaXMuYXV0aHNDb2xsZWN0aW9uVmlldy5yZW5kZXIoKS5lbCk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIGF1dGhvcml6ZUNsaWNrOiBmdW5jdGlvbiAoZSkge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICAgICAgaWYgKHRoaXMuYXV0aHNDb2xsZWN0aW9uVmlldy5jb2xsZWN0aW9uLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgdGhpcy5hdXRob3JpemUoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuYXV0aHNDb2xsZWN0aW9uVmlldy5oaWdobGlnaHRJbnZhbGlkKCk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgYXV0aG9yaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuYXV0aHNDb2xsZWN0aW9uVmlldy5jb2xsZWN0aW9uLmZvckVhY2goZnVuY3Rpb24gKGF1dGgpIHtcbiAgICAgICAgICAgIHZhciBrZXlBdXRoLCBiYXNpY0F1dGg7XG4gICAgICAgICAgICB2YXIgdHlwZSA9IGF1dGguZ2V0KCd0eXBlJyk7XG5cbiAgICAgICAgICAgIGlmICh0eXBlID09PSAnYXBpS2V5Jykge1xuICAgICAgICAgICAgICAgIGtleUF1dGggPSBuZXcgU3dhZ2dlckNsaWVudC5BcGlLZXlBdXRob3JpemF0aW9uKFxuICAgICAgICAgICAgICAgICAgICBhdXRoLmdldCgnbmFtZScpLFxuICAgICAgICAgICAgICAgICAgICBhdXRoLmdldCgndmFsdWUnKSxcbiAgICAgICAgICAgICAgICAgICAgYXV0aC5nZXQoJ2luJylcbiAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5yb3V0ZXIuYXBpLmNsaWVudEF1dGhvcml6YXRpb25zLmFkZChhdXRoLmdldCgndGl0bGUnKSwga2V5QXV0aCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdiYXNpYycpIHtcbiAgICAgICAgICAgICAgICBiYXNpY0F1dGggPSBuZXcgU3dhZ2dlckNsaWVudC5QYXNzd29yZEF1dGhvcml6YXRpb24oYXV0aC5nZXQoJ3VzZXJuYW1lJyksIGF1dGguZ2V0KCdwYXNzd29yZCcpKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJvdXRlci5hcGkuY2xpZW50QXV0aG9yaXphdGlvbnMuYWRkKGF1dGguZ2V0KCd0aXRsZScpLCBiYXNpY0F1dGgpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnb2F1dGgyJykge1xuICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlT2F1dGgyTG9naW4oYXV0aCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIHRoaXMpO1xuXG4gICAgICAgIHRoaXMucm91dGVyLmxvYWQoKTtcbiAgICB9LFxuXG4gICAgbG9nb3V0Q2xpY2s6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICB0aGlzLmF1dGhzQ29sbGVjdGlvblZpZXcuY29sbGVjdGlvbi5mb3JFYWNoKGZ1bmN0aW9uIChhdXRoKSB7XG4gICAgICAgICAgICB3aW5kb3cuc3dhZ2dlclVpLmFwaS5jbGllbnRBdXRob3JpemF0aW9ucy5yZW1vdmUoYXV0aC5nZXQoJ3RpdGxlJykpO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLnJvdXRlci5sb2FkKCk7XG4gICAgfSxcblxuICAgIC8vIHRha2VuIGZyb20gbGliL3N3YWdnZXItb2F1dGguanNcbiAgICBoYW5kbGVPYXV0aDJMb2dpbjogZnVuY3Rpb24gKGF1dGgpIHtcbiAgICAgICAgdmFyIGhvc3QgPSB3aW5kb3cubG9jYXRpb247XG4gICAgICAgIHZhciBwYXRobmFtZSA9IGxvY2F0aW9uLnBhdGhuYW1lLnN1YnN0cmluZygwLCBsb2NhdGlvbi5wYXRobmFtZS5sYXN0SW5kZXhPZignLycpKTtcbiAgICAgICAgdmFyIGRlZmF1bHRSZWRpcmVjdFVybCA9IGhvc3QucHJvdG9jb2wgKyAnLy8nICsgaG9zdC5ob3N0ICsgcGF0aG5hbWUgKyAnL28yYy5odG1sJztcbiAgICAgICAgdmFyIHJlZGlyZWN0VXJsID0gd2luZG93Lm9BdXRoUmVkaXJlY3RVcmwgfHwgZGVmYXVsdFJlZGlyZWN0VXJsO1xuICAgICAgICB2YXIgdXJsID0gbnVsbDtcbiAgICAgICAgdmFyIHNjb3BlcyA9IF8ubWFwKGF1dGguZ2V0KCdzY29wZXMnKSwgZnVuY3Rpb24gKHNjb3BlKSB7XG4gICAgICAgICAgICBpZihzY29wZS5jaGVja2VkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjb3BlLnNjb3BlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdmFyIGNvbnRhaW5lciA9IHdpbmRvdy5zd2FnZ2VyVWlBdXRoIHx8ICh3aW5kb3cuc3dhZ2dlclVpQXV0aCA9IHt9KTtcbiAgICAgICAgdmFyIHN0YXRlLCBkZXRzLCBlcDtcbiAgICAgICAgY29udGFpbmVyLk9BdXRoU2NoZW1lS2V5ID0gYXV0aC5nZXQoJ3RpdGxlJyk7XG5cbiAgICAgICAgd2luZG93LmVuYWJsZWRTY29wZXMgPSBzY29wZXM7XG4gICAgICAgIHZhciBmbG93ID0gYXV0aC5nZXQoJ2Zsb3cnKTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgYWNjZXNzIHRva2VuIHBhcmFtZXRlciByZXR1cm5lZCBieSB0aGUgc2VydmVyLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0gZGV0c1xuICAgICAgICAgKiAgICAgVGhlIGF1dGhvcmlzYXRpb24gc2NoZW1lIGNvbmZpZ3VyYXRpb24uXG4gICAgICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIGFjY2VzcyB0b2tlbiBwYXJhbWV0ZXJcbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIGdldFRva2VuTmFtZShkZXRzKSB7XG4gICAgICAgICAgICByZXR1cm4gZGV0cy52ZW5kb3JFeHRlbnNpb25zWyd4LXRva2VuTmFtZSddIHx8IGRldHMudG9rZW5OYW1lO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYoYXV0aC5nZXQoJ3R5cGUnKSA9PT0gJ29hdXRoMicgJiYgZmxvdyAmJiAoZmxvdyA9PT0gJ2ltcGxpY2l0JyB8fCBmbG93ID09PSAnYWNjZXNzQ29kZScpKSB7XG4gICAgICAgICAgICBkZXRzID0gYXV0aC5hdHRyaWJ1dGVzO1xuICAgICAgICAgICAgdXJsID0gZGV0cy5hdXRob3JpemF0aW9uVXJsICsgJz9yZXNwb25zZV90eXBlPScgKyAoZmxvdyA9PT0gJ2ltcGxpY2l0JyA/ICd0b2tlbicgOiAnY29kZScpO1xuICAgICAgICAgICAgY29udGFpbmVyLnRva2VuTmFtZSA9IGdldFRva2VuTmFtZShkZXRzKSB8fCAnYWNjZXNzX3Rva2VuJztcbiAgICAgICAgICAgIGNvbnRhaW5lci50b2tlblVybCA9IChmbG93ID09PSAnYWNjZXNzQ29kZScgPyBkZXRzLnRva2VuVXJsIDogbnVsbCk7XG4gICAgICAgICAgICBzdGF0ZSA9IGNvbnRhaW5lci5PQXV0aFNjaGVtZUtleTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmKGF1dGguZ2V0KCd0eXBlJykgPT09ICdvYXV0aDInICYmIGZsb3cgJiYgKGZsb3cgPT09ICdhcHBsaWNhdGlvbicpKSB7XG4gICAgICAgICAgICBkZXRzID0gYXV0aC5hdHRyaWJ1dGVzO1xuICAgICAgICAgICAgY29udGFpbmVyLnRva2VuTmFtZSA9IGdldFRva2VuTmFtZShkZXRzKSB8fCAnYWNjZXNzX3Rva2VuJztcbiAgICAgICAgICAgIHRoaXMuY2xpZW50Q3JlZGVudGlhbHNGbG93KHNjb3BlcywgZGV0cywgY29udGFpbmVyLk9BdXRoU2NoZW1lS2V5KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmKGF1dGguZ2V0KCd0eXBlJykgPT09ICdvYXV0aDInICYmIGZsb3cgJiYgKGZsb3cgPT09ICdwYXNzd29yZCcpKSB7XG4gICAgICAgICAgICBkZXRzID0gYXV0aC5hdHRyaWJ1dGVzO1xuICAgICAgICAgICAgY29udGFpbmVyLnRva2VuTmFtZSA9IGdldFRva2VuTmFtZShkZXRzKSB8fCAnYWNjZXNzX3Rva2VuJztcbiAgICAgICAgICAgIHRoaXMucGFzc3dvcmRGbG93KHNjb3BlcywgZGV0cywgY29udGFpbmVyLk9BdXRoU2NoZW1lS2V5KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmKGF1dGguZ2V0KCdncmFudFR5cGVzJykpIHtcbiAgICAgICAgICAgIC8vIDEuMiBzdXBwb3J0XG4gICAgICAgICAgICB2YXIgbyA9IGF1dGguZ2V0KCdncmFudFR5cGVzJyk7XG4gICAgICAgICAgICBmb3IodmFyIHQgaW4gbykge1xuICAgICAgICAgICAgICAgIGlmKG8uaGFzT3duUHJvcGVydHkodCkgJiYgdCA9PT0gJ2ltcGxpY2l0Jykge1xuICAgICAgICAgICAgICAgICAgICBkZXRzID0gb1t0XTtcbiAgICAgICAgICAgICAgICAgICAgZXAgPSBkZXRzLmxvZ2luRW5kcG9pbnQudXJsO1xuICAgICAgICAgICAgICAgICAgICB1cmwgPSBkZXRzLmxvZ2luRW5kcG9pbnQudXJsICsgJz9yZXNwb25zZV90eXBlPXRva2VuJztcbiAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyLnRva2VuTmFtZSA9IGdldFRva2VuTmFtZShkZXRzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoby5oYXNPd25Qcm9wZXJ0eSh0KSAmJiB0ID09PSAnYWNjZXNzQ29kZScpIHtcbiAgICAgICAgICAgICAgICAgICAgZGV0cyA9IG9bdF07XG4gICAgICAgICAgICAgICAgICAgIGVwID0gZGV0cy50b2tlblJlcXVlc3RFbmRwb2ludC51cmw7XG4gICAgICAgICAgICAgICAgICAgIHVybCA9IGRldHMudG9rZW5SZXF1ZXN0RW5kcG9pbnQudXJsICsgJz9yZXNwb25zZV90eXBlPWNvZGUnO1xuICAgICAgICAgICAgICAgICAgICBjb250YWluZXIudG9rZW5OYW1lID0gZ2V0VG9rZW5OYW1lKGRldHMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJlZGlyZWN0X3VyaSA9IHJlZGlyZWN0VXJsO1xuXG4gICAgICAgIHVybCArPSAnJnJlZGlyZWN0X3VyaT0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHJlZGlyZWN0VXJsKTtcbiAgICAgICAgdXJsICs9ICcmcmVhbG09JyArIGVuY29kZVVSSUNvbXBvbmVudChyZWFsbSk7XG4gICAgICAgIHVybCArPSAnJmNsaWVudF9pZD0nICsgZW5jb2RlVVJJQ29tcG9uZW50KGNsaWVudElkKTtcbiAgICAgICAgdXJsICs9ICcmc2NvcGU9JyArIGVuY29kZVVSSUNvbXBvbmVudChzY29wZXMuam9pbihzY29wZVNlcGFyYXRvcikpO1xuICAgICAgICB1cmwgKz0gJyZzdGF0ZT0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHN0YXRlKTtcbiAgICAgICAgZm9yICh2YXIga2V5IGluIGFkZGl0aW9uYWxRdWVyeVN0cmluZ1BhcmFtcykge1xuICAgICAgICAgICAgdXJsICs9ICcmJyArIGtleSArICc9JyArIGVuY29kZVVSSUNvbXBvbmVudChhZGRpdGlvbmFsUXVlcnlTdHJpbmdQYXJhbXNba2V5XSk7XG4gICAgICAgIH1cblxuICAgICAgICB3aW5kb3cub3Blbih1cmwpO1xuICAgIH0sXG5cbiAgICAvLyB0YWtlbiBmcm9tIGxpYi9zd2FnZ2VyLW9hdXRoLmpzXG4gICAgY2xpZW50Q3JlZGVudGlhbHNGbG93OiBmdW5jdGlvbiAoc2NvcGVzLCBvYXV0aCwgT0F1dGhTY2hlbWVLZXkpIHtcbiAgICAgICAgdGhpcy5hY2Nlc3NUb2tlblJlcXVlc3Qoc2NvcGVzLCBvYXV0aCwgT0F1dGhTY2hlbWVLZXksICdjbGllbnRfY3JlZGVudGlhbHMnKTtcbiAgICB9LFxuXG4gICAgcGFzc3dvcmRGbG93OiBmdW5jdGlvbiAoc2NvcGVzLCBvYXV0aCwgT0F1dGhTY2hlbWVLZXkpIHtcbiAgICAgICAgdGhpcy5hY2Nlc3NUb2tlblJlcXVlc3Qoc2NvcGVzLCBvYXV0aCwgT0F1dGhTY2hlbWVLZXksICdwYXNzd29yZCcsIHtcbiAgICAgICAgICAgICd1c2VybmFtZSc6IG9hdXRoLnVzZXJuYW1lLFxuICAgICAgICAgICAgJ3Bhc3N3b3JkJzogb2F1dGgucGFzc3dvcmRcbiAgICAgICAgfSk7XG4gICAgfSxcblxuICAgIGFjY2Vzc1Rva2VuUmVxdWVzdDogZnVuY3Rpb24gKHNjb3Blcywgb2F1dGgsIE9BdXRoU2NoZW1lS2V5LCBncmFudFR5cGUsIHBhcmFtcykge1xuICAgICAgICBwYXJhbXMgPSAkLmV4dGVuZCh7fSwge1xuICAgICAgICAgICAgJ3Njb3BlJzogc2NvcGVzLmpvaW4oJyAnKSxcbiAgICAgICAgICAgICdncmFudF90eXBlJzogZ3JhbnRUeXBlXG4gICAgICAgIH0sIHBhcmFtcyk7XG5cbiAgICAgICAgdmFyIGhlYWRlcnM9IHt9O1xuXG4gICAgICAgIHN3aXRjaCAob2F1dGguY2xpZW50QXV0aGVudGljYXRpb25UeXBlKSB7XG4gICAgICAgICAgICBjYXNlICdiYXNpYyc6XG4gICAgICAgICAgICAgICAgaGVhZGVycy5BdXRob3JpemF0aW9uID0gJ0Jhc2ljICcgKyBidG9hKG9hdXRoLmNsaWVudElkICsgJzonICsgb2F1dGguY2xpZW50U2VjcmV0KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ3JlcXVlc3QtYm9keSc6XG4gICAgICAgICAgICAgICAgcGFyYW1zLmNsaWVudF9pZCA9IG9hdXRoLmNsaWVudElkO1xuICAgICAgICAgICAgICAgIHBhcmFtcy5jbGllbnRfc2VjcmV0ID0gb2F1dGguY2xpZW50U2VjcmV0O1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgJC5hamF4KHtcbiAgICAgICAgICAgIHVybCA6IG9hdXRoLnRva2VuVXJsLFxuICAgICAgICAgICAgdHlwZTogJ1BPU1QnLFxuICAgICAgICAgICAgZGF0YTogcGFyYW1zLFxuICAgICAgICAgICAgaGVhZGVyczogaGVhZGVycyxcbiAgICAgICAgICAgIHN1Y2Nlc3M6IGZ1bmN0aW9uIChkYXRhKVxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIG9uT0F1dGhDb21wbGV0ZShkYXRhLCBPQXV0aFNjaGVtZUtleSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZXJyb3I6IGZ1bmN0aW9uICgpXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgb25PQXV0aENvbXBsZXRlKCcnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5Nb2RlbHMuQmFzaWNBdXRoTW9kZWwgPSBCYWNrYm9uZS5Nb2RlbC5leHRlbmQoe1xuICAgIGRlZmF1bHRzOiB7XG4gICAgICAgIHVzZXJuYW1lOiAnJyxcbiAgICAgICAgcGFzc3dvcmQ6ICcnLFxuICAgICAgICB0aXRsZTogJ2Jhc2ljJ1xuICAgIH0sXG5cbiAgICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMub24oJ2NoYW5nZScsIHRoaXMudmFsaWRhdGUpO1xuICAgIH0sXG5cbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdmFsaWQgPSAhIXRoaXMuZ2V0KCdwYXNzd29yZCcpICYmICEhdGhpcy5nZXQoJ3VzZXJuYW1lJyk7XG5cbiAgICAgICAgdGhpcy5zZXQoJ3ZhbGlkJywgdmFsaWQpO1xuXG4gICAgICAgIHJldHVybiB2YWxpZDtcbiAgICB9XG59KTsiLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5CYXNpY0F1dGhWaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoe1xuXG4gICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKG9wdHMpIHtcbiAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0cyB8fCB7fTtcbiAgICAgICAgdGhpcy5yb3V0ZXIgPSB0aGlzLm9wdGlvbnMucm91dGVyO1xuICAgIH0sXG5cbiAgICBldmVudHM6IHtcbiAgICAgICAgJ2NoYW5nZSAuYXV0aF9pbnB1dCc6ICdpbnB1dENoYW5nZSdcbiAgICB9LFxuXG4gICAgc2VsZWN0b3JzOiB7XG4gICAgICAgIHVzZXJuYW1lSW5wdXQ6ICcuYmFzaWNfYXV0aF9fdXNlcm5hbWUnLFxuICAgICAgICBwYXNzd29yZElucHV0OiAnLmJhc2ljX2F1dGhfX3Bhc3N3b3JkJ1xuICAgIH0sXG5cbiAgICBjbHM6IHtcbiAgICAgICAgZXJyb3I6ICdlcnJvcidcbiAgICB9LFxuXG4gICAgdGVtcGxhdGU6IEhhbmRsZWJhcnMudGVtcGxhdGVzLmJhc2ljX2F1dGgsXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uKCl7XG4gICAgICAgICQodGhpcy5lbCkuaHRtbCh0aGlzLnRlbXBsYXRlKHRoaXMubW9kZWwudG9KU09OKCkpKTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgaW5wdXRDaGFuZ2U6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIHZhciAkZWwgPSAkKGUudGFyZ2V0KTtcbiAgICAgICAgdmFyIHZhbCA9ICRlbC52YWwoKTtcbiAgICAgICAgdmFyIGF0dHIgPSAkZWwucHJvcCgnbmFtZScpO1xuXG4gICAgICAgIGlmICh2YWwpIHtcbiAgICAgICAgICAgICRlbC5yZW1vdmVDbGFzcyh0aGlzLmNscy5lcnJvcik7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLm1vZGVsLnNldChhdHRyLCB2YWwpO1xuICAgIH0sXG5cbiAgICBpc1ZhbGlkOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1vZGVsLnZhbGlkYXRlKCk7XG4gICAgfSxcblxuICAgIGhpZ2hsaWdodEludmFsaWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKCF0aGlzLm1vZGVsLmdldCgndXNlcm5hbWUnKSkge1xuICAgICAgICAgICAgdGhpcy4kKHRoaXMuc2VsZWN0b3JzLnVzZXJuYW1lSW5wdXQpLmFkZENsYXNzKHRoaXMuY2xzLmVycm9yKTtcbiAgICAgICAgfVxuICAgIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5Td2FnZ2VyVWkuVmlld3MuQ29udGVudFR5cGVWaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoe1xuICBpbml0aWFsaXplOiBmdW5jdGlvbigpIHt9LFxuXG4gIHJlbmRlcjogZnVuY3Rpb24oKXtcbiAgXHR0aGlzLm1vZGVsLmNvbnRlbnRUeXBlSWQgPSAnY3QnICsgTWF0aC5yYW5kb20oKTtcbiAgICAkKHRoaXMuZWwpLmh0bWwoSGFuZGxlYmFycy50ZW1wbGF0ZXMuY29udGVudF90eXBlKHRoaXMubW9kZWwpKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxufSk7IiwiJ3VzZSBzdHJpY3QnO1xuXG5Td2FnZ2VyVWkuVmlld3MuSGVhZGVyVmlldyA9IEJhY2tib25lLlZpZXcuZXh0ZW5kKHtcbiAgZXZlbnRzOiB7XG4gICAgJ2NsaWNrICNzaG93LXBldC1zdG9yZS1pY29uJyAgICA6ICdzaG93UGV0U3RvcmUnLFxuICAgICdjbGljayAjZXhwbG9yZScgICAgICAgICAgICAgICAgOiAnc2hvd0N1c3RvbScsXG4gICAgJ3N1Ym1pdCAjYXBpX3NlbGVjdG9yJyAgICAgICAgICA6ICdzaG93Q3VzdG9tJyxcbiAgICAna2V5dXAgI2lucHV0X2Jhc2VVcmwnICAgICAgICAgIDogJ3Nob3dDdXN0b21PbktleXVwJyxcbiAgICAna2V5dXAgI2lucHV0X2FwaUtleScgICAgICAgICAgIDogJ3Nob3dDdXN0b21PbktleXVwJ1xuICB9LFxuXG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uKCl7fSxcblxuICBzaG93UGV0U3RvcmU6IGZ1bmN0aW9uKCl7XG4gICAgdGhpcy50cmlnZ2VyKCd1cGRhdGUtc3dhZ2dlci11aScsIHtcbiAgICAgIHVybDonaHR0cDovL3BldHN0b3JlLnN3YWdnZXIuaW8vdjIvc3dhZ2dlci5qc29uJ1xuICAgIH0pO1xuICB9LFxuXG4gIHNob3dDdXN0b21PbktleXVwOiBmdW5jdGlvbihlKXtcbiAgICBpZiAoZS5rZXlDb2RlID09PSAxMykge1xuICAgICAgdGhpcy5zaG93Q3VzdG9tKCk7XG4gICAgfVxuICB9LFxuXG4gIHNob3dDdXN0b206IGZ1bmN0aW9uKGUpe1xuICAgIGlmIChlKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuXG4gICAgdGhpcy50cmlnZ2VyKCd1cGRhdGUtc3dhZ2dlci11aScsIHtcbiAgICAgIHVybDogJCgnI2lucHV0X2Jhc2VVcmwnKS52YWwoKVxuICAgIH0pO1xuICB9LFxuXG4gIHVwZGF0ZTogZnVuY3Rpb24odXJsLCBhcGlLZXksIHRyaWdnZXIpe1xuICAgIGlmICh0cmlnZ2VyID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRyaWdnZXIgPSBmYWxzZTtcbiAgICB9XG5cbiAgICAkKCcjaW5wdXRfYmFzZVVybCcpLnZhbCh1cmwpO1xuXG4gICAgaWYgKHRyaWdnZXIpIHtcbiAgICAgIHRoaXMudHJpZ2dlcigndXBkYXRlLXN3YWdnZXItdWknLCB7dXJsOnVybH0pO1xuICAgIH1cbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5NYWluVmlldyA9IEJhY2tib25lLlZpZXcuZXh0ZW5kKHtcbiAgYXBpc1NvcnRlciA6IHtcbiAgICBhbHBoYSAgIDogZnVuY3Rpb24oYSxiKXsgcmV0dXJuIGEubmFtZS5sb2NhbGVDb21wYXJlKGIubmFtZSk7IH1cbiAgfSxcbiAgb3BlcmF0aW9uc1NvcnRlcnMgOiB7XG4gICAgYWxwaGEgICA6IGZ1bmN0aW9uKGEsYil7IHJldHVybiBhLnBhdGgubG9jYWxlQ29tcGFyZShiLnBhdGgpOyB9LFxuICAgIG1ldGhvZCAgOiBmdW5jdGlvbihhLGIpeyByZXR1cm4gYS5tZXRob2QubG9jYWxlQ29tcGFyZShiLm1ldGhvZCk7IH1cbiAgfSxcbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24ob3B0cyl7XG4gICAgdmFyIHNvcnRlck9wdGlvbiwgc29ydGVyRm4sIGtleSwgdmFsdWU7XG4gICAgb3B0cyA9IG9wdHMgfHwge307XG5cbiAgICB0aGlzLnJvdXRlciA9IG9wdHMucm91dGVyO1xuXG4gICAgLy8gU29ydCBBUElzXG4gICAgaWYgKG9wdHMuc3dhZ2dlck9wdGlvbnMuYXBpc1NvcnRlcikge1xuICAgICAgc29ydGVyT3B0aW9uID0gb3B0cy5zd2FnZ2VyT3B0aW9ucy5hcGlzU29ydGVyO1xuICAgICAgaWYgKF8uaXNGdW5jdGlvbihzb3J0ZXJPcHRpb24pKSB7XG4gICAgICAgIHNvcnRlckZuID0gc29ydGVyT3B0aW9uO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc29ydGVyRm4gPSB0aGlzLmFwaXNTb3J0ZXJbc29ydGVyT3B0aW9uXTtcbiAgICAgIH1cbiAgICAgIGlmIChfLmlzRnVuY3Rpb24oc29ydGVyRm4pKSB7XG4gICAgICAgIHRoaXMubW9kZWwuYXBpc0FycmF5LnNvcnQoc29ydGVyRm4pO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBTb3J0IG9wZXJhdGlvbnMgb2YgZWFjaCBBUElcbiAgICBpZiAob3B0cy5zd2FnZ2VyT3B0aW9ucy5vcGVyYXRpb25zU29ydGVyKSB7XG4gICAgICBzb3J0ZXJPcHRpb24gPSBvcHRzLnN3YWdnZXJPcHRpb25zLm9wZXJhdGlvbnNTb3J0ZXI7XG4gICAgICBpZiAoXy5pc0Z1bmN0aW9uKHNvcnRlck9wdGlvbikpIHtcbiAgICAgICAgc29ydGVyRm4gPSBzb3J0ZXJPcHRpb247XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzb3J0ZXJGbiA9IHRoaXMub3BlcmF0aW9uc1NvcnRlcnNbc29ydGVyT3B0aW9uXTtcbiAgICAgIH1cbiAgICAgIGlmIChfLmlzRnVuY3Rpb24oc29ydGVyRm4pKSB7XG4gICAgICAgIGZvciAoa2V5IGluIHRoaXMubW9kZWwuYXBpc0FycmF5KSB7XG4gICAgICAgICAgdGhpcy5tb2RlbC5hcGlzQXJyYXlba2V5XS5vcGVyYXRpb25zQXJyYXkuc29ydChzb3J0ZXJGbik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBzZXQgdXAgdGhlIFVJIGZvciBpbnB1dFxuICAgIHRoaXMubW9kZWwuYXV0aHMgPSBbXTtcblxuICAgIGZvciAoa2V5IGluIHRoaXMubW9kZWwuc2VjdXJpdHlEZWZpbml0aW9ucykge1xuICAgICAgdmFsdWUgPSB0aGlzLm1vZGVsLnNlY3VyaXR5RGVmaW5pdGlvbnNba2V5XTtcblxuICAgICAgdGhpcy5tb2RlbC5hdXRocy5wdXNoKHtcbiAgICAgICAgbmFtZToga2V5LFxuICAgICAgICB0eXBlOiB2YWx1ZS50eXBlLFxuICAgICAgICB2YWx1ZTogdmFsdWVcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICgndmFsaWRhdG9yVXJsJyBpbiBvcHRzLnN3YWdnZXJPcHRpb25zKSB7XG4gICAgICAvLyBWYWxpZGF0b3IgVVJMIHNwZWNpZmllZCBleHBsaWNpdGx5XG4gICAgICB0aGlzLm1vZGVsLnZhbGlkYXRvclVybCA9IG9wdHMuc3dhZ2dlck9wdGlvbnMudmFsaWRhdG9yVXJsO1xuICAgIH0gZWxzZSBpZiAodGhpcy5tb2RlbC51cmwuaW5kZXhPZignbG9jYWxob3N0JykgPiAwIHx8IHRoaXMubW9kZWwudXJsLmluZGV4T2YoJzEyNy4wLjAuMScpID4gMCkge1xuICAgICAgLy8gTG9jYWxob3N0IG92ZXJyaWRlXG4gICAgICB0aGlzLm1vZGVsLnZhbGlkYXRvclVybCA9IG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubW9kZWwudmFsaWRhdG9yVXJsID0gJy8vb25saW5lLnN3YWdnZXIuaW8vdmFsaWRhdG9yJztcbiAgICB9XG5cbiAgICAvLyBKU29uRWRpdG9yIHJlcXVpcmVzIHR5cGU9J29iamVjdCcgdG8gYmUgcHJlc2VudCBvbiBkZWZpbmVkIHR5cGVzLCB3ZSBhZGQgaXQgaWYgaXQncyBtaXNzaW5nXG4gICAgLy8gaXMgdGhlcmUgYW55IHZhbGlkIGNhc2Ugd2VyZSBpdCBzaG91bGQgbm90IGJlIGFkZGVkID9cbiAgICB2YXIgZGVmO1xuICAgIGZvcihkZWYgaW4gdGhpcy5tb2RlbC5kZWZpbml0aW9ucyl7XG4gICAgICBpZiAoIXRoaXMubW9kZWwuZGVmaW5pdGlvbnNbZGVmXS50eXBlKXtcbiAgICAgICAgdGhpcy5tb2RlbC5kZWZpbml0aW9uc1tkZWZdLnR5cGUgPSAnb2JqZWN0JztcbiAgICAgIH1cbiAgICB9XG5cbiAgfSxcblxuICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAkKHRoaXMuZWwpLmh0bWwoSGFuZGxlYmFycy50ZW1wbGF0ZXMubWFpbih0aGlzLm1vZGVsKSk7XG4gICAgdGhpcy5pbmZvID0gdGhpcy4kKCcuaW5mbycpWzBdO1xuXG4gICAgaWYgKHRoaXMuaW5mbykge1xuICAgICAgdGhpcy5pbmZvLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5vbkxpbmtDbGljaywgdHJ1ZSk7XG4gICAgfVxuXG4gICAgdGhpcy5tb2RlbC5zZWN1cml0eURlZmluaXRpb25zID0gdGhpcy5tb2RlbC5zZWN1cml0eURlZmluaXRpb25zIHx8IHt9O1xuXG4gICAgLy8gUmVuZGVyIGVhY2ggcmVzb3VyY2VcblxuICAgIHZhciByZXNvdXJjZXMgPSB7fTtcbiAgICB2YXIgY291bnRlciA9IDA7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLm1vZGVsLmFwaXNBcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHJlc291cmNlID0gdGhpcy5tb2RlbC5hcGlzQXJyYXlbaV07XG4gICAgICB2YXIgaWQgPSByZXNvdXJjZS5uYW1lO1xuICAgICAgd2hpbGUgKHR5cGVvZiByZXNvdXJjZXNbaWRdICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBpZCA9IGlkICsgJ18nICsgY291bnRlcjtcbiAgICAgICAgY291bnRlciArPSAxO1xuICAgICAgfVxuICAgICAgcmVzb3VyY2UuaWQgPSBzYW5pdGl6ZUh0bWwoaWQpO1xuICAgICAgcmVzb3VyY2VzW2lkXSA9IHJlc291cmNlO1xuICAgICAgdGhpcy5hZGRSZXNvdXJjZShyZXNvdXJjZSwgdGhpcy5tb2RlbC5hdXRocyk7XG4gICAgfVxuXG4gICAgJCgnLnByb3BXcmFwJykuaG92ZXIoZnVuY3Rpb24gb25Ib3Zlcigpe1xuICAgICAgJCgnLm9wdGlvbnNXcmFwcGVyJywgJCh0aGlzKSkuc2hvdygpO1xuICAgIH0sIGZ1bmN0aW9uIG9mZmhvdmVyKCl7XG4gICAgICAkKCcub3B0aW9uc1dyYXBwZXInLCAkKHRoaXMpKS5oaWRlKCk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG5cbiAgYWRkUmVzb3VyY2U6IGZ1bmN0aW9uKHJlc291cmNlLCBhdXRocyl7XG4gICAgLy8gUmVuZGVyIGEgcmVzb3VyY2UgYW5kIGFkZCBpdCB0byByZXNvdXJjZXMgbGlcbiAgICByZXNvdXJjZS5pZCA9IHJlc291cmNlLmlkLnJlcGxhY2UoL1teYS16QS1aXFxkXS9nLCBmdW5jdGlvbihzdHIpIHsgcmV0dXJuIHN0ci5jaGFyQ29kZUF0KDApOyB9KTtcblxuICAgIC8vIE1ha2UgYWxsIGRlZmluaXRpb25zIGF2YWlsYWJsZSBhdCB0aGUgcm9vdCBvZiB0aGUgcmVzb3VyY2Ugc28gdGhhdCB0aGV5IGNhblxuICAgIC8vIGJlIGxvYWRlZCBieSB0aGUgSlNvbkVkaXRvclxuICAgIHJlc291cmNlLmRlZmluaXRpb25zID0gdGhpcy5tb2RlbC5kZWZpbml0aW9ucztcblxuICAgIHZhciByZXNvdXJjZVZpZXcgPSBuZXcgU3dhZ2dlclVpLlZpZXdzLlJlc291cmNlVmlldyh7XG4gICAgICBtb2RlbDogcmVzb3VyY2UsXG4gICAgICByb3V0ZXI6IHRoaXMucm91dGVyLFxuICAgICAgdGFnTmFtZTogJ2xpJyxcbiAgICAgIGlkOiAncmVzb3VyY2VfJyArIHJlc291cmNlLmlkLFxuICAgICAgY2xhc3NOYW1lOiAncmVzb3VyY2UnLFxuICAgICAgYXV0aHM6IGF1dGhzLFxuICAgICAgc3dhZ2dlck9wdGlvbnM6IHRoaXMub3B0aW9ucy5zd2FnZ2VyT3B0aW9uc1xuICAgIH0pO1xuICAgICQoJyNyZXNvdXJjZXMnLCB0aGlzLmVsKS5hcHBlbmQocmVzb3VyY2VWaWV3LnJlbmRlcigpLmVsKTtcbiAgfSxcblxuICBjbGVhcjogZnVuY3Rpb24oKXtcbiAgICAkKHRoaXMuZWwpLmh0bWwoJycpO1xuICB9LFxuXG4gIG9uTGlua0NsaWNrOiBmdW5jdGlvbiAoZSkge1xuICAgIHZhciBlbCA9IGUudGFyZ2V0O1xuXG4gICAgaWYgKGVsLnRhZ05hbWUgPT09ICdBJyAmJiBlbC5ocmVmICYmICFlbC50YXJnZXQpIHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB3aW5kb3cub3BlbihlbC5ocmVmLCAnX2JsYW5rJyk7XG4gICAgfVxuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLk1vZGVscy5PYXV0aDJNb2RlbCA9IEJhY2tib25lLk1vZGVsLmV4dGVuZCh7XG4gICAgZGVmYXVsdHM6IHtcbiAgICAgICAgc2NvcGVzOiB7fSxcbiAgICAgICAgaXNQYXNzd29yZEZsb3c6IGZhbHNlLFxuICAgICAgICBjbGllbnRBdXRoZW50aWNhdGlvblR5cGU6ICdub25lJ1xuICAgIH0sXG5cbiAgICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmKHRoaXMuYXR0cmlidXRlcyAmJiB0aGlzLmF0dHJpYnV0ZXMuc2NvcGVzKSB7XG4gICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IF8uY2xvbmVEZWVwKHRoaXMuYXR0cmlidXRlcyk7XG4gICAgICAgICAgICB2YXIgaSwgc2NvcGVzID0gW107XG4gICAgICAgICAgICBmb3IoaSBpbiBhdHRyaWJ1dGVzLnNjb3Blcykge1xuICAgICAgICAgICAgICAgIHZhciBzY29wZSA9IGF0dHJpYnV0ZXMuc2NvcGVzW2ldO1xuICAgICAgICAgICAgICAgIGlmKHR5cGVvZiBzY29wZS5kZXNjcmlwdGlvbiA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgc2NvcGVzW3Njb3BlXSA9IGF0dHJpYnV0ZXMuc2NvcGVzW2ldO1xuICAgICAgICAgICAgICAgICAgICBzY29wZXMucHVzaChhdHRyaWJ1dGVzLnNjb3Blc1tpXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXR0cmlidXRlcy5zY29wZXMgPSBzY29wZXM7XG4gICAgICAgICAgICB0aGlzLmF0dHJpYnV0ZXMgPSBhdHRyaWJ1dGVzO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuYXR0cmlidXRlcyAmJiB0aGlzLmF0dHJpYnV0ZXMuZmxvdykge1xuICAgICAgICAgICAgdmFyIGZsb3cgPSB0aGlzLmF0dHJpYnV0ZXMuZmxvdztcbiAgICAgICAgICAgIHRoaXMuc2V0KCdpc1Bhc3N3b3JkRmxvdycsIGZsb3cgPT09ICdwYXNzd29yZCcpO1xuICAgICAgICAgICAgdGhpcy5zZXQoJ3JlcXVpcmVDbGllbnRBdXRoZW50aWNhdGlvbicsIGZsb3cgPT09ICdhcHBsaWNhdGlvbicpO1xuICAgICAgICAgICAgdGhpcy5zZXQoJ2NsaWVudEF1dGhlbnRpY2F0aW9uJywgZmxvdyA9PT0gJ3Bhc3N3b3JkJyB8fCBmbG93ID09PSAnYXBwbGljYXRpb24nKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9uKCdjaGFuZ2UnLCB0aGlzLnZhbGlkYXRlKTtcbiAgICB9LFxuXG4gICAgc2V0U2NvcGVzOiBmdW5jdGlvbiAobmFtZSwgdmFsKSB7XG4gICAgICAgIHZhciBhdXRoID0gXy5leHRlbmQoe30sIHRoaXMuYXR0cmlidXRlcyk7XG4gICAgICAgIHZhciBpbmRleCA9IF8uZmluZEluZGV4KGF1dGguc2NvcGVzLCBmdW5jdGlvbihvKSB7XG4gICAgICAgICAgICByZXR1cm4gby5zY29wZSA9PT0gbmFtZTtcbiAgICAgICAgfSk7XG4gICAgICAgIGF1dGguc2NvcGVzW2luZGV4XS5jaGVja2VkID0gdmFsO1xuXG4gICAgICAgIHRoaXMuc2V0KGF1dGgpO1xuICAgICAgICB0aGlzLnZhbGlkYXRlKCk7XG4gICAgfSxcblxuICAgIHZhbGlkYXRlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgdmFsaWQgPSBmYWxzZTtcbiAgICAgIGlmICh0aGlzLmdldCgnaXNQYXNzd29yZEZsb3cnKSAmJlxuICAgICAgICAgICghdGhpcy5nZXQoJ3VzZXJuYW1lJykpKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5nZXQoJ2NsaWVudEF1dGhlbnRpY2F0aW9uVHlwZScpIGluIFsnYmFzaWMnLCAncmVxdWVzdC1ib2R5J10gJiZcbiAgICAgICAgICAoIXRoaXMuZ2V0KCdjbGllbnRJZCcpKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgdmFyIHNjcCA9IHRoaXMuZ2V0KCdzY29wZXMnKTtcbiAgICAgIHZhciBpZHggPSAgXy5maW5kSW5kZXgoc2NwLCBmdW5jdGlvbiAobykge1xuICAgICAgICAgcmV0dXJuIG8uY2hlY2tlZCA9PT0gdHJ1ZTtcbiAgICAgIH0pO1xuXG4gICAgICBpZihzY3AubGVuZ3RoID4gMCAmJiBpZHggPj0gMCkge1xuICAgICAgICAgIHZhbGlkID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYoc2NwLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHZhbGlkID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zZXQoJ3ZhbGlkJywgdmFsaWQpO1xuXG4gICAgICByZXR1cm4gdmFsaWQ7XG4gICAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5PYXV0aDJWaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoe1xuICAgIGV2ZW50czoge1xuICAgICAgICAnY2hhbmdlIC5vYXV0aC1zY29wZSc6ICdzY29wZUNoYW5nZScsXG4gICAgICAgICdjaGFuZ2UgLm9hdXRoLXVzZXJuYW1lJzogJ3NldFVzZXJuYW1lJyxcbiAgICAgICAgJ2NoYW5nZSAub2F1dGgtcGFzc3dvcmQnOiAnc2V0UGFzc3dvcmQnLFxuICAgICAgICAnY2hhbmdlIC5vYXV0aC1jbGllbnQtYXV0aGVudGljYXRpb24tdHlwZSc6ICdzZXRDbGllbnRBdXRoZW50aWNhdGlvblR5cGUnLFxuICAgICAgICAnY2hhbmdlIC5vYXV0aC1jbGllbnQtaWQnOiAnc2V0Q2xpZW50SWQnLFxuICAgICAgICAnY2hhbmdlIC5vYXV0aC1jbGllbnQtc2VjcmV0JzogJ3NldENsaWVudFNlY3JldCdcbiAgICB9LFxuXG4gICAgdGVtcGxhdGU6IEhhbmRsZWJhcnMudGVtcGxhdGVzLm9hdXRoMixcblxuICAgIGNsczoge1xuICAgICAgICBlcnJvcjogJ2Vycm9yJ1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy4kZWwuaHRtbCh0aGlzLnRlbXBsYXRlKHRoaXMubW9kZWwudG9KU09OKCkpKTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgc2NvcGVDaGFuZ2U6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIHZhciB2YWwgPSAkKGUudGFyZ2V0KS5wcm9wKCdjaGVja2VkJyk7XG4gICAgICAgIHZhciBzY29wZSA9ICQoZS50YXJnZXQpLmRhdGEoJ3Njb3BlJyk7XG5cbiAgICAgICAgdGhpcy5tb2RlbC5zZXRTY29wZXMoc2NvcGUsIHZhbCk7XG4gICAgfSxcblxuICAgIHNldFVzZXJuYW1lOiBmdW5jdGlvbiAoZSkge1xuICAgICAgICB2YXIgdmFsPSAkKGUudGFyZ2V0KS52YWwoKTtcbiAgICAgICAgdGhpcy5tb2RlbC5zZXQoJ3VzZXJuYW1lJywgdmFsKTtcbiAgICAgICAgaWYgKHZhbCkge1xuICAgICAgICAgICAgJChlLnRhcmdldCkucmVtb3ZlQ2xhc3ModGhpcy5jbHMuZXJyb3IpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIHNldFBhc3N3b3JkOiBmdW5jdGlvbiAoZSkge1xuICAgICAgICB0aGlzLm1vZGVsLnNldCgncGFzc3dvcmQnLCAkKGUudGFyZ2V0KS52YWwoKSk7XG4gICAgfSxcblxuICAgIHNldENsaWVudEF1dGhlbnRpY2F0aW9uVHlwZTogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgdmFyIHR5cGUgPSAkKGUudGFyZ2V0KS52YWwoKTtcbiAgICAgICAgdmFyICRlbCA9IHRoaXMuJGVsO1xuICAgICAgICB0aGlzLm1vZGVsLnNldCgnY2xpZW50QXV0aGVudGljYXRpb25UeXBlJywgdHlwZSk7XG5cbiAgICAgICAgc3dpdGNoKHR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgJ25vbmUnOlxuICAgICAgICAgICAgICAgICRlbC5maW5kKCcub2F1dGgtY2xpZW50LWF1dGhlbnRpY2F0aW9uJykuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnYmFzaWMnOlxuICAgICAgICAgICAgY2FzZSAncmVxdWVzdC1ib2R5JzpcbiAgICAgICAgICAgICAgICAkZWwuZmluZCgnLm9hdXRoLWNsaWVudC1pZCcpLnJlbW92ZUNsYXNzKHRoaXMuY2xzLmVycm9yKTtcbiAgICAgICAgICAgICAgICAkZWwuZmluZCgnLm9hdXRoLWNsaWVudC1hdXRoZW50aWNhdGlvbicpLnNob3coKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBzZXRDbGllbnRJZDogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgdmFyIHZhbCA9ICQoZS50YXJnZXQpLnZhbCgpO1xuICAgICAgICB0aGlzLm1vZGVsLnNldCgnY2xpZW50SWQnLCB2YWwpO1xuICAgICAgICBpZiAodmFsKSB7XG4gICAgICAgICAgICAkKGUudGFyZ2V0KS5yZW1vdmVDbGFzcyh0aGlzLmNscy5lcnJvcik7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgc2V0Q2xpZW50U2VjcmV0OiBmdW5jdGlvbiAoZSkge1xuICAgICAgICB0aGlzLm1vZGVsLnNldCgnY2xpZW50U2VjcmV0JywgJChlLnRhcmdldCkudmFsKCkpO1xuICAgICAgICAkKGUudGFyZ2V0KS5yZW1vdmVDbGFzcygnZXJyb3InKTtcbiAgICB9LFxuXG4gICAgaGlnaGxpZ2h0SW52YWxpZDogZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIXRoaXMubW9kZWwuZ2V0KCd1c2VybmFtZScpKSB7XG4gICAgICAgICAgICB0aGlzLiRlbC5maW5kKCcub2F1dGgtdXNlcm5hbWUnKS5hZGRDbGFzcyh0aGlzLmNscy5lcnJvcik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMubW9kZWwuZ2V0KCdjbGllbnRJZCcpKSB7XG4gICAgICAgICAgICB0aGlzLiRlbC5maW5kKCcub2F1dGgtY2xpZW50LWlkJykuYWRkQ2xhc3ModGhpcy5jbHMuZXJyb3IpO1xuICAgICAgICB9XG4gICAgfVxufSk7IiwiJ3VzZSBzdHJpY3QnO1xuXG5Td2FnZ2VyVWkuVmlld3MuT3BlcmF0aW9uVmlldyA9IEJhY2tib25lLlZpZXcuZXh0ZW5kKHtcbiAgaW52b2NhdGlvblVybDogbnVsbCxcblxuICBldmVudHM6IHtcbiAgICAnc3VibWl0IC5zYW5kYm94JyAgICAgICAgIDogJ3N1Ym1pdE9wZXJhdGlvbicsXG4gICAgJ2NsaWNrIC5zdWJtaXQnICAgICAgICAgICA6ICdzdWJtaXRPcGVyYXRpb24nLFxuICAgICdjbGljayAucmVzcG9uc2VfaGlkZXInICAgOiAnaGlkZVJlc3BvbnNlJyxcbiAgICAnY2xpY2sgLnRvZ2dsZU9wZXJhdGlvbicgIDogJ3RvZ2dsZU9wZXJhdGlvbkNvbnRlbnQnLFxuICAgICdtb3VzZWVudGVyIC5hcGktaWMnICAgICAgOiAnbW91c2VFbnRlcicsXG4gICAgJ2RibGNsaWNrIC5jdXJsJyAgICAgICAgICA6ICdzZWxlY3RUZXh0JyxcbiAgICAnY2hhbmdlIFtuYW1lPXJlc3BvbnNlQ29udGVudFR5cGVdJyA6ICdzaG93U25pcHBldCdcbiAgfSxcblxuICBpbml0aWFsaXplOiBmdW5jdGlvbihvcHRzKSB7XG4gICAgb3B0cyA9IG9wdHMgfHwge307XG4gICAgdGhpcy5yb3V0ZXIgPSBvcHRzLnJvdXRlcjtcbiAgICB0aGlzLmF1dGhzID0gb3B0cy5hdXRocztcbiAgICB0aGlzLnBhcmVudElkID0gdGhpcy5tb2RlbC5wYXJlbnRJZDtcbiAgICB0aGlzLm5pY2tuYW1lID0gdGhpcy5tb2RlbC5uaWNrbmFtZTtcbiAgICB0aGlzLm1vZGVsLmVuY29kZWRQYXJlbnRJZCA9IGVuY29kZVVSSUNvbXBvbmVudCh0aGlzLnBhcmVudElkKTtcblxuICAgIGlmIChvcHRzLnN3YWdnZXJPcHRpb25zKSB7XG4gICAgICB0aGlzLm1vZGVsLmRlZmF1bHRSZW5kZXJpbmcgPSBvcHRzLnN3YWdnZXJPcHRpb25zLmRlZmF1bHRNb2RlbFJlbmRlcmluZztcblxuICAgICAgaWYgKG9wdHMuc3dhZ2dlck9wdGlvbnMuc2hvd1JlcXVlc3RIZWFkZXJzKSB7XG4gICAgICAgIHRoaXMubW9kZWwuc2hvd1JlcXVlc3RIZWFkZXJzID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKG9wdHMuc3dhZ2dlck9wdGlvbnMuc2hvd09wZXJhdGlvbklkcykge1xuICAgICAgICB0aGlzLm1vZGVsLnNob3dPcGVyYXRpb25JZHMgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfSxcblxuICBzZWxlY3RUZXh0OiBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBkb2MgPSBkb2N1bWVudCxcbiAgICAgICAgdGV4dCA9IGV2ZW50LnRhcmdldC5maXJzdENoaWxkLFxuICAgICAgICByYW5nZSxcbiAgICAgICAgc2VsZWN0aW9uO1xuICAgIGlmIChkb2MuYm9keS5jcmVhdGVUZXh0UmFuZ2UpIHtcbiAgICAgIHJhbmdlID0gZG9jdW1lbnQuYm9keS5jcmVhdGVUZXh0UmFuZ2UoKTtcbiAgICAgIHJhbmdlLm1vdmVUb0VsZW1lbnRUZXh0KHRleHQpO1xuICAgICAgcmFuZ2Uuc2VsZWN0KCk7XG4gICAgfSBlbHNlIGlmICh3aW5kb3cuZ2V0U2VsZWN0aW9uKSB7XG4gICAgICBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgICByYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gICAgICByYW5nZS5zZWxlY3ROb2RlQ29udGVudHModGV4dCk7XG4gICAgICBzZWxlY3Rpb24ucmVtb3ZlQWxsUmFuZ2VzKCk7XG4gICAgICBzZWxlY3Rpb24uYWRkUmFuZ2UocmFuZ2UpO1xuICAgIH1cbiAgfSxcblxuICBtb3VzZUVudGVyOiBmdW5jdGlvbihlKSB7XG4gICAgdmFyIGVsZW0gPSAkKHRoaXMuZWwpLmZpbmQoJy5jb250ZW50Jyk7XG4gICAgdmFyIHggPSBlLnBhZ2VYO1xuICAgIHZhciB5ID0gZS5wYWdlWTtcbiAgICB2YXIgc2NYID0gJCh3aW5kb3cpLnNjcm9sbExlZnQoKTtcbiAgICB2YXIgc2NZID0gJCh3aW5kb3cpLnNjcm9sbFRvcCgpO1xuICAgIHZhciBzY01heFggPSBzY1ggKyAkKHdpbmRvdykud2lkdGgoKTtcbiAgICB2YXIgc2NNYXhZID0gc2NZICsgJCh3aW5kb3cpLmhlaWdodCgpO1xuICAgIHZhciB3ZCA9IGVsZW0ud2lkdGgoKTtcbiAgICB2YXIgaGdoID0gZWxlbS5oZWlnaHQoKTtcblxuICAgIGlmICh4ICsgd2QgPiBzY01heFgpIHtcbiAgICAgIHggPSBzY01heFggLSB3ZDtcbiAgICB9XG5cbiAgICBpZiAoeCA8IHNjWCkge1xuICAgICAgeCA9IHNjWDtcbiAgICB9XG5cbiAgICBpZiAoeSArIGhnaCA+IHNjTWF4WSkge1xuICAgICAgeSA9IHNjTWF4WSAtIGhnaDtcbiAgICB9XG5cbiAgICBpZiAoeSA8IHNjWSkge1xuICAgICAgeSA9IHNjWTtcbiAgICB9XG5cbiAgICB2YXIgcG9zID0ge307XG4gICAgcG9zLnRvcCA9IHk7XG4gICAgcG9zLmxlZnQgPSB4O1xuICAgIGVsZW0uY3NzKHBvcyk7XG4gIH0sXG5cbiAgLy8gTm90ZTogY29waWVkIGZyb20gQ29mZmVlU2NyaXB0IGNvbXBpbGVkIGZpbGVcbiAgLy8gVE9ETzogcmVmYWN0b3JcbiAgcmVuZGVyOiBmdW5jdGlvbigpIHtcbiAgICB2YXIgYSwgYXV0aCwgYXV0aHMsIGNvZGUsIGNvbnRlbnRUeXBlTW9kZWwsIGlzTWV0aG9kU3VibWlzc2lvblN1cHBvcnRlZCwgaywga2V5LCBsLCBsZW4sIGxlbjEsIGxlbjIsIGxlbjMsIGxlbjQsIG0sIG1vZGVsQXV0aHMsIG4sIG8sIHAsIHBhcmFtLCBxLCByZWYsIHJlZjEsIHJlZjIsIHJlZjMsIHJlZjQsIHJlZjUsIHJlc3BvbnNlQ29udGVudFR5cGVWaWV3LCByZXNwb25zZVNpZ25hdHVyZVZpZXcsIHNjaGVtYSwgc2NoZW1hT2JqLCBzY29wZUluZGV4LCBzaWduYXR1cmVNb2RlbCwgc3RhdHVzQ29kZSwgc3VjY2Vzc1Jlc3BvbnNlLCB0eXBlLCB2LCB2YWx1ZSwgcHJvZHVjZXMsIGlzWE1MLCBpc0pTT047XG4gICAgaXNNZXRob2RTdWJtaXNzaW9uU3VwcG9ydGVkID0galF1ZXJ5LmluQXJyYXkodGhpcy5tb2RlbC5tZXRob2QsIHRoaXMubW9kZWwuc3VwcG9ydGVkU3VibWl0TWV0aG9kcygpKSA+PSAwO1xuICAgIGlmICghaXNNZXRob2RTdWJtaXNzaW9uU3VwcG9ydGVkKSB7XG4gICAgICB0aGlzLm1vZGVsLmlzUmVhZE9ubHkgPSB0cnVlO1xuICAgIH1cbiAgICB0aGlzLm1vZGVsLmRlc2NyaXB0aW9uID0gdGhpcy5tb2RlbC5kZXNjcmlwdGlvbiB8fCB0aGlzLm1vZGVsLm5vdGVzO1xuICAgIHRoaXMubW9kZWwub2F1dGggPSBudWxsO1xuICAgIG1vZGVsQXV0aHMgPSB0aGlzLm1vZGVsLmF1dGhvcml6YXRpb25zIHx8IHRoaXMubW9kZWwuc2VjdXJpdHk7XG4gICAgaWYgKG1vZGVsQXV0aHMpIHtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KG1vZGVsQXV0aHMpKSB7XG4gICAgICAgIGZvciAobCA9IDAsIGxlbiA9IG1vZGVsQXV0aHMubGVuZ3RoOyBsIDwgbGVuOyBsKyspIHtcbiAgICAgICAgICBhdXRocyA9IG1vZGVsQXV0aHNbbF07XG4gICAgICAgICAgZm9yIChrZXkgaW4gYXV0aHMpIHtcbiAgICAgICAgICAgIGZvciAoYSBpbiB0aGlzLmF1dGhzKSB7XG4gICAgICAgICAgICAgIGF1dGggPSB0aGlzLmF1dGhzW2FdO1xuICAgICAgICAgICAgICBpZiAoa2V5ID09PSBhdXRoLm5hbWUpIHtcbiAgICAgICAgICAgICAgICBpZiAoYXV0aC50eXBlID09PSAnb2F1dGgyJykge1xuICAgICAgICAgICAgICAgICAgdGhpcy5tb2RlbC5vYXV0aCA9IHt9O1xuICAgICAgICAgICAgICAgICAgdGhpcy5tb2RlbC5vYXV0aC5zY29wZXMgPSBbXTtcbiAgICAgICAgICAgICAgICAgIHJlZjEgPSBhdXRoLnZhbHVlLnNjb3BlcztcbiAgICAgICAgICAgICAgICAgIGZvciAoayBpbiByZWYxKSB7XG4gICAgICAgICAgICAgICAgICAgIHYgPSByZWYxW2tdO1xuICAgICAgICAgICAgICAgICAgICBzY29wZUluZGV4ID0gYXV0aHNba2V5XS5pbmRleE9mKGspO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2NvcGVJbmRleCA+PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgbyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjb3BlOiBrLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246IHZcbiAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgIHRoaXMubW9kZWwub2F1dGguc2NvcGVzLnB1c2gobyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZvciAoayBpbiBtb2RlbEF1dGhzKSB7XG4gICAgICAgICAgdiA9IG1vZGVsQXV0aHNba107XG4gICAgICAgICAgaWYgKGsgPT09ICdvYXV0aDInKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5tb2RlbC5vYXV0aCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICB0aGlzLm1vZGVsLm9hdXRoID0ge307XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5tb2RlbC5vYXV0aC5zY29wZXMgPT09IHZvaWQgMCkge1xuICAgICAgICAgICAgICB0aGlzLm1vZGVsLm9hdXRoLnNjb3BlcyA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yIChtID0gMCwgbGVuMSA9IHYubGVuZ3RoOyBtIDwgbGVuMTsgbSsrKSB7XG4gICAgICAgICAgICAgIG8gPSB2W21dO1xuICAgICAgICAgICAgICB0aGlzLm1vZGVsLm9hdXRoLnNjb3Blcy5wdXNoKG8pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAodHlwZW9mIHRoaXMubW9kZWwucmVzcG9uc2VzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhpcy5tb2RlbC5yZXNwb25zZU1lc3NhZ2VzID0gW107XG4gICAgICByZWYyID0gdGhpcy5tb2RlbC5yZXNwb25zZXM7XG4gICAgICBmb3IgKGNvZGUgaW4gcmVmMikge1xuICAgICAgICB2YWx1ZSA9IHJlZjJbY29kZV07XG4gICAgICAgIHNjaGVtYSA9IG51bGw7XG4gICAgICAgIHNjaGVtYU9iaiA9IHRoaXMubW9kZWwucmVzcG9uc2VzW2NvZGVdLnNjaGVtYTtcbiAgICAgICAgaWYgKHNjaGVtYU9iaiAmJiBzY2hlbWFPYmouJHJlZikge1xuICAgICAgICAgIHNjaGVtYSA9IHNjaGVtYU9iai4kcmVmO1xuICAgICAgICAgIGlmIChzY2hlbWEuaW5kZXhPZignIy9kZWZpbml0aW9ucy8nKSAhPT0gLTEpIHtcbiAgICAgICAgICAgIHNjaGVtYSA9IHNjaGVtYS5yZXBsYWNlKC9eLiojXFwvZGVmaW5pdGlvbnNcXC8vLCAnJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMubW9kZWwucmVzcG9uc2VNZXNzYWdlcy5wdXNoKHtcbiAgICAgICAgICBjb2RlOiBjb2RlLFxuICAgICAgICAgIG1lc3NhZ2U6IHZhbHVlLmRlc2NyaXB0aW9uLFxuICAgICAgICAgIHJlc3BvbnNlTW9kZWw6IHNjaGVtYSxcbiAgICAgICAgICBoZWFkZXJzOiB2YWx1ZS5oZWFkZXJzLFxuICAgICAgICAgIHNjaGVtYTogc2NoZW1hT2JqXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAodHlwZW9mIHRoaXMubW9kZWwucmVzcG9uc2VNZXNzYWdlcyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRoaXMubW9kZWwucmVzcG9uc2VNZXNzYWdlcyA9IFtdO1xuICAgIH1cbiAgICBzaWduYXR1cmVNb2RlbCA9IG51bGw7XG4gICAgcHJvZHVjZXMgPSB0aGlzLm1vZGVsLnByb2R1Y2VzO1xuICAgIGlzWE1MID0gdGhpcy5jb250YWlucyhwcm9kdWNlcywgJ3htbCcpO1xuICAgIGlzSlNPTiA9IGlzWE1MID8gdGhpcy5jb250YWlucyhwcm9kdWNlcywgJ2pzb24nKSA6IHRydWU7XG5cbiAgICBpZiAodGhpcy5tb2RlbC5zdWNjZXNzUmVzcG9uc2UpIHtcbiAgICAgIHN1Y2Nlc3NSZXNwb25zZSA9IHRoaXMubW9kZWwuc3VjY2Vzc1Jlc3BvbnNlO1xuICAgICAgZm9yIChrZXkgaW4gc3VjY2Vzc1Jlc3BvbnNlKSB7XG4gICAgICAgIHZhbHVlID0gc3VjY2Vzc1Jlc3BvbnNlW2tleV07XG4gICAgICAgIHRoaXMubW9kZWwuc3VjY2Vzc0NvZGUgPSBrZXk7XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHR5cGVvZiB2YWx1ZS5jcmVhdGVKU09OU2FtcGxlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgdGhpcy5tb2RlbC5zdWNjZXNzRGVzY3JpcHRpb24gPSB2YWx1ZS5kZXNjcmlwdGlvbjtcbiAgICAgICAgICB0aGlzLm1vZGVsLmhlYWRlcnMgPSB0aGlzLnBhcnNlUmVzcG9uc2VIZWFkZXJzKHZhbHVlLmhlYWRlcnMpO1xuICAgICAgICAgIHNpZ25hdHVyZU1vZGVsID0ge1xuICAgICAgICAgICAgc2FtcGxlSlNPTjogaXNKU09OID8gSlNPTi5zdHJpbmdpZnkoU3dhZ2dlclVpLnBhcnRpYWxzLnNpZ25hdHVyZS5jcmVhdGVKU09OU2FtcGxlKHZhbHVlKSwgdm9pZCAwLCAyKSA6IGZhbHNlLFxuICAgICAgICAgICAgaXNQYXJhbTogZmFsc2UsXG4gICAgICAgICAgICBzYW1wbGVYTUw6IGlzWE1MID8gU3dhZ2dlclVpLnBhcnRpYWxzLnNpZ25hdHVyZS5jcmVhdGVYTUxTYW1wbGUodmFsdWUubmFtZSwgdmFsdWUuZGVmaW5pdGlvbiwgdmFsdWUubW9kZWxzKSA6IGZhbHNlLFxuICAgICAgICAgICAgc2lnbmF0dXJlOiBTd2FnZ2VyVWkucGFydGlhbHMuc2lnbmF0dXJlLmdldE1vZGVsU2lnbmF0dXJlKHZhbHVlLm5hbWUsIHZhbHVlLmRlZmluaXRpb24sIHZhbHVlLm1vZGVscywgdmFsdWUubW9kZWxQcm9wZXJ0eU1hY3JvKVxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2lnbmF0dXJlTW9kZWwgPSB7XG4gICAgICAgICAgICBzaWduYXR1cmU6IFN3YWdnZXJVaS5wYXJ0aWFscy5zaWduYXR1cmUuZ2V0UHJpbWl0aXZlU2lnbmF0dXJlKHZhbHVlKVxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHRoaXMubW9kZWwucmVzcG9uc2VDbGFzc1NpZ25hdHVyZSAmJiB0aGlzLm1vZGVsLnJlc3BvbnNlQ2xhc3NTaWduYXR1cmUgIT09ICdzdHJpbmcnKSB7XG4gICAgICBzaWduYXR1cmVNb2RlbCA9IHtcbiAgICAgICAgc2FtcGxlSlNPTjogdGhpcy5tb2RlbC5yZXNwb25zZVNhbXBsZUpTT04sXG4gICAgICAgIGlzUGFyYW06IGZhbHNlLFxuICAgICAgICBzaWduYXR1cmU6IHRoaXMubW9kZWwucmVzcG9uc2VDbGFzc1NpZ25hdHVyZVxuICAgICAgfTtcbiAgICB9XG4gICAgJCh0aGlzLmVsKS5odG1sKEhhbmRsZWJhcnMudGVtcGxhdGVzLm9wZXJhdGlvbih0aGlzLm1vZGVsKSk7XG4gICAgaWYgKHNpZ25hdHVyZU1vZGVsKSB7XG4gICAgICBzaWduYXR1cmVNb2RlbC5kZWZhdWx0UmVuZGVyaW5nID0gdGhpcy5tb2RlbC5kZWZhdWx0UmVuZGVyaW5nO1xuICAgICAgcmVzcG9uc2VTaWduYXR1cmVWaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5TaWduYXR1cmVWaWV3KHtcbiAgICAgICAgbW9kZWw6IHNpZ25hdHVyZU1vZGVsLFxuICAgICAgICByb3V0ZXI6IHRoaXMucm91dGVyLFxuICAgICAgICB0YWdOYW1lOiAnZGl2J1xuICAgICAgfSk7XG4gICAgICAkKCcubW9kZWwtc2lnbmF0dXJlJywgJCh0aGlzLmVsKSkuYXBwZW5kKHJlc3BvbnNlU2lnbmF0dXJlVmlldy5yZW5kZXIoKS5lbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubW9kZWwucmVzcG9uc2VDbGFzc1NpZ25hdHVyZSA9ICdzdHJpbmcnO1xuICAgICAgJCgnLm1vZGVsLXNpZ25hdHVyZScsICQodGhpcy5lbCkpLmh0bWwodGhpcy5tb2RlbC50eXBlKTtcbiAgICB9XG4gICAgY29udGVudFR5cGVNb2RlbCA9IHtcbiAgICAgIGlzUGFyYW06IGZhbHNlXG4gICAgfTtcbiAgICBjb250ZW50VHlwZU1vZGVsLmNvbnN1bWVzID0gdGhpcy5tb2RlbC5jb25zdW1lcztcbiAgICBjb250ZW50VHlwZU1vZGVsLnByb2R1Y2VzID0gdGhpcy5tb2RlbC5wcm9kdWNlcztcbiAgICByZWYzID0gdGhpcy5tb2RlbC5wYXJhbWV0ZXJzO1xuICAgIGZvciAobiA9IDAsIGxlbjIgPSByZWYzLmxlbmd0aDsgbiA8IGxlbjI7IG4rKykge1xuICAgICAgcGFyYW0gPSByZWYzW25dO1xuICAgICAgdHlwZSA9IHBhcmFtLnR5cGUgfHwgcGFyYW0uZGF0YVR5cGUgfHwgJyc7XG4gICAgICBpZiAodHlwZW9mIHR5cGUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHNjaGVtYSA9IHBhcmFtLnNjaGVtYTtcbiAgICAgICAgaWYgKHNjaGVtYSAmJiBzY2hlbWEuJHJlZikge1xuICAgICAgICAgIHJlZiA9IHNjaGVtYS4kcmVmO1xuICAgICAgICAgIGlmIChyZWYuaW5kZXhPZignIy9kZWZpbml0aW9ucy8nKSA9PT0gMCkge1xuICAgICAgICAgICAgdHlwZSA9IHJlZi5zdWJzdHJpbmcoJyMvZGVmaW5pdGlvbnMvJy5sZW5ndGgpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0eXBlID0gcmVmO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHR5cGUgJiYgdHlwZS50b0xvd2VyQ2FzZSgpID09PSAnZmlsZScpIHtcbiAgICAgICAgaWYgKCFjb250ZW50VHlwZU1vZGVsLmNvbnN1bWVzKSB7XG4gICAgICAgICAgY29udGVudFR5cGVNb2RlbC5jb25zdW1lcyA9ICdtdWx0aXBhcnQvZm9ybS1kYXRhJztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcGFyYW0udHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIHJlc3BvbnNlQ29udGVudFR5cGVWaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5SZXNwb25zZUNvbnRlbnRUeXBlVmlldyh7XG4gICAgICBtb2RlbDogY29udGVudFR5cGVNb2RlbCxcbiAgICAgIHJvdXRlcjogdGhpcy5yb3V0ZXJcbiAgICB9KTtcbiAgICAkKCcucmVzcG9uc2UtY29udGVudC10eXBlJywgJCh0aGlzLmVsKSkuYXBwZW5kKHJlc3BvbnNlQ29udGVudFR5cGVWaWV3LnJlbmRlcigpLmVsKTtcbiAgICByZWY0ID0gdGhpcy5tb2RlbC5wYXJhbWV0ZXJzO1xuICAgIGZvciAocCA9IDAsIGxlbjMgPSByZWY0Lmxlbmd0aDsgcCA8IGxlbjM7IHArKykge1xuICAgICAgcGFyYW0gPSByZWY0W3BdO1xuICAgICAgdGhpcy5hZGRQYXJhbWV0ZXIocGFyYW0sIGNvbnRlbnRUeXBlTW9kZWwuY29uc3VtZXMpO1xuICAgIH1cbiAgICByZWY1ID0gdGhpcy5tb2RlbC5yZXNwb25zZU1lc3NhZ2VzO1xuICAgIGZvciAocSA9IDAsIGxlbjQgPSByZWY1Lmxlbmd0aDsgcSA8IGxlbjQ7IHErKykge1xuICAgICAgc3RhdHVzQ29kZSA9IHJlZjVbcV07XG4gICAgICBzdGF0dXNDb2RlLmlzWE1MID0gaXNYTUw7XG4gICAgICBzdGF0dXNDb2RlLmlzSlNPTiA9IGlzSlNPTjtcbiAgICAgIGlmICghXy5pc1VuZGVmaW5lZChzdGF0dXNDb2RlLmhlYWRlcnMpKSB7XG4gICAgICAgIHN0YXR1c0NvZGUuaGVhZGVycyA9IHRoaXMucGFyc2VIZWFkZXJzVHlwZShzdGF0dXNDb2RlLmhlYWRlcnMpO1xuICAgICAgfVxuICAgICAgdGhpcy5hZGRTdGF0dXNDb2RlKHN0YXR1c0NvZGUpO1xuICAgIH1cblxuICAgIGlmIChBcnJheS5pc0FycmF5KHRoaXMubW9kZWwuc2VjdXJpdHkpKSB7XG4gICAgICB2YXIgYXV0aHNNb2RlbCA9IFN3YWdnZXJVaS51dGlscy5wYXJzZVNlY3VyaXR5RGVmaW5pdGlvbnModGhpcy5tb2RlbC5zZWN1cml0eSwgdGhpcy5tb2RlbC5wYXJlbnQuc2VjdXJpdHlEZWZpbml0aW9ucyk7XG5cbiAgICAgIGF1dGhzTW9kZWwuaXNMb2dvdXQgPSAhXy5pc0VtcHR5KHRoaXMubW9kZWwuY2xpZW50QXV0aG9yaXphdGlvbnMuYXV0aHopO1xuICAgICAgdGhpcy5hdXRoVmlldyA9IG5ldyBTd2FnZ2VyVWkuVmlld3MuQXV0aEJ1dHRvblZpZXcoe1xuICAgICAgICBkYXRhOiBhdXRoc01vZGVsLFxuICAgICAgICByb3V0ZXI6IHRoaXMucm91dGVyLFxuICAgICAgICBpc09wZXJhdGlvbjogdHJ1ZSxcbiAgICAgICAgbW9kZWw6IHtcbiAgICAgICAgICBzY29wZXM6IGF1dGhzTW9kZWwuc2NvcGVzXG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgdGhpcy4kKCcuYXV0aG9yaXplLXdyYXBwZXInKS5hcHBlbmQodGhpcy5hdXRoVmlldy5yZW5kZXIoKS5lbCk7XG4gICAgfVxuXG4gICAgdGhpcy5zaG93U25pcHBldCgpO1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxuXG4gIHBhcnNlSGVhZGVyc1R5cGU6IGZ1bmN0aW9uIChoZWFkZXJzKSB7XG4gICAgdmFyIG1hcCA9IHtcbiAgICAgICdzdHJpbmcnOiB7XG4gICAgICAgICdkYXRlLXRpbWUnOiAnZGF0ZVRpbWUnLFxuICAgICAgICAnZGF0ZScgICAgIDogJ2RhdGUnXG4gICAgICB9XG4gICAgfTtcblxuICAgIF8uZm9yRWFjaChoZWFkZXJzLCBmdW5jdGlvbiAoaGVhZGVyKSB7XG4gICAgICB2YXIgdmFsdWU7XG4gICAgICBoZWFkZXIgPSBoZWFkZXIgfHwge307XG4gICAgICB2YWx1ZSA9IG1hcFtoZWFkZXIudHlwZV0gJiYgbWFwW2hlYWRlci50eXBlXVtoZWFkZXIuZm9ybWF0XTtcbiAgICAgIGlmICghXy5pc1VuZGVmaW5lZCh2YWx1ZSkpIHtcbiAgICAgICAgaGVhZGVyLnR5cGUgPSB2YWx1ZTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiBoZWFkZXJzO1xuICB9LFxuXG4gIGNvbnRhaW5zOiBmdW5jdGlvbiAocHJvZHVjZXMsIHR5cGUpIHtcbiAgICByZXR1cm4gcHJvZHVjZXMuZmlsdGVyKGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgIGlmICh2YWwuaW5kZXhPZih0eXBlKSA+IC0xKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH0pLmxlbmd0aDtcbiAgfSxcblxuICBwYXJzZVJlc3BvbnNlSGVhZGVyczogZnVuY3Rpb24gKGRhdGEpIHtcbiAgICB2YXIgSEVBREVSU19TRVBBUkFUT1IgPSAnOyAnO1xuICAgIHZhciBoZWFkZXJzID0gXy5jbG9uZShkYXRhKTtcblxuICAgIF8uZm9yRWFjaChoZWFkZXJzLCBmdW5jdGlvbiAoaGVhZGVyKSB7XG4gICAgICB2YXIgb3RoZXIgPSBbXTtcbiAgICAgIF8uZm9yRWFjaChoZWFkZXIsIGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG4gICAgICAgIHZhciBwcm9wZXJ0aWVzID0gWyd0eXBlJywgJ2Rlc2NyaXB0aW9uJ107XG4gICAgICAgIGlmIChwcm9wZXJ0aWVzLmluZGV4T2Yoa2V5LnRvTG93ZXJDYXNlKCkpID09PSAtMSkge1xuICAgICAgICAgIG90aGVyLnB1c2goa2V5ICsgJzogJyArIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIG90aGVyLmpvaW4oSEVBREVSU19TRVBBUkFUT1IpO1xuICAgICAgaGVhZGVyLm90aGVyID0gb3RoZXI7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gaGVhZGVycztcbiAgfSxcblxuICBhZGRQYXJhbWV0ZXI6IGZ1bmN0aW9uKHBhcmFtLCBjb25zdW1lcykge1xuICAgIC8vIFJlbmRlciBhIHBhcmFtZXRlclxuICAgIHBhcmFtLmNvbnN1bWVzID0gY29uc3VtZXM7XG4gICAgcGFyYW0uZGVmYXVsdFJlbmRlcmluZyA9IHRoaXMubW9kZWwuZGVmYXVsdFJlbmRlcmluZztcblxuICAgIC8vIENvcHkgdGhpcyBwYXJhbSBKU09OIHNwZWMgc28gdGhhdCBpdCB3aWxsIGJlIGF2YWlsYWJsZSBmb3IgSnNvbkVkaXRvclxuICAgIGlmKHBhcmFtLnNjaGVtYSl7XG4gICAgICAkLmV4dGVuZCh0cnVlLCBwYXJhbS5zY2hlbWEsIHRoaXMubW9kZWwuZGVmaW5pdGlvbnNbcGFyYW0udHlwZV0pO1xuICAgICAgcGFyYW0uc2NoZW1hLmRlZmluaXRpb25zID0gdGhpcy5tb2RlbC5kZWZpbml0aW9ucztcbiAgICAgIC8vIFRoaXMgaXMgcmVxdWlyZWQgZm9yIEpzb25FZGl0b3IgdG8gZGlzcGxheSB0aGUgcm9vdCBwcm9wZXJseVxuICAgICAgaWYoIXBhcmFtLnNjaGVtYS50eXBlKXtcbiAgICAgICAgcGFyYW0uc2NoZW1hLnR5cGUgPSAnb2JqZWN0JztcbiAgICAgIH1cbiAgICAgIC8vIFRoaXMgaXMgdGhlIHRpdGxlIHRoYXQgd2lsbCBiZSB1c2VkIGJ5IEpzb25FZGl0b3IgZm9yIHRoZSByb290XG4gICAgICAvLyBTaW5jZSB3ZSBhbHJlYWR5IGRpc3BsYXkgdGhlIHBhcmFtZXRlcidzIG5hbWUgaW4gdGhlIFBhcmFtZXRlciBjb2x1bW5cbiAgICAgIC8vIFdlIHNldCB0aGlzIHRvIHNwYWNlLCB3ZSBjYW4ndCBzZXQgaXQgdG8gbnVsbCBvciBzcGFjZSBvdGhlcndpc2UgSnNvbkVkaXRvclxuICAgICAgLy8gd2lsbCByZXBsYWNlIGl0IHdpdGggdGhlIHRleHQgXCJyb290XCIgd2hpY2ggd29uJ3QgbG9vayBnb29kIG9uIHNjcmVlblxuICAgICAgaWYoIXBhcmFtLnNjaGVtYS50aXRsZSl7XG4gICAgICAgIHBhcmFtLnNjaGVtYS50aXRsZSA9ICcgJztcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgcGFyYW1WaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5QYXJhbWV0ZXJWaWV3KHtcbiAgICAgIG1vZGVsOiBwYXJhbSxcbiAgICAgIHRhZ05hbWU6ICd0cicsXG4gICAgICByZWFkT25seTogdGhpcy5tb2RlbC5pc1JlYWRPbmx5LFxuICAgICAgc3dhZ2dlck9wdGlvbnM6IHRoaXMub3B0aW9ucy5zd2FnZ2VyT3B0aW9uc1xuICAgIH0pO1xuICAgICQoJy5vcGVyYXRpb24tcGFyYW1zJywgJCh0aGlzLmVsKSkuYXBwZW5kKHBhcmFtVmlldy5yZW5kZXIoKS5lbCk7XG4gIH0sXG5cbiAgYWRkU3RhdHVzQ29kZTogZnVuY3Rpb24oc3RhdHVzQ29kZSkge1xuICAgIC8vIFJlbmRlciBzdGF0dXMgY29kZXNcbiAgICBzdGF0dXNDb2RlLmRlZmF1bHRSZW5kZXJpbmcgPSB0aGlzLm1vZGVsLmRlZmF1bHRSZW5kZXJpbmc7XG4gICAgdmFyIHN0YXR1c0NvZGVWaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5TdGF0dXNDb2RlVmlldyh7XG4gICAgICBtb2RlbDogc3RhdHVzQ29kZSxcbiAgICAgIHRhZ05hbWU6ICd0cicsXG4gICAgICByb3V0ZXI6IHRoaXMucm91dGVyXG4gICAgfSk7XG4gICAgJCgnLm9wZXJhdGlvbi1zdGF0dXMnLCAkKHRoaXMuZWwpKS5hcHBlbmQoc3RhdHVzQ29kZVZpZXcucmVuZGVyKCkuZWwpO1xuICB9LFxuXG4gIC8vIE5vdGU6IGNvcGllZCBmcm9tIENvZmZlZVNjcmlwdCBjb21waWxlZCBmaWxlXG4gIC8vIFRPRE86IHJlZGFjdG9yXG4gIHN1Ym1pdE9wZXJhdGlvbjogZnVuY3Rpb24oZSkge1xuICAgIHZhciBlcnJvcl9mcmVlLCBmb3JtLCBpc0ZpbGVVcGxvYWQsIG1hcCwgb3B0cztcbiAgICBpZiAoZSAhPT0gbnVsbCkge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgICBmb3JtID0gJCgnLnNhbmRib3gnLCAkKHRoaXMuZWwpKTtcbiAgICBlcnJvcl9mcmVlID0gdHJ1ZTtcbiAgICBmb3JtLmZpbmQoJ2lucHV0LnJlcXVpcmVkJykuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgICQodGhpcykucmVtb3ZlQ2xhc3MoJ2Vycm9yJyk7XG4gICAgICBpZiAoalF1ZXJ5LnRyaW0oJCh0aGlzKS52YWwoKSkgPT09ICcnKSB7XG4gICAgICAgICQodGhpcykuYWRkQ2xhc3MoJ2Vycm9yJyk7XG4gICAgICAgICQodGhpcykud2lnZ2xlKHtcbiAgICAgICAgICBjYWxsYmFjazogKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICQoX3RoaXMpLmZvY3VzKCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pKHRoaXMpXG4gICAgICAgIH0pO1xuICAgICAgICBlcnJvcl9mcmVlID0gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gICAgZm9ybS5maW5kKCd0ZXh0YXJlYS5yZXF1aXJlZDp2aXNpYmxlJykuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgICQodGhpcykucmVtb3ZlQ2xhc3MoJ2Vycm9yJyk7XG4gICAgICBpZiAoalF1ZXJ5LnRyaW0oJCh0aGlzKS52YWwoKSkgPT09ICcnKSB7XG4gICAgICAgICQodGhpcykuYWRkQ2xhc3MoJ2Vycm9yJyk7XG4gICAgICAgICQodGhpcykud2lnZ2xlKHtcbiAgICAgICAgICBjYWxsYmFjazogKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgIHJldHVybiAkKF90aGlzKS5mb2N1cygpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9KSh0aGlzKVxuICAgICAgICB9KTtcbiAgICAgICAgZXJyb3JfZnJlZSA9IGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGZvcm0uZmluZCgnc2VsZWN0LnJlcXVpcmVkJykuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgICQodGhpcykucmVtb3ZlQ2xhc3MoJ2Vycm9yJyk7XG4gICAgICBpZiAodGhpcy5zZWxlY3RlZEluZGV4ID09PSAtMSkge1xuICAgICAgICAkKHRoaXMpLmFkZENsYXNzKCdlcnJvcicpO1xuICAgICAgICAkKHRoaXMpLndpZ2dsZSh7XG4gICAgICAgICAgY2FsbGJhY2s6IChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAkKF90aGlzKS5mb2N1cygpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9KSh0aGlzKVxuICAgICAgICB9KTtcbiAgICAgICAgZXJyb3JfZnJlZSA9IGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGlmIChlcnJvcl9mcmVlKSB7XG4gICAgICBtYXAgPSB0aGlzLmdldElucHV0TWFwKGZvcm0pO1xuICAgICAgaXNGaWxlVXBsb2FkID0gdGhpcy5pc0ZpbGVVcGxvYWQoZm9ybSk7XG4gICAgICBvcHRzID0ge1xuICAgICAgICBwYXJlbnQ6IHRoaXNcbiAgICAgIH07XG4gICAgICBpZiAodGhpcy5vcHRpb25zLnN3YWdnZXJPcHRpb25zKSB7XG4gICAgICAgIGZvcih2YXIga2V5IGluIHRoaXMub3B0aW9ucy5zd2FnZ2VyT3B0aW9ucykge1xuICAgICAgICAgIG9wdHNba2V5XSA9IHRoaXMub3B0aW9ucy5zd2FnZ2VyT3B0aW9uc1trZXldO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHZhciBwaTtcbiAgICAgIGZvcihwaSA9IDA7IHBpIDwgdGhpcy5tb2RlbC5wYXJhbWV0ZXJzLmxlbmd0aDsgcGkrKyl7XG4gICAgICAgIHZhciBwID0gdGhpcy5tb2RlbC5wYXJhbWV0ZXJzW3BpXTtcbiAgICAgICAgaWYoIHAuanNvbkVkaXRvciAmJiBwLmpzb25FZGl0b3IuaXNFbmFibGVkKCkpe1xuICAgICAgICAgIHZhciBqc29uID0gcC5qc29uRWRpdG9yLmdldFZhbHVlKCk7XG4gICAgICAgICAgbWFwW3AubmFtZV0gPSBKU09OLnN0cmluZ2lmeShqc29uKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBvcHRzLnJlc3BvbnNlQ29udGVudFR5cGUgPSAkKCdkaXYgc2VsZWN0W25hbWU9cmVzcG9uc2VDb250ZW50VHlwZV0nLCAkKHRoaXMuZWwpKS52YWwoKTtcbiAgICAgIG9wdHMucmVxdWVzdENvbnRlbnRUeXBlID0gJCgnZGl2IHNlbGVjdFtuYW1lPXBhcmFtZXRlckNvbnRlbnRUeXBlXScsICQodGhpcy5lbCkpLnZhbCgpO1xuICAgICAgJCgnLnJlc3BvbnNlX3Rocm9iYmVyJywgJCh0aGlzLmVsKSkuc2hvdygpO1xuICAgICAgaWYgKGlzRmlsZVVwbG9hZCkge1xuICAgICAgICAkKCcucmVxdWVzdF91cmwnLCAkKHRoaXMuZWwpKS5odG1sKCc8cHJlPjwvcHJlPicpO1xuICAgICAgICAkKCcucmVxdWVzdF91cmwgcHJlJywgJCh0aGlzLmVsKSkudGV4dCh0aGlzLmludm9jYXRpb25VcmwpO1xuXG4gICAgICAgIG9wdHMudXNlSlF1ZXJ5ID0gdHJ1ZTtcbiAgICAgICAgbWFwLnBhcmFtZXRlckNvbnRlbnRUeXBlID0gJ211bHRpcGFydC9mb3JtLWRhdGEnO1xuICAgICAgICB0aGlzLm1hcCA9IG1hcDtcbiAgICAgICAgcmV0dXJuIHRoaXMubW9kZWwuZXhlY3V0ZShtYXAsIG9wdHMsIHRoaXMuc2hvd0NvbXBsZXRlU3RhdHVzLCB0aGlzLnNob3dFcnJvclN0YXR1cywgdGhpcyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm1hcCA9IG1hcDtcbiAgICAgICAgcmV0dXJuIHRoaXMubW9kZWwuZXhlY3V0ZShtYXAsIG9wdHMsIHRoaXMuc2hvd0NvbXBsZXRlU3RhdHVzLCB0aGlzLnNob3dFcnJvclN0YXR1cywgdGhpcyk7XG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIGdldElucHV0TWFwOiBmdW5jdGlvbiAoZm9ybSkge1xuICAgIHZhciBtYXAsIHJlZjEsIGwsIGxlbiwgbywgcmVmMiwgbSwgbGVuMSwgdmFsLCByZWYzLCBuLCBsZW4yO1xuICAgIG1hcCA9IHt9O1xuICAgIHJlZjEgPSBmb3JtLmZpbmQoJ2lucHV0Jyk7XG4gICAgZm9yIChsID0gMCwgbGVuID0gcmVmMS5sZW5ndGg7IGwgPCBsZW47IGwrKykge1xuICAgICAgbyA9IHJlZjFbbF07XG4gICAgICBpZiAoKG8udmFsdWUgIT09IG51bGwpICYmIGpRdWVyeS50cmltKG8udmFsdWUpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgbWFwW28ubmFtZV0gPSBvLnZhbHVlO1xuICAgICAgfVxuICAgICAgaWYgKG8udHlwZSA9PT0gJ2ZpbGUnKSB7XG4gICAgICAgIG1hcFtvLm5hbWVdID0gby5maWxlc1swXTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmVmMiA9IGZvcm0uZmluZCgndGV4dGFyZWEnKTtcbiAgICBmb3IgKG0gPSAwLCBsZW4xID0gcmVmMi5sZW5ndGg7IG0gPCBsZW4xOyBtKyspIHtcbiAgICAgIG8gPSByZWYyW21dO1xuICAgICAgdmFsID0gdGhpcy5nZXRUZXh0QXJlYVZhbHVlKG8pO1xuICAgICAgaWYgKCh2YWwgIT09IG51bGwpICYmIGpRdWVyeS50cmltKHZhbCkubGVuZ3RoID4gMCkge1xuICAgICAgICBtYXBbby5uYW1lXSA9IHZhbDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmVmMyA9IGZvcm0uZmluZCgnc2VsZWN0Jyk7XG4gICAgZm9yIChuID0gMCwgbGVuMiA9IHJlZjMubGVuZ3RoOyBuIDwgbGVuMjsgbisrKSB7XG4gICAgICBvID0gcmVmM1tuXTtcbiAgICAgIHZhbCA9IHRoaXMuZ2V0U2VsZWN0ZWRWYWx1ZShvKTtcbiAgICAgIGlmICgodmFsICE9PSBudWxsKSAmJiBqUXVlcnkudHJpbSh2YWwpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgbWFwW28ubmFtZV0gPSB2YWw7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBtYXA7XG4gIH0sXG5cbiAgaXNGaWxlVXBsb2FkOiBmdW5jdGlvbiAoZm9ybSkge1xuICAgIHZhciByZWYxLCBsLCBsZW4sIG87XG4gICAgdmFyIGlzRmlsZVVwbG9hZCA9IGZhbHNlO1xuICAgIHJlZjEgPSBmb3JtLmZpbmQoJ2lucHV0Jyk7XG4gICAgZm9yIChsID0gMCwgbGVuID0gcmVmMS5sZW5ndGg7IGwgPCBsZW47IGwrKykge1xuICAgICAgbyA9IHJlZjFbbF07XG4gICAgICBpZiAoby50eXBlID09PSAnZmlsZScpIHtcbiAgICAgICAgaXNGaWxlVXBsb2FkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGlzRmlsZVVwbG9hZDtcbiAgfSxcblxuICBzdWNjZXNzOiBmdW5jdGlvbihyZXNwb25zZSwgcGFyZW50KSB7XG4gICAgcGFyZW50LnNob3dDb21wbGV0ZVN0YXR1cyhyZXNwb25zZSk7XG4gIH0sXG5cbiAgLy8gd3JhcHMgYSBqcXVlcnkgcmVzcG9uc2UgYXMgYSBzaHJlZCByZXNwb25zZVxuICB3cmFwOiBmdW5jdGlvbihkYXRhKSB7XG4gICAgdmFyIGgsIGhlYWRlckFycmF5LCBoZWFkZXJzLCBpLCBsLCBsZW4sIG87XG4gICAgaGVhZGVycyA9IHt9O1xuICAgIGhlYWRlckFycmF5ID0gZGF0YS5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKS5zcGxpdCgnXFxyJyk7XG4gICAgZm9yIChsID0gMCwgbGVuID0gaGVhZGVyQXJyYXkubGVuZ3RoOyBsIDwgbGVuOyBsKyspIHtcbiAgICAgIGkgPSBoZWFkZXJBcnJheVtsXTtcbiAgICAgIGggPSBpLm1hdGNoKC9eKFteOl0qPyk6KC4qKSQvKTtcbiAgICAgIGlmICghaCkge1xuICAgICAgICBoID0gW107XG4gICAgICB9XG4gICAgICBoLnNoaWZ0KCk7XG4gICAgICBpZiAoaFswXSAhPT0gdm9pZCAwICYmIGhbMV0gIT09IHZvaWQgMCkge1xuICAgICAgICBoZWFkZXJzW2hbMF0udHJpbSgpXSA9IGhbMV0udHJpbSgpO1xuICAgICAgfVxuICAgIH1cbiAgICBvID0ge307XG4gICAgby5jb250ZW50ID0ge307XG4gICAgby5jb250ZW50LmRhdGEgPSBkYXRhLnJlc3BvbnNlVGV4dDtcbiAgICBvLmhlYWRlcnMgPSBoZWFkZXJzO1xuICAgIG8ucmVxdWVzdCA9IHt9O1xuICAgIG8ucmVxdWVzdC51cmwgPSB0aGlzLmludm9jYXRpb25Vcmw7XG4gICAgby5zdGF0dXMgPSBkYXRhLnN0YXR1cztcbiAgICByZXR1cm4gbztcbiAgfSxcblxuICBnZXRTZWxlY3RlZFZhbHVlOiBmdW5jdGlvbihzZWxlY3QpIHtcbiAgICBpZiAoIXNlbGVjdC5tdWx0aXBsZSkge1xuICAgICAgcmV0dXJuIHNlbGVjdC52YWx1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIG9wdGlvbnMgPSBbXTtcbiAgICAgIGZvciAodmFyIGwgPSAwLCBsZW4gPSBzZWxlY3Qub3B0aW9ucy5sZW5ndGg7IGwgPCBsZW47IGwrKykge1xuICAgICAgICB2YXIgb3B0ID0gc2VsZWN0Lm9wdGlvbnNbbF07XG4gICAgICAgIGlmIChvcHQuc2VsZWN0ZWQpIHtcbiAgICAgICAgICBvcHRpb25zLnB1c2gob3B0LnZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG9wdGlvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm4gb3B0aW9ucztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICAvLyBoYW5kbGVyIGZvciBoaWRlIHJlc3BvbnNlIGxpbmtcbiAgaGlkZVJlc3BvbnNlOiBmdW5jdGlvbihlKSB7XG4gICAgaWYgKGUpIHsgZS5wcmV2ZW50RGVmYXVsdCgpOyB9XG4gICAgJCgnLnJlc3BvbnNlJywgJCh0aGlzLmVsKSkuc2xpZGVVcCgpO1xuICAgICQoJy5yZXNwb25zZV9oaWRlcicsICQodGhpcy5lbCkpLmZhZGVPdXQoKTtcbiAgfSxcblxuICAvLyBTaG93IHJlc3BvbnNlIGZyb20gc2VydmVyXG4gIHNob3dSZXNwb25zZTogZnVuY3Rpb24ocmVzcG9uc2UpIHtcbiAgICB2YXIgcHJldHR5SnNvbiA9IEpTT04uc3RyaW5naWZ5KHJlc3BvbnNlLCBudWxsLCAnXFx0JykucmVwbGFjZSgvXFxuL2csICc8YnI+Jyk7XG4gICAgJCgnLnJlc3BvbnNlX2JvZHknLCAkKHRoaXMuZWwpKS5odG1sKF8uZXNjYXBlKHByZXR0eUpzb24pKTtcbiAgfSxcblxuICAvLyBTaG93IGVycm9yIGZyb20gc2VydmVyXG4gIHNob3dFcnJvclN0YXR1czogZnVuY3Rpb24oZGF0YSwgcGFyZW50KSB7XG4gICAgcGFyZW50LnNob3dTdGF0dXMoZGF0YSk7XG4gIH0sXG5cbiAgLy8gc2hvdyB0aGUgc3RhdHVzIGNvZGVzXG4gIHNob3dDb21wbGV0ZVN0YXR1czogZnVuY3Rpb24oZGF0YSwgcGFyZW50KXtcbiAgICBwYXJlbnQuc2hvd1N0YXR1cyhkYXRhKTtcbiAgfSxcblxuICAvLyBBZGFwdGVkIGZyb20gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjg5MzI1OS80NTQwMDRcbiAgLy8gTm90ZTogZGlyZWN0bHkgcG9ydGVkIGZyb20gQ29mZmVlU2NyaXB0XG4gIC8vIFRPRE86IENsZWFudXAgQ29mZmVlU2NyaXB0IGFydGlmYWN0c1xuICBmb3JtYXRYbWw6IGZ1bmN0aW9uKHhtbCkge1xuICAgIHZhciBjb250ZXhwLCBmbiwgZm9ybWF0dGVkLCBpbmRlbnQsIGwsIGxhc3RUeXBlLCBsZW4sIGxpbmVzLCBsbiwgcGFkLCByZWcsIHRyYW5zaXRpb25zLCB3c2V4cDtcbiAgICByZWcgPSAvKD4pKDwpKFxcLyopL2c7XG4gICAgd3NleHAgPSAvWyBdKiguKilbIF0rXFxuL2c7XG4gICAgY29udGV4cCA9IC8oPC4rPikoLitcXG4pL2c7XG4gICAgeG1sID0geG1sLnJlcGxhY2UoL1xcclxcbi9nLCAnXFxuJykucmVwbGFjZShyZWcsICckMVxcbiQyJDMnKS5yZXBsYWNlKHdzZXhwLCAnJDFcXG4nKS5yZXBsYWNlKGNvbnRleHAsICckMVxcbiQyJyk7XG4gICAgcGFkID0gMDtcbiAgICBmb3JtYXR0ZWQgPSAnJztcbiAgICBsaW5lcyA9IHhtbC5zcGxpdCgnXFxuJyk7XG4gICAgaW5kZW50ID0gMDtcbiAgICBsYXN0VHlwZSA9ICdvdGhlcic7XG4gICAgdHJhbnNpdGlvbnMgPSB7XG4gICAgICAnc2luZ2xlLT5zaW5nbGUnOiAwLFxuICAgICAgJ3NpbmdsZS0+Y2xvc2luZyc6IC0xLFxuICAgICAgJ3NpbmdsZS0+b3BlbmluZyc6IDAsXG4gICAgICAnc2luZ2xlLT5vdGhlcic6IDAsXG4gICAgICAnY2xvc2luZy0+c2luZ2xlJzogMCxcbiAgICAgICdjbG9zaW5nLT5jbG9zaW5nJzogLTEsXG4gICAgICAnY2xvc2luZy0+b3BlbmluZyc6IDAsXG4gICAgICAnY2xvc2luZy0+b3RoZXInOiAwLFxuICAgICAgJ29wZW5pbmctPnNpbmdsZSc6IDEsXG4gICAgICAnb3BlbmluZy0+Y2xvc2luZyc6IDAsXG4gICAgICAnb3BlbmluZy0+b3BlbmluZyc6IDEsXG4gICAgICAnb3BlbmluZy0+b3RoZXInOiAxLFxuICAgICAgJ290aGVyLT5zaW5nbGUnOiAwLFxuICAgICAgJ290aGVyLT5jbG9zaW5nJzogLTEsXG4gICAgICAnb3RoZXItPm9wZW5pbmcnOiAwLFxuICAgICAgJ290aGVyLT5vdGhlcic6IDBcbiAgICB9O1xuICAgIGZuID0gZnVuY3Rpb24obG4pIHtcbiAgICAgIHZhciBmcm9tVG8sIGosIGtleSwgcGFkZGluZywgdHlwZSwgdHlwZXMsIHZhbHVlO1xuICAgICAgdHlwZXMgPSB7XG4gICAgICAgIHNpbmdsZTogQm9vbGVhbihsbi5tYXRjaCgvPC4rXFwvPi8pKSxcbiAgICAgICAgY2xvc2luZzogQm9vbGVhbihsbi5tYXRjaCgvPFxcLy4rPi8pKSxcbiAgICAgICAgb3BlbmluZzogQm9vbGVhbihsbi5tYXRjaCgvPFteIT9dLio+LykpXG4gICAgICB9O1xuICAgICAgdHlwZSA9ICgoZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciByZXN1bHRzO1xuICAgICAgICByZXN1bHRzID0gW107XG4gICAgICAgIGZvciAoa2V5IGluIHR5cGVzKSB7XG4gICAgICAgICAgdmFsdWUgPSB0eXBlc1trZXldO1xuICAgICAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAgICAgcmVzdWx0cy5wdXNoKGtleSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHRzO1xuICAgICAgfSkoKSlbMF07XG4gICAgICB0eXBlID0gdHlwZSA9PT0gdm9pZCAwID8gJ290aGVyJyA6IHR5cGU7XG4gICAgICBmcm9tVG8gPSBsYXN0VHlwZSArICctPicgKyB0eXBlO1xuICAgICAgbGFzdFR5cGUgPSB0eXBlO1xuICAgICAgcGFkZGluZyA9ICcnO1xuICAgICAgaW5kZW50ICs9IHRyYW5zaXRpb25zW2Zyb21Ub107XG4gICAgICBwYWRkaW5nID0gKChmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIG0sIHJlZjEsIHJlc3VsdHM7XG4gICAgICAgIHJlc3VsdHMgPSBbXTtcbiAgICAgICAgZm9yIChqID0gbSA9IDAsIHJlZjEgPSBpbmRlbnQ7IDAgPD0gcmVmMSA/IG0gPCByZWYxIDogbSA+IHJlZjE7IGogPSAwIDw9IHJlZjEgPyArK20gOiAtLW0pIHtcbiAgICAgICAgICByZXN1bHRzLnB1c2goJyAgJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgICB9KSgpKS5qb2luKCcnKTtcbiAgICAgIGlmIChmcm9tVG8gPT09ICdvcGVuaW5nLT5jbG9zaW5nJykge1xuICAgICAgICBmb3JtYXR0ZWQgPSBmb3JtYXR0ZWQuc3Vic3RyKDAsIGZvcm1hdHRlZC5sZW5ndGggLSAxKSArIGxuICsgJ1xcbic7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3JtYXR0ZWQgKz0gcGFkZGluZyArIGxuICsgJ1xcbic7XG4gICAgICB9XG4gICAgfTtcbiAgICBmb3IgKGwgPSAwLCBsZW4gPSBsaW5lcy5sZW5ndGg7IGwgPCBsZW47IGwrKykge1xuICAgICAgbG4gPSBsaW5lc1tsXTtcbiAgICAgIGZuKGxuKTtcbiAgICB9XG4gICAgcmV0dXJuIGZvcm1hdHRlZDtcbiAgfSxcblxuICAvLyBwdXRzIHRoZSByZXNwb25zZSBkYXRhIGluIFVJXG4gIHNob3dTdGF0dXM6IGZ1bmN0aW9uKHJlc3BvbnNlKSB7XG4gICAgdmFyIHVybCwgY29udGVudDtcbiAgICBpZiAocmVzcG9uc2UuY29udGVudCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb250ZW50ID0gcmVzcG9uc2UuZGF0YTtcbiAgICAgIHVybCA9IHJlc3BvbnNlLnVybDtcbiAgICB9IGVsc2Uge1xuICAgICAgY29udGVudCA9IHJlc3BvbnNlLmNvbnRlbnQuZGF0YTtcbiAgICAgIHVybCA9IHJlc3BvbnNlLnJlcXVlc3QudXJsO1xuICAgIH1cbiAgICB2YXIgaGVhZGVycyA9IHJlc3BvbnNlLmhlYWRlcnM7XG4gICAgaWYodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBjb250ZW50ID0galF1ZXJ5LnRyaW0oY29udGVudCk7XG4gICAgfVxuXG4gICAgLy8gaWYgc2VydmVyIGlzIG5pY2UsIGFuZCBzZW5kcyBjb250ZW50LXR5cGUgYmFjaywgd2UgY2FuIHVzZSBpdFxuICAgIHZhciBjb250ZW50VHlwZSA9IG51bGw7XG4gICAgaWYgKGhlYWRlcnMpIHtcbiAgICAgIGNvbnRlbnRUeXBlID0gaGVhZGVyc1snQ29udGVudC1UeXBlJ10gfHwgaGVhZGVyc1snY29udGVudC10eXBlJ107XG4gICAgICBpZiAoY29udGVudFR5cGUpIHtcbiAgICAgICAgY29udGVudFR5cGUgPSBjb250ZW50VHlwZS5zcGxpdCgnOycpWzBdLnRyaW0oKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAkKCcucmVzcG9uc2VfYm9keScsICQodGhpcy5lbCkpLnJlbW92ZUNsYXNzKCdqc29uJyk7XG4gICAgJCgnLnJlc3BvbnNlX2JvZHknLCAkKHRoaXMuZWwpKS5yZW1vdmVDbGFzcygneG1sJyk7XG5cbiAgICB2YXIgc3VwcG9ydHNBdWRpb1BsYXliYWNrID0gZnVuY3Rpb24oY29udGVudFR5cGUpe1xuICAgICAgdmFyIGF1ZGlvRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2F1ZGlvJyk7XG4gICAgICByZXR1cm4gISEoYXVkaW9FbGVtZW50LmNhblBsYXlUeXBlICYmIGF1ZGlvRWxlbWVudC5jYW5QbGF5VHlwZShjb250ZW50VHlwZSkucmVwbGFjZSgvbm8vLCAnJykpO1xuICAgIH07XG5cbiAgICB2YXIgcHJlO1xuICAgIHZhciBjb2RlO1xuICAgIHZhciBza2lwSGlnaGxpZ2h0ID0gZmFsc2U7XG4gICAgaWYgKCFjb250ZW50KSB7XG4gICAgICBjb2RlID0gJCgnPGNvZGUgLz4nKS50ZXh0KCdubyBjb250ZW50Jyk7XG4gICAgICBwcmUgPSAkKCc8cHJlIGNsYXNzPVwianNvblwiIC8+JykuYXBwZW5kKGNvZGUpO1xuXG4gICAgICAvLyBKU09OXG4gICAgfSBlbHNlIGlmIChcbiAgICAgICAgY29udGVudFR5cGUgPT09ICdhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nIHx8XG4gICAgICAgIGhlYWRlcnNbJ0NvbnRlbnQtRGlzcG9zaXRpb24nXSAmJiAoL2F0dGFjaG1lbnQvKS50ZXN0KGhlYWRlcnNbJ0NvbnRlbnQtRGlzcG9zaXRpb24nXSkgfHxcbiAgICAgICAgaGVhZGVyc1snY29udGVudC1kaXNwb3NpdGlvbiddICYmICgvYXR0YWNobWVudC8pLnRlc3QoaGVhZGVyc1snY29udGVudC1kaXNwb3NpdGlvbiddKSB8fFxuICAgICAgICBoZWFkZXJzWydDb250ZW50LURlc2NyaXB0aW9uJ10gJiYgKC9GaWxlIFRyYW5zZmVyLykudGVzdChoZWFkZXJzWydDb250ZW50LURlc2NyaXB0aW9uJ10pIHx8XG4gICAgICAgIGhlYWRlcnNbJ2NvbnRlbnQtZGVzY3JpcHRpb24nXSAmJiAoL0ZpbGUgVHJhbnNmZXIvKS50ZXN0KGhlYWRlcnNbJ2NvbnRlbnQtZGVzY3JpcHRpb24nXSkpIHtcblxuICAgICAgaWYgKCdCbG9iJyBpbiB3aW5kb3cpIHtcbiAgICAgICAgdmFyIHR5cGUgPSBjb250ZW50VHlwZSB8fCAndGV4dC9odG1sJztcbiAgICAgICAgdmFyIGEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XG4gICAgICAgIHZhciBocmVmO1xuXG4gICAgICAgIGlmKHt9LnRvU3RyaW5nLmFwcGx5KGNvbnRlbnQpID09PSAnW29iamVjdCBCbG9iXScpIHtcbiAgICAgICAgICBocmVmID0gd2luZG93LlVSTC5jcmVhdGVPYmplY3RVUkwoY29udGVudCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgdmFyIGJpbmFyeURhdGEgPSBbXTtcbiAgICAgICAgICBiaW5hcnlEYXRhLnB1c2goY29udGVudCk7XG4gICAgICAgICAgaHJlZiA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKG5ldyBCbG9iKGJpbmFyeURhdGEsIHt0eXBlOiB0eXBlfSkpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBmaWxlTmFtZSA9IHJlc3BvbnNlLnVybC5zdWJzdHIocmVzcG9uc2UudXJsLmxhc3RJbmRleE9mKCcvJykgKyAxKTtcbiAgICAgICAgdmFyIGRvd25sb2FkID0gW3R5cGUsIGZpbGVOYW1lLCBocmVmXS5qb2luKCc6Jyk7XG5cbiAgICAgICAgLy8gVXNlIGZpbGVuYW1lIGZyb20gcmVzcG9uc2UgaGVhZGVyXG4gICAgICAgIHZhciBkaXNwb3NpdGlvbiA9IGhlYWRlcnNbJ2NvbnRlbnQtZGlzcG9zaXRpb24nXSB8fCBoZWFkZXJzWydDb250ZW50LURpc3Bvc2l0aW9uJ107XG4gICAgICAgIGlmKHR5cGVvZiBkaXNwb3NpdGlvbiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICB2YXIgcmVzcG9uc2VGaWxlbmFtZSA9IC9maWxlbmFtZT0oW147XSopOz8vLmV4ZWMoZGlzcG9zaXRpb24pO1xuICAgICAgICAgIGlmKHJlc3BvbnNlRmlsZW5hbWUgIT09IG51bGwgJiYgcmVzcG9uc2VGaWxlbmFtZS5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICBkb3dubG9hZCA9IHJlc3BvbnNlRmlsZW5hbWVbMV07XG4gICAgICAgICAgICBmaWxlTmFtZSA9IGRvd25sb2FkO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGEuc2V0QXR0cmlidXRlKCdocmVmJywgaHJlZik7XG4gICAgICAgIGEuc2V0QXR0cmlidXRlKCdkb3dubG9hZCcsIGRvd25sb2FkKTtcbiAgICAgICAgYS5pbm5lclRleHQgPSAnRG93bmxvYWQgJyArIGZpbGVOYW1lO1xuXG4gICAgICAgIHByZSA9ICQoJzxkaXYvPicpLmFwcGVuZChhKTtcbiAgICAgICAgc2tpcEhpZ2hsaWdodCA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwcmUgPSAkKCc8cHJlIGNsYXNzPVwianNvblwiIC8+JykuYXBwZW5kKCdEb3dubG9hZCBoZWFkZXJzIGRldGVjdGVkIGJ1dCB5b3VyIGJyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCBkb3dubG9hZGluZyBiaW5hcnkgdmlhIFhIUiAoQmxvYikuJyk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChjb250ZW50VHlwZSA9PT0gJ2FwcGxpY2F0aW9uL2pzb24nIHx8IC9cXCtqc29uJC8udGVzdChjb250ZW50VHlwZSkpIHtcbiAgICAgIHZhciBqc29uID0gbnVsbDtcbiAgICAgIHRyeSB7XG4gICAgICAgIGpzb24gPSBKU09OLnN0cmluZ2lmeShKU09OLnBhcnNlKGNvbnRlbnQpLCBudWxsLCAnICAnKTtcbiAgICAgIH0gY2F0Y2ggKF9lcnJvcikge1xuICAgICAgICBqc29uID0gJ2NhblxcJ3QgcGFyc2UgSlNPTi4gIFJhdyByZXN1bHQ6XFxuXFxuJyArIGNvbnRlbnQ7XG4gICAgICB9XG4gICAgICBjb2RlID0gJCgnPGNvZGUgLz4nKS50ZXh0KGpzb24pO1xuICAgICAgcHJlID0gJCgnPHByZSBjbGFzcz1cImpzb25cIiAvPicpLmFwcGVuZChjb2RlKTtcblxuICAgICAgLy8gWE1MXG4gICAgfSBlbHNlIGlmIChjb250ZW50VHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3htbCcgfHwgL1xcK3htbCQvLnRlc3QoY29udGVudFR5cGUpKSB7XG4gICAgICBjb2RlID0gJCgnPGNvZGUgLz4nKS50ZXh0KHRoaXMuZm9ybWF0WG1sKGNvbnRlbnQpKTtcbiAgICAgIHByZSA9ICQoJzxwcmUgY2xhc3M9XCJ4bWxcIiAvPicpLmFwcGVuZChjb2RlKTtcblxuICAgICAgLy8gSFRNTFxuICAgIH0gZWxzZSBpZiAoY29udGVudFR5cGUgPT09ICd0ZXh0L2h0bWwnKSB7XG4gICAgICBjb2RlID0gJCgnPGNvZGUgLz4nKS5odG1sKF8uZXNjYXBlKGNvbnRlbnQpKTtcbiAgICAgIHByZSA9ICQoJzxwcmUgY2xhc3M9XCJ4bWxcIiAvPicpLmFwcGVuZChjb2RlKTtcblxuICAgICAgLy8gUGxhaW4gVGV4dFxuICAgIH0gZWxzZSBpZiAoL3RleHRcXC9wbGFpbi8udGVzdChjb250ZW50VHlwZSkpIHtcbiAgICAgIGNvZGUgPSAkKCc8Y29kZSAvPicpLnRleHQoY29udGVudCk7XG4gICAgICBwcmUgPSAkKCc8cHJlIGNsYXNzPVwicGxhaW5cIiAvPicpLmFwcGVuZChjb2RlKTtcblxuICAgICAgLy8gSW1hZ2VcbiAgICB9IGVsc2UgaWYgKC9eaW1hZ2VcXC8vLnRlc3QoY29udGVudFR5cGUpKSB7XG4gICAgICB2YXIgdXJsQ3JlYXRvciA9IHdpbmRvdy5VUkwgfHwgd2luZG93LndlYmtpdFVSTDtcbiAgICAgIHZhciBpbWFnZVVybCA9IHVybENyZWF0b3IuY3JlYXRlT2JqZWN0VVJMKGNvbnRlbnQpO1xuXG4gICAgICBwcmUgPSAkKCc8aW1nPicpLmF0dHIoICdzcmMnLCBpbWFnZVVybCk7XG4gICAgICAvLyBBdWRpb1xuICAgIH0gZWxzZSBpZiAoL15hdWRpb1xcLy8udGVzdChjb250ZW50VHlwZSkgJiYgc3VwcG9ydHNBdWRpb1BsYXliYWNrKGNvbnRlbnRUeXBlKSkge1xuICAgICAgcHJlID0gJCgnPGF1ZGlvIGNvbnRyb2xzPicpLmFwcGVuZCgkKCc8c291cmNlPicpLmF0dHIoJ3NyYycsIHVybCkuYXR0cigndHlwZScsIGNvbnRlbnRUeXBlKSk7XG4gICAgfSBlbHNlIGlmKGhlYWRlcnMubG9jYXRpb24gfHwgaGVhZGVycy5Mb2NhdGlvbikge1xuICAgICAgLy8gTG9jYXRpb24gaGVhZGVyIGJhc2VkIHJlZGlyZWN0IGRvd25sb2FkXG4gICAgICB3aW5kb3cubG9jYXRpb24gPSByZXNwb25zZS51cmw7XG5cbiAgICAgIC8vIEFueXRoaW5nIGVsc2UgKENPUlMpXG4gICAgfSBlbHNlIHtcbiAgICAgIGNvZGUgPSAkKCc8Y29kZSAvPicpLnRleHQoY29udGVudCk7XG4gICAgICBwcmUgPSAkKCc8cHJlIGNsYXNzPVwianNvblwiIC8+JykuYXBwZW5kKGNvZGUpO1xuICAgIH1cbiAgICB2YXIgcmVzcG9uc2VfYm9keSA9IHByZTtcbiAgICAkKCcucmVxdWVzdF91cmwnLCAkKHRoaXMuZWwpKS5odG1sKCc8cHJlPjwvcHJlPicpO1xuICAgICQoJy5yZXF1ZXN0X3VybCBwcmUnLCAkKHRoaXMuZWwpKS50ZXh0KHVybCk7XG4gICAgJCgnLnJlc3BvbnNlX2NvZGUnLCAkKHRoaXMuZWwpKS5odG1sKCc8cHJlPicgKyByZXNwb25zZS5zdGF0dXMgKyAnPC9wcmU+Jyk7XG4gICAgJCgnLnJlc3BvbnNlX2JvZHknLCAkKHRoaXMuZWwpKS5odG1sKHJlc3BvbnNlX2JvZHkpO1xuICAgICQoJy5yZXNwb25zZV9oZWFkZXJzJywgJCh0aGlzLmVsKSkuaHRtbCgnPHByZT4nICsgXy5lc2NhcGUoSlNPTi5zdHJpbmdpZnkocmVzcG9uc2UuaGVhZGVycywgbnVsbCwgJyAgJykpLnJlcGxhY2UoL1xcbi9nLCAnPGJyPicpICsgJzwvcHJlPicpO1xuICAgICQoJy5yZXNwb25zZScsICQodGhpcy5lbCkpLnNsaWRlRG93bigpO1xuICAgICQoJy5yZXNwb25zZV9oaWRlcicsICQodGhpcy5lbCkpLnNob3coKTtcbiAgICAkKCcucmVzcG9uc2VfdGhyb2JiZXInLCAkKHRoaXMuZWwpKS5oaWRlKCk7XG5cblxuICAgIC8vIGFkZHMgY3VybCBvdXRwdXRcbiAgICB2YXIgY3VybENvbW1hbmQgPSB0aGlzLm1vZGVsLmFzQ3VybCh0aGlzLm1hcCwge3Jlc3BvbnNlQ29udGVudFR5cGU6IGNvbnRlbnRUeXBlfSk7XG4gICAgY3VybENvbW1hbmQgPSBjdXJsQ29tbWFuZC5yZXBsYWNlKCchJywgJyYjMzM7Jyk7XG4gICAgJCggJ2Rpdi5jdXJsJywgJCh0aGlzLmVsKSkuaHRtbCgnPHByZT4nICsgXy5lc2NhcGUoY3VybENvbW1hbmQpICsgJzwvcHJlPicpO1xuXG4gICAgLy8gb25seSBoaWdobGlnaHQgdGhlIHJlc3BvbnNlIGlmIHJlc3BvbnNlIGlzIGxlc3MgdGhhbiB0aHJlc2hvbGQsIGRlZmF1bHQgc3RhdGUgaXMgaGlnaGxpZ2h0IHJlc3BvbnNlXG4gICAgdmFyIG9wdHMgPSB0aGlzLm9wdGlvbnMuc3dhZ2dlck9wdGlvbnM7XG5cbiAgICBpZiAob3B0cy5zaG93UmVxdWVzdEhlYWRlcnMpIHtcbiAgICAgIHZhciBmb3JtID0gJCgnLnNhbmRib3gnLCAkKHRoaXMuZWwpKSxcbiAgICAgICAgICBtYXAgPSB0aGlzLmdldElucHV0TWFwKGZvcm0pLFxuICAgICAgICAgIHJlcXVlc3RIZWFkZXJzID0gdGhpcy5tb2RlbC5nZXRIZWFkZXJQYXJhbXMobWFwKTtcbiAgICAgIGRlbGV0ZSByZXF1ZXN0SGVhZGVyc1snQ29udGVudC1UeXBlJ107XG4gICAgICAkKCcucmVxdWVzdF9oZWFkZXJzJywgJCh0aGlzLmVsKSkuaHRtbCgnPHByZT4nICsgXy5lc2NhcGUoSlNPTi5zdHJpbmdpZnkocmVxdWVzdEhlYWRlcnMsIG51bGwsICcgICcpKS5yZXBsYWNlKC9cXG4vZywgJzxicj4nKSArICc8L3ByZT4nKTtcbiAgICB9XG5cbiAgICAvLyBDYWxsIHVzZXItZGVmaW5lZCBob29rXG4gICAgaWYgKG9wdHMucmVzcG9uc2VIb29rcyAmJiBvcHRzLnJlc3BvbnNlSG9va3NbdGhpcy5uaWNrbmFtZV0pIHtcbiAgICAgIG9wdHMucmVzcG9uc2VIb29rc1t0aGlzLm5pY2tuYW1lXShyZXNwb25zZSwgdGhpcyk7XG4gICAgfVxuXG4gICAgdmFyIHJlc3BvbnNlX2JvZHlfZWwgPSAkKCcucmVzcG9uc2VfYm9keScsICQodGhpcy5lbCkpWzBdO1xuICAgIC8vIG9ubHkgaGlnaGxpZ2h0IHRoZSByZXNwb25zZSBpZiByZXNwb25zZSBpcyBsZXNzIHRoYW4gdGhyZXNob2xkLCBkZWZhdWx0IHN0YXRlIGlzIGhpZ2hsaWdodCByZXNwb25zZVxuICAgIGlmIChvcHRzLmhpZ2hsaWdodFNpemVUaHJlc2hvbGQgJiYgdHlwZW9mIHJlc3BvbnNlLmRhdGEgIT09ICd1bmRlZmluZWQnICYmIHJlc3BvbnNlLmRhdGEubGVuZ3RoID4gb3B0cy5oaWdobGlnaHRTaXplVGhyZXNob2xkIHx8IHNraXBIaWdobGlnaHQpIHtcbiAgICAgIHJldHVybiByZXNwb25zZV9ib2R5X2VsO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gaGxqcy5oaWdobGlnaHRCbG9jayhyZXNwb25zZV9ib2R5X2VsKTtcbiAgICB9XG4gIH0sXG5cbiAgdG9nZ2xlT3BlcmF0aW9uQ29udGVudDogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgdmFyIGVsZW0gPSAkKCcjJyArIERvY3MuZXNjYXBlUmVzb3VyY2VOYW1lKHRoaXMucGFyZW50SWQgKyAnXycgKyB0aGlzLm5pY2tuYW1lICsgJ19jb250ZW50JykpO1xuICAgIGlmIChlbGVtLmlzKCc6dmlzaWJsZScpKXtcbiAgICAgICQuYmJxLnB1c2hTdGF0ZSgnIy8nLCAyKTtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBEb2NzLmNvbGxhcHNlT3BlcmF0aW9uKGVsZW0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBEb2NzLmV4cGFuZE9wZXJhdGlvbihlbGVtKTtcbiAgICB9XG4gIH0sXG5cbiAgZ2V0VGV4dEFyZWFWYWx1ZTogZnVuY3Rpb24odGV4dEFyZWEpIHtcbiAgICB2YXIgcGFyYW0sIHBhcnNlZCwgcmVzdWx0LCBpO1xuICAgIGlmICh0ZXh0QXJlYS52YWx1ZSA9PT0gbnVsbCB8fCBqUXVlcnkudHJpbSh0ZXh0QXJlYS52YWx1ZSkubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcGFyYW0gPSB0aGlzLmdldFBhcmFtQnlOYW1lKHRleHRBcmVhLm5hbWUpO1xuICAgIGlmIChwYXJhbSAmJiBwYXJhbS50eXBlICYmIHBhcmFtLnR5cGUudG9Mb3dlckNhc2UoKSA9PT0gJ2FycmF5Jykge1xuICAgICAgcGFyc2VkID0gdGV4dEFyZWEudmFsdWUuc3BsaXQoJ1xcbicpO1xuICAgICAgcmVzdWx0ID0gW107XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgcGFyc2VkLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChwYXJzZWRbaV0gIT09IG51bGwgJiYgalF1ZXJ5LnRyaW0ocGFyc2VkW2ldKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgcmVzdWx0LnB1c2gocGFyc2VkW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdC5sZW5ndGggPiAwID8gcmVzdWx0IDogbnVsbDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRleHRBcmVhLnZhbHVlO1xuICAgIH1cbiAgfSxcblxuICBzaG93U25pcHBldDogZnVuY3Rpb24gKCkge1xuICAgIHZhciBjb250ZW50VHlwZUVsID0gdGhpcy4kKCdbbmFtZT1yZXNwb25zZUNvbnRlbnRUeXBlXScpO1xuICAgIHZhciB4bWxTbmlwcGV0RWwgPSB0aGlzLiQoJy5vcGVyYXRpb24tc3RhdHVzIC5zbmlwcGV0X3htbCwgLnJlc3BvbnNlLWNsYXNzIC5zbmlwcGV0X3htbCcpO1xuICAgIHZhciBqc29uU25pcHBldEVsID0gdGhpcy4kKCcub3BlcmF0aW9uLXN0YXR1cyAuc25pcHBldF9qc29uLCAucmVzcG9uc2UtY2xhc3MgLnNuaXBwZXRfanNvbicpO1xuICAgIHZhciBjb250ZW50VHlwZTtcblxuICAgIGlmICghY29udGVudFR5cGVFbC5sZW5ndGgpIHsgcmV0dXJuOyB9XG4gICAgY29udGVudFR5cGUgPSBjb250ZW50VHlwZUVsLnZhbCgpO1xuXG4gICAgaWYgKGNvbnRlbnRUeXBlLmluZGV4T2YoJ3htbCcpID4gLTEpIHtcbiAgICAgIHhtbFNuaXBwZXRFbC5zaG93KCk7XG4gICAgICBqc29uU25pcHBldEVsLmhpZGUoKTtcbiAgICB9IGVsc2Uge1xuICAgICAganNvblNuaXBwZXRFbC5zaG93KCk7XG4gICAgICB4bWxTbmlwcGV0RWwuaGlkZSgpO1xuICAgIH1cbiAgfSxcblxuICBnZXRQYXJhbUJ5TmFtZTogZnVuY3Rpb24obmFtZSkge1xuICAgIHZhciBpO1xuICAgIGlmICh0aGlzLm1vZGVsLnBhcmFtZXRlcnMpIHtcbiAgICAgIGZvcihpID0gMDsgaSA8IHRoaXMubW9kZWwucGFyYW1ldGVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAodGhpcy5tb2RlbC5wYXJhbWV0ZXJzW2ldLm5hbWUgPT09IG5hbWUpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5tb2RlbC5wYXJhbWV0ZXJzW2ldO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5Td2FnZ2VyVWkuVmlld3MuUGFyYW1ldGVyQ29udGVudFR5cGVWaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoe1xuICBpbml0aWFsaXplOiBmdW5jdGlvbiAgKCkge30sXG5cbiAgcmVuZGVyOiBmdW5jdGlvbigpe1xuICAgIHRoaXMubW9kZWwucGFyYW1ldGVyQ29udGVudFR5cGVJZCA9ICdwY3QnICsgTWF0aC5yYW5kb20oKTtcbiAgICAkKHRoaXMuZWwpLmh0bWwoSGFuZGxlYmFycy50ZW1wbGF0ZXMucGFyYW1ldGVyX2NvbnRlbnRfdHlwZSh0aGlzLm1vZGVsKSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxufSk7IiwiJ3VzZSBzdHJpY3QnO1xuXG5Td2FnZ2VyVWkuVmlld3MuUGFyYW1ldGVyVmlldyA9IEJhY2tib25lLlZpZXcuZXh0ZW5kKHtcbiAgZXZlbnRzOiB7XG4gICAgJ2NoYW5nZSBbbmFtZT1wYXJhbWV0ZXJDb250ZW50VHlwZV0nIDogJ3RvZ2dsZVBhcmFtZXRlclNuaXBwZXQnXG4gIH0sXG5cbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oKXtcbiAgICBIYW5kbGViYXJzLnJlZ2lzdGVySGVscGVyKCdpc0FycmF5JywgZnVuY3Rpb24ocGFyYW0sIG9wdHMpIHtcbiAgICAgIHZhciBwYXJhbVR5cGUgPSBwYXJhbS50eXBlICYmIHBhcmFtLnR5cGUudG9Mb3dlckNhc2UoKTtcbiAgICAgIGlmIChwYXJhbVR5cGUgPT09ICdhcnJheScgfHwgcGFyYW0uYWxsb3dNdWx0aXBsZSkge1xuICAgICAgICByZXR1cm4gb3B0cy5mbih0aGlzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBvcHRzLmludmVyc2UodGhpcyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0sXG5cbiAgcmVuZGVyOiBmdW5jdGlvbigpIHtcbiAgICB2YXIgdHlwZSA9IHRoaXMubW9kZWwudHlwZSB8fCB0aGlzLm1vZGVsLmRhdGFUeXBlO1xuICAgIHZhciBtb2RlbFR5cGUgPSB0aGlzLm1vZGVsLm1vZGVsU2lnbmF0dXJlLnR5cGU7XG4gICAgdmFyIG1vZGVsRGVmaW5pdGlvbnMgPSB0aGlzLm1vZGVsLm1vZGVsU2lnbmF0dXJlLmRlZmluaXRpb25zO1xuICAgIHZhciBzY2hlbWEgPSB0aGlzLm1vZGVsLnNjaGVtYSB8fCB7fTtcbiAgICB2YXIgY29uc3VtZXMgPSB0aGlzLm1vZGVsLmNvbnN1bWVzIHx8IFtdO1xuICAgIHZhciBzYW1wbGVKU09OLCBzaWduYXR1cmVWaWV3O1xuXG4gICAgaWYgKHR5cGVvZiB0eXBlID09PSAndW5kZWZpbmVkJykge1xuICAgICAgaWYgKHNjaGVtYS4kcmVmKSB7XG4gICAgICAgIHZhciByZWYgPSBzY2hlbWEuJHJlZjtcbiAgICAgICAgaWYgKHJlZi5pbmRleE9mKCcjL2RlZmluaXRpb25zLycpID09PSAwKSB7XG4gICAgICAgICAgdHlwZSA9IHJlZi5zdWJzdHJpbmcoJyMvZGVmaW5pdGlvbnMvJy5sZW5ndGgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHR5cGUgPSByZWY7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLm1vZGVsLnR5cGUgPSB0eXBlO1xuICAgIHRoaXMubW9kZWwucGFyYW1UeXBlID0gdGhpcy5tb2RlbC5pbiB8fCB0aGlzLm1vZGVsLnBhcmFtVHlwZTtcbiAgICB0aGlzLm1vZGVsLmlzQm9keSA9IHRoaXMubW9kZWwucGFyYW1UeXBlID09PSAnYm9keScgfHwgdGhpcy5tb2RlbC5pbiA9PT0gJ2JvZHknO1xuICAgIHRoaXMubW9kZWwuaXNGaWxlID0gdHlwZSAmJiB0eXBlLnRvTG93ZXJDYXNlKCkgPT09ICdmaWxlJztcblxuICAgIC8vIEFsbG93IGZvciBkZWZhdWx0ID09PSBmYWxzZVxuICAgIGlmKHR5cGVvZiB0aGlzLm1vZGVsLmRlZmF1bHQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB0aGlzLm1vZGVsLmRlZmF1bHQgPSB0aGlzLm1vZGVsLmRlZmF1bHRWYWx1ZTtcbiAgICB9XG5cbiAgICB0aGlzLm1vZGVsLmhhc0RlZmF1bHQgPSAodHlwZW9mIHRoaXMubW9kZWwuZGVmYXVsdCAhPT0gJ3VuZGVmaW5lZCcpO1xuICAgIHRoaXMubW9kZWwudmFsdWVJZCA9ICdtJyArIHRoaXMubW9kZWwubmFtZSArIE1hdGgucmFuZG9tKCk7XG5cbiAgICBpZiAodGhpcy5tb2RlbC5hbGxvd2FibGVWYWx1ZXMpIHtcbiAgICAgIHRoaXMubW9kZWwuaXNMaXN0ID0gdHJ1ZTtcbiAgICB9XG5cbiAgICB2YXIgaXNYTUwgPSB0aGlzLmNvbnRhaW5zKGNvbnN1bWVzLCAneG1sJyk7XG4gICAgdmFyIGlzSlNPTiA9IGlzWE1MID8gdGhpcy5jb250YWlucyhjb25zdW1lcywgJ2pzb24nKSA6IHRydWU7XG4gICAgc2FtcGxlSlNPTiA9IFN3YWdnZXJVaS5wYXJ0aWFscy5zaWduYXR1cmUuY3JlYXRlUGFyYW1ldGVySlNPTlNhbXBsZShtb2RlbFR5cGUsIG1vZGVsRGVmaW5pdGlvbnMpO1xuXG4gICAgdmFyIHRlbXBsYXRlID0gdGhpcy50ZW1wbGF0ZSgpO1xuICAgICQodGhpcy5lbCkuaHRtbCh0ZW1wbGF0ZSh0aGlzLm1vZGVsKSk7XG5cbiAgICB2YXIgc2lnbmF0dXJlTW9kZWwgPSB7XG4gICAgICBzYW1wbGVKU09OOiBpc0pTT04gPyBzYW1wbGVKU09OIDogZmFsc2UsXG4gICAgICBzYW1wbGVYTUw6IHNhbXBsZUpTT04gJiYgaXNYTUwgPyBTd2FnZ2VyVWkucGFydGlhbHMuc2lnbmF0dXJlLmNyZWF0ZVhNTFNhbXBsZSgnJywgc2NoZW1hLCBtb2RlbERlZmluaXRpb25zLCB0cnVlKSA6IGZhbHNlLFxuICAgICAgaXNQYXJhbTogdHJ1ZSxcbiAgICAgIHNpZ25hdHVyZTogU3dhZ2dlclVpLnBhcnRpYWxzLnNpZ25hdHVyZS5nZXRQYXJhbWV0ZXJNb2RlbFNpZ25hdHVyZShtb2RlbFR5cGUsIG1vZGVsRGVmaW5pdGlvbnMpLFxuICAgICAgZGVmYXVsdFJlbmRlcmluZzogdGhpcy5tb2RlbC5kZWZhdWx0UmVuZGVyaW5nXG4gICAgfTtcblxuICAgIGlmIChzYW1wbGVKU09OKSB7XG4gICAgICBzaWduYXR1cmVWaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5TaWduYXR1cmVWaWV3KHttb2RlbDogc2lnbmF0dXJlTW9kZWwsIHRhZ05hbWU6ICdkaXYnfSk7XG4gICAgICAkKCcubW9kZWwtc2lnbmF0dXJlJywgJCh0aGlzLmVsKSkuYXBwZW5kKHNpZ25hdHVyZVZpZXcucmVuZGVyKCkuZWwpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICQoJy5tb2RlbC1zaWduYXR1cmUnLCAkKHRoaXMuZWwpKS5odG1sKHRoaXMubW9kZWwuc2lnbmF0dXJlKTtcbiAgICB9XG5cbiAgICB2YXIgaXNQYXJhbSA9IGZhbHNlO1xuXG4gICAgaWYoIHRoaXMub3B0aW9ucy5zd2FnZ2VyT3B0aW9ucy5qc29uRWRpdG9yICYmIHRoaXMubW9kZWwuaXNCb2R5ICYmIHRoaXMubW9kZWwuc2NoZW1hKXtcbiAgICAgIHZhciAkc2VsZiA9ICQodGhpcy5lbCk7XG4gICAgICB0aGlzLm1vZGVsLmpzb25FZGl0b3IgPVxuICAgICAgICAvKiBnbG9iYWwgSlNPTkVkaXRvciAqL1xuICAgICAgICBuZXcgSlNPTkVkaXRvcigkKCcuZWRpdG9yX2hvbGRlcicsICRzZWxmKVswXSxcbiAgICAgICAgICAgICAgICAgICAgICAge3NjaGVtYTogdGhpcy5tb2RlbC5zY2hlbWEsIHN0YXJ0dmFsIDogdGhpcy5tb2RlbC5kZWZhdWx0LFxuICAgICAgICAgICAgICAgICAgICAgICAgYWpheDp0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzYWJsZV9wcm9wZXJ0aWVzOnRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNhYmxlX2VkaXRfanNvbjp0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgaWNvbmxpYjogJ3N3YWdnZXInIH0pO1xuICAgICAgLy8gVGhpcyBpcyBzbyB0aGF0IHRoZSBzaWduYXR1cmUgY2FuIHNlbmQgYmFjayB0aGUgc2FtcGxlIHRvIHRoZSBqc29uIGVkaXRvclxuICAgICAgLy8gVE9ETzogU2lnbmF0dXJlVmlldyBzaG91bGQgZXhwb3NlIGFuIGV2ZW50IFwib25TYW1wbGVDbGlja2VkXCIgaW5zdGVhZFxuICAgICAgc2lnbmF0dXJlTW9kZWwuanNvbkVkaXRvciA9IHRoaXMubW9kZWwuanNvbkVkaXRvcjtcbiAgICAgICQoJy5ib2R5LXRleHRhcmVhJywgJHNlbGYpLmhpZGUoKTtcbiAgICAgICQoJy5lZGl0b3JfaG9sZGVyJywgJHNlbGYpLnNob3coKTtcbiAgICAgICQoJy5wYXJhbWV0ZXItY29udGVudC10eXBlJywgJHNlbGYpXG4gICAgICAgIC5jaGFuZ2UoZnVuY3Rpb24oZSl7XG4gICAgICAgICAgICBpZihlLnRhcmdldC52YWx1ZSA9PT0gJ2FwcGxpY2F0aW9uL3htbCcpe1xuICAgICAgICAgICAgICAkKCcuYm9keS10ZXh0YXJlYScsICRzZWxmKS5zaG93KCk7XG4gICAgICAgICAgICAgICQoJy5lZGl0b3JfaG9sZGVyJywgJHNlbGYpLmhpZGUoKTtcbiAgICAgICAgICAgICAgdGhpcy5tb2RlbC5qc29uRWRpdG9yLmRpc2FibGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAkKCcuYm9keS10ZXh0YXJlYScsICRzZWxmKS5oaWRlKCk7XG4gICAgICAgICAgICAgICQoJy5lZGl0b3JfaG9sZGVyJywgJHNlbGYpLnNob3coKTtcbiAgICAgICAgICAgICAgdGhpcy5tb2RlbC5qc29uRWRpdG9yLmVuYWJsZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cblxuXG4gICAgaWYgKHRoaXMubW9kZWwuaXNCb2R5KSB7XG4gICAgICBpc1BhcmFtID0gdHJ1ZTtcbiAgICB9XG5cbiAgICB2YXIgY29udGVudFR5cGVNb2RlbCA9IHtcbiAgICAgIGlzUGFyYW06IGlzUGFyYW1cbiAgICB9O1xuXG4gICAgY29udGVudFR5cGVNb2RlbC5jb25zdW1lcyA9IHRoaXMubW9kZWwuY29uc3VtZXM7XG5cbiAgICBpZiAoaXNQYXJhbSkge1xuICAgICAgdmFyIHBhcmFtZXRlckNvbnRlbnRUeXBlVmlldyA9IG5ldyBTd2FnZ2VyVWkuVmlld3MuUGFyYW1ldGVyQ29udGVudFR5cGVWaWV3KHttb2RlbDogY29udGVudFR5cGVNb2RlbH0pO1xuICAgICAgJCgnLnBhcmFtZXRlci1jb250ZW50LXR5cGUnLCAkKHRoaXMuZWwpKS5hcHBlbmQocGFyYW1ldGVyQ29udGVudFR5cGVWaWV3LnJlbmRlcigpLmVsKTtcbiAgICAgIHRoaXMudG9nZ2xlUGFyYW1ldGVyU25pcHBldCgpO1xuICAgIH1cblxuICAgIGVsc2Uge1xuICAgICAgdmFyIHJlc3BvbnNlQ29udGVudFR5cGVWaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5SZXNwb25zZUNvbnRlbnRUeXBlVmlldyh7bW9kZWw6IGNvbnRlbnRUeXBlTW9kZWx9KTtcbiAgICAgICQoJy5yZXNwb25zZS1jb250ZW50LXR5cGUnLCAkKHRoaXMuZWwpKS5hcHBlbmQocmVzcG9uc2VDb250ZW50VHlwZVZpZXcucmVuZGVyKCkuZWwpO1xuICAgICAgdGhpcy50b2dnbGVSZXNwb25zZVNuaXBwZXQoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfSxcblxuICBjb250YWluczogZnVuY3Rpb24gKGNvbnN1bWVzLCB0eXBlKSB7XG4gICAgcmV0dXJuIGNvbnN1bWVzLmZpbHRlcihmdW5jdGlvbiAodmFsKSB7XG4gICAgICBpZiAodmFsLmluZGV4T2YodHlwZSkgPiAtMSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9KS5sZW5ndGg7XG4gIH0sXG5cbiAgdG9nZ2xlUGFyYW1ldGVyU25pcHBldDogZnVuY3Rpb24gKCkge1xuICAgIHZhciBjb250ZW50VHlwZSA9IHRoaXMuJCgnW25hbWU9cGFyYW1ldGVyQ29udGVudFR5cGVdJykudmFsKCk7XG5cbiAgICB0aGlzLnRvZ2dsZVNuaXBwZXQoY29udGVudFR5cGUpO1xuICB9LFxuXG4gIHRvZ2dsZVJlc3BvbnNlU25pcHBldDogZnVuY3Rpb24gKCkge1xuICAgIHZhciBjb250ZW50RWwgPSB0aGlzLiQoJ1tuYW1lPXJlc3BvbnNlQ29udGVudFR5cGVdJyk7XG5cbiAgICBpZiAoIWNvbnRlbnRFbC5sZW5ndGgpIHsgcmV0dXJuOyB9XG5cbiAgICB0aGlzLnRvZ2dsZVNuaXBwZXQoY29udGVudEVsLnZhbCgpKTtcbiAgfSxcblxuICB0b2dnbGVTbmlwcGV0OiBmdW5jdGlvbiAodHlwZSkge1xuICAgIHR5cGUgPSB0eXBlIHx8ICcnO1xuICAgIGlmICh0eXBlLmluZGV4T2YoJ3htbCcpID4gLTEpIHtcbiAgICAgIHRoaXMuJCgnLnNuaXBwZXRfeG1sJykuc2hvdygpO1xuICAgICAgdGhpcy4kKCcuc25pcHBldF9qc29uJykuaGlkZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLiQoJy5zbmlwcGV0X2pzb24nKS5zaG93KCk7XG4gICAgICB0aGlzLiQoJy5zbmlwcGV0X3htbCcpLmhpZGUoKTtcbiAgICB9XG4gIH0sXG5cbiAgLy8gUmV0dXJuIGFuIGFwcHJvcHJpYXRlIHRlbXBsYXRlIGJhc2VkIG9uIGlmIHRoZSBwYXJhbWV0ZXIgaXMgYSBsaXN0LCByZWFkb25seSwgcmVxdWlyZWRcbiAgdGVtcGxhdGU6IGZ1bmN0aW9uKCl7XG4gICAgaWYgKHRoaXMubW9kZWwuaXNMaXN0KSB7XG4gICAgICByZXR1cm4gSGFuZGxlYmFycy50ZW1wbGF0ZXMucGFyYW1fbGlzdDtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHRoaXMub3B0aW9ucy5yZWFkT25seSkge1xuICAgICAgICBpZiAodGhpcy5tb2RlbC5yZXF1aXJlZCkge1xuICAgICAgICAgIHJldHVybiBIYW5kbGViYXJzLnRlbXBsYXRlcy5wYXJhbV9yZWFkb25seV9yZXF1aXJlZDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gSGFuZGxlYmFycy50ZW1wbGF0ZXMucGFyYW1fcmVhZG9ubHk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0aGlzLm1vZGVsLnJlcXVpcmVkKSB7XG4gICAgICAgICAgcmV0dXJuIEhhbmRsZWJhcnMudGVtcGxhdGVzLnBhcmFtX3JlcXVpcmVkO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBIYW5kbGViYXJzLnRlbXBsYXRlcy5wYXJhbTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qIGpzaGludCAtVzEyMiAqL1xuU3dhZ2dlclVpLnBhcnRpYWxzLnNpZ25hdHVyZSA9IChmdW5jdGlvbiAoKSB7XG4gIC8vIGNvcHktcGFzdGVkIGZyb20gc3dhZ2dlci1qc1xuICB2YXIgcmVzb2x2ZVNjaGVtYSA9IGZ1bmN0aW9uIChzY2hlbWEpIHtcbiAgICBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5zY2hlbWEpKSB7XG4gICAgICBzY2hlbWEgPSByZXNvbHZlU2NoZW1hKHNjaGVtYS5zY2hlbWEpO1xuICAgIH1cblxuICAgIHJldHVybiBzY2hlbWE7XG4gIH07XG5cbiAgLy8gY29weS1wYXN0ZWQgZnJvbSBzd2FnZ2VyLWpzXG4gIHZhciBzaW1wbGVSZWYgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIGlmICh0eXBlb2YgbmFtZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGlmIChuYW1lLmluZGV4T2YoJyMvZGVmaW5pdGlvbnMvJykgPT09IDApIHtcbiAgICAgIHJldHVybiBuYW1lLnN1YnN0cmluZygnIy9kZWZpbml0aW9ucy8nLmxlbmd0aCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBuYW1lO1xuICAgIH1cbiAgfTtcblxuICAvLyBjb3B5LXBhc3RlZCBmcm9tIHN3YWdnZXItanNcbiAgdmFyIGdldElubGluZU1vZGVsID0gZnVuY3Rpb24oaW5saW5lU3RyKSB7XG4gICAgaWYoL15JbmxpbmUgTW9kZWwgXFxkKyQvLnRlc3QoaW5saW5lU3RyKSAmJiB0aGlzLmlubGluZU1vZGVscykge1xuICAgICAgdmFyIGlkID0gcGFyc2VJbnQoaW5saW5lU3RyLnN1YnN0cignSW5saW5lIE1vZGVsJy5sZW5ndGgpLnRyaW0oKSwxMCk7IC8vXG4gICAgICB2YXIgbW9kZWwgPSB0aGlzLmlubGluZU1vZGVsc1tpZF07XG4gICAgICByZXR1cm4gbW9kZWw7XG4gICAgfVxuICAgIC8vIEknbSByZXR1cm5pbmcgbnVsbCBoZXJlLCBzaG91bGQgSSByYXRoZXIgdGhyb3cgYW4gZXJyb3I/XG4gICAgcmV0dXJuIG51bGw7XG4gIH07XG5cbiAgLy8gY29weS1wYXN0ZWQgZnJvbSBzd2FnZ2VyLWpzXG4gIHZhciBmb3JtYXRYbWwgPSBmdW5jdGlvbih4bWwpIHtcbiAgICB2YXIgY29udGV4cCwgZm4sIGZvcm1hdHRlZCwgaW5kZW50LCBsLCBsYXN0VHlwZSwgbGVuLCBsaW5lcywgbG4sIHBhZCwgcmVnLCB0cmFuc2l0aW9ucywgd3NleHA7XG4gICAgcmVnID0gLyg+KSg8KShcXC8qKS9nO1xuICAgIHdzZXhwID0gL1sgXSooLiopWyBdK1xcbi9nO1xuICAgIGNvbnRleHAgPSAvKDwuKz4pKC4rXFxuKS9nO1xuICAgIHhtbCA9IHhtbC5yZXBsYWNlKHJlZywgJyQxXFxuJDIkMycpLnJlcGxhY2Uod3NleHAsICckMVxcbicpLnJlcGxhY2UoY29udGV4cCwgJyQxXFxuJDInKTtcbiAgICBwYWQgPSAwO1xuICAgIGZvcm1hdHRlZCA9ICcnO1xuICAgIGxpbmVzID0geG1sLnNwbGl0KCdcXG4nKTtcbiAgICBpbmRlbnQgPSAwO1xuICAgIGxhc3RUeXBlID0gJ290aGVyJztcbiAgICB0cmFuc2l0aW9ucyA9IHtcbiAgICAgICdzaW5nbGUtPnNpbmdsZSc6IDAsXG4gICAgICAnc2luZ2xlLT5jbG9zaW5nJzogLTEsXG4gICAgICAnc2luZ2xlLT5vcGVuaW5nJzogMCxcbiAgICAgICdzaW5nbGUtPm90aGVyJzogMCxcbiAgICAgICdjbG9zaW5nLT5zaW5nbGUnOiAwLFxuICAgICAgJ2Nsb3NpbmctPmNsb3NpbmcnOiAtMSxcbiAgICAgICdjbG9zaW5nLT5vcGVuaW5nJzogMCxcbiAgICAgICdjbG9zaW5nLT5vdGhlcic6IDAsXG4gICAgICAnb3BlbmluZy0+c2luZ2xlJzogMSxcbiAgICAgICdvcGVuaW5nLT5jbG9zaW5nJzogMCxcbiAgICAgICdvcGVuaW5nLT5vcGVuaW5nJzogMSxcbiAgICAgICdvcGVuaW5nLT5vdGhlcic6IDEsXG4gICAgICAnb3RoZXItPnNpbmdsZSc6IDAsXG4gICAgICAnb3RoZXItPmNsb3NpbmcnOiAtMSxcbiAgICAgICdvdGhlci0+b3BlbmluZyc6IDAsXG4gICAgICAnb3RoZXItPm90aGVyJzogMFxuICAgIH07XG4gICAgZm4gPSBmdW5jdGlvbihsbikge1xuICAgICAgdmFyIGZyb21Ubywgaiwga2V5LCBwYWRkaW5nLCB0eXBlLCB0eXBlcywgdmFsdWU7XG4gICAgICB0eXBlcyA9IHtcbiAgICAgICAgc2luZ2xlOiBCb29sZWFuKGxuLm1hdGNoKC88LitcXC8+LykpLFxuICAgICAgICBjbG9zaW5nOiBCb29sZWFuKGxuLm1hdGNoKC88XFwvLis+LykpLFxuICAgICAgICBvcGVuaW5nOiBCb29sZWFuKGxuLm1hdGNoKC88W14hP10uKj4vKSlcbiAgICAgIH07XG4gICAgICB0eXBlID0gKChmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIHJlc3VsdHM7XG4gICAgICAgIHJlc3VsdHMgPSBbXTtcbiAgICAgICAgZm9yIChrZXkgaW4gdHlwZXMpIHtcbiAgICAgICAgICB2YWx1ZSA9IHR5cGVzW2tleV07XG4gICAgICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgICAgICByZXN1bHRzLnB1c2goa2V5KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgICB9KSgpKVswXTtcbiAgICAgIHR5cGUgPSB0eXBlID09PSB2b2lkIDAgPyAnb3RoZXInIDogdHlwZTtcbiAgICAgIGZyb21UbyA9IGxhc3RUeXBlICsgJy0+JyArIHR5cGU7XG4gICAgICBsYXN0VHlwZSA9IHR5cGU7XG4gICAgICBwYWRkaW5nID0gJyc7XG4gICAgICBpbmRlbnQgKz0gdHJhbnNpdGlvbnNbZnJvbVRvXTtcbiAgICAgIHBhZGRpbmcgPSAoKGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgbSwgcmVmMSwgcmVzdWx0cztcbiAgICAgICAgcmVzdWx0cyA9IFtdO1xuICAgICAgICBmb3IgKGogPSBtID0gMCwgcmVmMSA9IGluZGVudDsgMCA8PSByZWYxID8gbSA8IHJlZjEgOiBtID4gcmVmMTsgaiA9IDAgPD0gcmVmMSA/ICsrbSA6IC0tbSkge1xuICAgICAgICAgIHJlc3VsdHMucHVzaCgnICAnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0cztcbiAgICAgIH0pKCkpLmpvaW4oJycpO1xuICAgICAgaWYgKGZyb21UbyA9PT0gJ29wZW5pbmctPmNsb3NpbmcnKSB7XG4gICAgICAgIGZvcm1hdHRlZCA9IGZvcm1hdHRlZC5zdWJzdHIoMCwgZm9ybWF0dGVkLmxlbmd0aCAtIDEpICsgbG4gKyAnXFxuJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZvcm1hdHRlZCArPSBwYWRkaW5nICsgbG4gKyAnXFxuJztcbiAgICAgIH1cbiAgICB9O1xuICAgIGZvciAobCA9IDAsIGxlbiA9IGxpbmVzLmxlbmd0aDsgbCA8IGxlbjsgbCsrKSB7XG4gICAgICBsbiA9IGxpbmVzW2xdO1xuICAgICAgZm4obG4pO1xuICAgIH1cbiAgICByZXR1cm4gZm9ybWF0dGVkO1xuICB9O1xuXG4gIC8vIGNvcHktcGFzdGVkIGZyb20gc3dhZ2dlci1qc1xuICB2YXIgZ2V0TW9kZWxTaWduYXR1cmUgPSBmdW5jdGlvbiAobmFtZSwgc2NoZW1hLCBtb2RlbHMsIG1vZGVsUHJvcGVydHlNYWNybykge1xuICAgIHZhciBzdHJvbmdPcGVuID0gJzxzcGFuIGNsYXNzPVwic3Ryb25nXCI+JztcbiAgICB2YXIgc3Ryb25nQ2xvc2UgPSAnPC9zcGFuPic7XG5cbiAgICB2YXIgb3B0aW9uSHRtbCA9IGZ1bmN0aW9uIChsYWJlbCwgdmFsdWUpIHtcbiAgICAgIHJldHVybiAnPHRyPjx0ZCBjbGFzcz1cIm9wdGlvbk5hbWVcIj4nICsgbGFiZWwgKyAnOjwvdGQ+PHRkPicgKyB2YWx1ZSArICc8L3RkPjwvdHI+JztcbiAgICB9O1xuXG5cbiAgICAvLyBBbGxvdyBmb3IgaWdub3JpbmcgdGhlICduYW1lJyBhcmd1bWVudC4uLi4gc2hpZnRpbmcgdGhlIHJlc3RcbiAgICBpZihfLmlzT2JqZWN0KGFyZ3VtZW50c1swXSkpIHtcbiAgICAgIG5hbWUgPSB2b2lkIDA7XG4gICAgICBzY2hlbWEgPSBhcmd1bWVudHNbMF07XG4gICAgICBtb2RlbHMgPSBhcmd1bWVudHNbMV07XG4gICAgICBtb2RlbFByb3BlcnR5TWFjcm8gPSBhcmd1bWVudHNbMl07XG4gICAgfVxuXG4gICAgbW9kZWxzID0gbW9kZWxzIHx8IHt9O1xuXG4gICAgLy8gUmVzb2x2ZSB0aGUgc2NoZW1hIChIYW5kbGUgbmVzdGVkIHNjaGVtYXMpXG4gICAgc2NoZW1hID0gcmVzb2x2ZVNjaGVtYShzY2hlbWEpO1xuXG4gICAgLy8gUmV0dXJuIGZvciBlbXB0eSBvYmplY3RcbiAgICBpZihfLmlzRW1wdHkoc2NoZW1hKSkge1xuICAgICAgcmV0dXJuIHN0cm9uZ09wZW4gKyAnRW1wdHknICsgc3Ryb25nQ2xvc2U7XG4gICAgfVxuXG4gICAgLy8gRGVyZWZlcmVuY2UgJHJlZiBmcm9tICdtb2RlbHMnXG4gICAgaWYodHlwZW9mIHNjaGVtYS4kcmVmID09PSAnc3RyaW5nJykge1xuICAgICAgbmFtZSA9IHNpbXBsZVJlZihzY2hlbWEuJHJlZik7XG4gICAgICBzY2hlbWEgPSBtb2RlbHNbbmFtZV07XG4gICAgICBpZih0eXBlb2Ygc2NoZW1hID09PSAndW5kZWZpbmVkJylcbiAgICAgIHtcbiAgICAgICAgcmV0dXJuIHN0cm9uZ09wZW4gKyBuYW1lICsgJyBpcyBub3QgZGVmaW5lZCEnICsgc3Ryb25nQ2xvc2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYodHlwZW9mIG5hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICBuYW1lID0gc2NoZW1hLnRpdGxlIHx8ICdJbmxpbmUgTW9kZWwnO1xuICAgIH1cblxuICAgIC8vIElmIHdlIGFyZSBhIE1vZGVsIG9iamVjdC4uLiBhZGp1c3QgYWNjb3JkaW5nbHlcbiAgICBpZihzY2hlbWEuZGVmaW5pdGlvbikge1xuICAgICAgc2NoZW1hID0gc2NoZW1hLmRlZmluaXRpb247XG4gICAgfVxuXG4gICAgaWYodHlwZW9mIG1vZGVsUHJvcGVydHlNYWNybyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgbW9kZWxQcm9wZXJ0eU1hY3JvID0gZnVuY3Rpb24ocHJvcCl7XG4gICAgICAgIHJldHVybiAocHJvcCB8fCB7fSkuZGVmYXVsdDtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgdmFyIHJlZmVyZW5jZXMgPSB7fTtcbiAgICB2YXIgc2Vlbk1vZGVscyA9IFtdO1xuICAgIHZhciBpbmxpbmVNb2RlbHMgPSAwO1xuXG4gICAgLy8gR2VuZXJhdGUgY3VycmVudCBIVE1MXG4gICAgdmFyIGh0bWwgPSBwcm9jZXNzTW9kZWwoc2NoZW1hLCBuYW1lKTtcblxuICAgIC8vIEdlbmVyYXRlIHJlZmVyZW5jZXMgSFRNTFxuICAgIHdoaWxlIChfLmtleXMocmVmZXJlbmNlcykubGVuZ3RoID4gMCkge1xuICAgICAgLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuICAgICAgXy5mb3JFYWNoKHJlZmVyZW5jZXMsIGZ1bmN0aW9uIChzY2hlbWEsIG5hbWUpIHtcbiAgICAgICAgdmFyIHNlZW5Nb2RlbCA9IF8uaW5kZXhPZihzZWVuTW9kZWxzLCBuYW1lKSA+IC0xO1xuXG4gICAgICAgIGRlbGV0ZSByZWZlcmVuY2VzW25hbWVdO1xuXG4gICAgICAgIGlmICghc2Vlbk1vZGVsKSB7XG4gICAgICAgICAgc2Vlbk1vZGVscy5wdXNoKG5hbWUpO1xuXG4gICAgICAgICAgaHRtbCArPSAnPGJyIC8+JyArIHByb2Nlc3NNb2RlbChzY2hlbWEsIG5hbWUpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIC8qIGpzaGludCBpZ25vcmU6ZW5kICovXG4gICAgfVxuXG4gICAgcmV0dXJuIGh0bWw7XG5cblxuICAgIGZ1bmN0aW9uIGFkZFJlZmVyZW5jZShzY2hlbWEsIG5hbWUsIHNraXBSZWYpIHtcbiAgICAgIHZhciBtb2RlbE5hbWUgPSBuYW1lO1xuICAgICAgdmFyIG1vZGVsO1xuXG4gICAgICBpZiAoc2NoZW1hLiRyZWYpIHtcbiAgICAgICAgbW9kZWxOYW1lID0gc2NoZW1hLnRpdGxlIHx8IHNpbXBsZVJlZihzY2hlbWEuJHJlZik7XG4gICAgICAgIG1vZGVsID0gbW9kZWxzW3NpbXBsZVJlZihzY2hlbWEuJHJlZildO1xuICAgICAgfSBlbHNlIGlmIChfLmlzVW5kZWZpbmVkKG5hbWUpKSB7XG4gICAgICAgIG1vZGVsTmFtZSA9IHNjaGVtYS50aXRsZSB8fCAnSW5saW5lIE1vZGVsICcgKyAoKytpbmxpbmVNb2RlbHMpO1xuICAgICAgICBtb2RlbCA9IHtkZWZpbml0aW9uOiBzY2hlbWF9O1xuICAgICAgfVxuXG4gICAgICBpZiAoc2tpcFJlZiAhPT0gdHJ1ZSkge1xuICAgICAgICByZWZlcmVuY2VzW21vZGVsTmFtZV0gPSBfLmlzVW5kZWZpbmVkKG1vZGVsKSA/IHt9IDogbW9kZWwuZGVmaW5pdGlvbjtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG1vZGVsTmFtZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwcmltaXRpdmVUb0hUTUwoc2NoZW1hKSB7XG4gICAgICB2YXIgaHRtbCA9ICc8c3BhbiBjbGFzcz1cInByb3BUeXBlXCI+JztcbiAgICAgIHZhciB0eXBlID0gc2NoZW1hLnR5cGUgfHwgJ29iamVjdCc7XG5cbiAgICAgIGlmIChzY2hlbWEuJHJlZikge1xuICAgICAgICBodG1sICs9IGFkZFJlZmVyZW5jZShzY2hlbWEsIHNpbXBsZVJlZihzY2hlbWEuJHJlZikpO1xuICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnb2JqZWN0Jykge1xuICAgICAgICBpZiAoIV8uaXNVbmRlZmluZWQoc2NoZW1hLnByb3BlcnRpZXMpKSB7XG4gICAgICAgICAgaHRtbCArPSBhZGRSZWZlcmVuY2Uoc2NoZW1hKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBodG1sICs9ICdvYmplY3QnO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdhcnJheScpIHtcbiAgICAgICAgaHRtbCArPSAnQXJyYXlbJztcblxuICAgICAgICBpZiAoXy5pc0FycmF5KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgICBodG1sICs9IF8ubWFwKHNjaGVtYS5pdGVtcywgYWRkUmVmZXJlbmNlKS5qb2luKCcsJyk7XG4gICAgICAgIH0gZWxzZSBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgICBpZiAoXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMuJHJlZikpIHtcbiAgICAgICAgICAgIGlmICghXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMudHlwZSkgJiYgXy5pbmRleE9mKFsnYXJyYXknLCAnb2JqZWN0J10sIHNjaGVtYS5pdGVtcy50eXBlKSA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgaHRtbCArPSBzY2hlbWEuaXRlbXMudHlwZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGh0bWwgKz0gYWRkUmVmZXJlbmNlKHNjaGVtYS5pdGVtcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGh0bWwgKz0gYWRkUmVmZXJlbmNlKHNjaGVtYS5pdGVtcywgc2ltcGxlUmVmKHNjaGVtYS5pdGVtcy4kcmVmKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCdBcnJheSB0eXBlXFwncyBcXCdpdGVtc1xcJyBzY2hlbWEgaXMgbm90IGFuIGFycmF5IG9yIGFuIG9iamVjdCwgY2Fubm90IHByb2Nlc3MnKTtcbiAgICAgICAgICBodG1sICs9ICdvYmplY3QnO1xuICAgICAgICB9XG5cbiAgICAgICAgaHRtbCArPSAnXSc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBodG1sICs9IHNjaGVtYS50eXBlO1xuICAgICAgfVxuXG4gICAgICBodG1sICs9ICc8L3NwYW4+JztcblxuICAgICAgcmV0dXJuIGh0bWw7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcHJpbWl0aXZlVG9PcHRpb25zSFRNTChzY2hlbWEsIGh0bWwpIHtcbiAgICAgIHZhciBvcHRpb25zID0gJyc7XG4gICAgICB2YXIgdHlwZSA9IHNjaGVtYS50eXBlIHx8ICdvYmplY3QnO1xuICAgICAgdmFyIGlzQXJyYXkgPSB0eXBlID09PSAnYXJyYXknO1xuXG4gICAgICBpZiAoIV8uaXNVbmRlZmluZWQoc2NoZW1hLmRlc2NyaXB0aW9uKSkge1xuICAgICAgICBodG1sICs9ICc6ICcgKyAnPHNwYW4gY2xhc3M9XCJwcm9wRGVzY1wiPicgKyBzY2hlbWEuZGVzY3JpcHRpb24gKyAnPC9zcGFuPic7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2hlbWEuZW51bSkge1xuICAgICAgICBodG1sICs9ICcgPSA8c3BhbiBjbGFzcz1cInByb3BWYWxzXCI+W1xcJycgKyBzY2hlbWEuZW51bS5qb2luKCdcXCcsIFxcJycpICsgJ1xcJ108L3NwYW4+JztcbiAgICAgIH1cblxuICAgICAgaWYgKGlzQXJyYXkpIHtcbiAgICAgICAgaWYgKF8uaXNQbGFpbk9iamVjdChzY2hlbWEuaXRlbXMpICYmICFfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcy50eXBlKSkge1xuICAgICAgICAgIHR5cGUgPSBzY2hlbWEuaXRlbXMudHlwZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0eXBlID0gJ29iamVjdCc7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKHNjaGVtYS5kZWZhdWx0KSkge1xuICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ0RlZmF1bHQnLCBzY2hlbWEuZGVmYXVsdCk7XG4gICAgICB9XG5cbiAgICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSAnc3RyaW5nJzpcbiAgICAgICAgaWYgKHNjaGVtYS5taW5MZW5ndGgpIHtcbiAgICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ01pbi4gTGVuZ3RoJywgc2NoZW1hLm1pbkxlbmd0aCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc2NoZW1hLm1heExlbmd0aCkge1xuICAgICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnTWF4LiBMZW5ndGgnLCBzY2hlbWEubWF4TGVuZ3RoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzY2hlbWEucGF0dGVybikge1xuICAgICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnUmVnLiBFeHAuJywgc2NoZW1hLnBhdHRlcm4pO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnaW50ZWdlcic6XG4gICAgICBjYXNlICdudW1iZXInOlxuICAgICAgICBpZiAoc2NoZW1hLm1pbmltdW0pIHtcbiAgICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ01pbi4gVmFsdWUnLCBzY2hlbWEubWluaW11bSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc2NoZW1hLmV4Y2x1c2l2ZU1pbmltdW0pIHtcbiAgICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ0V4Y2x1c2l2ZSBNaW4uJywgJ3RydWUnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzY2hlbWEubWF4aW11bSkge1xuICAgICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnTWF4LiBWYWx1ZScsIHNjaGVtYS5tYXhpbXVtKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzY2hlbWEuZXhjbHVzaXZlTWF4aW11bSkge1xuICAgICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnRXhjbHVzaXZlIE1heC4nLCAndHJ1ZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNjaGVtYS5tdWx0aXBsZU9mKSB7XG4gICAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdNdWx0aXBsZSBPZicsIHNjaGVtYS5tdWx0aXBsZU9mKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNBcnJheSkge1xuICAgICAgICBpZiAoc2NoZW1hLm1pbkl0ZW1zKSB7XG4gICAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdNaW4uIEl0ZW1zJywgc2NoZW1hLm1pbkl0ZW1zKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzY2hlbWEubWF4SXRlbXMpIHtcbiAgICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ01heC4gSXRlbXMnLCBzY2hlbWEubWF4SXRlbXMpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNjaGVtYS51bmlxdWVJdGVtcykge1xuICAgICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnVW5pcXVlIEl0ZW1zJywgJ3RydWUnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzY2hlbWEuY29sbGVjdGlvbkZvcm1hdCkge1xuICAgICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnQ29sbC4gRm9ybWF0Jywgc2NoZW1hLmNvbGxlY3Rpb25Gb3JtYXQpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgaWYgKF8uaXNBcnJheShzY2hlbWEuZW51bSkpIHtcbiAgICAgICAgICB2YXIgZW51bVN0cmluZztcblxuICAgICAgICAgIGlmICh0eXBlID09PSAnbnVtYmVyJyB8fCB0eXBlID09PSAnaW50ZWdlcicpIHtcbiAgICAgICAgICAgIGVudW1TdHJpbmcgPSBzY2hlbWEuZW51bS5qb2luKCcsICcpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBlbnVtU3RyaW5nID0gJ1wiJyArIHNjaGVtYS5lbnVtLmpvaW4oJ1wiLCBcIicpICsgJ1wiJztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ0VudW0nLCBlbnVtU3RyaW5nKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAob3B0aW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGh0bWwgPSAnPHNwYW4gY2xhc3M9XCJwcm9wV3JhcFwiPicgKyBodG1sICsgJzx0YWJsZSBjbGFzcz1cIm9wdGlvbnNXcmFwcGVyXCI+PHRyPjx0aCBjb2xzcGFuPVwiMlwiPicgKyB0eXBlICsgJzwvdGg+PC90cj4nICsgb3B0aW9ucyArICc8L3RhYmxlPjwvc3Bhbj4nO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gaHRtbDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwcm9jZXNzTW9kZWwoc2NoZW1hLCBuYW1lKSB7XG4gICAgICB2YXIgdHlwZSA9IHNjaGVtYS50eXBlIHx8ICdvYmplY3QnO1xuICAgICAgdmFyIGlzQXJyYXkgPSBzY2hlbWEudHlwZSA9PT0gJ2FycmF5JztcbiAgICAgIHZhciBodG1sID0gc3Ryb25nT3BlbiArIG5hbWUgKyAnICcgKyAoaXNBcnJheSA/ICdbJyA6ICd7JykgKyBzdHJvbmdDbG9zZTtcbiAgICAgIHZhciBjb250ZW50cztcblxuICAgICAgaWYgKG5hbWUpIHtcbiAgICAgICAgc2Vlbk1vZGVscy5wdXNoKG5hbWUpO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNBcnJheSkge1xuICAgICAgICBpZiAoXy5pc0FycmF5KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgICBodG1sICs9ICc8ZGl2PicgKyBfLm1hcChzY2hlbWEuaXRlbXMsIGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICB2YXIgdHlwZSA9IGl0ZW0udHlwZSB8fCAnb2JqZWN0JztcblxuICAgICAgICAgICAgaWYgKF8uaXNVbmRlZmluZWQoaXRlbS4kcmVmKSkge1xuICAgICAgICAgICAgICBpZiAoXy5pbmRleE9mKFsnYXJyYXknLCAnb2JqZWN0J10sIHR5cGUpID4gLTEpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZSA9PT0gJ29iamVjdCcgJiYgXy5pc1VuZGVmaW5lZChpdGVtLnByb3BlcnRpZXMpKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gJ29iamVjdCc7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBhZGRSZWZlcmVuY2UoaXRlbSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBwcmltaXRpdmVUb09wdGlvbnNIVE1MKGl0ZW0sIHR5cGUpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXR1cm4gYWRkUmVmZXJlbmNlKGl0ZW0sIHNpbXBsZVJlZihpdGVtLiRyZWYpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KS5qb2luKCcsPC9kaXY+PGRpdj4nKTtcbiAgICAgICAgfSBlbHNlIGlmIChfLmlzUGxhaW5PYmplY3Qoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICAgIGlmIChfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcy4kcmVmKSkge1xuICAgICAgICAgICAgaWYgKF8uaW5kZXhPZihbJ2FycmF5JywgJ29iamVjdCddLCBzY2hlbWEuaXRlbXMudHlwZSB8fCAnb2JqZWN0JykgPiAtMSkge1xuICAgICAgICAgICAgICBpZiAoKF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zLnR5cGUpIHx8IHNjaGVtYS5pdGVtcy50eXBlID09PSAnb2JqZWN0JykgJiYgXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMucHJvcGVydGllcykpIHtcbiAgICAgICAgICAgICAgICBodG1sICs9ICc8ZGl2Pm9iamVjdDwvZGl2Pic7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaHRtbCArPSAnPGRpdj4nICsgYWRkUmVmZXJlbmNlKHNjaGVtYS5pdGVtcykgKyAnPC9kaXY+JztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgaHRtbCArPSAnPGRpdj4nICsgcHJpbWl0aXZlVG9PcHRpb25zSFRNTChzY2hlbWEuaXRlbXMsIHNjaGVtYS5pdGVtcy50eXBlKSArICc8L2Rpdj4nO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBodG1sICs9ICc8ZGl2PicgKyBhZGRSZWZlcmVuY2Uoc2NoZW1hLml0ZW1zLCBzaW1wbGVSZWYoc2NoZW1hLml0ZW1zLiRyZWYpKSArICc8L2Rpdj4nO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zb2xlLmxvZygnQXJyYXkgdHlwZVxcJ3MgXFwnaXRlbXNcXCcgcHJvcGVydHkgaXMgbm90IGFuIGFycmF5IG9yIGFuIG9iamVjdCwgY2Fubm90IHByb2Nlc3MnKTtcbiAgICAgICAgICBodG1sICs9ICc8ZGl2Pm9iamVjdDwvZGl2Pic7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChzY2hlbWEuJHJlZikge1xuICAgICAgICAgIGh0bWwgKz0gJzxkaXY+JyArIGFkZFJlZmVyZW5jZShzY2hlbWEsIG5hbWUpICsgJzwvZGl2Pic7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5wcm9wZXJ0aWVzKSkge1xuICAgICAgICAgICAgY29udGVudHMgPSBfLm1hcChzY2hlbWEucHJvcGVydGllcywgZnVuY3Rpb24gKHByb3BlcnR5LCBuYW1lKSB7XG4gICAgICAgICAgICAgIHZhciBwcm9wZXJ0eUlzUmVxdWlyZWQgPSAoXy5pbmRleE9mKHNjaGVtYS5yZXF1aXJlZCwgbmFtZSkgPj0gMCk7XG4gICAgICAgICAgICAgIHZhciBjUHJvcGVydHkgPSBfLmNsb25lRGVlcChwcm9wZXJ0eSk7XG5cbiAgICAgICAgICAgICAgdmFyIHJlcXVpcmVkQ2xhc3MgPSBwcm9wZXJ0eUlzUmVxdWlyZWQgPyAncmVxdWlyZWQnIDogJyc7XG4gICAgICAgICAgICAgIHZhciBodG1sID0gJzxzcGFuIGNsYXNzPVwicHJvcE5hbWUgJyArIHJlcXVpcmVkQ2xhc3MgKyAnXCI+JyArIG5hbWUgKyAnPC9zcGFuPiAoJztcbiAgICAgICAgICAgICAgdmFyIG1vZGVsO1xuXG4gICAgICAgICAgICAgIC8vIEFsbG93IG1hY3JvIHRvIHNldCB0aGUgZGVmYXVsdCB2YWx1ZVxuICAgICAgICAgICAgICBjUHJvcGVydHkuZGVmYXVsdCA9IG1vZGVsUHJvcGVydHlNYWNybyhjUHJvcGVydHkpO1xuXG4gICAgICAgICAgICAgIC8vIFJlc29sdmUgdGhlIHNjaGVtYSAoSGFuZGxlIG5lc3RlZCBzY2hlbWFzKVxuICAgICAgICAgICAgICBjUHJvcGVydHkgPSByZXNvbHZlU2NoZW1hKGNQcm9wZXJ0eSk7XG5cbiAgICAgICAgICAgICAgLy8gV2UgbmVlZCB0byBoYW5kbGUgcHJvcGVydHkgcmVmZXJlbmNlcyB0byBwcmltaXRpdmVzIChJc3N1ZSAzMzkpXG4gICAgICAgICAgICAgIGlmICghXy5pc1VuZGVmaW5lZChjUHJvcGVydHkuJHJlZikpIHtcbiAgICAgICAgICAgICAgICBtb2RlbCA9IG1vZGVsc1tzaW1wbGVSZWYoY1Byb3BlcnR5LiRyZWYpXTtcblxuICAgICAgICAgICAgICAgIGlmICghXy5pc1VuZGVmaW5lZChtb2RlbCkgJiYgXy5pbmRleE9mKFt1bmRlZmluZWQsICdhcnJheScsICdvYmplY3QnXSwgbW9kZWwuZGVmaW5pdGlvbi50eXBlKSA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgIC8vIFVzZSByZWZlcmVuY2VkIHNjaGVtYVxuICAgICAgICAgICAgICAgICAgY1Byb3BlcnR5ID0gcmVzb2x2ZVNjaGVtYShtb2RlbC5kZWZpbml0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBodG1sICs9IHByaW1pdGl2ZVRvSFRNTChjUHJvcGVydHkpO1xuXG4gICAgICAgICAgICAgIGlmKCFwcm9wZXJ0eUlzUmVxdWlyZWQpIHtcbiAgICAgICAgICAgICAgICBodG1sICs9ICcsIDxzcGFuIGNsYXNzPVwicHJvcE9wdEtleVwiPm9wdGlvbmFsPC9zcGFuPic7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBpZihwcm9wZXJ0eS5yZWFkT25seSkge1xuICAgICAgICAgICAgICAgICAgaHRtbCArPSAnLCA8c3BhbiBjbGFzcz1cInByb3BSZWFkT25seVwiPnJlYWQgb25seTwvc3Bhbj4nO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgaHRtbCArPSAnKSc7XG5cbiAgICAgICAgICAgICAgcmV0dXJuICc8ZGl2JyArIChwcm9wZXJ0eS5yZWFkT25seSA/ICcgY2xhc3M9XCJyZWFkT25seVwiJyA6ICcnKSArICc+JyArIHByaW1pdGl2ZVRvT3B0aW9uc0hUTUwoY1Byb3BlcnR5LCBodG1sKTtcbiAgICAgICAgICAgIH0pLmpvaW4oJyw8L2Rpdj4nKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoY29udGVudHMpIHtcbiAgICAgICAgICAgIGh0bWwgKz0gY29udGVudHMgKyAnPC9kaXY+JztcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaHRtbCArPSAnPGRpdj4nICsgcHJpbWl0aXZlVG9PcHRpb25zSFRNTChzY2hlbWEsIHR5cGUpICsgJzwvZGl2Pic7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGh0bWwgKyBzdHJvbmdPcGVuICsgKGlzQXJyYXkgPyAnXScgOiAnfScpICsgc3Ryb25nQ2xvc2U7XG4gICAgfVxuXG4gIH07XG5cbiAgLy8gY29weS1wYXN0ZWQgZnJvbSBzd2FnZ2VyLWpzXG4gIHZhciBzY2hlbWFUb0pTT04gPSBmdW5jdGlvbiAoc2NoZW1hLCBtb2RlbHMsIG1vZGVsc1RvSWdub3JlLCBtb2RlbFByb3BlcnR5TWFjcm8pIHtcbiAgICAvLyBSZXNvbHZlIHRoZSBzY2hlbWEgKEhhbmRsZSBuZXN0ZWQgc2NoZW1hcylcbiAgICBzY2hlbWEgPSByZXNvbHZlU2NoZW1hKHNjaGVtYSk7XG5cbiAgICBpZih0eXBlb2YgbW9kZWxQcm9wZXJ0eU1hY3JvICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICBtb2RlbFByb3BlcnR5TWFjcm8gPSBmdW5jdGlvbihwcm9wKXtcbiAgICAgICAgcmV0dXJuIChwcm9wIHx8IHt9KS5kZWZhdWx0O1xuICAgICAgfTtcbiAgICB9XG5cbiAgICBtb2RlbHNUb0lnbm9yZT0gbW9kZWxzVG9JZ25vcmUgfHwge307XG5cbiAgICB2YXIgdHlwZSA9IHNjaGVtYS50eXBlIHx8ICdvYmplY3QnO1xuICAgIHZhciBmb3JtYXQgPSBzY2hlbWEuZm9ybWF0O1xuICAgIHZhciBtb2RlbDtcbiAgICB2YXIgb3V0cHV0O1xuXG4gICAgaWYgKCFfLmlzVW5kZWZpbmVkKHNjaGVtYS5leGFtcGxlKSkge1xuICAgICAgb3V0cHV0ID0gc2NoZW1hLmV4YW1wbGU7XG4gICAgfSBlbHNlIGlmIChfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcykgJiYgXy5pc0FycmF5KHNjaGVtYS5lbnVtKSkge1xuICAgICAgb3V0cHV0ID0gc2NoZW1hLmVudW1bMF07XG4gICAgfVxuXG4gICAgaWYgKF8uaXNVbmRlZmluZWQob3V0cHV0KSkge1xuICAgICAgaWYgKHNjaGVtYS4kcmVmKSB7XG4gICAgICAgIG1vZGVsID0gbW9kZWxzW3NpbXBsZVJlZihzY2hlbWEuJHJlZildO1xuXG4gICAgICAgIGlmICghXy5pc1VuZGVmaW5lZChtb2RlbCkpIHtcbiAgICAgICAgICBpZiAoXy5pc1VuZGVmaW5lZChtb2RlbHNUb0lnbm9yZVttb2RlbC5uYW1lXSkpIHtcbiAgICAgICAgICAgIG1vZGVsc1RvSWdub3JlW21vZGVsLm5hbWVdID0gbW9kZWw7XG4gICAgICAgICAgICBvdXRwdXQgPSBzY2hlbWFUb0pTT04obW9kZWwuZGVmaW5pdGlvbiwgbW9kZWxzLCBtb2RlbHNUb0lnbm9yZSwgbW9kZWxQcm9wZXJ0eU1hY3JvKTtcbiAgICAgICAgICAgIGRlbGV0ZSBtb2RlbHNUb0lnbm9yZVttb2RlbC5uYW1lXTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKG1vZGVsLnR5cGUgPT09ICdhcnJheScpIHtcbiAgICAgICAgICAgICAgb3V0cHV0ID0gW107XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBvdXRwdXQgPSB7fTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoIV8uaXNVbmRlZmluZWQoc2NoZW1hLmRlZmF1bHQpKSB7XG4gICAgICAgIG91dHB1dCA9IHNjaGVtYS5kZWZhdWx0O1xuICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgICBpZiAoZm9ybWF0ID09PSAnZGF0ZS10aW1lJykge1xuICAgICAgICAgIG91dHB1dCA9IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKTtcbiAgICAgICAgfSBlbHNlIGlmIChmb3JtYXQgPT09ICdkYXRlJykge1xuICAgICAgICAgIG91dHB1dCA9IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKS5zcGxpdCgnVCcpWzBdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG91dHB1dCA9ICdzdHJpbmcnO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdpbnRlZ2VyJykge1xuICAgICAgICBvdXRwdXQgPSAwO1xuICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJykge1xuICAgICAgICBvdXRwdXQgPSAwLjA7XG4gICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdib29sZWFuJykge1xuICAgICAgICBvdXRwdXQgPSB0cnVlO1xuICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnb2JqZWN0Jykge1xuICAgICAgICBvdXRwdXQgPSB7fTtcblxuICAgICAgICBfLmZvckVhY2goc2NoZW1hLnByb3BlcnRpZXMsIGZ1bmN0aW9uIChwcm9wZXJ0eSwgbmFtZSkge1xuICAgICAgICAgIHZhciBjUHJvcGVydHkgPSBfLmNsb25lRGVlcChwcm9wZXJ0eSk7XG5cbiAgICAgICAgICAvLyBBbGxvdyBtYWNybyB0byBzZXQgdGhlIGRlZmF1bHQgdmFsdWVcbiAgICAgICAgICBjUHJvcGVydHkuZGVmYXVsdCA9IG1vZGVsUHJvcGVydHlNYWNybyhwcm9wZXJ0eSk7XG5cbiAgICAgICAgICBvdXRwdXRbbmFtZV0gPSBzY2hlbWFUb0pTT04oY1Byb3BlcnR5LCBtb2RlbHMsIG1vZGVsc1RvSWdub3JlLCBtb2RlbFByb3BlcnR5TWFjcm8pO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2FycmF5Jykge1xuICAgICAgICBvdXRwdXQgPSBbXTtcblxuICAgICAgICBpZiAoXy5pc0FycmF5KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgICBfLmZvckVhY2goc2NoZW1hLml0ZW1zLCBmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgICAgb3V0cHV0LnB1c2goc2NoZW1hVG9KU09OKGl0ZW0sIG1vZGVscywgbW9kZWxzVG9JZ25vcmUsIG1vZGVsUHJvcGVydHlNYWNybykpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKF8uaXNQbGFpbk9iamVjdChzY2hlbWEuaXRlbXMpKSB7XG4gICAgICAgICAgb3V0cHV0LnB1c2goc2NoZW1hVG9KU09OKHNjaGVtYS5pdGVtcywgbW9kZWxzLCBtb2RlbHNUb0lnbm9yZSwgbW9kZWxQcm9wZXJ0eU1hY3JvKSk7XG4gICAgICAgIH0gZWxzZSBpZiAoXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMpKSB7XG4gICAgICAgICAgb3V0cHV0LnB1c2goe30pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCdBcnJheSB0eXBlXFwncyBcXCdpdGVtc1xcJyBwcm9wZXJ0eSBpcyBub3QgYW4gYXJyYXkgb3IgYW4gb2JqZWN0LCBjYW5ub3QgcHJvY2VzcycpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dHB1dDtcbiAgfTtcblxuICAvLyBjb3B5LXBhc3RlZCBmcm9tIHN3YWdnZXItanNcbiAgdmFyIGNyZWF0ZUpTT05TYW1wbGUgPSBmdW5jdGlvbiAodmFsdWUsIG1vZGVsc1RvSWdub3JlKSB7XG4gICAgbW9kZWxzVG9JZ25vcmUgPSBtb2RlbHNUb0lnbm9yZSB8fCB7fTtcblxuICAgIG1vZGVsc1RvSWdub3JlW3ZhbHVlLm5hbWVdID0gdmFsdWU7XG5cbiAgICAvLyBSZXNwb25zZSBzdXBwb3J0XG4gICAgaWYgKHZhbHVlLmV4YW1wbGVzICYmIF8uaXNQbGFpbk9iamVjdCh2YWx1ZS5leGFtcGxlcykpIHtcbiAgICAgIHZhbHVlID0gXy5jbG9uZURlZXAodmFsdWUpO1xuICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyh2YWx1ZS5leGFtcGxlcyk7XG5cbiAgICAgIF8uZm9yRWFjaChrZXlzLCBmdW5jdGlvbihrZXkpIHtcbiAgICAgICAgaWYoa2V5LmluZGV4T2YoJ2FwcGxpY2F0aW9uL2pzb24nKSA9PT0gMCkge1xuICAgICAgICAgIHZhciBleGFtcGxlID0gdmFsdWUuZXhhbXBsZXNba2V5XTtcbiAgICAgICAgICBpZiAoXy5pc1N0cmluZyhleGFtcGxlKSkge1xuICAgICAgICAgICAgZXhhbXBsZSA9IGpzeWFtbC5zYWZlTG9hZChleGFtcGxlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdmFsdWUuZGVmaW5pdGlvbi5leGFtcGxlID0gZXhhbXBsZTtcbiAgICAgICAgICByZXR1cm4gc2NoZW1hVG9KU09OKHZhbHVlLmRlZmluaXRpb24sIGV4YW1wbGUsIG1vZGVsc1RvSWdub3JlLCB2YWx1ZS5tb2RlbFByb3BlcnR5TWFjcm8pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAodmFsdWUuZXhhbXBsZXMpIHtcbiAgICAgIHZhbHVlID0gXy5jbG9uZURlZXAodmFsdWUpO1xuICAgICAgdmFyIGV4YW1wbGUgPSB2YWx1ZS5leGFtcGxlcztcbiAgICAgIGlmIChfLmlzU3RyaW5nKGV4YW1wbGUpKSB7XG4gICAgICAgIGV4YW1wbGUgPSBqc3lhbWwuc2FmZUxvYWQoZXhhbXBsZSk7XG4gICAgICB9XG4gICAgICB2YWx1ZS5kZWZpbml0aW9uLmV4YW1wbGUgPSBleGFtcGxlO1xuICAgICAgcmV0dXJuIHNjaGVtYVRvSlNPTih2YWx1ZS5kZWZpbml0aW9uLCBleGFtcGxlLCBtb2RlbHNUb0lnbm9yZSwgdmFsdWUubW9kZWxQcm9wZXJ0eU1hY3JvKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2NoZW1hVG9KU09OKHZhbHVlLmRlZmluaXRpb24sIHZhbHVlLm1vZGVscywgbW9kZWxzVG9JZ25vcmUsIHZhbHVlLm1vZGVsUHJvcGVydHlNYWNybyk7XG4gIH07XG5cbiAgLy8gY29weS1wYXN0ZWQgZnJvbSBzd2FnZ2VyLWpzXG4gIHZhciBnZXRQYXJhbWV0ZXJNb2RlbFNpZ25hdHVyZSA9IGZ1bmN0aW9uICh0eXBlLCBkZWZpbml0aW9ucykge1xuICAgICAgdmFyIGlzUHJpbWl0aXZlLCBsaXN0VHlwZTtcblxuICAgICAgaWYgKHR5cGUgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICBsaXN0VHlwZSA9IHRydWU7XG4gICAgICAgIHR5cGUgPSB0eXBlWzBdO1xuICAgICAgfVxuXG4gICAgICAvLyBDb252ZXJ0IHVuZGVmaW5lZCB0byBzdHJpbmcgb2YgJ3VuZGVmaW5lZCdcbiAgICAgIGlmICh0eXBlb2YgdHlwZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgdHlwZSA9ICd1bmRlZmluZWQnO1xuICAgICAgICBpc1ByaW1pdGl2ZSA9IHRydWU7XG5cbiAgICAgIH0gZWxzZSBpZiAoZGVmaW5pdGlvbnNbdHlwZV0pe1xuICAgICAgICAvLyBhIG1vZGVsIGRlZiBleGlzdHM/XG4gICAgICAgIHR5cGUgPSBkZWZpbml0aW9uc1t0eXBlXTsgLyogTW9kZWwgKi9cbiAgICAgICAgaXNQcmltaXRpdmUgPSBmYWxzZTtcblxuICAgICAgfSBlbHNlIGlmIChnZXRJbmxpbmVNb2RlbCh0eXBlKSkge1xuICAgICAgICB0eXBlID0gZ2V0SW5saW5lTW9kZWwodHlwZSk7IC8qIE1vZGVsICovXG4gICAgICAgIGlzUHJpbWl0aXZlID0gZmFsc2U7XG5cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFdlIGRlZmF1bHQgdG8gcHJpbWl0aXZlXG4gICAgICAgIGlzUHJpbWl0aXZlID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzUHJpbWl0aXZlKSB7XG4gICAgICAgIGlmIChsaXN0VHlwZSkge1xuICAgICAgICAgIHJldHVybiAnQXJyYXlbJyArIHR5cGUgKyAnXSc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHR5cGUudG9TdHJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGxpc3RUeXBlKSB7XG4gICAgICAgICAgcmV0dXJuICdBcnJheVsnICsgZ2V0TW9kZWxTaWduYXR1cmUodHlwZS5uYW1lLCB0eXBlLmRlZmluaXRpb24sIHR5cGUubW9kZWxzLCB0eXBlLm1vZGVsUHJvcGVydHlNYWNybykgKyAnXSc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIGdldE1vZGVsU2lnbmF0dXJlKHR5cGUubmFtZSwgdHlwZS5kZWZpbml0aW9uLCB0eXBlLm1vZGVscywgdHlwZS5tb2RlbFByb3BlcnR5TWFjcm8pO1xuICAgICAgICB9XG4gICAgICB9XG4gIH07XG5cbiAgLy8gY29weS1wYXN0ZWQgZnJvbSBzd2FnZ2VyLWpzXG4gIHZhciBjcmVhdGVQYXJhbWV0ZXJKU09OU2FtcGxlID0gZnVuY3Rpb24gKHR5cGUsIG1vZGVscykge1xuICAgIHZhciBsaXN0VHlwZSwgc2FtcGxlSnNvbiwgaW5uZXJUeXBlO1xuICAgIG1vZGVscyA9IG1vZGVscyB8fCB7fTtcblxuICAgIGxpc3RUeXBlID0gKHR5cGUgaW5zdGFuY2VvZiBBcnJheSk7XG4gICAgaW5uZXJUeXBlID0gbGlzdFR5cGUgPyB0eXBlWzBdIDogdHlwZTtcblxuICAgIGlmKG1vZGVsc1tpbm5lclR5cGVdKSB7XG4gICAgICBzYW1wbGVKc29uID0gY3JlYXRlSlNPTlNhbXBsZShtb2RlbHNbaW5uZXJUeXBlXSk7XG4gICAgfSBlbHNlIGlmIChnZXRJbmxpbmVNb2RlbChpbm5lclR5cGUpKXtcbiAgICAgIHNhbXBsZUpzb24gPSBjcmVhdGVKU09OU2FtcGxlKGdldElubGluZU1vZGVsKGlubmVyVHlwZSkpOyAvLyBtYXkgcmV0dXJuIG51bGwsIGlmIHR5cGUgaXNuJ3QgY29ycmVjdFxuICAgIH1cblxuXG4gICAgaWYgKHNhbXBsZUpzb24pIHtcbiAgICAgIHNhbXBsZUpzb24gPSBsaXN0VHlwZSA/IFtzYW1wbGVKc29uXSA6IHNhbXBsZUpzb247XG5cbiAgICAgIGlmICh0eXBlb2Ygc2FtcGxlSnNvbiA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIHNhbXBsZUpzb247XG4gICAgICB9IGVsc2UgaWYgKF8uaXNPYmplY3Qoc2FtcGxlSnNvbikpIHtcbiAgICAgICAgdmFyIHQgPSBzYW1wbGVKc29uO1xuXG4gICAgICAgIGlmIChzYW1wbGVKc29uIGluc3RhbmNlb2YgQXJyYXkgJiYgc2FtcGxlSnNvbi5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgdCA9IHNhbXBsZUpzb25bMF07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodC5ub2RlTmFtZSAmJiB0eXBlb2YgdCA9PT0gJ05vZGUnKSB7XG4gICAgICAgICAgdmFyIHhtbFN0cmluZyA9IG5ldyBYTUxTZXJpYWxpemVyKCkuc2VyaWFsaXplVG9TdHJpbmcodCk7XG5cbiAgICAgICAgICByZXR1cm4gZm9ybWF0WG1sKHhtbFN0cmluZyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHNhbXBsZUpzb24sIG51bGwsIDIpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gc2FtcGxlSnNvbjtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgdmFyIHdyYXBUYWcgPSBmdW5jdGlvbiAobmFtZSwgdmFsdWUsIGF0dHJzKSB7XG4gICAgdmFyIHN0ciwgYXR0cmlidXRlcztcblxuICAgIGF0dHJzID0gYXR0cnMgfHwgW107XG5cbiAgICBhdHRyaWJ1dGVzID0gYXR0cnMubWFwKGZ1bmN0aW9uIChhdHRyKSB7XG4gICAgICByZXR1cm4gJyAnICsgYXR0ci5uYW1lICsgJz1cIicgKyBhdHRyLnZhbHVlICsgJ1wiJztcbiAgICB9KS5qb2luKCcnKTtcblxuICAgIGlmICghbmFtZSkge1xuICAgICAgcmV0dXJuIGdldEVycm9yTWVzc2FnZSgnTm9kZSBuYW1lIGlzIG5vdCBwcm92aWRlZCcpO1xuICAgIH1cblxuICAgIHN0ciA9IFtcbiAgICAgICc8JywgbmFtZSxcbiAgICAgIGF0dHJpYnV0ZXMsXG4gICAgICAnPicsXG4gICAgICB2YWx1ZSxcbiAgICAgICc8LycsIG5hbWUsICc+J1xuICAgIF07XG5cbiAgICByZXR1cm4gc3RyLmpvaW4oJycpO1xuICB9O1xuXG4gIC8vIENvbW1lbnRpbmcgdGhpcyBmdW50aW9uIGFzIHRoZSBuYW1lcyBhcmUgbm93IGRldGVybWluZWQgYmVmb3JlaGFuZCBhbmQgdGhlIHByZWZpeCBwYXJ0IGlzIGV4cG9zZWQgYXMgYSBzZXBhcmF0ZSBmdW5jdGlvbiB8IGh0dHBzOi8vZ2l0aHViLmNvbS9zd2FnZ2VyLWFwaS9zd2FnZ2VyLXVpL2lzc3Vlcy8yNTc3XG4gLyoqIHZhciBnZXROYW1lID0gZnVuY3Rpb24gKG5hbWUsIHhtbCkge1xuICAgIHZhciByZXN1bHQgPSBuYW1lIHx8ICcnO1xuXG4gICAgeG1sID0geG1sIHx8IHt9O1xuXG4gICAgaWYgKHhtbC5uYW1lKSB7XG4gICAgICByZXN1bHQgPSB4bWwubmFtZTtcbiAgICB9XG5cbiAgICBpZiAoeG1sLnByZWZpeCkge1xuICAgICAgcmVzdWx0ID0geG1sLnByZWZpeCArICc6JyArIHJlc3VsdDtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuICAqL1xuICBcbiAgdmFyIGdldFByZWZpeCA9IGZ1bmN0aW9uIChuYW1lLCB4bWwpIHtcbiAgICB2YXIgcmVzdWx0ID0gbmFtZSB8fCAnJztcblxuICAgIHhtbCA9IHhtbCB8fCB7fTtcblxuICAgIGlmICh4bWwucHJlZml4KSB7XG4gICAgICByZXN1bHQgPSB4bWwucHJlZml4ICsgJzonICsgcmVzdWx0O1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG5cbiAgdmFyIGdldE5hbWVzcGFjZSA9IGZ1bmN0aW9uICh4bWwpIHtcbiAgICB2YXIgbmFtZXNwYWNlID0gJyc7XG4gICAgdmFyIG5hbWUgPSAneG1sbnMnO1xuXG4gICAgeG1sID0geG1sIHx8IHt9O1xuXG4gICAgaWYgKHhtbC5uYW1lc3BhY2UpIHtcbiAgICAgIG5hbWVzcGFjZSA9IHhtbC5uYW1lc3BhY2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBuYW1lc3BhY2U7XG4gICAgfVxuXG4gICAgaWYgKHhtbC5wcmVmaXgpIHtcbiAgICAgIG5hbWUgKz0gJzonICsgeG1sLnByZWZpeDtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgbmFtZTogbmFtZSxcbiAgICAgIHZhbHVlOiBuYW1lc3BhY2VcbiAgICB9O1xuICB9O1xuXG4gIHZhciBjcmVhdGVBcnJheVhNTCA9IGZ1bmN0aW9uIChkZXNjcmlwdG9yKSB7XG4gICAgdmFyIG5hbWUgPSBkZXNjcmlwdG9yLm5hbWU7XG4gICAgdmFyIGNvbmZpZyA9IGRlc2NyaXB0b3IuY29uZmlnO1xuICAgIHZhciBkZWZpbml0aW9uID0gZGVzY3JpcHRvci5kZWZpbml0aW9uO1xuICAgIHZhciBtb2RlbHMgPSBkZXNjcmlwdG9yLm1vZGVscztcbiAgICB2YXIgdmFsdWU7XG4gICAgdmFyIGl0ZW1zID0gZGVmaW5pdGlvbi5pdGVtcztcbiAgICB2YXIgeG1sID0gZGVmaW5pdGlvbi54bWwgfHwge307XG4gICAgdmFyIG5hbWVzcGFjZSA9IGdldE5hbWVzcGFjZSh4bWwpO1xuICAgIHZhciBhdHRyaWJ1dGVzID0gW107XG5cbiAgICBpZiAoIWl0ZW1zKSB7IHJldHVybiBnZXRFcnJvck1lc3NhZ2UoKTsgfVxuICAgIHZhciBrZXkgPSBuYW1lO1xuICAgIC8vIElmIHRoZXJlIGlzIGEgbmFtZSBzcGVjaWZpZWQgZm9yIHRoZSBhcnJheSBlbGVtZW50cywgdXNlIHRoYXQgZm9yIHRoZSBhcnJheSBlbGVtZW50cyBuYW1lIHwgaHR0cHM6Ly9naXRodWIuY29tL3N3YWdnZXItYXBpL3N3YWdnZXItdWkvaXNzdWVzLzI1NzdcbiAgICBpZihpdGVtcy54bWwgJiYgaXRlbXMueG1sLm5hbWUpIHtcbiAgICAgICAga2V5ID0gaXRlbXMueG1sLm5hbWU7XG4gICAgfVxuICAgIHZhbHVlID0gY3JlYXRlU2NoZW1hWE1MKGtleSwgaXRlbXMsIG1vZGVscywgY29uZmlnKTtcbiAgICBpZiAobmFtZXNwYWNlKSB7XG4gICAgICBhdHRyaWJ1dGVzLnB1c2gobmFtZXNwYWNlKTtcbiAgICB9XG5cbiAgICBpZiAoeG1sLndyYXBwZWQpIHtcbiAgICAgIHZhbHVlID0gd3JhcFRhZyhuYW1lLCB2YWx1ZSwgYXR0cmlidXRlcyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlO1xuICB9O1xuXG4gIHZhciBnZXRQcmltaXRpdmVTaWduYXR1cmUgPSBmdW5jdGlvbiAoc2NoZW1hKSB7XG4gICAgdmFyIHR5cGUsIGl0ZW1zO1xuXG4gICAgc2NoZW1hID0gc2NoZW1hIHx8IHt9O1xuICAgIGl0ZW1zID0gc2NoZW1hLml0ZW1zIHx8IHt9O1xuICAgIHR5cGUgPSBzY2hlbWEudHlwZSB8fCAnJztcblxuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSAnb2JqZWN0JzogcmV0dXJuICdPYmplY3QgaXMgbm90IGEgcHJpbWl0aXZlJztcbiAgICAgIGNhc2UgJ2FycmF5JyA6IHJldHVybiAnQXJyYXlbJyArIChpdGVtcy5mb3JtYXQgfHwgaXRlbXMudHlwZSkgKyAnXSc7XG4gICAgICBkZWZhdWx0OiByZXR1cm4gc2NoZW1hLmZvcm1hdCB8fCB0eXBlO1xuICAgIH1cbiAgfTtcblxuICB2YXIgY3JlYXRlUHJpbWl0aXZlWE1MID0gZnVuY3Rpb24gKGRlc2NyaXB0b3IpIHtcbiAgICB2YXIgbmFtZSA9IGRlc2NyaXB0b3IubmFtZTtcbiAgICB2YXIgZGVmaW5pdGlvbiA9IGRlc2NyaXB0b3IuZGVmaW5pdGlvbjtcbiAgICB2YXIgcHJpbWl0aXZlc01hcCA9IHtcbiAgICAgICdzdHJpbmcnOiB7XG4gICAgICAgICdkYXRlJzogbmV3IERhdGUoMSkudG9JU09TdHJpbmcoKS5zcGxpdCgnVCcpWzBdLFxuICAgICAgICAnZGF0ZS10aW1lJyA6IG5ldyBEYXRlKDEpLnRvSVNPU3RyaW5nKCksXG4gICAgICAgICdkZWZhdWx0JzogJ3N0cmluZydcbiAgICAgIH0sXG4gICAgICAnaW50ZWdlcic6IHtcbiAgICAgICAgJ2RlZmF1bHQnOiAxXG4gICAgICB9LFxuICAgICAgJ251bWJlcic6IHtcbiAgICAgICAgJ2RlZmF1bHQnOiAxLjFcbiAgICAgIH0sXG4gICAgICAnYm9vbGVhbic6IHtcbiAgICAgICAgJ2RlZmF1bHQnOiB0cnVlXG4gICAgICB9XG4gICAgfTtcbiAgICB2YXIgdHlwZSA9IGRlZmluaXRpb24udHlwZTtcbiAgICB2YXIgZm9ybWF0ID0gZGVmaW5pdGlvbi5mb3JtYXQ7XG4gICAgdmFyIHhtbCA9IGRlZmluaXRpb24ueG1sIHx8IHt9O1xuICAgIHZhciBuYW1lc3BhY2UgPSBnZXROYW1lc3BhY2UoeG1sKTtcbiAgICB2YXIgYXR0cmlidXRlcyA9IFtdO1xuICAgIHZhciB2YWx1ZTtcblxuICAgIGlmIChfLmtleXMocHJpbWl0aXZlc01hcCkuaW5kZXhPZih0eXBlKSA8IDApIHsgcmV0dXJuIGdldEVycm9yTWVzc2FnZSgpOyB9XG5cbiAgICBpZiAoXy5pc0FycmF5KGRlZmluaXRpb24uZW51bSkpe1xuICAgICAgdmFsdWUgPSBkZWZpbml0aW9uLmVudW1bMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhbHVlID0gZGVmaW5pdGlvbi5leGFtcGxlIHx8IHByaW1pdGl2ZXNNYXBbdHlwZV1bZm9ybWF0XSB8fCBwcmltaXRpdmVzTWFwW3R5cGVdLmRlZmF1bHQ7XG4gICAgfVxuXG4gICAgaWYgKHhtbC5hdHRyaWJ1dGUpIHtcbiAgICAgIHJldHVybiB7bmFtZTogbmFtZSwgdmFsdWU6IHZhbHVlfTtcbiAgICB9XG5cbiAgICBpZiAobmFtZXNwYWNlKSB7XG4gICAgICBhdHRyaWJ1dGVzLnB1c2gobmFtZXNwYWNlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gd3JhcFRhZyhuYW1lLCB2YWx1ZSwgYXR0cmlidXRlcyk7XG4gIH07XG5cbiAgZnVuY3Rpb24gY3JlYXRlT2JqZWN0WE1MIChkZXNjcmlwdG9yKSB7XG4gICAgdmFyIG5hbWUgPSBkZXNjcmlwdG9yLm5hbWU7XG4gICAgdmFyIGRlZmluaXRpb24gPSBkZXNjcmlwdG9yLmRlZmluaXRpb247XG4gICAgdmFyIGNvbmZpZyA9IGRlc2NyaXB0b3IuY29uZmlnO1xuICAgIHZhciBtb2RlbHMgPSBkZXNjcmlwdG9yLm1vZGVscztcbiAgICB2YXIgaXNQYXJhbSA9IGRlc2NyaXB0b3IuY29uZmlnLmlzUGFyYW07XG4gICAgdmFyIHNlcmlhbGl6ZWRQcm9wZXJ0aWVzO1xuICAgIHZhciBhdHRycyA9IFtdO1xuICAgIHZhciBwcm9wZXJ0aWVzID0gZGVmaW5pdGlvbi5wcm9wZXJ0aWVzO1xuICAgIHZhciBhZGRpdGlvbmFsUHJvcGVydGllcyA9IGRlZmluaXRpb24uYWRkaXRpb25hbFByb3BlcnRpZXM7XG4gICAgdmFyIHhtbCA9IGRlZmluaXRpb24ueG1sO1xuICAgIHZhciBuYW1lc3BhY2UgPSBnZXROYW1lc3BhY2UoeG1sKTtcblxuICAgIGlmIChuYW1lc3BhY2UpIHtcbiAgICAgIGF0dHJzLnB1c2gobmFtZXNwYWNlKTtcbiAgICB9ICAgXG5cbiAgICBpZiAoIXByb3BlcnRpZXMgJiYgIWFkZGl0aW9uYWxQcm9wZXJ0aWVzKSB7IHJldHVybiBnZXRFcnJvck1lc3NhZ2UoKTsgfVxuXG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgfHwge307XG5cbiAgICBzZXJpYWxpemVkUHJvcGVydGllcyA9IF8ubWFwKHByb3BlcnRpZXMsIGZ1bmN0aW9uIChwcm9wLCBrZXkpIHtcbiAgICAgIHZhciB4bWwsIHJlc3VsdDtcblxuICAgICAgaWYgKGlzUGFyYW0gJiYgcHJvcC5yZWFkT25seSkge1xuICAgICAgICByZXR1cm4gJyc7XG4gICAgICB9XG5cbiAgICAgIHhtbCA9IHByb3AueG1sIHx8IHt9O1xuICAgICAgcmVzdWx0ID0gY3JlYXRlU2NoZW1hWE1MKGtleSwgcHJvcCwgbW9kZWxzLCBjb25maWcpO1xuXG4gICAgICBpZiAoeG1sLmF0dHJpYnV0ZSkge1xuICAgICAgICBhdHRycy5wdXNoKHJlc3VsdCk7XG4gICAgICAgIHJldHVybiAnJztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9KS5qb2luKCcnKTtcblxuICAgIGlmIChhZGRpdGlvbmFsUHJvcGVydGllcykge1xuICAgICAgc2VyaWFsaXplZFByb3BlcnRpZXMgKz0gJzwhLS0gYWRkaXRpb25hbCBlbGVtZW50cyBhbGxvd2VkIC0tPic7XG4gICAgfVxuXG4gICAgcmV0dXJuIHdyYXBUYWcobmFtZSwgc2VyaWFsaXplZFByb3BlcnRpZXMsIGF0dHJzKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldEluZmluaXRlTG9vcE1lc3NhZ2UgKG5hbWUsIGxvb3BUbykge1xuICAgIHJldHVybiB3cmFwVGFnKG5hbWUsICc8IS0tIEluZmluaXRlIGxvb3AgJHJlZjonICsgbG9vcFRvICsgJyAtLT4nKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldEVycm9yTWVzc2FnZSAoZGV0YWlscykge1xuICAgIGRldGFpbHMgPSBkZXRhaWxzID8gJzogJyArIGRldGFpbHMgOiAnJztcbiAgICByZXR1cm4gJzwhLS0gaW52YWxpZCBYTUwnICsgZGV0YWlscyArICcgLS0+JztcbiAgfVxuXG4gIGZ1bmN0aW9uIGNyZWF0ZVNjaGVtYVhNTCAobmFtZSwgZGVmaW5pdGlvbiwgbW9kZWxzLCBjb25maWcpIHtcbiAgICB2YXIgJHJlZiA9IF8uaXNPYmplY3QoZGVmaW5pdGlvbikgPyBkZWZpbml0aW9uLiRyZWYgOiBudWxsO1xuICAgIHZhciBvdXRwdXQsIGluZGV4O1xuICAgIGNvbmZpZyA9IGNvbmZpZyB8fCB7fTtcbiAgICBjb25maWcubW9kZWxzVG9JZ25vcmUgPSBjb25maWcubW9kZWxzVG9JZ25vcmUgfHwgW107XG4gICBcbiAgICB2YXIgZGVzY3JpcHRvciA9IF8uaXNTdHJpbmcoJHJlZikgPyBnZXREZXNjcmlwdG9yQnlSZWYoJHJlZiwgbmFtZSwgbW9kZWxzLCBjb25maWcpXG4gICAgICAgIDogZ2V0RGVzY3JpcHRvcihuYW1lLCBkZWZpbml0aW9uLCBtb2RlbHMsIGNvbmZpZyk7XG4gICAgXG4gICAgaWYgKCFkZXNjcmlwdG9yKSB7XG4gICAgICByZXR1cm4gZ2V0RXJyb3JNZXNzYWdlKCk7XG4gICAgfVxuXG4gICAgc3dpdGNoIChkZXNjcmlwdG9yLnR5cGUpIHtcbiAgICAgIGNhc2UgJ2FycmF5JzpcbiAgICAgICAgb3V0cHV0ID0gY3JlYXRlQXJyYXlYTUwoZGVzY3JpcHRvcik7IGJyZWFrO1xuICAgICAgY2FzZSAnb2JqZWN0JzpcbiAgICAgICAgb3V0cHV0ID0gY3JlYXRlT2JqZWN0WE1MKGRlc2NyaXB0b3IpOyBicmVhaztcbiAgICAgIGNhc2UgJ2xvb3AnOlxuICAgICAgICBvdXRwdXQgPSBnZXRJbmZpbml0ZUxvb3BNZXNzYWdlKGRlc2NyaXB0b3IubmFtZSwgZGVzY3JpcHRvci5jb25maWcubG9vcFRvKTsgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBvdXRwdXQgPSBjcmVhdGVQcmltaXRpdmVYTUwoZGVzY3JpcHRvcik7XG4gICAgfVxuXG4gICAgaWYgKCRyZWYgJiYgZGVzY3JpcHRvci50eXBlICE9PSAnbG9vcCcpIHtcbiAgICAgIGluZGV4ID0gY29uZmlnLm1vZGVsc1RvSWdub3JlLmluZGV4T2YoJHJlZik7XG4gICAgICBpZiAoaW5kZXggPiAtMSkge1xuICAgICAgICBjb25maWcubW9kZWxzVG9JZ25vcmUuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gb3V0cHV0O1xuICB9XG5cbiAgZnVuY3Rpb24gRGVzY3JpcHRvciAobmFtZSwgdHlwZSwgZGVmaW5pdGlvbiwgbW9kZWxzLCBjb25maWcpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigpO1xuICAgIH1cbiAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZyB8fCB7fTtcbiAgICB0aGlzLmNvbmZpZy5tb2RlbHNUb0lnbm9yZSA9IHRoaXMuY29uZmlnLm1vZGVsc1RvSWdub3JlIHx8IFtdO1xuICAgIC8vIG5hbWUgaXMgYWxyZWFkeSBzZXQgYnkgZ2V0RGVzY3JpcHRvckJ5UmVmIG9yIGdldERlc2NyaXB0b3IgZnVuY3Rpb24gZGVwZW5kaW5nIG9uIHRoZSB0eXBlLiBPbmx5IHByZWZpeCwgaWYgcHJlc2VudCBpcyBuZWVkZWQgdG8gYmUgc2V0IGhlcmUgfCBodHRwczovL2dpdGh1Yi5jb20vc3dhZ2dlci1hcGkvc3dhZ2dlci11aS9pc3N1ZXMvMjU3N1xuICAgIHRoaXMubmFtZSA9IGdldFByZWZpeChuYW1lLCBkZWZpbml0aW9uLnhtbCk7XG4gICAgdGhpcy5kZWZpbml0aW9uID0gZGVmaW5pdGlvbjtcbiAgICB0aGlzLm1vZGVscyA9IG1vZGVscztcbiAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0RGVzY3JpcHRvckJ5UmVmKCRyZWYsIG5hbWUsIG1vZGVscywgY29uZmlnKSB7XG4gICAgdmFyIG1vZGVsVHlwZSA9IHNpbXBsZVJlZigkcmVmKTtcbiAgICB2YXIgbW9kZWwgPSBtb2RlbHNbbW9kZWxUeXBlXSB8fCB7fTtcbiAgICB2YXIgdHlwZSA9IG1vZGVsLmRlZmluaXRpb24gJiYgbW9kZWwuZGVmaW5pdGlvbi50eXBlID8gbW9kZWwuZGVmaW5pdGlvbi50eXBlIDogJ29iamVjdCc7XG4gICAgLy8gSWYgbW9kZWwgZGVmaW5pdGlvbiB4bWwgbmFtZSBpcyBwcmVzZW50LCB0aGVuIHRoYXQgd2lsbCBiZSBwcmVmZXJyZWQgb3ZlciBtb2RlbCBuYW1lLiBUaGlzIGlzIHRoZSBjYXNlIG9mIHByZWZlcnJpbmcgWG1sRWxlbWVudCBuYW1lIG92ZXIgWG1sUm9vdEVsZW1lbnQgbmFtZSBpZiBYbWxFbGVtZW50IG5hbWUgaXMgcHJvdmlkZWQgfCBodHRwczovL2dpdGh1Yi5jb20vc3dhZ2dlci1hcGkvc3dhZ2dlci11aS9pc3N1ZXMvMjU3N1xuICAgIGlmKG1vZGVsLmRlZmluaXRpb24gJiYgbW9kZWwuZGVmaW5pdGlvbi54bWwgJiYgbW9kZWwuZGVmaW5pdGlvbi54bWwubmFtZSkge1xuICAgICAgICBuYW1lID0gbmFtZSB8fCBtb2RlbC5kZWZpbml0aW9uLnhtbC5uYW1lIHx8IG1vZGVsLm5hbWU7XG4gICAgfVxuICAgIC8vIGVsc2Ugb25seSBtb2RlbCBuYW1lIHdpbGwgYmUgY29uc2lkZXJlZCBmb3IgZGV0ZXJtaW5hdGlvbiB8IGh0dHBzOi8vZ2l0aHViLmNvbS9zd2FnZ2VyLWFwaS9zd2FnZ2VyLXVpL2lzc3Vlcy8yNTc3XG4gICAgZWxzZSB7XG4gICAgICAgIG5hbWUgPSBuYW1lIHx8IG1vZGVsLm5hbWU7XG4gICAgfVxuICAgIFxuICAgIGlmIChjb25maWcubW9kZWxzVG9JZ25vcmUuaW5kZXhPZigkcmVmKSA+IC0xKSB7XG4gICAgICB0eXBlID0gJ2xvb3AnO1xuICAgICAgY29uZmlnLmxvb3BUbyA9IG1vZGVsVHlwZTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uZmlnLm1vZGVsc1RvSWdub3JlLnB1c2goJHJlZik7XG4gICAgfVxuXG4gICAgaWYgKCFtb2RlbC5kZWZpbml0aW9uKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBEZXNjcmlwdG9yKG5hbWUsIHR5cGUsIG1vZGVsLmRlZmluaXRpb24sIG1vZGVscywgY29uZmlnKTsgICAgXG4gIH1cblxuICBmdW5jdGlvbiBnZXREZXNjcmlwdG9yIChuYW1lLCBkZWZpbml0aW9uLCBtb2RlbHMsIGNvbmZpZyl7XG4gICAgdmFyIHR5cGUgPSBkZWZpbml0aW9uLnR5cGUgfHwgJ29iamVjdCc7XG4gICAgLy8gSWYgZGVmaW5pdGlvbiB4bWwgbmFtZSBpcyBwcmVzZW50LCB0aGVuIHRoYXQgd2lsbCBiZSBwcmVmZXJyZWQgb3ZlciBuYW1lIHwgaHR0cHM6Ly9naXRodWIuY29tL3N3YWdnZXItYXBpL3N3YWdnZXItdWkvaXNzdWVzLzI1NzdcbiAgICBpZihkZWZpbml0aW9uLnhtbCAmJiBkZWZpbml0aW9uLnhtbC5uYW1lKSB7XG4gICAgICAgIG5hbWUgPSBkZWZpbml0aW9uLnhtbC5uYW1lIHx8IG5hbWU7XG4gICAgfVxuICAgIGlmICghZGVmaW5pdGlvbikge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBEZXNjcmlwdG9yKG5hbWUsIHR5cGUsIGRlZmluaXRpb24sIG1vZGVscywgY29uZmlnKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNyZWF0ZVhNTFNhbXBsZSAobmFtZSwgZGVmaW5pdGlvbiwgbW9kZWxzLCBpc1BhcmFtKSB7XG4gICAgdmFyIHByb2xvZyA9ICc8P3htbCB2ZXJzaW9uPVwiMS4wXCI/Pic7XG5cbiAgICByZXR1cm4gZm9ybWF0WG1sKHByb2xvZyArIGNyZWF0ZVNjaGVtYVhNTChuYW1lLCBkZWZpbml0aW9uLCBtb2RlbHMsIHsgaXNQYXJhbTogaXNQYXJhbSB9ICkpO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICAgIGdldE1vZGVsU2lnbmF0dXJlOiBnZXRNb2RlbFNpZ25hdHVyZSxcbiAgICAgIGNyZWF0ZUpTT05TYW1wbGU6IGNyZWF0ZUpTT05TYW1wbGUsXG4gICAgICBnZXRQYXJhbWV0ZXJNb2RlbFNpZ25hdHVyZTogZ2V0UGFyYW1ldGVyTW9kZWxTaWduYXR1cmUsXG4gICAgICBjcmVhdGVQYXJhbWV0ZXJKU09OU2FtcGxlOiBjcmVhdGVQYXJhbWV0ZXJKU09OU2FtcGxlLFxuICAgICAgY3JlYXRlU2NoZW1hWE1MOiBjcmVhdGVTY2hlbWFYTUwsXG4gICAgICBjcmVhdGVYTUxTYW1wbGU6IGNyZWF0ZVhNTFNhbXBsZSxcbiAgICAgIGdldFByaW1pdGl2ZVNpZ25hdHVyZTogZ2V0UHJpbWl0aXZlU2lnbmF0dXJlXG4gIH07XG5cbn0pKCk7XG4iLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5Qb3B1cFZpZXcgPSBCYWNrYm9uZS5WaWV3LmV4dGVuZCh7XG4gICAgZXZlbnRzOiB7XG4gICAgICAgICdjbGljayAuYXBpLXBvcHVwLWNhbmNlbCc6ICdjYW5jZWxDbGljaydcbiAgICB9LFxuXG4gICAgdGVtcGxhdGU6IEhhbmRsZWJhcnMudGVtcGxhdGVzLnBvcHVwLFxuICAgIGNsYXNzTmFtZTogJ2FwaS1wb3B1cC1kaWFsb2cnLFxuXG4gICAgc2VsZWN0b3JzOiB7XG4gICAgICAgIGNvbnRlbnQ6ICcuYXBpLXBvcHVwLWNvbnRlbnQnLFxuICAgICAgICBtYWluICAgOiAnI3N3YWdnZXItdWktY29udGFpbmVyJ1xuICAgIH0sXG5cbiAgICBpbml0aWFsaXplOiBmdW5jdGlvbigpe1xuICAgICAgICB0aGlzLiRlbC5odG1sKHRoaXMudGVtcGxhdGUodGhpcy5tb2RlbCkpO1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy4kKHRoaXMuc2VsZWN0b3JzLmNvbnRlbnQpLmFwcGVuZCh0aGlzLm1vZGVsLmNvbnRlbnQpO1xuICAgICAgICAkKHRoaXMuc2VsZWN0b3JzLm1haW4pLmZpcnN0KCkuYXBwZW5kKHRoaXMuZWwpO1xuICAgICAgICB0aGlzLnNob3dQb3B1cCgpO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICBzaG93UG9wdXA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy4kZWwuc2hvdygpO1xuICAgIH0sXG5cbiAgICBjYW5jZWxDbGljazogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnJlbW92ZSgpO1xuICAgIH1cblxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5SZXNvdXJjZVZpZXcgPSBCYWNrYm9uZS5WaWV3LmV4dGVuZCh7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uKG9wdHMpIHtcbiAgICBvcHRzID0gb3B0cyB8fCB7fTtcbiAgICB0aGlzLnJvdXRlciA9IG9wdHMucm91dGVyO1xuICAgIHRoaXMuYXV0aHMgPSBvcHRzLmF1dGhzO1xuICAgIGlmICgnJyA9PT0gdGhpcy5tb2RlbC5kZXNjcmlwdGlvbikge1xuICAgICAgdGhpcy5tb2RlbC5kZXNjcmlwdGlvbiA9IG51bGw7XG4gICAgfVxuICAgIGlmICh0aGlzLm1vZGVsLmRlc2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLm1vZGVsLnN1bW1hcnkgPSB0aGlzLm1vZGVsLmRlc2NyaXB0aW9uO1xuICAgIH1cbiAgICB0aGlzLm51bWJlciA9IDA7XG4gIH0sXG5cbiAgcmVuZGVyOiBmdW5jdGlvbigpe1xuICAgIHZhciBtZXRob2RzID0ge307XG5cblxuICAgICQodGhpcy5lbCkuaHRtbChIYW5kbGViYXJzLnRlbXBsYXRlcy5yZXNvdXJjZSh0aGlzLm1vZGVsKSk7XG5cbiAgICAvLyBSZW5kZXIgZWFjaCBvcGVyYXRpb25cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubW9kZWwub3BlcmF0aW9uc0FycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgb3BlcmF0aW9uID0gdGhpcy5tb2RlbC5vcGVyYXRpb25zQXJyYXlbaV07XG4gICAgICB2YXIgY291bnRlciA9IDA7XG4gICAgICB2YXIgaWQgPSBvcGVyYXRpb24ubmlja25hbWU7XG5cbiAgICAgIHdoaWxlICh0eXBlb2YgbWV0aG9kc1tpZF0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGlkID0gaWQgKyAnXycgKyBjb3VudGVyO1xuICAgICAgICBjb3VudGVyICs9IDE7XG4gICAgICB9XG5cbiAgICAgIG1ldGhvZHNbaWRdID0gb3BlcmF0aW9uO1xuXG4gICAgICBvcGVyYXRpb24ubmlja25hbWUgPSBpZDtcbiAgICAgIG9wZXJhdGlvbi5wYXJlbnRJZCA9IHRoaXMubW9kZWwuaWQ7XG4gICAgICBvcGVyYXRpb24uZGVmaW5pdGlvbnMgPSB0aGlzLm1vZGVsLmRlZmluaXRpb25zOyAvLyBtYWtlIEpzb24gU2NoZW1hIGF2YWlsYWJsZSBmb3IgSlNvbkVkaXRvciBpbiB0aGlzIG9wZXJhdGlvblxuICAgICAgdGhpcy5hZGRPcGVyYXRpb24ob3BlcmF0aW9uKTtcbiAgICB9XG5cbiAgICAkKCcudG9nZ2xlRW5kcG9pbnRMaXN0JywgdGhpcy5lbCkuY2xpY2sodGhpcy5jYWxsRG9jcy5iaW5kKHRoaXMsICd0b2dnbGVFbmRwb2ludExpc3RGb3JSZXNvdXJjZScpKTtcbiAgICAkKCcuY29sbGFwc2VSZXNvdXJjZScsIHRoaXMuZWwpLmNsaWNrKHRoaXMuY2FsbERvY3MuYmluZCh0aGlzLCAnY29sbGFwc2VPcGVyYXRpb25zRm9yUmVzb3VyY2UnKSk7XG4gICAgJCgnLmV4cGFuZFJlc291cmNlJywgdGhpcy5lbCkuY2xpY2sodGhpcy5jYWxsRG9jcy5iaW5kKHRoaXMsICdleHBhbmRPcGVyYXRpb25zRm9yUmVzb3VyY2UnKSk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfSxcblxuICBhZGRPcGVyYXRpb246IGZ1bmN0aW9uKG9wZXJhdGlvbikge1xuXG4gICAgb3BlcmF0aW9uLm51bWJlciA9IHRoaXMubnVtYmVyO1xuXG4gICAgLy8gUmVuZGVyIGFuIG9wZXJhdGlvbiBhbmQgYWRkIGl0IHRvIG9wZXJhdGlvbnMgbGlcbiAgICB2YXIgb3BlcmF0aW9uVmlldyA9IG5ldyBTd2FnZ2VyVWkuVmlld3MuT3BlcmF0aW9uVmlldyh7XG4gICAgICBtb2RlbDogb3BlcmF0aW9uLFxuICAgICAgcm91dGVyOiB0aGlzLnJvdXRlcixcbiAgICAgIHRhZ05hbWU6ICdsaScsXG4gICAgICBjbGFzc05hbWU6ICdlbmRwb2ludCcsXG4gICAgICBzd2FnZ2VyT3B0aW9uczogdGhpcy5vcHRpb25zLnN3YWdnZXJPcHRpb25zLFxuICAgICAgYXV0aHM6IHRoaXMuYXV0aHNcbiAgICB9KTtcblxuICAgICQoJy5lbmRwb2ludHMnLCAkKHRoaXMuZWwpKS5hcHBlbmQob3BlcmF0aW9uVmlldy5yZW5kZXIoKS5lbCk7XG5cbiAgICB0aGlzLm51bWJlcisrO1xuXG4gIH0sXG4gIC8vIEdlbmVyaWMgRXZlbnQgaGFuZGxlciAoYERvY3NgIGlzIGdsb2JhbClcblxuXG4gIGNhbGxEb2NzOiBmdW5jdGlvbihmbk5hbWUsIGUpIHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgRG9jc1tmbk5hbWVdKGUuY3VycmVudFRhcmdldC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnKSk7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5Td2FnZ2VyVWkuVmlld3MuUmVzcG9uc2VDb250ZW50VHlwZVZpZXcgPSBCYWNrYm9uZS5WaWV3LmV4dGVuZCh7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uKCl7fSxcblxuICByZW5kZXI6IGZ1bmN0aW9uKCl7XG4gICAgdGhpcy5tb2RlbC5yZXNwb25zZUNvbnRlbnRUeXBlSWQgPSAncmN0JyArIE1hdGgucmFuZG9tKCk7XG4gICAgJCh0aGlzLmVsKS5odG1sKEhhbmRsZWJhcnMudGVtcGxhdGVzLnJlc3BvbnNlX2NvbnRlbnRfdHlwZSh0aGlzLm1vZGVsKSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbn0pOyIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLlZpZXdzLlNpZ25hdHVyZVZpZXcgPSBCYWNrYm9uZS5WaWV3LmV4dGVuZCh7XG4gIGV2ZW50czoge1xuICAgICdjbGljayBhLmRlc2NyaXB0aW9uLWxpbmsnICAgICAgIDogJ3N3aXRjaFRvRGVzY3JpcHRpb24nLFxuICAgICdjbGljayBhLnNuaXBwZXQtbGluaycgICAgICAgICAgIDogJ3N3aXRjaFRvU25pcHBldCcsXG4gICAgJ21vdXNlZG93biAuc25pcHBldF9qc29uJyAgICAgICAgICA6ICdqc29uU25pcHBldE1vdXNlRG93bicsXG4gICAgJ21vdXNlZG93biAuc25pcHBldF94bWwnICAgICAgICAgIDogJ3htbFNuaXBwZXRNb3VzZURvd24nXG4gIH0sXG5cbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkge1xuICB9LFxuXG4gIHJlbmRlcjogZnVuY3Rpb24oKXtcblxuICAgICQodGhpcy5lbCkuaHRtbChIYW5kbGViYXJzLnRlbXBsYXRlcy5zaWduYXR1cmUodGhpcy5tb2RlbCkpO1xuXG4gICAgaWYgKHRoaXMubW9kZWwuZGVmYXVsdFJlbmRlcmluZyA9PT0gJ21vZGVsJykge1xuICAgICAgdGhpcy5zd2l0Y2hUb0Rlc2NyaXB0aW9uKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc3dpdGNoVG9TbmlwcGV0KCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG5cbiAgLy8gaGFuZGxlciBmb3Igc2hvdyBzaWduYXR1cmVcbiAgc3dpdGNoVG9EZXNjcmlwdGlvbjogZnVuY3Rpb24oZSl7XG4gICAgaWYgKGUpIHsgZS5wcmV2ZW50RGVmYXVsdCgpOyB9XG5cbiAgICAkKCcuc25pcHBldCcsICQodGhpcy5lbCkpLmhpZGUoKTtcbiAgICAkKCcuZGVzY3JpcHRpb24nLCAkKHRoaXMuZWwpKS5zaG93KCk7XG4gICAgJCgnLmRlc2NyaXB0aW9uLWxpbmsnLCAkKHRoaXMuZWwpKS5hZGRDbGFzcygnc2VsZWN0ZWQnKTtcbiAgICAkKCcuc25pcHBldC1saW5rJywgJCh0aGlzLmVsKSkucmVtb3ZlQ2xhc3MoJ3NlbGVjdGVkJyk7XG4gIH0sXG5cbiAgLy8gaGFuZGxlciBmb3Igc2hvdyBzYW1wbGVcbiAgc3dpdGNoVG9TbmlwcGV0OiBmdW5jdGlvbihlKXtcbiAgICBpZiAoZSkgeyBlLnByZXZlbnREZWZhdWx0KCk7IH1cblxuICAgICQoJy5zbmlwcGV0JywgJCh0aGlzLmVsKSkuc2hvdygpO1xuICAgICQoJy5kZXNjcmlwdGlvbicsICQodGhpcy5lbCkpLmhpZGUoKTtcbiAgICAkKCcuc25pcHBldC1saW5rJywgJCh0aGlzLmVsKSkuYWRkQ2xhc3MoJ3NlbGVjdGVkJyk7XG4gICAgJCgnLmRlc2NyaXB0aW9uLWxpbmsnLCAkKHRoaXMuZWwpKS5yZW1vdmVDbGFzcygnc2VsZWN0ZWQnKTtcbiAgfSxcblxuICAvLyBoYW5kbGVyIGZvciBzbmlwcGV0IHRvIHRleHQgYXJlYVxuICBzbmlwcGV0VG9UZXh0QXJlYTogZnVuY3Rpb24odmFsKSB7XG4gICAgdmFyIHRleHRBcmVhID0gJCgndGV4dGFyZWEnLCAkKHRoaXMuZWwucGFyZW50Tm9kZS5wYXJlbnROb2RlLnBhcmVudE5vZGUpKTtcblxuICAgIC8vIEZpeCBmb3IgYnVnIGluIElFIDEwLzExIHdoaWNoIGNhdXNlcyBwbGFjZWhvbGRlciB0ZXh0IHRvIGJlIGNvcGllZCB0byBcInZhbHVlXCJcbiAgICBpZiAoJC50cmltKHRleHRBcmVhLnZhbCgpKSA9PT0gJycgfHwgdGV4dEFyZWEucHJvcCgncGxhY2Vob2xkZXInKSA9PT0gdGV4dEFyZWEudmFsKCkpIHtcbiAgICAgIHRleHRBcmVhLnZhbCh2YWwpO1xuICAgICAgLy8gVE9ETyBtb3ZlIHRoaXMgY29kZSBvdXRzaWRlIG9mIHRoZSB2aWV3IGFuZCBleHBvc2UgYW4gZXZlbnQgaW5zdGVhZFxuICAgICAgaWYoIHRoaXMubW9kZWwuanNvbkVkaXRvciAmJiB0aGlzLm1vZGVsLmpzb25FZGl0b3IuaXNFbmFibGVkKCkpe1xuICAgICAgICB0aGlzLm1vZGVsLmpzb25FZGl0b3Iuc2V0VmFsdWUoSlNPTi5wYXJzZSh0aGlzLm1vZGVsLnNhbXBsZUpTT04pKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAganNvblNuaXBwZXRNb3VzZURvd246IGZ1bmN0aW9uIChlKSB7XG4gICAgaWYgKHRoaXMubW9kZWwuaXNQYXJhbSkge1xuICAgICAgaWYgKGUpIHsgZS5wcmV2ZW50RGVmYXVsdCgpOyB9XG5cbiAgICAgIHRoaXMuc25pcHBldFRvVGV4dEFyZWEodGhpcy5tb2RlbC5zYW1wbGVKU09OKTtcbiAgICB9XG4gIH0sXG5cbiAgeG1sU25pcHBldE1vdXNlRG93bjogZnVuY3Rpb24gKGUpIHtcbiAgICBpZiAodGhpcy5tb2RlbC5pc1BhcmFtKSB7XG4gICAgICBpZiAoZSkgeyBlLnByZXZlbnREZWZhdWx0KCk7IH1cblxuICAgICAgdGhpcy5zbmlwcGV0VG9UZXh0QXJlYSh0aGlzLm1vZGVsLnNhbXBsZVhNTCk7XG4gICAgfVxuICB9XG59KTsiLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5TdGF0dXNDb2RlVmlldyA9IEJhY2tib25lLlZpZXcuZXh0ZW5kKHtcbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKG9wdHMpIHtcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRzIHx8IHt9O1xuICAgIHRoaXMucm91dGVyID0gdGhpcy5vcHRpb25zLnJvdXRlcjtcbiAgfSxcblxuICByZW5kZXI6IGZ1bmN0aW9uKCl7XG4gICAgdmFyIHJlc3BvbnNlTW9kZWwsIHJlc3BvbnNlTW9kZWxWaWV3O1xuICAgIHZhciB2YWx1ZSA9IHRoaXMucm91dGVyLmFwaS5tb2RlbHNbdGhpcy5tb2RlbC5yZXNwb25zZU1vZGVsXTtcbiAgICAkKHRoaXMuZWwpLmh0bWwoSGFuZGxlYmFycy50ZW1wbGF0ZXMuc3RhdHVzX2NvZGUodGhpcy5tb2RlbCkpO1xuXG4gICAgaWYgKHRoaXMucm91dGVyLmFwaS5tb2RlbHMuaGFzT3duUHJvcGVydHkodGhpcy5tb2RlbC5yZXNwb25zZU1vZGVsKSkge1xuICAgICAgcmVzcG9uc2VNb2RlbCA9IHtcbiAgICAgICAgc2FtcGxlSlNPTjogSlNPTi5zdHJpbmdpZnkoU3dhZ2dlclVpLnBhcnRpYWxzLnNpZ25hdHVyZS5jcmVhdGVKU09OU2FtcGxlKHZhbHVlKSwgdm9pZCAwLCAyKSxcbiAgICAgICAgc2FtcGxlWE1MOiB0aGlzLm1vZGVsLmlzWE1MID8gU3dhZ2dlclVpLnBhcnRpYWxzLnNpZ25hdHVyZS5jcmVhdGVYTUxTYW1wbGUoJycsIHRoaXMubW9kZWwuc2NoZW1hLCB0aGlzLnJvdXRlci5hcGkubW9kZWxzKSA6IGZhbHNlLFxuICAgICAgICBpc1BhcmFtOiBmYWxzZSxcbiAgICAgICAgc2lnbmF0dXJlOiBTd2FnZ2VyVWkucGFydGlhbHMuc2lnbmF0dXJlLmdldE1vZGVsU2lnbmF0dXJlKHRoaXMubW9kZWwucmVzcG9uc2VNb2RlbCwgdmFsdWUsIHRoaXMucm91dGVyLmFwaS5tb2RlbHMpLFxuICAgICAgICBkZWZhdWx0UmVuZGVyaW5nOiB0aGlzLm1vZGVsLmRlZmF1bHRSZW5kZXJpbmdcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3BvbnNlTW9kZWwgPSB7XG4gICAgICAgIHNpZ25hdHVyZTogU3dhZ2dlclVpLnBhcnRpYWxzLnNpZ25hdHVyZS5nZXRQcmltaXRpdmVTaWduYXR1cmUodGhpcy5tb2RlbC5zY2hlbWEpXG4gICAgICB9O1xuICAgIH1cblxuICAgIHJlc3BvbnNlTW9kZWxWaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5TaWduYXR1cmVWaWV3KHttb2RlbDogcmVzcG9uc2VNb2RlbCwgdGFnTmFtZTogJ2Rpdid9KTtcbiAgICAkKCcubW9kZWwtc2lnbmF0dXJlJywgdGhpcy4kZWwpLmFwcGVuZChyZXNwb25zZU1vZGVsVmlldy5yZW5kZXIoKS5lbCk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbn0pOyJdfQ==