Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 1 | /** |
| 2 | * swagger-ui - Swagger UI is a dependency-free collection of HTML, JavaScript, and CSS assets that dynamically generate beautiful documentation from a Swagger-compliant API |
| 3 | * @version v2.1.0 |
| 4 | * @link http://swagger.io |
| 5 | * @license Apache 2.0 |
| 6 | */ |
| 7 | (function(){this["Handlebars"] = this["Handlebars"] || {}; |
| 8 | this["Handlebars"]["templates"] = this["Handlebars"]["templates"] || {}; |
| 9 | this["Handlebars"]["templates"]["apikey_button_view"] = Handlebars.template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 10 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 11 | return "<!--div class='auth_button' id='apikey_button'><img class='auth_icon' alt='apply api key' src='images/apikey.jpeg'></div-->\n<div class='auth_container' id='apikey_container'>\n <div class='key_input_container'>\n <div class='auth_label'><label for='input_apiKey_entry'>" |
| 12 | + escapeExpression(((helper = (helper = helpers.keyName || (depth0 != null ? depth0.keyName : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"keyName","hash":{},"data":data}) : helper))) |
| 13 | + "</label></div>\n <input placeholder='api_key' class='auth_input' id='input_apiKey_entry' name='apiKey' type='text'/>\n <div class='auth_submit'><a class='auth_submit_button' id='apply_api_key' href='#''>apply</a></div>\n </div>\n</div>\n\n"; |
| 14 | },"useData":true}); |
| 15 | this["Handlebars"]["templates"]["basic_auth_button_view"] = Handlebars.template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 16 | return "<div class='auth_button' id='basic_auth_button'><img class='auth_icon' src='images/password.jpeg'></div>\n<div class='auth_container' id='basic_auth_container'>\n <div class='key_input_container'>\n <div class=\"auth_label\"><label for=\"input_username\">Username</label></div>\n <input placeholder=\"username\" class=\"auth_input\" id=\"input_username\" name=\"username\" type=\"text\"/>\n <div class=\"auth_label\"><label for=\"password\">Password</label></div>\n <input placeholder=\"password\" class=\"auth_input\" id=\"input_password\" name=\"password\" type=\"password\"/>\n <div class='auth_submit'><a class='auth_submit_button' id=\"apply_basic_auth\" href=\"#\">apply</a></div>\n </div>\n</div>\n\n"; |
| 17 | },"useData":true}); |
| 18 | this["Handlebars"]["templates"]["content_type"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
| 19 | var stack1, buffer = ""; |
| 20 | stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.produces : depth0), {"name":"each","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data}); |
| 21 | if (stack1 != null) { buffer += stack1; } |
| 22 | return buffer; |
| 23 | },"2":function(depth0,helpers,partials,data) { |
| 24 | var stack1, lambda=this.lambda, buffer = " <option value=\""; |
| 25 | stack1 = lambda(depth0, depth0); |
| 26 | if (stack1 != null) { buffer += stack1; } |
| 27 | buffer += "\">"; |
| 28 | stack1 = lambda(depth0, depth0); |
| 29 | if (stack1 != null) { buffer += stack1; } |
| 30 | return buffer + "</option>\n"; |
| 31 | },"4":function(depth0,helpers,partials,data) { |
| 32 | return " <option value=\"application/json\">application/json</option>\n"; |
| 33 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 34 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<label for=\"" |
| 35 | + escapeExpression(((helper = (helper = helpers.contentTypeId || (depth0 != null ? depth0.contentTypeId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"contentTypeId","hash":{},"data":data}) : helper))) |
| 36 | + "\">Response Content Type</label>\n<select name=\"contentType\" id=\"" |
| 37 | + escapeExpression(((helper = (helper = helpers.contentTypeId || (depth0 != null ? depth0.contentTypeId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"contentTypeId","hash":{},"data":data}) : helper))) |
| 38 | + "\">\n"; |
| 39 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.produces : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(4, data),"data":data}); |
| 40 | if (stack1 != null) { buffer += stack1; } |
| 41 | return buffer + "</select>\n"; |
| 42 | },"useData":true}); |
| 43 | 'use strict'; |
| 44 | |
| 45 | |
| 46 | $(function() { |
| 47 | |
| 48 | // Helper function for vertically aligning DOM elements |
| 49 | // http://www.seodenver.com/simple-vertical-align-plugin-for-jquery/ |
| 50 | $.fn.vAlign = function() { |
| 51 | return this.each(function(){ |
| 52 | var ah = $(this).height(); |
| 53 | var ph = $(this).parent().height(); |
| 54 | var mh = (ph - ah) / 2; |
| 55 | $(this).css('margin-top', mh); |
| 56 | }); |
| 57 | }; |
| 58 | |
| 59 | $.fn.stretchFormtasticInputWidthToParent = function() { |
| 60 | return this.each(function(){ |
| 61 | var p_width = $(this).closest("form").innerWidth(); |
| 62 | var p_padding = parseInt($(this).closest("form").css('padding-left') ,10) + parseInt($(this).closest('form').css('padding-right'), 10); |
| 63 | var this_padding = parseInt($(this).css('padding-left'), 10) + parseInt($(this).css('padding-right'), 10); |
| 64 | $(this).css('width', p_width - p_padding - this_padding); |
| 65 | }); |
| 66 | }; |
| 67 | |
| 68 | $('form.formtastic li.string input, form.formtastic textarea').stretchFormtasticInputWidthToParent(); |
| 69 | |
| 70 | // Vertically center these paragraphs |
| 71 | // Parent may need a min-height for this to work.. |
| 72 | $('ul.downplayed li div.content p').vAlign(); |
| 73 | |
| 74 | // When a sandbox form is submitted.. |
| 75 | $("form.sandbox").submit(function(){ |
| 76 | |
| 77 | var error_free = true; |
| 78 | |
| 79 | // Cycle through the forms required inputs |
| 80 | $(this).find("input.required").each(function() { |
| 81 | |
| 82 | // Remove any existing error styles from the input |
| 83 | $(this).removeClass('error'); |
| 84 | |
| 85 | // Tack the error style on if the input is empty.. |
| 86 | if ($(this).val() === '') { |
| 87 | $(this).addClass('error'); |
| 88 | $(this).wiggle(); |
| 89 | error_free = false; |
| 90 | } |
| 91 | |
| 92 | }); |
| 93 | |
| 94 | return error_free; |
| 95 | }); |
| 96 | |
| 97 | }); |
| 98 | |
| 99 | function clippyCopiedCallback() { |
| 100 | $('#api_key_copied').fadeIn().delay(1000).fadeOut(); |
| 101 | |
| 102 | // var b = $("#clippy_tooltip_" + a); |
| 103 | // b.length != 0 && (b.attr("title", "copied!").trigger("tipsy.reload"), setTimeout(function() { |
| 104 | // b.attr("title", "copy to clipboard") |
| 105 | // }, |
| 106 | // 500)) |
| 107 | } |
| 108 | |
| 109 | // Logging function that accounts for browsers that don't have window.console |
| 110 | function log(){ |
| 111 | log.history = log.history || []; |
| 112 | log.history.push(arguments); |
| 113 | if(this.console){ |
| 114 | console.log( Array.prototype.slice.call(arguments)[0] ); |
| 115 | } |
| 116 | } |
| 117 | |
| 118 | // Handle browsers that do console incorrectly (IE9 and below, see http://stackoverflow.com/a/5539378/7913) |
| 119 | if (Function.prototype.bind && console && typeof console.log === "object") { |
| 120 | [ |
| 121 | "log","info","warn","error","assert","dir","clear","profile","profileEnd" |
| 122 | ].forEach(function (method) { |
| 123 | console[method] = this.bind(console[method], console); |
| 124 | }, Function.prototype.call); |
| 125 | } |
| 126 | |
| 127 | window.Docs = { |
| 128 | |
| 129 | shebang: function() { |
| 130 | |
| 131 | // If shebang has an operation nickname in it.. |
| 132 | // e.g. /docs/#!/words/get_search |
| 133 | var fragments = $.param.fragment().split('/'); |
| 134 | fragments.shift(); // get rid of the bang |
| 135 | |
| 136 | switch (fragments.length) { |
| 137 | case 1: |
| 138 | if (fragments[0].length > 0) { // prevent matching "#/" |
| 139 | // Expand all operations for the resource and scroll to it |
| 140 | var dom_id = 'resource_' + fragments[0]; |
| 141 | |
| 142 | Docs.expandEndpointListForResource(fragments[0]); |
| 143 | $("#"+dom_id).slideto({highlight: false}); |
| 144 | } |
| 145 | break; |
| 146 | case 2: |
| 147 | // Refer to the endpoint DOM element, e.g. #words_get_search |
| 148 | |
| 149 | // Expand Resource |
| 150 | Docs.expandEndpointListForResource(fragments[0]); |
| 151 | $("#"+dom_id).slideto({highlight: false}); |
| 152 | |
| 153 | // Expand operation |
| 154 | var li_dom_id = fragments.join('_'); |
| 155 | var li_content_dom_id = li_dom_id + "_content"; |
| 156 | |
| 157 | |
| 158 | Docs.expandOperation($('#'+li_content_dom_id)); |
| 159 | $('#'+li_dom_id).slideto({highlight: false}); |
| 160 | break; |
| 161 | } |
| 162 | |
| 163 | }, |
| 164 | |
| 165 | toggleEndpointListForResource: function(resource) { |
| 166 | var elem = $('li#resource_' + Docs.escapeResourceName(resource) + ' ul.endpoints'); |
| 167 | if (elem.is(':visible')) { |
| 168 | Docs.collapseEndpointListForResource(resource); |
| 169 | } else { |
| 170 | Docs.expandEndpointListForResource(resource); |
| 171 | } |
| 172 | }, |
| 173 | |
| 174 | // Expand resource |
| 175 | expandEndpointListForResource: function(resource) { |
| 176 | var resource = Docs.escapeResourceName(resource); |
| 177 | if (resource == '') { |
| 178 | $('.resource ul.endpoints').slideDown(); |
| 179 | return; |
| 180 | } |
| 181 | |
| 182 | $('li#resource_' + resource).addClass('active'); |
| 183 | |
| 184 | var elem = $('li#resource_' + resource + ' ul.endpoints'); |
| 185 | elem.slideDown(); |
| 186 | }, |
| 187 | |
| 188 | // Collapse resource and mark as explicitly closed |
| 189 | collapseEndpointListForResource: function(resource) { |
| 190 | var resource = Docs.escapeResourceName(resource); |
| 191 | if (resource == '') { |
| 192 | $('.resource ul.endpoints').slideUp(); |
| 193 | return; |
| 194 | } |
| 195 | |
| 196 | $('li#resource_' + resource).removeClass('active'); |
| 197 | |
| 198 | var elem = $('li#resource_' + resource + ' ul.endpoints'); |
| 199 | elem.slideUp(); |
| 200 | }, |
| 201 | |
| 202 | expandOperationsForResource: function(resource) { |
| 203 | // Make sure the resource container is open.. |
| 204 | Docs.expandEndpointListForResource(resource); |
| 205 | |
| 206 | if (resource == '') { |
| 207 | $('.resource ul.endpoints li.operation div.content').slideDown(); |
| 208 | return; |
| 209 | } |
| 210 | |
| 211 | $('li#resource_' + Docs.escapeResourceName(resource) + ' li.operation div.content').each(function() { |
| 212 | Docs.expandOperation($(this)); |
| 213 | }); |
| 214 | }, |
| 215 | |
| 216 | collapseOperationsForResource: function(resource) { |
| 217 | // Make sure the resource container is open.. |
| 218 | Docs.expandEndpointListForResource(resource); |
| 219 | |
| 220 | if (resource == '') { |
| 221 | $('.resource ul.endpoints li.operation div.content').slideUp(); |
| 222 | return; |
| 223 | } |
| 224 | |
| 225 | $('li#resource_' + Docs.escapeResourceName(resource) + ' li.operation div.content').each(function() { |
| 226 | Docs.collapseOperation($(this)); |
| 227 | }); |
| 228 | }, |
| 229 | |
| 230 | escapeResourceName: function(resource) { |
| 231 | return resource.replace(/[!"#$%&'()*+,.\/:;<=>?@\[\\\]\^`{|}~]/g, "\\$&"); |
| 232 | }, |
| 233 | |
| 234 | expandOperation: function(elem) { |
| 235 | elem.slideDown(); |
| 236 | }, |
| 237 | |
| 238 | collapseOperation: function(elem) { |
| 239 | elem.slideUp(); |
| 240 | } |
| 241 | }; |
| 242 | |
| 243 | 'use strict'; |
| 244 | |
| 245 | Handlebars.registerHelper('sanitize', function(html) { |
| 246 | // Strip the script tags from the html, and return it as a Handlebars.SafeString |
| 247 | html = html.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, ''); |
| 248 | return new Handlebars.SafeString(html); |
| 249 | }); |
| 250 | |
| 251 | Handlebars.registerHelper('renderTextParam', function(param) { |
| 252 | var result, type = 'text', idAtt = ''; |
| 253 | var isArray = param.type.toLowerCase() === 'array' || param.allowMultiple; |
| 254 | var defaultValue = isArray && Array.isArray(param.default) ? param.default.join('\n') : param.default; |
| 255 | |
| 256 | if (typeof defaultValue === 'undefined') { |
| 257 | defaultValue = ''; |
| 258 | } |
| 259 | |
| 260 | if(param.format && param.format === 'password') { |
| 261 | type = 'password'; |
| 262 | } |
| 263 | |
| 264 | if(param.valueId) { |
| 265 | idAtt = ' id=\'' + param.valueId + '\''; |
| 266 | } |
| 267 | |
| 268 | if(isArray) { |
| 269 | result = '<textarea class=\'body-textarea' + (param.required ? ' required' : '') + '\' name=\'' + param.name + '\'' + idAtt; |
| 270 | result += ' placeholder=\'Provide multiple values in new lines' + (param.required ? ' (at least one required).' : '.') + '\'>'; |
| 271 | result += defaultValue + '</textarea>'; |
| 272 | } else { |
| 273 | var parameterClass = 'parameter'; |
| 274 | if(param.required) { |
| 275 | parameterClass += ' required'; |
| 276 | } |
| 277 | result = '<input class=\'' + parameterClass + '\' minlength=\'' + (param.required ? 1 : 0) + '\''; |
| 278 | result += ' name=\'' + param.name +'\' placeholder=\'' + (param.required ? '(required)' : '') + '\'' + idAtt; |
| 279 | result += ' type=\'' + type + '\' value=\'' + defaultValue + '\'/>'; |
| 280 | } |
| 281 | return new Handlebars.SafeString(result); |
| 282 | }); |
| 283 | |
| 284 | this["Handlebars"]["templates"]["main"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
| 285 | var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression, buffer = " <div class=\"info_title\">" |
| 286 | + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.title : stack1), depth0)) |
| 287 | + "</div>\n <div class=\"info_description markdown\">"; |
| 288 | stack1 = lambda(((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.description : stack1), depth0); |
| 289 | if (stack1 != null) { buffer += stack1; } |
| 290 | buffer += "</div>\n"; |
| 291 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.externalDocs : depth0), {"name":"if","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data}); |
| 292 | if (stack1 != null) { buffer += stack1; } |
| 293 | buffer += " "; |
| 294 | stack1 = helpers['if'].call(depth0, ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.termsOfServiceUrl : stack1), {"name":"if","hash":{},"fn":this.program(4, data),"inverse":this.noop,"data":data}); |
| 295 | if (stack1 != null) { buffer += stack1; } |
| 296 | buffer += "\n "; |
| 297 | stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.name : stack1), {"name":"if","hash":{},"fn":this.program(6, data),"inverse":this.noop,"data":data}); |
| 298 | if (stack1 != null) { buffer += stack1; } |
| 299 | buffer += "\n "; |
| 300 | stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.url : stack1), {"name":"if","hash":{},"fn":this.program(8, data),"inverse":this.noop,"data":data}); |
| 301 | if (stack1 != null) { buffer += stack1; } |
| 302 | buffer += "\n "; |
| 303 | stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.email : stack1), {"name":"if","hash":{},"fn":this.program(10, data),"inverse":this.noop,"data":data}); |
| 304 | if (stack1 != null) { buffer += stack1; } |
| 305 | buffer += "\n "; |
| 306 | stack1 = helpers['if'].call(depth0, ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.license : stack1), {"name":"if","hash":{},"fn":this.program(12, data),"inverse":this.noop,"data":data}); |
| 307 | if (stack1 != null) { buffer += stack1; } |
| 308 | return buffer + "\n"; |
| 309 | },"2":function(depth0,helpers,partials,data) { |
| 310 | var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression; |
| 311 | return " <p>" |
| 312 | + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0.externalDocs : depth0)) != null ? stack1.description : stack1), depth0)) |
| 313 | + "</p>\n <a href=\"" |
| 314 | + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0.externalDocs : depth0)) != null ? stack1.url : stack1), depth0)) |
| 315 | + "\" target=\"_blank\">" |
| 316 | + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0.externalDocs : depth0)) != null ? stack1.url : stack1), depth0)) |
| 317 | + "</a>\n"; |
| 318 | },"4":function(depth0,helpers,partials,data) { |
| 319 | var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression; |
| 320 | return "<div class=\"info_tos\"><a href=\"" |
| 321 | + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.termsOfServiceUrl : stack1), depth0)) |
| 322 | + "\">Terms of service</a></div>"; |
| 323 | },"6":function(depth0,helpers,partials,data) { |
| 324 | var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression; |
| 325 | return "<div class='info_name'>Created by " |
| 326 | + escapeExpression(lambda(((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.name : stack1), depth0)) |
| 327 | + "</div>"; |
| 328 | },"8":function(depth0,helpers,partials,data) { |
| 329 | var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression; |
| 330 | return "<div class='info_url'>See more at <a href=\"" |
| 331 | + escapeExpression(lambda(((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.url : stack1), depth0)) |
| 332 | + "\">" |
| 333 | + escapeExpression(lambda(((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.url : stack1), depth0)) |
| 334 | + "</a></div>"; |
| 335 | },"10":function(depth0,helpers,partials,data) { |
| 336 | var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression; |
| 337 | return "<div class='info_email'><a href=\"mailto:" |
| 338 | + escapeExpression(lambda(((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.email : stack1), depth0)) |
| 339 | + "?subject=" |
| 340 | + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.title : stack1), depth0)) |
| 341 | + "\">Contact the developer</a></div>"; |
| 342 | },"12":function(depth0,helpers,partials,data) { |
| 343 | var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression; |
| 344 | return "<div class='info_license'><a href='" |
| 345 | + escapeExpression(lambda(((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.license : stack1)) != null ? stack1.url : stack1), depth0)) |
| 346 | + "'>" |
| 347 | + escapeExpression(lambda(((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.license : stack1)) != null ? stack1.name : stack1), depth0)) |
| 348 | + "</a></div>"; |
| 349 | },"14":function(depth0,helpers,partials,data) { |
| 350 | var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression; |
| 351 | return " , <span style=\"font-variant: small-caps\">api version</span>: " |
| 352 | + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.version : stack1), depth0)) |
| 353 | + "\n "; |
| 354 | },"16":function(depth0,helpers,partials,data) { |
| 355 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 356 | return " <span style=\"float:right\"><a href=\"" |
| 357 | + escapeExpression(((helper = (helper = helpers.validatorUrl || (depth0 != null ? depth0.validatorUrl : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"validatorUrl","hash":{},"data":data}) : helper))) |
| 358 | + "/debug?url=" |
| 359 | + escapeExpression(((helper = (helper = helpers.url || (depth0 != null ? depth0.url : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"url","hash":{},"data":data}) : helper))) |
| 360 | + "\"><img id=\"validator\" src=\"" |
| 361 | + escapeExpression(((helper = (helper = helpers.validatorUrl || (depth0 != null ? depth0.validatorUrl : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"validatorUrl","hash":{},"data":data}) : helper))) |
| 362 | + "?url=" |
| 363 | + escapeExpression(((helper = (helper = helpers.url || (depth0 != null ? depth0.url : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"url","hash":{},"data":data}) : helper))) |
| 364 | + "\"></a>\n </span>\n"; |
| 365 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 366 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<div class='info' id='api_info'>\n"; |
| 367 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.info : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data}); |
| 368 | if (stack1 != null) { buffer += stack1; } |
| 369 | buffer += "</div>\n<div class='container' id='resources_container'>\n <ul id='resources'></ul>\n\n <div class=\"footer\">\n <h4 style=\"color: #999\">[ <span style=\"font-variant: small-caps\">base url</span>: " |
| 370 | + escapeExpression(((helper = (helper = helpers.basePath || (depth0 != null ? depth0.basePath : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"basePath","hash":{},"data":data}) : helper))) |
| 371 | + "\n"; |
| 372 | stack1 = helpers['if'].call(depth0, ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.version : stack1), {"name":"if","hash":{},"fn":this.program(14, data),"inverse":this.noop,"data":data}); |
| 373 | if (stack1 != null) { buffer += stack1; } |
| 374 | buffer += "]\n"; |
| 375 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.validatorUrl : depth0), {"name":"if","hash":{},"fn":this.program(16, data),"inverse":this.noop,"data":data}); |
| 376 | if (stack1 != null) { buffer += stack1; } |
| 377 | return buffer + " </h4>\n </div>\n</div>\n"; |
| 378 | },"useData":true}); |
| 379 | this["Handlebars"]["templates"]["operation"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
| 380 | return "deprecated"; |
| 381 | },"3":function(depth0,helpers,partials,data) { |
| 382 | return " <h4>Warning: Deprecated</h4>\n"; |
| 383 | },"5":function(depth0,helpers,partials,data) { |
| 384 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, buffer = " <h4>Implementation Notes</h4>\n <div class=\"markdown\">"; |
| 385 | stack1 = ((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper)); |
| 386 | if (stack1 != null) { buffer += stack1; } |
| 387 | return buffer + "</div>\n"; |
| 388 | },"7":function(depth0,helpers,partials,data) { |
| 389 | return " <div class=\"auth\">\n <span class=\"api-ic ic-error\"></span>"; |
| 390 | },"9":function(depth0,helpers,partials,data) { |
| 391 | var stack1, buffer = " <div id=\"api_information_panel\" style=\"top: 526px; left: 776px; display: none;\">\n"; |
| 392 | stack1 = helpers.each.call(depth0, depth0, {"name":"each","hash":{},"fn":this.program(10, data),"inverse":this.noop,"data":data}); |
| 393 | if (stack1 != null) { buffer += stack1; } |
| 394 | return buffer + " </div>\n"; |
| 395 | },"10":function(depth0,helpers,partials,data) { |
| 396 | var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression, buffer = " <div title='"; |
| 397 | stack1 = lambda((depth0 != null ? depth0.description : depth0), depth0); |
| 398 | if (stack1 != null) { buffer += stack1; } |
| 399 | return buffer + "'>" |
| 400 | + escapeExpression(lambda((depth0 != null ? depth0.scope : depth0), depth0)) |
| 401 | + "</div>\n"; |
| 402 | },"12":function(depth0,helpers,partials,data) { |
| 403 | return "</div>"; |
| 404 | },"14":function(depth0,helpers,partials,data) { |
| 405 | return " <div class='access'>\n <span class=\"api-ic ic-off\" title=\"click to authenticate\"></span>\n </div>\n"; |
| 406 | },"16":function(depth0,helpers,partials,data) { |
| 407 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 408 | return " <h4>Response Class (Status " |
| 409 | + escapeExpression(((helper = (helper = helpers.successCode || (depth0 != null ? depth0.successCode : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"successCode","hash":{},"data":data}) : helper))) |
| 410 | + ")</h4>\n <p><span class=\"model-signature\" /></p>\n <br/>\n <div class=\"response-content-type\" />\n"; |
| 411 | },"18":function(depth0,helpers,partials,data) { |
| 412 | return " <h4>Parameters</h4>\n <table class='fullwidth'>\n <thead>\n <tr>\n <th style=\"width: 100px; max-width: 100px\">Parameter</th>\n <th style=\"width: 310px; max-width: 310px\">Value</th>\n <th style=\"width: 200px; max-width: 200px\">Description</th>\n <th style=\"width: 100px; max-width: 100px\">Parameter Type</th>\n <th style=\"width: 220px; max-width: 230px\">Data Type</th>\n </tr>\n </thead>\n <tbody class=\"operation-params\">\n\n </tbody>\n </table>\n"; |
| 413 | },"20":function(depth0,helpers,partials,data) { |
| 414 | return " <div style='margin:0;padding:0;display:inline'></div>\n <h4>Response Messages</h4>\n <table class='fullwidth'>\n <thead>\n <tr>\n <th>HTTP Status Code</th>\n <th>Reason</th>\n <th>Response Model</th>\n <th>Headers</th>\n </tr>\n </thead>\n <tbody class=\"operation-status\">\n\n </tbody>\n </table>\n"; |
| 415 | },"22":function(depth0,helpers,partials,data) { |
| 416 | return ""; |
| 417 | },"24":function(depth0,helpers,partials,data) { |
| 418 | return " <div class='sandbox_header'>\n <input class='submit' type='button' value='Try it out!' />\n <a href='#' class='response_hider' style='display:none'>Hide Response</a>\n <span class='response_throbber' style='display:none'></span>\n </div>\n"; |
| 419 | },"26":function(depth0,helpers,partials,data) { |
| 420 | return " <h4>Request Headers</h4>\n <div class='block request_headers'></div>\n"; |
| 421 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 422 | var stack1, helper, options, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, blockHelperMissing=helpers.blockHelperMissing, buffer = "\n <ul class='operations' >\n <li class='" |
| 423 | + escapeExpression(((helper = (helper = helpers.method || (depth0 != null ? depth0.method : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"method","hash":{},"data":data}) : helper))) |
| 424 | + " operation' id='" |
| 425 | + escapeExpression(((helper = (helper = helpers.parentId || (depth0 != null ? depth0.parentId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"parentId","hash":{},"data":data}) : helper))) |
| 426 | + "_" |
| 427 | + escapeExpression(((helper = (helper = helpers.nickname || (depth0 != null ? depth0.nickname : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"nickname","hash":{},"data":data}) : helper))) |
| 428 | + "'>\n <div class='heading'>\n <h3>\n <span class='http_method'>\n <a href='#!/" |
| 429 | + escapeExpression(((helper = (helper = helpers.encodedParentId || (depth0 != null ? depth0.encodedParentId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"encodedParentId","hash":{},"data":data}) : helper))) |
| 430 | + "/" |
| 431 | + escapeExpression(((helper = (helper = helpers.nickname || (depth0 != null ? depth0.nickname : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"nickname","hash":{},"data":data}) : helper))) |
| 432 | + "' class=\"toggleOperation\">" |
| 433 | + escapeExpression(((helper = (helper = helpers.method || (depth0 != null ? depth0.method : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"method","hash":{},"data":data}) : helper))) |
| 434 | + "</a>\n </span>\n <span class='path'>\n <a href='#!/" |
| 435 | + escapeExpression(((helper = (helper = helpers.encodedParentId || (depth0 != null ? depth0.encodedParentId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"encodedParentId","hash":{},"data":data}) : helper))) |
| 436 | + "/" |
| 437 | + escapeExpression(((helper = (helper = helpers.nickname || (depth0 != null ? depth0.nickname : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"nickname","hash":{},"data":data}) : helper))) |
| 438 | + "' class=\"toggleOperation "; |
| 439 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.deprecated : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data}); |
| 440 | if (stack1 != null) { buffer += stack1; } |
| 441 | buffer += "\">" |
| 442 | + escapeExpression(((helper = (helper = helpers.path || (depth0 != null ? depth0.path : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"path","hash":{},"data":data}) : helper))) |
| 443 | + "</a>\n </span>\n </h3>\n <ul class='options'>\n <li>\n <a href='#!/" |
| 444 | + escapeExpression(((helper = (helper = helpers.encodedParentId || (depth0 != null ? depth0.encodedParentId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"encodedParentId","hash":{},"data":data}) : helper))) |
| 445 | + "/" |
| 446 | + escapeExpression(((helper = (helper = helpers.nickname || (depth0 != null ? depth0.nickname : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"nickname","hash":{},"data":data}) : helper))) |
| 447 | + "' class=\"toggleOperation\">"; |
| 448 | stack1 = ((helper = (helper = helpers.summary || (depth0 != null ? depth0.summary : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"summary","hash":{},"data":data}) : helper)); |
| 449 | if (stack1 != null) { buffer += stack1; } |
| 450 | buffer += "</a>\n </li>\n </ul>\n </div>\n <div class='content' id='" |
| 451 | + escapeExpression(((helper = (helper = helpers.parentId || (depth0 != null ? depth0.parentId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"parentId","hash":{},"data":data}) : helper))) |
| 452 | + "_" |
| 453 | + escapeExpression(((helper = (helper = helpers.nickname || (depth0 != null ? depth0.nickname : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"nickname","hash":{},"data":data}) : helper))) |
| 454 | + "_content' style='display:none'>\n"; |
| 455 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.deprecated : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data}); |
| 456 | if (stack1 != null) { buffer += stack1; } |
| 457 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.description : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.noop,"data":data}); |
| 458 | if (stack1 != null) { buffer += stack1; } |
| 459 | stack1 = ((helper = (helper = helpers.oauth || (depth0 != null ? depth0.oauth : depth0)) != null ? helper : helperMissing),(options={"name":"oauth","hash":{},"fn":this.program(7, data),"inverse":this.noop,"data":data}),(typeof helper === functionType ? helper.call(depth0, options) : helper)); |
| 460 | if (!helpers.oauth) { stack1 = blockHelperMissing.call(depth0, stack1, options); } |
| 461 | if (stack1 != null) { buffer += stack1; } |
| 462 | buffer += "\n"; |
| 463 | stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.oauth : depth0), {"name":"each","hash":{},"fn":this.program(9, data),"inverse":this.noop,"data":data}); |
| 464 | if (stack1 != null) { buffer += stack1; } |
| 465 | buffer += " "; |
| 466 | stack1 = ((helper = (helper = helpers.oauth || (depth0 != null ? depth0.oauth : depth0)) != null ? helper : helperMissing),(options={"name":"oauth","hash":{},"fn":this.program(12, data),"inverse":this.noop,"data":data}),(typeof helper === functionType ? helper.call(depth0, options) : helper)); |
| 467 | if (!helpers.oauth) { stack1 = blockHelperMissing.call(depth0, stack1, options); } |
| 468 | if (stack1 != null) { buffer += stack1; } |
| 469 | buffer += "\n"; |
| 470 | stack1 = ((helper = (helper = helpers.oauth || (depth0 != null ? depth0.oauth : depth0)) != null ? helper : helperMissing),(options={"name":"oauth","hash":{},"fn":this.program(14, data),"inverse":this.noop,"data":data}),(typeof helper === functionType ? helper.call(depth0, options) : helper)); |
| 471 | if (!helpers.oauth) { stack1 = blockHelperMissing.call(depth0, stack1, options); } |
| 472 | if (stack1 != null) { buffer += stack1; } |
| 473 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.type : depth0), {"name":"if","hash":{},"fn":this.program(16, data),"inverse":this.noop,"data":data}); |
| 474 | if (stack1 != null) { buffer += stack1; } |
| 475 | buffer += " <form accept-charset='UTF-8' class='sandbox'>\n <div style='margin:0;padding:0;display:inline'></div>\n"; |
| 476 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.parameters : depth0), {"name":"if","hash":{},"fn":this.program(18, data),"inverse":this.noop,"data":data}); |
| 477 | if (stack1 != null) { buffer += stack1; } |
| 478 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.responseMessages : depth0), {"name":"if","hash":{},"fn":this.program(20, data),"inverse":this.noop,"data":data}); |
| 479 | if (stack1 != null) { buffer += stack1; } |
| 480 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isReadOnly : depth0), {"name":"if","hash":{},"fn":this.program(22, data),"inverse":this.program(24, data),"data":data}); |
| 481 | if (stack1 != null) { buffer += stack1; } |
| 482 | buffer += " </form>\n <div class='response' style='display:none'>\n <h4>Curl</h4>\n <div class='block curl'></div>\n <h4>Request URL</h4>\n <div class='block request_url'></div>\n"; |
| 483 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.showRequestHeaders : depth0), {"name":"if","hash":{},"fn":this.program(26, data),"inverse":this.noop,"data":data}); |
| 484 | if (stack1 != null) { buffer += stack1; } |
| 485 | return buffer + " <h4>Response Body</h4>\n <div class='block response_body'></div>\n <h4>Response Code</h4>\n <div class='block response_code'></div>\n <h4>Response Headers</h4>\n <div class='block response_headers'></div>\n </div>\n </div>\n </li>\n </ul>\n"; |
| 486 | },"useData":true}); |
| 487 | this["Handlebars"]["templates"]["param_list"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
| 488 | return " required"; |
| 489 | },"3":function(depth0,helpers,partials,data) { |
| 490 | return " multiple=\"multiple\""; |
| 491 | },"5":function(depth0,helpers,partials,data) { |
| 492 | return " required "; |
| 493 | },"7":function(depth0,helpers,partials,data) { |
| 494 | var stack1, buffer = " <option "; |
| 495 | stack1 = helpers.unless.call(depth0, (depth0 != null ? depth0.hasDefault : depth0), {"name":"unless","hash":{},"fn":this.program(8, data),"inverse":this.noop,"data":data}); |
| 496 | if (stack1 != null) { buffer += stack1; } |
| 497 | return buffer + " value=''></option>\n"; |
| 498 | },"8":function(depth0,helpers,partials,data) { |
| 499 | return " selected=\"\" "; |
| 500 | },"10":function(depth0,helpers,partials,data) { |
| 501 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "\n <option "; |
| 502 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isDefault : depth0), {"name":"if","hash":{},"fn":this.program(11, data),"inverse":this.noop,"data":data}); |
| 503 | if (stack1 != null) { buffer += stack1; } |
| 504 | buffer += " value='" |
| 505 | + escapeExpression(((helper = (helper = helpers.value || (depth0 != null ? depth0.value : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"value","hash":{},"data":data}) : helper))) |
| 506 | + "'> " |
| 507 | + escapeExpression(((helper = (helper = helpers.value || (depth0 != null ? depth0.value : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"value","hash":{},"data":data}) : helper))) |
| 508 | + " "; |
| 509 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isDefault : depth0), {"name":"if","hash":{},"fn":this.program(13, data),"inverse":this.noop,"data":data}); |
| 510 | if (stack1 != null) { buffer += stack1; } |
| 511 | return buffer + " </option>\n\n"; |
| 512 | },"11":function(depth0,helpers,partials,data) { |
| 513 | return " selected=\"\" "; |
| 514 | },"13":function(depth0,helpers,partials,data) { |
| 515 | return " (default) "; |
| 516 | },"15":function(depth0,helpers,partials,data) { |
| 517 | return "<strong>"; |
| 518 | },"17":function(depth0,helpers,partials,data) { |
| 519 | return "</strong>"; |
| 520 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 521 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<td class='code"; |
| 522 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.required : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data}); |
| 523 | if (stack1 != null) { buffer += stack1; } |
| 524 | buffer += "'><label for='" |
| 525 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
| 526 | + "'>" |
| 527 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 528 | + "</labe></td>\n<td>\n <select "; |
| 529 | stack1 = ((helpers.isArray || (depth0 && depth0.isArray) || helperMissing).call(depth0, depth0, {"name":"isArray","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data})); |
| 530 | if (stack1 != null) { buffer += stack1; } |
| 531 | buffer += " class=\"parameter "; |
| 532 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.required : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.noop,"data":data}); |
| 533 | if (stack1 != null) { buffer += stack1; } |
| 534 | buffer += "\" name=\"" |
| 535 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 536 | + "\" id=\"" |
| 537 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
| 538 | + "\">\n\n"; |
| 539 | stack1 = helpers.unless.call(depth0, (depth0 != null ? depth0.required : depth0), {"name":"unless","hash":{},"fn":this.program(7, data),"inverse":this.noop,"data":data}); |
| 540 | if (stack1 != null) { buffer += stack1; } |
| 541 | buffer += "\n"; |
| 542 | stack1 = helpers.each.call(depth0, ((stack1 = (depth0 != null ? depth0.allowableValues : depth0)) != null ? stack1.descriptiveValues : stack1), {"name":"each","hash":{},"fn":this.program(10, data),"inverse":this.noop,"data":data}); |
| 543 | if (stack1 != null) { buffer += stack1; } |
| 544 | buffer += "\n </select>\n</td>\n<td class=\"markdown\">"; |
| 545 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.required : depth0), {"name":"if","hash":{},"fn":this.program(15, data),"inverse":this.noop,"data":data}); |
| 546 | if (stack1 != null) { buffer += stack1; } |
| 547 | stack1 = ((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper)); |
| 548 | if (stack1 != null) { buffer += stack1; } |
| 549 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.required : depth0), {"name":"if","hash":{},"fn":this.program(17, data),"inverse":this.noop,"data":data}); |
| 550 | if (stack1 != null) { buffer += stack1; } |
| 551 | buffer += "</td>\n<td>"; |
| 552 | stack1 = ((helper = (helper = helpers.paramType || (depth0 != null ? depth0.paramType : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"paramType","hash":{},"data":data}) : helper)); |
| 553 | if (stack1 != null) { buffer += stack1; } |
| 554 | return buffer + "</td>\n<td><span class=\"model-signature\"></span></td>\n"; |
| 555 | },"useData":true}); |
| 556 | this["Handlebars"]["templates"]["param_readonly_required"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
| 557 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 558 | return " <textarea class='body-textarea' readonly='readonly' placeholder='(required)' name='" |
| 559 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 560 | + "' id='" |
| 561 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
| 562 | + "'>" |
| 563 | + escapeExpression(((helper = (helper = helpers['default'] || (depth0 != null ? depth0['default'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"default","hash":{},"data":data}) : helper))) |
| 564 | + "</textarea>\n"; |
| 565 | },"3":function(depth0,helpers,partials,data) { |
| 566 | var stack1, buffer = ""; |
| 567 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['default'] : depth0), {"name":"if","hash":{},"fn":this.program(4, data),"inverse":this.program(6, data),"data":data}); |
| 568 | if (stack1 != null) { buffer += stack1; } |
| 569 | return buffer; |
| 570 | },"4":function(depth0,helpers,partials,data) { |
| 571 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 572 | return " " |
| 573 | + escapeExpression(((helper = (helper = helpers['default'] || (depth0 != null ? depth0['default'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"default","hash":{},"data":data}) : helper))) |
| 574 | + "\n"; |
| 575 | },"6":function(depth0,helpers,partials,data) { |
| 576 | return " (empty)\n"; |
| 577 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 578 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<td class='code required'><label for='" |
| 579 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
| 580 | + "'>" |
| 581 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 582 | + "</label></td>\n<td>\n"; |
| 583 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isBody : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(3, data),"data":data}); |
| 584 | if (stack1 != null) { buffer += stack1; } |
| 585 | buffer += "</td>\n<td class=\"markdown\">"; |
| 586 | stack1 = ((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper)); |
| 587 | if (stack1 != null) { buffer += stack1; } |
| 588 | buffer += "</td>\n<td>"; |
| 589 | stack1 = ((helper = (helper = helpers.paramType || (depth0 != null ? depth0.paramType : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"paramType","hash":{},"data":data}) : helper)); |
| 590 | if (stack1 != null) { buffer += stack1; } |
| 591 | return buffer + "</td>\n<td><span class=\"model-signature\"></span></td>\n"; |
| 592 | },"useData":true}); |
| 593 | this["Handlebars"]["templates"]["param_readonly"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
| 594 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 595 | return " <textarea class='body-textarea' readonly='readonly' name='" |
| 596 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 597 | + "' id='" |
| 598 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
| 599 | + "'>" |
| 600 | + escapeExpression(((helper = (helper = helpers['default'] || (depth0 != null ? depth0['default'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"default","hash":{},"data":data}) : helper))) |
| 601 | + "</textarea>\n"; |
| 602 | },"3":function(depth0,helpers,partials,data) { |
| 603 | var stack1, buffer = ""; |
| 604 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['default'] : depth0), {"name":"if","hash":{},"fn":this.program(4, data),"inverse":this.program(6, data),"data":data}); |
| 605 | if (stack1 != null) { buffer += stack1; } |
| 606 | return buffer; |
| 607 | },"4":function(depth0,helpers,partials,data) { |
| 608 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 609 | return " " |
| 610 | + escapeExpression(((helper = (helper = helpers['default'] || (depth0 != null ? depth0['default'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"default","hash":{},"data":data}) : helper))) |
| 611 | + "\n"; |
| 612 | },"6":function(depth0,helpers,partials,data) { |
| 613 | return " (empty)\n"; |
| 614 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 615 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<td class='code'><label for='" |
| 616 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
| 617 | + "'>" |
| 618 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 619 | + "</label></td>\n<td>\n"; |
| 620 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isBody : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(3, data),"data":data}); |
| 621 | if (stack1 != null) { buffer += stack1; } |
| 622 | buffer += "</td>\n<td class=\"markdown\">"; |
| 623 | stack1 = ((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper)); |
| 624 | if (stack1 != null) { buffer += stack1; } |
| 625 | buffer += "</td>\n<td>"; |
| 626 | stack1 = ((helper = (helper = helpers.paramType || (depth0 != null ? depth0.paramType : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"paramType","hash":{},"data":data}) : helper)); |
| 627 | if (stack1 != null) { buffer += stack1; } |
| 628 | return buffer + "</td>\n<td><span class=\"model-signature\"></span></td>\n"; |
| 629 | },"useData":true}); |
| 630 | this["Handlebars"]["templates"]["param_required"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
| 631 | var stack1, buffer = ""; |
| 632 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isFile : depth0), {"name":"if","hash":{},"fn":this.program(2, data),"inverse":this.program(4, data),"data":data}); |
| 633 | if (stack1 != null) { buffer += stack1; } |
| 634 | return buffer; |
| 635 | },"2":function(depth0,helpers,partials,data) { |
| 636 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 637 | return " <input type=\"file\" name='" |
| 638 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 639 | + "' id='" |
| 640 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
| 641 | + "'/>\n"; |
| 642 | },"4":function(depth0,helpers,partials,data) { |
| 643 | var stack1, buffer = ""; |
| 644 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['default'] : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.program(7, data),"data":data}); |
| 645 | if (stack1 != null) { buffer += stack1; } |
| 646 | return buffer; |
| 647 | },"5":function(depth0,helpers,partials,data) { |
| 648 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 649 | return " <textarea class='body-textarea required' placeholder='(required)' name='" |
| 650 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 651 | + "' id=\"" |
| 652 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
| 653 | + "\">" |
| 654 | + escapeExpression(((helper = (helper = helpers['default'] || (depth0 != null ? depth0['default'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"default","hash":{},"data":data}) : helper))) |
| 655 | + "</textarea>\n <br />\n <div class=\"parameter-content-type\" />\n"; |
| 656 | },"7":function(depth0,helpers,partials,data) { |
| 657 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 658 | return " <textarea class='body-textarea required' placeholder='(required)' name='" |
| 659 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 660 | + "' id='" |
| 661 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
| 662 | + "'></textarea>\n <br />\n <div class=\"parameter-content-type\" />\n"; |
| 663 | },"9":function(depth0,helpers,partials,data) { |
| 664 | var stack1, buffer = ""; |
| 665 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isFile : depth0), {"name":"if","hash":{},"fn":this.program(10, data),"inverse":this.program(12, data),"data":data}); |
| 666 | if (stack1 != null) { buffer += stack1; } |
| 667 | return buffer; |
| 668 | },"10":function(depth0,helpers,partials,data) { |
| 669 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 670 | return " <input class='parameter' class='required' type='file' name='" |
| 671 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 672 | + "' id='" |
| 673 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
| 674 | + "'/>\n"; |
| 675 | },"12":function(depth0,helpers,partials,data) { |
| 676 | var stack1, helperMissing=helpers.helperMissing, buffer = ""; |
| 677 | stack1 = ((helpers.renderTextParam || (depth0 && depth0.renderTextParam) || helperMissing).call(depth0, depth0, {"name":"renderTextParam","hash":{},"fn":this.program(13, data),"inverse":this.noop,"data":data})); |
| 678 | if (stack1 != null) { buffer += stack1; } |
| 679 | return buffer; |
| 680 | },"13":function(depth0,helpers,partials,data) { |
| 681 | return ""; |
| 682 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 683 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<td class='code required'><label for='" |
| 684 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
| 685 | + "'>" |
| 686 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 687 | + "</label></td>\n<td>\n"; |
| 688 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isBody : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(9, data),"data":data}); |
| 689 | if (stack1 != null) { buffer += stack1; } |
| 690 | buffer += "</td>\n<td>\n <strong><span class=\"markdown\">"; |
| 691 | stack1 = ((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper)); |
| 692 | if (stack1 != null) { buffer += stack1; } |
| 693 | buffer += "</span></strong>\n</td>\n<td>"; |
| 694 | stack1 = ((helper = (helper = helpers.paramType || (depth0 != null ? depth0.paramType : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"paramType","hash":{},"data":data}) : helper)); |
| 695 | if (stack1 != null) { buffer += stack1; } |
| 696 | return buffer + "</td>\n<td><span class=\"model-signature\"></span></td>\n"; |
| 697 | },"useData":true}); |
| 698 | this["Handlebars"]["templates"]["param"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
| 699 | var stack1, buffer = ""; |
| 700 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isFile : depth0), {"name":"if","hash":{},"fn":this.program(2, data),"inverse":this.program(4, data),"data":data}); |
| 701 | if (stack1 != null) { buffer += stack1; } |
| 702 | return buffer; |
| 703 | },"2":function(depth0,helpers,partials,data) { |
| 704 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 705 | return " <input type=\"file\" name='" |
| 706 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 707 | + "' id='" |
| 708 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
| 709 | + "'/>\n <div class=\"parameter-content-type\" />\n"; |
| 710 | },"4":function(depth0,helpers,partials,data) { |
| 711 | var stack1, buffer = ""; |
| 712 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['default'] : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.program(7, data),"data":data}); |
| 713 | if (stack1 != null) { buffer += stack1; } |
| 714 | return buffer; |
| 715 | },"5":function(depth0,helpers,partials,data) { |
| 716 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 717 | return " <textarea class='body-textarea' name='" |
| 718 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 719 | + "' id='" |
| 720 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
| 721 | + "'>" |
| 722 | + escapeExpression(((helper = (helper = helpers['default'] || (depth0 != null ? depth0['default'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"default","hash":{},"data":data}) : helper))) |
| 723 | + "</textarea>\n <br />\n <div class=\"parameter-content-type\" />\n"; |
| 724 | },"7":function(depth0,helpers,partials,data) { |
| 725 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 726 | return " <textarea class='body-textarea' name='" |
| 727 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 728 | + "' id='" |
| 729 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
| 730 | + "'></textarea>\n <br />\n <div class=\"parameter-content-type\" />\n"; |
| 731 | },"9":function(depth0,helpers,partials,data) { |
| 732 | var stack1, buffer = ""; |
| 733 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isFile : depth0), {"name":"if","hash":{},"fn":this.program(2, data),"inverse":this.program(10, data),"data":data}); |
| 734 | if (stack1 != null) { buffer += stack1; } |
| 735 | return buffer; |
| 736 | },"10":function(depth0,helpers,partials,data) { |
| 737 | var stack1, helperMissing=helpers.helperMissing, buffer = ""; |
| 738 | stack1 = ((helpers.renderTextParam || (depth0 && depth0.renderTextParam) || helperMissing).call(depth0, depth0, {"name":"renderTextParam","hash":{},"fn":this.program(11, data),"inverse":this.noop,"data":data})); |
| 739 | if (stack1 != null) { buffer += stack1; } |
| 740 | return buffer; |
| 741 | },"11":function(depth0,helpers,partials,data) { |
| 742 | return ""; |
| 743 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 744 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<td class='code'><label for='" |
| 745 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
| 746 | + "'>" |
| 747 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 748 | + "</label></td>\n<td>\n\n"; |
| 749 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isBody : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(9, data),"data":data}); |
| 750 | if (stack1 != null) { buffer += stack1; } |
| 751 | buffer += "\n</td>\n<td class=\"markdown\">"; |
| 752 | stack1 = ((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper)); |
| 753 | if (stack1 != null) { buffer += stack1; } |
| 754 | buffer += "</td>\n<td>"; |
| 755 | stack1 = ((helper = (helper = helpers.paramType || (depth0 != null ? depth0.paramType : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"paramType","hash":{},"data":data}) : helper)); |
| 756 | if (stack1 != null) { buffer += stack1; } |
| 757 | return buffer + "</td>\n<td>\n <span class=\"model-signature\"></span>\n</td>\n"; |
| 758 | },"useData":true}); |
| 759 | this["Handlebars"]["templates"]["parameter_content_type"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
| 760 | var stack1, buffer = ""; |
| 761 | stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.consumes : depth0), {"name":"each","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data}); |
| 762 | if (stack1 != null) { buffer += stack1; } |
| 763 | return buffer; |
| 764 | },"2":function(depth0,helpers,partials,data) { |
| 765 | var stack1, lambda=this.lambda, buffer = " <option value=\""; |
| 766 | stack1 = lambda(depth0, depth0); |
| 767 | if (stack1 != null) { buffer += stack1; } |
| 768 | buffer += "\">"; |
| 769 | stack1 = lambda(depth0, depth0); |
| 770 | if (stack1 != null) { buffer += stack1; } |
| 771 | return buffer + "</option>\n"; |
| 772 | },"4":function(depth0,helpers,partials,data) { |
| 773 | return " <option value=\"application/json\">application/json</option>\n"; |
| 774 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 775 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<label for=\"" |
| 776 | + escapeExpression(((helper = (helper = helpers.parameterContentTypeId || (depth0 != null ? depth0.parameterContentTypeId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"parameterContentTypeId","hash":{},"data":data}) : helper))) |
| 777 | + "\">Parameter content type:</label>\n<select name=\"parameterContentType\" id=\"" |
| 778 | + escapeExpression(((helper = (helper = helpers.parameterContentTypeId || (depth0 != null ? depth0.parameterContentTypeId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"parameterContentTypeId","hash":{},"data":data}) : helper))) |
| 779 | + "\">\n"; |
| 780 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.consumes : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(4, data),"data":data}); |
| 781 | if (stack1 != null) { buffer += stack1; } |
| 782 | return buffer + "</select>\n"; |
| 783 | },"useData":true}); |
| 784 | this["Handlebars"]["templates"]["resource"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
| 785 | return " : "; |
| 786 | },"3":function(depth0,helpers,partials,data) { |
| 787 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 788 | return " <li>\n <a href='" |
| 789 | + escapeExpression(((helper = (helper = helpers.url || (depth0 != null ? depth0.url : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"url","hash":{},"data":data}) : helper))) |
| 790 | + "'>Raw</a>\n </li>\n"; |
| 791 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 792 | var stack1, helper, options, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, blockHelperMissing=helpers.blockHelperMissing, buffer = "<div class='heading'>\n <h2>\n <a href='#!/" |
| 793 | + escapeExpression(((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"id","hash":{},"data":data}) : helper))) |
| 794 | + "' class=\"toggleEndpointList\" data-id=\"" |
| 795 | + escapeExpression(((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"id","hash":{},"data":data}) : helper))) |
| 796 | + "\">" |
| 797 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 798 | + "</a> "; |
| 799 | stack1 = ((helper = (helper = helpers.summary || (depth0 != null ? depth0.summary : depth0)) != null ? helper : helperMissing),(options={"name":"summary","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data}),(typeof helper === functionType ? helper.call(depth0, options) : helper)); |
| 800 | if (!helpers.summary) { stack1 = blockHelperMissing.call(depth0, stack1, options); } |
| 801 | if (stack1 != null) { buffer += stack1; } |
| 802 | stack1 = ((helper = (helper = helpers.summary || (depth0 != null ? depth0.summary : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"summary","hash":{},"data":data}) : helper)); |
| 803 | if (stack1 != null) { buffer += stack1; } |
| 804 | buffer += "\n </h2>\n <ul class='options'>\n <li>\n <a href='#!/" |
| 805 | + escapeExpression(((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"id","hash":{},"data":data}) : helper))) |
| 806 | + "' id='endpointListTogger_" |
| 807 | + escapeExpression(((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"id","hash":{},"data":data}) : helper))) |
| 808 | + "' class=\"toggleEndpointList\" data-id=\"" |
| 809 | + escapeExpression(((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"id","hash":{},"data":data}) : helper))) |
| 810 | + "\">Show/Hide</a>\n </li>\n <li>\n <a href='#' class=\"collapseResource\" data-id=\"" |
| 811 | + escapeExpression(((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"id","hash":{},"data":data}) : helper))) |
| 812 | + "\">\n List Operations\n </a>\n </li>\n <li>\n <a href='#' class=\"expandResource\" data-id=\"" |
| 813 | + escapeExpression(((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"id","hash":{},"data":data}) : helper))) |
| 814 | + "\">\n Expand Operations\n </a>\n </li>\n"; |
| 815 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.url : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data}); |
| 816 | if (stack1 != null) { buffer += stack1; } |
| 817 | return buffer + " </ul>\n</div>\n<ul class='endpoints' id='" |
| 818 | + escapeExpression(((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"id","hash":{},"data":data}) : helper))) |
| 819 | + "_endpoint_list' style='display:none'>\n\n</ul>\n"; |
| 820 | },"useData":true}); |
| 821 | this["Handlebars"]["templates"]["response_content_type"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
| 822 | var stack1, buffer = ""; |
| 823 | stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.produces : depth0), {"name":"each","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data}); |
| 824 | if (stack1 != null) { buffer += stack1; } |
| 825 | return buffer; |
| 826 | },"2":function(depth0,helpers,partials,data) { |
| 827 | var stack1, lambda=this.lambda, buffer = " <option value=\""; |
| 828 | stack1 = lambda(depth0, depth0); |
| 829 | if (stack1 != null) { buffer += stack1; } |
| 830 | buffer += "\">"; |
| 831 | stack1 = lambda(depth0, depth0); |
| 832 | if (stack1 != null) { buffer += stack1; } |
| 833 | return buffer + "</option>\n"; |
| 834 | },"4":function(depth0,helpers,partials,data) { |
| 835 | return " <option value=\"application/json\">application/json</option>\n"; |
| 836 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 837 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<label for=\"" |
| 838 | + escapeExpression(((helper = (helper = helpers.responseContentTypeId || (depth0 != null ? depth0.responseContentTypeId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"responseContentTypeId","hash":{},"data":data}) : helper))) |
| 839 | + "\">Response Content Type</label>\n<select name=\"responseContentType\" id=\"" |
| 840 | + escapeExpression(((helper = (helper = helpers.responseContentTypeId || (depth0 != null ? depth0.responseContentTypeId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"responseContentTypeId","hash":{},"data":data}) : helper))) |
| 841 | + "\">\n"; |
| 842 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.produces : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(4, data),"data":data}); |
| 843 | if (stack1 != null) { buffer += stack1; } |
| 844 | return buffer + "</select>\n"; |
| 845 | },"useData":true}); |
| 846 | this["Handlebars"]["templates"]["signature"] = Handlebars.template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 847 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<div>\n<ul class=\"signature-nav\">\n <li><a class=\"description-link\" href=\"#\">Model</a></li>\n <li><a class=\"snippet-link\" href=\"#\">Model Schema</a></li>\n</ul>\n<div>\n\n<div class=\"signature-container\">\n <div class=\"description\">\n "; |
| 848 | stack1 = ((helper = (helper = helpers.signature || (depth0 != null ? depth0.signature : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"signature","hash":{},"data":data}) : helper)); |
| 849 | if (stack1 != null) { buffer += stack1; } |
| 850 | return buffer + "\n </div>\n\n <div class=\"snippet\">\n <pre><code>" |
| 851 | + escapeExpression(((helper = (helper = helpers.sampleJSON || (depth0 != null ? depth0.sampleJSON : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"sampleJSON","hash":{},"data":data}) : helper))) |
| 852 | + "</code></pre>\n <small class=\"notice\"></small>\n </div>\n</div>\n\n"; |
| 853 | },"useData":true}); |
| 854 | this["Handlebars"]["templates"]["status_code"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
| 855 | var lambda=this.lambda, escapeExpression=this.escapeExpression; |
| 856 | return " <tr>\n <td>" |
| 857 | + escapeExpression(lambda((data && data.key), depth0)) |
| 858 | + "</td>\n <td>" |
| 859 | + escapeExpression(lambda((depth0 != null ? depth0.description : depth0), depth0)) |
| 860 | + "</td>\n <td>" |
| 861 | + escapeExpression(lambda((depth0 != null ? depth0.type : depth0), depth0)) |
| 862 | + "</td>\n </tr>\n"; |
| 863 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 864 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<td width='15%' class='code'>" |
| 865 | + escapeExpression(((helper = (helper = helpers.code || (depth0 != null ? depth0.code : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"code","hash":{},"data":data}) : helper))) |
| 866 | + "</td>\n<td class=\"markdown\">"; |
| 867 | stack1 = ((helper = (helper = helpers.message || (depth0 != null ? depth0.message : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"message","hash":{},"data":data}) : helper)); |
| 868 | if (stack1 != null) { buffer += stack1; } |
| 869 | buffer += "</td>\n<td width='50%'><span class=\"model-signature\" /></td>\n<td class=\"headers\">\n <table>\n <tbody>\n"; |
| 870 | stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.headers : depth0), {"name":"each","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data}); |
| 871 | if (stack1 != null) { buffer += stack1; } |
| 872 | return buffer + " </tbody>\n </table>\n</td>"; |
| 873 | },"useData":true}); |
| 874 | /** |
| 875 | * swagger-client - swagger-client is a javascript client for use with swaggering APIs. |
| 876 | * @version v2.1.1 |
| 877 | * @link http://swagger.io |
| 878 | * @license apache 2.0 |
| 879 | */ |
| 880 | (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){ |
| 881 | 'use strict'; |
| 882 | |
| 883 | var auth = require('./lib/auth'); |
| 884 | var helpers = require('./lib/helpers'); |
| 885 | var SwaggerClient = require('./lib/client'); |
| 886 | var deprecationWrapper = function (url, options) { |
| 887 | helpers.log('This is deprecated, use "new SwaggerClient" instead.'); |
| 888 | |
| 889 | return new SwaggerClient(url, options); |
| 890 | }; |
| 891 | |
| 892 | /* Here for IE8 Support */ |
| 893 | if (!Array.prototype.indexOf) { |
| 894 | Array.prototype.indexOf = function(obj, start) { |
| 895 | for (var i = (start || 0), j = this.length; i < j; i++) { |
| 896 | if (this[i] === obj) { return i; } |
| 897 | } |
| 898 | return -1; |
| 899 | }; |
| 900 | } |
| 901 | |
| 902 | /* Here for IE8 Support */ |
| 903 | if (!String.prototype.trim) { |
| 904 | String.prototype.trim = function () { |
| 905 | return this.replace(/^\s+|\s+$/g, ''); |
| 906 | }; |
| 907 | } |
| 908 | |
| 909 | /* Here for node 10.x support */ |
| 910 | if (!String.prototype.endsWith) { |
| 911 | String.prototype.endsWith = function(suffix) { |
| 912 | return this.indexOf(suffix, this.length - suffix.length) !== -1; |
| 913 | }; |
| 914 | } |
| 915 | |
| 916 | module.exports = SwaggerClient; |
| 917 | |
| 918 | SwaggerClient.ApiKeyAuthorization = auth.ApiKeyAuthorization; |
| 919 | SwaggerClient.PasswordAuthorization = auth.PasswordAuthorization; |
| 920 | SwaggerClient.CookieAuthorization = auth.CookieAuthorization; |
| 921 | SwaggerClient.SwaggerApi = deprecationWrapper; |
| 922 | SwaggerClient.SwaggerClient = deprecationWrapper; |
| 923 | |
| 924 | },{"./lib/auth":2,"./lib/client":3,"./lib/helpers":4}],2:[function(require,module,exports){ |
| 925 | 'use strict'; |
| 926 | |
| 927 | var btoa = require('btoa'); // jshint ignore:line |
| 928 | var CookieJar = require('cookiejar'); |
| 929 | var _ = { |
| 930 | each: require('lodash-compat/collection/each'), |
| 931 | includes: require('lodash-compat/collection/includes'), |
| 932 | isObject: require('lodash-compat/lang/isObject'), |
| 933 | isArray: require('lodash-compat/lang/isArray') |
| 934 | }; |
| 935 | |
| 936 | /** |
| 937 | * SwaggerAuthorizations applys the correct authorization to an operation being executed |
| 938 | */ |
| 939 | var SwaggerAuthorizations = module.exports.SwaggerAuthorizations = function (authz) { |
| 940 | this.authz = authz || {}; |
| 941 | }; |
| 942 | |
| 943 | /** |
| 944 | * Add auths to the hash |
| 945 | * Will overwrite any existing |
| 946 | * |
| 947 | */ |
| 948 | SwaggerAuthorizations.prototype.add = function (name, auth) { |
| 949 | if(name && typeof name === 'object') { |
| 950 | for (var key in name) { |
| 951 | this.authz[key] = name[key]; |
| 952 | } |
| 953 | } else if(typeof name === 'string' ){ |
| 954 | this.authz[name] = auth; |
| 955 | } |
| 956 | |
| 957 | return auth; |
| 958 | }; |
| 959 | |
| 960 | SwaggerAuthorizations.prototype.remove = function (name) { |
| 961 | return delete this.authz[name]; |
| 962 | }; |
| 963 | |
| 964 | SwaggerAuthorizations.prototype.apply = function (obj, securities) { |
| 965 | var status = null; |
| 966 | var applyAll = !securities; |
| 967 | var flattenedSecurities = []; |
| 968 | |
| 969 | // Securities could be [ {} ] |
| 970 | _.each(securities, function (obj, key) { |
| 971 | |
| 972 | // Make sure we account for securities being [ str ] |
| 973 | if(typeof key === 'string') { |
| 974 | flattenedSecurities.push(key); |
| 975 | } |
| 976 | |
| 977 | // Flatten keys in to our array |
| 978 | _.each(obj, function (val, key) { |
| 979 | flattenedSecurities.push(key); |
| 980 | }); |
| 981 | }); |
| 982 | |
| 983 | _.each(this.authz, function (auth, authName) { |
| 984 | if(applyAll || _.includes(flattenedSecurities, authName)) { |
| 985 | status = status || !!auth.apply(obj); // logical ORs regarding status |
| 986 | } |
| 987 | }); |
| 988 | |
| 989 | return status; |
| 990 | }; |
| 991 | |
| 992 | /** |
| 993 | * ApiKeyAuthorization allows a query param or header to be injected |
| 994 | */ |
| 995 | var ApiKeyAuthorization = module.exports.ApiKeyAuthorization = function (name, value, type) { |
| 996 | this.name = name; |
| 997 | this.value = value; |
| 998 | this.type = type; |
| 999 | }; |
| 1000 | |
| 1001 | ApiKeyAuthorization.prototype.apply = function (obj) { |
| 1002 | if (this.type === 'query') { |
| 1003 | if (obj.url.indexOf('?') > 0) { |
| 1004 | obj.url = obj.url + '&' + this.name + '=' + this.value; |
| 1005 | } else { |
| 1006 | obj.url = obj.url + '?' + this.name + '=' + this.value; |
| 1007 | } |
| 1008 | |
| 1009 | return true; |
| 1010 | } else if (this.type === 'header') { |
| 1011 | obj.headers[this.name] = this.value; |
| 1012 | |
| 1013 | return true; |
| 1014 | } |
| 1015 | }; |
| 1016 | |
| 1017 | var CookieAuthorization = module.exports.CookieAuthorization = function (cookie) { |
| 1018 | this.cookie = cookie; |
| 1019 | }; |
| 1020 | |
| 1021 | CookieAuthorization.prototype.apply = function (obj) { |
| 1022 | obj.cookieJar = obj.cookieJar || new CookieJar(); |
| 1023 | obj.cookieJar.setCookie(this.cookie); |
| 1024 | |
| 1025 | return true; |
| 1026 | }; |
| 1027 | |
| 1028 | /** |
| 1029 | * Password Authorization is a basic auth implementation |
| 1030 | */ |
| 1031 | var PasswordAuthorization = module.exports.PasswordAuthorization = function (name, username, password) { |
| 1032 | this.name = name; |
| 1033 | this.username = username; |
| 1034 | this.password = password; |
| 1035 | }; |
| 1036 | |
| 1037 | PasswordAuthorization.prototype.apply = function (obj) { |
| 1038 | obj.headers.Authorization = 'Basic ' + btoa(this.username + ':' + this.password); |
| 1039 | |
| 1040 | return true; |
| 1041 | }; |
| 1042 | |
| 1043 | },{"btoa":17,"cookiejar":18,"lodash-compat/collection/each":54,"lodash-compat/collection/includes":57,"lodash-compat/lang/isArray":144,"lodash-compat/lang/isObject":148}],3:[function(require,module,exports){ |
| 1044 | 'use strict'; |
| 1045 | |
| 1046 | var _ = { |
| 1047 | bind: require('lodash-compat/function/bind'), |
| 1048 | cloneDeep: require('lodash-compat/lang/cloneDeep'), |
| 1049 | find: require('lodash-compat/collection/find'), |
| 1050 | forEach: require('lodash-compat/collection/forEach'), |
| 1051 | indexOf: require('lodash-compat/array/indexOf'), |
| 1052 | isArray: require('lodash-compat/lang/isArray'), |
| 1053 | isFunction: require('lodash-compat/lang/isFunction'), |
| 1054 | isPlainObject: require('lodash-compat/lang/isPlainObject'), |
| 1055 | isUndefined: require('lodash-compat/lang/isUndefined') |
| 1056 | }; |
| 1057 | var auth = require('./auth'); |
| 1058 | var helpers = require('./helpers'); |
| 1059 | var Model = require('./types/model'); |
| 1060 | var Operation = require('./types/operation'); |
| 1061 | var OperationGroup = require('./types/operationGroup'); |
| 1062 | var Resolver = require('./resolver'); |
| 1063 | var SwaggerHttp = require('./http'); |
| 1064 | var SwaggerSpecConverter = require('./spec-converter'); |
| 1065 | |
| 1066 | // We have to keep track of the function/property names to avoid collisions for tag names which are used to allow the |
| 1067 | // following usage: 'client.{tagName}' |
| 1068 | var reservedClientTags = [ |
| 1069 | 'apis', |
| 1070 | 'authorizationScheme', |
| 1071 | 'authorizations', |
| 1072 | 'basePath', |
| 1073 | 'build', |
| 1074 | 'buildFrom1_1Spec', |
| 1075 | 'buildFrom1_2Spec', |
| 1076 | 'buildFromSpec', |
| 1077 | 'clientAuthorizations', |
| 1078 | 'convertInfo', |
| 1079 | 'debug', |
| 1080 | 'defaultErrorCallback', |
| 1081 | 'defaultSuccessCallback', |
| 1082 | 'fail', |
| 1083 | 'failure', |
| 1084 | 'finish', |
| 1085 | 'help', |
| 1086 | 'idFromOp', |
| 1087 | 'info', |
| 1088 | 'initialize', |
| 1089 | 'isBuilt', |
| 1090 | 'isValid', |
| 1091 | 'modelPropertyMacro', |
| 1092 | 'models', |
| 1093 | 'modelsArray', |
| 1094 | 'options', |
| 1095 | 'parameterMacro', |
| 1096 | 'parseUri', |
| 1097 | 'progress', |
| 1098 | 'resourceCount', |
| 1099 | 'sampleModels', |
| 1100 | 'selfReflect', |
| 1101 | 'setConsolidatedModels', |
| 1102 | 'spec', |
| 1103 | 'supportedSubmitMethods', |
| 1104 | 'swaggerRequestHeaders', |
| 1105 | 'tagFromLabel', |
| 1106 | 'url', |
| 1107 | 'useJQuery' |
| 1108 | ]; |
| 1109 | // We have to keep track of the function/property names to avoid collisions for tag names which are used to allow the |
| 1110 | // following usage: 'client.apis.{tagName}' |
| 1111 | var reservedApiTags = [ |
| 1112 | 'apis', |
| 1113 | 'asCurl', |
| 1114 | 'description', |
| 1115 | 'externalDocs', |
| 1116 | 'help', |
| 1117 | 'label', |
| 1118 | 'name', |
| 1119 | 'operation', |
| 1120 | 'operations', |
| 1121 | 'operationsArray', |
| 1122 | 'path', |
| 1123 | 'tag' |
| 1124 | ]; |
| 1125 | var supportedOperationMethods = ['delete', 'get', 'head', 'options', 'patch', 'post', 'put']; |
| 1126 | var SwaggerClient = module.exports = function (url, options) { |
| 1127 | this.authorizations = null; |
| 1128 | this.authorizationScheme = null; |
| 1129 | this.basePath = null; |
| 1130 | this.debug = false; |
| 1131 | this.info = null; |
| 1132 | this.isBuilt = false; |
| 1133 | this.isValid = false; |
| 1134 | this.modelsArray = []; |
| 1135 | this.resourceCount = 0; |
| 1136 | this.url = null; |
| 1137 | this.useJQuery = false; |
| 1138 | |
| 1139 | this.clientAuthorizations = new auth.SwaggerAuthorizations(); |
| 1140 | |
| 1141 | if (typeof url !== 'undefined') { |
| 1142 | return this.initialize(url, options); |
| 1143 | } else { |
| 1144 | return this; |
| 1145 | } |
| 1146 | }; |
| 1147 | |
| 1148 | SwaggerClient.prototype.initialize = function (url, options) { |
| 1149 | this.models = {}; |
| 1150 | this.sampleModels = {}; |
| 1151 | |
| 1152 | if (typeof url === 'string') { |
| 1153 | this.url = url; |
| 1154 | } else if (typeof url === 'object') { |
| 1155 | options = url; |
| 1156 | this.url = options.url; |
| 1157 | } |
| 1158 | |
| 1159 | options = options || {}; |
| 1160 | this.clientAuthorizations.add(options.authorizations); |
| 1161 | this.swaggerRequestHeaders = options.swaggerRequestHeaders || 'application/json;charset=utf-8,*/*'; |
| 1162 | this.defaultSuccessCallback = options.defaultSuccessCallback || null; |
| 1163 | this.defaultErrorCallback = options.defaultErrorCallback || null; |
| 1164 | this.modelPropertyMacro = options.modelPropertyMacro || null; |
| 1165 | this.parameterMacro = options.modelPropertyMacro || null; |
| 1166 | |
| 1167 | if (typeof options.success === 'function') { |
| 1168 | this.success = options.success; |
| 1169 | } |
| 1170 | |
| 1171 | if (options.useJQuery) { |
| 1172 | this.useJQuery = options.useJQuery; |
| 1173 | } |
| 1174 | |
| 1175 | this.options = options || {}; |
| 1176 | |
| 1177 | this.supportedSubmitMethods = options.supportedSubmitMethods || []; |
| 1178 | this.failure = options.failure || function () {}; |
| 1179 | this.progress = options.progress || function () {}; |
| 1180 | this.spec = _.cloneDeep(options.spec); // Clone so we do not alter the provided document |
| 1181 | |
| 1182 | if (typeof options.success === 'function') { |
| 1183 | this.ready = true; |
| 1184 | this.build(); |
| 1185 | } |
| 1186 | }; |
| 1187 | |
| 1188 | SwaggerClient.prototype.build = function (mock) { |
| 1189 | if (this.isBuilt) { |
| 1190 | return this; |
| 1191 | } |
| 1192 | |
| 1193 | var self = this; |
| 1194 | |
| 1195 | this.progress('fetching resource list: ' + this.url); |
| 1196 | |
| 1197 | var obj = { |
| 1198 | useJQuery: this.useJQuery, |
| 1199 | url: this.url, |
| 1200 | method: 'get', |
| 1201 | headers: { |
| 1202 | accept: this.swaggerRequestHeaders |
| 1203 | }, |
| 1204 | on: { |
| 1205 | error: function (response) { |
| 1206 | if (self.url.substring(0, 4) !== 'http') { |
| 1207 | return self.fail('Please specify the protocol for ' + self.url); |
| 1208 | } else if (response.status === 0) { |
| 1209 | return self.fail('Can\'t read from server. It may not have the appropriate access-control-origin settings.'); |
| 1210 | } else if (response.status === 404) { |
| 1211 | return self.fail('Can\'t read swagger JSON from ' + self.url); |
| 1212 | } else { |
| 1213 | return self.fail(response.status + ' : ' + response.statusText + ' ' + self.url); |
| 1214 | } |
| 1215 | }, |
| 1216 | response: function (resp) { |
| 1217 | |
| 1218 | var responseObj = resp.obj; |
| 1219 | if(!responseObj) { |
| 1220 | return self.fail('failed to parse JSON/YAML response'); |
| 1221 | } |
| 1222 | |
| 1223 | self.swaggerVersion = responseObj.swaggerVersion; |
| 1224 | |
| 1225 | if (responseObj.swagger && parseInt(responseObj.swagger) === 2) { |
| 1226 | self.swaggerVersion = responseObj.swagger; |
| 1227 | |
| 1228 | new Resolver().resolve(responseObj, self.url, self.buildFromSpec, self); |
| 1229 | |
| 1230 | self.isValid = true; |
| 1231 | } else { |
| 1232 | var converter = new SwaggerSpecConverter(); |
| 1233 | converter.setDocumentationLocation(self.url); |
| 1234 | converter.convert(responseObj, self.clientAuthorizations, function(spec) { |
| 1235 | new Resolver().resolve(spec, self.url, self.buildFromSpec, self); |
| 1236 | self.isValid = true; |
| 1237 | }); |
| 1238 | } |
| 1239 | } |
| 1240 | } |
| 1241 | }; |
| 1242 | |
| 1243 | if (this.spec) { |
| 1244 | setTimeout(function () { |
| 1245 | new Resolver().resolve(self.spec, self.buildFromSpec, self); |
| 1246 | }, 10); |
| 1247 | } else { |
| 1248 | this.clientAuthorizations.apply(obj); |
| 1249 | |
| 1250 | if (mock) { |
| 1251 | return obj; |
| 1252 | } |
| 1253 | |
| 1254 | new SwaggerHttp().execute(obj, this.options); |
| 1255 | } |
| 1256 | |
| 1257 | return this; |
| 1258 | }; |
| 1259 | |
| 1260 | SwaggerClient.prototype.buildFromSpec = function (response) { |
| 1261 | if (this.isBuilt) { |
| 1262 | return this; |
| 1263 | } |
| 1264 | |
| 1265 | this.apis = {}; |
| 1266 | this.apisArray = []; |
| 1267 | this.basePath = response.basePath || ''; |
| 1268 | this.consumes = response.consumes; |
| 1269 | this.host = response.host || ''; |
| 1270 | this.info = response.info || {}; |
| 1271 | this.produces = response.produces; |
| 1272 | this.schemes = response.schemes || []; |
| 1273 | this.securityDefinitions = response.securityDefinitions; |
| 1274 | this.title = response.title || ''; |
| 1275 | |
| 1276 | if (response.externalDocs) { |
| 1277 | this.externalDocs = response.externalDocs; |
| 1278 | } |
| 1279 | |
| 1280 | // legacy support |
| 1281 | this.authSchemes = response.securityDefinitions; |
| 1282 | |
| 1283 | var definedTags = {}; |
| 1284 | var k; |
| 1285 | |
| 1286 | if (Array.isArray(response.tags)) { |
| 1287 | definedTags = {}; |
| 1288 | |
| 1289 | for (k = 0; k < response.tags.length; k++) { |
| 1290 | var t = response.tags[k]; |
| 1291 | definedTags[t.name] = t; |
| 1292 | } |
| 1293 | } |
| 1294 | |
| 1295 | var location; |
| 1296 | |
| 1297 | if (typeof this.url === 'string') { |
| 1298 | location = this.parseUri(this.url); |
| 1299 | if (typeof this.schemes === 'undefined' || this.schemes.length === 0) { |
| 1300 | this.scheme = location.scheme || 'http'; |
| 1301 | } else { |
| 1302 | this.scheme = this.schemes[0]; |
| 1303 | } |
| 1304 | |
| 1305 | if (typeof this.host === 'undefined' || this.host === '') { |
| 1306 | this.host = location.host; |
| 1307 | |
| 1308 | if (location.port) { |
| 1309 | this.host = this.host + ':' + location.port; |
| 1310 | } |
| 1311 | } |
| 1312 | } |
| 1313 | else { |
| 1314 | if (typeof this.schemes === 'undefined' || this.schemes.length === 0) { |
| 1315 | this.scheme = 'http'; |
| 1316 | } |
| 1317 | else { |
| 1318 | this.scheme = this.schemes[0]; |
| 1319 | } |
| 1320 | } |
| 1321 | |
| 1322 | this.definitions = response.definitions; |
| 1323 | |
| 1324 | var key; |
| 1325 | |
| 1326 | for (key in this.definitions) { |
| 1327 | var model = new Model(key, this.definitions[key], this.models, this.modelPropertyMacro); |
| 1328 | |
| 1329 | if (model) { |
| 1330 | this.models[key] = model; |
| 1331 | } |
| 1332 | } |
| 1333 | |
| 1334 | // get paths, create functions for each operationId |
| 1335 | var self = this; |
| 1336 | |
| 1337 | // Bind help to 'client.apis' |
| 1338 | self.apis.help = _.bind(self.help, self); |
| 1339 | |
| 1340 | _.forEach(response.paths, function (pathObj, path) { |
| 1341 | // Only process a path if it's an object |
| 1342 | if (!_.isPlainObject(pathObj)) { |
| 1343 | return; |
| 1344 | } |
| 1345 | |
| 1346 | _.forEach(supportedOperationMethods, function (method) { |
| 1347 | var operation = pathObj[method]; |
| 1348 | |
| 1349 | if (_.isUndefined(operation)) { |
| 1350 | // Operation does not exist |
| 1351 | return; |
| 1352 | } else if (!_.isPlainObject(operation)) { |
| 1353 | // Operation exists but it is not an Operation Object. Since this is invalid, log it. |
| 1354 | helpers.log('The \'' + method + '\' operation for \'' + path + '\' path is not an Operation Object'); |
| 1355 | |
| 1356 | return; |
| 1357 | } |
| 1358 | |
| 1359 | var tags = operation.tags; |
| 1360 | |
| 1361 | if (_.isUndefined(tags) || !_.isArray(tags) || tags.length === 0) { |
| 1362 | tags = operation.tags = [ 'default' ]; |
| 1363 | } |
| 1364 | |
| 1365 | var operationId = self.idFromOp(path, method, operation); |
| 1366 | var operationObject = new Operation(self, |
| 1367 | operation.scheme, |
| 1368 | operationId, |
| 1369 | method, |
| 1370 | path, |
| 1371 | operation, |
| 1372 | self.definitions, |
| 1373 | self.models, |
| 1374 | self.clientAuthorizations); |
| 1375 | |
| 1376 | // bind self operation's execute command to the api |
| 1377 | _.forEach(tags, function (tag) { |
| 1378 | var clientProperty = _.indexOf(reservedClientTags, tag) > -1 ? '_' + tag : tag; |
| 1379 | var apiProperty = _.indexOf(reservedApiTags, tag) > -1 ? '_' + tag : tag; |
| 1380 | var operationGroup = self[clientProperty]; |
| 1381 | |
| 1382 | if (clientProperty !== tag) { |
| 1383 | helpers.log('The \'' + tag + '\' tag conflicts with a SwaggerClient function/property name. Use \'client.' + |
| 1384 | clientProperty + '\' or \'client.apis.' + tag + '\' instead of \'client.' + tag + '\'.'); |
| 1385 | } |
| 1386 | |
| 1387 | if (apiProperty !== tag) { |
| 1388 | helpers.log('The \'' + tag + '\' tag conflicts with a SwaggerClient operation function/property name. Use ' + |
| 1389 | '\'client.apis.' + apiProperty + '\' instead of \'client.apis.' + tag + '\'.'); |
| 1390 | } |
| 1391 | |
| 1392 | if (_.indexOf(reservedApiTags, operationId) > -1) { |
| 1393 | helpers.log('The \'' + operationId + '\' operationId conflicts with a SwaggerClient operation ' + |
| 1394 | 'function/property name. Use \'client.apis.' + apiProperty + '._' + operationId + |
| 1395 | '\' instead of \'client.apis.' + apiProperty + '.' + operationId + '\'.'); |
| 1396 | |
| 1397 | operationId = '_' + operationId; |
| 1398 | operationObject.nickname = operationId; // So 'client.apis.[tag].operationId.help() works properly |
| 1399 | } |
| 1400 | |
| 1401 | if (_.isUndefined(operationGroup)) { |
| 1402 | operationGroup = self[clientProperty] = self.apis[apiProperty] = {}; |
| 1403 | |
| 1404 | operationGroup.operations = {}; |
| 1405 | operationGroup.label = apiProperty; |
| 1406 | operationGroup.apis = {}; |
| 1407 | |
| 1408 | var tagDef = definedTags[tag]; |
| 1409 | |
| 1410 | if (!_.isUndefined(tagDef)) { |
| 1411 | operationGroup.description = tagDef.description; |
| 1412 | operationGroup.externalDocs = tagDef.externalDocs; |
| 1413 | } |
| 1414 | |
| 1415 | self[clientProperty].help = _.bind(self.help, operationGroup); |
| 1416 | self.apisArray.push(new OperationGroup(tag, operationGroup.description, operationGroup.externalDocs, operationObject)); |
| 1417 | } |
| 1418 | |
| 1419 | // Bind tag help |
| 1420 | if (!_.isFunction(operationGroup.help)) { |
| 1421 | operationGroup.help = _.bind(self.help, operationGroup); |
| 1422 | } |
| 1423 | |
| 1424 | // bind to the apis object |
| 1425 | self.apis[apiProperty][operationId] = operationGroup[operationId] = _.bind(operationObject.execute, |
| 1426 | operationObject); |
| 1427 | self.apis[apiProperty][operationId].help = operationGroup[operationId].help = _.bind(operationObject.help, |
| 1428 | operationObject); |
| 1429 | self.apis[apiProperty][operationId].asCurl = operationGroup[operationId].asCurl = _.bind(operationObject.asCurl, |
| 1430 | operationObject); |
| 1431 | |
| 1432 | operationGroup.apis[operationId] = operationGroup.operations[operationId] = operationObject; |
| 1433 | |
| 1434 | // legacy UI feature |
| 1435 | var api = _.find(self.apisArray, function (api) { |
| 1436 | return api.tag === tag; |
| 1437 | }); |
| 1438 | |
| 1439 | if (api) { |
| 1440 | api.operationsArray.push(operationObject); |
| 1441 | } |
| 1442 | }); |
| 1443 | }); |
| 1444 | }); |
| 1445 | |
| 1446 | this.isBuilt = true; |
| 1447 | |
| 1448 | if (this.success) { |
| 1449 | this.isValid = true; |
| 1450 | this.isBuilt = true; |
| 1451 | this.success(); |
| 1452 | } |
| 1453 | |
| 1454 | return this; |
| 1455 | }; |
| 1456 | |
| 1457 | SwaggerClient.prototype.parseUri = function (uri) { |
| 1458 | var urlParseRE = /^(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/; |
| 1459 | var parts = urlParseRE.exec(uri); |
| 1460 | |
| 1461 | return { |
| 1462 | scheme: parts[4].replace(':',''), |
| 1463 | host: parts[11], |
| 1464 | port: parts[12], |
| 1465 | path: parts[15] |
| 1466 | }; |
| 1467 | }; |
| 1468 | |
| 1469 | SwaggerClient.prototype.help = function (dontPrint) { |
| 1470 | var output = ''; |
| 1471 | |
| 1472 | if (this instanceof SwaggerClient) { |
| 1473 | _.forEach(this.apis, function (api, name) { |
| 1474 | if (_.isPlainObject(api)) { |
| 1475 | output += 'operations for the \'' + name + '\' tag\n'; |
| 1476 | |
| 1477 | _.forEach(api.operations, function (operation, name) { |
| 1478 | output += ' * ' + name + ': ' + operation.summary + '\n'; |
| 1479 | }); |
| 1480 | } |
| 1481 | }); |
| 1482 | } else if (this instanceof OperationGroup || _.isPlainObject(this)) { |
| 1483 | output += 'operations for the \'' + this.label + '\' tag\n'; |
| 1484 | |
| 1485 | _.forEach(this.apis, function (operation, name) { |
| 1486 | output += ' * ' + name + ': ' + operation.summary + '\n'; |
| 1487 | }); |
| 1488 | } |
| 1489 | |
| 1490 | if (dontPrint) { |
| 1491 | return output; |
| 1492 | } else { |
| 1493 | helpers.log(output); |
| 1494 | |
| 1495 | return output; |
| 1496 | } |
| 1497 | }; |
| 1498 | |
| 1499 | SwaggerClient.prototype.tagFromLabel = function (label) { |
| 1500 | return label; |
| 1501 | }; |
| 1502 | |
| 1503 | SwaggerClient.prototype.idFromOp = function (path, httpMethod, op) { |
| 1504 | if(!op || !op.operationId) { |
| 1505 | op = op || {}; |
| 1506 | op.operationId = httpMethod + '_' + path; |
| 1507 | } |
| 1508 | var opId = op.operationId.replace(/[\s!@#$%^&*()_+=\[{\]};:<>|.\/?,\\'""-]/g, '_') || (path.substring(1) + '_' + httpMethod); |
| 1509 | |
| 1510 | opId = opId.replace(/((_){2,})/g, '_'); |
| 1511 | opId = opId.replace(/^(_)*/g, ''); |
| 1512 | opId = opId.replace(/([_])*$/g, ''); |
| 1513 | return opId; |
| 1514 | }; |
| 1515 | |
| 1516 | SwaggerClient.prototype.fail = function (message) { |
| 1517 | this.failure(message); |
| 1518 | |
| 1519 | throw message; |
| 1520 | }; |
| 1521 | |
| 1522 | },{"./auth":2,"./helpers":4,"./http":5,"./resolver":6,"./spec-converter":7,"./types/model":8,"./types/operation":9,"./types/operationGroup":10,"lodash-compat/array/indexOf":51,"lodash-compat/collection/find":55,"lodash-compat/collection/forEach":56,"lodash-compat/function/bind":60,"lodash-compat/lang/cloneDeep":142,"lodash-compat/lang/isArray":144,"lodash-compat/lang/isFunction":146,"lodash-compat/lang/isPlainObject":149,"lodash-compat/lang/isUndefined":152}],4:[function(require,module,exports){ |
| 1523 | (function (process){ |
| 1524 | 'use strict'; |
| 1525 | |
| 1526 | var _ = { |
| 1527 | isPlainObject: require('lodash-compat/lang/isPlainObject') |
| 1528 | }; |
| 1529 | |
| 1530 | module.exports.__bind = function (fn, me) { |
| 1531 | return function(){ |
| 1532 | return fn.apply(me, arguments); |
| 1533 | }; |
| 1534 | }; |
| 1535 | |
| 1536 | var log = module.exports.log = function() { |
| 1537 | // Only log if available and we're not testing |
| 1538 | if (console && process.env.NODE_ENV !== 'test') { |
| 1539 | console.log(Array.prototype.slice.call(arguments)[0]); |
| 1540 | } |
| 1541 | }; |
| 1542 | |
| 1543 | module.exports.fail = function (message) { |
| 1544 | log(message); |
| 1545 | }; |
| 1546 | |
| 1547 | module.exports.optionHtml = function (label, value) { |
| 1548 | return '<tr><td class="optionName">' + label + ':</td><td>' + value + '</td></tr>'; |
| 1549 | }; |
| 1550 | |
| 1551 | var resolveSchema = module.exports.resolveSchema = function (schema) { |
| 1552 | if (_.isPlainObject(schema.schema)) { |
| 1553 | schema = resolveSchema(schema.schema); |
| 1554 | } |
| 1555 | |
| 1556 | return schema; |
| 1557 | }; |
| 1558 | |
| 1559 | module.exports.typeFromJsonSchema = function (type, format) { |
| 1560 | var str; |
| 1561 | |
| 1562 | if (type === 'integer' && format === 'int32') { |
| 1563 | str = 'integer'; |
| 1564 | } else if (type === 'integer' && format === 'int64') { |
| 1565 | str = 'long'; |
| 1566 | } else if (type === 'integer' && typeof format === 'undefined') { |
| 1567 | str = 'long'; |
| 1568 | } else if (type === 'string' && format === 'date-time') { |
| 1569 | str = 'date-time'; |
| 1570 | } else if (type === 'string' && format === 'date') { |
| 1571 | str = 'date'; |
| 1572 | } else if (type === 'number' && format === 'float') { |
| 1573 | str = 'float'; |
| 1574 | } else if (type === 'number' && format === 'double') { |
| 1575 | str = 'double'; |
| 1576 | } else if (type === 'number' && typeof format === 'undefined') { |
| 1577 | str = 'double'; |
| 1578 | } else if (type === 'boolean') { |
| 1579 | str = 'boolean'; |
| 1580 | } else if (type === 'string') { |
| 1581 | str = 'string'; |
| 1582 | } |
| 1583 | |
| 1584 | return str; |
| 1585 | }; |
| 1586 | |
| 1587 | var simpleRef = module.exports.simpleRef = function (name) { |
| 1588 | if (typeof name === 'undefined') { |
| 1589 | return null; |
| 1590 | } |
| 1591 | |
| 1592 | if (name.indexOf('#/definitions/') === 0) { |
| 1593 | return name.substring('#/definitions/'.length); |
| 1594 | } else { |
| 1595 | return name; |
| 1596 | } |
| 1597 | }; |
| 1598 | |
| 1599 | var getStringSignature = module.exports.getStringSignature = function (obj, baseComponent) { |
| 1600 | var str = ''; |
| 1601 | |
| 1602 | if (typeof obj.$ref !== 'undefined') { |
| 1603 | str += simpleRef(obj.$ref); |
| 1604 | } else if (typeof obj.type === 'undefined') { |
| 1605 | str += 'object'; |
| 1606 | } else if (obj.type === 'array') { |
| 1607 | if (baseComponent) { |
| 1608 | str += getStringSignature((obj.items || obj.$ref || {})); |
| 1609 | } else { |
| 1610 | str += 'Array['; |
| 1611 | str += getStringSignature((obj.items || obj.$ref || {})); |
| 1612 | str += ']'; |
| 1613 | } |
| 1614 | } else if (obj.type === 'integer' && obj.format === 'int32') { |
| 1615 | str += 'integer'; |
| 1616 | } else if (obj.type === 'integer' && obj.format === 'int64') { |
| 1617 | str += 'long'; |
| 1618 | } else if (obj.type === 'integer' && typeof obj.format === 'undefined') { |
| 1619 | str += 'long'; |
| 1620 | } else if (obj.type === 'string' && obj.format === 'date-time') { |
| 1621 | str += 'date-time'; |
| 1622 | } else if (obj.type === 'string' && obj.format === 'date') { |
| 1623 | str += 'date'; |
| 1624 | } else if (obj.type === 'string' && typeof obj.format === 'undefined') { |
| 1625 | str += 'string'; |
| 1626 | } else if (obj.type === 'number' && obj.format === 'float') { |
| 1627 | str += 'float'; |
| 1628 | } else if (obj.type === 'number' && obj.format === 'double') { |
| 1629 | str += 'double'; |
| 1630 | } else if (obj.type === 'number' && typeof obj.format === 'undefined') { |
| 1631 | str += 'double'; |
| 1632 | } else if (obj.type === 'boolean') { |
| 1633 | str += 'boolean'; |
| 1634 | } else if (obj.$ref) { |
| 1635 | str += simpleRef(obj.$ref); |
| 1636 | } else { |
| 1637 | str += obj.type; |
| 1638 | } |
| 1639 | |
| 1640 | return str; |
| 1641 | }; |
| 1642 | |
| 1643 | }).call(this,require('_process')) |
| 1644 | |
| 1645 | },{"_process":16,"lodash-compat/lang/isPlainObject":149}],5:[function(require,module,exports){ |
| 1646 | 'use strict'; |
| 1647 | |
| 1648 | var helpers = require('./helpers'); |
| 1649 | var jQuery = require('jquery'); |
| 1650 | var request = require('superagent'); |
| 1651 | var jsyaml = require('js-yaml'); |
| 1652 | |
| 1653 | /* |
| 1654 | * JQueryHttpClient is a light-weight, node or browser HTTP client |
| 1655 | */ |
| 1656 | var JQueryHttpClient = function () {}; |
| 1657 | |
| 1658 | /* |
| 1659 | * SuperagentHttpClient is a light-weight, node or browser HTTP client |
| 1660 | */ |
| 1661 | var SuperagentHttpClient = function () {}; |
| 1662 | |
| 1663 | /** |
| 1664 | * SwaggerHttp is a wrapper for executing requests |
| 1665 | */ |
| 1666 | var SwaggerHttp = module.exports = function () {}; |
| 1667 | |
| 1668 | SwaggerHttp.prototype.execute = function (obj, opts) { |
| 1669 | var client; |
| 1670 | |
| 1671 | if(opts && opts.client) { |
| 1672 | client = opts.client; |
| 1673 | } |
| 1674 | else { |
| 1675 | client = new SuperagentHttpClient(opts); |
| 1676 | } |
| 1677 | |
| 1678 | // legacy support |
| 1679 | if ((obj && obj.useJQuery === true) || this.isInternetExplorer()) { |
| 1680 | client = new JQueryHttpClient(opts); |
| 1681 | } |
| 1682 | |
| 1683 | var success = obj.on.response; |
| 1684 | |
| 1685 | var responseInterceptor = function(data) { |
| 1686 | if(opts && opts.responseInterceptor) { |
| 1687 | data = opts.responseInterceptor.apply(data); |
| 1688 | } |
| 1689 | success(data); |
| 1690 | }; |
| 1691 | |
| 1692 | obj.on.response = function(data) { |
| 1693 | responseInterceptor(data); |
| 1694 | }; |
| 1695 | |
| 1696 | |
| 1697 | if (obj && typeof obj.body === 'object') { |
| 1698 | // special processing for file uploads via jquery |
| 1699 | if (obj.body.type && obj.body.type === 'formData'){ |
| 1700 | obj.contentType = false; |
| 1701 | obj.processData = false; |
| 1702 | |
| 1703 | delete obj.headers['Content-Type']; |
| 1704 | } else { |
| 1705 | obj.body = JSON.stringify(obj.body); |
| 1706 | } |
| 1707 | } |
| 1708 | client.execute(obj); |
| 1709 | }; |
| 1710 | |
| 1711 | SwaggerHttp.prototype.isInternetExplorer = function () { |
| 1712 | var detectedIE = false; |
| 1713 | |
| 1714 | if (typeof navigator !== 'undefined' && navigator.userAgent) { |
| 1715 | var nav = navigator.userAgent.toLowerCase(); |
| 1716 | |
| 1717 | if (nav.indexOf('msie') !== -1) { |
| 1718 | var version = parseInt(nav.split('msie')[1]); |
| 1719 | |
| 1720 | if (version <= 8) { |
| 1721 | detectedIE = true; |
| 1722 | } |
| 1723 | } |
| 1724 | } |
| 1725 | |
| 1726 | return detectedIE; |
| 1727 | }; |
| 1728 | |
| 1729 | JQueryHttpClient.prototype.execute = function (obj) { |
| 1730 | var cb = obj.on; |
| 1731 | var request = obj; |
| 1732 | |
| 1733 | obj.type = obj.method; |
| 1734 | obj.cache = false; |
| 1735 | delete obj.useJQuery; |
| 1736 | |
| 1737 | /* |
| 1738 | obj.beforeSend = function (xhr) { |
| 1739 | var key, results; |
| 1740 | if (obj.headers) { |
| 1741 | results = []; |
| 1742 | for (key in obj.headers) { |
| 1743 | if (key.toLowerCase() === 'content-type') { |
| 1744 | results.push(obj.contentType = obj.headers[key]); |
| 1745 | } else if (key.toLowerCase() === 'accept') { |
| 1746 | results.push(obj.accepts = obj.headers[key]); |
| 1747 | } else { |
| 1748 | results.push(xhr.setRequestHeader(key, obj.headers[key])); |
| 1749 | } |
| 1750 | } |
| 1751 | return results; |
| 1752 | } |
| 1753 | };*/ |
| 1754 | |
| 1755 | obj.data = obj.body; |
| 1756 | |
| 1757 | delete obj.body; |
| 1758 | |
| 1759 | obj.complete = function (response) { |
| 1760 | var headers = {}; |
| 1761 | var headerArray = response.getAllResponseHeaders().split('\n'); |
| 1762 | |
| 1763 | for (var i = 0; i < headerArray.length; i++) { |
| 1764 | var toSplit = headerArray[i].trim(); |
| 1765 | |
| 1766 | if (toSplit.length === 0) { |
| 1767 | continue; |
| 1768 | } |
| 1769 | |
| 1770 | var separator = toSplit.indexOf(':'); |
| 1771 | |
| 1772 | if (separator === -1) { |
| 1773 | // Name but no value in the header |
| 1774 | headers[toSplit] = null; |
| 1775 | |
| 1776 | continue; |
| 1777 | } |
| 1778 | |
| 1779 | var name = toSplit.substring(0, separator).trim(); |
| 1780 | var value = toSplit.substring(separator + 1).trim(); |
| 1781 | |
| 1782 | headers[name] = value; |
| 1783 | } |
| 1784 | |
| 1785 | var out = { |
| 1786 | url: request.url, |
| 1787 | method: request.method, |
| 1788 | status: response.status, |
| 1789 | statusText: response.statusText, |
| 1790 | data: response.responseText, |
| 1791 | headers: headers |
| 1792 | }; |
| 1793 | |
| 1794 | try { |
| 1795 | var possibleObj = response.responseJSON || jsyaml.safeLoad(response.responseText); |
| 1796 | out.obj = (typeof possibleObj === 'string') ? {} : possibleObj; |
| 1797 | } catch (ex) { |
| 1798 | // do not set out.obj |
| 1799 | helpers.log('unable to parse JSON/YAML content'); |
| 1800 | } |
| 1801 | |
| 1802 | // I can throw, or parse null? |
| 1803 | out.obj = out.obj || null; |
| 1804 | |
| 1805 | if (response.status >= 200 && response.status < 300) { |
| 1806 | cb.response(out); |
| 1807 | } else if (response.status === 0 || (response.status >= 400 && response.status < 599)) { |
| 1808 | cb.error(out); |
| 1809 | } else { |
| 1810 | return cb.response(out); |
| 1811 | } |
| 1812 | }; |
| 1813 | |
| 1814 | jQuery.support.cors = true; |
| 1815 | |
| 1816 | return jQuery.ajax(obj); |
| 1817 | }; |
| 1818 | |
| 1819 | SuperagentHttpClient.prototype.execute = function (obj) { |
| 1820 | var method = obj.method.toLowerCase(); |
| 1821 | |
| 1822 | if (method === 'delete') { |
| 1823 | method = 'del'; |
| 1824 | } |
| 1825 | var headers = obj.headers || {}; |
| 1826 | var r = request[method](obj.url); |
| 1827 | var name; |
| 1828 | for (name in headers) { |
| 1829 | r.set(name, headers[name]); |
| 1830 | } |
| 1831 | |
| 1832 | if (obj.body) { |
| 1833 | r.send(obj.body); |
| 1834 | } |
| 1835 | |
| 1836 | if(typeof r.buffer === 'function') { |
| 1837 | r.buffer(); // force superagent to populate res.text with the raw response data |
| 1838 | } |
| 1839 | |
| 1840 | r.end(function (err, res) { |
| 1841 | res = res || { |
| 1842 | status: 0, |
| 1843 | headers: {error: 'no response from server'} |
| 1844 | }; |
| 1845 | var response = { |
| 1846 | url: obj.url, |
| 1847 | method: obj.method, |
| 1848 | headers: res.headers |
| 1849 | }; |
| 1850 | var cb; |
| 1851 | |
| 1852 | if (!err && res.error) { |
| 1853 | err = res.error; |
| 1854 | } |
| 1855 | |
| 1856 | if (err && obj.on && obj.on.error) { |
| 1857 | response.obj = err; |
| 1858 | response.status = res ? res.status : 500; |
| 1859 | response.statusText = res ? res.text : err.message; |
| 1860 | cb = obj.on.error; |
| 1861 | } else if (res && obj.on && obj.on.response) { |
| 1862 | var possibleObj; |
| 1863 | |
| 1864 | // Already parsed by by superagent? |
| 1865 | if(res.body && Object.keys(res.body).length > 0) { |
| 1866 | possibleObj = res.body; |
| 1867 | } else { |
| 1868 | try { |
| 1869 | possibleObj = jsyaml.safeLoad(res.text); |
| 1870 | // can parse into a string... which we don't need running around in the system |
| 1871 | possibleObj = (typeof possibleObj === 'string') ? null : possibleObj; |
| 1872 | } catch(e) { |
| 1873 | helpers.log('cannot parse JSON/YAML content'); |
| 1874 | } |
| 1875 | } |
| 1876 | |
| 1877 | // null means we can't parse into object |
| 1878 | response.obj = possibleObj || null; |
| 1879 | |
| 1880 | response.status = res.status; |
| 1881 | response.statusText = res.text; |
| 1882 | cb = obj.on.response; |
| 1883 | } |
| 1884 | response.data = response.statusText; |
| 1885 | |
| 1886 | if (cb) { |
| 1887 | cb(response); |
| 1888 | } |
| 1889 | }); |
| 1890 | }; |
| 1891 | |
| 1892 | },{"./helpers":4,"jquery":19,"js-yaml":20,"superagent":163}],6:[function(require,module,exports){ |
| 1893 | 'use strict'; |
| 1894 | |
| 1895 | var SwaggerHttp = require('./http'); |
| 1896 | |
| 1897 | /** |
| 1898 | * Resolves a spec's remote references |
| 1899 | */ |
| 1900 | var Resolver = module.exports = function () {}; |
| 1901 | |
| 1902 | Resolver.prototype.resolve = function (spec, arg1, arg2, arg3) { |
| 1903 | var root = arg1, callback = arg2, scope = arg3, location, i; |
| 1904 | if(typeof arg1 === 'function') { |
| 1905 | root = null; |
| 1906 | callback = arg1; |
| 1907 | scope = arg2; |
| 1908 | } |
| 1909 | var _root = root; |
| 1910 | this.scope = (scope || this); |
| 1911 | this.iteration = this.iteration || 0; |
| 1912 | |
| 1913 | var name, path, property, propertyName; |
| 1914 | var processedCalls = 0, resolvedRefs = {}, unresolvedRefs = {}; |
| 1915 | var resolutionTable = []; // store objects for dereferencing |
| 1916 | |
| 1917 | // definitions |
| 1918 | for (name in spec.definitions) { |
| 1919 | var definition = spec.definitions[name]; |
| 1920 | for (propertyName in definition.properties) { |
| 1921 | property = definition.properties[propertyName]; |
| 1922 | this.resolveTo(root, property, resolutionTable, '/definitions'); |
| 1923 | } |
| 1924 | |
| 1925 | if(definition.allOf) { |
| 1926 | var allOf = definition.allOf; |
| 1927 | // the refs go first |
| 1928 | allOf.sort(function(a, b) { |
| 1929 | if(a.$ref && b.$ref) { return 0; } |
| 1930 | else if(a.$ref) { return -1; } |
| 1931 | else { return 1; } |
| 1932 | }); |
| 1933 | for (i = 0; i < allOf.length; i++) { |
| 1934 | property = allOf[i]; |
| 1935 | location = '/definitions/' + name + '/allOf'; |
| 1936 | this.resolveInline(null, spec, property, resolutionTable, unresolvedRefs, location); |
| 1937 | } |
| 1938 | } |
| 1939 | } |
| 1940 | |
| 1941 | // operations |
| 1942 | for (name in spec.paths) { |
| 1943 | var method, operation, responseCode; |
| 1944 | path = spec.paths[name]; |
| 1945 | |
| 1946 | for (method in path) { |
| 1947 | // operation reference |
| 1948 | if(method === '$ref') { |
| 1949 | // location = path[method]; |
| 1950 | location = '/paths' + name; |
| 1951 | this.resolveInline(root, spec, path, resolutionTable, unresolvedRefs, location); |
| 1952 | } |
| 1953 | else { |
| 1954 | operation = path[method]; |
| 1955 | |
| 1956 | var parameters = operation.parameters; |
| 1957 | for (i in parameters) { |
| 1958 | var parameter = parameters[i]; |
| 1959 | location = '/paths' + name + '/' + method + '/parameters'; |
| 1960 | |
| 1961 | if (parameter.in === 'body' && parameter.schema) { |
| 1962 | this.resolveTo(root, parameter.schema, resolutionTable, location); |
| 1963 | } |
| 1964 | |
| 1965 | if (parameter.$ref) { |
| 1966 | // parameter reference |
| 1967 | this.resolveInline(root, spec, parameter, resolutionTable, unresolvedRefs, parameter.$ref); |
| 1968 | } |
| 1969 | } |
| 1970 | |
| 1971 | for (responseCode in operation.responses) { |
| 1972 | var response = operation.responses[responseCode]; |
| 1973 | location = '/paths' + name + '/' + method + '/responses/' + responseCode; |
| 1974 | |
| 1975 | if(typeof response === 'object') { |
| 1976 | if(response.$ref) { |
| 1977 | // response reference |
| 1978 | this.resolveInline(root, spec, response, resolutionTable, unresolvedRefs, location); |
| 1979 | } |
| 1980 | if (response.schema) { |
| 1981 | this.resolveTo(root, response.schema, resolutionTable, location); |
| 1982 | } |
| 1983 | } |
| 1984 | } |
| 1985 | } |
| 1986 | } |
| 1987 | } |
| 1988 | |
| 1989 | var expectedCalls = 0, toResolve = []; |
| 1990 | // if the root is same as obj[i].root we can resolve locally |
| 1991 | var all = resolutionTable; |
| 1992 | |
| 1993 | for(i = 0; i < all.length; i++) { |
| 1994 | var a = all[i]; |
| 1995 | if(root === a.root) { |
| 1996 | if(a.resolveAs === 'ref') { |
| 1997 | // resolve any path walking |
| 1998 | var joined = ((a.root || '') + '/' + a.key).split('/'); |
| 1999 | var normalized = []; |
| 2000 | var url = ''; |
| 2001 | var k; |
| 2002 | |
| 2003 | if(a.key.indexOf('../') >= 0) { |
| 2004 | for(var j = 0; j < joined.length; j++) { |
| 2005 | if(joined[j] === '..') { |
| 2006 | normalized = normalized.slice(0, normalized.length-1); |
| 2007 | } |
| 2008 | else { |
| 2009 | normalized.push(joined[j]); |
| 2010 | } |
| 2011 | } |
| 2012 | for(k = 0; k < normalized.length; k ++) { |
| 2013 | if(k > 0) { |
| 2014 | url += '/'; |
| 2015 | } |
| 2016 | url += normalized[k]; |
| 2017 | } |
| 2018 | // we now have to remote resolve this because the path has changed |
| 2019 | a.root = url; |
| 2020 | toResolve.push(a); |
| 2021 | } |
| 2022 | else { |
| 2023 | var parts = a.key.split('#'); |
| 2024 | if(parts.length === 2) { |
| 2025 | if(parts[0].indexOf('http://') === 0 || parts[0].indexOf('https://') === 0) { |
| 2026 | a.root = parts[0]; |
| 2027 | } |
| 2028 | location = parts[1].split('/'); |
| 2029 | var r; |
| 2030 | var s = spec; |
| 2031 | for(k = 0; k < location.length; k++) { |
| 2032 | var part = location[k]; |
| 2033 | if(part !== '') { |
| 2034 | s = s[part]; |
| 2035 | if(typeof s !== 'undefined') { |
| 2036 | r = s; |
| 2037 | } |
| 2038 | else { |
| 2039 | r = null; |
| 2040 | break; |
| 2041 | } |
| 2042 | } |
| 2043 | } |
| 2044 | if(r === null) { |
| 2045 | // must resolve this too |
| 2046 | toResolve.push(a); |
| 2047 | } |
| 2048 | } |
| 2049 | } |
| 2050 | } |
| 2051 | else { |
| 2052 | if (a.resolveAs === 'inline') { |
| 2053 | toResolve.push(a); |
| 2054 | } |
| 2055 | } |
| 2056 | } |
| 2057 | else { |
| 2058 | toResolve.push(a); |
| 2059 | } |
| 2060 | } |
| 2061 | expectedCalls = toResolve.length; |
| 2062 | |
| 2063 | // resolve anything that is local |
| 2064 | for(var ii = 0; ii < toResolve.length; ii++) { |
| 2065 | (function(item, self) { |
| 2066 | if(item.root === null) { |
| 2067 | // local resolve |
| 2068 | self.resolveItem(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, item); |
| 2069 | processedCalls += 1; |
| 2070 | |
| 2071 | if(processedCalls === expectedCalls) { |
| 2072 | self.finish(spec, root, resolutionTable, resolvedRefs, unresolvedRefs, callback); |
| 2073 | } |
| 2074 | } |
| 2075 | else { |
| 2076 | var obj = { |
| 2077 | useJQuery: false, // TODO |
| 2078 | url: item.root, |
| 2079 | method: 'get', |
| 2080 | headers: { |
| 2081 | accept: self.scope.swaggerRequestHeaders || 'application/json' |
| 2082 | }, |
| 2083 | on: { |
| 2084 | error: function () { |
| 2085 | processedCalls += 1; |
| 2086 | unresolvedRefs[item.key] = null; |
| 2087 | |
| 2088 | if (processedCalls === expectedCalls) { |
| 2089 | self.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback); |
| 2090 | } |
| 2091 | }, // jshint ignore:line |
| 2092 | response: function (response) { |
| 2093 | var swagger = response.obj; |
| 2094 | self.resolveItem(swagger, _root, resolutionTable, resolvedRefs, unresolvedRefs, item); |
| 2095 | processedCalls += 1; |
| 2096 | |
| 2097 | if (processedCalls === expectedCalls) { |
| 2098 | self.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback); |
| 2099 | } |
| 2100 | } |
| 2101 | } // jshint ignore:line |
| 2102 | }; |
| 2103 | |
| 2104 | if (scope && scope.clientAuthorizations) { |
| 2105 | scope.clientAuthorizations.apply(obj); |
| 2106 | } |
| 2107 | new SwaggerHttp().execute(obj); |
| 2108 | } |
| 2109 | }(toResolve[ii], this)); |
| 2110 | } |
| 2111 | |
| 2112 | if (Object.keys(toResolve).length === 0) { |
| 2113 | this.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback); |
| 2114 | } |
| 2115 | }; |
| 2116 | |
| 2117 | Resolver.prototype.resolveItem = function(spec, root, resolutionTable, resolvedRefs, unresolvedRefs, item) { |
| 2118 | var path = item.location; |
| 2119 | var location = spec, parts = path.split('/'); |
| 2120 | for (var j = 0; j < parts.length; j++) { |
| 2121 | var segment = parts[j]; |
| 2122 | if(segment.indexOf('~1') !== -1) { |
| 2123 | segment = parts[j].replace(/~0/g, '~').replace(/~1/g, '/'); |
| 2124 | if(segment.charAt(0) !== '/') { |
| 2125 | segment = '/' + segment; |
| 2126 | } |
| 2127 | } |
| 2128 | if (typeof location === 'undefined' || location === null) { |
| 2129 | break; |
| 2130 | } |
| 2131 | if(segment === '' && j === (parts.length - 1) && parts.length > 1) { |
| 2132 | location = null; |
| 2133 | break; |
| 2134 | } |
| 2135 | if (segment.length > 0) { |
| 2136 | location = location[segment]; |
| 2137 | } |
| 2138 | } |
| 2139 | var resolved = item.key; |
| 2140 | parts = item.key.split('/'); |
| 2141 | var resolvedName = parts[parts.length-1]; |
| 2142 | |
| 2143 | if(resolvedName.indexOf('#') >= 0) { |
| 2144 | resolvedName = resolvedName.split('#')[1]; |
| 2145 | } |
| 2146 | |
| 2147 | if (location !== null && typeof location !== 'undefined') { |
| 2148 | resolvedRefs[resolved] = { |
| 2149 | name: resolvedName, |
| 2150 | obj: location, |
| 2151 | key: item.key, |
| 2152 | root: item.root |
| 2153 | }; |
| 2154 | } else { |
| 2155 | unresolvedRefs[resolved] = { |
| 2156 | root: item.root, |
| 2157 | location: item.location |
| 2158 | }; |
| 2159 | } |
| 2160 | }; |
| 2161 | |
| 2162 | Resolver.prototype.finish = function (spec, root, resolutionTable, resolvedRefs, unresolvedRefs, callback) { |
| 2163 | // walk resolution table and replace with resolved refs |
| 2164 | var ref; |
| 2165 | for (ref in resolutionTable) { |
| 2166 | var item = resolutionTable[ref]; |
| 2167 | |
| 2168 | var key = item.key; |
| 2169 | var resolvedTo = resolvedRefs[key]; |
| 2170 | if (resolvedTo) { |
| 2171 | spec.definitions = spec.definitions || {}; |
| 2172 | if (item.resolveAs === 'ref') { |
| 2173 | spec.definitions[resolvedTo.name] = resolvedTo.obj; |
| 2174 | item.obj.$ref = '#/definitions/' + resolvedTo.name; |
| 2175 | } else if (item.resolveAs === 'inline') { |
| 2176 | var targetObj = item.obj; |
| 2177 | targetObj['x-resolved-from'] = [ item.key ]; |
| 2178 | delete targetObj.$ref; |
| 2179 | |
| 2180 | for (key in resolvedTo.obj) { |
| 2181 | var abs = this.retainRoot(resolvedTo.obj[key], item.root); |
| 2182 | targetObj[key] = abs; |
| 2183 | } |
| 2184 | } |
| 2185 | } |
| 2186 | } |
| 2187 | var existingUnresolved = this.countUnresolvedRefs(spec); |
| 2188 | |
| 2189 | if(existingUnresolved.length === 0 || this.iteration > 5) { |
| 2190 | this.resolveAllOf(spec.definitions); |
| 2191 | callback.call(this.scope, spec, unresolvedRefs); |
| 2192 | } |
| 2193 | else { |
| 2194 | this.iteration += 1; |
| 2195 | this.resolve(spec, root, callback, this.scope); |
| 2196 | } |
| 2197 | }; |
| 2198 | |
| 2199 | Resolver.prototype.countUnresolvedRefs = function(spec) { |
| 2200 | var i; |
| 2201 | var refs = this.getRefs(spec); |
| 2202 | var keys = []; |
| 2203 | var unresolvedKeys = []; |
| 2204 | for(i in refs) { |
| 2205 | if(i.indexOf('#') === 0) { |
| 2206 | keys.push(i.substring(1)); |
| 2207 | } |
| 2208 | else { |
| 2209 | unresolvedKeys.push(i); |
| 2210 | } |
| 2211 | } |
| 2212 | |
| 2213 | // verify possible keys |
| 2214 | for(i in keys) { |
| 2215 | var part = keys[i]; |
| 2216 | var parts = part.split('/'); |
| 2217 | var obj = spec; |
| 2218 | |
| 2219 | for(var k in parts) { |
| 2220 | var key = parts[k]; |
| 2221 | if(key !== '') { |
| 2222 | obj = obj[key]; |
| 2223 | if(typeof obj === 'undefined') { |
| 2224 | unresolvedKeys.push(part); |
| 2225 | break; |
| 2226 | } |
| 2227 | } |
| 2228 | } |
| 2229 | } |
| 2230 | return unresolvedKeys.length; |
| 2231 | }; |
| 2232 | |
| 2233 | Resolver.prototype.getRefs = function(spec, obj) { |
| 2234 | obj = obj || spec; |
| 2235 | var output = {}; |
| 2236 | for(var key in obj) { |
| 2237 | var item = obj[key]; |
| 2238 | if(key === '$ref' && typeof item === 'string') { |
| 2239 | output[item] = null; |
| 2240 | } |
| 2241 | else if(typeof item === 'object') { |
| 2242 | var o = this.getRefs(item); |
| 2243 | for(var k in o) { |
| 2244 | output[k] = null; |
| 2245 | } |
| 2246 | } |
| 2247 | } |
| 2248 | return output; |
| 2249 | }; |
| 2250 | |
| 2251 | Resolver.prototype.retainRoot = function(obj, root) { |
| 2252 | // walk object and look for relative $refs |
| 2253 | for(var key in obj) { |
| 2254 | var item = obj[key]; |
| 2255 | if(key === '$ref' && typeof item === 'string') { |
| 2256 | // stop and inspect |
| 2257 | if(item.indexOf('http://') !== 0 && item.indexOf('https://') !== 0) { |
| 2258 | if(item.indexOf('#') !== 0) { |
| 2259 | item = '#' + item; |
| 2260 | } |
| 2261 | item = (root || '') + item; |
| 2262 | obj[key] = item; |
| 2263 | } |
| 2264 | } |
| 2265 | else if(typeof item === 'object') { |
| 2266 | this.retainRoot(item, root); |
| 2267 | } |
| 2268 | } |
| 2269 | return obj; |
| 2270 | }; |
| 2271 | |
| 2272 | /** |
| 2273 | * immediately in-lines local refs, queues remote refs |
| 2274 | * for inline resolution |
| 2275 | */ |
| 2276 | Resolver.prototype.resolveInline = function (root, spec, property, resolutionTable, unresolvedRefs, location) { |
| 2277 | var key = property.$ref, ref = property.$ref, i, p, p2, rs; |
| 2278 | var rootTrimmed = false; |
| 2279 | if (ref) { |
| 2280 | if(ref.indexOf('../') === 0) { |
| 2281 | // reset root |
| 2282 | p = ref.split('../'); |
| 2283 | p2 = root.split('/'); |
| 2284 | ref = ''; |
| 2285 | for(i = 0; i < p.length; i++) { |
| 2286 | if(p[i] === '') { |
| 2287 | p2 = p2.slice(0, p2.length-1); |
| 2288 | } |
| 2289 | else { |
| 2290 | ref += p[i]; |
| 2291 | } |
| 2292 | } |
| 2293 | root = ''; |
| 2294 | for(i = 0; i < p2.length - 1; i++) { |
| 2295 | if(i > 0) { root += '/'; } |
| 2296 | root += p2[i]; |
| 2297 | } |
| 2298 | rootTrimmed = true; |
| 2299 | } |
| 2300 | if(ref.indexOf('#') >= 0) { |
| 2301 | if(ref.indexOf('/') === 0) { |
| 2302 | rs = ref.split('#'); |
| 2303 | p = root.split('//'); |
| 2304 | p2 = p[1].split('/'); |
| 2305 | root = p[0] + '//' + p2[0] + rs[0]; |
| 2306 | location = rs[1]; |
| 2307 | } |
| 2308 | else { |
| 2309 | rs = ref.split('#'); |
| 2310 | if(rs[0] !== '') { |
| 2311 | p2 = root.split('/'); |
| 2312 | p2 = p2.slice(0, p2.length - 1); |
| 2313 | if(!rootTrimmed) { |
| 2314 | root = ''; |
| 2315 | for (var k = 0; k < p2.length; k++) { |
| 2316 | if(k > 0) { root += '/'; } |
| 2317 | root += p2[k]; |
| 2318 | } |
| 2319 | } |
| 2320 | root += '/' + ref.split('#')[0]; |
| 2321 | } |
| 2322 | location = rs[1]; |
| 2323 | } |
| 2324 | } |
| 2325 | if (ref.indexOf('http') === 0) { |
| 2326 | if(ref.indexOf('#') >= 0) { |
| 2327 | root = ref.split('#')[0]; |
| 2328 | location = ref.split('#')[1]; |
| 2329 | } |
| 2330 | else { |
| 2331 | root = ref; |
| 2332 | location = ''; |
| 2333 | } |
| 2334 | resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location}); |
| 2335 | } else if (ref.indexOf('#') === 0) { |
| 2336 | location = ref.split('#')[1]; |
| 2337 | resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location}); |
| 2338 | } |
| 2339 | else { |
| 2340 | resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location}); |
| 2341 | } |
| 2342 | } else if (property.type === 'array') { |
| 2343 | this.resolveTo(root, property.items, resolutionTable, location); |
| 2344 | } |
| 2345 | }; |
| 2346 | |
| 2347 | Resolver.prototype.resolveTo = function (root, property, resolutionTable, location) { |
| 2348 | var ref = property.$ref; |
| 2349 | |
| 2350 | if (ref) { |
| 2351 | if(ref.indexOf('#') >= 0) { |
| 2352 | location = ref.split('#')[1]; |
| 2353 | } |
| 2354 | resolutionTable.push({ |
| 2355 | obj: property, resolveAs: 'ref', root: root, key: ref, location: location |
| 2356 | }); |
| 2357 | } else if (property.type === 'array') { |
| 2358 | var items = property.items; |
| 2359 | this.resolveTo(root, items, resolutionTable, location); |
| 2360 | } |
| 2361 | }; |
| 2362 | |
| 2363 | Resolver.prototype.resolveAllOf = function(spec, obj, depth) { |
| 2364 | depth = depth || 0; |
| 2365 | obj = obj || spec; |
| 2366 | var name; |
| 2367 | for(var key in obj) { |
| 2368 | var item = obj[key]; |
| 2369 | if(item && typeof item.allOf !== 'undefined') { |
| 2370 | var allOf = item.allOf; |
| 2371 | if(Array.isArray(allOf)) { |
| 2372 | var output = {}; |
| 2373 | output['x-composed'] = true; |
| 2374 | for(var i = 0; i < allOf.length; i++) { |
| 2375 | var component = allOf[i]; |
| 2376 | var source = 'self'; |
| 2377 | if(typeof component['x-resolved-from'] !== 'undefined') { |
| 2378 | source = component['x-resolved-from'][0]; |
| 2379 | } |
| 2380 | |
| 2381 | for(var part in component) { |
| 2382 | if(!output.hasOwnProperty(part)) { |
| 2383 | output[part] = component[part]; |
| 2384 | if(part === 'properties') { |
| 2385 | for(name in output[part]) { |
| 2386 | output[part][name]['x-resolved-from'] = source; |
| 2387 | } |
| 2388 | } |
| 2389 | } |
| 2390 | else { |
| 2391 | if(part === 'properties') { |
| 2392 | var properties = component[part]; |
| 2393 | for(name in properties) { |
| 2394 | output.properties[name] = properties[name]; |
| 2395 | output.properties[name]['x-resolved-from'] = source; |
| 2396 | } |
| 2397 | } |
| 2398 | else if(part === 'required') { |
| 2399 | // merge & dedup the required array |
| 2400 | var a = output.required.concat(component[part]); |
| 2401 | for(var k = 0; k < a.length; ++k) { |
| 2402 | for(var j = k + 1; j < a.length; ++j) { |
| 2403 | if(a[k] === a[j]) { a.splice(j--, 1); } |
| 2404 | } |
| 2405 | } |
| 2406 | output.required = a; |
| 2407 | } |
| 2408 | else if(part === 'x-resolved-from') { |
| 2409 | output['x-resolved-from'].push(source); |
| 2410 | } |
| 2411 | else { |
| 2412 | // TODO: need to merge this property |
| 2413 | // console.log('what to do with ' + part) |
| 2414 | } |
| 2415 | } |
| 2416 | } |
| 2417 | } |
| 2418 | obj[key] = output; |
| 2419 | } |
| 2420 | } |
| 2421 | if(typeof item === 'object') { |
| 2422 | this.resolveAllOf(spec, item, depth + 1); |
| 2423 | } |
| 2424 | } |
| 2425 | }; |
| 2426 | |
| 2427 | },{"./http":5}],7:[function(require,module,exports){ |
| 2428 | 'use strict'; |
| 2429 | |
| 2430 | var SwaggerHttp = require('./http'); |
| 2431 | |
| 2432 | var SwaggerSpecConverter = module.exports = function () { |
| 2433 | this.errors = []; |
| 2434 | this.warnings = []; |
| 2435 | this.modelMap = {}; |
| 2436 | }; |
| 2437 | |
| 2438 | SwaggerSpecConverter.prototype.setDocumentationLocation = function (location) { |
| 2439 | this.docLocation = location; |
| 2440 | }; |
| 2441 | |
| 2442 | /** |
| 2443 | * converts a resource listing OR api declaration |
| 2444 | **/ |
| 2445 | SwaggerSpecConverter.prototype.convert = function (obj, clientAuthorizations, callback) { |
| 2446 | // not a valid spec |
| 2447 | if(!obj || !Array.isArray(obj.apis)) { |
| 2448 | return this.finish(callback, null); |
| 2449 | } |
| 2450 | this.clientAuthorizations = clientAuthorizations; |
| 2451 | |
| 2452 | // create a new swagger object to return |
| 2453 | var swagger = { swagger: '2.0' }; |
| 2454 | |
| 2455 | swagger.originalVersion = obj.swaggerVersion; |
| 2456 | |
| 2457 | // add the info |
| 2458 | this.apiInfo(obj, swagger); |
| 2459 | |
| 2460 | // add security definitions |
| 2461 | this.securityDefinitions(obj, swagger); |
| 2462 | |
| 2463 | // take basePath into account |
| 2464 | if (obj.basePath) { |
| 2465 | this.setDocumentationLocation(obj.basePath); |
| 2466 | } |
| 2467 | |
| 2468 | // take basePath into account |
| 2469 | if (obj.basePath) { |
| 2470 | this.setDocumentationLocation(obj.basePath); |
| 2471 | } |
| 2472 | |
| 2473 | // see if this is a single-file swagger definition |
| 2474 | var isSingleFileSwagger = false; |
| 2475 | var i; |
| 2476 | for(i = 0; i < obj.apis.length; i++) { |
| 2477 | var api = obj.apis[i]; |
| 2478 | if(Array.isArray(api.operations)) { |
| 2479 | isSingleFileSwagger = true; |
| 2480 | } |
| 2481 | } |
| 2482 | if(isSingleFileSwagger) { |
| 2483 | this.declaration(obj, swagger); |
| 2484 | this.finish(callback, swagger); |
| 2485 | } |
| 2486 | else { |
| 2487 | this.resourceListing(obj, swagger, callback); |
| 2488 | } |
| 2489 | }; |
| 2490 | |
| 2491 | SwaggerSpecConverter.prototype.declaration = function(obj, swagger) { |
| 2492 | var name, i, p, pos; |
| 2493 | if(!obj.apis) { |
| 2494 | return; |
| 2495 | } |
| 2496 | |
| 2497 | if (obj.basePath.indexOf('http://') === 0) { |
| 2498 | p = obj.basePath.substring('http://'.length); |
| 2499 | pos = p.indexOf('/'); |
| 2500 | if (pos > 0) { |
| 2501 | swagger.host = p.substring(0, pos); |
| 2502 | swagger.basePath = p.substring(pos); |
| 2503 | } |
| 2504 | else { |
| 2505 | swagger.host = p; |
| 2506 | swagger.basePath = '/'; |
| 2507 | } |
| 2508 | } else if (obj.basePath.indexOf('https://') === 0) { |
| 2509 | p = obj.basePath.substring('https://'.length); |
| 2510 | pos = p.indexOf('/'); |
| 2511 | if (pos > 0) { |
| 2512 | swagger.host = p.substring(0, pos); |
| 2513 | swagger.basePath = p.substring(pos); |
| 2514 | } |
| 2515 | else { |
| 2516 | swagger.host = p; |
| 2517 | swagger.basePath = '/'; |
| 2518 | } |
| 2519 | } else { |
| 2520 | swagger.basePath = obj.basePath; |
| 2521 | } |
| 2522 | |
| 2523 | var resourceLevelAuth; |
| 2524 | if(obj.authorizations) { |
| 2525 | resourceLevelAuth = obj.authorizations; |
| 2526 | } |
| 2527 | if(obj.consumes) { |
| 2528 | swagger.consumes = obj.consumes; |
| 2529 | } |
| 2530 | if(obj.produces) { |
| 2531 | swagger.produces = obj.produces; |
| 2532 | } |
| 2533 | |
| 2534 | // build a mapping of id to name for 1.0 model resolutions |
| 2535 | if(typeof obj === 'object') { |
| 2536 | for(name in obj.models) { |
| 2537 | var existingModel = obj.models[name]; |
| 2538 | var key = (existingModel.id || name); |
| 2539 | this.modelMap[key] = name; |
| 2540 | } |
| 2541 | } |
| 2542 | |
| 2543 | for(i = 0; i < obj.apis.length; i++) { |
| 2544 | var api = obj.apis[i]; |
| 2545 | var path = api.path; |
| 2546 | var operations = api.operations; |
| 2547 | this.operations(path, obj.resourcePath, operations, resourceLevelAuth, swagger); |
| 2548 | } |
| 2549 | |
| 2550 | var models = obj.models || {}; |
| 2551 | this.models(models, swagger); |
| 2552 | }; |
| 2553 | |
| 2554 | SwaggerSpecConverter.prototype.models = function(obj, swagger) { |
| 2555 | if(typeof obj !== 'object') { |
| 2556 | return; |
| 2557 | } |
| 2558 | var name; |
| 2559 | |
| 2560 | swagger.definitions = swagger.definitions || {}; |
| 2561 | for(name in obj) { |
| 2562 | var existingModel = obj[name]; |
| 2563 | var _enum = []; |
| 2564 | var schema = { properties: {}}; |
| 2565 | var propertyName; |
| 2566 | for(propertyName in existingModel.properties) { |
| 2567 | var existingProperty = existingModel.properties[propertyName]; |
| 2568 | var property = {}; |
| 2569 | this.dataType(existingProperty, property); |
| 2570 | if(existingProperty.description) { |
| 2571 | property.description = existingProperty.description; |
| 2572 | } |
| 2573 | if(existingProperty['enum']) { |
| 2574 | property['enum'] = existingProperty['enum']; |
| 2575 | } |
| 2576 | if(typeof existingProperty.required === 'boolean' && existingProperty.required === true) { |
| 2577 | _enum.push(propertyName); |
| 2578 | } |
| 2579 | if(typeof existingProperty.required === 'string' && existingProperty.required === 'true') { |
| 2580 | _enum.push(propertyName); |
| 2581 | } |
| 2582 | schema.properties[propertyName] = property; |
| 2583 | } |
| 2584 | if(_enum.length > 0) { |
| 2585 | schema['enum'] = _enum; |
| 2586 | } |
| 2587 | |
| 2588 | schema.required = existingModel.required; |
| 2589 | swagger.definitions[name] = schema; |
| 2590 | } |
| 2591 | }; |
| 2592 | |
| 2593 | SwaggerSpecConverter.prototype.extractTag = function(resourcePath) { |
| 2594 | var pathString = resourcePath || 'default'; |
| 2595 | if(pathString.indexOf('http:') === 0 || pathString.indexOf('https:') === 0) { |
| 2596 | pathString = pathString.split(['/']); |
| 2597 | pathString = pathString[pathString.length -1].substring(); |
| 2598 | } |
| 2599 | if(pathString.endsWith('.json')) { |
| 2600 | pathString = pathString.substring(0, pathString.length - '.json'.length); |
| 2601 | } |
| 2602 | return pathString.replace('/',''); |
| 2603 | }; |
| 2604 | |
| 2605 | SwaggerSpecConverter.prototype.operations = function(path, resourcePath, obj, resourceLevelAuth, swagger) { |
| 2606 | if(!Array.isArray(obj)) { |
| 2607 | return; |
| 2608 | } |
| 2609 | var i; |
| 2610 | |
| 2611 | if(!swagger.paths) { |
| 2612 | swagger.paths = {}; |
| 2613 | } |
| 2614 | |
| 2615 | var pathObj = swagger.paths[path] || {}; |
| 2616 | var tag = this.extractTag(resourcePath); |
| 2617 | swagger.tags = swagger.tags || []; |
| 2618 | var matched = false; |
| 2619 | for(i = 0; i < swagger.tags.length; i++) { |
| 2620 | var tagObject = swagger.tags[i]; |
| 2621 | if(tagObject.name === tag) { |
| 2622 | matched = true; |
| 2623 | } |
| 2624 | } |
| 2625 | if(!matched) { |
| 2626 | swagger.tags.push({name: tag}); |
| 2627 | } |
| 2628 | |
| 2629 | for(i = 0; i < obj.length; i++) { |
| 2630 | var existingOperation = obj[i]; |
| 2631 | var method = (existingOperation.method || existingOperation.httpMethod).toLowerCase(); |
| 2632 | var operation = {tags: [tag]}; |
| 2633 | var existingAuthorizations = existingOperation.authorizations; |
| 2634 | |
| 2635 | if(existingAuthorizations && Object.keys(existingAuthorizations).length === 0) { |
| 2636 | existingAuthorizations = resourceLevelAuth; |
| 2637 | } |
| 2638 | |
| 2639 | if(typeof existingAuthorizations !== 'undefined') { |
| 2640 | var scopesObject; |
| 2641 | for(var key in existingAuthorizations) { |
| 2642 | operation.security = operation.security || []; |
| 2643 | var scopes = existingAuthorizations[key]; |
| 2644 | if(scopes) { |
| 2645 | var securityScopes = []; |
| 2646 | for(var j in scopes) { |
| 2647 | securityScopes.push(scopes[j].scope); |
| 2648 | } |
| 2649 | scopesObject = {}; |
| 2650 | scopesObject[key] = securityScopes; |
| 2651 | operation.security.push(scopesObject); |
| 2652 | } |
| 2653 | else { |
| 2654 | scopesObject = {}; |
| 2655 | scopesObject[key] = []; |
| 2656 | operation.security.push(scopesObject); |
| 2657 | } |
| 2658 | } |
| 2659 | } |
| 2660 | |
| 2661 | if(existingOperation.consumes) { |
| 2662 | operation.consumes = existingOperation.consumes; |
| 2663 | } |
| 2664 | else if(swagger.consumes) { |
| 2665 | operation.consumes = swagger.consumes; |
| 2666 | } |
| 2667 | if(existingOperation.produces) { |
| 2668 | operation.produces = existingOperation.produces; |
| 2669 | } |
| 2670 | else if(swagger.produces) { |
| 2671 | operation.produces = swagger.produces; |
| 2672 | } |
| 2673 | if(existingOperation.summary) { |
| 2674 | operation.summary = existingOperation.summary; |
| 2675 | } |
| 2676 | if(existingOperation.notes) { |
| 2677 | operation.description = existingOperation.notes; |
| 2678 | } |
| 2679 | if(existingOperation.nickname) { |
| 2680 | operation.operationId = existingOperation.nickname; |
| 2681 | } |
| 2682 | if(existingOperation.deprecated) { |
| 2683 | operation.deprecated = existingOperation.deprecated; |
| 2684 | } |
| 2685 | |
| 2686 | this.authorizations(existingAuthorizations, swagger); |
| 2687 | this.parameters(operation, existingOperation.parameters, swagger); |
| 2688 | this.responseMessages(operation, existingOperation, swagger); |
| 2689 | |
| 2690 | pathObj[method] = operation; |
| 2691 | } |
| 2692 | |
| 2693 | swagger.paths[path] = pathObj; |
| 2694 | }; |
| 2695 | |
| 2696 | SwaggerSpecConverter.prototype.responseMessages = function(operation, existingOperation) { |
| 2697 | if(typeof existingOperation !== 'object') { |
| 2698 | return; |
| 2699 | } |
| 2700 | // build default response from the operation (1.x) |
| 2701 | var defaultResponse = {}; |
| 2702 | this.dataType(existingOperation, defaultResponse); |
| 2703 | // TODO: look into the real problem of rendering responses in swagger-ui |
| 2704 | // ....should reponseType have an implicit schema? |
| 2705 | if(!defaultResponse.schema && defaultResponse.type) { |
| 2706 | defaultResponse = {schema: defaultResponse}; |
| 2707 | } |
| 2708 | |
| 2709 | operation.responses = operation.responses || {}; |
| 2710 | |
| 2711 | // grab from responseMessages (1.2) |
| 2712 | var has200 = false; |
| 2713 | if(Array.isArray(existingOperation.responseMessages)) { |
| 2714 | var i; |
| 2715 | var existingResponses = existingOperation.responseMessages; |
| 2716 | for(i = 0; i < existingResponses.length; i++) { |
| 2717 | var existingResponse = existingResponses[i]; |
| 2718 | var response = { description: existingResponse.message }; |
| 2719 | if(existingResponse.code === 200) { |
| 2720 | has200 = true; |
| 2721 | } |
| 2722 | // Convert responseModel -> schema{$ref: responseModel} |
| 2723 | if(existingResponse.responseModel) { |
| 2724 | response.schema = {'$ref': existingResponse.responseModel}; |
| 2725 | } |
| 2726 | operation.responses['' + existingResponse.code] = response; |
| 2727 | } |
| 2728 | } |
| 2729 | |
| 2730 | if(has200) { |
| 2731 | operation.responses['default'] = defaultResponse; |
| 2732 | } |
| 2733 | else { |
| 2734 | operation.responses['200'] = defaultResponse; |
| 2735 | } |
| 2736 | }; |
| 2737 | |
| 2738 | SwaggerSpecConverter.prototype.authorizations = function(obj) { |
| 2739 | // TODO |
| 2740 | if(typeof obj !== 'object') { |
| 2741 | return; |
| 2742 | } |
| 2743 | }; |
| 2744 | |
| 2745 | SwaggerSpecConverter.prototype.parameters = function(operation, obj) { |
| 2746 | if(!Array.isArray(obj)) { |
| 2747 | return; |
| 2748 | } |
| 2749 | var i; |
| 2750 | for(i = 0; i < obj.length; i++) { |
| 2751 | var existingParameter = obj[i]; |
| 2752 | var parameter = {}; |
| 2753 | parameter.name = existingParameter.name; |
| 2754 | parameter.description = existingParameter.description; |
| 2755 | parameter.required = existingParameter.required; |
| 2756 | parameter.in = existingParameter.paramType; |
| 2757 | |
| 2758 | // per #168 |
| 2759 | if(parameter.in === 'body') { |
| 2760 | parameter.name = 'body'; |
| 2761 | } |
| 2762 | if(parameter.in === 'form') { |
| 2763 | parameter.in = 'formData'; |
| 2764 | } |
| 2765 | |
| 2766 | if(existingParameter.enum) { |
| 2767 | parameter.enum = existingParameter.enum; |
| 2768 | } |
| 2769 | |
| 2770 | if(existingParameter.allowMultiple === true || existingParameter.allowMultiple === 'true') { |
| 2771 | var innerType = {}; |
| 2772 | this.dataType(existingParameter, innerType); |
| 2773 | parameter.type = 'array'; |
| 2774 | parameter.items = innerType; |
| 2775 | |
| 2776 | if(existingParameter.allowableValues) { |
| 2777 | var av = existingParameter.allowableValues; |
| 2778 | if(av.valueType === 'LIST') { |
| 2779 | parameter['enum'] = av.values; |
| 2780 | } |
| 2781 | } |
| 2782 | } |
| 2783 | else { |
| 2784 | this.dataType(existingParameter, parameter); |
| 2785 | } |
| 2786 | |
| 2787 | operation.parameters = operation.parameters || []; |
| 2788 | operation.parameters.push(parameter); |
| 2789 | } |
| 2790 | }; |
| 2791 | |
| 2792 | SwaggerSpecConverter.prototype.dataType = function(source, target) { |
| 2793 | if(typeof source !== 'object') { |
| 2794 | return; |
| 2795 | } |
| 2796 | |
| 2797 | if(source.minimum) { |
| 2798 | target.minimum = source.minimum; |
| 2799 | } |
| 2800 | if(source.maximum) { |
| 2801 | target.maximum = source.maximum; |
| 2802 | } |
| 2803 | |
| 2804 | // default can be 'false' |
| 2805 | if(typeof source.defaultValue !== 'undefined') { |
| 2806 | target.default = source.defaultValue; |
| 2807 | } |
| 2808 | |
| 2809 | var jsonSchemaType = this.toJsonSchema(source); |
| 2810 | if(jsonSchemaType) { |
| 2811 | target = target || {}; |
| 2812 | if(jsonSchemaType.type) { |
| 2813 | target.type = jsonSchemaType.type; |
| 2814 | } |
| 2815 | if(jsonSchemaType.format) { |
| 2816 | target.format = jsonSchemaType.format; |
| 2817 | } |
| 2818 | if(jsonSchemaType.$ref) { |
| 2819 | target.schema = {$ref: jsonSchemaType.$ref}; |
| 2820 | } |
| 2821 | if(jsonSchemaType.items) { |
| 2822 | target.items = jsonSchemaType.items; |
| 2823 | } |
| 2824 | } |
| 2825 | }; |
| 2826 | |
| 2827 | SwaggerSpecConverter.prototype.toJsonSchema = function(source) { |
| 2828 | if(!source) { |
| 2829 | return 'object'; |
| 2830 | } |
| 2831 | var detectedType = (source.type || source.dataType || source.responseClass || ''); |
| 2832 | var lcType = detectedType.toLowerCase(); |
| 2833 | var format = (source.format || '').toLowerCase(); |
| 2834 | |
| 2835 | if(lcType.indexOf('list[') === 0) { |
| 2836 | var innerType = detectedType.substring(5, detectedType.length - 1); |
| 2837 | var jsonType = this.toJsonSchema({type: innerType}); |
| 2838 | return {type: 'array', items: jsonType}; |
| 2839 | } |
| 2840 | else if(lcType === 'int' || (lcType === 'integer' && format === 'int32')) |
| 2841 | {return {type: 'integer', format: 'int32'};} |
| 2842 | else if(lcType === 'long' || (lcType === 'integer' && format === 'int64')) |
| 2843 | {return {type: 'integer', format: 'int64'};} |
| 2844 | else if(lcType === 'integer') |
| 2845 | {return {type: 'integer', format: 'int64'};} |
| 2846 | else if(lcType === 'float' || (lcType === 'number' && format === 'float')) |
| 2847 | {return {type: 'number', format: 'float'};} |
| 2848 | else if(lcType === 'double' || (lcType === 'number' && format === 'double')) |
| 2849 | {return {type: 'number', format: 'double'};} |
| 2850 | else if((lcType === 'string' && format === 'date-time') || (lcType === 'date')) |
| 2851 | {return {type: 'string', format: 'date-time'};} |
| 2852 | else if(lcType === 'string') |
| 2853 | {return {type: 'string'};} |
| 2854 | else if(lcType === 'file') |
| 2855 | {return {type: 'file'};} |
| 2856 | else if(lcType === 'boolean') |
| 2857 | {return {type: 'boolean'};} |
| 2858 | else if(lcType === 'array' || lcType === 'list') { |
| 2859 | if(source.items) { |
| 2860 | var it = this.toJsonSchema(source.items); |
| 2861 | return {type: 'array', items: it}; |
| 2862 | } |
| 2863 | else { |
| 2864 | return {type: 'array', items: {type: 'object'}}; |
| 2865 | } |
| 2866 | } |
| 2867 | else if(source.$ref) { |
| 2868 | return {$ref: '#/definitions/' + this.modelMap[source.$ref] || source.$ref}; |
| 2869 | } |
| 2870 | else if(lcType === 'void' || lcType === '') |
| 2871 | {return {};} |
| 2872 | else { |
| 2873 | return {$ref: '#/definitions/' + this.modelMap[source.type] || source.type}; |
| 2874 | } |
| 2875 | }; |
| 2876 | |
| 2877 | SwaggerSpecConverter.prototype.resourceListing = function(obj, swagger, callback) { |
| 2878 | var i; |
| 2879 | var processedCount = 0; // jshint ignore:line |
| 2880 | var self = this; // jshint ignore:line |
| 2881 | var expectedCount = obj.apis.length; |
| 2882 | var _swagger = swagger; // jshint ignore:line |
| 2883 | |
| 2884 | if(expectedCount === 0) { |
| 2885 | this.finish(callback, swagger); |
| 2886 | } |
| 2887 | |
| 2888 | for(i = 0; i < expectedCount; i++) { |
| 2889 | var api = obj.apis[i]; |
| 2890 | var path = api.path; |
| 2891 | var absolutePath = this.getAbsolutePath(obj.swaggerVersion, this.docLocation, path); |
| 2892 | |
| 2893 | if(api.description) { |
| 2894 | swagger.tags = swagger.tags || []; |
| 2895 | swagger.tags.push({ |
| 2896 | name : this.extractTag(api.path), |
| 2897 | description : api.description || '' |
| 2898 | }); |
| 2899 | } |
| 2900 | var http = { |
| 2901 | url: absolutePath, |
| 2902 | headers: {accept: 'application/json'}, |
| 2903 | on: {}, |
| 2904 | method: 'get' |
| 2905 | }; |
| 2906 | /* jshint ignore:start */ |
| 2907 | http.on.response = function(data) { |
| 2908 | processedCount += 1; |
| 2909 | var obj = data.obj; |
| 2910 | if(obj) { |
| 2911 | self.declaration(obj, _swagger); |
| 2912 | } |
| 2913 | if(processedCount === expectedCount) { |
| 2914 | self.finish(callback, _swagger); |
| 2915 | } |
| 2916 | }; |
| 2917 | http.on.error = function(data) { |
| 2918 | console.error(data); |
| 2919 | processedCount += 1; |
| 2920 | if(processedCount === expectedCount) { |
| 2921 | self.finish(callback, _swagger); |
| 2922 | } |
| 2923 | }; |
| 2924 | /* jshint ignore:end */ |
| 2925 | |
| 2926 | if(this.clientAuthorizations && typeof this.clientAuthorizations.apply === 'function') { |
| 2927 | this.clientAuthorizations.apply(http); |
| 2928 | } |
| 2929 | |
| 2930 | new SwaggerHttp().execute(http); |
| 2931 | } |
| 2932 | }; |
| 2933 | |
| 2934 | SwaggerSpecConverter.prototype.getAbsolutePath = function(version, docLocation, path) { |
| 2935 | if(version === '1.0') { |
| 2936 | if(docLocation.endsWith('.json')) { |
| 2937 | // get root path |
| 2938 | var pos = docLocation.lastIndexOf('/'); |
| 2939 | if(pos > 0) { |
| 2940 | docLocation = docLocation.substring(0, pos); |
| 2941 | } |
| 2942 | } |
| 2943 | } |
| 2944 | |
| 2945 | var location = docLocation; |
| 2946 | if(path.indexOf('http://') === 0 || path.indexOf('https://') === 0) { |
| 2947 | location = path; |
| 2948 | } |
| 2949 | else { |
| 2950 | if(docLocation.endsWith('/')) { |
| 2951 | location = docLocation.substring(0, docLocation.length - 1); |
| 2952 | } |
| 2953 | location += path; |
| 2954 | } |
| 2955 | location = location.replace('{format}', 'json'); |
| 2956 | return location; |
| 2957 | }; |
| 2958 | |
| 2959 | SwaggerSpecConverter.prototype.securityDefinitions = function(obj, swagger) { |
| 2960 | if(obj.authorizations) { |
| 2961 | var name; |
| 2962 | for(name in obj.authorizations) { |
| 2963 | var isValid = false; |
| 2964 | var securityDefinition = {}; |
| 2965 | var definition = obj.authorizations[name]; |
| 2966 | if(definition.type === 'apiKey') { |
| 2967 | securityDefinition.type = 'apiKey'; |
| 2968 | securityDefinition.in = definition.passAs; |
| 2969 | securityDefinition.name = definition.keyname || name; |
| 2970 | isValid = true; |
| 2971 | } |
| 2972 | else if(definition.type === 'oauth2') { |
| 2973 | var existingScopes = definition.scopes || []; |
| 2974 | var scopes = {}; |
| 2975 | var i; |
| 2976 | for(i in existingScopes) { |
| 2977 | var scope = existingScopes[i]; |
| 2978 | scopes[scope.scope] = scope.description; |
| 2979 | } |
| 2980 | securityDefinition.type = 'oauth2'; |
| 2981 | if(i > 0) { |
| 2982 | securityDefinition.scopes = scopes; |
| 2983 | } |
| 2984 | if(definition.grantTypes) { |
| 2985 | if(definition.grantTypes.implicit) { |
| 2986 | var implicit = definition.grantTypes.implicit; |
| 2987 | securityDefinition.flow = 'implicit'; |
| 2988 | securityDefinition.authorizationUrl = implicit.loginEndpoint; |
| 2989 | isValid = true; |
| 2990 | } |
| 2991 | /* jshint ignore:start */ |
| 2992 | if(definition.grantTypes['authorization_code']) { |
| 2993 | if(!securityDefinition.flow) { |
| 2994 | // cannot set if flow is already defined |
| 2995 | var authCode = definition.grantTypes['authorization_code']; |
| 2996 | securityDefinition.flow = 'accessCode'; |
| 2997 | securityDefinition.authorizationUrl = authCode.tokenRequestEndpoint.url; |
| 2998 | securityDefinition.tokenUrl = authCode.tokenEndpoint.url; |
| 2999 | isValid = true; |
| 3000 | } |
| 3001 | } |
| 3002 | /* jshint ignore:end */ |
| 3003 | } |
| 3004 | } |
| 3005 | if(isValid) { |
| 3006 | swagger.securityDefinitions = swagger.securityDefinitions || {}; |
| 3007 | swagger.securityDefinitions[name] = securityDefinition; |
| 3008 | } |
| 3009 | } |
| 3010 | } |
| 3011 | }; |
| 3012 | |
| 3013 | SwaggerSpecConverter.prototype.apiInfo = function(obj, swagger) { |
| 3014 | // info section |
| 3015 | if(obj.info) { |
| 3016 | var info = obj.info; |
| 3017 | swagger.info = {}; |
| 3018 | |
| 3019 | if(info.contact) { |
| 3020 | swagger.info.contact = {}; |
| 3021 | swagger.info.contact.email = info.contact; |
| 3022 | } |
| 3023 | if(info.description) { |
| 3024 | swagger.info.description = info.description; |
| 3025 | } |
| 3026 | if(info.title) { |
| 3027 | swagger.info.title = info.title; |
| 3028 | } |
| 3029 | if(info.termsOfServiceUrl) { |
| 3030 | swagger.info.termsOfService = info.termsOfServiceUrl; |
| 3031 | } |
| 3032 | if(info.license || info.licenseUrl) { |
| 3033 | swagger.license = {}; |
| 3034 | if(info.license) { |
| 3035 | swagger.license.name = info.license; |
| 3036 | } |
| 3037 | if(info.licenseUrl) { |
| 3038 | swagger.license.url = info.licenseUrl; |
| 3039 | } |
| 3040 | } |
| 3041 | } |
| 3042 | else { |
| 3043 | this.warnings.push('missing info section'); |
| 3044 | } |
| 3045 | }; |
| 3046 | |
| 3047 | SwaggerSpecConverter.prototype.finish = function (callback, obj) { |
| 3048 | callback(obj); |
| 3049 | }; |
| 3050 | |
| 3051 | },{"./http":5}],8:[function(require,module,exports){ |
| 3052 | 'use strict'; |
| 3053 | |
| 3054 | var _ = { |
| 3055 | cloneDeep: require('lodash-compat/lang/cloneDeep'), |
| 3056 | forEach: require('lodash-compat/collection/forEach'), |
| 3057 | indexOf: require('lodash-compat/array/indexOf'), |
| 3058 | isArray: require('lodash-compat/lang/isArray'), |
| 3059 | isPlainObject: require('lodash-compat/lang/isPlainObject'), |
| 3060 | isString: require('lodash-compat/lang/isString'), |
| 3061 | isUndefined: require('lodash-compat/lang/isUndefined'), |
| 3062 | keys: require('lodash-compat/object/keys'), |
| 3063 | map: require('lodash-compat/collection/map') |
| 3064 | }; |
| 3065 | var helpers = require('../helpers'); |
| 3066 | var jsyaml = require('js-yaml'); |
| 3067 | |
| 3068 | var Model = module.exports = function (name, definition, models, modelPropertyMacro) { |
| 3069 | this.definition = definition || {}; |
| 3070 | this.isArray = definition.type === 'array'; |
| 3071 | this.models = models || {}; |
| 3072 | this.name = definition.title || name || 'Inline Model'; |
| 3073 | this.modelPropertyMacro = modelPropertyMacro || function (property) { |
| 3074 | return property.default; |
| 3075 | }; |
| 3076 | |
| 3077 | return this; |
| 3078 | }; |
| 3079 | |
| 3080 | var schemaToHTML = function (name, schema, models, modelPropertyMacro) { |
| 3081 | var strongOpen = '<span class="strong">'; |
| 3082 | var strongClose = '</span>'; |
| 3083 | var references = {}; |
| 3084 | var seenModels = []; |
| 3085 | var inlineModels = 0; |
| 3086 | var addReference = function (schema, name, skipRef) { |
| 3087 | var modelName = name; |
| 3088 | var model; |
| 3089 | |
| 3090 | if (schema.$ref) { |
| 3091 | modelName = schema.title || helpers.simpleRef(schema.$ref); |
| 3092 | model = models[modelName]; |
| 3093 | } else if (_.isUndefined(name)) { |
| 3094 | modelName = schema.title || 'Inline Model ' + (++inlineModels); |
| 3095 | model = new Model(modelName, schema, models, modelPropertyMacro); |
| 3096 | } |
| 3097 | |
| 3098 | if (skipRef !== true) { |
| 3099 | references[modelName] = _.isUndefined(model) ? {} : model.definition; |
| 3100 | } |
| 3101 | |
| 3102 | return modelName; |
| 3103 | }; |
| 3104 | |
| 3105 | var primitiveToHTML = function (schema) { |
| 3106 | var html = '<span class="propType">'; |
| 3107 | var type = schema.type || 'object'; |
| 3108 | |
| 3109 | if (schema.$ref) { |
| 3110 | html += addReference(schema, helpers.simpleRef(schema.$ref)); |
| 3111 | } else if (type === 'object') { |
| 3112 | if (!_.isUndefined(schema.properties)) { |
| 3113 | html += addReference(schema); |
| 3114 | } else { |
| 3115 | html += 'object'; |
| 3116 | } |
| 3117 | } else if (type === 'array') { |
| 3118 | html += 'Array['; |
| 3119 | |
| 3120 | if (_.isArray(schema.items)) { |
| 3121 | html += _.map(schema.items, addReference).join(','); |
| 3122 | } else if (_.isPlainObject(schema.items)) { |
| 3123 | if (_.isUndefined(schema.items.$ref)) { |
| 3124 | if (!_.isUndefined(schema.items.type) && _.indexOf(['array', 'object'], schema.items.type) === -1) { |
| 3125 | html += schema.items.type; |
| 3126 | } else { |
| 3127 | html += addReference(schema.items); |
| 3128 | } |
| 3129 | } else { |
| 3130 | html += addReference(schema.items, helpers.simpleRef(schema.items.$ref)); |
| 3131 | } |
| 3132 | } else { |
| 3133 | helpers.log('Array type\'s \'items\' schema is not an array or an object, cannot process'); |
| 3134 | html += 'object'; |
| 3135 | } |
| 3136 | |
| 3137 | html += ']'; |
| 3138 | } else { |
| 3139 | html += schema.type; |
| 3140 | } |
| 3141 | |
| 3142 | html += '</span>'; |
| 3143 | |
| 3144 | return html; |
| 3145 | }; |
| 3146 | var primitiveToOptionsHTML = function (schema, html) { |
| 3147 | var options = ''; |
| 3148 | var type = schema.type || 'object'; |
| 3149 | var isArray = type === 'array'; |
| 3150 | |
| 3151 | if (isArray) { |
| 3152 | if (_.isPlainObject(schema.items) && !_.isUndefined(schema.items.type)) { |
| 3153 | type = schema.items.type; |
| 3154 | } else { |
| 3155 | type = 'object'; |
| 3156 | } |
| 3157 | } |
| 3158 | |
| 3159 | if (!_.isUndefined(schema.default)) { |
| 3160 | options += helpers.optionHtml('Default', schema.default); |
| 3161 | } |
| 3162 | |
| 3163 | switch (type) { |
| 3164 | case 'string': |
| 3165 | if (schema.minLength) { |
| 3166 | options += helpers.optionHtml('Min. Length', schema.minLength); |
| 3167 | } |
| 3168 | |
| 3169 | if (schema.maxLength) { |
| 3170 | options += helpers.optionHtml('Max. Length', schema.maxLength); |
| 3171 | } |
| 3172 | |
| 3173 | if (schema.pattern) { |
| 3174 | options += helpers.optionHtml('Reg. Exp.', schema.pattern); |
| 3175 | } |
| 3176 | break; |
| 3177 | case 'integer': |
| 3178 | case 'number': |
| 3179 | if (schema.minimum) { |
| 3180 | options += helpers.optionHtml('Min. Value', schema.minimum); |
| 3181 | } |
| 3182 | |
| 3183 | if (schema.exclusiveMinimum) { |
| 3184 | options += helpers.optionHtml('Exclusive Min.', 'true'); |
| 3185 | } |
| 3186 | |
| 3187 | if (schema.maximum) { |
| 3188 | options += helpers.optionHtml('Max. Value', schema.maximum); |
| 3189 | } |
| 3190 | |
| 3191 | if (schema.exclusiveMaximum) { |
| 3192 | options += helpers.optionHtml('Exclusive Max.', 'true'); |
| 3193 | } |
| 3194 | |
| 3195 | if (schema.multipleOf) { |
| 3196 | options += helpers.optionHtml('Multiple Of', schema.multipleOf); |
| 3197 | } |
| 3198 | |
| 3199 | break; |
| 3200 | } |
| 3201 | |
| 3202 | if (isArray) { |
| 3203 | if (schema.minItems) { |
| 3204 | options += helpers.optionHtml('Min. Items', schema.minItems); |
| 3205 | } |
| 3206 | |
| 3207 | if (schema.maxItems) { |
| 3208 | options += helpers.optionHtml('Max. Items', schema.maxItems); |
| 3209 | } |
| 3210 | |
| 3211 | if (schema.uniqueItems) { |
| 3212 | options += helpers.optionHtml('Unique Items', 'true'); |
| 3213 | } |
| 3214 | |
| 3215 | if (schema.collectionFormat) { |
| 3216 | options += helpers.optionHtml('Coll. Format', schema.collectionFormat); |
| 3217 | } |
| 3218 | } |
| 3219 | |
| 3220 | if (_.isUndefined(schema.items)) { |
| 3221 | if (_.isArray(schema.enum)) { |
| 3222 | var enumString; |
| 3223 | |
| 3224 | if (type === 'number' || type === 'integer') { |
| 3225 | enumString = schema.enum.join(', '); |
| 3226 | } else { |
| 3227 | enumString = '"' + schema.enum.join('", "') + '"'; |
| 3228 | } |
| 3229 | |
| 3230 | options += helpers.optionHtml('Enum', enumString); |
| 3231 | } |
| 3232 | } |
| 3233 | |
| 3234 | if (options.length > 0) { |
| 3235 | html = '<span class="propWrap">' + html + '<table class="optionsWrapper"><tr><th colspan="2">' + type + '</th></tr>' + options + '</table></span>'; |
| 3236 | } |
| 3237 | |
| 3238 | return html; |
| 3239 | }; |
| 3240 | var processModel = function (schema, name) { |
| 3241 | var type = schema.type || 'object'; |
| 3242 | var isArray = schema.type === 'array'; |
| 3243 | var html = strongOpen + name + ' ' + (isArray ? '[' : '{') + strongClose; |
| 3244 | |
| 3245 | if (name) { |
| 3246 | seenModels.push(name); |
| 3247 | } |
| 3248 | |
| 3249 | if (isArray) { |
| 3250 | if (_.isArray(schema.items)) { |
| 3251 | html += '<div>' + _.map(schema.items, function (item) { |
| 3252 | var type = item.type || 'object'; |
| 3253 | |
| 3254 | if (_.isUndefined(item.$ref)) { |
| 3255 | if (_.indexOf(['array', 'object'], type) > -1) { |
| 3256 | if (type === 'object' && _.isUndefined(item.properties)) { |
| 3257 | return 'object'; |
| 3258 | } else { |
| 3259 | return addReference(item); |
| 3260 | } |
| 3261 | } else { |
| 3262 | return primitiveToOptionsHTML(item, type); |
| 3263 | } |
| 3264 | } else { |
| 3265 | return addReference(item, helpers.simpleRef(item.$ref)); |
| 3266 | } |
| 3267 | }).join(',</div><div>'); |
| 3268 | } else if (_.isPlainObject(schema.items)) { |
| 3269 | if (_.isUndefined(schema.items.$ref)) { |
| 3270 | if (_.indexOf(['array', 'object'], schema.items.type || 'object') > -1) { |
| 3271 | if ((_.isUndefined(schema.items.type) || schema.items.type === 'object') && _.isUndefined(schema.items.properties)) { |
| 3272 | html += '<div>object</div>'; |
| 3273 | } else { |
| 3274 | html += '<div>' + addReference(schema.items) + '</div>'; |
| 3275 | } |
| 3276 | } else { |
| 3277 | html += '<div>' + primitiveToOptionsHTML(schema.items, schema.items.type) + '</div>'; |
| 3278 | } |
| 3279 | } else { |
| 3280 | html += '<div>' + addReference(schema.items, helpers.simpleRef(schema.items.$ref)) + '</div>'; |
| 3281 | } |
| 3282 | } else { |
| 3283 | helpers.log('Array type\'s \'items\' property is not an array or an object, cannot process'); |
| 3284 | html += '<div>object</div>'; |
| 3285 | } |
| 3286 | } else { |
| 3287 | if (schema.$ref) { |
| 3288 | html += '<div>' + addReference(schema, name) + '</div>'; |
| 3289 | } else if (type === 'object') { |
| 3290 | html += '<div>'; |
| 3291 | |
| 3292 | if (_.isPlainObject(schema.properties)) { |
| 3293 | html += _.map(schema.properties, function (property, name) { |
| 3294 | var propertyIsRequired = (_.indexOf(schema.required, name) >= 0); |
| 3295 | var cProperty = _.cloneDeep(property); |
| 3296 | |
| 3297 | var requiredClass = propertyIsRequired ? 'required' : ''; |
| 3298 | var html = '<span class="propName ' + requiredClass + '">' + name + '</span> ('; |
| 3299 | var model; |
| 3300 | |
| 3301 | // Allow macro to set the default value |
| 3302 | cProperty.default = modelPropertyMacro(cProperty); |
| 3303 | |
| 3304 | // Resolve the schema (Handle nested schemas) |
| 3305 | cProperty = helpers.resolveSchema(cProperty); |
| 3306 | |
| 3307 | // We need to handle property references to primitives (Issue 339) |
| 3308 | if (!_.isUndefined(cProperty.$ref)) { |
| 3309 | model = models[helpers.simpleRef(cProperty.$ref)]; |
| 3310 | |
| 3311 | if (!_.isUndefined(model) && _.indexOf([undefined, 'array', 'object'], model.definition.type) === -1) { |
| 3312 | // Use referenced schema |
| 3313 | cProperty = helpers.resolveSchema(model.definition); |
| 3314 | } |
| 3315 | } |
| 3316 | |
| 3317 | html += primitiveToHTML(cProperty); |
| 3318 | |
| 3319 | if(!propertyIsRequired) { |
| 3320 | html += ', <span class="propOptKey">optional</span>'; |
| 3321 | } |
| 3322 | |
| 3323 | html += ')'; |
| 3324 | |
| 3325 | if (!_.isUndefined(cProperty.description)) { |
| 3326 | html += ': ' + '<span class="propDesc">' + cProperty.description + '</span>'; |
| 3327 | } |
| 3328 | |
| 3329 | if (cProperty.enum) { |
| 3330 | html += ' = <span class="propVals">[\'' + cProperty.enum.join('\', \'') + '\']</span>'; |
| 3331 | } |
| 3332 | |
| 3333 | return primitiveToOptionsHTML(cProperty, html); |
| 3334 | }).join(',</div><div>'); |
| 3335 | } |
| 3336 | |
| 3337 | html += '</div>'; |
| 3338 | } else { |
| 3339 | html += '<div>' + primitiveToOptionsHTML(schema, type) + '</div>'; |
| 3340 | } |
| 3341 | } |
| 3342 | |
| 3343 | return html + strongOpen + (isArray ? ']' : '}') + strongClose; |
| 3344 | }; |
| 3345 | |
| 3346 | // Resolve the schema (Handle nested schemas) |
| 3347 | schema = helpers.resolveSchema(schema); |
| 3348 | |
| 3349 | // Generate current HTML |
| 3350 | var html = processModel(schema, name); |
| 3351 | |
| 3352 | // Generate references HTML |
| 3353 | while (_.keys(references).length > 0) { |
| 3354 | /* jshint ignore:start */ |
| 3355 | _.forEach(references, function (schema, name) { |
| 3356 | var seenModel = _.indexOf(seenModels, name) > -1; |
| 3357 | |
| 3358 | delete references[name]; |
| 3359 | |
| 3360 | if (!seenModel) { |
| 3361 | seenModels.push(name); |
| 3362 | |
| 3363 | html += '<br />' + processModel(schema, name); |
| 3364 | } |
| 3365 | }); |
| 3366 | /* jshint ignore:end */ |
| 3367 | } |
| 3368 | |
| 3369 | return html; |
| 3370 | }; |
| 3371 | |
| 3372 | var schemaToJSON = function (schema, models, modelsToIgnore, modelPropertyMacro) { |
| 3373 | // Resolve the schema (Handle nested schemas) |
| 3374 | schema = helpers.resolveSchema(schema); |
| 3375 | |
| 3376 | var type = schema.type || 'object'; |
| 3377 | var format = schema.format; |
| 3378 | var model; |
| 3379 | var output; |
| 3380 | |
| 3381 | if (schema.example) { |
| 3382 | output = schema.example; |
| 3383 | } else if (_.isUndefined(schema.items) && _.isArray(schema.enum)) { |
| 3384 | output = schema.enum[0]; |
| 3385 | } |
| 3386 | |
| 3387 | if (_.isUndefined(output)) { |
| 3388 | if (schema.$ref) { |
| 3389 | model = models[helpers.simpleRef(schema.$ref)]; |
| 3390 | |
| 3391 | if (!_.isUndefined(model)) { |
| 3392 | if (_.isUndefined(modelsToIgnore[model.name])) { |
| 3393 | modelsToIgnore[model.name] = model; |
| 3394 | output = schemaToJSON(model.definition, models, modelsToIgnore, modelPropertyMacro); |
| 3395 | delete modelsToIgnore[model.name]; |
| 3396 | } else { |
| 3397 | if (model.type === 'array') { |
| 3398 | output = []; |
| 3399 | } else { |
| 3400 | output = {}; |
| 3401 | } |
| 3402 | } |
| 3403 | } |
| 3404 | } else if (!_.isUndefined(schema.default)) { |
| 3405 | output = schema.default; |
| 3406 | } else if (type === 'string') { |
| 3407 | if (format === 'date-time') { |
| 3408 | output = new Date().toISOString(); |
| 3409 | } else if (format === 'date') { |
| 3410 | output = new Date().toISOString().split('T')[0]; |
| 3411 | } else { |
| 3412 | output = 'string'; |
| 3413 | } |
| 3414 | } else if (type === 'integer') { |
| 3415 | output = 0; |
| 3416 | } else if (type === 'number') { |
| 3417 | output = 0.0; |
| 3418 | } else if (type === 'boolean') { |
| 3419 | output = true; |
| 3420 | } else if (type === 'object') { |
| 3421 | output = {}; |
| 3422 | |
| 3423 | _.forEach(schema.properties, function (property, name) { |
| 3424 | var cProperty = _.cloneDeep(property); |
| 3425 | |
| 3426 | // Allow macro to set the default value |
| 3427 | cProperty.default = modelPropertyMacro(property); |
| 3428 | |
| 3429 | output[name] = schemaToJSON(cProperty, models, modelsToIgnore, modelPropertyMacro); |
| 3430 | }); |
| 3431 | } else if (type === 'array') { |
| 3432 | output = []; |
| 3433 | |
| 3434 | if (_.isArray(schema.items)) { |
| 3435 | _.forEach(schema.items, function (item) { |
| 3436 | output.push(schemaToJSON(item, models, modelsToIgnore, modelPropertyMacro)); |
| 3437 | }); |
| 3438 | } else if (_.isPlainObject(schema.items)) { |
| 3439 | output.push(schemaToJSON(schema.items, models, modelsToIgnore, modelPropertyMacro)); |
| 3440 | } else if (_.isUndefined(schema.items)) { |
| 3441 | output.push({}); |
| 3442 | } else { |
| 3443 | helpers.log('Array type\'s \'items\' property is not an array or an object, cannot process'); |
| 3444 | } |
| 3445 | } |
| 3446 | } |
| 3447 | |
| 3448 | return output; |
| 3449 | }; |
| 3450 | |
| 3451 | Model.prototype.createJSONSample = Model.prototype.getSampleValue = function (modelsToIgnore) { |
| 3452 | modelsToIgnore = modelsToIgnore || {}; |
| 3453 | |
| 3454 | modelsToIgnore[this.name] = this; |
| 3455 | |
| 3456 | // Response support |
| 3457 | if (this.examples && _.isPlainObject(this.examples) && this.examples['application/json']) { |
| 3458 | this.definition.example = this.examples['application/json']; |
| 3459 | |
| 3460 | if (_.isString(this.definition.example)) { |
| 3461 | this.definition.example = jsyaml.safeLoad(this.definition.example); |
| 3462 | } |
| 3463 | } else if (!this.definition.example) { |
| 3464 | this.definition.example = this.examples; |
| 3465 | } |
| 3466 | |
| 3467 | return schemaToJSON(this.definition, this.models, modelsToIgnore, this.modelPropertyMacro); |
| 3468 | }; |
| 3469 | |
| 3470 | Model.prototype.getMockSignature = function () { |
| 3471 | return schemaToHTML(this.name, this.definition, this.models, this.modelPropertyMacro); |
| 3472 | }; |
| 3473 | |
| 3474 | },{"../helpers":4,"js-yaml":20,"lodash-compat/array/indexOf":51,"lodash-compat/collection/forEach":56,"lodash-compat/collection/map":58,"lodash-compat/lang/cloneDeep":142,"lodash-compat/lang/isArray":144,"lodash-compat/lang/isPlainObject":149,"lodash-compat/lang/isString":150,"lodash-compat/lang/isUndefined":152,"lodash-compat/object/keys":153}],9:[function(require,module,exports){ |
| 3475 | 'use strict'; |
| 3476 | |
| 3477 | var _ = { |
| 3478 | cloneDeep: require('lodash-compat/lang/cloneDeep'), |
| 3479 | isUndefined: require('lodash-compat/lang/isUndefined'), |
| 3480 | isEmpty: require('lodash-compat/lang/isEmpty') |
| 3481 | }; |
| 3482 | var helpers = require('../helpers'); |
| 3483 | var Model = require('./model'); |
| 3484 | var SwaggerHttp = require('../http'); |
| 3485 | |
| 3486 | var Operation = module.exports = function (parent, scheme, operationId, httpMethod, path, args, definitions, models, clientAuthorizations) { |
| 3487 | var errors = []; |
| 3488 | |
| 3489 | parent = parent || {}; |
| 3490 | args = args || {}; |
| 3491 | |
| 3492 | if(parent && parent.options) { |
| 3493 | this.client = parent.options.client || null; |
| 3494 | this.responseInterceptor = parent.options.responseInterceptor || null; |
| 3495 | } |
| 3496 | this.authorizations = args.security; |
| 3497 | this.basePath = parent.basePath || '/'; |
| 3498 | this.clientAuthorizations = clientAuthorizations; |
| 3499 | this.consumes = args.consumes || parent.consumes || ['application/json']; |
| 3500 | this.produces = args.produces || parent.produces || ['application/json']; |
| 3501 | this.deprecated = args.deprecated; |
| 3502 | this.description = args.description; |
| 3503 | this.host = parent.host || 'localhost'; |
| 3504 | this.method = (httpMethod || errors.push('Operation ' + operationId + ' is missing method.')); |
| 3505 | this.models = models || {}; |
| 3506 | this.nickname = (operationId || errors.push('Operations must have a nickname.')); |
| 3507 | this.operation = args; |
| 3508 | this.operations = {}; |
| 3509 | this.parameters = args !== null ? (args.parameters || []) : {}; |
| 3510 | this.parent = parent; |
| 3511 | this.path = (path || errors.push('Operation ' + this.nickname + ' is missing path.')); |
| 3512 | this.responses = (args.responses || {}); |
| 3513 | this.scheme = scheme || parent.scheme || 'http'; |
| 3514 | this.schemes = parent.schemes; |
| 3515 | this.security = args.security; |
| 3516 | this.summary = args.summary || ''; |
| 3517 | this.type = null; |
| 3518 | this.useJQuery = parent.useJQuery; |
| 3519 | this.parameterMacro = parent.parameterMacro || function (parameter) { |
| 3520 | return parameter.default; |
| 3521 | }; |
| 3522 | |
| 3523 | this.inlineModels = []; |
| 3524 | |
| 3525 | if (typeof this.deprecated === 'string') { |
| 3526 | switch(this.deprecated.toLowerCase()) { |
| 3527 | case 'true': case 'yes': case '1': { |
| 3528 | this.deprecated = true; |
| 3529 | break; |
| 3530 | } |
| 3531 | |
| 3532 | case 'false': case 'no': case '0': case null: { |
| 3533 | this.deprecated = false; |
| 3534 | break; |
| 3535 | } |
| 3536 | |
| 3537 | default: this.deprecated = Boolean(this.deprecated); |
| 3538 | } |
| 3539 | } |
| 3540 | |
| 3541 | var i, model; |
| 3542 | |
| 3543 | if (definitions) { |
| 3544 | // add to global models |
| 3545 | var key; |
| 3546 | |
| 3547 | for (key in definitions) { |
| 3548 | model = new Model(key, definitions[key], this.models, parent.modelPropertyMacro); |
| 3549 | |
| 3550 | if (model) { |
| 3551 | this.models[key] = model; |
| 3552 | } |
| 3553 | } |
| 3554 | } |
| 3555 | |
| 3556 | for (i = 0; i < this.parameters.length; i++) { |
| 3557 | var param = this.parameters[i]; |
| 3558 | |
| 3559 | // Allow macro to set the default value |
| 3560 | param.default = this.parameterMacro(param); |
| 3561 | |
| 3562 | if (param.type === 'array') { |
| 3563 | param.isList = true; |
| 3564 | param.allowMultiple = true; |
| 3565 | // the enum can be defined at the items level |
| 3566 | if (param.items && param.items.enum) { |
| 3567 | param['enum'] = param.items.enum; |
| 3568 | } |
| 3569 | } |
| 3570 | |
| 3571 | var innerType = this.getType(param); |
| 3572 | |
| 3573 | if (innerType && innerType.toString().toLowerCase() === 'boolean') { |
| 3574 | param.allowableValues = {}; |
| 3575 | param.isList = true; |
| 3576 | param['enum'] = [true, false]; // use actual primitives |
| 3577 | } |
| 3578 | |
| 3579 | if (typeof param['enum'] !== 'undefined') { |
| 3580 | var id; |
| 3581 | |
| 3582 | param.allowableValues = {}; |
| 3583 | param.allowableValues.values = []; |
| 3584 | param.allowableValues.descriptiveValues = []; |
| 3585 | |
| 3586 | for (id = 0; id < param['enum'].length; id++) { |
| 3587 | var value = param['enum'][id]; |
| 3588 | var isDefault = (value === param.default || value+'' === param.default); |
| 3589 | |
| 3590 | param.allowableValues.values.push(value); |
| 3591 | // Always have string for descriptive values.... |
| 3592 | param.allowableValues.descriptiveValues.push({value : value+'', isDefault: isDefault}); |
| 3593 | } |
| 3594 | } |
| 3595 | |
| 3596 | if (param.type === 'array') { |
| 3597 | innerType = [innerType]; |
| 3598 | |
| 3599 | if (typeof param.allowableValues === 'undefined') { |
| 3600 | // can't show as a list if no values to select from |
| 3601 | delete param.isList; |
| 3602 | delete param.allowMultiple; |
| 3603 | } |
| 3604 | } |
| 3605 | |
| 3606 | param.signature = this.getModelSignature(innerType, this.models).toString(); |
| 3607 | param.sampleJSON = this.getModelSampleJSON(innerType, this.models); |
| 3608 | param.responseClassSignature = param.signature; |
| 3609 | } |
| 3610 | |
| 3611 | var defaultResponseCode, response, responses = this.responses; |
| 3612 | |
| 3613 | if (responses['200']) { |
| 3614 | response = responses['200']; |
| 3615 | defaultResponseCode = '200'; |
| 3616 | } else if (responses['201']) { |
| 3617 | response = responses['201']; |
| 3618 | defaultResponseCode = '201'; |
| 3619 | } else if (responses['202']) { |
| 3620 | response = responses['202']; |
| 3621 | defaultResponseCode = '202'; |
| 3622 | } else if (responses['203']) { |
| 3623 | response = responses['203']; |
| 3624 | defaultResponseCode = '203'; |
| 3625 | } else if (responses['204']) { |
| 3626 | response = responses['204']; |
| 3627 | defaultResponseCode = '204'; |
| 3628 | } else if (responses['205']) { |
| 3629 | response = responses['205']; |
| 3630 | defaultResponseCode = '205'; |
| 3631 | } else if (responses['206']) { |
| 3632 | response = responses['206']; |
| 3633 | defaultResponseCode = '206'; |
| 3634 | } else if (responses['default']) { |
| 3635 | response = responses['default']; |
| 3636 | defaultResponseCode = 'default'; |
| 3637 | } |
| 3638 | |
| 3639 | if (response && response.schema) { |
| 3640 | var resolvedModel = this.resolveModel(response.schema, definitions); |
| 3641 | var successResponse; |
| 3642 | |
| 3643 | delete responses[defaultResponseCode]; |
| 3644 | |
| 3645 | if (resolvedModel) { |
| 3646 | this.successResponse = {}; |
| 3647 | successResponse = this.successResponse[defaultResponseCode] = resolvedModel; |
| 3648 | } else if (!response.schema.type || response.schema.type === 'object' || response.schema.type === 'array') { |
| 3649 | // Inline model |
| 3650 | this.successResponse = {}; |
| 3651 | successResponse = this.successResponse[defaultResponseCode] = new Model(undefined, response.schema || {}, this.models, parent.modelPropertyMacro); |
| 3652 | } else { |
| 3653 | // Primitive |
| 3654 | this.successResponse = {}; |
| 3655 | successResponse = this.successResponse[defaultResponseCode] = response.schema; |
| 3656 | } |
| 3657 | |
| 3658 | if (successResponse) { |
| 3659 | // Attach response properties |
| 3660 | if (response.description) { |
| 3661 | successResponse.description = response.description; |
| 3662 | } |
| 3663 | |
| 3664 | if (response.examples) { |
| 3665 | successResponse.examples = response.examples; |
| 3666 | } |
| 3667 | |
| 3668 | if (response.headers) { |
| 3669 | successResponse.headers = response.headers; |
| 3670 | } |
| 3671 | } |
| 3672 | |
| 3673 | this.type = response; |
| 3674 | } |
| 3675 | |
| 3676 | if (errors.length > 0) { |
| 3677 | if (this.resource && this.resource.api && this.resource.api.fail) { |
| 3678 | this.resource.api.fail(errors); |
| 3679 | } |
| 3680 | } |
| 3681 | |
| 3682 | return this; |
| 3683 | }; |
| 3684 | |
| 3685 | Operation.prototype.isDefaultArrayItemValue = function(value, param) { |
| 3686 | if (param.default && Array.isArray(param.default)) { |
| 3687 | return param.default.indexOf(value) !== -1; |
| 3688 | } |
| 3689 | return value === param.default; |
| 3690 | }; |
| 3691 | |
| 3692 | Operation.prototype.getType = function (param) { |
| 3693 | var type = param.type; |
| 3694 | var format = param.format; |
| 3695 | var isArray = false; |
| 3696 | var str; |
| 3697 | |
| 3698 | if (type === 'integer' && format === 'int32') { |
| 3699 | str = 'integer'; |
| 3700 | } else if (type === 'integer' && format === 'int64') { |
| 3701 | str = 'long'; |
| 3702 | } else if (type === 'integer') { |
| 3703 | str = 'integer'; |
| 3704 | } else if (type === 'string') { |
| 3705 | if (format === 'date-time') { |
| 3706 | str = 'date-time'; |
| 3707 | } else if (format === 'date') { |
| 3708 | str = 'date'; |
| 3709 | } else { |
| 3710 | str = 'string'; |
| 3711 | } |
| 3712 | } else if (type === 'number' && format === 'float') { |
| 3713 | str = 'float'; |
| 3714 | } else if (type === 'number' && format === 'double') { |
| 3715 | str = 'double'; |
| 3716 | } else if (type === 'number') { |
| 3717 | str = 'double'; |
| 3718 | } else if (type === 'boolean') { |
| 3719 | str = 'boolean'; |
| 3720 | } else if (type === 'array') { |
| 3721 | isArray = true; |
| 3722 | |
| 3723 | if (param.items) { |
| 3724 | str = this.getType(param.items); |
| 3725 | } |
| 3726 | } |
| 3727 | |
| 3728 | if (param.$ref) { |
| 3729 | str = helpers.simpleRef(param.$ref); |
| 3730 | } |
| 3731 | |
| 3732 | var schema = param.schema; |
| 3733 | |
| 3734 | if (schema) { |
| 3735 | var ref = schema.$ref; |
| 3736 | |
| 3737 | if (ref) { |
| 3738 | ref = helpers.simpleRef(ref); |
| 3739 | |
| 3740 | if (isArray) { |
| 3741 | return [ ref ]; |
| 3742 | } else { |
| 3743 | return ref; |
| 3744 | } |
| 3745 | } else { |
| 3746 | // If inline schema, we add it our interal hash -> which gives us it's ID (int) |
| 3747 | if(schema.type === 'object') { |
| 3748 | return this.addInlineModel(schema); |
| 3749 | } |
| 3750 | return this.getType(schema); |
| 3751 | } |
| 3752 | } |
| 3753 | if (isArray) { |
| 3754 | return [ str ]; |
| 3755 | } else { |
| 3756 | return str; |
| 3757 | } |
| 3758 | }; |
| 3759 | |
| 3760 | /** |
| 3761 | * adds an inline schema (model) to a hash, where we can ref it later |
| 3762 | * @param {object} schema a schema |
| 3763 | * @return {number} the ID of the schema being added, or null |
| 3764 | **/ |
| 3765 | Operation.prototype.addInlineModel = function (schema) { |
| 3766 | var len = this.inlineModels.length; |
| 3767 | var model = this.resolveModel(schema, {}); |
| 3768 | if(model) { |
| 3769 | this.inlineModels.push(model); |
| 3770 | return 'Inline Model '+len; // return string ref of the inline model (used with #getInlineModel) |
| 3771 | } |
| 3772 | return null; // report errors? |
| 3773 | }; |
| 3774 | |
| 3775 | /** |
| 3776 | * gets the internal ref to an inline model |
| 3777 | * @param {string} inline_str a string reference to an inline model |
| 3778 | * @return {Model} the model being referenced. Or null |
| 3779 | **/ |
| 3780 | Operation.prototype.getInlineModel = function(inlineStr) { |
| 3781 | if(/^Inline Model \d+$/.test(inlineStr)) { |
| 3782 | var id = parseInt(inlineStr.substr('Inline Model'.length).trim(),10); // |
| 3783 | var model = this.inlineModels[id]; |
| 3784 | return model; |
| 3785 | } |
| 3786 | // I'm returning null here, should I rather throw an error? |
| 3787 | return null; |
| 3788 | }; |
| 3789 | |
| 3790 | Operation.prototype.resolveModel = function (schema, definitions) { |
| 3791 | if (typeof schema.$ref !== 'undefined') { |
| 3792 | var ref = schema.$ref; |
| 3793 | |
| 3794 | if (ref.indexOf('#/definitions/') === 0) { |
| 3795 | ref = ref.substring('#/definitions/'.length); |
| 3796 | } |
| 3797 | |
| 3798 | if (definitions[ref]) { |
| 3799 | return new Model(ref, definitions[ref], this.models, this.parent.modelPropertyMacro); |
| 3800 | } |
| 3801 | // schema must at least be an object to get resolved to an inline Model |
| 3802 | } else if (schema && typeof schema === 'object' && |
| 3803 | (schema.type === 'object' || _.isUndefined(schema.type))) { |
| 3804 | return new Model(undefined, schema, this.models, this.parent.modelPropertyMacro); |
| 3805 | } |
| 3806 | |
| 3807 | return null; |
| 3808 | }; |
| 3809 | |
| 3810 | Operation.prototype.help = function (dontPrint) { |
| 3811 | var out = this.nickname + ': ' + this.summary + '\n'; |
| 3812 | |
| 3813 | for (var i = 0; i < this.parameters.length; i++) { |
| 3814 | var param = this.parameters[i]; |
| 3815 | var typeInfo = param.signature; |
| 3816 | |
| 3817 | out += '\n * ' + param.name + ' (' + typeInfo + '): ' + param.description; |
| 3818 | } |
| 3819 | |
| 3820 | if (typeof dontPrint === 'undefined') { |
| 3821 | helpers.log(out); |
| 3822 | } |
| 3823 | |
| 3824 | return out; |
| 3825 | }; |
| 3826 | |
| 3827 | Operation.prototype.getModelSignature = function (type, definitions) { |
| 3828 | var isPrimitive, listType; |
| 3829 | |
| 3830 | if (type instanceof Array) { |
| 3831 | listType = true; |
| 3832 | type = type[0]; |
| 3833 | } |
| 3834 | |
| 3835 | // Convert undefined to string of 'undefined' |
| 3836 | if (typeof type === 'undefined') { |
| 3837 | type = 'undefined'; |
| 3838 | isPrimitive = true; |
| 3839 | |
| 3840 | } else if (definitions[type]){ |
| 3841 | // a model def exists? |
| 3842 | type = definitions[type]; /* Model */ |
| 3843 | isPrimitive = false; |
| 3844 | |
| 3845 | } else if (this.getInlineModel(type)) { |
| 3846 | type = this.getInlineModel(type); /* Model */ |
| 3847 | isPrimitive = false; |
| 3848 | |
| 3849 | } else { |
| 3850 | // We default to primitive |
| 3851 | isPrimitive = true; |
| 3852 | } |
| 3853 | |
| 3854 | if (isPrimitive) { |
| 3855 | if (listType) { |
| 3856 | return 'Array[' + type + ']'; |
| 3857 | } else { |
| 3858 | return type.toString(); |
| 3859 | } |
| 3860 | } else { |
| 3861 | if (listType) { |
| 3862 | return 'Array[' + type.getMockSignature() + ']'; |
| 3863 | } else { |
| 3864 | return type.getMockSignature(); |
| 3865 | } |
| 3866 | } |
| 3867 | }; |
| 3868 | |
| 3869 | Operation.prototype.supportHeaderParams = function () { |
| 3870 | return true; |
| 3871 | }; |
| 3872 | |
| 3873 | Operation.prototype.supportedSubmitMethods = function () { |
| 3874 | return this.parent.supportedSubmitMethods; |
| 3875 | }; |
| 3876 | |
| 3877 | Operation.prototype.getHeaderParams = function (args) { |
| 3878 | var headers = this.setContentTypes(args, {}); |
| 3879 | |
| 3880 | for (var i = 0; i < this.parameters.length; i++) { |
| 3881 | var param = this.parameters[i]; |
| 3882 | |
| 3883 | if (typeof args[param.name] !== 'undefined') { |
| 3884 | if (param.in === 'header') { |
| 3885 | var value = args[param.name]; |
| 3886 | |
| 3887 | if (Array.isArray(value)) { |
| 3888 | value = value.toString(); |
| 3889 | } |
| 3890 | |
| 3891 | headers[param.name] = value; |
| 3892 | } |
| 3893 | } |
| 3894 | } |
| 3895 | |
| 3896 | return headers; |
| 3897 | }; |
| 3898 | |
| 3899 | Operation.prototype.urlify = function (args) { |
| 3900 | var formParams = {}; |
| 3901 | var requestUrl = this.path; |
| 3902 | var querystring = ''; // grab params from the args, build the querystring along the way |
| 3903 | |
| 3904 | for (var i = 0; i < this.parameters.length; i++) { |
| 3905 | var param = this.parameters[i]; |
| 3906 | |
| 3907 | if (typeof args[param.name] !== 'undefined') { |
| 3908 | if (param.in === 'path') { |
| 3909 | var reg = new RegExp('\{' + param.name + '\}', 'gi'); |
| 3910 | var value = args[param.name]; |
| 3911 | |
| 3912 | if (Array.isArray(value)) { |
| 3913 | value = this.encodePathCollection(param.collectionFormat, param.name, value); |
| 3914 | } else { |
| 3915 | value = this.encodePathParam(value); |
| 3916 | } |
| 3917 | |
| 3918 | requestUrl = requestUrl.replace(reg, value); |
| 3919 | } else if (param.in === 'query' && typeof args[param.name] !== 'undefined') { |
| 3920 | if (querystring === '') { |
| 3921 | querystring += '?'; |
| 3922 | } else { |
| 3923 | querystring += '&'; |
| 3924 | } |
| 3925 | |
| 3926 | if (typeof param.collectionFormat !== 'undefined') { |
| 3927 | var qp = args[param.name]; |
| 3928 | |
| 3929 | if (Array.isArray(qp)) { |
| 3930 | querystring += this.encodeQueryCollection(param.collectionFormat, param.name, qp); |
| 3931 | } else { |
| 3932 | querystring += this.encodeQueryParam(param.name) + '=' + this.encodeQueryParam(args[param.name]); |
| 3933 | } |
| 3934 | } else { |
| 3935 | querystring += this.encodeQueryParam(param.name) + '=' + this.encodeQueryParam(args[param.name]); |
| 3936 | } |
| 3937 | } else if (param.in === 'formData') { |
| 3938 | formParams[param.name] = args[param.name]; |
| 3939 | } |
| 3940 | } |
| 3941 | } |
| 3942 | var url = this.scheme + '://' + this.host; |
| 3943 | |
| 3944 | if (this.basePath !== '/') { |
| 3945 | url += this.basePath; |
| 3946 | } |
| 3947 | return url + requestUrl + querystring; |
| 3948 | }; |
| 3949 | |
| 3950 | Operation.prototype.getMissingParams = function (args) { |
| 3951 | var missingParams = []; // check required params, track the ones that are missing |
| 3952 | var i; |
| 3953 | |
| 3954 | for (i = 0; i < this.parameters.length; i++) { |
| 3955 | var param = this.parameters[i]; |
| 3956 | |
| 3957 | if (param.required === true) { |
| 3958 | if (typeof args[param.name] === 'undefined') { |
| 3959 | missingParams = param.name; |
| 3960 | } |
| 3961 | } |
| 3962 | } |
| 3963 | |
| 3964 | return missingParams; |
| 3965 | }; |
| 3966 | |
| 3967 | Operation.prototype.getBody = function (headers, args, opts) { |
| 3968 | var formParams = {}, body, key, value, hasBody = false; |
| 3969 | |
| 3970 | for (var i = 0; i < this.parameters.length; i++) { |
| 3971 | var param = this.parameters[i]; |
| 3972 | |
| 3973 | if (typeof args[param.name] !== 'undefined') { |
| 3974 | if (param.in === 'body') { |
| 3975 | body = args[param.name]; |
| 3976 | } else if (param.in === 'formData') { |
| 3977 | formParams[param.name] = args[param.name]; |
| 3978 | } |
| 3979 | } |
| 3980 | else { |
| 3981 | if(param.in === 'body') { |
| 3982 | hasBody = true; |
| 3983 | } |
| 3984 | } |
| 3985 | } |
| 3986 | |
| 3987 | // if body is null and hasBody is true, AND a JSON body is requested, send empty {} |
| 3988 | if(hasBody && typeof body === 'undefined') { |
| 3989 | var contentType = headers['Content-Type']; |
| 3990 | if(contentType && contentType.indexOf('application/json') === 0) { |
| 3991 | body = '{}'; |
| 3992 | } |
| 3993 | } |
| 3994 | |
| 3995 | // handle form params |
| 3996 | if (headers['Content-Type'] === 'application/x-www-form-urlencoded') { |
| 3997 | var encoded = ''; |
| 3998 | |
| 3999 | for (key in formParams) { |
| 4000 | value = formParams[key]; |
| 4001 | |
| 4002 | if (typeof value !== 'undefined') { |
| 4003 | if (encoded !== '') { |
| 4004 | encoded += '&'; |
| 4005 | } |
| 4006 | |
| 4007 | encoded += encodeURIComponent(key) + '=' + encodeURIComponent(value); |
| 4008 | } |
| 4009 | } |
| 4010 | |
| 4011 | body = encoded; |
| 4012 | } else if (headers['Content-Type'] && headers['Content-Type'].indexOf('multipart/form-data') >= 0) { |
| 4013 | if (opts.useJQuery) { |
| 4014 | var bodyParam = new FormData(); |
| 4015 | |
| 4016 | bodyParam.type = 'formData'; |
| 4017 | |
| 4018 | for (key in formParams) { |
| 4019 | value = args[key]; |
| 4020 | |
| 4021 | if (typeof value !== 'undefined') { |
| 4022 | // required for jquery file upload |
| 4023 | if (value.type === 'file' && value.value) { |
| 4024 | delete headers['Content-Type']; |
| 4025 | |
| 4026 | bodyParam.append(key, value.value); |
| 4027 | } else { |
| 4028 | bodyParam.append(key, value); |
| 4029 | } |
| 4030 | } |
| 4031 | } |
| 4032 | |
| 4033 | body = bodyParam; |
| 4034 | } |
| 4035 | } |
| 4036 | |
| 4037 | return body; |
| 4038 | }; |
| 4039 | |
| 4040 | /** |
| 4041 | * gets sample response for a single operation |
| 4042 | **/ |
| 4043 | Operation.prototype.getModelSampleJSON = function (type, models) { |
| 4044 | var listType, sampleJson, innerType; |
| 4045 | models = models || {}; |
| 4046 | |
| 4047 | listType = (type instanceof Array); |
| 4048 | innerType = listType ? type[0] : type; |
| 4049 | |
| 4050 | if(models[innerType]) { |
| 4051 | sampleJson = models[innerType].createJSONSample(); |
| 4052 | } else if (this.getInlineModel(innerType)){ |
| 4053 | sampleJson = this.getInlineModel(innerType).createJSONSample(); // may return null, if type isn't correct |
| 4054 | } |
| 4055 | |
| 4056 | |
| 4057 | if (sampleJson) { |
| 4058 | sampleJson = listType ? [sampleJson] : sampleJson; |
| 4059 | |
| 4060 | if (typeof sampleJson === 'string') { |
| 4061 | return sampleJson; |
| 4062 | } else if (typeof sampleJson === 'object') { |
| 4063 | var t = sampleJson; |
| 4064 | |
| 4065 | if (sampleJson instanceof Array && sampleJson.length > 0) { |
| 4066 | t = sampleJson[0]; |
| 4067 | } |
| 4068 | |
| 4069 | if (t.nodeName) { |
| 4070 | var xmlString = new XMLSerializer().serializeToString(t); |
| 4071 | |
| 4072 | return this.formatXml(xmlString); |
| 4073 | } else { |
| 4074 | return JSON.stringify(sampleJson, null, 2); |
| 4075 | } |
| 4076 | } else { |
| 4077 | return sampleJson; |
| 4078 | } |
| 4079 | } |
| 4080 | }; |
| 4081 | |
| 4082 | /** |
| 4083 | * legacy binding |
| 4084 | **/ |
| 4085 | Operation.prototype.do = function (args, opts, callback, error, parent) { |
| 4086 | return this.execute(args, opts, callback, error, parent); |
| 4087 | }; |
| 4088 | |
| 4089 | /** |
| 4090 | * executes an operation |
| 4091 | **/ |
| 4092 | Operation.prototype.execute = function (arg1, arg2, arg3, arg4, parent) { |
| 4093 | var args = arg1 || {}; |
| 4094 | var opts = {}, success, error; |
| 4095 | |
| 4096 | if (typeof arg2 === 'object') { |
| 4097 | opts = arg2; |
| 4098 | success = arg3; |
| 4099 | error = arg4; |
| 4100 | } |
| 4101 | |
| 4102 | if(this.client) { |
| 4103 | opts.client = this.client; |
| 4104 | } |
| 4105 | if(this.responseInterceptor) { |
| 4106 | opts.responseInterceptor = this.responseInterceptor; |
| 4107 | } |
| 4108 | |
| 4109 | |
| 4110 | if (typeof arg2 === 'function') { |
| 4111 | success = arg2; |
| 4112 | error = arg3; |
| 4113 | } |
| 4114 | |
| 4115 | success = (success || this.parent.defaultSuccessCallback || helpers.log); |
| 4116 | error = (error || this.parent.defaultErrorCallback || helpers.log); |
| 4117 | |
| 4118 | |
| 4119 | if (typeof opts.useJQuery === 'undefined') { |
| 4120 | opts.useJQuery = this.useJQuery; |
| 4121 | } |
| 4122 | var missingParams = this.getMissingParams(args); |
| 4123 | |
| 4124 | if (missingParams.length > 0) { |
| 4125 | var message = 'missing required params: ' + missingParams; |
| 4126 | |
| 4127 | helpers.fail(message); |
| 4128 | error(message); |
| 4129 | |
| 4130 | return; |
| 4131 | } |
| 4132 | |
| 4133 | var allHeaders = this.getHeaderParams(args); |
| 4134 | var contentTypeHeaders = this.setContentTypes(args, opts); |
| 4135 | var headers = {}, attrname; |
| 4136 | |
| 4137 | for (attrname in allHeaders) { headers[attrname] = allHeaders[attrname]; } |
| 4138 | for (attrname in contentTypeHeaders) { headers[attrname] = contentTypeHeaders[attrname]; } |
| 4139 | |
| 4140 | var body = this.getBody(contentTypeHeaders, args, opts); |
| 4141 | var url = this.urlify(args); |
| 4142 | |
| 4143 | if(url.indexOf('.{format}') > 0) { |
| 4144 | if(headers) { |
| 4145 | var format = headers.Accept || headers.accept; |
| 4146 | if(format && format.indexOf('json') > 0) { |
| 4147 | url = url.replace('.{format}', '.json'); |
| 4148 | } |
| 4149 | else if(format && format.indexOf('xml') > 0) { |
| 4150 | url = url.replace('.{format}', '.xml'); |
| 4151 | } |
| 4152 | } |
| 4153 | } |
| 4154 | |
| 4155 | var obj = { |
| 4156 | url: url, |
| 4157 | method: this.method.toUpperCase(), |
| 4158 | body: body, |
| 4159 | useJQuery: opts.useJQuery, |
| 4160 | headers: headers, |
| 4161 | on: { |
| 4162 | response: function (response) { |
| 4163 | return success(response, parent); |
| 4164 | }, |
| 4165 | error: function (response) { |
| 4166 | return error(response, parent); |
| 4167 | } |
| 4168 | } |
| 4169 | }; |
| 4170 | |
| 4171 | this.clientAuthorizations.apply(obj, this.operation.security); |
| 4172 | if (opts.mock === true) { |
| 4173 | return obj; |
| 4174 | } else { |
| 4175 | new SwaggerHttp().execute(obj, opts); |
| 4176 | } |
| 4177 | }; |
| 4178 | |
| 4179 | function itemByPriority(col, itemPriority) { |
| 4180 | |
| 4181 | // No priorities? return first... |
| 4182 | if(_.isEmpty(itemPriority)) { |
| 4183 | return col[0]; |
| 4184 | } |
| 4185 | |
| 4186 | for (var i = 0, len = itemPriority.length; i < len; i++) { |
| 4187 | if(col.indexOf(itemPriority[i]) > -1) { |
| 4188 | return itemPriority[i]; |
| 4189 | } |
| 4190 | } |
| 4191 | |
| 4192 | // Otherwise return first |
| 4193 | return col[0]; |
| 4194 | } |
| 4195 | |
| 4196 | Operation.prototype.setContentTypes = function (args, opts) { |
| 4197 | // default type |
| 4198 | var allDefinedParams = this.parameters; |
| 4199 | var body; |
| 4200 | var consumes = args.parameterContentType || itemByPriority(this.consumes, ['application/json', 'application/yaml']); |
| 4201 | var accepts = opts.responseContentType || itemByPriority(this.produces, ['application/json', 'application/yaml']); |
| 4202 | var definedFileParams = []; |
| 4203 | var definedFormParams = []; |
| 4204 | var headers = {}; |
| 4205 | var i; |
| 4206 | |
| 4207 | // get params from the operation and set them in definedFileParams, definedFormParams, headers |
| 4208 | for (i = 0; i < allDefinedParams.length; i++) { |
| 4209 | var param = allDefinedParams[i]; |
| 4210 | |
| 4211 | if (param.in === 'formData') { |
| 4212 | if (param.type === 'file') { |
| 4213 | definedFileParams.push(param); |
| 4214 | } else { |
| 4215 | definedFormParams.push(param); |
| 4216 | } |
| 4217 | } else if (param.in === 'header' && opts) { |
| 4218 | var key = param.name; |
| 4219 | var headerValue = opts[param.name]; |
| 4220 | |
| 4221 | if (typeof opts[param.name] !== 'undefined') { |
| 4222 | headers[key] = headerValue; |
| 4223 | } |
| 4224 | } else if (param.in === 'body' && typeof args[param.name] !== 'undefined') { |
| 4225 | body = args[param.name]; |
| 4226 | } |
| 4227 | } |
| 4228 | |
| 4229 | // if there's a body, need to set the consumes header via requestContentType |
| 4230 | if (this.method === 'post' || this.method === 'put' || this.method === 'patch') { |
| 4231 | if (opts.requestContentType) { |
| 4232 | consumes = opts.requestContentType; |
| 4233 | } |
| 4234 | // if any form params, content type must be set |
| 4235 | if (definedFormParams.length > 0) { |
| 4236 | if (opts.requestContentType) { // override if set |
| 4237 | consumes = opts.requestContentType; |
| 4238 | } else if (definedFileParams.length > 0) { // if a file, must be multipart/form-data |
| 4239 | consumes = 'multipart/form-data'; |
| 4240 | } else { // default to x-www-from-urlencoded |
| 4241 | consumes = 'application/x-www-form-urlencoded'; |
| 4242 | } |
| 4243 | } |
| 4244 | } |
| 4245 | else { |
| 4246 | consumes = null; |
| 4247 | } |
| 4248 | |
| 4249 | if (consumes && this.consumes) { |
| 4250 | if (this.consumes.indexOf(consumes) === -1) { |
| 4251 | helpers.log('server doesn\'t consume ' + consumes + ', try ' + JSON.stringify(this.consumes)); |
| 4252 | } |
| 4253 | } |
| 4254 | |
| 4255 | if (!this.matchesAccept(accepts)) { |
| 4256 | helpers.log('server can\'t produce ' + accepts); |
| 4257 | } |
| 4258 | |
| 4259 | if ((consumes && body !== '') || (consumes === 'application/x-www-form-urlencoded')) { |
| 4260 | headers['Content-Type'] = consumes; |
| 4261 | } |
| 4262 | |
| 4263 | if (accepts) { |
| 4264 | headers.Accept = accepts; |
| 4265 | } |
| 4266 | |
| 4267 | return headers; |
| 4268 | }; |
| 4269 | |
| 4270 | /** |
| 4271 | * Returns true if the request accepts header matches anything in this.produces. |
| 4272 | * If this.produces contains * / *, ignore the accept header. |
| 4273 | * @param {string=} accepts The client request accept header. |
| 4274 | * @return {boolean} |
| 4275 | */ |
| 4276 | Operation.prototype.matchesAccept = function(accepts) { |
| 4277 | // no accepts or produces, no problem! |
| 4278 | if (!accepts || !this.produces) { |
| 4279 | return true; |
| 4280 | } |
| 4281 | return this.produces.indexOf(accepts) !== -1 || this.produces.indexOf('*/*') !== -1; |
| 4282 | }; |
| 4283 | |
| 4284 | Operation.prototype.asCurl = function (args) { |
| 4285 | var obj = this.execute(args, {mock: true}); |
| 4286 | |
| 4287 | this.clientAuthorizations.apply(obj); |
| 4288 | |
| 4289 | var results = []; |
| 4290 | |
| 4291 | results.push('-X ' + this.method.toUpperCase()); |
| 4292 | |
| 4293 | if (obj.headers) { |
| 4294 | var key; |
| 4295 | |
| 4296 | for (key in obj.headers) { |
| 4297 | results.push('--header "' + key + ': ' + obj.headers[key] + '"'); |
| 4298 | } |
| 4299 | } |
| 4300 | |
| 4301 | if (obj.body) { |
| 4302 | var body; |
| 4303 | |
| 4304 | if (typeof obj.body === 'object') { |
| 4305 | body = JSON.stringify(obj.body); |
| 4306 | } else { |
| 4307 | body = obj.body; |
| 4308 | } |
| 4309 | |
| 4310 | results.push('-d "' + body.replace(/"/g, '\\"') + '"'); |
| 4311 | } |
| 4312 | |
| 4313 | return 'curl ' + (results.join(' ')) + ' "' + obj.url + '"'; |
| 4314 | }; |
| 4315 | |
| 4316 | Operation.prototype.encodePathCollection = function (type, name, value) { |
| 4317 | var encoded = ''; |
| 4318 | var i; |
| 4319 | var separator = ''; |
| 4320 | |
| 4321 | if (type === 'ssv') { |
| 4322 | separator = '%20'; |
| 4323 | } else if (type === 'tsv') { |
| 4324 | separator = '\\t'; |
| 4325 | } else if (type === 'pipes') { |
| 4326 | separator = '|'; |
| 4327 | } else { |
| 4328 | separator = ','; |
| 4329 | } |
| 4330 | |
| 4331 | for (i = 0; i < value.length; i++) { |
| 4332 | if (i === 0) { |
| 4333 | encoded = this.encodeQueryParam(value[i]); |
| 4334 | } else { |
| 4335 | encoded += separator + this.encodeQueryParam(value[i]); |
| 4336 | } |
| 4337 | } |
| 4338 | |
| 4339 | return encoded; |
| 4340 | }; |
| 4341 | |
| 4342 | Operation.prototype.encodeQueryCollection = function (type, name, value) { |
| 4343 | var encoded = ''; |
| 4344 | var i; |
| 4345 | |
| 4346 | if (type === 'default' || type === 'multi') { |
| 4347 | for (i = 0; i < value.length; i++) { |
| 4348 | if (i > 0) {encoded += '&';} |
| 4349 | |
| 4350 | encoded += this.encodeQueryParam(name) + '=' + this.encodeQueryParam(value[i]); |
| 4351 | } |
| 4352 | } else { |
| 4353 | var separator = ''; |
| 4354 | |
| 4355 | if (type === 'csv') { |
| 4356 | separator = ','; |
| 4357 | } else if (type === 'ssv') { |
| 4358 | separator = '%20'; |
| 4359 | } else if (type === 'tsv') { |
| 4360 | separator = '\\t'; |
| 4361 | } else if (type === 'pipes') { |
| 4362 | separator = '|'; |
| 4363 | } else if (type === 'brackets') { |
| 4364 | for (i = 0; i < value.length; i++) { |
| 4365 | if (i !== 0) { |
| 4366 | encoded += '&'; |
| 4367 | } |
| 4368 | |
| 4369 | encoded += this.encodeQueryParam(name) + '[]=' + this.encodeQueryParam(value[i]); |
| 4370 | } |
| 4371 | } |
| 4372 | |
| 4373 | if (separator !== '') { |
| 4374 | for (i = 0; i < value.length; i++) { |
| 4375 | if (i === 0) { |
| 4376 | encoded = this.encodeQueryParam(name) + '=' + this.encodeQueryParam(value[i]); |
| 4377 | } else { |
| 4378 | encoded += separator + this.encodeQueryParam(value[i]); |
| 4379 | } |
| 4380 | } |
| 4381 | } |
| 4382 | } |
| 4383 | |
| 4384 | return encoded; |
| 4385 | }; |
| 4386 | |
| 4387 | Operation.prototype.encodeQueryParam = function (arg) { |
| 4388 | return encodeURIComponent(arg); |
| 4389 | }; |
| 4390 | |
| 4391 | /** |
| 4392 | * TODO revisit, might not want to leave '/' |
| 4393 | **/ |
| 4394 | Operation.prototype.encodePathParam = function (pathParam) { |
| 4395 | return encodeURIComponent(pathParam); |
| 4396 | }; |
| 4397 | |
| 4398 | },{"../helpers":4,"../http":5,"./model":8,"lodash-compat/lang/cloneDeep":142,"lodash-compat/lang/isEmpty":145,"lodash-compat/lang/isUndefined":152}],10:[function(require,module,exports){ |
| 4399 | 'use strict'; |
| 4400 | |
| 4401 | var OperationGroup = module.exports = function (tag, description, externalDocs, operation) { |
| 4402 | this.description = description; |
| 4403 | this.externalDocs = externalDocs; |
| 4404 | this.name = tag; |
| 4405 | this.operation = operation; |
| 4406 | this.operationsArray = []; |
| 4407 | this.path = tag; |
| 4408 | this.tag = tag; |
| 4409 | }; |
| 4410 | |
| 4411 | OperationGroup.prototype.sort = function () { |
| 4412 | |
| 4413 | }; |
| 4414 | |
| 4415 | |
| 4416 | },{}],11:[function(require,module,exports){ |
| 4417 | |
| 4418 | },{}],12:[function(require,module,exports){ |
| 4419 | /*! |
| 4420 | * The buffer module from node.js, for the browser. |
| 4421 | * |
| 4422 | * @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org> |
| 4423 | * @license MIT |
| 4424 | */ |
| 4425 | |
| 4426 | var base64 = require('base64-js') |
| 4427 | var ieee754 = require('ieee754') |
| 4428 | var isArray = require('is-array') |
| 4429 | |
| 4430 | exports.Buffer = Buffer |
| 4431 | exports.SlowBuffer = SlowBuffer |
| 4432 | exports.INSPECT_MAX_BYTES = 50 |
| 4433 | Buffer.poolSize = 8192 // not used by this implementation |
| 4434 | |
| 4435 | var kMaxLength = 0x3fffffff |
| 4436 | var rootParent = {} |
| 4437 | |
| 4438 | /** |
| 4439 | * If `Buffer.TYPED_ARRAY_SUPPORT`: |
| 4440 | * === true Use Uint8Array implementation (fastest) |
| 4441 | * === false Use Object implementation (most compatible, even IE6) |
| 4442 | * |
| 4443 | * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, |
| 4444 | * Opera 11.6+, iOS 4.2+. |
| 4445 | * |
| 4446 | * Note: |
| 4447 | * |
| 4448 | * - Implementation must support adding new properties to `Uint8Array` instances. |
| 4449 | * Firefox 4-29 lacked support, fixed in Firefox 30+. |
| 4450 | * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. |
| 4451 | * |
| 4452 | * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. |
| 4453 | * |
| 4454 | * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of |
| 4455 | * incorrect length in some situations. |
| 4456 | * |
| 4457 | * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they will |
| 4458 | * get the Object implementation, which is slower but will work correctly. |
| 4459 | */ |
| 4460 | Buffer.TYPED_ARRAY_SUPPORT = (function () { |
| 4461 | try { |
| 4462 | var buf = new ArrayBuffer(0) |
| 4463 | var arr = new Uint8Array(buf) |
| 4464 | arr.foo = function () { return 42 } |
| 4465 | return arr.foo() === 42 && // typed array instances can be augmented |
| 4466 | typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` |
| 4467 | new Uint8Array(1).subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` |
| 4468 | } catch (e) { |
| 4469 | return false |
| 4470 | } |
| 4471 | })() |
| 4472 | |
| 4473 | /** |
| 4474 | * Class: Buffer |
| 4475 | * ============= |
| 4476 | * |
| 4477 | * The Buffer constructor returns instances of `Uint8Array` that are augmented |
| 4478 | * with function properties for all the node `Buffer` API functions. We use |
| 4479 | * `Uint8Array` so that square bracket notation works as expected -- it returns |
| 4480 | * a single octet. |
| 4481 | * |
| 4482 | * By augmenting the instances, we can avoid modifying the `Uint8Array` |
| 4483 | * prototype. |
| 4484 | */ |
| 4485 | function Buffer (subject, encoding) { |
| 4486 | var self = this |
| 4487 | if (!(self instanceof Buffer)) return new Buffer(subject, encoding) |
| 4488 | |
| 4489 | var type = typeof subject |
| 4490 | var length |
| 4491 | |
| 4492 | if (type === 'number') { |
| 4493 | length = +subject |
| 4494 | } else if (type === 'string') { |
| 4495 | length = Buffer.byteLength(subject, encoding) |
| 4496 | } else if (type === 'object' && subject !== null) { |
| 4497 | // assume object is array-like |
| 4498 | if (subject.type === 'Buffer' && isArray(subject.data)) subject = subject.data |
| 4499 | length = +subject.length |
| 4500 | } else { |
| 4501 | throw new TypeError('must start with number, buffer, array or string') |
| 4502 | } |
| 4503 | |
| 4504 | if (length > kMaxLength) { |
| 4505 | throw new RangeError('Attempt to allocate Buffer larger than maximum size: 0x' + |
| 4506 | kMaxLength.toString(16) + ' bytes') |
| 4507 | } |
| 4508 | |
| 4509 | if (length < 0) length = 0 |
| 4510 | else length >>>= 0 // coerce to uint32 |
| 4511 | |
| 4512 | if (Buffer.TYPED_ARRAY_SUPPORT) { |
| 4513 | // Preferred: Return an augmented `Uint8Array` instance for best performance |
| 4514 | self = Buffer._augment(new Uint8Array(length)) // eslint-disable-line consistent-this |
| 4515 | } else { |
| 4516 | // Fallback: Return THIS instance of Buffer (created by `new`) |
| 4517 | self.length = length |
| 4518 | self._isBuffer = true |
| 4519 | } |
| 4520 | |
| 4521 | var i |
| 4522 | if (Buffer.TYPED_ARRAY_SUPPORT && typeof subject.byteLength === 'number') { |
| 4523 | // Speed optimization -- use set if we're copying from a typed array |
| 4524 | self._set(subject) |
| 4525 | } else if (isArrayish(subject)) { |
| 4526 | // Treat array-ish objects as a byte array |
| 4527 | if (Buffer.isBuffer(subject)) { |
| 4528 | for (i = 0; i < length; i++) { |
| 4529 | self[i] = subject.readUInt8(i) |
| 4530 | } |
| 4531 | } else { |
| 4532 | for (i = 0; i < length; i++) { |
| 4533 | self[i] = ((subject[i] % 256) + 256) % 256 |
| 4534 | } |
| 4535 | } |
| 4536 | } else if (type === 'string') { |
| 4537 | self.write(subject, 0, encoding) |
| 4538 | } else if (type === 'number' && !Buffer.TYPED_ARRAY_SUPPORT) { |
| 4539 | for (i = 0; i < length; i++) { |
| 4540 | self[i] = 0 |
| 4541 | } |
| 4542 | } |
| 4543 | |
| 4544 | if (length > 0 && length <= Buffer.poolSize) self.parent = rootParent |
| 4545 | |
| 4546 | return self |
| 4547 | } |
| 4548 | |
| 4549 | function SlowBuffer (subject, encoding) { |
| 4550 | if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding) |
| 4551 | |
| 4552 | var buf = new Buffer(subject, encoding) |
| 4553 | delete buf.parent |
| 4554 | return buf |
| 4555 | } |
| 4556 | |
| 4557 | Buffer.isBuffer = function isBuffer (b) { |
| 4558 | return !!(b != null && b._isBuffer) |
| 4559 | } |
| 4560 | |
| 4561 | Buffer.compare = function compare (a, b) { |
| 4562 | if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { |
| 4563 | throw new TypeError('Arguments must be Buffers') |
| 4564 | } |
| 4565 | |
| 4566 | if (a === b) return 0 |
| 4567 | |
| 4568 | var x = a.length |
| 4569 | var y = b.length |
| 4570 | for (var i = 0, len = Math.min(x, y); i < len && a[i] === b[i]; i++) {} |
| 4571 | if (i !== len) { |
| 4572 | x = a[i] |
| 4573 | y = b[i] |
| 4574 | } |
| 4575 | if (x < y) return -1 |
| 4576 | if (y < x) return 1 |
| 4577 | return 0 |
| 4578 | } |
| 4579 | |
| 4580 | Buffer.isEncoding = function isEncoding (encoding) { |
| 4581 | switch (String(encoding).toLowerCase()) { |
| 4582 | case 'hex': |
| 4583 | case 'utf8': |
| 4584 | case 'utf-8': |
| 4585 | case 'ascii': |
| 4586 | case 'binary': |
| 4587 | case 'base64': |
| 4588 | case 'raw': |
| 4589 | case 'ucs2': |
| 4590 | case 'ucs-2': |
| 4591 | case 'utf16le': |
| 4592 | case 'utf-16le': |
| 4593 | return true |
| 4594 | default: |
| 4595 | return false |
| 4596 | } |
| 4597 | } |
| 4598 | |
| 4599 | Buffer.concat = function concat (list, totalLength) { |
| 4600 | if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.') |
| 4601 | |
| 4602 | if (list.length === 0) { |
| 4603 | return new Buffer(0) |
| 4604 | } else if (list.length === 1) { |
| 4605 | return list[0] |
| 4606 | } |
| 4607 | |
| 4608 | var i |
| 4609 | if (totalLength === undefined) { |
| 4610 | totalLength = 0 |
| 4611 | for (i = 0; i < list.length; i++) { |
| 4612 | totalLength += list[i].length |
| 4613 | } |
| 4614 | } |
| 4615 | |
| 4616 | var buf = new Buffer(totalLength) |
| 4617 | var pos = 0 |
| 4618 | for (i = 0; i < list.length; i++) { |
| 4619 | var item = list[i] |
| 4620 | item.copy(buf, pos) |
| 4621 | pos += item.length |
| 4622 | } |
| 4623 | return buf |
| 4624 | } |
| 4625 | |
| 4626 | Buffer.byteLength = function byteLength (str, encoding) { |
| 4627 | var ret |
| 4628 | str = str + '' |
| 4629 | switch (encoding || 'utf8') { |
| 4630 | case 'ascii': |
| 4631 | case 'binary': |
| 4632 | case 'raw': |
| 4633 | ret = str.length |
| 4634 | break |
| 4635 | case 'ucs2': |
| 4636 | case 'ucs-2': |
| 4637 | case 'utf16le': |
| 4638 | case 'utf-16le': |
| 4639 | ret = str.length * 2 |
| 4640 | break |
| 4641 | case 'hex': |
| 4642 | ret = str.length >>> 1 |
| 4643 | break |
| 4644 | case 'utf8': |
| 4645 | case 'utf-8': |
| 4646 | ret = utf8ToBytes(str).length |
| 4647 | break |
| 4648 | case 'base64': |
| 4649 | ret = base64ToBytes(str).length |
| 4650 | break |
| 4651 | default: |
| 4652 | ret = str.length |
| 4653 | } |
| 4654 | return ret |
| 4655 | } |
| 4656 | |
| 4657 | // pre-set for values that may exist in the future |
| 4658 | Buffer.prototype.length = undefined |
| 4659 | Buffer.prototype.parent = undefined |
| 4660 | |
| 4661 | // toString(encoding, start=0, end=buffer.length) |
| 4662 | Buffer.prototype.toString = function toString (encoding, start, end) { |
| 4663 | var loweredCase = false |
| 4664 | |
| 4665 | start = start >>> 0 |
| 4666 | end = end === undefined || end === Infinity ? this.length : end >>> 0 |
| 4667 | |
| 4668 | if (!encoding) encoding = 'utf8' |
| 4669 | if (start < 0) start = 0 |
| 4670 | if (end > this.length) end = this.length |
| 4671 | if (end <= start) return '' |
| 4672 | |
| 4673 | while (true) { |
| 4674 | switch (encoding) { |
| 4675 | case 'hex': |
| 4676 | return hexSlice(this, start, end) |
| 4677 | |
| 4678 | case 'utf8': |
| 4679 | case 'utf-8': |
| 4680 | return utf8Slice(this, start, end) |
| 4681 | |
| 4682 | case 'ascii': |
| 4683 | return asciiSlice(this, start, end) |
| 4684 | |
| 4685 | case 'binary': |
| 4686 | return binarySlice(this, start, end) |
| 4687 | |
| 4688 | case 'base64': |
| 4689 | return base64Slice(this, start, end) |
| 4690 | |
| 4691 | case 'ucs2': |
| 4692 | case 'ucs-2': |
| 4693 | case 'utf16le': |
| 4694 | case 'utf-16le': |
| 4695 | return utf16leSlice(this, start, end) |
| 4696 | |
| 4697 | default: |
| 4698 | if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) |
| 4699 | encoding = (encoding + '').toLowerCase() |
| 4700 | loweredCase = true |
| 4701 | } |
| 4702 | } |
| 4703 | } |
| 4704 | |
| 4705 | Buffer.prototype.equals = function equals (b) { |
| 4706 | if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') |
| 4707 | if (this === b) return true |
| 4708 | return Buffer.compare(this, b) === 0 |
| 4709 | } |
| 4710 | |
| 4711 | Buffer.prototype.inspect = function inspect () { |
| 4712 | var str = '' |
| 4713 | var max = exports.INSPECT_MAX_BYTES |
| 4714 | if (this.length > 0) { |
| 4715 | str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') |
| 4716 | if (this.length > max) str += ' ... ' |
| 4717 | } |
| 4718 | return '<Buffer ' + str + '>' |
| 4719 | } |
| 4720 | |
| 4721 | Buffer.prototype.compare = function compare (b) { |
| 4722 | if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') |
| 4723 | if (this === b) return 0 |
| 4724 | return Buffer.compare(this, b) |
| 4725 | } |
| 4726 | |
| 4727 | Buffer.prototype.indexOf = function indexOf (val, byteOffset) { |
| 4728 | if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff |
| 4729 | else if (byteOffset < -0x80000000) byteOffset = -0x80000000 |
| 4730 | byteOffset >>= 0 |
| 4731 | |
| 4732 | if (this.length === 0) return -1 |
| 4733 | if (byteOffset >= this.length) return -1 |
| 4734 | |
| 4735 | // Negative offsets start from the end of the buffer |
| 4736 | if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0) |
| 4737 | |
| 4738 | if (typeof val === 'string') { |
| 4739 | if (val.length === 0) return -1 // special case: looking for empty string always fails |
| 4740 | return String.prototype.indexOf.call(this, val, byteOffset) |
| 4741 | } |
| 4742 | if (Buffer.isBuffer(val)) { |
| 4743 | return arrayIndexOf(this, val, byteOffset) |
| 4744 | } |
| 4745 | if (typeof val === 'number') { |
| 4746 | if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') { |
| 4747 | return Uint8Array.prototype.indexOf.call(this, val, byteOffset) |
| 4748 | } |
| 4749 | return arrayIndexOf(this, [ val ], byteOffset) |
| 4750 | } |
| 4751 | |
| 4752 | function arrayIndexOf (arr, val, byteOffset) { |
| 4753 | var foundIndex = -1 |
| 4754 | for (var i = 0; byteOffset + i < arr.length; i++) { |
| 4755 | if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) { |
| 4756 | if (foundIndex === -1) foundIndex = i |
| 4757 | if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex |
| 4758 | } else { |
| 4759 | foundIndex = -1 |
| 4760 | } |
| 4761 | } |
| 4762 | return -1 |
| 4763 | } |
| 4764 | |
| 4765 | throw new TypeError('val must be string, number or Buffer') |
| 4766 | } |
| 4767 | |
| 4768 | // `get` will be removed in Node 0.13+ |
| 4769 | Buffer.prototype.get = function get (offset) { |
| 4770 | console.log('.get() is deprecated. Access using array indexes instead.') |
| 4771 | return this.readUInt8(offset) |
| 4772 | } |
| 4773 | |
| 4774 | // `set` will be removed in Node 0.13+ |
| 4775 | Buffer.prototype.set = function set (v, offset) { |
| 4776 | console.log('.set() is deprecated. Access using array indexes instead.') |
| 4777 | return this.writeUInt8(v, offset) |
| 4778 | } |
| 4779 | |
| 4780 | function hexWrite (buf, string, offset, length) { |
| 4781 | offset = Number(offset) || 0 |
| 4782 | var remaining = buf.length - offset |
| 4783 | if (!length) { |
| 4784 | length = remaining |
| 4785 | } else { |
| 4786 | length = Number(length) |
| 4787 | if (length > remaining) { |
| 4788 | length = remaining |
| 4789 | } |
| 4790 | } |
| 4791 | |
| 4792 | // must be an even number of digits |
| 4793 | var strLen = string.length |
| 4794 | if (strLen % 2 !== 0) throw new Error('Invalid hex string') |
| 4795 | |
| 4796 | if (length > strLen / 2) { |
| 4797 | length = strLen / 2 |
| 4798 | } |
| 4799 | for (var i = 0; i < length; i++) { |
| 4800 | var parsed = parseInt(string.substr(i * 2, 2), 16) |
| 4801 | if (isNaN(parsed)) throw new Error('Invalid hex string') |
| 4802 | buf[offset + i] = parsed |
| 4803 | } |
| 4804 | return i |
| 4805 | } |
| 4806 | |
| 4807 | function utf8Write (buf, string, offset, length) { |
| 4808 | var charsWritten = blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) |
| 4809 | return charsWritten |
| 4810 | } |
| 4811 | |
| 4812 | function asciiWrite (buf, string, offset, length) { |
| 4813 | var charsWritten = blitBuffer(asciiToBytes(string), buf, offset, length) |
| 4814 | return charsWritten |
| 4815 | } |
| 4816 | |
| 4817 | function binaryWrite (buf, string, offset, length) { |
| 4818 | return asciiWrite(buf, string, offset, length) |
| 4819 | } |
| 4820 | |
| 4821 | function base64Write (buf, string, offset, length) { |
| 4822 | var charsWritten = blitBuffer(base64ToBytes(string), buf, offset, length) |
| 4823 | return charsWritten |
| 4824 | } |
| 4825 | |
| 4826 | function utf16leWrite (buf, string, offset, length) { |
| 4827 | var charsWritten = blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) |
| 4828 | return charsWritten |
| 4829 | } |
| 4830 | |
| 4831 | Buffer.prototype.write = function write (string, offset, length, encoding) { |
| 4832 | // Support both (string, offset, length, encoding) |
| 4833 | // and the legacy (string, encoding, offset, length) |
| 4834 | if (isFinite(offset)) { |
| 4835 | if (!isFinite(length)) { |
| 4836 | encoding = length |
| 4837 | length = undefined |
| 4838 | } |
| 4839 | } else { // legacy |
| 4840 | var swap = encoding |
| 4841 | encoding = offset |
| 4842 | offset = length |
| 4843 | length = swap |
| 4844 | } |
| 4845 | |
| 4846 | offset = Number(offset) || 0 |
| 4847 | |
| 4848 | if (length < 0 || offset < 0 || offset > this.length) { |
| 4849 | throw new RangeError('attempt to write outside buffer bounds') |
| 4850 | } |
| 4851 | |
| 4852 | var remaining = this.length - offset |
| 4853 | if (!length) { |
| 4854 | length = remaining |
| 4855 | } else { |
| 4856 | length = Number(length) |
| 4857 | if (length > remaining) { |
| 4858 | length = remaining |
| 4859 | } |
| 4860 | } |
| 4861 | encoding = String(encoding || 'utf8').toLowerCase() |
| 4862 | |
| 4863 | var ret |
| 4864 | switch (encoding) { |
| 4865 | case 'hex': |
| 4866 | ret = hexWrite(this, string, offset, length) |
| 4867 | break |
| 4868 | case 'utf8': |
| 4869 | case 'utf-8': |
| 4870 | ret = utf8Write(this, string, offset, length) |
| 4871 | break |
| 4872 | case 'ascii': |
| 4873 | ret = asciiWrite(this, string, offset, length) |
| 4874 | break |
| 4875 | case 'binary': |
| 4876 | ret = binaryWrite(this, string, offset, length) |
| 4877 | break |
| 4878 | case 'base64': |
| 4879 | ret = base64Write(this, string, offset, length) |
| 4880 | break |
| 4881 | case 'ucs2': |
| 4882 | case 'ucs-2': |
| 4883 | case 'utf16le': |
| 4884 | case 'utf-16le': |
| 4885 | ret = utf16leWrite(this, string, offset, length) |
| 4886 | break |
| 4887 | default: |
| 4888 | throw new TypeError('Unknown encoding: ' + encoding) |
| 4889 | } |
| 4890 | return ret |
| 4891 | } |
| 4892 | |
| 4893 | Buffer.prototype.toJSON = function toJSON () { |
| 4894 | return { |
| 4895 | type: 'Buffer', |
| 4896 | data: Array.prototype.slice.call(this._arr || this, 0) |
| 4897 | } |
| 4898 | } |
| 4899 | |
| 4900 | function base64Slice (buf, start, end) { |
| 4901 | if (start === 0 && end === buf.length) { |
| 4902 | return base64.fromByteArray(buf) |
| 4903 | } else { |
| 4904 | return base64.fromByteArray(buf.slice(start, end)) |
| 4905 | } |
| 4906 | } |
| 4907 | |
| 4908 | function utf8Slice (buf, start, end) { |
| 4909 | var res = '' |
| 4910 | var tmp = '' |
| 4911 | end = Math.min(buf.length, end) |
| 4912 | |
| 4913 | for (var i = start; i < end; i++) { |
| 4914 | if (buf[i] <= 0x7F) { |
| 4915 | res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i]) |
| 4916 | tmp = '' |
| 4917 | } else { |
| 4918 | tmp += '%' + buf[i].toString(16) |
| 4919 | } |
| 4920 | } |
| 4921 | |
| 4922 | return res + decodeUtf8Char(tmp) |
| 4923 | } |
| 4924 | |
| 4925 | function asciiSlice (buf, start, end) { |
| 4926 | var ret = '' |
| 4927 | end = Math.min(buf.length, end) |
| 4928 | |
| 4929 | for (var i = start; i < end; i++) { |
| 4930 | ret += String.fromCharCode(buf[i] & 0x7F) |
| 4931 | } |
| 4932 | return ret |
| 4933 | } |
| 4934 | |
| 4935 | function binarySlice (buf, start, end) { |
| 4936 | var ret = '' |
| 4937 | end = Math.min(buf.length, end) |
| 4938 | |
| 4939 | for (var i = start; i < end; i++) { |
| 4940 | ret += String.fromCharCode(buf[i]) |
| 4941 | } |
| 4942 | return ret |
| 4943 | } |
| 4944 | |
| 4945 | function hexSlice (buf, start, end) { |
| 4946 | var len = buf.length |
| 4947 | |
| 4948 | if (!start || start < 0) start = 0 |
| 4949 | if (!end || end < 0 || end > len) end = len |
| 4950 | |
| 4951 | var out = '' |
| 4952 | for (var i = start; i < end; i++) { |
| 4953 | out += toHex(buf[i]) |
| 4954 | } |
| 4955 | return out |
| 4956 | } |
| 4957 | |
| 4958 | function utf16leSlice (buf, start, end) { |
| 4959 | var bytes = buf.slice(start, end) |
| 4960 | var res = '' |
| 4961 | for (var i = 0; i < bytes.length; i += 2) { |
| 4962 | res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) |
| 4963 | } |
| 4964 | return res |
| 4965 | } |
| 4966 | |
| 4967 | Buffer.prototype.slice = function slice (start, end) { |
| 4968 | var len = this.length |
| 4969 | start = ~~start |
| 4970 | end = end === undefined ? len : ~~end |
| 4971 | |
| 4972 | if (start < 0) { |
| 4973 | start += len |
| 4974 | if (start < 0) start = 0 |
| 4975 | } else if (start > len) { |
| 4976 | start = len |
| 4977 | } |
| 4978 | |
| 4979 | if (end < 0) { |
| 4980 | end += len |
| 4981 | if (end < 0) end = 0 |
| 4982 | } else if (end > len) { |
| 4983 | end = len |
| 4984 | } |
| 4985 | |
| 4986 | if (end < start) end = start |
| 4987 | |
| 4988 | var newBuf |
| 4989 | if (Buffer.TYPED_ARRAY_SUPPORT) { |
| 4990 | newBuf = Buffer._augment(this.subarray(start, end)) |
| 4991 | } else { |
| 4992 | var sliceLen = end - start |
| 4993 | newBuf = new Buffer(sliceLen, undefined) |
| 4994 | for (var i = 0; i < sliceLen; i++) { |
| 4995 | newBuf[i] = this[i + start] |
| 4996 | } |
| 4997 | } |
| 4998 | |
| 4999 | if (newBuf.length) newBuf.parent = this.parent || this |
| 5000 | |
| 5001 | return newBuf |
| 5002 | } |
| 5003 | |
| 5004 | /* |
| 5005 | * Need to make sure that buffer isn't trying to write out of bounds. |
| 5006 | */ |
| 5007 | function checkOffset (offset, ext, length) { |
| 5008 | if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') |
| 5009 | if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') |
| 5010 | } |
| 5011 | |
| 5012 | Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { |
| 5013 | offset = offset >>> 0 |
| 5014 | byteLength = byteLength >>> 0 |
| 5015 | if (!noAssert) checkOffset(offset, byteLength, this.length) |
| 5016 | |
| 5017 | var val = this[offset] |
| 5018 | var mul = 1 |
| 5019 | var i = 0 |
| 5020 | while (++i < byteLength && (mul *= 0x100)) { |
| 5021 | val += this[offset + i] * mul |
| 5022 | } |
| 5023 | |
| 5024 | return val |
| 5025 | } |
| 5026 | |
| 5027 | Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { |
| 5028 | offset = offset >>> 0 |
| 5029 | byteLength = byteLength >>> 0 |
| 5030 | if (!noAssert) { |
| 5031 | checkOffset(offset, byteLength, this.length) |
| 5032 | } |
| 5033 | |
| 5034 | var val = this[offset + --byteLength] |
| 5035 | var mul = 1 |
| 5036 | while (byteLength > 0 && (mul *= 0x100)) { |
| 5037 | val += this[offset + --byteLength] * mul |
| 5038 | } |
| 5039 | |
| 5040 | return val |
| 5041 | } |
| 5042 | |
| 5043 | Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { |
| 5044 | if (!noAssert) checkOffset(offset, 1, this.length) |
| 5045 | return this[offset] |
| 5046 | } |
| 5047 | |
| 5048 | Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { |
| 5049 | if (!noAssert) checkOffset(offset, 2, this.length) |
| 5050 | return this[offset] | (this[offset + 1] << 8) |
| 5051 | } |
| 5052 | |
| 5053 | Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { |
| 5054 | if (!noAssert) checkOffset(offset, 2, this.length) |
| 5055 | return (this[offset] << 8) | this[offset + 1] |
| 5056 | } |
| 5057 | |
| 5058 | Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { |
| 5059 | if (!noAssert) checkOffset(offset, 4, this.length) |
| 5060 | |
| 5061 | return ((this[offset]) | |
| 5062 | (this[offset + 1] << 8) | |
| 5063 | (this[offset + 2] << 16)) + |
| 5064 | (this[offset + 3] * 0x1000000) |
| 5065 | } |
| 5066 | |
| 5067 | Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { |
| 5068 | if (!noAssert) checkOffset(offset, 4, this.length) |
| 5069 | |
| 5070 | return (this[offset] * 0x1000000) + |
| 5071 | ((this[offset + 1] << 16) | |
| 5072 | (this[offset + 2] << 8) | |
| 5073 | this[offset + 3]) |
| 5074 | } |
| 5075 | |
| 5076 | Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { |
| 5077 | offset = offset >>> 0 |
| 5078 | byteLength = byteLength >>> 0 |
| 5079 | if (!noAssert) checkOffset(offset, byteLength, this.length) |
| 5080 | |
| 5081 | var val = this[offset] |
| 5082 | var mul = 1 |
| 5083 | var i = 0 |
| 5084 | while (++i < byteLength && (mul *= 0x100)) { |
| 5085 | val += this[offset + i] * mul |
| 5086 | } |
| 5087 | mul *= 0x80 |
| 5088 | |
| 5089 | if (val >= mul) val -= Math.pow(2, 8 * byteLength) |
| 5090 | |
| 5091 | return val |
| 5092 | } |
| 5093 | |
| 5094 | Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { |
| 5095 | offset = offset >>> 0 |
| 5096 | byteLength = byteLength >>> 0 |
| 5097 | if (!noAssert) checkOffset(offset, byteLength, this.length) |
| 5098 | |
| 5099 | var i = byteLength |
| 5100 | var mul = 1 |
| 5101 | var val = this[offset + --i] |
| 5102 | while (i > 0 && (mul *= 0x100)) { |
| 5103 | val += this[offset + --i] * mul |
| 5104 | } |
| 5105 | mul *= 0x80 |
| 5106 | |
| 5107 | if (val >= mul) val -= Math.pow(2, 8 * byteLength) |
| 5108 | |
| 5109 | return val |
| 5110 | } |
| 5111 | |
| 5112 | Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { |
| 5113 | if (!noAssert) checkOffset(offset, 1, this.length) |
| 5114 | if (!(this[offset] & 0x80)) return (this[offset]) |
| 5115 | return ((0xff - this[offset] + 1) * -1) |
| 5116 | } |
| 5117 | |
| 5118 | Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { |
| 5119 | if (!noAssert) checkOffset(offset, 2, this.length) |
| 5120 | var val = this[offset] | (this[offset + 1] << 8) |
| 5121 | return (val & 0x8000) ? val | 0xFFFF0000 : val |
| 5122 | } |
| 5123 | |
| 5124 | Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { |
| 5125 | if (!noAssert) checkOffset(offset, 2, this.length) |
| 5126 | var val = this[offset + 1] | (this[offset] << 8) |
| 5127 | return (val & 0x8000) ? val | 0xFFFF0000 : val |
| 5128 | } |
| 5129 | |
| 5130 | Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { |
| 5131 | if (!noAssert) checkOffset(offset, 4, this.length) |
| 5132 | |
| 5133 | return (this[offset]) | |
| 5134 | (this[offset + 1] << 8) | |
| 5135 | (this[offset + 2] << 16) | |
| 5136 | (this[offset + 3] << 24) |
| 5137 | } |
| 5138 | |
| 5139 | Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { |
| 5140 | if (!noAssert) checkOffset(offset, 4, this.length) |
| 5141 | |
| 5142 | return (this[offset] << 24) | |
| 5143 | (this[offset + 1] << 16) | |
| 5144 | (this[offset + 2] << 8) | |
| 5145 | (this[offset + 3]) |
| 5146 | } |
| 5147 | |
| 5148 | Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { |
| 5149 | if (!noAssert) checkOffset(offset, 4, this.length) |
| 5150 | return ieee754.read(this, offset, true, 23, 4) |
| 5151 | } |
| 5152 | |
| 5153 | Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { |
| 5154 | if (!noAssert) checkOffset(offset, 4, this.length) |
| 5155 | return ieee754.read(this, offset, false, 23, 4) |
| 5156 | } |
| 5157 | |
| 5158 | Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { |
| 5159 | if (!noAssert) checkOffset(offset, 8, this.length) |
| 5160 | return ieee754.read(this, offset, true, 52, 8) |
| 5161 | } |
| 5162 | |
| 5163 | Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { |
| 5164 | if (!noAssert) checkOffset(offset, 8, this.length) |
| 5165 | return ieee754.read(this, offset, false, 52, 8) |
| 5166 | } |
| 5167 | |
| 5168 | function checkInt (buf, value, offset, ext, max, min) { |
| 5169 | if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance') |
| 5170 | if (value > max || value < min) throw new RangeError('value is out of bounds') |
| 5171 | if (offset + ext > buf.length) throw new RangeError('index out of range') |
| 5172 | } |
| 5173 | |
| 5174 | Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { |
| 5175 | value = +value |
| 5176 | offset = offset >>> 0 |
| 5177 | byteLength = byteLength >>> 0 |
| 5178 | if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) |
| 5179 | |
| 5180 | var mul = 1 |
| 5181 | var i = 0 |
| 5182 | this[offset] = value & 0xFF |
| 5183 | while (++i < byteLength && (mul *= 0x100)) { |
| 5184 | this[offset + i] = (value / mul) >>> 0 & 0xFF |
| 5185 | } |
| 5186 | |
| 5187 | return offset + byteLength |
| 5188 | } |
| 5189 | |
| 5190 | Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { |
| 5191 | value = +value |
| 5192 | offset = offset >>> 0 |
| 5193 | byteLength = byteLength >>> 0 |
| 5194 | if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) |
| 5195 | |
| 5196 | var i = byteLength - 1 |
| 5197 | var mul = 1 |
| 5198 | this[offset + i] = value & 0xFF |
| 5199 | while (--i >= 0 && (mul *= 0x100)) { |
| 5200 | this[offset + i] = (value / mul) >>> 0 & 0xFF |
| 5201 | } |
| 5202 | |
| 5203 | return offset + byteLength |
| 5204 | } |
| 5205 | |
| 5206 | Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { |
| 5207 | value = +value |
| 5208 | offset = offset >>> 0 |
| 5209 | if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) |
| 5210 | if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) |
| 5211 | this[offset] = value |
| 5212 | return offset + 1 |
| 5213 | } |
| 5214 | |
| 5215 | function objectWriteUInt16 (buf, value, offset, littleEndian) { |
| 5216 | if (value < 0) value = 0xffff + value + 1 |
| 5217 | for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) { |
| 5218 | buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> |
| 5219 | (littleEndian ? i : 1 - i) * 8 |
| 5220 | } |
| 5221 | } |
| 5222 | |
| 5223 | Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { |
| 5224 | value = +value |
| 5225 | offset = offset >>> 0 |
| 5226 | if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) |
| 5227 | if (Buffer.TYPED_ARRAY_SUPPORT) { |
| 5228 | this[offset] = value |
| 5229 | this[offset + 1] = (value >>> 8) |
| 5230 | } else { |
| 5231 | objectWriteUInt16(this, value, offset, true) |
| 5232 | } |
| 5233 | return offset + 2 |
| 5234 | } |
| 5235 | |
| 5236 | Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { |
| 5237 | value = +value |
| 5238 | offset = offset >>> 0 |
| 5239 | if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) |
| 5240 | if (Buffer.TYPED_ARRAY_SUPPORT) { |
| 5241 | this[offset] = (value >>> 8) |
| 5242 | this[offset + 1] = value |
| 5243 | } else { |
| 5244 | objectWriteUInt16(this, value, offset, false) |
| 5245 | } |
| 5246 | return offset + 2 |
| 5247 | } |
| 5248 | |
| 5249 | function objectWriteUInt32 (buf, value, offset, littleEndian) { |
| 5250 | if (value < 0) value = 0xffffffff + value + 1 |
| 5251 | for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) { |
| 5252 | buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff |
| 5253 | } |
| 5254 | } |
| 5255 | |
| 5256 | Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { |
| 5257 | value = +value |
| 5258 | offset = offset >>> 0 |
| 5259 | if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) |
| 5260 | if (Buffer.TYPED_ARRAY_SUPPORT) { |
| 5261 | this[offset + 3] = (value >>> 24) |
| 5262 | this[offset + 2] = (value >>> 16) |
| 5263 | this[offset + 1] = (value >>> 8) |
| 5264 | this[offset] = value |
| 5265 | } else { |
| 5266 | objectWriteUInt32(this, value, offset, true) |
| 5267 | } |
| 5268 | return offset + 4 |
| 5269 | } |
| 5270 | |
| 5271 | Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { |
| 5272 | value = +value |
| 5273 | offset = offset >>> 0 |
| 5274 | if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) |
| 5275 | if (Buffer.TYPED_ARRAY_SUPPORT) { |
| 5276 | this[offset] = (value >>> 24) |
| 5277 | this[offset + 1] = (value >>> 16) |
| 5278 | this[offset + 2] = (value >>> 8) |
| 5279 | this[offset + 3] = value |
| 5280 | } else { |
| 5281 | objectWriteUInt32(this, value, offset, false) |
| 5282 | } |
| 5283 | return offset + 4 |
| 5284 | } |
| 5285 | |
| 5286 | Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { |
| 5287 | value = +value |
| 5288 | offset = offset >>> 0 |
| 5289 | if (!noAssert) { |
| 5290 | checkInt( |
| 5291 | this, value, offset, byteLength, |
| 5292 | Math.pow(2, 8 * byteLength - 1) - 1, |
| 5293 | -Math.pow(2, 8 * byteLength - 1) |
| 5294 | ) |
| 5295 | } |
| 5296 | |
| 5297 | var i = 0 |
| 5298 | var mul = 1 |
| 5299 | var sub = value < 0 ? 1 : 0 |
| 5300 | this[offset] = value & 0xFF |
| 5301 | while (++i < byteLength && (mul *= 0x100)) { |
| 5302 | this[offset + i] = ((value / mul) >> 0) - sub & 0xFF |
| 5303 | } |
| 5304 | |
| 5305 | return offset + byteLength |
| 5306 | } |
| 5307 | |
| 5308 | Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { |
| 5309 | value = +value |
| 5310 | offset = offset >>> 0 |
| 5311 | if (!noAssert) { |
| 5312 | checkInt( |
| 5313 | this, value, offset, byteLength, |
| 5314 | Math.pow(2, 8 * byteLength - 1) - 1, |
| 5315 | -Math.pow(2, 8 * byteLength - 1) |
| 5316 | ) |
| 5317 | } |
| 5318 | |
| 5319 | var i = byteLength - 1 |
| 5320 | var mul = 1 |
| 5321 | var sub = value < 0 ? 1 : 0 |
| 5322 | this[offset + i] = value & 0xFF |
| 5323 | while (--i >= 0 && (mul *= 0x100)) { |
| 5324 | this[offset + i] = ((value / mul) >> 0) - sub & 0xFF |
| 5325 | } |
| 5326 | |
| 5327 | return offset + byteLength |
| 5328 | } |
| 5329 | |
| 5330 | Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { |
| 5331 | value = +value |
| 5332 | offset = offset >>> 0 |
| 5333 | if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) |
| 5334 | if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) |
| 5335 | if (value < 0) value = 0xff + value + 1 |
| 5336 | this[offset] = value |
| 5337 | return offset + 1 |
| 5338 | } |
| 5339 | |
| 5340 | Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { |
| 5341 | value = +value |
| 5342 | offset = offset >>> 0 |
| 5343 | if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) |
| 5344 | if (Buffer.TYPED_ARRAY_SUPPORT) { |
| 5345 | this[offset] = value |
| 5346 | this[offset + 1] = (value >>> 8) |
| 5347 | } else { |
| 5348 | objectWriteUInt16(this, value, offset, true) |
| 5349 | } |
| 5350 | return offset + 2 |
| 5351 | } |
| 5352 | |
| 5353 | Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { |
| 5354 | value = +value |
| 5355 | offset = offset >>> 0 |
| 5356 | if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) |
| 5357 | if (Buffer.TYPED_ARRAY_SUPPORT) { |
| 5358 | this[offset] = (value >>> 8) |
| 5359 | this[offset + 1] = value |
| 5360 | } else { |
| 5361 | objectWriteUInt16(this, value, offset, false) |
| 5362 | } |
| 5363 | return offset + 2 |
| 5364 | } |
| 5365 | |
| 5366 | Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { |
| 5367 | value = +value |
| 5368 | offset = offset >>> 0 |
| 5369 | if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) |
| 5370 | if (Buffer.TYPED_ARRAY_SUPPORT) { |
| 5371 | this[offset] = value |
| 5372 | this[offset + 1] = (value >>> 8) |
| 5373 | this[offset + 2] = (value >>> 16) |
| 5374 | this[offset + 3] = (value >>> 24) |
| 5375 | } else { |
| 5376 | objectWriteUInt32(this, value, offset, true) |
| 5377 | } |
| 5378 | return offset + 4 |
| 5379 | } |
| 5380 | |
| 5381 | Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { |
| 5382 | value = +value |
| 5383 | offset = offset >>> 0 |
| 5384 | if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) |
| 5385 | if (value < 0) value = 0xffffffff + value + 1 |
| 5386 | if (Buffer.TYPED_ARRAY_SUPPORT) { |
| 5387 | this[offset] = (value >>> 24) |
| 5388 | this[offset + 1] = (value >>> 16) |
| 5389 | this[offset + 2] = (value >>> 8) |
| 5390 | this[offset + 3] = value |
| 5391 | } else { |
| 5392 | objectWriteUInt32(this, value, offset, false) |
| 5393 | } |
| 5394 | return offset + 4 |
| 5395 | } |
| 5396 | |
| 5397 | function checkIEEE754 (buf, value, offset, ext, max, min) { |
| 5398 | if (value > max || value < min) throw new RangeError('value is out of bounds') |
| 5399 | if (offset + ext > buf.length) throw new RangeError('index out of range') |
| 5400 | if (offset < 0) throw new RangeError('index out of range') |
| 5401 | } |
| 5402 | |
| 5403 | function writeFloat (buf, value, offset, littleEndian, noAssert) { |
| 5404 | if (!noAssert) { |
| 5405 | checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) |
| 5406 | } |
| 5407 | ieee754.write(buf, value, offset, littleEndian, 23, 4) |
| 5408 | return offset + 4 |
| 5409 | } |
| 5410 | |
| 5411 | Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { |
| 5412 | return writeFloat(this, value, offset, true, noAssert) |
| 5413 | } |
| 5414 | |
| 5415 | Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { |
| 5416 | return writeFloat(this, value, offset, false, noAssert) |
| 5417 | } |
| 5418 | |
| 5419 | function writeDouble (buf, value, offset, littleEndian, noAssert) { |
| 5420 | if (!noAssert) { |
| 5421 | checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) |
| 5422 | } |
| 5423 | ieee754.write(buf, value, offset, littleEndian, 52, 8) |
| 5424 | return offset + 8 |
| 5425 | } |
| 5426 | |
| 5427 | Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { |
| 5428 | return writeDouble(this, value, offset, true, noAssert) |
| 5429 | } |
| 5430 | |
| 5431 | Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { |
| 5432 | return writeDouble(this, value, offset, false, noAssert) |
| 5433 | } |
| 5434 | |
| 5435 | // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) |
| 5436 | Buffer.prototype.copy = function copy (target, target_start, start, end) { |
| 5437 | if (!start) start = 0 |
| 5438 | if (!end && end !== 0) end = this.length |
| 5439 | if (target_start >= target.length) target_start = target.length |
| 5440 | if (!target_start) target_start = 0 |
| 5441 | if (end > 0 && end < start) end = start |
| 5442 | |
| 5443 | // Copy 0 bytes; we're done |
| 5444 | if (end === start) return 0 |
| 5445 | if (target.length === 0 || this.length === 0) return 0 |
| 5446 | |
| 5447 | // Fatal error conditions |
| 5448 | if (target_start < 0) { |
| 5449 | throw new RangeError('targetStart out of bounds') |
| 5450 | } |
| 5451 | if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') |
| 5452 | if (end < 0) throw new RangeError('sourceEnd out of bounds') |
| 5453 | |
| 5454 | // Are we oob? |
| 5455 | if (end > this.length) end = this.length |
| 5456 | if (target.length - target_start < end - start) { |
| 5457 | end = target.length - target_start + start |
| 5458 | } |
| 5459 | |
| 5460 | var len = end - start |
| 5461 | |
| 5462 | if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { |
| 5463 | for (var i = 0; i < len; i++) { |
| 5464 | target[i + target_start] = this[i + start] |
| 5465 | } |
| 5466 | } else { |
| 5467 | target._set(this.subarray(start, start + len), target_start) |
| 5468 | } |
| 5469 | |
| 5470 | return len |
| 5471 | } |
| 5472 | |
| 5473 | // fill(value, start=0, end=buffer.length) |
| 5474 | Buffer.prototype.fill = function fill (value, start, end) { |
| 5475 | if (!value) value = 0 |
| 5476 | if (!start) start = 0 |
| 5477 | if (!end) end = this.length |
| 5478 | |
| 5479 | if (end < start) throw new RangeError('end < start') |
| 5480 | |
| 5481 | // Fill 0 bytes; we're done |
| 5482 | if (end === start) return |
| 5483 | if (this.length === 0) return |
| 5484 | |
| 5485 | if (start < 0 || start >= this.length) throw new RangeError('start out of bounds') |
| 5486 | if (end < 0 || end > this.length) throw new RangeError('end out of bounds') |
| 5487 | |
| 5488 | var i |
| 5489 | if (typeof value === 'number') { |
| 5490 | for (i = start; i < end; i++) { |
| 5491 | this[i] = value |
| 5492 | } |
| 5493 | } else { |
| 5494 | var bytes = utf8ToBytes(value.toString()) |
| 5495 | var len = bytes.length |
| 5496 | for (i = start; i < end; i++) { |
| 5497 | this[i] = bytes[i % len] |
| 5498 | } |
| 5499 | } |
| 5500 | |
| 5501 | return this |
| 5502 | } |
| 5503 | |
| 5504 | /** |
| 5505 | * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance. |
| 5506 | * Added in Node 0.12. Only available in browsers that support ArrayBuffer. |
| 5507 | */ |
| 5508 | Buffer.prototype.toArrayBuffer = function toArrayBuffer () { |
| 5509 | if (typeof Uint8Array !== 'undefined') { |
| 5510 | if (Buffer.TYPED_ARRAY_SUPPORT) { |
| 5511 | return (new Buffer(this)).buffer |
| 5512 | } else { |
| 5513 | var buf = new Uint8Array(this.length) |
| 5514 | for (var i = 0, len = buf.length; i < len; i += 1) { |
| 5515 | buf[i] = this[i] |
| 5516 | } |
| 5517 | return buf.buffer |
| 5518 | } |
| 5519 | } else { |
| 5520 | throw new TypeError('Buffer.toArrayBuffer not supported in this browser') |
| 5521 | } |
| 5522 | } |
| 5523 | |
| 5524 | // HELPER FUNCTIONS |
| 5525 | // ================ |
| 5526 | |
| 5527 | var BP = Buffer.prototype |
| 5528 | |
| 5529 | /** |
| 5530 | * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods |
| 5531 | */ |
| 5532 | Buffer._augment = function _augment (arr) { |
| 5533 | arr.constructor = Buffer |
| 5534 | arr._isBuffer = true |
| 5535 | |
| 5536 | // save reference to original Uint8Array set method before overwriting |
| 5537 | arr._set = arr.set |
| 5538 | |
| 5539 | // deprecated, will be removed in node 0.13+ |
| 5540 | arr.get = BP.get |
| 5541 | arr.set = BP.set |
| 5542 | |
| 5543 | arr.write = BP.write |
| 5544 | arr.toString = BP.toString |
| 5545 | arr.toLocaleString = BP.toString |
| 5546 | arr.toJSON = BP.toJSON |
| 5547 | arr.equals = BP.equals |
| 5548 | arr.compare = BP.compare |
| 5549 | arr.indexOf = BP.indexOf |
| 5550 | arr.copy = BP.copy |
| 5551 | arr.slice = BP.slice |
| 5552 | arr.readUIntLE = BP.readUIntLE |
| 5553 | arr.readUIntBE = BP.readUIntBE |
| 5554 | arr.readUInt8 = BP.readUInt8 |
| 5555 | arr.readUInt16LE = BP.readUInt16LE |
| 5556 | arr.readUInt16BE = BP.readUInt16BE |
| 5557 | arr.readUInt32LE = BP.readUInt32LE |
| 5558 | arr.readUInt32BE = BP.readUInt32BE |
| 5559 | arr.readIntLE = BP.readIntLE |
| 5560 | arr.readIntBE = BP.readIntBE |
| 5561 | arr.readInt8 = BP.readInt8 |
| 5562 | arr.readInt16LE = BP.readInt16LE |
| 5563 | arr.readInt16BE = BP.readInt16BE |
| 5564 | arr.readInt32LE = BP.readInt32LE |
| 5565 | arr.readInt32BE = BP.readInt32BE |
| 5566 | arr.readFloatLE = BP.readFloatLE |
| 5567 | arr.readFloatBE = BP.readFloatBE |
| 5568 | arr.readDoubleLE = BP.readDoubleLE |
| 5569 | arr.readDoubleBE = BP.readDoubleBE |
| 5570 | arr.writeUInt8 = BP.writeUInt8 |
| 5571 | arr.writeUIntLE = BP.writeUIntLE |
| 5572 | arr.writeUIntBE = BP.writeUIntBE |
| 5573 | arr.writeUInt16LE = BP.writeUInt16LE |
| 5574 | arr.writeUInt16BE = BP.writeUInt16BE |
| 5575 | arr.writeUInt32LE = BP.writeUInt32LE |
| 5576 | arr.writeUInt32BE = BP.writeUInt32BE |
| 5577 | arr.writeIntLE = BP.writeIntLE |
| 5578 | arr.writeIntBE = BP.writeIntBE |
| 5579 | arr.writeInt8 = BP.writeInt8 |
| 5580 | arr.writeInt16LE = BP.writeInt16LE |
| 5581 | arr.writeInt16BE = BP.writeInt16BE |
| 5582 | arr.writeInt32LE = BP.writeInt32LE |
| 5583 | arr.writeInt32BE = BP.writeInt32BE |
| 5584 | arr.writeFloatLE = BP.writeFloatLE |
| 5585 | arr.writeFloatBE = BP.writeFloatBE |
| 5586 | arr.writeDoubleLE = BP.writeDoubleLE |
| 5587 | arr.writeDoubleBE = BP.writeDoubleBE |
| 5588 | arr.fill = BP.fill |
| 5589 | arr.inspect = BP.inspect |
| 5590 | arr.toArrayBuffer = BP.toArrayBuffer |
| 5591 | |
| 5592 | return arr |
| 5593 | } |
| 5594 | |
| 5595 | var INVALID_BASE64_RE = /[^+\/0-9A-z\-]/g |
| 5596 | |
| 5597 | function base64clean (str) { |
| 5598 | // Node strips out invalid characters like \n and \t from the string, base64-js does not |
| 5599 | str = stringtrim(str).replace(INVALID_BASE64_RE, '') |
| 5600 | // Node converts strings with length < 2 to '' |
| 5601 | if (str.length < 2) return '' |
| 5602 | // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not |
| 5603 | while (str.length % 4 !== 0) { |
| 5604 | str = str + '=' |
| 5605 | } |
| 5606 | return str |
| 5607 | } |
| 5608 | |
| 5609 | function stringtrim (str) { |
| 5610 | if (str.trim) return str.trim() |
| 5611 | return str.replace(/^\s+|\s+$/g, '') |
| 5612 | } |
| 5613 | |
| 5614 | function isArrayish (subject) { |
| 5615 | return isArray(subject) || Buffer.isBuffer(subject) || |
| 5616 | subject && typeof subject === 'object' && |
| 5617 | typeof subject.length === 'number' |
| 5618 | } |
| 5619 | |
| 5620 | function toHex (n) { |
| 5621 | if (n < 16) return '0' + n.toString(16) |
| 5622 | return n.toString(16) |
| 5623 | } |
| 5624 | |
| 5625 | function utf8ToBytes (string, units) { |
| 5626 | units = units || Infinity |
| 5627 | var codePoint |
| 5628 | var length = string.length |
| 5629 | var leadSurrogate = null |
| 5630 | var bytes = [] |
| 5631 | var i = 0 |
| 5632 | |
| 5633 | for (; i < length; i++) { |
| 5634 | codePoint = string.charCodeAt(i) |
| 5635 | |
| 5636 | // is surrogate component |
| 5637 | if (codePoint > 0xD7FF && codePoint < 0xE000) { |
| 5638 | // last char was a lead |
| 5639 | if (leadSurrogate) { |
| 5640 | // 2 leads in a row |
| 5641 | if (codePoint < 0xDC00) { |
| 5642 | if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) |
| 5643 | leadSurrogate = codePoint |
| 5644 | continue |
| 5645 | } else { |
| 5646 | // valid surrogate pair |
| 5647 | codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000 |
| 5648 | leadSurrogate = null |
| 5649 | } |
| 5650 | } else { |
| 5651 | // no lead yet |
| 5652 | |
| 5653 | if (codePoint > 0xDBFF) { |
| 5654 | // unexpected trail |
| 5655 | if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) |
| 5656 | continue |
| 5657 | } else if (i + 1 === length) { |
| 5658 | // unpaired lead |
| 5659 | if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) |
| 5660 | continue |
| 5661 | } else { |
| 5662 | // valid lead |
| 5663 | leadSurrogate = codePoint |
| 5664 | continue |
| 5665 | } |
| 5666 | } |
| 5667 | } else if (leadSurrogate) { |
| 5668 | // valid bmp char, but last char was a lead |
| 5669 | if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) |
| 5670 | leadSurrogate = null |
| 5671 | } |
| 5672 | |
| 5673 | // encode utf8 |
| 5674 | if (codePoint < 0x80) { |
| 5675 | if ((units -= 1) < 0) break |
| 5676 | bytes.push(codePoint) |
| 5677 | } else if (codePoint < 0x800) { |
| 5678 | if ((units -= 2) < 0) break |
| 5679 | bytes.push( |
| 5680 | codePoint >> 0x6 | 0xC0, |
| 5681 | codePoint & 0x3F | 0x80 |
| 5682 | ) |
| 5683 | } else if (codePoint < 0x10000) { |
| 5684 | if ((units -= 3) < 0) break |
| 5685 | bytes.push( |
| 5686 | codePoint >> 0xC | 0xE0, |
| 5687 | codePoint >> 0x6 & 0x3F | 0x80, |
| 5688 | codePoint & 0x3F | 0x80 |
| 5689 | ) |
| 5690 | } else if (codePoint < 0x200000) { |
| 5691 | if ((units -= 4) < 0) break |
| 5692 | bytes.push( |
| 5693 | codePoint >> 0x12 | 0xF0, |
| 5694 | codePoint >> 0xC & 0x3F | 0x80, |
| 5695 | codePoint >> 0x6 & 0x3F | 0x80, |
| 5696 | codePoint & 0x3F | 0x80 |
| 5697 | ) |
| 5698 | } else { |
| 5699 | throw new Error('Invalid code point') |
| 5700 | } |
| 5701 | } |
| 5702 | |
| 5703 | return bytes |
| 5704 | } |
| 5705 | |
| 5706 | function asciiToBytes (str) { |
| 5707 | var byteArray = [] |
| 5708 | for (var i = 0; i < str.length; i++) { |
| 5709 | // Node's code seems to be doing this and not & 0x7F.. |
| 5710 | byteArray.push(str.charCodeAt(i) & 0xFF) |
| 5711 | } |
| 5712 | return byteArray |
| 5713 | } |
| 5714 | |
| 5715 | function utf16leToBytes (str, units) { |
| 5716 | var c, hi, lo |
| 5717 | var byteArray = [] |
| 5718 | for (var i = 0; i < str.length; i++) { |
| 5719 | if ((units -= 2) < 0) break |
| 5720 | |
| 5721 | c = str.charCodeAt(i) |
| 5722 | hi = c >> 8 |
| 5723 | lo = c % 256 |
| 5724 | byteArray.push(lo) |
| 5725 | byteArray.push(hi) |
| 5726 | } |
| 5727 | |
| 5728 | return byteArray |
| 5729 | } |
| 5730 | |
| 5731 | function base64ToBytes (str) { |
| 5732 | return base64.toByteArray(base64clean(str)) |
| 5733 | } |
| 5734 | |
| 5735 | function blitBuffer (src, dst, offset, length) { |
| 5736 | for (var i = 0; i < length; i++) { |
| 5737 | if ((i + offset >= dst.length) || (i >= src.length)) break |
| 5738 | dst[i + offset] = src[i] |
| 5739 | } |
| 5740 | return i |
| 5741 | } |
| 5742 | |
| 5743 | function decodeUtf8Char (str) { |
| 5744 | try { |
| 5745 | return decodeURIComponent(str) |
| 5746 | } catch (err) { |
| 5747 | return String.fromCharCode(0xFFFD) // UTF 8 invalid char |
| 5748 | } |
| 5749 | } |
| 5750 | |
| 5751 | },{"base64-js":13,"ieee754":14,"is-array":15}],13:[function(require,module,exports){ |
| 5752 | var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; |
| 5753 | |
| 5754 | ;(function (exports) { |
| 5755 | 'use strict'; |
| 5756 | |
| 5757 | var Arr = (typeof Uint8Array !== 'undefined') |
| 5758 | ? Uint8Array |
| 5759 | : Array |
| 5760 | |
| 5761 | var PLUS = '+'.charCodeAt(0) |
| 5762 | var SLASH = '/'.charCodeAt(0) |
| 5763 | var NUMBER = '0'.charCodeAt(0) |
| 5764 | var LOWER = 'a'.charCodeAt(0) |
| 5765 | var UPPER = 'A'.charCodeAt(0) |
| 5766 | var PLUS_URL_SAFE = '-'.charCodeAt(0) |
| 5767 | var SLASH_URL_SAFE = '_'.charCodeAt(0) |
| 5768 | |
| 5769 | function decode (elt) { |
| 5770 | var code = elt.charCodeAt(0) |
| 5771 | if (code === PLUS || |
| 5772 | code === PLUS_URL_SAFE) |
| 5773 | return 62 // '+' |
| 5774 | if (code === SLASH || |
| 5775 | code === SLASH_URL_SAFE) |
| 5776 | return 63 // '/' |
| 5777 | if (code < NUMBER) |
| 5778 | return -1 //no match |
| 5779 | if (code < NUMBER + 10) |
| 5780 | return code - NUMBER + 26 + 26 |
| 5781 | if (code < UPPER + 26) |
| 5782 | return code - UPPER |
| 5783 | if (code < LOWER + 26) |
| 5784 | return code - LOWER + 26 |
| 5785 | } |
| 5786 | |
| 5787 | function b64ToByteArray (b64) { |
| 5788 | var i, j, l, tmp, placeHolders, arr |
| 5789 | |
| 5790 | if (b64.length % 4 > 0) { |
| 5791 | throw new Error('Invalid string. Length must be a multiple of 4') |
| 5792 | } |
| 5793 | |
| 5794 | // the number of equal signs (place holders) |
| 5795 | // if there are two placeholders, than the two characters before it |
| 5796 | // represent one byte |
| 5797 | // if there is only one, then the three characters before it represent 2 bytes |
| 5798 | // this is just a cheap hack to not do indexOf twice |
| 5799 | var len = b64.length |
| 5800 | placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0 |
| 5801 | |
| 5802 | // base64 is 4/3 + up to two characters of the original data |
| 5803 | arr = new Arr(b64.length * 3 / 4 - placeHolders) |
| 5804 | |
| 5805 | // if there are placeholders, only get up to the last complete 4 chars |
| 5806 | l = placeHolders > 0 ? b64.length - 4 : b64.length |
| 5807 | |
| 5808 | var L = 0 |
| 5809 | |
| 5810 | function push (v) { |
| 5811 | arr[L++] = v |
| 5812 | } |
| 5813 | |
| 5814 | for (i = 0, j = 0; i < l; i += 4, j += 3) { |
| 5815 | tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3)) |
| 5816 | push((tmp & 0xFF0000) >> 16) |
| 5817 | push((tmp & 0xFF00) >> 8) |
| 5818 | push(tmp & 0xFF) |
| 5819 | } |
| 5820 | |
| 5821 | if (placeHolders === 2) { |
| 5822 | tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4) |
| 5823 | push(tmp & 0xFF) |
| 5824 | } else if (placeHolders === 1) { |
| 5825 | tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2) |
| 5826 | push((tmp >> 8) & 0xFF) |
| 5827 | push(tmp & 0xFF) |
| 5828 | } |
| 5829 | |
| 5830 | return arr |
| 5831 | } |
| 5832 | |
| 5833 | function uint8ToBase64 (uint8) { |
| 5834 | var i, |
| 5835 | extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes |
| 5836 | output = "", |
| 5837 | temp, length |
| 5838 | |
| 5839 | function encode (num) { |
| 5840 | return lookup.charAt(num) |
| 5841 | } |
| 5842 | |
| 5843 | function tripletToBase64 (num) { |
| 5844 | return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F) |
| 5845 | } |
| 5846 | |
| 5847 | // go through the array every three bytes, we'll deal with trailing stuff later |
| 5848 | for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { |
| 5849 | temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) |
| 5850 | output += tripletToBase64(temp) |
| 5851 | } |
| 5852 | |
| 5853 | // pad the end with zeros, but make sure to not forget the extra bytes |
| 5854 | switch (extraBytes) { |
| 5855 | case 1: |
| 5856 | temp = uint8[uint8.length - 1] |
| 5857 | output += encode(temp >> 2) |
| 5858 | output += encode((temp << 4) & 0x3F) |
| 5859 | output += '==' |
| 5860 | break |
| 5861 | case 2: |
| 5862 | temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]) |
| 5863 | output += encode(temp >> 10) |
| 5864 | output += encode((temp >> 4) & 0x3F) |
| 5865 | output += encode((temp << 2) & 0x3F) |
| 5866 | output += '=' |
| 5867 | break |
| 5868 | } |
| 5869 | |
| 5870 | return output |
| 5871 | } |
| 5872 | |
| 5873 | exports.toByteArray = b64ToByteArray |
| 5874 | exports.fromByteArray = uint8ToBase64 |
| 5875 | }(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) |
| 5876 | |
| 5877 | },{}],14:[function(require,module,exports){ |
| 5878 | exports.read = function(buffer, offset, isLE, mLen, nBytes) { |
| 5879 | var e, m, |
| 5880 | eLen = nBytes * 8 - mLen - 1, |
| 5881 | eMax = (1 << eLen) - 1, |
| 5882 | eBias = eMax >> 1, |
| 5883 | nBits = -7, |
| 5884 | i = isLE ? (nBytes - 1) : 0, |
| 5885 | d = isLE ? -1 : 1, |
| 5886 | s = buffer[offset + i]; |
| 5887 | |
| 5888 | i += d; |
| 5889 | |
| 5890 | e = s & ((1 << (-nBits)) - 1); |
| 5891 | s >>= (-nBits); |
| 5892 | nBits += eLen; |
| 5893 | for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); |
| 5894 | |
| 5895 | m = e & ((1 << (-nBits)) - 1); |
| 5896 | e >>= (-nBits); |
| 5897 | nBits += mLen; |
| 5898 | for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); |
| 5899 | |
| 5900 | if (e === 0) { |
| 5901 | e = 1 - eBias; |
| 5902 | } else if (e === eMax) { |
| 5903 | return m ? NaN : ((s ? -1 : 1) * Infinity); |
| 5904 | } else { |
| 5905 | m = m + Math.pow(2, mLen); |
| 5906 | e = e - eBias; |
| 5907 | } |
| 5908 | return (s ? -1 : 1) * m * Math.pow(2, e - mLen); |
| 5909 | }; |
| 5910 | |
| 5911 | exports.write = function(buffer, value, offset, isLE, mLen, nBytes) { |
| 5912 | var e, m, c, |
| 5913 | eLen = nBytes * 8 - mLen - 1, |
| 5914 | eMax = (1 << eLen) - 1, |
| 5915 | eBias = eMax >> 1, |
| 5916 | rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), |
| 5917 | i = isLE ? 0 : (nBytes - 1), |
| 5918 | d = isLE ? 1 : -1, |
| 5919 | s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; |
| 5920 | |
| 5921 | value = Math.abs(value); |
| 5922 | |
| 5923 | if (isNaN(value) || value === Infinity) { |
| 5924 | m = isNaN(value) ? 1 : 0; |
| 5925 | e = eMax; |
| 5926 | } else { |
| 5927 | e = Math.floor(Math.log(value) / Math.LN2); |
| 5928 | if (value * (c = Math.pow(2, -e)) < 1) { |
| 5929 | e--; |
| 5930 | c *= 2; |
| 5931 | } |
| 5932 | if (e + eBias >= 1) { |
| 5933 | value += rt / c; |
| 5934 | } else { |
| 5935 | value += rt * Math.pow(2, 1 - eBias); |
| 5936 | } |
| 5937 | if (value * c >= 2) { |
| 5938 | e++; |
| 5939 | c /= 2; |
| 5940 | } |
| 5941 | |
| 5942 | if (e + eBias >= eMax) { |
| 5943 | m = 0; |
| 5944 | e = eMax; |
| 5945 | } else if (e + eBias >= 1) { |
| 5946 | m = (value * c - 1) * Math.pow(2, mLen); |
| 5947 | e = e + eBias; |
| 5948 | } else { |
| 5949 | m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); |
| 5950 | e = 0; |
| 5951 | } |
| 5952 | } |
| 5953 | |
| 5954 | for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); |
| 5955 | |
| 5956 | e = (e << mLen) | m; |
| 5957 | eLen += mLen; |
| 5958 | for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); |
| 5959 | |
| 5960 | buffer[offset + i - d] |= s * 128; |
| 5961 | }; |
| 5962 | |
| 5963 | },{}],15:[function(require,module,exports){ |
| 5964 | |
| 5965 | /** |
| 5966 | * isArray |
| 5967 | */ |
| 5968 | |
| 5969 | var isArray = Array.isArray; |
| 5970 | |
| 5971 | /** |
| 5972 | * toString |
| 5973 | */ |
| 5974 | |
| 5975 | var str = Object.prototype.toString; |
| 5976 | |
| 5977 | /** |
| 5978 | * Whether or not the given `val` |
| 5979 | * is an array. |
| 5980 | * |
| 5981 | * example: |
| 5982 | * |
| 5983 | * isArray([]); |
| 5984 | * // > true |
| 5985 | * isArray(arguments); |
| 5986 | * // > false |
| 5987 | * isArray(''); |
| 5988 | * // > false |
| 5989 | * |
| 5990 | * @param {mixed} val |
| 5991 | * @return {bool} |
| 5992 | */ |
| 5993 | |
| 5994 | module.exports = isArray || function (val) { |
| 5995 | return !! val && '[object Array]' == str.call(val); |
| 5996 | }; |
| 5997 | |
| 5998 | },{}],16:[function(require,module,exports){ |
| 5999 | // shim for using process in browser |
| 6000 | |
| 6001 | var process = module.exports = {}; |
| 6002 | var queue = []; |
| 6003 | var draining = false; |
| 6004 | |
| 6005 | function drainQueue() { |
| 6006 | if (draining) { |
| 6007 | return; |
| 6008 | } |
| 6009 | draining = true; |
| 6010 | var currentQueue; |
| 6011 | var len = queue.length; |
| 6012 | while(len) { |
| 6013 | currentQueue = queue; |
| 6014 | queue = []; |
| 6015 | var i = -1; |
| 6016 | while (++i < len) { |
| 6017 | currentQueue[i](); |
| 6018 | } |
| 6019 | len = queue.length; |
| 6020 | } |
| 6021 | draining = false; |
| 6022 | } |
| 6023 | process.nextTick = function (fun) { |
| 6024 | queue.push(fun); |
| 6025 | if (!draining) { |
| 6026 | setTimeout(drainQueue, 0); |
| 6027 | } |
| 6028 | }; |
| 6029 | |
| 6030 | process.title = 'browser'; |
| 6031 | process.browser = true; |
| 6032 | process.env = {}; |
| 6033 | process.argv = []; |
| 6034 | process.version = ''; // empty string to avoid regexp issues |
| 6035 | process.versions = {}; |
| 6036 | |
| 6037 | function noop() {} |
| 6038 | |
| 6039 | process.on = noop; |
| 6040 | process.addListener = noop; |
| 6041 | process.once = noop; |
| 6042 | process.off = noop; |
| 6043 | process.removeListener = noop; |
| 6044 | process.removeAllListeners = noop; |
| 6045 | process.emit = noop; |
| 6046 | |
| 6047 | process.binding = function (name) { |
| 6048 | throw new Error('process.binding is not supported'); |
| 6049 | }; |
| 6050 | |
| 6051 | // TODO(shtylman) |
| 6052 | process.cwd = function () { return '/' }; |
| 6053 | process.chdir = function (dir) { |
| 6054 | throw new Error('process.chdir is not supported'); |
| 6055 | }; |
| 6056 | process.umask = function() { return 0; }; |
| 6057 | |
| 6058 | },{}],17:[function(require,module,exports){ |
| 6059 | (function (Buffer){ |
| 6060 | (function () { |
| 6061 | "use strict"; |
| 6062 | |
| 6063 | function btoa(str) { |
| 6064 | var buffer |
| 6065 | ; |
| 6066 | |
| 6067 | if (str instanceof Buffer) { |
| 6068 | buffer = str; |
| 6069 | } else { |
| 6070 | buffer = new Buffer(str.toString(), 'binary'); |
| 6071 | } |
| 6072 | |
| 6073 | return buffer.toString('base64'); |
| 6074 | } |
| 6075 | |
| 6076 | module.exports = btoa; |
| 6077 | }()); |
| 6078 | |
| 6079 | }).call(this,require("buffer").Buffer) |
| 6080 | |
| 6081 | },{"buffer":12}],18:[function(require,module,exports){ |
| 6082 | /* jshint node: true */ |
| 6083 | (function () { |
| 6084 | "use strict"; |
| 6085 | |
| 6086 | function CookieAccessInfo(domain, path, secure, script) { |
| 6087 | if (this instanceof CookieAccessInfo) { |
| 6088 | this.domain = domain || undefined; |
| 6089 | this.path = path || "/"; |
| 6090 | this.secure = !!secure; |
| 6091 | this.script = !!script; |
| 6092 | return this; |
| 6093 | } |
| 6094 | return new CookieAccessInfo(domain, path, secure, script); |
| 6095 | } |
| 6096 | exports.CookieAccessInfo = CookieAccessInfo; |
| 6097 | |
| 6098 | function Cookie(cookiestr, request_domain, request_path) { |
| 6099 | if (cookiestr instanceof Cookie) { |
| 6100 | return cookiestr; |
| 6101 | } |
| 6102 | if (this instanceof Cookie) { |
| 6103 | this.name = null; |
| 6104 | this.value = null; |
| 6105 | this.expiration_date = Infinity; |
| 6106 | this.path = String(request_path || "/"); |
| 6107 | this.explicit_path = false; |
| 6108 | this.domain = request_domain || null; |
| 6109 | this.explicit_domain = false; |
| 6110 | this.secure = false; //how to define default? |
| 6111 | this.noscript = false; //httponly |
| 6112 | if (cookiestr) { |
| 6113 | this.parse(cookiestr, request_domain, request_path); |
| 6114 | } |
| 6115 | return this; |
| 6116 | } |
| 6117 | return new Cookie(cookiestr); |
| 6118 | } |
| 6119 | exports.Cookie = Cookie; |
| 6120 | |
| 6121 | Cookie.prototype.toString = function toString() { |
| 6122 | var str = [this.name + "=" + this.value]; |
| 6123 | if (this.expiration_date !== Infinity) { |
| 6124 | str.push("expires=" + (new Date(this.expiration_date)).toGMTString()); |
| 6125 | } |
| 6126 | if (this.domain) { |
| 6127 | str.push("domain=" + this.domain); |
| 6128 | } |
| 6129 | if (this.path) { |
| 6130 | str.push("path=" + this.path); |
| 6131 | } |
| 6132 | if (this.secure) { |
| 6133 | str.push("secure"); |
| 6134 | } |
| 6135 | if (this.noscript) { |
| 6136 | str.push("httponly"); |
| 6137 | } |
| 6138 | return str.join("; "); |
| 6139 | }; |
| 6140 | |
| 6141 | Cookie.prototype.toValueString = function toValueString() { |
| 6142 | return this.name + "=" + this.value; |
| 6143 | }; |
| 6144 | |
| 6145 | var cookie_str_splitter = /[:](?=\s*[a-zA-Z0-9_\-]+\s*[=])/g; |
| 6146 | Cookie.prototype.parse = function parse(str, request_domain, request_path) { |
| 6147 | if (this instanceof Cookie) { |
| 6148 | var parts = str.split(";").filter(function (value) { |
| 6149 | return !!value; |
| 6150 | }), |
| 6151 | pair = parts[0].match(/([^=]+)=([\s\S]*)/), |
| 6152 | key = pair[1], |
| 6153 | value = pair[2], |
| 6154 | i; |
| 6155 | this.name = key; |
| 6156 | this.value = value; |
| 6157 | |
| 6158 | for (i = 1; i < parts.length; i += 1) { |
| 6159 | pair = parts[i].match(/([^=]+)(?:=([\s\S]*))?/); |
| 6160 | key = pair[1].trim().toLowerCase(); |
| 6161 | value = pair[2]; |
| 6162 | switch (key) { |
| 6163 | case "httponly": |
| 6164 | this.noscript = true; |
| 6165 | break; |
| 6166 | case "expires": |
| 6167 | this.expiration_date = value ? |
| 6168 | Number(Date.parse(value)) : |
| 6169 | Infinity; |
| 6170 | break; |
| 6171 | case "path": |
| 6172 | this.path = value ? |
| 6173 | value.trim() : |
| 6174 | ""; |
| 6175 | this.explicit_path = true; |
| 6176 | break; |
| 6177 | case "domain": |
| 6178 | this.domain = value ? |
| 6179 | value.trim() : |
| 6180 | ""; |
| 6181 | this.explicit_domain = !!this.domain; |
| 6182 | break; |
| 6183 | case "secure": |
| 6184 | this.secure = true; |
| 6185 | break; |
| 6186 | } |
| 6187 | } |
| 6188 | |
| 6189 | if (!this.explicit_path) { |
| 6190 | this.path = request_path || "/"; |
| 6191 | } |
| 6192 | if (!this.explicit_domain) { |
| 6193 | this.domain = request_domain; |
| 6194 | } |
| 6195 | |
| 6196 | return this; |
| 6197 | } |
| 6198 | return new Cookie().parse(str, request_domain, request_path); |
| 6199 | }; |
| 6200 | |
| 6201 | Cookie.prototype.matches = function matches(access_info) { |
| 6202 | if (this.noscript && access_info.script || |
| 6203 | this.secure && !access_info.secure || |
| 6204 | !this.collidesWith(access_info)) { |
| 6205 | return false; |
| 6206 | } |
| 6207 | return true; |
| 6208 | }; |
| 6209 | |
| 6210 | Cookie.prototype.collidesWith = function collidesWith(access_info) { |
| 6211 | if ((this.path && !access_info.path) || (this.domain && !access_info.domain)) { |
| 6212 | return false; |
| 6213 | } |
| 6214 | if (this.path && access_info.path.indexOf(this.path) !== 0) { |
| 6215 | return false; |
| 6216 | } |
| 6217 | if (!this.explicit_path) { |
| 6218 | if (this.path !== access_info.path) { |
| 6219 | return false; |
| 6220 | } |
| 6221 | } |
| 6222 | var access_domain = access_info.domain && access_info.domain.replace(/^[\.]/,''); |
| 6223 | var cookie_domain = this.domain && this.domain.replace(/^[\.]/,''); |
| 6224 | if (cookie_domain === access_domain) { |
| 6225 | return true; |
| 6226 | } |
| 6227 | if (cookie_domain) { |
| 6228 | if (!this.explicit_domain) { |
| 6229 | return false; // we already checked if the domains were exactly the same |
| 6230 | } |
| 6231 | var wildcard = access_domain.indexOf(cookie_domain); |
| 6232 | if (wildcard === -1 || wildcard !== access_domain.length - cookie_domain.length) { |
| 6233 | return false; |
| 6234 | } |
| 6235 | return true; |
| 6236 | } |
| 6237 | return true; |
| 6238 | }; |
| 6239 | |
| 6240 | function CookieJar() { |
| 6241 | var cookies, cookies_list, collidable_cookie; |
| 6242 | if (this instanceof CookieJar) { |
| 6243 | cookies = Object.create(null); //name: [Cookie] |
| 6244 | |
| 6245 | this.setCookie = function setCookie(cookie, request_domain, request_path) { |
| 6246 | var remove, i; |
| 6247 | cookie = new Cookie(cookie, request_domain, request_path); |
| 6248 | //Delete the cookie if the set is past the current time |
| 6249 | remove = cookie.expiration_date <= Date.now(); |
| 6250 | if (cookies[cookie.name] !== undefined) { |
| 6251 | cookies_list = cookies[cookie.name]; |
| 6252 | for (i = 0; i < cookies_list.length; i += 1) { |
| 6253 | collidable_cookie = cookies_list[i]; |
| 6254 | if (collidable_cookie.collidesWith(cookie)) { |
| 6255 | if (remove) { |
| 6256 | cookies_list.splice(i, 1); |
| 6257 | if (cookies_list.length === 0) { |
| 6258 | delete cookies[cookie.name]; |
| 6259 | } |
| 6260 | return false; |
| 6261 | } |
| 6262 | cookies_list[i] = cookie; |
| 6263 | return cookie; |
| 6264 | } |
| 6265 | } |
| 6266 | if (remove) { |
| 6267 | return false; |
| 6268 | } |
| 6269 | cookies_list.push(cookie); |
| 6270 | return cookie; |
| 6271 | } |
| 6272 | if (remove) { |
| 6273 | return false; |
| 6274 | } |
| 6275 | cookies[cookie.name] = [cookie]; |
| 6276 | return cookies[cookie.name]; |
| 6277 | }; |
| 6278 | //returns a cookie |
| 6279 | this.getCookie = function getCookie(cookie_name, access_info) { |
| 6280 | var cookie, i; |
| 6281 | cookies_list = cookies[cookie_name]; |
| 6282 | if (!cookies_list) { |
| 6283 | return; |
| 6284 | } |
| 6285 | for (i = 0; i < cookies_list.length; i += 1) { |
| 6286 | cookie = cookies_list[i]; |
| 6287 | if (cookie.expiration_date <= Date.now()) { |
| 6288 | if (cookies_list.length === 0) { |
| 6289 | delete cookies[cookie.name]; |
| 6290 | } |
| 6291 | continue; |
| 6292 | } |
| 6293 | if (cookie.matches(access_info)) { |
| 6294 | return cookie; |
| 6295 | } |
| 6296 | } |
| 6297 | }; |
| 6298 | //returns a list of cookies |
| 6299 | this.getCookies = function getCookies(access_info) { |
| 6300 | var matches = [], cookie_name, cookie; |
| 6301 | for (cookie_name in cookies) { |
| 6302 | cookie = this.getCookie(cookie_name, access_info); |
| 6303 | if (cookie) { |
| 6304 | matches.push(cookie); |
| 6305 | } |
| 6306 | } |
| 6307 | matches.toString = function toString() { |
| 6308 | return matches.join(":"); |
| 6309 | }; |
| 6310 | matches.toValueString = function toValueString() { |
| 6311 | return matches.map(function (c) { |
| 6312 | return c.toValueString(); |
| 6313 | }).join(';'); |
| 6314 | }; |
| 6315 | return matches; |
| 6316 | }; |
| 6317 | |
| 6318 | return this; |
| 6319 | } |
| 6320 | return new CookieJar(); |
| 6321 | } |
| 6322 | exports.CookieJar = CookieJar; |
| 6323 | |
| 6324 | //returns list of cookies that were set correctly. Cookies that are expired and removed are not returned. |
| 6325 | CookieJar.prototype.setCookies = function setCookies(cookies, request_domain, request_path) { |
| 6326 | cookies = Array.isArray(cookies) ? |
| 6327 | cookies : |
| 6328 | cookies.split(cookie_str_splitter); |
| 6329 | var successful = [], |
| 6330 | i, |
| 6331 | cookie; |
| 6332 | cookies = cookies.map(Cookie); |
| 6333 | for (i = 0; i < cookies.length; i += 1) { |
| 6334 | cookie = cookies[i]; |
| 6335 | if (this.setCookie(cookie, request_domain, request_path)) { |
| 6336 | successful.push(cookie); |
| 6337 | } |
| 6338 | } |
| 6339 | return successful; |
| 6340 | }; |
| 6341 | }()); |
| 6342 | |
| 6343 | },{}],19:[function(require,module,exports){ |
| 6344 | /*! |
| 6345 | * jQuery JavaScript Library v2.1.4 |
| 6346 | * http://jquery.com/ |
| 6347 | * |
| 6348 | * Includes Sizzle.js |
| 6349 | * http://sizzlejs.com/ |
| 6350 | * |
| 6351 | * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors |
| 6352 | * Released under the MIT license |
| 6353 | * http://jquery.org/license |
| 6354 | * |
| 6355 | * Date: 2015-04-28T16:01Z |
| 6356 | */ |
| 6357 | |
| 6358 | (function( global, factory ) { |
| 6359 | |
| 6360 | if ( typeof module === "object" && typeof module.exports === "object" ) { |
| 6361 | // For CommonJS and CommonJS-like environments where a proper `window` |
| 6362 | // is present, execute the factory and get jQuery. |
| 6363 | // For environments that do not have a `window` with a `document` |
| 6364 | // (such as Node.js), expose a factory as module.exports. |
| 6365 | // This accentuates the need for the creation of a real `window`. |
| 6366 | // e.g. var jQuery = require("jquery")(window); |
| 6367 | // See ticket #14549 for more info. |
| 6368 | module.exports = global.document ? |
| 6369 | factory( global, true ) : |
| 6370 | function( w ) { |
| 6371 | if ( !w.document ) { |
| 6372 | throw new Error( "jQuery requires a window with a document" ); |
| 6373 | } |
| 6374 | return factory( w ); |
| 6375 | }; |
| 6376 | } else { |
| 6377 | factory( global ); |
| 6378 | } |
| 6379 | |
| 6380 | // Pass this if window is not defined yet |
| 6381 | }(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { |
| 6382 | |
| 6383 | // Support: Firefox 18+ |
| 6384 | // Can't be in strict mode, several libs including ASP.NET trace |
| 6385 | // the stack via arguments.caller.callee and Firefox dies if |
| 6386 | // you try to trace through "use strict" call chains. (#13335) |
| 6387 | // |
| 6388 | |
| 6389 | var arr = []; |
| 6390 | |
| 6391 | var slice = arr.slice; |
| 6392 | |
| 6393 | var concat = arr.concat; |
| 6394 | |
| 6395 | var push = arr.push; |
| 6396 | |
| 6397 | var indexOf = arr.indexOf; |
| 6398 | |
| 6399 | var class2type = {}; |
| 6400 | |
| 6401 | var toString = class2type.toString; |
| 6402 | |
| 6403 | var hasOwn = class2type.hasOwnProperty; |
| 6404 | |
| 6405 | var support = {}; |
| 6406 | |
| 6407 | |
| 6408 | |
| 6409 | var |
| 6410 | // Use the correct document accordingly with window argument (sandbox) |
| 6411 | document = window.document, |
| 6412 | |
| 6413 | version = "2.1.4", |
| 6414 | |
| 6415 | // Define a local copy of jQuery |
| 6416 | jQuery = function( selector, context ) { |
| 6417 | // The jQuery object is actually just the init constructor 'enhanced' |
| 6418 | // Need init if jQuery is called (just allow error to be thrown if not included) |
| 6419 | return new jQuery.fn.init( selector, context ); |
| 6420 | }, |
| 6421 | |
| 6422 | // Support: Android<4.1 |
| 6423 | // Make sure we trim BOM and NBSP |
| 6424 | rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, |
| 6425 | |
| 6426 | // Matches dashed string for camelizing |
| 6427 | rmsPrefix = /^-ms-/, |
| 6428 | rdashAlpha = /-([\da-z])/gi, |
| 6429 | |
| 6430 | // Used by jQuery.camelCase as callback to replace() |
| 6431 | fcamelCase = function( all, letter ) { |
| 6432 | return letter.toUpperCase(); |
| 6433 | }; |
| 6434 | |
| 6435 | jQuery.fn = jQuery.prototype = { |
| 6436 | // The current version of jQuery being used |
| 6437 | jquery: version, |
| 6438 | |
| 6439 | constructor: jQuery, |
| 6440 | |
| 6441 | // Start with an empty selector |
| 6442 | selector: "", |
| 6443 | |
| 6444 | // The default length of a jQuery object is 0 |
| 6445 | length: 0, |
| 6446 | |
| 6447 | toArray: function() { |
| 6448 | return slice.call( this ); |
| 6449 | }, |
| 6450 | |
| 6451 | // Get the Nth element in the matched element set OR |
| 6452 | // Get the whole matched element set as a clean array |
| 6453 | get: function( num ) { |
| 6454 | return num != null ? |
| 6455 | |
| 6456 | // Return just the one element from the set |
| 6457 | ( num < 0 ? this[ num + this.length ] : this[ num ] ) : |
| 6458 | |
| 6459 | // Return all the elements in a clean array |
| 6460 | slice.call( this ); |
| 6461 | }, |
| 6462 | |
| 6463 | // Take an array of elements and push it onto the stack |
| 6464 | // (returning the new matched element set) |
| 6465 | pushStack: function( elems ) { |
| 6466 | |
| 6467 | // Build a new jQuery matched element set |
| 6468 | var ret = jQuery.merge( this.constructor(), elems ); |
| 6469 | |
| 6470 | // Add the old object onto the stack (as a reference) |
| 6471 | ret.prevObject = this; |
| 6472 | ret.context = this.context; |
| 6473 | |
| 6474 | // Return the newly-formed element set |
| 6475 | return ret; |
| 6476 | }, |
| 6477 | |
| 6478 | // Execute a callback for every element in the matched set. |
| 6479 | // (You can seed the arguments with an array of args, but this is |
| 6480 | // only used internally.) |
| 6481 | each: function( callback, args ) { |
| 6482 | return jQuery.each( this, callback, args ); |
| 6483 | }, |
| 6484 | |
| 6485 | map: function( callback ) { |
| 6486 | return this.pushStack( jQuery.map(this, function( elem, i ) { |
| 6487 | return callback.call( elem, i, elem ); |
| 6488 | })); |
| 6489 | }, |
| 6490 | |
| 6491 | slice: function() { |
| 6492 | return this.pushStack( slice.apply( this, arguments ) ); |
| 6493 | }, |
| 6494 | |
| 6495 | first: function() { |
| 6496 | return this.eq( 0 ); |
| 6497 | }, |
| 6498 | |
| 6499 | last: function() { |
| 6500 | return this.eq( -1 ); |
| 6501 | }, |
| 6502 | |
| 6503 | eq: function( i ) { |
| 6504 | var len = this.length, |
| 6505 | j = +i + ( i < 0 ? len : 0 ); |
| 6506 | return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); |
| 6507 | }, |
| 6508 | |
| 6509 | end: function() { |
| 6510 | return this.prevObject || this.constructor(null); |
| 6511 | }, |
| 6512 | |
| 6513 | // For internal use only. |
| 6514 | // Behaves like an Array's method, not like a jQuery method. |
| 6515 | push: push, |
| 6516 | sort: arr.sort, |
| 6517 | splice: arr.splice |
| 6518 | }; |
| 6519 | |
| 6520 | jQuery.extend = jQuery.fn.extend = function() { |
| 6521 | var options, name, src, copy, copyIsArray, clone, |
| 6522 | target = arguments[0] || {}, |
| 6523 | i = 1, |
| 6524 | length = arguments.length, |
| 6525 | deep = false; |
| 6526 | |
| 6527 | // Handle a deep copy situation |
| 6528 | if ( typeof target === "boolean" ) { |
| 6529 | deep = target; |
| 6530 | |
| 6531 | // Skip the boolean and the target |
| 6532 | target = arguments[ i ] || {}; |
| 6533 | i++; |
| 6534 | } |
| 6535 | |
| 6536 | // Handle case when target is a string or something (possible in deep copy) |
| 6537 | if ( typeof target !== "object" && !jQuery.isFunction(target) ) { |
| 6538 | target = {}; |
| 6539 | } |
| 6540 | |
| 6541 | // Extend jQuery itself if only one argument is passed |
| 6542 | if ( i === length ) { |
| 6543 | target = this; |
| 6544 | i--; |
| 6545 | } |
| 6546 | |
| 6547 | for ( ; i < length; i++ ) { |
| 6548 | // Only deal with non-null/undefined values |
| 6549 | if ( (options = arguments[ i ]) != null ) { |
| 6550 | // Extend the base object |
| 6551 | for ( name in options ) { |
| 6552 | src = target[ name ]; |
| 6553 | copy = options[ name ]; |
| 6554 | |
| 6555 | // Prevent never-ending loop |
| 6556 | if ( target === copy ) { |
| 6557 | continue; |
| 6558 | } |
| 6559 | |
| 6560 | // Recurse if we're merging plain objects or arrays |
| 6561 | if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { |
| 6562 | if ( copyIsArray ) { |
| 6563 | copyIsArray = false; |
| 6564 | clone = src && jQuery.isArray(src) ? src : []; |
| 6565 | |
| 6566 | } else { |
| 6567 | clone = src && jQuery.isPlainObject(src) ? src : {}; |
| 6568 | } |
| 6569 | |
| 6570 | // Never move original objects, clone them |
| 6571 | target[ name ] = jQuery.extend( deep, clone, copy ); |
| 6572 | |
| 6573 | // Don't bring in undefined values |
| 6574 | } else if ( copy !== undefined ) { |
| 6575 | target[ name ] = copy; |
| 6576 | } |
| 6577 | } |
| 6578 | } |
| 6579 | } |
| 6580 | |
| 6581 | // Return the modified object |
| 6582 | return target; |
| 6583 | }; |
| 6584 | |
| 6585 | jQuery.extend({ |
| 6586 | // Unique for each copy of jQuery on the page |
| 6587 | expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), |
| 6588 | |
| 6589 | // Assume jQuery is ready without the ready module |
| 6590 | isReady: true, |
| 6591 | |
| 6592 | error: function( msg ) { |
| 6593 | throw new Error( msg ); |
| 6594 | }, |
| 6595 | |
| 6596 | noop: function() {}, |
| 6597 | |
| 6598 | isFunction: function( obj ) { |
| 6599 | return jQuery.type(obj) === "function"; |
| 6600 | }, |
| 6601 | |
| 6602 | isArray: Array.isArray, |
| 6603 | |
| 6604 | isWindow: function( obj ) { |
| 6605 | return obj != null && obj === obj.window; |
| 6606 | }, |
| 6607 | |
| 6608 | isNumeric: function( obj ) { |
| 6609 | // parseFloat NaNs numeric-cast false positives (null|true|false|"") |
| 6610 | // ...but misinterprets leading-number strings, particularly hex literals ("0x...") |
| 6611 | // subtraction forces infinities to NaN |
| 6612 | // adding 1 corrects loss of precision from parseFloat (#15100) |
| 6613 | return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0; |
| 6614 | }, |
| 6615 | |
| 6616 | isPlainObject: function( obj ) { |
| 6617 | // Not plain objects: |
| 6618 | // - Any object or value whose internal [[Class]] property is not "[object Object]" |
| 6619 | // - DOM nodes |
| 6620 | // - window |
| 6621 | if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { |
| 6622 | return false; |
| 6623 | } |
| 6624 | |
| 6625 | if ( obj.constructor && |
| 6626 | !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) { |
| 6627 | return false; |
| 6628 | } |
| 6629 | |
| 6630 | // If the function hasn't returned already, we're confident that |
| 6631 | // |obj| is a plain object, created by {} or constructed with new Object |
| 6632 | return true; |
| 6633 | }, |
| 6634 | |
| 6635 | isEmptyObject: function( obj ) { |
| 6636 | var name; |
| 6637 | for ( name in obj ) { |
| 6638 | return false; |
| 6639 | } |
| 6640 | return true; |
| 6641 | }, |
| 6642 | |
| 6643 | type: function( obj ) { |
| 6644 | if ( obj == null ) { |
| 6645 | return obj + ""; |
| 6646 | } |
| 6647 | // Support: Android<4.0, iOS<6 (functionish RegExp) |
| 6648 | return typeof obj === "object" || typeof obj === "function" ? |
| 6649 | class2type[ toString.call(obj) ] || "object" : |
| 6650 | typeof obj; |
| 6651 | }, |
| 6652 | |
| 6653 | // Evaluates a script in a global context |
| 6654 | globalEval: function( code ) { |
| 6655 | var script, |
| 6656 | indirect = eval; |
| 6657 | |
| 6658 | code = jQuery.trim( code ); |
| 6659 | |
| 6660 | if ( code ) { |
| 6661 | // If the code includes a valid, prologue position |
| 6662 | // strict mode pragma, execute code by injecting a |
| 6663 | // script tag into the document. |
| 6664 | if ( code.indexOf("use strict") === 1 ) { |
| 6665 | script = document.createElement("script"); |
| 6666 | script.text = code; |
| 6667 | document.head.appendChild( script ).parentNode.removeChild( script ); |
| 6668 | } else { |
| 6669 | // Otherwise, avoid the DOM node creation, insertion |
| 6670 | // and removal by using an indirect global eval |
| 6671 | indirect( code ); |
| 6672 | } |
| 6673 | } |
| 6674 | }, |
| 6675 | |
| 6676 | // Convert dashed to camelCase; used by the css and data modules |
| 6677 | // Support: IE9-11+ |
| 6678 | // Microsoft forgot to hump their vendor prefix (#9572) |
| 6679 | camelCase: function( string ) { |
| 6680 | return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); |
| 6681 | }, |
| 6682 | |
| 6683 | nodeName: function( elem, name ) { |
| 6684 | return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); |
| 6685 | }, |
| 6686 | |
| 6687 | // args is for internal usage only |
| 6688 | each: function( obj, callback, args ) { |
| 6689 | var value, |
| 6690 | i = 0, |
| 6691 | length = obj.length, |
| 6692 | isArray = isArraylike( obj ); |
| 6693 | |
| 6694 | if ( args ) { |
| 6695 | if ( isArray ) { |
| 6696 | for ( ; i < length; i++ ) { |
| 6697 | value = callback.apply( obj[ i ], args ); |
| 6698 | |
| 6699 | if ( value === false ) { |
| 6700 | break; |
| 6701 | } |
| 6702 | } |
| 6703 | } else { |
| 6704 | for ( i in obj ) { |
| 6705 | value = callback.apply( obj[ i ], args ); |
| 6706 | |
| 6707 | if ( value === false ) { |
| 6708 | break; |
| 6709 | } |
| 6710 | } |
| 6711 | } |
| 6712 | |
| 6713 | // A special, fast, case for the most common use of each |
| 6714 | } else { |
| 6715 | if ( isArray ) { |
| 6716 | for ( ; i < length; i++ ) { |
| 6717 | value = callback.call( obj[ i ], i, obj[ i ] ); |
| 6718 | |
| 6719 | if ( value === false ) { |
| 6720 | break; |
| 6721 | } |
| 6722 | } |
| 6723 | } else { |
| 6724 | for ( i in obj ) { |
| 6725 | value = callback.call( obj[ i ], i, obj[ i ] ); |
| 6726 | |
| 6727 | if ( value === false ) { |
| 6728 | break; |
| 6729 | } |
| 6730 | } |
| 6731 | } |
| 6732 | } |
| 6733 | |
| 6734 | return obj; |
| 6735 | }, |
| 6736 | |
| 6737 | // Support: Android<4.1 |
| 6738 | trim: function( text ) { |
| 6739 | return text == null ? |
| 6740 | "" : |
| 6741 | ( text + "" ).replace( rtrim, "" ); |
| 6742 | }, |
| 6743 | |
| 6744 | // results is for internal usage only |
| 6745 | makeArray: function( arr, results ) { |
| 6746 | var ret = results || []; |
| 6747 | |
| 6748 | if ( arr != null ) { |
| 6749 | if ( isArraylike( Object(arr) ) ) { |
| 6750 | jQuery.merge( ret, |
| 6751 | typeof arr === "string" ? |
| 6752 | [ arr ] : arr |
| 6753 | ); |
| 6754 | } else { |
| 6755 | push.call( ret, arr ); |
| 6756 | } |
| 6757 | } |
| 6758 | |
| 6759 | return ret; |
| 6760 | }, |
| 6761 | |
| 6762 | inArray: function( elem, arr, i ) { |
| 6763 | return arr == null ? -1 : indexOf.call( arr, elem, i ); |
| 6764 | }, |
| 6765 | |
| 6766 | merge: function( first, second ) { |
| 6767 | var len = +second.length, |
| 6768 | j = 0, |
| 6769 | i = first.length; |
| 6770 | |
| 6771 | for ( ; j < len; j++ ) { |
| 6772 | first[ i++ ] = second[ j ]; |
| 6773 | } |
| 6774 | |
| 6775 | first.length = i; |
| 6776 | |
| 6777 | return first; |
| 6778 | }, |
| 6779 | |
| 6780 | grep: function( elems, callback, invert ) { |
| 6781 | var callbackInverse, |
| 6782 | matches = [], |
| 6783 | i = 0, |
| 6784 | length = elems.length, |
| 6785 | callbackExpect = !invert; |
| 6786 | |
| 6787 | // Go through the array, only saving the items |
| 6788 | // that pass the validator function |
| 6789 | for ( ; i < length; i++ ) { |
| 6790 | callbackInverse = !callback( elems[ i ], i ); |
| 6791 | if ( callbackInverse !== callbackExpect ) { |
| 6792 | matches.push( elems[ i ] ); |
| 6793 | } |
| 6794 | } |
| 6795 | |
| 6796 | return matches; |
| 6797 | }, |
| 6798 | |
| 6799 | // arg is for internal usage only |
| 6800 | map: function( elems, callback, arg ) { |
| 6801 | var value, |
| 6802 | i = 0, |
| 6803 | length = elems.length, |
| 6804 | isArray = isArraylike( elems ), |
| 6805 | ret = []; |
| 6806 | |
| 6807 | // Go through the array, translating each of the items to their new values |
| 6808 | if ( isArray ) { |
| 6809 | for ( ; i < length; i++ ) { |
| 6810 | value = callback( elems[ i ], i, arg ); |
| 6811 | |
| 6812 | if ( value != null ) { |
| 6813 | ret.push( value ); |
| 6814 | } |
| 6815 | } |
| 6816 | |
| 6817 | // Go through every key on the object, |
| 6818 | } else { |
| 6819 | for ( i in elems ) { |
| 6820 | value = callback( elems[ i ], i, arg ); |
| 6821 | |
| 6822 | if ( value != null ) { |
| 6823 | ret.push( value ); |
| 6824 | } |
| 6825 | } |
| 6826 | } |
| 6827 | |
| 6828 | // Flatten any nested arrays |
| 6829 | return concat.apply( [], ret ); |
| 6830 | }, |
| 6831 | |
| 6832 | // A global GUID counter for objects |
| 6833 | guid: 1, |
| 6834 | |
| 6835 | // Bind a function to a context, optionally partially applying any |
| 6836 | // arguments. |
| 6837 | proxy: function( fn, context ) { |
| 6838 | var tmp, args, proxy; |
| 6839 | |
| 6840 | if ( typeof context === "string" ) { |
| 6841 | tmp = fn[ context ]; |
| 6842 | context = fn; |
| 6843 | fn = tmp; |
| 6844 | } |
| 6845 | |
| 6846 | // Quick check to determine if target is callable, in the spec |
| 6847 | // this throws a TypeError, but we will just return undefined. |
| 6848 | if ( !jQuery.isFunction( fn ) ) { |
| 6849 | return undefined; |
| 6850 | } |
| 6851 | |
| 6852 | // Simulated bind |
| 6853 | args = slice.call( arguments, 2 ); |
| 6854 | proxy = function() { |
| 6855 | return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); |
| 6856 | }; |
| 6857 | |
| 6858 | // Set the guid of unique handler to the same of original handler, so it can be removed |
| 6859 | proxy.guid = fn.guid = fn.guid || jQuery.guid++; |
| 6860 | |
| 6861 | return proxy; |
| 6862 | }, |
| 6863 | |
| 6864 | now: Date.now, |
| 6865 | |
| 6866 | // jQuery.support is not used in Core but other projects attach their |
| 6867 | // properties to it so it needs to exist. |
| 6868 | support: support |
| 6869 | }); |
| 6870 | |
| 6871 | // Populate the class2type map |
| 6872 | jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { |
| 6873 | class2type[ "[object " + name + "]" ] = name.toLowerCase(); |
| 6874 | }); |
| 6875 | |
| 6876 | function isArraylike( obj ) { |
| 6877 | |
| 6878 | // Support: iOS 8.2 (not reproducible in simulator) |
| 6879 | // `in` check used to prevent JIT error (gh-2145) |
| 6880 | // hasOwn isn't used here due to false negatives |
| 6881 | // regarding Nodelist length in IE |
| 6882 | var length = "length" in obj && obj.length, |
| 6883 | type = jQuery.type( obj ); |
| 6884 | |
| 6885 | if ( type === "function" || jQuery.isWindow( obj ) ) { |
| 6886 | return false; |
| 6887 | } |
| 6888 | |
| 6889 | if ( obj.nodeType === 1 && length ) { |
| 6890 | return true; |
| 6891 | } |
| 6892 | |
| 6893 | return type === "array" || length === 0 || |
| 6894 | typeof length === "number" && length > 0 && ( length - 1 ) in obj; |
| 6895 | } |
| 6896 | var Sizzle = |
| 6897 | /*! |
| 6898 | * Sizzle CSS Selector Engine v2.2.0-pre |
| 6899 | * http://sizzlejs.com/ |
| 6900 | * |
| 6901 | * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors |
| 6902 | * Released under the MIT license |
| 6903 | * http://jquery.org/license |
| 6904 | * |
| 6905 | * Date: 2014-12-16 |
| 6906 | */ |
| 6907 | (function( window ) { |
| 6908 | |
| 6909 | var i, |
| 6910 | support, |
| 6911 | Expr, |
| 6912 | getText, |
| 6913 | isXML, |
| 6914 | tokenize, |
| 6915 | compile, |
| 6916 | select, |
| 6917 | outermostContext, |
| 6918 | sortInput, |
| 6919 | hasDuplicate, |
| 6920 | |
| 6921 | // Local document vars |
| 6922 | setDocument, |
| 6923 | document, |
| 6924 | docElem, |
| 6925 | documentIsHTML, |
| 6926 | rbuggyQSA, |
| 6927 | rbuggyMatches, |
| 6928 | matches, |
| 6929 | contains, |
| 6930 | |
| 6931 | // Instance-specific data |
| 6932 | expando = "sizzle" + 1 * new Date(), |
| 6933 | preferredDoc = window.document, |
| 6934 | dirruns = 0, |
| 6935 | done = 0, |
| 6936 | classCache = createCache(), |
| 6937 | tokenCache = createCache(), |
| 6938 | compilerCache = createCache(), |
| 6939 | sortOrder = function( a, b ) { |
| 6940 | if ( a === b ) { |
| 6941 | hasDuplicate = true; |
| 6942 | } |
| 6943 | return 0; |
| 6944 | }, |
| 6945 | |
| 6946 | // General-purpose constants |
| 6947 | MAX_NEGATIVE = 1 << 31, |
| 6948 | |
| 6949 | // Instance methods |
| 6950 | hasOwn = ({}).hasOwnProperty, |
| 6951 | arr = [], |
| 6952 | pop = arr.pop, |
| 6953 | push_native = arr.push, |
| 6954 | push = arr.push, |
| 6955 | slice = arr.slice, |
| 6956 | // Use a stripped-down indexOf as it's faster than native |
| 6957 | // http://jsperf.com/thor-indexof-vs-for/5 |
| 6958 | indexOf = function( list, elem ) { |
| 6959 | var i = 0, |
| 6960 | len = list.length; |
| 6961 | for ( ; i < len; i++ ) { |
| 6962 | if ( list[i] === elem ) { |
| 6963 | return i; |
| 6964 | } |
| 6965 | } |
| 6966 | return -1; |
| 6967 | }, |
| 6968 | |
| 6969 | booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", |
| 6970 | |
| 6971 | // Regular expressions |
| 6972 | |
| 6973 | // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace |
| 6974 | whitespace = "[\\x20\\t\\r\\n\\f]", |
| 6975 | // http://www.w3.org/TR/css3-syntax/#characters |
| 6976 | characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", |
| 6977 | |
| 6978 | // Loosely modeled on CSS identifier characters |
| 6979 | // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors |
| 6980 | // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier |
| 6981 | identifier = characterEncoding.replace( "w", "w#" ), |
| 6982 | |
| 6983 | // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors |
| 6984 | attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace + |
| 6985 | // Operator (capture 2) |
| 6986 | "*([*^$|!~]?=)" + whitespace + |
| 6987 | // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" |
| 6988 | "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + |
| 6989 | "*\\]", |
| 6990 | |
| 6991 | pseudos = ":(" + characterEncoding + ")(?:\\((" + |
| 6992 | // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: |
| 6993 | // 1. quoted (capture 3; capture 4 or capture 5) |
| 6994 | "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + |
| 6995 | // 2. simple (capture 6) |
| 6996 | "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + |
| 6997 | // 3. anything else (capture 2) |
| 6998 | ".*" + |
| 6999 | ")\\)|)", |
| 7000 | |
| 7001 | // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter |
| 7002 | rwhitespace = new RegExp( whitespace + "+", "g" ), |
| 7003 | rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), |
| 7004 | |
| 7005 | rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), |
| 7006 | rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), |
| 7007 | |
| 7008 | rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), |
| 7009 | |
| 7010 | rpseudo = new RegExp( pseudos ), |
| 7011 | ridentifier = new RegExp( "^" + identifier + "$" ), |
| 7012 | |
| 7013 | matchExpr = { |
| 7014 | "ID": new RegExp( "^#(" + characterEncoding + ")" ), |
| 7015 | "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), |
| 7016 | "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), |
| 7017 | "ATTR": new RegExp( "^" + attributes ), |
| 7018 | "PSEUDO": new RegExp( "^" + pseudos ), |
| 7019 | "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + |
| 7020 | "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + |
| 7021 | "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), |
| 7022 | "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), |
| 7023 | // For use in libraries implementing .is() |
| 7024 | // We use this for POS matching in `select` |
| 7025 | "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + |
| 7026 | whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) |
| 7027 | }, |
| 7028 | |
| 7029 | rinputs = /^(?:input|select|textarea|button)$/i, |
| 7030 | rheader = /^h\d$/i, |
| 7031 | |
| 7032 | rnative = /^[^{]+\{\s*\[native \w/, |
| 7033 | |
| 7034 | // Easily-parseable/retrievable ID or TAG or CLASS selectors |
| 7035 | rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, |
| 7036 | |
| 7037 | rsibling = /[+~]/, |
| 7038 | rescape = /'|\\/g, |
| 7039 | |
| 7040 | // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters |
| 7041 | runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), |
| 7042 | funescape = function( _, escaped, escapedWhitespace ) { |
| 7043 | var high = "0x" + escaped - 0x10000; |
| 7044 | // NaN means non-codepoint |
| 7045 | // Support: Firefox<24 |
| 7046 | // Workaround erroneous numeric interpretation of +"0x" |
| 7047 | return high !== high || escapedWhitespace ? |
| 7048 | escaped : |
| 7049 | high < 0 ? |
| 7050 | // BMP codepoint |
| 7051 | String.fromCharCode( high + 0x10000 ) : |
| 7052 | // Supplemental Plane codepoint (surrogate pair) |
| 7053 | String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); |
| 7054 | }, |
| 7055 | |
| 7056 | // Used for iframes |
| 7057 | // See setDocument() |
| 7058 | // Removing the function wrapper causes a "Permission Denied" |
| 7059 | // error in IE |
| 7060 | unloadHandler = function() { |
| 7061 | setDocument(); |
| 7062 | }; |
| 7063 | |
| 7064 | // Optimize for push.apply( _, NodeList ) |
| 7065 | try { |
| 7066 | push.apply( |
| 7067 | (arr = slice.call( preferredDoc.childNodes )), |
| 7068 | preferredDoc.childNodes |
| 7069 | ); |
| 7070 | // Support: Android<4.0 |
| 7071 | // Detect silently failing push.apply |
| 7072 | arr[ preferredDoc.childNodes.length ].nodeType; |
| 7073 | } catch ( e ) { |
| 7074 | push = { apply: arr.length ? |
| 7075 | |
| 7076 | // Leverage slice if possible |
| 7077 | function( target, els ) { |
| 7078 | push_native.apply( target, slice.call(els) ); |
| 7079 | } : |
| 7080 | |
| 7081 | // Support: IE<9 |
| 7082 | // Otherwise append directly |
| 7083 | function( target, els ) { |
| 7084 | var j = target.length, |
| 7085 | i = 0; |
| 7086 | // Can't trust NodeList.length |
| 7087 | while ( (target[j++] = els[i++]) ) {} |
| 7088 | target.length = j - 1; |
| 7089 | } |
| 7090 | }; |
| 7091 | } |
| 7092 | |
| 7093 | function Sizzle( selector, context, results, seed ) { |
| 7094 | var match, elem, m, nodeType, |
| 7095 | // QSA vars |
| 7096 | i, groups, old, nid, newContext, newSelector; |
| 7097 | |
| 7098 | if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { |
| 7099 | setDocument( context ); |
| 7100 | } |
| 7101 | |
| 7102 | context = context || document; |
| 7103 | results = results || []; |
| 7104 | nodeType = context.nodeType; |
| 7105 | |
| 7106 | if ( typeof selector !== "string" || !selector || |
| 7107 | nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { |
| 7108 | |
| 7109 | return results; |
| 7110 | } |
| 7111 | |
| 7112 | if ( !seed && documentIsHTML ) { |
| 7113 | |
| 7114 | // Try to shortcut find operations when possible (e.g., not under DocumentFragment) |
| 7115 | if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { |
| 7116 | // Speed-up: Sizzle("#ID") |
| 7117 | if ( (m = match[1]) ) { |
| 7118 | if ( nodeType === 9 ) { |
| 7119 | elem = context.getElementById( m ); |
| 7120 | // Check parentNode to catch when Blackberry 4.6 returns |
| 7121 | // nodes that are no longer in the document (jQuery #6963) |
| 7122 | if ( elem && elem.parentNode ) { |
| 7123 | // Handle the case where IE, Opera, and Webkit return items |
| 7124 | // by name instead of ID |
| 7125 | if ( elem.id === m ) { |
| 7126 | results.push( elem ); |
| 7127 | return results; |
| 7128 | } |
| 7129 | } else { |
| 7130 | return results; |
| 7131 | } |
| 7132 | } else { |
| 7133 | // Context is not a document |
| 7134 | if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && |
| 7135 | contains( context, elem ) && elem.id === m ) { |
| 7136 | results.push( elem ); |
| 7137 | return results; |
| 7138 | } |
| 7139 | } |
| 7140 | |
| 7141 | // Speed-up: Sizzle("TAG") |
| 7142 | } else if ( match[2] ) { |
| 7143 | push.apply( results, context.getElementsByTagName( selector ) ); |
| 7144 | return results; |
| 7145 | |
| 7146 | // Speed-up: Sizzle(".CLASS") |
| 7147 | } else if ( (m = match[3]) && support.getElementsByClassName ) { |
| 7148 | push.apply( results, context.getElementsByClassName( m ) ); |
| 7149 | return results; |
| 7150 | } |
| 7151 | } |
| 7152 | |
| 7153 | // QSA path |
| 7154 | if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { |
| 7155 | nid = old = expando; |
| 7156 | newContext = context; |
| 7157 | newSelector = nodeType !== 1 && selector; |
| 7158 | |
| 7159 | // qSA works strangely on Element-rooted queries |
| 7160 | // We can work around this by specifying an extra ID on the root |
| 7161 | // and working up from there (Thanks to Andrew Dupont for the technique) |
| 7162 | // IE 8 doesn't work on object elements |
| 7163 | if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { |
| 7164 | groups = tokenize( selector ); |
| 7165 | |
| 7166 | if ( (old = context.getAttribute("id")) ) { |
| 7167 | nid = old.replace( rescape, "\\$&" ); |
| 7168 | } else { |
| 7169 | context.setAttribute( "id", nid ); |
| 7170 | } |
| 7171 | nid = "[id='" + nid + "'] "; |
| 7172 | |
| 7173 | i = groups.length; |
| 7174 | while ( i-- ) { |
| 7175 | groups[i] = nid + toSelector( groups[i] ); |
| 7176 | } |
| 7177 | newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; |
| 7178 | newSelector = groups.join(","); |
| 7179 | } |
| 7180 | |
| 7181 | if ( newSelector ) { |
| 7182 | try { |
| 7183 | push.apply( results, |
| 7184 | newContext.querySelectorAll( newSelector ) |
| 7185 | ); |
| 7186 | return results; |
| 7187 | } catch(qsaError) { |
| 7188 | } finally { |
| 7189 | if ( !old ) { |
| 7190 | context.removeAttribute("id"); |
| 7191 | } |
| 7192 | } |
| 7193 | } |
| 7194 | } |
| 7195 | } |
| 7196 | |
| 7197 | // All others |
| 7198 | return select( selector.replace( rtrim, "$1" ), context, results, seed ); |
| 7199 | } |
| 7200 | |
| 7201 | /** |
| 7202 | * Create key-value caches of limited size |
| 7203 | * @returns {Function(string, Object)} Returns the Object data after storing it on itself with |
| 7204 | * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) |
| 7205 | * deleting the oldest entry |
| 7206 | */ |
| 7207 | function createCache() { |
| 7208 | var keys = []; |
| 7209 | |
| 7210 | function cache( key, value ) { |
| 7211 | // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) |
| 7212 | if ( keys.push( key + " " ) > Expr.cacheLength ) { |
| 7213 | // Only keep the most recent entries |
| 7214 | delete cache[ keys.shift() ]; |
| 7215 | } |
| 7216 | return (cache[ key + " " ] = value); |
| 7217 | } |
| 7218 | return cache; |
| 7219 | } |
| 7220 | |
| 7221 | /** |
| 7222 | * Mark a function for special use by Sizzle |
| 7223 | * @param {Function} fn The function to mark |
| 7224 | */ |
| 7225 | function markFunction( fn ) { |
| 7226 | fn[ expando ] = true; |
| 7227 | return fn; |
| 7228 | } |
| 7229 | |
| 7230 | /** |
| 7231 | * Support testing using an element |
| 7232 | * @param {Function} fn Passed the created div and expects a boolean result |
| 7233 | */ |
| 7234 | function assert( fn ) { |
| 7235 | var div = document.createElement("div"); |
| 7236 | |
| 7237 | try { |
| 7238 | return !!fn( div ); |
| 7239 | } catch (e) { |
| 7240 | return false; |
| 7241 | } finally { |
| 7242 | // Remove from its parent by default |
| 7243 | if ( div.parentNode ) { |
| 7244 | div.parentNode.removeChild( div ); |
| 7245 | } |
| 7246 | // release memory in IE |
| 7247 | div = null; |
| 7248 | } |
| 7249 | } |
| 7250 | |
| 7251 | /** |
| 7252 | * Adds the same handler for all of the specified attrs |
| 7253 | * @param {String} attrs Pipe-separated list of attributes |
| 7254 | * @param {Function} handler The method that will be applied |
| 7255 | */ |
| 7256 | function addHandle( attrs, handler ) { |
| 7257 | var arr = attrs.split("|"), |
| 7258 | i = attrs.length; |
| 7259 | |
| 7260 | while ( i-- ) { |
| 7261 | Expr.attrHandle[ arr[i] ] = handler; |
| 7262 | } |
| 7263 | } |
| 7264 | |
| 7265 | /** |
| 7266 | * Checks document order of two siblings |
| 7267 | * @param {Element} a |
| 7268 | * @param {Element} b |
| 7269 | * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b |
| 7270 | */ |
| 7271 | function siblingCheck( a, b ) { |
| 7272 | var cur = b && a, |
| 7273 | diff = cur && a.nodeType === 1 && b.nodeType === 1 && |
| 7274 | ( ~b.sourceIndex || MAX_NEGATIVE ) - |
| 7275 | ( ~a.sourceIndex || MAX_NEGATIVE ); |
| 7276 | |
| 7277 | // Use IE sourceIndex if available on both nodes |
| 7278 | if ( diff ) { |
| 7279 | return diff; |
| 7280 | } |
| 7281 | |
| 7282 | // Check if b follows a |
| 7283 | if ( cur ) { |
| 7284 | while ( (cur = cur.nextSibling) ) { |
| 7285 | if ( cur === b ) { |
| 7286 | return -1; |
| 7287 | } |
| 7288 | } |
| 7289 | } |
| 7290 | |
| 7291 | return a ? 1 : -1; |
| 7292 | } |
| 7293 | |
| 7294 | /** |
| 7295 | * Returns a function to use in pseudos for input types |
| 7296 | * @param {String} type |
| 7297 | */ |
| 7298 | function createInputPseudo( type ) { |
| 7299 | return function( elem ) { |
| 7300 | var name = elem.nodeName.toLowerCase(); |
| 7301 | return name === "input" && elem.type === type; |
| 7302 | }; |
| 7303 | } |
| 7304 | |
| 7305 | /** |
| 7306 | * Returns a function to use in pseudos for buttons |
| 7307 | * @param {String} type |
| 7308 | */ |
| 7309 | function createButtonPseudo( type ) { |
| 7310 | return function( elem ) { |
| 7311 | var name = elem.nodeName.toLowerCase(); |
| 7312 | return (name === "input" || name === "button") && elem.type === type; |
| 7313 | }; |
| 7314 | } |
| 7315 | |
| 7316 | /** |
| 7317 | * Returns a function to use in pseudos for positionals |
| 7318 | * @param {Function} fn |
| 7319 | */ |
| 7320 | function createPositionalPseudo( fn ) { |
| 7321 | return markFunction(function( argument ) { |
| 7322 | argument = +argument; |
| 7323 | return markFunction(function( seed, matches ) { |
| 7324 | var j, |
| 7325 | matchIndexes = fn( [], seed.length, argument ), |
| 7326 | i = matchIndexes.length; |
| 7327 | |
| 7328 | // Match elements found at the specified indexes |
| 7329 | while ( i-- ) { |
| 7330 | if ( seed[ (j = matchIndexes[i]) ] ) { |
| 7331 | seed[j] = !(matches[j] = seed[j]); |
| 7332 | } |
| 7333 | } |
| 7334 | }); |
| 7335 | }); |
| 7336 | } |
| 7337 | |
| 7338 | /** |
| 7339 | * Checks a node for validity as a Sizzle context |
| 7340 | * @param {Element|Object=} context |
| 7341 | * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value |
| 7342 | */ |
| 7343 | function testContext( context ) { |
| 7344 | return context && typeof context.getElementsByTagName !== "undefined" && context; |
| 7345 | } |
| 7346 | |
| 7347 | // Expose support vars for convenience |
| 7348 | support = Sizzle.support = {}; |
| 7349 | |
| 7350 | /** |
| 7351 | * Detects XML nodes |
| 7352 | * @param {Element|Object} elem An element or a document |
| 7353 | * @returns {Boolean} True iff elem is a non-HTML XML node |
| 7354 | */ |
| 7355 | isXML = Sizzle.isXML = function( elem ) { |
| 7356 | // documentElement is verified for cases where it doesn't yet exist |
| 7357 | // (such as loading iframes in IE - #4833) |
| 7358 | var documentElement = elem && (elem.ownerDocument || elem).documentElement; |
| 7359 | return documentElement ? documentElement.nodeName !== "HTML" : false; |
| 7360 | }; |
| 7361 | |
| 7362 | /** |
| 7363 | * Sets document-related variables once based on the current document |
| 7364 | * @param {Element|Object} [doc] An element or document object to use to set the document |
| 7365 | * @returns {Object} Returns the current document |
| 7366 | */ |
| 7367 | setDocument = Sizzle.setDocument = function( node ) { |
| 7368 | var hasCompare, parent, |
| 7369 | doc = node ? node.ownerDocument || node : preferredDoc; |
| 7370 | |
| 7371 | // If no document and documentElement is available, return |
| 7372 | if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { |
| 7373 | return document; |
| 7374 | } |
| 7375 | |
| 7376 | // Set our document |
| 7377 | document = doc; |
| 7378 | docElem = doc.documentElement; |
| 7379 | parent = doc.defaultView; |
| 7380 | |
| 7381 | // Support: IE>8 |
| 7382 | // If iframe document is assigned to "document" variable and if iframe has been reloaded, |
| 7383 | // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 |
| 7384 | // IE6-8 do not support the defaultView property so parent will be undefined |
| 7385 | if ( parent && parent !== parent.top ) { |
| 7386 | // IE11 does not have attachEvent, so all must suffer |
| 7387 | if ( parent.addEventListener ) { |
| 7388 | parent.addEventListener( "unload", unloadHandler, false ); |
| 7389 | } else if ( parent.attachEvent ) { |
| 7390 | parent.attachEvent( "onunload", unloadHandler ); |
| 7391 | } |
| 7392 | } |
| 7393 | |
| 7394 | /* Support tests |
| 7395 | ---------------------------------------------------------------------- */ |
| 7396 | documentIsHTML = !isXML( doc ); |
| 7397 | |
| 7398 | /* Attributes |
| 7399 | ---------------------------------------------------------------------- */ |
| 7400 | |
| 7401 | // Support: IE<8 |
| 7402 | // Verify that getAttribute really returns attributes and not properties |
| 7403 | // (excepting IE8 booleans) |
| 7404 | support.attributes = assert(function( div ) { |
| 7405 | div.className = "i"; |
| 7406 | return !div.getAttribute("className"); |
| 7407 | }); |
| 7408 | |
| 7409 | /* getElement(s)By* |
| 7410 | ---------------------------------------------------------------------- */ |
| 7411 | |
| 7412 | // Check if getElementsByTagName("*") returns only elements |
| 7413 | support.getElementsByTagName = assert(function( div ) { |
| 7414 | div.appendChild( doc.createComment("") ); |
| 7415 | return !div.getElementsByTagName("*").length; |
| 7416 | }); |
| 7417 | |
| 7418 | // Support: IE<9 |
| 7419 | support.getElementsByClassName = rnative.test( doc.getElementsByClassName ); |
| 7420 | |
| 7421 | // Support: IE<10 |
| 7422 | // Check if getElementById returns elements by name |
| 7423 | // The broken getElementById methods don't pick up programatically-set names, |
| 7424 | // so use a roundabout getElementsByName test |
| 7425 | support.getById = assert(function( div ) { |
| 7426 | docElem.appendChild( div ).id = expando; |
| 7427 | return !doc.getElementsByName || !doc.getElementsByName( expando ).length; |
| 7428 | }); |
| 7429 | |
| 7430 | // ID find and filter |
| 7431 | if ( support.getById ) { |
| 7432 | Expr.find["ID"] = function( id, context ) { |
| 7433 | if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { |
| 7434 | var m = context.getElementById( id ); |
| 7435 | // Check parentNode to catch when Blackberry 4.6 returns |
| 7436 | // nodes that are no longer in the document #6963 |
| 7437 | return m && m.parentNode ? [ m ] : []; |
| 7438 | } |
| 7439 | }; |
| 7440 | Expr.filter["ID"] = function( id ) { |
| 7441 | var attrId = id.replace( runescape, funescape ); |
| 7442 | return function( elem ) { |
| 7443 | return elem.getAttribute("id") === attrId; |
| 7444 | }; |
| 7445 | }; |
| 7446 | } else { |
| 7447 | // Support: IE6/7 |
| 7448 | // getElementById is not reliable as a find shortcut |
| 7449 | delete Expr.find["ID"]; |
| 7450 | |
| 7451 | Expr.filter["ID"] = function( id ) { |
| 7452 | var attrId = id.replace( runescape, funescape ); |
| 7453 | return function( elem ) { |
| 7454 | var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); |
| 7455 | return node && node.value === attrId; |
| 7456 | }; |
| 7457 | }; |
| 7458 | } |
| 7459 | |
| 7460 | // Tag |
| 7461 | Expr.find["TAG"] = support.getElementsByTagName ? |
| 7462 | function( tag, context ) { |
| 7463 | if ( typeof context.getElementsByTagName !== "undefined" ) { |
| 7464 | return context.getElementsByTagName( tag ); |
| 7465 | |
| 7466 | // DocumentFragment nodes don't have gEBTN |
| 7467 | } else if ( support.qsa ) { |
| 7468 | return context.querySelectorAll( tag ); |
| 7469 | } |
| 7470 | } : |
| 7471 | |
| 7472 | function( tag, context ) { |
| 7473 | var elem, |
| 7474 | tmp = [], |
| 7475 | i = 0, |
| 7476 | // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too |
| 7477 | results = context.getElementsByTagName( tag ); |
| 7478 | |
| 7479 | // Filter out possible comments |
| 7480 | if ( tag === "*" ) { |
| 7481 | while ( (elem = results[i++]) ) { |
| 7482 | if ( elem.nodeType === 1 ) { |
| 7483 | tmp.push( elem ); |
| 7484 | } |
| 7485 | } |
| 7486 | |
| 7487 | return tmp; |
| 7488 | } |
| 7489 | return results; |
| 7490 | }; |
| 7491 | |
| 7492 | // Class |
| 7493 | Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { |
| 7494 | if ( documentIsHTML ) { |
| 7495 | return context.getElementsByClassName( className ); |
| 7496 | } |
| 7497 | }; |
| 7498 | |
| 7499 | /* QSA/matchesSelector |
| 7500 | ---------------------------------------------------------------------- */ |
| 7501 | |
| 7502 | // QSA and matchesSelector support |
| 7503 | |
| 7504 | // matchesSelector(:active) reports false when true (IE9/Opera 11.5) |
| 7505 | rbuggyMatches = []; |
| 7506 | |
| 7507 | // qSa(:focus) reports false when true (Chrome 21) |
| 7508 | // We allow this because of a bug in IE8/9 that throws an error |
| 7509 | // whenever `document.activeElement` is accessed on an iframe |
| 7510 | // So, we allow :focus to pass through QSA all the time to avoid the IE error |
| 7511 | // See http://bugs.jquery.com/ticket/13378 |
| 7512 | rbuggyQSA = []; |
| 7513 | |
| 7514 | if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { |
| 7515 | // Build QSA regex |
| 7516 | // Regex strategy adopted from Diego Perini |
| 7517 | assert(function( div ) { |
| 7518 | // Select is set to empty string on purpose |
| 7519 | // This is to test IE's treatment of not explicitly |
| 7520 | // setting a boolean content attribute, |
| 7521 | // since its presence should be enough |
| 7522 | // http://bugs.jquery.com/ticket/12359 |
| 7523 | docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" + |
| 7524 | "<select id='" + expando + "-\f]' msallowcapture=''>" + |
| 7525 | "<option selected=''></option></select>"; |
| 7526 | |
| 7527 | // Support: IE8, Opera 11-12.16 |
| 7528 | // Nothing should be selected when empty strings follow ^= or $= or *= |
| 7529 | // The test attribute must be unknown in Opera but "safe" for WinRT |
| 7530 | // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section |
| 7531 | if ( div.querySelectorAll("[msallowcapture^='']").length ) { |
| 7532 | rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); |
| 7533 | } |
| 7534 | |
| 7535 | // Support: IE8 |
| 7536 | // Boolean attributes and "value" are not treated correctly |
| 7537 | if ( !div.querySelectorAll("[selected]").length ) { |
| 7538 | rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); |
| 7539 | } |
| 7540 | |
| 7541 | // Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+ |
| 7542 | if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) { |
| 7543 | rbuggyQSA.push("~="); |
| 7544 | } |
| 7545 | |
| 7546 | // Webkit/Opera - :checked should return selected option elements |
| 7547 | // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked |
| 7548 | // IE8 throws error here and will not see later tests |
| 7549 | if ( !div.querySelectorAll(":checked").length ) { |
| 7550 | rbuggyQSA.push(":checked"); |
| 7551 | } |
| 7552 | |
| 7553 | // Support: Safari 8+, iOS 8+ |
| 7554 | // https://bugs.webkit.org/show_bug.cgi?id=136851 |
| 7555 | // In-page `selector#id sibing-combinator selector` fails |
| 7556 | if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) { |
| 7557 | rbuggyQSA.push(".#.+[+~]"); |
| 7558 | } |
| 7559 | }); |
| 7560 | |
| 7561 | assert(function( div ) { |
| 7562 | // Support: Windows 8 Native Apps |
| 7563 | // The type and name attributes are restricted during .innerHTML assignment |
| 7564 | var input = doc.createElement("input"); |
| 7565 | input.setAttribute( "type", "hidden" ); |
| 7566 | div.appendChild( input ).setAttribute( "name", "D" ); |
| 7567 | |
| 7568 | // Support: IE8 |
| 7569 | // Enforce case-sensitivity of name attribute |
| 7570 | if ( div.querySelectorAll("[name=d]").length ) { |
| 7571 | rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); |
| 7572 | } |
| 7573 | |
| 7574 | // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) |
| 7575 | // IE8 throws error here and will not see later tests |
| 7576 | if ( !div.querySelectorAll(":enabled").length ) { |
| 7577 | rbuggyQSA.push( ":enabled", ":disabled" ); |
| 7578 | } |
| 7579 | |
| 7580 | // Opera 10-11 does not throw on post-comma invalid pseudos |
| 7581 | div.querySelectorAll("*,:x"); |
| 7582 | rbuggyQSA.push(",.*:"); |
| 7583 | }); |
| 7584 | } |
| 7585 | |
| 7586 | if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || |
| 7587 | docElem.webkitMatchesSelector || |
| 7588 | docElem.mozMatchesSelector || |
| 7589 | docElem.oMatchesSelector || |
| 7590 | docElem.msMatchesSelector) )) ) { |
| 7591 | |
| 7592 | assert(function( div ) { |
| 7593 | // Check to see if it's possible to do matchesSelector |
| 7594 | // on a disconnected node (IE 9) |
| 7595 | support.disconnectedMatch = matches.call( div, "div" ); |
| 7596 | |
| 7597 | // This should fail with an exception |
| 7598 | // Gecko does not error, returns false instead |
| 7599 | matches.call( div, "[s!='']:x" ); |
| 7600 | rbuggyMatches.push( "!=", pseudos ); |
| 7601 | }); |
| 7602 | } |
| 7603 | |
| 7604 | rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); |
| 7605 | rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); |
| 7606 | |
| 7607 | /* Contains |
| 7608 | ---------------------------------------------------------------------- */ |
| 7609 | hasCompare = rnative.test( docElem.compareDocumentPosition ); |
| 7610 | |
| 7611 | // Element contains another |
| 7612 | // Purposefully does not implement inclusive descendent |
| 7613 | // As in, an element does not contain itself |
| 7614 | contains = hasCompare || rnative.test( docElem.contains ) ? |
| 7615 | function( a, b ) { |
| 7616 | var adown = a.nodeType === 9 ? a.documentElement : a, |
| 7617 | bup = b && b.parentNode; |
| 7618 | return a === bup || !!( bup && bup.nodeType === 1 && ( |
| 7619 | adown.contains ? |
| 7620 | adown.contains( bup ) : |
| 7621 | a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 |
| 7622 | )); |
| 7623 | } : |
| 7624 | function( a, b ) { |
| 7625 | if ( b ) { |
| 7626 | while ( (b = b.parentNode) ) { |
| 7627 | if ( b === a ) { |
| 7628 | return true; |
| 7629 | } |
| 7630 | } |
| 7631 | } |
| 7632 | return false; |
| 7633 | }; |
| 7634 | |
| 7635 | /* Sorting |
| 7636 | ---------------------------------------------------------------------- */ |
| 7637 | |
| 7638 | // Document order sorting |
| 7639 | sortOrder = hasCompare ? |
| 7640 | function( a, b ) { |
| 7641 | |
| 7642 | // Flag for duplicate removal |
| 7643 | if ( a === b ) { |
| 7644 | hasDuplicate = true; |
| 7645 | return 0; |
| 7646 | } |
| 7647 | |
| 7648 | // Sort on method existence if only one input has compareDocumentPosition |
| 7649 | var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; |
| 7650 | if ( compare ) { |
| 7651 | return compare; |
| 7652 | } |
| 7653 | |
| 7654 | // Calculate position if both inputs belong to the same document |
| 7655 | compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? |
| 7656 | a.compareDocumentPosition( b ) : |
| 7657 | |
| 7658 | // Otherwise we know they are disconnected |
| 7659 | 1; |
| 7660 | |
| 7661 | // Disconnected nodes |
| 7662 | if ( compare & 1 || |
| 7663 | (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { |
| 7664 | |
| 7665 | // Choose the first element that is related to our preferred document |
| 7666 | if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { |
| 7667 | return -1; |
| 7668 | } |
| 7669 | if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { |
| 7670 | return 1; |
| 7671 | } |
| 7672 | |
| 7673 | // Maintain original order |
| 7674 | return sortInput ? |
| 7675 | ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : |
| 7676 | 0; |
| 7677 | } |
| 7678 | |
| 7679 | return compare & 4 ? -1 : 1; |
| 7680 | } : |
| 7681 | function( a, b ) { |
| 7682 | // Exit early if the nodes are identical |
| 7683 | if ( a === b ) { |
| 7684 | hasDuplicate = true; |
| 7685 | return 0; |
| 7686 | } |
| 7687 | |
| 7688 | var cur, |
| 7689 | i = 0, |
| 7690 | aup = a.parentNode, |
| 7691 | bup = b.parentNode, |
| 7692 | ap = [ a ], |
| 7693 | bp = [ b ]; |
| 7694 | |
| 7695 | // Parentless nodes are either documents or disconnected |
| 7696 | if ( !aup || !bup ) { |
| 7697 | return a === doc ? -1 : |
| 7698 | b === doc ? 1 : |
| 7699 | aup ? -1 : |
| 7700 | bup ? 1 : |
| 7701 | sortInput ? |
| 7702 | ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : |
| 7703 | 0; |
| 7704 | |
| 7705 | // If the nodes are siblings, we can do a quick check |
| 7706 | } else if ( aup === bup ) { |
| 7707 | return siblingCheck( a, b ); |
| 7708 | } |
| 7709 | |
| 7710 | // Otherwise we need full lists of their ancestors for comparison |
| 7711 | cur = a; |
| 7712 | while ( (cur = cur.parentNode) ) { |
| 7713 | ap.unshift( cur ); |
| 7714 | } |
| 7715 | cur = b; |
| 7716 | while ( (cur = cur.parentNode) ) { |
| 7717 | bp.unshift( cur ); |
| 7718 | } |
| 7719 | |
| 7720 | // Walk down the tree looking for a discrepancy |
| 7721 | while ( ap[i] === bp[i] ) { |
| 7722 | i++; |
| 7723 | } |
| 7724 | |
| 7725 | return i ? |
| 7726 | // Do a sibling check if the nodes have a common ancestor |
| 7727 | siblingCheck( ap[i], bp[i] ) : |
| 7728 | |
| 7729 | // Otherwise nodes in our document sort first |
| 7730 | ap[i] === preferredDoc ? -1 : |
| 7731 | bp[i] === preferredDoc ? 1 : |
| 7732 | 0; |
| 7733 | }; |
| 7734 | |
| 7735 | return doc; |
| 7736 | }; |
| 7737 | |
| 7738 | Sizzle.matches = function( expr, elements ) { |
| 7739 | return Sizzle( expr, null, null, elements ); |
| 7740 | }; |
| 7741 | |
| 7742 | Sizzle.matchesSelector = function( elem, expr ) { |
| 7743 | // Set document vars if needed |
| 7744 | if ( ( elem.ownerDocument || elem ) !== document ) { |
| 7745 | setDocument( elem ); |
| 7746 | } |
| 7747 | |
| 7748 | // Make sure that attribute selectors are quoted |
| 7749 | expr = expr.replace( rattributeQuotes, "='$1']" ); |
| 7750 | |
| 7751 | if ( support.matchesSelector && documentIsHTML && |
| 7752 | ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && |
| 7753 | ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { |
| 7754 | |
| 7755 | try { |
| 7756 | var ret = matches.call( elem, expr ); |
| 7757 | |
| 7758 | // IE 9's matchesSelector returns false on disconnected nodes |
| 7759 | if ( ret || support.disconnectedMatch || |
| 7760 | // As well, disconnected nodes are said to be in a document |
| 7761 | // fragment in IE 9 |
| 7762 | elem.document && elem.document.nodeType !== 11 ) { |
| 7763 | return ret; |
| 7764 | } |
| 7765 | } catch (e) {} |
| 7766 | } |
| 7767 | |
| 7768 | return Sizzle( expr, document, null, [ elem ] ).length > 0; |
| 7769 | }; |
| 7770 | |
| 7771 | Sizzle.contains = function( context, elem ) { |
| 7772 | // Set document vars if needed |
| 7773 | if ( ( context.ownerDocument || context ) !== document ) { |
| 7774 | setDocument( context ); |
| 7775 | } |
| 7776 | return contains( context, elem ); |
| 7777 | }; |
| 7778 | |
| 7779 | Sizzle.attr = function( elem, name ) { |
| 7780 | // Set document vars if needed |
| 7781 | if ( ( elem.ownerDocument || elem ) !== document ) { |
| 7782 | setDocument( elem ); |
| 7783 | } |
| 7784 | |
| 7785 | var fn = Expr.attrHandle[ name.toLowerCase() ], |
| 7786 | // Don't get fooled by Object.prototype properties (jQuery #13807) |
| 7787 | val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? |
| 7788 | fn( elem, name, !documentIsHTML ) : |
| 7789 | undefined; |
| 7790 | |
| 7791 | return val !== undefined ? |
| 7792 | val : |
| 7793 | support.attributes || !documentIsHTML ? |
| 7794 | elem.getAttribute( name ) : |
| 7795 | (val = elem.getAttributeNode(name)) && val.specified ? |
| 7796 | val.value : |
| 7797 | null; |
| 7798 | }; |
| 7799 | |
| 7800 | Sizzle.error = function( msg ) { |
| 7801 | throw new Error( "Syntax error, unrecognized expression: " + msg ); |
| 7802 | }; |
| 7803 | |
| 7804 | /** |
| 7805 | * Document sorting and removing duplicates |
| 7806 | * @param {ArrayLike} results |
| 7807 | */ |
| 7808 | Sizzle.uniqueSort = function( results ) { |
| 7809 | var elem, |
| 7810 | duplicates = [], |
| 7811 | j = 0, |
| 7812 | i = 0; |
| 7813 | |
| 7814 | // Unless we *know* we can detect duplicates, assume their presence |
| 7815 | hasDuplicate = !support.detectDuplicates; |
| 7816 | sortInput = !support.sortStable && results.slice( 0 ); |
| 7817 | results.sort( sortOrder ); |
| 7818 | |
| 7819 | if ( hasDuplicate ) { |
| 7820 | while ( (elem = results[i++]) ) { |
| 7821 | if ( elem === results[ i ] ) { |
| 7822 | j = duplicates.push( i ); |
| 7823 | } |
| 7824 | } |
| 7825 | while ( j-- ) { |
| 7826 | results.splice( duplicates[ j ], 1 ); |
| 7827 | } |
| 7828 | } |
| 7829 | |
| 7830 | // Clear input after sorting to release objects |
| 7831 | // See https://github.com/jquery/sizzle/pull/225 |
| 7832 | sortInput = null; |
| 7833 | |
| 7834 | return results; |
| 7835 | }; |
| 7836 | |
| 7837 | /** |
| 7838 | * Utility function for retrieving the text value of an array of DOM nodes |
| 7839 | * @param {Array|Element} elem |
| 7840 | */ |
| 7841 | getText = Sizzle.getText = function( elem ) { |
| 7842 | var node, |
| 7843 | ret = "", |
| 7844 | i = 0, |
| 7845 | nodeType = elem.nodeType; |
| 7846 | |
| 7847 | if ( !nodeType ) { |
| 7848 | // If no nodeType, this is expected to be an array |
| 7849 | while ( (node = elem[i++]) ) { |
| 7850 | // Do not traverse comment nodes |
| 7851 | ret += getText( node ); |
| 7852 | } |
| 7853 | } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { |
| 7854 | // Use textContent for elements |
| 7855 | // innerText usage removed for consistency of new lines (jQuery #11153) |
| 7856 | if ( typeof elem.textContent === "string" ) { |
| 7857 | return elem.textContent; |
| 7858 | } else { |
| 7859 | // Traverse its children |
| 7860 | for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { |
| 7861 | ret += getText( elem ); |
| 7862 | } |
| 7863 | } |
| 7864 | } else if ( nodeType === 3 || nodeType === 4 ) { |
| 7865 | return elem.nodeValue; |
| 7866 | } |
| 7867 | // Do not include comment or processing instruction nodes |
| 7868 | |
| 7869 | return ret; |
| 7870 | }; |
| 7871 | |
| 7872 | Expr = Sizzle.selectors = { |
| 7873 | |
| 7874 | // Can be adjusted by the user |
| 7875 | cacheLength: 50, |
| 7876 | |
| 7877 | createPseudo: markFunction, |
| 7878 | |
| 7879 | match: matchExpr, |
| 7880 | |
| 7881 | attrHandle: {}, |
| 7882 | |
| 7883 | find: {}, |
| 7884 | |
| 7885 | relative: { |
| 7886 | ">": { dir: "parentNode", first: true }, |
| 7887 | " ": { dir: "parentNode" }, |
| 7888 | "+": { dir: "previousSibling", first: true }, |
| 7889 | "~": { dir: "previousSibling" } |
| 7890 | }, |
| 7891 | |
| 7892 | preFilter: { |
| 7893 | "ATTR": function( match ) { |
| 7894 | match[1] = match[1].replace( runescape, funescape ); |
| 7895 | |
| 7896 | // Move the given value to match[3] whether quoted or unquoted |
| 7897 | match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); |
| 7898 | |
| 7899 | if ( match[2] === "~=" ) { |
| 7900 | match[3] = " " + match[3] + " "; |
| 7901 | } |
| 7902 | |
| 7903 | return match.slice( 0, 4 ); |
| 7904 | }, |
| 7905 | |
| 7906 | "CHILD": function( match ) { |
| 7907 | /* matches from matchExpr["CHILD"] |
| 7908 | 1 type (only|nth|...) |
| 7909 | 2 what (child|of-type) |
| 7910 | 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) |
| 7911 | 4 xn-component of xn+y argument ([+-]?\d*n|) |
| 7912 | 5 sign of xn-component |
| 7913 | 6 x of xn-component |
| 7914 | 7 sign of y-component |
| 7915 | 8 y of y-component |
| 7916 | */ |
| 7917 | match[1] = match[1].toLowerCase(); |
| 7918 | |
| 7919 | if ( match[1].slice( 0, 3 ) === "nth" ) { |
| 7920 | // nth-* requires argument |
| 7921 | if ( !match[3] ) { |
| 7922 | Sizzle.error( match[0] ); |
| 7923 | } |
| 7924 | |
| 7925 | // numeric x and y parameters for Expr.filter.CHILD |
| 7926 | // remember that false/true cast respectively to 0/1 |
| 7927 | match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); |
| 7928 | match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); |
| 7929 | |
| 7930 | // other types prohibit arguments |
| 7931 | } else if ( match[3] ) { |
| 7932 | Sizzle.error( match[0] ); |
| 7933 | } |
| 7934 | |
| 7935 | return match; |
| 7936 | }, |
| 7937 | |
| 7938 | "PSEUDO": function( match ) { |
| 7939 | var excess, |
| 7940 | unquoted = !match[6] && match[2]; |
| 7941 | |
| 7942 | if ( matchExpr["CHILD"].test( match[0] ) ) { |
| 7943 | return null; |
| 7944 | } |
| 7945 | |
| 7946 | // Accept quoted arguments as-is |
| 7947 | if ( match[3] ) { |
| 7948 | match[2] = match[4] || match[5] || ""; |
| 7949 | |
| 7950 | // Strip excess characters from unquoted arguments |
| 7951 | } else if ( unquoted && rpseudo.test( unquoted ) && |
| 7952 | // Get excess from tokenize (recursively) |
| 7953 | (excess = tokenize( unquoted, true )) && |
| 7954 | // advance to the next closing parenthesis |
| 7955 | (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { |
| 7956 | |
| 7957 | // excess is a negative index |
| 7958 | match[0] = match[0].slice( 0, excess ); |
| 7959 | match[2] = unquoted.slice( 0, excess ); |
| 7960 | } |
| 7961 | |
| 7962 | // Return only captures needed by the pseudo filter method (type and argument) |
| 7963 | return match.slice( 0, 3 ); |
| 7964 | } |
| 7965 | }, |
| 7966 | |
| 7967 | filter: { |
| 7968 | |
| 7969 | "TAG": function( nodeNameSelector ) { |
| 7970 | var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); |
| 7971 | return nodeNameSelector === "*" ? |
| 7972 | function() { return true; } : |
| 7973 | function( elem ) { |
| 7974 | return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; |
| 7975 | }; |
| 7976 | }, |
| 7977 | |
| 7978 | "CLASS": function( className ) { |
| 7979 | var pattern = classCache[ className + " " ]; |
| 7980 | |
| 7981 | return pattern || |
| 7982 | (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && |
| 7983 | classCache( className, function( elem ) { |
| 7984 | return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); |
| 7985 | }); |
| 7986 | }, |
| 7987 | |
| 7988 | "ATTR": function( name, operator, check ) { |
| 7989 | return function( elem ) { |
| 7990 | var result = Sizzle.attr( elem, name ); |
| 7991 | |
| 7992 | if ( result == null ) { |
| 7993 | return operator === "!="; |
| 7994 | } |
| 7995 | if ( !operator ) { |
| 7996 | return true; |
| 7997 | } |
| 7998 | |
| 7999 | result += ""; |
| 8000 | |
| 8001 | return operator === "=" ? result === check : |
| 8002 | operator === "!=" ? result !== check : |
| 8003 | operator === "^=" ? check && result.indexOf( check ) === 0 : |
| 8004 | operator === "*=" ? check && result.indexOf( check ) > -1 : |
| 8005 | operator === "$=" ? check && result.slice( -check.length ) === check : |
| 8006 | operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : |
| 8007 | operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : |
| 8008 | false; |
| 8009 | }; |
| 8010 | }, |
| 8011 | |
| 8012 | "CHILD": function( type, what, argument, first, last ) { |
| 8013 | var simple = type.slice( 0, 3 ) !== "nth", |
| 8014 | forward = type.slice( -4 ) !== "last", |
| 8015 | ofType = what === "of-type"; |
| 8016 | |
| 8017 | return first === 1 && last === 0 ? |
| 8018 | |
| 8019 | // Shortcut for :nth-*(n) |
| 8020 | function( elem ) { |
| 8021 | return !!elem.parentNode; |
| 8022 | } : |
| 8023 | |
| 8024 | function( elem, context, xml ) { |
| 8025 | var cache, outerCache, node, diff, nodeIndex, start, |
| 8026 | dir = simple !== forward ? "nextSibling" : "previousSibling", |
| 8027 | parent = elem.parentNode, |
| 8028 | name = ofType && elem.nodeName.toLowerCase(), |
| 8029 | useCache = !xml && !ofType; |
| 8030 | |
| 8031 | if ( parent ) { |
| 8032 | |
| 8033 | // :(first|last|only)-(child|of-type) |
| 8034 | if ( simple ) { |
| 8035 | while ( dir ) { |
| 8036 | node = elem; |
| 8037 | while ( (node = node[ dir ]) ) { |
| 8038 | if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { |
| 8039 | return false; |
| 8040 | } |
| 8041 | } |
| 8042 | // Reverse direction for :only-* (if we haven't yet done so) |
| 8043 | start = dir = type === "only" && !start && "nextSibling"; |
| 8044 | } |
| 8045 | return true; |
| 8046 | } |
| 8047 | |
| 8048 | start = [ forward ? parent.firstChild : parent.lastChild ]; |
| 8049 | |
| 8050 | // non-xml :nth-child(...) stores cache data on `parent` |
| 8051 | if ( forward && useCache ) { |
| 8052 | // Seek `elem` from a previously-cached index |
| 8053 | outerCache = parent[ expando ] || (parent[ expando ] = {}); |
| 8054 | cache = outerCache[ type ] || []; |
| 8055 | nodeIndex = cache[0] === dirruns && cache[1]; |
| 8056 | diff = cache[0] === dirruns && cache[2]; |
| 8057 | node = nodeIndex && parent.childNodes[ nodeIndex ]; |
| 8058 | |
| 8059 | while ( (node = ++nodeIndex && node && node[ dir ] || |
| 8060 | |
| 8061 | // Fallback to seeking `elem` from the start |
| 8062 | (diff = nodeIndex = 0) || start.pop()) ) { |
| 8063 | |
| 8064 | // When found, cache indexes on `parent` and break |
| 8065 | if ( node.nodeType === 1 && ++diff && node === elem ) { |
| 8066 | outerCache[ type ] = [ dirruns, nodeIndex, diff ]; |
| 8067 | break; |
| 8068 | } |
| 8069 | } |
| 8070 | |
| 8071 | // Use previously-cached element index if available |
| 8072 | } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { |
| 8073 | diff = cache[1]; |
| 8074 | |
| 8075 | // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) |
| 8076 | } else { |
| 8077 | // Use the same loop as above to seek `elem` from the start |
| 8078 | while ( (node = ++nodeIndex && node && node[ dir ] || |
| 8079 | (diff = nodeIndex = 0) || start.pop()) ) { |
| 8080 | |
| 8081 | if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { |
| 8082 | // Cache the index of each encountered element |
| 8083 | if ( useCache ) { |
| 8084 | (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; |
| 8085 | } |
| 8086 | |
| 8087 | if ( node === elem ) { |
| 8088 | break; |
| 8089 | } |
| 8090 | } |
| 8091 | } |
| 8092 | } |
| 8093 | |
| 8094 | // Incorporate the offset, then check against cycle size |
| 8095 | diff -= last; |
| 8096 | return diff === first || ( diff % first === 0 && diff / first >= 0 ); |
| 8097 | } |
| 8098 | }; |
| 8099 | }, |
| 8100 | |
| 8101 | "PSEUDO": function( pseudo, argument ) { |
| 8102 | // pseudo-class names are case-insensitive |
| 8103 | // http://www.w3.org/TR/selectors/#pseudo-classes |
| 8104 | // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters |
| 8105 | // Remember that setFilters inherits from pseudos |
| 8106 | var args, |
| 8107 | fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || |
| 8108 | Sizzle.error( "unsupported pseudo: " + pseudo ); |
| 8109 | |
| 8110 | // The user may use createPseudo to indicate that |
| 8111 | // arguments are needed to create the filter function |
| 8112 | // just as Sizzle does |
| 8113 | if ( fn[ expando ] ) { |
| 8114 | return fn( argument ); |
| 8115 | } |
| 8116 | |
| 8117 | // But maintain support for old signatures |
| 8118 | if ( fn.length > 1 ) { |
| 8119 | args = [ pseudo, pseudo, "", argument ]; |
| 8120 | return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? |
| 8121 | markFunction(function( seed, matches ) { |
| 8122 | var idx, |
| 8123 | matched = fn( seed, argument ), |
| 8124 | i = matched.length; |
| 8125 | while ( i-- ) { |
| 8126 | idx = indexOf( seed, matched[i] ); |
| 8127 | seed[ idx ] = !( matches[ idx ] = matched[i] ); |
| 8128 | } |
| 8129 | }) : |
| 8130 | function( elem ) { |
| 8131 | return fn( elem, 0, args ); |
| 8132 | }; |
| 8133 | } |
| 8134 | |
| 8135 | return fn; |
| 8136 | } |
| 8137 | }, |
| 8138 | |
| 8139 | pseudos: { |
| 8140 | // Potentially complex pseudos |
| 8141 | "not": markFunction(function( selector ) { |
| 8142 | // Trim the selector passed to compile |
| 8143 | // to avoid treating leading and trailing |
| 8144 | // spaces as combinators |
| 8145 | var input = [], |
| 8146 | results = [], |
| 8147 | matcher = compile( selector.replace( rtrim, "$1" ) ); |
| 8148 | |
| 8149 | return matcher[ expando ] ? |
| 8150 | markFunction(function( seed, matches, context, xml ) { |
| 8151 | var elem, |
| 8152 | unmatched = matcher( seed, null, xml, [] ), |
| 8153 | i = seed.length; |
| 8154 | |
| 8155 | // Match elements unmatched by `matcher` |
| 8156 | while ( i-- ) { |
| 8157 | if ( (elem = unmatched[i]) ) { |
| 8158 | seed[i] = !(matches[i] = elem); |
| 8159 | } |
| 8160 | } |
| 8161 | }) : |
| 8162 | function( elem, context, xml ) { |
| 8163 | input[0] = elem; |
| 8164 | matcher( input, null, xml, results ); |
| 8165 | // Don't keep the element (issue #299) |
| 8166 | input[0] = null; |
| 8167 | return !results.pop(); |
| 8168 | }; |
| 8169 | }), |
| 8170 | |
| 8171 | "has": markFunction(function( selector ) { |
| 8172 | return function( elem ) { |
| 8173 | return Sizzle( selector, elem ).length > 0; |
| 8174 | }; |
| 8175 | }), |
| 8176 | |
| 8177 | "contains": markFunction(function( text ) { |
| 8178 | text = text.replace( runescape, funescape ); |
| 8179 | return function( elem ) { |
| 8180 | return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; |
| 8181 | }; |
| 8182 | }), |
| 8183 | |
| 8184 | // "Whether an element is represented by a :lang() selector |
| 8185 | // is based solely on the element's language value |
| 8186 | // being equal to the identifier C, |
| 8187 | // or beginning with the identifier C immediately followed by "-". |
| 8188 | // The matching of C against the element's language value is performed case-insensitively. |
| 8189 | // The identifier C does not have to be a valid language name." |
| 8190 | // http://www.w3.org/TR/selectors/#lang-pseudo |
| 8191 | "lang": markFunction( function( lang ) { |
| 8192 | // lang value must be a valid identifier |
| 8193 | if ( !ridentifier.test(lang || "") ) { |
| 8194 | Sizzle.error( "unsupported lang: " + lang ); |
| 8195 | } |
| 8196 | lang = lang.replace( runescape, funescape ).toLowerCase(); |
| 8197 | return function( elem ) { |
| 8198 | var elemLang; |
| 8199 | do { |
| 8200 | if ( (elemLang = documentIsHTML ? |
| 8201 | elem.lang : |
| 8202 | elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { |
| 8203 | |
| 8204 | elemLang = elemLang.toLowerCase(); |
| 8205 | return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; |
| 8206 | } |
| 8207 | } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); |
| 8208 | return false; |
| 8209 | }; |
| 8210 | }), |
| 8211 | |
| 8212 | // Miscellaneous |
| 8213 | "target": function( elem ) { |
| 8214 | var hash = window.location && window.location.hash; |
| 8215 | return hash && hash.slice( 1 ) === elem.id; |
| 8216 | }, |
| 8217 | |
| 8218 | "root": function( elem ) { |
| 8219 | return elem === docElem; |
| 8220 | }, |
| 8221 | |
| 8222 | "focus": function( elem ) { |
| 8223 | return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); |
| 8224 | }, |
| 8225 | |
| 8226 | // Boolean properties |
| 8227 | "enabled": function( elem ) { |
| 8228 | return elem.disabled === false; |
| 8229 | }, |
| 8230 | |
| 8231 | "disabled": function( elem ) { |
| 8232 | return elem.disabled === true; |
| 8233 | }, |
| 8234 | |
| 8235 | "checked": function( elem ) { |
| 8236 | // In CSS3, :checked should return both checked and selected elements |
| 8237 | // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked |
| 8238 | var nodeName = elem.nodeName.toLowerCase(); |
| 8239 | return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); |
| 8240 | }, |
| 8241 | |
| 8242 | "selected": function( elem ) { |
| 8243 | // Accessing this property makes selected-by-default |
| 8244 | // options in Safari work properly |
| 8245 | if ( elem.parentNode ) { |
| 8246 | elem.parentNode.selectedIndex; |
| 8247 | } |
| 8248 | |
| 8249 | return elem.selected === true; |
| 8250 | }, |
| 8251 | |
| 8252 | // Contents |
| 8253 | "empty": function( elem ) { |
| 8254 | // http://www.w3.org/TR/selectors/#empty-pseudo |
| 8255 | // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), |
| 8256 | // but not by others (comment: 8; processing instruction: 7; etc.) |
| 8257 | // nodeType < 6 works because attributes (2) do not appear as children |
| 8258 | for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { |
| 8259 | if ( elem.nodeType < 6 ) { |
| 8260 | return false; |
| 8261 | } |
| 8262 | } |
| 8263 | return true; |
| 8264 | }, |
| 8265 | |
| 8266 | "parent": function( elem ) { |
| 8267 | return !Expr.pseudos["empty"]( elem ); |
| 8268 | }, |
| 8269 | |
| 8270 | // Element/input types |
| 8271 | "header": function( elem ) { |
| 8272 | return rheader.test( elem.nodeName ); |
| 8273 | }, |
| 8274 | |
| 8275 | "input": function( elem ) { |
| 8276 | return rinputs.test( elem.nodeName ); |
| 8277 | }, |
| 8278 | |
| 8279 | "button": function( elem ) { |
| 8280 | var name = elem.nodeName.toLowerCase(); |
| 8281 | return name === "input" && elem.type === "button" || name === "button"; |
| 8282 | }, |
| 8283 | |
| 8284 | "text": function( elem ) { |
| 8285 | var attr; |
| 8286 | return elem.nodeName.toLowerCase() === "input" && |
| 8287 | elem.type === "text" && |
| 8288 | |
| 8289 | // Support: IE<8 |
| 8290 | // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" |
| 8291 | ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); |
| 8292 | }, |
| 8293 | |
| 8294 | // Position-in-collection |
| 8295 | "first": createPositionalPseudo(function() { |
| 8296 | return [ 0 ]; |
| 8297 | }), |
| 8298 | |
| 8299 | "last": createPositionalPseudo(function( matchIndexes, length ) { |
| 8300 | return [ length - 1 ]; |
| 8301 | }), |
| 8302 | |
| 8303 | "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { |
| 8304 | return [ argument < 0 ? argument + length : argument ]; |
| 8305 | }), |
| 8306 | |
| 8307 | "even": createPositionalPseudo(function( matchIndexes, length ) { |
| 8308 | var i = 0; |
| 8309 | for ( ; i < length; i += 2 ) { |
| 8310 | matchIndexes.push( i ); |
| 8311 | } |
| 8312 | return matchIndexes; |
| 8313 | }), |
| 8314 | |
| 8315 | "odd": createPositionalPseudo(function( matchIndexes, length ) { |
| 8316 | var i = 1; |
| 8317 | for ( ; i < length; i += 2 ) { |
| 8318 | matchIndexes.push( i ); |
| 8319 | } |
| 8320 | return matchIndexes; |
| 8321 | }), |
| 8322 | |
| 8323 | "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { |
| 8324 | var i = argument < 0 ? argument + length : argument; |
| 8325 | for ( ; --i >= 0; ) { |
| 8326 | matchIndexes.push( i ); |
| 8327 | } |
| 8328 | return matchIndexes; |
| 8329 | }), |
| 8330 | |
| 8331 | "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { |
| 8332 | var i = argument < 0 ? argument + length : argument; |
| 8333 | for ( ; ++i < length; ) { |
| 8334 | matchIndexes.push( i ); |
| 8335 | } |
| 8336 | return matchIndexes; |
| 8337 | }) |
| 8338 | } |
| 8339 | }; |
| 8340 | |
| 8341 | Expr.pseudos["nth"] = Expr.pseudos["eq"]; |
| 8342 | |
| 8343 | // Add button/input type pseudos |
| 8344 | for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { |
| 8345 | Expr.pseudos[ i ] = createInputPseudo( i ); |
| 8346 | } |
| 8347 | for ( i in { submit: true, reset: true } ) { |
| 8348 | Expr.pseudos[ i ] = createButtonPseudo( i ); |
| 8349 | } |
| 8350 | |
| 8351 | // Easy API for creating new setFilters |
| 8352 | function setFilters() {} |
| 8353 | setFilters.prototype = Expr.filters = Expr.pseudos; |
| 8354 | Expr.setFilters = new setFilters(); |
| 8355 | |
| 8356 | tokenize = Sizzle.tokenize = function( selector, parseOnly ) { |
| 8357 | var matched, match, tokens, type, |
| 8358 | soFar, groups, preFilters, |
| 8359 | cached = tokenCache[ selector + " " ]; |
| 8360 | |
| 8361 | if ( cached ) { |
| 8362 | return parseOnly ? 0 : cached.slice( 0 ); |
| 8363 | } |
| 8364 | |
| 8365 | soFar = selector; |
| 8366 | groups = []; |
| 8367 | preFilters = Expr.preFilter; |
| 8368 | |
| 8369 | while ( soFar ) { |
| 8370 | |
| 8371 | // Comma and first run |
| 8372 | if ( !matched || (match = rcomma.exec( soFar )) ) { |
| 8373 | if ( match ) { |
| 8374 | // Don't consume trailing commas as valid |
| 8375 | soFar = soFar.slice( match[0].length ) || soFar; |
| 8376 | } |
| 8377 | groups.push( (tokens = []) ); |
| 8378 | } |
| 8379 | |
| 8380 | matched = false; |
| 8381 | |
| 8382 | // Combinators |
| 8383 | if ( (match = rcombinators.exec( soFar )) ) { |
| 8384 | matched = match.shift(); |
| 8385 | tokens.push({ |
| 8386 | value: matched, |
| 8387 | // Cast descendant combinators to space |
| 8388 | type: match[0].replace( rtrim, " " ) |
| 8389 | }); |
| 8390 | soFar = soFar.slice( matched.length ); |
| 8391 | } |
| 8392 | |
| 8393 | // Filters |
| 8394 | for ( type in Expr.filter ) { |
| 8395 | if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || |
| 8396 | (match = preFilters[ type ]( match ))) ) { |
| 8397 | matched = match.shift(); |
| 8398 | tokens.push({ |
| 8399 | value: matched, |
| 8400 | type: type, |
| 8401 | matches: match |
| 8402 | }); |
| 8403 | soFar = soFar.slice( matched.length ); |
| 8404 | } |
| 8405 | } |
| 8406 | |
| 8407 | if ( !matched ) { |
| 8408 | break; |
| 8409 | } |
| 8410 | } |
| 8411 | |
| 8412 | // Return the length of the invalid excess |
| 8413 | // if we're just parsing |
| 8414 | // Otherwise, throw an error or return tokens |
| 8415 | return parseOnly ? |
| 8416 | soFar.length : |
| 8417 | soFar ? |
| 8418 | Sizzle.error( selector ) : |
| 8419 | // Cache the tokens |
| 8420 | tokenCache( selector, groups ).slice( 0 ); |
| 8421 | }; |
| 8422 | |
| 8423 | function toSelector( tokens ) { |
| 8424 | var i = 0, |
| 8425 | len = tokens.length, |
| 8426 | selector = ""; |
| 8427 | for ( ; i < len; i++ ) { |
| 8428 | selector += tokens[i].value; |
| 8429 | } |
| 8430 | return selector; |
| 8431 | } |
| 8432 | |
| 8433 | function addCombinator( matcher, combinator, base ) { |
| 8434 | var dir = combinator.dir, |
| 8435 | checkNonElements = base && dir === "parentNode", |
| 8436 | doneName = done++; |
| 8437 | |
| 8438 | return combinator.first ? |
| 8439 | // Check against closest ancestor/preceding element |
| 8440 | function( elem, context, xml ) { |
| 8441 | while ( (elem = elem[ dir ]) ) { |
| 8442 | if ( elem.nodeType === 1 || checkNonElements ) { |
| 8443 | return matcher( elem, context, xml ); |
| 8444 | } |
| 8445 | } |
| 8446 | } : |
| 8447 | |
| 8448 | // Check against all ancestor/preceding elements |
| 8449 | function( elem, context, xml ) { |
| 8450 | var oldCache, outerCache, |
| 8451 | newCache = [ dirruns, doneName ]; |
| 8452 | |
| 8453 | // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching |
| 8454 | if ( xml ) { |
| 8455 | while ( (elem = elem[ dir ]) ) { |
| 8456 | if ( elem.nodeType === 1 || checkNonElements ) { |
| 8457 | if ( matcher( elem, context, xml ) ) { |
| 8458 | return true; |
| 8459 | } |
| 8460 | } |
| 8461 | } |
| 8462 | } else { |
| 8463 | while ( (elem = elem[ dir ]) ) { |
| 8464 | if ( elem.nodeType === 1 || checkNonElements ) { |
| 8465 | outerCache = elem[ expando ] || (elem[ expando ] = {}); |
| 8466 | if ( (oldCache = outerCache[ dir ]) && |
| 8467 | oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { |
| 8468 | |
| 8469 | // Assign to newCache so results back-propagate to previous elements |
| 8470 | return (newCache[ 2 ] = oldCache[ 2 ]); |
| 8471 | } else { |
| 8472 | // Reuse newcache so results back-propagate to previous elements |
| 8473 | outerCache[ dir ] = newCache; |
| 8474 | |
| 8475 | // A match means we're done; a fail means we have to keep checking |
| 8476 | if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { |
| 8477 | return true; |
| 8478 | } |
| 8479 | } |
| 8480 | } |
| 8481 | } |
| 8482 | } |
| 8483 | }; |
| 8484 | } |
| 8485 | |
| 8486 | function elementMatcher( matchers ) { |
| 8487 | return matchers.length > 1 ? |
| 8488 | function( elem, context, xml ) { |
| 8489 | var i = matchers.length; |
| 8490 | while ( i-- ) { |
| 8491 | if ( !matchers[i]( elem, context, xml ) ) { |
| 8492 | return false; |
| 8493 | } |
| 8494 | } |
| 8495 | return true; |
| 8496 | } : |
| 8497 | matchers[0]; |
| 8498 | } |
| 8499 | |
| 8500 | function multipleContexts( selector, contexts, results ) { |
| 8501 | var i = 0, |
| 8502 | len = contexts.length; |
| 8503 | for ( ; i < len; i++ ) { |
| 8504 | Sizzle( selector, contexts[i], results ); |
| 8505 | } |
| 8506 | return results; |
| 8507 | } |
| 8508 | |
| 8509 | function condense( unmatched, map, filter, context, xml ) { |
| 8510 | var elem, |
| 8511 | newUnmatched = [], |
| 8512 | i = 0, |
| 8513 | len = unmatched.length, |
| 8514 | mapped = map != null; |
| 8515 | |
| 8516 | for ( ; i < len; i++ ) { |
| 8517 | if ( (elem = unmatched[i]) ) { |
| 8518 | if ( !filter || filter( elem, context, xml ) ) { |
| 8519 | newUnmatched.push( elem ); |
| 8520 | if ( mapped ) { |
| 8521 | map.push( i ); |
| 8522 | } |
| 8523 | } |
| 8524 | } |
| 8525 | } |
| 8526 | |
| 8527 | return newUnmatched; |
| 8528 | } |
| 8529 | |
| 8530 | function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { |
| 8531 | if ( postFilter && !postFilter[ expando ] ) { |
| 8532 | postFilter = setMatcher( postFilter ); |
| 8533 | } |
| 8534 | if ( postFinder && !postFinder[ expando ] ) { |
| 8535 | postFinder = setMatcher( postFinder, postSelector ); |
| 8536 | } |
| 8537 | return markFunction(function( seed, results, context, xml ) { |
| 8538 | var temp, i, elem, |
| 8539 | preMap = [], |
| 8540 | postMap = [], |
| 8541 | preexisting = results.length, |
| 8542 | |
| 8543 | // Get initial elements from seed or context |
| 8544 | elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), |
| 8545 | |
| 8546 | // Prefilter to get matcher input, preserving a map for seed-results synchronization |
| 8547 | matcherIn = preFilter && ( seed || !selector ) ? |
| 8548 | condense( elems, preMap, preFilter, context, xml ) : |
| 8549 | elems, |
| 8550 | |
| 8551 | matcherOut = matcher ? |
| 8552 | // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, |
| 8553 | postFinder || ( seed ? preFilter : preexisting || postFilter ) ? |
| 8554 | |
| 8555 | // ...intermediate processing is necessary |
| 8556 | [] : |
| 8557 | |
| 8558 | // ...otherwise use results directly |
| 8559 | results : |
| 8560 | matcherIn; |
| 8561 | |
| 8562 | // Find primary matches |
| 8563 | if ( matcher ) { |
| 8564 | matcher( matcherIn, matcherOut, context, xml ); |
| 8565 | } |
| 8566 | |
| 8567 | // Apply postFilter |
| 8568 | if ( postFilter ) { |
| 8569 | temp = condense( matcherOut, postMap ); |
| 8570 | postFilter( temp, [], context, xml ); |
| 8571 | |
| 8572 | // Un-match failing elements by moving them back to matcherIn |
| 8573 | i = temp.length; |
| 8574 | while ( i-- ) { |
| 8575 | if ( (elem = temp[i]) ) { |
| 8576 | matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); |
| 8577 | } |
| 8578 | } |
| 8579 | } |
| 8580 | |
| 8581 | if ( seed ) { |
| 8582 | if ( postFinder || preFilter ) { |
| 8583 | if ( postFinder ) { |
| 8584 | // Get the final matcherOut by condensing this intermediate into postFinder contexts |
| 8585 | temp = []; |
| 8586 | i = matcherOut.length; |
| 8587 | while ( i-- ) { |
| 8588 | if ( (elem = matcherOut[i]) ) { |
| 8589 | // Restore matcherIn since elem is not yet a final match |
| 8590 | temp.push( (matcherIn[i] = elem) ); |
| 8591 | } |
| 8592 | } |
| 8593 | postFinder( null, (matcherOut = []), temp, xml ); |
| 8594 | } |
| 8595 | |
| 8596 | // Move matched elements from seed to results to keep them synchronized |
| 8597 | i = matcherOut.length; |
| 8598 | while ( i-- ) { |
| 8599 | if ( (elem = matcherOut[i]) && |
| 8600 | (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { |
| 8601 | |
| 8602 | seed[temp] = !(results[temp] = elem); |
| 8603 | } |
| 8604 | } |
| 8605 | } |
| 8606 | |
| 8607 | // Add elements to results, through postFinder if defined |
| 8608 | } else { |
| 8609 | matcherOut = condense( |
| 8610 | matcherOut === results ? |
| 8611 | matcherOut.splice( preexisting, matcherOut.length ) : |
| 8612 | matcherOut |
| 8613 | ); |
| 8614 | if ( postFinder ) { |
| 8615 | postFinder( null, results, matcherOut, xml ); |
| 8616 | } else { |
| 8617 | push.apply( results, matcherOut ); |
| 8618 | } |
| 8619 | } |
| 8620 | }); |
| 8621 | } |
| 8622 | |
| 8623 | function matcherFromTokens( tokens ) { |
| 8624 | var checkContext, matcher, j, |
| 8625 | len = tokens.length, |
| 8626 | leadingRelative = Expr.relative[ tokens[0].type ], |
| 8627 | implicitRelative = leadingRelative || Expr.relative[" "], |
| 8628 | i = leadingRelative ? 1 : 0, |
| 8629 | |
| 8630 | // The foundational matcher ensures that elements are reachable from top-level context(s) |
| 8631 | matchContext = addCombinator( function( elem ) { |
| 8632 | return elem === checkContext; |
| 8633 | }, implicitRelative, true ), |
| 8634 | matchAnyContext = addCombinator( function( elem ) { |
| 8635 | return indexOf( checkContext, elem ) > -1; |
| 8636 | }, implicitRelative, true ), |
| 8637 | matchers = [ function( elem, context, xml ) { |
| 8638 | var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( |
| 8639 | (checkContext = context).nodeType ? |
| 8640 | matchContext( elem, context, xml ) : |
| 8641 | matchAnyContext( elem, context, xml ) ); |
| 8642 | // Avoid hanging onto element (issue #299) |
| 8643 | checkContext = null; |
| 8644 | return ret; |
| 8645 | } ]; |
| 8646 | |
| 8647 | for ( ; i < len; i++ ) { |
| 8648 | if ( (matcher = Expr.relative[ tokens[i].type ]) ) { |
| 8649 | matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; |
| 8650 | } else { |
| 8651 | matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); |
| 8652 | |
| 8653 | // Return special upon seeing a positional matcher |
| 8654 | if ( matcher[ expando ] ) { |
| 8655 | // Find the next relative operator (if any) for proper handling |
| 8656 | j = ++i; |
| 8657 | for ( ; j < len; j++ ) { |
| 8658 | if ( Expr.relative[ tokens[j].type ] ) { |
| 8659 | break; |
| 8660 | } |
| 8661 | } |
| 8662 | return setMatcher( |
| 8663 | i > 1 && elementMatcher( matchers ), |
| 8664 | i > 1 && toSelector( |
| 8665 | // If the preceding token was a descendant combinator, insert an implicit any-element `*` |
| 8666 | tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) |
| 8667 | ).replace( rtrim, "$1" ), |
| 8668 | matcher, |
| 8669 | i < j && matcherFromTokens( tokens.slice( i, j ) ), |
| 8670 | j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), |
| 8671 | j < len && toSelector( tokens ) |
| 8672 | ); |
| 8673 | } |
| 8674 | matchers.push( matcher ); |
| 8675 | } |
| 8676 | } |
| 8677 | |
| 8678 | return elementMatcher( matchers ); |
| 8679 | } |
| 8680 | |
| 8681 | function matcherFromGroupMatchers( elementMatchers, setMatchers ) { |
| 8682 | var bySet = setMatchers.length > 0, |
| 8683 | byElement = elementMatchers.length > 0, |
| 8684 | superMatcher = function( seed, context, xml, results, outermost ) { |
| 8685 | var elem, j, matcher, |
| 8686 | matchedCount = 0, |
| 8687 | i = "0", |
| 8688 | unmatched = seed && [], |
| 8689 | setMatched = [], |
| 8690 | contextBackup = outermostContext, |
| 8691 | // We must always have either seed elements or outermost context |
| 8692 | elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), |
| 8693 | // Use integer dirruns iff this is the outermost matcher |
| 8694 | dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), |
| 8695 | len = elems.length; |
| 8696 | |
| 8697 | if ( outermost ) { |
| 8698 | outermostContext = context !== document && context; |
| 8699 | } |
| 8700 | |
| 8701 | // Add elements passing elementMatchers directly to results |
| 8702 | // Keep `i` a string if there are no elements so `matchedCount` will be "00" below |
| 8703 | // Support: IE<9, Safari |
| 8704 | // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id |
| 8705 | for ( ; i !== len && (elem = elems[i]) != null; i++ ) { |
| 8706 | if ( byElement && elem ) { |
| 8707 | j = 0; |
| 8708 | while ( (matcher = elementMatchers[j++]) ) { |
| 8709 | if ( matcher( elem, context, xml ) ) { |
| 8710 | results.push( elem ); |
| 8711 | break; |
| 8712 | } |
| 8713 | } |
| 8714 | if ( outermost ) { |
| 8715 | dirruns = dirrunsUnique; |
| 8716 | } |
| 8717 | } |
| 8718 | |
| 8719 | // Track unmatched elements for set filters |
| 8720 | if ( bySet ) { |
| 8721 | // They will have gone through all possible matchers |
| 8722 | if ( (elem = !matcher && elem) ) { |
| 8723 | matchedCount--; |
| 8724 | } |
| 8725 | |
| 8726 | // Lengthen the array for every element, matched or not |
| 8727 | if ( seed ) { |
| 8728 | unmatched.push( elem ); |
| 8729 | } |
| 8730 | } |
| 8731 | } |
| 8732 | |
| 8733 | // Apply set filters to unmatched elements |
| 8734 | matchedCount += i; |
| 8735 | if ( bySet && i !== matchedCount ) { |
| 8736 | j = 0; |
| 8737 | while ( (matcher = setMatchers[j++]) ) { |
| 8738 | matcher( unmatched, setMatched, context, xml ); |
| 8739 | } |
| 8740 | |
| 8741 | if ( seed ) { |
| 8742 | // Reintegrate element matches to eliminate the need for sorting |
| 8743 | if ( matchedCount > 0 ) { |
| 8744 | while ( i-- ) { |
| 8745 | if ( !(unmatched[i] || setMatched[i]) ) { |
| 8746 | setMatched[i] = pop.call( results ); |
| 8747 | } |
| 8748 | } |
| 8749 | } |
| 8750 | |
| 8751 | // Discard index placeholder values to get only actual matches |
| 8752 | setMatched = condense( setMatched ); |
| 8753 | } |
| 8754 | |
| 8755 | // Add matches to results |
| 8756 | push.apply( results, setMatched ); |
| 8757 | |
| 8758 | // Seedless set matches succeeding multiple successful matchers stipulate sorting |
| 8759 | if ( outermost && !seed && setMatched.length > 0 && |
| 8760 | ( matchedCount + setMatchers.length ) > 1 ) { |
| 8761 | |
| 8762 | Sizzle.uniqueSort( results ); |
| 8763 | } |
| 8764 | } |
| 8765 | |
| 8766 | // Override manipulation of globals by nested matchers |
| 8767 | if ( outermost ) { |
| 8768 | dirruns = dirrunsUnique; |
| 8769 | outermostContext = contextBackup; |
| 8770 | } |
| 8771 | |
| 8772 | return unmatched; |
| 8773 | }; |
| 8774 | |
| 8775 | return bySet ? |
| 8776 | markFunction( superMatcher ) : |
| 8777 | superMatcher; |
| 8778 | } |
| 8779 | |
| 8780 | compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { |
| 8781 | var i, |
| 8782 | setMatchers = [], |
| 8783 | elementMatchers = [], |
| 8784 | cached = compilerCache[ selector + " " ]; |
| 8785 | |
| 8786 | if ( !cached ) { |
| 8787 | // Generate a function of recursive functions that can be used to check each element |
| 8788 | if ( !match ) { |
| 8789 | match = tokenize( selector ); |
| 8790 | } |
| 8791 | i = match.length; |
| 8792 | while ( i-- ) { |
| 8793 | cached = matcherFromTokens( match[i] ); |
| 8794 | if ( cached[ expando ] ) { |
| 8795 | setMatchers.push( cached ); |
| 8796 | } else { |
| 8797 | elementMatchers.push( cached ); |
| 8798 | } |
| 8799 | } |
| 8800 | |
| 8801 | // Cache the compiled function |
| 8802 | cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); |
| 8803 | |
| 8804 | // Save selector and tokenization |
| 8805 | cached.selector = selector; |
| 8806 | } |
| 8807 | return cached; |
| 8808 | }; |
| 8809 | |
| 8810 | /** |
| 8811 | * A low-level selection function that works with Sizzle's compiled |
| 8812 | * selector functions |
| 8813 | * @param {String|Function} selector A selector or a pre-compiled |
| 8814 | * selector function built with Sizzle.compile |
| 8815 | * @param {Element} context |
| 8816 | * @param {Array} [results] |
| 8817 | * @param {Array} [seed] A set of elements to match against |
| 8818 | */ |
| 8819 | select = Sizzle.select = function( selector, context, results, seed ) { |
| 8820 | var i, tokens, token, type, find, |
| 8821 | compiled = typeof selector === "function" && selector, |
| 8822 | match = !seed && tokenize( (selector = compiled.selector || selector) ); |
| 8823 | |
| 8824 | results = results || []; |
| 8825 | |
| 8826 | // Try to minimize operations if there is no seed and only one group |
| 8827 | if ( match.length === 1 ) { |
| 8828 | |
| 8829 | // Take a shortcut and set the context if the root selector is an ID |
| 8830 | tokens = match[0] = match[0].slice( 0 ); |
| 8831 | if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && |
| 8832 | support.getById && context.nodeType === 9 && documentIsHTML && |
| 8833 | Expr.relative[ tokens[1].type ] ) { |
| 8834 | |
| 8835 | context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; |
| 8836 | if ( !context ) { |
| 8837 | return results; |
| 8838 | |
| 8839 | // Precompiled matchers will still verify ancestry, so step up a level |
| 8840 | } else if ( compiled ) { |
| 8841 | context = context.parentNode; |
| 8842 | } |
| 8843 | |
| 8844 | selector = selector.slice( tokens.shift().value.length ); |
| 8845 | } |
| 8846 | |
| 8847 | // Fetch a seed set for right-to-left matching |
| 8848 | i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; |
| 8849 | while ( i-- ) { |
| 8850 | token = tokens[i]; |
| 8851 | |
| 8852 | // Abort if we hit a combinator |
| 8853 | if ( Expr.relative[ (type = token.type) ] ) { |
| 8854 | break; |
| 8855 | } |
| 8856 | if ( (find = Expr.find[ type ]) ) { |
| 8857 | // Search, expanding context for leading sibling combinators |
| 8858 | if ( (seed = find( |
| 8859 | token.matches[0].replace( runescape, funescape ), |
| 8860 | rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context |
| 8861 | )) ) { |
| 8862 | |
| 8863 | // If seed is empty or no tokens remain, we can return early |
| 8864 | tokens.splice( i, 1 ); |
| 8865 | selector = seed.length && toSelector( tokens ); |
| 8866 | if ( !selector ) { |
| 8867 | push.apply( results, seed ); |
| 8868 | return results; |
| 8869 | } |
| 8870 | |
| 8871 | break; |
| 8872 | } |
| 8873 | } |
| 8874 | } |
| 8875 | } |
| 8876 | |
| 8877 | // Compile and execute a filtering function if one is not provided |
| 8878 | // Provide `match` to avoid retokenization if we modified the selector above |
| 8879 | ( compiled || compile( selector, match ) )( |
| 8880 | seed, |
| 8881 | context, |
| 8882 | !documentIsHTML, |
| 8883 | results, |
| 8884 | rsibling.test( selector ) && testContext( context.parentNode ) || context |
| 8885 | ); |
| 8886 | return results; |
| 8887 | }; |
| 8888 | |
| 8889 | // One-time assignments |
| 8890 | |
| 8891 | // Sort stability |
| 8892 | support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; |
| 8893 | |
| 8894 | // Support: Chrome 14-35+ |
| 8895 | // Always assume duplicates if they aren't passed to the comparison function |
| 8896 | support.detectDuplicates = !!hasDuplicate; |
| 8897 | |
| 8898 | // Initialize against the default document |
| 8899 | setDocument(); |
| 8900 | |
| 8901 | // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) |
| 8902 | // Detached nodes confoundingly follow *each other* |
| 8903 | support.sortDetached = assert(function( div1 ) { |
| 8904 | // Should return 1, but returns 4 (following) |
| 8905 | return div1.compareDocumentPosition( document.createElement("div") ) & 1; |
| 8906 | }); |
| 8907 | |
| 8908 | // Support: IE<8 |
| 8909 | // Prevent attribute/property "interpolation" |
| 8910 | // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx |
| 8911 | if ( !assert(function( div ) { |
| 8912 | div.innerHTML = "<a href='#'></a>"; |
| 8913 | return div.firstChild.getAttribute("href") === "#" ; |
| 8914 | }) ) { |
| 8915 | addHandle( "type|href|height|width", function( elem, name, isXML ) { |
| 8916 | if ( !isXML ) { |
| 8917 | return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); |
| 8918 | } |
| 8919 | }); |
| 8920 | } |
| 8921 | |
| 8922 | // Support: IE<9 |
| 8923 | // Use defaultValue in place of getAttribute("value") |
| 8924 | if ( !support.attributes || !assert(function( div ) { |
| 8925 | div.innerHTML = "<input/>"; |
| 8926 | div.firstChild.setAttribute( "value", "" ); |
| 8927 | return div.firstChild.getAttribute( "value" ) === ""; |
| 8928 | }) ) { |
| 8929 | addHandle( "value", function( elem, name, isXML ) { |
| 8930 | if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { |
| 8931 | return elem.defaultValue; |
| 8932 | } |
| 8933 | }); |
| 8934 | } |
| 8935 | |
| 8936 | // Support: IE<9 |
| 8937 | // Use getAttributeNode to fetch booleans when getAttribute lies |
| 8938 | if ( !assert(function( div ) { |
| 8939 | return div.getAttribute("disabled") == null; |
| 8940 | }) ) { |
| 8941 | addHandle( booleans, function( elem, name, isXML ) { |
| 8942 | var val; |
| 8943 | if ( !isXML ) { |
| 8944 | return elem[ name ] === true ? name.toLowerCase() : |
| 8945 | (val = elem.getAttributeNode( name )) && val.specified ? |
| 8946 | val.value : |
| 8947 | null; |
| 8948 | } |
| 8949 | }); |
| 8950 | } |
| 8951 | |
| 8952 | return Sizzle; |
| 8953 | |
| 8954 | })( window ); |
| 8955 | |
| 8956 | |
| 8957 | |
| 8958 | jQuery.find = Sizzle; |
| 8959 | jQuery.expr = Sizzle.selectors; |
| 8960 | jQuery.expr[":"] = jQuery.expr.pseudos; |
| 8961 | jQuery.unique = Sizzle.uniqueSort; |
| 8962 | jQuery.text = Sizzle.getText; |
| 8963 | jQuery.isXMLDoc = Sizzle.isXML; |
| 8964 | jQuery.contains = Sizzle.contains; |
| 8965 | |
| 8966 | |
| 8967 | |
| 8968 | var rneedsContext = jQuery.expr.match.needsContext; |
| 8969 | |
| 8970 | var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/); |
| 8971 | |
| 8972 | |
| 8973 | |
| 8974 | var risSimple = /^.[^:#\[\.,]*$/; |
| 8975 | |
| 8976 | // Implement the identical functionality for filter and not |
| 8977 | function winnow( elements, qualifier, not ) { |
| 8978 | if ( jQuery.isFunction( qualifier ) ) { |
| 8979 | return jQuery.grep( elements, function( elem, i ) { |
| 8980 | /* jshint -W018 */ |
| 8981 | return !!qualifier.call( elem, i, elem ) !== not; |
| 8982 | }); |
| 8983 | |
| 8984 | } |
| 8985 | |
| 8986 | if ( qualifier.nodeType ) { |
| 8987 | return jQuery.grep( elements, function( elem ) { |
| 8988 | return ( elem === qualifier ) !== not; |
| 8989 | }); |
| 8990 | |
| 8991 | } |
| 8992 | |
| 8993 | if ( typeof qualifier === "string" ) { |
| 8994 | if ( risSimple.test( qualifier ) ) { |
| 8995 | return jQuery.filter( qualifier, elements, not ); |
| 8996 | } |
| 8997 | |
| 8998 | qualifier = jQuery.filter( qualifier, elements ); |
| 8999 | } |
| 9000 | |
| 9001 | return jQuery.grep( elements, function( elem ) { |
| 9002 | return ( indexOf.call( qualifier, elem ) >= 0 ) !== not; |
| 9003 | }); |
| 9004 | } |
| 9005 | |
| 9006 | jQuery.filter = function( expr, elems, not ) { |
| 9007 | var elem = elems[ 0 ]; |
| 9008 | |
| 9009 | if ( not ) { |
| 9010 | expr = ":not(" + expr + ")"; |
| 9011 | } |
| 9012 | |
| 9013 | return elems.length === 1 && elem.nodeType === 1 ? |
| 9014 | jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : |
| 9015 | jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { |
| 9016 | return elem.nodeType === 1; |
| 9017 | })); |
| 9018 | }; |
| 9019 | |
| 9020 | jQuery.fn.extend({ |
| 9021 | find: function( selector ) { |
| 9022 | var i, |
| 9023 | len = this.length, |
| 9024 | ret = [], |
| 9025 | self = this; |
| 9026 | |
| 9027 | if ( typeof selector !== "string" ) { |
| 9028 | return this.pushStack( jQuery( selector ).filter(function() { |
| 9029 | for ( i = 0; i < len; i++ ) { |
| 9030 | if ( jQuery.contains( self[ i ], this ) ) { |
| 9031 | return true; |
| 9032 | } |
| 9033 | } |
| 9034 | }) ); |
| 9035 | } |
| 9036 | |
| 9037 | for ( i = 0; i < len; i++ ) { |
| 9038 | jQuery.find( selector, self[ i ], ret ); |
| 9039 | } |
| 9040 | |
| 9041 | // Needed because $( selector, context ) becomes $( context ).find( selector ) |
| 9042 | ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); |
| 9043 | ret.selector = this.selector ? this.selector + " " + selector : selector; |
| 9044 | return ret; |
| 9045 | }, |
| 9046 | filter: function( selector ) { |
| 9047 | return this.pushStack( winnow(this, selector || [], false) ); |
| 9048 | }, |
| 9049 | not: function( selector ) { |
| 9050 | return this.pushStack( winnow(this, selector || [], true) ); |
| 9051 | }, |
| 9052 | is: function( selector ) { |
| 9053 | return !!winnow( |
| 9054 | this, |
| 9055 | |
| 9056 | // If this is a positional/relative selector, check membership in the returned set |
| 9057 | // so $("p:first").is("p:last") won't return true for a doc with two "p". |
| 9058 | typeof selector === "string" && rneedsContext.test( selector ) ? |
| 9059 | jQuery( selector ) : |
| 9060 | selector || [], |
| 9061 | false |
| 9062 | ).length; |
| 9063 | } |
| 9064 | }); |
| 9065 | |
| 9066 | |
| 9067 | // Initialize a jQuery object |
| 9068 | |
| 9069 | |
| 9070 | // A central reference to the root jQuery(document) |
| 9071 | var rootjQuery, |
| 9072 | |
| 9073 | // A simple way to check for HTML strings |
| 9074 | // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) |
| 9075 | // Strict HTML recognition (#11290: must start with <) |
| 9076 | rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, |
| 9077 | |
| 9078 | init = jQuery.fn.init = function( selector, context ) { |
| 9079 | var match, elem; |
| 9080 | |
| 9081 | // HANDLE: $(""), $(null), $(undefined), $(false) |
| 9082 | if ( !selector ) { |
| 9083 | return this; |
| 9084 | } |
| 9085 | |
| 9086 | // Handle HTML strings |
| 9087 | if ( typeof selector === "string" ) { |
| 9088 | if ( selector[0] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) { |
| 9089 | // Assume that strings that start and end with <> are HTML and skip the regex check |
| 9090 | match = [ null, selector, null ]; |
| 9091 | |
| 9092 | } else { |
| 9093 | match = rquickExpr.exec( selector ); |
| 9094 | } |
| 9095 | |
| 9096 | // Match html or make sure no context is specified for #id |
| 9097 | if ( match && (match[1] || !context) ) { |
| 9098 | |
| 9099 | // HANDLE: $(html) -> $(array) |
| 9100 | if ( match[1] ) { |
| 9101 | context = context instanceof jQuery ? context[0] : context; |
| 9102 | |
| 9103 | // Option to run scripts is true for back-compat |
| 9104 | // Intentionally let the error be thrown if parseHTML is not present |
| 9105 | jQuery.merge( this, jQuery.parseHTML( |
| 9106 | match[1], |
| 9107 | context && context.nodeType ? context.ownerDocument || context : document, |
| 9108 | true |
| 9109 | ) ); |
| 9110 | |
| 9111 | // HANDLE: $(html, props) |
| 9112 | if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { |
| 9113 | for ( match in context ) { |
| 9114 | // Properties of context are called as methods if possible |
| 9115 | if ( jQuery.isFunction( this[ match ] ) ) { |
| 9116 | this[ match ]( context[ match ] ); |
| 9117 | |
| 9118 | // ...and otherwise set as attributes |
| 9119 | } else { |
| 9120 | this.attr( match, context[ match ] ); |
| 9121 | } |
| 9122 | } |
| 9123 | } |
| 9124 | |
| 9125 | return this; |
| 9126 | |
| 9127 | // HANDLE: $(#id) |
| 9128 | } else { |
| 9129 | elem = document.getElementById( match[2] ); |
| 9130 | |
| 9131 | // Support: Blackberry 4.6 |
| 9132 | // gEBID returns nodes no longer in the document (#6963) |
| 9133 | if ( elem && elem.parentNode ) { |
| 9134 | // Inject the element directly into the jQuery object |
| 9135 | this.length = 1; |
| 9136 | this[0] = elem; |
| 9137 | } |
| 9138 | |
| 9139 | this.context = document; |
| 9140 | this.selector = selector; |
| 9141 | return this; |
| 9142 | } |
| 9143 | |
| 9144 | // HANDLE: $(expr, $(...)) |
| 9145 | } else if ( !context || context.jquery ) { |
| 9146 | return ( context || rootjQuery ).find( selector ); |
| 9147 | |
| 9148 | // HANDLE: $(expr, context) |
| 9149 | // (which is just equivalent to: $(context).find(expr) |
| 9150 | } else { |
| 9151 | return this.constructor( context ).find( selector ); |
| 9152 | } |
| 9153 | |
| 9154 | // HANDLE: $(DOMElement) |
| 9155 | } else if ( selector.nodeType ) { |
| 9156 | this.context = this[0] = selector; |
| 9157 | this.length = 1; |
| 9158 | return this; |
| 9159 | |
| 9160 | // HANDLE: $(function) |
| 9161 | // Shortcut for document ready |
| 9162 | } else if ( jQuery.isFunction( selector ) ) { |
| 9163 | return typeof rootjQuery.ready !== "undefined" ? |
| 9164 | rootjQuery.ready( selector ) : |
| 9165 | // Execute immediately if ready is not present |
| 9166 | selector( jQuery ); |
| 9167 | } |
| 9168 | |
| 9169 | if ( selector.selector !== undefined ) { |
| 9170 | this.selector = selector.selector; |
| 9171 | this.context = selector.context; |
| 9172 | } |
| 9173 | |
| 9174 | return jQuery.makeArray( selector, this ); |
| 9175 | }; |
| 9176 | |
| 9177 | // Give the init function the jQuery prototype for later instantiation |
| 9178 | init.prototype = jQuery.fn; |
| 9179 | |
| 9180 | // Initialize central reference |
| 9181 | rootjQuery = jQuery( document ); |
| 9182 | |
| 9183 | |
| 9184 | var rparentsprev = /^(?:parents|prev(?:Until|All))/, |
| 9185 | // Methods guaranteed to produce a unique set when starting from a unique set |
| 9186 | guaranteedUnique = { |
| 9187 | children: true, |
| 9188 | contents: true, |
| 9189 | next: true, |
| 9190 | prev: true |
| 9191 | }; |
| 9192 | |
| 9193 | jQuery.extend({ |
| 9194 | dir: function( elem, dir, until ) { |
| 9195 | var matched = [], |
| 9196 | truncate = until !== undefined; |
| 9197 | |
| 9198 | while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) { |
| 9199 | if ( elem.nodeType === 1 ) { |
| 9200 | if ( truncate && jQuery( elem ).is( until ) ) { |
| 9201 | break; |
| 9202 | } |
| 9203 | matched.push( elem ); |
| 9204 | } |
| 9205 | } |
| 9206 | return matched; |
| 9207 | }, |
| 9208 | |
| 9209 | sibling: function( n, elem ) { |
| 9210 | var matched = []; |
| 9211 | |
| 9212 | for ( ; n; n = n.nextSibling ) { |
| 9213 | if ( n.nodeType === 1 && n !== elem ) { |
| 9214 | matched.push( n ); |
| 9215 | } |
| 9216 | } |
| 9217 | |
| 9218 | return matched; |
| 9219 | } |
| 9220 | }); |
| 9221 | |
| 9222 | jQuery.fn.extend({ |
| 9223 | has: function( target ) { |
| 9224 | var targets = jQuery( target, this ), |
| 9225 | l = targets.length; |
| 9226 | |
| 9227 | return this.filter(function() { |
| 9228 | var i = 0; |
| 9229 | for ( ; i < l; i++ ) { |
| 9230 | if ( jQuery.contains( this, targets[i] ) ) { |
| 9231 | return true; |
| 9232 | } |
| 9233 | } |
| 9234 | }); |
| 9235 | }, |
| 9236 | |
| 9237 | closest: function( selectors, context ) { |
| 9238 | var cur, |
| 9239 | i = 0, |
| 9240 | l = this.length, |
| 9241 | matched = [], |
| 9242 | pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? |
| 9243 | jQuery( selectors, context || this.context ) : |
| 9244 | 0; |
| 9245 | |
| 9246 | for ( ; i < l; i++ ) { |
| 9247 | for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { |
| 9248 | // Always skip document fragments |
| 9249 | if ( cur.nodeType < 11 && (pos ? |
| 9250 | pos.index(cur) > -1 : |
| 9251 | |
| 9252 | // Don't pass non-elements to Sizzle |
| 9253 | cur.nodeType === 1 && |
| 9254 | jQuery.find.matchesSelector(cur, selectors)) ) { |
| 9255 | |
| 9256 | matched.push( cur ); |
| 9257 | break; |
| 9258 | } |
| 9259 | } |
| 9260 | } |
| 9261 | |
| 9262 | return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); |
| 9263 | }, |
| 9264 | |
| 9265 | // Determine the position of an element within the set |
| 9266 | index: function( elem ) { |
| 9267 | |
| 9268 | // No argument, return index in parent |
| 9269 | if ( !elem ) { |
| 9270 | return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; |
| 9271 | } |
| 9272 | |
| 9273 | // Index in selector |
| 9274 | if ( typeof elem === "string" ) { |
| 9275 | return indexOf.call( jQuery( elem ), this[ 0 ] ); |
| 9276 | } |
| 9277 | |
| 9278 | // Locate the position of the desired element |
| 9279 | return indexOf.call( this, |
| 9280 | |
| 9281 | // If it receives a jQuery object, the first element is used |
| 9282 | elem.jquery ? elem[ 0 ] : elem |
| 9283 | ); |
| 9284 | }, |
| 9285 | |
| 9286 | add: function( selector, context ) { |
| 9287 | return this.pushStack( |
| 9288 | jQuery.unique( |
| 9289 | jQuery.merge( this.get(), jQuery( selector, context ) ) |
| 9290 | ) |
| 9291 | ); |
| 9292 | }, |
| 9293 | |
| 9294 | addBack: function( selector ) { |
| 9295 | return this.add( selector == null ? |
| 9296 | this.prevObject : this.prevObject.filter(selector) |
| 9297 | ); |
| 9298 | } |
| 9299 | }); |
| 9300 | |
| 9301 | function sibling( cur, dir ) { |
| 9302 | while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {} |
| 9303 | return cur; |
| 9304 | } |
| 9305 | |
| 9306 | jQuery.each({ |
| 9307 | parent: function( elem ) { |
| 9308 | var parent = elem.parentNode; |
| 9309 | return parent && parent.nodeType !== 11 ? parent : null; |
| 9310 | }, |
| 9311 | parents: function( elem ) { |
| 9312 | return jQuery.dir( elem, "parentNode" ); |
| 9313 | }, |
| 9314 | parentsUntil: function( elem, i, until ) { |
| 9315 | return jQuery.dir( elem, "parentNode", until ); |
| 9316 | }, |
| 9317 | next: function( elem ) { |
| 9318 | return sibling( elem, "nextSibling" ); |
| 9319 | }, |
| 9320 | prev: function( elem ) { |
| 9321 | return sibling( elem, "previousSibling" ); |
| 9322 | }, |
| 9323 | nextAll: function( elem ) { |
| 9324 | return jQuery.dir( elem, "nextSibling" ); |
| 9325 | }, |
| 9326 | prevAll: function( elem ) { |
| 9327 | return jQuery.dir( elem, "previousSibling" ); |
| 9328 | }, |
| 9329 | nextUntil: function( elem, i, until ) { |
| 9330 | return jQuery.dir( elem, "nextSibling", until ); |
| 9331 | }, |
| 9332 | prevUntil: function( elem, i, until ) { |
| 9333 | return jQuery.dir( elem, "previousSibling", until ); |
| 9334 | }, |
| 9335 | siblings: function( elem ) { |
| 9336 | return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); |
| 9337 | }, |
| 9338 | children: function( elem ) { |
| 9339 | return jQuery.sibling( elem.firstChild ); |
| 9340 | }, |
| 9341 | contents: function( elem ) { |
| 9342 | return elem.contentDocument || jQuery.merge( [], elem.childNodes ); |
| 9343 | } |
| 9344 | }, function( name, fn ) { |
| 9345 | jQuery.fn[ name ] = function( until, selector ) { |
| 9346 | var matched = jQuery.map( this, fn, until ); |
| 9347 | |
| 9348 | if ( name.slice( -5 ) !== "Until" ) { |
| 9349 | selector = until; |
| 9350 | } |
| 9351 | |
| 9352 | if ( selector && typeof selector === "string" ) { |
| 9353 | matched = jQuery.filter( selector, matched ); |
| 9354 | } |
| 9355 | |
| 9356 | if ( this.length > 1 ) { |
| 9357 | // Remove duplicates |
| 9358 | if ( !guaranteedUnique[ name ] ) { |
| 9359 | jQuery.unique( matched ); |
| 9360 | } |
| 9361 | |
| 9362 | // Reverse order for parents* and prev-derivatives |
| 9363 | if ( rparentsprev.test( name ) ) { |
| 9364 | matched.reverse(); |
| 9365 | } |
| 9366 | } |
| 9367 | |
| 9368 | return this.pushStack( matched ); |
| 9369 | }; |
| 9370 | }); |
| 9371 | var rnotwhite = (/\S+/g); |
| 9372 | |
| 9373 | |
| 9374 | |
| 9375 | // String to Object options format cache |
| 9376 | var optionsCache = {}; |
| 9377 | |
| 9378 | // Convert String-formatted options into Object-formatted ones and store in cache |
| 9379 | function createOptions( options ) { |
| 9380 | var object = optionsCache[ options ] = {}; |
| 9381 | jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { |
| 9382 | object[ flag ] = true; |
| 9383 | }); |
| 9384 | return object; |
| 9385 | } |
| 9386 | |
| 9387 | /* |
| 9388 | * Create a callback list using the following parameters: |
| 9389 | * |
| 9390 | * options: an optional list of space-separated options that will change how |
| 9391 | * the callback list behaves or a more traditional option object |
| 9392 | * |
| 9393 | * By default a callback list will act like an event callback list and can be |
| 9394 | * "fired" multiple times. |
| 9395 | * |
| 9396 | * Possible options: |
| 9397 | * |
| 9398 | * once: will ensure the callback list can only be fired once (like a Deferred) |
| 9399 | * |
| 9400 | * memory: will keep track of previous values and will call any callback added |
| 9401 | * after the list has been fired right away with the latest "memorized" |
| 9402 | * values (like a Deferred) |
| 9403 | * |
| 9404 | * unique: will ensure a callback can only be added once (no duplicate in the list) |
| 9405 | * |
| 9406 | * stopOnFalse: interrupt callings when a callback returns false |
| 9407 | * |
| 9408 | */ |
| 9409 | jQuery.Callbacks = function( options ) { |
| 9410 | |
| 9411 | // Convert options from String-formatted to Object-formatted if needed |
| 9412 | // (we check in cache first) |
| 9413 | options = typeof options === "string" ? |
| 9414 | ( optionsCache[ options ] || createOptions( options ) ) : |
| 9415 | jQuery.extend( {}, options ); |
| 9416 | |
| 9417 | var // Last fire value (for non-forgettable lists) |
| 9418 | memory, |
| 9419 | // Flag to know if list was already fired |
| 9420 | fired, |
| 9421 | // Flag to know if list is currently firing |
| 9422 | firing, |
| 9423 | // First callback to fire (used internally by add and fireWith) |
| 9424 | firingStart, |
| 9425 | // End of the loop when firing |
| 9426 | firingLength, |
| 9427 | // Index of currently firing callback (modified by remove if needed) |
| 9428 | firingIndex, |
| 9429 | // Actual callback list |
| 9430 | list = [], |
| 9431 | // Stack of fire calls for repeatable lists |
| 9432 | stack = !options.once && [], |
| 9433 | // Fire callbacks |
| 9434 | fire = function( data ) { |
| 9435 | memory = options.memory && data; |
| 9436 | fired = true; |
| 9437 | firingIndex = firingStart || 0; |
| 9438 | firingStart = 0; |
| 9439 | firingLength = list.length; |
| 9440 | firing = true; |
| 9441 | for ( ; list && firingIndex < firingLength; firingIndex++ ) { |
| 9442 | if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { |
| 9443 | memory = false; // To prevent further calls using add |
| 9444 | break; |
| 9445 | } |
| 9446 | } |
| 9447 | firing = false; |
| 9448 | if ( list ) { |
| 9449 | if ( stack ) { |
| 9450 | if ( stack.length ) { |
| 9451 | fire( stack.shift() ); |
| 9452 | } |
| 9453 | } else if ( memory ) { |
| 9454 | list = []; |
| 9455 | } else { |
| 9456 | self.disable(); |
| 9457 | } |
| 9458 | } |
| 9459 | }, |
| 9460 | // Actual Callbacks object |
| 9461 | self = { |
| 9462 | // Add a callback or a collection of callbacks to the list |
| 9463 | add: function() { |
| 9464 | if ( list ) { |
| 9465 | // First, we save the current length |
| 9466 | var start = list.length; |
| 9467 | (function add( args ) { |
| 9468 | jQuery.each( args, function( _, arg ) { |
| 9469 | var type = jQuery.type( arg ); |
| 9470 | if ( type === "function" ) { |
| 9471 | if ( !options.unique || !self.has( arg ) ) { |
| 9472 | list.push( arg ); |
| 9473 | } |
| 9474 | } else if ( arg && arg.length && type !== "string" ) { |
| 9475 | // Inspect recursively |
| 9476 | add( arg ); |
| 9477 | } |
| 9478 | }); |
| 9479 | })( arguments ); |
| 9480 | // Do we need to add the callbacks to the |
| 9481 | // current firing batch? |
| 9482 | if ( firing ) { |
| 9483 | firingLength = list.length; |
| 9484 | // With memory, if we're not firing then |
| 9485 | // we should call right away |
| 9486 | } else if ( memory ) { |
| 9487 | firingStart = start; |
| 9488 | fire( memory ); |
| 9489 | } |
| 9490 | } |
| 9491 | return this; |
| 9492 | }, |
| 9493 | // Remove a callback from the list |
| 9494 | remove: function() { |
| 9495 | if ( list ) { |
| 9496 | jQuery.each( arguments, function( _, arg ) { |
| 9497 | var index; |
| 9498 | while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { |
| 9499 | list.splice( index, 1 ); |
| 9500 | // Handle firing indexes |
| 9501 | if ( firing ) { |
| 9502 | if ( index <= firingLength ) { |
| 9503 | firingLength--; |
| 9504 | } |
| 9505 | if ( index <= firingIndex ) { |
| 9506 | firingIndex--; |
| 9507 | } |
| 9508 | } |
| 9509 | } |
| 9510 | }); |
| 9511 | } |
| 9512 | return this; |
| 9513 | }, |
| 9514 | // Check if a given callback is in the list. |
| 9515 | // If no argument is given, return whether or not list has callbacks attached. |
| 9516 | has: function( fn ) { |
| 9517 | return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); |
| 9518 | }, |
| 9519 | // Remove all callbacks from the list |
| 9520 | empty: function() { |
| 9521 | list = []; |
| 9522 | firingLength = 0; |
| 9523 | return this; |
| 9524 | }, |
| 9525 | // Have the list do nothing anymore |
| 9526 | disable: function() { |
| 9527 | list = stack = memory = undefined; |
| 9528 | return this; |
| 9529 | }, |
| 9530 | // Is it disabled? |
| 9531 | disabled: function() { |
| 9532 | return !list; |
| 9533 | }, |
| 9534 | // Lock the list in its current state |
| 9535 | lock: function() { |
| 9536 | stack = undefined; |
| 9537 | if ( !memory ) { |
| 9538 | self.disable(); |
| 9539 | } |
| 9540 | return this; |
| 9541 | }, |
| 9542 | // Is it locked? |
| 9543 | locked: function() { |
| 9544 | return !stack; |
| 9545 | }, |
| 9546 | // Call all callbacks with the given context and arguments |
| 9547 | fireWith: function( context, args ) { |
| 9548 | if ( list && ( !fired || stack ) ) { |
| 9549 | args = args || []; |
| 9550 | args = [ context, args.slice ? args.slice() : args ]; |
| 9551 | if ( firing ) { |
| 9552 | stack.push( args ); |
| 9553 | } else { |
| 9554 | fire( args ); |
| 9555 | } |
| 9556 | } |
| 9557 | return this; |
| 9558 | }, |
| 9559 | // Call all the callbacks with the given arguments |
| 9560 | fire: function() { |
| 9561 | self.fireWith( this, arguments ); |
| 9562 | return this; |
| 9563 | }, |
| 9564 | // To know if the callbacks have already been called at least once |
| 9565 | fired: function() { |
| 9566 | return !!fired; |
| 9567 | } |
| 9568 | }; |
| 9569 | |
| 9570 | return self; |
| 9571 | }; |
| 9572 | |
| 9573 | |
| 9574 | jQuery.extend({ |
| 9575 | |
| 9576 | Deferred: function( func ) { |
| 9577 | var tuples = [ |
| 9578 | // action, add listener, listener list, final state |
| 9579 | [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], |
| 9580 | [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], |
| 9581 | [ "notify", "progress", jQuery.Callbacks("memory") ] |
| 9582 | ], |
| 9583 | state = "pending", |
| 9584 | promise = { |
| 9585 | state: function() { |
| 9586 | return state; |
| 9587 | }, |
| 9588 | always: function() { |
| 9589 | deferred.done( arguments ).fail( arguments ); |
| 9590 | return this; |
| 9591 | }, |
| 9592 | then: function( /* fnDone, fnFail, fnProgress */ ) { |
| 9593 | var fns = arguments; |
| 9594 | return jQuery.Deferred(function( newDefer ) { |
| 9595 | jQuery.each( tuples, function( i, tuple ) { |
| 9596 | var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; |
| 9597 | // deferred[ done | fail | progress ] for forwarding actions to newDefer |
| 9598 | deferred[ tuple[1] ](function() { |
| 9599 | var returned = fn && fn.apply( this, arguments ); |
| 9600 | if ( returned && jQuery.isFunction( returned.promise ) ) { |
| 9601 | returned.promise() |
| 9602 | .done( newDefer.resolve ) |
| 9603 | .fail( newDefer.reject ) |
| 9604 | .progress( newDefer.notify ); |
| 9605 | } else { |
| 9606 | newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); |
| 9607 | } |
| 9608 | }); |
| 9609 | }); |
| 9610 | fns = null; |
| 9611 | }).promise(); |
| 9612 | }, |
| 9613 | // Get a promise for this deferred |
| 9614 | // If obj is provided, the promise aspect is added to the object |
| 9615 | promise: function( obj ) { |
| 9616 | return obj != null ? jQuery.extend( obj, promise ) : promise; |
| 9617 | } |
| 9618 | }, |
| 9619 | deferred = {}; |
| 9620 | |
| 9621 | // Keep pipe for back-compat |
| 9622 | promise.pipe = promise.then; |
| 9623 | |
| 9624 | // Add list-specific methods |
| 9625 | jQuery.each( tuples, function( i, tuple ) { |
| 9626 | var list = tuple[ 2 ], |
| 9627 | stateString = tuple[ 3 ]; |
| 9628 | |
| 9629 | // promise[ done | fail | progress ] = list.add |
| 9630 | promise[ tuple[1] ] = list.add; |
| 9631 | |
| 9632 | // Handle state |
| 9633 | if ( stateString ) { |
| 9634 | list.add(function() { |
| 9635 | // state = [ resolved | rejected ] |
| 9636 | state = stateString; |
| 9637 | |
| 9638 | // [ reject_list | resolve_list ].disable; progress_list.lock |
| 9639 | }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); |
| 9640 | } |
| 9641 | |
| 9642 | // deferred[ resolve | reject | notify ] |
| 9643 | deferred[ tuple[0] ] = function() { |
| 9644 | deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); |
| 9645 | return this; |
| 9646 | }; |
| 9647 | deferred[ tuple[0] + "With" ] = list.fireWith; |
| 9648 | }); |
| 9649 | |
| 9650 | // Make the deferred a promise |
| 9651 | promise.promise( deferred ); |
| 9652 | |
| 9653 | // Call given func if any |
| 9654 | if ( func ) { |
| 9655 | func.call( deferred, deferred ); |
| 9656 | } |
| 9657 | |
| 9658 | // All done! |
| 9659 | return deferred; |
| 9660 | }, |
| 9661 | |
| 9662 | // Deferred helper |
| 9663 | when: function( subordinate /* , ..., subordinateN */ ) { |
| 9664 | var i = 0, |
| 9665 | resolveValues = slice.call( arguments ), |
| 9666 | length = resolveValues.length, |
| 9667 | |
| 9668 | // the count of uncompleted subordinates |
| 9669 | remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, |
| 9670 | |
| 9671 | // the master Deferred. If resolveValues consist of only a single Deferred, just use that. |
| 9672 | deferred = remaining === 1 ? subordinate : jQuery.Deferred(), |
| 9673 | |
| 9674 | // Update function for both resolve and progress values |
| 9675 | updateFunc = function( i, contexts, values ) { |
| 9676 | return function( value ) { |
| 9677 | contexts[ i ] = this; |
| 9678 | values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; |
| 9679 | if ( values === progressValues ) { |
| 9680 | deferred.notifyWith( contexts, values ); |
| 9681 | } else if ( !( --remaining ) ) { |
| 9682 | deferred.resolveWith( contexts, values ); |
| 9683 | } |
| 9684 | }; |
| 9685 | }, |
| 9686 | |
| 9687 | progressValues, progressContexts, resolveContexts; |
| 9688 | |
| 9689 | // Add listeners to Deferred subordinates; treat others as resolved |
| 9690 | if ( length > 1 ) { |
| 9691 | progressValues = new Array( length ); |
| 9692 | progressContexts = new Array( length ); |
| 9693 | resolveContexts = new Array( length ); |
| 9694 | for ( ; i < length; i++ ) { |
| 9695 | if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { |
| 9696 | resolveValues[ i ].promise() |
| 9697 | .done( updateFunc( i, resolveContexts, resolveValues ) ) |
| 9698 | .fail( deferred.reject ) |
| 9699 | .progress( updateFunc( i, progressContexts, progressValues ) ); |
| 9700 | } else { |
| 9701 | --remaining; |
| 9702 | } |
| 9703 | } |
| 9704 | } |
| 9705 | |
| 9706 | // If we're not waiting on anything, resolve the master |
| 9707 | if ( !remaining ) { |
| 9708 | deferred.resolveWith( resolveContexts, resolveValues ); |
| 9709 | } |
| 9710 | |
| 9711 | return deferred.promise(); |
| 9712 | } |
| 9713 | }); |
| 9714 | |
| 9715 | |
| 9716 | // The deferred used on DOM ready |
| 9717 | var readyList; |
| 9718 | |
| 9719 | jQuery.fn.ready = function( fn ) { |
| 9720 | // Add the callback |
| 9721 | jQuery.ready.promise().done( fn ); |
| 9722 | |
| 9723 | return this; |
| 9724 | }; |
| 9725 | |
| 9726 | jQuery.extend({ |
| 9727 | // Is the DOM ready to be used? Set to true once it occurs. |
| 9728 | isReady: false, |
| 9729 | |
| 9730 | // A counter to track how many items to wait for before |
| 9731 | // the ready event fires. See #6781 |
| 9732 | readyWait: 1, |
| 9733 | |
| 9734 | // Hold (or release) the ready event |
| 9735 | holdReady: function( hold ) { |
| 9736 | if ( hold ) { |
| 9737 | jQuery.readyWait++; |
| 9738 | } else { |
| 9739 | jQuery.ready( true ); |
| 9740 | } |
| 9741 | }, |
| 9742 | |
| 9743 | // Handle when the DOM is ready |
| 9744 | ready: function( wait ) { |
| 9745 | |
| 9746 | // Abort if there are pending holds or we're already ready |
| 9747 | if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { |
| 9748 | return; |
| 9749 | } |
| 9750 | |
| 9751 | // Remember that the DOM is ready |
| 9752 | jQuery.isReady = true; |
| 9753 | |
| 9754 | // If a normal DOM Ready event fired, decrement, and wait if need be |
| 9755 | if ( wait !== true && --jQuery.readyWait > 0 ) { |
| 9756 | return; |
| 9757 | } |
| 9758 | |
| 9759 | // If there are functions bound, to execute |
| 9760 | readyList.resolveWith( document, [ jQuery ] ); |
| 9761 | |
| 9762 | // Trigger any bound ready events |
| 9763 | if ( jQuery.fn.triggerHandler ) { |
| 9764 | jQuery( document ).triggerHandler( "ready" ); |
| 9765 | jQuery( document ).off( "ready" ); |
| 9766 | } |
| 9767 | } |
| 9768 | }); |
| 9769 | |
| 9770 | /** |
| 9771 | * The ready event handler and self cleanup method |
| 9772 | */ |
| 9773 | function completed() { |
| 9774 | document.removeEventListener( "DOMContentLoaded", completed, false ); |
| 9775 | window.removeEventListener( "load", completed, false ); |
| 9776 | jQuery.ready(); |
| 9777 | } |
| 9778 | |
| 9779 | jQuery.ready.promise = function( obj ) { |
| 9780 | if ( !readyList ) { |
| 9781 | |
| 9782 | readyList = jQuery.Deferred(); |
| 9783 | |
| 9784 | // Catch cases where $(document).ready() is called after the browser event has already occurred. |
| 9785 | // We once tried to use readyState "interactive" here, but it caused issues like the one |
| 9786 | // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 |
| 9787 | if ( document.readyState === "complete" ) { |
| 9788 | // Handle it asynchronously to allow scripts the opportunity to delay ready |
| 9789 | setTimeout( jQuery.ready ); |
| 9790 | |
| 9791 | } else { |
| 9792 | |
| 9793 | // Use the handy event callback |
| 9794 | document.addEventListener( "DOMContentLoaded", completed, false ); |
| 9795 | |
| 9796 | // A fallback to window.onload, that will always work |
| 9797 | window.addEventListener( "load", completed, false ); |
| 9798 | } |
| 9799 | } |
| 9800 | return readyList.promise( obj ); |
| 9801 | }; |
| 9802 | |
| 9803 | // Kick off the DOM ready check even if the user does not |
| 9804 | jQuery.ready.promise(); |
| 9805 | |
| 9806 | |
| 9807 | |
| 9808 | |
| 9809 | // Multifunctional method to get and set values of a collection |
| 9810 | // The value/s can optionally be executed if it's a function |
| 9811 | var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) { |
| 9812 | var i = 0, |
| 9813 | len = elems.length, |
| 9814 | bulk = key == null; |
| 9815 | |
| 9816 | // Sets many values |
| 9817 | if ( jQuery.type( key ) === "object" ) { |
| 9818 | chainable = true; |
| 9819 | for ( i in key ) { |
| 9820 | jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); |
| 9821 | } |
| 9822 | |
| 9823 | // Sets one value |
| 9824 | } else if ( value !== undefined ) { |
| 9825 | chainable = true; |
| 9826 | |
| 9827 | if ( !jQuery.isFunction( value ) ) { |
| 9828 | raw = true; |
| 9829 | } |
| 9830 | |
| 9831 | if ( bulk ) { |
| 9832 | // Bulk operations run against the entire set |
| 9833 | if ( raw ) { |
| 9834 | fn.call( elems, value ); |
| 9835 | fn = null; |
| 9836 | |
| 9837 | // ...except when executing function values |
| 9838 | } else { |
| 9839 | bulk = fn; |
| 9840 | fn = function( elem, key, value ) { |
| 9841 | return bulk.call( jQuery( elem ), value ); |
| 9842 | }; |
| 9843 | } |
| 9844 | } |
| 9845 | |
| 9846 | if ( fn ) { |
| 9847 | for ( ; i < len; i++ ) { |
| 9848 | fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); |
| 9849 | } |
| 9850 | } |
| 9851 | } |
| 9852 | |
| 9853 | return chainable ? |
| 9854 | elems : |
| 9855 | |
| 9856 | // Gets |
| 9857 | bulk ? |
| 9858 | fn.call( elems ) : |
| 9859 | len ? fn( elems[0], key ) : emptyGet; |
| 9860 | }; |
| 9861 | |
| 9862 | |
| 9863 | /** |
| 9864 | * Determines whether an object can have data |
| 9865 | */ |
| 9866 | jQuery.acceptData = function( owner ) { |
| 9867 | // Accepts only: |
| 9868 | // - Node |
| 9869 | // - Node.ELEMENT_NODE |
| 9870 | // - Node.DOCUMENT_NODE |
| 9871 | // - Object |
| 9872 | // - Any |
| 9873 | /* jshint -W018 */ |
| 9874 | return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); |
| 9875 | }; |
| 9876 | |
| 9877 | |
| 9878 | function Data() { |
| 9879 | // Support: Android<4, |
| 9880 | // Old WebKit does not have Object.preventExtensions/freeze method, |
| 9881 | // return new empty object instead with no [[set]] accessor |
| 9882 | Object.defineProperty( this.cache = {}, 0, { |
| 9883 | get: function() { |
| 9884 | return {}; |
| 9885 | } |
| 9886 | }); |
| 9887 | |
| 9888 | this.expando = jQuery.expando + Data.uid++; |
| 9889 | } |
| 9890 | |
| 9891 | Data.uid = 1; |
| 9892 | Data.accepts = jQuery.acceptData; |
| 9893 | |
| 9894 | Data.prototype = { |
| 9895 | key: function( owner ) { |
| 9896 | // We can accept data for non-element nodes in modern browsers, |
| 9897 | // but we should not, see #8335. |
| 9898 | // Always return the key for a frozen object. |
| 9899 | if ( !Data.accepts( owner ) ) { |
| 9900 | return 0; |
| 9901 | } |
| 9902 | |
| 9903 | var descriptor = {}, |
| 9904 | // Check if the owner object already has a cache key |
| 9905 | unlock = owner[ this.expando ]; |
| 9906 | |
| 9907 | // If not, create one |
| 9908 | if ( !unlock ) { |
| 9909 | unlock = Data.uid++; |
| 9910 | |
| 9911 | // Secure it in a non-enumerable, non-writable property |
| 9912 | try { |
| 9913 | descriptor[ this.expando ] = { value: unlock }; |
| 9914 | Object.defineProperties( owner, descriptor ); |
| 9915 | |
| 9916 | // Support: Android<4 |
| 9917 | // Fallback to a less secure definition |
| 9918 | } catch ( e ) { |
| 9919 | descriptor[ this.expando ] = unlock; |
| 9920 | jQuery.extend( owner, descriptor ); |
| 9921 | } |
| 9922 | } |
| 9923 | |
| 9924 | // Ensure the cache object |
| 9925 | if ( !this.cache[ unlock ] ) { |
| 9926 | this.cache[ unlock ] = {}; |
| 9927 | } |
| 9928 | |
| 9929 | return unlock; |
| 9930 | }, |
| 9931 | set: function( owner, data, value ) { |
| 9932 | var prop, |
| 9933 | // There may be an unlock assigned to this node, |
| 9934 | // if there is no entry for this "owner", create one inline |
| 9935 | // and set the unlock as though an owner entry had always existed |
| 9936 | unlock = this.key( owner ), |
| 9937 | cache = this.cache[ unlock ]; |
| 9938 | |
| 9939 | // Handle: [ owner, key, value ] args |
| 9940 | if ( typeof data === "string" ) { |
| 9941 | cache[ data ] = value; |
| 9942 | |
| 9943 | // Handle: [ owner, { properties } ] args |
| 9944 | } else { |
| 9945 | // Fresh assignments by object are shallow copied |
| 9946 | if ( jQuery.isEmptyObject( cache ) ) { |
| 9947 | jQuery.extend( this.cache[ unlock ], data ); |
| 9948 | // Otherwise, copy the properties one-by-one to the cache object |
| 9949 | } else { |
| 9950 | for ( prop in data ) { |
| 9951 | cache[ prop ] = data[ prop ]; |
| 9952 | } |
| 9953 | } |
| 9954 | } |
| 9955 | return cache; |
| 9956 | }, |
| 9957 | get: function( owner, key ) { |
| 9958 | // Either a valid cache is found, or will be created. |
| 9959 | // New caches will be created and the unlock returned, |
| 9960 | // allowing direct access to the newly created |
| 9961 | // empty data object. A valid owner object must be provided. |
| 9962 | var cache = this.cache[ this.key( owner ) ]; |
| 9963 | |
| 9964 | return key === undefined ? |
| 9965 | cache : cache[ key ]; |
| 9966 | }, |
| 9967 | access: function( owner, key, value ) { |
| 9968 | var stored; |
| 9969 | // In cases where either: |
| 9970 | // |
| 9971 | // 1. No key was specified |
| 9972 | // 2. A string key was specified, but no value provided |
| 9973 | // |
| 9974 | // Take the "read" path and allow the get method to determine |
| 9975 | // which value to return, respectively either: |
| 9976 | // |
| 9977 | // 1. The entire cache object |
| 9978 | // 2. The data stored at the key |
| 9979 | // |
| 9980 | if ( key === undefined || |
| 9981 | ((key && typeof key === "string") && value === undefined) ) { |
| 9982 | |
| 9983 | stored = this.get( owner, key ); |
| 9984 | |
| 9985 | return stored !== undefined ? |
| 9986 | stored : this.get( owner, jQuery.camelCase(key) ); |
| 9987 | } |
| 9988 | |
| 9989 | // [*]When the key is not a string, or both a key and value |
| 9990 | // are specified, set or extend (existing objects) with either: |
| 9991 | // |
| 9992 | // 1. An object of properties |
| 9993 | // 2. A key and value |
| 9994 | // |
| 9995 | this.set( owner, key, value ); |
| 9996 | |
| 9997 | // Since the "set" path can have two possible entry points |
| 9998 | // return the expected data based on which path was taken[*] |
| 9999 | return value !== undefined ? value : key; |
| 10000 | }, |
| 10001 | remove: function( owner, key ) { |
| 10002 | var i, name, camel, |
| 10003 | unlock = this.key( owner ), |
| 10004 | cache = this.cache[ unlock ]; |
| 10005 | |
| 10006 | if ( key === undefined ) { |
| 10007 | this.cache[ unlock ] = {}; |
| 10008 | |
| 10009 | } else { |
| 10010 | // Support array or space separated string of keys |
| 10011 | if ( jQuery.isArray( key ) ) { |
| 10012 | // If "name" is an array of keys... |
| 10013 | // When data is initially created, via ("key", "val") signature, |
| 10014 | // keys will be converted to camelCase. |
| 10015 | // Since there is no way to tell _how_ a key was added, remove |
| 10016 | // both plain key and camelCase key. #12786 |
| 10017 | // This will only penalize the array argument path. |
| 10018 | name = key.concat( key.map( jQuery.camelCase ) ); |
| 10019 | } else { |
| 10020 | camel = jQuery.camelCase( key ); |
| 10021 | // Try the string as a key before any manipulation |
| 10022 | if ( key in cache ) { |
| 10023 | name = [ key, camel ]; |
| 10024 | } else { |
| 10025 | // If a key with the spaces exists, use it. |
| 10026 | // Otherwise, create an array by matching non-whitespace |
| 10027 | name = camel; |
| 10028 | name = name in cache ? |
| 10029 | [ name ] : ( name.match( rnotwhite ) || [] ); |
| 10030 | } |
| 10031 | } |
| 10032 | |
| 10033 | i = name.length; |
| 10034 | while ( i-- ) { |
| 10035 | delete cache[ name[ i ] ]; |
| 10036 | } |
| 10037 | } |
| 10038 | }, |
| 10039 | hasData: function( owner ) { |
| 10040 | return !jQuery.isEmptyObject( |
| 10041 | this.cache[ owner[ this.expando ] ] || {} |
| 10042 | ); |
| 10043 | }, |
| 10044 | discard: function( owner ) { |
| 10045 | if ( owner[ this.expando ] ) { |
| 10046 | delete this.cache[ owner[ this.expando ] ]; |
| 10047 | } |
| 10048 | } |
| 10049 | }; |
| 10050 | var data_priv = new Data(); |
| 10051 | |
| 10052 | var data_user = new Data(); |
| 10053 | |
| 10054 | |
| 10055 | |
| 10056 | // Implementation Summary |
| 10057 | // |
| 10058 | // 1. Enforce API surface and semantic compatibility with 1.9.x branch |
| 10059 | // 2. Improve the module's maintainability by reducing the storage |
| 10060 | // paths to a single mechanism. |
| 10061 | // 3. Use the same single mechanism to support "private" and "user" data. |
| 10062 | // 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) |
| 10063 | // 5. Avoid exposing implementation details on user objects (eg. expando properties) |
| 10064 | // 6. Provide a clear path for implementation upgrade to WeakMap in 2014 |
| 10065 | |
| 10066 | var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, |
| 10067 | rmultiDash = /([A-Z])/g; |
| 10068 | |
| 10069 | function dataAttr( elem, key, data ) { |
| 10070 | var name; |
| 10071 | |
| 10072 | // If nothing was found internally, try to fetch any |
| 10073 | // data from the HTML5 data-* attribute |
| 10074 | if ( data === undefined && elem.nodeType === 1 ) { |
| 10075 | name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); |
| 10076 | data = elem.getAttribute( name ); |
| 10077 | |
| 10078 | if ( typeof data === "string" ) { |
| 10079 | try { |
| 10080 | data = data === "true" ? true : |
| 10081 | data === "false" ? false : |
| 10082 | data === "null" ? null : |
| 10083 | // Only convert to a number if it doesn't change the string |
| 10084 | +data + "" === data ? +data : |
| 10085 | rbrace.test( data ) ? jQuery.parseJSON( data ) : |
| 10086 | data; |
| 10087 | } catch( e ) {} |
| 10088 | |
| 10089 | // Make sure we set the data so it isn't changed later |
| 10090 | data_user.set( elem, key, data ); |
| 10091 | } else { |
| 10092 | data = undefined; |
| 10093 | } |
| 10094 | } |
| 10095 | return data; |
| 10096 | } |
| 10097 | |
| 10098 | jQuery.extend({ |
| 10099 | hasData: function( elem ) { |
| 10100 | return data_user.hasData( elem ) || data_priv.hasData( elem ); |
| 10101 | }, |
| 10102 | |
| 10103 | data: function( elem, name, data ) { |
| 10104 | return data_user.access( elem, name, data ); |
| 10105 | }, |
| 10106 | |
| 10107 | removeData: function( elem, name ) { |
| 10108 | data_user.remove( elem, name ); |
| 10109 | }, |
| 10110 | |
| 10111 | // TODO: Now that all calls to _data and _removeData have been replaced |
| 10112 | // with direct calls to data_priv methods, these can be deprecated. |
| 10113 | _data: function( elem, name, data ) { |
| 10114 | return data_priv.access( elem, name, data ); |
| 10115 | }, |
| 10116 | |
| 10117 | _removeData: function( elem, name ) { |
| 10118 | data_priv.remove( elem, name ); |
| 10119 | } |
| 10120 | }); |
| 10121 | |
| 10122 | jQuery.fn.extend({ |
| 10123 | data: function( key, value ) { |
| 10124 | var i, name, data, |
| 10125 | elem = this[ 0 ], |
| 10126 | attrs = elem && elem.attributes; |
| 10127 | |
| 10128 | // Gets all values |
| 10129 | if ( key === undefined ) { |
| 10130 | if ( this.length ) { |
| 10131 | data = data_user.get( elem ); |
| 10132 | |
| 10133 | if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) { |
| 10134 | i = attrs.length; |
| 10135 | while ( i-- ) { |
| 10136 | |
| 10137 | // Support: IE11+ |
| 10138 | // The attrs elements can be null (#14894) |
| 10139 | if ( attrs[ i ] ) { |
| 10140 | name = attrs[ i ].name; |
| 10141 | if ( name.indexOf( "data-" ) === 0 ) { |
| 10142 | name = jQuery.camelCase( name.slice(5) ); |
| 10143 | dataAttr( elem, name, data[ name ] ); |
| 10144 | } |
| 10145 | } |
| 10146 | } |
| 10147 | data_priv.set( elem, "hasDataAttrs", true ); |
| 10148 | } |
| 10149 | } |
| 10150 | |
| 10151 | return data; |
| 10152 | } |
| 10153 | |
| 10154 | // Sets multiple values |
| 10155 | if ( typeof key === "object" ) { |
| 10156 | return this.each(function() { |
| 10157 | data_user.set( this, key ); |
| 10158 | }); |
| 10159 | } |
| 10160 | |
| 10161 | return access( this, function( value ) { |
| 10162 | var data, |
| 10163 | camelKey = jQuery.camelCase( key ); |
| 10164 | |
| 10165 | // The calling jQuery object (element matches) is not empty |
| 10166 | // (and therefore has an element appears at this[ 0 ]) and the |
| 10167 | // `value` parameter was not undefined. An empty jQuery object |
| 10168 | // will result in `undefined` for elem = this[ 0 ] which will |
| 10169 | // throw an exception if an attempt to read a data cache is made. |
| 10170 | if ( elem && value === undefined ) { |
| 10171 | // Attempt to get data from the cache |
| 10172 | // with the key as-is |
| 10173 | data = data_user.get( elem, key ); |
| 10174 | if ( data !== undefined ) { |
| 10175 | return data; |
| 10176 | } |
| 10177 | |
| 10178 | // Attempt to get data from the cache |
| 10179 | // with the key camelized |
| 10180 | data = data_user.get( elem, camelKey ); |
| 10181 | if ( data !== undefined ) { |
| 10182 | return data; |
| 10183 | } |
| 10184 | |
| 10185 | // Attempt to "discover" the data in |
| 10186 | // HTML5 custom data-* attrs |
| 10187 | data = dataAttr( elem, camelKey, undefined ); |
| 10188 | if ( data !== undefined ) { |
| 10189 | return data; |
| 10190 | } |
| 10191 | |
| 10192 | // We tried really hard, but the data doesn't exist. |
| 10193 | return; |
| 10194 | } |
| 10195 | |
| 10196 | // Set the data... |
| 10197 | this.each(function() { |
| 10198 | // First, attempt to store a copy or reference of any |
| 10199 | // data that might've been store with a camelCased key. |
| 10200 | var data = data_user.get( this, camelKey ); |
| 10201 | |
| 10202 | // For HTML5 data-* attribute interop, we have to |
| 10203 | // store property names with dashes in a camelCase form. |
| 10204 | // This might not apply to all properties...* |
| 10205 | data_user.set( this, camelKey, value ); |
| 10206 | |
| 10207 | // *... In the case of properties that might _actually_ |
| 10208 | // have dashes, we need to also store a copy of that |
| 10209 | // unchanged property. |
| 10210 | if ( key.indexOf("-") !== -1 && data !== undefined ) { |
| 10211 | data_user.set( this, key, value ); |
| 10212 | } |
| 10213 | }); |
| 10214 | }, null, value, arguments.length > 1, null, true ); |
| 10215 | }, |
| 10216 | |
| 10217 | removeData: function( key ) { |
| 10218 | return this.each(function() { |
| 10219 | data_user.remove( this, key ); |
| 10220 | }); |
| 10221 | } |
| 10222 | }); |
| 10223 | |
| 10224 | |
| 10225 | jQuery.extend({ |
| 10226 | queue: function( elem, type, data ) { |
| 10227 | var queue; |
| 10228 | |
| 10229 | if ( elem ) { |
| 10230 | type = ( type || "fx" ) + "queue"; |
| 10231 | queue = data_priv.get( elem, type ); |
| 10232 | |
| 10233 | // Speed up dequeue by getting out quickly if this is just a lookup |
| 10234 | if ( data ) { |
| 10235 | if ( !queue || jQuery.isArray( data ) ) { |
| 10236 | queue = data_priv.access( elem, type, jQuery.makeArray(data) ); |
| 10237 | } else { |
| 10238 | queue.push( data ); |
| 10239 | } |
| 10240 | } |
| 10241 | return queue || []; |
| 10242 | } |
| 10243 | }, |
| 10244 | |
| 10245 | dequeue: function( elem, type ) { |
| 10246 | type = type || "fx"; |
| 10247 | |
| 10248 | var queue = jQuery.queue( elem, type ), |
| 10249 | startLength = queue.length, |
| 10250 | fn = queue.shift(), |
| 10251 | hooks = jQuery._queueHooks( elem, type ), |
| 10252 | next = function() { |
| 10253 | jQuery.dequeue( elem, type ); |
| 10254 | }; |
| 10255 | |
| 10256 | // If the fx queue is dequeued, always remove the progress sentinel |
| 10257 | if ( fn === "inprogress" ) { |
| 10258 | fn = queue.shift(); |
| 10259 | startLength--; |
| 10260 | } |
| 10261 | |
| 10262 | if ( fn ) { |
| 10263 | |
| 10264 | // Add a progress sentinel to prevent the fx queue from being |
| 10265 | // automatically dequeued |
| 10266 | if ( type === "fx" ) { |
| 10267 | queue.unshift( "inprogress" ); |
| 10268 | } |
| 10269 | |
| 10270 | // Clear up the last queue stop function |
| 10271 | delete hooks.stop; |
| 10272 | fn.call( elem, next, hooks ); |
| 10273 | } |
| 10274 | |
| 10275 | if ( !startLength && hooks ) { |
| 10276 | hooks.empty.fire(); |
| 10277 | } |
| 10278 | }, |
| 10279 | |
| 10280 | // Not public - generate a queueHooks object, or return the current one |
| 10281 | _queueHooks: function( elem, type ) { |
| 10282 | var key = type + "queueHooks"; |
| 10283 | return data_priv.get( elem, key ) || data_priv.access( elem, key, { |
| 10284 | empty: jQuery.Callbacks("once memory").add(function() { |
| 10285 | data_priv.remove( elem, [ type + "queue", key ] ); |
| 10286 | }) |
| 10287 | }); |
| 10288 | } |
| 10289 | }); |
| 10290 | |
| 10291 | jQuery.fn.extend({ |
| 10292 | queue: function( type, data ) { |
| 10293 | var setter = 2; |
| 10294 | |
| 10295 | if ( typeof type !== "string" ) { |
| 10296 | data = type; |
| 10297 | type = "fx"; |
| 10298 | setter--; |
| 10299 | } |
| 10300 | |
| 10301 | if ( arguments.length < setter ) { |
| 10302 | return jQuery.queue( this[0], type ); |
| 10303 | } |
| 10304 | |
| 10305 | return data === undefined ? |
| 10306 | this : |
| 10307 | this.each(function() { |
| 10308 | var queue = jQuery.queue( this, type, data ); |
| 10309 | |
| 10310 | // Ensure a hooks for this queue |
| 10311 | jQuery._queueHooks( this, type ); |
| 10312 | |
| 10313 | if ( type === "fx" && queue[0] !== "inprogress" ) { |
| 10314 | jQuery.dequeue( this, type ); |
| 10315 | } |
| 10316 | }); |
| 10317 | }, |
| 10318 | dequeue: function( type ) { |
| 10319 | return this.each(function() { |
| 10320 | jQuery.dequeue( this, type ); |
| 10321 | }); |
| 10322 | }, |
| 10323 | clearQueue: function( type ) { |
| 10324 | return this.queue( type || "fx", [] ); |
| 10325 | }, |
| 10326 | // Get a promise resolved when queues of a certain type |
| 10327 | // are emptied (fx is the type by default) |
| 10328 | promise: function( type, obj ) { |
| 10329 | var tmp, |
| 10330 | count = 1, |
| 10331 | defer = jQuery.Deferred(), |
| 10332 | elements = this, |
| 10333 | i = this.length, |
| 10334 | resolve = function() { |
| 10335 | if ( !( --count ) ) { |
| 10336 | defer.resolveWith( elements, [ elements ] ); |
| 10337 | } |
| 10338 | }; |
| 10339 | |
| 10340 | if ( typeof type !== "string" ) { |
| 10341 | obj = type; |
| 10342 | type = undefined; |
| 10343 | } |
| 10344 | type = type || "fx"; |
| 10345 | |
| 10346 | while ( i-- ) { |
| 10347 | tmp = data_priv.get( elements[ i ], type + "queueHooks" ); |
| 10348 | if ( tmp && tmp.empty ) { |
| 10349 | count++; |
| 10350 | tmp.empty.add( resolve ); |
| 10351 | } |
| 10352 | } |
| 10353 | resolve(); |
| 10354 | return defer.promise( obj ); |
| 10355 | } |
| 10356 | }); |
| 10357 | var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source; |
| 10358 | |
| 10359 | var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; |
| 10360 | |
| 10361 | var isHidden = function( elem, el ) { |
| 10362 | // isHidden might be called from jQuery#filter function; |
| 10363 | // in that case, element will be second argument |
| 10364 | elem = el || elem; |
| 10365 | return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); |
| 10366 | }; |
| 10367 | |
| 10368 | var rcheckableType = (/^(?:checkbox|radio)$/i); |
| 10369 | |
| 10370 | |
| 10371 | |
| 10372 | (function() { |
| 10373 | var fragment = document.createDocumentFragment(), |
| 10374 | div = fragment.appendChild( document.createElement( "div" ) ), |
| 10375 | input = document.createElement( "input" ); |
| 10376 | |
| 10377 | // Support: Safari<=5.1 |
| 10378 | // Check state lost if the name is set (#11217) |
| 10379 | // Support: Windows Web Apps (WWA) |
| 10380 | // `name` and `type` must use .setAttribute for WWA (#14901) |
| 10381 | input.setAttribute( "type", "radio" ); |
| 10382 | input.setAttribute( "checked", "checked" ); |
| 10383 | input.setAttribute( "name", "t" ); |
| 10384 | |
| 10385 | div.appendChild( input ); |
| 10386 | |
| 10387 | // Support: Safari<=5.1, Android<4.2 |
| 10388 | // Older WebKit doesn't clone checked state correctly in fragments |
| 10389 | support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; |
| 10390 | |
| 10391 | // Support: IE<=11+ |
| 10392 | // Make sure textarea (and checkbox) defaultValue is properly cloned |
| 10393 | div.innerHTML = "<textarea>x</textarea>"; |
| 10394 | support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; |
| 10395 | })(); |
| 10396 | var strundefined = typeof undefined; |
| 10397 | |
| 10398 | |
| 10399 | |
| 10400 | support.focusinBubbles = "onfocusin" in window; |
| 10401 | |
| 10402 | |
| 10403 | var |
| 10404 | rkeyEvent = /^key/, |
| 10405 | rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/, |
| 10406 | rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, |
| 10407 | rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; |
| 10408 | |
| 10409 | function returnTrue() { |
| 10410 | return true; |
| 10411 | } |
| 10412 | |
| 10413 | function returnFalse() { |
| 10414 | return false; |
| 10415 | } |
| 10416 | |
| 10417 | function safeActiveElement() { |
| 10418 | try { |
| 10419 | return document.activeElement; |
| 10420 | } catch ( err ) { } |
| 10421 | } |
| 10422 | |
| 10423 | /* |
| 10424 | * Helper functions for managing events -- not part of the public interface. |
| 10425 | * Props to Dean Edwards' addEvent library for many of the ideas. |
| 10426 | */ |
| 10427 | jQuery.event = { |
| 10428 | |
| 10429 | global: {}, |
| 10430 | |
| 10431 | add: function( elem, types, handler, data, selector ) { |
| 10432 | |
| 10433 | var handleObjIn, eventHandle, tmp, |
| 10434 | events, t, handleObj, |
| 10435 | special, handlers, type, namespaces, origType, |
| 10436 | elemData = data_priv.get( elem ); |
| 10437 | |
| 10438 | // Don't attach events to noData or text/comment nodes (but allow plain objects) |
| 10439 | if ( !elemData ) { |
| 10440 | return; |
| 10441 | } |
| 10442 | |
| 10443 | // Caller can pass in an object of custom data in lieu of the handler |
| 10444 | if ( handler.handler ) { |
| 10445 | handleObjIn = handler; |
| 10446 | handler = handleObjIn.handler; |
| 10447 | selector = handleObjIn.selector; |
| 10448 | } |
| 10449 | |
| 10450 | // Make sure that the handler has a unique ID, used to find/remove it later |
| 10451 | if ( !handler.guid ) { |
| 10452 | handler.guid = jQuery.guid++; |
| 10453 | } |
| 10454 | |
| 10455 | // Init the element's event structure and main handler, if this is the first |
| 10456 | if ( !(events = elemData.events) ) { |
| 10457 | events = elemData.events = {}; |
| 10458 | } |
| 10459 | if ( !(eventHandle = elemData.handle) ) { |
| 10460 | eventHandle = elemData.handle = function( e ) { |
| 10461 | // Discard the second event of a jQuery.event.trigger() and |
| 10462 | // when an event is called after a page has unloaded |
| 10463 | return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ? |
| 10464 | jQuery.event.dispatch.apply( elem, arguments ) : undefined; |
| 10465 | }; |
| 10466 | } |
| 10467 | |
| 10468 | // Handle multiple events separated by a space |
| 10469 | types = ( types || "" ).match( rnotwhite ) || [ "" ]; |
| 10470 | t = types.length; |
| 10471 | while ( t-- ) { |
| 10472 | tmp = rtypenamespace.exec( types[t] ) || []; |
| 10473 | type = origType = tmp[1]; |
| 10474 | namespaces = ( tmp[2] || "" ).split( "." ).sort(); |
| 10475 | |
| 10476 | // There *must* be a type, no attaching namespace-only handlers |
| 10477 | if ( !type ) { |
| 10478 | continue; |
| 10479 | } |
| 10480 | |
| 10481 | // If event changes its type, use the special event handlers for the changed type |
| 10482 | special = jQuery.event.special[ type ] || {}; |
| 10483 | |
| 10484 | // If selector defined, determine special event api type, otherwise given type |
| 10485 | type = ( selector ? special.delegateType : special.bindType ) || type; |
| 10486 | |
| 10487 | // Update special based on newly reset type |
| 10488 | special = jQuery.event.special[ type ] || {}; |
| 10489 | |
| 10490 | // handleObj is passed to all event handlers |
| 10491 | handleObj = jQuery.extend({ |
| 10492 | type: type, |
| 10493 | origType: origType, |
| 10494 | data: data, |
| 10495 | handler: handler, |
| 10496 | guid: handler.guid, |
| 10497 | selector: selector, |
| 10498 | needsContext: selector && jQuery.expr.match.needsContext.test( selector ), |
| 10499 | namespace: namespaces.join(".") |
| 10500 | }, handleObjIn ); |
| 10501 | |
| 10502 | // Init the event handler queue if we're the first |
| 10503 | if ( !(handlers = events[ type ]) ) { |
| 10504 | handlers = events[ type ] = []; |
| 10505 | handlers.delegateCount = 0; |
| 10506 | |
| 10507 | // Only use addEventListener if the special events handler returns false |
| 10508 | if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { |
| 10509 | if ( elem.addEventListener ) { |
| 10510 | elem.addEventListener( type, eventHandle, false ); |
| 10511 | } |
| 10512 | } |
| 10513 | } |
| 10514 | |
| 10515 | if ( special.add ) { |
| 10516 | special.add.call( elem, handleObj ); |
| 10517 | |
| 10518 | if ( !handleObj.handler.guid ) { |
| 10519 | handleObj.handler.guid = handler.guid; |
| 10520 | } |
| 10521 | } |
| 10522 | |
| 10523 | // Add to the element's handler list, delegates in front |
| 10524 | if ( selector ) { |
| 10525 | handlers.splice( handlers.delegateCount++, 0, handleObj ); |
| 10526 | } else { |
| 10527 | handlers.push( handleObj ); |
| 10528 | } |
| 10529 | |
| 10530 | // Keep track of which events have ever been used, for event optimization |
| 10531 | jQuery.event.global[ type ] = true; |
| 10532 | } |
| 10533 | |
| 10534 | }, |
| 10535 | |
| 10536 | // Detach an event or set of events from an element |
| 10537 | remove: function( elem, types, handler, selector, mappedTypes ) { |
| 10538 | |
| 10539 | var j, origCount, tmp, |
| 10540 | events, t, handleObj, |
| 10541 | special, handlers, type, namespaces, origType, |
| 10542 | elemData = data_priv.hasData( elem ) && data_priv.get( elem ); |
| 10543 | |
| 10544 | if ( !elemData || !(events = elemData.events) ) { |
| 10545 | return; |
| 10546 | } |
| 10547 | |
| 10548 | // Once for each type.namespace in types; type may be omitted |
| 10549 | types = ( types || "" ).match( rnotwhite ) || [ "" ]; |
| 10550 | t = types.length; |
| 10551 | while ( t-- ) { |
| 10552 | tmp = rtypenamespace.exec( types[t] ) || []; |
| 10553 | type = origType = tmp[1]; |
| 10554 | namespaces = ( tmp[2] || "" ).split( "." ).sort(); |
| 10555 | |
| 10556 | // Unbind all events (on this namespace, if provided) for the element |
| 10557 | if ( !type ) { |
| 10558 | for ( type in events ) { |
| 10559 | jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); |
| 10560 | } |
| 10561 | continue; |
| 10562 | } |
| 10563 | |
| 10564 | special = jQuery.event.special[ type ] || {}; |
| 10565 | type = ( selector ? special.delegateType : special.bindType ) || type; |
| 10566 | handlers = events[ type ] || []; |
| 10567 | tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); |
| 10568 | |
| 10569 | // Remove matching events |
| 10570 | origCount = j = handlers.length; |
| 10571 | while ( j-- ) { |
| 10572 | handleObj = handlers[ j ]; |
| 10573 | |
| 10574 | if ( ( mappedTypes || origType === handleObj.origType ) && |
| 10575 | ( !handler || handler.guid === handleObj.guid ) && |
| 10576 | ( !tmp || tmp.test( handleObj.namespace ) ) && |
| 10577 | ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { |
| 10578 | handlers.splice( j, 1 ); |
| 10579 | |
| 10580 | if ( handleObj.selector ) { |
| 10581 | handlers.delegateCount--; |
| 10582 | } |
| 10583 | if ( special.remove ) { |
| 10584 | special.remove.call( elem, handleObj ); |
| 10585 | } |
| 10586 | } |
| 10587 | } |
| 10588 | |
| 10589 | // Remove generic event handler if we removed something and no more handlers exist |
| 10590 | // (avoids potential for endless recursion during removal of special event handlers) |
| 10591 | if ( origCount && !handlers.length ) { |
| 10592 | if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { |
| 10593 | jQuery.removeEvent( elem, type, elemData.handle ); |
| 10594 | } |
| 10595 | |
| 10596 | delete events[ type ]; |
| 10597 | } |
| 10598 | } |
| 10599 | |
| 10600 | // Remove the expando if it's no longer used |
| 10601 | if ( jQuery.isEmptyObject( events ) ) { |
| 10602 | delete elemData.handle; |
| 10603 | data_priv.remove( elem, "events" ); |
| 10604 | } |
| 10605 | }, |
| 10606 | |
| 10607 | trigger: function( event, data, elem, onlyHandlers ) { |
| 10608 | |
| 10609 | var i, cur, tmp, bubbleType, ontype, handle, special, |
| 10610 | eventPath = [ elem || document ], |
| 10611 | type = hasOwn.call( event, "type" ) ? event.type : event, |
| 10612 | namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; |
| 10613 | |
| 10614 | cur = tmp = elem = elem || document; |
| 10615 | |
| 10616 | // Don't do events on text and comment nodes |
| 10617 | if ( elem.nodeType === 3 || elem.nodeType === 8 ) { |
| 10618 | return; |
| 10619 | } |
| 10620 | |
| 10621 | // focus/blur morphs to focusin/out; ensure we're not firing them right now |
| 10622 | if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { |
| 10623 | return; |
| 10624 | } |
| 10625 | |
| 10626 | if ( type.indexOf(".") >= 0 ) { |
| 10627 | // Namespaced trigger; create a regexp to match event type in handle() |
| 10628 | namespaces = type.split("."); |
| 10629 | type = namespaces.shift(); |
| 10630 | namespaces.sort(); |
| 10631 | } |
| 10632 | ontype = type.indexOf(":") < 0 && "on" + type; |
| 10633 | |
| 10634 | // Caller can pass in a jQuery.Event object, Object, or just an event type string |
| 10635 | event = event[ jQuery.expando ] ? |
| 10636 | event : |
| 10637 | new jQuery.Event( type, typeof event === "object" && event ); |
| 10638 | |
| 10639 | // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) |
| 10640 | event.isTrigger = onlyHandlers ? 2 : 3; |
| 10641 | event.namespace = namespaces.join("."); |
| 10642 | event.namespace_re = event.namespace ? |
| 10643 | new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : |
| 10644 | null; |
| 10645 | |
| 10646 | // Clean up the event in case it is being reused |
| 10647 | event.result = undefined; |
| 10648 | if ( !event.target ) { |
| 10649 | event.target = elem; |
| 10650 | } |
| 10651 | |
| 10652 | // Clone any incoming data and prepend the event, creating the handler arg list |
| 10653 | data = data == null ? |
| 10654 | [ event ] : |
| 10655 | jQuery.makeArray( data, [ event ] ); |
| 10656 | |
| 10657 | // Allow special events to draw outside the lines |
| 10658 | special = jQuery.event.special[ type ] || {}; |
| 10659 | if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { |
| 10660 | return; |
| 10661 | } |
| 10662 | |
| 10663 | // Determine event propagation path in advance, per W3C events spec (#9951) |
| 10664 | // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) |
| 10665 | if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { |
| 10666 | |
| 10667 | bubbleType = special.delegateType || type; |
| 10668 | if ( !rfocusMorph.test( bubbleType + type ) ) { |
| 10669 | cur = cur.parentNode; |
| 10670 | } |
| 10671 | for ( ; cur; cur = cur.parentNode ) { |
| 10672 | eventPath.push( cur ); |
| 10673 | tmp = cur; |
| 10674 | } |
| 10675 | |
| 10676 | // Only add window if we got to document (e.g., not plain obj or detached DOM) |
| 10677 | if ( tmp === (elem.ownerDocument || document) ) { |
| 10678 | eventPath.push( tmp.defaultView || tmp.parentWindow || window ); |
| 10679 | } |
| 10680 | } |
| 10681 | |
| 10682 | // Fire handlers on the event path |
| 10683 | i = 0; |
| 10684 | while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { |
| 10685 | |
| 10686 | event.type = i > 1 ? |
| 10687 | bubbleType : |
| 10688 | special.bindType || type; |
| 10689 | |
| 10690 | // jQuery handler |
| 10691 | handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" ); |
| 10692 | if ( handle ) { |
| 10693 | handle.apply( cur, data ); |
| 10694 | } |
| 10695 | |
| 10696 | // Native handler |
| 10697 | handle = ontype && cur[ ontype ]; |
| 10698 | if ( handle && handle.apply && jQuery.acceptData( cur ) ) { |
| 10699 | event.result = handle.apply( cur, data ); |
| 10700 | if ( event.result === false ) { |
| 10701 | event.preventDefault(); |
| 10702 | } |
| 10703 | } |
| 10704 | } |
| 10705 | event.type = type; |
| 10706 | |
| 10707 | // If nobody prevented the default action, do it now |
| 10708 | if ( !onlyHandlers && !event.isDefaultPrevented() ) { |
| 10709 | |
| 10710 | if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && |
| 10711 | jQuery.acceptData( elem ) ) { |
| 10712 | |
| 10713 | // Call a native DOM method on the target with the same name name as the event. |
| 10714 | // Don't do default actions on window, that's where global variables be (#6170) |
| 10715 | if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) { |
| 10716 | |
| 10717 | // Don't re-trigger an onFOO event when we call its FOO() method |
| 10718 | tmp = elem[ ontype ]; |
| 10719 | |
| 10720 | if ( tmp ) { |
| 10721 | elem[ ontype ] = null; |
| 10722 | } |
| 10723 | |
| 10724 | // Prevent re-triggering of the same event, since we already bubbled it above |
| 10725 | jQuery.event.triggered = type; |
| 10726 | elem[ type ](); |
| 10727 | jQuery.event.triggered = undefined; |
| 10728 | |
| 10729 | if ( tmp ) { |
| 10730 | elem[ ontype ] = tmp; |
| 10731 | } |
| 10732 | } |
| 10733 | } |
| 10734 | } |
| 10735 | |
| 10736 | return event.result; |
| 10737 | }, |
| 10738 | |
| 10739 | dispatch: function( event ) { |
| 10740 | |
| 10741 | // Make a writable jQuery.Event from the native event object |
| 10742 | event = jQuery.event.fix( event ); |
| 10743 | |
| 10744 | var i, j, ret, matched, handleObj, |
| 10745 | handlerQueue = [], |
| 10746 | args = slice.call( arguments ), |
| 10747 | handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [], |
| 10748 | special = jQuery.event.special[ event.type ] || {}; |
| 10749 | |
| 10750 | // Use the fix-ed jQuery.Event rather than the (read-only) native event |
| 10751 | args[0] = event; |
| 10752 | event.delegateTarget = this; |
| 10753 | |
| 10754 | // Call the preDispatch hook for the mapped type, and let it bail if desired |
| 10755 | if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { |
| 10756 | return; |
| 10757 | } |
| 10758 | |
| 10759 | // Determine handlers |
| 10760 | handlerQueue = jQuery.event.handlers.call( this, event, handlers ); |
| 10761 | |
| 10762 | // Run delegates first; they may want to stop propagation beneath us |
| 10763 | i = 0; |
| 10764 | while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { |
| 10765 | event.currentTarget = matched.elem; |
| 10766 | |
| 10767 | j = 0; |
| 10768 | while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { |
| 10769 | |
| 10770 | // Triggered event must either 1) have no namespace, or 2) have namespace(s) |
| 10771 | // a subset or equal to those in the bound event (both can have no namespace). |
| 10772 | if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { |
| 10773 | |
| 10774 | event.handleObj = handleObj; |
| 10775 | event.data = handleObj.data; |
| 10776 | |
| 10777 | ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) |
| 10778 | .apply( matched.elem, args ); |
| 10779 | |
| 10780 | if ( ret !== undefined ) { |
| 10781 | if ( (event.result = ret) === false ) { |
| 10782 | event.preventDefault(); |
| 10783 | event.stopPropagation(); |
| 10784 | } |
| 10785 | } |
| 10786 | } |
| 10787 | } |
| 10788 | } |
| 10789 | |
| 10790 | // Call the postDispatch hook for the mapped type |
| 10791 | if ( special.postDispatch ) { |
| 10792 | special.postDispatch.call( this, event ); |
| 10793 | } |
| 10794 | |
| 10795 | return event.result; |
| 10796 | }, |
| 10797 | |
| 10798 | handlers: function( event, handlers ) { |
| 10799 | var i, matches, sel, handleObj, |
| 10800 | handlerQueue = [], |
| 10801 | delegateCount = handlers.delegateCount, |
| 10802 | cur = event.target; |
| 10803 | |
| 10804 | // Find delegate handlers |
| 10805 | // Black-hole SVG <use> instance trees (#13180) |
| 10806 | // Avoid non-left-click bubbling in Firefox (#3861) |
| 10807 | if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { |
| 10808 | |
| 10809 | for ( ; cur !== this; cur = cur.parentNode || this ) { |
| 10810 | |
| 10811 | // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) |
| 10812 | if ( cur.disabled !== true || event.type !== "click" ) { |
| 10813 | matches = []; |
| 10814 | for ( i = 0; i < delegateCount; i++ ) { |
| 10815 | handleObj = handlers[ i ]; |
| 10816 | |
| 10817 | // Don't conflict with Object.prototype properties (#13203) |
| 10818 | sel = handleObj.selector + " "; |
| 10819 | |
| 10820 | if ( matches[ sel ] === undefined ) { |
| 10821 | matches[ sel ] = handleObj.needsContext ? |
| 10822 | jQuery( sel, this ).index( cur ) >= 0 : |
| 10823 | jQuery.find( sel, this, null, [ cur ] ).length; |
| 10824 | } |
| 10825 | if ( matches[ sel ] ) { |
| 10826 | matches.push( handleObj ); |
| 10827 | } |
| 10828 | } |
| 10829 | if ( matches.length ) { |
| 10830 | handlerQueue.push({ elem: cur, handlers: matches }); |
| 10831 | } |
| 10832 | } |
| 10833 | } |
| 10834 | } |
| 10835 | |
| 10836 | // Add the remaining (directly-bound) handlers |
| 10837 | if ( delegateCount < handlers.length ) { |
| 10838 | handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); |
| 10839 | } |
| 10840 | |
| 10841 | return handlerQueue; |
| 10842 | }, |
| 10843 | |
| 10844 | // Includes some event props shared by KeyEvent and MouseEvent |
| 10845 | props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), |
| 10846 | |
| 10847 | fixHooks: {}, |
| 10848 | |
| 10849 | keyHooks: { |
| 10850 | props: "char charCode key keyCode".split(" "), |
| 10851 | filter: function( event, original ) { |
| 10852 | |
| 10853 | // Add which for key events |
| 10854 | if ( event.which == null ) { |
| 10855 | event.which = original.charCode != null ? original.charCode : original.keyCode; |
| 10856 | } |
| 10857 | |
| 10858 | return event; |
| 10859 | } |
| 10860 | }, |
| 10861 | |
| 10862 | mouseHooks: { |
| 10863 | props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "), |
| 10864 | filter: function( event, original ) { |
| 10865 | var eventDoc, doc, body, |
| 10866 | button = original.button; |
| 10867 | |
| 10868 | // Calculate pageX/Y if missing and clientX/Y available |
| 10869 | if ( event.pageX == null && original.clientX != null ) { |
| 10870 | eventDoc = event.target.ownerDocument || document; |
| 10871 | doc = eventDoc.documentElement; |
| 10872 | body = eventDoc.body; |
| 10873 | |
| 10874 | event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); |
| 10875 | event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); |
| 10876 | } |
| 10877 | |
| 10878 | // Add which for click: 1 === left; 2 === middle; 3 === right |
| 10879 | // Note: button is not normalized, so don't use it |
| 10880 | if ( !event.which && button !== undefined ) { |
| 10881 | event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); |
| 10882 | } |
| 10883 | |
| 10884 | return event; |
| 10885 | } |
| 10886 | }, |
| 10887 | |
| 10888 | fix: function( event ) { |
| 10889 | if ( event[ jQuery.expando ] ) { |
| 10890 | return event; |
| 10891 | } |
| 10892 | |
| 10893 | // Create a writable copy of the event object and normalize some properties |
| 10894 | var i, prop, copy, |
| 10895 | type = event.type, |
| 10896 | originalEvent = event, |
| 10897 | fixHook = this.fixHooks[ type ]; |
| 10898 | |
| 10899 | if ( !fixHook ) { |
| 10900 | this.fixHooks[ type ] = fixHook = |
| 10901 | rmouseEvent.test( type ) ? this.mouseHooks : |
| 10902 | rkeyEvent.test( type ) ? this.keyHooks : |
| 10903 | {}; |
| 10904 | } |
| 10905 | copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; |
| 10906 | |
| 10907 | event = new jQuery.Event( originalEvent ); |
| 10908 | |
| 10909 | i = copy.length; |
| 10910 | while ( i-- ) { |
| 10911 | prop = copy[ i ]; |
| 10912 | event[ prop ] = originalEvent[ prop ]; |
| 10913 | } |
| 10914 | |
| 10915 | // Support: Cordova 2.5 (WebKit) (#13255) |
| 10916 | // All events should have a target; Cordova deviceready doesn't |
| 10917 | if ( !event.target ) { |
| 10918 | event.target = document; |
| 10919 | } |
| 10920 | |
| 10921 | // Support: Safari 6.0+, Chrome<28 |
| 10922 | // Target should not be a text node (#504, #13143) |
| 10923 | if ( event.target.nodeType === 3 ) { |
| 10924 | event.target = event.target.parentNode; |
| 10925 | } |
| 10926 | |
| 10927 | return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; |
| 10928 | }, |
| 10929 | |
| 10930 | special: { |
| 10931 | load: { |
| 10932 | // Prevent triggered image.load events from bubbling to window.load |
| 10933 | noBubble: true |
| 10934 | }, |
| 10935 | focus: { |
| 10936 | // Fire native event if possible so blur/focus sequence is correct |
| 10937 | trigger: function() { |
| 10938 | if ( this !== safeActiveElement() && this.focus ) { |
| 10939 | this.focus(); |
| 10940 | return false; |
| 10941 | } |
| 10942 | }, |
| 10943 | delegateType: "focusin" |
| 10944 | }, |
| 10945 | blur: { |
| 10946 | trigger: function() { |
| 10947 | if ( this === safeActiveElement() && this.blur ) { |
| 10948 | this.blur(); |
| 10949 | return false; |
| 10950 | } |
| 10951 | }, |
| 10952 | delegateType: "focusout" |
| 10953 | }, |
| 10954 | click: { |
| 10955 | // For checkbox, fire native event so checked state will be right |
| 10956 | trigger: function() { |
| 10957 | if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) { |
| 10958 | this.click(); |
| 10959 | return false; |
| 10960 | } |
| 10961 | }, |
| 10962 | |
| 10963 | // For cross-browser consistency, don't fire native .click() on links |
| 10964 | _default: function( event ) { |
| 10965 | return jQuery.nodeName( event.target, "a" ); |
| 10966 | } |
| 10967 | }, |
| 10968 | |
| 10969 | beforeunload: { |
| 10970 | postDispatch: function( event ) { |
| 10971 | |
| 10972 | // Support: Firefox 20+ |
| 10973 | // Firefox doesn't alert if the returnValue field is not set. |
| 10974 | if ( event.result !== undefined && event.originalEvent ) { |
| 10975 | event.originalEvent.returnValue = event.result; |
| 10976 | } |
| 10977 | } |
| 10978 | } |
| 10979 | }, |
| 10980 | |
| 10981 | simulate: function( type, elem, event, bubble ) { |
| 10982 | // Piggyback on a donor event to simulate a different one. |
| 10983 | // Fake originalEvent to avoid donor's stopPropagation, but if the |
| 10984 | // simulated event prevents default then we do the same on the donor. |
| 10985 | var e = jQuery.extend( |
| 10986 | new jQuery.Event(), |
| 10987 | event, |
| 10988 | { |
| 10989 | type: type, |
| 10990 | isSimulated: true, |
| 10991 | originalEvent: {} |
| 10992 | } |
| 10993 | ); |
| 10994 | if ( bubble ) { |
| 10995 | jQuery.event.trigger( e, null, elem ); |
| 10996 | } else { |
| 10997 | jQuery.event.dispatch.call( elem, e ); |
| 10998 | } |
| 10999 | if ( e.isDefaultPrevented() ) { |
| 11000 | event.preventDefault(); |
| 11001 | } |
| 11002 | } |
| 11003 | }; |
| 11004 | |
| 11005 | jQuery.removeEvent = function( elem, type, handle ) { |
| 11006 | if ( elem.removeEventListener ) { |
| 11007 | elem.removeEventListener( type, handle, false ); |
| 11008 | } |
| 11009 | }; |
| 11010 | |
| 11011 | jQuery.Event = function( src, props ) { |
| 11012 | // Allow instantiation without the 'new' keyword |
| 11013 | if ( !(this instanceof jQuery.Event) ) { |
| 11014 | return new jQuery.Event( src, props ); |
| 11015 | } |
| 11016 | |
| 11017 | // Event object |
| 11018 | if ( src && src.type ) { |
| 11019 | this.originalEvent = src; |
| 11020 | this.type = src.type; |
| 11021 | |
| 11022 | // Events bubbling up the document may have been marked as prevented |
| 11023 | // by a handler lower down the tree; reflect the correct value. |
| 11024 | this.isDefaultPrevented = src.defaultPrevented || |
| 11025 | src.defaultPrevented === undefined && |
| 11026 | // Support: Android<4.0 |
| 11027 | src.returnValue === false ? |
| 11028 | returnTrue : |
| 11029 | returnFalse; |
| 11030 | |
| 11031 | // Event type |
| 11032 | } else { |
| 11033 | this.type = src; |
| 11034 | } |
| 11035 | |
| 11036 | // Put explicitly provided properties onto the event object |
| 11037 | if ( props ) { |
| 11038 | jQuery.extend( this, props ); |
| 11039 | } |
| 11040 | |
| 11041 | // Create a timestamp if incoming event doesn't have one |
| 11042 | this.timeStamp = src && src.timeStamp || jQuery.now(); |
| 11043 | |
| 11044 | // Mark it as fixed |
| 11045 | this[ jQuery.expando ] = true; |
| 11046 | }; |
| 11047 | |
| 11048 | // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding |
| 11049 | // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html |
| 11050 | jQuery.Event.prototype = { |
| 11051 | isDefaultPrevented: returnFalse, |
| 11052 | isPropagationStopped: returnFalse, |
| 11053 | isImmediatePropagationStopped: returnFalse, |
| 11054 | |
| 11055 | preventDefault: function() { |
| 11056 | var e = this.originalEvent; |
| 11057 | |
| 11058 | this.isDefaultPrevented = returnTrue; |
| 11059 | |
| 11060 | if ( e && e.preventDefault ) { |
| 11061 | e.preventDefault(); |
| 11062 | } |
| 11063 | }, |
| 11064 | stopPropagation: function() { |
| 11065 | var e = this.originalEvent; |
| 11066 | |
| 11067 | this.isPropagationStopped = returnTrue; |
| 11068 | |
| 11069 | if ( e && e.stopPropagation ) { |
| 11070 | e.stopPropagation(); |
| 11071 | } |
| 11072 | }, |
| 11073 | stopImmediatePropagation: function() { |
| 11074 | var e = this.originalEvent; |
| 11075 | |
| 11076 | this.isImmediatePropagationStopped = returnTrue; |
| 11077 | |
| 11078 | if ( e && e.stopImmediatePropagation ) { |
| 11079 | e.stopImmediatePropagation(); |
| 11080 | } |
| 11081 | |
| 11082 | this.stopPropagation(); |
| 11083 | } |
| 11084 | }; |
| 11085 | |
| 11086 | // Create mouseenter/leave events using mouseover/out and event-time checks |
| 11087 | // Support: Chrome 15+ |
| 11088 | jQuery.each({ |
| 11089 | mouseenter: "mouseover", |
| 11090 | mouseleave: "mouseout", |
| 11091 | pointerenter: "pointerover", |
| 11092 | pointerleave: "pointerout" |
| 11093 | }, function( orig, fix ) { |
| 11094 | jQuery.event.special[ orig ] = { |
| 11095 | delegateType: fix, |
| 11096 | bindType: fix, |
| 11097 | |
| 11098 | handle: function( event ) { |
| 11099 | var ret, |
| 11100 | target = this, |
| 11101 | related = event.relatedTarget, |
| 11102 | handleObj = event.handleObj; |
| 11103 | |
| 11104 | // For mousenter/leave call the handler if related is outside the target. |
| 11105 | // NB: No relatedTarget if the mouse left/entered the browser window |
| 11106 | if ( !related || (related !== target && !jQuery.contains( target, related )) ) { |
| 11107 | event.type = handleObj.origType; |
| 11108 | ret = handleObj.handler.apply( this, arguments ); |
| 11109 | event.type = fix; |
| 11110 | } |
| 11111 | return ret; |
| 11112 | } |
| 11113 | }; |
| 11114 | }); |
| 11115 | |
| 11116 | // Support: Firefox, Chrome, Safari |
| 11117 | // Create "bubbling" focus and blur events |
| 11118 | if ( !support.focusinBubbles ) { |
| 11119 | jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { |
| 11120 | |
| 11121 | // Attach a single capturing handler on the document while someone wants focusin/focusout |
| 11122 | var handler = function( event ) { |
| 11123 | jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); |
| 11124 | }; |
| 11125 | |
| 11126 | jQuery.event.special[ fix ] = { |
| 11127 | setup: function() { |
| 11128 | var doc = this.ownerDocument || this, |
| 11129 | attaches = data_priv.access( doc, fix ); |
| 11130 | |
| 11131 | if ( !attaches ) { |
| 11132 | doc.addEventListener( orig, handler, true ); |
| 11133 | } |
| 11134 | data_priv.access( doc, fix, ( attaches || 0 ) + 1 ); |
| 11135 | }, |
| 11136 | teardown: function() { |
| 11137 | var doc = this.ownerDocument || this, |
| 11138 | attaches = data_priv.access( doc, fix ) - 1; |
| 11139 | |
| 11140 | if ( !attaches ) { |
| 11141 | doc.removeEventListener( orig, handler, true ); |
| 11142 | data_priv.remove( doc, fix ); |
| 11143 | |
| 11144 | } else { |
| 11145 | data_priv.access( doc, fix, attaches ); |
| 11146 | } |
| 11147 | } |
| 11148 | }; |
| 11149 | }); |
| 11150 | } |
| 11151 | |
| 11152 | jQuery.fn.extend({ |
| 11153 | |
| 11154 | on: function( types, selector, data, fn, /*INTERNAL*/ one ) { |
| 11155 | var origFn, type; |
| 11156 | |
| 11157 | // Types can be a map of types/handlers |
| 11158 | if ( typeof types === "object" ) { |
| 11159 | // ( types-Object, selector, data ) |
| 11160 | if ( typeof selector !== "string" ) { |
| 11161 | // ( types-Object, data ) |
| 11162 | data = data || selector; |
| 11163 | selector = undefined; |
| 11164 | } |
| 11165 | for ( type in types ) { |
| 11166 | this.on( type, selector, data, types[ type ], one ); |
| 11167 | } |
| 11168 | return this; |
| 11169 | } |
| 11170 | |
| 11171 | if ( data == null && fn == null ) { |
| 11172 | // ( types, fn ) |
| 11173 | fn = selector; |
| 11174 | data = selector = undefined; |
| 11175 | } else if ( fn == null ) { |
| 11176 | if ( typeof selector === "string" ) { |
| 11177 | // ( types, selector, fn ) |
| 11178 | fn = data; |
| 11179 | data = undefined; |
| 11180 | } else { |
| 11181 | // ( types, data, fn ) |
| 11182 | fn = data; |
| 11183 | data = selector; |
| 11184 | selector = undefined; |
| 11185 | } |
| 11186 | } |
| 11187 | if ( fn === false ) { |
| 11188 | fn = returnFalse; |
| 11189 | } else if ( !fn ) { |
| 11190 | return this; |
| 11191 | } |
| 11192 | |
| 11193 | if ( one === 1 ) { |
| 11194 | origFn = fn; |
| 11195 | fn = function( event ) { |
| 11196 | // Can use an empty set, since event contains the info |
| 11197 | jQuery().off( event ); |
| 11198 | return origFn.apply( this, arguments ); |
| 11199 | }; |
| 11200 | // Use same guid so caller can remove using origFn |
| 11201 | fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); |
| 11202 | } |
| 11203 | return this.each( function() { |
| 11204 | jQuery.event.add( this, types, fn, data, selector ); |
| 11205 | }); |
| 11206 | }, |
| 11207 | one: function( types, selector, data, fn ) { |
| 11208 | return this.on( types, selector, data, fn, 1 ); |
| 11209 | }, |
| 11210 | off: function( types, selector, fn ) { |
| 11211 | var handleObj, type; |
| 11212 | if ( types && types.preventDefault && types.handleObj ) { |
| 11213 | // ( event ) dispatched jQuery.Event |
| 11214 | handleObj = types.handleObj; |
| 11215 | jQuery( types.delegateTarget ).off( |
| 11216 | handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, |
| 11217 | handleObj.selector, |
| 11218 | handleObj.handler |
| 11219 | ); |
| 11220 | return this; |
| 11221 | } |
| 11222 | if ( typeof types === "object" ) { |
| 11223 | // ( types-object [, selector] ) |
| 11224 | for ( type in types ) { |
| 11225 | this.off( type, selector, types[ type ] ); |
| 11226 | } |
| 11227 | return this; |
| 11228 | } |
| 11229 | if ( selector === false || typeof selector === "function" ) { |
| 11230 | // ( types [, fn] ) |
| 11231 | fn = selector; |
| 11232 | selector = undefined; |
| 11233 | } |
| 11234 | if ( fn === false ) { |
| 11235 | fn = returnFalse; |
| 11236 | } |
| 11237 | return this.each(function() { |
| 11238 | jQuery.event.remove( this, types, fn, selector ); |
| 11239 | }); |
| 11240 | }, |
| 11241 | |
| 11242 | trigger: function( type, data ) { |
| 11243 | return this.each(function() { |
| 11244 | jQuery.event.trigger( type, data, this ); |
| 11245 | }); |
| 11246 | }, |
| 11247 | triggerHandler: function( type, data ) { |
| 11248 | var elem = this[0]; |
| 11249 | if ( elem ) { |
| 11250 | return jQuery.event.trigger( type, data, elem, true ); |
| 11251 | } |
| 11252 | } |
| 11253 | }); |
| 11254 | |
| 11255 | |
| 11256 | var |
| 11257 | rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, |
| 11258 | rtagName = /<([\w:]+)/, |
| 11259 | rhtml = /<|&#?\w+;/, |
| 11260 | rnoInnerhtml = /<(?:script|style|link)/i, |
| 11261 | // checked="checked" or checked |
| 11262 | rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, |
| 11263 | rscriptType = /^$|\/(?:java|ecma)script/i, |
| 11264 | rscriptTypeMasked = /^true\/(.*)/, |
| 11265 | rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g, |
| 11266 | |
| 11267 | // We have to close these tags to support XHTML (#13200) |
| 11268 | wrapMap = { |
| 11269 | |
| 11270 | // Support: IE9 |
| 11271 | option: [ 1, "<select multiple='multiple'>", "</select>" ], |
| 11272 | |
| 11273 | thead: [ 1, "<table>", "</table>" ], |
| 11274 | col: [ 2, "<table><colgroup>", "</colgroup></table>" ], |
| 11275 | tr: [ 2, "<table><tbody>", "</tbody></table>" ], |
| 11276 | td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], |
| 11277 | |
| 11278 | _default: [ 0, "", "" ] |
| 11279 | }; |
| 11280 | |
| 11281 | // Support: IE9 |
| 11282 | wrapMap.optgroup = wrapMap.option; |
| 11283 | |
| 11284 | wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; |
| 11285 | wrapMap.th = wrapMap.td; |
| 11286 | |
| 11287 | // Support: 1.x compatibility |
| 11288 | // Manipulating tables requires a tbody |
| 11289 | function manipulationTarget( elem, content ) { |
| 11290 | return jQuery.nodeName( elem, "table" ) && |
| 11291 | jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? |
| 11292 | |
| 11293 | elem.getElementsByTagName("tbody")[0] || |
| 11294 | elem.appendChild( elem.ownerDocument.createElement("tbody") ) : |
| 11295 | elem; |
| 11296 | } |
| 11297 | |
| 11298 | // Replace/restore the type attribute of script elements for safe DOM manipulation |
| 11299 | function disableScript( elem ) { |
| 11300 | elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type; |
| 11301 | return elem; |
| 11302 | } |
| 11303 | function restoreScript( elem ) { |
| 11304 | var match = rscriptTypeMasked.exec( elem.type ); |
| 11305 | |
| 11306 | if ( match ) { |
| 11307 | elem.type = match[ 1 ]; |
| 11308 | } else { |
| 11309 | elem.removeAttribute("type"); |
| 11310 | } |
| 11311 | |
| 11312 | return elem; |
| 11313 | } |
| 11314 | |
| 11315 | // Mark scripts as having already been evaluated |
| 11316 | function setGlobalEval( elems, refElements ) { |
| 11317 | var i = 0, |
| 11318 | l = elems.length; |
| 11319 | |
| 11320 | for ( ; i < l; i++ ) { |
| 11321 | data_priv.set( |
| 11322 | elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" ) |
| 11323 | ); |
| 11324 | } |
| 11325 | } |
| 11326 | |
| 11327 | function cloneCopyEvent( src, dest ) { |
| 11328 | var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; |
| 11329 | |
| 11330 | if ( dest.nodeType !== 1 ) { |
| 11331 | return; |
| 11332 | } |
| 11333 | |
| 11334 | // 1. Copy private data: events, handlers, etc. |
| 11335 | if ( data_priv.hasData( src ) ) { |
| 11336 | pdataOld = data_priv.access( src ); |
| 11337 | pdataCur = data_priv.set( dest, pdataOld ); |
| 11338 | events = pdataOld.events; |
| 11339 | |
| 11340 | if ( events ) { |
| 11341 | delete pdataCur.handle; |
| 11342 | pdataCur.events = {}; |
| 11343 | |
| 11344 | for ( type in events ) { |
| 11345 | for ( i = 0, l = events[ type ].length; i < l; i++ ) { |
| 11346 | jQuery.event.add( dest, type, events[ type ][ i ] ); |
| 11347 | } |
| 11348 | } |
| 11349 | } |
| 11350 | } |
| 11351 | |
| 11352 | // 2. Copy user data |
| 11353 | if ( data_user.hasData( src ) ) { |
| 11354 | udataOld = data_user.access( src ); |
| 11355 | udataCur = jQuery.extend( {}, udataOld ); |
| 11356 | |
| 11357 | data_user.set( dest, udataCur ); |
| 11358 | } |
| 11359 | } |
| 11360 | |
| 11361 | function getAll( context, tag ) { |
| 11362 | var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) : |
| 11363 | context.querySelectorAll ? context.querySelectorAll( tag || "*" ) : |
| 11364 | []; |
| 11365 | |
| 11366 | return tag === undefined || tag && jQuery.nodeName( context, tag ) ? |
| 11367 | jQuery.merge( [ context ], ret ) : |
| 11368 | ret; |
| 11369 | } |
| 11370 | |
| 11371 | // Fix IE bugs, see support tests |
| 11372 | function fixInput( src, dest ) { |
| 11373 | var nodeName = dest.nodeName.toLowerCase(); |
| 11374 | |
| 11375 | // Fails to persist the checked state of a cloned checkbox or radio button. |
| 11376 | if ( nodeName === "input" && rcheckableType.test( src.type ) ) { |
| 11377 | dest.checked = src.checked; |
| 11378 | |
| 11379 | // Fails to return the selected option to the default selected state when cloning options |
| 11380 | } else if ( nodeName === "input" || nodeName === "textarea" ) { |
| 11381 | dest.defaultValue = src.defaultValue; |
| 11382 | } |
| 11383 | } |
| 11384 | |
| 11385 | jQuery.extend({ |
| 11386 | clone: function( elem, dataAndEvents, deepDataAndEvents ) { |
| 11387 | var i, l, srcElements, destElements, |
| 11388 | clone = elem.cloneNode( true ), |
| 11389 | inPage = jQuery.contains( elem.ownerDocument, elem ); |
| 11390 | |
| 11391 | // Fix IE cloning issues |
| 11392 | if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && |
| 11393 | !jQuery.isXMLDoc( elem ) ) { |
| 11394 | |
| 11395 | // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 |
| 11396 | destElements = getAll( clone ); |
| 11397 | srcElements = getAll( elem ); |
| 11398 | |
| 11399 | for ( i = 0, l = srcElements.length; i < l; i++ ) { |
| 11400 | fixInput( srcElements[ i ], destElements[ i ] ); |
| 11401 | } |
| 11402 | } |
| 11403 | |
| 11404 | // Copy the events from the original to the clone |
| 11405 | if ( dataAndEvents ) { |
| 11406 | if ( deepDataAndEvents ) { |
| 11407 | srcElements = srcElements || getAll( elem ); |
| 11408 | destElements = destElements || getAll( clone ); |
| 11409 | |
| 11410 | for ( i = 0, l = srcElements.length; i < l; i++ ) { |
| 11411 | cloneCopyEvent( srcElements[ i ], destElements[ i ] ); |
| 11412 | } |
| 11413 | } else { |
| 11414 | cloneCopyEvent( elem, clone ); |
| 11415 | } |
| 11416 | } |
| 11417 | |
| 11418 | // Preserve script evaluation history |
| 11419 | destElements = getAll( clone, "script" ); |
| 11420 | if ( destElements.length > 0 ) { |
| 11421 | setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); |
| 11422 | } |
| 11423 | |
| 11424 | // Return the cloned set |
| 11425 | return clone; |
| 11426 | }, |
| 11427 | |
| 11428 | buildFragment: function( elems, context, scripts, selection ) { |
| 11429 | var elem, tmp, tag, wrap, contains, j, |
| 11430 | fragment = context.createDocumentFragment(), |
| 11431 | nodes = [], |
| 11432 | i = 0, |
| 11433 | l = elems.length; |
| 11434 | |
| 11435 | for ( ; i < l; i++ ) { |
| 11436 | elem = elems[ i ]; |
| 11437 | |
| 11438 | if ( elem || elem === 0 ) { |
| 11439 | |
| 11440 | // Add nodes directly |
| 11441 | if ( jQuery.type( elem ) === "object" ) { |
| 11442 | // Support: QtWebKit, PhantomJS |
| 11443 | // push.apply(_, arraylike) throws on ancient WebKit |
| 11444 | jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); |
| 11445 | |
| 11446 | // Convert non-html into a text node |
| 11447 | } else if ( !rhtml.test( elem ) ) { |
| 11448 | nodes.push( context.createTextNode( elem ) ); |
| 11449 | |
| 11450 | // Convert html into DOM nodes |
| 11451 | } else { |
| 11452 | tmp = tmp || fragment.appendChild( context.createElement("div") ); |
| 11453 | |
| 11454 | // Deserialize a standard representation |
| 11455 | tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); |
| 11456 | wrap = wrapMap[ tag ] || wrapMap._default; |
| 11457 | tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[ 2 ]; |
| 11458 | |
| 11459 | // Descend through wrappers to the right content |
| 11460 | j = wrap[ 0 ]; |
| 11461 | while ( j-- ) { |
| 11462 | tmp = tmp.lastChild; |
| 11463 | } |
| 11464 | |
| 11465 | // Support: QtWebKit, PhantomJS |
| 11466 | // push.apply(_, arraylike) throws on ancient WebKit |
| 11467 | jQuery.merge( nodes, tmp.childNodes ); |
| 11468 | |
| 11469 | // Remember the top-level container |
| 11470 | tmp = fragment.firstChild; |
| 11471 | |
| 11472 | // Ensure the created nodes are orphaned (#12392) |
| 11473 | tmp.textContent = ""; |
| 11474 | } |
| 11475 | } |
| 11476 | } |
| 11477 | |
| 11478 | // Remove wrapper from fragment |
| 11479 | fragment.textContent = ""; |
| 11480 | |
| 11481 | i = 0; |
| 11482 | while ( (elem = nodes[ i++ ]) ) { |
| 11483 | |
| 11484 | // #4087 - If origin and destination elements are the same, and this is |
| 11485 | // that element, do not do anything |
| 11486 | if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { |
| 11487 | continue; |
| 11488 | } |
| 11489 | |
| 11490 | contains = jQuery.contains( elem.ownerDocument, elem ); |
| 11491 | |
| 11492 | // Append to fragment |
| 11493 | tmp = getAll( fragment.appendChild( elem ), "script" ); |
| 11494 | |
| 11495 | // Preserve script evaluation history |
| 11496 | if ( contains ) { |
| 11497 | setGlobalEval( tmp ); |
| 11498 | } |
| 11499 | |
| 11500 | // Capture executables |
| 11501 | if ( scripts ) { |
| 11502 | j = 0; |
| 11503 | while ( (elem = tmp[ j++ ]) ) { |
| 11504 | if ( rscriptType.test( elem.type || "" ) ) { |
| 11505 | scripts.push( elem ); |
| 11506 | } |
| 11507 | } |
| 11508 | } |
| 11509 | } |
| 11510 | |
| 11511 | return fragment; |
| 11512 | }, |
| 11513 | |
| 11514 | cleanData: function( elems ) { |
| 11515 | var data, elem, type, key, |
| 11516 | special = jQuery.event.special, |
| 11517 | i = 0; |
| 11518 | |
| 11519 | for ( ; (elem = elems[ i ]) !== undefined; i++ ) { |
| 11520 | if ( jQuery.acceptData( elem ) ) { |
| 11521 | key = elem[ data_priv.expando ]; |
| 11522 | |
| 11523 | if ( key && (data = data_priv.cache[ key ]) ) { |
| 11524 | if ( data.events ) { |
| 11525 | for ( type in data.events ) { |
| 11526 | if ( special[ type ] ) { |
| 11527 | jQuery.event.remove( elem, type ); |
| 11528 | |
| 11529 | // This is a shortcut to avoid jQuery.event.remove's overhead |
| 11530 | } else { |
| 11531 | jQuery.removeEvent( elem, type, data.handle ); |
| 11532 | } |
| 11533 | } |
| 11534 | } |
| 11535 | if ( data_priv.cache[ key ] ) { |
| 11536 | // Discard any remaining `private` data |
| 11537 | delete data_priv.cache[ key ]; |
| 11538 | } |
| 11539 | } |
| 11540 | } |
| 11541 | // Discard any remaining `user` data |
| 11542 | delete data_user.cache[ elem[ data_user.expando ] ]; |
| 11543 | } |
| 11544 | } |
| 11545 | }); |
| 11546 | |
| 11547 | jQuery.fn.extend({ |
| 11548 | text: function( value ) { |
| 11549 | return access( this, function( value ) { |
| 11550 | return value === undefined ? |
| 11551 | jQuery.text( this ) : |
| 11552 | this.empty().each(function() { |
| 11553 | if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { |
| 11554 | this.textContent = value; |
| 11555 | } |
| 11556 | }); |
| 11557 | }, null, value, arguments.length ); |
| 11558 | }, |
| 11559 | |
| 11560 | append: function() { |
| 11561 | return this.domManip( arguments, function( elem ) { |
| 11562 | if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { |
| 11563 | var target = manipulationTarget( this, elem ); |
| 11564 | target.appendChild( elem ); |
| 11565 | } |
| 11566 | }); |
| 11567 | }, |
| 11568 | |
| 11569 | prepend: function() { |
| 11570 | return this.domManip( arguments, function( elem ) { |
| 11571 | if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { |
| 11572 | var target = manipulationTarget( this, elem ); |
| 11573 | target.insertBefore( elem, target.firstChild ); |
| 11574 | } |
| 11575 | }); |
| 11576 | }, |
| 11577 | |
| 11578 | before: function() { |
| 11579 | return this.domManip( arguments, function( elem ) { |
| 11580 | if ( this.parentNode ) { |
| 11581 | this.parentNode.insertBefore( elem, this ); |
| 11582 | } |
| 11583 | }); |
| 11584 | }, |
| 11585 | |
| 11586 | after: function() { |
| 11587 | return this.domManip( arguments, function( elem ) { |
| 11588 | if ( this.parentNode ) { |
| 11589 | this.parentNode.insertBefore( elem, this.nextSibling ); |
| 11590 | } |
| 11591 | }); |
| 11592 | }, |
| 11593 | |
| 11594 | remove: function( selector, keepData /* Internal Use Only */ ) { |
| 11595 | var elem, |
| 11596 | elems = selector ? jQuery.filter( selector, this ) : this, |
| 11597 | i = 0; |
| 11598 | |
| 11599 | for ( ; (elem = elems[i]) != null; i++ ) { |
| 11600 | if ( !keepData && elem.nodeType === 1 ) { |
| 11601 | jQuery.cleanData( getAll( elem ) ); |
| 11602 | } |
| 11603 | |
| 11604 | if ( elem.parentNode ) { |
| 11605 | if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { |
| 11606 | setGlobalEval( getAll( elem, "script" ) ); |
| 11607 | } |
| 11608 | elem.parentNode.removeChild( elem ); |
| 11609 | } |
| 11610 | } |
| 11611 | |
| 11612 | return this; |
| 11613 | }, |
| 11614 | |
| 11615 | empty: function() { |
| 11616 | var elem, |
| 11617 | i = 0; |
| 11618 | |
| 11619 | for ( ; (elem = this[i]) != null; i++ ) { |
| 11620 | if ( elem.nodeType === 1 ) { |
| 11621 | |
| 11622 | // Prevent memory leaks |
| 11623 | jQuery.cleanData( getAll( elem, false ) ); |
| 11624 | |
| 11625 | // Remove any remaining nodes |
| 11626 | elem.textContent = ""; |
| 11627 | } |
| 11628 | } |
| 11629 | |
| 11630 | return this; |
| 11631 | }, |
| 11632 | |
| 11633 | clone: function( dataAndEvents, deepDataAndEvents ) { |
| 11634 | dataAndEvents = dataAndEvents == null ? false : dataAndEvents; |
| 11635 | deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; |
| 11636 | |
| 11637 | return this.map(function() { |
| 11638 | return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); |
| 11639 | }); |
| 11640 | }, |
| 11641 | |
| 11642 | html: function( value ) { |
| 11643 | return access( this, function( value ) { |
| 11644 | var elem = this[ 0 ] || {}, |
| 11645 | i = 0, |
| 11646 | l = this.length; |
| 11647 | |
| 11648 | if ( value === undefined && elem.nodeType === 1 ) { |
| 11649 | return elem.innerHTML; |
| 11650 | } |
| 11651 | |
| 11652 | // See if we can take a shortcut and just use innerHTML |
| 11653 | if ( typeof value === "string" && !rnoInnerhtml.test( value ) && |
| 11654 | !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { |
| 11655 | |
| 11656 | value = value.replace( rxhtmlTag, "<$1></$2>" ); |
| 11657 | |
| 11658 | try { |
| 11659 | for ( ; i < l; i++ ) { |
| 11660 | elem = this[ i ] || {}; |
| 11661 | |
| 11662 | // Remove element nodes and prevent memory leaks |
| 11663 | if ( elem.nodeType === 1 ) { |
| 11664 | jQuery.cleanData( getAll( elem, false ) ); |
| 11665 | elem.innerHTML = value; |
| 11666 | } |
| 11667 | } |
| 11668 | |
| 11669 | elem = 0; |
| 11670 | |
| 11671 | // If using innerHTML throws an exception, use the fallback method |
| 11672 | } catch( e ) {} |
| 11673 | } |
| 11674 | |
| 11675 | if ( elem ) { |
| 11676 | this.empty().append( value ); |
| 11677 | } |
| 11678 | }, null, value, arguments.length ); |
| 11679 | }, |
| 11680 | |
| 11681 | replaceWith: function() { |
| 11682 | var arg = arguments[ 0 ]; |
| 11683 | |
| 11684 | // Make the changes, replacing each context element with the new content |
| 11685 | this.domManip( arguments, function( elem ) { |
| 11686 | arg = this.parentNode; |
| 11687 | |
| 11688 | jQuery.cleanData( getAll( this ) ); |
| 11689 | |
| 11690 | if ( arg ) { |
| 11691 | arg.replaceChild( elem, this ); |
| 11692 | } |
| 11693 | }); |
| 11694 | |
| 11695 | // Force removal if there was no new content (e.g., from empty arguments) |
| 11696 | return arg && (arg.length || arg.nodeType) ? this : this.remove(); |
| 11697 | }, |
| 11698 | |
| 11699 | detach: function( selector ) { |
| 11700 | return this.remove( selector, true ); |
| 11701 | }, |
| 11702 | |
| 11703 | domManip: function( args, callback ) { |
| 11704 | |
| 11705 | // Flatten any nested arrays |
| 11706 | args = concat.apply( [], args ); |
| 11707 | |
| 11708 | var fragment, first, scripts, hasScripts, node, doc, |
| 11709 | i = 0, |
| 11710 | l = this.length, |
| 11711 | set = this, |
| 11712 | iNoClone = l - 1, |
| 11713 | value = args[ 0 ], |
| 11714 | isFunction = jQuery.isFunction( value ); |
| 11715 | |
| 11716 | // We can't cloneNode fragments that contain checked, in WebKit |
| 11717 | if ( isFunction || |
| 11718 | ( l > 1 && typeof value === "string" && |
| 11719 | !support.checkClone && rchecked.test( value ) ) ) { |
| 11720 | return this.each(function( index ) { |
| 11721 | var self = set.eq( index ); |
| 11722 | if ( isFunction ) { |
| 11723 | args[ 0 ] = value.call( this, index, self.html() ); |
| 11724 | } |
| 11725 | self.domManip( args, callback ); |
| 11726 | }); |
| 11727 | } |
| 11728 | |
| 11729 | if ( l ) { |
| 11730 | fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); |
| 11731 | first = fragment.firstChild; |
| 11732 | |
| 11733 | if ( fragment.childNodes.length === 1 ) { |
| 11734 | fragment = first; |
| 11735 | } |
| 11736 | |
| 11737 | if ( first ) { |
| 11738 | scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); |
| 11739 | hasScripts = scripts.length; |
| 11740 | |
| 11741 | // Use the original fragment for the last item instead of the first because it can end up |
| 11742 | // being emptied incorrectly in certain situations (#8070). |
| 11743 | for ( ; i < l; i++ ) { |
| 11744 | node = fragment; |
| 11745 | |
| 11746 | if ( i !== iNoClone ) { |
| 11747 | node = jQuery.clone( node, true, true ); |
| 11748 | |
| 11749 | // Keep references to cloned scripts for later restoration |
| 11750 | if ( hasScripts ) { |
| 11751 | // Support: QtWebKit |
| 11752 | // jQuery.merge because push.apply(_, arraylike) throws |
| 11753 | jQuery.merge( scripts, getAll( node, "script" ) ); |
| 11754 | } |
| 11755 | } |
| 11756 | |
| 11757 | callback.call( this[ i ], node, i ); |
| 11758 | } |
| 11759 | |
| 11760 | if ( hasScripts ) { |
| 11761 | doc = scripts[ scripts.length - 1 ].ownerDocument; |
| 11762 | |
| 11763 | // Reenable scripts |
| 11764 | jQuery.map( scripts, restoreScript ); |
| 11765 | |
| 11766 | // Evaluate executable scripts on first document insertion |
| 11767 | for ( i = 0; i < hasScripts; i++ ) { |
| 11768 | node = scripts[ i ]; |
| 11769 | if ( rscriptType.test( node.type || "" ) && |
| 11770 | !data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) { |
| 11771 | |
| 11772 | if ( node.src ) { |
| 11773 | // Optional AJAX dependency, but won't run scripts if not present |
| 11774 | if ( jQuery._evalUrl ) { |
| 11775 | jQuery._evalUrl( node.src ); |
| 11776 | } |
| 11777 | } else { |
| 11778 | jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) ); |
| 11779 | } |
| 11780 | } |
| 11781 | } |
| 11782 | } |
| 11783 | } |
| 11784 | } |
| 11785 | |
| 11786 | return this; |
| 11787 | } |
| 11788 | }); |
| 11789 | |
| 11790 | jQuery.each({ |
| 11791 | appendTo: "append", |
| 11792 | prependTo: "prepend", |
| 11793 | insertBefore: "before", |
| 11794 | insertAfter: "after", |
| 11795 | replaceAll: "replaceWith" |
| 11796 | }, function( name, original ) { |
| 11797 | jQuery.fn[ name ] = function( selector ) { |
| 11798 | var elems, |
| 11799 | ret = [], |
| 11800 | insert = jQuery( selector ), |
| 11801 | last = insert.length - 1, |
| 11802 | i = 0; |
| 11803 | |
| 11804 | for ( ; i <= last; i++ ) { |
| 11805 | elems = i === last ? this : this.clone( true ); |
| 11806 | jQuery( insert[ i ] )[ original ]( elems ); |
| 11807 | |
| 11808 | // Support: QtWebKit |
| 11809 | // .get() because push.apply(_, arraylike) throws |
| 11810 | push.apply( ret, elems.get() ); |
| 11811 | } |
| 11812 | |
| 11813 | return this.pushStack( ret ); |
| 11814 | }; |
| 11815 | }); |
| 11816 | |
| 11817 | |
| 11818 | var iframe, |
| 11819 | elemdisplay = {}; |
| 11820 | |
| 11821 | /** |
| 11822 | * Retrieve the actual display of a element |
| 11823 | * @param {String} name nodeName of the element |
| 11824 | * @param {Object} doc Document object |
| 11825 | */ |
| 11826 | // Called only from within defaultDisplay |
| 11827 | function actualDisplay( name, doc ) { |
| 11828 | var style, |
| 11829 | elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), |
| 11830 | |
| 11831 | // getDefaultComputedStyle might be reliably used only on attached element |
| 11832 | display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ? |
| 11833 | |
| 11834 | // Use of this method is a temporary fix (more like optimization) until something better comes along, |
| 11835 | // since it was removed from specification and supported only in FF |
| 11836 | style.display : jQuery.css( elem[ 0 ], "display" ); |
| 11837 | |
| 11838 | // We don't have any data stored on the element, |
| 11839 | // so use "detach" method as fast way to get rid of the element |
| 11840 | elem.detach(); |
| 11841 | |
| 11842 | return display; |
| 11843 | } |
| 11844 | |
| 11845 | /** |
| 11846 | * Try to determine the default display value of an element |
| 11847 | * @param {String} nodeName |
| 11848 | */ |
| 11849 | function defaultDisplay( nodeName ) { |
| 11850 | var doc = document, |
| 11851 | display = elemdisplay[ nodeName ]; |
| 11852 | |
| 11853 | if ( !display ) { |
| 11854 | display = actualDisplay( nodeName, doc ); |
| 11855 | |
| 11856 | // If the simple way fails, read from inside an iframe |
| 11857 | if ( display === "none" || !display ) { |
| 11858 | |
| 11859 | // Use the already-created iframe if possible |
| 11860 | iframe = (iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" )).appendTo( doc.documentElement ); |
| 11861 | |
| 11862 | // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse |
| 11863 | doc = iframe[ 0 ].contentDocument; |
| 11864 | |
| 11865 | // Support: IE |
| 11866 | doc.write(); |
| 11867 | doc.close(); |
| 11868 | |
| 11869 | display = actualDisplay( nodeName, doc ); |
| 11870 | iframe.detach(); |
| 11871 | } |
| 11872 | |
| 11873 | // Store the correct default display |
| 11874 | elemdisplay[ nodeName ] = display; |
| 11875 | } |
| 11876 | |
| 11877 | return display; |
| 11878 | } |
| 11879 | var rmargin = (/^margin/); |
| 11880 | |
| 11881 | var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); |
| 11882 | |
| 11883 | var getStyles = function( elem ) { |
| 11884 | // Support: IE<=11+, Firefox<=30+ (#15098, #14150) |
| 11885 | // IE throws on elements created in popups |
| 11886 | // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" |
| 11887 | if ( elem.ownerDocument.defaultView.opener ) { |
| 11888 | return elem.ownerDocument.defaultView.getComputedStyle( elem, null ); |
| 11889 | } |
| 11890 | |
| 11891 | return window.getComputedStyle( elem, null ); |
| 11892 | }; |
| 11893 | |
| 11894 | |
| 11895 | |
| 11896 | function curCSS( elem, name, computed ) { |
| 11897 | var width, minWidth, maxWidth, ret, |
| 11898 | style = elem.style; |
| 11899 | |
| 11900 | computed = computed || getStyles( elem ); |
| 11901 | |
| 11902 | // Support: IE9 |
| 11903 | // getPropertyValue is only needed for .css('filter') (#12537) |
| 11904 | if ( computed ) { |
| 11905 | ret = computed.getPropertyValue( name ) || computed[ name ]; |
| 11906 | } |
| 11907 | |
| 11908 | if ( computed ) { |
| 11909 | |
| 11910 | if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { |
| 11911 | ret = jQuery.style( elem, name ); |
| 11912 | } |
| 11913 | |
| 11914 | // Support: iOS < 6 |
| 11915 | // A tribute to the "awesome hack by Dean Edwards" |
| 11916 | // iOS < 6 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels |
| 11917 | // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values |
| 11918 | if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { |
| 11919 | |
| 11920 | // Remember the original values |
| 11921 | width = style.width; |
| 11922 | minWidth = style.minWidth; |
| 11923 | maxWidth = style.maxWidth; |
| 11924 | |
| 11925 | // Put in the new values to get a computed value out |
| 11926 | style.minWidth = style.maxWidth = style.width = ret; |
| 11927 | ret = computed.width; |
| 11928 | |
| 11929 | // Revert the changed values |
| 11930 | style.width = width; |
| 11931 | style.minWidth = minWidth; |
| 11932 | style.maxWidth = maxWidth; |
| 11933 | } |
| 11934 | } |
| 11935 | |
| 11936 | return ret !== undefined ? |
| 11937 | // Support: IE |
| 11938 | // IE returns zIndex value as an integer. |
| 11939 | ret + "" : |
| 11940 | ret; |
| 11941 | } |
| 11942 | |
| 11943 | |
| 11944 | function addGetHookIf( conditionFn, hookFn ) { |
| 11945 | // Define the hook, we'll check on the first run if it's really needed. |
| 11946 | return { |
| 11947 | get: function() { |
| 11948 | if ( conditionFn() ) { |
| 11949 | // Hook not needed (or it's not possible to use it due |
| 11950 | // to missing dependency), remove it. |
| 11951 | delete this.get; |
| 11952 | return; |
| 11953 | } |
| 11954 | |
| 11955 | // Hook needed; redefine it so that the support test is not executed again. |
| 11956 | return (this.get = hookFn).apply( this, arguments ); |
| 11957 | } |
| 11958 | }; |
| 11959 | } |
| 11960 | |
| 11961 | |
| 11962 | (function() { |
| 11963 | var pixelPositionVal, boxSizingReliableVal, |
| 11964 | docElem = document.documentElement, |
| 11965 | container = document.createElement( "div" ), |
| 11966 | div = document.createElement( "div" ); |
| 11967 | |
| 11968 | if ( !div.style ) { |
| 11969 | return; |
| 11970 | } |
| 11971 | |
| 11972 | // Support: IE9-11+ |
| 11973 | // Style of cloned element affects source element cloned (#8908) |
| 11974 | div.style.backgroundClip = "content-box"; |
| 11975 | div.cloneNode( true ).style.backgroundClip = ""; |
| 11976 | support.clearCloneStyle = div.style.backgroundClip === "content-box"; |
| 11977 | |
| 11978 | container.style.cssText = "border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;" + |
| 11979 | "position:absolute"; |
| 11980 | container.appendChild( div ); |
| 11981 | |
| 11982 | // Executing both pixelPosition & boxSizingReliable tests require only one layout |
| 11983 | // so they're executed at the same time to save the second computation. |
| 11984 | function computePixelPositionAndBoxSizingReliable() { |
| 11985 | div.style.cssText = |
| 11986 | // Support: Firefox<29, Android 2.3 |
| 11987 | // Vendor-prefix box-sizing |
| 11988 | "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;" + |
| 11989 | "box-sizing:border-box;display:block;margin-top:1%;top:1%;" + |
| 11990 | "border:1px;padding:1px;width:4px;position:absolute"; |
| 11991 | div.innerHTML = ""; |
| 11992 | docElem.appendChild( container ); |
| 11993 | |
| 11994 | var divStyle = window.getComputedStyle( div, null ); |
| 11995 | pixelPositionVal = divStyle.top !== "1%"; |
| 11996 | boxSizingReliableVal = divStyle.width === "4px"; |
| 11997 | |
| 11998 | docElem.removeChild( container ); |
| 11999 | } |
| 12000 | |
| 12001 | // Support: node.js jsdom |
| 12002 | // Don't assume that getComputedStyle is a property of the global object |
| 12003 | if ( window.getComputedStyle ) { |
| 12004 | jQuery.extend( support, { |
| 12005 | pixelPosition: function() { |
| 12006 | |
| 12007 | // This test is executed only once but we still do memoizing |
| 12008 | // since we can use the boxSizingReliable pre-computing. |
| 12009 | // No need to check if the test was already performed, though. |
| 12010 | computePixelPositionAndBoxSizingReliable(); |
| 12011 | return pixelPositionVal; |
| 12012 | }, |
| 12013 | boxSizingReliable: function() { |
| 12014 | if ( boxSizingReliableVal == null ) { |
| 12015 | computePixelPositionAndBoxSizingReliable(); |
| 12016 | } |
| 12017 | return boxSizingReliableVal; |
| 12018 | }, |
| 12019 | reliableMarginRight: function() { |
| 12020 | |
| 12021 | // Support: Android 2.3 |
| 12022 | // Check if div with explicit width and no margin-right incorrectly |
| 12023 | // gets computed margin-right based on width of container. (#3333) |
| 12024 | // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right |
| 12025 | // This support function is only executed once so no memoizing is needed. |
| 12026 | var ret, |
| 12027 | marginDiv = div.appendChild( document.createElement( "div" ) ); |
| 12028 | |
| 12029 | // Reset CSS: box-sizing; display; margin; border; padding |
| 12030 | marginDiv.style.cssText = div.style.cssText = |
| 12031 | // Support: Firefox<29, Android 2.3 |
| 12032 | // Vendor-prefix box-sizing |
| 12033 | "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" + |
| 12034 | "box-sizing:content-box;display:block;margin:0;border:0;padding:0"; |
| 12035 | marginDiv.style.marginRight = marginDiv.style.width = "0"; |
| 12036 | div.style.width = "1px"; |
| 12037 | docElem.appendChild( container ); |
| 12038 | |
| 12039 | ret = !parseFloat( window.getComputedStyle( marginDiv, null ).marginRight ); |
| 12040 | |
| 12041 | docElem.removeChild( container ); |
| 12042 | div.removeChild( marginDiv ); |
| 12043 | |
| 12044 | return ret; |
| 12045 | } |
| 12046 | }); |
| 12047 | } |
| 12048 | })(); |
| 12049 | |
| 12050 | |
| 12051 | // A method for quickly swapping in/out CSS properties to get correct calculations. |
| 12052 | jQuery.swap = function( elem, options, callback, args ) { |
| 12053 | var ret, name, |
| 12054 | old = {}; |
| 12055 | |
| 12056 | // Remember the old values, and insert the new ones |
| 12057 | for ( name in options ) { |
| 12058 | old[ name ] = elem.style[ name ]; |
| 12059 | elem.style[ name ] = options[ name ]; |
| 12060 | } |
| 12061 | |
| 12062 | ret = callback.apply( elem, args || [] ); |
| 12063 | |
| 12064 | // Revert the old values |
| 12065 | for ( name in options ) { |
| 12066 | elem.style[ name ] = old[ name ]; |
| 12067 | } |
| 12068 | |
| 12069 | return ret; |
| 12070 | }; |
| 12071 | |
| 12072 | |
| 12073 | var |
| 12074 | // Swappable if display is none or starts with table except "table", "table-cell", or "table-caption" |
| 12075 | // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display |
| 12076 | rdisplayswap = /^(none|table(?!-c[ea]).+)/, |
| 12077 | rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ), |
| 12078 | rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ), |
| 12079 | |
| 12080 | cssShow = { position: "absolute", visibility: "hidden", display: "block" }, |
| 12081 | cssNormalTransform = { |
| 12082 | letterSpacing: "0", |
| 12083 | fontWeight: "400" |
| 12084 | }, |
| 12085 | |
| 12086 | cssPrefixes = [ "Webkit", "O", "Moz", "ms" ]; |
| 12087 | |
| 12088 | // Return a css property mapped to a potentially vendor prefixed property |
| 12089 | function vendorPropName( style, name ) { |
| 12090 | |
| 12091 | // Shortcut for names that are not vendor prefixed |
| 12092 | if ( name in style ) { |
| 12093 | return name; |
| 12094 | } |
| 12095 | |
| 12096 | // Check for vendor prefixed names |
| 12097 | var capName = name[0].toUpperCase() + name.slice(1), |
| 12098 | origName = name, |
| 12099 | i = cssPrefixes.length; |
| 12100 | |
| 12101 | while ( i-- ) { |
| 12102 | name = cssPrefixes[ i ] + capName; |
| 12103 | if ( name in style ) { |
| 12104 | return name; |
| 12105 | } |
| 12106 | } |
| 12107 | |
| 12108 | return origName; |
| 12109 | } |
| 12110 | |
| 12111 | function setPositiveNumber( elem, value, subtract ) { |
| 12112 | var matches = rnumsplit.exec( value ); |
| 12113 | return matches ? |
| 12114 | // Guard against undefined "subtract", e.g., when used as in cssHooks |
| 12115 | Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : |
| 12116 | value; |
| 12117 | } |
| 12118 | |
| 12119 | function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { |
| 12120 | var i = extra === ( isBorderBox ? "border" : "content" ) ? |
| 12121 | // If we already have the right measurement, avoid augmentation |
| 12122 | 4 : |
| 12123 | // Otherwise initialize for horizontal or vertical properties |
| 12124 | name === "width" ? 1 : 0, |
| 12125 | |
| 12126 | val = 0; |
| 12127 | |
| 12128 | for ( ; i < 4; i += 2 ) { |
| 12129 | // Both box models exclude margin, so add it if we want it |
| 12130 | if ( extra === "margin" ) { |
| 12131 | val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); |
| 12132 | } |
| 12133 | |
| 12134 | if ( isBorderBox ) { |
| 12135 | // border-box includes padding, so remove it if we want content |
| 12136 | if ( extra === "content" ) { |
| 12137 | val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); |
| 12138 | } |
| 12139 | |
| 12140 | // At this point, extra isn't border nor margin, so remove border |
| 12141 | if ( extra !== "margin" ) { |
| 12142 | val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); |
| 12143 | } |
| 12144 | } else { |
| 12145 | // At this point, extra isn't content, so add padding |
| 12146 | val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); |
| 12147 | |
| 12148 | // At this point, extra isn't content nor padding, so add border |
| 12149 | if ( extra !== "padding" ) { |
| 12150 | val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); |
| 12151 | } |
| 12152 | } |
| 12153 | } |
| 12154 | |
| 12155 | return val; |
| 12156 | } |
| 12157 | |
| 12158 | function getWidthOrHeight( elem, name, extra ) { |
| 12159 | |
| 12160 | // Start with offset property, which is equivalent to the border-box value |
| 12161 | var valueIsBorderBox = true, |
| 12162 | val = name === "width" ? elem.offsetWidth : elem.offsetHeight, |
| 12163 | styles = getStyles( elem ), |
| 12164 | isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; |
| 12165 | |
| 12166 | // Some non-html elements return undefined for offsetWidth, so check for null/undefined |
| 12167 | // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 |
| 12168 | // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 |
| 12169 | if ( val <= 0 || val == null ) { |
| 12170 | // Fall back to computed then uncomputed css if necessary |
| 12171 | val = curCSS( elem, name, styles ); |
| 12172 | if ( val < 0 || val == null ) { |
| 12173 | val = elem.style[ name ]; |
| 12174 | } |
| 12175 | |
| 12176 | // Computed unit is not pixels. Stop here and return. |
| 12177 | if ( rnumnonpx.test(val) ) { |
| 12178 | return val; |
| 12179 | } |
| 12180 | |
| 12181 | // Check for style in case a browser which returns unreliable values |
| 12182 | // for getComputedStyle silently falls back to the reliable elem.style |
| 12183 | valueIsBorderBox = isBorderBox && |
| 12184 | ( support.boxSizingReliable() || val === elem.style[ name ] ); |
| 12185 | |
| 12186 | // Normalize "", auto, and prepare for extra |
| 12187 | val = parseFloat( val ) || 0; |
| 12188 | } |
| 12189 | |
| 12190 | // Use the active box-sizing model to add/subtract irrelevant styles |
| 12191 | return ( val + |
| 12192 | augmentWidthOrHeight( |
| 12193 | elem, |
| 12194 | name, |
| 12195 | extra || ( isBorderBox ? "border" : "content" ), |
| 12196 | valueIsBorderBox, |
| 12197 | styles |
| 12198 | ) |
| 12199 | ) + "px"; |
| 12200 | } |
| 12201 | |
| 12202 | function showHide( elements, show ) { |
| 12203 | var display, elem, hidden, |
| 12204 | values = [], |
| 12205 | index = 0, |
| 12206 | length = elements.length; |
| 12207 | |
| 12208 | for ( ; index < length; index++ ) { |
| 12209 | elem = elements[ index ]; |
| 12210 | if ( !elem.style ) { |
| 12211 | continue; |
| 12212 | } |
| 12213 | |
| 12214 | values[ index ] = data_priv.get( elem, "olddisplay" ); |
| 12215 | display = elem.style.display; |
| 12216 | if ( show ) { |
| 12217 | // Reset the inline display of this element to learn if it is |
| 12218 | // being hidden by cascaded rules or not |
| 12219 | if ( !values[ index ] && display === "none" ) { |
| 12220 | elem.style.display = ""; |
| 12221 | } |
| 12222 | |
| 12223 | // Set elements which have been overridden with display: none |
| 12224 | // in a stylesheet to whatever the default browser style is |
| 12225 | // for such an element |
| 12226 | if ( elem.style.display === "" && isHidden( elem ) ) { |
| 12227 | values[ index ] = data_priv.access( elem, "olddisplay", defaultDisplay(elem.nodeName) ); |
| 12228 | } |
| 12229 | } else { |
| 12230 | hidden = isHidden( elem ); |
| 12231 | |
| 12232 | if ( display !== "none" || !hidden ) { |
| 12233 | data_priv.set( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) ); |
| 12234 | } |
| 12235 | } |
| 12236 | } |
| 12237 | |
| 12238 | // Set the display of most of the elements in a second loop |
| 12239 | // to avoid the constant reflow |
| 12240 | for ( index = 0; index < length; index++ ) { |
| 12241 | elem = elements[ index ]; |
| 12242 | if ( !elem.style ) { |
| 12243 | continue; |
| 12244 | } |
| 12245 | if ( !show || elem.style.display === "none" || elem.style.display === "" ) { |
| 12246 | elem.style.display = show ? values[ index ] || "" : "none"; |
| 12247 | } |
| 12248 | } |
| 12249 | |
| 12250 | return elements; |
| 12251 | } |
| 12252 | |
| 12253 | jQuery.extend({ |
| 12254 | |
| 12255 | // Add in style property hooks for overriding the default |
| 12256 | // behavior of getting and setting a style property |
| 12257 | cssHooks: { |
| 12258 | opacity: { |
| 12259 | get: function( elem, computed ) { |
| 12260 | if ( computed ) { |
| 12261 | |
| 12262 | // We should always get a number back from opacity |
| 12263 | var ret = curCSS( elem, "opacity" ); |
| 12264 | return ret === "" ? "1" : ret; |
| 12265 | } |
| 12266 | } |
| 12267 | } |
| 12268 | }, |
| 12269 | |
| 12270 | // Don't automatically add "px" to these possibly-unitless properties |
| 12271 | cssNumber: { |
| 12272 | "columnCount": true, |
| 12273 | "fillOpacity": true, |
| 12274 | "flexGrow": true, |
| 12275 | "flexShrink": true, |
| 12276 | "fontWeight": true, |
| 12277 | "lineHeight": true, |
| 12278 | "opacity": true, |
| 12279 | "order": true, |
| 12280 | "orphans": true, |
| 12281 | "widows": true, |
| 12282 | "zIndex": true, |
| 12283 | "zoom": true |
| 12284 | }, |
| 12285 | |
| 12286 | // Add in properties whose names you wish to fix before |
| 12287 | // setting or getting the value |
| 12288 | cssProps: { |
| 12289 | "float": "cssFloat" |
| 12290 | }, |
| 12291 | |
| 12292 | // Get and set the style property on a DOM Node |
| 12293 | style: function( elem, name, value, extra ) { |
| 12294 | |
| 12295 | // Don't set styles on text and comment nodes |
| 12296 | if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { |
| 12297 | return; |
| 12298 | } |
| 12299 | |
| 12300 | // Make sure that we're working with the right name |
| 12301 | var ret, type, hooks, |
| 12302 | origName = jQuery.camelCase( name ), |
| 12303 | style = elem.style; |
| 12304 | |
| 12305 | name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); |
| 12306 | |
| 12307 | // Gets hook for the prefixed version, then unprefixed version |
| 12308 | hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; |
| 12309 | |
| 12310 | // Check if we're setting a value |
| 12311 | if ( value !== undefined ) { |
| 12312 | type = typeof value; |
| 12313 | |
| 12314 | // Convert "+=" or "-=" to relative numbers (#7345) |
| 12315 | if ( type === "string" && (ret = rrelNum.exec( value )) ) { |
| 12316 | value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); |
| 12317 | // Fixes bug #9237 |
| 12318 | type = "number"; |
| 12319 | } |
| 12320 | |
| 12321 | // Make sure that null and NaN values aren't set (#7116) |
| 12322 | if ( value == null || value !== value ) { |
| 12323 | return; |
| 12324 | } |
| 12325 | |
| 12326 | // If a number, add 'px' to the (except for certain CSS properties) |
| 12327 | if ( type === "number" && !jQuery.cssNumber[ origName ] ) { |
| 12328 | value += "px"; |
| 12329 | } |
| 12330 | |
| 12331 | // Support: IE9-11+ |
| 12332 | // background-* props affect original clone's values |
| 12333 | if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { |
| 12334 | style[ name ] = "inherit"; |
| 12335 | } |
| 12336 | |
| 12337 | // If a hook was provided, use that value, otherwise just set the specified value |
| 12338 | if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { |
| 12339 | style[ name ] = value; |
| 12340 | } |
| 12341 | |
| 12342 | } else { |
| 12343 | // If a hook was provided get the non-computed value from there |
| 12344 | if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { |
| 12345 | return ret; |
| 12346 | } |
| 12347 | |
| 12348 | // Otherwise just get the value from the style object |
| 12349 | return style[ name ]; |
| 12350 | } |
| 12351 | }, |
| 12352 | |
| 12353 | css: function( elem, name, extra, styles ) { |
| 12354 | var val, num, hooks, |
| 12355 | origName = jQuery.camelCase( name ); |
| 12356 | |
| 12357 | // Make sure that we're working with the right name |
| 12358 | name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); |
| 12359 | |
| 12360 | // Try prefixed name followed by the unprefixed name |
| 12361 | hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; |
| 12362 | |
| 12363 | // If a hook was provided get the computed value from there |
| 12364 | if ( hooks && "get" in hooks ) { |
| 12365 | val = hooks.get( elem, true, extra ); |
| 12366 | } |
| 12367 | |
| 12368 | // Otherwise, if a way to get the computed value exists, use that |
| 12369 | if ( val === undefined ) { |
| 12370 | val = curCSS( elem, name, styles ); |
| 12371 | } |
| 12372 | |
| 12373 | // Convert "normal" to computed value |
| 12374 | if ( val === "normal" && name in cssNormalTransform ) { |
| 12375 | val = cssNormalTransform[ name ]; |
| 12376 | } |
| 12377 | |
| 12378 | // Make numeric if forced or a qualifier was provided and val looks numeric |
| 12379 | if ( extra === "" || extra ) { |
| 12380 | num = parseFloat( val ); |
| 12381 | return extra === true || jQuery.isNumeric( num ) ? num || 0 : val; |
| 12382 | } |
| 12383 | return val; |
| 12384 | } |
| 12385 | }); |
| 12386 | |
| 12387 | jQuery.each([ "height", "width" ], function( i, name ) { |
| 12388 | jQuery.cssHooks[ name ] = { |
| 12389 | get: function( elem, computed, extra ) { |
| 12390 | if ( computed ) { |
| 12391 | |
| 12392 | // Certain elements can have dimension info if we invisibly show them |
| 12393 | // but it must have a current display style that would benefit |
| 12394 | return rdisplayswap.test( jQuery.css( elem, "display" ) ) && elem.offsetWidth === 0 ? |
| 12395 | jQuery.swap( elem, cssShow, function() { |
| 12396 | return getWidthOrHeight( elem, name, extra ); |
| 12397 | }) : |
| 12398 | getWidthOrHeight( elem, name, extra ); |
| 12399 | } |
| 12400 | }, |
| 12401 | |
| 12402 | set: function( elem, value, extra ) { |
| 12403 | var styles = extra && getStyles( elem ); |
| 12404 | return setPositiveNumber( elem, value, extra ? |
| 12405 | augmentWidthOrHeight( |
| 12406 | elem, |
| 12407 | name, |
| 12408 | extra, |
| 12409 | jQuery.css( elem, "boxSizing", false, styles ) === "border-box", |
| 12410 | styles |
| 12411 | ) : 0 |
| 12412 | ); |
| 12413 | } |
| 12414 | }; |
| 12415 | }); |
| 12416 | |
| 12417 | // Support: Android 2.3 |
| 12418 | jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight, |
| 12419 | function( elem, computed ) { |
| 12420 | if ( computed ) { |
| 12421 | return jQuery.swap( elem, { "display": "inline-block" }, |
| 12422 | curCSS, [ elem, "marginRight" ] ); |
| 12423 | } |
| 12424 | } |
| 12425 | ); |
| 12426 | |
| 12427 | // These hooks are used by animate to expand properties |
| 12428 | jQuery.each({ |
| 12429 | margin: "", |
| 12430 | padding: "", |
| 12431 | border: "Width" |
| 12432 | }, function( prefix, suffix ) { |
| 12433 | jQuery.cssHooks[ prefix + suffix ] = { |
| 12434 | expand: function( value ) { |
| 12435 | var i = 0, |
| 12436 | expanded = {}, |
| 12437 | |
| 12438 | // Assumes a single number if not a string |
| 12439 | parts = typeof value === "string" ? value.split(" ") : [ value ]; |
| 12440 | |
| 12441 | for ( ; i < 4; i++ ) { |
| 12442 | expanded[ prefix + cssExpand[ i ] + suffix ] = |
| 12443 | parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; |
| 12444 | } |
| 12445 | |
| 12446 | return expanded; |
| 12447 | } |
| 12448 | }; |
| 12449 | |
| 12450 | if ( !rmargin.test( prefix ) ) { |
| 12451 | jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; |
| 12452 | } |
| 12453 | }); |
| 12454 | |
| 12455 | jQuery.fn.extend({ |
| 12456 | css: function( name, value ) { |
| 12457 | return access( this, function( elem, name, value ) { |
| 12458 | var styles, len, |
| 12459 | map = {}, |
| 12460 | i = 0; |
| 12461 | |
| 12462 | if ( jQuery.isArray( name ) ) { |
| 12463 | styles = getStyles( elem ); |
| 12464 | len = name.length; |
| 12465 | |
| 12466 | for ( ; i < len; i++ ) { |
| 12467 | map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); |
| 12468 | } |
| 12469 | |
| 12470 | return map; |
| 12471 | } |
| 12472 | |
| 12473 | return value !== undefined ? |
| 12474 | jQuery.style( elem, name, value ) : |
| 12475 | jQuery.css( elem, name ); |
| 12476 | }, name, value, arguments.length > 1 ); |
| 12477 | }, |
| 12478 | show: function() { |
| 12479 | return showHide( this, true ); |
| 12480 | }, |
| 12481 | hide: function() { |
| 12482 | return showHide( this ); |
| 12483 | }, |
| 12484 | toggle: function( state ) { |
| 12485 | if ( typeof state === "boolean" ) { |
| 12486 | return state ? this.show() : this.hide(); |
| 12487 | } |
| 12488 | |
| 12489 | return this.each(function() { |
| 12490 | if ( isHidden( this ) ) { |
| 12491 | jQuery( this ).show(); |
| 12492 | } else { |
| 12493 | jQuery( this ).hide(); |
| 12494 | } |
| 12495 | }); |
| 12496 | } |
| 12497 | }); |
| 12498 | |
| 12499 | |
| 12500 | function Tween( elem, options, prop, end, easing ) { |
| 12501 | return new Tween.prototype.init( elem, options, prop, end, easing ); |
| 12502 | } |
| 12503 | jQuery.Tween = Tween; |
| 12504 | |
| 12505 | Tween.prototype = { |
| 12506 | constructor: Tween, |
| 12507 | init: function( elem, options, prop, end, easing, unit ) { |
| 12508 | this.elem = elem; |
| 12509 | this.prop = prop; |
| 12510 | this.easing = easing || "swing"; |
| 12511 | this.options = options; |
| 12512 | this.start = this.now = this.cur(); |
| 12513 | this.end = end; |
| 12514 | this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); |
| 12515 | }, |
| 12516 | cur: function() { |
| 12517 | var hooks = Tween.propHooks[ this.prop ]; |
| 12518 | |
| 12519 | return hooks && hooks.get ? |
| 12520 | hooks.get( this ) : |
| 12521 | Tween.propHooks._default.get( this ); |
| 12522 | }, |
| 12523 | run: function( percent ) { |
| 12524 | var eased, |
| 12525 | hooks = Tween.propHooks[ this.prop ]; |
| 12526 | |
| 12527 | if ( this.options.duration ) { |
| 12528 | this.pos = eased = jQuery.easing[ this.easing ]( |
| 12529 | percent, this.options.duration * percent, 0, 1, this.options.duration |
| 12530 | ); |
| 12531 | } else { |
| 12532 | this.pos = eased = percent; |
| 12533 | } |
| 12534 | this.now = ( this.end - this.start ) * eased + this.start; |
| 12535 | |
| 12536 | if ( this.options.step ) { |
| 12537 | this.options.step.call( this.elem, this.now, this ); |
| 12538 | } |
| 12539 | |
| 12540 | if ( hooks && hooks.set ) { |
| 12541 | hooks.set( this ); |
| 12542 | } else { |
| 12543 | Tween.propHooks._default.set( this ); |
| 12544 | } |
| 12545 | return this; |
| 12546 | } |
| 12547 | }; |
| 12548 | |
| 12549 | Tween.prototype.init.prototype = Tween.prototype; |
| 12550 | |
| 12551 | Tween.propHooks = { |
| 12552 | _default: { |
| 12553 | get: function( tween ) { |
| 12554 | var result; |
| 12555 | |
| 12556 | if ( tween.elem[ tween.prop ] != null && |
| 12557 | (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) { |
| 12558 | return tween.elem[ tween.prop ]; |
| 12559 | } |
| 12560 | |
| 12561 | // Passing an empty string as a 3rd parameter to .css will automatically |
| 12562 | // attempt a parseFloat and fallback to a string if the parse fails. |
| 12563 | // Simple values such as "10px" are parsed to Float; |
| 12564 | // complex values such as "rotate(1rad)" are returned as-is. |
| 12565 | result = jQuery.css( tween.elem, tween.prop, "" ); |
| 12566 | // Empty strings, null, undefined and "auto" are converted to 0. |
| 12567 | return !result || result === "auto" ? 0 : result; |
| 12568 | }, |
| 12569 | set: function( tween ) { |
| 12570 | // Use step hook for back compat. |
| 12571 | // Use cssHook if its there. |
| 12572 | // Use .style if available and use plain properties where available. |
| 12573 | if ( jQuery.fx.step[ tween.prop ] ) { |
| 12574 | jQuery.fx.step[ tween.prop ]( tween ); |
| 12575 | } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) { |
| 12576 | jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); |
| 12577 | } else { |
| 12578 | tween.elem[ tween.prop ] = tween.now; |
| 12579 | } |
| 12580 | } |
| 12581 | } |
| 12582 | }; |
| 12583 | |
| 12584 | // Support: IE9 |
| 12585 | // Panic based approach to setting things on disconnected nodes |
| 12586 | Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { |
| 12587 | set: function( tween ) { |
| 12588 | if ( tween.elem.nodeType && tween.elem.parentNode ) { |
| 12589 | tween.elem[ tween.prop ] = tween.now; |
| 12590 | } |
| 12591 | } |
| 12592 | }; |
| 12593 | |
| 12594 | jQuery.easing = { |
| 12595 | linear: function( p ) { |
| 12596 | return p; |
| 12597 | }, |
| 12598 | swing: function( p ) { |
| 12599 | return 0.5 - Math.cos( p * Math.PI ) / 2; |
| 12600 | } |
| 12601 | }; |
| 12602 | |
| 12603 | jQuery.fx = Tween.prototype.init; |
| 12604 | |
| 12605 | // Back Compat <1.8 extension point |
| 12606 | jQuery.fx.step = {}; |
| 12607 | |
| 12608 | |
| 12609 | |
| 12610 | |
| 12611 | var |
| 12612 | fxNow, timerId, |
| 12613 | rfxtypes = /^(?:toggle|show|hide)$/, |
| 12614 | rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ), |
| 12615 | rrun = /queueHooks$/, |
| 12616 | animationPrefilters = [ defaultPrefilter ], |
| 12617 | tweeners = { |
| 12618 | "*": [ function( prop, value ) { |
| 12619 | var tween = this.createTween( prop, value ), |
| 12620 | target = tween.cur(), |
| 12621 | parts = rfxnum.exec( value ), |
| 12622 | unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), |
| 12623 | |
| 12624 | // Starting value computation is required for potential unit mismatches |
| 12625 | start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) && |
| 12626 | rfxnum.exec( jQuery.css( tween.elem, prop ) ), |
| 12627 | scale = 1, |
| 12628 | maxIterations = 20; |
| 12629 | |
| 12630 | if ( start && start[ 3 ] !== unit ) { |
| 12631 | // Trust units reported by jQuery.css |
| 12632 | unit = unit || start[ 3 ]; |
| 12633 | |
| 12634 | // Make sure we update the tween properties later on |
| 12635 | parts = parts || []; |
| 12636 | |
| 12637 | // Iteratively approximate from a nonzero starting point |
| 12638 | start = +target || 1; |
| 12639 | |
| 12640 | do { |
| 12641 | // If previous iteration zeroed out, double until we get *something*. |
| 12642 | // Use string for doubling so we don't accidentally see scale as unchanged below |
| 12643 | scale = scale || ".5"; |
| 12644 | |
| 12645 | // Adjust and apply |
| 12646 | start = start / scale; |
| 12647 | jQuery.style( tween.elem, prop, start + unit ); |
| 12648 | |
| 12649 | // Update scale, tolerating zero or NaN from tween.cur(), |
| 12650 | // break the loop if scale is unchanged or perfect, or if we've just had enough |
| 12651 | } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations ); |
| 12652 | } |
| 12653 | |
| 12654 | // Update tween properties |
| 12655 | if ( parts ) { |
| 12656 | start = tween.start = +start || +target || 0; |
| 12657 | tween.unit = unit; |
| 12658 | // If a +=/-= token was provided, we're doing a relative animation |
| 12659 | tween.end = parts[ 1 ] ? |
| 12660 | start + ( parts[ 1 ] + 1 ) * parts[ 2 ] : |
| 12661 | +parts[ 2 ]; |
| 12662 | } |
| 12663 | |
| 12664 | return tween; |
| 12665 | } ] |
| 12666 | }; |
| 12667 | |
| 12668 | // Animations created synchronously will run synchronously |
| 12669 | function createFxNow() { |
| 12670 | setTimeout(function() { |
| 12671 | fxNow = undefined; |
| 12672 | }); |
| 12673 | return ( fxNow = jQuery.now() ); |
| 12674 | } |
| 12675 | |
| 12676 | // Generate parameters to create a standard animation |
| 12677 | function genFx( type, includeWidth ) { |
| 12678 | var which, |
| 12679 | i = 0, |
| 12680 | attrs = { height: type }; |
| 12681 | |
| 12682 | // If we include width, step value is 1 to do all cssExpand values, |
| 12683 | // otherwise step value is 2 to skip over Left and Right |
| 12684 | includeWidth = includeWidth ? 1 : 0; |
| 12685 | for ( ; i < 4 ; i += 2 - includeWidth ) { |
| 12686 | which = cssExpand[ i ]; |
| 12687 | attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; |
| 12688 | } |
| 12689 | |
| 12690 | if ( includeWidth ) { |
| 12691 | attrs.opacity = attrs.width = type; |
| 12692 | } |
| 12693 | |
| 12694 | return attrs; |
| 12695 | } |
| 12696 | |
| 12697 | function createTween( value, prop, animation ) { |
| 12698 | var tween, |
| 12699 | collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ), |
| 12700 | index = 0, |
| 12701 | length = collection.length; |
| 12702 | for ( ; index < length; index++ ) { |
| 12703 | if ( (tween = collection[ index ].call( animation, prop, value )) ) { |
| 12704 | |
| 12705 | // We're done with this property |
| 12706 | return tween; |
| 12707 | } |
| 12708 | } |
| 12709 | } |
| 12710 | |
| 12711 | function defaultPrefilter( elem, props, opts ) { |
| 12712 | /* jshint validthis: true */ |
| 12713 | var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay, |
| 12714 | anim = this, |
| 12715 | orig = {}, |
| 12716 | style = elem.style, |
| 12717 | hidden = elem.nodeType && isHidden( elem ), |
| 12718 | dataShow = data_priv.get( elem, "fxshow" ); |
| 12719 | |
| 12720 | // Handle queue: false promises |
| 12721 | if ( !opts.queue ) { |
| 12722 | hooks = jQuery._queueHooks( elem, "fx" ); |
| 12723 | if ( hooks.unqueued == null ) { |
| 12724 | hooks.unqueued = 0; |
| 12725 | oldfire = hooks.empty.fire; |
| 12726 | hooks.empty.fire = function() { |
| 12727 | if ( !hooks.unqueued ) { |
| 12728 | oldfire(); |
| 12729 | } |
| 12730 | }; |
| 12731 | } |
| 12732 | hooks.unqueued++; |
| 12733 | |
| 12734 | anim.always(function() { |
| 12735 | // Ensure the complete handler is called before this completes |
| 12736 | anim.always(function() { |
| 12737 | hooks.unqueued--; |
| 12738 | if ( !jQuery.queue( elem, "fx" ).length ) { |
| 12739 | hooks.empty.fire(); |
| 12740 | } |
| 12741 | }); |
| 12742 | }); |
| 12743 | } |
| 12744 | |
| 12745 | // Height/width overflow pass |
| 12746 | if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) { |
| 12747 | // Make sure that nothing sneaks out |
| 12748 | // Record all 3 overflow attributes because IE9-10 do not |
| 12749 | // change the overflow attribute when overflowX and |
| 12750 | // overflowY are set to the same value |
| 12751 | opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; |
| 12752 | |
| 12753 | // Set display property to inline-block for height/width |
| 12754 | // animations on inline elements that are having width/height animated |
| 12755 | display = jQuery.css( elem, "display" ); |
| 12756 | |
| 12757 | // Test default display if display is currently "none" |
| 12758 | checkDisplay = display === "none" ? |
| 12759 | data_priv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display; |
| 12760 | |
| 12761 | if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) { |
| 12762 | style.display = "inline-block"; |
| 12763 | } |
| 12764 | } |
| 12765 | |
| 12766 | if ( opts.overflow ) { |
| 12767 | style.overflow = "hidden"; |
| 12768 | anim.always(function() { |
| 12769 | style.overflow = opts.overflow[ 0 ]; |
| 12770 | style.overflowX = opts.overflow[ 1 ]; |
| 12771 | style.overflowY = opts.overflow[ 2 ]; |
| 12772 | }); |
| 12773 | } |
| 12774 | |
| 12775 | // show/hide pass |
| 12776 | for ( prop in props ) { |
| 12777 | value = props[ prop ]; |
| 12778 | if ( rfxtypes.exec( value ) ) { |
| 12779 | delete props[ prop ]; |
| 12780 | toggle = toggle || value === "toggle"; |
| 12781 | if ( value === ( hidden ? "hide" : "show" ) ) { |
| 12782 | |
| 12783 | // If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden |
| 12784 | if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { |
| 12785 | hidden = true; |
| 12786 | } else { |
| 12787 | continue; |
| 12788 | } |
| 12789 | } |
| 12790 | orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); |
| 12791 | |
| 12792 | // Any non-fx value stops us from restoring the original display value |
| 12793 | } else { |
| 12794 | display = undefined; |
| 12795 | } |
| 12796 | } |
| 12797 | |
| 12798 | if ( !jQuery.isEmptyObject( orig ) ) { |
| 12799 | if ( dataShow ) { |
| 12800 | if ( "hidden" in dataShow ) { |
| 12801 | hidden = dataShow.hidden; |
| 12802 | } |
| 12803 | } else { |
| 12804 | dataShow = data_priv.access( elem, "fxshow", {} ); |
| 12805 | } |
| 12806 | |
| 12807 | // Store state if its toggle - enables .stop().toggle() to "reverse" |
| 12808 | if ( toggle ) { |
| 12809 | dataShow.hidden = !hidden; |
| 12810 | } |
| 12811 | if ( hidden ) { |
| 12812 | jQuery( elem ).show(); |
| 12813 | } else { |
| 12814 | anim.done(function() { |
| 12815 | jQuery( elem ).hide(); |
| 12816 | }); |
| 12817 | } |
| 12818 | anim.done(function() { |
| 12819 | var prop; |
| 12820 | |
| 12821 | data_priv.remove( elem, "fxshow" ); |
| 12822 | for ( prop in orig ) { |
| 12823 | jQuery.style( elem, prop, orig[ prop ] ); |
| 12824 | } |
| 12825 | }); |
| 12826 | for ( prop in orig ) { |
| 12827 | tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); |
| 12828 | |
| 12829 | if ( !( prop in dataShow ) ) { |
| 12830 | dataShow[ prop ] = tween.start; |
| 12831 | if ( hidden ) { |
| 12832 | tween.end = tween.start; |
| 12833 | tween.start = prop === "width" || prop === "height" ? 1 : 0; |
| 12834 | } |
| 12835 | } |
| 12836 | } |
| 12837 | |
| 12838 | // If this is a noop like .hide().hide(), restore an overwritten display value |
| 12839 | } else if ( (display === "none" ? defaultDisplay( elem.nodeName ) : display) === "inline" ) { |
| 12840 | style.display = display; |
| 12841 | } |
| 12842 | } |
| 12843 | |
| 12844 | function propFilter( props, specialEasing ) { |
| 12845 | var index, name, easing, value, hooks; |
| 12846 | |
| 12847 | // camelCase, specialEasing and expand cssHook pass |
| 12848 | for ( index in props ) { |
| 12849 | name = jQuery.camelCase( index ); |
| 12850 | easing = specialEasing[ name ]; |
| 12851 | value = props[ index ]; |
| 12852 | if ( jQuery.isArray( value ) ) { |
| 12853 | easing = value[ 1 ]; |
| 12854 | value = props[ index ] = value[ 0 ]; |
| 12855 | } |
| 12856 | |
| 12857 | if ( index !== name ) { |
| 12858 | props[ name ] = value; |
| 12859 | delete props[ index ]; |
| 12860 | } |
| 12861 | |
| 12862 | hooks = jQuery.cssHooks[ name ]; |
| 12863 | if ( hooks && "expand" in hooks ) { |
| 12864 | value = hooks.expand( value ); |
| 12865 | delete props[ name ]; |
| 12866 | |
| 12867 | // Not quite $.extend, this won't overwrite existing keys. |
| 12868 | // Reusing 'index' because we have the correct "name" |
| 12869 | for ( index in value ) { |
| 12870 | if ( !( index in props ) ) { |
| 12871 | props[ index ] = value[ index ]; |
| 12872 | specialEasing[ index ] = easing; |
| 12873 | } |
| 12874 | } |
| 12875 | } else { |
| 12876 | specialEasing[ name ] = easing; |
| 12877 | } |
| 12878 | } |
| 12879 | } |
| 12880 | |
| 12881 | function Animation( elem, properties, options ) { |
| 12882 | var result, |
| 12883 | stopped, |
| 12884 | index = 0, |
| 12885 | length = animationPrefilters.length, |
| 12886 | deferred = jQuery.Deferred().always( function() { |
| 12887 | // Don't match elem in the :animated selector |
| 12888 | delete tick.elem; |
| 12889 | }), |
| 12890 | tick = function() { |
| 12891 | if ( stopped ) { |
| 12892 | return false; |
| 12893 | } |
| 12894 | var currentTime = fxNow || createFxNow(), |
| 12895 | remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), |
| 12896 | // Support: Android 2.3 |
| 12897 | // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) |
| 12898 | temp = remaining / animation.duration || 0, |
| 12899 | percent = 1 - temp, |
| 12900 | index = 0, |
| 12901 | length = animation.tweens.length; |
| 12902 | |
| 12903 | for ( ; index < length ; index++ ) { |
| 12904 | animation.tweens[ index ].run( percent ); |
| 12905 | } |
| 12906 | |
| 12907 | deferred.notifyWith( elem, [ animation, percent, remaining ]); |
| 12908 | |
| 12909 | if ( percent < 1 && length ) { |
| 12910 | return remaining; |
| 12911 | } else { |
| 12912 | deferred.resolveWith( elem, [ animation ] ); |
| 12913 | return false; |
| 12914 | } |
| 12915 | }, |
| 12916 | animation = deferred.promise({ |
| 12917 | elem: elem, |
| 12918 | props: jQuery.extend( {}, properties ), |
| 12919 | opts: jQuery.extend( true, { specialEasing: {} }, options ), |
| 12920 | originalProperties: properties, |
| 12921 | originalOptions: options, |
| 12922 | startTime: fxNow || createFxNow(), |
| 12923 | duration: options.duration, |
| 12924 | tweens: [], |
| 12925 | createTween: function( prop, end ) { |
| 12926 | var tween = jQuery.Tween( elem, animation.opts, prop, end, |
| 12927 | animation.opts.specialEasing[ prop ] || animation.opts.easing ); |
| 12928 | animation.tweens.push( tween ); |
| 12929 | return tween; |
| 12930 | }, |
| 12931 | stop: function( gotoEnd ) { |
| 12932 | var index = 0, |
| 12933 | // If we are going to the end, we want to run all the tweens |
| 12934 | // otherwise we skip this part |
| 12935 | length = gotoEnd ? animation.tweens.length : 0; |
| 12936 | if ( stopped ) { |
| 12937 | return this; |
| 12938 | } |
| 12939 | stopped = true; |
| 12940 | for ( ; index < length ; index++ ) { |
| 12941 | animation.tweens[ index ].run( 1 ); |
| 12942 | } |
| 12943 | |
| 12944 | // Resolve when we played the last frame; otherwise, reject |
| 12945 | if ( gotoEnd ) { |
| 12946 | deferred.resolveWith( elem, [ animation, gotoEnd ] ); |
| 12947 | } else { |
| 12948 | deferred.rejectWith( elem, [ animation, gotoEnd ] ); |
| 12949 | } |
| 12950 | return this; |
| 12951 | } |
| 12952 | }), |
| 12953 | props = animation.props; |
| 12954 | |
| 12955 | propFilter( props, animation.opts.specialEasing ); |
| 12956 | |
| 12957 | for ( ; index < length ; index++ ) { |
| 12958 | result = animationPrefilters[ index ].call( animation, elem, props, animation.opts ); |
| 12959 | if ( result ) { |
| 12960 | return result; |
| 12961 | } |
| 12962 | } |
| 12963 | |
| 12964 | jQuery.map( props, createTween, animation ); |
| 12965 | |
| 12966 | if ( jQuery.isFunction( animation.opts.start ) ) { |
| 12967 | animation.opts.start.call( elem, animation ); |
| 12968 | } |
| 12969 | |
| 12970 | jQuery.fx.timer( |
| 12971 | jQuery.extend( tick, { |
| 12972 | elem: elem, |
| 12973 | anim: animation, |
| 12974 | queue: animation.opts.queue |
| 12975 | }) |
| 12976 | ); |
| 12977 | |
| 12978 | // attach callbacks from options |
| 12979 | return animation.progress( animation.opts.progress ) |
| 12980 | .done( animation.opts.done, animation.opts.complete ) |
| 12981 | .fail( animation.opts.fail ) |
| 12982 | .always( animation.opts.always ); |
| 12983 | } |
| 12984 | |
| 12985 | jQuery.Animation = jQuery.extend( Animation, { |
| 12986 | |
| 12987 | tweener: function( props, callback ) { |
| 12988 | if ( jQuery.isFunction( props ) ) { |
| 12989 | callback = props; |
| 12990 | props = [ "*" ]; |
| 12991 | } else { |
| 12992 | props = props.split(" "); |
| 12993 | } |
| 12994 | |
| 12995 | var prop, |
| 12996 | index = 0, |
| 12997 | length = props.length; |
| 12998 | |
| 12999 | for ( ; index < length ; index++ ) { |
| 13000 | prop = props[ index ]; |
| 13001 | tweeners[ prop ] = tweeners[ prop ] || []; |
| 13002 | tweeners[ prop ].unshift( callback ); |
| 13003 | } |
| 13004 | }, |
| 13005 | |
| 13006 | prefilter: function( callback, prepend ) { |
| 13007 | if ( prepend ) { |
| 13008 | animationPrefilters.unshift( callback ); |
| 13009 | } else { |
| 13010 | animationPrefilters.push( callback ); |
| 13011 | } |
| 13012 | } |
| 13013 | }); |
| 13014 | |
| 13015 | jQuery.speed = function( speed, easing, fn ) { |
| 13016 | var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { |
| 13017 | complete: fn || !fn && easing || |
| 13018 | jQuery.isFunction( speed ) && speed, |
| 13019 | duration: speed, |
| 13020 | easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing |
| 13021 | }; |
| 13022 | |
| 13023 | opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : |
| 13024 | opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; |
| 13025 | |
| 13026 | // Normalize opt.queue - true/undefined/null -> "fx" |
| 13027 | if ( opt.queue == null || opt.queue === true ) { |
| 13028 | opt.queue = "fx"; |
| 13029 | } |
| 13030 | |
| 13031 | // Queueing |
| 13032 | opt.old = opt.complete; |
| 13033 | |
| 13034 | opt.complete = function() { |
| 13035 | if ( jQuery.isFunction( opt.old ) ) { |
| 13036 | opt.old.call( this ); |
| 13037 | } |
| 13038 | |
| 13039 | if ( opt.queue ) { |
| 13040 | jQuery.dequeue( this, opt.queue ); |
| 13041 | } |
| 13042 | }; |
| 13043 | |
| 13044 | return opt; |
| 13045 | }; |
| 13046 | |
| 13047 | jQuery.fn.extend({ |
| 13048 | fadeTo: function( speed, to, easing, callback ) { |
| 13049 | |
| 13050 | // Show any hidden elements after setting opacity to 0 |
| 13051 | return this.filter( isHidden ).css( "opacity", 0 ).show() |
| 13052 | |
| 13053 | // Animate to the value specified |
| 13054 | .end().animate({ opacity: to }, speed, easing, callback ); |
| 13055 | }, |
| 13056 | animate: function( prop, speed, easing, callback ) { |
| 13057 | var empty = jQuery.isEmptyObject( prop ), |
| 13058 | optall = jQuery.speed( speed, easing, callback ), |
| 13059 | doAnimation = function() { |
| 13060 | // Operate on a copy of prop so per-property easing won't be lost |
| 13061 | var anim = Animation( this, jQuery.extend( {}, prop ), optall ); |
| 13062 | |
| 13063 | // Empty animations, or finishing resolves immediately |
| 13064 | if ( empty || data_priv.get( this, "finish" ) ) { |
| 13065 | anim.stop( true ); |
| 13066 | } |
| 13067 | }; |
| 13068 | doAnimation.finish = doAnimation; |
| 13069 | |
| 13070 | return empty || optall.queue === false ? |
| 13071 | this.each( doAnimation ) : |
| 13072 | this.queue( optall.queue, doAnimation ); |
| 13073 | }, |
| 13074 | stop: function( type, clearQueue, gotoEnd ) { |
| 13075 | var stopQueue = function( hooks ) { |
| 13076 | var stop = hooks.stop; |
| 13077 | delete hooks.stop; |
| 13078 | stop( gotoEnd ); |
| 13079 | }; |
| 13080 | |
| 13081 | if ( typeof type !== "string" ) { |
| 13082 | gotoEnd = clearQueue; |
| 13083 | clearQueue = type; |
| 13084 | type = undefined; |
| 13085 | } |
| 13086 | if ( clearQueue && type !== false ) { |
| 13087 | this.queue( type || "fx", [] ); |
| 13088 | } |
| 13089 | |
| 13090 | return this.each(function() { |
| 13091 | var dequeue = true, |
| 13092 | index = type != null && type + "queueHooks", |
| 13093 | timers = jQuery.timers, |
| 13094 | data = data_priv.get( this ); |
| 13095 | |
| 13096 | if ( index ) { |
| 13097 | if ( data[ index ] && data[ index ].stop ) { |
| 13098 | stopQueue( data[ index ] ); |
| 13099 | } |
| 13100 | } else { |
| 13101 | for ( index in data ) { |
| 13102 | if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { |
| 13103 | stopQueue( data[ index ] ); |
| 13104 | } |
| 13105 | } |
| 13106 | } |
| 13107 | |
| 13108 | for ( index = timers.length; index--; ) { |
| 13109 | if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) { |
| 13110 | timers[ index ].anim.stop( gotoEnd ); |
| 13111 | dequeue = false; |
| 13112 | timers.splice( index, 1 ); |
| 13113 | } |
| 13114 | } |
| 13115 | |
| 13116 | // Start the next in the queue if the last step wasn't forced. |
| 13117 | // Timers currently will call their complete callbacks, which |
| 13118 | // will dequeue but only if they were gotoEnd. |
| 13119 | if ( dequeue || !gotoEnd ) { |
| 13120 | jQuery.dequeue( this, type ); |
| 13121 | } |
| 13122 | }); |
| 13123 | }, |
| 13124 | finish: function( type ) { |
| 13125 | if ( type !== false ) { |
| 13126 | type = type || "fx"; |
| 13127 | } |
| 13128 | return this.each(function() { |
| 13129 | var index, |
| 13130 | data = data_priv.get( this ), |
| 13131 | queue = data[ type + "queue" ], |
| 13132 | hooks = data[ type + "queueHooks" ], |
| 13133 | timers = jQuery.timers, |
| 13134 | length = queue ? queue.length : 0; |
| 13135 | |
| 13136 | // Enable finishing flag on private data |
| 13137 | data.finish = true; |
| 13138 | |
| 13139 | // Empty the queue first |
| 13140 | jQuery.queue( this, type, [] ); |
| 13141 | |
| 13142 | if ( hooks && hooks.stop ) { |
| 13143 | hooks.stop.call( this, true ); |
| 13144 | } |
| 13145 | |
| 13146 | // Look for any active animations, and finish them |
| 13147 | for ( index = timers.length; index--; ) { |
| 13148 | if ( timers[ index ].elem === this && timers[ index ].queue === type ) { |
| 13149 | timers[ index ].anim.stop( true ); |
| 13150 | timers.splice( index, 1 ); |
| 13151 | } |
| 13152 | } |
| 13153 | |
| 13154 | // Look for any animations in the old queue and finish them |
| 13155 | for ( index = 0; index < length; index++ ) { |
| 13156 | if ( queue[ index ] && queue[ index ].finish ) { |
| 13157 | queue[ index ].finish.call( this ); |
| 13158 | } |
| 13159 | } |
| 13160 | |
| 13161 | // Turn off finishing flag |
| 13162 | delete data.finish; |
| 13163 | }); |
| 13164 | } |
| 13165 | }); |
| 13166 | |
| 13167 | jQuery.each([ "toggle", "show", "hide" ], function( i, name ) { |
| 13168 | var cssFn = jQuery.fn[ name ]; |
| 13169 | jQuery.fn[ name ] = function( speed, easing, callback ) { |
| 13170 | return speed == null || typeof speed === "boolean" ? |
| 13171 | cssFn.apply( this, arguments ) : |
| 13172 | this.animate( genFx( name, true ), speed, easing, callback ); |
| 13173 | }; |
| 13174 | }); |
| 13175 | |
| 13176 | // Generate shortcuts for custom animations |
| 13177 | jQuery.each({ |
| 13178 | slideDown: genFx("show"), |
| 13179 | slideUp: genFx("hide"), |
| 13180 | slideToggle: genFx("toggle"), |
| 13181 | fadeIn: { opacity: "show" }, |
| 13182 | fadeOut: { opacity: "hide" }, |
| 13183 | fadeToggle: { opacity: "toggle" } |
| 13184 | }, function( name, props ) { |
| 13185 | jQuery.fn[ name ] = function( speed, easing, callback ) { |
| 13186 | return this.animate( props, speed, easing, callback ); |
| 13187 | }; |
| 13188 | }); |
| 13189 | |
| 13190 | jQuery.timers = []; |
| 13191 | jQuery.fx.tick = function() { |
| 13192 | var timer, |
| 13193 | i = 0, |
| 13194 | timers = jQuery.timers; |
| 13195 | |
| 13196 | fxNow = jQuery.now(); |
| 13197 | |
| 13198 | for ( ; i < timers.length; i++ ) { |
| 13199 | timer = timers[ i ]; |
| 13200 | // Checks the timer has not already been removed |
| 13201 | if ( !timer() && timers[ i ] === timer ) { |
| 13202 | timers.splice( i--, 1 ); |
| 13203 | } |
| 13204 | } |
| 13205 | |
| 13206 | if ( !timers.length ) { |
| 13207 | jQuery.fx.stop(); |
| 13208 | } |
| 13209 | fxNow = undefined; |
| 13210 | }; |
| 13211 | |
| 13212 | jQuery.fx.timer = function( timer ) { |
| 13213 | jQuery.timers.push( timer ); |
| 13214 | if ( timer() ) { |
| 13215 | jQuery.fx.start(); |
| 13216 | } else { |
| 13217 | jQuery.timers.pop(); |
| 13218 | } |
| 13219 | }; |
| 13220 | |
| 13221 | jQuery.fx.interval = 13; |
| 13222 | |
| 13223 | jQuery.fx.start = function() { |
| 13224 | if ( !timerId ) { |
| 13225 | timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval ); |
| 13226 | } |
| 13227 | }; |
| 13228 | |
| 13229 | jQuery.fx.stop = function() { |
| 13230 | clearInterval( timerId ); |
| 13231 | timerId = null; |
| 13232 | }; |
| 13233 | |
| 13234 | jQuery.fx.speeds = { |
| 13235 | slow: 600, |
| 13236 | fast: 200, |
| 13237 | // Default speed |
| 13238 | _default: 400 |
| 13239 | }; |
| 13240 | |
| 13241 | |
| 13242 | // Based off of the plugin by Clint Helfers, with permission. |
| 13243 | // http://blindsignals.com/index.php/2009/07/jquery-delay/ |
| 13244 | jQuery.fn.delay = function( time, type ) { |
| 13245 | time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; |
| 13246 | type = type || "fx"; |
| 13247 | |
| 13248 | return this.queue( type, function( next, hooks ) { |
| 13249 | var timeout = setTimeout( next, time ); |
| 13250 | hooks.stop = function() { |
| 13251 | clearTimeout( timeout ); |
| 13252 | }; |
| 13253 | }); |
| 13254 | }; |
| 13255 | |
| 13256 | |
| 13257 | (function() { |
| 13258 | var input = document.createElement( "input" ), |
| 13259 | select = document.createElement( "select" ), |
| 13260 | opt = select.appendChild( document.createElement( "option" ) ); |
| 13261 | |
| 13262 | input.type = "checkbox"; |
| 13263 | |
| 13264 | // Support: iOS<=5.1, Android<=4.2+ |
| 13265 | // Default value for a checkbox should be "on" |
| 13266 | support.checkOn = input.value !== ""; |
| 13267 | |
| 13268 | // Support: IE<=11+ |
| 13269 | // Must access selectedIndex to make default options select |
| 13270 | support.optSelected = opt.selected; |
| 13271 | |
| 13272 | // Support: Android<=2.3 |
| 13273 | // Options inside disabled selects are incorrectly marked as disabled |
| 13274 | select.disabled = true; |
| 13275 | support.optDisabled = !opt.disabled; |
| 13276 | |
| 13277 | // Support: IE<=11+ |
| 13278 | // An input loses its value after becoming a radio |
| 13279 | input = document.createElement( "input" ); |
| 13280 | input.value = "t"; |
| 13281 | input.type = "radio"; |
| 13282 | support.radioValue = input.value === "t"; |
| 13283 | })(); |
| 13284 | |
| 13285 | |
| 13286 | var nodeHook, boolHook, |
| 13287 | attrHandle = jQuery.expr.attrHandle; |
| 13288 | |
| 13289 | jQuery.fn.extend({ |
| 13290 | attr: function( name, value ) { |
| 13291 | return access( this, jQuery.attr, name, value, arguments.length > 1 ); |
| 13292 | }, |
| 13293 | |
| 13294 | removeAttr: function( name ) { |
| 13295 | return this.each(function() { |
| 13296 | jQuery.removeAttr( this, name ); |
| 13297 | }); |
| 13298 | } |
| 13299 | }); |
| 13300 | |
| 13301 | jQuery.extend({ |
| 13302 | attr: function( elem, name, value ) { |
| 13303 | var hooks, ret, |
| 13304 | nType = elem.nodeType; |
| 13305 | |
| 13306 | // don't get/set attributes on text, comment and attribute nodes |
| 13307 | if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { |
| 13308 | return; |
| 13309 | } |
| 13310 | |
| 13311 | // Fallback to prop when attributes are not supported |
| 13312 | if ( typeof elem.getAttribute === strundefined ) { |
| 13313 | return jQuery.prop( elem, name, value ); |
| 13314 | } |
| 13315 | |
| 13316 | // All attributes are lowercase |
| 13317 | // Grab necessary hook if one is defined |
| 13318 | if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { |
| 13319 | name = name.toLowerCase(); |
| 13320 | hooks = jQuery.attrHooks[ name ] || |
| 13321 | ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook ); |
| 13322 | } |
| 13323 | |
| 13324 | if ( value !== undefined ) { |
| 13325 | |
| 13326 | if ( value === null ) { |
| 13327 | jQuery.removeAttr( elem, name ); |
| 13328 | |
| 13329 | } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { |
| 13330 | return ret; |
| 13331 | |
| 13332 | } else { |
| 13333 | elem.setAttribute( name, value + "" ); |
| 13334 | return value; |
| 13335 | } |
| 13336 | |
| 13337 | } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { |
| 13338 | return ret; |
| 13339 | |
| 13340 | } else { |
| 13341 | ret = jQuery.find.attr( elem, name ); |
| 13342 | |
| 13343 | // Non-existent attributes return null, we normalize to undefined |
| 13344 | return ret == null ? |
| 13345 | undefined : |
| 13346 | ret; |
| 13347 | } |
| 13348 | }, |
| 13349 | |
| 13350 | removeAttr: function( elem, value ) { |
| 13351 | var name, propName, |
| 13352 | i = 0, |
| 13353 | attrNames = value && value.match( rnotwhite ); |
| 13354 | |
| 13355 | if ( attrNames && elem.nodeType === 1 ) { |
| 13356 | while ( (name = attrNames[i++]) ) { |
| 13357 | propName = jQuery.propFix[ name ] || name; |
| 13358 | |
| 13359 | // Boolean attributes get special treatment (#10870) |
| 13360 | if ( jQuery.expr.match.bool.test( name ) ) { |
| 13361 | // Set corresponding property to false |
| 13362 | elem[ propName ] = false; |
| 13363 | } |
| 13364 | |
| 13365 | elem.removeAttribute( name ); |
| 13366 | } |
| 13367 | } |
| 13368 | }, |
| 13369 | |
| 13370 | attrHooks: { |
| 13371 | type: { |
| 13372 | set: function( elem, value ) { |
| 13373 | if ( !support.radioValue && value === "radio" && |
| 13374 | jQuery.nodeName( elem, "input" ) ) { |
| 13375 | var val = elem.value; |
| 13376 | elem.setAttribute( "type", value ); |
| 13377 | if ( val ) { |
| 13378 | elem.value = val; |
| 13379 | } |
| 13380 | return value; |
| 13381 | } |
| 13382 | } |
| 13383 | } |
| 13384 | } |
| 13385 | }); |
| 13386 | |
| 13387 | // Hooks for boolean attributes |
| 13388 | boolHook = { |
| 13389 | set: function( elem, value, name ) { |
| 13390 | if ( value === false ) { |
| 13391 | // Remove boolean attributes when set to false |
| 13392 | jQuery.removeAttr( elem, name ); |
| 13393 | } else { |
| 13394 | elem.setAttribute( name, name ); |
| 13395 | } |
| 13396 | return name; |
| 13397 | } |
| 13398 | }; |
| 13399 | jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { |
| 13400 | var getter = attrHandle[ name ] || jQuery.find.attr; |
| 13401 | |
| 13402 | attrHandle[ name ] = function( elem, name, isXML ) { |
| 13403 | var ret, handle; |
| 13404 | if ( !isXML ) { |
| 13405 | // Avoid an infinite loop by temporarily removing this function from the getter |
| 13406 | handle = attrHandle[ name ]; |
| 13407 | attrHandle[ name ] = ret; |
| 13408 | ret = getter( elem, name, isXML ) != null ? |
| 13409 | name.toLowerCase() : |
| 13410 | null; |
| 13411 | attrHandle[ name ] = handle; |
| 13412 | } |
| 13413 | return ret; |
| 13414 | }; |
| 13415 | }); |
| 13416 | |
| 13417 | |
| 13418 | |
| 13419 | |
| 13420 | var rfocusable = /^(?:input|select|textarea|button)$/i; |
| 13421 | |
| 13422 | jQuery.fn.extend({ |
| 13423 | prop: function( name, value ) { |
| 13424 | return access( this, jQuery.prop, name, value, arguments.length > 1 ); |
| 13425 | }, |
| 13426 | |
| 13427 | removeProp: function( name ) { |
| 13428 | return this.each(function() { |
| 13429 | delete this[ jQuery.propFix[ name ] || name ]; |
| 13430 | }); |
| 13431 | } |
| 13432 | }); |
| 13433 | |
| 13434 | jQuery.extend({ |
| 13435 | propFix: { |
| 13436 | "for": "htmlFor", |
| 13437 | "class": "className" |
| 13438 | }, |
| 13439 | |
| 13440 | prop: function( elem, name, value ) { |
| 13441 | var ret, hooks, notxml, |
| 13442 | nType = elem.nodeType; |
| 13443 | |
| 13444 | // Don't get/set properties on text, comment and attribute nodes |
| 13445 | if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { |
| 13446 | return; |
| 13447 | } |
| 13448 | |
| 13449 | notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); |
| 13450 | |
| 13451 | if ( notxml ) { |
| 13452 | // Fix name and attach hooks |
| 13453 | name = jQuery.propFix[ name ] || name; |
| 13454 | hooks = jQuery.propHooks[ name ]; |
| 13455 | } |
| 13456 | |
| 13457 | if ( value !== undefined ) { |
| 13458 | return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ? |
| 13459 | ret : |
| 13460 | ( elem[ name ] = value ); |
| 13461 | |
| 13462 | } else { |
| 13463 | return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ? |
| 13464 | ret : |
| 13465 | elem[ name ]; |
| 13466 | } |
| 13467 | }, |
| 13468 | |
| 13469 | propHooks: { |
| 13470 | tabIndex: { |
| 13471 | get: function( elem ) { |
| 13472 | return elem.hasAttribute( "tabindex" ) || rfocusable.test( elem.nodeName ) || elem.href ? |
| 13473 | elem.tabIndex : |
| 13474 | -1; |
| 13475 | } |
| 13476 | } |
| 13477 | } |
| 13478 | }); |
| 13479 | |
| 13480 | if ( !support.optSelected ) { |
| 13481 | jQuery.propHooks.selected = { |
| 13482 | get: function( elem ) { |
| 13483 | var parent = elem.parentNode; |
| 13484 | if ( parent && parent.parentNode ) { |
| 13485 | parent.parentNode.selectedIndex; |
| 13486 | } |
| 13487 | return null; |
| 13488 | } |
| 13489 | }; |
| 13490 | } |
| 13491 | |
| 13492 | jQuery.each([ |
| 13493 | "tabIndex", |
| 13494 | "readOnly", |
| 13495 | "maxLength", |
| 13496 | "cellSpacing", |
| 13497 | "cellPadding", |
| 13498 | "rowSpan", |
| 13499 | "colSpan", |
| 13500 | "useMap", |
| 13501 | "frameBorder", |
| 13502 | "contentEditable" |
| 13503 | ], function() { |
| 13504 | jQuery.propFix[ this.toLowerCase() ] = this; |
| 13505 | }); |
| 13506 | |
| 13507 | |
| 13508 | |
| 13509 | |
| 13510 | var rclass = /[\t\r\n\f]/g; |
| 13511 | |
| 13512 | jQuery.fn.extend({ |
| 13513 | addClass: function( value ) { |
| 13514 | var classes, elem, cur, clazz, j, finalValue, |
| 13515 | proceed = typeof value === "string" && value, |
| 13516 | i = 0, |
| 13517 | len = this.length; |
| 13518 | |
| 13519 | if ( jQuery.isFunction( value ) ) { |
| 13520 | return this.each(function( j ) { |
| 13521 | jQuery( this ).addClass( value.call( this, j, this.className ) ); |
| 13522 | }); |
| 13523 | } |
| 13524 | |
| 13525 | if ( proceed ) { |
| 13526 | // The disjunction here is for better compressibility (see removeClass) |
| 13527 | classes = ( value || "" ).match( rnotwhite ) || []; |
| 13528 | |
| 13529 | for ( ; i < len; i++ ) { |
| 13530 | elem = this[ i ]; |
| 13531 | cur = elem.nodeType === 1 && ( elem.className ? |
| 13532 | ( " " + elem.className + " " ).replace( rclass, " " ) : |
| 13533 | " " |
| 13534 | ); |
| 13535 | |
| 13536 | if ( cur ) { |
| 13537 | j = 0; |
| 13538 | while ( (clazz = classes[j++]) ) { |
| 13539 | if ( cur.indexOf( " " + clazz + " " ) < 0 ) { |
| 13540 | cur += clazz + " "; |
| 13541 | } |
| 13542 | } |
| 13543 | |
| 13544 | // only assign if different to avoid unneeded rendering. |
| 13545 | finalValue = jQuery.trim( cur ); |
| 13546 | if ( elem.className !== finalValue ) { |
| 13547 | elem.className = finalValue; |
| 13548 | } |
| 13549 | } |
| 13550 | } |
| 13551 | } |
| 13552 | |
| 13553 | return this; |
| 13554 | }, |
| 13555 | |
| 13556 | removeClass: function( value ) { |
| 13557 | var classes, elem, cur, clazz, j, finalValue, |
| 13558 | proceed = arguments.length === 0 || typeof value === "string" && value, |
| 13559 | i = 0, |
| 13560 | len = this.length; |
| 13561 | |
| 13562 | if ( jQuery.isFunction( value ) ) { |
| 13563 | return this.each(function( j ) { |
| 13564 | jQuery( this ).removeClass( value.call( this, j, this.className ) ); |
| 13565 | }); |
| 13566 | } |
| 13567 | if ( proceed ) { |
| 13568 | classes = ( value || "" ).match( rnotwhite ) || []; |
| 13569 | |
| 13570 | for ( ; i < len; i++ ) { |
| 13571 | elem = this[ i ]; |
| 13572 | // This expression is here for better compressibility (see addClass) |
| 13573 | cur = elem.nodeType === 1 && ( elem.className ? |
| 13574 | ( " " + elem.className + " " ).replace( rclass, " " ) : |
| 13575 | "" |
| 13576 | ); |
| 13577 | |
| 13578 | if ( cur ) { |
| 13579 | j = 0; |
| 13580 | while ( (clazz = classes[j++]) ) { |
| 13581 | // Remove *all* instances |
| 13582 | while ( cur.indexOf( " " + clazz + " " ) >= 0 ) { |
| 13583 | cur = cur.replace( " " + clazz + " ", " " ); |
| 13584 | } |
| 13585 | } |
| 13586 | |
| 13587 | // Only assign if different to avoid unneeded rendering. |
| 13588 | finalValue = value ? jQuery.trim( cur ) : ""; |
| 13589 | if ( elem.className !== finalValue ) { |
| 13590 | elem.className = finalValue; |
| 13591 | } |
| 13592 | } |
| 13593 | } |
| 13594 | } |
| 13595 | |
| 13596 | return this; |
| 13597 | }, |
| 13598 | |
| 13599 | toggleClass: function( value, stateVal ) { |
| 13600 | var type = typeof value; |
| 13601 | |
| 13602 | if ( typeof stateVal === "boolean" && type === "string" ) { |
| 13603 | return stateVal ? this.addClass( value ) : this.removeClass( value ); |
| 13604 | } |
| 13605 | |
| 13606 | if ( jQuery.isFunction( value ) ) { |
| 13607 | return this.each(function( i ) { |
| 13608 | jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); |
| 13609 | }); |
| 13610 | } |
| 13611 | |
| 13612 | return this.each(function() { |
| 13613 | if ( type === "string" ) { |
| 13614 | // Toggle individual class names |
| 13615 | var className, |
| 13616 | i = 0, |
| 13617 | self = jQuery( this ), |
| 13618 | classNames = value.match( rnotwhite ) || []; |
| 13619 | |
| 13620 | while ( (className = classNames[ i++ ]) ) { |
| 13621 | // Check each className given, space separated list |
| 13622 | if ( self.hasClass( className ) ) { |
| 13623 | self.removeClass( className ); |
| 13624 | } else { |
| 13625 | self.addClass( className ); |
| 13626 | } |
| 13627 | } |
| 13628 | |
| 13629 | // Toggle whole class name |
| 13630 | } else if ( type === strundefined || type === "boolean" ) { |
| 13631 | if ( this.className ) { |
| 13632 | // store className if set |
| 13633 | data_priv.set( this, "__className__", this.className ); |
| 13634 | } |
| 13635 | |
| 13636 | // If the element has a class name or if we're passed `false`, |
| 13637 | // then remove the whole classname (if there was one, the above saved it). |
| 13638 | // Otherwise bring back whatever was previously saved (if anything), |
| 13639 | // falling back to the empty string if nothing was stored. |
| 13640 | this.className = this.className || value === false ? "" : data_priv.get( this, "__className__" ) || ""; |
| 13641 | } |
| 13642 | }); |
| 13643 | }, |
| 13644 | |
| 13645 | hasClass: function( selector ) { |
| 13646 | var className = " " + selector + " ", |
| 13647 | i = 0, |
| 13648 | l = this.length; |
| 13649 | for ( ; i < l; i++ ) { |
| 13650 | if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { |
| 13651 | return true; |
| 13652 | } |
| 13653 | } |
| 13654 | |
| 13655 | return false; |
| 13656 | } |
| 13657 | }); |
| 13658 | |
| 13659 | |
| 13660 | |
| 13661 | |
| 13662 | var rreturn = /\r/g; |
| 13663 | |
| 13664 | jQuery.fn.extend({ |
| 13665 | val: function( value ) { |
| 13666 | var hooks, ret, isFunction, |
| 13667 | elem = this[0]; |
| 13668 | |
| 13669 | if ( !arguments.length ) { |
| 13670 | if ( elem ) { |
| 13671 | hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; |
| 13672 | |
| 13673 | if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { |
| 13674 | return ret; |
| 13675 | } |
| 13676 | |
| 13677 | ret = elem.value; |
| 13678 | |
| 13679 | return typeof ret === "string" ? |
| 13680 | // Handle most common string cases |
| 13681 | ret.replace(rreturn, "") : |
| 13682 | // Handle cases where value is null/undef or number |
| 13683 | ret == null ? "" : ret; |
| 13684 | } |
| 13685 | |
| 13686 | return; |
| 13687 | } |
| 13688 | |
| 13689 | isFunction = jQuery.isFunction( value ); |
| 13690 | |
| 13691 | return this.each(function( i ) { |
| 13692 | var val; |
| 13693 | |
| 13694 | if ( this.nodeType !== 1 ) { |
| 13695 | return; |
| 13696 | } |
| 13697 | |
| 13698 | if ( isFunction ) { |
| 13699 | val = value.call( this, i, jQuery( this ).val() ); |
| 13700 | } else { |
| 13701 | val = value; |
| 13702 | } |
| 13703 | |
| 13704 | // Treat null/undefined as ""; convert numbers to string |
| 13705 | if ( val == null ) { |
| 13706 | val = ""; |
| 13707 | |
| 13708 | } else if ( typeof val === "number" ) { |
| 13709 | val += ""; |
| 13710 | |
| 13711 | } else if ( jQuery.isArray( val ) ) { |
| 13712 | val = jQuery.map( val, function( value ) { |
| 13713 | return value == null ? "" : value + ""; |
| 13714 | }); |
| 13715 | } |
| 13716 | |
| 13717 | hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; |
| 13718 | |
| 13719 | // If set returns undefined, fall back to normal setting |
| 13720 | if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { |
| 13721 | this.value = val; |
| 13722 | } |
| 13723 | }); |
| 13724 | } |
| 13725 | }); |
| 13726 | |
| 13727 | jQuery.extend({ |
| 13728 | valHooks: { |
| 13729 | option: { |
| 13730 | get: function( elem ) { |
| 13731 | var val = jQuery.find.attr( elem, "value" ); |
| 13732 | return val != null ? |
| 13733 | val : |
| 13734 | // Support: IE10-11+ |
| 13735 | // option.text throws exceptions (#14686, #14858) |
| 13736 | jQuery.trim( jQuery.text( elem ) ); |
| 13737 | } |
| 13738 | }, |
| 13739 | select: { |
| 13740 | get: function( elem ) { |
| 13741 | var value, option, |
| 13742 | options = elem.options, |
| 13743 | index = elem.selectedIndex, |
| 13744 | one = elem.type === "select-one" || index < 0, |
| 13745 | values = one ? null : [], |
| 13746 | max = one ? index + 1 : options.length, |
| 13747 | i = index < 0 ? |
| 13748 | max : |
| 13749 | one ? index : 0; |
| 13750 | |
| 13751 | // Loop through all the selected options |
| 13752 | for ( ; i < max; i++ ) { |
| 13753 | option = options[ i ]; |
| 13754 | |
| 13755 | // IE6-9 doesn't update selected after form reset (#2551) |
| 13756 | if ( ( option.selected || i === index ) && |
| 13757 | // Don't return options that are disabled or in a disabled optgroup |
| 13758 | ( support.optDisabled ? !option.disabled : option.getAttribute( "disabled" ) === null ) && |
| 13759 | ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { |
| 13760 | |
| 13761 | // Get the specific value for the option |
| 13762 | value = jQuery( option ).val(); |
| 13763 | |
| 13764 | // We don't need an array for one selects |
| 13765 | if ( one ) { |
| 13766 | return value; |
| 13767 | } |
| 13768 | |
| 13769 | // Multi-Selects return an array |
| 13770 | values.push( value ); |
| 13771 | } |
| 13772 | } |
| 13773 | |
| 13774 | return values; |
| 13775 | }, |
| 13776 | |
| 13777 | set: function( elem, value ) { |
| 13778 | var optionSet, option, |
| 13779 | options = elem.options, |
| 13780 | values = jQuery.makeArray( value ), |
| 13781 | i = options.length; |
| 13782 | |
| 13783 | while ( i-- ) { |
| 13784 | option = options[ i ]; |
| 13785 | if ( (option.selected = jQuery.inArray( option.value, values ) >= 0) ) { |
| 13786 | optionSet = true; |
| 13787 | } |
| 13788 | } |
| 13789 | |
| 13790 | // Force browsers to behave consistently when non-matching value is set |
| 13791 | if ( !optionSet ) { |
| 13792 | elem.selectedIndex = -1; |
| 13793 | } |
| 13794 | return values; |
| 13795 | } |
| 13796 | } |
| 13797 | } |
| 13798 | }); |
| 13799 | |
| 13800 | // Radios and checkboxes getter/setter |
| 13801 | jQuery.each([ "radio", "checkbox" ], function() { |
| 13802 | jQuery.valHooks[ this ] = { |
| 13803 | set: function( elem, value ) { |
| 13804 | if ( jQuery.isArray( value ) ) { |
| 13805 | return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); |
| 13806 | } |
| 13807 | } |
| 13808 | }; |
| 13809 | if ( !support.checkOn ) { |
| 13810 | jQuery.valHooks[ this ].get = function( elem ) { |
| 13811 | return elem.getAttribute("value") === null ? "on" : elem.value; |
| 13812 | }; |
| 13813 | } |
| 13814 | }); |
| 13815 | |
| 13816 | |
| 13817 | |
| 13818 | |
| 13819 | // Return jQuery for attributes-only inclusion |
| 13820 | |
| 13821 | |
| 13822 | jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + |
| 13823 | "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + |
| 13824 | "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { |
| 13825 | |
| 13826 | // Handle event binding |
| 13827 | jQuery.fn[ name ] = function( data, fn ) { |
| 13828 | return arguments.length > 0 ? |
| 13829 | this.on( name, null, data, fn ) : |
| 13830 | this.trigger( name ); |
| 13831 | }; |
| 13832 | }); |
| 13833 | |
| 13834 | jQuery.fn.extend({ |
| 13835 | hover: function( fnOver, fnOut ) { |
| 13836 | return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); |
| 13837 | }, |
| 13838 | |
| 13839 | bind: function( types, data, fn ) { |
| 13840 | return this.on( types, null, data, fn ); |
| 13841 | }, |
| 13842 | unbind: function( types, fn ) { |
| 13843 | return this.off( types, null, fn ); |
| 13844 | }, |
| 13845 | |
| 13846 | delegate: function( selector, types, data, fn ) { |
| 13847 | return this.on( types, selector, data, fn ); |
| 13848 | }, |
| 13849 | undelegate: function( selector, types, fn ) { |
| 13850 | // ( namespace ) or ( selector, types [, fn] ) |
| 13851 | return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); |
| 13852 | } |
| 13853 | }); |
| 13854 | |
| 13855 | |
| 13856 | var nonce = jQuery.now(); |
| 13857 | |
| 13858 | var rquery = (/\?/); |
| 13859 | |
| 13860 | |
| 13861 | |
| 13862 | // Support: Android 2.3 |
| 13863 | // Workaround failure to string-cast null input |
| 13864 | jQuery.parseJSON = function( data ) { |
| 13865 | return JSON.parse( data + "" ); |
| 13866 | }; |
| 13867 | |
| 13868 | |
| 13869 | // Cross-browser xml parsing |
| 13870 | jQuery.parseXML = function( data ) { |
| 13871 | var xml, tmp; |
| 13872 | if ( !data || typeof data !== "string" ) { |
| 13873 | return null; |
| 13874 | } |
| 13875 | |
| 13876 | // Support: IE9 |
| 13877 | try { |
| 13878 | tmp = new DOMParser(); |
| 13879 | xml = tmp.parseFromString( data, "text/xml" ); |
| 13880 | } catch ( e ) { |
| 13881 | xml = undefined; |
| 13882 | } |
| 13883 | |
| 13884 | if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { |
| 13885 | jQuery.error( "Invalid XML: " + data ); |
| 13886 | } |
| 13887 | return xml; |
| 13888 | }; |
| 13889 | |
| 13890 | |
| 13891 | var |
| 13892 | rhash = /#.*$/, |
| 13893 | rts = /([?&])_=[^&]*/, |
| 13894 | rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, |
| 13895 | // #7653, #8125, #8152: local protocol detection |
| 13896 | rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, |
| 13897 | rnoContent = /^(?:GET|HEAD)$/, |
| 13898 | rprotocol = /^\/\//, |
| 13899 | rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/, |
| 13900 | |
| 13901 | /* Prefilters |
| 13902 | * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) |
| 13903 | * 2) These are called: |
| 13904 | * - BEFORE asking for a transport |
| 13905 | * - AFTER param serialization (s.data is a string if s.processData is true) |
| 13906 | * 3) key is the dataType |
| 13907 | * 4) the catchall symbol "*" can be used |
| 13908 | * 5) execution will start with transport dataType and THEN continue down to "*" if needed |
| 13909 | */ |
| 13910 | prefilters = {}, |
| 13911 | |
| 13912 | /* Transports bindings |
| 13913 | * 1) key is the dataType |
| 13914 | * 2) the catchall symbol "*" can be used |
| 13915 | * 3) selection will start with transport dataType and THEN go to "*" if needed |
| 13916 | */ |
| 13917 | transports = {}, |
| 13918 | |
| 13919 | // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression |
| 13920 | allTypes = "*/".concat( "*" ), |
| 13921 | |
| 13922 | // Document location |
| 13923 | ajaxLocation = window.location.href, |
| 13924 | |
| 13925 | // Segment location into parts |
| 13926 | ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; |
| 13927 | |
| 13928 | // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport |
| 13929 | function addToPrefiltersOrTransports( structure ) { |
| 13930 | |
| 13931 | // dataTypeExpression is optional and defaults to "*" |
| 13932 | return function( dataTypeExpression, func ) { |
| 13933 | |
| 13934 | if ( typeof dataTypeExpression !== "string" ) { |
| 13935 | func = dataTypeExpression; |
| 13936 | dataTypeExpression = "*"; |
| 13937 | } |
| 13938 | |
| 13939 | var dataType, |
| 13940 | i = 0, |
| 13941 | dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || []; |
| 13942 | |
| 13943 | if ( jQuery.isFunction( func ) ) { |
| 13944 | // For each dataType in the dataTypeExpression |
| 13945 | while ( (dataType = dataTypes[i++]) ) { |
| 13946 | // Prepend if requested |
| 13947 | if ( dataType[0] === "+" ) { |
| 13948 | dataType = dataType.slice( 1 ) || "*"; |
| 13949 | (structure[ dataType ] = structure[ dataType ] || []).unshift( func ); |
| 13950 | |
| 13951 | // Otherwise append |
| 13952 | } else { |
| 13953 | (structure[ dataType ] = structure[ dataType ] || []).push( func ); |
| 13954 | } |
| 13955 | } |
| 13956 | } |
| 13957 | }; |
| 13958 | } |
| 13959 | |
| 13960 | // Base inspection function for prefilters and transports |
| 13961 | function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { |
| 13962 | |
| 13963 | var inspected = {}, |
| 13964 | seekingTransport = ( structure === transports ); |
| 13965 | |
| 13966 | function inspect( dataType ) { |
| 13967 | var selected; |
| 13968 | inspected[ dataType ] = true; |
| 13969 | jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { |
| 13970 | var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); |
| 13971 | if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) { |
| 13972 | options.dataTypes.unshift( dataTypeOrTransport ); |
| 13973 | inspect( dataTypeOrTransport ); |
| 13974 | return false; |
| 13975 | } else if ( seekingTransport ) { |
| 13976 | return !( selected = dataTypeOrTransport ); |
| 13977 | } |
| 13978 | }); |
| 13979 | return selected; |
| 13980 | } |
| 13981 | |
| 13982 | return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); |
| 13983 | } |
| 13984 | |
| 13985 | // A special extend for ajax options |
| 13986 | // that takes "flat" options (not to be deep extended) |
| 13987 | // Fixes #9887 |
| 13988 | function ajaxExtend( target, src ) { |
| 13989 | var key, deep, |
| 13990 | flatOptions = jQuery.ajaxSettings.flatOptions || {}; |
| 13991 | |
| 13992 | for ( key in src ) { |
| 13993 | if ( src[ key ] !== undefined ) { |
| 13994 | ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ]; |
| 13995 | } |
| 13996 | } |
| 13997 | if ( deep ) { |
| 13998 | jQuery.extend( true, target, deep ); |
| 13999 | } |
| 14000 | |
| 14001 | return target; |
| 14002 | } |
| 14003 | |
| 14004 | /* Handles responses to an ajax request: |
| 14005 | * - finds the right dataType (mediates between content-type and expected dataType) |
| 14006 | * - returns the corresponding response |
| 14007 | */ |
| 14008 | function ajaxHandleResponses( s, jqXHR, responses ) { |
| 14009 | |
| 14010 | var ct, type, finalDataType, firstDataType, |
| 14011 | contents = s.contents, |
| 14012 | dataTypes = s.dataTypes; |
| 14013 | |
| 14014 | // Remove auto dataType and get content-type in the process |
| 14015 | while ( dataTypes[ 0 ] === "*" ) { |
| 14016 | dataTypes.shift(); |
| 14017 | if ( ct === undefined ) { |
| 14018 | ct = s.mimeType || jqXHR.getResponseHeader("Content-Type"); |
| 14019 | } |
| 14020 | } |
| 14021 | |
| 14022 | // Check if we're dealing with a known content-type |
| 14023 | if ( ct ) { |
| 14024 | for ( type in contents ) { |
| 14025 | if ( contents[ type ] && contents[ type ].test( ct ) ) { |
| 14026 | dataTypes.unshift( type ); |
| 14027 | break; |
| 14028 | } |
| 14029 | } |
| 14030 | } |
| 14031 | |
| 14032 | // Check to see if we have a response for the expected dataType |
| 14033 | if ( dataTypes[ 0 ] in responses ) { |
| 14034 | finalDataType = dataTypes[ 0 ]; |
| 14035 | } else { |
| 14036 | // Try convertible dataTypes |
| 14037 | for ( type in responses ) { |
| 14038 | if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) { |
| 14039 | finalDataType = type; |
| 14040 | break; |
| 14041 | } |
| 14042 | if ( !firstDataType ) { |
| 14043 | firstDataType = type; |
| 14044 | } |
| 14045 | } |
| 14046 | // Or just use first one |
| 14047 | finalDataType = finalDataType || firstDataType; |
| 14048 | } |
| 14049 | |
| 14050 | // If we found a dataType |
| 14051 | // We add the dataType to the list if needed |
| 14052 | // and return the corresponding response |
| 14053 | if ( finalDataType ) { |
| 14054 | if ( finalDataType !== dataTypes[ 0 ] ) { |
| 14055 | dataTypes.unshift( finalDataType ); |
| 14056 | } |
| 14057 | return responses[ finalDataType ]; |
| 14058 | } |
| 14059 | } |
| 14060 | |
| 14061 | /* Chain conversions given the request and the original response |
| 14062 | * Also sets the responseXXX fields on the jqXHR instance |
| 14063 | */ |
| 14064 | function ajaxConvert( s, response, jqXHR, isSuccess ) { |
| 14065 | var conv2, current, conv, tmp, prev, |
| 14066 | converters = {}, |
| 14067 | // Work with a copy of dataTypes in case we need to modify it for conversion |
| 14068 | dataTypes = s.dataTypes.slice(); |
| 14069 | |
| 14070 | // Create converters map with lowercased keys |
| 14071 | if ( dataTypes[ 1 ] ) { |
| 14072 | for ( conv in s.converters ) { |
| 14073 | converters[ conv.toLowerCase() ] = s.converters[ conv ]; |
| 14074 | } |
| 14075 | } |
| 14076 | |
| 14077 | current = dataTypes.shift(); |
| 14078 | |
| 14079 | // Convert to each sequential dataType |
| 14080 | while ( current ) { |
| 14081 | |
| 14082 | if ( s.responseFields[ current ] ) { |
| 14083 | jqXHR[ s.responseFields[ current ] ] = response; |
| 14084 | } |
| 14085 | |
| 14086 | // Apply the dataFilter if provided |
| 14087 | if ( !prev && isSuccess && s.dataFilter ) { |
| 14088 | response = s.dataFilter( response, s.dataType ); |
| 14089 | } |
| 14090 | |
| 14091 | prev = current; |
| 14092 | current = dataTypes.shift(); |
| 14093 | |
| 14094 | if ( current ) { |
| 14095 | |
| 14096 | // There's only work to do if current dataType is non-auto |
| 14097 | if ( current === "*" ) { |
| 14098 | |
| 14099 | current = prev; |
| 14100 | |
| 14101 | // Convert response if prev dataType is non-auto and differs from current |
| 14102 | } else if ( prev !== "*" && prev !== current ) { |
| 14103 | |
| 14104 | // Seek a direct converter |
| 14105 | conv = converters[ prev + " " + current ] || converters[ "* " + current ]; |
| 14106 | |
| 14107 | // If none found, seek a pair |
| 14108 | if ( !conv ) { |
| 14109 | for ( conv2 in converters ) { |
| 14110 | |
| 14111 | // If conv2 outputs current |
| 14112 | tmp = conv2.split( " " ); |
| 14113 | if ( tmp[ 1 ] === current ) { |
| 14114 | |
| 14115 | // If prev can be converted to accepted input |
| 14116 | conv = converters[ prev + " " + tmp[ 0 ] ] || |
| 14117 | converters[ "* " + tmp[ 0 ] ]; |
| 14118 | if ( conv ) { |
| 14119 | // Condense equivalence converters |
| 14120 | if ( conv === true ) { |
| 14121 | conv = converters[ conv2 ]; |
| 14122 | |
| 14123 | // Otherwise, insert the intermediate dataType |
| 14124 | } else if ( converters[ conv2 ] !== true ) { |
| 14125 | current = tmp[ 0 ]; |
| 14126 | dataTypes.unshift( tmp[ 1 ] ); |
| 14127 | } |
| 14128 | break; |
| 14129 | } |
| 14130 | } |
| 14131 | } |
| 14132 | } |
| 14133 | |
| 14134 | // Apply converter (if not an equivalence) |
| 14135 | if ( conv !== true ) { |
| 14136 | |
| 14137 | // Unless errors are allowed to bubble, catch and return them |
| 14138 | if ( conv && s[ "throws" ] ) { |
| 14139 | response = conv( response ); |
| 14140 | } else { |
| 14141 | try { |
| 14142 | response = conv( response ); |
| 14143 | } catch ( e ) { |
| 14144 | return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; |
| 14145 | } |
| 14146 | } |
| 14147 | } |
| 14148 | } |
| 14149 | } |
| 14150 | } |
| 14151 | |
| 14152 | return { state: "success", data: response }; |
| 14153 | } |
| 14154 | |
| 14155 | jQuery.extend({ |
| 14156 | |
| 14157 | // Counter for holding the number of active queries |
| 14158 | active: 0, |
| 14159 | |
| 14160 | // Last-Modified header cache for next request |
| 14161 | lastModified: {}, |
| 14162 | etag: {}, |
| 14163 | |
| 14164 | ajaxSettings: { |
| 14165 | url: ajaxLocation, |
| 14166 | type: "GET", |
| 14167 | isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), |
| 14168 | global: true, |
| 14169 | processData: true, |
| 14170 | async: true, |
| 14171 | contentType: "application/x-www-form-urlencoded; charset=UTF-8", |
| 14172 | /* |
| 14173 | timeout: 0, |
| 14174 | data: null, |
| 14175 | dataType: null, |
| 14176 | username: null, |
| 14177 | password: null, |
| 14178 | cache: null, |
| 14179 | throws: false, |
| 14180 | traditional: false, |
| 14181 | headers: {}, |
| 14182 | */ |
| 14183 | |
| 14184 | accepts: { |
| 14185 | "*": allTypes, |
| 14186 | text: "text/plain", |
| 14187 | html: "text/html", |
| 14188 | xml: "application/xml, text/xml", |
| 14189 | json: "application/json, text/javascript" |
| 14190 | }, |
| 14191 | |
| 14192 | contents: { |
| 14193 | xml: /xml/, |
| 14194 | html: /html/, |
| 14195 | json: /json/ |
| 14196 | }, |
| 14197 | |
| 14198 | responseFields: { |
| 14199 | xml: "responseXML", |
| 14200 | text: "responseText", |
| 14201 | json: "responseJSON" |
| 14202 | }, |
| 14203 | |
| 14204 | // Data converters |
| 14205 | // Keys separate source (or catchall "*") and destination types with a single space |
| 14206 | converters: { |
| 14207 | |
| 14208 | // Convert anything to text |
| 14209 | "* text": String, |
| 14210 | |
| 14211 | // Text to html (true = no transformation) |
| 14212 | "text html": true, |
| 14213 | |
| 14214 | // Evaluate text as a json expression |
| 14215 | "text json": jQuery.parseJSON, |
| 14216 | |
| 14217 | // Parse text as xml |
| 14218 | "text xml": jQuery.parseXML |
| 14219 | }, |
| 14220 | |
| 14221 | // For options that shouldn't be deep extended: |
| 14222 | // you can add your own custom options here if |
| 14223 | // and when you create one that shouldn't be |
| 14224 | // deep extended (see ajaxExtend) |
| 14225 | flatOptions: { |
| 14226 | url: true, |
| 14227 | context: true |
| 14228 | } |
| 14229 | }, |
| 14230 | |
| 14231 | // Creates a full fledged settings object into target |
| 14232 | // with both ajaxSettings and settings fields. |
| 14233 | // If target is omitted, writes into ajaxSettings. |
| 14234 | ajaxSetup: function( target, settings ) { |
| 14235 | return settings ? |
| 14236 | |
| 14237 | // Building a settings object |
| 14238 | ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : |
| 14239 | |
| 14240 | // Extending ajaxSettings |
| 14241 | ajaxExtend( jQuery.ajaxSettings, target ); |
| 14242 | }, |
| 14243 | |
| 14244 | ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), |
| 14245 | ajaxTransport: addToPrefiltersOrTransports( transports ), |
| 14246 | |
| 14247 | // Main method |
| 14248 | ajax: function( url, options ) { |
| 14249 | |
| 14250 | // If url is an object, simulate pre-1.5 signature |
| 14251 | if ( typeof url === "object" ) { |
| 14252 | options = url; |
| 14253 | url = undefined; |
| 14254 | } |
| 14255 | |
| 14256 | // Force options to be an object |
| 14257 | options = options || {}; |
| 14258 | |
| 14259 | var transport, |
| 14260 | // URL without anti-cache param |
| 14261 | cacheURL, |
| 14262 | // Response headers |
| 14263 | responseHeadersString, |
| 14264 | responseHeaders, |
| 14265 | // timeout handle |
| 14266 | timeoutTimer, |
| 14267 | // Cross-domain detection vars |
| 14268 | parts, |
| 14269 | // To know if global events are to be dispatched |
| 14270 | fireGlobals, |
| 14271 | // Loop variable |
| 14272 | i, |
| 14273 | // Create the final options object |
| 14274 | s = jQuery.ajaxSetup( {}, options ), |
| 14275 | // Callbacks context |
| 14276 | callbackContext = s.context || s, |
| 14277 | // Context for global events is callbackContext if it is a DOM node or jQuery collection |
| 14278 | globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ? |
| 14279 | jQuery( callbackContext ) : |
| 14280 | jQuery.event, |
| 14281 | // Deferreds |
| 14282 | deferred = jQuery.Deferred(), |
| 14283 | completeDeferred = jQuery.Callbacks("once memory"), |
| 14284 | // Status-dependent callbacks |
| 14285 | statusCode = s.statusCode || {}, |
| 14286 | // Headers (they are sent all at once) |
| 14287 | requestHeaders = {}, |
| 14288 | requestHeadersNames = {}, |
| 14289 | // The jqXHR state |
| 14290 | state = 0, |
| 14291 | // Default abort message |
| 14292 | strAbort = "canceled", |
| 14293 | // Fake xhr |
| 14294 | jqXHR = { |
| 14295 | readyState: 0, |
| 14296 | |
| 14297 | // Builds headers hashtable if needed |
| 14298 | getResponseHeader: function( key ) { |
| 14299 | var match; |
| 14300 | if ( state === 2 ) { |
| 14301 | if ( !responseHeaders ) { |
| 14302 | responseHeaders = {}; |
| 14303 | while ( (match = rheaders.exec( responseHeadersString )) ) { |
| 14304 | responseHeaders[ match[1].toLowerCase() ] = match[ 2 ]; |
| 14305 | } |
| 14306 | } |
| 14307 | match = responseHeaders[ key.toLowerCase() ]; |
| 14308 | } |
| 14309 | return match == null ? null : match; |
| 14310 | }, |
| 14311 | |
| 14312 | // Raw string |
| 14313 | getAllResponseHeaders: function() { |
| 14314 | return state === 2 ? responseHeadersString : null; |
| 14315 | }, |
| 14316 | |
| 14317 | // Caches the header |
| 14318 | setRequestHeader: function( name, value ) { |
| 14319 | var lname = name.toLowerCase(); |
| 14320 | if ( !state ) { |
| 14321 | name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; |
| 14322 | requestHeaders[ name ] = value; |
| 14323 | } |
| 14324 | return this; |
| 14325 | }, |
| 14326 | |
| 14327 | // Overrides response content-type header |
| 14328 | overrideMimeType: function( type ) { |
| 14329 | if ( !state ) { |
| 14330 | s.mimeType = type; |
| 14331 | } |
| 14332 | return this; |
| 14333 | }, |
| 14334 | |
| 14335 | // Status-dependent callbacks |
| 14336 | statusCode: function( map ) { |
| 14337 | var code; |
| 14338 | if ( map ) { |
| 14339 | if ( state < 2 ) { |
| 14340 | for ( code in map ) { |
| 14341 | // Lazy-add the new callback in a way that preserves old ones |
| 14342 | statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; |
| 14343 | } |
| 14344 | } else { |
| 14345 | // Execute the appropriate callbacks |
| 14346 | jqXHR.always( map[ jqXHR.status ] ); |
| 14347 | } |
| 14348 | } |
| 14349 | return this; |
| 14350 | }, |
| 14351 | |
| 14352 | // Cancel the request |
| 14353 | abort: function( statusText ) { |
| 14354 | var finalText = statusText || strAbort; |
| 14355 | if ( transport ) { |
| 14356 | transport.abort( finalText ); |
| 14357 | } |
| 14358 | done( 0, finalText ); |
| 14359 | return this; |
| 14360 | } |
| 14361 | }; |
| 14362 | |
| 14363 | // Attach deferreds |
| 14364 | deferred.promise( jqXHR ).complete = completeDeferred.add; |
| 14365 | jqXHR.success = jqXHR.done; |
| 14366 | jqXHR.error = jqXHR.fail; |
| 14367 | |
| 14368 | // Remove hash character (#7531: and string promotion) |
| 14369 | // Add protocol if not provided (prefilters might expect it) |
| 14370 | // Handle falsy url in the settings object (#10093: consistency with old signature) |
| 14371 | // We also use the url parameter if available |
| 14372 | s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ) |
| 14373 | .replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); |
| 14374 | |
| 14375 | // Alias method option to type as per ticket #12004 |
| 14376 | s.type = options.method || options.type || s.method || s.type; |
| 14377 | |
| 14378 | // Extract dataTypes list |
| 14379 | s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ]; |
| 14380 | |
| 14381 | // A cross-domain request is in order when we have a protocol:host:port mismatch |
| 14382 | if ( s.crossDomain == null ) { |
| 14383 | parts = rurl.exec( s.url.toLowerCase() ); |
| 14384 | s.crossDomain = !!( parts && |
| 14385 | ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] || |
| 14386 | ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !== |
| 14387 | ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) ) |
| 14388 | ); |
| 14389 | } |
| 14390 | |
| 14391 | // Convert data if not already a string |
| 14392 | if ( s.data && s.processData && typeof s.data !== "string" ) { |
| 14393 | s.data = jQuery.param( s.data, s.traditional ); |
| 14394 | } |
| 14395 | |
| 14396 | // Apply prefilters |
| 14397 | inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); |
| 14398 | |
| 14399 | // If request was aborted inside a prefilter, stop there |
| 14400 | if ( state === 2 ) { |
| 14401 | return jqXHR; |
| 14402 | } |
| 14403 | |
| 14404 | // We can fire global events as of now if asked to |
| 14405 | // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) |
| 14406 | fireGlobals = jQuery.event && s.global; |
| 14407 | |
| 14408 | // Watch for a new set of requests |
| 14409 | if ( fireGlobals && jQuery.active++ === 0 ) { |
| 14410 | jQuery.event.trigger("ajaxStart"); |
| 14411 | } |
| 14412 | |
| 14413 | // Uppercase the type |
| 14414 | s.type = s.type.toUpperCase(); |
| 14415 | |
| 14416 | // Determine if request has content |
| 14417 | s.hasContent = !rnoContent.test( s.type ); |
| 14418 | |
| 14419 | // Save the URL in case we're toying with the If-Modified-Since |
| 14420 | // and/or If-None-Match header later on |
| 14421 | cacheURL = s.url; |
| 14422 | |
| 14423 | // More options handling for requests with no content |
| 14424 | if ( !s.hasContent ) { |
| 14425 | |
| 14426 | // If data is available, append data to url |
| 14427 | if ( s.data ) { |
| 14428 | cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data ); |
| 14429 | // #9682: remove data so that it's not used in an eventual retry |
| 14430 | delete s.data; |
| 14431 | } |
| 14432 | |
| 14433 | // Add anti-cache in url if needed |
| 14434 | if ( s.cache === false ) { |
| 14435 | s.url = rts.test( cacheURL ) ? |
| 14436 | |
| 14437 | // If there is already a '_' parameter, set its value |
| 14438 | cacheURL.replace( rts, "$1_=" + nonce++ ) : |
| 14439 | |
| 14440 | // Otherwise add one to the end |
| 14441 | cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++; |
| 14442 | } |
| 14443 | } |
| 14444 | |
| 14445 | // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. |
| 14446 | if ( s.ifModified ) { |
| 14447 | if ( jQuery.lastModified[ cacheURL ] ) { |
| 14448 | jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); |
| 14449 | } |
| 14450 | if ( jQuery.etag[ cacheURL ] ) { |
| 14451 | jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); |
| 14452 | } |
| 14453 | } |
| 14454 | |
| 14455 | // Set the correct header, if data is being sent |
| 14456 | if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { |
| 14457 | jqXHR.setRequestHeader( "Content-Type", s.contentType ); |
| 14458 | } |
| 14459 | |
| 14460 | // Set the Accepts header for the server, depending on the dataType |
| 14461 | jqXHR.setRequestHeader( |
| 14462 | "Accept", |
| 14463 | s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? |
| 14464 | s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : |
| 14465 | s.accepts[ "*" ] |
| 14466 | ); |
| 14467 | |
| 14468 | // Check for headers option |
| 14469 | for ( i in s.headers ) { |
| 14470 | jqXHR.setRequestHeader( i, s.headers[ i ] ); |
| 14471 | } |
| 14472 | |
| 14473 | // Allow custom headers/mimetypes and early abort |
| 14474 | if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { |
| 14475 | // Abort if not done already and return |
| 14476 | return jqXHR.abort(); |
| 14477 | } |
| 14478 | |
| 14479 | // Aborting is no longer a cancellation |
| 14480 | strAbort = "abort"; |
| 14481 | |
| 14482 | // Install callbacks on deferreds |
| 14483 | for ( i in { success: 1, error: 1, complete: 1 } ) { |
| 14484 | jqXHR[ i ]( s[ i ] ); |
| 14485 | } |
| 14486 | |
| 14487 | // Get transport |
| 14488 | transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); |
| 14489 | |
| 14490 | // If no transport, we auto-abort |
| 14491 | if ( !transport ) { |
| 14492 | done( -1, "No Transport" ); |
| 14493 | } else { |
| 14494 | jqXHR.readyState = 1; |
| 14495 | |
| 14496 | // Send global event |
| 14497 | if ( fireGlobals ) { |
| 14498 | globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); |
| 14499 | } |
| 14500 | // Timeout |
| 14501 | if ( s.async && s.timeout > 0 ) { |
| 14502 | timeoutTimer = setTimeout(function() { |
| 14503 | jqXHR.abort("timeout"); |
| 14504 | }, s.timeout ); |
| 14505 | } |
| 14506 | |
| 14507 | try { |
| 14508 | state = 1; |
| 14509 | transport.send( requestHeaders, done ); |
| 14510 | } catch ( e ) { |
| 14511 | // Propagate exception as error if not done |
| 14512 | if ( state < 2 ) { |
| 14513 | done( -1, e ); |
| 14514 | // Simply rethrow otherwise |
| 14515 | } else { |
| 14516 | throw e; |
| 14517 | } |
| 14518 | } |
| 14519 | } |
| 14520 | |
| 14521 | // Callback for when everything is done |
| 14522 | function done( status, nativeStatusText, responses, headers ) { |
| 14523 | var isSuccess, success, error, response, modified, |
| 14524 | statusText = nativeStatusText; |
| 14525 | |
| 14526 | // Called once |
| 14527 | if ( state === 2 ) { |
| 14528 | return; |
| 14529 | } |
| 14530 | |
| 14531 | // State is "done" now |
| 14532 | state = 2; |
| 14533 | |
| 14534 | // Clear timeout if it exists |
| 14535 | if ( timeoutTimer ) { |
| 14536 | clearTimeout( timeoutTimer ); |
| 14537 | } |
| 14538 | |
| 14539 | // Dereference transport for early garbage collection |
| 14540 | // (no matter how long the jqXHR object will be used) |
| 14541 | transport = undefined; |
| 14542 | |
| 14543 | // Cache response headers |
| 14544 | responseHeadersString = headers || ""; |
| 14545 | |
| 14546 | // Set readyState |
| 14547 | jqXHR.readyState = status > 0 ? 4 : 0; |
| 14548 | |
| 14549 | // Determine if successful |
| 14550 | isSuccess = status >= 200 && status < 300 || status === 304; |
| 14551 | |
| 14552 | // Get response data |
| 14553 | if ( responses ) { |
| 14554 | response = ajaxHandleResponses( s, jqXHR, responses ); |
| 14555 | } |
| 14556 | |
| 14557 | // Convert no matter what (that way responseXXX fields are always set) |
| 14558 | response = ajaxConvert( s, response, jqXHR, isSuccess ); |
| 14559 | |
| 14560 | // If successful, handle type chaining |
| 14561 | if ( isSuccess ) { |
| 14562 | |
| 14563 | // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. |
| 14564 | if ( s.ifModified ) { |
| 14565 | modified = jqXHR.getResponseHeader("Last-Modified"); |
| 14566 | if ( modified ) { |
| 14567 | jQuery.lastModified[ cacheURL ] = modified; |
| 14568 | } |
| 14569 | modified = jqXHR.getResponseHeader("etag"); |
| 14570 | if ( modified ) { |
| 14571 | jQuery.etag[ cacheURL ] = modified; |
| 14572 | } |
| 14573 | } |
| 14574 | |
| 14575 | // if no content |
| 14576 | if ( status === 204 || s.type === "HEAD" ) { |
| 14577 | statusText = "nocontent"; |
| 14578 | |
| 14579 | // if not modified |
| 14580 | } else if ( status === 304 ) { |
| 14581 | statusText = "notmodified"; |
| 14582 | |
| 14583 | // If we have data, let's convert it |
| 14584 | } else { |
| 14585 | statusText = response.state; |
| 14586 | success = response.data; |
| 14587 | error = response.error; |
| 14588 | isSuccess = !error; |
| 14589 | } |
| 14590 | } else { |
| 14591 | // Extract error from statusText and normalize for non-aborts |
| 14592 | error = statusText; |
| 14593 | if ( status || !statusText ) { |
| 14594 | statusText = "error"; |
| 14595 | if ( status < 0 ) { |
| 14596 | status = 0; |
| 14597 | } |
| 14598 | } |
| 14599 | } |
| 14600 | |
| 14601 | // Set data for the fake xhr object |
| 14602 | jqXHR.status = status; |
| 14603 | jqXHR.statusText = ( nativeStatusText || statusText ) + ""; |
| 14604 | |
| 14605 | // Success/Error |
| 14606 | if ( isSuccess ) { |
| 14607 | deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); |
| 14608 | } else { |
| 14609 | deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); |
| 14610 | } |
| 14611 | |
| 14612 | // Status-dependent callbacks |
| 14613 | jqXHR.statusCode( statusCode ); |
| 14614 | statusCode = undefined; |
| 14615 | |
| 14616 | if ( fireGlobals ) { |
| 14617 | globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", |
| 14618 | [ jqXHR, s, isSuccess ? success : error ] ); |
| 14619 | } |
| 14620 | |
| 14621 | // Complete |
| 14622 | completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); |
| 14623 | |
| 14624 | if ( fireGlobals ) { |
| 14625 | globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); |
| 14626 | // Handle the global AJAX counter |
| 14627 | if ( !( --jQuery.active ) ) { |
| 14628 | jQuery.event.trigger("ajaxStop"); |
| 14629 | } |
| 14630 | } |
| 14631 | } |
| 14632 | |
| 14633 | return jqXHR; |
| 14634 | }, |
| 14635 | |
| 14636 | getJSON: function( url, data, callback ) { |
| 14637 | return jQuery.get( url, data, callback, "json" ); |
| 14638 | }, |
| 14639 | |
| 14640 | getScript: function( url, callback ) { |
| 14641 | return jQuery.get( url, undefined, callback, "script" ); |
| 14642 | } |
| 14643 | }); |
| 14644 | |
| 14645 | jQuery.each( [ "get", "post" ], function( i, method ) { |
| 14646 | jQuery[ method ] = function( url, data, callback, type ) { |
| 14647 | // Shift arguments if data argument was omitted |
| 14648 | if ( jQuery.isFunction( data ) ) { |
| 14649 | type = type || callback; |
| 14650 | callback = data; |
| 14651 | data = undefined; |
| 14652 | } |
| 14653 | |
| 14654 | return jQuery.ajax({ |
| 14655 | url: url, |
| 14656 | type: method, |
| 14657 | dataType: type, |
| 14658 | data: data, |
| 14659 | success: callback |
| 14660 | }); |
| 14661 | }; |
| 14662 | }); |
| 14663 | |
| 14664 | |
| 14665 | jQuery._evalUrl = function( url ) { |
| 14666 | return jQuery.ajax({ |
| 14667 | url: url, |
| 14668 | type: "GET", |
| 14669 | dataType: "script", |
| 14670 | async: false, |
| 14671 | global: false, |
| 14672 | "throws": true |
| 14673 | }); |
| 14674 | }; |
| 14675 | |
| 14676 | |
| 14677 | jQuery.fn.extend({ |
| 14678 | wrapAll: function( html ) { |
| 14679 | var wrap; |
| 14680 | |
| 14681 | if ( jQuery.isFunction( html ) ) { |
| 14682 | return this.each(function( i ) { |
| 14683 | jQuery( this ).wrapAll( html.call(this, i) ); |
| 14684 | }); |
| 14685 | } |
| 14686 | |
| 14687 | if ( this[ 0 ] ) { |
| 14688 | |
| 14689 | // The elements to wrap the target around |
| 14690 | wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); |
| 14691 | |
| 14692 | if ( this[ 0 ].parentNode ) { |
| 14693 | wrap.insertBefore( this[ 0 ] ); |
| 14694 | } |
| 14695 | |
| 14696 | wrap.map(function() { |
| 14697 | var elem = this; |
| 14698 | |
| 14699 | while ( elem.firstElementChild ) { |
| 14700 | elem = elem.firstElementChild; |
| 14701 | } |
| 14702 | |
| 14703 | return elem; |
| 14704 | }).append( this ); |
| 14705 | } |
| 14706 | |
| 14707 | return this; |
| 14708 | }, |
| 14709 | |
| 14710 | wrapInner: function( html ) { |
| 14711 | if ( jQuery.isFunction( html ) ) { |
| 14712 | return this.each(function( i ) { |
| 14713 | jQuery( this ).wrapInner( html.call(this, i) ); |
| 14714 | }); |
| 14715 | } |
| 14716 | |
| 14717 | return this.each(function() { |
| 14718 | var self = jQuery( this ), |
| 14719 | contents = self.contents(); |
| 14720 | |
| 14721 | if ( contents.length ) { |
| 14722 | contents.wrapAll( html ); |
| 14723 | |
| 14724 | } else { |
| 14725 | self.append( html ); |
| 14726 | } |
| 14727 | }); |
| 14728 | }, |
| 14729 | |
| 14730 | wrap: function( html ) { |
| 14731 | var isFunction = jQuery.isFunction( html ); |
| 14732 | |
| 14733 | return this.each(function( i ) { |
| 14734 | jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); |
| 14735 | }); |
| 14736 | }, |
| 14737 | |
| 14738 | unwrap: function() { |
| 14739 | return this.parent().each(function() { |
| 14740 | if ( !jQuery.nodeName( this, "body" ) ) { |
| 14741 | jQuery( this ).replaceWith( this.childNodes ); |
| 14742 | } |
| 14743 | }).end(); |
| 14744 | } |
| 14745 | }); |
| 14746 | |
| 14747 | |
| 14748 | jQuery.expr.filters.hidden = function( elem ) { |
| 14749 | // Support: Opera <= 12.12 |
| 14750 | // Opera reports offsetWidths and offsetHeights less than zero on some elements |
| 14751 | return elem.offsetWidth <= 0 && elem.offsetHeight <= 0; |
| 14752 | }; |
| 14753 | jQuery.expr.filters.visible = function( elem ) { |
| 14754 | return !jQuery.expr.filters.hidden( elem ); |
| 14755 | }; |
| 14756 | |
| 14757 | |
| 14758 | |
| 14759 | |
| 14760 | var r20 = /%20/g, |
| 14761 | rbracket = /\[\]$/, |
| 14762 | rCRLF = /\r?\n/g, |
| 14763 | rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, |
| 14764 | rsubmittable = /^(?:input|select|textarea|keygen)/i; |
| 14765 | |
| 14766 | function buildParams( prefix, obj, traditional, add ) { |
| 14767 | var name; |
| 14768 | |
| 14769 | if ( jQuery.isArray( obj ) ) { |
| 14770 | // Serialize array item. |
| 14771 | jQuery.each( obj, function( i, v ) { |
| 14772 | if ( traditional || rbracket.test( prefix ) ) { |
| 14773 | // Treat each array item as a scalar. |
| 14774 | add( prefix, v ); |
| 14775 | |
| 14776 | } else { |
| 14777 | // Item is non-scalar (array or object), encode its numeric index. |
| 14778 | buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add ); |
| 14779 | } |
| 14780 | }); |
| 14781 | |
| 14782 | } else if ( !traditional && jQuery.type( obj ) === "object" ) { |
| 14783 | // Serialize object item. |
| 14784 | for ( name in obj ) { |
| 14785 | buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); |
| 14786 | } |
| 14787 | |
| 14788 | } else { |
| 14789 | // Serialize scalar item. |
| 14790 | add( prefix, obj ); |
| 14791 | } |
| 14792 | } |
| 14793 | |
| 14794 | // Serialize an array of form elements or a set of |
| 14795 | // key/values into a query string |
| 14796 | jQuery.param = function( a, traditional ) { |
| 14797 | var prefix, |
| 14798 | s = [], |
| 14799 | add = function( key, value ) { |
| 14800 | // If value is a function, invoke it and return its value |
| 14801 | value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value ); |
| 14802 | s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); |
| 14803 | }; |
| 14804 | |
| 14805 | // Set traditional to true for jQuery <= 1.3.2 behavior. |
| 14806 | if ( traditional === undefined ) { |
| 14807 | traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; |
| 14808 | } |
| 14809 | |
| 14810 | // If an array was passed in, assume that it is an array of form elements. |
| 14811 | if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { |
| 14812 | // Serialize the form elements |
| 14813 | jQuery.each( a, function() { |
| 14814 | add( this.name, this.value ); |
| 14815 | }); |
| 14816 | |
| 14817 | } else { |
| 14818 | // If traditional, encode the "old" way (the way 1.3.2 or older |
| 14819 | // did it), otherwise encode params recursively. |
| 14820 | for ( prefix in a ) { |
| 14821 | buildParams( prefix, a[ prefix ], traditional, add ); |
| 14822 | } |
| 14823 | } |
| 14824 | |
| 14825 | // Return the resulting serialization |
| 14826 | return s.join( "&" ).replace( r20, "+" ); |
| 14827 | }; |
| 14828 | |
| 14829 | jQuery.fn.extend({ |
| 14830 | serialize: function() { |
| 14831 | return jQuery.param( this.serializeArray() ); |
| 14832 | }, |
| 14833 | serializeArray: function() { |
| 14834 | return this.map(function() { |
| 14835 | // Can add propHook for "elements" to filter or add form elements |
| 14836 | var elements = jQuery.prop( this, "elements" ); |
| 14837 | return elements ? jQuery.makeArray( elements ) : this; |
| 14838 | }) |
| 14839 | .filter(function() { |
| 14840 | var type = this.type; |
| 14841 | |
| 14842 | // Use .is( ":disabled" ) so that fieldset[disabled] works |
| 14843 | return this.name && !jQuery( this ).is( ":disabled" ) && |
| 14844 | rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && |
| 14845 | ( this.checked || !rcheckableType.test( type ) ); |
| 14846 | }) |
| 14847 | .map(function( i, elem ) { |
| 14848 | var val = jQuery( this ).val(); |
| 14849 | |
| 14850 | return val == null ? |
| 14851 | null : |
| 14852 | jQuery.isArray( val ) ? |
| 14853 | jQuery.map( val, function( val ) { |
| 14854 | return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; |
| 14855 | }) : |
| 14856 | { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; |
| 14857 | }).get(); |
| 14858 | } |
| 14859 | }); |
| 14860 | |
| 14861 | |
| 14862 | jQuery.ajaxSettings.xhr = function() { |
| 14863 | try { |
| 14864 | return new XMLHttpRequest(); |
| 14865 | } catch( e ) {} |
| 14866 | }; |
| 14867 | |
| 14868 | var xhrId = 0, |
| 14869 | xhrCallbacks = {}, |
| 14870 | xhrSuccessStatus = { |
| 14871 | // file protocol always yields status code 0, assume 200 |
| 14872 | 0: 200, |
| 14873 | // Support: IE9 |
| 14874 | // #1450: sometimes IE returns 1223 when it should be 204 |
| 14875 | 1223: 204 |
| 14876 | }, |
| 14877 | xhrSupported = jQuery.ajaxSettings.xhr(); |
| 14878 | |
| 14879 | // Support: IE9 |
| 14880 | // Open requests must be manually aborted on unload (#5280) |
| 14881 | // See https://support.microsoft.com/kb/2856746 for more info |
| 14882 | if ( window.attachEvent ) { |
| 14883 | window.attachEvent( "onunload", function() { |
| 14884 | for ( var key in xhrCallbacks ) { |
| 14885 | xhrCallbacks[ key ](); |
| 14886 | } |
| 14887 | }); |
| 14888 | } |
| 14889 | |
| 14890 | support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); |
| 14891 | support.ajax = xhrSupported = !!xhrSupported; |
| 14892 | |
| 14893 | jQuery.ajaxTransport(function( options ) { |
| 14894 | var callback; |
| 14895 | |
| 14896 | // Cross domain only allowed if supported through XMLHttpRequest |
| 14897 | if ( support.cors || xhrSupported && !options.crossDomain ) { |
| 14898 | return { |
| 14899 | send: function( headers, complete ) { |
| 14900 | var i, |
| 14901 | xhr = options.xhr(), |
| 14902 | id = ++xhrId; |
| 14903 | |
| 14904 | xhr.open( options.type, options.url, options.async, options.username, options.password ); |
| 14905 | |
| 14906 | // Apply custom fields if provided |
| 14907 | if ( options.xhrFields ) { |
| 14908 | for ( i in options.xhrFields ) { |
| 14909 | xhr[ i ] = options.xhrFields[ i ]; |
| 14910 | } |
| 14911 | } |
| 14912 | |
| 14913 | // Override mime type if needed |
| 14914 | if ( options.mimeType && xhr.overrideMimeType ) { |
| 14915 | xhr.overrideMimeType( options.mimeType ); |
| 14916 | } |
| 14917 | |
| 14918 | // X-Requested-With header |
| 14919 | // For cross-domain requests, seeing as conditions for a preflight are |
| 14920 | // akin to a jigsaw puzzle, we simply never set it to be sure. |
| 14921 | // (it can always be set on a per-request basis or even using ajaxSetup) |
| 14922 | // For same-domain requests, won't change header if already provided. |
| 14923 | if ( !options.crossDomain && !headers["X-Requested-With"] ) { |
| 14924 | headers["X-Requested-With"] = "XMLHttpRequest"; |
| 14925 | } |
| 14926 | |
| 14927 | // Set headers |
| 14928 | for ( i in headers ) { |
| 14929 | xhr.setRequestHeader( i, headers[ i ] ); |
| 14930 | } |
| 14931 | |
| 14932 | // Callback |
| 14933 | callback = function( type ) { |
| 14934 | return function() { |
| 14935 | if ( callback ) { |
| 14936 | delete xhrCallbacks[ id ]; |
| 14937 | callback = xhr.onload = xhr.onerror = null; |
| 14938 | |
| 14939 | if ( type === "abort" ) { |
| 14940 | xhr.abort(); |
| 14941 | } else if ( type === "error" ) { |
| 14942 | complete( |
| 14943 | // file: protocol always yields status 0; see #8605, #14207 |
| 14944 | xhr.status, |
| 14945 | xhr.statusText |
| 14946 | ); |
| 14947 | } else { |
| 14948 | complete( |
| 14949 | xhrSuccessStatus[ xhr.status ] || xhr.status, |
| 14950 | xhr.statusText, |
| 14951 | // Support: IE9 |
| 14952 | // Accessing binary-data responseText throws an exception |
| 14953 | // (#11426) |
| 14954 | typeof xhr.responseText === "string" ? { |
| 14955 | text: xhr.responseText |
| 14956 | } : undefined, |
| 14957 | xhr.getAllResponseHeaders() |
| 14958 | ); |
| 14959 | } |
| 14960 | } |
| 14961 | }; |
| 14962 | }; |
| 14963 | |
| 14964 | // Listen to events |
| 14965 | xhr.onload = callback(); |
| 14966 | xhr.onerror = callback("error"); |
| 14967 | |
| 14968 | // Create the abort callback |
| 14969 | callback = xhrCallbacks[ id ] = callback("abort"); |
| 14970 | |
| 14971 | try { |
| 14972 | // Do send the request (this may raise an exception) |
| 14973 | xhr.send( options.hasContent && options.data || null ); |
| 14974 | } catch ( e ) { |
| 14975 | // #14683: Only rethrow if this hasn't been notified as an error yet |
| 14976 | if ( callback ) { |
| 14977 | throw e; |
| 14978 | } |
| 14979 | } |
| 14980 | }, |
| 14981 | |
| 14982 | abort: function() { |
| 14983 | if ( callback ) { |
| 14984 | callback(); |
| 14985 | } |
| 14986 | } |
| 14987 | }; |
| 14988 | } |
| 14989 | }); |
| 14990 | |
| 14991 | |
| 14992 | |
| 14993 | |
| 14994 | // Install script dataType |
| 14995 | jQuery.ajaxSetup({ |
| 14996 | accepts: { |
| 14997 | script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" |
| 14998 | }, |
| 14999 | contents: { |
| 15000 | script: /(?:java|ecma)script/ |
| 15001 | }, |
| 15002 | converters: { |
| 15003 | "text script": function( text ) { |
| 15004 | jQuery.globalEval( text ); |
| 15005 | return text; |
| 15006 | } |
| 15007 | } |
| 15008 | }); |
| 15009 | |
| 15010 | // Handle cache's special case and crossDomain |
| 15011 | jQuery.ajaxPrefilter( "script", function( s ) { |
| 15012 | if ( s.cache === undefined ) { |
| 15013 | s.cache = false; |
| 15014 | } |
| 15015 | if ( s.crossDomain ) { |
| 15016 | s.type = "GET"; |
| 15017 | } |
| 15018 | }); |
| 15019 | |
| 15020 | // Bind script tag hack transport |
| 15021 | jQuery.ajaxTransport( "script", function( s ) { |
| 15022 | // This transport only deals with cross domain requests |
| 15023 | if ( s.crossDomain ) { |
| 15024 | var script, callback; |
| 15025 | return { |
| 15026 | send: function( _, complete ) { |
| 15027 | script = jQuery("<script>").prop({ |
| 15028 | async: true, |
| 15029 | charset: s.scriptCharset, |
| 15030 | src: s.url |
| 15031 | }).on( |
| 15032 | "load error", |
| 15033 | callback = function( evt ) { |
| 15034 | script.remove(); |
| 15035 | callback = null; |
| 15036 | if ( evt ) { |
| 15037 | complete( evt.type === "error" ? 404 : 200, evt.type ); |
| 15038 | } |
| 15039 | } |
| 15040 | ); |
| 15041 | document.head.appendChild( script[ 0 ] ); |
| 15042 | }, |
| 15043 | abort: function() { |
| 15044 | if ( callback ) { |
| 15045 | callback(); |
| 15046 | } |
| 15047 | } |
| 15048 | }; |
| 15049 | } |
| 15050 | }); |
| 15051 | |
| 15052 | |
| 15053 | |
| 15054 | |
| 15055 | var oldCallbacks = [], |
| 15056 | rjsonp = /(=)\?(?=&|$)|\?\?/; |
| 15057 | |
| 15058 | // Default jsonp settings |
| 15059 | jQuery.ajaxSetup({ |
| 15060 | jsonp: "callback", |
| 15061 | jsonpCallback: function() { |
| 15062 | var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); |
| 15063 | this[ callback ] = true; |
| 15064 | return callback; |
| 15065 | } |
| 15066 | }); |
| 15067 | |
| 15068 | // Detect, normalize options and install callbacks for jsonp requests |
| 15069 | jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { |
| 15070 | |
| 15071 | var callbackName, overwritten, responseContainer, |
| 15072 | jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? |
| 15073 | "url" : |
| 15074 | typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data" |
| 15075 | ); |
| 15076 | |
| 15077 | // Handle iff the expected data type is "jsonp" or we have a parameter to set |
| 15078 | if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { |
| 15079 | |
| 15080 | // Get callback name, remembering preexisting value associated with it |
| 15081 | callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ? |
| 15082 | s.jsonpCallback() : |
| 15083 | s.jsonpCallback; |
| 15084 | |
| 15085 | // Insert callback into url or form data |
| 15086 | if ( jsonProp ) { |
| 15087 | s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); |
| 15088 | } else if ( s.jsonp !== false ) { |
| 15089 | s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; |
| 15090 | } |
| 15091 | |
| 15092 | // Use data converter to retrieve json after script execution |
| 15093 | s.converters["script json"] = function() { |
| 15094 | if ( !responseContainer ) { |
| 15095 | jQuery.error( callbackName + " was not called" ); |
| 15096 | } |
| 15097 | return responseContainer[ 0 ]; |
| 15098 | }; |
| 15099 | |
| 15100 | // force json dataType |
| 15101 | s.dataTypes[ 0 ] = "json"; |
| 15102 | |
| 15103 | // Install callback |
| 15104 | overwritten = window[ callbackName ]; |
| 15105 | window[ callbackName ] = function() { |
| 15106 | responseContainer = arguments; |
| 15107 | }; |
| 15108 | |
| 15109 | // Clean-up function (fires after converters) |
| 15110 | jqXHR.always(function() { |
| 15111 | // Restore preexisting value |
| 15112 | window[ callbackName ] = overwritten; |
| 15113 | |
| 15114 | // Save back as free |
| 15115 | if ( s[ callbackName ] ) { |
| 15116 | // make sure that re-using the options doesn't screw things around |
| 15117 | s.jsonpCallback = originalSettings.jsonpCallback; |
| 15118 | |
| 15119 | // save the callback name for future use |
| 15120 | oldCallbacks.push( callbackName ); |
| 15121 | } |
| 15122 | |
| 15123 | // Call if it was a function and we have a response |
| 15124 | if ( responseContainer && jQuery.isFunction( overwritten ) ) { |
| 15125 | overwritten( responseContainer[ 0 ] ); |
| 15126 | } |
| 15127 | |
| 15128 | responseContainer = overwritten = undefined; |
| 15129 | }); |
| 15130 | |
| 15131 | // Delegate to script |
| 15132 | return "script"; |
| 15133 | } |
| 15134 | }); |
| 15135 | |
| 15136 | |
| 15137 | |
| 15138 | |
| 15139 | // data: string of html |
| 15140 | // context (optional): If specified, the fragment will be created in this context, defaults to document |
| 15141 | // keepScripts (optional): If true, will include scripts passed in the html string |
| 15142 | jQuery.parseHTML = function( data, context, keepScripts ) { |
| 15143 | if ( !data || typeof data !== "string" ) { |
| 15144 | return null; |
| 15145 | } |
| 15146 | if ( typeof context === "boolean" ) { |
| 15147 | keepScripts = context; |
| 15148 | context = false; |
| 15149 | } |
| 15150 | context = context || document; |
| 15151 | |
| 15152 | var parsed = rsingleTag.exec( data ), |
| 15153 | scripts = !keepScripts && []; |
| 15154 | |
| 15155 | // Single tag |
| 15156 | if ( parsed ) { |
| 15157 | return [ context.createElement( parsed[1] ) ]; |
| 15158 | } |
| 15159 | |
| 15160 | parsed = jQuery.buildFragment( [ data ], context, scripts ); |
| 15161 | |
| 15162 | if ( scripts && scripts.length ) { |
| 15163 | jQuery( scripts ).remove(); |
| 15164 | } |
| 15165 | |
| 15166 | return jQuery.merge( [], parsed.childNodes ); |
| 15167 | }; |
| 15168 | |
| 15169 | |
| 15170 | // Keep a copy of the old load method |
| 15171 | var _load = jQuery.fn.load; |
| 15172 | |
| 15173 | /** |
| 15174 | * Load a url into a page |
| 15175 | */ |
| 15176 | jQuery.fn.load = function( url, params, callback ) { |
| 15177 | if ( typeof url !== "string" && _load ) { |
| 15178 | return _load.apply( this, arguments ); |
| 15179 | } |
| 15180 | |
| 15181 | var selector, type, response, |
| 15182 | self = this, |
| 15183 | off = url.indexOf(" "); |
| 15184 | |
| 15185 | if ( off >= 0 ) { |
| 15186 | selector = jQuery.trim( url.slice( off ) ); |
| 15187 | url = url.slice( 0, off ); |
| 15188 | } |
| 15189 | |
| 15190 | // If it's a function |
| 15191 | if ( jQuery.isFunction( params ) ) { |
| 15192 | |
| 15193 | // We assume that it's the callback |
| 15194 | callback = params; |
| 15195 | params = undefined; |
| 15196 | |
| 15197 | // Otherwise, build a param string |
| 15198 | } else if ( params && typeof params === "object" ) { |
| 15199 | type = "POST"; |
| 15200 | } |
| 15201 | |
| 15202 | // If we have elements to modify, make the request |
| 15203 | if ( self.length > 0 ) { |
| 15204 | jQuery.ajax({ |
| 15205 | url: url, |
| 15206 | |
| 15207 | // if "type" variable is undefined, then "GET" method will be used |
| 15208 | type: type, |
| 15209 | dataType: "html", |
| 15210 | data: params |
| 15211 | }).done(function( responseText ) { |
| 15212 | |
| 15213 | // Save response for use in complete callback |
| 15214 | response = arguments; |
| 15215 | |
| 15216 | self.html( selector ? |
| 15217 | |
| 15218 | // If a selector was specified, locate the right elements in a dummy div |
| 15219 | // Exclude scripts to avoid IE 'Permission Denied' errors |
| 15220 | jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) : |
| 15221 | |
| 15222 | // Otherwise use the full result |
| 15223 | responseText ); |
| 15224 | |
| 15225 | }).complete( callback && function( jqXHR, status ) { |
| 15226 | self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] ); |
| 15227 | }); |
| 15228 | } |
| 15229 | |
| 15230 | return this; |
| 15231 | }; |
| 15232 | |
| 15233 | |
| 15234 | |
| 15235 | |
| 15236 | // Attach a bunch of functions for handling common AJAX events |
| 15237 | jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) { |
| 15238 | jQuery.fn[ type ] = function( fn ) { |
| 15239 | return this.on( type, fn ); |
| 15240 | }; |
| 15241 | }); |
| 15242 | |
| 15243 | |
| 15244 | |
| 15245 | |
| 15246 | jQuery.expr.filters.animated = function( elem ) { |
| 15247 | return jQuery.grep(jQuery.timers, function( fn ) { |
| 15248 | return elem === fn.elem; |
| 15249 | }).length; |
| 15250 | }; |
| 15251 | |
| 15252 | |
| 15253 | |
| 15254 | |
| 15255 | var docElem = window.document.documentElement; |
| 15256 | |
| 15257 | /** |
| 15258 | * Gets a window from an element |
| 15259 | */ |
| 15260 | function getWindow( elem ) { |
| 15261 | return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView; |
| 15262 | } |
| 15263 | |
| 15264 | jQuery.offset = { |
| 15265 | setOffset: function( elem, options, i ) { |
| 15266 | var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, |
| 15267 | position = jQuery.css( elem, "position" ), |
| 15268 | curElem = jQuery( elem ), |
| 15269 | props = {}; |
| 15270 | |
| 15271 | // Set position first, in-case top/left are set even on static elem |
| 15272 | if ( position === "static" ) { |
| 15273 | elem.style.position = "relative"; |
| 15274 | } |
| 15275 | |
| 15276 | curOffset = curElem.offset(); |
| 15277 | curCSSTop = jQuery.css( elem, "top" ); |
| 15278 | curCSSLeft = jQuery.css( elem, "left" ); |
| 15279 | calculatePosition = ( position === "absolute" || position === "fixed" ) && |
| 15280 | ( curCSSTop + curCSSLeft ).indexOf("auto") > -1; |
| 15281 | |
| 15282 | // Need to be able to calculate position if either |
| 15283 | // top or left is auto and position is either absolute or fixed |
| 15284 | if ( calculatePosition ) { |
| 15285 | curPosition = curElem.position(); |
| 15286 | curTop = curPosition.top; |
| 15287 | curLeft = curPosition.left; |
| 15288 | |
| 15289 | } else { |
| 15290 | curTop = parseFloat( curCSSTop ) || 0; |
| 15291 | curLeft = parseFloat( curCSSLeft ) || 0; |
| 15292 | } |
| 15293 | |
| 15294 | if ( jQuery.isFunction( options ) ) { |
| 15295 | options = options.call( elem, i, curOffset ); |
| 15296 | } |
| 15297 | |
| 15298 | if ( options.top != null ) { |
| 15299 | props.top = ( options.top - curOffset.top ) + curTop; |
| 15300 | } |
| 15301 | if ( options.left != null ) { |
| 15302 | props.left = ( options.left - curOffset.left ) + curLeft; |
| 15303 | } |
| 15304 | |
| 15305 | if ( "using" in options ) { |
| 15306 | options.using.call( elem, props ); |
| 15307 | |
| 15308 | } else { |
| 15309 | curElem.css( props ); |
| 15310 | } |
| 15311 | } |
| 15312 | }; |
| 15313 | |
| 15314 | jQuery.fn.extend({ |
| 15315 | offset: function( options ) { |
| 15316 | if ( arguments.length ) { |
| 15317 | return options === undefined ? |
| 15318 | this : |
| 15319 | this.each(function( i ) { |
| 15320 | jQuery.offset.setOffset( this, options, i ); |
| 15321 | }); |
| 15322 | } |
| 15323 | |
| 15324 | var docElem, win, |
| 15325 | elem = this[ 0 ], |
| 15326 | box = { top: 0, left: 0 }, |
| 15327 | doc = elem && elem.ownerDocument; |
| 15328 | |
| 15329 | if ( !doc ) { |
| 15330 | return; |
| 15331 | } |
| 15332 | |
| 15333 | docElem = doc.documentElement; |
| 15334 | |
| 15335 | // Make sure it's not a disconnected DOM node |
| 15336 | if ( !jQuery.contains( docElem, elem ) ) { |
| 15337 | return box; |
| 15338 | } |
| 15339 | |
| 15340 | // Support: BlackBerry 5, iOS 3 (original iPhone) |
| 15341 | // If we don't have gBCR, just use 0,0 rather than error |
| 15342 | if ( typeof elem.getBoundingClientRect !== strundefined ) { |
| 15343 | box = elem.getBoundingClientRect(); |
| 15344 | } |
| 15345 | win = getWindow( doc ); |
| 15346 | return { |
| 15347 | top: box.top + win.pageYOffset - docElem.clientTop, |
| 15348 | left: box.left + win.pageXOffset - docElem.clientLeft |
| 15349 | }; |
| 15350 | }, |
| 15351 | |
| 15352 | position: function() { |
| 15353 | if ( !this[ 0 ] ) { |
| 15354 | return; |
| 15355 | } |
| 15356 | |
| 15357 | var offsetParent, offset, |
| 15358 | elem = this[ 0 ], |
| 15359 | parentOffset = { top: 0, left: 0 }; |
| 15360 | |
| 15361 | // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent |
| 15362 | if ( jQuery.css( elem, "position" ) === "fixed" ) { |
| 15363 | // Assume getBoundingClientRect is there when computed position is fixed |
| 15364 | offset = elem.getBoundingClientRect(); |
| 15365 | |
| 15366 | } else { |
| 15367 | // Get *real* offsetParent |
| 15368 | offsetParent = this.offsetParent(); |
| 15369 | |
| 15370 | // Get correct offsets |
| 15371 | offset = this.offset(); |
| 15372 | if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) { |
| 15373 | parentOffset = offsetParent.offset(); |
| 15374 | } |
| 15375 | |
| 15376 | // Add offsetParent borders |
| 15377 | parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ); |
| 15378 | parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true ); |
| 15379 | } |
| 15380 | |
| 15381 | // Subtract parent offsets and element margins |
| 15382 | return { |
| 15383 | top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), |
| 15384 | left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true ) |
| 15385 | }; |
| 15386 | }, |
| 15387 | |
| 15388 | offsetParent: function() { |
| 15389 | return this.map(function() { |
| 15390 | var offsetParent = this.offsetParent || docElem; |
| 15391 | |
| 15392 | while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position" ) === "static" ) ) { |
| 15393 | offsetParent = offsetParent.offsetParent; |
| 15394 | } |
| 15395 | |
| 15396 | return offsetParent || docElem; |
| 15397 | }); |
| 15398 | } |
| 15399 | }); |
| 15400 | |
| 15401 | // Create scrollLeft and scrollTop methods |
| 15402 | jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) { |
| 15403 | var top = "pageYOffset" === prop; |
| 15404 | |
| 15405 | jQuery.fn[ method ] = function( val ) { |
| 15406 | return access( this, function( elem, method, val ) { |
| 15407 | var win = getWindow( elem ); |
| 15408 | |
| 15409 | if ( val === undefined ) { |
| 15410 | return win ? win[ prop ] : elem[ method ]; |
| 15411 | } |
| 15412 | |
| 15413 | if ( win ) { |
| 15414 | win.scrollTo( |
| 15415 | !top ? val : window.pageXOffset, |
| 15416 | top ? val : window.pageYOffset |
| 15417 | ); |
| 15418 | |
| 15419 | } else { |
| 15420 | elem[ method ] = val; |
| 15421 | } |
| 15422 | }, method, val, arguments.length, null ); |
| 15423 | }; |
| 15424 | }); |
| 15425 | |
| 15426 | // Support: Safari<7+, Chrome<37+ |
| 15427 | // Add the top/left cssHooks using jQuery.fn.position |
| 15428 | // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 |
| 15429 | // Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280 |
| 15430 | // getComputedStyle returns percent when specified for top/left/bottom/right; |
| 15431 | // rather than make the css module depend on the offset module, just check for it here |
| 15432 | jQuery.each( [ "top", "left" ], function( i, prop ) { |
| 15433 | jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, |
| 15434 | function( elem, computed ) { |
| 15435 | if ( computed ) { |
| 15436 | computed = curCSS( elem, prop ); |
| 15437 | // If curCSS returns percentage, fallback to offset |
| 15438 | return rnumnonpx.test( computed ) ? |
| 15439 | jQuery( elem ).position()[ prop ] + "px" : |
| 15440 | computed; |
| 15441 | } |
| 15442 | } |
| 15443 | ); |
| 15444 | }); |
| 15445 | |
| 15446 | |
| 15447 | // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods |
| 15448 | jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { |
| 15449 | jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) { |
| 15450 | // Margin is only for outerHeight, outerWidth |
| 15451 | jQuery.fn[ funcName ] = function( margin, value ) { |
| 15452 | var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), |
| 15453 | extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); |
| 15454 | |
| 15455 | return access( this, function( elem, type, value ) { |
| 15456 | var doc; |
| 15457 | |
| 15458 | if ( jQuery.isWindow( elem ) ) { |
| 15459 | // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there |
| 15460 | // isn't a whole lot we can do. See pull request at this URL for discussion: |
| 15461 | // https://github.com/jquery/jquery/pull/764 |
| 15462 | return elem.document.documentElement[ "client" + name ]; |
| 15463 | } |
| 15464 | |
| 15465 | // Get document width or height |
| 15466 | if ( elem.nodeType === 9 ) { |
| 15467 | doc = elem.documentElement; |
| 15468 | |
| 15469 | // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], |
| 15470 | // whichever is greatest |
| 15471 | return Math.max( |
| 15472 | elem.body[ "scroll" + name ], doc[ "scroll" + name ], |
| 15473 | elem.body[ "offset" + name ], doc[ "offset" + name ], |
| 15474 | doc[ "client" + name ] |
| 15475 | ); |
| 15476 | } |
| 15477 | |
| 15478 | return value === undefined ? |
| 15479 | // Get width or height on the element, requesting but not forcing parseFloat |
| 15480 | jQuery.css( elem, type, extra ) : |
| 15481 | |
| 15482 | // Set width or height on the element |
| 15483 | jQuery.style( elem, type, value, extra ); |
| 15484 | }, type, chainable ? margin : undefined, chainable, null ); |
| 15485 | }; |
| 15486 | }); |
| 15487 | }); |
| 15488 | |
| 15489 | |
| 15490 | // The number of elements contained in the matched element set |
| 15491 | jQuery.fn.size = function() { |
| 15492 | return this.length; |
| 15493 | }; |
| 15494 | |
| 15495 | jQuery.fn.andSelf = jQuery.fn.addBack; |
| 15496 | |
| 15497 | |
| 15498 | |
| 15499 | |
| 15500 | // Register as a named AMD module, since jQuery can be concatenated with other |
| 15501 | // files that may use define, but not via a proper concatenation script that |
| 15502 | // understands anonymous AMD modules. A named AMD is safest and most robust |
| 15503 | // way to register. Lowercase jquery is used because AMD module names are |
| 15504 | // derived from file names, and jQuery is normally delivered in a lowercase |
| 15505 | // file name. Do this after creating the global so that if an AMD module wants |
| 15506 | // to call noConflict to hide this version of jQuery, it will work. |
| 15507 | |
| 15508 | // Note that for maximum portability, libraries that are not jQuery should |
| 15509 | // declare themselves as anonymous modules, and avoid setting a global if an |
| 15510 | // AMD loader is present. jQuery is a special case. For more information, see |
| 15511 | // https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon |
| 15512 | |
| 15513 | if ( typeof define === "function" && define.amd ) { |
| 15514 | define( "jquery", [], function() { |
| 15515 | return jQuery; |
| 15516 | }); |
| 15517 | } |
| 15518 | |
| 15519 | |
| 15520 | |
| 15521 | |
| 15522 | var |
| 15523 | // Map over jQuery in case of overwrite |
| 15524 | _jQuery = window.jQuery, |
| 15525 | |
| 15526 | // Map over the $ in case of overwrite |
| 15527 | _$ = window.$; |
| 15528 | |
| 15529 | jQuery.noConflict = function( deep ) { |
| 15530 | if ( window.$ === jQuery ) { |
| 15531 | window.$ = _$; |
| 15532 | } |
| 15533 | |
| 15534 | if ( deep && window.jQuery === jQuery ) { |
| 15535 | window.jQuery = _jQuery; |
| 15536 | } |
| 15537 | |
| 15538 | return jQuery; |
| 15539 | }; |
| 15540 | |
| 15541 | // Expose jQuery and $ identifiers, even in AMD |
| 15542 | // (#7102#comment:10, https://github.com/jquery/jquery/pull/557) |
| 15543 | // and CommonJS for browser emulators (#13566) |
| 15544 | if ( typeof noGlobal === strundefined ) { |
| 15545 | window.jQuery = window.$ = jQuery; |
| 15546 | } |
| 15547 | |
| 15548 | |
| 15549 | |
| 15550 | |
| 15551 | return jQuery; |
| 15552 | |
| 15553 | })); |
| 15554 | |
| 15555 | },{}],20:[function(require,module,exports){ |
| 15556 | 'use strict'; |
| 15557 | |
| 15558 | |
| 15559 | var yaml = require('./lib/js-yaml.js'); |
| 15560 | |
| 15561 | |
| 15562 | module.exports = yaml; |
| 15563 | |
| 15564 | },{"./lib/js-yaml.js":21}],21:[function(require,module,exports){ |
| 15565 | 'use strict'; |
| 15566 | |
| 15567 | |
| 15568 | var loader = require('./js-yaml/loader'); |
| 15569 | var dumper = require('./js-yaml/dumper'); |
| 15570 | |
| 15571 | |
| 15572 | function deprecated(name) { |
| 15573 | return function () { |
| 15574 | throw new Error('Function ' + name + ' is deprecated and cannot be used.'); |
| 15575 | }; |
| 15576 | } |
| 15577 | |
| 15578 | |
| 15579 | module.exports.Type = require('./js-yaml/type'); |
| 15580 | module.exports.Schema = require('./js-yaml/schema'); |
| 15581 | module.exports.FAILSAFE_SCHEMA = require('./js-yaml/schema/failsafe'); |
| 15582 | module.exports.JSON_SCHEMA = require('./js-yaml/schema/json'); |
| 15583 | module.exports.CORE_SCHEMA = require('./js-yaml/schema/core'); |
| 15584 | module.exports.DEFAULT_SAFE_SCHEMA = require('./js-yaml/schema/default_safe'); |
| 15585 | module.exports.DEFAULT_FULL_SCHEMA = require('./js-yaml/schema/default_full'); |
| 15586 | module.exports.load = loader.load; |
| 15587 | module.exports.loadAll = loader.loadAll; |
| 15588 | module.exports.safeLoad = loader.safeLoad; |
| 15589 | module.exports.safeLoadAll = loader.safeLoadAll; |
| 15590 | module.exports.dump = dumper.dump; |
| 15591 | module.exports.safeDump = dumper.safeDump; |
| 15592 | module.exports.YAMLException = require('./js-yaml/exception'); |
| 15593 | |
| 15594 | // Deprecared schema names from JS-YAML 2.0.x |
| 15595 | module.exports.MINIMAL_SCHEMA = require('./js-yaml/schema/failsafe'); |
| 15596 | module.exports.SAFE_SCHEMA = require('./js-yaml/schema/default_safe'); |
| 15597 | module.exports.DEFAULT_SCHEMA = require('./js-yaml/schema/default_full'); |
| 15598 | |
| 15599 | // Deprecated functions from JS-YAML 1.x.x |
| 15600 | module.exports.scan = deprecated('scan'); |
| 15601 | module.exports.parse = deprecated('parse'); |
| 15602 | module.exports.compose = deprecated('compose'); |
| 15603 | module.exports.addConstructor = deprecated('addConstructor'); |
| 15604 | |
| 15605 | },{"./js-yaml/dumper":23,"./js-yaml/exception":24,"./js-yaml/loader":25,"./js-yaml/schema":27,"./js-yaml/schema/core":28,"./js-yaml/schema/default_full":29,"./js-yaml/schema/default_safe":30,"./js-yaml/schema/failsafe":31,"./js-yaml/schema/json":32,"./js-yaml/type":33}],22:[function(require,module,exports){ |
| 15606 | 'use strict'; |
| 15607 | |
| 15608 | |
| 15609 | function isNothing(subject) { |
| 15610 | return (typeof subject === 'undefined') || (null === subject); |
| 15611 | } |
| 15612 | |
| 15613 | |
| 15614 | function isObject(subject) { |
| 15615 | return (typeof subject === 'object') && (null !== subject); |
| 15616 | } |
| 15617 | |
| 15618 | |
| 15619 | function toArray(sequence) { |
| 15620 | if (Array.isArray(sequence)) { |
| 15621 | return sequence; |
| 15622 | } else if (isNothing(sequence)) { |
| 15623 | return []; |
| 15624 | } |
| 15625 | return [ sequence ]; |
| 15626 | } |
| 15627 | |
| 15628 | |
| 15629 | function extend(target, source) { |
| 15630 | var index, length, key, sourceKeys; |
| 15631 | |
| 15632 | if (source) { |
| 15633 | sourceKeys = Object.keys(source); |
| 15634 | |
| 15635 | for (index = 0, length = sourceKeys.length; index < length; index += 1) { |
| 15636 | key = sourceKeys[index]; |
| 15637 | target[key] = source[key]; |
| 15638 | } |
| 15639 | } |
| 15640 | |
| 15641 | return target; |
| 15642 | } |
| 15643 | |
| 15644 | |
| 15645 | function repeat(string, count) { |
| 15646 | var result = '', cycle; |
| 15647 | |
| 15648 | for (cycle = 0; cycle < count; cycle += 1) { |
| 15649 | result += string; |
| 15650 | } |
| 15651 | |
| 15652 | return result; |
| 15653 | } |
| 15654 | |
| 15655 | |
| 15656 | function isNegativeZero(number) { |
| 15657 | return (0 === number) && (Number.NEGATIVE_INFINITY === 1 / number); |
| 15658 | } |
| 15659 | |
| 15660 | |
| 15661 | module.exports.isNothing = isNothing; |
| 15662 | module.exports.isObject = isObject; |
| 15663 | module.exports.toArray = toArray; |
| 15664 | module.exports.repeat = repeat; |
| 15665 | module.exports.isNegativeZero = isNegativeZero; |
| 15666 | module.exports.extend = extend; |
| 15667 | |
| 15668 | },{}],23:[function(require,module,exports){ |
| 15669 | 'use strict'; |
| 15670 | |
| 15671 | /*eslint-disable no-use-before-define*/ |
| 15672 | |
| 15673 | var common = require('./common'); |
| 15674 | var YAMLException = require('./exception'); |
| 15675 | var DEFAULT_FULL_SCHEMA = require('./schema/default_full'); |
| 15676 | var DEFAULT_SAFE_SCHEMA = require('./schema/default_safe'); |
| 15677 | |
| 15678 | var _toString = Object.prototype.toString; |
| 15679 | var _hasOwnProperty = Object.prototype.hasOwnProperty; |
| 15680 | |
| 15681 | var CHAR_TAB = 0x09; /* Tab */ |
| 15682 | var CHAR_LINE_FEED = 0x0A; /* LF */ |
| 15683 | var CHAR_CARRIAGE_RETURN = 0x0D; /* CR */ |
| 15684 | var CHAR_SPACE = 0x20; /* Space */ |
| 15685 | var CHAR_EXCLAMATION = 0x21; /* ! */ |
| 15686 | var CHAR_DOUBLE_QUOTE = 0x22; /* " */ |
| 15687 | var CHAR_SHARP = 0x23; /* # */ |
| 15688 | var CHAR_PERCENT = 0x25; /* % */ |
| 15689 | var CHAR_AMPERSAND = 0x26; /* & */ |
| 15690 | var CHAR_SINGLE_QUOTE = 0x27; /* ' */ |
| 15691 | var CHAR_ASTERISK = 0x2A; /* * */ |
| 15692 | var CHAR_COMMA = 0x2C; /* , */ |
| 15693 | var CHAR_MINUS = 0x2D; /* - */ |
| 15694 | var CHAR_COLON = 0x3A; /* : */ |
| 15695 | var CHAR_GREATER_THAN = 0x3E; /* > */ |
| 15696 | var CHAR_QUESTION = 0x3F; /* ? */ |
| 15697 | var CHAR_COMMERCIAL_AT = 0x40; /* @ */ |
| 15698 | var CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */ |
| 15699 | var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */ |
| 15700 | var CHAR_GRAVE_ACCENT = 0x60; /* ` */ |
| 15701 | var CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */ |
| 15702 | var CHAR_VERTICAL_LINE = 0x7C; /* | */ |
| 15703 | var CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */ |
| 15704 | |
| 15705 | var ESCAPE_SEQUENCES = {}; |
| 15706 | |
| 15707 | ESCAPE_SEQUENCES[0x00] = '\\0'; |
| 15708 | ESCAPE_SEQUENCES[0x07] = '\\a'; |
| 15709 | ESCAPE_SEQUENCES[0x08] = '\\b'; |
| 15710 | ESCAPE_SEQUENCES[0x09] = '\\t'; |
| 15711 | ESCAPE_SEQUENCES[0x0A] = '\\n'; |
| 15712 | ESCAPE_SEQUENCES[0x0B] = '\\v'; |
| 15713 | ESCAPE_SEQUENCES[0x0C] = '\\f'; |
| 15714 | ESCAPE_SEQUENCES[0x0D] = '\\r'; |
| 15715 | ESCAPE_SEQUENCES[0x1B] = '\\e'; |
| 15716 | ESCAPE_SEQUENCES[0x22] = '\\"'; |
| 15717 | ESCAPE_SEQUENCES[0x5C] = '\\\\'; |
| 15718 | ESCAPE_SEQUENCES[0x85] = '\\N'; |
| 15719 | ESCAPE_SEQUENCES[0xA0] = '\\_'; |
| 15720 | ESCAPE_SEQUENCES[0x2028] = '\\L'; |
| 15721 | ESCAPE_SEQUENCES[0x2029] = '\\P'; |
| 15722 | |
| 15723 | var DEPRECATED_BOOLEANS_SYNTAX = [ |
| 15724 | 'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON', |
| 15725 | 'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF' |
| 15726 | ]; |
| 15727 | |
| 15728 | function compileStyleMap(schema, map) { |
| 15729 | var result, keys, index, length, tag, style, type; |
| 15730 | |
| 15731 | if (null === map) { |
| 15732 | return {}; |
| 15733 | } |
| 15734 | |
| 15735 | result = {}; |
| 15736 | keys = Object.keys(map); |
| 15737 | |
| 15738 | for (index = 0, length = keys.length; index < length; index += 1) { |
| 15739 | tag = keys[index]; |
| 15740 | style = String(map[tag]); |
| 15741 | |
| 15742 | if ('!!' === tag.slice(0, 2)) { |
| 15743 | tag = 'tag:yaml.org,2002:' + tag.slice(2); |
| 15744 | } |
| 15745 | |
| 15746 | type = schema.compiledTypeMap[tag]; |
| 15747 | |
| 15748 | if (type && _hasOwnProperty.call(type.styleAliases, style)) { |
| 15749 | style = type.styleAliases[style]; |
| 15750 | } |
| 15751 | |
| 15752 | result[tag] = style; |
| 15753 | } |
| 15754 | |
| 15755 | return result; |
| 15756 | } |
| 15757 | |
| 15758 | function encodeHex(character) { |
| 15759 | var string, handle, length; |
| 15760 | |
| 15761 | string = character.toString(16).toUpperCase(); |
| 15762 | |
| 15763 | if (character <= 0xFF) { |
| 15764 | handle = 'x'; |
| 15765 | length = 2; |
| 15766 | } else if (character <= 0xFFFF) { |
| 15767 | handle = 'u'; |
| 15768 | length = 4; |
| 15769 | } else if (character <= 0xFFFFFFFF) { |
| 15770 | handle = 'U'; |
| 15771 | length = 8; |
| 15772 | } else { |
| 15773 | throw new YAMLException('code point within a string may not be greater than 0xFFFFFFFF'); |
| 15774 | } |
| 15775 | |
| 15776 | return '\\' + handle + common.repeat('0', length - string.length) + string; |
| 15777 | } |
| 15778 | |
| 15779 | function State(options) { |
| 15780 | this.schema = options['schema'] || DEFAULT_FULL_SCHEMA; |
| 15781 | this.indent = Math.max(1, (options['indent'] || 2)); |
| 15782 | this.skipInvalid = options['skipInvalid'] || false; |
| 15783 | this.flowLevel = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']); |
| 15784 | this.styleMap = compileStyleMap(this.schema, options['styles'] || null); |
| 15785 | this.sortKeys = options['sortKeys'] || false; |
| 15786 | |
| 15787 | this.implicitTypes = this.schema.compiledImplicit; |
| 15788 | this.explicitTypes = this.schema.compiledExplicit; |
| 15789 | |
| 15790 | this.tag = null; |
| 15791 | this.result = ''; |
| 15792 | |
| 15793 | this.duplicates = []; |
| 15794 | this.usedDuplicates = null; |
| 15795 | } |
| 15796 | |
| 15797 | function indentString(string, spaces) { |
| 15798 | var ind = common.repeat(' ', spaces), |
| 15799 | position = 0, |
| 15800 | next = -1, |
| 15801 | result = '', |
| 15802 | line, |
| 15803 | length = string.length; |
| 15804 | |
| 15805 | while (position < length) { |
| 15806 | next = string.indexOf('\n', position); |
| 15807 | if (next === -1) { |
| 15808 | line = string.slice(position); |
| 15809 | position = length; |
| 15810 | } else { |
| 15811 | line = string.slice(position, next + 1); |
| 15812 | position = next + 1; |
| 15813 | } |
| 15814 | if (line.length && line !== '\n') { |
| 15815 | result += ind; |
| 15816 | } |
| 15817 | result += line; |
| 15818 | } |
| 15819 | |
| 15820 | return result; |
| 15821 | } |
| 15822 | |
| 15823 | function generateNextLine(state, level) { |
| 15824 | return '\n' + common.repeat(' ', state.indent * level); |
| 15825 | } |
| 15826 | |
| 15827 | function testImplicitResolving(state, str) { |
| 15828 | var index, length, type; |
| 15829 | |
| 15830 | for (index = 0, length = state.implicitTypes.length; index < length; index += 1) { |
| 15831 | type = state.implicitTypes[index]; |
| 15832 | |
| 15833 | if (type.resolve(str)) { |
| 15834 | return true; |
| 15835 | } |
| 15836 | } |
| 15837 | |
| 15838 | return false; |
| 15839 | } |
| 15840 | |
| 15841 | function StringBuilder(source) { |
| 15842 | this.source = source; |
| 15843 | this.result = ''; |
| 15844 | this.checkpoint = 0; |
| 15845 | } |
| 15846 | |
| 15847 | StringBuilder.prototype.takeUpTo = function (position) { |
| 15848 | var er; |
| 15849 | |
| 15850 | if (position < this.checkpoint) { |
| 15851 | er = new Error('position should be > checkpoint'); |
| 15852 | er.position = position; |
| 15853 | er.checkpoint = this.checkpoint; |
| 15854 | throw er; |
| 15855 | } |
| 15856 | |
| 15857 | this.result += this.source.slice(this.checkpoint, position); |
| 15858 | this.checkpoint = position; |
| 15859 | return this; |
| 15860 | }; |
| 15861 | |
| 15862 | StringBuilder.prototype.escapeChar = function () { |
| 15863 | var character, esc; |
| 15864 | |
| 15865 | character = this.source.charCodeAt(this.checkpoint); |
| 15866 | esc = ESCAPE_SEQUENCES[character] || encodeHex(character); |
| 15867 | this.result += esc; |
| 15868 | this.checkpoint += 1; |
| 15869 | |
| 15870 | return this; |
| 15871 | }; |
| 15872 | |
| 15873 | StringBuilder.prototype.finish = function () { |
| 15874 | if (this.source.length > this.checkpoint) { |
| 15875 | this.takeUpTo(this.source.length); |
| 15876 | } |
| 15877 | }; |
| 15878 | |
| 15879 | function writeScalar(state, object, level) { |
| 15880 | var simple, first, spaceWrap, folded, literal, single, double, |
| 15881 | sawLineFeed, linePosition, longestLine, indent, max, character, |
| 15882 | position, escapeSeq, hexEsc, previous, lineLength, modifier, |
| 15883 | trailingLineBreaks, result; |
| 15884 | |
| 15885 | if (0 === object.length) { |
| 15886 | state.dump = "''"; |
| 15887 | return; |
| 15888 | } |
| 15889 | |
| 15890 | if (-1 !== DEPRECATED_BOOLEANS_SYNTAX.indexOf(object)) { |
| 15891 | state.dump = "'" + object + "'"; |
| 15892 | return; |
| 15893 | } |
| 15894 | |
| 15895 | simple = true; |
| 15896 | first = object.length ? object.charCodeAt(0) : 0; |
| 15897 | spaceWrap = (CHAR_SPACE === first || |
| 15898 | CHAR_SPACE === object.charCodeAt(object.length - 1)); |
| 15899 | |
| 15900 | // Simplified check for restricted first characters |
| 15901 | // http://www.yaml.org/spec/1.2/spec.html#ns-plain-first%28c%29 |
| 15902 | if (CHAR_MINUS === first || |
| 15903 | CHAR_QUESTION === first || |
| 15904 | CHAR_COMMERCIAL_AT === first || |
| 15905 | CHAR_GRAVE_ACCENT === first) { |
| 15906 | simple = false; |
| 15907 | } |
| 15908 | |
| 15909 | // can only use > and | if not wrapped in spaces. |
| 15910 | if (spaceWrap) { |
| 15911 | simple = false; |
| 15912 | folded = false; |
| 15913 | literal = false; |
| 15914 | } else { |
| 15915 | folded = true; |
| 15916 | literal = true; |
| 15917 | } |
| 15918 | |
| 15919 | single = true; |
| 15920 | double = new StringBuilder(object); |
| 15921 | |
| 15922 | sawLineFeed = false; |
| 15923 | linePosition = 0; |
| 15924 | longestLine = 0; |
| 15925 | |
| 15926 | indent = state.indent * level; |
| 15927 | max = 80; |
| 15928 | if (indent < 40) { |
| 15929 | max -= indent; |
| 15930 | } else { |
| 15931 | max = 40; |
| 15932 | } |
| 15933 | |
| 15934 | for (position = 0; position < object.length; position++) { |
| 15935 | character = object.charCodeAt(position); |
| 15936 | if (simple) { |
| 15937 | // Characters that can never appear in the simple scalar |
| 15938 | if (!simpleChar(character)) { |
| 15939 | simple = false; |
| 15940 | } else { |
| 15941 | // Still simple. If we make it all the way through like |
| 15942 | // this, then we can just dump the string as-is. |
| 15943 | continue; |
| 15944 | } |
| 15945 | } |
| 15946 | |
| 15947 | if (single && character === CHAR_SINGLE_QUOTE) { |
| 15948 | single = false; |
| 15949 | } |
| 15950 | |
| 15951 | escapeSeq = ESCAPE_SEQUENCES[character]; |
| 15952 | hexEsc = needsHexEscape(character); |
| 15953 | |
| 15954 | if (!escapeSeq && !hexEsc) { |
| 15955 | continue; |
| 15956 | } |
| 15957 | |
| 15958 | if (character !== CHAR_LINE_FEED && |
| 15959 | character !== CHAR_DOUBLE_QUOTE && |
| 15960 | character !== CHAR_SINGLE_QUOTE) { |
| 15961 | folded = false; |
| 15962 | literal = false; |
| 15963 | } else if (character === CHAR_LINE_FEED) { |
| 15964 | sawLineFeed = true; |
| 15965 | single = false; |
| 15966 | if (position > 0) { |
| 15967 | previous = object.charCodeAt(position - 1); |
| 15968 | if (previous === CHAR_SPACE) { |
| 15969 | literal = false; |
| 15970 | folded = false; |
| 15971 | } |
| 15972 | } |
| 15973 | if (folded) { |
| 15974 | lineLength = position - linePosition; |
| 15975 | linePosition = position; |
| 15976 | if (lineLength > longestLine) { |
| 15977 | longestLine = lineLength; |
| 15978 | } |
| 15979 | } |
| 15980 | } |
| 15981 | |
| 15982 | if (character !== CHAR_DOUBLE_QUOTE) { |
| 15983 | single = false; |
| 15984 | } |
| 15985 | |
| 15986 | double.takeUpTo(position); |
| 15987 | double.escapeChar(); |
| 15988 | } |
| 15989 | |
| 15990 | if (simple && testImplicitResolving(state, object)) { |
| 15991 | simple = false; |
| 15992 | } |
| 15993 | |
| 15994 | modifier = ''; |
| 15995 | if (folded || literal) { |
| 15996 | trailingLineBreaks = 0; |
| 15997 | if (object.charCodeAt(object.length - 1) === CHAR_LINE_FEED) { |
| 15998 | trailingLineBreaks += 1; |
| 15999 | if (object.charCodeAt(object.length - 2) === CHAR_LINE_FEED) { |
| 16000 | trailingLineBreaks += 1; |
| 16001 | } |
| 16002 | } |
| 16003 | |
| 16004 | if (trailingLineBreaks === 0) { |
| 16005 | modifier = '-'; |
| 16006 | } else if (trailingLineBreaks === 2) { |
| 16007 | modifier = '+'; |
| 16008 | } |
| 16009 | } |
| 16010 | |
| 16011 | if (literal && longestLine < max) { |
| 16012 | folded = false; |
| 16013 | } |
| 16014 | |
| 16015 | // If it's literally one line, then don't bother with the literal. |
| 16016 | // We may still want to do a fold, though, if it's a super long line. |
| 16017 | if (!sawLineFeed) { |
| 16018 | literal = false; |
| 16019 | } |
| 16020 | |
| 16021 | if (simple) { |
| 16022 | state.dump = object; |
| 16023 | } else if (single) { |
| 16024 | state.dump = '\'' + object + '\''; |
| 16025 | } else if (folded) { |
| 16026 | result = fold(object, max); |
| 16027 | state.dump = '>' + modifier + '\n' + indentString(result, indent); |
| 16028 | } else if (literal) { |
| 16029 | if (!modifier) { |
| 16030 | object = object.replace(/\n$/, ''); |
| 16031 | } |
| 16032 | state.dump = '|' + modifier + '\n' + indentString(object, indent); |
| 16033 | } else if (double) { |
| 16034 | double.finish(); |
| 16035 | state.dump = '"' + double.result + '"'; |
| 16036 | } else { |
| 16037 | throw new Error('Failed to dump scalar value'); |
| 16038 | } |
| 16039 | |
| 16040 | return; |
| 16041 | } |
| 16042 | |
| 16043 | // The `trailing` var is a regexp match of any trailing `\n` characters. |
| 16044 | // |
| 16045 | // There are three cases we care about: |
| 16046 | // |
| 16047 | // 1. One trailing `\n` on the string. Just use `|` or `>`. |
| 16048 | // This is the assumed default. (trailing = null) |
| 16049 | // 2. No trailing `\n` on the string. Use `|-` or `>-` to "chomp" the end. |
| 16050 | // 3. More than one trailing `\n` on the string. Use `|+` or `>+`. |
| 16051 | // |
| 16052 | // In the case of `>+`, these line breaks are *not* doubled (like the line |
| 16053 | // breaks within the string), so it's important to only end with the exact |
| 16054 | // same number as we started. |
| 16055 | function fold(object, max) { |
| 16056 | var result = '', |
| 16057 | position = 0, |
| 16058 | length = object.length, |
| 16059 | trailing = /\n+$/.exec(object), |
| 16060 | newLine; |
| 16061 | |
| 16062 | if (trailing) { |
| 16063 | length = trailing.index + 1; |
| 16064 | } |
| 16065 | |
| 16066 | while (position < length) { |
| 16067 | newLine = object.indexOf('\n', position); |
| 16068 | if (newLine > length || newLine === -1) { |
| 16069 | if (result) { |
| 16070 | result += '\n\n'; |
| 16071 | } |
| 16072 | result += foldLine(object.slice(position, length), max); |
| 16073 | position = length; |
| 16074 | } else { |
| 16075 | if (result) { |
| 16076 | result += '\n\n'; |
| 16077 | } |
| 16078 | result += foldLine(object.slice(position, newLine), max); |
| 16079 | position = newLine + 1; |
| 16080 | } |
| 16081 | } |
| 16082 | if (trailing && trailing[0] !== '\n') { |
| 16083 | result += trailing[0]; |
| 16084 | } |
| 16085 | |
| 16086 | return result; |
| 16087 | } |
| 16088 | |
| 16089 | function foldLine(line, max) { |
| 16090 | if (line === '') { |
| 16091 | return line; |
| 16092 | } |
| 16093 | |
| 16094 | var foldRe = /[^\s] [^\s]/g, |
| 16095 | result = '', |
| 16096 | prevMatch = 0, |
| 16097 | foldStart = 0, |
| 16098 | match = foldRe.exec(line), |
| 16099 | index, |
| 16100 | foldEnd, |
| 16101 | folded; |
| 16102 | |
| 16103 | while (match) { |
| 16104 | index = match.index; |
| 16105 | |
| 16106 | // when we cross the max len, if the previous match would've |
| 16107 | // been ok, use that one, and carry on. If there was no previous |
| 16108 | // match on this fold section, then just have a long line. |
| 16109 | if (index - foldStart > max) { |
| 16110 | if (prevMatch !== foldStart) { |
| 16111 | foldEnd = prevMatch; |
| 16112 | } else { |
| 16113 | foldEnd = index; |
| 16114 | } |
| 16115 | |
| 16116 | if (result) { |
| 16117 | result += '\n'; |
| 16118 | } |
| 16119 | folded = line.slice(foldStart, foldEnd); |
| 16120 | result += folded; |
| 16121 | foldStart = foldEnd + 1; |
| 16122 | } |
| 16123 | prevMatch = index + 1; |
| 16124 | match = foldRe.exec(line); |
| 16125 | } |
| 16126 | |
| 16127 | if (result) { |
| 16128 | result += '\n'; |
| 16129 | } |
| 16130 | |
| 16131 | // if we end up with one last word at the end, then the last bit might |
| 16132 | // be slightly bigger than we wanted, because we exited out of the loop. |
| 16133 | if (foldStart !== prevMatch && line.length - foldStart > max) { |
| 16134 | result += line.slice(foldStart, prevMatch) + '\n' + |
| 16135 | line.slice(prevMatch + 1); |
| 16136 | } else { |
| 16137 | result += line.slice(foldStart); |
| 16138 | } |
| 16139 | |
| 16140 | return result; |
| 16141 | } |
| 16142 | |
| 16143 | // Returns true if character can be found in a simple scalar |
| 16144 | function simpleChar(character) { |
| 16145 | return CHAR_TAB !== character && |
| 16146 | CHAR_LINE_FEED !== character && |
| 16147 | CHAR_CARRIAGE_RETURN !== character && |
| 16148 | CHAR_COMMA !== character && |
| 16149 | CHAR_LEFT_SQUARE_BRACKET !== character && |
| 16150 | CHAR_RIGHT_SQUARE_BRACKET !== character && |
| 16151 | CHAR_LEFT_CURLY_BRACKET !== character && |
| 16152 | CHAR_RIGHT_CURLY_BRACKET !== character && |
| 16153 | CHAR_SHARP !== character && |
| 16154 | CHAR_AMPERSAND !== character && |
| 16155 | CHAR_ASTERISK !== character && |
| 16156 | CHAR_EXCLAMATION !== character && |
| 16157 | CHAR_VERTICAL_LINE !== character && |
| 16158 | CHAR_GREATER_THAN !== character && |
| 16159 | CHAR_SINGLE_QUOTE !== character && |
| 16160 | CHAR_DOUBLE_QUOTE !== character && |
| 16161 | CHAR_PERCENT !== character && |
| 16162 | CHAR_COLON !== character && |
| 16163 | !ESCAPE_SEQUENCES[character] && |
| 16164 | !needsHexEscape(character); |
| 16165 | } |
| 16166 | |
| 16167 | // Returns true if the character code needs to be escaped. |
| 16168 | function needsHexEscape(character) { |
| 16169 | return !((0x00020 <= character && character <= 0x00007E) || |
| 16170 | (0x00085 === character) || |
| 16171 | (0x000A0 <= character && character <= 0x00D7FF) || |
| 16172 | (0x0E000 <= character && character <= 0x00FFFD) || |
| 16173 | (0x10000 <= character && character <= 0x10FFFF)); |
| 16174 | } |
| 16175 | |
| 16176 | function writeFlowSequence(state, level, object) { |
| 16177 | var _result = '', |
| 16178 | _tag = state.tag, |
| 16179 | index, |
| 16180 | length; |
| 16181 | |
| 16182 | for (index = 0, length = object.length; index < length; index += 1) { |
| 16183 | // Write only valid elements. |
| 16184 | if (writeNode(state, level, object[index], false, false)) { |
| 16185 | if (0 !== index) { |
| 16186 | _result += ', '; |
| 16187 | } |
| 16188 | _result += state.dump; |
| 16189 | } |
| 16190 | } |
| 16191 | |
| 16192 | state.tag = _tag; |
| 16193 | state.dump = '[' + _result + ']'; |
| 16194 | } |
| 16195 | |
| 16196 | function writeBlockSequence(state, level, object, compact) { |
| 16197 | var _result = '', |
| 16198 | _tag = state.tag, |
| 16199 | index, |
| 16200 | length; |
| 16201 | |
| 16202 | for (index = 0, length = object.length; index < length; index += 1) { |
| 16203 | // Write only valid elements. |
| 16204 | if (writeNode(state, level + 1, object[index], true, true)) { |
| 16205 | if (!compact || 0 !== index) { |
| 16206 | _result += generateNextLine(state, level); |
| 16207 | } |
| 16208 | _result += '- ' + state.dump; |
| 16209 | } |
| 16210 | } |
| 16211 | |
| 16212 | state.tag = _tag; |
| 16213 | state.dump = _result || '[]'; // Empty sequence if no valid values. |
| 16214 | } |
| 16215 | |
| 16216 | function writeFlowMapping(state, level, object) { |
| 16217 | var _result = '', |
| 16218 | _tag = state.tag, |
| 16219 | objectKeyList = Object.keys(object), |
| 16220 | index, |
| 16221 | length, |
| 16222 | objectKey, |
| 16223 | objectValue, |
| 16224 | pairBuffer; |
| 16225 | |
| 16226 | for (index = 0, length = objectKeyList.length; index < length; index += 1) { |
| 16227 | pairBuffer = ''; |
| 16228 | |
| 16229 | if (0 !== index) { |
| 16230 | pairBuffer += ', '; |
| 16231 | } |
| 16232 | |
| 16233 | objectKey = objectKeyList[index]; |
| 16234 | objectValue = object[objectKey]; |
| 16235 | |
| 16236 | if (!writeNode(state, level, objectKey, false, false)) { |
| 16237 | continue; // Skip this pair because of invalid key; |
| 16238 | } |
| 16239 | |
| 16240 | if (state.dump.length > 1024) { |
| 16241 | pairBuffer += '? '; |
| 16242 | } |
| 16243 | |
| 16244 | pairBuffer += state.dump + ': '; |
| 16245 | |
| 16246 | if (!writeNode(state, level, objectValue, false, false)) { |
| 16247 | continue; // Skip this pair because of invalid value. |
| 16248 | } |
| 16249 | |
| 16250 | pairBuffer += state.dump; |
| 16251 | |
| 16252 | // Both key and value are valid. |
| 16253 | _result += pairBuffer; |
| 16254 | } |
| 16255 | |
| 16256 | state.tag = _tag; |
| 16257 | state.dump = '{' + _result + '}'; |
| 16258 | } |
| 16259 | |
| 16260 | function writeBlockMapping(state, level, object, compact) { |
| 16261 | var _result = '', |
| 16262 | _tag = state.tag, |
| 16263 | objectKeyList = Object.keys(object), |
| 16264 | index, |
| 16265 | length, |
| 16266 | objectKey, |
| 16267 | objectValue, |
| 16268 | explicitPair, |
| 16269 | pairBuffer; |
| 16270 | |
| 16271 | // Allow sorting keys so that the output file is deterministic |
| 16272 | if (state.sortKeys === true) { |
| 16273 | // Default sorting |
| 16274 | objectKeyList.sort(); |
| 16275 | } else if (typeof state.sortKeys === 'function') { |
| 16276 | // Custom sort function |
| 16277 | objectKeyList.sort(state.sortKeys); |
| 16278 | } else if (state.sortKeys) { |
| 16279 | // Something is wrong |
| 16280 | throw new YAMLException('sortKeys must be a boolean or a function'); |
| 16281 | } |
| 16282 | |
| 16283 | for (index = 0, length = objectKeyList.length; index < length; index += 1) { |
| 16284 | pairBuffer = ''; |
| 16285 | |
| 16286 | if (!compact || 0 !== index) { |
| 16287 | pairBuffer += generateNextLine(state, level); |
| 16288 | } |
| 16289 | |
| 16290 | objectKey = objectKeyList[index]; |
| 16291 | objectValue = object[objectKey]; |
| 16292 | |
| 16293 | if (!writeNode(state, level + 1, objectKey, true, true)) { |
| 16294 | continue; // Skip this pair because of invalid key. |
| 16295 | } |
| 16296 | |
| 16297 | explicitPair = (null !== state.tag && '?' !== state.tag) || |
| 16298 | (state.dump && state.dump.length > 1024); |
| 16299 | |
| 16300 | if (explicitPair) { |
| 16301 | if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { |
| 16302 | pairBuffer += '?'; |
| 16303 | } else { |
| 16304 | pairBuffer += '? '; |
| 16305 | } |
| 16306 | } |
| 16307 | |
| 16308 | pairBuffer += state.dump; |
| 16309 | |
| 16310 | if (explicitPair) { |
| 16311 | pairBuffer += generateNextLine(state, level); |
| 16312 | } |
| 16313 | |
| 16314 | if (!writeNode(state, level + 1, objectValue, true, explicitPair)) { |
| 16315 | continue; // Skip this pair because of invalid value. |
| 16316 | } |
| 16317 | |
| 16318 | if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { |
| 16319 | pairBuffer += ':'; |
| 16320 | } else { |
| 16321 | pairBuffer += ': '; |
| 16322 | } |
| 16323 | |
| 16324 | pairBuffer += state.dump; |
| 16325 | |
| 16326 | // Both key and value are valid. |
| 16327 | _result += pairBuffer; |
| 16328 | } |
| 16329 | |
| 16330 | state.tag = _tag; |
| 16331 | state.dump = _result || '{}'; // Empty mapping if no valid pairs. |
| 16332 | } |
| 16333 | |
| 16334 | function detectType(state, object, explicit) { |
| 16335 | var _result, typeList, index, length, type, style; |
| 16336 | |
| 16337 | typeList = explicit ? state.explicitTypes : state.implicitTypes; |
| 16338 | |
| 16339 | for (index = 0, length = typeList.length; index < length; index += 1) { |
| 16340 | type = typeList[index]; |
| 16341 | |
| 16342 | if ((type.instanceOf || type.predicate) && |
| 16343 | (!type.instanceOf || (('object' === typeof object) && (object instanceof type.instanceOf))) && |
| 16344 | (!type.predicate || type.predicate(object))) { |
| 16345 | |
| 16346 | state.tag = explicit ? type.tag : '?'; |
| 16347 | |
| 16348 | if (type.represent) { |
| 16349 | style = state.styleMap[type.tag] || type.defaultStyle; |
| 16350 | |
| 16351 | if ('[object Function]' === _toString.call(type.represent)) { |
| 16352 | _result = type.represent(object, style); |
| 16353 | } else if (_hasOwnProperty.call(type.represent, style)) { |
| 16354 | _result = type.represent[style](object, style); |
| 16355 | } else { |
| 16356 | throw new YAMLException('!<' + type.tag + '> tag resolver accepts not "' + style + '" style'); |
| 16357 | } |
| 16358 | |
| 16359 | state.dump = _result; |
| 16360 | } |
| 16361 | |
| 16362 | return true; |
| 16363 | } |
| 16364 | } |
| 16365 | |
| 16366 | return false; |
| 16367 | } |
| 16368 | |
| 16369 | // Serializes `object` and writes it to global `result`. |
| 16370 | // Returns true on success, or false on invalid object. |
| 16371 | // |
| 16372 | function writeNode(state, level, object, block, compact) { |
| 16373 | state.tag = null; |
| 16374 | state.dump = object; |
| 16375 | |
| 16376 | if (!detectType(state, object, false)) { |
| 16377 | detectType(state, object, true); |
| 16378 | } |
| 16379 | |
| 16380 | var type = _toString.call(state.dump); |
| 16381 | |
| 16382 | if (block) { |
| 16383 | block = (0 > state.flowLevel || state.flowLevel > level); |
| 16384 | } |
| 16385 | |
| 16386 | if ((null !== state.tag && '?' !== state.tag) || (2 !== state.indent && level > 0)) { |
| 16387 | compact = false; |
| 16388 | } |
| 16389 | |
| 16390 | var objectOrArray = '[object Object]' === type || '[object Array]' === type, |
| 16391 | duplicateIndex, |
| 16392 | duplicate; |
| 16393 | |
| 16394 | if (objectOrArray) { |
| 16395 | duplicateIndex = state.duplicates.indexOf(object); |
| 16396 | duplicate = duplicateIndex !== -1; |
| 16397 | } |
| 16398 | |
| 16399 | if (duplicate && state.usedDuplicates[duplicateIndex]) { |
| 16400 | state.dump = '*ref_' + duplicateIndex; |
| 16401 | } else { |
| 16402 | if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) { |
| 16403 | state.usedDuplicates[duplicateIndex] = true; |
| 16404 | } |
| 16405 | if ('[object Object]' === type) { |
| 16406 | if (block && (0 !== Object.keys(state.dump).length)) { |
| 16407 | writeBlockMapping(state, level, state.dump, compact); |
| 16408 | if (duplicate) { |
| 16409 | state.dump = '&ref_' + duplicateIndex + (0 === level ? '\n' : '') + state.dump; |
| 16410 | } |
| 16411 | } else { |
| 16412 | writeFlowMapping(state, level, state.dump); |
| 16413 | if (duplicate) { |
| 16414 | state.dump = '&ref_' + duplicateIndex + ' ' + state.dump; |
| 16415 | } |
| 16416 | } |
| 16417 | } else if ('[object Array]' === type) { |
| 16418 | if (block && (0 !== state.dump.length)) { |
| 16419 | writeBlockSequence(state, level, state.dump, compact); |
| 16420 | if (duplicate) { |
| 16421 | state.dump = '&ref_' + duplicateIndex + (0 === level ? '\n' : '') + state.dump; |
| 16422 | } |
| 16423 | } else { |
| 16424 | writeFlowSequence(state, level, state.dump); |
| 16425 | if (duplicate) { |
| 16426 | state.dump = '&ref_' + duplicateIndex + ' ' + state.dump; |
| 16427 | } |
| 16428 | } |
| 16429 | } else if ('[object String]' === type) { |
| 16430 | if ('?' !== state.tag) { |
| 16431 | writeScalar(state, state.dump, level); |
| 16432 | } |
| 16433 | } else { |
| 16434 | if (state.skipInvalid) { |
| 16435 | return false; |
| 16436 | } |
| 16437 | throw new YAMLException('unacceptable kind of an object to dump ' + type); |
| 16438 | } |
| 16439 | |
| 16440 | if (null !== state.tag && '?' !== state.tag) { |
| 16441 | state.dump = '!<' + state.tag + '> ' + state.dump; |
| 16442 | } |
| 16443 | } |
| 16444 | |
| 16445 | return true; |
| 16446 | } |
| 16447 | |
| 16448 | function getDuplicateReferences(object, state) { |
| 16449 | var objects = [], |
| 16450 | duplicatesIndexes = [], |
| 16451 | index, |
| 16452 | length; |
| 16453 | |
| 16454 | inspectNode(object, objects, duplicatesIndexes); |
| 16455 | |
| 16456 | for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) { |
| 16457 | state.duplicates.push(objects[duplicatesIndexes[index]]); |
| 16458 | } |
| 16459 | state.usedDuplicates = new Array(length); |
| 16460 | } |
| 16461 | |
| 16462 | function inspectNode(object, objects, duplicatesIndexes) { |
| 16463 | var type = _toString.call(object), |
| 16464 | objectKeyList, |
| 16465 | index, |
| 16466 | length; |
| 16467 | |
| 16468 | if (null !== object && 'object' === typeof object) { |
| 16469 | index = objects.indexOf(object); |
| 16470 | if (-1 !== index) { |
| 16471 | if (-1 === duplicatesIndexes.indexOf(index)) { |
| 16472 | duplicatesIndexes.push(index); |
| 16473 | } |
| 16474 | } else { |
| 16475 | objects.push(object); |
| 16476 | |
| 16477 | if (Array.isArray(object)) { |
| 16478 | for (index = 0, length = object.length; index < length; index += 1) { |
| 16479 | inspectNode(object[index], objects, duplicatesIndexes); |
| 16480 | } |
| 16481 | } else { |
| 16482 | objectKeyList = Object.keys(object); |
| 16483 | |
| 16484 | for (index = 0, length = objectKeyList.length; index < length; index += 1) { |
| 16485 | inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes); |
| 16486 | } |
| 16487 | } |
| 16488 | } |
| 16489 | } |
| 16490 | } |
| 16491 | |
| 16492 | function dump(input, options) { |
| 16493 | options = options || {}; |
| 16494 | |
| 16495 | var state = new State(options); |
| 16496 | |
| 16497 | getDuplicateReferences(input, state); |
| 16498 | |
| 16499 | if (writeNode(state, 0, input, true, true)) { |
| 16500 | return state.dump + '\n'; |
| 16501 | } |
| 16502 | return ''; |
| 16503 | } |
| 16504 | |
| 16505 | function safeDump(input, options) { |
| 16506 | return dump(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options)); |
| 16507 | } |
| 16508 | |
| 16509 | module.exports.dump = dump; |
| 16510 | module.exports.safeDump = safeDump; |
| 16511 | |
| 16512 | },{"./common":22,"./exception":24,"./schema/default_full":29,"./schema/default_safe":30}],24:[function(require,module,exports){ |
| 16513 | 'use strict'; |
| 16514 | |
| 16515 | |
| 16516 | function YAMLException(reason, mark) { |
| 16517 | this.name = 'YAMLException'; |
| 16518 | this.reason = reason; |
| 16519 | this.mark = mark; |
| 16520 | this.message = this.toString(false); |
| 16521 | } |
| 16522 | |
| 16523 | |
| 16524 | YAMLException.prototype.toString = function toString(compact) { |
| 16525 | var result; |
| 16526 | |
| 16527 | result = 'JS-YAML: ' + (this.reason || '(unknown reason)'); |
| 16528 | |
| 16529 | if (!compact && this.mark) { |
| 16530 | result += ' ' + this.mark.toString(); |
| 16531 | } |
| 16532 | |
| 16533 | return result; |
| 16534 | }; |
| 16535 | |
| 16536 | |
| 16537 | module.exports = YAMLException; |
| 16538 | |
| 16539 | },{}],25:[function(require,module,exports){ |
| 16540 | 'use strict'; |
| 16541 | |
| 16542 | /*eslint-disable max-len,no-use-before-define*/ |
| 16543 | |
| 16544 | var common = require('./common'); |
| 16545 | var YAMLException = require('./exception'); |
| 16546 | var Mark = require('./mark'); |
| 16547 | var DEFAULT_SAFE_SCHEMA = require('./schema/default_safe'); |
| 16548 | var DEFAULT_FULL_SCHEMA = require('./schema/default_full'); |
| 16549 | |
| 16550 | |
| 16551 | var _hasOwnProperty = Object.prototype.hasOwnProperty; |
| 16552 | |
| 16553 | |
| 16554 | var CONTEXT_FLOW_IN = 1; |
| 16555 | var CONTEXT_FLOW_OUT = 2; |
| 16556 | var CONTEXT_BLOCK_IN = 3; |
| 16557 | var CONTEXT_BLOCK_OUT = 4; |
| 16558 | |
| 16559 | |
| 16560 | var CHOMPING_CLIP = 1; |
| 16561 | var CHOMPING_STRIP = 2; |
| 16562 | var CHOMPING_KEEP = 3; |
| 16563 | |
| 16564 | |
| 16565 | var PATTERN_NON_PRINTABLE = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/; |
| 16566 | var PATTERN_NON_ASCII_LINE_BREAKS = /[\x85\u2028\u2029]/; |
| 16567 | var PATTERN_FLOW_INDICATORS = /[,\[\]\{\}]/; |
| 16568 | var PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\-]+!)$/i; |
| 16569 | var PATTERN_TAG_URI = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i; |
| 16570 | |
| 16571 | |
| 16572 | function is_EOL(c) { |
| 16573 | return (c === 0x0A/* LF */) || (c === 0x0D/* CR */); |
| 16574 | } |
| 16575 | |
| 16576 | function is_WHITE_SPACE(c) { |
| 16577 | return (c === 0x09/* Tab */) || (c === 0x20/* Space */); |
| 16578 | } |
| 16579 | |
| 16580 | function is_WS_OR_EOL(c) { |
| 16581 | return (c === 0x09/* Tab */) || |
| 16582 | (c === 0x20/* Space */) || |
| 16583 | (c === 0x0A/* LF */) || |
| 16584 | (c === 0x0D/* CR */); |
| 16585 | } |
| 16586 | |
| 16587 | function is_FLOW_INDICATOR(c) { |
| 16588 | return 0x2C/* , */ === c || |
| 16589 | 0x5B/* [ */ === c || |
| 16590 | 0x5D/* ] */ === c || |
| 16591 | 0x7B/* { */ === c || |
| 16592 | 0x7D/* } */ === c; |
| 16593 | } |
| 16594 | |
| 16595 | function fromHexCode(c) { |
| 16596 | var lc; |
| 16597 | |
| 16598 | if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) { |
| 16599 | return c - 0x30; |
| 16600 | } |
| 16601 | |
| 16602 | /*eslint-disable no-bitwise*/ |
| 16603 | lc = c | 0x20; |
| 16604 | |
| 16605 | if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) { |
| 16606 | return lc - 0x61 + 10; |
| 16607 | } |
| 16608 | |
| 16609 | return -1; |
| 16610 | } |
| 16611 | |
| 16612 | function escapedHexLen(c) { |
| 16613 | if (c === 0x78/* x */) { return 2; } |
| 16614 | if (c === 0x75/* u */) { return 4; } |
| 16615 | if (c === 0x55/* U */) { return 8; } |
| 16616 | return 0; |
| 16617 | } |
| 16618 | |
| 16619 | function fromDecimalCode(c) { |
| 16620 | if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) { |
| 16621 | return c - 0x30; |
| 16622 | } |
| 16623 | |
| 16624 | return -1; |
| 16625 | } |
| 16626 | |
| 16627 | function simpleEscapeSequence(c) { |
| 16628 | return (c === 0x30/* 0 */) ? '\x00' : |
| 16629 | (c === 0x61/* a */) ? '\x07' : |
| 16630 | (c === 0x62/* b */) ? '\x08' : |
| 16631 | (c === 0x74/* t */) ? '\x09' : |
| 16632 | (c === 0x09/* Tab */) ? '\x09' : |
| 16633 | (c === 0x6E/* n */) ? '\x0A' : |
| 16634 | (c === 0x76/* v */) ? '\x0B' : |
| 16635 | (c === 0x66/* f */) ? '\x0C' : |
| 16636 | (c === 0x72/* r */) ? '\x0D' : |
| 16637 | (c === 0x65/* e */) ? '\x1B' : |
| 16638 | (c === 0x20/* Space */) ? ' ' : |
| 16639 | (c === 0x22/* " */) ? '\x22' : |
| 16640 | (c === 0x2F/* / */) ? '/' : |
| 16641 | (c === 0x5C/* \ */) ? '\x5C' : |
| 16642 | (c === 0x4E/* N */) ? '\x85' : |
| 16643 | (c === 0x5F/* _ */) ? '\xA0' : |
| 16644 | (c === 0x4C/* L */) ? '\u2028' : |
| 16645 | (c === 0x50/* P */) ? '\u2029' : ''; |
| 16646 | } |
| 16647 | |
| 16648 | function charFromCodepoint(c) { |
| 16649 | if (c <= 0xFFFF) { |
| 16650 | return String.fromCharCode(c); |
| 16651 | } |
| 16652 | // Encode UTF-16 surrogate pair |
| 16653 | // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF |
| 16654 | return String.fromCharCode(((c - 0x010000) >> 10) + 0xD800, |
| 16655 | ((c - 0x010000) & 0x03FF) + 0xDC00); |
| 16656 | } |
| 16657 | |
| 16658 | var simpleEscapeCheck = new Array(256); // integer, for fast access |
| 16659 | var simpleEscapeMap = new Array(256); |
| 16660 | for (var i = 0; i < 256; i++) { |
| 16661 | simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0; |
| 16662 | simpleEscapeMap[i] = simpleEscapeSequence(i); |
| 16663 | } |
| 16664 | |
| 16665 | |
| 16666 | function State(input, options) { |
| 16667 | this.input = input; |
| 16668 | |
| 16669 | this.filename = options['filename'] || null; |
| 16670 | this.schema = options['schema'] || DEFAULT_FULL_SCHEMA; |
| 16671 | this.onWarning = options['onWarning'] || null; |
| 16672 | this.legacy = options['legacy'] || false; |
| 16673 | |
| 16674 | this.implicitTypes = this.schema.compiledImplicit; |
| 16675 | this.typeMap = this.schema.compiledTypeMap; |
| 16676 | |
| 16677 | this.length = input.length; |
| 16678 | this.position = 0; |
| 16679 | this.line = 0; |
| 16680 | this.lineStart = 0; |
| 16681 | this.lineIndent = 0; |
| 16682 | |
| 16683 | this.documents = []; |
| 16684 | |
| 16685 | /* |
| 16686 | this.version; |
| 16687 | this.checkLineBreaks; |
| 16688 | this.tagMap; |
| 16689 | this.anchorMap; |
| 16690 | this.tag; |
| 16691 | this.anchor; |
| 16692 | this.kind; |
| 16693 | this.result;*/ |
| 16694 | |
| 16695 | } |
| 16696 | |
| 16697 | |
| 16698 | function generateError(state, message) { |
| 16699 | return new YAMLException( |
| 16700 | message, |
| 16701 | new Mark(state.filename, state.input, state.position, state.line, (state.position - state.lineStart))); |
| 16702 | } |
| 16703 | |
| 16704 | function throwError(state, message) { |
| 16705 | throw generateError(state, message); |
| 16706 | } |
| 16707 | |
| 16708 | function throwWarning(state, message) { |
| 16709 | var error = generateError(state, message); |
| 16710 | |
| 16711 | if (state.onWarning) { |
| 16712 | state.onWarning.call(null, error); |
| 16713 | } else { |
| 16714 | throw error; |
| 16715 | } |
| 16716 | } |
| 16717 | |
| 16718 | |
| 16719 | var directiveHandlers = { |
| 16720 | |
| 16721 | YAML: function handleYamlDirective(state, name, args) { |
| 16722 | |
| 16723 | var match, major, minor; |
| 16724 | |
| 16725 | if (null !== state.version) { |
| 16726 | throwError(state, 'duplication of %YAML directive'); |
| 16727 | } |
| 16728 | |
| 16729 | if (1 !== args.length) { |
| 16730 | throwError(state, 'YAML directive accepts exactly one argument'); |
| 16731 | } |
| 16732 | |
| 16733 | match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]); |
| 16734 | |
| 16735 | if (null === match) { |
| 16736 | throwError(state, 'ill-formed argument of the YAML directive'); |
| 16737 | } |
| 16738 | |
| 16739 | major = parseInt(match[1], 10); |
| 16740 | minor = parseInt(match[2], 10); |
| 16741 | |
| 16742 | if (1 !== major) { |
| 16743 | throwError(state, 'unacceptable YAML version of the document'); |
| 16744 | } |
| 16745 | |
| 16746 | state.version = args[0]; |
| 16747 | state.checkLineBreaks = (minor < 2); |
| 16748 | |
| 16749 | if (1 !== minor && 2 !== minor) { |
| 16750 | throwWarning(state, 'unsupported YAML version of the document'); |
| 16751 | } |
| 16752 | }, |
| 16753 | |
| 16754 | TAG: function handleTagDirective(state, name, args) { |
| 16755 | |
| 16756 | var handle, prefix; |
| 16757 | |
| 16758 | if (2 !== args.length) { |
| 16759 | throwError(state, 'TAG directive accepts exactly two arguments'); |
| 16760 | } |
| 16761 | |
| 16762 | handle = args[0]; |
| 16763 | prefix = args[1]; |
| 16764 | |
| 16765 | if (!PATTERN_TAG_HANDLE.test(handle)) { |
| 16766 | throwError(state, 'ill-formed tag handle (first argument) of the TAG directive'); |
| 16767 | } |
| 16768 | |
| 16769 | if (_hasOwnProperty.call(state.tagMap, handle)) { |
| 16770 | throwError(state, 'there is a previously declared suffix for "' + handle + '" tag handle'); |
| 16771 | } |
| 16772 | |
| 16773 | if (!PATTERN_TAG_URI.test(prefix)) { |
| 16774 | throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive'); |
| 16775 | } |
| 16776 | |
| 16777 | state.tagMap[handle] = prefix; |
| 16778 | } |
| 16779 | }; |
| 16780 | |
| 16781 | |
| 16782 | function captureSegment(state, start, end, checkJson) { |
| 16783 | var _position, _length, _character, _result; |
| 16784 | |
| 16785 | if (start < end) { |
| 16786 | _result = state.input.slice(start, end); |
| 16787 | |
| 16788 | if (checkJson) { |
| 16789 | for (_position = 0, _length = _result.length; |
| 16790 | _position < _length; |
| 16791 | _position += 1) { |
| 16792 | _character = _result.charCodeAt(_position); |
| 16793 | if (!(0x09 === _character || |
| 16794 | 0x20 <= _character && _character <= 0x10FFFF)) { |
| 16795 | throwError(state, 'expected valid JSON character'); |
| 16796 | } |
| 16797 | } |
| 16798 | } |
| 16799 | |
| 16800 | state.result += _result; |
| 16801 | } |
| 16802 | } |
| 16803 | |
| 16804 | function mergeMappings(state, destination, source) { |
| 16805 | var sourceKeys, key, index, quantity; |
| 16806 | |
| 16807 | if (!common.isObject(source)) { |
| 16808 | throwError(state, 'cannot merge mappings; the provided source object is unacceptable'); |
| 16809 | } |
| 16810 | |
| 16811 | sourceKeys = Object.keys(source); |
| 16812 | |
| 16813 | for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) { |
| 16814 | key = sourceKeys[index]; |
| 16815 | |
| 16816 | if (!_hasOwnProperty.call(destination, key)) { |
| 16817 | destination[key] = source[key]; |
| 16818 | } |
| 16819 | } |
| 16820 | } |
| 16821 | |
| 16822 | function storeMappingPair(state, _result, keyTag, keyNode, valueNode) { |
| 16823 | var index, quantity; |
| 16824 | |
| 16825 | keyNode = String(keyNode); |
| 16826 | |
| 16827 | if (null === _result) { |
| 16828 | _result = {}; |
| 16829 | } |
| 16830 | |
| 16831 | if ('tag:yaml.org,2002:merge' === keyTag) { |
| 16832 | if (Array.isArray(valueNode)) { |
| 16833 | for (index = 0, quantity = valueNode.length; index < quantity; index += 1) { |
| 16834 | mergeMappings(state, _result, valueNode[index]); |
| 16835 | } |
| 16836 | } else { |
| 16837 | mergeMappings(state, _result, valueNode); |
| 16838 | } |
| 16839 | } else { |
| 16840 | _result[keyNode] = valueNode; |
| 16841 | } |
| 16842 | |
| 16843 | return _result; |
| 16844 | } |
| 16845 | |
| 16846 | function readLineBreak(state) { |
| 16847 | var ch; |
| 16848 | |
| 16849 | ch = state.input.charCodeAt(state.position); |
| 16850 | |
| 16851 | if (0x0A/* LF */ === ch) { |
| 16852 | state.position++; |
| 16853 | } else if (0x0D/* CR */ === ch) { |
| 16854 | state.position++; |
| 16855 | if (0x0A/* LF */ === state.input.charCodeAt(state.position)) { |
| 16856 | state.position++; |
| 16857 | } |
| 16858 | } else { |
| 16859 | throwError(state, 'a line break is expected'); |
| 16860 | } |
| 16861 | |
| 16862 | state.line += 1; |
| 16863 | state.lineStart = state.position; |
| 16864 | } |
| 16865 | |
| 16866 | function skipSeparationSpace(state, allowComments, checkIndent) { |
| 16867 | var lineBreaks = 0, |
| 16868 | ch = state.input.charCodeAt(state.position); |
| 16869 | |
| 16870 | while (0 !== ch) { |
| 16871 | while (is_WHITE_SPACE(ch)) { |
| 16872 | ch = state.input.charCodeAt(++state.position); |
| 16873 | } |
| 16874 | |
| 16875 | if (allowComments && 0x23/* # */ === ch) { |
| 16876 | do { |
| 16877 | ch = state.input.charCodeAt(++state.position); |
| 16878 | } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && 0 !== ch); |
| 16879 | } |
| 16880 | |
| 16881 | if (is_EOL(ch)) { |
| 16882 | readLineBreak(state); |
| 16883 | |
| 16884 | ch = state.input.charCodeAt(state.position); |
| 16885 | lineBreaks++; |
| 16886 | state.lineIndent = 0; |
| 16887 | |
| 16888 | while (0x20/* Space */ === ch) { |
| 16889 | state.lineIndent++; |
| 16890 | ch = state.input.charCodeAt(++state.position); |
| 16891 | } |
| 16892 | } else { |
| 16893 | break; |
| 16894 | } |
| 16895 | } |
| 16896 | |
| 16897 | if (-1 !== checkIndent && 0 !== lineBreaks && state.lineIndent < checkIndent) { |
| 16898 | throwWarning(state, 'deficient indentation'); |
| 16899 | } |
| 16900 | |
| 16901 | return lineBreaks; |
| 16902 | } |
| 16903 | |
| 16904 | function testDocumentSeparator(state) { |
| 16905 | var _position = state.position, |
| 16906 | ch; |
| 16907 | |
| 16908 | ch = state.input.charCodeAt(_position); |
| 16909 | |
| 16910 | // Condition state.position === state.lineStart is tested |
| 16911 | // in parent on each call, for efficiency. No needs to test here again. |
| 16912 | if ((0x2D/* - */ === ch || 0x2E/* . */ === ch) && |
| 16913 | state.input.charCodeAt(_position + 1) === ch && |
| 16914 | state.input.charCodeAt(_position + 2) === ch) { |
| 16915 | |
| 16916 | _position += 3; |
| 16917 | |
| 16918 | ch = state.input.charCodeAt(_position); |
| 16919 | |
| 16920 | if (ch === 0 || is_WS_OR_EOL(ch)) { |
| 16921 | return true; |
| 16922 | } |
| 16923 | } |
| 16924 | |
| 16925 | return false; |
| 16926 | } |
| 16927 | |
| 16928 | function writeFoldedLines(state, count) { |
| 16929 | if (1 === count) { |
| 16930 | state.result += ' '; |
| 16931 | } else if (count > 1) { |
| 16932 | state.result += common.repeat('\n', count - 1); |
| 16933 | } |
| 16934 | } |
| 16935 | |
| 16936 | |
| 16937 | function readPlainScalar(state, nodeIndent, withinFlowCollection) { |
| 16938 | var preceding, |
| 16939 | following, |
| 16940 | captureStart, |
| 16941 | captureEnd, |
| 16942 | hasPendingContent, |
| 16943 | _line, |
| 16944 | _lineStart, |
| 16945 | _lineIndent, |
| 16946 | _kind = state.kind, |
| 16947 | _result = state.result, |
| 16948 | ch; |
| 16949 | |
| 16950 | ch = state.input.charCodeAt(state.position); |
| 16951 | |
| 16952 | if (is_WS_OR_EOL(ch) || |
| 16953 | is_FLOW_INDICATOR(ch) || |
| 16954 | 0x23/* # */ === ch || |
| 16955 | 0x26/* & */ === ch || |
| 16956 | 0x2A/* * */ === ch || |
| 16957 | 0x21/* ! */ === ch || |
| 16958 | 0x7C/* | */ === ch || |
| 16959 | 0x3E/* > */ === ch || |
| 16960 | 0x27/* ' */ === ch || |
| 16961 | 0x22/* " */ === ch || |
| 16962 | 0x25/* % */ === ch || |
| 16963 | 0x40/* @ */ === ch || |
| 16964 | 0x60/* ` */ === ch) { |
| 16965 | return false; |
| 16966 | } |
| 16967 | |
| 16968 | if (0x3F/* ? */ === ch || 0x2D/* - */ === ch) { |
| 16969 | following = state.input.charCodeAt(state.position + 1); |
| 16970 | |
| 16971 | if (is_WS_OR_EOL(following) || |
| 16972 | withinFlowCollection && is_FLOW_INDICATOR(following)) { |
| 16973 | return false; |
| 16974 | } |
| 16975 | } |
| 16976 | |
| 16977 | state.kind = 'scalar'; |
| 16978 | state.result = ''; |
| 16979 | captureStart = captureEnd = state.position; |
| 16980 | hasPendingContent = false; |
| 16981 | |
| 16982 | while (0 !== ch) { |
| 16983 | if (0x3A/* : */ === ch) { |
| 16984 | following = state.input.charCodeAt(state.position + 1); |
| 16985 | |
| 16986 | if (is_WS_OR_EOL(following) || |
| 16987 | withinFlowCollection && is_FLOW_INDICATOR(following)) { |
| 16988 | break; |
| 16989 | } |
| 16990 | |
| 16991 | } else if (0x23/* # */ === ch) { |
| 16992 | preceding = state.input.charCodeAt(state.position - 1); |
| 16993 | |
| 16994 | if (is_WS_OR_EOL(preceding)) { |
| 16995 | break; |
| 16996 | } |
| 16997 | |
| 16998 | } else if ((state.position === state.lineStart && testDocumentSeparator(state)) || |
| 16999 | withinFlowCollection && is_FLOW_INDICATOR(ch)) { |
| 17000 | break; |
| 17001 | |
| 17002 | } else if (is_EOL(ch)) { |
| 17003 | _line = state.line; |
| 17004 | _lineStart = state.lineStart; |
| 17005 | _lineIndent = state.lineIndent; |
| 17006 | skipSeparationSpace(state, false, -1); |
| 17007 | |
| 17008 | if (state.lineIndent >= nodeIndent) { |
| 17009 | hasPendingContent = true; |
| 17010 | ch = state.input.charCodeAt(state.position); |
| 17011 | continue; |
| 17012 | } else { |
| 17013 | state.position = captureEnd; |
| 17014 | state.line = _line; |
| 17015 | state.lineStart = _lineStart; |
| 17016 | state.lineIndent = _lineIndent; |
| 17017 | break; |
| 17018 | } |
| 17019 | } |
| 17020 | |
| 17021 | if (hasPendingContent) { |
| 17022 | captureSegment(state, captureStart, captureEnd, false); |
| 17023 | writeFoldedLines(state, state.line - _line); |
| 17024 | captureStart = captureEnd = state.position; |
| 17025 | hasPendingContent = false; |
| 17026 | } |
| 17027 | |
| 17028 | if (!is_WHITE_SPACE(ch)) { |
| 17029 | captureEnd = state.position + 1; |
| 17030 | } |
| 17031 | |
| 17032 | ch = state.input.charCodeAt(++state.position); |
| 17033 | } |
| 17034 | |
| 17035 | captureSegment(state, captureStart, captureEnd, false); |
| 17036 | |
| 17037 | if (state.result) { |
| 17038 | return true; |
| 17039 | } |
| 17040 | |
| 17041 | state.kind = _kind; |
| 17042 | state.result = _result; |
| 17043 | return false; |
| 17044 | } |
| 17045 | |
| 17046 | function readSingleQuotedScalar(state, nodeIndent) { |
| 17047 | var ch, |
| 17048 | captureStart, captureEnd; |
| 17049 | |
| 17050 | ch = state.input.charCodeAt(state.position); |
| 17051 | |
| 17052 | if (0x27/* ' */ !== ch) { |
| 17053 | return false; |
| 17054 | } |
| 17055 | |
| 17056 | state.kind = 'scalar'; |
| 17057 | state.result = ''; |
| 17058 | state.position++; |
| 17059 | captureStart = captureEnd = state.position; |
| 17060 | |
| 17061 | while (0 !== (ch = state.input.charCodeAt(state.position))) { |
| 17062 | if (0x27/* ' */ === ch) { |
| 17063 | captureSegment(state, captureStart, state.position, true); |
| 17064 | ch = state.input.charCodeAt(++state.position); |
| 17065 | |
| 17066 | if (0x27/* ' */ === ch) { |
| 17067 | captureStart = captureEnd = state.position; |
| 17068 | state.position++; |
| 17069 | } else { |
| 17070 | return true; |
| 17071 | } |
| 17072 | |
| 17073 | } else if (is_EOL(ch)) { |
| 17074 | captureSegment(state, captureStart, captureEnd, true); |
| 17075 | writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent)); |
| 17076 | captureStart = captureEnd = state.position; |
| 17077 | |
| 17078 | } else if (state.position === state.lineStart && testDocumentSeparator(state)) { |
| 17079 | throwError(state, 'unexpected end of the document within a single quoted scalar'); |
| 17080 | |
| 17081 | } else { |
| 17082 | state.position++; |
| 17083 | captureEnd = state.position; |
| 17084 | } |
| 17085 | } |
| 17086 | |
| 17087 | throwError(state, 'unexpected end of the stream within a single quoted scalar'); |
| 17088 | } |
| 17089 | |
| 17090 | function readDoubleQuotedScalar(state, nodeIndent) { |
| 17091 | var captureStart, |
| 17092 | captureEnd, |
| 17093 | hexLength, |
| 17094 | hexResult, |
| 17095 | tmp, tmpEsc, |
| 17096 | ch; |
| 17097 | |
| 17098 | ch = state.input.charCodeAt(state.position); |
| 17099 | |
| 17100 | if (0x22/* " */ !== ch) { |
| 17101 | return false; |
| 17102 | } |
| 17103 | |
| 17104 | state.kind = 'scalar'; |
| 17105 | state.result = ''; |
| 17106 | state.position++; |
| 17107 | captureStart = captureEnd = state.position; |
| 17108 | |
| 17109 | while (0 !== (ch = state.input.charCodeAt(state.position))) { |
| 17110 | if (0x22/* " */ === ch) { |
| 17111 | captureSegment(state, captureStart, state.position, true); |
| 17112 | state.position++; |
| 17113 | return true; |
| 17114 | |
| 17115 | } else if (0x5C/* \ */ === ch) { |
| 17116 | captureSegment(state, captureStart, state.position, true); |
| 17117 | ch = state.input.charCodeAt(++state.position); |
| 17118 | |
| 17119 | if (is_EOL(ch)) { |
| 17120 | skipSeparationSpace(state, false, nodeIndent); |
| 17121 | |
| 17122 | // TODO: rework to inline fn with no type cast? |
| 17123 | } else if (ch < 256 && simpleEscapeCheck[ch]) { |
| 17124 | state.result += simpleEscapeMap[ch]; |
| 17125 | state.position++; |
| 17126 | |
| 17127 | } else if ((tmp = escapedHexLen(ch)) > 0) { |
| 17128 | hexLength = tmp; |
| 17129 | hexResult = 0; |
| 17130 | |
| 17131 | for (; hexLength > 0; hexLength--) { |
| 17132 | ch = state.input.charCodeAt(++state.position); |
| 17133 | |
| 17134 | if ((tmp = fromHexCode(ch)) >= 0) { |
| 17135 | hexResult = (hexResult << 4) + tmp; |
| 17136 | |
| 17137 | } else { |
| 17138 | throwError(state, 'expected hexadecimal character'); |
| 17139 | } |
| 17140 | } |
| 17141 | |
| 17142 | state.result += charFromCodepoint(hexResult); |
| 17143 | |
| 17144 | state.position++; |
| 17145 | |
| 17146 | } else { |
| 17147 | throwError(state, 'unknown escape sequence'); |
| 17148 | } |
| 17149 | |
| 17150 | captureStart = captureEnd = state.position; |
| 17151 | |
| 17152 | } else if (is_EOL(ch)) { |
| 17153 | captureSegment(state, captureStart, captureEnd, true); |
| 17154 | writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent)); |
| 17155 | captureStart = captureEnd = state.position; |
| 17156 | |
| 17157 | } else if (state.position === state.lineStart && testDocumentSeparator(state)) { |
| 17158 | throwError(state, 'unexpected end of the document within a double quoted scalar'); |
| 17159 | |
| 17160 | } else { |
| 17161 | state.position++; |
| 17162 | captureEnd = state.position; |
| 17163 | } |
| 17164 | } |
| 17165 | |
| 17166 | throwError(state, 'unexpected end of the stream within a double quoted scalar'); |
| 17167 | } |
| 17168 | |
| 17169 | function readFlowCollection(state, nodeIndent) { |
| 17170 | var readNext = true, |
| 17171 | _line, |
| 17172 | _tag = state.tag, |
| 17173 | _result, |
| 17174 | _anchor = state.anchor, |
| 17175 | following, |
| 17176 | terminator, |
| 17177 | isPair, |
| 17178 | isExplicitPair, |
| 17179 | isMapping, |
| 17180 | keyNode, |
| 17181 | keyTag, |
| 17182 | valueNode, |
| 17183 | ch; |
| 17184 | |
| 17185 | ch = state.input.charCodeAt(state.position); |
| 17186 | |
| 17187 | if (ch === 0x5B/* [ */) { |
| 17188 | terminator = 0x5D;/* ] */ |
| 17189 | isMapping = false; |
| 17190 | _result = []; |
| 17191 | } else if (ch === 0x7B/* { */) { |
| 17192 | terminator = 0x7D;/* } */ |
| 17193 | isMapping = true; |
| 17194 | _result = {}; |
| 17195 | } else { |
| 17196 | return false; |
| 17197 | } |
| 17198 | |
| 17199 | if (null !== state.anchor) { |
| 17200 | state.anchorMap[state.anchor] = _result; |
| 17201 | } |
| 17202 | |
| 17203 | ch = state.input.charCodeAt(++state.position); |
| 17204 | |
| 17205 | while (0 !== ch) { |
| 17206 | skipSeparationSpace(state, true, nodeIndent); |
| 17207 | |
| 17208 | ch = state.input.charCodeAt(state.position); |
| 17209 | |
| 17210 | if (ch === terminator) { |
| 17211 | state.position++; |
| 17212 | state.tag = _tag; |
| 17213 | state.anchor = _anchor; |
| 17214 | state.kind = isMapping ? 'mapping' : 'sequence'; |
| 17215 | state.result = _result; |
| 17216 | return true; |
| 17217 | } else if (!readNext) { |
| 17218 | throwError(state, 'missed comma between flow collection entries'); |
| 17219 | } |
| 17220 | |
| 17221 | keyTag = keyNode = valueNode = null; |
| 17222 | isPair = isExplicitPair = false; |
| 17223 | |
| 17224 | if (0x3F/* ? */ === ch) { |
| 17225 | following = state.input.charCodeAt(state.position + 1); |
| 17226 | |
| 17227 | if (is_WS_OR_EOL(following)) { |
| 17228 | isPair = isExplicitPair = true; |
| 17229 | state.position++; |
| 17230 | skipSeparationSpace(state, true, nodeIndent); |
| 17231 | } |
| 17232 | } |
| 17233 | |
| 17234 | _line = state.line; |
| 17235 | composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); |
| 17236 | keyTag = state.tag; |
| 17237 | keyNode = state.result; |
| 17238 | skipSeparationSpace(state, true, nodeIndent); |
| 17239 | |
| 17240 | ch = state.input.charCodeAt(state.position); |
| 17241 | |
| 17242 | if ((isExplicitPair || state.line === _line) && 0x3A/* : */ === ch) { |
| 17243 | isPair = true; |
| 17244 | ch = state.input.charCodeAt(++state.position); |
| 17245 | skipSeparationSpace(state, true, nodeIndent); |
| 17246 | composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); |
| 17247 | valueNode = state.result; |
| 17248 | } |
| 17249 | |
| 17250 | if (isMapping) { |
| 17251 | storeMappingPair(state, _result, keyTag, keyNode, valueNode); |
| 17252 | } else if (isPair) { |
| 17253 | _result.push(storeMappingPair(state, null, keyTag, keyNode, valueNode)); |
| 17254 | } else { |
| 17255 | _result.push(keyNode); |
| 17256 | } |
| 17257 | |
| 17258 | skipSeparationSpace(state, true, nodeIndent); |
| 17259 | |
| 17260 | ch = state.input.charCodeAt(state.position); |
| 17261 | |
| 17262 | if (0x2C/* , */ === ch) { |
| 17263 | readNext = true; |
| 17264 | ch = state.input.charCodeAt(++state.position); |
| 17265 | } else { |
| 17266 | readNext = false; |
| 17267 | } |
| 17268 | } |
| 17269 | |
| 17270 | throwError(state, 'unexpected end of the stream within a flow collection'); |
| 17271 | } |
| 17272 | |
| 17273 | function readBlockScalar(state, nodeIndent) { |
| 17274 | var captureStart, |
| 17275 | folding, |
| 17276 | chomping = CHOMPING_CLIP, |
| 17277 | detectedIndent = false, |
| 17278 | textIndent = nodeIndent, |
| 17279 | emptyLines = 0, |
| 17280 | atMoreIndented = false, |
| 17281 | tmp, |
| 17282 | ch; |
| 17283 | |
| 17284 | ch = state.input.charCodeAt(state.position); |
| 17285 | |
| 17286 | if (ch === 0x7C/* | */) { |
| 17287 | folding = false; |
| 17288 | } else if (ch === 0x3E/* > */) { |
| 17289 | folding = true; |
| 17290 | } else { |
| 17291 | return false; |
| 17292 | } |
| 17293 | |
| 17294 | state.kind = 'scalar'; |
| 17295 | state.result = ''; |
| 17296 | |
| 17297 | while (0 !== ch) { |
| 17298 | ch = state.input.charCodeAt(++state.position); |
| 17299 | |
| 17300 | if (0x2B/* + */ === ch || 0x2D/* - */ === ch) { |
| 17301 | if (CHOMPING_CLIP === chomping) { |
| 17302 | chomping = (0x2B/* + */ === ch) ? CHOMPING_KEEP : CHOMPING_STRIP; |
| 17303 | } else { |
| 17304 | throwError(state, 'repeat of a chomping mode identifier'); |
| 17305 | } |
| 17306 | |
| 17307 | } else if ((tmp = fromDecimalCode(ch)) >= 0) { |
| 17308 | if (tmp === 0) { |
| 17309 | throwError(state, 'bad explicit indentation width of a block scalar; it cannot be less than one'); |
| 17310 | } else if (!detectedIndent) { |
| 17311 | textIndent = nodeIndent + tmp - 1; |
| 17312 | detectedIndent = true; |
| 17313 | } else { |
| 17314 | throwError(state, 'repeat of an indentation width identifier'); |
| 17315 | } |
| 17316 | |
| 17317 | } else { |
| 17318 | break; |
| 17319 | } |
| 17320 | } |
| 17321 | |
| 17322 | if (is_WHITE_SPACE(ch)) { |
| 17323 | do { ch = state.input.charCodeAt(++state.position); } |
| 17324 | while (is_WHITE_SPACE(ch)); |
| 17325 | |
| 17326 | if (0x23/* # */ === ch) { |
| 17327 | do { ch = state.input.charCodeAt(++state.position); } |
| 17328 | while (!is_EOL(ch) && (0 !== ch)); |
| 17329 | } |
| 17330 | } |
| 17331 | |
| 17332 | while (0 !== ch) { |
| 17333 | readLineBreak(state); |
| 17334 | state.lineIndent = 0; |
| 17335 | |
| 17336 | ch = state.input.charCodeAt(state.position); |
| 17337 | |
| 17338 | while ((!detectedIndent || state.lineIndent < textIndent) && |
| 17339 | (0x20/* Space */ === ch)) { |
| 17340 | state.lineIndent++; |
| 17341 | ch = state.input.charCodeAt(++state.position); |
| 17342 | } |
| 17343 | |
| 17344 | if (!detectedIndent && state.lineIndent > textIndent) { |
| 17345 | textIndent = state.lineIndent; |
| 17346 | } |
| 17347 | |
| 17348 | if (is_EOL(ch)) { |
| 17349 | emptyLines++; |
| 17350 | continue; |
| 17351 | } |
| 17352 | |
| 17353 | // End of the scalar. |
| 17354 | if (state.lineIndent < textIndent) { |
| 17355 | |
| 17356 | // Perform the chomping. |
| 17357 | if (chomping === CHOMPING_KEEP) { |
| 17358 | state.result += common.repeat('\n', emptyLines); |
| 17359 | } else if (chomping === CHOMPING_CLIP) { |
| 17360 | if (detectedIndent) { // i.e. only if the scalar is not empty. |
| 17361 | state.result += '\n'; |
| 17362 | } |
| 17363 | } |
| 17364 | |
| 17365 | // Break this `while` cycle and go to the funciton's epilogue. |
| 17366 | break; |
| 17367 | } |
| 17368 | |
| 17369 | // Folded style: use fancy rules to handle line breaks. |
| 17370 | if (folding) { |
| 17371 | |
| 17372 | // Lines starting with white space characters (more-indented lines) are not folded. |
| 17373 | if (is_WHITE_SPACE(ch)) { |
| 17374 | atMoreIndented = true; |
| 17375 | state.result += common.repeat('\n', emptyLines + 1); |
| 17376 | |
| 17377 | // End of more-indented block. |
| 17378 | } else if (atMoreIndented) { |
| 17379 | atMoreIndented = false; |
| 17380 | state.result += common.repeat('\n', emptyLines + 1); |
| 17381 | |
| 17382 | // Just one line break - perceive as the same line. |
| 17383 | } else if (0 === emptyLines) { |
| 17384 | if (detectedIndent) { // i.e. only if we have already read some scalar content. |
| 17385 | state.result += ' '; |
| 17386 | } |
| 17387 | |
| 17388 | // Several line breaks - perceive as different lines. |
| 17389 | } else { |
| 17390 | state.result += common.repeat('\n', emptyLines); |
| 17391 | } |
| 17392 | |
| 17393 | // Literal style: just add exact number of line breaks between content lines. |
| 17394 | } else if (detectedIndent) { |
| 17395 | // If current line isn't the first one - count line break from the last content line. |
| 17396 | state.result += common.repeat('\n', emptyLines + 1); |
| 17397 | } else { |
| 17398 | // In case of the first content line - count only empty lines. |
| 17399 | } |
| 17400 | |
| 17401 | detectedIndent = true; |
| 17402 | emptyLines = 0; |
| 17403 | captureStart = state.position; |
| 17404 | |
| 17405 | while (!is_EOL(ch) && (0 !== ch)) { |
| 17406 | ch = state.input.charCodeAt(++state.position); |
| 17407 | } |
| 17408 | |
| 17409 | captureSegment(state, captureStart, state.position, false); |
| 17410 | } |
| 17411 | |
| 17412 | return true; |
| 17413 | } |
| 17414 | |
| 17415 | function readBlockSequence(state, nodeIndent) { |
| 17416 | var _line, |
| 17417 | _tag = state.tag, |
| 17418 | _anchor = state.anchor, |
| 17419 | _result = [], |
| 17420 | following, |
| 17421 | detected = false, |
| 17422 | ch; |
| 17423 | |
| 17424 | if (null !== state.anchor) { |
| 17425 | state.anchorMap[state.anchor] = _result; |
| 17426 | } |
| 17427 | |
| 17428 | ch = state.input.charCodeAt(state.position); |
| 17429 | |
| 17430 | while (0 !== ch) { |
| 17431 | |
| 17432 | if (0x2D/* - */ !== ch) { |
| 17433 | break; |
| 17434 | } |
| 17435 | |
| 17436 | following = state.input.charCodeAt(state.position + 1); |
| 17437 | |
| 17438 | if (!is_WS_OR_EOL(following)) { |
| 17439 | break; |
| 17440 | } |
| 17441 | |
| 17442 | detected = true; |
| 17443 | state.position++; |
| 17444 | |
| 17445 | if (skipSeparationSpace(state, true, -1)) { |
| 17446 | if (state.lineIndent <= nodeIndent) { |
| 17447 | _result.push(null); |
| 17448 | ch = state.input.charCodeAt(state.position); |
| 17449 | continue; |
| 17450 | } |
| 17451 | } |
| 17452 | |
| 17453 | _line = state.line; |
| 17454 | composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true); |
| 17455 | _result.push(state.result); |
| 17456 | skipSeparationSpace(state, true, -1); |
| 17457 | |
| 17458 | ch = state.input.charCodeAt(state.position); |
| 17459 | |
| 17460 | if ((state.line === _line || state.lineIndent > nodeIndent) && (0 !== ch)) { |
| 17461 | throwError(state, 'bad indentation of a sequence entry'); |
| 17462 | } else if (state.lineIndent < nodeIndent) { |
| 17463 | break; |
| 17464 | } |
| 17465 | } |
| 17466 | |
| 17467 | if (detected) { |
| 17468 | state.tag = _tag; |
| 17469 | state.anchor = _anchor; |
| 17470 | state.kind = 'sequence'; |
| 17471 | state.result = _result; |
| 17472 | return true; |
| 17473 | } |
| 17474 | return false; |
| 17475 | } |
| 17476 | |
| 17477 | function readBlockMapping(state, nodeIndent, flowIndent) { |
| 17478 | var following, |
| 17479 | allowCompact, |
| 17480 | _line, |
| 17481 | _tag = state.tag, |
| 17482 | _anchor = state.anchor, |
| 17483 | _result = {}, |
| 17484 | keyTag = null, |
| 17485 | keyNode = null, |
| 17486 | valueNode = null, |
| 17487 | atExplicitKey = false, |
| 17488 | detected = false, |
| 17489 | ch; |
| 17490 | |
| 17491 | if (null !== state.anchor) { |
| 17492 | state.anchorMap[state.anchor] = _result; |
| 17493 | } |
| 17494 | |
| 17495 | ch = state.input.charCodeAt(state.position); |
| 17496 | |
| 17497 | while (0 !== ch) { |
| 17498 | following = state.input.charCodeAt(state.position + 1); |
| 17499 | _line = state.line; // Save the current line. |
| 17500 | |
| 17501 | // |
| 17502 | // Explicit notation case. There are two separate blocks: |
| 17503 | // first for the key (denoted by "?") and second for the value (denoted by ":") |
| 17504 | // |
| 17505 | if ((0x3F/* ? */ === ch || 0x3A/* : */ === ch) && is_WS_OR_EOL(following)) { |
| 17506 | |
| 17507 | if (0x3F/* ? */ === ch) { |
| 17508 | if (atExplicitKey) { |
| 17509 | storeMappingPair(state, _result, keyTag, keyNode, null); |
| 17510 | keyTag = keyNode = valueNode = null; |
| 17511 | } |
| 17512 | |
| 17513 | detected = true; |
| 17514 | atExplicitKey = true; |
| 17515 | allowCompact = true; |
| 17516 | |
| 17517 | } else if (atExplicitKey) { |
| 17518 | // i.e. 0x3A/* : */ === character after the explicit key. |
| 17519 | atExplicitKey = false; |
| 17520 | allowCompact = true; |
| 17521 | |
| 17522 | } else { |
| 17523 | throwError(state, 'incomplete explicit mapping pair; a key node is missed'); |
| 17524 | } |
| 17525 | |
| 17526 | state.position += 1; |
| 17527 | ch = following; |
| 17528 | |
| 17529 | // |
| 17530 | // Implicit notation case. Flow-style node as the key first, then ":", and the value. |
| 17531 | // |
| 17532 | } else if (composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) { |
| 17533 | |
| 17534 | if (state.line === _line) { |
| 17535 | ch = state.input.charCodeAt(state.position); |
| 17536 | |
| 17537 | while (is_WHITE_SPACE(ch)) { |
| 17538 | ch = state.input.charCodeAt(++state.position); |
| 17539 | } |
| 17540 | |
| 17541 | if (0x3A/* : */ === ch) { |
| 17542 | ch = state.input.charCodeAt(++state.position); |
| 17543 | |
| 17544 | if (!is_WS_OR_EOL(ch)) { |
| 17545 | throwError(state, 'a whitespace character is expected after the key-value separator within a block mapping'); |
| 17546 | } |
| 17547 | |
| 17548 | if (atExplicitKey) { |
| 17549 | storeMappingPair(state, _result, keyTag, keyNode, null); |
| 17550 | keyTag = keyNode = valueNode = null; |
| 17551 | } |
| 17552 | |
| 17553 | detected = true; |
| 17554 | atExplicitKey = false; |
| 17555 | allowCompact = false; |
| 17556 | keyTag = state.tag; |
| 17557 | keyNode = state.result; |
| 17558 | |
| 17559 | } else if (detected) { |
| 17560 | throwError(state, 'can not read an implicit mapping pair; a colon is missed'); |
| 17561 | |
| 17562 | } else { |
| 17563 | state.tag = _tag; |
| 17564 | state.anchor = _anchor; |
| 17565 | return true; // Keep the result of `composeNode`. |
| 17566 | } |
| 17567 | |
| 17568 | } else if (detected) { |
| 17569 | throwError(state, 'can not read a block mapping entry; a multiline key may not be an implicit key'); |
| 17570 | |
| 17571 | } else { |
| 17572 | state.tag = _tag; |
| 17573 | state.anchor = _anchor; |
| 17574 | return true; // Keep the result of `composeNode`. |
| 17575 | } |
| 17576 | |
| 17577 | } else { |
| 17578 | break; // Reading is done. Go to the epilogue. |
| 17579 | } |
| 17580 | |
| 17581 | // |
| 17582 | // Common reading code for both explicit and implicit notations. |
| 17583 | // |
| 17584 | if (state.line === _line || state.lineIndent > nodeIndent) { |
| 17585 | if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) { |
| 17586 | if (atExplicitKey) { |
| 17587 | keyNode = state.result; |
| 17588 | } else { |
| 17589 | valueNode = state.result; |
| 17590 | } |
| 17591 | } |
| 17592 | |
| 17593 | if (!atExplicitKey) { |
| 17594 | storeMappingPair(state, _result, keyTag, keyNode, valueNode); |
| 17595 | keyTag = keyNode = valueNode = null; |
| 17596 | } |
| 17597 | |
| 17598 | skipSeparationSpace(state, true, -1); |
| 17599 | ch = state.input.charCodeAt(state.position); |
| 17600 | } |
| 17601 | |
| 17602 | if (state.lineIndent > nodeIndent && (0 !== ch)) { |
| 17603 | throwError(state, 'bad indentation of a mapping entry'); |
| 17604 | } else if (state.lineIndent < nodeIndent) { |
| 17605 | break; |
| 17606 | } |
| 17607 | } |
| 17608 | |
| 17609 | // |
| 17610 | // Epilogue. |
| 17611 | // |
| 17612 | |
| 17613 | // Special case: last mapping's node contains only the key in explicit notation. |
| 17614 | if (atExplicitKey) { |
| 17615 | storeMappingPair(state, _result, keyTag, keyNode, null); |
| 17616 | } |
| 17617 | |
| 17618 | // Expose the resulting mapping. |
| 17619 | if (detected) { |
| 17620 | state.tag = _tag; |
| 17621 | state.anchor = _anchor; |
| 17622 | state.kind = 'mapping'; |
| 17623 | state.result = _result; |
| 17624 | } |
| 17625 | |
| 17626 | return detected; |
| 17627 | } |
| 17628 | |
| 17629 | function readTagProperty(state) { |
| 17630 | var _position, |
| 17631 | isVerbatim = false, |
| 17632 | isNamed = false, |
| 17633 | tagHandle, |
| 17634 | tagName, |
| 17635 | ch; |
| 17636 | |
| 17637 | ch = state.input.charCodeAt(state.position); |
| 17638 | |
| 17639 | if (0x21/* ! */ !== ch) { |
| 17640 | return false; |
| 17641 | } |
| 17642 | |
| 17643 | if (null !== state.tag) { |
| 17644 | throwError(state, 'duplication of a tag property'); |
| 17645 | } |
| 17646 | |
| 17647 | ch = state.input.charCodeAt(++state.position); |
| 17648 | |
| 17649 | if (0x3C/* < */ === ch) { |
| 17650 | isVerbatim = true; |
| 17651 | ch = state.input.charCodeAt(++state.position); |
| 17652 | |
| 17653 | } else if (0x21/* ! */ === ch) { |
| 17654 | isNamed = true; |
| 17655 | tagHandle = '!!'; |
| 17656 | ch = state.input.charCodeAt(++state.position); |
| 17657 | |
| 17658 | } else { |
| 17659 | tagHandle = '!'; |
| 17660 | } |
| 17661 | |
| 17662 | _position = state.position; |
| 17663 | |
| 17664 | if (isVerbatim) { |
| 17665 | do { ch = state.input.charCodeAt(++state.position); } |
| 17666 | while (0 !== ch && 0x3E/* > */ !== ch); |
| 17667 | |
| 17668 | if (state.position < state.length) { |
| 17669 | tagName = state.input.slice(_position, state.position); |
| 17670 | ch = state.input.charCodeAt(++state.position); |
| 17671 | } else { |
| 17672 | throwError(state, 'unexpected end of the stream within a verbatim tag'); |
| 17673 | } |
| 17674 | } else { |
| 17675 | while (0 !== ch && !is_WS_OR_EOL(ch)) { |
| 17676 | |
| 17677 | if (0x21/* ! */ === ch) { |
| 17678 | if (!isNamed) { |
| 17679 | tagHandle = state.input.slice(_position - 1, state.position + 1); |
| 17680 | |
| 17681 | if (!PATTERN_TAG_HANDLE.test(tagHandle)) { |
| 17682 | throwError(state, 'named tag handle cannot contain such characters'); |
| 17683 | } |
| 17684 | |
| 17685 | isNamed = true; |
| 17686 | _position = state.position + 1; |
| 17687 | } else { |
| 17688 | throwError(state, 'tag suffix cannot contain exclamation marks'); |
| 17689 | } |
| 17690 | } |
| 17691 | |
| 17692 | ch = state.input.charCodeAt(++state.position); |
| 17693 | } |
| 17694 | |
| 17695 | tagName = state.input.slice(_position, state.position); |
| 17696 | |
| 17697 | if (PATTERN_FLOW_INDICATORS.test(tagName)) { |
| 17698 | throwError(state, 'tag suffix cannot contain flow indicator characters'); |
| 17699 | } |
| 17700 | } |
| 17701 | |
| 17702 | if (tagName && !PATTERN_TAG_URI.test(tagName)) { |
| 17703 | throwError(state, 'tag name cannot contain such characters: ' + tagName); |
| 17704 | } |
| 17705 | |
| 17706 | if (isVerbatim) { |
| 17707 | state.tag = tagName; |
| 17708 | |
| 17709 | } else if (_hasOwnProperty.call(state.tagMap, tagHandle)) { |
| 17710 | state.tag = state.tagMap[tagHandle] + tagName; |
| 17711 | |
| 17712 | } else if ('!' === tagHandle) { |
| 17713 | state.tag = '!' + tagName; |
| 17714 | |
| 17715 | } else if ('!!' === tagHandle) { |
| 17716 | state.tag = 'tag:yaml.org,2002:' + tagName; |
| 17717 | |
| 17718 | } else { |
| 17719 | throwError(state, 'undeclared tag handle "' + tagHandle + '"'); |
| 17720 | } |
| 17721 | |
| 17722 | return true; |
| 17723 | } |
| 17724 | |
| 17725 | function readAnchorProperty(state) { |
| 17726 | var _position, |
| 17727 | ch; |
| 17728 | |
| 17729 | ch = state.input.charCodeAt(state.position); |
| 17730 | |
| 17731 | if (0x26/* & */ !== ch) { |
| 17732 | return false; |
| 17733 | } |
| 17734 | |
| 17735 | if (null !== state.anchor) { |
| 17736 | throwError(state, 'duplication of an anchor property'); |
| 17737 | } |
| 17738 | |
| 17739 | ch = state.input.charCodeAt(++state.position); |
| 17740 | _position = state.position; |
| 17741 | |
| 17742 | while (0 !== ch && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) { |
| 17743 | ch = state.input.charCodeAt(++state.position); |
| 17744 | } |
| 17745 | |
| 17746 | if (state.position === _position) { |
| 17747 | throwError(state, 'name of an anchor node must contain at least one character'); |
| 17748 | } |
| 17749 | |
| 17750 | state.anchor = state.input.slice(_position, state.position); |
| 17751 | return true; |
| 17752 | } |
| 17753 | |
| 17754 | function readAlias(state) { |
| 17755 | var _position, alias, |
| 17756 | len = state.length, |
| 17757 | input = state.input, |
| 17758 | ch; |
| 17759 | |
| 17760 | ch = state.input.charCodeAt(state.position); |
| 17761 | |
| 17762 | if (0x2A/* * */ !== ch) { |
| 17763 | return false; |
| 17764 | } |
| 17765 | |
| 17766 | ch = state.input.charCodeAt(++state.position); |
| 17767 | _position = state.position; |
| 17768 | |
| 17769 | while (0 !== ch && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) { |
| 17770 | ch = state.input.charCodeAt(++state.position); |
| 17771 | } |
| 17772 | |
| 17773 | if (state.position === _position) { |
| 17774 | throwError(state, 'name of an alias node must contain at least one character'); |
| 17775 | } |
| 17776 | |
| 17777 | alias = state.input.slice(_position, state.position); |
| 17778 | |
| 17779 | if (!state.anchorMap.hasOwnProperty(alias)) { |
| 17780 | throwError(state, 'unidentified alias "' + alias + '"'); |
| 17781 | } |
| 17782 | |
| 17783 | state.result = state.anchorMap[alias]; |
| 17784 | skipSeparationSpace(state, true, -1); |
| 17785 | return true; |
| 17786 | } |
| 17787 | |
| 17788 | function composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) { |
| 17789 | var allowBlockStyles, |
| 17790 | allowBlockScalars, |
| 17791 | allowBlockCollections, |
| 17792 | indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this<parent |
| 17793 | atNewLine = false, |
| 17794 | hasContent = false, |
| 17795 | typeIndex, |
| 17796 | typeQuantity, |
| 17797 | type, |
| 17798 | flowIndent, |
| 17799 | blockIndent, |
| 17800 | _result; |
| 17801 | |
| 17802 | state.tag = null; |
| 17803 | state.anchor = null; |
| 17804 | state.kind = null; |
| 17805 | state.result = null; |
| 17806 | |
| 17807 | allowBlockStyles = allowBlockScalars = allowBlockCollections = |
| 17808 | CONTEXT_BLOCK_OUT === nodeContext || |
| 17809 | CONTEXT_BLOCK_IN === nodeContext; |
| 17810 | |
| 17811 | if (allowToSeek) { |
| 17812 | if (skipSeparationSpace(state, true, -1)) { |
| 17813 | atNewLine = true; |
| 17814 | |
| 17815 | if (state.lineIndent > parentIndent) { |
| 17816 | indentStatus = 1; |
| 17817 | } else if (state.lineIndent === parentIndent) { |
| 17818 | indentStatus = 0; |
| 17819 | } else if (state.lineIndent < parentIndent) { |
| 17820 | indentStatus = -1; |
| 17821 | } |
| 17822 | } |
| 17823 | } |
| 17824 | |
| 17825 | if (1 === indentStatus) { |
| 17826 | while (readTagProperty(state) || readAnchorProperty(state)) { |
| 17827 | if (skipSeparationSpace(state, true, -1)) { |
| 17828 | atNewLine = true; |
| 17829 | allowBlockCollections = allowBlockStyles; |
| 17830 | |
| 17831 | if (state.lineIndent > parentIndent) { |
| 17832 | indentStatus = 1; |
| 17833 | } else if (state.lineIndent === parentIndent) { |
| 17834 | indentStatus = 0; |
| 17835 | } else if (state.lineIndent < parentIndent) { |
| 17836 | indentStatus = -1; |
| 17837 | } |
| 17838 | } else { |
| 17839 | allowBlockCollections = false; |
| 17840 | } |
| 17841 | } |
| 17842 | } |
| 17843 | |
| 17844 | if (allowBlockCollections) { |
| 17845 | allowBlockCollections = atNewLine || allowCompact; |
| 17846 | } |
| 17847 | |
| 17848 | if (1 === indentStatus || CONTEXT_BLOCK_OUT === nodeContext) { |
| 17849 | if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) { |
| 17850 | flowIndent = parentIndent; |
| 17851 | } else { |
| 17852 | flowIndent = parentIndent + 1; |
| 17853 | } |
| 17854 | |
| 17855 | blockIndent = state.position - state.lineStart; |
| 17856 | |
| 17857 | if (1 === indentStatus) { |
| 17858 | if (allowBlockCollections && |
| 17859 | (readBlockSequence(state, blockIndent) || |
| 17860 | readBlockMapping(state, blockIndent, flowIndent)) || |
| 17861 | readFlowCollection(state, flowIndent)) { |
| 17862 | hasContent = true; |
| 17863 | } else { |
| 17864 | if ((allowBlockScalars && readBlockScalar(state, flowIndent)) || |
| 17865 | readSingleQuotedScalar(state, flowIndent) || |
| 17866 | readDoubleQuotedScalar(state, flowIndent)) { |
| 17867 | hasContent = true; |
| 17868 | |
| 17869 | } else if (readAlias(state)) { |
| 17870 | hasContent = true; |
| 17871 | |
| 17872 | if (null !== state.tag || null !== state.anchor) { |
| 17873 | throwError(state, 'alias node should not have any properties'); |
| 17874 | } |
| 17875 | |
| 17876 | } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) { |
| 17877 | hasContent = true; |
| 17878 | |
| 17879 | if (null === state.tag) { |
| 17880 | state.tag = '?'; |
| 17881 | } |
| 17882 | } |
| 17883 | |
| 17884 | if (null !== state.anchor) { |
| 17885 | state.anchorMap[state.anchor] = state.result; |
| 17886 | } |
| 17887 | } |
| 17888 | } else if (0 === indentStatus) { |
| 17889 | // Special case: block sequences are allowed to have same indentation level as the parent. |
| 17890 | // http://www.yaml.org/spec/1.2/spec.html#id2799784 |
| 17891 | hasContent = allowBlockCollections && readBlockSequence(state, blockIndent); |
| 17892 | } |
| 17893 | } |
| 17894 | |
| 17895 | if (null !== state.tag && '!' !== state.tag) { |
| 17896 | if ('?' === state.tag) { |
| 17897 | for (typeIndex = 0, typeQuantity = state.implicitTypes.length; |
| 17898 | typeIndex < typeQuantity; |
| 17899 | typeIndex += 1) { |
| 17900 | type = state.implicitTypes[typeIndex]; |
| 17901 | |
| 17902 | // Implicit resolving is not allowed for non-scalar types, and '?' |
| 17903 | // non-specific tag is only assigned to plain scalars. So, it isn't |
| 17904 | // needed to check for 'kind' conformity. |
| 17905 | |
| 17906 | if (type.resolve(state.result)) { // `state.result` updated in resolver if matched |
| 17907 | state.result = type.construct(state.result); |
| 17908 | state.tag = type.tag; |
| 17909 | if (null !== state.anchor) { |
| 17910 | state.anchorMap[state.anchor] = state.result; |
| 17911 | } |
| 17912 | break; |
| 17913 | } |
| 17914 | } |
| 17915 | } else if (_hasOwnProperty.call(state.typeMap, state.tag)) { |
| 17916 | type = state.typeMap[state.tag]; |
| 17917 | |
| 17918 | if (null !== state.result && type.kind !== state.kind) { |
| 17919 | throwError(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be "' + type.kind + '", not "' + state.kind + '"'); |
| 17920 | } |
| 17921 | |
| 17922 | if (!type.resolve(state.result)) { // `state.result` updated in resolver if matched |
| 17923 | throwError(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag'); |
| 17924 | } else { |
| 17925 | state.result = type.construct(state.result); |
| 17926 | if (null !== state.anchor) { |
| 17927 | state.anchorMap[state.anchor] = state.result; |
| 17928 | } |
| 17929 | } |
| 17930 | } else { |
| 17931 | throwWarning(state, 'unknown tag !<' + state.tag + '>'); |
| 17932 | } |
| 17933 | } |
| 17934 | |
| 17935 | return null !== state.tag || null !== state.anchor || hasContent; |
| 17936 | } |
| 17937 | |
| 17938 | function readDocument(state) { |
| 17939 | var documentStart = state.position, |
| 17940 | _position, |
| 17941 | directiveName, |
| 17942 | directiveArgs, |
| 17943 | hasDirectives = false, |
| 17944 | ch; |
| 17945 | |
| 17946 | state.version = null; |
| 17947 | state.checkLineBreaks = state.legacy; |
| 17948 | state.tagMap = {}; |
| 17949 | state.anchorMap = {}; |
| 17950 | |
| 17951 | while (0 !== (ch = state.input.charCodeAt(state.position))) { |
| 17952 | skipSeparationSpace(state, true, -1); |
| 17953 | |
| 17954 | ch = state.input.charCodeAt(state.position); |
| 17955 | |
| 17956 | if (state.lineIndent > 0 || 0x25/* % */ !== ch) { |
| 17957 | break; |
| 17958 | } |
| 17959 | |
| 17960 | hasDirectives = true; |
| 17961 | ch = state.input.charCodeAt(++state.position); |
| 17962 | _position = state.position; |
| 17963 | |
| 17964 | while (0 !== ch && !is_WS_OR_EOL(ch)) { |
| 17965 | ch = state.input.charCodeAt(++state.position); |
| 17966 | } |
| 17967 | |
| 17968 | directiveName = state.input.slice(_position, state.position); |
| 17969 | directiveArgs = []; |
| 17970 | |
| 17971 | if (directiveName.length < 1) { |
| 17972 | throwError(state, 'directive name must not be less than one character in length'); |
| 17973 | } |
| 17974 | |
| 17975 | while (0 !== ch) { |
| 17976 | while (is_WHITE_SPACE(ch)) { |
| 17977 | ch = state.input.charCodeAt(++state.position); |
| 17978 | } |
| 17979 | |
| 17980 | if (0x23/* # */ === ch) { |
| 17981 | do { ch = state.input.charCodeAt(++state.position); } |
| 17982 | while (0 !== ch && !is_EOL(ch)); |
| 17983 | break; |
| 17984 | } |
| 17985 | |
| 17986 | if (is_EOL(ch)) { |
| 17987 | break; |
| 17988 | } |
| 17989 | |
| 17990 | _position = state.position; |
| 17991 | |
| 17992 | while (0 !== ch && !is_WS_OR_EOL(ch)) { |
| 17993 | ch = state.input.charCodeAt(++state.position); |
| 17994 | } |
| 17995 | |
| 17996 | directiveArgs.push(state.input.slice(_position, state.position)); |
| 17997 | } |
| 17998 | |
| 17999 | if (0 !== ch) { |
| 18000 | readLineBreak(state); |
| 18001 | } |
| 18002 | |
| 18003 | if (_hasOwnProperty.call(directiveHandlers, directiveName)) { |
| 18004 | directiveHandlers[directiveName](state, directiveName, directiveArgs); |
| 18005 | } else { |
| 18006 | throwWarning(state, 'unknown document directive "' + directiveName + '"'); |
| 18007 | } |
| 18008 | } |
| 18009 | |
| 18010 | skipSeparationSpace(state, true, -1); |
| 18011 | |
| 18012 | if (0 === state.lineIndent && |
| 18013 | 0x2D/* - */ === state.input.charCodeAt(state.position) && |
| 18014 | 0x2D/* - */ === state.input.charCodeAt(state.position + 1) && |
| 18015 | 0x2D/* - */ === state.input.charCodeAt(state.position + 2)) { |
| 18016 | state.position += 3; |
| 18017 | skipSeparationSpace(state, true, -1); |
| 18018 | |
| 18019 | } else if (hasDirectives) { |
| 18020 | throwError(state, 'directives end mark is expected'); |
| 18021 | } |
| 18022 | |
| 18023 | composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true); |
| 18024 | skipSeparationSpace(state, true, -1); |
| 18025 | |
| 18026 | if (state.checkLineBreaks && |
| 18027 | PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) { |
| 18028 | throwWarning(state, 'non-ASCII line breaks are interpreted as content'); |
| 18029 | } |
| 18030 | |
| 18031 | state.documents.push(state.result); |
| 18032 | |
| 18033 | if (state.position === state.lineStart && testDocumentSeparator(state)) { |
| 18034 | |
| 18035 | if (0x2E/* . */ === state.input.charCodeAt(state.position)) { |
| 18036 | state.position += 3; |
| 18037 | skipSeparationSpace(state, true, -1); |
| 18038 | } |
| 18039 | return; |
| 18040 | } |
| 18041 | |
| 18042 | if (state.position < (state.length - 1)) { |
| 18043 | throwError(state, 'end of the stream or a document separator is expected'); |
| 18044 | } else { |
| 18045 | return; |
| 18046 | } |
| 18047 | } |
| 18048 | |
| 18049 | |
| 18050 | function loadDocuments(input, options) { |
| 18051 | input = String(input); |
| 18052 | options = options || {}; |
| 18053 | |
| 18054 | if (input.length !== 0) { |
| 18055 | |
| 18056 | // Add tailing `\n` if not exists |
| 18057 | if (0x0A/* LF */ !== input.charCodeAt(input.length - 1) && |
| 18058 | 0x0D/* CR */ !== input.charCodeAt(input.length - 1)) { |
| 18059 | input += '\n'; |
| 18060 | } |
| 18061 | |
| 18062 | // Strip BOM |
| 18063 | if (input.charCodeAt(0) === 0xFEFF) { |
| 18064 | input = input.slice(1); |
| 18065 | } |
| 18066 | } |
| 18067 | |
| 18068 | var state = new State(input, options); |
| 18069 | |
| 18070 | if (PATTERN_NON_PRINTABLE.test(state.input)) { |
| 18071 | throwError(state, 'the stream contains non-printable characters'); |
| 18072 | } |
| 18073 | |
| 18074 | // Use 0 as string terminator. That significantly simplifies bounds check. |
| 18075 | state.input += '\0'; |
| 18076 | |
| 18077 | while (0x20/* Space */ === state.input.charCodeAt(state.position)) { |
| 18078 | state.lineIndent += 1; |
| 18079 | state.position += 1; |
| 18080 | } |
| 18081 | |
| 18082 | while (state.position < (state.length - 1)) { |
| 18083 | readDocument(state); |
| 18084 | } |
| 18085 | |
| 18086 | return state.documents; |
| 18087 | } |
| 18088 | |
| 18089 | |
| 18090 | function loadAll(input, iterator, options) { |
| 18091 | var documents = loadDocuments(input, options), index, length; |
| 18092 | |
| 18093 | for (index = 0, length = documents.length; index < length; index += 1) { |
| 18094 | iterator(documents[index]); |
| 18095 | } |
| 18096 | } |
| 18097 | |
| 18098 | |
| 18099 | function load(input, options) { |
| 18100 | var documents = loadDocuments(input, options), index, length; |
| 18101 | |
| 18102 | if (0 === documents.length) { |
| 18103 | /*eslint-disable no-undefined*/ |
| 18104 | return undefined; |
| 18105 | } else if (1 === documents.length) { |
| 18106 | return documents[0]; |
| 18107 | } |
| 18108 | throw new YAMLException('expected a single document in the stream, but found more'); |
| 18109 | } |
| 18110 | |
| 18111 | |
| 18112 | function safeLoadAll(input, output, options) { |
| 18113 | loadAll(input, output, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options)); |
| 18114 | } |
| 18115 | |
| 18116 | |
| 18117 | function safeLoad(input, options) { |
| 18118 | return load(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options)); |
| 18119 | } |
| 18120 | |
| 18121 | |
| 18122 | module.exports.loadAll = loadAll; |
| 18123 | module.exports.load = load; |
| 18124 | module.exports.safeLoadAll = safeLoadAll; |
| 18125 | module.exports.safeLoad = safeLoad; |
| 18126 | |
| 18127 | },{"./common":22,"./exception":24,"./mark":26,"./schema/default_full":29,"./schema/default_safe":30}],26:[function(require,module,exports){ |
| 18128 | 'use strict'; |
| 18129 | |
| 18130 | |
| 18131 | var common = require('./common'); |
| 18132 | |
| 18133 | |
| 18134 | function Mark(name, buffer, position, line, column) { |
| 18135 | this.name = name; |
| 18136 | this.buffer = buffer; |
| 18137 | this.position = position; |
| 18138 | this.line = line; |
| 18139 | this.column = column; |
| 18140 | } |
| 18141 | |
| 18142 | |
| 18143 | Mark.prototype.getSnippet = function getSnippet(indent, maxLength) { |
| 18144 | var head, start, tail, end, snippet; |
| 18145 | |
| 18146 | if (!this.buffer) { |
| 18147 | return null; |
| 18148 | } |
| 18149 | |
| 18150 | indent = indent || 4; |
| 18151 | maxLength = maxLength || 75; |
| 18152 | |
| 18153 | head = ''; |
| 18154 | start = this.position; |
| 18155 | |
| 18156 | while (start > 0 && -1 === '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(start - 1))) { |
| 18157 | start -= 1; |
| 18158 | if (this.position - start > (maxLength / 2 - 1)) { |
| 18159 | head = ' ... '; |
| 18160 | start += 5; |
| 18161 | break; |
| 18162 | } |
| 18163 | } |
| 18164 | |
| 18165 | tail = ''; |
| 18166 | end = this.position; |
| 18167 | |
| 18168 | while (end < this.buffer.length && -1 === '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(end))) { |
| 18169 | end += 1; |
| 18170 | if (end - this.position > (maxLength / 2 - 1)) { |
| 18171 | tail = ' ... '; |
| 18172 | end -= 5; |
| 18173 | break; |
| 18174 | } |
| 18175 | } |
| 18176 | |
| 18177 | snippet = this.buffer.slice(start, end); |
| 18178 | |
| 18179 | return common.repeat(' ', indent) + head + snippet + tail + '\n' + |
| 18180 | common.repeat(' ', indent + this.position - start + head.length) + '^'; |
| 18181 | }; |
| 18182 | |
| 18183 | |
| 18184 | Mark.prototype.toString = function toString(compact) { |
| 18185 | var snippet, where = ''; |
| 18186 | |
| 18187 | if (this.name) { |
| 18188 | where += 'in "' + this.name + '" '; |
| 18189 | } |
| 18190 | |
| 18191 | where += 'at line ' + (this.line + 1) + ', column ' + (this.column + 1); |
| 18192 | |
| 18193 | if (!compact) { |
| 18194 | snippet = this.getSnippet(); |
| 18195 | |
| 18196 | if (snippet) { |
| 18197 | where += ':\n' + snippet; |
| 18198 | } |
| 18199 | } |
| 18200 | |
| 18201 | return where; |
| 18202 | }; |
| 18203 | |
| 18204 | |
| 18205 | module.exports = Mark; |
| 18206 | |
| 18207 | },{"./common":22}],27:[function(require,module,exports){ |
| 18208 | 'use strict'; |
| 18209 | |
| 18210 | /*eslint-disable max-len*/ |
| 18211 | |
| 18212 | var common = require('./common'); |
| 18213 | var YAMLException = require('./exception'); |
| 18214 | var Type = require('./type'); |
| 18215 | |
| 18216 | |
| 18217 | function compileList(schema, name, result) { |
| 18218 | var exclude = []; |
| 18219 | |
| 18220 | schema.include.forEach(function (includedSchema) { |
| 18221 | result = compileList(includedSchema, name, result); |
| 18222 | }); |
| 18223 | |
| 18224 | schema[name].forEach(function (currentType) { |
| 18225 | result.forEach(function (previousType, previousIndex) { |
| 18226 | if (previousType.tag === currentType.tag) { |
| 18227 | exclude.push(previousIndex); |
| 18228 | } |
| 18229 | }); |
| 18230 | |
| 18231 | result.push(currentType); |
| 18232 | }); |
| 18233 | |
| 18234 | return result.filter(function (type, index) { |
| 18235 | return -1 === exclude.indexOf(index); |
| 18236 | }); |
| 18237 | } |
| 18238 | |
| 18239 | |
| 18240 | function compileMap(/* lists... */) { |
| 18241 | var result = {}, index, length; |
| 18242 | |
| 18243 | function collectType(type) { |
| 18244 | result[type.tag] = type; |
| 18245 | } |
| 18246 | |
| 18247 | for (index = 0, length = arguments.length; index < length; index += 1) { |
| 18248 | arguments[index].forEach(collectType); |
| 18249 | } |
| 18250 | |
| 18251 | return result; |
| 18252 | } |
| 18253 | |
| 18254 | |
| 18255 | function Schema(definition) { |
| 18256 | this.include = definition.include || []; |
| 18257 | this.implicit = definition.implicit || []; |
| 18258 | this.explicit = definition.explicit || []; |
| 18259 | |
| 18260 | this.implicit.forEach(function (type) { |
| 18261 | if (type.loadKind && 'scalar' !== type.loadKind) { |
| 18262 | throw new YAMLException('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.'); |
| 18263 | } |
| 18264 | }); |
| 18265 | |
| 18266 | this.compiledImplicit = compileList(this, 'implicit', []); |
| 18267 | this.compiledExplicit = compileList(this, 'explicit', []); |
| 18268 | this.compiledTypeMap = compileMap(this.compiledImplicit, this.compiledExplicit); |
| 18269 | } |
| 18270 | |
| 18271 | |
| 18272 | Schema.DEFAULT = null; |
| 18273 | |
| 18274 | |
| 18275 | Schema.create = function createSchema() { |
| 18276 | var schemas, types; |
| 18277 | |
| 18278 | switch (arguments.length) { |
| 18279 | case 1: |
| 18280 | schemas = Schema.DEFAULT; |
| 18281 | types = arguments[0]; |
| 18282 | break; |
| 18283 | |
| 18284 | case 2: |
| 18285 | schemas = arguments[0]; |
| 18286 | types = arguments[1]; |
| 18287 | break; |
| 18288 | |
| 18289 | default: |
| 18290 | throw new YAMLException('Wrong number of arguments for Schema.create function'); |
| 18291 | } |
| 18292 | |
| 18293 | schemas = common.toArray(schemas); |
| 18294 | types = common.toArray(types); |
| 18295 | |
| 18296 | if (!schemas.every(function (schema) { return schema instanceof Schema; })) { |
| 18297 | throw new YAMLException('Specified list of super schemas (or a single Schema object) contains a non-Schema object.'); |
| 18298 | } |
| 18299 | |
| 18300 | if (!types.every(function (type) { return type instanceof Type; })) { |
| 18301 | throw new YAMLException('Specified list of YAML types (or a single Type object) contains a non-Type object.'); |
| 18302 | } |
| 18303 | |
| 18304 | return new Schema({ |
| 18305 | include: schemas, |
| 18306 | explicit: types |
| 18307 | }); |
| 18308 | }; |
| 18309 | |
| 18310 | |
| 18311 | module.exports = Schema; |
| 18312 | |
| 18313 | },{"./common":22,"./exception":24,"./type":33}],28:[function(require,module,exports){ |
| 18314 | // Standard YAML's Core schema. |
| 18315 | // http://www.yaml.org/spec/1.2/spec.html#id2804923 |
| 18316 | // |
| 18317 | // NOTE: JS-YAML does not support schema-specific tag resolution restrictions. |
| 18318 | // So, Core schema has no distinctions from JSON schema is JS-YAML. |
| 18319 | |
| 18320 | |
| 18321 | 'use strict'; |
| 18322 | |
| 18323 | |
| 18324 | var Schema = require('../schema'); |
| 18325 | |
| 18326 | |
| 18327 | module.exports = new Schema({ |
| 18328 | include: [ |
| 18329 | require('./json') |
| 18330 | ] |
| 18331 | }); |
| 18332 | |
| 18333 | },{"../schema":27,"./json":32}],29:[function(require,module,exports){ |
| 18334 | // JS-YAML's default schema for `load` function. |
| 18335 | // It is not described in the YAML specification. |
| 18336 | // |
| 18337 | // This schema is based on JS-YAML's default safe schema and includes |
| 18338 | // JavaScript-specific types: !!js/undefined, !!js/regexp and !!js/function. |
| 18339 | // |
| 18340 | // Also this schema is used as default base schema at `Schema.create` function. |
| 18341 | |
| 18342 | |
| 18343 | 'use strict'; |
| 18344 | |
| 18345 | |
| 18346 | var Schema = require('../schema'); |
| 18347 | |
| 18348 | |
| 18349 | module.exports = Schema.DEFAULT = new Schema({ |
| 18350 | include: [ |
| 18351 | require('./default_safe') |
| 18352 | ], |
| 18353 | explicit: [ |
| 18354 | require('../type/js/undefined'), |
| 18355 | require('../type/js/regexp'), |
| 18356 | require('../type/js/function') |
| 18357 | ] |
| 18358 | }); |
| 18359 | |
| 18360 | },{"../schema":27,"../type/js/function":38,"../type/js/regexp":39,"../type/js/undefined":40,"./default_safe":30}],30:[function(require,module,exports){ |
| 18361 | // JS-YAML's default schema for `safeLoad` function. |
| 18362 | // It is not described in the YAML specification. |
| 18363 | // |
| 18364 | // This schema is based on standard YAML's Core schema and includes most of |
| 18365 | // extra types described at YAML tag repository. (http://yaml.org/type/) |
| 18366 | |
| 18367 | |
| 18368 | 'use strict'; |
| 18369 | |
| 18370 | |
| 18371 | var Schema = require('../schema'); |
| 18372 | |
| 18373 | |
| 18374 | module.exports = new Schema({ |
| 18375 | include: [ |
| 18376 | require('./core') |
| 18377 | ], |
| 18378 | implicit: [ |
| 18379 | require('../type/timestamp'), |
| 18380 | require('../type/merge') |
| 18381 | ], |
| 18382 | explicit: [ |
| 18383 | require('../type/binary'), |
| 18384 | require('../type/omap'), |
| 18385 | require('../type/pairs'), |
| 18386 | require('../type/set') |
| 18387 | ] |
| 18388 | }); |
| 18389 | |
| 18390 | },{"../schema":27,"../type/binary":34,"../type/merge":42,"../type/omap":44,"../type/pairs":45,"../type/set":47,"../type/timestamp":49,"./core":28}],31:[function(require,module,exports){ |
| 18391 | // Standard YAML's Failsafe schema. |
| 18392 | // http://www.yaml.org/spec/1.2/spec.html#id2802346 |
| 18393 | |
| 18394 | |
| 18395 | 'use strict'; |
| 18396 | |
| 18397 | |
| 18398 | var Schema = require('../schema'); |
| 18399 | |
| 18400 | |
| 18401 | module.exports = new Schema({ |
| 18402 | explicit: [ |
| 18403 | require('../type/str'), |
| 18404 | require('../type/seq'), |
| 18405 | require('../type/map') |
| 18406 | ] |
| 18407 | }); |
| 18408 | |
| 18409 | },{"../schema":27,"../type/map":41,"../type/seq":46,"../type/str":48}],32:[function(require,module,exports){ |
| 18410 | // Standard YAML's JSON schema. |
| 18411 | // http://www.yaml.org/spec/1.2/spec.html#id2803231 |
| 18412 | // |
| 18413 | // NOTE: JS-YAML does not support schema-specific tag resolution restrictions. |
| 18414 | // So, this schema is not such strict as defined in the YAML specification. |
| 18415 | // It allows numbers in binary notaion, use `Null` and `NULL` as `null`, etc. |
| 18416 | |
| 18417 | |
| 18418 | 'use strict'; |
| 18419 | |
| 18420 | |
| 18421 | var Schema = require('../schema'); |
| 18422 | |
| 18423 | |
| 18424 | module.exports = new Schema({ |
| 18425 | include: [ |
| 18426 | require('./failsafe') |
| 18427 | ], |
| 18428 | implicit: [ |
| 18429 | require('../type/null'), |
| 18430 | require('../type/bool'), |
| 18431 | require('../type/int'), |
| 18432 | require('../type/float') |
| 18433 | ] |
| 18434 | }); |
| 18435 | |
| 18436 | },{"../schema":27,"../type/bool":35,"../type/float":36,"../type/int":37,"../type/null":43,"./failsafe":31}],33:[function(require,module,exports){ |
| 18437 | 'use strict'; |
| 18438 | |
| 18439 | var YAMLException = require('./exception'); |
| 18440 | |
| 18441 | var TYPE_CONSTRUCTOR_OPTIONS = [ |
| 18442 | 'kind', |
| 18443 | 'resolve', |
| 18444 | 'construct', |
| 18445 | 'instanceOf', |
| 18446 | 'predicate', |
| 18447 | 'represent', |
| 18448 | 'defaultStyle', |
| 18449 | 'styleAliases' |
| 18450 | ]; |
| 18451 | |
| 18452 | var YAML_NODE_KINDS = [ |
| 18453 | 'scalar', |
| 18454 | 'sequence', |
| 18455 | 'mapping' |
| 18456 | ]; |
| 18457 | |
| 18458 | function compileStyleAliases(map) { |
| 18459 | var result = {}; |
| 18460 | |
| 18461 | if (null !== map) { |
| 18462 | Object.keys(map).forEach(function (style) { |
| 18463 | map[style].forEach(function (alias) { |
| 18464 | result[String(alias)] = style; |
| 18465 | }); |
| 18466 | }); |
| 18467 | } |
| 18468 | |
| 18469 | return result; |
| 18470 | } |
| 18471 | |
| 18472 | function Type(tag, options) { |
| 18473 | options = options || {}; |
| 18474 | |
| 18475 | Object.keys(options).forEach(function (name) { |
| 18476 | if (-1 === TYPE_CONSTRUCTOR_OPTIONS.indexOf(name)) { |
| 18477 | throw new YAMLException('Unknown option "' + name + '" is met in definition of "' + tag + '" YAML type.'); |
| 18478 | } |
| 18479 | }); |
| 18480 | |
| 18481 | // TODO: Add tag format check. |
| 18482 | this.tag = tag; |
| 18483 | this.kind = options['kind'] || null; |
| 18484 | this.resolve = options['resolve'] || function () { return true; }; |
| 18485 | this.construct = options['construct'] || function (data) { return data; }; |
| 18486 | this.instanceOf = options['instanceOf'] || null; |
| 18487 | this.predicate = options['predicate'] || null; |
| 18488 | this.represent = options['represent'] || null; |
| 18489 | this.defaultStyle = options['defaultStyle'] || null; |
| 18490 | this.styleAliases = compileStyleAliases(options['styleAliases'] || null); |
| 18491 | |
| 18492 | if (-1 === YAML_NODE_KINDS.indexOf(this.kind)) { |
| 18493 | throw new YAMLException('Unknown kind "' + this.kind + '" is specified for "' + tag + '" YAML type.'); |
| 18494 | } |
| 18495 | } |
| 18496 | |
| 18497 | module.exports = Type; |
| 18498 | |
| 18499 | },{"./exception":24}],34:[function(require,module,exports){ |
| 18500 | 'use strict'; |
| 18501 | |
| 18502 | /*eslint-disable no-bitwise*/ |
| 18503 | |
| 18504 | // A trick for browserified version. |
| 18505 | // Since we make browserifier to ignore `buffer` module, NodeBuffer will be undefined |
| 18506 | var NodeBuffer = require('buffer').Buffer; |
| 18507 | var Type = require('../type'); |
| 18508 | |
| 18509 | |
| 18510 | // [ 64, 65, 66 ] -> [ padding, CR, LF ] |
| 18511 | var BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r'; |
| 18512 | |
| 18513 | |
| 18514 | function resolveYamlBinary(data) { |
| 18515 | if (null === data) { |
| 18516 | return false; |
| 18517 | } |
| 18518 | |
| 18519 | var code, idx, bitlen = 0, len = 0, max = data.length, map = BASE64_MAP; |
| 18520 | |
| 18521 | // Convert one by one. |
| 18522 | for (idx = 0; idx < max; idx++) { |
| 18523 | code = map.indexOf(data.charAt(idx)); |
| 18524 | |
| 18525 | // Skip CR/LF |
| 18526 | if (code > 64) { continue; } |
| 18527 | |
| 18528 | // Fail on illegal characters |
| 18529 | if (code < 0) { return false; } |
| 18530 | |
| 18531 | bitlen += 6; |
| 18532 | } |
| 18533 | |
| 18534 | // If there are any bits left, source was corrupted |
| 18535 | return (bitlen % 8) === 0; |
| 18536 | } |
| 18537 | |
| 18538 | function constructYamlBinary(data) { |
| 18539 | var code, idx, tailbits, |
| 18540 | input = data.replace(/[\r\n=]/g, ''), // remove CR/LF & padding to simplify scan |
| 18541 | max = input.length, |
| 18542 | map = BASE64_MAP, |
| 18543 | bits = 0, |
| 18544 | result = []; |
| 18545 | |
| 18546 | // Collect by 6*4 bits (3 bytes) |
| 18547 | |
| 18548 | for (idx = 0; idx < max; idx++) { |
| 18549 | if ((idx % 4 === 0) && idx) { |
| 18550 | result.push((bits >> 16) & 0xFF); |
| 18551 | result.push((bits >> 8) & 0xFF); |
| 18552 | result.push(bits & 0xFF); |
| 18553 | } |
| 18554 | |
| 18555 | bits = (bits << 6) | map.indexOf(input.charAt(idx)); |
| 18556 | } |
| 18557 | |
| 18558 | // Dump tail |
| 18559 | |
| 18560 | tailbits = (max % 4) * 6; |
| 18561 | |
| 18562 | if (tailbits === 0) { |
| 18563 | result.push((bits >> 16) & 0xFF); |
| 18564 | result.push((bits >> 8) & 0xFF); |
| 18565 | result.push(bits & 0xFF); |
| 18566 | } else if (tailbits === 18) { |
| 18567 | result.push((bits >> 10) & 0xFF); |
| 18568 | result.push((bits >> 2) & 0xFF); |
| 18569 | } else if (tailbits === 12) { |
| 18570 | result.push((bits >> 4) & 0xFF); |
| 18571 | } |
| 18572 | |
| 18573 | // Wrap into Buffer for NodeJS and leave Array for browser |
| 18574 | if (NodeBuffer) { |
| 18575 | return new NodeBuffer(result); |
| 18576 | } |
| 18577 | |
| 18578 | return result; |
| 18579 | } |
| 18580 | |
| 18581 | function representYamlBinary(object /*, style*/) { |
| 18582 | var result = '', bits = 0, idx, tail, |
| 18583 | max = object.length, |
| 18584 | map = BASE64_MAP; |
| 18585 | |
| 18586 | // Convert every three bytes to 4 ASCII characters. |
| 18587 | |
| 18588 | for (idx = 0; idx < max; idx++) { |
| 18589 | if ((idx % 3 === 0) && idx) { |
| 18590 | result += map[(bits >> 18) & 0x3F]; |
| 18591 | result += map[(bits >> 12) & 0x3F]; |
| 18592 | result += map[(bits >> 6) & 0x3F]; |
| 18593 | result += map[bits & 0x3F]; |
| 18594 | } |
| 18595 | |
| 18596 | bits = (bits << 8) + object[idx]; |
| 18597 | } |
| 18598 | |
| 18599 | // Dump tail |
| 18600 | |
| 18601 | tail = max % 3; |
| 18602 | |
| 18603 | if (tail === 0) { |
| 18604 | result += map[(bits >> 18) & 0x3F]; |
| 18605 | result += map[(bits >> 12) & 0x3F]; |
| 18606 | result += map[(bits >> 6) & 0x3F]; |
| 18607 | result += map[bits & 0x3F]; |
| 18608 | } else if (tail === 2) { |
| 18609 | result += map[(bits >> 10) & 0x3F]; |
| 18610 | result += map[(bits >> 4) & 0x3F]; |
| 18611 | result += map[(bits << 2) & 0x3F]; |
| 18612 | result += map[64]; |
| 18613 | } else if (tail === 1) { |
| 18614 | result += map[(bits >> 2) & 0x3F]; |
| 18615 | result += map[(bits << 4) & 0x3F]; |
| 18616 | result += map[64]; |
| 18617 | result += map[64]; |
| 18618 | } |
| 18619 | |
| 18620 | return result; |
| 18621 | } |
| 18622 | |
| 18623 | function isBinary(object) { |
| 18624 | return NodeBuffer && NodeBuffer.isBuffer(object); |
| 18625 | } |
| 18626 | |
| 18627 | module.exports = new Type('tag:yaml.org,2002:binary', { |
| 18628 | kind: 'scalar', |
| 18629 | resolve: resolveYamlBinary, |
| 18630 | construct: constructYamlBinary, |
| 18631 | predicate: isBinary, |
| 18632 | represent: representYamlBinary |
| 18633 | }); |
| 18634 | |
| 18635 | },{"../type":33,"buffer":11}],35:[function(require,module,exports){ |
| 18636 | 'use strict'; |
| 18637 | |
| 18638 | var Type = require('../type'); |
| 18639 | |
| 18640 | function resolveYamlBoolean(data) { |
| 18641 | if (null === data) { |
| 18642 | return false; |
| 18643 | } |
| 18644 | |
| 18645 | var max = data.length; |
| 18646 | |
| 18647 | return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) || |
| 18648 | (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE')); |
| 18649 | } |
| 18650 | |
| 18651 | function constructYamlBoolean(data) { |
| 18652 | return data === 'true' || |
| 18653 | data === 'True' || |
| 18654 | data === 'TRUE'; |
| 18655 | } |
| 18656 | |
| 18657 | function isBoolean(object) { |
| 18658 | return '[object Boolean]' === Object.prototype.toString.call(object); |
| 18659 | } |
| 18660 | |
| 18661 | module.exports = new Type('tag:yaml.org,2002:bool', { |
| 18662 | kind: 'scalar', |
| 18663 | resolve: resolveYamlBoolean, |
| 18664 | construct: constructYamlBoolean, |
| 18665 | predicate: isBoolean, |
| 18666 | represent: { |
| 18667 | lowercase: function (object) { return object ? 'true' : 'false'; }, |
| 18668 | uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; }, |
| 18669 | camelcase: function (object) { return object ? 'True' : 'False'; } |
| 18670 | }, |
| 18671 | defaultStyle: 'lowercase' |
| 18672 | }); |
| 18673 | |
| 18674 | },{"../type":33}],36:[function(require,module,exports){ |
| 18675 | 'use strict'; |
| 18676 | |
| 18677 | var common = require('../common'); |
| 18678 | var Type = require('../type'); |
| 18679 | |
| 18680 | var YAML_FLOAT_PATTERN = new RegExp( |
| 18681 | '^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?' + |
| 18682 | '|\\.[0-9_]+(?:[eE][-+][0-9]+)?' + |
| 18683 | '|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*' + |
| 18684 | '|[-+]?\\.(?:inf|Inf|INF)' + |
| 18685 | '|\\.(?:nan|NaN|NAN))$'); |
| 18686 | |
| 18687 | function resolveYamlFloat(data) { |
| 18688 | if (null === data) { |
| 18689 | return false; |
| 18690 | } |
| 18691 | |
| 18692 | var value, sign, base, digits; |
| 18693 | |
| 18694 | if (!YAML_FLOAT_PATTERN.test(data)) { |
| 18695 | return false; |
| 18696 | } |
| 18697 | return true; |
| 18698 | } |
| 18699 | |
| 18700 | function constructYamlFloat(data) { |
| 18701 | var value, sign, base, digits; |
| 18702 | |
| 18703 | value = data.replace(/_/g, '').toLowerCase(); |
| 18704 | sign = '-' === value[0] ? -1 : 1; |
| 18705 | digits = []; |
| 18706 | |
| 18707 | if (0 <= '+-'.indexOf(value[0])) { |
| 18708 | value = value.slice(1); |
| 18709 | } |
| 18710 | |
| 18711 | if ('.inf' === value) { |
| 18712 | return (1 === sign) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY; |
| 18713 | |
| 18714 | } else if ('.nan' === value) { |
| 18715 | return NaN; |
| 18716 | |
| 18717 | } else if (0 <= value.indexOf(':')) { |
| 18718 | value.split(':').forEach(function (v) { |
| 18719 | digits.unshift(parseFloat(v, 10)); |
| 18720 | }); |
| 18721 | |
| 18722 | value = 0.0; |
| 18723 | base = 1; |
| 18724 | |
| 18725 | digits.forEach(function (d) { |
| 18726 | value += d * base; |
| 18727 | base *= 60; |
| 18728 | }); |
| 18729 | |
| 18730 | return sign * value; |
| 18731 | |
| 18732 | } |
| 18733 | return sign * parseFloat(value, 10); |
| 18734 | } |
| 18735 | |
| 18736 | function representYamlFloat(object, style) { |
| 18737 | if (isNaN(object)) { |
| 18738 | switch (style) { |
| 18739 | case 'lowercase': |
| 18740 | return '.nan'; |
| 18741 | case 'uppercase': |
| 18742 | return '.NAN'; |
| 18743 | case 'camelcase': |
| 18744 | return '.NaN'; |
| 18745 | } |
| 18746 | } else if (Number.POSITIVE_INFINITY === object) { |
| 18747 | switch (style) { |
| 18748 | case 'lowercase': |
| 18749 | return '.inf'; |
| 18750 | case 'uppercase': |
| 18751 | return '.INF'; |
| 18752 | case 'camelcase': |
| 18753 | return '.Inf'; |
| 18754 | } |
| 18755 | } else if (Number.NEGATIVE_INFINITY === object) { |
| 18756 | switch (style) { |
| 18757 | case 'lowercase': |
| 18758 | return '-.inf'; |
| 18759 | case 'uppercase': |
| 18760 | return '-.INF'; |
| 18761 | case 'camelcase': |
| 18762 | return '-.Inf'; |
| 18763 | } |
| 18764 | } else if (common.isNegativeZero(object)) { |
| 18765 | return '-0.0'; |
| 18766 | } |
| 18767 | return object.toString(10); |
| 18768 | } |
| 18769 | |
| 18770 | function isFloat(object) { |
| 18771 | return ('[object Number]' === Object.prototype.toString.call(object)) && |
| 18772 | (0 !== object % 1 || common.isNegativeZero(object)); |
| 18773 | } |
| 18774 | |
| 18775 | module.exports = new Type('tag:yaml.org,2002:float', { |
| 18776 | kind: 'scalar', |
| 18777 | resolve: resolveYamlFloat, |
| 18778 | construct: constructYamlFloat, |
| 18779 | predicate: isFloat, |
| 18780 | represent: representYamlFloat, |
| 18781 | defaultStyle: 'lowercase' |
| 18782 | }); |
| 18783 | |
| 18784 | },{"../common":22,"../type":33}],37:[function(require,module,exports){ |
| 18785 | 'use strict'; |
| 18786 | |
| 18787 | var common = require('../common'); |
| 18788 | var Type = require('../type'); |
| 18789 | |
| 18790 | function isHexCode(c) { |
| 18791 | return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) || |
| 18792 | ((0x41/* A */ <= c) && (c <= 0x46/* F */)) || |
| 18793 | ((0x61/* a */ <= c) && (c <= 0x66/* f */)); |
| 18794 | } |
| 18795 | |
| 18796 | function isOctCode(c) { |
| 18797 | return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */)); |
| 18798 | } |
| 18799 | |
| 18800 | function isDecCode(c) { |
| 18801 | return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)); |
| 18802 | } |
| 18803 | |
| 18804 | function resolveYamlInteger(data) { |
| 18805 | if (null === data) { |
| 18806 | return false; |
| 18807 | } |
| 18808 | |
| 18809 | var max = data.length, |
| 18810 | index = 0, |
| 18811 | hasDigits = false, |
| 18812 | ch; |
| 18813 | |
| 18814 | if (!max) { return false; } |
| 18815 | |
| 18816 | ch = data[index]; |
| 18817 | |
| 18818 | // sign |
| 18819 | if (ch === '-' || ch === '+') { |
| 18820 | ch = data[++index]; |
| 18821 | } |
| 18822 | |
| 18823 | if (ch === '0') { |
| 18824 | // 0 |
| 18825 | if (index + 1 === max) { return true; } |
| 18826 | ch = data[++index]; |
| 18827 | |
| 18828 | // base 2, base 8, base 16 |
| 18829 | |
| 18830 | if (ch === 'b') { |
| 18831 | // base 2 |
| 18832 | index++; |
| 18833 | |
| 18834 | for (; index < max; index++) { |
| 18835 | ch = data[index]; |
| 18836 | if (ch === '_') { continue; } |
| 18837 | if (ch !== '0' && ch !== '1') { |
| 18838 | return false; |
| 18839 | } |
| 18840 | hasDigits = true; |
| 18841 | } |
| 18842 | return hasDigits; |
| 18843 | } |
| 18844 | |
| 18845 | |
| 18846 | if (ch === 'x') { |
| 18847 | // base 16 |
| 18848 | index++; |
| 18849 | |
| 18850 | for (; index < max; index++) { |
| 18851 | ch = data[index]; |
| 18852 | if (ch === '_') { continue; } |
| 18853 | if (!isHexCode(data.charCodeAt(index))) { |
| 18854 | return false; |
| 18855 | } |
| 18856 | hasDigits = true; |
| 18857 | } |
| 18858 | return hasDigits; |
| 18859 | } |
| 18860 | |
| 18861 | // base 8 |
| 18862 | for (; index < max; index++) { |
| 18863 | ch = data[index]; |
| 18864 | if (ch === '_') { continue; } |
| 18865 | if (!isOctCode(data.charCodeAt(index))) { |
| 18866 | return false; |
| 18867 | } |
| 18868 | hasDigits = true; |
| 18869 | } |
| 18870 | return hasDigits; |
| 18871 | } |
| 18872 | |
| 18873 | // base 10 (except 0) or base 60 |
| 18874 | |
| 18875 | for (; index < max; index++) { |
| 18876 | ch = data[index]; |
| 18877 | if (ch === '_') { continue; } |
| 18878 | if (ch === ':') { break; } |
| 18879 | if (!isDecCode(data.charCodeAt(index))) { |
| 18880 | return false; |
| 18881 | } |
| 18882 | hasDigits = true; |
| 18883 | } |
| 18884 | |
| 18885 | if (!hasDigits) { return false; } |
| 18886 | |
| 18887 | // if !base60 - done; |
| 18888 | if (ch !== ':') { return true; } |
| 18889 | |
| 18890 | // base60 almost not used, no needs to optimize |
| 18891 | return /^(:[0-5]?[0-9])+$/.test(data.slice(index)); |
| 18892 | } |
| 18893 | |
| 18894 | function constructYamlInteger(data) { |
| 18895 | var value = data, sign = 1, ch, base, digits = []; |
| 18896 | |
| 18897 | if (value.indexOf('_') !== -1) { |
| 18898 | value = value.replace(/_/g, ''); |
| 18899 | } |
| 18900 | |
| 18901 | ch = value[0]; |
| 18902 | |
| 18903 | if (ch === '-' || ch === '+') { |
| 18904 | if (ch === '-') { sign = -1; } |
| 18905 | value = value.slice(1); |
| 18906 | ch = value[0]; |
| 18907 | } |
| 18908 | |
| 18909 | if ('0' === value) { |
| 18910 | return 0; |
| 18911 | } |
| 18912 | |
| 18913 | if (ch === '0') { |
| 18914 | if (value[1] === 'b') { |
| 18915 | return sign * parseInt(value.slice(2), 2); |
| 18916 | } |
| 18917 | if (value[1] === 'x') { |
| 18918 | return sign * parseInt(value, 16); |
| 18919 | } |
| 18920 | return sign * parseInt(value, 8); |
| 18921 | |
| 18922 | } |
| 18923 | |
| 18924 | if (value.indexOf(':') !== -1) { |
| 18925 | value.split(':').forEach(function (v) { |
| 18926 | digits.unshift(parseInt(v, 10)); |
| 18927 | }); |
| 18928 | |
| 18929 | value = 0; |
| 18930 | base = 1; |
| 18931 | |
| 18932 | digits.forEach(function (d) { |
| 18933 | value += (d * base); |
| 18934 | base *= 60; |
| 18935 | }); |
| 18936 | |
| 18937 | return sign * value; |
| 18938 | |
| 18939 | } |
| 18940 | |
| 18941 | return sign * parseInt(value, 10); |
| 18942 | } |
| 18943 | |
| 18944 | function isInteger(object) { |
| 18945 | return ('[object Number]' === Object.prototype.toString.call(object)) && |
| 18946 | (0 === object % 1 && !common.isNegativeZero(object)); |
| 18947 | } |
| 18948 | |
| 18949 | module.exports = new Type('tag:yaml.org,2002:int', { |
| 18950 | kind: 'scalar', |
| 18951 | resolve: resolveYamlInteger, |
| 18952 | construct: constructYamlInteger, |
| 18953 | predicate: isInteger, |
| 18954 | represent: { |
| 18955 | binary: function (object) { return '0b' + object.toString(2); }, |
| 18956 | octal: function (object) { return '0' + object.toString(8); }, |
| 18957 | decimal: function (object) { return object.toString(10); }, |
| 18958 | hexadecimal: function (object) { return '0x' + object.toString(16).toUpperCase(); } |
| 18959 | }, |
| 18960 | defaultStyle: 'decimal', |
| 18961 | styleAliases: { |
| 18962 | binary: [ 2, 'bin' ], |
| 18963 | octal: [ 8, 'oct' ], |
| 18964 | decimal: [ 10, 'dec' ], |
| 18965 | hexadecimal: [ 16, 'hex' ] |
| 18966 | } |
| 18967 | }); |
| 18968 | |
| 18969 | },{"../common":22,"../type":33}],38:[function(require,module,exports){ |
| 18970 | 'use strict'; |
| 18971 | |
| 18972 | var esprima; |
| 18973 | |
| 18974 | // Browserified version does not have esprima |
| 18975 | // |
| 18976 | // 1. For node.js just require module as deps |
| 18977 | // 2. For browser try to require mudule via external AMD system. |
| 18978 | // If not found - try to fallback to window.esprima. If not |
| 18979 | // found too - then fail to parse. |
| 18980 | // |
| 18981 | try { |
| 18982 | esprima = require('esprima'); |
| 18983 | } catch (_) { |
| 18984 | /*global window */ |
| 18985 | if (typeof window !== 'undefined') { esprima = window.esprima; } |
| 18986 | } |
| 18987 | |
| 18988 | var Type = require('../../type'); |
| 18989 | |
| 18990 | function resolveJavascriptFunction(data) { |
| 18991 | if (null === data) { |
| 18992 | return false; |
| 18993 | } |
| 18994 | |
| 18995 | try { |
| 18996 | var source = '(' + data + ')', |
| 18997 | ast = esprima.parse(source, { range: true }), |
| 18998 | params = [], |
| 18999 | body; |
| 19000 | |
| 19001 | if ('Program' !== ast.type || |
| 19002 | 1 !== ast.body.length || |
| 19003 | 'ExpressionStatement' !== ast.body[0].type || |
| 19004 | 'FunctionExpression' !== ast.body[0].expression.type) { |
| 19005 | return false; |
| 19006 | } |
| 19007 | |
| 19008 | return true; |
| 19009 | } catch (err) { |
| 19010 | return false; |
| 19011 | } |
| 19012 | } |
| 19013 | |
| 19014 | function constructJavascriptFunction(data) { |
| 19015 | /*jslint evil:true*/ |
| 19016 | |
| 19017 | var source = '(' + data + ')', |
| 19018 | ast = esprima.parse(source, { range: true }), |
| 19019 | params = [], |
| 19020 | body; |
| 19021 | |
| 19022 | if ('Program' !== ast.type || |
| 19023 | 1 !== ast.body.length || |
| 19024 | 'ExpressionStatement' !== ast.body[0].type || |
| 19025 | 'FunctionExpression' !== ast.body[0].expression.type) { |
| 19026 | throw new Error('Failed to resolve function'); |
| 19027 | } |
| 19028 | |
| 19029 | ast.body[0].expression.params.forEach(function (param) { |
| 19030 | params.push(param.name); |
| 19031 | }); |
| 19032 | |
| 19033 | body = ast.body[0].expression.body.range; |
| 19034 | |
| 19035 | // Esprima's ranges include the first '{' and the last '}' characters on |
| 19036 | // function expressions. So cut them out. |
| 19037 | /*eslint-disable no-new-func*/ |
| 19038 | return new Function(params, source.slice(body[0] + 1, body[1] - 1)); |
| 19039 | } |
| 19040 | |
| 19041 | function representJavascriptFunction(object /*, style*/) { |
| 19042 | return object.toString(); |
| 19043 | } |
| 19044 | |
| 19045 | function isFunction(object) { |
| 19046 | return '[object Function]' === Object.prototype.toString.call(object); |
| 19047 | } |
| 19048 | |
| 19049 | module.exports = new Type('tag:yaml.org,2002:js/function', { |
| 19050 | kind: 'scalar', |
| 19051 | resolve: resolveJavascriptFunction, |
| 19052 | construct: constructJavascriptFunction, |
| 19053 | predicate: isFunction, |
| 19054 | represent: representJavascriptFunction |
| 19055 | }); |
| 19056 | |
| 19057 | },{"../../type":33,"esprima":50}],39:[function(require,module,exports){ |
| 19058 | 'use strict'; |
| 19059 | |
| 19060 | var Type = require('../../type'); |
| 19061 | |
| 19062 | function resolveJavascriptRegExp(data) { |
| 19063 | if (null === data) { |
| 19064 | return false; |
| 19065 | } |
| 19066 | |
| 19067 | if (0 === data.length) { |
| 19068 | return false; |
| 19069 | } |
| 19070 | |
| 19071 | var regexp = data, |
| 19072 | tail = /\/([gim]*)$/.exec(data), |
| 19073 | modifiers = ''; |
| 19074 | |
| 19075 | // if regexp starts with '/' it can have modifiers and must be properly closed |
| 19076 | // `/foo/gim` - modifiers tail can be maximum 3 chars |
| 19077 | if ('/' === regexp[0]) { |
| 19078 | if (tail) { |
| 19079 | modifiers = tail[1]; |
| 19080 | } |
| 19081 | |
| 19082 | if (modifiers.length > 3) { return false; } |
| 19083 | // if expression starts with /, is should be properly terminated |
| 19084 | if (regexp[regexp.length - modifiers.length - 1] !== '/') { return false; } |
| 19085 | |
| 19086 | regexp = regexp.slice(1, regexp.length - modifiers.length - 1); |
| 19087 | } |
| 19088 | |
| 19089 | try { |
| 19090 | var dummy = new RegExp(regexp, modifiers); |
| 19091 | return true; |
| 19092 | } catch (error) { |
| 19093 | return false; |
| 19094 | } |
| 19095 | } |
| 19096 | |
| 19097 | function constructJavascriptRegExp(data) { |
| 19098 | var regexp = data, |
| 19099 | tail = /\/([gim]*)$/.exec(data), |
| 19100 | modifiers = ''; |
| 19101 | |
| 19102 | // `/foo/gim` - tail can be maximum 4 chars |
| 19103 | if ('/' === regexp[0]) { |
| 19104 | if (tail) { |
| 19105 | modifiers = tail[1]; |
| 19106 | } |
| 19107 | regexp = regexp.slice(1, regexp.length - modifiers.length - 1); |
| 19108 | } |
| 19109 | |
| 19110 | return new RegExp(regexp, modifiers); |
| 19111 | } |
| 19112 | |
| 19113 | function representJavascriptRegExp(object /*, style*/) { |
| 19114 | var result = '/' + object.source + '/'; |
| 19115 | |
| 19116 | if (object.global) { |
| 19117 | result += 'g'; |
| 19118 | } |
| 19119 | |
| 19120 | if (object.multiline) { |
| 19121 | result += 'm'; |
| 19122 | } |
| 19123 | |
| 19124 | if (object.ignoreCase) { |
| 19125 | result += 'i'; |
| 19126 | } |
| 19127 | |
| 19128 | return result; |
| 19129 | } |
| 19130 | |
| 19131 | function isRegExp(object) { |
| 19132 | return '[object RegExp]' === Object.prototype.toString.call(object); |
| 19133 | } |
| 19134 | |
| 19135 | module.exports = new Type('tag:yaml.org,2002:js/regexp', { |
| 19136 | kind: 'scalar', |
| 19137 | resolve: resolveJavascriptRegExp, |
| 19138 | construct: constructJavascriptRegExp, |
| 19139 | predicate: isRegExp, |
| 19140 | represent: representJavascriptRegExp |
| 19141 | }); |
| 19142 | |
| 19143 | },{"../../type":33}],40:[function(require,module,exports){ |
| 19144 | 'use strict'; |
| 19145 | |
| 19146 | var Type = require('../../type'); |
| 19147 | |
| 19148 | function resolveJavascriptUndefined() { |
| 19149 | return true; |
| 19150 | } |
| 19151 | |
| 19152 | function constructJavascriptUndefined() { |
| 19153 | /*eslint-disable no-undefined*/ |
| 19154 | return undefined; |
| 19155 | } |
| 19156 | |
| 19157 | function representJavascriptUndefined() { |
| 19158 | return ''; |
| 19159 | } |
| 19160 | |
| 19161 | function isUndefined(object) { |
| 19162 | return 'undefined' === typeof object; |
| 19163 | } |
| 19164 | |
| 19165 | module.exports = new Type('tag:yaml.org,2002:js/undefined', { |
| 19166 | kind: 'scalar', |
| 19167 | resolve: resolveJavascriptUndefined, |
| 19168 | construct: constructJavascriptUndefined, |
| 19169 | predicate: isUndefined, |
| 19170 | represent: representJavascriptUndefined |
| 19171 | }); |
| 19172 | |
| 19173 | },{"../../type":33}],41:[function(require,module,exports){ |
| 19174 | 'use strict'; |
| 19175 | |
| 19176 | var Type = require('../type'); |
| 19177 | |
| 19178 | module.exports = new Type('tag:yaml.org,2002:map', { |
| 19179 | kind: 'mapping', |
| 19180 | construct: function (data) { return null !== data ? data : {}; } |
| 19181 | }); |
| 19182 | |
| 19183 | },{"../type":33}],42:[function(require,module,exports){ |
| 19184 | 'use strict'; |
| 19185 | |
| 19186 | var Type = require('../type'); |
| 19187 | |
| 19188 | function resolveYamlMerge(data) { |
| 19189 | return '<<' === data || null === data; |
| 19190 | } |
| 19191 | |
| 19192 | module.exports = new Type('tag:yaml.org,2002:merge', { |
| 19193 | kind: 'scalar', |
| 19194 | resolve: resolveYamlMerge |
| 19195 | }); |
| 19196 | |
| 19197 | },{"../type":33}],43:[function(require,module,exports){ |
| 19198 | 'use strict'; |
| 19199 | |
| 19200 | var Type = require('../type'); |
| 19201 | |
| 19202 | function resolveYamlNull(data) { |
| 19203 | if (null === data) { |
| 19204 | return true; |
| 19205 | } |
| 19206 | |
| 19207 | var max = data.length; |
| 19208 | |
| 19209 | return (max === 1 && data === '~') || |
| 19210 | (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL')); |
| 19211 | } |
| 19212 | |
| 19213 | function constructYamlNull() { |
| 19214 | return null; |
| 19215 | } |
| 19216 | |
| 19217 | function isNull(object) { |
| 19218 | return null === object; |
| 19219 | } |
| 19220 | |
| 19221 | module.exports = new Type('tag:yaml.org,2002:null', { |
| 19222 | kind: 'scalar', |
| 19223 | resolve: resolveYamlNull, |
| 19224 | construct: constructYamlNull, |
| 19225 | predicate: isNull, |
| 19226 | represent: { |
| 19227 | canonical: function () { return '~'; }, |
| 19228 | lowercase: function () { return 'null'; }, |
| 19229 | uppercase: function () { return 'NULL'; }, |
| 19230 | camelcase: function () { return 'Null'; } |
| 19231 | }, |
| 19232 | defaultStyle: 'lowercase' |
| 19233 | }); |
| 19234 | |
| 19235 | },{"../type":33}],44:[function(require,module,exports){ |
| 19236 | 'use strict'; |
| 19237 | |
| 19238 | var Type = require('../type'); |
| 19239 | |
| 19240 | var _hasOwnProperty = Object.prototype.hasOwnProperty; |
| 19241 | var _toString = Object.prototype.toString; |
| 19242 | |
| 19243 | function resolveYamlOmap(data) { |
| 19244 | if (null === data) { |
| 19245 | return true; |
| 19246 | } |
| 19247 | |
| 19248 | var objectKeys = [], index, length, pair, pairKey, pairHasKey, |
| 19249 | object = data; |
| 19250 | |
| 19251 | for (index = 0, length = object.length; index < length; index += 1) { |
| 19252 | pair = object[index]; |
| 19253 | pairHasKey = false; |
| 19254 | |
| 19255 | if ('[object Object]' !== _toString.call(pair)) { |
| 19256 | return false; |
| 19257 | } |
| 19258 | |
| 19259 | for (pairKey in pair) { |
| 19260 | if (_hasOwnProperty.call(pair, pairKey)) { |
| 19261 | if (!pairHasKey) { |
| 19262 | pairHasKey = true; |
| 19263 | } else { |
| 19264 | return false; |
| 19265 | } |
| 19266 | } |
| 19267 | } |
| 19268 | |
| 19269 | if (!pairHasKey) { |
| 19270 | return false; |
| 19271 | } |
| 19272 | |
| 19273 | if (-1 === objectKeys.indexOf(pairKey)) { |
| 19274 | objectKeys.push(pairKey); |
| 19275 | } else { |
| 19276 | return false; |
| 19277 | } |
| 19278 | } |
| 19279 | |
| 19280 | return true; |
| 19281 | } |
| 19282 | |
| 19283 | function constructYamlOmap(data) { |
| 19284 | return null !== data ? data : []; |
| 19285 | } |
| 19286 | |
| 19287 | module.exports = new Type('tag:yaml.org,2002:omap', { |
| 19288 | kind: 'sequence', |
| 19289 | resolve: resolveYamlOmap, |
| 19290 | construct: constructYamlOmap |
| 19291 | }); |
| 19292 | |
| 19293 | },{"../type":33}],45:[function(require,module,exports){ |
| 19294 | 'use strict'; |
| 19295 | |
| 19296 | var Type = require('../type'); |
| 19297 | |
| 19298 | var _toString = Object.prototype.toString; |
| 19299 | |
| 19300 | function resolveYamlPairs(data) { |
| 19301 | if (null === data) { |
| 19302 | return true; |
| 19303 | } |
| 19304 | |
| 19305 | var index, length, pair, keys, result, |
| 19306 | object = data; |
| 19307 | |
| 19308 | result = new Array(object.length); |
| 19309 | |
| 19310 | for (index = 0, length = object.length; index < length; index += 1) { |
| 19311 | pair = object[index]; |
| 19312 | |
| 19313 | if ('[object Object]' !== _toString.call(pair)) { |
| 19314 | return false; |
| 19315 | } |
| 19316 | |
| 19317 | keys = Object.keys(pair); |
| 19318 | |
| 19319 | if (1 !== keys.length) { |
| 19320 | return false; |
| 19321 | } |
| 19322 | |
| 19323 | result[index] = [ keys[0], pair[keys[0]] ]; |
| 19324 | } |
| 19325 | |
| 19326 | return true; |
| 19327 | } |
| 19328 | |
| 19329 | function constructYamlPairs(data) { |
| 19330 | if (null === data) { |
| 19331 | return []; |
| 19332 | } |
| 19333 | |
| 19334 | var index, length, pair, keys, result, |
| 19335 | object = data; |
| 19336 | |
| 19337 | result = new Array(object.length); |
| 19338 | |
| 19339 | for (index = 0, length = object.length; index < length; index += 1) { |
| 19340 | pair = object[index]; |
| 19341 | |
| 19342 | keys = Object.keys(pair); |
| 19343 | |
| 19344 | result[index] = [ keys[0], pair[keys[0]] ]; |
| 19345 | } |
| 19346 | |
| 19347 | return result; |
| 19348 | } |
| 19349 | |
| 19350 | module.exports = new Type('tag:yaml.org,2002:pairs', { |
| 19351 | kind: 'sequence', |
| 19352 | resolve: resolveYamlPairs, |
| 19353 | construct: constructYamlPairs |
| 19354 | }); |
| 19355 | |
| 19356 | },{"../type":33}],46:[function(require,module,exports){ |
| 19357 | 'use strict'; |
| 19358 | |
| 19359 | var Type = require('../type'); |
| 19360 | |
| 19361 | module.exports = new Type('tag:yaml.org,2002:seq', { |
| 19362 | kind: 'sequence', |
| 19363 | construct: function (data) { return null !== data ? data : []; } |
| 19364 | }); |
| 19365 | |
| 19366 | },{"../type":33}],47:[function(require,module,exports){ |
| 19367 | 'use strict'; |
| 19368 | |
| 19369 | var Type = require('../type'); |
| 19370 | |
| 19371 | var _hasOwnProperty = Object.prototype.hasOwnProperty; |
| 19372 | |
| 19373 | function resolveYamlSet(data) { |
| 19374 | if (null === data) { |
| 19375 | return true; |
| 19376 | } |
| 19377 | |
| 19378 | var key, object = data; |
| 19379 | |
| 19380 | for (key in object) { |
| 19381 | if (_hasOwnProperty.call(object, key)) { |
| 19382 | if (null !== object[key]) { |
| 19383 | return false; |
| 19384 | } |
| 19385 | } |
| 19386 | } |
| 19387 | |
| 19388 | return true; |
| 19389 | } |
| 19390 | |
| 19391 | function constructYamlSet(data) { |
| 19392 | return null !== data ? data : {}; |
| 19393 | } |
| 19394 | |
| 19395 | module.exports = new Type('tag:yaml.org,2002:set', { |
| 19396 | kind: 'mapping', |
| 19397 | resolve: resolveYamlSet, |
| 19398 | construct: constructYamlSet |
| 19399 | }); |
| 19400 | |
| 19401 | },{"../type":33}],48:[function(require,module,exports){ |
| 19402 | 'use strict'; |
| 19403 | |
| 19404 | var Type = require('../type'); |
| 19405 | |
| 19406 | module.exports = new Type('tag:yaml.org,2002:str', { |
| 19407 | kind: 'scalar', |
| 19408 | construct: function (data) { return null !== data ? data : ''; } |
| 19409 | }); |
| 19410 | |
| 19411 | },{"../type":33}],49:[function(require,module,exports){ |
| 19412 | 'use strict'; |
| 19413 | |
| 19414 | var Type = require('../type'); |
| 19415 | |
| 19416 | var YAML_TIMESTAMP_REGEXP = new RegExp( |
| 19417 | '^([0-9][0-9][0-9][0-9])' + // [1] year |
| 19418 | '-([0-9][0-9]?)' + // [2] month |
| 19419 | '-([0-9][0-9]?)' + // [3] day |
| 19420 | '(?:(?:[Tt]|[ \\t]+)' + // ... |
| 19421 | '([0-9][0-9]?)' + // [4] hour |
| 19422 | ':([0-9][0-9])' + // [5] minute |
| 19423 | ':([0-9][0-9])' + // [6] second |
| 19424 | '(?:\\.([0-9]*))?' + // [7] fraction |
| 19425 | '(?:[ \\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour |
| 19426 | '(?::([0-9][0-9]))?))?)?$'); // [11] tz_minute |
| 19427 | |
| 19428 | function resolveYamlTimestamp(data) { |
| 19429 | if (null === data) { |
| 19430 | return false; |
| 19431 | } |
| 19432 | |
| 19433 | var match, year, month, day, hour, minute, second, fraction = 0, |
| 19434 | delta = null, tz_hour, tz_minute, date; |
| 19435 | |
| 19436 | match = YAML_TIMESTAMP_REGEXP.exec(data); |
| 19437 | |
| 19438 | if (null === match) { |
| 19439 | return false; |
| 19440 | } |
| 19441 | |
| 19442 | return true; |
| 19443 | } |
| 19444 | |
| 19445 | function constructYamlTimestamp(data) { |
| 19446 | var match, year, month, day, hour, minute, second, fraction = 0, |
| 19447 | delta = null, tz_hour, tz_minute, date; |
| 19448 | |
| 19449 | match = YAML_TIMESTAMP_REGEXP.exec(data); |
| 19450 | |
| 19451 | if (null === match) { |
| 19452 | throw new Error('Date resolve error'); |
| 19453 | } |
| 19454 | |
| 19455 | // match: [1] year [2] month [3] day |
| 19456 | |
| 19457 | year = +(match[1]); |
| 19458 | month = +(match[2]) - 1; // JS month starts with 0 |
| 19459 | day = +(match[3]); |
| 19460 | |
| 19461 | if (!match[4]) { // no hour |
| 19462 | return new Date(Date.UTC(year, month, day)); |
| 19463 | } |
| 19464 | |
| 19465 | // match: [4] hour [5] minute [6] second [7] fraction |
| 19466 | |
| 19467 | hour = +(match[4]); |
| 19468 | minute = +(match[5]); |
| 19469 | second = +(match[6]); |
| 19470 | |
| 19471 | if (match[7]) { |
| 19472 | fraction = match[7].slice(0, 3); |
| 19473 | while (fraction.length < 3) { // milli-seconds |
| 19474 | fraction += '0'; |
| 19475 | } |
| 19476 | fraction = +fraction; |
| 19477 | } |
| 19478 | |
| 19479 | // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute |
| 19480 | |
| 19481 | if (match[9]) { |
| 19482 | tz_hour = +(match[10]); |
| 19483 | tz_minute = +(match[11] || 0); |
| 19484 | delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds |
| 19485 | if ('-' === match[9]) { |
| 19486 | delta = -delta; |
| 19487 | } |
| 19488 | } |
| 19489 | |
| 19490 | date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction)); |
| 19491 | |
| 19492 | if (delta) { |
| 19493 | date.setTime(date.getTime() - delta); |
| 19494 | } |
| 19495 | |
| 19496 | return date; |
| 19497 | } |
| 19498 | |
| 19499 | function representYamlTimestamp(object /*, style*/) { |
| 19500 | return object.toISOString(); |
| 19501 | } |
| 19502 | |
| 19503 | module.exports = new Type('tag:yaml.org,2002:timestamp', { |
| 19504 | kind: 'scalar', |
| 19505 | resolve: resolveYamlTimestamp, |
| 19506 | construct: constructYamlTimestamp, |
| 19507 | instanceOf: Date, |
| 19508 | represent: representYamlTimestamp |
| 19509 | }); |
| 19510 | |
| 19511 | },{"../type":33}],50:[function(require,module,exports){ |
| 19512 | /* |
| 19513 | Copyright (C) 2013 Ariya Hidayat <ariya.hidayat@gmail.com> |
| 19514 | Copyright (C) 2013 Thaddee Tyl <thaddee.tyl@gmail.com> |
| 19515 | Copyright (C) 2013 Mathias Bynens <mathias@qiwi.be> |
| 19516 | Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com> |
| 19517 | Copyright (C) 2012 Mathias Bynens <mathias@qiwi.be> |
| 19518 | Copyright (C) 2012 Joost-Wim Boekesteijn <joost-wim@boekesteijn.nl> |
| 19519 | Copyright (C) 2012 Kris Kowal <kris.kowal@cixar.com> |
| 19520 | Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com> |
| 19521 | Copyright (C) 2012 Arpad Borsos <arpad.borsos@googlemail.com> |
| 19522 | Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com> |
| 19523 | |
| 19524 | Redistribution and use in source and binary forms, with or without |
| 19525 | modification, are permitted provided that the following conditions are met: |
| 19526 | |
| 19527 | * Redistributions of source code must retain the above copyright |
| 19528 | notice, this list of conditions and the following disclaimer. |
| 19529 | * Redistributions in binary form must reproduce the above copyright |
| 19530 | notice, this list of conditions and the following disclaimer in the |
| 19531 | documentation and/or other materials provided with the distribution. |
| 19532 | |
| 19533 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| 19534 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 19535 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 19536 | ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY |
| 19537 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 19538 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 19539 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| 19540 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 19541 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| 19542 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 19543 | */ |
| 19544 | |
| 19545 | (function (root, factory) { |
| 19546 | 'use strict'; |
| 19547 | |
| 19548 | // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js, |
| 19549 | // Rhino, and plain browser loading. |
| 19550 | |
| 19551 | /* istanbul ignore next */ |
| 19552 | if (typeof define === 'function' && define.amd) { |
| 19553 | define(['exports'], factory); |
| 19554 | } else if (typeof exports !== 'undefined') { |
| 19555 | factory(exports); |
| 19556 | } else { |
| 19557 | factory((root.esprima = {})); |
| 19558 | } |
| 19559 | }(this, function (exports) { |
| 19560 | 'use strict'; |
| 19561 | |
| 19562 | var Token, |
| 19563 | TokenName, |
| 19564 | FnExprTokens, |
| 19565 | Syntax, |
| 19566 | PlaceHolders, |
| 19567 | Messages, |
| 19568 | Regex, |
| 19569 | source, |
| 19570 | strict, |
| 19571 | sourceType, |
| 19572 | index, |
| 19573 | lineNumber, |
| 19574 | lineStart, |
| 19575 | hasLineTerminator, |
| 19576 | lastIndex, |
| 19577 | lastLineNumber, |
| 19578 | lastLineStart, |
| 19579 | startIndex, |
| 19580 | startLineNumber, |
| 19581 | startLineStart, |
| 19582 | scanning, |
| 19583 | length, |
| 19584 | lookahead, |
| 19585 | state, |
| 19586 | extra, |
| 19587 | isBindingElement, |
| 19588 | isAssignmentTarget, |
| 19589 | firstCoverInitializedNameError; |
| 19590 | |
| 19591 | Token = { |
| 19592 | BooleanLiteral: 1, |
| 19593 | EOF: 2, |
| 19594 | Identifier: 3, |
| 19595 | Keyword: 4, |
| 19596 | NullLiteral: 5, |
| 19597 | NumericLiteral: 6, |
| 19598 | Punctuator: 7, |
| 19599 | StringLiteral: 8, |
| 19600 | RegularExpression: 9, |
| 19601 | Template: 10 |
| 19602 | }; |
| 19603 | |
| 19604 | TokenName = {}; |
| 19605 | TokenName[Token.BooleanLiteral] = 'Boolean'; |
| 19606 | TokenName[Token.EOF] = '<end>'; |
| 19607 | TokenName[Token.Identifier] = 'Identifier'; |
| 19608 | TokenName[Token.Keyword] = 'Keyword'; |
| 19609 | TokenName[Token.NullLiteral] = 'Null'; |
| 19610 | TokenName[Token.NumericLiteral] = 'Numeric'; |
| 19611 | TokenName[Token.Punctuator] = 'Punctuator'; |
| 19612 | TokenName[Token.StringLiteral] = 'String'; |
| 19613 | TokenName[Token.RegularExpression] = 'RegularExpression'; |
| 19614 | TokenName[Token.Template] = 'Template'; |
| 19615 | |
| 19616 | // A function following one of those tokens is an expression. |
| 19617 | FnExprTokens = ['(', '{', '[', 'in', 'typeof', 'instanceof', 'new', |
| 19618 | 'return', 'case', 'delete', 'throw', 'void', |
| 19619 | // assignment operators |
| 19620 | '=', '+=', '-=', '*=', '/=', '%=', '<<=', '>>=', '>>>=', |
| 19621 | '&=', '|=', '^=', ',', |
| 19622 | // binary/unary operators |
| 19623 | '+', '-', '*', '/', '%', '++', '--', '<<', '>>', '>>>', '&', |
| 19624 | '|', '^', '!', '~', '&&', '||', '?', ':', '===', '==', '>=', |
| 19625 | '<=', '<', '>', '!=', '!==']; |
| 19626 | |
| 19627 | Syntax = { |
| 19628 | AssignmentExpression: 'AssignmentExpression', |
| 19629 | AssignmentPattern: 'AssignmentPattern', |
| 19630 | ArrayExpression: 'ArrayExpression', |
| 19631 | ArrayPattern: 'ArrayPattern', |
| 19632 | ArrowFunctionExpression: 'ArrowFunctionExpression', |
| 19633 | BlockStatement: 'BlockStatement', |
| 19634 | BinaryExpression: 'BinaryExpression', |
| 19635 | BreakStatement: 'BreakStatement', |
| 19636 | CallExpression: 'CallExpression', |
| 19637 | CatchClause: 'CatchClause', |
| 19638 | ClassBody: 'ClassBody', |
| 19639 | ClassDeclaration: 'ClassDeclaration', |
| 19640 | ClassExpression: 'ClassExpression', |
| 19641 | ConditionalExpression: 'ConditionalExpression', |
| 19642 | ContinueStatement: 'ContinueStatement', |
| 19643 | DoWhileStatement: 'DoWhileStatement', |
| 19644 | DebuggerStatement: 'DebuggerStatement', |
| 19645 | EmptyStatement: 'EmptyStatement', |
| 19646 | ExportAllDeclaration: 'ExportAllDeclaration', |
| 19647 | ExportDefaultDeclaration: 'ExportDefaultDeclaration', |
| 19648 | ExportNamedDeclaration: 'ExportNamedDeclaration', |
| 19649 | ExportSpecifier: 'ExportSpecifier', |
| 19650 | ExpressionStatement: 'ExpressionStatement', |
| 19651 | ForStatement: 'ForStatement', |
| 19652 | ForInStatement: 'ForInStatement', |
| 19653 | FunctionDeclaration: 'FunctionDeclaration', |
| 19654 | FunctionExpression: 'FunctionExpression', |
| 19655 | Identifier: 'Identifier', |
| 19656 | IfStatement: 'IfStatement', |
| 19657 | ImportDeclaration: 'ImportDeclaration', |
| 19658 | ImportDefaultSpecifier: 'ImportDefaultSpecifier', |
| 19659 | ImportNamespaceSpecifier: 'ImportNamespaceSpecifier', |
| 19660 | ImportSpecifier: 'ImportSpecifier', |
| 19661 | Literal: 'Literal', |
| 19662 | LabeledStatement: 'LabeledStatement', |
| 19663 | LogicalExpression: 'LogicalExpression', |
| 19664 | MemberExpression: 'MemberExpression', |
| 19665 | MethodDefinition: 'MethodDefinition', |
| 19666 | NewExpression: 'NewExpression', |
| 19667 | ObjectExpression: 'ObjectExpression', |
| 19668 | ObjectPattern: 'ObjectPattern', |
| 19669 | Program: 'Program', |
| 19670 | Property: 'Property', |
| 19671 | RestElement: 'RestElement', |
| 19672 | ReturnStatement: 'ReturnStatement', |
| 19673 | SequenceExpression: 'SequenceExpression', |
| 19674 | SpreadElement: 'SpreadElement', |
| 19675 | Super: 'Super', |
| 19676 | SwitchCase: 'SwitchCase', |
| 19677 | SwitchStatement: 'SwitchStatement', |
| 19678 | TaggedTemplateExpression: 'TaggedTemplateExpression', |
| 19679 | TemplateElement: 'TemplateElement', |
| 19680 | TemplateLiteral: 'TemplateLiteral', |
| 19681 | ThisExpression: 'ThisExpression', |
| 19682 | ThrowStatement: 'ThrowStatement', |
| 19683 | TryStatement: 'TryStatement', |
| 19684 | UnaryExpression: 'UnaryExpression', |
| 19685 | UpdateExpression: 'UpdateExpression', |
| 19686 | VariableDeclaration: 'VariableDeclaration', |
| 19687 | VariableDeclarator: 'VariableDeclarator', |
| 19688 | WhileStatement: 'WhileStatement', |
| 19689 | WithStatement: 'WithStatement' |
| 19690 | }; |
| 19691 | |
| 19692 | PlaceHolders = { |
| 19693 | ArrowParameterPlaceHolder: 'ArrowParameterPlaceHolder' |
| 19694 | }; |
| 19695 | |
| 19696 | // Error messages should be identical to V8. |
| 19697 | Messages = { |
| 19698 | UnexpectedToken: 'Unexpected token %0', |
| 19699 | UnexpectedNumber: 'Unexpected number', |
| 19700 | UnexpectedString: 'Unexpected string', |
| 19701 | UnexpectedIdentifier: 'Unexpected identifier', |
| 19702 | UnexpectedReserved: 'Unexpected reserved word', |
| 19703 | UnexpectedTemplate: 'Unexpected quasi %0', |
| 19704 | UnexpectedEOS: 'Unexpected end of input', |
| 19705 | NewlineAfterThrow: 'Illegal newline after throw', |
| 19706 | InvalidRegExp: 'Invalid regular expression', |
| 19707 | UnterminatedRegExp: 'Invalid regular expression: missing /', |
| 19708 | InvalidLHSInAssignment: 'Invalid left-hand side in assignment', |
| 19709 | InvalidLHSInForIn: 'Invalid left-hand side in for-in', |
| 19710 | MultipleDefaultsInSwitch: 'More than one default clause in switch statement', |
| 19711 | NoCatchOrFinally: 'Missing catch or finally after try', |
| 19712 | UnknownLabel: 'Undefined label \'%0\'', |
| 19713 | Redeclaration: '%0 \'%1\' has already been declared', |
| 19714 | IllegalContinue: 'Illegal continue statement', |
| 19715 | IllegalBreak: 'Illegal break statement', |
| 19716 | IllegalReturn: 'Illegal return statement', |
| 19717 | StrictModeWith: 'Strict mode code may not include a with statement', |
| 19718 | StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode', |
| 19719 | StrictVarName: 'Variable name may not be eval or arguments in strict mode', |
| 19720 | StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode', |
| 19721 | StrictParamDupe: 'Strict mode function may not have duplicate parameter names', |
| 19722 | StrictFunctionName: 'Function name may not be eval or arguments in strict mode', |
| 19723 | StrictOctalLiteral: 'Octal literals are not allowed in strict mode.', |
| 19724 | StrictDelete: 'Delete of an unqualified identifier in strict mode.', |
| 19725 | StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode', |
| 19726 | StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode', |
| 19727 | StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode', |
| 19728 | StrictReservedWord: 'Use of future reserved word in strict mode', |
| 19729 | TemplateOctalLiteral: 'Octal literals are not allowed in template strings.', |
| 19730 | ParameterAfterRestParameter: 'Rest parameter must be last formal parameter', |
| 19731 | DefaultRestParameter: 'Unexpected token =', |
| 19732 | ObjectPatternAsRestParameter: 'Unexpected token {', |
| 19733 | DuplicateProtoProperty: 'Duplicate __proto__ fields are not allowed in object literals', |
| 19734 | ConstructorSpecialMethod: 'Class constructor may not be an accessor', |
| 19735 | DuplicateConstructor: 'A class may only have one constructor', |
| 19736 | StaticPrototype: 'Classes may not have static property named prototype', |
| 19737 | MissingFromClause: 'Unexpected token', |
| 19738 | NoAsAfterImportNamespace: 'Unexpected token', |
| 19739 | InvalidModuleSpecifier: 'Unexpected token', |
| 19740 | IllegalImportDeclaration: 'Unexpected token', |
| 19741 | IllegalExportDeclaration: 'Unexpected token' |
| 19742 | }; |
| 19743 | |
| 19744 | // See also tools/generate-unicode-regex.py. |
| 19745 | Regex = { |
| 19746 | NonAsciiIdentifierStart: new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]'), |
| 19747 | NonAsciiIdentifierPart: new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B2\u08E4-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D60-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA69D\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2D\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]') |
| 19748 | }; |
| 19749 | |
| 19750 | // Ensure the condition is true, otherwise throw an error. |
| 19751 | // This is only to have a better contract semantic, i.e. another safety net |
| 19752 | // to catch a logic error. The condition shall be fulfilled in normal case. |
| 19753 | // Do NOT use this to enforce a certain condition on any user input. |
| 19754 | |
| 19755 | function assert(condition, message) { |
| 19756 | /* istanbul ignore if */ |
| 19757 | if (!condition) { |
| 19758 | throw new Error('ASSERT: ' + message); |
| 19759 | } |
| 19760 | } |
| 19761 | |
| 19762 | function isDecimalDigit(ch) { |
| 19763 | return (ch >= 0x30 && ch <= 0x39); // 0..9 |
| 19764 | } |
| 19765 | |
| 19766 | function isHexDigit(ch) { |
| 19767 | return '0123456789abcdefABCDEF'.indexOf(ch) >= 0; |
| 19768 | } |
| 19769 | |
| 19770 | function isOctalDigit(ch) { |
| 19771 | return '01234567'.indexOf(ch) >= 0; |
| 19772 | } |
| 19773 | |
| 19774 | function octalToDecimal(ch) { |
| 19775 | // \0 is not octal escape sequence |
| 19776 | var octal = (ch !== '0'), code = '01234567'.indexOf(ch); |
| 19777 | |
| 19778 | if (index < length && isOctalDigit(source[index])) { |
| 19779 | octal = true; |
| 19780 | code = code * 8 + '01234567'.indexOf(source[index++]); |
| 19781 | |
| 19782 | // 3 digits are only allowed when string starts |
| 19783 | // with 0, 1, 2, 3 |
| 19784 | if ('0123'.indexOf(ch) >= 0 && |
| 19785 | index < length && |
| 19786 | isOctalDigit(source[index])) { |
| 19787 | code = code * 8 + '01234567'.indexOf(source[index++]); |
| 19788 | } |
| 19789 | } |
| 19790 | |
| 19791 | return { |
| 19792 | code: code, |
| 19793 | octal: octal |
| 19794 | }; |
| 19795 | } |
| 19796 | |
| 19797 | // 7.2 White Space |
| 19798 | |
| 19799 | function isWhiteSpace(ch) { |
| 19800 | return (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) || |
| 19801 | (ch >= 0x1680 && [0x1680, 0x180E, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(ch) >= 0); |
| 19802 | } |
| 19803 | |
| 19804 | // 7.3 Line Terminators |
| 19805 | |
| 19806 | function isLineTerminator(ch) { |
| 19807 | return (ch === 0x0A) || (ch === 0x0D) || (ch === 0x2028) || (ch === 0x2029); |
| 19808 | } |
| 19809 | |
| 19810 | // 7.6 Identifier Names and Identifiers |
| 19811 | |
| 19812 | function isIdentifierStart(ch) { |
| 19813 | return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore) |
| 19814 | (ch >= 0x41 && ch <= 0x5A) || // A..Z |
| 19815 | (ch >= 0x61 && ch <= 0x7A) || // a..z |
| 19816 | (ch === 0x5C) || // \ (backslash) |
| 19817 | ((ch >= 0x80) && Regex.NonAsciiIdentifierStart.test(String.fromCharCode(ch))); |
| 19818 | } |
| 19819 | |
| 19820 | function isIdentifierPart(ch) { |
| 19821 | return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore) |
| 19822 | (ch >= 0x41 && ch <= 0x5A) || // A..Z |
| 19823 | (ch >= 0x61 && ch <= 0x7A) || // a..z |
| 19824 | (ch >= 0x30 && ch <= 0x39) || // 0..9 |
| 19825 | (ch === 0x5C) || // \ (backslash) |
| 19826 | ((ch >= 0x80) && Regex.NonAsciiIdentifierPart.test(String.fromCharCode(ch))); |
| 19827 | } |
| 19828 | |
| 19829 | // 7.6.1.2 Future Reserved Words |
| 19830 | |
| 19831 | function isFutureReservedWord(id) { |
| 19832 | switch (id) { |
| 19833 | case 'enum': |
| 19834 | case 'export': |
| 19835 | case 'import': |
| 19836 | case 'super': |
| 19837 | return true; |
| 19838 | default: |
| 19839 | return false; |
| 19840 | } |
| 19841 | } |
| 19842 | |
| 19843 | // 11.6.2.2 Future Reserved Words |
| 19844 | |
| 19845 | function isStrictModeReservedWord(id) { |
| 19846 | switch (id) { |
| 19847 | case 'implements': |
| 19848 | case 'interface': |
| 19849 | case 'package': |
| 19850 | case 'private': |
| 19851 | case 'protected': |
| 19852 | case 'public': |
| 19853 | case 'static': |
| 19854 | case 'yield': |
| 19855 | case 'let': |
| 19856 | return true; |
| 19857 | default: |
| 19858 | return false; |
| 19859 | } |
| 19860 | } |
| 19861 | |
| 19862 | function isRestrictedWord(id) { |
| 19863 | return id === 'eval' || id === 'arguments'; |
| 19864 | } |
| 19865 | |
| 19866 | // 7.6.1.1 Keywords |
| 19867 | |
| 19868 | function isKeyword(id) { |
| 19869 | |
| 19870 | // 'const' is specialized as Keyword in V8. |
| 19871 | // 'yield' and 'let' are for compatibility with SpiderMonkey and ES.next. |
| 19872 | // Some others are from future reserved words. |
| 19873 | |
| 19874 | switch (id.length) { |
| 19875 | case 2: |
| 19876 | return (id === 'if') || (id === 'in') || (id === 'do'); |
| 19877 | case 3: |
| 19878 | return (id === 'var') || (id === 'for') || (id === 'new') || |
| 19879 | (id === 'try') || (id === 'let'); |
| 19880 | case 4: |
| 19881 | return (id === 'this') || (id === 'else') || (id === 'case') || |
| 19882 | (id === 'void') || (id === 'with') || (id === 'enum'); |
| 19883 | case 5: |
| 19884 | return (id === 'while') || (id === 'break') || (id === 'catch') || |
| 19885 | (id === 'throw') || (id === 'const') || (id === 'yield') || |
| 19886 | (id === 'class') || (id === 'super'); |
| 19887 | case 6: |
| 19888 | return (id === 'return') || (id === 'typeof') || (id === 'delete') || |
| 19889 | (id === 'switch') || (id === 'export') || (id === 'import'); |
| 19890 | case 7: |
| 19891 | return (id === 'default') || (id === 'finally') || (id === 'extends'); |
| 19892 | case 8: |
| 19893 | return (id === 'function') || (id === 'continue') || (id === 'debugger'); |
| 19894 | case 10: |
| 19895 | return (id === 'instanceof'); |
| 19896 | default: |
| 19897 | return false; |
| 19898 | } |
| 19899 | } |
| 19900 | |
| 19901 | // 7.4 Comments |
| 19902 | |
| 19903 | function addComment(type, value, start, end, loc) { |
| 19904 | var comment; |
| 19905 | |
| 19906 | assert(typeof start === 'number', 'Comment must have valid position'); |
| 19907 | |
| 19908 | state.lastCommentStart = start; |
| 19909 | |
| 19910 | comment = { |
| 19911 | type: type, |
| 19912 | value: value |
| 19913 | }; |
| 19914 | if (extra.range) { |
| 19915 | comment.range = [start, end]; |
| 19916 | } |
| 19917 | if (extra.loc) { |
| 19918 | comment.loc = loc; |
| 19919 | } |
| 19920 | extra.comments.push(comment); |
| 19921 | if (extra.attachComment) { |
| 19922 | extra.leadingComments.push(comment); |
| 19923 | extra.trailingComments.push(comment); |
| 19924 | } |
| 19925 | } |
| 19926 | |
| 19927 | function skipSingleLineComment(offset) { |
| 19928 | var start, loc, ch, comment; |
| 19929 | |
| 19930 | start = index - offset; |
| 19931 | loc = { |
| 19932 | start: { |
| 19933 | line: lineNumber, |
| 19934 | column: index - lineStart - offset |
| 19935 | } |
| 19936 | }; |
| 19937 | |
| 19938 | while (index < length) { |
| 19939 | ch = source.charCodeAt(index); |
| 19940 | ++index; |
| 19941 | if (isLineTerminator(ch)) { |
| 19942 | hasLineTerminator = true; |
| 19943 | if (extra.comments) { |
| 19944 | comment = source.slice(start + offset, index - 1); |
| 19945 | loc.end = { |
| 19946 | line: lineNumber, |
| 19947 | column: index - lineStart - 1 |
| 19948 | }; |
| 19949 | addComment('Line', comment, start, index - 1, loc); |
| 19950 | } |
| 19951 | if (ch === 13 && source.charCodeAt(index) === 10) { |
| 19952 | ++index; |
| 19953 | } |
| 19954 | ++lineNumber; |
| 19955 | lineStart = index; |
| 19956 | return; |
| 19957 | } |
| 19958 | } |
| 19959 | |
| 19960 | if (extra.comments) { |
| 19961 | comment = source.slice(start + offset, index); |
| 19962 | loc.end = { |
| 19963 | line: lineNumber, |
| 19964 | column: index - lineStart |
| 19965 | }; |
| 19966 | addComment('Line', comment, start, index, loc); |
| 19967 | } |
| 19968 | } |
| 19969 | |
| 19970 | function skipMultiLineComment() { |
| 19971 | var start, loc, ch, comment; |
| 19972 | |
| 19973 | if (extra.comments) { |
| 19974 | start = index - 2; |
| 19975 | loc = { |
| 19976 | start: { |
| 19977 | line: lineNumber, |
| 19978 | column: index - lineStart - 2 |
| 19979 | } |
| 19980 | }; |
| 19981 | } |
| 19982 | |
| 19983 | while (index < length) { |
| 19984 | ch = source.charCodeAt(index); |
| 19985 | if (isLineTerminator(ch)) { |
| 19986 | if (ch === 0x0D && source.charCodeAt(index + 1) === 0x0A) { |
| 19987 | ++index; |
| 19988 | } |
| 19989 | hasLineTerminator = true; |
| 19990 | ++lineNumber; |
| 19991 | ++index; |
| 19992 | lineStart = index; |
| 19993 | } else if (ch === 0x2A) { |
| 19994 | // Block comment ends with '*/'. |
| 19995 | if (source.charCodeAt(index + 1) === 0x2F) { |
| 19996 | ++index; |
| 19997 | ++index; |
| 19998 | if (extra.comments) { |
| 19999 | comment = source.slice(start + 2, index - 2); |
| 20000 | loc.end = { |
| 20001 | line: lineNumber, |
| 20002 | column: index - lineStart |
| 20003 | }; |
| 20004 | addComment('Block', comment, start, index, loc); |
| 20005 | } |
| 20006 | return; |
| 20007 | } |
| 20008 | ++index; |
| 20009 | } else { |
| 20010 | ++index; |
| 20011 | } |
| 20012 | } |
| 20013 | |
| 20014 | // Ran off the end of the file - the whole thing is a comment |
| 20015 | if (extra.comments) { |
| 20016 | loc.end = { |
| 20017 | line: lineNumber, |
| 20018 | column: index - lineStart |
| 20019 | }; |
| 20020 | comment = source.slice(start + 2, index); |
| 20021 | addComment('Block', comment, start, index, loc); |
| 20022 | } |
| 20023 | tolerateUnexpectedToken(); |
| 20024 | } |
| 20025 | |
| 20026 | function skipComment() { |
| 20027 | var ch, start; |
| 20028 | hasLineTerminator = false; |
| 20029 | |
| 20030 | start = (index === 0); |
| 20031 | while (index < length) { |
| 20032 | ch = source.charCodeAt(index); |
| 20033 | |
| 20034 | if (isWhiteSpace(ch)) { |
| 20035 | ++index; |
| 20036 | } else if (isLineTerminator(ch)) { |
| 20037 | hasLineTerminator = true; |
| 20038 | ++index; |
| 20039 | if (ch === 0x0D && source.charCodeAt(index) === 0x0A) { |
| 20040 | ++index; |
| 20041 | } |
| 20042 | ++lineNumber; |
| 20043 | lineStart = index; |
| 20044 | start = true; |
| 20045 | } else if (ch === 0x2F) { // U+002F is '/' |
| 20046 | ch = source.charCodeAt(index + 1); |
| 20047 | if (ch === 0x2F) { |
| 20048 | ++index; |
| 20049 | ++index; |
| 20050 | skipSingleLineComment(2); |
| 20051 | start = true; |
| 20052 | } else if (ch === 0x2A) { // U+002A is '*' |
| 20053 | ++index; |
| 20054 | ++index; |
| 20055 | skipMultiLineComment(); |
| 20056 | } else { |
| 20057 | break; |
| 20058 | } |
| 20059 | } else if (start && ch === 0x2D) { // U+002D is '-' |
| 20060 | // U+003E is '>' |
| 20061 | if ((source.charCodeAt(index + 1) === 0x2D) && (source.charCodeAt(index + 2) === 0x3E)) { |
| 20062 | // '-->' is a single-line comment |
| 20063 | index += 3; |
| 20064 | skipSingleLineComment(3); |
| 20065 | } else { |
| 20066 | break; |
| 20067 | } |
| 20068 | } else if (ch === 0x3C) { // U+003C is '<' |
| 20069 | if (source.slice(index + 1, index + 4) === '!--') { |
| 20070 | ++index; // `<` |
| 20071 | ++index; // `!` |
| 20072 | ++index; // `-` |
| 20073 | ++index; // `-` |
| 20074 | skipSingleLineComment(4); |
| 20075 | } else { |
| 20076 | break; |
| 20077 | } |
| 20078 | } else { |
| 20079 | break; |
| 20080 | } |
| 20081 | } |
| 20082 | } |
| 20083 | |
| 20084 | function scanHexEscape(prefix) { |
| 20085 | var i, len, ch, code = 0; |
| 20086 | |
| 20087 | len = (prefix === 'u') ? 4 : 2; |
| 20088 | for (i = 0; i < len; ++i) { |
| 20089 | if (index < length && isHexDigit(source[index])) { |
| 20090 | ch = source[index++]; |
| 20091 | code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase()); |
| 20092 | } else { |
| 20093 | return ''; |
| 20094 | } |
| 20095 | } |
| 20096 | return String.fromCharCode(code); |
| 20097 | } |
| 20098 | |
| 20099 | function scanUnicodeCodePointEscape() { |
| 20100 | var ch, code, cu1, cu2; |
| 20101 | |
| 20102 | ch = source[index]; |
| 20103 | code = 0; |
| 20104 | |
| 20105 | // At least, one hex digit is required. |
| 20106 | if (ch === '}') { |
| 20107 | throwUnexpectedToken(); |
| 20108 | } |
| 20109 | |
| 20110 | while (index < length) { |
| 20111 | ch = source[index++]; |
| 20112 | if (!isHexDigit(ch)) { |
| 20113 | break; |
| 20114 | } |
| 20115 | code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase()); |
| 20116 | } |
| 20117 | |
| 20118 | if (code > 0x10FFFF || ch !== '}') { |
| 20119 | throwUnexpectedToken(); |
| 20120 | } |
| 20121 | |
| 20122 | // UTF-16 Encoding |
| 20123 | if (code <= 0xFFFF) { |
| 20124 | return String.fromCharCode(code); |
| 20125 | } |
| 20126 | cu1 = ((code - 0x10000) >> 10) + 0xD800; |
| 20127 | cu2 = ((code - 0x10000) & 1023) + 0xDC00; |
| 20128 | return String.fromCharCode(cu1, cu2); |
| 20129 | } |
| 20130 | |
| 20131 | function getEscapedIdentifier() { |
| 20132 | var ch, id; |
| 20133 | |
| 20134 | ch = source.charCodeAt(index++); |
| 20135 | id = String.fromCharCode(ch); |
| 20136 | |
| 20137 | // '\u' (U+005C, U+0075) denotes an escaped character. |
| 20138 | if (ch === 0x5C) { |
| 20139 | if (source.charCodeAt(index) !== 0x75) { |
| 20140 | throwUnexpectedToken(); |
| 20141 | } |
| 20142 | ++index; |
| 20143 | ch = scanHexEscape('u'); |
| 20144 | if (!ch || ch === '\\' || !isIdentifierStart(ch.charCodeAt(0))) { |
| 20145 | throwUnexpectedToken(); |
| 20146 | } |
| 20147 | id = ch; |
| 20148 | } |
| 20149 | |
| 20150 | while (index < length) { |
| 20151 | ch = source.charCodeAt(index); |
| 20152 | if (!isIdentifierPart(ch)) { |
| 20153 | break; |
| 20154 | } |
| 20155 | ++index; |
| 20156 | id += String.fromCharCode(ch); |
| 20157 | |
| 20158 | // '\u' (U+005C, U+0075) denotes an escaped character. |
| 20159 | if (ch === 0x5C) { |
| 20160 | id = id.substr(0, id.length - 1); |
| 20161 | if (source.charCodeAt(index) !== 0x75) { |
| 20162 | throwUnexpectedToken(); |
| 20163 | } |
| 20164 | ++index; |
| 20165 | ch = scanHexEscape('u'); |
| 20166 | if (!ch || ch === '\\' || !isIdentifierPart(ch.charCodeAt(0))) { |
| 20167 | throwUnexpectedToken(); |
| 20168 | } |
| 20169 | id += ch; |
| 20170 | } |
| 20171 | } |
| 20172 | |
| 20173 | return id; |
| 20174 | } |
| 20175 | |
| 20176 | function getIdentifier() { |
| 20177 | var start, ch; |
| 20178 | |
| 20179 | start = index++; |
| 20180 | while (index < length) { |
| 20181 | ch = source.charCodeAt(index); |
| 20182 | if (ch === 0x5C) { |
| 20183 | // Blackslash (U+005C) marks Unicode escape sequence. |
| 20184 | index = start; |
| 20185 | return getEscapedIdentifier(); |
| 20186 | } |
| 20187 | if (isIdentifierPart(ch)) { |
| 20188 | ++index; |
| 20189 | } else { |
| 20190 | break; |
| 20191 | } |
| 20192 | } |
| 20193 | |
| 20194 | return source.slice(start, index); |
| 20195 | } |
| 20196 | |
| 20197 | function scanIdentifier() { |
| 20198 | var start, id, type; |
| 20199 | |
| 20200 | start = index; |
| 20201 | |
| 20202 | // Backslash (U+005C) starts an escaped character. |
| 20203 | id = (source.charCodeAt(index) === 0x5C) ? getEscapedIdentifier() : getIdentifier(); |
| 20204 | |
| 20205 | // There is no keyword or literal with only one character. |
| 20206 | // Thus, it must be an identifier. |
| 20207 | if (id.length === 1) { |
| 20208 | type = Token.Identifier; |
| 20209 | } else if (isKeyword(id)) { |
| 20210 | type = Token.Keyword; |
| 20211 | } else if (id === 'null') { |
| 20212 | type = Token.NullLiteral; |
| 20213 | } else if (id === 'true' || id === 'false') { |
| 20214 | type = Token.BooleanLiteral; |
| 20215 | } else { |
| 20216 | type = Token.Identifier; |
| 20217 | } |
| 20218 | |
| 20219 | return { |
| 20220 | type: type, |
| 20221 | value: id, |
| 20222 | lineNumber: lineNumber, |
| 20223 | lineStart: lineStart, |
| 20224 | start: start, |
| 20225 | end: index |
| 20226 | }; |
| 20227 | } |
| 20228 | |
| 20229 | |
| 20230 | // 7.7 Punctuators |
| 20231 | |
| 20232 | function scanPunctuator() { |
| 20233 | var token, str; |
| 20234 | |
| 20235 | token = { |
| 20236 | type: Token.Punctuator, |
| 20237 | value: '', |
| 20238 | lineNumber: lineNumber, |
| 20239 | lineStart: lineStart, |
| 20240 | start: index, |
| 20241 | end: index |
| 20242 | }; |
| 20243 | |
| 20244 | // Check for most common single-character punctuators. |
| 20245 | str = source[index]; |
| 20246 | switch (str) { |
| 20247 | |
| 20248 | case '(': |
| 20249 | if (extra.tokenize) { |
| 20250 | extra.openParenToken = extra.tokens.length; |
| 20251 | } |
| 20252 | ++index; |
| 20253 | break; |
| 20254 | |
| 20255 | case '{': |
| 20256 | if (extra.tokenize) { |
| 20257 | extra.openCurlyToken = extra.tokens.length; |
| 20258 | } |
| 20259 | state.curlyStack.push('{'); |
| 20260 | ++index; |
| 20261 | break; |
| 20262 | |
| 20263 | case '.': |
| 20264 | ++index; |
| 20265 | if (source[index] === '.' && source[index + 1] === '.') { |
| 20266 | // Spread operator: ... |
| 20267 | index += 2; |
| 20268 | str = '...'; |
| 20269 | } |
| 20270 | break; |
| 20271 | |
| 20272 | case '}': |
| 20273 | ++index; |
| 20274 | state.curlyStack.pop(); |
| 20275 | break; |
| 20276 | case ')': |
| 20277 | case ';': |
| 20278 | case ',': |
| 20279 | case '[': |
| 20280 | case ']': |
| 20281 | case ':': |
| 20282 | case '?': |
| 20283 | case '~': |
| 20284 | ++index; |
| 20285 | break; |
| 20286 | |
| 20287 | default: |
| 20288 | // 4-character punctuator. |
| 20289 | str = source.substr(index, 4); |
| 20290 | if (str === '>>>=') { |
| 20291 | index += 4; |
| 20292 | } else { |
| 20293 | |
| 20294 | // 3-character punctuators. |
| 20295 | str = str.substr(0, 3); |
| 20296 | if (str === '===' || str === '!==' || str === '>>>' || |
| 20297 | str === '<<=' || str === '>>=') { |
| 20298 | index += 3; |
| 20299 | } else { |
| 20300 | |
| 20301 | // 2-character punctuators. |
| 20302 | str = str.substr(0, 2); |
| 20303 | if (str === '&&' || str === '||' || str === '==' || str === '!=' || |
| 20304 | str === '+=' || str === '-=' || str === '*=' || str === '/=' || |
| 20305 | str === '++' || str === '--' || str === '<<' || str === '>>' || |
| 20306 | str === '&=' || str === '|=' || str === '^=' || str === '%=' || |
| 20307 | str === '<=' || str === '>=' || str === '=>') { |
| 20308 | index += 2; |
| 20309 | } else { |
| 20310 | |
| 20311 | // 1-character punctuators. |
| 20312 | str = source[index]; |
| 20313 | if ('<>=!+-*%&|^/'.indexOf(str) >= 0) { |
| 20314 | ++index; |
| 20315 | } |
| 20316 | } |
| 20317 | } |
| 20318 | } |
| 20319 | } |
| 20320 | |
| 20321 | if (index === token.start) { |
| 20322 | throwUnexpectedToken(); |
| 20323 | } |
| 20324 | |
| 20325 | token.end = index; |
| 20326 | token.value = str; |
| 20327 | return token; |
| 20328 | } |
| 20329 | |
| 20330 | // 7.8.3 Numeric Literals |
| 20331 | |
| 20332 | function scanHexLiteral(start) { |
| 20333 | var number = ''; |
| 20334 | |
| 20335 | while (index < length) { |
| 20336 | if (!isHexDigit(source[index])) { |
| 20337 | break; |
| 20338 | } |
| 20339 | number += source[index++]; |
| 20340 | } |
| 20341 | |
| 20342 | if (number.length === 0) { |
| 20343 | throwUnexpectedToken(); |
| 20344 | } |
| 20345 | |
| 20346 | if (isIdentifierStart(source.charCodeAt(index))) { |
| 20347 | throwUnexpectedToken(); |
| 20348 | } |
| 20349 | |
| 20350 | return { |
| 20351 | type: Token.NumericLiteral, |
| 20352 | value: parseInt('0x' + number, 16), |
| 20353 | lineNumber: lineNumber, |
| 20354 | lineStart: lineStart, |
| 20355 | start: start, |
| 20356 | end: index |
| 20357 | }; |
| 20358 | } |
| 20359 | |
| 20360 | function scanBinaryLiteral(start) { |
| 20361 | var ch, number; |
| 20362 | |
| 20363 | number = ''; |
| 20364 | |
| 20365 | while (index < length) { |
| 20366 | ch = source[index]; |
| 20367 | if (ch !== '0' && ch !== '1') { |
| 20368 | break; |
| 20369 | } |
| 20370 | number += source[index++]; |
| 20371 | } |
| 20372 | |
| 20373 | if (number.length === 0) { |
| 20374 | // only 0b or 0B |
| 20375 | throwUnexpectedToken(); |
| 20376 | } |
| 20377 | |
| 20378 | if (index < length) { |
| 20379 | ch = source.charCodeAt(index); |
| 20380 | /* istanbul ignore else */ |
| 20381 | if (isIdentifierStart(ch) || isDecimalDigit(ch)) { |
| 20382 | throwUnexpectedToken(); |
| 20383 | } |
| 20384 | } |
| 20385 | |
| 20386 | return { |
| 20387 | type: Token.NumericLiteral, |
| 20388 | value: parseInt(number, 2), |
| 20389 | lineNumber: lineNumber, |
| 20390 | lineStart: lineStart, |
| 20391 | start: start, |
| 20392 | end: index |
| 20393 | }; |
| 20394 | } |
| 20395 | |
| 20396 | function scanOctalLiteral(prefix, start) { |
| 20397 | var number, octal; |
| 20398 | |
| 20399 | if (isOctalDigit(prefix)) { |
| 20400 | octal = true; |
| 20401 | number = '0' + source[index++]; |
| 20402 | } else { |
| 20403 | octal = false; |
| 20404 | ++index; |
| 20405 | number = ''; |
| 20406 | } |
| 20407 | |
| 20408 | while (index < length) { |
| 20409 | if (!isOctalDigit(source[index])) { |
| 20410 | break; |
| 20411 | } |
| 20412 | number += source[index++]; |
| 20413 | } |
| 20414 | |
| 20415 | if (!octal && number.length === 0) { |
| 20416 | // only 0o or 0O |
| 20417 | throwUnexpectedToken(); |
| 20418 | } |
| 20419 | |
| 20420 | if (isIdentifierStart(source.charCodeAt(index)) || isDecimalDigit(source.charCodeAt(index))) { |
| 20421 | throwUnexpectedToken(); |
| 20422 | } |
| 20423 | |
| 20424 | return { |
| 20425 | type: Token.NumericLiteral, |
| 20426 | value: parseInt(number, 8), |
| 20427 | octal: octal, |
| 20428 | lineNumber: lineNumber, |
| 20429 | lineStart: lineStart, |
| 20430 | start: start, |
| 20431 | end: index |
| 20432 | }; |
| 20433 | } |
| 20434 | |
| 20435 | function isImplicitOctalLiteral() { |
| 20436 | var i, ch; |
| 20437 | |
| 20438 | // Implicit octal, unless there is a non-octal digit. |
| 20439 | // (Annex B.1.1 on Numeric Literals) |
| 20440 | for (i = index + 1; i < length; ++i) { |
| 20441 | ch = source[i]; |
| 20442 | if (ch === '8' || ch === '9') { |
| 20443 | return false; |
| 20444 | } |
| 20445 | if (!isOctalDigit(ch)) { |
| 20446 | return true; |
| 20447 | } |
| 20448 | } |
| 20449 | |
| 20450 | return true; |
| 20451 | } |
| 20452 | |
| 20453 | function scanNumericLiteral() { |
| 20454 | var number, start, ch; |
| 20455 | |
| 20456 | ch = source[index]; |
| 20457 | assert(isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'), |
| 20458 | 'Numeric literal must start with a decimal digit or a decimal point'); |
| 20459 | |
| 20460 | start = index; |
| 20461 | number = ''; |
| 20462 | if (ch !== '.') { |
| 20463 | number = source[index++]; |
| 20464 | ch = source[index]; |
| 20465 | |
| 20466 | // Hex number starts with '0x'. |
| 20467 | // Octal number starts with '0'. |
| 20468 | // Octal number in ES6 starts with '0o'. |
| 20469 | // Binary number in ES6 starts with '0b'. |
| 20470 | if (number === '0') { |
| 20471 | if (ch === 'x' || ch === 'X') { |
| 20472 | ++index; |
| 20473 | return scanHexLiteral(start); |
| 20474 | } |
| 20475 | if (ch === 'b' || ch === 'B') { |
| 20476 | ++index; |
| 20477 | return scanBinaryLiteral(start); |
| 20478 | } |
| 20479 | if (ch === 'o' || ch === 'O') { |
| 20480 | return scanOctalLiteral(ch, start); |
| 20481 | } |
| 20482 | |
| 20483 | if (isOctalDigit(ch)) { |
| 20484 | if (isImplicitOctalLiteral()) { |
| 20485 | return scanOctalLiteral(ch, start); |
| 20486 | } |
| 20487 | } |
| 20488 | } |
| 20489 | |
| 20490 | while (isDecimalDigit(source.charCodeAt(index))) { |
| 20491 | number += source[index++]; |
| 20492 | } |
| 20493 | ch = source[index]; |
| 20494 | } |
| 20495 | |
| 20496 | if (ch === '.') { |
| 20497 | number += source[index++]; |
| 20498 | while (isDecimalDigit(source.charCodeAt(index))) { |
| 20499 | number += source[index++]; |
| 20500 | } |
| 20501 | ch = source[index]; |
| 20502 | } |
| 20503 | |
| 20504 | if (ch === 'e' || ch === 'E') { |
| 20505 | number += source[index++]; |
| 20506 | |
| 20507 | ch = source[index]; |
| 20508 | if (ch === '+' || ch === '-') { |
| 20509 | number += source[index++]; |
| 20510 | } |
| 20511 | if (isDecimalDigit(source.charCodeAt(index))) { |
| 20512 | while (isDecimalDigit(source.charCodeAt(index))) { |
| 20513 | number += source[index++]; |
| 20514 | } |
| 20515 | } else { |
| 20516 | throwUnexpectedToken(); |
| 20517 | } |
| 20518 | } |
| 20519 | |
| 20520 | if (isIdentifierStart(source.charCodeAt(index))) { |
| 20521 | throwUnexpectedToken(); |
| 20522 | } |
| 20523 | |
| 20524 | return { |
| 20525 | type: Token.NumericLiteral, |
| 20526 | value: parseFloat(number), |
| 20527 | lineNumber: lineNumber, |
| 20528 | lineStart: lineStart, |
| 20529 | start: start, |
| 20530 | end: index |
| 20531 | }; |
| 20532 | } |
| 20533 | |
| 20534 | // 7.8.4 String Literals |
| 20535 | |
| 20536 | function scanStringLiteral() { |
| 20537 | var str = '', quote, start, ch, unescaped, octToDec, octal = false; |
| 20538 | |
| 20539 | quote = source[index]; |
| 20540 | assert((quote === '\'' || quote === '"'), |
| 20541 | 'String literal must starts with a quote'); |
| 20542 | |
| 20543 | start = index; |
| 20544 | ++index; |
| 20545 | |
| 20546 | while (index < length) { |
| 20547 | ch = source[index++]; |
| 20548 | |
| 20549 | if (ch === quote) { |
| 20550 | quote = ''; |
| 20551 | break; |
| 20552 | } else if (ch === '\\') { |
| 20553 | ch = source[index++]; |
| 20554 | if (!ch || !isLineTerminator(ch.charCodeAt(0))) { |
| 20555 | switch (ch) { |
| 20556 | case 'u': |
| 20557 | case 'x': |
| 20558 | if (source[index] === '{') { |
| 20559 | ++index; |
| 20560 | str += scanUnicodeCodePointEscape(); |
| 20561 | } else { |
| 20562 | unescaped = scanHexEscape(ch); |
| 20563 | if (!unescaped) { |
| 20564 | throw throwUnexpectedToken(); |
| 20565 | } |
| 20566 | str += unescaped; |
| 20567 | } |
| 20568 | break; |
| 20569 | case 'n': |
| 20570 | str += '\n'; |
| 20571 | break; |
| 20572 | case 'r': |
| 20573 | str += '\r'; |
| 20574 | break; |
| 20575 | case 't': |
| 20576 | str += '\t'; |
| 20577 | break; |
| 20578 | case 'b': |
| 20579 | str += '\b'; |
| 20580 | break; |
| 20581 | case 'f': |
| 20582 | str += '\f'; |
| 20583 | break; |
| 20584 | case 'v': |
| 20585 | str += '\x0B'; |
| 20586 | break; |
| 20587 | case '8': |
| 20588 | case '9': |
| 20589 | throw throwUnexpectedToken(); |
| 20590 | |
| 20591 | default: |
| 20592 | if (isOctalDigit(ch)) { |
| 20593 | octToDec = octalToDecimal(ch); |
| 20594 | |
| 20595 | octal = octToDec.octal || octal; |
| 20596 | str += String.fromCharCode(octToDec.code); |
| 20597 | } else { |
| 20598 | str += ch; |
| 20599 | } |
| 20600 | break; |
| 20601 | } |
| 20602 | } else { |
| 20603 | ++lineNumber; |
| 20604 | if (ch === '\r' && source[index] === '\n') { |
| 20605 | ++index; |
| 20606 | } |
| 20607 | lineStart = index; |
| 20608 | } |
| 20609 | } else if (isLineTerminator(ch.charCodeAt(0))) { |
| 20610 | break; |
| 20611 | } else { |
| 20612 | str += ch; |
| 20613 | } |
| 20614 | } |
| 20615 | |
| 20616 | if (quote !== '') { |
| 20617 | throwUnexpectedToken(); |
| 20618 | } |
| 20619 | |
| 20620 | return { |
| 20621 | type: Token.StringLiteral, |
| 20622 | value: str, |
| 20623 | octal: octal, |
| 20624 | lineNumber: startLineNumber, |
| 20625 | lineStart: startLineStart, |
| 20626 | start: start, |
| 20627 | end: index |
| 20628 | }; |
| 20629 | } |
| 20630 | |
| 20631 | function scanTemplate() { |
| 20632 | var cooked = '', ch, start, rawOffset, terminated, head, tail, restore, unescaped; |
| 20633 | |
| 20634 | terminated = false; |
| 20635 | tail = false; |
| 20636 | start = index; |
| 20637 | head = (source[index] === '`'); |
| 20638 | rawOffset = 2; |
| 20639 | |
| 20640 | ++index; |
| 20641 | |
| 20642 | while (index < length) { |
| 20643 | ch = source[index++]; |
| 20644 | if (ch === '`') { |
| 20645 | rawOffset = 1; |
| 20646 | tail = true; |
| 20647 | terminated = true; |
| 20648 | break; |
| 20649 | } else if (ch === '$') { |
| 20650 | if (source[index] === '{') { |
| 20651 | state.curlyStack.push('${'); |
| 20652 | ++index; |
| 20653 | terminated = true; |
| 20654 | break; |
| 20655 | } |
| 20656 | cooked += ch; |
| 20657 | } else if (ch === '\\') { |
| 20658 | ch = source[index++]; |
| 20659 | if (!isLineTerminator(ch.charCodeAt(0))) { |
| 20660 | switch (ch) { |
| 20661 | case 'n': |
| 20662 | cooked += '\n'; |
| 20663 | break; |
| 20664 | case 'r': |
| 20665 | cooked += '\r'; |
| 20666 | break; |
| 20667 | case 't': |
| 20668 | cooked += '\t'; |
| 20669 | break; |
| 20670 | case 'u': |
| 20671 | case 'x': |
| 20672 | if (source[index] === '{') { |
| 20673 | ++index; |
| 20674 | cooked += scanUnicodeCodePointEscape(); |
| 20675 | } else { |
| 20676 | restore = index; |
| 20677 | unescaped = scanHexEscape(ch); |
| 20678 | if (unescaped) { |
| 20679 | cooked += unescaped; |
| 20680 | } else { |
| 20681 | index = restore; |
| 20682 | cooked += ch; |
| 20683 | } |
| 20684 | } |
| 20685 | break; |
| 20686 | case 'b': |
| 20687 | cooked += '\b'; |
| 20688 | break; |
| 20689 | case 'f': |
| 20690 | cooked += '\f'; |
| 20691 | break; |
| 20692 | case 'v': |
| 20693 | cooked += '\v'; |
| 20694 | break; |
| 20695 | |
| 20696 | default: |
| 20697 | if (ch === '0') { |
| 20698 | if (isDecimalDigit(source.charCodeAt(index))) { |
| 20699 | // Illegal: \01 \02 and so on |
| 20700 | throwError(Messages.TemplateOctalLiteral); |
| 20701 | } |
| 20702 | cooked += '\0'; |
| 20703 | } else if (isOctalDigit(ch)) { |
| 20704 | // Illegal: \1 \2 |
| 20705 | throwError(Messages.TemplateOctalLiteral); |
| 20706 | } else { |
| 20707 | cooked += ch; |
| 20708 | } |
| 20709 | break; |
| 20710 | } |
| 20711 | } else { |
| 20712 | ++lineNumber; |
| 20713 | if (ch === '\r' && source[index] === '\n') { |
| 20714 | ++index; |
| 20715 | } |
| 20716 | lineStart = index; |
| 20717 | } |
| 20718 | } else if (isLineTerminator(ch.charCodeAt(0))) { |
| 20719 | ++lineNumber; |
| 20720 | if (ch === '\r' && source[index] === '\n') { |
| 20721 | ++index; |
| 20722 | } |
| 20723 | lineStart = index; |
| 20724 | cooked += '\n'; |
| 20725 | } else { |
| 20726 | cooked += ch; |
| 20727 | } |
| 20728 | } |
| 20729 | |
| 20730 | if (!terminated) { |
| 20731 | throwUnexpectedToken(); |
| 20732 | } |
| 20733 | |
| 20734 | if (!head) { |
| 20735 | state.curlyStack.pop(); |
| 20736 | } |
| 20737 | |
| 20738 | return { |
| 20739 | type: Token.Template, |
| 20740 | value: { |
| 20741 | cooked: cooked, |
| 20742 | raw: source.slice(start + 1, index - rawOffset) |
| 20743 | }, |
| 20744 | head: head, |
| 20745 | tail: tail, |
| 20746 | lineNumber: lineNumber, |
| 20747 | lineStart: lineStart, |
| 20748 | start: start, |
| 20749 | end: index |
| 20750 | }; |
| 20751 | } |
| 20752 | |
| 20753 | function testRegExp(pattern, flags) { |
| 20754 | var tmp = pattern; |
| 20755 | |
| 20756 | if (flags.indexOf('u') >= 0) { |
| 20757 | // Replace each astral symbol and every Unicode escape sequence |
| 20758 | // that possibly represents an astral symbol or a paired surrogate |
| 20759 | // with a single ASCII symbol to avoid throwing on regular |
| 20760 | // expressions that are only valid in combination with the `/u` |
| 20761 | // flag. |
| 20762 | // Note: replacing with the ASCII symbol `x` might cause false |
| 20763 | // negatives in unlikely scenarios. For example, `[\u{61}-b]` is a |
| 20764 | // perfectly valid pattern that is equivalent to `[a-b]`, but it |
| 20765 | // would be replaced by `[x-b]` which throws an error. |
| 20766 | tmp = tmp |
| 20767 | .replace(/\\u\{([0-9a-fA-F]+)\}/g, function ($0, $1) { |
| 20768 | if (parseInt($1, 16) <= 0x10FFFF) { |
| 20769 | return 'x'; |
| 20770 | } |
| 20771 | throwUnexpectedToken(null, Messages.InvalidRegExp); |
| 20772 | }) |
| 20773 | .replace( |
| 20774 | /\\u([a-fA-F0-9]{4})|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, |
| 20775 | 'x' |
| 20776 | ); |
| 20777 | } |
| 20778 | |
| 20779 | // First, detect invalid regular expressions. |
| 20780 | try { |
| 20781 | RegExp(tmp); |
| 20782 | } catch (e) { |
| 20783 | throwUnexpectedToken(null, Messages.InvalidRegExp); |
| 20784 | } |
| 20785 | |
| 20786 | // Return a regular expression object for this pattern-flag pair, or |
| 20787 | // `null` in case the current environment doesn't support the flags it |
| 20788 | // uses. |
| 20789 | try { |
| 20790 | return new RegExp(pattern, flags); |
| 20791 | } catch (exception) { |
| 20792 | return null; |
| 20793 | } |
| 20794 | } |
| 20795 | |
| 20796 | function scanRegExpBody() { |
| 20797 | var ch, str, classMarker, terminated, body; |
| 20798 | |
| 20799 | ch = source[index]; |
| 20800 | assert(ch === '/', 'Regular expression literal must start with a slash'); |
| 20801 | str = source[index++]; |
| 20802 | |
| 20803 | classMarker = false; |
| 20804 | terminated = false; |
| 20805 | while (index < length) { |
| 20806 | ch = source[index++]; |
| 20807 | str += ch; |
| 20808 | if (ch === '\\') { |
| 20809 | ch = source[index++]; |
| 20810 | // ECMA-262 7.8.5 |
| 20811 | if (isLineTerminator(ch.charCodeAt(0))) { |
| 20812 | throwUnexpectedToken(null, Messages.UnterminatedRegExp); |
| 20813 | } |
| 20814 | str += ch; |
| 20815 | } else if (isLineTerminator(ch.charCodeAt(0))) { |
| 20816 | throwUnexpectedToken(null, Messages.UnterminatedRegExp); |
| 20817 | } else if (classMarker) { |
| 20818 | if (ch === ']') { |
| 20819 | classMarker = false; |
| 20820 | } |
| 20821 | } else { |
| 20822 | if (ch === '/') { |
| 20823 | terminated = true; |
| 20824 | break; |
| 20825 | } else if (ch === '[') { |
| 20826 | classMarker = true; |
| 20827 | } |
| 20828 | } |
| 20829 | } |
| 20830 | |
| 20831 | if (!terminated) { |
| 20832 | throwUnexpectedToken(null, Messages.UnterminatedRegExp); |
| 20833 | } |
| 20834 | |
| 20835 | // Exclude leading and trailing slash. |
| 20836 | body = str.substr(1, str.length - 2); |
| 20837 | return { |
| 20838 | value: body, |
| 20839 | literal: str |
| 20840 | }; |
| 20841 | } |
| 20842 | |
| 20843 | function scanRegExpFlags() { |
| 20844 | var ch, str, flags, restore; |
| 20845 | |
| 20846 | str = ''; |
| 20847 | flags = ''; |
| 20848 | while (index < length) { |
| 20849 | ch = source[index]; |
| 20850 | if (!isIdentifierPart(ch.charCodeAt(0))) { |
| 20851 | break; |
| 20852 | } |
| 20853 | |
| 20854 | ++index; |
| 20855 | if (ch === '\\' && index < length) { |
| 20856 | ch = source[index]; |
| 20857 | if (ch === 'u') { |
| 20858 | ++index; |
| 20859 | restore = index; |
| 20860 | ch = scanHexEscape('u'); |
| 20861 | if (ch) { |
| 20862 | flags += ch; |
| 20863 | for (str += '\\u'; restore < index; ++restore) { |
| 20864 | str += source[restore]; |
| 20865 | } |
| 20866 | } else { |
| 20867 | index = restore; |
| 20868 | flags += 'u'; |
| 20869 | str += '\\u'; |
| 20870 | } |
| 20871 | tolerateUnexpectedToken(); |
| 20872 | } else { |
| 20873 | str += '\\'; |
| 20874 | tolerateUnexpectedToken(); |
| 20875 | } |
| 20876 | } else { |
| 20877 | flags += ch; |
| 20878 | str += ch; |
| 20879 | } |
| 20880 | } |
| 20881 | |
| 20882 | return { |
| 20883 | value: flags, |
| 20884 | literal: str |
| 20885 | }; |
| 20886 | } |
| 20887 | |
| 20888 | function scanRegExp() { |
| 20889 | scanning = true; |
| 20890 | var start, body, flags, value; |
| 20891 | |
| 20892 | lookahead = null; |
| 20893 | skipComment(); |
| 20894 | start = index; |
| 20895 | |
| 20896 | body = scanRegExpBody(); |
| 20897 | flags = scanRegExpFlags(); |
| 20898 | value = testRegExp(body.value, flags.value); |
| 20899 | scanning = false; |
| 20900 | if (extra.tokenize) { |
| 20901 | return { |
| 20902 | type: Token.RegularExpression, |
| 20903 | value: value, |
| 20904 | regex: { |
| 20905 | pattern: body.value, |
| 20906 | flags: flags.value |
| 20907 | }, |
| 20908 | lineNumber: lineNumber, |
| 20909 | lineStart: lineStart, |
| 20910 | start: start, |
| 20911 | end: index |
| 20912 | }; |
| 20913 | } |
| 20914 | |
| 20915 | return { |
| 20916 | literal: body.literal + flags.literal, |
| 20917 | value: value, |
| 20918 | regex: { |
| 20919 | pattern: body.value, |
| 20920 | flags: flags.value |
| 20921 | }, |
| 20922 | start: start, |
| 20923 | end: index |
| 20924 | }; |
| 20925 | } |
| 20926 | |
| 20927 | function collectRegex() { |
| 20928 | var pos, loc, regex, token; |
| 20929 | |
| 20930 | skipComment(); |
| 20931 | |
| 20932 | pos = index; |
| 20933 | loc = { |
| 20934 | start: { |
| 20935 | line: lineNumber, |
| 20936 | column: index - lineStart |
| 20937 | } |
| 20938 | }; |
| 20939 | |
| 20940 | regex = scanRegExp(); |
| 20941 | |
| 20942 | loc.end = { |
| 20943 | line: lineNumber, |
| 20944 | column: index - lineStart |
| 20945 | }; |
| 20946 | |
| 20947 | /* istanbul ignore next */ |
| 20948 | if (!extra.tokenize) { |
| 20949 | // Pop the previous token, which is likely '/' or '/=' |
| 20950 | if (extra.tokens.length > 0) { |
| 20951 | token = extra.tokens[extra.tokens.length - 1]; |
| 20952 | if (token.range[0] === pos && token.type === 'Punctuator') { |
| 20953 | if (token.value === '/' || token.value === '/=') { |
| 20954 | extra.tokens.pop(); |
| 20955 | } |
| 20956 | } |
| 20957 | } |
| 20958 | |
| 20959 | extra.tokens.push({ |
| 20960 | type: 'RegularExpression', |
| 20961 | value: regex.literal, |
| 20962 | regex: regex.regex, |
| 20963 | range: [pos, index], |
| 20964 | loc: loc |
| 20965 | }); |
| 20966 | } |
| 20967 | |
| 20968 | return regex; |
| 20969 | } |
| 20970 | |
| 20971 | function isIdentifierName(token) { |
| 20972 | return token.type === Token.Identifier || |
| 20973 | token.type === Token.Keyword || |
| 20974 | token.type === Token.BooleanLiteral || |
| 20975 | token.type === Token.NullLiteral; |
| 20976 | } |
| 20977 | |
| 20978 | function advanceSlash() { |
| 20979 | var prevToken, |
| 20980 | checkToken; |
| 20981 | // Using the following algorithm: |
| 20982 | // https://github.com/mozilla/sweet.js/wiki/design |
| 20983 | prevToken = extra.tokens[extra.tokens.length - 1]; |
| 20984 | if (!prevToken) { |
| 20985 | // Nothing before that: it cannot be a division. |
| 20986 | return collectRegex(); |
| 20987 | } |
| 20988 | if (prevToken.type === 'Punctuator') { |
| 20989 | if (prevToken.value === ']') { |
| 20990 | return scanPunctuator(); |
| 20991 | } |
| 20992 | if (prevToken.value === ')') { |
| 20993 | checkToken = extra.tokens[extra.openParenToken - 1]; |
| 20994 | if (checkToken && |
| 20995 | checkToken.type === 'Keyword' && |
| 20996 | (checkToken.value === 'if' || |
| 20997 | checkToken.value === 'while' || |
| 20998 | checkToken.value === 'for' || |
| 20999 | checkToken.value === 'with')) { |
| 21000 | return collectRegex(); |
| 21001 | } |
| 21002 | return scanPunctuator(); |
| 21003 | } |
| 21004 | if (prevToken.value === '}') { |
| 21005 | // Dividing a function by anything makes little sense, |
| 21006 | // but we have to check for that. |
| 21007 | if (extra.tokens[extra.openCurlyToken - 3] && |
| 21008 | extra.tokens[extra.openCurlyToken - 3].type === 'Keyword') { |
| 21009 | // Anonymous function. |
| 21010 | checkToken = extra.tokens[extra.openCurlyToken - 4]; |
| 21011 | if (!checkToken) { |
| 21012 | return scanPunctuator(); |
| 21013 | } |
| 21014 | } else if (extra.tokens[extra.openCurlyToken - 4] && |
| 21015 | extra.tokens[extra.openCurlyToken - 4].type === 'Keyword') { |
| 21016 | // Named function. |
| 21017 | checkToken = extra.tokens[extra.openCurlyToken - 5]; |
| 21018 | if (!checkToken) { |
| 21019 | return collectRegex(); |
| 21020 | } |
| 21021 | } else { |
| 21022 | return scanPunctuator(); |
| 21023 | } |
| 21024 | // checkToken determines whether the function is |
| 21025 | // a declaration or an expression. |
| 21026 | if (FnExprTokens.indexOf(checkToken.value) >= 0) { |
| 21027 | // It is an expression. |
| 21028 | return scanPunctuator(); |
| 21029 | } |
| 21030 | // It is a declaration. |
| 21031 | return collectRegex(); |
| 21032 | } |
| 21033 | return collectRegex(); |
| 21034 | } |
| 21035 | if (prevToken.type === 'Keyword' && prevToken.value !== 'this') { |
| 21036 | return collectRegex(); |
| 21037 | } |
| 21038 | return scanPunctuator(); |
| 21039 | } |
| 21040 | |
| 21041 | function advance() { |
| 21042 | var ch, token; |
| 21043 | |
| 21044 | if (index >= length) { |
| 21045 | return { |
| 21046 | type: Token.EOF, |
| 21047 | lineNumber: lineNumber, |
| 21048 | lineStart: lineStart, |
| 21049 | start: index, |
| 21050 | end: index |
| 21051 | }; |
| 21052 | } |
| 21053 | |
| 21054 | ch = source.charCodeAt(index); |
| 21055 | |
| 21056 | if (isIdentifierStart(ch)) { |
| 21057 | token = scanIdentifier(); |
| 21058 | if (strict && isStrictModeReservedWord(token.value)) { |
| 21059 | token.type = Token.Keyword; |
| 21060 | } |
| 21061 | return token; |
| 21062 | } |
| 21063 | |
| 21064 | // Very common: ( and ) and ; |
| 21065 | if (ch === 0x28 || ch === 0x29 || ch === 0x3B) { |
| 21066 | return scanPunctuator(); |
| 21067 | } |
| 21068 | |
| 21069 | // String literal starts with single quote (U+0027) or double quote (U+0022). |
| 21070 | if (ch === 0x27 || ch === 0x22) { |
| 21071 | return scanStringLiteral(); |
| 21072 | } |
| 21073 | |
| 21074 | // Dot (.) U+002E can also start a floating-point number, hence the need |
| 21075 | // to check the next character. |
| 21076 | if (ch === 0x2E) { |
| 21077 | if (isDecimalDigit(source.charCodeAt(index + 1))) { |
| 21078 | return scanNumericLiteral(); |
| 21079 | } |
| 21080 | return scanPunctuator(); |
| 21081 | } |
| 21082 | |
| 21083 | if (isDecimalDigit(ch)) { |
| 21084 | return scanNumericLiteral(); |
| 21085 | } |
| 21086 | |
| 21087 | // Slash (/) U+002F can also start a regex. |
| 21088 | if (extra.tokenize && ch === 0x2F) { |
| 21089 | return advanceSlash(); |
| 21090 | } |
| 21091 | |
| 21092 | // Template literals start with ` (U+0060) for template head |
| 21093 | // or } (U+007D) for template middle or template tail. |
| 21094 | if (ch === 0x60 || (ch === 0x7D && state.curlyStack[state.curlyStack.length - 1] === '${')) { |
| 21095 | return scanTemplate(); |
| 21096 | } |
| 21097 | |
| 21098 | return scanPunctuator(); |
| 21099 | } |
| 21100 | |
| 21101 | function collectToken() { |
| 21102 | var loc, token, value, entry; |
| 21103 | |
| 21104 | loc = { |
| 21105 | start: { |
| 21106 | line: lineNumber, |
| 21107 | column: index - lineStart |
| 21108 | } |
| 21109 | }; |
| 21110 | |
| 21111 | token = advance(); |
| 21112 | loc.end = { |
| 21113 | line: lineNumber, |
| 21114 | column: index - lineStart |
| 21115 | }; |
| 21116 | |
| 21117 | if (token.type !== Token.EOF) { |
| 21118 | value = source.slice(token.start, token.end); |
| 21119 | entry = { |
| 21120 | type: TokenName[token.type], |
| 21121 | value: value, |
| 21122 | range: [token.start, token.end], |
| 21123 | loc: loc |
| 21124 | }; |
| 21125 | if (token.regex) { |
| 21126 | entry.regex = { |
| 21127 | pattern: token.regex.pattern, |
| 21128 | flags: token.regex.flags |
| 21129 | }; |
| 21130 | } |
| 21131 | extra.tokens.push(entry); |
| 21132 | } |
| 21133 | |
| 21134 | return token; |
| 21135 | } |
| 21136 | |
| 21137 | function lex() { |
| 21138 | var token; |
| 21139 | scanning = true; |
| 21140 | |
| 21141 | lastIndex = index; |
| 21142 | lastLineNumber = lineNumber; |
| 21143 | lastLineStart = lineStart; |
| 21144 | |
| 21145 | skipComment(); |
| 21146 | |
| 21147 | token = lookahead; |
| 21148 | |
| 21149 | startIndex = index; |
| 21150 | startLineNumber = lineNumber; |
| 21151 | startLineStart = lineStart; |
| 21152 | |
| 21153 | lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance(); |
| 21154 | scanning = false; |
| 21155 | return token; |
| 21156 | } |
| 21157 | |
| 21158 | function peek() { |
| 21159 | scanning = true; |
| 21160 | |
| 21161 | skipComment(); |
| 21162 | |
| 21163 | lastIndex = index; |
| 21164 | lastLineNumber = lineNumber; |
| 21165 | lastLineStart = lineStart; |
| 21166 | |
| 21167 | startIndex = index; |
| 21168 | startLineNumber = lineNumber; |
| 21169 | startLineStart = lineStart; |
| 21170 | |
| 21171 | lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance(); |
| 21172 | scanning = false; |
| 21173 | } |
| 21174 | |
| 21175 | function Position() { |
| 21176 | this.line = startLineNumber; |
| 21177 | this.column = startIndex - startLineStart; |
| 21178 | } |
| 21179 | |
| 21180 | function SourceLocation() { |
| 21181 | this.start = new Position(); |
| 21182 | this.end = null; |
| 21183 | } |
| 21184 | |
| 21185 | function WrappingSourceLocation(startToken) { |
| 21186 | this.start = { |
| 21187 | line: startToken.lineNumber, |
| 21188 | column: startToken.start - startToken.lineStart |
| 21189 | }; |
| 21190 | this.end = null; |
| 21191 | } |
| 21192 | |
| 21193 | function Node() { |
| 21194 | if (extra.range) { |
| 21195 | this.range = [startIndex, 0]; |
| 21196 | } |
| 21197 | if (extra.loc) { |
| 21198 | this.loc = new SourceLocation(); |
| 21199 | } |
| 21200 | } |
| 21201 | |
| 21202 | function WrappingNode(startToken) { |
| 21203 | if (extra.range) { |
| 21204 | this.range = [startToken.start, 0]; |
| 21205 | } |
| 21206 | if (extra.loc) { |
| 21207 | this.loc = new WrappingSourceLocation(startToken); |
| 21208 | } |
| 21209 | } |
| 21210 | |
| 21211 | WrappingNode.prototype = Node.prototype = { |
| 21212 | |
| 21213 | processComment: function () { |
| 21214 | var lastChild, |
| 21215 | leadingComments, |
| 21216 | trailingComments, |
| 21217 | bottomRight = extra.bottomRightStack, |
| 21218 | i, |
| 21219 | comment, |
| 21220 | last = bottomRight[bottomRight.length - 1]; |
| 21221 | |
| 21222 | if (this.type === Syntax.Program) { |
| 21223 | if (this.body.length > 0) { |
| 21224 | return; |
| 21225 | } |
| 21226 | } |
| 21227 | |
| 21228 | if (extra.trailingComments.length > 0) { |
| 21229 | trailingComments = []; |
| 21230 | for (i = extra.trailingComments.length - 1; i >= 0; --i) { |
| 21231 | comment = extra.trailingComments[i]; |
| 21232 | if (comment.range[0] >= this.range[1]) { |
| 21233 | trailingComments.unshift(comment); |
| 21234 | extra.trailingComments.splice(i, 1); |
| 21235 | } |
| 21236 | } |
| 21237 | extra.trailingComments = []; |
| 21238 | } else { |
| 21239 | if (last && last.trailingComments && last.trailingComments[0].range[0] >= this.range[1]) { |
| 21240 | trailingComments = last.trailingComments; |
| 21241 | delete last.trailingComments; |
| 21242 | } |
| 21243 | } |
| 21244 | |
| 21245 | // Eating the stack. |
| 21246 | if (last) { |
| 21247 | while (last && last.range[0] >= this.range[0]) { |
| 21248 | lastChild = last; |
| 21249 | last = bottomRight.pop(); |
| 21250 | } |
| 21251 | } |
| 21252 | |
| 21253 | if (lastChild) { |
| 21254 | if (lastChild.leadingComments && lastChild.leadingComments[lastChild.leadingComments.length - 1].range[1] <= this.range[0]) { |
| 21255 | this.leadingComments = lastChild.leadingComments; |
| 21256 | lastChild.leadingComments = undefined; |
| 21257 | } |
| 21258 | } else if (extra.leadingComments.length > 0) { |
| 21259 | leadingComments = []; |
| 21260 | for (i = extra.leadingComments.length - 1; i >= 0; --i) { |
| 21261 | comment = extra.leadingComments[i]; |
| 21262 | if (comment.range[1] <= this.range[0]) { |
| 21263 | leadingComments.unshift(comment); |
| 21264 | extra.leadingComments.splice(i, 1); |
| 21265 | } |
| 21266 | } |
| 21267 | } |
| 21268 | |
| 21269 | |
| 21270 | if (leadingComments && leadingComments.length > 0) { |
| 21271 | this.leadingComments = leadingComments; |
| 21272 | } |
| 21273 | if (trailingComments && trailingComments.length > 0) { |
| 21274 | this.trailingComments = trailingComments; |
| 21275 | } |
| 21276 | |
| 21277 | bottomRight.push(this); |
| 21278 | }, |
| 21279 | |
| 21280 | finish: function () { |
| 21281 | if (extra.range) { |
| 21282 | this.range[1] = lastIndex; |
| 21283 | } |
| 21284 | if (extra.loc) { |
| 21285 | this.loc.end = { |
| 21286 | line: lastLineNumber, |
| 21287 | column: lastIndex - lastLineStart |
| 21288 | }; |
| 21289 | if (extra.source) { |
| 21290 | this.loc.source = extra.source; |
| 21291 | } |
| 21292 | } |
| 21293 | |
| 21294 | if (extra.attachComment) { |
| 21295 | this.processComment(); |
| 21296 | } |
| 21297 | }, |
| 21298 | |
| 21299 | finishArrayExpression: function (elements) { |
| 21300 | this.type = Syntax.ArrayExpression; |
| 21301 | this.elements = elements; |
| 21302 | this.finish(); |
| 21303 | return this; |
| 21304 | }, |
| 21305 | |
| 21306 | finishArrayPattern: function (elements) { |
| 21307 | this.type = Syntax.ArrayPattern; |
| 21308 | this.elements = elements; |
| 21309 | this.finish(); |
| 21310 | return this; |
| 21311 | }, |
| 21312 | |
| 21313 | finishArrowFunctionExpression: function (params, defaults, body, expression) { |
| 21314 | this.type = Syntax.ArrowFunctionExpression; |
| 21315 | this.id = null; |
| 21316 | this.params = params; |
| 21317 | this.defaults = defaults; |
| 21318 | this.body = body; |
| 21319 | this.generator = false; |
| 21320 | this.expression = expression; |
| 21321 | this.finish(); |
| 21322 | return this; |
| 21323 | }, |
| 21324 | |
| 21325 | finishAssignmentExpression: function (operator, left, right) { |
| 21326 | this.type = Syntax.AssignmentExpression; |
| 21327 | this.operator = operator; |
| 21328 | this.left = left; |
| 21329 | this.right = right; |
| 21330 | this.finish(); |
| 21331 | return this; |
| 21332 | }, |
| 21333 | |
| 21334 | finishAssignmentPattern: function (left, right) { |
| 21335 | this.type = Syntax.AssignmentPattern; |
| 21336 | this.left = left; |
| 21337 | this.right = right; |
| 21338 | this.finish(); |
| 21339 | return this; |
| 21340 | }, |
| 21341 | |
| 21342 | finishBinaryExpression: function (operator, left, right) { |
| 21343 | this.type = (operator === '||' || operator === '&&') ? Syntax.LogicalExpression : Syntax.BinaryExpression; |
| 21344 | this.operator = operator; |
| 21345 | this.left = left; |
| 21346 | this.right = right; |
| 21347 | this.finish(); |
| 21348 | return this; |
| 21349 | }, |
| 21350 | |
| 21351 | finishBlockStatement: function (body) { |
| 21352 | this.type = Syntax.BlockStatement; |
| 21353 | this.body = body; |
| 21354 | this.finish(); |
| 21355 | return this; |
| 21356 | }, |
| 21357 | |
| 21358 | finishBreakStatement: function (label) { |
| 21359 | this.type = Syntax.BreakStatement; |
| 21360 | this.label = label; |
| 21361 | this.finish(); |
| 21362 | return this; |
| 21363 | }, |
| 21364 | |
| 21365 | finishCallExpression: function (callee, args) { |
| 21366 | this.type = Syntax.CallExpression; |
| 21367 | this.callee = callee; |
| 21368 | this.arguments = args; |
| 21369 | this.finish(); |
| 21370 | return this; |
| 21371 | }, |
| 21372 | |
| 21373 | finishCatchClause: function (param, body) { |
| 21374 | this.type = Syntax.CatchClause; |
| 21375 | this.param = param; |
| 21376 | this.body = body; |
| 21377 | this.finish(); |
| 21378 | return this; |
| 21379 | }, |
| 21380 | |
| 21381 | finishClassBody: function (body) { |
| 21382 | this.type = Syntax.ClassBody; |
| 21383 | this.body = body; |
| 21384 | this.finish(); |
| 21385 | return this; |
| 21386 | }, |
| 21387 | |
| 21388 | finishClassDeclaration: function (id, superClass, body) { |
| 21389 | this.type = Syntax.ClassDeclaration; |
| 21390 | this.id = id; |
| 21391 | this.superClass = superClass; |
| 21392 | this.body = body; |
| 21393 | this.finish(); |
| 21394 | return this; |
| 21395 | }, |
| 21396 | |
| 21397 | finishClassExpression: function (id, superClass, body) { |
| 21398 | this.type = Syntax.ClassExpression; |
| 21399 | this.id = id; |
| 21400 | this.superClass = superClass; |
| 21401 | this.body = body; |
| 21402 | this.finish(); |
| 21403 | return this; |
| 21404 | }, |
| 21405 | |
| 21406 | finishConditionalExpression: function (test, consequent, alternate) { |
| 21407 | this.type = Syntax.ConditionalExpression; |
| 21408 | this.test = test; |
| 21409 | this.consequent = consequent; |
| 21410 | this.alternate = alternate; |
| 21411 | this.finish(); |
| 21412 | return this; |
| 21413 | }, |
| 21414 | |
| 21415 | finishContinueStatement: function (label) { |
| 21416 | this.type = Syntax.ContinueStatement; |
| 21417 | this.label = label; |
| 21418 | this.finish(); |
| 21419 | return this; |
| 21420 | }, |
| 21421 | |
| 21422 | finishDebuggerStatement: function () { |
| 21423 | this.type = Syntax.DebuggerStatement; |
| 21424 | this.finish(); |
| 21425 | return this; |
| 21426 | }, |
| 21427 | |
| 21428 | finishDoWhileStatement: function (body, test) { |
| 21429 | this.type = Syntax.DoWhileStatement; |
| 21430 | this.body = body; |
| 21431 | this.test = test; |
| 21432 | this.finish(); |
| 21433 | return this; |
| 21434 | }, |
| 21435 | |
| 21436 | finishEmptyStatement: function () { |
| 21437 | this.type = Syntax.EmptyStatement; |
| 21438 | this.finish(); |
| 21439 | return this; |
| 21440 | }, |
| 21441 | |
| 21442 | finishExpressionStatement: function (expression) { |
| 21443 | this.type = Syntax.ExpressionStatement; |
| 21444 | this.expression = expression; |
| 21445 | this.finish(); |
| 21446 | return this; |
| 21447 | }, |
| 21448 | |
| 21449 | finishForStatement: function (init, test, update, body) { |
| 21450 | this.type = Syntax.ForStatement; |
| 21451 | this.init = init; |
| 21452 | this.test = test; |
| 21453 | this.update = update; |
| 21454 | this.body = body; |
| 21455 | this.finish(); |
| 21456 | return this; |
| 21457 | }, |
| 21458 | |
| 21459 | finishForInStatement: function (left, right, body) { |
| 21460 | this.type = Syntax.ForInStatement; |
| 21461 | this.left = left; |
| 21462 | this.right = right; |
| 21463 | this.body = body; |
| 21464 | this.each = false; |
| 21465 | this.finish(); |
| 21466 | return this; |
| 21467 | }, |
| 21468 | |
| 21469 | finishFunctionDeclaration: function (id, params, defaults, body) { |
| 21470 | this.type = Syntax.FunctionDeclaration; |
| 21471 | this.id = id; |
| 21472 | this.params = params; |
| 21473 | this.defaults = defaults; |
| 21474 | this.body = body; |
| 21475 | this.generator = false; |
| 21476 | this.expression = false; |
| 21477 | this.finish(); |
| 21478 | return this; |
| 21479 | }, |
| 21480 | |
| 21481 | finishFunctionExpression: function (id, params, defaults, body) { |
| 21482 | this.type = Syntax.FunctionExpression; |
| 21483 | this.id = id; |
| 21484 | this.params = params; |
| 21485 | this.defaults = defaults; |
| 21486 | this.body = body; |
| 21487 | this.generator = false; |
| 21488 | this.expression = false; |
| 21489 | this.finish(); |
| 21490 | return this; |
| 21491 | }, |
| 21492 | |
| 21493 | finishIdentifier: function (name) { |
| 21494 | this.type = Syntax.Identifier; |
| 21495 | this.name = name; |
| 21496 | this.finish(); |
| 21497 | return this; |
| 21498 | }, |
| 21499 | |
| 21500 | finishIfStatement: function (test, consequent, alternate) { |
| 21501 | this.type = Syntax.IfStatement; |
| 21502 | this.test = test; |
| 21503 | this.consequent = consequent; |
| 21504 | this.alternate = alternate; |
| 21505 | this.finish(); |
| 21506 | return this; |
| 21507 | }, |
| 21508 | |
| 21509 | finishLabeledStatement: function (label, body) { |
| 21510 | this.type = Syntax.LabeledStatement; |
| 21511 | this.label = label; |
| 21512 | this.body = body; |
| 21513 | this.finish(); |
| 21514 | return this; |
| 21515 | }, |
| 21516 | |
| 21517 | finishLiteral: function (token) { |
| 21518 | this.type = Syntax.Literal; |
| 21519 | this.value = token.value; |
| 21520 | this.raw = source.slice(token.start, token.end); |
| 21521 | if (token.regex) { |
| 21522 | this.regex = token.regex; |
| 21523 | } |
| 21524 | this.finish(); |
| 21525 | return this; |
| 21526 | }, |
| 21527 | |
| 21528 | finishMemberExpression: function (accessor, object, property) { |
| 21529 | this.type = Syntax.MemberExpression; |
| 21530 | this.computed = accessor === '['; |
| 21531 | this.object = object; |
| 21532 | this.property = property; |
| 21533 | this.finish(); |
| 21534 | return this; |
| 21535 | }, |
| 21536 | |
| 21537 | finishNewExpression: function (callee, args) { |
| 21538 | this.type = Syntax.NewExpression; |
| 21539 | this.callee = callee; |
| 21540 | this.arguments = args; |
| 21541 | this.finish(); |
| 21542 | return this; |
| 21543 | }, |
| 21544 | |
| 21545 | finishObjectExpression: function (properties) { |
| 21546 | this.type = Syntax.ObjectExpression; |
| 21547 | this.properties = properties; |
| 21548 | this.finish(); |
| 21549 | return this; |
| 21550 | }, |
| 21551 | |
| 21552 | finishObjectPattern: function (properties) { |
| 21553 | this.type = Syntax.ObjectPattern; |
| 21554 | this.properties = properties; |
| 21555 | this.finish(); |
| 21556 | return this; |
| 21557 | }, |
| 21558 | |
| 21559 | finishPostfixExpression: function (operator, argument) { |
| 21560 | this.type = Syntax.UpdateExpression; |
| 21561 | this.operator = operator; |
| 21562 | this.argument = argument; |
| 21563 | this.prefix = false; |
| 21564 | this.finish(); |
| 21565 | return this; |
| 21566 | }, |
| 21567 | |
| 21568 | finishProgram: function (body) { |
| 21569 | this.type = Syntax.Program; |
| 21570 | this.body = body; |
| 21571 | if (sourceType === 'module') { |
| 21572 | // very restrictive for now |
| 21573 | this.sourceType = sourceType; |
| 21574 | } |
| 21575 | this.finish(); |
| 21576 | return this; |
| 21577 | }, |
| 21578 | |
| 21579 | finishProperty: function (kind, key, computed, value, method, shorthand) { |
| 21580 | this.type = Syntax.Property; |
| 21581 | this.key = key; |
| 21582 | this.computed = computed; |
| 21583 | this.value = value; |
| 21584 | this.kind = kind; |
| 21585 | this.method = method; |
| 21586 | this.shorthand = shorthand; |
| 21587 | this.finish(); |
| 21588 | return this; |
| 21589 | }, |
| 21590 | |
| 21591 | finishRestElement: function (argument) { |
| 21592 | this.type = Syntax.RestElement; |
| 21593 | this.argument = argument; |
| 21594 | this.finish(); |
| 21595 | return this; |
| 21596 | }, |
| 21597 | |
| 21598 | finishReturnStatement: function (argument) { |
| 21599 | this.type = Syntax.ReturnStatement; |
| 21600 | this.argument = argument; |
| 21601 | this.finish(); |
| 21602 | return this; |
| 21603 | }, |
| 21604 | |
| 21605 | finishSequenceExpression: function (expressions) { |
| 21606 | this.type = Syntax.SequenceExpression; |
| 21607 | this.expressions = expressions; |
| 21608 | this.finish(); |
| 21609 | return this; |
| 21610 | }, |
| 21611 | |
| 21612 | finishSpreadElement: function (argument) { |
| 21613 | this.type = Syntax.SpreadElement; |
| 21614 | this.argument = argument; |
| 21615 | this.finish(); |
| 21616 | return this; |
| 21617 | }, |
| 21618 | |
| 21619 | finishSwitchCase: function (test, consequent) { |
| 21620 | this.type = Syntax.SwitchCase; |
| 21621 | this.test = test; |
| 21622 | this.consequent = consequent; |
| 21623 | this.finish(); |
| 21624 | return this; |
| 21625 | }, |
| 21626 | |
| 21627 | finishSuper: function () { |
| 21628 | this.type = Syntax.Super; |
| 21629 | this.finish(); |
| 21630 | return this; |
| 21631 | }, |
| 21632 | |
| 21633 | finishSwitchStatement: function (discriminant, cases) { |
| 21634 | this.type = Syntax.SwitchStatement; |
| 21635 | this.discriminant = discriminant; |
| 21636 | this.cases = cases; |
| 21637 | this.finish(); |
| 21638 | return this; |
| 21639 | }, |
| 21640 | |
| 21641 | finishTaggedTemplateExpression: function (tag, quasi) { |
| 21642 | this.type = Syntax.TaggedTemplateExpression; |
| 21643 | this.tag = tag; |
| 21644 | this.quasi = quasi; |
| 21645 | this.finish(); |
| 21646 | return this; |
| 21647 | }, |
| 21648 | |
| 21649 | finishTemplateElement: function (value, tail) { |
| 21650 | this.type = Syntax.TemplateElement; |
| 21651 | this.value = value; |
| 21652 | this.tail = tail; |
| 21653 | this.finish(); |
| 21654 | return this; |
| 21655 | }, |
| 21656 | |
| 21657 | finishTemplateLiteral: function (quasis, expressions) { |
| 21658 | this.type = Syntax.TemplateLiteral; |
| 21659 | this.quasis = quasis; |
| 21660 | this.expressions = expressions; |
| 21661 | this.finish(); |
| 21662 | return this; |
| 21663 | }, |
| 21664 | |
| 21665 | finishThisExpression: function () { |
| 21666 | this.type = Syntax.ThisExpression; |
| 21667 | this.finish(); |
| 21668 | return this; |
| 21669 | }, |
| 21670 | |
| 21671 | finishThrowStatement: function (argument) { |
| 21672 | this.type = Syntax.ThrowStatement; |
| 21673 | this.argument = argument; |
| 21674 | this.finish(); |
| 21675 | return this; |
| 21676 | }, |
| 21677 | |
| 21678 | finishTryStatement: function (block, handler, finalizer) { |
| 21679 | this.type = Syntax.TryStatement; |
| 21680 | this.block = block; |
| 21681 | this.guardedHandlers = []; |
| 21682 | this.handlers = handler ? [ handler ] : []; |
| 21683 | this.handler = handler; |
| 21684 | this.finalizer = finalizer; |
| 21685 | this.finish(); |
| 21686 | return this; |
| 21687 | }, |
| 21688 | |
| 21689 | finishUnaryExpression: function (operator, argument) { |
| 21690 | this.type = (operator === '++' || operator === '--') ? Syntax.UpdateExpression : Syntax.UnaryExpression; |
| 21691 | this.operator = operator; |
| 21692 | this.argument = argument; |
| 21693 | this.prefix = true; |
| 21694 | this.finish(); |
| 21695 | return this; |
| 21696 | }, |
| 21697 | |
| 21698 | finishVariableDeclaration: function (declarations) { |
| 21699 | this.type = Syntax.VariableDeclaration; |
| 21700 | this.declarations = declarations; |
| 21701 | this.kind = 'var'; |
| 21702 | this.finish(); |
| 21703 | return this; |
| 21704 | }, |
| 21705 | |
| 21706 | finishLexicalDeclaration: function (declarations, kind) { |
| 21707 | this.type = Syntax.VariableDeclaration; |
| 21708 | this.declarations = declarations; |
| 21709 | this.kind = kind; |
| 21710 | this.finish(); |
| 21711 | return this; |
| 21712 | }, |
| 21713 | |
| 21714 | finishVariableDeclarator: function (id, init) { |
| 21715 | this.type = Syntax.VariableDeclarator; |
| 21716 | this.id = id; |
| 21717 | this.init = init; |
| 21718 | this.finish(); |
| 21719 | return this; |
| 21720 | }, |
| 21721 | |
| 21722 | finishWhileStatement: function (test, body) { |
| 21723 | this.type = Syntax.WhileStatement; |
| 21724 | this.test = test; |
| 21725 | this.body = body; |
| 21726 | this.finish(); |
| 21727 | return this; |
| 21728 | }, |
| 21729 | |
| 21730 | finishWithStatement: function (object, body) { |
| 21731 | this.type = Syntax.WithStatement; |
| 21732 | this.object = object; |
| 21733 | this.body = body; |
| 21734 | this.finish(); |
| 21735 | return this; |
| 21736 | }, |
| 21737 | |
| 21738 | finishExportSpecifier: function (local, exported) { |
| 21739 | this.type = Syntax.ExportSpecifier; |
| 21740 | this.exported = exported || local; |
| 21741 | this.local = local; |
| 21742 | this.finish(); |
| 21743 | return this; |
| 21744 | }, |
| 21745 | |
| 21746 | finishImportDefaultSpecifier: function (local) { |
| 21747 | this.type = Syntax.ImportDefaultSpecifier; |
| 21748 | this.local = local; |
| 21749 | this.finish(); |
| 21750 | return this; |
| 21751 | }, |
| 21752 | |
| 21753 | finishImportNamespaceSpecifier: function (local) { |
| 21754 | this.type = Syntax.ImportNamespaceSpecifier; |
| 21755 | this.local = local; |
| 21756 | this.finish(); |
| 21757 | return this; |
| 21758 | }, |
| 21759 | |
| 21760 | finishExportNamedDeclaration: function (declaration, specifiers, src) { |
| 21761 | this.type = Syntax.ExportNamedDeclaration; |
| 21762 | this.declaration = declaration; |
| 21763 | this.specifiers = specifiers; |
| 21764 | this.source = src; |
| 21765 | this.finish(); |
| 21766 | return this; |
| 21767 | }, |
| 21768 | |
| 21769 | finishExportDefaultDeclaration: function (declaration) { |
| 21770 | this.type = Syntax.ExportDefaultDeclaration; |
| 21771 | this.declaration = declaration; |
| 21772 | this.finish(); |
| 21773 | return this; |
| 21774 | }, |
| 21775 | |
| 21776 | finishExportAllDeclaration: function (src) { |
| 21777 | this.type = Syntax.ExportAllDeclaration; |
| 21778 | this.source = src; |
| 21779 | this.finish(); |
| 21780 | return this; |
| 21781 | }, |
| 21782 | |
| 21783 | finishImportSpecifier: function (local, imported) { |
| 21784 | this.type = Syntax.ImportSpecifier; |
| 21785 | this.local = local || imported; |
| 21786 | this.imported = imported; |
| 21787 | this.finish(); |
| 21788 | return this; |
| 21789 | }, |
| 21790 | |
| 21791 | finishImportDeclaration: function (specifiers, src) { |
| 21792 | this.type = Syntax.ImportDeclaration; |
| 21793 | this.specifiers = specifiers; |
| 21794 | this.source = src; |
| 21795 | this.finish(); |
| 21796 | return this; |
| 21797 | } |
| 21798 | }; |
| 21799 | |
| 21800 | |
| 21801 | function recordError(error) { |
| 21802 | var e, existing; |
| 21803 | |
| 21804 | for (e = 0; e < extra.errors.length; e++) { |
| 21805 | existing = extra.errors[e]; |
| 21806 | // Prevent duplicated error. |
| 21807 | /* istanbul ignore next */ |
| 21808 | if (existing.index === error.index && existing.message === error.message) { |
| 21809 | return; |
| 21810 | } |
| 21811 | } |
| 21812 | |
| 21813 | extra.errors.push(error); |
| 21814 | } |
| 21815 | |
| 21816 | function createError(line, pos, description) { |
| 21817 | var error = new Error('Line ' + line + ': ' + description); |
| 21818 | error.index = pos; |
| 21819 | error.lineNumber = line; |
| 21820 | error.column = pos - (scanning ? lineStart : lastLineStart) + 1; |
| 21821 | error.description = description; |
| 21822 | return error; |
| 21823 | } |
| 21824 | |
| 21825 | // Throw an exception |
| 21826 | |
| 21827 | function throwError(messageFormat) { |
| 21828 | var args, msg; |
| 21829 | |
| 21830 | args = Array.prototype.slice.call(arguments, 1); |
| 21831 | msg = messageFormat.replace(/%(\d)/g, |
| 21832 | function (whole, idx) { |
| 21833 | assert(idx < args.length, 'Message reference must be in range'); |
| 21834 | return args[idx]; |
| 21835 | } |
| 21836 | ); |
| 21837 | |
| 21838 | throw createError(lastLineNumber, lastIndex, msg); |
| 21839 | } |
| 21840 | |
| 21841 | function tolerateError(messageFormat) { |
| 21842 | var args, msg, error; |
| 21843 | |
| 21844 | args = Array.prototype.slice.call(arguments, 1); |
| 21845 | /* istanbul ignore next */ |
| 21846 | msg = messageFormat.replace(/%(\d)/g, |
| 21847 | function (whole, idx) { |
| 21848 | assert(idx < args.length, 'Message reference must be in range'); |
| 21849 | return args[idx]; |
| 21850 | } |
| 21851 | ); |
| 21852 | |
| 21853 | error = createError(lineNumber, lastIndex, msg); |
| 21854 | if (extra.errors) { |
| 21855 | recordError(error); |
| 21856 | } else { |
| 21857 | throw error; |
| 21858 | } |
| 21859 | } |
| 21860 | |
| 21861 | // Throw an exception because of the token. |
| 21862 | |
| 21863 | function unexpectedTokenError(token, message) { |
| 21864 | var value, msg = message || Messages.UnexpectedToken; |
| 21865 | |
| 21866 | if (token) { |
| 21867 | if (!message) { |
| 21868 | msg = (token.type === Token.EOF) ? Messages.UnexpectedEOS : |
| 21869 | (token.type === Token.Identifier) ? Messages.UnexpectedIdentifier : |
| 21870 | (token.type === Token.NumericLiteral) ? Messages.UnexpectedNumber : |
| 21871 | (token.type === Token.StringLiteral) ? Messages.UnexpectedString : |
| 21872 | (token.type === Token.Template) ? Messages.UnexpectedTemplate : |
| 21873 | Messages.UnexpectedToken; |
| 21874 | |
| 21875 | if (token.type === Token.Keyword) { |
| 21876 | if (isFutureReservedWord(token.value)) { |
| 21877 | msg = Messages.UnexpectedReserved; |
| 21878 | } else if (strict && isStrictModeReservedWord(token.value)) { |
| 21879 | msg = Messages.StrictReservedWord; |
| 21880 | } |
| 21881 | } |
| 21882 | } |
| 21883 | |
| 21884 | value = (token.type === Token.Template) ? token.value.raw : token.value; |
| 21885 | } else { |
| 21886 | value = 'ILLEGAL'; |
| 21887 | } |
| 21888 | |
| 21889 | msg = msg.replace('%0', value); |
| 21890 | |
| 21891 | return (token && typeof token.lineNumber === 'number') ? |
| 21892 | createError(token.lineNumber, token.start, msg) : |
| 21893 | createError(scanning ? lineNumber : lastLineNumber, scanning ? index : lastIndex, msg); |
| 21894 | } |
| 21895 | |
| 21896 | function throwUnexpectedToken(token, message) { |
| 21897 | throw unexpectedTokenError(token, message); |
| 21898 | } |
| 21899 | |
| 21900 | function tolerateUnexpectedToken(token, message) { |
| 21901 | var error = unexpectedTokenError(token, message); |
| 21902 | if (extra.errors) { |
| 21903 | recordError(error); |
| 21904 | } else { |
| 21905 | throw error; |
| 21906 | } |
| 21907 | } |
| 21908 | |
| 21909 | // Expect the next token to match the specified punctuator. |
| 21910 | // If not, an exception will be thrown. |
| 21911 | |
| 21912 | function expect(value) { |
| 21913 | var token = lex(); |
| 21914 | if (token.type !== Token.Punctuator || token.value !== value) { |
| 21915 | throwUnexpectedToken(token); |
| 21916 | } |
| 21917 | } |
| 21918 | |
| 21919 | /** |
| 21920 | * @name expectCommaSeparator |
| 21921 | * @description Quietly expect a comma when in tolerant mode, otherwise delegates |
| 21922 | * to <code>expect(value)</code> |
| 21923 | * @since 2.0 |
| 21924 | */ |
| 21925 | function expectCommaSeparator() { |
| 21926 | var token; |
| 21927 | |
| 21928 | if (extra.errors) { |
| 21929 | token = lookahead; |
| 21930 | if (token.type === Token.Punctuator && token.value === ',') { |
| 21931 | lex(); |
| 21932 | } else if (token.type === Token.Punctuator && token.value === ';') { |
| 21933 | lex(); |
| 21934 | tolerateUnexpectedToken(token); |
| 21935 | } else { |
| 21936 | tolerateUnexpectedToken(token, Messages.UnexpectedToken); |
| 21937 | } |
| 21938 | } else { |
| 21939 | expect(','); |
| 21940 | } |
| 21941 | } |
| 21942 | |
| 21943 | // Expect the next token to match the specified keyword. |
| 21944 | // If not, an exception will be thrown. |
| 21945 | |
| 21946 | function expectKeyword(keyword) { |
| 21947 | var token = lex(); |
| 21948 | if (token.type !== Token.Keyword || token.value !== keyword) { |
| 21949 | throwUnexpectedToken(token); |
| 21950 | } |
| 21951 | } |
| 21952 | |
| 21953 | // Return true if the next token matches the specified punctuator. |
| 21954 | |
| 21955 | function match(value) { |
| 21956 | return lookahead.type === Token.Punctuator && lookahead.value === value; |
| 21957 | } |
| 21958 | |
| 21959 | // Return true if the next token matches the specified keyword |
| 21960 | |
| 21961 | function matchKeyword(keyword) { |
| 21962 | return lookahead.type === Token.Keyword && lookahead.value === keyword; |
| 21963 | } |
| 21964 | |
| 21965 | // Return true if the next token matches the specified contextual keyword |
| 21966 | // (where an identifier is sometimes a keyword depending on the context) |
| 21967 | |
| 21968 | function matchContextualKeyword(keyword) { |
| 21969 | return lookahead.type === Token.Identifier && lookahead.value === keyword; |
| 21970 | } |
| 21971 | |
| 21972 | // Return true if the next token is an assignment operator |
| 21973 | |
| 21974 | function matchAssign() { |
| 21975 | var op; |
| 21976 | |
| 21977 | if (lookahead.type !== Token.Punctuator) { |
| 21978 | return false; |
| 21979 | } |
| 21980 | op = lookahead.value; |
| 21981 | return op === '=' || |
| 21982 | op === '*=' || |
| 21983 | op === '/=' || |
| 21984 | op === '%=' || |
| 21985 | op === '+=' || |
| 21986 | op === '-=' || |
| 21987 | op === '<<=' || |
| 21988 | op === '>>=' || |
| 21989 | op === '>>>=' || |
| 21990 | op === '&=' || |
| 21991 | op === '^=' || |
| 21992 | op === '|='; |
| 21993 | } |
| 21994 | |
| 21995 | function consumeSemicolon() { |
| 21996 | // Catch the very common case first: immediately a semicolon (U+003B). |
| 21997 | if (source.charCodeAt(startIndex) === 0x3B || match(';')) { |
| 21998 | lex(); |
| 21999 | return; |
| 22000 | } |
| 22001 | |
| 22002 | if (hasLineTerminator) { |
| 22003 | return; |
| 22004 | } |
| 22005 | |
| 22006 | // FIXME(ikarienator): this is seemingly an issue in the previous location info convention. |
| 22007 | lastIndex = startIndex; |
| 22008 | lastLineNumber = startLineNumber; |
| 22009 | lastLineStart = startLineStart; |
| 22010 | |
| 22011 | if (lookahead.type !== Token.EOF && !match('}')) { |
| 22012 | throwUnexpectedToken(lookahead); |
| 22013 | } |
| 22014 | } |
| 22015 | |
| 22016 | // Cover grammar support. |
| 22017 | // |
| 22018 | // When an assignment expression position starts with an left parenthesis, the determination of the type |
| 22019 | // of the syntax is to be deferred arbitrarily long until the end of the parentheses pair (plus a lookahead) |
| 22020 | // or the first comma. This situation also defers the determination of all the expressions nested in the pair. |
| 22021 | // |
| 22022 | // There are three productions that can be parsed in a parentheses pair that needs to be determined |
| 22023 | // after the outermost pair is closed. They are: |
| 22024 | // |
| 22025 | // 1. AssignmentExpression |
| 22026 | // 2. BindingElements |
| 22027 | // 3. AssignmentTargets |
| 22028 | // |
| 22029 | // In order to avoid exponential backtracking, we use two flags to denote if the production can be |
| 22030 | // binding element or assignment target. |
| 22031 | // |
| 22032 | // The three productions have the relationship: |
| 22033 | // |
| 22034 | // BindingElements ⊆ AssignmentTargets ⊆ AssignmentExpression |
| 22035 | // |
| 22036 | // with a single exception that CoverInitializedName when used directly in an Expression, generates |
| 22037 | // an early error. Therefore, we need the third state, firstCoverInitializedNameError, to track the |
| 22038 | // first usage of CoverInitializedName and report it when we reached the end of the parentheses pair. |
| 22039 | // |
| 22040 | // isolateCoverGrammar function runs the given parser function with a new cover grammar context, and it does not |
| 22041 | // effect the current flags. This means the production the parser parses is only used as an expression. Therefore |
| 22042 | // the CoverInitializedName check is conducted. |
| 22043 | // |
| 22044 | // inheritCoverGrammar function runs the given parse function with a new cover grammar context, and it propagates |
| 22045 | // the flags outside of the parser. This means the production the parser parses is used as a part of a potential |
| 22046 | // pattern. The CoverInitializedName check is deferred. |
| 22047 | function isolateCoverGrammar(parser) { |
| 22048 | var oldIsBindingElement = isBindingElement, |
| 22049 | oldIsAssignmentTarget = isAssignmentTarget, |
| 22050 | oldFirstCoverInitializedNameError = firstCoverInitializedNameError, |
| 22051 | result; |
| 22052 | isBindingElement = true; |
| 22053 | isAssignmentTarget = true; |
| 22054 | firstCoverInitializedNameError = null; |
| 22055 | result = parser(); |
| 22056 | if (firstCoverInitializedNameError !== null) { |
| 22057 | throwUnexpectedToken(firstCoverInitializedNameError); |
| 22058 | } |
| 22059 | isBindingElement = oldIsBindingElement; |
| 22060 | isAssignmentTarget = oldIsAssignmentTarget; |
| 22061 | firstCoverInitializedNameError = oldFirstCoverInitializedNameError; |
| 22062 | return result; |
| 22063 | } |
| 22064 | |
| 22065 | function inheritCoverGrammar(parser) { |
| 22066 | var oldIsBindingElement = isBindingElement, |
| 22067 | oldIsAssignmentTarget = isAssignmentTarget, |
| 22068 | oldFirstCoverInitializedNameError = firstCoverInitializedNameError, |
| 22069 | result; |
| 22070 | isBindingElement = true; |
| 22071 | isAssignmentTarget = true; |
| 22072 | firstCoverInitializedNameError = null; |
| 22073 | result = parser(); |
| 22074 | isBindingElement = isBindingElement && oldIsBindingElement; |
| 22075 | isAssignmentTarget = isAssignmentTarget && oldIsAssignmentTarget; |
| 22076 | firstCoverInitializedNameError = oldFirstCoverInitializedNameError || firstCoverInitializedNameError; |
| 22077 | return result; |
| 22078 | } |
| 22079 | |
| 22080 | function parseArrayPattern() { |
| 22081 | var node = new Node(), elements = [], rest, restNode; |
| 22082 | expect('['); |
| 22083 | |
| 22084 | while (!match(']')) { |
| 22085 | if (match(',')) { |
| 22086 | lex(); |
| 22087 | elements.push(null); |
| 22088 | } else { |
| 22089 | if (match('...')) { |
| 22090 | restNode = new Node(); |
| 22091 | lex(); |
| 22092 | rest = parseVariableIdentifier(); |
| 22093 | elements.push(restNode.finishRestElement(rest)); |
| 22094 | break; |
| 22095 | } else { |
| 22096 | elements.push(parsePatternWithDefault()); |
| 22097 | } |
| 22098 | if (!match(']')) { |
| 22099 | expect(','); |
| 22100 | } |
| 22101 | } |
| 22102 | |
| 22103 | } |
| 22104 | |
| 22105 | expect(']'); |
| 22106 | |
| 22107 | return node.finishArrayPattern(elements); |
| 22108 | } |
| 22109 | |
| 22110 | function parsePropertyPattern() { |
| 22111 | var node = new Node(), key, computed = match('['), init; |
| 22112 | if (lookahead.type === Token.Identifier) { |
| 22113 | key = parseVariableIdentifier(); |
| 22114 | if (match('=')) { |
| 22115 | lex(); |
| 22116 | init = parseAssignmentExpression(); |
| 22117 | return node.finishProperty( |
| 22118 | 'init', key, false, |
| 22119 | new WrappingNode(key).finishAssignmentPattern(key, init), false, false); |
| 22120 | } else if (!match(':')) { |
| 22121 | return node.finishProperty('init', key, false, key, false, true); |
| 22122 | } |
| 22123 | } else { |
| 22124 | key = parseObjectPropertyKey(); |
| 22125 | } |
| 22126 | expect(':'); |
| 22127 | init = parsePatternWithDefault(); |
| 22128 | return node.finishProperty('init', key, computed, init, false, false); |
| 22129 | } |
| 22130 | |
| 22131 | function parseObjectPattern() { |
| 22132 | var node = new Node(), properties = []; |
| 22133 | |
| 22134 | expect('{'); |
| 22135 | |
| 22136 | while (!match('}')) { |
| 22137 | properties.push(parsePropertyPattern()); |
| 22138 | if (!match('}')) { |
| 22139 | expect(','); |
| 22140 | } |
| 22141 | } |
| 22142 | |
| 22143 | lex(); |
| 22144 | |
| 22145 | return node.finishObjectPattern(properties); |
| 22146 | } |
| 22147 | |
| 22148 | function parsePattern() { |
| 22149 | if (lookahead.type === Token.Identifier) { |
| 22150 | return parseVariableIdentifier(); |
| 22151 | } else if (match('[')) { |
| 22152 | return parseArrayPattern(); |
| 22153 | } else if (match('{')) { |
| 22154 | return parseObjectPattern(); |
| 22155 | } |
| 22156 | throwUnexpectedToken(lookahead); |
| 22157 | } |
| 22158 | |
| 22159 | function parsePatternWithDefault() { |
| 22160 | var startToken = lookahead, pattern, right; |
| 22161 | pattern = parsePattern(); |
| 22162 | if (match('=')) { |
| 22163 | lex(); |
| 22164 | right = isolateCoverGrammar(parseAssignmentExpression); |
| 22165 | pattern = new WrappingNode(startToken).finishAssignmentPattern(pattern, right); |
| 22166 | } |
| 22167 | return pattern; |
| 22168 | } |
| 22169 | |
| 22170 | // 11.1.4 Array Initialiser |
| 22171 | |
| 22172 | function parseArrayInitialiser() { |
| 22173 | var elements = [], node = new Node(), restSpread; |
| 22174 | |
| 22175 | expect('['); |
| 22176 | |
| 22177 | while (!match(']')) { |
| 22178 | if (match(',')) { |
| 22179 | lex(); |
| 22180 | elements.push(null); |
| 22181 | } else if (match('...')) { |
| 22182 | restSpread = new Node(); |
| 22183 | lex(); |
| 22184 | restSpread.finishSpreadElement(inheritCoverGrammar(parseAssignmentExpression)); |
| 22185 | |
| 22186 | if (!match(']')) { |
| 22187 | isAssignmentTarget = isBindingElement = false; |
| 22188 | expect(','); |
| 22189 | } |
| 22190 | elements.push(restSpread); |
| 22191 | } else { |
| 22192 | elements.push(inheritCoverGrammar(parseAssignmentExpression)); |
| 22193 | |
| 22194 | if (!match(']')) { |
| 22195 | expect(','); |
| 22196 | } |
| 22197 | } |
| 22198 | } |
| 22199 | |
| 22200 | lex(); |
| 22201 | |
| 22202 | return node.finishArrayExpression(elements); |
| 22203 | } |
| 22204 | |
| 22205 | // 11.1.5 Object Initialiser |
| 22206 | |
| 22207 | function parsePropertyFunction(node, paramInfo) { |
| 22208 | var previousStrict, body; |
| 22209 | |
| 22210 | isAssignmentTarget = isBindingElement = false; |
| 22211 | |
| 22212 | previousStrict = strict; |
| 22213 | body = isolateCoverGrammar(parseFunctionSourceElements); |
| 22214 | |
| 22215 | if (strict && paramInfo.firstRestricted) { |
| 22216 | tolerateUnexpectedToken(paramInfo.firstRestricted, paramInfo.message); |
| 22217 | } |
| 22218 | if (strict && paramInfo.stricted) { |
| 22219 | tolerateUnexpectedToken(paramInfo.stricted, paramInfo.message); |
| 22220 | } |
| 22221 | |
| 22222 | strict = previousStrict; |
| 22223 | return node.finishFunctionExpression(null, paramInfo.params, paramInfo.defaults, body); |
| 22224 | } |
| 22225 | |
| 22226 | function parsePropertyMethodFunction() { |
| 22227 | var params, method, node = new Node(); |
| 22228 | |
| 22229 | params = parseParams(); |
| 22230 | method = parsePropertyFunction(node, params); |
| 22231 | |
| 22232 | return method; |
| 22233 | } |
| 22234 | |
| 22235 | function parseObjectPropertyKey() { |
| 22236 | var token, node = new Node(), expr; |
| 22237 | |
| 22238 | token = lex(); |
| 22239 | |
| 22240 | // Note: This function is called only from parseObjectProperty(), where |
| 22241 | // EOF and Punctuator tokens are already filtered out. |
| 22242 | |
| 22243 | switch (token.type) { |
| 22244 | case Token.StringLiteral: |
| 22245 | case Token.NumericLiteral: |
| 22246 | if (strict && token.octal) { |
| 22247 | tolerateUnexpectedToken(token, Messages.StrictOctalLiteral); |
| 22248 | } |
| 22249 | return node.finishLiteral(token); |
| 22250 | case Token.Identifier: |
| 22251 | case Token.BooleanLiteral: |
| 22252 | case Token.NullLiteral: |
| 22253 | case Token.Keyword: |
| 22254 | return node.finishIdentifier(token.value); |
| 22255 | case Token.Punctuator: |
| 22256 | if (token.value === '[') { |
| 22257 | expr = isolateCoverGrammar(parseAssignmentExpression); |
| 22258 | expect(']'); |
| 22259 | return expr; |
| 22260 | } |
| 22261 | break; |
| 22262 | } |
| 22263 | throwUnexpectedToken(token); |
| 22264 | } |
| 22265 | |
| 22266 | function lookaheadPropertyName() { |
| 22267 | switch (lookahead.type) { |
| 22268 | case Token.Identifier: |
| 22269 | case Token.StringLiteral: |
| 22270 | case Token.BooleanLiteral: |
| 22271 | case Token.NullLiteral: |
| 22272 | case Token.NumericLiteral: |
| 22273 | case Token.Keyword: |
| 22274 | return true; |
| 22275 | case Token.Punctuator: |
| 22276 | return lookahead.value === '['; |
| 22277 | } |
| 22278 | return false; |
| 22279 | } |
| 22280 | |
| 22281 | // This function is to try to parse a MethodDefinition as defined in 14.3. But in the case of object literals, |
| 22282 | // it might be called at a position where there is in fact a short hand identifier pattern or a data property. |
| 22283 | // This can only be determined after we consumed up to the left parentheses. |
| 22284 | // |
| 22285 | // In order to avoid back tracking, it returns `null` if the position is not a MethodDefinition and the caller |
| 22286 | // is responsible to visit other options. |
| 22287 | function tryParseMethodDefinition(token, key, computed, node) { |
| 22288 | var value, options, methodNode; |
| 22289 | |
| 22290 | if (token.type === Token.Identifier) { |
| 22291 | // check for `get` and `set`; |
| 22292 | |
| 22293 | if (token.value === 'get' && lookaheadPropertyName()) { |
| 22294 | computed = match('['); |
| 22295 | key = parseObjectPropertyKey(); |
| 22296 | methodNode = new Node(); |
| 22297 | expect('('); |
| 22298 | expect(')'); |
| 22299 | value = parsePropertyFunction(methodNode, { |
| 22300 | params: [], |
| 22301 | defaults: [], |
| 22302 | stricted: null, |
| 22303 | firstRestricted: null, |
| 22304 | message: null |
| 22305 | }); |
| 22306 | return node.finishProperty('get', key, computed, value, false, false); |
| 22307 | } else if (token.value === 'set' && lookaheadPropertyName()) { |
| 22308 | computed = match('['); |
| 22309 | key = parseObjectPropertyKey(); |
| 22310 | methodNode = new Node(); |
| 22311 | expect('('); |
| 22312 | |
| 22313 | options = { |
| 22314 | params: [], |
| 22315 | defaultCount: 0, |
| 22316 | defaults: [], |
| 22317 | firstRestricted: null, |
| 22318 | paramSet: {} |
| 22319 | }; |
| 22320 | if (match(')')) { |
| 22321 | tolerateUnexpectedToken(lookahead); |
| 22322 | } else { |
| 22323 | parseParam(options); |
| 22324 | if (options.defaultCount === 0) { |
| 22325 | options.defaults = []; |
| 22326 | } |
| 22327 | } |
| 22328 | expect(')'); |
| 22329 | |
| 22330 | value = parsePropertyFunction(methodNode, options); |
| 22331 | return node.finishProperty('set', key, computed, value, false, false); |
| 22332 | } |
| 22333 | } |
| 22334 | |
| 22335 | if (match('(')) { |
| 22336 | value = parsePropertyMethodFunction(); |
| 22337 | return node.finishProperty('init', key, computed, value, true, false); |
| 22338 | } |
| 22339 | |
| 22340 | // Not a MethodDefinition. |
| 22341 | return null; |
| 22342 | } |
| 22343 | |
| 22344 | function checkProto(key, computed, hasProto) { |
| 22345 | if (computed === false && (key.type === Syntax.Identifier && key.name === '__proto__' || |
| 22346 | key.type === Syntax.Literal && key.value === '__proto__')) { |
| 22347 | if (hasProto.value) { |
| 22348 | tolerateError(Messages.DuplicateProtoProperty); |
| 22349 | } else { |
| 22350 | hasProto.value = true; |
| 22351 | } |
| 22352 | } |
| 22353 | } |
| 22354 | |
| 22355 | function parseObjectProperty(hasProto) { |
| 22356 | var token = lookahead, node = new Node(), computed, key, maybeMethod, value; |
| 22357 | |
| 22358 | computed = match('['); |
| 22359 | key = parseObjectPropertyKey(); |
| 22360 | maybeMethod = tryParseMethodDefinition(token, key, computed, node); |
| 22361 | |
| 22362 | if (maybeMethod) { |
| 22363 | checkProto(maybeMethod.key, maybeMethod.computed, hasProto); |
| 22364 | // finished |
| 22365 | return maybeMethod; |
| 22366 | } |
| 22367 | |
| 22368 | // init property or short hand property. |
| 22369 | checkProto(key, computed, hasProto); |
| 22370 | |
| 22371 | if (match(':')) { |
| 22372 | lex(); |
| 22373 | value = inheritCoverGrammar(parseAssignmentExpression); |
| 22374 | return node.finishProperty('init', key, computed, value, false, false); |
| 22375 | } |
| 22376 | |
| 22377 | if (token.type === Token.Identifier) { |
| 22378 | if (match('=')) { |
| 22379 | firstCoverInitializedNameError = lookahead; |
| 22380 | lex(); |
| 22381 | value = isolateCoverGrammar(parseAssignmentExpression); |
| 22382 | return node.finishProperty('init', key, computed, |
| 22383 | new WrappingNode(token).finishAssignmentPattern(key, value), false, true); |
| 22384 | } |
| 22385 | return node.finishProperty('init', key, computed, key, false, true); |
| 22386 | } |
| 22387 | |
| 22388 | throwUnexpectedToken(lookahead); |
| 22389 | } |
| 22390 | |
| 22391 | function parseObjectInitialiser() { |
| 22392 | var properties = [], hasProto = {value: false}, node = new Node(); |
| 22393 | |
| 22394 | expect('{'); |
| 22395 | |
| 22396 | while (!match('}')) { |
| 22397 | properties.push(parseObjectProperty(hasProto)); |
| 22398 | |
| 22399 | if (!match('}')) { |
| 22400 | expectCommaSeparator(); |
| 22401 | } |
| 22402 | } |
| 22403 | |
| 22404 | expect('}'); |
| 22405 | |
| 22406 | return node.finishObjectExpression(properties); |
| 22407 | } |
| 22408 | |
| 22409 | function reinterpretExpressionAsPattern(expr) { |
| 22410 | var i; |
| 22411 | switch (expr.type) { |
| 22412 | case Syntax.Identifier: |
| 22413 | case Syntax.MemberExpression: |
| 22414 | case Syntax.RestElement: |
| 22415 | case Syntax.AssignmentPattern: |
| 22416 | break; |
| 22417 | case Syntax.SpreadElement: |
| 22418 | expr.type = Syntax.RestElement; |
| 22419 | reinterpretExpressionAsPattern(expr.argument); |
| 22420 | break; |
| 22421 | case Syntax.ArrayExpression: |
| 22422 | expr.type = Syntax.ArrayPattern; |
| 22423 | for (i = 0; i < expr.elements.length; i++) { |
| 22424 | if (expr.elements[i] !== null) { |
| 22425 | reinterpretExpressionAsPattern(expr.elements[i]); |
| 22426 | } |
| 22427 | } |
| 22428 | break; |
| 22429 | case Syntax.ObjectExpression: |
| 22430 | expr.type = Syntax.ObjectPattern; |
| 22431 | for (i = 0; i < expr.properties.length; i++) { |
| 22432 | reinterpretExpressionAsPattern(expr.properties[i].value); |
| 22433 | } |
| 22434 | break; |
| 22435 | case Syntax.AssignmentExpression: |
| 22436 | expr.type = Syntax.AssignmentPattern; |
| 22437 | reinterpretExpressionAsPattern(expr.left); |
| 22438 | break; |
| 22439 | default: |
| 22440 | // Allow other node type for tolerant parsing. |
| 22441 | break; |
| 22442 | } |
| 22443 | } |
| 22444 | |
| 22445 | function parseTemplateElement(option) { |
| 22446 | var node, token; |
| 22447 | |
| 22448 | if (lookahead.type !== Token.Template || (option.head && !lookahead.head)) { |
| 22449 | throwUnexpectedToken(); |
| 22450 | } |
| 22451 | |
| 22452 | node = new Node(); |
| 22453 | token = lex(); |
| 22454 | |
| 22455 | return node.finishTemplateElement({ raw: token.value.raw, cooked: token.value.cooked }, token.tail); |
| 22456 | } |
| 22457 | |
| 22458 | function parseTemplateLiteral() { |
| 22459 | var quasi, quasis, expressions, node = new Node(); |
| 22460 | |
| 22461 | quasi = parseTemplateElement({ head: true }); |
| 22462 | quasis = [ quasi ]; |
| 22463 | expressions = []; |
| 22464 | |
| 22465 | while (!quasi.tail) { |
| 22466 | expressions.push(parseExpression()); |
| 22467 | quasi = parseTemplateElement({ head: false }); |
| 22468 | quasis.push(quasi); |
| 22469 | } |
| 22470 | |
| 22471 | return node.finishTemplateLiteral(quasis, expressions); |
| 22472 | } |
| 22473 | |
| 22474 | // 11.1.6 The Grouping Operator |
| 22475 | |
| 22476 | function parseGroupExpression() { |
| 22477 | var expr, expressions, startToken, i; |
| 22478 | |
| 22479 | expect('('); |
| 22480 | |
| 22481 | if (match(')')) { |
| 22482 | lex(); |
| 22483 | if (!match('=>')) { |
| 22484 | expect('=>'); |
| 22485 | } |
| 22486 | return { |
| 22487 | type: PlaceHolders.ArrowParameterPlaceHolder, |
| 22488 | params: [] |
| 22489 | }; |
| 22490 | } |
| 22491 | |
| 22492 | startToken = lookahead; |
| 22493 | if (match('...')) { |
| 22494 | expr = parseRestElement(); |
| 22495 | expect(')'); |
| 22496 | if (!match('=>')) { |
| 22497 | expect('=>'); |
| 22498 | } |
| 22499 | return { |
| 22500 | type: PlaceHolders.ArrowParameterPlaceHolder, |
| 22501 | params: [expr] |
| 22502 | }; |
| 22503 | } |
| 22504 | |
| 22505 | isBindingElement = true; |
| 22506 | expr = inheritCoverGrammar(parseAssignmentExpression); |
| 22507 | |
| 22508 | if (match(',')) { |
| 22509 | isAssignmentTarget = false; |
| 22510 | expressions = [expr]; |
| 22511 | |
| 22512 | while (startIndex < length) { |
| 22513 | if (!match(',')) { |
| 22514 | break; |
| 22515 | } |
| 22516 | lex(); |
| 22517 | |
| 22518 | if (match('...')) { |
| 22519 | if (!isBindingElement) { |
| 22520 | throwUnexpectedToken(lookahead); |
| 22521 | } |
| 22522 | expressions.push(parseRestElement()); |
| 22523 | expect(')'); |
| 22524 | if (!match('=>')) { |
| 22525 | expect('=>'); |
| 22526 | } |
| 22527 | isBindingElement = false; |
| 22528 | for (i = 0; i < expressions.length; i++) { |
| 22529 | reinterpretExpressionAsPattern(expressions[i]); |
| 22530 | } |
| 22531 | return { |
| 22532 | type: PlaceHolders.ArrowParameterPlaceHolder, |
| 22533 | params: expressions |
| 22534 | }; |
| 22535 | } |
| 22536 | |
| 22537 | expressions.push(inheritCoverGrammar(parseAssignmentExpression)); |
| 22538 | } |
| 22539 | |
| 22540 | expr = new WrappingNode(startToken).finishSequenceExpression(expressions); |
| 22541 | } |
| 22542 | |
| 22543 | |
| 22544 | expect(')'); |
| 22545 | |
| 22546 | if (match('=>')) { |
| 22547 | if (!isBindingElement) { |
| 22548 | throwUnexpectedToken(lookahead); |
| 22549 | } |
| 22550 | |
| 22551 | if (expr.type === Syntax.SequenceExpression) { |
| 22552 | for (i = 0; i < expr.expressions.length; i++) { |
| 22553 | reinterpretExpressionAsPattern(expr.expressions[i]); |
| 22554 | } |
| 22555 | } else { |
| 22556 | reinterpretExpressionAsPattern(expr); |
| 22557 | } |
| 22558 | |
| 22559 | expr = { |
| 22560 | type: PlaceHolders.ArrowParameterPlaceHolder, |
| 22561 | params: expr.type === Syntax.SequenceExpression ? expr.expressions : [expr] |
| 22562 | }; |
| 22563 | } |
| 22564 | isBindingElement = false; |
| 22565 | return expr; |
| 22566 | } |
| 22567 | |
| 22568 | |
| 22569 | // 11.1 Primary Expressions |
| 22570 | |
| 22571 | function parsePrimaryExpression() { |
| 22572 | var type, token, expr, node; |
| 22573 | |
| 22574 | if (match('(')) { |
| 22575 | isBindingElement = false; |
| 22576 | return inheritCoverGrammar(parseGroupExpression); |
| 22577 | } |
| 22578 | |
| 22579 | if (match('[')) { |
| 22580 | return inheritCoverGrammar(parseArrayInitialiser); |
| 22581 | } |
| 22582 | |
| 22583 | if (match('{')) { |
| 22584 | return inheritCoverGrammar(parseObjectInitialiser); |
| 22585 | } |
| 22586 | |
| 22587 | type = lookahead.type; |
| 22588 | node = new Node(); |
| 22589 | |
| 22590 | if (type === Token.Identifier) { |
| 22591 | expr = node.finishIdentifier(lex().value); |
| 22592 | } else if (type === Token.StringLiteral || type === Token.NumericLiteral) { |
| 22593 | isAssignmentTarget = isBindingElement = false; |
| 22594 | if (strict && lookahead.octal) { |
| 22595 | tolerateUnexpectedToken(lookahead, Messages.StrictOctalLiteral); |
| 22596 | } |
| 22597 | expr = node.finishLiteral(lex()); |
| 22598 | } else if (type === Token.Keyword) { |
| 22599 | isAssignmentTarget = isBindingElement = false; |
| 22600 | if (matchKeyword('function')) { |
| 22601 | return parseFunctionExpression(); |
| 22602 | } |
| 22603 | if (matchKeyword('this')) { |
| 22604 | lex(); |
| 22605 | return node.finishThisExpression(); |
| 22606 | } |
| 22607 | if (matchKeyword('class')) { |
| 22608 | return parseClassExpression(); |
| 22609 | } |
| 22610 | throwUnexpectedToken(lex()); |
| 22611 | } else if (type === Token.BooleanLiteral) { |
| 22612 | isAssignmentTarget = isBindingElement = false; |
| 22613 | token = lex(); |
| 22614 | token.value = (token.value === 'true'); |
| 22615 | expr = node.finishLiteral(token); |
| 22616 | } else if (type === Token.NullLiteral) { |
| 22617 | isAssignmentTarget = isBindingElement = false; |
| 22618 | token = lex(); |
| 22619 | token.value = null; |
| 22620 | expr = node.finishLiteral(token); |
| 22621 | } else if (match('/') || match('/=')) { |
| 22622 | isAssignmentTarget = isBindingElement = false; |
| 22623 | index = startIndex; |
| 22624 | |
| 22625 | if (typeof extra.tokens !== 'undefined') { |
| 22626 | token = collectRegex(); |
| 22627 | } else { |
| 22628 | token = scanRegExp(); |
| 22629 | } |
| 22630 | lex(); |
| 22631 | expr = node.finishLiteral(token); |
| 22632 | } else if (type === Token.Template) { |
| 22633 | expr = parseTemplateLiteral(); |
| 22634 | } else { |
| 22635 | throwUnexpectedToken(lex()); |
| 22636 | } |
| 22637 | |
| 22638 | return expr; |
| 22639 | } |
| 22640 | |
| 22641 | // 11.2 Left-Hand-Side Expressions |
| 22642 | |
| 22643 | function parseArguments() { |
| 22644 | var args = []; |
| 22645 | |
| 22646 | expect('('); |
| 22647 | |
| 22648 | if (!match(')')) { |
| 22649 | while (startIndex < length) { |
| 22650 | args.push(isolateCoverGrammar(parseAssignmentExpression)); |
| 22651 | if (match(')')) { |
| 22652 | break; |
| 22653 | } |
| 22654 | expectCommaSeparator(); |
| 22655 | } |
| 22656 | } |
| 22657 | |
| 22658 | expect(')'); |
| 22659 | |
| 22660 | return args; |
| 22661 | } |
| 22662 | |
| 22663 | function parseNonComputedProperty() { |
| 22664 | var token, node = new Node(); |
| 22665 | |
| 22666 | token = lex(); |
| 22667 | |
| 22668 | if (!isIdentifierName(token)) { |
| 22669 | throwUnexpectedToken(token); |
| 22670 | } |
| 22671 | |
| 22672 | return node.finishIdentifier(token.value); |
| 22673 | } |
| 22674 | |
| 22675 | function parseNonComputedMember() { |
| 22676 | expect('.'); |
| 22677 | |
| 22678 | return parseNonComputedProperty(); |
| 22679 | } |
| 22680 | |
| 22681 | function parseComputedMember() { |
| 22682 | var expr; |
| 22683 | |
| 22684 | expect('['); |
| 22685 | |
| 22686 | expr = isolateCoverGrammar(parseExpression); |
| 22687 | |
| 22688 | expect(']'); |
| 22689 | |
| 22690 | return expr; |
| 22691 | } |
| 22692 | |
| 22693 | function parseNewExpression() { |
| 22694 | var callee, args, node = new Node(); |
| 22695 | |
| 22696 | expectKeyword('new'); |
| 22697 | callee = isolateCoverGrammar(parseLeftHandSideExpression); |
| 22698 | args = match('(') ? parseArguments() : []; |
| 22699 | |
| 22700 | isAssignmentTarget = isBindingElement = false; |
| 22701 | |
| 22702 | return node.finishNewExpression(callee, args); |
| 22703 | } |
| 22704 | |
| 22705 | function parseLeftHandSideExpressionAllowCall() { |
| 22706 | var quasi, expr, args, property, startToken, previousAllowIn = state.allowIn; |
| 22707 | |
| 22708 | startToken = lookahead; |
| 22709 | state.allowIn = true; |
| 22710 | |
| 22711 | if (matchKeyword('super') && state.inFunctionBody) { |
| 22712 | expr = new Node(); |
| 22713 | lex(); |
| 22714 | expr = expr.finishSuper(); |
| 22715 | if (!match('(') && !match('.') && !match('[')) { |
| 22716 | throwUnexpectedToken(lookahead); |
| 22717 | } |
| 22718 | } else { |
| 22719 | expr = inheritCoverGrammar(matchKeyword('new') ? parseNewExpression : parsePrimaryExpression); |
| 22720 | } |
| 22721 | |
| 22722 | for (;;) { |
| 22723 | if (match('.')) { |
| 22724 | isBindingElement = false; |
| 22725 | isAssignmentTarget = true; |
| 22726 | property = parseNonComputedMember(); |
| 22727 | expr = new WrappingNode(startToken).finishMemberExpression('.', expr, property); |
| 22728 | } else if (match('(')) { |
| 22729 | isBindingElement = false; |
| 22730 | isAssignmentTarget = false; |
| 22731 | args = parseArguments(); |
| 22732 | expr = new WrappingNode(startToken).finishCallExpression(expr, args); |
| 22733 | } else if (match('[')) { |
| 22734 | isBindingElement = false; |
| 22735 | isAssignmentTarget = true; |
| 22736 | property = parseComputedMember(); |
| 22737 | expr = new WrappingNode(startToken).finishMemberExpression('[', expr, property); |
| 22738 | } else if (lookahead.type === Token.Template && lookahead.head) { |
| 22739 | quasi = parseTemplateLiteral(); |
| 22740 | expr = new WrappingNode(startToken).finishTaggedTemplateExpression(expr, quasi); |
| 22741 | } else { |
| 22742 | break; |
| 22743 | } |
| 22744 | } |
| 22745 | state.allowIn = previousAllowIn; |
| 22746 | |
| 22747 | return expr; |
| 22748 | } |
| 22749 | |
| 22750 | function parseLeftHandSideExpression() { |
| 22751 | var quasi, expr, property, startToken; |
| 22752 | assert(state.allowIn, 'callee of new expression always allow in keyword.'); |
| 22753 | |
| 22754 | startToken = lookahead; |
| 22755 | |
| 22756 | if (matchKeyword('super') && state.inFunctionBody) { |
| 22757 | expr = new Node(); |
| 22758 | lex(); |
| 22759 | expr = expr.finishSuper(); |
| 22760 | if (!match('[') && !match('.')) { |
| 22761 | throwUnexpectedToken(lookahead); |
| 22762 | } |
| 22763 | } else { |
| 22764 | expr = inheritCoverGrammar(matchKeyword('new') ? parseNewExpression : parsePrimaryExpression); |
| 22765 | } |
| 22766 | |
| 22767 | for (;;) { |
| 22768 | if (match('[')) { |
| 22769 | isBindingElement = false; |
| 22770 | isAssignmentTarget = true; |
| 22771 | property = parseComputedMember(); |
| 22772 | expr = new WrappingNode(startToken).finishMemberExpression('[', expr, property); |
| 22773 | } else if (match('.')) { |
| 22774 | isBindingElement = false; |
| 22775 | isAssignmentTarget = true; |
| 22776 | property = parseNonComputedMember(); |
| 22777 | expr = new WrappingNode(startToken).finishMemberExpression('.', expr, property); |
| 22778 | } else if (lookahead.type === Token.Template && lookahead.head) { |
| 22779 | quasi = parseTemplateLiteral(); |
| 22780 | expr = new WrappingNode(startToken).finishTaggedTemplateExpression(expr, quasi); |
| 22781 | } else { |
| 22782 | break; |
| 22783 | } |
| 22784 | } |
| 22785 | return expr; |
| 22786 | } |
| 22787 | |
| 22788 | // 11.3 Postfix Expressions |
| 22789 | |
| 22790 | function parsePostfixExpression() { |
| 22791 | var expr, token, startToken = lookahead; |
| 22792 | |
| 22793 | expr = inheritCoverGrammar(parseLeftHandSideExpressionAllowCall); |
| 22794 | |
| 22795 | if (!hasLineTerminator && lookahead.type === Token.Punctuator) { |
| 22796 | if (match('++') || match('--')) { |
| 22797 | // 11.3.1, 11.3.2 |
| 22798 | if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) { |
| 22799 | tolerateError(Messages.StrictLHSPostfix); |
| 22800 | } |
| 22801 | |
| 22802 | if (!isAssignmentTarget) { |
| 22803 | tolerateError(Messages.InvalidLHSInAssignment); |
| 22804 | } |
| 22805 | |
| 22806 | isAssignmentTarget = isBindingElement = false; |
| 22807 | |
| 22808 | token = lex(); |
| 22809 | expr = new WrappingNode(startToken).finishPostfixExpression(token.value, expr); |
| 22810 | } |
| 22811 | } |
| 22812 | |
| 22813 | return expr; |
| 22814 | } |
| 22815 | |
| 22816 | // 11.4 Unary Operators |
| 22817 | |
| 22818 | function parseUnaryExpression() { |
| 22819 | var token, expr, startToken; |
| 22820 | |
| 22821 | if (lookahead.type !== Token.Punctuator && lookahead.type !== Token.Keyword) { |
| 22822 | expr = parsePostfixExpression(); |
| 22823 | } else if (match('++') || match('--')) { |
| 22824 | startToken = lookahead; |
| 22825 | token = lex(); |
| 22826 | expr = inheritCoverGrammar(parseUnaryExpression); |
| 22827 | // 11.4.4, 11.4.5 |
| 22828 | if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) { |
| 22829 | tolerateError(Messages.StrictLHSPrefix); |
| 22830 | } |
| 22831 | |
| 22832 | if (!isAssignmentTarget) { |
| 22833 | tolerateError(Messages.InvalidLHSInAssignment); |
| 22834 | } |
| 22835 | expr = new WrappingNode(startToken).finishUnaryExpression(token.value, expr); |
| 22836 | isAssignmentTarget = isBindingElement = false; |
| 22837 | } else if (match('+') || match('-') || match('~') || match('!')) { |
| 22838 | startToken = lookahead; |
| 22839 | token = lex(); |
| 22840 | expr = inheritCoverGrammar(parseUnaryExpression); |
| 22841 | expr = new WrappingNode(startToken).finishUnaryExpression(token.value, expr); |
| 22842 | isAssignmentTarget = isBindingElement = false; |
| 22843 | } else if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) { |
| 22844 | startToken = lookahead; |
| 22845 | token = lex(); |
| 22846 | expr = inheritCoverGrammar(parseUnaryExpression); |
| 22847 | expr = new WrappingNode(startToken).finishUnaryExpression(token.value, expr); |
| 22848 | if (strict && expr.operator === 'delete' && expr.argument.type === Syntax.Identifier) { |
| 22849 | tolerateError(Messages.StrictDelete); |
| 22850 | } |
| 22851 | isAssignmentTarget = isBindingElement = false; |
| 22852 | } else { |
| 22853 | expr = parsePostfixExpression(); |
| 22854 | } |
| 22855 | |
| 22856 | return expr; |
| 22857 | } |
| 22858 | |
| 22859 | function binaryPrecedence(token, allowIn) { |
| 22860 | var prec = 0; |
| 22861 | |
| 22862 | if (token.type !== Token.Punctuator && token.type !== Token.Keyword) { |
| 22863 | return 0; |
| 22864 | } |
| 22865 | |
| 22866 | switch (token.value) { |
| 22867 | case '||': |
| 22868 | prec = 1; |
| 22869 | break; |
| 22870 | |
| 22871 | case '&&': |
| 22872 | prec = 2; |
| 22873 | break; |
| 22874 | |
| 22875 | case '|': |
| 22876 | prec = 3; |
| 22877 | break; |
| 22878 | |
| 22879 | case '^': |
| 22880 | prec = 4; |
| 22881 | break; |
| 22882 | |
| 22883 | case '&': |
| 22884 | prec = 5; |
| 22885 | break; |
| 22886 | |
| 22887 | case '==': |
| 22888 | case '!=': |
| 22889 | case '===': |
| 22890 | case '!==': |
| 22891 | prec = 6; |
| 22892 | break; |
| 22893 | |
| 22894 | case '<': |
| 22895 | case '>': |
| 22896 | case '<=': |
| 22897 | case '>=': |
| 22898 | case 'instanceof': |
| 22899 | prec = 7; |
| 22900 | break; |
| 22901 | |
| 22902 | case 'in': |
| 22903 | prec = allowIn ? 7 : 0; |
| 22904 | break; |
| 22905 | |
| 22906 | case '<<': |
| 22907 | case '>>': |
| 22908 | case '>>>': |
| 22909 | prec = 8; |
| 22910 | break; |
| 22911 | |
| 22912 | case '+': |
| 22913 | case '-': |
| 22914 | prec = 9; |
| 22915 | break; |
| 22916 | |
| 22917 | case '*': |
| 22918 | case '/': |
| 22919 | case '%': |
| 22920 | prec = 11; |
| 22921 | break; |
| 22922 | |
| 22923 | default: |
| 22924 | break; |
| 22925 | } |
| 22926 | |
| 22927 | return prec; |
| 22928 | } |
| 22929 | |
| 22930 | // 11.5 Multiplicative Operators |
| 22931 | // 11.6 Additive Operators |
| 22932 | // 11.7 Bitwise Shift Operators |
| 22933 | // 11.8 Relational Operators |
| 22934 | // 11.9 Equality Operators |
| 22935 | // 11.10 Binary Bitwise Operators |
| 22936 | // 11.11 Binary Logical Operators |
| 22937 | |
| 22938 | function parseBinaryExpression() { |
| 22939 | var marker, markers, expr, token, prec, stack, right, operator, left, i; |
| 22940 | |
| 22941 | marker = lookahead; |
| 22942 | left = inheritCoverGrammar(parseUnaryExpression); |
| 22943 | |
| 22944 | token = lookahead; |
| 22945 | prec = binaryPrecedence(token, state.allowIn); |
| 22946 | if (prec === 0) { |
| 22947 | return left; |
| 22948 | } |
| 22949 | isAssignmentTarget = isBindingElement = false; |
| 22950 | token.prec = prec; |
| 22951 | lex(); |
| 22952 | |
| 22953 | markers = [marker, lookahead]; |
| 22954 | right = isolateCoverGrammar(parseUnaryExpression); |
| 22955 | |
| 22956 | stack = [left, token, right]; |
| 22957 | |
| 22958 | while ((prec = binaryPrecedence(lookahead, state.allowIn)) > 0) { |
| 22959 | |
| 22960 | // Reduce: make a binary expression from the three topmost entries. |
| 22961 | while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) { |
| 22962 | right = stack.pop(); |
| 22963 | operator = stack.pop().value; |
| 22964 | left = stack.pop(); |
| 22965 | markers.pop(); |
| 22966 | expr = new WrappingNode(markers[markers.length - 1]).finishBinaryExpression(operator, left, right); |
| 22967 | stack.push(expr); |
| 22968 | } |
| 22969 | |
| 22970 | // Shift. |
| 22971 | token = lex(); |
| 22972 | token.prec = prec; |
| 22973 | stack.push(token); |
| 22974 | markers.push(lookahead); |
| 22975 | expr = isolateCoverGrammar(parseUnaryExpression); |
| 22976 | stack.push(expr); |
| 22977 | } |
| 22978 | |
| 22979 | // Final reduce to clean-up the stack. |
| 22980 | i = stack.length - 1; |
| 22981 | expr = stack[i]; |
| 22982 | markers.pop(); |
| 22983 | while (i > 1) { |
| 22984 | expr = new WrappingNode(markers.pop()).finishBinaryExpression(stack[i - 1].value, stack[i - 2], expr); |
| 22985 | i -= 2; |
| 22986 | } |
| 22987 | |
| 22988 | return expr; |
| 22989 | } |
| 22990 | |
| 22991 | |
| 22992 | // 11.12 Conditional Operator |
| 22993 | |
| 22994 | function parseConditionalExpression() { |
| 22995 | var expr, previousAllowIn, consequent, alternate, startToken; |
| 22996 | |
| 22997 | startToken = lookahead; |
| 22998 | |
| 22999 | expr = inheritCoverGrammar(parseBinaryExpression); |
| 23000 | if (match('?')) { |
| 23001 | lex(); |
| 23002 | previousAllowIn = state.allowIn; |
| 23003 | state.allowIn = true; |
| 23004 | consequent = isolateCoverGrammar(parseAssignmentExpression); |
| 23005 | state.allowIn = previousAllowIn; |
| 23006 | expect(':'); |
| 23007 | alternate = isolateCoverGrammar(parseAssignmentExpression); |
| 23008 | |
| 23009 | expr = new WrappingNode(startToken).finishConditionalExpression(expr, consequent, alternate); |
| 23010 | isAssignmentTarget = isBindingElement = false; |
| 23011 | } |
| 23012 | |
| 23013 | return expr; |
| 23014 | } |
| 23015 | |
| 23016 | // [ES6] 14.2 Arrow Function |
| 23017 | |
| 23018 | function parseConciseBody() { |
| 23019 | if (match('{')) { |
| 23020 | return parseFunctionSourceElements(); |
| 23021 | } |
| 23022 | return isolateCoverGrammar(parseAssignmentExpression); |
| 23023 | } |
| 23024 | |
| 23025 | function checkPatternParam(options, param) { |
| 23026 | var i; |
| 23027 | switch (param.type) { |
| 23028 | case Syntax.Identifier: |
| 23029 | validateParam(options, param, param.name); |
| 23030 | break; |
| 23031 | case Syntax.RestElement: |
| 23032 | checkPatternParam(options, param.argument); |
| 23033 | break; |
| 23034 | case Syntax.AssignmentPattern: |
| 23035 | checkPatternParam(options, param.left); |
| 23036 | break; |
| 23037 | case Syntax.ArrayPattern: |
| 23038 | for (i = 0; i < param.elements.length; i++) { |
| 23039 | if (param.elements[i] !== null) { |
| 23040 | checkPatternParam(options, param.elements[i]); |
| 23041 | } |
| 23042 | } |
| 23043 | break; |
| 23044 | default: |
| 23045 | assert(param.type === Syntax.ObjectPattern, 'Invalid type'); |
| 23046 | for (i = 0; i < param.properties.length; i++) { |
| 23047 | checkPatternParam(options, param.properties[i].value); |
| 23048 | } |
| 23049 | break; |
| 23050 | } |
| 23051 | } |
| 23052 | function reinterpretAsCoverFormalsList(expr) { |
| 23053 | var i, len, param, params, defaults, defaultCount, options, token; |
| 23054 | |
| 23055 | defaults = []; |
| 23056 | defaultCount = 0; |
| 23057 | params = [expr]; |
| 23058 | |
| 23059 | switch (expr.type) { |
| 23060 | case Syntax.Identifier: |
| 23061 | break; |
| 23062 | case PlaceHolders.ArrowParameterPlaceHolder: |
| 23063 | params = expr.params; |
| 23064 | break; |
| 23065 | default: |
| 23066 | return null; |
| 23067 | } |
| 23068 | |
| 23069 | options = { |
| 23070 | paramSet: {} |
| 23071 | }; |
| 23072 | |
| 23073 | for (i = 0, len = params.length; i < len; i += 1) { |
| 23074 | param = params[i]; |
| 23075 | switch (param.type) { |
| 23076 | case Syntax.AssignmentPattern: |
| 23077 | params[i] = param.left; |
| 23078 | defaults.push(param.right); |
| 23079 | ++defaultCount; |
| 23080 | checkPatternParam(options, param.left); |
| 23081 | break; |
| 23082 | default: |
| 23083 | checkPatternParam(options, param); |
| 23084 | params[i] = param; |
| 23085 | defaults.push(null); |
| 23086 | break; |
| 23087 | } |
| 23088 | } |
| 23089 | |
| 23090 | if (options.message === Messages.StrictParamDupe) { |
| 23091 | token = strict ? options.stricted : options.firstRestricted; |
| 23092 | throwUnexpectedToken(token, options.message); |
| 23093 | } |
| 23094 | |
| 23095 | if (defaultCount === 0) { |
| 23096 | defaults = []; |
| 23097 | } |
| 23098 | |
| 23099 | return { |
| 23100 | params: params, |
| 23101 | defaults: defaults, |
| 23102 | stricted: options.stricted, |
| 23103 | firstRestricted: options.firstRestricted, |
| 23104 | message: options.message |
| 23105 | }; |
| 23106 | } |
| 23107 | |
| 23108 | function parseArrowFunctionExpression(options, node) { |
| 23109 | var previousStrict, body; |
| 23110 | |
| 23111 | if (hasLineTerminator) { |
| 23112 | tolerateUnexpectedToken(lookahead); |
| 23113 | } |
| 23114 | expect('=>'); |
| 23115 | previousStrict = strict; |
| 23116 | |
| 23117 | body = parseConciseBody(); |
| 23118 | |
| 23119 | if (strict && options.firstRestricted) { |
| 23120 | throwUnexpectedToken(options.firstRestricted, options.message); |
| 23121 | } |
| 23122 | if (strict && options.stricted) { |
| 23123 | tolerateUnexpectedToken(options.stricted, options.message); |
| 23124 | } |
| 23125 | |
| 23126 | strict = previousStrict; |
| 23127 | |
| 23128 | return node.finishArrowFunctionExpression(options.params, options.defaults, body, body.type !== Syntax.BlockStatement); |
| 23129 | } |
| 23130 | |
| 23131 | // 11.13 Assignment Operators |
| 23132 | |
| 23133 | function parseAssignmentExpression() { |
| 23134 | var token, expr, right, list, startToken; |
| 23135 | |
| 23136 | startToken = lookahead; |
| 23137 | token = lookahead; |
| 23138 | |
| 23139 | expr = parseConditionalExpression(); |
| 23140 | |
| 23141 | if (expr.type === PlaceHolders.ArrowParameterPlaceHolder || match('=>')) { |
| 23142 | isAssignmentTarget = isBindingElement = false; |
| 23143 | list = reinterpretAsCoverFormalsList(expr); |
| 23144 | |
| 23145 | if (list) { |
| 23146 | firstCoverInitializedNameError = null; |
| 23147 | return parseArrowFunctionExpression(list, new WrappingNode(startToken)); |
| 23148 | } |
| 23149 | |
| 23150 | return expr; |
| 23151 | } |
| 23152 | |
| 23153 | if (matchAssign()) { |
| 23154 | if (!isAssignmentTarget) { |
| 23155 | tolerateError(Messages.InvalidLHSInAssignment); |
| 23156 | } |
| 23157 | |
| 23158 | // 11.13.1 |
| 23159 | if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) { |
| 23160 | tolerateUnexpectedToken(token, Messages.StrictLHSAssignment); |
| 23161 | } |
| 23162 | |
| 23163 | if (!match('=')) { |
| 23164 | isAssignmentTarget = isBindingElement = false; |
| 23165 | } else { |
| 23166 | reinterpretExpressionAsPattern(expr); |
| 23167 | } |
| 23168 | |
| 23169 | token = lex(); |
| 23170 | right = isolateCoverGrammar(parseAssignmentExpression); |
| 23171 | expr = new WrappingNode(startToken).finishAssignmentExpression(token.value, expr, right); |
| 23172 | firstCoverInitializedNameError = null; |
| 23173 | } |
| 23174 | |
| 23175 | return expr; |
| 23176 | } |
| 23177 | |
| 23178 | // 11.14 Comma Operator |
| 23179 | |
| 23180 | function parseExpression() { |
| 23181 | var expr, startToken = lookahead, expressions; |
| 23182 | |
| 23183 | expr = isolateCoverGrammar(parseAssignmentExpression); |
| 23184 | |
| 23185 | if (match(',')) { |
| 23186 | expressions = [expr]; |
| 23187 | |
| 23188 | while (startIndex < length) { |
| 23189 | if (!match(',')) { |
| 23190 | break; |
| 23191 | } |
| 23192 | lex(); |
| 23193 | expressions.push(isolateCoverGrammar(parseAssignmentExpression)); |
| 23194 | } |
| 23195 | |
| 23196 | expr = new WrappingNode(startToken).finishSequenceExpression(expressions); |
| 23197 | } |
| 23198 | |
| 23199 | return expr; |
| 23200 | } |
| 23201 | |
| 23202 | // 12.1 Block |
| 23203 | |
| 23204 | function parseStatementListItem() { |
| 23205 | if (lookahead.type === Token.Keyword) { |
| 23206 | switch (lookahead.value) { |
| 23207 | case 'export': |
| 23208 | if (sourceType !== 'module') { |
| 23209 | tolerateUnexpectedToken(lookahead, Messages.IllegalExportDeclaration); |
| 23210 | } |
| 23211 | return parseExportDeclaration(); |
| 23212 | case 'import': |
| 23213 | if (sourceType !== 'module') { |
| 23214 | tolerateUnexpectedToken(lookahead, Messages.IllegalImportDeclaration); |
| 23215 | } |
| 23216 | return parseImportDeclaration(); |
| 23217 | case 'const': |
| 23218 | case 'let': |
| 23219 | return parseLexicalDeclaration({inFor: false}); |
| 23220 | case 'function': |
| 23221 | return parseFunctionDeclaration(new Node()); |
| 23222 | case 'class': |
| 23223 | return parseClassDeclaration(); |
| 23224 | } |
| 23225 | } |
| 23226 | |
| 23227 | return parseStatement(); |
| 23228 | } |
| 23229 | |
| 23230 | function parseStatementList() { |
| 23231 | var list = []; |
| 23232 | while (startIndex < length) { |
| 23233 | if (match('}')) { |
| 23234 | break; |
| 23235 | } |
| 23236 | list.push(parseStatementListItem()); |
| 23237 | } |
| 23238 | |
| 23239 | return list; |
| 23240 | } |
| 23241 | |
| 23242 | function parseBlock() { |
| 23243 | var block, node = new Node(); |
| 23244 | |
| 23245 | expect('{'); |
| 23246 | |
| 23247 | block = parseStatementList(); |
| 23248 | |
| 23249 | expect('}'); |
| 23250 | |
| 23251 | return node.finishBlockStatement(block); |
| 23252 | } |
| 23253 | |
| 23254 | // 12.2 Variable Statement |
| 23255 | |
| 23256 | function parseVariableIdentifier() { |
| 23257 | var token, node = new Node(); |
| 23258 | |
| 23259 | token = lex(); |
| 23260 | |
| 23261 | if (token.type !== Token.Identifier) { |
| 23262 | if (strict && token.type === Token.Keyword && isStrictModeReservedWord(token.value)) { |
| 23263 | tolerateUnexpectedToken(token, Messages.StrictReservedWord); |
| 23264 | } else { |
| 23265 | throwUnexpectedToken(token); |
| 23266 | } |
| 23267 | } |
| 23268 | |
| 23269 | return node.finishIdentifier(token.value); |
| 23270 | } |
| 23271 | |
| 23272 | function parseVariableDeclaration() { |
| 23273 | var init = null, id, node = new Node(); |
| 23274 | |
| 23275 | id = parsePattern(); |
| 23276 | |
| 23277 | // 12.2.1 |
| 23278 | if (strict && isRestrictedWord(id.name)) { |
| 23279 | tolerateError(Messages.StrictVarName); |
| 23280 | } |
| 23281 | |
| 23282 | if (match('=')) { |
| 23283 | lex(); |
| 23284 | init = isolateCoverGrammar(parseAssignmentExpression); |
| 23285 | } else if (id.type !== Syntax.Identifier) { |
| 23286 | expect('='); |
| 23287 | } |
| 23288 | |
| 23289 | return node.finishVariableDeclarator(id, init); |
| 23290 | } |
| 23291 | |
| 23292 | function parseVariableDeclarationList() { |
| 23293 | var list = []; |
| 23294 | |
| 23295 | do { |
| 23296 | list.push(parseVariableDeclaration()); |
| 23297 | if (!match(',')) { |
| 23298 | break; |
| 23299 | } |
| 23300 | lex(); |
| 23301 | } while (startIndex < length); |
| 23302 | |
| 23303 | return list; |
| 23304 | } |
| 23305 | |
| 23306 | function parseVariableStatement(node) { |
| 23307 | var declarations; |
| 23308 | |
| 23309 | expectKeyword('var'); |
| 23310 | |
| 23311 | declarations = parseVariableDeclarationList(); |
| 23312 | |
| 23313 | consumeSemicolon(); |
| 23314 | |
| 23315 | return node.finishVariableDeclaration(declarations); |
| 23316 | } |
| 23317 | |
| 23318 | function parseLexicalBinding(kind, options) { |
| 23319 | var init = null, id, node = new Node(); |
| 23320 | |
| 23321 | id = parsePattern(); |
| 23322 | |
| 23323 | // 12.2.1 |
| 23324 | if (strict && id.type === Syntax.Identifier && isRestrictedWord(id.name)) { |
| 23325 | tolerateError(Messages.StrictVarName); |
| 23326 | } |
| 23327 | |
| 23328 | if (kind === 'const') { |
| 23329 | if (!matchKeyword('in')) { |
| 23330 | expect('='); |
| 23331 | init = isolateCoverGrammar(parseAssignmentExpression); |
| 23332 | } |
| 23333 | } else if ((!options.inFor && id.type !== Syntax.Identifier) || match('=')) { |
| 23334 | expect('='); |
| 23335 | init = isolateCoverGrammar(parseAssignmentExpression); |
| 23336 | } |
| 23337 | |
| 23338 | return node.finishVariableDeclarator(id, init); |
| 23339 | } |
| 23340 | |
| 23341 | function parseBindingList(kind, options) { |
| 23342 | var list = []; |
| 23343 | |
| 23344 | do { |
| 23345 | list.push(parseLexicalBinding(kind, options)); |
| 23346 | if (!match(',')) { |
| 23347 | break; |
| 23348 | } |
| 23349 | lex(); |
| 23350 | } while (startIndex < length); |
| 23351 | |
| 23352 | return list; |
| 23353 | } |
| 23354 | |
| 23355 | function parseLexicalDeclaration(options) { |
| 23356 | var kind, declarations, node = new Node(); |
| 23357 | |
| 23358 | kind = lex().value; |
| 23359 | assert(kind === 'let' || kind === 'const', 'Lexical declaration must be either let or const'); |
| 23360 | |
| 23361 | declarations = parseBindingList(kind, options); |
| 23362 | |
| 23363 | consumeSemicolon(); |
| 23364 | |
| 23365 | return node.finishLexicalDeclaration(declarations, kind); |
| 23366 | } |
| 23367 | |
| 23368 | function parseRestElement() { |
| 23369 | var param, node = new Node(); |
| 23370 | |
| 23371 | lex(); |
| 23372 | |
| 23373 | if (match('{')) { |
| 23374 | throwError(Messages.ObjectPatternAsRestParameter); |
| 23375 | } |
| 23376 | |
| 23377 | param = parseVariableIdentifier(); |
| 23378 | |
| 23379 | if (match('=')) { |
| 23380 | throwError(Messages.DefaultRestParameter); |
| 23381 | } |
| 23382 | |
| 23383 | if (!match(')')) { |
| 23384 | throwError(Messages.ParameterAfterRestParameter); |
| 23385 | } |
| 23386 | |
| 23387 | return node.finishRestElement(param); |
| 23388 | } |
| 23389 | |
| 23390 | // 12.3 Empty Statement |
| 23391 | |
| 23392 | function parseEmptyStatement(node) { |
| 23393 | expect(';'); |
| 23394 | return node.finishEmptyStatement(); |
| 23395 | } |
| 23396 | |
| 23397 | // 12.4 Expression Statement |
| 23398 | |
| 23399 | function parseExpressionStatement(node) { |
| 23400 | var expr = parseExpression(); |
| 23401 | consumeSemicolon(); |
| 23402 | return node.finishExpressionStatement(expr); |
| 23403 | } |
| 23404 | |
| 23405 | // 12.5 If statement |
| 23406 | |
| 23407 | function parseIfStatement(node) { |
| 23408 | var test, consequent, alternate; |
| 23409 | |
| 23410 | expectKeyword('if'); |
| 23411 | |
| 23412 | expect('('); |
| 23413 | |
| 23414 | test = parseExpression(); |
| 23415 | |
| 23416 | expect(')'); |
| 23417 | |
| 23418 | consequent = parseStatement(); |
| 23419 | |
| 23420 | if (matchKeyword('else')) { |
| 23421 | lex(); |
| 23422 | alternate = parseStatement(); |
| 23423 | } else { |
| 23424 | alternate = null; |
| 23425 | } |
| 23426 | |
| 23427 | return node.finishIfStatement(test, consequent, alternate); |
| 23428 | } |
| 23429 | |
| 23430 | // 12.6 Iteration Statements |
| 23431 | |
| 23432 | function parseDoWhileStatement(node) { |
| 23433 | var body, test, oldInIteration; |
| 23434 | |
| 23435 | expectKeyword('do'); |
| 23436 | |
| 23437 | oldInIteration = state.inIteration; |
| 23438 | state.inIteration = true; |
| 23439 | |
| 23440 | body = parseStatement(); |
| 23441 | |
| 23442 | state.inIteration = oldInIteration; |
| 23443 | |
| 23444 | expectKeyword('while'); |
| 23445 | |
| 23446 | expect('('); |
| 23447 | |
| 23448 | test = parseExpression(); |
| 23449 | |
| 23450 | expect(')'); |
| 23451 | |
| 23452 | if (match(';')) { |
| 23453 | lex(); |
| 23454 | } |
| 23455 | |
| 23456 | return node.finishDoWhileStatement(body, test); |
| 23457 | } |
| 23458 | |
| 23459 | function parseWhileStatement(node) { |
| 23460 | var test, body, oldInIteration; |
| 23461 | |
| 23462 | expectKeyword('while'); |
| 23463 | |
| 23464 | expect('('); |
| 23465 | |
| 23466 | test = parseExpression(); |
| 23467 | |
| 23468 | expect(')'); |
| 23469 | |
| 23470 | oldInIteration = state.inIteration; |
| 23471 | state.inIteration = true; |
| 23472 | |
| 23473 | body = parseStatement(); |
| 23474 | |
| 23475 | state.inIteration = oldInIteration; |
| 23476 | |
| 23477 | return node.finishWhileStatement(test, body); |
| 23478 | } |
| 23479 | |
| 23480 | function parseForStatement(node) { |
| 23481 | var init, initSeq, initStartToken, test, update, left, right, kind, declarations, |
| 23482 | body, oldInIteration, previousAllowIn = state.allowIn; |
| 23483 | |
| 23484 | init = test = update = null; |
| 23485 | |
| 23486 | expectKeyword('for'); |
| 23487 | |
| 23488 | expect('('); |
| 23489 | |
| 23490 | if (match(';')) { |
| 23491 | lex(); |
| 23492 | } else { |
| 23493 | if (matchKeyword('var')) { |
| 23494 | init = new Node(); |
| 23495 | lex(); |
| 23496 | |
| 23497 | state.allowIn = false; |
| 23498 | init = init.finishVariableDeclaration(parseVariableDeclarationList()); |
| 23499 | state.allowIn = previousAllowIn; |
| 23500 | |
| 23501 | if (init.declarations.length === 1 && matchKeyword('in')) { |
| 23502 | lex(); |
| 23503 | left = init; |
| 23504 | right = parseExpression(); |
| 23505 | init = null; |
| 23506 | } else { |
| 23507 | expect(';'); |
| 23508 | } |
| 23509 | } else if (matchKeyword('const') || matchKeyword('let')) { |
| 23510 | init = new Node(); |
| 23511 | kind = lex().value; |
| 23512 | |
| 23513 | state.allowIn = false; |
| 23514 | declarations = parseBindingList(kind, {inFor: true}); |
| 23515 | state.allowIn = previousAllowIn; |
| 23516 | |
| 23517 | if (declarations.length === 1 && declarations[0].init === null && matchKeyword('in')) { |
| 23518 | init = init.finishLexicalDeclaration(declarations, kind); |
| 23519 | lex(); |
| 23520 | left = init; |
| 23521 | right = parseExpression(); |
| 23522 | init = null; |
| 23523 | } else { |
| 23524 | consumeSemicolon(); |
| 23525 | init = init.finishLexicalDeclaration(declarations, kind); |
| 23526 | } |
| 23527 | } else { |
| 23528 | initStartToken = lookahead; |
| 23529 | state.allowIn = false; |
| 23530 | init = inheritCoverGrammar(parseAssignmentExpression); |
| 23531 | state.allowIn = previousAllowIn; |
| 23532 | |
| 23533 | if (matchKeyword('in')) { |
| 23534 | if (!isAssignmentTarget) { |
| 23535 | tolerateError(Messages.InvalidLHSInForIn); |
| 23536 | } |
| 23537 | |
| 23538 | lex(); |
| 23539 | reinterpretExpressionAsPattern(init); |
| 23540 | left = init; |
| 23541 | right = parseExpression(); |
| 23542 | init = null; |
| 23543 | } else { |
| 23544 | if (match(',')) { |
| 23545 | initSeq = [init]; |
| 23546 | while (match(',')) { |
| 23547 | lex(); |
| 23548 | initSeq.push(isolateCoverGrammar(parseAssignmentExpression)); |
| 23549 | } |
| 23550 | init = new WrappingNode(initStartToken).finishSequenceExpression(initSeq); |
| 23551 | } |
| 23552 | expect(';'); |
| 23553 | } |
| 23554 | } |
| 23555 | } |
| 23556 | |
| 23557 | if (typeof left === 'undefined') { |
| 23558 | |
| 23559 | if (!match(';')) { |
| 23560 | test = parseExpression(); |
| 23561 | } |
| 23562 | expect(';'); |
| 23563 | |
| 23564 | if (!match(')')) { |
| 23565 | update = parseExpression(); |
| 23566 | } |
| 23567 | } |
| 23568 | |
| 23569 | expect(')'); |
| 23570 | |
| 23571 | oldInIteration = state.inIteration; |
| 23572 | state.inIteration = true; |
| 23573 | |
| 23574 | body = isolateCoverGrammar(parseStatement); |
| 23575 | |
| 23576 | state.inIteration = oldInIteration; |
| 23577 | |
| 23578 | return (typeof left === 'undefined') ? |
| 23579 | node.finishForStatement(init, test, update, body) : |
| 23580 | node.finishForInStatement(left, right, body); |
| 23581 | } |
| 23582 | |
| 23583 | // 12.7 The continue statement |
| 23584 | |
| 23585 | function parseContinueStatement(node) { |
| 23586 | var label = null, key; |
| 23587 | |
| 23588 | expectKeyword('continue'); |
| 23589 | |
| 23590 | // Optimize the most common form: 'continue;'. |
| 23591 | if (source.charCodeAt(startIndex) === 0x3B) { |
| 23592 | lex(); |
| 23593 | |
| 23594 | if (!state.inIteration) { |
| 23595 | throwError(Messages.IllegalContinue); |
| 23596 | } |
| 23597 | |
| 23598 | return node.finishContinueStatement(null); |
| 23599 | } |
| 23600 | |
| 23601 | if (hasLineTerminator) { |
| 23602 | if (!state.inIteration) { |
| 23603 | throwError(Messages.IllegalContinue); |
| 23604 | } |
| 23605 | |
| 23606 | return node.finishContinueStatement(null); |
| 23607 | } |
| 23608 | |
| 23609 | if (lookahead.type === Token.Identifier) { |
| 23610 | label = parseVariableIdentifier(); |
| 23611 | |
| 23612 | key = '$' + label.name; |
| 23613 | if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) { |
| 23614 | throwError(Messages.UnknownLabel, label.name); |
| 23615 | } |
| 23616 | } |
| 23617 | |
| 23618 | consumeSemicolon(); |
| 23619 | |
| 23620 | if (label === null && !state.inIteration) { |
| 23621 | throwError(Messages.IllegalContinue); |
| 23622 | } |
| 23623 | |
| 23624 | return node.finishContinueStatement(label); |
| 23625 | } |
| 23626 | |
| 23627 | // 12.8 The break statement |
| 23628 | |
| 23629 | function parseBreakStatement(node) { |
| 23630 | var label = null, key; |
| 23631 | |
| 23632 | expectKeyword('break'); |
| 23633 | |
| 23634 | // Catch the very common case first: immediately a semicolon (U+003B). |
| 23635 | if (source.charCodeAt(lastIndex) === 0x3B) { |
| 23636 | lex(); |
| 23637 | |
| 23638 | if (!(state.inIteration || state.inSwitch)) { |
| 23639 | throwError(Messages.IllegalBreak); |
| 23640 | } |
| 23641 | |
| 23642 | return node.finishBreakStatement(null); |
| 23643 | } |
| 23644 | |
| 23645 | if (hasLineTerminator) { |
| 23646 | if (!(state.inIteration || state.inSwitch)) { |
| 23647 | throwError(Messages.IllegalBreak); |
| 23648 | } |
| 23649 | |
| 23650 | return node.finishBreakStatement(null); |
| 23651 | } |
| 23652 | |
| 23653 | if (lookahead.type === Token.Identifier) { |
| 23654 | label = parseVariableIdentifier(); |
| 23655 | |
| 23656 | key = '$' + label.name; |
| 23657 | if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) { |
| 23658 | throwError(Messages.UnknownLabel, label.name); |
| 23659 | } |
| 23660 | } |
| 23661 | |
| 23662 | consumeSemicolon(); |
| 23663 | |
| 23664 | if (label === null && !(state.inIteration || state.inSwitch)) { |
| 23665 | throwError(Messages.IllegalBreak); |
| 23666 | } |
| 23667 | |
| 23668 | return node.finishBreakStatement(label); |
| 23669 | } |
| 23670 | |
| 23671 | // 12.9 The return statement |
| 23672 | |
| 23673 | function parseReturnStatement(node) { |
| 23674 | var argument = null; |
| 23675 | |
| 23676 | expectKeyword('return'); |
| 23677 | |
| 23678 | if (!state.inFunctionBody) { |
| 23679 | tolerateError(Messages.IllegalReturn); |
| 23680 | } |
| 23681 | |
| 23682 | // 'return' followed by a space and an identifier is very common. |
| 23683 | if (source.charCodeAt(lastIndex) === 0x20) { |
| 23684 | if (isIdentifierStart(source.charCodeAt(lastIndex + 1))) { |
| 23685 | argument = parseExpression(); |
| 23686 | consumeSemicolon(); |
| 23687 | return node.finishReturnStatement(argument); |
| 23688 | } |
| 23689 | } |
| 23690 | |
| 23691 | if (hasLineTerminator) { |
| 23692 | // HACK |
| 23693 | return node.finishReturnStatement(null); |
| 23694 | } |
| 23695 | |
| 23696 | if (!match(';')) { |
| 23697 | if (!match('}') && lookahead.type !== Token.EOF) { |
| 23698 | argument = parseExpression(); |
| 23699 | } |
| 23700 | } |
| 23701 | |
| 23702 | consumeSemicolon(); |
| 23703 | |
| 23704 | return node.finishReturnStatement(argument); |
| 23705 | } |
| 23706 | |
| 23707 | // 12.10 The with statement |
| 23708 | |
| 23709 | function parseWithStatement(node) { |
| 23710 | var object, body; |
| 23711 | |
| 23712 | if (strict) { |
| 23713 | tolerateError(Messages.StrictModeWith); |
| 23714 | } |
| 23715 | |
| 23716 | expectKeyword('with'); |
| 23717 | |
| 23718 | expect('('); |
| 23719 | |
| 23720 | object = parseExpression(); |
| 23721 | |
| 23722 | expect(')'); |
| 23723 | |
| 23724 | body = parseStatement(); |
| 23725 | |
| 23726 | return node.finishWithStatement(object, body); |
| 23727 | } |
| 23728 | |
| 23729 | // 12.10 The swith statement |
| 23730 | |
| 23731 | function parseSwitchCase() { |
| 23732 | var test, consequent = [], statement, node = new Node(); |
| 23733 | |
| 23734 | if (matchKeyword('default')) { |
| 23735 | lex(); |
| 23736 | test = null; |
| 23737 | } else { |
| 23738 | expectKeyword('case'); |
| 23739 | test = parseExpression(); |
| 23740 | } |
| 23741 | expect(':'); |
| 23742 | |
| 23743 | while (startIndex < length) { |
| 23744 | if (match('}') || matchKeyword('default') || matchKeyword('case')) { |
| 23745 | break; |
| 23746 | } |
| 23747 | statement = parseStatementListItem(); |
| 23748 | consequent.push(statement); |
| 23749 | } |
| 23750 | |
| 23751 | return node.finishSwitchCase(test, consequent); |
| 23752 | } |
| 23753 | |
| 23754 | function parseSwitchStatement(node) { |
| 23755 | var discriminant, cases, clause, oldInSwitch, defaultFound; |
| 23756 | |
| 23757 | expectKeyword('switch'); |
| 23758 | |
| 23759 | expect('('); |
| 23760 | |
| 23761 | discriminant = parseExpression(); |
| 23762 | |
| 23763 | expect(')'); |
| 23764 | |
| 23765 | expect('{'); |
| 23766 | |
| 23767 | cases = []; |
| 23768 | |
| 23769 | if (match('}')) { |
| 23770 | lex(); |
| 23771 | return node.finishSwitchStatement(discriminant, cases); |
| 23772 | } |
| 23773 | |
| 23774 | oldInSwitch = state.inSwitch; |
| 23775 | state.inSwitch = true; |
| 23776 | defaultFound = false; |
| 23777 | |
| 23778 | while (startIndex < length) { |
| 23779 | if (match('}')) { |
| 23780 | break; |
| 23781 | } |
| 23782 | clause = parseSwitchCase(); |
| 23783 | if (clause.test === null) { |
| 23784 | if (defaultFound) { |
| 23785 | throwError(Messages.MultipleDefaultsInSwitch); |
| 23786 | } |
| 23787 | defaultFound = true; |
| 23788 | } |
| 23789 | cases.push(clause); |
| 23790 | } |
| 23791 | |
| 23792 | state.inSwitch = oldInSwitch; |
| 23793 | |
| 23794 | expect('}'); |
| 23795 | |
| 23796 | return node.finishSwitchStatement(discriminant, cases); |
| 23797 | } |
| 23798 | |
| 23799 | // 12.13 The throw statement |
| 23800 | |
| 23801 | function parseThrowStatement(node) { |
| 23802 | var argument; |
| 23803 | |
| 23804 | expectKeyword('throw'); |
| 23805 | |
| 23806 | if (hasLineTerminator) { |
| 23807 | throwError(Messages.NewlineAfterThrow); |
| 23808 | } |
| 23809 | |
| 23810 | argument = parseExpression(); |
| 23811 | |
| 23812 | consumeSemicolon(); |
| 23813 | |
| 23814 | return node.finishThrowStatement(argument); |
| 23815 | } |
| 23816 | |
| 23817 | // 12.14 The try statement |
| 23818 | |
| 23819 | function parseCatchClause() { |
| 23820 | var param, body, node = new Node(); |
| 23821 | |
| 23822 | expectKeyword('catch'); |
| 23823 | |
| 23824 | expect('('); |
| 23825 | if (match(')')) { |
| 23826 | throwUnexpectedToken(lookahead); |
| 23827 | } |
| 23828 | |
| 23829 | param = parsePattern(); |
| 23830 | |
| 23831 | // 12.14.1 |
| 23832 | if (strict && isRestrictedWord(param.name)) { |
| 23833 | tolerateError(Messages.StrictCatchVariable); |
| 23834 | } |
| 23835 | |
| 23836 | expect(')'); |
| 23837 | body = parseBlock(); |
| 23838 | return node.finishCatchClause(param, body); |
| 23839 | } |
| 23840 | |
| 23841 | function parseTryStatement(node) { |
| 23842 | var block, handler = null, finalizer = null; |
| 23843 | |
| 23844 | expectKeyword('try'); |
| 23845 | |
| 23846 | block = parseBlock(); |
| 23847 | |
| 23848 | if (matchKeyword('catch')) { |
| 23849 | handler = parseCatchClause(); |
| 23850 | } |
| 23851 | |
| 23852 | if (matchKeyword('finally')) { |
| 23853 | lex(); |
| 23854 | finalizer = parseBlock(); |
| 23855 | } |
| 23856 | |
| 23857 | if (!handler && !finalizer) { |
| 23858 | throwError(Messages.NoCatchOrFinally); |
| 23859 | } |
| 23860 | |
| 23861 | return node.finishTryStatement(block, handler, finalizer); |
| 23862 | } |
| 23863 | |
| 23864 | // 12.15 The debugger statement |
| 23865 | |
| 23866 | function parseDebuggerStatement(node) { |
| 23867 | expectKeyword('debugger'); |
| 23868 | |
| 23869 | consumeSemicolon(); |
| 23870 | |
| 23871 | return node.finishDebuggerStatement(); |
| 23872 | } |
| 23873 | |
| 23874 | // 12 Statements |
| 23875 | |
| 23876 | function parseStatement() { |
| 23877 | var type = lookahead.type, |
| 23878 | expr, |
| 23879 | labeledBody, |
| 23880 | key, |
| 23881 | node; |
| 23882 | |
| 23883 | if (type === Token.EOF) { |
| 23884 | throwUnexpectedToken(lookahead); |
| 23885 | } |
| 23886 | |
| 23887 | if (type === Token.Punctuator && lookahead.value === '{') { |
| 23888 | return parseBlock(); |
| 23889 | } |
| 23890 | isAssignmentTarget = isBindingElement = true; |
| 23891 | node = new Node(); |
| 23892 | |
| 23893 | if (type === Token.Punctuator) { |
| 23894 | switch (lookahead.value) { |
| 23895 | case ';': |
| 23896 | return parseEmptyStatement(node); |
| 23897 | case '(': |
| 23898 | return parseExpressionStatement(node); |
| 23899 | default: |
| 23900 | break; |
| 23901 | } |
| 23902 | } else if (type === Token.Keyword) { |
| 23903 | switch (lookahead.value) { |
| 23904 | case 'break': |
| 23905 | return parseBreakStatement(node); |
| 23906 | case 'continue': |
| 23907 | return parseContinueStatement(node); |
| 23908 | case 'debugger': |
| 23909 | return parseDebuggerStatement(node); |
| 23910 | case 'do': |
| 23911 | return parseDoWhileStatement(node); |
| 23912 | case 'for': |
| 23913 | return parseForStatement(node); |
| 23914 | case 'function': |
| 23915 | return parseFunctionDeclaration(node); |
| 23916 | case 'if': |
| 23917 | return parseIfStatement(node); |
| 23918 | case 'return': |
| 23919 | return parseReturnStatement(node); |
| 23920 | case 'switch': |
| 23921 | return parseSwitchStatement(node); |
| 23922 | case 'throw': |
| 23923 | return parseThrowStatement(node); |
| 23924 | case 'try': |
| 23925 | return parseTryStatement(node); |
| 23926 | case 'var': |
| 23927 | return parseVariableStatement(node); |
| 23928 | case 'while': |
| 23929 | return parseWhileStatement(node); |
| 23930 | case 'with': |
| 23931 | return parseWithStatement(node); |
| 23932 | default: |
| 23933 | break; |
| 23934 | } |
| 23935 | } |
| 23936 | |
| 23937 | expr = parseExpression(); |
| 23938 | |
| 23939 | // 12.12 Labelled Statements |
| 23940 | if ((expr.type === Syntax.Identifier) && match(':')) { |
| 23941 | lex(); |
| 23942 | |
| 23943 | key = '$' + expr.name; |
| 23944 | if (Object.prototype.hasOwnProperty.call(state.labelSet, key)) { |
| 23945 | throwError(Messages.Redeclaration, 'Label', expr.name); |
| 23946 | } |
| 23947 | |
| 23948 | state.labelSet[key] = true; |
| 23949 | labeledBody = parseStatement(); |
| 23950 | delete state.labelSet[key]; |
| 23951 | return node.finishLabeledStatement(expr, labeledBody); |
| 23952 | } |
| 23953 | |
| 23954 | consumeSemicolon(); |
| 23955 | |
| 23956 | return node.finishExpressionStatement(expr); |
| 23957 | } |
| 23958 | |
| 23959 | // 13 Function Definition |
| 23960 | |
| 23961 | function parseFunctionSourceElements() { |
| 23962 | var statement, body = [], token, directive, firstRestricted, |
| 23963 | oldLabelSet, oldInIteration, oldInSwitch, oldInFunctionBody, oldParenthesisCount, |
| 23964 | node = new Node(); |
| 23965 | |
| 23966 | expect('{'); |
| 23967 | |
| 23968 | while (startIndex < length) { |
| 23969 | if (lookahead.type !== Token.StringLiteral) { |
| 23970 | break; |
| 23971 | } |
| 23972 | token = lookahead; |
| 23973 | |
| 23974 | statement = parseStatementListItem(); |
| 23975 | body.push(statement); |
| 23976 | if (statement.expression.type !== Syntax.Literal) { |
| 23977 | // this is not directive |
| 23978 | break; |
| 23979 | } |
| 23980 | directive = source.slice(token.start + 1, token.end - 1); |
| 23981 | if (directive === 'use strict') { |
| 23982 | strict = true; |
| 23983 | if (firstRestricted) { |
| 23984 | tolerateUnexpectedToken(firstRestricted, Messages.StrictOctalLiteral); |
| 23985 | } |
| 23986 | } else { |
| 23987 | if (!firstRestricted && token.octal) { |
| 23988 | firstRestricted = token; |
| 23989 | } |
| 23990 | } |
| 23991 | } |
| 23992 | |
| 23993 | oldLabelSet = state.labelSet; |
| 23994 | oldInIteration = state.inIteration; |
| 23995 | oldInSwitch = state.inSwitch; |
| 23996 | oldInFunctionBody = state.inFunctionBody; |
| 23997 | oldParenthesisCount = state.parenthesizedCount; |
| 23998 | |
| 23999 | state.labelSet = {}; |
| 24000 | state.inIteration = false; |
| 24001 | state.inSwitch = false; |
| 24002 | state.inFunctionBody = true; |
| 24003 | state.parenthesizedCount = 0; |
| 24004 | |
| 24005 | while (startIndex < length) { |
| 24006 | if (match('}')) { |
| 24007 | break; |
| 24008 | } |
| 24009 | body.push(parseStatementListItem()); |
| 24010 | } |
| 24011 | |
| 24012 | expect('}'); |
| 24013 | |
| 24014 | state.labelSet = oldLabelSet; |
| 24015 | state.inIteration = oldInIteration; |
| 24016 | state.inSwitch = oldInSwitch; |
| 24017 | state.inFunctionBody = oldInFunctionBody; |
| 24018 | state.parenthesizedCount = oldParenthesisCount; |
| 24019 | |
| 24020 | return node.finishBlockStatement(body); |
| 24021 | } |
| 24022 | |
| 24023 | function validateParam(options, param, name) { |
| 24024 | var key = '$' + name; |
| 24025 | if (strict) { |
| 24026 | if (isRestrictedWord(name)) { |
| 24027 | options.stricted = param; |
| 24028 | options.message = Messages.StrictParamName; |
| 24029 | } |
| 24030 | if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) { |
| 24031 | options.stricted = param; |
| 24032 | options.message = Messages.StrictParamDupe; |
| 24033 | } |
| 24034 | } else if (!options.firstRestricted) { |
| 24035 | if (isRestrictedWord(name)) { |
| 24036 | options.firstRestricted = param; |
| 24037 | options.message = Messages.StrictParamName; |
| 24038 | } else if (isStrictModeReservedWord(name)) { |
| 24039 | options.firstRestricted = param; |
| 24040 | options.message = Messages.StrictReservedWord; |
| 24041 | } else if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) { |
| 24042 | options.firstRestricted = param; |
| 24043 | options.message = Messages.StrictParamDupe; |
| 24044 | } |
| 24045 | } |
| 24046 | options.paramSet[key] = true; |
| 24047 | } |
| 24048 | |
| 24049 | function parseParam(options) { |
| 24050 | var token, param, def; |
| 24051 | |
| 24052 | token = lookahead; |
| 24053 | if (token.value === '...') { |
| 24054 | param = parseRestElement(); |
| 24055 | validateParam(options, param.argument, param.argument.name); |
| 24056 | options.params.push(param); |
| 24057 | options.defaults.push(null); |
| 24058 | return false; |
| 24059 | } |
| 24060 | |
| 24061 | param = parsePatternWithDefault(); |
| 24062 | validateParam(options, token, token.value); |
| 24063 | |
| 24064 | if (param.type === Syntax.AssignmentPattern) { |
| 24065 | def = param.right; |
| 24066 | param = param.left; |
| 24067 | ++options.defaultCount; |
| 24068 | } |
| 24069 | |
| 24070 | options.params.push(param); |
| 24071 | options.defaults.push(def); |
| 24072 | |
| 24073 | return !match(')'); |
| 24074 | } |
| 24075 | |
| 24076 | function parseParams(firstRestricted) { |
| 24077 | var options; |
| 24078 | |
| 24079 | options = { |
| 24080 | params: [], |
| 24081 | defaultCount: 0, |
| 24082 | defaults: [], |
| 24083 | firstRestricted: firstRestricted |
| 24084 | }; |
| 24085 | |
| 24086 | expect('('); |
| 24087 | |
| 24088 | if (!match(')')) { |
| 24089 | options.paramSet = {}; |
| 24090 | while (startIndex < length) { |
| 24091 | if (!parseParam(options)) { |
| 24092 | break; |
| 24093 | } |
| 24094 | expect(','); |
| 24095 | } |
| 24096 | } |
| 24097 | |
| 24098 | expect(')'); |
| 24099 | |
| 24100 | if (options.defaultCount === 0) { |
| 24101 | options.defaults = []; |
| 24102 | } |
| 24103 | |
| 24104 | return { |
| 24105 | params: options.params, |
| 24106 | defaults: options.defaults, |
| 24107 | stricted: options.stricted, |
| 24108 | firstRestricted: options.firstRestricted, |
| 24109 | message: options.message |
| 24110 | }; |
| 24111 | } |
| 24112 | |
| 24113 | function parseFunctionDeclaration(node, identifierIsOptional) { |
| 24114 | var id = null, params = [], defaults = [], body, token, stricted, tmp, firstRestricted, message, previousStrict; |
| 24115 | |
| 24116 | expectKeyword('function'); |
| 24117 | if (!identifierIsOptional || !match('(')) { |
| 24118 | token = lookahead; |
| 24119 | id = parseVariableIdentifier(); |
| 24120 | if (strict) { |
| 24121 | if (isRestrictedWord(token.value)) { |
| 24122 | tolerateUnexpectedToken(token, Messages.StrictFunctionName); |
| 24123 | } |
| 24124 | } else { |
| 24125 | if (isRestrictedWord(token.value)) { |
| 24126 | firstRestricted = token; |
| 24127 | message = Messages.StrictFunctionName; |
| 24128 | } else if (isStrictModeReservedWord(token.value)) { |
| 24129 | firstRestricted = token; |
| 24130 | message = Messages.StrictReservedWord; |
| 24131 | } |
| 24132 | } |
| 24133 | } |
| 24134 | |
| 24135 | tmp = parseParams(firstRestricted); |
| 24136 | params = tmp.params; |
| 24137 | defaults = tmp.defaults; |
| 24138 | stricted = tmp.stricted; |
| 24139 | firstRestricted = tmp.firstRestricted; |
| 24140 | if (tmp.message) { |
| 24141 | message = tmp.message; |
| 24142 | } |
| 24143 | |
| 24144 | previousStrict = strict; |
| 24145 | body = parseFunctionSourceElements(); |
| 24146 | if (strict && firstRestricted) { |
| 24147 | throwUnexpectedToken(firstRestricted, message); |
| 24148 | } |
| 24149 | if (strict && stricted) { |
| 24150 | tolerateUnexpectedToken(stricted, message); |
| 24151 | } |
| 24152 | strict = previousStrict; |
| 24153 | |
| 24154 | return node.finishFunctionDeclaration(id, params, defaults, body); |
| 24155 | } |
| 24156 | |
| 24157 | function parseFunctionExpression() { |
| 24158 | var token, id = null, stricted, firstRestricted, message, tmp, |
| 24159 | params = [], defaults = [], body, previousStrict, node = new Node(); |
| 24160 | |
| 24161 | expectKeyword('function'); |
| 24162 | |
| 24163 | if (!match('(')) { |
| 24164 | token = lookahead; |
| 24165 | id = parseVariableIdentifier(); |
| 24166 | if (strict) { |
| 24167 | if (isRestrictedWord(token.value)) { |
| 24168 | tolerateUnexpectedToken(token, Messages.StrictFunctionName); |
| 24169 | } |
| 24170 | } else { |
| 24171 | if (isRestrictedWord(token.value)) { |
| 24172 | firstRestricted = token; |
| 24173 | message = Messages.StrictFunctionName; |
| 24174 | } else if (isStrictModeReservedWord(token.value)) { |
| 24175 | firstRestricted = token; |
| 24176 | message = Messages.StrictReservedWord; |
| 24177 | } |
| 24178 | } |
| 24179 | } |
| 24180 | |
| 24181 | tmp = parseParams(firstRestricted); |
| 24182 | params = tmp.params; |
| 24183 | defaults = tmp.defaults; |
| 24184 | stricted = tmp.stricted; |
| 24185 | firstRestricted = tmp.firstRestricted; |
| 24186 | if (tmp.message) { |
| 24187 | message = tmp.message; |
| 24188 | } |
| 24189 | |
| 24190 | previousStrict = strict; |
| 24191 | body = parseFunctionSourceElements(); |
| 24192 | if (strict && firstRestricted) { |
| 24193 | throwUnexpectedToken(firstRestricted, message); |
| 24194 | } |
| 24195 | if (strict && stricted) { |
| 24196 | tolerateUnexpectedToken(stricted, message); |
| 24197 | } |
| 24198 | strict = previousStrict; |
| 24199 | |
| 24200 | return node.finishFunctionExpression(id, params, defaults, body); |
| 24201 | } |
| 24202 | |
| 24203 | |
| 24204 | function parseClassBody() { |
| 24205 | var classBody, token, isStatic, hasConstructor = false, body, method, computed, key; |
| 24206 | |
| 24207 | classBody = new Node(); |
| 24208 | |
| 24209 | expect('{'); |
| 24210 | body = []; |
| 24211 | while (!match('}')) { |
| 24212 | if (match(';')) { |
| 24213 | lex(); |
| 24214 | } else { |
| 24215 | method = new Node(); |
| 24216 | token = lookahead; |
| 24217 | isStatic = false; |
| 24218 | computed = match('['); |
| 24219 | key = parseObjectPropertyKey(); |
| 24220 | if (key.name === 'static' && lookaheadPropertyName()) { |
| 24221 | token = lookahead; |
| 24222 | isStatic = true; |
| 24223 | computed = match('['); |
| 24224 | key = parseObjectPropertyKey(); |
| 24225 | } |
| 24226 | method = tryParseMethodDefinition(token, key, computed, method); |
| 24227 | if (method) { |
| 24228 | method['static'] = isStatic; |
| 24229 | if (method.kind === 'init') { |
| 24230 | method.kind = 'method'; |
| 24231 | } |
| 24232 | if (!isStatic) { |
| 24233 | if (!method.computed && (method.key.name || method.key.value.toString()) === 'constructor') { |
| 24234 | if (method.kind !== 'method' || !method.method || method.value.generator) { |
| 24235 | throwUnexpectedToken(token, Messages.ConstructorSpecialMethod); |
| 24236 | } |
| 24237 | if (hasConstructor) { |
| 24238 | throwUnexpectedToken(token, Messages.DuplicateConstructor); |
| 24239 | } else { |
| 24240 | hasConstructor = true; |
| 24241 | } |
| 24242 | method.kind = 'constructor'; |
| 24243 | } |
| 24244 | } else { |
| 24245 | if (!method.computed && (method.key.name || method.key.value.toString()) === 'prototype') { |
| 24246 | throwUnexpectedToken(token, Messages.StaticPrototype); |
| 24247 | } |
| 24248 | } |
| 24249 | method.type = Syntax.MethodDefinition; |
| 24250 | delete method.method; |
| 24251 | delete method.shorthand; |
| 24252 | body.push(method); |
| 24253 | } else { |
| 24254 | throwUnexpectedToken(lookahead); |
| 24255 | } |
| 24256 | } |
| 24257 | } |
| 24258 | lex(); |
| 24259 | return classBody.finishClassBody(body); |
| 24260 | } |
| 24261 | |
| 24262 | function parseClassDeclaration(identifierIsOptional) { |
| 24263 | var id = null, superClass = null, classNode = new Node(), classBody, previousStrict = strict; |
| 24264 | strict = true; |
| 24265 | |
| 24266 | expectKeyword('class'); |
| 24267 | |
| 24268 | if (!identifierIsOptional || lookahead.type === Token.Identifier) { |
| 24269 | id = parseVariableIdentifier(); |
| 24270 | } |
| 24271 | |
| 24272 | if (matchKeyword('extends')) { |
| 24273 | lex(); |
| 24274 | superClass = isolateCoverGrammar(parseLeftHandSideExpressionAllowCall); |
| 24275 | } |
| 24276 | classBody = parseClassBody(); |
| 24277 | strict = previousStrict; |
| 24278 | |
| 24279 | return classNode.finishClassDeclaration(id, superClass, classBody); |
| 24280 | } |
| 24281 | |
| 24282 | function parseClassExpression() { |
| 24283 | var id = null, superClass = null, classNode = new Node(), classBody, previousStrict = strict; |
| 24284 | strict = true; |
| 24285 | |
| 24286 | expectKeyword('class'); |
| 24287 | |
| 24288 | if (lookahead.type === Token.Identifier) { |
| 24289 | id = parseVariableIdentifier(); |
| 24290 | } |
| 24291 | |
| 24292 | if (matchKeyword('extends')) { |
| 24293 | lex(); |
| 24294 | superClass = isolateCoverGrammar(parseLeftHandSideExpressionAllowCall); |
| 24295 | } |
| 24296 | classBody = parseClassBody(); |
| 24297 | strict = previousStrict; |
| 24298 | |
| 24299 | return classNode.finishClassExpression(id, superClass, classBody); |
| 24300 | } |
| 24301 | |
| 24302 | // Modules grammar from: |
| 24303 | // people.mozilla.org/~jorendorff/es6-draft.html |
| 24304 | |
| 24305 | function parseModuleSpecifier() { |
| 24306 | var node = new Node(); |
| 24307 | |
| 24308 | if (lookahead.type !== Token.StringLiteral) { |
| 24309 | throwError(Messages.InvalidModuleSpecifier); |
| 24310 | } |
| 24311 | return node.finishLiteral(lex()); |
| 24312 | } |
| 24313 | |
| 24314 | function parseExportSpecifier() { |
| 24315 | var exported, local, node = new Node(), def; |
| 24316 | if (matchKeyword('default')) { |
| 24317 | // export {default} from 'something'; |
| 24318 | def = new Node(); |
| 24319 | lex(); |
| 24320 | local = def.finishIdentifier('default'); |
| 24321 | } else { |
| 24322 | local = parseVariableIdentifier(); |
| 24323 | } |
| 24324 | if (matchContextualKeyword('as')) { |
| 24325 | lex(); |
| 24326 | exported = parseNonComputedProperty(); |
| 24327 | } |
| 24328 | return node.finishExportSpecifier(local, exported); |
| 24329 | } |
| 24330 | |
| 24331 | function parseExportNamedDeclaration(node) { |
| 24332 | var declaration = null, |
| 24333 | isExportFromIdentifier, |
| 24334 | src = null, specifiers = []; |
| 24335 | |
| 24336 | // non-default export |
| 24337 | if (lookahead.type === Token.Keyword) { |
| 24338 | // covers: |
| 24339 | // export var f = 1; |
| 24340 | switch (lookahead.value) { |
| 24341 | case 'let': |
| 24342 | case 'const': |
| 24343 | case 'var': |
| 24344 | case 'class': |
| 24345 | case 'function': |
| 24346 | declaration = parseStatementListItem(); |
| 24347 | return node.finishExportNamedDeclaration(declaration, specifiers, null); |
| 24348 | } |
| 24349 | } |
| 24350 | |
| 24351 | expect('{'); |
| 24352 | if (!match('}')) { |
| 24353 | do { |
| 24354 | isExportFromIdentifier = isExportFromIdentifier || matchKeyword('default'); |
| 24355 | specifiers.push(parseExportSpecifier()); |
| 24356 | } while (match(',') && lex()); |
| 24357 | } |
| 24358 | expect('}'); |
| 24359 | |
| 24360 | if (matchContextualKeyword('from')) { |
| 24361 | // covering: |
| 24362 | // export {default} from 'foo'; |
| 24363 | // export {foo} from 'foo'; |
| 24364 | lex(); |
| 24365 | src = parseModuleSpecifier(); |
| 24366 | consumeSemicolon(); |
| 24367 | } else if (isExportFromIdentifier) { |
| 24368 | // covering: |
| 24369 | // export {default}; // missing fromClause |
| 24370 | throwError(lookahead.value ? |
| 24371 | Messages.UnexpectedToken : Messages.MissingFromClause, lookahead.value); |
| 24372 | } else { |
| 24373 | // cover |
| 24374 | // export {foo}; |
| 24375 | consumeSemicolon(); |
| 24376 | } |
| 24377 | return node.finishExportNamedDeclaration(declaration, specifiers, src); |
| 24378 | } |
| 24379 | |
| 24380 | function parseExportDefaultDeclaration(node) { |
| 24381 | var declaration = null, |
| 24382 | expression = null; |
| 24383 | |
| 24384 | // covers: |
| 24385 | // export default ... |
| 24386 | expectKeyword('default'); |
| 24387 | |
| 24388 | if (matchKeyword('function')) { |
| 24389 | // covers: |
| 24390 | // export default function foo () {} |
| 24391 | // export default function () {} |
| 24392 | declaration = parseFunctionDeclaration(new Node(), true); |
| 24393 | return node.finishExportDefaultDeclaration(declaration); |
| 24394 | } |
| 24395 | if (matchKeyword('class')) { |
| 24396 | declaration = parseClassDeclaration(true); |
| 24397 | return node.finishExportDefaultDeclaration(declaration); |
| 24398 | } |
| 24399 | |
| 24400 | if (matchContextualKeyword('from')) { |
| 24401 | throwError(Messages.UnexpectedToken, lookahead.value); |
| 24402 | } |
| 24403 | |
| 24404 | // covers: |
| 24405 | // export default {}; |
| 24406 | // export default []; |
| 24407 | // export default (1 + 2); |
| 24408 | if (match('{')) { |
| 24409 | expression = parseObjectInitialiser(); |
| 24410 | } else if (match('[')) { |
| 24411 | expression = parseArrayInitialiser(); |
| 24412 | } else { |
| 24413 | expression = parseAssignmentExpression(); |
| 24414 | } |
| 24415 | consumeSemicolon(); |
| 24416 | return node.finishExportDefaultDeclaration(expression); |
| 24417 | } |
| 24418 | |
| 24419 | function parseExportAllDeclaration(node) { |
| 24420 | var src; |
| 24421 | |
| 24422 | // covers: |
| 24423 | // export * from 'foo'; |
| 24424 | expect('*'); |
| 24425 | if (!matchContextualKeyword('from')) { |
| 24426 | throwError(lookahead.value ? |
| 24427 | Messages.UnexpectedToken : Messages.MissingFromClause, lookahead.value); |
| 24428 | } |
| 24429 | lex(); |
| 24430 | src = parseModuleSpecifier(); |
| 24431 | consumeSemicolon(); |
| 24432 | |
| 24433 | return node.finishExportAllDeclaration(src); |
| 24434 | } |
| 24435 | |
| 24436 | function parseExportDeclaration() { |
| 24437 | var node = new Node(); |
| 24438 | if (state.inFunctionBody) { |
| 24439 | throwError(Messages.IllegalExportDeclaration); |
| 24440 | } |
| 24441 | |
| 24442 | expectKeyword('export'); |
| 24443 | |
| 24444 | if (matchKeyword('default')) { |
| 24445 | return parseExportDefaultDeclaration(node); |
| 24446 | } |
| 24447 | if (match('*')) { |
| 24448 | return parseExportAllDeclaration(node); |
| 24449 | } |
| 24450 | return parseExportNamedDeclaration(node); |
| 24451 | } |
| 24452 | |
| 24453 | function parseImportSpecifier() { |
| 24454 | // import {<foo as bar>} ...; |
| 24455 | var local, imported, node = new Node(); |
| 24456 | |
| 24457 | imported = parseNonComputedProperty(); |
| 24458 | if (matchContextualKeyword('as')) { |
| 24459 | lex(); |
| 24460 | local = parseVariableIdentifier(); |
| 24461 | } |
| 24462 | |
| 24463 | return node.finishImportSpecifier(local, imported); |
| 24464 | } |
| 24465 | |
| 24466 | function parseNamedImports() { |
| 24467 | var specifiers = []; |
| 24468 | // {foo, bar as bas} |
| 24469 | expect('{'); |
| 24470 | if (!match('}')) { |
| 24471 | do { |
| 24472 | specifiers.push(parseImportSpecifier()); |
| 24473 | } while (match(',') && lex()); |
| 24474 | } |
| 24475 | expect('}'); |
| 24476 | return specifiers; |
| 24477 | } |
| 24478 | |
| 24479 | function parseImportDefaultSpecifier() { |
| 24480 | // import <foo> ...; |
| 24481 | var local, node = new Node(); |
| 24482 | |
| 24483 | local = parseNonComputedProperty(); |
| 24484 | |
| 24485 | return node.finishImportDefaultSpecifier(local); |
| 24486 | } |
| 24487 | |
| 24488 | function parseImportNamespaceSpecifier() { |
| 24489 | // import <* as foo> ...; |
| 24490 | var local, node = new Node(); |
| 24491 | |
| 24492 | expect('*'); |
| 24493 | if (!matchContextualKeyword('as')) { |
| 24494 | throwError(Messages.NoAsAfterImportNamespace); |
| 24495 | } |
| 24496 | lex(); |
| 24497 | local = parseNonComputedProperty(); |
| 24498 | |
| 24499 | return node.finishImportNamespaceSpecifier(local); |
| 24500 | } |
| 24501 | |
| 24502 | function parseImportDeclaration() { |
| 24503 | var specifiers, src, node = new Node(); |
| 24504 | |
| 24505 | if (state.inFunctionBody) { |
| 24506 | throwError(Messages.IllegalImportDeclaration); |
| 24507 | } |
| 24508 | |
| 24509 | expectKeyword('import'); |
| 24510 | specifiers = []; |
| 24511 | |
| 24512 | if (lookahead.type === Token.StringLiteral) { |
| 24513 | // covers: |
| 24514 | // import 'foo'; |
| 24515 | src = parseModuleSpecifier(); |
| 24516 | consumeSemicolon(); |
| 24517 | return node.finishImportDeclaration(specifiers, src); |
| 24518 | } |
| 24519 | |
| 24520 | if (!matchKeyword('default') && isIdentifierName(lookahead)) { |
| 24521 | // covers: |
| 24522 | // import foo |
| 24523 | // import foo, ... |
| 24524 | specifiers.push(parseImportDefaultSpecifier()); |
| 24525 | if (match(',')) { |
| 24526 | lex(); |
| 24527 | } |
| 24528 | } |
| 24529 | if (match('*')) { |
| 24530 | // covers: |
| 24531 | // import foo, * as foo |
| 24532 | // import * as foo |
| 24533 | specifiers.push(parseImportNamespaceSpecifier()); |
| 24534 | } else if (match('{')) { |
| 24535 | // covers: |
| 24536 | // import foo, {bar} |
| 24537 | // import {bar} |
| 24538 | specifiers = specifiers.concat(parseNamedImports()); |
| 24539 | } |
| 24540 | |
| 24541 | if (!matchContextualKeyword('from')) { |
| 24542 | throwError(lookahead.value ? |
| 24543 | Messages.UnexpectedToken : Messages.MissingFromClause, lookahead.value); |
| 24544 | } |
| 24545 | lex(); |
| 24546 | src = parseModuleSpecifier(); |
| 24547 | consumeSemicolon(); |
| 24548 | |
| 24549 | return node.finishImportDeclaration(specifiers, src); |
| 24550 | } |
| 24551 | |
| 24552 | // 14 Program |
| 24553 | |
| 24554 | function parseScriptBody() { |
| 24555 | var statement, body = [], token, directive, firstRestricted; |
| 24556 | |
| 24557 | while (startIndex < length) { |
| 24558 | token = lookahead; |
| 24559 | if (token.type !== Token.StringLiteral) { |
| 24560 | break; |
| 24561 | } |
| 24562 | |
| 24563 | statement = parseStatementListItem(); |
| 24564 | body.push(statement); |
| 24565 | if (statement.expression.type !== Syntax.Literal) { |
| 24566 | // this is not directive |
| 24567 | break; |
| 24568 | } |
| 24569 | directive = source.slice(token.start + 1, token.end - 1); |
| 24570 | if (directive === 'use strict') { |
| 24571 | strict = true; |
| 24572 | if (firstRestricted) { |
| 24573 | tolerateUnexpectedToken(firstRestricted, Messages.StrictOctalLiteral); |
| 24574 | } |
| 24575 | } else { |
| 24576 | if (!firstRestricted && token.octal) { |
| 24577 | firstRestricted = token; |
| 24578 | } |
| 24579 | } |
| 24580 | } |
| 24581 | |
| 24582 | while (startIndex < length) { |
| 24583 | statement = parseStatementListItem(); |
| 24584 | /* istanbul ignore if */ |
| 24585 | if (typeof statement === 'undefined') { |
| 24586 | break; |
| 24587 | } |
| 24588 | body.push(statement); |
| 24589 | } |
| 24590 | return body; |
| 24591 | } |
| 24592 | |
| 24593 | function parseProgram() { |
| 24594 | var body, node; |
| 24595 | |
| 24596 | peek(); |
| 24597 | node = new Node(); |
| 24598 | |
| 24599 | body = parseScriptBody(); |
| 24600 | return node.finishProgram(body); |
| 24601 | } |
| 24602 | |
| 24603 | function filterTokenLocation() { |
| 24604 | var i, entry, token, tokens = []; |
| 24605 | |
| 24606 | for (i = 0; i < extra.tokens.length; ++i) { |
| 24607 | entry = extra.tokens[i]; |
| 24608 | token = { |
| 24609 | type: entry.type, |
| 24610 | value: entry.value |
| 24611 | }; |
| 24612 | if (entry.regex) { |
| 24613 | token.regex = { |
| 24614 | pattern: entry.regex.pattern, |
| 24615 | flags: entry.regex.flags |
| 24616 | }; |
| 24617 | } |
| 24618 | if (extra.range) { |
| 24619 | token.range = entry.range; |
| 24620 | } |
| 24621 | if (extra.loc) { |
| 24622 | token.loc = entry.loc; |
| 24623 | } |
| 24624 | tokens.push(token); |
| 24625 | } |
| 24626 | |
| 24627 | extra.tokens = tokens; |
| 24628 | } |
| 24629 | |
| 24630 | function tokenize(code, options) { |
| 24631 | var toString, |
| 24632 | tokens; |
| 24633 | |
| 24634 | toString = String; |
| 24635 | if (typeof code !== 'string' && !(code instanceof String)) { |
| 24636 | code = toString(code); |
| 24637 | } |
| 24638 | |
| 24639 | source = code; |
| 24640 | index = 0; |
| 24641 | lineNumber = (source.length > 0) ? 1 : 0; |
| 24642 | lineStart = 0; |
| 24643 | startIndex = index; |
| 24644 | startLineNumber = lineNumber; |
| 24645 | startLineStart = lineStart; |
| 24646 | length = source.length; |
| 24647 | lookahead = null; |
| 24648 | state = { |
| 24649 | allowIn: true, |
| 24650 | labelSet: {}, |
| 24651 | inFunctionBody: false, |
| 24652 | inIteration: false, |
| 24653 | inSwitch: false, |
| 24654 | lastCommentStart: -1, |
| 24655 | curlyStack: [] |
| 24656 | }; |
| 24657 | |
| 24658 | extra = {}; |
| 24659 | |
| 24660 | // Options matching. |
| 24661 | options = options || {}; |
| 24662 | |
| 24663 | // Of course we collect tokens here. |
| 24664 | options.tokens = true; |
| 24665 | extra.tokens = []; |
| 24666 | extra.tokenize = true; |
| 24667 | // The following two fields are necessary to compute the Regex tokens. |
| 24668 | extra.openParenToken = -1; |
| 24669 | extra.openCurlyToken = -1; |
| 24670 | |
| 24671 | extra.range = (typeof options.range === 'boolean') && options.range; |
| 24672 | extra.loc = (typeof options.loc === 'boolean') && options.loc; |
| 24673 | |
| 24674 | if (typeof options.comment === 'boolean' && options.comment) { |
| 24675 | extra.comments = []; |
| 24676 | } |
| 24677 | if (typeof options.tolerant === 'boolean' && options.tolerant) { |
| 24678 | extra.errors = []; |
| 24679 | } |
| 24680 | |
| 24681 | try { |
| 24682 | peek(); |
| 24683 | if (lookahead.type === Token.EOF) { |
| 24684 | return extra.tokens; |
| 24685 | } |
| 24686 | |
| 24687 | lex(); |
| 24688 | while (lookahead.type !== Token.EOF) { |
| 24689 | try { |
| 24690 | lex(); |
| 24691 | } catch (lexError) { |
| 24692 | if (extra.errors) { |
| 24693 | recordError(lexError); |
| 24694 | // We have to break on the first error |
| 24695 | // to avoid infinite loops. |
| 24696 | break; |
| 24697 | } else { |
| 24698 | throw lexError; |
| 24699 | } |
| 24700 | } |
| 24701 | } |
| 24702 | |
| 24703 | filterTokenLocation(); |
| 24704 | tokens = extra.tokens; |
| 24705 | if (typeof extra.comments !== 'undefined') { |
| 24706 | tokens.comments = extra.comments; |
| 24707 | } |
| 24708 | if (typeof extra.errors !== 'undefined') { |
| 24709 | tokens.errors = extra.errors; |
| 24710 | } |
| 24711 | } catch (e) { |
| 24712 | throw e; |
| 24713 | } finally { |
| 24714 | extra = {}; |
| 24715 | } |
| 24716 | return tokens; |
| 24717 | } |
| 24718 | |
| 24719 | function parse(code, options) { |
| 24720 | var program, toString; |
| 24721 | |
| 24722 | toString = String; |
| 24723 | if (typeof code !== 'string' && !(code instanceof String)) { |
| 24724 | code = toString(code); |
| 24725 | } |
| 24726 | |
| 24727 | source = code; |
| 24728 | index = 0; |
| 24729 | lineNumber = (source.length > 0) ? 1 : 0; |
| 24730 | lineStart = 0; |
| 24731 | startIndex = index; |
| 24732 | startLineNumber = lineNumber; |
| 24733 | startLineStart = lineStart; |
| 24734 | length = source.length; |
| 24735 | lookahead = null; |
| 24736 | state = { |
| 24737 | allowIn: true, |
| 24738 | labelSet: {}, |
| 24739 | inFunctionBody: false, |
| 24740 | inIteration: false, |
| 24741 | inSwitch: false, |
| 24742 | lastCommentStart: -1, |
| 24743 | curlyStack: [] |
| 24744 | }; |
| 24745 | sourceType = 'script'; |
| 24746 | strict = false; |
| 24747 | |
| 24748 | extra = {}; |
| 24749 | if (typeof options !== 'undefined') { |
| 24750 | extra.range = (typeof options.range === 'boolean') && options.range; |
| 24751 | extra.loc = (typeof options.loc === 'boolean') && options.loc; |
| 24752 | extra.attachComment = (typeof options.attachComment === 'boolean') && options.attachComment; |
| 24753 | |
| 24754 | if (extra.loc && options.source !== null && options.source !== undefined) { |
| 24755 | extra.source = toString(options.source); |
| 24756 | } |
| 24757 | |
| 24758 | if (typeof options.tokens === 'boolean' && options.tokens) { |
| 24759 | extra.tokens = []; |
| 24760 | } |
| 24761 | if (typeof options.comment === 'boolean' && options.comment) { |
| 24762 | extra.comments = []; |
| 24763 | } |
| 24764 | if (typeof options.tolerant === 'boolean' && options.tolerant) { |
| 24765 | extra.errors = []; |
| 24766 | } |
| 24767 | if (extra.attachComment) { |
| 24768 | extra.range = true; |
| 24769 | extra.comments = []; |
| 24770 | extra.bottomRightStack = []; |
| 24771 | extra.trailingComments = []; |
| 24772 | extra.leadingComments = []; |
| 24773 | } |
| 24774 | if (options.sourceType === 'module') { |
| 24775 | // very restrictive condition for now |
| 24776 | sourceType = options.sourceType; |
| 24777 | strict = true; |
| 24778 | } |
| 24779 | } |
| 24780 | |
| 24781 | try { |
| 24782 | program = parseProgram(); |
| 24783 | if (typeof extra.comments !== 'undefined') { |
| 24784 | program.comments = extra.comments; |
| 24785 | } |
| 24786 | if (typeof extra.tokens !== 'undefined') { |
| 24787 | filterTokenLocation(); |
| 24788 | program.tokens = extra.tokens; |
| 24789 | } |
| 24790 | if (typeof extra.errors !== 'undefined') { |
| 24791 | program.errors = extra.errors; |
| 24792 | } |
| 24793 | } catch (e) { |
| 24794 | throw e; |
| 24795 | } finally { |
| 24796 | extra = {}; |
| 24797 | } |
| 24798 | |
| 24799 | return program; |
| 24800 | } |
| 24801 | |
| 24802 | // Sync with *.json manifests. |
| 24803 | exports.version = '2.2.0'; |
| 24804 | |
| 24805 | exports.tokenize = tokenize; |
| 24806 | |
| 24807 | exports.parse = parse; |
| 24808 | |
| 24809 | // Deep copy. |
| 24810 | /* istanbul ignore next */ |
| 24811 | exports.Syntax = (function () { |
| 24812 | var name, types = {}; |
| 24813 | |
| 24814 | if (typeof Object.create === 'function') { |
| 24815 | types = Object.create(null); |
| 24816 | } |
| 24817 | |
| 24818 | for (name in Syntax) { |
| 24819 | if (Syntax.hasOwnProperty(name)) { |
| 24820 | types[name] = Syntax[name]; |
| 24821 | } |
| 24822 | } |
| 24823 | |
| 24824 | if (typeof Object.freeze === 'function') { |
| 24825 | Object.freeze(types); |
| 24826 | } |
| 24827 | |
| 24828 | return types; |
| 24829 | }()); |
| 24830 | |
| 24831 | })); |
| 24832 | /* vim: set sw=4 ts=4 et tw=80 : */ |
| 24833 | |
| 24834 | },{}],51:[function(require,module,exports){ |
| 24835 | var baseIndexOf = require('../internal/baseIndexOf'), |
| 24836 | binaryIndex = require('../internal/binaryIndex'); |
| 24837 | |
| 24838 | /* Native method references for those with the same name as other `lodash` methods. */ |
| 24839 | var nativeMax = Math.max; |
| 24840 | |
| 24841 | /** |
| 24842 | * Gets the index at which the first occurrence of `value` is found in `array` |
| 24843 | * using [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) |
| 24844 | * for equality comparisons. If `fromIndex` is negative, it is used as the offset |
| 24845 | * from the end of `array`. If `array` is sorted providing `true` for `fromIndex` |
| 24846 | * performs a faster binary search. |
| 24847 | * |
| 24848 | * @static |
| 24849 | * @memberOf _ |
| 24850 | * @category Array |
| 24851 | * @param {Array} array The array to search. |
| 24852 | * @param {*} value The value to search for. |
| 24853 | * @param {boolean|number} [fromIndex=0] The index to search from or `true` |
| 24854 | * to perform a binary search on a sorted array. |
| 24855 | * @returns {number} Returns the index of the matched value, else `-1`. |
| 24856 | * @example |
| 24857 | * |
| 24858 | * _.indexOf([1, 2, 1, 2], 2); |
| 24859 | * // => 1 |
| 24860 | * |
| 24861 | * // using `fromIndex` |
| 24862 | * _.indexOf([1, 2, 1, 2], 2, 2); |
| 24863 | * // => 3 |
| 24864 | * |
| 24865 | * // performing a binary search |
| 24866 | * _.indexOf([1, 1, 2, 2], 2, true); |
| 24867 | * // => 2 |
| 24868 | */ |
| 24869 | function indexOf(array, value, fromIndex) { |
| 24870 | var length = array ? array.length : 0; |
| 24871 | if (!length) { |
| 24872 | return -1; |
| 24873 | } |
| 24874 | if (typeof fromIndex == 'number') { |
| 24875 | fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex; |
| 24876 | } else if (fromIndex) { |
| 24877 | var index = binaryIndex(array, value), |
| 24878 | other = array[index]; |
| 24879 | |
| 24880 | if (value === value ? (value === other) : (other !== other)) { |
| 24881 | return index; |
| 24882 | } |
| 24883 | return -1; |
| 24884 | } |
| 24885 | return baseIndexOf(array, value, fromIndex || 0); |
| 24886 | } |
| 24887 | |
| 24888 | module.exports = indexOf; |
| 24889 | |
| 24890 | },{"../internal/baseIndexOf":80,"../internal/binaryIndex":95}],52:[function(require,module,exports){ |
| 24891 | /** |
| 24892 | * Gets the last element of `array`. |
| 24893 | * |
| 24894 | * @static |
| 24895 | * @memberOf _ |
| 24896 | * @category Array |
| 24897 | * @param {Array} array The array to query. |
| 24898 | * @returns {*} Returns the last element of `array`. |
| 24899 | * @example |
| 24900 | * |
| 24901 | * _.last([1, 2, 3]); |
| 24902 | * // => 3 |
| 24903 | */ |
| 24904 | function last(array) { |
| 24905 | var length = array ? array.length : 0; |
| 24906 | return length ? array[length - 1] : undefined; |
| 24907 | } |
| 24908 | |
| 24909 | module.exports = last; |
| 24910 | |
| 24911 | },{}],53:[function(require,module,exports){ |
| 24912 | var LazyWrapper = require('../internal/LazyWrapper'), |
| 24913 | LodashWrapper = require('../internal/LodashWrapper'), |
| 24914 | baseLodash = require('../internal/baseLodash'), |
| 24915 | isArray = require('../lang/isArray'), |
| 24916 | isObjectLike = require('../internal/isObjectLike'), |
| 24917 | wrapperClone = require('../internal/wrapperClone'); |
| 24918 | |
| 24919 | /** Used for native method references. */ |
| 24920 | var objectProto = Object.prototype; |
| 24921 | |
| 24922 | /** Used to check objects for own properties. */ |
| 24923 | var hasOwnProperty = objectProto.hasOwnProperty; |
| 24924 | |
| 24925 | /** |
| 24926 | * Creates a `lodash` object which wraps `value` to enable implicit chaining. |
| 24927 | * Methods that operate on and return arrays, collections, and functions can |
| 24928 | * be chained together. Methods that return a boolean or single value will |
| 24929 | * automatically end the chain returning the unwrapped value. Explicit chaining |
| 24930 | * may be enabled using `_.chain`. The execution of chained methods is lazy, |
| 24931 | * that is, execution is deferred until `_#value` is implicitly or explicitly |
| 24932 | * called. |
| 24933 | * |
| 24934 | * Lazy evaluation allows several methods to support shortcut fusion. Shortcut |
| 24935 | * fusion is an optimization that merges iteratees to avoid creating intermediate |
| 24936 | * arrays and reduce the number of iteratee executions. |
| 24937 | * |
| 24938 | * Chaining is supported in custom builds as long as the `_#value` method is |
| 24939 | * directly or indirectly included in the build. |
| 24940 | * |
| 24941 | * In addition to lodash methods, wrappers have `Array` and `String` methods. |
| 24942 | * |
| 24943 | * The wrapper `Array` methods are: |
| 24944 | * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, |
| 24945 | * `splice`, and `unshift` |
| 24946 | * |
| 24947 | * The wrapper `String` methods are: |
| 24948 | * `replace` and `split` |
| 24949 | * |
| 24950 | * The wrapper methods that support shortcut fusion are: |
| 24951 | * `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`, |
| 24952 | * `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`, |
| 24953 | * `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`, |
| 24954 | * and `where` |
| 24955 | * |
| 24956 | * The chainable wrapper methods are: |
| 24957 | * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`, |
| 24958 | * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`, |
| 24959 | * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defer`, `delay`, |
| 24960 | * `difference`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `fill`, |
| 24961 | * `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`, `forEach`, |
| 24962 | * `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `functions`, |
| 24963 | * `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, `invoke`, `keys`, |
| 24964 | * `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, |
| 24965 | * `memoize`, `merge`, `method`, `methodOf`, `mixin`, `negate`, `omit`, `once`, |
| 24966 | * `pairs`, `partial`, `partialRight`, `partition`, `pick`, `plant`, `pluck`, |
| 24967 | * `property`, `propertyOf`, `pull`, `pullAt`, `push`, `range`, `rearg`, |
| 24968 | * `reject`, `remove`, `rest`, `restParam`, `reverse`, `set`, `shuffle`, |
| 24969 | * `slice`, `sort`, `sortBy`, `sortByAll`, `sortByOrder`, `splice`, `spread`, |
| 24970 | * `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`, |
| 24971 | * `thru`, `times`, `toArray`, `toPlainObject`, `transform`, `union`, `uniq`, |
| 24972 | * `unshift`, `unzip`, `unzipWith`, `values`, `valuesIn`, `where`, `without`, |
| 24973 | * `wrap`, `xor`, `zip`, `zipObject`, `zipWith` |
| 24974 | * |
| 24975 | * The wrapper methods that are **not** chainable by default are: |
| 24976 | * `add`, `attempt`, `camelCase`, `capitalize`, `clone`, `cloneDeep`, `deburr`, |
| 24977 | * `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, |
| 24978 | * `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, `get`, |
| 24979 | * `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`, `inRange`, `isArguments`, |
| 24980 | * `isArray`, `isBoolean`, `isDate`, `isElement`, `isEmpty`, `isEqual`, `isError`, |
| 24981 | * `isFinite` `isFunction`, `isMatch`, `isNative`, `isNaN`, `isNull`, `isNumber`, |
| 24982 | * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, |
| 24983 | * `isTypedArray`, `join`, `kebabCase`, `last`, `lastIndexOf`, `lt`, `lte`, |
| 24984 | * `max`, `min`, `noConflict`, `noop`, `now`, `pad`, `padLeft`, `padRight`, |
| 24985 | * `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, `repeat`, `result`, |
| 24986 | * `runInContext`, `shift`, `size`, `snakeCase`, `some`, `sortedIndex`, |
| 24987 | * `sortedLastIndex`, `startCase`, `startsWith`, `sum`, `template`, `trim`, |
| 24988 | * `trimLeft`, `trimRight`, `trunc`, `unescape`, `uniqueId`, `value`, and `words` |
| 24989 | * |
| 24990 | * The wrapper method `sample` will return a wrapped value when `n` is provided, |
| 24991 | * otherwise an unwrapped value is returned. |
| 24992 | * |
| 24993 | * @name _ |
| 24994 | * @constructor |
| 24995 | * @category Chain |
| 24996 | * @param {*} value The value to wrap in a `lodash` instance. |
| 24997 | * @returns {Object} Returns the new `lodash` wrapper instance. |
| 24998 | * @example |
| 24999 | * |
| 25000 | * var wrapped = _([1, 2, 3]); |
| 25001 | * |
| 25002 | * // returns an unwrapped value |
| 25003 | * wrapped.reduce(function(total, n) { |
| 25004 | * return total + n; |
| 25005 | * }); |
| 25006 | * // => 6 |
| 25007 | * |
| 25008 | * // returns a wrapped value |
| 25009 | * var squares = wrapped.map(function(n) { |
| 25010 | * return n * n; |
| 25011 | * }); |
| 25012 | * |
| 25013 | * _.isArray(squares); |
| 25014 | * // => false |
| 25015 | * |
| 25016 | * _.isArray(squares.value()); |
| 25017 | * // => true |
| 25018 | */ |
| 25019 | function lodash(value) { |
| 25020 | if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { |
| 25021 | if (value instanceof LodashWrapper) { |
| 25022 | return value; |
| 25023 | } |
| 25024 | if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) { |
| 25025 | return wrapperClone(value); |
| 25026 | } |
| 25027 | } |
| 25028 | return new LodashWrapper(value); |
| 25029 | } |
| 25030 | |
| 25031 | // Ensure wrappers are instances of `baseLodash`. |
| 25032 | lodash.prototype = baseLodash.prototype; |
| 25033 | |
| 25034 | module.exports = lodash; |
| 25035 | |
| 25036 | },{"../internal/LazyWrapper":62,"../internal/LodashWrapper":63,"../internal/baseLodash":85,"../internal/isObjectLike":129,"../internal/wrapperClone":141,"../lang/isArray":144}],54:[function(require,module,exports){ |
| 25037 | module.exports = require('./forEach'); |
| 25038 | |
| 25039 | },{"./forEach":56}],55:[function(require,module,exports){ |
| 25040 | var baseEach = require('../internal/baseEach'), |
| 25041 | createFind = require('../internal/createFind'); |
| 25042 | |
| 25043 | /** |
| 25044 | * Iterates over elements of `collection`, returning the first element |
| 25045 | * `predicate` returns truthy for. The predicate is bound to `thisArg` and |
| 25046 | * invoked with three arguments: (value, index|key, collection). |
| 25047 | * |
| 25048 | * If a property name is provided for `predicate` the created `_.property` |
| 25049 | * style callback returns the property value of the given element. |
| 25050 | * |
| 25051 | * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| 25052 | * style callback returns `true` for elements that have a matching property |
| 25053 | * value, else `false`. |
| 25054 | * |
| 25055 | * If an object is provided for `predicate` the created `_.matches` style |
| 25056 | * callback returns `true` for elements that have the properties of the given |
| 25057 | * object, else `false`. |
| 25058 | * |
| 25059 | * @static |
| 25060 | * @memberOf _ |
| 25061 | * @alias detect |
| 25062 | * @category Collection |
| 25063 | * @param {Array|Object|string} collection The collection to search. |
| 25064 | * @param {Function|Object|string} [predicate=_.identity] The function invoked |
| 25065 | * per iteration. |
| 25066 | * @param {*} [thisArg] The `this` binding of `predicate`. |
| 25067 | * @returns {*} Returns the matched element, else `undefined`. |
| 25068 | * @example |
| 25069 | * |
| 25070 | * var users = [ |
| 25071 | * { 'user': 'barney', 'age': 36, 'active': true }, |
| 25072 | * { 'user': 'fred', 'age': 40, 'active': false }, |
| 25073 | * { 'user': 'pebbles', 'age': 1, 'active': true } |
| 25074 | * ]; |
| 25075 | * |
| 25076 | * _.result(_.find(users, function(chr) { |
| 25077 | * return chr.age < 40; |
| 25078 | * }), 'user'); |
| 25079 | * // => 'barney' |
| 25080 | * |
| 25081 | * // using the `_.matches` callback shorthand |
| 25082 | * _.result(_.find(users, { 'age': 1, 'active': true }), 'user'); |
| 25083 | * // => 'pebbles' |
| 25084 | * |
| 25085 | * // using the `_.matchesProperty` callback shorthand |
| 25086 | * _.result(_.find(users, 'active', false), 'user'); |
| 25087 | * // => 'fred' |
| 25088 | * |
| 25089 | * // using the `_.property` callback shorthand |
| 25090 | * _.result(_.find(users, 'active'), 'user'); |
| 25091 | * // => 'barney' |
| 25092 | */ |
| 25093 | var find = createFind(baseEach); |
| 25094 | |
| 25095 | module.exports = find; |
| 25096 | |
| 25097 | },{"../internal/baseEach":73,"../internal/createFind":105}],56:[function(require,module,exports){ |
| 25098 | var arrayEach = require('../internal/arrayEach'), |
| 25099 | baseEach = require('../internal/baseEach'), |
| 25100 | createForEach = require('../internal/createForEach'); |
| 25101 | |
| 25102 | /** |
| 25103 | * Iterates over elements of `collection` invoking `iteratee` for each element. |
| 25104 | * The `iteratee` is bound to `thisArg` and invoked with three arguments: |
| 25105 | * (value, index|key, collection). Iteratee functions may exit iteration early |
| 25106 | * by explicitly returning `false`. |
| 25107 | * |
| 25108 | * **Note:** As with other "Collections" methods, objects with a "length" property |
| 25109 | * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` |
| 25110 | * may be used for object iteration. |
| 25111 | * |
| 25112 | * @static |
| 25113 | * @memberOf _ |
| 25114 | * @alias each |
| 25115 | * @category Collection |
| 25116 | * @param {Array|Object|string} collection The collection to iterate over. |
| 25117 | * @param {Function} [iteratee=_.identity] The function invoked per iteration. |
| 25118 | * @param {*} [thisArg] The `this` binding of `iteratee`. |
| 25119 | * @returns {Array|Object|string} Returns `collection`. |
| 25120 | * @example |
| 25121 | * |
| 25122 | * _([1, 2]).forEach(function(n) { |
| 25123 | * console.log(n); |
| 25124 | * }).value(); |
| 25125 | * // => logs each value from left to right and returns the array |
| 25126 | * |
| 25127 | * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) { |
| 25128 | * console.log(n, key); |
| 25129 | * }); |
| 25130 | * // => logs each value-key pair and returns the object (iteration order is not guaranteed) |
| 25131 | */ |
| 25132 | var forEach = createForEach(arrayEach, baseEach); |
| 25133 | |
| 25134 | module.exports = forEach; |
| 25135 | |
| 25136 | },{"../internal/arrayEach":65,"../internal/baseEach":73,"../internal/createForEach":106}],57:[function(require,module,exports){ |
| 25137 | var baseIndexOf = require('../internal/baseIndexOf'), |
| 25138 | getLength = require('../internal/getLength'), |
| 25139 | isArray = require('../lang/isArray'), |
| 25140 | isIterateeCall = require('../internal/isIterateeCall'), |
| 25141 | isLength = require('../internal/isLength'), |
| 25142 | isString = require('../lang/isString'), |
| 25143 | values = require('../object/values'); |
| 25144 | |
| 25145 | /* Native method references for those with the same name as other `lodash` methods. */ |
| 25146 | var nativeMax = Math.max; |
| 25147 | |
| 25148 | /** |
| 25149 | * Checks if `value` is in `collection` using |
| 25150 | * [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) |
| 25151 | * for equality comparisons. If `fromIndex` is negative, it is used as the offset |
| 25152 | * from the end of `collection`. |
| 25153 | * |
| 25154 | * @static |
| 25155 | * @memberOf _ |
| 25156 | * @alias contains, include |
| 25157 | * @category Collection |
| 25158 | * @param {Array|Object|string} collection The collection to search. |
| 25159 | * @param {*} target The value to search for. |
| 25160 | * @param {number} [fromIndex=0] The index to search from. |
| 25161 | * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. |
| 25162 | * @returns {boolean} Returns `true` if a matching element is found, else `false`. |
| 25163 | * @example |
| 25164 | * |
| 25165 | * _.includes([1, 2, 3], 1); |
| 25166 | * // => true |
| 25167 | * |
| 25168 | * _.includes([1, 2, 3], 1, 2); |
| 25169 | * // => false |
| 25170 | * |
| 25171 | * _.includes({ 'user': 'fred', 'age': 40 }, 'fred'); |
| 25172 | * // => true |
| 25173 | * |
| 25174 | * _.includes('pebbles', 'eb'); |
| 25175 | * // => true |
| 25176 | */ |
| 25177 | function includes(collection, target, fromIndex, guard) { |
| 25178 | var length = collection ? getLength(collection) : 0; |
| 25179 | if (!isLength(length)) { |
| 25180 | collection = values(collection); |
| 25181 | length = collection.length; |
| 25182 | } |
| 25183 | if (!length) { |
| 25184 | return false; |
| 25185 | } |
| 25186 | if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) { |
| 25187 | fromIndex = 0; |
| 25188 | } else { |
| 25189 | fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0); |
| 25190 | } |
| 25191 | return (typeof collection == 'string' || !isArray(collection) && isString(collection)) |
| 25192 | ? (fromIndex < length && collection.indexOf(target, fromIndex) > -1) |
| 25193 | : (baseIndexOf(collection, target, fromIndex) > -1); |
| 25194 | } |
| 25195 | |
| 25196 | module.exports = includes; |
| 25197 | |
| 25198 | },{"../internal/baseIndexOf":80,"../internal/getLength":115,"../internal/isIterateeCall":125,"../internal/isLength":128,"../lang/isArray":144,"../lang/isString":150,"../object/values":156}],58:[function(require,module,exports){ |
| 25199 | var arrayMap = require('../internal/arrayMap'), |
| 25200 | baseCallback = require('../internal/baseCallback'), |
| 25201 | baseMap = require('../internal/baseMap'), |
| 25202 | isArray = require('../lang/isArray'); |
| 25203 | |
| 25204 | /** |
| 25205 | * Creates an array of values by running each element in `collection` through |
| 25206 | * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three |
| 25207 | * arguments: (value, index|key, collection). |
| 25208 | * |
| 25209 | * If a property name is provided for `iteratee` the created `_.property` |
| 25210 | * style callback returns the property value of the given element. |
| 25211 | * |
| 25212 | * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| 25213 | * style callback returns `true` for elements that have a matching property |
| 25214 | * value, else `false`. |
| 25215 | * |
| 25216 | * If an object is provided for `iteratee` the created `_.matches` style |
| 25217 | * callback returns `true` for elements that have the properties of the given |
| 25218 | * object, else `false`. |
| 25219 | * |
| 25220 | * Many lodash methods are guarded to work as iteratees for methods like |
| 25221 | * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. |
| 25222 | * |
| 25223 | * The guarded methods are: |
| 25224 | * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`, |
| 25225 | * `drop`, `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`, |
| 25226 | * `parseInt`, `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`, |
| 25227 | * `trimLeft`, `trimRight`, `trunc`, `random`, `range`, `sample`, `some`, |
| 25228 | * `sum`, `uniq`, and `words` |
| 25229 | * |
| 25230 | * @static |
| 25231 | * @memberOf _ |
| 25232 | * @alias collect |
| 25233 | * @category Collection |
| 25234 | * @param {Array|Object|string} collection The collection to iterate over. |
| 25235 | * @param {Function|Object|string} [iteratee=_.identity] The function invoked |
| 25236 | * per iteration. |
| 25237 | * @param {*} [thisArg] The `this` binding of `iteratee`. |
| 25238 | * @returns {Array} Returns the new mapped array. |
| 25239 | * @example |
| 25240 | * |
| 25241 | * function timesThree(n) { |
| 25242 | * return n * 3; |
| 25243 | * } |
| 25244 | * |
| 25245 | * _.map([1, 2], timesThree); |
| 25246 | * // => [3, 6] |
| 25247 | * |
| 25248 | * _.map({ 'a': 1, 'b': 2 }, timesThree); |
| 25249 | * // => [3, 6] (iteration order is not guaranteed) |
| 25250 | * |
| 25251 | * var users = [ |
| 25252 | * { 'user': 'barney' }, |
| 25253 | * { 'user': 'fred' } |
| 25254 | * ]; |
| 25255 | * |
| 25256 | * // using the `_.property` callback shorthand |
| 25257 | * _.map(users, 'user'); |
| 25258 | * // => ['barney', 'fred'] |
| 25259 | */ |
| 25260 | function map(collection, iteratee, thisArg) { |
| 25261 | var func = isArray(collection) ? arrayMap : baseMap; |
| 25262 | iteratee = baseCallback(iteratee, thisArg, 3); |
| 25263 | return func(collection, iteratee); |
| 25264 | } |
| 25265 | |
| 25266 | module.exports = map; |
| 25267 | |
| 25268 | },{"../internal/arrayMap":66,"../internal/baseCallback":69,"../internal/baseMap":86,"../lang/isArray":144}],59:[function(require,module,exports){ |
| 25269 | var getNative = require('../internal/getNative'); |
| 25270 | |
| 25271 | /* Native method references for those with the same name as other `lodash` methods. */ |
| 25272 | var nativeNow = getNative(Date, 'now'); |
| 25273 | |
| 25274 | /** |
| 25275 | * Gets the number of milliseconds that have elapsed since the Unix epoch |
| 25276 | * (1 January 1970 00:00:00 UTC). |
| 25277 | * |
| 25278 | * @static |
| 25279 | * @memberOf _ |
| 25280 | * @category Date |
| 25281 | * @example |
| 25282 | * |
| 25283 | * _.defer(function(stamp) { |
| 25284 | * console.log(_.now() - stamp); |
| 25285 | * }, _.now()); |
| 25286 | * // => logs the number of milliseconds it took for the deferred function to be invoked |
| 25287 | */ |
| 25288 | var now = nativeNow || function() { |
| 25289 | return new Date().getTime(); |
| 25290 | }; |
| 25291 | |
| 25292 | module.exports = now; |
| 25293 | |
| 25294 | },{"../internal/getNative":117}],60:[function(require,module,exports){ |
| 25295 | var createWrapper = require('../internal/createWrapper'), |
| 25296 | replaceHolders = require('../internal/replaceHolders'), |
| 25297 | restParam = require('./restParam'); |
| 25298 | |
| 25299 | /** Used to compose bitmasks for wrapper metadata. */ |
| 25300 | var BIND_FLAG = 1, |
| 25301 | PARTIAL_FLAG = 32; |
| 25302 | |
| 25303 | /** |
| 25304 | * Creates a function that invokes `func` with the `this` binding of `thisArg` |
| 25305 | * and prepends any additional `_.bind` arguments to those provided to the |
| 25306 | * bound function. |
| 25307 | * |
| 25308 | * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, |
| 25309 | * may be used as a placeholder for partially applied arguments. |
| 25310 | * |
| 25311 | * **Note:** Unlike native `Function#bind` this method does not set the "length" |
| 25312 | * property of bound functions. |
| 25313 | * |
| 25314 | * @static |
| 25315 | * @memberOf _ |
| 25316 | * @category Function |
| 25317 | * @param {Function} func The function to bind. |
| 25318 | * @param {*} thisArg The `this` binding of `func`. |
| 25319 | * @param {...*} [partials] The arguments to be partially applied. |
| 25320 | * @returns {Function} Returns the new bound function. |
| 25321 | * @example |
| 25322 | * |
| 25323 | * var greet = function(greeting, punctuation) { |
| 25324 | * return greeting + ' ' + this.user + punctuation; |
| 25325 | * }; |
| 25326 | * |
| 25327 | * var object = { 'user': 'fred' }; |
| 25328 | * |
| 25329 | * var bound = _.bind(greet, object, 'hi'); |
| 25330 | * bound('!'); |
| 25331 | * // => 'hi fred!' |
| 25332 | * |
| 25333 | * // using placeholders |
| 25334 | * var bound = _.bind(greet, object, _, '!'); |
| 25335 | * bound('hi'); |
| 25336 | * // => 'hi fred!' |
| 25337 | */ |
| 25338 | var bind = restParam(function(func, thisArg, partials) { |
| 25339 | var bitmask = BIND_FLAG; |
| 25340 | if (partials.length) { |
| 25341 | var holders = replaceHolders(partials, bind.placeholder); |
| 25342 | bitmask |= PARTIAL_FLAG; |
| 25343 | } |
| 25344 | return createWrapper(func, bitmask, thisArg, partials, holders); |
| 25345 | }); |
| 25346 | |
| 25347 | // Assign default placeholders. |
| 25348 | bind.placeholder = {}; |
| 25349 | |
| 25350 | module.exports = bind; |
| 25351 | |
| 25352 | },{"../internal/createWrapper":109,"../internal/replaceHolders":135,"./restParam":61}],61:[function(require,module,exports){ |
| 25353 | /** Used as the `TypeError` message for "Functions" methods. */ |
| 25354 | var FUNC_ERROR_TEXT = 'Expected a function'; |
| 25355 | |
| 25356 | /* Native method references for those with the same name as other `lodash` methods. */ |
| 25357 | var nativeMax = Math.max; |
| 25358 | |
| 25359 | /** |
| 25360 | * Creates a function that invokes `func` with the `this` binding of the |
| 25361 | * created function and arguments from `start` and beyond provided as an array. |
| 25362 | * |
| 25363 | * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters). |
| 25364 | * |
| 25365 | * @static |
| 25366 | * @memberOf _ |
| 25367 | * @category Function |
| 25368 | * @param {Function} func The function to apply a rest parameter to. |
| 25369 | * @param {number} [start=func.length-1] The start position of the rest parameter. |
| 25370 | * @returns {Function} Returns the new function. |
| 25371 | * @example |
| 25372 | * |
| 25373 | * var say = _.restParam(function(what, names) { |
| 25374 | * return what + ' ' + _.initial(names).join(', ') + |
| 25375 | * (_.size(names) > 1 ? ', & ' : '') + _.last(names); |
| 25376 | * }); |
| 25377 | * |
| 25378 | * say('hello', 'fred', 'barney', 'pebbles'); |
| 25379 | * // => 'hello fred, barney, & pebbles' |
| 25380 | */ |
| 25381 | function restParam(func, start) { |
| 25382 | if (typeof func != 'function') { |
| 25383 | throw new TypeError(FUNC_ERROR_TEXT); |
| 25384 | } |
| 25385 | start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0); |
| 25386 | return function() { |
| 25387 | var args = arguments, |
| 25388 | index = -1, |
| 25389 | length = nativeMax(args.length - start, 0), |
| 25390 | rest = Array(length); |
| 25391 | |
| 25392 | while (++index < length) { |
| 25393 | rest[index] = args[start + index]; |
| 25394 | } |
| 25395 | switch (start) { |
| 25396 | case 0: return func.call(this, rest); |
| 25397 | case 1: return func.call(this, args[0], rest); |
| 25398 | case 2: return func.call(this, args[0], args[1], rest); |
| 25399 | } |
| 25400 | var otherArgs = Array(start + 1); |
| 25401 | index = -1; |
| 25402 | while (++index < start) { |
| 25403 | otherArgs[index] = args[index]; |
| 25404 | } |
| 25405 | otherArgs[start] = rest; |
| 25406 | return func.apply(this, otherArgs); |
| 25407 | }; |
| 25408 | } |
| 25409 | |
| 25410 | module.exports = restParam; |
| 25411 | |
| 25412 | },{}],62:[function(require,module,exports){ |
| 25413 | var baseCreate = require('./baseCreate'), |
| 25414 | baseLodash = require('./baseLodash'); |
| 25415 | |
| 25416 | /** Used as references for `-Infinity` and `Infinity`. */ |
| 25417 | var POSITIVE_INFINITY = Number.POSITIVE_INFINITY; |
| 25418 | |
| 25419 | /** |
| 25420 | * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. |
| 25421 | * |
| 25422 | * @private |
| 25423 | * @param {*} value The value to wrap. |
| 25424 | */ |
| 25425 | function LazyWrapper(value) { |
| 25426 | this.__wrapped__ = value; |
| 25427 | this.__actions__ = null; |
| 25428 | this.__dir__ = 1; |
| 25429 | this.__dropCount__ = 0; |
| 25430 | this.__filtered__ = false; |
| 25431 | this.__iteratees__ = null; |
| 25432 | this.__takeCount__ = POSITIVE_INFINITY; |
| 25433 | this.__views__ = null; |
| 25434 | } |
| 25435 | |
| 25436 | LazyWrapper.prototype = baseCreate(baseLodash.prototype); |
| 25437 | LazyWrapper.prototype.constructor = LazyWrapper; |
| 25438 | |
| 25439 | module.exports = LazyWrapper; |
| 25440 | |
| 25441 | },{"./baseCreate":72,"./baseLodash":85}],63:[function(require,module,exports){ |
| 25442 | var baseCreate = require('./baseCreate'), |
| 25443 | baseLodash = require('./baseLodash'); |
| 25444 | |
| 25445 | /** |
| 25446 | * The base constructor for creating `lodash` wrapper objects. |
| 25447 | * |
| 25448 | * @private |
| 25449 | * @param {*} value The value to wrap. |
| 25450 | * @param {boolean} [chainAll] Enable chaining for all wrapper methods. |
| 25451 | * @param {Array} [actions=[]] Actions to peform to resolve the unwrapped value. |
| 25452 | */ |
| 25453 | function LodashWrapper(value, chainAll, actions) { |
| 25454 | this.__wrapped__ = value; |
| 25455 | this.__actions__ = actions || []; |
| 25456 | this.__chain__ = !!chainAll; |
| 25457 | } |
| 25458 | |
| 25459 | LodashWrapper.prototype = baseCreate(baseLodash.prototype); |
| 25460 | LodashWrapper.prototype.constructor = LodashWrapper; |
| 25461 | |
| 25462 | module.exports = LodashWrapper; |
| 25463 | |
| 25464 | },{"./baseCreate":72,"./baseLodash":85}],64:[function(require,module,exports){ |
| 25465 | /** |
| 25466 | * Copies the values of `source` to `array`. |
| 25467 | * |
| 25468 | * @private |
| 25469 | * @param {Array} source The array to copy values from. |
| 25470 | * @param {Array} [array=[]] The array to copy values to. |
| 25471 | * @returns {Array} Returns `array`. |
| 25472 | */ |
| 25473 | function arrayCopy(source, array) { |
| 25474 | var index = -1, |
| 25475 | length = source.length; |
| 25476 | |
| 25477 | array || (array = Array(length)); |
| 25478 | while (++index < length) { |
| 25479 | array[index] = source[index]; |
| 25480 | } |
| 25481 | return array; |
| 25482 | } |
| 25483 | |
| 25484 | module.exports = arrayCopy; |
| 25485 | |
| 25486 | },{}],65:[function(require,module,exports){ |
| 25487 | /** |
| 25488 | * A specialized version of `_.forEach` for arrays without support for callback |
| 25489 | * shorthands and `this` binding. |
| 25490 | * |
| 25491 | * @private |
| 25492 | * @param {Array} array The array to iterate over. |
| 25493 | * @param {Function} iteratee The function invoked per iteration. |
| 25494 | * @returns {Array} Returns `array`. |
| 25495 | */ |
| 25496 | function arrayEach(array, iteratee) { |
| 25497 | var index = -1, |
| 25498 | length = array.length; |
| 25499 | |
| 25500 | while (++index < length) { |
| 25501 | if (iteratee(array[index], index, array) === false) { |
| 25502 | break; |
| 25503 | } |
| 25504 | } |
| 25505 | return array; |
| 25506 | } |
| 25507 | |
| 25508 | module.exports = arrayEach; |
| 25509 | |
| 25510 | },{}],66:[function(require,module,exports){ |
| 25511 | /** |
| 25512 | * A specialized version of `_.map` for arrays without support for callback |
| 25513 | * shorthands and `this` binding. |
| 25514 | * |
| 25515 | * @private |
| 25516 | * @param {Array} array The array to iterate over. |
| 25517 | * @param {Function} iteratee The function invoked per iteration. |
| 25518 | * @returns {Array} Returns the new mapped array. |
| 25519 | */ |
| 25520 | function arrayMap(array, iteratee) { |
| 25521 | var index = -1, |
| 25522 | length = array.length, |
| 25523 | result = Array(length); |
| 25524 | |
| 25525 | while (++index < length) { |
| 25526 | result[index] = iteratee(array[index], index, array); |
| 25527 | } |
| 25528 | return result; |
| 25529 | } |
| 25530 | |
| 25531 | module.exports = arrayMap; |
| 25532 | |
| 25533 | },{}],67:[function(require,module,exports){ |
| 25534 | /** |
| 25535 | * A specialized version of `_.some` for arrays without support for callback |
| 25536 | * shorthands and `this` binding. |
| 25537 | * |
| 25538 | * @private |
| 25539 | * @param {Array} array The array to iterate over. |
| 25540 | * @param {Function} predicate The function invoked per iteration. |
| 25541 | * @returns {boolean} Returns `true` if any element passes the predicate check, |
| 25542 | * else `false`. |
| 25543 | */ |
| 25544 | function arraySome(array, predicate) { |
| 25545 | var index = -1, |
| 25546 | length = array.length; |
| 25547 | |
| 25548 | while (++index < length) { |
| 25549 | if (predicate(array[index], index, array)) { |
| 25550 | return true; |
| 25551 | } |
| 25552 | } |
| 25553 | return false; |
| 25554 | } |
| 25555 | |
| 25556 | module.exports = arraySome; |
| 25557 | |
| 25558 | },{}],68:[function(require,module,exports){ |
| 25559 | var baseCopy = require('./baseCopy'), |
| 25560 | keys = require('../object/keys'); |
| 25561 | |
| 25562 | /** |
| 25563 | * The base implementation of `_.assign` without support for argument juggling, |
| 25564 | * multiple sources, and `customizer` functions. |
| 25565 | * |
| 25566 | * @private |
| 25567 | * @param {Object} object The destination object. |
| 25568 | * @param {Object} source The source object. |
| 25569 | * @returns {Object} Returns `object`. |
| 25570 | */ |
| 25571 | function baseAssign(object, source) { |
| 25572 | return source == null |
| 25573 | ? object |
| 25574 | : baseCopy(source, keys(source), object); |
| 25575 | } |
| 25576 | |
| 25577 | module.exports = baseAssign; |
| 25578 | |
| 25579 | },{"../object/keys":153,"./baseCopy":71}],69:[function(require,module,exports){ |
| 25580 | var baseMatches = require('./baseMatches'), |
| 25581 | baseMatchesProperty = require('./baseMatchesProperty'), |
| 25582 | bindCallback = require('./bindCallback'), |
| 25583 | identity = require('../utility/identity'), |
| 25584 | property = require('../utility/property'); |
| 25585 | |
| 25586 | /** |
| 25587 | * The base implementation of `_.callback` which supports specifying the |
| 25588 | * number of arguments to provide to `func`. |
| 25589 | * |
| 25590 | * @private |
| 25591 | * @param {*} [func=_.identity] The value to convert to a callback. |
| 25592 | * @param {*} [thisArg] The `this` binding of `func`. |
| 25593 | * @param {number} [argCount] The number of arguments to provide to `func`. |
| 25594 | * @returns {Function} Returns the callback. |
| 25595 | */ |
| 25596 | function baseCallback(func, thisArg, argCount) { |
| 25597 | var type = typeof func; |
| 25598 | if (type == 'function') { |
| 25599 | return thisArg === undefined |
| 25600 | ? func |
| 25601 | : bindCallback(func, thisArg, argCount); |
| 25602 | } |
| 25603 | if (func == null) { |
| 25604 | return identity; |
| 25605 | } |
| 25606 | if (type == 'object') { |
| 25607 | return baseMatches(func); |
| 25608 | } |
| 25609 | return thisArg === undefined |
| 25610 | ? property(func) |
| 25611 | : baseMatchesProperty(func, thisArg); |
| 25612 | } |
| 25613 | |
| 25614 | module.exports = baseCallback; |
| 25615 | |
| 25616 | },{"../utility/identity":160,"../utility/property":162,"./baseMatches":87,"./baseMatchesProperty":88,"./bindCallback":97}],70:[function(require,module,exports){ |
| 25617 | var arrayCopy = require('./arrayCopy'), |
| 25618 | arrayEach = require('./arrayEach'), |
| 25619 | baseAssign = require('./baseAssign'), |
| 25620 | baseForOwn = require('./baseForOwn'), |
| 25621 | initCloneArray = require('./initCloneArray'), |
| 25622 | initCloneByTag = require('./initCloneByTag'), |
| 25623 | initCloneObject = require('./initCloneObject'), |
| 25624 | isArray = require('../lang/isArray'), |
| 25625 | isHostObject = require('./isHostObject'), |
| 25626 | isObject = require('../lang/isObject'); |
| 25627 | |
| 25628 | /** `Object#toString` result references. */ |
| 25629 | var argsTag = '[object Arguments]', |
| 25630 | arrayTag = '[object Array]', |
| 25631 | boolTag = '[object Boolean]', |
| 25632 | dateTag = '[object Date]', |
| 25633 | errorTag = '[object Error]', |
| 25634 | funcTag = '[object Function]', |
| 25635 | mapTag = '[object Map]', |
| 25636 | numberTag = '[object Number]', |
| 25637 | objectTag = '[object Object]', |
| 25638 | regexpTag = '[object RegExp]', |
| 25639 | setTag = '[object Set]', |
| 25640 | stringTag = '[object String]', |
| 25641 | weakMapTag = '[object WeakMap]'; |
| 25642 | |
| 25643 | var arrayBufferTag = '[object ArrayBuffer]', |
| 25644 | float32Tag = '[object Float32Array]', |
| 25645 | float64Tag = '[object Float64Array]', |
| 25646 | int8Tag = '[object Int8Array]', |
| 25647 | int16Tag = '[object Int16Array]', |
| 25648 | int32Tag = '[object Int32Array]', |
| 25649 | uint8Tag = '[object Uint8Array]', |
| 25650 | uint8ClampedTag = '[object Uint8ClampedArray]', |
| 25651 | uint16Tag = '[object Uint16Array]', |
| 25652 | uint32Tag = '[object Uint32Array]'; |
| 25653 | |
| 25654 | /** Used to identify `toStringTag` values supported by `_.clone`. */ |
| 25655 | var cloneableTags = {}; |
| 25656 | cloneableTags[argsTag] = cloneableTags[arrayTag] = |
| 25657 | cloneableTags[arrayBufferTag] = cloneableTags[boolTag] = |
| 25658 | cloneableTags[dateTag] = cloneableTags[float32Tag] = |
| 25659 | cloneableTags[float64Tag] = cloneableTags[int8Tag] = |
| 25660 | cloneableTags[int16Tag] = cloneableTags[int32Tag] = |
| 25661 | cloneableTags[numberTag] = cloneableTags[objectTag] = |
| 25662 | cloneableTags[regexpTag] = cloneableTags[stringTag] = |
| 25663 | cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = |
| 25664 | cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; |
| 25665 | cloneableTags[errorTag] = cloneableTags[funcTag] = |
| 25666 | cloneableTags[mapTag] = cloneableTags[setTag] = |
| 25667 | cloneableTags[weakMapTag] = false; |
| 25668 | |
| 25669 | /** Used for native method references. */ |
| 25670 | var objectProto = Object.prototype; |
| 25671 | |
| 25672 | /** |
| 25673 | * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring) |
| 25674 | * of values. |
| 25675 | */ |
| 25676 | var objToString = objectProto.toString; |
| 25677 | |
| 25678 | /** |
| 25679 | * The base implementation of `_.clone` without support for argument juggling |
| 25680 | * and `this` binding `customizer` functions. |
| 25681 | * |
| 25682 | * @private |
| 25683 | * @param {*} value The value to clone. |
| 25684 | * @param {boolean} [isDeep] Specify a deep clone. |
| 25685 | * @param {Function} [customizer] The function to customize cloning values. |
| 25686 | * @param {string} [key] The key of `value`. |
| 25687 | * @param {Object} [object] The object `value` belongs to. |
| 25688 | * @param {Array} [stackA=[]] Tracks traversed source objects. |
| 25689 | * @param {Array} [stackB=[]] Associates clones with source counterparts. |
| 25690 | * @returns {*} Returns the cloned value. |
| 25691 | */ |
| 25692 | function baseClone(value, isDeep, customizer, key, object, stackA, stackB) { |
| 25693 | var result; |
| 25694 | if (customizer) { |
| 25695 | result = object ? customizer(value, key, object) : customizer(value); |
| 25696 | } |
| 25697 | if (result !== undefined) { |
| 25698 | return result; |
| 25699 | } |
| 25700 | if (!isObject(value)) { |
| 25701 | return value; |
| 25702 | } |
| 25703 | var isArr = isArray(value); |
| 25704 | if (isArr) { |
| 25705 | result = initCloneArray(value); |
| 25706 | if (!isDeep) { |
| 25707 | return arrayCopy(value, result); |
| 25708 | } |
| 25709 | } else { |
| 25710 | var tag = objToString.call(value), |
| 25711 | isFunc = tag == funcTag; |
| 25712 | |
| 25713 | if (tag == objectTag || tag == argsTag || (isFunc && !object)) { |
| 25714 | if (isHostObject(value)) { |
| 25715 | return object ? value : {}; |
| 25716 | } |
| 25717 | result = initCloneObject(isFunc ? {} : value); |
| 25718 | if (!isDeep) { |
| 25719 | return baseAssign(result, value); |
| 25720 | } |
| 25721 | } else { |
| 25722 | return cloneableTags[tag] |
| 25723 | ? initCloneByTag(value, tag, isDeep) |
| 25724 | : (object ? value : {}); |
| 25725 | } |
| 25726 | } |
| 25727 | // Check for circular references and return corresponding clone. |
| 25728 | stackA || (stackA = []); |
| 25729 | stackB || (stackB = []); |
| 25730 | |
| 25731 | var length = stackA.length; |
| 25732 | while (length--) { |
| 25733 | if (stackA[length] == value) { |
| 25734 | return stackB[length]; |
| 25735 | } |
| 25736 | } |
| 25737 | // Add the source value to the stack of traversed objects and associate it with its clone. |
| 25738 | stackA.push(value); |
| 25739 | stackB.push(result); |
| 25740 | |
| 25741 | // Recursively populate clone (susceptible to call stack limits). |
| 25742 | (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) { |
| 25743 | result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB); |
| 25744 | }); |
| 25745 | return result; |
| 25746 | } |
| 25747 | |
| 25748 | module.exports = baseClone; |
| 25749 | |
| 25750 | },{"../lang/isArray":144,"../lang/isObject":148,"./arrayCopy":64,"./arrayEach":65,"./baseAssign":68,"./baseForOwn":78,"./initCloneArray":119,"./initCloneByTag":120,"./initCloneObject":121,"./isHostObject":123}],71:[function(require,module,exports){ |
| 25751 | /** |
| 25752 | * Copies properties of `source` to `object`. |
| 25753 | * |
| 25754 | * @private |
| 25755 | * @param {Object} source The object to copy properties from. |
| 25756 | * @param {Array} props The property names to copy. |
| 25757 | * @param {Object} [object={}] The object to copy properties to. |
| 25758 | * @returns {Object} Returns `object`. |
| 25759 | */ |
| 25760 | function baseCopy(source, props, object) { |
| 25761 | object || (object = {}); |
| 25762 | |
| 25763 | var index = -1, |
| 25764 | length = props.length; |
| 25765 | |
| 25766 | while (++index < length) { |
| 25767 | var key = props[index]; |
| 25768 | object[key] = source[key]; |
| 25769 | } |
| 25770 | return object; |
| 25771 | } |
| 25772 | |
| 25773 | module.exports = baseCopy; |
| 25774 | |
| 25775 | },{}],72:[function(require,module,exports){ |
| 25776 | var isObject = require('../lang/isObject'); |
| 25777 | |
| 25778 | /** |
| 25779 | * The base implementation of `_.create` without support for assigning |
| 25780 | * properties to the created object. |
| 25781 | * |
| 25782 | * @private |
| 25783 | * @param {Object} prototype The object to inherit from. |
| 25784 | * @returns {Object} Returns the new object. |
| 25785 | */ |
| 25786 | var baseCreate = (function() { |
| 25787 | function object() {} |
| 25788 | return function(prototype) { |
| 25789 | if (isObject(prototype)) { |
| 25790 | object.prototype = prototype; |
| 25791 | var result = new object; |
| 25792 | object.prototype = null; |
| 25793 | } |
| 25794 | return result || {}; |
| 25795 | }; |
| 25796 | }()); |
| 25797 | |
| 25798 | module.exports = baseCreate; |
| 25799 | |
| 25800 | },{"../lang/isObject":148}],73:[function(require,module,exports){ |
| 25801 | var baseForOwn = require('./baseForOwn'), |
| 25802 | createBaseEach = require('./createBaseEach'); |
| 25803 | |
| 25804 | /** |
| 25805 | * The base implementation of `_.forEach` without support for callback |
| 25806 | * shorthands and `this` binding. |
| 25807 | * |
| 25808 | * @private |
| 25809 | * @param {Array|Object|string} collection The collection to iterate over. |
| 25810 | * @param {Function} iteratee The function invoked per iteration. |
| 25811 | * @returns {Array|Object|string} Returns `collection`. |
| 25812 | */ |
| 25813 | var baseEach = createBaseEach(baseForOwn); |
| 25814 | |
| 25815 | module.exports = baseEach; |
| 25816 | |
| 25817 | },{"./baseForOwn":78,"./createBaseEach":101}],74:[function(require,module,exports){ |
| 25818 | /** |
| 25819 | * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.findLastKey`, |
| 25820 | * without support for callback shorthands and `this` binding, which iterates |
| 25821 | * over `collection` using the provided `eachFunc`. |
| 25822 | * |
| 25823 | * @private |
| 25824 | * @param {Array|Object|string} collection The collection to search. |
| 25825 | * @param {Function} predicate The function invoked per iteration. |
| 25826 | * @param {Function} eachFunc The function to iterate over `collection`. |
| 25827 | * @param {boolean} [retKey] Specify returning the key of the found element |
| 25828 | * instead of the element itself. |
| 25829 | * @returns {*} Returns the found element or its key, else `undefined`. |
| 25830 | */ |
| 25831 | function baseFind(collection, predicate, eachFunc, retKey) { |
| 25832 | var result; |
| 25833 | eachFunc(collection, function(value, key, collection) { |
| 25834 | if (predicate(value, key, collection)) { |
| 25835 | result = retKey ? key : value; |
| 25836 | return false; |
| 25837 | } |
| 25838 | }); |
| 25839 | return result; |
| 25840 | } |
| 25841 | |
| 25842 | module.exports = baseFind; |
| 25843 | |
| 25844 | },{}],75:[function(require,module,exports){ |
| 25845 | /** |
| 25846 | * The base implementation of `_.findIndex` and `_.findLastIndex` without |
| 25847 | * support for callback shorthands and `this` binding. |
| 25848 | * |
| 25849 | * @private |
| 25850 | * @param {Array} array The array to search. |
| 25851 | * @param {Function} predicate The function invoked per iteration. |
| 25852 | * @param {boolean} [fromRight] Specify iterating from right to left. |
| 25853 | * @returns {number} Returns the index of the matched value, else `-1`. |
| 25854 | */ |
| 25855 | function baseFindIndex(array, predicate, fromRight) { |
| 25856 | var length = array.length, |
| 25857 | index = fromRight ? length : -1; |
| 25858 | |
| 25859 | while ((fromRight ? index-- : ++index < length)) { |
| 25860 | if (predicate(array[index], index, array)) { |
| 25861 | return index; |
| 25862 | } |
| 25863 | } |
| 25864 | return -1; |
| 25865 | } |
| 25866 | |
| 25867 | module.exports = baseFindIndex; |
| 25868 | |
| 25869 | },{}],76:[function(require,module,exports){ |
| 25870 | var createBaseFor = require('./createBaseFor'); |
| 25871 | |
| 25872 | /** |
| 25873 | * The base implementation of `baseForIn` and `baseForOwn` which iterates |
| 25874 | * over `object` properties returned by `keysFunc` invoking `iteratee` for |
| 25875 | * each property. Iteratee functions may exit iteration early by explicitly |
| 25876 | * returning `false`. |
| 25877 | * |
| 25878 | * @private |
| 25879 | * @param {Object} object The object to iterate over. |
| 25880 | * @param {Function} iteratee The function invoked per iteration. |
| 25881 | * @param {Function} keysFunc The function to get the keys of `object`. |
| 25882 | * @returns {Object} Returns `object`. |
| 25883 | */ |
| 25884 | var baseFor = createBaseFor(); |
| 25885 | |
| 25886 | module.exports = baseFor; |
| 25887 | |
| 25888 | },{"./createBaseFor":102}],77:[function(require,module,exports){ |
| 25889 | var baseFor = require('./baseFor'), |
| 25890 | keysIn = require('../object/keysIn'); |
| 25891 | |
| 25892 | /** |
| 25893 | * The base implementation of `_.forIn` without support for callback |
| 25894 | * shorthands and `this` binding. |
| 25895 | * |
| 25896 | * @private |
| 25897 | * @param {Object} object The object to iterate over. |
| 25898 | * @param {Function} iteratee The function invoked per iteration. |
| 25899 | * @returns {Object} Returns `object`. |
| 25900 | */ |
| 25901 | function baseForIn(object, iteratee) { |
| 25902 | return baseFor(object, iteratee, keysIn); |
| 25903 | } |
| 25904 | |
| 25905 | module.exports = baseForIn; |
| 25906 | |
| 25907 | },{"../object/keysIn":154,"./baseFor":76}],78:[function(require,module,exports){ |
| 25908 | var baseFor = require('./baseFor'), |
| 25909 | keys = require('../object/keys'); |
| 25910 | |
| 25911 | /** |
| 25912 | * The base implementation of `_.forOwn` without support for callback |
| 25913 | * shorthands and `this` binding. |
| 25914 | * |
| 25915 | * @private |
| 25916 | * @param {Object} object The object to iterate over. |
| 25917 | * @param {Function} iteratee The function invoked per iteration. |
| 25918 | * @returns {Object} Returns `object`. |
| 25919 | */ |
| 25920 | function baseForOwn(object, iteratee) { |
| 25921 | return baseFor(object, iteratee, keys); |
| 25922 | } |
| 25923 | |
| 25924 | module.exports = baseForOwn; |
| 25925 | |
| 25926 | },{"../object/keys":153,"./baseFor":76}],79:[function(require,module,exports){ |
| 25927 | var toObject = require('./toObject'); |
| 25928 | |
| 25929 | /** |
| 25930 | * The base implementation of `get` without support for string paths |
| 25931 | * and default values. |
| 25932 | * |
| 25933 | * @private |
| 25934 | * @param {Object} object The object to query. |
| 25935 | * @param {Array} path The path of the property to get. |
| 25936 | * @param {string} [pathKey] The key representation of path. |
| 25937 | * @returns {*} Returns the resolved value. |
| 25938 | */ |
| 25939 | function baseGet(object, path, pathKey) { |
| 25940 | if (object == null) { |
| 25941 | return; |
| 25942 | } |
| 25943 | object = toObject(object); |
| 25944 | if (pathKey !== undefined && pathKey in object) { |
| 25945 | path = [pathKey]; |
| 25946 | } |
| 25947 | var index = 0, |
| 25948 | length = path.length; |
| 25949 | |
| 25950 | while (object != null && index < length) { |
| 25951 | object = toObject(object)[path[index++]]; |
| 25952 | } |
| 25953 | return (index && index == length) ? object : undefined; |
| 25954 | } |
| 25955 | |
| 25956 | module.exports = baseGet; |
| 25957 | |
| 25958 | },{"./toObject":139}],80:[function(require,module,exports){ |
| 25959 | var indexOfNaN = require('./indexOfNaN'); |
| 25960 | |
| 25961 | /** |
| 25962 | * The base implementation of `_.indexOf` without support for binary searches. |
| 25963 | * |
| 25964 | * @private |
| 25965 | * @param {Array} array The array to search. |
| 25966 | * @param {*} value The value to search for. |
| 25967 | * @param {number} fromIndex The index to search from. |
| 25968 | * @returns {number} Returns the index of the matched value, else `-1`. |
| 25969 | */ |
| 25970 | function baseIndexOf(array, value, fromIndex) { |
| 25971 | if (value !== value) { |
| 25972 | return indexOfNaN(array, fromIndex); |
| 25973 | } |
| 25974 | var index = fromIndex - 1, |
| 25975 | length = array.length; |
| 25976 | |
| 25977 | while (++index < length) { |
| 25978 | if (array[index] === value) { |
| 25979 | return index; |
| 25980 | } |
| 25981 | } |
| 25982 | return -1; |
| 25983 | } |
| 25984 | |
| 25985 | module.exports = baseIndexOf; |
| 25986 | |
| 25987 | },{"./indexOfNaN":118}],81:[function(require,module,exports){ |
| 25988 | var baseIsEqualDeep = require('./baseIsEqualDeep'), |
| 25989 | isObject = require('../lang/isObject'), |
| 25990 | isObjectLike = require('./isObjectLike'); |
| 25991 | |
| 25992 | /** |
| 25993 | * The base implementation of `_.isEqual` without support for `this` binding |
| 25994 | * `customizer` functions. |
| 25995 | * |
| 25996 | * @private |
| 25997 | * @param {*} value The value to compare. |
| 25998 | * @param {*} other The other value to compare. |
| 25999 | * @param {Function} [customizer] The function to customize comparing values. |
| 26000 | * @param {boolean} [isLoose] Specify performing partial comparisons. |
| 26001 | * @param {Array} [stackA] Tracks traversed `value` objects. |
| 26002 | * @param {Array} [stackB] Tracks traversed `other` objects. |
| 26003 | * @returns {boolean} Returns `true` if the values are equivalent, else `false`. |
| 26004 | */ |
| 26005 | function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) { |
| 26006 | if (value === other) { |
| 26007 | return true; |
| 26008 | } |
| 26009 | if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) { |
| 26010 | return value !== value && other !== other; |
| 26011 | } |
| 26012 | return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB); |
| 26013 | } |
| 26014 | |
| 26015 | module.exports = baseIsEqual; |
| 26016 | |
| 26017 | },{"../lang/isObject":148,"./baseIsEqualDeep":82,"./isObjectLike":129}],82:[function(require,module,exports){ |
| 26018 | var equalArrays = require('./equalArrays'), |
| 26019 | equalByTag = require('./equalByTag'), |
| 26020 | equalObjects = require('./equalObjects'), |
| 26021 | isArray = require('../lang/isArray'), |
| 26022 | isHostObject = require('./isHostObject'), |
| 26023 | isTypedArray = require('../lang/isTypedArray'); |
| 26024 | |
| 26025 | /** `Object#toString` result references. */ |
| 26026 | var argsTag = '[object Arguments]', |
| 26027 | arrayTag = '[object Array]', |
| 26028 | objectTag = '[object Object]'; |
| 26029 | |
| 26030 | /** Used for native method references. */ |
| 26031 | var objectProto = Object.prototype; |
| 26032 | |
| 26033 | /** Used to check objects for own properties. */ |
| 26034 | var hasOwnProperty = objectProto.hasOwnProperty; |
| 26035 | |
| 26036 | /** |
| 26037 | * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring) |
| 26038 | * of values. |
| 26039 | */ |
| 26040 | var objToString = objectProto.toString; |
| 26041 | |
| 26042 | /** |
| 26043 | * A specialized version of `baseIsEqual` for arrays and objects which performs |
| 26044 | * deep comparisons and tracks traversed objects enabling objects with circular |
| 26045 | * references to be compared. |
| 26046 | * |
| 26047 | * @private |
| 26048 | * @param {Object} object The object to compare. |
| 26049 | * @param {Object} other The other object to compare. |
| 26050 | * @param {Function} equalFunc The function to determine equivalents of values. |
| 26051 | * @param {Function} [customizer] The function to customize comparing objects. |
| 26052 | * @param {boolean} [isLoose] Specify performing partial comparisons. |
| 26053 | * @param {Array} [stackA=[]] Tracks traversed `value` objects. |
| 26054 | * @param {Array} [stackB=[]] Tracks traversed `other` objects. |
| 26055 | * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. |
| 26056 | */ |
| 26057 | function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) { |
| 26058 | var objIsArr = isArray(object), |
| 26059 | othIsArr = isArray(other), |
| 26060 | objTag = arrayTag, |
| 26061 | othTag = arrayTag; |
| 26062 | |
| 26063 | if (!objIsArr) { |
| 26064 | objTag = objToString.call(object); |
| 26065 | if (objTag == argsTag) { |
| 26066 | objTag = objectTag; |
| 26067 | } else if (objTag != objectTag) { |
| 26068 | objIsArr = isTypedArray(object); |
| 26069 | } |
| 26070 | } |
| 26071 | if (!othIsArr) { |
| 26072 | othTag = objToString.call(other); |
| 26073 | if (othTag == argsTag) { |
| 26074 | othTag = objectTag; |
| 26075 | } else if (othTag != objectTag) { |
| 26076 | othIsArr = isTypedArray(other); |
| 26077 | } |
| 26078 | } |
| 26079 | var objIsObj = objTag == objectTag && !isHostObject(object), |
| 26080 | othIsObj = othTag == objectTag && !isHostObject(other), |
| 26081 | isSameTag = objTag == othTag; |
| 26082 | |
| 26083 | if (isSameTag && !(objIsArr || objIsObj)) { |
| 26084 | return equalByTag(object, other, objTag); |
| 26085 | } |
| 26086 | if (!isLoose) { |
| 26087 | var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), |
| 26088 | othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); |
| 26089 | |
| 26090 | if (objIsWrapped || othIsWrapped) { |
| 26091 | return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB); |
| 26092 | } |
| 26093 | } |
| 26094 | if (!isSameTag) { |
| 26095 | return false; |
| 26096 | } |
| 26097 | // Assume cyclic values are equal. |
| 26098 | // For more information on detecting circular references see https://es5.github.io/#JO. |
| 26099 | stackA || (stackA = []); |
| 26100 | stackB || (stackB = []); |
| 26101 | |
| 26102 | var length = stackA.length; |
| 26103 | while (length--) { |
| 26104 | if (stackA[length] == object) { |
| 26105 | return stackB[length] == other; |
| 26106 | } |
| 26107 | } |
| 26108 | // Add `object` and `other` to the stack of traversed objects. |
| 26109 | stackA.push(object); |
| 26110 | stackB.push(other); |
| 26111 | |
| 26112 | var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB); |
| 26113 | |
| 26114 | stackA.pop(); |
| 26115 | stackB.pop(); |
| 26116 | |
| 26117 | return result; |
| 26118 | } |
| 26119 | |
| 26120 | module.exports = baseIsEqualDeep; |
| 26121 | |
| 26122 | },{"../lang/isArray":144,"../lang/isTypedArray":151,"./equalArrays":110,"./equalByTag":111,"./equalObjects":112,"./isHostObject":123}],83:[function(require,module,exports){ |
| 26123 | /** |
| 26124 | * The base implementation of `_.isFunction` without support for environments |
| 26125 | * with incorrect `typeof` results. |
| 26126 | * |
| 26127 | * @private |
| 26128 | * @param {*} value The value to check. |
| 26129 | * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
| 26130 | */ |
| 26131 | function baseIsFunction(value) { |
| 26132 | // Avoid a Chakra JIT bug in compatibility modes of IE 11. |
| 26133 | // See https://github.com/jashkenas/underscore/issues/1621 for more details. |
| 26134 | return typeof value == 'function' || false; |
| 26135 | } |
| 26136 | |
| 26137 | module.exports = baseIsFunction; |
| 26138 | |
| 26139 | },{}],84:[function(require,module,exports){ |
| 26140 | var baseIsEqual = require('./baseIsEqual'), |
| 26141 | toObject = require('./toObject'); |
| 26142 | |
| 26143 | /** |
| 26144 | * The base implementation of `_.isMatch` without support for callback |
| 26145 | * shorthands and `this` binding. |
| 26146 | * |
| 26147 | * @private |
| 26148 | * @param {Object} object The object to inspect. |
| 26149 | * @param {Array} matchData The propery names, values, and compare flags to match. |
| 26150 | * @param {Function} [customizer] The function to customize comparing objects. |
| 26151 | * @returns {boolean} Returns `true` if `object` is a match, else `false`. |
| 26152 | */ |
| 26153 | function baseIsMatch(object, matchData, customizer) { |
| 26154 | var index = matchData.length, |
| 26155 | length = index, |
| 26156 | noCustomizer = !customizer; |
| 26157 | |
| 26158 | if (object == null) { |
| 26159 | return !length; |
| 26160 | } |
| 26161 | object = toObject(object); |
| 26162 | while (index--) { |
| 26163 | var data = matchData[index]; |
| 26164 | if ((noCustomizer && data[2]) |
| 26165 | ? data[1] !== object[data[0]] |
| 26166 | : !(data[0] in object) |
| 26167 | ) { |
| 26168 | return false; |
| 26169 | } |
| 26170 | } |
| 26171 | while (++index < length) { |
| 26172 | data = matchData[index]; |
| 26173 | var key = data[0], |
| 26174 | objValue = object[key], |
| 26175 | srcValue = data[1]; |
| 26176 | |
| 26177 | if (noCustomizer && data[2]) { |
| 26178 | if (objValue === undefined && !(key in object)) { |
| 26179 | return false; |
| 26180 | } |
| 26181 | } else { |
| 26182 | var result = customizer ? customizer(objValue, srcValue, key) : undefined; |
| 26183 | if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) { |
| 26184 | return false; |
| 26185 | } |
| 26186 | } |
| 26187 | } |
| 26188 | return true; |
| 26189 | } |
| 26190 | |
| 26191 | module.exports = baseIsMatch; |
| 26192 | |
| 26193 | },{"./baseIsEqual":81,"./toObject":139}],85:[function(require,module,exports){ |
| 26194 | /** |
| 26195 | * The function whose prototype all chaining wrappers inherit from. |
| 26196 | * |
| 26197 | * @private |
| 26198 | */ |
| 26199 | function baseLodash() { |
| 26200 | // No operation performed. |
| 26201 | } |
| 26202 | |
| 26203 | module.exports = baseLodash; |
| 26204 | |
| 26205 | },{}],86:[function(require,module,exports){ |
| 26206 | var baseEach = require('./baseEach'), |
| 26207 | isArrayLike = require('./isArrayLike'); |
| 26208 | |
| 26209 | /** |
| 26210 | * The base implementation of `_.map` without support for callback shorthands |
| 26211 | * and `this` binding. |
| 26212 | * |
| 26213 | * @private |
| 26214 | * @param {Array|Object|string} collection The collection to iterate over. |
| 26215 | * @param {Function} iteratee The function invoked per iteration. |
| 26216 | * @returns {Array} Returns the new mapped array. |
| 26217 | */ |
| 26218 | function baseMap(collection, iteratee) { |
| 26219 | var index = -1, |
| 26220 | result = isArrayLike(collection) ? Array(collection.length) : []; |
| 26221 | |
| 26222 | baseEach(collection, function(value, key, collection) { |
| 26223 | result[++index] = iteratee(value, key, collection); |
| 26224 | }); |
| 26225 | return result; |
| 26226 | } |
| 26227 | |
| 26228 | module.exports = baseMap; |
| 26229 | |
| 26230 | },{"./baseEach":73,"./isArrayLike":122}],87:[function(require,module,exports){ |
| 26231 | var baseIsMatch = require('./baseIsMatch'), |
| 26232 | getMatchData = require('./getMatchData'), |
| 26233 | toObject = require('./toObject'); |
| 26234 | |
| 26235 | /** |
| 26236 | * The base implementation of `_.matches` which does not clone `source`. |
| 26237 | * |
| 26238 | * @private |
| 26239 | * @param {Object} source The object of property values to match. |
| 26240 | * @returns {Function} Returns the new function. |
| 26241 | */ |
| 26242 | function baseMatches(source) { |
| 26243 | var matchData = getMatchData(source); |
| 26244 | if (matchData.length == 1 && matchData[0][2]) { |
| 26245 | var key = matchData[0][0], |
| 26246 | value = matchData[0][1]; |
| 26247 | |
| 26248 | return function(object) { |
| 26249 | if (object == null) { |
| 26250 | return false; |
| 26251 | } |
| 26252 | object = toObject(object); |
| 26253 | return object[key] === value && (value !== undefined || (key in object)); |
| 26254 | }; |
| 26255 | } |
| 26256 | return function(object) { |
| 26257 | return baseIsMatch(object, matchData); |
| 26258 | }; |
| 26259 | } |
| 26260 | |
| 26261 | module.exports = baseMatches; |
| 26262 | |
| 26263 | },{"./baseIsMatch":84,"./getMatchData":116,"./toObject":139}],88:[function(require,module,exports){ |
| 26264 | var baseGet = require('./baseGet'), |
| 26265 | baseIsEqual = require('./baseIsEqual'), |
| 26266 | baseSlice = require('./baseSlice'), |
| 26267 | isArray = require('../lang/isArray'), |
| 26268 | isKey = require('./isKey'), |
| 26269 | isStrictComparable = require('./isStrictComparable'), |
| 26270 | last = require('../array/last'), |
| 26271 | toObject = require('./toObject'), |
| 26272 | toPath = require('./toPath'); |
| 26273 | |
| 26274 | /** |
| 26275 | * The base implementation of `_.matchesProperty` which does not clone `srcValue`. |
| 26276 | * |
| 26277 | * @private |
| 26278 | * @param {string} path The path of the property to get. |
| 26279 | * @param {*} srcValue The value to compare. |
| 26280 | * @returns {Function} Returns the new function. |
| 26281 | */ |
| 26282 | function baseMatchesProperty(path, srcValue) { |
| 26283 | var isArr = isArray(path), |
| 26284 | isCommon = isKey(path) && isStrictComparable(srcValue), |
| 26285 | pathKey = (path + ''); |
| 26286 | |
| 26287 | path = toPath(path); |
| 26288 | return function(object) { |
| 26289 | if (object == null) { |
| 26290 | return false; |
| 26291 | } |
| 26292 | var key = pathKey; |
| 26293 | object = toObject(object); |
| 26294 | if ((isArr || !isCommon) && !(key in object)) { |
| 26295 | object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); |
| 26296 | if (object == null) { |
| 26297 | return false; |
| 26298 | } |
| 26299 | key = last(path); |
| 26300 | object = toObject(object); |
| 26301 | } |
| 26302 | return object[key] === srcValue |
| 26303 | ? (srcValue !== undefined || (key in object)) |
| 26304 | : baseIsEqual(srcValue, object[key], undefined, true); |
| 26305 | }; |
| 26306 | } |
| 26307 | |
| 26308 | module.exports = baseMatchesProperty; |
| 26309 | |
| 26310 | },{"../array/last":52,"../lang/isArray":144,"./baseGet":79,"./baseIsEqual":81,"./baseSlice":92,"./isKey":126,"./isStrictComparable":130,"./toObject":139,"./toPath":140}],89:[function(require,module,exports){ |
| 26311 | var toObject = require('./toObject'); |
| 26312 | |
| 26313 | /** |
| 26314 | * The base implementation of `_.property` without support for deep paths. |
| 26315 | * |
| 26316 | * @private |
| 26317 | * @param {string} key The key of the property to get. |
| 26318 | * @returns {Function} Returns the new function. |
| 26319 | */ |
| 26320 | function baseProperty(key) { |
| 26321 | return function(object) { |
| 26322 | return object == null ? undefined : toObject(object)[key]; |
| 26323 | }; |
| 26324 | } |
| 26325 | |
| 26326 | module.exports = baseProperty; |
| 26327 | |
| 26328 | },{"./toObject":139}],90:[function(require,module,exports){ |
| 26329 | var baseGet = require('./baseGet'), |
| 26330 | toPath = require('./toPath'); |
| 26331 | |
| 26332 | /** |
| 26333 | * A specialized version of `baseProperty` which supports deep paths. |
| 26334 | * |
| 26335 | * @private |
| 26336 | * @param {Array|string} path The path of the property to get. |
| 26337 | * @returns {Function} Returns the new function. |
| 26338 | */ |
| 26339 | function basePropertyDeep(path) { |
| 26340 | var pathKey = (path + ''); |
| 26341 | path = toPath(path); |
| 26342 | return function(object) { |
| 26343 | return baseGet(object, path, pathKey); |
| 26344 | }; |
| 26345 | } |
| 26346 | |
| 26347 | module.exports = basePropertyDeep; |
| 26348 | |
| 26349 | },{"./baseGet":79,"./toPath":140}],91:[function(require,module,exports){ |
| 26350 | var identity = require('../utility/identity'), |
| 26351 | metaMap = require('./metaMap'); |
| 26352 | |
| 26353 | /** |
| 26354 | * The base implementation of `setData` without support for hot loop detection. |
| 26355 | * |
| 26356 | * @private |
| 26357 | * @param {Function} func The function to associate metadata with. |
| 26358 | * @param {*} data The metadata. |
| 26359 | * @returns {Function} Returns `func`. |
| 26360 | */ |
| 26361 | var baseSetData = !metaMap ? identity : function(func, data) { |
| 26362 | metaMap.set(func, data); |
| 26363 | return func; |
| 26364 | }; |
| 26365 | |
| 26366 | module.exports = baseSetData; |
| 26367 | |
| 26368 | },{"../utility/identity":160,"./metaMap":132}],92:[function(require,module,exports){ |
| 26369 | /** |
| 26370 | * The base implementation of `_.slice` without an iteratee call guard. |
| 26371 | * |
| 26372 | * @private |
| 26373 | * @param {Array} array The array to slice. |
| 26374 | * @param {number} [start=0] The start position. |
| 26375 | * @param {number} [end=array.length] The end position. |
| 26376 | * @returns {Array} Returns the slice of `array`. |
| 26377 | */ |
| 26378 | function baseSlice(array, start, end) { |
| 26379 | var index = -1, |
| 26380 | length = array.length; |
| 26381 | |
| 26382 | start = start == null ? 0 : (+start || 0); |
| 26383 | if (start < 0) { |
| 26384 | start = -start > length ? 0 : (length + start); |
| 26385 | } |
| 26386 | end = (end === undefined || end > length) ? length : (+end || 0); |
| 26387 | if (end < 0) { |
| 26388 | end += length; |
| 26389 | } |
| 26390 | length = start > end ? 0 : ((end - start) >>> 0); |
| 26391 | start >>>= 0; |
| 26392 | |
| 26393 | var result = Array(length); |
| 26394 | while (++index < length) { |
| 26395 | result[index] = array[index + start]; |
| 26396 | } |
| 26397 | return result; |
| 26398 | } |
| 26399 | |
| 26400 | module.exports = baseSlice; |
| 26401 | |
| 26402 | },{}],93:[function(require,module,exports){ |
| 26403 | /** |
| 26404 | * Converts `value` to a string if it's not one. An empty string is returned |
| 26405 | * for `null` or `undefined` values. |
| 26406 | * |
| 26407 | * @private |
| 26408 | * @param {*} value The value to process. |
| 26409 | * @returns {string} Returns the string. |
| 26410 | */ |
| 26411 | function baseToString(value) { |
| 26412 | if (typeof value == 'string') { |
| 26413 | return value; |
| 26414 | } |
| 26415 | return value == null ? '' : (value + ''); |
| 26416 | } |
| 26417 | |
| 26418 | module.exports = baseToString; |
| 26419 | |
| 26420 | },{}],94:[function(require,module,exports){ |
| 26421 | /** |
| 26422 | * The base implementation of `_.values` and `_.valuesIn` which creates an |
| 26423 | * array of `object` property values corresponding to the property names |
| 26424 | * of `props`. |
| 26425 | * |
| 26426 | * @private |
| 26427 | * @param {Object} object The object to query. |
| 26428 | * @param {Array} props The property names to get values for. |
| 26429 | * @returns {Object} Returns the array of property values. |
| 26430 | */ |
| 26431 | function baseValues(object, props) { |
| 26432 | var index = -1, |
| 26433 | length = props.length, |
| 26434 | result = Array(length); |
| 26435 | |
| 26436 | while (++index < length) { |
| 26437 | result[index] = object[props[index]]; |
| 26438 | } |
| 26439 | return result; |
| 26440 | } |
| 26441 | |
| 26442 | module.exports = baseValues; |
| 26443 | |
| 26444 | },{}],95:[function(require,module,exports){ |
| 26445 | var binaryIndexBy = require('./binaryIndexBy'), |
| 26446 | identity = require('../utility/identity'); |
| 26447 | |
| 26448 | /** Used as references for the maximum length and index of an array. */ |
| 26449 | var MAX_ARRAY_LENGTH = 4294967295, |
| 26450 | HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; |
| 26451 | |
| 26452 | /** |
| 26453 | * Performs a binary search of `array` to determine the index at which `value` |
| 26454 | * should be inserted into `array` in order to maintain its sort order. |
| 26455 | * |
| 26456 | * @private |
| 26457 | * @param {Array} array The sorted array to inspect. |
| 26458 | * @param {*} value The value to evaluate. |
| 26459 | * @param {boolean} [retHighest] Specify returning the highest qualified index. |
| 26460 | * @returns {number} Returns the index at which `value` should be inserted |
| 26461 | * into `array`. |
| 26462 | */ |
| 26463 | function binaryIndex(array, value, retHighest) { |
| 26464 | var low = 0, |
| 26465 | high = array ? array.length : low; |
| 26466 | |
| 26467 | if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { |
| 26468 | while (low < high) { |
| 26469 | var mid = (low + high) >>> 1, |
| 26470 | computed = array[mid]; |
| 26471 | |
| 26472 | if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) { |
| 26473 | low = mid + 1; |
| 26474 | } else { |
| 26475 | high = mid; |
| 26476 | } |
| 26477 | } |
| 26478 | return high; |
| 26479 | } |
| 26480 | return binaryIndexBy(array, value, identity, retHighest); |
| 26481 | } |
| 26482 | |
| 26483 | module.exports = binaryIndex; |
| 26484 | |
| 26485 | },{"../utility/identity":160,"./binaryIndexBy":96}],96:[function(require,module,exports){ |
| 26486 | /** Native method references. */ |
| 26487 | var floor = Math.floor; |
| 26488 | |
| 26489 | /* Native method references for those with the same name as other `lodash` methods. */ |
| 26490 | var nativeMin = Math.min; |
| 26491 | |
| 26492 | /** Used as references for the maximum length and index of an array. */ |
| 26493 | var MAX_ARRAY_LENGTH = 4294967295, |
| 26494 | MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1; |
| 26495 | |
| 26496 | /** |
| 26497 | * This function is like `binaryIndex` except that it invokes `iteratee` for |
| 26498 | * `value` and each element of `array` to compute their sort ranking. The |
| 26499 | * iteratee is invoked with one argument; (value). |
| 26500 | * |
| 26501 | * @private |
| 26502 | * @param {Array} array The sorted array to inspect. |
| 26503 | * @param {*} value The value to evaluate. |
| 26504 | * @param {Function} iteratee The function invoked per iteration. |
| 26505 | * @param {boolean} [retHighest] Specify returning the highest qualified index. |
| 26506 | * @returns {number} Returns the index at which `value` should be inserted |
| 26507 | * into `array`. |
| 26508 | */ |
| 26509 | function binaryIndexBy(array, value, iteratee, retHighest) { |
| 26510 | value = iteratee(value); |
| 26511 | |
| 26512 | var low = 0, |
| 26513 | high = array ? array.length : 0, |
| 26514 | valIsNaN = value !== value, |
| 26515 | valIsNull = value === null, |
| 26516 | valIsUndef = value === undefined; |
| 26517 | |
| 26518 | while (low < high) { |
| 26519 | var mid = floor((low + high) / 2), |
| 26520 | computed = iteratee(array[mid]), |
| 26521 | isDef = computed !== undefined, |
| 26522 | isReflexive = computed === computed; |
| 26523 | |
| 26524 | if (valIsNaN) { |
| 26525 | var setLow = isReflexive || retHighest; |
| 26526 | } else if (valIsNull) { |
| 26527 | setLow = isReflexive && isDef && (retHighest || computed != null); |
| 26528 | } else if (valIsUndef) { |
| 26529 | setLow = isReflexive && (retHighest || isDef); |
| 26530 | } else if (computed == null) { |
| 26531 | setLow = false; |
| 26532 | } else { |
| 26533 | setLow = retHighest ? (computed <= value) : (computed < value); |
| 26534 | } |
| 26535 | if (setLow) { |
| 26536 | low = mid + 1; |
| 26537 | } else { |
| 26538 | high = mid; |
| 26539 | } |
| 26540 | } |
| 26541 | return nativeMin(high, MAX_ARRAY_INDEX); |
| 26542 | } |
| 26543 | |
| 26544 | module.exports = binaryIndexBy; |
| 26545 | |
| 26546 | },{}],97:[function(require,module,exports){ |
| 26547 | var identity = require('../utility/identity'); |
| 26548 | |
| 26549 | /** |
| 26550 | * A specialized version of `baseCallback` which only supports `this` binding |
| 26551 | * and specifying the number of arguments to provide to `func`. |
| 26552 | * |
| 26553 | * @private |
| 26554 | * @param {Function} func The function to bind. |
| 26555 | * @param {*} thisArg The `this` binding of `func`. |
| 26556 | * @param {number} [argCount] The number of arguments to provide to `func`. |
| 26557 | * @returns {Function} Returns the callback. |
| 26558 | */ |
| 26559 | function bindCallback(func, thisArg, argCount) { |
| 26560 | if (typeof func != 'function') { |
| 26561 | return identity; |
| 26562 | } |
| 26563 | if (thisArg === undefined) { |
| 26564 | return func; |
| 26565 | } |
| 26566 | switch (argCount) { |
| 26567 | case 1: return function(value) { |
| 26568 | return func.call(thisArg, value); |
| 26569 | }; |
| 26570 | case 3: return function(value, index, collection) { |
| 26571 | return func.call(thisArg, value, index, collection); |
| 26572 | }; |
| 26573 | case 4: return function(accumulator, value, index, collection) { |
| 26574 | return func.call(thisArg, accumulator, value, index, collection); |
| 26575 | }; |
| 26576 | case 5: return function(value, other, key, object, source) { |
| 26577 | return func.call(thisArg, value, other, key, object, source); |
| 26578 | }; |
| 26579 | } |
| 26580 | return function() { |
| 26581 | return func.apply(thisArg, arguments); |
| 26582 | }; |
| 26583 | } |
| 26584 | |
| 26585 | module.exports = bindCallback; |
| 26586 | |
| 26587 | },{"../utility/identity":160}],98:[function(require,module,exports){ |
| 26588 | (function (global){ |
| 26589 | var constant = require('../utility/constant'), |
| 26590 | getNative = require('./getNative'); |
| 26591 | |
| 26592 | /** Native method references. */ |
| 26593 | var ArrayBuffer = getNative(global, 'ArrayBuffer'), |
| 26594 | bufferSlice = getNative(ArrayBuffer && new ArrayBuffer(0), 'slice'), |
| 26595 | floor = Math.floor, |
| 26596 | Uint8Array = getNative(global, 'Uint8Array'); |
| 26597 | |
| 26598 | /** Used to clone array buffers. */ |
| 26599 | var Float64Array = (function() { |
| 26600 | // Safari 5 errors when using an array buffer to initialize a typed array |
| 26601 | // where the array buffer's `byteLength` is not a multiple of the typed |
| 26602 | // array's `BYTES_PER_ELEMENT`. |
| 26603 | try { |
| 26604 | var func = getNative(global, 'Float64Array'), |
| 26605 | result = new func(new ArrayBuffer(10), 0, 1) && func; |
| 26606 | } catch(e) {} |
| 26607 | return result || null; |
| 26608 | }()); |
| 26609 | |
| 26610 | /** Used as the size, in bytes, of each `Float64Array` element. */ |
| 26611 | var FLOAT64_BYTES_PER_ELEMENT = Float64Array ? Float64Array.BYTES_PER_ELEMENT : 0; |
| 26612 | |
| 26613 | /** |
| 26614 | * Creates a clone of the given array buffer. |
| 26615 | * |
| 26616 | * @private |
| 26617 | * @param {ArrayBuffer} buffer The array buffer to clone. |
| 26618 | * @returns {ArrayBuffer} Returns the cloned array buffer. |
| 26619 | */ |
| 26620 | function bufferClone(buffer) { |
| 26621 | return bufferSlice.call(buffer, 0); |
| 26622 | } |
| 26623 | if (!bufferSlice) { |
| 26624 | // PhantomJS has `ArrayBuffer` and `Uint8Array` but not `Float64Array`. |
| 26625 | bufferClone = !(ArrayBuffer && Uint8Array) ? constant(null) : function(buffer) { |
| 26626 | var byteLength = buffer.byteLength, |
| 26627 | floatLength = Float64Array ? floor(byteLength / FLOAT64_BYTES_PER_ELEMENT) : 0, |
| 26628 | offset = floatLength * FLOAT64_BYTES_PER_ELEMENT, |
| 26629 | result = new ArrayBuffer(byteLength); |
| 26630 | |
| 26631 | if (floatLength) { |
| 26632 | var view = new Float64Array(result, 0, floatLength); |
| 26633 | view.set(new Float64Array(buffer, 0, floatLength)); |
| 26634 | } |
| 26635 | if (byteLength != offset) { |
| 26636 | view = new Uint8Array(result, offset); |
| 26637 | view.set(new Uint8Array(buffer, offset)); |
| 26638 | } |
| 26639 | return result; |
| 26640 | }; |
| 26641 | } |
| 26642 | |
| 26643 | module.exports = bufferClone; |
| 26644 | |
| 26645 | }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
| 26646 | |
| 26647 | },{"../utility/constant":159,"./getNative":117}],99:[function(require,module,exports){ |
| 26648 | /* Native method references for those with the same name as other `lodash` methods. */ |
| 26649 | var nativeMax = Math.max; |
| 26650 | |
| 26651 | /** |
| 26652 | * Creates an array that is the composition of partially applied arguments, |
| 26653 | * placeholders, and provided arguments into a single array of arguments. |
| 26654 | * |
| 26655 | * @private |
| 26656 | * @param {Array|Object} args The provided arguments. |
| 26657 | * @param {Array} partials The arguments to prepend to those provided. |
| 26658 | * @param {Array} holders The `partials` placeholder indexes. |
| 26659 | * @returns {Array} Returns the new array of composed arguments. |
| 26660 | */ |
| 26661 | function composeArgs(args, partials, holders) { |
| 26662 | var holdersLength = holders.length, |
| 26663 | argsIndex = -1, |
| 26664 | argsLength = nativeMax(args.length - holdersLength, 0), |
| 26665 | leftIndex = -1, |
| 26666 | leftLength = partials.length, |
| 26667 | result = Array(argsLength + leftLength); |
| 26668 | |
| 26669 | while (++leftIndex < leftLength) { |
| 26670 | result[leftIndex] = partials[leftIndex]; |
| 26671 | } |
| 26672 | while (++argsIndex < holdersLength) { |
| 26673 | result[holders[argsIndex]] = args[argsIndex]; |
| 26674 | } |
| 26675 | while (argsLength--) { |
| 26676 | result[leftIndex++] = args[argsIndex++]; |
| 26677 | } |
| 26678 | return result; |
| 26679 | } |
| 26680 | |
| 26681 | module.exports = composeArgs; |
| 26682 | |
| 26683 | },{}],100:[function(require,module,exports){ |
| 26684 | /* Native method references for those with the same name as other `lodash` methods. */ |
| 26685 | var nativeMax = Math.max; |
| 26686 | |
| 26687 | /** |
| 26688 | * This function is like `composeArgs` except that the arguments composition |
| 26689 | * is tailored for `_.partialRight`. |
| 26690 | * |
| 26691 | * @private |
| 26692 | * @param {Array|Object} args The provided arguments. |
| 26693 | * @param {Array} partials The arguments to append to those provided. |
| 26694 | * @param {Array} holders The `partials` placeholder indexes. |
| 26695 | * @returns {Array} Returns the new array of composed arguments. |
| 26696 | */ |
| 26697 | function composeArgsRight(args, partials, holders) { |
| 26698 | var holdersIndex = -1, |
| 26699 | holdersLength = holders.length, |
| 26700 | argsIndex = -1, |
| 26701 | argsLength = nativeMax(args.length - holdersLength, 0), |
| 26702 | rightIndex = -1, |
| 26703 | rightLength = partials.length, |
| 26704 | result = Array(argsLength + rightLength); |
| 26705 | |
| 26706 | while (++argsIndex < argsLength) { |
| 26707 | result[argsIndex] = args[argsIndex]; |
| 26708 | } |
| 26709 | var offset = argsIndex; |
| 26710 | while (++rightIndex < rightLength) { |
| 26711 | result[offset + rightIndex] = partials[rightIndex]; |
| 26712 | } |
| 26713 | while (++holdersIndex < holdersLength) { |
| 26714 | result[offset + holders[holdersIndex]] = args[argsIndex++]; |
| 26715 | } |
| 26716 | return result; |
| 26717 | } |
| 26718 | |
| 26719 | module.exports = composeArgsRight; |
| 26720 | |
| 26721 | },{}],101:[function(require,module,exports){ |
| 26722 | var getLength = require('./getLength'), |
| 26723 | isLength = require('./isLength'), |
| 26724 | toObject = require('./toObject'); |
| 26725 | |
| 26726 | /** |
| 26727 | * Creates a `baseEach` or `baseEachRight` function. |
| 26728 | * |
| 26729 | * @private |
| 26730 | * @param {Function} eachFunc The function to iterate over a collection. |
| 26731 | * @param {boolean} [fromRight] Specify iterating from right to left. |
| 26732 | * @returns {Function} Returns the new base function. |
| 26733 | */ |
| 26734 | function createBaseEach(eachFunc, fromRight) { |
| 26735 | return function(collection, iteratee) { |
| 26736 | var length = collection ? getLength(collection) : 0; |
| 26737 | if (!isLength(length)) { |
| 26738 | return eachFunc(collection, iteratee); |
| 26739 | } |
| 26740 | var index = fromRight ? length : -1, |
| 26741 | iterable = toObject(collection); |
| 26742 | |
| 26743 | while ((fromRight ? index-- : ++index < length)) { |
| 26744 | if (iteratee(iterable[index], index, iterable) === false) { |
| 26745 | break; |
| 26746 | } |
| 26747 | } |
| 26748 | return collection; |
| 26749 | }; |
| 26750 | } |
| 26751 | |
| 26752 | module.exports = createBaseEach; |
| 26753 | |
| 26754 | },{"./getLength":115,"./isLength":128,"./toObject":139}],102:[function(require,module,exports){ |
| 26755 | var toObject = require('./toObject'); |
| 26756 | |
| 26757 | /** |
| 26758 | * Creates a base function for `_.forIn` or `_.forInRight`. |
| 26759 | * |
| 26760 | * @private |
| 26761 | * @param {boolean} [fromRight] Specify iterating from right to left. |
| 26762 | * @returns {Function} Returns the new base function. |
| 26763 | */ |
| 26764 | function createBaseFor(fromRight) { |
| 26765 | return function(object, iteratee, keysFunc) { |
| 26766 | var iterable = toObject(object), |
| 26767 | props = keysFunc(object), |
| 26768 | length = props.length, |
| 26769 | index = fromRight ? length : -1; |
| 26770 | |
| 26771 | while ((fromRight ? index-- : ++index < length)) { |
| 26772 | var key = props[index]; |
| 26773 | if (iteratee(iterable[key], key, iterable) === false) { |
| 26774 | break; |
| 26775 | } |
| 26776 | } |
| 26777 | return object; |
| 26778 | }; |
| 26779 | } |
| 26780 | |
| 26781 | module.exports = createBaseFor; |
| 26782 | |
| 26783 | },{"./toObject":139}],103:[function(require,module,exports){ |
| 26784 | (function (global){ |
| 26785 | var createCtorWrapper = require('./createCtorWrapper'); |
| 26786 | |
| 26787 | /** |
| 26788 | * Creates a function that wraps `func` and invokes it with the `this` |
| 26789 | * binding of `thisArg`. |
| 26790 | * |
| 26791 | * @private |
| 26792 | * @param {Function} func The function to bind. |
| 26793 | * @param {*} [thisArg] The `this` binding of `func`. |
| 26794 | * @returns {Function} Returns the new bound function. |
| 26795 | */ |
| 26796 | function createBindWrapper(func, thisArg) { |
| 26797 | var Ctor = createCtorWrapper(func); |
| 26798 | |
| 26799 | function wrapper() { |
| 26800 | var fn = (this && this !== global && this instanceof wrapper) ? Ctor : func; |
| 26801 | return fn.apply(thisArg, arguments); |
| 26802 | } |
| 26803 | return wrapper; |
| 26804 | } |
| 26805 | |
| 26806 | module.exports = createBindWrapper; |
| 26807 | |
| 26808 | }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
| 26809 | |
| 26810 | },{"./createCtorWrapper":104}],104:[function(require,module,exports){ |
| 26811 | var baseCreate = require('./baseCreate'), |
| 26812 | isObject = require('../lang/isObject'); |
| 26813 | |
| 26814 | /** |
| 26815 | * Creates a function that produces an instance of `Ctor` regardless of |
| 26816 | * whether it was invoked as part of a `new` expression or by `call` or `apply`. |
| 26817 | * |
| 26818 | * @private |
| 26819 | * @param {Function} Ctor The constructor to wrap. |
| 26820 | * @returns {Function} Returns the new wrapped function. |
| 26821 | */ |
| 26822 | function createCtorWrapper(Ctor) { |
| 26823 | return function() { |
| 26824 | // Use a `switch` statement to work with class constructors. |
| 26825 | // See https://people.mozilla.org/~jorendorff/es6-draft.html#sec-ecmascript-function-objects-call-thisargument-argumentslist |
| 26826 | // for more details. |
| 26827 | var args = arguments; |
| 26828 | switch (args.length) { |
| 26829 | case 0: return new Ctor; |
| 26830 | case 1: return new Ctor(args[0]); |
| 26831 | case 2: return new Ctor(args[0], args[1]); |
| 26832 | case 3: return new Ctor(args[0], args[1], args[2]); |
| 26833 | case 4: return new Ctor(args[0], args[1], args[2], args[3]); |
| 26834 | case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); |
| 26835 | } |
| 26836 | var thisBinding = baseCreate(Ctor.prototype), |
| 26837 | result = Ctor.apply(thisBinding, args); |
| 26838 | |
| 26839 | // Mimic the constructor's `return` behavior. |
| 26840 | // See https://es5.github.io/#x13.2.2 for more details. |
| 26841 | return isObject(result) ? result : thisBinding; |
| 26842 | }; |
| 26843 | } |
| 26844 | |
| 26845 | module.exports = createCtorWrapper; |
| 26846 | |
| 26847 | },{"../lang/isObject":148,"./baseCreate":72}],105:[function(require,module,exports){ |
| 26848 | var baseCallback = require('./baseCallback'), |
| 26849 | baseFind = require('./baseFind'), |
| 26850 | baseFindIndex = require('./baseFindIndex'), |
| 26851 | isArray = require('../lang/isArray'); |
| 26852 | |
| 26853 | /** |
| 26854 | * Creates a `_.find` or `_.findLast` function. |
| 26855 | * |
| 26856 | * @private |
| 26857 | * @param {Function} eachFunc The function to iterate over a collection. |
| 26858 | * @param {boolean} [fromRight] Specify iterating from right to left. |
| 26859 | * @returns {Function} Returns the new find function. |
| 26860 | */ |
| 26861 | function createFind(eachFunc, fromRight) { |
| 26862 | return function(collection, predicate, thisArg) { |
| 26863 | predicate = baseCallback(predicate, thisArg, 3); |
| 26864 | if (isArray(collection)) { |
| 26865 | var index = baseFindIndex(collection, predicate, fromRight); |
| 26866 | return index > -1 ? collection[index] : undefined; |
| 26867 | } |
| 26868 | return baseFind(collection, predicate, eachFunc); |
| 26869 | }; |
| 26870 | } |
| 26871 | |
| 26872 | module.exports = createFind; |
| 26873 | |
| 26874 | },{"../lang/isArray":144,"./baseCallback":69,"./baseFind":74,"./baseFindIndex":75}],106:[function(require,module,exports){ |
| 26875 | var bindCallback = require('./bindCallback'), |
| 26876 | isArray = require('../lang/isArray'); |
| 26877 | |
| 26878 | /** |
| 26879 | * Creates a function for `_.forEach` or `_.forEachRight`. |
| 26880 | * |
| 26881 | * @private |
| 26882 | * @param {Function} arrayFunc The function to iterate over an array. |
| 26883 | * @param {Function} eachFunc The function to iterate over a collection. |
| 26884 | * @returns {Function} Returns the new each function. |
| 26885 | */ |
| 26886 | function createForEach(arrayFunc, eachFunc) { |
| 26887 | return function(collection, iteratee, thisArg) { |
| 26888 | return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) |
| 26889 | ? arrayFunc(collection, iteratee) |
| 26890 | : eachFunc(collection, bindCallback(iteratee, thisArg, 3)); |
| 26891 | }; |
| 26892 | } |
| 26893 | |
| 26894 | module.exports = createForEach; |
| 26895 | |
| 26896 | },{"../lang/isArray":144,"./bindCallback":97}],107:[function(require,module,exports){ |
| 26897 | (function (global){ |
| 26898 | var arrayCopy = require('./arrayCopy'), |
| 26899 | composeArgs = require('./composeArgs'), |
| 26900 | composeArgsRight = require('./composeArgsRight'), |
| 26901 | createCtorWrapper = require('./createCtorWrapper'), |
| 26902 | isLaziable = require('./isLaziable'), |
| 26903 | reorder = require('./reorder'), |
| 26904 | replaceHolders = require('./replaceHolders'), |
| 26905 | setData = require('./setData'); |
| 26906 | |
| 26907 | /** Used to compose bitmasks for wrapper metadata. */ |
| 26908 | var BIND_FLAG = 1, |
| 26909 | BIND_KEY_FLAG = 2, |
| 26910 | CURRY_BOUND_FLAG = 4, |
| 26911 | CURRY_FLAG = 8, |
| 26912 | CURRY_RIGHT_FLAG = 16, |
| 26913 | PARTIAL_FLAG = 32, |
| 26914 | PARTIAL_RIGHT_FLAG = 64, |
| 26915 | ARY_FLAG = 128; |
| 26916 | |
| 26917 | /* Native method references for those with the same name as other `lodash` methods. */ |
| 26918 | var nativeMax = Math.max; |
| 26919 | |
| 26920 | /** |
| 26921 | * Creates a function that wraps `func` and invokes it with optional `this` |
| 26922 | * binding of, partial application, and currying. |
| 26923 | * |
| 26924 | * @private |
| 26925 | * @param {Function|string} func The function or method name to reference. |
| 26926 | * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. |
| 26927 | * @param {*} [thisArg] The `this` binding of `func`. |
| 26928 | * @param {Array} [partials] The arguments to prepend to those provided to the new function. |
| 26929 | * @param {Array} [holders] The `partials` placeholder indexes. |
| 26930 | * @param {Array} [partialsRight] The arguments to append to those provided to the new function. |
| 26931 | * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. |
| 26932 | * @param {Array} [argPos] The argument positions of the new function. |
| 26933 | * @param {number} [ary] The arity cap of `func`. |
| 26934 | * @param {number} [arity] The arity of `func`. |
| 26935 | * @returns {Function} Returns the new wrapped function. |
| 26936 | */ |
| 26937 | function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { |
| 26938 | var isAry = bitmask & ARY_FLAG, |
| 26939 | isBind = bitmask & BIND_FLAG, |
| 26940 | isBindKey = bitmask & BIND_KEY_FLAG, |
| 26941 | isCurry = bitmask & CURRY_FLAG, |
| 26942 | isCurryBound = bitmask & CURRY_BOUND_FLAG, |
| 26943 | isCurryRight = bitmask & CURRY_RIGHT_FLAG, |
| 26944 | Ctor = isBindKey ? null : createCtorWrapper(func); |
| 26945 | |
| 26946 | function wrapper() { |
| 26947 | // Avoid `arguments` object use disqualifying optimizations by |
| 26948 | // converting it to an array before providing it to other functions. |
| 26949 | var length = arguments.length, |
| 26950 | index = length, |
| 26951 | args = Array(length); |
| 26952 | |
| 26953 | while (index--) { |
| 26954 | args[index] = arguments[index]; |
| 26955 | } |
| 26956 | if (partials) { |
| 26957 | args = composeArgs(args, partials, holders); |
| 26958 | } |
| 26959 | if (partialsRight) { |
| 26960 | args = composeArgsRight(args, partialsRight, holdersRight); |
| 26961 | } |
| 26962 | if (isCurry || isCurryRight) { |
| 26963 | var placeholder = wrapper.placeholder, |
| 26964 | argsHolders = replaceHolders(args, placeholder); |
| 26965 | |
| 26966 | length -= argsHolders.length; |
| 26967 | if (length < arity) { |
| 26968 | var newArgPos = argPos ? arrayCopy(argPos) : null, |
| 26969 | newArity = nativeMax(arity - length, 0), |
| 26970 | newsHolders = isCurry ? argsHolders : null, |
| 26971 | newHoldersRight = isCurry ? null : argsHolders, |
| 26972 | newPartials = isCurry ? args : null, |
| 26973 | newPartialsRight = isCurry ? null : args; |
| 26974 | |
| 26975 | bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); |
| 26976 | bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); |
| 26977 | |
| 26978 | if (!isCurryBound) { |
| 26979 | bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); |
| 26980 | } |
| 26981 | var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity], |
| 26982 | result = createHybridWrapper.apply(undefined, newData); |
| 26983 | |
| 26984 | if (isLaziable(func)) { |
| 26985 | setData(result, newData); |
| 26986 | } |
| 26987 | result.placeholder = placeholder; |
| 26988 | return result; |
| 26989 | } |
| 26990 | } |
| 26991 | var thisBinding = isBind ? thisArg : this, |
| 26992 | fn = isBindKey ? thisBinding[func] : func; |
| 26993 | |
| 26994 | if (argPos) { |
| 26995 | args = reorder(args, argPos); |
| 26996 | } |
| 26997 | if (isAry && ary < args.length) { |
| 26998 | args.length = ary; |
| 26999 | } |
| 27000 | if (this && this !== global && this instanceof wrapper) { |
| 27001 | fn = Ctor || createCtorWrapper(func); |
| 27002 | } |
| 27003 | return fn.apply(thisBinding, args); |
| 27004 | } |
| 27005 | return wrapper; |
| 27006 | } |
| 27007 | |
| 27008 | module.exports = createHybridWrapper; |
| 27009 | |
| 27010 | }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
| 27011 | |
| 27012 | },{"./arrayCopy":64,"./composeArgs":99,"./composeArgsRight":100,"./createCtorWrapper":104,"./isLaziable":127,"./reorder":134,"./replaceHolders":135,"./setData":136}],108:[function(require,module,exports){ |
| 27013 | (function (global){ |
| 27014 | var createCtorWrapper = require('./createCtorWrapper'); |
| 27015 | |
| 27016 | /** Used to compose bitmasks for wrapper metadata. */ |
| 27017 | var BIND_FLAG = 1; |
| 27018 | |
| 27019 | /** |
| 27020 | * Creates a function that wraps `func` and invokes it with the optional `this` |
| 27021 | * binding of `thisArg` and the `partials` prepended to those provided to |
| 27022 | * the wrapper. |
| 27023 | * |
| 27024 | * @private |
| 27025 | * @param {Function} func The function to partially apply arguments to. |
| 27026 | * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. |
| 27027 | * @param {*} thisArg The `this` binding of `func`. |
| 27028 | * @param {Array} partials The arguments to prepend to those provided to the new function. |
| 27029 | * @returns {Function} Returns the new bound function. |
| 27030 | */ |
| 27031 | function createPartialWrapper(func, bitmask, thisArg, partials) { |
| 27032 | var isBind = bitmask & BIND_FLAG, |
| 27033 | Ctor = createCtorWrapper(func); |
| 27034 | |
| 27035 | function wrapper() { |
| 27036 | // Avoid `arguments` object use disqualifying optimizations by |
| 27037 | // converting it to an array before providing it `func`. |
| 27038 | var argsIndex = -1, |
| 27039 | argsLength = arguments.length, |
| 27040 | leftIndex = -1, |
| 27041 | leftLength = partials.length, |
| 27042 | args = Array(argsLength + leftLength); |
| 27043 | |
| 27044 | while (++leftIndex < leftLength) { |
| 27045 | args[leftIndex] = partials[leftIndex]; |
| 27046 | } |
| 27047 | while (argsLength--) { |
| 27048 | args[leftIndex++] = arguments[++argsIndex]; |
| 27049 | } |
| 27050 | var fn = (this && this !== global && this instanceof wrapper) ? Ctor : func; |
| 27051 | return fn.apply(isBind ? thisArg : this, args); |
| 27052 | } |
| 27053 | return wrapper; |
| 27054 | } |
| 27055 | |
| 27056 | module.exports = createPartialWrapper; |
| 27057 | |
| 27058 | }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
| 27059 | |
| 27060 | },{"./createCtorWrapper":104}],109:[function(require,module,exports){ |
| 27061 | var baseSetData = require('./baseSetData'), |
| 27062 | createBindWrapper = require('./createBindWrapper'), |
| 27063 | createHybridWrapper = require('./createHybridWrapper'), |
| 27064 | createPartialWrapper = require('./createPartialWrapper'), |
| 27065 | getData = require('./getData'), |
| 27066 | mergeData = require('./mergeData'), |
| 27067 | setData = require('./setData'); |
| 27068 | |
| 27069 | /** Used to compose bitmasks for wrapper metadata. */ |
| 27070 | var BIND_FLAG = 1, |
| 27071 | BIND_KEY_FLAG = 2, |
| 27072 | PARTIAL_FLAG = 32, |
| 27073 | PARTIAL_RIGHT_FLAG = 64; |
| 27074 | |
| 27075 | /** Used as the `TypeError` message for "Functions" methods. */ |
| 27076 | var FUNC_ERROR_TEXT = 'Expected a function'; |
| 27077 | |
| 27078 | /* Native method references for those with the same name as other `lodash` methods. */ |
| 27079 | var nativeMax = Math.max; |
| 27080 | |
| 27081 | /** |
| 27082 | * Creates a function that either curries or invokes `func` with optional |
| 27083 | * `this` binding and partially applied arguments. |
| 27084 | * |
| 27085 | * @private |
| 27086 | * @param {Function|string} func The function or method name to reference. |
| 27087 | * @param {number} bitmask The bitmask of flags. |
| 27088 | * The bitmask may be composed of the following flags: |
| 27089 | * 1 - `_.bind` |
| 27090 | * 2 - `_.bindKey` |
| 27091 | * 4 - `_.curry` or `_.curryRight` of a bound function |
| 27092 | * 8 - `_.curry` |
| 27093 | * 16 - `_.curryRight` |
| 27094 | * 32 - `_.partial` |
| 27095 | * 64 - `_.partialRight` |
| 27096 | * 128 - `_.rearg` |
| 27097 | * 256 - `_.ary` |
| 27098 | * @param {*} [thisArg] The `this` binding of `func`. |
| 27099 | * @param {Array} [partials] The arguments to be partially applied. |
| 27100 | * @param {Array} [holders] The `partials` placeholder indexes. |
| 27101 | * @param {Array} [argPos] The argument positions of the new function. |
| 27102 | * @param {number} [ary] The arity cap of `func`. |
| 27103 | * @param {number} [arity] The arity of `func`. |
| 27104 | * @returns {Function} Returns the new wrapped function. |
| 27105 | */ |
| 27106 | function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { |
| 27107 | var isBindKey = bitmask & BIND_KEY_FLAG; |
| 27108 | if (!isBindKey && typeof func != 'function') { |
| 27109 | throw new TypeError(FUNC_ERROR_TEXT); |
| 27110 | } |
| 27111 | var length = partials ? partials.length : 0; |
| 27112 | if (!length) { |
| 27113 | bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG); |
| 27114 | partials = holders = null; |
| 27115 | } |
| 27116 | length -= (holders ? holders.length : 0); |
| 27117 | if (bitmask & PARTIAL_RIGHT_FLAG) { |
| 27118 | var partialsRight = partials, |
| 27119 | holdersRight = holders; |
| 27120 | |
| 27121 | partials = holders = null; |
| 27122 | } |
| 27123 | var data = isBindKey ? null : getData(func), |
| 27124 | newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity]; |
| 27125 | |
| 27126 | if (data) { |
| 27127 | mergeData(newData, data); |
| 27128 | bitmask = newData[1]; |
| 27129 | arity = newData[9]; |
| 27130 | } |
| 27131 | newData[9] = arity == null |
| 27132 | ? (isBindKey ? 0 : func.length) |
| 27133 | : (nativeMax(arity - length, 0) || 0); |
| 27134 | |
| 27135 | if (bitmask == BIND_FLAG) { |
| 27136 | var result = createBindWrapper(newData[0], newData[2]); |
| 27137 | } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) { |
| 27138 | result = createPartialWrapper.apply(undefined, newData); |
| 27139 | } else { |
| 27140 | result = createHybridWrapper.apply(undefined, newData); |
| 27141 | } |
| 27142 | var setter = data ? baseSetData : setData; |
| 27143 | return setter(result, newData); |
| 27144 | } |
| 27145 | |
| 27146 | module.exports = createWrapper; |
| 27147 | |
| 27148 | },{"./baseSetData":91,"./createBindWrapper":103,"./createHybridWrapper":107,"./createPartialWrapper":108,"./getData":113,"./mergeData":131,"./setData":136}],110:[function(require,module,exports){ |
| 27149 | var arraySome = require('./arraySome'); |
| 27150 | |
| 27151 | /** |
| 27152 | * A specialized version of `baseIsEqualDeep` for arrays with support for |
| 27153 | * partial deep comparisons. |
| 27154 | * |
| 27155 | * @private |
| 27156 | * @param {Array} array The array to compare. |
| 27157 | * @param {Array} other The other array to compare. |
| 27158 | * @param {Function} equalFunc The function to determine equivalents of values. |
| 27159 | * @param {Function} [customizer] The function to customize comparing arrays. |
| 27160 | * @param {boolean} [isLoose] Specify performing partial comparisons. |
| 27161 | * @param {Array} [stackA] Tracks traversed `value` objects. |
| 27162 | * @param {Array} [stackB] Tracks traversed `other` objects. |
| 27163 | * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. |
| 27164 | */ |
| 27165 | function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) { |
| 27166 | var index = -1, |
| 27167 | arrLength = array.length, |
| 27168 | othLength = other.length; |
| 27169 | |
| 27170 | if (arrLength != othLength && !(isLoose && othLength > arrLength)) { |
| 27171 | return false; |
| 27172 | } |
| 27173 | // Ignore non-index properties. |
| 27174 | while (++index < arrLength) { |
| 27175 | var arrValue = array[index], |
| 27176 | othValue = other[index], |
| 27177 | result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined; |
| 27178 | |
| 27179 | if (result !== undefined) { |
| 27180 | if (result) { |
| 27181 | continue; |
| 27182 | } |
| 27183 | return false; |
| 27184 | } |
| 27185 | // Recursively compare arrays (susceptible to call stack limits). |
| 27186 | if (isLoose) { |
| 27187 | if (!arraySome(other, function(othValue) { |
| 27188 | return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB); |
| 27189 | })) { |
| 27190 | return false; |
| 27191 | } |
| 27192 | } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) { |
| 27193 | return false; |
| 27194 | } |
| 27195 | } |
| 27196 | return true; |
| 27197 | } |
| 27198 | |
| 27199 | module.exports = equalArrays; |
| 27200 | |
| 27201 | },{"./arraySome":67}],111:[function(require,module,exports){ |
| 27202 | /** `Object#toString` result references. */ |
| 27203 | var boolTag = '[object Boolean]', |
| 27204 | dateTag = '[object Date]', |
| 27205 | errorTag = '[object Error]', |
| 27206 | numberTag = '[object Number]', |
| 27207 | regexpTag = '[object RegExp]', |
| 27208 | stringTag = '[object String]'; |
| 27209 | |
| 27210 | /** |
| 27211 | * A specialized version of `baseIsEqualDeep` for comparing objects of |
| 27212 | * the same `toStringTag`. |
| 27213 | * |
| 27214 | * **Note:** This function only supports comparing values with tags of |
| 27215 | * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. |
| 27216 | * |
| 27217 | * @private |
| 27218 | * @param {Object} value The object to compare. |
| 27219 | * @param {Object} other The other object to compare. |
| 27220 | * @param {string} tag The `toStringTag` of the objects to compare. |
| 27221 | * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. |
| 27222 | */ |
| 27223 | function equalByTag(object, other, tag) { |
| 27224 | switch (tag) { |
| 27225 | case boolTag: |
| 27226 | case dateTag: |
| 27227 | // Coerce dates and booleans to numbers, dates to milliseconds and booleans |
| 27228 | // to `1` or `0` treating invalid dates coerced to `NaN` as not equal. |
| 27229 | return +object == +other; |
| 27230 | |
| 27231 | case errorTag: |
| 27232 | return object.name == other.name && object.message == other.message; |
| 27233 | |
| 27234 | case numberTag: |
| 27235 | // Treat `NaN` vs. `NaN` as equal. |
| 27236 | return (object != +object) |
| 27237 | ? other != +other |
| 27238 | : object == +other; |
| 27239 | |
| 27240 | case regexpTag: |
| 27241 | case stringTag: |
| 27242 | // Coerce regexes to strings and treat strings primitives and string |
| 27243 | // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details. |
| 27244 | return object == (other + ''); |
| 27245 | } |
| 27246 | return false; |
| 27247 | } |
| 27248 | |
| 27249 | module.exports = equalByTag; |
| 27250 | |
| 27251 | },{}],112:[function(require,module,exports){ |
| 27252 | var keys = require('../object/keys'); |
| 27253 | |
| 27254 | /** Used for native method references. */ |
| 27255 | var objectProto = Object.prototype; |
| 27256 | |
| 27257 | /** Used to check objects for own properties. */ |
| 27258 | var hasOwnProperty = objectProto.hasOwnProperty; |
| 27259 | |
| 27260 | /** |
| 27261 | * A specialized version of `baseIsEqualDeep` for objects with support for |
| 27262 | * partial deep comparisons. |
| 27263 | * |
| 27264 | * @private |
| 27265 | * @param {Object} object The object to compare. |
| 27266 | * @param {Object} other The other object to compare. |
| 27267 | * @param {Function} equalFunc The function to determine equivalents of values. |
| 27268 | * @param {Function} [customizer] The function to customize comparing values. |
| 27269 | * @param {boolean} [isLoose] Specify performing partial comparisons. |
| 27270 | * @param {Array} [stackA] Tracks traversed `value` objects. |
| 27271 | * @param {Array} [stackB] Tracks traversed `other` objects. |
| 27272 | * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. |
| 27273 | */ |
| 27274 | function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) { |
| 27275 | var objProps = keys(object), |
| 27276 | objLength = objProps.length, |
| 27277 | othProps = keys(other), |
| 27278 | othLength = othProps.length; |
| 27279 | |
| 27280 | if (objLength != othLength && !isLoose) { |
| 27281 | return false; |
| 27282 | } |
| 27283 | var index = objLength; |
| 27284 | while (index--) { |
| 27285 | var key = objProps[index]; |
| 27286 | if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) { |
| 27287 | return false; |
| 27288 | } |
| 27289 | } |
| 27290 | var skipCtor = isLoose; |
| 27291 | while (++index < objLength) { |
| 27292 | key = objProps[index]; |
| 27293 | var objValue = object[key], |
| 27294 | othValue = other[key], |
| 27295 | result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined; |
| 27296 | |
| 27297 | // Recursively compare objects (susceptible to call stack limits). |
| 27298 | if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) { |
| 27299 | return false; |
| 27300 | } |
| 27301 | skipCtor || (skipCtor = key == 'constructor'); |
| 27302 | } |
| 27303 | if (!skipCtor) { |
| 27304 | var objCtor = object.constructor, |
| 27305 | othCtor = other.constructor; |
| 27306 | |
| 27307 | // Non `Object` object instances with different constructors are not equal. |
| 27308 | if (objCtor != othCtor && |
| 27309 | ('constructor' in object && 'constructor' in other) && |
| 27310 | !(typeof objCtor == 'function' && objCtor instanceof objCtor && |
| 27311 | typeof othCtor == 'function' && othCtor instanceof othCtor)) { |
| 27312 | return false; |
| 27313 | } |
| 27314 | } |
| 27315 | return true; |
| 27316 | } |
| 27317 | |
| 27318 | module.exports = equalObjects; |
| 27319 | |
| 27320 | },{"../object/keys":153}],113:[function(require,module,exports){ |
| 27321 | var metaMap = require('./metaMap'), |
| 27322 | noop = require('../utility/noop'); |
| 27323 | |
| 27324 | /** |
| 27325 | * Gets metadata for `func`. |
| 27326 | * |
| 27327 | * @private |
| 27328 | * @param {Function} func The function to query. |
| 27329 | * @returns {*} Returns the metadata for `func`. |
| 27330 | */ |
| 27331 | var getData = !metaMap ? noop : function(func) { |
| 27332 | return metaMap.get(func); |
| 27333 | }; |
| 27334 | |
| 27335 | module.exports = getData; |
| 27336 | |
| 27337 | },{"../utility/noop":161,"./metaMap":132}],114:[function(require,module,exports){ |
| 27338 | var realNames = require('./realNames'); |
| 27339 | |
| 27340 | /** |
| 27341 | * Gets the name of `func`. |
| 27342 | * |
| 27343 | * @private |
| 27344 | * @param {Function} func The function to query. |
| 27345 | * @returns {string} Returns the function name. |
| 27346 | */ |
| 27347 | function getFuncName(func) { |
| 27348 | var result = func.name, |
| 27349 | array = realNames[result], |
| 27350 | length = array ? array.length : 0; |
| 27351 | |
| 27352 | while (length--) { |
| 27353 | var data = array[length], |
| 27354 | otherFunc = data.func; |
| 27355 | if (otherFunc == null || otherFunc == func) { |
| 27356 | return data.name; |
| 27357 | } |
| 27358 | } |
| 27359 | return result; |
| 27360 | } |
| 27361 | |
| 27362 | module.exports = getFuncName; |
| 27363 | |
| 27364 | },{"./realNames":133}],115:[function(require,module,exports){ |
| 27365 | var baseProperty = require('./baseProperty'); |
| 27366 | |
| 27367 | /** |
| 27368 | * Gets the "length" property value of `object`. |
| 27369 | * |
| 27370 | * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) |
| 27371 | * that affects Safari on at least iOS 8.1-8.3 ARM64. |
| 27372 | * |
| 27373 | * @private |
| 27374 | * @param {Object} object The object to query. |
| 27375 | * @returns {*} Returns the "length" value. |
| 27376 | */ |
| 27377 | var getLength = baseProperty('length'); |
| 27378 | |
| 27379 | module.exports = getLength; |
| 27380 | |
| 27381 | },{"./baseProperty":89}],116:[function(require,module,exports){ |
| 27382 | var isStrictComparable = require('./isStrictComparable'), |
| 27383 | pairs = require('../object/pairs'); |
| 27384 | |
| 27385 | /** |
| 27386 | * Gets the propery names, values, and compare flags of `object`. |
| 27387 | * |
| 27388 | * @private |
| 27389 | * @param {Object} object The object to query. |
| 27390 | * @returns {Array} Returns the match data of `object`. |
| 27391 | */ |
| 27392 | function getMatchData(object) { |
| 27393 | var result = pairs(object), |
| 27394 | length = result.length; |
| 27395 | |
| 27396 | while (length--) { |
| 27397 | result[length][2] = isStrictComparable(result[length][1]); |
| 27398 | } |
| 27399 | return result; |
| 27400 | } |
| 27401 | |
| 27402 | module.exports = getMatchData; |
| 27403 | |
| 27404 | },{"../object/pairs":155,"./isStrictComparable":130}],117:[function(require,module,exports){ |
| 27405 | var isNative = require('../lang/isNative'); |
| 27406 | |
| 27407 | /** |
| 27408 | * Gets the native function at `key` of `object`. |
| 27409 | * |
| 27410 | * @private |
| 27411 | * @param {Object} object The object to query. |
| 27412 | * @param {string} key The key of the method to get. |
| 27413 | * @returns {*} Returns the function if it's native, else `undefined`. |
| 27414 | */ |
| 27415 | function getNative(object, key) { |
| 27416 | var value = object == null ? undefined : object[key]; |
| 27417 | return isNative(value) ? value : undefined; |
| 27418 | } |
| 27419 | |
| 27420 | module.exports = getNative; |
| 27421 | |
| 27422 | },{"../lang/isNative":147}],118:[function(require,module,exports){ |
| 27423 | /** |
| 27424 | * Gets the index at which the first occurrence of `NaN` is found in `array`. |
| 27425 | * |
| 27426 | * @private |
| 27427 | * @param {Array} array The array to search. |
| 27428 | * @param {number} fromIndex The index to search from. |
| 27429 | * @param {boolean} [fromRight] Specify iterating from right to left. |
| 27430 | * @returns {number} Returns the index of the matched `NaN`, else `-1`. |
| 27431 | */ |
| 27432 | function indexOfNaN(array, fromIndex, fromRight) { |
| 27433 | var length = array.length, |
| 27434 | index = fromIndex + (fromRight ? 0 : -1); |
| 27435 | |
| 27436 | while ((fromRight ? index-- : ++index < length)) { |
| 27437 | var other = array[index]; |
| 27438 | if (other !== other) { |
| 27439 | return index; |
| 27440 | } |
| 27441 | } |
| 27442 | return -1; |
| 27443 | } |
| 27444 | |
| 27445 | module.exports = indexOfNaN; |
| 27446 | |
| 27447 | },{}],119:[function(require,module,exports){ |
| 27448 | /** Used for native method references. */ |
| 27449 | var objectProto = Object.prototype; |
| 27450 | |
| 27451 | /** Used to check objects for own properties. */ |
| 27452 | var hasOwnProperty = objectProto.hasOwnProperty; |
| 27453 | |
| 27454 | /** |
| 27455 | * Initializes an array clone. |
| 27456 | * |
| 27457 | * @private |
| 27458 | * @param {Array} array The array to clone. |
| 27459 | * @returns {Array} Returns the initialized clone. |
| 27460 | */ |
| 27461 | function initCloneArray(array) { |
| 27462 | var length = array.length, |
| 27463 | result = new array.constructor(length); |
| 27464 | |
| 27465 | // Add array properties assigned by `RegExp#exec`. |
| 27466 | if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { |
| 27467 | result.index = array.index; |
| 27468 | result.input = array.input; |
| 27469 | } |
| 27470 | return result; |
| 27471 | } |
| 27472 | |
| 27473 | module.exports = initCloneArray; |
| 27474 | |
| 27475 | },{}],120:[function(require,module,exports){ |
| 27476 | (function (global){ |
| 27477 | var bufferClone = require('./bufferClone'); |
| 27478 | |
| 27479 | /** `Object#toString` result references. */ |
| 27480 | var boolTag = '[object Boolean]', |
| 27481 | dateTag = '[object Date]', |
| 27482 | numberTag = '[object Number]', |
| 27483 | regexpTag = '[object RegExp]', |
| 27484 | stringTag = '[object String]'; |
| 27485 | |
| 27486 | var arrayBufferTag = '[object ArrayBuffer]', |
| 27487 | float32Tag = '[object Float32Array]', |
| 27488 | float64Tag = '[object Float64Array]', |
| 27489 | int8Tag = '[object Int8Array]', |
| 27490 | int16Tag = '[object Int16Array]', |
| 27491 | int32Tag = '[object Int32Array]', |
| 27492 | uint8Tag = '[object Uint8Array]', |
| 27493 | uint8ClampedTag = '[object Uint8ClampedArray]', |
| 27494 | uint16Tag = '[object Uint16Array]', |
| 27495 | uint32Tag = '[object Uint32Array]'; |
| 27496 | |
| 27497 | /** Used to match `RegExp` flags from their coerced string values. */ |
| 27498 | var reFlags = /\w*$/; |
| 27499 | |
| 27500 | /** Used to lookup a type array constructors by `toStringTag`. */ |
| 27501 | var ctorByTag = {}; |
| 27502 | ctorByTag[float32Tag] = global.Float32Array; |
| 27503 | ctorByTag[float64Tag] = global.Float64Array; |
| 27504 | ctorByTag[int8Tag] = global.Int8Array; |
| 27505 | ctorByTag[int16Tag] = global.Int16Array; |
| 27506 | ctorByTag[int32Tag] = global.Int32Array; |
| 27507 | ctorByTag[uint8Tag] = global.Uint8Array; |
| 27508 | ctorByTag[uint8ClampedTag] = global.Uint8ClampedArray; |
| 27509 | ctorByTag[uint16Tag] = global.Uint16Array; |
| 27510 | ctorByTag[uint32Tag] = global.Uint32Array; |
| 27511 | |
| 27512 | /** |
| 27513 | * Initializes an object clone based on its `toStringTag`. |
| 27514 | * |
| 27515 | * **Note:** This function only supports cloning values with tags of |
| 27516 | * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. |
| 27517 | * |
| 27518 | * @private |
| 27519 | * @param {Object} object The object to clone. |
| 27520 | * @param {string} tag The `toStringTag` of the object to clone. |
| 27521 | * @param {boolean} [isDeep] Specify a deep clone. |
| 27522 | * @returns {Object} Returns the initialized clone. |
| 27523 | */ |
| 27524 | function initCloneByTag(object, tag, isDeep) { |
| 27525 | var Ctor = object.constructor; |
| 27526 | switch (tag) { |
| 27527 | case arrayBufferTag: |
| 27528 | return bufferClone(object); |
| 27529 | |
| 27530 | case boolTag: |
| 27531 | case dateTag: |
| 27532 | return new Ctor(+object); |
| 27533 | |
| 27534 | case float32Tag: case float64Tag: |
| 27535 | case int8Tag: case int16Tag: case int32Tag: |
| 27536 | case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: |
| 27537 | // Safari 5 mobile incorrectly has `Object` as the constructor of typed arrays. |
| 27538 | if (Ctor instanceof Ctor) { |
| 27539 | Ctor = ctorByTag[tag]; |
| 27540 | } |
| 27541 | var buffer = object.buffer; |
| 27542 | return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length); |
| 27543 | |
| 27544 | case numberTag: |
| 27545 | case stringTag: |
| 27546 | return new Ctor(object); |
| 27547 | |
| 27548 | case regexpTag: |
| 27549 | var result = new Ctor(object.source, reFlags.exec(object)); |
| 27550 | result.lastIndex = object.lastIndex; |
| 27551 | } |
| 27552 | return result; |
| 27553 | } |
| 27554 | |
| 27555 | module.exports = initCloneByTag; |
| 27556 | |
| 27557 | }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
| 27558 | |
| 27559 | },{"./bufferClone":98}],121:[function(require,module,exports){ |
| 27560 | /** |
| 27561 | * Initializes an object clone. |
| 27562 | * |
| 27563 | * @private |
| 27564 | * @param {Object} object The object to clone. |
| 27565 | * @returns {Object} Returns the initialized clone. |
| 27566 | */ |
| 27567 | function initCloneObject(object) { |
| 27568 | var Ctor = object.constructor; |
| 27569 | if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) { |
| 27570 | Ctor = Object; |
| 27571 | } |
| 27572 | return new Ctor; |
| 27573 | } |
| 27574 | |
| 27575 | module.exports = initCloneObject; |
| 27576 | |
| 27577 | },{}],122:[function(require,module,exports){ |
| 27578 | var getLength = require('./getLength'), |
| 27579 | isLength = require('./isLength'); |
| 27580 | |
| 27581 | /** |
| 27582 | * Checks if `value` is array-like. |
| 27583 | * |
| 27584 | * @private |
| 27585 | * @param {*} value The value to check. |
| 27586 | * @returns {boolean} Returns `true` if `value` is array-like, else `false`. |
| 27587 | */ |
| 27588 | function isArrayLike(value) { |
| 27589 | return value != null && isLength(getLength(value)); |
| 27590 | } |
| 27591 | |
| 27592 | module.exports = isArrayLike; |
| 27593 | |
| 27594 | },{"./getLength":115,"./isLength":128}],123:[function(require,module,exports){ |
| 27595 | /** |
| 27596 | * Checks if `value` is a host object in IE < 9. |
| 27597 | * |
| 27598 | * @private |
| 27599 | * @param {*} value The value to check. |
| 27600 | * @returns {boolean} Returns `true` if `value` is a host object, else `false`. |
| 27601 | */ |
| 27602 | var isHostObject = (function() { |
| 27603 | try { |
| 27604 | Object({ 'toString': 0 } + ''); |
| 27605 | } catch(e) { |
| 27606 | return function() { return false; }; |
| 27607 | } |
| 27608 | return function(value) { |
| 27609 | // IE < 9 presents many host objects as `Object` objects that can coerce |
| 27610 | // to strings despite having improperly defined `toString` methods. |
| 27611 | return typeof value.toString != 'function' && typeof (value + '') == 'string'; |
| 27612 | }; |
| 27613 | }()); |
| 27614 | |
| 27615 | module.exports = isHostObject; |
| 27616 | |
| 27617 | },{}],124:[function(require,module,exports){ |
| 27618 | /** Used to detect unsigned integer values. */ |
| 27619 | var reIsUint = /^\d+$/; |
| 27620 | |
| 27621 | /** |
| 27622 | * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer) |
| 27623 | * of an array-like value. |
| 27624 | */ |
| 27625 | var MAX_SAFE_INTEGER = 9007199254740991; |
| 27626 | |
| 27627 | /** |
| 27628 | * Checks if `value` is a valid array-like index. |
| 27629 | * |
| 27630 | * @private |
| 27631 | * @param {*} value The value to check. |
| 27632 | * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. |
| 27633 | * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. |
| 27634 | */ |
| 27635 | function isIndex(value, length) { |
| 27636 | value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; |
| 27637 | length = length == null ? MAX_SAFE_INTEGER : length; |
| 27638 | return value > -1 && value % 1 == 0 && value < length; |
| 27639 | } |
| 27640 | |
| 27641 | module.exports = isIndex; |
| 27642 | |
| 27643 | },{}],125:[function(require,module,exports){ |
| 27644 | var isArrayLike = require('./isArrayLike'), |
| 27645 | isIndex = require('./isIndex'), |
| 27646 | isObject = require('../lang/isObject'); |
| 27647 | |
| 27648 | /** |
| 27649 | * Checks if the provided arguments are from an iteratee call. |
| 27650 | * |
| 27651 | * @private |
| 27652 | * @param {*} value The potential iteratee value argument. |
| 27653 | * @param {*} index The potential iteratee index or key argument. |
| 27654 | * @param {*} object The potential iteratee object argument. |
| 27655 | * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`. |
| 27656 | */ |
| 27657 | function isIterateeCall(value, index, object) { |
| 27658 | if (!isObject(object)) { |
| 27659 | return false; |
| 27660 | } |
| 27661 | var type = typeof index; |
| 27662 | if (type == 'number' |
| 27663 | ? (isArrayLike(object) && isIndex(index, object.length)) |
| 27664 | : (type == 'string' && index in object)) { |
| 27665 | var other = object[index]; |
| 27666 | return value === value ? (value === other) : (other !== other); |
| 27667 | } |
| 27668 | return false; |
| 27669 | } |
| 27670 | |
| 27671 | module.exports = isIterateeCall; |
| 27672 | |
| 27673 | },{"../lang/isObject":148,"./isArrayLike":122,"./isIndex":124}],126:[function(require,module,exports){ |
| 27674 | var isArray = require('../lang/isArray'), |
| 27675 | toObject = require('./toObject'); |
| 27676 | |
| 27677 | /** Used to match property names within property paths. */ |
| 27678 | var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/, |
| 27679 | reIsPlainProp = /^\w*$/; |
| 27680 | |
| 27681 | /** |
| 27682 | * Checks if `value` is a property name and not a property path. |
| 27683 | * |
| 27684 | * @private |
| 27685 | * @param {*} value The value to check. |
| 27686 | * @param {Object} [object] The object to query keys on. |
| 27687 | * @returns {boolean} Returns `true` if `value` is a property name, else `false`. |
| 27688 | */ |
| 27689 | function isKey(value, object) { |
| 27690 | var type = typeof value; |
| 27691 | if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') { |
| 27692 | return true; |
| 27693 | } |
| 27694 | if (isArray(value)) { |
| 27695 | return false; |
| 27696 | } |
| 27697 | var result = !reIsDeepProp.test(value); |
| 27698 | return result || (object != null && value in toObject(object)); |
| 27699 | } |
| 27700 | |
| 27701 | module.exports = isKey; |
| 27702 | |
| 27703 | },{"../lang/isArray":144,"./toObject":139}],127:[function(require,module,exports){ |
| 27704 | var LazyWrapper = require('./LazyWrapper'), |
| 27705 | getData = require('./getData'), |
| 27706 | getFuncName = require('./getFuncName'), |
| 27707 | lodash = require('../chain/lodash'); |
| 27708 | |
| 27709 | /** |
| 27710 | * Checks if `func` has a lazy counterpart. |
| 27711 | * |
| 27712 | * @private |
| 27713 | * @param {Function} func The function to check. |
| 27714 | * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`. |
| 27715 | */ |
| 27716 | function isLaziable(func) { |
| 27717 | var funcName = getFuncName(func); |
| 27718 | if (!(funcName in LazyWrapper.prototype)) { |
| 27719 | return false; |
| 27720 | } |
| 27721 | var other = lodash[funcName]; |
| 27722 | if (func === other) { |
| 27723 | return true; |
| 27724 | } |
| 27725 | var data = getData(other); |
| 27726 | return !!data && func === data[0]; |
| 27727 | } |
| 27728 | |
| 27729 | module.exports = isLaziable; |
| 27730 | |
| 27731 | },{"../chain/lodash":53,"./LazyWrapper":62,"./getData":113,"./getFuncName":114}],128:[function(require,module,exports){ |
| 27732 | /** |
| 27733 | * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer) |
| 27734 | * of an array-like value. |
| 27735 | */ |
| 27736 | var MAX_SAFE_INTEGER = 9007199254740991; |
| 27737 | |
| 27738 | /** |
| 27739 | * Checks if `value` is a valid array-like length. |
| 27740 | * |
| 27741 | * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength). |
| 27742 | * |
| 27743 | * @private |
| 27744 | * @param {*} value The value to check. |
| 27745 | * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. |
| 27746 | */ |
| 27747 | function isLength(value) { |
| 27748 | return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; |
| 27749 | } |
| 27750 | |
| 27751 | module.exports = isLength; |
| 27752 | |
| 27753 | },{}],129:[function(require,module,exports){ |
| 27754 | /** |
| 27755 | * Checks if `value` is object-like. |
| 27756 | * |
| 27757 | * @private |
| 27758 | * @param {*} value The value to check. |
| 27759 | * @returns {boolean} Returns `true` if `value` is object-like, else `false`. |
| 27760 | */ |
| 27761 | function isObjectLike(value) { |
| 27762 | return !!value && typeof value == 'object'; |
| 27763 | } |
| 27764 | |
| 27765 | module.exports = isObjectLike; |
| 27766 | |
| 27767 | },{}],130:[function(require,module,exports){ |
| 27768 | var isObject = require('../lang/isObject'); |
| 27769 | |
| 27770 | /** |
| 27771 | * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. |
| 27772 | * |
| 27773 | * @private |
| 27774 | * @param {*} value The value to check. |
| 27775 | * @returns {boolean} Returns `true` if `value` if suitable for strict |
| 27776 | * equality comparisons, else `false`. |
| 27777 | */ |
| 27778 | function isStrictComparable(value) { |
| 27779 | return value === value && !isObject(value); |
| 27780 | } |
| 27781 | |
| 27782 | module.exports = isStrictComparable; |
| 27783 | |
| 27784 | },{"../lang/isObject":148}],131:[function(require,module,exports){ |
| 27785 | var arrayCopy = require('./arrayCopy'), |
| 27786 | composeArgs = require('./composeArgs'), |
| 27787 | composeArgsRight = require('./composeArgsRight'), |
| 27788 | replaceHolders = require('./replaceHolders'); |
| 27789 | |
| 27790 | /** Used to compose bitmasks for wrapper metadata. */ |
| 27791 | var BIND_FLAG = 1, |
| 27792 | CURRY_BOUND_FLAG = 4, |
| 27793 | CURRY_FLAG = 8, |
| 27794 | ARY_FLAG = 128, |
| 27795 | REARG_FLAG = 256; |
| 27796 | |
| 27797 | /** Used as the internal argument placeholder. */ |
| 27798 | var PLACEHOLDER = '__lodash_placeholder__'; |
| 27799 | |
| 27800 | /* Native method references for those with the same name as other `lodash` methods. */ |
| 27801 | var nativeMin = Math.min; |
| 27802 | |
| 27803 | /** |
| 27804 | * Merges the function metadata of `source` into `data`. |
| 27805 | * |
| 27806 | * Merging metadata reduces the number of wrappers required to invoke a function. |
| 27807 | * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` |
| 27808 | * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg` |
| 27809 | * augment function arguments, making the order in which they are executed important, |
| 27810 | * preventing the merging of metadata. However, we make an exception for a safe |
| 27811 | * common case where curried functions have `_.ary` and or `_.rearg` applied. |
| 27812 | * |
| 27813 | * @private |
| 27814 | * @param {Array} data The destination metadata. |
| 27815 | * @param {Array} source The source metadata. |
| 27816 | * @returns {Array} Returns `data`. |
| 27817 | */ |
| 27818 | function mergeData(data, source) { |
| 27819 | var bitmask = data[1], |
| 27820 | srcBitmask = source[1], |
| 27821 | newBitmask = bitmask | srcBitmask, |
| 27822 | isCommon = newBitmask < ARY_FLAG; |
| 27823 | |
| 27824 | var isCombo = |
| 27825 | (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) || |
| 27826 | (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) || |
| 27827 | (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG); |
| 27828 | |
| 27829 | // Exit early if metadata can't be merged. |
| 27830 | if (!(isCommon || isCombo)) { |
| 27831 | return data; |
| 27832 | } |
| 27833 | // Use source `thisArg` if available. |
| 27834 | if (srcBitmask & BIND_FLAG) { |
| 27835 | data[2] = source[2]; |
| 27836 | // Set when currying a bound function. |
| 27837 | newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG; |
| 27838 | } |
| 27839 | // Compose partial arguments. |
| 27840 | var value = source[3]; |
| 27841 | if (value) { |
| 27842 | var partials = data[3]; |
| 27843 | data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value); |
| 27844 | data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]); |
| 27845 | } |
| 27846 | // Compose partial right arguments. |
| 27847 | value = source[5]; |
| 27848 | if (value) { |
| 27849 | partials = data[5]; |
| 27850 | data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value); |
| 27851 | data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]); |
| 27852 | } |
| 27853 | // Use source `argPos` if available. |
| 27854 | value = source[7]; |
| 27855 | if (value) { |
| 27856 | data[7] = arrayCopy(value); |
| 27857 | } |
| 27858 | // Use source `ary` if it's smaller. |
| 27859 | if (srcBitmask & ARY_FLAG) { |
| 27860 | data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); |
| 27861 | } |
| 27862 | // Use source `arity` if one is not provided. |
| 27863 | if (data[9] == null) { |
| 27864 | data[9] = source[9]; |
| 27865 | } |
| 27866 | // Use source `func` and merge bitmasks. |
| 27867 | data[0] = source[0]; |
| 27868 | data[1] = newBitmask; |
| 27869 | |
| 27870 | return data; |
| 27871 | } |
| 27872 | |
| 27873 | module.exports = mergeData; |
| 27874 | |
| 27875 | },{"./arrayCopy":64,"./composeArgs":99,"./composeArgsRight":100,"./replaceHolders":135}],132:[function(require,module,exports){ |
| 27876 | (function (global){ |
| 27877 | var getNative = require('./getNative'); |
| 27878 | |
| 27879 | /** Native method references. */ |
| 27880 | var WeakMap = getNative(global, 'WeakMap'); |
| 27881 | |
| 27882 | /** Used to store function metadata. */ |
| 27883 | var metaMap = WeakMap && new WeakMap; |
| 27884 | |
| 27885 | module.exports = metaMap; |
| 27886 | |
| 27887 | }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
| 27888 | |
| 27889 | },{"./getNative":117}],133:[function(require,module,exports){ |
| 27890 | /** Used to lookup unminified function names. */ |
| 27891 | var realNames = {}; |
| 27892 | |
| 27893 | module.exports = realNames; |
| 27894 | |
| 27895 | },{}],134:[function(require,module,exports){ |
| 27896 | var arrayCopy = require('./arrayCopy'), |
| 27897 | isIndex = require('./isIndex'); |
| 27898 | |
| 27899 | /* Native method references for those with the same name as other `lodash` methods. */ |
| 27900 | var nativeMin = Math.min; |
| 27901 | |
| 27902 | /** |
| 27903 | * Reorder `array` according to the specified indexes where the element at |
| 27904 | * the first index is assigned as the first element, the element at |
| 27905 | * the second index is assigned as the second element, and so on. |
| 27906 | * |
| 27907 | * @private |
| 27908 | * @param {Array} array The array to reorder. |
| 27909 | * @param {Array} indexes The arranged array indexes. |
| 27910 | * @returns {Array} Returns `array`. |
| 27911 | */ |
| 27912 | function reorder(array, indexes) { |
| 27913 | var arrLength = array.length, |
| 27914 | length = nativeMin(indexes.length, arrLength), |
| 27915 | oldArray = arrayCopy(array); |
| 27916 | |
| 27917 | while (length--) { |
| 27918 | var index = indexes[length]; |
| 27919 | array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; |
| 27920 | } |
| 27921 | return array; |
| 27922 | } |
| 27923 | |
| 27924 | module.exports = reorder; |
| 27925 | |
| 27926 | },{"./arrayCopy":64,"./isIndex":124}],135:[function(require,module,exports){ |
| 27927 | /** Used as the internal argument placeholder. */ |
| 27928 | var PLACEHOLDER = '__lodash_placeholder__'; |
| 27929 | |
| 27930 | /** |
| 27931 | * Replaces all `placeholder` elements in `array` with an internal placeholder |
| 27932 | * and returns an array of their indexes. |
| 27933 | * |
| 27934 | * @private |
| 27935 | * @param {Array} array The array to modify. |
| 27936 | * @param {*} placeholder The placeholder to replace. |
| 27937 | * @returns {Array} Returns the new array of placeholder indexes. |
| 27938 | */ |
| 27939 | function replaceHolders(array, placeholder) { |
| 27940 | var index = -1, |
| 27941 | length = array.length, |
| 27942 | resIndex = -1, |
| 27943 | result = []; |
| 27944 | |
| 27945 | while (++index < length) { |
| 27946 | if (array[index] === placeholder) { |
| 27947 | array[index] = PLACEHOLDER; |
| 27948 | result[++resIndex] = index; |
| 27949 | } |
| 27950 | } |
| 27951 | return result; |
| 27952 | } |
| 27953 | |
| 27954 | module.exports = replaceHolders; |
| 27955 | |
| 27956 | },{}],136:[function(require,module,exports){ |
| 27957 | var baseSetData = require('./baseSetData'), |
| 27958 | now = require('../date/now'); |
| 27959 | |
| 27960 | /** Used to detect when a function becomes hot. */ |
| 27961 | var HOT_COUNT = 150, |
| 27962 | HOT_SPAN = 16; |
| 27963 | |
| 27964 | /** |
| 27965 | * Sets metadata for `func`. |
| 27966 | * |
| 27967 | * **Note:** If this function becomes hot, i.e. is invoked a lot in a short |
| 27968 | * period of time, it will trip its breaker and transition to an identity function |
| 27969 | * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070) |
| 27970 | * for more details. |
| 27971 | * |
| 27972 | * @private |
| 27973 | * @param {Function} func The function to associate metadata with. |
| 27974 | * @param {*} data The metadata. |
| 27975 | * @returns {Function} Returns `func`. |
| 27976 | */ |
| 27977 | var setData = (function() { |
| 27978 | var count = 0, |
| 27979 | lastCalled = 0; |
| 27980 | |
| 27981 | return function(key, value) { |
| 27982 | var stamp = now(), |
| 27983 | remaining = HOT_SPAN - (stamp - lastCalled); |
| 27984 | |
| 27985 | lastCalled = stamp; |
| 27986 | if (remaining > 0) { |
| 27987 | if (++count >= HOT_COUNT) { |
| 27988 | return key; |
| 27989 | } |
| 27990 | } else { |
| 27991 | count = 0; |
| 27992 | } |
| 27993 | return baseSetData(key, value); |
| 27994 | }; |
| 27995 | }()); |
| 27996 | |
| 27997 | module.exports = setData; |
| 27998 | |
| 27999 | },{"../date/now":59,"./baseSetData":91}],137:[function(require,module,exports){ |
| 28000 | var baseForIn = require('./baseForIn'), |
| 28001 | isArguments = require('../lang/isArguments'), |
| 28002 | isHostObject = require('./isHostObject'), |
| 28003 | isObjectLike = require('./isObjectLike'), |
| 28004 | support = require('../support'); |
| 28005 | |
| 28006 | /** `Object#toString` result references. */ |
| 28007 | var objectTag = '[object Object]'; |
| 28008 | |
| 28009 | /** Used for native method references. */ |
| 28010 | var objectProto = Object.prototype; |
| 28011 | |
| 28012 | /** Used to check objects for own properties. */ |
| 28013 | var hasOwnProperty = objectProto.hasOwnProperty; |
| 28014 | |
| 28015 | /** |
| 28016 | * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring) |
| 28017 | * of values. |
| 28018 | */ |
| 28019 | var objToString = objectProto.toString; |
| 28020 | |
| 28021 | /** |
| 28022 | * A fallback implementation of `_.isPlainObject` which checks if `value` |
| 28023 | * is an object created by the `Object` constructor or has a `[[Prototype]]` |
| 28024 | * of `null`. |
| 28025 | * |
| 28026 | * @private |
| 28027 | * @param {*} value The value to check. |
| 28028 | * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. |
| 28029 | */ |
| 28030 | function shimIsPlainObject(value) { |
| 28031 | var Ctor; |
| 28032 | |
| 28033 | // Exit early for non `Object` objects. |
| 28034 | if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isHostObject(value)) || |
| 28035 | (!hasOwnProperty.call(value, 'constructor') && |
| 28036 | (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor))) || |
| 28037 | (!support.argsTag && isArguments(value))) { |
| 28038 | return false; |
| 28039 | } |
| 28040 | // IE < 9 iterates inherited properties before own properties. If the first |
| 28041 | // iterated property is an object's own property then there are no inherited |
| 28042 | // enumerable properties. |
| 28043 | var result; |
| 28044 | if (support.ownLast) { |
| 28045 | baseForIn(value, function(subValue, key, object) { |
| 28046 | result = hasOwnProperty.call(object, key); |
| 28047 | return false; |
| 28048 | }); |
| 28049 | return result !== false; |
| 28050 | } |
| 28051 | // In most environments an object's own properties are iterated before |
| 28052 | // its inherited properties. If the last iterated property is an object's |
| 28053 | // own property then there are no inherited enumerable properties. |
| 28054 | baseForIn(value, function(subValue, key) { |
| 28055 | result = key; |
| 28056 | }); |
| 28057 | return result === undefined || hasOwnProperty.call(value, result); |
| 28058 | } |
| 28059 | |
| 28060 | module.exports = shimIsPlainObject; |
| 28061 | |
| 28062 | },{"../lang/isArguments":143,"../support":158,"./baseForIn":77,"./isHostObject":123,"./isObjectLike":129}],138:[function(require,module,exports){ |
| 28063 | var isArguments = require('../lang/isArguments'), |
| 28064 | isArray = require('../lang/isArray'), |
| 28065 | isIndex = require('./isIndex'), |
| 28066 | isLength = require('./isLength'), |
| 28067 | isString = require('../lang/isString'), |
| 28068 | keysIn = require('../object/keysIn'); |
| 28069 | |
| 28070 | /** Used for native method references. */ |
| 28071 | var objectProto = Object.prototype; |
| 28072 | |
| 28073 | /** Used to check objects for own properties. */ |
| 28074 | var hasOwnProperty = objectProto.hasOwnProperty; |
| 28075 | |
| 28076 | /** |
| 28077 | * A fallback implementation of `Object.keys` which creates an array of the |
| 28078 | * own enumerable property names of `object`. |
| 28079 | * |
| 28080 | * @private |
| 28081 | * @param {Object} object The object to query. |
| 28082 | * @returns {Array} Returns the array of property names. |
| 28083 | */ |
| 28084 | function shimKeys(object) { |
| 28085 | var props = keysIn(object), |
| 28086 | propsLength = props.length, |
| 28087 | length = propsLength && object.length; |
| 28088 | |
| 28089 | var allowIndexes = !!length && isLength(length) && |
| 28090 | (isArray(object) || isArguments(object) || isString(object)); |
| 28091 | |
| 28092 | var index = -1, |
| 28093 | result = []; |
| 28094 | |
| 28095 | while (++index < propsLength) { |
| 28096 | var key = props[index]; |
| 28097 | if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { |
| 28098 | result.push(key); |
| 28099 | } |
| 28100 | } |
| 28101 | return result; |
| 28102 | } |
| 28103 | |
| 28104 | module.exports = shimKeys; |
| 28105 | |
| 28106 | },{"../lang/isArguments":143,"../lang/isArray":144,"../lang/isString":150,"../object/keysIn":154,"./isIndex":124,"./isLength":128}],139:[function(require,module,exports){ |
| 28107 | var isObject = require('../lang/isObject'), |
| 28108 | isString = require('../lang/isString'), |
| 28109 | support = require('../support'); |
| 28110 | |
| 28111 | /** |
| 28112 | * Converts `value` to an object if it's not one. |
| 28113 | * |
| 28114 | * @private |
| 28115 | * @param {*} value The value to process. |
| 28116 | * @returns {Object} Returns the object. |
| 28117 | */ |
| 28118 | function toObject(value) { |
| 28119 | if (support.unindexedChars && isString(value)) { |
| 28120 | var index = -1, |
| 28121 | length = value.length, |
| 28122 | result = Object(value); |
| 28123 | |
| 28124 | while (++index < length) { |
| 28125 | result[index] = value.charAt(index); |
| 28126 | } |
| 28127 | return result; |
| 28128 | } |
| 28129 | return isObject(value) ? value : Object(value); |
| 28130 | } |
| 28131 | |
| 28132 | module.exports = toObject; |
| 28133 | |
| 28134 | },{"../lang/isObject":148,"../lang/isString":150,"../support":158}],140:[function(require,module,exports){ |
| 28135 | var baseToString = require('./baseToString'), |
| 28136 | isArray = require('../lang/isArray'); |
| 28137 | |
| 28138 | /** Used to match property names within property paths. */ |
| 28139 | var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g; |
| 28140 | |
| 28141 | /** Used to match backslashes in property paths. */ |
| 28142 | var reEscapeChar = /\\(\\)?/g; |
| 28143 | |
| 28144 | /** |
| 28145 | * Converts `value` to property path array if it's not one. |
| 28146 | * |
| 28147 | * @private |
| 28148 | * @param {*} value The value to process. |
| 28149 | * @returns {Array} Returns the property path array. |
| 28150 | */ |
| 28151 | function toPath(value) { |
| 28152 | if (isArray(value)) { |
| 28153 | return value; |
| 28154 | } |
| 28155 | var result = []; |
| 28156 | baseToString(value).replace(rePropName, function(match, number, quote, string) { |
| 28157 | result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); |
| 28158 | }); |
| 28159 | return result; |
| 28160 | } |
| 28161 | |
| 28162 | module.exports = toPath; |
| 28163 | |
| 28164 | },{"../lang/isArray":144,"./baseToString":93}],141:[function(require,module,exports){ |
| 28165 | var LazyWrapper = require('./LazyWrapper'), |
| 28166 | LodashWrapper = require('./LodashWrapper'), |
| 28167 | arrayCopy = require('./arrayCopy'); |
| 28168 | |
| 28169 | /** |
| 28170 | * Creates a clone of `wrapper`. |
| 28171 | * |
| 28172 | * @private |
| 28173 | * @param {Object} wrapper The wrapper to clone. |
| 28174 | * @returns {Object} Returns the cloned wrapper. |
| 28175 | */ |
| 28176 | function wrapperClone(wrapper) { |
| 28177 | return wrapper instanceof LazyWrapper |
| 28178 | ? wrapper.clone() |
| 28179 | : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__)); |
| 28180 | } |
| 28181 | |
| 28182 | module.exports = wrapperClone; |
| 28183 | |
| 28184 | },{"./LazyWrapper":62,"./LodashWrapper":63,"./arrayCopy":64}],142:[function(require,module,exports){ |
| 28185 | var baseClone = require('../internal/baseClone'), |
| 28186 | bindCallback = require('../internal/bindCallback'); |
| 28187 | |
| 28188 | /** |
| 28189 | * Creates a deep clone of `value`. If `customizer` is provided it is invoked |
| 28190 | * to produce the cloned values. If `customizer` returns `undefined` cloning |
| 28191 | * is handled by the method instead. The `customizer` is bound to `thisArg` |
| 28192 | * and invoked with two argument; (value [, index|key, object]). |
| 28193 | * |
| 28194 | * **Note:** This method is loosely based on the |
| 28195 | * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm). |
| 28196 | * The enumerable properties of `arguments` objects and objects created by |
| 28197 | * constructors other than `Object` are cloned to plain `Object` objects. An |
| 28198 | * empty object is returned for uncloneable values such as functions, DOM nodes, |
| 28199 | * Maps, Sets, and WeakMaps. |
| 28200 | * |
| 28201 | * @static |
| 28202 | * @memberOf _ |
| 28203 | * @category Lang |
| 28204 | * @param {*} value The value to deep clone. |
| 28205 | * @param {Function} [customizer] The function to customize cloning values. |
| 28206 | * @param {*} [thisArg] The `this` binding of `customizer`. |
| 28207 | * @returns {*} Returns the deep cloned value. |
| 28208 | * @example |
| 28209 | * |
| 28210 | * var users = [ |
| 28211 | * { 'user': 'barney' }, |
| 28212 | * { 'user': 'fred' } |
| 28213 | * ]; |
| 28214 | * |
| 28215 | * var deep = _.cloneDeep(users); |
| 28216 | * deep[0] === users[0]; |
| 28217 | * // => false |
| 28218 | * |
| 28219 | * // using a customizer callback |
| 28220 | * var el = _.cloneDeep(document.body, function(value) { |
| 28221 | * if (_.isElement(value)) { |
| 28222 | * return value.cloneNode(true); |
| 28223 | * } |
| 28224 | * }); |
| 28225 | * |
| 28226 | * el === document.body |
| 28227 | * // => false |
| 28228 | * el.nodeName |
| 28229 | * // => BODY |
| 28230 | * el.childNodes.length; |
| 28231 | * // => 20 |
| 28232 | */ |
| 28233 | function cloneDeep(value, customizer, thisArg) { |
| 28234 | return typeof customizer == 'function' |
| 28235 | ? baseClone(value, true, bindCallback(customizer, thisArg, 1)) |
| 28236 | : baseClone(value, true); |
| 28237 | } |
| 28238 | |
| 28239 | module.exports = cloneDeep; |
| 28240 | |
| 28241 | },{"../internal/baseClone":70,"../internal/bindCallback":97}],143:[function(require,module,exports){ |
| 28242 | var isArrayLike = require('../internal/isArrayLike'), |
| 28243 | isObjectLike = require('../internal/isObjectLike'), |
| 28244 | support = require('../support'); |
| 28245 | |
| 28246 | /** `Object#toString` result references. */ |
| 28247 | var argsTag = '[object Arguments]'; |
| 28248 | |
| 28249 | /** Used for native method references. */ |
| 28250 | var objectProto = Object.prototype; |
| 28251 | |
| 28252 | /** Used to check objects for own properties. */ |
| 28253 | var hasOwnProperty = objectProto.hasOwnProperty; |
| 28254 | |
| 28255 | /** |
| 28256 | * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring) |
| 28257 | * of values. |
| 28258 | */ |
| 28259 | var objToString = objectProto.toString; |
| 28260 | |
| 28261 | /** Native method references. */ |
| 28262 | var propertyIsEnumerable = objectProto.propertyIsEnumerable; |
| 28263 | |
| 28264 | /** |
| 28265 | * Checks if `value` is classified as an `arguments` object. |
| 28266 | * |
| 28267 | * @static |
| 28268 | * @memberOf _ |
| 28269 | * @category Lang |
| 28270 | * @param {*} value The value to check. |
| 28271 | * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
| 28272 | * @example |
| 28273 | * |
| 28274 | * _.isArguments(function() { return arguments; }()); |
| 28275 | * // => true |
| 28276 | * |
| 28277 | * _.isArguments([1, 2, 3]); |
| 28278 | * // => false |
| 28279 | */ |
| 28280 | function isArguments(value) { |
| 28281 | return isObjectLike(value) && isArrayLike(value) && objToString.call(value) == argsTag; |
| 28282 | } |
| 28283 | // Fallback for environments without a `toStringTag` for `arguments` objects. |
| 28284 | if (!support.argsTag) { |
| 28285 | isArguments = function(value) { |
| 28286 | return isObjectLike(value) && isArrayLike(value) && |
| 28287 | hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee'); |
| 28288 | }; |
| 28289 | } |
| 28290 | |
| 28291 | module.exports = isArguments; |
| 28292 | |
| 28293 | },{"../internal/isArrayLike":122,"../internal/isObjectLike":129,"../support":158}],144:[function(require,module,exports){ |
| 28294 | var getNative = require('../internal/getNative'), |
| 28295 | isLength = require('../internal/isLength'), |
| 28296 | isObjectLike = require('../internal/isObjectLike'); |
| 28297 | |
| 28298 | /** `Object#toString` result references. */ |
| 28299 | var arrayTag = '[object Array]'; |
| 28300 | |
| 28301 | /** Used for native method references. */ |
| 28302 | var objectProto = Object.prototype; |
| 28303 | |
| 28304 | /** |
| 28305 | * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring) |
| 28306 | * of values. |
| 28307 | */ |
| 28308 | var objToString = objectProto.toString; |
| 28309 | |
| 28310 | /* Native method references for those with the same name as other `lodash` methods. */ |
| 28311 | var nativeIsArray = getNative(Array, 'isArray'); |
| 28312 | |
| 28313 | /** |
| 28314 | * Checks if `value` is classified as an `Array` object. |
| 28315 | * |
| 28316 | * @static |
| 28317 | * @memberOf _ |
| 28318 | * @category Lang |
| 28319 | * @param {*} value The value to check. |
| 28320 | * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
| 28321 | * @example |
| 28322 | * |
| 28323 | * _.isArray([1, 2, 3]); |
| 28324 | * // => true |
| 28325 | * |
| 28326 | * _.isArray(function() { return arguments; }()); |
| 28327 | * // => false |
| 28328 | */ |
| 28329 | var isArray = nativeIsArray || function(value) { |
| 28330 | return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag; |
| 28331 | }; |
| 28332 | |
| 28333 | module.exports = isArray; |
| 28334 | |
| 28335 | },{"../internal/getNative":117,"../internal/isLength":128,"../internal/isObjectLike":129}],145:[function(require,module,exports){ |
| 28336 | var isArguments = require('./isArguments'), |
| 28337 | isArray = require('./isArray'), |
| 28338 | isArrayLike = require('../internal/isArrayLike'), |
| 28339 | isFunction = require('./isFunction'), |
| 28340 | isObjectLike = require('../internal/isObjectLike'), |
| 28341 | isString = require('./isString'), |
| 28342 | keys = require('../object/keys'); |
| 28343 | |
| 28344 | /** |
| 28345 | * Checks if `value` is empty. A value is considered empty unless it is an |
| 28346 | * `arguments` object, array, string, or jQuery-like collection with a length |
| 28347 | * greater than `0` or an object with own enumerable properties. |
| 28348 | * |
| 28349 | * @static |
| 28350 | * @memberOf _ |
| 28351 | * @category Lang |
| 28352 | * @param {Array|Object|string} value The value to inspect. |
| 28353 | * @returns {boolean} Returns `true` if `value` is empty, else `false`. |
| 28354 | * @example |
| 28355 | * |
| 28356 | * _.isEmpty(null); |
| 28357 | * // => true |
| 28358 | * |
| 28359 | * _.isEmpty(true); |
| 28360 | * // => true |
| 28361 | * |
| 28362 | * _.isEmpty(1); |
| 28363 | * // => true |
| 28364 | * |
| 28365 | * _.isEmpty([1, 2, 3]); |
| 28366 | * // => false |
| 28367 | * |
| 28368 | * _.isEmpty({ 'a': 1 }); |
| 28369 | * // => false |
| 28370 | */ |
| 28371 | function isEmpty(value) { |
| 28372 | if (value == null) { |
| 28373 | return true; |
| 28374 | } |
| 28375 | if (isArrayLike(value) && (isArray(value) || isString(value) || isArguments(value) || |
| 28376 | (isObjectLike(value) && isFunction(value.splice)))) { |
| 28377 | return !value.length; |
| 28378 | } |
| 28379 | return !keys(value).length; |
| 28380 | } |
| 28381 | |
| 28382 | module.exports = isEmpty; |
| 28383 | |
| 28384 | },{"../internal/isArrayLike":122,"../internal/isObjectLike":129,"../object/keys":153,"./isArguments":143,"./isArray":144,"./isFunction":146,"./isString":150}],146:[function(require,module,exports){ |
| 28385 | (function (global){ |
| 28386 | var baseIsFunction = require('../internal/baseIsFunction'), |
| 28387 | getNative = require('../internal/getNative'); |
| 28388 | |
| 28389 | /** `Object#toString` result references. */ |
| 28390 | var funcTag = '[object Function]'; |
| 28391 | |
| 28392 | /** Used for native method references. */ |
| 28393 | var objectProto = Object.prototype; |
| 28394 | |
| 28395 | /** |
| 28396 | * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring) |
| 28397 | * of values. |
| 28398 | */ |
| 28399 | var objToString = objectProto.toString; |
| 28400 | |
| 28401 | /** Native method references. */ |
| 28402 | var Uint8Array = getNative(global, 'Uint8Array'); |
| 28403 | |
| 28404 | /** |
| 28405 | * Checks if `value` is classified as a `Function` object. |
| 28406 | * |
| 28407 | * @static |
| 28408 | * @memberOf _ |
| 28409 | * @category Lang |
| 28410 | * @param {*} value The value to check. |
| 28411 | * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
| 28412 | * @example |
| 28413 | * |
| 28414 | * _.isFunction(_); |
| 28415 | * // => true |
| 28416 | * |
| 28417 | * _.isFunction(/abc/); |
| 28418 | * // => false |
| 28419 | */ |
| 28420 | var isFunction = !(baseIsFunction(/x/) || (Uint8Array && !baseIsFunction(Uint8Array))) ? baseIsFunction : function(value) { |
| 28421 | // The use of `Object#toString` avoids issues with the `typeof` operator |
| 28422 | // in older versions of Chrome and Safari which return 'function' for regexes |
| 28423 | // and Safari 8 equivalents which return 'object' for typed array constructors. |
| 28424 | return objToString.call(value) == funcTag; |
| 28425 | }; |
| 28426 | |
| 28427 | module.exports = isFunction; |
| 28428 | |
| 28429 | }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
| 28430 | |
| 28431 | },{"../internal/baseIsFunction":83,"../internal/getNative":117}],147:[function(require,module,exports){ |
| 28432 | var escapeRegExp = require('../string/escapeRegExp'), |
| 28433 | isHostObject = require('../internal/isHostObject'), |
| 28434 | isObjectLike = require('../internal/isObjectLike'); |
| 28435 | |
| 28436 | /** `Object#toString` result references. */ |
| 28437 | var funcTag = '[object Function]'; |
| 28438 | |
| 28439 | /** Used to detect host constructors (Safari > 5). */ |
| 28440 | var reIsHostCtor = /^\[object .+?Constructor\]$/; |
| 28441 | |
| 28442 | /** Used for native method references. */ |
| 28443 | var objectProto = Object.prototype; |
| 28444 | |
| 28445 | /** Used to resolve the decompiled source of functions. */ |
| 28446 | var fnToString = Function.prototype.toString; |
| 28447 | |
| 28448 | /** Used to check objects for own properties. */ |
| 28449 | var hasOwnProperty = objectProto.hasOwnProperty; |
| 28450 | |
| 28451 | /** |
| 28452 | * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring) |
| 28453 | * of values. |
| 28454 | */ |
| 28455 | var objToString = objectProto.toString; |
| 28456 | |
| 28457 | /** Used to detect if a method is native. */ |
| 28458 | var reIsNative = RegExp('^' + |
| 28459 | escapeRegExp(fnToString.call(hasOwnProperty)) |
| 28460 | .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' |
| 28461 | ); |
| 28462 | |
| 28463 | /** |
| 28464 | * Checks if `value` is a native function. |
| 28465 | * |
| 28466 | * @static |
| 28467 | * @memberOf _ |
| 28468 | * @category Lang |
| 28469 | * @param {*} value The value to check. |
| 28470 | * @returns {boolean} Returns `true` if `value` is a native function, else `false`. |
| 28471 | * @example |
| 28472 | * |
| 28473 | * _.isNative(Array.prototype.push); |
| 28474 | * // => true |
| 28475 | * |
| 28476 | * _.isNative(_); |
| 28477 | * // => false |
| 28478 | */ |
| 28479 | function isNative(value) { |
| 28480 | if (value == null) { |
| 28481 | return false; |
| 28482 | } |
| 28483 | if (objToString.call(value) == funcTag) { |
| 28484 | return reIsNative.test(fnToString.call(value)); |
| 28485 | } |
| 28486 | return isObjectLike(value) && (isHostObject(value) ? reIsNative : reIsHostCtor).test(value); |
| 28487 | } |
| 28488 | |
| 28489 | module.exports = isNative; |
| 28490 | |
| 28491 | },{"../internal/isHostObject":123,"../internal/isObjectLike":129,"../string/escapeRegExp":157}],148:[function(require,module,exports){ |
| 28492 | /** |
| 28493 | * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. |
| 28494 | * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) |
| 28495 | * |
| 28496 | * @static |
| 28497 | * @memberOf _ |
| 28498 | * @category Lang |
| 28499 | * @param {*} value The value to check. |
| 28500 | * @returns {boolean} Returns `true` if `value` is an object, else `false`. |
| 28501 | * @example |
| 28502 | * |
| 28503 | * _.isObject({}); |
| 28504 | * // => true |
| 28505 | * |
| 28506 | * _.isObject([1, 2, 3]); |
| 28507 | * // => true |
| 28508 | * |
| 28509 | * _.isObject(1); |
| 28510 | * // => false |
| 28511 | */ |
| 28512 | function isObject(value) { |
| 28513 | // Avoid a V8 JIT bug in Chrome 19-20. |
| 28514 | // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. |
| 28515 | var type = typeof value; |
| 28516 | return !!value && (type == 'object' || type == 'function'); |
| 28517 | } |
| 28518 | |
| 28519 | module.exports = isObject; |
| 28520 | |
| 28521 | },{}],149:[function(require,module,exports){ |
| 28522 | var getNative = require('../internal/getNative'), |
| 28523 | isArguments = require('./isArguments'), |
| 28524 | shimIsPlainObject = require('../internal/shimIsPlainObject'), |
| 28525 | support = require('../support'); |
| 28526 | |
| 28527 | /** `Object#toString` result references. */ |
| 28528 | var objectTag = '[object Object]'; |
| 28529 | |
| 28530 | /** Used for native method references. */ |
| 28531 | var objectProto = Object.prototype; |
| 28532 | |
| 28533 | /** |
| 28534 | * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring) |
| 28535 | * of values. |
| 28536 | */ |
| 28537 | var objToString = objectProto.toString; |
| 28538 | |
| 28539 | /** Native method references. */ |
| 28540 | var getPrototypeOf = getNative(Object, 'getPrototypeOf'); |
| 28541 | |
| 28542 | /** |
| 28543 | * Checks if `value` is a plain object, that is, an object created by the |
| 28544 | * `Object` constructor or one with a `[[Prototype]]` of `null`. |
| 28545 | * |
| 28546 | * **Note:** This method assumes objects created by the `Object` constructor |
| 28547 | * have no inherited enumerable properties. |
| 28548 | * |
| 28549 | * @static |
| 28550 | * @memberOf _ |
| 28551 | * @category Lang |
| 28552 | * @param {*} value The value to check. |
| 28553 | * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. |
| 28554 | * @example |
| 28555 | * |
| 28556 | * function Foo() { |
| 28557 | * this.a = 1; |
| 28558 | * } |
| 28559 | * |
| 28560 | * _.isPlainObject(new Foo); |
| 28561 | * // => false |
| 28562 | * |
| 28563 | * _.isPlainObject([1, 2, 3]); |
| 28564 | * // => false |
| 28565 | * |
| 28566 | * _.isPlainObject({ 'x': 0, 'y': 0 }); |
| 28567 | * // => true |
| 28568 | * |
| 28569 | * _.isPlainObject(Object.create(null)); |
| 28570 | * // => true |
| 28571 | */ |
| 28572 | var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { |
| 28573 | if (!(value && objToString.call(value) == objectTag) || (!support.argsTag && isArguments(value))) { |
| 28574 | return false; |
| 28575 | } |
| 28576 | var valueOf = getNative(value, 'valueOf'), |
| 28577 | objProto = valueOf && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); |
| 28578 | |
| 28579 | return objProto |
| 28580 | ? (value == objProto || getPrototypeOf(value) == objProto) |
| 28581 | : shimIsPlainObject(value); |
| 28582 | }; |
| 28583 | |
| 28584 | module.exports = isPlainObject; |
| 28585 | |
| 28586 | },{"../internal/getNative":117,"../internal/shimIsPlainObject":137,"../support":158,"./isArguments":143}],150:[function(require,module,exports){ |
| 28587 | var isObjectLike = require('../internal/isObjectLike'); |
| 28588 | |
| 28589 | /** `Object#toString` result references. */ |
| 28590 | var stringTag = '[object String]'; |
| 28591 | |
| 28592 | /** Used for native method references. */ |
| 28593 | var objectProto = Object.prototype; |
| 28594 | |
| 28595 | /** |
| 28596 | * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring) |
| 28597 | * of values. |
| 28598 | */ |
| 28599 | var objToString = objectProto.toString; |
| 28600 | |
| 28601 | /** |
| 28602 | * Checks if `value` is classified as a `String` primitive or object. |
| 28603 | * |
| 28604 | * @static |
| 28605 | * @memberOf _ |
| 28606 | * @category Lang |
| 28607 | * @param {*} value The value to check. |
| 28608 | * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
| 28609 | * @example |
| 28610 | * |
| 28611 | * _.isString('abc'); |
| 28612 | * // => true |
| 28613 | * |
| 28614 | * _.isString(1); |
| 28615 | * // => false |
| 28616 | */ |
| 28617 | function isString(value) { |
| 28618 | return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag); |
| 28619 | } |
| 28620 | |
| 28621 | module.exports = isString; |
| 28622 | |
| 28623 | },{"../internal/isObjectLike":129}],151:[function(require,module,exports){ |
| 28624 | var isLength = require('../internal/isLength'), |
| 28625 | isObjectLike = require('../internal/isObjectLike'); |
| 28626 | |
| 28627 | /** `Object#toString` result references. */ |
| 28628 | var argsTag = '[object Arguments]', |
| 28629 | arrayTag = '[object Array]', |
| 28630 | boolTag = '[object Boolean]', |
| 28631 | dateTag = '[object Date]', |
| 28632 | errorTag = '[object Error]', |
| 28633 | funcTag = '[object Function]', |
| 28634 | mapTag = '[object Map]', |
| 28635 | numberTag = '[object Number]', |
| 28636 | objectTag = '[object Object]', |
| 28637 | regexpTag = '[object RegExp]', |
| 28638 | setTag = '[object Set]', |
| 28639 | stringTag = '[object String]', |
| 28640 | weakMapTag = '[object WeakMap]'; |
| 28641 | |
| 28642 | var arrayBufferTag = '[object ArrayBuffer]', |
| 28643 | float32Tag = '[object Float32Array]', |
| 28644 | float64Tag = '[object Float64Array]', |
| 28645 | int8Tag = '[object Int8Array]', |
| 28646 | int16Tag = '[object Int16Array]', |
| 28647 | int32Tag = '[object Int32Array]', |
| 28648 | uint8Tag = '[object Uint8Array]', |
| 28649 | uint8ClampedTag = '[object Uint8ClampedArray]', |
| 28650 | uint16Tag = '[object Uint16Array]', |
| 28651 | uint32Tag = '[object Uint32Array]'; |
| 28652 | |
| 28653 | /** Used to identify `toStringTag` values of typed arrays. */ |
| 28654 | var typedArrayTags = {}; |
| 28655 | typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = |
| 28656 | typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = |
| 28657 | typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = |
| 28658 | typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = |
| 28659 | typedArrayTags[uint32Tag] = true; |
| 28660 | typedArrayTags[argsTag] = typedArrayTags[arrayTag] = |
| 28661 | typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = |
| 28662 | typedArrayTags[dateTag] = typedArrayTags[errorTag] = |
| 28663 | typedArrayTags[funcTag] = typedArrayTags[mapTag] = |
| 28664 | typedArrayTags[numberTag] = typedArrayTags[objectTag] = |
| 28665 | typedArrayTags[regexpTag] = typedArrayTags[setTag] = |
| 28666 | typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; |
| 28667 | |
| 28668 | /** Used for native method references. */ |
| 28669 | var objectProto = Object.prototype; |
| 28670 | |
| 28671 | /** |
| 28672 | * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring) |
| 28673 | * of values. |
| 28674 | */ |
| 28675 | var objToString = objectProto.toString; |
| 28676 | |
| 28677 | /** |
| 28678 | * Checks if `value` is classified as a typed array. |
| 28679 | * |
| 28680 | * @static |
| 28681 | * @memberOf _ |
| 28682 | * @category Lang |
| 28683 | * @param {*} value The value to check. |
| 28684 | * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
| 28685 | * @example |
| 28686 | * |
| 28687 | * _.isTypedArray(new Uint8Array); |
| 28688 | * // => true |
| 28689 | * |
| 28690 | * _.isTypedArray([]); |
| 28691 | * // => false |
| 28692 | */ |
| 28693 | function isTypedArray(value) { |
| 28694 | return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)]; |
| 28695 | } |
| 28696 | |
| 28697 | module.exports = isTypedArray; |
| 28698 | |
| 28699 | },{"../internal/isLength":128,"../internal/isObjectLike":129}],152:[function(require,module,exports){ |
| 28700 | /** |
| 28701 | * Checks if `value` is `undefined`. |
| 28702 | * |
| 28703 | * @static |
| 28704 | * @memberOf _ |
| 28705 | * @category Lang |
| 28706 | * @param {*} value The value to check. |
| 28707 | * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. |
| 28708 | * @example |
| 28709 | * |
| 28710 | * _.isUndefined(void 0); |
| 28711 | * // => true |
| 28712 | * |
| 28713 | * _.isUndefined(null); |
| 28714 | * // => false |
| 28715 | */ |
| 28716 | function isUndefined(value) { |
| 28717 | return value === undefined; |
| 28718 | } |
| 28719 | |
| 28720 | module.exports = isUndefined; |
| 28721 | |
| 28722 | },{}],153:[function(require,module,exports){ |
| 28723 | var getNative = require('../internal/getNative'), |
| 28724 | isArrayLike = require('../internal/isArrayLike'), |
| 28725 | isObject = require('../lang/isObject'), |
| 28726 | shimKeys = require('../internal/shimKeys'), |
| 28727 | support = require('../support'); |
| 28728 | |
| 28729 | /* Native method references for those with the same name as other `lodash` methods. */ |
| 28730 | var nativeKeys = getNative(Object, 'keys'); |
| 28731 | |
| 28732 | /** |
| 28733 | * Creates an array of the own enumerable property names of `object`. |
| 28734 | * |
| 28735 | * **Note:** Non-object values are coerced to objects. See the |
| 28736 | * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.keys) |
| 28737 | * for more details. |
| 28738 | * |
| 28739 | * @static |
| 28740 | * @memberOf _ |
| 28741 | * @category Object |
| 28742 | * @param {Object} object The object to query. |
| 28743 | * @returns {Array} Returns the array of property names. |
| 28744 | * @example |
| 28745 | * |
| 28746 | * function Foo() { |
| 28747 | * this.a = 1; |
| 28748 | * this.b = 2; |
| 28749 | * } |
| 28750 | * |
| 28751 | * Foo.prototype.c = 3; |
| 28752 | * |
| 28753 | * _.keys(new Foo); |
| 28754 | * // => ['a', 'b'] (iteration order is not guaranteed) |
| 28755 | * |
| 28756 | * _.keys('hi'); |
| 28757 | * // => ['0', '1'] |
| 28758 | */ |
| 28759 | var keys = !nativeKeys ? shimKeys : function(object) { |
| 28760 | var Ctor = object == null ? null : object.constructor; |
| 28761 | if ((typeof Ctor == 'function' && Ctor.prototype === object) || |
| 28762 | (typeof object == 'function' ? support.enumPrototypes : isArrayLike(object))) { |
| 28763 | return shimKeys(object); |
| 28764 | } |
| 28765 | return isObject(object) ? nativeKeys(object) : []; |
| 28766 | }; |
| 28767 | |
| 28768 | module.exports = keys; |
| 28769 | |
| 28770 | },{"../internal/getNative":117,"../internal/isArrayLike":122,"../internal/shimKeys":138,"../lang/isObject":148,"../support":158}],154:[function(require,module,exports){ |
| 28771 | var arrayEach = require('../internal/arrayEach'), |
| 28772 | isArguments = require('../lang/isArguments'), |
| 28773 | isArray = require('../lang/isArray'), |
| 28774 | isFunction = require('../lang/isFunction'), |
| 28775 | isIndex = require('../internal/isIndex'), |
| 28776 | isLength = require('../internal/isLength'), |
| 28777 | isObject = require('../lang/isObject'), |
| 28778 | isString = require('../lang/isString'), |
| 28779 | support = require('../support'); |
| 28780 | |
| 28781 | /** `Object#toString` result references. */ |
| 28782 | var arrayTag = '[object Array]', |
| 28783 | boolTag = '[object Boolean]', |
| 28784 | dateTag = '[object Date]', |
| 28785 | errorTag = '[object Error]', |
| 28786 | funcTag = '[object Function]', |
| 28787 | numberTag = '[object Number]', |
| 28788 | objectTag = '[object Object]', |
| 28789 | regexpTag = '[object RegExp]', |
| 28790 | stringTag = '[object String]'; |
| 28791 | |
| 28792 | /** Used to fix the JScript `[[DontEnum]]` bug. */ |
| 28793 | var shadowProps = [ |
| 28794 | 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', |
| 28795 | 'toLocaleString', 'toString', 'valueOf' |
| 28796 | ]; |
| 28797 | |
| 28798 | /** Used for native method references. */ |
| 28799 | var errorProto = Error.prototype, |
| 28800 | objectProto = Object.prototype, |
| 28801 | stringProto = String.prototype; |
| 28802 | |
| 28803 | /** Used to check objects for own properties. */ |
| 28804 | var hasOwnProperty = objectProto.hasOwnProperty; |
| 28805 | |
| 28806 | /** |
| 28807 | * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring) |
| 28808 | * of values. |
| 28809 | */ |
| 28810 | var objToString = objectProto.toString; |
| 28811 | |
| 28812 | /** Used to avoid iterating over non-enumerable properties in IE < 9. */ |
| 28813 | var nonEnumProps = {}; |
| 28814 | nonEnumProps[arrayTag] = nonEnumProps[dateTag] = nonEnumProps[numberTag] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true }; |
| 28815 | nonEnumProps[boolTag] = nonEnumProps[stringTag] = { 'constructor': true, 'toString': true, 'valueOf': true }; |
| 28816 | nonEnumProps[errorTag] = nonEnumProps[funcTag] = nonEnumProps[regexpTag] = { 'constructor': true, 'toString': true }; |
| 28817 | nonEnumProps[objectTag] = { 'constructor': true }; |
| 28818 | |
| 28819 | arrayEach(shadowProps, function(key) { |
| 28820 | for (var tag in nonEnumProps) { |
| 28821 | if (hasOwnProperty.call(nonEnumProps, tag)) { |
| 28822 | var props = nonEnumProps[tag]; |
| 28823 | props[key] = hasOwnProperty.call(props, key); |
| 28824 | } |
| 28825 | } |
| 28826 | }); |
| 28827 | |
| 28828 | /** |
| 28829 | * Creates an array of the own and inherited enumerable property names of `object`. |
| 28830 | * |
| 28831 | * **Note:** Non-object values are coerced to objects. |
| 28832 | * |
| 28833 | * @static |
| 28834 | * @memberOf _ |
| 28835 | * @category Object |
| 28836 | * @param {Object} object The object to query. |
| 28837 | * @returns {Array} Returns the array of property names. |
| 28838 | * @example |
| 28839 | * |
| 28840 | * function Foo() { |
| 28841 | * this.a = 1; |
| 28842 | * this.b = 2; |
| 28843 | * } |
| 28844 | * |
| 28845 | * Foo.prototype.c = 3; |
| 28846 | * |
| 28847 | * _.keysIn(new Foo); |
| 28848 | * // => ['a', 'b', 'c'] (iteration order is not guaranteed) |
| 28849 | */ |
| 28850 | function keysIn(object) { |
| 28851 | if (object == null) { |
| 28852 | return []; |
| 28853 | } |
| 28854 | if (!isObject(object)) { |
| 28855 | object = Object(object); |
| 28856 | } |
| 28857 | var length = object.length; |
| 28858 | |
| 28859 | length = (length && isLength(length) && |
| 28860 | (isArray(object) || isArguments(object) || isString(object)) && length) || 0; |
| 28861 | |
| 28862 | var Ctor = object.constructor, |
| 28863 | index = -1, |
| 28864 | proto = (isFunction(Ctor) && Ctor.prototype) || objectProto, |
| 28865 | isProto = proto === object, |
| 28866 | result = Array(length), |
| 28867 | skipIndexes = length > 0, |
| 28868 | skipErrorProps = support.enumErrorProps && (object === errorProto || object instanceof Error), |
| 28869 | skipProto = support.enumPrototypes && isFunction(object); |
| 28870 | |
| 28871 | while (++index < length) { |
| 28872 | result[index] = (index + ''); |
| 28873 | } |
| 28874 | // lodash skips the `constructor` property when it infers it is iterating |
| 28875 | // over a `prototype` object because IE < 9 can't set the `[[Enumerable]]` |
| 28876 | // attribute of an existing property and the `constructor` property of a |
| 28877 | // prototype defaults to non-enumerable. |
| 28878 | for (var key in object) { |
| 28879 | if (!(skipProto && key == 'prototype') && |
| 28880 | !(skipErrorProps && (key == 'message' || key == 'name')) && |
| 28881 | !(skipIndexes && isIndex(key, length)) && |
| 28882 | !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { |
| 28883 | result.push(key); |
| 28884 | } |
| 28885 | } |
| 28886 | if (support.nonEnumShadows && object !== objectProto) { |
| 28887 | var tag = object === stringProto ? stringTag : (object === errorProto ? errorTag : objToString.call(object)), |
| 28888 | nonEnums = nonEnumProps[tag] || nonEnumProps[objectTag]; |
| 28889 | |
| 28890 | if (tag == objectTag) { |
| 28891 | proto = objectProto; |
| 28892 | } |
| 28893 | length = shadowProps.length; |
| 28894 | while (length--) { |
| 28895 | key = shadowProps[length]; |
| 28896 | var nonEnum = nonEnums[key]; |
| 28897 | if (!(isProto && nonEnum) && |
| 28898 | (nonEnum ? hasOwnProperty.call(object, key) : object[key] !== proto[key])) { |
| 28899 | result.push(key); |
| 28900 | } |
| 28901 | } |
| 28902 | } |
| 28903 | return result; |
| 28904 | } |
| 28905 | |
| 28906 | module.exports = keysIn; |
| 28907 | |
| 28908 | },{"../internal/arrayEach":65,"../internal/isIndex":124,"../internal/isLength":128,"../lang/isArguments":143,"../lang/isArray":144,"../lang/isFunction":146,"../lang/isObject":148,"../lang/isString":150,"../support":158}],155:[function(require,module,exports){ |
| 28909 | var keys = require('./keys'), |
| 28910 | toObject = require('../internal/toObject'); |
| 28911 | |
| 28912 | /** |
| 28913 | * Creates a two dimensional array of the key-value pairs for `object`, |
| 28914 | * e.g. `[[key1, value1], [key2, value2]]`. |
| 28915 | * |
| 28916 | * @static |
| 28917 | * @memberOf _ |
| 28918 | * @category Object |
| 28919 | * @param {Object} object The object to query. |
| 28920 | * @returns {Array} Returns the new array of key-value pairs. |
| 28921 | * @example |
| 28922 | * |
| 28923 | * _.pairs({ 'barney': 36, 'fred': 40 }); |
| 28924 | * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed) |
| 28925 | */ |
| 28926 | function pairs(object) { |
| 28927 | object = toObject(object); |
| 28928 | |
| 28929 | var index = -1, |
| 28930 | props = keys(object), |
| 28931 | length = props.length, |
| 28932 | result = Array(length); |
| 28933 | |
| 28934 | while (++index < length) { |
| 28935 | var key = props[index]; |
| 28936 | result[index] = [key, object[key]]; |
| 28937 | } |
| 28938 | return result; |
| 28939 | } |
| 28940 | |
| 28941 | module.exports = pairs; |
| 28942 | |
| 28943 | },{"../internal/toObject":139,"./keys":153}],156:[function(require,module,exports){ |
| 28944 | var baseValues = require('../internal/baseValues'), |
| 28945 | keys = require('./keys'); |
| 28946 | |
| 28947 | /** |
| 28948 | * Creates an array of the own enumerable property values of `object`. |
| 28949 | * |
| 28950 | * **Note:** Non-object values are coerced to objects. |
| 28951 | * |
| 28952 | * @static |
| 28953 | * @memberOf _ |
| 28954 | * @category Object |
| 28955 | * @param {Object} object The object to query. |
| 28956 | * @returns {Array} Returns the array of property values. |
| 28957 | * @example |
| 28958 | * |
| 28959 | * function Foo() { |
| 28960 | * this.a = 1; |
| 28961 | * this.b = 2; |
| 28962 | * } |
| 28963 | * |
| 28964 | * Foo.prototype.c = 3; |
| 28965 | * |
| 28966 | * _.values(new Foo); |
| 28967 | * // => [1, 2] (iteration order is not guaranteed) |
| 28968 | * |
| 28969 | * _.values('hi'); |
| 28970 | * // => ['h', 'i'] |
| 28971 | */ |
| 28972 | function values(object) { |
| 28973 | return baseValues(object, keys(object)); |
| 28974 | } |
| 28975 | |
| 28976 | module.exports = values; |
| 28977 | |
| 28978 | },{"../internal/baseValues":94,"./keys":153}],157:[function(require,module,exports){ |
| 28979 | var baseToString = require('../internal/baseToString'); |
| 28980 | |
| 28981 | /** |
| 28982 | * Used to match `RegExp` [special characters](http://www.regular-expressions.info/characters.html#special). |
| 28983 | * In addition to special characters the forward slash is escaped to allow for |
| 28984 | * easier `eval` use and `Function` compilation. |
| 28985 | */ |
| 28986 | var reRegExpChars = /[.*+?^${}()|[\]\/\\]/g, |
| 28987 | reHasRegExpChars = RegExp(reRegExpChars.source); |
| 28988 | |
| 28989 | /** |
| 28990 | * Escapes the `RegExp` special characters "\", "/", "^", "$", ".", "|", "?", |
| 28991 | * "*", "+", "(", ")", "[", "]", "{" and "}" in `string`. |
| 28992 | * |
| 28993 | * @static |
| 28994 | * @memberOf _ |
| 28995 | * @category String |
| 28996 | * @param {string} [string=''] The string to escape. |
| 28997 | * @returns {string} Returns the escaped string. |
| 28998 | * @example |
| 28999 | * |
| 29000 | * _.escapeRegExp('[lodash](https://lodash.com/)'); |
| 29001 | * // => '\[lodash\]\(https:\/\/lodash\.com\/\)' |
| 29002 | */ |
| 29003 | function escapeRegExp(string) { |
| 29004 | string = baseToString(string); |
| 29005 | return (string && reHasRegExpChars.test(string)) |
| 29006 | ? string.replace(reRegExpChars, '\\$&') |
| 29007 | : string; |
| 29008 | } |
| 29009 | |
| 29010 | module.exports = escapeRegExp; |
| 29011 | |
| 29012 | },{"../internal/baseToString":93}],158:[function(require,module,exports){ |
| 29013 | (function (global){ |
| 29014 | /** `Object#toString` result references. */ |
| 29015 | var argsTag = '[object Arguments]', |
| 29016 | objectTag = '[object Object]'; |
| 29017 | |
| 29018 | /** Used for native method references. */ |
| 29019 | var arrayProto = Array.prototype, |
| 29020 | errorProto = Error.prototype, |
| 29021 | objectProto = Object.prototype; |
| 29022 | |
| 29023 | /** Used to detect DOM support. */ |
| 29024 | var document = (document = global.window) ? document.document : null; |
| 29025 | |
| 29026 | /** |
| 29027 | * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring) |
| 29028 | * of values. |
| 29029 | */ |
| 29030 | var objToString = objectProto.toString; |
| 29031 | |
| 29032 | /** Native method references. */ |
| 29033 | var propertyIsEnumerable = objectProto.propertyIsEnumerable, |
| 29034 | splice = arrayProto.splice; |
| 29035 | |
| 29036 | /** |
| 29037 | * An object environment feature flags. |
| 29038 | * |
| 29039 | * @static |
| 29040 | * @memberOf _ |
| 29041 | * @type Object |
| 29042 | */ |
| 29043 | var support = {}; |
| 29044 | |
| 29045 | (function(x) { |
| 29046 | var Ctor = function() { this.x = x; }, |
| 29047 | object = { '0': x, 'length': x }, |
| 29048 | props = []; |
| 29049 | |
| 29050 | Ctor.prototype = { 'valueOf': x, 'y': x }; |
| 29051 | for (var key in new Ctor) { props.push(key); } |
| 29052 | |
| 29053 | /** |
| 29054 | * Detect if the `toStringTag` of `arguments` objects is resolvable |
| 29055 | * (all but Firefox < 4, IE < 9). |
| 29056 | * |
| 29057 | * @memberOf _.support |
| 29058 | * @type boolean |
| 29059 | */ |
| 29060 | support.argsTag = objToString.call(arguments) == argsTag; |
| 29061 | |
| 29062 | /** |
| 29063 | * Detect if `name` or `message` properties of `Error.prototype` are |
| 29064 | * enumerable by default (IE < 9, Safari < 5.1). |
| 29065 | * |
| 29066 | * @memberOf _.support |
| 29067 | * @type boolean |
| 29068 | */ |
| 29069 | support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || |
| 29070 | propertyIsEnumerable.call(errorProto, 'name'); |
| 29071 | |
| 29072 | /** |
| 29073 | * Detect if `prototype` properties are enumerable by default. |
| 29074 | * |
| 29075 | * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1 |
| 29076 | * (if the prototype or a property on the prototype has been set) |
| 29077 | * incorrectly set the `[[Enumerable]]` value of a function's `prototype` |
| 29078 | * property to `true`. |
| 29079 | * |
| 29080 | * @memberOf _.support |
| 29081 | * @type boolean |
| 29082 | */ |
| 29083 | support.enumPrototypes = propertyIsEnumerable.call(Ctor, 'prototype'); |
| 29084 | |
| 29085 | /** |
| 29086 | * Detect if the `toStringTag` of DOM nodes is resolvable (all but IE < 9). |
| 29087 | * |
| 29088 | * @memberOf _.support |
| 29089 | * @type boolean |
| 29090 | */ |
| 29091 | support.nodeTag = objToString.call(document) != objectTag; |
| 29092 | |
| 29093 | /** |
| 29094 | * Detect if properties shadowing those on `Object.prototype` are non-enumerable. |
| 29095 | * |
| 29096 | * In IE < 9 an object's own properties, shadowing non-enumerable ones, |
| 29097 | * are made non-enumerable as well (a.k.a the JScript `[[DontEnum]]` bug). |
| 29098 | * |
| 29099 | * @memberOf _.support |
| 29100 | * @type boolean |
| 29101 | */ |
| 29102 | support.nonEnumShadows = !/valueOf/.test(props); |
| 29103 | |
| 29104 | /** |
| 29105 | * Detect if own properties are iterated after inherited properties (IE < 9). |
| 29106 | * |
| 29107 | * @memberOf _.support |
| 29108 | * @type boolean |
| 29109 | */ |
| 29110 | support.ownLast = props[0] != 'x'; |
| 29111 | |
| 29112 | /** |
| 29113 | * Detect if `Array#shift` and `Array#splice` augment array-like objects |
| 29114 | * correctly. |
| 29115 | * |
| 29116 | * Firefox < 10, compatibility modes of IE 8, and IE < 9 have buggy Array |
| 29117 | * `shift()` and `splice()` functions that fail to remove the last element, |
| 29118 | * `value[0]`, of array-like objects even though the "length" property is |
| 29119 | * set to `0`. The `shift()` method is buggy in compatibility modes of IE 8, |
| 29120 | * while `splice()` is buggy regardless of mode in IE < 9. |
| 29121 | * |
| 29122 | * @memberOf _.support |
| 29123 | * @type boolean |
| 29124 | */ |
| 29125 | support.spliceObjects = (splice.call(object, 0, 1), !object[0]); |
| 29126 | |
| 29127 | /** |
| 29128 | * Detect lack of support for accessing string characters by index. |
| 29129 | * |
| 29130 | * IE < 8 can't access characters by index. IE 8 can only access characters |
| 29131 | * by index on string literals, not string objects. |
| 29132 | * |
| 29133 | * @memberOf _.support |
| 29134 | * @type boolean |
| 29135 | */ |
| 29136 | support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx'; |
| 29137 | |
| 29138 | /** |
| 29139 | * Detect if the DOM is supported. |
| 29140 | * |
| 29141 | * @memberOf _.support |
| 29142 | * @type boolean |
| 29143 | */ |
| 29144 | try { |
| 29145 | support.dom = document.createDocumentFragment().nodeType === 11; |
| 29146 | } catch(e) { |
| 29147 | support.dom = false; |
| 29148 | } |
| 29149 | }(1, 0)); |
| 29150 | |
| 29151 | module.exports = support; |
| 29152 | |
| 29153 | }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
| 29154 | |
| 29155 | },{}],159:[function(require,module,exports){ |
| 29156 | /** |
| 29157 | * Creates a function that returns `value`. |
| 29158 | * |
| 29159 | * @static |
| 29160 | * @memberOf _ |
| 29161 | * @category Utility |
| 29162 | * @param {*} value The value to return from the new function. |
| 29163 | * @returns {Function} Returns the new function. |
| 29164 | * @example |
| 29165 | * |
| 29166 | * var object = { 'user': 'fred' }; |
| 29167 | * var getter = _.constant(object); |
| 29168 | * |
| 29169 | * getter() === object; |
| 29170 | * // => true |
| 29171 | */ |
| 29172 | function constant(value) { |
| 29173 | return function() { |
| 29174 | return value; |
| 29175 | }; |
| 29176 | } |
| 29177 | |
| 29178 | module.exports = constant; |
| 29179 | |
| 29180 | },{}],160:[function(require,module,exports){ |
| 29181 | /** |
| 29182 | * This method returns the first argument provided to it. |
| 29183 | * |
| 29184 | * @static |
| 29185 | * @memberOf _ |
| 29186 | * @category Utility |
| 29187 | * @param {*} value Any value. |
| 29188 | * @returns {*} Returns `value`. |
| 29189 | * @example |
| 29190 | * |
| 29191 | * var object = { 'user': 'fred' }; |
| 29192 | * |
| 29193 | * _.identity(object) === object; |
| 29194 | * // => true |
| 29195 | */ |
| 29196 | function identity(value) { |
| 29197 | return value; |
| 29198 | } |
| 29199 | |
| 29200 | module.exports = identity; |
| 29201 | |
| 29202 | },{}],161:[function(require,module,exports){ |
| 29203 | /** |
| 29204 | * A no-operation function that returns `undefined` regardless of the |
| 29205 | * arguments it receives. |
| 29206 | * |
| 29207 | * @static |
| 29208 | * @memberOf _ |
| 29209 | * @category Utility |
| 29210 | * @example |
| 29211 | * |
| 29212 | * var object = { 'user': 'fred' }; |
| 29213 | * |
| 29214 | * _.noop(object) === undefined; |
| 29215 | * // => true |
| 29216 | */ |
| 29217 | function noop() { |
| 29218 | // No operation performed. |
| 29219 | } |
| 29220 | |
| 29221 | module.exports = noop; |
| 29222 | |
| 29223 | },{}],162:[function(require,module,exports){ |
| 29224 | var baseProperty = require('../internal/baseProperty'), |
| 29225 | basePropertyDeep = require('../internal/basePropertyDeep'), |
| 29226 | isKey = require('../internal/isKey'); |
| 29227 | |
| 29228 | /** |
| 29229 | * Creates a function that returns the property value at `path` on a |
| 29230 | * given object. |
| 29231 | * |
| 29232 | * @static |
| 29233 | * @memberOf _ |
| 29234 | * @category Utility |
| 29235 | * @param {Array|string} path The path of the property to get. |
| 29236 | * @returns {Function} Returns the new function. |
| 29237 | * @example |
| 29238 | * |
| 29239 | * var objects = [ |
| 29240 | * { 'a': { 'b': { 'c': 2 } } }, |
| 29241 | * { 'a': { 'b': { 'c': 1 } } } |
| 29242 | * ]; |
| 29243 | * |
| 29244 | * _.map(objects, _.property('a.b.c')); |
| 29245 | * // => [2, 1] |
| 29246 | * |
| 29247 | * _.pluck(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c'); |
| 29248 | * // => [1, 2] |
| 29249 | */ |
| 29250 | function property(path) { |
| 29251 | return isKey(path) ? baseProperty(path) : basePropertyDeep(path); |
| 29252 | } |
| 29253 | |
| 29254 | module.exports = property; |
| 29255 | |
| 29256 | },{"../internal/baseProperty":89,"../internal/basePropertyDeep":90,"../internal/isKey":126}],163:[function(require,module,exports){ |
| 29257 | /** |
| 29258 | * Module dependencies. |
| 29259 | */ |
| 29260 | |
| 29261 | var Emitter = require('emitter'); |
| 29262 | var reduce = require('reduce'); |
| 29263 | |
| 29264 | /** |
| 29265 | * Root reference for iframes. |
| 29266 | */ |
| 29267 | |
| 29268 | var root = 'undefined' == typeof window |
| 29269 | ? (this || self) |
| 29270 | : window; |
| 29271 | |
| 29272 | /** |
| 29273 | * Noop. |
| 29274 | */ |
| 29275 | |
| 29276 | function noop(){}; |
| 29277 | |
| 29278 | /** |
| 29279 | * Check if `obj` is a host object, |
| 29280 | * we don't want to serialize these :) |
| 29281 | * |
| 29282 | * TODO: future proof, move to compoent land |
| 29283 | * |
| 29284 | * @param {Object} obj |
| 29285 | * @return {Boolean} |
| 29286 | * @api private |
| 29287 | */ |
| 29288 | |
| 29289 | function isHost(obj) { |
| 29290 | var str = {}.toString.call(obj); |
| 29291 | |
| 29292 | switch (str) { |
| 29293 | case '[object File]': |
| 29294 | case '[object Blob]': |
| 29295 | case '[object FormData]': |
| 29296 | return true; |
| 29297 | default: |
| 29298 | return false; |
| 29299 | } |
| 29300 | } |
| 29301 | |
| 29302 | /** |
| 29303 | * Determine XHR. |
| 29304 | */ |
| 29305 | |
| 29306 | request.getXHR = function () { |
| 29307 | if (root.XMLHttpRequest |
| 29308 | && (!root.location || 'file:' != root.location.protocol |
| 29309 | || !root.ActiveXObject)) { |
| 29310 | return new XMLHttpRequest; |
| 29311 | } else { |
| 29312 | try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {} |
| 29313 | try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {} |
| 29314 | try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {} |
| 29315 | try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {} |
| 29316 | } |
| 29317 | return false; |
| 29318 | }; |
| 29319 | |
| 29320 | /** |
| 29321 | * Removes leading and trailing whitespace, added to support IE. |
| 29322 | * |
| 29323 | * @param {String} s |
| 29324 | * @return {String} |
| 29325 | * @api private |
| 29326 | */ |
| 29327 | |
| 29328 | var trim = ''.trim |
| 29329 | ? function(s) { return s.trim(); } |
| 29330 | : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); }; |
| 29331 | |
| 29332 | /** |
| 29333 | * Check if `obj` is an object. |
| 29334 | * |
| 29335 | * @param {Object} obj |
| 29336 | * @return {Boolean} |
| 29337 | * @api private |
| 29338 | */ |
| 29339 | |
| 29340 | function isObject(obj) { |
| 29341 | return obj === Object(obj); |
| 29342 | } |
| 29343 | |
| 29344 | /** |
| 29345 | * Serialize the given `obj`. |
| 29346 | * |
| 29347 | * @param {Object} obj |
| 29348 | * @return {String} |
| 29349 | * @api private |
| 29350 | */ |
| 29351 | |
| 29352 | function serialize(obj) { |
| 29353 | if (!isObject(obj)) return obj; |
| 29354 | var pairs = []; |
| 29355 | for (var key in obj) { |
| 29356 | if (null != obj[key]) { |
| 29357 | pairs.push(encodeURIComponent(key) |
| 29358 | + '=' + encodeURIComponent(obj[key])); |
| 29359 | } |
| 29360 | } |
| 29361 | return pairs.join('&'); |
| 29362 | } |
| 29363 | |
| 29364 | /** |
| 29365 | * Expose serialization method. |
| 29366 | */ |
| 29367 | |
| 29368 | request.serializeObject = serialize; |
| 29369 | |
| 29370 | /** |
| 29371 | * Parse the given x-www-form-urlencoded `str`. |
| 29372 | * |
| 29373 | * @param {String} str |
| 29374 | * @return {Object} |
| 29375 | * @api private |
| 29376 | */ |
| 29377 | |
| 29378 | function parseString(str) { |
| 29379 | var obj = {}; |
| 29380 | var pairs = str.split('&'); |
| 29381 | var parts; |
| 29382 | var pair; |
| 29383 | |
| 29384 | for (var i = 0, len = pairs.length; i < len; ++i) { |
| 29385 | pair = pairs[i]; |
| 29386 | parts = pair.split('='); |
| 29387 | obj[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]); |
| 29388 | } |
| 29389 | |
| 29390 | return obj; |
| 29391 | } |
| 29392 | |
| 29393 | /** |
| 29394 | * Expose parser. |
| 29395 | */ |
| 29396 | |
| 29397 | request.parseString = parseString; |
| 29398 | |
| 29399 | /** |
| 29400 | * Default MIME type map. |
| 29401 | * |
| 29402 | * superagent.types.xml = 'application/xml'; |
| 29403 | * |
| 29404 | */ |
| 29405 | |
| 29406 | request.types = { |
| 29407 | html: 'text/html', |
| 29408 | json: 'application/json', |
| 29409 | xml: 'application/xml', |
| 29410 | urlencoded: 'application/x-www-form-urlencoded', |
| 29411 | 'form': 'application/x-www-form-urlencoded', |
| 29412 | 'form-data': 'application/x-www-form-urlencoded' |
| 29413 | }; |
| 29414 | |
| 29415 | /** |
| 29416 | * Default serialization map. |
| 29417 | * |
| 29418 | * superagent.serialize['application/xml'] = function(obj){ |
| 29419 | * return 'generated xml here'; |
| 29420 | * }; |
| 29421 | * |
| 29422 | */ |
| 29423 | |
| 29424 | request.serialize = { |
| 29425 | 'application/x-www-form-urlencoded': serialize, |
| 29426 | 'application/json': JSON.stringify |
| 29427 | }; |
| 29428 | |
| 29429 | /** |
| 29430 | * Default parsers. |
| 29431 | * |
| 29432 | * superagent.parse['application/xml'] = function(str){ |
| 29433 | * return { object parsed from str }; |
| 29434 | * }; |
| 29435 | * |
| 29436 | */ |
| 29437 | |
| 29438 | request.parse = { |
| 29439 | 'application/x-www-form-urlencoded': parseString, |
| 29440 | 'application/json': JSON.parse |
| 29441 | }; |
| 29442 | |
| 29443 | /** |
| 29444 | * Parse the given header `str` into |
| 29445 | * an object containing the mapped fields. |
| 29446 | * |
| 29447 | * @param {String} str |
| 29448 | * @return {Object} |
| 29449 | * @api private |
| 29450 | */ |
| 29451 | |
| 29452 | function parseHeader(str) { |
| 29453 | var lines = str.split(/\r?\n/); |
| 29454 | var fields = {}; |
| 29455 | var index; |
| 29456 | var line; |
| 29457 | var field; |
| 29458 | var val; |
| 29459 | |
| 29460 | lines.pop(); // trailing CRLF |
| 29461 | |
| 29462 | for (var i = 0, len = lines.length; i < len; ++i) { |
| 29463 | line = lines[i]; |
| 29464 | index = line.indexOf(':'); |
| 29465 | field = line.slice(0, index).toLowerCase(); |
| 29466 | val = trim(line.slice(index + 1)); |
| 29467 | fields[field] = val; |
| 29468 | } |
| 29469 | |
| 29470 | return fields; |
| 29471 | } |
| 29472 | |
| 29473 | /** |
| 29474 | * Return the mime type for the given `str`. |
| 29475 | * |
| 29476 | * @param {String} str |
| 29477 | * @return {String} |
| 29478 | * @api private |
| 29479 | */ |
| 29480 | |
| 29481 | function type(str){ |
| 29482 | return str.split(/ *; */).shift(); |
| 29483 | }; |
| 29484 | |
| 29485 | /** |
| 29486 | * Return header field parameters. |
| 29487 | * |
| 29488 | * @param {String} str |
| 29489 | * @return {Object} |
| 29490 | * @api private |
| 29491 | */ |
| 29492 | |
| 29493 | function params(str){ |
| 29494 | return reduce(str.split(/ *; */), function(obj, str){ |
| 29495 | var parts = str.split(/ *= */) |
| 29496 | , key = parts.shift() |
| 29497 | , val = parts.shift(); |
| 29498 | |
| 29499 | if (key && val) obj[key] = val; |
| 29500 | return obj; |
| 29501 | }, {}); |
| 29502 | }; |
| 29503 | |
| 29504 | /** |
| 29505 | * Initialize a new `Response` with the given `xhr`. |
| 29506 | * |
| 29507 | * - set flags (.ok, .error, etc) |
| 29508 | * - parse header |
| 29509 | * |
| 29510 | * Examples: |
| 29511 | * |
| 29512 | * Aliasing `superagent` as `request` is nice: |
| 29513 | * |
| 29514 | * request = superagent; |
| 29515 | * |
| 29516 | * We can use the promise-like API, or pass callbacks: |
| 29517 | * |
| 29518 | * request.get('/').end(function(res){}); |
| 29519 | * request.get('/', function(res){}); |
| 29520 | * |
| 29521 | * Sending data can be chained: |
| 29522 | * |
| 29523 | * request |
| 29524 | * .post('/user') |
| 29525 | * .send({ name: 'tj' }) |
| 29526 | * .end(function(res){}); |
| 29527 | * |
| 29528 | * Or passed to `.send()`: |
| 29529 | * |
| 29530 | * request |
| 29531 | * .post('/user') |
| 29532 | * .send({ name: 'tj' }, function(res){}); |
| 29533 | * |
| 29534 | * Or passed to `.post()`: |
| 29535 | * |
| 29536 | * request |
| 29537 | * .post('/user', { name: 'tj' }) |
| 29538 | * .end(function(res){}); |
| 29539 | * |
| 29540 | * Or further reduced to a single call for simple cases: |
| 29541 | * |
| 29542 | * request |
| 29543 | * .post('/user', { name: 'tj' }, function(res){}); |
| 29544 | * |
| 29545 | * @param {XMLHTTPRequest} xhr |
| 29546 | * @param {Object} options |
| 29547 | * @api private |
| 29548 | */ |
| 29549 | |
| 29550 | function Response(req, options) { |
| 29551 | options = options || {}; |
| 29552 | this.req = req; |
| 29553 | this.xhr = this.req.xhr; |
| 29554 | // responseText is accessible only if responseType is '' or 'text' and on older browsers |
| 29555 | this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined') |
| 29556 | ? this.xhr.responseText |
| 29557 | : null; |
| 29558 | this.statusText = this.req.xhr.statusText; |
| 29559 | this.setStatusProperties(this.xhr.status); |
| 29560 | this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders()); |
| 29561 | // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but |
| 29562 | // getResponseHeader still works. so we get content-type even if getting |
| 29563 | // other headers fails. |
| 29564 | this.header['content-type'] = this.xhr.getResponseHeader('content-type'); |
| 29565 | this.setHeaderProperties(this.header); |
| 29566 | this.body = this.req.method != 'HEAD' |
| 29567 | ? this.parseBody(this.text ? this.text : this.xhr.response) |
| 29568 | : null; |
| 29569 | } |
| 29570 | |
| 29571 | /** |
| 29572 | * Get case-insensitive `field` value. |
| 29573 | * |
| 29574 | * @param {String} field |
| 29575 | * @return {String} |
| 29576 | * @api public |
| 29577 | */ |
| 29578 | |
| 29579 | Response.prototype.get = function(field){ |
| 29580 | return this.header[field.toLowerCase()]; |
| 29581 | }; |
| 29582 | |
| 29583 | /** |
| 29584 | * Set header related properties: |
| 29585 | * |
| 29586 | * - `.type` the content type without params |
| 29587 | * |
| 29588 | * A response of "Content-Type: text/plain; charset=utf-8" |
| 29589 | * will provide you with a `.type` of "text/plain". |
| 29590 | * |
| 29591 | * @param {Object} header |
| 29592 | * @api private |
| 29593 | */ |
| 29594 | |
| 29595 | Response.prototype.setHeaderProperties = function(header){ |
| 29596 | // content-type |
| 29597 | var ct = this.header['content-type'] || ''; |
| 29598 | this.type = type(ct); |
| 29599 | |
| 29600 | // params |
| 29601 | var obj = params(ct); |
| 29602 | for (var key in obj) this[key] = obj[key]; |
| 29603 | }; |
| 29604 | |
| 29605 | /** |
| 29606 | * Parse the given body `str`. |
| 29607 | * |
| 29608 | * Used for auto-parsing of bodies. Parsers |
| 29609 | * are defined on the `superagent.parse` object. |
| 29610 | * |
| 29611 | * @param {String} str |
| 29612 | * @return {Mixed} |
| 29613 | * @api private |
| 29614 | */ |
| 29615 | |
| 29616 | Response.prototype.parseBody = function(str){ |
| 29617 | var parse = request.parse[this.type]; |
| 29618 | return parse && str && (str.length || str instanceof Object) |
| 29619 | ? parse(str) |
| 29620 | : null; |
| 29621 | }; |
| 29622 | |
| 29623 | /** |
| 29624 | * Set flags such as `.ok` based on `status`. |
| 29625 | * |
| 29626 | * For example a 2xx response will give you a `.ok` of __true__ |
| 29627 | * whereas 5xx will be __false__ and `.error` will be __true__. The |
| 29628 | * `.clientError` and `.serverError` are also available to be more |
| 29629 | * specific, and `.statusType` is the class of error ranging from 1..5 |
| 29630 | * sometimes useful for mapping respond colors etc. |
| 29631 | * |
| 29632 | * "sugar" properties are also defined for common cases. Currently providing: |
| 29633 | * |
| 29634 | * - .noContent |
| 29635 | * - .badRequest |
| 29636 | * - .unauthorized |
| 29637 | * - .notAcceptable |
| 29638 | * - .notFound |
| 29639 | * |
| 29640 | * @param {Number} status |
| 29641 | * @api private |
| 29642 | */ |
| 29643 | |
| 29644 | Response.prototype.setStatusProperties = function(status){ |
| 29645 | // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request |
| 29646 | if (status === 1223) { |
| 29647 | status = 204; |
| 29648 | } |
| 29649 | |
| 29650 | var type = status / 100 | 0; |
| 29651 | |
| 29652 | // status / class |
| 29653 | this.status = status; |
| 29654 | this.statusType = type; |
| 29655 | |
| 29656 | // basics |
| 29657 | this.info = 1 == type; |
| 29658 | this.ok = 2 == type; |
| 29659 | this.clientError = 4 == type; |
| 29660 | this.serverError = 5 == type; |
| 29661 | this.error = (4 == type || 5 == type) |
| 29662 | ? this.toError() |
| 29663 | : false; |
| 29664 | |
| 29665 | // sugar |
| 29666 | this.accepted = 202 == status; |
| 29667 | this.noContent = 204 == status; |
| 29668 | this.badRequest = 400 == status; |
| 29669 | this.unauthorized = 401 == status; |
| 29670 | this.notAcceptable = 406 == status; |
| 29671 | this.notFound = 404 == status; |
| 29672 | this.forbidden = 403 == status; |
| 29673 | }; |
| 29674 | |
| 29675 | /** |
| 29676 | * Return an `Error` representative of this response. |
| 29677 | * |
| 29678 | * @return {Error} |
| 29679 | * @api public |
| 29680 | */ |
| 29681 | |
| 29682 | Response.prototype.toError = function(){ |
| 29683 | var req = this.req; |
| 29684 | var method = req.method; |
| 29685 | var url = req.url; |
| 29686 | |
| 29687 | var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')'; |
| 29688 | var err = new Error(msg); |
| 29689 | err.status = this.status; |
| 29690 | err.method = method; |
| 29691 | err.url = url; |
| 29692 | |
| 29693 | return err; |
| 29694 | }; |
| 29695 | |
| 29696 | /** |
| 29697 | * Expose `Response`. |
| 29698 | */ |
| 29699 | |
| 29700 | request.Response = Response; |
| 29701 | |
| 29702 | /** |
| 29703 | * Initialize a new `Request` with the given `method` and `url`. |
| 29704 | * |
| 29705 | * @param {String} method |
| 29706 | * @param {String} url |
| 29707 | * @api public |
| 29708 | */ |
| 29709 | |
| 29710 | function Request(method, url) { |
| 29711 | var self = this; |
| 29712 | Emitter.call(this); |
| 29713 | this._query = this._query || []; |
| 29714 | this.method = method; |
| 29715 | this.url = url; |
| 29716 | this.header = {}; |
| 29717 | this._header = {}; |
| 29718 | this.on('end', function(){ |
| 29719 | var err = null; |
| 29720 | var res = null; |
| 29721 | |
| 29722 | try { |
| 29723 | res = new Response(self); |
| 29724 | } catch(e) { |
| 29725 | err = new Error('Parser is unable to parse the response'); |
| 29726 | err.parse = true; |
| 29727 | err.original = e; |
| 29728 | return self.callback(err); |
| 29729 | } |
| 29730 | |
| 29731 | self.emit('response', res); |
| 29732 | |
| 29733 | if (err) { |
| 29734 | return self.callback(err, res); |
| 29735 | } |
| 29736 | |
| 29737 | if (res.status >= 200 && res.status < 300) { |
| 29738 | return self.callback(err, res); |
| 29739 | } |
| 29740 | |
| 29741 | var new_err = new Error(res.statusText || 'Unsuccessful HTTP response'); |
| 29742 | new_err.original = err; |
| 29743 | new_err.response = res; |
| 29744 | new_err.status = res.status; |
| 29745 | |
| 29746 | self.callback(err || new_err, res); |
| 29747 | }); |
| 29748 | } |
| 29749 | |
| 29750 | /** |
| 29751 | * Mixin `Emitter`. |
| 29752 | */ |
| 29753 | |
| 29754 | Emitter(Request.prototype); |
| 29755 | |
| 29756 | /** |
| 29757 | * Allow for extension |
| 29758 | */ |
| 29759 | |
| 29760 | Request.prototype.use = function(fn) { |
| 29761 | fn(this); |
| 29762 | return this; |
| 29763 | } |
| 29764 | |
| 29765 | /** |
| 29766 | * Set timeout to `ms`. |
| 29767 | * |
| 29768 | * @param {Number} ms |
| 29769 | * @return {Request} for chaining |
| 29770 | * @api public |
| 29771 | */ |
| 29772 | |
| 29773 | Request.prototype.timeout = function(ms){ |
| 29774 | this._timeout = ms; |
| 29775 | return this; |
| 29776 | }; |
| 29777 | |
| 29778 | /** |
| 29779 | * Clear previous timeout. |
| 29780 | * |
| 29781 | * @return {Request} for chaining |
| 29782 | * @api public |
| 29783 | */ |
| 29784 | |
| 29785 | Request.prototype.clearTimeout = function(){ |
| 29786 | this._timeout = 0; |
| 29787 | clearTimeout(this._timer); |
| 29788 | return this; |
| 29789 | }; |
| 29790 | |
| 29791 | /** |
| 29792 | * Abort the request, and clear potential timeout. |
| 29793 | * |
| 29794 | * @return {Request} |
| 29795 | * @api public |
| 29796 | */ |
| 29797 | |
| 29798 | Request.prototype.abort = function(){ |
| 29799 | if (this.aborted) return; |
| 29800 | this.aborted = true; |
| 29801 | this.xhr.abort(); |
| 29802 | this.clearTimeout(); |
| 29803 | this.emit('abort'); |
| 29804 | return this; |
| 29805 | }; |
| 29806 | |
| 29807 | /** |
| 29808 | * Set header `field` to `val`, or multiple fields with one object. |
| 29809 | * |
| 29810 | * Examples: |
| 29811 | * |
| 29812 | * req.get('/') |
| 29813 | * .set('Accept', 'application/json') |
| 29814 | * .set('X-API-Key', 'foobar') |
| 29815 | * .end(callback); |
| 29816 | * |
| 29817 | * req.get('/') |
| 29818 | * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' }) |
| 29819 | * .end(callback); |
| 29820 | * |
| 29821 | * @param {String|Object} field |
| 29822 | * @param {String} val |
| 29823 | * @return {Request} for chaining |
| 29824 | * @api public |
| 29825 | */ |
| 29826 | |
| 29827 | Request.prototype.set = function(field, val){ |
| 29828 | if (isObject(field)) { |
| 29829 | for (var key in field) { |
| 29830 | this.set(key, field[key]); |
| 29831 | } |
| 29832 | return this; |
| 29833 | } |
| 29834 | this._header[field.toLowerCase()] = val; |
| 29835 | this.header[field] = val; |
| 29836 | return this; |
| 29837 | }; |
| 29838 | |
| 29839 | /** |
| 29840 | * Remove header `field`. |
| 29841 | * |
| 29842 | * Example: |
| 29843 | * |
| 29844 | * req.get('/') |
| 29845 | * .unset('User-Agent') |
| 29846 | * .end(callback); |
| 29847 | * |
| 29848 | * @param {String} field |
| 29849 | * @return {Request} for chaining |
| 29850 | * @api public |
| 29851 | */ |
| 29852 | |
| 29853 | Request.prototype.unset = function(field){ |
| 29854 | delete this._header[field.toLowerCase()]; |
| 29855 | delete this.header[field]; |
| 29856 | return this; |
| 29857 | }; |
| 29858 | |
| 29859 | /** |
| 29860 | * Get case-insensitive header `field` value. |
| 29861 | * |
| 29862 | * @param {String} field |
| 29863 | * @return {String} |
| 29864 | * @api private |
| 29865 | */ |
| 29866 | |
| 29867 | Request.prototype.getHeader = function(field){ |
| 29868 | return this._header[field.toLowerCase()]; |
| 29869 | }; |
| 29870 | |
| 29871 | /** |
| 29872 | * Set Content-Type to `type`, mapping values from `request.types`. |
| 29873 | * |
| 29874 | * Examples: |
| 29875 | * |
| 29876 | * superagent.types.xml = 'application/xml'; |
| 29877 | * |
| 29878 | * request.post('/') |
| 29879 | * .type('xml') |
| 29880 | * .send(xmlstring) |
| 29881 | * .end(callback); |
| 29882 | * |
| 29883 | * request.post('/') |
| 29884 | * .type('application/xml') |
| 29885 | * .send(xmlstring) |
| 29886 | * .end(callback); |
| 29887 | * |
| 29888 | * @param {String} type |
| 29889 | * @return {Request} for chaining |
| 29890 | * @api public |
| 29891 | */ |
| 29892 | |
| 29893 | Request.prototype.type = function(type){ |
| 29894 | this.set('Content-Type', request.types[type] || type); |
| 29895 | return this; |
| 29896 | }; |
| 29897 | |
| 29898 | /** |
| 29899 | * Set Accept to `type`, mapping values from `request.types`. |
| 29900 | * |
| 29901 | * Examples: |
| 29902 | * |
| 29903 | * superagent.types.json = 'application/json'; |
| 29904 | * |
| 29905 | * request.get('/agent') |
| 29906 | * .accept('json') |
| 29907 | * .end(callback); |
| 29908 | * |
| 29909 | * request.get('/agent') |
| 29910 | * .accept('application/json') |
| 29911 | * .end(callback); |
| 29912 | * |
| 29913 | * @param {String} accept |
| 29914 | * @return {Request} for chaining |
| 29915 | * @api public |
| 29916 | */ |
| 29917 | |
| 29918 | Request.prototype.accept = function(type){ |
| 29919 | this.set('Accept', request.types[type] || type); |
| 29920 | return this; |
| 29921 | }; |
| 29922 | |
| 29923 | /** |
| 29924 | * Set Authorization field value with `user` and `pass`. |
| 29925 | * |
| 29926 | * @param {String} user |
| 29927 | * @param {String} pass |
| 29928 | * @return {Request} for chaining |
| 29929 | * @api public |
| 29930 | */ |
| 29931 | |
| 29932 | Request.prototype.auth = function(user, pass){ |
| 29933 | var str = btoa(user + ':' + pass); |
| 29934 | this.set('Authorization', 'Basic ' + str); |
| 29935 | return this; |
| 29936 | }; |
| 29937 | |
| 29938 | /** |
| 29939 | * Add query-string `val`. |
| 29940 | * |
| 29941 | * Examples: |
| 29942 | * |
| 29943 | * request.get('/shoes') |
| 29944 | * .query('size=10') |
| 29945 | * .query({ color: 'blue' }) |
| 29946 | * |
| 29947 | * @param {Object|String} val |
| 29948 | * @return {Request} for chaining |
| 29949 | * @api public |
| 29950 | */ |
| 29951 | |
| 29952 | Request.prototype.query = function(val){ |
| 29953 | if ('string' != typeof val) val = serialize(val); |
| 29954 | if (val) this._query.push(val); |
| 29955 | return this; |
| 29956 | }; |
| 29957 | |
| 29958 | /** |
| 29959 | * Write the field `name` and `val` for "multipart/form-data" |
| 29960 | * request bodies. |
| 29961 | * |
| 29962 | * ``` js |
| 29963 | * request.post('/upload') |
| 29964 | * .field('foo', 'bar') |
| 29965 | * .end(callback); |
| 29966 | * ``` |
| 29967 | * |
| 29968 | * @param {String} name |
| 29969 | * @param {String|Blob|File} val |
| 29970 | * @return {Request} for chaining |
| 29971 | * @api public |
| 29972 | */ |
| 29973 | |
| 29974 | Request.prototype.field = function(name, val){ |
| 29975 | if (!this._formData) this._formData = new root.FormData(); |
| 29976 | this._formData.append(name, val); |
| 29977 | return this; |
| 29978 | }; |
| 29979 | |
| 29980 | /** |
| 29981 | * Queue the given `file` as an attachment to the specified `field`, |
| 29982 | * with optional `filename`. |
| 29983 | * |
| 29984 | * ``` js |
| 29985 | * request.post('/upload') |
| 29986 | * .attach(new Blob(['<a id="a"><b id="b">hey!</b></a>'], { type: "text/html"})) |
| 29987 | * .end(callback); |
| 29988 | * ``` |
| 29989 | * |
| 29990 | * @param {String} field |
| 29991 | * @param {Blob|File} file |
| 29992 | * @param {String} filename |
| 29993 | * @return {Request} for chaining |
| 29994 | * @api public |
| 29995 | */ |
| 29996 | |
| 29997 | Request.prototype.attach = function(field, file, filename){ |
| 29998 | if (!this._formData) this._formData = new root.FormData(); |
| 29999 | this._formData.append(field, file, filename); |
| 30000 | return this; |
| 30001 | }; |
| 30002 | |
| 30003 | /** |
| 30004 | * Send `data`, defaulting the `.type()` to "json" when |
| 30005 | * an object is given. |
| 30006 | * |
| 30007 | * Examples: |
| 30008 | * |
| 30009 | * // querystring |
| 30010 | * request.get('/search') |
| 30011 | * .end(callback) |
| 30012 | * |
| 30013 | * // multiple data "writes" |
| 30014 | * request.get('/search') |
| 30015 | * .send({ search: 'query' }) |
| 30016 | * .send({ range: '1..5' }) |
| 30017 | * .send({ order: 'desc' }) |
| 30018 | * .end(callback) |
| 30019 | * |
| 30020 | * // manual json |
| 30021 | * request.post('/user') |
| 30022 | * .type('json') |
| 30023 | * .send('{"name":"tj"}) |
| 30024 | * .end(callback) |
| 30025 | * |
| 30026 | * // auto json |
| 30027 | * request.post('/user') |
| 30028 | * .send({ name: 'tj' }) |
| 30029 | * .end(callback) |
| 30030 | * |
| 30031 | * // manual x-www-form-urlencoded |
| 30032 | * request.post('/user') |
| 30033 | * .type('form') |
| 30034 | * .send('name=tj') |
| 30035 | * .end(callback) |
| 30036 | * |
| 30037 | * // auto x-www-form-urlencoded |
| 30038 | * request.post('/user') |
| 30039 | * .type('form') |
| 30040 | * .send({ name: 'tj' }) |
| 30041 | * .end(callback) |
| 30042 | * |
| 30043 | * // defaults to x-www-form-urlencoded |
| 30044 | * request.post('/user') |
| 30045 | * .send('name=tobi') |
| 30046 | * .send('species=ferret') |
| 30047 | * .end(callback) |
| 30048 | * |
| 30049 | * @param {String|Object} data |
| 30050 | * @return {Request} for chaining |
| 30051 | * @api public |
| 30052 | */ |
| 30053 | |
| 30054 | Request.prototype.send = function(data){ |
| 30055 | var obj = isObject(data); |
| 30056 | var type = this.getHeader('Content-Type'); |
| 30057 | |
| 30058 | // merge |
| 30059 | if (obj && isObject(this._data)) { |
| 30060 | for (var key in data) { |
| 30061 | this._data[key] = data[key]; |
| 30062 | } |
| 30063 | } else if ('string' == typeof data) { |
| 30064 | if (!type) this.type('form'); |
| 30065 | type = this.getHeader('Content-Type'); |
| 30066 | if ('application/x-www-form-urlencoded' == type) { |
| 30067 | this._data = this._data |
| 30068 | ? this._data + '&' + data |
| 30069 | : data; |
| 30070 | } else { |
| 30071 | this._data = (this._data || '') + data; |
| 30072 | } |
| 30073 | } else { |
| 30074 | this._data = data; |
| 30075 | } |
| 30076 | |
| 30077 | if (!obj || isHost(data)) return this; |
| 30078 | if (!type) this.type('json'); |
| 30079 | return this; |
| 30080 | }; |
| 30081 | |
| 30082 | /** |
| 30083 | * Invoke the callback with `err` and `res` |
| 30084 | * and handle arity check. |
| 30085 | * |
| 30086 | * @param {Error} err |
| 30087 | * @param {Response} res |
| 30088 | * @api private |
| 30089 | */ |
| 30090 | |
| 30091 | Request.prototype.callback = function(err, res){ |
| 30092 | var fn = this._callback; |
| 30093 | this.clearTimeout(); |
| 30094 | fn(err, res); |
| 30095 | }; |
| 30096 | |
| 30097 | /** |
| 30098 | * Invoke callback with x-domain error. |
| 30099 | * |
| 30100 | * @api private |
| 30101 | */ |
| 30102 | |
| 30103 | Request.prototype.crossDomainError = function(){ |
| 30104 | var err = new Error('Origin is not allowed by Access-Control-Allow-Origin'); |
| 30105 | err.crossDomain = true; |
| 30106 | this.callback(err); |
| 30107 | }; |
| 30108 | |
| 30109 | /** |
| 30110 | * Invoke callback with timeout error. |
| 30111 | * |
| 30112 | * @api private |
| 30113 | */ |
| 30114 | |
| 30115 | Request.prototype.timeoutError = function(){ |
| 30116 | var timeout = this._timeout; |
| 30117 | var err = new Error('timeout of ' + timeout + 'ms exceeded'); |
| 30118 | err.timeout = timeout; |
| 30119 | this.callback(err); |
| 30120 | }; |
| 30121 | |
| 30122 | /** |
| 30123 | * Enable transmission of cookies with x-domain requests. |
| 30124 | * |
| 30125 | * Note that for this to work the origin must not be |
| 30126 | * using "Access-Control-Allow-Origin" with a wildcard, |
| 30127 | * and also must set "Access-Control-Allow-Credentials" |
| 30128 | * to "true". |
| 30129 | * |
| 30130 | * @api public |
| 30131 | */ |
| 30132 | |
| 30133 | Request.prototype.withCredentials = function(){ |
| 30134 | this._withCredentials = true; |
| 30135 | return this; |
| 30136 | }; |
| 30137 | |
| 30138 | /** |
| 30139 | * Initiate request, invoking callback `fn(res)` |
| 30140 | * with an instanceof `Response`. |
| 30141 | * |
| 30142 | * @param {Function} fn |
| 30143 | * @return {Request} for chaining |
| 30144 | * @api public |
| 30145 | */ |
| 30146 | |
| 30147 | Request.prototype.end = function(fn){ |
| 30148 | var self = this; |
| 30149 | var xhr = this.xhr = request.getXHR(); |
| 30150 | var query = this._query.join('&'); |
| 30151 | var timeout = this._timeout; |
| 30152 | var data = this._formData || this._data; |
| 30153 | |
| 30154 | // store callback |
| 30155 | this._callback = fn || noop; |
| 30156 | |
| 30157 | // state change |
| 30158 | xhr.onreadystatechange = function(){ |
| 30159 | if (4 != xhr.readyState) return; |
| 30160 | |
| 30161 | // In IE9, reads to any property (e.g. status) off of an aborted XHR will |
| 30162 | // result in the error "Could not complete the operation due to error c00c023f" |
| 30163 | var status; |
| 30164 | try { status = xhr.status } catch(e) { status = 0; } |
| 30165 | |
| 30166 | if (0 == status) { |
| 30167 | if (self.timedout) return self.timeoutError(); |
| 30168 | if (self.aborted) return; |
| 30169 | return self.crossDomainError(); |
| 30170 | } |
| 30171 | self.emit('end'); |
| 30172 | }; |
| 30173 | |
| 30174 | // progress |
| 30175 | var handleProgress = function(e){ |
| 30176 | if (e.total > 0) { |
| 30177 | e.percent = e.loaded / e.total * 100; |
| 30178 | } |
| 30179 | self.emit('progress', e); |
| 30180 | }; |
| 30181 | if (this.hasListeners('progress')) { |
| 30182 | xhr.onprogress = handleProgress; |
| 30183 | } |
| 30184 | try { |
| 30185 | if (xhr.upload && this.hasListeners('progress')) { |
| 30186 | xhr.upload.onprogress = handleProgress; |
| 30187 | } |
| 30188 | } catch(e) { |
| 30189 | // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist. |
| 30190 | // Reported here: |
| 30191 | // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context |
| 30192 | } |
| 30193 | |
| 30194 | // timeout |
| 30195 | if (timeout && !this._timer) { |
| 30196 | this._timer = setTimeout(function(){ |
| 30197 | self.timedout = true; |
| 30198 | self.abort(); |
| 30199 | }, timeout); |
| 30200 | } |
| 30201 | |
| 30202 | // querystring |
| 30203 | if (query) { |
| 30204 | query = request.serializeObject(query); |
| 30205 | this.url += ~this.url.indexOf('?') |
| 30206 | ? '&' + query |
| 30207 | : '?' + query; |
| 30208 | } |
| 30209 | |
| 30210 | // initiate request |
| 30211 | xhr.open(this.method, this.url, true); |
| 30212 | |
| 30213 | // CORS |
| 30214 | if (this._withCredentials) xhr.withCredentials = true; |
| 30215 | |
| 30216 | // body |
| 30217 | if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !isHost(data)) { |
| 30218 | // serialize stuff |
| 30219 | var serialize = request.serialize[this.getHeader('Content-Type')]; |
| 30220 | if (serialize) data = serialize(data); |
| 30221 | } |
| 30222 | |
| 30223 | // set header fields |
| 30224 | for (var field in this.header) { |
| 30225 | if (null == this.header[field]) continue; |
| 30226 | xhr.setRequestHeader(field, this.header[field]); |
| 30227 | } |
| 30228 | |
| 30229 | // send stuff |
| 30230 | this.emit('request', this); |
| 30231 | xhr.send(data); |
| 30232 | return this; |
| 30233 | }; |
| 30234 | |
| 30235 | /** |
| 30236 | * Expose `Request`. |
| 30237 | */ |
| 30238 | |
| 30239 | request.Request = Request; |
| 30240 | |
| 30241 | /** |
| 30242 | * Issue a request: |
| 30243 | * |
| 30244 | * Examples: |
| 30245 | * |
| 30246 | * request('GET', '/users').end(callback) |
| 30247 | * request('/users').end(callback) |
| 30248 | * request('/users', callback) |
| 30249 | * |
| 30250 | * @param {String} method |
| 30251 | * @param {String|Function} url or callback |
| 30252 | * @return {Request} |
| 30253 | * @api public |
| 30254 | */ |
| 30255 | |
| 30256 | function request(method, url) { |
| 30257 | // callback |
| 30258 | if ('function' == typeof url) { |
| 30259 | return new Request('GET', method).end(url); |
| 30260 | } |
| 30261 | |
| 30262 | // url first |
| 30263 | if (1 == arguments.length) { |
| 30264 | return new Request('GET', method); |
| 30265 | } |
| 30266 | |
| 30267 | return new Request(method, url); |
| 30268 | } |
| 30269 | |
| 30270 | /** |
| 30271 | * GET `url` with optional callback `fn(res)`. |
| 30272 | * |
| 30273 | * @param {String} url |
| 30274 | * @param {Mixed|Function} data or fn |
| 30275 | * @param {Function} fn |
| 30276 | * @return {Request} |
| 30277 | * @api public |
| 30278 | */ |
| 30279 | |
| 30280 | request.get = function(url, data, fn){ |
| 30281 | var req = request('GET', url); |
| 30282 | if ('function' == typeof data) fn = data, data = null; |
| 30283 | if (data) req.query(data); |
| 30284 | if (fn) req.end(fn); |
| 30285 | return req; |
| 30286 | }; |
| 30287 | |
| 30288 | /** |
| 30289 | * HEAD `url` with optional callback `fn(res)`. |
| 30290 | * |
| 30291 | * @param {String} url |
| 30292 | * @param {Mixed|Function} data or fn |
| 30293 | * @param {Function} fn |
| 30294 | * @return {Request} |
| 30295 | * @api public |
| 30296 | */ |
| 30297 | |
| 30298 | request.head = function(url, data, fn){ |
| 30299 | var req = request('HEAD', url); |
| 30300 | if ('function' == typeof data) fn = data, data = null; |
| 30301 | if (data) req.send(data); |
| 30302 | if (fn) req.end(fn); |
| 30303 | return req; |
| 30304 | }; |
| 30305 | |
| 30306 | /** |
| 30307 | * DELETE `url` with optional callback `fn(res)`. |
| 30308 | * |
| 30309 | * @param {String} url |
| 30310 | * @param {Function} fn |
| 30311 | * @return {Request} |
| 30312 | * @api public |
| 30313 | */ |
| 30314 | |
| 30315 | request.del = function(url, fn){ |
| 30316 | var req = request('DELETE', url); |
| 30317 | if (fn) req.end(fn); |
| 30318 | return req; |
| 30319 | }; |
| 30320 | |
| 30321 | /** |
| 30322 | * PATCH `url` with optional `data` and callback `fn(res)`. |
| 30323 | * |
| 30324 | * @param {String} url |
| 30325 | * @param {Mixed} data |
| 30326 | * @param {Function} fn |
| 30327 | * @return {Request} |
| 30328 | * @api public |
| 30329 | */ |
| 30330 | |
| 30331 | request.patch = function(url, data, fn){ |
| 30332 | var req = request('PATCH', url); |
| 30333 | if ('function' == typeof data) fn = data, data = null; |
| 30334 | if (data) req.send(data); |
| 30335 | if (fn) req.end(fn); |
| 30336 | return req; |
| 30337 | }; |
| 30338 | |
| 30339 | /** |
| 30340 | * POST `url` with optional `data` and callback `fn(res)`. |
| 30341 | * |
| 30342 | * @param {String} url |
| 30343 | * @param {Mixed} data |
| 30344 | * @param {Function} fn |
| 30345 | * @return {Request} |
| 30346 | * @api public |
| 30347 | */ |
| 30348 | |
| 30349 | request.post = function(url, data, fn){ |
| 30350 | var req = request('POST', url); |
| 30351 | if ('function' == typeof data) fn = data, data = null; |
| 30352 | if (data) req.send(data); |
| 30353 | if (fn) req.end(fn); |
| 30354 | return req; |
| 30355 | }; |
| 30356 | |
| 30357 | /** |
| 30358 | * PUT `url` with optional `data` and callback `fn(res)`. |
| 30359 | * |
| 30360 | * @param {String} url |
| 30361 | * @param {Mixed|Function} data or fn |
| 30362 | * @param {Function} fn |
| 30363 | * @return {Request} |
| 30364 | * @api public |
| 30365 | */ |
| 30366 | |
| 30367 | request.put = function(url, data, fn){ |
| 30368 | var req = request('PUT', url); |
| 30369 | if ('function' == typeof data) fn = data, data = null; |
| 30370 | if (data) req.send(data); |
| 30371 | if (fn) req.end(fn); |
| 30372 | return req; |
| 30373 | }; |
| 30374 | |
| 30375 | /** |
| 30376 | * Expose `request`. |
| 30377 | */ |
| 30378 | |
| 30379 | module.exports = request; |
| 30380 | |
| 30381 | },{"emitter":164,"reduce":165}],164:[function(require,module,exports){ |
| 30382 | |
| 30383 | /** |
| 30384 | * Expose `Emitter`. |
| 30385 | */ |
| 30386 | |
| 30387 | module.exports = Emitter; |
| 30388 | |
| 30389 | /** |
| 30390 | * Initialize a new `Emitter`. |
| 30391 | * |
| 30392 | * @api public |
| 30393 | */ |
| 30394 | |
| 30395 | function Emitter(obj) { |
| 30396 | if (obj) return mixin(obj); |
| 30397 | }; |
| 30398 | |
| 30399 | /** |
| 30400 | * Mixin the emitter properties. |
| 30401 | * |
| 30402 | * @param {Object} obj |
| 30403 | * @return {Object} |
| 30404 | * @api private |
| 30405 | */ |
| 30406 | |
| 30407 | function mixin(obj) { |
| 30408 | for (var key in Emitter.prototype) { |
| 30409 | obj[key] = Emitter.prototype[key]; |
| 30410 | } |
| 30411 | return obj; |
| 30412 | } |
| 30413 | |
| 30414 | /** |
| 30415 | * Listen on the given `event` with `fn`. |
| 30416 | * |
| 30417 | * @param {String} event |
| 30418 | * @param {Function} fn |
| 30419 | * @return {Emitter} |
| 30420 | * @api public |
| 30421 | */ |
| 30422 | |
| 30423 | Emitter.prototype.on = |
| 30424 | Emitter.prototype.addEventListener = function(event, fn){ |
| 30425 | this._callbacks = this._callbacks || {}; |
| 30426 | (this._callbacks[event] = this._callbacks[event] || []) |
| 30427 | .push(fn); |
| 30428 | return this; |
| 30429 | }; |
| 30430 | |
| 30431 | /** |
| 30432 | * Adds an `event` listener that will be invoked a single |
| 30433 | * time then automatically removed. |
| 30434 | * |
| 30435 | * @param {String} event |
| 30436 | * @param {Function} fn |
| 30437 | * @return {Emitter} |
| 30438 | * @api public |
| 30439 | */ |
| 30440 | |
| 30441 | Emitter.prototype.once = function(event, fn){ |
| 30442 | var self = this; |
| 30443 | this._callbacks = this._callbacks || {}; |
| 30444 | |
| 30445 | function on() { |
| 30446 | self.off(event, on); |
| 30447 | fn.apply(this, arguments); |
| 30448 | } |
| 30449 | |
| 30450 | on.fn = fn; |
| 30451 | this.on(event, on); |
| 30452 | return this; |
| 30453 | }; |
| 30454 | |
| 30455 | /** |
| 30456 | * Remove the given callback for `event` or all |
| 30457 | * registered callbacks. |
| 30458 | * |
| 30459 | * @param {String} event |
| 30460 | * @param {Function} fn |
| 30461 | * @return {Emitter} |
| 30462 | * @api public |
| 30463 | */ |
| 30464 | |
| 30465 | Emitter.prototype.off = |
| 30466 | Emitter.prototype.removeListener = |
| 30467 | Emitter.prototype.removeAllListeners = |
| 30468 | Emitter.prototype.removeEventListener = function(event, fn){ |
| 30469 | this._callbacks = this._callbacks || {}; |
| 30470 | |
| 30471 | // all |
| 30472 | if (0 == arguments.length) { |
| 30473 | this._callbacks = {}; |
| 30474 | return this; |
| 30475 | } |
| 30476 | |
| 30477 | // specific event |
| 30478 | var callbacks = this._callbacks[event]; |
| 30479 | if (!callbacks) return this; |
| 30480 | |
| 30481 | // remove all handlers |
| 30482 | if (1 == arguments.length) { |
| 30483 | delete this._callbacks[event]; |
| 30484 | return this; |
| 30485 | } |
| 30486 | |
| 30487 | // remove specific handler |
| 30488 | var cb; |
| 30489 | for (var i = 0; i < callbacks.length; i++) { |
| 30490 | cb = callbacks[i]; |
| 30491 | if (cb === fn || cb.fn === fn) { |
| 30492 | callbacks.splice(i, 1); |
| 30493 | break; |
| 30494 | } |
| 30495 | } |
| 30496 | return this; |
| 30497 | }; |
| 30498 | |
| 30499 | /** |
| 30500 | * Emit `event` with the given args. |
| 30501 | * |
| 30502 | * @param {String} event |
| 30503 | * @param {Mixed} ... |
| 30504 | * @return {Emitter} |
| 30505 | */ |
| 30506 | |
| 30507 | Emitter.prototype.emit = function(event){ |
| 30508 | this._callbacks = this._callbacks || {}; |
| 30509 | var args = [].slice.call(arguments, 1) |
| 30510 | , callbacks = this._callbacks[event]; |
| 30511 | |
| 30512 | if (callbacks) { |
| 30513 | callbacks = callbacks.slice(0); |
| 30514 | for (var i = 0, len = callbacks.length; i < len; ++i) { |
| 30515 | callbacks[i].apply(this, args); |
| 30516 | } |
| 30517 | } |
| 30518 | |
| 30519 | return this; |
| 30520 | }; |
| 30521 | |
| 30522 | /** |
| 30523 | * Return array of callbacks for `event`. |
| 30524 | * |
| 30525 | * @param {String} event |
| 30526 | * @return {Array} |
| 30527 | * @api public |
| 30528 | */ |
| 30529 | |
| 30530 | Emitter.prototype.listeners = function(event){ |
| 30531 | this._callbacks = this._callbacks || {}; |
| 30532 | return this._callbacks[event] || []; |
| 30533 | }; |
| 30534 | |
| 30535 | /** |
| 30536 | * Check if this emitter has `event` handlers. |
| 30537 | * |
| 30538 | * @param {String} event |
| 30539 | * @return {Boolean} |
| 30540 | * @api public |
| 30541 | */ |
| 30542 | |
| 30543 | Emitter.prototype.hasListeners = function(event){ |
| 30544 | return !! this.listeners(event).length; |
| 30545 | }; |
| 30546 | |
| 30547 | },{}],165:[function(require,module,exports){ |
| 30548 | |
| 30549 | /** |
| 30550 | * Reduce `arr` with `fn`. |
| 30551 | * |
| 30552 | * @param {Array} arr |
| 30553 | * @param {Function} fn |
| 30554 | * @param {Mixed} initial |
| 30555 | * |
| 30556 | * TODO: combatible error handling? |
| 30557 | */ |
| 30558 | |
| 30559 | module.exports = function(arr, fn, initial){ |
| 30560 | var idx = 0; |
| 30561 | var len = arr.length; |
| 30562 | var curr = arguments.length == 3 |
| 30563 | ? initial |
| 30564 | : arr[idx++]; |
| 30565 | |
| 30566 | while (idx < len) { |
| 30567 | curr = fn.call(null, curr, arr[idx], ++idx, arr); |
| 30568 | } |
| 30569 | |
| 30570 | return curr; |
| 30571 | }; |
| 30572 | },{}]},{},[1])(1) |
| 30573 | }); |
| 30574 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJpbmRleC5qcyIsImxpYi9hdXRoLmpzIiwibGliL2NsaWVudC5qcyIsImxpYi9oZWxwZXJzLmpzIiwibGliL2h0dHAuanMiLCJsaWIvcmVzb2x2ZXIuanMiLCJsaWIvc3BlYy1jb252ZXJ0ZXIuanMiLCJsaWIvdHlwZXMvbW9kZWwuanMiLCJsaWIvdHlwZXMvb3BlcmF0aW9uLmpzIiwibGliL3R5cGVzL29wZXJhdGlvbkdyb3VwLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcmVzb2x2ZS9lbXB0eS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9idWZmZXIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnVmZmVyL25vZGVfbW9kdWxlcy9iYXNlNjQtanMvbGliL2I2NC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9idWZmZXIvbm9kZV9tb2R1bGVzL2llZWU3NTQvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnVmZmVyL25vZGVfbW9kdWxlcy9pcy1hcnJheS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wcm9jZXNzL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvYnRvYS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9jb29raWVqYXIvY29va2llamFyLmpzIiwibm9kZV9tb2R1bGVzL2pxdWVyeS9kaXN0L2pxdWVyeS5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC9jb21tb24uanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC9kdW1wZXIuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC9leGNlcHRpb24uanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC9sb2FkZXIuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC9tYXJrLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvc2NoZW1hLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvc2NoZW1hL2NvcmUuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC9zY2hlbWEvZGVmYXVsdF9mdWxsLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvc2NoZW1hL2RlZmF1bHRfc2FmZS5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3NjaGVtYS9mYWlsc2FmZS5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3NjaGVtYS9qc29uLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvYmluYXJ5LmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9ib29sLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9mbG9hdC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvaW50LmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9qcy9mdW5jdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvanMvcmVnZXhwLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9qcy91bmRlZmluZWQuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL21hcC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvbWVyZ2UuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL251bGwuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL29tYXAuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL3BhaXJzLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9zZXEuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL3NldC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvc3RyLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS90aW1lc3RhbXAuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9ub2RlX21vZHVsZXMvZXNwcmltYS9lc3ByaW1hLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvYXJyYXkvaW5kZXhPZi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2FycmF5L2xhc3QuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jaGFpbi9sb2Rhc2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2VhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2ZpbmQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2ZvckVhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2luY2x1ZGVzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9tYXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9kYXRlL25vdy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2Z1bmN0aW9uL2JpbmQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9mdW5jdGlvbi9yZXN0UGFyYW0uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9MYXp5V3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL0xvZGFzaFdyYXBwZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9hcnJheUNvcHkuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9hcnJheUVhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9hcnJheU1hcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2FycmF5U29tZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VBc3NpZ24uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlQ2FsbGJhY2suanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlQ2xvbmUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlQ29weS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VDcmVhdGUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlRWFjaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VGaW5kLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUZpbmRJbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VGb3IuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlRm9ySW4uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlRm9yT3duLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUdldC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VJbmRleE9mLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUlzRXF1YWwuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlSXNFcXVhbERlZXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlSXNGdW5jdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VJc01hdGNoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUxvZGFzaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VNYXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlTWF0Y2hlcy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VNYXRjaGVzUHJvcGVydHkuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlUHJvcGVydHkuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlUHJvcGVydHlEZWVwLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVNldERhdGEuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlU2xpY2UuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlVG9TdHJpbmcuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlVmFsdWVzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmluYXJ5SW5kZXguanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iaW5hcnlJbmRleEJ5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmluZENhbGxiYWNrLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYnVmZmVyQ2xvbmUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jb21wb3NlQXJncy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NvbXBvc2VBcmdzUmlnaHQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jcmVhdGVCYXNlRWFjaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NyZWF0ZUJhc2VGb3IuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jcmVhdGVCaW5kV3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NyZWF0ZUN0b3JXcmFwcGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlRmluZC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NyZWF0ZUZvckVhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jcmVhdGVIeWJyaWRXcmFwcGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlUGFydGlhbFdyYXBwZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jcmVhdGVXcmFwcGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvZXF1YWxBcnJheXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9lcXVhbEJ5VGFnLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvZXF1YWxPYmplY3RzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvZ2V0RGF0YS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldEZ1bmNOYW1lLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvZ2V0TGVuZ3RoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvZ2V0TWF0Y2hEYXRhLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvZ2V0TmF0aXZlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaW5kZXhPZk5hTi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2luaXRDbG9uZUFycmF5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaW5pdENsb25lQnlUYWcuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pbml0Q2xvbmVPYmplY3QuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0FycmF5TGlrZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2lzSG9zdE9iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2lzSW5kZXguanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0l0ZXJhdGVlQ2FsbC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2lzS2V5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaXNMYXppYWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2lzTGVuZ3RoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaXNPYmplY3RMaWtlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaXNTdHJpY3RDb21wYXJhYmxlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvbWVyZ2VEYXRhLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvbWV0YU1hcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL3JlYWxOYW1lcy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL3Jlb3JkZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9yZXBsYWNlSG9sZGVycy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL3NldERhdGEuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9zaGltSXNQbGFpbk9iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL3NoaW1LZXlzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvdG9PYmplY3QuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC90b1BhdGguanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC93cmFwcGVyQ2xvbmUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9sYW5nL2Nsb25lRGVlcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNBcmd1bWVudHMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9sYW5nL2lzQXJyYXkuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9sYW5nL2lzRW1wdHkuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9sYW5nL2lzRnVuY3Rpb24uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9sYW5nL2lzTmF0aXZlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc09iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNQbGFpbk9iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNTdHJpbmcuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9sYW5nL2lzVHlwZWRBcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNVbmRlZmluZWQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9vYmplY3Qva2V5cy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L29iamVjdC9rZXlzSW4uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9vYmplY3QvcGFpcnMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9vYmplY3QvdmFsdWVzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvc3RyaW5nL2VzY2FwZVJlZ0V4cC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L3N1cHBvcnQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC91dGlsaXR5L2NvbnN0YW50LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvdXRpbGl0eS9pZGVudGl0eS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L3V0aWxpdHkvbm9vcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L3V0aWxpdHkvcHJvcGVydHkuanMiLCJub2RlX21vZHVsZXMvc3VwZXJhZ2VudC9saWIvY2xpZW50LmpzIiwibm9kZV9tb2R1bGVzL3N1cGVyYWdlbnQvbm9kZV9tb2R1bGVzL2NvbXBvbmVudC1lbWl0dGVyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3N1cGVyYWdlbnQvbm9kZV9tb2R1bGVzL3JlZHVjZS1jb21wb25lbnQvaW5kZXguanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUM3ZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3RIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDclBBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOW1CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JhQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzE1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7O0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ256Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUMxREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxL1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxMEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsakRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDenNLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0hBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDdkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUN2REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQy9HQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDM0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25FQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDL0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDekZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUMvQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUMxQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ2hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNubUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIid1c2Ugc3RyaWN0JztcblxudmFyIGF1dGggPSByZXF1aXJlKCcuL2xpYi9hdXRoJyk7XG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4vbGliL2hlbHBlcnMnKTtcbnZhciBTd2FnZ2VyQ2xpZW50ID0gcmVxdWlyZSgnLi9saWIvY2xpZW50Jyk7XG52YXIgZGVwcmVjYXRpb25XcmFwcGVyID0gZnVuY3Rpb24gKHVybCwgb3B0aW9ucykge1xuICBoZWxwZXJzLmxvZygnVGhpcyBpcyBkZXByZWNhdGVkLCB1c2UgXCJuZXcgU3dhZ2dlckNsaWVudFwiIGluc3RlYWQuJyk7XG5cbiAgcmV0dXJuIG5ldyBTd2FnZ2VyQ2xpZW50KHVybCwgb3B0aW9ucyk7XG59O1xuXG4vKiBIZXJlIGZvciBJRTggU3VwcG9ydCAqL1xuaWYgKCFBcnJheS5wcm90b3R5cGUuaW5kZXhPZikge1xuICBBcnJheS5wcm90b3R5cGUuaW5kZXhPZiA9IGZ1bmN0aW9uKG9iaiwgc3RhcnQpIHtcbiAgICBmb3IgKHZhciBpID0gKHN0YXJ0IHx8IDApLCBqID0gdGhpcy5sZW5ndGg7IGkgPCBqOyBpKyspIHtcbiAgICAgIGlmICh0aGlzW2ldID09PSBvYmopIHsgcmV0dXJuIGk7IH1cbiAgICB9XG4gICAgcmV0dXJuIC0xO1xuICB9O1xufVxuXG4vKiBIZXJlIGZvciBJRTggU3VwcG9ydCAqL1xuaWYgKCFTdHJpbmcucHJvdG90eXBlLnRyaW0pIHtcbiAgU3RyaW5nLnByb3RvdHlwZS50cmltID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnJlcGxhY2UoL15cXHMrfFxccyskL2csICcnKTtcbiAgfTtcbn1cblxuLyogSGVyZSBmb3Igbm9kZSAxMC54IHN1cHBvcnQgKi9cbmlmICghU3RyaW5nLnByb3RvdHlwZS5lbmRzV2l0aCkge1xuICBTdHJpbmcucHJvdG90eXBlLmVuZHNXaXRoID0gZnVuY3Rpb24oc3VmZml4KSB7XG4gICAgcmV0dXJuIHRoaXMuaW5kZXhPZihzdWZmaXgsIHRoaXMubGVuZ3RoIC0gc3VmZml4Lmxlbmd0aCkgIT09IC0xO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFN3YWdnZXJDbGllbnQ7XG5cblN3YWdnZXJDbGllbnQuQXBpS2V5QXV0aG9yaXphdGlvbiA9IGF1dGguQXBpS2V5QXV0aG9yaXphdGlvbjtcblN3YWdnZXJDbGllbnQuUGFzc3dvcmRBdXRob3JpemF0aW9uID0gYXV0aC5QYXNzd29yZEF1dGhvcml6YXRpb247XG5Td2FnZ2VyQ2xpZW50LkNvb2tpZUF1dGhvcml6YXRpb24gPSBhdXRoLkNvb2tpZUF1dGhvcml6YXRpb247XG5Td2FnZ2VyQ2xpZW50LlN3YWdnZXJBcGkgPSBkZXByZWNhdGlvbldyYXBwZXI7XG5Td2FnZ2VyQ2xpZW50LlN3YWdnZXJDbGllbnQgPSBkZXByZWNhdGlvbldyYXBwZXI7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBidG9hID0gcmVxdWlyZSgnYnRvYScpOyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbnZhciBDb29raWVKYXIgPSByZXF1aXJlKCdjb29raWVqYXInKTtcbnZhciBfID0ge1xuICBlYWNoOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2NvbGxlY3Rpb24vZWFjaCcpLFxuICBpbmNsdWRlczogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2luY2x1ZGVzJyksXG4gIGlzT2JqZWN0OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNPYmplY3QnKSxcbiAgaXNBcnJheTogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzQXJyYXknKVxufTtcblxuLyoqXG4gKiBTd2FnZ2VyQXV0aG9yaXphdGlvbnMgYXBwbHlzIHRoZSBjb3JyZWN0IGF1dGhvcml6YXRpb24gdG8gYW4gb3BlcmF0aW9uIGJlaW5nIGV4ZWN1dGVkXG4gKi9cbnZhciBTd2FnZ2VyQXV0aG9yaXphdGlvbnMgPSBtb2R1bGUuZXhwb3J0cy5Td2FnZ2VyQXV0aG9yaXphdGlvbnMgPSBmdW5jdGlvbiAoYXV0aHopIHtcbiAgdGhpcy5hdXRoeiA9IGF1dGh6IHx8IHt9O1xufTtcblxuLyoqXG4gKiBBZGQgYXV0aHMgdG8gdGhlIGhhc2hcbiAqIFdpbGwgb3ZlcndyaXRlIGFueSBleGlzdGluZ1xuICpcbiAqL1xuU3dhZ2dlckF1dGhvcml6YXRpb25zLnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiAobmFtZSwgYXV0aCkge1xuICBpZihuYW1lICYmIHR5cGVvZiBuYW1lID09PSAnb2JqZWN0Jykge1xuICAgIGZvciAodmFyIGtleSBpbiBuYW1lKSB7XG4gICAgICB0aGlzLmF1dGh6W2tleV0gPSBuYW1lW2tleV07XG4gICAgfVxuICB9IGVsc2UgaWYodHlwZW9mIG5hbWUgPT09ICdzdHJpbmcnICl7XG4gICAgdGhpcy5hdXRoeltuYW1lXSA9IGF1dGg7XG4gIH1cblxuICByZXR1cm4gYXV0aDtcbn07XG5cblN3YWdnZXJBdXRob3JpemF0aW9ucy5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgcmV0dXJuIGRlbGV0ZSB0aGlzLmF1dGh6W25hbWVdO1xufTtcblxuU3dhZ2dlckF1dGhvcml6YXRpb25zLnByb3RvdHlwZS5hcHBseSA9IGZ1bmN0aW9uIChvYmosIHNlY3VyaXRpZXMpIHtcbiAgdmFyIHN0YXR1cyA9IG51bGw7XG4gIHZhciBhcHBseUFsbCA9ICFzZWN1cml0aWVzO1xuICB2YXIgZmxhdHRlbmVkU2VjdXJpdGllcyA9IFtdO1xuXG4gIC8vIFNlY3VyaXRpZXMgY291bGQgYmUgWyB7fSBdXG4gIF8uZWFjaChzZWN1cml0aWVzLCBmdW5jdGlvbiAob2JqLCBrZXkpIHtcblxuICAgIC8vIE1ha2Ugc3VyZSB3ZSBhY2NvdW50IGZvciBzZWN1cml0aWVzIGJlaW5nIFsgc3RyIF1cbiAgICBpZih0eXBlb2Yga2V5ID09PSAnc3RyaW5nJykge1xuICAgICAgZmxhdHRlbmVkU2VjdXJpdGllcy5wdXNoKGtleSk7XG4gICAgfVxuXG4gICAgLy8gRmxhdHRlbiBrZXlzIGluIHRvIG91ciBhcnJheVxuICAgIF8uZWFjaChvYmosIGZ1bmN0aW9uICh2YWwsIGtleSkge1xuICAgICAgZmxhdHRlbmVkU2VjdXJpdGllcy5wdXNoKGtleSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIF8uZWFjaCh0aGlzLmF1dGh6LCBmdW5jdGlvbiAoYXV0aCwgYXV0aE5hbWUpIHtcbiAgICBpZihhcHBseUFsbCB8fCBfLmluY2x1ZGVzKGZsYXR0ZW5lZFNlY3VyaXRpZXMsIGF1dGhOYW1lKSkge1xuICAgICAgc3RhdHVzID0gc3RhdHVzIHx8ICEhYXV0aC5hcHBseShvYmopOyAvLyBsb2dpY2FsIE9ScyByZWdhcmRpbmcgc3RhdHVzXG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gc3RhdHVzO1xufTtcblxuLyoqXG4gKiBBcGlLZXlBdXRob3JpemF0aW9uIGFsbG93cyBhIHF1ZXJ5IHBhcmFtIG9yIGhlYWRlciB0byBiZSBpbmplY3RlZFxuICovXG52YXIgQXBpS2V5QXV0aG9yaXphdGlvbiA9IG1vZHVsZS5leHBvcnRzLkFwaUtleUF1dGhvcml6YXRpb24gPSBmdW5jdGlvbiAobmFtZSwgdmFsdWUsIHR5cGUpIHtcbiAgdGhpcy5uYW1lID0gbmFtZTtcbiAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICB0aGlzLnR5cGUgPSB0eXBlO1xufTtcblxuQXBpS2V5QXV0aG9yaXphdGlvbi5wcm90b3R5cGUuYXBwbHkgPSBmdW5jdGlvbiAob2JqKSB7XG4gIGlmICh0aGlzLnR5cGUgPT09ICdxdWVyeScpIHtcbiAgICBpZiAob2JqLnVybC5pbmRleE9mKCc/JykgPiAwKSB7XG4gICAgICBvYmoudXJsID0gb2JqLnVybCArICcmJyArIHRoaXMubmFtZSArICc9JyArIHRoaXMudmFsdWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9iai51cmwgPSBvYmoudXJsICsgJz8nICsgdGhpcy5uYW1lICsgJz0nICsgdGhpcy52YWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBlbHNlIGlmICh0aGlzLnR5cGUgPT09ICdoZWFkZXInKSB7XG4gICAgb2JqLmhlYWRlcnNbdGhpcy5uYW1lXSA9IHRoaXMudmFsdWU7XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufTtcblxudmFyIENvb2tpZUF1dGhvcml6YXRpb24gPSBtb2R1bGUuZXhwb3J0cy5Db29raWVBdXRob3JpemF0aW9uID0gZnVuY3Rpb24gKGNvb2tpZSkge1xuICB0aGlzLmNvb2tpZSA9IGNvb2tpZTtcbn07XG5cbkNvb2tpZUF1dGhvcml6YXRpb24ucHJvdG90eXBlLmFwcGx5ID0gZnVuY3Rpb24gKG9iaikge1xuICBvYmouY29va2llSmFyID0gb2JqLmNvb2tpZUphciB8fCBuZXcgQ29va2llSmFyKCk7XG4gIG9iai5jb29raWVKYXIuc2V0Q29va2llKHRoaXMuY29va2llKTtcblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbi8qKlxuICogUGFzc3dvcmQgQXV0aG9yaXphdGlvbiBpcyBhIGJhc2ljIGF1dGggaW1wbGVtZW50YXRpb25cbiAqL1xudmFyIFBhc3N3b3JkQXV0aG9yaXphdGlvbiA9IG1vZHVsZS5leHBvcnRzLlBhc3N3b3JkQXV0aG9yaXphdGlvbiA9IGZ1bmN0aW9uIChuYW1lLCB1c2VybmFtZSwgcGFzc3dvcmQpIHtcbiAgdGhpcy5uYW1lID0gbmFtZTtcbiAgdGhpcy51c2VybmFtZSA9IHVzZXJuYW1lO1xuICB0aGlzLnBhc3N3b3JkID0gcGFzc3dvcmQ7XG59O1xuXG5QYXNzd29yZEF1dGhvcml6YXRpb24ucHJvdG90eXBlLmFwcGx5ID0gZnVuY3Rpb24gKG9iaikge1xuICBvYmouaGVhZGVycy5BdXRob3JpemF0aW9uID0gJ0Jhc2ljICcgKyBidG9hKHRoaXMudXNlcm5hbWUgKyAnOicgKyB0aGlzLnBhc3N3b3JkKTtcblxuICByZXR1cm4gdHJ1ZTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBfID0ge1xuICBiaW5kOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2Z1bmN0aW9uL2JpbmQnKSxcbiAgY2xvbmVEZWVwOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvY2xvbmVEZWVwJyksXG4gIGZpbmQ6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9maW5kJyksXG4gIGZvckVhY2g6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9mb3JFYWNoJyksXG4gIGluZGV4T2Y6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvYXJyYXkvaW5kZXhPZicpLFxuICBpc0FycmF5OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNBcnJheScpLFxuICBpc0Z1bmN0aW9uOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNGdW5jdGlvbicpLFxuICBpc1BsYWluT2JqZWN0OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNQbGFpbk9iamVjdCcpLFxuICBpc1VuZGVmaW5lZDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzVW5kZWZpbmVkJylcbn07XG52YXIgYXV0aCA9IHJlcXVpcmUoJy4vYXV0aCcpO1xudmFyIGhlbHBlcnMgPSByZXF1aXJlKCcuL2hlbHBlcnMnKTtcbnZhciBNb2RlbCA9IHJlcXVpcmUoJy4vdHlwZXMvbW9kZWwnKTtcbnZhciBPcGVyYXRpb24gPSByZXF1aXJlKCcuL3R5cGVzL29wZXJhdGlvbicpO1xudmFyIE9wZXJhdGlvbkdyb3VwID0gcmVxdWlyZSgnLi90eXBlcy9vcGVyYXRpb25Hcm91cCcpO1xudmFyIFJlc29sdmVyID0gcmVxdWlyZSgnLi9yZXNvbHZlcicpO1xudmFyIFN3YWdnZXJIdHRwID0gcmVxdWlyZSgnLi9odHRwJyk7XG52YXIgU3dhZ2dlclNwZWNDb252ZXJ0ZXIgPSByZXF1aXJlKCcuL3NwZWMtY29udmVydGVyJyk7XG5cbi8vIFdlIGhhdmUgdG8ga2VlcCB0cmFjayBvZiB0aGUgZnVuY3Rpb24vcHJvcGVydHkgbmFtZXMgdG8gYXZvaWQgY29sbGlzaW9ucyBmb3IgdGFnIG5hbWVzIHdoaWNoIGFyZSB1c2VkIHRvIGFsbG93IHRoZVxuLy8gZm9sbG93aW5nIHVzYWdlOiAnY2xpZW50Lnt0YWdOYW1lfSdcbnZhciByZXNlcnZlZENsaWVudFRhZ3MgPSBbXG4gICdhcGlzJyxcbiAgJ2F1dGhvcml6YXRpb25TY2hlbWUnLFxuICAnYXV0aG9yaXphdGlvbnMnLFxuICAnYmFzZVBhdGgnLFxuICAnYnVpbGQnLFxuICAnYnVpbGRGcm9tMV8xU3BlYycsXG4gICdidWlsZEZyb20xXzJTcGVjJyxcbiAgJ2J1aWxkRnJvbVNwZWMnLFxuICAnY2xpZW50QXV0aG9yaXphdGlvbnMnLFxuICAnY29udmVydEluZm8nLFxuICAnZGVidWcnLFxuICAnZGVmYXVsdEVycm9yQ2FsbGJhY2snLFxuICAnZGVmYXVsdFN1Y2Nlc3NDYWxsYmFjaycsXG4gICdmYWlsJyxcbiAgJ2ZhaWx1cmUnLFxuICAnZmluaXNoJyxcbiAgJ2hlbHAnLFxuICAnaWRGcm9tT3AnLFxuICAnaW5mbycsXG4gICdpbml0aWFsaXplJyxcbiAgJ2lzQnVpbHQnLFxuICAnaXNWYWxpZCcsXG4gICdtb2RlbFByb3BlcnR5TWFjcm8nLFxuICAnbW9kZWxzJyxcbiAgJ21vZGVsc0FycmF5JyxcbiAgJ29wdGlvbnMnLFxuICAncGFyYW1ldGVyTWFjcm8nLFxuICAncGFyc2VVcmknLFxuICAncHJvZ3Jlc3MnLFxuICAncmVzb3VyY2VDb3VudCcsXG4gICdzYW1wbGVNb2RlbHMnLFxuICAnc2VsZlJlZmxlY3QnLFxuICAnc2V0Q29uc29saWRhdGVkTW9kZWxzJyxcbiAgJ3NwZWMnLFxuICAnc3VwcG9ydGVkU3VibWl0TWV0aG9kcycsXG4gICdzd2FnZ2VyUmVxdWVzdEhlYWRlcnMnLFxuICAndGFnRnJvbUxhYmVsJyxcbiAgJ3VybCcsXG4gICd1c2VKUXVlcnknXG5dO1xuLy8gV2UgaGF2ZSB0byBrZWVwIHRyYWNrIG9mIHRoZSBmdW5jdGlvbi9wcm9wZXJ0eSBuYW1lcyB0byBhdm9pZCBjb2xsaXNpb25zIGZvciB0YWcgbmFtZXMgd2hpY2ggYXJlIHVzZWQgdG8gYWxsb3cgdGhlXG4vLyBmb2xsb3dpbmcgdXNhZ2U6ICdjbGllbnQuYXBpcy57dGFnTmFtZX0nXG52YXIgcmVzZXJ2ZWRBcGlUYWdzID0gW1xuICAnYXBpcycsXG4gICdhc0N1cmwnLFxuICAnZGVzY3JpcHRpb24nLFxuICAnZXh0ZXJuYWxEb2NzJyxcbiAgJ2hlbHAnLFxuICAnbGFiZWwnLFxuICAnbmFtZScsXG4gICdvcGVyYXRpb24nLFxuICAnb3BlcmF0aW9ucycsXG4gICdvcGVyYXRpb25zQXJyYXknLFxuICAncGF0aCcsXG4gICd0YWcnXG5dO1xudmFyIHN1cHBvcnRlZE9wZXJhdGlvbk1ldGhvZHMgPSBbJ2RlbGV0ZScsICdnZXQnLCAnaGVhZCcsICdvcHRpb25zJywgJ3BhdGNoJywgJ3Bvc3QnLCAncHV0J107XG52YXIgU3dhZ2dlckNsaWVudCA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHVybCwgb3B0aW9ucykge1xuICB0aGlzLmF1dGhvcml6YXRpb25zID0gbnVsbDtcbiAgdGhpcy5hdXRob3JpemF0aW9uU2NoZW1lID0gbnVsbDtcbiAgdGhpcy5iYXNlUGF0aCA9IG51bGw7XG4gIHRoaXMuZGVidWcgPSBmYWxzZTtcbiAgdGhpcy5pbmZvID0gbnVsbDtcbiAgdGhpcy5pc0J1aWx0ID0gZmFsc2U7XG4gIHRoaXMuaXNWYWxpZCA9IGZhbHNlO1xuICB0aGlzLm1vZGVsc0FycmF5ID0gW107XG4gIHRoaXMucmVzb3VyY2VDb3VudCA9IDA7XG4gIHRoaXMudXJsID0gbnVsbDtcbiAgdGhpcy51c2VKUXVlcnkgPSBmYWxzZTtcblxuICB0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zID0gbmV3IGF1dGguU3dhZ2dlckF1dGhvcml6YXRpb25zKCk7XG5cbiAgaWYgKHR5cGVvZiB1cmwgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgcmV0dXJuIHRoaXMuaW5pdGlhbGl6ZSh1cmwsIG9wdGlvbnMpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB0aGlzO1xuICB9XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5pbml0aWFsaXplID0gZnVuY3Rpb24gKHVybCwgb3B0aW9ucykge1xuICB0aGlzLm1vZGVscyA9IHt9O1xuICB0aGlzLnNhbXBsZU1vZGVscyA9IHt9O1xuXG4gIGlmICh0eXBlb2YgdXJsID09PSAnc3RyaW5nJykge1xuICAgIHRoaXMudXJsID0gdXJsO1xuICB9IGVsc2UgaWYgKHR5cGVvZiB1cmwgPT09ICdvYmplY3QnKSB7XG4gICAgb3B0aW9ucyA9IHVybDtcbiAgICB0aGlzLnVybCA9IG9wdGlvbnMudXJsO1xuICB9XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHRoaXMuY2xpZW50QXV0aG9yaXphdGlvbnMuYWRkKG9wdGlvbnMuYXV0aG9yaXphdGlvbnMpO1xuICB0aGlzLnN3YWdnZXJSZXF1ZXN0SGVhZGVycyA9IG9wdGlvbnMuc3dhZ2dlclJlcXVlc3RIZWFkZXJzIHx8ICdhcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTgsKi8qJztcbiAgdGhpcy5kZWZhdWx0U3VjY2Vzc0NhbGxiYWNrID0gb3B0aW9ucy5kZWZhdWx0U3VjY2Vzc0NhbGxiYWNrIHx8IG51bGw7XG4gIHRoaXMuZGVmYXVsdEVycm9yQ2FsbGJhY2sgPSBvcHRpb25zLmRlZmF1bHRFcnJvckNhbGxiYWNrIHx8IG51bGw7XG4gIHRoaXMubW9kZWxQcm9wZXJ0eU1hY3JvID0gb3B0aW9ucy5tb2RlbFByb3BlcnR5TWFjcm8gfHwgbnVsbDtcbiAgdGhpcy5wYXJhbWV0ZXJNYWNybyA9IG9wdGlvbnMubW9kZWxQcm9wZXJ0eU1hY3JvIHx8IG51bGw7XG5cbiAgaWYgKHR5cGVvZiBvcHRpb25zLnN1Y2Nlc3MgPT09ICdmdW5jdGlvbicpIHtcbiAgICB0aGlzLnN1Y2Nlc3MgPSBvcHRpb25zLnN1Y2Nlc3M7XG4gIH1cblxuICBpZiAob3B0aW9ucy51c2VKUXVlcnkpIHtcbiAgICB0aGlzLnVzZUpRdWVyeSA9IG9wdGlvbnMudXNlSlF1ZXJ5O1xuICB9XG5cbiAgdGhpcy5vcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB0aGlzLnN1cHBvcnRlZFN1Ym1pdE1ldGhvZHMgPSBvcHRpb25zLnN1cHBvcnRlZFN1Ym1pdE1ldGhvZHMgfHwgW107XG4gIHRoaXMuZmFpbHVyZSA9IG9wdGlvbnMuZmFpbHVyZSB8fCBmdW5jdGlvbiAoKSB7fTtcbiAgdGhpcy5wcm9ncmVzcyA9IG9wdGlvbnMucHJvZ3Jlc3MgfHwgZnVuY3Rpb24gKCkge307XG4gIHRoaXMuc3BlYyA9IF8uY2xvbmVEZWVwKG9wdGlvbnMuc3BlYyk7IC8vIENsb25lIHNvIHdlIGRvIG5vdCBhbHRlciB0aGUgcHJvdmlkZWQgZG9jdW1lbnRcblxuICBpZiAodHlwZW9mIG9wdGlvbnMuc3VjY2VzcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHRoaXMucmVhZHkgPSB0cnVlO1xuICAgIHRoaXMuYnVpbGQoKTtcbiAgfVxufTtcblxuU3dhZ2dlckNsaWVudC5wcm90b3R5cGUuYnVpbGQgPSBmdW5jdGlvbiAobW9jaykge1xuICBpZiAodGhpcy5pc0J1aWx0KSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy5wcm9ncmVzcygnZmV0Y2hpbmcgcmVzb3VyY2UgbGlzdDogJyArIHRoaXMudXJsKTtcblxuICB2YXIgb2JqID0ge1xuICAgIHVzZUpRdWVyeTogdGhpcy51c2VKUXVlcnksXG4gICAgdXJsOiB0aGlzLnVybCxcbiAgICBtZXRob2Q6ICdnZXQnLFxuICAgIGhlYWRlcnM6IHtcbiAgICAgIGFjY2VwdDogdGhpcy5zd2FnZ2VyUmVxdWVzdEhlYWRlcnNcbiAgICB9LFxuICAgIG9uOiB7XG4gICAgICBlcnJvcjogZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgIGlmIChzZWxmLnVybC5zdWJzdHJpbmcoMCwgNCkgIT09ICdodHRwJykge1xuICAgICAgICAgIHJldHVybiBzZWxmLmZhaWwoJ1BsZWFzZSBzcGVjaWZ5IHRoZSBwcm90b2NvbCBmb3IgJyArIHNlbGYudXJsKTtcbiAgICAgICAgfSBlbHNlIGlmIChyZXNwb25zZS5zdGF0dXMgPT09IDApIHtcbiAgICAgICAgICByZXR1cm4gc2VsZi5mYWlsKCdDYW5cXCd0IHJlYWQgZnJvbSBzZXJ2ZXIuICBJdCBtYXkgbm90IGhhdmUgdGhlIGFwcHJvcHJpYXRlIGFjY2Vzcy1jb250cm9sLW9yaWdpbiBzZXR0aW5ncy4nKTtcbiAgICAgICAgfSBlbHNlIGlmIChyZXNwb25zZS5zdGF0dXMgPT09IDQwNCkge1xuICAgICAgICAgIHJldHVybiBzZWxmLmZhaWwoJ0NhblxcJ3QgcmVhZCBzd2FnZ2VyIEpTT04gZnJvbSAnICsgc2VsZi51cmwpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBzZWxmLmZhaWwocmVzcG9uc2Uuc3RhdHVzICsgJyA6ICcgKyByZXNwb25zZS5zdGF0dXNUZXh0ICsgJyAnICsgc2VsZi51cmwpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgcmVzcG9uc2U6IGZ1bmN0aW9uIChyZXNwKSB7XG5cbiAgICAgICAgdmFyIHJlc3BvbnNlT2JqID0gcmVzcC5vYmo7XG4gICAgICAgIGlmKCFyZXNwb25zZU9iaikge1xuICAgICAgICAgIHJldHVybiBzZWxmLmZhaWwoJ2ZhaWxlZCB0byBwYXJzZSBKU09OL1lBTUwgcmVzcG9uc2UnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHNlbGYuc3dhZ2dlclZlcnNpb24gPSByZXNwb25zZU9iai5zd2FnZ2VyVmVyc2lvbjtcblxuICAgICAgICBpZiAocmVzcG9uc2VPYmouc3dhZ2dlciAmJiBwYXJzZUludChyZXNwb25zZU9iai5zd2FnZ2VyKSA9PT0gMikge1xuICAgICAgICAgIHNlbGYuc3dhZ2dlclZlcnNpb24gPSByZXNwb25zZU9iai5zd2FnZ2VyO1xuXG4gICAgICAgICAgbmV3IFJlc29sdmVyKCkucmVzb2x2ZShyZXNwb25zZU9iaiwgc2VsZi51cmwsIHNlbGYuYnVpbGRGcm9tU3BlYywgc2VsZik7XG5cbiAgICAgICAgICBzZWxmLmlzVmFsaWQgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciBjb252ZXJ0ZXIgPSBuZXcgU3dhZ2dlclNwZWNDb252ZXJ0ZXIoKTtcbiAgICAgICAgICBjb252ZXJ0ZXIuc2V0RG9jdW1lbnRhdGlvbkxvY2F0aW9uKHNlbGYudXJsKTtcbiAgICAgICAgICBjb252ZXJ0ZXIuY29udmVydChyZXNwb25zZU9iaiwgc2VsZi5jbGllbnRBdXRob3JpemF0aW9ucywgZnVuY3Rpb24oc3BlYykge1xuICAgICAgICAgICAgbmV3IFJlc29sdmVyKCkucmVzb2x2ZShzcGVjLCBzZWxmLnVybCwgc2VsZi5idWlsZEZyb21TcGVjLCBzZWxmKTtcbiAgICAgICAgICAgIHNlbGYuaXNWYWxpZCA9IHRydWU7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgaWYgKHRoaXMuc3BlYykge1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgbmV3IFJlc29sdmVyKCkucmVzb2x2ZShzZWxmLnNwZWMsIHNlbGYuYnVpbGRGcm9tU3BlYywgc2VsZik7XG4gICB9LCAxMCk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5jbGllbnRBdXRob3JpemF0aW9ucy5hcHBseShvYmopO1xuXG4gICAgaWYgKG1vY2spIHtcbiAgICAgIHJldHVybiBvYmo7XG4gICAgfVxuXG4gICAgbmV3IFN3YWdnZXJIdHRwKCkuZXhlY3V0ZShvYmosIHRoaXMub3B0aW9ucyk7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLmJ1aWxkRnJvbVNwZWMgPSBmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgaWYgKHRoaXMuaXNCdWlsdCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgdGhpcy5hcGlzID0ge307XG4gIHRoaXMuYXBpc0FycmF5ID0gW107XG4gIHRoaXMuYmFzZVBhdGggPSByZXNwb25zZS5iYXNlUGF0aCB8fCAnJztcbiAgdGhpcy5jb25zdW1lcyA9IHJlc3BvbnNlLmNvbnN1bWVzO1xuICB0aGlzLmhvc3QgPSByZXNwb25zZS5ob3N0IHx8ICcnO1xuICB0aGlzLmluZm8gPSByZXNwb25zZS5pbmZvIHx8IHt9O1xuICB0aGlzLnByb2R1Y2VzID0gcmVzcG9uc2UucHJvZHVjZXM7XG4gIHRoaXMuc2NoZW1lcyA9IHJlc3BvbnNlLnNjaGVtZXMgfHwgW107XG4gIHRoaXMuc2VjdXJpdHlEZWZpbml0aW9ucyA9IHJlc3BvbnNlLnNlY3VyaXR5RGVmaW5pdGlvbnM7XG4gIHRoaXMudGl0bGUgPSByZXNwb25zZS50aXRsZSB8fCAnJztcblxuICBpZiAocmVzcG9uc2UuZXh0ZXJuYWxEb2NzKSB7XG4gICAgdGhpcy5leHRlcm5hbERvY3MgPSByZXNwb25zZS5leHRlcm5hbERvY3M7XG4gIH1cblxuICAvLyBsZWdhY3kgc3VwcG9ydFxuICB0aGlzLmF1dGhTY2hlbWVzID0gcmVzcG9uc2Uuc2VjdXJpdHlEZWZpbml0aW9ucztcblxuICB2YXIgZGVmaW5lZFRhZ3MgPSB7fTtcbiAgdmFyIGs7XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkocmVzcG9uc2UudGFncykpIHtcbiAgICBkZWZpbmVkVGFncyA9IHt9O1xuXG4gICAgZm9yIChrID0gMDsgayA8IHJlc3BvbnNlLnRhZ3MubGVuZ3RoOyBrKyspIHtcbiAgICAgIHZhciB0ID0gcmVzcG9uc2UudGFnc1trXTtcbiAgICAgIGRlZmluZWRUYWdzW3QubmFtZV0gPSB0O1xuICAgIH1cbiAgfVxuXG4gIHZhciBsb2NhdGlvbjtcblxuICBpZiAodHlwZW9mIHRoaXMudXJsID09PSAnc3RyaW5nJykge1xuICAgIGxvY2F0aW9uID0gdGhpcy5wYXJzZVVyaSh0aGlzLnVybCk7XG4gICAgaWYgKHR5cGVvZiB0aGlzLnNjaGVtZXMgPT09ICd1bmRlZmluZWQnIHx8IHRoaXMuc2NoZW1lcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRoaXMuc2NoZW1lID0gbG9jYXRpb24uc2NoZW1lIHx8ICdodHRwJztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zY2hlbWUgPSB0aGlzLnNjaGVtZXNbMF07XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiB0aGlzLmhvc3QgPT09ICd1bmRlZmluZWQnIHx8IHRoaXMuaG9zdCA9PT0gJycpIHtcbiAgICAgIHRoaXMuaG9zdCA9IGxvY2F0aW9uLmhvc3Q7XG5cbiAgICAgIGlmIChsb2NhdGlvbi5wb3J0KSB7XG4gICAgICAgIHRoaXMuaG9zdCA9IHRoaXMuaG9zdCArICc6JyArIGxvY2F0aW9uLnBvcnQ7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGVsc2Uge1xuICAgIGlmICh0eXBlb2YgdGhpcy5zY2hlbWVzID09PSAndW5kZWZpbmVkJyB8fCB0aGlzLnNjaGVtZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLnNjaGVtZSA9ICdodHRwJztcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB0aGlzLnNjaGVtZSA9IHRoaXMuc2NoZW1lc1swXTtcbiAgICB9XG4gIH1cblxuICB0aGlzLmRlZmluaXRpb25zID0gcmVzcG9uc2UuZGVmaW5pdGlvbnM7XG5cbiAgdmFyIGtleTtcblxuICBmb3IgKGtleSBpbiB0aGlzLmRlZmluaXRpb25zKSB7XG4gICAgdmFyIG1vZGVsID0gbmV3IE1vZGVsKGtleSwgdGhpcy5kZWZpbml0aW9uc1trZXldLCB0aGlzLm1vZGVscywgdGhpcy5tb2RlbFByb3BlcnR5TWFjcm8pO1xuXG4gICAgaWYgKG1vZGVsKSB7XG4gICAgICB0aGlzLm1vZGVsc1trZXldID0gbW9kZWw7XG4gICAgfVxuICB9XG5cbiAgLy8gZ2V0IHBhdGhzLCBjcmVhdGUgZnVuY3Rpb25zIGZvciBlYWNoIG9wZXJhdGlvbklkXG4gIHZhciBzZWxmID0gdGhpcztcblxuICAvLyBCaW5kIGhlbHAgdG8gJ2NsaWVudC5hcGlzJ1xuICBzZWxmLmFwaXMuaGVscCA9IF8uYmluZChzZWxmLmhlbHAsIHNlbGYpO1xuXG4gIF8uZm9yRWFjaChyZXNwb25zZS5wYXRocywgZnVuY3Rpb24gKHBhdGhPYmosIHBhdGgpIHtcbiAgICAvLyBPbmx5IHByb2Nlc3MgYSBwYXRoIGlmIGl0J3MgYW4gb2JqZWN0XG4gICAgaWYgKCFfLmlzUGxhaW5PYmplY3QocGF0aE9iaikpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBfLmZvckVhY2goc3VwcG9ydGVkT3BlcmF0aW9uTWV0aG9kcywgZnVuY3Rpb24gKG1ldGhvZCkge1xuICAgICAgdmFyIG9wZXJhdGlvbiA9IHBhdGhPYmpbbWV0aG9kXTtcblxuICAgICAgaWYgKF8uaXNVbmRlZmluZWQob3BlcmF0aW9uKSkge1xuICAgICAgICAvLyBPcGVyYXRpb24gZG9lcyBub3QgZXhpc3RcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBlbHNlIGlmICghXy5pc1BsYWluT2JqZWN0KG9wZXJhdGlvbikpIHtcbiAgICAgICAgLy8gT3BlcmF0aW9uIGV4aXN0cyBidXQgaXQgaXMgbm90IGFuIE9wZXJhdGlvbiBPYmplY3QuICBTaW5jZSB0aGlzIGlzIGludmFsaWQsIGxvZyBpdC5cbiAgICAgICAgaGVscGVycy5sb2coJ1RoZSBcXCcnICsgbWV0aG9kICsgJ1xcJyBvcGVyYXRpb24gZm9yIFxcJycgKyBwYXRoICsgJ1xcJyBwYXRoIGlzIG5vdCBhbiBPcGVyYXRpb24gT2JqZWN0Jyk7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgdGFncyA9IG9wZXJhdGlvbi50YWdzO1xuXG4gICAgICBpZiAoXy5pc1VuZGVmaW5lZCh0YWdzKSB8fCAhXy5pc0FycmF5KHRhZ3MpIHx8IHRhZ3MubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRhZ3MgPSBvcGVyYXRpb24udGFncyA9IFsgJ2RlZmF1bHQnIF07XG4gICAgICB9XG5cbiAgICAgIHZhciBvcGVyYXRpb25JZCA9IHNlbGYuaWRGcm9tT3AocGF0aCwgbWV0aG9kLCBvcGVyYXRpb24pO1xuICAgICAgdmFyIG9wZXJhdGlvbk9iamVjdCA9IG5ldyBPcGVyYXRpb24oc2VsZixcbiAgICAgICAgb3BlcmF0aW9uLnNjaGVtZSxcbiAgICAgICAgb3BlcmF0aW9uSWQsXG4gICAgICAgIG1ldGhvZCxcbiAgICAgICAgcGF0aCxcbiAgICAgICAgb3BlcmF0aW9uLFxuICAgICAgICBzZWxmLmRlZmluaXRpb25zLFxuICAgICAgICBzZWxmLm1vZGVscyxcbiAgICAgICAgc2VsZi5jbGllbnRBdXRob3JpemF0aW9ucyk7XG5cbiAgICAgIC8vIGJpbmQgc2VsZiBvcGVyYXRpb24ncyBleGVjdXRlIGNvbW1hbmQgdG8gdGhlIGFwaVxuICAgICAgXy5mb3JFYWNoKHRhZ3MsIGZ1bmN0aW9uICh0YWcpIHtcbiAgICAgICAgdmFyIGNsaWVudFByb3BlcnR5ID0gXy5pbmRleE9mKHJlc2VydmVkQ2xpZW50VGFncywgdGFnKSA+IC0xID8gJ18nICsgdGFnIDogdGFnO1xuICAgICAgICB2YXIgYXBpUHJvcGVydHkgPSBfLmluZGV4T2YocmVzZXJ2ZWRBcGlUYWdzLCB0YWcpID4gLTEgPyAnXycgKyB0YWcgOiB0YWc7XG4gICAgICAgIHZhciBvcGVyYXRpb25Hcm91cCA9IHNlbGZbY2xpZW50UHJvcGVydHldO1xuXG4gICAgICAgIGlmIChjbGllbnRQcm9wZXJ0eSAhPT0gdGFnKSB7XG4gICAgICAgICAgaGVscGVycy5sb2coJ1RoZSBcXCcnICsgdGFnICsgJ1xcJyB0YWcgY29uZmxpY3RzIHdpdGggYSBTd2FnZ2VyQ2xpZW50IGZ1bmN0aW9uL3Byb3BlcnR5IG5hbWUuICBVc2UgXFwnY2xpZW50LicgK1xuICAgICAgICAgICAgICAgICAgICAgIGNsaWVudFByb3BlcnR5ICsgJ1xcJyBvciBcXCdjbGllbnQuYXBpcy4nICsgdGFnICsgJ1xcJyBpbnN0ZWFkIG9mIFxcJ2NsaWVudC4nICsgdGFnICsgJ1xcJy4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChhcGlQcm9wZXJ0eSAhPT0gdGFnKSB7XG4gICAgICAgICAgaGVscGVycy5sb2coJ1RoZSBcXCcnICsgdGFnICsgJ1xcJyB0YWcgY29uZmxpY3RzIHdpdGggYSBTd2FnZ2VyQ2xpZW50IG9wZXJhdGlvbiBmdW5jdGlvbi9wcm9wZXJ0eSBuYW1lLiAgVXNlICcgK1xuICAgICAgICAgICAgICAgICAgICAgICdcXCdjbGllbnQuYXBpcy4nICsgYXBpUHJvcGVydHkgKyAnXFwnIGluc3RlYWQgb2YgXFwnY2xpZW50LmFwaXMuJyArIHRhZyArICdcXCcuJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoXy5pbmRleE9mKHJlc2VydmVkQXBpVGFncywgb3BlcmF0aW9uSWQpID4gLTEpIHtcbiAgICAgICAgICBoZWxwZXJzLmxvZygnVGhlIFxcJycgKyBvcGVyYXRpb25JZCArICdcXCcgb3BlcmF0aW9uSWQgY29uZmxpY3RzIHdpdGggYSBTd2FnZ2VyQ2xpZW50IG9wZXJhdGlvbiAnICtcbiAgICAgICAgICAgICAgICAgICAgICAnZnVuY3Rpb24vcHJvcGVydHkgbmFtZS4gIFVzZSBcXCdjbGllbnQuYXBpcy4nICsgYXBpUHJvcGVydHkgKyAnLl8nICsgb3BlcmF0aW9uSWQgK1xuICAgICAgICAgICAgICAgICAgICAgICdcXCcgaW5zdGVhZCBvZiBcXCdjbGllbnQuYXBpcy4nICsgYXBpUHJvcGVydHkgKyAnLicgKyBvcGVyYXRpb25JZCArICdcXCcuJyk7XG5cbiAgICAgICAgICBvcGVyYXRpb25JZCA9ICdfJyArIG9wZXJhdGlvbklkO1xuICAgICAgICAgIG9wZXJhdGlvbk9iamVjdC5uaWNrbmFtZSA9IG9wZXJhdGlvbklkOyAvLyBTbyAnY2xpZW50LmFwaXMuW3RhZ10ub3BlcmF0aW9uSWQuaGVscCgpIHdvcmtzIHByb3Blcmx5XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoXy5pc1VuZGVmaW5lZChvcGVyYXRpb25Hcm91cCkpIHtcbiAgICAgICAgICBvcGVyYXRpb25Hcm91cCA9IHNlbGZbY2xpZW50UHJvcGVydHldID0gc2VsZi5hcGlzW2FwaVByb3BlcnR5XSA9IHt9O1xuXG4gICAgICAgICAgb3BlcmF0aW9uR3JvdXAub3BlcmF0aW9ucyA9IHt9O1xuICAgICAgICAgIG9wZXJhdGlvbkdyb3VwLmxhYmVsID0gYXBpUHJvcGVydHk7XG4gICAgICAgICAgb3BlcmF0aW9uR3JvdXAuYXBpcyA9IHt9O1xuXG4gICAgICAgICAgdmFyIHRhZ0RlZiA9IGRlZmluZWRUYWdzW3RhZ107XG5cbiAgICAgICAgICBpZiAoIV8uaXNVbmRlZmluZWQodGFnRGVmKSkge1xuICAgICAgICAgICAgb3BlcmF0aW9uR3JvdXAuZGVzY3JpcHRpb24gPSB0YWdEZWYuZGVzY3JpcHRpb247XG4gICAgICAgICAgICBvcGVyYXRpb25Hcm91cC5leHRlcm5hbERvY3MgPSB0YWdEZWYuZXh0ZXJuYWxEb2NzO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHNlbGZbY2xpZW50UHJvcGVydHldLmhlbHAgPSBfLmJpbmQoc2VsZi5oZWxwLCBvcGVyYXRpb25Hcm91cCk7XG4gICAgICAgICAgc2VsZi5hcGlzQXJyYXkucHVzaChuZXcgT3BlcmF0aW9uR3JvdXAodGFnLCBvcGVyYXRpb25Hcm91cC5kZXNjcmlwdGlvbiwgb3BlcmF0aW9uR3JvdXAuZXh0ZXJuYWxEb2NzLCBvcGVyYXRpb25PYmplY3QpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEJpbmQgdGFnIGhlbHBcbiAgICAgICAgaWYgKCFfLmlzRnVuY3Rpb24ob3BlcmF0aW9uR3JvdXAuaGVscCkpIHtcbiAgICAgICAgICBvcGVyYXRpb25Hcm91cC5oZWxwID0gXy5iaW5kKHNlbGYuaGVscCwgb3BlcmF0aW9uR3JvdXApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gYmluZCB0byB0aGUgYXBpcyBvYmplY3RcbiAgICAgICAgc2VsZi5hcGlzW2FwaVByb3BlcnR5XVtvcGVyYXRpb25JZF0gPSBvcGVyYXRpb25Hcm91cFtvcGVyYXRpb25JZF0gPSBfLmJpbmQob3BlcmF0aW9uT2JqZWN0LmV4ZWN1dGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uT2JqZWN0KTtcbiAgICAgICAgc2VsZi5hcGlzW2FwaVByb3BlcnR5XVtvcGVyYXRpb25JZF0uaGVscCA9IG9wZXJhdGlvbkdyb3VwW29wZXJhdGlvbklkXS5oZWxwID0gXy5iaW5kKG9wZXJhdGlvbk9iamVjdC5oZWxwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uT2JqZWN0KTtcbiAgICAgICAgc2VsZi5hcGlzW2FwaVByb3BlcnR5XVtvcGVyYXRpb25JZF0uYXNDdXJsID0gb3BlcmF0aW9uR3JvdXBbb3BlcmF0aW9uSWRdLmFzQ3VybCA9IF8uYmluZChvcGVyYXRpb25PYmplY3QuYXNDdXJsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbk9iamVjdCk7XG5cbiAgICAgICAgb3BlcmF0aW9uR3JvdXAuYXBpc1tvcGVyYXRpb25JZF0gPSBvcGVyYXRpb25Hcm91cC5vcGVyYXRpb25zW29wZXJhdGlvbklkXSA9IG9wZXJhdGlvbk9iamVjdDtcblxuICAgICAgICAvLyBsZWdhY3kgVUkgZmVhdHVyZVxuICAgICAgICB2YXIgYXBpID0gXy5maW5kKHNlbGYuYXBpc0FycmF5LCBmdW5jdGlvbiAoYXBpKSB7XG4gICAgICAgICAgcmV0dXJuIGFwaS50YWcgPT09IHRhZztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKGFwaSkge1xuICAgICAgICAgIGFwaS5vcGVyYXRpb25zQXJyYXkucHVzaChvcGVyYXRpb25PYmplY3QpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgdGhpcy5pc0J1aWx0ID0gdHJ1ZTtcblxuICBpZiAodGhpcy5zdWNjZXNzKSB7XG4gICAgdGhpcy5pc1ZhbGlkID0gdHJ1ZTtcbiAgICB0aGlzLmlzQnVpbHQgPSB0cnVlO1xuICAgIHRoaXMuc3VjY2VzcygpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5wYXJzZVVyaSA9IGZ1bmN0aW9uICh1cmkpIHtcbiAgdmFyIHVybFBhcnNlUkUgPSAvXigoKChbXjpcXC8jXFw/XSs6KT8oPzooXFwvXFwvKSgoPzooKFteOkBcXC8jXFw/XSspKD86XFw6KFteOkBcXC8jXFw/XSspKT8pQCk/KChbXjpcXC8jXFw/XFxdXFxbXSt8XFxbW15cXC9cXF1AIz9dK1xcXSkoPzpcXDooWzAtOV0rKSk/KSk/KT8pPygoXFwvPyg/OlteXFwvXFw/I10rXFwvKykqKShbXlxcPyNdKikpKT8oXFw/W14jXSspPykoIy4qKT8vO1xuICB2YXIgcGFydHMgPSB1cmxQYXJzZVJFLmV4ZWModXJpKTtcblxuICByZXR1cm4ge1xuICAgIHNjaGVtZTogcGFydHNbNF0ucmVwbGFjZSgnOicsJycpLFxuICAgIGhvc3Q6IHBhcnRzWzExXSxcbiAgICBwb3J0OiBwYXJ0c1sxMl0sXG4gICAgcGF0aDogcGFydHNbMTVdXG4gIH07XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5oZWxwID0gZnVuY3Rpb24gKGRvbnRQcmludCkge1xuICB2YXIgb3V0cHV0ID0gJyc7XG5cbiAgaWYgKHRoaXMgaW5zdGFuY2VvZiBTd2FnZ2VyQ2xpZW50KSB7XG4gICAgXy5mb3JFYWNoKHRoaXMuYXBpcywgZnVuY3Rpb24gKGFwaSwgbmFtZSkge1xuICAgICAgaWYgKF8uaXNQbGFpbk9iamVjdChhcGkpKSB7XG4gICAgICAgIG91dHB1dCArPSAnb3BlcmF0aW9ucyBmb3IgdGhlIFxcJycgKyBuYW1lICsgJ1xcJyB0YWdcXG4nO1xuXG4gICAgICAgIF8uZm9yRWFjaChhcGkub3BlcmF0aW9ucywgZnVuY3Rpb24gKG9wZXJhdGlvbiwgbmFtZSkge1xuICAgICAgICAgIG91dHB1dCArPSAnICAqICcgKyBuYW1lICsgJzogJyArIG9wZXJhdGlvbi5zdW1tYXJ5ICsgJ1xcbic7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9IGVsc2UgaWYgKHRoaXMgaW5zdGFuY2VvZiBPcGVyYXRpb25Hcm91cCB8fCBfLmlzUGxhaW5PYmplY3QodGhpcykpIHtcbiAgICBvdXRwdXQgKz0gJ29wZXJhdGlvbnMgZm9yIHRoZSBcXCcnICsgdGhpcy5sYWJlbCArICdcXCcgdGFnXFxuJztcblxuICAgIF8uZm9yRWFjaCh0aGlzLmFwaXMsIGZ1bmN0aW9uIChvcGVyYXRpb24sIG5hbWUpIHtcbiAgICAgIG91dHB1dCArPSAnICAqICcgKyBuYW1lICsgJzogJyArIG9wZXJhdGlvbi5zdW1tYXJ5ICsgJ1xcbic7XG4gICAgfSk7XG4gIH1cblxuICBpZiAoZG9udFByaW50KSB7XG4gICAgcmV0dXJuIG91dHB1dDtcbiAgfSBlbHNlIHtcbiAgICBoZWxwZXJzLmxvZyhvdXRwdXQpO1xuXG4gICAgcmV0dXJuIG91dHB1dDtcbiAgfVxufTtcblxuU3dhZ2dlckNsaWVudC5wcm90b3R5cGUudGFnRnJvbUxhYmVsID0gZnVuY3Rpb24gKGxhYmVsKSB7XG4gIHJldHVybiBsYWJlbDtcbn07XG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLmlkRnJvbU9wID0gZnVuY3Rpb24gKHBhdGgsIGh0dHBNZXRob2QsIG9wKSB7XG4gIGlmKCFvcCB8fCAhb3Aub3BlcmF0aW9uSWQpIHtcbiAgICBvcCA9IG9wIHx8IHt9O1xuICAgIG9wLm9wZXJhdGlvbklkID0gaHR0cE1ldGhvZCArICdfJyArIHBhdGg7XG4gIH1cbiAgdmFyIG9wSWQgPSBvcC5vcGVyYXRpb25JZC5yZXBsYWNlKC9bXFxzIUAjJCVeJiooKV8rPVxcW3tcXF19Ozo8PnwuXFwvPyxcXFxcJ1wiXCItXS9nLCAnXycpIHx8IChwYXRoLnN1YnN0cmluZygxKSArICdfJyArIGh0dHBNZXRob2QpO1xuXG4gIG9wSWQgPSBvcElkLnJlcGxhY2UoLygoXyl7Mix9KS9nLCAnXycpO1xuICBvcElkID0gb3BJZC5yZXBsYWNlKC9eKF8pKi9nLCAnJyk7XG4gIG9wSWQgPSBvcElkLnJlcGxhY2UoLyhbX10pKiQvZywgJycpO1xuICByZXR1cm4gb3BJZDtcbn07XG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLmZhaWwgPSBmdW5jdGlvbiAobWVzc2FnZSkge1xuICB0aGlzLmZhaWx1cmUobWVzc2FnZSk7XG5cbiAgdGhyb3cgbWVzc2FnZTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBfID0ge1xuICBpc1BsYWluT2JqZWN0OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNQbGFpbk9iamVjdCcpXG59O1xuXG5tb2R1bGUuZXhwb3J0cy5fX2JpbmQgPSBmdW5jdGlvbiAoZm4sIG1lKSB7XG4gIHJldHVybiBmdW5jdGlvbigpe1xuICAgIHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTtcbiAgfTtcbn07XG5cbnZhciBsb2cgPSBtb2R1bGUuZXhwb3J0cy5sb2cgPSBmdW5jdGlvbigpIHtcbiAgLy8gT25seSBsb2cgaWYgYXZhaWxhYmxlIGFuZCB3ZSdyZSBub3QgdGVzdGluZ1xuICBpZiAoY29uc29sZSAmJiBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Rlc3QnKSB7XG4gICAgY29uc29sZS5sb2coQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKVswXSk7XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzLmZhaWwgPSBmdW5jdGlvbiAobWVzc2FnZSkge1xuICBsb2cobWVzc2FnZSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5vcHRpb25IdG1sID0gZnVuY3Rpb24gKGxhYmVsLCB2YWx1ZSkge1xuICByZXR1cm4gJzx0cj48dGQgY2xhc3M9XCJvcHRpb25OYW1lXCI+JyArIGxhYmVsICsgJzo8L3RkPjx0ZD4nICsgdmFsdWUgKyAnPC90ZD48L3RyPic7XG59O1xuXG52YXIgcmVzb2x2ZVNjaGVtYSA9IG1vZHVsZS5leHBvcnRzLnJlc29sdmVTY2hlbWEgPSBmdW5jdGlvbiAoc2NoZW1hKSB7XG4gIGlmIChfLmlzUGxhaW5PYmplY3Qoc2NoZW1hLnNjaGVtYSkpIHtcbiAgICBzY2hlbWEgPSByZXNvbHZlU2NoZW1hKHNjaGVtYS5zY2hlbWEpO1xuICB9XG5cbiAgcmV0dXJuIHNjaGVtYTtcbn07XG5cbm1vZHVsZS5leHBvcnRzLnR5cGVGcm9tSnNvblNjaGVtYSA9IGZ1bmN0aW9uICh0eXBlLCBmb3JtYXQpIHtcbiAgdmFyIHN0cjtcblxuICBpZiAodHlwZSA9PT0gJ2ludGVnZXInICYmIGZvcm1hdCA9PT0gJ2ludDMyJykge1xuICAgIHN0ciA9ICdpbnRlZ2VyJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnaW50ZWdlcicgJiYgZm9ybWF0ID09PSAnaW50NjQnKSB7XG4gICAgc3RyID0gJ2xvbmcnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdpbnRlZ2VyJyAmJiB0eXBlb2YgZm9ybWF0ID09PSAndW5kZWZpbmVkJykge1xuICAgIHN0ciA9ICdsb25nJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnc3RyaW5nJyAmJiBmb3JtYXQgPT09ICdkYXRlLXRpbWUnKSB7XG4gICAgc3RyID0gJ2RhdGUtdGltZSc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3N0cmluZycgJiYgZm9ybWF0ID09PSAnZGF0ZScpIHtcbiAgICBzdHIgPSAnZGF0ZSc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ251bWJlcicgJiYgZm9ybWF0ID09PSAnZmxvYXQnKSB7XG4gICAgc3RyID0gJ2Zsb2F0JztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJyAmJiBmb3JtYXQgPT09ICdkb3VibGUnKSB7XG4gICAgc3RyID0gJ2RvdWJsZSc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ251bWJlcicgJiYgdHlwZW9mIGZvcm1hdCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBzdHIgPSAnZG91YmxlJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnYm9vbGVhbicpIHtcbiAgICBzdHIgPSAnYm9vbGVhbic7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICBzdHIgPSAnc3RyaW5nJztcbiAgfVxuXG4gIHJldHVybiBzdHI7XG59O1xuXG52YXIgc2ltcGxlUmVmID0gbW9kdWxlLmV4cG9ydHMuc2ltcGxlUmVmID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgaWYgKHR5cGVvZiBuYW1lID09PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKG5hbWUuaW5kZXhPZignIy9kZWZpbml0aW9ucy8nKSA9PT0gMCkge1xuICAgIHJldHVybiBuYW1lLnN1YnN0cmluZygnIy9kZWZpbml0aW9ucy8nLmxlbmd0aCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG5hbWU7XG4gIH1cbn07XG5cbnZhciBnZXRTdHJpbmdTaWduYXR1cmUgPSBtb2R1bGUuZXhwb3J0cy5nZXRTdHJpbmdTaWduYXR1cmUgPSBmdW5jdGlvbiAob2JqLCBiYXNlQ29tcG9uZW50KSB7XG4gIHZhciBzdHIgPSAnJztcblxuICBpZiAodHlwZW9mIG9iai4kcmVmICE9PSAndW5kZWZpbmVkJykge1xuICAgIHN0ciArPSBzaW1wbGVSZWYob2JqLiRyZWYpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBvYmoudHlwZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBzdHIgKz0gJ29iamVjdCc7XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdhcnJheScpIHtcbiAgICBpZiAoYmFzZUNvbXBvbmVudCkge1xuICAgICAgc3RyICs9IGdldFN0cmluZ1NpZ25hdHVyZSgob2JqLml0ZW1zIHx8IG9iai4kcmVmIHx8IHt9KSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ciArPSAnQXJyYXlbJztcbiAgICAgIHN0ciArPSBnZXRTdHJpbmdTaWduYXR1cmUoKG9iai5pdGVtcyB8fCBvYmouJHJlZiB8fCB7fSkpO1xuICAgICAgc3RyICs9ICddJztcbiAgICB9XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdpbnRlZ2VyJyAmJiBvYmouZm9ybWF0ID09PSAnaW50MzInKSB7XG4gICAgc3RyICs9ICdpbnRlZ2VyJztcbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ2ludGVnZXInICYmIG9iai5mb3JtYXQgPT09ICdpbnQ2NCcpIHtcbiAgICBzdHIgKz0gJ2xvbmcnO1xuICB9IGVsc2UgaWYgKG9iai50eXBlID09PSAnaW50ZWdlcicgJiYgdHlwZW9mIG9iai5mb3JtYXQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgc3RyICs9ICdsb25nJztcbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ3N0cmluZycgJiYgb2JqLmZvcm1hdCA9PT0gJ2RhdGUtdGltZScpIHtcbiAgICBzdHIgKz0gJ2RhdGUtdGltZSc7XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdzdHJpbmcnICYmIG9iai5mb3JtYXQgPT09ICdkYXRlJykge1xuICAgIHN0ciArPSAnZGF0ZSc7XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdzdHJpbmcnICYmIHR5cGVvZiBvYmouZm9ybWF0ID09PSAndW5kZWZpbmVkJykge1xuICAgIHN0ciArPSAnc3RyaW5nJztcbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ251bWJlcicgJiYgb2JqLmZvcm1hdCA9PT0gJ2Zsb2F0Jykge1xuICAgIHN0ciArPSAnZmxvYXQnO1xuICB9IGVsc2UgaWYgKG9iai50eXBlID09PSAnbnVtYmVyJyAmJiBvYmouZm9ybWF0ID09PSAnZG91YmxlJykge1xuICAgIHN0ciArPSAnZG91YmxlJztcbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ251bWJlcicgJiYgdHlwZW9mIG9iai5mb3JtYXQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgc3RyICs9ICdkb3VibGUnO1xuICB9IGVsc2UgaWYgKG9iai50eXBlID09PSAnYm9vbGVhbicpIHtcbiAgICBzdHIgKz0gJ2Jvb2xlYW4nO1xuICB9IGVsc2UgaWYgKG9iai4kcmVmKSB7XG4gICAgc3RyICs9IHNpbXBsZVJlZihvYmouJHJlZik7XG4gIH0gZWxzZSB7XG4gICAgc3RyICs9IG9iai50eXBlO1xuICB9XG5cbiAgcmV0dXJuIHN0cjtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBoZWxwZXJzID0gcmVxdWlyZSgnLi9oZWxwZXJzJyk7XG52YXIgalF1ZXJ5ID0gcmVxdWlyZSgnanF1ZXJ5Jyk7XG52YXIgcmVxdWVzdCA9IHJlcXVpcmUoJ3N1cGVyYWdlbnQnKTtcbnZhciBqc3lhbWwgPSByZXF1aXJlKCdqcy15YW1sJyk7XG5cbi8qXG4gKiBKUXVlcnlIdHRwQ2xpZW50IGlzIGEgbGlnaHQtd2VpZ2h0LCBub2RlIG9yIGJyb3dzZXIgSFRUUCBjbGllbnRcbiAqL1xudmFyIEpRdWVyeUh0dHBDbGllbnQgPSBmdW5jdGlvbiAoKSB7fTtcblxuLypcbiAqIFN1cGVyYWdlbnRIdHRwQ2xpZW50IGlzIGEgbGlnaHQtd2VpZ2h0LCBub2RlIG9yIGJyb3dzZXIgSFRUUCBjbGllbnRcbiAqL1xudmFyIFN1cGVyYWdlbnRIdHRwQ2xpZW50ID0gZnVuY3Rpb24gKCkge307XG5cbi8qKlxuICogU3dhZ2dlckh0dHAgaXMgYSB3cmFwcGVyIGZvciBleGVjdXRpbmcgcmVxdWVzdHNcbiAqL1xudmFyIFN3YWdnZXJIdHRwID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7fTtcblxuU3dhZ2dlckh0dHAucHJvdG90eXBlLmV4ZWN1dGUgPSBmdW5jdGlvbiAob2JqLCBvcHRzKSB7XG4gIHZhciBjbGllbnQ7XG5cbiAgaWYob3B0cyAmJiBvcHRzLmNsaWVudCkge1xuICAgIGNsaWVudCA9IG9wdHMuY2xpZW50O1xuICB9XG4gIGVsc2Uge1xuICAgIGNsaWVudCA9IG5ldyBTdXBlcmFnZW50SHR0cENsaWVudChvcHRzKTtcbiAgfVxuXG4gIC8vIGxlZ2FjeSBzdXBwb3J0XG4gIGlmICgob2JqICYmIG9iai51c2VKUXVlcnkgPT09IHRydWUpIHx8IHRoaXMuaXNJbnRlcm5ldEV4cGxvcmVyKCkpIHtcbiAgICBjbGllbnQgPSBuZXcgSlF1ZXJ5SHR0cENsaWVudChvcHRzKTtcbiAgfVxuXG4gIHZhciBzdWNjZXNzID0gb2JqLm9uLnJlc3BvbnNlO1xuXG4gIHZhciByZXNwb25zZUludGVyY2VwdG9yID0gZnVuY3Rpb24oZGF0YSkge1xuICAgIGlmKG9wdHMgJiYgb3B0cy5yZXNwb25zZUludGVyY2VwdG9yKSB7XG4gICAgICBkYXRhID0gb3B0cy5yZXNwb25zZUludGVyY2VwdG9yLmFwcGx5KGRhdGEpO1xuICAgIH1cbiAgICBzdWNjZXNzKGRhdGEpO1xuICB9O1xuXG4gIG9iai5vbi5yZXNwb25zZSA9IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICByZXNwb25zZUludGVyY2VwdG9yKGRhdGEpO1xuICB9O1xuXG5cbiAgaWYgKG9iaiAmJiB0eXBlb2Ygb2JqLmJvZHkgPT09ICdvYmplY3QnKSB7XG4gICAgLy8gc3BlY2lhbCBwcm9jZXNzaW5nIGZvciBmaWxlIHVwbG9hZHMgdmlhIGpxdWVyeVxuICAgIGlmIChvYmouYm9keS50eXBlICYmIG9iai5ib2R5LnR5cGUgPT09ICdmb3JtRGF0YScpe1xuICAgICAgb2JqLmNvbnRlbnRUeXBlID0gZmFsc2U7XG4gICAgICBvYmoucHJvY2Vzc0RhdGEgPSBmYWxzZTtcblxuICAgICAgZGVsZXRlIG9iai5oZWFkZXJzWydDb250ZW50LVR5cGUnXTtcbiAgICB9IGVsc2Uge1xuICAgICAgb2JqLmJvZHkgPSBKU09OLnN0cmluZ2lmeShvYmouYm9keSk7XG4gICAgfVxuICB9XG4gIGNsaWVudC5leGVjdXRlKG9iaik7XG59O1xuXG5Td2FnZ2VySHR0cC5wcm90b3R5cGUuaXNJbnRlcm5ldEV4cGxvcmVyID0gZnVuY3Rpb24gKCkge1xuICB2YXIgZGV0ZWN0ZWRJRSA9IGZhbHNlO1xuXG4gIGlmICh0eXBlb2YgbmF2aWdhdG9yICE9PSAndW5kZWZpbmVkJyAmJiBuYXZpZ2F0b3IudXNlckFnZW50KSB7XG4gICAgdmFyIG5hdiA9IG5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKTtcblxuICAgIGlmIChuYXYuaW5kZXhPZignbXNpZScpICE9PSAtMSkge1xuICAgICAgdmFyIHZlcnNpb24gPSBwYXJzZUludChuYXYuc3BsaXQoJ21zaWUnKVsxXSk7XG5cbiAgICAgIGlmICh2ZXJzaW9uIDw9IDgpIHtcbiAgICAgICAgZGV0ZWN0ZWRJRSA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGRldGVjdGVkSUU7XG59O1xuXG5KUXVlcnlIdHRwQ2xpZW50LnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24gKG9iaikge1xuICB2YXIgY2IgPSBvYmoub247XG4gIHZhciByZXF1ZXN0ID0gb2JqO1xuXG4gIG9iai50eXBlID0gb2JqLm1ldGhvZDtcbiAgb2JqLmNhY2hlID0gZmFsc2U7XG4gIGRlbGV0ZSBvYmoudXNlSlF1ZXJ5O1xuXG4gIC8qXG4gIG9iai5iZWZvcmVTZW5kID0gZnVuY3Rpb24gKHhocikge1xuICAgIHZhciBrZXksIHJlc3VsdHM7XG4gICAgaWYgKG9iai5oZWFkZXJzKSB7XG4gICAgICByZXN1bHRzID0gW107XG4gICAgICBmb3IgKGtleSBpbiBvYmouaGVhZGVycykge1xuICAgICAgICBpZiAoa2V5LnRvTG93ZXJDYXNlKCkgPT09ICdjb250ZW50LXR5cGUnKSB7XG4gICAgICAgICAgcmVzdWx0cy5wdXNoKG9iai5jb250ZW50VHlwZSA9IG9iai5oZWFkZXJzW2tleV0pO1xuICAgICAgICB9IGVsc2UgaWYgKGtleS50b0xvd2VyQ2FzZSgpID09PSAnYWNjZXB0Jykge1xuICAgICAgICAgIHJlc3VsdHMucHVzaChvYmouYWNjZXB0cyA9IG9iai5oZWFkZXJzW2tleV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc3VsdHMucHVzaCh4aHIuc2V0UmVxdWVzdEhlYWRlcihrZXksIG9iai5oZWFkZXJzW2tleV0pKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgfVxuICB9OyovXG5cbiAgb2JqLmRhdGEgPSBvYmouYm9keTtcblxuICBkZWxldGUgb2JqLmJvZHk7XG5cbiAgb2JqLmNvbXBsZXRlID0gZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgdmFyIGhlYWRlcnMgPSB7fTtcbiAgICB2YXIgaGVhZGVyQXJyYXkgPSByZXNwb25zZS5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKS5zcGxpdCgnXFxuJyk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGhlYWRlckFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgdG9TcGxpdCA9IGhlYWRlckFycmF5W2ldLnRyaW0oKTtcblxuICAgICAgaWYgKHRvU3BsaXQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICB2YXIgc2VwYXJhdG9yID0gdG9TcGxpdC5pbmRleE9mKCc6Jyk7XG5cbiAgICAgIGlmIChzZXBhcmF0b3IgPT09IC0xKSB7XG4gICAgICAgIC8vIE5hbWUgYnV0IG5vIHZhbHVlIGluIHRoZSBoZWFkZXJcbiAgICAgICAgaGVhZGVyc1t0b1NwbGl0XSA9IG51bGw7XG5cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHZhciBuYW1lID0gdG9TcGxpdC5zdWJzdHJpbmcoMCwgc2VwYXJhdG9yKS50cmltKCk7XG4gICAgICB2YXIgdmFsdWUgPSB0b1NwbGl0LnN1YnN0cmluZyhzZXBhcmF0b3IgKyAxKS50cmltKCk7XG5cbiAgICAgIGhlYWRlcnNbbmFtZV0gPSB2YWx1ZTtcbiAgICB9XG5cbiAgICB2YXIgb3V0ID0ge1xuICAgICAgdXJsOiByZXF1ZXN0LnVybCxcbiAgICAgIG1ldGhvZDogcmVxdWVzdC5tZXRob2QsXG4gICAgICBzdGF0dXM6IHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgIHN0YXR1c1RleHQ6IHJlc3BvbnNlLnN0YXR1c1RleHQsXG4gICAgICBkYXRhOiByZXNwb25zZS5yZXNwb25zZVRleHQsXG4gICAgICBoZWFkZXJzOiBoZWFkZXJzXG4gICAgfTtcblxuICAgIHRyeSB7XG4gICAgICB2YXIgcG9zc2libGVPYmogPSAgcmVzcG9uc2UucmVzcG9uc2VKU09OIHx8IGpzeWFtbC5zYWZlTG9hZChyZXNwb25zZS5yZXNwb25zZVRleHQpO1xuICAgICAgb3V0Lm9iaiA9ICh0eXBlb2YgcG9zc2libGVPYmogPT09ICdzdHJpbmcnKSA/IHt9IDogcG9zc2libGVPYmo7XG4gICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgIC8vIGRvIG5vdCBzZXQgb3V0Lm9ialxuICAgICAgaGVscGVycy5sb2coJ3VuYWJsZSB0byBwYXJzZSBKU09OL1lBTUwgY29udGVudCcpO1xuICAgIH1cblxuICAgIC8vIEkgY2FuIHRocm93LCBvciBwYXJzZSBudWxsP1xuICAgIG91dC5vYmogPSBvdXQub2JqIHx8IG51bGw7XG5cbiAgICBpZiAocmVzcG9uc2Uuc3RhdHVzID49IDIwMCAmJiByZXNwb25zZS5zdGF0dXMgPCAzMDApIHtcbiAgICAgIGNiLnJlc3BvbnNlKG91dCk7XG4gICAgfSBlbHNlIGlmIChyZXNwb25zZS5zdGF0dXMgPT09IDAgfHwgKHJlc3BvbnNlLnN0YXR1cyA+PSA0MDAgJiYgcmVzcG9uc2Uuc3RhdHVzIDwgNTk5KSkge1xuICAgICAgY2IuZXJyb3Iob3V0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGNiLnJlc3BvbnNlKG91dCk7XG4gICAgfVxuICB9O1xuXG4gIGpRdWVyeS5zdXBwb3J0LmNvcnMgPSB0cnVlO1xuXG4gIHJldHVybiBqUXVlcnkuYWpheChvYmopO1xufTtcblxuU3VwZXJhZ2VudEh0dHBDbGllbnQucHJvdG90eXBlLmV4ZWN1dGUgPSBmdW5jdGlvbiAob2JqKSB7XG4gIHZhciBtZXRob2QgPSBvYmoubWV0aG9kLnRvTG93ZXJDYXNlKCk7XG5cbiAgaWYgKG1ldGhvZCA9PT0gJ2RlbGV0ZScpIHtcbiAgICBtZXRob2QgPSAnZGVsJztcbiAgfVxuICB2YXIgaGVhZGVycyA9IG9iai5oZWFkZXJzIHx8IHt9O1xuICB2YXIgciA9IHJlcXVlc3RbbWV0aG9kXShvYmoudXJsKTtcbiAgdmFyIG5hbWU7XG4gIGZvciAobmFtZSBpbiBoZWFkZXJzKSB7XG4gICAgci5zZXQobmFtZSwgaGVhZGVyc1tuYW1lXSk7XG4gIH1cblxuICBpZiAob2JqLmJvZHkpIHtcbiAgICByLnNlbmQob2JqLmJvZHkpO1xuICB9XG5cbiAgaWYodHlwZW9mIHIuYnVmZmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgci5idWZmZXIoKTsgLy8gZm9yY2Ugc3VwZXJhZ2VudCB0byBwb3B1bGF0ZSByZXMudGV4dCB3aXRoIHRoZSByYXcgcmVzcG9uc2UgZGF0YVxuICB9XG5cbiAgci5lbmQoZnVuY3Rpb24gKGVyciwgcmVzKSB7XG4gICAgcmVzID0gcmVzIHx8IHtcbiAgICAgIHN0YXR1czogMCxcbiAgICAgIGhlYWRlcnM6IHtlcnJvcjogJ25vIHJlc3BvbnNlIGZyb20gc2VydmVyJ31cbiAgICB9O1xuICAgIHZhciByZXNwb25zZSA9IHtcbiAgICAgIHVybDogb2JqLnVybCxcbiAgICAgIG1ldGhvZDogb2JqLm1ldGhvZCxcbiAgICAgIGhlYWRlcnM6IHJlcy5oZWFkZXJzXG4gICAgfTtcbiAgICB2YXIgY2I7XG5cbiAgICBpZiAoIWVyciAmJiByZXMuZXJyb3IpIHtcbiAgICAgIGVyciA9IHJlcy5lcnJvcjtcbiAgICB9XG5cbiAgICBpZiAoZXJyICYmIG9iai5vbiAmJiBvYmoub24uZXJyb3IpIHtcbiAgICAgIHJlc3BvbnNlLm9iaiA9IGVycjtcbiAgICAgIHJlc3BvbnNlLnN0YXR1cyA9IHJlcyA/IHJlcy5zdGF0dXMgOiA1MDA7XG4gICAgICByZXNwb25zZS5zdGF0dXNUZXh0ID0gcmVzID8gcmVzLnRleHQgOiBlcnIubWVzc2FnZTtcbiAgICAgIGNiID0gb2JqLm9uLmVycm9yO1xuICAgIH0gZWxzZSBpZiAocmVzICYmIG9iai5vbiAmJiBvYmoub24ucmVzcG9uc2UpIHtcbiAgICAgIHZhciBwb3NzaWJsZU9iajtcblxuICAgICAgLy8gQWxyZWFkeSBwYXJzZWQgYnkgYnkgc3VwZXJhZ2VudD9cbiAgICAgIGlmKHJlcy5ib2R5ICYmIE9iamVjdC5rZXlzKHJlcy5ib2R5KS5sZW5ndGggPiAwKSB7XG4gICAgICAgIHBvc3NpYmxlT2JqID0gcmVzLmJvZHk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBwb3NzaWJsZU9iaiA9IGpzeWFtbC5zYWZlTG9hZChyZXMudGV4dCk7XG4gICAgICAgICAgICAvLyBjYW4gcGFyc2UgaW50byBhIHN0cmluZy4uLiB3aGljaCB3ZSBkb24ndCBuZWVkIHJ1bm5pbmcgYXJvdW5kIGluIHRoZSBzeXN0ZW1cbiAgICAgICAgICAgIHBvc3NpYmxlT2JqID0gKHR5cGVvZiBwb3NzaWJsZU9iaiA9PT0gJ3N0cmluZycpID8gbnVsbCA6IHBvc3NpYmxlT2JqO1xuICAgICAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICAgICAgaGVscGVycy5sb2coJ2Nhbm5vdCBwYXJzZSBKU09OL1lBTUwgY29udGVudCcpO1xuICAgICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gbnVsbCBtZWFucyB3ZSBjYW4ndCBwYXJzZSBpbnRvIG9iamVjdFxuICAgICAgcmVzcG9uc2Uub2JqID0gcG9zc2libGVPYmogfHwgbnVsbDtcblxuICAgICAgcmVzcG9uc2Uuc3RhdHVzID0gcmVzLnN0YXR1cztcbiAgICAgIHJlc3BvbnNlLnN0YXR1c1RleHQgPSByZXMudGV4dDtcbiAgICAgIGNiID0gb2JqLm9uLnJlc3BvbnNlO1xuICAgIH1cbiAgICByZXNwb25zZS5kYXRhID0gcmVzcG9uc2Uuc3RhdHVzVGV4dDtcblxuICAgIGlmIChjYikge1xuICAgICAgY2IocmVzcG9uc2UpO1xuICAgIH1cbiAgfSk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgU3dhZ2dlckh0dHAgPSByZXF1aXJlKCcuL2h0dHAnKTtcblxuLyoqIFxuICogUmVzb2x2ZXMgYSBzcGVjJ3MgcmVtb3RlIHJlZmVyZW5jZXNcbiAqL1xudmFyIFJlc29sdmVyID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7fTtcblxuUmVzb2x2ZXIucHJvdG90eXBlLnJlc29sdmUgPSBmdW5jdGlvbiAoc3BlYywgYXJnMSwgYXJnMiwgYXJnMykge1xuICB2YXIgcm9vdCA9IGFyZzEsIGNhbGxiYWNrID0gYXJnMiwgc2NvcGUgPSBhcmczLCBsb2NhdGlvbiwgaTtcbiAgaWYodHlwZW9mIGFyZzEgPT09ICdmdW5jdGlvbicpIHtcbiAgICByb290ID0gbnVsbDtcbiAgICBjYWxsYmFjayA9IGFyZzE7XG4gICAgc2NvcGUgPSBhcmcyO1xuICB9XG4gIHZhciBfcm9vdCA9IHJvb3Q7XG4gIHRoaXMuc2NvcGUgPSAoc2NvcGUgfHwgdGhpcyk7XG4gIHRoaXMuaXRlcmF0aW9uID0gdGhpcy5pdGVyYXRpb24gfHwgMDtcblxuICB2YXIgbmFtZSwgcGF0aCwgcHJvcGVydHksIHByb3BlcnR5TmFtZTtcbiAgdmFyIHByb2Nlc3NlZENhbGxzID0gMCwgcmVzb2x2ZWRSZWZzID0ge30sIHVucmVzb2x2ZWRSZWZzID0ge307XG4gIHZhciByZXNvbHV0aW9uVGFibGUgPSBbXTsgLy8gc3RvcmUgb2JqZWN0cyBmb3IgZGVyZWZlcmVuY2luZ1xuXG4gIC8vIGRlZmluaXRpb25zXG4gIGZvciAobmFtZSBpbiBzcGVjLmRlZmluaXRpb25zKSB7XG4gICAgdmFyIGRlZmluaXRpb24gPSBzcGVjLmRlZmluaXRpb25zW25hbWVdO1xuICAgIGZvciAocHJvcGVydHlOYW1lIGluIGRlZmluaXRpb24ucHJvcGVydGllcykge1xuICAgICAgcHJvcGVydHkgPSBkZWZpbml0aW9uLnByb3BlcnRpZXNbcHJvcGVydHlOYW1lXTtcbiAgICAgIHRoaXMucmVzb2x2ZVRvKHJvb3QsIHByb3BlcnR5LCByZXNvbHV0aW9uVGFibGUsICcvZGVmaW5pdGlvbnMnKTtcbiAgICB9XG5cbiAgICBpZihkZWZpbml0aW9uLmFsbE9mKSB7XG4gICAgICB2YXIgYWxsT2YgPSBkZWZpbml0aW9uLmFsbE9mO1xuICAgICAgLy8gdGhlIHJlZnMgZ28gZmlyc3RcbiAgICAgIGFsbE9mLnNvcnQoZnVuY3Rpb24oYSwgYikge1xuICAgICAgICBpZihhLiRyZWYgJiYgYi4kcmVmKSB7IHJldHVybiAwOyB9XG4gICAgICAgIGVsc2UgaWYoYS4kcmVmKSB7IHJldHVybiAtMTsgfVxuICAgICAgICBlbHNlIHsgcmV0dXJuIDE7IH1cbiAgICAgIH0pO1xuICAgICAgZm9yIChpID0gMDsgaSA8IGFsbE9mLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHByb3BlcnR5ID0gYWxsT2ZbaV07XG4gICAgICAgIGxvY2F0aW9uID0gJy9kZWZpbml0aW9ucy8nICsgbmFtZSArICcvYWxsT2YnO1xuICAgICAgICB0aGlzLnJlc29sdmVJbmxpbmUobnVsbCwgc3BlYywgcHJvcGVydHksIHJlc29sdXRpb25UYWJsZSwgdW5yZXNvbHZlZFJlZnMsIGxvY2F0aW9uKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBvcGVyYXRpb25zXG4gIGZvciAobmFtZSBpbiBzcGVjLnBhdGhzKSB7XG4gICAgdmFyIG1ldGhvZCwgb3BlcmF0aW9uLCByZXNwb25zZUNvZGU7XG4gICAgcGF0aCA9IHNwZWMucGF0aHNbbmFtZV07XG5cbiAgICBmb3IgKG1ldGhvZCBpbiBwYXRoKSB7XG4gICAgICAvLyBvcGVyYXRpb24gcmVmZXJlbmNlXG4gICAgICBpZihtZXRob2QgPT09ICckcmVmJykge1xuICAgICAgICAvLyBsb2NhdGlvbiA9IHBhdGhbbWV0aG9kXTtcbiAgICAgICAgbG9jYXRpb24gPSAnL3BhdGhzJyArIG5hbWU7XG4gICAgICAgIHRoaXMucmVzb2x2ZUlubGluZShyb290LCBzcGVjLCBwYXRoLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBsb2NhdGlvbik7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgb3BlcmF0aW9uID0gcGF0aFttZXRob2RdO1xuXG4gICAgICAgIHZhciBwYXJhbWV0ZXJzID0gb3BlcmF0aW9uLnBhcmFtZXRlcnM7XG4gICAgICAgIGZvciAoaSBpbiBwYXJhbWV0ZXJzKSB7XG4gICAgICAgICAgdmFyIHBhcmFtZXRlciA9IHBhcmFtZXRlcnNbaV07XG4gICAgICAgICAgbG9jYXRpb24gPSAnL3BhdGhzJyArIG5hbWUgKyAnLycgKyBtZXRob2QgKyAnL3BhcmFtZXRlcnMnO1xuXG4gICAgICAgICAgaWYgKHBhcmFtZXRlci5pbiA9PT0gJ2JvZHknICYmIHBhcmFtZXRlci5zY2hlbWEpIHtcbiAgICAgICAgICAgIHRoaXMucmVzb2x2ZVRvKHJvb3QsIHBhcmFtZXRlci5zY2hlbWEsIHJlc29sdXRpb25UYWJsZSwgbG9jYXRpb24pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChwYXJhbWV0ZXIuJHJlZikge1xuICAgICAgICAgICAgLy8gcGFyYW1ldGVyIHJlZmVyZW5jZVxuICAgICAgICAgICAgdGhpcy5yZXNvbHZlSW5saW5lKHJvb3QsIHNwZWMsIHBhcmFtZXRlciwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgcGFyYW1ldGVyLiRyZWYpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAocmVzcG9uc2VDb2RlIGluIG9wZXJhdGlvbi5yZXNwb25zZXMpIHtcbiAgICAgICAgICB2YXIgcmVzcG9uc2UgPSBvcGVyYXRpb24ucmVzcG9uc2VzW3Jlc3BvbnNlQ29kZV07XG4gICAgICAgICAgbG9jYXRpb24gPSAnL3BhdGhzJyArIG5hbWUgKyAnLycgKyBtZXRob2QgKyAnL3Jlc3BvbnNlcy8nICsgcmVzcG9uc2VDb2RlO1xuXG4gICAgICAgICAgaWYodHlwZW9mIHJlc3BvbnNlID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgaWYocmVzcG9uc2UuJHJlZikge1xuICAgICAgICAgICAgICAvLyByZXNwb25zZSByZWZlcmVuY2VcbiAgICAgICAgICAgICAgdGhpcy5yZXNvbHZlSW5saW5lKHJvb3QsIHNwZWMsIHJlc3BvbnNlLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBsb2NhdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocmVzcG9uc2Uuc2NoZW1hKSB7XG4gICAgICAgICAgICAgIHRoaXMucmVzb2x2ZVRvKHJvb3QsIHJlc3BvbnNlLnNjaGVtYSwgcmVzb2x1dGlvblRhYmxlLCBsb2NhdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIGV4cGVjdGVkQ2FsbHMgPSAwLCB0b1Jlc29sdmUgPSBbXTtcbiAgLy8gaWYgdGhlIHJvb3QgaXMgc2FtZSBhcyBvYmpbaV0ucm9vdCB3ZSBjYW4gcmVzb2x2ZSBsb2NhbGx5XG4gIHZhciBhbGwgPSByZXNvbHV0aW9uVGFibGU7XG5cbiAgZm9yKGkgPSAwOyBpIDwgYWxsLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGEgPSBhbGxbaV07XG4gICAgaWYocm9vdCA9PT0gYS5yb290KSB7XG4gICAgICBpZihhLnJlc29sdmVBcyA9PT0gJ3JlZicpIHtcbiAgICAgICAgLy8gcmVzb2x2ZSBhbnkgcGF0aCB3YWxraW5nXG4gICAgICAgIHZhciBqb2luZWQgPSAoKGEucm9vdCB8fCAnJykgKyAnLycgKyBhLmtleSkuc3BsaXQoJy8nKTtcbiAgICAgICAgdmFyIG5vcm1hbGl6ZWQgPSBbXTtcbiAgICAgICAgdmFyIHVybCA9ICcnO1xuICAgICAgICB2YXIgaztcblxuICAgICAgICBpZihhLmtleS5pbmRleE9mKCcuLi8nKSA+PSAwKSB7XG4gICAgICAgICAgZm9yKHZhciBqID0gMDsgaiA8IGpvaW5lZC5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgaWYoam9pbmVkW2pdID09PSAnLi4nKSB7XG4gICAgICAgICAgICAgIG5vcm1hbGl6ZWQgPSBub3JtYWxpemVkLnNsaWNlKDAsIG5vcm1hbGl6ZWQubGVuZ3RoLTEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgIG5vcm1hbGl6ZWQucHVzaChqb2luZWRbal0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBmb3IoayA9IDA7IGsgPCBub3JtYWxpemVkLmxlbmd0aDsgayArKykge1xuICAgICAgICAgICAgaWYoayA+IDApIHtcbiAgICAgICAgICAgICAgdXJsICs9ICcvJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHVybCArPSBub3JtYWxpemVkW2tdO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyB3ZSBub3cgaGF2ZSB0byByZW1vdGUgcmVzb2x2ZSB0aGlzIGJlY2F1c2UgdGhlIHBhdGggaGFzIGNoYW5nZWRcbiAgICAgICAgICBhLnJvb3QgPSB1cmw7XG4gICAgICAgICAgdG9SZXNvbHZlLnB1c2goYSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgdmFyIHBhcnRzID0gYS5rZXkuc3BsaXQoJyMnKTtcbiAgICAgICAgICBpZihwYXJ0cy5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgICAgIGlmKHBhcnRzWzBdLmluZGV4T2YoJ2h0dHA6Ly8nKSA9PT0gMCB8fCBwYXJ0c1swXS5pbmRleE9mKCdodHRwczovLycpID09PSAwKSB7XG4gICAgICAgICAgICAgIGEucm9vdCA9IHBhcnRzWzBdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbG9jYXRpb24gPSBwYXJ0c1sxXS5zcGxpdCgnLycpO1xuICAgICAgICAgICAgdmFyIHI7XG4gICAgICAgICAgICB2YXIgcyA9IHNwZWM7XG4gICAgICAgICAgICBmb3IoayA9IDA7IGsgPCBsb2NhdGlvbi5sZW5ndGg7IGsrKykge1xuICAgICAgICAgICAgICB2YXIgcGFydCA9IGxvY2F0aW9uW2tdO1xuICAgICAgICAgICAgICBpZihwYXJ0ICE9PSAnJykge1xuICAgICAgICAgICAgICAgIHMgPSBzW3BhcnRdO1xuICAgICAgICAgICAgICAgIGlmKHR5cGVvZiBzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgICAgciA9IHM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgciA9IG51bGw7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmKHIgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgLy8gbXVzdCByZXNvbHZlIHRoaXMgdG9vXG4gICAgICAgICAgICAgIHRvUmVzb2x2ZS5wdXNoKGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIGlmIChhLnJlc29sdmVBcyA9PT0gJ2lubGluZScpIHtcbiAgICAgICAgICB0b1Jlc29sdmUucHVzaChhKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHRvUmVzb2x2ZS5wdXNoKGEpO1xuICAgIH1cbiAgfVxuICBleHBlY3RlZENhbGxzID0gdG9SZXNvbHZlLmxlbmd0aDtcblxuICAvLyByZXNvbHZlIGFueXRoaW5nIHRoYXQgaXMgbG9jYWxcbiAgZm9yKHZhciBpaSA9IDA7IGlpIDwgdG9SZXNvbHZlLmxlbmd0aDsgaWkrKykge1xuICAgIChmdW5jdGlvbihpdGVtLCBzZWxmKSB7XG4gICAgICBpZihpdGVtLnJvb3QgPT09IG51bGwpIHtcbiAgICAgICAgLy8gbG9jYWwgcmVzb2x2ZVxuICAgICAgICBzZWxmLnJlc29sdmVJdGVtKHNwZWMsIF9yb290LCByZXNvbHV0aW9uVGFibGUsIHJlc29sdmVkUmVmcywgdW5yZXNvbHZlZFJlZnMsIGl0ZW0pO1xuICAgICAgICBwcm9jZXNzZWRDYWxscyArPSAxO1xuXG4gICAgICAgIGlmKHByb2Nlc3NlZENhbGxzID09PSBleHBlY3RlZENhbGxzKSB7XG4gICAgICAgICAgc2VsZi5maW5pc2goc3BlYywgcm9vdCwgcmVzb2x1dGlvblRhYmxlLCByZXNvbHZlZFJlZnMsIHVucmVzb2x2ZWRSZWZzLCBjYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICB2YXIgb2JqID0ge1xuICAgICAgICAgIHVzZUpRdWVyeTogZmFsc2UsICAvLyBUT0RPXG4gICAgICAgICAgdXJsOiBpdGVtLnJvb3QsXG4gICAgICAgICAgbWV0aG9kOiAnZ2V0JyxcbiAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICBhY2NlcHQ6IHNlbGYuc2NvcGUuc3dhZ2dlclJlcXVlc3RIZWFkZXJzIHx8ICdhcHBsaWNhdGlvbi9qc29uJ1xuICAgICAgICAgIH0sXG4gICAgICAgICAgb246IHtcbiAgICAgICAgICAgIGVycm9yOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgIHByb2Nlc3NlZENhbGxzICs9IDE7XG4gICAgICAgICAgICAgIHVucmVzb2x2ZWRSZWZzW2l0ZW0ua2V5XSA9IG51bGw7XG5cbiAgICAgICAgICAgICAgaWYgKHByb2Nlc3NlZENhbGxzID09PSBleHBlY3RlZENhbGxzKSB7XG4gICAgICAgICAgICAgICAgc2VsZi5maW5pc2goc3BlYywgX3Jvb3QsIHJlc29sdXRpb25UYWJsZSwgcmVzb2x2ZWRSZWZzLCB1bnJlc29sdmVkUmVmcywgY2FsbGJhY2spO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LCAgLy8ganNoaW50IGlnbm9yZTpsaW5lXG4gICAgICAgICAgICByZXNwb25zZTogZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgIHZhciBzd2FnZ2VyID0gcmVzcG9uc2Uub2JqO1xuICAgICAgICAgICAgICBzZWxmLnJlc29sdmVJdGVtKHN3YWdnZXIsIF9yb290LCByZXNvbHV0aW9uVGFibGUsIHJlc29sdmVkUmVmcywgdW5yZXNvbHZlZFJlZnMsIGl0ZW0pO1xuICAgICAgICAgICAgICBwcm9jZXNzZWRDYWxscyArPSAxO1xuXG4gICAgICAgICAgICAgIGlmIChwcm9jZXNzZWRDYWxscyA9PT0gZXhwZWN0ZWRDYWxscykge1xuICAgICAgICAgICAgICAgIHNlbGYuZmluaXNoKHNwZWMsIF9yb290LCByZXNvbHV0aW9uVGFibGUsIHJlc29sdmVkUmVmcywgdW5yZXNvbHZlZFJlZnMsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gLy8ganNoaW50IGlnbm9yZTpsaW5lXG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKHNjb3BlICYmIHNjb3BlLmNsaWVudEF1dGhvcml6YXRpb25zKSB7XG4gICAgICAgICAgc2NvcGUuY2xpZW50QXV0aG9yaXphdGlvbnMuYXBwbHkob2JqKTtcbiAgICAgICAgfVxuICAgICAgICBuZXcgU3dhZ2dlckh0dHAoKS5leGVjdXRlKG9iaik7XG4gICAgICB9XG4gICAgfSh0b1Jlc29sdmVbaWldLCB0aGlzKSk7XG4gIH1cblxuICBpZiAoT2JqZWN0LmtleXModG9SZXNvbHZlKS5sZW5ndGggPT09IDApIHtcbiAgICB0aGlzLmZpbmlzaChzcGVjLCBfcm9vdCwgcmVzb2x1dGlvblRhYmxlLCByZXNvbHZlZFJlZnMsIHVucmVzb2x2ZWRSZWZzLCBjYWxsYmFjayk7XG4gIH1cbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS5yZXNvbHZlSXRlbSA9IGZ1bmN0aW9uKHNwZWMsIHJvb3QsIHJlc29sdXRpb25UYWJsZSwgcmVzb2x2ZWRSZWZzLCB1bnJlc29sdmVkUmVmcywgaXRlbSkge1xuICB2YXIgcGF0aCA9IGl0ZW0ubG9jYXRpb247XG4gIHZhciBsb2NhdGlvbiA9IHNwZWMsIHBhcnRzID0gcGF0aC5zcGxpdCgnLycpO1xuICBmb3IgKHZhciBqID0gMDsgaiA8IHBhcnRzLmxlbmd0aDsgaisrKSB7XG4gICAgdmFyIHNlZ21lbnQgPSBwYXJ0c1tqXTtcbiAgICBpZihzZWdtZW50LmluZGV4T2YoJ34xJykgIT09IC0xKSB7XG4gICAgICBzZWdtZW50ID0gcGFydHNbal0ucmVwbGFjZSgvfjAvZywgJ34nKS5yZXBsYWNlKC9+MS9nLCAnLycpO1xuICAgICAgaWYoc2VnbWVudC5jaGFyQXQoMCkgIT09ICcvJykge1xuICAgICAgICBzZWdtZW50ID0gJy8nICsgc2VnbWVudDtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHR5cGVvZiBsb2NhdGlvbiA9PT0gJ3VuZGVmaW5lZCcgfHwgbG9jYXRpb24gPT09IG51bGwpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBpZihzZWdtZW50ID09PSAnJyAmJiBqID09PSAocGFydHMubGVuZ3RoIC0gMSkgICYmIHBhcnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgIGxvY2F0aW9uID0gbnVsbDtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBpZiAoc2VnbWVudC5sZW5ndGggPiAwKSB7XG4gICAgICBsb2NhdGlvbiA9IGxvY2F0aW9uW3NlZ21lbnRdO1xuICAgIH1cbiAgfVxuICB2YXIgcmVzb2x2ZWQgPSBpdGVtLmtleTtcbiAgcGFydHMgPSBpdGVtLmtleS5zcGxpdCgnLycpO1xuICB2YXIgcmVzb2x2ZWROYW1lID0gcGFydHNbcGFydHMubGVuZ3RoLTFdO1xuXG4gIGlmKHJlc29sdmVkTmFtZS5pbmRleE9mKCcjJykgPj0gMCkge1xuICAgIHJlc29sdmVkTmFtZSA9IHJlc29sdmVkTmFtZS5zcGxpdCgnIycpWzFdO1xuICB9XG5cbiAgaWYgKGxvY2F0aW9uICE9PSBudWxsICYmIHR5cGVvZiBsb2NhdGlvbiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXNvbHZlZFJlZnNbcmVzb2x2ZWRdID0ge1xuICAgICAgbmFtZTogcmVzb2x2ZWROYW1lLFxuICAgICAgb2JqOiBsb2NhdGlvbixcbiAgICAgIGtleTogaXRlbS5rZXksXG4gICAgICByb290OiBpdGVtLnJvb3RcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIHVucmVzb2x2ZWRSZWZzW3Jlc29sdmVkXSA9IHtcbiAgICAgIHJvb3Q6IGl0ZW0ucm9vdCxcbiAgICAgIGxvY2F0aW9uOiBpdGVtLmxvY2F0aW9uXG4gICAgfTtcbiAgfVxufTtcblxuUmVzb2x2ZXIucHJvdG90eXBlLmZpbmlzaCA9IGZ1bmN0aW9uIChzcGVjLCByb290LCByZXNvbHV0aW9uVGFibGUsIHJlc29sdmVkUmVmcywgdW5yZXNvbHZlZFJlZnMsIGNhbGxiYWNrKSB7XG4gIC8vIHdhbGsgcmVzb2x1dGlvbiB0YWJsZSBhbmQgcmVwbGFjZSB3aXRoIHJlc29sdmVkIHJlZnNcbiAgdmFyIHJlZjtcbiAgZm9yIChyZWYgaW4gcmVzb2x1dGlvblRhYmxlKSB7XG4gICAgdmFyIGl0ZW0gPSByZXNvbHV0aW9uVGFibGVbcmVmXTtcblxuICAgIHZhciBrZXkgPSBpdGVtLmtleTtcbiAgICB2YXIgcmVzb2x2ZWRUbyA9IHJlc29sdmVkUmVmc1trZXldO1xuICAgIGlmIChyZXNvbHZlZFRvKSB7XG4gICAgICBzcGVjLmRlZmluaXRpb25zID0gc3BlYy5kZWZpbml0aW9ucyB8fCB7fTtcbiAgICAgIGlmIChpdGVtLnJlc29sdmVBcyA9PT0gJ3JlZicpIHtcbiAgICAgICAgc3BlYy5kZWZpbml0aW9uc1tyZXNvbHZlZFRvLm5hbWVdID0gcmVzb2x2ZWRUby5vYmo7XG4gICAgICAgIGl0ZW0ub2JqLiRyZWYgPSAnIy9kZWZpbml0aW9ucy8nICsgcmVzb2x2ZWRUby5uYW1lO1xuICAgICAgfSBlbHNlIGlmIChpdGVtLnJlc29sdmVBcyA9PT0gJ2lubGluZScpIHtcbiAgICAgICAgdmFyIHRhcmdldE9iaiA9IGl0ZW0ub2JqO1xuICAgICAgICB0YXJnZXRPYmpbJ3gtcmVzb2x2ZWQtZnJvbSddID0gWyBpdGVtLmtleSBdO1xuICAgICAgICBkZWxldGUgdGFyZ2V0T2JqLiRyZWY7XG5cbiAgICAgICAgZm9yIChrZXkgaW4gcmVzb2x2ZWRUby5vYmopIHtcbiAgICAgICAgICB2YXIgYWJzID0gdGhpcy5yZXRhaW5Sb290KHJlc29sdmVkVG8ub2JqW2tleV0sIGl0ZW0ucm9vdCk7XG4gICAgICAgICAgdGFyZ2V0T2JqW2tleV0gPSBhYnM7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgdmFyIGV4aXN0aW5nVW5yZXNvbHZlZCA9IHRoaXMuY291bnRVbnJlc29sdmVkUmVmcyhzcGVjKTtcblxuICBpZihleGlzdGluZ1VucmVzb2x2ZWQubGVuZ3RoID09PSAwIHx8IHRoaXMuaXRlcmF0aW9uID4gNSkge1xuICAgIHRoaXMucmVzb2x2ZUFsbE9mKHNwZWMuZGVmaW5pdGlvbnMpO1xuICAgIGNhbGxiYWNrLmNhbGwodGhpcy5zY29wZSwgc3BlYywgdW5yZXNvbHZlZFJlZnMpO1xuICB9XG4gIGVsc2Uge1xuICAgIHRoaXMuaXRlcmF0aW9uICs9IDE7XG4gICAgdGhpcy5yZXNvbHZlKHNwZWMsIHJvb3QsIGNhbGxiYWNrLCB0aGlzLnNjb3BlKTtcbiAgfVxufTtcblxuUmVzb2x2ZXIucHJvdG90eXBlLmNvdW50VW5yZXNvbHZlZFJlZnMgPSBmdW5jdGlvbihzcGVjKSB7XG4gIHZhciBpO1xuICB2YXIgcmVmcyA9IHRoaXMuZ2V0UmVmcyhzcGVjKTtcbiAgdmFyIGtleXMgPSBbXTtcbiAgdmFyIHVucmVzb2x2ZWRLZXlzID0gW107XG4gIGZvcihpIGluIHJlZnMpIHtcbiAgICBpZihpLmluZGV4T2YoJyMnKSA9PT0gMCkge1xuICAgICAga2V5cy5wdXNoKGkuc3Vic3RyaW5nKDEpKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB1bnJlc29sdmVkS2V5cy5wdXNoKGkpO1xuICAgIH1cbiAgfVxuXG4gIC8vIHZlcmlmeSBwb3NzaWJsZSBrZXlzXG4gIGZvcihpIGluIGtleXMpIHtcbiAgICB2YXIgcGFydCA9IGtleXNbaV07XG4gICAgdmFyIHBhcnRzID0gcGFydC5zcGxpdCgnLycpO1xuICAgIHZhciBvYmogPSBzcGVjO1xuXG4gICAgZm9yKHZhciBrIGluIHBhcnRzKSB7XG4gICAgICB2YXIga2V5ID0gcGFydHNba107XG4gICAgICBpZihrZXkgIT09ICcnKSB7XG4gICAgICAgIG9iaiA9IG9ialtrZXldO1xuICAgICAgICBpZih0eXBlb2Ygb2JqID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIHVucmVzb2x2ZWRLZXlzLnB1c2gocGFydCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHVucmVzb2x2ZWRLZXlzLmxlbmd0aDtcbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS5nZXRSZWZzID0gZnVuY3Rpb24oc3BlYywgb2JqKSB7XG4gIG9iaiA9IG9iaiB8fCBzcGVjO1xuICB2YXIgb3V0cHV0ID0ge307XG4gIGZvcih2YXIga2V5IGluIG9iaikge1xuICAgIHZhciBpdGVtID0gb2JqW2tleV07XG4gICAgaWYoa2V5ID09PSAnJHJlZicgJiYgdHlwZW9mIGl0ZW0gPT09ICdzdHJpbmcnKSB7XG4gICAgICBvdXRwdXRbaXRlbV0gPSBudWxsO1xuICAgIH1cbiAgICBlbHNlIGlmKHR5cGVvZiBpdGVtID09PSAnb2JqZWN0Jykge1xuICAgICAgdmFyIG8gPSB0aGlzLmdldFJlZnMoaXRlbSk7XG4gICAgICBmb3IodmFyIGsgaW4gbykge1xuICAgICAgICBvdXRwdXRba10gPSBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gb3V0cHV0O1xufTtcblxuUmVzb2x2ZXIucHJvdG90eXBlLnJldGFpblJvb3QgPSBmdW5jdGlvbihvYmosIHJvb3QpIHtcbiAgLy8gd2FsayBvYmplY3QgYW5kIGxvb2sgZm9yIHJlbGF0aXZlICRyZWZzXG4gIGZvcih2YXIga2V5IGluIG9iaikge1xuICAgIHZhciBpdGVtID0gb2JqW2tleV07XG4gICAgaWYoa2V5ID09PSAnJHJlZicgJiYgdHlwZW9mIGl0ZW0gPT09ICdzdHJpbmcnKSB7XG4gICAgICAvLyBzdG9wIGFuZCBpbnNwZWN0XG4gICAgICBpZihpdGVtLmluZGV4T2YoJ2h0dHA6Ly8nKSAhPT0gMCAmJiBpdGVtLmluZGV4T2YoJ2h0dHBzOi8vJykgIT09IDApIHtcbiAgICAgICAgaWYoaXRlbS5pbmRleE9mKCcjJykgIT09IDApIHtcbiAgICAgICAgICBpdGVtID0gJyMnICsgaXRlbTtcbiAgICAgICAgfVxuICAgICAgICBpdGVtID0gKHJvb3QgfHwgJycpICsgaXRlbTtcbiAgICAgICAgb2JqW2tleV0gPSBpdGVtO1xuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIGlmKHR5cGVvZiBpdGVtID09PSAnb2JqZWN0Jykge1xuICAgICAgdGhpcy5yZXRhaW5Sb290KGl0ZW0sIHJvb3QpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gb2JqO1xufTtcblxuLyoqXG4gKiBpbW1lZGlhdGVseSBpbi1saW5lcyBsb2NhbCByZWZzLCBxdWV1ZXMgcmVtb3RlIHJlZnNcbiAqIGZvciBpbmxpbmUgcmVzb2x1dGlvblxuICovXG5SZXNvbHZlci5wcm90b3R5cGUucmVzb2x2ZUlubGluZSA9IGZ1bmN0aW9uIChyb290LCBzcGVjLCBwcm9wZXJ0eSwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgbG9jYXRpb24pIHtcbiAgdmFyIGtleSA9IHByb3BlcnR5LiRyZWYsIHJlZiA9IHByb3BlcnR5LiRyZWYsIGksIHAsIHAyLCBycztcbiAgdmFyIHJvb3RUcmltbWVkID0gZmFsc2U7XG4gIGlmIChyZWYpIHtcbiAgICBpZihyZWYuaW5kZXhPZignLi4vJykgPT09IDApIHtcbiAgICAgIC8vIHJlc2V0IHJvb3RcbiAgICAgIHAgPSByZWYuc3BsaXQoJy4uLycpO1xuICAgICAgcDIgPSByb290LnNwbGl0KCcvJyk7XG4gICAgICByZWYgPSAnJztcbiAgICAgIGZvcihpID0gMDsgaSA8IHAubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYocFtpXSA9PT0gJycpIHtcbiAgICAgICAgICBwMiA9IHAyLnNsaWNlKDAsIHAyLmxlbmd0aC0xKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICByZWYgKz0gcFtpXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcm9vdCA9ICcnO1xuICAgICAgZm9yKGkgPSAwOyBpIDwgcDIubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgIGlmKGkgPiAwKSB7IHJvb3QgKz0gJy8nOyB9XG4gICAgICAgIHJvb3QgKz0gcDJbaV07XG4gICAgICB9XG4gICAgICByb290VHJpbW1lZCA9IHRydWU7XG4gICAgfVxuICAgIGlmKHJlZi5pbmRleE9mKCcjJykgPj0gMCkge1xuICAgICAgaWYocmVmLmluZGV4T2YoJy8nKSA9PT0gMCkge1xuICAgICAgICBycyA9IHJlZi5zcGxpdCgnIycpO1xuICAgICAgICBwICA9IHJvb3Quc3BsaXQoJy8vJyk7XG4gICAgICAgIHAyID0gcFsxXS5zcGxpdCgnLycpO1xuICAgICAgICByb290ID0gcFswXSArICcvLycgKyBwMlswXSArIHJzWzBdO1xuICAgICAgICBsb2NhdGlvbiA9IHJzWzFdO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHJzID0gcmVmLnNwbGl0KCcjJyk7XG4gICAgICAgIGlmKHJzWzBdICE9PSAnJykge1xuICAgICAgICAgIHAyID0gcm9vdC5zcGxpdCgnLycpO1xuICAgICAgICAgIHAyID0gcDIuc2xpY2UoMCwgcDIubGVuZ3RoIC0gMSk7XG4gICAgICAgICAgaWYoIXJvb3RUcmltbWVkKSB7XG4gICAgICAgICAgICByb290ID0gJyc7XG4gICAgICAgICAgICBmb3IgKHZhciBrID0gMDsgayA8IHAyLmxlbmd0aDsgaysrKSB7XG4gICAgICAgICAgICAgIGlmKGsgPiAwKSB7IHJvb3QgKz0gJy8nOyB9XG4gICAgICAgICAgICAgIHJvb3QgKz0gcDJba107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHJvb3QgKz0gJy8nICsgcmVmLnNwbGl0KCcjJylbMF07XG4gICAgICAgIH1cbiAgICAgICAgbG9jYXRpb24gPSByc1sxXTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHJlZi5pbmRleE9mKCdodHRwJykgPT09IDApIHtcbiAgICAgIGlmKHJlZi5pbmRleE9mKCcjJykgPj0gMCkge1xuICAgICAgICByb290ID0gcmVmLnNwbGl0KCcjJylbMF07XG4gICAgICAgIGxvY2F0aW9uID0gcmVmLnNwbGl0KCcjJylbMV07XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgcm9vdCA9IHJlZjtcbiAgICAgICAgbG9jYXRpb24gPSAnJztcbiAgICAgIH1cbiAgICAgIHJlc29sdXRpb25UYWJsZS5wdXNoKHtvYmo6IHByb3BlcnR5LCByZXNvbHZlQXM6ICdpbmxpbmUnLCByb290OiByb290LCBrZXk6IGtleSwgbG9jYXRpb246IGxvY2F0aW9ufSk7XG4gICAgfSBlbHNlIGlmIChyZWYuaW5kZXhPZignIycpID09PSAwKSB7XG4gICAgICBsb2NhdGlvbiA9IHJlZi5zcGxpdCgnIycpWzFdO1xuICAgICAgcmVzb2x1dGlvblRhYmxlLnB1c2goe29iajogcHJvcGVydHksIHJlc29sdmVBczogJ2lubGluZScsIHJvb3Q6IHJvb3QsIGtleToga2V5LCBsb2NhdGlvbjogbG9jYXRpb259KTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICByZXNvbHV0aW9uVGFibGUucHVzaCh7b2JqOiBwcm9wZXJ0eSwgcmVzb2x2ZUFzOiAnaW5saW5lJywgcm9vdDogcm9vdCwga2V5OiBrZXksIGxvY2F0aW9uOiBsb2NhdGlvbn0pO1xuICAgIH1cbiAgfSBlbHNlIGlmIChwcm9wZXJ0eS50eXBlID09PSAnYXJyYXknKSB7XG4gICAgdGhpcy5yZXNvbHZlVG8ocm9vdCwgcHJvcGVydHkuaXRlbXMsIHJlc29sdXRpb25UYWJsZSwgbG9jYXRpb24pO1xuICB9XG59O1xuXG5SZXNvbHZlci5wcm90b3R5cGUucmVzb2x2ZVRvID0gZnVuY3Rpb24gKHJvb3QsIHByb3BlcnR5LCByZXNvbHV0aW9uVGFibGUsIGxvY2F0aW9uKSB7XG4gIHZhciByZWYgPSBwcm9wZXJ0eS4kcmVmO1xuXG4gIGlmIChyZWYpIHtcbiAgICBpZihyZWYuaW5kZXhPZignIycpID49IDApIHtcbiAgICAgIGxvY2F0aW9uID0gcmVmLnNwbGl0KCcjJylbMV07XG4gICAgfVxuICAgIHJlc29sdXRpb25UYWJsZS5wdXNoKHtcbiAgICAgIG9iajogcHJvcGVydHksIHJlc29sdmVBczogJ3JlZicsIHJvb3Q6IHJvb3QsIGtleTogcmVmLCBsb2NhdGlvbjogbG9jYXRpb25cbiAgICB9KTtcbiAgfSBlbHNlIGlmIChwcm9wZXJ0eS50eXBlID09PSAnYXJyYXknKSB7XG4gICAgdmFyIGl0ZW1zID0gcHJvcGVydHkuaXRlbXM7XG4gICAgdGhpcy5yZXNvbHZlVG8ocm9vdCwgaXRlbXMsIHJlc29sdXRpb25UYWJsZSwgbG9jYXRpb24pO1xuICB9XG59O1xuXG5SZXNvbHZlci5wcm90b3R5cGUucmVzb2x2ZUFsbE9mID0gZnVuY3Rpb24oc3BlYywgb2JqLCBkZXB0aCkge1xuICBkZXB0aCA9IGRlcHRoIHx8IDA7XG4gIG9iaiA9IG9iaiB8fCBzcGVjO1xuICB2YXIgbmFtZTtcbiAgZm9yKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgdmFyIGl0ZW0gPSBvYmpba2V5XTtcbiAgICBpZihpdGVtICYmIHR5cGVvZiBpdGVtLmFsbE9mICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdmFyIGFsbE9mID0gaXRlbS5hbGxPZjtcbiAgICAgIGlmKEFycmF5LmlzQXJyYXkoYWxsT2YpKSB7XG4gICAgICAgIHZhciBvdXRwdXQgPSB7fTtcbiAgICAgICAgb3V0cHV0Wyd4LWNvbXBvc2VkJ10gPSB0cnVlO1xuICAgICAgICBmb3IodmFyIGkgPSAwOyBpIDwgYWxsT2YubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICB2YXIgY29tcG9uZW50ID0gYWxsT2ZbaV07XG4gICAgICAgICAgdmFyIHNvdXJjZSA9ICdzZWxmJztcbiAgICAgICAgICBpZih0eXBlb2YgY29tcG9uZW50Wyd4LXJlc29sdmVkLWZyb20nXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHNvdXJjZSA9IGNvbXBvbmVudFsneC1yZXNvbHZlZC1mcm9tJ11bMF07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZm9yKHZhciBwYXJ0IGluIGNvbXBvbmVudCkge1xuICAgICAgICAgICAgaWYoIW91dHB1dC5oYXNPd25Qcm9wZXJ0eShwYXJ0KSkge1xuICAgICAgICAgICAgICBvdXRwdXRbcGFydF0gPSBjb21wb25lbnRbcGFydF07XG4gICAgICAgICAgICAgIGlmKHBhcnQgPT09ICdwcm9wZXJ0aWVzJykge1xuICAgICAgICAgICAgICAgIGZvcihuYW1lIGluIG91dHB1dFtwYXJ0XSkge1xuICAgICAgICAgICAgICAgICAgb3V0cHV0W3BhcnRdW25hbWVdWyd4LXJlc29sdmVkLWZyb20nXSA9IHNvdXJjZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICBpZihwYXJ0ID09PSAncHJvcGVydGllcycpIHtcbiAgICAgICAgICAgICAgICB2YXIgcHJvcGVydGllcyA9IGNvbXBvbmVudFtwYXJ0XTtcbiAgICAgICAgICAgICAgICBmb3IobmFtZSBpbiBwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICAgICAgICBvdXRwdXQucHJvcGVydGllc1tuYW1lXSA9IHByb3BlcnRpZXNbbmFtZV07XG4gICAgICAgICAgICAgICAgICBvdXRwdXQucHJvcGVydGllc1tuYW1lXVsneC1yZXNvbHZlZC1mcm9tJ10gPSBzb3VyY2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGVsc2UgaWYocGFydCA9PT0gJ3JlcXVpcmVkJykge1xuICAgICAgICAgICAgICAgIC8vIG1lcmdlICYgZGVkdXAgdGhlIHJlcXVpcmVkIGFycmF5XG4gICAgICAgICAgICAgICAgdmFyIGEgPSBvdXRwdXQucmVxdWlyZWQuY29uY2F0KGNvbXBvbmVudFtwYXJ0XSk7XG4gICAgICAgICAgICAgICAgZm9yKHZhciBrID0gMDsgayA8IGEubGVuZ3RoOyArK2spIHtcbiAgICAgICAgICAgICAgICAgIGZvcih2YXIgaiA9IGsgKyAxOyBqIDwgYS5sZW5ndGg7ICsraikge1xuICAgICAgICAgICAgICAgICAgICBpZihhW2tdID09PSBhW2pdKSB7IGEuc3BsaWNlKGotLSwgMSk7IH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgb3V0cHV0LnJlcXVpcmVkID0gYTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBlbHNlIGlmKHBhcnQgPT09ICd4LXJlc29sdmVkLWZyb20nKSB7XG4gICAgICAgICAgICAgICAgb3V0cHV0Wyd4LXJlc29sdmVkLWZyb20nXS5wdXNoKHNvdXJjZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gVE9ETzogbmVlZCB0byBtZXJnZSB0aGlzIHByb3BlcnR5XG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJ3doYXQgdG8gZG8gd2l0aCAnICsgcGFydClcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBvYmpba2V5XSA9IG91dHB1dDtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYodHlwZW9mIGl0ZW0gPT09ICdvYmplY3QnKSB7XG4gICAgICB0aGlzLnJlc29sdmVBbGxPZihzcGVjLCBpdGVtLCBkZXB0aCArIDEpO1xuICAgIH1cbiAgfVxufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFN3YWdnZXJIdHRwID0gcmVxdWlyZSgnLi9odHRwJyk7XG5cbnZhciBTd2FnZ2VyU3BlY0NvbnZlcnRlciA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmVycm9ycyA9IFtdO1xuICB0aGlzLndhcm5pbmdzID0gW107XG4gIHRoaXMubW9kZWxNYXAgPSB7fTtcbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5zZXREb2N1bWVudGF0aW9uTG9jYXRpb24gPSBmdW5jdGlvbiAobG9jYXRpb24pIHtcbiAgdGhpcy5kb2NMb2NhdGlvbiA9IGxvY2F0aW9uO1xufTtcblxuLyoqXG4gKiBjb252ZXJ0cyBhIHJlc291cmNlIGxpc3RpbmcgT1IgYXBpIGRlY2xhcmF0aW9uXG4gKiovXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuY29udmVydCA9IGZ1bmN0aW9uIChvYmosIGNsaWVudEF1dGhvcml6YXRpb25zLCBjYWxsYmFjaykge1xuICAvLyBub3QgYSB2YWxpZCBzcGVjXG4gIGlmKCFvYmogfHwgIUFycmF5LmlzQXJyYXkob2JqLmFwaXMpKSB7XG4gICAgcmV0dXJuIHRoaXMuZmluaXNoKGNhbGxiYWNrLCBudWxsKTtcbiAgfVxuICB0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zID0gY2xpZW50QXV0aG9yaXphdGlvbnM7XG5cbiAgLy8gY3JlYXRlIGEgbmV3IHN3YWdnZXIgb2JqZWN0IHRvIHJldHVyblxuICB2YXIgc3dhZ2dlciA9IHsgc3dhZ2dlcjogJzIuMCcgfTtcblxuICBzd2FnZ2VyLm9yaWdpbmFsVmVyc2lvbiA9IG9iai5zd2FnZ2VyVmVyc2lvbjtcblxuICAvLyBhZGQgdGhlIGluZm9cbiAgdGhpcy5hcGlJbmZvKG9iaiwgc3dhZ2dlcik7XG5cbiAgLy8gYWRkIHNlY3VyaXR5IGRlZmluaXRpb25zXG4gIHRoaXMuc2VjdXJpdHlEZWZpbml0aW9ucyhvYmosIHN3YWdnZXIpO1xuXG4gIC8vIHRha2UgYmFzZVBhdGggaW50byBhY2NvdW50XG4gIGlmIChvYmouYmFzZVBhdGgpIHtcbiAgICB0aGlzLnNldERvY3VtZW50YXRpb25Mb2NhdGlvbihvYmouYmFzZVBhdGgpO1xuICB9XG5cbiAgLy8gdGFrZSBiYXNlUGF0aCBpbnRvIGFjY291bnRcbiAgaWYgKG9iai5iYXNlUGF0aCkge1xuICAgIHRoaXMuc2V0RG9jdW1lbnRhdGlvbkxvY2F0aW9uKG9iai5iYXNlUGF0aCk7XG4gIH1cblxuICAvLyBzZWUgaWYgdGhpcyBpcyBhIHNpbmdsZS1maWxlIHN3YWdnZXIgZGVmaW5pdGlvblxuICB2YXIgaXNTaW5nbGVGaWxlU3dhZ2dlciA9IGZhbHNlO1xuICB2YXIgaTtcbiAgZm9yKGkgPSAwOyBpIDwgb2JqLmFwaXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgYXBpID0gb2JqLmFwaXNbaV07XG4gICAgaWYoQXJyYXkuaXNBcnJheShhcGkub3BlcmF0aW9ucykpIHtcbiAgICAgIGlzU2luZ2xlRmlsZVN3YWdnZXIgPSB0cnVlO1xuICAgIH1cbiAgfVxuICBpZihpc1NpbmdsZUZpbGVTd2FnZ2VyKSB7XG4gICAgdGhpcy5kZWNsYXJhdGlvbihvYmosIHN3YWdnZXIpO1xuICAgIHRoaXMuZmluaXNoKGNhbGxiYWNrLCBzd2FnZ2VyKTtcbiAgfVxuICBlbHNlIHtcbiAgICB0aGlzLnJlc291cmNlTGlzdGluZyhvYmosIHN3YWdnZXIsIGNhbGxiYWNrKTtcbiAgfVxufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLmRlY2xhcmF0aW9uID0gZnVuY3Rpb24ob2JqLCBzd2FnZ2VyKSB7XG4gIHZhciBuYW1lLCBpLCBwLCBwb3M7XG4gIGlmKCFvYmouYXBpcykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChvYmouYmFzZVBhdGguaW5kZXhPZignaHR0cDovLycpID09PSAwKSB7XG4gICAgcCA9IG9iai5iYXNlUGF0aC5zdWJzdHJpbmcoJ2h0dHA6Ly8nLmxlbmd0aCk7XG4gICAgcG9zID0gcC5pbmRleE9mKCcvJyk7XG4gICAgaWYgKHBvcyA+IDApIHtcbiAgICAgIHN3YWdnZXIuaG9zdCA9IHAuc3Vic3RyaW5nKDAsIHBvcyk7XG4gICAgICBzd2FnZ2VyLmJhc2VQYXRoID0gcC5zdWJzdHJpbmcocG9zKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBzd2FnZ2VyLmhvc3QgPSBwO1xuICAgICAgc3dhZ2dlci5iYXNlUGF0aCA9ICcvJztcbiAgICB9XG4gIH0gZWxzZSBpZiAob2JqLmJhc2VQYXRoLmluZGV4T2YoJ2h0dHBzOi8vJykgPT09IDApIHtcbiAgICBwID0gb2JqLmJhc2VQYXRoLnN1YnN0cmluZygnaHR0cHM6Ly8nLmxlbmd0aCk7XG4gICAgcG9zID0gcC5pbmRleE9mKCcvJyk7XG4gICAgaWYgKHBvcyA+IDApIHtcbiAgICAgIHN3YWdnZXIuaG9zdCA9IHAuc3Vic3RyaW5nKDAsIHBvcyk7XG4gICAgICBzd2FnZ2VyLmJhc2VQYXRoID0gcC5zdWJzdHJpbmcocG9zKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBzd2FnZ2VyLmhvc3QgPSBwO1xuICAgICAgc3dhZ2dlci5iYXNlUGF0aCA9ICcvJztcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgc3dhZ2dlci5iYXNlUGF0aCA9IG9iai5iYXNlUGF0aDtcbiAgfVxuXG4gIHZhciByZXNvdXJjZUxldmVsQXV0aDtcbiAgaWYob2JqLmF1dGhvcml6YXRpb25zKSB7XG4gICAgcmVzb3VyY2VMZXZlbEF1dGggPSBvYmouYXV0aG9yaXphdGlvbnM7XG4gIH1cbiAgaWYob2JqLmNvbnN1bWVzKSB7XG4gICAgc3dhZ2dlci5jb25zdW1lcyA9IG9iai5jb25zdW1lcztcbiAgfVxuICBpZihvYmoucHJvZHVjZXMpIHtcbiAgICBzd2FnZ2VyLnByb2R1Y2VzID0gb2JqLnByb2R1Y2VzO1xuICB9XG5cbiAgLy8gYnVpbGQgYSBtYXBwaW5nIG9mIGlkIHRvIG5hbWUgZm9yIDEuMCBtb2RlbCByZXNvbHV0aW9uc1xuICBpZih0eXBlb2Ygb2JqID09PSAnb2JqZWN0Jykge1xuICAgIGZvcihuYW1lIGluIG9iai5tb2RlbHMpIHtcbiAgICAgIHZhciBleGlzdGluZ01vZGVsID0gb2JqLm1vZGVsc1tuYW1lXTtcbiAgICAgIHZhciBrZXkgPSAoZXhpc3RpbmdNb2RlbC5pZCB8fCBuYW1lKTtcbiAgICAgIHRoaXMubW9kZWxNYXBba2V5XSA9IG5hbWU7XG4gICAgfVxuICB9XG5cbiAgZm9yKGkgPSAwOyBpIDwgb2JqLmFwaXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgYXBpID0gb2JqLmFwaXNbaV07XG4gICAgdmFyIHBhdGggPSBhcGkucGF0aDtcbiAgICB2YXIgb3BlcmF0aW9ucyA9IGFwaS5vcGVyYXRpb25zO1xuICAgIHRoaXMub3BlcmF0aW9ucyhwYXRoLCBvYmoucmVzb3VyY2VQYXRoLCBvcGVyYXRpb25zLCByZXNvdXJjZUxldmVsQXV0aCwgc3dhZ2dlcik7XG4gIH1cblxuICB2YXIgbW9kZWxzID0gb2JqLm1vZGVscyB8fCB7fTtcbiAgdGhpcy5tb2RlbHMobW9kZWxzLCBzd2FnZ2VyKTtcbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5tb2RlbHMgPSBmdW5jdGlvbihvYmosIHN3YWdnZXIpIHtcbiAgaWYodHlwZW9mIG9iaiAhPT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgdmFyIG5hbWU7XG5cbiAgc3dhZ2dlci5kZWZpbml0aW9ucyA9IHN3YWdnZXIuZGVmaW5pdGlvbnMgfHwge307XG4gIGZvcihuYW1lIGluIG9iaikge1xuICAgIHZhciBleGlzdGluZ01vZGVsID0gb2JqW25hbWVdO1xuICAgIHZhciBfZW51bSA9IFtdO1xuICAgIHZhciBzY2hlbWEgPSB7IHByb3BlcnRpZXM6IHt9fTtcbiAgICB2YXIgcHJvcGVydHlOYW1lO1xuICAgIGZvcihwcm9wZXJ0eU5hbWUgaW4gZXhpc3RpbmdNb2RlbC5wcm9wZXJ0aWVzKSB7XG4gICAgICB2YXIgZXhpc3RpbmdQcm9wZXJ0eSA9IGV4aXN0aW5nTW9kZWwucHJvcGVydGllc1twcm9wZXJ0eU5hbWVdO1xuICAgICAgdmFyIHByb3BlcnR5ID0ge307XG4gICAgICB0aGlzLmRhdGFUeXBlKGV4aXN0aW5nUHJvcGVydHksIHByb3BlcnR5KTtcbiAgICAgIGlmKGV4aXN0aW5nUHJvcGVydHkuZGVzY3JpcHRpb24pIHtcbiAgICAgICAgcHJvcGVydHkuZGVzY3JpcHRpb24gPSBleGlzdGluZ1Byb3BlcnR5LmRlc2NyaXB0aW9uO1xuICAgICAgfVxuICAgICAgaWYoZXhpc3RpbmdQcm9wZXJ0eVsnZW51bSddKSB7XG4gICAgICAgIHByb3BlcnR5WydlbnVtJ10gPSBleGlzdGluZ1Byb3BlcnR5WydlbnVtJ107XG4gICAgICB9XG4gICAgICBpZih0eXBlb2YgZXhpc3RpbmdQcm9wZXJ0eS5yZXF1aXJlZCA9PT0gJ2Jvb2xlYW4nICYmIGV4aXN0aW5nUHJvcGVydHkucmVxdWlyZWQgPT09IHRydWUpIHtcbiAgICAgICAgX2VudW0ucHVzaChwcm9wZXJ0eU5hbWUpO1xuICAgICAgfVxuICAgICAgaWYodHlwZW9mIGV4aXN0aW5nUHJvcGVydHkucmVxdWlyZWQgPT09ICdzdHJpbmcnICYmIGV4aXN0aW5nUHJvcGVydHkucmVxdWlyZWQgPT09ICd0cnVlJykge1xuICAgICAgICBfZW51bS5wdXNoKHByb3BlcnR5TmFtZSk7XG4gICAgICB9XG4gICAgICBzY2hlbWEucHJvcGVydGllc1twcm9wZXJ0eU5hbWVdID0gcHJvcGVydHk7XG4gICAgfVxuICAgIGlmKF9lbnVtLmxlbmd0aCA+IDApIHtcbiAgICAgIHNjaGVtYVsnZW51bSddID0gX2VudW07XG4gICAgfVxuXG4gICAgc2NoZW1hLnJlcXVpcmVkID0gZXhpc3RpbmdNb2RlbC5yZXF1aXJlZDtcbiAgICBzd2FnZ2VyLmRlZmluaXRpb25zW25hbWVdID0gc2NoZW1hO1xuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuZXh0cmFjdFRhZyA9IGZ1bmN0aW9uKHJlc291cmNlUGF0aCkge1xuICB2YXIgcGF0aFN0cmluZyA9IHJlc291cmNlUGF0aCB8fCAnZGVmYXVsdCc7XG4gIGlmKHBhdGhTdHJpbmcuaW5kZXhPZignaHR0cDonKSA9PT0gMCB8fCBwYXRoU3RyaW5nLmluZGV4T2YoJ2h0dHBzOicpID09PSAwKSB7XG4gICAgcGF0aFN0cmluZyA9IHBhdGhTdHJpbmcuc3BsaXQoWycvJ10pO1xuICAgIHBhdGhTdHJpbmcgPSBwYXRoU3RyaW5nW3BhdGhTdHJpbmcubGVuZ3RoIC0xXS5zdWJzdHJpbmcoKTtcbiAgfVxuICBpZihwYXRoU3RyaW5nLmVuZHNXaXRoKCcuanNvbicpKSB7XG4gICAgcGF0aFN0cmluZyA9IHBhdGhTdHJpbmcuc3Vic3RyaW5nKDAsIHBhdGhTdHJpbmcubGVuZ3RoIC0gJy5qc29uJy5sZW5ndGgpO1xuICB9XG4gIHJldHVybiBwYXRoU3RyaW5nLnJlcGxhY2UoJy8nLCcnKTtcbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5vcGVyYXRpb25zID0gZnVuY3Rpb24ocGF0aCwgcmVzb3VyY2VQYXRoLCBvYmosIHJlc291cmNlTGV2ZWxBdXRoLCBzd2FnZ2VyKSB7XG4gIGlmKCFBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgdmFyIGk7XG5cbiAgaWYoIXN3YWdnZXIucGF0aHMpIHtcbiAgICBzd2FnZ2VyLnBhdGhzID0ge307XG4gIH1cblxuICB2YXIgcGF0aE9iaiA9IHN3YWdnZXIucGF0aHNbcGF0aF0gfHwge307XG4gIHZhciB0YWcgPSB0aGlzLmV4dHJhY3RUYWcocmVzb3VyY2VQYXRoKTtcbiAgc3dhZ2dlci50YWdzID0gc3dhZ2dlci50YWdzIHx8IFtdO1xuICB2YXIgbWF0Y2hlZCA9IGZhbHNlO1xuICBmb3IoaSA9IDA7IGkgPCBzd2FnZ2VyLnRhZ3MubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgdGFnT2JqZWN0ID0gc3dhZ2dlci50YWdzW2ldO1xuICAgIGlmKHRhZ09iamVjdC5uYW1lID09PSB0YWcpIHtcbiAgICAgIG1hdGNoZWQgPSB0cnVlO1xuICAgIH1cbiAgfVxuICBpZighbWF0Y2hlZCkge1xuICAgIHN3YWdnZXIudGFncy5wdXNoKHtuYW1lOiB0YWd9KTtcbiAgfVxuXG4gIGZvcihpID0gMDsgaSA8IG9iai5sZW5ndGg7IGkrKykge1xuICAgIHZhciBleGlzdGluZ09wZXJhdGlvbiA9IG9ialtpXTtcbiAgICB2YXIgbWV0aG9kID0gKGV4aXN0aW5nT3BlcmF0aW9uLm1ldGhvZCB8fCBleGlzdGluZ09wZXJhdGlvbi5odHRwTWV0aG9kKS50b0xvd2VyQ2FzZSgpO1xuICAgIHZhciBvcGVyYXRpb24gPSB7dGFnczogW3RhZ119O1xuICAgIHZhciBleGlzdGluZ0F1dGhvcml6YXRpb25zID0gZXhpc3RpbmdPcGVyYXRpb24uYXV0aG9yaXphdGlvbnM7XG5cbiAgICBpZihleGlzdGluZ0F1dGhvcml6YXRpb25zICYmIE9iamVjdC5rZXlzKGV4aXN0aW5nQXV0aG9yaXphdGlvbnMpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgZXhpc3RpbmdBdXRob3JpemF0aW9ucyA9IHJlc291cmNlTGV2ZWxBdXRoO1xuICAgIH1cblxuICAgIGlmKHR5cGVvZiBleGlzdGluZ0F1dGhvcml6YXRpb25zICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdmFyIHNjb3Blc09iamVjdDtcbiAgICAgIGZvcih2YXIga2V5IGluIGV4aXN0aW5nQXV0aG9yaXphdGlvbnMpIHtcbiAgICAgICAgb3BlcmF0aW9uLnNlY3VyaXR5ID0gb3BlcmF0aW9uLnNlY3VyaXR5IHx8IFtdO1xuICAgICAgICB2YXIgc2NvcGVzID0gZXhpc3RpbmdBdXRob3JpemF0aW9uc1trZXldO1xuICAgICAgICBpZihzY29wZXMpIHtcbiAgICAgICAgICB2YXIgc2VjdXJpdHlTY29wZXMgPSBbXTtcbiAgICAgICAgICBmb3IodmFyIGogaW4gc2NvcGVzKSB7XG4gICAgICAgICAgICBzZWN1cml0eVNjb3Blcy5wdXNoKHNjb3Blc1tqXS5zY29wZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHNjb3Blc09iamVjdCA9IHt9O1xuICAgICAgICAgIHNjb3Blc09iamVjdFtrZXldID0gc2VjdXJpdHlTY29wZXM7XG4gICAgICAgICAgb3BlcmF0aW9uLnNlY3VyaXR5LnB1c2goc2NvcGVzT2JqZWN0KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBzY29wZXNPYmplY3QgPSB7fTtcbiAgICAgICAgICBzY29wZXNPYmplY3Rba2V5XSA9IFtdO1xuICAgICAgICAgIG9wZXJhdGlvbi5zZWN1cml0eS5wdXNoKHNjb3Blc09iamVjdCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZihleGlzdGluZ09wZXJhdGlvbi5jb25zdW1lcykge1xuICAgICAgb3BlcmF0aW9uLmNvbnN1bWVzID0gZXhpc3RpbmdPcGVyYXRpb24uY29uc3VtZXM7XG4gICAgfVxuICAgIGVsc2UgaWYoc3dhZ2dlci5jb25zdW1lcykge1xuICAgICAgb3BlcmF0aW9uLmNvbnN1bWVzID0gc3dhZ2dlci5jb25zdW1lcztcbiAgICB9XG4gICAgaWYoZXhpc3RpbmdPcGVyYXRpb24ucHJvZHVjZXMpIHtcbiAgICAgIG9wZXJhdGlvbi5wcm9kdWNlcyA9IGV4aXN0aW5nT3BlcmF0aW9uLnByb2R1Y2VzO1xuICAgIH1cbiAgICBlbHNlIGlmKHN3YWdnZXIucHJvZHVjZXMpIHtcbiAgICAgIG9wZXJhdGlvbi5wcm9kdWNlcyA9IHN3YWdnZXIucHJvZHVjZXM7XG4gICAgfVxuICAgIGlmKGV4aXN0aW5nT3BlcmF0aW9uLnN1bW1hcnkpIHtcbiAgICAgIG9wZXJhdGlvbi5zdW1tYXJ5ID0gZXhpc3RpbmdPcGVyYXRpb24uc3VtbWFyeTtcbiAgICB9XG4gICAgaWYoZXhpc3RpbmdPcGVyYXRpb24ubm90ZXMpIHtcbiAgICAgIG9wZXJhdGlvbi5kZXNjcmlwdGlvbiA9IGV4aXN0aW5nT3BlcmF0aW9uLm5vdGVzO1xuICAgIH1cbiAgICBpZihleGlzdGluZ09wZXJhdGlvbi5uaWNrbmFtZSkge1xuICAgICAgb3BlcmF0aW9uLm9wZXJhdGlvbklkID0gZXhpc3RpbmdPcGVyYXRpb24ubmlja25hbWU7XG4gICAgfVxuICAgIGlmKGV4aXN0aW5nT3BlcmF0aW9uLmRlcHJlY2F0ZWQpIHtcbiAgICAgIG9wZXJhdGlvbi5kZXByZWNhdGVkID0gZXhpc3RpbmdPcGVyYXRpb24uZGVwcmVjYXRlZDtcbiAgICB9XG5cbiAgICB0aGlzLmF1dGhvcml6YXRpb25zKGV4aXN0aW5nQXV0aG9yaXphdGlvbnMsIHN3YWdnZXIpO1xuICAgIHRoaXMucGFyYW1ldGVycyhvcGVyYXRpb24sIGV4aXN0aW5nT3BlcmF0aW9uLnBhcmFtZXRlcnMsIHN3YWdnZXIpO1xuICAgIHRoaXMucmVzcG9uc2VNZXNzYWdlcyhvcGVyYXRpb24sIGV4aXN0aW5nT3BlcmF0aW9uLCBzd2FnZ2VyKTtcblxuICAgIHBhdGhPYmpbbWV0aG9kXSA9IG9wZXJhdGlvbjtcbiAgfVxuXG4gIHN3YWdnZXIucGF0aHNbcGF0aF0gPSBwYXRoT2JqO1xufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLnJlc3BvbnNlTWVzc2FnZXMgPSBmdW5jdGlvbihvcGVyYXRpb24sIGV4aXN0aW5nT3BlcmF0aW9uKSB7XG4gIGlmKHR5cGVvZiBleGlzdGluZ09wZXJhdGlvbiAhPT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgLy8gYnVpbGQgZGVmYXVsdCByZXNwb25zZSBmcm9tIHRoZSBvcGVyYXRpb24gKDEueClcbiAgdmFyIGRlZmF1bHRSZXNwb25zZSA9IHt9O1xuICB0aGlzLmRhdGFUeXBlKGV4aXN0aW5nT3BlcmF0aW9uLCBkZWZhdWx0UmVzcG9uc2UpO1xuICAvLyBUT0RPOiBsb29rIGludG8gdGhlIHJlYWwgcHJvYmxlbSBvZiByZW5kZXJpbmcgcmVzcG9uc2VzIGluIHN3YWdnZXItdWlcbiAgLy8gLi4uLnNob3VsZCByZXBvbnNlVHlwZSBoYXZlIGFuIGltcGxpY2l0IHNjaGVtYT9cbiAgaWYoIWRlZmF1bHRSZXNwb25zZS5zY2hlbWEgJiYgZGVmYXVsdFJlc3BvbnNlLnR5cGUpIHtcbiAgICBkZWZhdWx0UmVzcG9uc2UgPSB7c2NoZW1hOiBkZWZhdWx0UmVzcG9uc2V9O1xuICB9XG5cbiAgb3BlcmF0aW9uLnJlc3BvbnNlcyA9IG9wZXJhdGlvbi5yZXNwb25zZXMgfHwge307XG5cbiAgLy8gZ3JhYiBmcm9tIHJlc3BvbnNlTWVzc2FnZXMgKDEuMilcbiAgdmFyIGhhczIwMCA9IGZhbHNlO1xuICBpZihBcnJheS5pc0FycmF5KGV4aXN0aW5nT3BlcmF0aW9uLnJlc3BvbnNlTWVzc2FnZXMpKSB7XG4gICAgdmFyIGk7XG4gICAgdmFyIGV4aXN0aW5nUmVzcG9uc2VzID0gZXhpc3RpbmdPcGVyYXRpb24ucmVzcG9uc2VNZXNzYWdlcztcbiAgICBmb3IoaSA9IDA7IGkgPCBleGlzdGluZ1Jlc3BvbnNlcy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGV4aXN0aW5nUmVzcG9uc2UgPSBleGlzdGluZ1Jlc3BvbnNlc1tpXTtcbiAgICAgIHZhciByZXNwb25zZSA9IHsgZGVzY3JpcHRpb246IGV4aXN0aW5nUmVzcG9uc2UubWVzc2FnZSB9O1xuICAgICAgaWYoZXhpc3RpbmdSZXNwb25zZS5jb2RlID09PSAyMDApIHtcbiAgICAgICAgaGFzMjAwID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIC8vIENvbnZlcnQgcmVzcG9uc2VNb2RlbCAtPiBzY2hlbWF7JHJlZjogcmVzcG9uc2VNb2RlbH1cbiAgICAgIGlmKGV4aXN0aW5nUmVzcG9uc2UucmVzcG9uc2VNb2RlbCkge1xuICAgICAgICByZXNwb25zZS5zY2hlbWEgPSB7JyRyZWYnOiBleGlzdGluZ1Jlc3BvbnNlLnJlc3BvbnNlTW9kZWx9O1xuICAgICAgfVxuICAgICAgb3BlcmF0aW9uLnJlc3BvbnNlc1snJyArIGV4aXN0aW5nUmVzcG9uc2UuY29kZV0gPSByZXNwb25zZTtcbiAgICB9XG4gIH1cblxuICBpZihoYXMyMDApIHtcbiAgICBvcGVyYXRpb24ucmVzcG9uc2VzWydkZWZhdWx0J10gPSBkZWZhdWx0UmVzcG9uc2U7XG4gIH1cbiAgZWxzZSB7XG4gICAgb3BlcmF0aW9uLnJlc3BvbnNlc1snMjAwJ10gPSBkZWZhdWx0UmVzcG9uc2U7XG4gIH1cbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5hdXRob3JpemF0aW9ucyA9IGZ1bmN0aW9uKG9iaikge1xuICAvLyBUT0RPXG4gIGlmKHR5cGVvZiBvYmogIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuO1xuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUucGFyYW1ldGVycyA9IGZ1bmN0aW9uKG9wZXJhdGlvbiwgb2JqKSB7XG4gIGlmKCFBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgdmFyIGk7XG4gIGZvcihpID0gMDsgaSA8IG9iai5sZW5ndGg7IGkrKykge1xuICAgIHZhciBleGlzdGluZ1BhcmFtZXRlciA9IG9ialtpXTtcbiAgICB2YXIgcGFyYW1ldGVyID0ge307XG4gICAgcGFyYW1ldGVyLm5hbWUgPSBleGlzdGluZ1BhcmFtZXRlci5uYW1lO1xuICAgIHBhcmFtZXRlci5kZXNjcmlwdGlvbiA9IGV4aXN0aW5nUGFyYW1ldGVyLmRlc2NyaXB0aW9uO1xuICAgIHBhcmFtZXRlci5yZXF1aXJlZCA9IGV4aXN0aW5nUGFyYW1ldGVyLnJlcXVpcmVkO1xuICAgIHBhcmFtZXRlci5pbiA9IGV4aXN0aW5nUGFyYW1ldGVyLnBhcmFtVHlwZTtcblxuICAgIC8vIHBlciAjMTY4XG4gICAgaWYocGFyYW1ldGVyLmluID09PSAnYm9keScpIHtcbiAgICAgIHBhcmFtZXRlci5uYW1lID0gJ2JvZHknO1xuICAgIH1cbiAgICBpZihwYXJhbWV0ZXIuaW4gPT09ICdmb3JtJykge1xuICAgICAgcGFyYW1ldGVyLmluID0gJ2Zvcm1EYXRhJztcbiAgICB9XG5cbiAgICBpZihleGlzdGluZ1BhcmFtZXRlci5lbnVtKSB7XG4gICAgICBwYXJhbWV0ZXIuZW51bSA9IGV4aXN0aW5nUGFyYW1ldGVyLmVudW07XG4gICAgfVxuXG4gICAgaWYoZXhpc3RpbmdQYXJhbWV0ZXIuYWxsb3dNdWx0aXBsZSA9PT0gdHJ1ZSB8fCBleGlzdGluZ1BhcmFtZXRlci5hbGxvd011bHRpcGxlID09PSAndHJ1ZScpIHtcbiAgICAgIHZhciBpbm5lclR5cGUgPSB7fTtcbiAgICAgIHRoaXMuZGF0YVR5cGUoZXhpc3RpbmdQYXJhbWV0ZXIsIGlubmVyVHlwZSk7XG4gICAgICBwYXJhbWV0ZXIudHlwZSA9ICdhcnJheSc7XG4gICAgICBwYXJhbWV0ZXIuaXRlbXMgPSBpbm5lclR5cGU7XG5cbiAgICAgIGlmKGV4aXN0aW5nUGFyYW1ldGVyLmFsbG93YWJsZVZhbHVlcykge1xuICAgICAgICB2YXIgYXYgPSBleGlzdGluZ1BhcmFtZXRlci5hbGxvd2FibGVWYWx1ZXM7XG4gICAgICAgIGlmKGF2LnZhbHVlVHlwZSA9PT0gJ0xJU1QnKSB7XG4gICAgICAgICAgcGFyYW1ldGVyWydlbnVtJ10gPSBhdi52YWx1ZXM7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB0aGlzLmRhdGFUeXBlKGV4aXN0aW5nUGFyYW1ldGVyLCBwYXJhbWV0ZXIpO1xuICAgIH1cblxuICAgIG9wZXJhdGlvbi5wYXJhbWV0ZXJzID0gb3BlcmF0aW9uLnBhcmFtZXRlcnMgfHwgW107XG4gICAgb3BlcmF0aW9uLnBhcmFtZXRlcnMucHVzaChwYXJhbWV0ZXIpO1xuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuZGF0YVR5cGUgPSBmdW5jdGlvbihzb3VyY2UsIHRhcmdldCkge1xuICBpZih0eXBlb2Ygc291cmNlICE9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmKHNvdXJjZS5taW5pbXVtKSB7XG4gICAgdGFyZ2V0Lm1pbmltdW0gPSBzb3VyY2UubWluaW11bTtcbiAgfVxuICBpZihzb3VyY2UubWF4aW11bSkge1xuICAgIHRhcmdldC5tYXhpbXVtID0gc291cmNlLm1heGltdW07XG4gIH1cblxuICAvLyBkZWZhdWx0IGNhbiBiZSAnZmFsc2UnXG4gIGlmKHR5cGVvZiBzb3VyY2UuZGVmYXVsdFZhbHVlICE9PSAndW5kZWZpbmVkJykge1xuICAgIHRhcmdldC5kZWZhdWx0ID0gc291cmNlLmRlZmF1bHRWYWx1ZTtcbiAgfVxuXG4gIHZhciBqc29uU2NoZW1hVHlwZSA9IHRoaXMudG9Kc29uU2NoZW1hKHNvdXJjZSk7XG4gIGlmKGpzb25TY2hlbWFUeXBlKSB7XG4gICAgdGFyZ2V0ID0gdGFyZ2V0IHx8IHt9O1xuICAgIGlmKGpzb25TY2hlbWFUeXBlLnR5cGUpIHtcbiAgICAgIHRhcmdldC50eXBlID0ganNvblNjaGVtYVR5cGUudHlwZTtcbiAgICB9XG4gICAgaWYoanNvblNjaGVtYVR5cGUuZm9ybWF0KSB7XG4gICAgICB0YXJnZXQuZm9ybWF0ID0ganNvblNjaGVtYVR5cGUuZm9ybWF0O1xuICAgIH1cbiAgICBpZihqc29uU2NoZW1hVHlwZS4kcmVmKSB7XG4gICAgICB0YXJnZXQuc2NoZW1hID0geyRyZWY6IGpzb25TY2hlbWFUeXBlLiRyZWZ9O1xuICAgIH1cbiAgICBpZihqc29uU2NoZW1hVHlwZS5pdGVtcykge1xuICAgICAgdGFyZ2V0Lml0ZW1zID0ganNvblNjaGVtYVR5cGUuaXRlbXM7XG4gICAgfVxuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUudG9Kc29uU2NoZW1hID0gZnVuY3Rpb24oc291cmNlKSB7XG4gIGlmKCFzb3VyY2UpIHtcbiAgICByZXR1cm4gJ29iamVjdCc7XG4gIH1cbiAgdmFyIGRldGVjdGVkVHlwZSA9IChzb3VyY2UudHlwZSB8fCBzb3VyY2UuZGF0YVR5cGUgfHwgc291cmNlLnJlc3BvbnNlQ2xhc3MgfHwgJycpO1xuICB2YXIgbGNUeXBlID0gZGV0ZWN0ZWRUeXBlLnRvTG93ZXJDYXNlKCk7XG4gIHZhciBmb3JtYXQgPSAoc291cmNlLmZvcm1hdCB8fCAnJykudG9Mb3dlckNhc2UoKTtcblxuICBpZihsY1R5cGUuaW5kZXhPZignbGlzdFsnKSA9PT0gMCkge1xuICAgIHZhciBpbm5lclR5cGUgPSBkZXRlY3RlZFR5cGUuc3Vic3RyaW5nKDUsIGRldGVjdGVkVHlwZS5sZW5ndGggLSAxKTtcbiAgICB2YXIganNvblR5cGUgPSB0aGlzLnRvSnNvblNjaGVtYSh7dHlwZTogaW5uZXJUeXBlfSk7XG4gICAgcmV0dXJuIHt0eXBlOiAnYXJyYXknLCBpdGVtczoganNvblR5cGV9O1xuICB9XG4gIGVsc2UgaWYobGNUeXBlID09PSAnaW50JyB8fCAobGNUeXBlID09PSAnaW50ZWdlcicgJiYgZm9ybWF0ID09PSAnaW50MzInKSlcbiAgICB7cmV0dXJuIHt0eXBlOiAnaW50ZWdlcicsIGZvcm1hdDogJ2ludDMyJ307fVxuICBlbHNlIGlmKGxjVHlwZSA9PT0gJ2xvbmcnIHx8IChsY1R5cGUgPT09ICdpbnRlZ2VyJyAmJiBmb3JtYXQgPT09ICdpbnQ2NCcpKVxuICAgIHtyZXR1cm4ge3R5cGU6ICdpbnRlZ2VyJywgZm9ybWF0OiAnaW50NjQnfTt9XG4gIGVsc2UgaWYobGNUeXBlID09PSAnaW50ZWdlcicpXG4gICAge3JldHVybiB7dHlwZTogJ2ludGVnZXInLCBmb3JtYXQ6ICdpbnQ2NCd9O31cbiAgZWxzZSBpZihsY1R5cGUgPT09ICdmbG9hdCcgfHwgKGxjVHlwZSA9PT0gJ251bWJlcicgJiYgZm9ybWF0ID09PSAnZmxvYXQnKSlcbiAgICB7cmV0dXJuIHt0eXBlOiAnbnVtYmVyJywgZm9ybWF0OiAnZmxvYXQnfTt9XG4gIGVsc2UgaWYobGNUeXBlID09PSAnZG91YmxlJyB8fCAobGNUeXBlID09PSAnbnVtYmVyJyAmJiBmb3JtYXQgPT09ICdkb3VibGUnKSlcbiAgICB7cmV0dXJuIHt0eXBlOiAnbnVtYmVyJywgZm9ybWF0OiAnZG91YmxlJ307fVxuICBlbHNlIGlmKChsY1R5cGUgPT09ICdzdHJpbmcnICYmIGZvcm1hdCA9PT0gJ2RhdGUtdGltZScpIHx8IChsY1R5cGUgPT09ICdkYXRlJykpXG4gICAge3JldHVybiB7dHlwZTogJ3N0cmluZycsIGZvcm1hdDogJ2RhdGUtdGltZSd9O31cbiAgZWxzZSBpZihsY1R5cGUgPT09ICdzdHJpbmcnKVxuICAgIHtyZXR1cm4ge3R5cGU6ICdzdHJpbmcnfTt9XG4gIGVsc2UgaWYobGNUeXBlID09PSAnZmlsZScpXG4gICAge3JldHVybiB7dHlwZTogJ2ZpbGUnfTt9XG4gIGVsc2UgaWYobGNUeXBlID09PSAnYm9vbGVhbicpXG4gICAge3JldHVybiB7dHlwZTogJ2Jvb2xlYW4nfTt9XG4gIGVsc2UgaWYobGNUeXBlID09PSAnYXJyYXknIHx8IGxjVHlwZSA9PT0gJ2xpc3QnKSB7XG4gICAgaWYoc291cmNlLml0ZW1zKSB7XG4gICAgICB2YXIgaXQgPSB0aGlzLnRvSnNvblNjaGVtYShzb3VyY2UuaXRlbXMpO1xuICAgICAgcmV0dXJuIHt0eXBlOiAnYXJyYXknLCBpdGVtczogaXR9O1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHJldHVybiB7dHlwZTogJ2FycmF5JywgaXRlbXM6IHt0eXBlOiAnb2JqZWN0J319O1xuICAgIH1cbiAgfVxuICBlbHNlIGlmKHNvdXJjZS4kcmVmKSB7XG4gICAgcmV0dXJuIHskcmVmOiAnIy9kZWZpbml0aW9ucy8nICsgdGhpcy5tb2RlbE1hcFtzb3VyY2UuJHJlZl0gfHwgc291cmNlLiRyZWZ9O1xuICB9XG4gIGVsc2UgaWYobGNUeXBlID09PSAndm9pZCcgfHwgbGNUeXBlID09PSAnJylcbiAgICB7cmV0dXJuIHt9O31cbiAgZWxzZSB7XG4gICAgcmV0dXJuIHskcmVmOiAnIy9kZWZpbml0aW9ucy8nICsgdGhpcy5tb2RlbE1hcFtzb3VyY2UudHlwZV0gfHwgc291cmNlLnR5cGV9O1xuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUucmVzb3VyY2VMaXN0aW5nID0gZnVuY3Rpb24ob2JqLCBzd2FnZ2VyLCBjYWxsYmFjaykge1xuICB2YXIgaTtcbiAgdmFyIHByb2Nlc3NlZENvdW50ID0gMDsgICAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbiAgdmFyIHNlbGYgPSB0aGlzOyAgICAgICAgICAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbiAgdmFyIGV4cGVjdGVkQ291bnQgPSBvYmouYXBpcy5sZW5ndGg7XG4gIHZhciBfc3dhZ2dlciA9IHN3YWdnZXI7ICAgLy8ganNoaW50IGlnbm9yZTpsaW5lXG5cbiAgaWYoZXhwZWN0ZWRDb3VudCA9PT0gMCkge1xuICAgIHRoaXMuZmluaXNoKGNhbGxiYWNrLCBzd2FnZ2VyKTtcbiAgfVxuXG4gIGZvcihpID0gMDsgaSA8IGV4cGVjdGVkQ291bnQ7IGkrKykge1xuICAgIHZhciBhcGkgPSBvYmouYXBpc1tpXTtcbiAgICB2YXIgcGF0aCA9IGFwaS5wYXRoO1xuICAgIHZhciBhYnNvbHV0ZVBhdGggPSB0aGlzLmdldEFic29sdXRlUGF0aChvYmouc3dhZ2dlclZlcnNpb24sIHRoaXMuZG9jTG9jYXRpb24sIHBhdGgpO1xuXG4gICAgaWYoYXBpLmRlc2NyaXB0aW9uKSB7XG4gICAgICBzd2FnZ2VyLnRhZ3MgPSBzd2FnZ2VyLnRhZ3MgfHwgW107XG4gICAgICBzd2FnZ2VyLnRhZ3MucHVzaCh7XG4gICAgICAgIG5hbWUgOiB0aGlzLmV4dHJhY3RUYWcoYXBpLnBhdGgpLFxuICAgICAgICBkZXNjcmlwdGlvbiA6IGFwaS5kZXNjcmlwdGlvbiB8fCAnJ1xuICAgICAgfSk7XG4gICAgfVxuICAgIHZhciBodHRwID0ge1xuICAgICAgdXJsOiBhYnNvbHV0ZVBhdGgsXG4gICAgICBoZWFkZXJzOiB7YWNjZXB0OiAnYXBwbGljYXRpb24vanNvbid9LFxuICAgICAgb246IHt9LFxuICAgICAgbWV0aG9kOiAnZ2V0J1xuICAgIH07XG4gICAgLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuICAgIGh0dHAub24ucmVzcG9uc2UgPSBmdW5jdGlvbihkYXRhKSB7XG4gICAgICBwcm9jZXNzZWRDb3VudCArPSAxO1xuICAgICAgdmFyIG9iaiA9IGRhdGEub2JqO1xuICAgICAgaWYob2JqKSB7XG4gICAgICAgIHNlbGYuZGVjbGFyYXRpb24ob2JqLCBfc3dhZ2dlcik7XG4gICAgICB9XG4gICAgICBpZihwcm9jZXNzZWRDb3VudCA9PT0gZXhwZWN0ZWRDb3VudCkge1xuICAgICAgICBzZWxmLmZpbmlzaChjYWxsYmFjaywgX3N3YWdnZXIpO1xuICAgICAgfVxuICAgIH07XG4gICAgaHR0cC5vbi5lcnJvciA9IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZGF0YSk7XG4gICAgICBwcm9jZXNzZWRDb3VudCArPSAxO1xuICAgICAgaWYocHJvY2Vzc2VkQ291bnQgPT09IGV4cGVjdGVkQ291bnQpIHtcbiAgICAgICAgc2VsZi5maW5pc2goY2FsbGJhY2ssIF9zd2FnZ2VyKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIC8qIGpzaGludCBpZ25vcmU6ZW5kICovXG5cbiAgICBpZih0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zICYmIHR5cGVvZiB0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zLmFwcGx5ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zLmFwcGx5KGh0dHApO1xuICAgIH1cblxuICAgIG5ldyBTd2FnZ2VySHR0cCgpLmV4ZWN1dGUoaHR0cCk7XG4gIH1cbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5nZXRBYnNvbHV0ZVBhdGggPSBmdW5jdGlvbih2ZXJzaW9uLCBkb2NMb2NhdGlvbiwgcGF0aCkgIHtcbiAgaWYodmVyc2lvbiA9PT0gJzEuMCcpIHtcbiAgICBpZihkb2NMb2NhdGlvbi5lbmRzV2l0aCgnLmpzb24nKSkge1xuICAgICAgLy8gZ2V0IHJvb3QgcGF0aFxuICAgICAgdmFyIHBvcyA9IGRvY0xvY2F0aW9uLmxhc3RJbmRleE9mKCcvJyk7XG4gICAgICBpZihwb3MgPiAwKSB7XG4gICAgICAgIGRvY0xvY2F0aW9uID0gZG9jTG9jYXRpb24uc3Vic3RyaW5nKDAsIHBvcyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIGxvY2F0aW9uID0gZG9jTG9jYXRpb247XG4gIGlmKHBhdGguaW5kZXhPZignaHR0cDovLycpID09PSAwIHx8IHBhdGguaW5kZXhPZignaHR0cHM6Ly8nKSA9PT0gMCkge1xuICAgIGxvY2F0aW9uID0gcGF0aDtcbiAgfVxuICBlbHNlIHtcbiAgICBpZihkb2NMb2NhdGlvbi5lbmRzV2l0aCgnLycpKSB7XG4gICAgICBsb2NhdGlvbiA9IGRvY0xvY2F0aW9uLnN1YnN0cmluZygwLCBkb2NMb2NhdGlvbi5sZW5ndGggLSAxKTtcbiAgICB9XG4gICAgbG9jYXRpb24gKz0gcGF0aDtcbiAgfVxuICBsb2NhdGlvbiA9IGxvY2F0aW9uLnJlcGxhY2UoJ3tmb3JtYXR9JywgJ2pzb24nKTtcbiAgcmV0dXJuIGxvY2F0aW9uO1xufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLnNlY3VyaXR5RGVmaW5pdGlvbnMgPSBmdW5jdGlvbihvYmosIHN3YWdnZXIpIHtcbiAgaWYob2JqLmF1dGhvcml6YXRpb25zKSB7XG4gICAgdmFyIG5hbWU7XG4gICAgZm9yKG5hbWUgaW4gb2JqLmF1dGhvcml6YXRpb25zKSB7XG4gICAgICB2YXIgaXNWYWxpZCA9IGZhbHNlO1xuICAgICAgdmFyIHNlY3VyaXR5RGVmaW5pdGlvbiA9IHt9O1xuICAgICAgdmFyIGRlZmluaXRpb24gPSBvYmouYXV0aG9yaXphdGlvbnNbbmFtZV07XG4gICAgICBpZihkZWZpbml0aW9uLnR5cGUgPT09ICdhcGlLZXknKSB7XG4gICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi50eXBlID0gJ2FwaUtleSc7XG4gICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi5pbiA9IGRlZmluaXRpb24ucGFzc0FzO1xuICAgICAgICBzZWN1cml0eURlZmluaXRpb24ubmFtZSA9IGRlZmluaXRpb24ua2V5bmFtZSB8fCBuYW1lO1xuICAgICAgICBpc1ZhbGlkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYoZGVmaW5pdGlvbi50eXBlID09PSAnb2F1dGgyJykge1xuICAgICAgICB2YXIgZXhpc3RpbmdTY29wZXMgPSBkZWZpbml0aW9uLnNjb3BlcyB8fCBbXTtcbiAgICAgICAgdmFyIHNjb3BlcyA9IHt9O1xuICAgICAgICB2YXIgaTtcbiAgICAgICAgZm9yKGkgaW4gZXhpc3RpbmdTY29wZXMpIHtcbiAgICAgICAgICB2YXIgc2NvcGUgPSBleGlzdGluZ1Njb3Blc1tpXTtcbiAgICAgICAgICBzY29wZXNbc2NvcGUuc2NvcGVdID0gc2NvcGUuZGVzY3JpcHRpb247XG4gICAgICAgIH1cbiAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLnR5cGUgPSAnb2F1dGgyJztcbiAgICAgICAgaWYoaSA+IDApIHtcbiAgICAgICAgICBzZWN1cml0eURlZmluaXRpb24uc2NvcGVzID0gc2NvcGVzO1xuICAgICAgICB9XG4gICAgICAgIGlmKGRlZmluaXRpb24uZ3JhbnRUeXBlcykge1xuICAgICAgICAgIGlmKGRlZmluaXRpb24uZ3JhbnRUeXBlcy5pbXBsaWNpdCkge1xuICAgICAgICAgICAgdmFyIGltcGxpY2l0ID0gZGVmaW5pdGlvbi5ncmFudFR5cGVzLmltcGxpY2l0O1xuICAgICAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLmZsb3cgPSAnaW1wbGljaXQnO1xuICAgICAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLmF1dGhvcml6YXRpb25VcmwgPSBpbXBsaWNpdC5sb2dpbkVuZHBvaW50O1xuICAgICAgICAgICAgaXNWYWxpZCA9IHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cbiAgICAgICAgICBpZihkZWZpbml0aW9uLmdyYW50VHlwZXNbJ2F1dGhvcml6YXRpb25fY29kZSddKSB7XG4gICAgICAgICAgICBpZighc2VjdXJpdHlEZWZpbml0aW9uLmZsb3cpIHtcbiAgICAgICAgICAgICAgLy8gY2Fubm90IHNldCBpZiBmbG93IGlzIGFscmVhZHkgZGVmaW5lZFxuICAgICAgICAgICAgICB2YXIgYXV0aENvZGUgPSBkZWZpbml0aW9uLmdyYW50VHlwZXNbJ2F1dGhvcml6YXRpb25fY29kZSddO1xuICAgICAgICAgICAgICBzZWN1cml0eURlZmluaXRpb24uZmxvdyA9ICdhY2Nlc3NDb2RlJztcbiAgICAgICAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLmF1dGhvcml6YXRpb25VcmwgPSBhdXRoQ29kZS50b2tlblJlcXVlc3RFbmRwb2ludC51cmw7XG4gICAgICAgICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi50b2tlblVybCA9IGF1dGhDb2RlLnRva2VuRW5kcG9pbnQudXJsO1xuICAgICAgICAgICAgICBpc1ZhbGlkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgLyoganNoaW50IGlnbm9yZTplbmQgKi9cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYoaXNWYWxpZCkge1xuICAgICAgICBzd2FnZ2VyLnNlY3VyaXR5RGVmaW5pdGlvbnMgPSBzd2FnZ2VyLnNlY3VyaXR5RGVmaW5pdGlvbnMgfHwge307XG4gICAgICAgIHN3YWdnZXIuc2VjdXJpdHlEZWZpbml0aW9uc1tuYW1lXSA9IHNlY3VyaXR5RGVmaW5pdGlvbjtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5hcGlJbmZvID0gZnVuY3Rpb24ob2JqLCBzd2FnZ2VyKSB7XG4gIC8vIGluZm8gc2VjdGlvblxuICBpZihvYmouaW5mbykge1xuICAgIHZhciBpbmZvID0gb2JqLmluZm87XG4gICAgc3dhZ2dlci5pbmZvID0ge307XG5cbiAgICBpZihpbmZvLmNvbnRhY3QpIHtcbiAgICAgIHN3YWdnZXIuaW5mby5jb250YWN0ID0ge307XG4gICAgICBzd2FnZ2VyLmluZm8uY29udGFjdC5lbWFpbCA9IGluZm8uY29udGFjdDtcbiAgICB9XG4gICAgaWYoaW5mby5kZXNjcmlwdGlvbikge1xuICAgICAgc3dhZ2dlci5pbmZvLmRlc2NyaXB0aW9uID0gaW5mby5kZXNjcmlwdGlvbjtcbiAgICB9XG4gICAgaWYoaW5mby50aXRsZSkge1xuICAgICAgc3dhZ2dlci5pbmZvLnRpdGxlID0gaW5mby50aXRsZTtcbiAgICB9XG4gICAgaWYoaW5mby50ZXJtc09mU2VydmljZVVybCkge1xuICAgICAgc3dhZ2dlci5pbmZvLnRlcm1zT2ZTZXJ2aWNlID0gaW5mby50ZXJtc09mU2VydmljZVVybDtcbiAgICB9XG4gICAgaWYoaW5mby5saWNlbnNlIHx8IGluZm8ubGljZW5zZVVybCkge1xuICAgICAgc3dhZ2dlci5saWNlbnNlID0ge307XG4gICAgICBpZihpbmZvLmxpY2Vuc2UpIHtcbiAgICAgICAgc3dhZ2dlci5saWNlbnNlLm5hbWUgPSBpbmZvLmxpY2Vuc2U7XG4gICAgICB9XG4gICAgICBpZihpbmZvLmxpY2Vuc2VVcmwpIHtcbiAgICAgICAgc3dhZ2dlci5saWNlbnNlLnVybCA9IGluZm8ubGljZW5zZVVybDtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgZWxzZSB7XG4gICAgdGhpcy53YXJuaW5ncy5wdXNoKCdtaXNzaW5nIGluZm8gc2VjdGlvbicpO1xuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuZmluaXNoID0gZnVuY3Rpb24gKGNhbGxiYWNrLCBvYmopIHtcbiAgY2FsbGJhY2sob2JqKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBfID0ge1xuICBjbG9uZURlZXA6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9jbG9uZURlZXAnKSxcbiAgZm9yRWFjaDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2ZvckVhY2gnKSxcbiAgaW5kZXhPZjogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9hcnJheS9pbmRleE9mJyksXG4gIGlzQXJyYXk6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc0FycmF5JyksXG4gIGlzUGxhaW5PYmplY3Q6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc1BsYWluT2JqZWN0JyksXG4gIGlzU3RyaW5nOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNTdHJpbmcnKSxcbiAgaXNVbmRlZmluZWQ6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc1VuZGVmaW5lZCcpLFxuICBrZXlzOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L29iamVjdC9rZXlzJyksXG4gIG1hcDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL21hcCcpXG59O1xudmFyIGhlbHBlcnMgPSByZXF1aXJlKCcuLi9oZWxwZXJzJyk7XG52YXIganN5YW1sID0gcmVxdWlyZSgnanMteWFtbCcpO1xuXG52YXIgTW9kZWwgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChuYW1lLCBkZWZpbml0aW9uLCBtb2RlbHMsIG1vZGVsUHJvcGVydHlNYWNybykge1xuICB0aGlzLmRlZmluaXRpb24gPSBkZWZpbml0aW9uIHx8IHt9O1xuICB0aGlzLmlzQXJyYXkgPSBkZWZpbml0aW9uLnR5cGUgPT09ICdhcnJheSc7XG4gIHRoaXMubW9kZWxzID0gbW9kZWxzIHx8IHt9O1xuICB0aGlzLm5hbWUgPSBkZWZpbml0aW9uLnRpdGxlIHx8IG5hbWUgfHwgJ0lubGluZSBNb2RlbCc7XG4gIHRoaXMubW9kZWxQcm9wZXJ0eU1hY3JvID0gbW9kZWxQcm9wZXJ0eU1hY3JvIHx8IGZ1bmN0aW9uIChwcm9wZXJ0eSkge1xuICAgIHJldHVybiBwcm9wZXJ0eS5kZWZhdWx0O1xuICB9O1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxudmFyIHNjaGVtYVRvSFRNTCA9IGZ1bmN0aW9uIChuYW1lLCBzY2hlbWEsIG1vZGVscywgbW9kZWxQcm9wZXJ0eU1hY3JvKSB7XG4gIHZhciBzdHJvbmdPcGVuID0gJzxzcGFuIGNsYXNzPVwic3Ryb25nXCI+JztcbiAgdmFyIHN0cm9uZ0Nsb3NlID0gJzwvc3Bhbj4nO1xuICB2YXIgcmVmZXJlbmNlcyA9IHt9O1xuICB2YXIgc2Vlbk1vZGVscyA9IFtdO1xuICB2YXIgaW5saW5lTW9kZWxzID0gMDtcbiAgdmFyIGFkZFJlZmVyZW5jZSA9IGZ1bmN0aW9uIChzY2hlbWEsIG5hbWUsIHNraXBSZWYpIHtcbiAgICB2YXIgbW9kZWxOYW1lID0gbmFtZTtcbiAgICB2YXIgbW9kZWw7XG5cbiAgICBpZiAoc2NoZW1hLiRyZWYpIHtcbiAgICAgIG1vZGVsTmFtZSA9IHNjaGVtYS50aXRsZSB8fCBoZWxwZXJzLnNpbXBsZVJlZihzY2hlbWEuJHJlZik7XG4gICAgICBtb2RlbCA9IG1vZGVsc1ttb2RlbE5hbWVdO1xuICAgIH0gZWxzZSBpZiAoXy5pc1VuZGVmaW5lZChuYW1lKSkge1xuICAgICAgbW9kZWxOYW1lID0gc2NoZW1hLnRpdGxlIHx8ICdJbmxpbmUgTW9kZWwgJyArICgrK2lubGluZU1vZGVscyk7XG4gICAgICBtb2RlbCA9IG5ldyBNb2RlbChtb2RlbE5hbWUsIHNjaGVtYSwgbW9kZWxzLCBtb2RlbFByb3BlcnR5TWFjcm8pO1xuICAgIH1cblxuICAgIGlmIChza2lwUmVmICE9PSB0cnVlKSB7XG4gICAgICByZWZlcmVuY2VzW21vZGVsTmFtZV0gPSBfLmlzVW5kZWZpbmVkKG1vZGVsKSA/IHt9IDogbW9kZWwuZGVmaW5pdGlvbjtcbiAgICB9XG5cbiAgICByZXR1cm4gbW9kZWxOYW1lO1xuICB9O1xuXG4gIHZhciBwcmltaXRpdmVUb0hUTUwgPSBmdW5jdGlvbiAoc2NoZW1hKSB7XG4gICAgdmFyIGh0bWwgPSAnPHNwYW4gY2xhc3M9XCJwcm9wVHlwZVwiPic7XG4gICAgdmFyIHR5cGUgPSBzY2hlbWEudHlwZSB8fCAnb2JqZWN0JztcblxuICAgIGlmIChzY2hlbWEuJHJlZikge1xuICAgICAgaHRtbCArPSBhZGRSZWZlcmVuY2Uoc2NoZW1hLCBoZWxwZXJzLnNpbXBsZVJlZihzY2hlbWEuJHJlZikpO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGlmICghXy5pc1VuZGVmaW5lZChzY2hlbWEucHJvcGVydGllcykpIHtcbiAgICAgICAgaHRtbCArPSBhZGRSZWZlcmVuY2Uoc2NoZW1hKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGh0bWwgKz0gJ29iamVjdCc7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnYXJyYXknKSB7XG4gICAgICBodG1sICs9ICdBcnJheVsnO1xuXG4gICAgICBpZiAoXy5pc0FycmF5KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgaHRtbCArPSBfLm1hcChzY2hlbWEuaXRlbXMsIGFkZFJlZmVyZW5jZSkuam9pbignLCcpO1xuICAgICAgfSBlbHNlIGlmIChfLmlzUGxhaW5PYmplY3Qoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICBpZiAoXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMuJHJlZikpIHtcbiAgICAgICAgICBpZiAoIV8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zLnR5cGUpICYmIF8uaW5kZXhPZihbJ2FycmF5JywgJ29iamVjdCddLCBzY2hlbWEuaXRlbXMudHlwZSkgPT09IC0xKSB7XG4gICAgICAgICAgICBodG1sICs9IHNjaGVtYS5pdGVtcy50eXBlO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBodG1sICs9IGFkZFJlZmVyZW5jZShzY2hlbWEuaXRlbXMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBodG1sICs9IGFkZFJlZmVyZW5jZShzY2hlbWEuaXRlbXMsIGhlbHBlcnMuc2ltcGxlUmVmKHNjaGVtYS5pdGVtcy4kcmVmKSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGhlbHBlcnMubG9nKCdBcnJheSB0eXBlXFwncyBcXCdpdGVtc1xcJyBzY2hlbWEgaXMgbm90IGFuIGFycmF5IG9yIGFuIG9iamVjdCwgY2Fubm90IHByb2Nlc3MnKTtcbiAgICAgICAgaHRtbCArPSAnb2JqZWN0JztcbiAgICAgIH1cblxuICAgICAgaHRtbCArPSAnXSc7XG4gICAgfSBlbHNlIHtcbiAgICAgIGh0bWwgKz0gc2NoZW1hLnR5cGU7XG4gICAgfVxuXG4gICAgaHRtbCArPSAnPC9zcGFuPic7XG5cbiAgICByZXR1cm4gaHRtbDtcbiAgfTtcbiAgdmFyIHByaW1pdGl2ZVRvT3B0aW9uc0hUTUwgPSBmdW5jdGlvbiAoc2NoZW1hLCBodG1sKSB7XG4gICAgdmFyIG9wdGlvbnMgPSAnJztcbiAgICB2YXIgdHlwZSA9IHNjaGVtYS50eXBlIHx8ICdvYmplY3QnO1xuICAgIHZhciBpc0FycmF5ID0gdHlwZSA9PT0gJ2FycmF5JztcblxuICAgIGlmIChpc0FycmF5KSB7XG4gICAgICBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5pdGVtcykgJiYgIV8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zLnR5cGUpKSB7XG4gICAgICAgIHR5cGUgPSBzY2hlbWEuaXRlbXMudHlwZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHR5cGUgPSAnb2JqZWN0JztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIV8uaXNVbmRlZmluZWQoc2NoZW1hLmRlZmF1bHQpKSB7XG4gICAgICBvcHRpb25zICs9IGhlbHBlcnMub3B0aW9uSHRtbCgnRGVmYXVsdCcsIHNjaGVtYS5kZWZhdWx0KTtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgaWYgKHNjaGVtYS5taW5MZW5ndGgpIHtcbiAgICAgICAgb3B0aW9ucyArPSBoZWxwZXJzLm9wdGlvbkh0bWwoJ01pbi4gTGVuZ3RoJywgc2NoZW1hLm1pbkxlbmd0aCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2hlbWEubWF4TGVuZ3RoKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gaGVscGVycy5vcHRpb25IdG1sKCdNYXguIExlbmd0aCcsIHNjaGVtYS5tYXhMZW5ndGgpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLnBhdHRlcm4pIHtcbiAgICAgICAgb3B0aW9ucyArPSBoZWxwZXJzLm9wdGlvbkh0bWwoJ1JlZy4gRXhwLicsIHNjaGVtYS5wYXR0ZXJuKTtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2ludGVnZXInOlxuICAgIGNhc2UgJ251bWJlcic6XG4gICAgICBpZiAoc2NoZW1hLm1pbmltdW0pIHtcbiAgICAgICAgb3B0aW9ucyArPSBoZWxwZXJzLm9wdGlvbkh0bWwoJ01pbi4gVmFsdWUnLCBzY2hlbWEubWluaW11bSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2hlbWEuZXhjbHVzaXZlTWluaW11bSkge1xuICAgICAgICBvcHRpb25zICs9IGhlbHBlcnMub3B0aW9uSHRtbCgnRXhjbHVzaXZlIE1pbi4nLCAndHJ1ZScpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLm1heGltdW0pIHtcbiAgICAgICAgb3B0aW9ucyArPSBoZWxwZXJzLm9wdGlvbkh0bWwoJ01heC4gVmFsdWUnLCBzY2hlbWEubWF4aW11bSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2hlbWEuZXhjbHVzaXZlTWF4aW11bSkge1xuICAgICAgICBvcHRpb25zICs9IGhlbHBlcnMub3B0aW9uSHRtbCgnRXhjbHVzaXZlIE1heC4nLCAndHJ1ZScpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLm11bHRpcGxlT2YpIHtcbiAgICAgICAgb3B0aW9ucyArPSBoZWxwZXJzLm9wdGlvbkh0bWwoJ011bHRpcGxlIE9mJywgc2NoZW1hLm11bHRpcGxlT2YpO1xuICAgICAgfVxuXG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBpZiAoaXNBcnJheSkge1xuICAgICAgaWYgKHNjaGVtYS5taW5JdGVtcykge1xuICAgICAgICBvcHRpb25zICs9IGhlbHBlcnMub3B0aW9uSHRtbCgnTWluLiBJdGVtcycsIHNjaGVtYS5taW5JdGVtcyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2hlbWEubWF4SXRlbXMpIHtcbiAgICAgICAgb3B0aW9ucyArPSBoZWxwZXJzLm9wdGlvbkh0bWwoJ01heC4gSXRlbXMnLCBzY2hlbWEubWF4SXRlbXMpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLnVuaXF1ZUl0ZW1zKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gaGVscGVycy5vcHRpb25IdG1sKCdVbmlxdWUgSXRlbXMnLCAndHJ1ZScpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLmNvbGxlY3Rpb25Gb3JtYXQpIHtcbiAgICAgICAgb3B0aW9ucyArPSBoZWxwZXJzLm9wdGlvbkh0bWwoJ0NvbGwuIEZvcm1hdCcsIHNjaGVtYS5jb2xsZWN0aW9uRm9ybWF0KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMpKSB7XG4gICAgICBpZiAoXy5pc0FycmF5KHNjaGVtYS5lbnVtKSkge1xuICAgICAgICB2YXIgZW51bVN0cmluZztcblxuICAgICAgICBpZiAodHlwZSA9PT0gJ251bWJlcicgfHwgdHlwZSA9PT0gJ2ludGVnZXInKSB7XG4gICAgICAgICAgZW51bVN0cmluZyA9IHNjaGVtYS5lbnVtLmpvaW4oJywgJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZW51bVN0cmluZyA9ICdcIicgKyBzY2hlbWEuZW51bS5qb2luKCdcIiwgXCInKSArICdcIic7XG4gICAgICAgIH1cblxuICAgICAgICBvcHRpb25zICs9IGhlbHBlcnMub3B0aW9uSHRtbCgnRW51bScsIGVudW1TdHJpbmcpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChvcHRpb25zLmxlbmd0aCA+IDApIHtcbiAgICAgIGh0bWwgPSAnPHNwYW4gY2xhc3M9XCJwcm9wV3JhcFwiPicgKyBodG1sICsgJzx0YWJsZSBjbGFzcz1cIm9wdGlvbnNXcmFwcGVyXCI+PHRyPjx0aCBjb2xzcGFuPVwiMlwiPicgKyB0eXBlICsgJzwvdGg+PC90cj4nICsgb3B0aW9ucyArICc8L3RhYmxlPjwvc3Bhbj4nO1xuICAgIH1cblxuICAgIHJldHVybiBodG1sO1xuICB9O1xuICB2YXIgcHJvY2Vzc01vZGVsID0gZnVuY3Rpb24gKHNjaGVtYSwgbmFtZSkge1xuICAgIHZhciB0eXBlID0gc2NoZW1hLnR5cGUgfHwgJ29iamVjdCc7XG4gICAgdmFyIGlzQXJyYXkgPSBzY2hlbWEudHlwZSA9PT0gJ2FycmF5JztcbiAgICB2YXIgaHRtbCA9IHN0cm9uZ09wZW4gKyBuYW1lICsgJyAnICsgKGlzQXJyYXkgPyAnWycgOiAneycpICsgc3Ryb25nQ2xvc2U7XG5cbiAgICBpZiAobmFtZSkge1xuICAgICAgc2Vlbk1vZGVscy5wdXNoKG5hbWUpO1xuICAgIH1cblxuICAgIGlmIChpc0FycmF5KSB7XG4gICAgICBpZiAoXy5pc0FycmF5KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgaHRtbCArPSAnPGRpdj4nICsgXy5tYXAoc2NoZW1hLml0ZW1zLCBmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgIHZhciB0eXBlID0gaXRlbS50eXBlIHx8ICdvYmplY3QnO1xuXG4gICAgICAgICAgaWYgKF8uaXNVbmRlZmluZWQoaXRlbS4kcmVmKSkge1xuICAgICAgICAgICAgaWYgKF8uaW5kZXhPZihbJ2FycmF5JywgJ29iamVjdCddLCB0eXBlKSA+IC0xKSB7XG4gICAgICAgICAgICAgIGlmICh0eXBlID09PSAnb2JqZWN0JyAmJiBfLmlzVW5kZWZpbmVkKGl0ZW0ucHJvcGVydGllcykpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gJ29iamVjdCc7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFkZFJlZmVyZW5jZShpdGVtKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHByaW1pdGl2ZVRvT3B0aW9uc0hUTUwoaXRlbSwgdHlwZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBhZGRSZWZlcmVuY2UoaXRlbSwgaGVscGVycy5zaW1wbGVSZWYoaXRlbS4kcmVmKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KS5qb2luKCcsPC9kaXY+PGRpdj4nKTtcbiAgICAgIH0gZWxzZSBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgaWYgKF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zLiRyZWYpKSB7XG4gICAgICAgICAgaWYgKF8uaW5kZXhPZihbJ2FycmF5JywgJ29iamVjdCddLCBzY2hlbWEuaXRlbXMudHlwZSB8fCAnb2JqZWN0JykgPiAtMSkge1xuICAgICAgICAgICAgaWYgKChfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcy50eXBlKSB8fCBzY2hlbWEuaXRlbXMudHlwZSA9PT0gJ29iamVjdCcpICYmIF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zLnByb3BlcnRpZXMpKSB7XG4gICAgICAgICAgICAgIGh0bWwgKz0gJzxkaXY+b2JqZWN0PC9kaXY+JztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGh0bWwgKz0gJzxkaXY+JyArIGFkZFJlZmVyZW5jZShzY2hlbWEuaXRlbXMpICsgJzwvZGl2Pic7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGh0bWwgKz0gJzxkaXY+JyArIHByaW1pdGl2ZVRvT3B0aW9uc0hUTUwoc2NoZW1hLml0ZW1zLCBzY2hlbWEuaXRlbXMudHlwZSkgKyAnPC9kaXY+JztcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaHRtbCArPSAnPGRpdj4nICsgYWRkUmVmZXJlbmNlKHNjaGVtYS5pdGVtcywgaGVscGVycy5zaW1wbGVSZWYoc2NoZW1hLml0ZW1zLiRyZWYpKSArICc8L2Rpdj4nO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBoZWxwZXJzLmxvZygnQXJyYXkgdHlwZVxcJ3MgXFwnaXRlbXNcXCcgcHJvcGVydHkgaXMgbm90IGFuIGFycmF5IG9yIGFuIG9iamVjdCwgY2Fubm90IHByb2Nlc3MnKTtcbiAgICAgICAgaHRtbCArPSAnPGRpdj5vYmplY3Q8L2Rpdj4nO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoc2NoZW1hLiRyZWYpIHtcbiAgICAgICAgaHRtbCArPSAnPGRpdj4nICsgYWRkUmVmZXJlbmNlKHNjaGVtYSwgbmFtZSkgKyAnPC9kaXY+JztcbiAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgaHRtbCArPSAnPGRpdj4nO1xuXG4gICAgICAgIGlmIChfLmlzUGxhaW5PYmplY3Qoc2NoZW1hLnByb3BlcnRpZXMpKSB7XG4gICAgICAgICAgaHRtbCArPSBfLm1hcChzY2hlbWEucHJvcGVydGllcywgZnVuY3Rpb24gKHByb3BlcnR5LCBuYW1lKSB7XG4gICAgICAgICAgICB2YXIgcHJvcGVydHlJc1JlcXVpcmVkID0gKF8uaW5kZXhPZihzY2hlbWEucmVxdWlyZWQsIG5hbWUpID49IDApO1xuICAgICAgICAgICAgdmFyIGNQcm9wZXJ0eSA9IF8uY2xvbmVEZWVwKHByb3BlcnR5KTtcblxuICAgICAgICAgICAgdmFyIHJlcXVpcmVkQ2xhc3MgPSBwcm9wZXJ0eUlzUmVxdWlyZWQgPyAncmVxdWlyZWQnIDogJyc7XG4gICAgICAgICAgICB2YXIgaHRtbCA9ICc8c3BhbiBjbGFzcz1cInByb3BOYW1lICcgKyByZXF1aXJlZENsYXNzICsgJ1wiPicgKyBuYW1lICsgJzwvc3Bhbj4gKCc7XG4gICAgICAgICAgICB2YXIgbW9kZWw7XG5cbiAgICAgICAgICAgIC8vIEFsbG93IG1hY3JvIHRvIHNldCB0aGUgZGVmYXVsdCB2YWx1ZVxuICAgICAgICAgICAgY1Byb3BlcnR5LmRlZmF1bHQgPSBtb2RlbFByb3BlcnR5TWFjcm8oY1Byb3BlcnR5KTtcblxuICAgICAgICAgICAgLy8gUmVzb2x2ZSB0aGUgc2NoZW1hIChIYW5kbGUgbmVzdGVkIHNjaGVtYXMpXG4gICAgICAgICAgICBjUHJvcGVydHkgPSBoZWxwZXJzLnJlc29sdmVTY2hlbWEoY1Byb3BlcnR5KTtcblxuICAgICAgICAgICAgLy8gV2UgbmVlZCB0byBoYW5kbGUgcHJvcGVydHkgcmVmZXJlbmNlcyB0byBwcmltaXRpdmVzIChJc3N1ZSAzMzkpXG4gICAgICAgICAgICBpZiAoIV8uaXNVbmRlZmluZWQoY1Byb3BlcnR5LiRyZWYpKSB7XG4gICAgICAgICAgICAgIG1vZGVsID0gbW9kZWxzW2hlbHBlcnMuc2ltcGxlUmVmKGNQcm9wZXJ0eS4kcmVmKV07XG5cbiAgICAgICAgICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKG1vZGVsKSAmJiBfLmluZGV4T2YoW3VuZGVmaW5lZCwgJ2FycmF5JywgJ29iamVjdCddLCBtb2RlbC5kZWZpbml0aW9uLnR5cGUpID09PSAtMSkge1xuICAgICAgICAgICAgICAgIC8vIFVzZSByZWZlcmVuY2VkIHNjaGVtYVxuICAgICAgICAgICAgICAgIGNQcm9wZXJ0eSA9IGhlbHBlcnMucmVzb2x2ZVNjaGVtYShtb2RlbC5kZWZpbml0aW9uKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBodG1sICs9IHByaW1pdGl2ZVRvSFRNTChjUHJvcGVydHkpO1xuXG4gICAgICAgICAgICBpZighcHJvcGVydHlJc1JlcXVpcmVkKSB7XG4gICAgICAgICAgICAgIGh0bWwgKz0gJywgPHNwYW4gY2xhc3M9XCJwcm9wT3B0S2V5XCI+b3B0aW9uYWw8L3NwYW4+JztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaHRtbCArPSAnKSc7XG5cbiAgICAgICAgICAgIGlmICghXy5pc1VuZGVmaW5lZChjUHJvcGVydHkuZGVzY3JpcHRpb24pKSB7XG4gICAgICAgICAgICAgIGh0bWwgKz0gJzogJyArICc8c3BhbiBjbGFzcz1cInByb3BEZXNjXCI+JyArIGNQcm9wZXJ0eS5kZXNjcmlwdGlvbiArICc8L3NwYW4+JztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGNQcm9wZXJ0eS5lbnVtKSB7XG4gICAgICAgICAgICAgIGh0bWwgKz0gJyA9IDxzcGFuIGNsYXNzPVwicHJvcFZhbHNcIj5bXFwnJyArIGNQcm9wZXJ0eS5lbnVtLmpvaW4oJ1xcJywgXFwnJykgKyAnXFwnXTwvc3Bhbj4nO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gcHJpbWl0aXZlVG9PcHRpb25zSFRNTChjUHJvcGVydHksIGh0bWwpO1xuICAgICAgICAgIH0pLmpvaW4oJyw8L2Rpdj48ZGl2PicpO1xuICAgICAgICB9XG5cbiAgICAgICAgaHRtbCArPSAnPC9kaXY+JztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGh0bWwgKz0gJzxkaXY+JyArIHByaW1pdGl2ZVRvT3B0aW9uc0hUTUwoc2NoZW1hLCB0eXBlKSArICc8L2Rpdj4nO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBodG1sICsgc3Ryb25nT3BlbiArIChpc0FycmF5ID8gJ10nIDogJ30nKSArIHN0cm9uZ0Nsb3NlO1xuICB9O1xuXG4gIC8vIFJlc29sdmUgdGhlIHNjaGVtYSAoSGFuZGxlIG5lc3RlZCBzY2hlbWFzKVxuICBzY2hlbWEgPSBoZWxwZXJzLnJlc29sdmVTY2hlbWEoc2NoZW1hKTtcblxuICAvLyBHZW5lcmF0ZSBjdXJyZW50IEhUTUxcbiAgdmFyIGh0bWwgPSBwcm9jZXNzTW9kZWwoc2NoZW1hLCBuYW1lKTtcblxuICAvLyBHZW5lcmF0ZSByZWZlcmVuY2VzIEhUTUxcbiAgd2hpbGUgKF8ua2V5cyhyZWZlcmVuY2VzKS5sZW5ndGggPiAwKSB7XG4gICAgLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuICAgIF8uZm9yRWFjaChyZWZlcmVuY2VzLCBmdW5jdGlvbiAoc2NoZW1hLCBuYW1lKSB7XG4gICAgICB2YXIgc2Vlbk1vZGVsID0gXy5pbmRleE9mKHNlZW5Nb2RlbHMsIG5hbWUpID4gLTE7XG5cbiAgICAgIGRlbGV0ZSByZWZlcmVuY2VzW25hbWVdO1xuXG4gICAgICBpZiAoIXNlZW5Nb2RlbCkge1xuICAgICAgICBzZWVuTW9kZWxzLnB1c2gobmFtZSk7XG5cbiAgICAgICAgaHRtbCArPSAnPGJyIC8+JyArIHByb2Nlc3NNb2RlbChzY2hlbWEsIG5hbWUpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIC8qIGpzaGludCBpZ25vcmU6ZW5kICovXG4gIH1cblxuICByZXR1cm4gaHRtbDtcbn07XG5cbnZhciBzY2hlbWFUb0pTT04gPSBmdW5jdGlvbiAoc2NoZW1hLCBtb2RlbHMsIG1vZGVsc1RvSWdub3JlLCBtb2RlbFByb3BlcnR5TWFjcm8pIHtcbiAgLy8gUmVzb2x2ZSB0aGUgc2NoZW1hIChIYW5kbGUgbmVzdGVkIHNjaGVtYXMpXG4gIHNjaGVtYSA9IGhlbHBlcnMucmVzb2x2ZVNjaGVtYShzY2hlbWEpO1xuXG4gIHZhciB0eXBlID0gc2NoZW1hLnR5cGUgfHwgJ29iamVjdCc7XG4gIHZhciBmb3JtYXQgPSBzY2hlbWEuZm9ybWF0O1xuICB2YXIgbW9kZWw7XG4gIHZhciBvdXRwdXQ7XG5cbiAgaWYgKHNjaGVtYS5leGFtcGxlKSB7XG4gICAgb3V0cHV0ID0gc2NoZW1hLmV4YW1wbGU7XG4gIH0gZWxzZSBpZiAoXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMpICYmIF8uaXNBcnJheShzY2hlbWEuZW51bSkpIHtcbiAgICBvdXRwdXQgPSBzY2hlbWEuZW51bVswXTtcbiAgfVxuXG4gIGlmIChfLmlzVW5kZWZpbmVkKG91dHB1dCkpIHtcbiAgICBpZiAoc2NoZW1hLiRyZWYpIHtcbiAgICAgIG1vZGVsID0gbW9kZWxzW2hlbHBlcnMuc2ltcGxlUmVmKHNjaGVtYS4kcmVmKV07XG5cbiAgICAgIGlmICghXy5pc1VuZGVmaW5lZChtb2RlbCkpIHtcbiAgICAgICAgaWYgKF8uaXNVbmRlZmluZWQobW9kZWxzVG9JZ25vcmVbbW9kZWwubmFtZV0pKSB7XG4gICAgICAgICAgbW9kZWxzVG9JZ25vcmVbbW9kZWwubmFtZV0gPSBtb2RlbDtcbiAgICAgICAgICBvdXRwdXQgPSBzY2hlbWFUb0pTT04obW9kZWwuZGVmaW5pdGlvbiwgbW9kZWxzLCBtb2RlbHNUb0lnbm9yZSwgbW9kZWxQcm9wZXJ0eU1hY3JvKTtcbiAgICAgICAgICBkZWxldGUgbW9kZWxzVG9JZ25vcmVbbW9kZWwubmFtZV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKG1vZGVsLnR5cGUgPT09ICdhcnJheScpIHtcbiAgICAgICAgICAgIG91dHB1dCA9IFtdO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBvdXRwdXQgPSB7fTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKCFfLmlzVW5kZWZpbmVkKHNjaGVtYS5kZWZhdWx0KSkge1xuICAgICAgb3V0cHV0ID0gc2NoZW1hLmRlZmF1bHQ7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgaWYgKGZvcm1hdCA9PT0gJ2RhdGUtdGltZScpIHtcbiAgICAgICAgb3V0cHV0ID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpO1xuICAgICAgfSBlbHNlIGlmIChmb3JtYXQgPT09ICdkYXRlJykge1xuICAgICAgICBvdXRwdXQgPSBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCkuc3BsaXQoJ1QnKVswXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG91dHB1dCA9ICdzdHJpbmcnO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2ludGVnZXInKSB7XG4gICAgICBvdXRwdXQgPSAwO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ251bWJlcicpIHtcbiAgICAgIG91dHB1dCA9IDAuMDtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdib29sZWFuJykge1xuICAgICAgb3V0cHV0ID0gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgICBvdXRwdXQgPSB7fTtcblxuICAgICAgXy5mb3JFYWNoKHNjaGVtYS5wcm9wZXJ0aWVzLCBmdW5jdGlvbiAocHJvcGVydHksIG5hbWUpIHtcbiAgICAgICAgdmFyIGNQcm9wZXJ0eSA9IF8uY2xvbmVEZWVwKHByb3BlcnR5KTtcblxuICAgICAgICAvLyBBbGxvdyBtYWNybyB0byBzZXQgdGhlIGRlZmF1bHQgdmFsdWVcbiAgICAgICAgY1Byb3BlcnR5LmRlZmF1bHQgPSBtb2RlbFByb3BlcnR5TWFjcm8ocHJvcGVydHkpO1xuXG4gICAgICAgIG91dHB1dFtuYW1lXSA9IHNjaGVtYVRvSlNPTihjUHJvcGVydHksIG1vZGVscywgbW9kZWxzVG9JZ25vcmUsIG1vZGVsUHJvcGVydHlNYWNybyk7XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdhcnJheScpIHtcbiAgICAgIG91dHB1dCA9IFtdO1xuXG4gICAgICBpZiAoXy5pc0FycmF5KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgXy5mb3JFYWNoKHNjaGVtYS5pdGVtcywgZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICBvdXRwdXQucHVzaChzY2hlbWFUb0pTT04oaXRlbSwgbW9kZWxzLCBtb2RlbHNUb0lnbm9yZSwgbW9kZWxQcm9wZXJ0eU1hY3JvKSk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmIChfLmlzUGxhaW5PYmplY3Qoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICBvdXRwdXQucHVzaChzY2hlbWFUb0pTT04oc2NoZW1hLml0ZW1zLCBtb2RlbHMsIG1vZGVsc1RvSWdub3JlLCBtb2RlbFByb3BlcnR5TWFjcm8pKTtcbiAgICAgIH0gZWxzZSBpZiAoXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMpKSB7XG4gICAgICAgIG91dHB1dC5wdXNoKHt9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGhlbHBlcnMubG9nKCdBcnJheSB0eXBlXFwncyBcXCdpdGVtc1xcJyBwcm9wZXJ0eSBpcyBub3QgYW4gYXJyYXkgb3IgYW4gb2JqZWN0LCBjYW5ub3QgcHJvY2VzcycpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvdXRwdXQ7XG59O1xuXG5Nb2RlbC5wcm90b3R5cGUuY3JlYXRlSlNPTlNhbXBsZSA9IE1vZGVsLnByb3RvdHlwZS5nZXRTYW1wbGVWYWx1ZSA9IGZ1bmN0aW9uIChtb2RlbHNUb0lnbm9yZSkge1xuICBtb2RlbHNUb0lnbm9yZSA9IG1vZGVsc1RvSWdub3JlIHx8IHt9O1xuXG4gIG1vZGVsc1RvSWdub3JlW3RoaXMubmFtZV0gPSB0aGlzO1xuXG4gIC8vIFJlc3BvbnNlIHN1cHBvcnRcbiAgaWYgKHRoaXMuZXhhbXBsZXMgJiYgXy5pc1BsYWluT2JqZWN0KHRoaXMuZXhhbXBsZXMpICYmIHRoaXMuZXhhbXBsZXNbJ2FwcGxpY2F0aW9uL2pzb24nXSkge1xuICAgIHRoaXMuZGVmaW5pdGlvbi5leGFtcGxlID0gdGhpcy5leGFtcGxlc1snYXBwbGljYXRpb24vanNvbiddO1xuXG4gICAgaWYgKF8uaXNTdHJpbmcodGhpcy5kZWZpbml0aW9uLmV4YW1wbGUpKSB7XG4gICAgICB0aGlzLmRlZmluaXRpb24uZXhhbXBsZSA9IGpzeWFtbC5zYWZlTG9hZCh0aGlzLmRlZmluaXRpb24uZXhhbXBsZSk7XG4gICAgfVxuICB9IGVsc2UgaWYgKCF0aGlzLmRlZmluaXRpb24uZXhhbXBsZSkge1xuICAgIHRoaXMuZGVmaW5pdGlvbi5leGFtcGxlID0gdGhpcy5leGFtcGxlcztcbiAgfVxuXG4gIHJldHVybiBzY2hlbWFUb0pTT04odGhpcy5kZWZpbml0aW9uLCB0aGlzLm1vZGVscywgbW9kZWxzVG9JZ25vcmUsIHRoaXMubW9kZWxQcm9wZXJ0eU1hY3JvKTtcbn07XG5cbk1vZGVsLnByb3RvdHlwZS5nZXRNb2NrU2lnbmF0dXJlID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gc2NoZW1hVG9IVE1MKHRoaXMubmFtZSwgdGhpcy5kZWZpbml0aW9uLCB0aGlzLm1vZGVscywgdGhpcy5tb2RlbFByb3BlcnR5TWFjcm8pO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIF8gPSB7XG4gIGNsb25lRGVlcDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2Nsb25lRGVlcCcpLFxuICBpc1VuZGVmaW5lZDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzVW5kZWZpbmVkJyksXG4gIGlzRW1wdHk6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc0VtcHR5Jylcbn07XG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4uL2hlbHBlcnMnKTtcbnZhciBNb2RlbCA9IHJlcXVpcmUoJy4vbW9kZWwnKTtcbnZhciBTd2FnZ2VySHR0cCA9IHJlcXVpcmUoJy4uL2h0dHAnKTtcblxudmFyIE9wZXJhdGlvbiA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHBhcmVudCwgc2NoZW1lLCBvcGVyYXRpb25JZCwgaHR0cE1ldGhvZCwgcGF0aCwgYXJncywgZGVmaW5pdGlvbnMsIG1vZGVscywgY2xpZW50QXV0aG9yaXphdGlvbnMpIHtcbiAgdmFyIGVycm9ycyA9IFtdO1xuXG4gIHBhcmVudCA9IHBhcmVudCB8fCB7fTtcbiAgYXJncyA9IGFyZ3MgfHwge307XG5cbiAgaWYocGFyZW50ICYmIHBhcmVudC5vcHRpb25zKSB7XG4gICAgdGhpcy5jbGllbnQgPSBwYXJlbnQub3B0aW9ucy5jbGllbnQgfHwgbnVsbDtcbiAgICB0aGlzLnJlc3BvbnNlSW50ZXJjZXB0b3IgPSBwYXJlbnQub3B0aW9ucy5yZXNwb25zZUludGVyY2VwdG9yIHx8IG51bGw7XG4gIH1cbiAgdGhpcy5hdXRob3JpemF0aW9ucyA9IGFyZ3Muc2VjdXJpdHk7XG4gIHRoaXMuYmFzZVBhdGggPSBwYXJlbnQuYmFzZVBhdGggfHwgJy8nO1xuICB0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zID0gY2xpZW50QXV0aG9yaXphdGlvbnM7XG4gIHRoaXMuY29uc3VtZXMgPSBhcmdzLmNvbnN1bWVzIHx8IHBhcmVudC5jb25zdW1lcyB8fCBbJ2FwcGxpY2F0aW9uL2pzb24nXTtcbiAgdGhpcy5wcm9kdWNlcyA9IGFyZ3MucHJvZHVjZXMgfHwgcGFyZW50LnByb2R1Y2VzIHx8IFsnYXBwbGljYXRpb24vanNvbiddO1xuICB0aGlzLmRlcHJlY2F0ZWQgPSBhcmdzLmRlcHJlY2F0ZWQ7XG4gIHRoaXMuZGVzY3JpcHRpb24gPSBhcmdzLmRlc2NyaXB0aW9uO1xuICB0aGlzLmhvc3QgPSBwYXJlbnQuaG9zdCB8fCAnbG9jYWxob3N0JztcbiAgdGhpcy5tZXRob2QgPSAoaHR0cE1ldGhvZCB8fCBlcnJvcnMucHVzaCgnT3BlcmF0aW9uICcgKyBvcGVyYXRpb25JZCArICcgaXMgbWlzc2luZyBtZXRob2QuJykpO1xuICB0aGlzLm1vZGVscyA9IG1vZGVscyB8fCB7fTtcbiAgdGhpcy5uaWNrbmFtZSA9IChvcGVyYXRpb25JZCB8fCBlcnJvcnMucHVzaCgnT3BlcmF0aW9ucyBtdXN0IGhhdmUgYSBuaWNrbmFtZS4nKSk7XG4gIHRoaXMub3BlcmF0aW9uID0gYXJncztcbiAgdGhpcy5vcGVyYXRpb25zID0ge307XG4gIHRoaXMucGFyYW1ldGVycyA9IGFyZ3MgIT09IG51bGwgPyAoYXJncy5wYXJhbWV0ZXJzIHx8IFtdKSA6IHt9O1xuICB0aGlzLnBhcmVudCA9IHBhcmVudDtcbiAgdGhpcy5wYXRoID0gKHBhdGggfHwgZXJyb3JzLnB1c2goJ09wZXJhdGlvbiAnICsgdGhpcy5uaWNrbmFtZSArICcgaXMgbWlzc2luZyBwYXRoLicpKTtcbiAgdGhpcy5yZXNwb25zZXMgPSAoYXJncy5yZXNwb25zZXMgfHwge30pO1xuICB0aGlzLnNjaGVtZSA9IHNjaGVtZSB8fCBwYXJlbnQuc2NoZW1lIHx8ICdodHRwJztcbiAgdGhpcy5zY2hlbWVzID0gcGFyZW50LnNjaGVtZXM7XG4gIHRoaXMuc2VjdXJpdHkgPSBhcmdzLnNlY3VyaXR5O1xuICB0aGlzLnN1bW1hcnkgPSBhcmdzLnN1bW1hcnkgfHwgJyc7XG4gIHRoaXMudHlwZSA9IG51bGw7XG4gIHRoaXMudXNlSlF1ZXJ5ID0gcGFyZW50LnVzZUpRdWVyeTtcbiAgdGhpcy5wYXJhbWV0ZXJNYWNybyA9IHBhcmVudC5wYXJhbWV0ZXJNYWNybyB8fCBmdW5jdGlvbiAocGFyYW1ldGVyKSB7XG4gICAgcmV0dXJuIHBhcmFtZXRlci5kZWZhdWx0O1xuICB9O1xuXG4gIHRoaXMuaW5saW5lTW9kZWxzID0gW107XG5cbiAgaWYgKHR5cGVvZiB0aGlzLmRlcHJlY2F0ZWQgPT09ICdzdHJpbmcnKSB7XG4gICAgc3dpdGNoKHRoaXMuZGVwcmVjYXRlZC50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICBjYXNlICd0cnVlJzogY2FzZSAneWVzJzogY2FzZSAnMSc6IHtcbiAgICAgICAgdGhpcy5kZXByZWNhdGVkID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGNhc2UgJ2ZhbHNlJzogY2FzZSAnbm8nOiBjYXNlICcwJzogY2FzZSBudWxsOiB7XG4gICAgICAgIHRoaXMuZGVwcmVjYXRlZCA9IGZhbHNlO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgZGVmYXVsdDogdGhpcy5kZXByZWNhdGVkID0gQm9vbGVhbih0aGlzLmRlcHJlY2F0ZWQpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBpLCBtb2RlbDtcblxuICBpZiAoZGVmaW5pdGlvbnMpIHtcbiAgICAvLyBhZGQgdG8gZ2xvYmFsIG1vZGVsc1xuICAgIHZhciBrZXk7XG5cbiAgICBmb3IgKGtleSBpbiBkZWZpbml0aW9ucykge1xuICAgICAgbW9kZWwgPSBuZXcgTW9kZWwoa2V5LCBkZWZpbml0aW9uc1trZXldLCB0aGlzLm1vZGVscywgcGFyZW50Lm1vZGVsUHJvcGVydHlNYWNybyk7XG5cbiAgICAgIGlmIChtb2RlbCkge1xuICAgICAgICB0aGlzLm1vZGVsc1trZXldID0gbW9kZWw7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZm9yIChpID0gMDsgaSA8IHRoaXMucGFyYW1ldGVycy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwYXJhbSA9IHRoaXMucGFyYW1ldGVyc1tpXTtcblxuICAgIC8vIEFsbG93IG1hY3JvIHRvIHNldCB0aGUgZGVmYXVsdCB2YWx1ZVxuICAgIHBhcmFtLmRlZmF1bHQgPSB0aGlzLnBhcmFtZXRlck1hY3JvKHBhcmFtKTtcblxuICAgIGlmIChwYXJhbS50eXBlID09PSAnYXJyYXknKSB7XG4gICAgICBwYXJhbS5pc0xpc3QgPSB0cnVlO1xuICAgICAgcGFyYW0uYWxsb3dNdWx0aXBsZSA9IHRydWU7XG4gICAgICAvLyB0aGUgZW51bSBjYW4gYmUgZGVmaW5lZCBhdCB0aGUgaXRlbXMgbGV2ZWxcbiAgICAgIGlmIChwYXJhbS5pdGVtcyAmJiBwYXJhbS5pdGVtcy5lbnVtKSB7XG4gICAgICAgIHBhcmFtWydlbnVtJ10gPSBwYXJhbS5pdGVtcy5lbnVtO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBpbm5lclR5cGUgPSB0aGlzLmdldFR5cGUocGFyYW0pO1xuXG4gICAgaWYgKGlubmVyVHlwZSAmJiBpbm5lclR5cGUudG9TdHJpbmcoKS50b0xvd2VyQ2FzZSgpID09PSAnYm9vbGVhbicpIHtcbiAgICAgIHBhcmFtLmFsbG93YWJsZVZhbHVlcyA9IHt9O1xuICAgICAgcGFyYW0uaXNMaXN0ID0gdHJ1ZTtcbiAgICAgIHBhcmFtWydlbnVtJ10gPSBbdHJ1ZSwgZmFsc2VdOyAvLyB1c2UgYWN0dWFsIHByaW1pdGl2ZXNcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHBhcmFtWydlbnVtJ10gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB2YXIgaWQ7XG5cbiAgICAgIHBhcmFtLmFsbG93YWJsZVZhbHVlcyA9IHt9O1xuICAgICAgcGFyYW0uYWxsb3dhYmxlVmFsdWVzLnZhbHVlcyA9IFtdO1xuICAgICAgcGFyYW0uYWxsb3dhYmxlVmFsdWVzLmRlc2NyaXB0aXZlVmFsdWVzID0gW107XG5cbiAgICAgIGZvciAoaWQgPSAwOyBpZCA8IHBhcmFtWydlbnVtJ10ubGVuZ3RoOyBpZCsrKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IHBhcmFtWydlbnVtJ11baWRdO1xuICAgICAgICB2YXIgaXNEZWZhdWx0ID0gKHZhbHVlID09PSBwYXJhbS5kZWZhdWx0IHx8IHZhbHVlKycnID09PSBwYXJhbS5kZWZhdWx0KTtcblxuICAgICAgICBwYXJhbS5hbGxvd2FibGVWYWx1ZXMudmFsdWVzLnB1c2godmFsdWUpO1xuICAgICAgICAvLyBBbHdheXMgaGF2ZSBzdHJpbmcgZm9yIGRlc2NyaXB0aXZlIHZhbHVlcy4uLi5cbiAgICAgICAgcGFyYW0uYWxsb3dhYmxlVmFsdWVzLmRlc2NyaXB0aXZlVmFsdWVzLnB1c2goe3ZhbHVlIDogdmFsdWUrJycsIGlzRGVmYXVsdDogaXNEZWZhdWx0fSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtLnR5cGUgPT09ICdhcnJheScpIHtcbiAgICAgIGlubmVyVHlwZSA9IFtpbm5lclR5cGVdO1xuXG4gICAgICBpZiAodHlwZW9mIHBhcmFtLmFsbG93YWJsZVZhbHVlcyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgLy8gY2FuJ3Qgc2hvdyBhcyBhIGxpc3QgaWYgbm8gdmFsdWVzIHRvIHNlbGVjdCBmcm9tXG4gICAgICAgIGRlbGV0ZSBwYXJhbS5pc0xpc3Q7XG4gICAgICAgIGRlbGV0ZSBwYXJhbS5hbGxvd011bHRpcGxlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHBhcmFtLnNpZ25hdHVyZSA9IHRoaXMuZ2V0TW9kZWxTaWduYXR1cmUoaW5uZXJUeXBlLCB0aGlzLm1vZGVscykudG9TdHJpbmcoKTtcbiAgICBwYXJhbS5zYW1wbGVKU09OID0gdGhpcy5nZXRNb2RlbFNhbXBsZUpTT04oaW5uZXJUeXBlLCB0aGlzLm1vZGVscyk7XG4gICAgcGFyYW0ucmVzcG9uc2VDbGFzc1NpZ25hdHVyZSA9IHBhcmFtLnNpZ25hdHVyZTtcbiAgfVxuXG4gIHZhciBkZWZhdWx0UmVzcG9uc2VDb2RlLCByZXNwb25zZSwgcmVzcG9uc2VzID0gdGhpcy5yZXNwb25zZXM7XG5cbiAgaWYgKHJlc3BvbnNlc1snMjAwJ10pIHtcbiAgICByZXNwb25zZSA9IHJlc3BvbnNlc1snMjAwJ107XG4gICAgZGVmYXVsdFJlc3BvbnNlQ29kZSA9ICcyMDAnO1xuICB9IGVsc2UgaWYgKHJlc3BvbnNlc1snMjAxJ10pIHtcbiAgICByZXNwb25zZSA9IHJlc3BvbnNlc1snMjAxJ107XG4gICAgZGVmYXVsdFJlc3BvbnNlQ29kZSA9ICcyMDEnO1xuICB9IGVsc2UgaWYgKHJlc3BvbnNlc1snMjAyJ10pIHtcbiAgICByZXNwb25zZSA9IHJlc3BvbnNlc1snMjAyJ107XG4gICAgZGVmYXVsdFJlc3BvbnNlQ29kZSA9ICcyMDInO1xuICB9IGVsc2UgaWYgKHJlc3BvbnNlc1snMjAzJ10pIHtcbiAgICByZXNwb25zZSA9IHJlc3BvbnNlc1snMjAzJ107XG4gICAgZGVmYXVsdFJlc3BvbnNlQ29kZSA9ICcyMDMnO1xuICB9IGVsc2UgaWYgKHJlc3BvbnNlc1snMjA0J10pIHtcbiAgICByZXNwb25zZSA9IHJlc3BvbnNlc1snMjA0J107XG4gICAgZGVmYXVsdFJlc3BvbnNlQ29kZSA9ICcyMDQnO1xuICB9IGVsc2UgaWYgKHJlc3BvbnNlc1snMjA1J10pIHtcbiAgICByZXNwb25zZSA9IHJlc3BvbnNlc1snMjA1J107XG4gICAgZGVmYXVsdFJlc3BvbnNlQ29kZSA9ICcyMDUnO1xuICB9IGVsc2UgaWYgKHJlc3BvbnNlc1snMjA2J10pIHtcbiAgICByZXNwb25zZSA9IHJlc3BvbnNlc1snMjA2J107XG4gICAgZGVmYXVsdFJlc3BvbnNlQ29kZSA9ICcyMDYnO1xuICB9IGVsc2UgaWYgKHJlc3BvbnNlc1snZGVmYXVsdCddKSB7XG4gICAgcmVzcG9uc2UgPSByZXNwb25zZXNbJ2RlZmF1bHQnXTtcbiAgICBkZWZhdWx0UmVzcG9uc2VDb2RlID0gJ2RlZmF1bHQnO1xuICB9XG5cbiAgaWYgKHJlc3BvbnNlICYmIHJlc3BvbnNlLnNjaGVtYSkge1xuICAgIHZhciByZXNvbHZlZE1vZGVsID0gdGhpcy5yZXNvbHZlTW9kZWwocmVzcG9uc2Uuc2NoZW1hLCBkZWZpbml0aW9ucyk7XG4gICAgdmFyIHN1Y2Nlc3NSZXNwb25zZTtcblxuICAgIGRlbGV0ZSByZXNwb25zZXNbZGVmYXVsdFJlc3BvbnNlQ29kZV07XG5cbiAgICBpZiAocmVzb2x2ZWRNb2RlbCkge1xuICAgICAgdGhpcy5zdWNjZXNzUmVzcG9uc2UgPSB7fTtcbiAgICAgIHN1Y2Nlc3NSZXNwb25zZSA9IHRoaXMuc3VjY2Vzc1Jlc3BvbnNlW2RlZmF1bHRSZXNwb25zZUNvZGVdID0gcmVzb2x2ZWRNb2RlbDtcbiAgICB9IGVsc2UgaWYgKCFyZXNwb25zZS5zY2hlbWEudHlwZSB8fCByZXNwb25zZS5zY2hlbWEudHlwZSA9PT0gJ29iamVjdCcgfHwgcmVzcG9uc2Uuc2NoZW1hLnR5cGUgPT09ICdhcnJheScpIHtcbiAgICAgIC8vIElubGluZSBtb2RlbFxuICAgICAgdGhpcy5zdWNjZXNzUmVzcG9uc2UgPSB7fTtcbiAgICAgIHN1Y2Nlc3NSZXNwb25zZSA9IHRoaXMuc3VjY2Vzc1Jlc3BvbnNlW2RlZmF1bHRSZXNwb25zZUNvZGVdID0gbmV3IE1vZGVsKHVuZGVmaW5lZCwgcmVzcG9uc2Uuc2NoZW1hIHx8IHt9LCB0aGlzLm1vZGVscywgcGFyZW50Lm1vZGVsUHJvcGVydHlNYWNybyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFByaW1pdGl2ZVxuICAgICAgdGhpcy5zdWNjZXNzUmVzcG9uc2UgPSB7fTtcbiAgICAgIHN1Y2Nlc3NSZXNwb25zZSA9IHRoaXMuc3VjY2Vzc1Jlc3BvbnNlW2RlZmF1bHRSZXNwb25zZUNvZGVdID0gcmVzcG9uc2Uuc2NoZW1hO1xuICAgIH1cblxuICAgIGlmIChzdWNjZXNzUmVzcG9uc2UpIHtcbiAgICAgIC8vIEF0dGFjaCByZXNwb25zZSBwcm9wZXJ0aWVzXG4gICAgICBpZiAocmVzcG9uc2UuZGVzY3JpcHRpb24pIHtcbiAgICAgICAgc3VjY2Vzc1Jlc3BvbnNlLmRlc2NyaXB0aW9uID0gcmVzcG9uc2UuZGVzY3JpcHRpb247XG4gICAgICB9XG5cbiAgICAgIGlmIChyZXNwb25zZS5leGFtcGxlcykge1xuICAgICAgICBzdWNjZXNzUmVzcG9uc2UuZXhhbXBsZXMgPSByZXNwb25zZS5leGFtcGxlcztcbiAgICAgIH1cblxuICAgICAgaWYgKHJlc3BvbnNlLmhlYWRlcnMpIHtcbiAgICAgICAgc3VjY2Vzc1Jlc3BvbnNlLmhlYWRlcnMgPSByZXNwb25zZS5oZWFkZXJzO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMudHlwZSA9IHJlc3BvbnNlO1xuICB9XG5cbiAgaWYgKGVycm9ycy5sZW5ndGggPiAwKSB7XG4gICAgaWYgKHRoaXMucmVzb3VyY2UgJiYgdGhpcy5yZXNvdXJjZS5hcGkgJiYgdGhpcy5yZXNvdXJjZS5hcGkuZmFpbCkge1xuICAgICAgdGhpcy5yZXNvdXJjZS5hcGkuZmFpbChlcnJvcnMpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5pc0RlZmF1bHRBcnJheUl0ZW1WYWx1ZSA9IGZ1bmN0aW9uKHZhbHVlLCBwYXJhbSkge1xuICBpZiAocGFyYW0uZGVmYXVsdCAmJiBBcnJheS5pc0FycmF5KHBhcmFtLmRlZmF1bHQpKSB7XG4gICAgcmV0dXJuIHBhcmFtLmRlZmF1bHQuaW5kZXhPZih2YWx1ZSkgIT09IC0xO1xuICB9XG4gIHJldHVybiB2YWx1ZSA9PT0gcGFyYW0uZGVmYXVsdDtcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuZ2V0VHlwZSA9IGZ1bmN0aW9uIChwYXJhbSkge1xuICB2YXIgdHlwZSA9IHBhcmFtLnR5cGU7XG4gIHZhciBmb3JtYXQgPSBwYXJhbS5mb3JtYXQ7XG4gIHZhciBpc0FycmF5ID0gZmFsc2U7XG4gIHZhciBzdHI7XG5cbiAgaWYgKHR5cGUgPT09ICdpbnRlZ2VyJyAmJiBmb3JtYXQgPT09ICdpbnQzMicpIHtcbiAgICBzdHIgPSAnaW50ZWdlcic7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2ludGVnZXInICYmIGZvcm1hdCA9PT0gJ2ludDY0Jykge1xuICAgIHN0ciA9ICdsb25nJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnaW50ZWdlcicpIHtcbiAgICBzdHIgPSAnaW50ZWdlcic7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICBpZiAoZm9ybWF0ID09PSAnZGF0ZS10aW1lJykge1xuICAgICAgc3RyID0gJ2RhdGUtdGltZSc7XG4gICAgfSBlbHNlIGlmIChmb3JtYXQgPT09ICdkYXRlJykge1xuICAgICAgc3RyID0gJ2RhdGUnO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgPSAnc3RyaW5nJztcbiAgICB9XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ251bWJlcicgJiYgZm9ybWF0ID09PSAnZmxvYXQnKSB7XG4gICAgc3RyID0gJ2Zsb2F0JztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJyAmJiBmb3JtYXQgPT09ICdkb3VibGUnKSB7XG4gICAgc3RyID0gJ2RvdWJsZSc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ251bWJlcicpIHtcbiAgICBzdHIgPSAnZG91YmxlJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnYm9vbGVhbicpIHtcbiAgICBzdHIgPSAnYm9vbGVhbic7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2FycmF5Jykge1xuICAgIGlzQXJyYXkgPSB0cnVlO1xuXG4gICAgaWYgKHBhcmFtLml0ZW1zKSB7XG4gICAgICBzdHIgPSB0aGlzLmdldFR5cGUocGFyYW0uaXRlbXMpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChwYXJhbS4kcmVmKSB7XG4gICAgc3RyID0gaGVscGVycy5zaW1wbGVSZWYocGFyYW0uJHJlZik7XG4gIH1cblxuICB2YXIgc2NoZW1hID0gcGFyYW0uc2NoZW1hO1xuXG4gIGlmIChzY2hlbWEpIHtcbiAgICB2YXIgcmVmID0gc2NoZW1hLiRyZWY7XG5cbiAgICBpZiAocmVmKSB7XG4gICAgICByZWYgPSBoZWxwZXJzLnNpbXBsZVJlZihyZWYpO1xuXG4gICAgICBpZiAoaXNBcnJheSkge1xuICAgICAgICByZXR1cm4gWyByZWYgXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiByZWY7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElmIGlubGluZSBzY2hlbWEsIHdlIGFkZCBpdCBvdXIgaW50ZXJhbCBoYXNoIC0+IHdoaWNoIGdpdmVzIHVzIGl0J3MgSUQgKGludClcbiAgICAgIGlmKHNjaGVtYS50eXBlID09PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gdGhpcy5hZGRJbmxpbmVNb2RlbChzY2hlbWEpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuZ2V0VHlwZShzY2hlbWEpO1xuICAgIH1cbiAgfVxuICBpZiAoaXNBcnJheSkge1xuICAgIHJldHVybiBbIHN0ciBdO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBzdHI7XG4gIH1cbn07XG5cbi8qKlxuICogYWRkcyBhbiBpbmxpbmUgc2NoZW1hIChtb2RlbCkgdG8gYSBoYXNoLCB3aGVyZSB3ZSBjYW4gcmVmIGl0IGxhdGVyXG4gKiBAcGFyYW0ge29iamVjdH0gc2NoZW1hIGEgc2NoZW1hXG4gKiBAcmV0dXJuIHtudW1iZXJ9IHRoZSBJRCBvZiB0aGUgc2NoZW1hIGJlaW5nIGFkZGVkLCBvciBudWxsXG4gKiovXG5PcGVyYXRpb24ucHJvdG90eXBlLmFkZElubGluZU1vZGVsID0gZnVuY3Rpb24gKHNjaGVtYSkge1xuICB2YXIgbGVuID0gdGhpcy5pbmxpbmVNb2RlbHMubGVuZ3RoO1xuICB2YXIgbW9kZWwgPSB0aGlzLnJlc29sdmVNb2RlbChzY2hlbWEsIHt9KTtcbiAgaWYobW9kZWwpIHtcbiAgICB0aGlzLmlubGluZU1vZGVscy5wdXNoKG1vZGVsKTtcbiAgICByZXR1cm4gJ0lubGluZSBNb2RlbCAnK2xlbjsgLy8gcmV0dXJuIHN0cmluZyByZWYgb2YgdGhlIGlubGluZSBtb2RlbCAodXNlZCB3aXRoICNnZXRJbmxpbmVNb2RlbClcbiAgfVxuICByZXR1cm4gbnVsbDsgLy8gcmVwb3J0IGVycm9ycz9cbn07XG5cbi8qKlxuICogZ2V0cyB0aGUgaW50ZXJuYWwgcmVmIHRvIGFuIGlubGluZSBtb2RlbFxuICogQHBhcmFtIHtzdHJpbmd9IGlubGluZV9zdHIgYSBzdHJpbmcgcmVmZXJlbmNlIHRvIGFuIGlubGluZSBtb2RlbFxuICogQHJldHVybiB7TW9kZWx9IHRoZSBtb2RlbCBiZWluZyByZWZlcmVuY2VkLiBPciBudWxsXG4gKiovXG5PcGVyYXRpb24ucHJvdG90eXBlLmdldElubGluZU1vZGVsID0gZnVuY3Rpb24oaW5saW5lU3RyKSB7XG4gIGlmKC9eSW5saW5lIE1vZGVsIFxcZCskLy50ZXN0KGlubGluZVN0cikpIHtcbiAgICB2YXIgaWQgPSBwYXJzZUludChpbmxpbmVTdHIuc3Vic3RyKCdJbmxpbmUgTW9kZWwnLmxlbmd0aCkudHJpbSgpLDEwKTsgLy9cbiAgICB2YXIgbW9kZWwgPSB0aGlzLmlubGluZU1vZGVsc1tpZF07XG4gICAgcmV0dXJuIG1vZGVsO1xuICB9XG4gIC8vIEknbSByZXR1cm5pbmcgbnVsbCBoZXJlLCBzaG91bGQgSSByYXRoZXIgdGhyb3cgYW4gZXJyb3I/XG4gIHJldHVybiBudWxsO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5yZXNvbHZlTW9kZWwgPSBmdW5jdGlvbiAoc2NoZW1hLCBkZWZpbml0aW9ucykge1xuICBpZiAodHlwZW9mIHNjaGVtYS4kcmVmICE9PSAndW5kZWZpbmVkJykge1xuICAgIHZhciByZWYgPSBzY2hlbWEuJHJlZjtcblxuICAgIGlmIChyZWYuaW5kZXhPZignIy9kZWZpbml0aW9ucy8nKSA9PT0gMCkge1xuICAgICAgcmVmID0gcmVmLnN1YnN0cmluZygnIy9kZWZpbml0aW9ucy8nLmxlbmd0aCk7XG4gICAgfVxuXG4gICAgaWYgKGRlZmluaXRpb25zW3JlZl0pIHtcbiAgICAgIHJldHVybiBuZXcgTW9kZWwocmVmLCBkZWZpbml0aW9uc1tyZWZdLCB0aGlzLm1vZGVscywgdGhpcy5wYXJlbnQubW9kZWxQcm9wZXJ0eU1hY3JvKTtcbiAgICB9XG4gIC8vIHNjaGVtYSBtdXN0IGF0IGxlYXN0IGJlIGFuIG9iamVjdCB0byBnZXQgcmVzb2x2ZWQgdG8gYW4gaW5saW5lIE1vZGVsXG4gIH0gZWxzZSBpZiAoc2NoZW1hICYmIHR5cGVvZiBzY2hlbWEgPT09ICdvYmplY3QnICYmXG4gICAgICAgICAgICAoc2NoZW1hLnR5cGUgPT09ICdvYmplY3QnIHx8IF8uaXNVbmRlZmluZWQoc2NoZW1hLnR5cGUpKSkge1xuICAgIHJldHVybiBuZXcgTW9kZWwodW5kZWZpbmVkLCBzY2hlbWEsIHRoaXMubW9kZWxzLCB0aGlzLnBhcmVudC5tb2RlbFByb3BlcnR5TWFjcm8pO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmhlbHAgPSBmdW5jdGlvbiAoZG9udFByaW50KSB7XG4gIHZhciBvdXQgPSB0aGlzLm5pY2tuYW1lICsgJzogJyArIHRoaXMuc3VtbWFyeSArICdcXG4nO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5wYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcmFtID0gdGhpcy5wYXJhbWV0ZXJzW2ldO1xuICAgIHZhciB0eXBlSW5mbyA9IHBhcmFtLnNpZ25hdHVyZTtcblxuICAgIG91dCArPSAnXFxuICAqICcgKyBwYXJhbS5uYW1lICsgJyAoJyArIHR5cGVJbmZvICsgJyk6ICcgKyBwYXJhbS5kZXNjcmlwdGlvbjtcbiAgfVxuXG4gIGlmICh0eXBlb2YgZG9udFByaW50ID09PSAndW5kZWZpbmVkJykge1xuICAgIGhlbHBlcnMubG9nKG91dCk7XG4gIH1cblxuICByZXR1cm4gb3V0O1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5nZXRNb2RlbFNpZ25hdHVyZSA9IGZ1bmN0aW9uICh0eXBlLCBkZWZpbml0aW9ucykge1xuICB2YXIgaXNQcmltaXRpdmUsIGxpc3RUeXBlO1xuXG4gIGlmICh0eXBlIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICBsaXN0VHlwZSA9IHRydWU7XG4gICAgdHlwZSA9IHR5cGVbMF07XG4gIH1cblxuICAvLyBDb252ZXJ0IHVuZGVmaW5lZCB0byBzdHJpbmcgb2YgJ3VuZGVmaW5lZCdcbiAgaWYgKHR5cGVvZiB0eXBlID09PSAndW5kZWZpbmVkJykge1xuICAgIHR5cGUgPSAndW5kZWZpbmVkJztcbiAgICBpc1ByaW1pdGl2ZSA9IHRydWU7XG5cbiAgfSBlbHNlIGlmIChkZWZpbml0aW9uc1t0eXBlXSl7XG4gICAgLy8gYSBtb2RlbCBkZWYgZXhpc3RzP1xuICAgIHR5cGUgPSBkZWZpbml0aW9uc1t0eXBlXTsgLyogTW9kZWwgKi9cbiAgICBpc1ByaW1pdGl2ZSA9IGZhbHNlO1xuXG4gIH0gZWxzZSBpZiAodGhpcy5nZXRJbmxpbmVNb2RlbCh0eXBlKSkge1xuICAgIHR5cGUgPSB0aGlzLmdldElubGluZU1vZGVsKHR5cGUpOyAvKiBNb2RlbCAqL1xuICAgIGlzUHJpbWl0aXZlID0gZmFsc2U7XG5cbiAgfSBlbHNlIHtcbiAgICAvLyBXZSBkZWZhdWx0IHRvIHByaW1pdGl2ZVxuICAgIGlzUHJpbWl0aXZlID0gdHJ1ZTtcbiAgfVxuXG4gIGlmIChpc1ByaW1pdGl2ZSkge1xuICAgIGlmIChsaXN0VHlwZSkge1xuICAgICAgcmV0dXJuICdBcnJheVsnICsgdHlwZSArICddJztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHR5cGUudG9TdHJpbmcoKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGxpc3RUeXBlKSB7XG4gICAgICByZXR1cm4gJ0FycmF5WycgKyB0eXBlLmdldE1vY2tTaWduYXR1cmUoKSArICddJztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHR5cGUuZ2V0TW9ja1NpZ25hdHVyZSgpO1xuICAgIH1cbiAgfVxufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5zdXBwb3J0SGVhZGVyUGFyYW1zID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdHJ1ZTtcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuc3VwcG9ydGVkU3VibWl0TWV0aG9kcyA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMucGFyZW50LnN1cHBvcnRlZFN1Ym1pdE1ldGhvZHM7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmdldEhlYWRlclBhcmFtcyA9IGZ1bmN0aW9uIChhcmdzKSB7XG4gIHZhciBoZWFkZXJzID0gdGhpcy5zZXRDb250ZW50VHlwZXMoYXJncywge30pO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5wYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcmFtID0gdGhpcy5wYXJhbWV0ZXJzW2ldO1xuXG4gICAgaWYgKHR5cGVvZiBhcmdzW3BhcmFtLm5hbWVdICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgaWYgKHBhcmFtLmluID09PSAnaGVhZGVyJykge1xuICAgICAgICB2YXIgdmFsdWUgPSBhcmdzW3BhcmFtLm5hbWVdO1xuXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgIHZhbHVlID0gdmFsdWUudG9TdHJpbmcoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGhlYWRlcnNbcGFyYW0ubmFtZV0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gaGVhZGVycztcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUudXJsaWZ5ID0gZnVuY3Rpb24gKGFyZ3MpIHtcbiAgdmFyIGZvcm1QYXJhbXMgPSB7fTtcbiAgdmFyIHJlcXVlc3RVcmwgPSB0aGlzLnBhdGg7XG4gIHZhciBxdWVyeXN0cmluZyA9ICcnOyAvLyBncmFiIHBhcmFtcyBmcm9tIHRoZSBhcmdzLCBidWlsZCB0aGUgcXVlcnlzdHJpbmcgYWxvbmcgdGhlIHdheVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5wYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcmFtID0gdGhpcy5wYXJhbWV0ZXJzW2ldO1xuXG4gICAgaWYgKHR5cGVvZiBhcmdzW3BhcmFtLm5hbWVdICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgaWYgKHBhcmFtLmluID09PSAncGF0aCcpIHtcbiAgICAgICAgdmFyIHJlZyA9IG5ldyBSZWdFeHAoJ1xceycgKyBwYXJhbS5uYW1lICsgJ1xcfScsICdnaScpO1xuICAgICAgICB2YXIgdmFsdWUgPSBhcmdzW3BhcmFtLm5hbWVdO1xuXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgIHZhbHVlID0gdGhpcy5lbmNvZGVQYXRoQ29sbGVjdGlvbihwYXJhbS5jb2xsZWN0aW9uRm9ybWF0LCBwYXJhbS5uYW1lLCB2YWx1ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFsdWUgPSB0aGlzLmVuY29kZVBhdGhQYXJhbSh2YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXF1ZXN0VXJsID0gcmVxdWVzdFVybC5yZXBsYWNlKHJlZywgdmFsdWUpO1xuICAgICAgfSBlbHNlIGlmIChwYXJhbS5pbiA9PT0gJ3F1ZXJ5JyAmJiB0eXBlb2YgYXJnc1twYXJhbS5uYW1lXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgaWYgKHF1ZXJ5c3RyaW5nID09PSAnJykge1xuICAgICAgICAgIHF1ZXJ5c3RyaW5nICs9ICc/JztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBxdWVyeXN0cmluZyArPSAnJic7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHBhcmFtLmNvbGxlY3Rpb25Gb3JtYXQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgdmFyIHFwID0gYXJnc1twYXJhbS5uYW1lXTtcblxuICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHFwKSkge1xuICAgICAgICAgICAgcXVlcnlzdHJpbmcgKz0gdGhpcy5lbmNvZGVRdWVyeUNvbGxlY3Rpb24ocGFyYW0uY29sbGVjdGlvbkZvcm1hdCwgcGFyYW0ubmFtZSwgcXApO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBxdWVyeXN0cmluZyArPSB0aGlzLmVuY29kZVF1ZXJ5UGFyYW0ocGFyYW0ubmFtZSkgKyAnPScgKyB0aGlzLmVuY29kZVF1ZXJ5UGFyYW0oYXJnc1twYXJhbS5uYW1lXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHF1ZXJ5c3RyaW5nICs9IHRoaXMuZW5jb2RlUXVlcnlQYXJhbShwYXJhbS5uYW1lKSArICc9JyArIHRoaXMuZW5jb2RlUXVlcnlQYXJhbShhcmdzW3BhcmFtLm5hbWVdKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChwYXJhbS5pbiA9PT0gJ2Zvcm1EYXRhJykge1xuICAgICAgICBmb3JtUGFyYW1zW3BhcmFtLm5hbWVdID0gYXJnc1twYXJhbS5uYW1lXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgdmFyIHVybCA9IHRoaXMuc2NoZW1lICsgJzovLycgKyB0aGlzLmhvc3Q7XG5cbiAgaWYgKHRoaXMuYmFzZVBhdGggIT09ICcvJykge1xuICAgIHVybCArPSB0aGlzLmJhc2VQYXRoO1xuICB9XG4gIHJldHVybiB1cmwgKyByZXF1ZXN0VXJsICsgcXVlcnlzdHJpbmc7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmdldE1pc3NpbmdQYXJhbXMgPSBmdW5jdGlvbiAoYXJncykge1xuICB2YXIgbWlzc2luZ1BhcmFtcyA9IFtdOyAvLyBjaGVjayByZXF1aXJlZCBwYXJhbXMsIHRyYWNrIHRoZSBvbmVzIHRoYXQgYXJlIG1pc3NpbmdcbiAgdmFyIGk7XG5cbiAgZm9yIChpID0gMDsgaSA8IHRoaXMucGFyYW1ldGVycy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwYXJhbSA9IHRoaXMucGFyYW1ldGVyc1tpXTtcblxuICAgIGlmIChwYXJhbS5yZXF1aXJlZCA9PT0gdHJ1ZSkge1xuICAgICAgaWYgKHR5cGVvZiBhcmdzW3BhcmFtLm5hbWVdID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICBtaXNzaW5nUGFyYW1zID0gcGFyYW0ubmFtZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbWlzc2luZ1BhcmFtcztcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuZ2V0Qm9keSA9IGZ1bmN0aW9uIChoZWFkZXJzLCBhcmdzLCBvcHRzKSB7XG4gIHZhciBmb3JtUGFyYW1zID0ge30sIGJvZHksIGtleSwgdmFsdWUsIGhhc0JvZHkgPSBmYWxzZTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMucGFyYW1ldGVycy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwYXJhbSA9IHRoaXMucGFyYW1ldGVyc1tpXTtcblxuICAgIGlmICh0eXBlb2YgYXJnc1twYXJhbS5uYW1lXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGlmIChwYXJhbS5pbiA9PT0gJ2JvZHknKSB7XG4gICAgICAgIGJvZHkgPSBhcmdzW3BhcmFtLm5hbWVdO1xuICAgICAgfSBlbHNlIGlmIChwYXJhbS5pbiA9PT0gJ2Zvcm1EYXRhJykge1xuICAgICAgICBmb3JtUGFyYW1zW3BhcmFtLm5hbWVdID0gYXJnc1twYXJhbS5uYW1lXTtcbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBpZihwYXJhbS5pbiA9PT0gJ2JvZHknKSB7XG4gICAgICAgIGhhc0JvZHkgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIGlmIGJvZHkgaXMgbnVsbCBhbmQgaGFzQm9keSBpcyB0cnVlLCBBTkQgYSBKU09OIGJvZHkgaXMgcmVxdWVzdGVkLCBzZW5kIGVtcHR5IHt9XG4gIGlmKGhhc0JvZHkgJiYgdHlwZW9mIGJvZHkgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgdmFyIGNvbnRlbnRUeXBlID0gaGVhZGVyc1snQ29udGVudC1UeXBlJ107XG4gICAgaWYoY29udGVudFR5cGUgJiYgY29udGVudFR5cGUuaW5kZXhPZignYXBwbGljYXRpb24vanNvbicpID09PSAwKSB7XG4gICAgICBib2R5ID0gJ3t9JztcbiAgICB9XG4gIH1cblxuICAvLyBoYW5kbGUgZm9ybSBwYXJhbXNcbiAgaWYgKGhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddID09PSAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJykge1xuICAgIHZhciBlbmNvZGVkID0gJyc7XG5cbiAgICBmb3IgKGtleSBpbiBmb3JtUGFyYW1zKSB7XG4gICAgICB2YWx1ZSA9IGZvcm1QYXJhbXNba2V5XTtcblxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgaWYgKGVuY29kZWQgIT09ICcnKSB7XG4gICAgICAgICAgZW5jb2RlZCArPSAnJic7XG4gICAgICAgIH1cblxuICAgICAgICBlbmNvZGVkICs9IGVuY29kZVVSSUNvbXBvbmVudChrZXkpICsgJz0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBib2R5ID0gZW5jb2RlZDtcbiAgfSBlbHNlIGlmIChoZWFkZXJzWydDb250ZW50LVR5cGUnXSAmJiBoZWFkZXJzWydDb250ZW50LVR5cGUnXS5pbmRleE9mKCdtdWx0aXBhcnQvZm9ybS1kYXRhJykgPj0gMCkge1xuICAgIGlmIChvcHRzLnVzZUpRdWVyeSkge1xuICAgICAgdmFyIGJvZHlQYXJhbSA9IG5ldyBGb3JtRGF0YSgpO1xuXG4gICAgICBib2R5UGFyYW0udHlwZSA9ICdmb3JtRGF0YSc7XG5cbiAgICAgIGZvciAoa2V5IGluIGZvcm1QYXJhbXMpIHtcbiAgICAgICAgdmFsdWUgPSBhcmdzW2tleV07XG5cbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAvLyByZXF1aXJlZCBmb3IganF1ZXJ5IGZpbGUgdXBsb2FkXG4gICAgICAgICAgaWYgKHZhbHVlLnR5cGUgPT09ICdmaWxlJyAmJiB2YWx1ZS52YWx1ZSkge1xuICAgICAgICAgICAgZGVsZXRlIGhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddO1xuXG4gICAgICAgICAgICBib2R5UGFyYW0uYXBwZW5kKGtleSwgdmFsdWUudmFsdWUpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBib2R5UGFyYW0uYXBwZW5kKGtleSwgdmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBib2R5ID0gYm9keVBhcmFtO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBib2R5O1xufTtcblxuLyoqXG4gKiBnZXRzIHNhbXBsZSByZXNwb25zZSBmb3IgYSBzaW5nbGUgb3BlcmF0aW9uXG4gKiovXG5PcGVyYXRpb24ucHJvdG90eXBlLmdldE1vZGVsU2FtcGxlSlNPTiA9IGZ1bmN0aW9uICh0eXBlLCBtb2RlbHMpIHtcbiAgdmFyIGxpc3RUeXBlLCBzYW1wbGVKc29uLCBpbm5lclR5cGU7XG4gIG1vZGVscyA9IG1vZGVscyB8fCB7fTtcblxuICBsaXN0VHlwZSA9ICh0eXBlIGluc3RhbmNlb2YgQXJyYXkpO1xuICBpbm5lclR5cGUgPSBsaXN0VHlwZSA/IHR5cGVbMF0gOiB0eXBlO1xuXG4gIGlmKG1vZGVsc1tpbm5lclR5cGVdKSB7XG4gICAgc2FtcGxlSnNvbiA9IG1vZGVsc1tpbm5lclR5cGVdLmNyZWF0ZUpTT05TYW1wbGUoKTtcbiAgfSBlbHNlIGlmICh0aGlzLmdldElubGluZU1vZGVsKGlubmVyVHlwZSkpe1xuICAgIHNhbXBsZUpzb24gPSB0aGlzLmdldElubGluZU1vZGVsKGlubmVyVHlwZSkuY3JlYXRlSlNPTlNhbXBsZSgpOyAvLyBtYXkgcmV0dXJuIG51bGwsIGlmIHR5cGUgaXNuJ3QgY29ycmVjdFxuICB9XG5cblxuICBpZiAoc2FtcGxlSnNvbikge1xuICAgIHNhbXBsZUpzb24gPSBsaXN0VHlwZSA/IFtzYW1wbGVKc29uXSA6IHNhbXBsZUpzb247XG5cbiAgICBpZiAodHlwZW9mIHNhbXBsZUpzb24gPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gc2FtcGxlSnNvbjtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBzYW1wbGVKc29uID09PSAnb2JqZWN0Jykge1xuICAgICAgdmFyIHQgPSBzYW1wbGVKc29uO1xuXG4gICAgICBpZiAoc2FtcGxlSnNvbiBpbnN0YW5jZW9mIEFycmF5ICYmIHNhbXBsZUpzb24ubGVuZ3RoID4gMCkge1xuICAgICAgICB0ID0gc2FtcGxlSnNvblswXTtcbiAgICAgIH1cblxuICAgICAgaWYgKHQubm9kZU5hbWUpIHtcbiAgICAgICAgdmFyIHhtbFN0cmluZyA9IG5ldyBYTUxTZXJpYWxpemVyKCkuc2VyaWFsaXplVG9TdHJpbmcodCk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0WG1sKHhtbFN0cmluZyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoc2FtcGxlSnNvbiwgbnVsbCwgMik7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBzYW1wbGVKc29uO1xuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBsZWdhY3kgYmluZGluZ1xuICoqL1xuT3BlcmF0aW9uLnByb3RvdHlwZS5kbyA9IGZ1bmN0aW9uIChhcmdzLCBvcHRzLCBjYWxsYmFjaywgZXJyb3IsIHBhcmVudCkge1xuICByZXR1cm4gdGhpcy5leGVjdXRlKGFyZ3MsIG9wdHMsIGNhbGxiYWNrLCBlcnJvciwgcGFyZW50KTtcbn07XG5cbi8qKlxuICogZXhlY3V0ZXMgYW4gb3BlcmF0aW9uXG4gKiovXG5PcGVyYXRpb24ucHJvdG90eXBlLmV4ZWN1dGUgPSBmdW5jdGlvbiAoYXJnMSwgYXJnMiwgYXJnMywgYXJnNCwgcGFyZW50KSB7XG4gIHZhciBhcmdzID0gYXJnMSB8fCB7fTtcbiAgdmFyIG9wdHMgPSB7fSwgc3VjY2VzcywgZXJyb3I7XG5cbiAgaWYgKHR5cGVvZiBhcmcyID09PSAnb2JqZWN0Jykge1xuICAgIG9wdHMgPSBhcmcyO1xuICAgIHN1Y2Nlc3MgPSBhcmczO1xuICAgIGVycm9yID0gYXJnNDtcbiAgfVxuXG4gIGlmKHRoaXMuY2xpZW50KSB7XG4gICAgb3B0cy5jbGllbnQgPSB0aGlzLmNsaWVudDtcbiAgfVxuICBpZih0aGlzLnJlc3BvbnNlSW50ZXJjZXB0b3IpIHtcbiAgICBvcHRzLnJlc3BvbnNlSW50ZXJjZXB0b3IgPSB0aGlzLnJlc3BvbnNlSW50ZXJjZXB0b3I7XG4gIH1cblxuXG4gIGlmICh0eXBlb2YgYXJnMiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHN1Y2Nlc3MgPSBhcmcyO1xuICAgIGVycm9yID0gYXJnMztcbiAgfVxuXG4gIHN1Y2Nlc3MgPSAoc3VjY2VzcyB8fCB0aGlzLnBhcmVudC5kZWZhdWx0U3VjY2Vzc0NhbGxiYWNrIHx8IGhlbHBlcnMubG9nKTtcbiAgZXJyb3IgPSAoZXJyb3IgfHwgdGhpcy5wYXJlbnQuZGVmYXVsdEVycm9yQ2FsbGJhY2sgfHwgaGVscGVycy5sb2cpO1xuXG5cbiAgaWYgKHR5cGVvZiBvcHRzLnVzZUpRdWVyeSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBvcHRzLnVzZUpRdWVyeSA9IHRoaXMudXNlSlF1ZXJ5O1xuICB9XG4gIHZhciBtaXNzaW5nUGFyYW1zID0gdGhpcy5nZXRNaXNzaW5nUGFyYW1zKGFyZ3MpO1xuXG4gIGlmIChtaXNzaW5nUGFyYW1zLmxlbmd0aCA+IDApIHtcbiAgICB2YXIgbWVzc2FnZSA9ICdtaXNzaW5nIHJlcXVpcmVkIHBhcmFtczogJyArIG1pc3NpbmdQYXJhbXM7XG5cbiAgICBoZWxwZXJzLmZhaWwobWVzc2FnZSk7XG4gICAgZXJyb3IobWVzc2FnZSk7XG5cbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgYWxsSGVhZGVycyA9IHRoaXMuZ2V0SGVhZGVyUGFyYW1zKGFyZ3MpO1xuICB2YXIgY29udGVudFR5cGVIZWFkZXJzID0gdGhpcy5zZXRDb250ZW50VHlwZXMoYXJncywgb3B0cyk7XG4gIHZhciBoZWFkZXJzID0ge30sIGF0dHJuYW1lO1xuXG4gIGZvciAoYXR0cm5hbWUgaW4gYWxsSGVhZGVycykgeyBoZWFkZXJzW2F0dHJuYW1lXSA9IGFsbEhlYWRlcnNbYXR0cm5hbWVdOyB9XG4gIGZvciAoYXR0cm5hbWUgaW4gY29udGVudFR5cGVIZWFkZXJzKSB7IGhlYWRlcnNbYXR0cm5hbWVdID0gY29udGVudFR5cGVIZWFkZXJzW2F0dHJuYW1lXTsgfVxuXG4gIHZhciBib2R5ID0gdGhpcy5nZXRCb2R5KGNvbnRlbnRUeXBlSGVhZGVycywgYXJncywgb3B0cyk7XG4gIHZhciB1cmwgPSB0aGlzLnVybGlmeShhcmdzKTtcblxuICBpZih1cmwuaW5kZXhPZignLntmb3JtYXR9JykgPiAwKSB7XG4gICAgaWYoaGVhZGVycykge1xuICAgICAgdmFyIGZvcm1hdCA9IGhlYWRlcnMuQWNjZXB0IHx8IGhlYWRlcnMuYWNjZXB0O1xuICAgICAgaWYoZm9ybWF0ICYmIGZvcm1hdC5pbmRleE9mKCdqc29uJykgPiAwKSB7XG4gICAgICAgIHVybCA9IHVybC5yZXBsYWNlKCcue2Zvcm1hdH0nLCAnLmpzb24nKTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYoZm9ybWF0ICYmIGZvcm1hdC5pbmRleE9mKCd4bWwnKSA+IDApIHtcbiAgICAgICAgdXJsID0gdXJsLnJlcGxhY2UoJy57Zm9ybWF0fScsICcueG1sJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIG9iaiA9IHtcbiAgICB1cmw6IHVybCxcbiAgICBtZXRob2Q6IHRoaXMubWV0aG9kLnRvVXBwZXJDYXNlKCksXG4gICAgYm9keTogYm9keSxcbiAgICB1c2VKUXVlcnk6IG9wdHMudXNlSlF1ZXJ5LFxuICAgIGhlYWRlcnM6IGhlYWRlcnMsXG4gICAgb246IHtcbiAgICAgIHJlc3BvbnNlOiBmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgICAgcmV0dXJuIHN1Y2Nlc3MocmVzcG9uc2UsIHBhcmVudCk7XG4gICAgICB9LFxuICAgICAgZXJyb3I6IGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgICByZXR1cm4gZXJyb3IocmVzcG9uc2UsIHBhcmVudCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHRoaXMuY2xpZW50QXV0aG9yaXphdGlvbnMuYXBwbHkob2JqLCB0aGlzLm9wZXJhdGlvbi5zZWN1cml0eSk7XG4gIGlmIChvcHRzLm1vY2sgPT09IHRydWUpIHtcbiAgICByZXR1cm4gb2JqO1xuICB9IGVsc2Uge1xuICAgIG5ldyBTd2FnZ2VySHR0cCgpLmV4ZWN1dGUob2JqLCBvcHRzKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gaXRlbUJ5UHJpb3JpdHkoY29sLCBpdGVtUHJpb3JpdHkpIHtcblxuICAvLyBObyBwcmlvcml0aWVzPyByZXR1cm4gZmlyc3QuLi5cbiAgaWYoXy5pc0VtcHR5KGl0ZW1Qcmlvcml0eSkpIHtcbiAgICByZXR1cm4gY29sWzBdO1xuICB9XG5cbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGl0ZW1Qcmlvcml0eS5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGlmKGNvbC5pbmRleE9mKGl0ZW1Qcmlvcml0eVtpXSkgPiAtMSkge1xuICAgICAgcmV0dXJuIGl0ZW1Qcmlvcml0eVtpXTtcbiAgICB9XG4gIH1cblxuICAvLyBPdGhlcndpc2UgcmV0dXJuIGZpcnN0XG4gIHJldHVybiBjb2xbMF07XG59XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuc2V0Q29udGVudFR5cGVzID0gZnVuY3Rpb24gKGFyZ3MsIG9wdHMpIHtcbiAgLy8gZGVmYXVsdCB0eXBlXG4gIHZhciBhbGxEZWZpbmVkUGFyYW1zID0gdGhpcy5wYXJhbWV0ZXJzO1xuICB2YXIgYm9keTtcbiAgdmFyIGNvbnN1bWVzID0gYXJncy5wYXJhbWV0ZXJDb250ZW50VHlwZSB8fCBpdGVtQnlQcmlvcml0eSh0aGlzLmNvbnN1bWVzLCBbJ2FwcGxpY2F0aW9uL2pzb24nLCAnYXBwbGljYXRpb24veWFtbCddKTtcbiAgdmFyIGFjY2VwdHMgPSBvcHRzLnJlc3BvbnNlQ29udGVudFR5cGUgfHwgaXRlbUJ5UHJpb3JpdHkodGhpcy5wcm9kdWNlcywgWydhcHBsaWNhdGlvbi9qc29uJywgJ2FwcGxpY2F0aW9uL3lhbWwnXSk7XG4gIHZhciBkZWZpbmVkRmlsZVBhcmFtcyA9IFtdO1xuICB2YXIgZGVmaW5lZEZvcm1QYXJhbXMgPSBbXTtcbiAgdmFyIGhlYWRlcnMgPSB7fTtcbiAgdmFyIGk7XG5cbiAgLy8gZ2V0IHBhcmFtcyBmcm9tIHRoZSBvcGVyYXRpb24gYW5kIHNldCB0aGVtIGluIGRlZmluZWRGaWxlUGFyYW1zLCBkZWZpbmVkRm9ybVBhcmFtcywgaGVhZGVyc1xuICBmb3IgKGkgPSAwOyBpIDwgYWxsRGVmaW5lZFBhcmFtcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwYXJhbSA9IGFsbERlZmluZWRQYXJhbXNbaV07XG5cbiAgICBpZiAocGFyYW0uaW4gPT09ICdmb3JtRGF0YScpIHtcbiAgICAgIGlmIChwYXJhbS50eXBlID09PSAnZmlsZScpIHtcbiAgICAgICAgZGVmaW5lZEZpbGVQYXJhbXMucHVzaChwYXJhbSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkZWZpbmVkRm9ybVBhcmFtcy5wdXNoKHBhcmFtKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHBhcmFtLmluID09PSAnaGVhZGVyJyAmJiBvcHRzKSB7XG4gICAgICB2YXIga2V5ID0gcGFyYW0ubmFtZTtcbiAgICAgIHZhciBoZWFkZXJWYWx1ZSA9IG9wdHNbcGFyYW0ubmFtZV07XG5cbiAgICAgIGlmICh0eXBlb2Ygb3B0c1twYXJhbS5uYW1lXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgaGVhZGVyc1trZXldID0gaGVhZGVyVmFsdWU7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChwYXJhbS5pbiA9PT0gJ2JvZHknICYmIHR5cGVvZiBhcmdzW3BhcmFtLm5hbWVdICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgYm9keSA9IGFyZ3NbcGFyYW0ubmFtZV07XG4gICAgfVxuICB9XG5cbiAgLy8gaWYgdGhlcmUncyBhIGJvZHksIG5lZWQgdG8gc2V0IHRoZSBjb25zdW1lcyBoZWFkZXIgdmlhIHJlcXVlc3RDb250ZW50VHlwZVxuICBpZiAodGhpcy5tZXRob2QgPT09ICdwb3N0JyB8fCB0aGlzLm1ldGhvZCA9PT0gJ3B1dCcgfHwgdGhpcy5tZXRob2QgPT09ICdwYXRjaCcpIHtcbiAgICBpZiAob3B0cy5yZXF1ZXN0Q29udGVudFR5cGUpIHtcbiAgICAgIGNvbnN1bWVzID0gb3B0cy5yZXF1ZXN0Q29udGVudFR5cGU7XG4gICAgfVxuICAgIC8vIGlmIGFueSBmb3JtIHBhcmFtcywgY29udGVudCB0eXBlIG11c3QgYmUgc2V0XG4gICAgaWYgKGRlZmluZWRGb3JtUGFyYW1zLmxlbmd0aCA+IDApIHtcbiAgICAgIGlmIChvcHRzLnJlcXVlc3RDb250ZW50VHlwZSkgeyAgICAgICAgICAgICAvLyBvdmVycmlkZSBpZiBzZXRcbiAgICAgICAgY29uc3VtZXMgPSBvcHRzLnJlcXVlc3RDb250ZW50VHlwZTtcbiAgICAgIH0gZWxzZSBpZiAoZGVmaW5lZEZpbGVQYXJhbXMubGVuZ3RoID4gMCkgeyAvLyBpZiBhIGZpbGUsIG11c3QgYmUgbXVsdGlwYXJ0L2Zvcm0tZGF0YVxuICAgICAgICBjb25zdW1lcyA9ICdtdWx0aXBhcnQvZm9ybS1kYXRhJztcbiAgICAgIH0gZWxzZSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBkZWZhdWx0IHRvIHgtd3d3LWZyb20tdXJsZW5jb2RlZFxuICAgICAgICBjb25zdW1lcyA9ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBlbHNlIHtcbiAgICBjb25zdW1lcyA9IG51bGw7XG4gIH1cblxuICBpZiAoY29uc3VtZXMgJiYgdGhpcy5jb25zdW1lcykge1xuICAgIGlmICh0aGlzLmNvbnN1bWVzLmluZGV4T2YoY29uc3VtZXMpID09PSAtMSkge1xuICAgICAgaGVscGVycy5sb2coJ3NlcnZlciBkb2VzblxcJ3QgY29uc3VtZSAnICsgY29uc3VtZXMgKyAnLCB0cnkgJyArIEpTT04uc3RyaW5naWZ5KHRoaXMuY29uc3VtZXMpKTtcbiAgICB9XG4gIH1cblxuICBpZiAoIXRoaXMubWF0Y2hlc0FjY2VwdChhY2NlcHRzKSkge1xuICAgIGhlbHBlcnMubG9nKCdzZXJ2ZXIgY2FuXFwndCBwcm9kdWNlICcgKyBhY2NlcHRzKTtcbiAgfVxuXG4gIGlmICgoY29uc3VtZXMgJiYgYm9keSAhPT0gJycpIHx8IChjb25zdW1lcyA9PT0gJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcpKSB7XG4gICAgaGVhZGVyc1snQ29udGVudC1UeXBlJ10gPSBjb25zdW1lcztcbiAgfVxuXG4gIGlmIChhY2NlcHRzKSB7XG4gICAgaGVhZGVycy5BY2NlcHQgPSBhY2NlcHRzO1xuICB9XG5cbiAgcmV0dXJuIGhlYWRlcnM7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgcmVxdWVzdCBhY2NlcHRzIGhlYWRlciBtYXRjaGVzIGFueXRoaW5nIGluIHRoaXMucHJvZHVjZXMuXG4gKiAgSWYgdGhpcy5wcm9kdWNlcyBjb250YWlucyAqIC8gKiwgaWdub3JlIHRoZSBhY2NlcHQgaGVhZGVyLiBcbiAqIEBwYXJhbSB7c3RyaW5nPX0gYWNjZXB0cyBUaGUgY2xpZW50IHJlcXVlc3QgYWNjZXB0IGhlYWRlci5cbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbk9wZXJhdGlvbi5wcm90b3R5cGUubWF0Y2hlc0FjY2VwdCA9IGZ1bmN0aW9uKGFjY2VwdHMpIHtcbiAgLy8gbm8gYWNjZXB0cyBvciBwcm9kdWNlcywgbm8gcHJvYmxlbSFcbiAgaWYgKCFhY2NlcHRzIHx8ICF0aGlzLnByb2R1Y2VzKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIHRoaXMucHJvZHVjZXMuaW5kZXhPZihhY2NlcHRzKSAhPT0gLTEgfHwgdGhpcy5wcm9kdWNlcy5pbmRleE9mKCcqLyonKSAhPT0gLTE7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmFzQ3VybCA9IGZ1bmN0aW9uIChhcmdzKSB7XG4gIHZhciBvYmogPSB0aGlzLmV4ZWN1dGUoYXJncywge21vY2s6IHRydWV9KTtcblxuICB0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zLmFwcGx5KG9iaik7XG5cbiAgdmFyIHJlc3VsdHMgPSBbXTtcblxuICByZXN1bHRzLnB1c2goJy1YICcgKyB0aGlzLm1ldGhvZC50b1VwcGVyQ2FzZSgpKTtcblxuICBpZiAob2JqLmhlYWRlcnMpIHtcbiAgICB2YXIga2V5O1xuXG4gICAgZm9yIChrZXkgaW4gb2JqLmhlYWRlcnMpIHtcbiAgICAgIHJlc3VsdHMucHVzaCgnLS1oZWFkZXIgXCInICsga2V5ICsgJzogJyArIG9iai5oZWFkZXJzW2tleV0gKyAnXCInKTtcbiAgICB9XG4gIH1cblxuICBpZiAob2JqLmJvZHkpIHtcbiAgICB2YXIgYm9keTtcblxuICAgIGlmICh0eXBlb2Ygb2JqLmJvZHkgPT09ICdvYmplY3QnKSB7XG4gICAgICBib2R5ID0gSlNPTi5zdHJpbmdpZnkob2JqLmJvZHkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBib2R5ID0gb2JqLmJvZHk7XG4gICAgfVxuXG4gICAgcmVzdWx0cy5wdXNoKCctZCBcIicgKyBib2R5LnJlcGxhY2UoL1wiL2csICdcXFxcXCInKSArICdcIicpO1xuICB9XG5cbiAgcmV0dXJuICdjdXJsICcgKyAocmVzdWx0cy5qb2luKCcgJykpICsgJyBcIicgKyBvYmoudXJsICsgJ1wiJztcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuZW5jb2RlUGF0aENvbGxlY3Rpb24gPSBmdW5jdGlvbiAodHlwZSwgbmFtZSwgdmFsdWUpIHtcbiAgdmFyIGVuY29kZWQgPSAnJztcbiAgdmFyIGk7XG4gIHZhciBzZXBhcmF0b3IgPSAnJztcblxuICBpZiAodHlwZSA9PT0gJ3NzdicpIHtcbiAgICBzZXBhcmF0b3IgPSAnJTIwJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAndHN2Jykge1xuICAgIHNlcGFyYXRvciA9ICdcXFxcdCc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3BpcGVzJykge1xuICAgIHNlcGFyYXRvciA9ICd8JztcbiAgfSBlbHNlIHtcbiAgICBzZXBhcmF0b3IgPSAnLCc7XG4gIH1cblxuICBmb3IgKGkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoaSA9PT0gMCkge1xuICAgICAgZW5jb2RlZCA9IHRoaXMuZW5jb2RlUXVlcnlQYXJhbSh2YWx1ZVtpXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVuY29kZWQgKz0gc2VwYXJhdG9yICsgdGhpcy5lbmNvZGVRdWVyeVBhcmFtKHZhbHVlW2ldKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZW5jb2RlZDtcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuZW5jb2RlUXVlcnlDb2xsZWN0aW9uID0gZnVuY3Rpb24gKHR5cGUsIG5hbWUsIHZhbHVlKSB7XG4gIHZhciBlbmNvZGVkID0gJyc7XG4gIHZhciBpO1xuXG4gIGlmICh0eXBlID09PSAnZGVmYXVsdCcgfHwgdHlwZSA9PT0gJ211bHRpJykge1xuICAgIGZvciAoaSA9IDA7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGkgPiAwKSB7ZW5jb2RlZCArPSAnJic7fVxuXG4gICAgICBlbmNvZGVkICs9IHRoaXMuZW5jb2RlUXVlcnlQYXJhbShuYW1lKSArICc9JyArIHRoaXMuZW5jb2RlUXVlcnlQYXJhbSh2YWx1ZVtpXSk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHZhciBzZXBhcmF0b3IgPSAnJztcblxuICAgIGlmICh0eXBlID09PSAnY3N2Jykge1xuICAgICAgc2VwYXJhdG9yID0gJywnO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3NzdicpIHtcbiAgICAgIHNlcGFyYXRvciA9ICclMjAnO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3RzdicpIHtcbiAgICAgIHNlcGFyYXRvciA9ICdcXFxcdCc7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAncGlwZXMnKSB7XG4gICAgICBzZXBhcmF0b3IgPSAnfCc7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnYnJhY2tldHMnKSB7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGkgIT09IDApIHtcbiAgICAgICAgICBlbmNvZGVkICs9ICcmJztcbiAgICAgICAgfVxuXG4gICAgICAgIGVuY29kZWQgKz0gdGhpcy5lbmNvZGVRdWVyeVBhcmFtKG5hbWUpICsgJ1tdPScgKyB0aGlzLmVuY29kZVF1ZXJ5UGFyYW0odmFsdWVbaV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzZXBhcmF0b3IgIT09ICcnKSB7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGkgPT09IDApIHtcbiAgICAgICAgICBlbmNvZGVkID0gdGhpcy5lbmNvZGVRdWVyeVBhcmFtKG5hbWUpICsgJz0nICsgdGhpcy5lbmNvZGVRdWVyeVBhcmFtKHZhbHVlW2ldKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBlbmNvZGVkICs9IHNlcGFyYXRvciArIHRoaXMuZW5jb2RlUXVlcnlQYXJhbSh2YWx1ZVtpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gZW5jb2RlZDtcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuZW5jb2RlUXVlcnlQYXJhbSA9IGZ1bmN0aW9uIChhcmcpIHtcbiAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudChhcmcpO1xufTtcblxuLyoqXG4gKiBUT0RPIHJldmlzaXQsIG1pZ2h0IG5vdCB3YW50IHRvIGxlYXZlICcvJ1xuICoqL1xuT3BlcmF0aW9uLnByb3RvdHlwZS5lbmNvZGVQYXRoUGFyYW0gPSBmdW5jdGlvbiAocGF0aFBhcmFtKSB7XG4gIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQocGF0aFBhcmFtKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBPcGVyYXRpb25Hcm91cCA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHRhZywgZGVzY3JpcHRpb24sIGV4dGVybmFsRG9jcywgb3BlcmF0aW9uKSB7XG4gIHRoaXMuZGVzY3JpcHRpb24gPSBkZXNjcmlwdGlvbjtcbiAgdGhpcy5leHRlcm5hbERvY3MgPSBleHRlcm5hbERvY3M7XG4gIHRoaXMubmFtZSA9IHRhZztcbiAgdGhpcy5vcGVyYXRpb24gPSBvcGVyYXRpb247XG4gIHRoaXMub3BlcmF0aW9uc0FycmF5ID0gW107XG4gIHRoaXMucGF0aCA9IHRhZztcbiAgdGhpcy50YWcgPSB0YWc7XG59O1xuXG5PcGVyYXRpb25Hcm91cC5wcm90b3R5cGUuc29ydCA9IGZ1bmN0aW9uICgpIHtcblxufTtcblxuIixudWxsLCIvKiFcbiAqIFRoZSBidWZmZXIgbW9kdWxlIGZyb20gbm9kZS5qcywgZm9yIHRoZSBicm93c2VyLlxuICpcbiAqIEBhdXRob3IgICBGZXJvc3MgQWJvdWtoYWRpamVoIDxmZXJvc3NAZmVyb3NzLm9yZz4gPGh0dHA6Ly9mZXJvc3Mub3JnPlxuICogQGxpY2Vuc2UgIE1JVFxuICovXG5cbnZhciBiYXNlNjQgPSByZXF1aXJlKCdiYXNlNjQtanMnKVxudmFyIGllZWU3NTQgPSByZXF1aXJlKCdpZWVlNzU0JylcbnZhciBpc0FycmF5ID0gcmVxdWlyZSgnaXMtYXJyYXknKVxuXG5leHBvcnRzLkJ1ZmZlciA9IEJ1ZmZlclxuZXhwb3J0cy5TbG93QnVmZmVyID0gU2xvd0J1ZmZlclxuZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUyA9IDUwXG5CdWZmZXIucG9vbFNpemUgPSA4MTkyIC8vIG5vdCB1c2VkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb25cblxudmFyIGtNYXhMZW5ndGggPSAweDNmZmZmZmZmXG52YXIgcm9vdFBhcmVudCA9IHt9XG5cbi8qKlxuICogSWYgYEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUYDpcbiAqICAgPT09IHRydWUgICAgVXNlIFVpbnQ4QXJyYXkgaW1wbGVtZW50YXRpb24gKGZhc3Rlc3QpXG4gKiAgID09PSBmYWxzZSAgIFVzZSBPYmplY3QgaW1wbGVtZW50YXRpb24gKG1vc3QgY29tcGF0aWJsZSwgZXZlbiBJRTYpXG4gKlxuICogQnJvd3NlcnMgdGhhdCBzdXBwb3J0IHR5cGVkIGFycmF5cyBhcmUgSUUgMTArLCBGaXJlZm94IDQrLCBDaHJvbWUgNyssIFNhZmFyaSA1LjErLFxuICogT3BlcmEgMTEuNissIGlPUyA0LjIrLlxuICpcbiAqIE5vdGU6XG4gKlxuICogLSBJbXBsZW1lbnRhdGlvbiBtdXN0IHN1cHBvcnQgYWRkaW5nIG5ldyBwcm9wZXJ0aWVzIHRvIGBVaW50OEFycmF5YCBpbnN0YW5jZXMuXG4gKiAgIEZpcmVmb3ggNC0yOSBsYWNrZWQgc3VwcG9ydCwgZml4ZWQgaW4gRmlyZWZveCAzMCsuXG4gKiAgIFNlZTogaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9Njk1NDM4LlxuICpcbiAqICAtIENocm9tZSA5LTEwIGlzIG1pc3NpbmcgdGhlIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24uXG4gKlxuICogIC0gSUUxMCBoYXMgYSBicm9rZW4gYFR5cGVkQXJyYXkucHJvdG90eXBlLnN1YmFycmF5YCBmdW5jdGlvbiB3aGljaCByZXR1cm5zIGFycmF5cyBvZlxuICogICAgaW5jb3JyZWN0IGxlbmd0aCBpbiBzb21lIHNpdHVhdGlvbnMuXG4gKlxuICogV2UgZGV0ZWN0IHRoZXNlIGJ1Z2d5IGJyb3dzZXJzIGFuZCBzZXQgYEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUYCB0byBgZmFsc2VgIHNvIHRoZXkgd2lsbFxuICogZ2V0IHRoZSBPYmplY3QgaW1wbGVtZW50YXRpb24sIHdoaWNoIGlzIHNsb3dlciBidXQgd2lsbCB3b3JrIGNvcnJlY3RseS5cbiAqL1xuQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgPSAoZnVuY3Rpb24gKCkge1xuICB0cnkge1xuICAgIHZhciBidWYgPSBuZXcgQXJyYXlCdWZmZXIoMClcbiAgICB2YXIgYXJyID0gbmV3IFVpbnQ4QXJyYXkoYnVmKVxuICAgIGFyci5mb28gPSBmdW5jdGlvbiAoKSB7IHJldHVybiA0MiB9XG4gICAgcmV0dXJuIGFyci5mb28oKSA9PT0gNDIgJiYgLy8gdHlwZWQgYXJyYXkgaW5zdGFuY2VzIGNhbiBiZSBhdWdtZW50ZWRcbiAgICAgICAgdHlwZW9mIGFyci5zdWJhcnJheSA9PT0gJ2Z1bmN0aW9uJyAmJiAvLyBjaHJvbWUgOS0xMCBsYWNrIGBzdWJhcnJheWBcbiAgICAgICAgbmV3IFVpbnQ4QXJyYXkoMSkuc3ViYXJyYXkoMSwgMSkuYnl0ZUxlbmd0aCA9PT0gMCAvLyBpZTEwIGhhcyBicm9rZW4gYHN1YmFycmF5YFxuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbn0pKClcblxuLyoqXG4gKiBDbGFzczogQnVmZmVyXG4gKiA9PT09PT09PT09PT09XG4gKlxuICogVGhlIEJ1ZmZlciBjb25zdHJ1Y3RvciByZXR1cm5zIGluc3RhbmNlcyBvZiBgVWludDhBcnJheWAgdGhhdCBhcmUgYXVnbWVudGVkXG4gKiB3aXRoIGZ1bmN0aW9uIHByb3BlcnRpZXMgZm9yIGFsbCB0aGUgbm9kZSBgQnVmZmVyYCBBUEkgZnVuY3Rpb25zLiBXZSB1c2VcbiAqIGBVaW50OEFycmF5YCBzbyB0aGF0IHNxdWFyZSBicmFja2V0IG5vdGF0aW9uIHdvcmtzIGFzIGV4cGVjdGVkIC0tIGl0IHJldHVybnNcbiAqIGEgc2luZ2xlIG9jdGV0LlxuICpcbiAqIEJ5IGF1Z21lbnRpbmcgdGhlIGluc3RhbmNlcywgd2UgY2FuIGF2b2lkIG1vZGlmeWluZyB0aGUgYFVpbnQ4QXJyYXlgXG4gKiBwcm90b3R5cGUuXG4gKi9cbmZ1bmN0aW9uIEJ1ZmZlciAoc3ViamVjdCwgZW5jb2RpbmcpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIGlmICghKHNlbGYgaW5zdGFuY2VvZiBCdWZmZXIpKSByZXR1cm4gbmV3IEJ1ZmZlcihzdWJqZWN0LCBlbmNvZGluZylcblxuICB2YXIgdHlwZSA9IHR5cGVvZiBzdWJqZWN0XG4gIHZhciBsZW5ndGhcblxuICBpZiAodHlwZSA9PT0gJ251bWJlcicpIHtcbiAgICBsZW5ndGggPSArc3ViamVjdFxuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgbGVuZ3RoID0gQnVmZmVyLmJ5dGVMZW5ndGgoc3ViamVjdCwgZW5jb2RpbmcpXG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ29iamVjdCcgJiYgc3ViamVjdCAhPT0gbnVsbCkge1xuICAgIC8vIGFzc3VtZSBvYmplY3QgaXMgYXJyYXktbGlrZVxuICAgIGlmIChzdWJqZWN0LnR5cGUgPT09ICdCdWZmZXInICYmIGlzQXJyYXkoc3ViamVjdC5kYXRhKSkgc3ViamVjdCA9IHN1YmplY3QuZGF0YVxuICAgIGxlbmd0aCA9ICtzdWJqZWN0Lmxlbmd0aFxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ211c3Qgc3RhcnQgd2l0aCBudW1iZXIsIGJ1ZmZlciwgYXJyYXkgb3Igc3RyaW5nJylcbiAgfVxuXG4gIGlmIChsZW5ndGggPiBrTWF4TGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0F0dGVtcHQgdG8gYWxsb2NhdGUgQnVmZmVyIGxhcmdlciB0aGFuIG1heGltdW0gc2l6ZTogMHgnICtcbiAgICAgIGtNYXhMZW5ndGgudG9TdHJpbmcoMTYpICsgJyBieXRlcycpXG4gIH1cblxuICBpZiAobGVuZ3RoIDwgMCkgbGVuZ3RoID0gMFxuICBlbHNlIGxlbmd0aCA+Pj49IDAgLy8gY29lcmNlIHRvIHVpbnQzMlxuXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIC8vIFByZWZlcnJlZDogUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2UgZm9yIGJlc3QgcGVyZm9ybWFuY2VcbiAgICBzZWxmID0gQnVmZmVyLl9hdWdtZW50KG5ldyBVaW50OEFycmF5KGxlbmd0aCkpIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgY29uc2lzdGVudC10aGlzXG4gIH0gZWxzZSB7XG4gICAgLy8gRmFsbGJhY2s6IFJldHVybiBUSElTIGluc3RhbmNlIG9mIEJ1ZmZlciAoY3JlYXRlZCBieSBgbmV3YClcbiAgICBzZWxmLmxlbmd0aCA9IGxlbmd0aFxuICAgIHNlbGYuX2lzQnVmZmVyID0gdHJ1ZVxuICB9XG5cbiAgdmFyIGlcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUICYmIHR5cGVvZiBzdWJqZWN0LmJ5dGVMZW5ndGggPT09ICdudW1iZXInKSB7XG4gICAgLy8gU3BlZWQgb3B0aW1pemF0aW9uIC0tIHVzZSBzZXQgaWYgd2UncmUgY29weWluZyBmcm9tIGEgdHlwZWQgYXJyYXlcbiAgICBzZWxmLl9zZXQoc3ViamVjdClcbiAgfSBlbHNlIGlmIChpc0FycmF5aXNoKHN1YmplY3QpKSB7XG4gICAgLy8gVHJlYXQgYXJyYXktaXNoIG9iamVjdHMgYXMgYSBieXRlIGFycmF5XG4gICAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihzdWJqZWN0KSkge1xuICAgICAgZm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHNlbGZbaV0gPSBzdWJqZWN0LnJlYWRVSW50OChpKVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgc2VsZltpXSA9ICgoc3ViamVjdFtpXSAlIDI1NikgKyAyNTYpICUgMjU2XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgc2VsZi53cml0ZShzdWJqZWN0LCAwLCBlbmNvZGluZylcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJyAmJiAhQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHNlbGZbaV0gPSAwXG4gICAgfVxuICB9XG5cbiAgaWYgKGxlbmd0aCA+IDAgJiYgbGVuZ3RoIDw9IEJ1ZmZlci5wb29sU2l6ZSkgc2VsZi5wYXJlbnQgPSByb290UGFyZW50XG5cbiAgcmV0dXJuIHNlbGZcbn1cblxuZnVuY3Rpb24gU2xvd0J1ZmZlciAoc3ViamVjdCwgZW5jb2RpbmcpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFNsb3dCdWZmZXIpKSByZXR1cm4gbmV3IFNsb3dCdWZmZXIoc3ViamVjdCwgZW5jb2RpbmcpXG5cbiAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIoc3ViamVjdCwgZW5jb2RpbmcpXG4gIGRlbGV0ZSBidWYucGFyZW50XG4gIHJldHVybiBidWZcbn1cblxuQnVmZmVyLmlzQnVmZmVyID0gZnVuY3Rpb24gaXNCdWZmZXIgKGIpIHtcbiAgcmV0dXJuICEhKGIgIT0gbnVsbCAmJiBiLl9pc0J1ZmZlcilcbn1cblxuQnVmZmVyLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlIChhLCBiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGEpIHx8ICFCdWZmZXIuaXNCdWZmZXIoYikpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudHMgbXVzdCBiZSBCdWZmZXJzJylcbiAgfVxuXG4gIGlmIChhID09PSBiKSByZXR1cm4gMFxuXG4gIHZhciB4ID0gYS5sZW5ndGhcbiAgdmFyIHkgPSBiLmxlbmd0aFxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gTWF0aC5taW4oeCwgeSk7IGkgPCBsZW4gJiYgYVtpXSA9PT0gYltpXTsgaSsrKSB7fVxuICBpZiAoaSAhPT0gbGVuKSB7XG4gICAgeCA9IGFbaV1cbiAgICB5ID0gYltpXVxuICB9XG4gIGlmICh4IDwgeSkgcmV0dXJuIC0xXG4gIGlmICh5IDwgeCkgcmV0dXJuIDFcbiAgcmV0dXJuIDBcbn1cblxuQnVmZmVyLmlzRW5jb2RpbmcgPSBmdW5jdGlvbiBpc0VuY29kaW5nIChlbmNvZGluZykge1xuICBzd2l0Y2ggKFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKSkge1xuICAgIGNhc2UgJ2hleCc6XG4gICAgY2FzZSAndXRmOCc6XG4gICAgY2FzZSAndXRmLTgnOlxuICAgIGNhc2UgJ2FzY2lpJzpcbiAgICBjYXNlICdiaW5hcnknOlxuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgY2FzZSAncmF3JzpcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgcmV0dXJuIHRydWVcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuQnVmZmVyLmNvbmNhdCA9IGZ1bmN0aW9uIGNvbmNhdCAobGlzdCwgdG90YWxMZW5ndGgpIHtcbiAgaWYgKCFpc0FycmF5KGxpc3QpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdsaXN0IGFyZ3VtZW50IG11c3QgYmUgYW4gQXJyYXkgb2YgQnVmZmVycy4nKVxuXG4gIGlmIChsaXN0Lmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBuZXcgQnVmZmVyKDApXG4gIH0gZWxzZSBpZiAobGlzdC5sZW5ndGggPT09IDEpIHtcbiAgICByZXR1cm4gbGlzdFswXVxuICB9XG5cbiAgdmFyIGlcbiAgaWYgKHRvdGFsTGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICB0b3RhbExlbmd0aCA9IDBcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7IGkrKykge1xuICAgICAgdG90YWxMZW5ndGggKz0gbGlzdFtpXS5sZW5ndGhcbiAgICB9XG4gIH1cblxuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcih0b3RhbExlbmd0aClcbiAgdmFyIHBvcyA9IDBcbiAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgaXRlbSA9IGxpc3RbaV1cbiAgICBpdGVtLmNvcHkoYnVmLCBwb3MpXG4gICAgcG9zICs9IGl0ZW0ubGVuZ3RoXG4gIH1cbiAgcmV0dXJuIGJ1ZlxufVxuXG5CdWZmZXIuYnl0ZUxlbmd0aCA9IGZ1bmN0aW9uIGJ5dGVMZW5ndGggKHN0ciwgZW5jb2RpbmcpIHtcbiAgdmFyIHJldFxuICBzdHIgPSBzdHIgKyAnJ1xuICBzd2l0Y2ggKGVuY29kaW5nIHx8ICd1dGY4Jykge1xuICAgIGNhc2UgJ2FzY2lpJzpcbiAgICBjYXNlICdiaW5hcnknOlxuICAgIGNhc2UgJ3Jhdyc6XG4gICAgICByZXQgPSBzdHIubGVuZ3RoXG4gICAgICBicmVha1xuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICBjYXNlICd1dGYxNmxlJzpcbiAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICByZXQgPSBzdHIubGVuZ3RoICogMlxuICAgICAgYnJlYWtcbiAgICBjYXNlICdoZXgnOlxuICAgICAgcmV0ID0gc3RyLmxlbmd0aCA+Pj4gMVxuICAgICAgYnJlYWtcbiAgICBjYXNlICd1dGY4JzpcbiAgICBjYXNlICd1dGYtOCc6XG4gICAgICByZXQgPSB1dGY4VG9CeXRlcyhzdHIpLmxlbmd0aFxuICAgICAgYnJlYWtcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgcmV0ID0gYmFzZTY0VG9CeXRlcyhzdHIpLmxlbmd0aFxuICAgICAgYnJlYWtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0ID0gc3RyLmxlbmd0aFxuICB9XG4gIHJldHVybiByZXRcbn1cblxuLy8gcHJlLXNldCBmb3IgdmFsdWVzIHRoYXQgbWF5IGV4aXN0IGluIHRoZSBmdXR1cmVcbkJ1ZmZlci5wcm90b3R5cGUubGVuZ3RoID0gdW5kZWZpbmVkXG5CdWZmZXIucHJvdG90eXBlLnBhcmVudCA9IHVuZGVmaW5lZFxuXG4vLyB0b1N0cmluZyhlbmNvZGluZywgc3RhcnQ9MCwgZW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcgKGVuY29kaW5nLCBzdGFydCwgZW5kKSB7XG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG5cbiAgc3RhcnQgPSBzdGFydCA+Pj4gMFxuICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCB8fCBlbmQgPT09IEluZmluaXR5ID8gdGhpcy5sZW5ndGggOiBlbmQgPj4+IDBcblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuICBpZiAoc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgaWYgKGVuZCA+IHRoaXMubGVuZ3RoKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAoZW5kIDw9IHN0YXJ0KSByZXR1cm4gJydcblxuICB3aGlsZSAodHJ1ZSkge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBoZXhTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICAgIHJldHVybiBhc2NpaVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBiaW5hcnlTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICByZXR1cm4gYmFzZTY0U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIHV0ZjE2bGVTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICAgICAgZW5jb2RpbmcgPSAoZW5jb2RpbmcgKyAnJykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbiBlcXVhbHMgKGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXInKVxuICBpZiAodGhpcyA9PT0gYikgcmV0dXJuIHRydWVcbiAgcmV0dXJuIEJ1ZmZlci5jb21wYXJlKHRoaXMsIGIpID09PSAwXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5zcGVjdCA9IGZ1bmN0aW9uIGluc3BlY3QgKCkge1xuICB2YXIgc3RyID0gJydcbiAgdmFyIG1heCA9IGV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVNcbiAgaWYgKHRoaXMubGVuZ3RoID4gMCkge1xuICAgIHN0ciA9IHRoaXMudG9TdHJpbmcoJ2hleCcsIDAsIG1heCkubWF0Y2goLy57Mn0vZykuam9pbignICcpXG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbWF4KSBzdHIgKz0gJyAuLi4gJ1xuICB9XG4gIHJldHVybiAnPEJ1ZmZlciAnICsgc3RyICsgJz4nXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUgKGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXInKVxuICBpZiAodGhpcyA9PT0gYikgcmV0dXJuIDBcbiAgcmV0dXJuIEJ1ZmZlci5jb21wYXJlKHRoaXMsIGIpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5kZXhPZiA9IGZ1bmN0aW9uIGluZGV4T2YgKHZhbCwgYnl0ZU9mZnNldCkge1xuICBpZiAoYnl0ZU9mZnNldCA+IDB4N2ZmZmZmZmYpIGJ5dGVPZmZzZXQgPSAweDdmZmZmZmZmXG4gIGVsc2UgaWYgKGJ5dGVPZmZzZXQgPCAtMHg4MDAwMDAwMCkgYnl0ZU9mZnNldCA9IC0weDgwMDAwMDAwXG4gIGJ5dGVPZmZzZXQgPj49IDBcblxuICBpZiAodGhpcy5sZW5ndGggPT09IDApIHJldHVybiAtMVxuICBpZiAoYnl0ZU9mZnNldCA+PSB0aGlzLmxlbmd0aCkgcmV0dXJuIC0xXG5cbiAgLy8gTmVnYXRpdmUgb2Zmc2V0cyBzdGFydCBmcm9tIHRoZSBlbmQgb2YgdGhlIGJ1ZmZlclxuICBpZiAoYnl0ZU9mZnNldCA8IDApIGJ5dGVPZmZzZXQgPSBNYXRoLm1heCh0aGlzLmxlbmd0aCArIGJ5dGVPZmZzZXQsIDApXG5cbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKHZhbC5sZW5ndGggPT09IDApIHJldHVybiAtMSAvLyBzcGVjaWFsIGNhc2U6IGxvb2tpbmcgZm9yIGVtcHR5IHN0cmluZyBhbHdheXMgZmFpbHNcbiAgICByZXR1cm4gU3RyaW5nLnByb3RvdHlwZS5pbmRleE9mLmNhbGwodGhpcywgdmFsLCBieXRlT2Zmc2V0KVxuICB9XG4gIGlmIChCdWZmZXIuaXNCdWZmZXIodmFsKSkge1xuICAgIHJldHVybiBhcnJheUluZGV4T2YodGhpcywgdmFsLCBieXRlT2Zmc2V0KVxuICB9XG4gIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCAmJiBVaW50OEFycmF5LnByb3RvdHlwZS5pbmRleE9mID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKHRoaXMsIHZhbCwgYnl0ZU9mZnNldClcbiAgICB9XG4gICAgcmV0dXJuIGFycmF5SW5kZXhPZih0aGlzLCBbIHZhbCBdLCBieXRlT2Zmc2V0KVxuICB9XG5cbiAgZnVuY3Rpb24gYXJyYXlJbmRleE9mIChhcnIsIHZhbCwgYnl0ZU9mZnNldCkge1xuICAgIHZhciBmb3VuZEluZGV4ID0gLTFcbiAgICBmb3IgKHZhciBpID0gMDsgYnl0ZU9mZnNldCArIGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChhcnJbYnl0ZU9mZnNldCArIGldID09PSB2YWxbZm91bmRJbmRleCA9PT0gLTEgPyAwIDogaSAtIGZvdW5kSW5kZXhdKSB7XG4gICAgICAgIGlmIChmb3VuZEluZGV4ID09PSAtMSkgZm91bmRJbmRleCA9IGlcbiAgICAgICAgaWYgKGkgLSBmb3VuZEluZGV4ICsgMSA9PT0gdmFsLmxlbmd0aCkgcmV0dXJuIGJ5dGVPZmZzZXQgKyBmb3VuZEluZGV4XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3VuZEluZGV4ID0gLTFcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIC0xXG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKCd2YWwgbXVzdCBiZSBzdHJpbmcsIG51bWJlciBvciBCdWZmZXInKVxufVxuXG4vLyBgZ2V0YCB3aWxsIGJlIHJlbW92ZWQgaW4gTm9kZSAwLjEzK1xuQnVmZmVyLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiBnZXQgKG9mZnNldCkge1xuICBjb25zb2xlLmxvZygnLmdldCgpIGlzIGRlcHJlY2F0ZWQuIEFjY2VzcyB1c2luZyBhcnJheSBpbmRleGVzIGluc3RlYWQuJylcbiAgcmV0dXJuIHRoaXMucmVhZFVJbnQ4KG9mZnNldClcbn1cblxuLy8gYHNldGAgd2lsbCBiZSByZW1vdmVkIGluIE5vZGUgMC4xMytcbkJ1ZmZlci5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gc2V0ICh2LCBvZmZzZXQpIHtcbiAgY29uc29sZS5sb2coJy5zZXQoKSBpcyBkZXByZWNhdGVkLiBBY2Nlc3MgdXNpbmcgYXJyYXkgaW5kZXhlcyBpbnN0ZWFkLicpXG4gIHJldHVybiB0aGlzLndyaXRlVUludDgodiwgb2Zmc2V0KVxufVxuXG5mdW5jdGlvbiBoZXhXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIG9mZnNldCA9IE51bWJlcihvZmZzZXQpIHx8IDBcbiAgdmFyIHJlbWFpbmluZyA9IGJ1Zi5sZW5ndGggLSBvZmZzZXRcbiAgaWYgKCFsZW5ndGgpIHtcbiAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgfSBlbHNlIHtcbiAgICBsZW5ndGggPSBOdW1iZXIobGVuZ3RoKVxuICAgIGlmIChsZW5ndGggPiByZW1haW5pbmcpIHtcbiAgICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICAgIH1cbiAgfVxuXG4gIC8vIG11c3QgYmUgYW4gZXZlbiBudW1iZXIgb2YgZGlnaXRzXG4gIHZhciBzdHJMZW4gPSBzdHJpbmcubGVuZ3RoXG4gIGlmIChzdHJMZW4gJSAyICE9PSAwKSB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaGV4IHN0cmluZycpXG5cbiAgaWYgKGxlbmd0aCA+IHN0ckxlbiAvIDIpIHtcbiAgICBsZW5ndGggPSBzdHJMZW4gLyAyXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgIHZhciBwYXJzZWQgPSBwYXJzZUludChzdHJpbmcuc3Vic3RyKGkgKiAyLCAyKSwgMTYpXG4gICAgaWYgKGlzTmFOKHBhcnNlZCkpIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBoZXggc3RyaW5nJylcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSBwYXJzZWRcbiAgfVxuICByZXR1cm4gaVxufVxuXG5mdW5jdGlvbiB1dGY4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICB2YXIgY2hhcnNXcml0dGVuID0gYmxpdEJ1ZmZlcih1dGY4VG9CeXRlcyhzdHJpbmcsIGJ1Zi5sZW5ndGggLSBvZmZzZXQpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxuICByZXR1cm4gY2hhcnNXcml0dGVuXG59XG5cbmZ1bmN0aW9uIGFzY2lpV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICB2YXIgY2hhcnNXcml0dGVuID0gYmxpdEJ1ZmZlcihhc2NpaVRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbiAgcmV0dXJuIGNoYXJzV3JpdHRlblxufVxuXG5mdW5jdGlvbiBiaW5hcnlXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBhc2NpaVdyaXRlKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYmFzZTY0V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICB2YXIgY2hhcnNXcml0dGVuID0gYmxpdEJ1ZmZlcihiYXNlNjRUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG4gIHJldHVybiBjaGFyc1dyaXR0ZW5cbn1cblxuZnVuY3Rpb24gdXRmMTZsZVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgdmFyIGNoYXJzV3JpdHRlbiA9IGJsaXRCdWZmZXIodXRmMTZsZVRvQnl0ZXMoc3RyaW5nLCBidWYubGVuZ3RoIC0gb2Zmc2V0KSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbiAgcmV0dXJuIGNoYXJzV3JpdHRlblxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gd3JpdGUgKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgsIGVuY29kaW5nKSB7XG4gIC8vIFN1cHBvcnQgYm90aCAoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCwgZW5jb2RpbmcpXG4gIC8vIGFuZCB0aGUgbGVnYWN5IChzdHJpbmcsIGVuY29kaW5nLCBvZmZzZXQsIGxlbmd0aClcbiAgaWYgKGlzRmluaXRlKG9mZnNldCkpIHtcbiAgICBpZiAoIWlzRmluaXRlKGxlbmd0aCkpIHtcbiAgICAgIGVuY29kaW5nID0gbGVuZ3RoXG4gICAgICBsZW5ndGggPSB1bmRlZmluZWRcbiAgICB9XG4gIH0gZWxzZSB7ICAvLyBsZWdhY3lcbiAgICB2YXIgc3dhcCA9IGVuY29kaW5nXG4gICAgZW5jb2RpbmcgPSBvZmZzZXRcbiAgICBvZmZzZXQgPSBsZW5ndGhcbiAgICBsZW5ndGggPSBzd2FwXG4gIH1cblxuICBvZmZzZXQgPSBOdW1iZXIob2Zmc2V0KSB8fCAwXG5cbiAgaWYgKGxlbmd0aCA8IDAgfHwgb2Zmc2V0IDwgMCB8fCBvZmZzZXQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdhdHRlbXB0IHRvIHdyaXRlIG91dHNpZGUgYnVmZmVyIGJvdW5kcycpXG4gIH1cblxuICB2YXIgcmVtYWluaW5nID0gdGhpcy5sZW5ndGggLSBvZmZzZXRcbiAgaWYgKCFsZW5ndGgpIHtcbiAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgfSBlbHNlIHtcbiAgICBsZW5ndGggPSBOdW1iZXIobGVuZ3RoKVxuICAgIGlmIChsZW5ndGggPiByZW1haW5pbmcpIHtcbiAgICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICAgIH1cbiAgfVxuICBlbmNvZGluZyA9IFN0cmluZyhlbmNvZGluZyB8fCAndXRmOCcpLnRvTG93ZXJDYXNlKClcblxuICB2YXIgcmV0XG4gIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICBjYXNlICdoZXgnOlxuICAgICAgcmV0ID0gaGV4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAndXRmOCc6XG4gICAgY2FzZSAndXRmLTgnOlxuICAgICAgcmV0ID0gdXRmOFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgIHJldCA9IGFzY2lpV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgIHJldCA9IGJpbmFyeVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICByZXQgPSBiYXNlNjRXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuICAgICAgYnJlYWtcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgcmV0ID0gdXRmMTZsZVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG4gICAgICBicmVha1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTiAoKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogJ0J1ZmZlcicsXG4gICAgZGF0YTogQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwodGhpcy5fYXJyIHx8IHRoaXMsIDApXG4gIH1cbn1cblxuZnVuY3Rpb24gYmFzZTY0U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICBpZiAoc3RhcnQgPT09IDAgJiYgZW5kID09PSBidWYubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1ZilcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmLnNsaWNlKHN0YXJ0LCBlbmQpKVxuICB9XG59XG5cbmZ1bmN0aW9uIHV0ZjhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXMgPSAnJ1xuICB2YXIgdG1wID0gJydcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgaWYgKGJ1ZltpXSA8PSAweDdGKSB7XG4gICAgICByZXMgKz0gZGVjb2RlVXRmOENoYXIodG1wKSArIFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldKVxuICAgICAgdG1wID0gJydcbiAgICB9IGVsc2Uge1xuICAgICAgdG1wICs9ICclJyArIGJ1ZltpXS50b1N0cmluZygxNilcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzICsgZGVjb2RlVXRmOENoYXIodG1wKVxufVxuXG5mdW5jdGlvbiBhc2NpaVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJldCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSAmIDB4N0YpXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBiaW5hcnlTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0pXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBoZXhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG5cbiAgaWYgKCFzdGFydCB8fCBzdGFydCA8IDApIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCB8fCBlbmQgPCAwIHx8IGVuZCA+IGxlbikgZW5kID0gbGVuXG5cbiAgdmFyIG91dCA9ICcnXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgb3V0ICs9IHRvSGV4KGJ1ZltpXSlcbiAgfVxuICByZXR1cm4gb3V0XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBieXRlcyA9IGJ1Zi5zbGljZShzdGFydCwgZW5kKVxuICB2YXIgcmVzID0gJydcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkgKz0gMikge1xuICAgIHJlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGVzW2ldICsgYnl0ZXNbaSArIDFdICogMjU2KVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uIHNsaWNlIChzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBzdGFydCA9IH5+c3RhcnRcbiAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyBsZW4gOiB+fmVuZFxuXG4gIGlmIChzdGFydCA8IDApIHtcbiAgICBzdGFydCArPSBsZW5cbiAgICBpZiAoc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgfSBlbHNlIGlmIChzdGFydCA+IGxlbikge1xuICAgIHN0YXJ0ID0gbGVuXG4gIH1cblxuICBpZiAoZW5kIDwgMCkge1xuICAgIGVuZCArPSBsZW5cbiAgICBpZiAoZW5kIDwgMCkgZW5kID0gMFxuICB9IGVsc2UgaWYgKGVuZCA+IGxlbikge1xuICAgIGVuZCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIHZhciBuZXdCdWZcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgbmV3QnVmID0gQnVmZmVyLl9hdWdtZW50KHRoaXMuc3ViYXJyYXkoc3RhcnQsIGVuZCkpXG4gIH0gZWxzZSB7XG4gICAgdmFyIHNsaWNlTGVuID0gZW5kIC0gc3RhcnRcbiAgICBuZXdCdWYgPSBuZXcgQnVmZmVyKHNsaWNlTGVuLCB1bmRlZmluZWQpXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzbGljZUxlbjsgaSsrKSB7XG4gICAgICBuZXdCdWZbaV0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH1cblxuICBpZiAobmV3QnVmLmxlbmd0aCkgbmV3QnVmLnBhcmVudCA9IHRoaXMucGFyZW50IHx8IHRoaXNcblxuICByZXR1cm4gbmV3QnVmXG59XG5cbi8qXG4gKiBOZWVkIHRvIG1ha2Ugc3VyZSB0aGF0IGJ1ZmZlciBpc24ndCB0cnlpbmcgdG8gd3JpdGUgb3V0IG9mIGJvdW5kcy5cbiAqL1xuZnVuY3Rpb24gY2hlY2tPZmZzZXQgKG9mZnNldCwgZXh0LCBsZW5ndGgpIHtcbiAgaWYgKChvZmZzZXQgJSAxKSAhPT0gMCB8fCBvZmZzZXQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignb2Zmc2V0IGlzIG5vdCB1aW50JylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RyeWluZyB0byBhY2Nlc3MgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50TEUgPSBmdW5jdGlvbiByZWFkVUludExFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludEJFID0gZnVuY3Rpb24gcmVhZFVJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG4gIH1cblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAtLWJ5dGVMZW5ndGhdXG4gIHZhciBtdWwgPSAxXG4gIHdoaWxlIChieXRlTGVuZ3RoID4gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIC0tYnl0ZUxlbmd0aF0gKiBtdWxcbiAgfVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDggPSBmdW5jdGlvbiByZWFkVUludDggKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAxLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIHRoaXNbb2Zmc2V0XVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZMRSA9IGZ1bmN0aW9uIHJlYWRVSW50MTZMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gdGhpc1tvZmZzZXRdIHwgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2QkUgPSBmdW5jdGlvbiByZWFkVUludDE2QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuICh0aGlzW29mZnNldF0gPDwgOCkgfCB0aGlzW29mZnNldCArIDFdXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkxFID0gZnVuY3Rpb24gcmVhZFVJbnQzMkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICgodGhpc1tvZmZzZXRdKSB8XG4gICAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KSB8XG4gICAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCAxNikpICtcbiAgICAgICh0aGlzW29mZnNldCArIDNdICogMHgxMDAwMDAwKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJCRSA9IGZ1bmN0aW9uIHJlYWRVSW50MzJCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdICogMHgxMDAwMDAwKSArXG4gICAgKCh0aGlzW29mZnNldCArIDFdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgOCkgfFxuICAgIHRoaXNbb2Zmc2V0ICsgM10pXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludExFID0gZnVuY3Rpb24gcmVhZEludExFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKSB2YWwgLT0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpXG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnRCRSA9IGZ1bmN0aW9uIHJlYWRJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgaSA9IGJ5dGVMZW5ndGhcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1pXVxuICB3aGlsZSAoaSA+IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyAtLWldICogbXVsXG4gIH1cbiAgbXVsICo9IDB4ODBcblxuICBpZiAodmFsID49IG11bCkgdmFsIC09IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50OCA9IGZ1bmN0aW9uIHJlYWRJbnQ4IChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIGlmICghKHRoaXNbb2Zmc2V0XSAmIDB4ODApKSByZXR1cm4gKHRoaXNbb2Zmc2V0XSlcbiAgcmV0dXJuICgoMHhmZiAtIHRoaXNbb2Zmc2V0XSArIDEpICogLTEpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2TEUgPSBmdW5jdGlvbiByZWFkSW50MTZMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdIHwgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOClcbiAgcmV0dXJuICh2YWwgJiAweDgwMDApID8gdmFsIHwgMHhGRkZGMDAwMCA6IHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkJFID0gZnVuY3Rpb24gcmVhZEludDE2QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgMV0gfCAodGhpc1tvZmZzZXRdIDw8IDgpXG4gIHJldHVybiAodmFsICYgMHg4MDAwKSA/IHZhbCB8IDB4RkZGRjAwMDAgOiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJMRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0pIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSA8PCAyNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJCRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0gPDwgMjQpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRMRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdExFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRCRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdEJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCBmYWxzZSwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUxFID0gZnVuY3Rpb24gcmVhZERvdWJsZUxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgOCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCA1MiwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlQkUgPSBmdW5jdGlvbiByZWFkRG91YmxlQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA4LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCA1MiwgOClcbn1cblxuZnVuY3Rpb24gY2hlY2tJbnQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihidWYpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdidWZmZXIgbXVzdCBiZSBhIEJ1ZmZlciBpbnN0YW5jZScpXG4gIGlmICh2YWx1ZSA+IG1heCB8fCB2YWx1ZSA8IG1pbikgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3ZhbHVlIGlzIG91dCBvZiBib3VuZHMnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnRMRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKSwgMClcblxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgdGhpc1tvZmZzZXRdID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICh2YWx1ZSAvIG11bCkgPj4+IDAgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludEJFID0gZnVuY3Rpb24gd3JpdGVVSW50QkUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCksIDApXG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoIC0gMVxuICB2YXIgbXVsID0gMVxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpID4+PiAwICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQ4ID0gZnVuY3Rpb24gd3JpdGVVSW50OCAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDEsIDB4ZmYsIDApXG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHZhbHVlID0gTWF0aC5mbG9vcih2YWx1ZSlcbiAgdGhpc1tvZmZzZXRdID0gdmFsdWVcbiAgcmV0dXJuIG9mZnNldCArIDFcbn1cblxuZnVuY3Rpb24gb2JqZWN0V3JpdGVVSW50MTYgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZmZmICsgdmFsdWUgKyAxXG4gIGZvciAodmFyIGkgPSAwLCBqID0gTWF0aC5taW4oYnVmLmxlbmd0aCAtIG9mZnNldCwgMik7IGkgPCBqOyBpKyspIHtcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSAodmFsdWUgJiAoMHhmZiA8PCAoOCAqIChsaXR0bGVFbmRpYW4gPyBpIDogMSAtIGkpKSkpID4+PlxuICAgICAgKGxpdHRsZUVuZGlhbiA/IGkgOiAxIC0gaSkgKiA4XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkxFID0gZnVuY3Rpb24gd3JpdGVVSW50MTZMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gdmFsdWVcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVVSW50MTZCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSB2YWx1ZVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbmZ1bmN0aW9uIG9iamVjdFdyaXRlVUludDMyIChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDFcbiAgZm9yICh2YXIgaSA9IDAsIGogPSBNYXRoLm1pbihidWYubGVuZ3RoIC0gb2Zmc2V0LCA0KTsgaSA8IGo7IGkrKykge1xuICAgIGJ1ZltvZmZzZXQgKyBpXSA9ICh2YWx1ZSA+Pj4gKGxpdHRsZUVuZGlhbiA/IGkgOiAzIC0gaSkgKiA4KSAmIDB4ZmZcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyTEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHhmZmZmZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldF0gPSB2YWx1ZVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkJFID0gZnVuY3Rpb24gd3JpdGVVSW50MzJCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDNdID0gdmFsdWVcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50TEUgPSBmdW5jdGlvbiB3cml0ZUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrSW50KFxuICAgICAgdGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCxcbiAgICAgIE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoIC0gMSkgLSAxLFxuICAgICAgLU1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoIC0gMSlcbiAgICApXG4gIH1cblxuICB2YXIgaSA9IDBcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHN1YiA9IHZhbHVlIDwgMCA/IDEgOiAwXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAoKHZhbHVlIC8gbXVsKSA+PiAwKSAtIHN1YiAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRCRSA9IGZ1bmN0aW9uIHdyaXRlSW50QkUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJbnQoXG4gICAgICB0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLFxuICAgICAgTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGggLSAxKSAtIDEsXG4gICAgICAtTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGggLSAxKVxuICAgIClcbiAgfVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHN1YiA9IHZhbHVlIDwgMCA/IDEgOiAwXG4gIHRoaXNbb2Zmc2V0ICsgaV0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKC0taSA+PSAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICgodmFsdWUgLyBtdWwpID4+IDApIC0gc3ViICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDggPSBmdW5jdGlvbiB3cml0ZUludDggKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAxLCAweDdmLCAtMHg4MClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkgdmFsdWUgPSBNYXRoLmZsb29yKHZhbHVlKVxuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmYgKyB2YWx1ZSArIDFcbiAgdGhpc1tvZmZzZXRdID0gdmFsdWVcbiAgcmV0dXJuIG9mZnNldCArIDFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2TEUgPSBmdW5jdGlvbiB3cml0ZUludDE2TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweDdmZmYsIC0weDgwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9IHZhbHVlXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVJbnQxNkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHg3ZmZmLCAtMHg4MDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9IHZhbHVlXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyTEUgPSBmdW5jdGlvbiB3cml0ZUludDMyTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gdmFsdWVcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgPj4+IDI0KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZUludDMyQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmZmZmZmICsgdmFsdWUgKyAxXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDNdID0gdmFsdWVcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5mdW5jdGlvbiBjaGVja0lFRUU3NTQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAodmFsdWUgPiBtYXggfHwgdmFsdWUgPCBtaW4pIHRocm93IG5ldyBSYW5nZUVycm9yKCd2YWx1ZSBpcyBvdXQgb2YgYm91bmRzJylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGJ1Zi5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdpbmRleCBvdXQgb2YgcmFuZ2UnKVxuICBpZiAob2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbmZ1bmN0aW9uIHdyaXRlRmxvYXQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgNCwgMy40MDI4MjM0NjYzODUyODg2ZSszOCwgLTMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgpXG4gIH1cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgMjMsIDQpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdExFID0gZnVuY3Rpb24gd3JpdGVGbG9hdExFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0QkUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gd3JpdGVEb3VibGUgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgOCwgMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgsIC0xLjc5NzY5MzEzNDg2MjMxNTdFKzMwOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCA1MiwgOClcbiAgcmV0dXJuIG9mZnNldCArIDhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUxFID0gZnVuY3Rpb24gd3JpdGVEb3VibGVMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlQkUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG4vLyBjb3B5KHRhcmdldEJ1ZmZlciwgdGFyZ2V0U3RhcnQ9MCwgc291cmNlU3RhcnQ9MCwgc291cmNlRW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbiBjb3B5ICh0YXJnZXQsIHRhcmdldF9zdGFydCwgc3RhcnQsIGVuZCkge1xuICBpZiAoIXN0YXJ0KSBzdGFydCA9IDBcbiAgaWYgKCFlbmQgJiYgZW5kICE9PSAwKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0X3N0YXJ0ID49IHRhcmdldC5sZW5ndGgpIHRhcmdldF9zdGFydCA9IHRhcmdldC5sZW5ndGhcbiAgaWYgKCF0YXJnZXRfc3RhcnQpIHRhcmdldF9zdGFydCA9IDBcbiAgaWYgKGVuZCA+IDAgJiYgZW5kIDwgc3RhcnQpIGVuZCA9IHN0YXJ0XG5cbiAgLy8gQ29weSAwIGJ5dGVzOyB3ZSdyZSBkb25lXG4gIGlmIChlbmQgPT09IHN0YXJ0KSByZXR1cm4gMFxuICBpZiAodGFyZ2V0Lmxlbmd0aCA9PT0gMCB8fCB0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIDBcblxuICAvLyBGYXRhbCBlcnJvciBjb25kaXRpb25zXG4gIGlmICh0YXJnZXRfc3RhcnQgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3RhcmdldFN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICB9XG4gIGlmIChzdGFydCA8IDAgfHwgc3RhcnQgPj0gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgaWYgKGVuZCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VFbmQgb3V0IG9mIGJvdW5kcycpXG5cbiAgLy8gQXJlIHdlIG9vYj9cbiAgaWYgKGVuZCA+IHRoaXMubGVuZ3RoKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0Lmxlbmd0aCAtIHRhcmdldF9zdGFydCA8IGVuZCAtIHN0YXJ0KSB7XG4gICAgZW5kID0gdGFyZ2V0Lmxlbmd0aCAtIHRhcmdldF9zdGFydCArIHN0YXJ0XG4gIH1cblxuICB2YXIgbGVuID0gZW5kIC0gc3RhcnRcblxuICBpZiAobGVuIDwgMTAwMCB8fCAhQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICB0YXJnZXRbaSArIHRhcmdldF9zdGFydF0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGFyZ2V0Ll9zZXQodGhpcy5zdWJhcnJheShzdGFydCwgc3RhcnQgKyBsZW4pLCB0YXJnZXRfc3RhcnQpXG4gIH1cblxuICByZXR1cm4gbGVuXG59XG5cbi8vIGZpbGwodmFsdWUsIHN0YXJ0PTAsIGVuZD1idWZmZXIubGVuZ3RoKVxuQnVmZmVyLnByb3RvdHlwZS5maWxsID0gZnVuY3Rpb24gZmlsbCAodmFsdWUsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKCF2YWx1ZSkgdmFsdWUgPSAwXG4gIGlmICghc3RhcnQpIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCkgZW5kID0gdGhpcy5sZW5ndGhcblxuICBpZiAoZW5kIDwgc3RhcnQpIHRocm93IG5ldyBSYW5nZUVycm9yKCdlbmQgPCBzdGFydCcpXG5cbiAgLy8gRmlsbCAwIGJ5dGVzOyB3ZSdyZSBkb25lXG4gIGlmIChlbmQgPT09IHN0YXJ0KSByZXR1cm5cbiAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm5cblxuICBpZiAoc3RhcnQgPCAwIHx8IHN0YXJ0ID49IHRoaXMubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignc3RhcnQgb3V0IG9mIGJvdW5kcycpXG4gIGlmIChlbmQgPCAwIHx8IGVuZCA+IHRoaXMubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignZW5kIG91dCBvZiBib3VuZHMnKVxuXG4gIHZhciBpXG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgZm9yIChpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgICAgdGhpc1tpXSA9IHZhbHVlXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHZhciBieXRlcyA9IHV0ZjhUb0J5dGVzKHZhbHVlLnRvU3RyaW5nKCkpXG4gICAgdmFyIGxlbiA9IGJ5dGVzLmxlbmd0aFxuICAgIGZvciAoaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICAgIHRoaXNbaV0gPSBieXRlc1tpICUgbGVuXVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzXG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBgQXJyYXlCdWZmZXJgIHdpdGggdGhlICpjb3BpZWQqIG1lbW9yeSBvZiB0aGUgYnVmZmVyIGluc3RhbmNlLlxuICogQWRkZWQgaW4gTm9kZSAwLjEyLiBPbmx5IGF2YWlsYWJsZSBpbiBicm93c2VycyB0aGF0IHN1cHBvcnQgQXJyYXlCdWZmZXIuXG4gKi9cbkJ1ZmZlci5wcm90b3R5cGUudG9BcnJheUJ1ZmZlciA9IGZ1bmN0aW9uIHRvQXJyYXlCdWZmZXIgKCkge1xuICBpZiAodHlwZW9mIFVpbnQ4QXJyYXkgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgICByZXR1cm4gKG5ldyBCdWZmZXIodGhpcykpLmJ1ZmZlclxuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgYnVmID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5sZW5ndGgpXG4gICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gYnVmLmxlbmd0aDsgaSA8IGxlbjsgaSArPSAxKSB7XG4gICAgICAgIGJ1ZltpXSA9IHRoaXNbaV1cbiAgICAgIH1cbiAgICAgIHJldHVybiBidWYuYnVmZmVyXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0J1ZmZlci50b0FycmF5QnVmZmVyIG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyBicm93c2VyJylcbiAgfVxufVxuXG4vLyBIRUxQRVIgRlVOQ1RJT05TXG4vLyA9PT09PT09PT09PT09PT09XG5cbnZhciBCUCA9IEJ1ZmZlci5wcm90b3R5cGVcblxuLyoqXG4gKiBBdWdtZW50IGEgVWludDhBcnJheSAqaW5zdGFuY2UqIChub3QgdGhlIFVpbnQ4QXJyYXkgY2xhc3MhKSB3aXRoIEJ1ZmZlciBtZXRob2RzXG4gKi9cbkJ1ZmZlci5fYXVnbWVudCA9IGZ1bmN0aW9uIF9hdWdtZW50IChhcnIpIHtcbiAgYXJyLmNvbnN0cnVjdG9yID0gQnVmZmVyXG4gIGFyci5faXNCdWZmZXIgPSB0cnVlXG5cbiAgLy8gc2F2ZSByZWZlcmVuY2UgdG8gb3JpZ2luYWwgVWludDhBcnJheSBzZXQgbWV0aG9kIGJlZm9yZSBvdmVyd3JpdGluZ1xuICBhcnIuX3NldCA9IGFyci5zZXRcblxuICAvLyBkZXByZWNhdGVkLCB3aWxsIGJlIHJlbW92ZWQgaW4gbm9kZSAwLjEzK1xuICBhcnIuZ2V0ID0gQlAuZ2V0XG4gIGFyci5zZXQgPSBCUC5zZXRcblxuICBhcnIud3JpdGUgPSBCUC53cml0ZVxuICBhcnIudG9TdHJpbmcgPSBCUC50b1N0cmluZ1xuICBhcnIudG9Mb2NhbGVTdHJpbmcgPSBCUC50b1N0cmluZ1xuICBhcnIudG9KU09OID0gQlAudG9KU09OXG4gIGFyci5lcXVhbHMgPSBCUC5lcXVhbHNcbiAgYXJyLmNvbXBhcmUgPSBCUC5jb21wYXJlXG4gIGFyci5pbmRleE9mID0gQlAuaW5kZXhPZlxuICBhcnIuY29weSA9IEJQLmNvcHlcbiAgYXJyLnNsaWNlID0gQlAuc2xpY2VcbiAgYXJyLnJlYWRVSW50TEUgPSBCUC5yZWFkVUludExFXG4gIGFyci5yZWFkVUludEJFID0gQlAucmVhZFVJbnRCRVxuICBhcnIucmVhZFVJbnQ4ID0gQlAucmVhZFVJbnQ4XG4gIGFyci5yZWFkVUludDE2TEUgPSBCUC5yZWFkVUludDE2TEVcbiAgYXJyLnJlYWRVSW50MTZCRSA9IEJQLnJlYWRVSW50MTZCRVxuICBhcnIucmVhZFVJbnQzMkxFID0gQlAucmVhZFVJbnQzMkxFXG4gIGFyci5yZWFkVUludDMyQkUgPSBCUC5yZWFkVUludDMyQkVcbiAgYXJyLnJlYWRJbnRMRSA9IEJQLnJlYWRJbnRMRVxuICBhcnIucmVhZEludEJFID0gQlAucmVhZEludEJFXG4gIGFyci5yZWFkSW50OCA9IEJQLnJlYWRJbnQ4XG4gIGFyci5yZWFkSW50MTZMRSA9IEJQLnJlYWRJbnQxNkxFXG4gIGFyci5yZWFkSW50MTZCRSA9IEJQLnJlYWRJbnQxNkJFXG4gIGFyci5yZWFkSW50MzJMRSA9IEJQLnJlYWRJbnQzMkxFXG4gIGFyci5yZWFkSW50MzJCRSA9IEJQLnJlYWRJbnQzMkJFXG4gIGFyci5yZWFkRmxvYXRMRSA9IEJQLnJlYWRGbG9hdExFXG4gIGFyci5yZWFkRmxvYXRCRSA9IEJQLnJlYWRGbG9hdEJFXG4gIGFyci5yZWFkRG91YmxlTEUgPSBCUC5yZWFkRG91YmxlTEVcbiAgYXJyLnJlYWREb3VibGVCRSA9IEJQLnJlYWREb3VibGVCRVxuICBhcnIud3JpdGVVSW50OCA9IEJQLndyaXRlVUludDhcbiAgYXJyLndyaXRlVUludExFID0gQlAud3JpdGVVSW50TEVcbiAgYXJyLndyaXRlVUludEJFID0gQlAud3JpdGVVSW50QkVcbiAgYXJyLndyaXRlVUludDE2TEUgPSBCUC53cml0ZVVJbnQxNkxFXG4gIGFyci53cml0ZVVJbnQxNkJFID0gQlAud3JpdGVVSW50MTZCRVxuICBhcnIud3JpdGVVSW50MzJMRSA9IEJQLndyaXRlVUludDMyTEVcbiAgYXJyLndyaXRlVUludDMyQkUgPSBCUC53cml0ZVVJbnQzMkJFXG4gIGFyci53cml0ZUludExFID0gQlAud3JpdGVJbnRMRVxuICBhcnIud3JpdGVJbnRCRSA9IEJQLndyaXRlSW50QkVcbiAgYXJyLndyaXRlSW50OCA9IEJQLndyaXRlSW50OFxuICBhcnIud3JpdGVJbnQxNkxFID0gQlAud3JpdGVJbnQxNkxFXG4gIGFyci53cml0ZUludDE2QkUgPSBCUC53cml0ZUludDE2QkVcbiAgYXJyLndyaXRlSW50MzJMRSA9IEJQLndyaXRlSW50MzJMRVxuICBhcnIud3JpdGVJbnQzMkJFID0gQlAud3JpdGVJbnQzMkJFXG4gIGFyci53cml0ZUZsb2F0TEUgPSBCUC53cml0ZUZsb2F0TEVcbiAgYXJyLndyaXRlRmxvYXRCRSA9IEJQLndyaXRlRmxvYXRCRVxuICBhcnIud3JpdGVEb3VibGVMRSA9IEJQLndyaXRlRG91YmxlTEVcbiAgYXJyLndyaXRlRG91YmxlQkUgPSBCUC53cml0ZURvdWJsZUJFXG4gIGFyci5maWxsID0gQlAuZmlsbFxuICBhcnIuaW5zcGVjdCA9IEJQLmluc3BlY3RcbiAgYXJyLnRvQXJyYXlCdWZmZXIgPSBCUC50b0FycmF5QnVmZmVyXG5cbiAgcmV0dXJuIGFyclxufVxuXG52YXIgSU5WQUxJRF9CQVNFNjRfUkUgPSAvW14rXFwvMC05QS16XFwtXS9nXG5cbmZ1bmN0aW9uIGJhc2U2NGNsZWFuIChzdHIpIHtcbiAgLy8gTm9kZSBzdHJpcHMgb3V0IGludmFsaWQgY2hhcmFjdGVycyBsaWtlIFxcbiBhbmQgXFx0IGZyb20gdGhlIHN0cmluZywgYmFzZTY0LWpzIGRvZXMgbm90XG4gIHN0ciA9IHN0cmluZ3RyaW0oc3RyKS5yZXBsYWNlKElOVkFMSURfQkFTRTY0X1JFLCAnJylcbiAgLy8gTm9kZSBjb252ZXJ0cyBzdHJpbmdzIHdpdGggbGVuZ3RoIDwgMiB0byAnJ1xuICBpZiAoc3RyLmxlbmd0aCA8IDIpIHJldHVybiAnJ1xuICAvLyBOb2RlIGFsbG93cyBmb3Igbm9uLXBhZGRlZCBiYXNlNjQgc3RyaW5ncyAobWlzc2luZyB0cmFpbGluZyA9PT0pLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgd2hpbGUgKHN0ci5sZW5ndGggJSA0ICE9PSAwKSB7XG4gICAgc3RyID0gc3RyICsgJz0nXG4gIH1cbiAgcmV0dXJuIHN0clxufVxuXG5mdW5jdGlvbiBzdHJpbmd0cmltIChzdHIpIHtcbiAgaWYgKHN0ci50cmltKSByZXR1cm4gc3RyLnRyaW0oKVxuICByZXR1cm4gc3RyLnJlcGxhY2UoL15cXHMrfFxccyskL2csICcnKVxufVxuXG5mdW5jdGlvbiBpc0FycmF5aXNoIChzdWJqZWN0KSB7XG4gIHJldHVybiBpc0FycmF5KHN1YmplY3QpIHx8IEJ1ZmZlci5pc0J1ZmZlcihzdWJqZWN0KSB8fFxuICAgICAgc3ViamVjdCAmJiB0eXBlb2Ygc3ViamVjdCA9PT0gJ29iamVjdCcgJiZcbiAgICAgIHR5cGVvZiBzdWJqZWN0Lmxlbmd0aCA9PT0gJ251bWJlcidcbn1cblxuZnVuY3Rpb24gdG9IZXggKG4pIHtcbiAgaWYgKG4gPCAxNikgcmV0dXJuICcwJyArIG4udG9TdHJpbmcoMTYpXG4gIHJldHVybiBuLnRvU3RyaW5nKDE2KVxufVxuXG5mdW5jdGlvbiB1dGY4VG9CeXRlcyAoc3RyaW5nLCB1bml0cykge1xuICB1bml0cyA9IHVuaXRzIHx8IEluZmluaXR5XG4gIHZhciBjb2RlUG9pbnRcbiAgdmFyIGxlbmd0aCA9IHN0cmluZy5sZW5ndGhcbiAgdmFyIGxlYWRTdXJyb2dhdGUgPSBudWxsXG4gIHZhciBieXRlcyA9IFtdXG4gIHZhciBpID0gMFxuXG4gIGZvciAoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICBjb2RlUG9pbnQgPSBzdHJpbmcuY2hhckNvZGVBdChpKVxuXG4gICAgLy8gaXMgc3Vycm9nYXRlIGNvbXBvbmVudFxuICAgIGlmIChjb2RlUG9pbnQgPiAweEQ3RkYgJiYgY29kZVBvaW50IDwgMHhFMDAwKSB7XG4gICAgICAvLyBsYXN0IGNoYXIgd2FzIGEgbGVhZFxuICAgICAgaWYgKGxlYWRTdXJyb2dhdGUpIHtcbiAgICAgICAgLy8gMiBsZWFkcyBpbiBhIHJvd1xuICAgICAgICBpZiAoY29kZVBvaW50IDwgMHhEQzAwKSB7XG4gICAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgICAgbGVhZFN1cnJvZ2F0ZSA9IGNvZGVQb2ludFxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gdmFsaWQgc3Vycm9nYXRlIHBhaXJcbiAgICAgICAgICBjb2RlUG9pbnQgPSBsZWFkU3Vycm9nYXRlIC0gMHhEODAwIDw8IDEwIHwgY29kZVBvaW50IC0gMHhEQzAwIHwgMHgxMDAwMFxuICAgICAgICAgIGxlYWRTdXJyb2dhdGUgPSBudWxsXG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG5vIGxlYWQgeWV0XG5cbiAgICAgICAgaWYgKGNvZGVQb2ludCA+IDB4REJGRikge1xuICAgICAgICAgIC8vIHVuZXhwZWN0ZWQgdHJhaWxcbiAgICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9IGVsc2UgaWYgKGkgKyAxID09PSBsZW5ndGgpIHtcbiAgICAgICAgICAvLyB1bnBhaXJlZCBsZWFkXG4gICAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyB2YWxpZCBsZWFkXG4gICAgICAgICAgbGVhZFN1cnJvZ2F0ZSA9IGNvZGVQb2ludFxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGxlYWRTdXJyb2dhdGUpIHtcbiAgICAgIC8vIHZhbGlkIGJtcCBjaGFyLCBidXQgbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgbGVhZFN1cnJvZ2F0ZSA9IG51bGxcbiAgICB9XG5cbiAgICAvLyBlbmNvZGUgdXRmOFxuICAgIGlmIChjb2RlUG9pbnQgPCAweDgwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDEpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goY29kZVBvaW50KVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHg4MDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMikgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiB8IDB4QzAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDEwMDAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDMpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgfCAweEUwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2ICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDIwMDAwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSA0KSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHgxMiB8IDB4RjAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY29kZSBwb2ludCcpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVzXG59XG5cbmZ1bmN0aW9uIGFzY2lpVG9CeXRlcyAoc3RyKSB7XG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykge1xuICAgIC8vIE5vZGUncyBjb2RlIHNlZW1zIHRvIGJlIGRvaW5nIHRoaXMgYW5kIG5vdCAmIDB4N0YuLlxuICAgIGJ5dGVBcnJheS5wdXNoKHN0ci5jaGFyQ29kZUF0KGkpICYgMHhGRilcbiAgfVxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVUb0J5dGVzIChzdHIsIHVuaXRzKSB7XG4gIHZhciBjLCBoaSwgbG9cbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKCh1bml0cyAtPSAyKSA8IDApIGJyZWFrXG5cbiAgICBjID0gc3RyLmNoYXJDb2RlQXQoaSlcbiAgICBoaSA9IGMgPj4gOFxuICAgIGxvID0gYyAlIDI1NlxuICAgIGJ5dGVBcnJheS5wdXNoKGxvKVxuICAgIGJ5dGVBcnJheS5wdXNoKGhpKVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiBiYXNlNjRUb0J5dGVzIChzdHIpIHtcbiAgcmV0dXJuIGJhc2U2NC50b0J5dGVBcnJheShiYXNlNjRjbGVhbihzdHIpKVxufVxuXG5mdW5jdGlvbiBibGl0QnVmZmVyIChzcmMsIGRzdCwgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgIGlmICgoaSArIG9mZnNldCA+PSBkc3QubGVuZ3RoKSB8fCAoaSA+PSBzcmMubGVuZ3RoKSkgYnJlYWtcbiAgICBkc3RbaSArIG9mZnNldF0gPSBzcmNbaV1cbiAgfVxuICByZXR1cm4gaVxufVxuXG5mdW5jdGlvbiBkZWNvZGVVdGY4Q2hhciAoc3RyKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChzdHIpXG4gIH0gY2F0Y2ggKGVycikge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4RkZGRCkgLy8gVVRGIDggaW52YWxpZCBjaGFyXG4gIH1cbn1cbiIsInZhciBsb29rdXAgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLyc7XG5cbjsoZnVuY3Rpb24gKGV4cG9ydHMpIHtcblx0J3VzZSBzdHJpY3QnO1xuXG4gIHZhciBBcnIgPSAodHlwZW9mIFVpbnQ4QXJyYXkgIT09ICd1bmRlZmluZWQnKVxuICAgID8gVWludDhBcnJheVxuICAgIDogQXJyYXlcblxuXHR2YXIgUExVUyAgID0gJysnLmNoYXJDb2RlQXQoMClcblx0dmFyIFNMQVNIICA9ICcvJy5jaGFyQ29kZUF0KDApXG5cdHZhciBOVU1CRVIgPSAnMCcuY2hhckNvZGVBdCgwKVxuXHR2YXIgTE9XRVIgID0gJ2EnLmNoYXJDb2RlQXQoMClcblx0dmFyIFVQUEVSICA9ICdBJy5jaGFyQ29kZUF0KDApXG5cdHZhciBQTFVTX1VSTF9TQUZFID0gJy0nLmNoYXJDb2RlQXQoMClcblx0dmFyIFNMQVNIX1VSTF9TQUZFID0gJ18nLmNoYXJDb2RlQXQoMClcblxuXHRmdW5jdGlvbiBkZWNvZGUgKGVsdCkge1xuXHRcdHZhciBjb2RlID0gZWx0LmNoYXJDb2RlQXQoMClcblx0XHRpZiAoY29kZSA9PT0gUExVUyB8fFxuXHRcdCAgICBjb2RlID09PSBQTFVTX1VSTF9TQUZFKVxuXHRcdFx0cmV0dXJuIDYyIC8vICcrJ1xuXHRcdGlmIChjb2RlID09PSBTTEFTSCB8fFxuXHRcdCAgICBjb2RlID09PSBTTEFTSF9VUkxfU0FGRSlcblx0XHRcdHJldHVybiA2MyAvLyAnLydcblx0XHRpZiAoY29kZSA8IE5VTUJFUilcblx0XHRcdHJldHVybiAtMSAvL25vIG1hdGNoXG5cdFx0aWYgKGNvZGUgPCBOVU1CRVIgKyAxMClcblx0XHRcdHJldHVybiBjb2RlIC0gTlVNQkVSICsgMjYgKyAyNlxuXHRcdGlmIChjb2RlIDwgVVBQRVIgKyAyNilcblx0XHRcdHJldHVybiBjb2RlIC0gVVBQRVJcblx0XHRpZiAoY29kZSA8IExPV0VSICsgMjYpXG5cdFx0XHRyZXR1cm4gY29kZSAtIExPV0VSICsgMjZcblx0fVxuXG5cdGZ1bmN0aW9uIGI2NFRvQnl0ZUFycmF5IChiNjQpIHtcblx0XHR2YXIgaSwgaiwgbCwgdG1wLCBwbGFjZUhvbGRlcnMsIGFyclxuXG5cdFx0aWYgKGI2NC5sZW5ndGggJSA0ID4gMCkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHN0cmluZy4gTGVuZ3RoIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA0Jylcblx0XHR9XG5cblx0XHQvLyB0aGUgbnVtYmVyIG9mIGVxdWFsIHNpZ25zIChwbGFjZSBob2xkZXJzKVxuXHRcdC8vIGlmIHRoZXJlIGFyZSB0d28gcGxhY2Vob2xkZXJzLCB0aGFuIHRoZSB0d28gY2hhcmFjdGVycyBiZWZvcmUgaXRcblx0XHQvLyByZXByZXNlbnQgb25lIGJ5dGVcblx0XHQvLyBpZiB0aGVyZSBpcyBvbmx5IG9uZSwgdGhlbiB0aGUgdGhyZWUgY2hhcmFjdGVycyBiZWZvcmUgaXQgcmVwcmVzZW50IDIgYnl0ZXNcblx0XHQvLyB0aGlzIGlzIGp1c3QgYSBjaGVhcCBoYWNrIHRvIG5vdCBkbyBpbmRleE9mIHR3aWNlXG5cdFx0dmFyIGxlbiA9IGI2NC5sZW5ndGhcblx0XHRwbGFjZUhvbGRlcnMgPSAnPScgPT09IGI2NC5jaGFyQXQobGVuIC0gMikgPyAyIDogJz0nID09PSBiNjQuY2hhckF0KGxlbiAtIDEpID8gMSA6IDBcblxuXHRcdC8vIGJhc2U2NCBpcyA0LzMgKyB1cCB0byB0d28gY2hhcmFjdGVycyBvZiB0aGUgb3JpZ2luYWwgZGF0YVxuXHRcdGFyciA9IG5ldyBBcnIoYjY0Lmxlbmd0aCAqIDMgLyA0IC0gcGxhY2VIb2xkZXJzKVxuXG5cdFx0Ly8gaWYgdGhlcmUgYXJlIHBsYWNlaG9sZGVycywgb25seSBnZXQgdXAgdG8gdGhlIGxhc3QgY29tcGxldGUgNCBjaGFyc1xuXHRcdGwgPSBwbGFjZUhvbGRlcnMgPiAwID8gYjY0Lmxlbmd0aCAtIDQgOiBiNjQubGVuZ3RoXG5cblx0XHR2YXIgTCA9IDBcblxuXHRcdGZ1bmN0aW9uIHB1c2ggKHYpIHtcblx0XHRcdGFycltMKytdID0gdlxuXHRcdH1cblxuXHRcdGZvciAoaSA9IDAsIGogPSAwOyBpIDwgbDsgaSArPSA0LCBqICs9IDMpIHtcblx0XHRcdHRtcCA9IChkZWNvZGUoYjY0LmNoYXJBdChpKSkgPDwgMTgpIHwgKGRlY29kZShiNjQuY2hhckF0KGkgKyAxKSkgPDwgMTIpIHwgKGRlY29kZShiNjQuY2hhckF0KGkgKyAyKSkgPDwgNikgfCBkZWNvZGUoYjY0LmNoYXJBdChpICsgMykpXG5cdFx0XHRwdXNoKCh0bXAgJiAweEZGMDAwMCkgPj4gMTYpXG5cdFx0XHRwdXNoKCh0bXAgJiAweEZGMDApID4+IDgpXG5cdFx0XHRwdXNoKHRtcCAmIDB4RkYpXG5cdFx0fVxuXG5cdFx0aWYgKHBsYWNlSG9sZGVycyA9PT0gMikge1xuXHRcdFx0dG1wID0gKGRlY29kZShiNjQuY2hhckF0KGkpKSA8PCAyKSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMSkpID4+IDQpXG5cdFx0XHRwdXNoKHRtcCAmIDB4RkYpXG5cdFx0fSBlbHNlIGlmIChwbGFjZUhvbGRlcnMgPT09IDEpIHtcblx0XHRcdHRtcCA9IChkZWNvZGUoYjY0LmNoYXJBdChpKSkgPDwgMTApIHwgKGRlY29kZShiNjQuY2hhckF0KGkgKyAxKSkgPDwgNCkgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDIpKSA+PiAyKVxuXHRcdFx0cHVzaCgodG1wID4+IDgpICYgMHhGRilcblx0XHRcdHB1c2godG1wICYgMHhGRilcblx0XHR9XG5cblx0XHRyZXR1cm4gYXJyXG5cdH1cblxuXHRmdW5jdGlvbiB1aW50OFRvQmFzZTY0ICh1aW50OCkge1xuXHRcdHZhciBpLFxuXHRcdFx0ZXh0cmFCeXRlcyA9IHVpbnQ4Lmxlbmd0aCAlIDMsIC8vIGlmIHdlIGhhdmUgMSBieXRlIGxlZnQsIHBhZCAyIGJ5dGVzXG5cdFx0XHRvdXRwdXQgPSBcIlwiLFxuXHRcdFx0dGVtcCwgbGVuZ3RoXG5cblx0XHRmdW5jdGlvbiBlbmNvZGUgKG51bSkge1xuXHRcdFx0cmV0dXJuIGxvb2t1cC5jaGFyQXQobnVtKVxuXHRcdH1cblxuXHRcdGZ1bmN0aW9uIHRyaXBsZXRUb0Jhc2U2NCAobnVtKSB7XG5cdFx0XHRyZXR1cm4gZW5jb2RlKG51bSA+PiAxOCAmIDB4M0YpICsgZW5jb2RlKG51bSA+PiAxMiAmIDB4M0YpICsgZW5jb2RlKG51bSA+PiA2ICYgMHgzRikgKyBlbmNvZGUobnVtICYgMHgzRilcblx0XHR9XG5cblx0XHQvLyBnbyB0aHJvdWdoIHRoZSBhcnJheSBldmVyeSB0aHJlZSBieXRlcywgd2UnbGwgZGVhbCB3aXRoIHRyYWlsaW5nIHN0dWZmIGxhdGVyXG5cdFx0Zm9yIChpID0gMCwgbGVuZ3RoID0gdWludDgubGVuZ3RoIC0gZXh0cmFCeXRlczsgaSA8IGxlbmd0aDsgaSArPSAzKSB7XG5cdFx0XHR0ZW1wID0gKHVpbnQ4W2ldIDw8IDE2KSArICh1aW50OFtpICsgMV0gPDwgOCkgKyAodWludDhbaSArIDJdKVxuXHRcdFx0b3V0cHV0ICs9IHRyaXBsZXRUb0Jhc2U2NCh0ZW1wKVxuXHRcdH1cblxuXHRcdC8vIHBhZCB0aGUgZW5kIHdpdGggemVyb3MsIGJ1dCBtYWtlIHN1cmUgdG8gbm90IGZvcmdldCB0aGUgZXh0cmEgYnl0ZXNcblx0XHRzd2l0Y2ggKGV4dHJhQnl0ZXMpIHtcblx0XHRcdGNhc2UgMTpcblx0XHRcdFx0dGVtcCA9IHVpbnQ4W3VpbnQ4Lmxlbmd0aCAtIDFdXG5cdFx0XHRcdG91dHB1dCArPSBlbmNvZGUodGVtcCA+PiAyKVxuXHRcdFx0XHRvdXRwdXQgKz0gZW5jb2RlKCh0ZW1wIDw8IDQpICYgMHgzRilcblx0XHRcdFx0b3V0cHV0ICs9ICc9PSdcblx0XHRcdFx0YnJlYWtcblx0XHRcdGNhc2UgMjpcblx0XHRcdFx0dGVtcCA9ICh1aW50OFt1aW50OC5sZW5ndGggLSAyXSA8PCA4KSArICh1aW50OFt1aW50OC5sZW5ndGggLSAxXSlcblx0XHRcdFx0b3V0cHV0ICs9IGVuY29kZSh0ZW1wID4+IDEwKVxuXHRcdFx0XHRvdXRwdXQgKz0gZW5jb2RlKCh0ZW1wID4+IDQpICYgMHgzRilcblx0XHRcdFx0b3V0cHV0ICs9IGVuY29kZSgodGVtcCA8PCAyKSAmIDB4M0YpXG5cdFx0XHRcdG91dHB1dCArPSAnPSdcblx0XHRcdFx0YnJlYWtcblx0XHR9XG5cblx0XHRyZXR1cm4gb3V0cHV0XG5cdH1cblxuXHRleHBvcnRzLnRvQnl0ZUFycmF5ID0gYjY0VG9CeXRlQXJyYXlcblx0ZXhwb3J0cy5mcm9tQnl0ZUFycmF5ID0gdWludDhUb0Jhc2U2NFxufSh0eXBlb2YgZXhwb3J0cyA9PT0gJ3VuZGVmaW5lZCcgPyAodGhpcy5iYXNlNjRqcyA9IHt9KSA6IGV4cG9ydHMpKVxuIiwiZXhwb3J0cy5yZWFkID0gZnVuY3Rpb24oYnVmZmVyLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbSxcbiAgICAgIGVMZW4gPSBuQnl0ZXMgKiA4IC0gbUxlbiAtIDEsXG4gICAgICBlTWF4ID0gKDEgPDwgZUxlbikgLSAxLFxuICAgICAgZUJpYXMgPSBlTWF4ID4+IDEsXG4gICAgICBuQml0cyA9IC03LFxuICAgICAgaSA9IGlzTEUgPyAobkJ5dGVzIC0gMSkgOiAwLFxuICAgICAgZCA9IGlzTEUgPyAtMSA6IDEsXG4gICAgICBzID0gYnVmZmVyW29mZnNldCArIGldO1xuXG4gIGkgKz0gZDtcblxuICBlID0gcyAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKTtcbiAgcyA+Pj0gKC1uQml0cyk7XG4gIG5CaXRzICs9IGVMZW47XG4gIGZvciAoOyBuQml0cyA+IDA7IGUgPSBlICogMjU2ICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpO1xuXG4gIG0gPSBlICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpO1xuICBlID4+PSAoLW5CaXRzKTtcbiAgbkJpdHMgKz0gbUxlbjtcbiAgZm9yICg7IG5CaXRzID4gMDsgbSA9IG0gKiAyNTYgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCk7XG5cbiAgaWYgKGUgPT09IDApIHtcbiAgICBlID0gMSAtIGVCaWFzO1xuICB9IGVsc2UgaWYgKGUgPT09IGVNYXgpIHtcbiAgICByZXR1cm4gbSA/IE5hTiA6ICgocyA/IC0xIDogMSkgKiBJbmZpbml0eSk7XG4gIH0gZWxzZSB7XG4gICAgbSA9IG0gKyBNYXRoLnBvdygyLCBtTGVuKTtcbiAgICBlID0gZSAtIGVCaWFzO1xuICB9XG4gIHJldHVybiAocyA/IC0xIDogMSkgKiBtICogTWF0aC5wb3coMiwgZSAtIG1MZW4pO1xufTtcblxuZXhwb3J0cy53cml0ZSA9IGZ1bmN0aW9uKGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtLCBjLFxuICAgICAgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMSxcbiAgICAgIGVNYXggPSAoMSA8PCBlTGVuKSAtIDEsXG4gICAgICBlQmlhcyA9IGVNYXggPj4gMSxcbiAgICAgIHJ0ID0gKG1MZW4gPT09IDIzID8gTWF0aC5wb3coMiwgLTI0KSAtIE1hdGgucG93KDIsIC03NykgOiAwKSxcbiAgICAgIGkgPSBpc0xFID8gMCA6IChuQnl0ZXMgLSAxKSxcbiAgICAgIGQgPSBpc0xFID8gMSA6IC0xLFxuICAgICAgcyA9IHZhbHVlIDwgMCB8fCAodmFsdWUgPT09IDAgJiYgMSAvIHZhbHVlIDwgMCkgPyAxIDogMDtcblxuICB2YWx1ZSA9IE1hdGguYWJzKHZhbHVlKTtcblxuICBpZiAoaXNOYU4odmFsdWUpIHx8IHZhbHVlID09PSBJbmZpbml0eSkge1xuICAgIG0gPSBpc05hTih2YWx1ZSkgPyAxIDogMDtcbiAgICBlID0gZU1heDtcbiAgfSBlbHNlIHtcbiAgICBlID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMik7XG4gICAgaWYgKHZhbHVlICogKGMgPSBNYXRoLnBvdygyLCAtZSkpIDwgMSkge1xuICAgICAgZS0tO1xuICAgICAgYyAqPSAyO1xuICAgIH1cbiAgICBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIHZhbHVlICs9IHJ0IC8gYztcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWUgKz0gcnQgKiBNYXRoLnBvdygyLCAxIC0gZUJpYXMpO1xuICAgIH1cbiAgICBpZiAodmFsdWUgKiBjID49IDIpIHtcbiAgICAgIGUrKztcbiAgICAgIGMgLz0gMjtcbiAgICB9XG5cbiAgICBpZiAoZSArIGVCaWFzID49IGVNYXgpIHtcbiAgICAgIG0gPSAwO1xuICAgICAgZSA9IGVNYXg7XG4gICAgfSBlbHNlIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgbSA9ICh2YWx1ZSAqIGMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pO1xuICAgICAgZSA9IGUgKyBlQmlhcztcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IHZhbHVlICogTWF0aC5wb3coMiwgZUJpYXMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pO1xuICAgICAgZSA9IDA7XG4gICAgfVxuICB9XG5cbiAgZm9yICg7IG1MZW4gPj0gODsgYnVmZmVyW29mZnNldCArIGldID0gbSAmIDB4ZmYsIGkgKz0gZCwgbSAvPSAyNTYsIG1MZW4gLT0gOCk7XG5cbiAgZSA9IChlIDw8IG1MZW4pIHwgbTtcbiAgZUxlbiArPSBtTGVuO1xuICBmb3IgKDsgZUxlbiA+IDA7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IGUgJiAweGZmLCBpICs9IGQsIGUgLz0gMjU2LCBlTGVuIC09IDgpO1xuXG4gIGJ1ZmZlcltvZmZzZXQgKyBpIC0gZF0gfD0gcyAqIDEyODtcbn07XG4iLCJcbi8qKlxuICogaXNBcnJheVxuICovXG5cbnZhciBpc0FycmF5ID0gQXJyYXkuaXNBcnJheTtcblxuLyoqXG4gKiB0b1N0cmluZ1xuICovXG5cbnZhciBzdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG4vKipcbiAqIFdoZXRoZXIgb3Igbm90IHRoZSBnaXZlbiBgdmFsYFxuICogaXMgYW4gYXJyYXkuXG4gKlxuICogZXhhbXBsZTpcbiAqXG4gKiAgICAgICAgaXNBcnJheShbXSk7XG4gKiAgICAgICAgLy8gPiB0cnVlXG4gKiAgICAgICAgaXNBcnJheShhcmd1bWVudHMpO1xuICogICAgICAgIC8vID4gZmFsc2VcbiAqICAgICAgICBpc0FycmF5KCcnKTtcbiAqICAgICAgICAvLyA+IGZhbHNlXG4gKlxuICogQHBhcmFtIHttaXhlZH0gdmFsXG4gKiBAcmV0dXJuIHtib29sfVxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gaXNBcnJheSB8fCBmdW5jdGlvbiAodmFsKSB7XG4gIHJldHVybiAhISB2YWwgJiYgJ1tvYmplY3QgQXJyYXldJyA9PSBzdHIuY2FsbCh2YWwpO1xufTtcbiIsIi8vIHNoaW0gZm9yIHVzaW5nIHByb2Nlc3MgaW4gYnJvd3NlclxuXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG52YXIgcXVldWUgPSBbXTtcbnZhciBkcmFpbmluZyA9IGZhbHNlO1xuXG5mdW5jdGlvbiBkcmFpblF1ZXVlKCkge1xuICAgIGlmIChkcmFpbmluZykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGRyYWluaW5nID0gdHJ1ZTtcbiAgICB2YXIgY3VycmVudFF1ZXVlO1xuICAgIHZhciBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgd2hpbGUobGVuKSB7XG4gICAgICAgIGN1cnJlbnRRdWV1ZSA9IHF1ZXVlO1xuICAgICAgICBxdWV1ZSA9IFtdO1xuICAgICAgICB2YXIgaSA9IC0xO1xuICAgICAgICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgICAgICAgICBjdXJyZW50UXVldWVbaV0oKTtcbiAgICAgICAgfVxuICAgICAgICBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgfVxuICAgIGRyYWluaW5nID0gZmFsc2U7XG59XG5wcm9jZXNzLm5leHRUaWNrID0gZnVuY3Rpb24gKGZ1bikge1xuICAgIHF1ZXVlLnB1c2goZnVuKTtcbiAgICBpZiAoIWRyYWluaW5nKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZHJhaW5RdWV1ZSwgMCk7XG4gICAgfVxufTtcblxucHJvY2Vzcy50aXRsZSA9ICdicm93c2VyJztcbnByb2Nlc3MuYnJvd3NlciA9IHRydWU7XG5wcm9jZXNzLmVudiA9IHt9O1xucHJvY2Vzcy5hcmd2ID0gW107XG5wcm9jZXNzLnZlcnNpb24gPSAnJzsgLy8gZW1wdHkgc3RyaW5nIHRvIGF2b2lkIHJlZ2V4cCBpc3N1ZXNcbnByb2Nlc3MudmVyc2lvbnMgPSB7fTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnByb2Nlc3Mub24gPSBub29wO1xucHJvY2Vzcy5hZGRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLm9uY2UgPSBub29wO1xucHJvY2Vzcy5vZmYgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUFsbExpc3RlbmVycyA9IG5vb3A7XG5wcm9jZXNzLmVtaXQgPSBub29wO1xuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5cbi8vIFRPRE8oc2h0eWxtYW4pXG5wcm9jZXNzLmN3ZCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuICcvJyB9O1xucHJvY2Vzcy5jaGRpciA9IGZ1bmN0aW9uIChkaXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuY2hkaXIgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcbnByb2Nlc3MudW1hc2sgPSBmdW5jdGlvbigpIHsgcmV0dXJuIDA7IH07XG4iLCIoZnVuY3Rpb24gKCkge1xuICBcInVzZSBzdHJpY3RcIjtcblxuICBmdW5jdGlvbiBidG9hKHN0cikge1xuICAgIHZhciBidWZmZXJcbiAgICAgIDtcblxuICAgIGlmIChzdHIgaW5zdGFuY2VvZiBCdWZmZXIpIHtcbiAgICAgIGJ1ZmZlciA9IHN0cjtcbiAgICB9IGVsc2Uge1xuICAgICAgYnVmZmVyID0gbmV3IEJ1ZmZlcihzdHIudG9TdHJpbmcoKSwgJ2JpbmFyeScpO1xuICAgIH1cblxuICAgIHJldHVybiBidWZmZXIudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICB9XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBidG9hO1xufSgpKTtcbiIsIi8qIGpzaGludCBub2RlOiB0cnVlICovXG4oZnVuY3Rpb24gKCkge1xuICAgIFwidXNlIHN0cmljdFwiO1xuXG4gICAgZnVuY3Rpb24gQ29va2llQWNjZXNzSW5mbyhkb21haW4sIHBhdGgsIHNlY3VyZSwgc2NyaXB0KSB7XG4gICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgQ29va2llQWNjZXNzSW5mbykge1xuICAgICAgICAgICAgdGhpcy5kb21haW4gPSBkb21haW4gfHwgdW5kZWZpbmVkO1xuICAgICAgICAgICAgdGhpcy5wYXRoID0gcGF0aCB8fCBcIi9cIjtcbiAgICAgICAgICAgIHRoaXMuc2VjdXJlID0gISFzZWN1cmU7XG4gICAgICAgICAgICB0aGlzLnNjcmlwdCA9ICEhc2NyaXB0O1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBDb29raWVBY2Nlc3NJbmZvKGRvbWFpbiwgcGF0aCwgc2VjdXJlLCBzY3JpcHQpO1xuICAgIH1cbiAgICBleHBvcnRzLkNvb2tpZUFjY2Vzc0luZm8gPSBDb29raWVBY2Nlc3NJbmZvO1xuXG4gICAgZnVuY3Rpb24gQ29va2llKGNvb2tpZXN0ciwgcmVxdWVzdF9kb21haW4sIHJlcXVlc3RfcGF0aCkge1xuICAgICAgICBpZiAoY29va2llc3RyIGluc3RhbmNlb2YgQ29va2llKSB7XG4gICAgICAgICAgICByZXR1cm4gY29va2llc3RyO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgQ29va2llKSB7XG4gICAgICAgICAgICB0aGlzLm5hbWUgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy52YWx1ZSA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLmV4cGlyYXRpb25fZGF0ZSA9IEluZmluaXR5O1xuICAgICAgICAgICAgdGhpcy5wYXRoID0gU3RyaW5nKHJlcXVlc3RfcGF0aCB8fCBcIi9cIik7XG4gICAgICAgICAgICB0aGlzLmV4cGxpY2l0X3BhdGggPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuZG9tYWluID0gcmVxdWVzdF9kb21haW4gfHwgbnVsbDtcbiAgICAgICAgICAgIHRoaXMuZXhwbGljaXRfZG9tYWluID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLnNlY3VyZSA9IGZhbHNlOyAvL2hvdyB0byBkZWZpbmUgZGVmYXVsdD9cbiAgICAgICAgICAgIHRoaXMubm9zY3JpcHQgPSBmYWxzZTsgLy9odHRwb25seVxuICAgICAgICAgICAgaWYgKGNvb2tpZXN0cikge1xuICAgICAgICAgICAgICAgIHRoaXMucGFyc2UoY29va2llc3RyLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgQ29va2llKGNvb2tpZXN0cik7XG4gICAgfVxuICAgIGV4cG9ydHMuQ29va2llID0gQ29va2llO1xuXG4gICAgQ29va2llLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgICAgICB2YXIgc3RyID0gW3RoaXMubmFtZSArIFwiPVwiICsgdGhpcy52YWx1ZV07XG4gICAgICAgIGlmICh0aGlzLmV4cGlyYXRpb25fZGF0ZSAhPT0gSW5maW5pdHkpIHtcbiAgICAgICAgICAgIHN0ci5wdXNoKFwiZXhwaXJlcz1cIiArIChuZXcgRGF0ZSh0aGlzLmV4cGlyYXRpb25fZGF0ZSkpLnRvR01UU3RyaW5nKCkpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmRvbWFpbikge1xuICAgICAgICAgICAgc3RyLnB1c2goXCJkb21haW49XCIgKyB0aGlzLmRvbWFpbik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucGF0aCkge1xuICAgICAgICAgICAgc3RyLnB1c2goXCJwYXRoPVwiICsgdGhpcy5wYXRoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5zZWN1cmUpIHtcbiAgICAgICAgICAgIHN0ci5wdXNoKFwic2VjdXJlXCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLm5vc2NyaXB0KSB7XG4gICAgICAgICAgICBzdHIucHVzaChcImh0dHBvbmx5XCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdHIuam9pbihcIjsgXCIpO1xuICAgIH07XG5cbiAgICBDb29raWUucHJvdG90eXBlLnRvVmFsdWVTdHJpbmcgPSBmdW5jdGlvbiB0b1ZhbHVlU3RyaW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5uYW1lICsgXCI9XCIgKyB0aGlzLnZhbHVlO1xuICAgIH07XG5cbiAgICB2YXIgY29va2llX3N0cl9zcGxpdHRlciA9IC9bOl0oPz1cXHMqW2EtekEtWjAtOV9cXC1dK1xccypbPV0pL2c7XG4gICAgQ29va2llLnByb3RvdHlwZS5wYXJzZSA9IGZ1bmN0aW9uIHBhcnNlKHN0ciwgcmVxdWVzdF9kb21haW4sIHJlcXVlc3RfcGF0aCkge1xuICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIENvb2tpZSkge1xuICAgICAgICAgICAgdmFyIHBhcnRzID0gc3RyLnNwbGl0KFwiO1wiKS5maWx0ZXIoZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAhIXZhbHVlO1xuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIHBhaXIgPSBwYXJ0c1swXS5tYXRjaCgvKFtePV0rKT0oW1xcc1xcU10qKS8pLFxuICAgICAgICAgICAgICAgIGtleSA9IHBhaXJbMV0sXG4gICAgICAgICAgICAgICAgdmFsdWUgPSBwYWlyWzJdLFxuICAgICAgICAgICAgICAgIGk7XG4gICAgICAgICAgICB0aGlzLm5hbWUgPSBrZXk7XG4gICAgICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG5cbiAgICAgICAgICAgIGZvciAoaSA9IDE7IGkgPCBwYXJ0cy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgIHBhaXIgPSBwYXJ0c1tpXS5tYXRjaCgvKFtePV0rKSg/Oj0oW1xcc1xcU10qKSk/Lyk7XG4gICAgICAgICAgICAgICAga2V5ID0gcGFpclsxXS50cmltKCkudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHBhaXJbMl07XG4gICAgICAgICAgICAgICAgc3dpdGNoIChrZXkpIHtcbiAgICAgICAgICAgICAgICBjYXNlIFwiaHR0cG9ubHlcIjpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ub3NjcmlwdCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJleHBpcmVzXCI6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXhwaXJhdGlvbl9kYXRlID0gdmFsdWUgP1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIE51bWJlcihEYXRlLnBhcnNlKHZhbHVlKSkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZmluaXR5O1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIFwicGF0aFwiOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBhdGggPSB2YWx1ZSA/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUudHJpbSgpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIlwiO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmV4cGxpY2l0X3BhdGggPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIFwiZG9tYWluXCI6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZG9tYWluID0gdmFsdWUgP1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLnRyaW0oKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJcIjtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5leHBsaWNpdF9kb21haW4gPSAhIXRoaXMuZG9tYWluO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIFwic2VjdXJlXCI6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2VjdXJlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIXRoaXMuZXhwbGljaXRfcGF0aCkge1xuICAgICAgICAgICAgICAgdGhpcy5wYXRoID0gcmVxdWVzdF9wYXRoIHx8IFwiL1wiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCF0aGlzLmV4cGxpY2l0X2RvbWFpbikge1xuICAgICAgICAgICAgICAgdGhpcy5kb21haW4gPSByZXF1ZXN0X2RvbWFpbjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBDb29raWUoKS5wYXJzZShzdHIsIHJlcXVlc3RfZG9tYWluLCByZXF1ZXN0X3BhdGgpO1xuICAgIH07XG5cbiAgICBDb29raWUucHJvdG90eXBlLm1hdGNoZXMgPSBmdW5jdGlvbiBtYXRjaGVzKGFjY2Vzc19pbmZvKSB7XG4gICAgICAgIGlmICh0aGlzLm5vc2NyaXB0ICYmIGFjY2Vzc19pbmZvLnNjcmlwdCB8fFxuICAgICAgICAgICAgICAgIHRoaXMuc2VjdXJlICYmICFhY2Nlc3NfaW5mby5zZWN1cmUgfHxcbiAgICAgICAgICAgICAgICAhdGhpcy5jb2xsaWRlc1dpdGgoYWNjZXNzX2luZm8pKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcblxuICAgIENvb2tpZS5wcm90b3R5cGUuY29sbGlkZXNXaXRoID0gZnVuY3Rpb24gY29sbGlkZXNXaXRoKGFjY2Vzc19pbmZvKSB7XG4gICAgICAgIGlmICgodGhpcy5wYXRoICYmICFhY2Nlc3NfaW5mby5wYXRoKSB8fCAodGhpcy5kb21haW4gJiYgIWFjY2Vzc19pbmZvLmRvbWFpbikpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5wYXRoICYmIGFjY2Vzc19pbmZvLnBhdGguaW5kZXhPZih0aGlzLnBhdGgpICE9PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLmV4cGxpY2l0X3BhdGgpIHtcbiAgICAgICAgICAgaWYgKHRoaXMucGF0aCAhPT0gYWNjZXNzX2luZm8ucGF0aCkge1xuICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGFjY2Vzc19kb21haW4gPSBhY2Nlc3NfaW5mby5kb21haW4gJiYgYWNjZXNzX2luZm8uZG9tYWluLnJlcGxhY2UoL15bXFwuXS8sJycpO1xuICAgICAgICB2YXIgY29va2llX2RvbWFpbiA9IHRoaXMuZG9tYWluICYmIHRoaXMuZG9tYWluLnJlcGxhY2UoL15bXFwuXS8sJycpO1xuICAgICAgICBpZiAoY29va2llX2RvbWFpbiA9PT0gYWNjZXNzX2RvbWFpbikge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvb2tpZV9kb21haW4pIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5leHBsaWNpdF9kb21haW4pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIHdlIGFscmVhZHkgY2hlY2tlZCBpZiB0aGUgZG9tYWlucyB3ZXJlIGV4YWN0bHkgdGhlIHNhbWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciB3aWxkY2FyZCA9IGFjY2Vzc19kb21haW4uaW5kZXhPZihjb29raWVfZG9tYWluKTtcbiAgICAgICAgICAgIGlmICh3aWxkY2FyZCA9PT0gLTEgfHwgd2lsZGNhcmQgIT09IGFjY2Vzc19kb21haW4ubGVuZ3RoIC0gY29va2llX2RvbWFpbi5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gQ29va2llSmFyKCkge1xuICAgICAgICB2YXIgY29va2llcywgY29va2llc19saXN0LCBjb2xsaWRhYmxlX2Nvb2tpZTtcbiAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBDb29raWVKYXIpIHtcbiAgICAgICAgICAgIGNvb2tpZXMgPSBPYmplY3QuY3JlYXRlKG51bGwpOyAvL25hbWU6IFtDb29raWVdXG5cbiAgICAgICAgICAgIHRoaXMuc2V0Q29va2llID0gZnVuY3Rpb24gc2V0Q29va2llKGNvb2tpZSwgcmVxdWVzdF9kb21haW4sIHJlcXVlc3RfcGF0aCkge1xuICAgICAgICAgICAgICAgIHZhciByZW1vdmUsIGk7XG4gICAgICAgICAgICAgICAgY29va2llID0gbmV3IENvb2tpZShjb29raWUsIHJlcXVlc3RfZG9tYWluLCByZXF1ZXN0X3BhdGgpO1xuICAgICAgICAgICAgICAgIC8vRGVsZXRlIHRoZSBjb29raWUgaWYgdGhlIHNldCBpcyBwYXN0IHRoZSBjdXJyZW50IHRpbWVcbiAgICAgICAgICAgICAgICByZW1vdmUgPSBjb29raWUuZXhwaXJhdGlvbl9kYXRlIDw9IERhdGUubm93KCk7XG4gICAgICAgICAgICAgICAgaWYgKGNvb2tpZXNbY29va2llLm5hbWVdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29va2llc19saXN0ID0gY29va2llc1tjb29raWUubmFtZV07XG4gICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBjb29raWVzX2xpc3QubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbGxpZGFibGVfY29va2llID0gY29va2llc19saXN0W2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbGxpZGFibGVfY29va2llLmNvbGxpZGVzV2l0aChjb29raWUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlbW92ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb29raWVzX2xpc3Quc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29va2llc19saXN0Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGNvb2tpZXNbY29va2llLm5hbWVdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29va2llc19saXN0W2ldID0gY29va2llO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjb29raWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlbW92ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvb2tpZXNfbGlzdC5wdXNoKGNvb2tpZSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjb29raWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChyZW1vdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb29raWVzW2Nvb2tpZS5uYW1lXSA9IFtjb29raWVdO1xuICAgICAgICAgICAgICAgIHJldHVybiBjb29raWVzW2Nvb2tpZS5uYW1lXTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICAvL3JldHVybnMgYSBjb29raWVcbiAgICAgICAgICAgIHRoaXMuZ2V0Q29va2llID0gZnVuY3Rpb24gZ2V0Q29va2llKGNvb2tpZV9uYW1lLCBhY2Nlc3NfaW5mbykge1xuICAgICAgICAgICAgICAgIHZhciBjb29raWUsIGk7XG4gICAgICAgICAgICAgICAgY29va2llc19saXN0ID0gY29va2llc1tjb29raWVfbmFtZV07XG4gICAgICAgICAgICAgICAgaWYgKCFjb29raWVzX2xpc3QpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY29va2llc19saXN0Lmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvb2tpZSA9IGNvb2tpZXNfbGlzdFtpXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvb2tpZS5leHBpcmF0aW9uX2RhdGUgPD0gRGF0ZS5ub3coKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvb2tpZXNfbGlzdC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgY29va2llc1tjb29raWUubmFtZV07XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoY29va2llLm1hdGNoZXMoYWNjZXNzX2luZm8pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29va2llO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vcmV0dXJucyBhIGxpc3Qgb2YgY29va2llc1xuICAgICAgICAgICAgdGhpcy5nZXRDb29raWVzID0gZnVuY3Rpb24gZ2V0Q29va2llcyhhY2Nlc3NfaW5mbykge1xuICAgICAgICAgICAgICAgIHZhciBtYXRjaGVzID0gW10sIGNvb2tpZV9uYW1lLCBjb29raWU7XG4gICAgICAgICAgICAgICAgZm9yIChjb29raWVfbmFtZSBpbiBjb29raWVzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvb2tpZSA9IHRoaXMuZ2V0Q29va2llKGNvb2tpZV9uYW1lLCBhY2Nlc3NfaW5mbyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjb29raWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoZXMucHVzaChjb29raWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG1hdGNoZXMudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoZXMuam9pbihcIjpcIik7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBtYXRjaGVzLnRvVmFsdWVTdHJpbmcgPSBmdW5jdGlvbiB0b1ZhbHVlU3RyaW5nKCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbWF0Y2hlcy5tYXAoZnVuY3Rpb24gKGMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjLnRvVmFsdWVTdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgfSkuam9pbignOycpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoZXM7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IENvb2tpZUphcigpO1xuICAgIH1cbiAgICBleHBvcnRzLkNvb2tpZUphciA9IENvb2tpZUphcjtcblxuICAgIC8vcmV0dXJucyBsaXN0IG9mIGNvb2tpZXMgdGhhdCB3ZXJlIHNldCBjb3JyZWN0bHkuIENvb2tpZXMgdGhhdCBhcmUgZXhwaXJlZCBhbmQgcmVtb3ZlZCBhcmUgbm90IHJldHVybmVkLlxuICAgIENvb2tpZUphci5wcm90b3R5cGUuc2V0Q29va2llcyA9IGZ1bmN0aW9uIHNldENvb2tpZXMoY29va2llcywgcmVxdWVzdF9kb21haW4sIHJlcXVlc3RfcGF0aCkge1xuICAgICAgICBjb29raWVzID0gQXJyYXkuaXNBcnJheShjb29raWVzKSA/XG4gICAgICAgICAgICAgICAgY29va2llcyA6XG4gICAgICAgICAgICAgICAgY29va2llcy5zcGxpdChjb29raWVfc3RyX3NwbGl0dGVyKTtcbiAgICAgICAgdmFyIHN1Y2Nlc3NmdWwgPSBbXSxcbiAgICAgICAgICAgIGksXG4gICAgICAgICAgICBjb29raWU7XG4gICAgICAgIGNvb2tpZXMgPSBjb29raWVzLm1hcChDb29raWUpO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY29va2llcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgY29va2llID0gY29va2llc1tpXTtcbiAgICAgICAgICAgIGlmICh0aGlzLnNldENvb2tpZShjb29raWUsIHJlcXVlc3RfZG9tYWluLCByZXF1ZXN0X3BhdGgpKSB7XG4gICAgICAgICAgICAgICAgc3VjY2Vzc2Z1bC5wdXNoKGNvb2tpZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHN1Y2Nlc3NmdWw7XG4gICAgfTtcbn0oKSk7XG4iLCIvKiFcbiAqIGpRdWVyeSBKYXZhU2NyaXB0IExpYnJhcnkgdjIuMS40XG4gKiBodHRwOi8vanF1ZXJ5LmNvbS9cbiAqXG4gKiBJbmNsdWRlcyBTaXp6bGUuanNcbiAqIGh0dHA6Ly9zaXp6bGVqcy5jb20vXG4gKlxuICogQ29weXJpZ2h0IDIwMDUsIDIwMTQgalF1ZXJ5IEZvdW5kYXRpb24sIEluYy4gYW5kIG90aGVyIGNvbnRyaWJ1dG9yc1xuICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlXG4gKiBodHRwOi8vanF1ZXJ5Lm9yZy9saWNlbnNlXG4gKlxuICogRGF0ZTogMjAxNS0wNC0yOFQxNjowMVpcbiAqL1xuXG4oZnVuY3Rpb24oIGdsb2JhbCwgZmFjdG9yeSApIHtcblxuXHRpZiAoIHR5cGVvZiBtb2R1bGUgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG1vZHVsZS5leHBvcnRzID09PSBcIm9iamVjdFwiICkge1xuXHRcdC8vIEZvciBDb21tb25KUyBhbmQgQ29tbW9uSlMtbGlrZSBlbnZpcm9ubWVudHMgd2hlcmUgYSBwcm9wZXIgYHdpbmRvd2Bcblx0XHQvLyBpcyBwcmVzZW50LCBleGVjdXRlIHRoZSBmYWN0b3J5IGFuZCBnZXQgalF1ZXJ5LlxuXHRcdC8vIEZvciBlbnZpcm9ubWVudHMgdGhhdCBkbyBub3QgaGF2ZSBhIGB3aW5kb3dgIHdpdGggYSBgZG9jdW1lbnRgXG5cdFx0Ly8gKHN1Y2ggYXMgTm9kZS5qcyksIGV4cG9zZSBhIGZhY3RvcnkgYXMgbW9kdWxlLmV4cG9ydHMuXG5cdFx0Ly8gVGhpcyBhY2NlbnR1YXRlcyB0aGUgbmVlZCBmb3IgdGhlIGNyZWF0aW9uIG9mIGEgcmVhbCBgd2luZG93YC5cblx0XHQvLyBlLmcuIHZhciBqUXVlcnkgPSByZXF1aXJlKFwianF1ZXJ5XCIpKHdpbmRvdyk7XG5cdFx0Ly8gU2VlIHRpY2tldCAjMTQ1NDkgZm9yIG1vcmUgaW5mby5cblx0XHRtb2R1bGUuZXhwb3J0cyA9IGdsb2JhbC5kb2N1bWVudCA/XG5cdFx0XHRmYWN0b3J5KCBnbG9iYWwsIHRydWUgKSA6XG5cdFx0XHRmdW5jdGlvbiggdyApIHtcblx0XHRcdFx0aWYgKCAhdy5kb2N1bWVudCApIHtcblx0XHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoIFwialF1ZXJ5IHJlcXVpcmVzIGEgd2luZG93IHdpdGggYSBkb2N1bWVudFwiICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIGZhY3RvcnkoIHcgKTtcblx0XHRcdH07XG5cdH0gZWxzZSB7XG5cdFx0ZmFjdG9yeSggZ2xvYmFsICk7XG5cdH1cblxuLy8gUGFzcyB0aGlzIGlmIHdpbmRvdyBpcyBub3QgZGVmaW5lZCB5ZXRcbn0odHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHRoaXMsIGZ1bmN0aW9uKCB3aW5kb3csIG5vR2xvYmFsICkge1xuXG4vLyBTdXBwb3J0OiBGaXJlZm94IDE4K1xuLy8gQ2FuJ3QgYmUgaW4gc3RyaWN0IG1vZGUsIHNldmVyYWwgbGlicyBpbmNsdWRpbmcgQVNQLk5FVCB0cmFjZVxuLy8gdGhlIHN0YWNrIHZpYSBhcmd1bWVudHMuY2FsbGVyLmNhbGxlZSBhbmQgRmlyZWZveCBkaWVzIGlmXG4vLyB5b3UgdHJ5IHRvIHRyYWNlIHRocm91Z2ggXCJ1c2Ugc3RyaWN0XCIgY2FsbCBjaGFpbnMuICgjMTMzMzUpXG4vL1xuXG52YXIgYXJyID0gW107XG5cbnZhciBzbGljZSA9IGFyci5zbGljZTtcblxudmFyIGNvbmNhdCA9IGFyci5jb25jYXQ7XG5cbnZhciBwdXNoID0gYXJyLnB1c2g7XG5cbnZhciBpbmRleE9mID0gYXJyLmluZGV4T2Y7XG5cbnZhciBjbGFzczJ0eXBlID0ge307XG5cbnZhciB0b1N0cmluZyA9IGNsYXNzMnR5cGUudG9TdHJpbmc7XG5cbnZhciBoYXNPd24gPSBjbGFzczJ0eXBlLmhhc093blByb3BlcnR5O1xuXG52YXIgc3VwcG9ydCA9IHt9O1xuXG5cblxudmFyXG5cdC8vIFVzZSB0aGUgY29ycmVjdCBkb2N1bWVudCBhY2NvcmRpbmdseSB3aXRoIHdpbmRvdyBhcmd1bWVudCAoc2FuZGJveClcblx0ZG9jdW1lbnQgPSB3aW5kb3cuZG9jdW1lbnQsXG5cblx0dmVyc2lvbiA9IFwiMi4xLjRcIixcblxuXHQvLyBEZWZpbmUgYSBsb2NhbCBjb3B5IG9mIGpRdWVyeVxuXHRqUXVlcnkgPSBmdW5jdGlvbiggc2VsZWN0b3IsIGNvbnRleHQgKSB7XG5cdFx0Ly8gVGhlIGpRdWVyeSBvYmplY3QgaXMgYWN0dWFsbHkganVzdCB0aGUgaW5pdCBjb25zdHJ1Y3RvciAnZW5oYW5jZWQnXG5cdFx0Ly8gTmVlZCBpbml0IGlmIGpRdWVyeSBpcyBjYWxsZWQgKGp1c3QgYWxsb3cgZXJyb3IgdG8gYmUgdGhyb3duIGlmIG5vdCBpbmNsdWRlZClcblx0XHRyZXR1cm4gbmV3IGpRdWVyeS5mbi5pbml0KCBzZWxlY3RvciwgY29udGV4dCApO1xuXHR9LFxuXG5cdC8vIFN1cHBvcnQ6IEFuZHJvaWQ8NC4xXG5cdC8vIE1ha2Ugc3VyZSB3ZSB0cmltIEJPTSBhbmQgTkJTUFxuXHRydHJpbSA9IC9eW1xcc1xcdUZFRkZcXHhBMF0rfFtcXHNcXHVGRUZGXFx4QTBdKyQvZyxcblxuXHQvLyBNYXRjaGVzIGRhc2hlZCBzdHJpbmcgZm9yIGNhbWVsaXppbmdcblx0cm1zUHJlZml4ID0gL14tbXMtLyxcblx0cmRhc2hBbHBoYSA9IC8tKFtcXGRhLXpdKS9naSxcblxuXHQvLyBVc2VkIGJ5IGpRdWVyeS5jYW1lbENhc2UgYXMgY2FsbGJhY2sgdG8gcmVwbGFjZSgpXG5cdGZjYW1lbENhc2UgPSBmdW5jdGlvbiggYWxsLCBsZXR0ZXIgKSB7XG5cdFx0cmV0dXJuIGxldHRlci50b1VwcGVyQ2FzZSgpO1xuXHR9O1xuXG5qUXVlcnkuZm4gPSBqUXVlcnkucHJvdG90eXBlID0ge1xuXHQvLyBUaGUgY3VycmVudCB2ZXJzaW9uIG9mIGpRdWVyeSBiZWluZyB1c2VkXG5cdGpxdWVyeTogdmVyc2lvbixcblxuXHRjb25zdHJ1Y3RvcjogalF1ZXJ5LFxuXG5cdC8vIFN0YXJ0IHdpdGggYW4gZW1wdHkgc2VsZWN0b3Jcblx0c2VsZWN0b3I6IFwiXCIsXG5cblx0Ly8gVGhlIGRlZmF1bHQgbGVuZ3RoIG9mIGEgalF1ZXJ5IG9iamVjdCBpcyAwXG5cdGxlbmd0aDogMCxcblxuXHR0b0FycmF5OiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gc2xpY2UuY2FsbCggdGhpcyApO1xuXHR9LFxuXG5cdC8vIEdldCB0aGUgTnRoIGVsZW1lbnQgaW4gdGhlIG1hdGNoZWQgZWxlbWVudCBzZXQgT1Jcblx0Ly8gR2V0IHRoZSB3aG9sZSBtYXRjaGVkIGVsZW1lbnQgc2V0IGFzIGEgY2xlYW4gYXJyYXlcblx0Z2V0OiBmdW5jdGlvbiggbnVtICkge1xuXHRcdHJldHVybiBudW0gIT0gbnVsbCA/XG5cblx0XHRcdC8vIFJldHVybiBqdXN0IHRoZSBvbmUgZWxlbWVudCBmcm9tIHRoZSBzZXRcblx0XHRcdCggbnVtIDwgMCA/IHRoaXNbIG51bSArIHRoaXMubGVuZ3RoIF0gOiB0aGlzWyBudW0gXSApIDpcblxuXHRcdFx0Ly8gUmV0dXJuIGFsbCB0aGUgZWxlbWVudHMgaW4gYSBjbGVhbiBhcnJheVxuXHRcdFx0c2xpY2UuY2FsbCggdGhpcyApO1xuXHR9LFxuXG5cdC8vIFRha2UgYW4gYXJyYXkgb2YgZWxlbWVudHMgYW5kIHB1c2ggaXQgb250byB0aGUgc3RhY2tcblx0Ly8gKHJldHVybmluZyB0aGUgbmV3IG1hdGNoZWQgZWxlbWVudCBzZXQpXG5cdHB1c2hTdGFjazogZnVuY3Rpb24oIGVsZW1zICkge1xuXG5cdFx0Ly8gQnVpbGQgYSBuZXcgalF1ZXJ5IG1hdGNoZWQgZWxlbWVudCBzZXRcblx0XHR2YXIgcmV0ID0galF1ZXJ5Lm1lcmdlKCB0aGlzLmNvbnN0cnVjdG9yKCksIGVsZW1zICk7XG5cblx0XHQvLyBBZGQgdGhlIG9sZCBvYmplY3Qgb250byB0aGUgc3RhY2sgKGFzIGEgcmVmZXJlbmNlKVxuXHRcdHJldC5wcmV2T2JqZWN0ID0gdGhpcztcblx0XHRyZXQuY29udGV4dCA9IHRoaXMuY29udGV4dDtcblxuXHRcdC8vIFJldHVybiB0aGUgbmV3bHktZm9ybWVkIGVsZW1lbnQgc2V0XG5cdFx0cmV0dXJuIHJldDtcblx0fSxcblxuXHQvLyBFeGVjdXRlIGEgY2FsbGJhY2sgZm9yIGV2ZXJ5IGVsZW1lbnQgaW4gdGhlIG1hdGNoZWQgc2V0LlxuXHQvLyAoWW91IGNhbiBzZWVkIHRoZSBhcmd1bWVudHMgd2l0aCBhbiBhcnJheSBvZiBhcmdzLCBidXQgdGhpcyBpc1xuXHQvLyBvbmx5IHVzZWQgaW50ZXJuYWxseS4pXG5cdGVhY2g6IGZ1bmN0aW9uKCBjYWxsYmFjaywgYXJncyApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmVhY2goIHRoaXMsIGNhbGxiYWNrLCBhcmdzICk7XG5cdH0sXG5cblx0bWFwOiBmdW5jdGlvbiggY2FsbGJhY2sgKSB7XG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCBqUXVlcnkubWFwKHRoaXMsIGZ1bmN0aW9uKCBlbGVtLCBpICkge1xuXHRcdFx0cmV0dXJuIGNhbGxiYWNrLmNhbGwoIGVsZW0sIGksIGVsZW0gKTtcblx0XHR9KSk7XG5cdH0sXG5cblx0c2xpY2U6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggc2xpY2UuYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApICk7XG5cdH0sXG5cblx0Zmlyc3Q6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLmVxKCAwICk7XG5cdH0sXG5cblx0bGFzdDogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuZXEoIC0xICk7XG5cdH0sXG5cblx0ZXE6IGZ1bmN0aW9uKCBpICkge1xuXHRcdHZhciBsZW4gPSB0aGlzLmxlbmd0aCxcblx0XHRcdGogPSAraSArICggaSA8IDAgPyBsZW4gOiAwICk7XG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCBqID49IDAgJiYgaiA8IGxlbiA/IFsgdGhpc1tqXSBdIDogW10gKTtcblx0fSxcblxuXHRlbmQ6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLnByZXZPYmplY3QgfHwgdGhpcy5jb25zdHJ1Y3RvcihudWxsKTtcblx0fSxcblxuXHQvLyBGb3IgaW50ZXJuYWwgdXNlIG9ubHkuXG5cdC8vIEJlaGF2ZXMgbGlrZSBhbiBBcnJheSdzIG1ldGhvZCwgbm90IGxpa2UgYSBqUXVlcnkgbWV0aG9kLlxuXHRwdXNoOiBwdXNoLFxuXHRzb3J0OiBhcnIuc29ydCxcblx0c3BsaWNlOiBhcnIuc3BsaWNlXG59O1xuXG5qUXVlcnkuZXh0ZW5kID0galF1ZXJ5LmZuLmV4dGVuZCA9IGZ1bmN0aW9uKCkge1xuXHR2YXIgb3B0aW9ucywgbmFtZSwgc3JjLCBjb3B5LCBjb3B5SXNBcnJheSwgY2xvbmUsXG5cdFx0dGFyZ2V0ID0gYXJndW1lbnRzWzBdIHx8IHt9LFxuXHRcdGkgPSAxLFxuXHRcdGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGgsXG5cdFx0ZGVlcCA9IGZhbHNlO1xuXG5cdC8vIEhhbmRsZSBhIGRlZXAgY29weSBzaXR1YXRpb25cblx0aWYgKCB0eXBlb2YgdGFyZ2V0ID09PSBcImJvb2xlYW5cIiApIHtcblx0XHRkZWVwID0gdGFyZ2V0O1xuXG5cdFx0Ly8gU2tpcCB0aGUgYm9vbGVhbiBhbmQgdGhlIHRhcmdldFxuXHRcdHRhcmdldCA9IGFyZ3VtZW50c1sgaSBdIHx8IHt9O1xuXHRcdGkrKztcblx0fVxuXG5cdC8vIEhhbmRsZSBjYXNlIHdoZW4gdGFyZ2V0IGlzIGEgc3RyaW5nIG9yIHNvbWV0aGluZyAocG9zc2libGUgaW4gZGVlcCBjb3B5KVxuXHRpZiAoIHR5cGVvZiB0YXJnZXQgIT09IFwib2JqZWN0XCIgJiYgIWpRdWVyeS5pc0Z1bmN0aW9uKHRhcmdldCkgKSB7XG5cdFx0dGFyZ2V0ID0ge307XG5cdH1cblxuXHQvLyBFeHRlbmQgalF1ZXJ5IGl0c2VsZiBpZiBvbmx5IG9uZSBhcmd1bWVudCBpcyBwYXNzZWRcblx0aWYgKCBpID09PSBsZW5ndGggKSB7XG5cdFx0dGFyZ2V0ID0gdGhpcztcblx0XHRpLS07XG5cdH1cblxuXHRmb3IgKCA7IGkgPCBsZW5ndGg7IGkrKyApIHtcblx0XHQvLyBPbmx5IGRlYWwgd2l0aCBub24tbnVsbC91bmRlZmluZWQgdmFsdWVzXG5cdFx0aWYgKCAob3B0aW9ucyA9IGFyZ3VtZW50c1sgaSBdKSAhPSBudWxsICkge1xuXHRcdFx0Ly8gRXh0ZW5kIHRoZSBiYXNlIG9iamVjdFxuXHRcdFx0Zm9yICggbmFtZSBpbiBvcHRpb25zICkge1xuXHRcdFx0XHRzcmMgPSB0YXJnZXRbIG5hbWUgXTtcblx0XHRcdFx0Y29weSA9IG9wdGlvbnNbIG5hbWUgXTtcblxuXHRcdFx0XHQvLyBQcmV2ZW50IG5ldmVyLWVuZGluZyBsb29wXG5cdFx0XHRcdGlmICggdGFyZ2V0ID09PSBjb3B5ICkge1xuXHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gUmVjdXJzZSBpZiB3ZSdyZSBtZXJnaW5nIHBsYWluIG9iamVjdHMgb3IgYXJyYXlzXG5cdFx0XHRcdGlmICggZGVlcCAmJiBjb3B5ICYmICggalF1ZXJ5LmlzUGxhaW5PYmplY3QoY29weSkgfHwgKGNvcHlJc0FycmF5ID0galF1ZXJ5LmlzQXJyYXkoY29weSkpICkgKSB7XG5cdFx0XHRcdFx0aWYgKCBjb3B5SXNBcnJheSApIHtcblx0XHRcdFx0XHRcdGNvcHlJc0FycmF5ID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRjbG9uZSA9IHNyYyAmJiBqUXVlcnkuaXNBcnJheShzcmMpID8gc3JjIDogW107XG5cblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0Y2xvbmUgPSBzcmMgJiYgalF1ZXJ5LmlzUGxhaW5PYmplY3Qoc3JjKSA/IHNyYyA6IHt9O1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIE5ldmVyIG1vdmUgb3JpZ2luYWwgb2JqZWN0cywgY2xvbmUgdGhlbVxuXHRcdFx0XHRcdHRhcmdldFsgbmFtZSBdID0galF1ZXJ5LmV4dGVuZCggZGVlcCwgY2xvbmUsIGNvcHkgKTtcblxuXHRcdFx0XHQvLyBEb24ndCBicmluZyBpbiB1bmRlZmluZWQgdmFsdWVzXG5cdFx0XHRcdH0gZWxzZSBpZiAoIGNvcHkgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHR0YXJnZXRbIG5hbWUgXSA9IGNvcHk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBSZXR1cm4gdGhlIG1vZGlmaWVkIG9iamVjdFxuXHRyZXR1cm4gdGFyZ2V0O1xufTtcblxualF1ZXJ5LmV4dGVuZCh7XG5cdC8vIFVuaXF1ZSBmb3IgZWFjaCBjb3B5IG9mIGpRdWVyeSBvbiB0aGUgcGFnZVxuXHRleHBhbmRvOiBcImpRdWVyeVwiICsgKCB2ZXJzaW9uICsgTWF0aC5yYW5kb20oKSApLnJlcGxhY2UoIC9cXEQvZywgXCJcIiApLFxuXG5cdC8vIEFzc3VtZSBqUXVlcnkgaXMgcmVhZHkgd2l0aG91dCB0aGUgcmVhZHkgbW9kdWxlXG5cdGlzUmVhZHk6IHRydWUsXG5cblx0ZXJyb3I6IGZ1bmN0aW9uKCBtc2cgKSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKCBtc2cgKTtcblx0fSxcblxuXHRub29wOiBmdW5jdGlvbigpIHt9LFxuXG5cdGlzRnVuY3Rpb246IGZ1bmN0aW9uKCBvYmogKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS50eXBlKG9iaikgPT09IFwiZnVuY3Rpb25cIjtcblx0fSxcblxuXHRpc0FycmF5OiBBcnJheS5pc0FycmF5LFxuXG5cdGlzV2luZG93OiBmdW5jdGlvbiggb2JqICkge1xuXHRcdHJldHVybiBvYmogIT0gbnVsbCAmJiBvYmogPT09IG9iai53aW5kb3c7XG5cdH0sXG5cblx0aXNOdW1lcmljOiBmdW5jdGlvbiggb2JqICkge1xuXHRcdC8vIHBhcnNlRmxvYXQgTmFOcyBudW1lcmljLWNhc3QgZmFsc2UgcG9zaXRpdmVzIChudWxsfHRydWV8ZmFsc2V8XCJcIilcblx0XHQvLyAuLi5idXQgbWlzaW50ZXJwcmV0cyBsZWFkaW5nLW51bWJlciBzdHJpbmdzLCBwYXJ0aWN1bGFybHkgaGV4IGxpdGVyYWxzIChcIjB4Li4uXCIpXG5cdFx0Ly8gc3VidHJhY3Rpb24gZm9yY2VzIGluZmluaXRpZXMgdG8gTmFOXG5cdFx0Ly8gYWRkaW5nIDEgY29ycmVjdHMgbG9zcyBvZiBwcmVjaXNpb24gZnJvbSBwYXJzZUZsb2F0ICgjMTUxMDApXG5cdFx0cmV0dXJuICFqUXVlcnkuaXNBcnJheSggb2JqICkgJiYgKG9iaiAtIHBhcnNlRmxvYXQoIG9iaiApICsgMSkgPj0gMDtcblx0fSxcblxuXHRpc1BsYWluT2JqZWN0OiBmdW5jdGlvbiggb2JqICkge1xuXHRcdC8vIE5vdCBwbGFpbiBvYmplY3RzOlxuXHRcdC8vIC0gQW55IG9iamVjdCBvciB2YWx1ZSB3aG9zZSBpbnRlcm5hbCBbW0NsYXNzXV0gcHJvcGVydHkgaXMgbm90IFwiW29iamVjdCBPYmplY3RdXCJcblx0XHQvLyAtIERPTSBub2Rlc1xuXHRcdC8vIC0gd2luZG93XG5cdFx0aWYgKCBqUXVlcnkudHlwZSggb2JqICkgIT09IFwib2JqZWN0XCIgfHwgb2JqLm5vZGVUeXBlIHx8IGpRdWVyeS5pc1dpbmRvdyggb2JqICkgKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0aWYgKCBvYmouY29uc3RydWN0b3IgJiZcblx0XHRcdFx0IWhhc093bi5jYWxsKCBvYmouY29uc3RydWN0b3IucHJvdG90eXBlLCBcImlzUHJvdG90eXBlT2ZcIiApICkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdC8vIElmIHRoZSBmdW5jdGlvbiBoYXNuJ3QgcmV0dXJuZWQgYWxyZWFkeSwgd2UncmUgY29uZmlkZW50IHRoYXRcblx0XHQvLyB8b2JqfCBpcyBhIHBsYWluIG9iamVjdCwgY3JlYXRlZCBieSB7fSBvciBjb25zdHJ1Y3RlZCB3aXRoIG5ldyBPYmplY3Rcblx0XHRyZXR1cm4gdHJ1ZTtcblx0fSxcblxuXHRpc0VtcHR5T2JqZWN0OiBmdW5jdGlvbiggb2JqICkge1xuXHRcdHZhciBuYW1lO1xuXHRcdGZvciAoIG5hbWUgaW4gb2JqICkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fSxcblxuXHR0eXBlOiBmdW5jdGlvbiggb2JqICkge1xuXHRcdGlmICggb2JqID09IG51bGwgKSB7XG5cdFx0XHRyZXR1cm4gb2JqICsgXCJcIjtcblx0XHR9XG5cdFx0Ly8gU3VwcG9ydDogQW5kcm9pZDw0LjAsIGlPUzw2IChmdW5jdGlvbmlzaCBSZWdFeHApXG5cdFx0cmV0dXJuIHR5cGVvZiBvYmogPT09IFwib2JqZWN0XCIgfHwgdHlwZW9mIG9iaiA9PT0gXCJmdW5jdGlvblwiID9cblx0XHRcdGNsYXNzMnR5cGVbIHRvU3RyaW5nLmNhbGwob2JqKSBdIHx8IFwib2JqZWN0XCIgOlxuXHRcdFx0dHlwZW9mIG9iajtcblx0fSxcblxuXHQvLyBFdmFsdWF0ZXMgYSBzY3JpcHQgaW4gYSBnbG9iYWwgY29udGV4dFxuXHRnbG9iYWxFdmFsOiBmdW5jdGlvbiggY29kZSApIHtcblx0XHR2YXIgc2NyaXB0LFxuXHRcdFx0aW5kaXJlY3QgPSBldmFsO1xuXG5cdFx0Y29kZSA9IGpRdWVyeS50cmltKCBjb2RlICk7XG5cblx0XHRpZiAoIGNvZGUgKSB7XG5cdFx0XHQvLyBJZiB0aGUgY29kZSBpbmNsdWRlcyBhIHZhbGlkLCBwcm9sb2d1ZSBwb3NpdGlvblxuXHRcdFx0Ly8gc3RyaWN0IG1vZGUgcHJhZ21hLCBleGVjdXRlIGNvZGUgYnkgaW5qZWN0aW5nIGFcblx0XHRcdC8vIHNjcmlwdCB0YWcgaW50byB0aGUgZG9jdW1lbnQuXG5cdFx0XHRpZiAoIGNvZGUuaW5kZXhPZihcInVzZSBzdHJpY3RcIikgPT09IDEgKSB7XG5cdFx0XHRcdHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzY3JpcHRcIik7XG5cdFx0XHRcdHNjcmlwdC50ZXh0ID0gY29kZTtcblx0XHRcdFx0ZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZCggc2NyaXB0ICkucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCggc2NyaXB0ICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gT3RoZXJ3aXNlLCBhdm9pZCB0aGUgRE9NIG5vZGUgY3JlYXRpb24sIGluc2VydGlvblxuXHRcdFx0Ly8gYW5kIHJlbW92YWwgYnkgdXNpbmcgYW4gaW5kaXJlY3QgZ2xvYmFsIGV2YWxcblx0XHRcdFx0aW5kaXJlY3QoIGNvZGUgKTtcblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cblx0Ly8gQ29udmVydCBkYXNoZWQgdG8gY2FtZWxDYXNlOyB1c2VkIGJ5IHRoZSBjc3MgYW5kIGRhdGEgbW9kdWxlc1xuXHQvLyBTdXBwb3J0OiBJRTktMTErXG5cdC8vIE1pY3Jvc29mdCBmb3Jnb3QgdG8gaHVtcCB0aGVpciB2ZW5kb3IgcHJlZml4ICgjOTU3Milcblx0Y2FtZWxDYXNlOiBmdW5jdGlvbiggc3RyaW5nICkge1xuXHRcdHJldHVybiBzdHJpbmcucmVwbGFjZSggcm1zUHJlZml4LCBcIm1zLVwiICkucmVwbGFjZSggcmRhc2hBbHBoYSwgZmNhbWVsQ2FzZSApO1xuXHR9LFxuXG5cdG5vZGVOYW1lOiBmdW5jdGlvbiggZWxlbSwgbmFtZSApIHtcblx0XHRyZXR1cm4gZWxlbS5ub2RlTmFtZSAmJiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IG5hbWUudG9Mb3dlckNhc2UoKTtcblx0fSxcblxuXHQvLyBhcmdzIGlzIGZvciBpbnRlcm5hbCB1c2FnZSBvbmx5XG5cdGVhY2g6IGZ1bmN0aW9uKCBvYmosIGNhbGxiYWNrLCBhcmdzICkge1xuXHRcdHZhciB2YWx1ZSxcblx0XHRcdGkgPSAwLFxuXHRcdFx0bGVuZ3RoID0gb2JqLmxlbmd0aCxcblx0XHRcdGlzQXJyYXkgPSBpc0FycmF5bGlrZSggb2JqICk7XG5cblx0XHRpZiAoIGFyZ3MgKSB7XG5cdFx0XHRpZiAoIGlzQXJyYXkgKSB7XG5cdFx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSsrICkge1xuXHRcdFx0XHRcdHZhbHVlID0gY2FsbGJhY2suYXBwbHkoIG9ialsgaSBdLCBhcmdzICk7XG5cblx0XHRcdFx0XHRpZiAoIHZhbHVlID09PSBmYWxzZSApIHtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Zm9yICggaSBpbiBvYmogKSB7XG5cdFx0XHRcdFx0dmFsdWUgPSBjYWxsYmFjay5hcHBseSggb2JqWyBpIF0sIGFyZ3MgKTtcblxuXHRcdFx0XHRcdGlmICggdmFsdWUgPT09IGZhbHNlICkge1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHQvLyBBIHNwZWNpYWwsIGZhc3QsIGNhc2UgZm9yIHRoZSBtb3N0IGNvbW1vbiB1c2Ugb2YgZWFjaFxuXHRcdH0gZWxzZSB7XG5cdFx0XHRpZiAoIGlzQXJyYXkgKSB7XG5cdFx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSsrICkge1xuXHRcdFx0XHRcdHZhbHVlID0gY2FsbGJhY2suY2FsbCggb2JqWyBpIF0sIGksIG9ialsgaSBdICk7XG5cblx0XHRcdFx0XHRpZiAoIHZhbHVlID09PSBmYWxzZSApIHtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Zm9yICggaSBpbiBvYmogKSB7XG5cdFx0XHRcdFx0dmFsdWUgPSBjYWxsYmFjay5jYWxsKCBvYmpbIGkgXSwgaSwgb2JqWyBpIF0gKTtcblxuXHRcdFx0XHRcdGlmICggdmFsdWUgPT09IGZhbHNlICkge1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG9iajtcblx0fSxcblxuXHQvLyBTdXBwb3J0OiBBbmRyb2lkPDQuMVxuXHR0cmltOiBmdW5jdGlvbiggdGV4dCApIHtcblx0XHRyZXR1cm4gdGV4dCA9PSBudWxsID9cblx0XHRcdFwiXCIgOlxuXHRcdFx0KCB0ZXh0ICsgXCJcIiApLnJlcGxhY2UoIHJ0cmltLCBcIlwiICk7XG5cdH0sXG5cblx0Ly8gcmVzdWx0cyBpcyBmb3IgaW50ZXJuYWwgdXNhZ2Ugb25seVxuXHRtYWtlQXJyYXk6IGZ1bmN0aW9uKCBhcnIsIHJlc3VsdHMgKSB7XG5cdFx0dmFyIHJldCA9IHJlc3VsdHMgfHwgW107XG5cblx0XHRpZiAoIGFyciAhPSBudWxsICkge1xuXHRcdFx0aWYgKCBpc0FycmF5bGlrZSggT2JqZWN0KGFycikgKSApIHtcblx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCByZXQsXG5cdFx0XHRcdFx0dHlwZW9mIGFyciA9PT0gXCJzdHJpbmdcIiA/XG5cdFx0XHRcdFx0WyBhcnIgXSA6IGFyclxuXHRcdFx0XHQpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cHVzaC5jYWxsKCByZXQsIGFyciApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiByZXQ7XG5cdH0sXG5cblx0aW5BcnJheTogZnVuY3Rpb24oIGVsZW0sIGFyciwgaSApIHtcblx0XHRyZXR1cm4gYXJyID09IG51bGwgPyAtMSA6IGluZGV4T2YuY2FsbCggYXJyLCBlbGVtLCBpICk7XG5cdH0sXG5cblx0bWVyZ2U6IGZ1bmN0aW9uKCBmaXJzdCwgc2Vjb25kICkge1xuXHRcdHZhciBsZW4gPSArc2Vjb25kLmxlbmd0aCxcblx0XHRcdGogPSAwLFxuXHRcdFx0aSA9IGZpcnN0Lmxlbmd0aDtcblxuXHRcdGZvciAoIDsgaiA8IGxlbjsgaisrICkge1xuXHRcdFx0Zmlyc3RbIGkrKyBdID0gc2Vjb25kWyBqIF07XG5cdFx0fVxuXG5cdFx0Zmlyc3QubGVuZ3RoID0gaTtcblxuXHRcdHJldHVybiBmaXJzdDtcblx0fSxcblxuXHRncmVwOiBmdW5jdGlvbiggZWxlbXMsIGNhbGxiYWNrLCBpbnZlcnQgKSB7XG5cdFx0dmFyIGNhbGxiYWNrSW52ZXJzZSxcblx0XHRcdG1hdGNoZXMgPSBbXSxcblx0XHRcdGkgPSAwLFxuXHRcdFx0bGVuZ3RoID0gZWxlbXMubGVuZ3RoLFxuXHRcdFx0Y2FsbGJhY2tFeHBlY3QgPSAhaW52ZXJ0O1xuXG5cdFx0Ly8gR28gdGhyb3VnaCB0aGUgYXJyYXksIG9ubHkgc2F2aW5nIHRoZSBpdGVtc1xuXHRcdC8vIHRoYXQgcGFzcyB0aGUgdmFsaWRhdG9yIGZ1bmN0aW9uXG5cdFx0Zm9yICggOyBpIDwgbGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRjYWxsYmFja0ludmVyc2UgPSAhY2FsbGJhY2soIGVsZW1zWyBpIF0sIGkgKTtcblx0XHRcdGlmICggY2FsbGJhY2tJbnZlcnNlICE9PSBjYWxsYmFja0V4cGVjdCApIHtcblx0XHRcdFx0bWF0Y2hlcy5wdXNoKCBlbGVtc1sgaSBdICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG1hdGNoZXM7XG5cdH0sXG5cblx0Ly8gYXJnIGlzIGZvciBpbnRlcm5hbCB1c2FnZSBvbmx5XG5cdG1hcDogZnVuY3Rpb24oIGVsZW1zLCBjYWxsYmFjaywgYXJnICkge1xuXHRcdHZhciB2YWx1ZSxcblx0XHRcdGkgPSAwLFxuXHRcdFx0bGVuZ3RoID0gZWxlbXMubGVuZ3RoLFxuXHRcdFx0aXNBcnJheSA9IGlzQXJyYXlsaWtlKCBlbGVtcyApLFxuXHRcdFx0cmV0ID0gW107XG5cblx0XHQvLyBHbyB0aHJvdWdoIHRoZSBhcnJheSwgdHJhbnNsYXRpbmcgZWFjaCBvZiB0aGUgaXRlbXMgdG8gdGhlaXIgbmV3IHZhbHVlc1xuXHRcdGlmICggaXNBcnJheSApIHtcblx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSsrICkge1xuXHRcdFx0XHR2YWx1ZSA9IGNhbGxiYWNrKCBlbGVtc1sgaSBdLCBpLCBhcmcgKTtcblxuXHRcdFx0XHRpZiAoIHZhbHVlICE9IG51bGwgKSB7XG5cdFx0XHRcdFx0cmV0LnB1c2goIHZhbHVlICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdC8vIEdvIHRocm91Z2ggZXZlcnkga2V5IG9uIHRoZSBvYmplY3QsXG5cdFx0fSBlbHNlIHtcblx0XHRcdGZvciAoIGkgaW4gZWxlbXMgKSB7XG5cdFx0XHRcdHZhbHVlID0gY2FsbGJhY2soIGVsZW1zWyBpIF0sIGksIGFyZyApO1xuXG5cdFx0XHRcdGlmICggdmFsdWUgIT0gbnVsbCApIHtcblx0XHRcdFx0XHRyZXQucHVzaCggdmFsdWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIEZsYXR0ZW4gYW55IG5lc3RlZCBhcnJheXNcblx0XHRyZXR1cm4gY29uY2F0LmFwcGx5KCBbXSwgcmV0ICk7XG5cdH0sXG5cblx0Ly8gQSBnbG9iYWwgR1VJRCBjb3VudGVyIGZvciBvYmplY3RzXG5cdGd1aWQ6IDEsXG5cblx0Ly8gQmluZCBhIGZ1bmN0aW9uIHRvIGEgY29udGV4dCwgb3B0aW9uYWxseSBwYXJ0aWFsbHkgYXBwbHlpbmcgYW55XG5cdC8vIGFyZ3VtZW50cy5cblx0cHJveHk6IGZ1bmN0aW9uKCBmbiwgY29udGV4dCApIHtcblx0XHR2YXIgdG1wLCBhcmdzLCBwcm94eTtcblxuXHRcdGlmICggdHlwZW9mIGNvbnRleHQgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHR0bXAgPSBmblsgY29udGV4dCBdO1xuXHRcdFx0Y29udGV4dCA9IGZuO1xuXHRcdFx0Zm4gPSB0bXA7XG5cdFx0fVxuXG5cdFx0Ly8gUXVpY2sgY2hlY2sgdG8gZGV0ZXJtaW5lIGlmIHRhcmdldCBpcyBjYWxsYWJsZSwgaW4gdGhlIHNwZWNcblx0XHQvLyB0aGlzIHRocm93cyBhIFR5cGVFcnJvciwgYnV0IHdlIHdpbGwganVzdCByZXR1cm4gdW5kZWZpbmVkLlxuXHRcdGlmICggIWpRdWVyeS5pc0Z1bmN0aW9uKCBmbiApICkge1xuXHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0XHR9XG5cblx0XHQvLyBTaW11bGF0ZWQgYmluZFxuXHRcdGFyZ3MgPSBzbGljZS5jYWxsKCBhcmd1bWVudHMsIDIgKTtcblx0XHRwcm94eSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIGZuLmFwcGx5KCBjb250ZXh0IHx8IHRoaXMsIGFyZ3MuY29uY2F0KCBzbGljZS5jYWxsKCBhcmd1bWVudHMgKSApICk7XG5cdFx0fTtcblxuXHRcdC8vIFNldCB0aGUgZ3VpZCBvZiB1bmlxdWUgaGFuZGxlciB0byB0aGUgc2FtZSBvZiBvcmlnaW5hbCBoYW5kbGVyLCBzbyBpdCBjYW4gYmUgcmVtb3ZlZFxuXHRcdHByb3h5Lmd1aWQgPSBmbi5ndWlkID0gZm4uZ3VpZCB8fCBqUXVlcnkuZ3VpZCsrO1xuXG5cdFx0cmV0dXJuIHByb3h5O1xuXHR9LFxuXG5cdG5vdzogRGF0ZS5ub3csXG5cblx0Ly8galF1ZXJ5LnN1cHBvcnQgaXMgbm90IHVzZWQgaW4gQ29yZSBidXQgb3RoZXIgcHJvamVjdHMgYXR0YWNoIHRoZWlyXG5cdC8vIHByb3BlcnRpZXMgdG8gaXQgc28gaXQgbmVlZHMgdG8gZXhpc3QuXG5cdHN1cHBvcnQ6IHN1cHBvcnRcbn0pO1xuXG4vLyBQb3B1bGF0ZSB0aGUgY2xhc3MydHlwZSBtYXBcbmpRdWVyeS5lYWNoKFwiQm9vbGVhbiBOdW1iZXIgU3RyaW5nIEZ1bmN0aW9uIEFycmF5IERhdGUgUmVnRXhwIE9iamVjdCBFcnJvclwiLnNwbGl0KFwiIFwiKSwgZnVuY3Rpb24oaSwgbmFtZSkge1xuXHRjbGFzczJ0eXBlWyBcIltvYmplY3QgXCIgKyBuYW1lICsgXCJdXCIgXSA9IG5hbWUudG9Mb3dlckNhc2UoKTtcbn0pO1xuXG5mdW5jdGlvbiBpc0FycmF5bGlrZSggb2JqICkge1xuXG5cdC8vIFN1cHBvcnQ6IGlPUyA4LjIgKG5vdCByZXByb2R1Y2libGUgaW4gc2ltdWxhdG9yKVxuXHQvLyBgaW5gIGNoZWNrIHVzZWQgdG8gcHJldmVudCBKSVQgZXJyb3IgKGdoLTIxNDUpXG5cdC8vIGhhc093biBpc24ndCB1c2VkIGhlcmUgZHVlIHRvIGZhbHNlIG5lZ2F0aXZlc1xuXHQvLyByZWdhcmRpbmcgTm9kZWxpc3QgbGVuZ3RoIGluIElFXG5cdHZhciBsZW5ndGggPSBcImxlbmd0aFwiIGluIG9iaiAmJiBvYmoubGVuZ3RoLFxuXHRcdHR5cGUgPSBqUXVlcnkudHlwZSggb2JqICk7XG5cblx0aWYgKCB0eXBlID09PSBcImZ1bmN0aW9uXCIgfHwgalF1ZXJ5LmlzV2luZG93KCBvYmogKSApIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHRpZiAoIG9iai5ub2RlVHlwZSA9PT0gMSAmJiBsZW5ndGggKSB7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblxuXHRyZXR1cm4gdHlwZSA9PT0gXCJhcnJheVwiIHx8IGxlbmd0aCA9PT0gMCB8fFxuXHRcdHR5cGVvZiBsZW5ndGggPT09IFwibnVtYmVyXCIgJiYgbGVuZ3RoID4gMCAmJiAoIGxlbmd0aCAtIDEgKSBpbiBvYmo7XG59XG52YXIgU2l6emxlID1cbi8qIVxuICogU2l6emxlIENTUyBTZWxlY3RvciBFbmdpbmUgdjIuMi4wLXByZVxuICogaHR0cDovL3NpenpsZWpzLmNvbS9cbiAqXG4gKiBDb3B5cmlnaHQgMjAwOCwgMjAxNCBqUXVlcnkgRm91bmRhdGlvbiwgSW5jLiBhbmQgb3RoZXIgY29udHJpYnV0b3JzXG4gKiBSZWxlYXNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2VcbiAqIGh0dHA6Ly9qcXVlcnkub3JnL2xpY2Vuc2VcbiAqXG4gKiBEYXRlOiAyMDE0LTEyLTE2XG4gKi9cbihmdW5jdGlvbiggd2luZG93ICkge1xuXG52YXIgaSxcblx0c3VwcG9ydCxcblx0RXhwcixcblx0Z2V0VGV4dCxcblx0aXNYTUwsXG5cdHRva2VuaXplLFxuXHRjb21waWxlLFxuXHRzZWxlY3QsXG5cdG91dGVybW9zdENvbnRleHQsXG5cdHNvcnRJbnB1dCxcblx0aGFzRHVwbGljYXRlLFxuXG5cdC8vIExvY2FsIGRvY3VtZW50IHZhcnNcblx0c2V0RG9jdW1lbnQsXG5cdGRvY3VtZW50LFxuXHRkb2NFbGVtLFxuXHRkb2N1bWVudElzSFRNTCxcblx0cmJ1Z2d5UVNBLFxuXHRyYnVnZ3lNYXRjaGVzLFxuXHRtYXRjaGVzLFxuXHRjb250YWlucyxcblxuXHQvLyBJbnN0YW5jZS1zcGVjaWZpYyBkYXRhXG5cdGV4cGFuZG8gPSBcInNpenpsZVwiICsgMSAqIG5ldyBEYXRlKCksXG5cdHByZWZlcnJlZERvYyA9IHdpbmRvdy5kb2N1bWVudCxcblx0ZGlycnVucyA9IDAsXG5cdGRvbmUgPSAwLFxuXHRjbGFzc0NhY2hlID0gY3JlYXRlQ2FjaGUoKSxcblx0dG9rZW5DYWNoZSA9IGNyZWF0ZUNhY2hlKCksXG5cdGNvbXBpbGVyQ2FjaGUgPSBjcmVhdGVDYWNoZSgpLFxuXHRzb3J0T3JkZXIgPSBmdW5jdGlvbiggYSwgYiApIHtcblx0XHRpZiAoIGEgPT09IGIgKSB7XG5cdFx0XHRoYXNEdXBsaWNhdGUgPSB0cnVlO1xuXHRcdH1cblx0XHRyZXR1cm4gMDtcblx0fSxcblxuXHQvLyBHZW5lcmFsLXB1cnBvc2UgY29uc3RhbnRzXG5cdE1BWF9ORUdBVElWRSA9IDEgPDwgMzEsXG5cblx0Ly8gSW5zdGFuY2UgbWV0aG9kc1xuXHRoYXNPd24gPSAoe30pLmhhc093blByb3BlcnR5LFxuXHRhcnIgPSBbXSxcblx0cG9wID0gYXJyLnBvcCxcblx0cHVzaF9uYXRpdmUgPSBhcnIucHVzaCxcblx0cHVzaCA9IGFyci5wdXNoLFxuXHRzbGljZSA9IGFyci5zbGljZSxcblx0Ly8gVXNlIGEgc3RyaXBwZWQtZG93biBpbmRleE9mIGFzIGl0J3MgZmFzdGVyIHRoYW4gbmF0aXZlXG5cdC8vIGh0dHA6Ly9qc3BlcmYuY29tL3Rob3ItaW5kZXhvZi12cy1mb3IvNVxuXHRpbmRleE9mID0gZnVuY3Rpb24oIGxpc3QsIGVsZW0gKSB7XG5cdFx0dmFyIGkgPSAwLFxuXHRcdFx0bGVuID0gbGlzdC5sZW5ndGg7XG5cdFx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0XHRpZiAoIGxpc3RbaV0gPT09IGVsZW0gKSB7XG5cdFx0XHRcdHJldHVybiBpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gLTE7XG5cdH0sXG5cblx0Ym9vbGVhbnMgPSBcImNoZWNrZWR8c2VsZWN0ZWR8YXN5bmN8YXV0b2ZvY3VzfGF1dG9wbGF5fGNvbnRyb2xzfGRlZmVyfGRpc2FibGVkfGhpZGRlbnxpc21hcHxsb29wfG11bHRpcGxlfG9wZW58cmVhZG9ubHl8cmVxdWlyZWR8c2NvcGVkXCIsXG5cblx0Ly8gUmVndWxhciBleHByZXNzaW9uc1xuXG5cdC8vIFdoaXRlc3BhY2UgY2hhcmFjdGVycyBodHRwOi8vd3d3LnczLm9yZy9UUi9jc3MzLXNlbGVjdG9ycy8jd2hpdGVzcGFjZVxuXHR3aGl0ZXNwYWNlID0gXCJbXFxcXHgyMFxcXFx0XFxcXHJcXFxcblxcXFxmXVwiLFxuXHQvLyBodHRwOi8vd3d3LnczLm9yZy9UUi9jc3MzLXN5bnRheC8jY2hhcmFjdGVyc1xuXHRjaGFyYWN0ZXJFbmNvZGluZyA9IFwiKD86XFxcXFxcXFwufFtcXFxcdy1dfFteXFxcXHgwMC1cXFxceGEwXSkrXCIsXG5cblx0Ly8gTG9vc2VseSBtb2RlbGVkIG9uIENTUyBpZGVudGlmaWVyIGNoYXJhY3RlcnNcblx0Ly8gQW4gdW5xdW90ZWQgdmFsdWUgc2hvdWxkIGJlIGEgQ1NTIGlkZW50aWZpZXIgaHR0cDovL3d3dy53My5vcmcvVFIvY3NzMy1zZWxlY3RvcnMvI2F0dHJpYnV0ZS1zZWxlY3RvcnNcblx0Ly8gUHJvcGVyIHN5bnRheDogaHR0cDovL3d3dy53My5vcmcvVFIvQ1NTMjEvc3luZGF0YS5odG1sI3ZhbHVlLWRlZi1pZGVudGlmaWVyXG5cdGlkZW50aWZpZXIgPSBjaGFyYWN0ZXJFbmNvZGluZy5yZXBsYWNlKCBcIndcIiwgXCJ3I1wiICksXG5cblx0Ly8gQXR0cmlidXRlIHNlbGVjdG9yczogaHR0cDovL3d3dy53My5vcmcvVFIvc2VsZWN0b3JzLyNhdHRyaWJ1dGUtc2VsZWN0b3JzXG5cdGF0dHJpYnV0ZXMgPSBcIlxcXFxbXCIgKyB3aGl0ZXNwYWNlICsgXCIqKFwiICsgY2hhcmFjdGVyRW5jb2RpbmcgKyBcIikoPzpcIiArIHdoaXRlc3BhY2UgK1xuXHRcdC8vIE9wZXJhdG9yIChjYXB0dXJlIDIpXG5cdFx0XCIqKFsqXiR8IX5dPz0pXCIgKyB3aGl0ZXNwYWNlICtcblx0XHQvLyBcIkF0dHJpYnV0ZSB2YWx1ZXMgbXVzdCBiZSBDU1MgaWRlbnRpZmllcnMgW2NhcHR1cmUgNV0gb3Igc3RyaW5ncyBbY2FwdHVyZSAzIG9yIGNhcHR1cmUgNF1cIlxuXHRcdFwiKig/OicoKD86XFxcXFxcXFwufFteXFxcXFxcXFwnXSkqKSd8XFxcIigoPzpcXFxcXFxcXC58W15cXFxcXFxcXFxcXCJdKSopXFxcInwoXCIgKyBpZGVudGlmaWVyICsgXCIpKXwpXCIgKyB3aGl0ZXNwYWNlICtcblx0XHRcIipcXFxcXVwiLFxuXG5cdHBzZXVkb3MgPSBcIjooXCIgKyBjaGFyYWN0ZXJFbmNvZGluZyArIFwiKSg/OlxcXFwoKFwiICtcblx0XHQvLyBUbyByZWR1Y2UgdGhlIG51bWJlciBvZiBzZWxlY3RvcnMgbmVlZGluZyB0b2tlbml6ZSBpbiB0aGUgcHJlRmlsdGVyLCBwcmVmZXIgYXJndW1lbnRzOlxuXHRcdC8vIDEuIHF1b3RlZCAoY2FwdHVyZSAzOyBjYXB0dXJlIDQgb3IgY2FwdHVyZSA1KVxuXHRcdFwiKCcoKD86XFxcXFxcXFwufFteXFxcXFxcXFwnXSkqKSd8XFxcIigoPzpcXFxcXFxcXC58W15cXFxcXFxcXFxcXCJdKSopXFxcIil8XCIgK1xuXHRcdC8vIDIuIHNpbXBsZSAoY2FwdHVyZSA2KVxuXHRcdFwiKCg/OlxcXFxcXFxcLnxbXlxcXFxcXFxcKClbXFxcXF1dfFwiICsgYXR0cmlidXRlcyArIFwiKSopfFwiICtcblx0XHQvLyAzLiBhbnl0aGluZyBlbHNlIChjYXB0dXJlIDIpXG5cdFx0XCIuKlwiICtcblx0XHRcIilcXFxcKXwpXCIsXG5cblx0Ly8gTGVhZGluZyBhbmQgbm9uLWVzY2FwZWQgdHJhaWxpbmcgd2hpdGVzcGFjZSwgY2FwdHVyaW5nIHNvbWUgbm9uLXdoaXRlc3BhY2UgY2hhcmFjdGVycyBwcmVjZWRpbmcgdGhlIGxhdHRlclxuXHRyd2hpdGVzcGFjZSA9IG5ldyBSZWdFeHAoIHdoaXRlc3BhY2UgKyBcIitcIiwgXCJnXCIgKSxcblx0cnRyaW0gPSBuZXcgUmVnRXhwKCBcIl5cIiArIHdoaXRlc3BhY2UgKyBcIit8KCg/Ol58W15cXFxcXFxcXF0pKD86XFxcXFxcXFwuKSopXCIgKyB3aGl0ZXNwYWNlICsgXCIrJFwiLCBcImdcIiApLFxuXG5cdHJjb21tYSA9IG5ldyBSZWdFeHAoIFwiXlwiICsgd2hpdGVzcGFjZSArIFwiKixcIiArIHdoaXRlc3BhY2UgKyBcIipcIiApLFxuXHRyY29tYmluYXRvcnMgPSBuZXcgUmVnRXhwKCBcIl5cIiArIHdoaXRlc3BhY2UgKyBcIiooWz4rfl18XCIgKyB3aGl0ZXNwYWNlICsgXCIpXCIgKyB3aGl0ZXNwYWNlICsgXCIqXCIgKSxcblxuXHRyYXR0cmlidXRlUXVvdGVzID0gbmV3IFJlZ0V4cCggXCI9XCIgKyB3aGl0ZXNwYWNlICsgXCIqKFteXFxcXF0nXFxcIl0qPylcIiArIHdoaXRlc3BhY2UgKyBcIipcXFxcXVwiLCBcImdcIiApLFxuXG5cdHJwc2V1ZG8gPSBuZXcgUmVnRXhwKCBwc2V1ZG9zICksXG5cdHJpZGVudGlmaWVyID0gbmV3IFJlZ0V4cCggXCJeXCIgKyBpZGVudGlmaWVyICsgXCIkXCIgKSxcblxuXHRtYXRjaEV4cHIgPSB7XG5cdFx0XCJJRFwiOiBuZXcgUmVnRXhwKCBcIl4jKFwiICsgY2hhcmFjdGVyRW5jb2RpbmcgKyBcIilcIiApLFxuXHRcdFwiQ0xBU1NcIjogbmV3IFJlZ0V4cCggXCJeXFxcXC4oXCIgKyBjaGFyYWN0ZXJFbmNvZGluZyArIFwiKVwiICksXG5cdFx0XCJUQUdcIjogbmV3IFJlZ0V4cCggXCJeKFwiICsgY2hhcmFjdGVyRW5jb2RpbmcucmVwbGFjZSggXCJ3XCIsIFwidypcIiApICsgXCIpXCIgKSxcblx0XHRcIkFUVFJcIjogbmV3IFJlZ0V4cCggXCJeXCIgKyBhdHRyaWJ1dGVzICksXG5cdFx0XCJQU0VVRE9cIjogbmV3IFJlZ0V4cCggXCJeXCIgKyBwc2V1ZG9zICksXG5cdFx0XCJDSElMRFwiOiBuZXcgUmVnRXhwKCBcIl46KG9ubHl8Zmlyc3R8bGFzdHxudGh8bnRoLWxhc3QpLShjaGlsZHxvZi10eXBlKSg/OlxcXFwoXCIgKyB3aGl0ZXNwYWNlICtcblx0XHRcdFwiKihldmVufG9kZHwoKFsrLV18KShcXFxcZCopbnwpXCIgKyB3aGl0ZXNwYWNlICsgXCIqKD86KFsrLV18KVwiICsgd2hpdGVzcGFjZSArXG5cdFx0XHRcIiooXFxcXGQrKXwpKVwiICsgd2hpdGVzcGFjZSArIFwiKlxcXFwpfClcIiwgXCJpXCIgKSxcblx0XHRcImJvb2xcIjogbmV3IFJlZ0V4cCggXCJeKD86XCIgKyBib29sZWFucyArIFwiKSRcIiwgXCJpXCIgKSxcblx0XHQvLyBGb3IgdXNlIGluIGxpYnJhcmllcyBpbXBsZW1lbnRpbmcgLmlzKClcblx0XHQvLyBXZSB1c2UgdGhpcyBmb3IgUE9TIG1hdGNoaW5nIGluIGBzZWxlY3RgXG5cdFx0XCJuZWVkc0NvbnRleHRcIjogbmV3IFJlZ0V4cCggXCJeXCIgKyB3aGl0ZXNwYWNlICsgXCIqWz4rfl18OihldmVufG9kZHxlcXxndHxsdHxudGh8Zmlyc3R8bGFzdCkoPzpcXFxcKFwiICtcblx0XHRcdHdoaXRlc3BhY2UgKyBcIiooKD86LVxcXFxkKT9cXFxcZCopXCIgKyB3aGl0ZXNwYWNlICsgXCIqXFxcXCl8KSg/PVteLV18JClcIiwgXCJpXCIgKVxuXHR9LFxuXG5cdHJpbnB1dHMgPSAvXig/OmlucHV0fHNlbGVjdHx0ZXh0YXJlYXxidXR0b24pJC9pLFxuXHRyaGVhZGVyID0gL15oXFxkJC9pLFxuXG5cdHJuYXRpdmUgPSAvXltee10rXFx7XFxzKlxcW25hdGl2ZSBcXHcvLFxuXG5cdC8vIEVhc2lseS1wYXJzZWFibGUvcmV0cmlldmFibGUgSUQgb3IgVEFHIG9yIENMQVNTIHNlbGVjdG9yc1xuXHRycXVpY2tFeHByID0gL14oPzojKFtcXHctXSspfChcXHcrKXxcXC4oW1xcdy1dKykpJC8sXG5cblx0cnNpYmxpbmcgPSAvWyt+XS8sXG5cdHJlc2NhcGUgPSAvJ3xcXFxcL2csXG5cblx0Ly8gQ1NTIGVzY2FwZXMgaHR0cDovL3d3dy53My5vcmcvVFIvQ1NTMjEvc3luZGF0YS5odG1sI2VzY2FwZWQtY2hhcmFjdGVyc1xuXHRydW5lc2NhcGUgPSBuZXcgUmVnRXhwKCBcIlxcXFxcXFxcKFtcXFxcZGEtZl17MSw2fVwiICsgd2hpdGVzcGFjZSArIFwiP3woXCIgKyB3aGl0ZXNwYWNlICsgXCIpfC4pXCIsIFwiaWdcIiApLFxuXHRmdW5lc2NhcGUgPSBmdW5jdGlvbiggXywgZXNjYXBlZCwgZXNjYXBlZFdoaXRlc3BhY2UgKSB7XG5cdFx0dmFyIGhpZ2ggPSBcIjB4XCIgKyBlc2NhcGVkIC0gMHgxMDAwMDtcblx0XHQvLyBOYU4gbWVhbnMgbm9uLWNvZGVwb2ludFxuXHRcdC8vIFN1cHBvcnQ6IEZpcmVmb3g8MjRcblx0XHQvLyBXb3JrYXJvdW5kIGVycm9uZW91cyBudW1lcmljIGludGVycHJldGF0aW9uIG9mICtcIjB4XCJcblx0XHRyZXR1cm4gaGlnaCAhPT0gaGlnaCB8fCBlc2NhcGVkV2hpdGVzcGFjZSA/XG5cdFx0XHRlc2NhcGVkIDpcblx0XHRcdGhpZ2ggPCAwID9cblx0XHRcdFx0Ly8gQk1QIGNvZGVwb2ludFxuXHRcdFx0XHRTdHJpbmcuZnJvbUNoYXJDb2RlKCBoaWdoICsgMHgxMDAwMCApIDpcblx0XHRcdFx0Ly8gU3VwcGxlbWVudGFsIFBsYW5lIGNvZGVwb2ludCAoc3Vycm9nYXRlIHBhaXIpXG5cdFx0XHRcdFN0cmluZy5mcm9tQ2hhckNvZGUoIGhpZ2ggPj4gMTAgfCAweEQ4MDAsIGhpZ2ggJiAweDNGRiB8IDB4REMwMCApO1xuXHR9LFxuXG5cdC8vIFVzZWQgZm9yIGlmcmFtZXNcblx0Ly8gU2VlIHNldERvY3VtZW50KClcblx0Ly8gUmVtb3ZpbmcgdGhlIGZ1bmN0aW9uIHdyYXBwZXIgY2F1c2VzIGEgXCJQZXJtaXNzaW9uIERlbmllZFwiXG5cdC8vIGVycm9yIGluIElFXG5cdHVubG9hZEhhbmRsZXIgPSBmdW5jdGlvbigpIHtcblx0XHRzZXREb2N1bWVudCgpO1xuXHR9O1xuXG4vLyBPcHRpbWl6ZSBmb3IgcHVzaC5hcHBseSggXywgTm9kZUxpc3QgKVxudHJ5IHtcblx0cHVzaC5hcHBseShcblx0XHQoYXJyID0gc2xpY2UuY2FsbCggcHJlZmVycmVkRG9jLmNoaWxkTm9kZXMgKSksXG5cdFx0cHJlZmVycmVkRG9jLmNoaWxkTm9kZXNcblx0KTtcblx0Ly8gU3VwcG9ydDogQW5kcm9pZDw0LjBcblx0Ly8gRGV0ZWN0IHNpbGVudGx5IGZhaWxpbmcgcHVzaC5hcHBseVxuXHRhcnJbIHByZWZlcnJlZERvYy5jaGlsZE5vZGVzLmxlbmd0aCBdLm5vZGVUeXBlO1xufSBjYXRjaCAoIGUgKSB7XG5cdHB1c2ggPSB7IGFwcGx5OiBhcnIubGVuZ3RoID9cblxuXHRcdC8vIExldmVyYWdlIHNsaWNlIGlmIHBvc3NpYmxlXG5cdFx0ZnVuY3Rpb24oIHRhcmdldCwgZWxzICkge1xuXHRcdFx0cHVzaF9uYXRpdmUuYXBwbHkoIHRhcmdldCwgc2xpY2UuY2FsbChlbHMpICk7XG5cdFx0fSA6XG5cblx0XHQvLyBTdXBwb3J0OiBJRTw5XG5cdFx0Ly8gT3RoZXJ3aXNlIGFwcGVuZCBkaXJlY3RseVxuXHRcdGZ1bmN0aW9uKCB0YXJnZXQsIGVscyApIHtcblx0XHRcdHZhciBqID0gdGFyZ2V0Lmxlbmd0aCxcblx0XHRcdFx0aSA9IDA7XG5cdFx0XHQvLyBDYW4ndCB0cnVzdCBOb2RlTGlzdC5sZW5ndGhcblx0XHRcdHdoaWxlICggKHRhcmdldFtqKytdID0gZWxzW2krK10pICkge31cblx0XHRcdHRhcmdldC5sZW5ndGggPSBqIC0gMTtcblx0XHR9XG5cdH07XG59XG5cbmZ1bmN0aW9uIFNpenpsZSggc2VsZWN0b3IsIGNvbnRleHQsIHJlc3VsdHMsIHNlZWQgKSB7XG5cdHZhciBtYXRjaCwgZWxlbSwgbSwgbm9kZVR5cGUsXG5cdFx0Ly8gUVNBIHZhcnNcblx0XHRpLCBncm91cHMsIG9sZCwgbmlkLCBuZXdDb250ZXh0LCBuZXdTZWxlY3RvcjtcblxuXHRpZiAoICggY29udGV4dCA/IGNvbnRleHQub3duZXJEb2N1bWVudCB8fCBjb250ZXh0IDogcHJlZmVycmVkRG9jICkgIT09IGRvY3VtZW50ICkge1xuXHRcdHNldERvY3VtZW50KCBjb250ZXh0ICk7XG5cdH1cblxuXHRjb250ZXh0ID0gY29udGV4dCB8fCBkb2N1bWVudDtcblx0cmVzdWx0cyA9IHJlc3VsdHMgfHwgW107XG5cdG5vZGVUeXBlID0gY29udGV4dC5ub2RlVHlwZTtcblxuXHRpZiAoIHR5cGVvZiBzZWxlY3RvciAhPT0gXCJzdHJpbmdcIiB8fCAhc2VsZWN0b3IgfHxcblx0XHRub2RlVHlwZSAhPT0gMSAmJiBub2RlVHlwZSAhPT0gOSAmJiBub2RlVHlwZSAhPT0gMTEgKSB7XG5cblx0XHRyZXR1cm4gcmVzdWx0cztcblx0fVxuXG5cdGlmICggIXNlZWQgJiYgZG9jdW1lbnRJc0hUTUwgKSB7XG5cblx0XHQvLyBUcnkgdG8gc2hvcnRjdXQgZmluZCBvcGVyYXRpb25zIHdoZW4gcG9zc2libGUgKGUuZy4sIG5vdCB1bmRlciBEb2N1bWVudEZyYWdtZW50KVxuXHRcdGlmICggbm9kZVR5cGUgIT09IDExICYmIChtYXRjaCA9IHJxdWlja0V4cHIuZXhlYyggc2VsZWN0b3IgKSkgKSB7XG5cdFx0XHQvLyBTcGVlZC11cDogU2l6emxlKFwiI0lEXCIpXG5cdFx0XHRpZiAoIChtID0gbWF0Y2hbMV0pICkge1xuXHRcdFx0XHRpZiAoIG5vZGVUeXBlID09PSA5ICkge1xuXHRcdFx0XHRcdGVsZW0gPSBjb250ZXh0LmdldEVsZW1lbnRCeUlkKCBtICk7XG5cdFx0XHRcdFx0Ly8gQ2hlY2sgcGFyZW50Tm9kZSB0byBjYXRjaCB3aGVuIEJsYWNrYmVycnkgNC42IHJldHVybnNcblx0XHRcdFx0XHQvLyBub2RlcyB0aGF0IGFyZSBubyBsb25nZXIgaW4gdGhlIGRvY3VtZW50IChqUXVlcnkgIzY5NjMpXG5cdFx0XHRcdFx0aWYgKCBlbGVtICYmIGVsZW0ucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0XHRcdC8vIEhhbmRsZSB0aGUgY2FzZSB3aGVyZSBJRSwgT3BlcmEsIGFuZCBXZWJraXQgcmV0dXJuIGl0ZW1zXG5cdFx0XHRcdFx0XHQvLyBieSBuYW1lIGluc3RlYWQgb2YgSURcblx0XHRcdFx0XHRcdGlmICggZWxlbS5pZCA9PT0gbSApIHtcblx0XHRcdFx0XHRcdFx0cmVzdWx0cy5wdXNoKCBlbGVtICk7XG5cdFx0XHRcdFx0XHRcdHJldHVybiByZXN1bHRzO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Ly8gQ29udGV4dCBpcyBub3QgYSBkb2N1bWVudFxuXHRcdFx0XHRcdGlmICggY29udGV4dC5vd25lckRvY3VtZW50ICYmIChlbGVtID0gY29udGV4dC5vd25lckRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCBtICkpICYmXG5cdFx0XHRcdFx0XHRjb250YWlucyggY29udGV4dCwgZWxlbSApICYmIGVsZW0uaWQgPT09IG0gKSB7XG5cdFx0XHRcdFx0XHRyZXN1bHRzLnB1c2goIGVsZW0gKTtcblx0XHRcdFx0XHRcdHJldHVybiByZXN1bHRzO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHQvLyBTcGVlZC11cDogU2l6emxlKFwiVEFHXCIpXG5cdFx0XHR9IGVsc2UgaWYgKCBtYXRjaFsyXSApIHtcblx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cywgY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSggc2VsZWN0b3IgKSApO1xuXHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblxuXHRcdFx0Ly8gU3BlZWQtdXA6IFNpenpsZShcIi5DTEFTU1wiKVxuXHRcdFx0fSBlbHNlIGlmICggKG0gPSBtYXRjaFszXSkgJiYgc3VwcG9ydC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lICkge1xuXHRcdFx0XHRwdXNoLmFwcGx5KCByZXN1bHRzLCBjb250ZXh0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoIG0gKSApO1xuXHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBRU0EgcGF0aFxuXHRcdGlmICggc3VwcG9ydC5xc2EgJiYgKCFyYnVnZ3lRU0EgfHwgIXJidWdneVFTQS50ZXN0KCBzZWxlY3RvciApKSApIHtcblx0XHRcdG5pZCA9IG9sZCA9IGV4cGFuZG87XG5cdFx0XHRuZXdDb250ZXh0ID0gY29udGV4dDtcblx0XHRcdG5ld1NlbGVjdG9yID0gbm9kZVR5cGUgIT09IDEgJiYgc2VsZWN0b3I7XG5cblx0XHRcdC8vIHFTQSB3b3JrcyBzdHJhbmdlbHkgb24gRWxlbWVudC1yb290ZWQgcXVlcmllc1xuXHRcdFx0Ly8gV2UgY2FuIHdvcmsgYXJvdW5kIHRoaXMgYnkgc3BlY2lmeWluZyBhbiBleHRyYSBJRCBvbiB0aGUgcm9vdFxuXHRcdFx0Ly8gYW5kIHdvcmtpbmcgdXAgZnJvbSB0aGVyZSAoVGhhbmtzIHRvIEFuZHJldyBEdXBvbnQgZm9yIHRoZSB0ZWNobmlxdWUpXG5cdFx0XHQvLyBJRSA4IGRvZXNuJ3Qgd29yayBvbiBvYmplY3QgZWxlbWVudHNcblx0XHRcdGlmICggbm9kZVR5cGUgPT09IDEgJiYgY29udGV4dC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpICE9PSBcIm9iamVjdFwiICkge1xuXHRcdFx0XHRncm91cHMgPSB0b2tlbml6ZSggc2VsZWN0b3IgKTtcblxuXHRcdFx0XHRpZiAoIChvbGQgPSBjb250ZXh0LmdldEF0dHJpYnV0ZShcImlkXCIpKSApIHtcblx0XHRcdFx0XHRuaWQgPSBvbGQucmVwbGFjZSggcmVzY2FwZSwgXCJcXFxcJCZcIiApO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGNvbnRleHQuc2V0QXR0cmlidXRlKCBcImlkXCIsIG5pZCApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdG5pZCA9IFwiW2lkPSdcIiArIG5pZCArIFwiJ10gXCI7XG5cblx0XHRcdFx0aSA9IGdyb3Vwcy5sZW5ndGg7XG5cdFx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRcdGdyb3Vwc1tpXSA9IG5pZCArIHRvU2VsZWN0b3IoIGdyb3Vwc1tpXSApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdG5ld0NvbnRleHQgPSByc2libGluZy50ZXN0KCBzZWxlY3RvciApICYmIHRlc3RDb250ZXh0KCBjb250ZXh0LnBhcmVudE5vZGUgKSB8fCBjb250ZXh0O1xuXHRcdFx0XHRuZXdTZWxlY3RvciA9IGdyb3Vwcy5qb2luKFwiLFwiKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBuZXdTZWxlY3RvciApIHtcblx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRwdXNoLmFwcGx5KCByZXN1bHRzLFxuXHRcdFx0XHRcdFx0bmV3Q29udGV4dC5xdWVyeVNlbGVjdG9yQWxsKCBuZXdTZWxlY3RvciApXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblx0XHRcdFx0fSBjYXRjaChxc2FFcnJvcikge1xuXHRcdFx0XHR9IGZpbmFsbHkge1xuXHRcdFx0XHRcdGlmICggIW9sZCApIHtcblx0XHRcdFx0XHRcdGNvbnRleHQucmVtb3ZlQXR0cmlidXRlKFwiaWRcIik7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gQWxsIG90aGVyc1xuXHRyZXR1cm4gc2VsZWN0KCBzZWxlY3Rvci5yZXBsYWNlKCBydHJpbSwgXCIkMVwiICksIGNvbnRleHQsIHJlc3VsdHMsIHNlZWQgKTtcbn1cblxuLyoqXG4gKiBDcmVhdGUga2V5LXZhbHVlIGNhY2hlcyBvZiBsaW1pdGVkIHNpemVcbiAqIEByZXR1cm5zIHtGdW5jdGlvbihzdHJpbmcsIE9iamVjdCl9IFJldHVybnMgdGhlIE9iamVjdCBkYXRhIGFmdGVyIHN0b3JpbmcgaXQgb24gaXRzZWxmIHdpdGhcbiAqXHRwcm9wZXJ0eSBuYW1lIHRoZSAoc3BhY2Utc3VmZml4ZWQpIHN0cmluZyBhbmQgKGlmIHRoZSBjYWNoZSBpcyBsYXJnZXIgdGhhbiBFeHByLmNhY2hlTGVuZ3RoKVxuICpcdGRlbGV0aW5nIHRoZSBvbGRlc3QgZW50cnlcbiAqL1xuZnVuY3Rpb24gY3JlYXRlQ2FjaGUoKSB7XG5cdHZhciBrZXlzID0gW107XG5cblx0ZnVuY3Rpb24gY2FjaGUoIGtleSwgdmFsdWUgKSB7XG5cdFx0Ly8gVXNlIChrZXkgKyBcIiBcIikgdG8gYXZvaWQgY29sbGlzaW9uIHdpdGggbmF0aXZlIHByb3RvdHlwZSBwcm9wZXJ0aWVzIChzZWUgSXNzdWUgIzE1Nylcblx0XHRpZiAoIGtleXMucHVzaCgga2V5ICsgXCIgXCIgKSA+IEV4cHIuY2FjaGVMZW5ndGggKSB7XG5cdFx0XHQvLyBPbmx5IGtlZXAgdGhlIG1vc3QgcmVjZW50IGVudHJpZXNcblx0XHRcdGRlbGV0ZSBjYWNoZVsga2V5cy5zaGlmdCgpIF07XG5cdFx0fVxuXHRcdHJldHVybiAoY2FjaGVbIGtleSArIFwiIFwiIF0gPSB2YWx1ZSk7XG5cdH1cblx0cmV0dXJuIGNhY2hlO1xufVxuXG4vKipcbiAqIE1hcmsgYSBmdW5jdGlvbiBmb3Igc3BlY2lhbCB1c2UgYnkgU2l6emxlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgZnVuY3Rpb24gdG8gbWFya1xuICovXG5mdW5jdGlvbiBtYXJrRnVuY3Rpb24oIGZuICkge1xuXHRmblsgZXhwYW5kbyBdID0gdHJ1ZTtcblx0cmV0dXJuIGZuO1xufVxuXG4vKipcbiAqIFN1cHBvcnQgdGVzdGluZyB1c2luZyBhbiBlbGVtZW50XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBQYXNzZWQgdGhlIGNyZWF0ZWQgZGl2IGFuZCBleHBlY3RzIGEgYm9vbGVhbiByZXN1bHRcbiAqL1xuZnVuY3Rpb24gYXNzZXJ0KCBmbiApIHtcblx0dmFyIGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG5cblx0dHJ5IHtcblx0XHRyZXR1cm4gISFmbiggZGl2ICk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH0gZmluYWxseSB7XG5cdFx0Ly8gUmVtb3ZlIGZyb20gaXRzIHBhcmVudCBieSBkZWZhdWx0XG5cdFx0aWYgKCBkaXYucGFyZW50Tm9kZSApIHtcblx0XHRcdGRpdi5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKCBkaXYgKTtcblx0XHR9XG5cdFx0Ly8gcmVsZWFzZSBtZW1vcnkgaW4gSUVcblx0XHRkaXYgPSBudWxsO1xuXHR9XG59XG5cbi8qKlxuICogQWRkcyB0aGUgc2FtZSBoYW5kbGVyIGZvciBhbGwgb2YgdGhlIHNwZWNpZmllZCBhdHRyc1xuICogQHBhcmFtIHtTdHJpbmd9IGF0dHJzIFBpcGUtc2VwYXJhdGVkIGxpc3Qgb2YgYXR0cmlidXRlc1xuICogQHBhcmFtIHtGdW5jdGlvbn0gaGFuZGxlciBUaGUgbWV0aG9kIHRoYXQgd2lsbCBiZSBhcHBsaWVkXG4gKi9cbmZ1bmN0aW9uIGFkZEhhbmRsZSggYXR0cnMsIGhhbmRsZXIgKSB7XG5cdHZhciBhcnIgPSBhdHRycy5zcGxpdChcInxcIiksXG5cdFx0aSA9IGF0dHJzLmxlbmd0aDtcblxuXHR3aGlsZSAoIGktLSApIHtcblx0XHRFeHByLmF0dHJIYW5kbGVbIGFycltpXSBdID0gaGFuZGxlcjtcblx0fVxufVxuXG4vKipcbiAqIENoZWNrcyBkb2N1bWVudCBvcmRlciBvZiB0d28gc2libGluZ3NcbiAqIEBwYXJhbSB7RWxlbWVudH0gYVxuICogQHBhcmFtIHtFbGVtZW50fSBiXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBSZXR1cm5zIGxlc3MgdGhhbiAwIGlmIGEgcHJlY2VkZXMgYiwgZ3JlYXRlciB0aGFuIDAgaWYgYSBmb2xsb3dzIGJcbiAqL1xuZnVuY3Rpb24gc2libGluZ0NoZWNrKCBhLCBiICkge1xuXHR2YXIgY3VyID0gYiAmJiBhLFxuXHRcdGRpZmYgPSBjdXIgJiYgYS5ub2RlVHlwZSA9PT0gMSAmJiBiLm5vZGVUeXBlID09PSAxICYmXG5cdFx0XHQoIH5iLnNvdXJjZUluZGV4IHx8IE1BWF9ORUdBVElWRSApIC1cblx0XHRcdCggfmEuc291cmNlSW5kZXggfHwgTUFYX05FR0FUSVZFICk7XG5cblx0Ly8gVXNlIElFIHNvdXJjZUluZGV4IGlmIGF2YWlsYWJsZSBvbiBib3RoIG5vZGVzXG5cdGlmICggZGlmZiApIHtcblx0XHRyZXR1cm4gZGlmZjtcblx0fVxuXG5cdC8vIENoZWNrIGlmIGIgZm9sbG93cyBhXG5cdGlmICggY3VyICkge1xuXHRcdHdoaWxlICggKGN1ciA9IGN1ci5uZXh0U2libGluZykgKSB7XG5cdFx0XHRpZiAoIGN1ciA9PT0gYiApIHtcblx0XHRcdFx0cmV0dXJuIC0xO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiBhID8gMSA6IC0xO1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBmdW5jdGlvbiB0byB1c2UgaW4gcHNldWRvcyBmb3IgaW5wdXQgdHlwZXNcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUlucHV0UHNldWRvKCB0eXBlICkge1xuXHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0dmFyIG5hbWUgPSBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG5cdFx0cmV0dXJuIG5hbWUgPT09IFwiaW5wdXRcIiAmJiBlbGVtLnR5cGUgPT09IHR5cGU7XG5cdH07XG59XG5cbi8qKlxuICogUmV0dXJucyBhIGZ1bmN0aW9uIHRvIHVzZSBpbiBwc2V1ZG9zIGZvciBidXR0b25zXG4gKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxuICovXG5mdW5jdGlvbiBjcmVhdGVCdXR0b25Qc2V1ZG8oIHR5cGUgKSB7XG5cdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHR2YXIgbmFtZSA9IGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblx0XHRyZXR1cm4gKG5hbWUgPT09IFwiaW5wdXRcIiB8fCBuYW1lID09PSBcImJ1dHRvblwiKSAmJiBlbGVtLnR5cGUgPT09IHR5cGU7XG5cdH07XG59XG5cbi8qKlxuICogUmV0dXJucyBhIGZ1bmN0aW9uIHRvIHVzZSBpbiBwc2V1ZG9zIGZvciBwb3NpdGlvbmFsc1xuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlUG9zaXRpb25hbFBzZXVkbyggZm4gKSB7XG5cdHJldHVybiBtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIGFyZ3VtZW50ICkge1xuXHRcdGFyZ3VtZW50ID0gK2FyZ3VtZW50O1xuXHRcdHJldHVybiBtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHNlZWQsIG1hdGNoZXMgKSB7XG5cdFx0XHR2YXIgaixcblx0XHRcdFx0bWF0Y2hJbmRleGVzID0gZm4oIFtdLCBzZWVkLmxlbmd0aCwgYXJndW1lbnQgKSxcblx0XHRcdFx0aSA9IG1hdGNoSW5kZXhlcy5sZW5ndGg7XG5cblx0XHRcdC8vIE1hdGNoIGVsZW1lbnRzIGZvdW5kIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXhlc1xuXHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdGlmICggc2VlZFsgKGogPSBtYXRjaEluZGV4ZXNbaV0pIF0gKSB7XG5cdFx0XHRcdFx0c2VlZFtqXSA9ICEobWF0Y2hlc1tqXSA9IHNlZWRbal0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0pO1xufVxuXG4vKipcbiAqIENoZWNrcyBhIG5vZGUgZm9yIHZhbGlkaXR5IGFzIGEgU2l6emxlIGNvbnRleHRcbiAqIEBwYXJhbSB7RWxlbWVudHxPYmplY3Q9fSBjb250ZXh0XG4gKiBAcmV0dXJucyB7RWxlbWVudHxPYmplY3R8Qm9vbGVhbn0gVGhlIGlucHV0IG5vZGUgaWYgYWNjZXB0YWJsZSwgb3RoZXJ3aXNlIGEgZmFsc3kgdmFsdWVcbiAqL1xuZnVuY3Rpb24gdGVzdENvbnRleHQoIGNvbnRleHQgKSB7XG5cdHJldHVybiBjb250ZXh0ICYmIHR5cGVvZiBjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lICE9PSBcInVuZGVmaW5lZFwiICYmIGNvbnRleHQ7XG59XG5cbi8vIEV4cG9zZSBzdXBwb3J0IHZhcnMgZm9yIGNvbnZlbmllbmNlXG5zdXBwb3J0ID0gU2l6emxlLnN1cHBvcnQgPSB7fTtcblxuLyoqXG4gKiBEZXRlY3RzIFhNTCBub2Rlc1xuICogQHBhcmFtIHtFbGVtZW50fE9iamVjdH0gZWxlbSBBbiBlbGVtZW50IG9yIGEgZG9jdW1lbnRcbiAqIEByZXR1cm5zIHtCb29sZWFufSBUcnVlIGlmZiBlbGVtIGlzIGEgbm9uLUhUTUwgWE1MIG5vZGVcbiAqL1xuaXNYTUwgPSBTaXp6bGUuaXNYTUwgPSBmdW5jdGlvbiggZWxlbSApIHtcblx0Ly8gZG9jdW1lbnRFbGVtZW50IGlzIHZlcmlmaWVkIGZvciBjYXNlcyB3aGVyZSBpdCBkb2Vzbid0IHlldCBleGlzdFxuXHQvLyAoc3VjaCBhcyBsb2FkaW5nIGlmcmFtZXMgaW4gSUUgLSAjNDgzMylcblx0dmFyIGRvY3VtZW50RWxlbWVudCA9IGVsZW0gJiYgKGVsZW0ub3duZXJEb2N1bWVudCB8fCBlbGVtKS5kb2N1bWVudEVsZW1lbnQ7XG5cdHJldHVybiBkb2N1bWVudEVsZW1lbnQgPyBkb2N1bWVudEVsZW1lbnQubm9kZU5hbWUgIT09IFwiSFRNTFwiIDogZmFsc2U7XG59O1xuXG4vKipcbiAqIFNldHMgZG9jdW1lbnQtcmVsYXRlZCB2YXJpYWJsZXMgb25jZSBiYXNlZCBvbiB0aGUgY3VycmVudCBkb2N1bWVudFxuICogQHBhcmFtIHtFbGVtZW50fE9iamVjdH0gW2RvY10gQW4gZWxlbWVudCBvciBkb2N1bWVudCBvYmplY3QgdG8gdXNlIHRvIHNldCB0aGUgZG9jdW1lbnRcbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGN1cnJlbnQgZG9jdW1lbnRcbiAqL1xuc2V0RG9jdW1lbnQgPSBTaXp6bGUuc2V0RG9jdW1lbnQgPSBmdW5jdGlvbiggbm9kZSApIHtcblx0dmFyIGhhc0NvbXBhcmUsIHBhcmVudCxcblx0XHRkb2MgPSBub2RlID8gbm9kZS5vd25lckRvY3VtZW50IHx8IG5vZGUgOiBwcmVmZXJyZWREb2M7XG5cblx0Ly8gSWYgbm8gZG9jdW1lbnQgYW5kIGRvY3VtZW50RWxlbWVudCBpcyBhdmFpbGFibGUsIHJldHVyblxuXHRpZiAoIGRvYyA9PT0gZG9jdW1lbnQgfHwgZG9jLm5vZGVUeXBlICE9PSA5IHx8ICFkb2MuZG9jdW1lbnRFbGVtZW50ICkge1xuXHRcdHJldHVybiBkb2N1bWVudDtcblx0fVxuXG5cdC8vIFNldCBvdXIgZG9jdW1lbnRcblx0ZG9jdW1lbnQgPSBkb2M7XG5cdGRvY0VsZW0gPSBkb2MuZG9jdW1lbnRFbGVtZW50O1xuXHRwYXJlbnQgPSBkb2MuZGVmYXVsdFZpZXc7XG5cblx0Ly8gU3VwcG9ydDogSUU+OFxuXHQvLyBJZiBpZnJhbWUgZG9jdW1lbnQgaXMgYXNzaWduZWQgdG8gXCJkb2N1bWVudFwiIHZhcmlhYmxlIGFuZCBpZiBpZnJhbWUgaGFzIGJlZW4gcmVsb2FkZWQsXG5cdC8vIElFIHdpbGwgdGhyb3cgXCJwZXJtaXNzaW9uIGRlbmllZFwiIGVycm9yIHdoZW4gYWNjZXNzaW5nIFwiZG9jdW1lbnRcIiB2YXJpYWJsZSwgc2VlIGpRdWVyeSAjMTM5MzZcblx0Ly8gSUU2LTggZG8gbm90IHN1cHBvcnQgdGhlIGRlZmF1bHRWaWV3IHByb3BlcnR5IHNvIHBhcmVudCB3aWxsIGJlIHVuZGVmaW5lZFxuXHRpZiAoIHBhcmVudCAmJiBwYXJlbnQgIT09IHBhcmVudC50b3AgKSB7XG5cdFx0Ly8gSUUxMSBkb2VzIG5vdCBoYXZlIGF0dGFjaEV2ZW50LCBzbyBhbGwgbXVzdCBzdWZmZXJcblx0XHRpZiAoIHBhcmVudC5hZGRFdmVudExpc3RlbmVyICkge1xuXHRcdFx0cGFyZW50LmFkZEV2ZW50TGlzdGVuZXIoIFwidW5sb2FkXCIsIHVubG9hZEhhbmRsZXIsIGZhbHNlICk7XG5cdFx0fSBlbHNlIGlmICggcGFyZW50LmF0dGFjaEV2ZW50ICkge1xuXHRcdFx0cGFyZW50LmF0dGFjaEV2ZW50KCBcIm9udW5sb2FkXCIsIHVubG9hZEhhbmRsZXIgKTtcblx0XHR9XG5cdH1cblxuXHQvKiBTdXBwb3J0IHRlc3RzXG5cdC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblx0ZG9jdW1lbnRJc0hUTUwgPSAhaXNYTUwoIGRvYyApO1xuXG5cdC8qIEF0dHJpYnV0ZXNcblx0LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG5cdC8vIFN1cHBvcnQ6IElFPDhcblx0Ly8gVmVyaWZ5IHRoYXQgZ2V0QXR0cmlidXRlIHJlYWxseSByZXR1cm5zIGF0dHJpYnV0ZXMgYW5kIG5vdCBwcm9wZXJ0aWVzXG5cdC8vIChleGNlcHRpbmcgSUU4IGJvb2xlYW5zKVxuXHRzdXBwb3J0LmF0dHJpYnV0ZXMgPSBhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcblx0XHRkaXYuY2xhc3NOYW1lID0gXCJpXCI7XG5cdFx0cmV0dXJuICFkaXYuZ2V0QXR0cmlidXRlKFwiY2xhc3NOYW1lXCIpO1xuXHR9KTtcblxuXHQvKiBnZXRFbGVtZW50KHMpQnkqXG5cdC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuXHQvLyBDaGVjayBpZiBnZXRFbGVtZW50c0J5VGFnTmFtZShcIipcIikgcmV0dXJucyBvbmx5IGVsZW1lbnRzXG5cdHN1cHBvcnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUgPSBhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcblx0XHRkaXYuYXBwZW5kQ2hpbGQoIGRvYy5jcmVhdGVDb21tZW50KFwiXCIpICk7XG5cdFx0cmV0dXJuICFkaXYuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCIqXCIpLmxlbmd0aDtcblx0fSk7XG5cblx0Ly8gU3VwcG9ydDogSUU8OVxuXHRzdXBwb3J0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgPSBybmF0aXZlLnRlc3QoIGRvYy5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lICk7XG5cblx0Ly8gU3VwcG9ydDogSUU8MTBcblx0Ly8gQ2hlY2sgaWYgZ2V0RWxlbWVudEJ5SWQgcmV0dXJucyBlbGVtZW50cyBieSBuYW1lXG5cdC8vIFRoZSBicm9rZW4gZ2V0RWxlbWVudEJ5SWQgbWV0aG9kcyBkb24ndCBwaWNrIHVwIHByb2dyYW1hdGljYWxseS1zZXQgbmFtZXMsXG5cdC8vIHNvIHVzZSBhIHJvdW5kYWJvdXQgZ2V0RWxlbWVudHNCeU5hbWUgdGVzdFxuXHRzdXBwb3J0LmdldEJ5SWQgPSBhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcblx0XHRkb2NFbGVtLmFwcGVuZENoaWxkKCBkaXYgKS5pZCA9IGV4cGFuZG87XG5cdFx0cmV0dXJuICFkb2MuZ2V0RWxlbWVudHNCeU5hbWUgfHwgIWRvYy5nZXRFbGVtZW50c0J5TmFtZSggZXhwYW5kbyApLmxlbmd0aDtcblx0fSk7XG5cblx0Ly8gSUQgZmluZCBhbmQgZmlsdGVyXG5cdGlmICggc3VwcG9ydC5nZXRCeUlkICkge1xuXHRcdEV4cHIuZmluZFtcIklEXCJdID0gZnVuY3Rpb24oIGlkLCBjb250ZXh0ICkge1xuXHRcdFx0aWYgKCB0eXBlb2YgY29udGV4dC5nZXRFbGVtZW50QnlJZCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBkb2N1bWVudElzSFRNTCApIHtcblx0XHRcdFx0dmFyIG0gPSBjb250ZXh0LmdldEVsZW1lbnRCeUlkKCBpZCApO1xuXHRcdFx0XHQvLyBDaGVjayBwYXJlbnROb2RlIHRvIGNhdGNoIHdoZW4gQmxhY2tiZXJyeSA0LjYgcmV0dXJuc1xuXHRcdFx0XHQvLyBub2RlcyB0aGF0IGFyZSBubyBsb25nZXIgaW4gdGhlIGRvY3VtZW50ICM2OTYzXG5cdFx0XHRcdHJldHVybiBtICYmIG0ucGFyZW50Tm9kZSA/IFsgbSBdIDogW107XG5cdFx0XHR9XG5cdFx0fTtcblx0XHRFeHByLmZpbHRlcltcIklEXCJdID0gZnVuY3Rpb24oIGlkICkge1xuXHRcdFx0dmFyIGF0dHJJZCA9IGlkLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICk7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHJldHVybiBlbGVtLmdldEF0dHJpYnV0ZShcImlkXCIpID09PSBhdHRySWQ7XG5cdFx0XHR9O1xuXHRcdH07XG5cdH0gZWxzZSB7XG5cdFx0Ly8gU3VwcG9ydDogSUU2Lzdcblx0XHQvLyBnZXRFbGVtZW50QnlJZCBpcyBub3QgcmVsaWFibGUgYXMgYSBmaW5kIHNob3J0Y3V0XG5cdFx0ZGVsZXRlIEV4cHIuZmluZFtcIklEXCJdO1xuXG5cdFx0RXhwci5maWx0ZXJbXCJJRFwiXSA9ICBmdW5jdGlvbiggaWQgKSB7XG5cdFx0XHR2YXIgYXR0cklkID0gaWQucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTtcblx0XHRcdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0dmFyIG5vZGUgPSB0eXBlb2YgZWxlbS5nZXRBdHRyaWJ1dGVOb2RlICE9PSBcInVuZGVmaW5lZFwiICYmIGVsZW0uZ2V0QXR0cmlidXRlTm9kZShcImlkXCIpO1xuXHRcdFx0XHRyZXR1cm4gbm9kZSAmJiBub2RlLnZhbHVlID09PSBhdHRySWQ7XG5cdFx0XHR9O1xuXHRcdH07XG5cdH1cblxuXHQvLyBUYWdcblx0RXhwci5maW5kW1wiVEFHXCJdID0gc3VwcG9ydC5nZXRFbGVtZW50c0J5VGFnTmFtZSA/XG5cdFx0ZnVuY3Rpb24oIHRhZywgY29udGV4dCApIHtcblx0XHRcdGlmICggdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUgIT09IFwidW5kZWZpbmVkXCIgKSB7XG5cdFx0XHRcdHJldHVybiBjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lKCB0YWcgKTtcblxuXHRcdFx0Ly8gRG9jdW1lbnRGcmFnbWVudCBub2RlcyBkb24ndCBoYXZlIGdFQlROXG5cdFx0XHR9IGVsc2UgaWYgKCBzdXBwb3J0LnFzYSApIHtcblx0XHRcdFx0cmV0dXJuIGNvbnRleHQucXVlcnlTZWxlY3RvckFsbCggdGFnICk7XG5cdFx0XHR9XG5cdFx0fSA6XG5cblx0XHRmdW5jdGlvbiggdGFnLCBjb250ZXh0ICkge1xuXHRcdFx0dmFyIGVsZW0sXG5cdFx0XHRcdHRtcCA9IFtdLFxuXHRcdFx0XHRpID0gMCxcblx0XHRcdFx0Ly8gQnkgaGFwcHkgY29pbmNpZGVuY2UsIGEgKGJyb2tlbikgZ0VCVE4gYXBwZWFycyBvbiBEb2N1bWVudEZyYWdtZW50IG5vZGVzIHRvb1xuXHRcdFx0XHRyZXN1bHRzID0gY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSggdGFnICk7XG5cblx0XHRcdC8vIEZpbHRlciBvdXQgcG9zc2libGUgY29tbWVudHNcblx0XHRcdGlmICggdGFnID09PSBcIipcIiApIHtcblx0XHRcdFx0d2hpbGUgKCAoZWxlbSA9IHJlc3VsdHNbaSsrXSkgKSB7XG5cdFx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICkge1xuXHRcdFx0XHRcdFx0dG1wLnB1c2goIGVsZW0gKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gdG1wO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0fTtcblxuXHQvLyBDbGFzc1xuXHRFeHByLmZpbmRbXCJDTEFTU1wiXSA9IHN1cHBvcnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSAmJiBmdW5jdGlvbiggY2xhc3NOYW1lLCBjb250ZXh0ICkge1xuXHRcdGlmICggZG9jdW1lbnRJc0hUTUwgKSB7XG5cdFx0XHRyZXR1cm4gY29udGV4dC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCBjbGFzc05hbWUgKTtcblx0XHR9XG5cdH07XG5cblx0LyogUVNBL21hdGNoZXNTZWxlY3RvclxuXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cblx0Ly8gUVNBIGFuZCBtYXRjaGVzU2VsZWN0b3Igc3VwcG9ydFxuXG5cdC8vIG1hdGNoZXNTZWxlY3Rvcig6YWN0aXZlKSByZXBvcnRzIGZhbHNlIHdoZW4gdHJ1ZSAoSUU5L09wZXJhIDExLjUpXG5cdHJidWdneU1hdGNoZXMgPSBbXTtcblxuXHQvLyBxU2EoOmZvY3VzKSByZXBvcnRzIGZhbHNlIHdoZW4gdHJ1ZSAoQ2hyb21lIDIxKVxuXHQvLyBXZSBhbGxvdyB0aGlzIGJlY2F1c2Ugb2YgYSBidWcgaW4gSUU4LzkgdGhhdCB0aHJvd3MgYW4gZXJyb3Jcblx0Ly8gd2hlbmV2ZXIgYGRvY3VtZW50LmFjdGl2ZUVsZW1lbnRgIGlzIGFjY2Vzc2VkIG9uIGFuIGlmcmFtZVxuXHQvLyBTbywgd2UgYWxsb3cgOmZvY3VzIHRvIHBhc3MgdGhyb3VnaCBRU0EgYWxsIHRoZSB0aW1lIHRvIGF2b2lkIHRoZSBJRSBlcnJvclxuXHQvLyBTZWUgaHR0cDovL2J1Z3MuanF1ZXJ5LmNvbS90aWNrZXQvMTMzNzhcblx0cmJ1Z2d5UVNBID0gW107XG5cblx0aWYgKCAoc3VwcG9ydC5xc2EgPSBybmF0aXZlLnRlc3QoIGRvYy5xdWVyeVNlbGVjdG9yQWxsICkpICkge1xuXHRcdC8vIEJ1aWxkIFFTQSByZWdleFxuXHRcdC8vIFJlZ2V4IHN0cmF0ZWd5IGFkb3B0ZWQgZnJvbSBEaWVnbyBQZXJpbmlcblx0XHRhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcblx0XHRcdC8vIFNlbGVjdCBpcyBzZXQgdG8gZW1wdHkgc3RyaW5nIG9uIHB1cnBvc2Vcblx0XHRcdC8vIFRoaXMgaXMgdG8gdGVzdCBJRSdzIHRyZWF0bWVudCBvZiBub3QgZXhwbGljaXRseVxuXHRcdFx0Ly8gc2V0dGluZyBhIGJvb2xlYW4gY29udGVudCBhdHRyaWJ1dGUsXG5cdFx0XHQvLyBzaW5jZSBpdHMgcHJlc2VuY2Ugc2hvdWxkIGJlIGVub3VnaFxuXHRcdFx0Ly8gaHR0cDovL2J1Z3MuanF1ZXJ5LmNvbS90aWNrZXQvMTIzNTlcblx0XHRcdGRvY0VsZW0uYXBwZW5kQ2hpbGQoIGRpdiApLmlubmVySFRNTCA9IFwiPGEgaWQ9J1wiICsgZXhwYW5kbyArIFwiJz48L2E+XCIgK1xuXHRcdFx0XHRcIjxzZWxlY3QgaWQ9J1wiICsgZXhwYW5kbyArIFwiLVxcZl0nIG1zYWxsb3djYXB0dXJlPScnPlwiICtcblx0XHRcdFx0XCI8b3B0aW9uIHNlbGVjdGVkPScnPjwvb3B0aW9uPjwvc2VsZWN0PlwiO1xuXG5cdFx0XHQvLyBTdXBwb3J0OiBJRTgsIE9wZXJhIDExLTEyLjE2XG5cdFx0XHQvLyBOb3RoaW5nIHNob3VsZCBiZSBzZWxlY3RlZCB3aGVuIGVtcHR5IHN0cmluZ3MgZm9sbG93IF49IG9yICQ9IG9yICo9XG5cdFx0XHQvLyBUaGUgdGVzdCBhdHRyaWJ1dGUgbXVzdCBiZSB1bmtub3duIGluIE9wZXJhIGJ1dCBcInNhZmVcIiBmb3IgV2luUlRcblx0XHRcdC8vIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9pZS9oaDQ2NTM4OC5hc3B4I2F0dHJpYnV0ZV9zZWN0aW9uXG5cdFx0XHRpZiAoIGRpdi5xdWVyeVNlbGVjdG9yQWxsKFwiW21zYWxsb3djYXB0dXJlXj0nJ11cIikubGVuZ3RoICkge1xuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaCggXCJbKl4kXT1cIiArIHdoaXRlc3BhY2UgKyBcIiooPzonJ3xcXFwiXFxcIilcIiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTdXBwb3J0OiBJRThcblx0XHRcdC8vIEJvb2xlYW4gYXR0cmlidXRlcyBhbmQgXCJ2YWx1ZVwiIGFyZSBub3QgdHJlYXRlZCBjb3JyZWN0bHlcblx0XHRcdGlmICggIWRpdi5xdWVyeVNlbGVjdG9yQWxsKFwiW3NlbGVjdGVkXVwiKS5sZW5ndGggKSB7XG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKCBcIlxcXFxbXCIgKyB3aGl0ZXNwYWNlICsgXCIqKD86dmFsdWV8XCIgKyBib29sZWFucyArIFwiKVwiICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFN1cHBvcnQ6IENocm9tZTwyOSwgQW5kcm9pZDw0LjIrLCBTYWZhcmk8Ny4wKywgaU9TPDcuMCssIFBoYW50b21KUzwxLjkuNytcblx0XHRcdGlmICggIWRpdi5xdWVyeVNlbGVjdG9yQWxsKCBcIltpZH49XCIgKyBleHBhbmRvICsgXCItXVwiICkubGVuZ3RoICkge1xuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaChcIn49XCIpO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBXZWJraXQvT3BlcmEgLSA6Y2hlY2tlZCBzaG91bGQgcmV0dXJuIHNlbGVjdGVkIG9wdGlvbiBlbGVtZW50c1xuXHRcdFx0Ly8gaHR0cDovL3d3dy53My5vcmcvVFIvMjAxMS9SRUMtY3NzMy1zZWxlY3RvcnMtMjAxMTA5MjkvI2NoZWNrZWRcblx0XHRcdC8vIElFOCB0aHJvd3MgZXJyb3IgaGVyZSBhbmQgd2lsbCBub3Qgc2VlIGxhdGVyIHRlc3RzXG5cdFx0XHRpZiAoICFkaXYucXVlcnlTZWxlY3RvckFsbChcIjpjaGVja2VkXCIpLmxlbmd0aCApIHtcblx0XHRcdFx0cmJ1Z2d5UVNBLnB1c2goXCI6Y2hlY2tlZFwiKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU3VwcG9ydDogU2FmYXJpIDgrLCBpT1MgOCtcblx0XHRcdC8vIGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0xMzY4NTFcblx0XHRcdC8vIEluLXBhZ2UgYHNlbGVjdG9yI2lkIHNpYmluZy1jb21iaW5hdG9yIHNlbGVjdG9yYCBmYWlsc1xuXHRcdFx0aWYgKCAhZGl2LnF1ZXJ5U2VsZWN0b3JBbGwoIFwiYSNcIiArIGV4cGFuZG8gKyBcIisqXCIgKS5sZW5ndGggKSB7XG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKFwiLiMuK1srfl1cIik7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHRhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcblx0XHRcdC8vIFN1cHBvcnQ6IFdpbmRvd3MgOCBOYXRpdmUgQXBwc1xuXHRcdFx0Ly8gVGhlIHR5cGUgYW5kIG5hbWUgYXR0cmlidXRlcyBhcmUgcmVzdHJpY3RlZCBkdXJpbmcgLmlubmVySFRNTCBhc3NpZ25tZW50XG5cdFx0XHR2YXIgaW5wdXQgPSBkb2MuY3JlYXRlRWxlbWVudChcImlucHV0XCIpO1xuXHRcdFx0aW5wdXQuc2V0QXR0cmlidXRlKCBcInR5cGVcIiwgXCJoaWRkZW5cIiApO1xuXHRcdFx0ZGl2LmFwcGVuZENoaWxkKCBpbnB1dCApLnNldEF0dHJpYnV0ZSggXCJuYW1lXCIsIFwiRFwiICk7XG5cblx0XHRcdC8vIFN1cHBvcnQ6IElFOFxuXHRcdFx0Ly8gRW5mb3JjZSBjYXNlLXNlbnNpdGl2aXR5IG9mIG5hbWUgYXR0cmlidXRlXG5cdFx0XHRpZiAoIGRpdi5xdWVyeVNlbGVjdG9yQWxsKFwiW25hbWU9ZF1cIikubGVuZ3RoICkge1xuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaCggXCJuYW1lXCIgKyB3aGl0ZXNwYWNlICsgXCIqWypeJHwhfl0/PVwiICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEZGIDMuNSAtIDplbmFibGVkLzpkaXNhYmxlZCBhbmQgaGlkZGVuIGVsZW1lbnRzIChoaWRkZW4gZWxlbWVudHMgYXJlIHN0aWxsIGVuYWJsZWQpXG5cdFx0XHQvLyBJRTggdGhyb3dzIGVycm9yIGhlcmUgYW5kIHdpbGwgbm90IHNlZSBsYXRlciB0ZXN0c1xuXHRcdFx0aWYgKCAhZGl2LnF1ZXJ5U2VsZWN0b3JBbGwoXCI6ZW5hYmxlZFwiKS5sZW5ndGggKSB7XG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKCBcIjplbmFibGVkXCIsIFwiOmRpc2FibGVkXCIgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gT3BlcmEgMTAtMTEgZG9lcyBub3QgdGhyb3cgb24gcG9zdC1jb21tYSBpbnZhbGlkIHBzZXVkb3Ncblx0XHRcdGRpdi5xdWVyeVNlbGVjdG9yQWxsKFwiKiw6eFwiKTtcblx0XHRcdHJidWdneVFTQS5wdXNoKFwiLC4qOlwiKTtcblx0XHR9KTtcblx0fVxuXG5cdGlmICggKHN1cHBvcnQubWF0Y2hlc1NlbGVjdG9yID0gcm5hdGl2ZS50ZXN0KCAobWF0Y2hlcyA9IGRvY0VsZW0ubWF0Y2hlcyB8fFxuXHRcdGRvY0VsZW0ud2Via2l0TWF0Y2hlc1NlbGVjdG9yIHx8XG5cdFx0ZG9jRWxlbS5tb3pNYXRjaGVzU2VsZWN0b3IgfHxcblx0XHRkb2NFbGVtLm9NYXRjaGVzU2VsZWN0b3IgfHxcblx0XHRkb2NFbGVtLm1zTWF0Y2hlc1NlbGVjdG9yKSApKSApIHtcblxuXHRcdGFzc2VydChmdW5jdGlvbiggZGl2ICkge1xuXHRcdFx0Ly8gQ2hlY2sgdG8gc2VlIGlmIGl0J3MgcG9zc2libGUgdG8gZG8gbWF0Y2hlc1NlbGVjdG9yXG5cdFx0XHQvLyBvbiBhIGRpc2Nvbm5lY3RlZCBub2RlIChJRSA5KVxuXHRcdFx0c3VwcG9ydC5kaXNjb25uZWN0ZWRNYXRjaCA9IG1hdGNoZXMuY2FsbCggZGl2LCBcImRpdlwiICk7XG5cblx0XHRcdC8vIFRoaXMgc2hvdWxkIGZhaWwgd2l0aCBhbiBleGNlcHRpb25cblx0XHRcdC8vIEdlY2tvIGRvZXMgbm90IGVycm9yLCByZXR1cm5zIGZhbHNlIGluc3RlYWRcblx0XHRcdG1hdGNoZXMuY2FsbCggZGl2LCBcIltzIT0nJ106eFwiICk7XG5cdFx0XHRyYnVnZ3lNYXRjaGVzLnB1c2goIFwiIT1cIiwgcHNldWRvcyApO1xuXHRcdH0pO1xuXHR9XG5cblx0cmJ1Z2d5UVNBID0gcmJ1Z2d5UVNBLmxlbmd0aCAmJiBuZXcgUmVnRXhwKCByYnVnZ3lRU0Euam9pbihcInxcIikgKTtcblx0cmJ1Z2d5TWF0Y2hlcyA9IHJidWdneU1hdGNoZXMubGVuZ3RoICYmIG5ldyBSZWdFeHAoIHJidWdneU1hdGNoZXMuam9pbihcInxcIikgKTtcblxuXHQvKiBDb250YWluc1xuXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cdGhhc0NvbXBhcmUgPSBybmF0aXZlLnRlc3QoIGRvY0VsZW0uY29tcGFyZURvY3VtZW50UG9zaXRpb24gKTtcblxuXHQvLyBFbGVtZW50IGNvbnRhaW5zIGFub3RoZXJcblx0Ly8gUHVycG9zZWZ1bGx5IGRvZXMgbm90IGltcGxlbWVudCBpbmNsdXNpdmUgZGVzY2VuZGVudFxuXHQvLyBBcyBpbiwgYW4gZWxlbWVudCBkb2VzIG5vdCBjb250YWluIGl0c2VsZlxuXHRjb250YWlucyA9IGhhc0NvbXBhcmUgfHwgcm5hdGl2ZS50ZXN0KCBkb2NFbGVtLmNvbnRhaW5zICkgP1xuXHRcdGZ1bmN0aW9uKCBhLCBiICkge1xuXHRcdFx0dmFyIGFkb3duID0gYS5ub2RlVHlwZSA9PT0gOSA/IGEuZG9jdW1lbnRFbGVtZW50IDogYSxcblx0XHRcdFx0YnVwID0gYiAmJiBiLnBhcmVudE5vZGU7XG5cdFx0XHRyZXR1cm4gYSA9PT0gYnVwIHx8ICEhKCBidXAgJiYgYnVwLm5vZGVUeXBlID09PSAxICYmIChcblx0XHRcdFx0YWRvd24uY29udGFpbnMgP1xuXHRcdFx0XHRcdGFkb3duLmNvbnRhaW5zKCBidXAgKSA6XG5cdFx0XHRcdFx0YS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiAmJiBhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKCBidXAgKSAmIDE2XG5cdFx0XHQpKTtcblx0XHR9IDpcblx0XHRmdW5jdGlvbiggYSwgYiApIHtcblx0XHRcdGlmICggYiApIHtcblx0XHRcdFx0d2hpbGUgKCAoYiA9IGIucGFyZW50Tm9kZSkgKSB7XG5cdFx0XHRcdFx0aWYgKCBiID09PSBhICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fTtcblxuXHQvKiBTb3J0aW5nXG5cdC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuXHQvLyBEb2N1bWVudCBvcmRlciBzb3J0aW5nXG5cdHNvcnRPcmRlciA9IGhhc0NvbXBhcmUgP1xuXHRmdW5jdGlvbiggYSwgYiApIHtcblxuXHRcdC8vIEZsYWcgZm9yIGR1cGxpY2F0ZSByZW1vdmFsXG5cdFx0aWYgKCBhID09PSBiICkge1xuXHRcdFx0aGFzRHVwbGljYXRlID0gdHJ1ZTtcblx0XHRcdHJldHVybiAwO1xuXHRcdH1cblxuXHRcdC8vIFNvcnQgb24gbWV0aG9kIGV4aXN0ZW5jZSBpZiBvbmx5IG9uZSBpbnB1dCBoYXMgY29tcGFyZURvY3VtZW50UG9zaXRpb25cblx0XHR2YXIgY29tcGFyZSA9ICFhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uIC0gIWIuY29tcGFyZURvY3VtZW50UG9zaXRpb247XG5cdFx0aWYgKCBjb21wYXJlICkge1xuXHRcdFx0cmV0dXJuIGNvbXBhcmU7XG5cdFx0fVxuXG5cdFx0Ly8gQ2FsY3VsYXRlIHBvc2l0aW9uIGlmIGJvdGggaW5wdXRzIGJlbG9uZyB0byB0aGUgc2FtZSBkb2N1bWVudFxuXHRcdGNvbXBhcmUgPSAoIGEub3duZXJEb2N1bWVudCB8fCBhICkgPT09ICggYi5vd25lckRvY3VtZW50IHx8IGIgKSA/XG5cdFx0XHRhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKCBiICkgOlxuXG5cdFx0XHQvLyBPdGhlcndpc2Ugd2Uga25vdyB0aGV5IGFyZSBkaXNjb25uZWN0ZWRcblx0XHRcdDE7XG5cblx0XHQvLyBEaXNjb25uZWN0ZWQgbm9kZXNcblx0XHRpZiAoIGNvbXBhcmUgJiAxIHx8XG5cdFx0XHQoIXN1cHBvcnQuc29ydERldGFjaGVkICYmIGIuY29tcGFyZURvY3VtZW50UG9zaXRpb24oIGEgKSA9PT0gY29tcGFyZSkgKSB7XG5cblx0XHRcdC8vIENob29zZSB0aGUgZmlyc3QgZWxlbWVudCB0aGF0IGlzIHJlbGF0ZWQgdG8gb3VyIHByZWZlcnJlZCBkb2N1bWVudFxuXHRcdFx0aWYgKCBhID09PSBkb2MgfHwgYS5vd25lckRvY3VtZW50ID09PSBwcmVmZXJyZWREb2MgJiYgY29udGFpbnMocHJlZmVycmVkRG9jLCBhKSApIHtcblx0XHRcdFx0cmV0dXJuIC0xO1xuXHRcdFx0fVxuXHRcdFx0aWYgKCBiID09PSBkb2MgfHwgYi5vd25lckRvY3VtZW50ID09PSBwcmVmZXJyZWREb2MgJiYgY29udGFpbnMocHJlZmVycmVkRG9jLCBiKSApIHtcblx0XHRcdFx0cmV0dXJuIDE7XG5cdFx0XHR9XG5cblx0XHRcdC8vIE1haW50YWluIG9yaWdpbmFsIG9yZGVyXG5cdFx0XHRyZXR1cm4gc29ydElucHV0ID9cblx0XHRcdFx0KCBpbmRleE9mKCBzb3J0SW5wdXQsIGEgKSAtIGluZGV4T2YoIHNvcnRJbnB1dCwgYiApICkgOlxuXHRcdFx0XHQwO1xuXHRcdH1cblxuXHRcdHJldHVybiBjb21wYXJlICYgNCA/IC0xIDogMTtcblx0fSA6XG5cdGZ1bmN0aW9uKCBhLCBiICkge1xuXHRcdC8vIEV4aXQgZWFybHkgaWYgdGhlIG5vZGVzIGFyZSBpZGVudGljYWxcblx0XHRpZiAoIGEgPT09IGIgKSB7XG5cdFx0XHRoYXNEdXBsaWNhdGUgPSB0cnVlO1xuXHRcdFx0cmV0dXJuIDA7XG5cdFx0fVxuXG5cdFx0dmFyIGN1cixcblx0XHRcdGkgPSAwLFxuXHRcdFx0YXVwID0gYS5wYXJlbnROb2RlLFxuXHRcdFx0YnVwID0gYi5wYXJlbnROb2RlLFxuXHRcdFx0YXAgPSBbIGEgXSxcblx0XHRcdGJwID0gWyBiIF07XG5cblx0XHQvLyBQYXJlbnRsZXNzIG5vZGVzIGFyZSBlaXRoZXIgZG9jdW1lbnRzIG9yIGRpc2Nvbm5lY3RlZFxuXHRcdGlmICggIWF1cCB8fCAhYnVwICkge1xuXHRcdFx0cmV0dXJuIGEgPT09IGRvYyA/IC0xIDpcblx0XHRcdFx0YiA9PT0gZG9jID8gMSA6XG5cdFx0XHRcdGF1cCA/IC0xIDpcblx0XHRcdFx0YnVwID8gMSA6XG5cdFx0XHRcdHNvcnRJbnB1dCA/XG5cdFx0XHRcdCggaW5kZXhPZiggc29ydElucHV0LCBhICkgLSBpbmRleE9mKCBzb3J0SW5wdXQsIGIgKSApIDpcblx0XHRcdFx0MDtcblxuXHRcdC8vIElmIHRoZSBub2RlcyBhcmUgc2libGluZ3MsIHdlIGNhbiBkbyBhIHF1aWNrIGNoZWNrXG5cdFx0fSBlbHNlIGlmICggYXVwID09PSBidXAgKSB7XG5cdFx0XHRyZXR1cm4gc2libGluZ0NoZWNrKCBhLCBiICk7XG5cdFx0fVxuXG5cdFx0Ly8gT3RoZXJ3aXNlIHdlIG5lZWQgZnVsbCBsaXN0cyBvZiB0aGVpciBhbmNlc3RvcnMgZm9yIGNvbXBhcmlzb25cblx0XHRjdXIgPSBhO1xuXHRcdHdoaWxlICggKGN1ciA9IGN1ci5wYXJlbnROb2RlKSApIHtcblx0XHRcdGFwLnVuc2hpZnQoIGN1ciApO1xuXHRcdH1cblx0XHRjdXIgPSBiO1xuXHRcdHdoaWxlICggKGN1ciA9IGN1ci5wYXJlbnROb2RlKSApIHtcblx0XHRcdGJwLnVuc2hpZnQoIGN1ciApO1xuXHRcdH1cblxuXHRcdC8vIFdhbGsgZG93biB0aGUgdHJlZSBsb29raW5nIGZvciBhIGRpc2NyZXBhbmN5XG5cdFx0d2hpbGUgKCBhcFtpXSA9PT0gYnBbaV0gKSB7XG5cdFx0XHRpKys7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGkgP1xuXHRcdFx0Ly8gRG8gYSBzaWJsaW5nIGNoZWNrIGlmIHRoZSBub2RlcyBoYXZlIGEgY29tbW9uIGFuY2VzdG9yXG5cdFx0XHRzaWJsaW5nQ2hlY2soIGFwW2ldLCBicFtpXSApIDpcblxuXHRcdFx0Ly8gT3RoZXJ3aXNlIG5vZGVzIGluIG91ciBkb2N1bWVudCBzb3J0IGZpcnN0XG5cdFx0XHRhcFtpXSA9PT0gcHJlZmVycmVkRG9jID8gLTEgOlxuXHRcdFx0YnBbaV0gPT09IHByZWZlcnJlZERvYyA/IDEgOlxuXHRcdFx0MDtcblx0fTtcblxuXHRyZXR1cm4gZG9jO1xufTtcblxuU2l6emxlLm1hdGNoZXMgPSBmdW5jdGlvbiggZXhwciwgZWxlbWVudHMgKSB7XG5cdHJldHVybiBTaXp6bGUoIGV4cHIsIG51bGwsIG51bGwsIGVsZW1lbnRzICk7XG59O1xuXG5TaXp6bGUubWF0Y2hlc1NlbGVjdG9yID0gZnVuY3Rpb24oIGVsZW0sIGV4cHIgKSB7XG5cdC8vIFNldCBkb2N1bWVudCB2YXJzIGlmIG5lZWRlZFxuXHRpZiAoICggZWxlbS5vd25lckRvY3VtZW50IHx8IGVsZW0gKSAhPT0gZG9jdW1lbnQgKSB7XG5cdFx0c2V0RG9jdW1lbnQoIGVsZW0gKTtcblx0fVxuXG5cdC8vIE1ha2Ugc3VyZSB0aGF0IGF0dHJpYnV0ZSBzZWxlY3RvcnMgYXJlIHF1b3RlZFxuXHRleHByID0gZXhwci5yZXBsYWNlKCByYXR0cmlidXRlUXVvdGVzLCBcIj0nJDEnXVwiICk7XG5cblx0aWYgKCBzdXBwb3J0Lm1hdGNoZXNTZWxlY3RvciAmJiBkb2N1bWVudElzSFRNTCAmJlxuXHRcdCggIXJidWdneU1hdGNoZXMgfHwgIXJidWdneU1hdGNoZXMudGVzdCggZXhwciApICkgJiZcblx0XHQoICFyYnVnZ3lRU0EgICAgIHx8ICFyYnVnZ3lRU0EudGVzdCggZXhwciApICkgKSB7XG5cblx0XHR0cnkge1xuXHRcdFx0dmFyIHJldCA9IG1hdGNoZXMuY2FsbCggZWxlbSwgZXhwciApO1xuXG5cdFx0XHQvLyBJRSA5J3MgbWF0Y2hlc1NlbGVjdG9yIHJldHVybnMgZmFsc2Ugb24gZGlzY29ubmVjdGVkIG5vZGVzXG5cdFx0XHRpZiAoIHJldCB8fCBzdXBwb3J0LmRpc2Nvbm5lY3RlZE1hdGNoIHx8XG5cdFx0XHRcdFx0Ly8gQXMgd2VsbCwgZGlzY29ubmVjdGVkIG5vZGVzIGFyZSBzYWlkIHRvIGJlIGluIGEgZG9jdW1lbnRcblx0XHRcdFx0XHQvLyBmcmFnbWVudCBpbiBJRSA5XG5cdFx0XHRcdFx0ZWxlbS5kb2N1bWVudCAmJiBlbGVtLmRvY3VtZW50Lm5vZGVUeXBlICE9PSAxMSApIHtcblx0XHRcdFx0cmV0dXJuIHJldDtcblx0XHRcdH1cblx0XHR9IGNhdGNoIChlKSB7fVxuXHR9XG5cblx0cmV0dXJuIFNpenpsZSggZXhwciwgZG9jdW1lbnQsIG51bGwsIFsgZWxlbSBdICkubGVuZ3RoID4gMDtcbn07XG5cblNpenpsZS5jb250YWlucyA9IGZ1bmN0aW9uKCBjb250ZXh0LCBlbGVtICkge1xuXHQvLyBTZXQgZG9jdW1lbnQgdmFycyBpZiBuZWVkZWRcblx0aWYgKCAoIGNvbnRleHQub3duZXJEb2N1bWVudCB8fCBjb250ZXh0ICkgIT09IGRvY3VtZW50ICkge1xuXHRcdHNldERvY3VtZW50KCBjb250ZXh0ICk7XG5cdH1cblx0cmV0dXJuIGNvbnRhaW5zKCBjb250ZXh0LCBlbGVtICk7XG59O1xuXG5TaXp6bGUuYXR0ciA9IGZ1bmN0aW9uKCBlbGVtLCBuYW1lICkge1xuXHQvLyBTZXQgZG9jdW1lbnQgdmFycyBpZiBuZWVkZWRcblx0aWYgKCAoIGVsZW0ub3duZXJEb2N1bWVudCB8fCBlbGVtICkgIT09IGRvY3VtZW50ICkge1xuXHRcdHNldERvY3VtZW50KCBlbGVtICk7XG5cdH1cblxuXHR2YXIgZm4gPSBFeHByLmF0dHJIYW5kbGVbIG5hbWUudG9Mb3dlckNhc2UoKSBdLFxuXHRcdC8vIERvbid0IGdldCBmb29sZWQgYnkgT2JqZWN0LnByb3RvdHlwZSBwcm9wZXJ0aWVzIChqUXVlcnkgIzEzODA3KVxuXHRcdHZhbCA9IGZuICYmIGhhc093bi5jYWxsKCBFeHByLmF0dHJIYW5kbGUsIG5hbWUudG9Mb3dlckNhc2UoKSApID9cblx0XHRcdGZuKCBlbGVtLCBuYW1lLCAhZG9jdW1lbnRJc0hUTUwgKSA6XG5cdFx0XHR1bmRlZmluZWQ7XG5cblx0cmV0dXJuIHZhbCAhPT0gdW5kZWZpbmVkID9cblx0XHR2YWwgOlxuXHRcdHN1cHBvcnQuYXR0cmlidXRlcyB8fCAhZG9jdW1lbnRJc0hUTUwgP1xuXHRcdFx0ZWxlbS5nZXRBdHRyaWJ1dGUoIG5hbWUgKSA6XG5cdFx0XHQodmFsID0gZWxlbS5nZXRBdHRyaWJ1dGVOb2RlKG5hbWUpKSAmJiB2YWwuc3BlY2lmaWVkID9cblx0XHRcdFx0dmFsLnZhbHVlIDpcblx0XHRcdFx0bnVsbDtcbn07XG5cblNpenpsZS5lcnJvciA9IGZ1bmN0aW9uKCBtc2cgKSB7XG5cdHRocm93IG5ldyBFcnJvciggXCJTeW50YXggZXJyb3IsIHVucmVjb2duaXplZCBleHByZXNzaW9uOiBcIiArIG1zZyApO1xufTtcblxuLyoqXG4gKiBEb2N1bWVudCBzb3J0aW5nIGFuZCByZW1vdmluZyBkdXBsaWNhdGVzXG4gKiBAcGFyYW0ge0FycmF5TGlrZX0gcmVzdWx0c1xuICovXG5TaXp6bGUudW5pcXVlU29ydCA9IGZ1bmN0aW9uKCByZXN1bHRzICkge1xuXHR2YXIgZWxlbSxcblx0XHRkdXBsaWNhdGVzID0gW10sXG5cdFx0aiA9IDAsXG5cdFx0aSA9IDA7XG5cblx0Ly8gVW5sZXNzIHdlICprbm93KiB3ZSBjYW4gZGV0ZWN0IGR1cGxpY2F0ZXMsIGFzc3VtZSB0aGVpciBwcmVzZW5jZVxuXHRoYXNEdXBsaWNhdGUgPSAhc3VwcG9ydC5kZXRlY3REdXBsaWNhdGVzO1xuXHRzb3J0SW5wdXQgPSAhc3VwcG9ydC5zb3J0U3RhYmxlICYmIHJlc3VsdHMuc2xpY2UoIDAgKTtcblx0cmVzdWx0cy5zb3J0KCBzb3J0T3JkZXIgKTtcblxuXHRpZiAoIGhhc0R1cGxpY2F0ZSApIHtcblx0XHR3aGlsZSAoIChlbGVtID0gcmVzdWx0c1tpKytdKSApIHtcblx0XHRcdGlmICggZWxlbSA9PT0gcmVzdWx0c1sgaSBdICkge1xuXHRcdFx0XHRqID0gZHVwbGljYXRlcy5wdXNoKCBpICk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHdoaWxlICggai0tICkge1xuXHRcdFx0cmVzdWx0cy5zcGxpY2UoIGR1cGxpY2F0ZXNbIGogXSwgMSApO1xuXHRcdH1cblx0fVxuXG5cdC8vIENsZWFyIGlucHV0IGFmdGVyIHNvcnRpbmcgdG8gcmVsZWFzZSBvYmplY3RzXG5cdC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vanF1ZXJ5L3NpenpsZS9wdWxsLzIyNVxuXHRzb3J0SW5wdXQgPSBudWxsO1xuXG5cdHJldHVybiByZXN1bHRzO1xufTtcblxuLyoqXG4gKiBVdGlsaXR5IGZ1bmN0aW9uIGZvciByZXRyaWV2aW5nIHRoZSB0ZXh0IHZhbHVlIG9mIGFuIGFycmF5IG9mIERPTSBub2Rlc1xuICogQHBhcmFtIHtBcnJheXxFbGVtZW50fSBlbGVtXG4gKi9cbmdldFRleHQgPSBTaXp6bGUuZ2V0VGV4dCA9IGZ1bmN0aW9uKCBlbGVtICkge1xuXHR2YXIgbm9kZSxcblx0XHRyZXQgPSBcIlwiLFxuXHRcdGkgPSAwLFxuXHRcdG5vZGVUeXBlID0gZWxlbS5ub2RlVHlwZTtcblxuXHRpZiAoICFub2RlVHlwZSApIHtcblx0XHQvLyBJZiBubyBub2RlVHlwZSwgdGhpcyBpcyBleHBlY3RlZCB0byBiZSBhbiBhcnJheVxuXHRcdHdoaWxlICggKG5vZGUgPSBlbGVtW2krK10pICkge1xuXHRcdFx0Ly8gRG8gbm90IHRyYXZlcnNlIGNvbW1lbnQgbm9kZXNcblx0XHRcdHJldCArPSBnZXRUZXh0KCBub2RlICk7XG5cdFx0fVxuXHR9IGVsc2UgaWYgKCBub2RlVHlwZSA9PT0gMSB8fCBub2RlVHlwZSA9PT0gOSB8fCBub2RlVHlwZSA9PT0gMTEgKSB7XG5cdFx0Ly8gVXNlIHRleHRDb250ZW50IGZvciBlbGVtZW50c1xuXHRcdC8vIGlubmVyVGV4dCB1c2FnZSByZW1vdmVkIGZvciBjb25zaXN0ZW5jeSBvZiBuZXcgbGluZXMgKGpRdWVyeSAjMTExNTMpXG5cdFx0aWYgKCB0eXBlb2YgZWxlbS50ZXh0Q29udGVudCA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHJldHVybiBlbGVtLnRleHRDb250ZW50O1xuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBUcmF2ZXJzZSBpdHMgY2hpbGRyZW5cblx0XHRcdGZvciAoIGVsZW0gPSBlbGVtLmZpcnN0Q2hpbGQ7IGVsZW07IGVsZW0gPSBlbGVtLm5leHRTaWJsaW5nICkge1xuXHRcdFx0XHRyZXQgKz0gZ2V0VGV4dCggZWxlbSApO1xuXHRcdFx0fVxuXHRcdH1cblx0fSBlbHNlIGlmICggbm9kZVR5cGUgPT09IDMgfHwgbm9kZVR5cGUgPT09IDQgKSB7XG5cdFx0cmV0dXJuIGVsZW0ubm9kZVZhbHVlO1xuXHR9XG5cdC8vIERvIG5vdCBpbmNsdWRlIGNvbW1lbnQgb3IgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBub2Rlc1xuXG5cdHJldHVybiByZXQ7XG59O1xuXG5FeHByID0gU2l6emxlLnNlbGVjdG9ycyA9IHtcblxuXHQvLyBDYW4gYmUgYWRqdXN0ZWQgYnkgdGhlIHVzZXJcblx0Y2FjaGVMZW5ndGg6IDUwLFxuXG5cdGNyZWF0ZVBzZXVkbzogbWFya0Z1bmN0aW9uLFxuXG5cdG1hdGNoOiBtYXRjaEV4cHIsXG5cblx0YXR0ckhhbmRsZToge30sXG5cblx0ZmluZDoge30sXG5cblx0cmVsYXRpdmU6IHtcblx0XHRcIj5cIjogeyBkaXI6IFwicGFyZW50Tm9kZVwiLCBmaXJzdDogdHJ1ZSB9LFxuXHRcdFwiIFwiOiB7IGRpcjogXCJwYXJlbnROb2RlXCIgfSxcblx0XHRcIitcIjogeyBkaXI6IFwicHJldmlvdXNTaWJsaW5nXCIsIGZpcnN0OiB0cnVlIH0sXG5cdFx0XCJ+XCI6IHsgZGlyOiBcInByZXZpb3VzU2libGluZ1wiIH1cblx0fSxcblxuXHRwcmVGaWx0ZXI6IHtcblx0XHRcIkFUVFJcIjogZnVuY3Rpb24oIG1hdGNoICkge1xuXHRcdFx0bWF0Y2hbMV0gPSBtYXRjaFsxXS5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApO1xuXG5cdFx0XHQvLyBNb3ZlIHRoZSBnaXZlbiB2YWx1ZSB0byBtYXRjaFszXSB3aGV0aGVyIHF1b3RlZCBvciB1bnF1b3RlZFxuXHRcdFx0bWF0Y2hbM10gPSAoIG1hdGNoWzNdIHx8IG1hdGNoWzRdIHx8IG1hdGNoWzVdIHx8IFwiXCIgKS5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApO1xuXG5cdFx0XHRpZiAoIG1hdGNoWzJdID09PSBcIn49XCIgKSB7XG5cdFx0XHRcdG1hdGNoWzNdID0gXCIgXCIgKyBtYXRjaFszXSArIFwiIFwiO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gbWF0Y2guc2xpY2UoIDAsIDQgKTtcblx0XHR9LFxuXG5cdFx0XCJDSElMRFwiOiBmdW5jdGlvbiggbWF0Y2ggKSB7XG5cdFx0XHQvKiBtYXRjaGVzIGZyb20gbWF0Y2hFeHByW1wiQ0hJTERcIl1cblx0XHRcdFx0MSB0eXBlIChvbmx5fG50aHwuLi4pXG5cdFx0XHRcdDIgd2hhdCAoY2hpbGR8b2YtdHlwZSlcblx0XHRcdFx0MyBhcmd1bWVudCAoZXZlbnxvZGR8XFxkKnxcXGQqbihbKy1dXFxkKyk/fC4uLilcblx0XHRcdFx0NCB4bi1jb21wb25lbnQgb2YgeG4reSBhcmd1bWVudCAoWystXT9cXGQqbnwpXG5cdFx0XHRcdDUgc2lnbiBvZiB4bi1jb21wb25lbnRcblx0XHRcdFx0NiB4IG9mIHhuLWNvbXBvbmVudFxuXHRcdFx0XHQ3IHNpZ24gb2YgeS1jb21wb25lbnRcblx0XHRcdFx0OCB5IG9mIHktY29tcG9uZW50XG5cdFx0XHQqL1xuXHRcdFx0bWF0Y2hbMV0gPSBtYXRjaFsxXS50b0xvd2VyQ2FzZSgpO1xuXG5cdFx0XHRpZiAoIG1hdGNoWzFdLnNsaWNlKCAwLCAzICkgPT09IFwibnRoXCIgKSB7XG5cdFx0XHRcdC8vIG50aC0qIHJlcXVpcmVzIGFyZ3VtZW50XG5cdFx0XHRcdGlmICggIW1hdGNoWzNdICkge1xuXHRcdFx0XHRcdFNpenpsZS5lcnJvciggbWF0Y2hbMF0gKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIG51bWVyaWMgeCBhbmQgeSBwYXJhbWV0ZXJzIGZvciBFeHByLmZpbHRlci5DSElMRFxuXHRcdFx0XHQvLyByZW1lbWJlciB0aGF0IGZhbHNlL3RydWUgY2FzdCByZXNwZWN0aXZlbHkgdG8gMC8xXG5cdFx0XHRcdG1hdGNoWzRdID0gKyggbWF0Y2hbNF0gPyBtYXRjaFs1XSArIChtYXRjaFs2XSB8fCAxKSA6IDIgKiAoIG1hdGNoWzNdID09PSBcImV2ZW5cIiB8fCBtYXRjaFszXSA9PT0gXCJvZGRcIiApICk7XG5cdFx0XHRcdG1hdGNoWzVdID0gKyggKCBtYXRjaFs3XSArIG1hdGNoWzhdICkgfHwgbWF0Y2hbM10gPT09IFwib2RkXCIgKTtcblxuXHRcdFx0Ly8gb3RoZXIgdHlwZXMgcHJvaGliaXQgYXJndW1lbnRzXG5cdFx0XHR9IGVsc2UgaWYgKCBtYXRjaFszXSApIHtcblx0XHRcdFx0U2l6emxlLmVycm9yKCBtYXRjaFswXSApO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gbWF0Y2g7XG5cdFx0fSxcblxuXHRcdFwiUFNFVURPXCI6IGZ1bmN0aW9uKCBtYXRjaCApIHtcblx0XHRcdHZhciBleGNlc3MsXG5cdFx0XHRcdHVucXVvdGVkID0gIW1hdGNoWzZdICYmIG1hdGNoWzJdO1xuXG5cdFx0XHRpZiAoIG1hdGNoRXhwcltcIkNISUxEXCJdLnRlc3QoIG1hdGNoWzBdICkgKSB7XG5cdFx0XHRcdHJldHVybiBudWxsO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBBY2NlcHQgcXVvdGVkIGFyZ3VtZW50cyBhcy1pc1xuXHRcdFx0aWYgKCBtYXRjaFszXSApIHtcblx0XHRcdFx0bWF0Y2hbMl0gPSBtYXRjaFs0XSB8fCBtYXRjaFs1XSB8fCBcIlwiO1xuXG5cdFx0XHQvLyBTdHJpcCBleGNlc3MgY2hhcmFjdGVycyBmcm9tIHVucXVvdGVkIGFyZ3VtZW50c1xuXHRcdFx0fSBlbHNlIGlmICggdW5xdW90ZWQgJiYgcnBzZXVkby50ZXN0KCB1bnF1b3RlZCApICYmXG5cdFx0XHRcdC8vIEdldCBleGNlc3MgZnJvbSB0b2tlbml6ZSAocmVjdXJzaXZlbHkpXG5cdFx0XHRcdChleGNlc3MgPSB0b2tlbml6ZSggdW5xdW90ZWQsIHRydWUgKSkgJiZcblx0XHRcdFx0Ly8gYWR2YW5jZSB0byB0aGUgbmV4dCBjbG9zaW5nIHBhcmVudGhlc2lzXG5cdFx0XHRcdChleGNlc3MgPSB1bnF1b3RlZC5pbmRleE9mKCBcIilcIiwgdW5xdW90ZWQubGVuZ3RoIC0gZXhjZXNzICkgLSB1bnF1b3RlZC5sZW5ndGgpICkge1xuXG5cdFx0XHRcdC8vIGV4Y2VzcyBpcyBhIG5lZ2F0aXZlIGluZGV4XG5cdFx0XHRcdG1hdGNoWzBdID0gbWF0Y2hbMF0uc2xpY2UoIDAsIGV4Y2VzcyApO1xuXHRcdFx0XHRtYXRjaFsyXSA9IHVucXVvdGVkLnNsaWNlKCAwLCBleGNlc3MgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gUmV0dXJuIG9ubHkgY2FwdHVyZXMgbmVlZGVkIGJ5IHRoZSBwc2V1ZG8gZmlsdGVyIG1ldGhvZCAodHlwZSBhbmQgYXJndW1lbnQpXG5cdFx0XHRyZXR1cm4gbWF0Y2guc2xpY2UoIDAsIDMgKTtcblx0XHR9XG5cdH0sXG5cblx0ZmlsdGVyOiB7XG5cblx0XHRcIlRBR1wiOiBmdW5jdGlvbiggbm9kZU5hbWVTZWxlY3RvciApIHtcblx0XHRcdHZhciBub2RlTmFtZSA9IG5vZGVOYW1lU2VsZWN0b3IucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0cmV0dXJuIG5vZGVOYW1lU2VsZWN0b3IgPT09IFwiKlwiID9cblx0XHRcdFx0ZnVuY3Rpb24oKSB7IHJldHVybiB0cnVlOyB9IDpcblx0XHRcdFx0ZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGVsZW0ubm9kZU5hbWUgJiYgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSBub2RlTmFtZTtcblx0XHRcdFx0fTtcblx0XHR9LFxuXG5cdFx0XCJDTEFTU1wiOiBmdW5jdGlvbiggY2xhc3NOYW1lICkge1xuXHRcdFx0dmFyIHBhdHRlcm4gPSBjbGFzc0NhY2hlWyBjbGFzc05hbWUgKyBcIiBcIiBdO1xuXG5cdFx0XHRyZXR1cm4gcGF0dGVybiB8fFxuXHRcdFx0XHQocGF0dGVybiA9IG5ldyBSZWdFeHAoIFwiKF58XCIgKyB3aGl0ZXNwYWNlICsgXCIpXCIgKyBjbGFzc05hbWUgKyBcIihcIiArIHdoaXRlc3BhY2UgKyBcInwkKVwiICkpICYmXG5cdFx0XHRcdGNsYXNzQ2FjaGUoIGNsYXNzTmFtZSwgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHBhdHRlcm4udGVzdCggdHlwZW9mIGVsZW0uY2xhc3NOYW1lID09PSBcInN0cmluZ1wiICYmIGVsZW0uY2xhc3NOYW1lIHx8IHR5cGVvZiBlbGVtLmdldEF0dHJpYnV0ZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBlbGVtLmdldEF0dHJpYnV0ZShcImNsYXNzXCIpIHx8IFwiXCIgKTtcblx0XHRcdFx0fSk7XG5cdFx0fSxcblxuXHRcdFwiQVRUUlwiOiBmdW5jdGlvbiggbmFtZSwgb3BlcmF0b3IsIGNoZWNrICkge1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHR2YXIgcmVzdWx0ID0gU2l6emxlLmF0dHIoIGVsZW0sIG5hbWUgKTtcblxuXHRcdFx0XHRpZiAoIHJlc3VsdCA9PSBudWxsICkge1xuXHRcdFx0XHRcdHJldHVybiBvcGVyYXRvciA9PT0gXCIhPVwiO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmICggIW9wZXJhdG9yICkge1xuXHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmVzdWx0ICs9IFwiXCI7XG5cblx0XHRcdFx0cmV0dXJuIG9wZXJhdG9yID09PSBcIj1cIiA/IHJlc3VsdCA9PT0gY2hlY2sgOlxuXHRcdFx0XHRcdG9wZXJhdG9yID09PSBcIiE9XCIgPyByZXN1bHQgIT09IGNoZWNrIDpcblx0XHRcdFx0XHRvcGVyYXRvciA9PT0gXCJePVwiID8gY2hlY2sgJiYgcmVzdWx0LmluZGV4T2YoIGNoZWNrICkgPT09IDAgOlxuXHRcdFx0XHRcdG9wZXJhdG9yID09PSBcIio9XCIgPyBjaGVjayAmJiByZXN1bHQuaW5kZXhPZiggY2hlY2sgKSA+IC0xIDpcblx0XHRcdFx0XHRvcGVyYXRvciA9PT0gXCIkPVwiID8gY2hlY2sgJiYgcmVzdWx0LnNsaWNlKCAtY2hlY2subGVuZ3RoICkgPT09IGNoZWNrIDpcblx0XHRcdFx0XHRvcGVyYXRvciA9PT0gXCJ+PVwiID8gKCBcIiBcIiArIHJlc3VsdC5yZXBsYWNlKCByd2hpdGVzcGFjZSwgXCIgXCIgKSArIFwiIFwiICkuaW5kZXhPZiggY2hlY2sgKSA+IC0xIDpcblx0XHRcdFx0XHRvcGVyYXRvciA9PT0gXCJ8PVwiID8gcmVzdWx0ID09PSBjaGVjayB8fCByZXN1bHQuc2xpY2UoIDAsIGNoZWNrLmxlbmd0aCArIDEgKSA9PT0gY2hlY2sgKyBcIi1cIiA6XG5cdFx0XHRcdFx0ZmFsc2U7XG5cdFx0XHR9O1xuXHRcdH0sXG5cblx0XHRcIkNISUxEXCI6IGZ1bmN0aW9uKCB0eXBlLCB3aGF0LCBhcmd1bWVudCwgZmlyc3QsIGxhc3QgKSB7XG5cdFx0XHR2YXIgc2ltcGxlID0gdHlwZS5zbGljZSggMCwgMyApICE9PSBcIm50aFwiLFxuXHRcdFx0XHRmb3J3YXJkID0gdHlwZS5zbGljZSggLTQgKSAhPT0gXCJsYXN0XCIsXG5cdFx0XHRcdG9mVHlwZSA9IHdoYXQgPT09IFwib2YtdHlwZVwiO1xuXG5cdFx0XHRyZXR1cm4gZmlyc3QgPT09IDEgJiYgbGFzdCA9PT0gMCA/XG5cblx0XHRcdFx0Ly8gU2hvcnRjdXQgZm9yIDpudGgtKihuKVxuXHRcdFx0XHRmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0XHRyZXR1cm4gISFlbGVtLnBhcmVudE5vZGU7XG5cdFx0XHRcdH0gOlxuXG5cdFx0XHRcdGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XG5cdFx0XHRcdFx0dmFyIGNhY2hlLCBvdXRlckNhY2hlLCBub2RlLCBkaWZmLCBub2RlSW5kZXgsIHN0YXJ0LFxuXHRcdFx0XHRcdFx0ZGlyID0gc2ltcGxlICE9PSBmb3J3YXJkID8gXCJuZXh0U2libGluZ1wiIDogXCJwcmV2aW91c1NpYmxpbmdcIixcblx0XHRcdFx0XHRcdHBhcmVudCA9IGVsZW0ucGFyZW50Tm9kZSxcblx0XHRcdFx0XHRcdG5hbWUgPSBvZlR5cGUgJiYgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpLFxuXHRcdFx0XHRcdFx0dXNlQ2FjaGUgPSAheG1sICYmICFvZlR5cGU7XG5cblx0XHRcdFx0XHRpZiAoIHBhcmVudCApIHtcblxuXHRcdFx0XHRcdFx0Ly8gOihmaXJzdHxsYXN0fG9ubHkpLShjaGlsZHxvZi10eXBlKVxuXHRcdFx0XHRcdFx0aWYgKCBzaW1wbGUgKSB7XG5cdFx0XHRcdFx0XHRcdHdoaWxlICggZGlyICkge1xuXHRcdFx0XHRcdFx0XHRcdG5vZGUgPSBlbGVtO1xuXHRcdFx0XHRcdFx0XHRcdHdoaWxlICggKG5vZGUgPSBub2RlWyBkaXIgXSkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRpZiAoIG9mVHlwZSA/IG5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gbmFtZSA6IG5vZGUubm9kZVR5cGUgPT09IDEgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0Ly8gUmV2ZXJzZSBkaXJlY3Rpb24gZm9yIDpvbmx5LSogKGlmIHdlIGhhdmVuJ3QgeWV0IGRvbmUgc28pXG5cdFx0XHRcdFx0XHRcdFx0c3RhcnQgPSBkaXIgPSB0eXBlID09PSBcIm9ubHlcIiAmJiAhc3RhcnQgJiYgXCJuZXh0U2libGluZ1wiO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRzdGFydCA9IFsgZm9yd2FyZCA/IHBhcmVudC5maXJzdENoaWxkIDogcGFyZW50Lmxhc3RDaGlsZCBdO1xuXG5cdFx0XHRcdFx0XHQvLyBub24teG1sIDpudGgtY2hpbGQoLi4uKSBzdG9yZXMgY2FjaGUgZGF0YSBvbiBgcGFyZW50YFxuXHRcdFx0XHRcdFx0aWYgKCBmb3J3YXJkICYmIHVzZUNhY2hlICkge1xuXHRcdFx0XHRcdFx0XHQvLyBTZWVrIGBlbGVtYCBmcm9tIGEgcHJldmlvdXNseS1jYWNoZWQgaW5kZXhcblx0XHRcdFx0XHRcdFx0b3V0ZXJDYWNoZSA9IHBhcmVudFsgZXhwYW5kbyBdIHx8IChwYXJlbnRbIGV4cGFuZG8gXSA9IHt9KTtcblx0XHRcdFx0XHRcdFx0Y2FjaGUgPSBvdXRlckNhY2hlWyB0eXBlIF0gfHwgW107XG5cdFx0XHRcdFx0XHRcdG5vZGVJbmRleCA9IGNhY2hlWzBdID09PSBkaXJydW5zICYmIGNhY2hlWzFdO1xuXHRcdFx0XHRcdFx0XHRkaWZmID0gY2FjaGVbMF0gPT09IGRpcnJ1bnMgJiYgY2FjaGVbMl07XG5cdFx0XHRcdFx0XHRcdG5vZGUgPSBub2RlSW5kZXggJiYgcGFyZW50LmNoaWxkTm9kZXNbIG5vZGVJbmRleCBdO1xuXG5cdFx0XHRcdFx0XHRcdHdoaWxlICggKG5vZGUgPSArK25vZGVJbmRleCAmJiBub2RlICYmIG5vZGVbIGRpciBdIHx8XG5cblx0XHRcdFx0XHRcdFx0XHQvLyBGYWxsYmFjayB0byBzZWVraW5nIGBlbGVtYCBmcm9tIHRoZSBzdGFydFxuXHRcdFx0XHRcdFx0XHRcdChkaWZmID0gbm9kZUluZGV4ID0gMCkgfHwgc3RhcnQucG9wKCkpICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gV2hlbiBmb3VuZCwgY2FjaGUgaW5kZXhlcyBvbiBgcGFyZW50YCBhbmQgYnJlYWtcblx0XHRcdFx0XHRcdFx0XHRpZiAoIG5vZGUubm9kZVR5cGUgPT09IDEgJiYgKytkaWZmICYmIG5vZGUgPT09IGVsZW0gKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRvdXRlckNhY2hlWyB0eXBlIF0gPSBbIGRpcnJ1bnMsIG5vZGVJbmRleCwgZGlmZiBdO1xuXHRcdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdC8vIFVzZSBwcmV2aW91c2x5LWNhY2hlZCBlbGVtZW50IGluZGV4IGlmIGF2YWlsYWJsZVxuXHRcdFx0XHRcdFx0fSBlbHNlIGlmICggdXNlQ2FjaGUgJiYgKGNhY2hlID0gKGVsZW1bIGV4cGFuZG8gXSB8fCAoZWxlbVsgZXhwYW5kbyBdID0ge30pKVsgdHlwZSBdKSAmJiBjYWNoZVswXSA9PT0gZGlycnVucyApIHtcblx0XHRcdFx0XHRcdFx0ZGlmZiA9IGNhY2hlWzFdO1xuXG5cdFx0XHRcdFx0XHQvLyB4bWwgOm50aC1jaGlsZCguLi4pIG9yIDpudGgtbGFzdC1jaGlsZCguLi4pIG9yIDpudGgoLWxhc3QpPy1vZi10eXBlKC4uLilcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdC8vIFVzZSB0aGUgc2FtZSBsb29wIGFzIGFib3ZlIHRvIHNlZWsgYGVsZW1gIGZyb20gdGhlIHN0YXJ0XG5cdFx0XHRcdFx0XHRcdHdoaWxlICggKG5vZGUgPSArK25vZGVJbmRleCAmJiBub2RlICYmIG5vZGVbIGRpciBdIHx8XG5cdFx0XHRcdFx0XHRcdFx0KGRpZmYgPSBub2RlSW5kZXggPSAwKSB8fCBzdGFydC5wb3AoKSkgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHRpZiAoICggb2ZUeXBlID8gbm9kZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSBuYW1lIDogbm9kZS5ub2RlVHlwZSA9PT0gMSApICYmICsrZGlmZiApIHtcblx0XHRcdFx0XHRcdFx0XHRcdC8vIENhY2hlIHRoZSBpbmRleCBvZiBlYWNoIGVuY291bnRlcmVkIGVsZW1lbnRcblx0XHRcdFx0XHRcdFx0XHRcdGlmICggdXNlQ2FjaGUgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdChub2RlWyBleHBhbmRvIF0gfHwgKG5vZGVbIGV4cGFuZG8gXSA9IHt9KSlbIHR5cGUgXSA9IFsgZGlycnVucywgZGlmZiBdO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdFx0XHRpZiAoIG5vZGUgPT09IGVsZW0gKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQvLyBJbmNvcnBvcmF0ZSB0aGUgb2Zmc2V0LCB0aGVuIGNoZWNrIGFnYWluc3QgY3ljbGUgc2l6ZVxuXHRcdFx0XHRcdFx0ZGlmZiAtPSBsYXN0O1xuXHRcdFx0XHRcdFx0cmV0dXJuIGRpZmYgPT09IGZpcnN0IHx8ICggZGlmZiAlIGZpcnN0ID09PSAwICYmIGRpZmYgLyBmaXJzdCA+PSAwICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9O1xuXHRcdH0sXG5cblx0XHRcIlBTRVVET1wiOiBmdW5jdGlvbiggcHNldWRvLCBhcmd1bWVudCApIHtcblx0XHRcdC8vIHBzZXVkby1jbGFzcyBuYW1lcyBhcmUgY2FzZS1pbnNlbnNpdGl2ZVxuXHRcdFx0Ly8gaHR0cDovL3d3dy53My5vcmcvVFIvc2VsZWN0b3JzLyNwc2V1ZG8tY2xhc3Nlc1xuXHRcdFx0Ly8gUHJpb3JpdGl6ZSBieSBjYXNlIHNlbnNpdGl2aXR5IGluIGNhc2UgY3VzdG9tIHBzZXVkb3MgYXJlIGFkZGVkIHdpdGggdXBwZXJjYXNlIGxldHRlcnNcblx0XHRcdC8vIFJlbWVtYmVyIHRoYXQgc2V0RmlsdGVycyBpbmhlcml0cyBmcm9tIHBzZXVkb3Ncblx0XHRcdHZhciBhcmdzLFxuXHRcdFx0XHRmbiA9IEV4cHIucHNldWRvc1sgcHNldWRvIF0gfHwgRXhwci5zZXRGaWx0ZXJzWyBwc2V1ZG8udG9Mb3dlckNhc2UoKSBdIHx8XG5cdFx0XHRcdFx0U2l6emxlLmVycm9yKCBcInVuc3VwcG9ydGVkIHBzZXVkbzogXCIgKyBwc2V1ZG8gKTtcblxuXHRcdFx0Ly8gVGhlIHVzZXIgbWF5IHVzZSBjcmVhdGVQc2V1ZG8gdG8gaW5kaWNhdGUgdGhhdFxuXHRcdFx0Ly8gYXJndW1lbnRzIGFyZSBuZWVkZWQgdG8gY3JlYXRlIHRoZSBmaWx0ZXIgZnVuY3Rpb25cblx0XHRcdC8vIGp1c3QgYXMgU2l6emxlIGRvZXNcblx0XHRcdGlmICggZm5bIGV4cGFuZG8gXSApIHtcblx0XHRcdFx0cmV0dXJuIGZuKCBhcmd1bWVudCApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBCdXQgbWFpbnRhaW4gc3VwcG9ydCBmb3Igb2xkIHNpZ25hdHVyZXNcblx0XHRcdGlmICggZm4ubGVuZ3RoID4gMSApIHtcblx0XHRcdFx0YXJncyA9IFsgcHNldWRvLCBwc2V1ZG8sIFwiXCIsIGFyZ3VtZW50IF07XG5cdFx0XHRcdHJldHVybiBFeHByLnNldEZpbHRlcnMuaGFzT3duUHJvcGVydHkoIHBzZXVkby50b0xvd2VyQ2FzZSgpICkgP1xuXHRcdFx0XHRcdG1hcmtGdW5jdGlvbihmdW5jdGlvbiggc2VlZCwgbWF0Y2hlcyApIHtcblx0XHRcdFx0XHRcdHZhciBpZHgsXG5cdFx0XHRcdFx0XHRcdG1hdGNoZWQgPSBmbiggc2VlZCwgYXJndW1lbnQgKSxcblx0XHRcdFx0XHRcdFx0aSA9IG1hdGNoZWQubGVuZ3RoO1xuXHRcdFx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdFx0XHRcdGlkeCA9IGluZGV4T2YoIHNlZWQsIG1hdGNoZWRbaV0gKTtcblx0XHRcdFx0XHRcdFx0c2VlZFsgaWR4IF0gPSAhKCBtYXRjaGVzWyBpZHggXSA9IG1hdGNoZWRbaV0gKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KSA6XG5cdFx0XHRcdFx0ZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZm4oIGVsZW0sIDAsIGFyZ3MgKTtcblx0XHRcdFx0XHR9O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZm47XG5cdFx0fVxuXHR9LFxuXG5cdHBzZXVkb3M6IHtcblx0XHQvLyBQb3RlbnRpYWxseSBjb21wbGV4IHBzZXVkb3Ncblx0XHRcIm5vdFwiOiBtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdFx0Ly8gVHJpbSB0aGUgc2VsZWN0b3IgcGFzc2VkIHRvIGNvbXBpbGVcblx0XHRcdC8vIHRvIGF2b2lkIHRyZWF0aW5nIGxlYWRpbmcgYW5kIHRyYWlsaW5nXG5cdFx0XHQvLyBzcGFjZXMgYXMgY29tYmluYXRvcnNcblx0XHRcdHZhciBpbnB1dCA9IFtdLFxuXHRcdFx0XHRyZXN1bHRzID0gW10sXG5cdFx0XHRcdG1hdGNoZXIgPSBjb21waWxlKCBzZWxlY3Rvci5yZXBsYWNlKCBydHJpbSwgXCIkMVwiICkgKTtcblxuXHRcdFx0cmV0dXJuIG1hdGNoZXJbIGV4cGFuZG8gXSA/XG5cdFx0XHRcdG1hcmtGdW5jdGlvbihmdW5jdGlvbiggc2VlZCwgbWF0Y2hlcywgY29udGV4dCwgeG1sICkge1xuXHRcdFx0XHRcdHZhciBlbGVtLFxuXHRcdFx0XHRcdFx0dW5tYXRjaGVkID0gbWF0Y2hlciggc2VlZCwgbnVsbCwgeG1sLCBbXSApLFxuXHRcdFx0XHRcdFx0aSA9IHNlZWQubGVuZ3RoO1xuXG5cdFx0XHRcdFx0Ly8gTWF0Y2ggZWxlbWVudHMgdW5tYXRjaGVkIGJ5IGBtYXRjaGVyYFxuXHRcdFx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRcdFx0aWYgKCAoZWxlbSA9IHVubWF0Y2hlZFtpXSkgKSB7XG5cdFx0XHRcdFx0XHRcdHNlZWRbaV0gPSAhKG1hdGNoZXNbaV0gPSBlbGVtKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pIDpcblx0XHRcdFx0ZnVuY3Rpb24oIGVsZW0sIGNvbnRleHQsIHhtbCApIHtcblx0XHRcdFx0XHRpbnB1dFswXSA9IGVsZW07XG5cdFx0XHRcdFx0bWF0Y2hlciggaW5wdXQsIG51bGwsIHhtbCwgcmVzdWx0cyApO1xuXHRcdFx0XHRcdC8vIERvbid0IGtlZXAgdGhlIGVsZW1lbnQgKGlzc3VlICMyOTkpXG5cdFx0XHRcdFx0aW5wdXRbMF0gPSBudWxsO1xuXHRcdFx0XHRcdHJldHVybiAhcmVzdWx0cy5wb3AoKTtcblx0XHRcdFx0fTtcblx0XHR9KSxcblxuXHRcdFwiaGFzXCI6IG1hcmtGdW5jdGlvbihmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHJldHVybiBTaXp6bGUoIHNlbGVjdG9yLCBlbGVtICkubGVuZ3RoID4gMDtcblx0XHRcdH07XG5cdFx0fSksXG5cblx0XHRcImNvbnRhaW5zXCI6IG1hcmtGdW5jdGlvbihmdW5jdGlvbiggdGV4dCApIHtcblx0XHRcdHRleHQgPSB0ZXh0LnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICk7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHJldHVybiAoIGVsZW0udGV4dENvbnRlbnQgfHwgZWxlbS5pbm5lclRleHQgfHwgZ2V0VGV4dCggZWxlbSApICkuaW5kZXhPZiggdGV4dCApID4gLTE7XG5cdFx0XHR9O1xuXHRcdH0pLFxuXG5cdFx0Ly8gXCJXaGV0aGVyIGFuIGVsZW1lbnQgaXMgcmVwcmVzZW50ZWQgYnkgYSA6bGFuZygpIHNlbGVjdG9yXG5cdFx0Ly8gaXMgYmFzZWQgc29sZWx5IG9uIHRoZSBlbGVtZW50J3MgbGFuZ3VhZ2UgdmFsdWVcblx0XHQvLyBiZWluZyBlcXVhbCB0byB0aGUgaWRlbnRpZmllciBDLFxuXHRcdC8vIG9yIGJlZ2lubmluZyB3aXRoIHRoZSBpZGVudGlmaWVyIEMgaW1tZWRpYXRlbHkgZm9sbG93ZWQgYnkgXCItXCIuXG5cdFx0Ly8gVGhlIG1hdGNoaW5nIG9mIEMgYWdhaW5zdCB0aGUgZWxlbWVudCdzIGxhbmd1YWdlIHZhbHVlIGlzIHBlcmZvcm1lZCBjYXNlLWluc2Vuc2l0aXZlbHkuXG5cdFx0Ly8gVGhlIGlkZW50aWZpZXIgQyBkb2VzIG5vdCBoYXZlIHRvIGJlIGEgdmFsaWQgbGFuZ3VhZ2UgbmFtZS5cIlxuXHRcdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSL3NlbGVjdG9ycy8jbGFuZy1wc2V1ZG9cblx0XHRcImxhbmdcIjogbWFya0Z1bmN0aW9uKCBmdW5jdGlvbiggbGFuZyApIHtcblx0XHRcdC8vIGxhbmcgdmFsdWUgbXVzdCBiZSBhIHZhbGlkIGlkZW50aWZpZXJcblx0XHRcdGlmICggIXJpZGVudGlmaWVyLnRlc3QobGFuZyB8fCBcIlwiKSApIHtcblx0XHRcdFx0U2l6emxlLmVycm9yKCBcInVuc3VwcG9ydGVkIGxhbmc6IFwiICsgbGFuZyApO1xuXHRcdFx0fVxuXHRcdFx0bGFuZyA9IGxhbmcucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHR2YXIgZWxlbUxhbmc7XG5cdFx0XHRcdGRvIHtcblx0XHRcdFx0XHRpZiAoIChlbGVtTGFuZyA9IGRvY3VtZW50SXNIVE1MID9cblx0XHRcdFx0XHRcdGVsZW0ubGFuZyA6XG5cdFx0XHRcdFx0XHRlbGVtLmdldEF0dHJpYnV0ZShcInhtbDpsYW5nXCIpIHx8IGVsZW0uZ2V0QXR0cmlidXRlKFwibGFuZ1wiKSkgKSB7XG5cblx0XHRcdFx0XHRcdGVsZW1MYW5nID0gZWxlbUxhbmcudG9Mb3dlckNhc2UoKTtcblx0XHRcdFx0XHRcdHJldHVybiBlbGVtTGFuZyA9PT0gbGFuZyB8fCBlbGVtTGFuZy5pbmRleE9mKCBsYW5nICsgXCItXCIgKSA9PT0gMDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gd2hpbGUgKCAoZWxlbSA9IGVsZW0ucGFyZW50Tm9kZSkgJiYgZWxlbS5ub2RlVHlwZSA9PT0gMSApO1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9O1xuXHRcdH0pLFxuXG5cdFx0Ly8gTWlzY2VsbGFuZW91c1xuXHRcdFwidGFyZ2V0XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0dmFyIGhhc2ggPSB3aW5kb3cubG9jYXRpb24gJiYgd2luZG93LmxvY2F0aW9uLmhhc2g7XG5cdFx0XHRyZXR1cm4gaGFzaCAmJiBoYXNoLnNsaWNlKCAxICkgPT09IGVsZW0uaWQ7XG5cdFx0fSxcblxuXHRcdFwicm9vdFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtID09PSBkb2NFbGVtO1xuXHRcdH0sXG5cblx0XHRcImZvY3VzXCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIGVsZW0gPT09IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgJiYgKCFkb2N1bWVudC5oYXNGb2N1cyB8fCBkb2N1bWVudC5oYXNGb2N1cygpKSAmJiAhIShlbGVtLnR5cGUgfHwgZWxlbS5ocmVmIHx8IH5lbGVtLnRhYkluZGV4KTtcblx0XHR9LFxuXG5cdFx0Ly8gQm9vbGVhbiBwcm9wZXJ0aWVzXG5cdFx0XCJlbmFibGVkXCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIGVsZW0uZGlzYWJsZWQgPT09IGZhbHNlO1xuXHRcdH0sXG5cblx0XHRcImRpc2FibGVkXCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIGVsZW0uZGlzYWJsZWQgPT09IHRydWU7XG5cdFx0fSxcblxuXHRcdFwiY2hlY2tlZFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdC8vIEluIENTUzMsIDpjaGVja2VkIHNob3VsZCByZXR1cm4gYm90aCBjaGVja2VkIGFuZCBzZWxlY3RlZCBlbGVtZW50c1xuXHRcdFx0Ly8gaHR0cDovL3d3dy53My5vcmcvVFIvMjAxMS9SRUMtY3NzMy1zZWxlY3RvcnMtMjAxMTA5MjkvI2NoZWNrZWRcblx0XHRcdHZhciBub2RlTmFtZSA9IGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblx0XHRcdHJldHVybiAobm9kZU5hbWUgPT09IFwiaW5wdXRcIiAmJiAhIWVsZW0uY2hlY2tlZCkgfHwgKG5vZGVOYW1lID09PSBcIm9wdGlvblwiICYmICEhZWxlbS5zZWxlY3RlZCk7XG5cdFx0fSxcblxuXHRcdFwic2VsZWN0ZWRcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHQvLyBBY2Nlc3NpbmcgdGhpcyBwcm9wZXJ0eSBtYWtlcyBzZWxlY3RlZC1ieS1kZWZhdWx0XG5cdFx0XHQvLyBvcHRpb25zIGluIFNhZmFyaSB3b3JrIHByb3Blcmx5XG5cdFx0XHRpZiAoIGVsZW0ucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0ZWxlbS5wYXJlbnROb2RlLnNlbGVjdGVkSW5kZXg7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBlbGVtLnNlbGVjdGVkID09PSB0cnVlO1xuXHRcdH0sXG5cblx0XHQvLyBDb250ZW50c1xuXHRcdFwiZW1wdHlcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHQvLyBodHRwOi8vd3d3LnczLm9yZy9UUi9zZWxlY3RvcnMvI2VtcHR5LXBzZXVkb1xuXHRcdFx0Ly8gOmVtcHR5IGlzIG5lZ2F0ZWQgYnkgZWxlbWVudCAoMSkgb3IgY29udGVudCBub2RlcyAodGV4dDogMzsgY2RhdGE6IDQ7IGVudGl0eSByZWY6IDUpLFxuXHRcdFx0Ly8gICBidXQgbm90IGJ5IG90aGVycyAoY29tbWVudDogODsgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbjogNzsgZXRjLilcblx0XHRcdC8vIG5vZGVUeXBlIDwgNiB3b3JrcyBiZWNhdXNlIGF0dHJpYnV0ZXMgKDIpIGRvIG5vdCBhcHBlYXIgYXMgY2hpbGRyZW5cblx0XHRcdGZvciAoIGVsZW0gPSBlbGVtLmZpcnN0Q2hpbGQ7IGVsZW07IGVsZW0gPSBlbGVtLm5leHRTaWJsaW5nICkge1xuXHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPCA2ICkge1xuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fSxcblxuXHRcdFwicGFyZW50XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuICFFeHByLnBzZXVkb3NbXCJlbXB0eVwiXSggZWxlbSApO1xuXHRcdH0sXG5cblx0XHQvLyBFbGVtZW50L2lucHV0IHR5cGVzXG5cdFx0XCJoZWFkZXJcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gcmhlYWRlci50ZXN0KCBlbGVtLm5vZGVOYW1lICk7XG5cdFx0fSxcblxuXHRcdFwiaW5wdXRcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gcmlucHV0cy50ZXN0KCBlbGVtLm5vZGVOYW1lICk7XG5cdFx0fSxcblxuXHRcdFwiYnV0dG9uXCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0dmFyIG5hbWUgPSBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRyZXR1cm4gbmFtZSA9PT0gXCJpbnB1dFwiICYmIGVsZW0udHlwZSA9PT0gXCJidXR0b25cIiB8fCBuYW1lID09PSBcImJ1dHRvblwiO1xuXHRcdH0sXG5cblx0XHRcInRleHRcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHR2YXIgYXR0cjtcblx0XHRcdHJldHVybiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IFwiaW5wdXRcIiAmJlxuXHRcdFx0XHRlbGVtLnR5cGUgPT09IFwidGV4dFwiICYmXG5cblx0XHRcdFx0Ly8gU3VwcG9ydDogSUU8OFxuXHRcdFx0XHQvLyBOZXcgSFRNTDUgYXR0cmlidXRlIHZhbHVlcyAoZS5nLiwgXCJzZWFyY2hcIikgYXBwZWFyIHdpdGggZWxlbS50eXBlID09PSBcInRleHRcIlxuXHRcdFx0XHQoIChhdHRyID0gZWxlbS5nZXRBdHRyaWJ1dGUoXCJ0eXBlXCIpKSA9PSBudWxsIHx8IGF0dHIudG9Mb3dlckNhc2UoKSA9PT0gXCJ0ZXh0XCIgKTtcblx0XHR9LFxuXG5cdFx0Ly8gUG9zaXRpb24taW4tY29sbGVjdGlvblxuXHRcdFwiZmlyc3RcIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyhmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiBbIDAgXTtcblx0XHR9KSxcblxuXHRcdFwibGFzdFwiOiBjcmVhdGVQb3NpdGlvbmFsUHNldWRvKGZ1bmN0aW9uKCBtYXRjaEluZGV4ZXMsIGxlbmd0aCApIHtcblx0XHRcdHJldHVybiBbIGxlbmd0aCAtIDEgXTtcblx0XHR9KSxcblxuXHRcdFwiZXFcIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyhmdW5jdGlvbiggbWF0Y2hJbmRleGVzLCBsZW5ndGgsIGFyZ3VtZW50ICkge1xuXHRcdFx0cmV0dXJuIFsgYXJndW1lbnQgPCAwID8gYXJndW1lbnQgKyBsZW5ndGggOiBhcmd1bWVudCBdO1xuXHRcdH0pLFxuXG5cdFx0XCJldmVuXCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoICkge1xuXHRcdFx0dmFyIGkgPSAwO1xuXHRcdFx0Zm9yICggOyBpIDwgbGVuZ3RoOyBpICs9IDIgKSB7XG5cdFx0XHRcdG1hdGNoSW5kZXhlcy5wdXNoKCBpICk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gbWF0Y2hJbmRleGVzO1xuXHRcdH0pLFxuXG5cdFx0XCJvZGRcIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyhmdW5jdGlvbiggbWF0Y2hJbmRleGVzLCBsZW5ndGggKSB7XG5cdFx0XHR2YXIgaSA9IDE7XG5cdFx0XHRmb3IgKCA7IGkgPCBsZW5ndGg7IGkgKz0gMiApIHtcblx0XHRcdFx0bWF0Y2hJbmRleGVzLnB1c2goIGkgKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBtYXRjaEluZGV4ZXM7XG5cdFx0fSksXG5cblx0XHRcImx0XCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoLCBhcmd1bWVudCApIHtcblx0XHRcdHZhciBpID0gYXJndW1lbnQgPCAwID8gYXJndW1lbnQgKyBsZW5ndGggOiBhcmd1bWVudDtcblx0XHRcdGZvciAoIDsgLS1pID49IDA7ICkge1xuXHRcdFx0XHRtYXRjaEluZGV4ZXMucHVzaCggaSApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG1hdGNoSW5kZXhlcztcblx0XHR9KSxcblxuXHRcdFwiZ3RcIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyhmdW5jdGlvbiggbWF0Y2hJbmRleGVzLCBsZW5ndGgsIGFyZ3VtZW50ICkge1xuXHRcdFx0dmFyIGkgPSBhcmd1bWVudCA8IDAgPyBhcmd1bWVudCArIGxlbmd0aCA6IGFyZ3VtZW50O1xuXHRcdFx0Zm9yICggOyArK2kgPCBsZW5ndGg7ICkge1xuXHRcdFx0XHRtYXRjaEluZGV4ZXMucHVzaCggaSApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG1hdGNoSW5kZXhlcztcblx0XHR9KVxuXHR9XG59O1xuXG5FeHByLnBzZXVkb3NbXCJudGhcIl0gPSBFeHByLnBzZXVkb3NbXCJlcVwiXTtcblxuLy8gQWRkIGJ1dHRvbi9pbnB1dCB0eXBlIHBzZXVkb3NcbmZvciAoIGkgaW4geyByYWRpbzogdHJ1ZSwgY2hlY2tib3g6IHRydWUsIGZpbGU6IHRydWUsIHBhc3N3b3JkOiB0cnVlLCBpbWFnZTogdHJ1ZSB9ICkge1xuXHRFeHByLnBzZXVkb3NbIGkgXSA9IGNyZWF0ZUlucHV0UHNldWRvKCBpICk7XG59XG5mb3IgKCBpIGluIHsgc3VibWl0OiB0cnVlLCByZXNldDogdHJ1ZSB9ICkge1xuXHRFeHByLnBzZXVkb3NbIGkgXSA9IGNyZWF0ZUJ1dHRvblBzZXVkbyggaSApO1xufVxuXG4vLyBFYXN5IEFQSSBmb3IgY3JlYXRpbmcgbmV3IHNldEZpbHRlcnNcbmZ1bmN0aW9uIHNldEZpbHRlcnMoKSB7fVxuc2V0RmlsdGVycy5wcm90b3R5cGUgPSBFeHByLmZpbHRlcnMgPSBFeHByLnBzZXVkb3M7XG5FeHByLnNldEZpbHRlcnMgPSBuZXcgc2V0RmlsdGVycygpO1xuXG50b2tlbml6ZSA9IFNpenpsZS50b2tlbml6ZSA9IGZ1bmN0aW9uKCBzZWxlY3RvciwgcGFyc2VPbmx5ICkge1xuXHR2YXIgbWF0Y2hlZCwgbWF0Y2gsIHRva2VucywgdHlwZSxcblx0XHRzb0ZhciwgZ3JvdXBzLCBwcmVGaWx0ZXJzLFxuXHRcdGNhY2hlZCA9IHRva2VuQ2FjaGVbIHNlbGVjdG9yICsgXCIgXCIgXTtcblxuXHRpZiAoIGNhY2hlZCApIHtcblx0XHRyZXR1cm4gcGFyc2VPbmx5ID8gMCA6IGNhY2hlZC5zbGljZSggMCApO1xuXHR9XG5cblx0c29GYXIgPSBzZWxlY3Rvcjtcblx0Z3JvdXBzID0gW107XG5cdHByZUZpbHRlcnMgPSBFeHByLnByZUZpbHRlcjtcblxuXHR3aGlsZSAoIHNvRmFyICkge1xuXG5cdFx0Ly8gQ29tbWEgYW5kIGZpcnN0IHJ1blxuXHRcdGlmICggIW1hdGNoZWQgfHwgKG1hdGNoID0gcmNvbW1hLmV4ZWMoIHNvRmFyICkpICkge1xuXHRcdFx0aWYgKCBtYXRjaCApIHtcblx0XHRcdFx0Ly8gRG9uJ3QgY29uc3VtZSB0cmFpbGluZyBjb21tYXMgYXMgdmFsaWRcblx0XHRcdFx0c29GYXIgPSBzb0Zhci5zbGljZSggbWF0Y2hbMF0ubGVuZ3RoICkgfHwgc29GYXI7XG5cdFx0XHR9XG5cdFx0XHRncm91cHMucHVzaCggKHRva2VucyA9IFtdKSApO1xuXHRcdH1cblxuXHRcdG1hdGNoZWQgPSBmYWxzZTtcblxuXHRcdC8vIENvbWJpbmF0b3JzXG5cdFx0aWYgKCAobWF0Y2ggPSByY29tYmluYXRvcnMuZXhlYyggc29GYXIgKSkgKSB7XG5cdFx0XHRtYXRjaGVkID0gbWF0Y2guc2hpZnQoKTtcblx0XHRcdHRva2Vucy5wdXNoKHtcblx0XHRcdFx0dmFsdWU6IG1hdGNoZWQsXG5cdFx0XHRcdC8vIENhc3QgZGVzY2VuZGFudCBjb21iaW5hdG9ycyB0byBzcGFjZVxuXHRcdFx0XHR0eXBlOiBtYXRjaFswXS5yZXBsYWNlKCBydHJpbSwgXCIgXCIgKVxuXHRcdFx0fSk7XG5cdFx0XHRzb0ZhciA9IHNvRmFyLnNsaWNlKCBtYXRjaGVkLmxlbmd0aCApO1xuXHRcdH1cblxuXHRcdC8vIEZpbHRlcnNcblx0XHRmb3IgKCB0eXBlIGluIEV4cHIuZmlsdGVyICkge1xuXHRcdFx0aWYgKCAobWF0Y2ggPSBtYXRjaEV4cHJbIHR5cGUgXS5leGVjKCBzb0ZhciApKSAmJiAoIXByZUZpbHRlcnNbIHR5cGUgXSB8fFxuXHRcdFx0XHQobWF0Y2ggPSBwcmVGaWx0ZXJzWyB0eXBlIF0oIG1hdGNoICkpKSApIHtcblx0XHRcdFx0bWF0Y2hlZCA9IG1hdGNoLnNoaWZ0KCk7XG5cdFx0XHRcdHRva2Vucy5wdXNoKHtcblx0XHRcdFx0XHR2YWx1ZTogbWF0Y2hlZCxcblx0XHRcdFx0XHR0eXBlOiB0eXBlLFxuXHRcdFx0XHRcdG1hdGNoZXM6IG1hdGNoXG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRzb0ZhciA9IHNvRmFyLnNsaWNlKCBtYXRjaGVkLmxlbmd0aCApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmICggIW1hdGNoZWQgKSB7XG5cdFx0XHRicmVhaztcblx0XHR9XG5cdH1cblxuXHQvLyBSZXR1cm4gdGhlIGxlbmd0aCBvZiB0aGUgaW52YWxpZCBleGNlc3Ncblx0Ly8gaWYgd2UncmUganVzdCBwYXJzaW5nXG5cdC8vIE90aGVyd2lzZSwgdGhyb3cgYW4gZXJyb3Igb3IgcmV0dXJuIHRva2Vuc1xuXHRyZXR1cm4gcGFyc2VPbmx5ID9cblx0XHRzb0Zhci5sZW5ndGggOlxuXHRcdHNvRmFyID9cblx0XHRcdFNpenpsZS5lcnJvciggc2VsZWN0b3IgKSA6XG5cdFx0XHQvLyBDYWNoZSB0aGUgdG9rZW5zXG5cdFx0XHR0b2tlbkNhY2hlKCBzZWxlY3RvciwgZ3JvdXBzICkuc2xpY2UoIDAgKTtcbn07XG5cbmZ1bmN0aW9uIHRvU2VsZWN0b3IoIHRva2VucyApIHtcblx0dmFyIGkgPSAwLFxuXHRcdGxlbiA9IHRva2Vucy5sZW5ndGgsXG5cdFx0c2VsZWN0b3IgPSBcIlwiO1xuXHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRzZWxlY3RvciArPSB0b2tlbnNbaV0udmFsdWU7XG5cdH1cblx0cmV0dXJuIHNlbGVjdG9yO1xufVxuXG5mdW5jdGlvbiBhZGRDb21iaW5hdG9yKCBtYXRjaGVyLCBjb21iaW5hdG9yLCBiYXNlICkge1xuXHR2YXIgZGlyID0gY29tYmluYXRvci5kaXIsXG5cdFx0Y2hlY2tOb25FbGVtZW50cyA9IGJhc2UgJiYgZGlyID09PSBcInBhcmVudE5vZGVcIixcblx0XHRkb25lTmFtZSA9IGRvbmUrKztcblxuXHRyZXR1cm4gY29tYmluYXRvci5maXJzdCA/XG5cdFx0Ly8gQ2hlY2sgYWdhaW5zdCBjbG9zZXN0IGFuY2VzdG9yL3ByZWNlZGluZyBlbGVtZW50XG5cdFx0ZnVuY3Rpb24oIGVsZW0sIGNvbnRleHQsIHhtbCApIHtcblx0XHRcdHdoaWxlICggKGVsZW0gPSBlbGVtWyBkaXIgXSkgKSB7XG5cdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSB8fCBjaGVja05vbkVsZW1lbnRzICkge1xuXHRcdFx0XHRcdHJldHVybiBtYXRjaGVyKCBlbGVtLCBjb250ZXh0LCB4bWwgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0gOlxuXG5cdFx0Ly8gQ2hlY2sgYWdhaW5zdCBhbGwgYW5jZXN0b3IvcHJlY2VkaW5nIGVsZW1lbnRzXG5cdFx0ZnVuY3Rpb24oIGVsZW0sIGNvbnRleHQsIHhtbCApIHtcblx0XHRcdHZhciBvbGRDYWNoZSwgb3V0ZXJDYWNoZSxcblx0XHRcdFx0bmV3Q2FjaGUgPSBbIGRpcnJ1bnMsIGRvbmVOYW1lIF07XG5cblx0XHRcdC8vIFdlIGNhbid0IHNldCBhcmJpdHJhcnkgZGF0YSBvbiBYTUwgbm9kZXMsIHNvIHRoZXkgZG9uJ3QgYmVuZWZpdCBmcm9tIGRpciBjYWNoaW5nXG5cdFx0XHRpZiAoIHhtbCApIHtcblx0XHRcdFx0d2hpbGUgKCAoZWxlbSA9IGVsZW1bIGRpciBdKSApIHtcblx0XHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgfHwgY2hlY2tOb25FbGVtZW50cyApIHtcblx0XHRcdFx0XHRcdGlmICggbWF0Y2hlciggZWxlbSwgY29udGV4dCwgeG1sICkgKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0d2hpbGUgKCAoZWxlbSA9IGVsZW1bIGRpciBdKSApIHtcblx0XHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgfHwgY2hlY2tOb25FbGVtZW50cyApIHtcblx0XHRcdFx0XHRcdG91dGVyQ2FjaGUgPSBlbGVtWyBleHBhbmRvIF0gfHwgKGVsZW1bIGV4cGFuZG8gXSA9IHt9KTtcblx0XHRcdFx0XHRcdGlmICggKG9sZENhY2hlID0gb3V0ZXJDYWNoZVsgZGlyIF0pICYmXG5cdFx0XHRcdFx0XHRcdG9sZENhY2hlWyAwIF0gPT09IGRpcnJ1bnMgJiYgb2xkQ2FjaGVbIDEgXSA9PT0gZG9uZU5hbWUgKSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gQXNzaWduIHRvIG5ld0NhY2hlIHNvIHJlc3VsdHMgYmFjay1wcm9wYWdhdGUgdG8gcHJldmlvdXMgZWxlbWVudHNcblx0XHRcdFx0XHRcdFx0cmV0dXJuIChuZXdDYWNoZVsgMiBdID0gb2xkQ2FjaGVbIDIgXSk7XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHQvLyBSZXVzZSBuZXdjYWNoZSBzbyByZXN1bHRzIGJhY2stcHJvcGFnYXRlIHRvIHByZXZpb3VzIGVsZW1lbnRzXG5cdFx0XHRcdFx0XHRcdG91dGVyQ2FjaGVbIGRpciBdID0gbmV3Q2FjaGU7XG5cblx0XHRcdFx0XHRcdFx0Ly8gQSBtYXRjaCBtZWFucyB3ZSdyZSBkb25lOyBhIGZhaWwgbWVhbnMgd2UgaGF2ZSB0byBrZWVwIGNoZWNraW5nXG5cdFx0XHRcdFx0XHRcdGlmICggKG5ld0NhY2hlWyAyIF0gPSBtYXRjaGVyKCBlbGVtLCBjb250ZXh0LCB4bWwgKSkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9O1xufVxuXG5mdW5jdGlvbiBlbGVtZW50TWF0Y2hlciggbWF0Y2hlcnMgKSB7XG5cdHJldHVybiBtYXRjaGVycy5sZW5ndGggPiAxID9cblx0XHRmdW5jdGlvbiggZWxlbSwgY29udGV4dCwgeG1sICkge1xuXHRcdFx0dmFyIGkgPSBtYXRjaGVycy5sZW5ndGg7XG5cdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0aWYgKCAhbWF0Y2hlcnNbaV0oIGVsZW0sIGNvbnRleHQsIHhtbCApICkge1xuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fSA6XG5cdFx0bWF0Y2hlcnNbMF07XG59XG5cbmZ1bmN0aW9uIG11bHRpcGxlQ29udGV4dHMoIHNlbGVjdG9yLCBjb250ZXh0cywgcmVzdWx0cyApIHtcblx0dmFyIGkgPSAwLFxuXHRcdGxlbiA9IGNvbnRleHRzLmxlbmd0aDtcblx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0U2l6emxlKCBzZWxlY3RvciwgY29udGV4dHNbaV0sIHJlc3VsdHMgKTtcblx0fVxuXHRyZXR1cm4gcmVzdWx0cztcbn1cblxuZnVuY3Rpb24gY29uZGVuc2UoIHVubWF0Y2hlZCwgbWFwLCBmaWx0ZXIsIGNvbnRleHQsIHhtbCApIHtcblx0dmFyIGVsZW0sXG5cdFx0bmV3VW5tYXRjaGVkID0gW10sXG5cdFx0aSA9IDAsXG5cdFx0bGVuID0gdW5tYXRjaGVkLmxlbmd0aCxcblx0XHRtYXBwZWQgPSBtYXAgIT0gbnVsbDtcblxuXHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRpZiAoIChlbGVtID0gdW5tYXRjaGVkW2ldKSApIHtcblx0XHRcdGlmICggIWZpbHRlciB8fCBmaWx0ZXIoIGVsZW0sIGNvbnRleHQsIHhtbCApICkge1xuXHRcdFx0XHRuZXdVbm1hdGNoZWQucHVzaCggZWxlbSApO1xuXHRcdFx0XHRpZiAoIG1hcHBlZCApIHtcblx0XHRcdFx0XHRtYXAucHVzaCggaSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIG5ld1VubWF0Y2hlZDtcbn1cblxuZnVuY3Rpb24gc2V0TWF0Y2hlciggcHJlRmlsdGVyLCBzZWxlY3RvciwgbWF0Y2hlciwgcG9zdEZpbHRlciwgcG9zdEZpbmRlciwgcG9zdFNlbGVjdG9yICkge1xuXHRpZiAoIHBvc3RGaWx0ZXIgJiYgIXBvc3RGaWx0ZXJbIGV4cGFuZG8gXSApIHtcblx0XHRwb3N0RmlsdGVyID0gc2V0TWF0Y2hlciggcG9zdEZpbHRlciApO1xuXHR9XG5cdGlmICggcG9zdEZpbmRlciAmJiAhcG9zdEZpbmRlclsgZXhwYW5kbyBdICkge1xuXHRcdHBvc3RGaW5kZXIgPSBzZXRNYXRjaGVyKCBwb3N0RmluZGVyLCBwb3N0U2VsZWN0b3IgKTtcblx0fVxuXHRyZXR1cm4gbWFya0Z1bmN0aW9uKGZ1bmN0aW9uKCBzZWVkLCByZXN1bHRzLCBjb250ZXh0LCB4bWwgKSB7XG5cdFx0dmFyIHRlbXAsIGksIGVsZW0sXG5cdFx0XHRwcmVNYXAgPSBbXSxcblx0XHRcdHBvc3RNYXAgPSBbXSxcblx0XHRcdHByZWV4aXN0aW5nID0gcmVzdWx0cy5sZW5ndGgsXG5cblx0XHRcdC8vIEdldCBpbml0aWFsIGVsZW1lbnRzIGZyb20gc2VlZCBvciBjb250ZXh0XG5cdFx0XHRlbGVtcyA9IHNlZWQgfHwgbXVsdGlwbGVDb250ZXh0cyggc2VsZWN0b3IgfHwgXCIqXCIsIGNvbnRleHQubm9kZVR5cGUgPyBbIGNvbnRleHQgXSA6IGNvbnRleHQsIFtdICksXG5cblx0XHRcdC8vIFByZWZpbHRlciB0byBnZXQgbWF0Y2hlciBpbnB1dCwgcHJlc2VydmluZyBhIG1hcCBmb3Igc2VlZC1yZXN1bHRzIHN5bmNocm9uaXphdGlvblxuXHRcdFx0bWF0Y2hlckluID0gcHJlRmlsdGVyICYmICggc2VlZCB8fCAhc2VsZWN0b3IgKSA/XG5cdFx0XHRcdGNvbmRlbnNlKCBlbGVtcywgcHJlTWFwLCBwcmVGaWx0ZXIsIGNvbnRleHQsIHhtbCApIDpcblx0XHRcdFx0ZWxlbXMsXG5cblx0XHRcdG1hdGNoZXJPdXQgPSBtYXRjaGVyID9cblx0XHRcdFx0Ly8gSWYgd2UgaGF2ZSBhIHBvc3RGaW5kZXIsIG9yIGZpbHRlcmVkIHNlZWQsIG9yIG5vbi1zZWVkIHBvc3RGaWx0ZXIgb3IgcHJlZXhpc3RpbmcgcmVzdWx0cyxcblx0XHRcdFx0cG9zdEZpbmRlciB8fCAoIHNlZWQgPyBwcmVGaWx0ZXIgOiBwcmVleGlzdGluZyB8fCBwb3N0RmlsdGVyICkgP1xuXG5cdFx0XHRcdFx0Ly8gLi4uaW50ZXJtZWRpYXRlIHByb2Nlc3NpbmcgaXMgbmVjZXNzYXJ5XG5cdFx0XHRcdFx0W10gOlxuXG5cdFx0XHRcdFx0Ly8gLi4ub3RoZXJ3aXNlIHVzZSByZXN1bHRzIGRpcmVjdGx5XG5cdFx0XHRcdFx0cmVzdWx0cyA6XG5cdFx0XHRcdG1hdGNoZXJJbjtcblxuXHRcdC8vIEZpbmQgcHJpbWFyeSBtYXRjaGVzXG5cdFx0aWYgKCBtYXRjaGVyICkge1xuXHRcdFx0bWF0Y2hlciggbWF0Y2hlckluLCBtYXRjaGVyT3V0LCBjb250ZXh0LCB4bWwgKTtcblx0XHR9XG5cblx0XHQvLyBBcHBseSBwb3N0RmlsdGVyXG5cdFx0aWYgKCBwb3N0RmlsdGVyICkge1xuXHRcdFx0dGVtcCA9IGNvbmRlbnNlKCBtYXRjaGVyT3V0LCBwb3N0TWFwICk7XG5cdFx0XHRwb3N0RmlsdGVyKCB0ZW1wLCBbXSwgY29udGV4dCwgeG1sICk7XG5cblx0XHRcdC8vIFVuLW1hdGNoIGZhaWxpbmcgZWxlbWVudHMgYnkgbW92aW5nIHRoZW0gYmFjayB0byBtYXRjaGVySW5cblx0XHRcdGkgPSB0ZW1wLmxlbmd0aDtcblx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRpZiAoIChlbGVtID0gdGVtcFtpXSkgKSB7XG5cdFx0XHRcdFx0bWF0Y2hlck91dFsgcG9zdE1hcFtpXSBdID0gIShtYXRjaGVySW5bIHBvc3RNYXBbaV0gXSA9IGVsZW0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKCBzZWVkICkge1xuXHRcdFx0aWYgKCBwb3N0RmluZGVyIHx8IHByZUZpbHRlciApIHtcblx0XHRcdFx0aWYgKCBwb3N0RmluZGVyICkge1xuXHRcdFx0XHRcdC8vIEdldCB0aGUgZmluYWwgbWF0Y2hlck91dCBieSBjb25kZW5zaW5nIHRoaXMgaW50ZXJtZWRpYXRlIGludG8gcG9zdEZpbmRlciBjb250ZXh0c1xuXHRcdFx0XHRcdHRlbXAgPSBbXTtcblx0XHRcdFx0XHRpID0gbWF0Y2hlck91dC5sZW5ndGg7XG5cdFx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdFx0XHRpZiAoIChlbGVtID0gbWF0Y2hlck91dFtpXSkgKSB7XG5cdFx0XHRcdFx0XHRcdC8vIFJlc3RvcmUgbWF0Y2hlckluIHNpbmNlIGVsZW0gaXMgbm90IHlldCBhIGZpbmFsIG1hdGNoXG5cdFx0XHRcdFx0XHRcdHRlbXAucHVzaCggKG1hdGNoZXJJbltpXSA9IGVsZW0pICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHBvc3RGaW5kZXIoIG51bGwsIChtYXRjaGVyT3V0ID0gW10pLCB0ZW1wLCB4bWwgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIE1vdmUgbWF0Y2hlZCBlbGVtZW50cyBmcm9tIHNlZWQgdG8gcmVzdWx0cyB0byBrZWVwIHRoZW0gc3luY2hyb25pemVkXG5cdFx0XHRcdGkgPSBtYXRjaGVyT3V0Lmxlbmd0aDtcblx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdFx0aWYgKCAoZWxlbSA9IG1hdGNoZXJPdXRbaV0pICYmXG5cdFx0XHRcdFx0XHQodGVtcCA9IHBvc3RGaW5kZXIgPyBpbmRleE9mKCBzZWVkLCBlbGVtICkgOiBwcmVNYXBbaV0pID4gLTEgKSB7XG5cblx0XHRcdFx0XHRcdHNlZWRbdGVtcF0gPSAhKHJlc3VsdHNbdGVtcF0gPSBlbGVtKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdC8vIEFkZCBlbGVtZW50cyB0byByZXN1bHRzLCB0aHJvdWdoIHBvc3RGaW5kZXIgaWYgZGVmaW5lZFxuXHRcdH0gZWxzZSB7XG5cdFx0XHRtYXRjaGVyT3V0ID0gY29uZGVuc2UoXG5cdFx0XHRcdG1hdGNoZXJPdXQgPT09IHJlc3VsdHMgP1xuXHRcdFx0XHRcdG1hdGNoZXJPdXQuc3BsaWNlKCBwcmVleGlzdGluZywgbWF0Y2hlck91dC5sZW5ndGggKSA6XG5cdFx0XHRcdFx0bWF0Y2hlck91dFxuXHRcdFx0KTtcblx0XHRcdGlmICggcG9zdEZpbmRlciApIHtcblx0XHRcdFx0cG9zdEZpbmRlciggbnVsbCwgcmVzdWx0cywgbWF0Y2hlck91dCwgeG1sICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRwdXNoLmFwcGx5KCByZXN1bHRzLCBtYXRjaGVyT3V0ICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9KTtcbn1cblxuZnVuY3Rpb24gbWF0Y2hlckZyb21Ub2tlbnMoIHRva2VucyApIHtcblx0dmFyIGNoZWNrQ29udGV4dCwgbWF0Y2hlciwgaixcblx0XHRsZW4gPSB0b2tlbnMubGVuZ3RoLFxuXHRcdGxlYWRpbmdSZWxhdGl2ZSA9IEV4cHIucmVsYXRpdmVbIHRva2Vuc1swXS50eXBlIF0sXG5cdFx0aW1wbGljaXRSZWxhdGl2ZSA9IGxlYWRpbmdSZWxhdGl2ZSB8fCBFeHByLnJlbGF0aXZlW1wiIFwiXSxcblx0XHRpID0gbGVhZGluZ1JlbGF0aXZlID8gMSA6IDAsXG5cblx0XHQvLyBUaGUgZm91bmRhdGlvbmFsIG1hdGNoZXIgZW5zdXJlcyB0aGF0IGVsZW1lbnRzIGFyZSByZWFjaGFibGUgZnJvbSB0b3AtbGV2ZWwgY29udGV4dChzKVxuXHRcdG1hdGNoQ29udGV4dCA9IGFkZENvbWJpbmF0b3IoIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIGVsZW0gPT09IGNoZWNrQ29udGV4dDtcblx0XHR9LCBpbXBsaWNpdFJlbGF0aXZlLCB0cnVlICksXG5cdFx0bWF0Y2hBbnlDb250ZXh0ID0gYWRkQ29tYmluYXRvciggZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gaW5kZXhPZiggY2hlY2tDb250ZXh0LCBlbGVtICkgPiAtMTtcblx0XHR9LCBpbXBsaWNpdFJlbGF0aXZlLCB0cnVlICksXG5cdFx0bWF0Y2hlcnMgPSBbIGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XG5cdFx0XHR2YXIgcmV0ID0gKCAhbGVhZGluZ1JlbGF0aXZlICYmICggeG1sIHx8IGNvbnRleHQgIT09IG91dGVybW9zdENvbnRleHQgKSApIHx8IChcblx0XHRcdFx0KGNoZWNrQ29udGV4dCA9IGNvbnRleHQpLm5vZGVUeXBlID9cblx0XHRcdFx0XHRtYXRjaENvbnRleHQoIGVsZW0sIGNvbnRleHQsIHhtbCApIDpcblx0XHRcdFx0XHRtYXRjaEFueUNvbnRleHQoIGVsZW0sIGNvbnRleHQsIHhtbCApICk7XG5cdFx0XHQvLyBBdm9pZCBoYW5naW5nIG9udG8gZWxlbWVudCAoaXNzdWUgIzI5OSlcblx0XHRcdGNoZWNrQ29udGV4dCA9IG51bGw7XG5cdFx0XHRyZXR1cm4gcmV0O1xuXHRcdH0gXTtcblxuXHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRpZiAoIChtYXRjaGVyID0gRXhwci5yZWxhdGl2ZVsgdG9rZW5zW2ldLnR5cGUgXSkgKSB7XG5cdFx0XHRtYXRjaGVycyA9IFsgYWRkQ29tYmluYXRvcihlbGVtZW50TWF0Y2hlciggbWF0Y2hlcnMgKSwgbWF0Y2hlcikgXTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0bWF0Y2hlciA9IEV4cHIuZmlsdGVyWyB0b2tlbnNbaV0udHlwZSBdLmFwcGx5KCBudWxsLCB0b2tlbnNbaV0ubWF0Y2hlcyApO1xuXG5cdFx0XHQvLyBSZXR1cm4gc3BlY2lhbCB1cG9uIHNlZWluZyBhIHBvc2l0aW9uYWwgbWF0Y2hlclxuXHRcdFx0aWYgKCBtYXRjaGVyWyBleHBhbmRvIF0gKSB7XG5cdFx0XHRcdC8vIEZpbmQgdGhlIG5leHQgcmVsYXRpdmUgb3BlcmF0b3IgKGlmIGFueSkgZm9yIHByb3BlciBoYW5kbGluZ1xuXHRcdFx0XHRqID0gKytpO1xuXHRcdFx0XHRmb3IgKCA7IGogPCBsZW47IGorKyApIHtcblx0XHRcdFx0XHRpZiAoIEV4cHIucmVsYXRpdmVbIHRva2Vuc1tqXS50eXBlIF0gKSB7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHNldE1hdGNoZXIoXG5cdFx0XHRcdFx0aSA+IDEgJiYgZWxlbWVudE1hdGNoZXIoIG1hdGNoZXJzICksXG5cdFx0XHRcdFx0aSA+IDEgJiYgdG9TZWxlY3Rvcihcblx0XHRcdFx0XHRcdC8vIElmIHRoZSBwcmVjZWRpbmcgdG9rZW4gd2FzIGEgZGVzY2VuZGFudCBjb21iaW5hdG9yLCBpbnNlcnQgYW4gaW1wbGljaXQgYW55LWVsZW1lbnQgYCpgXG5cdFx0XHRcdFx0XHR0b2tlbnMuc2xpY2UoIDAsIGkgLSAxICkuY29uY2F0KHsgdmFsdWU6IHRva2Vuc1sgaSAtIDIgXS50eXBlID09PSBcIiBcIiA/IFwiKlwiIDogXCJcIiB9KVxuXHRcdFx0XHRcdCkucmVwbGFjZSggcnRyaW0sIFwiJDFcIiApLFxuXHRcdFx0XHRcdG1hdGNoZXIsXG5cdFx0XHRcdFx0aSA8IGogJiYgbWF0Y2hlckZyb21Ub2tlbnMoIHRva2Vucy5zbGljZSggaSwgaiApICksXG5cdFx0XHRcdFx0aiA8IGxlbiAmJiBtYXRjaGVyRnJvbVRva2VucyggKHRva2VucyA9IHRva2Vucy5zbGljZSggaiApKSApLFxuXHRcdFx0XHRcdGogPCBsZW4gJiYgdG9TZWxlY3RvciggdG9rZW5zIClcblx0XHRcdFx0KTtcblx0XHRcdH1cblx0XHRcdG1hdGNoZXJzLnB1c2goIG1hdGNoZXIgKTtcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gZWxlbWVudE1hdGNoZXIoIG1hdGNoZXJzICk7XG59XG5cbmZ1bmN0aW9uIG1hdGNoZXJGcm9tR3JvdXBNYXRjaGVycyggZWxlbWVudE1hdGNoZXJzLCBzZXRNYXRjaGVycyApIHtcblx0dmFyIGJ5U2V0ID0gc2V0TWF0Y2hlcnMubGVuZ3RoID4gMCxcblx0XHRieUVsZW1lbnQgPSBlbGVtZW50TWF0Y2hlcnMubGVuZ3RoID4gMCxcblx0XHRzdXBlck1hdGNoZXIgPSBmdW5jdGlvbiggc2VlZCwgY29udGV4dCwgeG1sLCByZXN1bHRzLCBvdXRlcm1vc3QgKSB7XG5cdFx0XHR2YXIgZWxlbSwgaiwgbWF0Y2hlcixcblx0XHRcdFx0bWF0Y2hlZENvdW50ID0gMCxcblx0XHRcdFx0aSA9IFwiMFwiLFxuXHRcdFx0XHR1bm1hdGNoZWQgPSBzZWVkICYmIFtdLFxuXHRcdFx0XHRzZXRNYXRjaGVkID0gW10sXG5cdFx0XHRcdGNvbnRleHRCYWNrdXAgPSBvdXRlcm1vc3RDb250ZXh0LFxuXHRcdFx0XHQvLyBXZSBtdXN0IGFsd2F5cyBoYXZlIGVpdGhlciBzZWVkIGVsZW1lbnRzIG9yIG91dGVybW9zdCBjb250ZXh0XG5cdFx0XHRcdGVsZW1zID0gc2VlZCB8fCBieUVsZW1lbnQgJiYgRXhwci5maW5kW1wiVEFHXCJdKCBcIipcIiwgb3V0ZXJtb3N0ICksXG5cdFx0XHRcdC8vIFVzZSBpbnRlZ2VyIGRpcnJ1bnMgaWZmIHRoaXMgaXMgdGhlIG91dGVybW9zdCBtYXRjaGVyXG5cdFx0XHRcdGRpcnJ1bnNVbmlxdWUgPSAoZGlycnVucyArPSBjb250ZXh0QmFja3VwID09IG51bGwgPyAxIDogTWF0aC5yYW5kb20oKSB8fCAwLjEpLFxuXHRcdFx0XHRsZW4gPSBlbGVtcy5sZW5ndGg7XG5cblx0XHRcdGlmICggb3V0ZXJtb3N0ICkge1xuXHRcdFx0XHRvdXRlcm1vc3RDb250ZXh0ID0gY29udGV4dCAhPT0gZG9jdW1lbnQgJiYgY29udGV4dDtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQWRkIGVsZW1lbnRzIHBhc3NpbmcgZWxlbWVudE1hdGNoZXJzIGRpcmVjdGx5IHRvIHJlc3VsdHNcblx0XHRcdC8vIEtlZXAgYGlgIGEgc3RyaW5nIGlmIHRoZXJlIGFyZSBubyBlbGVtZW50cyBzbyBgbWF0Y2hlZENvdW50YCB3aWxsIGJlIFwiMDBcIiBiZWxvd1xuXHRcdFx0Ly8gU3VwcG9ydDogSUU8OSwgU2FmYXJpXG5cdFx0XHQvLyBUb2xlcmF0ZSBOb2RlTGlzdCBwcm9wZXJ0aWVzIChJRTogXCJsZW5ndGhcIjsgU2FmYXJpOiA8bnVtYmVyPikgbWF0Y2hpbmcgZWxlbWVudHMgYnkgaWRcblx0XHRcdGZvciAoIDsgaSAhPT0gbGVuICYmIChlbGVtID0gZWxlbXNbaV0pICE9IG51bGw7IGkrKyApIHtcblx0XHRcdFx0aWYgKCBieUVsZW1lbnQgJiYgZWxlbSApIHtcblx0XHRcdFx0XHRqID0gMDtcblx0XHRcdFx0XHR3aGlsZSAoIChtYXRjaGVyID0gZWxlbWVudE1hdGNoZXJzW2orK10pICkge1xuXHRcdFx0XHRcdFx0aWYgKCBtYXRjaGVyKCBlbGVtLCBjb250ZXh0LCB4bWwgKSApIHtcblx0XHRcdFx0XHRcdFx0cmVzdWx0cy5wdXNoKCBlbGVtICk7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZiAoIG91dGVybW9zdCApIHtcblx0XHRcdFx0XHRcdGRpcnJ1bnMgPSBkaXJydW5zVW5pcXVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFRyYWNrIHVubWF0Y2hlZCBlbGVtZW50cyBmb3Igc2V0IGZpbHRlcnNcblx0XHRcdFx0aWYgKCBieVNldCApIHtcblx0XHRcdFx0XHQvLyBUaGV5IHdpbGwgaGF2ZSBnb25lIHRocm91Z2ggYWxsIHBvc3NpYmxlIG1hdGNoZXJzXG5cdFx0XHRcdFx0aWYgKCAoZWxlbSA9ICFtYXRjaGVyICYmIGVsZW0pICkge1xuXHRcdFx0XHRcdFx0bWF0Y2hlZENvdW50LS07XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gTGVuZ3RoZW4gdGhlIGFycmF5IGZvciBldmVyeSBlbGVtZW50LCBtYXRjaGVkIG9yIG5vdFxuXHRcdFx0XHRcdGlmICggc2VlZCApIHtcblx0XHRcdFx0XHRcdHVubWF0Y2hlZC5wdXNoKCBlbGVtICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIEFwcGx5IHNldCBmaWx0ZXJzIHRvIHVubWF0Y2hlZCBlbGVtZW50c1xuXHRcdFx0bWF0Y2hlZENvdW50ICs9IGk7XG5cdFx0XHRpZiAoIGJ5U2V0ICYmIGkgIT09IG1hdGNoZWRDb3VudCApIHtcblx0XHRcdFx0aiA9IDA7XG5cdFx0XHRcdHdoaWxlICggKG1hdGNoZXIgPSBzZXRNYXRjaGVyc1tqKytdKSApIHtcblx0XHRcdFx0XHRtYXRjaGVyKCB1bm1hdGNoZWQsIHNldE1hdGNoZWQsIGNvbnRleHQsIHhtbCApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKCBzZWVkICkge1xuXHRcdFx0XHRcdC8vIFJlaW50ZWdyYXRlIGVsZW1lbnQgbWF0Y2hlcyB0byBlbGltaW5hdGUgdGhlIG5lZWQgZm9yIHNvcnRpbmdcblx0XHRcdFx0XHRpZiAoIG1hdGNoZWRDb3VudCA+IDAgKSB7XG5cdFx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0XHRcdFx0aWYgKCAhKHVubWF0Y2hlZFtpXSB8fCBzZXRNYXRjaGVkW2ldKSApIHtcblx0XHRcdFx0XHRcdFx0XHRzZXRNYXRjaGVkW2ldID0gcG9wLmNhbGwoIHJlc3VsdHMgKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIERpc2NhcmQgaW5kZXggcGxhY2Vob2xkZXIgdmFsdWVzIHRvIGdldCBvbmx5IGFjdHVhbCBtYXRjaGVzXG5cdFx0XHRcdFx0c2V0TWF0Y2hlZCA9IGNvbmRlbnNlKCBzZXRNYXRjaGVkICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBBZGQgbWF0Y2hlcyB0byByZXN1bHRzXG5cdFx0XHRcdHB1c2guYXBwbHkoIHJlc3VsdHMsIHNldE1hdGNoZWQgKTtcblxuXHRcdFx0XHQvLyBTZWVkbGVzcyBzZXQgbWF0Y2hlcyBzdWNjZWVkaW5nIG11bHRpcGxlIHN1Y2Nlc3NmdWwgbWF0Y2hlcnMgc3RpcHVsYXRlIHNvcnRpbmdcblx0XHRcdFx0aWYgKCBvdXRlcm1vc3QgJiYgIXNlZWQgJiYgc2V0TWF0Y2hlZC5sZW5ndGggPiAwICYmXG5cdFx0XHRcdFx0KCBtYXRjaGVkQ291bnQgKyBzZXRNYXRjaGVycy5sZW5ndGggKSA+IDEgKSB7XG5cblx0XHRcdFx0XHRTaXp6bGUudW5pcXVlU29ydCggcmVzdWx0cyApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIE92ZXJyaWRlIG1hbmlwdWxhdGlvbiBvZiBnbG9iYWxzIGJ5IG5lc3RlZCBtYXRjaGVyc1xuXHRcdFx0aWYgKCBvdXRlcm1vc3QgKSB7XG5cdFx0XHRcdGRpcnJ1bnMgPSBkaXJydW5zVW5pcXVlO1xuXHRcdFx0XHRvdXRlcm1vc3RDb250ZXh0ID0gY29udGV4dEJhY2t1cDtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHVubWF0Y2hlZDtcblx0XHR9O1xuXG5cdHJldHVybiBieVNldCA/XG5cdFx0bWFya0Z1bmN0aW9uKCBzdXBlck1hdGNoZXIgKSA6XG5cdFx0c3VwZXJNYXRjaGVyO1xufVxuXG5jb21waWxlID0gU2l6emxlLmNvbXBpbGUgPSBmdW5jdGlvbiggc2VsZWN0b3IsIG1hdGNoIC8qIEludGVybmFsIFVzZSBPbmx5ICovICkge1xuXHR2YXIgaSxcblx0XHRzZXRNYXRjaGVycyA9IFtdLFxuXHRcdGVsZW1lbnRNYXRjaGVycyA9IFtdLFxuXHRcdGNhY2hlZCA9IGNvbXBpbGVyQ2FjaGVbIHNlbGVjdG9yICsgXCIgXCIgXTtcblxuXHRpZiAoICFjYWNoZWQgKSB7XG5cdFx0Ly8gR2VuZXJhdGUgYSBmdW5jdGlvbiBvZiByZWN1cnNpdmUgZnVuY3Rpb25zIHRoYXQgY2FuIGJlIHVzZWQgdG8gY2hlY2sgZWFjaCBlbGVtZW50XG5cdFx0aWYgKCAhbWF0Y2ggKSB7XG5cdFx0XHRtYXRjaCA9IHRva2VuaXplKCBzZWxlY3RvciApO1xuXHRcdH1cblx0XHRpID0gbWF0Y2gubGVuZ3RoO1xuXHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0Y2FjaGVkID0gbWF0Y2hlckZyb21Ub2tlbnMoIG1hdGNoW2ldICk7XG5cdFx0XHRpZiAoIGNhY2hlZFsgZXhwYW5kbyBdICkge1xuXHRcdFx0XHRzZXRNYXRjaGVycy5wdXNoKCBjYWNoZWQgKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGVsZW1lbnRNYXRjaGVycy5wdXNoKCBjYWNoZWQgKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBDYWNoZSB0aGUgY29tcGlsZWQgZnVuY3Rpb25cblx0XHRjYWNoZWQgPSBjb21waWxlckNhY2hlKCBzZWxlY3RvciwgbWF0Y2hlckZyb21Hcm91cE1hdGNoZXJzKCBlbGVtZW50TWF0Y2hlcnMsIHNldE1hdGNoZXJzICkgKTtcblxuXHRcdC8vIFNhdmUgc2VsZWN0b3IgYW5kIHRva2VuaXphdGlvblxuXHRcdGNhY2hlZC5zZWxlY3RvciA9IHNlbGVjdG9yO1xuXHR9XG5cdHJldHVybiBjYWNoZWQ7XG59O1xuXG4vKipcbiAqIEEgbG93LWxldmVsIHNlbGVjdGlvbiBmdW5jdGlvbiB0aGF0IHdvcmtzIHdpdGggU2l6emxlJ3MgY29tcGlsZWRcbiAqICBzZWxlY3RvciBmdW5jdGlvbnNcbiAqIEBwYXJhbSB7U3RyaW5nfEZ1bmN0aW9ufSBzZWxlY3RvciBBIHNlbGVjdG9yIG9yIGEgcHJlLWNvbXBpbGVkXG4gKiAgc2VsZWN0b3IgZnVuY3Rpb24gYnVpbHQgd2l0aCBTaXp6bGUuY29tcGlsZVxuICogQHBhcmFtIHtFbGVtZW50fSBjb250ZXh0XG4gKiBAcGFyYW0ge0FycmF5fSBbcmVzdWx0c11cbiAqIEBwYXJhbSB7QXJyYXl9IFtzZWVkXSBBIHNldCBvZiBlbGVtZW50cyB0byBtYXRjaCBhZ2FpbnN0XG4gKi9cbnNlbGVjdCA9IFNpenpsZS5zZWxlY3QgPSBmdW5jdGlvbiggc2VsZWN0b3IsIGNvbnRleHQsIHJlc3VsdHMsIHNlZWQgKSB7XG5cdHZhciBpLCB0b2tlbnMsIHRva2VuLCB0eXBlLCBmaW5kLFxuXHRcdGNvbXBpbGVkID0gdHlwZW9mIHNlbGVjdG9yID09PSBcImZ1bmN0aW9uXCIgJiYgc2VsZWN0b3IsXG5cdFx0bWF0Y2ggPSAhc2VlZCAmJiB0b2tlbml6ZSggKHNlbGVjdG9yID0gY29tcGlsZWQuc2VsZWN0b3IgfHwgc2VsZWN0b3IpICk7XG5cblx0cmVzdWx0cyA9IHJlc3VsdHMgfHwgW107XG5cblx0Ly8gVHJ5IHRvIG1pbmltaXplIG9wZXJhdGlvbnMgaWYgdGhlcmUgaXMgbm8gc2VlZCBhbmQgb25seSBvbmUgZ3JvdXBcblx0aWYgKCBtYXRjaC5sZW5ndGggPT09IDEgKSB7XG5cblx0XHQvLyBUYWtlIGEgc2hvcnRjdXQgYW5kIHNldCB0aGUgY29udGV4dCBpZiB0aGUgcm9vdCBzZWxlY3RvciBpcyBhbiBJRFxuXHRcdHRva2VucyA9IG1hdGNoWzBdID0gbWF0Y2hbMF0uc2xpY2UoIDAgKTtcblx0XHRpZiAoIHRva2Vucy5sZW5ndGggPiAyICYmICh0b2tlbiA9IHRva2Vuc1swXSkudHlwZSA9PT0gXCJJRFwiICYmXG5cdFx0XHRcdHN1cHBvcnQuZ2V0QnlJZCAmJiBjb250ZXh0Lm5vZGVUeXBlID09PSA5ICYmIGRvY3VtZW50SXNIVE1MICYmXG5cdFx0XHRcdEV4cHIucmVsYXRpdmVbIHRva2Vuc1sxXS50eXBlIF0gKSB7XG5cblx0XHRcdGNvbnRleHQgPSAoIEV4cHIuZmluZFtcIklEXCJdKCB0b2tlbi5tYXRjaGVzWzBdLnJlcGxhY2UocnVuZXNjYXBlLCBmdW5lc2NhcGUpLCBjb250ZXh0ICkgfHwgW10gKVswXTtcblx0XHRcdGlmICggIWNvbnRleHQgKSB7XG5cdFx0XHRcdHJldHVybiByZXN1bHRzO1xuXG5cdFx0XHQvLyBQcmVjb21waWxlZCBtYXRjaGVycyB3aWxsIHN0aWxsIHZlcmlmeSBhbmNlc3RyeSwgc28gc3RlcCB1cCBhIGxldmVsXG5cdFx0XHR9IGVsc2UgaWYgKCBjb21waWxlZCApIHtcblx0XHRcdFx0Y29udGV4dCA9IGNvbnRleHQucGFyZW50Tm9kZTtcblx0XHRcdH1cblxuXHRcdFx0c2VsZWN0b3IgPSBzZWxlY3Rvci5zbGljZSggdG9rZW5zLnNoaWZ0KCkudmFsdWUubGVuZ3RoICk7XG5cdFx0fVxuXG5cdFx0Ly8gRmV0Y2ggYSBzZWVkIHNldCBmb3IgcmlnaHQtdG8tbGVmdCBtYXRjaGluZ1xuXHRcdGkgPSBtYXRjaEV4cHJbXCJuZWVkc0NvbnRleHRcIl0udGVzdCggc2VsZWN0b3IgKSA/IDAgOiB0b2tlbnMubGVuZ3RoO1xuXHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0dG9rZW4gPSB0b2tlbnNbaV07XG5cblx0XHRcdC8vIEFib3J0IGlmIHdlIGhpdCBhIGNvbWJpbmF0b3Jcblx0XHRcdGlmICggRXhwci5yZWxhdGl2ZVsgKHR5cGUgPSB0b2tlbi50eXBlKSBdICkge1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHRcdGlmICggKGZpbmQgPSBFeHByLmZpbmRbIHR5cGUgXSkgKSB7XG5cdFx0XHRcdC8vIFNlYXJjaCwgZXhwYW5kaW5nIGNvbnRleHQgZm9yIGxlYWRpbmcgc2libGluZyBjb21iaW5hdG9yc1xuXHRcdFx0XHRpZiAoIChzZWVkID0gZmluZChcblx0XHRcdFx0XHR0b2tlbi5tYXRjaGVzWzBdLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICksXG5cdFx0XHRcdFx0cnNpYmxpbmcudGVzdCggdG9rZW5zWzBdLnR5cGUgKSAmJiB0ZXN0Q29udGV4dCggY29udGV4dC5wYXJlbnROb2RlICkgfHwgY29udGV4dFxuXHRcdFx0XHQpKSApIHtcblxuXHRcdFx0XHRcdC8vIElmIHNlZWQgaXMgZW1wdHkgb3Igbm8gdG9rZW5zIHJlbWFpbiwgd2UgY2FuIHJldHVybiBlYXJseVxuXHRcdFx0XHRcdHRva2Vucy5zcGxpY2UoIGksIDEgKTtcblx0XHRcdFx0XHRzZWxlY3RvciA9IHNlZWQubGVuZ3RoICYmIHRvU2VsZWN0b3IoIHRva2VucyApO1xuXHRcdFx0XHRcdGlmICggIXNlbGVjdG9yICkge1xuXHRcdFx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cywgc2VlZCApO1xuXHRcdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBDb21waWxlIGFuZCBleGVjdXRlIGEgZmlsdGVyaW5nIGZ1bmN0aW9uIGlmIG9uZSBpcyBub3QgcHJvdmlkZWRcblx0Ly8gUHJvdmlkZSBgbWF0Y2hgIHRvIGF2b2lkIHJldG9rZW5pemF0aW9uIGlmIHdlIG1vZGlmaWVkIHRoZSBzZWxlY3RvciBhYm92ZVxuXHQoIGNvbXBpbGVkIHx8IGNvbXBpbGUoIHNlbGVjdG9yLCBtYXRjaCApICkoXG5cdFx0c2VlZCxcblx0XHRjb250ZXh0LFxuXHRcdCFkb2N1bWVudElzSFRNTCxcblx0XHRyZXN1bHRzLFxuXHRcdHJzaWJsaW5nLnRlc3QoIHNlbGVjdG9yICkgJiYgdGVzdENvbnRleHQoIGNvbnRleHQucGFyZW50Tm9kZSApIHx8IGNvbnRleHRcblx0KTtcblx0cmV0dXJuIHJlc3VsdHM7XG59O1xuXG4vLyBPbmUtdGltZSBhc3NpZ25tZW50c1xuXG4vLyBTb3J0IHN0YWJpbGl0eVxuc3VwcG9ydC5zb3J0U3RhYmxlID0gZXhwYW5kby5zcGxpdChcIlwiKS5zb3J0KCBzb3J0T3JkZXIgKS5qb2luKFwiXCIpID09PSBleHBhbmRvO1xuXG4vLyBTdXBwb3J0OiBDaHJvbWUgMTQtMzUrXG4vLyBBbHdheXMgYXNzdW1lIGR1cGxpY2F0ZXMgaWYgdGhleSBhcmVuJ3QgcGFzc2VkIHRvIHRoZSBjb21wYXJpc29uIGZ1bmN0aW9uXG5zdXBwb3J0LmRldGVjdER1cGxpY2F0ZXMgPSAhIWhhc0R1cGxpY2F0ZTtcblxuLy8gSW5pdGlhbGl6ZSBhZ2FpbnN0IHRoZSBkZWZhdWx0IGRvY3VtZW50XG5zZXREb2N1bWVudCgpO1xuXG4vLyBTdXBwb3J0OiBXZWJraXQ8NTM3LjMyIC0gU2FmYXJpIDYuMC4zL0Nocm9tZSAyNSAoZml4ZWQgaW4gQ2hyb21lIDI3KVxuLy8gRGV0YWNoZWQgbm9kZXMgY29uZm91bmRpbmdseSBmb2xsb3cgKmVhY2ggb3RoZXIqXG5zdXBwb3J0LnNvcnREZXRhY2hlZCA9IGFzc2VydChmdW5jdGlvbiggZGl2MSApIHtcblx0Ly8gU2hvdWxkIHJldHVybiAxLCBidXQgcmV0dXJucyA0IChmb2xsb3dpbmcpXG5cdHJldHVybiBkaXYxLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpICkgJiAxO1xufSk7XG5cbi8vIFN1cHBvcnQ6IElFPDhcbi8vIFByZXZlbnQgYXR0cmlidXRlL3Byb3BlcnR5IFwiaW50ZXJwb2xhdGlvblwiXG4vLyBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvbXM1MzY0MjklMjhWUy44NSUyOS5hc3B4XG5pZiAoICFhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcblx0ZGl2LmlubmVySFRNTCA9IFwiPGEgaHJlZj0nIyc+PC9hPlwiO1xuXHRyZXR1cm4gZGl2LmZpcnN0Q2hpbGQuZ2V0QXR0cmlidXRlKFwiaHJlZlwiKSA9PT0gXCIjXCIgO1xufSkgKSB7XG5cdGFkZEhhbmRsZSggXCJ0eXBlfGhyZWZ8aGVpZ2h0fHdpZHRoXCIsIGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBpc1hNTCApIHtcblx0XHRpZiAoICFpc1hNTCApIHtcblx0XHRcdHJldHVybiBlbGVtLmdldEF0dHJpYnV0ZSggbmFtZSwgbmFtZS50b0xvd2VyQ2FzZSgpID09PSBcInR5cGVcIiA/IDEgOiAyICk7XG5cdFx0fVxuXHR9KTtcbn1cblxuLy8gU3VwcG9ydDogSUU8OVxuLy8gVXNlIGRlZmF1bHRWYWx1ZSBpbiBwbGFjZSBvZiBnZXRBdHRyaWJ1dGUoXCJ2YWx1ZVwiKVxuaWYgKCAhc3VwcG9ydC5hdHRyaWJ1dGVzIHx8ICFhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcblx0ZGl2LmlubmVySFRNTCA9IFwiPGlucHV0Lz5cIjtcblx0ZGl2LmZpcnN0Q2hpbGQuc2V0QXR0cmlidXRlKCBcInZhbHVlXCIsIFwiXCIgKTtcblx0cmV0dXJuIGRpdi5maXJzdENoaWxkLmdldEF0dHJpYnV0ZSggXCJ2YWx1ZVwiICkgPT09IFwiXCI7XG59KSApIHtcblx0YWRkSGFuZGxlKCBcInZhbHVlXCIsIGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBpc1hNTCApIHtcblx0XHRpZiAoICFpc1hNTCAmJiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IFwiaW5wdXRcIiApIHtcblx0XHRcdHJldHVybiBlbGVtLmRlZmF1bHRWYWx1ZTtcblx0XHR9XG5cdH0pO1xufVxuXG4vLyBTdXBwb3J0OiBJRTw5XG4vLyBVc2UgZ2V0QXR0cmlidXRlTm9kZSB0byBmZXRjaCBib29sZWFucyB3aGVuIGdldEF0dHJpYnV0ZSBsaWVzXG5pZiAoICFhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcblx0cmV0dXJuIGRpdi5nZXRBdHRyaWJ1dGUoXCJkaXNhYmxlZFwiKSA9PSBudWxsO1xufSkgKSB7XG5cdGFkZEhhbmRsZSggYm9vbGVhbnMsIGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBpc1hNTCApIHtcblx0XHR2YXIgdmFsO1xuXHRcdGlmICggIWlzWE1MICkge1xuXHRcdFx0cmV0dXJuIGVsZW1bIG5hbWUgXSA9PT0gdHJ1ZSA/IG5hbWUudG9Mb3dlckNhc2UoKSA6XG5cdFx0XHRcdFx0KHZhbCA9IGVsZW0uZ2V0QXR0cmlidXRlTm9kZSggbmFtZSApKSAmJiB2YWwuc3BlY2lmaWVkID9cblx0XHRcdFx0XHR2YWwudmFsdWUgOlxuXHRcdFx0XHRudWxsO1xuXHRcdH1cblx0fSk7XG59XG5cbnJldHVybiBTaXp6bGU7XG5cbn0pKCB3aW5kb3cgKTtcblxuXG5cbmpRdWVyeS5maW5kID0gU2l6emxlO1xualF1ZXJ5LmV4cHIgPSBTaXp6bGUuc2VsZWN0b3JzO1xualF1ZXJ5LmV4cHJbXCI6XCJdID0galF1ZXJ5LmV4cHIucHNldWRvcztcbmpRdWVyeS51bmlxdWUgPSBTaXp6bGUudW5pcXVlU29ydDtcbmpRdWVyeS50ZXh0ID0gU2l6emxlLmdldFRleHQ7XG5qUXVlcnkuaXNYTUxEb2MgPSBTaXp6bGUuaXNYTUw7XG5qUXVlcnkuY29udGFpbnMgPSBTaXp6bGUuY29udGFpbnM7XG5cblxuXG52YXIgcm5lZWRzQ29udGV4dCA9IGpRdWVyeS5leHByLm1hdGNoLm5lZWRzQ29udGV4dDtcblxudmFyIHJzaW5nbGVUYWcgPSAoL148KFxcdyspXFxzKlxcLz8+KD86PFxcL1xcMT58KSQvKTtcblxuXG5cbnZhciByaXNTaW1wbGUgPSAvXi5bXjojXFxbXFwuLF0qJC87XG5cbi8vIEltcGxlbWVudCB0aGUgaWRlbnRpY2FsIGZ1bmN0aW9uYWxpdHkgZm9yIGZpbHRlciBhbmQgbm90XG5mdW5jdGlvbiB3aW5ub3coIGVsZW1lbnRzLCBxdWFsaWZpZXIsIG5vdCApIHtcblx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggcXVhbGlmaWVyICkgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5ncmVwKCBlbGVtZW50cywgZnVuY3Rpb24oIGVsZW0sIGkgKSB7XG5cdFx0XHQvKiBqc2hpbnQgLVcwMTggKi9cblx0XHRcdHJldHVybiAhIXF1YWxpZmllci5jYWxsKCBlbGVtLCBpLCBlbGVtICkgIT09IG5vdDtcblx0XHR9KTtcblxuXHR9XG5cblx0aWYgKCBxdWFsaWZpZXIubm9kZVR5cGUgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5ncmVwKCBlbGVtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gKCBlbGVtID09PSBxdWFsaWZpZXIgKSAhPT0gbm90O1xuXHRcdH0pO1xuXG5cdH1cblxuXHRpZiAoIHR5cGVvZiBxdWFsaWZpZXIgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0aWYgKCByaXNTaW1wbGUudGVzdCggcXVhbGlmaWVyICkgKSB7XG5cdFx0XHRyZXR1cm4galF1ZXJ5LmZpbHRlciggcXVhbGlmaWVyLCBlbGVtZW50cywgbm90ICk7XG5cdFx0fVxuXG5cdFx0cXVhbGlmaWVyID0galF1ZXJ5LmZpbHRlciggcXVhbGlmaWVyLCBlbGVtZW50cyApO1xuXHR9XG5cblx0cmV0dXJuIGpRdWVyeS5ncmVwKCBlbGVtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuICggaW5kZXhPZi5jYWxsKCBxdWFsaWZpZXIsIGVsZW0gKSA+PSAwICkgIT09IG5vdDtcblx0fSk7XG59XG5cbmpRdWVyeS5maWx0ZXIgPSBmdW5jdGlvbiggZXhwciwgZWxlbXMsIG5vdCApIHtcblx0dmFyIGVsZW0gPSBlbGVtc1sgMCBdO1xuXG5cdGlmICggbm90ICkge1xuXHRcdGV4cHIgPSBcIjpub3QoXCIgKyBleHByICsgXCIpXCI7XG5cdH1cblxuXHRyZXR1cm4gZWxlbXMubGVuZ3RoID09PSAxICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgP1xuXHRcdGpRdWVyeS5maW5kLm1hdGNoZXNTZWxlY3RvciggZWxlbSwgZXhwciApID8gWyBlbGVtIF0gOiBbXSA6XG5cdFx0alF1ZXJ5LmZpbmQubWF0Y2hlcyggZXhwciwgalF1ZXJ5LmdyZXAoIGVsZW1zLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtLm5vZGVUeXBlID09PSAxO1xuXHRcdH0pKTtcbn07XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHRmaW5kOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0dmFyIGksXG5cdFx0XHRsZW4gPSB0aGlzLmxlbmd0aCxcblx0XHRcdHJldCA9IFtdLFxuXHRcdFx0c2VsZiA9IHRoaXM7XG5cblx0XHRpZiAoIHR5cGVvZiBzZWxlY3RvciAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggalF1ZXJ5KCBzZWxlY3RvciApLmZpbHRlcihmdW5jdGlvbigpIHtcblx0XHRcdFx0Zm9yICggaSA9IDA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdFx0XHRpZiAoIGpRdWVyeS5jb250YWlucyggc2VsZlsgaSBdLCB0aGlzICkgKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0pICk7XG5cdFx0fVxuXG5cdFx0Zm9yICggaSA9IDA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdGpRdWVyeS5maW5kKCBzZWxlY3Rvciwgc2VsZlsgaSBdLCByZXQgKTtcblx0XHR9XG5cblx0XHQvLyBOZWVkZWQgYmVjYXVzZSAkKCBzZWxlY3RvciwgY29udGV4dCApIGJlY29tZXMgJCggY29udGV4dCApLmZpbmQoIHNlbGVjdG9yIClcblx0XHRyZXQgPSB0aGlzLnB1c2hTdGFjayggbGVuID4gMSA/IGpRdWVyeS51bmlxdWUoIHJldCApIDogcmV0ICk7XG5cdFx0cmV0LnNlbGVjdG9yID0gdGhpcy5zZWxlY3RvciA/IHRoaXMuc2VsZWN0b3IgKyBcIiBcIiArIHNlbGVjdG9yIDogc2VsZWN0b3I7XG5cdFx0cmV0dXJuIHJldDtcblx0fSxcblx0ZmlsdGVyOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCB3aW5ub3codGhpcywgc2VsZWN0b3IgfHwgW10sIGZhbHNlKSApO1xuXHR9LFxuXHRub3Q6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIHdpbm5vdyh0aGlzLCBzZWxlY3RvciB8fCBbXSwgdHJ1ZSkgKTtcblx0fSxcblx0aXM6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRyZXR1cm4gISF3aW5ub3coXG5cdFx0XHR0aGlzLFxuXG5cdFx0XHQvLyBJZiB0aGlzIGlzIGEgcG9zaXRpb25hbC9yZWxhdGl2ZSBzZWxlY3RvciwgY2hlY2sgbWVtYmVyc2hpcCBpbiB0aGUgcmV0dXJuZWQgc2V0XG5cdFx0XHQvLyBzbyAkKFwicDpmaXJzdFwiKS5pcyhcInA6bGFzdFwiKSB3b24ndCByZXR1cm4gdHJ1ZSBmb3IgYSBkb2Mgd2l0aCB0d28gXCJwXCIuXG5cdFx0XHR0eXBlb2Ygc2VsZWN0b3IgPT09IFwic3RyaW5nXCIgJiYgcm5lZWRzQ29udGV4dC50ZXN0KCBzZWxlY3RvciApID9cblx0XHRcdFx0alF1ZXJ5KCBzZWxlY3RvciApIDpcblx0XHRcdFx0c2VsZWN0b3IgfHwgW10sXG5cdFx0XHRmYWxzZVxuXHRcdCkubGVuZ3RoO1xuXHR9XG59KTtcblxuXG4vLyBJbml0aWFsaXplIGEgalF1ZXJ5IG9iamVjdFxuXG5cbi8vIEEgY2VudHJhbCByZWZlcmVuY2UgdG8gdGhlIHJvb3QgalF1ZXJ5KGRvY3VtZW50KVxudmFyIHJvb3RqUXVlcnksXG5cblx0Ly8gQSBzaW1wbGUgd2F5IHRvIGNoZWNrIGZvciBIVE1MIHN0cmluZ3Ncblx0Ly8gUHJpb3JpdGl6ZSAjaWQgb3ZlciA8dGFnPiB0byBhdm9pZCBYU1MgdmlhIGxvY2F0aW9uLmhhc2ggKCM5NTIxKVxuXHQvLyBTdHJpY3QgSFRNTCByZWNvZ25pdGlvbiAoIzExMjkwOiBtdXN0IHN0YXJ0IHdpdGggPClcblx0cnF1aWNrRXhwciA9IC9eKD86XFxzKig8W1xcd1xcV10rPilbXj5dKnwjKFtcXHctXSopKSQvLFxuXG5cdGluaXQgPSBqUXVlcnkuZm4uaW5pdCA9IGZ1bmN0aW9uKCBzZWxlY3RvciwgY29udGV4dCApIHtcblx0XHR2YXIgbWF0Y2gsIGVsZW07XG5cblx0XHQvLyBIQU5ETEU6ICQoXCJcIiksICQobnVsbCksICQodW5kZWZpbmVkKSwgJChmYWxzZSlcblx0XHRpZiAoICFzZWxlY3RvciApIHtcblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH1cblxuXHRcdC8vIEhhbmRsZSBIVE1MIHN0cmluZ3Ncblx0XHRpZiAoIHR5cGVvZiBzZWxlY3RvciA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdGlmICggc2VsZWN0b3JbMF0gPT09IFwiPFwiICYmIHNlbGVjdG9yWyBzZWxlY3Rvci5sZW5ndGggLSAxIF0gPT09IFwiPlwiICYmIHNlbGVjdG9yLmxlbmd0aCA+PSAzICkge1xuXHRcdFx0XHQvLyBBc3N1bWUgdGhhdCBzdHJpbmdzIHRoYXQgc3RhcnQgYW5kIGVuZCB3aXRoIDw+IGFyZSBIVE1MIGFuZCBza2lwIHRoZSByZWdleCBjaGVja1xuXHRcdFx0XHRtYXRjaCA9IFsgbnVsbCwgc2VsZWN0b3IsIG51bGwgXTtcblxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0bWF0Y2ggPSBycXVpY2tFeHByLmV4ZWMoIHNlbGVjdG9yICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIE1hdGNoIGh0bWwgb3IgbWFrZSBzdXJlIG5vIGNvbnRleHQgaXMgc3BlY2lmaWVkIGZvciAjaWRcblx0XHRcdGlmICggbWF0Y2ggJiYgKG1hdGNoWzFdIHx8ICFjb250ZXh0KSApIHtcblxuXHRcdFx0XHQvLyBIQU5ETEU6ICQoaHRtbCkgLT4gJChhcnJheSlcblx0XHRcdFx0aWYgKCBtYXRjaFsxXSApIHtcblx0XHRcdFx0XHRjb250ZXh0ID0gY29udGV4dCBpbnN0YW5jZW9mIGpRdWVyeSA/IGNvbnRleHRbMF0gOiBjb250ZXh0O1xuXG5cdFx0XHRcdFx0Ly8gT3B0aW9uIHRvIHJ1biBzY3JpcHRzIGlzIHRydWUgZm9yIGJhY2stY29tcGF0XG5cdFx0XHRcdFx0Ly8gSW50ZW50aW9uYWxseSBsZXQgdGhlIGVycm9yIGJlIHRocm93biBpZiBwYXJzZUhUTUwgaXMgbm90IHByZXNlbnRcblx0XHRcdFx0XHRqUXVlcnkubWVyZ2UoIHRoaXMsIGpRdWVyeS5wYXJzZUhUTUwoXG5cdFx0XHRcdFx0XHRtYXRjaFsxXSxcblx0XHRcdFx0XHRcdGNvbnRleHQgJiYgY29udGV4dC5ub2RlVHlwZSA/IGNvbnRleHQub3duZXJEb2N1bWVudCB8fCBjb250ZXh0IDogZG9jdW1lbnQsXG5cdFx0XHRcdFx0XHR0cnVlXG5cdFx0XHRcdFx0KSApO1xuXG5cdFx0XHRcdFx0Ly8gSEFORExFOiAkKGh0bWwsIHByb3BzKVxuXHRcdFx0XHRcdGlmICggcnNpbmdsZVRhZy50ZXN0KCBtYXRjaFsxXSApICYmIGpRdWVyeS5pc1BsYWluT2JqZWN0KCBjb250ZXh0ICkgKSB7XG5cdFx0XHRcdFx0XHRmb3IgKCBtYXRjaCBpbiBjb250ZXh0ICkge1xuXHRcdFx0XHRcdFx0XHQvLyBQcm9wZXJ0aWVzIG9mIGNvbnRleHQgYXJlIGNhbGxlZCBhcyBtZXRob2RzIGlmIHBvc3NpYmxlXG5cdFx0XHRcdFx0XHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHRoaXNbIG1hdGNoIF0gKSApIHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzWyBtYXRjaCBdKCBjb250ZXh0WyBtYXRjaCBdICk7XG5cblx0XHRcdFx0XHRcdFx0Ly8gLi4uYW5kIG90aGVyd2lzZSBzZXQgYXMgYXR0cmlidXRlc1xuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdHRoaXMuYXR0ciggbWF0Y2gsIGNvbnRleHRbIG1hdGNoIF0gKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXG5cdFx0XHRcdC8vIEhBTkRMRTogJCgjaWQpXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0ZWxlbSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCBtYXRjaFsyXSApO1xuXG5cdFx0XHRcdFx0Ly8gU3VwcG9ydDogQmxhY2tiZXJyeSA0LjZcblx0XHRcdFx0XHQvLyBnRUJJRCByZXR1cm5zIG5vZGVzIG5vIGxvbmdlciBpbiB0aGUgZG9jdW1lbnQgKCM2OTYzKVxuXHRcdFx0XHRcdGlmICggZWxlbSAmJiBlbGVtLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdFx0XHQvLyBJbmplY3QgdGhlIGVsZW1lbnQgZGlyZWN0bHkgaW50byB0aGUgalF1ZXJ5IG9iamVjdFxuXHRcdFx0XHRcdFx0dGhpcy5sZW5ndGggPSAxO1xuXHRcdFx0XHRcdFx0dGhpc1swXSA9IGVsZW07XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0dGhpcy5jb250ZXh0ID0gZG9jdW1lbnQ7XG5cdFx0XHRcdFx0dGhpcy5zZWxlY3RvciA9IHNlbGVjdG9yO1xuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0XHR9XG5cblx0XHRcdC8vIEhBTkRMRTogJChleHByLCAkKC4uLikpXG5cdFx0XHR9IGVsc2UgaWYgKCAhY29udGV4dCB8fCBjb250ZXh0LmpxdWVyeSApIHtcblx0XHRcdFx0cmV0dXJuICggY29udGV4dCB8fCByb290alF1ZXJ5ICkuZmluZCggc2VsZWN0b3IgKTtcblxuXHRcdFx0Ly8gSEFORExFOiAkKGV4cHIsIGNvbnRleHQpXG5cdFx0XHQvLyAod2hpY2ggaXMganVzdCBlcXVpdmFsZW50IHRvOiAkKGNvbnRleHQpLmZpbmQoZXhwcilcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHJldHVybiB0aGlzLmNvbnN0cnVjdG9yKCBjb250ZXh0ICkuZmluZCggc2VsZWN0b3IgKTtcblx0XHRcdH1cblxuXHRcdC8vIEhBTkRMRTogJChET01FbGVtZW50KVxuXHRcdH0gZWxzZSBpZiAoIHNlbGVjdG9yLm5vZGVUeXBlICkge1xuXHRcdFx0dGhpcy5jb250ZXh0ID0gdGhpc1swXSA9IHNlbGVjdG9yO1xuXHRcdFx0dGhpcy5sZW5ndGggPSAxO1xuXHRcdFx0cmV0dXJuIHRoaXM7XG5cblx0XHQvLyBIQU5ETEU6ICQoZnVuY3Rpb24pXG5cdFx0Ly8gU2hvcnRjdXQgZm9yIGRvY3VtZW50IHJlYWR5XG5cdFx0fSBlbHNlIGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHNlbGVjdG9yICkgKSB7XG5cdFx0XHRyZXR1cm4gdHlwZW9mIHJvb3RqUXVlcnkucmVhZHkgIT09IFwidW5kZWZpbmVkXCIgP1xuXHRcdFx0XHRyb290alF1ZXJ5LnJlYWR5KCBzZWxlY3RvciApIDpcblx0XHRcdFx0Ly8gRXhlY3V0ZSBpbW1lZGlhdGVseSBpZiByZWFkeSBpcyBub3QgcHJlc2VudFxuXHRcdFx0XHRzZWxlY3RvciggalF1ZXJ5ICk7XG5cdFx0fVxuXG5cdFx0aWYgKCBzZWxlY3Rvci5zZWxlY3RvciAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0dGhpcy5zZWxlY3RvciA9IHNlbGVjdG9yLnNlbGVjdG9yO1xuXHRcdFx0dGhpcy5jb250ZXh0ID0gc2VsZWN0b3IuY29udGV4dDtcblx0XHR9XG5cblx0XHRyZXR1cm4galF1ZXJ5Lm1ha2VBcnJheSggc2VsZWN0b3IsIHRoaXMgKTtcblx0fTtcblxuLy8gR2l2ZSB0aGUgaW5pdCBmdW5jdGlvbiB0aGUgalF1ZXJ5IHByb3RvdHlwZSBmb3IgbGF0ZXIgaW5zdGFudGlhdGlvblxuaW5pdC5wcm90b3R5cGUgPSBqUXVlcnkuZm47XG5cbi8vIEluaXRpYWxpemUgY2VudHJhbCByZWZlcmVuY2VcbnJvb3RqUXVlcnkgPSBqUXVlcnkoIGRvY3VtZW50ICk7XG5cblxudmFyIHJwYXJlbnRzcHJldiA9IC9eKD86cGFyZW50c3xwcmV2KD86VW50aWx8QWxsKSkvLFxuXHQvLyBNZXRob2RzIGd1YXJhbnRlZWQgdG8gcHJvZHVjZSBhIHVuaXF1ZSBzZXQgd2hlbiBzdGFydGluZyBmcm9tIGEgdW5pcXVlIHNldFxuXHRndWFyYW50ZWVkVW5pcXVlID0ge1xuXHRcdGNoaWxkcmVuOiB0cnVlLFxuXHRcdGNvbnRlbnRzOiB0cnVlLFxuXHRcdG5leHQ6IHRydWUsXG5cdFx0cHJldjogdHJ1ZVxuXHR9O1xuXG5qUXVlcnkuZXh0ZW5kKHtcblx0ZGlyOiBmdW5jdGlvbiggZWxlbSwgZGlyLCB1bnRpbCApIHtcblx0XHR2YXIgbWF0Y2hlZCA9IFtdLFxuXHRcdFx0dHJ1bmNhdGUgPSB1bnRpbCAhPT0gdW5kZWZpbmVkO1xuXG5cdFx0d2hpbGUgKCAoZWxlbSA9IGVsZW1bIGRpciBdKSAmJiBlbGVtLm5vZGVUeXBlICE9PSA5ICkge1xuXHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICkge1xuXHRcdFx0XHRpZiAoIHRydW5jYXRlICYmIGpRdWVyeSggZWxlbSApLmlzKCB1bnRpbCApICkge1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHRcdG1hdGNoZWQucHVzaCggZWxlbSApO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gbWF0Y2hlZDtcblx0fSxcblxuXHRzaWJsaW5nOiBmdW5jdGlvbiggbiwgZWxlbSApIHtcblx0XHR2YXIgbWF0Y2hlZCA9IFtdO1xuXG5cdFx0Zm9yICggOyBuOyBuID0gbi5uZXh0U2libGluZyApIHtcblx0XHRcdGlmICggbi5ub2RlVHlwZSA9PT0gMSAmJiBuICE9PSBlbGVtICkge1xuXHRcdFx0XHRtYXRjaGVkLnB1c2goIG4gKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gbWF0Y2hlZDtcblx0fVxufSk7XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHRoYXM6IGZ1bmN0aW9uKCB0YXJnZXQgKSB7XG5cdFx0dmFyIHRhcmdldHMgPSBqUXVlcnkoIHRhcmdldCwgdGhpcyApLFxuXHRcdFx0bCA9IHRhcmdldHMubGVuZ3RoO1xuXG5cdFx0cmV0dXJuIHRoaXMuZmlsdGVyKGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIGkgPSAwO1xuXHRcdFx0Zm9yICggOyBpIDwgbDsgaSsrICkge1xuXHRcdFx0XHRpZiAoIGpRdWVyeS5jb250YWlucyggdGhpcywgdGFyZ2V0c1tpXSApICkge1xuXHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0sXG5cblx0Y2xvc2VzdDogZnVuY3Rpb24oIHNlbGVjdG9ycywgY29udGV4dCApIHtcblx0XHR2YXIgY3VyLFxuXHRcdFx0aSA9IDAsXG5cdFx0XHRsID0gdGhpcy5sZW5ndGgsXG5cdFx0XHRtYXRjaGVkID0gW10sXG5cdFx0XHRwb3MgPSBybmVlZHNDb250ZXh0LnRlc3QoIHNlbGVjdG9ycyApIHx8IHR5cGVvZiBzZWxlY3RvcnMgIT09IFwic3RyaW5nXCIgP1xuXHRcdFx0XHRqUXVlcnkoIHNlbGVjdG9ycywgY29udGV4dCB8fCB0aGlzLmNvbnRleHQgKSA6XG5cdFx0XHRcdDA7XG5cblx0XHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRmb3IgKCBjdXIgPSB0aGlzW2ldOyBjdXIgJiYgY3VyICE9PSBjb250ZXh0OyBjdXIgPSBjdXIucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0Ly8gQWx3YXlzIHNraXAgZG9jdW1lbnQgZnJhZ21lbnRzXG5cdFx0XHRcdGlmICggY3VyLm5vZGVUeXBlIDwgMTEgJiYgKHBvcyA/XG5cdFx0XHRcdFx0cG9zLmluZGV4KGN1cikgPiAtMSA6XG5cblx0XHRcdFx0XHQvLyBEb24ndCBwYXNzIG5vbi1lbGVtZW50cyB0byBTaXp6bGVcblx0XHRcdFx0XHRjdXIubm9kZVR5cGUgPT09IDEgJiZcblx0XHRcdFx0XHRcdGpRdWVyeS5maW5kLm1hdGNoZXNTZWxlY3RvcihjdXIsIHNlbGVjdG9ycykpICkge1xuXG5cdFx0XHRcdFx0bWF0Y2hlZC5wdXNoKCBjdXIgKTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggbWF0Y2hlZC5sZW5ndGggPiAxID8galF1ZXJ5LnVuaXF1ZSggbWF0Y2hlZCApIDogbWF0Y2hlZCApO1xuXHR9LFxuXG5cdC8vIERldGVybWluZSB0aGUgcG9zaXRpb24gb2YgYW4gZWxlbWVudCB3aXRoaW4gdGhlIHNldFxuXHRpbmRleDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cblx0XHQvLyBObyBhcmd1bWVudCwgcmV0dXJuIGluZGV4IGluIHBhcmVudFxuXHRcdGlmICggIWVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gKCB0aGlzWyAwIF0gJiYgdGhpc1sgMCBdLnBhcmVudE5vZGUgKSA/IHRoaXMuZmlyc3QoKS5wcmV2QWxsKCkubGVuZ3RoIDogLTE7XG5cdFx0fVxuXG5cdFx0Ly8gSW5kZXggaW4gc2VsZWN0b3Jcblx0XHRpZiAoIHR5cGVvZiBlbGVtID09PSBcInN0cmluZ1wiICkge1xuXHRcdFx0cmV0dXJuIGluZGV4T2YuY2FsbCggalF1ZXJ5KCBlbGVtICksIHRoaXNbIDAgXSApO1xuXHRcdH1cblxuXHRcdC8vIExvY2F0ZSB0aGUgcG9zaXRpb24gb2YgdGhlIGRlc2lyZWQgZWxlbWVudFxuXHRcdHJldHVybiBpbmRleE9mLmNhbGwoIHRoaXMsXG5cblx0XHRcdC8vIElmIGl0IHJlY2VpdmVzIGEgalF1ZXJ5IG9iamVjdCwgdGhlIGZpcnN0IGVsZW1lbnQgaXMgdXNlZFxuXHRcdFx0ZWxlbS5qcXVlcnkgPyBlbGVtWyAwIF0gOiBlbGVtXG5cdFx0KTtcblx0fSxcblxuXHRhZGQ6IGZ1bmN0aW9uKCBzZWxlY3RvciwgY29udGV4dCApIHtcblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soXG5cdFx0XHRqUXVlcnkudW5pcXVlKFxuXHRcdFx0XHRqUXVlcnkubWVyZ2UoIHRoaXMuZ2V0KCksIGpRdWVyeSggc2VsZWN0b3IsIGNvbnRleHQgKSApXG5cdFx0XHQpXG5cdFx0KTtcblx0fSxcblxuXHRhZGRCYWNrOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0cmV0dXJuIHRoaXMuYWRkKCBzZWxlY3RvciA9PSBudWxsID9cblx0XHRcdHRoaXMucHJldk9iamVjdCA6IHRoaXMucHJldk9iamVjdC5maWx0ZXIoc2VsZWN0b3IpXG5cdFx0KTtcblx0fVxufSk7XG5cbmZ1bmN0aW9uIHNpYmxpbmcoIGN1ciwgZGlyICkge1xuXHR3aGlsZSAoIChjdXIgPSBjdXJbZGlyXSkgJiYgY3VyLm5vZGVUeXBlICE9PSAxICkge31cblx0cmV0dXJuIGN1cjtcbn1cblxualF1ZXJ5LmVhY2goe1xuXHRwYXJlbnQ6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHZhciBwYXJlbnQgPSBlbGVtLnBhcmVudE5vZGU7XG5cdFx0cmV0dXJuIHBhcmVudCAmJiBwYXJlbnQubm9kZVR5cGUgIT09IDExID8gcGFyZW50IDogbnVsbDtcblx0fSxcblx0cGFyZW50czogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5kaXIoIGVsZW0sIFwicGFyZW50Tm9kZVwiICk7XG5cdH0sXG5cdHBhcmVudHNVbnRpbDogZnVuY3Rpb24oIGVsZW0sIGksIHVudGlsICkge1xuXHRcdHJldHVybiBqUXVlcnkuZGlyKCBlbGVtLCBcInBhcmVudE5vZGVcIiwgdW50aWwgKTtcblx0fSxcblx0bmV4dDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIHNpYmxpbmcoIGVsZW0sIFwibmV4dFNpYmxpbmdcIiApO1xuXHR9LFxuXHRwcmV2OiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gc2libGluZyggZWxlbSwgXCJwcmV2aW91c1NpYmxpbmdcIiApO1xuXHR9LFxuXHRuZXh0QWxsOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmRpciggZWxlbSwgXCJuZXh0U2libGluZ1wiICk7XG5cdH0sXG5cdHByZXZBbGw6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBqUXVlcnkuZGlyKCBlbGVtLCBcInByZXZpb3VzU2libGluZ1wiICk7XG5cdH0sXG5cdG5leHRVbnRpbDogZnVuY3Rpb24oIGVsZW0sIGksIHVudGlsICkge1xuXHRcdHJldHVybiBqUXVlcnkuZGlyKCBlbGVtLCBcIm5leHRTaWJsaW5nXCIsIHVudGlsICk7XG5cdH0sXG5cdHByZXZVbnRpbDogZnVuY3Rpb24oIGVsZW0sIGksIHVudGlsICkge1xuXHRcdHJldHVybiBqUXVlcnkuZGlyKCBlbGVtLCBcInByZXZpb3VzU2libGluZ1wiLCB1bnRpbCApO1xuXHR9LFxuXHRzaWJsaW5nczogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5zaWJsaW5nKCAoIGVsZW0ucGFyZW50Tm9kZSB8fCB7fSApLmZpcnN0Q2hpbGQsIGVsZW0gKTtcblx0fSxcblx0Y2hpbGRyZW46IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBqUXVlcnkuc2libGluZyggZWxlbS5maXJzdENoaWxkICk7XG5cdH0sXG5cdGNvbnRlbnRzOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gZWxlbS5jb250ZW50RG9jdW1lbnQgfHwgalF1ZXJ5Lm1lcmdlKCBbXSwgZWxlbS5jaGlsZE5vZGVzICk7XG5cdH1cbn0sIGZ1bmN0aW9uKCBuYW1lLCBmbiApIHtcblx0alF1ZXJ5LmZuWyBuYW1lIF0gPSBmdW5jdGlvbiggdW50aWwsIHNlbGVjdG9yICkge1xuXHRcdHZhciBtYXRjaGVkID0galF1ZXJ5Lm1hcCggdGhpcywgZm4sIHVudGlsICk7XG5cblx0XHRpZiAoIG5hbWUuc2xpY2UoIC01ICkgIT09IFwiVW50aWxcIiApIHtcblx0XHRcdHNlbGVjdG9yID0gdW50aWw7XG5cdFx0fVxuXG5cdFx0aWYgKCBzZWxlY3RvciAmJiB0eXBlb2Ygc2VsZWN0b3IgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRtYXRjaGVkID0galF1ZXJ5LmZpbHRlciggc2VsZWN0b3IsIG1hdGNoZWQgKTtcblx0XHR9XG5cblx0XHRpZiAoIHRoaXMubGVuZ3RoID4gMSApIHtcblx0XHRcdC8vIFJlbW92ZSBkdXBsaWNhdGVzXG5cdFx0XHRpZiAoICFndWFyYW50ZWVkVW5pcXVlWyBuYW1lIF0gKSB7XG5cdFx0XHRcdGpRdWVyeS51bmlxdWUoIG1hdGNoZWQgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gUmV2ZXJzZSBvcmRlciBmb3IgcGFyZW50cyogYW5kIHByZXYtZGVyaXZhdGl2ZXNcblx0XHRcdGlmICggcnBhcmVudHNwcmV2LnRlc3QoIG5hbWUgKSApIHtcblx0XHRcdFx0bWF0Y2hlZC5yZXZlcnNlKCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCBtYXRjaGVkICk7XG5cdH07XG59KTtcbnZhciBybm90d2hpdGUgPSAoL1xcUysvZyk7XG5cblxuXG4vLyBTdHJpbmcgdG8gT2JqZWN0IG9wdGlvbnMgZm9ybWF0IGNhY2hlXG52YXIgb3B0aW9uc0NhY2hlID0ge307XG5cbi8vIENvbnZlcnQgU3RyaW5nLWZvcm1hdHRlZCBvcHRpb25zIGludG8gT2JqZWN0LWZvcm1hdHRlZCBvbmVzIGFuZCBzdG9yZSBpbiBjYWNoZVxuZnVuY3Rpb24gY3JlYXRlT3B0aW9ucyggb3B0aW9ucyApIHtcblx0dmFyIG9iamVjdCA9IG9wdGlvbnNDYWNoZVsgb3B0aW9ucyBdID0ge307XG5cdGpRdWVyeS5lYWNoKCBvcHRpb25zLm1hdGNoKCBybm90d2hpdGUgKSB8fCBbXSwgZnVuY3Rpb24oIF8sIGZsYWcgKSB7XG5cdFx0b2JqZWN0WyBmbGFnIF0gPSB0cnVlO1xuXHR9KTtcblx0cmV0dXJuIG9iamVjdDtcbn1cblxuLypcbiAqIENyZWF0ZSBhIGNhbGxiYWNrIGxpc3QgdXNpbmcgdGhlIGZvbGxvd2luZyBwYXJhbWV0ZXJzOlxuICpcbiAqXHRvcHRpb25zOiBhbiBvcHRpb25hbCBsaXN0IG9mIHNwYWNlLXNlcGFyYXRlZCBvcHRpb25zIHRoYXQgd2lsbCBjaGFuZ2UgaG93XG4gKlx0XHRcdHRoZSBjYWxsYmFjayBsaXN0IGJlaGF2ZXMgb3IgYSBtb3JlIHRyYWRpdGlvbmFsIG9wdGlvbiBvYmplY3RcbiAqXG4gKiBCeSBkZWZhdWx0IGEgY2FsbGJhY2sgbGlzdCB3aWxsIGFjdCBsaWtlIGFuIGV2ZW50IGNhbGxiYWNrIGxpc3QgYW5kIGNhbiBiZVxuICogXCJmaXJlZFwiIG11bHRpcGxlIHRpbWVzLlxuICpcbiAqIFBvc3NpYmxlIG9wdGlvbnM6XG4gKlxuICpcdG9uY2U6XHRcdFx0d2lsbCBlbnN1cmUgdGhlIGNhbGxiYWNrIGxpc3QgY2FuIG9ubHkgYmUgZmlyZWQgb25jZSAobGlrZSBhIERlZmVycmVkKVxuICpcbiAqXHRtZW1vcnk6XHRcdFx0d2lsbCBrZWVwIHRyYWNrIG9mIHByZXZpb3VzIHZhbHVlcyBhbmQgd2lsbCBjYWxsIGFueSBjYWxsYmFjayBhZGRlZFxuICpcdFx0XHRcdFx0YWZ0ZXIgdGhlIGxpc3QgaGFzIGJlZW4gZmlyZWQgcmlnaHQgYXdheSB3aXRoIHRoZSBsYXRlc3QgXCJtZW1vcml6ZWRcIlxuICpcdFx0XHRcdFx0dmFsdWVzIChsaWtlIGEgRGVmZXJyZWQpXG4gKlxuICpcdHVuaXF1ZTpcdFx0XHR3aWxsIGVuc3VyZSBhIGNhbGxiYWNrIGNhbiBvbmx5IGJlIGFkZGVkIG9uY2UgKG5vIGR1cGxpY2F0ZSBpbiB0aGUgbGlzdClcbiAqXG4gKlx0c3RvcE9uRmFsc2U6XHRpbnRlcnJ1cHQgY2FsbGluZ3Mgd2hlbiBhIGNhbGxiYWNrIHJldHVybnMgZmFsc2VcbiAqXG4gKi9cbmpRdWVyeS5DYWxsYmFja3MgPSBmdW5jdGlvbiggb3B0aW9ucyApIHtcblxuXHQvLyBDb252ZXJ0IG9wdGlvbnMgZnJvbSBTdHJpbmctZm9ybWF0dGVkIHRvIE9iamVjdC1mb3JtYXR0ZWQgaWYgbmVlZGVkXG5cdC8vICh3ZSBjaGVjayBpbiBjYWNoZSBmaXJzdClcblx0b3B0aW9ucyA9IHR5cGVvZiBvcHRpb25zID09PSBcInN0cmluZ1wiID9cblx0XHQoIG9wdGlvbnNDYWNoZVsgb3B0aW9ucyBdIHx8IGNyZWF0ZU9wdGlvbnMoIG9wdGlvbnMgKSApIDpcblx0XHRqUXVlcnkuZXh0ZW5kKCB7fSwgb3B0aW9ucyApO1xuXG5cdHZhciAvLyBMYXN0IGZpcmUgdmFsdWUgKGZvciBub24tZm9yZ2V0dGFibGUgbGlzdHMpXG5cdFx0bWVtb3J5LFxuXHRcdC8vIEZsYWcgdG8ga25vdyBpZiBsaXN0IHdhcyBhbHJlYWR5IGZpcmVkXG5cdFx0ZmlyZWQsXG5cdFx0Ly8gRmxhZyB0byBrbm93IGlmIGxpc3QgaXMgY3VycmVudGx5IGZpcmluZ1xuXHRcdGZpcmluZyxcblx0XHQvLyBGaXJzdCBjYWxsYmFjayB0byBmaXJlICh1c2VkIGludGVybmFsbHkgYnkgYWRkIGFuZCBmaXJlV2l0aClcblx0XHRmaXJpbmdTdGFydCxcblx0XHQvLyBFbmQgb2YgdGhlIGxvb3Agd2hlbiBmaXJpbmdcblx0XHRmaXJpbmdMZW5ndGgsXG5cdFx0Ly8gSW5kZXggb2YgY3VycmVudGx5IGZpcmluZyBjYWxsYmFjayAobW9kaWZpZWQgYnkgcmVtb3ZlIGlmIG5lZWRlZClcblx0XHRmaXJpbmdJbmRleCxcblx0XHQvLyBBY3R1YWwgY2FsbGJhY2sgbGlzdFxuXHRcdGxpc3QgPSBbXSxcblx0XHQvLyBTdGFjayBvZiBmaXJlIGNhbGxzIGZvciByZXBlYXRhYmxlIGxpc3RzXG5cdFx0c3RhY2sgPSAhb3B0aW9ucy5vbmNlICYmIFtdLFxuXHRcdC8vIEZpcmUgY2FsbGJhY2tzXG5cdFx0ZmlyZSA9IGZ1bmN0aW9uKCBkYXRhICkge1xuXHRcdFx0bWVtb3J5ID0gb3B0aW9ucy5tZW1vcnkgJiYgZGF0YTtcblx0XHRcdGZpcmVkID0gdHJ1ZTtcblx0XHRcdGZpcmluZ0luZGV4ID0gZmlyaW5nU3RhcnQgfHwgMDtcblx0XHRcdGZpcmluZ1N0YXJ0ID0gMDtcblx0XHRcdGZpcmluZ0xlbmd0aCA9IGxpc3QubGVuZ3RoO1xuXHRcdFx0ZmlyaW5nID0gdHJ1ZTtcblx0XHRcdGZvciAoIDsgbGlzdCAmJiBmaXJpbmdJbmRleCA8IGZpcmluZ0xlbmd0aDsgZmlyaW5nSW5kZXgrKyApIHtcblx0XHRcdFx0aWYgKCBsaXN0WyBmaXJpbmdJbmRleCBdLmFwcGx5KCBkYXRhWyAwIF0sIGRhdGFbIDEgXSApID09PSBmYWxzZSAmJiBvcHRpb25zLnN0b3BPbkZhbHNlICkge1xuXHRcdFx0XHRcdG1lbW9yeSA9IGZhbHNlOyAvLyBUbyBwcmV2ZW50IGZ1cnRoZXIgY2FsbHMgdXNpbmcgYWRkXG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGZpcmluZyA9IGZhbHNlO1xuXHRcdFx0aWYgKCBsaXN0ICkge1xuXHRcdFx0XHRpZiAoIHN0YWNrICkge1xuXHRcdFx0XHRcdGlmICggc3RhY2subGVuZ3RoICkge1xuXHRcdFx0XHRcdFx0ZmlyZSggc3RhY2suc2hpZnQoKSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSBlbHNlIGlmICggbWVtb3J5ICkge1xuXHRcdFx0XHRcdGxpc3QgPSBbXTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRzZWxmLmRpc2FibGUoKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0sXG5cdFx0Ly8gQWN0dWFsIENhbGxiYWNrcyBvYmplY3Rcblx0XHRzZWxmID0ge1xuXHRcdFx0Ly8gQWRkIGEgY2FsbGJhY2sgb3IgYSBjb2xsZWN0aW9uIG9mIGNhbGxiYWNrcyB0byB0aGUgbGlzdFxuXHRcdFx0YWRkOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCBsaXN0ICkge1xuXHRcdFx0XHRcdC8vIEZpcnN0LCB3ZSBzYXZlIHRoZSBjdXJyZW50IGxlbmd0aFxuXHRcdFx0XHRcdHZhciBzdGFydCA9IGxpc3QubGVuZ3RoO1xuXHRcdFx0XHRcdChmdW5jdGlvbiBhZGQoIGFyZ3MgKSB7XG5cdFx0XHRcdFx0XHRqUXVlcnkuZWFjaCggYXJncywgZnVuY3Rpb24oIF8sIGFyZyApIHtcblx0XHRcdFx0XHRcdFx0dmFyIHR5cGUgPSBqUXVlcnkudHlwZSggYXJnICk7XG5cdFx0XHRcdFx0XHRcdGlmICggdHlwZSA9PT0gXCJmdW5jdGlvblwiICkge1xuXHRcdFx0XHRcdFx0XHRcdGlmICggIW9wdGlvbnMudW5pcXVlIHx8ICFzZWxmLmhhcyggYXJnICkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRsaXN0LnB1c2goIGFyZyApO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fSBlbHNlIGlmICggYXJnICYmIGFyZy5sZW5ndGggJiYgdHlwZSAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdFx0XHRcdFx0XHQvLyBJbnNwZWN0IHJlY3Vyc2l2ZWx5XG5cdFx0XHRcdFx0XHRcdFx0YWRkKCBhcmcgKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0fSkoIGFyZ3VtZW50cyApO1xuXHRcdFx0XHRcdC8vIERvIHdlIG5lZWQgdG8gYWRkIHRoZSBjYWxsYmFja3MgdG8gdGhlXG5cdFx0XHRcdFx0Ly8gY3VycmVudCBmaXJpbmcgYmF0Y2g/XG5cdFx0XHRcdFx0aWYgKCBmaXJpbmcgKSB7XG5cdFx0XHRcdFx0XHRmaXJpbmdMZW5ndGggPSBsaXN0Lmxlbmd0aDtcblx0XHRcdFx0XHQvLyBXaXRoIG1lbW9yeSwgaWYgd2UncmUgbm90IGZpcmluZyB0aGVuXG5cdFx0XHRcdFx0Ly8gd2Ugc2hvdWxkIGNhbGwgcmlnaHQgYXdheVxuXHRcdFx0XHRcdH0gZWxzZSBpZiAoIG1lbW9yeSApIHtcblx0XHRcdFx0XHRcdGZpcmluZ1N0YXJ0ID0gc3RhcnQ7XG5cdFx0XHRcdFx0XHRmaXJlKCBtZW1vcnkgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9LFxuXHRcdFx0Ly8gUmVtb3ZlIGEgY2FsbGJhY2sgZnJvbSB0aGUgbGlzdFxuXHRcdFx0cmVtb3ZlOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCBsaXN0ICkge1xuXHRcdFx0XHRcdGpRdWVyeS5lYWNoKCBhcmd1bWVudHMsIGZ1bmN0aW9uKCBfLCBhcmcgKSB7XG5cdFx0XHRcdFx0XHR2YXIgaW5kZXg7XG5cdFx0XHRcdFx0XHR3aGlsZSAoICggaW5kZXggPSBqUXVlcnkuaW5BcnJheSggYXJnLCBsaXN0LCBpbmRleCApICkgPiAtMSApIHtcblx0XHRcdFx0XHRcdFx0bGlzdC5zcGxpY2UoIGluZGV4LCAxICk7XG5cdFx0XHRcdFx0XHRcdC8vIEhhbmRsZSBmaXJpbmcgaW5kZXhlc1xuXHRcdFx0XHRcdFx0XHRpZiAoIGZpcmluZyApIHtcblx0XHRcdFx0XHRcdFx0XHRpZiAoIGluZGV4IDw9IGZpcmluZ0xlbmd0aCApIHtcblx0XHRcdFx0XHRcdFx0XHRcdGZpcmluZ0xlbmd0aC0tO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRpZiAoIGluZGV4IDw9IGZpcmluZ0luZGV4ICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0ZmlyaW5nSW5kZXgtLTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH0sXG5cdFx0XHQvLyBDaGVjayBpZiBhIGdpdmVuIGNhbGxiYWNrIGlzIGluIHRoZSBsaXN0LlxuXHRcdFx0Ly8gSWYgbm8gYXJndW1lbnQgaXMgZ2l2ZW4sIHJldHVybiB3aGV0aGVyIG9yIG5vdCBsaXN0IGhhcyBjYWxsYmFja3MgYXR0YWNoZWQuXG5cdFx0XHRoYXM6IGZ1bmN0aW9uKCBmbiApIHtcblx0XHRcdFx0cmV0dXJuIGZuID8galF1ZXJ5LmluQXJyYXkoIGZuLCBsaXN0ICkgPiAtMSA6ICEhKCBsaXN0ICYmIGxpc3QubGVuZ3RoICk7XG5cdFx0XHR9LFxuXHRcdFx0Ly8gUmVtb3ZlIGFsbCBjYWxsYmFja3MgZnJvbSB0aGUgbGlzdFxuXHRcdFx0ZW1wdHk6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRsaXN0ID0gW107XG5cdFx0XHRcdGZpcmluZ0xlbmd0aCA9IDA7XG5cdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0fSxcblx0XHRcdC8vIEhhdmUgdGhlIGxpc3QgZG8gbm90aGluZyBhbnltb3JlXG5cdFx0XHRkaXNhYmxlOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0bGlzdCA9IHN0YWNrID0gbWVtb3J5ID0gdW5kZWZpbmVkO1xuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH0sXG5cdFx0XHQvLyBJcyBpdCBkaXNhYmxlZD9cblx0XHRcdGRpc2FibGVkOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0cmV0dXJuICFsaXN0O1xuXHRcdFx0fSxcblx0XHRcdC8vIExvY2sgdGhlIGxpc3QgaW4gaXRzIGN1cnJlbnQgc3RhdGVcblx0XHRcdGxvY2s6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRzdGFjayA9IHVuZGVmaW5lZDtcblx0XHRcdFx0aWYgKCAhbWVtb3J5ICkge1xuXHRcdFx0XHRcdHNlbGYuZGlzYWJsZSgpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0fSxcblx0XHRcdC8vIElzIGl0IGxvY2tlZD9cblx0XHRcdGxvY2tlZDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHJldHVybiAhc3RhY2s7XG5cdFx0XHR9LFxuXHRcdFx0Ly8gQ2FsbCBhbGwgY2FsbGJhY2tzIHdpdGggdGhlIGdpdmVuIGNvbnRleHQgYW5kIGFyZ3VtZW50c1xuXHRcdFx0ZmlyZVdpdGg6IGZ1bmN0aW9uKCBjb250ZXh0LCBhcmdzICkge1xuXHRcdFx0XHRpZiAoIGxpc3QgJiYgKCAhZmlyZWQgfHwgc3RhY2sgKSApIHtcblx0XHRcdFx0XHRhcmdzID0gYXJncyB8fCBbXTtcblx0XHRcdFx0XHRhcmdzID0gWyBjb250ZXh0LCBhcmdzLnNsaWNlID8gYXJncy5zbGljZSgpIDogYXJncyBdO1xuXHRcdFx0XHRcdGlmICggZmlyaW5nICkge1xuXHRcdFx0XHRcdFx0c3RhY2sucHVzaCggYXJncyApO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRmaXJlKCBhcmdzICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0fSxcblx0XHRcdC8vIENhbGwgYWxsIHRoZSBjYWxsYmFja3Mgd2l0aCB0aGUgZ2l2ZW4gYXJndW1lbnRzXG5cdFx0XHRmaXJlOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0c2VsZi5maXJlV2l0aCggdGhpcywgYXJndW1lbnRzICk7XG5cdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0fSxcblx0XHRcdC8vIFRvIGtub3cgaWYgdGhlIGNhbGxiYWNrcyBoYXZlIGFscmVhZHkgYmVlbiBjYWxsZWQgYXQgbGVhc3Qgb25jZVxuXHRcdFx0ZmlyZWQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRyZXR1cm4gISFmaXJlZDtcblx0XHRcdH1cblx0XHR9O1xuXG5cdHJldHVybiBzZWxmO1xufTtcblxuXG5qUXVlcnkuZXh0ZW5kKHtcblxuXHREZWZlcnJlZDogZnVuY3Rpb24oIGZ1bmMgKSB7XG5cdFx0dmFyIHR1cGxlcyA9IFtcblx0XHRcdFx0Ly8gYWN0aW9uLCBhZGQgbGlzdGVuZXIsIGxpc3RlbmVyIGxpc3QsIGZpbmFsIHN0YXRlXG5cdFx0XHRcdFsgXCJyZXNvbHZlXCIsIFwiZG9uZVwiLCBqUXVlcnkuQ2FsbGJhY2tzKFwib25jZSBtZW1vcnlcIiksIFwicmVzb2x2ZWRcIiBdLFxuXHRcdFx0XHRbIFwicmVqZWN0XCIsIFwiZmFpbFwiLCBqUXVlcnkuQ2FsbGJhY2tzKFwib25jZSBtZW1vcnlcIiksIFwicmVqZWN0ZWRcIiBdLFxuXHRcdFx0XHRbIFwibm90aWZ5XCIsIFwicHJvZ3Jlc3NcIiwgalF1ZXJ5LkNhbGxiYWNrcyhcIm1lbW9yeVwiKSBdXG5cdFx0XHRdLFxuXHRcdFx0c3RhdGUgPSBcInBlbmRpbmdcIixcblx0XHRcdHByb21pc2UgPSB7XG5cdFx0XHRcdHN0YXRlOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRyZXR1cm4gc3RhdGU7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdGFsd2F5czogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0ZGVmZXJyZWQuZG9uZSggYXJndW1lbnRzICkuZmFpbCggYXJndW1lbnRzICk7XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdHRoZW46IGZ1bmN0aW9uKCAvKiBmbkRvbmUsIGZuRmFpbCwgZm5Qcm9ncmVzcyAqLyApIHtcblx0XHRcdFx0XHR2YXIgZm5zID0gYXJndW1lbnRzO1xuXHRcdFx0XHRcdHJldHVybiBqUXVlcnkuRGVmZXJyZWQoZnVuY3Rpb24oIG5ld0RlZmVyICkge1xuXHRcdFx0XHRcdFx0alF1ZXJ5LmVhY2goIHR1cGxlcywgZnVuY3Rpb24oIGksIHR1cGxlICkge1xuXHRcdFx0XHRcdFx0XHR2YXIgZm4gPSBqUXVlcnkuaXNGdW5jdGlvbiggZm5zWyBpIF0gKSAmJiBmbnNbIGkgXTtcblx0XHRcdFx0XHRcdFx0Ly8gZGVmZXJyZWRbIGRvbmUgfCBmYWlsIHwgcHJvZ3Jlc3MgXSBmb3IgZm9yd2FyZGluZyBhY3Rpb25zIHRvIG5ld0RlZmVyXG5cdFx0XHRcdFx0XHRcdGRlZmVycmVkWyB0dXBsZVsxXSBdKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0XHRcdHZhciByZXR1cm5lZCA9IGZuICYmIGZuLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKTtcblx0XHRcdFx0XHRcdFx0XHRpZiAoIHJldHVybmVkICYmIGpRdWVyeS5pc0Z1bmN0aW9uKCByZXR1cm5lZC5wcm9taXNlICkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm5lZC5wcm9taXNlKClcblx0XHRcdFx0XHRcdFx0XHRcdFx0LmRvbmUoIG5ld0RlZmVyLnJlc29sdmUgKVxuXHRcdFx0XHRcdFx0XHRcdFx0XHQuZmFpbCggbmV3RGVmZXIucmVqZWN0IClcblx0XHRcdFx0XHRcdFx0XHRcdFx0LnByb2dyZXNzKCBuZXdEZWZlci5ub3RpZnkgKTtcblx0XHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdFx0bmV3RGVmZXJbIHR1cGxlWyAwIF0gKyBcIldpdGhcIiBdKCB0aGlzID09PSBwcm9taXNlID8gbmV3RGVmZXIucHJvbWlzZSgpIDogdGhpcywgZm4gPyBbIHJldHVybmVkIF0gOiBhcmd1bWVudHMgKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHRmbnMgPSBudWxsO1xuXHRcdFx0XHRcdH0pLnByb21pc2UoKTtcblx0XHRcdFx0fSxcblx0XHRcdFx0Ly8gR2V0IGEgcHJvbWlzZSBmb3IgdGhpcyBkZWZlcnJlZFxuXHRcdFx0XHQvLyBJZiBvYmogaXMgcHJvdmlkZWQsIHRoZSBwcm9taXNlIGFzcGVjdCBpcyBhZGRlZCB0byB0aGUgb2JqZWN0XG5cdFx0XHRcdHByb21pc2U6IGZ1bmN0aW9uKCBvYmogKSB7XG5cdFx0XHRcdFx0cmV0dXJuIG9iaiAhPSBudWxsID8galF1ZXJ5LmV4dGVuZCggb2JqLCBwcm9taXNlICkgOiBwcm9taXNlO1xuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0ZGVmZXJyZWQgPSB7fTtcblxuXHRcdC8vIEtlZXAgcGlwZSBmb3IgYmFjay1jb21wYXRcblx0XHRwcm9taXNlLnBpcGUgPSBwcm9taXNlLnRoZW47XG5cblx0XHQvLyBBZGQgbGlzdC1zcGVjaWZpYyBtZXRob2RzXG5cdFx0alF1ZXJ5LmVhY2goIHR1cGxlcywgZnVuY3Rpb24oIGksIHR1cGxlICkge1xuXHRcdFx0dmFyIGxpc3QgPSB0dXBsZVsgMiBdLFxuXHRcdFx0XHRzdGF0ZVN0cmluZyA9IHR1cGxlWyAzIF07XG5cblx0XHRcdC8vIHByb21pc2VbIGRvbmUgfCBmYWlsIHwgcHJvZ3Jlc3MgXSA9IGxpc3QuYWRkXG5cdFx0XHRwcm9taXNlWyB0dXBsZVsxXSBdID0gbGlzdC5hZGQ7XG5cblx0XHRcdC8vIEhhbmRsZSBzdGF0ZVxuXHRcdFx0aWYgKCBzdGF0ZVN0cmluZyApIHtcblx0XHRcdFx0bGlzdC5hZGQoZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0Ly8gc3RhdGUgPSBbIHJlc29sdmVkIHwgcmVqZWN0ZWQgXVxuXHRcdFx0XHRcdHN0YXRlID0gc3RhdGVTdHJpbmc7XG5cblx0XHRcdFx0Ly8gWyByZWplY3RfbGlzdCB8IHJlc29sdmVfbGlzdCBdLmRpc2FibGU7IHByb2dyZXNzX2xpc3QubG9ja1xuXHRcdFx0XHR9LCB0dXBsZXNbIGkgXiAxIF1bIDIgXS5kaXNhYmxlLCB0dXBsZXNbIDIgXVsgMiBdLmxvY2sgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gZGVmZXJyZWRbIHJlc29sdmUgfCByZWplY3QgfCBub3RpZnkgXVxuXHRcdFx0ZGVmZXJyZWRbIHR1cGxlWzBdIF0gPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0ZGVmZXJyZWRbIHR1cGxlWzBdICsgXCJXaXRoXCIgXSggdGhpcyA9PT0gZGVmZXJyZWQgPyBwcm9taXNlIDogdGhpcywgYXJndW1lbnRzICk7XG5cdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0fTtcblx0XHRcdGRlZmVycmVkWyB0dXBsZVswXSArIFwiV2l0aFwiIF0gPSBsaXN0LmZpcmVXaXRoO1xuXHRcdH0pO1xuXG5cdFx0Ly8gTWFrZSB0aGUgZGVmZXJyZWQgYSBwcm9taXNlXG5cdFx0cHJvbWlzZS5wcm9taXNlKCBkZWZlcnJlZCApO1xuXG5cdFx0Ly8gQ2FsbCBnaXZlbiBmdW5jIGlmIGFueVxuXHRcdGlmICggZnVuYyApIHtcblx0XHRcdGZ1bmMuY2FsbCggZGVmZXJyZWQsIGRlZmVycmVkICk7XG5cdFx0fVxuXG5cdFx0Ly8gQWxsIGRvbmUhXG5cdFx0cmV0dXJuIGRlZmVycmVkO1xuXHR9LFxuXG5cdC8vIERlZmVycmVkIGhlbHBlclxuXHR3aGVuOiBmdW5jdGlvbiggc3Vib3JkaW5hdGUgLyogLCAuLi4sIHN1Ym9yZGluYXRlTiAqLyApIHtcblx0XHR2YXIgaSA9IDAsXG5cdFx0XHRyZXNvbHZlVmFsdWVzID0gc2xpY2UuY2FsbCggYXJndW1lbnRzICksXG5cdFx0XHRsZW5ndGggPSByZXNvbHZlVmFsdWVzLmxlbmd0aCxcblxuXHRcdFx0Ly8gdGhlIGNvdW50IG9mIHVuY29tcGxldGVkIHN1Ym9yZGluYXRlc1xuXHRcdFx0cmVtYWluaW5nID0gbGVuZ3RoICE9PSAxIHx8ICggc3Vib3JkaW5hdGUgJiYgalF1ZXJ5LmlzRnVuY3Rpb24oIHN1Ym9yZGluYXRlLnByb21pc2UgKSApID8gbGVuZ3RoIDogMCxcblxuXHRcdFx0Ly8gdGhlIG1hc3RlciBEZWZlcnJlZC4gSWYgcmVzb2x2ZVZhbHVlcyBjb25zaXN0IG9mIG9ubHkgYSBzaW5nbGUgRGVmZXJyZWQsIGp1c3QgdXNlIHRoYXQuXG5cdFx0XHRkZWZlcnJlZCA9IHJlbWFpbmluZyA9PT0gMSA/IHN1Ym9yZGluYXRlIDogalF1ZXJ5LkRlZmVycmVkKCksXG5cblx0XHRcdC8vIFVwZGF0ZSBmdW5jdGlvbiBmb3IgYm90aCByZXNvbHZlIGFuZCBwcm9ncmVzcyB2YWx1ZXNcblx0XHRcdHVwZGF0ZUZ1bmMgPSBmdW5jdGlvbiggaSwgY29udGV4dHMsIHZhbHVlcyApIHtcblx0XHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdFx0XHRjb250ZXh0c1sgaSBdID0gdGhpcztcblx0XHRcdFx0XHR2YWx1ZXNbIGkgXSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxID8gc2xpY2UuY2FsbCggYXJndW1lbnRzICkgOiB2YWx1ZTtcblx0XHRcdFx0XHRpZiAoIHZhbHVlcyA9PT0gcHJvZ3Jlc3NWYWx1ZXMgKSB7XG5cdFx0XHRcdFx0XHRkZWZlcnJlZC5ub3RpZnlXaXRoKCBjb250ZXh0cywgdmFsdWVzICk7XG5cdFx0XHRcdFx0fSBlbHNlIGlmICggISggLS1yZW1haW5pbmcgKSApIHtcblx0XHRcdFx0XHRcdGRlZmVycmVkLnJlc29sdmVXaXRoKCBjb250ZXh0cywgdmFsdWVzICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9O1xuXHRcdFx0fSxcblxuXHRcdFx0cHJvZ3Jlc3NWYWx1ZXMsIHByb2dyZXNzQ29udGV4dHMsIHJlc29sdmVDb250ZXh0cztcblxuXHRcdC8vIEFkZCBsaXN0ZW5lcnMgdG8gRGVmZXJyZWQgc3Vib3JkaW5hdGVzOyB0cmVhdCBvdGhlcnMgYXMgcmVzb2x2ZWRcblx0XHRpZiAoIGxlbmd0aCA+IDEgKSB7XG5cdFx0XHRwcm9ncmVzc1ZhbHVlcyA9IG5ldyBBcnJheSggbGVuZ3RoICk7XG5cdFx0XHRwcm9ncmVzc0NvbnRleHRzID0gbmV3IEFycmF5KCBsZW5ndGggKTtcblx0XHRcdHJlc29sdmVDb250ZXh0cyA9IG5ldyBBcnJheSggbGVuZ3RoICk7XG5cdFx0XHRmb3IgKCA7IGkgPCBsZW5ndGg7IGkrKyApIHtcblx0XHRcdFx0aWYgKCByZXNvbHZlVmFsdWVzWyBpIF0gJiYgalF1ZXJ5LmlzRnVuY3Rpb24oIHJlc29sdmVWYWx1ZXNbIGkgXS5wcm9taXNlICkgKSB7XG5cdFx0XHRcdFx0cmVzb2x2ZVZhbHVlc1sgaSBdLnByb21pc2UoKVxuXHRcdFx0XHRcdFx0LmRvbmUoIHVwZGF0ZUZ1bmMoIGksIHJlc29sdmVDb250ZXh0cywgcmVzb2x2ZVZhbHVlcyApIClcblx0XHRcdFx0XHRcdC5mYWlsKCBkZWZlcnJlZC5yZWplY3QgKVxuXHRcdFx0XHRcdFx0LnByb2dyZXNzKCB1cGRhdGVGdW5jKCBpLCBwcm9ncmVzc0NvbnRleHRzLCBwcm9ncmVzc1ZhbHVlcyApICk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0LS1yZW1haW5pbmc7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBJZiB3ZSdyZSBub3Qgd2FpdGluZyBvbiBhbnl0aGluZywgcmVzb2x2ZSB0aGUgbWFzdGVyXG5cdFx0aWYgKCAhcmVtYWluaW5nICkge1xuXHRcdFx0ZGVmZXJyZWQucmVzb2x2ZVdpdGgoIHJlc29sdmVDb250ZXh0cywgcmVzb2x2ZVZhbHVlcyApO1xuXHRcdH1cblxuXHRcdHJldHVybiBkZWZlcnJlZC5wcm9taXNlKCk7XG5cdH1cbn0pO1xuXG5cbi8vIFRoZSBkZWZlcnJlZCB1c2VkIG9uIERPTSByZWFkeVxudmFyIHJlYWR5TGlzdDtcblxualF1ZXJ5LmZuLnJlYWR5ID0gZnVuY3Rpb24oIGZuICkge1xuXHQvLyBBZGQgdGhlIGNhbGxiYWNrXG5cdGpRdWVyeS5yZWFkeS5wcm9taXNlKCkuZG9uZSggZm4gKTtcblxuXHRyZXR1cm4gdGhpcztcbn07XG5cbmpRdWVyeS5leHRlbmQoe1xuXHQvLyBJcyB0aGUgRE9NIHJlYWR5IHRvIGJlIHVzZWQ/IFNldCB0byB0cnVlIG9uY2UgaXQgb2NjdXJzLlxuXHRpc1JlYWR5OiBmYWxzZSxcblxuXHQvLyBBIGNvdW50ZXIgdG8gdHJhY2sgaG93IG1hbnkgaXRlbXMgdG8gd2FpdCBmb3IgYmVmb3JlXG5cdC8vIHRoZSByZWFkeSBldmVudCBmaXJlcy4gU2VlICM2NzgxXG5cdHJlYWR5V2FpdDogMSxcblxuXHQvLyBIb2xkIChvciByZWxlYXNlKSB0aGUgcmVhZHkgZXZlbnRcblx0aG9sZFJlYWR5OiBmdW5jdGlvbiggaG9sZCApIHtcblx0XHRpZiAoIGhvbGQgKSB7XG5cdFx0XHRqUXVlcnkucmVhZHlXYWl0Kys7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGpRdWVyeS5yZWFkeSggdHJ1ZSApO1xuXHRcdH1cblx0fSxcblxuXHQvLyBIYW5kbGUgd2hlbiB0aGUgRE9NIGlzIHJlYWR5XG5cdHJlYWR5OiBmdW5jdGlvbiggd2FpdCApIHtcblxuXHRcdC8vIEFib3J0IGlmIHRoZXJlIGFyZSBwZW5kaW5nIGhvbGRzIG9yIHdlJ3JlIGFscmVhZHkgcmVhZHlcblx0XHRpZiAoIHdhaXQgPT09IHRydWUgPyAtLWpRdWVyeS5yZWFkeVdhaXQgOiBqUXVlcnkuaXNSZWFkeSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBSZW1lbWJlciB0aGF0IHRoZSBET00gaXMgcmVhZHlcblx0XHRqUXVlcnkuaXNSZWFkeSA9IHRydWU7XG5cblx0XHQvLyBJZiBhIG5vcm1hbCBET00gUmVhZHkgZXZlbnQgZmlyZWQsIGRlY3JlbWVudCwgYW5kIHdhaXQgaWYgbmVlZCBiZVxuXHRcdGlmICggd2FpdCAhPT0gdHJ1ZSAmJiAtLWpRdWVyeS5yZWFkeVdhaXQgPiAwICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIElmIHRoZXJlIGFyZSBmdW5jdGlvbnMgYm91bmQsIHRvIGV4ZWN1dGVcblx0XHRyZWFkeUxpc3QucmVzb2x2ZVdpdGgoIGRvY3VtZW50LCBbIGpRdWVyeSBdICk7XG5cblx0XHQvLyBUcmlnZ2VyIGFueSBib3VuZCByZWFkeSBldmVudHNcblx0XHRpZiAoIGpRdWVyeS5mbi50cmlnZ2VySGFuZGxlciApIHtcblx0XHRcdGpRdWVyeSggZG9jdW1lbnQgKS50cmlnZ2VySGFuZGxlciggXCJyZWFkeVwiICk7XG5cdFx0XHRqUXVlcnkoIGRvY3VtZW50ICkub2ZmKCBcInJlYWR5XCIgKTtcblx0XHR9XG5cdH1cbn0pO1xuXG4vKipcbiAqIFRoZSByZWFkeSBldmVudCBoYW5kbGVyIGFuZCBzZWxmIGNsZWFudXAgbWV0aG9kXG4gKi9cbmZ1bmN0aW9uIGNvbXBsZXRlZCgpIHtcblx0ZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lciggXCJET01Db250ZW50TG9hZGVkXCIsIGNvbXBsZXRlZCwgZmFsc2UgKTtcblx0d2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoIFwibG9hZFwiLCBjb21wbGV0ZWQsIGZhbHNlICk7XG5cdGpRdWVyeS5yZWFkeSgpO1xufVxuXG5qUXVlcnkucmVhZHkucHJvbWlzZSA9IGZ1bmN0aW9uKCBvYmogKSB7XG5cdGlmICggIXJlYWR5TGlzdCApIHtcblxuXHRcdHJlYWR5TGlzdCA9IGpRdWVyeS5EZWZlcnJlZCgpO1xuXG5cdFx0Ly8gQ2F0Y2ggY2FzZXMgd2hlcmUgJChkb2N1bWVudCkucmVhZHkoKSBpcyBjYWxsZWQgYWZ0ZXIgdGhlIGJyb3dzZXIgZXZlbnQgaGFzIGFscmVhZHkgb2NjdXJyZWQuXG5cdFx0Ly8gV2Ugb25jZSB0cmllZCB0byB1c2UgcmVhZHlTdGF0ZSBcImludGVyYWN0aXZlXCIgaGVyZSwgYnV0IGl0IGNhdXNlZCBpc3N1ZXMgbGlrZSB0aGUgb25lXG5cdFx0Ly8gZGlzY292ZXJlZCBieSBDaHJpc1MgaGVyZTogaHR0cDovL2J1Z3MuanF1ZXJ5LmNvbS90aWNrZXQvMTIyODIjY29tbWVudDoxNVxuXHRcdGlmICggZG9jdW1lbnQucmVhZHlTdGF0ZSA9PT0gXCJjb21wbGV0ZVwiICkge1xuXHRcdFx0Ly8gSGFuZGxlIGl0IGFzeW5jaHJvbm91c2x5IHRvIGFsbG93IHNjcmlwdHMgdGhlIG9wcG9ydHVuaXR5IHRvIGRlbGF5IHJlYWR5XG5cdFx0XHRzZXRUaW1lb3V0KCBqUXVlcnkucmVhZHkgKTtcblxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdC8vIFVzZSB0aGUgaGFuZHkgZXZlbnQgY2FsbGJhY2tcblx0XHRcdGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoIFwiRE9NQ29udGVudExvYWRlZFwiLCBjb21wbGV0ZWQsIGZhbHNlICk7XG5cblx0XHRcdC8vIEEgZmFsbGJhY2sgdG8gd2luZG93Lm9ubG9hZCwgdGhhdCB3aWxsIGFsd2F5cyB3b3JrXG5cdFx0XHR3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lciggXCJsb2FkXCIsIGNvbXBsZXRlZCwgZmFsc2UgKTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIHJlYWR5TGlzdC5wcm9taXNlKCBvYmogKTtcbn07XG5cbi8vIEtpY2sgb2ZmIHRoZSBET00gcmVhZHkgY2hlY2sgZXZlbiBpZiB0aGUgdXNlciBkb2VzIG5vdFxualF1ZXJ5LnJlYWR5LnByb21pc2UoKTtcblxuXG5cblxuLy8gTXVsdGlmdW5jdGlvbmFsIG1ldGhvZCB0byBnZXQgYW5kIHNldCB2YWx1ZXMgb2YgYSBjb2xsZWN0aW9uXG4vLyBUaGUgdmFsdWUvcyBjYW4gb3B0aW9uYWxseSBiZSBleGVjdXRlZCBpZiBpdCdzIGEgZnVuY3Rpb25cbnZhciBhY2Nlc3MgPSBqUXVlcnkuYWNjZXNzID0gZnVuY3Rpb24oIGVsZW1zLCBmbiwga2V5LCB2YWx1ZSwgY2hhaW5hYmxlLCBlbXB0eUdldCwgcmF3ICkge1xuXHR2YXIgaSA9IDAsXG5cdFx0bGVuID0gZWxlbXMubGVuZ3RoLFxuXHRcdGJ1bGsgPSBrZXkgPT0gbnVsbDtcblxuXHQvLyBTZXRzIG1hbnkgdmFsdWVzXG5cdGlmICggalF1ZXJ5LnR5cGUoIGtleSApID09PSBcIm9iamVjdFwiICkge1xuXHRcdGNoYWluYWJsZSA9IHRydWU7XG5cdFx0Zm9yICggaSBpbiBrZXkgKSB7XG5cdFx0XHRqUXVlcnkuYWNjZXNzKCBlbGVtcywgZm4sIGksIGtleVtpXSwgdHJ1ZSwgZW1wdHlHZXQsIHJhdyApO1xuXHRcdH1cblxuXHQvLyBTZXRzIG9uZSB2YWx1ZVxuXHR9IGVsc2UgaWYgKCB2YWx1ZSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdGNoYWluYWJsZSA9IHRydWU7XG5cblx0XHRpZiAoICFqUXVlcnkuaXNGdW5jdGlvbiggdmFsdWUgKSApIHtcblx0XHRcdHJhdyA9IHRydWU7XG5cdFx0fVxuXG5cdFx0aWYgKCBidWxrICkge1xuXHRcdFx0Ly8gQnVsayBvcGVyYXRpb25zIHJ1biBhZ2FpbnN0IHRoZSBlbnRpcmUgc2V0XG5cdFx0XHRpZiAoIHJhdyApIHtcblx0XHRcdFx0Zm4uY2FsbCggZWxlbXMsIHZhbHVlICk7XG5cdFx0XHRcdGZuID0gbnVsbDtcblxuXHRcdFx0Ly8gLi4uZXhjZXB0IHdoZW4gZXhlY3V0aW5nIGZ1bmN0aW9uIHZhbHVlc1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0YnVsayA9IGZuO1xuXHRcdFx0XHRmbiA9IGZ1bmN0aW9uKCBlbGVtLCBrZXksIHZhbHVlICkge1xuXHRcdFx0XHRcdHJldHVybiBidWxrLmNhbGwoIGpRdWVyeSggZWxlbSApLCB2YWx1ZSApO1xuXHRcdFx0XHR9O1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmICggZm4gKSB7XG5cdFx0XHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdFx0Zm4oIGVsZW1zW2ldLCBrZXksIHJhdyA/IHZhbHVlIDogdmFsdWUuY2FsbCggZWxlbXNbaV0sIGksIGZuKCBlbGVtc1tpXSwga2V5ICkgKSApO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiBjaGFpbmFibGUgP1xuXHRcdGVsZW1zIDpcblxuXHRcdC8vIEdldHNcblx0XHRidWxrID9cblx0XHRcdGZuLmNhbGwoIGVsZW1zICkgOlxuXHRcdFx0bGVuID8gZm4oIGVsZW1zWzBdLCBrZXkgKSA6IGVtcHR5R2V0O1xufTtcblxuXG4vKipcbiAqIERldGVybWluZXMgd2hldGhlciBhbiBvYmplY3QgY2FuIGhhdmUgZGF0YVxuICovXG5qUXVlcnkuYWNjZXB0RGF0YSA9IGZ1bmN0aW9uKCBvd25lciApIHtcblx0Ly8gQWNjZXB0cyBvbmx5OlxuXHQvLyAgLSBOb2RlXG5cdC8vICAgIC0gTm9kZS5FTEVNRU5UX05PREVcblx0Ly8gICAgLSBOb2RlLkRPQ1VNRU5UX05PREVcblx0Ly8gIC0gT2JqZWN0XG5cdC8vICAgIC0gQW55XG5cdC8qIGpzaGludCAtVzAxOCAqL1xuXHRyZXR1cm4gb3duZXIubm9kZVR5cGUgPT09IDEgfHwgb3duZXIubm9kZVR5cGUgPT09IDkgfHwgISggK293bmVyLm5vZGVUeXBlICk7XG59O1xuXG5cbmZ1bmN0aW9uIERhdGEoKSB7XG5cdC8vIFN1cHBvcnQ6IEFuZHJvaWQ8NCxcblx0Ly8gT2xkIFdlYktpdCBkb2VzIG5vdCBoYXZlIE9iamVjdC5wcmV2ZW50RXh0ZW5zaW9ucy9mcmVlemUgbWV0aG9kLFxuXHQvLyByZXR1cm4gbmV3IGVtcHR5IG9iamVjdCBpbnN0ZWFkIHdpdGggbm8gW1tzZXRdXSBhY2Nlc3NvclxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoIHRoaXMuY2FjaGUgPSB7fSwgMCwge1xuXHRcdGdldDogZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4ge307XG5cdFx0fVxuXHR9KTtcblxuXHR0aGlzLmV4cGFuZG8gPSBqUXVlcnkuZXhwYW5kbyArIERhdGEudWlkKys7XG59XG5cbkRhdGEudWlkID0gMTtcbkRhdGEuYWNjZXB0cyA9IGpRdWVyeS5hY2NlcHREYXRhO1xuXG5EYXRhLnByb3RvdHlwZSA9IHtcblx0a2V5OiBmdW5jdGlvbiggb3duZXIgKSB7XG5cdFx0Ly8gV2UgY2FuIGFjY2VwdCBkYXRhIGZvciBub24tZWxlbWVudCBub2RlcyBpbiBtb2Rlcm4gYnJvd3NlcnMsXG5cdFx0Ly8gYnV0IHdlIHNob3VsZCBub3QsIHNlZSAjODMzNS5cblx0XHQvLyBBbHdheXMgcmV0dXJuIHRoZSBrZXkgZm9yIGEgZnJvemVuIG9iamVjdC5cblx0XHRpZiAoICFEYXRhLmFjY2VwdHMoIG93bmVyICkgKSB7XG5cdFx0XHRyZXR1cm4gMDtcblx0XHR9XG5cblx0XHR2YXIgZGVzY3JpcHRvciA9IHt9LFxuXHRcdFx0Ly8gQ2hlY2sgaWYgdGhlIG93bmVyIG9iamVjdCBhbHJlYWR5IGhhcyBhIGNhY2hlIGtleVxuXHRcdFx0dW5sb2NrID0gb3duZXJbIHRoaXMuZXhwYW5kbyBdO1xuXG5cdFx0Ly8gSWYgbm90LCBjcmVhdGUgb25lXG5cdFx0aWYgKCAhdW5sb2NrICkge1xuXHRcdFx0dW5sb2NrID0gRGF0YS51aWQrKztcblxuXHRcdFx0Ly8gU2VjdXJlIGl0IGluIGEgbm9uLWVudW1lcmFibGUsIG5vbi13cml0YWJsZSBwcm9wZXJ0eVxuXHRcdFx0dHJ5IHtcblx0XHRcdFx0ZGVzY3JpcHRvclsgdGhpcy5leHBhbmRvIF0gPSB7IHZhbHVlOiB1bmxvY2sgfTtcblx0XHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnRpZXMoIG93bmVyLCBkZXNjcmlwdG9yICk7XG5cblx0XHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQ8NFxuXHRcdFx0Ly8gRmFsbGJhY2sgdG8gYSBsZXNzIHNlY3VyZSBkZWZpbml0aW9uXG5cdFx0XHR9IGNhdGNoICggZSApIHtcblx0XHRcdFx0ZGVzY3JpcHRvclsgdGhpcy5leHBhbmRvIF0gPSB1bmxvY2s7XG5cdFx0XHRcdGpRdWVyeS5leHRlbmQoIG93bmVyLCBkZXNjcmlwdG9yICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gRW5zdXJlIHRoZSBjYWNoZSBvYmplY3Rcblx0XHRpZiAoICF0aGlzLmNhY2hlWyB1bmxvY2sgXSApIHtcblx0XHRcdHRoaXMuY2FjaGVbIHVubG9jayBdID0ge307XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHVubG9jaztcblx0fSxcblx0c2V0OiBmdW5jdGlvbiggb3duZXIsIGRhdGEsIHZhbHVlICkge1xuXHRcdHZhciBwcm9wLFxuXHRcdFx0Ly8gVGhlcmUgbWF5IGJlIGFuIHVubG9jayBhc3NpZ25lZCB0byB0aGlzIG5vZGUsXG5cdFx0XHQvLyBpZiB0aGVyZSBpcyBubyBlbnRyeSBmb3IgdGhpcyBcIm93bmVyXCIsIGNyZWF0ZSBvbmUgaW5saW5lXG5cdFx0XHQvLyBhbmQgc2V0IHRoZSB1bmxvY2sgYXMgdGhvdWdoIGFuIG93bmVyIGVudHJ5IGhhZCBhbHdheXMgZXhpc3RlZFxuXHRcdFx0dW5sb2NrID0gdGhpcy5rZXkoIG93bmVyICksXG5cdFx0XHRjYWNoZSA9IHRoaXMuY2FjaGVbIHVubG9jayBdO1xuXG5cdFx0Ly8gSGFuZGxlOiBbIG93bmVyLCBrZXksIHZhbHVlIF0gYXJnc1xuXHRcdGlmICggdHlwZW9mIGRhdGEgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRjYWNoZVsgZGF0YSBdID0gdmFsdWU7XG5cblx0XHQvLyBIYW5kbGU6IFsgb3duZXIsIHsgcHJvcGVydGllcyB9IF0gYXJnc1xuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBGcmVzaCBhc3NpZ25tZW50cyBieSBvYmplY3QgYXJlIHNoYWxsb3cgY29waWVkXG5cdFx0XHRpZiAoIGpRdWVyeS5pc0VtcHR5T2JqZWN0KCBjYWNoZSApICkge1xuXHRcdFx0XHRqUXVlcnkuZXh0ZW5kKCB0aGlzLmNhY2hlWyB1bmxvY2sgXSwgZGF0YSApO1xuXHRcdFx0Ly8gT3RoZXJ3aXNlLCBjb3B5IHRoZSBwcm9wZXJ0aWVzIG9uZS1ieS1vbmUgdG8gdGhlIGNhY2hlIG9iamVjdFxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Zm9yICggcHJvcCBpbiBkYXRhICkge1xuXHRcdFx0XHRcdGNhY2hlWyBwcm9wIF0gPSBkYXRhWyBwcm9wIF07XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGNhY2hlO1xuXHR9LFxuXHRnZXQ6IGZ1bmN0aW9uKCBvd25lciwga2V5ICkge1xuXHRcdC8vIEVpdGhlciBhIHZhbGlkIGNhY2hlIGlzIGZvdW5kLCBvciB3aWxsIGJlIGNyZWF0ZWQuXG5cdFx0Ly8gTmV3IGNhY2hlcyB3aWxsIGJlIGNyZWF0ZWQgYW5kIHRoZSB1bmxvY2sgcmV0dXJuZWQsXG5cdFx0Ly8gYWxsb3dpbmcgZGlyZWN0IGFjY2VzcyB0byB0aGUgbmV3bHkgY3JlYXRlZFxuXHRcdC8vIGVtcHR5IGRhdGEgb2JqZWN0LiBBIHZhbGlkIG93bmVyIG9iamVjdCBtdXN0IGJlIHByb3ZpZGVkLlxuXHRcdHZhciBjYWNoZSA9IHRoaXMuY2FjaGVbIHRoaXMua2V5KCBvd25lciApIF07XG5cblx0XHRyZXR1cm4ga2V5ID09PSB1bmRlZmluZWQgP1xuXHRcdFx0Y2FjaGUgOiBjYWNoZVsga2V5IF07XG5cdH0sXG5cdGFjY2VzczogZnVuY3Rpb24oIG93bmVyLCBrZXksIHZhbHVlICkge1xuXHRcdHZhciBzdG9yZWQ7XG5cdFx0Ly8gSW4gY2FzZXMgd2hlcmUgZWl0aGVyOlxuXHRcdC8vXG5cdFx0Ly8gICAxLiBObyBrZXkgd2FzIHNwZWNpZmllZFxuXHRcdC8vICAgMi4gQSBzdHJpbmcga2V5IHdhcyBzcGVjaWZpZWQsIGJ1dCBubyB2YWx1ZSBwcm92aWRlZFxuXHRcdC8vXG5cdFx0Ly8gVGFrZSB0aGUgXCJyZWFkXCIgcGF0aCBhbmQgYWxsb3cgdGhlIGdldCBtZXRob2QgdG8gZGV0ZXJtaW5lXG5cdFx0Ly8gd2hpY2ggdmFsdWUgdG8gcmV0dXJuLCByZXNwZWN0aXZlbHkgZWl0aGVyOlxuXHRcdC8vXG5cdFx0Ly8gICAxLiBUaGUgZW50aXJlIGNhY2hlIG9iamVjdFxuXHRcdC8vICAgMi4gVGhlIGRhdGEgc3RvcmVkIGF0IHRoZSBrZXlcblx0XHQvL1xuXHRcdGlmICgga2V5ID09PSB1bmRlZmluZWQgfHxcblx0XHRcdFx0KChrZXkgJiYgdHlwZW9mIGtleSA9PT0gXCJzdHJpbmdcIikgJiYgdmFsdWUgPT09IHVuZGVmaW5lZCkgKSB7XG5cblx0XHRcdHN0b3JlZCA9IHRoaXMuZ2V0KCBvd25lciwga2V5ICk7XG5cblx0XHRcdHJldHVybiBzdG9yZWQgIT09IHVuZGVmaW5lZCA/XG5cdFx0XHRcdHN0b3JlZCA6IHRoaXMuZ2V0KCBvd25lciwgalF1ZXJ5LmNhbWVsQ2FzZShrZXkpICk7XG5cdFx0fVxuXG5cdFx0Ly8gWypdV2hlbiB0aGUga2V5IGlzIG5vdCBhIHN0cmluZywgb3IgYm90aCBhIGtleSBhbmQgdmFsdWVcblx0XHQvLyBhcmUgc3BlY2lmaWVkLCBzZXQgb3IgZXh0ZW5kIChleGlzdGluZyBvYmplY3RzKSB3aXRoIGVpdGhlcjpcblx0XHQvL1xuXHRcdC8vICAgMS4gQW4gb2JqZWN0IG9mIHByb3BlcnRpZXNcblx0XHQvLyAgIDIuIEEga2V5IGFuZCB2YWx1ZVxuXHRcdC8vXG5cdFx0dGhpcy5zZXQoIG93bmVyLCBrZXksIHZhbHVlICk7XG5cblx0XHQvLyBTaW5jZSB0aGUgXCJzZXRcIiBwYXRoIGNhbiBoYXZlIHR3byBwb3NzaWJsZSBlbnRyeSBwb2ludHNcblx0XHQvLyByZXR1cm4gdGhlIGV4cGVjdGVkIGRhdGEgYmFzZWQgb24gd2hpY2ggcGF0aCB3YXMgdGFrZW5bKl1cblx0XHRyZXR1cm4gdmFsdWUgIT09IHVuZGVmaW5lZCA/IHZhbHVlIDoga2V5O1xuXHR9LFxuXHRyZW1vdmU6IGZ1bmN0aW9uKCBvd25lciwga2V5ICkge1xuXHRcdHZhciBpLCBuYW1lLCBjYW1lbCxcblx0XHRcdHVubG9jayA9IHRoaXMua2V5KCBvd25lciApLFxuXHRcdFx0Y2FjaGUgPSB0aGlzLmNhY2hlWyB1bmxvY2sgXTtcblxuXHRcdGlmICgga2V5ID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHR0aGlzLmNhY2hlWyB1bmxvY2sgXSA9IHt9O1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIFN1cHBvcnQgYXJyYXkgb3Igc3BhY2Ugc2VwYXJhdGVkIHN0cmluZyBvZiBrZXlzXG5cdFx0XHRpZiAoIGpRdWVyeS5pc0FycmF5KCBrZXkgKSApIHtcblx0XHRcdFx0Ly8gSWYgXCJuYW1lXCIgaXMgYW4gYXJyYXkgb2Yga2V5cy4uLlxuXHRcdFx0XHQvLyBXaGVuIGRhdGEgaXMgaW5pdGlhbGx5IGNyZWF0ZWQsIHZpYSAoXCJrZXlcIiwgXCJ2YWxcIikgc2lnbmF0dXJlLFxuXHRcdFx0XHQvLyBrZXlzIHdpbGwgYmUgY29udmVydGVkIHRvIGNhbWVsQ2FzZS5cblx0XHRcdFx0Ly8gU2luY2UgdGhlcmUgaXMgbm8gd2F5IHRvIHRlbGwgX2hvd18gYSBrZXkgd2FzIGFkZGVkLCByZW1vdmVcblx0XHRcdFx0Ly8gYm90aCBwbGFpbiBrZXkgYW5kIGNhbWVsQ2FzZSBrZXkuICMxMjc4NlxuXHRcdFx0XHQvLyBUaGlzIHdpbGwgb25seSBwZW5hbGl6ZSB0aGUgYXJyYXkgYXJndW1lbnQgcGF0aC5cblx0XHRcdFx0bmFtZSA9IGtleS5jb25jYXQoIGtleS5tYXAoIGpRdWVyeS5jYW1lbENhc2UgKSApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y2FtZWwgPSBqUXVlcnkuY2FtZWxDYXNlKCBrZXkgKTtcblx0XHRcdFx0Ly8gVHJ5IHRoZSBzdHJpbmcgYXMgYSBrZXkgYmVmb3JlIGFueSBtYW5pcHVsYXRpb25cblx0XHRcdFx0aWYgKCBrZXkgaW4gY2FjaGUgKSB7XG5cdFx0XHRcdFx0bmFtZSA9IFsga2V5LCBjYW1lbCBdO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdC8vIElmIGEga2V5IHdpdGggdGhlIHNwYWNlcyBleGlzdHMsIHVzZSBpdC5cblx0XHRcdFx0XHQvLyBPdGhlcndpc2UsIGNyZWF0ZSBhbiBhcnJheSBieSBtYXRjaGluZyBub24td2hpdGVzcGFjZVxuXHRcdFx0XHRcdG5hbWUgPSBjYW1lbDtcblx0XHRcdFx0XHRuYW1lID0gbmFtZSBpbiBjYWNoZSA/XG5cdFx0XHRcdFx0XHRbIG5hbWUgXSA6ICggbmFtZS5tYXRjaCggcm5vdHdoaXRlICkgfHwgW10gKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRpID0gbmFtZS5sZW5ndGg7XG5cdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0ZGVsZXRlIGNhY2hlWyBuYW1lWyBpIF0gXTtcblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cdGhhc0RhdGE6IGZ1bmN0aW9uKCBvd25lciApIHtcblx0XHRyZXR1cm4gIWpRdWVyeS5pc0VtcHR5T2JqZWN0KFxuXHRcdFx0dGhpcy5jYWNoZVsgb3duZXJbIHRoaXMuZXhwYW5kbyBdIF0gfHwge31cblx0XHQpO1xuXHR9LFxuXHRkaXNjYXJkOiBmdW5jdGlvbiggb3duZXIgKSB7XG5cdFx0aWYgKCBvd25lclsgdGhpcy5leHBhbmRvIF0gKSB7XG5cdFx0XHRkZWxldGUgdGhpcy5jYWNoZVsgb3duZXJbIHRoaXMuZXhwYW5kbyBdIF07XG5cdFx0fVxuXHR9XG59O1xudmFyIGRhdGFfcHJpdiA9IG5ldyBEYXRhKCk7XG5cbnZhciBkYXRhX3VzZXIgPSBuZXcgRGF0YSgpO1xuXG5cblxuLy9cdEltcGxlbWVudGF0aW9uIFN1bW1hcnlcbi8vXG4vL1x0MS4gRW5mb3JjZSBBUEkgc3VyZmFjZSBhbmQgc2VtYW50aWMgY29tcGF0aWJpbGl0eSB3aXRoIDEuOS54IGJyYW5jaFxuLy9cdDIuIEltcHJvdmUgdGhlIG1vZHVsZSdzIG1haW50YWluYWJpbGl0eSBieSByZWR1Y2luZyB0aGUgc3RvcmFnZVxuLy9cdFx0cGF0aHMgdG8gYSBzaW5nbGUgbWVjaGFuaXNtLlxuLy9cdDMuIFVzZSB0aGUgc2FtZSBzaW5nbGUgbWVjaGFuaXNtIHRvIHN1cHBvcnQgXCJwcml2YXRlXCIgYW5kIFwidXNlclwiIGRhdGEuXG4vL1x0NC4gX05ldmVyXyBleHBvc2UgXCJwcml2YXRlXCIgZGF0YSB0byB1c2VyIGNvZGUgKFRPRE86IERyb3AgX2RhdGEsIF9yZW1vdmVEYXRhKVxuLy9cdDUuIEF2b2lkIGV4cG9zaW5nIGltcGxlbWVudGF0aW9uIGRldGFpbHMgb24gdXNlciBvYmplY3RzIChlZy4gZXhwYW5kbyBwcm9wZXJ0aWVzKVxuLy9cdDYuIFByb3ZpZGUgYSBjbGVhciBwYXRoIGZvciBpbXBsZW1lbnRhdGlvbiB1cGdyYWRlIHRvIFdlYWtNYXAgaW4gMjAxNFxuXG52YXIgcmJyYWNlID0gL14oPzpcXHtbXFx3XFxXXSpcXH18XFxbW1xcd1xcV10qXFxdKSQvLFxuXHRybXVsdGlEYXNoID0gLyhbQS1aXSkvZztcblxuZnVuY3Rpb24gZGF0YUF0dHIoIGVsZW0sIGtleSwgZGF0YSApIHtcblx0dmFyIG5hbWU7XG5cblx0Ly8gSWYgbm90aGluZyB3YXMgZm91bmQgaW50ZXJuYWxseSwgdHJ5IHRvIGZldGNoIGFueVxuXHQvLyBkYXRhIGZyb20gdGhlIEhUTUw1IGRhdGEtKiBhdHRyaWJ1dGVcblx0aWYgKCBkYXRhID09PSB1bmRlZmluZWQgJiYgZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRuYW1lID0gXCJkYXRhLVwiICsga2V5LnJlcGxhY2UoIHJtdWx0aURhc2gsIFwiLSQxXCIgKS50b0xvd2VyQ2FzZSgpO1xuXHRcdGRhdGEgPSBlbGVtLmdldEF0dHJpYnV0ZSggbmFtZSApO1xuXG5cdFx0aWYgKCB0eXBlb2YgZGF0YSA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHRyeSB7XG5cdFx0XHRcdGRhdGEgPSBkYXRhID09PSBcInRydWVcIiA/IHRydWUgOlxuXHRcdFx0XHRcdGRhdGEgPT09IFwiZmFsc2VcIiA/IGZhbHNlIDpcblx0XHRcdFx0XHRkYXRhID09PSBcIm51bGxcIiA/IG51bGwgOlxuXHRcdFx0XHRcdC8vIE9ubHkgY29udmVydCB0byBhIG51bWJlciBpZiBpdCBkb2Vzbid0IGNoYW5nZSB0aGUgc3RyaW5nXG5cdFx0XHRcdFx0K2RhdGEgKyBcIlwiID09PSBkYXRhID8gK2RhdGEgOlxuXHRcdFx0XHRcdHJicmFjZS50ZXN0KCBkYXRhICkgPyBqUXVlcnkucGFyc2VKU09OKCBkYXRhICkgOlxuXHRcdFx0XHRcdGRhdGE7XG5cdFx0XHR9IGNhdGNoKCBlICkge31cblxuXHRcdFx0Ly8gTWFrZSBzdXJlIHdlIHNldCB0aGUgZGF0YSBzbyBpdCBpc24ndCBjaGFuZ2VkIGxhdGVyXG5cdFx0XHRkYXRhX3VzZXIuc2V0KCBlbGVtLCBrZXksIGRhdGEgKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0ZGF0YSA9IHVuZGVmaW5lZDtcblx0XHR9XG5cdH1cblx0cmV0dXJuIGRhdGE7XG59XG5cbmpRdWVyeS5leHRlbmQoe1xuXHRoYXNEYXRhOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gZGF0YV91c2VyLmhhc0RhdGEoIGVsZW0gKSB8fCBkYXRhX3ByaXYuaGFzRGF0YSggZWxlbSApO1xuXHR9LFxuXG5cdGRhdGE6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBkYXRhICkge1xuXHRcdHJldHVybiBkYXRhX3VzZXIuYWNjZXNzKCBlbGVtLCBuYW1lLCBkYXRhICk7XG5cdH0sXG5cblx0cmVtb3ZlRGF0YTogZnVuY3Rpb24oIGVsZW0sIG5hbWUgKSB7XG5cdFx0ZGF0YV91c2VyLnJlbW92ZSggZWxlbSwgbmFtZSApO1xuXHR9LFxuXG5cdC8vIFRPRE86IE5vdyB0aGF0IGFsbCBjYWxscyB0byBfZGF0YSBhbmQgX3JlbW92ZURhdGEgaGF2ZSBiZWVuIHJlcGxhY2VkXG5cdC8vIHdpdGggZGlyZWN0IGNhbGxzIHRvIGRhdGFfcHJpdiBtZXRob2RzLCB0aGVzZSBjYW4gYmUgZGVwcmVjYXRlZC5cblx0X2RhdGE6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBkYXRhICkge1xuXHRcdHJldHVybiBkYXRhX3ByaXYuYWNjZXNzKCBlbGVtLCBuYW1lLCBkYXRhICk7XG5cdH0sXG5cblx0X3JlbW92ZURhdGE6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lICkge1xuXHRcdGRhdGFfcHJpdi5yZW1vdmUoIGVsZW0sIG5hbWUgKTtcblx0fVxufSk7XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHRkYXRhOiBmdW5jdGlvbigga2V5LCB2YWx1ZSApIHtcblx0XHR2YXIgaSwgbmFtZSwgZGF0YSxcblx0XHRcdGVsZW0gPSB0aGlzWyAwIF0sXG5cdFx0XHRhdHRycyA9IGVsZW0gJiYgZWxlbS5hdHRyaWJ1dGVzO1xuXG5cdFx0Ly8gR2V0cyBhbGwgdmFsdWVzXG5cdFx0aWYgKCBrZXkgPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdGlmICggdGhpcy5sZW5ndGggKSB7XG5cdFx0XHRcdGRhdGEgPSBkYXRhX3VzZXIuZ2V0KCBlbGVtICk7XG5cblx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICYmICFkYXRhX3ByaXYuZ2V0KCBlbGVtLCBcImhhc0RhdGFBdHRyc1wiICkgKSB7XG5cdFx0XHRcdFx0aSA9IGF0dHJzLmxlbmd0aDtcblx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblxuXHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUxMStcblx0XHRcdFx0XHRcdC8vIFRoZSBhdHRycyBlbGVtZW50cyBjYW4gYmUgbnVsbCAoIzE0ODk0KVxuXHRcdFx0XHRcdFx0aWYgKCBhdHRyc1sgaSBdICkge1xuXHRcdFx0XHRcdFx0XHRuYW1lID0gYXR0cnNbIGkgXS5uYW1lO1xuXHRcdFx0XHRcdFx0XHRpZiAoIG5hbWUuaW5kZXhPZiggXCJkYXRhLVwiICkgPT09IDAgKSB7XG5cdFx0XHRcdFx0XHRcdFx0bmFtZSA9IGpRdWVyeS5jYW1lbENhc2UoIG5hbWUuc2xpY2UoNSkgKTtcblx0XHRcdFx0XHRcdFx0XHRkYXRhQXR0ciggZWxlbSwgbmFtZSwgZGF0YVsgbmFtZSBdICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0ZGF0YV9wcml2LnNldCggZWxlbSwgXCJoYXNEYXRhQXR0cnNcIiwgdHJ1ZSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBkYXRhO1xuXHRcdH1cblxuXHRcdC8vIFNldHMgbXVsdGlwbGUgdmFsdWVzXG5cdFx0aWYgKCB0eXBlb2Yga2V5ID09PSBcIm9iamVjdFwiICkge1xuXHRcdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdFx0ZGF0YV91c2VyLnNldCggdGhpcywga2V5ICk7XG5cdFx0XHR9KTtcblx0XHR9XG5cblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0XHR2YXIgZGF0YSxcblx0XHRcdFx0Y2FtZWxLZXkgPSBqUXVlcnkuY2FtZWxDYXNlKCBrZXkgKTtcblxuXHRcdFx0Ly8gVGhlIGNhbGxpbmcgalF1ZXJ5IG9iamVjdCAoZWxlbWVudCBtYXRjaGVzKSBpcyBub3QgZW1wdHlcblx0XHRcdC8vIChhbmQgdGhlcmVmb3JlIGhhcyBhbiBlbGVtZW50IGFwcGVhcnMgYXQgdGhpc1sgMCBdKSBhbmQgdGhlXG5cdFx0XHQvLyBgdmFsdWVgIHBhcmFtZXRlciB3YXMgbm90IHVuZGVmaW5lZC4gQW4gZW1wdHkgalF1ZXJ5IG9iamVjdFxuXHRcdFx0Ly8gd2lsbCByZXN1bHQgaW4gYHVuZGVmaW5lZGAgZm9yIGVsZW0gPSB0aGlzWyAwIF0gd2hpY2ggd2lsbFxuXHRcdFx0Ly8gdGhyb3cgYW4gZXhjZXB0aW9uIGlmIGFuIGF0dGVtcHQgdG8gcmVhZCBhIGRhdGEgY2FjaGUgaXMgbWFkZS5cblx0XHRcdGlmICggZWxlbSAmJiB2YWx1ZSA9PT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHQvLyBBdHRlbXB0IHRvIGdldCBkYXRhIGZyb20gdGhlIGNhY2hlXG5cdFx0XHRcdC8vIHdpdGggdGhlIGtleSBhcy1pc1xuXHRcdFx0XHRkYXRhID0gZGF0YV91c2VyLmdldCggZWxlbSwga2V5ICk7XG5cdFx0XHRcdGlmICggZGF0YSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdHJldHVybiBkYXRhO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gQXR0ZW1wdCB0byBnZXQgZGF0YSBmcm9tIHRoZSBjYWNoZVxuXHRcdFx0XHQvLyB3aXRoIHRoZSBrZXkgY2FtZWxpemVkXG5cdFx0XHRcdGRhdGEgPSBkYXRhX3VzZXIuZ2V0KCBlbGVtLCBjYW1lbEtleSApO1xuXHRcdFx0XHRpZiAoIGRhdGEgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHRyZXR1cm4gZGF0YTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEF0dGVtcHQgdG8gXCJkaXNjb3ZlclwiIHRoZSBkYXRhIGluXG5cdFx0XHRcdC8vIEhUTUw1IGN1c3RvbSBkYXRhLSogYXR0cnNcblx0XHRcdFx0ZGF0YSA9IGRhdGFBdHRyKCBlbGVtLCBjYW1lbEtleSwgdW5kZWZpbmVkICk7XG5cdFx0XHRcdGlmICggZGF0YSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdHJldHVybiBkYXRhO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gV2UgdHJpZWQgcmVhbGx5IGhhcmQsIGJ1dCB0aGUgZGF0YSBkb2Vzbid0IGV4aXN0LlxuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNldCB0aGUgZGF0YS4uLlxuXHRcdFx0dGhpcy5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHQvLyBGaXJzdCwgYXR0ZW1wdCB0byBzdG9yZSBhIGNvcHkgb3IgcmVmZXJlbmNlIG9mIGFueVxuXHRcdFx0XHQvLyBkYXRhIHRoYXQgbWlnaHQndmUgYmVlbiBzdG9yZSB3aXRoIGEgY2FtZWxDYXNlZCBrZXkuXG5cdFx0XHRcdHZhciBkYXRhID0gZGF0YV91c2VyLmdldCggdGhpcywgY2FtZWxLZXkgKTtcblxuXHRcdFx0XHQvLyBGb3IgSFRNTDUgZGF0YS0qIGF0dHJpYnV0ZSBpbnRlcm9wLCB3ZSBoYXZlIHRvXG5cdFx0XHRcdC8vIHN0b3JlIHByb3BlcnR5IG5hbWVzIHdpdGggZGFzaGVzIGluIGEgY2FtZWxDYXNlIGZvcm0uXG5cdFx0XHRcdC8vIFRoaXMgbWlnaHQgbm90IGFwcGx5IHRvIGFsbCBwcm9wZXJ0aWVzLi4uKlxuXHRcdFx0XHRkYXRhX3VzZXIuc2V0KCB0aGlzLCBjYW1lbEtleSwgdmFsdWUgKTtcblxuXHRcdFx0XHQvLyAqLi4uIEluIHRoZSBjYXNlIG9mIHByb3BlcnRpZXMgdGhhdCBtaWdodCBfYWN0dWFsbHlfXG5cdFx0XHRcdC8vIGhhdmUgZGFzaGVzLCB3ZSBuZWVkIHRvIGFsc28gc3RvcmUgYSBjb3B5IG9mIHRoYXRcblx0XHRcdFx0Ly8gdW5jaGFuZ2VkIHByb3BlcnR5LlxuXHRcdFx0XHRpZiAoIGtleS5pbmRleE9mKFwiLVwiKSAhPT0gLTEgJiYgZGF0YSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdGRhdGFfdXNlci5zZXQoIHRoaXMsIGtleSwgdmFsdWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fSwgbnVsbCwgdmFsdWUsIGFyZ3VtZW50cy5sZW5ndGggPiAxLCBudWxsLCB0cnVlICk7XG5cdH0sXG5cblx0cmVtb3ZlRGF0YTogZnVuY3Rpb24oIGtleSApIHtcblx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0ZGF0YV91c2VyLnJlbW92ZSggdGhpcywga2V5ICk7XG5cdFx0fSk7XG5cdH1cbn0pO1xuXG5cbmpRdWVyeS5leHRlbmQoe1xuXHRxdWV1ZTogZnVuY3Rpb24oIGVsZW0sIHR5cGUsIGRhdGEgKSB7XG5cdFx0dmFyIHF1ZXVlO1xuXG5cdFx0aWYgKCBlbGVtICkge1xuXHRcdFx0dHlwZSA9ICggdHlwZSB8fCBcImZ4XCIgKSArIFwicXVldWVcIjtcblx0XHRcdHF1ZXVlID0gZGF0YV9wcml2LmdldCggZWxlbSwgdHlwZSApO1xuXG5cdFx0XHQvLyBTcGVlZCB1cCBkZXF1ZXVlIGJ5IGdldHRpbmcgb3V0IHF1aWNrbHkgaWYgdGhpcyBpcyBqdXN0IGEgbG9va3VwXG5cdFx0XHRpZiAoIGRhdGEgKSB7XG5cdFx0XHRcdGlmICggIXF1ZXVlIHx8IGpRdWVyeS5pc0FycmF5KCBkYXRhICkgKSB7XG5cdFx0XHRcdFx0cXVldWUgPSBkYXRhX3ByaXYuYWNjZXNzKCBlbGVtLCB0eXBlLCBqUXVlcnkubWFrZUFycmF5KGRhdGEpICk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cXVldWUucHVzaCggZGF0YSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcXVldWUgfHwgW107XG5cdFx0fVxuXHR9LFxuXG5cdGRlcXVldWU6IGZ1bmN0aW9uKCBlbGVtLCB0eXBlICkge1xuXHRcdHR5cGUgPSB0eXBlIHx8IFwiZnhcIjtcblxuXHRcdHZhciBxdWV1ZSA9IGpRdWVyeS5xdWV1ZSggZWxlbSwgdHlwZSApLFxuXHRcdFx0c3RhcnRMZW5ndGggPSBxdWV1ZS5sZW5ndGgsXG5cdFx0XHRmbiA9IHF1ZXVlLnNoaWZ0KCksXG5cdFx0XHRob29rcyA9IGpRdWVyeS5fcXVldWVIb29rcyggZWxlbSwgdHlwZSApLFxuXHRcdFx0bmV4dCA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRqUXVlcnkuZGVxdWV1ZSggZWxlbSwgdHlwZSApO1xuXHRcdFx0fTtcblxuXHRcdC8vIElmIHRoZSBmeCBxdWV1ZSBpcyBkZXF1ZXVlZCwgYWx3YXlzIHJlbW92ZSB0aGUgcHJvZ3Jlc3Mgc2VudGluZWxcblx0XHRpZiAoIGZuID09PSBcImlucHJvZ3Jlc3NcIiApIHtcblx0XHRcdGZuID0gcXVldWUuc2hpZnQoKTtcblx0XHRcdHN0YXJ0TGVuZ3RoLS07XG5cdFx0fVxuXG5cdFx0aWYgKCBmbiApIHtcblxuXHRcdFx0Ly8gQWRkIGEgcHJvZ3Jlc3Mgc2VudGluZWwgdG8gcHJldmVudCB0aGUgZnggcXVldWUgZnJvbSBiZWluZ1xuXHRcdFx0Ly8gYXV0b21hdGljYWxseSBkZXF1ZXVlZFxuXHRcdFx0aWYgKCB0eXBlID09PSBcImZ4XCIgKSB7XG5cdFx0XHRcdHF1ZXVlLnVuc2hpZnQoIFwiaW5wcm9ncmVzc1wiICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIENsZWFyIHVwIHRoZSBsYXN0IHF1ZXVlIHN0b3AgZnVuY3Rpb25cblx0XHRcdGRlbGV0ZSBob29rcy5zdG9wO1xuXHRcdFx0Zm4uY2FsbCggZWxlbSwgbmV4dCwgaG9va3MgKTtcblx0XHR9XG5cblx0XHRpZiAoICFzdGFydExlbmd0aCAmJiBob29rcyApIHtcblx0XHRcdGhvb2tzLmVtcHR5LmZpcmUoKTtcblx0XHR9XG5cdH0sXG5cblx0Ly8gTm90IHB1YmxpYyAtIGdlbmVyYXRlIGEgcXVldWVIb29rcyBvYmplY3QsIG9yIHJldHVybiB0aGUgY3VycmVudCBvbmVcblx0X3F1ZXVlSG9va3M6IGZ1bmN0aW9uKCBlbGVtLCB0eXBlICkge1xuXHRcdHZhciBrZXkgPSB0eXBlICsgXCJxdWV1ZUhvb2tzXCI7XG5cdFx0cmV0dXJuIGRhdGFfcHJpdi5nZXQoIGVsZW0sIGtleSApIHx8IGRhdGFfcHJpdi5hY2Nlc3MoIGVsZW0sIGtleSwge1xuXHRcdFx0ZW1wdHk6IGpRdWVyeS5DYWxsYmFja3MoXCJvbmNlIG1lbW9yeVwiKS5hZGQoZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGRhdGFfcHJpdi5yZW1vdmUoIGVsZW0sIFsgdHlwZSArIFwicXVldWVcIiwga2V5IF0gKTtcblx0XHRcdH0pXG5cdFx0fSk7XG5cdH1cbn0pO1xuXG5qUXVlcnkuZm4uZXh0ZW5kKHtcblx0cXVldWU6IGZ1bmN0aW9uKCB0eXBlLCBkYXRhICkge1xuXHRcdHZhciBzZXR0ZXIgPSAyO1xuXG5cdFx0aWYgKCB0eXBlb2YgdHlwZSAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdGRhdGEgPSB0eXBlO1xuXHRcdFx0dHlwZSA9IFwiZnhcIjtcblx0XHRcdHNldHRlci0tO1xuXHRcdH1cblxuXHRcdGlmICggYXJndW1lbnRzLmxlbmd0aCA8IHNldHRlciApIHtcblx0XHRcdHJldHVybiBqUXVlcnkucXVldWUoIHRoaXNbMF0sIHR5cGUgKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gZGF0YSA9PT0gdW5kZWZpbmVkID9cblx0XHRcdHRoaXMgOlxuXHRcdFx0dGhpcy5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR2YXIgcXVldWUgPSBqUXVlcnkucXVldWUoIHRoaXMsIHR5cGUsIGRhdGEgKTtcblxuXHRcdFx0XHQvLyBFbnN1cmUgYSBob29rcyBmb3IgdGhpcyBxdWV1ZVxuXHRcdFx0XHRqUXVlcnkuX3F1ZXVlSG9va3MoIHRoaXMsIHR5cGUgKTtcblxuXHRcdFx0XHRpZiAoIHR5cGUgPT09IFwiZnhcIiAmJiBxdWV1ZVswXSAhPT0gXCJpbnByb2dyZXNzXCIgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5LmRlcXVldWUoIHRoaXMsIHR5cGUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdH0sXG5cdGRlcXVldWU6IGZ1bmN0aW9uKCB0eXBlICkge1xuXHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRqUXVlcnkuZGVxdWV1ZSggdGhpcywgdHlwZSApO1xuXHRcdH0pO1xuXHR9LFxuXHRjbGVhclF1ZXVlOiBmdW5jdGlvbiggdHlwZSApIHtcblx0XHRyZXR1cm4gdGhpcy5xdWV1ZSggdHlwZSB8fCBcImZ4XCIsIFtdICk7XG5cdH0sXG5cdC8vIEdldCBhIHByb21pc2UgcmVzb2x2ZWQgd2hlbiBxdWV1ZXMgb2YgYSBjZXJ0YWluIHR5cGVcblx0Ly8gYXJlIGVtcHRpZWQgKGZ4IGlzIHRoZSB0eXBlIGJ5IGRlZmF1bHQpXG5cdHByb21pc2U6IGZ1bmN0aW9uKCB0eXBlLCBvYmogKSB7XG5cdFx0dmFyIHRtcCxcblx0XHRcdGNvdW50ID0gMSxcblx0XHRcdGRlZmVyID0galF1ZXJ5LkRlZmVycmVkKCksXG5cdFx0XHRlbGVtZW50cyA9IHRoaXMsXG5cdFx0XHRpID0gdGhpcy5sZW5ndGgsXG5cdFx0XHRyZXNvbHZlID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggISggLS1jb3VudCApICkge1xuXHRcdFx0XHRcdGRlZmVyLnJlc29sdmVXaXRoKCBlbGVtZW50cywgWyBlbGVtZW50cyBdICk7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cblx0XHRpZiAoIHR5cGVvZiB0eXBlICE9PSBcInN0cmluZ1wiICkge1xuXHRcdFx0b2JqID0gdHlwZTtcblx0XHRcdHR5cGUgPSB1bmRlZmluZWQ7XG5cdFx0fVxuXHRcdHR5cGUgPSB0eXBlIHx8IFwiZnhcIjtcblxuXHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0dG1wID0gZGF0YV9wcml2LmdldCggZWxlbWVudHNbIGkgXSwgdHlwZSArIFwicXVldWVIb29rc1wiICk7XG5cdFx0XHRpZiAoIHRtcCAmJiB0bXAuZW1wdHkgKSB7XG5cdFx0XHRcdGNvdW50Kys7XG5cdFx0XHRcdHRtcC5lbXB0eS5hZGQoIHJlc29sdmUgKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmVzb2x2ZSgpO1xuXHRcdHJldHVybiBkZWZlci5wcm9taXNlKCBvYmogKTtcblx0fVxufSk7XG52YXIgcG51bSA9ICgvWystXT8oPzpcXGQqXFwufClcXGQrKD86W2VFXVsrLV0/XFxkK3wpLykuc291cmNlO1xuXG52YXIgY3NzRXhwYW5kID0gWyBcIlRvcFwiLCBcIlJpZ2h0XCIsIFwiQm90dG9tXCIsIFwiTGVmdFwiIF07XG5cbnZhciBpc0hpZGRlbiA9IGZ1bmN0aW9uKCBlbGVtLCBlbCApIHtcblx0XHQvLyBpc0hpZGRlbiBtaWdodCBiZSBjYWxsZWQgZnJvbSBqUXVlcnkjZmlsdGVyIGZ1bmN0aW9uO1xuXHRcdC8vIGluIHRoYXQgY2FzZSwgZWxlbWVudCB3aWxsIGJlIHNlY29uZCBhcmd1bWVudFxuXHRcdGVsZW0gPSBlbCB8fCBlbGVtO1xuXHRcdHJldHVybiBqUXVlcnkuY3NzKCBlbGVtLCBcImRpc3BsYXlcIiApID09PSBcIm5vbmVcIiB8fCAhalF1ZXJ5LmNvbnRhaW5zKCBlbGVtLm93bmVyRG9jdW1lbnQsIGVsZW0gKTtcblx0fTtcblxudmFyIHJjaGVja2FibGVUeXBlID0gKC9eKD86Y2hlY2tib3h8cmFkaW8pJC9pKTtcblxuXG5cbihmdW5jdGlvbigpIHtcblx0dmFyIGZyYWdtZW50ID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpLFxuXHRcdGRpdiA9IGZyYWdtZW50LmFwcGVuZENoaWxkKCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImRpdlwiICkgKSxcblx0XHRpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiaW5wdXRcIiApO1xuXG5cdC8vIFN1cHBvcnQ6IFNhZmFyaTw9NS4xXG5cdC8vIENoZWNrIHN0YXRlIGxvc3QgaWYgdGhlIG5hbWUgaXMgc2V0ICgjMTEyMTcpXG5cdC8vIFN1cHBvcnQ6IFdpbmRvd3MgV2ViIEFwcHMgKFdXQSlcblx0Ly8gYG5hbWVgIGFuZCBgdHlwZWAgbXVzdCB1c2UgLnNldEF0dHJpYnV0ZSBmb3IgV1dBICgjMTQ5MDEpXG5cdGlucHV0LnNldEF0dHJpYnV0ZSggXCJ0eXBlXCIsIFwicmFkaW9cIiApO1xuXHRpbnB1dC5zZXRBdHRyaWJ1dGUoIFwiY2hlY2tlZFwiLCBcImNoZWNrZWRcIiApO1xuXHRpbnB1dC5zZXRBdHRyaWJ1dGUoIFwibmFtZVwiLCBcInRcIiApO1xuXG5cdGRpdi5hcHBlbmRDaGlsZCggaW5wdXQgKTtcblxuXHQvLyBTdXBwb3J0OiBTYWZhcmk8PTUuMSwgQW5kcm9pZDw0LjJcblx0Ly8gT2xkZXIgV2ViS2l0IGRvZXNuJ3QgY2xvbmUgY2hlY2tlZCBzdGF0ZSBjb3JyZWN0bHkgaW4gZnJhZ21lbnRzXG5cdHN1cHBvcnQuY2hlY2tDbG9uZSA9IGRpdi5jbG9uZU5vZGUoIHRydWUgKS5jbG9uZU5vZGUoIHRydWUgKS5sYXN0Q2hpbGQuY2hlY2tlZDtcblxuXHQvLyBTdXBwb3J0OiBJRTw9MTErXG5cdC8vIE1ha2Ugc3VyZSB0ZXh0YXJlYSAoYW5kIGNoZWNrYm94KSBkZWZhdWx0VmFsdWUgaXMgcHJvcGVybHkgY2xvbmVkXG5cdGRpdi5pbm5lckhUTUwgPSBcIjx0ZXh0YXJlYT54PC90ZXh0YXJlYT5cIjtcblx0c3VwcG9ydC5ub0Nsb25lQ2hlY2tlZCA9ICEhZGl2LmNsb25lTm9kZSggdHJ1ZSApLmxhc3RDaGlsZC5kZWZhdWx0VmFsdWU7XG59KSgpO1xudmFyIHN0cnVuZGVmaW5lZCA9IHR5cGVvZiB1bmRlZmluZWQ7XG5cblxuXG5zdXBwb3J0LmZvY3VzaW5CdWJibGVzID0gXCJvbmZvY3VzaW5cIiBpbiB3aW5kb3c7XG5cblxudmFyXG5cdHJrZXlFdmVudCA9IC9ea2V5Lyxcblx0cm1vdXNlRXZlbnQgPSAvXig/Om1vdXNlfHBvaW50ZXJ8Y29udGV4dG1lbnUpfGNsaWNrLyxcblx0cmZvY3VzTW9ycGggPSAvXig/OmZvY3VzaW5mb2N1c3xmb2N1c291dGJsdXIpJC8sXG5cdHJ0eXBlbmFtZXNwYWNlID0gL14oW14uXSopKD86XFwuKC4rKXwpJC87XG5cbmZ1bmN0aW9uIHJldHVyblRydWUoKSB7XG5cdHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiByZXR1cm5GYWxzZSgpIHtcblx0cmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBzYWZlQWN0aXZlRWxlbWVudCgpIHtcblx0dHJ5IHtcblx0XHRyZXR1cm4gZG9jdW1lbnQuYWN0aXZlRWxlbWVudDtcblx0fSBjYXRjaCAoIGVyciApIHsgfVxufVxuXG4vKlxuICogSGVscGVyIGZ1bmN0aW9ucyBmb3IgbWFuYWdpbmcgZXZlbnRzIC0tIG5vdCBwYXJ0IG9mIHRoZSBwdWJsaWMgaW50ZXJmYWNlLlxuICogUHJvcHMgdG8gRGVhbiBFZHdhcmRzJyBhZGRFdmVudCBsaWJyYXJ5IGZvciBtYW55IG9mIHRoZSBpZGVhcy5cbiAqL1xualF1ZXJ5LmV2ZW50ID0ge1xuXG5cdGdsb2JhbDoge30sXG5cblx0YWRkOiBmdW5jdGlvbiggZWxlbSwgdHlwZXMsIGhhbmRsZXIsIGRhdGEsIHNlbGVjdG9yICkge1xuXG5cdFx0dmFyIGhhbmRsZU9iakluLCBldmVudEhhbmRsZSwgdG1wLFxuXHRcdFx0ZXZlbnRzLCB0LCBoYW5kbGVPYmosXG5cdFx0XHRzcGVjaWFsLCBoYW5kbGVycywgdHlwZSwgbmFtZXNwYWNlcywgb3JpZ1R5cGUsXG5cdFx0XHRlbGVtRGF0YSA9IGRhdGFfcHJpdi5nZXQoIGVsZW0gKTtcblxuXHRcdC8vIERvbid0IGF0dGFjaCBldmVudHMgdG8gbm9EYXRhIG9yIHRleHQvY29tbWVudCBub2RlcyAoYnV0IGFsbG93IHBsYWluIG9iamVjdHMpXG5cdFx0aWYgKCAhZWxlbURhdGEgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gQ2FsbGVyIGNhbiBwYXNzIGluIGFuIG9iamVjdCBvZiBjdXN0b20gZGF0YSBpbiBsaWV1IG9mIHRoZSBoYW5kbGVyXG5cdFx0aWYgKCBoYW5kbGVyLmhhbmRsZXIgKSB7XG5cdFx0XHRoYW5kbGVPYmpJbiA9IGhhbmRsZXI7XG5cdFx0XHRoYW5kbGVyID0gaGFuZGxlT2JqSW4uaGFuZGxlcjtcblx0XHRcdHNlbGVjdG9yID0gaGFuZGxlT2JqSW4uc2VsZWN0b3I7XG5cdFx0fVxuXG5cdFx0Ly8gTWFrZSBzdXJlIHRoYXQgdGhlIGhhbmRsZXIgaGFzIGEgdW5pcXVlIElELCB1c2VkIHRvIGZpbmQvcmVtb3ZlIGl0IGxhdGVyXG5cdFx0aWYgKCAhaGFuZGxlci5ndWlkICkge1xuXHRcdFx0aGFuZGxlci5ndWlkID0galF1ZXJ5Lmd1aWQrKztcblx0XHR9XG5cblx0XHQvLyBJbml0IHRoZSBlbGVtZW50J3MgZXZlbnQgc3RydWN0dXJlIGFuZCBtYWluIGhhbmRsZXIsIGlmIHRoaXMgaXMgdGhlIGZpcnN0XG5cdFx0aWYgKCAhKGV2ZW50cyA9IGVsZW1EYXRhLmV2ZW50cykgKSB7XG5cdFx0XHRldmVudHMgPSBlbGVtRGF0YS5ldmVudHMgPSB7fTtcblx0XHR9XG5cdFx0aWYgKCAhKGV2ZW50SGFuZGxlID0gZWxlbURhdGEuaGFuZGxlKSApIHtcblx0XHRcdGV2ZW50SGFuZGxlID0gZWxlbURhdGEuaGFuZGxlID0gZnVuY3Rpb24oIGUgKSB7XG5cdFx0XHRcdC8vIERpc2NhcmQgdGhlIHNlY29uZCBldmVudCBvZiBhIGpRdWVyeS5ldmVudC50cmlnZ2VyKCkgYW5kXG5cdFx0XHRcdC8vIHdoZW4gYW4gZXZlbnQgaXMgY2FsbGVkIGFmdGVyIGEgcGFnZSBoYXMgdW5sb2FkZWRcblx0XHRcdFx0cmV0dXJuIHR5cGVvZiBqUXVlcnkgIT09IHN0cnVuZGVmaW5lZCAmJiBqUXVlcnkuZXZlbnQudHJpZ2dlcmVkICE9PSBlLnR5cGUgP1xuXHRcdFx0XHRcdGpRdWVyeS5ldmVudC5kaXNwYXRjaC5hcHBseSggZWxlbSwgYXJndW1lbnRzICkgOiB1bmRlZmluZWQ7XG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdC8vIEhhbmRsZSBtdWx0aXBsZSBldmVudHMgc2VwYXJhdGVkIGJ5IGEgc3BhY2Vcblx0XHR0eXBlcyA9ICggdHlwZXMgfHwgXCJcIiApLm1hdGNoKCBybm90d2hpdGUgKSB8fCBbIFwiXCIgXTtcblx0XHR0ID0gdHlwZXMubGVuZ3RoO1xuXHRcdHdoaWxlICggdC0tICkge1xuXHRcdFx0dG1wID0gcnR5cGVuYW1lc3BhY2UuZXhlYyggdHlwZXNbdF0gKSB8fCBbXTtcblx0XHRcdHR5cGUgPSBvcmlnVHlwZSA9IHRtcFsxXTtcblx0XHRcdG5hbWVzcGFjZXMgPSAoIHRtcFsyXSB8fCBcIlwiICkuc3BsaXQoIFwiLlwiICkuc29ydCgpO1xuXG5cdFx0XHQvLyBUaGVyZSAqbXVzdCogYmUgYSB0eXBlLCBubyBhdHRhY2hpbmcgbmFtZXNwYWNlLW9ubHkgaGFuZGxlcnNcblx0XHRcdGlmICggIXR5cGUgKSB7XG5cdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBJZiBldmVudCBjaGFuZ2VzIGl0cyB0eXBlLCB1c2UgdGhlIHNwZWNpYWwgZXZlbnQgaGFuZGxlcnMgZm9yIHRoZSBjaGFuZ2VkIHR5cGVcblx0XHRcdHNwZWNpYWwgPSBqUXVlcnkuZXZlbnQuc3BlY2lhbFsgdHlwZSBdIHx8IHt9O1xuXG5cdFx0XHQvLyBJZiBzZWxlY3RvciBkZWZpbmVkLCBkZXRlcm1pbmUgc3BlY2lhbCBldmVudCBhcGkgdHlwZSwgb3RoZXJ3aXNlIGdpdmVuIHR5cGVcblx0XHRcdHR5cGUgPSAoIHNlbGVjdG9yID8gc3BlY2lhbC5kZWxlZ2F0ZVR5cGUgOiBzcGVjaWFsLmJpbmRUeXBlICkgfHwgdHlwZTtcblxuXHRcdFx0Ly8gVXBkYXRlIHNwZWNpYWwgYmFzZWQgb24gbmV3bHkgcmVzZXQgdHlwZVxuXHRcdFx0c3BlY2lhbCA9IGpRdWVyeS5ldmVudC5zcGVjaWFsWyB0eXBlIF0gfHwge307XG5cblx0XHRcdC8vIGhhbmRsZU9iaiBpcyBwYXNzZWQgdG8gYWxsIGV2ZW50IGhhbmRsZXJzXG5cdFx0XHRoYW5kbGVPYmogPSBqUXVlcnkuZXh0ZW5kKHtcblx0XHRcdFx0dHlwZTogdHlwZSxcblx0XHRcdFx0b3JpZ1R5cGU6IG9yaWdUeXBlLFxuXHRcdFx0XHRkYXRhOiBkYXRhLFxuXHRcdFx0XHRoYW5kbGVyOiBoYW5kbGVyLFxuXHRcdFx0XHRndWlkOiBoYW5kbGVyLmd1aWQsXG5cdFx0XHRcdHNlbGVjdG9yOiBzZWxlY3Rvcixcblx0XHRcdFx0bmVlZHNDb250ZXh0OiBzZWxlY3RvciAmJiBqUXVlcnkuZXhwci5tYXRjaC5uZWVkc0NvbnRleHQudGVzdCggc2VsZWN0b3IgKSxcblx0XHRcdFx0bmFtZXNwYWNlOiBuYW1lc3BhY2VzLmpvaW4oXCIuXCIpXG5cdFx0XHR9LCBoYW5kbGVPYmpJbiApO1xuXG5cdFx0XHQvLyBJbml0IHRoZSBldmVudCBoYW5kbGVyIHF1ZXVlIGlmIHdlJ3JlIHRoZSBmaXJzdFxuXHRcdFx0aWYgKCAhKGhhbmRsZXJzID0gZXZlbnRzWyB0eXBlIF0pICkge1xuXHRcdFx0XHRoYW5kbGVycyA9IGV2ZW50c1sgdHlwZSBdID0gW107XG5cdFx0XHRcdGhhbmRsZXJzLmRlbGVnYXRlQ291bnQgPSAwO1xuXG5cdFx0XHRcdC8vIE9ubHkgdXNlIGFkZEV2ZW50TGlzdGVuZXIgaWYgdGhlIHNwZWNpYWwgZXZlbnRzIGhhbmRsZXIgcmV0dXJucyBmYWxzZVxuXHRcdFx0XHRpZiAoICFzcGVjaWFsLnNldHVwIHx8IHNwZWNpYWwuc2V0dXAuY2FsbCggZWxlbSwgZGF0YSwgbmFtZXNwYWNlcywgZXZlbnRIYW5kbGUgKSA9PT0gZmFsc2UgKSB7XG5cdFx0XHRcdFx0aWYgKCBlbGVtLmFkZEV2ZW50TGlzdGVuZXIgKSB7XG5cdFx0XHRcdFx0XHRlbGVtLmFkZEV2ZW50TGlzdGVuZXIoIHR5cGUsIGV2ZW50SGFuZGxlLCBmYWxzZSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIHNwZWNpYWwuYWRkICkge1xuXHRcdFx0XHRzcGVjaWFsLmFkZC5jYWxsKCBlbGVtLCBoYW5kbGVPYmogKTtcblxuXHRcdFx0XHRpZiAoICFoYW5kbGVPYmouaGFuZGxlci5ndWlkICkge1xuXHRcdFx0XHRcdGhhbmRsZU9iai5oYW5kbGVyLmd1aWQgPSBoYW5kbGVyLmd1aWQ7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gQWRkIHRvIHRoZSBlbGVtZW50J3MgaGFuZGxlciBsaXN0LCBkZWxlZ2F0ZXMgaW4gZnJvbnRcblx0XHRcdGlmICggc2VsZWN0b3IgKSB7XG5cdFx0XHRcdGhhbmRsZXJzLnNwbGljZSggaGFuZGxlcnMuZGVsZWdhdGVDb3VudCsrLCAwLCBoYW5kbGVPYmogKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGhhbmRsZXJzLnB1c2goIGhhbmRsZU9iaiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBLZWVwIHRyYWNrIG9mIHdoaWNoIGV2ZW50cyBoYXZlIGV2ZXIgYmVlbiB1c2VkLCBmb3IgZXZlbnQgb3B0aW1pemF0aW9uXG5cdFx0XHRqUXVlcnkuZXZlbnQuZ2xvYmFsWyB0eXBlIF0gPSB0cnVlO1xuXHRcdH1cblxuXHR9LFxuXG5cdC8vIERldGFjaCBhbiBldmVudCBvciBzZXQgb2YgZXZlbnRzIGZyb20gYW4gZWxlbWVudFxuXHRyZW1vdmU6IGZ1bmN0aW9uKCBlbGVtLCB0eXBlcywgaGFuZGxlciwgc2VsZWN0b3IsIG1hcHBlZFR5cGVzICkge1xuXG5cdFx0dmFyIGosIG9yaWdDb3VudCwgdG1wLFxuXHRcdFx0ZXZlbnRzLCB0LCBoYW5kbGVPYmosXG5cdFx0XHRzcGVjaWFsLCBoYW5kbGVycywgdHlwZSwgbmFtZXNwYWNlcywgb3JpZ1R5cGUsXG5cdFx0XHRlbGVtRGF0YSA9IGRhdGFfcHJpdi5oYXNEYXRhKCBlbGVtICkgJiYgZGF0YV9wcml2LmdldCggZWxlbSApO1xuXG5cdFx0aWYgKCAhZWxlbURhdGEgfHwgIShldmVudHMgPSBlbGVtRGF0YS5ldmVudHMpICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIE9uY2UgZm9yIGVhY2ggdHlwZS5uYW1lc3BhY2UgaW4gdHlwZXM7IHR5cGUgbWF5IGJlIG9taXR0ZWRcblx0XHR0eXBlcyA9ICggdHlwZXMgfHwgXCJcIiApLm1hdGNoKCBybm90d2hpdGUgKSB8fCBbIFwiXCIgXTtcblx0XHR0ID0gdHlwZXMubGVuZ3RoO1xuXHRcdHdoaWxlICggdC0tICkge1xuXHRcdFx0dG1wID0gcnR5cGVuYW1lc3BhY2UuZXhlYyggdHlwZXNbdF0gKSB8fCBbXTtcblx0XHRcdHR5cGUgPSBvcmlnVHlwZSA9IHRtcFsxXTtcblx0XHRcdG5hbWVzcGFjZXMgPSAoIHRtcFsyXSB8fCBcIlwiICkuc3BsaXQoIFwiLlwiICkuc29ydCgpO1xuXG5cdFx0XHQvLyBVbmJpbmQgYWxsIGV2ZW50cyAob24gdGhpcyBuYW1lc3BhY2UsIGlmIHByb3ZpZGVkKSBmb3IgdGhlIGVsZW1lbnRcblx0XHRcdGlmICggIXR5cGUgKSB7XG5cdFx0XHRcdGZvciAoIHR5cGUgaW4gZXZlbnRzICkge1xuXHRcdFx0XHRcdGpRdWVyeS5ldmVudC5yZW1vdmUoIGVsZW0sIHR5cGUgKyB0eXBlc1sgdCBdLCBoYW5kbGVyLCBzZWxlY3RvciwgdHJ1ZSApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0fVxuXG5cdFx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWxbIHR5cGUgXSB8fCB7fTtcblx0XHRcdHR5cGUgPSAoIHNlbGVjdG9yID8gc3BlY2lhbC5kZWxlZ2F0ZVR5cGUgOiBzcGVjaWFsLmJpbmRUeXBlICkgfHwgdHlwZTtcblx0XHRcdGhhbmRsZXJzID0gZXZlbnRzWyB0eXBlIF0gfHwgW107XG5cdFx0XHR0bXAgPSB0bXBbMl0gJiYgbmV3IFJlZ0V4cCggXCIoXnxcXFxcLilcIiArIG5hbWVzcGFjZXMuam9pbihcIlxcXFwuKD86LipcXFxcLnwpXCIpICsgXCIoXFxcXC58JClcIiApO1xuXG5cdFx0XHQvLyBSZW1vdmUgbWF0Y2hpbmcgZXZlbnRzXG5cdFx0XHRvcmlnQ291bnQgPSBqID0gaGFuZGxlcnMubGVuZ3RoO1xuXHRcdFx0d2hpbGUgKCBqLS0gKSB7XG5cdFx0XHRcdGhhbmRsZU9iaiA9IGhhbmRsZXJzWyBqIF07XG5cblx0XHRcdFx0aWYgKCAoIG1hcHBlZFR5cGVzIHx8IG9yaWdUeXBlID09PSBoYW5kbGVPYmoub3JpZ1R5cGUgKSAmJlxuXHRcdFx0XHRcdCggIWhhbmRsZXIgfHwgaGFuZGxlci5ndWlkID09PSBoYW5kbGVPYmouZ3VpZCApICYmXG5cdFx0XHRcdFx0KCAhdG1wIHx8IHRtcC50ZXN0KCBoYW5kbGVPYmoubmFtZXNwYWNlICkgKSAmJlxuXHRcdFx0XHRcdCggIXNlbGVjdG9yIHx8IHNlbGVjdG9yID09PSBoYW5kbGVPYmouc2VsZWN0b3IgfHwgc2VsZWN0b3IgPT09IFwiKipcIiAmJiBoYW5kbGVPYmouc2VsZWN0b3IgKSApIHtcblx0XHRcdFx0XHRoYW5kbGVycy5zcGxpY2UoIGosIDEgKTtcblxuXHRcdFx0XHRcdGlmICggaGFuZGxlT2JqLnNlbGVjdG9yICkge1xuXHRcdFx0XHRcdFx0aGFuZGxlcnMuZGVsZWdhdGVDb3VudC0tO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZiAoIHNwZWNpYWwucmVtb3ZlICkge1xuXHRcdFx0XHRcdFx0c3BlY2lhbC5yZW1vdmUuY2FsbCggZWxlbSwgaGFuZGxlT2JqICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIFJlbW92ZSBnZW5lcmljIGV2ZW50IGhhbmRsZXIgaWYgd2UgcmVtb3ZlZCBzb21ldGhpbmcgYW5kIG5vIG1vcmUgaGFuZGxlcnMgZXhpc3Rcblx0XHRcdC8vIChhdm9pZHMgcG90ZW50aWFsIGZvciBlbmRsZXNzIHJlY3Vyc2lvbiBkdXJpbmcgcmVtb3ZhbCBvZiBzcGVjaWFsIGV2ZW50IGhhbmRsZXJzKVxuXHRcdFx0aWYgKCBvcmlnQ291bnQgJiYgIWhhbmRsZXJzLmxlbmd0aCApIHtcblx0XHRcdFx0aWYgKCAhc3BlY2lhbC50ZWFyZG93biB8fCBzcGVjaWFsLnRlYXJkb3duLmNhbGwoIGVsZW0sIG5hbWVzcGFjZXMsIGVsZW1EYXRhLmhhbmRsZSApID09PSBmYWxzZSApIHtcblx0XHRcdFx0XHRqUXVlcnkucmVtb3ZlRXZlbnQoIGVsZW0sIHR5cGUsIGVsZW1EYXRhLmhhbmRsZSApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0ZGVsZXRlIGV2ZW50c1sgdHlwZSBdO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFJlbW92ZSB0aGUgZXhwYW5kbyBpZiBpdCdzIG5vIGxvbmdlciB1c2VkXG5cdFx0aWYgKCBqUXVlcnkuaXNFbXB0eU9iamVjdCggZXZlbnRzICkgKSB7XG5cdFx0XHRkZWxldGUgZWxlbURhdGEuaGFuZGxlO1xuXHRcdFx0ZGF0YV9wcml2LnJlbW92ZSggZWxlbSwgXCJldmVudHNcIiApO1xuXHRcdH1cblx0fSxcblxuXHR0cmlnZ2VyOiBmdW5jdGlvbiggZXZlbnQsIGRhdGEsIGVsZW0sIG9ubHlIYW5kbGVycyApIHtcblxuXHRcdHZhciBpLCBjdXIsIHRtcCwgYnViYmxlVHlwZSwgb250eXBlLCBoYW5kbGUsIHNwZWNpYWwsXG5cdFx0XHRldmVudFBhdGggPSBbIGVsZW0gfHwgZG9jdW1lbnQgXSxcblx0XHRcdHR5cGUgPSBoYXNPd24uY2FsbCggZXZlbnQsIFwidHlwZVwiICkgPyBldmVudC50eXBlIDogZXZlbnQsXG5cdFx0XHRuYW1lc3BhY2VzID0gaGFzT3duLmNhbGwoIGV2ZW50LCBcIm5hbWVzcGFjZVwiICkgPyBldmVudC5uYW1lc3BhY2Uuc3BsaXQoXCIuXCIpIDogW107XG5cblx0XHRjdXIgPSB0bXAgPSBlbGVtID0gZWxlbSB8fCBkb2N1bWVudDtcblxuXHRcdC8vIERvbid0IGRvIGV2ZW50cyBvbiB0ZXh0IGFuZCBjb21tZW50IG5vZGVzXG5cdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAzIHx8IGVsZW0ubm9kZVR5cGUgPT09IDggKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gZm9jdXMvYmx1ciBtb3JwaHMgdG8gZm9jdXNpbi9vdXQ7IGVuc3VyZSB3ZSdyZSBub3QgZmlyaW5nIHRoZW0gcmlnaHQgbm93XG5cdFx0aWYgKCByZm9jdXNNb3JwaC50ZXN0KCB0eXBlICsgalF1ZXJ5LmV2ZW50LnRyaWdnZXJlZCApICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmICggdHlwZS5pbmRleE9mKFwiLlwiKSA+PSAwICkge1xuXHRcdFx0Ly8gTmFtZXNwYWNlZCB0cmlnZ2VyOyBjcmVhdGUgYSByZWdleHAgdG8gbWF0Y2ggZXZlbnQgdHlwZSBpbiBoYW5kbGUoKVxuXHRcdFx0bmFtZXNwYWNlcyA9IHR5cGUuc3BsaXQoXCIuXCIpO1xuXHRcdFx0dHlwZSA9IG5hbWVzcGFjZXMuc2hpZnQoKTtcblx0XHRcdG5hbWVzcGFjZXMuc29ydCgpO1xuXHRcdH1cblx0XHRvbnR5cGUgPSB0eXBlLmluZGV4T2YoXCI6XCIpIDwgMCAmJiBcIm9uXCIgKyB0eXBlO1xuXG5cdFx0Ly8gQ2FsbGVyIGNhbiBwYXNzIGluIGEgalF1ZXJ5LkV2ZW50IG9iamVjdCwgT2JqZWN0LCBvciBqdXN0IGFuIGV2ZW50IHR5cGUgc3RyaW5nXG5cdFx0ZXZlbnQgPSBldmVudFsgalF1ZXJ5LmV4cGFuZG8gXSA/XG5cdFx0XHRldmVudCA6XG5cdFx0XHRuZXcgalF1ZXJ5LkV2ZW50KCB0eXBlLCB0eXBlb2YgZXZlbnQgPT09IFwib2JqZWN0XCIgJiYgZXZlbnQgKTtcblxuXHRcdC8vIFRyaWdnZXIgYml0bWFzazogJiAxIGZvciBuYXRpdmUgaGFuZGxlcnM7ICYgMiBmb3IgalF1ZXJ5IChhbHdheXMgdHJ1ZSlcblx0XHRldmVudC5pc1RyaWdnZXIgPSBvbmx5SGFuZGxlcnMgPyAyIDogMztcblx0XHRldmVudC5uYW1lc3BhY2UgPSBuYW1lc3BhY2VzLmpvaW4oXCIuXCIpO1xuXHRcdGV2ZW50Lm5hbWVzcGFjZV9yZSA9IGV2ZW50Lm5hbWVzcGFjZSA/XG5cdFx0XHRuZXcgUmVnRXhwKCBcIihefFxcXFwuKVwiICsgbmFtZXNwYWNlcy5qb2luKFwiXFxcXC4oPzouKlxcXFwufClcIikgKyBcIihcXFxcLnwkKVwiICkgOlxuXHRcdFx0bnVsbDtcblxuXHRcdC8vIENsZWFuIHVwIHRoZSBldmVudCBpbiBjYXNlIGl0IGlzIGJlaW5nIHJldXNlZFxuXHRcdGV2ZW50LnJlc3VsdCA9IHVuZGVmaW5lZDtcblx0XHRpZiAoICFldmVudC50YXJnZXQgKSB7XG5cdFx0XHRldmVudC50YXJnZXQgPSBlbGVtO1xuXHRcdH1cblxuXHRcdC8vIENsb25lIGFueSBpbmNvbWluZyBkYXRhIGFuZCBwcmVwZW5kIHRoZSBldmVudCwgY3JlYXRpbmcgdGhlIGhhbmRsZXIgYXJnIGxpc3Rcblx0XHRkYXRhID0gZGF0YSA9PSBudWxsID9cblx0XHRcdFsgZXZlbnQgXSA6XG5cdFx0XHRqUXVlcnkubWFrZUFycmF5KCBkYXRhLCBbIGV2ZW50IF0gKTtcblxuXHRcdC8vIEFsbG93IHNwZWNpYWwgZXZlbnRzIHRvIGRyYXcgb3V0c2lkZSB0aGUgbGluZXNcblx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWxbIHR5cGUgXSB8fCB7fTtcblx0XHRpZiAoICFvbmx5SGFuZGxlcnMgJiYgc3BlY2lhbC50cmlnZ2VyICYmIHNwZWNpYWwudHJpZ2dlci5hcHBseSggZWxlbSwgZGF0YSApID09PSBmYWxzZSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBEZXRlcm1pbmUgZXZlbnQgcHJvcGFnYXRpb24gcGF0aCBpbiBhZHZhbmNlLCBwZXIgVzNDIGV2ZW50cyBzcGVjICgjOTk1MSlcblx0XHQvLyBCdWJibGUgdXAgdG8gZG9jdW1lbnQsIHRoZW4gdG8gd2luZG93OyB3YXRjaCBmb3IgYSBnbG9iYWwgb3duZXJEb2N1bWVudCB2YXIgKCM5NzI0KVxuXHRcdGlmICggIW9ubHlIYW5kbGVycyAmJiAhc3BlY2lhbC5ub0J1YmJsZSAmJiAhalF1ZXJ5LmlzV2luZG93KCBlbGVtICkgKSB7XG5cblx0XHRcdGJ1YmJsZVR5cGUgPSBzcGVjaWFsLmRlbGVnYXRlVHlwZSB8fCB0eXBlO1xuXHRcdFx0aWYgKCAhcmZvY3VzTW9ycGgudGVzdCggYnViYmxlVHlwZSArIHR5cGUgKSApIHtcblx0XHRcdFx0Y3VyID0gY3VyLnBhcmVudE5vZGU7XG5cdFx0XHR9XG5cdFx0XHRmb3IgKCA7IGN1cjsgY3VyID0gY3VyLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdGV2ZW50UGF0aC5wdXNoKCBjdXIgKTtcblx0XHRcdFx0dG1wID0gY3VyO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBPbmx5IGFkZCB3aW5kb3cgaWYgd2UgZ290IHRvIGRvY3VtZW50IChlLmcuLCBub3QgcGxhaW4gb2JqIG9yIGRldGFjaGVkIERPTSlcblx0XHRcdGlmICggdG1wID09PSAoZWxlbS5vd25lckRvY3VtZW50IHx8IGRvY3VtZW50KSApIHtcblx0XHRcdFx0ZXZlbnRQYXRoLnB1c2goIHRtcC5kZWZhdWx0VmlldyB8fCB0bXAucGFyZW50V2luZG93IHx8IHdpbmRvdyApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIEZpcmUgaGFuZGxlcnMgb24gdGhlIGV2ZW50IHBhdGhcblx0XHRpID0gMDtcblx0XHR3aGlsZSAoIChjdXIgPSBldmVudFBhdGhbaSsrXSkgJiYgIWV2ZW50LmlzUHJvcGFnYXRpb25TdG9wcGVkKCkgKSB7XG5cblx0XHRcdGV2ZW50LnR5cGUgPSBpID4gMSA/XG5cdFx0XHRcdGJ1YmJsZVR5cGUgOlxuXHRcdFx0XHRzcGVjaWFsLmJpbmRUeXBlIHx8IHR5cGU7XG5cblx0XHRcdC8vIGpRdWVyeSBoYW5kbGVyXG5cdFx0XHRoYW5kbGUgPSAoIGRhdGFfcHJpdi5nZXQoIGN1ciwgXCJldmVudHNcIiApIHx8IHt9IClbIGV2ZW50LnR5cGUgXSAmJiBkYXRhX3ByaXYuZ2V0KCBjdXIsIFwiaGFuZGxlXCIgKTtcblx0XHRcdGlmICggaGFuZGxlICkge1xuXHRcdFx0XHRoYW5kbGUuYXBwbHkoIGN1ciwgZGF0YSApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBOYXRpdmUgaGFuZGxlclxuXHRcdFx0aGFuZGxlID0gb250eXBlICYmIGN1clsgb250eXBlIF07XG5cdFx0XHRpZiAoIGhhbmRsZSAmJiBoYW5kbGUuYXBwbHkgJiYgalF1ZXJ5LmFjY2VwdERhdGEoIGN1ciApICkge1xuXHRcdFx0XHRldmVudC5yZXN1bHQgPSBoYW5kbGUuYXBwbHkoIGN1ciwgZGF0YSApO1xuXHRcdFx0XHRpZiAoIGV2ZW50LnJlc3VsdCA9PT0gZmFsc2UgKSB7XG5cdFx0XHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XHRldmVudC50eXBlID0gdHlwZTtcblxuXHRcdC8vIElmIG5vYm9keSBwcmV2ZW50ZWQgdGhlIGRlZmF1bHQgYWN0aW9uLCBkbyBpdCBub3dcblx0XHRpZiAoICFvbmx5SGFuZGxlcnMgJiYgIWV2ZW50LmlzRGVmYXVsdFByZXZlbnRlZCgpICkge1xuXG5cdFx0XHRpZiAoICghc3BlY2lhbC5fZGVmYXVsdCB8fCBzcGVjaWFsLl9kZWZhdWx0LmFwcGx5KCBldmVudFBhdGgucG9wKCksIGRhdGEgKSA9PT0gZmFsc2UpICYmXG5cdFx0XHRcdGpRdWVyeS5hY2NlcHREYXRhKCBlbGVtICkgKSB7XG5cblx0XHRcdFx0Ly8gQ2FsbCBhIG5hdGl2ZSBET00gbWV0aG9kIG9uIHRoZSB0YXJnZXQgd2l0aCB0aGUgc2FtZSBuYW1lIG5hbWUgYXMgdGhlIGV2ZW50LlxuXHRcdFx0XHQvLyBEb24ndCBkbyBkZWZhdWx0IGFjdGlvbnMgb24gd2luZG93LCB0aGF0J3Mgd2hlcmUgZ2xvYmFsIHZhcmlhYmxlcyBiZSAoIzYxNzApXG5cdFx0XHRcdGlmICggb250eXBlICYmIGpRdWVyeS5pc0Z1bmN0aW9uKCBlbGVtWyB0eXBlIF0gKSAmJiAhalF1ZXJ5LmlzV2luZG93KCBlbGVtICkgKSB7XG5cblx0XHRcdFx0XHQvLyBEb24ndCByZS10cmlnZ2VyIGFuIG9uRk9PIGV2ZW50IHdoZW4gd2UgY2FsbCBpdHMgRk9PKCkgbWV0aG9kXG5cdFx0XHRcdFx0dG1wID0gZWxlbVsgb250eXBlIF07XG5cblx0XHRcdFx0XHRpZiAoIHRtcCApIHtcblx0XHRcdFx0XHRcdGVsZW1bIG9udHlwZSBdID0gbnVsbDtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBQcmV2ZW50IHJlLXRyaWdnZXJpbmcgb2YgdGhlIHNhbWUgZXZlbnQsIHNpbmNlIHdlIGFscmVhZHkgYnViYmxlZCBpdCBhYm92ZVxuXHRcdFx0XHRcdGpRdWVyeS5ldmVudC50cmlnZ2VyZWQgPSB0eXBlO1xuXHRcdFx0XHRcdGVsZW1bIHR5cGUgXSgpO1xuXHRcdFx0XHRcdGpRdWVyeS5ldmVudC50cmlnZ2VyZWQgPSB1bmRlZmluZWQ7XG5cblx0XHRcdFx0XHRpZiAoIHRtcCApIHtcblx0XHRcdFx0XHRcdGVsZW1bIG9udHlwZSBdID0gdG1wO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBldmVudC5yZXN1bHQ7XG5cdH0sXG5cblx0ZGlzcGF0Y2g6IGZ1bmN0aW9uKCBldmVudCApIHtcblxuXHRcdC8vIE1ha2UgYSB3cml0YWJsZSBqUXVlcnkuRXZlbnQgZnJvbSB0aGUgbmF0aXZlIGV2ZW50IG9iamVjdFxuXHRcdGV2ZW50ID0galF1ZXJ5LmV2ZW50LmZpeCggZXZlbnQgKTtcblxuXHRcdHZhciBpLCBqLCByZXQsIG1hdGNoZWQsIGhhbmRsZU9iaixcblx0XHRcdGhhbmRsZXJRdWV1ZSA9IFtdLFxuXHRcdFx0YXJncyA9IHNsaWNlLmNhbGwoIGFyZ3VtZW50cyApLFxuXHRcdFx0aGFuZGxlcnMgPSAoIGRhdGFfcHJpdi5nZXQoIHRoaXMsIFwiZXZlbnRzXCIgKSB8fCB7fSApWyBldmVudC50eXBlIF0gfHwgW10sXG5cdFx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWxbIGV2ZW50LnR5cGUgXSB8fCB7fTtcblxuXHRcdC8vIFVzZSB0aGUgZml4LWVkIGpRdWVyeS5FdmVudCByYXRoZXIgdGhhbiB0aGUgKHJlYWQtb25seSkgbmF0aXZlIGV2ZW50XG5cdFx0YXJnc1swXSA9IGV2ZW50O1xuXHRcdGV2ZW50LmRlbGVnYXRlVGFyZ2V0ID0gdGhpcztcblxuXHRcdC8vIENhbGwgdGhlIHByZURpc3BhdGNoIGhvb2sgZm9yIHRoZSBtYXBwZWQgdHlwZSwgYW5kIGxldCBpdCBiYWlsIGlmIGRlc2lyZWRcblx0XHRpZiAoIHNwZWNpYWwucHJlRGlzcGF0Y2ggJiYgc3BlY2lhbC5wcmVEaXNwYXRjaC5jYWxsKCB0aGlzLCBldmVudCApID09PSBmYWxzZSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBEZXRlcm1pbmUgaGFuZGxlcnNcblx0XHRoYW5kbGVyUXVldWUgPSBqUXVlcnkuZXZlbnQuaGFuZGxlcnMuY2FsbCggdGhpcywgZXZlbnQsIGhhbmRsZXJzICk7XG5cblx0XHQvLyBSdW4gZGVsZWdhdGVzIGZpcnN0OyB0aGV5IG1heSB3YW50IHRvIHN0b3AgcHJvcGFnYXRpb24gYmVuZWF0aCB1c1xuXHRcdGkgPSAwO1xuXHRcdHdoaWxlICggKG1hdGNoZWQgPSBoYW5kbGVyUXVldWVbIGkrKyBdKSAmJiAhZXZlbnQuaXNQcm9wYWdhdGlvblN0b3BwZWQoKSApIHtcblx0XHRcdGV2ZW50LmN1cnJlbnRUYXJnZXQgPSBtYXRjaGVkLmVsZW07XG5cblx0XHRcdGogPSAwO1xuXHRcdFx0d2hpbGUgKCAoaGFuZGxlT2JqID0gbWF0Y2hlZC5oYW5kbGVyc1sgaisrIF0pICYmICFldmVudC5pc0ltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZCgpICkge1xuXG5cdFx0XHRcdC8vIFRyaWdnZXJlZCBldmVudCBtdXN0IGVpdGhlciAxKSBoYXZlIG5vIG5hbWVzcGFjZSwgb3IgMikgaGF2ZSBuYW1lc3BhY2Uocylcblx0XHRcdFx0Ly8gYSBzdWJzZXQgb3IgZXF1YWwgdG8gdGhvc2UgaW4gdGhlIGJvdW5kIGV2ZW50IChib3RoIGNhbiBoYXZlIG5vIG5hbWVzcGFjZSkuXG5cdFx0XHRcdGlmICggIWV2ZW50Lm5hbWVzcGFjZV9yZSB8fCBldmVudC5uYW1lc3BhY2VfcmUudGVzdCggaGFuZGxlT2JqLm5hbWVzcGFjZSApICkge1xuXG5cdFx0XHRcdFx0ZXZlbnQuaGFuZGxlT2JqID0gaGFuZGxlT2JqO1xuXHRcdFx0XHRcdGV2ZW50LmRhdGEgPSBoYW5kbGVPYmouZGF0YTtcblxuXHRcdFx0XHRcdHJldCA9ICggKGpRdWVyeS5ldmVudC5zcGVjaWFsWyBoYW5kbGVPYmoub3JpZ1R5cGUgXSB8fCB7fSkuaGFuZGxlIHx8IGhhbmRsZU9iai5oYW5kbGVyIClcblx0XHRcdFx0XHRcdFx0LmFwcGx5KCBtYXRjaGVkLmVsZW0sIGFyZ3MgKTtcblxuXHRcdFx0XHRcdGlmICggcmV0ICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0XHRpZiAoIChldmVudC5yZXN1bHQgPSByZXQpID09PSBmYWxzZSApIHtcblx0XHRcdFx0XHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0XHRcdFx0ZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gQ2FsbCB0aGUgcG9zdERpc3BhdGNoIGhvb2sgZm9yIHRoZSBtYXBwZWQgdHlwZVxuXHRcdGlmICggc3BlY2lhbC5wb3N0RGlzcGF0Y2ggKSB7XG5cdFx0XHRzcGVjaWFsLnBvc3REaXNwYXRjaC5jYWxsKCB0aGlzLCBldmVudCApO1xuXHRcdH1cblxuXHRcdHJldHVybiBldmVudC5yZXN1bHQ7XG5cdH0sXG5cblx0aGFuZGxlcnM6IGZ1bmN0aW9uKCBldmVudCwgaGFuZGxlcnMgKSB7XG5cdFx0dmFyIGksIG1hdGNoZXMsIHNlbCwgaGFuZGxlT2JqLFxuXHRcdFx0aGFuZGxlclF1ZXVlID0gW10sXG5cdFx0XHRkZWxlZ2F0ZUNvdW50ID0gaGFuZGxlcnMuZGVsZWdhdGVDb3VudCxcblx0XHRcdGN1ciA9IGV2ZW50LnRhcmdldDtcblxuXHRcdC8vIEZpbmQgZGVsZWdhdGUgaGFuZGxlcnNcblx0XHQvLyBCbGFjay1ob2xlIFNWRyA8dXNlPiBpbnN0YW5jZSB0cmVlcyAoIzEzMTgwKVxuXHRcdC8vIEF2b2lkIG5vbi1sZWZ0LWNsaWNrIGJ1YmJsaW5nIGluIEZpcmVmb3ggKCMzODYxKVxuXHRcdGlmICggZGVsZWdhdGVDb3VudCAmJiBjdXIubm9kZVR5cGUgJiYgKCFldmVudC5idXR0b24gfHwgZXZlbnQudHlwZSAhPT0gXCJjbGlja1wiKSApIHtcblxuXHRcdFx0Zm9yICggOyBjdXIgIT09IHRoaXM7IGN1ciA9IGN1ci5wYXJlbnROb2RlIHx8IHRoaXMgKSB7XG5cblx0XHRcdFx0Ly8gRG9uJ3QgcHJvY2VzcyBjbGlja3Mgb24gZGlzYWJsZWQgZWxlbWVudHMgKCM2OTExLCAjODE2NSwgIzExMzgyLCAjMTE3NjQpXG5cdFx0XHRcdGlmICggY3VyLmRpc2FibGVkICE9PSB0cnVlIHx8IGV2ZW50LnR5cGUgIT09IFwiY2xpY2tcIiApIHtcblx0XHRcdFx0XHRtYXRjaGVzID0gW107XG5cdFx0XHRcdFx0Zm9yICggaSA9IDA7IGkgPCBkZWxlZ2F0ZUNvdW50OyBpKysgKSB7XG5cdFx0XHRcdFx0XHRoYW5kbGVPYmogPSBoYW5kbGVyc1sgaSBdO1xuXG5cdFx0XHRcdFx0XHQvLyBEb24ndCBjb25mbGljdCB3aXRoIE9iamVjdC5wcm90b3R5cGUgcHJvcGVydGllcyAoIzEzMjAzKVxuXHRcdFx0XHRcdFx0c2VsID0gaGFuZGxlT2JqLnNlbGVjdG9yICsgXCIgXCI7XG5cblx0XHRcdFx0XHRcdGlmICggbWF0Y2hlc1sgc2VsIF0gPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHRcdFx0bWF0Y2hlc1sgc2VsIF0gPSBoYW5kbGVPYmoubmVlZHNDb250ZXh0ID9cblx0XHRcdFx0XHRcdFx0XHRqUXVlcnkoIHNlbCwgdGhpcyApLmluZGV4KCBjdXIgKSA+PSAwIDpcblx0XHRcdFx0XHRcdFx0XHRqUXVlcnkuZmluZCggc2VsLCB0aGlzLCBudWxsLCBbIGN1ciBdICkubGVuZ3RoO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0aWYgKCBtYXRjaGVzWyBzZWwgXSApIHtcblx0XHRcdFx0XHRcdFx0bWF0Y2hlcy5wdXNoKCBoYW5kbGVPYmogKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKCBtYXRjaGVzLmxlbmd0aCApIHtcblx0XHRcdFx0XHRcdGhhbmRsZXJRdWV1ZS5wdXNoKHsgZWxlbTogY3VyLCBoYW5kbGVyczogbWF0Y2hlcyB9KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBBZGQgdGhlIHJlbWFpbmluZyAoZGlyZWN0bHktYm91bmQpIGhhbmRsZXJzXG5cdFx0aWYgKCBkZWxlZ2F0ZUNvdW50IDwgaGFuZGxlcnMubGVuZ3RoICkge1xuXHRcdFx0aGFuZGxlclF1ZXVlLnB1c2goeyBlbGVtOiB0aGlzLCBoYW5kbGVyczogaGFuZGxlcnMuc2xpY2UoIGRlbGVnYXRlQ291bnQgKSB9KTtcblx0XHR9XG5cblx0XHRyZXR1cm4gaGFuZGxlclF1ZXVlO1xuXHR9LFxuXG5cdC8vIEluY2x1ZGVzIHNvbWUgZXZlbnQgcHJvcHMgc2hhcmVkIGJ5IEtleUV2ZW50IGFuZCBNb3VzZUV2ZW50XG5cdHByb3BzOiBcImFsdEtleSBidWJibGVzIGNhbmNlbGFibGUgY3RybEtleSBjdXJyZW50VGFyZ2V0IGV2ZW50UGhhc2UgbWV0YUtleSByZWxhdGVkVGFyZ2V0IHNoaWZ0S2V5IHRhcmdldCB0aW1lU3RhbXAgdmlldyB3aGljaFwiLnNwbGl0KFwiIFwiKSxcblxuXHRmaXhIb29rczoge30sXG5cblx0a2V5SG9va3M6IHtcblx0XHRwcm9wczogXCJjaGFyIGNoYXJDb2RlIGtleSBrZXlDb2RlXCIuc3BsaXQoXCIgXCIpLFxuXHRcdGZpbHRlcjogZnVuY3Rpb24oIGV2ZW50LCBvcmlnaW5hbCApIHtcblxuXHRcdFx0Ly8gQWRkIHdoaWNoIGZvciBrZXkgZXZlbnRzXG5cdFx0XHRpZiAoIGV2ZW50LndoaWNoID09IG51bGwgKSB7XG5cdFx0XHRcdGV2ZW50LndoaWNoID0gb3JpZ2luYWwuY2hhckNvZGUgIT0gbnVsbCA/IG9yaWdpbmFsLmNoYXJDb2RlIDogb3JpZ2luYWwua2V5Q29kZTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGV2ZW50O1xuXHRcdH1cblx0fSxcblxuXHRtb3VzZUhvb2tzOiB7XG5cdFx0cHJvcHM6IFwiYnV0dG9uIGJ1dHRvbnMgY2xpZW50WCBjbGllbnRZIG9mZnNldFggb2Zmc2V0WSBwYWdlWCBwYWdlWSBzY3JlZW5YIHNjcmVlblkgdG9FbGVtZW50XCIuc3BsaXQoXCIgXCIpLFxuXHRcdGZpbHRlcjogZnVuY3Rpb24oIGV2ZW50LCBvcmlnaW5hbCApIHtcblx0XHRcdHZhciBldmVudERvYywgZG9jLCBib2R5LFxuXHRcdFx0XHRidXR0b24gPSBvcmlnaW5hbC5idXR0b247XG5cblx0XHRcdC8vIENhbGN1bGF0ZSBwYWdlWC9ZIGlmIG1pc3NpbmcgYW5kIGNsaWVudFgvWSBhdmFpbGFibGVcblx0XHRcdGlmICggZXZlbnQucGFnZVggPT0gbnVsbCAmJiBvcmlnaW5hbC5jbGllbnRYICE9IG51bGwgKSB7XG5cdFx0XHRcdGV2ZW50RG9jID0gZXZlbnQudGFyZ2V0Lm93bmVyRG9jdW1lbnQgfHwgZG9jdW1lbnQ7XG5cdFx0XHRcdGRvYyA9IGV2ZW50RG9jLmRvY3VtZW50RWxlbWVudDtcblx0XHRcdFx0Ym9keSA9IGV2ZW50RG9jLmJvZHk7XG5cblx0XHRcdFx0ZXZlbnQucGFnZVggPSBvcmlnaW5hbC5jbGllbnRYICsgKCBkb2MgJiYgZG9jLnNjcm9sbExlZnQgfHwgYm9keSAmJiBib2R5LnNjcm9sbExlZnQgfHwgMCApIC0gKCBkb2MgJiYgZG9jLmNsaWVudExlZnQgfHwgYm9keSAmJiBib2R5LmNsaWVudExlZnQgfHwgMCApO1xuXHRcdFx0XHRldmVudC5wYWdlWSA9IG9yaWdpbmFsLmNsaWVudFkgKyAoIGRvYyAmJiBkb2Muc2Nyb2xsVG9wICB8fCBib2R5ICYmIGJvZHkuc2Nyb2xsVG9wICB8fCAwICkgLSAoIGRvYyAmJiBkb2MuY2xpZW50VG9wICB8fCBib2R5ICYmIGJvZHkuY2xpZW50VG9wICB8fCAwICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEFkZCB3aGljaCBmb3IgY2xpY2s6IDEgPT09IGxlZnQ7IDIgPT09IG1pZGRsZTsgMyA9PT0gcmlnaHRcblx0XHRcdC8vIE5vdGU6IGJ1dHRvbiBpcyBub3Qgbm9ybWFsaXplZCwgc28gZG9uJ3QgdXNlIGl0XG5cdFx0XHRpZiAoICFldmVudC53aGljaCAmJiBidXR0b24gIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0ZXZlbnQud2hpY2ggPSAoIGJ1dHRvbiAmIDEgPyAxIDogKCBidXR0b24gJiAyID8gMyA6ICggYnV0dG9uICYgNCA/IDIgOiAwICkgKSApO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZXZlbnQ7XG5cdFx0fVxuXHR9LFxuXG5cdGZpeDogZnVuY3Rpb24oIGV2ZW50ICkge1xuXHRcdGlmICggZXZlbnRbIGpRdWVyeS5leHBhbmRvIF0gKSB7XG5cdFx0XHRyZXR1cm4gZXZlbnQ7XG5cdFx0fVxuXG5cdFx0Ly8gQ3JlYXRlIGEgd3JpdGFibGUgY29weSBvZiB0aGUgZXZlbnQgb2JqZWN0IGFuZCBub3JtYWxpemUgc29tZSBwcm9wZXJ0aWVzXG5cdFx0dmFyIGksIHByb3AsIGNvcHksXG5cdFx0XHR0eXBlID0gZXZlbnQudHlwZSxcblx0XHRcdG9yaWdpbmFsRXZlbnQgPSBldmVudCxcblx0XHRcdGZpeEhvb2sgPSB0aGlzLmZpeEhvb2tzWyB0eXBlIF07XG5cblx0XHRpZiAoICFmaXhIb29rICkge1xuXHRcdFx0dGhpcy5maXhIb29rc1sgdHlwZSBdID0gZml4SG9vayA9XG5cdFx0XHRcdHJtb3VzZUV2ZW50LnRlc3QoIHR5cGUgKSA/IHRoaXMubW91c2VIb29rcyA6XG5cdFx0XHRcdHJrZXlFdmVudC50ZXN0KCB0eXBlICkgPyB0aGlzLmtleUhvb2tzIDpcblx0XHRcdFx0e307XG5cdFx0fVxuXHRcdGNvcHkgPSBmaXhIb29rLnByb3BzID8gdGhpcy5wcm9wcy5jb25jYXQoIGZpeEhvb2sucHJvcHMgKSA6IHRoaXMucHJvcHM7XG5cblx0XHRldmVudCA9IG5ldyBqUXVlcnkuRXZlbnQoIG9yaWdpbmFsRXZlbnQgKTtcblxuXHRcdGkgPSBjb3B5Lmxlbmd0aDtcblx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdHByb3AgPSBjb3B5WyBpIF07XG5cdFx0XHRldmVudFsgcHJvcCBdID0gb3JpZ2luYWxFdmVudFsgcHJvcCBdO1xuXHRcdH1cblxuXHRcdC8vIFN1cHBvcnQ6IENvcmRvdmEgMi41IChXZWJLaXQpICgjMTMyNTUpXG5cdFx0Ly8gQWxsIGV2ZW50cyBzaG91bGQgaGF2ZSBhIHRhcmdldDsgQ29yZG92YSBkZXZpY2VyZWFkeSBkb2Vzbid0XG5cdFx0aWYgKCAhZXZlbnQudGFyZ2V0ICkge1xuXHRcdFx0ZXZlbnQudGFyZ2V0ID0gZG9jdW1lbnQ7XG5cdFx0fVxuXG5cdFx0Ly8gU3VwcG9ydDogU2FmYXJpIDYuMCssIENocm9tZTwyOFxuXHRcdC8vIFRhcmdldCBzaG91bGQgbm90IGJlIGEgdGV4dCBub2RlICgjNTA0LCAjMTMxNDMpXG5cdFx0aWYgKCBldmVudC50YXJnZXQubm9kZVR5cGUgPT09IDMgKSB7XG5cdFx0XHRldmVudC50YXJnZXQgPSBldmVudC50YXJnZXQucGFyZW50Tm9kZTtcblx0XHR9XG5cblx0XHRyZXR1cm4gZml4SG9vay5maWx0ZXIgPyBmaXhIb29rLmZpbHRlciggZXZlbnQsIG9yaWdpbmFsRXZlbnQgKSA6IGV2ZW50O1xuXHR9LFxuXG5cdHNwZWNpYWw6IHtcblx0XHRsb2FkOiB7XG5cdFx0XHQvLyBQcmV2ZW50IHRyaWdnZXJlZCBpbWFnZS5sb2FkIGV2ZW50cyBmcm9tIGJ1YmJsaW5nIHRvIHdpbmRvdy5sb2FkXG5cdFx0XHRub0J1YmJsZTogdHJ1ZVxuXHRcdH0sXG5cdFx0Zm9jdXM6IHtcblx0XHRcdC8vIEZpcmUgbmF0aXZlIGV2ZW50IGlmIHBvc3NpYmxlIHNvIGJsdXIvZm9jdXMgc2VxdWVuY2UgaXMgY29ycmVjdFxuXHRcdFx0dHJpZ2dlcjogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggdGhpcyAhPT0gc2FmZUFjdGl2ZUVsZW1lbnQoKSAmJiB0aGlzLmZvY3VzICkge1xuXHRcdFx0XHRcdHRoaXMuZm9jdXMoKTtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cdFx0XHRkZWxlZ2F0ZVR5cGU6IFwiZm9jdXNpblwiXG5cdFx0fSxcblx0XHRibHVyOiB7XG5cdFx0XHR0cmlnZ2VyOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCB0aGlzID09PSBzYWZlQWN0aXZlRWxlbWVudCgpICYmIHRoaXMuYmx1ciApIHtcblx0XHRcdFx0XHR0aGlzLmJsdXIoKTtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cdFx0XHRkZWxlZ2F0ZVR5cGU6IFwiZm9jdXNvdXRcIlxuXHRcdH0sXG5cdFx0Y2xpY2s6IHtcblx0XHRcdC8vIEZvciBjaGVja2JveCwgZmlyZSBuYXRpdmUgZXZlbnQgc28gY2hlY2tlZCBzdGF0ZSB3aWxsIGJlIHJpZ2h0XG5cdFx0XHR0cmlnZ2VyOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCB0aGlzLnR5cGUgPT09IFwiY2hlY2tib3hcIiAmJiB0aGlzLmNsaWNrICYmIGpRdWVyeS5ub2RlTmFtZSggdGhpcywgXCJpbnB1dFwiICkgKSB7XG5cdFx0XHRcdFx0dGhpcy5jbGljaygpO1xuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0fSxcblxuXHRcdFx0Ly8gRm9yIGNyb3NzLWJyb3dzZXIgY29uc2lzdGVuY3ksIGRvbid0IGZpcmUgbmF0aXZlIC5jbGljaygpIG9uIGxpbmtzXG5cdFx0XHRfZGVmYXVsdDogZnVuY3Rpb24oIGV2ZW50ICkge1xuXHRcdFx0XHRyZXR1cm4galF1ZXJ5Lm5vZGVOYW1lKCBldmVudC50YXJnZXQsIFwiYVwiICk7XG5cdFx0XHR9XG5cdFx0fSxcblxuXHRcdGJlZm9yZXVubG9hZDoge1xuXHRcdFx0cG9zdERpc3BhdGNoOiBmdW5jdGlvbiggZXZlbnQgKSB7XG5cblx0XHRcdFx0Ly8gU3VwcG9ydDogRmlyZWZveCAyMCtcblx0XHRcdFx0Ly8gRmlyZWZveCBkb2Vzbid0IGFsZXJ0IGlmIHRoZSByZXR1cm5WYWx1ZSBmaWVsZCBpcyBub3Qgc2V0LlxuXHRcdFx0XHRpZiAoIGV2ZW50LnJlc3VsdCAhPT0gdW5kZWZpbmVkICYmIGV2ZW50Lm9yaWdpbmFsRXZlbnQgKSB7XG5cdFx0XHRcdFx0ZXZlbnQub3JpZ2luYWxFdmVudC5yZXR1cm5WYWx1ZSA9IGV2ZW50LnJlc3VsdDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fSxcblxuXHRzaW11bGF0ZTogZnVuY3Rpb24oIHR5cGUsIGVsZW0sIGV2ZW50LCBidWJibGUgKSB7XG5cdFx0Ly8gUGlnZ3liYWNrIG9uIGEgZG9ub3IgZXZlbnQgdG8gc2ltdWxhdGUgYSBkaWZmZXJlbnQgb25lLlxuXHRcdC8vIEZha2Ugb3JpZ2luYWxFdmVudCB0byBhdm9pZCBkb25vcidzIHN0b3BQcm9wYWdhdGlvbiwgYnV0IGlmIHRoZVxuXHRcdC8vIHNpbXVsYXRlZCBldmVudCBwcmV2ZW50cyBkZWZhdWx0IHRoZW4gd2UgZG8gdGhlIHNhbWUgb24gdGhlIGRvbm9yLlxuXHRcdHZhciBlID0galF1ZXJ5LmV4dGVuZChcblx0XHRcdG5ldyBqUXVlcnkuRXZlbnQoKSxcblx0XHRcdGV2ZW50LFxuXHRcdFx0e1xuXHRcdFx0XHR0eXBlOiB0eXBlLFxuXHRcdFx0XHRpc1NpbXVsYXRlZDogdHJ1ZSxcblx0XHRcdFx0b3JpZ2luYWxFdmVudDoge31cblx0XHRcdH1cblx0XHQpO1xuXHRcdGlmICggYnViYmxlICkge1xuXHRcdFx0alF1ZXJ5LmV2ZW50LnRyaWdnZXIoIGUsIG51bGwsIGVsZW0gKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0alF1ZXJ5LmV2ZW50LmRpc3BhdGNoLmNhbGwoIGVsZW0sIGUgKTtcblx0XHR9XG5cdFx0aWYgKCBlLmlzRGVmYXVsdFByZXZlbnRlZCgpICkge1xuXHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHR9XG5cdH1cbn07XG5cbmpRdWVyeS5yZW1vdmVFdmVudCA9IGZ1bmN0aW9uKCBlbGVtLCB0eXBlLCBoYW5kbGUgKSB7XG5cdGlmICggZWxlbS5yZW1vdmVFdmVudExpc3RlbmVyICkge1xuXHRcdGVsZW0ucmVtb3ZlRXZlbnRMaXN0ZW5lciggdHlwZSwgaGFuZGxlLCBmYWxzZSApO1xuXHR9XG59O1xuXG5qUXVlcnkuRXZlbnQgPSBmdW5jdGlvbiggc3JjLCBwcm9wcyApIHtcblx0Ly8gQWxsb3cgaW5zdGFudGlhdGlvbiB3aXRob3V0IHRoZSAnbmV3JyBrZXl3b3JkXG5cdGlmICggISh0aGlzIGluc3RhbmNlb2YgalF1ZXJ5LkV2ZW50KSApIHtcblx0XHRyZXR1cm4gbmV3IGpRdWVyeS5FdmVudCggc3JjLCBwcm9wcyApO1xuXHR9XG5cblx0Ly8gRXZlbnQgb2JqZWN0XG5cdGlmICggc3JjICYmIHNyYy50eXBlICkge1xuXHRcdHRoaXMub3JpZ2luYWxFdmVudCA9IHNyYztcblx0XHR0aGlzLnR5cGUgPSBzcmMudHlwZTtcblxuXHRcdC8vIEV2ZW50cyBidWJibGluZyB1cCB0aGUgZG9jdW1lbnQgbWF5IGhhdmUgYmVlbiBtYXJrZWQgYXMgcHJldmVudGVkXG5cdFx0Ly8gYnkgYSBoYW5kbGVyIGxvd2VyIGRvd24gdGhlIHRyZWU7IHJlZmxlY3QgdGhlIGNvcnJlY3QgdmFsdWUuXG5cdFx0dGhpcy5pc0RlZmF1bHRQcmV2ZW50ZWQgPSBzcmMuZGVmYXVsdFByZXZlbnRlZCB8fFxuXHRcdFx0XHRzcmMuZGVmYXVsdFByZXZlbnRlZCA9PT0gdW5kZWZpbmVkICYmXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQ8NC4wXG5cdFx0XHRcdHNyYy5yZXR1cm5WYWx1ZSA9PT0gZmFsc2UgP1xuXHRcdFx0cmV0dXJuVHJ1ZSA6XG5cdFx0XHRyZXR1cm5GYWxzZTtcblxuXHQvLyBFdmVudCB0eXBlXG5cdH0gZWxzZSB7XG5cdFx0dGhpcy50eXBlID0gc3JjO1xuXHR9XG5cblx0Ly8gUHV0IGV4cGxpY2l0bHkgcHJvdmlkZWQgcHJvcGVydGllcyBvbnRvIHRoZSBldmVudCBvYmplY3Rcblx0aWYgKCBwcm9wcyApIHtcblx0XHRqUXVlcnkuZXh0ZW5kKCB0aGlzLCBwcm9wcyApO1xuXHR9XG5cblx0Ly8gQ3JlYXRlIGEgdGltZXN0YW1wIGlmIGluY29taW5nIGV2ZW50IGRvZXNuJ3QgaGF2ZSBvbmVcblx0dGhpcy50aW1lU3RhbXAgPSBzcmMgJiYgc3JjLnRpbWVTdGFtcCB8fCBqUXVlcnkubm93KCk7XG5cblx0Ly8gTWFyayBpdCBhcyBmaXhlZFxuXHR0aGlzWyBqUXVlcnkuZXhwYW5kbyBdID0gdHJ1ZTtcbn07XG5cbi8vIGpRdWVyeS5FdmVudCBpcyBiYXNlZCBvbiBET00zIEV2ZW50cyBhcyBzcGVjaWZpZWQgYnkgdGhlIEVDTUFTY3JpcHQgTGFuZ3VhZ2UgQmluZGluZ1xuLy8gaHR0cDovL3d3dy53My5vcmcvVFIvMjAwMy9XRC1ET00tTGV2ZWwtMy1FdmVudHMtMjAwMzAzMzEvZWNtYS1zY3JpcHQtYmluZGluZy5odG1sXG5qUXVlcnkuRXZlbnQucHJvdG90eXBlID0ge1xuXHRpc0RlZmF1bHRQcmV2ZW50ZWQ6IHJldHVybkZhbHNlLFxuXHRpc1Byb3BhZ2F0aW9uU3RvcHBlZDogcmV0dXJuRmFsc2UsXG5cdGlzSW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkOiByZXR1cm5GYWxzZSxcblxuXHRwcmV2ZW50RGVmYXVsdDogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGUgPSB0aGlzLm9yaWdpbmFsRXZlbnQ7XG5cblx0XHR0aGlzLmlzRGVmYXVsdFByZXZlbnRlZCA9IHJldHVyblRydWU7XG5cblx0XHRpZiAoIGUgJiYgZS5wcmV2ZW50RGVmYXVsdCApIHtcblx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHR9XG5cdH0sXG5cdHN0b3BQcm9wYWdhdGlvbjogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGUgPSB0aGlzLm9yaWdpbmFsRXZlbnQ7XG5cblx0XHR0aGlzLmlzUHJvcGFnYXRpb25TdG9wcGVkID0gcmV0dXJuVHJ1ZTtcblxuXHRcdGlmICggZSAmJiBlLnN0b3BQcm9wYWdhdGlvbiApIHtcblx0XHRcdGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdFx0fVxuXHR9LFxuXHRzdG9wSW1tZWRpYXRlUHJvcGFnYXRpb246IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBlID0gdGhpcy5vcmlnaW5hbEV2ZW50O1xuXG5cdFx0dGhpcy5pc0ltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZCA9IHJldHVyblRydWU7XG5cblx0XHRpZiAoIGUgJiYgZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24gKSB7XG5cdFx0XHRlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuXHRcdH1cblxuXHRcdHRoaXMuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdH1cbn07XG5cbi8vIENyZWF0ZSBtb3VzZWVudGVyL2xlYXZlIGV2ZW50cyB1c2luZyBtb3VzZW92ZXIvb3V0IGFuZCBldmVudC10aW1lIGNoZWNrc1xuLy8gU3VwcG9ydDogQ2hyb21lIDE1K1xualF1ZXJ5LmVhY2goe1xuXHRtb3VzZWVudGVyOiBcIm1vdXNlb3ZlclwiLFxuXHRtb3VzZWxlYXZlOiBcIm1vdXNlb3V0XCIsXG5cdHBvaW50ZXJlbnRlcjogXCJwb2ludGVyb3ZlclwiLFxuXHRwb2ludGVybGVhdmU6IFwicG9pbnRlcm91dFwiXG59LCBmdW5jdGlvbiggb3JpZywgZml4ICkge1xuXHRqUXVlcnkuZXZlbnQuc3BlY2lhbFsgb3JpZyBdID0ge1xuXHRcdGRlbGVnYXRlVHlwZTogZml4LFxuXHRcdGJpbmRUeXBlOiBmaXgsXG5cblx0XHRoYW5kbGU6IGZ1bmN0aW9uKCBldmVudCApIHtcblx0XHRcdHZhciByZXQsXG5cdFx0XHRcdHRhcmdldCA9IHRoaXMsXG5cdFx0XHRcdHJlbGF0ZWQgPSBldmVudC5yZWxhdGVkVGFyZ2V0LFxuXHRcdFx0XHRoYW5kbGVPYmogPSBldmVudC5oYW5kbGVPYmo7XG5cblx0XHRcdC8vIEZvciBtb3VzZW50ZXIvbGVhdmUgY2FsbCB0aGUgaGFuZGxlciBpZiByZWxhdGVkIGlzIG91dHNpZGUgdGhlIHRhcmdldC5cblx0XHRcdC8vIE5COiBObyByZWxhdGVkVGFyZ2V0IGlmIHRoZSBtb3VzZSBsZWZ0L2VudGVyZWQgdGhlIGJyb3dzZXIgd2luZG93XG5cdFx0XHRpZiAoICFyZWxhdGVkIHx8IChyZWxhdGVkICE9PSB0YXJnZXQgJiYgIWpRdWVyeS5jb250YWlucyggdGFyZ2V0LCByZWxhdGVkICkpICkge1xuXHRcdFx0XHRldmVudC50eXBlID0gaGFuZGxlT2JqLm9yaWdUeXBlO1xuXHRcdFx0XHRyZXQgPSBoYW5kbGVPYmouaGFuZGxlci5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XG5cdFx0XHRcdGV2ZW50LnR5cGUgPSBmaXg7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcmV0O1xuXHRcdH1cblx0fTtcbn0pO1xuXG4vLyBTdXBwb3J0OiBGaXJlZm94LCBDaHJvbWUsIFNhZmFyaVxuLy8gQ3JlYXRlIFwiYnViYmxpbmdcIiBmb2N1cyBhbmQgYmx1ciBldmVudHNcbmlmICggIXN1cHBvcnQuZm9jdXNpbkJ1YmJsZXMgKSB7XG5cdGpRdWVyeS5lYWNoKHsgZm9jdXM6IFwiZm9jdXNpblwiLCBibHVyOiBcImZvY3Vzb3V0XCIgfSwgZnVuY3Rpb24oIG9yaWcsIGZpeCApIHtcblxuXHRcdC8vIEF0dGFjaCBhIHNpbmdsZSBjYXB0dXJpbmcgaGFuZGxlciBvbiB0aGUgZG9jdW1lbnQgd2hpbGUgc29tZW9uZSB3YW50cyBmb2N1c2luL2ZvY3Vzb3V0XG5cdFx0dmFyIGhhbmRsZXIgPSBmdW5jdGlvbiggZXZlbnQgKSB7XG5cdFx0XHRcdGpRdWVyeS5ldmVudC5zaW11bGF0ZSggZml4LCBldmVudC50YXJnZXQsIGpRdWVyeS5ldmVudC5maXgoIGV2ZW50ICksIHRydWUgKTtcblx0XHRcdH07XG5cblx0XHRqUXVlcnkuZXZlbnQuc3BlY2lhbFsgZml4IF0gPSB7XG5cdFx0XHRzZXR1cDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHZhciBkb2MgPSB0aGlzLm93bmVyRG9jdW1lbnQgfHwgdGhpcyxcblx0XHRcdFx0XHRhdHRhY2hlcyA9IGRhdGFfcHJpdi5hY2Nlc3MoIGRvYywgZml4ICk7XG5cblx0XHRcdFx0aWYgKCAhYXR0YWNoZXMgKSB7XG5cdFx0XHRcdFx0ZG9jLmFkZEV2ZW50TGlzdGVuZXIoIG9yaWcsIGhhbmRsZXIsIHRydWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRkYXRhX3ByaXYuYWNjZXNzKCBkb2MsIGZpeCwgKCBhdHRhY2hlcyB8fCAwICkgKyAxICk7XG5cdFx0XHR9LFxuXHRcdFx0dGVhcmRvd246IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR2YXIgZG9jID0gdGhpcy5vd25lckRvY3VtZW50IHx8IHRoaXMsXG5cdFx0XHRcdFx0YXR0YWNoZXMgPSBkYXRhX3ByaXYuYWNjZXNzKCBkb2MsIGZpeCApIC0gMTtcblxuXHRcdFx0XHRpZiAoICFhdHRhY2hlcyApIHtcblx0XHRcdFx0XHRkb2MucmVtb3ZlRXZlbnRMaXN0ZW5lciggb3JpZywgaGFuZGxlciwgdHJ1ZSApO1xuXHRcdFx0XHRcdGRhdGFfcHJpdi5yZW1vdmUoIGRvYywgZml4ICk7XG5cblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRkYXRhX3ByaXYuYWNjZXNzKCBkb2MsIGZpeCwgYXR0YWNoZXMgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH07XG5cdH0pO1xufVxuXG5qUXVlcnkuZm4uZXh0ZW5kKHtcblxuXHRvbjogZnVuY3Rpb24oIHR5cGVzLCBzZWxlY3RvciwgZGF0YSwgZm4sIC8qSU5URVJOQUwqLyBvbmUgKSB7XG5cdFx0dmFyIG9yaWdGbiwgdHlwZTtcblxuXHRcdC8vIFR5cGVzIGNhbiBiZSBhIG1hcCBvZiB0eXBlcy9oYW5kbGVyc1xuXHRcdGlmICggdHlwZW9mIHR5cGVzID09PSBcIm9iamVjdFwiICkge1xuXHRcdFx0Ly8gKCB0eXBlcy1PYmplY3QsIHNlbGVjdG9yLCBkYXRhIClcblx0XHRcdGlmICggdHlwZW9mIHNlbGVjdG9yICE9PSBcInN0cmluZ1wiICkge1xuXHRcdFx0XHQvLyAoIHR5cGVzLU9iamVjdCwgZGF0YSApXG5cdFx0XHRcdGRhdGEgPSBkYXRhIHx8IHNlbGVjdG9yO1xuXHRcdFx0XHRzZWxlY3RvciA9IHVuZGVmaW5lZDtcblx0XHRcdH1cblx0XHRcdGZvciAoIHR5cGUgaW4gdHlwZXMgKSB7XG5cdFx0XHRcdHRoaXMub24oIHR5cGUsIHNlbGVjdG9yLCBkYXRhLCB0eXBlc1sgdHlwZSBdLCBvbmUgKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH1cblxuXHRcdGlmICggZGF0YSA9PSBudWxsICYmIGZuID09IG51bGwgKSB7XG5cdFx0XHQvLyAoIHR5cGVzLCBmbiApXG5cdFx0XHRmbiA9IHNlbGVjdG9yO1xuXHRcdFx0ZGF0YSA9IHNlbGVjdG9yID0gdW5kZWZpbmVkO1xuXHRcdH0gZWxzZSBpZiAoIGZuID09IG51bGwgKSB7XG5cdFx0XHRpZiAoIHR5cGVvZiBzZWxlY3RvciA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdFx0Ly8gKCB0eXBlcywgc2VsZWN0b3IsIGZuIClcblx0XHRcdFx0Zm4gPSBkYXRhO1xuXHRcdFx0XHRkYXRhID0gdW5kZWZpbmVkO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Ly8gKCB0eXBlcywgZGF0YSwgZm4gKVxuXHRcdFx0XHRmbiA9IGRhdGE7XG5cdFx0XHRcdGRhdGEgPSBzZWxlY3Rvcjtcblx0XHRcdFx0c2VsZWN0b3IgPSB1bmRlZmluZWQ7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGlmICggZm4gPT09IGZhbHNlICkge1xuXHRcdFx0Zm4gPSByZXR1cm5GYWxzZTtcblx0XHR9IGVsc2UgaWYgKCAhZm4gKSB7XG5cdFx0XHRyZXR1cm4gdGhpcztcblx0XHR9XG5cblx0XHRpZiAoIG9uZSA9PT0gMSApIHtcblx0XHRcdG9yaWdGbiA9IGZuO1xuXHRcdFx0Zm4gPSBmdW5jdGlvbiggZXZlbnQgKSB7XG5cdFx0XHRcdC8vIENhbiB1c2UgYW4gZW1wdHkgc2V0LCBzaW5jZSBldmVudCBjb250YWlucyB0aGUgaW5mb1xuXHRcdFx0XHRqUXVlcnkoKS5vZmYoIGV2ZW50ICk7XG5cdFx0XHRcdHJldHVybiBvcmlnRm4uYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApO1xuXHRcdFx0fTtcblx0XHRcdC8vIFVzZSBzYW1lIGd1aWQgc28gY2FsbGVyIGNhbiByZW1vdmUgdXNpbmcgb3JpZ0ZuXG5cdFx0XHRmbi5ndWlkID0gb3JpZ0ZuLmd1aWQgfHwgKCBvcmlnRm4uZ3VpZCA9IGpRdWVyeS5ndWlkKysgKTtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHRqUXVlcnkuZXZlbnQuYWRkKCB0aGlzLCB0eXBlcywgZm4sIGRhdGEsIHNlbGVjdG9yICk7XG5cdFx0fSk7XG5cdH0sXG5cdG9uZTogZnVuY3Rpb24oIHR5cGVzLCBzZWxlY3RvciwgZGF0YSwgZm4gKSB7XG5cdFx0cmV0dXJuIHRoaXMub24oIHR5cGVzLCBzZWxlY3RvciwgZGF0YSwgZm4sIDEgKTtcblx0fSxcblx0b2ZmOiBmdW5jdGlvbiggdHlwZXMsIHNlbGVjdG9yLCBmbiApIHtcblx0XHR2YXIgaGFuZGxlT2JqLCB0eXBlO1xuXHRcdGlmICggdHlwZXMgJiYgdHlwZXMucHJldmVudERlZmF1bHQgJiYgdHlwZXMuaGFuZGxlT2JqICkge1xuXHRcdFx0Ly8gKCBldmVudCApICBkaXNwYXRjaGVkIGpRdWVyeS5FdmVudFxuXHRcdFx0aGFuZGxlT2JqID0gdHlwZXMuaGFuZGxlT2JqO1xuXHRcdFx0alF1ZXJ5KCB0eXBlcy5kZWxlZ2F0ZVRhcmdldCApLm9mZihcblx0XHRcdFx0aGFuZGxlT2JqLm5hbWVzcGFjZSA/IGhhbmRsZU9iai5vcmlnVHlwZSArIFwiLlwiICsgaGFuZGxlT2JqLm5hbWVzcGFjZSA6IGhhbmRsZU9iai5vcmlnVHlwZSxcblx0XHRcdFx0aGFuZGxlT2JqLnNlbGVjdG9yLFxuXHRcdFx0XHRoYW5kbGVPYmouaGFuZGxlclxuXHRcdFx0KTtcblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH1cblx0XHRpZiAoIHR5cGVvZiB0eXBlcyA9PT0gXCJvYmplY3RcIiApIHtcblx0XHRcdC8vICggdHlwZXMtb2JqZWN0IFssIHNlbGVjdG9yXSApXG5cdFx0XHRmb3IgKCB0eXBlIGluIHR5cGVzICkge1xuXHRcdFx0XHR0aGlzLm9mZiggdHlwZSwgc2VsZWN0b3IsIHR5cGVzWyB0eXBlIF0gKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH1cblx0XHRpZiAoIHNlbGVjdG9yID09PSBmYWxzZSB8fCB0eXBlb2Ygc2VsZWN0b3IgPT09IFwiZnVuY3Rpb25cIiApIHtcblx0XHRcdC8vICggdHlwZXMgWywgZm5dIClcblx0XHRcdGZuID0gc2VsZWN0b3I7XG5cdFx0XHRzZWxlY3RvciA9IHVuZGVmaW5lZDtcblx0XHR9XG5cdFx0aWYgKCBmbiA9PT0gZmFsc2UgKSB7XG5cdFx0XHRmbiA9IHJldHVybkZhbHNlO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0alF1ZXJ5LmV2ZW50LnJlbW92ZSggdGhpcywgdHlwZXMsIGZuLCBzZWxlY3RvciApO1xuXHRcdH0pO1xuXHR9LFxuXG5cdHRyaWdnZXI6IGZ1bmN0aW9uKCB0eXBlLCBkYXRhICkge1xuXHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRqUXVlcnkuZXZlbnQudHJpZ2dlciggdHlwZSwgZGF0YSwgdGhpcyApO1xuXHRcdH0pO1xuXHR9LFxuXHR0cmlnZ2VySGFuZGxlcjogZnVuY3Rpb24oIHR5cGUsIGRhdGEgKSB7XG5cdFx0dmFyIGVsZW0gPSB0aGlzWzBdO1xuXHRcdGlmICggZWxlbSApIHtcblx0XHRcdHJldHVybiBqUXVlcnkuZXZlbnQudHJpZ2dlciggdHlwZSwgZGF0YSwgZWxlbSwgdHJ1ZSApO1xuXHRcdH1cblx0fVxufSk7XG5cblxudmFyXG5cdHJ4aHRtbFRhZyA9IC88KD8hYXJlYXxicnxjb2x8ZW1iZWR8aHJ8aW1nfGlucHV0fGxpbmt8bWV0YXxwYXJhbSkoKFtcXHc6XSspW14+XSopXFwvPi9naSxcblx0cnRhZ05hbWUgPSAvPChbXFx3Ol0rKS8sXG5cdHJodG1sID0gLzx8JiM/XFx3KzsvLFxuXHRybm9Jbm5lcmh0bWwgPSAvPCg/OnNjcmlwdHxzdHlsZXxsaW5rKS9pLFxuXHQvLyBjaGVja2VkPVwiY2hlY2tlZFwiIG9yIGNoZWNrZWRcblx0cmNoZWNrZWQgPSAvY2hlY2tlZFxccyooPzpbXj1dfD1cXHMqLmNoZWNrZWQuKS9pLFxuXHRyc2NyaXB0VHlwZSA9IC9eJHxcXC8oPzpqYXZhfGVjbWEpc2NyaXB0L2ksXG5cdHJzY3JpcHRUeXBlTWFza2VkID0gL150cnVlXFwvKC4qKS8sXG5cdHJjbGVhblNjcmlwdCA9IC9eXFxzKjwhKD86XFxbQ0RBVEFcXFt8LS0pfCg/OlxcXVxcXXwtLSk+XFxzKiQvZyxcblxuXHQvLyBXZSBoYXZlIHRvIGNsb3NlIHRoZXNlIHRhZ3MgdG8gc3VwcG9ydCBYSFRNTCAoIzEzMjAwKVxuXHR3cmFwTWFwID0ge1xuXG5cdFx0Ly8gU3VwcG9ydDogSUU5XG5cdFx0b3B0aW9uOiBbIDEsIFwiPHNlbGVjdCBtdWx0aXBsZT0nbXVsdGlwbGUnPlwiLCBcIjwvc2VsZWN0PlwiIF0sXG5cblx0XHR0aGVhZDogWyAxLCBcIjx0YWJsZT5cIiwgXCI8L3RhYmxlPlwiIF0sXG5cdFx0Y29sOiBbIDIsIFwiPHRhYmxlPjxjb2xncm91cD5cIiwgXCI8L2NvbGdyb3VwPjwvdGFibGU+XCIgXSxcblx0XHR0cjogWyAyLCBcIjx0YWJsZT48dGJvZHk+XCIsIFwiPC90Ym9keT48L3RhYmxlPlwiIF0sXG5cdFx0dGQ6IFsgMywgXCI8dGFibGU+PHRib2R5Pjx0cj5cIiwgXCI8L3RyPjwvdGJvZHk+PC90YWJsZT5cIiBdLFxuXG5cdFx0X2RlZmF1bHQ6IFsgMCwgXCJcIiwgXCJcIiBdXG5cdH07XG5cbi8vIFN1cHBvcnQ6IElFOVxud3JhcE1hcC5vcHRncm91cCA9IHdyYXBNYXAub3B0aW9uO1xuXG53cmFwTWFwLnRib2R5ID0gd3JhcE1hcC50Zm9vdCA9IHdyYXBNYXAuY29sZ3JvdXAgPSB3cmFwTWFwLmNhcHRpb24gPSB3cmFwTWFwLnRoZWFkO1xud3JhcE1hcC50aCA9IHdyYXBNYXAudGQ7XG5cbi8vIFN1cHBvcnQ6IDEueCBjb21wYXRpYmlsaXR5XG4vLyBNYW5pcHVsYXRpbmcgdGFibGVzIHJlcXVpcmVzIGEgdGJvZHlcbmZ1bmN0aW9uIG1hbmlwdWxhdGlvblRhcmdldCggZWxlbSwgY29udGVudCApIHtcblx0cmV0dXJuIGpRdWVyeS5ub2RlTmFtZSggZWxlbSwgXCJ0YWJsZVwiICkgJiZcblx0XHRqUXVlcnkubm9kZU5hbWUoIGNvbnRlbnQubm9kZVR5cGUgIT09IDExID8gY29udGVudCA6IGNvbnRlbnQuZmlyc3RDaGlsZCwgXCJ0clwiICkgP1xuXG5cdFx0ZWxlbS5nZXRFbGVtZW50c0J5VGFnTmFtZShcInRib2R5XCIpWzBdIHx8XG5cdFx0XHRlbGVtLmFwcGVuZENoaWxkKCBlbGVtLm93bmVyRG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInRib2R5XCIpICkgOlxuXHRcdGVsZW07XG59XG5cbi8vIFJlcGxhY2UvcmVzdG9yZSB0aGUgdHlwZSBhdHRyaWJ1dGUgb2Ygc2NyaXB0IGVsZW1lbnRzIGZvciBzYWZlIERPTSBtYW5pcHVsYXRpb25cbmZ1bmN0aW9uIGRpc2FibGVTY3JpcHQoIGVsZW0gKSB7XG5cdGVsZW0udHlwZSA9IChlbGVtLmdldEF0dHJpYnV0ZShcInR5cGVcIikgIT09IG51bGwpICsgXCIvXCIgKyBlbGVtLnR5cGU7XG5cdHJldHVybiBlbGVtO1xufVxuZnVuY3Rpb24gcmVzdG9yZVNjcmlwdCggZWxlbSApIHtcblx0dmFyIG1hdGNoID0gcnNjcmlwdFR5cGVNYXNrZWQuZXhlYyggZWxlbS50eXBlICk7XG5cblx0aWYgKCBtYXRjaCApIHtcblx0XHRlbGVtLnR5cGUgPSBtYXRjaFsgMSBdO1xuXHR9IGVsc2Uge1xuXHRcdGVsZW0ucmVtb3ZlQXR0cmlidXRlKFwidHlwZVwiKTtcblx0fVxuXG5cdHJldHVybiBlbGVtO1xufVxuXG4vLyBNYXJrIHNjcmlwdHMgYXMgaGF2aW5nIGFscmVhZHkgYmVlbiBldmFsdWF0ZWRcbmZ1bmN0aW9uIHNldEdsb2JhbEV2YWwoIGVsZW1zLCByZWZFbGVtZW50cyApIHtcblx0dmFyIGkgPSAwLFxuXHRcdGwgPSBlbGVtcy5sZW5ndGg7XG5cblx0Zm9yICggOyBpIDwgbDsgaSsrICkge1xuXHRcdGRhdGFfcHJpdi5zZXQoXG5cdFx0XHRlbGVtc1sgaSBdLCBcImdsb2JhbEV2YWxcIiwgIXJlZkVsZW1lbnRzIHx8IGRhdGFfcHJpdi5nZXQoIHJlZkVsZW1lbnRzWyBpIF0sIFwiZ2xvYmFsRXZhbFwiIClcblx0XHQpO1xuXHR9XG59XG5cbmZ1bmN0aW9uIGNsb25lQ29weUV2ZW50KCBzcmMsIGRlc3QgKSB7XG5cdHZhciBpLCBsLCB0eXBlLCBwZGF0YU9sZCwgcGRhdGFDdXIsIHVkYXRhT2xkLCB1ZGF0YUN1ciwgZXZlbnRzO1xuXG5cdGlmICggZGVzdC5ub2RlVHlwZSAhPT0gMSApIHtcblx0XHRyZXR1cm47XG5cdH1cblxuXHQvLyAxLiBDb3B5IHByaXZhdGUgZGF0YTogZXZlbnRzLCBoYW5kbGVycywgZXRjLlxuXHRpZiAoIGRhdGFfcHJpdi5oYXNEYXRhKCBzcmMgKSApIHtcblx0XHRwZGF0YU9sZCA9IGRhdGFfcHJpdi5hY2Nlc3MoIHNyYyApO1xuXHRcdHBkYXRhQ3VyID0gZGF0YV9wcml2LnNldCggZGVzdCwgcGRhdGFPbGQgKTtcblx0XHRldmVudHMgPSBwZGF0YU9sZC5ldmVudHM7XG5cblx0XHRpZiAoIGV2ZW50cyApIHtcblx0XHRcdGRlbGV0ZSBwZGF0YUN1ci5oYW5kbGU7XG5cdFx0XHRwZGF0YUN1ci5ldmVudHMgPSB7fTtcblxuXHRcdFx0Zm9yICggdHlwZSBpbiBldmVudHMgKSB7XG5cdFx0XHRcdGZvciAoIGkgPSAwLCBsID0gZXZlbnRzWyB0eXBlIF0ubGVuZ3RoOyBpIDwgbDsgaSsrICkge1xuXHRcdFx0XHRcdGpRdWVyeS5ldmVudC5hZGQoIGRlc3QsIHR5cGUsIGV2ZW50c1sgdHlwZSBdWyBpIF0gKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8vIDIuIENvcHkgdXNlciBkYXRhXG5cdGlmICggZGF0YV91c2VyLmhhc0RhdGEoIHNyYyApICkge1xuXHRcdHVkYXRhT2xkID0gZGF0YV91c2VyLmFjY2Vzcyggc3JjICk7XG5cdFx0dWRhdGFDdXIgPSBqUXVlcnkuZXh0ZW5kKCB7fSwgdWRhdGFPbGQgKTtcblxuXHRcdGRhdGFfdXNlci5zZXQoIGRlc3QsIHVkYXRhQ3VyICk7XG5cdH1cbn1cblxuZnVuY3Rpb24gZ2V0QWxsKCBjb250ZXh0LCB0YWcgKSB7XG5cdHZhciByZXQgPSBjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lID8gY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSggdGFnIHx8IFwiKlwiICkgOlxuXHRcdFx0Y29udGV4dC5xdWVyeVNlbGVjdG9yQWxsID8gY29udGV4dC5xdWVyeVNlbGVjdG9yQWxsKCB0YWcgfHwgXCIqXCIgKSA6XG5cdFx0XHRbXTtcblxuXHRyZXR1cm4gdGFnID09PSB1bmRlZmluZWQgfHwgdGFnICYmIGpRdWVyeS5ub2RlTmFtZSggY29udGV4dCwgdGFnICkgP1xuXHRcdGpRdWVyeS5tZXJnZSggWyBjb250ZXh0IF0sIHJldCApIDpcblx0XHRyZXQ7XG59XG5cbi8vIEZpeCBJRSBidWdzLCBzZWUgc3VwcG9ydCB0ZXN0c1xuZnVuY3Rpb24gZml4SW5wdXQoIHNyYywgZGVzdCApIHtcblx0dmFyIG5vZGVOYW1lID0gZGVzdC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXG5cdC8vIEZhaWxzIHRvIHBlcnNpc3QgdGhlIGNoZWNrZWQgc3RhdGUgb2YgYSBjbG9uZWQgY2hlY2tib3ggb3IgcmFkaW8gYnV0dG9uLlxuXHRpZiAoIG5vZGVOYW1lID09PSBcImlucHV0XCIgJiYgcmNoZWNrYWJsZVR5cGUudGVzdCggc3JjLnR5cGUgKSApIHtcblx0XHRkZXN0LmNoZWNrZWQgPSBzcmMuY2hlY2tlZDtcblxuXHQvLyBGYWlscyB0byByZXR1cm4gdGhlIHNlbGVjdGVkIG9wdGlvbiB0byB0aGUgZGVmYXVsdCBzZWxlY3RlZCBzdGF0ZSB3aGVuIGNsb25pbmcgb3B0aW9uc1xuXHR9IGVsc2UgaWYgKCBub2RlTmFtZSA9PT0gXCJpbnB1dFwiIHx8IG5vZGVOYW1lID09PSBcInRleHRhcmVhXCIgKSB7XG5cdFx0ZGVzdC5kZWZhdWx0VmFsdWUgPSBzcmMuZGVmYXVsdFZhbHVlO1xuXHR9XG59XG5cbmpRdWVyeS5leHRlbmQoe1xuXHRjbG9uZTogZnVuY3Rpb24oIGVsZW0sIGRhdGFBbmRFdmVudHMsIGRlZXBEYXRhQW5kRXZlbnRzICkge1xuXHRcdHZhciBpLCBsLCBzcmNFbGVtZW50cywgZGVzdEVsZW1lbnRzLFxuXHRcdFx0Y2xvbmUgPSBlbGVtLmNsb25lTm9kZSggdHJ1ZSApLFxuXHRcdFx0aW5QYWdlID0galF1ZXJ5LmNvbnRhaW5zKCBlbGVtLm93bmVyRG9jdW1lbnQsIGVsZW0gKTtcblxuXHRcdC8vIEZpeCBJRSBjbG9uaW5nIGlzc3Vlc1xuXHRcdGlmICggIXN1cHBvcnQubm9DbG9uZUNoZWNrZWQgJiYgKCBlbGVtLm5vZGVUeXBlID09PSAxIHx8IGVsZW0ubm9kZVR5cGUgPT09IDExICkgJiZcblx0XHRcdFx0IWpRdWVyeS5pc1hNTERvYyggZWxlbSApICkge1xuXG5cdFx0XHQvLyBXZSBlc2NoZXcgU2l6emxlIGhlcmUgZm9yIHBlcmZvcm1hbmNlIHJlYXNvbnM6IGh0dHA6Ly9qc3BlcmYuY29tL2dldGFsbC12cy1zaXp6bGUvMlxuXHRcdFx0ZGVzdEVsZW1lbnRzID0gZ2V0QWxsKCBjbG9uZSApO1xuXHRcdFx0c3JjRWxlbWVudHMgPSBnZXRBbGwoIGVsZW0gKTtcblxuXHRcdFx0Zm9yICggaSA9IDAsIGwgPSBzcmNFbGVtZW50cy5sZW5ndGg7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRcdGZpeElucHV0KCBzcmNFbGVtZW50c1sgaSBdLCBkZXN0RWxlbWVudHNbIGkgXSApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIENvcHkgdGhlIGV2ZW50cyBmcm9tIHRoZSBvcmlnaW5hbCB0byB0aGUgY2xvbmVcblx0XHRpZiAoIGRhdGFBbmRFdmVudHMgKSB7XG5cdFx0XHRpZiAoIGRlZXBEYXRhQW5kRXZlbnRzICkge1xuXHRcdFx0XHRzcmNFbGVtZW50cyA9IHNyY0VsZW1lbnRzIHx8IGdldEFsbCggZWxlbSApO1xuXHRcdFx0XHRkZXN0RWxlbWVudHMgPSBkZXN0RWxlbWVudHMgfHwgZ2V0QWxsKCBjbG9uZSApO1xuXG5cdFx0XHRcdGZvciAoIGkgPSAwLCBsID0gc3JjRWxlbWVudHMubGVuZ3RoOyBpIDwgbDsgaSsrICkge1xuXHRcdFx0XHRcdGNsb25lQ29weUV2ZW50KCBzcmNFbGVtZW50c1sgaSBdLCBkZXN0RWxlbWVudHNbIGkgXSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRjbG9uZUNvcHlFdmVudCggZWxlbSwgY2xvbmUgKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBQcmVzZXJ2ZSBzY3JpcHQgZXZhbHVhdGlvbiBoaXN0b3J5XG5cdFx0ZGVzdEVsZW1lbnRzID0gZ2V0QWxsKCBjbG9uZSwgXCJzY3JpcHRcIiApO1xuXHRcdGlmICggZGVzdEVsZW1lbnRzLmxlbmd0aCA+IDAgKSB7XG5cdFx0XHRzZXRHbG9iYWxFdmFsKCBkZXN0RWxlbWVudHMsICFpblBhZ2UgJiYgZ2V0QWxsKCBlbGVtLCBcInNjcmlwdFwiICkgKTtcblx0XHR9XG5cblx0XHQvLyBSZXR1cm4gdGhlIGNsb25lZCBzZXRcblx0XHRyZXR1cm4gY2xvbmU7XG5cdH0sXG5cblx0YnVpbGRGcmFnbWVudDogZnVuY3Rpb24oIGVsZW1zLCBjb250ZXh0LCBzY3JpcHRzLCBzZWxlY3Rpb24gKSB7XG5cdFx0dmFyIGVsZW0sIHRtcCwgdGFnLCB3cmFwLCBjb250YWlucywgaixcblx0XHRcdGZyYWdtZW50ID0gY29udGV4dC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCksXG5cdFx0XHRub2RlcyA9IFtdLFxuXHRcdFx0aSA9IDAsXG5cdFx0XHRsID0gZWxlbXMubGVuZ3RoO1xuXG5cdFx0Zm9yICggOyBpIDwgbDsgaSsrICkge1xuXHRcdFx0ZWxlbSA9IGVsZW1zWyBpIF07XG5cblx0XHRcdGlmICggZWxlbSB8fCBlbGVtID09PSAwICkge1xuXG5cdFx0XHRcdC8vIEFkZCBub2RlcyBkaXJlY3RseVxuXHRcdFx0XHRpZiAoIGpRdWVyeS50eXBlKCBlbGVtICkgPT09IFwib2JqZWN0XCIgKSB7XG5cdFx0XHRcdFx0Ly8gU3VwcG9ydDogUXRXZWJLaXQsIFBoYW50b21KU1xuXHRcdFx0XHRcdC8vIHB1c2guYXBwbHkoXywgYXJyYXlsaWtlKSB0aHJvd3Mgb24gYW5jaWVudCBXZWJLaXRcblx0XHRcdFx0XHRqUXVlcnkubWVyZ2UoIG5vZGVzLCBlbGVtLm5vZGVUeXBlID8gWyBlbGVtIF0gOiBlbGVtICk7XG5cblx0XHRcdFx0Ly8gQ29udmVydCBub24taHRtbCBpbnRvIGEgdGV4dCBub2RlXG5cdFx0XHRcdH0gZWxzZSBpZiAoICFyaHRtbC50ZXN0KCBlbGVtICkgKSB7XG5cdFx0XHRcdFx0bm9kZXMucHVzaCggY29udGV4dC5jcmVhdGVUZXh0Tm9kZSggZWxlbSApICk7XG5cblx0XHRcdFx0Ly8gQ29udmVydCBodG1sIGludG8gRE9NIG5vZGVzXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0dG1wID0gdG1wIHx8IGZyYWdtZW50LmFwcGVuZENoaWxkKCBjb250ZXh0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIikgKTtcblxuXHRcdFx0XHRcdC8vIERlc2VyaWFsaXplIGEgc3RhbmRhcmQgcmVwcmVzZW50YXRpb25cblx0XHRcdFx0XHR0YWcgPSAoIHJ0YWdOYW1lLmV4ZWMoIGVsZW0gKSB8fCBbIFwiXCIsIFwiXCIgXSApWyAxIF0udG9Mb3dlckNhc2UoKTtcblx0XHRcdFx0XHR3cmFwID0gd3JhcE1hcFsgdGFnIF0gfHwgd3JhcE1hcC5fZGVmYXVsdDtcblx0XHRcdFx0XHR0bXAuaW5uZXJIVE1MID0gd3JhcFsgMSBdICsgZWxlbS5yZXBsYWNlKCByeGh0bWxUYWcsIFwiPCQxPjwvJDI+XCIgKSArIHdyYXBbIDIgXTtcblxuXHRcdFx0XHRcdC8vIERlc2NlbmQgdGhyb3VnaCB3cmFwcGVycyB0byB0aGUgcmlnaHQgY29udGVudFxuXHRcdFx0XHRcdGogPSB3cmFwWyAwIF07XG5cdFx0XHRcdFx0d2hpbGUgKCBqLS0gKSB7XG5cdFx0XHRcdFx0XHR0bXAgPSB0bXAubGFzdENoaWxkO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIFN1cHBvcnQ6IFF0V2ViS2l0LCBQaGFudG9tSlNcblx0XHRcdFx0XHQvLyBwdXNoLmFwcGx5KF8sIGFycmF5bGlrZSkgdGhyb3dzIG9uIGFuY2llbnQgV2ViS2l0XG5cdFx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCBub2RlcywgdG1wLmNoaWxkTm9kZXMgKTtcblxuXHRcdFx0XHRcdC8vIFJlbWVtYmVyIHRoZSB0b3AtbGV2ZWwgY29udGFpbmVyXG5cdFx0XHRcdFx0dG1wID0gZnJhZ21lbnQuZmlyc3RDaGlsZDtcblxuXHRcdFx0XHRcdC8vIEVuc3VyZSB0aGUgY3JlYXRlZCBub2RlcyBhcmUgb3JwaGFuZWQgKCMxMjM5Milcblx0XHRcdFx0XHR0bXAudGV4dENvbnRlbnQgPSBcIlwiO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gUmVtb3ZlIHdyYXBwZXIgZnJvbSBmcmFnbWVudFxuXHRcdGZyYWdtZW50LnRleHRDb250ZW50ID0gXCJcIjtcblxuXHRcdGkgPSAwO1xuXHRcdHdoaWxlICggKGVsZW0gPSBub2Rlc1sgaSsrIF0pICkge1xuXG5cdFx0XHQvLyAjNDA4NyAtIElmIG9yaWdpbiBhbmQgZGVzdGluYXRpb24gZWxlbWVudHMgYXJlIHRoZSBzYW1lLCBhbmQgdGhpcyBpc1xuXHRcdFx0Ly8gdGhhdCBlbGVtZW50LCBkbyBub3QgZG8gYW55dGhpbmdcblx0XHRcdGlmICggc2VsZWN0aW9uICYmIGpRdWVyeS5pbkFycmF5KCBlbGVtLCBzZWxlY3Rpb24gKSAhPT0gLTEgKSB7XG5cdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0fVxuXG5cdFx0XHRjb250YWlucyA9IGpRdWVyeS5jb250YWlucyggZWxlbS5vd25lckRvY3VtZW50LCBlbGVtICk7XG5cblx0XHRcdC8vIEFwcGVuZCB0byBmcmFnbWVudFxuXHRcdFx0dG1wID0gZ2V0QWxsKCBmcmFnbWVudC5hcHBlbmRDaGlsZCggZWxlbSApLCBcInNjcmlwdFwiICk7XG5cblx0XHRcdC8vIFByZXNlcnZlIHNjcmlwdCBldmFsdWF0aW9uIGhpc3Rvcnlcblx0XHRcdGlmICggY29udGFpbnMgKSB7XG5cdFx0XHRcdHNldEdsb2JhbEV2YWwoIHRtcCApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBDYXB0dXJlIGV4ZWN1dGFibGVzXG5cdFx0XHRpZiAoIHNjcmlwdHMgKSB7XG5cdFx0XHRcdGogPSAwO1xuXHRcdFx0XHR3aGlsZSAoIChlbGVtID0gdG1wWyBqKysgXSkgKSB7XG5cdFx0XHRcdFx0aWYgKCByc2NyaXB0VHlwZS50ZXN0KCBlbGVtLnR5cGUgfHwgXCJcIiApICkge1xuXHRcdFx0XHRcdFx0c2NyaXB0cy5wdXNoKCBlbGVtICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGZyYWdtZW50O1xuXHR9LFxuXG5cdGNsZWFuRGF0YTogZnVuY3Rpb24oIGVsZW1zICkge1xuXHRcdHZhciBkYXRhLCBlbGVtLCB0eXBlLCBrZXksXG5cdFx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWwsXG5cdFx0XHRpID0gMDtcblxuXHRcdGZvciAoIDsgKGVsZW0gPSBlbGVtc1sgaSBdKSAhPT0gdW5kZWZpbmVkOyBpKysgKSB7XG5cdFx0XHRpZiAoIGpRdWVyeS5hY2NlcHREYXRhKCBlbGVtICkgKSB7XG5cdFx0XHRcdGtleSA9IGVsZW1bIGRhdGFfcHJpdi5leHBhbmRvIF07XG5cblx0XHRcdFx0aWYgKCBrZXkgJiYgKGRhdGEgPSBkYXRhX3ByaXYuY2FjaGVbIGtleSBdKSApIHtcblx0XHRcdFx0XHRpZiAoIGRhdGEuZXZlbnRzICkge1xuXHRcdFx0XHRcdFx0Zm9yICggdHlwZSBpbiBkYXRhLmV2ZW50cyApIHtcblx0XHRcdFx0XHRcdFx0aWYgKCBzcGVjaWFsWyB0eXBlIF0gKSB7XG5cdFx0XHRcdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LnJlbW92ZSggZWxlbSwgdHlwZSApO1xuXG5cdFx0XHRcdFx0XHRcdC8vIFRoaXMgaXMgYSBzaG9ydGN1dCB0byBhdm9pZCBqUXVlcnkuZXZlbnQucmVtb3ZlJ3Mgb3ZlcmhlYWRcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRqUXVlcnkucmVtb3ZlRXZlbnQoIGVsZW0sIHR5cGUsIGRhdGEuaGFuZGxlICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKCBkYXRhX3ByaXYuY2FjaGVbIGtleSBdICkge1xuXHRcdFx0XHRcdFx0Ly8gRGlzY2FyZCBhbnkgcmVtYWluaW5nIGBwcml2YXRlYCBkYXRhXG5cdFx0XHRcdFx0XHRkZWxldGUgZGF0YV9wcml2LmNhY2hlWyBrZXkgXTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdC8vIERpc2NhcmQgYW55IHJlbWFpbmluZyBgdXNlcmAgZGF0YVxuXHRcdFx0ZGVsZXRlIGRhdGFfdXNlci5jYWNoZVsgZWxlbVsgZGF0YV91c2VyLmV4cGFuZG8gXSBdO1xuXHRcdH1cblx0fVxufSk7XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHR0ZXh0OiBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdFx0cmV0dXJuIHZhbHVlID09PSB1bmRlZmluZWQgP1xuXHRcdFx0XHRqUXVlcnkudGV4dCggdGhpcyApIDpcblx0XHRcdFx0dGhpcy5lbXB0eSgpLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0aWYgKCB0aGlzLm5vZGVUeXBlID09PSAxIHx8IHRoaXMubm9kZVR5cGUgPT09IDExIHx8IHRoaXMubm9kZVR5cGUgPT09IDkgKSB7XG5cdFx0XHRcdFx0XHR0aGlzLnRleHRDb250ZW50ID0gdmFsdWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblx0XHR9LCBudWxsLCB2YWx1ZSwgYXJndW1lbnRzLmxlbmd0aCApO1xuXHR9LFxuXG5cdGFwcGVuZDogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuZG9tTWFuaXAoIGFyZ3VtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRpZiAoIHRoaXMubm9kZVR5cGUgPT09IDEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gMTEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gOSApIHtcblx0XHRcdFx0dmFyIHRhcmdldCA9IG1hbmlwdWxhdGlvblRhcmdldCggdGhpcywgZWxlbSApO1xuXHRcdFx0XHR0YXJnZXQuYXBwZW5kQ2hpbGQoIGVsZW0gKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fSxcblxuXHRwcmVwZW5kOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5kb21NYW5pcCggYXJndW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdGlmICggdGhpcy5ub2RlVHlwZSA9PT0gMSB8fCB0aGlzLm5vZGVUeXBlID09PSAxMSB8fCB0aGlzLm5vZGVUeXBlID09PSA5ICkge1xuXHRcdFx0XHR2YXIgdGFyZ2V0ID0gbWFuaXB1bGF0aW9uVGFyZ2V0KCB0aGlzLCBlbGVtICk7XG5cdFx0XHRcdHRhcmdldC5pbnNlcnRCZWZvcmUoIGVsZW0sIHRhcmdldC5maXJzdENoaWxkICk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0sXG5cblx0YmVmb3JlOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5kb21NYW5pcCggYXJndW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdGlmICggdGhpcy5wYXJlbnROb2RlICkge1xuXHRcdFx0XHR0aGlzLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKCBlbGVtLCB0aGlzICk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0sXG5cblx0YWZ0ZXI6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLmRvbU1hbmlwKCBhcmd1bWVudHMsIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0aWYgKCB0aGlzLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdHRoaXMucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoIGVsZW0sIHRoaXMubmV4dFNpYmxpbmcgKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fSxcblxuXHRyZW1vdmU6IGZ1bmN0aW9uKCBzZWxlY3Rvciwga2VlcERhdGEgLyogSW50ZXJuYWwgVXNlIE9ubHkgKi8gKSB7XG5cdFx0dmFyIGVsZW0sXG5cdFx0XHRlbGVtcyA9IHNlbGVjdG9yID8galF1ZXJ5LmZpbHRlciggc2VsZWN0b3IsIHRoaXMgKSA6IHRoaXMsXG5cdFx0XHRpID0gMDtcblxuXHRcdGZvciAoIDsgKGVsZW0gPSBlbGVtc1tpXSkgIT0gbnVsbDsgaSsrICkge1xuXHRcdFx0aWYgKCAha2VlcERhdGEgJiYgZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdFx0alF1ZXJ5LmNsZWFuRGF0YSggZ2V0QWxsKCBlbGVtICkgKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBlbGVtLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdGlmICgga2VlcERhdGEgJiYgalF1ZXJ5LmNvbnRhaW5zKCBlbGVtLm93bmVyRG9jdW1lbnQsIGVsZW0gKSApIHtcblx0XHRcdFx0XHRzZXRHbG9iYWxFdmFsKCBnZXRBbGwoIGVsZW0sIFwic2NyaXB0XCIgKSApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGVsZW0ucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCggZWxlbSApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdGVtcHR5OiBmdW5jdGlvbigpIHtcblx0XHR2YXIgZWxlbSxcblx0XHRcdGkgPSAwO1xuXG5cdFx0Zm9yICggOyAoZWxlbSA9IHRoaXNbaV0pICE9IG51bGw7IGkrKyApIHtcblx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblxuXHRcdFx0XHQvLyBQcmV2ZW50IG1lbW9yeSBsZWFrc1xuXHRcdFx0XHRqUXVlcnkuY2xlYW5EYXRhKCBnZXRBbGwoIGVsZW0sIGZhbHNlICkgKTtcblxuXHRcdFx0XHQvLyBSZW1vdmUgYW55IHJlbWFpbmluZyBub2Rlc1xuXHRcdFx0XHRlbGVtLnRleHRDb250ZW50ID0gXCJcIjtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcztcblx0fSxcblxuXHRjbG9uZTogZnVuY3Rpb24oIGRhdGFBbmRFdmVudHMsIGRlZXBEYXRhQW5kRXZlbnRzICkge1xuXHRcdGRhdGFBbmRFdmVudHMgPSBkYXRhQW5kRXZlbnRzID09IG51bGwgPyBmYWxzZSA6IGRhdGFBbmRFdmVudHM7XG5cdFx0ZGVlcERhdGFBbmRFdmVudHMgPSBkZWVwRGF0YUFuZEV2ZW50cyA9PSBudWxsID8gZGF0YUFuZEV2ZW50cyA6IGRlZXBEYXRhQW5kRXZlbnRzO1xuXG5cdFx0cmV0dXJuIHRoaXMubWFwKGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIGpRdWVyeS5jbG9uZSggdGhpcywgZGF0YUFuZEV2ZW50cywgZGVlcERhdGFBbmRFdmVudHMgKTtcblx0XHR9KTtcblx0fSxcblxuXHRodG1sOiBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdFx0dmFyIGVsZW0gPSB0aGlzWyAwIF0gfHwge30sXG5cdFx0XHRcdGkgPSAwLFxuXHRcdFx0XHRsID0gdGhpcy5sZW5ndGg7XG5cblx0XHRcdGlmICggdmFsdWUgPT09IHVuZGVmaW5lZCAmJiBlbGVtLm5vZGVUeXBlID09PSAxICkge1xuXHRcdFx0XHRyZXR1cm4gZWxlbS5pbm5lckhUTUw7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNlZSBpZiB3ZSBjYW4gdGFrZSBhIHNob3J0Y3V0IGFuZCBqdXN0IHVzZSBpbm5lckhUTUxcblx0XHRcdGlmICggdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiICYmICFybm9Jbm5lcmh0bWwudGVzdCggdmFsdWUgKSAmJlxuXHRcdFx0XHQhd3JhcE1hcFsgKCBydGFnTmFtZS5leGVjKCB2YWx1ZSApIHx8IFsgXCJcIiwgXCJcIiBdIClbIDEgXS50b0xvd2VyQ2FzZSgpIF0gKSB7XG5cblx0XHRcdFx0dmFsdWUgPSB2YWx1ZS5yZXBsYWNlKCByeGh0bWxUYWcsIFwiPCQxPjwvJDI+XCIgKTtcblxuXHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdGZvciAoIDsgaSA8IGw7IGkrKyApIHtcblx0XHRcdFx0XHRcdGVsZW0gPSB0aGlzWyBpIF0gfHwge307XG5cblx0XHRcdFx0XHRcdC8vIFJlbW92ZSBlbGVtZW50IG5vZGVzIGFuZCBwcmV2ZW50IG1lbW9yeSBsZWFrc1xuXHRcdFx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICkge1xuXHRcdFx0XHRcdFx0XHRqUXVlcnkuY2xlYW5EYXRhKCBnZXRBbGwoIGVsZW0sIGZhbHNlICkgKTtcblx0XHRcdFx0XHRcdFx0ZWxlbS5pbm5lckhUTUwgPSB2YWx1ZTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRlbGVtID0gMDtcblxuXHRcdFx0XHQvLyBJZiB1c2luZyBpbm5lckhUTUwgdGhyb3dzIGFuIGV4Y2VwdGlvbiwgdXNlIHRoZSBmYWxsYmFjayBtZXRob2Rcblx0XHRcdFx0fSBjYXRjaCggZSApIHt9XG5cdFx0XHR9XG5cblx0XHRcdGlmICggZWxlbSApIHtcblx0XHRcdFx0dGhpcy5lbXB0eSgpLmFwcGVuZCggdmFsdWUgKTtcblx0XHRcdH1cblx0XHR9LCBudWxsLCB2YWx1ZSwgYXJndW1lbnRzLmxlbmd0aCApO1xuXHR9LFxuXG5cdHJlcGxhY2VXaXRoOiBmdW5jdGlvbigpIHtcblx0XHR2YXIgYXJnID0gYXJndW1lbnRzWyAwIF07XG5cblx0XHQvLyBNYWtlIHRoZSBjaGFuZ2VzLCByZXBsYWNpbmcgZWFjaCBjb250ZXh0IGVsZW1lbnQgd2l0aCB0aGUgbmV3IGNvbnRlbnRcblx0XHR0aGlzLmRvbU1hbmlwKCBhcmd1bWVudHMsIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0YXJnID0gdGhpcy5wYXJlbnROb2RlO1xuXG5cdFx0XHRqUXVlcnkuY2xlYW5EYXRhKCBnZXRBbGwoIHRoaXMgKSApO1xuXG5cdFx0XHRpZiAoIGFyZyApIHtcblx0XHRcdFx0YXJnLnJlcGxhY2VDaGlsZCggZWxlbSwgdGhpcyApO1xuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdFx0Ly8gRm9yY2UgcmVtb3ZhbCBpZiB0aGVyZSB3YXMgbm8gbmV3IGNvbnRlbnQgKGUuZy4sIGZyb20gZW1wdHkgYXJndW1lbnRzKVxuXHRcdHJldHVybiBhcmcgJiYgKGFyZy5sZW5ndGggfHwgYXJnLm5vZGVUeXBlKSA/IHRoaXMgOiB0aGlzLnJlbW92ZSgpO1xuXHR9LFxuXG5cdGRldGFjaDogZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHJldHVybiB0aGlzLnJlbW92ZSggc2VsZWN0b3IsIHRydWUgKTtcblx0fSxcblxuXHRkb21NYW5pcDogZnVuY3Rpb24oIGFyZ3MsIGNhbGxiYWNrICkge1xuXG5cdFx0Ly8gRmxhdHRlbiBhbnkgbmVzdGVkIGFycmF5c1xuXHRcdGFyZ3MgPSBjb25jYXQuYXBwbHkoIFtdLCBhcmdzICk7XG5cblx0XHR2YXIgZnJhZ21lbnQsIGZpcnN0LCBzY3JpcHRzLCBoYXNTY3JpcHRzLCBub2RlLCBkb2MsXG5cdFx0XHRpID0gMCxcblx0XHRcdGwgPSB0aGlzLmxlbmd0aCxcblx0XHRcdHNldCA9IHRoaXMsXG5cdFx0XHRpTm9DbG9uZSA9IGwgLSAxLFxuXHRcdFx0dmFsdWUgPSBhcmdzWyAwIF0sXG5cdFx0XHRpc0Z1bmN0aW9uID0galF1ZXJ5LmlzRnVuY3Rpb24oIHZhbHVlICk7XG5cblx0XHQvLyBXZSBjYW4ndCBjbG9uZU5vZGUgZnJhZ21lbnRzIHRoYXQgY29udGFpbiBjaGVja2VkLCBpbiBXZWJLaXRcblx0XHRpZiAoIGlzRnVuY3Rpb24gfHxcblx0XHRcdFx0KCBsID4gMSAmJiB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgJiZcblx0XHRcdFx0XHQhc3VwcG9ydC5jaGVja0Nsb25lICYmIHJjaGVja2VkLnRlc3QoIHZhbHVlICkgKSApIHtcblx0XHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oIGluZGV4ICkge1xuXHRcdFx0XHR2YXIgc2VsZiA9IHNldC5lcSggaW5kZXggKTtcblx0XHRcdFx0aWYgKCBpc0Z1bmN0aW9uICkge1xuXHRcdFx0XHRcdGFyZ3NbIDAgXSA9IHZhbHVlLmNhbGwoIHRoaXMsIGluZGV4LCBzZWxmLmh0bWwoKSApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHNlbGYuZG9tTWFuaXAoIGFyZ3MsIGNhbGxiYWNrICk7XG5cdFx0XHR9KTtcblx0XHR9XG5cblx0XHRpZiAoIGwgKSB7XG5cdFx0XHRmcmFnbWVudCA9IGpRdWVyeS5idWlsZEZyYWdtZW50KCBhcmdzLCB0aGlzWyAwIF0ub3duZXJEb2N1bWVudCwgZmFsc2UsIHRoaXMgKTtcblx0XHRcdGZpcnN0ID0gZnJhZ21lbnQuZmlyc3RDaGlsZDtcblxuXHRcdFx0aWYgKCBmcmFnbWVudC5jaGlsZE5vZGVzLmxlbmd0aCA9PT0gMSApIHtcblx0XHRcdFx0ZnJhZ21lbnQgPSBmaXJzdDtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBmaXJzdCApIHtcblx0XHRcdFx0c2NyaXB0cyA9IGpRdWVyeS5tYXAoIGdldEFsbCggZnJhZ21lbnQsIFwic2NyaXB0XCIgKSwgZGlzYWJsZVNjcmlwdCApO1xuXHRcdFx0XHRoYXNTY3JpcHRzID0gc2NyaXB0cy5sZW5ndGg7XG5cblx0XHRcdFx0Ly8gVXNlIHRoZSBvcmlnaW5hbCBmcmFnbWVudCBmb3IgdGhlIGxhc3QgaXRlbSBpbnN0ZWFkIG9mIHRoZSBmaXJzdCBiZWNhdXNlIGl0IGNhbiBlbmQgdXBcblx0XHRcdFx0Ly8gYmVpbmcgZW1wdGllZCBpbmNvcnJlY3RseSBpbiBjZXJ0YWluIHNpdHVhdGlvbnMgKCM4MDcwKS5cblx0XHRcdFx0Zm9yICggOyBpIDwgbDsgaSsrICkge1xuXHRcdFx0XHRcdG5vZGUgPSBmcmFnbWVudDtcblxuXHRcdFx0XHRcdGlmICggaSAhPT0gaU5vQ2xvbmUgKSB7XG5cdFx0XHRcdFx0XHRub2RlID0galF1ZXJ5LmNsb25lKCBub2RlLCB0cnVlLCB0cnVlICk7XG5cblx0XHRcdFx0XHRcdC8vIEtlZXAgcmVmZXJlbmNlcyB0byBjbG9uZWQgc2NyaXB0cyBmb3IgbGF0ZXIgcmVzdG9yYXRpb25cblx0XHRcdFx0XHRcdGlmICggaGFzU2NyaXB0cyApIHtcblx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogUXRXZWJLaXRcblx0XHRcdFx0XHRcdFx0Ly8galF1ZXJ5Lm1lcmdlIGJlY2F1c2UgcHVzaC5hcHBseShfLCBhcnJheWxpa2UpIHRocm93c1xuXHRcdFx0XHRcdFx0XHRqUXVlcnkubWVyZ2UoIHNjcmlwdHMsIGdldEFsbCggbm9kZSwgXCJzY3JpcHRcIiApICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Y2FsbGJhY2suY2FsbCggdGhpc1sgaSBdLCBub2RlLCBpICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoIGhhc1NjcmlwdHMgKSB7XG5cdFx0XHRcdFx0ZG9jID0gc2NyaXB0c1sgc2NyaXB0cy5sZW5ndGggLSAxIF0ub3duZXJEb2N1bWVudDtcblxuXHRcdFx0XHRcdC8vIFJlZW5hYmxlIHNjcmlwdHNcblx0XHRcdFx0XHRqUXVlcnkubWFwKCBzY3JpcHRzLCByZXN0b3JlU2NyaXB0ICk7XG5cblx0XHRcdFx0XHQvLyBFdmFsdWF0ZSBleGVjdXRhYmxlIHNjcmlwdHMgb24gZmlyc3QgZG9jdW1lbnQgaW5zZXJ0aW9uXG5cdFx0XHRcdFx0Zm9yICggaSA9IDA7IGkgPCBoYXNTY3JpcHRzOyBpKysgKSB7XG5cdFx0XHRcdFx0XHRub2RlID0gc2NyaXB0c1sgaSBdO1xuXHRcdFx0XHRcdFx0aWYgKCByc2NyaXB0VHlwZS50ZXN0KCBub2RlLnR5cGUgfHwgXCJcIiApICYmXG5cdFx0XHRcdFx0XHRcdCFkYXRhX3ByaXYuYWNjZXNzKCBub2RlLCBcImdsb2JhbEV2YWxcIiApICYmIGpRdWVyeS5jb250YWlucyggZG9jLCBub2RlICkgKSB7XG5cblx0XHRcdFx0XHRcdFx0aWYgKCBub2RlLnNyYyApIHtcblx0XHRcdFx0XHRcdFx0XHQvLyBPcHRpb25hbCBBSkFYIGRlcGVuZGVuY3ksIGJ1dCB3b24ndCBydW4gc2NyaXB0cyBpZiBub3QgcHJlc2VudFxuXHRcdFx0XHRcdFx0XHRcdGlmICggalF1ZXJ5Ll9ldmFsVXJsICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0alF1ZXJ5Ll9ldmFsVXJsKCBub2RlLnNyYyApO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRqUXVlcnkuZ2xvYmFsRXZhbCggbm9kZS50ZXh0Q29udGVudC5yZXBsYWNlKCByY2xlYW5TY3JpcHQsIFwiXCIgKSApO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cbn0pO1xuXG5qUXVlcnkuZWFjaCh7XG5cdGFwcGVuZFRvOiBcImFwcGVuZFwiLFxuXHRwcmVwZW5kVG86IFwicHJlcGVuZFwiLFxuXHRpbnNlcnRCZWZvcmU6IFwiYmVmb3JlXCIsXG5cdGluc2VydEFmdGVyOiBcImFmdGVyXCIsXG5cdHJlcGxhY2VBbGw6IFwicmVwbGFjZVdpdGhcIlxufSwgZnVuY3Rpb24oIG5hbWUsIG9yaWdpbmFsICkge1xuXHRqUXVlcnkuZm5bIG5hbWUgXSA9IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHR2YXIgZWxlbXMsXG5cdFx0XHRyZXQgPSBbXSxcblx0XHRcdGluc2VydCA9IGpRdWVyeSggc2VsZWN0b3IgKSxcblx0XHRcdGxhc3QgPSBpbnNlcnQubGVuZ3RoIC0gMSxcblx0XHRcdGkgPSAwO1xuXG5cdFx0Zm9yICggOyBpIDw9IGxhc3Q7IGkrKyApIHtcblx0XHRcdGVsZW1zID0gaSA9PT0gbGFzdCA/IHRoaXMgOiB0aGlzLmNsb25lKCB0cnVlICk7XG5cdFx0XHRqUXVlcnkoIGluc2VydFsgaSBdIClbIG9yaWdpbmFsIF0oIGVsZW1zICk7XG5cblx0XHRcdC8vIFN1cHBvcnQ6IFF0V2ViS2l0XG5cdFx0XHQvLyAuZ2V0KCkgYmVjYXVzZSBwdXNoLmFwcGx5KF8sIGFycmF5bGlrZSkgdGhyb3dzXG5cdFx0XHRwdXNoLmFwcGx5KCByZXQsIGVsZW1zLmdldCgpICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCByZXQgKTtcblx0fTtcbn0pO1xuXG5cbnZhciBpZnJhbWUsXG5cdGVsZW1kaXNwbGF5ID0ge307XG5cbi8qKlxuICogUmV0cmlldmUgdGhlIGFjdHVhbCBkaXNwbGF5IG9mIGEgZWxlbWVudFxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgbm9kZU5hbWUgb2YgdGhlIGVsZW1lbnRcbiAqIEBwYXJhbSB7T2JqZWN0fSBkb2MgRG9jdW1lbnQgb2JqZWN0XG4gKi9cbi8vIENhbGxlZCBvbmx5IGZyb20gd2l0aGluIGRlZmF1bHREaXNwbGF5XG5mdW5jdGlvbiBhY3R1YWxEaXNwbGF5KCBuYW1lLCBkb2MgKSB7XG5cdHZhciBzdHlsZSxcblx0XHRlbGVtID0galF1ZXJ5KCBkb2MuY3JlYXRlRWxlbWVudCggbmFtZSApICkuYXBwZW5kVG8oIGRvYy5ib2R5ICksXG5cblx0XHQvLyBnZXREZWZhdWx0Q29tcHV0ZWRTdHlsZSBtaWdodCBiZSByZWxpYWJseSB1c2VkIG9ubHkgb24gYXR0YWNoZWQgZWxlbWVudFxuXHRcdGRpc3BsYXkgPSB3aW5kb3cuZ2V0RGVmYXVsdENvbXB1dGVkU3R5bGUgJiYgKCBzdHlsZSA9IHdpbmRvdy5nZXREZWZhdWx0Q29tcHV0ZWRTdHlsZSggZWxlbVsgMCBdICkgKSA/XG5cblx0XHRcdC8vIFVzZSBvZiB0aGlzIG1ldGhvZCBpcyBhIHRlbXBvcmFyeSBmaXggKG1vcmUgbGlrZSBvcHRpbWl6YXRpb24pIHVudGlsIHNvbWV0aGluZyBiZXR0ZXIgY29tZXMgYWxvbmcsXG5cdFx0XHQvLyBzaW5jZSBpdCB3YXMgcmVtb3ZlZCBmcm9tIHNwZWNpZmljYXRpb24gYW5kIHN1cHBvcnRlZCBvbmx5IGluIEZGXG5cdFx0XHRzdHlsZS5kaXNwbGF5IDogalF1ZXJ5LmNzcyggZWxlbVsgMCBdLCBcImRpc3BsYXlcIiApO1xuXG5cdC8vIFdlIGRvbid0IGhhdmUgYW55IGRhdGEgc3RvcmVkIG9uIHRoZSBlbGVtZW50LFxuXHQvLyBzbyB1c2UgXCJkZXRhY2hcIiBtZXRob2QgYXMgZmFzdCB3YXkgdG8gZ2V0IHJpZCBvZiB0aGUgZWxlbWVudFxuXHRlbGVtLmRldGFjaCgpO1xuXG5cdHJldHVybiBkaXNwbGF5O1xufVxuXG4vKipcbiAqIFRyeSB0byBkZXRlcm1pbmUgdGhlIGRlZmF1bHQgZGlzcGxheSB2YWx1ZSBvZiBhbiBlbGVtZW50XG4gKiBAcGFyYW0ge1N0cmluZ30gbm9kZU5hbWVcbiAqL1xuZnVuY3Rpb24gZGVmYXVsdERpc3BsYXkoIG5vZGVOYW1lICkge1xuXHR2YXIgZG9jID0gZG9jdW1lbnQsXG5cdFx0ZGlzcGxheSA9IGVsZW1kaXNwbGF5WyBub2RlTmFtZSBdO1xuXG5cdGlmICggIWRpc3BsYXkgKSB7XG5cdFx0ZGlzcGxheSA9IGFjdHVhbERpc3BsYXkoIG5vZGVOYW1lLCBkb2MgKTtcblxuXHRcdC8vIElmIHRoZSBzaW1wbGUgd2F5IGZhaWxzLCByZWFkIGZyb20gaW5zaWRlIGFuIGlmcmFtZVxuXHRcdGlmICggZGlzcGxheSA9PT0gXCJub25lXCIgfHwgIWRpc3BsYXkgKSB7XG5cblx0XHRcdC8vIFVzZSB0aGUgYWxyZWFkeS1jcmVhdGVkIGlmcmFtZSBpZiBwb3NzaWJsZVxuXHRcdFx0aWZyYW1lID0gKGlmcmFtZSB8fCBqUXVlcnkoIFwiPGlmcmFtZSBmcmFtZWJvcmRlcj0nMCcgd2lkdGg9JzAnIGhlaWdodD0nMCcvPlwiICkpLmFwcGVuZFRvKCBkb2MuZG9jdW1lbnRFbGVtZW50ICk7XG5cblx0XHRcdC8vIEFsd2F5cyB3cml0ZSBhIG5ldyBIVE1MIHNrZWxldG9uIHNvIFdlYmtpdCBhbmQgRmlyZWZveCBkb24ndCBjaG9rZSBvbiByZXVzZVxuXHRcdFx0ZG9jID0gaWZyYW1lWyAwIF0uY29udGVudERvY3VtZW50O1xuXG5cdFx0XHQvLyBTdXBwb3J0OiBJRVxuXHRcdFx0ZG9jLndyaXRlKCk7XG5cdFx0XHRkb2MuY2xvc2UoKTtcblxuXHRcdFx0ZGlzcGxheSA9IGFjdHVhbERpc3BsYXkoIG5vZGVOYW1lLCBkb2MgKTtcblx0XHRcdGlmcmFtZS5kZXRhY2goKTtcblx0XHR9XG5cblx0XHQvLyBTdG9yZSB0aGUgY29ycmVjdCBkZWZhdWx0IGRpc3BsYXlcblx0XHRlbGVtZGlzcGxheVsgbm9kZU5hbWUgXSA9IGRpc3BsYXk7XG5cdH1cblxuXHRyZXR1cm4gZGlzcGxheTtcbn1cbnZhciBybWFyZ2luID0gKC9ebWFyZ2luLyk7XG5cbnZhciBybnVtbm9ucHggPSBuZXcgUmVnRXhwKCBcIl4oXCIgKyBwbnVtICsgXCIpKD8hcHgpW2EteiVdKyRcIiwgXCJpXCIgKTtcblxudmFyIGdldFN0eWxlcyA9IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdC8vIFN1cHBvcnQ6IElFPD0xMSssIEZpcmVmb3g8PTMwKyAoIzE1MDk4LCAjMTQxNTApXG5cdFx0Ly8gSUUgdGhyb3dzIG9uIGVsZW1lbnRzIGNyZWF0ZWQgaW4gcG9wdXBzXG5cdFx0Ly8gRkYgbWVhbndoaWxlIHRocm93cyBvbiBmcmFtZSBlbGVtZW50cyB0aHJvdWdoIFwiZGVmYXVsdFZpZXcuZ2V0Q29tcHV0ZWRTdHlsZVwiXG5cdFx0aWYgKCBlbGVtLm93bmVyRG9jdW1lbnQuZGVmYXVsdFZpZXcub3BlbmVyICkge1xuXHRcdFx0cmV0dXJuIGVsZW0ub3duZXJEb2N1bWVudC5kZWZhdWx0Vmlldy5nZXRDb21wdXRlZFN0eWxlKCBlbGVtLCBudWxsICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKCBlbGVtLCBudWxsICk7XG5cdH07XG5cblxuXG5mdW5jdGlvbiBjdXJDU1MoIGVsZW0sIG5hbWUsIGNvbXB1dGVkICkge1xuXHR2YXIgd2lkdGgsIG1pbldpZHRoLCBtYXhXaWR0aCwgcmV0LFxuXHRcdHN0eWxlID0gZWxlbS5zdHlsZTtcblxuXHRjb21wdXRlZCA9IGNvbXB1dGVkIHx8IGdldFN0eWxlcyggZWxlbSApO1xuXG5cdC8vIFN1cHBvcnQ6IElFOVxuXHQvLyBnZXRQcm9wZXJ0eVZhbHVlIGlzIG9ubHkgbmVlZGVkIGZvciAuY3NzKCdmaWx0ZXInKSAoIzEyNTM3KVxuXHRpZiAoIGNvbXB1dGVkICkge1xuXHRcdHJldCA9IGNvbXB1dGVkLmdldFByb3BlcnR5VmFsdWUoIG5hbWUgKSB8fCBjb21wdXRlZFsgbmFtZSBdO1xuXHR9XG5cblx0aWYgKCBjb21wdXRlZCApIHtcblxuXHRcdGlmICggcmV0ID09PSBcIlwiICYmICFqUXVlcnkuY29udGFpbnMoIGVsZW0ub3duZXJEb2N1bWVudCwgZWxlbSApICkge1xuXHRcdFx0cmV0ID0galF1ZXJ5LnN0eWxlKCBlbGVtLCBuYW1lICk7XG5cdFx0fVxuXG5cdFx0Ly8gU3VwcG9ydDogaU9TIDwgNlxuXHRcdC8vIEEgdHJpYnV0ZSB0byB0aGUgXCJhd2Vzb21lIGhhY2sgYnkgRGVhbiBFZHdhcmRzXCJcblx0XHQvLyBpT1MgPCA2IChhdCBsZWFzdCkgcmV0dXJucyBwZXJjZW50YWdlIGZvciBhIGxhcmdlciBzZXQgb2YgdmFsdWVzLCBidXQgd2lkdGggc2VlbXMgdG8gYmUgcmVsaWFibHkgcGl4ZWxzXG5cdFx0Ly8gdGhpcyBpcyBhZ2FpbnN0IHRoZSBDU1NPTSBkcmFmdCBzcGVjOiBodHRwOi8vZGV2LnczLm9yZy9jc3N3Zy9jc3NvbS8jcmVzb2x2ZWQtdmFsdWVzXG5cdFx0aWYgKCBybnVtbm9ucHgudGVzdCggcmV0ICkgJiYgcm1hcmdpbi50ZXN0KCBuYW1lICkgKSB7XG5cblx0XHRcdC8vIFJlbWVtYmVyIHRoZSBvcmlnaW5hbCB2YWx1ZXNcblx0XHRcdHdpZHRoID0gc3R5bGUud2lkdGg7XG5cdFx0XHRtaW5XaWR0aCA9IHN0eWxlLm1pbldpZHRoO1xuXHRcdFx0bWF4V2lkdGggPSBzdHlsZS5tYXhXaWR0aDtcblxuXHRcdFx0Ly8gUHV0IGluIHRoZSBuZXcgdmFsdWVzIHRvIGdldCBhIGNvbXB1dGVkIHZhbHVlIG91dFxuXHRcdFx0c3R5bGUubWluV2lkdGggPSBzdHlsZS5tYXhXaWR0aCA9IHN0eWxlLndpZHRoID0gcmV0O1xuXHRcdFx0cmV0ID0gY29tcHV0ZWQud2lkdGg7XG5cblx0XHRcdC8vIFJldmVydCB0aGUgY2hhbmdlZCB2YWx1ZXNcblx0XHRcdHN0eWxlLndpZHRoID0gd2lkdGg7XG5cdFx0XHRzdHlsZS5taW5XaWR0aCA9IG1pbldpZHRoO1xuXHRcdFx0c3R5bGUubWF4V2lkdGggPSBtYXhXaWR0aDtcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gcmV0ICE9PSB1bmRlZmluZWQgP1xuXHRcdC8vIFN1cHBvcnQ6IElFXG5cdFx0Ly8gSUUgcmV0dXJucyB6SW5kZXggdmFsdWUgYXMgYW4gaW50ZWdlci5cblx0XHRyZXQgKyBcIlwiIDpcblx0XHRyZXQ7XG59XG5cblxuZnVuY3Rpb24gYWRkR2V0SG9va0lmKCBjb25kaXRpb25GbiwgaG9va0ZuICkge1xuXHQvLyBEZWZpbmUgdGhlIGhvb2ssIHdlJ2xsIGNoZWNrIG9uIHRoZSBmaXJzdCBydW4gaWYgaXQncyByZWFsbHkgbmVlZGVkLlxuXHRyZXR1cm4ge1xuXHRcdGdldDogZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoIGNvbmRpdGlvbkZuKCkgKSB7XG5cdFx0XHRcdC8vIEhvb2sgbm90IG5lZWRlZCAob3IgaXQncyBub3QgcG9zc2libGUgdG8gdXNlIGl0IGR1ZVxuXHRcdFx0XHQvLyB0byBtaXNzaW5nIGRlcGVuZGVuY3kpLCByZW1vdmUgaXQuXG5cdFx0XHRcdGRlbGV0ZSB0aGlzLmdldDtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBIb29rIG5lZWRlZDsgcmVkZWZpbmUgaXQgc28gdGhhdCB0aGUgc3VwcG9ydCB0ZXN0IGlzIG5vdCBleGVjdXRlZCBhZ2Fpbi5cblx0XHRcdHJldHVybiAodGhpcy5nZXQgPSBob29rRm4pLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKTtcblx0XHR9XG5cdH07XG59XG5cblxuKGZ1bmN0aW9uKCkge1xuXHR2YXIgcGl4ZWxQb3NpdGlvblZhbCwgYm94U2l6aW5nUmVsaWFibGVWYWwsXG5cdFx0ZG9jRWxlbSA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCxcblx0XHRjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImRpdlwiICksXG5cdFx0ZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJkaXZcIiApO1xuXG5cdGlmICggIWRpdi5zdHlsZSApIHtcblx0XHRyZXR1cm47XG5cdH1cblxuXHQvLyBTdXBwb3J0OiBJRTktMTErXG5cdC8vIFN0eWxlIG9mIGNsb25lZCBlbGVtZW50IGFmZmVjdHMgc291cmNlIGVsZW1lbnQgY2xvbmVkICgjODkwOClcblx0ZGl2LnN0eWxlLmJhY2tncm91bmRDbGlwID0gXCJjb250ZW50LWJveFwiO1xuXHRkaXYuY2xvbmVOb2RlKCB0cnVlICkuc3R5bGUuYmFja2dyb3VuZENsaXAgPSBcIlwiO1xuXHRzdXBwb3J0LmNsZWFyQ2xvbmVTdHlsZSA9IGRpdi5zdHlsZS5iYWNrZ3JvdW5kQ2xpcCA9PT0gXCJjb250ZW50LWJveFwiO1xuXG5cdGNvbnRhaW5lci5zdHlsZS5jc3NUZXh0ID0gXCJib3JkZXI6MDt3aWR0aDowO2hlaWdodDowO3RvcDowO2xlZnQ6LTk5OTlweDttYXJnaW4tdG9wOjFweDtcIiArXG5cdFx0XCJwb3NpdGlvbjphYnNvbHV0ZVwiO1xuXHRjb250YWluZXIuYXBwZW5kQ2hpbGQoIGRpdiApO1xuXG5cdC8vIEV4ZWN1dGluZyBib3RoIHBpeGVsUG9zaXRpb24gJiBib3hTaXppbmdSZWxpYWJsZSB0ZXN0cyByZXF1aXJlIG9ubHkgb25lIGxheW91dFxuXHQvLyBzbyB0aGV5J3JlIGV4ZWN1dGVkIGF0IHRoZSBzYW1lIHRpbWUgdG8gc2F2ZSB0aGUgc2Vjb25kIGNvbXB1dGF0aW9uLlxuXHRmdW5jdGlvbiBjb21wdXRlUGl4ZWxQb3NpdGlvbkFuZEJveFNpemluZ1JlbGlhYmxlKCkge1xuXHRcdGRpdi5zdHlsZS5jc3NUZXh0ID1cblx0XHRcdC8vIFN1cHBvcnQ6IEZpcmVmb3g8MjksIEFuZHJvaWQgMi4zXG5cdFx0XHQvLyBWZW5kb3ItcHJlZml4IGJveC1zaXppbmdcblx0XHRcdFwiLXdlYmtpdC1ib3gtc2l6aW5nOmJvcmRlci1ib3g7LW1vei1ib3gtc2l6aW5nOmJvcmRlci1ib3g7XCIgK1xuXHRcdFx0XCJib3gtc2l6aW5nOmJvcmRlci1ib3g7ZGlzcGxheTpibG9jazttYXJnaW4tdG9wOjElO3RvcDoxJTtcIiArXG5cdFx0XHRcImJvcmRlcjoxcHg7cGFkZGluZzoxcHg7d2lkdGg6NHB4O3Bvc2l0aW9uOmFic29sdXRlXCI7XG5cdFx0ZGl2LmlubmVySFRNTCA9IFwiXCI7XG5cdFx0ZG9jRWxlbS5hcHBlbmRDaGlsZCggY29udGFpbmVyICk7XG5cblx0XHR2YXIgZGl2U3R5bGUgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSggZGl2LCBudWxsICk7XG5cdFx0cGl4ZWxQb3NpdGlvblZhbCA9IGRpdlN0eWxlLnRvcCAhPT0gXCIxJVwiO1xuXHRcdGJveFNpemluZ1JlbGlhYmxlVmFsID0gZGl2U3R5bGUud2lkdGggPT09IFwiNHB4XCI7XG5cblx0XHRkb2NFbGVtLnJlbW92ZUNoaWxkKCBjb250YWluZXIgKTtcblx0fVxuXG5cdC8vIFN1cHBvcnQ6IG5vZGUuanMganNkb21cblx0Ly8gRG9uJ3QgYXNzdW1lIHRoYXQgZ2V0Q29tcHV0ZWRTdHlsZSBpcyBhIHByb3BlcnR5IG9mIHRoZSBnbG9iYWwgb2JqZWN0XG5cdGlmICggd2luZG93LmdldENvbXB1dGVkU3R5bGUgKSB7XG5cdFx0alF1ZXJ5LmV4dGVuZCggc3VwcG9ydCwge1xuXHRcdFx0cGl4ZWxQb3NpdGlvbjogZnVuY3Rpb24oKSB7XG5cblx0XHRcdFx0Ly8gVGhpcyB0ZXN0IGlzIGV4ZWN1dGVkIG9ubHkgb25jZSBidXQgd2Ugc3RpbGwgZG8gbWVtb2l6aW5nXG5cdFx0XHRcdC8vIHNpbmNlIHdlIGNhbiB1c2UgdGhlIGJveFNpemluZ1JlbGlhYmxlIHByZS1jb21wdXRpbmcuXG5cdFx0XHRcdC8vIE5vIG5lZWQgdG8gY2hlY2sgaWYgdGhlIHRlc3Qgd2FzIGFscmVhZHkgcGVyZm9ybWVkLCB0aG91Z2guXG5cdFx0XHRcdGNvbXB1dGVQaXhlbFBvc2l0aW9uQW5kQm94U2l6aW5nUmVsaWFibGUoKTtcblx0XHRcdFx0cmV0dXJuIHBpeGVsUG9zaXRpb25WYWw7XG5cdFx0XHR9LFxuXHRcdFx0Ym94U2l6aW5nUmVsaWFibGU6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoIGJveFNpemluZ1JlbGlhYmxlVmFsID09IG51bGwgKSB7XG5cdFx0XHRcdFx0Y29tcHV0ZVBpeGVsUG9zaXRpb25BbmRCb3hTaXppbmdSZWxpYWJsZSgpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBib3hTaXppbmdSZWxpYWJsZVZhbDtcblx0XHRcdH0sXG5cdFx0XHRyZWxpYWJsZU1hcmdpblJpZ2h0OiBmdW5jdGlvbigpIHtcblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDIuM1xuXHRcdFx0XHQvLyBDaGVjayBpZiBkaXYgd2l0aCBleHBsaWNpdCB3aWR0aCBhbmQgbm8gbWFyZ2luLXJpZ2h0IGluY29ycmVjdGx5XG5cdFx0XHRcdC8vIGdldHMgY29tcHV0ZWQgbWFyZ2luLXJpZ2h0IGJhc2VkIG9uIHdpZHRoIG9mIGNvbnRhaW5lci4gKCMzMzMzKVxuXHRcdFx0XHQvLyBXZWJLaXQgQnVnIDEzMzQzIC0gZ2V0Q29tcHV0ZWRTdHlsZSByZXR1cm5zIHdyb25nIHZhbHVlIGZvciBtYXJnaW4tcmlnaHRcblx0XHRcdFx0Ly8gVGhpcyBzdXBwb3J0IGZ1bmN0aW9uIGlzIG9ubHkgZXhlY3V0ZWQgb25jZSBzbyBubyBtZW1vaXppbmcgaXMgbmVlZGVkLlxuXHRcdFx0XHR2YXIgcmV0LFxuXHRcdFx0XHRcdG1hcmdpbkRpdiA9IGRpdi5hcHBlbmRDaGlsZCggZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJkaXZcIiApICk7XG5cblx0XHRcdFx0Ly8gUmVzZXQgQ1NTOiBib3gtc2l6aW5nOyBkaXNwbGF5OyBtYXJnaW47IGJvcmRlcjsgcGFkZGluZ1xuXHRcdFx0XHRtYXJnaW5EaXYuc3R5bGUuY3NzVGV4dCA9IGRpdi5zdHlsZS5jc3NUZXh0ID1cblx0XHRcdFx0XHQvLyBTdXBwb3J0OiBGaXJlZm94PDI5LCBBbmRyb2lkIDIuM1xuXHRcdFx0XHRcdC8vIFZlbmRvci1wcmVmaXggYm94LXNpemluZ1xuXHRcdFx0XHRcdFwiLXdlYmtpdC1ib3gtc2l6aW5nOmNvbnRlbnQtYm94Oy1tb3otYm94LXNpemluZzpjb250ZW50LWJveDtcIiArXG5cdFx0XHRcdFx0XCJib3gtc2l6aW5nOmNvbnRlbnQtYm94O2Rpc3BsYXk6YmxvY2s7bWFyZ2luOjA7Ym9yZGVyOjA7cGFkZGluZzowXCI7XG5cdFx0XHRcdG1hcmdpbkRpdi5zdHlsZS5tYXJnaW5SaWdodCA9IG1hcmdpbkRpdi5zdHlsZS53aWR0aCA9IFwiMFwiO1xuXHRcdFx0XHRkaXYuc3R5bGUud2lkdGggPSBcIjFweFwiO1xuXHRcdFx0XHRkb2NFbGVtLmFwcGVuZENoaWxkKCBjb250YWluZXIgKTtcblxuXHRcdFx0XHRyZXQgPSAhcGFyc2VGbG9hdCggd2luZG93LmdldENvbXB1dGVkU3R5bGUoIG1hcmdpbkRpdiwgbnVsbCApLm1hcmdpblJpZ2h0ICk7XG5cblx0XHRcdFx0ZG9jRWxlbS5yZW1vdmVDaGlsZCggY29udGFpbmVyICk7XG5cdFx0XHRcdGRpdi5yZW1vdmVDaGlsZCggbWFyZ2luRGl2ICk7XG5cblx0XHRcdFx0cmV0dXJuIHJldDtcblx0XHRcdH1cblx0XHR9KTtcblx0fVxufSkoKTtcblxuXG4vLyBBIG1ldGhvZCBmb3IgcXVpY2tseSBzd2FwcGluZyBpbi9vdXQgQ1NTIHByb3BlcnRpZXMgdG8gZ2V0IGNvcnJlY3QgY2FsY3VsYXRpb25zLlxualF1ZXJ5LnN3YXAgPSBmdW5jdGlvbiggZWxlbSwgb3B0aW9ucywgY2FsbGJhY2ssIGFyZ3MgKSB7XG5cdHZhciByZXQsIG5hbWUsXG5cdFx0b2xkID0ge307XG5cblx0Ly8gUmVtZW1iZXIgdGhlIG9sZCB2YWx1ZXMsIGFuZCBpbnNlcnQgdGhlIG5ldyBvbmVzXG5cdGZvciAoIG5hbWUgaW4gb3B0aW9ucyApIHtcblx0XHRvbGRbIG5hbWUgXSA9IGVsZW0uc3R5bGVbIG5hbWUgXTtcblx0XHRlbGVtLnN0eWxlWyBuYW1lIF0gPSBvcHRpb25zWyBuYW1lIF07XG5cdH1cblxuXHRyZXQgPSBjYWxsYmFjay5hcHBseSggZWxlbSwgYXJncyB8fCBbXSApO1xuXG5cdC8vIFJldmVydCB0aGUgb2xkIHZhbHVlc1xuXHRmb3IgKCBuYW1lIGluIG9wdGlvbnMgKSB7XG5cdFx0ZWxlbS5zdHlsZVsgbmFtZSBdID0gb2xkWyBuYW1lIF07XG5cdH1cblxuXHRyZXR1cm4gcmV0O1xufTtcblxuXG52YXJcblx0Ly8gU3dhcHBhYmxlIGlmIGRpc3BsYXkgaXMgbm9uZSBvciBzdGFydHMgd2l0aCB0YWJsZSBleGNlcHQgXCJ0YWJsZVwiLCBcInRhYmxlLWNlbGxcIiwgb3IgXCJ0YWJsZS1jYXB0aW9uXCJcblx0Ly8gU2VlIGhlcmUgZm9yIGRpc3BsYXkgdmFsdWVzOiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL0NTUy9kaXNwbGF5XG5cdHJkaXNwbGF5c3dhcCA9IC9eKG5vbmV8dGFibGUoPyEtY1tlYV0pLispLyxcblx0cm51bXNwbGl0ID0gbmV3IFJlZ0V4cCggXCJeKFwiICsgcG51bSArIFwiKSguKikkXCIsIFwiaVwiICksXG5cdHJyZWxOdW0gPSBuZXcgUmVnRXhwKCBcIl4oWystXSk9KFwiICsgcG51bSArIFwiKVwiLCBcImlcIiApLFxuXG5cdGNzc1Nob3cgPSB7IHBvc2l0aW9uOiBcImFic29sdXRlXCIsIHZpc2liaWxpdHk6IFwiaGlkZGVuXCIsIGRpc3BsYXk6IFwiYmxvY2tcIiB9LFxuXHRjc3NOb3JtYWxUcmFuc2Zvcm0gPSB7XG5cdFx0bGV0dGVyU3BhY2luZzogXCIwXCIsXG5cdFx0Zm9udFdlaWdodDogXCI0MDBcIlxuXHR9LFxuXG5cdGNzc1ByZWZpeGVzID0gWyBcIldlYmtpdFwiLCBcIk9cIiwgXCJNb3pcIiwgXCJtc1wiIF07XG5cbi8vIFJldHVybiBhIGNzcyBwcm9wZXJ0eSBtYXBwZWQgdG8gYSBwb3RlbnRpYWxseSB2ZW5kb3IgcHJlZml4ZWQgcHJvcGVydHlcbmZ1bmN0aW9uIHZlbmRvclByb3BOYW1lKCBzdHlsZSwgbmFtZSApIHtcblxuXHQvLyBTaG9ydGN1dCBmb3IgbmFtZXMgdGhhdCBhcmUgbm90IHZlbmRvciBwcmVmaXhlZFxuXHRpZiAoIG5hbWUgaW4gc3R5bGUgKSB7XG5cdFx0cmV0dXJuIG5hbWU7XG5cdH1cblxuXHQvLyBDaGVjayBmb3IgdmVuZG9yIHByZWZpeGVkIG5hbWVzXG5cdHZhciBjYXBOYW1lID0gbmFtZVswXS50b1VwcGVyQ2FzZSgpICsgbmFtZS5zbGljZSgxKSxcblx0XHRvcmlnTmFtZSA9IG5hbWUsXG5cdFx0aSA9IGNzc1ByZWZpeGVzLmxlbmd0aDtcblxuXHR3aGlsZSAoIGktLSApIHtcblx0XHRuYW1lID0gY3NzUHJlZml4ZXNbIGkgXSArIGNhcE5hbWU7XG5cdFx0aWYgKCBuYW1lIGluIHN0eWxlICkge1xuXHRcdFx0cmV0dXJuIG5hbWU7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIG9yaWdOYW1lO1xufVxuXG5mdW5jdGlvbiBzZXRQb3NpdGl2ZU51bWJlciggZWxlbSwgdmFsdWUsIHN1YnRyYWN0ICkge1xuXHR2YXIgbWF0Y2hlcyA9IHJudW1zcGxpdC5leGVjKCB2YWx1ZSApO1xuXHRyZXR1cm4gbWF0Y2hlcyA/XG5cdFx0Ly8gR3VhcmQgYWdhaW5zdCB1bmRlZmluZWQgXCJzdWJ0cmFjdFwiLCBlLmcuLCB3aGVuIHVzZWQgYXMgaW4gY3NzSG9va3Ncblx0XHRNYXRoLm1heCggMCwgbWF0Y2hlc1sgMSBdIC0gKCBzdWJ0cmFjdCB8fCAwICkgKSArICggbWF0Y2hlc1sgMiBdIHx8IFwicHhcIiApIDpcblx0XHR2YWx1ZTtcbn1cblxuZnVuY3Rpb24gYXVnbWVudFdpZHRoT3JIZWlnaHQoIGVsZW0sIG5hbWUsIGV4dHJhLCBpc0JvcmRlckJveCwgc3R5bGVzICkge1xuXHR2YXIgaSA9IGV4dHJhID09PSAoIGlzQm9yZGVyQm94ID8gXCJib3JkZXJcIiA6IFwiY29udGVudFwiICkgP1xuXHRcdC8vIElmIHdlIGFscmVhZHkgaGF2ZSB0aGUgcmlnaHQgbWVhc3VyZW1lbnQsIGF2b2lkIGF1Z21lbnRhdGlvblxuXHRcdDQgOlxuXHRcdC8vIE90aGVyd2lzZSBpbml0aWFsaXplIGZvciBob3Jpem9udGFsIG9yIHZlcnRpY2FsIHByb3BlcnRpZXNcblx0XHRuYW1lID09PSBcIndpZHRoXCIgPyAxIDogMCxcblxuXHRcdHZhbCA9IDA7XG5cblx0Zm9yICggOyBpIDwgNDsgaSArPSAyICkge1xuXHRcdC8vIEJvdGggYm94IG1vZGVscyBleGNsdWRlIG1hcmdpbiwgc28gYWRkIGl0IGlmIHdlIHdhbnQgaXRcblx0XHRpZiAoIGV4dHJhID09PSBcIm1hcmdpblwiICkge1xuXHRcdFx0dmFsICs9IGpRdWVyeS5jc3MoIGVsZW0sIGV4dHJhICsgY3NzRXhwYW5kWyBpIF0sIHRydWUsIHN0eWxlcyApO1xuXHRcdH1cblxuXHRcdGlmICggaXNCb3JkZXJCb3ggKSB7XG5cdFx0XHQvLyBib3JkZXItYm94IGluY2x1ZGVzIHBhZGRpbmcsIHNvIHJlbW92ZSBpdCBpZiB3ZSB3YW50IGNvbnRlbnRcblx0XHRcdGlmICggZXh0cmEgPT09IFwiY29udGVudFwiICkge1xuXHRcdFx0XHR2YWwgLT0galF1ZXJ5LmNzcyggZWxlbSwgXCJwYWRkaW5nXCIgKyBjc3NFeHBhbmRbIGkgXSwgdHJ1ZSwgc3R5bGVzICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEF0IHRoaXMgcG9pbnQsIGV4dHJhIGlzbid0IGJvcmRlciBub3IgbWFyZ2luLCBzbyByZW1vdmUgYm9yZGVyXG5cdFx0XHRpZiAoIGV4dHJhICE9PSBcIm1hcmdpblwiICkge1xuXHRcdFx0XHR2YWwgLT0galF1ZXJ5LmNzcyggZWxlbSwgXCJib3JkZXJcIiArIGNzc0V4cGFuZFsgaSBdICsgXCJXaWR0aFwiLCB0cnVlLCBzdHlsZXMgKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gQXQgdGhpcyBwb2ludCwgZXh0cmEgaXNuJ3QgY29udGVudCwgc28gYWRkIHBhZGRpbmdcblx0XHRcdHZhbCArPSBqUXVlcnkuY3NzKCBlbGVtLCBcInBhZGRpbmdcIiArIGNzc0V4cGFuZFsgaSBdLCB0cnVlLCBzdHlsZXMgKTtcblxuXHRcdFx0Ly8gQXQgdGhpcyBwb2ludCwgZXh0cmEgaXNuJ3QgY29udGVudCBub3IgcGFkZGluZywgc28gYWRkIGJvcmRlclxuXHRcdFx0aWYgKCBleHRyYSAhPT0gXCJwYWRkaW5nXCIgKSB7XG5cdFx0XHRcdHZhbCArPSBqUXVlcnkuY3NzKCBlbGVtLCBcImJvcmRlclwiICsgY3NzRXhwYW5kWyBpIF0gKyBcIldpZHRoXCIsIHRydWUsIHN0eWxlcyApO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiB2YWw7XG59XG5cbmZ1bmN0aW9uIGdldFdpZHRoT3JIZWlnaHQoIGVsZW0sIG5hbWUsIGV4dHJhICkge1xuXG5cdC8vIFN0YXJ0IHdpdGggb2Zmc2V0IHByb3BlcnR5LCB3aGljaCBpcyBlcXVpdmFsZW50IHRvIHRoZSBib3JkZXItYm94IHZhbHVlXG5cdHZhciB2YWx1ZUlzQm9yZGVyQm94ID0gdHJ1ZSxcblx0XHR2YWwgPSBuYW1lID09PSBcIndpZHRoXCIgPyBlbGVtLm9mZnNldFdpZHRoIDogZWxlbS5vZmZzZXRIZWlnaHQsXG5cdFx0c3R5bGVzID0gZ2V0U3R5bGVzKCBlbGVtICksXG5cdFx0aXNCb3JkZXJCb3ggPSBqUXVlcnkuY3NzKCBlbGVtLCBcImJveFNpemluZ1wiLCBmYWxzZSwgc3R5bGVzICkgPT09IFwiYm9yZGVyLWJveFwiO1xuXG5cdC8vIFNvbWUgbm9uLWh0bWwgZWxlbWVudHMgcmV0dXJuIHVuZGVmaW5lZCBmb3Igb2Zmc2V0V2lkdGgsIHNvIGNoZWNrIGZvciBudWxsL3VuZGVmaW5lZFxuXHQvLyBzdmcgLSBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD02NDkyODVcblx0Ly8gTWF0aE1MIC0gaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9NDkxNjY4XG5cdGlmICggdmFsIDw9IDAgfHwgdmFsID09IG51bGwgKSB7XG5cdFx0Ly8gRmFsbCBiYWNrIHRvIGNvbXB1dGVkIHRoZW4gdW5jb21wdXRlZCBjc3MgaWYgbmVjZXNzYXJ5XG5cdFx0dmFsID0gY3VyQ1NTKCBlbGVtLCBuYW1lLCBzdHlsZXMgKTtcblx0XHRpZiAoIHZhbCA8IDAgfHwgdmFsID09IG51bGwgKSB7XG5cdFx0XHR2YWwgPSBlbGVtLnN0eWxlWyBuYW1lIF07XG5cdFx0fVxuXG5cdFx0Ly8gQ29tcHV0ZWQgdW5pdCBpcyBub3QgcGl4ZWxzLiBTdG9wIGhlcmUgYW5kIHJldHVybi5cblx0XHRpZiAoIHJudW1ub25weC50ZXN0KHZhbCkgKSB7XG5cdFx0XHRyZXR1cm4gdmFsO1xuXHRcdH1cblxuXHRcdC8vIENoZWNrIGZvciBzdHlsZSBpbiBjYXNlIGEgYnJvd3NlciB3aGljaCByZXR1cm5zIHVucmVsaWFibGUgdmFsdWVzXG5cdFx0Ly8gZm9yIGdldENvbXB1dGVkU3R5bGUgc2lsZW50bHkgZmFsbHMgYmFjayB0byB0aGUgcmVsaWFibGUgZWxlbS5zdHlsZVxuXHRcdHZhbHVlSXNCb3JkZXJCb3ggPSBpc0JvcmRlckJveCAmJlxuXHRcdFx0KCBzdXBwb3J0LmJveFNpemluZ1JlbGlhYmxlKCkgfHwgdmFsID09PSBlbGVtLnN0eWxlWyBuYW1lIF0gKTtcblxuXHRcdC8vIE5vcm1hbGl6ZSBcIlwiLCBhdXRvLCBhbmQgcHJlcGFyZSBmb3IgZXh0cmFcblx0XHR2YWwgPSBwYXJzZUZsb2F0KCB2YWwgKSB8fCAwO1xuXHR9XG5cblx0Ly8gVXNlIHRoZSBhY3RpdmUgYm94LXNpemluZyBtb2RlbCB0byBhZGQvc3VidHJhY3QgaXJyZWxldmFudCBzdHlsZXNcblx0cmV0dXJuICggdmFsICtcblx0XHRhdWdtZW50V2lkdGhPckhlaWdodChcblx0XHRcdGVsZW0sXG5cdFx0XHRuYW1lLFxuXHRcdFx0ZXh0cmEgfHwgKCBpc0JvcmRlckJveCA/IFwiYm9yZGVyXCIgOiBcImNvbnRlbnRcIiApLFxuXHRcdFx0dmFsdWVJc0JvcmRlckJveCxcblx0XHRcdHN0eWxlc1xuXHRcdClcblx0KSArIFwicHhcIjtcbn1cblxuZnVuY3Rpb24gc2hvd0hpZGUoIGVsZW1lbnRzLCBzaG93ICkge1xuXHR2YXIgZGlzcGxheSwgZWxlbSwgaGlkZGVuLFxuXHRcdHZhbHVlcyA9IFtdLFxuXHRcdGluZGV4ID0gMCxcblx0XHRsZW5ndGggPSBlbGVtZW50cy5sZW5ndGg7XG5cblx0Zm9yICggOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHtcblx0XHRlbGVtID0gZWxlbWVudHNbIGluZGV4IF07XG5cdFx0aWYgKCAhZWxlbS5zdHlsZSApIHtcblx0XHRcdGNvbnRpbnVlO1xuXHRcdH1cblxuXHRcdHZhbHVlc1sgaW5kZXggXSA9IGRhdGFfcHJpdi5nZXQoIGVsZW0sIFwib2xkZGlzcGxheVwiICk7XG5cdFx0ZGlzcGxheSA9IGVsZW0uc3R5bGUuZGlzcGxheTtcblx0XHRpZiAoIHNob3cgKSB7XG5cdFx0XHQvLyBSZXNldCB0aGUgaW5saW5lIGRpc3BsYXkgb2YgdGhpcyBlbGVtZW50IHRvIGxlYXJuIGlmIGl0IGlzXG5cdFx0XHQvLyBiZWluZyBoaWRkZW4gYnkgY2FzY2FkZWQgcnVsZXMgb3Igbm90XG5cdFx0XHRpZiAoICF2YWx1ZXNbIGluZGV4IF0gJiYgZGlzcGxheSA9PT0gXCJub25lXCIgKSB7XG5cdFx0XHRcdGVsZW0uc3R5bGUuZGlzcGxheSA9IFwiXCI7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNldCBlbGVtZW50cyB3aGljaCBoYXZlIGJlZW4gb3ZlcnJpZGRlbiB3aXRoIGRpc3BsYXk6IG5vbmVcblx0XHRcdC8vIGluIGEgc3R5bGVzaGVldCB0byB3aGF0ZXZlciB0aGUgZGVmYXVsdCBicm93c2VyIHN0eWxlIGlzXG5cdFx0XHQvLyBmb3Igc3VjaCBhbiBlbGVtZW50XG5cdFx0XHRpZiAoIGVsZW0uc3R5bGUuZGlzcGxheSA9PT0gXCJcIiAmJiBpc0hpZGRlbiggZWxlbSApICkge1xuXHRcdFx0XHR2YWx1ZXNbIGluZGV4IF0gPSBkYXRhX3ByaXYuYWNjZXNzKCBlbGVtLCBcIm9sZGRpc3BsYXlcIiwgZGVmYXVsdERpc3BsYXkoZWxlbS5ub2RlTmFtZSkgKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0aGlkZGVuID0gaXNIaWRkZW4oIGVsZW0gKTtcblxuXHRcdFx0aWYgKCBkaXNwbGF5ICE9PSBcIm5vbmVcIiB8fCAhaGlkZGVuICkge1xuXHRcdFx0XHRkYXRhX3ByaXYuc2V0KCBlbGVtLCBcIm9sZGRpc3BsYXlcIiwgaGlkZGVuID8gZGlzcGxheSA6IGpRdWVyeS5jc3MoIGVsZW0sIFwiZGlzcGxheVwiICkgKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBTZXQgdGhlIGRpc3BsYXkgb2YgbW9zdCBvZiB0aGUgZWxlbWVudHMgaW4gYSBzZWNvbmQgbG9vcFxuXHQvLyB0byBhdm9pZCB0aGUgY29uc3RhbnQgcmVmbG93XG5cdGZvciAoIGluZGV4ID0gMDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KysgKSB7XG5cdFx0ZWxlbSA9IGVsZW1lbnRzWyBpbmRleCBdO1xuXHRcdGlmICggIWVsZW0uc3R5bGUgKSB7XG5cdFx0XHRjb250aW51ZTtcblx0XHR9XG5cdFx0aWYgKCAhc2hvdyB8fCBlbGVtLnN0eWxlLmRpc3BsYXkgPT09IFwibm9uZVwiIHx8IGVsZW0uc3R5bGUuZGlzcGxheSA9PT0gXCJcIiApIHtcblx0XHRcdGVsZW0uc3R5bGUuZGlzcGxheSA9IHNob3cgPyB2YWx1ZXNbIGluZGV4IF0gfHwgXCJcIiA6IFwibm9uZVwiO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiBlbGVtZW50cztcbn1cblxualF1ZXJ5LmV4dGVuZCh7XG5cblx0Ly8gQWRkIGluIHN0eWxlIHByb3BlcnR5IGhvb2tzIGZvciBvdmVycmlkaW5nIHRoZSBkZWZhdWx0XG5cdC8vIGJlaGF2aW9yIG9mIGdldHRpbmcgYW5kIHNldHRpbmcgYSBzdHlsZSBwcm9wZXJ0eVxuXHRjc3NIb29rczoge1xuXHRcdG9wYWNpdHk6IHtcblx0XHRcdGdldDogZnVuY3Rpb24oIGVsZW0sIGNvbXB1dGVkICkge1xuXHRcdFx0XHRpZiAoIGNvbXB1dGVkICkge1xuXG5cdFx0XHRcdFx0Ly8gV2Ugc2hvdWxkIGFsd2F5cyBnZXQgYSBudW1iZXIgYmFjayBmcm9tIG9wYWNpdHlcblx0XHRcdFx0XHR2YXIgcmV0ID0gY3VyQ1NTKCBlbGVtLCBcIm9wYWNpdHlcIiApO1xuXHRcdFx0XHRcdHJldHVybiByZXQgPT09IFwiXCIgPyBcIjFcIiA6IHJldDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fSxcblxuXHQvLyBEb24ndCBhdXRvbWF0aWNhbGx5IGFkZCBcInB4XCIgdG8gdGhlc2UgcG9zc2libHktdW5pdGxlc3MgcHJvcGVydGllc1xuXHRjc3NOdW1iZXI6IHtcblx0XHRcImNvbHVtbkNvdW50XCI6IHRydWUsXG5cdFx0XCJmaWxsT3BhY2l0eVwiOiB0cnVlLFxuXHRcdFwiZmxleEdyb3dcIjogdHJ1ZSxcblx0XHRcImZsZXhTaHJpbmtcIjogdHJ1ZSxcblx0XHRcImZvbnRXZWlnaHRcIjogdHJ1ZSxcblx0XHRcImxpbmVIZWlnaHRcIjogdHJ1ZSxcblx0XHRcIm9wYWNpdHlcIjogdHJ1ZSxcblx0XHRcIm9yZGVyXCI6IHRydWUsXG5cdFx0XCJvcnBoYW5zXCI6IHRydWUsXG5cdFx0XCJ3aWRvd3NcIjogdHJ1ZSxcblx0XHRcInpJbmRleFwiOiB0cnVlLFxuXHRcdFwiem9vbVwiOiB0cnVlXG5cdH0sXG5cblx0Ly8gQWRkIGluIHByb3BlcnRpZXMgd2hvc2UgbmFtZXMgeW91IHdpc2ggdG8gZml4IGJlZm9yZVxuXHQvLyBzZXR0aW5nIG9yIGdldHRpbmcgdGhlIHZhbHVlXG5cdGNzc1Byb3BzOiB7XG5cdFx0XCJmbG9hdFwiOiBcImNzc0Zsb2F0XCJcblx0fSxcblxuXHQvLyBHZXQgYW5kIHNldCB0aGUgc3R5bGUgcHJvcGVydHkgb24gYSBET00gTm9kZVxuXHRzdHlsZTogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIHZhbHVlLCBleHRyYSApIHtcblxuXHRcdC8vIERvbid0IHNldCBzdHlsZXMgb24gdGV4dCBhbmQgY29tbWVudCBub2Rlc1xuXHRcdGlmICggIWVsZW0gfHwgZWxlbS5ub2RlVHlwZSA9PT0gMyB8fCBlbGVtLm5vZGVUeXBlID09PSA4IHx8ICFlbGVtLnN0eWxlICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIE1ha2Ugc3VyZSB0aGF0IHdlJ3JlIHdvcmtpbmcgd2l0aCB0aGUgcmlnaHQgbmFtZVxuXHRcdHZhciByZXQsIHR5cGUsIGhvb2tzLFxuXHRcdFx0b3JpZ05hbWUgPSBqUXVlcnkuY2FtZWxDYXNlKCBuYW1lICksXG5cdFx0XHRzdHlsZSA9IGVsZW0uc3R5bGU7XG5cblx0XHRuYW1lID0galF1ZXJ5LmNzc1Byb3BzWyBvcmlnTmFtZSBdIHx8ICggalF1ZXJ5LmNzc1Byb3BzWyBvcmlnTmFtZSBdID0gdmVuZG9yUHJvcE5hbWUoIHN0eWxlLCBvcmlnTmFtZSApICk7XG5cblx0XHQvLyBHZXRzIGhvb2sgZm9yIHRoZSBwcmVmaXhlZCB2ZXJzaW9uLCB0aGVuIHVucHJlZml4ZWQgdmVyc2lvblxuXHRcdGhvb2tzID0galF1ZXJ5LmNzc0hvb2tzWyBuYW1lIF0gfHwgalF1ZXJ5LmNzc0hvb2tzWyBvcmlnTmFtZSBdO1xuXG5cdFx0Ly8gQ2hlY2sgaWYgd2UncmUgc2V0dGluZyBhIHZhbHVlXG5cdFx0aWYgKCB2YWx1ZSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0dHlwZSA9IHR5cGVvZiB2YWx1ZTtcblxuXHRcdFx0Ly8gQ29udmVydCBcIis9XCIgb3IgXCItPVwiIHRvIHJlbGF0aXZlIG51bWJlcnMgKCM3MzQ1KVxuXHRcdFx0aWYgKCB0eXBlID09PSBcInN0cmluZ1wiICYmIChyZXQgPSBycmVsTnVtLmV4ZWMoIHZhbHVlICkpICkge1xuXHRcdFx0XHR2YWx1ZSA9ICggcmV0WzFdICsgMSApICogcmV0WzJdICsgcGFyc2VGbG9hdCggalF1ZXJ5LmNzcyggZWxlbSwgbmFtZSApICk7XG5cdFx0XHRcdC8vIEZpeGVzIGJ1ZyAjOTIzN1xuXHRcdFx0XHR0eXBlID0gXCJudW1iZXJcIjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gTWFrZSBzdXJlIHRoYXQgbnVsbCBhbmQgTmFOIHZhbHVlcyBhcmVuJ3Qgc2V0ICgjNzExNilcblx0XHRcdGlmICggdmFsdWUgPT0gbnVsbCB8fCB2YWx1ZSAhPT0gdmFsdWUgKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gSWYgYSBudW1iZXIsIGFkZCAncHgnIHRvIHRoZSAoZXhjZXB0IGZvciBjZXJ0YWluIENTUyBwcm9wZXJ0aWVzKVxuXHRcdFx0aWYgKCB0eXBlID09PSBcIm51bWJlclwiICYmICFqUXVlcnkuY3NzTnVtYmVyWyBvcmlnTmFtZSBdICkge1xuXHRcdFx0XHR2YWx1ZSArPSBcInB4XCI7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFN1cHBvcnQ6IElFOS0xMStcblx0XHRcdC8vIGJhY2tncm91bmQtKiBwcm9wcyBhZmZlY3Qgb3JpZ2luYWwgY2xvbmUncyB2YWx1ZXNcblx0XHRcdGlmICggIXN1cHBvcnQuY2xlYXJDbG9uZVN0eWxlICYmIHZhbHVlID09PSBcIlwiICYmIG5hbWUuaW5kZXhPZiggXCJiYWNrZ3JvdW5kXCIgKSA9PT0gMCApIHtcblx0XHRcdFx0c3R5bGVbIG5hbWUgXSA9IFwiaW5oZXJpdFwiO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBJZiBhIGhvb2sgd2FzIHByb3ZpZGVkLCB1c2UgdGhhdCB2YWx1ZSwgb3RoZXJ3aXNlIGp1c3Qgc2V0IHRoZSBzcGVjaWZpZWQgdmFsdWVcblx0XHRcdGlmICggIWhvb2tzIHx8ICEoXCJzZXRcIiBpbiBob29rcykgfHwgKHZhbHVlID0gaG9va3Muc2V0KCBlbGVtLCB2YWx1ZSwgZXh0cmEgKSkgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0c3R5bGVbIG5hbWUgXSA9IHZhbHVlO1xuXHRcdFx0fVxuXG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIElmIGEgaG9vayB3YXMgcHJvdmlkZWQgZ2V0IHRoZSBub24tY29tcHV0ZWQgdmFsdWUgZnJvbSB0aGVyZVxuXHRcdFx0aWYgKCBob29rcyAmJiBcImdldFwiIGluIGhvb2tzICYmIChyZXQgPSBob29rcy5nZXQoIGVsZW0sIGZhbHNlLCBleHRyYSApKSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRyZXR1cm4gcmV0O1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBPdGhlcndpc2UganVzdCBnZXQgdGhlIHZhbHVlIGZyb20gdGhlIHN0eWxlIG9iamVjdFxuXHRcdFx0cmV0dXJuIHN0eWxlWyBuYW1lIF07XG5cdFx0fVxuXHR9LFxuXG5cdGNzczogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIGV4dHJhLCBzdHlsZXMgKSB7XG5cdFx0dmFyIHZhbCwgbnVtLCBob29rcyxcblx0XHRcdG9yaWdOYW1lID0galF1ZXJ5LmNhbWVsQ2FzZSggbmFtZSApO1xuXG5cdFx0Ly8gTWFrZSBzdXJlIHRoYXQgd2UncmUgd29ya2luZyB3aXRoIHRoZSByaWdodCBuYW1lXG5cdFx0bmFtZSA9IGpRdWVyeS5jc3NQcm9wc1sgb3JpZ05hbWUgXSB8fCAoIGpRdWVyeS5jc3NQcm9wc1sgb3JpZ05hbWUgXSA9IHZlbmRvclByb3BOYW1lKCBlbGVtLnN0eWxlLCBvcmlnTmFtZSApICk7XG5cblx0XHQvLyBUcnkgcHJlZml4ZWQgbmFtZSBmb2xsb3dlZCBieSB0aGUgdW5wcmVmaXhlZCBuYW1lXG5cdFx0aG9va3MgPSBqUXVlcnkuY3NzSG9va3NbIG5hbWUgXSB8fCBqUXVlcnkuY3NzSG9va3NbIG9yaWdOYW1lIF07XG5cblx0XHQvLyBJZiBhIGhvb2sgd2FzIHByb3ZpZGVkIGdldCB0aGUgY29tcHV0ZWQgdmFsdWUgZnJvbSB0aGVyZVxuXHRcdGlmICggaG9va3MgJiYgXCJnZXRcIiBpbiBob29rcyApIHtcblx0XHRcdHZhbCA9IGhvb2tzLmdldCggZWxlbSwgdHJ1ZSwgZXh0cmEgKTtcblx0XHR9XG5cblx0XHQvLyBPdGhlcndpc2UsIGlmIGEgd2F5IHRvIGdldCB0aGUgY29tcHV0ZWQgdmFsdWUgZXhpc3RzLCB1c2UgdGhhdFxuXHRcdGlmICggdmFsID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHR2YWwgPSBjdXJDU1MoIGVsZW0sIG5hbWUsIHN0eWxlcyApO1xuXHRcdH1cblxuXHRcdC8vIENvbnZlcnQgXCJub3JtYWxcIiB0byBjb21wdXRlZCB2YWx1ZVxuXHRcdGlmICggdmFsID09PSBcIm5vcm1hbFwiICYmIG5hbWUgaW4gY3NzTm9ybWFsVHJhbnNmb3JtICkge1xuXHRcdFx0dmFsID0gY3NzTm9ybWFsVHJhbnNmb3JtWyBuYW1lIF07XG5cdFx0fVxuXG5cdFx0Ly8gTWFrZSBudW1lcmljIGlmIGZvcmNlZCBvciBhIHF1YWxpZmllciB3YXMgcHJvdmlkZWQgYW5kIHZhbCBsb29rcyBudW1lcmljXG5cdFx0aWYgKCBleHRyYSA9PT0gXCJcIiB8fCBleHRyYSApIHtcblx0XHRcdG51bSA9IHBhcnNlRmxvYXQoIHZhbCApO1xuXHRcdFx0cmV0dXJuIGV4dHJhID09PSB0cnVlIHx8IGpRdWVyeS5pc051bWVyaWMoIG51bSApID8gbnVtIHx8IDAgOiB2YWw7XG5cdFx0fVxuXHRcdHJldHVybiB2YWw7XG5cdH1cbn0pO1xuXG5qUXVlcnkuZWFjaChbIFwiaGVpZ2h0XCIsIFwid2lkdGhcIiBdLCBmdW5jdGlvbiggaSwgbmFtZSApIHtcblx0alF1ZXJ5LmNzc0hvb2tzWyBuYW1lIF0gPSB7XG5cdFx0Z2V0OiBmdW5jdGlvbiggZWxlbSwgY29tcHV0ZWQsIGV4dHJhICkge1xuXHRcdFx0aWYgKCBjb21wdXRlZCApIHtcblxuXHRcdFx0XHQvLyBDZXJ0YWluIGVsZW1lbnRzIGNhbiBoYXZlIGRpbWVuc2lvbiBpbmZvIGlmIHdlIGludmlzaWJseSBzaG93IHRoZW1cblx0XHRcdFx0Ly8gYnV0IGl0IG11c3QgaGF2ZSBhIGN1cnJlbnQgZGlzcGxheSBzdHlsZSB0aGF0IHdvdWxkIGJlbmVmaXRcblx0XHRcdFx0cmV0dXJuIHJkaXNwbGF5c3dhcC50ZXN0KCBqUXVlcnkuY3NzKCBlbGVtLCBcImRpc3BsYXlcIiApICkgJiYgZWxlbS5vZmZzZXRXaWR0aCA9PT0gMCA/XG5cdFx0XHRcdFx0alF1ZXJ5LnN3YXAoIGVsZW0sIGNzc1Nob3csIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIGdldFdpZHRoT3JIZWlnaHQoIGVsZW0sIG5hbWUsIGV4dHJhICk7XG5cdFx0XHRcdFx0fSkgOlxuXHRcdFx0XHRcdGdldFdpZHRoT3JIZWlnaHQoIGVsZW0sIG5hbWUsIGV4dHJhICk7XG5cdFx0XHR9XG5cdFx0fSxcblxuXHRcdHNldDogZnVuY3Rpb24oIGVsZW0sIHZhbHVlLCBleHRyYSApIHtcblx0XHRcdHZhciBzdHlsZXMgPSBleHRyYSAmJiBnZXRTdHlsZXMoIGVsZW0gKTtcblx0XHRcdHJldHVybiBzZXRQb3NpdGl2ZU51bWJlciggZWxlbSwgdmFsdWUsIGV4dHJhID9cblx0XHRcdFx0YXVnbWVudFdpZHRoT3JIZWlnaHQoXG5cdFx0XHRcdFx0ZWxlbSxcblx0XHRcdFx0XHRuYW1lLFxuXHRcdFx0XHRcdGV4dHJhLFxuXHRcdFx0XHRcdGpRdWVyeS5jc3MoIGVsZW0sIFwiYm94U2l6aW5nXCIsIGZhbHNlLCBzdHlsZXMgKSA9PT0gXCJib3JkZXItYm94XCIsXG5cdFx0XHRcdFx0c3R5bGVzXG5cdFx0XHRcdCkgOiAwXG5cdFx0XHQpO1xuXHRcdH1cblx0fTtcbn0pO1xuXG4vLyBTdXBwb3J0OiBBbmRyb2lkIDIuM1xualF1ZXJ5LmNzc0hvb2tzLm1hcmdpblJpZ2h0ID0gYWRkR2V0SG9va0lmKCBzdXBwb3J0LnJlbGlhYmxlTWFyZ2luUmlnaHQsXG5cdGZ1bmN0aW9uKCBlbGVtLCBjb21wdXRlZCApIHtcblx0XHRpZiAoIGNvbXB1dGVkICkge1xuXHRcdFx0cmV0dXJuIGpRdWVyeS5zd2FwKCBlbGVtLCB7IFwiZGlzcGxheVwiOiBcImlubGluZS1ibG9ja1wiIH0sXG5cdFx0XHRcdGN1ckNTUywgWyBlbGVtLCBcIm1hcmdpblJpZ2h0XCIgXSApO1xuXHRcdH1cblx0fVxuKTtcblxuLy8gVGhlc2UgaG9va3MgYXJlIHVzZWQgYnkgYW5pbWF0ZSB0byBleHBhbmQgcHJvcGVydGllc1xualF1ZXJ5LmVhY2goe1xuXHRtYXJnaW46IFwiXCIsXG5cdHBhZGRpbmc6IFwiXCIsXG5cdGJvcmRlcjogXCJXaWR0aFwiXG59LCBmdW5jdGlvbiggcHJlZml4LCBzdWZmaXggKSB7XG5cdGpRdWVyeS5jc3NIb29rc1sgcHJlZml4ICsgc3VmZml4IF0gPSB7XG5cdFx0ZXhwYW5kOiBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0XHR2YXIgaSA9IDAsXG5cdFx0XHRcdGV4cGFuZGVkID0ge30sXG5cblx0XHRcdFx0Ly8gQXNzdW1lcyBhIHNpbmdsZSBudW1iZXIgaWYgbm90IGEgc3RyaW5nXG5cdFx0XHRcdHBhcnRzID0gdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiID8gdmFsdWUuc3BsaXQoXCIgXCIpIDogWyB2YWx1ZSBdO1xuXG5cdFx0XHRmb3IgKCA7IGkgPCA0OyBpKysgKSB7XG5cdFx0XHRcdGV4cGFuZGVkWyBwcmVmaXggKyBjc3NFeHBhbmRbIGkgXSArIHN1ZmZpeCBdID1cblx0XHRcdFx0XHRwYXJ0c1sgaSBdIHx8IHBhcnRzWyBpIC0gMiBdIHx8IHBhcnRzWyAwIF07XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBleHBhbmRlZDtcblx0XHR9XG5cdH07XG5cblx0aWYgKCAhcm1hcmdpbi50ZXN0KCBwcmVmaXggKSApIHtcblx0XHRqUXVlcnkuY3NzSG9va3NbIHByZWZpeCArIHN1ZmZpeCBdLnNldCA9IHNldFBvc2l0aXZlTnVtYmVyO1xuXHR9XG59KTtcblxualF1ZXJ5LmZuLmV4dGVuZCh7XG5cdGNzczogZnVuY3Rpb24oIG5hbWUsIHZhbHVlICkge1xuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCB2YWx1ZSApIHtcblx0XHRcdHZhciBzdHlsZXMsIGxlbixcblx0XHRcdFx0bWFwID0ge30sXG5cdFx0XHRcdGkgPSAwO1xuXG5cdFx0XHRpZiAoIGpRdWVyeS5pc0FycmF5KCBuYW1lICkgKSB7XG5cdFx0XHRcdHN0eWxlcyA9IGdldFN0eWxlcyggZWxlbSApO1xuXHRcdFx0XHRsZW4gPSBuYW1lLmxlbmd0aDtcblxuXHRcdFx0XHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdFx0XHRtYXBbIG5hbWVbIGkgXSBdID0galF1ZXJ5LmNzcyggZWxlbSwgbmFtZVsgaSBdLCBmYWxzZSwgc3R5bGVzICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gbWFwO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gdmFsdWUgIT09IHVuZGVmaW5lZCA/XG5cdFx0XHRcdGpRdWVyeS5zdHlsZSggZWxlbSwgbmFtZSwgdmFsdWUgKSA6XG5cdFx0XHRcdGpRdWVyeS5jc3MoIGVsZW0sIG5hbWUgKTtcblx0XHR9LCBuYW1lLCB2YWx1ZSwgYXJndW1lbnRzLmxlbmd0aCA+IDEgKTtcblx0fSxcblx0c2hvdzogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHNob3dIaWRlKCB0aGlzLCB0cnVlICk7XG5cdH0sXG5cdGhpZGU6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBzaG93SGlkZSggdGhpcyApO1xuXHR9LFxuXHR0b2dnbGU6IGZ1bmN0aW9uKCBzdGF0ZSApIHtcblx0XHRpZiAoIHR5cGVvZiBzdGF0ZSA9PT0gXCJib29sZWFuXCIgKSB7XG5cdFx0XHRyZXR1cm4gc3RhdGUgPyB0aGlzLnNob3coKSA6IHRoaXMuaGlkZSgpO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoIGlzSGlkZGVuKCB0aGlzICkgKSB7XG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLnNob3coKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLmhpZGUoKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fVxufSk7XG5cblxuZnVuY3Rpb24gVHdlZW4oIGVsZW0sIG9wdGlvbnMsIHByb3AsIGVuZCwgZWFzaW5nICkge1xuXHRyZXR1cm4gbmV3IFR3ZWVuLnByb3RvdHlwZS5pbml0KCBlbGVtLCBvcHRpb25zLCBwcm9wLCBlbmQsIGVhc2luZyApO1xufVxualF1ZXJ5LlR3ZWVuID0gVHdlZW47XG5cblR3ZWVuLnByb3RvdHlwZSA9IHtcblx0Y29uc3RydWN0b3I6IFR3ZWVuLFxuXHRpbml0OiBmdW5jdGlvbiggZWxlbSwgb3B0aW9ucywgcHJvcCwgZW5kLCBlYXNpbmcsIHVuaXQgKSB7XG5cdFx0dGhpcy5lbGVtID0gZWxlbTtcblx0XHR0aGlzLnByb3AgPSBwcm9wO1xuXHRcdHRoaXMuZWFzaW5nID0gZWFzaW5nIHx8IFwic3dpbmdcIjtcblx0XHR0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuXHRcdHRoaXMuc3RhcnQgPSB0aGlzLm5vdyA9IHRoaXMuY3VyKCk7XG5cdFx0dGhpcy5lbmQgPSBlbmQ7XG5cdFx0dGhpcy51bml0ID0gdW5pdCB8fCAoIGpRdWVyeS5jc3NOdW1iZXJbIHByb3AgXSA/IFwiXCIgOiBcInB4XCIgKTtcblx0fSxcblx0Y3VyOiBmdW5jdGlvbigpIHtcblx0XHR2YXIgaG9va3MgPSBUd2Vlbi5wcm9wSG9va3NbIHRoaXMucHJvcCBdO1xuXG5cdFx0cmV0dXJuIGhvb2tzICYmIGhvb2tzLmdldCA/XG5cdFx0XHRob29rcy5nZXQoIHRoaXMgKSA6XG5cdFx0XHRUd2Vlbi5wcm9wSG9va3MuX2RlZmF1bHQuZ2V0KCB0aGlzICk7XG5cdH0sXG5cdHJ1bjogZnVuY3Rpb24oIHBlcmNlbnQgKSB7XG5cdFx0dmFyIGVhc2VkLFxuXHRcdFx0aG9va3MgPSBUd2Vlbi5wcm9wSG9va3NbIHRoaXMucHJvcCBdO1xuXG5cdFx0aWYgKCB0aGlzLm9wdGlvbnMuZHVyYXRpb24gKSB7XG5cdFx0XHR0aGlzLnBvcyA9IGVhc2VkID0galF1ZXJ5LmVhc2luZ1sgdGhpcy5lYXNpbmcgXShcblx0XHRcdFx0cGVyY2VudCwgdGhpcy5vcHRpb25zLmR1cmF0aW9uICogcGVyY2VudCwgMCwgMSwgdGhpcy5vcHRpb25zLmR1cmF0aW9uXG5cdFx0XHQpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLnBvcyA9IGVhc2VkID0gcGVyY2VudDtcblx0XHR9XG5cdFx0dGhpcy5ub3cgPSAoIHRoaXMuZW5kIC0gdGhpcy5zdGFydCApICogZWFzZWQgKyB0aGlzLnN0YXJ0O1xuXG5cdFx0aWYgKCB0aGlzLm9wdGlvbnMuc3RlcCApIHtcblx0XHRcdHRoaXMub3B0aW9ucy5zdGVwLmNhbGwoIHRoaXMuZWxlbSwgdGhpcy5ub3csIHRoaXMgKTtcblx0XHR9XG5cblx0XHRpZiAoIGhvb2tzICYmIGhvb2tzLnNldCApIHtcblx0XHRcdGhvb2tzLnNldCggdGhpcyApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRUd2Vlbi5wcm9wSG9va3MuX2RlZmF1bHQuc2V0KCB0aGlzICk7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzO1xuXHR9XG59O1xuXG5Ud2Vlbi5wcm90b3R5cGUuaW5pdC5wcm90b3R5cGUgPSBUd2Vlbi5wcm90b3R5cGU7XG5cblR3ZWVuLnByb3BIb29rcyA9IHtcblx0X2RlZmF1bHQ6IHtcblx0XHRnZXQ6IGZ1bmN0aW9uKCB0d2VlbiApIHtcblx0XHRcdHZhciByZXN1bHQ7XG5cblx0XHRcdGlmICggdHdlZW4uZWxlbVsgdHdlZW4ucHJvcCBdICE9IG51bGwgJiZcblx0XHRcdFx0KCF0d2Vlbi5lbGVtLnN0eWxlIHx8IHR3ZWVuLmVsZW0uc3R5bGVbIHR3ZWVuLnByb3AgXSA9PSBudWxsKSApIHtcblx0XHRcdFx0cmV0dXJuIHR3ZWVuLmVsZW1bIHR3ZWVuLnByb3AgXTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gUGFzc2luZyBhbiBlbXB0eSBzdHJpbmcgYXMgYSAzcmQgcGFyYW1ldGVyIHRvIC5jc3Mgd2lsbCBhdXRvbWF0aWNhbGx5XG5cdFx0XHQvLyBhdHRlbXB0IGEgcGFyc2VGbG9hdCBhbmQgZmFsbGJhY2sgdG8gYSBzdHJpbmcgaWYgdGhlIHBhcnNlIGZhaWxzLlxuXHRcdFx0Ly8gU2ltcGxlIHZhbHVlcyBzdWNoIGFzIFwiMTBweFwiIGFyZSBwYXJzZWQgdG8gRmxvYXQ7XG5cdFx0XHQvLyBjb21wbGV4IHZhbHVlcyBzdWNoIGFzIFwicm90YXRlKDFyYWQpXCIgYXJlIHJldHVybmVkIGFzLWlzLlxuXHRcdFx0cmVzdWx0ID0galF1ZXJ5LmNzcyggdHdlZW4uZWxlbSwgdHdlZW4ucHJvcCwgXCJcIiApO1xuXHRcdFx0Ly8gRW1wdHkgc3RyaW5ncywgbnVsbCwgdW5kZWZpbmVkIGFuZCBcImF1dG9cIiBhcmUgY29udmVydGVkIHRvIDAuXG5cdFx0XHRyZXR1cm4gIXJlc3VsdCB8fCByZXN1bHQgPT09IFwiYXV0b1wiID8gMCA6IHJlc3VsdDtcblx0XHR9LFxuXHRcdHNldDogZnVuY3Rpb24oIHR3ZWVuICkge1xuXHRcdFx0Ly8gVXNlIHN0ZXAgaG9vayBmb3IgYmFjayBjb21wYXQuXG5cdFx0XHQvLyBVc2UgY3NzSG9vayBpZiBpdHMgdGhlcmUuXG5cdFx0XHQvLyBVc2UgLnN0eWxlIGlmIGF2YWlsYWJsZSBhbmQgdXNlIHBsYWluIHByb3BlcnRpZXMgd2hlcmUgYXZhaWxhYmxlLlxuXHRcdFx0aWYgKCBqUXVlcnkuZnguc3RlcFsgdHdlZW4ucHJvcCBdICkge1xuXHRcdFx0XHRqUXVlcnkuZnguc3RlcFsgdHdlZW4ucHJvcCBdKCB0d2VlbiApO1xuXHRcdFx0fSBlbHNlIGlmICggdHdlZW4uZWxlbS5zdHlsZSAmJiAoIHR3ZWVuLmVsZW0uc3R5bGVbIGpRdWVyeS5jc3NQcm9wc1sgdHdlZW4ucHJvcCBdIF0gIT0gbnVsbCB8fCBqUXVlcnkuY3NzSG9va3NbIHR3ZWVuLnByb3AgXSApICkge1xuXHRcdFx0XHRqUXVlcnkuc3R5bGUoIHR3ZWVuLmVsZW0sIHR3ZWVuLnByb3AsIHR3ZWVuLm5vdyArIHR3ZWVuLnVuaXQgKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHR3ZWVuLmVsZW1bIHR3ZWVuLnByb3AgXSA9IHR3ZWVuLm5vdztcblx0XHRcdH1cblx0XHR9XG5cdH1cbn07XG5cbi8vIFN1cHBvcnQ6IElFOVxuLy8gUGFuaWMgYmFzZWQgYXBwcm9hY2ggdG8gc2V0dGluZyB0aGluZ3Mgb24gZGlzY29ubmVjdGVkIG5vZGVzXG5Ud2Vlbi5wcm9wSG9va3Muc2Nyb2xsVG9wID0gVHdlZW4ucHJvcEhvb2tzLnNjcm9sbExlZnQgPSB7XG5cdHNldDogZnVuY3Rpb24oIHR3ZWVuICkge1xuXHRcdGlmICggdHdlZW4uZWxlbS5ub2RlVHlwZSAmJiB0d2Vlbi5lbGVtLnBhcmVudE5vZGUgKSB7XG5cdFx0XHR0d2Vlbi5lbGVtWyB0d2Vlbi5wcm9wIF0gPSB0d2Vlbi5ub3c7XG5cdFx0fVxuXHR9XG59O1xuXG5qUXVlcnkuZWFzaW5nID0ge1xuXHRsaW5lYXI6IGZ1bmN0aW9uKCBwICkge1xuXHRcdHJldHVybiBwO1xuXHR9LFxuXHRzd2luZzogZnVuY3Rpb24oIHAgKSB7XG5cdFx0cmV0dXJuIDAuNSAtIE1hdGguY29zKCBwICogTWF0aC5QSSApIC8gMjtcblx0fVxufTtcblxualF1ZXJ5LmZ4ID0gVHdlZW4ucHJvdG90eXBlLmluaXQ7XG5cbi8vIEJhY2sgQ29tcGF0IDwxLjggZXh0ZW5zaW9uIHBvaW50XG5qUXVlcnkuZnguc3RlcCA9IHt9O1xuXG5cblxuXG52YXJcblx0ZnhOb3csIHRpbWVySWQsXG5cdHJmeHR5cGVzID0gL14oPzp0b2dnbGV8c2hvd3xoaWRlKSQvLFxuXHRyZnhudW0gPSBuZXcgUmVnRXhwKCBcIl4oPzooWystXSk9fCkoXCIgKyBwbnVtICsgXCIpKFthLXolXSopJFwiLCBcImlcIiApLFxuXHRycnVuID0gL3F1ZXVlSG9va3MkLyxcblx0YW5pbWF0aW9uUHJlZmlsdGVycyA9IFsgZGVmYXVsdFByZWZpbHRlciBdLFxuXHR0d2VlbmVycyA9IHtcblx0XHRcIipcIjogWyBmdW5jdGlvbiggcHJvcCwgdmFsdWUgKSB7XG5cdFx0XHR2YXIgdHdlZW4gPSB0aGlzLmNyZWF0ZVR3ZWVuKCBwcm9wLCB2YWx1ZSApLFxuXHRcdFx0XHR0YXJnZXQgPSB0d2Vlbi5jdXIoKSxcblx0XHRcdFx0cGFydHMgPSByZnhudW0uZXhlYyggdmFsdWUgKSxcblx0XHRcdFx0dW5pdCA9IHBhcnRzICYmIHBhcnRzWyAzIF0gfHwgKCBqUXVlcnkuY3NzTnVtYmVyWyBwcm9wIF0gPyBcIlwiIDogXCJweFwiICksXG5cblx0XHRcdFx0Ly8gU3RhcnRpbmcgdmFsdWUgY29tcHV0YXRpb24gaXMgcmVxdWlyZWQgZm9yIHBvdGVudGlhbCB1bml0IG1pc21hdGNoZXNcblx0XHRcdFx0c3RhcnQgPSAoIGpRdWVyeS5jc3NOdW1iZXJbIHByb3AgXSB8fCB1bml0ICE9PSBcInB4XCIgJiYgK3RhcmdldCApICYmXG5cdFx0XHRcdFx0cmZ4bnVtLmV4ZWMoIGpRdWVyeS5jc3MoIHR3ZWVuLmVsZW0sIHByb3AgKSApLFxuXHRcdFx0XHRzY2FsZSA9IDEsXG5cdFx0XHRcdG1heEl0ZXJhdGlvbnMgPSAyMDtcblxuXHRcdFx0aWYgKCBzdGFydCAmJiBzdGFydFsgMyBdICE9PSB1bml0ICkge1xuXHRcdFx0XHQvLyBUcnVzdCB1bml0cyByZXBvcnRlZCBieSBqUXVlcnkuY3NzXG5cdFx0XHRcdHVuaXQgPSB1bml0IHx8IHN0YXJ0WyAzIF07XG5cblx0XHRcdFx0Ly8gTWFrZSBzdXJlIHdlIHVwZGF0ZSB0aGUgdHdlZW4gcHJvcGVydGllcyBsYXRlciBvblxuXHRcdFx0XHRwYXJ0cyA9IHBhcnRzIHx8IFtdO1xuXG5cdFx0XHRcdC8vIEl0ZXJhdGl2ZWx5IGFwcHJveGltYXRlIGZyb20gYSBub256ZXJvIHN0YXJ0aW5nIHBvaW50XG5cdFx0XHRcdHN0YXJ0ID0gK3RhcmdldCB8fCAxO1xuXG5cdFx0XHRcdGRvIHtcblx0XHRcdFx0XHQvLyBJZiBwcmV2aW91cyBpdGVyYXRpb24gemVyb2VkIG91dCwgZG91YmxlIHVudGlsIHdlIGdldCAqc29tZXRoaW5nKi5cblx0XHRcdFx0XHQvLyBVc2Ugc3RyaW5nIGZvciBkb3VibGluZyBzbyB3ZSBkb24ndCBhY2NpZGVudGFsbHkgc2VlIHNjYWxlIGFzIHVuY2hhbmdlZCBiZWxvd1xuXHRcdFx0XHRcdHNjYWxlID0gc2NhbGUgfHwgXCIuNVwiO1xuXG5cdFx0XHRcdFx0Ly8gQWRqdXN0IGFuZCBhcHBseVxuXHRcdFx0XHRcdHN0YXJ0ID0gc3RhcnQgLyBzY2FsZTtcblx0XHRcdFx0XHRqUXVlcnkuc3R5bGUoIHR3ZWVuLmVsZW0sIHByb3AsIHN0YXJ0ICsgdW5pdCApO1xuXG5cdFx0XHRcdC8vIFVwZGF0ZSBzY2FsZSwgdG9sZXJhdGluZyB6ZXJvIG9yIE5hTiBmcm9tIHR3ZWVuLmN1cigpLFxuXHRcdFx0XHQvLyBicmVhayB0aGUgbG9vcCBpZiBzY2FsZSBpcyB1bmNoYW5nZWQgb3IgcGVyZmVjdCwgb3IgaWYgd2UndmUganVzdCBoYWQgZW5vdWdoXG5cdFx0XHRcdH0gd2hpbGUgKCBzY2FsZSAhPT0gKHNjYWxlID0gdHdlZW4uY3VyKCkgLyB0YXJnZXQpICYmIHNjYWxlICE9PSAxICYmIC0tbWF4SXRlcmF0aW9ucyApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBVcGRhdGUgdHdlZW4gcHJvcGVydGllc1xuXHRcdFx0aWYgKCBwYXJ0cyApIHtcblx0XHRcdFx0c3RhcnQgPSB0d2Vlbi5zdGFydCA9ICtzdGFydCB8fCArdGFyZ2V0IHx8IDA7XG5cdFx0XHRcdHR3ZWVuLnVuaXQgPSB1bml0O1xuXHRcdFx0XHQvLyBJZiBhICs9Ly09IHRva2VuIHdhcyBwcm92aWRlZCwgd2UncmUgZG9pbmcgYSByZWxhdGl2ZSBhbmltYXRpb25cblx0XHRcdFx0dHdlZW4uZW5kID0gcGFydHNbIDEgXSA/XG5cdFx0XHRcdFx0c3RhcnQgKyAoIHBhcnRzWyAxIF0gKyAxICkgKiBwYXJ0c1sgMiBdIDpcblx0XHRcdFx0XHQrcGFydHNbIDIgXTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHR3ZWVuO1xuXHRcdH0gXVxuXHR9O1xuXG4vLyBBbmltYXRpb25zIGNyZWF0ZWQgc3luY2hyb25vdXNseSB3aWxsIHJ1biBzeW5jaHJvbm91c2x5XG5mdW5jdGlvbiBjcmVhdGVGeE5vdygpIHtcblx0c2V0VGltZW91dChmdW5jdGlvbigpIHtcblx0XHRmeE5vdyA9IHVuZGVmaW5lZDtcblx0fSk7XG5cdHJldHVybiAoIGZ4Tm93ID0galF1ZXJ5Lm5vdygpICk7XG59XG5cbi8vIEdlbmVyYXRlIHBhcmFtZXRlcnMgdG8gY3JlYXRlIGEgc3RhbmRhcmQgYW5pbWF0aW9uXG5mdW5jdGlvbiBnZW5GeCggdHlwZSwgaW5jbHVkZVdpZHRoICkge1xuXHR2YXIgd2hpY2gsXG5cdFx0aSA9IDAsXG5cdFx0YXR0cnMgPSB7IGhlaWdodDogdHlwZSB9O1xuXG5cdC8vIElmIHdlIGluY2x1ZGUgd2lkdGgsIHN0ZXAgdmFsdWUgaXMgMSB0byBkbyBhbGwgY3NzRXhwYW5kIHZhbHVlcyxcblx0Ly8gb3RoZXJ3aXNlIHN0ZXAgdmFsdWUgaXMgMiB0byBza2lwIG92ZXIgTGVmdCBhbmQgUmlnaHRcblx0aW5jbHVkZVdpZHRoID0gaW5jbHVkZVdpZHRoID8gMSA6IDA7XG5cdGZvciAoIDsgaSA8IDQgOyBpICs9IDIgLSBpbmNsdWRlV2lkdGggKSB7XG5cdFx0d2hpY2ggPSBjc3NFeHBhbmRbIGkgXTtcblx0XHRhdHRyc1sgXCJtYXJnaW5cIiArIHdoaWNoIF0gPSBhdHRyc1sgXCJwYWRkaW5nXCIgKyB3aGljaCBdID0gdHlwZTtcblx0fVxuXG5cdGlmICggaW5jbHVkZVdpZHRoICkge1xuXHRcdGF0dHJzLm9wYWNpdHkgPSBhdHRycy53aWR0aCA9IHR5cGU7XG5cdH1cblxuXHRyZXR1cm4gYXR0cnM7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVR3ZWVuKCB2YWx1ZSwgcHJvcCwgYW5pbWF0aW9uICkge1xuXHR2YXIgdHdlZW4sXG5cdFx0Y29sbGVjdGlvbiA9ICggdHdlZW5lcnNbIHByb3AgXSB8fCBbXSApLmNvbmNhdCggdHdlZW5lcnNbIFwiKlwiIF0gKSxcblx0XHRpbmRleCA9IDAsXG5cdFx0bGVuZ3RoID0gY29sbGVjdGlvbi5sZW5ndGg7XG5cdGZvciAoIDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KysgKSB7XG5cdFx0aWYgKCAodHdlZW4gPSBjb2xsZWN0aW9uWyBpbmRleCBdLmNhbGwoIGFuaW1hdGlvbiwgcHJvcCwgdmFsdWUgKSkgKSB7XG5cblx0XHRcdC8vIFdlJ3JlIGRvbmUgd2l0aCB0aGlzIHByb3BlcnR5XG5cdFx0XHRyZXR1cm4gdHdlZW47XG5cdFx0fVxuXHR9XG59XG5cbmZ1bmN0aW9uIGRlZmF1bHRQcmVmaWx0ZXIoIGVsZW0sIHByb3BzLCBvcHRzICkge1xuXHQvKiBqc2hpbnQgdmFsaWR0aGlzOiB0cnVlICovXG5cdHZhciBwcm9wLCB2YWx1ZSwgdG9nZ2xlLCB0d2VlbiwgaG9va3MsIG9sZGZpcmUsIGRpc3BsYXksIGNoZWNrRGlzcGxheSxcblx0XHRhbmltID0gdGhpcyxcblx0XHRvcmlnID0ge30sXG5cdFx0c3R5bGUgPSBlbGVtLnN0eWxlLFxuXHRcdGhpZGRlbiA9IGVsZW0ubm9kZVR5cGUgJiYgaXNIaWRkZW4oIGVsZW0gKSxcblx0XHRkYXRhU2hvdyA9IGRhdGFfcHJpdi5nZXQoIGVsZW0sIFwiZnhzaG93XCIgKTtcblxuXHQvLyBIYW5kbGUgcXVldWU6IGZhbHNlIHByb21pc2VzXG5cdGlmICggIW9wdHMucXVldWUgKSB7XG5cdFx0aG9va3MgPSBqUXVlcnkuX3F1ZXVlSG9va3MoIGVsZW0sIFwiZnhcIiApO1xuXHRcdGlmICggaG9va3MudW5xdWV1ZWQgPT0gbnVsbCApIHtcblx0XHRcdGhvb2tzLnVucXVldWVkID0gMDtcblx0XHRcdG9sZGZpcmUgPSBob29rcy5lbXB0eS5maXJlO1xuXHRcdFx0aG9va3MuZW1wdHkuZmlyZSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoICFob29rcy51bnF1ZXVlZCApIHtcblx0XHRcdFx0XHRvbGRmaXJlKCk7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cdFx0fVxuXHRcdGhvb2tzLnVucXVldWVkKys7XG5cblx0XHRhbmltLmFsd2F5cyhmdW5jdGlvbigpIHtcblx0XHRcdC8vIEVuc3VyZSB0aGUgY29tcGxldGUgaGFuZGxlciBpcyBjYWxsZWQgYmVmb3JlIHRoaXMgY29tcGxldGVzXG5cdFx0XHRhbmltLmFsd2F5cyhmdW5jdGlvbigpIHtcblx0XHRcdFx0aG9va3MudW5xdWV1ZWQtLTtcblx0XHRcdFx0aWYgKCAhalF1ZXJ5LnF1ZXVlKCBlbGVtLCBcImZ4XCIgKS5sZW5ndGggKSB7XG5cdFx0XHRcdFx0aG9va3MuZW1wdHkuZmlyZSgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9KTtcblx0fVxuXG5cdC8vIEhlaWdodC93aWR0aCBvdmVyZmxvdyBwYXNzXG5cdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSAmJiAoIFwiaGVpZ2h0XCIgaW4gcHJvcHMgfHwgXCJ3aWR0aFwiIGluIHByb3BzICkgKSB7XG5cdFx0Ly8gTWFrZSBzdXJlIHRoYXQgbm90aGluZyBzbmVha3Mgb3V0XG5cdFx0Ly8gUmVjb3JkIGFsbCAzIG92ZXJmbG93IGF0dHJpYnV0ZXMgYmVjYXVzZSBJRTktMTAgZG8gbm90XG5cdFx0Ly8gY2hhbmdlIHRoZSBvdmVyZmxvdyBhdHRyaWJ1dGUgd2hlbiBvdmVyZmxvd1ggYW5kXG5cdFx0Ly8gb3ZlcmZsb3dZIGFyZSBzZXQgdG8gdGhlIHNhbWUgdmFsdWVcblx0XHRvcHRzLm92ZXJmbG93ID0gWyBzdHlsZS5vdmVyZmxvdywgc3R5bGUub3ZlcmZsb3dYLCBzdHlsZS5vdmVyZmxvd1kgXTtcblxuXHRcdC8vIFNldCBkaXNwbGF5IHByb3BlcnR5IHRvIGlubGluZS1ibG9jayBmb3IgaGVpZ2h0L3dpZHRoXG5cdFx0Ly8gYW5pbWF0aW9ucyBvbiBpbmxpbmUgZWxlbWVudHMgdGhhdCBhcmUgaGF2aW5nIHdpZHRoL2hlaWdodCBhbmltYXRlZFxuXHRcdGRpc3BsYXkgPSBqUXVlcnkuY3NzKCBlbGVtLCBcImRpc3BsYXlcIiApO1xuXG5cdFx0Ly8gVGVzdCBkZWZhdWx0IGRpc3BsYXkgaWYgZGlzcGxheSBpcyBjdXJyZW50bHkgXCJub25lXCJcblx0XHRjaGVja0Rpc3BsYXkgPSBkaXNwbGF5ID09PSBcIm5vbmVcIiA/XG5cdFx0XHRkYXRhX3ByaXYuZ2V0KCBlbGVtLCBcIm9sZGRpc3BsYXlcIiApIHx8IGRlZmF1bHREaXNwbGF5KCBlbGVtLm5vZGVOYW1lICkgOiBkaXNwbGF5O1xuXG5cdFx0aWYgKCBjaGVja0Rpc3BsYXkgPT09IFwiaW5saW5lXCIgJiYgalF1ZXJ5LmNzcyggZWxlbSwgXCJmbG9hdFwiICkgPT09IFwibm9uZVwiICkge1xuXHRcdFx0c3R5bGUuZGlzcGxheSA9IFwiaW5saW5lLWJsb2NrXCI7XG5cdFx0fVxuXHR9XG5cblx0aWYgKCBvcHRzLm92ZXJmbG93ICkge1xuXHRcdHN0eWxlLm92ZXJmbG93ID0gXCJoaWRkZW5cIjtcblx0XHRhbmltLmFsd2F5cyhmdW5jdGlvbigpIHtcblx0XHRcdHN0eWxlLm92ZXJmbG93ID0gb3B0cy5vdmVyZmxvd1sgMCBdO1xuXHRcdFx0c3R5bGUub3ZlcmZsb3dYID0gb3B0cy5vdmVyZmxvd1sgMSBdO1xuXHRcdFx0c3R5bGUub3ZlcmZsb3dZID0gb3B0cy5vdmVyZmxvd1sgMiBdO1xuXHRcdH0pO1xuXHR9XG5cblx0Ly8gc2hvdy9oaWRlIHBhc3Ncblx0Zm9yICggcHJvcCBpbiBwcm9wcyApIHtcblx0XHR2YWx1ZSA9IHByb3BzWyBwcm9wIF07XG5cdFx0aWYgKCByZnh0eXBlcy5leGVjKCB2YWx1ZSApICkge1xuXHRcdFx0ZGVsZXRlIHByb3BzWyBwcm9wIF07XG5cdFx0XHR0b2dnbGUgPSB0b2dnbGUgfHwgdmFsdWUgPT09IFwidG9nZ2xlXCI7XG5cdFx0XHRpZiAoIHZhbHVlID09PSAoIGhpZGRlbiA/IFwiaGlkZVwiIDogXCJzaG93XCIgKSApIHtcblxuXHRcdFx0XHQvLyBJZiB0aGVyZSBpcyBkYXRhU2hvdyBsZWZ0IG92ZXIgZnJvbSBhIHN0b3BwZWQgaGlkZSBvciBzaG93IGFuZCB3ZSBhcmUgZ29pbmcgdG8gcHJvY2VlZCB3aXRoIHNob3csIHdlIHNob3VsZCBwcmV0ZW5kIHRvIGJlIGhpZGRlblxuXHRcdFx0XHRpZiAoIHZhbHVlID09PSBcInNob3dcIiAmJiBkYXRhU2hvdyAmJiBkYXRhU2hvd1sgcHJvcCBdICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0aGlkZGVuID0gdHJ1ZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRjb250aW51ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0b3JpZ1sgcHJvcCBdID0gZGF0YVNob3cgJiYgZGF0YVNob3dbIHByb3AgXSB8fCBqUXVlcnkuc3R5bGUoIGVsZW0sIHByb3AgKTtcblxuXHRcdC8vIEFueSBub24tZnggdmFsdWUgc3RvcHMgdXMgZnJvbSByZXN0b3JpbmcgdGhlIG9yaWdpbmFsIGRpc3BsYXkgdmFsdWVcblx0XHR9IGVsc2Uge1xuXHRcdFx0ZGlzcGxheSA9IHVuZGVmaW5lZDtcblx0XHR9XG5cdH1cblxuXHRpZiAoICFqUXVlcnkuaXNFbXB0eU9iamVjdCggb3JpZyApICkge1xuXHRcdGlmICggZGF0YVNob3cgKSB7XG5cdFx0XHRpZiAoIFwiaGlkZGVuXCIgaW4gZGF0YVNob3cgKSB7XG5cdFx0XHRcdGhpZGRlbiA9IGRhdGFTaG93LmhpZGRlbjtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0ZGF0YVNob3cgPSBkYXRhX3ByaXYuYWNjZXNzKCBlbGVtLCBcImZ4c2hvd1wiLCB7fSApO1xuXHRcdH1cblxuXHRcdC8vIFN0b3JlIHN0YXRlIGlmIGl0cyB0b2dnbGUgLSBlbmFibGVzIC5zdG9wKCkudG9nZ2xlKCkgdG8gXCJyZXZlcnNlXCJcblx0XHRpZiAoIHRvZ2dsZSApIHtcblx0XHRcdGRhdGFTaG93LmhpZGRlbiA9ICFoaWRkZW47XG5cdFx0fVxuXHRcdGlmICggaGlkZGVuICkge1xuXHRcdFx0alF1ZXJ5KCBlbGVtICkuc2hvdygpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRhbmltLmRvbmUoZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGpRdWVyeSggZWxlbSApLmhpZGUoKTtcblx0XHRcdH0pO1xuXHRcdH1cblx0XHRhbmltLmRvbmUoZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgcHJvcDtcblxuXHRcdFx0ZGF0YV9wcml2LnJlbW92ZSggZWxlbSwgXCJmeHNob3dcIiApO1xuXHRcdFx0Zm9yICggcHJvcCBpbiBvcmlnICkge1xuXHRcdFx0XHRqUXVlcnkuc3R5bGUoIGVsZW0sIHByb3AsIG9yaWdbIHByb3AgXSApO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHRcdGZvciAoIHByb3AgaW4gb3JpZyApIHtcblx0XHRcdHR3ZWVuID0gY3JlYXRlVHdlZW4oIGhpZGRlbiA/IGRhdGFTaG93WyBwcm9wIF0gOiAwLCBwcm9wLCBhbmltICk7XG5cblx0XHRcdGlmICggISggcHJvcCBpbiBkYXRhU2hvdyApICkge1xuXHRcdFx0XHRkYXRhU2hvd1sgcHJvcCBdID0gdHdlZW4uc3RhcnQ7XG5cdFx0XHRcdGlmICggaGlkZGVuICkge1xuXHRcdFx0XHRcdHR3ZWVuLmVuZCA9IHR3ZWVuLnN0YXJ0O1xuXHRcdFx0XHRcdHR3ZWVuLnN0YXJ0ID0gcHJvcCA9PT0gXCJ3aWR0aFwiIHx8IHByb3AgPT09IFwiaGVpZ2h0XCIgPyAxIDogMDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHQvLyBJZiB0aGlzIGlzIGEgbm9vcCBsaWtlIC5oaWRlKCkuaGlkZSgpLCByZXN0b3JlIGFuIG92ZXJ3cml0dGVuIGRpc3BsYXkgdmFsdWVcblx0fSBlbHNlIGlmICggKGRpc3BsYXkgPT09IFwibm9uZVwiID8gZGVmYXVsdERpc3BsYXkoIGVsZW0ubm9kZU5hbWUgKSA6IGRpc3BsYXkpID09PSBcImlubGluZVwiICkge1xuXHRcdHN0eWxlLmRpc3BsYXkgPSBkaXNwbGF5O1xuXHR9XG59XG5cbmZ1bmN0aW9uIHByb3BGaWx0ZXIoIHByb3BzLCBzcGVjaWFsRWFzaW5nICkge1xuXHR2YXIgaW5kZXgsIG5hbWUsIGVhc2luZywgdmFsdWUsIGhvb2tzO1xuXG5cdC8vIGNhbWVsQ2FzZSwgc3BlY2lhbEVhc2luZyBhbmQgZXhwYW5kIGNzc0hvb2sgcGFzc1xuXHRmb3IgKCBpbmRleCBpbiBwcm9wcyApIHtcblx0XHRuYW1lID0galF1ZXJ5LmNhbWVsQ2FzZSggaW5kZXggKTtcblx0XHRlYXNpbmcgPSBzcGVjaWFsRWFzaW5nWyBuYW1lIF07XG5cdFx0dmFsdWUgPSBwcm9wc1sgaW5kZXggXTtcblx0XHRpZiAoIGpRdWVyeS5pc0FycmF5KCB2YWx1ZSApICkge1xuXHRcdFx0ZWFzaW5nID0gdmFsdWVbIDEgXTtcblx0XHRcdHZhbHVlID0gcHJvcHNbIGluZGV4IF0gPSB2YWx1ZVsgMCBdO1xuXHRcdH1cblxuXHRcdGlmICggaW5kZXggIT09IG5hbWUgKSB7XG5cdFx0XHRwcm9wc1sgbmFtZSBdID0gdmFsdWU7XG5cdFx0XHRkZWxldGUgcHJvcHNbIGluZGV4IF07XG5cdFx0fVxuXG5cdFx0aG9va3MgPSBqUXVlcnkuY3NzSG9va3NbIG5hbWUgXTtcblx0XHRpZiAoIGhvb2tzICYmIFwiZXhwYW5kXCIgaW4gaG9va3MgKSB7XG5cdFx0XHR2YWx1ZSA9IGhvb2tzLmV4cGFuZCggdmFsdWUgKTtcblx0XHRcdGRlbGV0ZSBwcm9wc1sgbmFtZSBdO1xuXG5cdFx0XHQvLyBOb3QgcXVpdGUgJC5leHRlbmQsIHRoaXMgd29uJ3Qgb3ZlcndyaXRlIGV4aXN0aW5nIGtleXMuXG5cdFx0XHQvLyBSZXVzaW5nICdpbmRleCcgYmVjYXVzZSB3ZSBoYXZlIHRoZSBjb3JyZWN0IFwibmFtZVwiXG5cdFx0XHRmb3IgKCBpbmRleCBpbiB2YWx1ZSApIHtcblx0XHRcdFx0aWYgKCAhKCBpbmRleCBpbiBwcm9wcyApICkge1xuXHRcdFx0XHRcdHByb3BzWyBpbmRleCBdID0gdmFsdWVbIGluZGV4IF07XG5cdFx0XHRcdFx0c3BlY2lhbEVhc2luZ1sgaW5kZXggXSA9IGVhc2luZztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRzcGVjaWFsRWFzaW5nWyBuYW1lIF0gPSBlYXNpbmc7XG5cdFx0fVxuXHR9XG59XG5cbmZ1bmN0aW9uIEFuaW1hdGlvbiggZWxlbSwgcHJvcGVydGllcywgb3B0aW9ucyApIHtcblx0dmFyIHJlc3VsdCxcblx0XHRzdG9wcGVkLFxuXHRcdGluZGV4ID0gMCxcblx0XHRsZW5ndGggPSBhbmltYXRpb25QcmVmaWx0ZXJzLmxlbmd0aCxcblx0XHRkZWZlcnJlZCA9IGpRdWVyeS5EZWZlcnJlZCgpLmFsd2F5cyggZnVuY3Rpb24oKSB7XG5cdFx0XHQvLyBEb24ndCBtYXRjaCBlbGVtIGluIHRoZSA6YW5pbWF0ZWQgc2VsZWN0b3Jcblx0XHRcdGRlbGV0ZSB0aWNrLmVsZW07XG5cdFx0fSksXG5cdFx0dGljayA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0aWYgKCBzdG9wcGVkICkge1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cdFx0XHR2YXIgY3VycmVudFRpbWUgPSBmeE5vdyB8fCBjcmVhdGVGeE5vdygpLFxuXHRcdFx0XHRyZW1haW5pbmcgPSBNYXRoLm1heCggMCwgYW5pbWF0aW9uLnN0YXJ0VGltZSArIGFuaW1hdGlvbi5kdXJhdGlvbiAtIGN1cnJlbnRUaW1lICksXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQgMi4zXG5cdFx0XHRcdC8vIEFyY2hhaWMgY3Jhc2ggYnVnIHdvbid0IGFsbG93IHVzIHRvIHVzZSBgMSAtICggMC41IHx8IDAgKWAgKCMxMjQ5Nylcblx0XHRcdFx0dGVtcCA9IHJlbWFpbmluZyAvIGFuaW1hdGlvbi5kdXJhdGlvbiB8fCAwLFxuXHRcdFx0XHRwZXJjZW50ID0gMSAtIHRlbXAsXG5cdFx0XHRcdGluZGV4ID0gMCxcblx0XHRcdFx0bGVuZ3RoID0gYW5pbWF0aW9uLnR3ZWVucy5sZW5ndGg7XG5cblx0XHRcdGZvciAoIDsgaW5kZXggPCBsZW5ndGggOyBpbmRleCsrICkge1xuXHRcdFx0XHRhbmltYXRpb24udHdlZW5zWyBpbmRleCBdLnJ1biggcGVyY2VudCApO1xuXHRcdFx0fVxuXG5cdFx0XHRkZWZlcnJlZC5ub3RpZnlXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiwgcGVyY2VudCwgcmVtYWluaW5nIF0pO1xuXG5cdFx0XHRpZiAoIHBlcmNlbnQgPCAxICYmIGxlbmd0aCApIHtcblx0XHRcdFx0cmV0dXJuIHJlbWFpbmluZztcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGRlZmVycmVkLnJlc29sdmVXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiBdICk7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHR9LFxuXHRcdGFuaW1hdGlvbiA9IGRlZmVycmVkLnByb21pc2Uoe1xuXHRcdFx0ZWxlbTogZWxlbSxcblx0XHRcdHByb3BzOiBqUXVlcnkuZXh0ZW5kKCB7fSwgcHJvcGVydGllcyApLFxuXHRcdFx0b3B0czogalF1ZXJ5LmV4dGVuZCggdHJ1ZSwgeyBzcGVjaWFsRWFzaW5nOiB7fSB9LCBvcHRpb25zICksXG5cdFx0XHRvcmlnaW5hbFByb3BlcnRpZXM6IHByb3BlcnRpZXMsXG5cdFx0XHRvcmlnaW5hbE9wdGlvbnM6IG9wdGlvbnMsXG5cdFx0XHRzdGFydFRpbWU6IGZ4Tm93IHx8IGNyZWF0ZUZ4Tm93KCksXG5cdFx0XHRkdXJhdGlvbjogb3B0aW9ucy5kdXJhdGlvbixcblx0XHRcdHR3ZWVuczogW10sXG5cdFx0XHRjcmVhdGVUd2VlbjogZnVuY3Rpb24oIHByb3AsIGVuZCApIHtcblx0XHRcdFx0dmFyIHR3ZWVuID0galF1ZXJ5LlR3ZWVuKCBlbGVtLCBhbmltYXRpb24ub3B0cywgcHJvcCwgZW5kLFxuXHRcdFx0XHRcdFx0YW5pbWF0aW9uLm9wdHMuc3BlY2lhbEVhc2luZ1sgcHJvcCBdIHx8IGFuaW1hdGlvbi5vcHRzLmVhc2luZyApO1xuXHRcdFx0XHRhbmltYXRpb24udHdlZW5zLnB1c2goIHR3ZWVuICk7XG5cdFx0XHRcdHJldHVybiB0d2Vlbjtcblx0XHRcdH0sXG5cdFx0XHRzdG9wOiBmdW5jdGlvbiggZ290b0VuZCApIHtcblx0XHRcdFx0dmFyIGluZGV4ID0gMCxcblx0XHRcdFx0XHQvLyBJZiB3ZSBhcmUgZ29pbmcgdG8gdGhlIGVuZCwgd2Ugd2FudCB0byBydW4gYWxsIHRoZSB0d2VlbnNcblx0XHRcdFx0XHQvLyBvdGhlcndpc2Ugd2Ugc2tpcCB0aGlzIHBhcnRcblx0XHRcdFx0XHRsZW5ndGggPSBnb3RvRW5kID8gYW5pbWF0aW9uLnR3ZWVucy5sZW5ndGggOiAwO1xuXHRcdFx0XHRpZiAoIHN0b3BwZWQgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH1cblx0XHRcdFx0c3RvcHBlZCA9IHRydWU7XG5cdFx0XHRcdGZvciAoIDsgaW5kZXggPCBsZW5ndGggOyBpbmRleCsrICkge1xuXHRcdFx0XHRcdGFuaW1hdGlvbi50d2VlbnNbIGluZGV4IF0ucnVuKCAxICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBSZXNvbHZlIHdoZW4gd2UgcGxheWVkIHRoZSBsYXN0IGZyYW1lOyBvdGhlcndpc2UsIHJlamVjdFxuXHRcdFx0XHRpZiAoIGdvdG9FbmQgKSB7XG5cdFx0XHRcdFx0ZGVmZXJyZWQucmVzb2x2ZVdpdGgoIGVsZW0sIFsgYW5pbWF0aW9uLCBnb3RvRW5kIF0gKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRkZWZlcnJlZC5yZWplY3RXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiwgZ290b0VuZCBdICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9XG5cdFx0fSksXG5cdFx0cHJvcHMgPSBhbmltYXRpb24ucHJvcHM7XG5cblx0cHJvcEZpbHRlciggcHJvcHMsIGFuaW1hdGlvbi5vcHRzLnNwZWNpYWxFYXNpbmcgKTtcblxuXHRmb3IgKCA7IGluZGV4IDwgbGVuZ3RoIDsgaW5kZXgrKyApIHtcblx0XHRyZXN1bHQgPSBhbmltYXRpb25QcmVmaWx0ZXJzWyBpbmRleCBdLmNhbGwoIGFuaW1hdGlvbiwgZWxlbSwgcHJvcHMsIGFuaW1hdGlvbi5vcHRzICk7XG5cdFx0aWYgKCByZXN1bHQgKSB7XG5cdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdH1cblx0fVxuXG5cdGpRdWVyeS5tYXAoIHByb3BzLCBjcmVhdGVUd2VlbiwgYW5pbWF0aW9uICk7XG5cblx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggYW5pbWF0aW9uLm9wdHMuc3RhcnQgKSApIHtcblx0XHRhbmltYXRpb24ub3B0cy5zdGFydC5jYWxsKCBlbGVtLCBhbmltYXRpb24gKTtcblx0fVxuXG5cdGpRdWVyeS5meC50aW1lcihcblx0XHRqUXVlcnkuZXh0ZW5kKCB0aWNrLCB7XG5cdFx0XHRlbGVtOiBlbGVtLFxuXHRcdFx0YW5pbTogYW5pbWF0aW9uLFxuXHRcdFx0cXVldWU6IGFuaW1hdGlvbi5vcHRzLnF1ZXVlXG5cdFx0fSlcblx0KTtcblxuXHQvLyBhdHRhY2ggY2FsbGJhY2tzIGZyb20gb3B0aW9uc1xuXHRyZXR1cm4gYW5pbWF0aW9uLnByb2dyZXNzKCBhbmltYXRpb24ub3B0cy5wcm9ncmVzcyApXG5cdFx0LmRvbmUoIGFuaW1hdGlvbi5vcHRzLmRvbmUsIGFuaW1hdGlvbi5vcHRzLmNvbXBsZXRlIClcblx0XHQuZmFpbCggYW5pbWF0aW9uLm9wdHMuZmFpbCApXG5cdFx0LmFsd2F5cyggYW5pbWF0aW9uLm9wdHMuYWx3YXlzICk7XG59XG5cbmpRdWVyeS5BbmltYXRpb24gPSBqUXVlcnkuZXh0ZW5kKCBBbmltYXRpb24sIHtcblxuXHR0d2VlbmVyOiBmdW5jdGlvbiggcHJvcHMsIGNhbGxiYWNrICkge1xuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHByb3BzICkgKSB7XG5cdFx0XHRjYWxsYmFjayA9IHByb3BzO1xuXHRcdFx0cHJvcHMgPSBbIFwiKlwiIF07XG5cdFx0fSBlbHNlIHtcblx0XHRcdHByb3BzID0gcHJvcHMuc3BsaXQoXCIgXCIpO1xuXHRcdH1cblxuXHRcdHZhciBwcm9wLFxuXHRcdFx0aW5kZXggPSAwLFxuXHRcdFx0bGVuZ3RoID0gcHJvcHMubGVuZ3RoO1xuXG5cdFx0Zm9yICggOyBpbmRleCA8IGxlbmd0aCA7IGluZGV4KysgKSB7XG5cdFx0XHRwcm9wID0gcHJvcHNbIGluZGV4IF07XG5cdFx0XHR0d2VlbmVyc1sgcHJvcCBdID0gdHdlZW5lcnNbIHByb3AgXSB8fCBbXTtcblx0XHRcdHR3ZWVuZXJzWyBwcm9wIF0udW5zaGlmdCggY2FsbGJhY2sgKTtcblx0XHR9XG5cdH0sXG5cblx0cHJlZmlsdGVyOiBmdW5jdGlvbiggY2FsbGJhY2ssIHByZXBlbmQgKSB7XG5cdFx0aWYgKCBwcmVwZW5kICkge1xuXHRcdFx0YW5pbWF0aW9uUHJlZmlsdGVycy51bnNoaWZ0KCBjYWxsYmFjayApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRhbmltYXRpb25QcmVmaWx0ZXJzLnB1c2goIGNhbGxiYWNrICk7XG5cdFx0fVxuXHR9XG59KTtcblxualF1ZXJ5LnNwZWVkID0gZnVuY3Rpb24oIHNwZWVkLCBlYXNpbmcsIGZuICkge1xuXHR2YXIgb3B0ID0gc3BlZWQgJiYgdHlwZW9mIHNwZWVkID09PSBcIm9iamVjdFwiID8galF1ZXJ5LmV4dGVuZCgge30sIHNwZWVkICkgOiB7XG5cdFx0Y29tcGxldGU6IGZuIHx8ICFmbiAmJiBlYXNpbmcgfHxcblx0XHRcdGpRdWVyeS5pc0Z1bmN0aW9uKCBzcGVlZCApICYmIHNwZWVkLFxuXHRcdGR1cmF0aW9uOiBzcGVlZCxcblx0XHRlYXNpbmc6IGZuICYmIGVhc2luZyB8fCBlYXNpbmcgJiYgIWpRdWVyeS5pc0Z1bmN0aW9uKCBlYXNpbmcgKSAmJiBlYXNpbmdcblx0fTtcblxuXHRvcHQuZHVyYXRpb24gPSBqUXVlcnkuZngub2ZmID8gMCA6IHR5cGVvZiBvcHQuZHVyYXRpb24gPT09IFwibnVtYmVyXCIgPyBvcHQuZHVyYXRpb24gOlxuXHRcdG9wdC5kdXJhdGlvbiBpbiBqUXVlcnkuZnguc3BlZWRzID8galF1ZXJ5LmZ4LnNwZWVkc1sgb3B0LmR1cmF0aW9uIF0gOiBqUXVlcnkuZnguc3BlZWRzLl9kZWZhdWx0O1xuXG5cdC8vIE5vcm1hbGl6ZSBvcHQucXVldWUgLSB0cnVlL3VuZGVmaW5lZC9udWxsIC0+IFwiZnhcIlxuXHRpZiAoIG9wdC5xdWV1ZSA9PSBudWxsIHx8IG9wdC5xdWV1ZSA9PT0gdHJ1ZSApIHtcblx0XHRvcHQucXVldWUgPSBcImZ4XCI7XG5cdH1cblxuXHQvLyBRdWV1ZWluZ1xuXHRvcHQub2xkID0gb3B0LmNvbXBsZXRlO1xuXG5cdG9wdC5jb21wbGV0ZSA9IGZ1bmN0aW9uKCkge1xuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIG9wdC5vbGQgKSApIHtcblx0XHRcdG9wdC5vbGQuY2FsbCggdGhpcyApO1xuXHRcdH1cblxuXHRcdGlmICggb3B0LnF1ZXVlICkge1xuXHRcdFx0alF1ZXJ5LmRlcXVldWUoIHRoaXMsIG9wdC5xdWV1ZSApO1xuXHRcdH1cblx0fTtcblxuXHRyZXR1cm4gb3B0O1xufTtcblxualF1ZXJ5LmZuLmV4dGVuZCh7XG5cdGZhZGVUbzogZnVuY3Rpb24oIHNwZWVkLCB0bywgZWFzaW5nLCBjYWxsYmFjayApIHtcblxuXHRcdC8vIFNob3cgYW55IGhpZGRlbiBlbGVtZW50cyBhZnRlciBzZXR0aW5nIG9wYWNpdHkgdG8gMFxuXHRcdHJldHVybiB0aGlzLmZpbHRlciggaXNIaWRkZW4gKS5jc3MoIFwib3BhY2l0eVwiLCAwICkuc2hvdygpXG5cblx0XHRcdC8vIEFuaW1hdGUgdG8gdGhlIHZhbHVlIHNwZWNpZmllZFxuXHRcdFx0LmVuZCgpLmFuaW1hdGUoeyBvcGFjaXR5OiB0byB9LCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApO1xuXHR9LFxuXHRhbmltYXRlOiBmdW5jdGlvbiggcHJvcCwgc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKSB7XG5cdFx0dmFyIGVtcHR5ID0galF1ZXJ5LmlzRW1wdHlPYmplY3QoIHByb3AgKSxcblx0XHRcdG9wdGFsbCA9IGpRdWVyeS5zcGVlZCggc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKSxcblx0XHRcdGRvQW5pbWF0aW9uID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdC8vIE9wZXJhdGUgb24gYSBjb3B5IG9mIHByb3Agc28gcGVyLXByb3BlcnR5IGVhc2luZyB3b24ndCBiZSBsb3N0XG5cdFx0XHRcdHZhciBhbmltID0gQW5pbWF0aW9uKCB0aGlzLCBqUXVlcnkuZXh0ZW5kKCB7fSwgcHJvcCApLCBvcHRhbGwgKTtcblxuXHRcdFx0XHQvLyBFbXB0eSBhbmltYXRpb25zLCBvciBmaW5pc2hpbmcgcmVzb2x2ZXMgaW1tZWRpYXRlbHlcblx0XHRcdFx0aWYgKCBlbXB0eSB8fCBkYXRhX3ByaXYuZ2V0KCB0aGlzLCBcImZpbmlzaFwiICkgKSB7XG5cdFx0XHRcdFx0YW5pbS5zdG9wKCB0cnVlICk7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cdFx0XHRkb0FuaW1hdGlvbi5maW5pc2ggPSBkb0FuaW1hdGlvbjtcblxuXHRcdHJldHVybiBlbXB0eSB8fCBvcHRhbGwucXVldWUgPT09IGZhbHNlID9cblx0XHRcdHRoaXMuZWFjaCggZG9BbmltYXRpb24gKSA6XG5cdFx0XHR0aGlzLnF1ZXVlKCBvcHRhbGwucXVldWUsIGRvQW5pbWF0aW9uICk7XG5cdH0sXG5cdHN0b3A6IGZ1bmN0aW9uKCB0eXBlLCBjbGVhclF1ZXVlLCBnb3RvRW5kICkge1xuXHRcdHZhciBzdG9wUXVldWUgPSBmdW5jdGlvbiggaG9va3MgKSB7XG5cdFx0XHR2YXIgc3RvcCA9IGhvb2tzLnN0b3A7XG5cdFx0XHRkZWxldGUgaG9va3Muc3RvcDtcblx0XHRcdHN0b3AoIGdvdG9FbmQgKTtcblx0XHR9O1xuXG5cdFx0aWYgKCB0eXBlb2YgdHlwZSAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdGdvdG9FbmQgPSBjbGVhclF1ZXVlO1xuXHRcdFx0Y2xlYXJRdWV1ZSA9IHR5cGU7XG5cdFx0XHR0eXBlID0gdW5kZWZpbmVkO1xuXHRcdH1cblx0XHRpZiAoIGNsZWFyUXVldWUgJiYgdHlwZSAhPT0gZmFsc2UgKSB7XG5cdFx0XHR0aGlzLnF1ZXVlKCB0eXBlIHx8IFwiZnhcIiwgW10gKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIGRlcXVldWUgPSB0cnVlLFxuXHRcdFx0XHRpbmRleCA9IHR5cGUgIT0gbnVsbCAmJiB0eXBlICsgXCJxdWV1ZUhvb2tzXCIsXG5cdFx0XHRcdHRpbWVycyA9IGpRdWVyeS50aW1lcnMsXG5cdFx0XHRcdGRhdGEgPSBkYXRhX3ByaXYuZ2V0KCB0aGlzICk7XG5cblx0XHRcdGlmICggaW5kZXggKSB7XG5cdFx0XHRcdGlmICggZGF0YVsgaW5kZXggXSAmJiBkYXRhWyBpbmRleCBdLnN0b3AgKSB7XG5cdFx0XHRcdFx0c3RvcFF1ZXVlKCBkYXRhWyBpbmRleCBdICk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGZvciAoIGluZGV4IGluIGRhdGEgKSB7XG5cdFx0XHRcdFx0aWYgKCBkYXRhWyBpbmRleCBdICYmIGRhdGFbIGluZGV4IF0uc3RvcCAmJiBycnVuLnRlc3QoIGluZGV4ICkgKSB7XG5cdFx0XHRcdFx0XHRzdG9wUXVldWUoIGRhdGFbIGluZGV4IF0gKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Zm9yICggaW5kZXggPSB0aW1lcnMubGVuZ3RoOyBpbmRleC0tOyApIHtcblx0XHRcdFx0aWYgKCB0aW1lcnNbIGluZGV4IF0uZWxlbSA9PT0gdGhpcyAmJiAodHlwZSA9PSBudWxsIHx8IHRpbWVyc1sgaW5kZXggXS5xdWV1ZSA9PT0gdHlwZSkgKSB7XG5cdFx0XHRcdFx0dGltZXJzWyBpbmRleCBdLmFuaW0uc3RvcCggZ290b0VuZCApO1xuXHRcdFx0XHRcdGRlcXVldWUgPSBmYWxzZTtcblx0XHRcdFx0XHR0aW1lcnMuc3BsaWNlKCBpbmRleCwgMSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIFN0YXJ0IHRoZSBuZXh0IGluIHRoZSBxdWV1ZSBpZiB0aGUgbGFzdCBzdGVwIHdhc24ndCBmb3JjZWQuXG5cdFx0XHQvLyBUaW1lcnMgY3VycmVudGx5IHdpbGwgY2FsbCB0aGVpciBjb21wbGV0ZSBjYWxsYmFja3MsIHdoaWNoXG5cdFx0XHQvLyB3aWxsIGRlcXVldWUgYnV0IG9ubHkgaWYgdGhleSB3ZXJlIGdvdG9FbmQuXG5cdFx0XHRpZiAoIGRlcXVldWUgfHwgIWdvdG9FbmQgKSB7XG5cdFx0XHRcdGpRdWVyeS5kZXF1ZXVlKCB0aGlzLCB0eXBlICk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0sXG5cdGZpbmlzaDogZnVuY3Rpb24oIHR5cGUgKSB7XG5cdFx0aWYgKCB0eXBlICE9PSBmYWxzZSApIHtcblx0XHRcdHR5cGUgPSB0eXBlIHx8IFwiZnhcIjtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdHZhciBpbmRleCxcblx0XHRcdFx0ZGF0YSA9IGRhdGFfcHJpdi5nZXQoIHRoaXMgKSxcblx0XHRcdFx0cXVldWUgPSBkYXRhWyB0eXBlICsgXCJxdWV1ZVwiIF0sXG5cdFx0XHRcdGhvb2tzID0gZGF0YVsgdHlwZSArIFwicXVldWVIb29rc1wiIF0sXG5cdFx0XHRcdHRpbWVycyA9IGpRdWVyeS50aW1lcnMsXG5cdFx0XHRcdGxlbmd0aCA9IHF1ZXVlID8gcXVldWUubGVuZ3RoIDogMDtcblxuXHRcdFx0Ly8gRW5hYmxlIGZpbmlzaGluZyBmbGFnIG9uIHByaXZhdGUgZGF0YVxuXHRcdFx0ZGF0YS5maW5pc2ggPSB0cnVlO1xuXG5cdFx0XHQvLyBFbXB0eSB0aGUgcXVldWUgZmlyc3Rcblx0XHRcdGpRdWVyeS5xdWV1ZSggdGhpcywgdHlwZSwgW10gKTtcblxuXHRcdFx0aWYgKCBob29rcyAmJiBob29rcy5zdG9wICkge1xuXHRcdFx0XHRob29rcy5zdG9wLmNhbGwoIHRoaXMsIHRydWUgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gTG9vayBmb3IgYW55IGFjdGl2ZSBhbmltYXRpb25zLCBhbmQgZmluaXNoIHRoZW1cblx0XHRcdGZvciAoIGluZGV4ID0gdGltZXJzLmxlbmd0aDsgaW5kZXgtLTsgKSB7XG5cdFx0XHRcdGlmICggdGltZXJzWyBpbmRleCBdLmVsZW0gPT09IHRoaXMgJiYgdGltZXJzWyBpbmRleCBdLnF1ZXVlID09PSB0eXBlICkge1xuXHRcdFx0XHRcdHRpbWVyc1sgaW5kZXggXS5hbmltLnN0b3AoIHRydWUgKTtcblx0XHRcdFx0XHR0aW1lcnMuc3BsaWNlKCBpbmRleCwgMSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIExvb2sgZm9yIGFueSBhbmltYXRpb25zIGluIHRoZSBvbGQgcXVldWUgYW5kIGZpbmlzaCB0aGVtXG5cdFx0XHRmb3IgKCBpbmRleCA9IDA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrICkge1xuXHRcdFx0XHRpZiAoIHF1ZXVlWyBpbmRleCBdICYmIHF1ZXVlWyBpbmRleCBdLmZpbmlzaCApIHtcblx0XHRcdFx0XHRxdWV1ZVsgaW5kZXggXS5maW5pc2guY2FsbCggdGhpcyApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIFR1cm4gb2ZmIGZpbmlzaGluZyBmbGFnXG5cdFx0XHRkZWxldGUgZGF0YS5maW5pc2g7XG5cdFx0fSk7XG5cdH1cbn0pO1xuXG5qUXVlcnkuZWFjaChbIFwidG9nZ2xlXCIsIFwic2hvd1wiLCBcImhpZGVcIiBdLCBmdW5jdGlvbiggaSwgbmFtZSApIHtcblx0dmFyIGNzc0ZuID0galF1ZXJ5LmZuWyBuYW1lIF07XG5cdGpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICkge1xuXHRcdHJldHVybiBzcGVlZCA9PSBudWxsIHx8IHR5cGVvZiBzcGVlZCA9PT0gXCJib29sZWFuXCIgP1xuXHRcdFx0Y3NzRm4uYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApIDpcblx0XHRcdHRoaXMuYW5pbWF0ZSggZ2VuRngoIG5hbWUsIHRydWUgKSwgc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKTtcblx0fTtcbn0pO1xuXG4vLyBHZW5lcmF0ZSBzaG9ydGN1dHMgZm9yIGN1c3RvbSBhbmltYXRpb25zXG5qUXVlcnkuZWFjaCh7XG5cdHNsaWRlRG93bjogZ2VuRngoXCJzaG93XCIpLFxuXHRzbGlkZVVwOiBnZW5GeChcImhpZGVcIiksXG5cdHNsaWRlVG9nZ2xlOiBnZW5GeChcInRvZ2dsZVwiKSxcblx0ZmFkZUluOiB7IG9wYWNpdHk6IFwic2hvd1wiIH0sXG5cdGZhZGVPdXQ6IHsgb3BhY2l0eTogXCJoaWRlXCIgfSxcblx0ZmFkZVRvZ2dsZTogeyBvcGFjaXR5OiBcInRvZ2dsZVwiIH1cbn0sIGZ1bmN0aW9uKCBuYW1lLCBwcm9wcyApIHtcblx0alF1ZXJ5LmZuWyBuYW1lIF0gPSBmdW5jdGlvbiggc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKSB7XG5cdFx0cmV0dXJuIHRoaXMuYW5pbWF0ZSggcHJvcHMsIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICk7XG5cdH07XG59KTtcblxualF1ZXJ5LnRpbWVycyA9IFtdO1xualF1ZXJ5LmZ4LnRpY2sgPSBmdW5jdGlvbigpIHtcblx0dmFyIHRpbWVyLFxuXHRcdGkgPSAwLFxuXHRcdHRpbWVycyA9IGpRdWVyeS50aW1lcnM7XG5cblx0ZnhOb3cgPSBqUXVlcnkubm93KCk7XG5cblx0Zm9yICggOyBpIDwgdGltZXJzLmxlbmd0aDsgaSsrICkge1xuXHRcdHRpbWVyID0gdGltZXJzWyBpIF07XG5cdFx0Ly8gQ2hlY2tzIHRoZSB0aW1lciBoYXMgbm90IGFscmVhZHkgYmVlbiByZW1vdmVkXG5cdFx0aWYgKCAhdGltZXIoKSAmJiB0aW1lcnNbIGkgXSA9PT0gdGltZXIgKSB7XG5cdFx0XHR0aW1lcnMuc3BsaWNlKCBpLS0sIDEgKTtcblx0XHR9XG5cdH1cblxuXHRpZiAoICF0aW1lcnMubGVuZ3RoICkge1xuXHRcdGpRdWVyeS5meC5zdG9wKCk7XG5cdH1cblx0ZnhOb3cgPSB1bmRlZmluZWQ7XG59O1xuXG5qUXVlcnkuZngudGltZXIgPSBmdW5jdGlvbiggdGltZXIgKSB7XG5cdGpRdWVyeS50aW1lcnMucHVzaCggdGltZXIgKTtcblx0aWYgKCB0aW1lcigpICkge1xuXHRcdGpRdWVyeS5meC5zdGFydCgpO1xuXHR9IGVsc2Uge1xuXHRcdGpRdWVyeS50aW1lcnMucG9wKCk7XG5cdH1cbn07XG5cbmpRdWVyeS5meC5pbnRlcnZhbCA9IDEzO1xuXG5qUXVlcnkuZnguc3RhcnQgPSBmdW5jdGlvbigpIHtcblx0aWYgKCAhdGltZXJJZCApIHtcblx0XHR0aW1lcklkID0gc2V0SW50ZXJ2YWwoIGpRdWVyeS5meC50aWNrLCBqUXVlcnkuZnguaW50ZXJ2YWwgKTtcblx0fVxufTtcblxualF1ZXJ5LmZ4LnN0b3AgPSBmdW5jdGlvbigpIHtcblx0Y2xlYXJJbnRlcnZhbCggdGltZXJJZCApO1xuXHR0aW1lcklkID0gbnVsbDtcbn07XG5cbmpRdWVyeS5meC5zcGVlZHMgPSB7XG5cdHNsb3c6IDYwMCxcblx0ZmFzdDogMjAwLFxuXHQvLyBEZWZhdWx0IHNwZWVkXG5cdF9kZWZhdWx0OiA0MDBcbn07XG5cblxuLy8gQmFzZWQgb2ZmIG9mIHRoZSBwbHVnaW4gYnkgQ2xpbnQgSGVsZmVycywgd2l0aCBwZXJtaXNzaW9uLlxuLy8gaHR0cDovL2JsaW5kc2lnbmFscy5jb20vaW5kZXgucGhwLzIwMDkvMDcvanF1ZXJ5LWRlbGF5L1xualF1ZXJ5LmZuLmRlbGF5ID0gZnVuY3Rpb24oIHRpbWUsIHR5cGUgKSB7XG5cdHRpbWUgPSBqUXVlcnkuZnggPyBqUXVlcnkuZnguc3BlZWRzWyB0aW1lIF0gfHwgdGltZSA6IHRpbWU7XG5cdHR5cGUgPSB0eXBlIHx8IFwiZnhcIjtcblxuXHRyZXR1cm4gdGhpcy5xdWV1ZSggdHlwZSwgZnVuY3Rpb24oIG5leHQsIGhvb2tzICkge1xuXHRcdHZhciB0aW1lb3V0ID0gc2V0VGltZW91dCggbmV4dCwgdGltZSApO1xuXHRcdGhvb2tzLnN0b3AgPSBmdW5jdGlvbigpIHtcblx0XHRcdGNsZWFyVGltZW91dCggdGltZW91dCApO1xuXHRcdH07XG5cdH0pO1xufTtcblxuXG4oZnVuY3Rpb24oKSB7XG5cdHZhciBpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiaW5wdXRcIiApLFxuXHRcdHNlbGVjdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwic2VsZWN0XCIgKSxcblx0XHRvcHQgPSBzZWxlY3QuYXBwZW5kQ2hpbGQoIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwib3B0aW9uXCIgKSApO1xuXG5cdGlucHV0LnR5cGUgPSBcImNoZWNrYm94XCI7XG5cblx0Ly8gU3VwcG9ydDogaU9TPD01LjEsIEFuZHJvaWQ8PTQuMitcblx0Ly8gRGVmYXVsdCB2YWx1ZSBmb3IgYSBjaGVja2JveCBzaG91bGQgYmUgXCJvblwiXG5cdHN1cHBvcnQuY2hlY2tPbiA9IGlucHV0LnZhbHVlICE9PSBcIlwiO1xuXG5cdC8vIFN1cHBvcnQ6IElFPD0xMStcblx0Ly8gTXVzdCBhY2Nlc3Mgc2VsZWN0ZWRJbmRleCB0byBtYWtlIGRlZmF1bHQgb3B0aW9ucyBzZWxlY3Rcblx0c3VwcG9ydC5vcHRTZWxlY3RlZCA9IG9wdC5zZWxlY3RlZDtcblxuXHQvLyBTdXBwb3J0OiBBbmRyb2lkPD0yLjNcblx0Ly8gT3B0aW9ucyBpbnNpZGUgZGlzYWJsZWQgc2VsZWN0cyBhcmUgaW5jb3JyZWN0bHkgbWFya2VkIGFzIGRpc2FibGVkXG5cdHNlbGVjdC5kaXNhYmxlZCA9IHRydWU7XG5cdHN1cHBvcnQub3B0RGlzYWJsZWQgPSAhb3B0LmRpc2FibGVkO1xuXG5cdC8vIFN1cHBvcnQ6IElFPD0xMStcblx0Ly8gQW4gaW5wdXQgbG9zZXMgaXRzIHZhbHVlIGFmdGVyIGJlY29taW5nIGEgcmFkaW9cblx0aW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImlucHV0XCIgKTtcblx0aW5wdXQudmFsdWUgPSBcInRcIjtcblx0aW5wdXQudHlwZSA9IFwicmFkaW9cIjtcblx0c3VwcG9ydC5yYWRpb1ZhbHVlID0gaW5wdXQudmFsdWUgPT09IFwidFwiO1xufSkoKTtcblxuXG52YXIgbm9kZUhvb2ssIGJvb2xIb29rLFxuXHRhdHRySGFuZGxlID0galF1ZXJ5LmV4cHIuYXR0ckhhbmRsZTtcblxualF1ZXJ5LmZuLmV4dGVuZCh7XG5cdGF0dHI6IGZ1bmN0aW9uKCBuYW1lLCB2YWx1ZSApIHtcblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBqUXVlcnkuYXR0ciwgbmFtZSwgdmFsdWUsIGFyZ3VtZW50cy5sZW5ndGggPiAxICk7XG5cdH0sXG5cblx0cmVtb3ZlQXR0cjogZnVuY3Rpb24oIG5hbWUgKSB7XG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdGpRdWVyeS5yZW1vdmVBdHRyKCB0aGlzLCBuYW1lICk7XG5cdFx0fSk7XG5cdH1cbn0pO1xuXG5qUXVlcnkuZXh0ZW5kKHtcblx0YXR0cjogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIHZhbHVlICkge1xuXHRcdHZhciBob29rcywgcmV0LFxuXHRcdFx0blR5cGUgPSBlbGVtLm5vZGVUeXBlO1xuXG5cdFx0Ly8gZG9uJ3QgZ2V0L3NldCBhdHRyaWJ1dGVzIG9uIHRleHQsIGNvbW1lbnQgYW5kIGF0dHJpYnV0ZSBub2Rlc1xuXHRcdGlmICggIWVsZW0gfHwgblR5cGUgPT09IDMgfHwgblR5cGUgPT09IDggfHwgblR5cGUgPT09IDIgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gRmFsbGJhY2sgdG8gcHJvcCB3aGVuIGF0dHJpYnV0ZXMgYXJlIG5vdCBzdXBwb3J0ZWRcblx0XHRpZiAoIHR5cGVvZiBlbGVtLmdldEF0dHJpYnV0ZSA9PT0gc3RydW5kZWZpbmVkICkge1xuXHRcdFx0cmV0dXJuIGpRdWVyeS5wcm9wKCBlbGVtLCBuYW1lLCB2YWx1ZSApO1xuXHRcdH1cblxuXHRcdC8vIEFsbCBhdHRyaWJ1dGVzIGFyZSBsb3dlcmNhc2Vcblx0XHQvLyBHcmFiIG5lY2Vzc2FyeSBob29rIGlmIG9uZSBpcyBkZWZpbmVkXG5cdFx0aWYgKCBuVHlwZSAhPT0gMSB8fCAhalF1ZXJ5LmlzWE1MRG9jKCBlbGVtICkgKSB7XG5cdFx0XHRuYW1lID0gbmFtZS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0aG9va3MgPSBqUXVlcnkuYXR0ckhvb2tzWyBuYW1lIF0gfHxcblx0XHRcdFx0KCBqUXVlcnkuZXhwci5tYXRjaC5ib29sLnRlc3QoIG5hbWUgKSA/IGJvb2xIb29rIDogbm9kZUhvb2sgKTtcblx0XHR9XG5cblx0XHRpZiAoIHZhbHVlICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdGlmICggdmFsdWUgPT09IG51bGwgKSB7XG5cdFx0XHRcdGpRdWVyeS5yZW1vdmVBdHRyKCBlbGVtLCBuYW1lICk7XG5cblx0XHRcdH0gZWxzZSBpZiAoIGhvb2tzICYmIFwic2V0XCIgaW4gaG9va3MgJiYgKHJldCA9IGhvb2tzLnNldCggZWxlbSwgdmFsdWUsIG5hbWUgKSkgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0cmV0dXJuIHJldDtcblxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZWxlbS5zZXRBdHRyaWJ1dGUoIG5hbWUsIHZhbHVlICsgXCJcIiApO1xuXHRcdFx0XHRyZXR1cm4gdmFsdWU7XG5cdFx0XHR9XG5cblx0XHR9IGVsc2UgaWYgKCBob29rcyAmJiBcImdldFwiIGluIGhvb2tzICYmIChyZXQgPSBob29rcy5nZXQoIGVsZW0sIG5hbWUgKSkgIT09IG51bGwgKSB7XG5cdFx0XHRyZXR1cm4gcmV0O1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldCA9IGpRdWVyeS5maW5kLmF0dHIoIGVsZW0sIG5hbWUgKTtcblxuXHRcdFx0Ly8gTm9uLWV4aXN0ZW50IGF0dHJpYnV0ZXMgcmV0dXJuIG51bGwsIHdlIG5vcm1hbGl6ZSB0byB1bmRlZmluZWRcblx0XHRcdHJldHVybiByZXQgPT0gbnVsbCA/XG5cdFx0XHRcdHVuZGVmaW5lZCA6XG5cdFx0XHRcdHJldDtcblx0XHR9XG5cdH0sXG5cblx0cmVtb3ZlQXR0cjogZnVuY3Rpb24oIGVsZW0sIHZhbHVlICkge1xuXHRcdHZhciBuYW1lLCBwcm9wTmFtZSxcblx0XHRcdGkgPSAwLFxuXHRcdFx0YXR0ck5hbWVzID0gdmFsdWUgJiYgdmFsdWUubWF0Y2goIHJub3R3aGl0ZSApO1xuXG5cdFx0aWYgKCBhdHRyTmFtZXMgJiYgZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdHdoaWxlICggKG5hbWUgPSBhdHRyTmFtZXNbaSsrXSkgKSB7XG5cdFx0XHRcdHByb3BOYW1lID0galF1ZXJ5LnByb3BGaXhbIG5hbWUgXSB8fCBuYW1lO1xuXG5cdFx0XHRcdC8vIEJvb2xlYW4gYXR0cmlidXRlcyBnZXQgc3BlY2lhbCB0cmVhdG1lbnQgKCMxMDg3MClcblx0XHRcdFx0aWYgKCBqUXVlcnkuZXhwci5tYXRjaC5ib29sLnRlc3QoIG5hbWUgKSApIHtcblx0XHRcdFx0XHQvLyBTZXQgY29ycmVzcG9uZGluZyBwcm9wZXJ0eSB0byBmYWxzZVxuXHRcdFx0XHRcdGVsZW1bIHByb3BOYW1lIF0gPSBmYWxzZTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGVsZW0ucmVtb3ZlQXR0cmlidXRlKCBuYW1lICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXG5cdGF0dHJIb29rczoge1xuXHRcdHR5cGU6IHtcblx0XHRcdHNldDogZnVuY3Rpb24oIGVsZW0sIHZhbHVlICkge1xuXHRcdFx0XHRpZiAoICFzdXBwb3J0LnJhZGlvVmFsdWUgJiYgdmFsdWUgPT09IFwicmFkaW9cIiAmJlxuXHRcdFx0XHRcdGpRdWVyeS5ub2RlTmFtZSggZWxlbSwgXCJpbnB1dFwiICkgKSB7XG5cdFx0XHRcdFx0dmFyIHZhbCA9IGVsZW0udmFsdWU7XG5cdFx0XHRcdFx0ZWxlbS5zZXRBdHRyaWJ1dGUoIFwidHlwZVwiLCB2YWx1ZSApO1xuXHRcdFx0XHRcdGlmICggdmFsICkge1xuXHRcdFx0XHRcdFx0ZWxlbS52YWx1ZSA9IHZhbDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIHZhbHVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59KTtcblxuLy8gSG9va3MgZm9yIGJvb2xlYW4gYXR0cmlidXRlc1xuYm9vbEhvb2sgPSB7XG5cdHNldDogZnVuY3Rpb24oIGVsZW0sIHZhbHVlLCBuYW1lICkge1xuXHRcdGlmICggdmFsdWUgPT09IGZhbHNlICkge1xuXHRcdFx0Ly8gUmVtb3ZlIGJvb2xlYW4gYXR0cmlidXRlcyB3aGVuIHNldCB0byBmYWxzZVxuXHRcdFx0alF1ZXJ5LnJlbW92ZUF0dHIoIGVsZW0sIG5hbWUgKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0ZWxlbS5zZXRBdHRyaWJ1dGUoIG5hbWUsIG5hbWUgKTtcblx0XHR9XG5cdFx0cmV0dXJuIG5hbWU7XG5cdH1cbn07XG5qUXVlcnkuZWFjaCggalF1ZXJ5LmV4cHIubWF0Y2guYm9vbC5zb3VyY2UubWF0Y2goIC9cXHcrL2cgKSwgZnVuY3Rpb24oIGksIG5hbWUgKSB7XG5cdHZhciBnZXR0ZXIgPSBhdHRySGFuZGxlWyBuYW1lIF0gfHwgalF1ZXJ5LmZpbmQuYXR0cjtcblxuXHRhdHRySGFuZGxlWyBuYW1lIF0gPSBmdW5jdGlvbiggZWxlbSwgbmFtZSwgaXNYTUwgKSB7XG5cdFx0dmFyIHJldCwgaGFuZGxlO1xuXHRcdGlmICggIWlzWE1MICkge1xuXHRcdFx0Ly8gQXZvaWQgYW4gaW5maW5pdGUgbG9vcCBieSB0ZW1wb3JhcmlseSByZW1vdmluZyB0aGlzIGZ1bmN0aW9uIGZyb20gdGhlIGdldHRlclxuXHRcdFx0aGFuZGxlID0gYXR0ckhhbmRsZVsgbmFtZSBdO1xuXHRcdFx0YXR0ckhhbmRsZVsgbmFtZSBdID0gcmV0O1xuXHRcdFx0cmV0ID0gZ2V0dGVyKCBlbGVtLCBuYW1lLCBpc1hNTCApICE9IG51bGwgP1xuXHRcdFx0XHRuYW1lLnRvTG93ZXJDYXNlKCkgOlxuXHRcdFx0XHRudWxsO1xuXHRcdFx0YXR0ckhhbmRsZVsgbmFtZSBdID0gaGFuZGxlO1xuXHRcdH1cblx0XHRyZXR1cm4gcmV0O1xuXHR9O1xufSk7XG5cblxuXG5cbnZhciByZm9jdXNhYmxlID0gL14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8YnV0dG9uKSQvaTtcblxualF1ZXJ5LmZuLmV4dGVuZCh7XG5cdHByb3A6IGZ1bmN0aW9uKCBuYW1lLCB2YWx1ZSApIHtcblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBqUXVlcnkucHJvcCwgbmFtZSwgdmFsdWUsIGFyZ3VtZW50cy5sZW5ndGggPiAxICk7XG5cdH0sXG5cblx0cmVtb3ZlUHJvcDogZnVuY3Rpb24oIG5hbWUgKSB7XG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdGRlbGV0ZSB0aGlzWyBqUXVlcnkucHJvcEZpeFsgbmFtZSBdIHx8IG5hbWUgXTtcblx0XHR9KTtcblx0fVxufSk7XG5cbmpRdWVyeS5leHRlbmQoe1xuXHRwcm9wRml4OiB7XG5cdFx0XCJmb3JcIjogXCJodG1sRm9yXCIsXG5cdFx0XCJjbGFzc1wiOiBcImNsYXNzTmFtZVwiXG5cdH0sXG5cblx0cHJvcDogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIHZhbHVlICkge1xuXHRcdHZhciByZXQsIGhvb2tzLCBub3R4bWwsXG5cdFx0XHRuVHlwZSA9IGVsZW0ubm9kZVR5cGU7XG5cblx0XHQvLyBEb24ndCBnZXQvc2V0IHByb3BlcnRpZXMgb24gdGV4dCwgY29tbWVudCBhbmQgYXR0cmlidXRlIG5vZGVzXG5cdFx0aWYgKCAhZWxlbSB8fCBuVHlwZSA9PT0gMyB8fCBuVHlwZSA9PT0gOCB8fCBuVHlwZSA9PT0gMiApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRub3R4bWwgPSBuVHlwZSAhPT0gMSB8fCAhalF1ZXJ5LmlzWE1MRG9jKCBlbGVtICk7XG5cblx0XHRpZiAoIG5vdHhtbCApIHtcblx0XHRcdC8vIEZpeCBuYW1lIGFuZCBhdHRhY2ggaG9va3Ncblx0XHRcdG5hbWUgPSBqUXVlcnkucHJvcEZpeFsgbmFtZSBdIHx8IG5hbWU7XG5cdFx0XHRob29rcyA9IGpRdWVyeS5wcm9wSG9va3NbIG5hbWUgXTtcblx0XHR9XG5cblx0XHRpZiAoIHZhbHVlICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRyZXR1cm4gaG9va3MgJiYgXCJzZXRcIiBpbiBob29rcyAmJiAocmV0ID0gaG9va3Muc2V0KCBlbGVtLCB2YWx1ZSwgbmFtZSApKSAhPT0gdW5kZWZpbmVkID9cblx0XHRcdFx0cmV0IDpcblx0XHRcdFx0KCBlbGVtWyBuYW1lIF0gPSB2YWx1ZSApO1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiBob29rcyAmJiBcImdldFwiIGluIGhvb2tzICYmIChyZXQgPSBob29rcy5nZXQoIGVsZW0sIG5hbWUgKSkgIT09IG51bGwgP1xuXHRcdFx0XHRyZXQgOlxuXHRcdFx0XHRlbGVtWyBuYW1lIF07XG5cdFx0fVxuXHR9LFxuXG5cdHByb3BIb29rczoge1xuXHRcdHRhYkluZGV4OiB7XG5cdFx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRyZXR1cm4gZWxlbS5oYXNBdHRyaWJ1dGUoIFwidGFiaW5kZXhcIiApIHx8IHJmb2N1c2FibGUudGVzdCggZWxlbS5ub2RlTmFtZSApIHx8IGVsZW0uaHJlZiA/XG5cdFx0XHRcdFx0ZWxlbS50YWJJbmRleCA6XG5cdFx0XHRcdFx0LTE7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59KTtcblxuaWYgKCAhc3VwcG9ydC5vcHRTZWxlY3RlZCApIHtcblx0alF1ZXJ5LnByb3BIb29rcy5zZWxlY3RlZCA9IHtcblx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0dmFyIHBhcmVudCA9IGVsZW0ucGFyZW50Tm9kZTtcblx0XHRcdGlmICggcGFyZW50ICYmIHBhcmVudC5wYXJlbnROb2RlICkge1xuXHRcdFx0XHRwYXJlbnQucGFyZW50Tm9kZS5zZWxlY3RlZEluZGV4O1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0fVxuXHR9O1xufVxuXG5qUXVlcnkuZWFjaChbXG5cdFwidGFiSW5kZXhcIixcblx0XCJyZWFkT25seVwiLFxuXHRcIm1heExlbmd0aFwiLFxuXHRcImNlbGxTcGFjaW5nXCIsXG5cdFwiY2VsbFBhZGRpbmdcIixcblx0XCJyb3dTcGFuXCIsXG5cdFwiY29sU3BhblwiLFxuXHRcInVzZU1hcFwiLFxuXHRcImZyYW1lQm9yZGVyXCIsXG5cdFwiY29udGVudEVkaXRhYmxlXCJcbl0sIGZ1bmN0aW9uKCkge1xuXHRqUXVlcnkucHJvcEZpeFsgdGhpcy50b0xvd2VyQ2FzZSgpIF0gPSB0aGlzO1xufSk7XG5cblxuXG5cbnZhciByY2xhc3MgPSAvW1xcdFxcclxcblxcZl0vZztcblxualF1ZXJ5LmZuLmV4dGVuZCh7XG5cdGFkZENsYXNzOiBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0dmFyIGNsYXNzZXMsIGVsZW0sIGN1ciwgY2xhenosIGosIGZpbmFsVmFsdWUsXG5cdFx0XHRwcm9jZWVkID0gdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiICYmIHZhbHVlLFxuXHRcdFx0aSA9IDAsXG5cdFx0XHRsZW4gPSB0aGlzLmxlbmd0aDtcblxuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHZhbHVlICkgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCBqICkge1xuXHRcdFx0XHRqUXVlcnkoIHRoaXMgKS5hZGRDbGFzcyggdmFsdWUuY2FsbCggdGhpcywgaiwgdGhpcy5jbGFzc05hbWUgKSApO1xuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0aWYgKCBwcm9jZWVkICkge1xuXHRcdFx0Ly8gVGhlIGRpc2p1bmN0aW9uIGhlcmUgaXMgZm9yIGJldHRlciBjb21wcmVzc2liaWxpdHkgKHNlZSByZW1vdmVDbGFzcylcblx0XHRcdGNsYXNzZXMgPSAoIHZhbHVlIHx8IFwiXCIgKS5tYXRjaCggcm5vdHdoaXRlICkgfHwgW107XG5cblx0XHRcdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdFx0XHRlbGVtID0gdGhpc1sgaSBdO1xuXHRcdFx0XHRjdXIgPSBlbGVtLm5vZGVUeXBlID09PSAxICYmICggZWxlbS5jbGFzc05hbWUgP1xuXHRcdFx0XHRcdCggXCIgXCIgKyBlbGVtLmNsYXNzTmFtZSArIFwiIFwiICkucmVwbGFjZSggcmNsYXNzLCBcIiBcIiApIDpcblx0XHRcdFx0XHRcIiBcIlxuXHRcdFx0XHQpO1xuXG5cdFx0XHRcdGlmICggY3VyICkge1xuXHRcdFx0XHRcdGogPSAwO1xuXHRcdFx0XHRcdHdoaWxlICggKGNsYXp6ID0gY2xhc3Nlc1tqKytdKSApIHtcblx0XHRcdFx0XHRcdGlmICggY3VyLmluZGV4T2YoIFwiIFwiICsgY2xhenogKyBcIiBcIiApIDwgMCApIHtcblx0XHRcdFx0XHRcdFx0Y3VyICs9IGNsYXp6ICsgXCIgXCI7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gb25seSBhc3NpZ24gaWYgZGlmZmVyZW50IHRvIGF2b2lkIHVubmVlZGVkIHJlbmRlcmluZy5cblx0XHRcdFx0XHRmaW5hbFZhbHVlID0galF1ZXJ5LnRyaW0oIGN1ciApO1xuXHRcdFx0XHRcdGlmICggZWxlbS5jbGFzc05hbWUgIT09IGZpbmFsVmFsdWUgKSB7XG5cdFx0XHRcdFx0XHRlbGVtLmNsYXNzTmFtZSA9IGZpbmFsVmFsdWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0cmVtb3ZlQ2xhc3M6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHR2YXIgY2xhc3NlcywgZWxlbSwgY3VyLCBjbGF6eiwgaiwgZmluYWxWYWx1ZSxcblx0XHRcdHByb2NlZWQgPSBhcmd1bWVudHMubGVuZ3RoID09PSAwIHx8IHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiB2YWx1ZSxcblx0XHRcdGkgPSAwLFxuXHRcdFx0bGVuID0gdGhpcy5sZW5ndGg7XG5cblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCB2YWx1ZSApICkge1xuXHRcdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiggaiApIHtcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkucmVtb3ZlQ2xhc3MoIHZhbHVlLmNhbGwoIHRoaXMsIGosIHRoaXMuY2xhc3NOYW1lICkgKTtcblx0XHRcdH0pO1xuXHRcdH1cblx0XHRpZiAoIHByb2NlZWQgKSB7XG5cdFx0XHRjbGFzc2VzID0gKCB2YWx1ZSB8fCBcIlwiICkubWF0Y2goIHJub3R3aGl0ZSApIHx8IFtdO1xuXG5cdFx0XHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdFx0ZWxlbSA9IHRoaXNbIGkgXTtcblx0XHRcdFx0Ly8gVGhpcyBleHByZXNzaW9uIGlzIGhlcmUgZm9yIGJldHRlciBjb21wcmVzc2liaWxpdHkgKHNlZSBhZGRDbGFzcylcblx0XHRcdFx0Y3VyID0gZWxlbS5ub2RlVHlwZSA9PT0gMSAmJiAoIGVsZW0uY2xhc3NOYW1lID9cblx0XHRcdFx0XHQoIFwiIFwiICsgZWxlbS5jbGFzc05hbWUgKyBcIiBcIiApLnJlcGxhY2UoIHJjbGFzcywgXCIgXCIgKSA6XG5cdFx0XHRcdFx0XCJcIlxuXHRcdFx0XHQpO1xuXG5cdFx0XHRcdGlmICggY3VyICkge1xuXHRcdFx0XHRcdGogPSAwO1xuXHRcdFx0XHRcdHdoaWxlICggKGNsYXp6ID0gY2xhc3Nlc1tqKytdKSApIHtcblx0XHRcdFx0XHRcdC8vIFJlbW92ZSAqYWxsKiBpbnN0YW5jZXNcblx0XHRcdFx0XHRcdHdoaWxlICggY3VyLmluZGV4T2YoIFwiIFwiICsgY2xhenogKyBcIiBcIiApID49IDAgKSB7XG5cdFx0XHRcdFx0XHRcdGN1ciA9IGN1ci5yZXBsYWNlKCBcIiBcIiArIGNsYXp6ICsgXCIgXCIsIFwiIFwiICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gT25seSBhc3NpZ24gaWYgZGlmZmVyZW50IHRvIGF2b2lkIHVubmVlZGVkIHJlbmRlcmluZy5cblx0XHRcdFx0XHRmaW5hbFZhbHVlID0gdmFsdWUgPyBqUXVlcnkudHJpbSggY3VyICkgOiBcIlwiO1xuXHRcdFx0XHRcdGlmICggZWxlbS5jbGFzc05hbWUgIT09IGZpbmFsVmFsdWUgKSB7XG5cdFx0XHRcdFx0XHRlbGVtLmNsYXNzTmFtZSA9IGZpbmFsVmFsdWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0dG9nZ2xlQ2xhc3M6IGZ1bmN0aW9uKCB2YWx1ZSwgc3RhdGVWYWwgKSB7XG5cdFx0dmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG5cblx0XHRpZiAoIHR5cGVvZiBzdGF0ZVZhbCA9PT0gXCJib29sZWFuXCIgJiYgdHlwZSA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHJldHVybiBzdGF0ZVZhbCA/IHRoaXMuYWRkQ2xhc3MoIHZhbHVlICkgOiB0aGlzLnJlbW92ZUNsYXNzKCB2YWx1ZSApO1xuXHRcdH1cblxuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHZhbHVlICkgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCBpICkge1xuXHRcdFx0XHRqUXVlcnkoIHRoaXMgKS50b2dnbGVDbGFzcyggdmFsdWUuY2FsbCh0aGlzLCBpLCB0aGlzLmNsYXNzTmFtZSwgc3RhdGVWYWwpLCBzdGF0ZVZhbCApO1xuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdGlmICggdHlwZSA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdFx0Ly8gVG9nZ2xlIGluZGl2aWR1YWwgY2xhc3MgbmFtZXNcblx0XHRcdFx0dmFyIGNsYXNzTmFtZSxcblx0XHRcdFx0XHRpID0gMCxcblx0XHRcdFx0XHRzZWxmID0galF1ZXJ5KCB0aGlzICksXG5cdFx0XHRcdFx0Y2xhc3NOYW1lcyA9IHZhbHVlLm1hdGNoKCBybm90d2hpdGUgKSB8fCBbXTtcblxuXHRcdFx0XHR3aGlsZSAoIChjbGFzc05hbWUgPSBjbGFzc05hbWVzWyBpKysgXSkgKSB7XG5cdFx0XHRcdFx0Ly8gQ2hlY2sgZWFjaCBjbGFzc05hbWUgZ2l2ZW4sIHNwYWNlIHNlcGFyYXRlZCBsaXN0XG5cdFx0XHRcdFx0aWYgKCBzZWxmLmhhc0NsYXNzKCBjbGFzc05hbWUgKSApIHtcblx0XHRcdFx0XHRcdHNlbGYucmVtb3ZlQ2xhc3MoIGNsYXNzTmFtZSApO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRzZWxmLmFkZENsYXNzKCBjbGFzc05hbWUgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0Ly8gVG9nZ2xlIHdob2xlIGNsYXNzIG5hbWVcblx0XHRcdH0gZWxzZSBpZiAoIHR5cGUgPT09IHN0cnVuZGVmaW5lZCB8fCB0eXBlID09PSBcImJvb2xlYW5cIiApIHtcblx0XHRcdFx0aWYgKCB0aGlzLmNsYXNzTmFtZSApIHtcblx0XHRcdFx0XHQvLyBzdG9yZSBjbGFzc05hbWUgaWYgc2V0XG5cdFx0XHRcdFx0ZGF0YV9wcml2LnNldCggdGhpcywgXCJfX2NsYXNzTmFtZV9fXCIsIHRoaXMuY2xhc3NOYW1lICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBJZiB0aGUgZWxlbWVudCBoYXMgYSBjbGFzcyBuYW1lIG9yIGlmIHdlJ3JlIHBhc3NlZCBgZmFsc2VgLFxuXHRcdFx0XHQvLyB0aGVuIHJlbW92ZSB0aGUgd2hvbGUgY2xhc3NuYW1lIChpZiB0aGVyZSB3YXMgb25lLCB0aGUgYWJvdmUgc2F2ZWQgaXQpLlxuXHRcdFx0XHQvLyBPdGhlcndpc2UgYnJpbmcgYmFjayB3aGF0ZXZlciB3YXMgcHJldmlvdXNseSBzYXZlZCAoaWYgYW55dGhpbmcpLFxuXHRcdFx0XHQvLyBmYWxsaW5nIGJhY2sgdG8gdGhlIGVtcHR5IHN0cmluZyBpZiBub3RoaW5nIHdhcyBzdG9yZWQuXG5cdFx0XHRcdHRoaXMuY2xhc3NOYW1lID0gdGhpcy5jbGFzc05hbWUgfHwgdmFsdWUgPT09IGZhbHNlID8gXCJcIiA6IGRhdGFfcHJpdi5nZXQoIHRoaXMsIFwiX19jbGFzc05hbWVfX1wiICkgfHwgXCJcIjtcblx0XHRcdH1cblx0XHR9KTtcblx0fSxcblxuXHRoYXNDbGFzczogZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHZhciBjbGFzc05hbWUgPSBcIiBcIiArIHNlbGVjdG9yICsgXCIgXCIsXG5cdFx0XHRpID0gMCxcblx0XHRcdGwgPSB0aGlzLmxlbmd0aDtcblx0XHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRpZiAoIHRoaXNbaV0ubm9kZVR5cGUgPT09IDEgJiYgKFwiIFwiICsgdGhpc1tpXS5jbGFzc05hbWUgKyBcIiBcIikucmVwbGFjZShyY2xhc3MsIFwiIFwiKS5pbmRleE9mKCBjbGFzc05hbWUgKSA+PSAwICkge1xuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn0pO1xuXG5cblxuXG52YXIgcnJldHVybiA9IC9cXHIvZztcblxualF1ZXJ5LmZuLmV4dGVuZCh7XG5cdHZhbDogZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdHZhciBob29rcywgcmV0LCBpc0Z1bmN0aW9uLFxuXHRcdFx0ZWxlbSA9IHRoaXNbMF07XG5cblx0XHRpZiAoICFhcmd1bWVudHMubGVuZ3RoICkge1xuXHRcdFx0aWYgKCBlbGVtICkge1xuXHRcdFx0XHRob29rcyA9IGpRdWVyeS52YWxIb29rc1sgZWxlbS50eXBlIF0gfHwgalF1ZXJ5LnZhbEhvb2tzWyBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgXTtcblxuXHRcdFx0XHRpZiAoIGhvb2tzICYmIFwiZ2V0XCIgaW4gaG9va3MgJiYgKHJldCA9IGhvb2tzLmdldCggZWxlbSwgXCJ2YWx1ZVwiICkpICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHJldDtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldCA9IGVsZW0udmFsdWU7XG5cblx0XHRcdFx0cmV0dXJuIHR5cGVvZiByZXQgPT09IFwic3RyaW5nXCIgP1xuXHRcdFx0XHRcdC8vIEhhbmRsZSBtb3N0IGNvbW1vbiBzdHJpbmcgY2FzZXNcblx0XHRcdFx0XHRyZXQucmVwbGFjZShycmV0dXJuLCBcIlwiKSA6XG5cdFx0XHRcdFx0Ly8gSGFuZGxlIGNhc2VzIHdoZXJlIHZhbHVlIGlzIG51bGwvdW5kZWYgb3IgbnVtYmVyXG5cdFx0XHRcdFx0cmV0ID09IG51bGwgPyBcIlwiIDogcmV0O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aXNGdW5jdGlvbiA9IGpRdWVyeS5pc0Z1bmN0aW9uKCB2YWx1ZSApO1xuXG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiggaSApIHtcblx0XHRcdHZhciB2YWw7XG5cblx0XHRcdGlmICggdGhpcy5ub2RlVHlwZSAhPT0gMSApIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGlzRnVuY3Rpb24gKSB7XG5cdFx0XHRcdHZhbCA9IHZhbHVlLmNhbGwoIHRoaXMsIGksIGpRdWVyeSggdGhpcyApLnZhbCgpICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR2YWwgPSB2YWx1ZTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gVHJlYXQgbnVsbC91bmRlZmluZWQgYXMgXCJcIjsgY29udmVydCBudW1iZXJzIHRvIHN0cmluZ1xuXHRcdFx0aWYgKCB2YWwgPT0gbnVsbCApIHtcblx0XHRcdFx0dmFsID0gXCJcIjtcblxuXHRcdFx0fSBlbHNlIGlmICggdHlwZW9mIHZhbCA9PT0gXCJudW1iZXJcIiApIHtcblx0XHRcdFx0dmFsICs9IFwiXCI7XG5cblx0XHRcdH0gZWxzZSBpZiAoIGpRdWVyeS5pc0FycmF5KCB2YWwgKSApIHtcblx0XHRcdFx0dmFsID0galF1ZXJ5Lm1hcCggdmFsLCBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHZhbHVlID09IG51bGwgPyBcIlwiIDogdmFsdWUgKyBcIlwiO1xuXHRcdFx0XHR9KTtcblx0XHRcdH1cblxuXHRcdFx0aG9va3MgPSBqUXVlcnkudmFsSG9va3NbIHRoaXMudHlwZSBdIHx8IGpRdWVyeS52YWxIb29rc1sgdGhpcy5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpIF07XG5cblx0XHRcdC8vIElmIHNldCByZXR1cm5zIHVuZGVmaW5lZCwgZmFsbCBiYWNrIHRvIG5vcm1hbCBzZXR0aW5nXG5cdFx0XHRpZiAoICFob29rcyB8fCAhKFwic2V0XCIgaW4gaG9va3MpIHx8IGhvb2tzLnNldCggdGhpcywgdmFsLCBcInZhbHVlXCIgKSA9PT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHR0aGlzLnZhbHVlID0gdmFsO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG59KTtcblxualF1ZXJ5LmV4dGVuZCh7XG5cdHZhbEhvb2tzOiB7XG5cdFx0b3B0aW9uOiB7XG5cdFx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHR2YXIgdmFsID0galF1ZXJ5LmZpbmQuYXR0ciggZWxlbSwgXCJ2YWx1ZVwiICk7XG5cdFx0XHRcdHJldHVybiB2YWwgIT0gbnVsbCA/XG5cdFx0XHRcdFx0dmFsIDpcblx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRTEwLTExK1xuXHRcdFx0XHRcdC8vIG9wdGlvbi50ZXh0IHRocm93cyBleGNlcHRpb25zICgjMTQ2ODYsICMxNDg1OClcblx0XHRcdFx0XHRqUXVlcnkudHJpbSggalF1ZXJ5LnRleHQoIGVsZW0gKSApO1xuXHRcdFx0fVxuXHRcdH0sXG5cdFx0c2VsZWN0OiB7XG5cdFx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHR2YXIgdmFsdWUsIG9wdGlvbixcblx0XHRcdFx0XHRvcHRpb25zID0gZWxlbS5vcHRpb25zLFxuXHRcdFx0XHRcdGluZGV4ID0gZWxlbS5zZWxlY3RlZEluZGV4LFxuXHRcdFx0XHRcdG9uZSA9IGVsZW0udHlwZSA9PT0gXCJzZWxlY3Qtb25lXCIgfHwgaW5kZXggPCAwLFxuXHRcdFx0XHRcdHZhbHVlcyA9IG9uZSA/IG51bGwgOiBbXSxcblx0XHRcdFx0XHRtYXggPSBvbmUgPyBpbmRleCArIDEgOiBvcHRpb25zLmxlbmd0aCxcblx0XHRcdFx0XHRpID0gaW5kZXggPCAwID9cblx0XHRcdFx0XHRcdG1heCA6XG5cdFx0XHRcdFx0XHRvbmUgPyBpbmRleCA6IDA7XG5cblx0XHRcdFx0Ly8gTG9vcCB0aHJvdWdoIGFsbCB0aGUgc2VsZWN0ZWQgb3B0aW9uc1xuXHRcdFx0XHRmb3IgKCA7IGkgPCBtYXg7IGkrKyApIHtcblx0XHRcdFx0XHRvcHRpb24gPSBvcHRpb25zWyBpIF07XG5cblx0XHRcdFx0XHQvLyBJRTYtOSBkb2Vzbid0IHVwZGF0ZSBzZWxlY3RlZCBhZnRlciBmb3JtIHJlc2V0ICgjMjU1MSlcblx0XHRcdFx0XHRpZiAoICggb3B0aW9uLnNlbGVjdGVkIHx8IGkgPT09IGluZGV4ICkgJiZcblx0XHRcdFx0XHRcdFx0Ly8gRG9uJ3QgcmV0dXJuIG9wdGlvbnMgdGhhdCBhcmUgZGlzYWJsZWQgb3IgaW4gYSBkaXNhYmxlZCBvcHRncm91cFxuXHRcdFx0XHRcdFx0XHQoIHN1cHBvcnQub3B0RGlzYWJsZWQgPyAhb3B0aW9uLmRpc2FibGVkIDogb3B0aW9uLmdldEF0dHJpYnV0ZSggXCJkaXNhYmxlZFwiICkgPT09IG51bGwgKSAmJlxuXHRcdFx0XHRcdFx0XHQoICFvcHRpb24ucGFyZW50Tm9kZS5kaXNhYmxlZCB8fCAhalF1ZXJ5Lm5vZGVOYW1lKCBvcHRpb24ucGFyZW50Tm9kZSwgXCJvcHRncm91cFwiICkgKSApIHtcblxuXHRcdFx0XHRcdFx0Ly8gR2V0IHRoZSBzcGVjaWZpYyB2YWx1ZSBmb3IgdGhlIG9wdGlvblxuXHRcdFx0XHRcdFx0dmFsdWUgPSBqUXVlcnkoIG9wdGlvbiApLnZhbCgpO1xuXG5cdFx0XHRcdFx0XHQvLyBXZSBkb24ndCBuZWVkIGFuIGFycmF5IGZvciBvbmUgc2VsZWN0c1xuXHRcdFx0XHRcdFx0aWYgKCBvbmUgKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiB2YWx1ZTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0Ly8gTXVsdGktU2VsZWN0cyByZXR1cm4gYW4gYXJyYXlcblx0XHRcdFx0XHRcdHZhbHVlcy5wdXNoKCB2YWx1ZSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiB2YWx1ZXM7XG5cdFx0XHR9LFxuXG5cdFx0XHRzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSApIHtcblx0XHRcdFx0dmFyIG9wdGlvblNldCwgb3B0aW9uLFxuXHRcdFx0XHRcdG9wdGlvbnMgPSBlbGVtLm9wdGlvbnMsXG5cdFx0XHRcdFx0dmFsdWVzID0galF1ZXJ5Lm1ha2VBcnJheSggdmFsdWUgKSxcblx0XHRcdFx0XHRpID0gb3B0aW9ucy5sZW5ndGg7XG5cblx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdFx0b3B0aW9uID0gb3B0aW9uc1sgaSBdO1xuXHRcdFx0XHRcdGlmICggKG9wdGlvbi5zZWxlY3RlZCA9IGpRdWVyeS5pbkFycmF5KCBvcHRpb24udmFsdWUsIHZhbHVlcyApID49IDApICkge1xuXHRcdFx0XHRcdFx0b3B0aW9uU2V0ID0gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBGb3JjZSBicm93c2VycyB0byBiZWhhdmUgY29uc2lzdGVudGx5IHdoZW4gbm9uLW1hdGNoaW5nIHZhbHVlIGlzIHNldFxuXHRcdFx0XHRpZiAoICFvcHRpb25TZXQgKSB7XG5cdFx0XHRcdFx0ZWxlbS5zZWxlY3RlZEluZGV4ID0gLTE7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHZhbHVlcztcblx0XHRcdH1cblx0XHR9XG5cdH1cbn0pO1xuXG4vLyBSYWRpb3MgYW5kIGNoZWNrYm94ZXMgZ2V0dGVyL3NldHRlclxualF1ZXJ5LmVhY2goWyBcInJhZGlvXCIsIFwiY2hlY2tib3hcIiBdLCBmdW5jdGlvbigpIHtcblx0alF1ZXJ5LnZhbEhvb2tzWyB0aGlzIF0gPSB7XG5cdFx0c2V0OiBmdW5jdGlvbiggZWxlbSwgdmFsdWUgKSB7XG5cdFx0XHRpZiAoIGpRdWVyeS5pc0FycmF5KCB2YWx1ZSApICkge1xuXHRcdFx0XHRyZXR1cm4gKCBlbGVtLmNoZWNrZWQgPSBqUXVlcnkuaW5BcnJheSggalF1ZXJ5KGVsZW0pLnZhbCgpLCB2YWx1ZSApID49IDAgKTtcblx0XHRcdH1cblx0XHR9XG5cdH07XG5cdGlmICggIXN1cHBvcnQuY2hlY2tPbiApIHtcblx0XHRqUXVlcnkudmFsSG9va3NbIHRoaXMgXS5nZXQgPSBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtLmdldEF0dHJpYnV0ZShcInZhbHVlXCIpID09PSBudWxsID8gXCJvblwiIDogZWxlbS52YWx1ZTtcblx0XHR9O1xuXHR9XG59KTtcblxuXG5cblxuLy8gUmV0dXJuIGpRdWVyeSBmb3IgYXR0cmlidXRlcy1vbmx5IGluY2x1c2lvblxuXG5cbmpRdWVyeS5lYWNoKCAoXCJibHVyIGZvY3VzIGZvY3VzaW4gZm9jdXNvdXQgbG9hZCByZXNpemUgc2Nyb2xsIHVubG9hZCBjbGljayBkYmxjbGljayBcIiArXG5cdFwibW91c2Vkb3duIG1vdXNldXAgbW91c2Vtb3ZlIG1vdXNlb3ZlciBtb3VzZW91dCBtb3VzZWVudGVyIG1vdXNlbGVhdmUgXCIgK1xuXHRcImNoYW5nZSBzZWxlY3Qgc3VibWl0IGtleWRvd24ga2V5cHJlc3Mga2V5dXAgZXJyb3IgY29udGV4dG1lbnVcIikuc3BsaXQoXCIgXCIpLCBmdW5jdGlvbiggaSwgbmFtZSApIHtcblxuXHQvLyBIYW5kbGUgZXZlbnQgYmluZGluZ1xuXHRqUXVlcnkuZm5bIG5hbWUgXSA9IGZ1bmN0aW9uKCBkYXRhLCBmbiApIHtcblx0XHRyZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA+IDAgP1xuXHRcdFx0dGhpcy5vbiggbmFtZSwgbnVsbCwgZGF0YSwgZm4gKSA6XG5cdFx0XHR0aGlzLnRyaWdnZXIoIG5hbWUgKTtcblx0fTtcbn0pO1xuXG5qUXVlcnkuZm4uZXh0ZW5kKHtcblx0aG92ZXI6IGZ1bmN0aW9uKCBmbk92ZXIsIGZuT3V0ICkge1xuXHRcdHJldHVybiB0aGlzLm1vdXNlZW50ZXIoIGZuT3ZlciApLm1vdXNlbGVhdmUoIGZuT3V0IHx8IGZuT3ZlciApO1xuXHR9LFxuXG5cdGJpbmQ6IGZ1bmN0aW9uKCB0eXBlcywgZGF0YSwgZm4gKSB7XG5cdFx0cmV0dXJuIHRoaXMub24oIHR5cGVzLCBudWxsLCBkYXRhLCBmbiApO1xuXHR9LFxuXHR1bmJpbmQ6IGZ1bmN0aW9uKCB0eXBlcywgZm4gKSB7XG5cdFx0cmV0dXJuIHRoaXMub2ZmKCB0eXBlcywgbnVsbCwgZm4gKTtcblx0fSxcblxuXHRkZWxlZ2F0ZTogZnVuY3Rpb24oIHNlbGVjdG9yLCB0eXBlcywgZGF0YSwgZm4gKSB7XG5cdFx0cmV0dXJuIHRoaXMub24oIHR5cGVzLCBzZWxlY3RvciwgZGF0YSwgZm4gKTtcblx0fSxcblx0dW5kZWxlZ2F0ZTogZnVuY3Rpb24oIHNlbGVjdG9yLCB0eXBlcywgZm4gKSB7XG5cdFx0Ly8gKCBuYW1lc3BhY2UgKSBvciAoIHNlbGVjdG9yLCB0eXBlcyBbLCBmbl0gKVxuXHRcdHJldHVybiBhcmd1bWVudHMubGVuZ3RoID09PSAxID8gdGhpcy5vZmYoIHNlbGVjdG9yLCBcIioqXCIgKSA6IHRoaXMub2ZmKCB0eXBlcywgc2VsZWN0b3IgfHwgXCIqKlwiLCBmbiApO1xuXHR9XG59KTtcblxuXG52YXIgbm9uY2UgPSBqUXVlcnkubm93KCk7XG5cbnZhciBycXVlcnkgPSAoL1xcPy8pO1xuXG5cblxuLy8gU3VwcG9ydDogQW5kcm9pZCAyLjNcbi8vIFdvcmthcm91bmQgZmFpbHVyZSB0byBzdHJpbmctY2FzdCBudWxsIGlucHV0XG5qUXVlcnkucGFyc2VKU09OID0gZnVuY3Rpb24oIGRhdGEgKSB7XG5cdHJldHVybiBKU09OLnBhcnNlKCBkYXRhICsgXCJcIiApO1xufTtcblxuXG4vLyBDcm9zcy1icm93c2VyIHhtbCBwYXJzaW5nXG5qUXVlcnkucGFyc2VYTUwgPSBmdW5jdGlvbiggZGF0YSApIHtcblx0dmFyIHhtbCwgdG1wO1xuXHRpZiAoICFkYXRhIHx8IHR5cGVvZiBkYXRhICE9PSBcInN0cmluZ1wiICkge1xuXHRcdHJldHVybiBudWxsO1xuXHR9XG5cblx0Ly8gU3VwcG9ydDogSUU5XG5cdHRyeSB7XG5cdFx0dG1wID0gbmV3IERPTVBhcnNlcigpO1xuXHRcdHhtbCA9IHRtcC5wYXJzZUZyb21TdHJpbmcoIGRhdGEsIFwidGV4dC94bWxcIiApO1xuXHR9IGNhdGNoICggZSApIHtcblx0XHR4bWwgPSB1bmRlZmluZWQ7XG5cdH1cblxuXHRpZiAoICF4bWwgfHwgeG1sLmdldEVsZW1lbnRzQnlUYWdOYW1lKCBcInBhcnNlcmVycm9yXCIgKS5sZW5ndGggKSB7XG5cdFx0alF1ZXJ5LmVycm9yKCBcIkludmFsaWQgWE1MOiBcIiArIGRhdGEgKTtcblx0fVxuXHRyZXR1cm4geG1sO1xufTtcblxuXG52YXJcblx0cmhhc2ggPSAvIy4qJC8sXG5cdHJ0cyA9IC8oWz8mXSlfPVteJl0qLyxcblx0cmhlYWRlcnMgPSAvXiguKj8pOlsgXFx0XSooW15cXHJcXG5dKikkL21nLFxuXHQvLyAjNzY1MywgIzgxMjUsICM4MTUyOiBsb2NhbCBwcm90b2NvbCBkZXRlY3Rpb25cblx0cmxvY2FsUHJvdG9jb2wgPSAvXig/OmFib3V0fGFwcHxhcHAtc3RvcmFnZXwuKy1leHRlbnNpb258ZmlsZXxyZXN8d2lkZ2V0KTokLyxcblx0cm5vQ29udGVudCA9IC9eKD86R0VUfEhFQUQpJC8sXG5cdHJwcm90b2NvbCA9IC9eXFwvXFwvLyxcblx0cnVybCA9IC9eKFtcXHcuKy1dKzopKD86XFwvXFwvKD86W15cXC8/I10qQHwpKFteXFwvPyM6XSopKD86OihcXGQrKXwpfCkvLFxuXG5cdC8qIFByZWZpbHRlcnNcblx0ICogMSkgVGhleSBhcmUgdXNlZnVsIHRvIGludHJvZHVjZSBjdXN0b20gZGF0YVR5cGVzIChzZWUgYWpheC9qc29ucC5qcyBmb3IgYW4gZXhhbXBsZSlcblx0ICogMikgVGhlc2UgYXJlIGNhbGxlZDpcblx0ICogICAgLSBCRUZPUkUgYXNraW5nIGZvciBhIHRyYW5zcG9ydFxuXHQgKiAgICAtIEFGVEVSIHBhcmFtIHNlcmlhbGl6YXRpb24gKHMuZGF0YSBpcyBhIHN0cmluZyBpZiBzLnByb2Nlc3NEYXRhIGlzIHRydWUpXG5cdCAqIDMpIGtleSBpcyB0aGUgZGF0YVR5cGVcblx0ICogNCkgdGhlIGNhdGNoYWxsIHN5bWJvbCBcIipcIiBjYW4gYmUgdXNlZFxuXHQgKiA1KSBleGVjdXRpb24gd2lsbCBzdGFydCB3aXRoIHRyYW5zcG9ydCBkYXRhVHlwZSBhbmQgVEhFTiBjb250aW51ZSBkb3duIHRvIFwiKlwiIGlmIG5lZWRlZFxuXHQgKi9cblx0cHJlZmlsdGVycyA9IHt9LFxuXG5cdC8qIFRyYW5zcG9ydHMgYmluZGluZ3Ncblx0ICogMSkga2V5IGlzIHRoZSBkYXRhVHlwZVxuXHQgKiAyKSB0aGUgY2F0Y2hhbGwgc3ltYm9sIFwiKlwiIGNhbiBiZSB1c2VkXG5cdCAqIDMpIHNlbGVjdGlvbiB3aWxsIHN0YXJ0IHdpdGggdHJhbnNwb3J0IGRhdGFUeXBlIGFuZCBUSEVOIGdvIHRvIFwiKlwiIGlmIG5lZWRlZFxuXHQgKi9cblx0dHJhbnNwb3J0cyA9IHt9LFxuXG5cdC8vIEF2b2lkIGNvbW1lbnQtcHJvbG9nIGNoYXIgc2VxdWVuY2UgKCMxMDA5OCk7IG11c3QgYXBwZWFzZSBsaW50IGFuZCBldmFkZSBjb21wcmVzc2lvblxuXHRhbGxUeXBlcyA9IFwiKi9cIi5jb25jYXQoIFwiKlwiICksXG5cblx0Ly8gRG9jdW1lbnQgbG9jYXRpb25cblx0YWpheExvY2F0aW9uID0gd2luZG93LmxvY2F0aW9uLmhyZWYsXG5cblx0Ly8gU2VnbWVudCBsb2NhdGlvbiBpbnRvIHBhcnRzXG5cdGFqYXhMb2NQYXJ0cyA9IHJ1cmwuZXhlYyggYWpheExvY2F0aW9uLnRvTG93ZXJDYXNlKCkgKSB8fCBbXTtcblxuLy8gQmFzZSBcImNvbnN0cnVjdG9yXCIgZm9yIGpRdWVyeS5hamF4UHJlZmlsdGVyIGFuZCBqUXVlcnkuYWpheFRyYW5zcG9ydFxuZnVuY3Rpb24gYWRkVG9QcmVmaWx0ZXJzT3JUcmFuc3BvcnRzKCBzdHJ1Y3R1cmUgKSB7XG5cblx0Ly8gZGF0YVR5cGVFeHByZXNzaW9uIGlzIG9wdGlvbmFsIGFuZCBkZWZhdWx0cyB0byBcIipcIlxuXHRyZXR1cm4gZnVuY3Rpb24oIGRhdGFUeXBlRXhwcmVzc2lvbiwgZnVuYyApIHtcblxuXHRcdGlmICggdHlwZW9mIGRhdGFUeXBlRXhwcmVzc2lvbiAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdGZ1bmMgPSBkYXRhVHlwZUV4cHJlc3Npb247XG5cdFx0XHRkYXRhVHlwZUV4cHJlc3Npb24gPSBcIipcIjtcblx0XHR9XG5cblx0XHR2YXIgZGF0YVR5cGUsXG5cdFx0XHRpID0gMCxcblx0XHRcdGRhdGFUeXBlcyA9IGRhdGFUeXBlRXhwcmVzc2lvbi50b0xvd2VyQ2FzZSgpLm1hdGNoKCBybm90d2hpdGUgKSB8fCBbXTtcblxuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIGZ1bmMgKSApIHtcblx0XHRcdC8vIEZvciBlYWNoIGRhdGFUeXBlIGluIHRoZSBkYXRhVHlwZUV4cHJlc3Npb25cblx0XHRcdHdoaWxlICggKGRhdGFUeXBlID0gZGF0YVR5cGVzW2krK10pICkge1xuXHRcdFx0XHQvLyBQcmVwZW5kIGlmIHJlcXVlc3RlZFxuXHRcdFx0XHRpZiAoIGRhdGFUeXBlWzBdID09PSBcIitcIiApIHtcblx0XHRcdFx0XHRkYXRhVHlwZSA9IGRhdGFUeXBlLnNsaWNlKCAxICkgfHwgXCIqXCI7XG5cdFx0XHRcdFx0KHN0cnVjdHVyZVsgZGF0YVR5cGUgXSA9IHN0cnVjdHVyZVsgZGF0YVR5cGUgXSB8fCBbXSkudW5zaGlmdCggZnVuYyApO1xuXG5cdFx0XHRcdC8vIE90aGVyd2lzZSBhcHBlbmRcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHQoc3RydWN0dXJlWyBkYXRhVHlwZSBdID0gc3RydWN0dXJlWyBkYXRhVHlwZSBdIHx8IFtdKS5wdXNoKCBmdW5jICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH07XG59XG5cbi8vIEJhc2UgaW5zcGVjdGlvbiBmdW5jdGlvbiBmb3IgcHJlZmlsdGVycyBhbmQgdHJhbnNwb3J0c1xuZnVuY3Rpb24gaW5zcGVjdFByZWZpbHRlcnNPclRyYW5zcG9ydHMoIHN0cnVjdHVyZSwgb3B0aW9ucywgb3JpZ2luYWxPcHRpb25zLCBqcVhIUiApIHtcblxuXHR2YXIgaW5zcGVjdGVkID0ge30sXG5cdFx0c2Vla2luZ1RyYW5zcG9ydCA9ICggc3RydWN0dXJlID09PSB0cmFuc3BvcnRzICk7XG5cblx0ZnVuY3Rpb24gaW5zcGVjdCggZGF0YVR5cGUgKSB7XG5cdFx0dmFyIHNlbGVjdGVkO1xuXHRcdGluc3BlY3RlZFsgZGF0YVR5cGUgXSA9IHRydWU7XG5cdFx0alF1ZXJ5LmVhY2goIHN0cnVjdHVyZVsgZGF0YVR5cGUgXSB8fCBbXSwgZnVuY3Rpb24oIF8sIHByZWZpbHRlck9yRmFjdG9yeSApIHtcblx0XHRcdHZhciBkYXRhVHlwZU9yVHJhbnNwb3J0ID0gcHJlZmlsdGVyT3JGYWN0b3J5KCBvcHRpb25zLCBvcmlnaW5hbE9wdGlvbnMsIGpxWEhSICk7XG5cdFx0XHRpZiAoIHR5cGVvZiBkYXRhVHlwZU9yVHJhbnNwb3J0ID09PSBcInN0cmluZ1wiICYmICFzZWVraW5nVHJhbnNwb3J0ICYmICFpbnNwZWN0ZWRbIGRhdGFUeXBlT3JUcmFuc3BvcnQgXSApIHtcblx0XHRcdFx0b3B0aW9ucy5kYXRhVHlwZXMudW5zaGlmdCggZGF0YVR5cGVPclRyYW5zcG9ydCApO1xuXHRcdFx0XHRpbnNwZWN0KCBkYXRhVHlwZU9yVHJhbnNwb3J0ICk7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH0gZWxzZSBpZiAoIHNlZWtpbmdUcmFuc3BvcnQgKSB7XG5cdFx0XHRcdHJldHVybiAhKCBzZWxlY3RlZCA9IGRhdGFUeXBlT3JUcmFuc3BvcnQgKTtcblx0XHRcdH1cblx0XHR9KTtcblx0XHRyZXR1cm4gc2VsZWN0ZWQ7XG5cdH1cblxuXHRyZXR1cm4gaW5zcGVjdCggb3B0aW9ucy5kYXRhVHlwZXNbIDAgXSApIHx8ICFpbnNwZWN0ZWRbIFwiKlwiIF0gJiYgaW5zcGVjdCggXCIqXCIgKTtcbn1cblxuLy8gQSBzcGVjaWFsIGV4dGVuZCBmb3IgYWpheCBvcHRpb25zXG4vLyB0aGF0IHRha2VzIFwiZmxhdFwiIG9wdGlvbnMgKG5vdCB0byBiZSBkZWVwIGV4dGVuZGVkKVxuLy8gRml4ZXMgIzk4ODdcbmZ1bmN0aW9uIGFqYXhFeHRlbmQoIHRhcmdldCwgc3JjICkge1xuXHR2YXIga2V5LCBkZWVwLFxuXHRcdGZsYXRPcHRpb25zID0galF1ZXJ5LmFqYXhTZXR0aW5ncy5mbGF0T3B0aW9ucyB8fCB7fTtcblxuXHRmb3IgKCBrZXkgaW4gc3JjICkge1xuXHRcdGlmICggc3JjWyBrZXkgXSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0KCBmbGF0T3B0aW9uc1sga2V5IF0gPyB0YXJnZXQgOiAoIGRlZXAgfHwgKGRlZXAgPSB7fSkgKSApWyBrZXkgXSA9IHNyY1sga2V5IF07XG5cdFx0fVxuXHR9XG5cdGlmICggZGVlcCApIHtcblx0XHRqUXVlcnkuZXh0ZW5kKCB0cnVlLCB0YXJnZXQsIGRlZXAgKTtcblx0fVxuXG5cdHJldHVybiB0YXJnZXQ7XG59XG5cbi8qIEhhbmRsZXMgcmVzcG9uc2VzIHRvIGFuIGFqYXggcmVxdWVzdDpcbiAqIC0gZmluZHMgdGhlIHJpZ2h0IGRhdGFUeXBlIChtZWRpYXRlcyBiZXR3ZWVuIGNvbnRlbnQtdHlwZSBhbmQgZXhwZWN0ZWQgZGF0YVR5cGUpXG4gKiAtIHJldHVybnMgdGhlIGNvcnJlc3BvbmRpbmcgcmVzcG9uc2VcbiAqL1xuZnVuY3Rpb24gYWpheEhhbmRsZVJlc3BvbnNlcyggcywganFYSFIsIHJlc3BvbnNlcyApIHtcblxuXHR2YXIgY3QsIHR5cGUsIGZpbmFsRGF0YVR5cGUsIGZpcnN0RGF0YVR5cGUsXG5cdFx0Y29udGVudHMgPSBzLmNvbnRlbnRzLFxuXHRcdGRhdGFUeXBlcyA9IHMuZGF0YVR5cGVzO1xuXG5cdC8vIFJlbW92ZSBhdXRvIGRhdGFUeXBlIGFuZCBnZXQgY29udGVudC10eXBlIGluIHRoZSBwcm9jZXNzXG5cdHdoaWxlICggZGF0YVR5cGVzWyAwIF0gPT09IFwiKlwiICkge1xuXHRcdGRhdGFUeXBlcy5zaGlmdCgpO1xuXHRcdGlmICggY3QgPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdGN0ID0gcy5taW1lVHlwZSB8fCBqcVhIUi5nZXRSZXNwb25zZUhlYWRlcihcIkNvbnRlbnQtVHlwZVwiKTtcblx0XHR9XG5cdH1cblxuXHQvLyBDaGVjayBpZiB3ZSdyZSBkZWFsaW5nIHdpdGggYSBrbm93biBjb250ZW50LXR5cGVcblx0aWYgKCBjdCApIHtcblx0XHRmb3IgKCB0eXBlIGluIGNvbnRlbnRzICkge1xuXHRcdFx0aWYgKCBjb250ZW50c1sgdHlwZSBdICYmIGNvbnRlbnRzWyB0eXBlIF0udGVzdCggY3QgKSApIHtcblx0XHRcdFx0ZGF0YVR5cGVzLnVuc2hpZnQoIHR5cGUgKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gQ2hlY2sgdG8gc2VlIGlmIHdlIGhhdmUgYSByZXNwb25zZSBmb3IgdGhlIGV4cGVjdGVkIGRhdGFUeXBlXG5cdGlmICggZGF0YVR5cGVzWyAwIF0gaW4gcmVzcG9uc2VzICkge1xuXHRcdGZpbmFsRGF0YVR5cGUgPSBkYXRhVHlwZXNbIDAgXTtcblx0fSBlbHNlIHtcblx0XHQvLyBUcnkgY29udmVydGlibGUgZGF0YVR5cGVzXG5cdFx0Zm9yICggdHlwZSBpbiByZXNwb25zZXMgKSB7XG5cdFx0XHRpZiAoICFkYXRhVHlwZXNbIDAgXSB8fCBzLmNvbnZlcnRlcnNbIHR5cGUgKyBcIiBcIiArIGRhdGFUeXBlc1swXSBdICkge1xuXHRcdFx0XHRmaW5hbERhdGFUeXBlID0gdHlwZTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0XHRpZiAoICFmaXJzdERhdGFUeXBlICkge1xuXHRcdFx0XHRmaXJzdERhdGFUeXBlID0gdHlwZTtcblx0XHRcdH1cblx0XHR9XG5cdFx0Ly8gT3IganVzdCB1c2UgZmlyc3Qgb25lXG5cdFx0ZmluYWxEYXRhVHlwZSA9IGZpbmFsRGF0YVR5cGUgfHwgZmlyc3REYXRhVHlwZTtcblx0fVxuXG5cdC8vIElmIHdlIGZvdW5kIGEgZGF0YVR5cGVcblx0Ly8gV2UgYWRkIHRoZSBkYXRhVHlwZSB0byB0aGUgbGlzdCBpZiBuZWVkZWRcblx0Ly8gYW5kIHJldHVybiB0aGUgY29ycmVzcG9uZGluZyByZXNwb25zZVxuXHRpZiAoIGZpbmFsRGF0YVR5cGUgKSB7XG5cdFx0aWYgKCBmaW5hbERhdGFUeXBlICE9PSBkYXRhVHlwZXNbIDAgXSApIHtcblx0XHRcdGRhdGFUeXBlcy51bnNoaWZ0KCBmaW5hbERhdGFUeXBlICk7XG5cdFx0fVxuXHRcdHJldHVybiByZXNwb25zZXNbIGZpbmFsRGF0YVR5cGUgXTtcblx0fVxufVxuXG4vKiBDaGFpbiBjb252ZXJzaW9ucyBnaXZlbiB0aGUgcmVxdWVzdCBhbmQgdGhlIG9yaWdpbmFsIHJlc3BvbnNlXG4gKiBBbHNvIHNldHMgdGhlIHJlc3BvbnNlWFhYIGZpZWxkcyBvbiB0aGUganFYSFIgaW5zdGFuY2VcbiAqL1xuZnVuY3Rpb24gYWpheENvbnZlcnQoIHMsIHJlc3BvbnNlLCBqcVhIUiwgaXNTdWNjZXNzICkge1xuXHR2YXIgY29udjIsIGN1cnJlbnQsIGNvbnYsIHRtcCwgcHJldixcblx0XHRjb252ZXJ0ZXJzID0ge30sXG5cdFx0Ly8gV29yayB3aXRoIGEgY29weSBvZiBkYXRhVHlwZXMgaW4gY2FzZSB3ZSBuZWVkIHRvIG1vZGlmeSBpdCBmb3IgY29udmVyc2lvblxuXHRcdGRhdGFUeXBlcyA9IHMuZGF0YVR5cGVzLnNsaWNlKCk7XG5cblx0Ly8gQ3JlYXRlIGNvbnZlcnRlcnMgbWFwIHdpdGggbG93ZXJjYXNlZCBrZXlzXG5cdGlmICggZGF0YVR5cGVzWyAxIF0gKSB7XG5cdFx0Zm9yICggY29udiBpbiBzLmNvbnZlcnRlcnMgKSB7XG5cdFx0XHRjb252ZXJ0ZXJzWyBjb252LnRvTG93ZXJDYXNlKCkgXSA9IHMuY29udmVydGVyc1sgY29udiBdO1xuXHRcdH1cblx0fVxuXG5cdGN1cnJlbnQgPSBkYXRhVHlwZXMuc2hpZnQoKTtcblxuXHQvLyBDb252ZXJ0IHRvIGVhY2ggc2VxdWVudGlhbCBkYXRhVHlwZVxuXHR3aGlsZSAoIGN1cnJlbnQgKSB7XG5cblx0XHRpZiAoIHMucmVzcG9uc2VGaWVsZHNbIGN1cnJlbnQgXSApIHtcblx0XHRcdGpxWEhSWyBzLnJlc3BvbnNlRmllbGRzWyBjdXJyZW50IF0gXSA9IHJlc3BvbnNlO1xuXHRcdH1cblxuXHRcdC8vIEFwcGx5IHRoZSBkYXRhRmlsdGVyIGlmIHByb3ZpZGVkXG5cdFx0aWYgKCAhcHJldiAmJiBpc1N1Y2Nlc3MgJiYgcy5kYXRhRmlsdGVyICkge1xuXHRcdFx0cmVzcG9uc2UgPSBzLmRhdGFGaWx0ZXIoIHJlc3BvbnNlLCBzLmRhdGFUeXBlICk7XG5cdFx0fVxuXG5cdFx0cHJldiA9IGN1cnJlbnQ7XG5cdFx0Y3VycmVudCA9IGRhdGFUeXBlcy5zaGlmdCgpO1xuXG5cdFx0aWYgKCBjdXJyZW50ICkge1xuXG5cdFx0Ly8gVGhlcmUncyBvbmx5IHdvcmsgdG8gZG8gaWYgY3VycmVudCBkYXRhVHlwZSBpcyBub24tYXV0b1xuXHRcdFx0aWYgKCBjdXJyZW50ID09PSBcIipcIiApIHtcblxuXHRcdFx0XHRjdXJyZW50ID0gcHJldjtcblxuXHRcdFx0Ly8gQ29udmVydCByZXNwb25zZSBpZiBwcmV2IGRhdGFUeXBlIGlzIG5vbi1hdXRvIGFuZCBkaWZmZXJzIGZyb20gY3VycmVudFxuXHRcdFx0fSBlbHNlIGlmICggcHJldiAhPT0gXCIqXCIgJiYgcHJldiAhPT0gY3VycmVudCApIHtcblxuXHRcdFx0XHQvLyBTZWVrIGEgZGlyZWN0IGNvbnZlcnRlclxuXHRcdFx0XHRjb252ID0gY29udmVydGVyc1sgcHJldiArIFwiIFwiICsgY3VycmVudCBdIHx8IGNvbnZlcnRlcnNbIFwiKiBcIiArIGN1cnJlbnQgXTtcblxuXHRcdFx0XHQvLyBJZiBub25lIGZvdW5kLCBzZWVrIGEgcGFpclxuXHRcdFx0XHRpZiAoICFjb252ICkge1xuXHRcdFx0XHRcdGZvciAoIGNvbnYyIGluIGNvbnZlcnRlcnMgKSB7XG5cblx0XHRcdFx0XHRcdC8vIElmIGNvbnYyIG91dHB1dHMgY3VycmVudFxuXHRcdFx0XHRcdFx0dG1wID0gY29udjIuc3BsaXQoIFwiIFwiICk7XG5cdFx0XHRcdFx0XHRpZiAoIHRtcFsgMSBdID09PSBjdXJyZW50ICkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIElmIHByZXYgY2FuIGJlIGNvbnZlcnRlZCB0byBhY2NlcHRlZCBpbnB1dFxuXHRcdFx0XHRcdFx0XHRjb252ID0gY29udmVydGVyc1sgcHJldiArIFwiIFwiICsgdG1wWyAwIF0gXSB8fFxuXHRcdFx0XHRcdFx0XHRcdGNvbnZlcnRlcnNbIFwiKiBcIiArIHRtcFsgMCBdIF07XG5cdFx0XHRcdFx0XHRcdGlmICggY29udiApIHtcblx0XHRcdFx0XHRcdFx0XHQvLyBDb25kZW5zZSBlcXVpdmFsZW5jZSBjb252ZXJ0ZXJzXG5cdFx0XHRcdFx0XHRcdFx0aWYgKCBjb252ID09PSB0cnVlICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0Y29udiA9IGNvbnZlcnRlcnNbIGNvbnYyIF07XG5cblx0XHRcdFx0XHRcdFx0XHQvLyBPdGhlcndpc2UsIGluc2VydCB0aGUgaW50ZXJtZWRpYXRlIGRhdGFUeXBlXG5cdFx0XHRcdFx0XHRcdFx0fSBlbHNlIGlmICggY29udmVydGVyc1sgY29udjIgXSAhPT0gdHJ1ZSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdGN1cnJlbnQgPSB0bXBbIDAgXTtcblx0XHRcdFx0XHRcdFx0XHRcdGRhdGFUeXBlcy51bnNoaWZ0KCB0bXBbIDEgXSApO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEFwcGx5IGNvbnZlcnRlciAoaWYgbm90IGFuIGVxdWl2YWxlbmNlKVxuXHRcdFx0XHRpZiAoIGNvbnYgIT09IHRydWUgKSB7XG5cblx0XHRcdFx0XHQvLyBVbmxlc3MgZXJyb3JzIGFyZSBhbGxvd2VkIHRvIGJ1YmJsZSwgY2F0Y2ggYW5kIHJldHVybiB0aGVtXG5cdFx0XHRcdFx0aWYgKCBjb252ICYmIHNbIFwidGhyb3dzXCIgXSApIHtcblx0XHRcdFx0XHRcdHJlc3BvbnNlID0gY29udiggcmVzcG9uc2UgKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRcdFx0cmVzcG9uc2UgPSBjb252KCByZXNwb25zZSApO1xuXHRcdFx0XHRcdFx0fSBjYXRjaCAoIGUgKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiB7IHN0YXRlOiBcInBhcnNlcmVycm9yXCIsIGVycm9yOiBjb252ID8gZSA6IFwiTm8gY29udmVyc2lvbiBmcm9tIFwiICsgcHJldiArIFwiIHRvIFwiICsgY3VycmVudCB9O1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiB7IHN0YXRlOiBcInN1Y2Nlc3NcIiwgZGF0YTogcmVzcG9uc2UgfTtcbn1cblxualF1ZXJ5LmV4dGVuZCh7XG5cblx0Ly8gQ291bnRlciBmb3IgaG9sZGluZyB0aGUgbnVtYmVyIG9mIGFjdGl2ZSBxdWVyaWVzXG5cdGFjdGl2ZTogMCxcblxuXHQvLyBMYXN0LU1vZGlmaWVkIGhlYWRlciBjYWNoZSBmb3IgbmV4dCByZXF1ZXN0XG5cdGxhc3RNb2RpZmllZDoge30sXG5cdGV0YWc6IHt9LFxuXG5cdGFqYXhTZXR0aW5nczoge1xuXHRcdHVybDogYWpheExvY2F0aW9uLFxuXHRcdHR5cGU6IFwiR0VUXCIsXG5cdFx0aXNMb2NhbDogcmxvY2FsUHJvdG9jb2wudGVzdCggYWpheExvY1BhcnRzWyAxIF0gKSxcblx0XHRnbG9iYWw6IHRydWUsXG5cdFx0cHJvY2Vzc0RhdGE6IHRydWUsXG5cdFx0YXN5bmM6IHRydWUsXG5cdFx0Y29udGVudFR5cGU6IFwiYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkOyBjaGFyc2V0PVVURi04XCIsXG5cdFx0Lypcblx0XHR0aW1lb3V0OiAwLFxuXHRcdGRhdGE6IG51bGwsXG5cdFx0ZGF0YVR5cGU6IG51bGwsXG5cdFx0dXNlcm5hbWU6IG51bGwsXG5cdFx0cGFzc3dvcmQ6IG51bGwsXG5cdFx0Y2FjaGU6IG51bGwsXG5cdFx0dGhyb3dzOiBmYWxzZSxcblx0XHR0cmFkaXRpb25hbDogZmFsc2UsXG5cdFx0aGVhZGVyczoge30sXG5cdFx0Ki9cblxuXHRcdGFjY2VwdHM6IHtcblx0XHRcdFwiKlwiOiBhbGxUeXBlcyxcblx0XHRcdHRleHQ6IFwidGV4dC9wbGFpblwiLFxuXHRcdFx0aHRtbDogXCJ0ZXh0L2h0bWxcIixcblx0XHRcdHhtbDogXCJhcHBsaWNhdGlvbi94bWwsIHRleHQveG1sXCIsXG5cdFx0XHRqc29uOiBcImFwcGxpY2F0aW9uL2pzb24sIHRleHQvamF2YXNjcmlwdFwiXG5cdFx0fSxcblxuXHRcdGNvbnRlbnRzOiB7XG5cdFx0XHR4bWw6IC94bWwvLFxuXHRcdFx0aHRtbDogL2h0bWwvLFxuXHRcdFx0anNvbjogL2pzb24vXG5cdFx0fSxcblxuXHRcdHJlc3BvbnNlRmllbGRzOiB7XG5cdFx0XHR4bWw6IFwicmVzcG9uc2VYTUxcIixcblx0XHRcdHRleHQ6IFwicmVzcG9uc2VUZXh0XCIsXG5cdFx0XHRqc29uOiBcInJlc3BvbnNlSlNPTlwiXG5cdFx0fSxcblxuXHRcdC8vIERhdGEgY29udmVydGVyc1xuXHRcdC8vIEtleXMgc2VwYXJhdGUgc291cmNlIChvciBjYXRjaGFsbCBcIipcIikgYW5kIGRlc3RpbmF0aW9uIHR5cGVzIHdpdGggYSBzaW5nbGUgc3BhY2Vcblx0XHRjb252ZXJ0ZXJzOiB7XG5cblx0XHRcdC8vIENvbnZlcnQgYW55dGhpbmcgdG8gdGV4dFxuXHRcdFx0XCIqIHRleHRcIjogU3RyaW5nLFxuXG5cdFx0XHQvLyBUZXh0IHRvIGh0bWwgKHRydWUgPSBubyB0cmFuc2Zvcm1hdGlvbilcblx0XHRcdFwidGV4dCBodG1sXCI6IHRydWUsXG5cblx0XHRcdC8vIEV2YWx1YXRlIHRleHQgYXMgYSBqc29uIGV4cHJlc3Npb25cblx0XHRcdFwidGV4dCBqc29uXCI6IGpRdWVyeS5wYXJzZUpTT04sXG5cblx0XHRcdC8vIFBhcnNlIHRleHQgYXMgeG1sXG5cdFx0XHRcInRleHQgeG1sXCI6IGpRdWVyeS5wYXJzZVhNTFxuXHRcdH0sXG5cblx0XHQvLyBGb3Igb3B0aW9ucyB0aGF0IHNob3VsZG4ndCBiZSBkZWVwIGV4dGVuZGVkOlxuXHRcdC8vIHlvdSBjYW4gYWRkIHlvdXIgb3duIGN1c3RvbSBvcHRpb25zIGhlcmUgaWZcblx0XHQvLyBhbmQgd2hlbiB5b3UgY3JlYXRlIG9uZSB0aGF0IHNob3VsZG4ndCBiZVxuXHRcdC8vIGRlZXAgZXh0ZW5kZWQgKHNlZSBhamF4RXh0ZW5kKVxuXHRcdGZsYXRPcHRpb25zOiB7XG5cdFx0XHR1cmw6IHRydWUsXG5cdFx0XHRjb250ZXh0OiB0cnVlXG5cdFx0fVxuXHR9LFxuXG5cdC8vIENyZWF0ZXMgYSBmdWxsIGZsZWRnZWQgc2V0dGluZ3Mgb2JqZWN0IGludG8gdGFyZ2V0XG5cdC8vIHdpdGggYm90aCBhamF4U2V0dGluZ3MgYW5kIHNldHRpbmdzIGZpZWxkcy5cblx0Ly8gSWYgdGFyZ2V0IGlzIG9taXR0ZWQsIHdyaXRlcyBpbnRvIGFqYXhTZXR0aW5ncy5cblx0YWpheFNldHVwOiBmdW5jdGlvbiggdGFyZ2V0LCBzZXR0aW5ncyApIHtcblx0XHRyZXR1cm4gc2V0dGluZ3MgP1xuXG5cdFx0XHQvLyBCdWlsZGluZyBhIHNldHRpbmdzIG9iamVjdFxuXHRcdFx0YWpheEV4dGVuZCggYWpheEV4dGVuZCggdGFyZ2V0LCBqUXVlcnkuYWpheFNldHRpbmdzICksIHNldHRpbmdzICkgOlxuXG5cdFx0XHQvLyBFeHRlbmRpbmcgYWpheFNldHRpbmdzXG5cdFx0XHRhamF4RXh0ZW5kKCBqUXVlcnkuYWpheFNldHRpbmdzLCB0YXJnZXQgKTtcblx0fSxcblxuXHRhamF4UHJlZmlsdGVyOiBhZGRUb1ByZWZpbHRlcnNPclRyYW5zcG9ydHMoIHByZWZpbHRlcnMgKSxcblx0YWpheFRyYW5zcG9ydDogYWRkVG9QcmVmaWx0ZXJzT3JUcmFuc3BvcnRzKCB0cmFuc3BvcnRzICksXG5cblx0Ly8gTWFpbiBtZXRob2Rcblx0YWpheDogZnVuY3Rpb24oIHVybCwgb3B0aW9ucyApIHtcblxuXHRcdC8vIElmIHVybCBpcyBhbiBvYmplY3QsIHNpbXVsYXRlIHByZS0xLjUgc2lnbmF0dXJlXG5cdFx0aWYgKCB0eXBlb2YgdXJsID09PSBcIm9iamVjdFwiICkge1xuXHRcdFx0b3B0aW9ucyA9IHVybDtcblx0XHRcdHVybCA9IHVuZGVmaW5lZDtcblx0XHR9XG5cblx0XHQvLyBGb3JjZSBvcHRpb25zIHRvIGJlIGFuIG9iamVjdFxuXHRcdG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG5cdFx0dmFyIHRyYW5zcG9ydCxcblx0XHRcdC8vIFVSTCB3aXRob3V0IGFudGktY2FjaGUgcGFyYW1cblx0XHRcdGNhY2hlVVJMLFxuXHRcdFx0Ly8gUmVzcG9uc2UgaGVhZGVyc1xuXHRcdFx0cmVzcG9uc2VIZWFkZXJzU3RyaW5nLFxuXHRcdFx0cmVzcG9uc2VIZWFkZXJzLFxuXHRcdFx0Ly8gdGltZW91dCBoYW5kbGVcblx0XHRcdHRpbWVvdXRUaW1lcixcblx0XHRcdC8vIENyb3NzLWRvbWFpbiBkZXRlY3Rpb24gdmFyc1xuXHRcdFx0cGFydHMsXG5cdFx0XHQvLyBUbyBrbm93IGlmIGdsb2JhbCBldmVudHMgYXJlIHRvIGJlIGRpc3BhdGNoZWRcblx0XHRcdGZpcmVHbG9iYWxzLFxuXHRcdFx0Ly8gTG9vcCB2YXJpYWJsZVxuXHRcdFx0aSxcblx0XHRcdC8vIENyZWF0ZSB0aGUgZmluYWwgb3B0aW9ucyBvYmplY3Rcblx0XHRcdHMgPSBqUXVlcnkuYWpheFNldHVwKCB7fSwgb3B0aW9ucyApLFxuXHRcdFx0Ly8gQ2FsbGJhY2tzIGNvbnRleHRcblx0XHRcdGNhbGxiYWNrQ29udGV4dCA9IHMuY29udGV4dCB8fCBzLFxuXHRcdFx0Ly8gQ29udGV4dCBmb3IgZ2xvYmFsIGV2ZW50cyBpcyBjYWxsYmFja0NvbnRleHQgaWYgaXQgaXMgYSBET00gbm9kZSBvciBqUXVlcnkgY29sbGVjdGlvblxuXHRcdFx0Z2xvYmFsRXZlbnRDb250ZXh0ID0gcy5jb250ZXh0ICYmICggY2FsbGJhY2tDb250ZXh0Lm5vZGVUeXBlIHx8IGNhbGxiYWNrQ29udGV4dC5qcXVlcnkgKSA/XG5cdFx0XHRcdGpRdWVyeSggY2FsbGJhY2tDb250ZXh0ICkgOlxuXHRcdFx0XHRqUXVlcnkuZXZlbnQsXG5cdFx0XHQvLyBEZWZlcnJlZHNcblx0XHRcdGRlZmVycmVkID0galF1ZXJ5LkRlZmVycmVkKCksXG5cdFx0XHRjb21wbGV0ZURlZmVycmVkID0galF1ZXJ5LkNhbGxiYWNrcyhcIm9uY2UgbWVtb3J5XCIpLFxuXHRcdFx0Ly8gU3RhdHVzLWRlcGVuZGVudCBjYWxsYmFja3Ncblx0XHRcdHN0YXR1c0NvZGUgPSBzLnN0YXR1c0NvZGUgfHwge30sXG5cdFx0XHQvLyBIZWFkZXJzICh0aGV5IGFyZSBzZW50IGFsbCBhdCBvbmNlKVxuXHRcdFx0cmVxdWVzdEhlYWRlcnMgPSB7fSxcblx0XHRcdHJlcXVlc3RIZWFkZXJzTmFtZXMgPSB7fSxcblx0XHRcdC8vIFRoZSBqcVhIUiBzdGF0ZVxuXHRcdFx0c3RhdGUgPSAwLFxuXHRcdFx0Ly8gRGVmYXVsdCBhYm9ydCBtZXNzYWdlXG5cdFx0XHRzdHJBYm9ydCA9IFwiY2FuY2VsZWRcIixcblx0XHRcdC8vIEZha2UgeGhyXG5cdFx0XHRqcVhIUiA9IHtcblx0XHRcdFx0cmVhZHlTdGF0ZTogMCxcblxuXHRcdFx0XHQvLyBCdWlsZHMgaGVhZGVycyBoYXNodGFibGUgaWYgbmVlZGVkXG5cdFx0XHRcdGdldFJlc3BvbnNlSGVhZGVyOiBmdW5jdGlvbigga2V5ICkge1xuXHRcdFx0XHRcdHZhciBtYXRjaDtcblx0XHRcdFx0XHRpZiAoIHN0YXRlID09PSAyICkge1xuXHRcdFx0XHRcdFx0aWYgKCAhcmVzcG9uc2VIZWFkZXJzICkge1xuXHRcdFx0XHRcdFx0XHRyZXNwb25zZUhlYWRlcnMgPSB7fTtcblx0XHRcdFx0XHRcdFx0d2hpbGUgKCAobWF0Y2ggPSByaGVhZGVycy5leGVjKCByZXNwb25zZUhlYWRlcnNTdHJpbmcgKSkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0cmVzcG9uc2VIZWFkZXJzWyBtYXRjaFsxXS50b0xvd2VyQ2FzZSgpIF0gPSBtYXRjaFsgMiBdO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRtYXRjaCA9IHJlc3BvbnNlSGVhZGVyc1sga2V5LnRvTG93ZXJDYXNlKCkgXTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIG1hdGNoID09IG51bGwgPyBudWxsIDogbWF0Y2g7XG5cdFx0XHRcdH0sXG5cblx0XHRcdFx0Ly8gUmF3IHN0cmluZ1xuXHRcdFx0XHRnZXRBbGxSZXNwb25zZUhlYWRlcnM6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdHJldHVybiBzdGF0ZSA9PT0gMiA/IHJlc3BvbnNlSGVhZGVyc1N0cmluZyA6IG51bGw7XG5cdFx0XHRcdH0sXG5cblx0XHRcdFx0Ly8gQ2FjaGVzIHRoZSBoZWFkZXJcblx0XHRcdFx0c2V0UmVxdWVzdEhlYWRlcjogZnVuY3Rpb24oIG5hbWUsIHZhbHVlICkge1xuXHRcdFx0XHRcdHZhciBsbmFtZSA9IG5hbWUudG9Mb3dlckNhc2UoKTtcblx0XHRcdFx0XHRpZiAoICFzdGF0ZSApIHtcblx0XHRcdFx0XHRcdG5hbWUgPSByZXF1ZXN0SGVhZGVyc05hbWVzWyBsbmFtZSBdID0gcmVxdWVzdEhlYWRlcnNOYW1lc1sgbG5hbWUgXSB8fCBuYW1lO1xuXHRcdFx0XHRcdFx0cmVxdWVzdEhlYWRlcnNbIG5hbWUgXSA9IHZhbHVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdFx0fSxcblxuXHRcdFx0XHQvLyBPdmVycmlkZXMgcmVzcG9uc2UgY29udGVudC10eXBlIGhlYWRlclxuXHRcdFx0XHRvdmVycmlkZU1pbWVUeXBlOiBmdW5jdGlvbiggdHlwZSApIHtcblx0XHRcdFx0XHRpZiAoICFzdGF0ZSApIHtcblx0XHRcdFx0XHRcdHMubWltZVR5cGUgPSB0eXBlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdFx0fSxcblxuXHRcdFx0XHQvLyBTdGF0dXMtZGVwZW5kZW50IGNhbGxiYWNrc1xuXHRcdFx0XHRzdGF0dXNDb2RlOiBmdW5jdGlvbiggbWFwICkge1xuXHRcdFx0XHRcdHZhciBjb2RlO1xuXHRcdFx0XHRcdGlmICggbWFwICkge1xuXHRcdFx0XHRcdFx0aWYgKCBzdGF0ZSA8IDIgKSB7XG5cdFx0XHRcdFx0XHRcdGZvciAoIGNvZGUgaW4gbWFwICkge1xuXHRcdFx0XHRcdFx0XHRcdC8vIExhenktYWRkIHRoZSBuZXcgY2FsbGJhY2sgaW4gYSB3YXkgdGhhdCBwcmVzZXJ2ZXMgb2xkIG9uZXNcblx0XHRcdFx0XHRcdFx0XHRzdGF0dXNDb2RlWyBjb2RlIF0gPSBbIHN0YXR1c0NvZGVbIGNvZGUgXSwgbWFwWyBjb2RlIF0gXTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0Ly8gRXhlY3V0ZSB0aGUgYXBwcm9wcmlhdGUgY2FsbGJhY2tzXG5cdFx0XHRcdFx0XHRcdGpxWEhSLmFsd2F5cyggbWFwWyBqcVhIUi5zdGF0dXMgXSApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdFx0fSxcblxuXHRcdFx0XHQvLyBDYW5jZWwgdGhlIHJlcXVlc3Rcblx0XHRcdFx0YWJvcnQ6IGZ1bmN0aW9uKCBzdGF0dXNUZXh0ICkge1xuXHRcdFx0XHRcdHZhciBmaW5hbFRleHQgPSBzdGF0dXNUZXh0IHx8IHN0ckFib3J0O1xuXHRcdFx0XHRcdGlmICggdHJhbnNwb3J0ICkge1xuXHRcdFx0XHRcdFx0dHJhbnNwb3J0LmFib3J0KCBmaW5hbFRleHQgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0ZG9uZSggMCwgZmluYWxUZXh0ICk7XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cblx0XHQvLyBBdHRhY2ggZGVmZXJyZWRzXG5cdFx0ZGVmZXJyZWQucHJvbWlzZSgganFYSFIgKS5jb21wbGV0ZSA9IGNvbXBsZXRlRGVmZXJyZWQuYWRkO1xuXHRcdGpxWEhSLnN1Y2Nlc3MgPSBqcVhIUi5kb25lO1xuXHRcdGpxWEhSLmVycm9yID0ganFYSFIuZmFpbDtcblxuXHRcdC8vIFJlbW92ZSBoYXNoIGNoYXJhY3RlciAoIzc1MzE6IGFuZCBzdHJpbmcgcHJvbW90aW9uKVxuXHRcdC8vIEFkZCBwcm90b2NvbCBpZiBub3QgcHJvdmlkZWQgKHByZWZpbHRlcnMgbWlnaHQgZXhwZWN0IGl0KVxuXHRcdC8vIEhhbmRsZSBmYWxzeSB1cmwgaW4gdGhlIHNldHRpbmdzIG9iamVjdCAoIzEwMDkzOiBjb25zaXN0ZW5jeSB3aXRoIG9sZCBzaWduYXR1cmUpXG5cdFx0Ly8gV2UgYWxzbyB1c2UgdGhlIHVybCBwYXJhbWV0ZXIgaWYgYXZhaWxhYmxlXG5cdFx0cy51cmwgPSAoICggdXJsIHx8IHMudXJsIHx8IGFqYXhMb2NhdGlvbiApICsgXCJcIiApLnJlcGxhY2UoIHJoYXNoLCBcIlwiIClcblx0XHRcdC5yZXBsYWNlKCBycHJvdG9jb2wsIGFqYXhMb2NQYXJ0c1sgMSBdICsgXCIvL1wiICk7XG5cblx0XHQvLyBBbGlhcyBtZXRob2Qgb3B0aW9uIHRvIHR5cGUgYXMgcGVyIHRpY2tldCAjMTIwMDRcblx0XHRzLnR5cGUgPSBvcHRpb25zLm1ldGhvZCB8fCBvcHRpb25zLnR5cGUgfHwgcy5tZXRob2QgfHwgcy50eXBlO1xuXG5cdFx0Ly8gRXh0cmFjdCBkYXRhVHlwZXMgbGlzdFxuXHRcdHMuZGF0YVR5cGVzID0galF1ZXJ5LnRyaW0oIHMuZGF0YVR5cGUgfHwgXCIqXCIgKS50b0xvd2VyQ2FzZSgpLm1hdGNoKCBybm90d2hpdGUgKSB8fCBbIFwiXCIgXTtcblxuXHRcdC8vIEEgY3Jvc3MtZG9tYWluIHJlcXVlc3QgaXMgaW4gb3JkZXIgd2hlbiB3ZSBoYXZlIGEgcHJvdG9jb2w6aG9zdDpwb3J0IG1pc21hdGNoXG5cdFx0aWYgKCBzLmNyb3NzRG9tYWluID09IG51bGwgKSB7XG5cdFx0XHRwYXJ0cyA9IHJ1cmwuZXhlYyggcy51cmwudG9Mb3dlckNhc2UoKSApO1xuXHRcdFx0cy5jcm9zc0RvbWFpbiA9ICEhKCBwYXJ0cyAmJlxuXHRcdFx0XHQoIHBhcnRzWyAxIF0gIT09IGFqYXhMb2NQYXJ0c1sgMSBdIHx8IHBhcnRzWyAyIF0gIT09IGFqYXhMb2NQYXJ0c1sgMiBdIHx8XG5cdFx0XHRcdFx0KCBwYXJ0c1sgMyBdIHx8ICggcGFydHNbIDEgXSA9PT0gXCJodHRwOlwiID8gXCI4MFwiIDogXCI0NDNcIiApICkgIT09XG5cdFx0XHRcdFx0XHQoIGFqYXhMb2NQYXJ0c1sgMyBdIHx8ICggYWpheExvY1BhcnRzWyAxIF0gPT09IFwiaHR0cDpcIiA/IFwiODBcIiA6IFwiNDQzXCIgKSApIClcblx0XHRcdCk7XG5cdFx0fVxuXG5cdFx0Ly8gQ29udmVydCBkYXRhIGlmIG5vdCBhbHJlYWR5IGEgc3RyaW5nXG5cdFx0aWYgKCBzLmRhdGEgJiYgcy5wcm9jZXNzRGF0YSAmJiB0eXBlb2Ygcy5kYXRhICE9PSBcInN0cmluZ1wiICkge1xuXHRcdFx0cy5kYXRhID0galF1ZXJ5LnBhcmFtKCBzLmRhdGEsIHMudHJhZGl0aW9uYWwgKTtcblx0XHR9XG5cblx0XHQvLyBBcHBseSBwcmVmaWx0ZXJzXG5cdFx0aW5zcGVjdFByZWZpbHRlcnNPclRyYW5zcG9ydHMoIHByZWZpbHRlcnMsIHMsIG9wdGlvbnMsIGpxWEhSICk7XG5cblx0XHQvLyBJZiByZXF1ZXN0IHdhcyBhYm9ydGVkIGluc2lkZSBhIHByZWZpbHRlciwgc3RvcCB0aGVyZVxuXHRcdGlmICggc3RhdGUgPT09IDIgKSB7XG5cdFx0XHRyZXR1cm4ganFYSFI7XG5cdFx0fVxuXG5cdFx0Ly8gV2UgY2FuIGZpcmUgZ2xvYmFsIGV2ZW50cyBhcyBvZiBub3cgaWYgYXNrZWQgdG9cblx0XHQvLyBEb24ndCBmaXJlIGV2ZW50cyBpZiBqUXVlcnkuZXZlbnQgaXMgdW5kZWZpbmVkIGluIGFuIEFNRC11c2FnZSBzY2VuYXJpbyAoIzE1MTE4KVxuXHRcdGZpcmVHbG9iYWxzID0galF1ZXJ5LmV2ZW50ICYmIHMuZ2xvYmFsO1xuXG5cdFx0Ly8gV2F0Y2ggZm9yIGEgbmV3IHNldCBvZiByZXF1ZXN0c1xuXHRcdGlmICggZmlyZUdsb2JhbHMgJiYgalF1ZXJ5LmFjdGl2ZSsrID09PSAwICkge1xuXHRcdFx0alF1ZXJ5LmV2ZW50LnRyaWdnZXIoXCJhamF4U3RhcnRcIik7XG5cdFx0fVxuXG5cdFx0Ly8gVXBwZXJjYXNlIHRoZSB0eXBlXG5cdFx0cy50eXBlID0gcy50eXBlLnRvVXBwZXJDYXNlKCk7XG5cblx0XHQvLyBEZXRlcm1pbmUgaWYgcmVxdWVzdCBoYXMgY29udGVudFxuXHRcdHMuaGFzQ29udGVudCA9ICFybm9Db250ZW50LnRlc3QoIHMudHlwZSApO1xuXG5cdFx0Ly8gU2F2ZSB0aGUgVVJMIGluIGNhc2Ugd2UncmUgdG95aW5nIHdpdGggdGhlIElmLU1vZGlmaWVkLVNpbmNlXG5cdFx0Ly8gYW5kL29yIElmLU5vbmUtTWF0Y2ggaGVhZGVyIGxhdGVyIG9uXG5cdFx0Y2FjaGVVUkwgPSBzLnVybDtcblxuXHRcdC8vIE1vcmUgb3B0aW9ucyBoYW5kbGluZyBmb3IgcmVxdWVzdHMgd2l0aCBubyBjb250ZW50XG5cdFx0aWYgKCAhcy5oYXNDb250ZW50ICkge1xuXG5cdFx0XHQvLyBJZiBkYXRhIGlzIGF2YWlsYWJsZSwgYXBwZW5kIGRhdGEgdG8gdXJsXG5cdFx0XHRpZiAoIHMuZGF0YSApIHtcblx0XHRcdFx0Y2FjaGVVUkwgPSAoIHMudXJsICs9ICggcnF1ZXJ5LnRlc3QoIGNhY2hlVVJMICkgPyBcIiZcIiA6IFwiP1wiICkgKyBzLmRhdGEgKTtcblx0XHRcdFx0Ly8gIzk2ODI6IHJlbW92ZSBkYXRhIHNvIHRoYXQgaXQncyBub3QgdXNlZCBpbiBhbiBldmVudHVhbCByZXRyeVxuXHRcdFx0XHRkZWxldGUgcy5kYXRhO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBBZGQgYW50aS1jYWNoZSBpbiB1cmwgaWYgbmVlZGVkXG5cdFx0XHRpZiAoIHMuY2FjaGUgPT09IGZhbHNlICkge1xuXHRcdFx0XHRzLnVybCA9IHJ0cy50ZXN0KCBjYWNoZVVSTCApID9cblxuXHRcdFx0XHRcdC8vIElmIHRoZXJlIGlzIGFscmVhZHkgYSAnXycgcGFyYW1ldGVyLCBzZXQgaXRzIHZhbHVlXG5cdFx0XHRcdFx0Y2FjaGVVUkwucmVwbGFjZSggcnRzLCBcIiQxXz1cIiArIG5vbmNlKysgKSA6XG5cblx0XHRcdFx0XHQvLyBPdGhlcndpc2UgYWRkIG9uZSB0byB0aGUgZW5kXG5cdFx0XHRcdFx0Y2FjaGVVUkwgKyAoIHJxdWVyeS50ZXN0KCBjYWNoZVVSTCApID8gXCImXCIgOiBcIj9cIiApICsgXCJfPVwiICsgbm9uY2UrKztcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBTZXQgdGhlIElmLU1vZGlmaWVkLVNpbmNlIGFuZC9vciBJZi1Ob25lLU1hdGNoIGhlYWRlciwgaWYgaW4gaWZNb2RpZmllZCBtb2RlLlxuXHRcdGlmICggcy5pZk1vZGlmaWVkICkge1xuXHRcdFx0aWYgKCBqUXVlcnkubGFzdE1vZGlmaWVkWyBjYWNoZVVSTCBdICkge1xuXHRcdFx0XHRqcVhIUi5zZXRSZXF1ZXN0SGVhZGVyKCBcIklmLU1vZGlmaWVkLVNpbmNlXCIsIGpRdWVyeS5sYXN0TW9kaWZpZWRbIGNhY2hlVVJMIF0gKTtcblx0XHRcdH1cblx0XHRcdGlmICggalF1ZXJ5LmV0YWdbIGNhY2hlVVJMIF0gKSB7XG5cdFx0XHRcdGpxWEhSLnNldFJlcXVlc3RIZWFkZXIoIFwiSWYtTm9uZS1NYXRjaFwiLCBqUXVlcnkuZXRhZ1sgY2FjaGVVUkwgXSApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFNldCB0aGUgY29ycmVjdCBoZWFkZXIsIGlmIGRhdGEgaXMgYmVpbmcgc2VudFxuXHRcdGlmICggcy5kYXRhICYmIHMuaGFzQ29udGVudCAmJiBzLmNvbnRlbnRUeXBlICE9PSBmYWxzZSB8fCBvcHRpb25zLmNvbnRlbnRUeXBlICkge1xuXHRcdFx0anFYSFIuc2V0UmVxdWVzdEhlYWRlciggXCJDb250ZW50LVR5cGVcIiwgcy5jb250ZW50VHlwZSApO1xuXHRcdH1cblxuXHRcdC8vIFNldCB0aGUgQWNjZXB0cyBoZWFkZXIgZm9yIHRoZSBzZXJ2ZXIsIGRlcGVuZGluZyBvbiB0aGUgZGF0YVR5cGVcblx0XHRqcVhIUi5zZXRSZXF1ZXN0SGVhZGVyKFxuXHRcdFx0XCJBY2NlcHRcIixcblx0XHRcdHMuZGF0YVR5cGVzWyAwIF0gJiYgcy5hY2NlcHRzWyBzLmRhdGFUeXBlc1swXSBdID9cblx0XHRcdFx0cy5hY2NlcHRzWyBzLmRhdGFUeXBlc1swXSBdICsgKCBzLmRhdGFUeXBlc1sgMCBdICE9PSBcIipcIiA/IFwiLCBcIiArIGFsbFR5cGVzICsgXCI7IHE9MC4wMVwiIDogXCJcIiApIDpcblx0XHRcdFx0cy5hY2NlcHRzWyBcIipcIiBdXG5cdFx0KTtcblxuXHRcdC8vIENoZWNrIGZvciBoZWFkZXJzIG9wdGlvblxuXHRcdGZvciAoIGkgaW4gcy5oZWFkZXJzICkge1xuXHRcdFx0anFYSFIuc2V0UmVxdWVzdEhlYWRlciggaSwgcy5oZWFkZXJzWyBpIF0gKTtcblx0XHR9XG5cblx0XHQvLyBBbGxvdyBjdXN0b20gaGVhZGVycy9taW1ldHlwZXMgYW5kIGVhcmx5IGFib3J0XG5cdFx0aWYgKCBzLmJlZm9yZVNlbmQgJiYgKCBzLmJlZm9yZVNlbmQuY2FsbCggY2FsbGJhY2tDb250ZXh0LCBqcVhIUiwgcyApID09PSBmYWxzZSB8fCBzdGF0ZSA9PT0gMiApICkge1xuXHRcdFx0Ly8gQWJvcnQgaWYgbm90IGRvbmUgYWxyZWFkeSBhbmQgcmV0dXJuXG5cdFx0XHRyZXR1cm4ganFYSFIuYWJvcnQoKTtcblx0XHR9XG5cblx0XHQvLyBBYm9ydGluZyBpcyBubyBsb25nZXIgYSBjYW5jZWxsYXRpb25cblx0XHRzdHJBYm9ydCA9IFwiYWJvcnRcIjtcblxuXHRcdC8vIEluc3RhbGwgY2FsbGJhY2tzIG9uIGRlZmVycmVkc1xuXHRcdGZvciAoIGkgaW4geyBzdWNjZXNzOiAxLCBlcnJvcjogMSwgY29tcGxldGU6IDEgfSApIHtcblx0XHRcdGpxWEhSWyBpIF0oIHNbIGkgXSApO1xuXHRcdH1cblxuXHRcdC8vIEdldCB0cmFuc3BvcnRcblx0XHR0cmFuc3BvcnQgPSBpbnNwZWN0UHJlZmlsdGVyc09yVHJhbnNwb3J0cyggdHJhbnNwb3J0cywgcywgb3B0aW9ucywganFYSFIgKTtcblxuXHRcdC8vIElmIG5vIHRyYW5zcG9ydCwgd2UgYXV0by1hYm9ydFxuXHRcdGlmICggIXRyYW5zcG9ydCApIHtcblx0XHRcdGRvbmUoIC0xLCBcIk5vIFRyYW5zcG9ydFwiICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGpxWEhSLnJlYWR5U3RhdGUgPSAxO1xuXG5cdFx0XHQvLyBTZW5kIGdsb2JhbCBldmVudFxuXHRcdFx0aWYgKCBmaXJlR2xvYmFscyApIHtcblx0XHRcdFx0Z2xvYmFsRXZlbnRDb250ZXh0LnRyaWdnZXIoIFwiYWpheFNlbmRcIiwgWyBqcVhIUiwgcyBdICk7XG5cdFx0XHR9XG5cdFx0XHQvLyBUaW1lb3V0XG5cdFx0XHRpZiAoIHMuYXN5bmMgJiYgcy50aW1lb3V0ID4gMCApIHtcblx0XHRcdFx0dGltZW91dFRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRqcVhIUi5hYm9ydChcInRpbWVvdXRcIik7XG5cdFx0XHRcdH0sIHMudGltZW91dCApO1xuXHRcdFx0fVxuXG5cdFx0XHR0cnkge1xuXHRcdFx0XHRzdGF0ZSA9IDE7XG5cdFx0XHRcdHRyYW5zcG9ydC5zZW5kKCByZXF1ZXN0SGVhZGVycywgZG9uZSApO1xuXHRcdFx0fSBjYXRjaCAoIGUgKSB7XG5cdFx0XHRcdC8vIFByb3BhZ2F0ZSBleGNlcHRpb24gYXMgZXJyb3IgaWYgbm90IGRvbmVcblx0XHRcdFx0aWYgKCBzdGF0ZSA8IDIgKSB7XG5cdFx0XHRcdFx0ZG9uZSggLTEsIGUgKTtcblx0XHRcdFx0Ly8gU2ltcGx5IHJldGhyb3cgb3RoZXJ3aXNlXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0dGhyb3cgZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIENhbGxiYWNrIGZvciB3aGVuIGV2ZXJ5dGhpbmcgaXMgZG9uZVxuXHRcdGZ1bmN0aW9uIGRvbmUoIHN0YXR1cywgbmF0aXZlU3RhdHVzVGV4dCwgcmVzcG9uc2VzLCBoZWFkZXJzICkge1xuXHRcdFx0dmFyIGlzU3VjY2Vzcywgc3VjY2VzcywgZXJyb3IsIHJlc3BvbnNlLCBtb2RpZmllZCxcblx0XHRcdFx0c3RhdHVzVGV4dCA9IG5hdGl2ZVN0YXR1c1RleHQ7XG5cblx0XHRcdC8vIENhbGxlZCBvbmNlXG5cdFx0XHRpZiAoIHN0YXRlID09PSAyICkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdC8vIFN0YXRlIGlzIFwiZG9uZVwiIG5vd1xuXHRcdFx0c3RhdGUgPSAyO1xuXG5cdFx0XHQvLyBDbGVhciB0aW1lb3V0IGlmIGl0IGV4aXN0c1xuXHRcdFx0aWYgKCB0aW1lb3V0VGltZXIgKSB7XG5cdFx0XHRcdGNsZWFyVGltZW91dCggdGltZW91dFRpbWVyICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIERlcmVmZXJlbmNlIHRyYW5zcG9ydCBmb3IgZWFybHkgZ2FyYmFnZSBjb2xsZWN0aW9uXG5cdFx0XHQvLyAobm8gbWF0dGVyIGhvdyBsb25nIHRoZSBqcVhIUiBvYmplY3Qgd2lsbCBiZSB1c2VkKVxuXHRcdFx0dHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuXG5cdFx0XHQvLyBDYWNoZSByZXNwb25zZSBoZWFkZXJzXG5cdFx0XHRyZXNwb25zZUhlYWRlcnNTdHJpbmcgPSBoZWFkZXJzIHx8IFwiXCI7XG5cblx0XHRcdC8vIFNldCByZWFkeVN0YXRlXG5cdFx0XHRqcVhIUi5yZWFkeVN0YXRlID0gc3RhdHVzID4gMCA/IDQgOiAwO1xuXG5cdFx0XHQvLyBEZXRlcm1pbmUgaWYgc3VjY2Vzc2Z1bFxuXHRcdFx0aXNTdWNjZXNzID0gc3RhdHVzID49IDIwMCAmJiBzdGF0dXMgPCAzMDAgfHwgc3RhdHVzID09PSAzMDQ7XG5cblx0XHRcdC8vIEdldCByZXNwb25zZSBkYXRhXG5cdFx0XHRpZiAoIHJlc3BvbnNlcyApIHtcblx0XHRcdFx0cmVzcG9uc2UgPSBhamF4SGFuZGxlUmVzcG9uc2VzKCBzLCBqcVhIUiwgcmVzcG9uc2VzICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIENvbnZlcnQgbm8gbWF0dGVyIHdoYXQgKHRoYXQgd2F5IHJlc3BvbnNlWFhYIGZpZWxkcyBhcmUgYWx3YXlzIHNldClcblx0XHRcdHJlc3BvbnNlID0gYWpheENvbnZlcnQoIHMsIHJlc3BvbnNlLCBqcVhIUiwgaXNTdWNjZXNzICk7XG5cblx0XHRcdC8vIElmIHN1Y2Nlc3NmdWwsIGhhbmRsZSB0eXBlIGNoYWluaW5nXG5cdFx0XHRpZiAoIGlzU3VjY2VzcyApIHtcblxuXHRcdFx0XHQvLyBTZXQgdGhlIElmLU1vZGlmaWVkLVNpbmNlIGFuZC9vciBJZi1Ob25lLU1hdGNoIGhlYWRlciwgaWYgaW4gaWZNb2RpZmllZCBtb2RlLlxuXHRcdFx0XHRpZiAoIHMuaWZNb2RpZmllZCApIHtcblx0XHRcdFx0XHRtb2RpZmllZCA9IGpxWEhSLmdldFJlc3BvbnNlSGVhZGVyKFwiTGFzdC1Nb2RpZmllZFwiKTtcblx0XHRcdFx0XHRpZiAoIG1vZGlmaWVkICkge1xuXHRcdFx0XHRcdFx0alF1ZXJ5Lmxhc3RNb2RpZmllZFsgY2FjaGVVUkwgXSA9IG1vZGlmaWVkO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRtb2RpZmllZCA9IGpxWEhSLmdldFJlc3BvbnNlSGVhZGVyKFwiZXRhZ1wiKTtcblx0XHRcdFx0XHRpZiAoIG1vZGlmaWVkICkge1xuXHRcdFx0XHRcdFx0alF1ZXJ5LmV0YWdbIGNhY2hlVVJMIF0gPSBtb2RpZmllZDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBpZiBubyBjb250ZW50XG5cdFx0XHRcdGlmICggc3RhdHVzID09PSAyMDQgfHwgcy50eXBlID09PSBcIkhFQURcIiApIHtcblx0XHRcdFx0XHRzdGF0dXNUZXh0ID0gXCJub2NvbnRlbnRcIjtcblxuXHRcdFx0XHQvLyBpZiBub3QgbW9kaWZpZWRcblx0XHRcdFx0fSBlbHNlIGlmICggc3RhdHVzID09PSAzMDQgKSB7XG5cdFx0XHRcdFx0c3RhdHVzVGV4dCA9IFwibm90bW9kaWZpZWRcIjtcblxuXHRcdFx0XHQvLyBJZiB3ZSBoYXZlIGRhdGEsIGxldCdzIGNvbnZlcnQgaXRcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRzdGF0dXNUZXh0ID0gcmVzcG9uc2Uuc3RhdGU7XG5cdFx0XHRcdFx0c3VjY2VzcyA9IHJlc3BvbnNlLmRhdGE7XG5cdFx0XHRcdFx0ZXJyb3IgPSByZXNwb25zZS5lcnJvcjtcblx0XHRcdFx0XHRpc1N1Y2Nlc3MgPSAhZXJyb3I7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8vIEV4dHJhY3QgZXJyb3IgZnJvbSBzdGF0dXNUZXh0IGFuZCBub3JtYWxpemUgZm9yIG5vbi1hYm9ydHNcblx0XHRcdFx0ZXJyb3IgPSBzdGF0dXNUZXh0O1xuXHRcdFx0XHRpZiAoIHN0YXR1cyB8fCAhc3RhdHVzVGV4dCApIHtcblx0XHRcdFx0XHRzdGF0dXNUZXh0ID0gXCJlcnJvclwiO1xuXHRcdFx0XHRcdGlmICggc3RhdHVzIDwgMCApIHtcblx0XHRcdFx0XHRcdHN0YXR1cyA9IDA7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNldCBkYXRhIGZvciB0aGUgZmFrZSB4aHIgb2JqZWN0XG5cdFx0XHRqcVhIUi5zdGF0dXMgPSBzdGF0dXM7XG5cdFx0XHRqcVhIUi5zdGF0dXNUZXh0ID0gKCBuYXRpdmVTdGF0dXNUZXh0IHx8IHN0YXR1c1RleHQgKSArIFwiXCI7XG5cblx0XHRcdC8vIFN1Y2Nlc3MvRXJyb3Jcblx0XHRcdGlmICggaXNTdWNjZXNzICkge1xuXHRcdFx0XHRkZWZlcnJlZC5yZXNvbHZlV2l0aCggY2FsbGJhY2tDb250ZXh0LCBbIHN1Y2Nlc3MsIHN0YXR1c1RleHQsIGpxWEhSIF0gKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGRlZmVycmVkLnJlamVjdFdpdGgoIGNhbGxiYWNrQ29udGV4dCwgWyBqcVhIUiwgc3RhdHVzVGV4dCwgZXJyb3IgXSApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTdGF0dXMtZGVwZW5kZW50IGNhbGxiYWNrc1xuXHRcdFx0anFYSFIuc3RhdHVzQ29kZSggc3RhdHVzQ29kZSApO1xuXHRcdFx0c3RhdHVzQ29kZSA9IHVuZGVmaW5lZDtcblxuXHRcdFx0aWYgKCBmaXJlR2xvYmFscyApIHtcblx0XHRcdFx0Z2xvYmFsRXZlbnRDb250ZXh0LnRyaWdnZXIoIGlzU3VjY2VzcyA/IFwiYWpheFN1Y2Nlc3NcIiA6IFwiYWpheEVycm9yXCIsXG5cdFx0XHRcdFx0WyBqcVhIUiwgcywgaXNTdWNjZXNzID8gc3VjY2VzcyA6IGVycm9yIF0gKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ29tcGxldGVcblx0XHRcdGNvbXBsZXRlRGVmZXJyZWQuZmlyZVdpdGgoIGNhbGxiYWNrQ29udGV4dCwgWyBqcVhIUiwgc3RhdHVzVGV4dCBdICk7XG5cblx0XHRcdGlmICggZmlyZUdsb2JhbHMgKSB7XG5cdFx0XHRcdGdsb2JhbEV2ZW50Q29udGV4dC50cmlnZ2VyKCBcImFqYXhDb21wbGV0ZVwiLCBbIGpxWEhSLCBzIF0gKTtcblx0XHRcdFx0Ly8gSGFuZGxlIHRoZSBnbG9iYWwgQUpBWCBjb3VudGVyXG5cdFx0XHRcdGlmICggISggLS1qUXVlcnkuYWN0aXZlICkgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LnRyaWdnZXIoXCJhamF4U3RvcFwiKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBqcVhIUjtcblx0fSxcblxuXHRnZXRKU09OOiBmdW5jdGlvbiggdXJsLCBkYXRhLCBjYWxsYmFjayApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmdldCggdXJsLCBkYXRhLCBjYWxsYmFjaywgXCJqc29uXCIgKTtcblx0fSxcblxuXHRnZXRTY3JpcHQ6IGZ1bmN0aW9uKCB1cmwsIGNhbGxiYWNrICkge1xuXHRcdHJldHVybiBqUXVlcnkuZ2V0KCB1cmwsIHVuZGVmaW5lZCwgY2FsbGJhY2ssIFwic2NyaXB0XCIgKTtcblx0fVxufSk7XG5cbmpRdWVyeS5lYWNoKCBbIFwiZ2V0XCIsIFwicG9zdFwiIF0sIGZ1bmN0aW9uKCBpLCBtZXRob2QgKSB7XG5cdGpRdWVyeVsgbWV0aG9kIF0gPSBmdW5jdGlvbiggdXJsLCBkYXRhLCBjYWxsYmFjaywgdHlwZSApIHtcblx0XHQvLyBTaGlmdCBhcmd1bWVudHMgaWYgZGF0YSBhcmd1bWVudCB3YXMgb21pdHRlZFxuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIGRhdGEgKSApIHtcblx0XHRcdHR5cGUgPSB0eXBlIHx8IGNhbGxiYWNrO1xuXHRcdFx0Y2FsbGJhY2sgPSBkYXRhO1xuXHRcdFx0ZGF0YSA9IHVuZGVmaW5lZDtcblx0XHR9XG5cblx0XHRyZXR1cm4galF1ZXJ5LmFqYXgoe1xuXHRcdFx0dXJsOiB1cmwsXG5cdFx0XHR0eXBlOiBtZXRob2QsXG5cdFx0XHRkYXRhVHlwZTogdHlwZSxcblx0XHRcdGRhdGE6IGRhdGEsXG5cdFx0XHRzdWNjZXNzOiBjYWxsYmFja1xuXHRcdH0pO1xuXHR9O1xufSk7XG5cblxualF1ZXJ5Ll9ldmFsVXJsID0gZnVuY3Rpb24oIHVybCApIHtcblx0cmV0dXJuIGpRdWVyeS5hamF4KHtcblx0XHR1cmw6IHVybCxcblx0XHR0eXBlOiBcIkdFVFwiLFxuXHRcdGRhdGFUeXBlOiBcInNjcmlwdFwiLFxuXHRcdGFzeW5jOiBmYWxzZSxcblx0XHRnbG9iYWw6IGZhbHNlLFxuXHRcdFwidGhyb3dzXCI6IHRydWVcblx0fSk7XG59O1xuXG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHR3cmFwQWxsOiBmdW5jdGlvbiggaHRtbCApIHtcblx0XHR2YXIgd3JhcDtcblxuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIGh0bWwgKSApIHtcblx0XHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oIGkgKSB7XG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLndyYXBBbGwoIGh0bWwuY2FsbCh0aGlzLCBpKSApO1xuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0aWYgKCB0aGlzWyAwIF0gKSB7XG5cblx0XHRcdC8vIFRoZSBlbGVtZW50cyB0byB3cmFwIHRoZSB0YXJnZXQgYXJvdW5kXG5cdFx0XHR3cmFwID0galF1ZXJ5KCBodG1sLCB0aGlzWyAwIF0ub3duZXJEb2N1bWVudCApLmVxKCAwICkuY2xvbmUoIHRydWUgKTtcblxuXHRcdFx0aWYgKCB0aGlzWyAwIF0ucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0d3JhcC5pbnNlcnRCZWZvcmUoIHRoaXNbIDAgXSApO1xuXHRcdFx0fVxuXG5cdFx0XHR3cmFwLm1hcChmdW5jdGlvbigpIHtcblx0XHRcdFx0dmFyIGVsZW0gPSB0aGlzO1xuXG5cdFx0XHRcdHdoaWxlICggZWxlbS5maXJzdEVsZW1lbnRDaGlsZCApIHtcblx0XHRcdFx0XHRlbGVtID0gZWxlbS5maXJzdEVsZW1lbnRDaGlsZDtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiBlbGVtO1xuXHRcdFx0fSkuYXBwZW5kKCB0aGlzICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0d3JhcElubmVyOiBmdW5jdGlvbiggaHRtbCApIHtcblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBodG1sICkgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCBpICkge1xuXHRcdFx0XHRqUXVlcnkoIHRoaXMgKS53cmFwSW5uZXIoIGh0bWwuY2FsbCh0aGlzLCBpKSApO1xuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdHZhciBzZWxmID0galF1ZXJ5KCB0aGlzICksXG5cdFx0XHRcdGNvbnRlbnRzID0gc2VsZi5jb250ZW50cygpO1xuXG5cdFx0XHRpZiAoIGNvbnRlbnRzLmxlbmd0aCApIHtcblx0XHRcdFx0Y29udGVudHMud3JhcEFsbCggaHRtbCApO1xuXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRzZWxmLmFwcGVuZCggaHRtbCApO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9LFxuXG5cdHdyYXA6IGZ1bmN0aW9uKCBodG1sICkge1xuXHRcdHZhciBpc0Z1bmN0aW9uID0galF1ZXJ5LmlzRnVuY3Rpb24oIGh0bWwgKTtcblxuXHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oIGkgKSB7XG5cdFx0XHRqUXVlcnkoIHRoaXMgKS53cmFwQWxsKCBpc0Z1bmN0aW9uID8gaHRtbC5jYWxsKHRoaXMsIGkpIDogaHRtbCApO1xuXHRcdH0pO1xuXHR9LFxuXG5cdHVud3JhcDogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMucGFyZW50KCkuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdGlmICggIWpRdWVyeS5ub2RlTmFtZSggdGhpcywgXCJib2R5XCIgKSApIHtcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkucmVwbGFjZVdpdGgoIHRoaXMuY2hpbGROb2RlcyApO1xuXHRcdFx0fVxuXHRcdH0pLmVuZCgpO1xuXHR9XG59KTtcblxuXG5qUXVlcnkuZXhwci5maWx0ZXJzLmhpZGRlbiA9IGZ1bmN0aW9uKCBlbGVtICkge1xuXHQvLyBTdXBwb3J0OiBPcGVyYSA8PSAxMi4xMlxuXHQvLyBPcGVyYSByZXBvcnRzIG9mZnNldFdpZHRocyBhbmQgb2Zmc2V0SGVpZ2h0cyBsZXNzIHRoYW4gemVybyBvbiBzb21lIGVsZW1lbnRzXG5cdHJldHVybiBlbGVtLm9mZnNldFdpZHRoIDw9IDAgJiYgZWxlbS5vZmZzZXRIZWlnaHQgPD0gMDtcbn07XG5qUXVlcnkuZXhwci5maWx0ZXJzLnZpc2libGUgPSBmdW5jdGlvbiggZWxlbSApIHtcblx0cmV0dXJuICFqUXVlcnkuZXhwci5maWx0ZXJzLmhpZGRlbiggZWxlbSApO1xufTtcblxuXG5cblxudmFyIHIyMCA9IC8lMjAvZyxcblx0cmJyYWNrZXQgPSAvXFxbXFxdJC8sXG5cdHJDUkxGID0gL1xccj9cXG4vZyxcblx0cnN1Ym1pdHRlclR5cGVzID0gL14oPzpzdWJtaXR8YnV0dG9ufGltYWdlfHJlc2V0fGZpbGUpJC9pLFxuXHRyc3VibWl0dGFibGUgPSAvXig/OmlucHV0fHNlbGVjdHx0ZXh0YXJlYXxrZXlnZW4pL2k7XG5cbmZ1bmN0aW9uIGJ1aWxkUGFyYW1zKCBwcmVmaXgsIG9iaiwgdHJhZGl0aW9uYWwsIGFkZCApIHtcblx0dmFyIG5hbWU7XG5cblx0aWYgKCBqUXVlcnkuaXNBcnJheSggb2JqICkgKSB7XG5cdFx0Ly8gU2VyaWFsaXplIGFycmF5IGl0ZW0uXG5cdFx0alF1ZXJ5LmVhY2goIG9iaiwgZnVuY3Rpb24oIGksIHYgKSB7XG5cdFx0XHRpZiAoIHRyYWRpdGlvbmFsIHx8IHJicmFja2V0LnRlc3QoIHByZWZpeCApICkge1xuXHRcdFx0XHQvLyBUcmVhdCBlYWNoIGFycmF5IGl0ZW0gYXMgYSBzY2FsYXIuXG5cdFx0XHRcdGFkZCggcHJlZml4LCB2ICk7XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8vIEl0ZW0gaXMgbm9uLXNjYWxhciAoYXJyYXkgb3Igb2JqZWN0KSwgZW5jb2RlIGl0cyBudW1lcmljIGluZGV4LlxuXHRcdFx0XHRidWlsZFBhcmFtcyggcHJlZml4ICsgXCJbXCIgKyAoIHR5cGVvZiB2ID09PSBcIm9iamVjdFwiID8gaSA6IFwiXCIgKSArIFwiXVwiLCB2LCB0cmFkaXRpb25hbCwgYWRkICk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0fSBlbHNlIGlmICggIXRyYWRpdGlvbmFsICYmIGpRdWVyeS50eXBlKCBvYmogKSA9PT0gXCJvYmplY3RcIiApIHtcblx0XHQvLyBTZXJpYWxpemUgb2JqZWN0IGl0ZW0uXG5cdFx0Zm9yICggbmFtZSBpbiBvYmogKSB7XG5cdFx0XHRidWlsZFBhcmFtcyggcHJlZml4ICsgXCJbXCIgKyBuYW1lICsgXCJdXCIsIG9ialsgbmFtZSBdLCB0cmFkaXRpb25hbCwgYWRkICk7XG5cdFx0fVxuXG5cdH0gZWxzZSB7XG5cdFx0Ly8gU2VyaWFsaXplIHNjYWxhciBpdGVtLlxuXHRcdGFkZCggcHJlZml4LCBvYmogKTtcblx0fVxufVxuXG4vLyBTZXJpYWxpemUgYW4gYXJyYXkgb2YgZm9ybSBlbGVtZW50cyBvciBhIHNldCBvZlxuLy8ga2V5L3ZhbHVlcyBpbnRvIGEgcXVlcnkgc3RyaW5nXG5qUXVlcnkucGFyYW0gPSBmdW5jdGlvbiggYSwgdHJhZGl0aW9uYWwgKSB7XG5cdHZhciBwcmVmaXgsXG5cdFx0cyA9IFtdLFxuXHRcdGFkZCA9IGZ1bmN0aW9uKCBrZXksIHZhbHVlICkge1xuXHRcdFx0Ly8gSWYgdmFsdWUgaXMgYSBmdW5jdGlvbiwgaW52b2tlIGl0IGFuZCByZXR1cm4gaXRzIHZhbHVlXG5cdFx0XHR2YWx1ZSA9IGpRdWVyeS5pc0Z1bmN0aW9uKCB2YWx1ZSApID8gdmFsdWUoKSA6ICggdmFsdWUgPT0gbnVsbCA/IFwiXCIgOiB2YWx1ZSApO1xuXHRcdFx0c1sgcy5sZW5ndGggXSA9IGVuY29kZVVSSUNvbXBvbmVudCgga2V5ICkgKyBcIj1cIiArIGVuY29kZVVSSUNvbXBvbmVudCggdmFsdWUgKTtcblx0XHR9O1xuXG5cdC8vIFNldCB0cmFkaXRpb25hbCB0byB0cnVlIGZvciBqUXVlcnkgPD0gMS4zLjIgYmVoYXZpb3IuXG5cdGlmICggdHJhZGl0aW9uYWwgPT09IHVuZGVmaW5lZCApIHtcblx0XHR0cmFkaXRpb25hbCA9IGpRdWVyeS5hamF4U2V0dGluZ3MgJiYgalF1ZXJ5LmFqYXhTZXR0aW5ncy50cmFkaXRpb25hbDtcblx0fVxuXG5cdC8vIElmIGFuIGFycmF5IHdhcyBwYXNzZWQgaW4sIGFzc3VtZSB0aGF0IGl0IGlzIGFuIGFycmF5IG9mIGZvcm0gZWxlbWVudHMuXG5cdGlmICggalF1ZXJ5LmlzQXJyYXkoIGEgKSB8fCAoIGEuanF1ZXJ5ICYmICFqUXVlcnkuaXNQbGFpbk9iamVjdCggYSApICkgKSB7XG5cdFx0Ly8gU2VyaWFsaXplIHRoZSBmb3JtIGVsZW1lbnRzXG5cdFx0alF1ZXJ5LmVhY2goIGEsIGZ1bmN0aW9uKCkge1xuXHRcdFx0YWRkKCB0aGlzLm5hbWUsIHRoaXMudmFsdWUgKTtcblx0XHR9KTtcblxuXHR9IGVsc2Uge1xuXHRcdC8vIElmIHRyYWRpdGlvbmFsLCBlbmNvZGUgdGhlIFwib2xkXCIgd2F5ICh0aGUgd2F5IDEuMy4yIG9yIG9sZGVyXG5cdFx0Ly8gZGlkIGl0KSwgb3RoZXJ3aXNlIGVuY29kZSBwYXJhbXMgcmVjdXJzaXZlbHkuXG5cdFx0Zm9yICggcHJlZml4IGluIGEgKSB7XG5cdFx0XHRidWlsZFBhcmFtcyggcHJlZml4LCBhWyBwcmVmaXggXSwgdHJhZGl0aW9uYWwsIGFkZCApO1xuXHRcdH1cblx0fVxuXG5cdC8vIFJldHVybiB0aGUgcmVzdWx0aW5nIHNlcmlhbGl6YXRpb25cblx0cmV0dXJuIHMuam9pbiggXCImXCIgKS5yZXBsYWNlKCByMjAsIFwiK1wiICk7XG59O1xuXG5qUXVlcnkuZm4uZXh0ZW5kKHtcblx0c2VyaWFsaXplOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4galF1ZXJ5LnBhcmFtKCB0aGlzLnNlcmlhbGl6ZUFycmF5KCkgKTtcblx0fSxcblx0c2VyaWFsaXplQXJyYXk6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLm1hcChmdW5jdGlvbigpIHtcblx0XHRcdC8vIENhbiBhZGQgcHJvcEhvb2sgZm9yIFwiZWxlbWVudHNcIiB0byBmaWx0ZXIgb3IgYWRkIGZvcm0gZWxlbWVudHNcblx0XHRcdHZhciBlbGVtZW50cyA9IGpRdWVyeS5wcm9wKCB0aGlzLCBcImVsZW1lbnRzXCIgKTtcblx0XHRcdHJldHVybiBlbGVtZW50cyA/IGpRdWVyeS5tYWtlQXJyYXkoIGVsZW1lbnRzICkgOiB0aGlzO1xuXHRcdH0pXG5cdFx0LmZpbHRlcihmdW5jdGlvbigpIHtcblx0XHRcdHZhciB0eXBlID0gdGhpcy50eXBlO1xuXG5cdFx0XHQvLyBVc2UgLmlzKCBcIjpkaXNhYmxlZFwiICkgc28gdGhhdCBmaWVsZHNldFtkaXNhYmxlZF0gd29ya3Ncblx0XHRcdHJldHVybiB0aGlzLm5hbWUgJiYgIWpRdWVyeSggdGhpcyApLmlzKCBcIjpkaXNhYmxlZFwiICkgJiZcblx0XHRcdFx0cnN1Ym1pdHRhYmxlLnRlc3QoIHRoaXMubm9kZU5hbWUgKSAmJiAhcnN1Ym1pdHRlclR5cGVzLnRlc3QoIHR5cGUgKSAmJlxuXHRcdFx0XHQoIHRoaXMuY2hlY2tlZCB8fCAhcmNoZWNrYWJsZVR5cGUudGVzdCggdHlwZSApICk7XG5cdFx0fSlcblx0XHQubWFwKGZ1bmN0aW9uKCBpLCBlbGVtICkge1xuXHRcdFx0dmFyIHZhbCA9IGpRdWVyeSggdGhpcyApLnZhbCgpO1xuXG5cdFx0XHRyZXR1cm4gdmFsID09IG51bGwgP1xuXHRcdFx0XHRudWxsIDpcblx0XHRcdFx0alF1ZXJ5LmlzQXJyYXkoIHZhbCApID9cblx0XHRcdFx0XHRqUXVlcnkubWFwKCB2YWwsIGZ1bmN0aW9uKCB2YWwgKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4geyBuYW1lOiBlbGVtLm5hbWUsIHZhbHVlOiB2YWwucmVwbGFjZSggckNSTEYsIFwiXFxyXFxuXCIgKSB9O1xuXHRcdFx0XHRcdH0pIDpcblx0XHRcdFx0XHR7IG5hbWU6IGVsZW0ubmFtZSwgdmFsdWU6IHZhbC5yZXBsYWNlKCByQ1JMRiwgXCJcXHJcXG5cIiApIH07XG5cdFx0fSkuZ2V0KCk7XG5cdH1cbn0pO1xuXG5cbmpRdWVyeS5hamF4U2V0dGluZ3MueGhyID0gZnVuY3Rpb24oKSB7XG5cdHRyeSB7XG5cdFx0cmV0dXJuIG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuXHR9IGNhdGNoKCBlICkge31cbn07XG5cbnZhciB4aHJJZCA9IDAsXG5cdHhockNhbGxiYWNrcyA9IHt9LFxuXHR4aHJTdWNjZXNzU3RhdHVzID0ge1xuXHRcdC8vIGZpbGUgcHJvdG9jb2wgYWx3YXlzIHlpZWxkcyBzdGF0dXMgY29kZSAwLCBhc3N1bWUgMjAwXG5cdFx0MDogMjAwLFxuXHRcdC8vIFN1cHBvcnQ6IElFOVxuXHRcdC8vICMxNDUwOiBzb21ldGltZXMgSUUgcmV0dXJucyAxMjIzIHdoZW4gaXQgc2hvdWxkIGJlIDIwNFxuXHRcdDEyMjM6IDIwNFxuXHR9LFxuXHR4aHJTdXBwb3J0ZWQgPSBqUXVlcnkuYWpheFNldHRpbmdzLnhocigpO1xuXG4vLyBTdXBwb3J0OiBJRTlcbi8vIE9wZW4gcmVxdWVzdHMgbXVzdCBiZSBtYW51YWxseSBhYm9ydGVkIG9uIHVubG9hZCAoIzUyODApXG4vLyBTZWUgaHR0cHM6Ly9zdXBwb3J0Lm1pY3Jvc29mdC5jb20va2IvMjg1Njc0NiBmb3IgbW9yZSBpbmZvXG5pZiAoIHdpbmRvdy5hdHRhY2hFdmVudCApIHtcblx0d2luZG93LmF0dGFjaEV2ZW50KCBcIm9udW5sb2FkXCIsIGZ1bmN0aW9uKCkge1xuXHRcdGZvciAoIHZhciBrZXkgaW4geGhyQ2FsbGJhY2tzICkge1xuXHRcdFx0eGhyQ2FsbGJhY2tzWyBrZXkgXSgpO1xuXHRcdH1cblx0fSk7XG59XG5cbnN1cHBvcnQuY29ycyA9ICEheGhyU3VwcG9ydGVkICYmICggXCJ3aXRoQ3JlZGVudGlhbHNcIiBpbiB4aHJTdXBwb3J0ZWQgKTtcbnN1cHBvcnQuYWpheCA9IHhoclN1cHBvcnRlZCA9ICEheGhyU3VwcG9ydGVkO1xuXG5qUXVlcnkuYWpheFRyYW5zcG9ydChmdW5jdGlvbiggb3B0aW9ucyApIHtcblx0dmFyIGNhbGxiYWNrO1xuXG5cdC8vIENyb3NzIGRvbWFpbiBvbmx5IGFsbG93ZWQgaWYgc3VwcG9ydGVkIHRocm91Z2ggWE1MSHR0cFJlcXVlc3Rcblx0aWYgKCBzdXBwb3J0LmNvcnMgfHwgeGhyU3VwcG9ydGVkICYmICFvcHRpb25zLmNyb3NzRG9tYWluICkge1xuXHRcdHJldHVybiB7XG5cdFx0XHRzZW5kOiBmdW5jdGlvbiggaGVhZGVycywgY29tcGxldGUgKSB7XG5cdFx0XHRcdHZhciBpLFxuXHRcdFx0XHRcdHhociA9IG9wdGlvbnMueGhyKCksXG5cdFx0XHRcdFx0aWQgPSArK3hocklkO1xuXG5cdFx0XHRcdHhoci5vcGVuKCBvcHRpb25zLnR5cGUsIG9wdGlvbnMudXJsLCBvcHRpb25zLmFzeW5jLCBvcHRpb25zLnVzZXJuYW1lLCBvcHRpb25zLnBhc3N3b3JkICk7XG5cblx0XHRcdFx0Ly8gQXBwbHkgY3VzdG9tIGZpZWxkcyBpZiBwcm92aWRlZFxuXHRcdFx0XHRpZiAoIG9wdGlvbnMueGhyRmllbGRzICkge1xuXHRcdFx0XHRcdGZvciAoIGkgaW4gb3B0aW9ucy54aHJGaWVsZHMgKSB7XG5cdFx0XHRcdFx0XHR4aHJbIGkgXSA9IG9wdGlvbnMueGhyRmllbGRzWyBpIF07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gT3ZlcnJpZGUgbWltZSB0eXBlIGlmIG5lZWRlZFxuXHRcdFx0XHRpZiAoIG9wdGlvbnMubWltZVR5cGUgJiYgeGhyLm92ZXJyaWRlTWltZVR5cGUgKSB7XG5cdFx0XHRcdFx0eGhyLm92ZXJyaWRlTWltZVR5cGUoIG9wdGlvbnMubWltZVR5cGUgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFgtUmVxdWVzdGVkLVdpdGggaGVhZGVyXG5cdFx0XHRcdC8vIEZvciBjcm9zcy1kb21haW4gcmVxdWVzdHMsIHNlZWluZyBhcyBjb25kaXRpb25zIGZvciBhIHByZWZsaWdodCBhcmVcblx0XHRcdFx0Ly8gYWtpbiB0byBhIGppZ3NhdyBwdXp6bGUsIHdlIHNpbXBseSBuZXZlciBzZXQgaXQgdG8gYmUgc3VyZS5cblx0XHRcdFx0Ly8gKGl0IGNhbiBhbHdheXMgYmUgc2V0IG9uIGEgcGVyLXJlcXVlc3QgYmFzaXMgb3IgZXZlbiB1c2luZyBhamF4U2V0dXApXG5cdFx0XHRcdC8vIEZvciBzYW1lLWRvbWFpbiByZXF1ZXN0cywgd29uJ3QgY2hhbmdlIGhlYWRlciBpZiBhbHJlYWR5IHByb3ZpZGVkLlxuXHRcdFx0XHRpZiAoICFvcHRpb25zLmNyb3NzRG9tYWluICYmICFoZWFkZXJzW1wiWC1SZXF1ZXN0ZWQtV2l0aFwiXSApIHtcblx0XHRcdFx0XHRoZWFkZXJzW1wiWC1SZXF1ZXN0ZWQtV2l0aFwiXSA9IFwiWE1MSHR0cFJlcXVlc3RcIjtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFNldCBoZWFkZXJzXG5cdFx0XHRcdGZvciAoIGkgaW4gaGVhZGVycyApIHtcblx0XHRcdFx0XHR4aHIuc2V0UmVxdWVzdEhlYWRlciggaSwgaGVhZGVyc1sgaSBdICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBDYWxsYmFja1xuXHRcdFx0XHRjYWxsYmFjayA9IGZ1bmN0aW9uKCB0eXBlICkge1xuXHRcdFx0XHRcdHJldHVybiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdGlmICggY2FsbGJhY2sgKSB7XG5cdFx0XHRcdFx0XHRcdGRlbGV0ZSB4aHJDYWxsYmFja3NbIGlkIF07XG5cdFx0XHRcdFx0XHRcdGNhbGxiYWNrID0geGhyLm9ubG9hZCA9IHhoci5vbmVycm9yID0gbnVsbDtcblxuXHRcdFx0XHRcdFx0XHRpZiAoIHR5cGUgPT09IFwiYWJvcnRcIiApIHtcblx0XHRcdFx0XHRcdFx0XHR4aHIuYWJvcnQoKTtcblx0XHRcdFx0XHRcdFx0fSBlbHNlIGlmICggdHlwZSA9PT0gXCJlcnJvclwiICkge1xuXHRcdFx0XHRcdFx0XHRcdGNvbXBsZXRlKFxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gZmlsZTogcHJvdG9jb2wgYWx3YXlzIHlpZWxkcyBzdGF0dXMgMDsgc2VlICM4NjA1LCAjMTQyMDdcblx0XHRcdFx0XHRcdFx0XHRcdHhoci5zdGF0dXMsXG5cdFx0XHRcdFx0XHRcdFx0XHR4aHIuc3RhdHVzVGV4dFxuXHRcdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0Y29tcGxldGUoXG5cdFx0XHRcdFx0XHRcdFx0XHR4aHJTdWNjZXNzU3RhdHVzWyB4aHIuc3RhdHVzIF0gfHwgeGhyLnN0YXR1cyxcblx0XHRcdFx0XHRcdFx0XHRcdHhoci5zdGF0dXNUZXh0LFxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUU5XG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBBY2Nlc3NpbmcgYmluYXJ5LWRhdGEgcmVzcG9uc2VUZXh0IHRocm93cyBhbiBleGNlcHRpb25cblx0XHRcdFx0XHRcdFx0XHRcdC8vICgjMTE0MjYpXG5cdFx0XHRcdFx0XHRcdFx0XHR0eXBlb2YgeGhyLnJlc3BvbnNlVGV4dCA9PT0gXCJzdHJpbmdcIiA/IHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0dGV4dDogeGhyLnJlc3BvbnNlVGV4dFxuXHRcdFx0XHRcdFx0XHRcdFx0fSA6IHVuZGVmaW5lZCxcblx0XHRcdFx0XHRcdFx0XHRcdHhoci5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKVxuXHRcdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9O1xuXHRcdFx0XHR9O1xuXG5cdFx0XHRcdC8vIExpc3RlbiB0byBldmVudHNcblx0XHRcdFx0eGhyLm9ubG9hZCA9IGNhbGxiYWNrKCk7XG5cdFx0XHRcdHhoci5vbmVycm9yID0gY2FsbGJhY2soXCJlcnJvclwiKTtcblxuXHRcdFx0XHQvLyBDcmVhdGUgdGhlIGFib3J0IGNhbGxiYWNrXG5cdFx0XHRcdGNhbGxiYWNrID0geGhyQ2FsbGJhY2tzWyBpZCBdID0gY2FsbGJhY2soXCJhYm9ydFwiKTtcblxuXHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdC8vIERvIHNlbmQgdGhlIHJlcXVlc3QgKHRoaXMgbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbilcblx0XHRcdFx0XHR4aHIuc2VuZCggb3B0aW9ucy5oYXNDb250ZW50ICYmIG9wdGlvbnMuZGF0YSB8fCBudWxsICk7XG5cdFx0XHRcdH0gY2F0Y2ggKCBlICkge1xuXHRcdFx0XHRcdC8vICMxNDY4MzogT25seSByZXRocm93IGlmIHRoaXMgaGFzbid0IGJlZW4gbm90aWZpZWQgYXMgYW4gZXJyb3IgeWV0XG5cdFx0XHRcdFx0aWYgKCBjYWxsYmFjayApIHtcblx0XHRcdFx0XHRcdHRocm93IGU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXG5cdFx0XHRhYm9ydDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggY2FsbGJhY2sgKSB7XG5cdFx0XHRcdFx0Y2FsbGJhY2soKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH07XG5cdH1cbn0pO1xuXG5cblxuXG4vLyBJbnN0YWxsIHNjcmlwdCBkYXRhVHlwZVxualF1ZXJ5LmFqYXhTZXR1cCh7XG5cdGFjY2VwdHM6IHtcblx0XHRzY3JpcHQ6IFwidGV4dC9qYXZhc2NyaXB0LCBhcHBsaWNhdGlvbi9qYXZhc2NyaXB0LCBhcHBsaWNhdGlvbi9lY21hc2NyaXB0LCBhcHBsaWNhdGlvbi94LWVjbWFzY3JpcHRcIlxuXHR9LFxuXHRjb250ZW50czoge1xuXHRcdHNjcmlwdDogLyg/OmphdmF8ZWNtYSlzY3JpcHQvXG5cdH0sXG5cdGNvbnZlcnRlcnM6IHtcblx0XHRcInRleHQgc2NyaXB0XCI6IGZ1bmN0aW9uKCB0ZXh0ICkge1xuXHRcdFx0alF1ZXJ5Lmdsb2JhbEV2YWwoIHRleHQgKTtcblx0XHRcdHJldHVybiB0ZXh0O1xuXHRcdH1cblx0fVxufSk7XG5cbi8vIEhhbmRsZSBjYWNoZSdzIHNwZWNpYWwgY2FzZSBhbmQgY3Jvc3NEb21haW5cbmpRdWVyeS5hamF4UHJlZmlsdGVyKCBcInNjcmlwdFwiLCBmdW5jdGlvbiggcyApIHtcblx0aWYgKCBzLmNhY2hlID09PSB1bmRlZmluZWQgKSB7XG5cdFx0cy5jYWNoZSA9IGZhbHNlO1xuXHR9XG5cdGlmICggcy5jcm9zc0RvbWFpbiApIHtcblx0XHRzLnR5cGUgPSBcIkdFVFwiO1xuXHR9XG59KTtcblxuLy8gQmluZCBzY3JpcHQgdGFnIGhhY2sgdHJhbnNwb3J0XG5qUXVlcnkuYWpheFRyYW5zcG9ydCggXCJzY3JpcHRcIiwgZnVuY3Rpb24oIHMgKSB7XG5cdC8vIFRoaXMgdHJhbnNwb3J0IG9ubHkgZGVhbHMgd2l0aCBjcm9zcyBkb21haW4gcmVxdWVzdHNcblx0aWYgKCBzLmNyb3NzRG9tYWluICkge1xuXHRcdHZhciBzY3JpcHQsIGNhbGxiYWNrO1xuXHRcdHJldHVybiB7XG5cdFx0XHRzZW5kOiBmdW5jdGlvbiggXywgY29tcGxldGUgKSB7XG5cdFx0XHRcdHNjcmlwdCA9IGpRdWVyeShcIjxzY3JpcHQ+XCIpLnByb3Aoe1xuXHRcdFx0XHRcdGFzeW5jOiB0cnVlLFxuXHRcdFx0XHRcdGNoYXJzZXQ6IHMuc2NyaXB0Q2hhcnNldCxcblx0XHRcdFx0XHRzcmM6IHMudXJsXG5cdFx0XHRcdH0pLm9uKFxuXHRcdFx0XHRcdFwibG9hZCBlcnJvclwiLFxuXHRcdFx0XHRcdGNhbGxiYWNrID0gZnVuY3Rpb24oIGV2dCApIHtcblx0XHRcdFx0XHRcdHNjcmlwdC5yZW1vdmUoKTtcblx0XHRcdFx0XHRcdGNhbGxiYWNrID0gbnVsbDtcblx0XHRcdFx0XHRcdGlmICggZXZ0ICkge1xuXHRcdFx0XHRcdFx0XHRjb21wbGV0ZSggZXZ0LnR5cGUgPT09IFwiZXJyb3JcIiA/IDQwNCA6IDIwMCwgZXZ0LnR5cGUgKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdCk7XG5cdFx0XHRcdGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoIHNjcmlwdFsgMCBdICk7XG5cdFx0XHR9LFxuXHRcdFx0YWJvcnQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoIGNhbGxiYWNrICkge1xuXHRcdFx0XHRcdGNhbGxiYWNrKCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9O1xuXHR9XG59KTtcblxuXG5cblxudmFyIG9sZENhbGxiYWNrcyA9IFtdLFxuXHRyanNvbnAgPSAvKD0pXFw/KD89JnwkKXxcXD9cXD8vO1xuXG4vLyBEZWZhdWx0IGpzb25wIHNldHRpbmdzXG5qUXVlcnkuYWpheFNldHVwKHtcblx0anNvbnA6IFwiY2FsbGJhY2tcIixcblx0anNvbnBDYWxsYmFjazogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGNhbGxiYWNrID0gb2xkQ2FsbGJhY2tzLnBvcCgpIHx8ICggalF1ZXJ5LmV4cGFuZG8gKyBcIl9cIiArICggbm9uY2UrKyApICk7XG5cdFx0dGhpc1sgY2FsbGJhY2sgXSA9IHRydWU7XG5cdFx0cmV0dXJuIGNhbGxiYWNrO1xuXHR9XG59KTtcblxuLy8gRGV0ZWN0LCBub3JtYWxpemUgb3B0aW9ucyBhbmQgaW5zdGFsbCBjYWxsYmFja3MgZm9yIGpzb25wIHJlcXVlc3RzXG5qUXVlcnkuYWpheFByZWZpbHRlciggXCJqc29uIGpzb25wXCIsIGZ1bmN0aW9uKCBzLCBvcmlnaW5hbFNldHRpbmdzLCBqcVhIUiApIHtcblxuXHR2YXIgY2FsbGJhY2tOYW1lLCBvdmVyd3JpdHRlbiwgcmVzcG9uc2VDb250YWluZXIsXG5cdFx0anNvblByb3AgPSBzLmpzb25wICE9PSBmYWxzZSAmJiAoIHJqc29ucC50ZXN0KCBzLnVybCApID9cblx0XHRcdFwidXJsXCIgOlxuXHRcdFx0dHlwZW9mIHMuZGF0YSA9PT0gXCJzdHJpbmdcIiAmJiAhKCBzLmNvbnRlbnRUeXBlIHx8IFwiXCIgKS5pbmRleE9mKFwiYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkXCIpICYmIHJqc29ucC50ZXN0KCBzLmRhdGEgKSAmJiBcImRhdGFcIlxuXHRcdCk7XG5cblx0Ly8gSGFuZGxlIGlmZiB0aGUgZXhwZWN0ZWQgZGF0YSB0eXBlIGlzIFwianNvbnBcIiBvciB3ZSBoYXZlIGEgcGFyYW1ldGVyIHRvIHNldFxuXHRpZiAoIGpzb25Qcm9wIHx8IHMuZGF0YVR5cGVzWyAwIF0gPT09IFwianNvbnBcIiApIHtcblxuXHRcdC8vIEdldCBjYWxsYmFjayBuYW1lLCByZW1lbWJlcmluZyBwcmVleGlzdGluZyB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggaXRcblx0XHRjYWxsYmFja05hbWUgPSBzLmpzb25wQ2FsbGJhY2sgPSBqUXVlcnkuaXNGdW5jdGlvbiggcy5qc29ucENhbGxiYWNrICkgP1xuXHRcdFx0cy5qc29ucENhbGxiYWNrKCkgOlxuXHRcdFx0cy5qc29ucENhbGxiYWNrO1xuXG5cdFx0Ly8gSW5zZXJ0IGNhbGxiYWNrIGludG8gdXJsIG9yIGZvcm0gZGF0YVxuXHRcdGlmICgganNvblByb3AgKSB7XG5cdFx0XHRzWyBqc29uUHJvcCBdID0gc1sganNvblByb3AgXS5yZXBsYWNlKCByanNvbnAsIFwiJDFcIiArIGNhbGxiYWNrTmFtZSApO1xuXHRcdH0gZWxzZSBpZiAoIHMuanNvbnAgIT09IGZhbHNlICkge1xuXHRcdFx0cy51cmwgKz0gKCBycXVlcnkudGVzdCggcy51cmwgKSA/IFwiJlwiIDogXCI/XCIgKSArIHMuanNvbnAgKyBcIj1cIiArIGNhbGxiYWNrTmFtZTtcblx0XHR9XG5cblx0XHQvLyBVc2UgZGF0YSBjb252ZXJ0ZXIgdG8gcmV0cmlldmUganNvbiBhZnRlciBzY3JpcHQgZXhlY3V0aW9uXG5cdFx0cy5jb252ZXJ0ZXJzW1wic2NyaXB0IGpzb25cIl0gPSBmdW5jdGlvbigpIHtcblx0XHRcdGlmICggIXJlc3BvbnNlQ29udGFpbmVyICkge1xuXHRcdFx0XHRqUXVlcnkuZXJyb3IoIGNhbGxiYWNrTmFtZSArIFwiIHdhcyBub3QgY2FsbGVkXCIgKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiByZXNwb25zZUNvbnRhaW5lclsgMCBdO1xuXHRcdH07XG5cblx0XHQvLyBmb3JjZSBqc29uIGRhdGFUeXBlXG5cdFx0cy5kYXRhVHlwZXNbIDAgXSA9IFwianNvblwiO1xuXG5cdFx0Ly8gSW5zdGFsbCBjYWxsYmFja1xuXHRcdG92ZXJ3cml0dGVuID0gd2luZG93WyBjYWxsYmFja05hbWUgXTtcblx0XHR3aW5kb3dbIGNhbGxiYWNrTmFtZSBdID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXNwb25zZUNvbnRhaW5lciA9IGFyZ3VtZW50cztcblx0XHR9O1xuXG5cdFx0Ly8gQ2xlYW4tdXAgZnVuY3Rpb24gKGZpcmVzIGFmdGVyIGNvbnZlcnRlcnMpXG5cdFx0anFYSFIuYWx3YXlzKGZ1bmN0aW9uKCkge1xuXHRcdFx0Ly8gUmVzdG9yZSBwcmVleGlzdGluZyB2YWx1ZVxuXHRcdFx0d2luZG93WyBjYWxsYmFja05hbWUgXSA9IG92ZXJ3cml0dGVuO1xuXG5cdFx0XHQvLyBTYXZlIGJhY2sgYXMgZnJlZVxuXHRcdFx0aWYgKCBzWyBjYWxsYmFja05hbWUgXSApIHtcblx0XHRcdFx0Ly8gbWFrZSBzdXJlIHRoYXQgcmUtdXNpbmcgdGhlIG9wdGlvbnMgZG9lc24ndCBzY3JldyB0aGluZ3MgYXJvdW5kXG5cdFx0XHRcdHMuanNvbnBDYWxsYmFjayA9IG9yaWdpbmFsU2V0dGluZ3MuanNvbnBDYWxsYmFjaztcblxuXHRcdFx0XHQvLyBzYXZlIHRoZSBjYWxsYmFjayBuYW1lIGZvciBmdXR1cmUgdXNlXG5cdFx0XHRcdG9sZENhbGxiYWNrcy5wdXNoKCBjYWxsYmFja05hbWUgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ2FsbCBpZiBpdCB3YXMgYSBmdW5jdGlvbiBhbmQgd2UgaGF2ZSBhIHJlc3BvbnNlXG5cdFx0XHRpZiAoIHJlc3BvbnNlQ29udGFpbmVyICYmIGpRdWVyeS5pc0Z1bmN0aW9uKCBvdmVyd3JpdHRlbiApICkge1xuXHRcdFx0XHRvdmVyd3JpdHRlbiggcmVzcG9uc2VDb250YWluZXJbIDAgXSApO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXNwb25zZUNvbnRhaW5lciA9IG92ZXJ3cml0dGVuID0gdW5kZWZpbmVkO1xuXHRcdH0pO1xuXG5cdFx0Ly8gRGVsZWdhdGUgdG8gc2NyaXB0XG5cdFx0cmV0dXJuIFwic2NyaXB0XCI7XG5cdH1cbn0pO1xuXG5cblxuXG4vLyBkYXRhOiBzdHJpbmcgb2YgaHRtbFxuLy8gY29udGV4dCAob3B0aW9uYWwpOiBJZiBzcGVjaWZpZWQsIHRoZSBmcmFnbWVudCB3aWxsIGJlIGNyZWF0ZWQgaW4gdGhpcyBjb250ZXh0LCBkZWZhdWx0cyB0byBkb2N1bWVudFxuLy8ga2VlcFNjcmlwdHMgKG9wdGlvbmFsKTogSWYgdHJ1ZSwgd2lsbCBpbmNsdWRlIHNjcmlwdHMgcGFzc2VkIGluIHRoZSBodG1sIHN0cmluZ1xualF1ZXJ5LnBhcnNlSFRNTCA9IGZ1bmN0aW9uKCBkYXRhLCBjb250ZXh0LCBrZWVwU2NyaXB0cyApIHtcblx0aWYgKCAhZGF0YSB8fCB0eXBlb2YgZGF0YSAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRyZXR1cm4gbnVsbDtcblx0fVxuXHRpZiAoIHR5cGVvZiBjb250ZXh0ID09PSBcImJvb2xlYW5cIiApIHtcblx0XHRrZWVwU2NyaXB0cyA9IGNvbnRleHQ7XG5cdFx0Y29udGV4dCA9IGZhbHNlO1xuXHR9XG5cdGNvbnRleHQgPSBjb250ZXh0IHx8IGRvY3VtZW50O1xuXG5cdHZhciBwYXJzZWQgPSByc2luZ2xlVGFnLmV4ZWMoIGRhdGEgKSxcblx0XHRzY3JpcHRzID0gIWtlZXBTY3JpcHRzICYmIFtdO1xuXG5cdC8vIFNpbmdsZSB0YWdcblx0aWYgKCBwYXJzZWQgKSB7XG5cdFx0cmV0dXJuIFsgY29udGV4dC5jcmVhdGVFbGVtZW50KCBwYXJzZWRbMV0gKSBdO1xuXHR9XG5cblx0cGFyc2VkID0galF1ZXJ5LmJ1aWxkRnJhZ21lbnQoIFsgZGF0YSBdLCBjb250ZXh0LCBzY3JpcHRzICk7XG5cblx0aWYgKCBzY3JpcHRzICYmIHNjcmlwdHMubGVuZ3RoICkge1xuXHRcdGpRdWVyeSggc2NyaXB0cyApLnJlbW92ZSgpO1xuXHR9XG5cblx0cmV0dXJuIGpRdWVyeS5tZXJnZSggW10sIHBhcnNlZC5jaGlsZE5vZGVzICk7XG59O1xuXG5cbi8vIEtlZXAgYSBjb3B5IG9mIHRoZSBvbGQgbG9hZCBtZXRob2RcbnZhciBfbG9hZCA9IGpRdWVyeS5mbi5sb2FkO1xuXG4vKipcbiAqIExvYWQgYSB1cmwgaW50byBhIHBhZ2VcbiAqL1xualF1ZXJ5LmZuLmxvYWQgPSBmdW5jdGlvbiggdXJsLCBwYXJhbXMsIGNhbGxiYWNrICkge1xuXHRpZiAoIHR5cGVvZiB1cmwgIT09IFwic3RyaW5nXCIgJiYgX2xvYWQgKSB7XG5cdFx0cmV0dXJuIF9sb2FkLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKTtcblx0fVxuXG5cdHZhciBzZWxlY3RvciwgdHlwZSwgcmVzcG9uc2UsXG5cdFx0c2VsZiA9IHRoaXMsXG5cdFx0b2ZmID0gdXJsLmluZGV4T2YoXCIgXCIpO1xuXG5cdGlmICggb2ZmID49IDAgKSB7XG5cdFx0c2VsZWN0b3IgPSBqUXVlcnkudHJpbSggdXJsLnNsaWNlKCBvZmYgKSApO1xuXHRcdHVybCA9IHVybC5zbGljZSggMCwgb2ZmICk7XG5cdH1cblxuXHQvLyBJZiBpdCdzIGEgZnVuY3Rpb25cblx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggcGFyYW1zICkgKSB7XG5cblx0XHQvLyBXZSBhc3N1bWUgdGhhdCBpdCdzIHRoZSBjYWxsYmFja1xuXHRcdGNhbGxiYWNrID0gcGFyYW1zO1xuXHRcdHBhcmFtcyA9IHVuZGVmaW5lZDtcblxuXHQvLyBPdGhlcndpc2UsIGJ1aWxkIGEgcGFyYW0gc3RyaW5nXG5cdH0gZWxzZSBpZiAoIHBhcmFtcyAmJiB0eXBlb2YgcGFyYW1zID09PSBcIm9iamVjdFwiICkge1xuXHRcdHR5cGUgPSBcIlBPU1RcIjtcblx0fVxuXG5cdC8vIElmIHdlIGhhdmUgZWxlbWVudHMgdG8gbW9kaWZ5LCBtYWtlIHRoZSByZXF1ZXN0XG5cdGlmICggc2VsZi5sZW5ndGggPiAwICkge1xuXHRcdGpRdWVyeS5hamF4KHtcblx0XHRcdHVybDogdXJsLFxuXG5cdFx0XHQvLyBpZiBcInR5cGVcIiB2YXJpYWJsZSBpcyB1bmRlZmluZWQsIHRoZW4gXCJHRVRcIiBtZXRob2Qgd2lsbCBiZSB1c2VkXG5cdFx0XHR0eXBlOiB0eXBlLFxuXHRcdFx0ZGF0YVR5cGU6IFwiaHRtbFwiLFxuXHRcdFx0ZGF0YTogcGFyYW1zXG5cdFx0fSkuZG9uZShmdW5jdGlvbiggcmVzcG9uc2VUZXh0ICkge1xuXG5cdFx0XHQvLyBTYXZlIHJlc3BvbnNlIGZvciB1c2UgaW4gY29tcGxldGUgY2FsbGJhY2tcblx0XHRcdHJlc3BvbnNlID0gYXJndW1lbnRzO1xuXG5cdFx0XHRzZWxmLmh0bWwoIHNlbGVjdG9yID9cblxuXHRcdFx0XHQvLyBJZiBhIHNlbGVjdG9yIHdhcyBzcGVjaWZpZWQsIGxvY2F0ZSB0aGUgcmlnaHQgZWxlbWVudHMgaW4gYSBkdW1teSBkaXZcblx0XHRcdFx0Ly8gRXhjbHVkZSBzY3JpcHRzIHRvIGF2b2lkIElFICdQZXJtaXNzaW9uIERlbmllZCcgZXJyb3JzXG5cdFx0XHRcdGpRdWVyeShcIjxkaXY+XCIpLmFwcGVuZCggalF1ZXJ5LnBhcnNlSFRNTCggcmVzcG9uc2VUZXh0ICkgKS5maW5kKCBzZWxlY3RvciApIDpcblxuXHRcdFx0XHQvLyBPdGhlcndpc2UgdXNlIHRoZSBmdWxsIHJlc3VsdFxuXHRcdFx0XHRyZXNwb25zZVRleHQgKTtcblxuXHRcdH0pLmNvbXBsZXRlKCBjYWxsYmFjayAmJiBmdW5jdGlvbigganFYSFIsIHN0YXR1cyApIHtcblx0XHRcdHNlbGYuZWFjaCggY2FsbGJhY2ssIHJlc3BvbnNlIHx8IFsganFYSFIucmVzcG9uc2VUZXh0LCBzdGF0dXMsIGpxWEhSIF0gKTtcblx0XHR9KTtcblx0fVxuXG5cdHJldHVybiB0aGlzO1xufTtcblxuXG5cblxuLy8gQXR0YWNoIGEgYnVuY2ggb2YgZnVuY3Rpb25zIGZvciBoYW5kbGluZyBjb21tb24gQUpBWCBldmVudHNcbmpRdWVyeS5lYWNoKCBbIFwiYWpheFN0YXJ0XCIsIFwiYWpheFN0b3BcIiwgXCJhamF4Q29tcGxldGVcIiwgXCJhamF4RXJyb3JcIiwgXCJhamF4U3VjY2Vzc1wiLCBcImFqYXhTZW5kXCIgXSwgZnVuY3Rpb24oIGksIHR5cGUgKSB7XG5cdGpRdWVyeS5mblsgdHlwZSBdID0gZnVuY3Rpb24oIGZuICkge1xuXHRcdHJldHVybiB0aGlzLm9uKCB0eXBlLCBmbiApO1xuXHR9O1xufSk7XG5cblxuXG5cbmpRdWVyeS5leHByLmZpbHRlcnMuYW5pbWF0ZWQgPSBmdW5jdGlvbiggZWxlbSApIHtcblx0cmV0dXJuIGpRdWVyeS5ncmVwKGpRdWVyeS50aW1lcnMsIGZ1bmN0aW9uKCBmbiApIHtcblx0XHRyZXR1cm4gZWxlbSA9PT0gZm4uZWxlbTtcblx0fSkubGVuZ3RoO1xufTtcblxuXG5cblxudmFyIGRvY0VsZW0gPSB3aW5kb3cuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuXG4vKipcbiAqIEdldHMgYSB3aW5kb3cgZnJvbSBhbiBlbGVtZW50XG4gKi9cbmZ1bmN0aW9uIGdldFdpbmRvdyggZWxlbSApIHtcblx0cmV0dXJuIGpRdWVyeS5pc1dpbmRvdyggZWxlbSApID8gZWxlbSA6IGVsZW0ubm9kZVR5cGUgPT09IDkgJiYgZWxlbS5kZWZhdWx0Vmlldztcbn1cblxualF1ZXJ5Lm9mZnNldCA9IHtcblx0c2V0T2Zmc2V0OiBmdW5jdGlvbiggZWxlbSwgb3B0aW9ucywgaSApIHtcblx0XHR2YXIgY3VyUG9zaXRpb24sIGN1ckxlZnQsIGN1ckNTU1RvcCwgY3VyVG9wLCBjdXJPZmZzZXQsIGN1ckNTU0xlZnQsIGNhbGN1bGF0ZVBvc2l0aW9uLFxuXHRcdFx0cG9zaXRpb24gPSBqUXVlcnkuY3NzKCBlbGVtLCBcInBvc2l0aW9uXCIgKSxcblx0XHRcdGN1ckVsZW0gPSBqUXVlcnkoIGVsZW0gKSxcblx0XHRcdHByb3BzID0ge307XG5cblx0XHQvLyBTZXQgcG9zaXRpb24gZmlyc3QsIGluLWNhc2UgdG9wL2xlZnQgYXJlIHNldCBldmVuIG9uIHN0YXRpYyBlbGVtXG5cdFx0aWYgKCBwb3NpdGlvbiA9PT0gXCJzdGF0aWNcIiApIHtcblx0XHRcdGVsZW0uc3R5bGUucG9zaXRpb24gPSBcInJlbGF0aXZlXCI7XG5cdFx0fVxuXG5cdFx0Y3VyT2Zmc2V0ID0gY3VyRWxlbS5vZmZzZXQoKTtcblx0XHRjdXJDU1NUb3AgPSBqUXVlcnkuY3NzKCBlbGVtLCBcInRvcFwiICk7XG5cdFx0Y3VyQ1NTTGVmdCA9IGpRdWVyeS5jc3MoIGVsZW0sIFwibGVmdFwiICk7XG5cdFx0Y2FsY3VsYXRlUG9zaXRpb24gPSAoIHBvc2l0aW9uID09PSBcImFic29sdXRlXCIgfHwgcG9zaXRpb24gPT09IFwiZml4ZWRcIiApICYmXG5cdFx0XHQoIGN1ckNTU1RvcCArIGN1ckNTU0xlZnQgKS5pbmRleE9mKFwiYXV0b1wiKSA+IC0xO1xuXG5cdFx0Ly8gTmVlZCB0byBiZSBhYmxlIHRvIGNhbGN1bGF0ZSBwb3NpdGlvbiBpZiBlaXRoZXJcblx0XHQvLyB0b3Agb3IgbGVmdCBpcyBhdXRvIGFuZCBwb3NpdGlvbiBpcyBlaXRoZXIgYWJzb2x1dGUgb3IgZml4ZWRcblx0XHRpZiAoIGNhbGN1bGF0ZVBvc2l0aW9uICkge1xuXHRcdFx0Y3VyUG9zaXRpb24gPSBjdXJFbGVtLnBvc2l0aW9uKCk7XG5cdFx0XHRjdXJUb3AgPSBjdXJQb3NpdGlvbi50b3A7XG5cdFx0XHRjdXJMZWZ0ID0gY3VyUG9zaXRpb24ubGVmdDtcblxuXHRcdH0gZWxzZSB7XG5cdFx0XHRjdXJUb3AgPSBwYXJzZUZsb2F0KCBjdXJDU1NUb3AgKSB8fCAwO1xuXHRcdFx0Y3VyTGVmdCA9IHBhcnNlRmxvYXQoIGN1ckNTU0xlZnQgKSB8fCAwO1xuXHRcdH1cblxuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIG9wdGlvbnMgKSApIHtcblx0XHRcdG9wdGlvbnMgPSBvcHRpb25zLmNhbGwoIGVsZW0sIGksIGN1ck9mZnNldCApO1xuXHRcdH1cblxuXHRcdGlmICggb3B0aW9ucy50b3AgIT0gbnVsbCApIHtcblx0XHRcdHByb3BzLnRvcCA9ICggb3B0aW9ucy50b3AgLSBjdXJPZmZzZXQudG9wICkgKyBjdXJUb3A7XG5cdFx0fVxuXHRcdGlmICggb3B0aW9ucy5sZWZ0ICE9IG51bGwgKSB7XG5cdFx0XHRwcm9wcy5sZWZ0ID0gKCBvcHRpb25zLmxlZnQgLSBjdXJPZmZzZXQubGVmdCApICsgY3VyTGVmdDtcblx0XHR9XG5cblx0XHRpZiAoIFwidXNpbmdcIiBpbiBvcHRpb25zICkge1xuXHRcdFx0b3B0aW9ucy51c2luZy5jYWxsKCBlbGVtLCBwcm9wcyApO1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdGN1ckVsZW0uY3NzKCBwcm9wcyApO1xuXHRcdH1cblx0fVxufTtcblxualF1ZXJ5LmZuLmV4dGVuZCh7XG5cdG9mZnNldDogZnVuY3Rpb24oIG9wdGlvbnMgKSB7XG5cdFx0aWYgKCBhcmd1bWVudHMubGVuZ3RoICkge1xuXHRcdFx0cmV0dXJuIG9wdGlvbnMgPT09IHVuZGVmaW5lZCA/XG5cdFx0XHRcdHRoaXMgOlxuXHRcdFx0XHR0aGlzLmVhY2goZnVuY3Rpb24oIGkgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5Lm9mZnNldC5zZXRPZmZzZXQoIHRoaXMsIG9wdGlvbnMsIGkgKTtcblx0XHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0dmFyIGRvY0VsZW0sIHdpbixcblx0XHRcdGVsZW0gPSB0aGlzWyAwIF0sXG5cdFx0XHRib3ggPSB7IHRvcDogMCwgbGVmdDogMCB9LFxuXHRcdFx0ZG9jID0gZWxlbSAmJiBlbGVtLm93bmVyRG9jdW1lbnQ7XG5cblx0XHRpZiAoICFkb2MgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0ZG9jRWxlbSA9IGRvYy5kb2N1bWVudEVsZW1lbnQ7XG5cblx0XHQvLyBNYWtlIHN1cmUgaXQncyBub3QgYSBkaXNjb25uZWN0ZWQgRE9NIG5vZGVcblx0XHRpZiAoICFqUXVlcnkuY29udGFpbnMoIGRvY0VsZW0sIGVsZW0gKSApIHtcblx0XHRcdHJldHVybiBib3g7XG5cdFx0fVxuXG5cdFx0Ly8gU3VwcG9ydDogQmxhY2tCZXJyeSA1LCBpT1MgMyAob3JpZ2luYWwgaVBob25lKVxuXHRcdC8vIElmIHdlIGRvbid0IGhhdmUgZ0JDUiwganVzdCB1c2UgMCwwIHJhdGhlciB0aGFuIGVycm9yXG5cdFx0aWYgKCB0eXBlb2YgZWxlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QgIT09IHN0cnVuZGVmaW5lZCApIHtcblx0XHRcdGJveCA9IGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cdFx0fVxuXHRcdHdpbiA9IGdldFdpbmRvdyggZG9jICk7XG5cdFx0cmV0dXJuIHtcblx0XHRcdHRvcDogYm94LnRvcCArIHdpbi5wYWdlWU9mZnNldCAtIGRvY0VsZW0uY2xpZW50VG9wLFxuXHRcdFx0bGVmdDogYm94LmxlZnQgKyB3aW4ucGFnZVhPZmZzZXQgLSBkb2NFbGVtLmNsaWVudExlZnRcblx0XHR9O1xuXHR9LFxuXG5cdHBvc2l0aW9uOiBmdW5jdGlvbigpIHtcblx0XHRpZiAoICF0aGlzWyAwIF0gKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dmFyIG9mZnNldFBhcmVudCwgb2Zmc2V0LFxuXHRcdFx0ZWxlbSA9IHRoaXNbIDAgXSxcblx0XHRcdHBhcmVudE9mZnNldCA9IHsgdG9wOiAwLCBsZWZ0OiAwIH07XG5cblx0XHQvLyBGaXhlZCBlbGVtZW50cyBhcmUgb2Zmc2V0IGZyb20gd2luZG93IChwYXJlbnRPZmZzZXQgPSB7dG9wOjAsIGxlZnQ6IDB9LCBiZWNhdXNlIGl0IGlzIGl0cyBvbmx5IG9mZnNldCBwYXJlbnRcblx0XHRpZiAoIGpRdWVyeS5jc3MoIGVsZW0sIFwicG9zaXRpb25cIiApID09PSBcImZpeGVkXCIgKSB7XG5cdFx0XHQvLyBBc3N1bWUgZ2V0Qm91bmRpbmdDbGllbnRSZWN0IGlzIHRoZXJlIHdoZW4gY29tcHV0ZWQgcG9zaXRpb24gaXMgZml4ZWRcblx0XHRcdG9mZnNldCA9IGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gR2V0ICpyZWFsKiBvZmZzZXRQYXJlbnRcblx0XHRcdG9mZnNldFBhcmVudCA9IHRoaXMub2Zmc2V0UGFyZW50KCk7XG5cblx0XHRcdC8vIEdldCBjb3JyZWN0IG9mZnNldHNcblx0XHRcdG9mZnNldCA9IHRoaXMub2Zmc2V0KCk7XG5cdFx0XHRpZiAoICFqUXVlcnkubm9kZU5hbWUoIG9mZnNldFBhcmVudFsgMCBdLCBcImh0bWxcIiApICkge1xuXHRcdFx0XHRwYXJlbnRPZmZzZXQgPSBvZmZzZXRQYXJlbnQub2Zmc2V0KCk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEFkZCBvZmZzZXRQYXJlbnQgYm9yZGVyc1xuXHRcdFx0cGFyZW50T2Zmc2V0LnRvcCArPSBqUXVlcnkuY3NzKCBvZmZzZXRQYXJlbnRbIDAgXSwgXCJib3JkZXJUb3BXaWR0aFwiLCB0cnVlICk7XG5cdFx0XHRwYXJlbnRPZmZzZXQubGVmdCArPSBqUXVlcnkuY3NzKCBvZmZzZXRQYXJlbnRbIDAgXSwgXCJib3JkZXJMZWZ0V2lkdGhcIiwgdHJ1ZSApO1xuXHRcdH1cblxuXHRcdC8vIFN1YnRyYWN0IHBhcmVudCBvZmZzZXRzIGFuZCBlbGVtZW50IG1hcmdpbnNcblx0XHRyZXR1cm4ge1xuXHRcdFx0dG9wOiBvZmZzZXQudG9wIC0gcGFyZW50T2Zmc2V0LnRvcCAtIGpRdWVyeS5jc3MoIGVsZW0sIFwibWFyZ2luVG9wXCIsIHRydWUgKSxcblx0XHRcdGxlZnQ6IG9mZnNldC5sZWZ0IC0gcGFyZW50T2Zmc2V0LmxlZnQgLSBqUXVlcnkuY3NzKCBlbGVtLCBcIm1hcmdpbkxlZnRcIiwgdHJ1ZSApXG5cdFx0fTtcblx0fSxcblxuXHRvZmZzZXRQYXJlbnQ6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLm1hcChmdW5jdGlvbigpIHtcblx0XHRcdHZhciBvZmZzZXRQYXJlbnQgPSB0aGlzLm9mZnNldFBhcmVudCB8fCBkb2NFbGVtO1xuXG5cdFx0XHR3aGlsZSAoIG9mZnNldFBhcmVudCAmJiAoICFqUXVlcnkubm9kZU5hbWUoIG9mZnNldFBhcmVudCwgXCJodG1sXCIgKSAmJiBqUXVlcnkuY3NzKCBvZmZzZXRQYXJlbnQsIFwicG9zaXRpb25cIiApID09PSBcInN0YXRpY1wiICkgKSB7XG5cdFx0XHRcdG9mZnNldFBhcmVudCA9IG9mZnNldFBhcmVudC5vZmZzZXRQYXJlbnQ7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBvZmZzZXRQYXJlbnQgfHwgZG9jRWxlbTtcblx0XHR9KTtcblx0fVxufSk7XG5cbi8vIENyZWF0ZSBzY3JvbGxMZWZ0IGFuZCBzY3JvbGxUb3AgbWV0aG9kc1xualF1ZXJ5LmVhY2goIHsgc2Nyb2xsTGVmdDogXCJwYWdlWE9mZnNldFwiLCBzY3JvbGxUb3A6IFwicGFnZVlPZmZzZXRcIiB9LCBmdW5jdGlvbiggbWV0aG9kLCBwcm9wICkge1xuXHR2YXIgdG9wID0gXCJwYWdlWU9mZnNldFwiID09PSBwcm9wO1xuXG5cdGpRdWVyeS5mblsgbWV0aG9kIF0gPSBmdW5jdGlvbiggdmFsICkge1xuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCBlbGVtLCBtZXRob2QsIHZhbCApIHtcblx0XHRcdHZhciB3aW4gPSBnZXRXaW5kb3coIGVsZW0gKTtcblxuXHRcdFx0aWYgKCB2YWwgPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0cmV0dXJuIHdpbiA/IHdpblsgcHJvcCBdIDogZWxlbVsgbWV0aG9kIF07XG5cdFx0XHR9XG5cblx0XHRcdGlmICggd2luICkge1xuXHRcdFx0XHR3aW4uc2Nyb2xsVG8oXG5cdFx0XHRcdFx0IXRvcCA/IHZhbCA6IHdpbmRvdy5wYWdlWE9mZnNldCxcblx0XHRcdFx0XHR0b3AgPyB2YWwgOiB3aW5kb3cucGFnZVlPZmZzZXRcblx0XHRcdFx0KTtcblxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZWxlbVsgbWV0aG9kIF0gPSB2YWw7XG5cdFx0XHR9XG5cdFx0fSwgbWV0aG9kLCB2YWwsIGFyZ3VtZW50cy5sZW5ndGgsIG51bGwgKTtcblx0fTtcbn0pO1xuXG4vLyBTdXBwb3J0OiBTYWZhcmk8NyssIENocm9tZTwzNytcbi8vIEFkZCB0aGUgdG9wL2xlZnQgY3NzSG9va3MgdXNpbmcgalF1ZXJ5LmZuLnBvc2l0aW9uXG4vLyBXZWJraXQgYnVnOiBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MjkwODRcbi8vIEJsaW5rIGJ1ZzogaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTIyOTI4MFxuLy8gZ2V0Q29tcHV0ZWRTdHlsZSByZXR1cm5zIHBlcmNlbnQgd2hlbiBzcGVjaWZpZWQgZm9yIHRvcC9sZWZ0L2JvdHRvbS9yaWdodDtcbi8vIHJhdGhlciB0aGFuIG1ha2UgdGhlIGNzcyBtb2R1bGUgZGVwZW5kIG9uIHRoZSBvZmZzZXQgbW9kdWxlLCBqdXN0IGNoZWNrIGZvciBpdCBoZXJlXG5qUXVlcnkuZWFjaCggWyBcInRvcFwiLCBcImxlZnRcIiBdLCBmdW5jdGlvbiggaSwgcHJvcCApIHtcblx0alF1ZXJ5LmNzc0hvb2tzWyBwcm9wIF0gPSBhZGRHZXRIb29rSWYoIHN1cHBvcnQucGl4ZWxQb3NpdGlvbixcblx0XHRmdW5jdGlvbiggZWxlbSwgY29tcHV0ZWQgKSB7XG5cdFx0XHRpZiAoIGNvbXB1dGVkICkge1xuXHRcdFx0XHRjb21wdXRlZCA9IGN1ckNTUyggZWxlbSwgcHJvcCApO1xuXHRcdFx0XHQvLyBJZiBjdXJDU1MgcmV0dXJucyBwZXJjZW50YWdlLCBmYWxsYmFjayB0byBvZmZzZXRcblx0XHRcdFx0cmV0dXJuIHJudW1ub25weC50ZXN0KCBjb21wdXRlZCApID9cblx0XHRcdFx0XHRqUXVlcnkoIGVsZW0gKS5wb3NpdGlvbigpWyBwcm9wIF0gKyBcInB4XCIgOlxuXHRcdFx0XHRcdGNvbXB1dGVkO1xuXHRcdFx0fVxuXHRcdH1cblx0KTtcbn0pO1xuXG5cbi8vIENyZWF0ZSBpbm5lckhlaWdodCwgaW5uZXJXaWR0aCwgaGVpZ2h0LCB3aWR0aCwgb3V0ZXJIZWlnaHQgYW5kIG91dGVyV2lkdGggbWV0aG9kc1xualF1ZXJ5LmVhY2goIHsgSGVpZ2h0OiBcImhlaWdodFwiLCBXaWR0aDogXCJ3aWR0aFwiIH0sIGZ1bmN0aW9uKCBuYW1lLCB0eXBlICkge1xuXHRqUXVlcnkuZWFjaCggeyBwYWRkaW5nOiBcImlubmVyXCIgKyBuYW1lLCBjb250ZW50OiB0eXBlLCBcIlwiOiBcIm91dGVyXCIgKyBuYW1lIH0sIGZ1bmN0aW9uKCBkZWZhdWx0RXh0cmEsIGZ1bmNOYW1lICkge1xuXHRcdC8vIE1hcmdpbiBpcyBvbmx5IGZvciBvdXRlckhlaWdodCwgb3V0ZXJXaWR0aFxuXHRcdGpRdWVyeS5mblsgZnVuY05hbWUgXSA9IGZ1bmN0aW9uKCBtYXJnaW4sIHZhbHVlICkge1xuXHRcdFx0dmFyIGNoYWluYWJsZSA9IGFyZ3VtZW50cy5sZW5ndGggJiYgKCBkZWZhdWx0RXh0cmEgfHwgdHlwZW9mIG1hcmdpbiAhPT0gXCJib29sZWFuXCIgKSxcblx0XHRcdFx0ZXh0cmEgPSBkZWZhdWx0RXh0cmEgfHwgKCBtYXJnaW4gPT09IHRydWUgfHwgdmFsdWUgPT09IHRydWUgPyBcIm1hcmdpblwiIDogXCJib3JkZXJcIiApO1xuXG5cdFx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBmdW5jdGlvbiggZWxlbSwgdHlwZSwgdmFsdWUgKSB7XG5cdFx0XHRcdHZhciBkb2M7XG5cblx0XHRcdFx0aWYgKCBqUXVlcnkuaXNXaW5kb3coIGVsZW0gKSApIHtcblx0XHRcdFx0XHQvLyBBcyBvZiA1LzgvMjAxMiB0aGlzIHdpbGwgeWllbGQgaW5jb3JyZWN0IHJlc3VsdHMgZm9yIE1vYmlsZSBTYWZhcmksIGJ1dCB0aGVyZVxuXHRcdFx0XHRcdC8vIGlzbid0IGEgd2hvbGUgbG90IHdlIGNhbiBkby4gU2VlIHB1bGwgcmVxdWVzdCBhdCB0aGlzIFVSTCBmb3IgZGlzY3Vzc2lvbjpcblx0XHRcdFx0XHQvLyBodHRwczovL2dpdGh1Yi5jb20vanF1ZXJ5L2pxdWVyeS9wdWxsLzc2NFxuXHRcdFx0XHRcdHJldHVybiBlbGVtLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudFsgXCJjbGllbnRcIiArIG5hbWUgXTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEdldCBkb2N1bWVudCB3aWR0aCBvciBoZWlnaHRcblx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSA5ICkge1xuXHRcdFx0XHRcdGRvYyA9IGVsZW0uZG9jdW1lbnRFbGVtZW50O1xuXG5cdFx0XHRcdFx0Ly8gRWl0aGVyIHNjcm9sbFtXaWR0aC9IZWlnaHRdIG9yIG9mZnNldFtXaWR0aC9IZWlnaHRdIG9yIGNsaWVudFtXaWR0aC9IZWlnaHRdLFxuXHRcdFx0XHRcdC8vIHdoaWNoZXZlciBpcyBncmVhdGVzdFxuXHRcdFx0XHRcdHJldHVybiBNYXRoLm1heChcblx0XHRcdFx0XHRcdGVsZW0uYm9keVsgXCJzY3JvbGxcIiArIG5hbWUgXSwgZG9jWyBcInNjcm9sbFwiICsgbmFtZSBdLFxuXHRcdFx0XHRcdFx0ZWxlbS5ib2R5WyBcIm9mZnNldFwiICsgbmFtZSBdLCBkb2NbIFwib2Zmc2V0XCIgKyBuYW1lIF0sXG5cdFx0XHRcdFx0XHRkb2NbIFwiY2xpZW50XCIgKyBuYW1lIF1cblx0XHRcdFx0XHQpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIHZhbHVlID09PSB1bmRlZmluZWQgP1xuXHRcdFx0XHRcdC8vIEdldCB3aWR0aCBvciBoZWlnaHQgb24gdGhlIGVsZW1lbnQsIHJlcXVlc3RpbmcgYnV0IG5vdCBmb3JjaW5nIHBhcnNlRmxvYXRcblx0XHRcdFx0XHRqUXVlcnkuY3NzKCBlbGVtLCB0eXBlLCBleHRyYSApIDpcblxuXHRcdFx0XHRcdC8vIFNldCB3aWR0aCBvciBoZWlnaHQgb24gdGhlIGVsZW1lbnRcblx0XHRcdFx0XHRqUXVlcnkuc3R5bGUoIGVsZW0sIHR5cGUsIHZhbHVlLCBleHRyYSApO1xuXHRcdFx0fSwgdHlwZSwgY2hhaW5hYmxlID8gbWFyZ2luIDogdW5kZWZpbmVkLCBjaGFpbmFibGUsIG51bGwgKTtcblx0XHR9O1xuXHR9KTtcbn0pO1xuXG5cbi8vIFRoZSBudW1iZXIgb2YgZWxlbWVudHMgY29udGFpbmVkIGluIHRoZSBtYXRjaGVkIGVsZW1lbnQgc2V0XG5qUXVlcnkuZm4uc2l6ZSA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gdGhpcy5sZW5ndGg7XG59O1xuXG5qUXVlcnkuZm4uYW5kU2VsZiA9IGpRdWVyeS5mbi5hZGRCYWNrO1xuXG5cblxuXG4vLyBSZWdpc3RlciBhcyBhIG5hbWVkIEFNRCBtb2R1bGUsIHNpbmNlIGpRdWVyeSBjYW4gYmUgY29uY2F0ZW5hdGVkIHdpdGggb3RoZXJcbi8vIGZpbGVzIHRoYXQgbWF5IHVzZSBkZWZpbmUsIGJ1dCBub3QgdmlhIGEgcHJvcGVyIGNvbmNhdGVuYXRpb24gc2NyaXB0IHRoYXRcbi8vIHVuZGVyc3RhbmRzIGFub255bW91cyBBTUQgbW9kdWxlcy4gQSBuYW1lZCBBTUQgaXMgc2FmZXN0IGFuZCBtb3N0IHJvYnVzdFxuLy8gd2F5IHRvIHJlZ2lzdGVyLiBMb3dlcmNhc2UganF1ZXJ5IGlzIHVzZWQgYmVjYXVzZSBBTUQgbW9kdWxlIG5hbWVzIGFyZVxuLy8gZGVyaXZlZCBmcm9tIGZpbGUgbmFtZXMsIGFuZCBqUXVlcnkgaXMgbm9ybWFsbHkgZGVsaXZlcmVkIGluIGEgbG93ZXJjYXNlXG4vLyBmaWxlIG5hbWUuIERvIHRoaXMgYWZ0ZXIgY3JlYXRpbmcgdGhlIGdsb2JhbCBzbyB0aGF0IGlmIGFuIEFNRCBtb2R1bGUgd2FudHNcbi8vIHRvIGNhbGwgbm9Db25mbGljdCB0byBoaWRlIHRoaXMgdmVyc2lvbiBvZiBqUXVlcnksIGl0IHdpbGwgd29yay5cblxuLy8gTm90ZSB0aGF0IGZvciBtYXhpbXVtIHBvcnRhYmlsaXR5LCBsaWJyYXJpZXMgdGhhdCBhcmUgbm90IGpRdWVyeSBzaG91bGRcbi8vIGRlY2xhcmUgdGhlbXNlbHZlcyBhcyBhbm9ueW1vdXMgbW9kdWxlcywgYW5kIGF2b2lkIHNldHRpbmcgYSBnbG9iYWwgaWYgYW5cbi8vIEFNRCBsb2FkZXIgaXMgcHJlc2VudC4galF1ZXJ5IGlzIGEgc3BlY2lhbCBjYXNlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlXG4vLyBodHRwczovL2dpdGh1Yi5jb20vanJidXJrZS9yZXF1aXJlanMvd2lraS9VcGRhdGluZy1leGlzdGluZy1saWJyYXJpZXMjd2lraS1hbm9uXG5cbmlmICggdHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQgKSB7XG5cdGRlZmluZSggXCJqcXVlcnlcIiwgW10sIGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBqUXVlcnk7XG5cdH0pO1xufVxuXG5cblxuXG52YXJcblx0Ly8gTWFwIG92ZXIgalF1ZXJ5IGluIGNhc2Ugb2Ygb3ZlcndyaXRlXG5cdF9qUXVlcnkgPSB3aW5kb3cualF1ZXJ5LFxuXG5cdC8vIE1hcCBvdmVyIHRoZSAkIGluIGNhc2Ugb2Ygb3ZlcndyaXRlXG5cdF8kID0gd2luZG93LiQ7XG5cbmpRdWVyeS5ub0NvbmZsaWN0ID0gZnVuY3Rpb24oIGRlZXAgKSB7XG5cdGlmICggd2luZG93LiQgPT09IGpRdWVyeSApIHtcblx0XHR3aW5kb3cuJCA9IF8kO1xuXHR9XG5cblx0aWYgKCBkZWVwICYmIHdpbmRvdy5qUXVlcnkgPT09IGpRdWVyeSApIHtcblx0XHR3aW5kb3cualF1ZXJ5ID0gX2pRdWVyeTtcblx0fVxuXG5cdHJldHVybiBqUXVlcnk7XG59O1xuXG4vLyBFeHBvc2UgalF1ZXJ5IGFuZCAkIGlkZW50aWZpZXJzLCBldmVuIGluIEFNRFxuLy8gKCM3MTAyI2NvbW1lbnQ6MTAsIGh0dHBzOi8vZ2l0aHViLmNvbS9qcXVlcnkvanF1ZXJ5L3B1bGwvNTU3KVxuLy8gYW5kIENvbW1vbkpTIGZvciBicm93c2VyIGVtdWxhdG9ycyAoIzEzNTY2KVxuaWYgKCB0eXBlb2Ygbm9HbG9iYWwgPT09IHN0cnVuZGVmaW5lZCApIHtcblx0d2luZG93LmpRdWVyeSA9IHdpbmRvdy4kID0galF1ZXJ5O1xufVxuXG5cblxuXG5yZXR1cm4galF1ZXJ5O1xuXG59KSk7XG4iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIHlhbWwgPSByZXF1aXJlKCcuL2xpYi9qcy15YW1sLmpzJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSB5YW1sO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBsb2FkZXIgPSByZXF1aXJlKCcuL2pzLXlhbWwvbG9hZGVyJyk7XG52YXIgZHVtcGVyID0gcmVxdWlyZSgnLi9qcy15YW1sL2R1bXBlcicpO1xuXG5cbmZ1bmN0aW9uIGRlcHJlY2F0ZWQobmFtZSkge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHRocm93IG5ldyBFcnJvcignRnVuY3Rpb24gJyArIG5hbWUgKyAnIGlzIGRlcHJlY2F0ZWQgYW5kIGNhbm5vdCBiZSB1c2VkLicpO1xuICB9O1xufVxuXG5cbm1vZHVsZS5leHBvcnRzLlR5cGUgICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL2pzLXlhbWwvdHlwZScpO1xubW9kdWxlLmV4cG9ydHMuU2NoZW1hICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEnKTtcbm1vZHVsZS5leHBvcnRzLkZBSUxTQUZFX1NDSEVNQSAgICAgPSByZXF1aXJlKCcuL2pzLXlhbWwvc2NoZW1hL2ZhaWxzYWZlJyk7XG5tb2R1bGUuZXhwb3J0cy5KU09OX1NDSEVNQSAgICAgICAgID0gcmVxdWlyZSgnLi9qcy15YW1sL3NjaGVtYS9qc29uJyk7XG5tb2R1bGUuZXhwb3J0cy5DT1JFX1NDSEVNQSAgICAgICAgID0gcmVxdWlyZSgnLi9qcy15YW1sL3NjaGVtYS9jb3JlJyk7XG5tb2R1bGUuZXhwb3J0cy5ERUZBVUxUX1NBRkVfU0NIRU1BID0gcmVxdWlyZSgnLi9qcy15YW1sL3NjaGVtYS9kZWZhdWx0X3NhZmUnKTtcbm1vZHVsZS5leHBvcnRzLkRFRkFVTFRfRlVMTF9TQ0hFTUEgPSByZXF1aXJlKCcuL2pzLXlhbWwvc2NoZW1hL2RlZmF1bHRfZnVsbCcpO1xubW9kdWxlLmV4cG9ydHMubG9hZCAgICAgICAgICAgICAgICA9IGxvYWRlci5sb2FkO1xubW9kdWxlLmV4cG9ydHMubG9hZEFsbCAgICAgICAgICAgICA9IGxvYWRlci5sb2FkQWxsO1xubW9kdWxlLmV4cG9ydHMuc2FmZUxvYWQgICAgICAgICAgICA9IGxvYWRlci5zYWZlTG9hZDtcbm1vZHVsZS5leHBvcnRzLnNhZmVMb2FkQWxsICAgICAgICAgPSBsb2FkZXIuc2FmZUxvYWRBbGw7XG5tb2R1bGUuZXhwb3J0cy5kdW1wICAgICAgICAgICAgICAgID0gZHVtcGVyLmR1bXA7XG5tb2R1bGUuZXhwb3J0cy5zYWZlRHVtcCAgICAgICAgICAgID0gZHVtcGVyLnNhZmVEdW1wO1xubW9kdWxlLmV4cG9ydHMuWUFNTEV4Y2VwdGlvbiAgICAgICA9IHJlcXVpcmUoJy4vanMteWFtbC9leGNlcHRpb24nKTtcblxuLy8gRGVwcmVjYXJlZCBzY2hlbWEgbmFtZXMgZnJvbSBKUy1ZQU1MIDIuMC54XG5tb2R1bGUuZXhwb3J0cy5NSU5JTUFMX1NDSEVNQSA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvZmFpbHNhZmUnKTtcbm1vZHVsZS5leHBvcnRzLlNBRkVfU0NIRU1BICAgID0gcmVxdWlyZSgnLi9qcy15YW1sL3NjaGVtYS9kZWZhdWx0X3NhZmUnKTtcbm1vZHVsZS5leHBvcnRzLkRFRkFVTFRfU0NIRU1BID0gcmVxdWlyZSgnLi9qcy15YW1sL3NjaGVtYS9kZWZhdWx0X2Z1bGwnKTtcblxuLy8gRGVwcmVjYXRlZCBmdW5jdGlvbnMgZnJvbSBKUy1ZQU1MIDEueC54XG5tb2R1bGUuZXhwb3J0cy5zY2FuICAgICAgICAgICA9IGRlcHJlY2F0ZWQoJ3NjYW4nKTtcbm1vZHVsZS5leHBvcnRzLnBhcnNlICAgICAgICAgID0gZGVwcmVjYXRlZCgncGFyc2UnKTtcbm1vZHVsZS5leHBvcnRzLmNvbXBvc2UgICAgICAgID0gZGVwcmVjYXRlZCgnY29tcG9zZScpO1xubW9kdWxlLmV4cG9ydHMuYWRkQ29uc3RydWN0b3IgPSBkZXByZWNhdGVkKCdhZGRDb25zdHJ1Y3RvcicpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbmZ1bmN0aW9uIGlzTm90aGluZyhzdWJqZWN0KSB7XG4gIHJldHVybiAodHlwZW9mIHN1YmplY3QgPT09ICd1bmRlZmluZWQnKSB8fCAobnVsbCA9PT0gc3ViamVjdCk7XG59XG5cblxuZnVuY3Rpb24gaXNPYmplY3Qoc3ViamVjdCkge1xuICByZXR1cm4gKHR5cGVvZiBzdWJqZWN0ID09PSAnb2JqZWN0JykgJiYgKG51bGwgIT09IHN1YmplY3QpO1xufVxuXG5cbmZ1bmN0aW9uIHRvQXJyYXkoc2VxdWVuY2UpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkoc2VxdWVuY2UpKSB7XG4gICAgcmV0dXJuIHNlcXVlbmNlO1xuICB9IGVsc2UgaWYgKGlzTm90aGluZyhzZXF1ZW5jZSkpIHtcbiAgICByZXR1cm4gW107XG4gIH1cbiAgcmV0dXJuIFsgc2VxdWVuY2UgXTtcbn1cblxuXG5mdW5jdGlvbiBleHRlbmQodGFyZ2V0LCBzb3VyY2UpIHtcbiAgdmFyIGluZGV4LCBsZW5ndGgsIGtleSwgc291cmNlS2V5cztcblxuICBpZiAoc291cmNlKSB7XG4gICAgc291cmNlS2V5cyA9IE9iamVjdC5rZXlzKHNvdXJjZSk7XG5cbiAgICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gc291cmNlS2V5cy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgICBrZXkgPSBzb3VyY2VLZXlzW2luZGV4XTtcbiAgICAgIHRhcmdldFtrZXldID0gc291cmNlW2tleV07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRhcmdldDtcbn1cblxuXG5mdW5jdGlvbiByZXBlYXQoc3RyaW5nLCBjb3VudCkge1xuICB2YXIgcmVzdWx0ID0gJycsIGN5Y2xlO1xuXG4gIGZvciAoY3ljbGUgPSAwOyBjeWNsZSA8IGNvdW50OyBjeWNsZSArPSAxKSB7XG4gICAgcmVzdWx0ICs9IHN0cmluZztcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cblxuZnVuY3Rpb24gaXNOZWdhdGl2ZVplcm8obnVtYmVyKSB7XG4gIHJldHVybiAoMCA9PT0gbnVtYmVyKSAmJiAoTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZID09PSAxIC8gbnVtYmVyKTtcbn1cblxuXG5tb2R1bGUuZXhwb3J0cy5pc05vdGhpbmcgICAgICA9IGlzTm90aGluZztcbm1vZHVsZS5leHBvcnRzLmlzT2JqZWN0ICAgICAgID0gaXNPYmplY3Q7XG5tb2R1bGUuZXhwb3J0cy50b0FycmF5ICAgICAgICA9IHRvQXJyYXk7XG5tb2R1bGUuZXhwb3J0cy5yZXBlYXQgICAgICAgICA9IHJlcGVhdDtcbm1vZHVsZS5leHBvcnRzLmlzTmVnYXRpdmVaZXJvID0gaXNOZWdhdGl2ZVplcm87XG5tb2R1bGUuZXhwb3J0cy5leHRlbmQgICAgICAgICA9IGV4dGVuZDtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyplc2xpbnQtZGlzYWJsZSBuby11c2UtYmVmb3JlLWRlZmluZSovXG5cbnZhciBjb21tb24gICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9jb21tb24nKTtcbnZhciBZQU1MRXhjZXB0aW9uICAgICAgID0gcmVxdWlyZSgnLi9leGNlcHRpb24nKTtcbnZhciBERUZBVUxUX0ZVTExfU0NIRU1BID0gcmVxdWlyZSgnLi9zY2hlbWEvZGVmYXVsdF9mdWxsJyk7XG52YXIgREVGQVVMVF9TQUZFX1NDSEVNQSA9IHJlcXVpcmUoJy4vc2NoZW1hL2RlZmF1bHRfc2FmZScpO1xuXG52YXIgX3RvU3RyaW5nICAgICAgID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcbnZhciBfaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG52YXIgQ0hBUl9UQUIgICAgICAgICAgICAgICAgICA9IDB4MDk7IC8qIFRhYiAqL1xudmFyIENIQVJfTElORV9GRUVEICAgICAgICAgICAgPSAweDBBOyAvKiBMRiAqL1xudmFyIENIQVJfQ0FSUklBR0VfUkVUVVJOICAgICAgPSAweDBEOyAvKiBDUiAqL1xudmFyIENIQVJfU1BBQ0UgICAgICAgICAgICAgICAgPSAweDIwOyAvKiBTcGFjZSAqL1xudmFyIENIQVJfRVhDTEFNQVRJT04gICAgICAgICAgPSAweDIxOyAvKiAhICovXG52YXIgQ0hBUl9ET1VCTEVfUVVPVEUgICAgICAgICA9IDB4MjI7IC8qIFwiICovXG52YXIgQ0hBUl9TSEFSUCAgICAgICAgICAgICAgICA9IDB4MjM7IC8qICMgKi9cbnZhciBDSEFSX1BFUkNFTlQgICAgICAgICAgICAgID0gMHgyNTsgLyogJSAqL1xudmFyIENIQVJfQU1QRVJTQU5EICAgICAgICAgICAgPSAweDI2OyAvKiAmICovXG52YXIgQ0hBUl9TSU5HTEVfUVVPVEUgICAgICAgICA9IDB4Mjc7IC8qICcgKi9cbnZhciBDSEFSX0FTVEVSSVNLICAgICAgICAgICAgID0gMHgyQTsgLyogKiAqL1xudmFyIENIQVJfQ09NTUEgICAgICAgICAgICAgICAgPSAweDJDOyAvKiAsICovXG52YXIgQ0hBUl9NSU5VUyAgICAgICAgICAgICAgICA9IDB4MkQ7IC8qIC0gKi9cbnZhciBDSEFSX0NPTE9OICAgICAgICAgICAgICAgID0gMHgzQTsgLyogOiAqL1xudmFyIENIQVJfR1JFQVRFUl9USEFOICAgICAgICAgPSAweDNFOyAvKiA+ICovXG52YXIgQ0hBUl9RVUVTVElPTiAgICAgICAgICAgICA9IDB4M0Y7IC8qID8gKi9cbnZhciBDSEFSX0NPTU1FUkNJQUxfQVQgICAgICAgID0gMHg0MDsgLyogQCAqL1xudmFyIENIQVJfTEVGVF9TUVVBUkVfQlJBQ0tFVCAgPSAweDVCOyAvKiBbICovXG52YXIgQ0hBUl9SSUdIVF9TUVVBUkVfQlJBQ0tFVCA9IDB4NUQ7IC8qIF0gKi9cbnZhciBDSEFSX0dSQVZFX0FDQ0VOVCAgICAgICAgID0gMHg2MDsgLyogYCAqL1xudmFyIENIQVJfTEVGVF9DVVJMWV9CUkFDS0VUICAgPSAweDdCOyAvKiB7ICovXG52YXIgQ0hBUl9WRVJUSUNBTF9MSU5FICAgICAgICA9IDB4N0M7IC8qIHwgKi9cbnZhciBDSEFSX1JJR0hUX0NVUkxZX0JSQUNLRVQgID0gMHg3RDsgLyogfSAqL1xuXG52YXIgRVNDQVBFX1NFUVVFTkNFUyA9IHt9O1xuXG5FU0NBUEVfU0VRVUVOQ0VTWzB4MDBdICAgPSAnXFxcXDAnO1xuRVNDQVBFX1NFUVVFTkNFU1sweDA3XSAgID0gJ1xcXFxhJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgwOF0gICA9ICdcXFxcYic7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MDldICAgPSAnXFxcXHQnO1xuRVNDQVBFX1NFUVVFTkNFU1sweDBBXSAgID0gJ1xcXFxuJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgwQl0gICA9ICdcXFxcdic7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MENdICAgPSAnXFxcXGYnO1xuRVNDQVBFX1NFUVVFTkNFU1sweDBEXSAgID0gJ1xcXFxyJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgxQl0gICA9ICdcXFxcZSc7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MjJdICAgPSAnXFxcXFwiJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHg1Q10gICA9ICdcXFxcXFxcXCc7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4ODVdICAgPSAnXFxcXE4nO1xuRVNDQVBFX1NFUVVFTkNFU1sweEEwXSAgID0gJ1xcXFxfJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgyMDI4XSA9ICdcXFxcTCc7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MjAyOV0gPSAnXFxcXFAnO1xuXG52YXIgREVQUkVDQVRFRF9CT09MRUFOU19TWU5UQVggPSBbXG4gICd5JywgJ1knLCAneWVzJywgJ1llcycsICdZRVMnLCAnb24nLCAnT24nLCAnT04nLFxuICAnbicsICdOJywgJ25vJywgJ05vJywgJ05PJywgJ29mZicsICdPZmYnLCAnT0ZGJ1xuXTtcblxuZnVuY3Rpb24gY29tcGlsZVN0eWxlTWFwKHNjaGVtYSwgbWFwKSB7XG4gIHZhciByZXN1bHQsIGtleXMsIGluZGV4LCBsZW5ndGgsIHRhZywgc3R5bGUsIHR5cGU7XG5cbiAgaWYgKG51bGwgPT09IG1hcCkge1xuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIHJlc3VsdCA9IHt9O1xuICBrZXlzID0gT2JqZWN0LmtleXMobWFwKTtcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0ga2V5cy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgdGFnID0ga2V5c1tpbmRleF07XG4gICAgc3R5bGUgPSBTdHJpbmcobWFwW3RhZ10pO1xuXG4gICAgaWYgKCchIScgPT09IHRhZy5zbGljZSgwLCAyKSkge1xuICAgICAgdGFnID0gJ3RhZzp5YW1sLm9yZywyMDAyOicgKyB0YWcuc2xpY2UoMik7XG4gICAgfVxuXG4gICAgdHlwZSA9IHNjaGVtYS5jb21waWxlZFR5cGVNYXBbdGFnXTtcblxuICAgIGlmICh0eXBlICYmIF9oYXNPd25Qcm9wZXJ0eS5jYWxsKHR5cGUuc3R5bGVBbGlhc2VzLCBzdHlsZSkpIHtcbiAgICAgIHN0eWxlID0gdHlwZS5zdHlsZUFsaWFzZXNbc3R5bGVdO1xuICAgIH1cblxuICAgIHJlc3VsdFt0YWddID0gc3R5bGU7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBlbmNvZGVIZXgoY2hhcmFjdGVyKSB7XG4gIHZhciBzdHJpbmcsIGhhbmRsZSwgbGVuZ3RoO1xuXG4gIHN0cmluZyA9IGNoYXJhY3Rlci50b1N0cmluZygxNikudG9VcHBlckNhc2UoKTtcblxuICBpZiAoY2hhcmFjdGVyIDw9IDB4RkYpIHtcbiAgICBoYW5kbGUgPSAneCc7XG4gICAgbGVuZ3RoID0gMjtcbiAgfSBlbHNlIGlmIChjaGFyYWN0ZXIgPD0gMHhGRkZGKSB7XG4gICAgaGFuZGxlID0gJ3UnO1xuICAgIGxlbmd0aCA9IDQ7XG4gIH0gZWxzZSBpZiAoY2hhcmFjdGVyIDw9IDB4RkZGRkZGRkYpIHtcbiAgICBoYW5kbGUgPSAnVSc7XG4gICAgbGVuZ3RoID0gODtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignY29kZSBwb2ludCB3aXRoaW4gYSBzdHJpbmcgbWF5IG5vdCBiZSBncmVhdGVyIHRoYW4gMHhGRkZGRkZGRicpO1xuICB9XG5cbiAgcmV0dXJuICdcXFxcJyArIGhhbmRsZSArIGNvbW1vbi5yZXBlYXQoJzAnLCBsZW5ndGggLSBzdHJpbmcubGVuZ3RoKSArIHN0cmluZztcbn1cblxuZnVuY3Rpb24gU3RhdGUob3B0aW9ucykge1xuICB0aGlzLnNjaGVtYSAgICAgID0gb3B0aW9uc1snc2NoZW1hJ10gfHwgREVGQVVMVF9GVUxMX1NDSEVNQTtcbiAgdGhpcy5pbmRlbnQgICAgICA9IE1hdGgubWF4KDEsIChvcHRpb25zWydpbmRlbnQnXSB8fCAyKSk7XG4gIHRoaXMuc2tpcEludmFsaWQgPSBvcHRpb25zWydza2lwSW52YWxpZCddIHx8IGZhbHNlO1xuICB0aGlzLmZsb3dMZXZlbCAgID0gKGNvbW1vbi5pc05vdGhpbmcob3B0aW9uc1snZmxvd0xldmVsJ10pID8gLTEgOiBvcHRpb25zWydmbG93TGV2ZWwnXSk7XG4gIHRoaXMuc3R5bGVNYXAgICAgPSBjb21waWxlU3R5bGVNYXAodGhpcy5zY2hlbWEsIG9wdGlvbnNbJ3N0eWxlcyddIHx8IG51bGwpO1xuICB0aGlzLnNvcnRLZXlzICAgID0gb3B0aW9uc1snc29ydEtleXMnXSB8fCBmYWxzZTtcblxuICB0aGlzLmltcGxpY2l0VHlwZXMgPSB0aGlzLnNjaGVtYS5jb21waWxlZEltcGxpY2l0O1xuICB0aGlzLmV4cGxpY2l0VHlwZXMgPSB0aGlzLnNjaGVtYS5jb21waWxlZEV4cGxpY2l0O1xuXG4gIHRoaXMudGFnID0gbnVsbDtcbiAgdGhpcy5yZXN1bHQgPSAnJztcblxuICB0aGlzLmR1cGxpY2F0ZXMgPSBbXTtcbiAgdGhpcy51c2VkRHVwbGljYXRlcyA9IG51bGw7XG59XG5cbmZ1bmN0aW9uIGluZGVudFN0cmluZyhzdHJpbmcsIHNwYWNlcykge1xuICB2YXIgaW5kID0gY29tbW9uLnJlcGVhdCgnICcsIHNwYWNlcyksXG4gICAgICBwb3NpdGlvbiA9IDAsXG4gICAgICBuZXh0ID0gLTEsXG4gICAgICByZXN1bHQgPSAnJyxcbiAgICAgIGxpbmUsXG4gICAgICBsZW5ndGggPSBzdHJpbmcubGVuZ3RoO1xuXG4gIHdoaWxlIChwb3NpdGlvbiA8IGxlbmd0aCkge1xuICAgIG5leHQgPSBzdHJpbmcuaW5kZXhPZignXFxuJywgcG9zaXRpb24pO1xuICAgIGlmIChuZXh0ID09PSAtMSkge1xuICAgICAgbGluZSA9IHN0cmluZy5zbGljZShwb3NpdGlvbik7XG4gICAgICBwb3NpdGlvbiA9IGxlbmd0aDtcbiAgICB9IGVsc2Uge1xuICAgICAgbGluZSA9IHN0cmluZy5zbGljZShwb3NpdGlvbiwgbmV4dCArIDEpO1xuICAgICAgcG9zaXRpb24gPSBuZXh0ICsgMTtcbiAgICB9XG4gICAgaWYgKGxpbmUubGVuZ3RoICYmIGxpbmUgIT09ICdcXG4nKSB7XG4gICAgICByZXN1bHQgKz0gaW5kO1xuICAgIH1cbiAgICByZXN1bHQgKz0gbGluZTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIGdlbmVyYXRlTmV4dExpbmUoc3RhdGUsIGxldmVsKSB7XG4gIHJldHVybiAnXFxuJyArIGNvbW1vbi5yZXBlYXQoJyAnLCBzdGF0ZS5pbmRlbnQgKiBsZXZlbCk7XG59XG5cbmZ1bmN0aW9uIHRlc3RJbXBsaWNpdFJlc29sdmluZyhzdGF0ZSwgc3RyKSB7XG4gIHZhciBpbmRleCwgbGVuZ3RoLCB0eXBlO1xuXG4gIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBzdGF0ZS5pbXBsaWNpdFR5cGVzLmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICB0eXBlID0gc3RhdGUuaW1wbGljaXRUeXBlc1tpbmRleF07XG5cbiAgICBpZiAodHlwZS5yZXNvbHZlKHN0cikpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gU3RyaW5nQnVpbGRlcihzb3VyY2UpIHtcbiAgdGhpcy5zb3VyY2UgPSBzb3VyY2U7XG4gIHRoaXMucmVzdWx0ID0gJyc7XG4gIHRoaXMuY2hlY2twb2ludCA9IDA7XG59XG5cblN0cmluZ0J1aWxkZXIucHJvdG90eXBlLnRha2VVcFRvID0gZnVuY3Rpb24gKHBvc2l0aW9uKSB7XG4gIHZhciBlcjtcblxuICBpZiAocG9zaXRpb24gPCB0aGlzLmNoZWNrcG9pbnQpIHtcbiAgICBlciA9IG5ldyBFcnJvcigncG9zaXRpb24gc2hvdWxkIGJlID4gY2hlY2twb2ludCcpO1xuICAgIGVyLnBvc2l0aW9uID0gcG9zaXRpb247XG4gICAgZXIuY2hlY2twb2ludCA9IHRoaXMuY2hlY2twb2ludDtcbiAgICB0aHJvdyBlcjtcbiAgfVxuXG4gIHRoaXMucmVzdWx0ICs9IHRoaXMuc291cmNlLnNsaWNlKHRoaXMuY2hlY2twb2ludCwgcG9zaXRpb24pO1xuICB0aGlzLmNoZWNrcG9pbnQgPSBwb3NpdGlvbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5TdHJpbmdCdWlsZGVyLnByb3RvdHlwZS5lc2NhcGVDaGFyID0gZnVuY3Rpb24gKCkge1xuICB2YXIgY2hhcmFjdGVyLCBlc2M7XG5cbiAgY2hhcmFjdGVyID0gdGhpcy5zb3VyY2UuY2hhckNvZGVBdCh0aGlzLmNoZWNrcG9pbnQpO1xuICBlc2MgPSBFU0NBUEVfU0VRVUVOQ0VTW2NoYXJhY3Rlcl0gfHwgZW5jb2RlSGV4KGNoYXJhY3Rlcik7XG4gIHRoaXMucmVzdWx0ICs9IGVzYztcbiAgdGhpcy5jaGVja3BvaW50ICs9IDE7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5TdHJpbmdCdWlsZGVyLnByb3RvdHlwZS5maW5pc2ggPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLnNvdXJjZS5sZW5ndGggPiB0aGlzLmNoZWNrcG9pbnQpIHtcbiAgICB0aGlzLnRha2VVcFRvKHRoaXMuc291cmNlLmxlbmd0aCk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIHdyaXRlU2NhbGFyKHN0YXRlLCBvYmplY3QsIGxldmVsKSB7XG4gIHZhciBzaW1wbGUsIGZpcnN0LCBzcGFjZVdyYXAsIGZvbGRlZCwgbGl0ZXJhbCwgc2luZ2xlLCBkb3VibGUsXG4gICAgICBzYXdMaW5lRmVlZCwgbGluZVBvc2l0aW9uLCBsb25nZXN0TGluZSwgaW5kZW50LCBtYXgsIGNoYXJhY3RlcixcbiAgICAgIHBvc2l0aW9uLCBlc2NhcGVTZXEsIGhleEVzYywgcHJldmlvdXMsIGxpbmVMZW5ndGgsIG1vZGlmaWVyLFxuICAgICAgdHJhaWxpbmdMaW5lQnJlYWtzLCByZXN1bHQ7XG5cbiAgaWYgKDAgPT09IG9iamVjdC5sZW5ndGgpIHtcbiAgICBzdGF0ZS5kdW1wID0gXCInJ1wiO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmICgtMSAhPT0gREVQUkVDQVRFRF9CT09MRUFOU19TWU5UQVguaW5kZXhPZihvYmplY3QpKSB7XG4gICAgc3RhdGUuZHVtcCA9IFwiJ1wiICsgb2JqZWN0ICsgXCInXCI7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgc2ltcGxlID0gdHJ1ZTtcbiAgZmlyc3QgPSBvYmplY3QubGVuZ3RoID8gb2JqZWN0LmNoYXJDb2RlQXQoMCkgOiAwO1xuICBzcGFjZVdyYXAgPSAoQ0hBUl9TUEFDRSA9PT0gZmlyc3QgfHxcbiAgICAgICAgICAgICAgIENIQVJfU1BBQ0UgPT09IG9iamVjdC5jaGFyQ29kZUF0KG9iamVjdC5sZW5ndGggLSAxKSk7XG5cbiAgLy8gU2ltcGxpZmllZCBjaGVjayBmb3IgcmVzdHJpY3RlZCBmaXJzdCBjaGFyYWN0ZXJzXG4gIC8vIGh0dHA6Ly93d3cueWFtbC5vcmcvc3BlYy8xLjIvc3BlYy5odG1sI25zLXBsYWluLWZpcnN0JTI4YyUyOVxuICBpZiAoQ0hBUl9NSU5VUyAgICAgICAgID09PSBmaXJzdCB8fFxuICAgICAgQ0hBUl9RVUVTVElPTiAgICAgID09PSBmaXJzdCB8fFxuICAgICAgQ0hBUl9DT01NRVJDSUFMX0FUID09PSBmaXJzdCB8fFxuICAgICAgQ0hBUl9HUkFWRV9BQ0NFTlQgID09PSBmaXJzdCkge1xuICAgIHNpbXBsZSA9IGZhbHNlO1xuICB9XG5cbiAgLy8gY2FuIG9ubHkgdXNlID4gYW5kIHwgaWYgbm90IHdyYXBwZWQgaW4gc3BhY2VzLlxuICBpZiAoc3BhY2VXcmFwKSB7XG4gICAgc2ltcGxlID0gZmFsc2U7XG4gICAgZm9sZGVkID0gZmFsc2U7XG4gICAgbGl0ZXJhbCA9IGZhbHNlO1xuICB9IGVsc2Uge1xuICAgIGZvbGRlZCA9IHRydWU7XG4gICAgbGl0ZXJhbCA9IHRydWU7XG4gIH1cblxuICBzaW5nbGUgPSB0cnVlO1xuICBkb3VibGUgPSBuZXcgU3RyaW5nQnVpbGRlcihvYmplY3QpO1xuXG4gIHNhd0xpbmVGZWVkID0gZmFsc2U7XG4gIGxpbmVQb3NpdGlvbiA9IDA7XG4gIGxvbmdlc3RMaW5lID0gMDtcblxuICBpbmRlbnQgPSBzdGF0ZS5pbmRlbnQgKiBsZXZlbDtcbiAgbWF4ID0gODA7XG4gIGlmIChpbmRlbnQgPCA0MCkge1xuICAgIG1heCAtPSBpbmRlbnQ7XG4gIH0gZWxzZSB7XG4gICAgbWF4ID0gNDA7XG4gIH1cblxuICBmb3IgKHBvc2l0aW9uID0gMDsgcG9zaXRpb24gPCBvYmplY3QubGVuZ3RoOyBwb3NpdGlvbisrKSB7XG4gICAgY2hhcmFjdGVyID0gb2JqZWN0LmNoYXJDb2RlQXQocG9zaXRpb24pO1xuICAgIGlmIChzaW1wbGUpIHtcbiAgICAgIC8vIENoYXJhY3RlcnMgdGhhdCBjYW4gbmV2ZXIgYXBwZWFyIGluIHRoZSBzaW1wbGUgc2NhbGFyXG4gICAgICBpZiAoIXNpbXBsZUNoYXIoY2hhcmFjdGVyKSkge1xuICAgICAgICBzaW1wbGUgPSBmYWxzZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFN0aWxsIHNpbXBsZS4gIElmIHdlIG1ha2UgaXQgYWxsIHRoZSB3YXkgdGhyb3VnaCBsaWtlXG4gICAgICAgIC8vIHRoaXMsIHRoZW4gd2UgY2FuIGp1c3QgZHVtcCB0aGUgc3RyaW5nIGFzLWlzLlxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc2luZ2xlICYmIGNoYXJhY3RlciA9PT0gQ0hBUl9TSU5HTEVfUVVPVEUpIHtcbiAgICAgIHNpbmdsZSA9IGZhbHNlO1xuICAgIH1cblxuICAgIGVzY2FwZVNlcSA9IEVTQ0FQRV9TRVFVRU5DRVNbY2hhcmFjdGVyXTtcbiAgICBoZXhFc2MgPSBuZWVkc0hleEVzY2FwZShjaGFyYWN0ZXIpO1xuXG4gICAgaWYgKCFlc2NhcGVTZXEgJiYgIWhleEVzYykge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKGNoYXJhY3RlciAhPT0gQ0hBUl9MSU5FX0ZFRUQgJiZcbiAgICAgICAgY2hhcmFjdGVyICE9PSBDSEFSX0RPVUJMRV9RVU9URSAmJlxuICAgICAgICBjaGFyYWN0ZXIgIT09IENIQVJfU0lOR0xFX1FVT1RFKSB7XG4gICAgICBmb2xkZWQgPSBmYWxzZTtcbiAgICAgIGxpdGVyYWwgPSBmYWxzZTtcbiAgICB9IGVsc2UgaWYgKGNoYXJhY3RlciA9PT0gQ0hBUl9MSU5FX0ZFRUQpIHtcbiAgICAgIHNhd0xpbmVGZWVkID0gdHJ1ZTtcbiAgICAgIHNpbmdsZSA9IGZhbHNlO1xuICAgICAgaWYgKHBvc2l0aW9uID4gMCkge1xuICAgICAgICBwcmV2aW91cyA9IG9iamVjdC5jaGFyQ29kZUF0KHBvc2l0aW9uIC0gMSk7XG4gICAgICAgIGlmIChwcmV2aW91cyA9PT0gQ0hBUl9TUEFDRSkge1xuICAgICAgICAgIGxpdGVyYWwgPSBmYWxzZTtcbiAgICAgICAgICBmb2xkZWQgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGZvbGRlZCkge1xuICAgICAgICBsaW5lTGVuZ3RoID0gcG9zaXRpb24gLSBsaW5lUG9zaXRpb247XG4gICAgICAgIGxpbmVQb3NpdGlvbiA9IHBvc2l0aW9uO1xuICAgICAgICBpZiAobGluZUxlbmd0aCA+IGxvbmdlc3RMaW5lKSB7XG4gICAgICAgICAgbG9uZ2VzdExpbmUgPSBsaW5lTGVuZ3RoO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNoYXJhY3RlciAhPT0gQ0hBUl9ET1VCTEVfUVVPVEUpIHtcbiAgICAgIHNpbmdsZSA9IGZhbHNlO1xuICAgIH1cblxuICAgIGRvdWJsZS50YWtlVXBUbyhwb3NpdGlvbik7XG4gICAgZG91YmxlLmVzY2FwZUNoYXIoKTtcbiAgfVxuXG4gIGlmIChzaW1wbGUgJiYgdGVzdEltcGxpY2l0UmVzb2x2aW5nKHN0YXRlLCBvYmplY3QpKSB7XG4gICAgc2ltcGxlID0gZmFsc2U7XG4gIH1cblxuICBtb2RpZmllciA9ICcnO1xuICBpZiAoZm9sZGVkIHx8IGxpdGVyYWwpIHtcbiAgICB0cmFpbGluZ0xpbmVCcmVha3MgPSAwO1xuICAgIGlmIChvYmplY3QuY2hhckNvZGVBdChvYmplY3QubGVuZ3RoIC0gMSkgPT09IENIQVJfTElORV9GRUVEKSB7XG4gICAgICB0cmFpbGluZ0xpbmVCcmVha3MgKz0gMTtcbiAgICAgIGlmIChvYmplY3QuY2hhckNvZGVBdChvYmplY3QubGVuZ3RoIC0gMikgPT09IENIQVJfTElORV9GRUVEKSB7XG4gICAgICAgIHRyYWlsaW5nTGluZUJyZWFrcyArPSAxO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0cmFpbGluZ0xpbmVCcmVha3MgPT09IDApIHtcbiAgICAgIG1vZGlmaWVyID0gJy0nO1xuICAgIH0gZWxzZSBpZiAodHJhaWxpbmdMaW5lQnJlYWtzID09PSAyKSB7XG4gICAgICBtb2RpZmllciA9ICcrJztcbiAgICB9XG4gIH1cblxuICBpZiAobGl0ZXJhbCAmJiBsb25nZXN0TGluZSA8IG1heCkge1xuICAgIGZvbGRlZCA9IGZhbHNlO1xuICB9XG5cbiAgLy8gSWYgaXQncyBsaXRlcmFsbHkgb25lIGxpbmUsIHRoZW4gZG9uJ3QgYm90aGVyIHdpdGggdGhlIGxpdGVyYWwuXG4gIC8vIFdlIG1heSBzdGlsbCB3YW50IHRvIGRvIGEgZm9sZCwgdGhvdWdoLCBpZiBpdCdzIGEgc3VwZXIgbG9uZyBsaW5lLlxuICBpZiAoIXNhd0xpbmVGZWVkKSB7XG4gICAgbGl0ZXJhbCA9IGZhbHNlO1xuICB9XG5cbiAgaWYgKHNpbXBsZSkge1xuICAgIHN0YXRlLmR1bXAgPSBvYmplY3Q7XG4gIH0gZWxzZSBpZiAoc2luZ2xlKSB7XG4gICAgc3RhdGUuZHVtcCA9ICdcXCcnICsgb2JqZWN0ICsgJ1xcJyc7XG4gIH0gZWxzZSBpZiAoZm9sZGVkKSB7XG4gICAgcmVzdWx0ID0gZm9sZChvYmplY3QsIG1heCk7XG4gICAgc3RhdGUuZHVtcCA9ICc+JyArIG1vZGlmaWVyICsgJ1xcbicgKyBpbmRlbnRTdHJpbmcocmVzdWx0LCBpbmRlbnQpO1xuICB9IGVsc2UgaWYgKGxpdGVyYWwpIHtcbiAgICBpZiAoIW1vZGlmaWVyKSB7XG4gICAgICBvYmplY3QgPSBvYmplY3QucmVwbGFjZSgvXFxuJC8sICcnKTtcbiAgICB9XG4gICAgc3RhdGUuZHVtcCA9ICd8JyArIG1vZGlmaWVyICsgJ1xcbicgKyBpbmRlbnRTdHJpbmcob2JqZWN0LCBpbmRlbnQpO1xuICB9IGVsc2UgaWYgKGRvdWJsZSkge1xuICAgIGRvdWJsZS5maW5pc2goKTtcbiAgICBzdGF0ZS5kdW1wID0gJ1wiJyArIGRvdWJsZS5yZXN1bHQgKyAnXCInO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcignRmFpbGVkIHRvIGR1bXAgc2NhbGFyIHZhbHVlJyk7XG4gIH1cblxuICByZXR1cm47XG59XG5cbi8vIFRoZSBgdHJhaWxpbmdgIHZhciBpcyBhIHJlZ2V4cCBtYXRjaCBvZiBhbnkgdHJhaWxpbmcgYFxcbmAgY2hhcmFjdGVycy5cbi8vXG4vLyBUaGVyZSBhcmUgdGhyZWUgY2FzZXMgd2UgY2FyZSBhYm91dDpcbi8vXG4vLyAxLiBPbmUgdHJhaWxpbmcgYFxcbmAgb24gdGhlIHN0cmluZy4gIEp1c3QgdXNlIGB8YCBvciBgPmAuXG4vLyAgICBUaGlzIGlzIHRoZSBhc3N1bWVkIGRlZmF1bHQuICh0cmFpbGluZyA9IG51bGwpXG4vLyAyLiBObyB0cmFpbGluZyBgXFxuYCBvbiB0aGUgc3RyaW5nLiAgVXNlIGB8LWAgb3IgYD4tYCB0byBcImNob21wXCIgdGhlIGVuZC5cbi8vIDMuIE1vcmUgdGhhbiBvbmUgdHJhaWxpbmcgYFxcbmAgb24gdGhlIHN0cmluZy4gIFVzZSBgfCtgIG9yIGA+K2AuXG4vL1xuLy8gSW4gdGhlIGNhc2Ugb2YgYD4rYCwgdGhlc2UgbGluZSBicmVha3MgYXJlICpub3QqIGRvdWJsZWQgKGxpa2UgdGhlIGxpbmVcbi8vIGJyZWFrcyB3aXRoaW4gdGhlIHN0cmluZyksIHNvIGl0J3MgaW1wb3J0YW50IHRvIG9ubHkgZW5kIHdpdGggdGhlIGV4YWN0XG4vLyBzYW1lIG51bWJlciBhcyB3ZSBzdGFydGVkLlxuZnVuY3Rpb24gZm9sZChvYmplY3QsIG1heCkge1xuICB2YXIgcmVzdWx0ID0gJycsXG4gICAgICBwb3NpdGlvbiA9IDAsXG4gICAgICBsZW5ndGggPSBvYmplY3QubGVuZ3RoLFxuICAgICAgdHJhaWxpbmcgPSAvXFxuKyQvLmV4ZWMob2JqZWN0KSxcbiAgICAgIG5ld0xpbmU7XG5cbiAgaWYgKHRyYWlsaW5nKSB7XG4gICAgbGVuZ3RoID0gdHJhaWxpbmcuaW5kZXggKyAxO1xuICB9XG5cbiAgd2hpbGUgKHBvc2l0aW9uIDwgbGVuZ3RoKSB7XG4gICAgbmV3TGluZSA9IG9iamVjdC5pbmRleE9mKCdcXG4nLCBwb3NpdGlvbik7XG4gICAgaWYgKG5ld0xpbmUgPiBsZW5ndGggfHwgbmV3TGluZSA9PT0gLTEpIHtcbiAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgcmVzdWx0ICs9ICdcXG5cXG4nO1xuICAgICAgfVxuICAgICAgcmVzdWx0ICs9IGZvbGRMaW5lKG9iamVjdC5zbGljZShwb3NpdGlvbiwgbGVuZ3RoKSwgbWF4KTtcbiAgICAgIHBvc2l0aW9uID0gbGVuZ3RoO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgIHJlc3VsdCArPSAnXFxuXFxuJztcbiAgICAgIH1cbiAgICAgIHJlc3VsdCArPSBmb2xkTGluZShvYmplY3Quc2xpY2UocG9zaXRpb24sIG5ld0xpbmUpLCBtYXgpO1xuICAgICAgcG9zaXRpb24gPSBuZXdMaW5lICsgMTtcbiAgICB9XG4gIH1cbiAgaWYgKHRyYWlsaW5nICYmIHRyYWlsaW5nWzBdICE9PSAnXFxuJykge1xuICAgIHJlc3VsdCArPSB0cmFpbGluZ1swXTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIGZvbGRMaW5lKGxpbmUsIG1heCkge1xuICBpZiAobGluZSA9PT0gJycpIHtcbiAgICByZXR1cm4gbGluZTtcbiAgfVxuXG4gIHZhciBmb2xkUmUgPSAvW15cXHNdIFteXFxzXS9nLFxuICAgICAgcmVzdWx0ID0gJycsXG4gICAgICBwcmV2TWF0Y2ggPSAwLFxuICAgICAgZm9sZFN0YXJ0ID0gMCxcbiAgICAgIG1hdGNoID0gZm9sZFJlLmV4ZWMobGluZSksXG4gICAgICBpbmRleCxcbiAgICAgIGZvbGRFbmQsXG4gICAgICBmb2xkZWQ7XG5cbiAgd2hpbGUgKG1hdGNoKSB7XG4gICAgaW5kZXggPSBtYXRjaC5pbmRleDtcblxuICAgIC8vIHdoZW4gd2UgY3Jvc3MgdGhlIG1heCBsZW4sIGlmIHRoZSBwcmV2aW91cyBtYXRjaCB3b3VsZCd2ZVxuICAgIC8vIGJlZW4gb2ssIHVzZSB0aGF0IG9uZSwgYW5kIGNhcnJ5IG9uLiAgSWYgdGhlcmUgd2FzIG5vIHByZXZpb3VzXG4gICAgLy8gbWF0Y2ggb24gdGhpcyBmb2xkIHNlY3Rpb24sIHRoZW4ganVzdCBoYXZlIGEgbG9uZyBsaW5lLlxuICAgIGlmIChpbmRleCAtIGZvbGRTdGFydCA+IG1heCkge1xuICAgICAgaWYgKHByZXZNYXRjaCAhPT0gZm9sZFN0YXJ0KSB7XG4gICAgICAgIGZvbGRFbmQgPSBwcmV2TWF0Y2g7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb2xkRW5kID0gaW5kZXg7XG4gICAgICB9XG5cbiAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgcmVzdWx0ICs9ICdcXG4nO1xuICAgICAgfVxuICAgICAgZm9sZGVkID0gbGluZS5zbGljZShmb2xkU3RhcnQsIGZvbGRFbmQpO1xuICAgICAgcmVzdWx0ICs9IGZvbGRlZDtcbiAgICAgIGZvbGRTdGFydCA9IGZvbGRFbmQgKyAxO1xuICAgIH1cbiAgICBwcmV2TWF0Y2ggPSBpbmRleCArIDE7XG4gICAgbWF0Y2ggPSBmb2xkUmUuZXhlYyhsaW5lKTtcbiAgfVxuXG4gIGlmIChyZXN1bHQpIHtcbiAgICByZXN1bHQgKz0gJ1xcbic7XG4gIH1cblxuICAvLyBpZiB3ZSBlbmQgdXAgd2l0aCBvbmUgbGFzdCB3b3JkIGF0IHRoZSBlbmQsIHRoZW4gdGhlIGxhc3QgYml0IG1pZ2h0XG4gIC8vIGJlIHNsaWdodGx5IGJpZ2dlciB0aGFuIHdlIHdhbnRlZCwgYmVjYXVzZSB3ZSBleGl0ZWQgb3V0IG9mIHRoZSBsb29wLlxuICBpZiAoZm9sZFN0YXJ0ICE9PSBwcmV2TWF0Y2ggJiYgbGluZS5sZW5ndGggLSBmb2xkU3RhcnQgPiBtYXgpIHtcbiAgICByZXN1bHQgKz0gbGluZS5zbGljZShmb2xkU3RhcnQsIHByZXZNYXRjaCkgKyAnXFxuJyArXG4gICAgICAgICAgICAgIGxpbmUuc2xpY2UocHJldk1hdGNoICsgMSk7XG4gIH0gZWxzZSB7XG4gICAgcmVzdWx0ICs9IGxpbmUuc2xpY2UoZm9sZFN0YXJ0KTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8vIFJldHVybnMgdHJ1ZSBpZiBjaGFyYWN0ZXIgY2FuIGJlIGZvdW5kIGluIGEgc2ltcGxlIHNjYWxhclxuZnVuY3Rpb24gc2ltcGxlQ2hhcihjaGFyYWN0ZXIpIHtcbiAgcmV0dXJuIENIQVJfVEFCICAgICAgICAgICAgICAgICAgIT09IGNoYXJhY3RlciAmJlxuICAgICAgICAgQ0hBUl9MSU5FX0ZFRUQgICAgICAgICAgICAhPT0gY2hhcmFjdGVyICYmXG4gICAgICAgICBDSEFSX0NBUlJJQUdFX1JFVFVSTiAgICAgICE9PSBjaGFyYWN0ZXIgJiZcbiAgICAgICAgIENIQVJfQ09NTUEgICAgICAgICAgICAgICAgIT09IGNoYXJhY3RlciAmJlxuICAgICAgICAgQ0hBUl9MRUZUX1NRVUFSRV9CUkFDS0VUICAhPT0gY2hhcmFjdGVyICYmXG4gICAgICAgICBDSEFSX1JJR0hUX1NRVUFSRV9CUkFDS0VUICE9PSBjaGFyYWN0ZXIgJiZcbiAgICAgICAgIENIQVJfTEVGVF9DVVJMWV9CUkFDS0VUICAgIT09IGNoYXJhY3RlciAmJlxuICAgICAgICAgQ0hBUl9SSUdIVF9DVVJMWV9CUkFDS0VUICAhPT0gY2hhcmFjdGVyICYmXG4gICAgICAgICBDSEFSX1NIQVJQICAgICAgICAgICAgICAgICE9PSBjaGFyYWN0ZXIgJiZcbiAgICAgICAgIENIQVJfQU1QRVJTQU5EICAgICAgICAgICAgIT09IGNoYXJhY3RlciAmJlxuICAgICAgICAgQ0hBUl9BU1RFUklTSyAgICAgICAgICAgICAhPT0gY2hhcmFjdGVyICYmXG4gICAgICAgICBDSEFSX0VYQ0xBTUFUSU9OICAgICAgICAgICE9PSBjaGFyYWN0ZXIgJiZcbiAgICAgICAgIENIQVJfVkVSVElDQUxfTElORSAgICAgICAgIT09IGNoYXJhY3RlciAmJlxuICAgICAgICAgQ0hBUl9HUkVBVEVSX1RIQU4gICAgICAgICAhPT0gY2hhcmFjdGVyICYmXG4gICAgICAgICBDSEFSX1NJTkdMRV9RVU9URSAgICAgICAgICE9PSBjaGFyYWN0ZXIgJiZcbiAgICAgICAgIENIQVJfRE9VQkxFX1FVT1RFICAgICAgICAgIT09IGNoYXJhY3RlciAmJlxuICAgICAgICAgQ0hBUl9QRVJDRU5UICAgICAgICAgICAgICAhPT0gY2hhcmFjdGVyICYmXG4gICAgICAgICBDSEFSX0NPTE9OICAgICAgICAgICAgICAgICE9PSBjaGFyYWN0ZXIgJiZcbiAgICAgICAgICFFU0NBUEVfU0VRVUVOQ0VTW2NoYXJhY3Rlcl0gICAgICAgICAgICAmJlxuICAgICAgICAgIW5lZWRzSGV4RXNjYXBlKGNoYXJhY3Rlcik7XG59XG5cbi8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgY2hhcmFjdGVyIGNvZGUgbmVlZHMgdG8gYmUgZXNjYXBlZC5cbmZ1bmN0aW9uIG5lZWRzSGV4RXNjYXBlKGNoYXJhY3Rlcikge1xuICByZXR1cm4gISgoMHgwMDAyMCA8PSBjaGFyYWN0ZXIgJiYgY2hhcmFjdGVyIDw9IDB4MDAwMDdFKSB8fFxuICAgICAgICAgICAoMHgwMDA4NSA9PT0gY2hhcmFjdGVyKSAgICAgICAgICAgICAgICAgICAgICAgICB8fFxuICAgICAgICAgICAoMHgwMDBBMCA8PSBjaGFyYWN0ZXIgJiYgY2hhcmFjdGVyIDw9IDB4MDBEN0ZGKSB8fFxuICAgICAgICAgICAoMHgwRTAwMCA8PSBjaGFyYWN0ZXIgJiYgY2hhcmFjdGVyIDw9IDB4MDBGRkZEKSB8fFxuICAgICAgICAgICAoMHgxMDAwMCA8PSBjaGFyYWN0ZXIgJiYgY2hhcmFjdGVyIDw9IDB4MTBGRkZGKSk7XG59XG5cbmZ1bmN0aW9uIHdyaXRlRmxvd1NlcXVlbmNlKHN0YXRlLCBsZXZlbCwgb2JqZWN0KSB7XG4gIHZhciBfcmVzdWx0ID0gJycsXG4gICAgICBfdGFnICAgID0gc3RhdGUudGFnLFxuICAgICAgaW5kZXgsXG4gICAgICBsZW5ndGg7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IG9iamVjdC5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgLy8gV3JpdGUgb25seSB2YWxpZCBlbGVtZW50cy5cbiAgICBpZiAod3JpdGVOb2RlKHN0YXRlLCBsZXZlbCwgb2JqZWN0W2luZGV4XSwgZmFsc2UsIGZhbHNlKSkge1xuICAgICAgaWYgKDAgIT09IGluZGV4KSB7XG4gICAgICAgIF9yZXN1bHQgKz0gJywgJztcbiAgICAgIH1cbiAgICAgIF9yZXN1bHQgKz0gc3RhdGUuZHVtcDtcbiAgICB9XG4gIH1cblxuICBzdGF0ZS50YWcgPSBfdGFnO1xuICBzdGF0ZS5kdW1wID0gJ1snICsgX3Jlc3VsdCArICddJztcbn1cblxuZnVuY3Rpb24gd3JpdGVCbG9ja1NlcXVlbmNlKHN0YXRlLCBsZXZlbCwgb2JqZWN0LCBjb21wYWN0KSB7XG4gIHZhciBfcmVzdWx0ID0gJycsXG4gICAgICBfdGFnICAgID0gc3RhdGUudGFnLFxuICAgICAgaW5kZXgsXG4gICAgICBsZW5ndGg7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IG9iamVjdC5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgLy8gV3JpdGUgb25seSB2YWxpZCBlbGVtZW50cy5cbiAgICBpZiAod3JpdGVOb2RlKHN0YXRlLCBsZXZlbCArIDEsIG9iamVjdFtpbmRleF0sIHRydWUsIHRydWUpKSB7XG4gICAgICBpZiAoIWNvbXBhY3QgfHwgMCAhPT0gaW5kZXgpIHtcbiAgICAgICAgX3Jlc3VsdCArPSBnZW5lcmF0ZU5leHRMaW5lKHN0YXRlLCBsZXZlbCk7XG4gICAgICB9XG4gICAgICBfcmVzdWx0ICs9ICctICcgKyBzdGF0ZS5kdW1wO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRlLnRhZyA9IF90YWc7XG4gIHN0YXRlLmR1bXAgPSBfcmVzdWx0IHx8ICdbXSc7IC8vIEVtcHR5IHNlcXVlbmNlIGlmIG5vIHZhbGlkIHZhbHVlcy5cbn1cblxuZnVuY3Rpb24gd3JpdGVGbG93TWFwcGluZyhzdGF0ZSwgbGV2ZWwsIG9iamVjdCkge1xuICB2YXIgX3Jlc3VsdCAgICAgICA9ICcnLFxuICAgICAgX3RhZyAgICAgICAgICA9IHN0YXRlLnRhZyxcbiAgICAgIG9iamVjdEtleUxpc3QgPSBPYmplY3Qua2V5cyhvYmplY3QpLFxuICAgICAgaW5kZXgsXG4gICAgICBsZW5ndGgsXG4gICAgICBvYmplY3RLZXksXG4gICAgICBvYmplY3RWYWx1ZSxcbiAgICAgIHBhaXJCdWZmZXI7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IG9iamVjdEtleUxpc3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIHBhaXJCdWZmZXIgPSAnJztcblxuICAgIGlmICgwICE9PSBpbmRleCkge1xuICAgICAgcGFpckJ1ZmZlciArPSAnLCAnO1xuICAgIH1cblxuICAgIG9iamVjdEtleSA9IG9iamVjdEtleUxpc3RbaW5kZXhdO1xuICAgIG9iamVjdFZhbHVlID0gb2JqZWN0W29iamVjdEtleV07XG5cbiAgICBpZiAoIXdyaXRlTm9kZShzdGF0ZSwgbGV2ZWwsIG9iamVjdEtleSwgZmFsc2UsIGZhbHNlKSkge1xuICAgICAgY29udGludWU7IC8vIFNraXAgdGhpcyBwYWlyIGJlY2F1c2Ugb2YgaW52YWxpZCBrZXk7XG4gICAgfVxuXG4gICAgaWYgKHN0YXRlLmR1bXAubGVuZ3RoID4gMTAyNCkge1xuICAgICAgcGFpckJ1ZmZlciArPSAnPyAnO1xuICAgIH1cblxuICAgIHBhaXJCdWZmZXIgKz0gc3RhdGUuZHVtcCArICc6ICc7XG5cbiAgICBpZiAoIXdyaXRlTm9kZShzdGF0ZSwgbGV2ZWwsIG9iamVjdFZhbHVlLCBmYWxzZSwgZmFsc2UpKSB7XG4gICAgICBjb250aW51ZTsgLy8gU2tpcCB0aGlzIHBhaXIgYmVjYXVzZSBvZiBpbnZhbGlkIHZhbHVlLlxuICAgIH1cblxuICAgIHBhaXJCdWZmZXIgKz0gc3RhdGUuZHVtcDtcblxuICAgIC8vIEJvdGgga2V5IGFuZCB2YWx1ZSBhcmUgdmFsaWQuXG4gICAgX3Jlc3VsdCArPSBwYWlyQnVmZmVyO1xuICB9XG5cbiAgc3RhdGUudGFnID0gX3RhZztcbiAgc3RhdGUuZHVtcCA9ICd7JyArIF9yZXN1bHQgKyAnfSc7XG59XG5cbmZ1bmN0aW9uIHdyaXRlQmxvY2tNYXBwaW5nKHN0YXRlLCBsZXZlbCwgb2JqZWN0LCBjb21wYWN0KSB7XG4gIHZhciBfcmVzdWx0ICAgICAgID0gJycsXG4gICAgICBfdGFnICAgICAgICAgID0gc3RhdGUudGFnLFxuICAgICAgb2JqZWN0S2V5TGlzdCA9IE9iamVjdC5rZXlzKG9iamVjdCksXG4gICAgICBpbmRleCxcbiAgICAgIGxlbmd0aCxcbiAgICAgIG9iamVjdEtleSxcbiAgICAgIG9iamVjdFZhbHVlLFxuICAgICAgZXhwbGljaXRQYWlyLFxuICAgICAgcGFpckJ1ZmZlcjtcblxuICAvLyBBbGxvdyBzb3J0aW5nIGtleXMgc28gdGhhdCB0aGUgb3V0cHV0IGZpbGUgaXMgZGV0ZXJtaW5pc3RpY1xuICBpZiAoc3RhdGUuc29ydEtleXMgPT09IHRydWUpIHtcbiAgICAvLyBEZWZhdWx0IHNvcnRpbmdcbiAgICBvYmplY3RLZXlMaXN0LnNvcnQoKTtcbiAgfSBlbHNlIGlmICh0eXBlb2Ygc3RhdGUuc29ydEtleXMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAvLyBDdXN0b20gc29ydCBmdW5jdGlvblxuICAgIG9iamVjdEtleUxpc3Quc29ydChzdGF0ZS5zb3J0S2V5cyk7XG4gIH0gZWxzZSBpZiAoc3RhdGUuc29ydEtleXMpIHtcbiAgICAvLyBTb21ldGhpbmcgaXMgd3JvbmdcbiAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignc29ydEtleXMgbXVzdCBiZSBhIGJvb2xlYW4gb3IgYSBmdW5jdGlvbicpO1xuICB9XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IG9iamVjdEtleUxpc3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIHBhaXJCdWZmZXIgPSAnJztcblxuICAgIGlmICghY29tcGFjdCB8fCAwICE9PSBpbmRleCkge1xuICAgICAgcGFpckJ1ZmZlciArPSBnZW5lcmF0ZU5leHRMaW5lKHN0YXRlLCBsZXZlbCk7XG4gICAgfVxuXG4gICAgb2JqZWN0S2V5ID0gb2JqZWN0S2V5TGlzdFtpbmRleF07XG4gICAgb2JqZWN0VmFsdWUgPSBvYmplY3Rbb2JqZWN0S2V5XTtcblxuICAgIGlmICghd3JpdGVOb2RlKHN0YXRlLCBsZXZlbCArIDEsIG9iamVjdEtleSwgdHJ1ZSwgdHJ1ZSkpIHtcbiAgICAgIGNvbnRpbnVlOyAvLyBTa2lwIHRoaXMgcGFpciBiZWNhdXNlIG9mIGludmFsaWQga2V5LlxuICAgIH1cblxuICAgIGV4cGxpY2l0UGFpciA9IChudWxsICE9PSBzdGF0ZS50YWcgJiYgJz8nICE9PSBzdGF0ZS50YWcpIHx8XG4gICAgICAgICAgICAgICAgICAgKHN0YXRlLmR1bXAgJiYgc3RhdGUuZHVtcC5sZW5ndGggPiAxMDI0KTtcblxuICAgIGlmIChleHBsaWNpdFBhaXIpIHtcbiAgICAgIGlmIChzdGF0ZS5kdW1wICYmIENIQVJfTElORV9GRUVEID09PSBzdGF0ZS5kdW1wLmNoYXJDb2RlQXQoMCkpIHtcbiAgICAgICAgcGFpckJ1ZmZlciArPSAnPyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwYWlyQnVmZmVyICs9ICc/ICc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcGFpckJ1ZmZlciArPSBzdGF0ZS5kdW1wO1xuXG4gICAgaWYgKGV4cGxpY2l0UGFpcikge1xuICAgICAgcGFpckJ1ZmZlciArPSBnZW5lcmF0ZU5leHRMaW5lKHN0YXRlLCBsZXZlbCk7XG4gICAgfVxuXG4gICAgaWYgKCF3cml0ZU5vZGUoc3RhdGUsIGxldmVsICsgMSwgb2JqZWN0VmFsdWUsIHRydWUsIGV4cGxpY2l0UGFpcikpIHtcbiAgICAgIGNvbnRpbnVlOyAvLyBTa2lwIHRoaXMgcGFpciBiZWNhdXNlIG9mIGludmFsaWQgdmFsdWUuXG4gICAgfVxuXG4gICAgaWYgKHN0YXRlLmR1bXAgJiYgQ0hBUl9MSU5FX0ZFRUQgPT09IHN0YXRlLmR1bXAuY2hhckNvZGVBdCgwKSkge1xuICAgICAgcGFpckJ1ZmZlciArPSAnOic7XG4gICAgfSBlbHNlIHtcbiAgICAgIHBhaXJCdWZmZXIgKz0gJzogJztcbiAgICB9XG5cbiAgICBwYWlyQnVmZmVyICs9IHN0YXRlLmR1bXA7XG5cbiAgICAvLyBCb3RoIGtleSBhbmQgdmFsdWUgYXJlIHZhbGlkLlxuICAgIF9yZXN1bHQgKz0gcGFpckJ1ZmZlcjtcbiAgfVxuXG4gIHN0YXRlLnRhZyA9IF90YWc7XG4gIHN0YXRlLmR1bXAgPSBfcmVzdWx0IHx8ICd7fSc7IC8vIEVtcHR5IG1hcHBpbmcgaWYgbm8gdmFsaWQgcGFpcnMuXG59XG5cbmZ1bmN0aW9uIGRldGVjdFR5cGUoc3RhdGUsIG9iamVjdCwgZXhwbGljaXQpIHtcbiAgdmFyIF9yZXN1bHQsIHR5cGVMaXN0LCBpbmRleCwgbGVuZ3RoLCB0eXBlLCBzdHlsZTtcblxuICB0eXBlTGlzdCA9IGV4cGxpY2l0ID8gc3RhdGUuZXhwbGljaXRUeXBlcyA6IHN0YXRlLmltcGxpY2l0VHlwZXM7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IHR5cGVMaXN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICB0eXBlID0gdHlwZUxpc3RbaW5kZXhdO1xuXG4gICAgaWYgKCh0eXBlLmluc3RhbmNlT2YgIHx8IHR5cGUucHJlZGljYXRlKSAmJlxuICAgICAgICAoIXR5cGUuaW5zdGFuY2VPZiB8fCAoKCdvYmplY3QnID09PSB0eXBlb2Ygb2JqZWN0KSAmJiAob2JqZWN0IGluc3RhbmNlb2YgdHlwZS5pbnN0YW5jZU9mKSkpICYmXG4gICAgICAgICghdHlwZS5wcmVkaWNhdGUgIHx8IHR5cGUucHJlZGljYXRlKG9iamVjdCkpKSB7XG5cbiAgICAgIHN0YXRlLnRhZyA9IGV4cGxpY2l0ID8gdHlwZS50YWcgOiAnPyc7XG5cbiAgICAgIGlmICh0eXBlLnJlcHJlc2VudCkge1xuICAgICAgICBzdHlsZSA9IHN0YXRlLnN0eWxlTWFwW3R5cGUudGFnXSB8fCB0eXBlLmRlZmF1bHRTdHlsZTtcblxuICAgICAgICBpZiAoJ1tvYmplY3QgRnVuY3Rpb25dJyA9PT0gX3RvU3RyaW5nLmNhbGwodHlwZS5yZXByZXNlbnQpKSB7XG4gICAgICAgICAgX3Jlc3VsdCA9IHR5cGUucmVwcmVzZW50KG9iamVjdCwgc3R5bGUpO1xuICAgICAgICB9IGVsc2UgaWYgKF9oYXNPd25Qcm9wZXJ0eS5jYWxsKHR5cGUucmVwcmVzZW50LCBzdHlsZSkpIHtcbiAgICAgICAgICBfcmVzdWx0ID0gdHlwZS5yZXByZXNlbnRbc3R5bGVdKG9iamVjdCwgc3R5bGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCchPCcgKyB0eXBlLnRhZyArICc+IHRhZyByZXNvbHZlciBhY2NlcHRzIG5vdCBcIicgKyBzdHlsZSArICdcIiBzdHlsZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgc3RhdGUuZHVtcCA9IF9yZXN1bHQ7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuLy8gU2VyaWFsaXplcyBgb2JqZWN0YCBhbmQgd3JpdGVzIGl0IHRvIGdsb2JhbCBgcmVzdWx0YC5cbi8vIFJldHVybnMgdHJ1ZSBvbiBzdWNjZXNzLCBvciBmYWxzZSBvbiBpbnZhbGlkIG9iamVjdC5cbi8vXG5mdW5jdGlvbiB3cml0ZU5vZGUoc3RhdGUsIGxldmVsLCBvYmplY3QsIGJsb2NrLCBjb21wYWN0KSB7XG4gIHN0YXRlLnRhZyA9IG51bGw7XG4gIHN0YXRlLmR1bXAgPSBvYmplY3Q7XG5cbiAgaWYgKCFkZXRlY3RUeXBlKHN0YXRlLCBvYmplY3QsIGZhbHNlKSkge1xuICAgIGRldGVjdFR5cGUoc3RhdGUsIG9iamVjdCwgdHJ1ZSk7XG4gIH1cblxuICB2YXIgdHlwZSA9IF90b1N0cmluZy5jYWxsKHN0YXRlLmR1bXApO1xuXG4gIGlmIChibG9jaykge1xuICAgIGJsb2NrID0gKDAgPiBzdGF0ZS5mbG93TGV2ZWwgfHwgc3RhdGUuZmxvd0xldmVsID4gbGV2ZWwpO1xuICB9XG5cbiAgaWYgKChudWxsICE9PSBzdGF0ZS50YWcgJiYgJz8nICE9PSBzdGF0ZS50YWcpIHx8ICgyICE9PSBzdGF0ZS5pbmRlbnQgJiYgbGV2ZWwgPiAwKSkge1xuICAgIGNvbXBhY3QgPSBmYWxzZTtcbiAgfVxuXG4gIHZhciBvYmplY3RPckFycmF5ID0gJ1tvYmplY3QgT2JqZWN0XScgPT09IHR5cGUgfHwgJ1tvYmplY3QgQXJyYXldJyA9PT0gdHlwZSxcbiAgICAgIGR1cGxpY2F0ZUluZGV4LFxuICAgICAgZHVwbGljYXRlO1xuXG4gIGlmIChvYmplY3RPckFycmF5KSB7XG4gICAgZHVwbGljYXRlSW5kZXggPSBzdGF0ZS5kdXBsaWNhdGVzLmluZGV4T2Yob2JqZWN0KTtcbiAgICBkdXBsaWNhdGUgPSBkdXBsaWNhdGVJbmRleCAhPT0gLTE7XG4gIH1cblxuICBpZiAoZHVwbGljYXRlICYmIHN0YXRlLnVzZWREdXBsaWNhdGVzW2R1cGxpY2F0ZUluZGV4XSkge1xuICAgIHN0YXRlLmR1bXAgPSAnKnJlZl8nICsgZHVwbGljYXRlSW5kZXg7XG4gIH0gZWxzZSB7XG4gICAgaWYgKG9iamVjdE9yQXJyYXkgJiYgZHVwbGljYXRlICYmICFzdGF0ZS51c2VkRHVwbGljYXRlc1tkdXBsaWNhdGVJbmRleF0pIHtcbiAgICAgIHN0YXRlLnVzZWREdXBsaWNhdGVzW2R1cGxpY2F0ZUluZGV4XSA9IHRydWU7XG4gICAgfVxuICAgIGlmICgnW29iamVjdCBPYmplY3RdJyA9PT0gdHlwZSkge1xuICAgICAgaWYgKGJsb2NrICYmICgwICE9PSBPYmplY3Qua2V5cyhzdGF0ZS5kdW1wKS5sZW5ndGgpKSB7XG4gICAgICAgIHdyaXRlQmxvY2tNYXBwaW5nKHN0YXRlLCBsZXZlbCwgc3RhdGUuZHVtcCwgY29tcGFjdCk7XG4gICAgICAgIGlmIChkdXBsaWNhdGUpIHtcbiAgICAgICAgICBzdGF0ZS5kdW1wID0gJyZyZWZfJyArIGR1cGxpY2F0ZUluZGV4ICsgKDAgPT09IGxldmVsID8gJ1xcbicgOiAnJykgKyBzdGF0ZS5kdW1wO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB3cml0ZUZsb3dNYXBwaW5nKHN0YXRlLCBsZXZlbCwgc3RhdGUuZHVtcCk7XG4gICAgICAgIGlmIChkdXBsaWNhdGUpIHtcbiAgICAgICAgICBzdGF0ZS5kdW1wID0gJyZyZWZfJyArIGR1cGxpY2F0ZUluZGV4ICsgJyAnICsgc3RhdGUuZHVtcDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoJ1tvYmplY3QgQXJyYXldJyA9PT0gdHlwZSkge1xuICAgICAgaWYgKGJsb2NrICYmICgwICE9PSBzdGF0ZS5kdW1wLmxlbmd0aCkpIHtcbiAgICAgICAgd3JpdGVCbG9ja1NlcXVlbmNlKHN0YXRlLCBsZXZlbCwgc3RhdGUuZHVtcCwgY29tcGFjdCk7XG4gICAgICAgIGlmIChkdXBsaWNhdGUpIHtcbiAgICAgICAgICBzdGF0ZS5kdW1wID0gJyZyZWZfJyArIGR1cGxpY2F0ZUluZGV4ICsgKDAgPT09IGxldmVsID8gJ1xcbicgOiAnJykgKyBzdGF0ZS5kdW1wO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB3cml0ZUZsb3dTZXF1ZW5jZShzdGF0ZSwgbGV2ZWwsIHN0YXRlLmR1bXApO1xuICAgICAgICBpZiAoZHVwbGljYXRlKSB7XG4gICAgICAgICAgc3RhdGUuZHVtcCA9ICcmcmVmXycgKyBkdXBsaWNhdGVJbmRleCArICcgJyArIHN0YXRlLmR1bXA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKCdbb2JqZWN0IFN0cmluZ10nID09PSB0eXBlKSB7XG4gICAgICBpZiAoJz8nICE9PSBzdGF0ZS50YWcpIHtcbiAgICAgICAgd3JpdGVTY2FsYXIoc3RhdGUsIHN0YXRlLmR1bXAsIGxldmVsKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHN0YXRlLnNraXBJbnZhbGlkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCd1bmFjY2VwdGFibGUga2luZCBvZiBhbiBvYmplY3QgdG8gZHVtcCAnICsgdHlwZSk7XG4gICAgfVxuXG4gICAgaWYgKG51bGwgIT09IHN0YXRlLnRhZyAmJiAnPycgIT09IHN0YXRlLnRhZykge1xuICAgICAgc3RhdGUuZHVtcCA9ICchPCcgKyBzdGF0ZS50YWcgKyAnPiAnICsgc3RhdGUuZHVtcDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gZ2V0RHVwbGljYXRlUmVmZXJlbmNlcyhvYmplY3QsIHN0YXRlKSB7XG4gIHZhciBvYmplY3RzID0gW10sXG4gICAgICBkdXBsaWNhdGVzSW5kZXhlcyA9IFtdLFxuICAgICAgaW5kZXgsXG4gICAgICBsZW5ndGg7XG5cbiAgaW5zcGVjdE5vZGUob2JqZWN0LCBvYmplY3RzLCBkdXBsaWNhdGVzSW5kZXhlcyk7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IGR1cGxpY2F0ZXNJbmRleGVzLmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICBzdGF0ZS5kdXBsaWNhdGVzLnB1c2gob2JqZWN0c1tkdXBsaWNhdGVzSW5kZXhlc1tpbmRleF1dKTtcbiAgfVxuICBzdGF0ZS51c2VkRHVwbGljYXRlcyA9IG5ldyBBcnJheShsZW5ndGgpO1xufVxuXG5mdW5jdGlvbiBpbnNwZWN0Tm9kZShvYmplY3QsIG9iamVjdHMsIGR1cGxpY2F0ZXNJbmRleGVzKSB7XG4gIHZhciB0eXBlID0gX3RvU3RyaW5nLmNhbGwob2JqZWN0KSxcbiAgICAgIG9iamVjdEtleUxpc3QsXG4gICAgICBpbmRleCxcbiAgICAgIGxlbmd0aDtcblxuICBpZiAobnVsbCAhPT0gb2JqZWN0ICYmICdvYmplY3QnID09PSB0eXBlb2Ygb2JqZWN0KSB7XG4gICAgaW5kZXggPSBvYmplY3RzLmluZGV4T2Yob2JqZWN0KTtcbiAgICBpZiAoLTEgIT09IGluZGV4KSB7XG4gICAgICBpZiAoLTEgPT09IGR1cGxpY2F0ZXNJbmRleGVzLmluZGV4T2YoaW5kZXgpKSB7XG4gICAgICAgIGR1cGxpY2F0ZXNJbmRleGVzLnB1c2goaW5kZXgpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBvYmplY3RzLnB1c2gob2JqZWN0KTtcblxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkob2JqZWN0KSkge1xuICAgICAgICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gb2JqZWN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICAgICAgICBpbnNwZWN0Tm9kZShvYmplY3RbaW5kZXhdLCBvYmplY3RzLCBkdXBsaWNhdGVzSW5kZXhlcyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9iamVjdEtleUxpc3QgPSBPYmplY3Qua2V5cyhvYmplY3QpO1xuXG4gICAgICAgIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3RLZXlMaXN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICAgICAgICBpbnNwZWN0Tm9kZShvYmplY3Rbb2JqZWN0S2V5TGlzdFtpbmRleF1dLCBvYmplY3RzLCBkdXBsaWNhdGVzSW5kZXhlcyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZHVtcChpbnB1dCwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgc3RhdGUgPSBuZXcgU3RhdGUob3B0aW9ucyk7XG5cbiAgZ2V0RHVwbGljYXRlUmVmZXJlbmNlcyhpbnB1dCwgc3RhdGUpO1xuXG4gIGlmICh3cml0ZU5vZGUoc3RhdGUsIDAsIGlucHV0LCB0cnVlLCB0cnVlKSkge1xuICAgIHJldHVybiBzdGF0ZS5kdW1wICsgJ1xcbic7XG4gIH1cbiAgcmV0dXJuICcnO1xufVxuXG5mdW5jdGlvbiBzYWZlRHVtcChpbnB1dCwgb3B0aW9ucykge1xuICByZXR1cm4gZHVtcChpbnB1dCwgY29tbW9uLmV4dGVuZCh7IHNjaGVtYTogREVGQVVMVF9TQUZFX1NDSEVNQSB9LCBvcHRpb25zKSk7XG59XG5cbm1vZHVsZS5leHBvcnRzLmR1bXAgICAgID0gZHVtcDtcbm1vZHVsZS5leHBvcnRzLnNhZmVEdW1wID0gc2FmZUR1bXA7XG4iLCIndXNlIHN0cmljdCc7XG5cblxuZnVuY3Rpb24gWUFNTEV4Y2VwdGlvbihyZWFzb24sIG1hcmspIHtcbiAgdGhpcy5uYW1lICAgID0gJ1lBTUxFeGNlcHRpb24nO1xuICB0aGlzLnJlYXNvbiAgPSByZWFzb247XG4gIHRoaXMubWFyayAgICA9IG1hcms7XG4gIHRoaXMubWVzc2FnZSA9IHRoaXMudG9TdHJpbmcoZmFsc2UpO1xufVxuXG5cbllBTUxFeGNlcHRpb24ucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoY29tcGFjdCkge1xuICB2YXIgcmVzdWx0O1xuXG4gIHJlc3VsdCA9ICdKUy1ZQU1MOiAnICsgKHRoaXMucmVhc29uIHx8ICcodW5rbm93biByZWFzb24pJyk7XG5cbiAgaWYgKCFjb21wYWN0ICYmIHRoaXMubWFyaykge1xuICAgIHJlc3VsdCArPSAnICcgKyB0aGlzLm1hcmsudG9TdHJpbmcoKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gWUFNTEV4Y2VwdGlvbjtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyplc2xpbnQtZGlzYWJsZSBtYXgtbGVuLG5vLXVzZS1iZWZvcmUtZGVmaW5lKi9cblxudmFyIGNvbW1vbiAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIFlBTUxFeGNlcHRpb24gICAgICAgPSByZXF1aXJlKCcuL2V4Y2VwdGlvbicpO1xudmFyIE1hcmsgICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL21hcmsnKTtcbnZhciBERUZBVUxUX1NBRkVfU0NIRU1BID0gcmVxdWlyZSgnLi9zY2hlbWEvZGVmYXVsdF9zYWZlJyk7XG52YXIgREVGQVVMVF9GVUxMX1NDSEVNQSA9IHJlcXVpcmUoJy4vc2NoZW1hL2RlZmF1bHRfZnVsbCcpO1xuXG5cbnZhciBfaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG5cbnZhciBDT05URVhUX0ZMT1dfSU4gICA9IDE7XG52YXIgQ09OVEVYVF9GTE9XX09VVCAgPSAyO1xudmFyIENPTlRFWFRfQkxPQ0tfSU4gID0gMztcbnZhciBDT05URVhUX0JMT0NLX09VVCA9IDQ7XG5cblxudmFyIENIT01QSU5HX0NMSVAgID0gMTtcbnZhciBDSE9NUElOR19TVFJJUCA9IDI7XG52YXIgQ0hPTVBJTkdfS0VFUCAgPSAzO1xuXG5cbnZhciBQQVRURVJOX05PTl9QUklOVEFCTEUgICAgICAgICA9IC9bXFx4MDAtXFx4MDhcXHgwQlxceDBDXFx4MEUtXFx4MUZcXHg3Ri1cXHg4NFxceDg2LVxceDlGXFx1RkZGRVxcdUZGRkZdfFtcXHVEODAwLVxcdURCRkZdKD8hW1xcdURDMDAtXFx1REZGRl0pfCg/OlteXFx1RDgwMC1cXHVEQkZGXXxeKVtcXHVEQzAwLVxcdURGRkZdLztcbnZhciBQQVRURVJOX05PTl9BU0NJSV9MSU5FX0JSRUFLUyA9IC9bXFx4ODVcXHUyMDI4XFx1MjAyOV0vO1xudmFyIFBBVFRFUk5fRkxPV19JTkRJQ0FUT1JTICAgICAgID0gL1ssXFxbXFxdXFx7XFx9XS87XG52YXIgUEFUVEVSTl9UQUdfSEFORExFICAgICAgICAgICAgPSAvXig/OiF8ISF8IVthLXpcXC1dKyEpJC9pO1xudmFyIFBBVFRFUk5fVEFHX1VSSSAgICAgICAgICAgICAgID0gL14oPzohfFteLFxcW1xcXVxce1xcfV0pKD86JVswLTlhLWZdezJ9fFswLTlhLXpcXC0jO1xcL1xcPzpAJj1cXCtcXCQsX1xcLiF+XFwqJ1xcKFxcKVxcW1xcXV0pKiQvaTtcblxuXG5mdW5jdGlvbiBpc19FT0woYykge1xuICByZXR1cm4gKGMgPT09IDB4MEEvKiBMRiAqLykgfHwgKGMgPT09IDB4MEQvKiBDUiAqLyk7XG59XG5cbmZ1bmN0aW9uIGlzX1dISVRFX1NQQUNFKGMpIHtcbiAgcmV0dXJuIChjID09PSAweDA5LyogVGFiICovKSB8fCAoYyA9PT0gMHgyMC8qIFNwYWNlICovKTtcbn1cblxuZnVuY3Rpb24gaXNfV1NfT1JfRU9MKGMpIHtcbiAgcmV0dXJuIChjID09PSAweDA5LyogVGFiICovKSB8fFxuICAgICAgICAgKGMgPT09IDB4MjAvKiBTcGFjZSAqLykgfHxcbiAgICAgICAgIChjID09PSAweDBBLyogTEYgKi8pIHx8XG4gICAgICAgICAoYyA9PT0gMHgwRC8qIENSICovKTtcbn1cblxuZnVuY3Rpb24gaXNfRkxPV19JTkRJQ0FUT1IoYykge1xuICByZXR1cm4gMHgyQy8qICwgKi8gPT09IGMgfHxcbiAgICAgICAgIDB4NUIvKiBbICovID09PSBjIHx8XG4gICAgICAgICAweDVELyogXSAqLyA9PT0gYyB8fFxuICAgICAgICAgMHg3Qi8qIHsgKi8gPT09IGMgfHxcbiAgICAgICAgIDB4N0QvKiB9ICovID09PSBjO1xufVxuXG5mdW5jdGlvbiBmcm9tSGV4Q29kZShjKSB7XG4gIHZhciBsYztcblxuICBpZiAoKDB4MzAvKiAwICovIDw9IGMpICYmIChjIDw9IDB4MzkvKiA5ICovKSkge1xuICAgIHJldHVybiBjIC0gMHgzMDtcbiAgfVxuXG4gIC8qZXNsaW50LWRpc2FibGUgbm8tYml0d2lzZSovXG4gIGxjID0gYyB8IDB4MjA7XG5cbiAgaWYgKCgweDYxLyogYSAqLyA8PSBsYykgJiYgKGxjIDw9IDB4NjYvKiBmICovKSkge1xuICAgIHJldHVybiBsYyAtIDB4NjEgKyAxMDtcbiAgfVxuXG4gIHJldHVybiAtMTtcbn1cblxuZnVuY3Rpb24gZXNjYXBlZEhleExlbihjKSB7XG4gIGlmIChjID09PSAweDc4LyogeCAqLykgeyByZXR1cm4gMjsgfVxuICBpZiAoYyA9PT0gMHg3NS8qIHUgKi8pIHsgcmV0dXJuIDQ7IH1cbiAgaWYgKGMgPT09IDB4NTUvKiBVICovKSB7IHJldHVybiA4OyB9XG4gIHJldHVybiAwO1xufVxuXG5mdW5jdGlvbiBmcm9tRGVjaW1hbENvZGUoYykge1xuICBpZiAoKDB4MzAvKiAwICovIDw9IGMpICYmIChjIDw9IDB4MzkvKiA5ICovKSkge1xuICAgIHJldHVybiBjIC0gMHgzMDtcbiAgfVxuXG4gIHJldHVybiAtMTtcbn1cblxuZnVuY3Rpb24gc2ltcGxlRXNjYXBlU2VxdWVuY2UoYykge1xuICByZXR1cm4gKGMgPT09IDB4MzAvKiAwICovKSA/ICdcXHgwMCcgOlxuICAgICAgICAoYyA9PT0gMHg2MS8qIGEgKi8pID8gJ1xceDA3JyA6XG4gICAgICAgIChjID09PSAweDYyLyogYiAqLykgPyAnXFx4MDgnIDpcbiAgICAgICAgKGMgPT09IDB4NzQvKiB0ICovKSA/ICdcXHgwOScgOlxuICAgICAgICAoYyA9PT0gMHgwOS8qIFRhYiAqLykgPyAnXFx4MDknIDpcbiAgICAgICAgKGMgPT09IDB4NkUvKiBuICovKSA/ICdcXHgwQScgOlxuICAgICAgICAoYyA9PT0gMHg3Ni8qIHYgKi8pID8gJ1xceDBCJyA6XG4gICAgICAgIChjID09PSAweDY2LyogZiAqLykgPyAnXFx4MEMnIDpcbiAgICAgICAgKGMgPT09IDB4NzIvKiByICovKSA/ICdcXHgwRCcgOlxuICAgICAgICAoYyA9PT0gMHg2NS8qIGUgKi8pID8gJ1xceDFCJyA6XG4gICAgICAgIChjID09PSAweDIwLyogU3BhY2UgKi8pID8gJyAnIDpcbiAgICAgICAgKGMgPT09IDB4MjIvKiBcIiAqLykgPyAnXFx4MjInIDpcbiAgICAgICAgKGMgPT09IDB4MkYvKiAvICovKSA/ICcvJyA6XG4gICAgICAgIChjID09PSAweDVDLyogXFwgKi8pID8gJ1xceDVDJyA6XG4gICAgICAgIChjID09PSAweDRFLyogTiAqLykgPyAnXFx4ODUnIDpcbiAgICAgICAgKGMgPT09IDB4NUYvKiBfICovKSA/ICdcXHhBMCcgOlxuICAgICAgICAoYyA9PT0gMHg0Qy8qIEwgKi8pID8gJ1xcdTIwMjgnIDpcbiAgICAgICAgKGMgPT09IDB4NTAvKiBQICovKSA/ICdcXHUyMDI5JyA6ICcnO1xufVxuXG5mdW5jdGlvbiBjaGFyRnJvbUNvZGVwb2ludChjKSB7XG4gIGlmIChjIDw9IDB4RkZGRikge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKGMpO1xuICB9XG4gIC8vIEVuY29kZSBVVEYtMTYgc3Vycm9nYXRlIHBhaXJcbiAgLy8gaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvVVRGLTE2I0NvZGVfcG9pbnRzX1UuMkIwMTAwMDBfdG9fVS4yQjEwRkZGRlxuICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZSgoKGMgLSAweDAxMDAwMCkgPj4gMTApICsgMHhEODAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKGMgLSAweDAxMDAwMCkgJiAweDAzRkYpICsgMHhEQzAwKTtcbn1cblxudmFyIHNpbXBsZUVzY2FwZUNoZWNrID0gbmV3IEFycmF5KDI1Nik7IC8vIGludGVnZXIsIGZvciBmYXN0IGFjY2Vzc1xudmFyIHNpbXBsZUVzY2FwZU1hcCA9IG5ldyBBcnJheSgyNTYpO1xuZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7IGkrKykge1xuICBzaW1wbGVFc2NhcGVDaGVja1tpXSA9IHNpbXBsZUVzY2FwZVNlcXVlbmNlKGkpID8gMSA6IDA7XG4gIHNpbXBsZUVzY2FwZU1hcFtpXSA9IHNpbXBsZUVzY2FwZVNlcXVlbmNlKGkpO1xufVxuXG5cbmZ1bmN0aW9uIFN0YXRlKGlucHV0LCBvcHRpb25zKSB7XG4gIHRoaXMuaW5wdXQgPSBpbnB1dDtcblxuICB0aGlzLmZpbGVuYW1lICA9IG9wdGlvbnNbJ2ZpbGVuYW1lJ10gIHx8IG51bGw7XG4gIHRoaXMuc2NoZW1hICAgID0gb3B0aW9uc1snc2NoZW1hJ10gICAgfHwgREVGQVVMVF9GVUxMX1NDSEVNQTtcbiAgdGhpcy5vbldhcm5pbmcgPSBvcHRpb25zWydvbldhcm5pbmcnXSB8fCBudWxsO1xuICB0aGlzLmxlZ2FjeSAgICA9IG9wdGlvbnNbJ2xlZ2FjeSddICAgIHx8IGZhbHNlO1xuXG4gIHRoaXMuaW1wbGljaXRUeXBlcyA9IHRoaXMuc2NoZW1hLmNvbXBpbGVkSW1wbGljaXQ7XG4gIHRoaXMudHlwZU1hcCAgICAgICA9IHRoaXMuc2NoZW1hLmNvbXBpbGVkVHlwZU1hcDtcblxuICB0aGlzLmxlbmd0aCAgICAgPSBpbnB1dC5sZW5ndGg7XG4gIHRoaXMucG9zaXRpb24gICA9IDA7XG4gIHRoaXMubGluZSAgICAgICA9IDA7XG4gIHRoaXMubGluZVN0YXJ0ICA9IDA7XG4gIHRoaXMubGluZUluZGVudCA9IDA7XG5cbiAgdGhpcy5kb2N1bWVudHMgPSBbXTtcblxuICAvKlxuICB0aGlzLnZlcnNpb247XG4gIHRoaXMuY2hlY2tMaW5lQnJlYWtzO1xuICB0aGlzLnRhZ01hcDtcbiAgdGhpcy5hbmNob3JNYXA7XG4gIHRoaXMudGFnO1xuICB0aGlzLmFuY2hvcjtcbiAgdGhpcy5raW5kO1xuICB0aGlzLnJlc3VsdDsqL1xuXG59XG5cblxuZnVuY3Rpb24gZ2VuZXJhdGVFcnJvcihzdGF0ZSwgbWVzc2FnZSkge1xuICByZXR1cm4gbmV3IFlBTUxFeGNlcHRpb24oXG4gICAgbWVzc2FnZSxcbiAgICBuZXcgTWFyayhzdGF0ZS5maWxlbmFtZSwgc3RhdGUuaW5wdXQsIHN0YXRlLnBvc2l0aW9uLCBzdGF0ZS5saW5lLCAoc3RhdGUucG9zaXRpb24gLSBzdGF0ZS5saW5lU3RhcnQpKSk7XG59XG5cbmZ1bmN0aW9uIHRocm93RXJyb3Ioc3RhdGUsIG1lc3NhZ2UpIHtcbiAgdGhyb3cgZ2VuZXJhdGVFcnJvcihzdGF0ZSwgbWVzc2FnZSk7XG59XG5cbmZ1bmN0aW9uIHRocm93V2FybmluZyhzdGF0ZSwgbWVzc2FnZSkge1xuICB2YXIgZXJyb3IgPSBnZW5lcmF0ZUVycm9yKHN0YXRlLCBtZXNzYWdlKTtcblxuICBpZiAoc3RhdGUub25XYXJuaW5nKSB7XG4gICAgc3RhdGUub25XYXJuaW5nLmNhbGwobnVsbCwgZXJyb3IpO1xuICB9IGVsc2Uge1xuICAgIHRocm93IGVycm9yO1xuICB9XG59XG5cblxudmFyIGRpcmVjdGl2ZUhhbmRsZXJzID0ge1xuXG4gIFlBTUw6IGZ1bmN0aW9uIGhhbmRsZVlhbWxEaXJlY3RpdmUoc3RhdGUsIG5hbWUsIGFyZ3MpIHtcblxuICAgICAgdmFyIG1hdGNoLCBtYWpvciwgbWlub3I7XG5cbiAgICAgIGlmIChudWxsICE9PSBzdGF0ZS52ZXJzaW9uKSB7XG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdkdXBsaWNhdGlvbiBvZiAlWUFNTCBkaXJlY3RpdmUnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKDEgIT09IGFyZ3MubGVuZ3RoKSB7XG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdZQU1MIGRpcmVjdGl2ZSBhY2NlcHRzIGV4YWN0bHkgb25lIGFyZ3VtZW50Jyk7XG4gICAgICB9XG5cbiAgICAgIG1hdGNoID0gL14oWzAtOV0rKVxcLihbMC05XSspJC8uZXhlYyhhcmdzWzBdKTtcblxuICAgICAgaWYgKG51bGwgPT09IG1hdGNoKSB7XG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdpbGwtZm9ybWVkIGFyZ3VtZW50IG9mIHRoZSBZQU1MIGRpcmVjdGl2ZScpO1xuICAgICAgfVxuXG4gICAgICBtYWpvciA9IHBhcnNlSW50KG1hdGNoWzFdLCAxMCk7XG4gICAgICBtaW5vciA9IHBhcnNlSW50KG1hdGNoWzJdLCAxMCk7XG5cbiAgICAgIGlmICgxICE9PSBtYWpvcikge1xuICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndW5hY2NlcHRhYmxlIFlBTUwgdmVyc2lvbiBvZiB0aGUgZG9jdW1lbnQnKTtcbiAgICAgIH1cblxuICAgICAgc3RhdGUudmVyc2lvbiA9IGFyZ3NbMF07XG4gICAgICBzdGF0ZS5jaGVja0xpbmVCcmVha3MgPSAobWlub3IgPCAyKTtcblxuICAgICAgaWYgKDEgIT09IG1pbm9yICYmIDIgIT09IG1pbm9yKSB7XG4gICAgICAgIHRocm93V2FybmluZyhzdGF0ZSwgJ3Vuc3VwcG9ydGVkIFlBTUwgdmVyc2lvbiBvZiB0aGUgZG9jdW1lbnQnKTtcbiAgICAgIH1cbiAgICB9LFxuXG4gIFRBRzogZnVuY3Rpb24gaGFuZGxlVGFnRGlyZWN0aXZlKHN0YXRlLCBuYW1lLCBhcmdzKSB7XG5cbiAgICAgIHZhciBoYW5kbGUsIHByZWZpeDtcblxuICAgICAgaWYgKDIgIT09IGFyZ3MubGVuZ3RoKSB7XG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdUQUcgZGlyZWN0aXZlIGFjY2VwdHMgZXhhY3RseSB0d28gYXJndW1lbnRzJyk7XG4gICAgICB9XG5cbiAgICAgIGhhbmRsZSA9IGFyZ3NbMF07XG4gICAgICBwcmVmaXggPSBhcmdzWzFdO1xuXG4gICAgICBpZiAoIVBBVFRFUk5fVEFHX0hBTkRMRS50ZXN0KGhhbmRsZSkpIHtcbiAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2lsbC1mb3JtZWQgdGFnIGhhbmRsZSAoZmlyc3QgYXJndW1lbnQpIG9mIHRoZSBUQUcgZGlyZWN0aXZlJyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChfaGFzT3duUHJvcGVydHkuY2FsbChzdGF0ZS50YWdNYXAsIGhhbmRsZSkpIHtcbiAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3RoZXJlIGlzIGEgcHJldmlvdXNseSBkZWNsYXJlZCBzdWZmaXggZm9yIFwiJyArIGhhbmRsZSArICdcIiB0YWcgaGFuZGxlJyk7XG4gICAgICB9XG5cbiAgICAgIGlmICghUEFUVEVSTl9UQUdfVVJJLnRlc3QocHJlZml4KSkge1xuICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnaWxsLWZvcm1lZCB0YWcgcHJlZml4IChzZWNvbmQgYXJndW1lbnQpIG9mIHRoZSBUQUcgZGlyZWN0aXZlJyk7XG4gICAgICB9XG5cbiAgICAgIHN0YXRlLnRhZ01hcFtoYW5kbGVdID0gcHJlZml4O1xuICAgIH1cbn07XG5cblxuZnVuY3Rpb24gY2FwdHVyZVNlZ21lbnQoc3RhdGUsIHN0YXJ0LCBlbmQsIGNoZWNrSnNvbikge1xuICB2YXIgX3Bvc2l0aW9uLCBfbGVuZ3RoLCBfY2hhcmFjdGVyLCBfcmVzdWx0O1xuXG4gIGlmIChzdGFydCA8IGVuZCkge1xuICAgIF9yZXN1bHQgPSBzdGF0ZS5pbnB1dC5zbGljZShzdGFydCwgZW5kKTtcblxuICAgIGlmIChjaGVja0pzb24pIHtcbiAgICAgIGZvciAoX3Bvc2l0aW9uID0gMCwgX2xlbmd0aCA9IF9yZXN1bHQubGVuZ3RoO1xuICAgICAgICAgICBfcG9zaXRpb24gPCBfbGVuZ3RoO1xuICAgICAgICAgICBfcG9zaXRpb24gKz0gMSkge1xuICAgICAgICBfY2hhcmFjdGVyID0gX3Jlc3VsdC5jaGFyQ29kZUF0KF9wb3NpdGlvbik7XG4gICAgICAgIGlmICghKDB4MDkgPT09IF9jaGFyYWN0ZXIgfHxcbiAgICAgICAgICAgICAgMHgyMCA8PSBfY2hhcmFjdGVyICYmIF9jaGFyYWN0ZXIgPD0gMHgxMEZGRkYpKSB7XG4gICAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2V4cGVjdGVkIHZhbGlkIEpTT04gY2hhcmFjdGVyJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBzdGF0ZS5yZXN1bHQgKz0gX3Jlc3VsdDtcbiAgfVxufVxuXG5mdW5jdGlvbiBtZXJnZU1hcHBpbmdzKHN0YXRlLCBkZXN0aW5hdGlvbiwgc291cmNlKSB7XG4gIHZhciBzb3VyY2VLZXlzLCBrZXksIGluZGV4LCBxdWFudGl0eTtcblxuICBpZiAoIWNvbW1vbi5pc09iamVjdChzb3VyY2UpKSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2Nhbm5vdCBtZXJnZSBtYXBwaW5nczsgdGhlIHByb3ZpZGVkIHNvdXJjZSBvYmplY3QgaXMgdW5hY2NlcHRhYmxlJyk7XG4gIH1cblxuICBzb3VyY2VLZXlzID0gT2JqZWN0LmtleXMoc291cmNlKTtcblxuICBmb3IgKGluZGV4ID0gMCwgcXVhbnRpdHkgPSBzb3VyY2VLZXlzLmxlbmd0aDsgaW5kZXggPCBxdWFudGl0eTsgaW5kZXggKz0gMSkge1xuICAgIGtleSA9IHNvdXJjZUtleXNbaW5kZXhdO1xuXG4gICAgaWYgKCFfaGFzT3duUHJvcGVydHkuY2FsbChkZXN0aW5hdGlvbiwga2V5KSkge1xuICAgICAgZGVzdGluYXRpb25ba2V5XSA9IHNvdXJjZVtrZXldO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBzdG9yZU1hcHBpbmdQYWlyKHN0YXRlLCBfcmVzdWx0LCBrZXlUYWcsIGtleU5vZGUsIHZhbHVlTm9kZSkge1xuICB2YXIgaW5kZXgsIHF1YW50aXR5O1xuXG4gIGtleU5vZGUgPSBTdHJpbmcoa2V5Tm9kZSk7XG5cbiAgaWYgKG51bGwgPT09IF9yZXN1bHQpIHtcbiAgICBfcmVzdWx0ID0ge307XG4gIH1cblxuICBpZiAoJ3RhZzp5YW1sLm9yZywyMDAyOm1lcmdlJyA9PT0ga2V5VGFnKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWVOb2RlKSkge1xuICAgICAgZm9yIChpbmRleCA9IDAsIHF1YW50aXR5ID0gdmFsdWVOb2RlLmxlbmd0aDsgaW5kZXggPCBxdWFudGl0eTsgaW5kZXggKz0gMSkge1xuICAgICAgICBtZXJnZU1hcHBpbmdzKHN0YXRlLCBfcmVzdWx0LCB2YWx1ZU5vZGVbaW5kZXhdKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgbWVyZ2VNYXBwaW5ncyhzdGF0ZSwgX3Jlc3VsdCwgdmFsdWVOb2RlKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgX3Jlc3VsdFtrZXlOb2RlXSA9IHZhbHVlTm9kZTtcbiAgfVxuXG4gIHJldHVybiBfcmVzdWx0O1xufVxuXG5mdW5jdGlvbiByZWFkTGluZUJyZWFrKHN0YXRlKSB7XG4gIHZhciBjaDtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmICgweDBBLyogTEYgKi8gPT09IGNoKSB7XG4gICAgc3RhdGUucG9zaXRpb24rKztcbiAgfSBlbHNlIGlmICgweDBELyogQ1IgKi8gPT09IGNoKSB7XG4gICAgc3RhdGUucG9zaXRpb24rKztcbiAgICBpZiAoMHgwQS8qIExGICovID09PSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKSkge1xuICAgICAgc3RhdGUucG9zaXRpb24rKztcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2EgbGluZSBicmVhayBpcyBleHBlY3RlZCcpO1xuICB9XG5cbiAgc3RhdGUubGluZSArPSAxO1xuICBzdGF0ZS5saW5lU3RhcnQgPSBzdGF0ZS5wb3NpdGlvbjtcbn1cblxuZnVuY3Rpb24gc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgYWxsb3dDb21tZW50cywgY2hlY2tJbmRlbnQpIHtcbiAgdmFyIGxpbmVCcmVha3MgPSAwLFxuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICB3aGlsZSAoMCAhPT0gY2gpIHtcbiAgICB3aGlsZSAoaXNfV0hJVEVfU1BBQ0UoY2gpKSB7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgfVxuXG4gICAgaWYgKGFsbG93Q29tbWVudHMgJiYgMHgyMy8qICMgKi8gPT09IGNoKSB7XG4gICAgICBkbyB7XG4gICAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgICAgIH0gd2hpbGUgKGNoICE9PSAweDBBLyogTEYgKi8gJiYgY2ggIT09IDB4MEQvKiBDUiAqLyAmJiAwICE9PSBjaCk7XG4gICAgfVxuXG4gICAgaWYgKGlzX0VPTChjaCkpIHtcbiAgICAgIHJlYWRMaW5lQnJlYWsoc3RhdGUpO1xuXG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuICAgICAgbGluZUJyZWFrcysrO1xuICAgICAgc3RhdGUubGluZUluZGVudCA9IDA7XG5cbiAgICAgIHdoaWxlICgweDIwLyogU3BhY2UgKi8gPT09IGNoKSB7XG4gICAgICAgIHN0YXRlLmxpbmVJbmRlbnQrKztcbiAgICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBpZiAoLTEgIT09IGNoZWNrSW5kZW50ICYmIDAgIT09IGxpbmVCcmVha3MgJiYgc3RhdGUubGluZUluZGVudCA8IGNoZWNrSW5kZW50KSB7XG4gICAgdGhyb3dXYXJuaW5nKHN0YXRlLCAnZGVmaWNpZW50IGluZGVudGF0aW9uJyk7XG4gIH1cblxuICByZXR1cm4gbGluZUJyZWFrcztcbn1cblxuZnVuY3Rpb24gdGVzdERvY3VtZW50U2VwYXJhdG9yKHN0YXRlKSB7XG4gIHZhciBfcG9zaXRpb24gPSBzdGF0ZS5wb3NpdGlvbixcbiAgICAgIGNoO1xuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChfcG9zaXRpb24pO1xuXG4gIC8vIENvbmRpdGlvbiBzdGF0ZS5wb3NpdGlvbiA9PT0gc3RhdGUubGluZVN0YXJ0IGlzIHRlc3RlZFxuICAvLyBpbiBwYXJlbnQgb24gZWFjaCBjYWxsLCBmb3IgZWZmaWNpZW5jeS4gTm8gbmVlZHMgdG8gdGVzdCBoZXJlIGFnYWluLlxuICBpZiAoKDB4MkQvKiAtICovID09PSBjaCB8fCAweDJFLyogLiAqLyA9PT0gY2gpICYmXG4gICAgICBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KF9wb3NpdGlvbiArIDEpID09PSBjaCAmJlxuICAgICAgc3RhdGUuaW5wdXQuY2hhckNvZGVBdChfcG9zaXRpb24gKyAyKSA9PT0gY2gpIHtcblxuICAgIF9wb3NpdGlvbiArPSAzO1xuXG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KF9wb3NpdGlvbik7XG5cbiAgICBpZiAoY2ggPT09IDAgfHwgaXNfV1NfT1JfRU9MKGNoKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiB3cml0ZUZvbGRlZExpbmVzKHN0YXRlLCBjb3VudCkge1xuICBpZiAoMSA9PT0gY291bnQpIHtcbiAgICBzdGF0ZS5yZXN1bHQgKz0gJyAnO1xuICB9IGVsc2UgaWYgKGNvdW50ID4gMSkge1xuICAgIHN0YXRlLnJlc3VsdCArPSBjb21tb24ucmVwZWF0KCdcXG4nLCBjb3VudCAtIDEpO1xuICB9XG59XG5cblxuZnVuY3Rpb24gcmVhZFBsYWluU2NhbGFyKHN0YXRlLCBub2RlSW5kZW50LCB3aXRoaW5GbG93Q29sbGVjdGlvbikge1xuICB2YXIgcHJlY2VkaW5nLFxuICAgICAgZm9sbG93aW5nLFxuICAgICAgY2FwdHVyZVN0YXJ0LFxuICAgICAgY2FwdHVyZUVuZCxcbiAgICAgIGhhc1BlbmRpbmdDb250ZW50LFxuICAgICAgX2xpbmUsXG4gICAgICBfbGluZVN0YXJ0LFxuICAgICAgX2xpbmVJbmRlbnQsXG4gICAgICBfa2luZCA9IHN0YXRlLmtpbmQsXG4gICAgICBfcmVzdWx0ID0gc3RhdGUucmVzdWx0LFxuICAgICAgY2g7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoaXNfV1NfT1JfRU9MKGNoKSAgICAgICAgICAgICB8fFxuICAgICAgaXNfRkxPV19JTkRJQ0FUT1IoY2gpICAgICAgICB8fFxuICAgICAgMHgyMy8qICMgKi8gICAgICAgICAgID09PSBjaCB8fFxuICAgICAgMHgyNi8qICYgKi8gICAgICAgICAgID09PSBjaCB8fFxuICAgICAgMHgyQS8qICogKi8gICAgICAgICAgID09PSBjaCB8fFxuICAgICAgMHgyMS8qICEgKi8gICAgICAgICAgID09PSBjaCB8fFxuICAgICAgMHg3Qy8qIHwgKi8gICAgICAgICAgID09PSBjaCB8fFxuICAgICAgMHgzRS8qID4gKi8gICAgICAgICAgID09PSBjaCB8fFxuICAgICAgMHgyNy8qICcgKi8gICAgICAgICAgID09PSBjaCB8fFxuICAgICAgMHgyMi8qIFwiICovICAgICAgICAgICA9PT0gY2ggfHxcbiAgICAgIDB4MjUvKiAlICovICAgICAgICAgICA9PT0gY2ggfHxcbiAgICAgIDB4NDAvKiBAICovICAgICAgICAgICA9PT0gY2ggfHxcbiAgICAgIDB4NjAvKiBgICovICAgICAgICAgICA9PT0gY2gpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAoMHgzRi8qID8gKi8gPT09IGNoIHx8IDB4MkQvKiAtICovID09PSBjaCkge1xuICAgIGZvbGxvd2luZyA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24gKyAxKTtcblxuICAgIGlmIChpc19XU19PUl9FT0woZm9sbG93aW5nKSB8fFxuICAgICAgICB3aXRoaW5GbG93Q29sbGVjdGlvbiAmJiBpc19GTE9XX0lORElDQVRPUihmb2xsb3dpbmcpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgc3RhdGUua2luZCA9ICdzY2FsYXInO1xuICBzdGF0ZS5yZXN1bHQgPSAnJztcbiAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuICBoYXNQZW5kaW5nQ29udGVudCA9IGZhbHNlO1xuXG4gIHdoaWxlICgwICE9PSBjaCkge1xuICAgIGlmICgweDNBLyogOiAqLyA9PT0gY2gpIHtcbiAgICAgIGZvbGxvd2luZyA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24gKyAxKTtcblxuICAgICAgaWYgKGlzX1dTX09SX0VPTChmb2xsb3dpbmcpIHx8XG4gICAgICAgICAgd2l0aGluRmxvd0NvbGxlY3Rpb24gJiYgaXNfRkxPV19JTkRJQ0FUT1IoZm9sbG93aW5nKSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIH0gZWxzZSBpZiAoMHgyMy8qICMgKi8gPT09IGNoKSB7XG4gICAgICBwcmVjZWRpbmcgPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uIC0gMSk7XG5cbiAgICAgIGlmIChpc19XU19PUl9FT0wocHJlY2VkaW5nKSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIH0gZWxzZSBpZiAoKHN0YXRlLnBvc2l0aW9uID09PSBzdGF0ZS5saW5lU3RhcnQgJiYgdGVzdERvY3VtZW50U2VwYXJhdG9yKHN0YXRlKSkgfHxcbiAgICAgICAgICAgICAgIHdpdGhpbkZsb3dDb2xsZWN0aW9uICYmIGlzX0ZMT1dfSU5ESUNBVE9SKGNoKSkge1xuICAgICAgYnJlYWs7XG5cbiAgICB9IGVsc2UgaWYgKGlzX0VPTChjaCkpIHtcbiAgICAgIF9saW5lID0gc3RhdGUubGluZTtcbiAgICAgIF9saW5lU3RhcnQgPSBzdGF0ZS5saW5lU3RhcnQ7XG4gICAgICBfbGluZUluZGVudCA9IHN0YXRlLmxpbmVJbmRlbnQ7XG4gICAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCBmYWxzZSwgLTEpO1xuXG4gICAgICBpZiAoc3RhdGUubGluZUluZGVudCA+PSBub2RlSW5kZW50KSB7XG4gICAgICAgIGhhc1BlbmRpbmdDb250ZW50ID0gdHJ1ZTtcbiAgICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdGF0ZS5wb3NpdGlvbiA9IGNhcHR1cmVFbmQ7XG4gICAgICAgIHN0YXRlLmxpbmUgPSBfbGluZTtcbiAgICAgICAgc3RhdGUubGluZVN0YXJ0ID0gX2xpbmVTdGFydDtcbiAgICAgICAgc3RhdGUubGluZUluZGVudCA9IF9saW5lSW5kZW50O1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaGFzUGVuZGluZ0NvbnRlbnQpIHtcbiAgICAgIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIGNhcHR1cmVFbmQsIGZhbHNlKTtcbiAgICAgIHdyaXRlRm9sZGVkTGluZXMoc3RhdGUsIHN0YXRlLmxpbmUgLSBfbGluZSk7XG4gICAgICBjYXB0dXJlU3RhcnQgPSBjYXB0dXJlRW5kID0gc3RhdGUucG9zaXRpb247XG4gICAgICBoYXNQZW5kaW5nQ29udGVudCA9IGZhbHNlO1xuICAgIH1cblxuICAgIGlmICghaXNfV0hJVEVfU1BBQ0UoY2gpKSB7XG4gICAgICBjYXB0dXJlRW5kID0gc3RhdGUucG9zaXRpb24gKyAxO1xuICAgIH1cblxuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgfVxuXG4gIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIGNhcHR1cmVFbmQsIGZhbHNlKTtcblxuICBpZiAoc3RhdGUucmVzdWx0KSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBzdGF0ZS5raW5kID0gX2tpbmQ7XG4gIHN0YXRlLnJlc3VsdCA9IF9yZXN1bHQ7XG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gcmVhZFNpbmdsZVF1b3RlZFNjYWxhcihzdGF0ZSwgbm9kZUluZGVudCkge1xuICB2YXIgY2gsXG4gICAgICBjYXB0dXJlU3RhcnQsIGNhcHR1cmVFbmQ7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoMHgyNy8qICcgKi8gIT09IGNoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgc3RhdGUua2luZCA9ICdzY2FsYXInO1xuICBzdGF0ZS5yZXN1bHQgPSAnJztcbiAgc3RhdGUucG9zaXRpb24rKztcbiAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gIHdoaWxlICgwICE9PSAoY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKSkpIHtcbiAgICBpZiAoMHgyNy8qICcgKi8gPT09IGNoKSB7XG4gICAgICBjYXB0dXJlU2VnbWVudChzdGF0ZSwgY2FwdHVyZVN0YXJ0LCBzdGF0ZS5wb3NpdGlvbiwgdHJ1ZSk7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICAgIGlmICgweDI3LyogJyAqLyA9PT0gY2gpIHtcbiAgICAgICAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuICAgICAgICBzdGF0ZS5wb3NpdGlvbisrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICB9IGVsc2UgaWYgKGlzX0VPTChjaCkpIHtcbiAgICAgIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIGNhcHR1cmVFbmQsIHRydWUpO1xuICAgICAgd3JpdGVGb2xkZWRMaW5lcyhzdGF0ZSwgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgZmFsc2UsIG5vZGVJbmRlbnQpKTtcbiAgICAgIGNhcHR1cmVTdGFydCA9IGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbjtcblxuICAgIH0gZWxzZSBpZiAoc3RhdGUucG9zaXRpb24gPT09IHN0YXRlLmxpbmVTdGFydCAmJiB0ZXN0RG9jdW1lbnRTZXBhcmF0b3Ioc3RhdGUpKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndW5leHBlY3RlZCBlbmQgb2YgdGhlIGRvY3VtZW50IHdpdGhpbiBhIHNpbmdsZSBxdW90ZWQgc2NhbGFyJyk7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgc3RhdGUucG9zaXRpb24rKztcbiAgICAgIGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbjtcbiAgICB9XG4gIH1cblxuICB0aHJvd0Vycm9yKHN0YXRlLCAndW5leHBlY3RlZCBlbmQgb2YgdGhlIHN0cmVhbSB3aXRoaW4gYSBzaW5nbGUgcXVvdGVkIHNjYWxhcicpO1xufVxuXG5mdW5jdGlvbiByZWFkRG91YmxlUXVvdGVkU2NhbGFyKHN0YXRlLCBub2RlSW5kZW50KSB7XG4gIHZhciBjYXB0dXJlU3RhcnQsXG4gICAgICBjYXB0dXJlRW5kLFxuICAgICAgaGV4TGVuZ3RoLFxuICAgICAgaGV4UmVzdWx0LFxuICAgICAgdG1wLCB0bXBFc2MsXG4gICAgICBjaDtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmICgweDIyLyogXCIgKi8gIT09IGNoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgc3RhdGUua2luZCA9ICdzY2FsYXInO1xuICBzdGF0ZS5yZXN1bHQgPSAnJztcbiAgc3RhdGUucG9zaXRpb24rKztcbiAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gIHdoaWxlICgwICE9PSAoY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKSkpIHtcbiAgICBpZiAoMHgyMi8qIFwiICovID09PSBjaCkge1xuICAgICAgY2FwdHVyZVNlZ21lbnQoc3RhdGUsIGNhcHR1cmVTdGFydCwgc3RhdGUucG9zaXRpb24sIHRydWUpO1xuICAgICAgc3RhdGUucG9zaXRpb24rKztcbiAgICAgIHJldHVybiB0cnVlO1xuXG4gICAgfSBlbHNlIGlmICgweDVDLyogXFwgKi8gPT09IGNoKSB7XG4gICAgICBjYXB0dXJlU2VnbWVudChzdGF0ZSwgY2FwdHVyZVN0YXJ0LCBzdGF0ZS5wb3NpdGlvbiwgdHJ1ZSk7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICAgIGlmIChpc19FT0woY2gpKSB7XG4gICAgICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIGZhbHNlLCBub2RlSW5kZW50KTtcblxuICAgICAgICAvLyBUT0RPOiByZXdvcmsgdG8gaW5saW5lIGZuIHdpdGggbm8gdHlwZSBjYXN0P1xuICAgICAgfSBlbHNlIGlmIChjaCA8IDI1NiAmJiBzaW1wbGVFc2NhcGVDaGVja1tjaF0pIHtcbiAgICAgICAgc3RhdGUucmVzdWx0ICs9IHNpbXBsZUVzY2FwZU1hcFtjaF07XG4gICAgICAgIHN0YXRlLnBvc2l0aW9uKys7XG5cbiAgICAgIH0gZWxzZSBpZiAoKHRtcCA9IGVzY2FwZWRIZXhMZW4oY2gpKSA+IDApIHtcbiAgICAgICAgaGV4TGVuZ3RoID0gdG1wO1xuICAgICAgICBoZXhSZXN1bHQgPSAwO1xuXG4gICAgICAgIGZvciAoOyBoZXhMZW5ndGggPiAwOyBoZXhMZW5ndGgtLSkge1xuICAgICAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcblxuICAgICAgICAgIGlmICgodG1wID0gZnJvbUhleENvZGUoY2gpKSA+PSAwKSB7XG4gICAgICAgICAgICBoZXhSZXN1bHQgPSAoaGV4UmVzdWx0IDw8IDQpICsgdG1wO1xuXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdleHBlY3RlZCBoZXhhZGVjaW1hbCBjaGFyYWN0ZXInKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBzdGF0ZS5yZXN1bHQgKz0gY2hhckZyb21Db2RlcG9pbnQoaGV4UmVzdWx0KTtcblxuICAgICAgICBzdGF0ZS5wb3NpdGlvbisrO1xuXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndW5rbm93biBlc2NhcGUgc2VxdWVuY2UnKTtcbiAgICAgIH1cblxuICAgICAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gICAgfSBlbHNlIGlmIChpc19FT0woY2gpKSB7XG4gICAgICBjYXB0dXJlU2VnbWVudChzdGF0ZSwgY2FwdHVyZVN0YXJ0LCBjYXB0dXJlRW5kLCB0cnVlKTtcbiAgICAgIHdyaXRlRm9sZGVkTGluZXMoc3RhdGUsIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIGZhbHNlLCBub2RlSW5kZW50KSk7XG4gICAgICBjYXB0dXJlU3RhcnQgPSBjYXB0dXJlRW5kID0gc3RhdGUucG9zaXRpb247XG5cbiAgICB9IGVsc2UgaWYgKHN0YXRlLnBvc2l0aW9uID09PSBzdGF0ZS5saW5lU3RhcnQgJiYgdGVzdERvY3VtZW50U2VwYXJhdG9yKHN0YXRlKSkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3VuZXhwZWN0ZWQgZW5kIG9mIHRoZSBkb2N1bWVudCB3aXRoaW4gYSBkb3VibGUgcXVvdGVkIHNjYWxhcicpO1xuXG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXRlLnBvc2l0aW9uKys7XG4gICAgICBjYXB0dXJlRW5kID0gc3RhdGUucG9zaXRpb247XG4gICAgfVxuICB9XG5cbiAgdGhyb3dFcnJvcihzdGF0ZSwgJ3VuZXhwZWN0ZWQgZW5kIG9mIHRoZSBzdHJlYW0gd2l0aGluIGEgZG91YmxlIHF1b3RlZCBzY2FsYXInKTtcbn1cblxuZnVuY3Rpb24gcmVhZEZsb3dDb2xsZWN0aW9uKHN0YXRlLCBub2RlSW5kZW50KSB7XG4gIHZhciByZWFkTmV4dCA9IHRydWUsXG4gICAgICBfbGluZSxcbiAgICAgIF90YWcgICAgID0gc3RhdGUudGFnLFxuICAgICAgX3Jlc3VsdCxcbiAgICAgIF9hbmNob3IgID0gc3RhdGUuYW5jaG9yLFxuICAgICAgZm9sbG93aW5nLFxuICAgICAgdGVybWluYXRvcixcbiAgICAgIGlzUGFpcixcbiAgICAgIGlzRXhwbGljaXRQYWlyLFxuICAgICAgaXNNYXBwaW5nLFxuICAgICAga2V5Tm9kZSxcbiAgICAgIGtleVRhZyxcbiAgICAgIHZhbHVlTm9kZSxcbiAgICAgIGNoO1xuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgaWYgKGNoID09PSAweDVCLyogWyAqLykge1xuICAgIHRlcm1pbmF0b3IgPSAweDVEOy8qIF0gKi9cbiAgICBpc01hcHBpbmcgPSBmYWxzZTtcbiAgICBfcmVzdWx0ID0gW107XG4gIH0gZWxzZSBpZiAoY2ggPT09IDB4N0IvKiB7ICovKSB7XG4gICAgdGVybWluYXRvciA9IDB4N0Q7LyogfSAqL1xuICAgIGlzTWFwcGluZyA9IHRydWU7XG4gICAgX3Jlc3VsdCA9IHt9O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChudWxsICE9PSBzdGF0ZS5hbmNob3IpIHtcbiAgICBzdGF0ZS5hbmNob3JNYXBbc3RhdGUuYW5jaG9yXSA9IF9yZXN1bHQ7XG4gIH1cblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgd2hpbGUgKDAgIT09IGNoKSB7XG4gICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgbm9kZUluZGVudCk7XG5cbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gICAgaWYgKGNoID09PSB0ZXJtaW5hdG9yKSB7XG4gICAgICBzdGF0ZS5wb3NpdGlvbisrO1xuICAgICAgc3RhdGUudGFnID0gX3RhZztcbiAgICAgIHN0YXRlLmFuY2hvciA9IF9hbmNob3I7XG4gICAgICBzdGF0ZS5raW5kID0gaXNNYXBwaW5nID8gJ21hcHBpbmcnIDogJ3NlcXVlbmNlJztcbiAgICAgIHN0YXRlLnJlc3VsdCA9IF9yZXN1bHQ7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKCFyZWFkTmV4dCkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ21pc3NlZCBjb21tYSBiZXR3ZWVuIGZsb3cgY29sbGVjdGlvbiBlbnRyaWVzJyk7XG4gICAgfVxuXG4gICAga2V5VGFnID0ga2V5Tm9kZSA9IHZhbHVlTm9kZSA9IG51bGw7XG4gICAgaXNQYWlyID0gaXNFeHBsaWNpdFBhaXIgPSBmYWxzZTtcblxuICAgIGlmICgweDNGLyogPyAqLyA9PT0gY2gpIHtcbiAgICAgIGZvbGxvd2luZyA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24gKyAxKTtcblxuICAgICAgaWYgKGlzX1dTX09SX0VPTChmb2xsb3dpbmcpKSB7XG4gICAgICAgIGlzUGFpciA9IGlzRXhwbGljaXRQYWlyID0gdHJ1ZTtcbiAgICAgICAgc3RhdGUucG9zaXRpb24rKztcbiAgICAgICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgbm9kZUluZGVudCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgX2xpbmUgPSBzdGF0ZS5saW5lO1xuICAgIGNvbXBvc2VOb2RlKHN0YXRlLCBub2RlSW5kZW50LCBDT05URVhUX0ZMT1dfSU4sIGZhbHNlLCB0cnVlKTtcbiAgICBrZXlUYWcgPSBzdGF0ZS50YWc7XG4gICAga2V5Tm9kZSA9IHN0YXRlLnJlc3VsdDtcbiAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCBub2RlSW5kZW50KTtcblxuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICBpZiAoKGlzRXhwbGljaXRQYWlyIHx8IHN0YXRlLmxpbmUgPT09IF9saW5lKSAmJiAweDNBLyogOiAqLyA9PT0gY2gpIHtcbiAgICAgIGlzUGFpciA9IHRydWU7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCBub2RlSW5kZW50KTtcbiAgICAgIGNvbXBvc2VOb2RlKHN0YXRlLCBub2RlSW5kZW50LCBDT05URVhUX0ZMT1dfSU4sIGZhbHNlLCB0cnVlKTtcbiAgICAgIHZhbHVlTm9kZSA9IHN0YXRlLnJlc3VsdDtcbiAgICB9XG5cbiAgICBpZiAoaXNNYXBwaW5nKSB7XG4gICAgICBzdG9yZU1hcHBpbmdQYWlyKHN0YXRlLCBfcmVzdWx0LCBrZXlUYWcsIGtleU5vZGUsIHZhbHVlTm9kZSk7XG4gICAgfSBlbHNlIGlmIChpc1BhaXIpIHtcbiAgICAgIF9yZXN1bHQucHVzaChzdG9yZU1hcHBpbmdQYWlyKHN0YXRlLCBudWxsLCBrZXlUYWcsIGtleU5vZGUsIHZhbHVlTm9kZSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBfcmVzdWx0LnB1c2goa2V5Tm9kZSk7XG4gICAgfVxuXG4gICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgbm9kZUluZGVudCk7XG5cbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gICAgaWYgKDB4MkMvKiAsICovID09PSBjaCkge1xuICAgICAgcmVhZE5leHQgPSB0cnVlO1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZWFkTmV4dCA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHRocm93RXJyb3Ioc3RhdGUsICd1bmV4cGVjdGVkIGVuZCBvZiB0aGUgc3RyZWFtIHdpdGhpbiBhIGZsb3cgY29sbGVjdGlvbicpO1xufVxuXG5mdW5jdGlvbiByZWFkQmxvY2tTY2FsYXIoc3RhdGUsIG5vZGVJbmRlbnQpIHtcbiAgdmFyIGNhcHR1cmVTdGFydCxcbiAgICAgIGZvbGRpbmcsXG4gICAgICBjaG9tcGluZyAgICAgICA9IENIT01QSU5HX0NMSVAsXG4gICAgICBkZXRlY3RlZEluZGVudCA9IGZhbHNlLFxuICAgICAgdGV4dEluZGVudCAgICAgPSBub2RlSW5kZW50LFxuICAgICAgZW1wdHlMaW5lcyAgICAgPSAwLFxuICAgICAgYXRNb3JlSW5kZW50ZWQgPSBmYWxzZSxcbiAgICAgIHRtcCxcbiAgICAgIGNoO1xuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgaWYgKGNoID09PSAweDdDLyogfCAqLykge1xuICAgIGZvbGRpbmcgPSBmYWxzZTtcbiAgfSBlbHNlIGlmIChjaCA9PT0gMHgzRS8qID4gKi8pIHtcbiAgICBmb2xkaW5nID0gdHJ1ZTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBzdGF0ZS5raW5kID0gJ3NjYWxhcic7XG4gIHN0YXRlLnJlc3VsdCA9ICcnO1xuXG4gIHdoaWxlICgwICE9PSBjaCkge1xuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcblxuICAgIGlmICgweDJCLyogKyAqLyA9PT0gY2ggfHwgMHgyRC8qIC0gKi8gPT09IGNoKSB7XG4gICAgICBpZiAoQ0hPTVBJTkdfQ0xJUCA9PT0gY2hvbXBpbmcpIHtcbiAgICAgICAgY2hvbXBpbmcgPSAoMHgyQi8qICsgKi8gPT09IGNoKSA/IENIT01QSU5HX0tFRVAgOiBDSE9NUElOR19TVFJJUDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdyZXBlYXQgb2YgYSBjaG9tcGluZyBtb2RlIGlkZW50aWZpZXInKTtcbiAgICAgIH1cblxuICAgIH0gZWxzZSBpZiAoKHRtcCA9IGZyb21EZWNpbWFsQ29kZShjaCkpID49IDApIHtcbiAgICAgIGlmICh0bXAgPT09IDApIHtcbiAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2JhZCBleHBsaWNpdCBpbmRlbnRhdGlvbiB3aWR0aCBvZiBhIGJsb2NrIHNjYWxhcjsgaXQgY2Fubm90IGJlIGxlc3MgdGhhbiBvbmUnKTtcbiAgICAgIH0gZWxzZSBpZiAoIWRldGVjdGVkSW5kZW50KSB7XG4gICAgICAgIHRleHRJbmRlbnQgPSBub2RlSW5kZW50ICsgdG1wIC0gMTtcbiAgICAgICAgZGV0ZWN0ZWRJbmRlbnQgPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3JlcGVhdCBvZiBhbiBpbmRlbnRhdGlvbiB3aWR0aCBpZGVudGlmaWVyJyk7XG4gICAgICB9XG5cbiAgICB9IGVsc2Uge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgaWYgKGlzX1dISVRFX1NQQUNFKGNoKSkge1xuICAgIGRvIHsgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pOyB9XG4gICAgd2hpbGUgKGlzX1dISVRFX1NQQUNFKGNoKSk7XG5cbiAgICBpZiAoMHgyMy8qICMgKi8gPT09IGNoKSB7XG4gICAgICBkbyB7IGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTsgfVxuICAgICAgd2hpbGUgKCFpc19FT0woY2gpICYmICgwICE9PSBjaCkpO1xuICAgIH1cbiAgfVxuXG4gIHdoaWxlICgwICE9PSBjaCkge1xuICAgIHJlYWRMaW5lQnJlYWsoc3RhdGUpO1xuICAgIHN0YXRlLmxpbmVJbmRlbnQgPSAwO1xuXG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICAgIHdoaWxlICgoIWRldGVjdGVkSW5kZW50IHx8IHN0YXRlLmxpbmVJbmRlbnQgPCB0ZXh0SW5kZW50KSAmJlxuICAgICAgICAgICAoMHgyMC8qIFNwYWNlICovID09PSBjaCkpIHtcbiAgICAgIHN0YXRlLmxpbmVJbmRlbnQrKztcbiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgICB9XG5cbiAgICBpZiAoIWRldGVjdGVkSW5kZW50ICYmIHN0YXRlLmxpbmVJbmRlbnQgPiB0ZXh0SW5kZW50KSB7XG4gICAgICB0ZXh0SW5kZW50ID0gc3RhdGUubGluZUluZGVudDtcbiAgICB9XG5cbiAgICBpZiAoaXNfRU9MKGNoKSkge1xuICAgICAgZW1wdHlMaW5lcysrO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgLy8gRW5kIG9mIHRoZSBzY2FsYXIuXG4gICAgaWYgKHN0YXRlLmxpbmVJbmRlbnQgPCB0ZXh0SW5kZW50KSB7XG5cbiAgICAgIC8vIFBlcmZvcm0gdGhlIGNob21waW5nLlxuICAgICAgaWYgKGNob21waW5nID09PSBDSE9NUElOR19LRUVQKSB7XG4gICAgICAgIHN0YXRlLnJlc3VsdCArPSBjb21tb24ucmVwZWF0KCdcXG4nLCBlbXB0eUxpbmVzKTtcbiAgICAgIH0gZWxzZSBpZiAoY2hvbXBpbmcgPT09IENIT01QSU5HX0NMSVApIHtcbiAgICAgICAgaWYgKGRldGVjdGVkSW5kZW50KSB7IC8vIGkuZS4gb25seSBpZiB0aGUgc2NhbGFyIGlzIG5vdCBlbXB0eS5cbiAgICAgICAgICBzdGF0ZS5yZXN1bHQgKz0gJ1xcbic7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gQnJlYWsgdGhpcyBgd2hpbGVgIGN5Y2xlIGFuZCBnbyB0byB0aGUgZnVuY2l0b24ncyBlcGlsb2d1ZS5cbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIC8vIEZvbGRlZCBzdHlsZTogdXNlIGZhbmN5IHJ1bGVzIHRvIGhhbmRsZSBsaW5lIGJyZWFrcy5cbiAgICBpZiAoZm9sZGluZykge1xuXG4gICAgICAvLyBMaW5lcyBzdGFydGluZyB3aXRoIHdoaXRlIHNwYWNlIGNoYXJhY3RlcnMgKG1vcmUtaW5kZW50ZWQgbGluZXMpIGFyZSBub3QgZm9sZGVkLlxuICAgICAgaWYgKGlzX1dISVRFX1NQQUNFKGNoKSkge1xuICAgICAgICBhdE1vcmVJbmRlbnRlZCA9IHRydWU7XG4gICAgICAgIHN0YXRlLnJlc3VsdCArPSBjb21tb24ucmVwZWF0KCdcXG4nLCBlbXB0eUxpbmVzICsgMSk7XG5cbiAgICAgIC8vIEVuZCBvZiBtb3JlLWluZGVudGVkIGJsb2NrLlxuICAgICAgfSBlbHNlIGlmIChhdE1vcmVJbmRlbnRlZCkge1xuICAgICAgICBhdE1vcmVJbmRlbnRlZCA9IGZhbHNlO1xuICAgICAgICBzdGF0ZS5yZXN1bHQgKz0gY29tbW9uLnJlcGVhdCgnXFxuJywgZW1wdHlMaW5lcyArIDEpO1xuXG4gICAgICAvLyBKdXN0IG9uZSBsaW5lIGJyZWFrIC0gcGVyY2VpdmUgYXMgdGhlIHNhbWUgbGluZS5cbiAgICAgIH0gZWxzZSBpZiAoMCA9PT0gZW1wdHlMaW5lcykge1xuICAgICAgICBpZiAoZGV0ZWN0ZWRJbmRlbnQpIHsgLy8gaS5lLiBvbmx5IGlmIHdlIGhhdmUgYWxyZWFkeSByZWFkIHNvbWUgc2NhbGFyIGNvbnRlbnQuXG4gICAgICAgICAgc3RhdGUucmVzdWx0ICs9ICcgJztcbiAgICAgICAgfVxuXG4gICAgICAvLyBTZXZlcmFsIGxpbmUgYnJlYWtzIC0gcGVyY2VpdmUgYXMgZGlmZmVyZW50IGxpbmVzLlxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RhdGUucmVzdWx0ICs9IGNvbW1vbi5yZXBlYXQoJ1xcbicsIGVtcHR5TGluZXMpO1xuICAgICAgfVxuXG4gICAgLy8gTGl0ZXJhbCBzdHlsZToganVzdCBhZGQgZXhhY3QgbnVtYmVyIG9mIGxpbmUgYnJlYWtzIGJldHdlZW4gY29udGVudCBsaW5lcy5cbiAgICB9IGVsc2UgaWYgKGRldGVjdGVkSW5kZW50KSB7XG4gICAgICAvLyBJZiBjdXJyZW50IGxpbmUgaXNuJ3QgdGhlIGZpcnN0IG9uZSAtIGNvdW50IGxpbmUgYnJlYWsgZnJvbSB0aGUgbGFzdCBjb250ZW50IGxpbmUuXG4gICAgICBzdGF0ZS5yZXN1bHQgKz0gY29tbW9uLnJlcGVhdCgnXFxuJywgZW1wdHlMaW5lcyArIDEpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBJbiBjYXNlIG9mIHRoZSBmaXJzdCBjb250ZW50IGxpbmUgLSBjb3VudCBvbmx5IGVtcHR5IGxpbmVzLlxuICAgIH1cblxuICAgIGRldGVjdGVkSW5kZW50ID0gdHJ1ZTtcbiAgICBlbXB0eUxpbmVzID0gMDtcbiAgICBjYXB0dXJlU3RhcnQgPSBzdGF0ZS5wb3NpdGlvbjtcblxuICAgIHdoaWxlICghaXNfRU9MKGNoKSAmJiAoMCAhPT0gY2gpKSB7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgfVxuXG4gICAgY2FwdHVyZVNlZ21lbnQoc3RhdGUsIGNhcHR1cmVTdGFydCwgc3RhdGUucG9zaXRpb24sIGZhbHNlKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiByZWFkQmxvY2tTZXF1ZW5jZShzdGF0ZSwgbm9kZUluZGVudCkge1xuICB2YXIgX2xpbmUsXG4gICAgICBfdGFnICAgICAgPSBzdGF0ZS50YWcsXG4gICAgICBfYW5jaG9yICAgPSBzdGF0ZS5hbmNob3IsXG4gICAgICBfcmVzdWx0ICAgPSBbXSxcbiAgICAgIGZvbGxvd2luZyxcbiAgICAgIGRldGVjdGVkICA9IGZhbHNlLFxuICAgICAgY2g7XG5cbiAgaWYgKG51bGwgIT09IHN0YXRlLmFuY2hvcikge1xuICAgIHN0YXRlLmFuY2hvck1hcFtzdGF0ZS5hbmNob3JdID0gX3Jlc3VsdDtcbiAgfVxuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgd2hpbGUgKDAgIT09IGNoKSB7XG5cbiAgICBpZiAoMHgyRC8qIC0gKi8gIT09IGNoKSB7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBmb2xsb3dpbmcgPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uICsgMSk7XG5cbiAgICBpZiAoIWlzX1dTX09SX0VPTChmb2xsb3dpbmcpKSB7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBkZXRlY3RlZCA9IHRydWU7XG4gICAgc3RhdGUucG9zaXRpb24rKztcblxuICAgIGlmIChza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCAtMSkpIHtcbiAgICAgIGlmIChzdGF0ZS5saW5lSW5kZW50IDw9IG5vZGVJbmRlbnQpIHtcbiAgICAgICAgX3Jlc3VsdC5wdXNoKG51bGwpO1xuICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBfbGluZSA9IHN0YXRlLmxpbmU7XG4gICAgY29tcG9zZU5vZGUoc3RhdGUsIG5vZGVJbmRlbnQsIENPTlRFWFRfQkxPQ0tfSU4sIGZhbHNlLCB0cnVlKTtcbiAgICBfcmVzdWx0LnB1c2goc3RhdGUucmVzdWx0KTtcbiAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCAtMSk7XG5cbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gICAgaWYgKChzdGF0ZS5saW5lID09PSBfbGluZSB8fCBzdGF0ZS5saW5lSW5kZW50ID4gbm9kZUluZGVudCkgJiYgKDAgIT09IGNoKSkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2JhZCBpbmRlbnRhdGlvbiBvZiBhIHNlcXVlbmNlIGVudHJ5Jyk7XG4gICAgfSBlbHNlIGlmIChzdGF0ZS5saW5lSW5kZW50IDwgbm9kZUluZGVudCkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgaWYgKGRldGVjdGVkKSB7XG4gICAgc3RhdGUudGFnID0gX3RhZztcbiAgICBzdGF0ZS5hbmNob3IgPSBfYW5jaG9yO1xuICAgIHN0YXRlLmtpbmQgPSAnc2VxdWVuY2UnO1xuICAgIHN0YXRlLnJlc3VsdCA9IF9yZXN1bHQ7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiByZWFkQmxvY2tNYXBwaW5nKHN0YXRlLCBub2RlSW5kZW50LCBmbG93SW5kZW50KSB7XG4gIHZhciBmb2xsb3dpbmcsXG4gICAgICBhbGxvd0NvbXBhY3QsXG4gICAgICBfbGluZSxcbiAgICAgIF90YWcgICAgICAgICAgPSBzdGF0ZS50YWcsXG4gICAgICBfYW5jaG9yICAgICAgID0gc3RhdGUuYW5jaG9yLFxuICAgICAgX3Jlc3VsdCAgICAgICA9IHt9LFxuICAgICAga2V5VGFnICAgICAgICA9IG51bGwsXG4gICAgICBrZXlOb2RlICAgICAgID0gbnVsbCxcbiAgICAgIHZhbHVlTm9kZSAgICAgPSBudWxsLFxuICAgICAgYXRFeHBsaWNpdEtleSA9IGZhbHNlLFxuICAgICAgZGV0ZWN0ZWQgICAgICA9IGZhbHNlLFxuICAgICAgY2g7XG5cbiAgaWYgKG51bGwgIT09IHN0YXRlLmFuY2hvcikge1xuICAgIHN0YXRlLmFuY2hvck1hcFtzdGF0ZS5hbmNob3JdID0gX3Jlc3VsdDtcbiAgfVxuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgd2hpbGUgKDAgIT09IGNoKSB7XG4gICAgZm9sbG93aW5nID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbiArIDEpO1xuICAgIF9saW5lID0gc3RhdGUubGluZTsgLy8gU2F2ZSB0aGUgY3VycmVudCBsaW5lLlxuXG4gICAgLy9cbiAgICAvLyBFeHBsaWNpdCBub3RhdGlvbiBjYXNlLiBUaGVyZSBhcmUgdHdvIHNlcGFyYXRlIGJsb2NrczpcbiAgICAvLyBmaXJzdCBmb3IgdGhlIGtleSAoZGVub3RlZCBieSBcIj9cIikgYW5kIHNlY29uZCBmb3IgdGhlIHZhbHVlIChkZW5vdGVkIGJ5IFwiOlwiKVxuICAgIC8vXG4gICAgaWYgKCgweDNGLyogPyAqLyA9PT0gY2ggfHwgMHgzQS8qIDogKi8gID09PSBjaCkgJiYgaXNfV1NfT1JfRU9MKGZvbGxvd2luZykpIHtcblxuICAgICAgaWYgKDB4M0YvKiA/ICovID09PSBjaCkge1xuICAgICAgICBpZiAoYXRFeHBsaWNpdEtleSkge1xuICAgICAgICAgIHN0b3JlTWFwcGluZ1BhaXIoc3RhdGUsIF9yZXN1bHQsIGtleVRhZywga2V5Tm9kZSwgbnVsbCk7XG4gICAgICAgICAga2V5VGFnID0ga2V5Tm9kZSA9IHZhbHVlTm9kZSA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBkZXRlY3RlZCA9IHRydWU7XG4gICAgICAgIGF0RXhwbGljaXRLZXkgPSB0cnVlO1xuICAgICAgICBhbGxvd0NvbXBhY3QgPSB0cnVlO1xuXG4gICAgICB9IGVsc2UgaWYgKGF0RXhwbGljaXRLZXkpIHtcbiAgICAgICAgLy8gaS5lLiAweDNBLyogOiAqLyA9PT0gY2hhcmFjdGVyIGFmdGVyIHRoZSBleHBsaWNpdCBrZXkuXG4gICAgICAgIGF0RXhwbGljaXRLZXkgPSBmYWxzZTtcbiAgICAgICAgYWxsb3dDb21wYWN0ID0gdHJ1ZTtcblxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2luY29tcGxldGUgZXhwbGljaXQgbWFwcGluZyBwYWlyOyBhIGtleSBub2RlIGlzIG1pc3NlZCcpO1xuICAgICAgfVxuXG4gICAgICBzdGF0ZS5wb3NpdGlvbiArPSAxO1xuICAgICAgY2ggPSBmb2xsb3dpbmc7XG5cbiAgICAvL1xuICAgIC8vIEltcGxpY2l0IG5vdGF0aW9uIGNhc2UuIEZsb3ctc3R5bGUgbm9kZSBhcyB0aGUga2V5IGZpcnN0LCB0aGVuIFwiOlwiLCBhbmQgdGhlIHZhbHVlLlxuICAgIC8vXG4gICAgfSBlbHNlIGlmIChjb21wb3NlTm9kZShzdGF0ZSwgZmxvd0luZGVudCwgQ09OVEVYVF9GTE9XX09VVCwgZmFsc2UsIHRydWUpKSB7XG5cbiAgICAgIGlmIChzdGF0ZS5saW5lID09PSBfbGluZSkge1xuICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gICAgICAgIHdoaWxlIChpc19XSElURV9TUEFDRShjaCkpIHtcbiAgICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoMHgzQS8qIDogKi8gPT09IGNoKSB7XG4gICAgICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuXG4gICAgICAgICAgaWYgKCFpc19XU19PUl9FT0woY2gpKSB7XG4gICAgICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnYSB3aGl0ZXNwYWNlIGNoYXJhY3RlciBpcyBleHBlY3RlZCBhZnRlciB0aGUga2V5LXZhbHVlIHNlcGFyYXRvciB3aXRoaW4gYSBibG9jayBtYXBwaW5nJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGF0RXhwbGljaXRLZXkpIHtcbiAgICAgICAgICAgIHN0b3JlTWFwcGluZ1BhaXIoc3RhdGUsIF9yZXN1bHQsIGtleVRhZywga2V5Tm9kZSwgbnVsbCk7XG4gICAgICAgICAgICBrZXlUYWcgPSBrZXlOb2RlID0gdmFsdWVOb2RlID0gbnVsbDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBkZXRlY3RlZCA9IHRydWU7XG4gICAgICAgICAgYXRFeHBsaWNpdEtleSA9IGZhbHNlO1xuICAgICAgICAgIGFsbG93Q29tcGFjdCA9IGZhbHNlO1xuICAgICAgICAgIGtleVRhZyA9IHN0YXRlLnRhZztcbiAgICAgICAgICBrZXlOb2RlID0gc3RhdGUucmVzdWx0O1xuXG4gICAgICAgIH0gZWxzZSBpZiAoZGV0ZWN0ZWQpIHtcbiAgICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnY2FuIG5vdCByZWFkIGFuIGltcGxpY2l0IG1hcHBpbmcgcGFpcjsgYSBjb2xvbiBpcyBtaXNzZWQnKTtcblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN0YXRlLnRhZyA9IF90YWc7XG4gICAgICAgICAgc3RhdGUuYW5jaG9yID0gX2FuY2hvcjtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTsgLy8gS2VlcCB0aGUgcmVzdWx0IG9mIGBjb21wb3NlTm9kZWAuXG4gICAgICAgIH1cblxuICAgICAgfSBlbHNlIGlmIChkZXRlY3RlZCkge1xuICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnY2FuIG5vdCByZWFkIGEgYmxvY2sgbWFwcGluZyBlbnRyeTsgYSBtdWx0aWxpbmUga2V5IG1heSBub3QgYmUgYW4gaW1wbGljaXQga2V5Jyk7XG5cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXRlLnRhZyA9IF90YWc7XG4gICAgICAgIHN0YXRlLmFuY2hvciA9IF9hbmNob3I7XG4gICAgICAgIHJldHVybiB0cnVlOyAvLyBLZWVwIHRoZSByZXN1bHQgb2YgYGNvbXBvc2VOb2RlYC5cbiAgICAgIH1cblxuICAgIH0gZWxzZSB7XG4gICAgICBicmVhazsgLy8gUmVhZGluZyBpcyBkb25lLiBHbyB0byB0aGUgZXBpbG9ndWUuXG4gICAgfVxuXG4gICAgLy9cbiAgICAvLyBDb21tb24gcmVhZGluZyBjb2RlIGZvciBib3RoIGV4cGxpY2l0IGFuZCBpbXBsaWNpdCBub3RhdGlvbnMuXG4gICAgLy9cbiAgICBpZiAoc3RhdGUubGluZSA9PT0gX2xpbmUgfHwgc3RhdGUubGluZUluZGVudCA+IG5vZGVJbmRlbnQpIHtcbiAgICAgIGlmIChjb21wb3NlTm9kZShzdGF0ZSwgbm9kZUluZGVudCwgQ09OVEVYVF9CTE9DS19PVVQsIHRydWUsIGFsbG93Q29tcGFjdCkpIHtcbiAgICAgICAgaWYgKGF0RXhwbGljaXRLZXkpIHtcbiAgICAgICAgICBrZXlOb2RlID0gc3RhdGUucmVzdWx0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhbHVlTm9kZSA9IHN0YXRlLnJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoIWF0RXhwbGljaXRLZXkpIHtcbiAgICAgICAgc3RvcmVNYXBwaW5nUGFpcihzdGF0ZSwgX3Jlc3VsdCwga2V5VGFnLCBrZXlOb2RlLCB2YWx1ZU5vZGUpO1xuICAgICAgICBrZXlUYWcgPSBrZXlOb2RlID0gdmFsdWVOb2RlID0gbnVsbDtcbiAgICAgIH1cblxuICAgICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpO1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcbiAgICB9XG5cbiAgICBpZiAoc3RhdGUubGluZUluZGVudCA+IG5vZGVJbmRlbnQgJiYgKDAgIT09IGNoKSkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2JhZCBpbmRlbnRhdGlvbiBvZiBhIG1hcHBpbmcgZW50cnknKTtcbiAgICB9IGVsc2UgaWYgKHN0YXRlLmxpbmVJbmRlbnQgPCBub2RlSW5kZW50KSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICAvL1xuICAvLyBFcGlsb2d1ZS5cbiAgLy9cblxuICAvLyBTcGVjaWFsIGNhc2U6IGxhc3QgbWFwcGluZydzIG5vZGUgY29udGFpbnMgb25seSB0aGUga2V5IGluIGV4cGxpY2l0IG5vdGF0aW9uLlxuICBpZiAoYXRFeHBsaWNpdEtleSkge1xuICAgIHN0b3JlTWFwcGluZ1BhaXIoc3RhdGUsIF9yZXN1bHQsIGtleVRhZywga2V5Tm9kZSwgbnVsbCk7XG4gIH1cblxuICAvLyBFeHBvc2UgdGhlIHJlc3VsdGluZyBtYXBwaW5nLlxuICBpZiAoZGV0ZWN0ZWQpIHtcbiAgICBzdGF0ZS50YWcgPSBfdGFnO1xuICAgIHN0YXRlLmFuY2hvciA9IF9hbmNob3I7XG4gICAgc3RhdGUua2luZCA9ICdtYXBwaW5nJztcbiAgICBzdGF0ZS5yZXN1bHQgPSBfcmVzdWx0O1xuICB9XG5cbiAgcmV0dXJuIGRldGVjdGVkO1xufVxuXG5mdW5jdGlvbiByZWFkVGFnUHJvcGVydHkoc3RhdGUpIHtcbiAgdmFyIF9wb3NpdGlvbixcbiAgICAgIGlzVmVyYmF0aW0gPSBmYWxzZSxcbiAgICAgIGlzTmFtZWQgICAgPSBmYWxzZSxcbiAgICAgIHRhZ0hhbmRsZSxcbiAgICAgIHRhZ05hbWUsXG4gICAgICBjaDtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmICgweDIxLyogISAqLyAhPT0gY2gpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAobnVsbCAhPT0gc3RhdGUudGFnKSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2R1cGxpY2F0aW9uIG9mIGEgdGFnIHByb3BlcnR5Jyk7XG4gIH1cblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgaWYgKDB4M0MvKiA8ICovID09PSBjaCkge1xuICAgIGlzVmVyYmF0aW0gPSB0cnVlO1xuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcblxuICB9IGVsc2UgaWYgKDB4MjEvKiAhICovID09PSBjaCkge1xuICAgIGlzTmFtZWQgPSB0cnVlO1xuICAgIHRhZ0hhbmRsZSA9ICchISc7XG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuXG4gIH0gZWxzZSB7XG4gICAgdGFnSGFuZGxlID0gJyEnO1xuICB9XG5cbiAgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb247XG5cbiAgaWYgKGlzVmVyYmF0aW0pIHtcbiAgICBkbyB7IGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTsgfVxuICAgIHdoaWxlICgwICE9PSBjaCAmJiAweDNFLyogPiAqLyAhPT0gY2gpO1xuXG4gICAgaWYgKHN0YXRlLnBvc2l0aW9uIDwgc3RhdGUubGVuZ3RoKSB7XG4gICAgICB0YWdOYW1lID0gc3RhdGUuaW5wdXQuc2xpY2UoX3Bvc2l0aW9uLCBzdGF0ZS5wb3NpdGlvbik7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd1bmV4cGVjdGVkIGVuZCBvZiB0aGUgc3RyZWFtIHdpdGhpbiBhIHZlcmJhdGltIHRhZycpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB3aGlsZSAoMCAhPT0gY2ggJiYgIWlzX1dTX09SX0VPTChjaCkpIHtcblxuICAgICAgaWYgKDB4MjEvKiAhICovID09PSBjaCkge1xuICAgICAgICBpZiAoIWlzTmFtZWQpIHtcbiAgICAgICAgICB0YWdIYW5kbGUgPSBzdGF0ZS5pbnB1dC5zbGljZShfcG9zaXRpb24gLSAxLCBzdGF0ZS5wb3NpdGlvbiArIDEpO1xuXG4gICAgICAgICAgaWYgKCFQQVRURVJOX1RBR19IQU5ETEUudGVzdCh0YWdIYW5kbGUpKSB7XG4gICAgICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnbmFtZWQgdGFnIGhhbmRsZSBjYW5ub3QgY29udGFpbiBzdWNoIGNoYXJhY3RlcnMnKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpc05hbWVkID0gdHJ1ZTtcbiAgICAgICAgICBfcG9zaXRpb24gPSBzdGF0ZS5wb3NpdGlvbiArIDE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3RhZyBzdWZmaXggY2Fubm90IGNvbnRhaW4gZXhjbGFtYXRpb24gbWFya3MnKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgfVxuXG4gICAgdGFnTmFtZSA9IHN0YXRlLmlucHV0LnNsaWNlKF9wb3NpdGlvbiwgc3RhdGUucG9zaXRpb24pO1xuXG4gICAgaWYgKFBBVFRFUk5fRkxPV19JTkRJQ0FUT1JTLnRlc3QodGFnTmFtZSkpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd0YWcgc3VmZml4IGNhbm5vdCBjb250YWluIGZsb3cgaW5kaWNhdG9yIGNoYXJhY3RlcnMnKTtcbiAgICB9XG4gIH1cblxuICBpZiAodGFnTmFtZSAmJiAhUEFUVEVSTl9UQUdfVVJJLnRlc3QodGFnTmFtZSkpIHtcbiAgICB0aHJvd0Vycm9yKHN0YXRlLCAndGFnIG5hbWUgY2Fubm90IGNvbnRhaW4gc3VjaCBjaGFyYWN0ZXJzOiAnICsgdGFnTmFtZSk7XG4gIH1cblxuICBpZiAoaXNWZXJiYXRpbSkge1xuICAgIHN0YXRlLnRhZyA9IHRhZ05hbWU7XG5cbiAgfSBlbHNlIGlmIChfaGFzT3duUHJvcGVydHkuY2FsbChzdGF0ZS50YWdNYXAsIHRhZ0hhbmRsZSkpIHtcbiAgICBzdGF0ZS50YWcgPSBzdGF0ZS50YWdNYXBbdGFnSGFuZGxlXSArIHRhZ05hbWU7XG5cbiAgfSBlbHNlIGlmICgnIScgPT09IHRhZ0hhbmRsZSkge1xuICAgIHN0YXRlLnRhZyA9ICchJyArIHRhZ05hbWU7XG5cbiAgfSBlbHNlIGlmICgnISEnID09PSB0YWdIYW5kbGUpIHtcbiAgICBzdGF0ZS50YWcgPSAndGFnOnlhbWwub3JnLDIwMDI6JyArIHRhZ05hbWU7XG5cbiAgfSBlbHNlIHtcbiAgICB0aHJvd0Vycm9yKHN0YXRlLCAndW5kZWNsYXJlZCB0YWcgaGFuZGxlIFwiJyArIHRhZ0hhbmRsZSArICdcIicpO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIHJlYWRBbmNob3JQcm9wZXJ0eShzdGF0ZSkge1xuICB2YXIgX3Bvc2l0aW9uLFxuICAgICAgY2g7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoMHgyNi8qICYgKi8gIT09IGNoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKG51bGwgIT09IHN0YXRlLmFuY2hvcikge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICdkdXBsaWNhdGlvbiBvZiBhbiBhbmNob3IgcHJvcGVydHknKTtcbiAgfVxuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb247XG5cbiAgd2hpbGUgKDAgIT09IGNoICYmICFpc19XU19PUl9FT0woY2gpICYmICFpc19GTE9XX0lORElDQVRPUihjaCkpIHtcbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gIH1cblxuICBpZiAoc3RhdGUucG9zaXRpb24gPT09IF9wb3NpdGlvbikge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICduYW1lIG9mIGFuIGFuY2hvciBub2RlIG11c3QgY29udGFpbiBhdCBsZWFzdCBvbmUgY2hhcmFjdGVyJyk7XG4gIH1cblxuICBzdGF0ZS5hbmNob3IgPSBzdGF0ZS5pbnB1dC5zbGljZShfcG9zaXRpb24sIHN0YXRlLnBvc2l0aW9uKTtcbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIHJlYWRBbGlhcyhzdGF0ZSkge1xuICB2YXIgX3Bvc2l0aW9uLCBhbGlhcyxcbiAgICAgIGxlbiA9IHN0YXRlLmxlbmd0aCxcbiAgICAgIGlucHV0ID0gc3RhdGUuaW5wdXQsXG4gICAgICBjaDtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmICgweDJBLyogKiAqLyAhPT0gY2gpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gIF9wb3NpdGlvbiA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gIHdoaWxlICgwICE9PSBjaCAmJiAhaXNfV1NfT1JfRU9MKGNoKSAmJiAhaXNfRkxPV19JTkRJQ0FUT1IoY2gpKSB7XG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICB9XG5cbiAgaWYgKHN0YXRlLnBvc2l0aW9uID09PSBfcG9zaXRpb24pIHtcbiAgICB0aHJvd0Vycm9yKHN0YXRlLCAnbmFtZSBvZiBhbiBhbGlhcyBub2RlIG11c3QgY29udGFpbiBhdCBsZWFzdCBvbmUgY2hhcmFjdGVyJyk7XG4gIH1cblxuICBhbGlhcyA9IHN0YXRlLmlucHV0LnNsaWNlKF9wb3NpdGlvbiwgc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmICghc3RhdGUuYW5jaG9yTWFwLmhhc093blByb3BlcnR5KGFsaWFzKSkge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICd1bmlkZW50aWZpZWQgYWxpYXMgXCInICsgYWxpYXMgKyAnXCInKTtcbiAgfVxuXG4gIHN0YXRlLnJlc3VsdCA9IHN0YXRlLmFuY2hvck1hcFthbGlhc107XG4gIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTtcbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGNvbXBvc2VOb2RlKHN0YXRlLCBwYXJlbnRJbmRlbnQsIG5vZGVDb250ZXh0LCBhbGxvd1RvU2VlaywgYWxsb3dDb21wYWN0KSB7XG4gIHZhciBhbGxvd0Jsb2NrU3R5bGVzLFxuICAgICAgYWxsb3dCbG9ja1NjYWxhcnMsXG4gICAgICBhbGxvd0Jsb2NrQ29sbGVjdGlvbnMsXG4gICAgICBpbmRlbnRTdGF0dXMgPSAxLCAvLyAxOiB0aGlzPnBhcmVudCwgMDogdGhpcz1wYXJlbnQsIC0xOiB0aGlzPHBhcmVudFxuICAgICAgYXROZXdMaW5lICA9IGZhbHNlLFxuICAgICAgaGFzQ29udGVudCA9IGZhbHNlLFxuICAgICAgdHlwZUluZGV4LFxuICAgICAgdHlwZVF1YW50aXR5LFxuICAgICAgdHlwZSxcbiAgICAgIGZsb3dJbmRlbnQsXG4gICAgICBibG9ja0luZGVudCxcbiAgICAgIF9yZXN1bHQ7XG5cbiAgc3RhdGUudGFnICAgID0gbnVsbDtcbiAgc3RhdGUuYW5jaG9yID0gbnVsbDtcbiAgc3RhdGUua2luZCAgID0gbnVsbDtcbiAgc3RhdGUucmVzdWx0ID0gbnVsbDtcblxuICBhbGxvd0Jsb2NrU3R5bGVzID0gYWxsb3dCbG9ja1NjYWxhcnMgPSBhbGxvd0Jsb2NrQ29sbGVjdGlvbnMgPVxuICAgIENPTlRFWFRfQkxPQ0tfT1VUID09PSBub2RlQ29udGV4dCB8fFxuICAgIENPTlRFWFRfQkxPQ0tfSU4gID09PSBub2RlQ29udGV4dDtcblxuICBpZiAoYWxsb3dUb1NlZWspIHtcbiAgICBpZiAoc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpKSB7XG4gICAgICBhdE5ld0xpbmUgPSB0cnVlO1xuXG4gICAgICBpZiAoc3RhdGUubGluZUluZGVudCA+IHBhcmVudEluZGVudCkge1xuICAgICAgICBpbmRlbnRTdGF0dXMgPSAxO1xuICAgICAgfSBlbHNlIGlmIChzdGF0ZS5saW5lSW5kZW50ID09PSBwYXJlbnRJbmRlbnQpIHtcbiAgICAgICAgaW5kZW50U3RhdHVzID0gMDtcbiAgICAgIH0gZWxzZSBpZiAoc3RhdGUubGluZUluZGVudCA8IHBhcmVudEluZGVudCkge1xuICAgICAgICBpbmRlbnRTdGF0dXMgPSAtMTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAoMSA9PT0gaW5kZW50U3RhdHVzKSB7XG4gICAgd2hpbGUgKHJlYWRUYWdQcm9wZXJ0eShzdGF0ZSkgfHwgcmVhZEFuY2hvclByb3BlcnR5KHN0YXRlKSkge1xuICAgICAgaWYgKHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKSkge1xuICAgICAgICBhdE5ld0xpbmUgPSB0cnVlO1xuICAgICAgICBhbGxvd0Jsb2NrQ29sbGVjdGlvbnMgPSBhbGxvd0Jsb2NrU3R5bGVzO1xuXG4gICAgICAgIGlmIChzdGF0ZS5saW5lSW5kZW50ID4gcGFyZW50SW5kZW50KSB7XG4gICAgICAgICAgaW5kZW50U3RhdHVzID0gMTtcbiAgICAgICAgfSBlbHNlIGlmIChzdGF0ZS5saW5lSW5kZW50ID09PSBwYXJlbnRJbmRlbnQpIHtcbiAgICAgICAgICBpbmRlbnRTdGF0dXMgPSAwO1xuICAgICAgICB9IGVsc2UgaWYgKHN0YXRlLmxpbmVJbmRlbnQgPCBwYXJlbnRJbmRlbnQpIHtcbiAgICAgICAgICBpbmRlbnRTdGF0dXMgPSAtMTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYWxsb3dCbG9ja0NvbGxlY3Rpb25zID0gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKGFsbG93QmxvY2tDb2xsZWN0aW9ucykge1xuICAgIGFsbG93QmxvY2tDb2xsZWN0aW9ucyA9IGF0TmV3TGluZSB8fCBhbGxvd0NvbXBhY3Q7XG4gIH1cblxuICBpZiAoMSA9PT0gaW5kZW50U3RhdHVzIHx8IENPTlRFWFRfQkxPQ0tfT1VUID09PSBub2RlQ29udGV4dCkge1xuICAgIGlmIChDT05URVhUX0ZMT1dfSU4gPT09IG5vZGVDb250ZXh0IHx8IENPTlRFWFRfRkxPV19PVVQgPT09IG5vZGVDb250ZXh0KSB7XG4gICAgICBmbG93SW5kZW50ID0gcGFyZW50SW5kZW50O1xuICAgIH0gZWxzZSB7XG4gICAgICBmbG93SW5kZW50ID0gcGFyZW50SW5kZW50ICsgMTtcbiAgICB9XG5cbiAgICBibG9ja0luZGVudCA9IHN0YXRlLnBvc2l0aW9uIC0gc3RhdGUubGluZVN0YXJ0O1xuXG4gICAgaWYgKDEgPT09IGluZGVudFN0YXR1cykge1xuICAgICAgaWYgKGFsbG93QmxvY2tDb2xsZWN0aW9ucyAmJlxuICAgICAgICAgIChyZWFkQmxvY2tTZXF1ZW5jZShzdGF0ZSwgYmxvY2tJbmRlbnQpIHx8XG4gICAgICAgICAgIHJlYWRCbG9ja01hcHBpbmcoc3RhdGUsIGJsb2NrSW5kZW50LCBmbG93SW5kZW50KSkgfHxcbiAgICAgICAgICByZWFkRmxvd0NvbGxlY3Rpb24oc3RhdGUsIGZsb3dJbmRlbnQpKSB7XG4gICAgICAgIGhhc0NvbnRlbnQgPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKChhbGxvd0Jsb2NrU2NhbGFycyAmJiByZWFkQmxvY2tTY2FsYXIoc3RhdGUsIGZsb3dJbmRlbnQpKSB8fFxuICAgICAgICAgICAgcmVhZFNpbmdsZVF1b3RlZFNjYWxhcihzdGF0ZSwgZmxvd0luZGVudCkgfHxcbiAgICAgICAgICAgIHJlYWREb3VibGVRdW90ZWRTY2FsYXIoc3RhdGUsIGZsb3dJbmRlbnQpKSB7XG4gICAgICAgICAgaGFzQ29udGVudCA9IHRydWU7XG5cbiAgICAgICAgfSBlbHNlIGlmIChyZWFkQWxpYXMoc3RhdGUpKSB7XG4gICAgICAgICAgaGFzQ29udGVudCA9IHRydWU7XG5cbiAgICAgICAgICBpZiAobnVsbCAhPT0gc3RhdGUudGFnIHx8IG51bGwgIT09IHN0YXRlLmFuY2hvcikge1xuICAgICAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2FsaWFzIG5vZGUgc2hvdWxkIG5vdCBoYXZlIGFueSBwcm9wZXJ0aWVzJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgIH0gZWxzZSBpZiAocmVhZFBsYWluU2NhbGFyKHN0YXRlLCBmbG93SW5kZW50LCBDT05URVhUX0ZMT1dfSU4gPT09IG5vZGVDb250ZXh0KSkge1xuICAgICAgICAgIGhhc0NvbnRlbnQgPSB0cnVlO1xuXG4gICAgICAgICAgaWYgKG51bGwgPT09IHN0YXRlLnRhZykge1xuICAgICAgICAgICAgc3RhdGUudGFnID0gJz8nO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChudWxsICE9PSBzdGF0ZS5hbmNob3IpIHtcbiAgICAgICAgICBzdGF0ZS5hbmNob3JNYXBbc3RhdGUuYW5jaG9yXSA9IHN0YXRlLnJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoMCA9PT0gaW5kZW50U3RhdHVzKSB7XG4gICAgICAvLyBTcGVjaWFsIGNhc2U6IGJsb2NrIHNlcXVlbmNlcyBhcmUgYWxsb3dlZCB0byBoYXZlIHNhbWUgaW5kZW50YXRpb24gbGV2ZWwgYXMgdGhlIHBhcmVudC5cbiAgICAgIC8vIGh0dHA6Ly93d3cueWFtbC5vcmcvc3BlYy8xLjIvc3BlYy5odG1sI2lkMjc5OTc4NFxuICAgICAgaGFzQ29udGVudCA9IGFsbG93QmxvY2tDb2xsZWN0aW9ucyAmJiByZWFkQmxvY2tTZXF1ZW5jZShzdGF0ZSwgYmxvY2tJbmRlbnQpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChudWxsICE9PSBzdGF0ZS50YWcgJiYgJyEnICE9PSBzdGF0ZS50YWcpIHtcbiAgICBpZiAoJz8nID09PSBzdGF0ZS50YWcpIHtcbiAgICAgIGZvciAodHlwZUluZGV4ID0gMCwgdHlwZVF1YW50aXR5ID0gc3RhdGUuaW1wbGljaXRUeXBlcy5sZW5ndGg7XG4gICAgICAgICAgIHR5cGVJbmRleCA8IHR5cGVRdWFudGl0eTtcbiAgICAgICAgICAgdHlwZUluZGV4ICs9IDEpIHtcbiAgICAgICAgdHlwZSA9IHN0YXRlLmltcGxpY2l0VHlwZXNbdHlwZUluZGV4XTtcblxuICAgICAgICAvLyBJbXBsaWNpdCByZXNvbHZpbmcgaXMgbm90IGFsbG93ZWQgZm9yIG5vbi1zY2FsYXIgdHlwZXMsIGFuZCAnPydcbiAgICAgICAgLy8gbm9uLXNwZWNpZmljIHRhZyBpcyBvbmx5IGFzc2lnbmVkIHRvIHBsYWluIHNjYWxhcnMuIFNvLCBpdCBpc24ndFxuICAgICAgICAvLyBuZWVkZWQgdG8gY2hlY2sgZm9yICdraW5kJyBjb25mb3JtaXR5LlxuXG4gICAgICAgIGlmICh0eXBlLnJlc29sdmUoc3RhdGUucmVzdWx0KSkgeyAvLyBgc3RhdGUucmVzdWx0YCB1cGRhdGVkIGluIHJlc29sdmVyIGlmIG1hdGNoZWRcbiAgICAgICAgICBzdGF0ZS5yZXN1bHQgPSB0eXBlLmNvbnN0cnVjdChzdGF0ZS5yZXN1bHQpO1xuICAgICAgICAgIHN0YXRlLnRhZyA9IHR5cGUudGFnO1xuICAgICAgICAgIGlmIChudWxsICE9PSBzdGF0ZS5hbmNob3IpIHtcbiAgICAgICAgICAgIHN0YXRlLmFuY2hvck1hcFtzdGF0ZS5hbmNob3JdID0gc3RhdGUucmVzdWx0O1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoX2hhc093blByb3BlcnR5LmNhbGwoc3RhdGUudHlwZU1hcCwgc3RhdGUudGFnKSkge1xuICAgICAgdHlwZSA9IHN0YXRlLnR5cGVNYXBbc3RhdGUudGFnXTtcblxuICAgICAgaWYgKG51bGwgIT09IHN0YXRlLnJlc3VsdCAmJiB0eXBlLmtpbmQgIT09IHN0YXRlLmtpbmQpIHtcbiAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3VuYWNjZXB0YWJsZSBub2RlIGtpbmQgZm9yICE8JyArIHN0YXRlLnRhZyArICc+IHRhZzsgaXQgc2hvdWxkIGJlIFwiJyArIHR5cGUua2luZCArICdcIiwgbm90IFwiJyArIHN0YXRlLmtpbmQgKyAnXCInKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCF0eXBlLnJlc29sdmUoc3RhdGUucmVzdWx0KSkgeyAvLyBgc3RhdGUucmVzdWx0YCB1cGRhdGVkIGluIHJlc29sdmVyIGlmIG1hdGNoZWRcbiAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2Nhbm5vdCByZXNvbHZlIGEgbm9kZSB3aXRoICE8JyArIHN0YXRlLnRhZyArICc+IGV4cGxpY2l0IHRhZycpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RhdGUucmVzdWx0ID0gdHlwZS5jb25zdHJ1Y3Qoc3RhdGUucmVzdWx0KTtcbiAgICAgICAgaWYgKG51bGwgIT09IHN0YXRlLmFuY2hvcikge1xuICAgICAgICAgIHN0YXRlLmFuY2hvck1hcFtzdGF0ZS5hbmNob3JdID0gc3RhdGUucmVzdWx0O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93V2FybmluZyhzdGF0ZSwgJ3Vua25vd24gdGFnICE8JyArIHN0YXRlLnRhZyArICc+Jyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGwgIT09IHN0YXRlLnRhZyB8fCBudWxsICE9PSBzdGF0ZS5hbmNob3IgfHwgaGFzQ29udGVudDtcbn1cblxuZnVuY3Rpb24gcmVhZERvY3VtZW50KHN0YXRlKSB7XG4gIHZhciBkb2N1bWVudFN0YXJ0ID0gc3RhdGUucG9zaXRpb24sXG4gICAgICBfcG9zaXRpb24sXG4gICAgICBkaXJlY3RpdmVOYW1lLFxuICAgICAgZGlyZWN0aXZlQXJncyxcbiAgICAgIGhhc0RpcmVjdGl2ZXMgPSBmYWxzZSxcbiAgICAgIGNoO1xuXG4gIHN0YXRlLnZlcnNpb24gPSBudWxsO1xuICBzdGF0ZS5jaGVja0xpbmVCcmVha3MgPSBzdGF0ZS5sZWdhY3k7XG4gIHN0YXRlLnRhZ01hcCA9IHt9O1xuICBzdGF0ZS5hbmNob3JNYXAgPSB7fTtcblxuICB3aGlsZSAoMCAhPT0gKGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbikpKSB7XG4gICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpO1xuXG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICAgIGlmIChzdGF0ZS5saW5lSW5kZW50ID4gMCB8fCAweDI1LyogJSAqLyAhPT0gY2gpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIGhhc0RpcmVjdGl2ZXMgPSB0cnVlO1xuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgICBfcG9zaXRpb24gPSBzdGF0ZS5wb3NpdGlvbjtcblxuICAgIHdoaWxlICgwICE9PSBjaCAmJiAhaXNfV1NfT1JfRU9MKGNoKSkge1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgIH1cblxuICAgIGRpcmVjdGl2ZU5hbWUgPSBzdGF0ZS5pbnB1dC5zbGljZShfcG9zaXRpb24sIHN0YXRlLnBvc2l0aW9uKTtcbiAgICBkaXJlY3RpdmVBcmdzID0gW107XG5cbiAgICBpZiAoZGlyZWN0aXZlTmFtZS5sZW5ndGggPCAxKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZGlyZWN0aXZlIG5hbWUgbXVzdCBub3QgYmUgbGVzcyB0aGFuIG9uZSBjaGFyYWN0ZXIgaW4gbGVuZ3RoJyk7XG4gICAgfVxuXG4gICAgd2hpbGUgKDAgIT09IGNoKSB7XG4gICAgICB3aGlsZSAoaXNfV0hJVEVfU1BBQ0UoY2gpKSB7XG4gICAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgICAgIH1cblxuICAgICAgaWYgKDB4MjMvKiAjICovID09PSBjaCkge1xuICAgICAgICBkbyB7IGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTsgfVxuICAgICAgICB3aGlsZSAoMCAhPT0gY2ggJiYgIWlzX0VPTChjaCkpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgaWYgKGlzX0VPTChjaCkpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIF9wb3NpdGlvbiA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gICAgICB3aGlsZSAoMCAhPT0gY2ggJiYgIWlzX1dTX09SX0VPTChjaCkpIHtcbiAgICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgICAgfVxuXG4gICAgICBkaXJlY3RpdmVBcmdzLnB1c2goc3RhdGUuaW5wdXQuc2xpY2UoX3Bvc2l0aW9uLCBzdGF0ZS5wb3NpdGlvbikpO1xuICAgIH1cblxuICAgIGlmICgwICE9PSBjaCkge1xuICAgICAgcmVhZExpbmVCcmVhayhzdGF0ZSk7XG4gICAgfVxuXG4gICAgaWYgKF9oYXNPd25Qcm9wZXJ0eS5jYWxsKGRpcmVjdGl2ZUhhbmRsZXJzLCBkaXJlY3RpdmVOYW1lKSkge1xuICAgICAgZGlyZWN0aXZlSGFuZGxlcnNbZGlyZWN0aXZlTmFtZV0oc3RhdGUsIGRpcmVjdGl2ZU5hbWUsIGRpcmVjdGl2ZUFyZ3MpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvd1dhcm5pbmcoc3RhdGUsICd1bmtub3duIGRvY3VtZW50IGRpcmVjdGl2ZSBcIicgKyBkaXJlY3RpdmVOYW1lICsgJ1wiJyk7XG4gICAgfVxuICB9XG5cbiAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpO1xuXG4gIGlmICgwID09PSBzdGF0ZS5saW5lSW5kZW50ICYmXG4gICAgICAweDJELyogLSAqLyA9PT0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbikgJiZcbiAgICAgIDB4MkQvKiAtICovID09PSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uICsgMSkgJiZcbiAgICAgIDB4MkQvKiAtICovID09PSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uICsgMikpIHtcbiAgICBzdGF0ZS5wb3NpdGlvbiArPSAzO1xuICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTtcblxuICB9IGVsc2UgaWYgKGhhc0RpcmVjdGl2ZXMpIHtcbiAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZGlyZWN0aXZlcyBlbmQgbWFyayBpcyBleHBlY3RlZCcpO1xuICB9XG5cbiAgY29tcG9zZU5vZGUoc3RhdGUsIHN0YXRlLmxpbmVJbmRlbnQgLSAxLCBDT05URVhUX0JMT0NLX09VVCwgZmFsc2UsIHRydWUpO1xuICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCAtMSk7XG5cbiAgaWYgKHN0YXRlLmNoZWNrTGluZUJyZWFrcyAmJlxuICAgICAgUEFUVEVSTl9OT05fQVNDSUlfTElORV9CUkVBS1MudGVzdChzdGF0ZS5pbnB1dC5zbGljZShkb2N1bWVudFN0YXJ0LCBzdGF0ZS5wb3NpdGlvbikpKSB7XG4gICAgdGhyb3dXYXJuaW5nKHN0YXRlLCAnbm9uLUFTQ0lJIGxpbmUgYnJlYWtzIGFyZSBpbnRlcnByZXRlZCBhcyBjb250ZW50Jyk7XG4gIH1cblxuICBzdGF0ZS5kb2N1bWVudHMucHVzaChzdGF0ZS5yZXN1bHQpO1xuXG4gIGlmIChzdGF0ZS5wb3NpdGlvbiA9PT0gc3RhdGUubGluZVN0YXJ0ICYmIHRlc3REb2N1bWVudFNlcGFyYXRvcihzdGF0ZSkpIHtcblxuICAgIGlmICgweDJFLyogLiAqLyA9PT0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbikpIHtcbiAgICAgIHN0YXRlLnBvc2l0aW9uICs9IDM7XG4gICAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCAtMSk7XG4gICAgfVxuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChzdGF0ZS5wb3NpdGlvbiA8IChzdGF0ZS5sZW5ndGggLSAxKSkge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICdlbmQgb2YgdGhlIHN0cmVhbSBvciBhIGRvY3VtZW50IHNlcGFyYXRvciBpcyBleHBlY3RlZCcpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybjtcbiAgfVxufVxuXG5cbmZ1bmN0aW9uIGxvYWREb2N1bWVudHMoaW5wdXQsIG9wdGlvbnMpIHtcbiAgaW5wdXQgPSBTdHJpbmcoaW5wdXQpO1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICBpZiAoaW5wdXQubGVuZ3RoICE9PSAwKSB7XG5cbiAgICAvLyBBZGQgdGFpbGluZyBgXFxuYCBpZiBub3QgZXhpc3RzXG4gICAgaWYgKDB4MEEvKiBMRiAqLyAhPT0gaW5wdXQuY2hhckNvZGVBdChpbnB1dC5sZW5ndGggLSAxKSAmJlxuICAgICAgICAweDBELyogQ1IgKi8gIT09IGlucHV0LmNoYXJDb2RlQXQoaW5wdXQubGVuZ3RoIC0gMSkpIHtcbiAgICAgIGlucHV0ICs9ICdcXG4nO1xuICAgIH1cblxuICAgIC8vIFN0cmlwIEJPTVxuICAgIGlmIChpbnB1dC5jaGFyQ29kZUF0KDApID09PSAweEZFRkYpIHtcbiAgICAgIGlucHV0ID0gaW5wdXQuc2xpY2UoMSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIHN0YXRlID0gbmV3IFN0YXRlKGlucHV0LCBvcHRpb25zKTtcblxuICBpZiAoUEFUVEVSTl9OT05fUFJJTlRBQkxFLnRlc3Qoc3RhdGUuaW5wdXQpKSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3RoZSBzdHJlYW0gY29udGFpbnMgbm9uLXByaW50YWJsZSBjaGFyYWN0ZXJzJyk7XG4gIH1cblxuICAvLyBVc2UgMCBhcyBzdHJpbmcgdGVybWluYXRvci4gVGhhdCBzaWduaWZpY2FudGx5IHNpbXBsaWZpZXMgYm91bmRzIGNoZWNrLlxuICBzdGF0ZS5pbnB1dCArPSAnXFwwJztcblxuICB3aGlsZSAoMHgyMC8qIFNwYWNlICovID09PSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKSkge1xuICAgIHN0YXRlLmxpbmVJbmRlbnQgKz0gMTtcbiAgICBzdGF0ZS5wb3NpdGlvbiArPSAxO1xuICB9XG5cbiAgd2hpbGUgKHN0YXRlLnBvc2l0aW9uIDwgKHN0YXRlLmxlbmd0aCAtIDEpKSB7XG4gICAgcmVhZERvY3VtZW50KHN0YXRlKTtcbiAgfVxuXG4gIHJldHVybiBzdGF0ZS5kb2N1bWVudHM7XG59XG5cblxuZnVuY3Rpb24gbG9hZEFsbChpbnB1dCwgaXRlcmF0b3IsIG9wdGlvbnMpIHtcbiAgdmFyIGRvY3VtZW50cyA9IGxvYWREb2N1bWVudHMoaW5wdXQsIG9wdGlvbnMpLCBpbmRleCwgbGVuZ3RoO1xuXG4gIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBkb2N1bWVudHMubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIGl0ZXJhdG9yKGRvY3VtZW50c1tpbmRleF0pO1xuICB9XG59XG5cblxuZnVuY3Rpb24gbG9hZChpbnB1dCwgb3B0aW9ucykge1xuICB2YXIgZG9jdW1lbnRzID0gbG9hZERvY3VtZW50cyhpbnB1dCwgb3B0aW9ucyksIGluZGV4LCBsZW5ndGg7XG5cbiAgaWYgKDAgPT09IGRvY3VtZW50cy5sZW5ndGgpIHtcbiAgICAvKmVzbGludC1kaXNhYmxlIG5vLXVuZGVmaW5lZCovXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfSBlbHNlIGlmICgxID09PSBkb2N1bWVudHMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGRvY3VtZW50c1swXTtcbiAgfVxuICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignZXhwZWN0ZWQgYSBzaW5nbGUgZG9jdW1lbnQgaW4gdGhlIHN0cmVhbSwgYnV0IGZvdW5kIG1vcmUnKTtcbn1cblxuXG5mdW5jdGlvbiBzYWZlTG9hZEFsbChpbnB1dCwgb3V0cHV0LCBvcHRpb25zKSB7XG4gIGxvYWRBbGwoaW5wdXQsIG91dHB1dCwgY29tbW9uLmV4dGVuZCh7IHNjaGVtYTogREVGQVVMVF9TQUZFX1NDSEVNQSB9LCBvcHRpb25zKSk7XG59XG5cblxuZnVuY3Rpb24gc2FmZUxvYWQoaW5wdXQsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIGxvYWQoaW5wdXQsIGNvbW1vbi5leHRlbmQoeyBzY2hlbWE6IERFRkFVTFRfU0FGRV9TQ0hFTUEgfSwgb3B0aW9ucykpO1xufVxuXG5cbm1vZHVsZS5leHBvcnRzLmxvYWRBbGwgICAgID0gbG9hZEFsbDtcbm1vZHVsZS5leHBvcnRzLmxvYWQgICAgICAgID0gbG9hZDtcbm1vZHVsZS5leHBvcnRzLnNhZmVMb2FkQWxsID0gc2FmZUxvYWRBbGw7XG5tb2R1bGUuZXhwb3J0cy5zYWZlTG9hZCAgICA9IHNhZmVMb2FkO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xuXG5cbmZ1bmN0aW9uIE1hcmsobmFtZSwgYnVmZmVyLCBwb3NpdGlvbiwgbGluZSwgY29sdW1uKSB7XG4gIHRoaXMubmFtZSAgICAgPSBuYW1lO1xuICB0aGlzLmJ1ZmZlciAgID0gYnVmZmVyO1xuICB0aGlzLnBvc2l0aW9uID0gcG9zaXRpb247XG4gIHRoaXMubGluZSAgICAgPSBsaW5lO1xuICB0aGlzLmNvbHVtbiAgID0gY29sdW1uO1xufVxuXG5cbk1hcmsucHJvdG90eXBlLmdldFNuaXBwZXQgPSBmdW5jdGlvbiBnZXRTbmlwcGV0KGluZGVudCwgbWF4TGVuZ3RoKSB7XG4gIHZhciBoZWFkLCBzdGFydCwgdGFpbCwgZW5kLCBzbmlwcGV0O1xuXG4gIGlmICghdGhpcy5idWZmZXIpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGluZGVudCA9IGluZGVudCB8fCA0O1xuICBtYXhMZW5ndGggPSBtYXhMZW5ndGggfHwgNzU7XG5cbiAgaGVhZCA9ICcnO1xuICBzdGFydCA9IHRoaXMucG9zaXRpb247XG5cbiAgd2hpbGUgKHN0YXJ0ID4gMCAmJiAtMSA9PT0gJ1xceDAwXFxyXFxuXFx4ODVcXHUyMDI4XFx1MjAyOScuaW5kZXhPZih0aGlzLmJ1ZmZlci5jaGFyQXQoc3RhcnQgLSAxKSkpIHtcbiAgICBzdGFydCAtPSAxO1xuICAgIGlmICh0aGlzLnBvc2l0aW9uIC0gc3RhcnQgPiAobWF4TGVuZ3RoIC8gMiAtIDEpKSB7XG4gICAgICBoZWFkID0gJyAuLi4gJztcbiAgICAgIHN0YXJ0ICs9IDU7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICB0YWlsID0gJyc7XG4gIGVuZCA9IHRoaXMucG9zaXRpb247XG5cbiAgd2hpbGUgKGVuZCA8IHRoaXMuYnVmZmVyLmxlbmd0aCAmJiAtMSA9PT0gJ1xceDAwXFxyXFxuXFx4ODVcXHUyMDI4XFx1MjAyOScuaW5kZXhPZih0aGlzLmJ1ZmZlci5jaGFyQXQoZW5kKSkpIHtcbiAgICBlbmQgKz0gMTtcbiAgICBpZiAoZW5kIC0gdGhpcy5wb3NpdGlvbiA+IChtYXhMZW5ndGggLyAyIC0gMSkpIHtcbiAgICAgIHRhaWwgPSAnIC4uLiAnO1xuICAgICAgZW5kIC09IDU7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBzbmlwcGV0ID0gdGhpcy5idWZmZXIuc2xpY2Uoc3RhcnQsIGVuZCk7XG5cbiAgcmV0dXJuIGNvbW1vbi5yZXBlYXQoJyAnLCBpbmRlbnQpICsgaGVhZCArIHNuaXBwZXQgKyB0YWlsICsgJ1xcbicgK1xuICAgICAgICAgY29tbW9uLnJlcGVhdCgnICcsIGluZGVudCArIHRoaXMucG9zaXRpb24gLSBzdGFydCArIGhlYWQubGVuZ3RoKSArICdeJztcbn07XG5cblxuTWFyay5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZyhjb21wYWN0KSB7XG4gIHZhciBzbmlwcGV0LCB3aGVyZSA9ICcnO1xuXG4gIGlmICh0aGlzLm5hbWUpIHtcbiAgICB3aGVyZSArPSAnaW4gXCInICsgdGhpcy5uYW1lICsgJ1wiICc7XG4gIH1cblxuICB3aGVyZSArPSAnYXQgbGluZSAnICsgKHRoaXMubGluZSArIDEpICsgJywgY29sdW1uICcgKyAodGhpcy5jb2x1bW4gKyAxKTtcblxuICBpZiAoIWNvbXBhY3QpIHtcbiAgICBzbmlwcGV0ID0gdGhpcy5nZXRTbmlwcGV0KCk7XG5cbiAgICBpZiAoc25pcHBldCkge1xuICAgICAgd2hlcmUgKz0gJzpcXG4nICsgc25pcHBldDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gd2hlcmU7XG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gTWFyaztcbiIsIid1c2Ugc3RyaWN0JztcblxuLyplc2xpbnQtZGlzYWJsZSBtYXgtbGVuKi9cblxudmFyIGNvbW1vbiAgICAgICAgPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIFlBTUxFeGNlcHRpb24gPSByZXF1aXJlKCcuL2V4Y2VwdGlvbicpO1xudmFyIFR5cGUgICAgICAgICAgPSByZXF1aXJlKCcuL3R5cGUnKTtcblxuXG5mdW5jdGlvbiBjb21waWxlTGlzdChzY2hlbWEsIG5hbWUsIHJlc3VsdCkge1xuICB2YXIgZXhjbHVkZSA9IFtdO1xuXG4gIHNjaGVtYS5pbmNsdWRlLmZvckVhY2goZnVuY3Rpb24gKGluY2x1ZGVkU2NoZW1hKSB7XG4gICAgcmVzdWx0ID0gY29tcGlsZUxpc3QoaW5jbHVkZWRTY2hlbWEsIG5hbWUsIHJlc3VsdCk7XG4gIH0pO1xuXG4gIHNjaGVtYVtuYW1lXS5mb3JFYWNoKGZ1bmN0aW9uIChjdXJyZW50VHlwZSkge1xuICAgIHJlc3VsdC5mb3JFYWNoKGZ1bmN0aW9uIChwcmV2aW91c1R5cGUsIHByZXZpb3VzSW5kZXgpIHtcbiAgICAgIGlmIChwcmV2aW91c1R5cGUudGFnID09PSBjdXJyZW50VHlwZS50YWcpIHtcbiAgICAgICAgZXhjbHVkZS5wdXNoKHByZXZpb3VzSW5kZXgpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmVzdWx0LnB1c2goY3VycmVudFR5cGUpO1xuICB9KTtcblxuICByZXR1cm4gcmVzdWx0LmZpbHRlcihmdW5jdGlvbiAodHlwZSwgaW5kZXgpIHtcbiAgICByZXR1cm4gLTEgPT09IGV4Y2x1ZGUuaW5kZXhPZihpbmRleCk7XG4gIH0pO1xufVxuXG5cbmZ1bmN0aW9uIGNvbXBpbGVNYXAoLyogbGlzdHMuLi4gKi8pIHtcbiAgdmFyIHJlc3VsdCA9IHt9LCBpbmRleCwgbGVuZ3RoO1xuXG4gIGZ1bmN0aW9uIGNvbGxlY3RUeXBlKHR5cGUpIHtcbiAgICByZXN1bHRbdHlwZS50YWddID0gdHlwZTtcbiAgfVxuXG4gIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIGFyZ3VtZW50c1tpbmRleF0uZm9yRWFjaChjb2xsZWN0VHlwZSk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5cbmZ1bmN0aW9uIFNjaGVtYShkZWZpbml0aW9uKSB7XG4gIHRoaXMuaW5jbHVkZSAgPSBkZWZpbml0aW9uLmluY2x1ZGUgIHx8IFtdO1xuICB0aGlzLmltcGxpY2l0ID0gZGVmaW5pdGlvbi5pbXBsaWNpdCB8fCBbXTtcbiAgdGhpcy5leHBsaWNpdCA9IGRlZmluaXRpb24uZXhwbGljaXQgfHwgW107XG5cbiAgdGhpcy5pbXBsaWNpdC5mb3JFYWNoKGZ1bmN0aW9uICh0eXBlKSB7XG4gICAgaWYgKHR5cGUubG9hZEtpbmQgJiYgJ3NjYWxhcicgIT09IHR5cGUubG9hZEtpbmQpIHtcbiAgICAgIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdUaGVyZSBpcyBhIG5vbi1zY2FsYXIgdHlwZSBpbiB0aGUgaW1wbGljaXQgbGlzdCBvZiBhIHNjaGVtYS4gSW1wbGljaXQgcmVzb2x2aW5nIG9mIHN1Y2ggdHlwZXMgaXMgbm90IHN1cHBvcnRlZC4nKTtcbiAgICB9XG4gIH0pO1xuXG4gIHRoaXMuY29tcGlsZWRJbXBsaWNpdCA9IGNvbXBpbGVMaXN0KHRoaXMsICdpbXBsaWNpdCcsIFtdKTtcbiAgdGhpcy5jb21waWxlZEV4cGxpY2l0ID0gY29tcGlsZUxpc3QodGhpcywgJ2V4cGxpY2l0JywgW10pO1xuICB0aGlzLmNvbXBpbGVkVHlwZU1hcCAgPSBjb21waWxlTWFwKHRoaXMuY29tcGlsZWRJbXBsaWNpdCwgdGhpcy5jb21waWxlZEV4cGxpY2l0KTtcbn1cblxuXG5TY2hlbWEuREVGQVVMVCA9IG51bGw7XG5cblxuU2NoZW1hLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZVNjaGVtYSgpIHtcbiAgdmFyIHNjaGVtYXMsIHR5cGVzO1xuXG4gIHN3aXRjaCAoYXJndW1lbnRzLmxlbmd0aCkge1xuICBjYXNlIDE6XG4gICAgc2NoZW1hcyA9IFNjaGVtYS5ERUZBVUxUO1xuICAgIHR5cGVzID0gYXJndW1lbnRzWzBdO1xuICAgIGJyZWFrO1xuXG4gIGNhc2UgMjpcbiAgICBzY2hlbWFzID0gYXJndW1lbnRzWzBdO1xuICAgIHR5cGVzID0gYXJndW1lbnRzWzFdO1xuICAgIGJyZWFrO1xuXG4gIGRlZmF1bHQ6XG4gICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ1dyb25nIG51bWJlciBvZiBhcmd1bWVudHMgZm9yIFNjaGVtYS5jcmVhdGUgZnVuY3Rpb24nKTtcbiAgfVxuXG4gIHNjaGVtYXMgPSBjb21tb24udG9BcnJheShzY2hlbWFzKTtcbiAgdHlwZXMgPSBjb21tb24udG9BcnJheSh0eXBlcyk7XG5cbiAgaWYgKCFzY2hlbWFzLmV2ZXJ5KGZ1bmN0aW9uIChzY2hlbWEpIHsgcmV0dXJuIHNjaGVtYSBpbnN0YW5jZW9mIFNjaGVtYTsgfSkpIHtcbiAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignU3BlY2lmaWVkIGxpc3Qgb2Ygc3VwZXIgc2NoZW1hcyAob3IgYSBzaW5nbGUgU2NoZW1hIG9iamVjdCkgY29udGFpbnMgYSBub24tU2NoZW1hIG9iamVjdC4nKTtcbiAgfVxuXG4gIGlmICghdHlwZXMuZXZlcnkoZnVuY3Rpb24gKHR5cGUpIHsgcmV0dXJuIHR5cGUgaW5zdGFuY2VvZiBUeXBlOyB9KSkge1xuICAgIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdTcGVjaWZpZWQgbGlzdCBvZiBZQU1MIHR5cGVzIChvciBhIHNpbmdsZSBUeXBlIG9iamVjdCkgY29udGFpbnMgYSBub24tVHlwZSBvYmplY3QuJyk7XG4gIH1cblxuICByZXR1cm4gbmV3IFNjaGVtYSh7XG4gICAgaW5jbHVkZTogc2NoZW1hcyxcbiAgICBleHBsaWNpdDogdHlwZXNcbiAgfSk7XG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gU2NoZW1hO1xuIiwiLy8gU3RhbmRhcmQgWUFNTCdzIENvcmUgc2NoZW1hLlxuLy8gaHR0cDovL3d3dy55YW1sLm9yZy9zcGVjLzEuMi9zcGVjLmh0bWwjaWQyODA0OTIzXG4vL1xuLy8gTk9URTogSlMtWUFNTCBkb2VzIG5vdCBzdXBwb3J0IHNjaGVtYS1zcGVjaWZpYyB0YWcgcmVzb2x1dGlvbiByZXN0cmljdGlvbnMuXG4vLyBTbywgQ29yZSBzY2hlbWEgaGFzIG5vIGRpc3RpbmN0aW9ucyBmcm9tIEpTT04gc2NoZW1hIGlzIEpTLVlBTUwuXG5cblxuJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBTY2hlbWEgPSByZXF1aXJlKCcuLi9zY2hlbWEnKTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBTY2hlbWEoe1xuICBpbmNsdWRlOiBbXG4gICAgcmVxdWlyZSgnLi9qc29uJylcbiAgXVxufSk7XG4iLCIvLyBKUy1ZQU1MJ3MgZGVmYXVsdCBzY2hlbWEgZm9yIGBsb2FkYCBmdW5jdGlvbi5cbi8vIEl0IGlzIG5vdCBkZXNjcmliZWQgaW4gdGhlIFlBTUwgc3BlY2lmaWNhdGlvbi5cbi8vXG4vLyBUaGlzIHNjaGVtYSBpcyBiYXNlZCBvbiBKUy1ZQU1MJ3MgZGVmYXVsdCBzYWZlIHNjaGVtYSBhbmQgaW5jbHVkZXNcbi8vIEphdmFTY3JpcHQtc3BlY2lmaWMgdHlwZXM6ICEhanMvdW5kZWZpbmVkLCAhIWpzL3JlZ2V4cCBhbmQgISFqcy9mdW5jdGlvbi5cbi8vXG4vLyBBbHNvIHRoaXMgc2NoZW1hIGlzIHVzZWQgYXMgZGVmYXVsdCBiYXNlIHNjaGVtYSBhdCBgU2NoZW1hLmNyZWF0ZWAgZnVuY3Rpb24uXG5cblxuJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBTY2hlbWEgPSByZXF1aXJlKCcuLi9zY2hlbWEnKTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IFNjaGVtYS5ERUZBVUxUID0gbmV3IFNjaGVtYSh7XG4gIGluY2x1ZGU6IFtcbiAgICByZXF1aXJlKCcuL2RlZmF1bHRfc2FmZScpXG4gIF0sXG4gIGV4cGxpY2l0OiBbXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9qcy91bmRlZmluZWQnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL2pzL3JlZ2V4cCcpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvanMvZnVuY3Rpb24nKVxuICBdXG59KTtcbiIsIi8vIEpTLVlBTUwncyBkZWZhdWx0IHNjaGVtYSBmb3IgYHNhZmVMb2FkYCBmdW5jdGlvbi5cbi8vIEl0IGlzIG5vdCBkZXNjcmliZWQgaW4gdGhlIFlBTUwgc3BlY2lmaWNhdGlvbi5cbi8vXG4vLyBUaGlzIHNjaGVtYSBpcyBiYXNlZCBvbiBzdGFuZGFyZCBZQU1MJ3MgQ29yZSBzY2hlbWEgYW5kIGluY2x1ZGVzIG1vc3Qgb2Zcbi8vIGV4dHJhIHR5cGVzIGRlc2NyaWJlZCBhdCBZQU1MIHRhZyByZXBvc2l0b3J5LiAoaHR0cDovL3lhbWwub3JnL3R5cGUvKVxuXG5cbid1c2Ugc3RyaWN0JztcblxuXG52YXIgU2NoZW1hID0gcmVxdWlyZSgnLi4vc2NoZW1hJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgU2NoZW1hKHtcbiAgaW5jbHVkZTogW1xuICAgIHJlcXVpcmUoJy4vY29yZScpXG4gIF0sXG4gIGltcGxpY2l0OiBbXG4gICAgcmVxdWlyZSgnLi4vdHlwZS90aW1lc3RhbXAnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL21lcmdlJylcbiAgXSxcbiAgZXhwbGljaXQ6IFtcbiAgICByZXF1aXJlKCcuLi90eXBlL2JpbmFyeScpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvb21hcCcpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvcGFpcnMnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL3NldCcpXG4gIF1cbn0pO1xuIiwiLy8gU3RhbmRhcmQgWUFNTCdzIEZhaWxzYWZlIHNjaGVtYS5cbi8vIGh0dHA6Ly93d3cueWFtbC5vcmcvc3BlYy8xLjIvc3BlYy5odG1sI2lkMjgwMjM0NlxuXG5cbid1c2Ugc3RyaWN0JztcblxuXG52YXIgU2NoZW1hID0gcmVxdWlyZSgnLi4vc2NoZW1hJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgU2NoZW1hKHtcbiAgZXhwbGljaXQ6IFtcbiAgICByZXF1aXJlKCcuLi90eXBlL3N0cicpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvc2VxJyksXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9tYXAnKVxuICBdXG59KTtcbiIsIi8vIFN0YW5kYXJkIFlBTUwncyBKU09OIHNjaGVtYS5cbi8vIGh0dHA6Ly93d3cueWFtbC5vcmcvc3BlYy8xLjIvc3BlYy5odG1sI2lkMjgwMzIzMVxuLy9cbi8vIE5PVEU6IEpTLVlBTUwgZG9lcyBub3Qgc3VwcG9ydCBzY2hlbWEtc3BlY2lmaWMgdGFnIHJlc29sdXRpb24gcmVzdHJpY3Rpb25zLlxuLy8gU28sIHRoaXMgc2NoZW1hIGlzIG5vdCBzdWNoIHN0cmljdCBhcyBkZWZpbmVkIGluIHRoZSBZQU1MIHNwZWNpZmljYXRpb24uXG4vLyBJdCBhbGxvd3MgbnVtYmVycyBpbiBiaW5hcnkgbm90YWlvbiwgdXNlIGBOdWxsYCBhbmQgYE5VTExgIGFzIGBudWxsYCwgZXRjLlxuXG5cbid1c2Ugc3RyaWN0JztcblxuXG52YXIgU2NoZW1hID0gcmVxdWlyZSgnLi4vc2NoZW1hJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgU2NoZW1hKHtcbiAgaW5jbHVkZTogW1xuICAgIHJlcXVpcmUoJy4vZmFpbHNhZmUnKVxuICBdLFxuICBpbXBsaWNpdDogW1xuICAgIHJlcXVpcmUoJy4uL3R5cGUvbnVsbCcpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvYm9vbCcpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvaW50JyksXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9mbG9hdCcpXG4gIF1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgWUFNTEV4Y2VwdGlvbiA9IHJlcXVpcmUoJy4vZXhjZXB0aW9uJyk7XG5cbnZhciBUWVBFX0NPTlNUUlVDVE9SX09QVElPTlMgPSBbXG4gICdraW5kJyxcbiAgJ3Jlc29sdmUnLFxuICAnY29uc3RydWN0JyxcbiAgJ2luc3RhbmNlT2YnLFxuICAncHJlZGljYXRlJyxcbiAgJ3JlcHJlc2VudCcsXG4gICdkZWZhdWx0U3R5bGUnLFxuICAnc3R5bGVBbGlhc2VzJ1xuXTtcblxudmFyIFlBTUxfTk9ERV9LSU5EUyA9IFtcbiAgJ3NjYWxhcicsXG4gICdzZXF1ZW5jZScsXG4gICdtYXBwaW5nJ1xuXTtcblxuZnVuY3Rpb24gY29tcGlsZVN0eWxlQWxpYXNlcyhtYXApIHtcbiAgdmFyIHJlc3VsdCA9IHt9O1xuXG4gIGlmIChudWxsICE9PSBtYXApIHtcbiAgICBPYmplY3Qua2V5cyhtYXApLmZvckVhY2goZnVuY3Rpb24gKHN0eWxlKSB7XG4gICAgICBtYXBbc3R5bGVdLmZvckVhY2goZnVuY3Rpb24gKGFsaWFzKSB7XG4gICAgICAgIHJlc3VsdFtTdHJpbmcoYWxpYXMpXSA9IHN0eWxlO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBUeXBlKHRhZywgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICBPYmplY3Qua2V5cyhvcHRpb25zKS5mb3JFYWNoKGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgaWYgKC0xID09PSBUWVBFX0NPTlNUUlVDVE9SX09QVElPTlMuaW5kZXhPZihuYW1lKSkge1xuICAgICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ1Vua25vd24gb3B0aW9uIFwiJyArIG5hbWUgKyAnXCIgaXMgbWV0IGluIGRlZmluaXRpb24gb2YgXCInICsgdGFnICsgJ1wiIFlBTUwgdHlwZS4nKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIFRPRE86IEFkZCB0YWcgZm9ybWF0IGNoZWNrLlxuICB0aGlzLnRhZyAgICAgICAgICA9IHRhZztcbiAgdGhpcy5raW5kICAgICAgICAgPSBvcHRpb25zWydraW5kJ10gICAgICAgICB8fCBudWxsO1xuICB0aGlzLnJlc29sdmUgICAgICA9IG9wdGlvbnNbJ3Jlc29sdmUnXSAgICAgIHx8IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRydWU7IH07XG4gIHRoaXMuY29uc3RydWN0ICAgID0gb3B0aW9uc1snY29uc3RydWN0J10gICAgfHwgZnVuY3Rpb24gKGRhdGEpIHsgcmV0dXJuIGRhdGE7IH07XG4gIHRoaXMuaW5zdGFuY2VPZiAgID0gb3B0aW9uc1snaW5zdGFuY2VPZiddICAgfHwgbnVsbDtcbiAgdGhpcy5wcmVkaWNhdGUgICAgPSBvcHRpb25zWydwcmVkaWNhdGUnXSAgICB8fCBudWxsO1xuICB0aGlzLnJlcHJlc2VudCAgICA9IG9wdGlvbnNbJ3JlcHJlc2VudCddICAgIHx8IG51bGw7XG4gIHRoaXMuZGVmYXVsdFN0eWxlID0gb3B0aW9uc1snZGVmYXVsdFN0eWxlJ10gfHwgbnVsbDtcbiAgdGhpcy5zdHlsZUFsaWFzZXMgPSBjb21waWxlU3R5bGVBbGlhc2VzKG9wdGlvbnNbJ3N0eWxlQWxpYXNlcyddIHx8IG51bGwpO1xuXG4gIGlmICgtMSA9PT0gWUFNTF9OT0RFX0tJTkRTLmluZGV4T2YodGhpcy5raW5kKSkge1xuICAgIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdVbmtub3duIGtpbmQgXCInICsgdGhpcy5raW5kICsgJ1wiIGlzIHNwZWNpZmllZCBmb3IgXCInICsgdGFnICsgJ1wiIFlBTUwgdHlwZS4nKTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFR5cGU7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qZXNsaW50LWRpc2FibGUgbm8tYml0d2lzZSovXG5cbi8vIEEgdHJpY2sgZm9yIGJyb3dzZXJpZmllZCB2ZXJzaW9uLlxuLy8gU2luY2Ugd2UgbWFrZSBicm93c2VyaWZpZXIgdG8gaWdub3JlIGBidWZmZXJgIG1vZHVsZSwgTm9kZUJ1ZmZlciB3aWxsIGJlIHVuZGVmaW5lZFxudmFyIE5vZGVCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG52YXIgVHlwZSAgICAgICA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxuXG4vLyBbIDY0LCA2NSwgNjYgXSAtPiBbIHBhZGRpbmcsIENSLCBMRiBdXG52YXIgQkFTRTY0X01BUCA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvPVxcblxccic7XG5cblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxCaW5hcnkoZGF0YSkge1xuICBpZiAobnVsbCA9PT0gZGF0YSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciBjb2RlLCBpZHgsIGJpdGxlbiA9IDAsIGxlbiA9IDAsIG1heCA9IGRhdGEubGVuZ3RoLCBtYXAgPSBCQVNFNjRfTUFQO1xuXG4gIC8vIENvbnZlcnQgb25lIGJ5IG9uZS5cbiAgZm9yIChpZHggPSAwOyBpZHggPCBtYXg7IGlkeCsrKSB7XG4gICAgY29kZSA9IG1hcC5pbmRleE9mKGRhdGEuY2hhckF0KGlkeCkpO1xuXG4gICAgLy8gU2tpcCBDUi9MRlxuICAgIGlmIChjb2RlID4gNjQpIHsgY29udGludWU7IH1cblxuICAgIC8vIEZhaWwgb24gaWxsZWdhbCBjaGFyYWN0ZXJzXG4gICAgaWYgKGNvZGUgPCAwKSB7IHJldHVybiBmYWxzZTsgfVxuXG4gICAgYml0bGVuICs9IDY7XG4gIH1cblxuICAvLyBJZiB0aGVyZSBhcmUgYW55IGJpdHMgbGVmdCwgc291cmNlIHdhcyBjb3JydXB0ZWRcbiAgcmV0dXJuIChiaXRsZW4gJSA4KSA9PT0gMDtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0WWFtbEJpbmFyeShkYXRhKSB7XG4gIHZhciBjb2RlLCBpZHgsIHRhaWxiaXRzLFxuICAgICAgaW5wdXQgPSBkYXRhLnJlcGxhY2UoL1tcXHJcXG49XS9nLCAnJyksIC8vIHJlbW92ZSBDUi9MRiAmIHBhZGRpbmcgdG8gc2ltcGxpZnkgc2NhblxuICAgICAgbWF4ID0gaW5wdXQubGVuZ3RoLFxuICAgICAgbWFwID0gQkFTRTY0X01BUCxcbiAgICAgIGJpdHMgPSAwLFxuICAgICAgcmVzdWx0ID0gW107XG5cbiAgLy8gQ29sbGVjdCBieSA2KjQgYml0cyAoMyBieXRlcylcblxuICBmb3IgKGlkeCA9IDA7IGlkeCA8IG1heDsgaWR4KyspIHtcbiAgICBpZiAoKGlkeCAlIDQgPT09IDApICYmIGlkeCkge1xuICAgICAgcmVzdWx0LnB1c2goKGJpdHMgPj4gMTYpICYgMHhGRik7XG4gICAgICByZXN1bHQucHVzaCgoYml0cyA+PiA4KSAmIDB4RkYpO1xuICAgICAgcmVzdWx0LnB1c2goYml0cyAmIDB4RkYpO1xuICAgIH1cblxuICAgIGJpdHMgPSAoYml0cyA8PCA2KSB8IG1hcC5pbmRleE9mKGlucHV0LmNoYXJBdChpZHgpKTtcbiAgfVxuXG4gIC8vIER1bXAgdGFpbFxuXG4gIHRhaWxiaXRzID0gKG1heCAlIDQpICogNjtcblxuICBpZiAodGFpbGJpdHMgPT09IDApIHtcbiAgICByZXN1bHQucHVzaCgoYml0cyA+PiAxNikgJiAweEZGKTtcbiAgICByZXN1bHQucHVzaCgoYml0cyA+PiA4KSAmIDB4RkYpO1xuICAgIHJlc3VsdC5wdXNoKGJpdHMgJiAweEZGKTtcbiAgfSBlbHNlIGlmICh0YWlsYml0cyA9PT0gMTgpIHtcbiAgICByZXN1bHQucHVzaCgoYml0cyA+PiAxMCkgJiAweEZGKTtcbiAgICByZXN1bHQucHVzaCgoYml0cyA+PiAyKSAmIDB4RkYpO1xuICB9IGVsc2UgaWYgKHRhaWxiaXRzID09PSAxMikge1xuICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDQpICYgMHhGRik7XG4gIH1cblxuICAvLyBXcmFwIGludG8gQnVmZmVyIGZvciBOb2RlSlMgYW5kIGxlYXZlIEFycmF5IGZvciBicm93c2VyXG4gIGlmIChOb2RlQnVmZmVyKSB7XG4gICAgcmV0dXJuIG5ldyBOb2RlQnVmZmVyKHJlc3VsdCk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiByZXByZXNlbnRZYW1sQmluYXJ5KG9iamVjdCAvKiwgc3R5bGUqLykge1xuICB2YXIgcmVzdWx0ID0gJycsIGJpdHMgPSAwLCBpZHgsIHRhaWwsXG4gICAgICBtYXggPSBvYmplY3QubGVuZ3RoLFxuICAgICAgbWFwID0gQkFTRTY0X01BUDtcblxuICAvLyBDb252ZXJ0IGV2ZXJ5IHRocmVlIGJ5dGVzIHRvIDQgQVNDSUkgY2hhcmFjdGVycy5cblxuICBmb3IgKGlkeCA9IDA7IGlkeCA8IG1heDsgaWR4KyspIHtcbiAgICBpZiAoKGlkeCAlIDMgPT09IDApICYmIGlkeCkge1xuICAgICAgcmVzdWx0ICs9IG1hcFsoYml0cyA+PiAxOCkgJiAweDNGXTtcbiAgICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gMTIpICYgMHgzRl07XG4gICAgICByZXN1bHQgKz0gbWFwWyhiaXRzID4+IDYpICYgMHgzRl07XG4gICAgICByZXN1bHQgKz0gbWFwW2JpdHMgJiAweDNGXTtcbiAgICB9XG5cbiAgICBiaXRzID0gKGJpdHMgPDwgOCkgKyBvYmplY3RbaWR4XTtcbiAgfVxuXG4gIC8vIER1bXAgdGFpbFxuXG4gIHRhaWwgPSBtYXggJSAzO1xuXG4gIGlmICh0YWlsID09PSAwKSB7XG4gICAgcmVzdWx0ICs9IG1hcFsoYml0cyA+PiAxOCkgJiAweDNGXTtcbiAgICByZXN1bHQgKz0gbWFwWyhiaXRzID4+IDEyKSAmIDB4M0ZdO1xuICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gNikgJiAweDNGXTtcbiAgICByZXN1bHQgKz0gbWFwW2JpdHMgJiAweDNGXTtcbiAgfSBlbHNlIGlmICh0YWlsID09PSAyKSB7XG4gICAgcmVzdWx0ICs9IG1hcFsoYml0cyA+PiAxMCkgJiAweDNGXTtcbiAgICByZXN1bHQgKz0gbWFwWyhiaXRzID4+IDQpICYgMHgzRl07XG4gICAgcmVzdWx0ICs9IG1hcFsoYml0cyA8PCAyKSAmIDB4M0ZdO1xuICAgIHJlc3VsdCArPSBtYXBbNjRdO1xuICB9IGVsc2UgaWYgKHRhaWwgPT09IDEpIHtcbiAgICByZXN1bHQgKz0gbWFwWyhiaXRzID4+IDIpICYgMHgzRl07XG4gICAgcmVzdWx0ICs9IG1hcFsoYml0cyA8PCA0KSAmIDB4M0ZdO1xuICAgIHJlc3VsdCArPSBtYXBbNjRdO1xuICAgIHJlc3VsdCArPSBtYXBbNjRdO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gaXNCaW5hcnkob2JqZWN0KSB7XG4gIHJldHVybiBOb2RlQnVmZmVyICYmIE5vZGVCdWZmZXIuaXNCdWZmZXIob2JqZWN0KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6YmluYXJ5Jywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxCaW5hcnksXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbEJpbmFyeSxcbiAgcHJlZGljYXRlOiBpc0JpbmFyeSxcbiAgcmVwcmVzZW50OiByZXByZXNlbnRZYW1sQmluYXJ5XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbmZ1bmN0aW9uIHJlc29sdmVZYW1sQm9vbGVhbihkYXRhKSB7XG4gIGlmIChudWxsID09PSBkYXRhKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdmFyIG1heCA9IGRhdGEubGVuZ3RoO1xuXG4gIHJldHVybiAobWF4ID09PSA0ICYmIChkYXRhID09PSAndHJ1ZScgfHwgZGF0YSA9PT0gJ1RydWUnIHx8IGRhdGEgPT09ICdUUlVFJykpIHx8XG4gICAgICAgICAobWF4ID09PSA1ICYmIChkYXRhID09PSAnZmFsc2UnIHx8IGRhdGEgPT09ICdGYWxzZScgfHwgZGF0YSA9PT0gJ0ZBTFNFJykpO1xufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RZYW1sQm9vbGVhbihkYXRhKSB7XG4gIHJldHVybiBkYXRhID09PSAndHJ1ZScgfHxcbiAgICAgICAgIGRhdGEgPT09ICdUcnVlJyB8fFxuICAgICAgICAgZGF0YSA9PT0gJ1RSVUUnO1xufVxuXG5mdW5jdGlvbiBpc0Jvb2xlYW4ob2JqZWN0KSB7XG4gIHJldHVybiAnW29iamVjdCBCb29sZWFuXScgPT09IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmplY3QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpib29sJywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxCb29sZWFuLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdFlhbWxCb29sZWFuLFxuICBwcmVkaWNhdGU6IGlzQm9vbGVhbixcbiAgcmVwcmVzZW50OiB7XG4gICAgbG93ZXJjYXNlOiBmdW5jdGlvbiAob2JqZWN0KSB7IHJldHVybiBvYmplY3QgPyAndHJ1ZScgOiAnZmFsc2UnOyB9LFxuICAgIHVwcGVyY2FzZTogZnVuY3Rpb24gKG9iamVjdCkgeyByZXR1cm4gb2JqZWN0ID8gJ1RSVUUnIDogJ0ZBTFNFJzsgfSxcbiAgICBjYW1lbGNhc2U6IGZ1bmN0aW9uIChvYmplY3QpIHsgcmV0dXJuIG9iamVjdCA/ICdUcnVlJyA6ICdGYWxzZSc7IH1cbiAgfSxcbiAgZGVmYXVsdFN0eWxlOiAnbG93ZXJjYXNlJ1xufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBjb21tb24gPSByZXF1aXJlKCcuLi9jb21tb24nKTtcbnZhciBUeXBlICAgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbnZhciBZQU1MX0ZMT0FUX1BBVFRFUk4gPSBuZXcgUmVnRXhwKFxuICAnXig/OlstK10/KD86WzAtOV1bMC05X10qKVxcXFwuWzAtOV9dKig/OltlRV1bLStdWzAtOV0rKT8nICtcbiAgJ3xcXFxcLlswLTlfXSsoPzpbZUVdWy0rXVswLTldKyk/JyArXG4gICd8Wy0rXT9bMC05XVswLTlfXSooPzo6WzAtNV0/WzAtOV0pK1xcXFwuWzAtOV9dKicgK1xuICAnfFstK10/XFxcXC4oPzppbmZ8SW5mfElORiknICtcbiAgJ3xcXFxcLig/Om5hbnxOYU58TkFOKSkkJyk7XG5cbmZ1bmN0aW9uIHJlc29sdmVZYW1sRmxvYXQoZGF0YSkge1xuICBpZiAobnVsbCA9PT0gZGF0YSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciB2YWx1ZSwgc2lnbiwgYmFzZSwgZGlnaXRzO1xuXG4gIGlmICghWUFNTF9GTE9BVF9QQVRURVJOLnRlc3QoZGF0YSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxGbG9hdChkYXRhKSB7XG4gIHZhciB2YWx1ZSwgc2lnbiwgYmFzZSwgZGlnaXRzO1xuXG4gIHZhbHVlICA9IGRhdGEucmVwbGFjZSgvXy9nLCAnJykudG9Mb3dlckNhc2UoKTtcbiAgc2lnbiAgID0gJy0nID09PSB2YWx1ZVswXSA/IC0xIDogMTtcbiAgZGlnaXRzID0gW107XG5cbiAgaWYgKDAgPD0gJystJy5pbmRleE9mKHZhbHVlWzBdKSkge1xuICAgIHZhbHVlID0gdmFsdWUuc2xpY2UoMSk7XG4gIH1cblxuICBpZiAoJy5pbmYnID09PSB2YWx1ZSkge1xuICAgIHJldHVybiAoMSA9PT0gc2lnbikgPyBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkgOiBOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFk7XG5cbiAgfSBlbHNlIGlmICgnLm5hbicgPT09IHZhbHVlKSB7XG4gICAgcmV0dXJuIE5hTjtcblxuICB9IGVsc2UgaWYgKDAgPD0gdmFsdWUuaW5kZXhPZignOicpKSB7XG4gICAgdmFsdWUuc3BsaXQoJzonKS5mb3JFYWNoKGZ1bmN0aW9uICh2KSB7XG4gICAgICBkaWdpdHMudW5zaGlmdChwYXJzZUZsb2F0KHYsIDEwKSk7XG4gICAgfSk7XG5cbiAgICB2YWx1ZSA9IDAuMDtcbiAgICBiYXNlID0gMTtcblxuICAgIGRpZ2l0cy5mb3JFYWNoKGZ1bmN0aW9uIChkKSB7XG4gICAgICB2YWx1ZSArPSBkICogYmFzZTtcbiAgICAgIGJhc2UgKj0gNjA7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gc2lnbiAqIHZhbHVlO1xuXG4gIH1cbiAgcmV0dXJuIHNpZ24gKiBwYXJzZUZsb2F0KHZhbHVlLCAxMCk7XG59XG5cbmZ1bmN0aW9uIHJlcHJlc2VudFlhbWxGbG9hdChvYmplY3QsIHN0eWxlKSB7XG4gIGlmIChpc05hTihvYmplY3QpKSB7XG4gICAgc3dpdGNoIChzdHlsZSkge1xuICAgIGNhc2UgJ2xvd2VyY2FzZSc6XG4gICAgICByZXR1cm4gJy5uYW4nO1xuICAgIGNhc2UgJ3VwcGVyY2FzZSc6XG4gICAgICByZXR1cm4gJy5OQU4nO1xuICAgIGNhc2UgJ2NhbWVsY2FzZSc6XG4gICAgICByZXR1cm4gJy5OYU4nO1xuICAgIH1cbiAgfSBlbHNlIGlmIChOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkgPT09IG9iamVjdCkge1xuICAgIHN3aXRjaCAoc3R5bGUpIHtcbiAgICBjYXNlICdsb3dlcmNhc2UnOlxuICAgICAgcmV0dXJuICcuaW5mJztcbiAgICBjYXNlICd1cHBlcmNhc2UnOlxuICAgICAgcmV0dXJuICcuSU5GJztcbiAgICBjYXNlICdjYW1lbGNhc2UnOlxuICAgICAgcmV0dXJuICcuSW5mJztcbiAgICB9XG4gIH0gZWxzZSBpZiAoTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZID09PSBvYmplY3QpIHtcbiAgICBzd2l0Y2ggKHN0eWxlKSB7XG4gICAgY2FzZSAnbG93ZXJjYXNlJzpcbiAgICAgIHJldHVybiAnLS5pbmYnO1xuICAgIGNhc2UgJ3VwcGVyY2FzZSc6XG4gICAgICByZXR1cm4gJy0uSU5GJztcbiAgICBjYXNlICdjYW1lbGNhc2UnOlxuICAgICAgcmV0dXJuICctLkluZic7XG4gICAgfVxuICB9IGVsc2UgaWYgKGNvbW1vbi5pc05lZ2F0aXZlWmVybyhvYmplY3QpKSB7XG4gICAgcmV0dXJuICctMC4wJztcbiAgfVxuICByZXR1cm4gb2JqZWN0LnRvU3RyaW5nKDEwKTtcbn1cblxuZnVuY3Rpb24gaXNGbG9hdChvYmplY3QpIHtcbiAgcmV0dXJuICgnW29iamVjdCBOdW1iZXJdJyA9PT0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iamVjdCkpICYmXG4gICAgICAgICAoMCAhPT0gb2JqZWN0ICUgMSB8fCBjb21tb24uaXNOZWdhdGl2ZVplcm8ob2JqZWN0KSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOmZsb2F0Jywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxGbG9hdCxcbiAgY29uc3RydWN0OiBjb25zdHJ1Y3RZYW1sRmxvYXQsXG4gIHByZWRpY2F0ZTogaXNGbG9hdCxcbiAgcmVwcmVzZW50OiByZXByZXNlbnRZYW1sRmxvYXQsXG4gIGRlZmF1bHRTdHlsZTogJ2xvd2VyY2FzZSdcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY29tbW9uID0gcmVxdWlyZSgnLi4vY29tbW9uJyk7XG52YXIgVHlwZSAgID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG5mdW5jdGlvbiBpc0hleENvZGUoYykge1xuICByZXR1cm4gKCgweDMwLyogMCAqLyA8PSBjKSAmJiAoYyA8PSAweDM5LyogOSAqLykpIHx8XG4gICAgICAgICAoKDB4NDEvKiBBICovIDw9IGMpICYmIChjIDw9IDB4NDYvKiBGICovKSkgfHxcbiAgICAgICAgICgoMHg2MS8qIGEgKi8gPD0gYykgJiYgKGMgPD0gMHg2Ni8qIGYgKi8pKTtcbn1cblxuZnVuY3Rpb24gaXNPY3RDb2RlKGMpIHtcbiAgcmV0dXJuICgoMHgzMC8qIDAgKi8gPD0gYykgJiYgKGMgPD0gMHgzNy8qIDcgKi8pKTtcbn1cblxuZnVuY3Rpb24gaXNEZWNDb2RlKGMpIHtcbiAgcmV0dXJuICgoMHgzMC8qIDAgKi8gPD0gYykgJiYgKGMgPD0gMHgzOS8qIDkgKi8pKTtcbn1cblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxJbnRlZ2VyKGRhdGEpIHtcbiAgaWYgKG51bGwgPT09IGRhdGEpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YXIgbWF4ID0gZGF0YS5sZW5ndGgsXG4gICAgICBpbmRleCA9IDAsXG4gICAgICBoYXNEaWdpdHMgPSBmYWxzZSxcbiAgICAgIGNoO1xuXG4gIGlmICghbWF4KSB7IHJldHVybiBmYWxzZTsgfVxuXG4gIGNoID0gZGF0YVtpbmRleF07XG5cbiAgLy8gc2lnblxuICBpZiAoY2ggPT09ICctJyB8fCBjaCA9PT0gJysnKSB7XG4gICAgY2ggPSBkYXRhWysraW5kZXhdO1xuICB9XG5cbiAgaWYgKGNoID09PSAnMCcpIHtcbiAgICAvLyAwXG4gICAgaWYgKGluZGV4ICsgMSA9PT0gbWF4KSB7IHJldHVybiB0cnVlOyB9XG4gICAgY2ggPSBkYXRhWysraW5kZXhdO1xuXG4gICAgLy8gYmFzZSAyLCBiYXNlIDgsIGJhc2UgMTZcblxuICAgIGlmIChjaCA9PT0gJ2InKSB7XG4gICAgICAvLyBiYXNlIDJcbiAgICAgIGluZGV4Kys7XG5cbiAgICAgIGZvciAoOyBpbmRleCA8IG1heDsgaW5kZXgrKykge1xuICAgICAgICBjaCA9IGRhdGFbaW5kZXhdO1xuICAgICAgICBpZiAoY2ggPT09ICdfJykgeyBjb250aW51ZTsgfVxuICAgICAgICBpZiAoY2ggIT09ICcwJyAmJiBjaCAhPT0gJzEnKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGhhc0RpZ2l0cyA9IHRydWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gaGFzRGlnaXRzO1xuICAgIH1cblxuXG4gICAgaWYgKGNoID09PSAneCcpIHtcbiAgICAgIC8vIGJhc2UgMTZcbiAgICAgIGluZGV4Kys7XG5cbiAgICAgIGZvciAoOyBpbmRleCA8IG1heDsgaW5kZXgrKykge1xuICAgICAgICBjaCA9IGRhdGFbaW5kZXhdO1xuICAgICAgICBpZiAoY2ggPT09ICdfJykgeyBjb250aW51ZTsgfVxuICAgICAgICBpZiAoIWlzSGV4Q29kZShkYXRhLmNoYXJDb2RlQXQoaW5kZXgpKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBoYXNEaWdpdHMgPSB0cnVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGhhc0RpZ2l0cztcbiAgICB9XG5cbiAgICAvLyBiYXNlIDhcbiAgICBmb3IgKDsgaW5kZXggPCBtYXg7IGluZGV4KyspIHtcbiAgICAgIGNoID0gZGF0YVtpbmRleF07XG4gICAgICBpZiAoY2ggPT09ICdfJykgeyBjb250aW51ZTsgfVxuICAgICAgaWYgKCFpc09jdENvZGUoZGF0YS5jaGFyQ29kZUF0KGluZGV4KSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgaGFzRGlnaXRzID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGhhc0RpZ2l0cztcbiAgfVxuXG4gIC8vIGJhc2UgMTAgKGV4Y2VwdCAwKSBvciBiYXNlIDYwXG5cbiAgZm9yICg7IGluZGV4IDwgbWF4OyBpbmRleCsrKSB7XG4gICAgY2ggPSBkYXRhW2luZGV4XTtcbiAgICBpZiAoY2ggPT09ICdfJykgeyBjb250aW51ZTsgfVxuICAgIGlmIChjaCA9PT0gJzonKSB7IGJyZWFrOyB9XG4gICAgaWYgKCFpc0RlY0NvZGUoZGF0YS5jaGFyQ29kZUF0KGluZGV4KSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaGFzRGlnaXRzID0gdHJ1ZTtcbiAgfVxuXG4gIGlmICghaGFzRGlnaXRzKSB7IHJldHVybiBmYWxzZTsgfVxuXG4gIC8vIGlmICFiYXNlNjAgLSBkb25lO1xuICBpZiAoY2ggIT09ICc6JykgeyByZXR1cm4gdHJ1ZTsgfVxuXG4gIC8vIGJhc2U2MCBhbG1vc3Qgbm90IHVzZWQsIG5vIG5lZWRzIHRvIG9wdGltaXplXG4gIHJldHVybiAvXig6WzAtNV0/WzAtOV0pKyQvLnRlc3QoZGF0YS5zbGljZShpbmRleCkpO1xufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RZYW1sSW50ZWdlcihkYXRhKSB7XG4gIHZhciB2YWx1ZSA9IGRhdGEsIHNpZ24gPSAxLCBjaCwgYmFzZSwgZGlnaXRzID0gW107XG5cbiAgaWYgKHZhbHVlLmluZGV4T2YoJ18nKSAhPT0gLTEpIHtcbiAgICB2YWx1ZSA9IHZhbHVlLnJlcGxhY2UoL18vZywgJycpO1xuICB9XG5cbiAgY2ggPSB2YWx1ZVswXTtcblxuICBpZiAoY2ggPT09ICctJyB8fCBjaCA9PT0gJysnKSB7XG4gICAgaWYgKGNoID09PSAnLScpIHsgc2lnbiA9IC0xOyB9XG4gICAgdmFsdWUgPSB2YWx1ZS5zbGljZSgxKTtcbiAgICBjaCA9IHZhbHVlWzBdO1xuICB9XG5cbiAgaWYgKCcwJyA9PT0gdmFsdWUpIHtcbiAgICByZXR1cm4gMDtcbiAgfVxuXG4gIGlmIChjaCA9PT0gJzAnKSB7XG4gICAgaWYgKHZhbHVlWzFdID09PSAnYicpIHtcbiAgICAgIHJldHVybiBzaWduICogcGFyc2VJbnQodmFsdWUuc2xpY2UoMiksIDIpO1xuICAgIH1cbiAgICBpZiAodmFsdWVbMV0gPT09ICd4Jykge1xuICAgICAgcmV0dXJuIHNpZ24gKiBwYXJzZUludCh2YWx1ZSwgMTYpO1xuICAgIH1cbiAgICByZXR1cm4gc2lnbiAqIHBhcnNlSW50KHZhbHVlLCA4KTtcblxuICB9XG5cbiAgaWYgKHZhbHVlLmluZGV4T2YoJzonKSAhPT0gLTEpIHtcbiAgICB2YWx1ZS5zcGxpdCgnOicpLmZvckVhY2goZnVuY3Rpb24gKHYpIHtcbiAgICAgIGRpZ2l0cy51bnNoaWZ0KHBhcnNlSW50KHYsIDEwKSk7XG4gICAgfSk7XG5cbiAgICB2YWx1ZSA9IDA7XG4gICAgYmFzZSA9IDE7XG5cbiAgICBkaWdpdHMuZm9yRWFjaChmdW5jdGlvbiAoZCkge1xuICAgICAgdmFsdWUgKz0gKGQgKiBiYXNlKTtcbiAgICAgIGJhc2UgKj0gNjA7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gc2lnbiAqIHZhbHVlO1xuXG4gIH1cblxuICByZXR1cm4gc2lnbiAqIHBhcnNlSW50KHZhbHVlLCAxMCk7XG59XG5cbmZ1bmN0aW9uIGlzSW50ZWdlcihvYmplY3QpIHtcbiAgcmV0dXJuICgnW29iamVjdCBOdW1iZXJdJyA9PT0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iamVjdCkpICYmXG4gICAgICAgICAoMCA9PT0gb2JqZWN0ICUgMSAmJiAhY29tbW9uLmlzTmVnYXRpdmVaZXJvKG9iamVjdCkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjppbnQnLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICByZXNvbHZlOiByZXNvbHZlWWFtbEludGVnZXIsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbEludGVnZXIsXG4gIHByZWRpY2F0ZTogaXNJbnRlZ2VyLFxuICByZXByZXNlbnQ6IHtcbiAgICBiaW5hcnk6ICAgICAgZnVuY3Rpb24gKG9iamVjdCkgeyByZXR1cm4gJzBiJyArIG9iamVjdC50b1N0cmluZygyKTsgfSxcbiAgICBvY3RhbDogICAgICAgZnVuY3Rpb24gKG9iamVjdCkgeyByZXR1cm4gJzAnICArIG9iamVjdC50b1N0cmluZyg4KTsgfSxcbiAgICBkZWNpbWFsOiAgICAgZnVuY3Rpb24gKG9iamVjdCkgeyByZXR1cm4gICAgICAgIG9iamVjdC50b1N0cmluZygxMCk7IH0sXG4gICAgaGV4YWRlY2ltYWw6IGZ1bmN0aW9uIChvYmplY3QpIHsgcmV0dXJuICcweCcgKyBvYmplY3QudG9TdHJpbmcoMTYpLnRvVXBwZXJDYXNlKCk7IH1cbiAgfSxcbiAgZGVmYXVsdFN0eWxlOiAnZGVjaW1hbCcsXG4gIHN0eWxlQWxpYXNlczoge1xuICAgIGJpbmFyeTogICAgICBbIDIsICAnYmluJyBdLFxuICAgIG9jdGFsOiAgICAgICBbIDgsICAnb2N0JyBdLFxuICAgIGRlY2ltYWw6ICAgICBbIDEwLCAnZGVjJyBdLFxuICAgIGhleGFkZWNpbWFsOiBbIDE2LCAnaGV4JyBdXG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZXNwcmltYTtcblxuLy8gQnJvd3NlcmlmaWVkIHZlcnNpb24gZG9lcyBub3QgaGF2ZSBlc3ByaW1hXG4vL1xuLy8gMS4gRm9yIG5vZGUuanMganVzdCByZXF1aXJlIG1vZHVsZSBhcyBkZXBzXG4vLyAyLiBGb3IgYnJvd3NlciB0cnkgdG8gcmVxdWlyZSBtdWR1bGUgdmlhIGV4dGVybmFsIEFNRCBzeXN0ZW0uXG4vLyAgICBJZiBub3QgZm91bmQgLSB0cnkgdG8gZmFsbGJhY2sgdG8gd2luZG93LmVzcHJpbWEuIElmIG5vdFxuLy8gICAgZm91bmQgdG9vIC0gdGhlbiBmYWlsIHRvIHBhcnNlLlxuLy9cbnRyeSB7XG4gIGVzcHJpbWEgPSByZXF1aXJlKCdlc3ByaW1hJyk7XG59IGNhdGNoIChfKSB7XG4gIC8qZ2xvYmFsIHdpbmRvdyAqL1xuICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHsgZXNwcmltYSA9IHdpbmRvdy5lc3ByaW1hOyB9XG59XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vLi4vdHlwZScpO1xuXG5mdW5jdGlvbiByZXNvbHZlSmF2YXNjcmlwdEZ1bmN0aW9uKGRhdGEpIHtcbiAgaWYgKG51bGwgPT09IGRhdGEpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB0cnkge1xuICAgIHZhciBzb3VyY2UgPSAnKCcgKyBkYXRhICsgJyknLFxuICAgICAgICBhc3QgICAgPSBlc3ByaW1hLnBhcnNlKHNvdXJjZSwgeyByYW5nZTogdHJ1ZSB9KSxcbiAgICAgICAgcGFyYW1zID0gW10sXG4gICAgICAgIGJvZHk7XG5cbiAgICBpZiAoJ1Byb2dyYW0nICAgICAgICAgICAgICE9PSBhc3QudHlwZSAgICAgICAgIHx8XG4gICAgICAgIDEgICAgICAgICAgICAgICAgICAgICAhPT0gYXN0LmJvZHkubGVuZ3RoICB8fFxuICAgICAgICAnRXhwcmVzc2lvblN0YXRlbWVudCcgIT09IGFzdC5ib2R5WzBdLnR5cGUgfHxcbiAgICAgICAgJ0Z1bmN0aW9uRXhwcmVzc2lvbicgICE9PSBhc3QuYm9keVswXS5leHByZXNzaW9uLnR5cGUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdEphdmFzY3JpcHRGdW5jdGlvbihkYXRhKSB7XG4gIC8qanNsaW50IGV2aWw6dHJ1ZSovXG5cbiAgdmFyIHNvdXJjZSA9ICcoJyArIGRhdGEgKyAnKScsXG4gICAgICBhc3QgICAgPSBlc3ByaW1hLnBhcnNlKHNvdXJjZSwgeyByYW5nZTogdHJ1ZSB9KSxcbiAgICAgIHBhcmFtcyA9IFtdLFxuICAgICAgYm9keTtcblxuICBpZiAoJ1Byb2dyYW0nICAgICAgICAgICAgICE9PSBhc3QudHlwZSAgICAgICAgIHx8XG4gICAgICAxICAgICAgICAgICAgICAgICAgICAgIT09IGFzdC5ib2R5Lmxlbmd0aCAgfHxcbiAgICAgICdFeHByZXNzaW9uU3RhdGVtZW50JyAhPT0gYXN0LmJvZHlbMF0udHlwZSB8fFxuICAgICAgJ0Z1bmN0aW9uRXhwcmVzc2lvbicgICE9PSBhc3QuYm9keVswXS5leHByZXNzaW9uLnR5cGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byByZXNvbHZlIGZ1bmN0aW9uJyk7XG4gIH1cblxuICBhc3QuYm9keVswXS5leHByZXNzaW9uLnBhcmFtcy5mb3JFYWNoKGZ1bmN0aW9uIChwYXJhbSkge1xuICAgIHBhcmFtcy5wdXNoKHBhcmFtLm5hbWUpO1xuICB9KTtcblxuICBib2R5ID0gYXN0LmJvZHlbMF0uZXhwcmVzc2lvbi5ib2R5LnJhbmdlO1xuXG4gIC8vIEVzcHJpbWEncyByYW5nZXMgaW5jbHVkZSB0aGUgZmlyc3QgJ3snIGFuZCB0aGUgbGFzdCAnfScgY2hhcmFjdGVycyBvblxuICAvLyBmdW5jdGlvbiBleHByZXNzaW9ucy4gU28gY3V0IHRoZW0gb3V0LlxuICAvKmVzbGludC1kaXNhYmxlIG5vLW5ldy1mdW5jKi9cbiAgcmV0dXJuIG5ldyBGdW5jdGlvbihwYXJhbXMsIHNvdXJjZS5zbGljZShib2R5WzBdICsgMSwgYm9keVsxXSAtIDEpKTtcbn1cblxuZnVuY3Rpb24gcmVwcmVzZW50SmF2YXNjcmlwdEZ1bmN0aW9uKG9iamVjdCAvKiwgc3R5bGUqLykge1xuICByZXR1cm4gb2JqZWN0LnRvU3RyaW5nKCk7XG59XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24ob2JqZWN0KSB7XG4gIHJldHVybiAnW29iamVjdCBGdW5jdGlvbl0nID09PSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqZWN0KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6anMvZnVuY3Rpb24nLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICByZXNvbHZlOiByZXNvbHZlSmF2YXNjcmlwdEZ1bmN0aW9uLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdEphdmFzY3JpcHRGdW5jdGlvbixcbiAgcHJlZGljYXRlOiBpc0Z1bmN0aW9uLFxuICByZXByZXNlbnQ6IHJlcHJlc2VudEphdmFzY3JpcHRGdW5jdGlvblxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vLi4vdHlwZScpO1xuXG5mdW5jdGlvbiByZXNvbHZlSmF2YXNjcmlwdFJlZ0V4cChkYXRhKSB7XG4gIGlmIChudWxsID09PSBkYXRhKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKDAgPT09IGRhdGEubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdmFyIHJlZ2V4cCA9IGRhdGEsXG4gICAgICB0YWlsICAgPSAvXFwvKFtnaW1dKikkLy5leGVjKGRhdGEpLFxuICAgICAgbW9kaWZpZXJzID0gJyc7XG5cbiAgLy8gaWYgcmVnZXhwIHN0YXJ0cyB3aXRoICcvJyBpdCBjYW4gaGF2ZSBtb2RpZmllcnMgYW5kIG11c3QgYmUgcHJvcGVybHkgY2xvc2VkXG4gIC8vIGAvZm9vL2dpbWAgLSBtb2RpZmllcnMgdGFpbCBjYW4gYmUgbWF4aW11bSAzIGNoYXJzXG4gIGlmICgnLycgPT09IHJlZ2V4cFswXSkge1xuICAgIGlmICh0YWlsKSB7XG4gICAgICBtb2RpZmllcnMgPSB0YWlsWzFdO1xuICAgIH1cblxuICAgIGlmIChtb2RpZmllcnMubGVuZ3RoID4gMykgeyByZXR1cm4gZmFsc2U7IH1cbiAgICAvLyBpZiBleHByZXNzaW9uIHN0YXJ0cyB3aXRoIC8sIGlzIHNob3VsZCBiZSBwcm9wZXJseSB0ZXJtaW5hdGVkXG4gICAgaWYgKHJlZ2V4cFtyZWdleHAubGVuZ3RoIC0gbW9kaWZpZXJzLmxlbmd0aCAtIDFdICE9PSAnLycpIHsgcmV0dXJuIGZhbHNlOyB9XG5cbiAgICByZWdleHAgPSByZWdleHAuc2xpY2UoMSwgcmVnZXhwLmxlbmd0aCAtIG1vZGlmaWVycy5sZW5ndGggLSAxKTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgdmFyIGR1bW15ID0gbmV3IFJlZ0V4cChyZWdleHAsIG1vZGlmaWVycyk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdEphdmFzY3JpcHRSZWdFeHAoZGF0YSkge1xuICB2YXIgcmVnZXhwID0gZGF0YSxcbiAgICAgIHRhaWwgICA9IC9cXC8oW2dpbV0qKSQvLmV4ZWMoZGF0YSksXG4gICAgICBtb2RpZmllcnMgPSAnJztcblxuICAvLyBgL2Zvby9naW1gIC0gdGFpbCBjYW4gYmUgbWF4aW11bSA0IGNoYXJzXG4gIGlmICgnLycgPT09IHJlZ2V4cFswXSkge1xuICAgIGlmICh0YWlsKSB7XG4gICAgICBtb2RpZmllcnMgPSB0YWlsWzFdO1xuICAgIH1cbiAgICByZWdleHAgPSByZWdleHAuc2xpY2UoMSwgcmVnZXhwLmxlbmd0aCAtIG1vZGlmaWVycy5sZW5ndGggLSAxKTtcbiAgfVxuXG4gIHJldHVybiBuZXcgUmVnRXhwKHJlZ2V4cCwgbW9kaWZpZXJzKTtcbn1cblxuZnVuY3Rpb24gcmVwcmVzZW50SmF2YXNjcmlwdFJlZ0V4cChvYmplY3QgLyosIHN0eWxlKi8pIHtcbiAgdmFyIHJlc3VsdCA9ICcvJyArIG9iamVjdC5zb3VyY2UgKyAnLyc7XG5cbiAgaWYgKG9iamVjdC5nbG9iYWwpIHtcbiAgICByZXN1bHQgKz0gJ2cnO1xuICB9XG5cbiAgaWYgKG9iamVjdC5tdWx0aWxpbmUpIHtcbiAgICByZXN1bHQgKz0gJ20nO1xuICB9XG5cbiAgaWYgKG9iamVjdC5pZ25vcmVDYXNlKSB7XG4gICAgcmVzdWx0ICs9ICdpJztcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIGlzUmVnRXhwKG9iamVjdCkge1xuICByZXR1cm4gJ1tvYmplY3QgUmVnRXhwXScgPT09IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmplY3QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpqcy9yZWdleHAnLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICByZXNvbHZlOiByZXNvbHZlSmF2YXNjcmlwdFJlZ0V4cCxcbiAgY29uc3RydWN0OiBjb25zdHJ1Y3RKYXZhc2NyaXB0UmVnRXhwLFxuICBwcmVkaWNhdGU6IGlzUmVnRXhwLFxuICByZXByZXNlbnQ6IHJlcHJlc2VudEphdmFzY3JpcHRSZWdFeHBcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uLy4uL3R5cGUnKTtcblxuZnVuY3Rpb24gcmVzb2x2ZUphdmFzY3JpcHRVbmRlZmluZWQoKSB7XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RKYXZhc2NyaXB0VW5kZWZpbmVkKCkge1xuICAvKmVzbGludC1kaXNhYmxlIG5vLXVuZGVmaW5lZCovXG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIHJlcHJlc2VudEphdmFzY3JpcHRVbmRlZmluZWQoKSB7XG4gIHJldHVybiAnJztcbn1cblxuZnVuY3Rpb24gaXNVbmRlZmluZWQob2JqZWN0KSB7XG4gIHJldHVybiAndW5kZWZpbmVkJyA9PT0gdHlwZW9mIG9iamVjdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6anMvdW5kZWZpbmVkJywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZUphdmFzY3JpcHRVbmRlZmluZWQsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0SmF2YXNjcmlwdFVuZGVmaW5lZCxcbiAgcHJlZGljYXRlOiBpc1VuZGVmaW5lZCxcbiAgcmVwcmVzZW50OiByZXByZXNlbnRKYXZhc2NyaXB0VW5kZWZpbmVkXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOm1hcCcsIHtcbiAga2luZDogJ21hcHBpbmcnLFxuICBjb25zdHJ1Y3Q6IGZ1bmN0aW9uIChkYXRhKSB7IHJldHVybiBudWxsICE9PSBkYXRhID8gZGF0YSA6IHt9OyB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbmZ1bmN0aW9uIHJlc29sdmVZYW1sTWVyZ2UoZGF0YSkge1xuICByZXR1cm4gJzw8JyA9PT0gZGF0YSB8fCBudWxsID09PSBkYXRhO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjptZXJnZScsIHtcbiAga2luZDogJ3NjYWxhcicsXG4gIHJlc29sdmU6IHJlc29sdmVZYW1sTWVyZ2Vcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxOdWxsKGRhdGEpIHtcbiAgaWYgKG51bGwgPT09IGRhdGEpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHZhciBtYXggPSBkYXRhLmxlbmd0aDtcblxuICByZXR1cm4gKG1heCA9PT0gMSAmJiBkYXRhID09PSAnficpIHx8XG4gICAgICAgICAobWF4ID09PSA0ICYmIChkYXRhID09PSAnbnVsbCcgfHwgZGF0YSA9PT0gJ051bGwnIHx8IGRhdGEgPT09ICdOVUxMJykpO1xufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RZYW1sTnVsbCgpIHtcbiAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGlzTnVsbChvYmplY3QpIHtcbiAgcmV0dXJuIG51bGwgPT09IG9iamVjdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6bnVsbCcsIHtcbiAga2luZDogJ3NjYWxhcicsXG4gIHJlc29sdmU6IHJlc29sdmVZYW1sTnVsbCxcbiAgY29uc3RydWN0OiBjb25zdHJ1Y3RZYW1sTnVsbCxcbiAgcHJlZGljYXRlOiBpc051bGwsXG4gIHJlcHJlc2VudDoge1xuICAgIGNhbm9uaWNhbDogZnVuY3Rpb24gKCkgeyByZXR1cm4gJ34nOyAgICB9LFxuICAgIGxvd2VyY2FzZTogZnVuY3Rpb24gKCkgeyByZXR1cm4gJ251bGwnOyB9LFxuICAgIHVwcGVyY2FzZTogZnVuY3Rpb24gKCkgeyByZXR1cm4gJ05VTEwnOyB9LFxuICAgIGNhbWVsY2FzZTogZnVuY3Rpb24gKCkgeyByZXR1cm4gJ051bGwnOyB9XG4gIH0sXG4gIGRlZmF1bHRTdHlsZTogJ2xvd2VyY2FzZSdcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxudmFyIF9oYXNPd25Qcm9wZXJ0eSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG52YXIgX3RvU3RyaW5nICAgICAgID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxPbWFwKGRhdGEpIHtcbiAgaWYgKG51bGwgPT09IGRhdGEpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHZhciBvYmplY3RLZXlzID0gW10sIGluZGV4LCBsZW5ndGgsIHBhaXIsIHBhaXJLZXksIHBhaXJIYXNLZXksXG4gICAgICBvYmplY3QgPSBkYXRhO1xuXG4gIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIHBhaXIgPSBvYmplY3RbaW5kZXhdO1xuICAgIHBhaXJIYXNLZXkgPSBmYWxzZTtcblxuICAgIGlmICgnW29iamVjdCBPYmplY3RdJyAhPT0gX3RvU3RyaW5nLmNhbGwocGFpcikpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBmb3IgKHBhaXJLZXkgaW4gcGFpcikge1xuICAgICAgaWYgKF9oYXNPd25Qcm9wZXJ0eS5jYWxsKHBhaXIsIHBhaXJLZXkpKSB7XG4gICAgICAgIGlmICghcGFpckhhc0tleSkge1xuICAgICAgICAgIHBhaXJIYXNLZXkgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghcGFpckhhc0tleSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmICgtMSA9PT0gb2JqZWN0S2V5cy5pbmRleE9mKHBhaXJLZXkpKSB7XG4gICAgICBvYmplY3RLZXlzLnB1c2gocGFpcktleSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0WWFtbE9tYXAoZGF0YSkge1xuICByZXR1cm4gbnVsbCAhPT0gZGF0YSA/IGRhdGEgOiBbXTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6b21hcCcsIHtcbiAga2luZDogJ3NlcXVlbmNlJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxPbWFwLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdFlhbWxPbWFwXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbnZhciBfdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG5mdW5jdGlvbiByZXNvbHZlWWFtbFBhaXJzKGRhdGEpIHtcbiAgaWYgKG51bGwgPT09IGRhdGEpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHZhciBpbmRleCwgbGVuZ3RoLCBwYWlyLCBrZXlzLCByZXN1bHQsXG4gICAgICBvYmplY3QgPSBkYXRhO1xuXG4gIHJlc3VsdCA9IG5ldyBBcnJheShvYmplY3QubGVuZ3RoKTtcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gb2JqZWN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICBwYWlyID0gb2JqZWN0W2luZGV4XTtcblxuICAgIGlmICgnW29iamVjdCBPYmplY3RdJyAhPT0gX3RvU3RyaW5nLmNhbGwocGFpcikpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBrZXlzID0gT2JqZWN0LmtleXMocGFpcik7XG5cbiAgICBpZiAoMSAhPT0ga2V5cy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXN1bHRbaW5kZXhdID0gWyBrZXlzWzBdLCBwYWlyW2tleXNbMF1dIF07XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0WWFtbFBhaXJzKGRhdGEpIHtcbiAgaWYgKG51bGwgPT09IGRhdGEpIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICB2YXIgaW5kZXgsIGxlbmd0aCwgcGFpciwga2V5cywgcmVzdWx0LFxuICAgICAgb2JqZWN0ID0gZGF0YTtcblxuICByZXN1bHQgPSBuZXcgQXJyYXkob2JqZWN0Lmxlbmd0aCk7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IG9iamVjdC5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgcGFpciA9IG9iamVjdFtpbmRleF07XG5cbiAgICBrZXlzID0gT2JqZWN0LmtleXMocGFpcik7XG5cbiAgICByZXN1bHRbaW5kZXhdID0gWyBrZXlzWzBdLCBwYWlyW2tleXNbMF1dIF07XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpwYWlycycsIHtcbiAga2luZDogJ3NlcXVlbmNlJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxQYWlycyxcbiAgY29uc3RydWN0OiBjb25zdHJ1Y3RZYW1sUGFpcnNcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6c2VxJywge1xuICBraW5kOiAnc2VxdWVuY2UnLFxuICBjb25zdHJ1Y3Q6IGZ1bmN0aW9uIChkYXRhKSB7IHJldHVybiBudWxsICE9PSBkYXRhID8gZGF0YSA6IFtdOyB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbnZhciBfaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG5mdW5jdGlvbiByZXNvbHZlWWFtbFNldChkYXRhKSB7XG4gIGlmIChudWxsID09PSBkYXRhKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICB2YXIga2V5LCBvYmplY3QgPSBkYXRhO1xuXG4gIGZvciAoa2V5IGluIG9iamVjdCkge1xuICAgIGlmIChfaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkpIHtcbiAgICAgIGlmIChudWxsICE9PSBvYmplY3Rba2V5XSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxTZXQoZGF0YSkge1xuICByZXR1cm4gbnVsbCAhPT0gZGF0YSA/IGRhdGEgOiB7fTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6c2V0Jywge1xuICBraW5kOiAnbWFwcGluZycsXG4gIHJlc29sdmU6IHJlc29sdmVZYW1sU2V0LFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdFlhbWxTZXRcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6c3RyJywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgY29uc3RydWN0OiBmdW5jdGlvbiAoZGF0YSkgeyByZXR1cm4gbnVsbCAhPT0gZGF0YSA/IGRhdGEgOiAnJzsgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG52YXIgWUFNTF9USU1FU1RBTVBfUkVHRVhQID0gbmV3IFJlZ0V4cChcbiAgJ14oWzAtOV1bMC05XVswLTldWzAtOV0pJyAgICAgICAgICArIC8vIFsxXSB5ZWFyXG4gICctKFswLTldWzAtOV0/KScgICAgICAgICAgICAgICAgICAgKyAvLyBbMl0gbW9udGhcbiAgJy0oWzAtOV1bMC05XT8pJyAgICAgICAgICAgICAgICAgICArIC8vIFszXSBkYXlcbiAgJyg/Oig/OltUdF18WyBcXFxcdF0rKScgICAgICAgICAgICAgICsgLy8gLi4uXG4gICcoWzAtOV1bMC05XT8pJyAgICAgICAgICAgICAgICAgICAgKyAvLyBbNF0gaG91clxuICAnOihbMC05XVswLTldKScgICAgICAgICAgICAgICAgICAgICsgLy8gWzVdIG1pbnV0ZVxuICAnOihbMC05XVswLTldKScgICAgICAgICAgICAgICAgICAgICsgLy8gWzZdIHNlY29uZFxuICAnKD86XFxcXC4oWzAtOV0qKSk/JyAgICAgICAgICAgICAgICAgKyAvLyBbN10gZnJhY3Rpb25cbiAgJyg/OlsgXFxcXHRdKihafChbLStdKShbMC05XVswLTldPyknICsgLy8gWzhdIHR6IFs5XSB0el9zaWduIFsxMF0gdHpfaG91clxuICAnKD86OihbMC05XVswLTldKSk/KSk/KT8kJyk7ICAgICAgICAgLy8gWzExXSB0el9taW51dGVcblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxUaW1lc3RhbXAoZGF0YSkge1xuICBpZiAobnVsbCA9PT0gZGF0YSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciBtYXRjaCwgeWVhciwgbW9udGgsIGRheSwgaG91ciwgbWludXRlLCBzZWNvbmQsIGZyYWN0aW9uID0gMCxcbiAgICAgIGRlbHRhID0gbnVsbCwgdHpfaG91ciwgdHpfbWludXRlLCBkYXRlO1xuXG4gIG1hdGNoID0gWUFNTF9USU1FU1RBTVBfUkVHRVhQLmV4ZWMoZGF0YSk7XG5cbiAgaWYgKG51bGwgPT09IG1hdGNoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxUaW1lc3RhbXAoZGF0YSkge1xuICB2YXIgbWF0Y2gsIHllYXIsIG1vbnRoLCBkYXksIGhvdXIsIG1pbnV0ZSwgc2Vjb25kLCBmcmFjdGlvbiA9IDAsXG4gICAgICBkZWx0YSA9IG51bGwsIHR6X2hvdXIsIHR6X21pbnV0ZSwgZGF0ZTtcblxuICBtYXRjaCA9IFlBTUxfVElNRVNUQU1QX1JFR0VYUC5leGVjKGRhdGEpO1xuXG4gIGlmIChudWxsID09PSBtYXRjaCkge1xuICAgIHRocm93IG5ldyBFcnJvcignRGF0ZSByZXNvbHZlIGVycm9yJyk7XG4gIH1cblxuICAvLyBtYXRjaDogWzFdIHllYXIgWzJdIG1vbnRoIFszXSBkYXlcblxuICB5ZWFyID0gKyhtYXRjaFsxXSk7XG4gIG1vbnRoID0gKyhtYXRjaFsyXSkgLSAxOyAvLyBKUyBtb250aCBzdGFydHMgd2l0aCAwXG4gIGRheSA9ICsobWF0Y2hbM10pO1xuXG4gIGlmICghbWF0Y2hbNF0pIHsgLy8gbm8gaG91clxuICAgIHJldHVybiBuZXcgRGF0ZShEYXRlLlVUQyh5ZWFyLCBtb250aCwgZGF5KSk7XG4gIH1cblxuICAvLyBtYXRjaDogWzRdIGhvdXIgWzVdIG1pbnV0ZSBbNl0gc2Vjb25kIFs3XSBmcmFjdGlvblxuXG4gIGhvdXIgPSArKG1hdGNoWzRdKTtcbiAgbWludXRlID0gKyhtYXRjaFs1XSk7XG4gIHNlY29uZCA9ICsobWF0Y2hbNl0pO1xuXG4gIGlmIChtYXRjaFs3XSkge1xuICAgIGZyYWN0aW9uID0gbWF0Y2hbN10uc2xpY2UoMCwgMyk7XG4gICAgd2hpbGUgKGZyYWN0aW9uLmxlbmd0aCA8IDMpIHsgLy8gbWlsbGktc2Vjb25kc1xuICAgICAgZnJhY3Rpb24gKz0gJzAnO1xuICAgIH1cbiAgICBmcmFjdGlvbiA9ICtmcmFjdGlvbjtcbiAgfVxuXG4gIC8vIG1hdGNoOiBbOF0gdHogWzldIHR6X3NpZ24gWzEwXSB0el9ob3VyIFsxMV0gdHpfbWludXRlXG5cbiAgaWYgKG1hdGNoWzldKSB7XG4gICAgdHpfaG91ciA9ICsobWF0Y2hbMTBdKTtcbiAgICB0el9taW51dGUgPSArKG1hdGNoWzExXSB8fCAwKTtcbiAgICBkZWx0YSA9ICh0el9ob3VyICogNjAgKyB0el9taW51dGUpICogNjAwMDA7IC8vIGRlbHRhIGluIG1pbGktc2Vjb25kc1xuICAgIGlmICgnLScgPT09IG1hdGNoWzldKSB7XG4gICAgICBkZWx0YSA9IC1kZWx0YTtcbiAgICB9XG4gIH1cblxuICBkYXRlID0gbmV3IERhdGUoRGF0ZS5VVEMoeWVhciwgbW9udGgsIGRheSwgaG91ciwgbWludXRlLCBzZWNvbmQsIGZyYWN0aW9uKSk7XG5cbiAgaWYgKGRlbHRhKSB7XG4gICAgZGF0ZS5zZXRUaW1lKGRhdGUuZ2V0VGltZSgpIC0gZGVsdGEpO1xuICB9XG5cbiAgcmV0dXJuIGRhdGU7XG59XG5cbmZ1bmN0aW9uIHJlcHJlc2VudFlhbWxUaW1lc3RhbXAob2JqZWN0IC8qLCBzdHlsZSovKSB7XG4gIHJldHVybiBvYmplY3QudG9JU09TdHJpbmcoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6dGltZXN0YW1wJywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxUaW1lc3RhbXAsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbFRpbWVzdGFtcCxcbiAgaW5zdGFuY2VPZjogRGF0ZSxcbiAgcmVwcmVzZW50OiByZXByZXNlbnRZYW1sVGltZXN0YW1wXG59KTtcbiIsIi8qXG4gIENvcHlyaWdodCAoQykgMjAxMyBBcml5YSBIaWRheWF0IDxhcml5YS5oaWRheWF0QGdtYWlsLmNvbT5cbiAgQ29weXJpZ2h0IChDKSAyMDEzIFRoYWRkZWUgVHlsIDx0aGFkZGVlLnR5bEBnbWFpbC5jb20+XG4gIENvcHlyaWdodCAoQykgMjAxMyBNYXRoaWFzIEJ5bmVucyA8bWF0aGlhc0BxaXdpLmJlPlxuICBDb3B5cmlnaHQgKEMpIDIwMTIgQXJpeWEgSGlkYXlhdCA8YXJpeWEuaGlkYXlhdEBnbWFpbC5jb20+XG4gIENvcHlyaWdodCAoQykgMjAxMiBNYXRoaWFzIEJ5bmVucyA8bWF0aGlhc0BxaXdpLmJlPlxuICBDb3B5cmlnaHQgKEMpIDIwMTIgSm9vc3QtV2ltIEJvZWtlc3RlaWpuIDxqb29zdC13aW1AYm9la2VzdGVpam4ubmw+XG4gIENvcHlyaWdodCAoQykgMjAxMiBLcmlzIEtvd2FsIDxrcmlzLmtvd2FsQGNpeGFyLmNvbT5cbiAgQ29weXJpZ2h0IChDKSAyMDEyIFl1c3VrZSBTdXp1a2kgPHV0YXRhbmUudGVhQGdtYWlsLmNvbT5cbiAgQ29weXJpZ2h0IChDKSAyMDEyIEFycGFkIEJvcnNvcyA8YXJwYWQuYm9yc29zQGdvb2dsZW1haWwuY29tPlxuICBDb3B5cmlnaHQgKEMpIDIwMTEgQXJpeWEgSGlkYXlhdCA8YXJpeWEuaGlkYXlhdEBnbWFpbC5jb20+XG5cbiAgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4gIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuXG4gICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodFxuICAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGVcbiAgICAgIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXG5cbiAgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiAgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuICBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuICBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgPENPUFlSSUdIVCBIT0xERVI+IEJFIExJQUJMRSBGT1IgQU5ZXG4gIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4gIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUztcbiAgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EXG4gIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4gIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRlxuICBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7XG4gICAgJ3VzZSBzdHJpY3QnO1xuXG4gICAgLy8gVW5pdmVyc2FsIE1vZHVsZSBEZWZpbml0aW9uIChVTUQpIHRvIHN1cHBvcnQgQU1ELCBDb21tb25KUy9Ob2RlLmpzLFxuICAgIC8vIFJoaW5vLCBhbmQgcGxhaW4gYnJvd3NlciBsb2FkaW5nLlxuXG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XG4gICAgICAgIGRlZmluZShbJ2V4cG9ydHMnXSwgZmFjdG9yeSk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZXhwb3J0cyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgZmFjdG9yeShleHBvcnRzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBmYWN0b3J5KChyb290LmVzcHJpbWEgPSB7fSkpO1xuICAgIH1cbn0odGhpcywgZnVuY3Rpb24gKGV4cG9ydHMpIHtcbiAgICAndXNlIHN0cmljdCc7XG5cbiAgICB2YXIgVG9rZW4sXG4gICAgICAgIFRva2VuTmFtZSxcbiAgICAgICAgRm5FeHByVG9rZW5zLFxuICAgICAgICBTeW50YXgsXG4gICAgICAgIFBsYWNlSG9sZGVycyxcbiAgICAgICAgTWVzc2FnZXMsXG4gICAgICAgIFJlZ2V4LFxuICAgICAgICBzb3VyY2UsXG4gICAgICAgIHN0cmljdCxcbiAgICAgICAgc291cmNlVHlwZSxcbiAgICAgICAgaW5kZXgsXG4gICAgICAgIGxpbmVOdW1iZXIsXG4gICAgICAgIGxpbmVTdGFydCxcbiAgICAgICAgaGFzTGluZVRlcm1pbmF0b3IsXG4gICAgICAgIGxhc3RJbmRleCxcbiAgICAgICAgbGFzdExpbmVOdW1iZXIsXG4gICAgICAgIGxhc3RMaW5lU3RhcnQsXG4gICAgICAgIHN0YXJ0SW5kZXgsXG4gICAgICAgIHN0YXJ0TGluZU51bWJlcixcbiAgICAgICAgc3RhcnRMaW5lU3RhcnQsXG4gICAgICAgIHNjYW5uaW5nLFxuICAgICAgICBsZW5ndGgsXG4gICAgICAgIGxvb2thaGVhZCxcbiAgICAgICAgc3RhdGUsXG4gICAgICAgIGV4dHJhLFxuICAgICAgICBpc0JpbmRpbmdFbGVtZW50LFxuICAgICAgICBpc0Fzc2lnbm1lbnRUYXJnZXQsXG4gICAgICAgIGZpcnN0Q292ZXJJbml0aWFsaXplZE5hbWVFcnJvcjtcblxuICAgIFRva2VuID0ge1xuICAgICAgICBCb29sZWFuTGl0ZXJhbDogMSxcbiAgICAgICAgRU9GOiAyLFxuICAgICAgICBJZGVudGlmaWVyOiAzLFxuICAgICAgICBLZXl3b3JkOiA0LFxuICAgICAgICBOdWxsTGl0ZXJhbDogNSxcbiAgICAgICAgTnVtZXJpY0xpdGVyYWw6IDYsXG4gICAgICAgIFB1bmN0dWF0b3I6IDcsXG4gICAgICAgIFN0cmluZ0xpdGVyYWw6IDgsXG4gICAgICAgIFJlZ3VsYXJFeHByZXNzaW9uOiA5LFxuICAgICAgICBUZW1wbGF0ZTogMTBcbiAgICB9O1xuXG4gICAgVG9rZW5OYW1lID0ge307XG4gICAgVG9rZW5OYW1lW1Rva2VuLkJvb2xlYW5MaXRlcmFsXSA9ICdCb29sZWFuJztcbiAgICBUb2tlbk5hbWVbVG9rZW4uRU9GXSA9ICc8ZW5kPic7XG4gICAgVG9rZW5OYW1lW1Rva2VuLklkZW50aWZpZXJdID0gJ0lkZW50aWZpZXInO1xuICAgIFRva2VuTmFtZVtUb2tlbi5LZXl3b3JkXSA9ICdLZXl3b3JkJztcbiAgICBUb2tlbk5hbWVbVG9rZW4uTnVsbExpdGVyYWxdID0gJ051bGwnO1xuICAgIFRva2VuTmFtZVtUb2tlbi5OdW1lcmljTGl0ZXJhbF0gPSAnTnVtZXJpYyc7XG4gICAgVG9rZW5OYW1lW1Rva2VuLlB1bmN0dWF0b3JdID0gJ1B1bmN0dWF0b3InO1xuICAgIFRva2VuTmFtZVtUb2tlbi5TdHJpbmdMaXRlcmFsXSA9ICdTdHJpbmcnO1xuICAgIFRva2VuTmFtZVtUb2tlbi5SZWd1bGFyRXhwcmVzc2lvbl0gPSAnUmVndWxhckV4cHJlc3Npb24nO1xuICAgIFRva2VuTmFtZVtUb2tlbi5UZW1wbGF0ZV0gPSAnVGVtcGxhdGUnO1xuXG4gICAgLy8gQSBmdW5jdGlvbiBmb2xsb3dpbmcgb25lIG9mIHRob3NlIHRva2VucyBpcyBhbiBleHByZXNzaW9uLlxuICAgIEZuRXhwclRva2VucyA9IFsnKCcsICd7JywgJ1snLCAnaW4nLCAndHlwZW9mJywgJ2luc3RhbmNlb2YnLCAnbmV3JyxcbiAgICAgICAgICAgICAgICAgICAgJ3JldHVybicsICdjYXNlJywgJ2RlbGV0ZScsICd0aHJvdycsICd2b2lkJyxcbiAgICAgICAgICAgICAgICAgICAgLy8gYXNzaWdubWVudCBvcGVyYXRvcnNcbiAgICAgICAgICAgICAgICAgICAgJz0nLCAnKz0nLCAnLT0nLCAnKj0nLCAnLz0nLCAnJT0nLCAnPDw9JywgJz4+PScsICc+Pj49JyxcbiAgICAgICAgICAgICAgICAgICAgJyY9JywgJ3w9JywgJ149JywgJywnLFxuICAgICAgICAgICAgICAgICAgICAvLyBiaW5hcnkvdW5hcnkgb3BlcmF0b3JzXG4gICAgICAgICAgICAgICAgICAgICcrJywgJy0nLCAnKicsICcvJywgJyUnLCAnKysnLCAnLS0nLCAnPDwnLCAnPj4nLCAnPj4+JywgJyYnLFxuICAgICAgICAgICAgICAgICAgICAnfCcsICdeJywgJyEnLCAnficsICcmJicsICd8fCcsICc/JywgJzonLCAnPT09JywgJz09JywgJz49JyxcbiAgICAgICAgICAgICAgICAgICAgJzw9JywgJzwnLCAnPicsICchPScsICchPT0nXTtcblxuICAgIFN5bnRheCA9IHtcbiAgICAgICAgQXNzaWdubWVudEV4cHJlc3Npb246ICdBc3NpZ25tZW50RXhwcmVzc2lvbicsXG4gICAgICAgIEFzc2lnbm1lbnRQYXR0ZXJuOiAnQXNzaWdubWVudFBhdHRlcm4nLFxuICAgICAgICBBcnJheUV4cHJlc3Npb246ICdBcnJheUV4cHJlc3Npb24nLFxuICAgICAgICBBcnJheVBhdHRlcm46ICdBcnJheVBhdHRlcm4nLFxuICAgICAgICBBcnJvd0Z1bmN0aW9uRXhwcmVzc2lvbjogJ0Fycm93RnVuY3Rpb25FeHByZXNzaW9uJyxcbiAgICAgICAgQmxvY2tTdGF0ZW1lbnQ6ICdCbG9ja1N0YXRlbWVudCcsXG4gICAgICAgIEJpbmFyeUV4cHJlc3Npb246ICdCaW5hcnlFeHByZXNzaW9uJyxcbiAgICAgICAgQnJlYWtTdGF0ZW1lbnQ6ICdCcmVha1N0YXRlbWVudCcsXG4gICAgICAgIENhbGxFeHByZXNzaW9uOiAnQ2FsbEV4cHJlc3Npb24nLFxuICAgICAgICBDYXRjaENsYXVzZTogJ0NhdGNoQ2xhdXNlJyxcbiAgICAgICAgQ2xhc3NCb2R5OiAnQ2xhc3NCb2R5JyxcbiAgICAgICAgQ2xhc3NEZWNsYXJhdGlvbjogJ0NsYXNzRGVjbGFyYXRpb24nLFxuICAgICAgICBDbGFzc0V4cHJlc3Npb246ICdDbGFzc0V4cHJlc3Npb24nLFxuICAgICAgICBDb25kaXRpb25hbEV4cHJlc3Npb246ICdDb25kaXRpb25hbEV4cHJlc3Npb24nLFxuICAgICAgICBDb250aW51ZVN0YXRlbWVudDogJ0NvbnRpbnVlU3RhdGVtZW50JyxcbiAgICAgICAgRG9XaGlsZVN0YXRlbWVudDogJ0RvV2hpbGVTdGF0ZW1lbnQnLFxuICAgICAgICBEZWJ1Z2dlclN0YXRlbWVudDogJ0RlYnVnZ2VyU3RhdGVtZW50JyxcbiAgICAgICAgRW1wdHlTdGF0ZW1lbnQ6ICdFbXB0eVN0YXRlbWVudCcsXG4gICAgICAgIEV4cG9ydEFsbERlY2xhcmF0aW9uOiAnRXhwb3J0QWxsRGVjbGFyYXRpb24nLFxuICAgICAgICBFeHBvcnREZWZhdWx0RGVjbGFyYXRpb246ICdFeHBvcnREZWZhdWx0RGVjbGFyYXRpb24nLFxuICAgICAgICBFeHBvcnROYW1lZERlY2xhcmF0aW9uOiAnRXhwb3J0TmFtZWREZWNsYXJhdGlvbicsXG4gICAgICAgIEV4cG9ydFNwZWNpZmllcjogJ0V4cG9ydFNwZWNpZmllcicsXG4gICAgICAgIEV4cHJlc3Npb25TdGF0ZW1lbnQ6ICdFeHByZXNzaW9uU3RhdGVtZW50JyxcbiAgICAgICAgRm9yU3RhdGVtZW50OiAnRm9yU3RhdGVtZW50JyxcbiAgICAgICAgRm9ySW5TdGF0ZW1lbnQ6ICdGb3JJblN0YXRlbWVudCcsXG4gICAgICAgIEZ1bmN0aW9uRGVjbGFyYXRpb246ICdGdW5jdGlvbkRlY2xhcmF0aW9uJyxcbiAgICAgICAgRnVuY3Rpb25FeHByZXNzaW9uOiAnRnVuY3Rpb25FeHByZXNzaW9uJyxcbiAgICAgICAgSWRlbnRpZmllcjogJ0lkZW50aWZpZXInLFxuICAgICAgICBJZlN0YXRlbWVudDogJ0lmU3RhdGVtZW50JyxcbiAgICAgICAgSW1wb3J0RGVjbGFyYXRpb246ICdJbXBvcnREZWNsYXJhdGlvbicsXG4gICAgICAgIEltcG9ydERlZmF1bHRTcGVjaWZpZXI6ICdJbXBvcnREZWZhdWx0U3BlY2lmaWVyJyxcbiAgICAgICAgSW1wb3J0TmFtZXNwYWNlU3BlY2lmaWVyOiAnSW1wb3J0TmFtZXNwYWNlU3BlY2lmaWVyJyxcbiAgICAgICAgSW1wb3J0U3BlY2lmaWVyOiAnSW1wb3J0U3BlY2lmaWVyJyxcbiAgICAgICAgTGl0ZXJhbDogJ0xpdGVyYWwnLFxuICAgICAgICBMYWJlbGVkU3RhdGVtZW50OiAnTGFiZWxlZFN0YXRlbWVudCcsXG4gICAgICAgIExvZ2ljYWxFeHByZXNzaW9uOiAnTG9naWNhbEV4cHJlc3Npb24nLFxuICAgICAgICBNZW1iZXJFeHByZXNzaW9uOiAnTWVtYmVyRXhwcmVzc2lvbicsXG4gICAgICAgIE1ldGhvZERlZmluaXRpb246ICdNZXRob2REZWZpbml0aW9uJyxcbiAgICAgICAgTmV3RXhwcmVzc2lvbjogJ05ld0V4cHJlc3Npb24nLFxuICAgICAgICBPYmplY3RFeHByZXNzaW9uOiAnT2JqZWN0RXhwcmVzc2lvbicsXG4gICAgICAgIE9iamVjdFBhdHRlcm46ICdPYmplY3RQYXR0ZXJuJyxcbiAgICAgICAgUHJvZ3JhbTogJ1Byb2dyYW0nLFxuICAgICAgICBQcm9wZXJ0eTogJ1Byb3BlcnR5JyxcbiAgICAgICAgUmVzdEVsZW1lbnQ6ICdSZXN0RWxlbWVudCcsXG4gICAgICAgIFJldHVyblN0YXRlbWVudDogJ1JldHVyblN0YXRlbWVudCcsXG4gICAgICAgIFNlcXVlbmNlRXhwcmVzc2lvbjogJ1NlcXVlbmNlRXhwcmVzc2lvbicsXG4gICAgICAgIFNwcmVhZEVsZW1lbnQ6ICdTcHJlYWRFbGVtZW50JyxcbiAgICAgICAgU3VwZXI6ICdTdXBlcicsXG4gICAgICAgIFN3aXRjaENhc2U6ICdTd2l0Y2hDYXNlJyxcbiAgICAgICAgU3dpdGNoU3RhdGVtZW50OiAnU3dpdGNoU3RhdGVtZW50JyxcbiAgICAgICAgVGFnZ2VkVGVtcGxhdGVFeHByZXNzaW9uOiAnVGFnZ2VkVGVtcGxhdGVFeHByZXNzaW9uJyxcbiAgICAgICAgVGVtcGxhdGVFbGVtZW50OiAnVGVtcGxhdGVFbGVtZW50JyxcbiAgICAgICAgVGVtcGxhdGVMaXRlcmFsOiAnVGVtcGxhdGVMaXRlcmFsJyxcbiAgICAgICAgVGhpc0V4cHJlc3Npb246ICdUaGlzRXhwcmVzc2lvbicsXG4gICAgICAgIFRocm93U3RhdGVtZW50OiAnVGhyb3dTdGF0ZW1lbnQnLFxuICAgICAgICBUcnlTdGF0ZW1lbnQ6ICdUcnlTdGF0ZW1lbnQnLFxuICAgICAgICBVbmFyeUV4cHJlc3Npb246ICdVbmFyeUV4cHJlc3Npb24nLFxuICAgICAgICBVcGRhdGVFeHByZXNzaW9uOiAnVXBkYXRlRXhwcmVzc2lvbicsXG4gICAgICAgIFZhcmlhYmxlRGVjbGFyYXRpb246ICdWYXJpYWJsZURlY2xhcmF0aW9uJyxcbiAgICAgICAgVmFyaWFibGVEZWNsYXJhdG9yOiAnVmFyaWFibGVEZWNsYXJhdG9yJyxcbiAgICAgICAgV2hpbGVTdGF0ZW1lbnQ6ICdXaGlsZVN0YXRlbWVudCcsXG4gICAgICAgIFdpdGhTdGF0ZW1lbnQ6ICdXaXRoU3RhdGVtZW50J1xuICAgIH07XG5cbiAgICBQbGFjZUhvbGRlcnMgPSB7XG4gICAgICAgIEFycm93UGFyYW1ldGVyUGxhY2VIb2xkZXI6ICdBcnJvd1BhcmFtZXRlclBsYWNlSG9sZGVyJ1xuICAgIH07XG5cbiAgICAvLyBFcnJvciBtZXNzYWdlcyBzaG91bGQgYmUgaWRlbnRpY2FsIHRvIFY4LlxuICAgIE1lc3NhZ2VzID0ge1xuICAgICAgICBVbmV4cGVjdGVkVG9rZW46ICdVbmV4cGVjdGVkIHRva2VuICUwJyxcbiAgICAgICAgVW5leHBlY3RlZE51bWJlcjogJ1VuZXhwZWN0ZWQgbnVtYmVyJyxcbiAgICAgICAgVW5leHBlY3RlZFN0cmluZzogJ1VuZXhwZWN0ZWQgc3RyaW5nJyxcbiAgICAgICAgVW5leHBlY3RlZElkZW50aWZpZXI6ICdVbmV4cGVjdGVkIGlkZW50aWZpZXInLFxuICAgICAgICBVbmV4cGVjdGVkUmVzZXJ2ZWQ6ICdVbmV4cGVjdGVkIHJlc2VydmVkIHdvcmQnLFxuICAgICAgICBVbmV4cGVjdGVkVGVtcGxhdGU6ICdVbmV4cGVjdGVkIHF1YXNpICUwJyxcbiAgICAgICAgVW5leHBlY3RlZEVPUzogJ1VuZXhwZWN0ZWQgZW5kIG9mIGlucHV0JyxcbiAgICAgICAgTmV3bGluZUFmdGVyVGhyb3c6ICdJbGxlZ2FsIG5ld2xpbmUgYWZ0ZXIgdGhyb3cnLFxuICAgICAgICBJbnZhbGlkUmVnRXhwOiAnSW52YWxpZCByZWd1bGFyIGV4cHJlc3Npb24nLFxuICAgICAgICBVbnRlcm1pbmF0ZWRSZWdFeHA6ICdJbnZhbGlkIHJlZ3VsYXIgZXhwcmVzc2lvbjogbWlzc2luZyAvJyxcbiAgICAgICAgSW52YWxpZExIU0luQXNzaWdubWVudDogJ0ludmFsaWQgbGVmdC1oYW5kIHNpZGUgaW4gYXNzaWdubWVudCcsXG4gICAgICAgIEludmFsaWRMSFNJbkZvckluOiAnSW52YWxpZCBsZWZ0LWhhbmQgc2lkZSBpbiBmb3ItaW4nLFxuICAgICAgICBNdWx0aXBsZURlZmF1bHRzSW5Td2l0Y2g6ICdNb3JlIHRoYW4gb25lIGRlZmF1bHQgY2xhdXNlIGluIHN3aXRjaCBzdGF0ZW1lbnQnLFxuICAgICAgICBOb0NhdGNoT3JGaW5hbGx5OiAnTWlzc2luZyBjYXRjaCBvciBmaW5hbGx5IGFmdGVyIHRyeScsXG4gICAgICAgIFVua25vd25MYWJlbDogJ1VuZGVmaW5lZCBsYWJlbCBcXCclMFxcJycsXG4gICAgICAgIFJlZGVjbGFyYXRpb246ICclMCBcXCclMVxcJyBoYXMgYWxyZWFkeSBiZWVuIGRlY2xhcmVkJyxcbiAgICAgICAgSWxsZWdhbENvbnRpbnVlOiAnSWxsZWdhbCBjb250aW51ZSBzdGF0ZW1lbnQnLFxuICAgICAgICBJbGxlZ2FsQnJlYWs6ICdJbGxlZ2FsIGJyZWFrIHN0YXRlbWVudCcsXG4gICAgICAgIElsbGVnYWxSZXR1cm46ICdJbGxlZ2FsIHJldHVybiBzdGF0ZW1lbnQnLFxuICAgICAgICBTdHJpY3RNb2RlV2l0aDogJ1N0cmljdCBtb2RlIGNvZGUgbWF5IG5vdCBpbmNsdWRlIGEgd2l0aCBzdGF0ZW1lbnQnLFxuICAgICAgICBTdHJpY3RDYXRjaFZhcmlhYmxlOiAnQ2F0Y2ggdmFyaWFibGUgbWF5IG5vdCBiZSBldmFsIG9yIGFyZ3VtZW50cyBpbiBzdHJpY3QgbW9kZScsXG4gICAgICAgIFN0cmljdFZhck5hbWU6ICdWYXJpYWJsZSBuYW1lIG1heSBub3QgYmUgZXZhbCBvciBhcmd1bWVudHMgaW4gc3RyaWN0IG1vZGUnLFxuICAgICAgICBTdHJpY3RQYXJhbU5hbWU6ICdQYXJhbWV0ZXIgbmFtZSBldmFsIG9yIGFyZ3VtZW50cyBpcyBub3QgYWxsb3dlZCBpbiBzdHJpY3QgbW9kZScsXG4gICAgICAgIFN0cmljdFBhcmFtRHVwZTogJ1N0cmljdCBtb2RlIGZ1bmN0aW9uIG1heSBub3QgaGF2ZSBkdXBsaWNhdGUgcGFyYW1ldGVyIG5hbWVzJyxcbiAgICAgICAgU3RyaWN0RnVuY3Rpb25OYW1lOiAnRnVuY3Rpb24gbmFtZSBtYXkgbm90IGJlIGV2YWwgb3IgYXJndW1lbnRzIGluIHN0cmljdCBtb2RlJyxcbiAgICAgICAgU3RyaWN0T2N0YWxMaXRlcmFsOiAnT2N0YWwgbGl0ZXJhbHMgYXJlIG5vdCBhbGxvd2VkIGluIHN0cmljdCBtb2RlLicsXG4gICAgICAgIFN0cmljdERlbGV0ZTogJ0RlbGV0ZSBvZiBhbiB1bnF1YWxpZmllZCBpZGVudGlmaWVyIGluIHN0cmljdCBtb2RlLicsXG4gICAgICAgIFN0cmljdExIU0Fzc2lnbm1lbnQ6ICdBc3NpZ25tZW50IHRvIGV2YWwgb3IgYXJndW1lbnRzIGlzIG5vdCBhbGxvd2VkIGluIHN0cmljdCBtb2RlJyxcbiAgICAgICAgU3RyaWN0TEhTUG9zdGZpeDogJ1Bvc3RmaXggaW5jcmVtZW50L2RlY3JlbWVudCBtYXkgbm90IGhhdmUgZXZhbCBvciBhcmd1bWVudHMgb3BlcmFuZCBpbiBzdHJpY3QgbW9kZScsXG4gICAgICAgIFN0cmljdExIU1ByZWZpeDogJ1ByZWZpeCBpbmNyZW1lbnQvZGVjcmVtZW50IG1heSBub3QgaGF2ZSBldmFsIG9yIGFyZ3VtZW50cyBvcGVyYW5kIGluIHN0cmljdCBtb2RlJyxcbiAgICAgICAgU3RyaWN0UmVzZXJ2ZWRXb3JkOiAnVXNlIG9mIGZ1dHVyZSByZXNlcnZlZCB3b3JkIGluIHN0cmljdCBtb2RlJyxcbiAgICAgICAgVGVtcGxhdGVPY3RhbExpdGVyYWw6ICdPY3RhbCBsaXRlcmFscyBhcmUgbm90IGFsbG93ZWQgaW4gdGVtcGxhdGUgc3RyaW5ncy4nLFxuICAgICAgICBQYXJhbWV0ZXJBZnRlclJlc3RQYXJhbWV0ZXI6ICdSZXN0IHBhcmFtZXRlciBtdXN0IGJlIGxhc3QgZm9ybWFsIHBhcmFtZXRlcicsXG4gICAgICAgIERlZmF1bHRSZXN0UGFyYW1ldGVyOiAnVW5leHBlY3RlZCB0b2tlbiA9JyxcbiAgICAgICAgT2JqZWN0UGF0dGVybkFzUmVzdFBhcmFtZXRlcjogJ1VuZXhwZWN0ZWQgdG9rZW4geycsXG4gICAgICAgIER1cGxpY2F0ZVByb3RvUHJvcGVydHk6ICdEdXBsaWNhdGUgX19wcm90b19fIGZpZWxkcyBhcmUgbm90IGFsbG93ZWQgaW4gb2JqZWN0IGxpdGVyYWxzJyxcbiAgICAgICAgQ29uc3RydWN0b3JTcGVjaWFsTWV0aG9kOiAnQ2xhc3MgY29uc3RydWN0b3IgbWF5IG5vdCBiZSBhbiBhY2Nlc3NvcicsXG4gICAgICAgIER1cGxpY2F0ZUNvbnN0cnVjdG9yOiAnQSBjbGFzcyBtYXkgb25seSBoYXZlIG9uZSBjb25zdHJ1Y3RvcicsXG4gICAgICAgIFN0YXRpY1Byb3RvdHlwZTogJ0NsYXNzZXMgbWF5IG5vdCBoYXZlIHN0YXRpYyBwcm9wZXJ0eSBuYW1lZCBwcm90b3R5cGUnLFxuICAgICAgICBNaXNzaW5nRnJvbUNsYXVzZTogJ1VuZXhwZWN0ZWQgdG9rZW4nLFxuICAgICAgICBOb0FzQWZ0ZXJJbXBvcnROYW1lc3BhY2U6ICdVbmV4cGVjdGVkIHRva2VuJyxcbiAgICAgICAgSW52YWxpZE1vZHVsZVNwZWNpZmllcjogJ1VuZXhwZWN0ZWQgdG9rZW4nLFxuICAgICAgICBJbGxlZ2FsSW1wb3J0RGVjbGFyYXRpb246ICdVbmV4cGVjdGVkIHRva2VuJyxcbiAgICAgICAgSWxsZWdhbEV4cG9ydERlY2xhcmF0aW9uOiAnVW5leHBlY3RlZCB0b2tlbidcbiAgICB9O1xuXG4gICAgLy8gU2VlIGFsc28gdG9vbHMvZ2VuZXJhdGUtdW5pY29kZS1yZWdleC5weS5cbiAgICBSZWdleCA9IHtcbiAgICAgICAgTm9uQXNjaWlJZGVudGlmaWVyU3RhcnQ6IG5ldyBSZWdFeHAoJ1tcXHhBQVxceEI1XFx4QkFcXHhDMC1cXHhENlxceEQ4LVxceEY2XFx4RjgtXFx1MDJDMVxcdTAyQzYtXFx1MDJEMVxcdTAyRTAtXFx1MDJFNFxcdTAyRUNcXHUwMkVFXFx1MDM3MC1cXHUwMzc0XFx1MDM3NlxcdTAzNzdcXHUwMzdBLVxcdTAzN0RcXHUwMzdGXFx1MDM4NlxcdTAzODgtXFx1MDM4QVxcdTAzOENcXHUwMzhFLVxcdTAzQTFcXHUwM0EzLVxcdTAzRjVcXHUwM0Y3LVxcdTA0ODFcXHUwNDhBLVxcdTA1MkZcXHUwNTMxLVxcdTA1NTZcXHUwNTU5XFx1MDU2MS1cXHUwNTg3XFx1MDVEMC1cXHUwNUVBXFx1MDVGMC1cXHUwNUYyXFx1MDYyMC1cXHUwNjRBXFx1MDY2RVxcdTA2NkZcXHUwNjcxLVxcdTA2RDNcXHUwNkQ1XFx1MDZFNVxcdTA2RTZcXHUwNkVFXFx1MDZFRlxcdTA2RkEtXFx1MDZGQ1xcdTA2RkZcXHUwNzEwXFx1MDcxMi1cXHUwNzJGXFx1MDc0RC1cXHUwN0E1XFx1MDdCMVxcdTA3Q0EtXFx1MDdFQVxcdTA3RjRcXHUwN0Y1XFx1MDdGQVxcdTA4MDAtXFx1MDgxNVxcdTA4MUFcXHUwODI0XFx1MDgyOFxcdTA4NDAtXFx1MDg1OFxcdTA4QTAtXFx1MDhCMlxcdTA5MDQtXFx1MDkzOVxcdTA5M0RcXHUwOTUwXFx1MDk1OC1cXHUwOTYxXFx1MDk3MS1cXHUwOTgwXFx1MDk4NS1cXHUwOThDXFx1MDk4RlxcdTA5OTBcXHUwOTkzLVxcdTA5QThcXHUwOUFBLVxcdTA5QjBcXHUwOUIyXFx1MDlCNi1cXHUwOUI5XFx1MDlCRFxcdTA5Q0VcXHUwOURDXFx1MDlERFxcdTA5REYtXFx1MDlFMVxcdTA5RjBcXHUwOUYxXFx1MEEwNS1cXHUwQTBBXFx1MEEwRlxcdTBBMTBcXHUwQTEzLVxcdTBBMjhcXHUwQTJBLVxcdTBBMzBcXHUwQTMyXFx1MEEzM1xcdTBBMzVcXHUwQTM2XFx1MEEzOFxcdTBBMzlcXHUwQTU5LVxcdTBBNUNcXHUwQTVFXFx1MEE3Mi1cXHUwQTc0XFx1MEE4NS1cXHUwQThEXFx1MEE4Ri1cXHUwQTkxXFx1MEE5My1cXHUwQUE4XFx1MEFBQS1cXHUwQUIwXFx1MEFCMlxcdTBBQjNcXHUwQUI1LVxcdTBBQjlcXHUwQUJEXFx1MEFEMFxcdTBBRTBcXHUwQUUxXFx1MEIwNS1cXHUwQjBDXFx1MEIwRlxcdTBCMTBcXHUwQjEzLVxcdTBCMjhcXHUwQjJBLVxcdTBCMzBcXHUwQjMyXFx1MEIzM1xcdTBCMzUtXFx1MEIzOVxcdTBCM0RcXHUwQjVDXFx1MEI1RFxcdTBCNUYtXFx1MEI2MVxcdTBCNzFcXHUwQjgzXFx1MEI4NS1cXHUwQjhBXFx1MEI4RS1cXHUwQjkwXFx1MEI5Mi1cXHUwQjk1XFx1MEI5OVxcdTBCOUFcXHUwQjlDXFx1MEI5RVxcdTBCOUZcXHUwQkEzXFx1MEJBNFxcdTBCQTgtXFx1MEJBQVxcdTBCQUUtXFx1MEJCOVxcdTBCRDBcXHUwQzA1LVxcdTBDMENcXHUwQzBFLVxcdTBDMTBcXHUwQzEyLVxcdTBDMjhcXHUwQzJBLVxcdTBDMzlcXHUwQzNEXFx1MEM1OFxcdTBDNTlcXHUwQzYwXFx1MEM2MVxcdTBDODUtXFx1MEM4Q1xcdTBDOEUtXFx1MEM5MFxcdTBDOTItXFx1MENBOFxcdTBDQUEtXFx1MENCM1xcdTBDQjUtXFx1MENCOVxcdTBDQkRcXHUwQ0RFXFx1MENFMFxcdTBDRTFcXHUwQ0YxXFx1MENGMlxcdTBEMDUtXFx1MEQwQ1xcdTBEMEUtXFx1MEQxMFxcdTBEMTItXFx1MEQzQVxcdTBEM0RcXHUwRDRFXFx1MEQ2MFxcdTBENjFcXHUwRDdBLVxcdTBEN0ZcXHUwRDg1LVxcdTBEOTZcXHUwRDlBLVxcdTBEQjFcXHUwREIzLVxcdTBEQkJcXHUwREJEXFx1MERDMC1cXHUwREM2XFx1MEUwMS1cXHUwRTMwXFx1MEUzMlxcdTBFMzNcXHUwRTQwLVxcdTBFNDZcXHUwRTgxXFx1MEU4MlxcdTBFODRcXHUwRTg3XFx1MEU4OFxcdTBFOEFcXHUwRThEXFx1MEU5NC1cXHUwRTk3XFx1MEU5OS1cXHUwRTlGXFx1MEVBMS1cXHUwRUEzXFx1MEVBNVxcdTBFQTdcXHUwRUFBXFx1MEVBQlxcdTBFQUQtXFx1MEVCMFxcdTBFQjJcXHUwRUIzXFx1MEVCRFxcdTBFQzAtXFx1MEVDNFxcdTBFQzZcXHUwRURDLVxcdTBFREZcXHUwRjAwXFx1MEY0MC1cXHUwRjQ3XFx1MEY0OS1cXHUwRjZDXFx1MEY4OC1cXHUwRjhDXFx1MTAwMC1cXHUxMDJBXFx1MTAzRlxcdTEwNTAtXFx1MTA1NVxcdTEwNUEtXFx1MTA1RFxcdTEwNjFcXHUxMDY1XFx1MTA2NlxcdTEwNkUtXFx1MTA3MFxcdTEwNzUtXFx1MTA4MVxcdTEwOEVcXHUxMEEwLVxcdTEwQzVcXHUxMEM3XFx1MTBDRFxcdTEwRDAtXFx1MTBGQVxcdTEwRkMtXFx1MTI0OFxcdTEyNEEtXFx1MTI0RFxcdTEyNTAtXFx1MTI1NlxcdTEyNThcXHUxMjVBLVxcdTEyNURcXHUxMjYwLVxcdTEyODhcXHUxMjhBLVxcdTEyOERcXHUxMjkwLVxcdTEyQjBcXHUxMkIyLVxcdTEyQjVcXHUxMkI4LVxcdTEyQkVcXHUxMkMwXFx1MTJDMi1cXHUxMkM1XFx1MTJDOC1cXHUxMkQ2XFx1MTJEOC1cXHUxMzEwXFx1MTMxMi1cXHUxMzE1XFx1MTMxOC1cXHUxMzVBXFx1MTM4MC1cXHUxMzhGXFx1MTNBMC1cXHUxM0Y0XFx1MTQwMS1cXHUxNjZDXFx1MTY2Ri1cXHUxNjdGXFx1MTY4MS1cXHUxNjlBXFx1MTZBMC1cXHUxNkVBXFx1MTZFRS1cXHUxNkY4XFx1MTcwMC1cXHUxNzBDXFx1MTcwRS1cXHUxNzExXFx1MTcyMC1cXHUxNzMxXFx1MTc0MC1cXHUxNzUxXFx1MTc2MC1cXHUxNzZDXFx1MTc2RS1cXHUxNzcwXFx1MTc4MC1cXHUxN0IzXFx1MTdEN1xcdTE3RENcXHUxODIwLVxcdTE4NzdcXHUxODgwLVxcdTE4QThcXHUxOEFBXFx1MThCMC1cXHUxOEY1XFx1MTkwMC1cXHUxOTFFXFx1MTk1MC1cXHUxOTZEXFx1MTk3MC1cXHUxOTc0XFx1MTk4MC1cXHUxOUFCXFx1MTlDMS1cXHUxOUM3XFx1MUEwMC1cXHUxQTE2XFx1MUEyMC1cXHUxQTU0XFx1MUFBN1xcdTFCMDUtXFx1MUIzM1xcdTFCNDUtXFx1MUI0QlxcdTFCODMtXFx1MUJBMFxcdTFCQUVcXHUxQkFGXFx1MUJCQS1cXHUxQkU1XFx1MUMwMC1cXHUxQzIzXFx1MUM0RC1cXHUxQzRGXFx1MUM1QS1cXHUxQzdEXFx1MUNFOS1cXHUxQ0VDXFx1MUNFRS1cXHUxQ0YxXFx1MUNGNVxcdTFDRjZcXHUxRDAwLVxcdTFEQkZcXHUxRTAwLVxcdTFGMTVcXHUxRjE4LVxcdTFGMURcXHUxRjIwLVxcdTFGNDVcXHUxRjQ4LVxcdTFGNERcXHUxRjUwLVxcdTFGNTdcXHUxRjU5XFx1MUY1QlxcdTFGNURcXHUxRjVGLVxcdTFGN0RcXHUxRjgwLVxcdTFGQjRcXHUxRkI2LVxcdTFGQkNcXHUxRkJFXFx1MUZDMi1cXHUxRkM0XFx1MUZDNi1cXHUxRkNDXFx1MUZEMC1cXHUxRkQzXFx1MUZENi1cXHUxRkRCXFx1MUZFMC1cXHUxRkVDXFx1MUZGMi1cXHUxRkY0XFx1MUZGNi1cXHUxRkZDXFx1MjA3MVxcdTIwN0ZcXHUyMDkwLVxcdTIwOUNcXHUyMTAyXFx1MjEwN1xcdTIxMEEtXFx1MjExM1xcdTIxMTVcXHUyMTE5LVxcdTIxMURcXHUyMTI0XFx1MjEyNlxcdTIxMjhcXHUyMTJBLVxcdTIxMkRcXHUyMTJGLVxcdTIxMzlcXHUyMTNDLVxcdTIxM0ZcXHUyMTQ1LVxcdTIxNDlcXHUyMTRFXFx1MjE2MC1cXHUyMTg4XFx1MkMwMC1cXHUyQzJFXFx1MkMzMC1cXHUyQzVFXFx1MkM2MC1cXHUyQ0U0XFx1MkNFQi1cXHUyQ0VFXFx1MkNGMlxcdTJDRjNcXHUyRDAwLVxcdTJEMjVcXHUyRDI3XFx1MkQyRFxcdTJEMzAtXFx1MkQ2N1xcdTJENkZcXHUyRDgwLVxcdTJEOTZcXHUyREEwLVxcdTJEQTZcXHUyREE4LVxcdTJEQUVcXHUyREIwLVxcdTJEQjZcXHUyREI4LVxcdTJEQkVcXHUyREMwLVxcdTJEQzZcXHUyREM4LVxcdTJEQ0VcXHUyREQwLVxcdTJERDZcXHUyREQ4LVxcdTJEREVcXHUyRTJGXFx1MzAwNS1cXHUzMDA3XFx1MzAyMS1cXHUzMDI5XFx1MzAzMS1cXHUzMDM1XFx1MzAzOC1cXHUzMDNDXFx1MzA0MS1cXHUzMDk2XFx1MzA5RC1cXHUzMDlGXFx1MzBBMS1cXHUzMEZBXFx1MzBGQy1cXHUzMEZGXFx1MzEwNS1cXHUzMTJEXFx1MzEzMS1cXHUzMThFXFx1MzFBMC1cXHUzMUJBXFx1MzFGMC1cXHUzMUZGXFx1MzQwMC1cXHU0REI1XFx1NEUwMC1cXHU5RkNDXFx1QTAwMC1cXHVBNDhDXFx1QTREMC1cXHVBNEZEXFx1QTUwMC1cXHVBNjBDXFx1QTYxMC1cXHVBNjFGXFx1QTYyQVxcdUE2MkJcXHVBNjQwLVxcdUE2NkVcXHVBNjdGLVxcdUE2OURcXHVBNkEwLVxcdUE2RUZcXHVBNzE3LVxcdUE3MUZcXHVBNzIyLVxcdUE3ODhcXHVBNzhCLVxcdUE3OEVcXHVBNzkwLVxcdUE3QURcXHVBN0IwXFx1QTdCMVxcdUE3RjctXFx1QTgwMVxcdUE4MDMtXFx1QTgwNVxcdUE4MDctXFx1QTgwQVxcdUE4MEMtXFx1QTgyMlxcdUE4NDAtXFx1QTg3M1xcdUE4ODItXFx1QThCM1xcdUE4RjItXFx1QThGN1xcdUE4RkJcXHVBOTBBLVxcdUE5MjVcXHVBOTMwLVxcdUE5NDZcXHVBOTYwLVxcdUE5N0NcXHVBOTg0LVxcdUE5QjJcXHVBOUNGXFx1QTlFMC1cXHVBOUU0XFx1QTlFNi1cXHVBOUVGXFx1QTlGQS1cXHVBOUZFXFx1QUEwMC1cXHVBQTI4XFx1QUE0MC1cXHVBQTQyXFx1QUE0NC1cXHVBQTRCXFx1QUE2MC1cXHVBQTc2XFx1QUE3QVxcdUFBN0UtXFx1QUFBRlxcdUFBQjFcXHVBQUI1XFx1QUFCNlxcdUFBQjktXFx1QUFCRFxcdUFBQzBcXHVBQUMyXFx1QUFEQi1cXHVBQUREXFx1QUFFMC1cXHVBQUVBXFx1QUFGMi1cXHVBQUY0XFx1QUIwMS1cXHVBQjA2XFx1QUIwOS1cXHVBQjBFXFx1QUIxMS1cXHVBQjE2XFx1QUIyMC1cXHVBQjI2XFx1QUIyOC1cXHVBQjJFXFx1QUIzMC1cXHVBQjVBXFx1QUI1Qy1cXHVBQjVGXFx1QUI2NFxcdUFCNjVcXHVBQkMwLVxcdUFCRTJcXHVBQzAwLVxcdUQ3QTNcXHVEN0IwLVxcdUQ3QzZcXHVEN0NCLVxcdUQ3RkJcXHVGOTAwLVxcdUZBNkRcXHVGQTcwLVxcdUZBRDlcXHVGQjAwLVxcdUZCMDZcXHVGQjEzLVxcdUZCMTdcXHVGQjFEXFx1RkIxRi1cXHVGQjI4XFx1RkIyQS1cXHVGQjM2XFx1RkIzOC1cXHVGQjNDXFx1RkIzRVxcdUZCNDBcXHVGQjQxXFx1RkI0M1xcdUZCNDRcXHVGQjQ2LVxcdUZCQjFcXHVGQkQzLVxcdUZEM0RcXHVGRDUwLVxcdUZEOEZcXHVGRDkyLVxcdUZEQzdcXHVGREYwLVxcdUZERkJcXHVGRTcwLVxcdUZFNzRcXHVGRTc2LVxcdUZFRkNcXHVGRjIxLVxcdUZGM0FcXHVGRjQxLVxcdUZGNUFcXHVGRjY2LVxcdUZGQkVcXHVGRkMyLVxcdUZGQzdcXHVGRkNBLVxcdUZGQ0ZcXHVGRkQyLVxcdUZGRDdcXHVGRkRBLVxcdUZGRENdJyksXG4gICAgICAgIE5vbkFzY2lpSWRlbnRpZmllclBhcnQ6IG5ldyBSZWdFeHAoJ1tcXHhBQVxceEI1XFx4QkFcXHhDMC1cXHhENlxceEQ4LVxceEY2XFx4RjgtXFx1MDJDMVxcdTAyQzYtXFx1MDJEMVxcdTAyRTAtXFx1MDJFNFxcdTAyRUNcXHUwMkVFXFx1MDMwMC1cXHUwMzc0XFx1MDM3NlxcdTAzNzdcXHUwMzdBLVxcdTAzN0RcXHUwMzdGXFx1MDM4NlxcdTAzODgtXFx1MDM4QVxcdTAzOENcXHUwMzhFLVxcdTAzQTFcXHUwM0EzLVxcdTAzRjVcXHUwM0Y3LVxcdTA0ODFcXHUwNDgzLVxcdTA0ODdcXHUwNDhBLVxcdTA1MkZcXHUwNTMxLVxcdTA1NTZcXHUwNTU5XFx1MDU2MS1cXHUwNTg3XFx1MDU5MS1cXHUwNUJEXFx1MDVCRlxcdTA1QzFcXHUwNUMyXFx1MDVDNFxcdTA1QzVcXHUwNUM3XFx1MDVEMC1cXHUwNUVBXFx1MDVGMC1cXHUwNUYyXFx1MDYxMC1cXHUwNjFBXFx1MDYyMC1cXHUwNjY5XFx1MDY2RS1cXHUwNkQzXFx1MDZENS1cXHUwNkRDXFx1MDZERi1cXHUwNkU4XFx1MDZFQS1cXHUwNkZDXFx1MDZGRlxcdTA3MTAtXFx1MDc0QVxcdTA3NEQtXFx1MDdCMVxcdTA3QzAtXFx1MDdGNVxcdTA3RkFcXHUwODAwLVxcdTA4MkRcXHUwODQwLVxcdTA4NUJcXHUwOEEwLVxcdTA4QjJcXHUwOEU0LVxcdTA5NjNcXHUwOTY2LVxcdTA5NkZcXHUwOTcxLVxcdTA5ODNcXHUwOTg1LVxcdTA5OENcXHUwOThGXFx1MDk5MFxcdTA5OTMtXFx1MDlBOFxcdTA5QUEtXFx1MDlCMFxcdTA5QjJcXHUwOUI2LVxcdTA5QjlcXHUwOUJDLVxcdTA5QzRcXHUwOUM3XFx1MDlDOFxcdTA5Q0ItXFx1MDlDRVxcdTA5RDdcXHUwOURDXFx1MDlERFxcdTA5REYtXFx1MDlFM1xcdTA5RTYtXFx1MDlGMVxcdTBBMDEtXFx1MEEwM1xcdTBBMDUtXFx1MEEwQVxcdTBBMEZcXHUwQTEwXFx1MEExMy1cXHUwQTI4XFx1MEEyQS1cXHUwQTMwXFx1MEEzMlxcdTBBMzNcXHUwQTM1XFx1MEEzNlxcdTBBMzhcXHUwQTM5XFx1MEEzQ1xcdTBBM0UtXFx1MEE0MlxcdTBBNDdcXHUwQTQ4XFx1MEE0Qi1cXHUwQTREXFx1MEE1MVxcdTBBNTktXFx1MEE1Q1xcdTBBNUVcXHUwQTY2LVxcdTBBNzVcXHUwQTgxLVxcdTBBODNcXHUwQTg1LVxcdTBBOERcXHUwQThGLVxcdTBBOTFcXHUwQTkzLVxcdTBBQThcXHUwQUFBLVxcdTBBQjBcXHUwQUIyXFx1MEFCM1xcdTBBQjUtXFx1MEFCOVxcdTBBQkMtXFx1MEFDNVxcdTBBQzctXFx1MEFDOVxcdTBBQ0ItXFx1MEFDRFxcdTBBRDBcXHUwQUUwLVxcdTBBRTNcXHUwQUU2LVxcdTBBRUZcXHUwQjAxLVxcdTBCMDNcXHUwQjA1LVxcdTBCMENcXHUwQjBGXFx1MEIxMFxcdTBCMTMtXFx1MEIyOFxcdTBCMkEtXFx1MEIzMFxcdTBCMzJcXHUwQjMzXFx1MEIzNS1cXHUwQjM5XFx1MEIzQy1cXHUwQjQ0XFx1MEI0N1xcdTBCNDhcXHUwQjRCLVxcdTBCNERcXHUwQjU2XFx1MEI1N1xcdTBCNUNcXHUwQjVEXFx1MEI1Ri1cXHUwQjYzXFx1MEI2Ni1cXHUwQjZGXFx1MEI3MVxcdTBCODJcXHUwQjgzXFx1MEI4NS1cXHUwQjhBXFx1MEI4RS1cXHUwQjkwXFx1MEI5Mi1cXHUwQjk1XFx1MEI5OVxcdTBCOUFcXHUwQjlDXFx1MEI5RVxcdTBCOUZcXHUwQkEzXFx1MEJBNFxcdTBCQTgtXFx1MEJBQVxcdTBCQUUtXFx1MEJCOVxcdTBCQkUtXFx1MEJDMlxcdTBCQzYtXFx1MEJDOFxcdTBCQ0EtXFx1MEJDRFxcdTBCRDBcXHUwQkQ3XFx1MEJFNi1cXHUwQkVGXFx1MEMwMC1cXHUwQzAzXFx1MEMwNS1cXHUwQzBDXFx1MEMwRS1cXHUwQzEwXFx1MEMxMi1cXHUwQzI4XFx1MEMyQS1cXHUwQzM5XFx1MEMzRC1cXHUwQzQ0XFx1MEM0Ni1cXHUwQzQ4XFx1MEM0QS1cXHUwQzREXFx1MEM1NVxcdTBDNTZcXHUwQzU4XFx1MEM1OVxcdTBDNjAtXFx1MEM2M1xcdTBDNjYtXFx1MEM2RlxcdTBDODEtXFx1MEM4M1xcdTBDODUtXFx1MEM4Q1xcdTBDOEUtXFx1MEM5MFxcdTBDOTItXFx1MENBOFxcdTBDQUEtXFx1MENCM1xcdTBDQjUtXFx1MENCOVxcdTBDQkMtXFx1MENDNFxcdTBDQzYtXFx1MENDOFxcdTBDQ0EtXFx1MENDRFxcdTBDRDVcXHUwQ0Q2XFx1MENERVxcdTBDRTAtXFx1MENFM1xcdTBDRTYtXFx1MENFRlxcdTBDRjFcXHUwQ0YyXFx1MEQwMS1cXHUwRDAzXFx1MEQwNS1cXHUwRDBDXFx1MEQwRS1cXHUwRDEwXFx1MEQxMi1cXHUwRDNBXFx1MEQzRC1cXHUwRDQ0XFx1MEQ0Ni1cXHUwRDQ4XFx1MEQ0QS1cXHUwRDRFXFx1MEQ1N1xcdTBENjAtXFx1MEQ2M1xcdTBENjYtXFx1MEQ2RlxcdTBEN0EtXFx1MEQ3RlxcdTBEODJcXHUwRDgzXFx1MEQ4NS1cXHUwRDk2XFx1MEQ5QS1cXHUwREIxXFx1MERCMy1cXHUwREJCXFx1MERCRFxcdTBEQzAtXFx1MERDNlxcdTBEQ0FcXHUwRENGLVxcdTBERDRcXHUwREQ2XFx1MEREOC1cXHUwRERGXFx1MERFNi1cXHUwREVGXFx1MERGMlxcdTBERjNcXHUwRTAxLVxcdTBFM0FcXHUwRTQwLVxcdTBFNEVcXHUwRTUwLVxcdTBFNTlcXHUwRTgxXFx1MEU4MlxcdTBFODRcXHUwRTg3XFx1MEU4OFxcdTBFOEFcXHUwRThEXFx1MEU5NC1cXHUwRTk3XFx1MEU5OS1cXHUwRTlGXFx1MEVBMS1cXHUwRUEzXFx1MEVBNVxcdTBFQTdcXHUwRUFBXFx1MEVBQlxcdTBFQUQtXFx1MEVCOVxcdTBFQkItXFx1MEVCRFxcdTBFQzAtXFx1MEVDNFxcdTBFQzZcXHUwRUM4LVxcdTBFQ0RcXHUwRUQwLVxcdTBFRDlcXHUwRURDLVxcdTBFREZcXHUwRjAwXFx1MEYxOFxcdTBGMTlcXHUwRjIwLVxcdTBGMjlcXHUwRjM1XFx1MEYzN1xcdTBGMzlcXHUwRjNFLVxcdTBGNDdcXHUwRjQ5LVxcdTBGNkNcXHUwRjcxLVxcdTBGODRcXHUwRjg2LVxcdTBGOTdcXHUwRjk5LVxcdTBGQkNcXHUwRkM2XFx1MTAwMC1cXHUxMDQ5XFx1MTA1MC1cXHUxMDlEXFx1MTBBMC1cXHUxMEM1XFx1MTBDN1xcdTEwQ0RcXHUxMEQwLVxcdTEwRkFcXHUxMEZDLVxcdTEyNDhcXHUxMjRBLVxcdTEyNERcXHUxMjUwLVxcdTEyNTZcXHUxMjU4XFx1MTI1QS1cXHUxMjVEXFx1MTI2MC1cXHUxMjg4XFx1MTI4QS1cXHUxMjhEXFx1MTI5MC1cXHUxMkIwXFx1MTJCMi1cXHUxMkI1XFx1MTJCOC1cXHUxMkJFXFx1MTJDMFxcdTEyQzItXFx1MTJDNVxcdTEyQzgtXFx1MTJENlxcdTEyRDgtXFx1MTMxMFxcdTEzMTItXFx1MTMxNVxcdTEzMTgtXFx1MTM1QVxcdTEzNUQtXFx1MTM1RlxcdTEzODAtXFx1MTM4RlxcdTEzQTAtXFx1MTNGNFxcdTE0MDEtXFx1MTY2Q1xcdTE2NkYtXFx1MTY3RlxcdTE2ODEtXFx1MTY5QVxcdTE2QTAtXFx1MTZFQVxcdTE2RUUtXFx1MTZGOFxcdTE3MDAtXFx1MTcwQ1xcdTE3MEUtXFx1MTcxNFxcdTE3MjAtXFx1MTczNFxcdTE3NDAtXFx1MTc1M1xcdTE3NjAtXFx1MTc2Q1xcdTE3NkUtXFx1MTc3MFxcdTE3NzJcXHUxNzczXFx1MTc4MC1cXHUxN0QzXFx1MTdEN1xcdTE3RENcXHUxN0REXFx1MTdFMC1cXHUxN0U5XFx1MTgwQi1cXHUxODBEXFx1MTgxMC1cXHUxODE5XFx1MTgyMC1cXHUxODc3XFx1MTg4MC1cXHUxOEFBXFx1MThCMC1cXHUxOEY1XFx1MTkwMC1cXHUxOTFFXFx1MTkyMC1cXHUxOTJCXFx1MTkzMC1cXHUxOTNCXFx1MTk0Ni1cXHUxOTZEXFx1MTk3MC1cXHUxOTc0XFx1MTk4MC1cXHUxOUFCXFx1MTlCMC1cXHUxOUM5XFx1MTlEMC1cXHUxOUQ5XFx1MUEwMC1cXHUxQTFCXFx1MUEyMC1cXHUxQTVFXFx1MUE2MC1cXHUxQTdDXFx1MUE3Ri1cXHUxQTg5XFx1MUE5MC1cXHUxQTk5XFx1MUFBN1xcdTFBQjAtXFx1MUFCRFxcdTFCMDAtXFx1MUI0QlxcdTFCNTAtXFx1MUI1OVxcdTFCNkItXFx1MUI3M1xcdTFCODAtXFx1MUJGM1xcdTFDMDAtXFx1MUMzN1xcdTFDNDAtXFx1MUM0OVxcdTFDNEQtXFx1MUM3RFxcdTFDRDAtXFx1MUNEMlxcdTFDRDQtXFx1MUNGNlxcdTFDRjhcXHUxQ0Y5XFx1MUQwMC1cXHUxREY1XFx1MURGQy1cXHUxRjE1XFx1MUYxOC1cXHUxRjFEXFx1MUYyMC1cXHUxRjQ1XFx1MUY0OC1cXHUxRjREXFx1MUY1MC1cXHUxRjU3XFx1MUY1OVxcdTFGNUJcXHUxRjVEXFx1MUY1Ri1cXHUxRjdEXFx1MUY4MC1cXHUxRkI0XFx1MUZCNi1cXHUxRkJDXFx1MUZCRVxcdTFGQzItXFx1MUZDNFxcdTFGQzYtXFx1MUZDQ1xcdTFGRDAtXFx1MUZEM1xcdTFGRDYtXFx1MUZEQlxcdTFGRTAtXFx1MUZFQ1xcdTFGRjItXFx1MUZGNFxcdTFGRjYtXFx1MUZGQ1xcdTIwMENcXHUyMDBEXFx1MjAzRlxcdTIwNDBcXHUyMDU0XFx1MjA3MVxcdTIwN0ZcXHUyMDkwLVxcdTIwOUNcXHUyMEQwLVxcdTIwRENcXHUyMEUxXFx1MjBFNS1cXHUyMEYwXFx1MjEwMlxcdTIxMDdcXHUyMTBBLVxcdTIxMTNcXHUyMTE1XFx1MjExOS1cXHUyMTFEXFx1MjEyNFxcdTIxMjZcXHUyMTI4XFx1MjEyQS1cXHUyMTJEXFx1MjEyRi1cXHUyMTM5XFx1MjEzQy1cXHUyMTNGXFx1MjE0NS1cXHUyMTQ5XFx1MjE0RVxcdTIxNjAtXFx1MjE4OFxcdTJDMDAtXFx1MkMyRVxcdTJDMzAtXFx1MkM1RVxcdTJDNjAtXFx1MkNFNFxcdTJDRUItXFx1MkNGM1xcdTJEMDAtXFx1MkQyNVxcdTJEMjdcXHUyRDJEXFx1MkQzMC1cXHUyRDY3XFx1MkQ2RlxcdTJEN0YtXFx1MkQ5NlxcdTJEQTAtXFx1MkRBNlxcdTJEQTgtXFx1MkRBRVxcdTJEQjAtXFx1MkRCNlxcdTJEQjgtXFx1MkRCRVxcdTJEQzAtXFx1MkRDNlxcdTJEQzgtXFx1MkRDRVxcdTJERDAtXFx1MkRENlxcdTJERDgtXFx1MkRERVxcdTJERTAtXFx1MkRGRlxcdTJFMkZcXHUzMDA1LVxcdTMwMDdcXHUzMDIxLVxcdTMwMkZcXHUzMDMxLVxcdTMwMzVcXHUzMDM4LVxcdTMwM0NcXHUzMDQxLVxcdTMwOTZcXHUzMDk5XFx1MzA5QVxcdTMwOUQtXFx1MzA5RlxcdTMwQTEtXFx1MzBGQVxcdTMwRkMtXFx1MzBGRlxcdTMxMDUtXFx1MzEyRFxcdTMxMzEtXFx1MzE4RVxcdTMxQTAtXFx1MzFCQVxcdTMxRjAtXFx1MzFGRlxcdTM0MDAtXFx1NERCNVxcdTRFMDAtXFx1OUZDQ1xcdUEwMDAtXFx1QTQ4Q1xcdUE0RDAtXFx1QTRGRFxcdUE1MDAtXFx1QTYwQ1xcdUE2MTAtXFx1QTYyQlxcdUE2NDAtXFx1QTY2RlxcdUE2NzQtXFx1QTY3RFxcdUE2N0YtXFx1QTY5RFxcdUE2OUYtXFx1QTZGMVxcdUE3MTctXFx1QTcxRlxcdUE3MjItXFx1QTc4OFxcdUE3OEItXFx1QTc4RVxcdUE3OTAtXFx1QTdBRFxcdUE3QjBcXHVBN0IxXFx1QTdGNy1cXHVBODI3XFx1QTg0MC1cXHVBODczXFx1QTg4MC1cXHVBOEM0XFx1QThEMC1cXHVBOEQ5XFx1QThFMC1cXHVBOEY3XFx1QThGQlxcdUE5MDAtXFx1QTkyRFxcdUE5MzAtXFx1QTk1M1xcdUE5NjAtXFx1QTk3Q1xcdUE5ODAtXFx1QTlDMFxcdUE5Q0YtXFx1QTlEOVxcdUE5RTAtXFx1QTlGRVxcdUFBMDAtXFx1QUEzNlxcdUFBNDAtXFx1QUE0RFxcdUFBNTAtXFx1QUE1OVxcdUFBNjAtXFx1QUE3NlxcdUFBN0EtXFx1QUFDMlxcdUFBREItXFx1QUFERFxcdUFBRTAtXFx1QUFFRlxcdUFBRjItXFx1QUFGNlxcdUFCMDEtXFx1QUIwNlxcdUFCMDktXFx1QUIwRVxcdUFCMTEtXFx1QUIxNlxcdUFCMjAtXFx1QUIyNlxcdUFCMjgtXFx1QUIyRVxcdUFCMzAtXFx1QUI1QVxcdUFCNUMtXFx1QUI1RlxcdUFCNjRcXHVBQjY1XFx1QUJDMC1cXHVBQkVBXFx1QUJFQ1xcdUFCRURcXHVBQkYwLVxcdUFCRjlcXHVBQzAwLVxcdUQ3QTNcXHVEN0IwLVxcdUQ3QzZcXHVEN0NCLVxcdUQ3RkJcXHVGOTAwLVxcdUZBNkRcXHVGQTcwLVxcdUZBRDlcXHVGQjAwLVxcdUZCMDZcXHVGQjEzLVxcdUZCMTdcXHVGQjFELVxcdUZCMjhcXHVGQjJBLVxcdUZCMzZcXHVGQjM4LVxcdUZCM0NcXHVGQjNFXFx1RkI0MFxcdUZCNDFcXHVGQjQzXFx1RkI0NFxcdUZCNDYtXFx1RkJCMVxcdUZCRDMtXFx1RkQzRFxcdUZENTAtXFx1RkQ4RlxcdUZEOTItXFx1RkRDN1xcdUZERjAtXFx1RkRGQlxcdUZFMDAtXFx1RkUwRlxcdUZFMjAtXFx1RkUyRFxcdUZFMzNcXHVGRTM0XFx1RkU0RC1cXHVGRTRGXFx1RkU3MC1cXHVGRTc0XFx1RkU3Ni1cXHVGRUZDXFx1RkYxMC1cXHVGRjE5XFx1RkYyMS1cXHVGRjNBXFx1RkYzRlxcdUZGNDEtXFx1RkY1QVxcdUZGNjYtXFx1RkZCRVxcdUZGQzItXFx1RkZDN1xcdUZGQ0EtXFx1RkZDRlxcdUZGRDItXFx1RkZEN1xcdUZGREEtXFx1RkZEQ10nKVxuICAgIH07XG5cbiAgICAvLyBFbnN1cmUgdGhlIGNvbmRpdGlvbiBpcyB0cnVlLCBvdGhlcndpc2UgdGhyb3cgYW4gZXJyb3IuXG4gICAgLy8gVGhpcyBpcyBvbmx5IHRvIGhhdmUgYSBiZXR0ZXIgY29udHJhY3Qgc2VtYW50aWMsIGkuZS4gYW5vdGhlciBzYWZldHkgbmV0XG4gICAgLy8gdG8gY2F0Y2ggYSBsb2dpYyBlcnJvci4gVGhlIGNvbmRpdGlvbiBzaGFsbCBiZSBmdWxmaWxsZWQgaW4gbm9ybWFsIGNhc2UuXG4gICAgLy8gRG8gTk9UIHVzZSB0aGlzIHRvIGVuZm9yY2UgYSBjZXJ0YWluIGNvbmRpdGlvbiBvbiBhbnkgdXNlciBpbnB1dC5cblxuICAgIGZ1bmN0aW9uIGFzc2VydChjb25kaXRpb24sIG1lc3NhZ2UpIHtcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICAgIGlmICghY29uZGl0aW9uKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FTU0VSVDogJyArIG1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNEZWNpbWFsRGlnaXQoY2gpIHtcbiAgICAgICAgcmV0dXJuIChjaCA+PSAweDMwICYmIGNoIDw9IDB4MzkpOyAgIC8vIDAuLjlcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc0hleERpZ2l0KGNoKSB7XG4gICAgICAgIHJldHVybiAnMDEyMzQ1Njc4OWFiY2RlZkFCQ0RFRicuaW5kZXhPZihjaCkgPj0gMDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc09jdGFsRGlnaXQoY2gpIHtcbiAgICAgICAgcmV0dXJuICcwMTIzNDU2NycuaW5kZXhPZihjaCkgPj0gMDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBvY3RhbFRvRGVjaW1hbChjaCkge1xuICAgICAgICAvLyBcXDAgaXMgbm90IG9jdGFsIGVzY2FwZSBzZXF1ZW5jZVxuICAgICAgICB2YXIgb2N0YWwgPSAoY2ggIT09ICcwJyksIGNvZGUgPSAnMDEyMzQ1NjcnLmluZGV4T2YoY2gpO1xuXG4gICAgICAgIGlmIChpbmRleCA8IGxlbmd0aCAmJiBpc09jdGFsRGlnaXQoc291cmNlW2luZGV4XSkpIHtcbiAgICAgICAgICAgIG9jdGFsID0gdHJ1ZTtcbiAgICAgICAgICAgIGNvZGUgPSBjb2RlICogOCArICcwMTIzNDU2NycuaW5kZXhPZihzb3VyY2VbaW5kZXgrK10pO1xuXG4gICAgICAgICAgICAvLyAzIGRpZ2l0cyBhcmUgb25seSBhbGxvd2VkIHdoZW4gc3RyaW5nIHN0YXJ0c1xuICAgICAgICAgICAgLy8gd2l0aCAwLCAxLCAyLCAzXG4gICAgICAgICAgICBpZiAoJzAxMjMnLmluZGV4T2YoY2gpID49IDAgJiZcbiAgICAgICAgICAgICAgICAgICAgaW5kZXggPCBsZW5ndGggJiZcbiAgICAgICAgICAgICAgICAgICAgaXNPY3RhbERpZ2l0KHNvdXJjZVtpbmRleF0pKSB7XG4gICAgICAgICAgICAgICAgY29kZSA9IGNvZGUgKiA4ICsgJzAxMjM0NTY3Jy5pbmRleE9mKHNvdXJjZVtpbmRleCsrXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29kZTogY29kZSxcbiAgICAgICAgICAgIG9jdGFsOiBvY3RhbFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8vIDcuMiBXaGl0ZSBTcGFjZVxuXG4gICAgZnVuY3Rpb24gaXNXaGl0ZVNwYWNlKGNoKSB7XG4gICAgICAgIHJldHVybiAoY2ggPT09IDB4MjApIHx8IChjaCA9PT0gMHgwOSkgfHwgKGNoID09PSAweDBCKSB8fCAoY2ggPT09IDB4MEMpIHx8IChjaCA9PT0gMHhBMCkgfHxcbiAgICAgICAgICAgIChjaCA+PSAweDE2ODAgJiYgWzB4MTY4MCwgMHgxODBFLCAweDIwMDAsIDB4MjAwMSwgMHgyMDAyLCAweDIwMDMsIDB4MjAwNCwgMHgyMDA1LCAweDIwMDYsIDB4MjAwNywgMHgyMDA4LCAweDIwMDksIDB4MjAwQSwgMHgyMDJGLCAweDIwNUYsIDB4MzAwMCwgMHhGRUZGXS5pbmRleE9mKGNoKSA+PSAwKTtcbiAgICB9XG5cbiAgICAvLyA3LjMgTGluZSBUZXJtaW5hdG9yc1xuXG4gICAgZnVuY3Rpb24gaXNMaW5lVGVybWluYXRvcihjaCkge1xuICAgICAgICByZXR1cm4gKGNoID09PSAweDBBKSB8fCAoY2ggPT09IDB4MEQpIHx8IChjaCA9PT0gMHgyMDI4KSB8fCAoY2ggPT09IDB4MjAyOSk7XG4gICAgfVxuXG4gICAgLy8gNy42IElkZW50aWZpZXIgTmFtZXMgYW5kIElkZW50aWZpZXJzXG5cbiAgICBmdW5jdGlvbiBpc0lkZW50aWZpZXJTdGFydChjaCkge1xuICAgICAgICByZXR1cm4gKGNoID09PSAweDI0KSB8fCAoY2ggPT09IDB4NUYpIHx8ICAvLyAkIChkb2xsYXIpIGFuZCBfICh1bmRlcnNjb3JlKVxuICAgICAgICAgICAgKGNoID49IDB4NDEgJiYgY2ggPD0gMHg1QSkgfHwgICAgICAgICAvLyBBLi5aXG4gICAgICAgICAgICAoY2ggPj0gMHg2MSAmJiBjaCA8PSAweDdBKSB8fCAgICAgICAgIC8vIGEuLnpcbiAgICAgICAgICAgIChjaCA9PT0gMHg1QykgfHwgICAgICAgICAgICAgICAgICAgICAgLy8gXFwgKGJhY2tzbGFzaClcbiAgICAgICAgICAgICgoY2ggPj0gMHg4MCkgJiYgUmVnZXguTm9uQXNjaWlJZGVudGlmaWVyU3RhcnQudGVzdChTdHJpbmcuZnJvbUNoYXJDb2RlKGNoKSkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzSWRlbnRpZmllclBhcnQoY2gpIHtcbiAgICAgICAgcmV0dXJuIChjaCA9PT0gMHgyNCkgfHwgKGNoID09PSAweDVGKSB8fCAgLy8gJCAoZG9sbGFyKSBhbmQgXyAodW5kZXJzY29yZSlcbiAgICAgICAgICAgIChjaCA+PSAweDQxICYmIGNoIDw9IDB4NUEpIHx8ICAgICAgICAgLy8gQS4uWlxuICAgICAgICAgICAgKGNoID49IDB4NjEgJiYgY2ggPD0gMHg3QSkgfHwgICAgICAgICAvLyBhLi56XG4gICAgICAgICAgICAoY2ggPj0gMHgzMCAmJiBjaCA8PSAweDM5KSB8fCAgICAgICAgIC8vIDAuLjlcbiAgICAgICAgICAgIChjaCA9PT0gMHg1QykgfHwgICAgICAgICAgICAgICAgICAgICAgLy8gXFwgKGJhY2tzbGFzaClcbiAgICAgICAgICAgICgoY2ggPj0gMHg4MCkgJiYgUmVnZXguTm9uQXNjaWlJZGVudGlmaWVyUGFydC50ZXN0KFN0cmluZy5mcm9tQ2hhckNvZGUoY2gpKSk7XG4gICAgfVxuXG4gICAgLy8gNy42LjEuMiBGdXR1cmUgUmVzZXJ2ZWQgV29yZHNcblxuICAgIGZ1bmN0aW9uIGlzRnV0dXJlUmVzZXJ2ZWRXb3JkKGlkKSB7XG4gICAgICAgIHN3aXRjaCAoaWQpIHtcbiAgICAgICAgY2FzZSAnZW51bSc6XG4gICAgICAgIGNhc2UgJ2V4cG9ydCc6XG4gICAgICAgIGNhc2UgJ2ltcG9ydCc6XG4gICAgICAgIGNhc2UgJ3N1cGVyJzpcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gMTEuNi4yLjIgRnV0dXJlIFJlc2VydmVkIFdvcmRzXG5cbiAgICBmdW5jdGlvbiBpc1N0cmljdE1vZGVSZXNlcnZlZFdvcmQoaWQpIHtcbiAgICAgICAgc3dpdGNoIChpZCkge1xuICAgICAgICBjYXNlICdpbXBsZW1lbnRzJzpcbiAgICAgICAgY2FzZSAnaW50ZXJmYWNlJzpcbiAgICAgICAgY2FzZSAncGFja2FnZSc6XG4gICAgICAgIGNhc2UgJ3ByaXZhdGUnOlxuICAgICAgICBjYXNlICdwcm90ZWN0ZWQnOlxuICAgICAgICBjYXNlICdwdWJsaWMnOlxuICAgICAgICBjYXNlICdzdGF0aWMnOlxuICAgICAgICBjYXNlICd5aWVsZCc6XG4gICAgICAgIGNhc2UgJ2xldCc6XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzUmVzdHJpY3RlZFdvcmQoaWQpIHtcbiAgICAgICAgcmV0dXJuIGlkID09PSAnZXZhbCcgfHwgaWQgPT09ICdhcmd1bWVudHMnO1xuICAgIH1cblxuICAgIC8vIDcuNi4xLjEgS2V5d29yZHNcblxuICAgIGZ1bmN0aW9uIGlzS2V5d29yZChpZCkge1xuXG4gICAgICAgIC8vICdjb25zdCcgaXMgc3BlY2lhbGl6ZWQgYXMgS2V5d29yZCBpbiBWOC5cbiAgICAgICAgLy8gJ3lpZWxkJyBhbmQgJ2xldCcgYXJlIGZvciBjb21wYXRpYmlsaXR5IHdpdGggU3BpZGVyTW9ua2V5IGFuZCBFUy5uZXh0LlxuICAgICAgICAvLyBTb21lIG90aGVycyBhcmUgZnJvbSBmdXR1cmUgcmVzZXJ2ZWQgd29yZHMuXG5cbiAgICAgICAgc3dpdGNoIChpZC5sZW5ndGgpIHtcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgcmV0dXJuIChpZCA9PT0gJ2lmJykgfHwgKGlkID09PSAnaW4nKSB8fCAoaWQgPT09ICdkbycpO1xuICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICByZXR1cm4gKGlkID09PSAndmFyJykgfHwgKGlkID09PSAnZm9yJykgfHwgKGlkID09PSAnbmV3JykgfHxcbiAgICAgICAgICAgICAgICAoaWQgPT09ICd0cnknKSB8fCAoaWQgPT09ICdsZXQnKTtcbiAgICAgICAgY2FzZSA0OlxuICAgICAgICAgICAgcmV0dXJuIChpZCA9PT0gJ3RoaXMnKSB8fCAoaWQgPT09ICdlbHNlJykgfHwgKGlkID09PSAnY2FzZScpIHx8XG4gICAgICAgICAgICAgICAgKGlkID09PSAndm9pZCcpIHx8IChpZCA9PT0gJ3dpdGgnKSB8fCAoaWQgPT09ICdlbnVtJyk7XG4gICAgICAgIGNhc2UgNTpcbiAgICAgICAgICAgIHJldHVybiAoaWQgPT09ICd3aGlsZScpIHx8IChpZCA9PT0gJ2JyZWFrJykgfHwgKGlkID09PSAnY2F0Y2gnKSB8fFxuICAgICAgICAgICAgICAgIChpZCA9PT0gJ3Rocm93JykgfHwgKGlkID09PSAnY29uc3QnKSB8fCAoaWQgPT09ICd5aWVsZCcpIHx8XG4gICAgICAgICAgICAgICAgKGlkID09PSAnY2xhc3MnKSB8fCAoaWQgPT09ICdzdXBlcicpO1xuICAgICAgICBjYXNlIDY6XG4gICAgICAgICAgICByZXR1cm4gKGlkID09PSAncmV0dXJuJykgfHwgKGlkID09PSAndHlwZW9mJykgfHwgKGlkID09PSAnZGVsZXRlJykgfHxcbiAgICAgICAgICAgICAgICAoaWQgPT09ICdzd2l0Y2gnKSB8fCAoaWQgPT09ICdleHBvcnQnKSB8fCAoaWQgPT09ICdpbXBvcnQnKTtcbiAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgcmV0dXJuIChpZCA9PT0gJ2RlZmF1bHQnKSB8fCAoaWQgPT09ICdmaW5hbGx5JykgfHwgKGlkID09PSAnZXh0ZW5kcycpO1xuICAgICAgICBjYXNlIDg6XG4gICAgICAgICAgICByZXR1cm4gKGlkID09PSAnZnVuY3Rpb24nKSB8fCAoaWQgPT09ICdjb250aW51ZScpIHx8IChpZCA9PT0gJ2RlYnVnZ2VyJyk7XG4gICAgICAgIGNhc2UgMTA6XG4gICAgICAgICAgICByZXR1cm4gKGlkID09PSAnaW5zdGFuY2VvZicpO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gNy40IENvbW1lbnRzXG5cbiAgICBmdW5jdGlvbiBhZGRDb21tZW50KHR5cGUsIHZhbHVlLCBzdGFydCwgZW5kLCBsb2MpIHtcbiAgICAgICAgdmFyIGNvbW1lbnQ7XG5cbiAgICAgICAgYXNzZXJ0KHR5cGVvZiBzdGFydCA9PT0gJ251bWJlcicsICdDb21tZW50IG11c3QgaGF2ZSB2YWxpZCBwb3NpdGlvbicpO1xuXG4gICAgICAgIHN0YXRlLmxhc3RDb21tZW50U3RhcnQgPSBzdGFydDtcblxuICAgICAgICBjb21tZW50ID0ge1xuICAgICAgICAgICAgdHlwZTogdHlwZSxcbiAgICAgICAgICAgIHZhbHVlOiB2YWx1ZVxuICAgICAgICB9O1xuICAgICAgICBpZiAoZXh0cmEucmFuZ2UpIHtcbiAgICAgICAgICAgIGNvbW1lbnQucmFuZ2UgPSBbc3RhcnQsIGVuZF07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV4dHJhLmxvYykge1xuICAgICAgICAgICAgY29tbWVudC5sb2MgPSBsb2M7XG4gICAgICAgIH1cbiAgICAgICAgZXh0cmEuY29tbWVudHMucHVzaChjb21tZW50KTtcbiAgICAgICAgaWYgKGV4dHJhLmF0dGFjaENvbW1lbnQpIHtcbiAgICAgICAgICAgIGV4dHJhLmxlYWRpbmdDb21tZW50cy5wdXNoKGNvbW1lbnQpO1xuICAgICAgICAgICAgZXh0cmEudHJhaWxpbmdDb21tZW50cy5wdXNoKGNvbW1lbnQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2tpcFNpbmdsZUxpbmVDb21tZW50KG9mZnNldCkge1xuICAgICAgICB2YXIgc3RhcnQsIGxvYywgY2gsIGNvbW1lbnQ7XG5cbiAgICAgICAgc3RhcnQgPSBpbmRleCAtIG9mZnNldDtcbiAgICAgICAgbG9jID0ge1xuICAgICAgICAgICAgc3RhcnQ6IHtcbiAgICAgICAgICAgICAgICBsaW5lOiBsaW5lTnVtYmVyLFxuICAgICAgICAgICAgICAgIGNvbHVtbjogaW5kZXggLSBsaW5lU3RhcnQgLSBvZmZzZXRcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICB3aGlsZSAoaW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICAgIGNoID0gc291cmNlLmNoYXJDb2RlQXQoaW5kZXgpO1xuICAgICAgICAgICAgKytpbmRleDtcbiAgICAgICAgICAgIGlmIChpc0xpbmVUZXJtaW5hdG9yKGNoKSkge1xuICAgICAgICAgICAgICAgIGhhc0xpbmVUZXJtaW5hdG9yID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBpZiAoZXh0cmEuY29tbWVudHMpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IHNvdXJjZS5zbGljZShzdGFydCArIG9mZnNldCwgaW5kZXggLSAxKTtcbiAgICAgICAgICAgICAgICAgICAgbG9jLmVuZCA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpbmU6IGxpbmVOdW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2x1bW46IGluZGV4IC0gbGluZVN0YXJ0IC0gMVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICBhZGRDb21tZW50KCdMaW5lJywgY29tbWVudCwgc3RhcnQsIGluZGV4IC0gMSwgbG9jKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGNoID09PSAxMyAmJiBzb3VyY2UuY2hhckNvZGVBdChpbmRleCkgPT09IDEwKSB7XG4gICAgICAgICAgICAgICAgICAgICsraW5kZXg7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICsrbGluZU51bWJlcjtcbiAgICAgICAgICAgICAgICBsaW5lU3RhcnQgPSBpbmRleDtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXh0cmEuY29tbWVudHMpIHtcbiAgICAgICAgICAgIGNvbW1lbnQgPSBzb3VyY2Uuc2xpY2Uoc3RhcnQgKyBvZmZzZXQsIGluZGV4KTtcbiAgICAgICAgICAgIGxvYy5lbmQgPSB7XG4gICAgICAgICAgICAgICAgbGluZTogbGluZU51bWJlcixcbiAgICAgICAgICAgICAgICBjb2x1bW46IGluZGV4IC0gbGluZVN0YXJ0XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgYWRkQ29tbWVudCgnTGluZScsIGNvbW1lbnQsIHN0YXJ0LCBpbmRleCwgbG9jKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNraXBNdWx0aUxpbmVDb21tZW50KCkge1xuICAgICAgICB2YXIgc3RhcnQsIGxvYywgY2gsIGNvbW1lbnQ7XG5cbiAgICAgICAgaWYgKGV4dHJhLmNvbW1lbnRzKSB7XG4gICAgICAgICAgICBzdGFydCA9IGluZGV4IC0gMjtcbiAgICAgICAgICAgIGxvYyA9IHtcbiAgICAgICAgICAgICAgICBzdGFydDoge1xuICAgICAgICAgICAgICAgICAgICBsaW5lOiBsaW5lTnVtYmVyLFxuICAgICAgICAgICAgICAgICAgICBjb2x1bW46IGluZGV4IC0gbGluZVN0YXJ0IC0gMlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICB3aGlsZSAoaW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICAgIGNoID0gc291cmNlLmNoYXJDb2RlQXQoaW5kZXgpO1xuICAgICAgICAgICAgaWYgKGlzTGluZVRlcm1pbmF0b3IoY2gpKSB7XG4gICAgICAgICAgICAgICAgaWYgKGNoID09PSAweDBEICYmIHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4ICsgMSkgPT09IDB4MEEpIHtcbiAgICAgICAgICAgICAgICAgICAgKytpbmRleDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaGFzTGluZVRlcm1pbmF0b3IgPSB0cnVlO1xuICAgICAgICAgICAgICAgICsrbGluZU51bWJlcjtcbiAgICAgICAgICAgICAgICArK2luZGV4O1xuICAgICAgICAgICAgICAgIGxpbmVTdGFydCA9IGluZGV4O1xuICAgICAgICAgICAgfSBlbHNlIGlmIChjaCA9PT0gMHgyQSkge1xuICAgICAgICAgICAgICAgIC8vIEJsb2NrIGNvbW1lbnQgZW5kcyB3aXRoICcqLycuXG4gICAgICAgICAgICAgICAgaWYgKHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4ICsgMSkgPT09IDB4MkYpIHtcbiAgICAgICAgICAgICAgICAgICAgKytpbmRleDtcbiAgICAgICAgICAgICAgICAgICAgKytpbmRleDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGV4dHJhLmNvbW1lbnRzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb21tZW50ID0gc291cmNlLnNsaWNlKHN0YXJ0ICsgMiwgaW5kZXggLSAyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvYy5lbmQgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZTogbGluZU51bWJlcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2x1bW46IGluZGV4IC0gbGluZVN0YXJ0XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ29tbWVudCgnQmxvY2snLCBjb21tZW50LCBzdGFydCwgaW5kZXgsIGxvYyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICArK2luZGV4O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICArK2luZGV4O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmFuIG9mZiB0aGUgZW5kIG9mIHRoZSBmaWxlIC0gdGhlIHdob2xlIHRoaW5nIGlzIGEgY29tbWVudFxuICAgICAgICBpZiAoZXh0cmEuY29tbWVudHMpIHtcbiAgICAgICAgICAgIGxvYy5lbmQgPSB7XG4gICAgICAgICAgICAgICAgbGluZTogbGluZU51bWJlcixcbiAgICAgICAgICAgICAgICBjb2x1bW46IGluZGV4IC0gbGluZVN0YXJ0XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29tbWVudCA9IHNvdXJjZS5zbGljZShzdGFydCArIDIsIGluZGV4KTtcbiAgICAgICAgICAgIGFkZENvbW1lbnQoJ0Jsb2NrJywgY29tbWVudCwgc3RhcnQsIGluZGV4LCBsb2MpO1xuICAgICAgICB9XG4gICAgICAgIHRvbGVyYXRlVW5leHBlY3RlZFRva2VuKCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2tpcENvbW1lbnQoKSB7XG4gICAgICAgIHZhciBjaCwgc3RhcnQ7XG4gICAgICAgIGhhc0xpbmVUZXJtaW5hdG9yID0gZmFsc2U7XG5cbiAgICAgICAgc3RhcnQgPSAoaW5kZXggPT09IDApO1xuICAgICAgICB3aGlsZSAoaW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICAgIGNoID0gc291cmNlLmNoYXJDb2RlQXQoaW5kZXgpO1xuXG4gICAgICAgICAgICBpZiAoaXNXaGl0ZVNwYWNlKGNoKSkge1xuICAgICAgICAgICAgICAgICsraW5kZXg7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGlzTGluZVRlcm1pbmF0b3IoY2gpKSB7XG4gICAgICAgICAgICAgICAgaGFzTGluZVRlcm1pbmF0b3IgPSB0cnVlO1xuICAgICAgICAgICAgICAgICsraW5kZXg7XG4gICAgICAgICAgICAgICAgaWYgKGNoID09PSAweDBEICYmIHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KSA9PT0gMHgwQSkge1xuICAgICAgICAgICAgICAgICAgICArK2luZGV4O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICArK2xpbmVOdW1iZXI7XG4gICAgICAgICAgICAgICAgbGluZVN0YXJ0ID0gaW5kZXg7XG4gICAgICAgICAgICAgICAgc3RhcnQgPSB0cnVlO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChjaCA9PT0gMHgyRikgeyAvLyBVKzAwMkYgaXMgJy8nXG4gICAgICAgICAgICAgICAgY2ggPSBzb3VyY2UuY2hhckNvZGVBdChpbmRleCArIDEpO1xuICAgICAgICAgICAgICAgIGlmIChjaCA9PT0gMHgyRikge1xuICAgICAgICAgICAgICAgICAgICArK2luZGV4O1xuICAgICAgICAgICAgICAgICAgICArK2luZGV4O1xuICAgICAgICAgICAgICAgICAgICBza2lwU2luZ2xlTGluZUNvbW1lbnQoMik7XG4gICAgICAgICAgICAgICAgICAgIHN0YXJ0ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNoID09PSAweDJBKSB7ICAvLyBVKzAwMkEgaXMgJyonXG4gICAgICAgICAgICAgICAgICAgICsraW5kZXg7XG4gICAgICAgICAgICAgICAgICAgICsraW5kZXg7XG4gICAgICAgICAgICAgICAgICAgIHNraXBNdWx0aUxpbmVDb21tZW50KCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChzdGFydCAmJiBjaCA9PT0gMHgyRCkgeyAvLyBVKzAwMkQgaXMgJy0nXG4gICAgICAgICAgICAgICAgLy8gVSswMDNFIGlzICc+J1xuICAgICAgICAgICAgICAgIGlmICgoc291cmNlLmNoYXJDb2RlQXQoaW5kZXggKyAxKSA9PT0gMHgyRCkgJiYgKHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4ICsgMikgPT09IDB4M0UpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vICctLT4nIGlzIGEgc2luZ2xlLWxpbmUgY29tbWVudFxuICAgICAgICAgICAgICAgICAgICBpbmRleCArPSAzO1xuICAgICAgICAgICAgICAgICAgICBza2lwU2luZ2xlTGluZUNvbW1lbnQoMyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChjaCA9PT0gMHgzQykgeyAvLyBVKzAwM0MgaXMgJzwnXG4gICAgICAgICAgICAgICAgaWYgKHNvdXJjZS5zbGljZShpbmRleCArIDEsIGluZGV4ICsgNCkgPT09ICchLS0nKSB7XG4gICAgICAgICAgICAgICAgICAgICsraW5kZXg7IC8vIGA8YFxuICAgICAgICAgICAgICAgICAgICArK2luZGV4OyAvLyBgIWBcbiAgICAgICAgICAgICAgICAgICAgKytpbmRleDsgLy8gYC1gXG4gICAgICAgICAgICAgICAgICAgICsraW5kZXg7IC8vIGAtYFxuICAgICAgICAgICAgICAgICAgICBza2lwU2luZ2xlTGluZUNvbW1lbnQoNCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNjYW5IZXhFc2NhcGUocHJlZml4KSB7XG4gICAgICAgIHZhciBpLCBsZW4sIGNoLCBjb2RlID0gMDtcblxuICAgICAgICBsZW4gPSAocHJlZml4ID09PSAndScpID8gNCA6IDI7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW47ICsraSkge1xuICAgICAgICAgICAgaWYgKGluZGV4IDwgbGVuZ3RoICYmIGlzSGV4RGlnaXQoc291cmNlW2luZGV4XSkpIHtcbiAgICAgICAgICAgICAgICBjaCA9IHNvdXJjZVtpbmRleCsrXTtcbiAgICAgICAgICAgICAgICBjb2RlID0gY29kZSAqIDE2ICsgJzAxMjM0NTY3ODlhYmNkZWYnLmluZGV4T2YoY2gudG9Mb3dlckNhc2UoKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiAnJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZShjb2RlKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzY2FuVW5pY29kZUNvZGVQb2ludEVzY2FwZSgpIHtcbiAgICAgICAgdmFyIGNoLCBjb2RlLCBjdTEsIGN1MjtcblxuICAgICAgICBjaCA9IHNvdXJjZVtpbmRleF07XG4gICAgICAgIGNvZGUgPSAwO1xuXG4gICAgICAgIC8vIEF0IGxlYXN0LCBvbmUgaGV4IGRpZ2l0IGlzIHJlcXVpcmVkLlxuICAgICAgICBpZiAoY2ggPT09ICd9Jykge1xuICAgICAgICAgICAgdGhyb3dVbmV4cGVjdGVkVG9rZW4oKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHdoaWxlIChpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgICAgY2ggPSBzb3VyY2VbaW5kZXgrK107XG4gICAgICAgICAgICBpZiAoIWlzSGV4RGlnaXQoY2gpKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb2RlID0gY29kZSAqIDE2ICsgJzAxMjM0NTY3ODlhYmNkZWYnLmluZGV4T2YoY2gudG9Mb3dlckNhc2UoKSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29kZSA+IDB4MTBGRkZGIHx8IGNoICE9PSAnfScpIHtcbiAgICAgICAgICAgIHRocm93VW5leHBlY3RlZFRva2VuKCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBVVEYtMTYgRW5jb2RpbmdcbiAgICAgICAgaWYgKGNvZGUgPD0gMHhGRkZGKSB7XG4gICAgICAgICAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZShjb2RlKTtcbiAgICAgICAgfVxuICAgICAgICBjdTEgPSAoKGNvZGUgLSAweDEwMDAwKSA+PiAxMCkgKyAweEQ4MDA7XG4gICAgICAgIGN1MiA9ICgoY29kZSAtIDB4MTAwMDApICYgMTAyMykgKyAweERDMDA7XG4gICAgICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKGN1MSwgY3UyKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRFc2NhcGVkSWRlbnRpZmllcigpIHtcbiAgICAgICAgdmFyIGNoLCBpZDtcblxuICAgICAgICBjaCA9IHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KyspO1xuICAgICAgICBpZCA9IFN0cmluZy5mcm9tQ2hhckNvZGUoY2gpO1xuXG4gICAgICAgIC8vICdcXHUnIChVKzAwNUMsIFUrMDA3NSkgZGVub3RlcyBhbiBlc2NhcGVkIGNoYXJhY3Rlci5cbiAgICAgICAgaWYgKGNoID09PSAweDVDKSB7XG4gICAgICAgICAgICBpZiAoc291cmNlLmNoYXJDb2RlQXQoaW5kZXgpICE9PSAweDc1KSB7XG4gICAgICAgICAgICAgICAgdGhyb3dVbmV4cGVjdGVkVG9rZW4oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgICsraW5kZXg7XG4gICAgICAgICAgICBjaCA9IHNjYW5IZXhFc2NhcGUoJ3UnKTtcbiAgICAgICAgICAgIGlmICghY2ggfHwgY2ggPT09ICdcXFxcJyB8fCAhaXNJZGVudGlmaWVyU3RhcnQoY2guY2hhckNvZGVBdCgwKSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvd1VuZXhwZWN0ZWRUb2tlbigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWQgPSBjaDtcbiAgICAgICAgfVxuXG4gICAgICAgIHdoaWxlIChpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgICAgY2ggPSBzb3VyY2UuY2hhckNvZGVBdChpbmRleCk7XG4gICAgICAgICAgICBpZiAoIWlzSWRlbnRpZmllclBhcnQoY2gpKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICArK2luZGV4O1xuICAgICAgICAgICAgaWQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShjaCk7XG5cbiAgICAgICAgICAgIC8vICdcXHUnIChVKzAwNUMsIFUrMDA3NSkgZGVub3RlcyBhbiBlc2NhcGVkIGNoYXJhY3Rlci5cbiAgICAgICAgICAgIGlmIChjaCA9PT0gMHg1Qykge1xuICAgICAgICAgICAgICAgIGlkID0gaWQuc3Vic3RyKDAsIGlkLmxlbmd0aCAtIDEpO1xuICAgICAgICAgICAgICAgIGlmIChzb3VyY2UuY2hhckNvZGVBdChpbmRleCkgIT09IDB4NzUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3dVbmV4cGVjdGVkVG9rZW4oKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgKytpbmRleDtcbiAgICAgICAgICAgICAgICBjaCA9IHNjYW5IZXhFc2NhcGUoJ3UnKTtcbiAgICAgICAgICAgICAgICBpZiAoIWNoIHx8IGNoID09PSAnXFxcXCcgfHwgIWlzSWRlbnRpZmllclBhcnQoY2guY2hhckNvZGVBdCgwKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3dVbmV4cGVjdGVkVG9rZW4oKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWQgKz0gY2g7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gaWQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0SWRlbnRpZmllcigpIHtcbiAgICAgICAgdmFyIHN0YXJ0LCBjaDtcblxuICAgICAgICBzdGFydCA9IGluZGV4Kys7XG4gICAgICAgIHdoaWxlIChpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgICAgY2ggPSBzb3VyY2UuY2hhckNvZGVBdChpbmRleCk7XG4gICAgICAgICAgICBpZiAoY2ggPT09IDB4NUMpIHtcbiAgICAgICAgICAgICAgICAvLyBCbGFja3NsYXNoIChVKzAwNUMpIG1hcmtzIFVuaWNvZGUgZXNjYXBlIHNlcXVlbmNlLlxuICAgICAgICAgICAgICAgIGluZGV4ID0gc3RhcnQ7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGdldEVzY2FwZWRJZGVudGlmaWVyKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNJZGVudGlmaWVyUGFydChjaCkpIHtcbiAgICAgICAgICAgICAgICArK2luZGV4O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBzb3VyY2Uuc2xpY2Uoc3RhcnQsIGluZGV4KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzY2FuSWRlbnRpZmllcigpIHtcbiAgICAgICAgdmFyIHN0YXJ0LCBpZCwgdHlwZTtcblxuICAgICAgICBzdGFydCA9IGluZGV4O1xuXG4gICAgICAgIC8vIEJhY2tzbGFzaCAoVSswMDVDKSBzdGFydHMgYW4gZXNjYXBlZCBjaGFyYWN0ZXIuXG4gICAgICAgIGlkID0gKHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KSA9PT0gMHg1QykgPyBnZXRFc2NhcGVkSWRlbnRpZmllcigpIDogZ2V0SWRlbnRpZmllcigpO1xuXG4gICAgICAgIC8vIFRoZXJlIGlzIG5vIGtleXdvcmQgb3IgbGl0ZXJhbCB3aXRoIG9ubHkgb25lIGNoYXJhY3Rlci5cbiAgICAgICAgLy8gVGh1cywgaXQgbXVzdCBiZSBhbiBpZGVudGlmaWVyLlxuICAgICAgICBpZiAoaWQubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICB0eXBlID0gVG9rZW4uSWRlbnRpZmllcjtcbiAgICAgICAgfSBlbHNlIGlmIChpc0tleXdvcmQoaWQpKSB7XG4gICAgICAgICAgICB0eXBlID0gVG9rZW4uS2V5d29yZDtcbiAgICAgICAgfSBlbHNlIGlmIChpZCA9PT0gJ251bGwnKSB7XG4gICAgICAgICAgICB0eXBlID0gVG9rZW4uTnVsbExpdGVyYWw7XG4gICAgICAgIH0gZWxzZSBpZiAoaWQgPT09ICd0cnVlJyB8fCBpZCA9PT0gJ2ZhbHNlJykge1xuICAgICAgICAgICAgdHlwZSA9IFRva2VuLkJvb2xlYW5MaXRlcmFsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdHlwZSA9IFRva2VuLklkZW50aWZpZXI7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogdHlwZSxcbiAgICAgICAgICAgIHZhbHVlOiBpZCxcbiAgICAgICAgICAgIGxpbmVOdW1iZXI6IGxpbmVOdW1iZXIsXG4gICAgICAgICAgICBsaW5lU3RhcnQ6IGxpbmVTdGFydCxcbiAgICAgICAgICAgIHN0YXJ0OiBzdGFydCxcbiAgICAgICAgICAgIGVuZDogaW5kZXhcbiAgICAgICAgfTtcbiAgICB9XG5cblxuICAgIC8vIDcuNyBQdW5jdHVhdG9yc1xuXG4gICAgZnVuY3Rpb24gc2NhblB1bmN0dWF0b3IoKSB7XG4gICAgICAgIHZhciB0b2tlbiwgc3RyO1xuXG4gICAgICAgIHRva2VuID0ge1xuICAgICAgICAgICAgdHlwZTogVG9rZW4uUHVuY3R1YXRvcixcbiAgICAgICAgICAgIHZhbHVlOiAnJyxcbiAgICAgICAgICAgIGxpbmVOdW1iZXI6IGxpbmVOdW1iZXIsXG4gICAgICAgICAgICBsaW5lU3RhcnQ6IGxpbmVTdGFydCxcbiAgICAgICAgICAgIHN0YXJ0OiBpbmRleCxcbiAgICAgICAgICAgIGVuZDogaW5kZXhcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBDaGVjayBmb3IgbW9zdCBjb21tb24gc2luZ2xlLWNoYXJhY3RlciBwdW5jdHVhdG9ycy5cbiAgICAgICAgc3RyID0gc291cmNlW2luZGV4XTtcbiAgICAgICAgc3dpdGNoIChzdHIpIHtcblxuICAgICAgICBjYXNlICcoJzpcbiAgICAgICAgICAgIGlmIChleHRyYS50b2tlbml6ZSkge1xuICAgICAgICAgICAgICAgIGV4dHJhLm9wZW5QYXJlblRva2VuID0gZXh0cmEudG9rZW5zLmxlbmd0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgICsraW5kZXg7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlICd7JzpcbiAgICAgICAgICAgIGlmIChleHRyYS50b2tlbml6ZSkge1xuICAgICAgICAgICAgICAgIGV4dHJhLm9wZW5DdXJseVRva2VuID0gZXh0cmEudG9rZW5zLmxlbmd0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN0YXRlLmN1cmx5U3RhY2sucHVzaCgneycpO1xuICAgICAgICAgICAgKytpbmRleDtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgJy4nOlxuICAgICAgICAgICAgKytpbmRleDtcbiAgICAgICAgICAgIGlmIChzb3VyY2VbaW5kZXhdID09PSAnLicgJiYgc291cmNlW2luZGV4ICsgMV0gPT09ICcuJykge1xuICAgICAgICAgICAgICAgIC8vIFNwcmVhZCBvcGVyYXRvcjogLi4uXG4gICAgICAgICAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgICAgICAgICAgICBzdHIgPSAnLi4uJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgJ30nOlxuICAgICAgICAgICAgKytpbmRleDtcbiAgICAgICAgICAgIHN0YXRlLmN1cmx5U3RhY2sucG9wKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnKSc6XG4gICAgICAgIGNhc2UgJzsnOlxuICAgICAgICBjYXNlICcsJzpcbiAgICAgICAgY2FzZSAnWyc6XG4gICAgICAgIGNhc2UgJ10nOlxuICAgICAgICBjYXNlICc6JzpcbiAgICAgICAgY2FzZSAnPyc6XG4gICAgICAgIGNhc2UgJ34nOlxuICAgICAgICAgICAgKytpbmRleDtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAvLyA0LWNoYXJhY3RlciBwdW5jdHVhdG9yLlxuICAgICAgICAgICAgc3RyID0gc291cmNlLnN1YnN0cihpbmRleCwgNCk7XG4gICAgICAgICAgICBpZiAoc3RyID09PSAnPj4+PScpIHtcbiAgICAgICAgICAgICAgICBpbmRleCArPSA0O1xuICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIC8vIDMtY2hhcmFjdGVyIHB1bmN0dWF0b3JzLlxuICAgICAgICAgICAgICAgIHN0ciA9IHN0ci5zdWJzdHIoMCwgMyk7XG4gICAgICAgICAgICAgICAgaWYgKHN0ciA9PT0gJz09PScgfHwgc3RyID09PSAnIT09JyB8fCBzdHIgPT09ICc+Pj4nIHx8XG4gICAgICAgICAgICAgICAgICAgIHN0ciA9PT0gJzw8PScgfHwgc3RyID09PSAnPj49Jykge1xuICAgICAgICAgICAgICAgICAgICBpbmRleCArPSAzO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gMi1jaGFyYWN0ZXIgcHVuY3R1YXRvcnMuXG4gICAgICAgICAgICAgICAgICAgIHN0ciA9IHN0ci5zdWJzdHIoMCwgMik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdHIgPT09ICcmJicgfHwgc3RyID09PSAnfHwnIHx8IHN0ciA9PT0gJz09JyB8fCBzdHIgPT09ICchPScgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0ciA9PT0gJys9JyB8fCBzdHIgPT09ICctPScgfHwgc3RyID09PSAnKj0nIHx8IHN0ciA9PT0gJy89JyB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgc3RyID09PSAnKysnIHx8IHN0ciA9PT0gJy0tJyB8fCBzdHIgPT09ICc8PCcgfHwgc3RyID09PSAnPj4nIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHIgPT09ICcmPScgfHwgc3RyID09PSAnfD0nIHx8IHN0ciA9PT0gJ149JyB8fCBzdHIgPT09ICclPScgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0ciA9PT0gJzw9JyB8fCBzdHIgPT09ICc+PScgfHwgc3RyID09PSAnPT4nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbmRleCArPSAyO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyAxLWNoYXJhY3RlciBwdW5jdHVhdG9ycy5cbiAgICAgICAgICAgICAgICAgICAgICAgIHN0ciA9IHNvdXJjZVtpbmRleF07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoJzw+PSErLSolJnxeLycuaW5kZXhPZihzdHIpID49IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICArK2luZGV4O1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGluZGV4ID09PSB0b2tlbi5zdGFydCkge1xuICAgICAgICAgICAgdGhyb3dVbmV4cGVjdGVkVG9rZW4oKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRva2VuLmVuZCA9IGluZGV4O1xuICAgICAgICB0b2tlbi52YWx1ZSA9IHN0cjtcbiAgICAgICAgcmV0dXJuIHRva2VuO1xuICAgIH1cblxuICAgIC8vIDcuOC4zIE51bWVyaWMgTGl0ZXJhbHNcblxuICAgIGZ1bmN0aW9uIHNjYW5IZXhMaXRlcmFsKHN0YXJ0KSB7XG4gICAgICAgIHZhciBudW1iZXIgPSAnJztcblxuICAgICAgICB3aGlsZSAoaW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICAgIGlmICghaXNIZXhEaWdpdChzb3VyY2VbaW5kZXhdKSkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbnVtYmVyICs9IHNvdXJjZVtpbmRleCsrXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChudW1iZXIubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvd1VuZXhwZWN0ZWRUb2tlbigpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzSWRlbnRpZmllclN0YXJ0KHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KSkpIHtcbiAgICAgICAgICAgIHRocm93VW5leHBlY3RlZFRva2VuKCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogVG9rZW4uTnVtZXJpY0xpdGVyYWwsXG4gICAgICAgICAgICB2YWx1ZTogcGFyc2VJbnQoJzB4JyArIG51bWJlciwgMTYpLFxuICAgICAgICAgICAgbGluZU51bWJlcjogbGluZU51bWJlcixcbiAgICAgICAgICAgIGxpbmVTdGFydDogbGluZVN0YXJ0LFxuICAgICAgICAgICAgc3RhcnQ6IHN0YXJ0LFxuICAgICAgICAgICAgZW5kOiBpbmRleFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNjYW5CaW5hcnlMaXRlcmFsKHN0YXJ0KSB7XG4gICAgICAgIHZhciBjaCwgbnVtYmVyO1xuXG4gICAgICAgIG51bWJlciA9ICcnO1xuXG4gICAgICAgIHdoaWxlIChpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgICAgY2ggPSBzb3VyY2VbaW5kZXhdO1xuICAgICAgICAgICAgaWYgKGNoICE9PSAnMCcgJiYgY2ggIT09ICcxJykge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbnVtYmVyICs9IHNvdXJjZVtpbmRleCsrXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChudW1iZXIubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAvLyBvbmx5IDBiIG9yIDBCXG4gICAgICAgICAgICB0aHJvd1VuZXhwZWN0ZWRUb2tlbigpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGluZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgICBjaCA9IHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KTtcbiAgICAgICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgICAgICAgICBpZiAoaXNJZGVudGlmaWVyU3RhcnQoY2gpIHx8IGlzRGVjaW1hbERpZ2l0KGNoKSkge1xuICAgICAgICAgICAgICAgIHRocm93VW5leHBlY3RlZFRva2VuKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogVG9rZW4uTnVtZXJpY0xpdGVyYWwsXG4gICAgICAgICAgICB2YWx1ZTogcGFyc2VJbnQobnVtYmVyLCAyKSxcbiAgICAgICAgICAgIGxpbmVOdW1iZXI6IGxpbmVOdW1iZXIsXG4gICAgICAgICAgICBsaW5lU3RhcnQ6IGxpbmVTdGFydCxcbiAgICAgICAgICAgIHN0YXJ0OiBzdGFydCxcbiAgICAgICAgICAgIGVuZDogaW5kZXhcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzY2FuT2N0YWxMaXRlcmFsKHByZWZpeCwgc3RhcnQpIHtcbiAgICAgICAgdmFyIG51bWJlciwgb2N0YWw7XG5cbiAgICAgICAgaWYgKGlzT2N0YWxEaWdpdChwcmVmaXgpKSB7XG4gICAgICAgICAgICBvY3RhbCA9IHRydWU7XG4gICAgICAgICAgICBudW1iZXIgPSAnMCcgKyBzb3VyY2VbaW5kZXgrK107XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBvY3RhbCA9IGZhbHNlO1xuICAgICAgICAgICAgKytpbmRleDtcbiAgICAgICAgICAgIG51bWJlciA9ICcnO1xuICAgICAgICB9XG5cbiAgICAgICAgd2hpbGUgKGluZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAoIWlzT2N0YWxEaWdpdChzb3VyY2VbaW5kZXhdKSkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbnVtYmVyICs9IHNvdXJjZVtpbmRleCsrXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghb2N0YWwgJiYgbnVtYmVyLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgLy8gb25seSAwbyBvciAwT1xuICAgICAgICAgICAgdGhyb3dVbmV4cGVjdGVkVG9rZW4oKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc0lkZW50aWZpZXJTdGFydChzb3VyY2UuY2hhckNvZGVBdChpbmRleCkpIHx8IGlzRGVjaW1hbERpZ2l0KHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KSkpIHtcbiAgICAgICAgICAgIHRocm93VW5leHBlY3RlZFRva2VuKCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogVG9rZW4uTnVtZXJpY0xpdGVyYWwsXG4gICAgICAgICAgICB2YWx1ZTogcGFyc2VJbnQobnVtYmVyLCA4KSxcbiAgICAgICAgICAgIG9jdGFsOiBvY3RhbCxcbiAgICAgICAgICAgIGxpbmVOdW1iZXI6IGxpbmVOdW1iZXIsXG4gICAgICAgICAgICBsaW5lU3RhcnQ6IGxpbmVTdGFydCxcbiAgICAgICAgICAgIHN0YXJ0OiBzdGFydCxcbiAgICAgICAgICAgIGVuZDogaW5kZXhcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc0ltcGxpY2l0T2N0YWxMaXRlcmFsKCkge1xuICAgICAgICB2YXIgaSwgY2g7XG5cbiAgICAgICAgLy8gSW1wbGljaXQgb2N0YWwsIHVubGVzcyB0aGVyZSBpcyBhIG5vbi1vY3RhbCBkaWdpdC5cbiAgICAgICAgLy8gKEFubmV4IEIuMS4xIG9uIE51bWVyaWMgTGl0ZXJhbHMpXG4gICAgICAgIGZvciAoaSA9IGluZGV4ICsgMTsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICBjaCA9IHNvdXJjZVtpXTtcbiAgICAgICAgICAgIGlmIChjaCA9PT0gJzgnIHx8IGNoID09PSAnOScpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIWlzT2N0YWxEaWdpdChjaCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNjYW5OdW1lcmljTGl0ZXJhbCgpIHtcbiAgICAgICAgdmFyIG51bWJlciwgc3RhcnQsIGNoO1xuXG4gICAgICAgIGNoID0gc291cmNlW2luZGV4XTtcbiAgICAgICAgYXNzZXJ0KGlzRGVjaW1hbERpZ2l0KGNoLmNoYXJDb2RlQXQoMCkpIHx8IChjaCA9PT0gJy4nKSxcbiAgICAgICAgICAgICdOdW1lcmljIGxpdGVyYWwgbXVzdCBzdGFydCB3aXRoIGEgZGVjaW1hbCBkaWdpdCBvciBhIGRlY2ltYWwgcG9pbnQnKTtcblxuICAgICAgICBzdGFydCA9IGluZGV4O1xuICAgICAgICBudW1iZXIgPSAnJztcbiAgICAgICAgaWYgKGNoICE9PSAnLicpIHtcbiAgICAgICAgICAgIG51bWJlciA9IHNvdXJjZVtpbmRleCsrXTtcbiAgICAgICAgICAgIGNoID0gc291cmNlW2luZGV4XTtcblxuICAgICAgICAgICAgLy8gSGV4IG51bWJlciBzdGFydHMgd2l0aCAnMHgnLlxuICAgICAgICAgICAgLy8gT2N0YWwgbnVtYmVyIHN0YXJ0cyB3aXRoICcwJy5cbiAgICAgICAgICAgIC8vIE9jdGFsIG51bWJlciBpbiBFUzYgc3RhcnRzIHdpdGggJzBvJy5cbiAgICAgICAgICAgIC8vIEJpbmFyeSBudW1iZXIgaW4gRVM2IHN0YXJ0cyB3aXRoICcwYicuXG4gICAgICAgICAgICBpZiAobnVtYmVyID09PSAnMCcpIHtcbiAgICAgICAgICAgICAgICBpZiAoY2ggPT09ICd4JyB8fCBjaCA9PT0gJ1gnKSB7XG4gICAgICAgICAgICAgICAgICAgICsraW5kZXg7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzY2FuSGV4TGl0ZXJhbChzdGFydCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChjaCA9PT0gJ2InIHx8IGNoID09PSAnQicpIHtcbiAgICAgICAgICAgICAgICAgICAgKytpbmRleDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNjYW5CaW5hcnlMaXRlcmFsKHN0YXJ0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGNoID09PSAnbycgfHwgY2ggPT09ICdPJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2Nhbk9jdGFsTGl0ZXJhbChjaCwgc3RhcnQpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChpc09jdGFsRGlnaXQoY2gpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0ltcGxpY2l0T2N0YWxMaXRlcmFsKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzY2FuT2N0YWxMaXRlcmFsKGNoLCBzdGFydCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHdoaWxlIChpc0RlY2ltYWxEaWdpdChzb3VyY2UuY2hhckNvZGVBdChpbmRleCkpKSB7XG4gICAgICAgICAgICAgICAgbnVtYmVyICs9IHNvdXJjZVtpbmRleCsrXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNoID0gc291cmNlW2luZGV4XTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjaCA9PT0gJy4nKSB7XG4gICAgICAgICAgICBudW1iZXIgKz0gc291cmNlW2luZGV4KytdO1xuICAgICAgICAgICAgd2hpbGUgKGlzRGVjaW1hbERpZ2l0KHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KSkpIHtcbiAgICAgICAgICAgICAgICBudW1iZXIgKz0gc291cmNlW2luZGV4KytdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2ggPSBzb3VyY2VbaW5kZXhdO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNoID09PSAnZScgfHwgY2ggPT09ICdFJykge1xuICAgICAgICAgICAgbnVtYmVyICs9IHNvdXJjZVtpbmRleCsrXTtcblxuICAgICAgICAgICAgY2ggPSBzb3VyY2VbaW5kZXhdO1xuICAgICAgICAgICAgaWYgKGNoID09PSAnKycgfHwgY2ggPT09ICctJykge1xuICAgICAgICAgICAgICAgIG51bWJlciArPSBzb3VyY2VbaW5kZXgrK107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNEZWNpbWFsRGlnaXQoc291cmNlLmNoYXJDb2RlQXQoaW5kZXgpKSkge1xuICAgICAgICAgICAgICAgIHdoaWxlIChpc0RlY2ltYWxEaWdpdChzb3VyY2UuY2hhckNvZGVBdChpbmRleCkpKSB7XG4gICAgICAgICAgICAgICAgICAgIG51bWJlciArPSBzb3VyY2VbaW5kZXgrK107XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvd1VuZXhwZWN0ZWRUb2tlbigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzSWRlbnRpZmllclN0YXJ0KHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KSkpIHtcbiAgICAgICAgICAgIHRocm93VW5leHBlY3RlZFRva2VuKCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogVG9rZW4uTnVtZXJpY0xpdGVyYWwsXG4gICAgICAgICAgICB2YWx1ZTogcGFyc2VGbG9hdChudW1iZXIpLFxuICAgICAgICAgICAgbGluZU51bWJlcjogbGluZU51bWJlcixcbiAgICAgICAgICAgIGxpbmVTdGFydDogbGluZVN0YXJ0LFxuICAgICAgICAgICAgc3RhcnQ6IHN0YXJ0LFxuICAgICAgICAgICAgZW5kOiBpbmRleFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8vIDcuOC40IFN0cmluZyBMaXRlcmFsc1xuXG4gICAgZnVuY3Rpb24gc2NhblN0cmluZ0xpdGVyYWwoKSB7XG4gICAgICAgIHZhciBzdHIgPSAnJywgcXVvdGUsIHN0YXJ0LCBjaCwgdW5lc2NhcGVkLCBvY3RUb0RlYywgb2N0YWwgPSBmYWxzZTtcblxuICAgICAgICBxdW90ZSA9IHNvdXJjZVtpbmRleF07XG4gICAgICAgIGFzc2VydCgocXVvdGUgPT09ICdcXCcnIHx8IHF1b3RlID09PSAnXCInKSxcbiAgICAgICAgICAgICdTdHJpbmcgbGl0ZXJhbCBtdXN0IHN0YXJ0cyB3aXRoIGEgcXVvdGUnKTtcblxuICAgICAgICBzdGFydCA9IGluZGV4O1xuICAgICAgICArK2luZGV4O1xuXG4gICAgICAgIHdoaWxlIChpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgICAgY2ggPSBzb3VyY2VbaW5kZXgrK107XG5cbiAgICAgICAgICAgIGlmIChjaCA9PT0gcXVvdGUpIHtcbiAgICAgICAgICAgICAgICBxdW90ZSA9ICcnO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChjaCA9PT0gJ1xcXFwnKSB7XG4gICAgICAgICAgICAgICAgY2ggPSBzb3VyY2VbaW5kZXgrK107XG4gICAgICAgICAgICAgICAgaWYgKCFjaCB8fCAhaXNMaW5lVGVybWluYXRvcihjaC5jaGFyQ29kZUF0KDApKSkge1xuICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGNoKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3UnOlxuICAgICAgICAgICAgICAgICAgICBjYXNlICd4JzpcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzb3VyY2VbaW5kZXhdID09PSAneycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICArK2luZGV4O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ciArPSBzY2FuVW5pY29kZUNvZGVQb2ludEVzY2FwZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmVzY2FwZWQgPSBzY2FuSGV4RXNjYXBlKGNoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXVuZXNjYXBlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyB0aHJvd1VuZXhwZWN0ZWRUb2tlbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHIgKz0gdW5lc2NhcGVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ24nOlxuICAgICAgICAgICAgICAgICAgICAgICAgc3RyICs9ICdcXG4nO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgc3RyICs9ICdcXHInO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3QnOlxuICAgICAgICAgICAgICAgICAgICAgICAgc3RyICs9ICdcXHQnO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2InOlxuICAgICAgICAgICAgICAgICAgICAgICAgc3RyICs9ICdcXGInO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2YnOlxuICAgICAgICAgICAgICAgICAgICAgICAgc3RyICs9ICdcXGYnO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3YnOlxuICAgICAgICAgICAgICAgICAgICAgICAgc3RyICs9ICdcXHgwQic7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnOCc6XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJzknOlxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgdGhyb3dVbmV4cGVjdGVkVG9rZW4oKTtcblxuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzT2N0YWxEaWdpdChjaCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvY3RUb0RlYyA9IG9jdGFsVG9EZWNpbWFsKGNoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9jdGFsID0gb2N0VG9EZWMub2N0YWwgfHwgb2N0YWw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyICs9IFN0cmluZy5mcm9tQ2hhckNvZGUob2N0VG9EZWMuY29kZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ciArPSBjaDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgKytsaW5lTnVtYmVyO1xuICAgICAgICAgICAgICAgICAgICBpZiAoY2ggPT09ICdcXHInICYmIHNvdXJjZVtpbmRleF0gPT09ICdcXG4nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICArK2luZGV4O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGxpbmVTdGFydCA9IGluZGV4O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNMaW5lVGVybWluYXRvcihjaC5jaGFyQ29kZUF0KDApKSkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzdHIgKz0gY2g7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocXVvdGUgIT09ICcnKSB7XG4gICAgICAgICAgICB0aHJvd1VuZXhwZWN0ZWRUb2tlbigpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IFRva2VuLlN0cmluZ0xpdGVyYWwsXG4gICAgICAgICAgICB2YWx1ZTogc3RyLFxuICAgICAgICAgICAgb2N0YWw6IG9jdGFsLFxuICAgICAgICAgICAgbGluZU51bWJlcjogc3RhcnRMaW5lTnVtYmVyLFxuICAgICAgICAgICAgbGluZVN0YXJ0OiBzdGFydExpbmVTdGFydCxcbiAgICAgICAgICAgIHN0YXJ0OiBzdGFydCxcbiAgICAgICAgICAgIGVuZDogaW5kZXhcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzY2FuVGVtcGxhdGUoKSB7XG4gICAgICAgIHZhciBjb29rZWQgPSAnJywgY2gsIHN0YXJ0LCByYXdPZmZzZXQsIHRlcm1pbmF0ZWQsIGhlYWQsIHRhaWwsIHJlc3RvcmUsIHVuZXNjYXBlZDtcblxuICAgICAgICB0ZXJtaW5hdGVkID0gZmFsc2U7XG4gICAgICAgIHRhaWwgPSBmYWxzZTtcbiAgICAgICAgc3RhcnQgPSBpbmRleDtcbiAgICAgICAgaGVhZCA9IChzb3VyY2VbaW5kZXhdID09PSAnYCcpO1xuICAgICAgICByYXdPZmZzZXQgPSAyO1xuXG4gICAgICAgICsraW5kZXg7XG5cbiAgICAgICAgd2hpbGUgKGluZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgICBjaCA9IHNvdXJjZVtpbmRleCsrXTtcbiAgICAgICAgICAgIGlmIChjaCA9PT0gJ2AnKSB7XG4gICAgICAgICAgICAgICAgcmF3T2Zmc2V0ID0gMTtcbiAgICAgICAgICAgICAgICB0YWlsID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB0ZXJtaW5hdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2ggPT09ICckJykge1xuICAgICAgICAgICAgICAgIGlmIChzb3VyY2VbaW5kZXhdID09PSAneycpIHtcbiAgICAgICAgICAgICAgICAgICAgc3RhdGUuY3VybHlTdGFjay5wdXNoKCckeycpO1xuICAgICAgICAgICAgICAgICAgICArK2luZGV4O1xuICAgICAgICAgICAgICAgICAgICB0ZXJtaW5hdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvb2tlZCArPSBjaDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2ggPT09ICdcXFxcJykge1xuICAgICAgICAgICAgICAgIGNoID0gc291cmNlW2luZGV4KytdO1xuICAgICAgICAgICAgICAgIGlmICghaXNMaW5lVGVybWluYXRvcihjaC5jaGFyQ29kZUF0KDApKSkge1xuICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGNoKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ24nOlxuICAgICAgICAgICAgICAgICAgICAgICAgY29va2VkICs9ICdcXG4nO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgY29va2VkICs9ICdcXHInO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3QnOlxuICAgICAgICAgICAgICAgICAgICAgICAgY29va2VkICs9ICdcXHQnO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3UnOlxuICAgICAgICAgICAgICAgICAgICBjYXNlICd4JzpcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzb3VyY2VbaW5kZXhdID09PSAneycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICArK2luZGV4O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvb2tlZCArPSBzY2FuVW5pY29kZUNvZGVQb2ludEVzY2FwZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN0b3JlID0gaW5kZXg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5lc2NhcGVkID0gc2NhbkhleEVzY2FwZShjaCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHVuZXNjYXBlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb29rZWQgKz0gdW5lc2NhcGVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ID0gcmVzdG9yZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29va2VkICs9IGNoO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdiJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvb2tlZCArPSAnXFxiJztcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdmJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvb2tlZCArPSAnXFxmJztcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICd2JzpcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvb2tlZCArPSAnXFx2JztcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2ggPT09ICcwJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0RlY2ltYWxEaWdpdChzb3VyY2UuY2hhckNvZGVBdChpbmRleCkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElsbGVnYWw6IFxcMDEgXFwwMiBhbmQgc28gb25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dFcnJvcihNZXNzYWdlcy5UZW1wbGF0ZU9jdGFsTGl0ZXJhbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvb2tlZCArPSAnXFwwJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNPY3RhbERpZ2l0KGNoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElsbGVnYWw6IFxcMSBcXDJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd0Vycm9yKE1lc3NhZ2VzLlRlbXBsYXRlT2N0YWxMaXRlcmFsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29va2VkICs9IGNoO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICArK2xpbmVOdW1iZXI7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjaCA9PT0gJ1xccicgJiYgc291cmNlW2luZGV4XSA9PT0gJ1xcbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICsraW5kZXg7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgbGluZVN0YXJ0ID0gaW5kZXg7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChpc0xpbmVUZXJtaW5hdG9yKGNoLmNoYXJDb2RlQXQoMCkpKSB7XG4gICAgICAgICAgICAgICAgKytsaW5lTnVtYmVyO1xuICAgICAgICAgICAgICAgIGlmIChjaCA9PT0gJ1xccicgJiYgc291cmNlW2luZGV4XSA9PT0gJ1xcbicpIHtcbiAgICAgICAgICAgICAgICAgICAgKytpbmRleDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGluZVN0YXJ0ID0gaW5kZXg7XG4gICAgICAgICAgICAgICAgY29va2VkICs9ICdcXG4nO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb29rZWQgKz0gY2g7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRlcm1pbmF0ZWQpIHtcbiAgICAgICAgICAgIHRocm93VW5leHBlY3RlZFRva2VuKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWhlYWQpIHtcbiAgICAgICAgICAgIHN0YXRlLmN1cmx5U3RhY2sucG9wKCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogVG9rZW4uVGVtcGxhdGUsXG4gICAgICAgICAgICB2YWx1ZToge1xuICAgICAgICAgICAgICAgIGNvb2tlZDogY29va2VkLFxuICAgICAgICAgICAgICAgIHJhdzogc291cmNlLnNsaWNlKHN0YXJ0ICsgMSwgaW5kZXggLSByYXdPZmZzZXQpXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaGVhZDogaGVhZCxcbiAgICAgICAgICAgIHRhaWw6IHRhaWwsXG4gICAgICAgICAgICBsaW5lTnVtYmVyOiBsaW5lTnVtYmVyLFxuICAgICAgICAgICAgbGluZVN0YXJ0OiBsaW5lU3RhcnQsXG4gICAgICAgICAgICBzdGFydDogc3RhcnQsXG4gICAgICAgICAgICBlbmQ6IGluZGV4XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdGVzdFJlZ0V4cChwYXR0ZXJuLCBmbGFncykge1xuICAgICAgICB2YXIgdG1wID0gcGF0dGVybjtcblxuICAgICAgICBpZiAoZmxhZ3MuaW5kZXhPZigndScpID49IDApIHtcbiAgICAgICAgICAgIC8vIFJlcGxhY2UgZWFjaCBhc3RyYWwgc3ltYm9sIGFuZCBldmVyeSBVbmljb2RlIGVzY2FwZSBzZXF1ZW5jZVxuICAgICAgICAgICAgLy8gdGhhdCBwb3NzaWJseSByZXByZXNlbnRzIGFuIGFzdHJhbCBzeW1ib2wgb3IgYSBwYWlyZWQgc3Vycm9nYXRlXG4gICAgICAgICAgICAvLyB3aXRoIGEgc2luZ2xlIEFTQ0lJIHN5bWJvbCB0byBhdm9pZCB0aHJvd2luZyBvbiByZWd1bGFyXG4gICAgICAgICAgICAvLyBleHByZXNzaW9ucyB0aGF0IGFyZSBvbmx5IHZhbGlkIGluIGNvbWJpbmF0aW9uIHdpdGggdGhlIGAvdWBcbiAgICAgICAgICAgIC8vIGZsYWcuXG4gICAgICAgICAgICAvLyBOb3RlOiByZXBsYWNpbmcgd2l0aCB0aGUgQVNDSUkgc3ltYm9sIGB4YCBtaWdodCBjYXVzZSBmYWxzZVxuICAgICAgICAgICAgLy8gbmVnYXRpdmVzIGluIHVubGlrZWx5IHNjZW5hcmlvcy4gRm9yIGV4YW1wbGUsIGBbXFx1ezYxfS1iXWAgaXMgYVxuICAgICAgICAgICAgLy8gcGVyZmVjdGx5IHZhbGlkIHBhdHRlcm4gdGhhdCBpcyBlcXVpdmFsZW50IHRvIGBbYS1iXWAsIGJ1dCBpdFxuICAgICAgICAgICAgLy8gd291bGQgYmUgcmVwbGFjZWQgYnkgYFt4LWJdYCB3aGljaCB0aHJvd3MgYW4gZXJyb3IuXG4gICAgICAgICAgICB0bXAgPSB0bXBcbiAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxcXHVcXHsoWzAtOWEtZkEtRl0rKVxcfS9nLCBmdW5jdGlvbiAoJDAsICQxKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChwYXJzZUludCgkMSwgMTYpIDw9IDB4MTBGRkZGKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJ3gnO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRocm93VW5leHBlY3RlZFRva2VuKG51bGwsIE1lc3NhZ2VzLkludmFsaWRSZWdFeHApO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLnJlcGxhY2UoXG4gICAgICAgICAgICAgICAgICAgIC9cXFxcdShbYS1mQS1GMC05XXs0fSl8W1xcdUQ4MDAtXFx1REJGRl1bXFx1REMwMC1cXHVERkZGXS9nLFxuICAgICAgICAgICAgICAgICAgICAneCdcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRmlyc3QsIGRldGVjdCBpbnZhbGlkIHJlZ3VsYXIgZXhwcmVzc2lvbnMuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBSZWdFeHAodG1wKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgdGhyb3dVbmV4cGVjdGVkVG9rZW4obnVsbCwgTWVzc2FnZXMuSW52YWxpZFJlZ0V4cCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZXR1cm4gYSByZWd1bGFyIGV4cHJlc3Npb24gb2JqZWN0IGZvciB0aGlzIHBhdHRlcm4tZmxhZyBwYWlyLCBvclxuICAgICAgICAvLyBgbnVsbGAgaW4gY2FzZSB0aGUgY3VycmVudCBlbnZpcm9ubWVudCBkb2Vzbid0IHN1cHBvcnQgdGhlIGZsYWdzIGl0XG4gICAgICAgIC8vIHVzZXMuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFJlZ0V4cChwYXR0ZXJuLCBmbGFncyk7XG4gICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzY2FuUmVnRXhwQm9keSgpIHtcbiAgICAgICAgdmFyIGNoLCBzdHIsIGNsYXNzTWFya2VyLCB0ZXJtaW5hdGVkLCBib2R5O1xuXG4gICAgICAgIGNoID0gc291cmNlW2luZGV4XTtcbiAgICAgICAgYXNzZXJ0KGNoID09PSAnLycsICdSZWd1bGFyIGV4cHJlc3Npb24gbGl0ZXJhbCBtdXN0IHN0YXJ0IHdpdGggYSBzbGFzaCcpO1xuICAgICAgICBzdHIgPSBzb3VyY2VbaW5kZXgrK107XG5cbiAgICAgICAgY2xhc3NNYXJrZXIgPSBmYWxzZTtcbiAgICAgICAgdGVybWluYXRlZCA9IGZhbHNlO1xuICAgICAgICB3aGlsZSAoaW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICAgIGNoID0gc291cmNlW2luZGV4KytdO1xuICAgICAgICAgICAgc3RyICs9IGNoO1xuICAgICAgICAgICAgaWYgKGNoID09PSAnXFxcXCcpIHtcbiAgICAgICAgICAgICAgICBjaCA9IHNvdXJjZVtpbmRleCsrXTtcbiAgICAgICAgICAgICAgICAvLyBFQ01BLTI2MiA3LjguNVxuICAgICAgICAgICAgICAgIGlmIChpc0xpbmVUZXJtaW5hdG9yKGNoLmNoYXJDb2RlQXQoMCkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93VW5leHBlY3RlZFRva2VuKG51bGwsIE1lc3NhZ2VzLlVudGVybWluYXRlZFJlZ0V4cCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN0ciArPSBjaDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNMaW5lVGVybWluYXRvcihjaC5jaGFyQ29kZUF0KDApKSkge1xuICAgICAgICAgICAgICAgIHRocm93VW5leHBlY3RlZFRva2VuKG51bGwsIE1lc3NhZ2VzLlVudGVybWluYXRlZFJlZ0V4cCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNsYXNzTWFya2VyKSB7XG4gICAgICAgICAgICAgICAgaWYgKGNoID09PSAnXScpIHtcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NNYXJrZXIgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChjaCA9PT0gJy8nKSB7XG4gICAgICAgICAgICAgICAgICAgIHRlcm1pbmF0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNoID09PSAnWycpIHtcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NNYXJrZXIgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGVybWluYXRlZCkge1xuICAgICAgICAgICAgdGhyb3dVbmV4cGVjdGVkVG9rZW4obnVsbCwgTWVzc2FnZXMuVW50ZXJtaW5hdGVkUmVnRXhwKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEV4Y2x1ZGUgbGVhZGluZyBhbmQgdHJhaWxpbmcgc2xhc2guXG4gICAgICAgIGJvZHkgPSBzdHIuc3Vic3RyKDEsIHN0ci5sZW5ndGggLSAyKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHZhbHVlOiBib2R5LFxuICAgICAgICAgICAgbGl0ZXJhbDogc3RyXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2NhblJlZ0V4cEZsYWdzKCkge1xuICAgICAgICB2YXIgY2gsIHN0ciwgZmxhZ3MsIHJlc3RvcmU7XG5cbiAgICAgICAgc3RyID0gJyc7XG4gICAgICAgIGZsYWdzID0gJyc7XG4gICAgICAgIHdoaWxlIChpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgICAgY2ggPSBzb3VyY2VbaW5kZXhdO1xuICAgICAgICAgICAgaWYgKCFpc0lkZW50aWZpZXJQYXJ0KGNoLmNoYXJDb2RlQXQoMCkpKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICsraW5kZXg7XG4gICAgICAgICAgICBpZiAoY2ggPT09ICdcXFxcJyAmJiBpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGNoID0gc291cmNlW2luZGV4XTtcbiAgICAgICAgICAgICAgICBpZiAoY2ggPT09ICd1Jykge1xuICAgICAgICAgICAgICAgICAgICArK2luZGV4O1xuICAgICAgICAgICAgICAgICAgICByZXN0b3JlID0gaW5kZXg7XG4gICAgICAgICAgICAgICAgICAgIGNoID0gc2NhbkhleEVzY2FwZSgndScpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoY2gpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZsYWdzICs9IGNoO1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChzdHIgKz0gJ1xcXFx1JzsgcmVzdG9yZSA8IGluZGV4OyArK3Jlc3RvcmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHIgKz0gc291cmNlW3Jlc3RvcmVdO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXggPSByZXN0b3JlO1xuICAgICAgICAgICAgICAgICAgICAgICAgZmxhZ3MgKz0gJ3UnO1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyICs9ICdcXFxcdSc7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdG9sZXJhdGVVbmV4cGVjdGVkVG9rZW4oKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzdHIgKz0gJ1xcXFwnO1xuICAgICAgICAgICAgICAgICAgICB0b2xlcmF0ZVVuZXhwZWN0ZWRUb2tlbigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZmxhZ3MgKz0gY2g7XG4gICAgICAgICAgICAgICAgc3RyICs9IGNoO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHZhbHVlOiBmbGFncyxcbiAgICAgICAgICAgIGxpdGVyYWw6IHN0clxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNjYW5SZWdFeHAoKSB7XG4gICAgICAgIHNjYW5uaW5nID0gdHJ1ZTtcbiAgICAgICAgdmFyIHN0YXJ0LCBib2R5LCBmbGFncywgdmFsdWU7XG5cbiAgICAgICAgbG9va2FoZWFkID0gbnVsbDtcbiAgICAgICAgc2tpcENvbW1lbnQoKTtcbiAgICAgICAgc3RhcnQgPSBpbmRleDtcblxuICAgICAgICBib2R5ID0gc2NhblJlZ0V4cEJvZHkoKTtcbiAgICAgICAgZmxhZ3MgPSBzY2FuUmVnRXhwRmxhZ3MoKTtcbiAgICAgICAgdmFsdWUgPSB0ZXN0UmVnRXhwKGJvZHkudmFsdWUsIGZsYWdzLnZhbHVlKTtcbiAgICAgICAgc2Nhbm5pbmcgPSBmYWxzZTtcbiAgICAgICAgaWYgKGV4dHJhLnRva2VuaXplKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHR5cGU6IFRva2VuLlJlZ3VsYXJFeHByZXNzaW9uLFxuICAgICAgICAgICAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICByZWdleDoge1xuICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuOiBib2R5LnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBmbGFnczogZmxhZ3MudmFsdWVcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGxpbmVOdW1iZXI6IGxpbmVOdW1iZXIsXG4gICAgICAgICAgICAgICAgbGluZVN0YXJ0OiBsaW5lU3RhcnQsXG4gICAgICAgICAgICAgICAgc3RhcnQ6IHN0YXJ0LFxuICAgICAgICAgICAgICAgIGVuZDogaW5kZXhcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbGl0ZXJhbDogYm9keS5saXRlcmFsICsgZmxhZ3MubGl0ZXJhbCxcbiAgICAgICAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgIHJlZ2V4OiB7XG4gICAgICAgICAgICAgICAgcGF0dGVybjogYm9keS52YWx1ZSxcbiAgICAgICAgICAgICAgICBmbGFnczogZmxhZ3MudmFsdWVcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzdGFydDogc3RhcnQsXG4gICAgICAgICAgICBlbmQ6IGluZGV4XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY29sbGVjdFJlZ2V4KCkge1xuICAgICAgICB2YXIgcG9zLCBsb2MsIHJlZ2V4LCB0b2tlbjtcblxuICAgICAgICBza2lwQ29tbWVudCgpO1xuXG4gICAgICAgIHBvcyA9IGluZGV4O1xuICAgICAgICBsb2MgPSB7XG4gICAgICAgICAgICBzdGFydDoge1xuICAgICAgICAgICAgICAgIGxpbmU6IGxpbmVOdW1iZXIsXG4gICAgICAgICAgICAgICAgY29sdW1uOiBpbmRleCAtIGxpbmVTdGFydFxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHJlZ2V4ID0gc2NhblJlZ0V4cCgpO1xuXG4gICAgICAgIGxvYy5lbmQgPSB7XG4gICAgICAgICAgICBsaW5lOiBsaW5lTnVtYmVyLFxuICAgICAgICAgICAgY29sdW1uOiBpbmRleCAtIGxpbmVTdGFydFxuICAgICAgICB9O1xuXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgIGlmICghZXh0cmEudG9rZW5pemUpIHtcbiAgICAgICAgICAgIC8vIFBvcCB0aGUgcHJldmlvdXMgdG9rZW4sIHdoaWNoIGlzIGxpa2VseSAnLycgb3IgJy89J1xuICAgICAgICAgICAgaWYgKGV4dHJhLnRva2Vucy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgdG9rZW4gPSBleHRyYS50b2tlbnNbZXh0cmEudG9rZW5zLmxlbmd0aCAtIDFdO1xuICAgICAgICAgICAgICAgIGlmICh0b2tlbi5yYW5nZVswXSA9PT0gcG9zICYmIHRva2VuLnR5cGUgPT09ICdQdW5jdHVhdG9yJykge1xuICAgICAgICAgICAgICAgICAgICBpZiAodG9rZW4udmFsdWUgPT09ICcvJyB8fCB0b2tlbi52YWx1ZSA9PT0gJy89Jykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXh0cmEudG9rZW5zLnBvcCgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBleHRyYS50b2tlbnMucHVzaCh7XG4gICAgICAgICAgICAgICAgdHlwZTogJ1JlZ3VsYXJFeHByZXNzaW9uJyxcbiAgICAgICAgICAgICAgICB2YWx1ZTogcmVnZXgubGl0ZXJhbCxcbiAgICAgICAgICAgICAgICByZWdleDogcmVnZXgucmVnZXgsXG4gICAgICAgICAgICAgICAgcmFuZ2U6IFtwb3MsIGluZGV4XSxcbiAgICAgICAgICAgICAgICBsb2M6IGxvY1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVnZXg7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNJZGVudGlmaWVyTmFtZSh0b2tlbikge1xuICAgICAgICByZXR1cm4gdG9rZW4udHlwZSA9PT0gVG9rZW4uSWRlbnRpZmllciB8fFxuICAgICAgICAgICAgdG9rZW4udHlwZSA9PT0gVG9rZW4uS2V5d29yZCB8fFxuICAgICAgICAgICAgdG9rZW4udHlwZSA9PT0gVG9rZW4uQm9vbGVhbkxpdGVyYWwgfHxcbiAgICAgICAgICAgIHRva2VuLnR5cGUgPT09IFRva2VuLk51bGxMaXRlcmFsO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFkdmFuY2VTbGFzaCgpIHtcbiAgICAgICAgdmFyIHByZXZUb2tlbixcbiAgICAgICAgICAgIGNoZWNrVG9rZW47XG4gICAgICAgIC8vIFVzaW5nIHRoZSBmb2xsb3dpbmcgYWxnb3JpdGhtOlxuICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vbW96aWxsYS9zd2VldC5qcy93aWtpL2Rlc2lnblxuICAgICAgICBwcmV2VG9rZW4gPSBleHRyYS50b2tlbnNbZXh0cmEudG9rZW5zLmxlbmd0aCAtIDFdO1xuICAgICAgICBpZiAoIXByZXZUb2tlbikge1xuICAgICAgICAgICAgLy8gTm90aGluZyBiZWZvcmUgdGhhdDogaXQgY2Fubm90IGJlIGEgZGl2aXNpb24uXG4gICAgICAgICAgICByZXR1cm4gY29sbGVjdFJlZ2V4KCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByZXZUb2tlbi50eXBlID09PSAnUHVuY3R1YXRvcicpIHtcbiAgICAgICAgICAgIGlmIChwcmV2VG9rZW4udmFsdWUgPT09ICddJykge1xuICAgICAgICAgICAgICAgIHJldHVybiBzY2FuUHVuY3R1YXRvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHByZXZUb2tlbi52YWx1ZSA9PT0gJyknKSB7XG4gICAgICAgICAgICAgICAgY2hlY2tUb2tlbiA9IGV4dHJhLnRva2Vuc1tleHRyYS5vcGVuUGFyZW5Ub2tlbiAtIDFdO1xuICAgICAgICAgICAgICAgIGlmIChjaGVja1Rva2VuICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGVja1Rva2VuLnR5cGUgPT09ICdLZXl3b3JkJyAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgKGNoZWNrVG9rZW4udmFsdWUgPT09ICdpZicgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICBjaGVja1Rva2VuLnZhbHVlID09PSAnd2hpbGUnIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tUb2tlbi52YWx1ZSA9PT0gJ2ZvcicgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICBjaGVja1Rva2VuLnZhbHVlID09PSAnd2l0aCcpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjb2xsZWN0UmVnZXgoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjYW5QdW5jdHVhdG9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocHJldlRva2VuLnZhbHVlID09PSAnfScpIHtcbiAgICAgICAgICAgICAgICAvLyBEaXZpZGluZyBhIGZ1bmN0aW9uIGJ5IGFueXRoaW5nIG1ha2VzIGxpdHRsZSBzZW5zZSxcbiAgICAgICAgICAgICAgICAvLyBidXQgd2UgaGF2ZSB0byBjaGVjayBmb3IgdGhhdC5cbiAgICAgICAgICAgICAgICBpZiAoZXh0cmEudG9rZW5zW2V4dHJhLm9wZW5DdXJseVRva2VuIC0gM10gJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4dHJhLnRva2Vuc1tleHRyYS5vcGVuQ3VybHlUb2tlbiAtIDNdLnR5cGUgPT09ICdLZXl3b3JkJykge1xuICAgICAgICAgICAgICAgICAgICAvLyBBbm9ueW1vdXMgZnVuY3Rpb24uXG4gICAgICAgICAgICAgICAgICAgIGNoZWNrVG9rZW4gPSBleHRyYS50b2tlbnNbZXh0cmEub3BlbkN1cmx5VG9rZW4gLSA0XTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjaGVja1Rva2VuKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2NhblB1bmN0dWF0b3IoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZXh0cmEudG9rZW5zW2V4dHJhLm9wZW5DdXJseVRva2VuIC0gNF0gJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4dHJhLnRva2Vuc1tleHRyYS5vcGVuQ3VybHlUb2tlbiAtIDRdLnR5cGUgPT09ICdLZXl3b3JkJykge1xuICAgICAgICAgICAgICAgICAgICAvLyBOYW1lZCBmdW5jdGlvbi5cbiAgICAgICAgICAgICAgICAgICAgY2hlY2tUb2tlbiA9IGV4dHJhLnRva2Vuc1tleHRyYS5vcGVuQ3VybHlUb2tlbiAtIDVdO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWNoZWNrVG9rZW4pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjb2xsZWN0UmVnZXgoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzY2FuUHVuY3R1YXRvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBjaGVja1Rva2VuIGRldGVybWluZXMgd2hldGhlciB0aGUgZnVuY3Rpb24gaXNcbiAgICAgICAgICAgICAgICAvLyBhIGRlY2xhcmF0aW9uIG9yIGFuIGV4cHJlc3Npb24uXG4gICAgICAgICAgICAgICAgaWYgKEZuRXhwclRva2Vucy5pbmRleE9mKGNoZWNrVG9rZW4udmFsdWUpID49IDApIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSXQgaXMgYW4gZXhwcmVzc2lvbi5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNjYW5QdW5jdHVhdG9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIEl0IGlzIGEgZGVjbGFyYXRpb24uXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbGxlY3RSZWdleCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGNvbGxlY3RSZWdleCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwcmV2VG9rZW4udHlwZSA9PT0gJ0tleXdvcmQnICYmIHByZXZUb2tlbi52YWx1ZSAhPT0gJ3RoaXMnKSB7XG4gICAgICAgICAgICByZXR1cm4gY29sbGVjdFJlZ2V4KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNjYW5QdW5jdHVhdG9yKCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gYWR2YW5jZSgpIHtcbiAgICAgICAgdmFyIGNoLCB0b2tlbjtcblxuICAgICAgICBpZiAoaW5kZXggPj0gbGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHR5cGU6IFRva2VuLkVPRixcbiAgICAgICAgICAgICAgICBsaW5lTnVtYmVyOiBsaW5lTnVtYmVyLFxuICAgICAgICAgICAgICAgIGxpbmVTdGFydDogbGluZVN0YXJ0LFxuICAgICAgICAgICAgICAgIHN0YXJ0OiBpbmRleCxcbiAgICAgICAgICAgICAgICBlbmQ6IGluZGV4XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgY2ggPSBzb3VyY2UuY2hhckNvZGVBdChpbmRleCk7XG5cbiAgICAgICAgaWYgKGlzSWRlbnRpZmllclN0YXJ0KGNoKSkge1xuICAgICAgICAgICAgdG9rZW4gPSBzY2FuSWRlbnRpZmllcigpO1xuICAgICAgICAgICAgaWYgKHN0cmljdCAmJiBpc1N0cmljdE1vZGVSZXNlcnZlZFdvcmQodG9rZW4udmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgdG9rZW4udHlwZSA9IFRva2VuLktleXdvcmQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdG9rZW47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBWZXJ5IGNvbW1vbjogKCBhbmQgKSBhbmQgO1xuICAgICAgICBpZiAoY2ggPT09IDB4MjggfHwgY2ggPT09IDB4MjkgfHwgY2ggPT09IDB4M0IpIHtcbiAgICAgICAgICAgIHJldHVybiBzY2FuUHVuY3R1YXRvcigpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU3RyaW5nIGxpdGVyYWwgc3RhcnRzIHdpdGggc2luZ2xlIHF1b3RlIChVKzAwMjcpIG9yIGRvdWJsZSBxdW90ZSAoVSswMDIyKS5cbiAgICAgICAgaWYgKGNoID09PSAweDI3IHx8IGNoID09PSAweDIyKSB7XG4gICAgICAgICAgICByZXR1cm4gc2NhblN0cmluZ0xpdGVyYWwoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIERvdCAoLikgVSswMDJFIGNhbiBhbHNvIHN0YXJ0IGEgZmxvYXRpbmctcG9pbnQgbnVtYmVyLCBoZW5jZSB0aGUgbmVlZFxuICAgICAgICAvLyB0byBjaGVjayB0aGUgbmV4dCBjaGFyYWN0ZXIuXG4gICAgICAgIGlmIChjaCA9PT0gMHgyRSkge1xuICAgICAgICAgICAgaWYgKGlzRGVjaW1hbERpZ2l0KHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4ICsgMSkpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjYW5OdW1lcmljTGl0ZXJhbCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHNjYW5QdW5jdHVhdG9yKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNEZWNpbWFsRGlnaXQoY2gpKSB7XG4gICAgICAgICAgICByZXR1cm4gc2Nhbk51bWVyaWNMaXRlcmFsKCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTbGFzaCAoLykgVSswMDJGIGNhbiBhbHNvIHN0YXJ0IGEgcmVnZXguXG4gICAgICAgIGlmIChleHRyYS50b2tlbml6ZSAmJiBjaCA9PT0gMHgyRikge1xuICAgICAgICAgICAgcmV0dXJuIGFkdmFuY2VTbGFzaCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVGVtcGxhdGUgbGl0ZXJhbHMgc3RhcnQgd2l0aCBgIChVKzAwNjApIGZvciB0ZW1wbGF0ZSBoZWFkXG4gICAgICAgIC8vIG9yIH0gKFUrMDA3RCkgZm9yIHRlbXBsYXRlIG1pZGRsZSBvciB0ZW1wbGF0ZSB0YWlsLlxuICAgICAgICBpZiAoY2ggPT09IDB4NjAgfHwgKGNoID09PSAweDdEICYmIHN0YXRlLmN1cmx5U3RhY2tbc3RhdGUuY3VybHlTdGFjay5sZW5ndGggLSAxXSA9PT0gJyR7JykpIHtcbiAgICAgICAgICAgIHJldHVybiBzY2FuVGVtcGxhdGUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBzY2FuUHVuY3R1YXRvcigpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNvbGxlY3RUb2tlbigpIHtcbiAgICAgICAgdmFyIGxvYywgdG9rZW4sIHZhbHVlLCBlbnRyeTtcblxuICAgICAgICBsb2MgPSB7XG4gICAgICAgICAgICBzdGFydDoge1xuICAgICAgICAgICAgICAgIGxpbmU6IGxpbmVOdW1iZXIsXG4gICAgICAgICAgICAgICAgY29sdW1uOiBpbmRleCAtIGxpbmVTdGFydFxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRva2VuID0gYWR2YW5jZSgpO1xuICAgICAgICBsb2MuZW5kID0ge1xuICAgICAgICAgICAgbGluZTogbGluZU51bWJlcixcbiAgICAgICAgICAgIGNvbHVtbjogaW5kZXggLSBsaW5lU3RhcnRcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAodG9rZW4udHlwZSAhPT0gVG9rZW4uRU9GKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IHNvdXJjZS5zbGljZSh0b2tlbi5zdGFydCwgdG9rZW4uZW5kKTtcbiAgICAgICAgICAgIGVudHJ5ID0ge1xuICAgICAgICAgICAgICAgIHR5cGU6IFRva2VuTmFtZVt0b2tlbi50eXBlXSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgICAgICAgICAgcmFuZ2U6IFt0b2tlbi5zdGFydCwgdG9rZW4uZW5kXSxcbiAgICAgICAgICAgICAgICBsb2M6IGxvY1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmICh0b2tlbi5yZWdleCkge1xuICAgICAgICAgICAgICAgIGVudHJ5LnJlZ2V4ID0ge1xuICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuOiB0b2tlbi5yZWdleC5wYXR0ZXJuLFxuICAgICAgICAgICAgICAgICAgICBmbGFnczogdG9rZW4ucmVnZXguZmxhZ3NcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZXh0cmEudG9rZW5zLnB1c2goZW50cnkpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRva2VuO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxleCgpIHtcbiAgICAgICAgdmFyIHRva2VuO1xuICAgICAgICBzY2FubmluZyA9IHRydWU7XG5cbiAgICAgICAgbGFzdEluZGV4ID0gaW5kZXg7XG4gICAgICAgIGxhc3RMaW5lTnVtYmVyID0gbGluZU51bWJlcjtcbiAgICAgICAgbGFzdExpbmVTdGFydCA9IGxpbmVTdGFydDtcblxuICAgICAgICBza2lwQ29tbWVudCgpO1xuXG4gICAgICAgIHRva2VuID0gbG9va2FoZWFkO1xuXG4gICAgICAgIHN0YXJ0SW5kZXggPSBpbmRleDtcbiAgICAgICAgc3RhcnRMaW5lTnVtYmVyID0gbGluZU51bWJlcjtcbiAgICAgICAgc3RhcnRMaW5lU3RhcnQgPSBsaW5lU3RhcnQ7XG5cbiAgICAgICAgbG9va2FoZWFkID0gKHR5cGVvZiBleHRyYS50b2tlbnMgIT09ICd1bmRlZmluZWQnKSA/IGNvbGxlY3RUb2tlbigpIDogYWR2YW5jZSgpO1xuICAgICAgICBzY2FubmluZyA9IGZhbHNlO1xuICAgICAgICByZXR1cm4gdG9rZW47XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGVlaygpIHtcbiAgICAgICAgc2Nhbm5pbmcgPSB0cnVlO1xuXG4gICAgICAgIHNraXBDb21tZW50KCk7XG5cbiAgICAgICAgbGFzdEluZGV4ID0gaW5kZXg7XG4gICAgICAgIGxhc3RMaW5lTnVtYmVyID0gbGluZU51bWJlcjtcbiAgICAgICAgbGFzdExpbmVTdGFydCA9IGxpbmVTdGFydDtcblxuICAgICAgICBzdGFydEluZGV4ID0gaW5kZXg7XG4gICAgICAgIHN0YXJ0TGluZU51bWJlciA9IGxpbmVOdW1iZXI7XG4gICAgICAgIHN0YXJ0TGluZVN0YXJ0ID0gbGluZVN0YXJ0O1xuXG4gICAgICAgIGxvb2thaGVhZCA9ICh0eXBlb2YgZXh0cmEudG9rZW5zICE9PSAndW5kZWZpbmVkJykgPyBjb2xsZWN0VG9rZW4oKSA6IGFkdmFuY2UoKTtcbiAgICAgICAgc2Nhbm5pbmcgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBQb3NpdGlvbigpIHtcbiAgICAgICAgdGhpcy5saW5lID0gc3RhcnRMaW5lTnVtYmVyO1xuICAgICAgICB0aGlzLmNvbHVtbiA9IHN0YXJ0SW5kZXggLSBzdGFydExpbmVTdGFydDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBTb3VyY2VMb2NhdGlvbigpIHtcbiAgICAgICAgdGhpcy5zdGFydCA9IG5ldyBQb3NpdGlvbigpO1xuICAgICAgICB0aGlzLmVuZCA9IG51bGw7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gV3JhcHBpbmdTb3VyY2VMb2NhdGlvbihzdGFydFRva2VuKSB7XG4gICAgICAgIHRoaXMuc3RhcnQgPSB7XG4gICAgICAgICAgICBsaW5lOiBzdGFydFRva2VuLmxpbmVOdW1iZXIsXG4gICAgICAgICAgICBjb2x1bW46IHN0YXJ0VG9rZW4uc3RhcnQgLSBzdGFydFRva2VuLmxpbmVTdGFydFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLmVuZCA9IG51bGw7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gTm9kZSgpIHtcbiAgICAgICAgaWYgKGV4dHJhLnJhbmdlKSB7XG4gICAgICAgICAgICB0aGlzLnJhbmdlID0gW3N0YXJ0SW5kZXgsIDBdO1xuICAgICAgICB9XG4gICAgICAgIGlmIChleHRyYS5sb2MpIHtcbiAgICAgICAgICAgIHRoaXMubG9jID0gbmV3IFNvdXJjZUxvY2F0aW9uKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBXcmFwcGluZ05vZGUoc3RhcnRUb2tlbikge1xuICAgICAgICBpZiAoZXh0cmEucmFuZ2UpIHtcbiAgICAgICAgICAgIHRoaXMucmFuZ2UgPSBbc3RhcnRUb2tlbi5zdGFydCwgMF07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV4dHJhLmxvYykge1xuICAgICAgICAgICAgdGhpcy5sb2MgPSBuZXcgV3JhcHBpbmdTb3VyY2VMb2NhdGlvbihzdGFydFRva2VuKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIFdyYXBwaW5nTm9kZS5wcm90b3R5cGUgPSBOb2RlLnByb3RvdHlwZSA9IHtcblxuICAgICAgICBwcm9jZXNzQ29tbWVudDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGxhc3RDaGlsZCxcbiAgICAgICAgICAgICAgICBsZWFkaW5nQ29tbWVudHMsXG4gICAgICAgICAgICAgICAgdHJhaWxpbmdDb21tZW50cyxcbiAgICAgICAgICAgICAgICBib3R0b21SaWdodCA9IGV4dHJhLmJvdHRvbVJpZ2h0U3RhY2ssXG4gICAgICAgICAgICAgICAgaSxcbiAgICAgICAgICAgICAgICBjb21tZW50LFxuICAgICAgICAgICAgICAgIGxhc3QgPSBib3R0b21SaWdodFtib3R0b21SaWdodC5sZW5ndGggLSAxXTtcblxuICAgICAgICAgICAgaWYgKHRoaXMudHlwZSA9PT0gU3ludGF4LlByb2dyYW0pIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5ib2R5Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGV4dHJhLnRyYWlsaW5nQ29tbWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIHRyYWlsaW5nQ29tbWVudHMgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKGkgPSBleHRyYS50cmFpbGluZ0NvbW1lbnRzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbW1lbnQgPSBleHRyYS50cmFpbGluZ0NvbW1lbnRzW2ldO1xuICAgICAgICAgICAgICAgICAgICBpZiAoY29tbWVudC5yYW5nZVswXSA+PSB0aGlzLnJhbmdlWzFdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFpbGluZ0NvbW1lbnRzLnVuc2hpZnQoY29tbWVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBleHRyYS50cmFpbGluZ0NvbW1lbnRzLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBleHRyYS50cmFpbGluZ0NvbW1lbnRzID0gW107XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChsYXN0ICYmIGxhc3QudHJhaWxpbmdDb21tZW50cyAmJiBsYXN0LnRyYWlsaW5nQ29tbWVudHNbMF0ucmFuZ2VbMF0gPj0gdGhpcy5yYW5nZVsxXSkge1xuICAgICAgICAgICAgICAgICAgICB0cmFpbGluZ0NvbW1lbnRzID0gbGFzdC50cmFpbGluZ0NvbW1lbnRzO1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgbGFzdC50cmFpbGluZ0NvbW1lbnRzO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gRWF0aW5nIHRoZSBzdGFjay5cbiAgICAgICAgICAgIGlmIChsYXN0KSB7XG4gICAgICAgICAgICAgICAgd2hpbGUgKGxhc3QgJiYgbGFzdC5yYW5nZVswXSA+PSB0aGlzLnJhbmdlWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGxhc3RDaGlsZCA9IGxhc3Q7XG4gICAgICAgICAgICAgICAgICAgIGxhc3QgPSBib3R0b21SaWdodC5wb3AoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChsYXN0Q2hpbGQpIHtcbiAgICAgICAgICAgICAgICBpZiAobGFzdENoaWxkLmxlYWRpbmdDb21tZW50cyAmJiBsYXN0Q2hpbGQubGVhZGluZ0NvbW1lbnRzW2xhc3RDaGlsZC5sZWFkaW5nQ29tbWVudHMubGVuZ3RoIC0gMV0ucmFuZ2VbMV0gPD0gdGhpcy5yYW5nZVswXSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmxlYWRpbmdDb21tZW50cyA9IGxhc3RDaGlsZC5sZWFkaW5nQ29tbWVudHM7XG4gICAgICAgICAgICAgICAgICAgIGxhc3RDaGlsZC5sZWFkaW5nQ29tbWVudHMgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChleHRyYS5sZWFkaW5nQ29tbWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGxlYWRpbmdDb21tZW50cyA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAoaSA9IGV4dHJhLmxlYWRpbmdDb21tZW50cy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICAgICAgICAgICAgICBjb21tZW50ID0gZXh0cmEubGVhZGluZ0NvbW1lbnRzW2ldO1xuICAgICAgICAgICAgICAgICAgICBpZiAoY29tbWVudC5yYW5nZVsxXSA8PSB0aGlzLnJhbmdlWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZWFkaW5nQ29tbWVudHMudW5zaGlmdChjb21tZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4dHJhLmxlYWRpbmdDb21tZW50cy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cblxuICAgICAgICAgICAgaWYgKGxlYWRpbmdDb21tZW50cyAmJiBsZWFkaW5nQ29tbWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMubGVhZGluZ0NvbW1lbnRzID0gbGVhZGluZ0NvbW1lbnRzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRyYWlsaW5nQ29tbWVudHMgJiYgdHJhaWxpbmdDb21tZW50cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy50cmFpbGluZ0NvbW1lbnRzID0gdHJhaWxpbmdDb21tZW50cztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgYm90dG9tUmlnaHQucHVzaCh0aGlzKTtcbiAgICAgICAgfSxcblxuICAgICAgICBmaW5pc2g6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChleHRyYS5yYW5nZSkge1xuICAgICAgICAgICAgICAgIHRoaXMucmFuZ2VbMV0gPSBsYXN0SW5kZXg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZXh0cmEubG9jKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sb2MuZW5kID0ge1xuICAgICAgICAgICAgICAgICAgICBsaW5lOiBsYXN0TGluZU51bWJlcixcbiAgICAgICAgICAgICAgICAgICAgY29sdW1uOiBsYXN0SW5kZXggLSBsYXN0TGluZVN0YXJ0XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBpZiAoZXh0cmEuc291cmNlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9jLnNvdXJjZSA9IGV4dHJhLnNvdXJjZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChleHRyYS5hdHRhY2hDb21tZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzQ29tbWVudCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIGZpbmlzaEFycmF5RXhwcmVzc2lvbjogZnVuY3Rpb24gKGVsZW1lbnRzKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBTeW50YXguQXJyYXlFeHByZXNzaW9uO1xuICAgICAgICAgICAgdGhpcy5lbGVtZW50cyA9IGVsZW1lbnRzO1xuICAgICAgICAgICAgdGhpcy5maW5pc2goKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuXG4gICAgICAgIGZpbmlzaEFycmF5UGF0dGVybjogZnVuY3Rpb24gKGVsZW1lbnRzKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBTeW50YXguQXJyYXlQYXR0ZXJuO1xuICAgICAgICAgICAgdGhpcy5lbGVtZW50cyA9IGVsZW1lbnRzO1xuICAgICAgICAgICAgdGhpcy5maW5pc2goKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuXG4gICAgICAgIGZpbmlzaEFycm93RnVuY3Rpb25FeHByZXNzaW9uOiBmdW5jdGlvbiAocGFyYW1zLCBkZWZhdWx0cywgYm9keSwgZXhwcmVzc2lvbikge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gU3ludGF4LkFycm93RnVuY3Rpb25FeHByZXNzaW9uO1xuICAgICAgICAgICAgdGhpcy5pZCA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLnBhcmFtcyA9IHBhcmFtcztcbiAgICAgICAgICAgIHRoaXMuZGVmYXVsdHMgPSBkZWZhdWx0cztcbiAgICAgICAgICAgIHRoaXMuYm9keSA9IGJvZHk7XG4gICAgICAgICAgICB0aGlzLmdlbmVyYXRvciA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5leHByZXNzaW9uID0gZXhwcmVzc2lvbjtcbiAgICAgICAgICAgIHRoaXMuZmluaXNoKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICBmaW5pc2hBc3NpZ25tZW50RXhwcmVzc2lvbjogZnVuY3Rpb24gKG9wZXJhdG9yLCBsZWZ0LCByaWdodCkge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gU3ludGF4LkFzc2lnbm1lbnRFeHByZXNzaW9uO1xuICAgICAgICAgICAgdGhpcy5vcGVyYXRvciA9IG9wZXJhdG9yO1xuICAgICAgICAgICAgdGhpcy5sZWZ0ID0gbGVmdDtcbiAgICAgICAgICAgIHRoaXMucmlnaHQgPSByaWdodDtcbiAgICAgICAgICAgIHRoaXMuZmluaXNoKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICBmaW5pc2hBc3NpZ25tZW50UGF0dGVybjogZnVuY3Rpb24gKGxlZnQsIHJpZ2h0KSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBTeW50YXguQXNzaWdubWVudFBhdHRlcm47XG4gICAgICAgICAgICB0aGlzLmxlZnQgPSBsZWZ0O1xuICAgICAgICAgICAgdGhpcy5yaWdodCA9IHJpZ2h0O1xuICAgICAgICAgICAgdGhpcy5maW5pc2goKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuXG4gICAgICAgIGZpbmlzaEJpbmFyeUV4cHJlc3Npb246IGZ1bmN0aW9uIChvcGVyYXRvciwgbGVmdCwgcmlnaHQpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IChvcGVyYXRvciA9PT0gJ3x8JyB8fCBvcGVyYXRvciA9PT0gJyYmJykgPyBTeW50YXguTG9naWNhbEV4cHJlc3Npb24gOiBTeW50YXguQmluYXJ5RXhwcmVzc2lvbjtcbiAgICAgICAgICAgIHRoaXMub3BlcmF0b3IgPSBvcGVyYXRvcjtcbiAgICAgICAgICAgIHRoaXMubGVmdCA9IGxlZnQ7XG4gICAgICAgICAgICB0aGlzLnJpZ2h0ID0gcmlnaHQ7XG4gICAgICAgICAgICB0aGlzLmZpbmlzaCgpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZmluaXNoQmxvY2tTdGF0ZW1lbnQ6IGZ1bmN0aW9uIChib2R5KSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBTeW50YXguQmxvY2tTdGF0ZW1lbnQ7XG4gICAgICAgICAgICB0aGlzLmJvZHkgPSBib2R5O1xuICAgICAgICAgICAgdGhpcy5maW5pc2goKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuXG4gICAgICAgIGZpbmlzaEJyZWFrU3RhdGVtZW50OiBmdW5jdGlvbiAobGFiZWwpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFN5bnRheC5CcmVha1N0YXRlbWVudDtcbiAgICAgICAgICAgIHRoaXMubGFiZWwgPSBsYWJlbDtcbiAgICAgICAgICAgIHRoaXMuZmluaXNoKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICBmaW5pc2hDYWxsRXhwcmVzc2lvbjogZnVuY3Rpb24gKGNhbGxlZSwgYXJncykge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gU3ludGF4LkNhbGxFeHByZXNzaW9uO1xuICAgICAgICAgICAgdGhpcy5jYWxsZWUgPSBjYWxsZWU7XG4gICAgICAgICAgICB0aGlzLmFyZ3VtZW50cyA9IGFyZ3M7XG4gICAgICAgICAgICB0aGlzLmZpbmlzaCgpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZmluaXNoQ2F0Y2hDbGF1c2U6IGZ1bmN0aW9uIChwYXJhbSwgYm9keSkge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gU3ludGF4LkNhdGNoQ2xhdXNlO1xuICAgICAgICAgICAgdGhpcy5wYXJhbSA9IHBhcmFtO1xuICAgICAgICAgICAgdGhpcy5ib2R5ID0gYm9keTtcbiAgICAgICAgICAgIHRoaXMuZmluaXNoKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICBmaW5pc2hDbGFzc0JvZHk6IGZ1bmN0aW9uIChib2R5KSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBTeW50YXguQ2xhc3NCb2R5O1xuICAgICAgICAgICAgdGhpcy5ib2R5ID0gYm9keTtcbiAgICAgICAgICAgIHRoaXMuZmluaXNoKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICBmaW5pc2hDbGFzc0RlY2xhcmF0aW9uOiBmdW5jdGlvbiAoaWQsIHN1cGVyQ2xhc3MsIGJvZHkpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFN5bnRheC5DbGFzc0RlY2xhcmF0aW9uO1xuICAgICAgICAgICAgdGhpcy5pZCA9IGlkO1xuICAgICAgICAgICAgdGhpcy5zdXBlckNsYXNzID0gc3VwZXJDbGFzcztcbiAgICAgICAgICAgIHRoaXMuYm9keSA9IGJvZHk7XG4gICAgICAgICAgICB0aGlzLmZpbmlzaCgpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZmluaXNoQ2xhc3NFeHByZXNzaW9uOiBmdW5jdGlvbiAoaWQsIHN1cGVyQ2xhc3MsIGJvZHkpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFN5bnRheC5DbGFzc0V4cHJlc3Npb247XG4gICAgICAgICAgICB0aGlzLmlkID0gaWQ7XG4gICAgICAgICAgICB0aGlzLnN1cGVyQ2xhc3MgPSBzdXBlckNsYXNzO1xuICAgICAgICAgICAgdGhpcy5ib2R5ID0gYm9keTtcbiAgICAgICAgICAgIHRoaXMuZmluaXNoKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICBmaW5pc2hDb25kaXRpb25hbEV4cHJlc3Npb246IGZ1bmN0aW9uICh0ZXN0LCBjb25zZXF1ZW50LCBhbHRlcm5hdGUpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFN5bnRheC5Db25kaXRpb25hbEV4cHJlc3Npb247XG4gICAgICAgICAgICB0aGlzLnRlc3QgPSB0ZXN0O1xuICAgICAgICAgICAgdGhpcy5jb25zZXF1ZW50ID0gY29uc2VxdWVudDtcbiAgICAgICAgICAgIHRoaXMuYWx0ZXJuYXRlID0gYWx0ZXJuYXRlO1xuICAgICAgICAgICAgdGhpcy5maW5pc2goKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuXG4gICAgICAgIGZpbmlzaENvbnRpbnVlU3RhdGVtZW50OiBmdW5jdGlvbiAobGFiZWwpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFN5bnRheC5Db250aW51ZVN0YXRlbWVudDtcbiAgICAgICAgICAgIHRoaXMubGFiZWwgPSBsYWJlbDtcbiAgICAgICAgICAgIHRoaXMuZmluaXNoKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICBmaW5pc2hEZWJ1Z2dlclN0YXRlbWVudDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gU3ludGF4LkRlYnVnZ2VyU3RhdGVtZW50O1xuICAgICAgICAgICAgdGhpcy5maW5pc2goKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuXG4gICAgICAgIGZpbmlzaERvV2hpbGVTdGF0ZW1lbnQ6IGZ1bmN0aW9uIChib2R5LCB0ZXN0KSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBTeW50YXguRG9XaGlsZVN0YXRlbWVudDtcbiAgICAgICAgICAgIHRoaXMuYm9keSA9IGJvZHk7XG4gICAgICAgICAgICB0aGlzLnRlc3QgPSB0ZXN0O1xuICAgICAgICAgICAgdGhpcy5maW5pc2goKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuXG4gICAgICAgIGZpbmlzaEVtcHR5U3RhdGVtZW50OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBTeW50YXguRW1wdHlTdGF0ZW1lbnQ7XG4gICAgICAgICAgICB0aGlzLmZpbmlzaCgpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZmluaXNoRXhwcmVzc2lvblN0YXRlbWVudDogZnVuY3Rpb24gKGV4cHJlc3Npb24pIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFN5bnRheC5FeHByZXNzaW9uU3RhdGVtZW50O1xuICAgICAgICAgICAgdGhpcy5leHByZXNzaW9uID0gZXhwcmVzc2lvbjtcbiAgICAgICAgICAgIHRoaXMuZmluaXNoKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICBmaW5pc2hGb3JTdGF0ZW1lbnQ6IGZ1bmN0aW9uIChpbml0LCB0ZXN0LCB1cGRhdGUsIGJvZHkpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFN5bnRheC5Gb3JTdGF0ZW1lbnQ7XG4gICAgICAgICAgICB0aGlzLmluaXQgPSBpbml0O1xuICAgICAgICAgICAgdGhpcy50ZXN0ID0gdGVzdDtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlID0gdXBkYXRlO1xuICAgICAgICAgICAgdGhpcy5ib2R5ID0gYm9keTtcbiAgICAgICAgICAgIHRoaXMuZmluaXNoKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICBmaW5pc2hGb3JJblN0YXRlbWVudDogZnVuY3Rpb24gKGxlZnQsIHJpZ2h0LCBib2R5KSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBTeW50YXguRm9ySW5TdGF0ZW1lbnQ7XG4gICAgICAgICAgICB0aGlzLmxlZnQgPSBsZWZ0O1xuICAgICAgICAgICAgdGhpcy5yaWdodCA9IHJpZ2h0O1xuICAgICAgICAgICAgdGhpcy5ib2R5ID0gYm9keTtcbiAgICAgICAgICAgIHRoaXMuZWFjaCA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5maW5pc2goKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuXG4gICAgICAgIGZpbmlzaEZ1bmN0aW9uRGVjbGFyYXRpb246IGZ1bmN0aW9uIChpZCwgcGFyYW1zLCBkZWZhdWx0cywgYm9keSkge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gU3ludGF4LkZ1bmN0aW9uRGVjbGFyYXRpb247XG4gICAgICAgICAgICB0aGlzLmlkID0gaWQ7XG4gICAgICAgICAgICB0aGlzLnBhcmFtcyA9IHBhcmFtcztcbiAgICAgICAgICAgIHRoaXMuZGVmYXVsdHMgPSBkZWZhdWx0cztcbiAgICAgICAgICAgIHRoaXMuYm9keSA9IGJvZHk7XG4gICAgICAgICAgICB0aGlzLmdlbmVyYXRvciA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5leHByZXNzaW9uID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLmZpbmlzaCgpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZmluaXNoRnVuY3Rpb25FeHByZXNzaW9uOiBmdW5jdGlvbiAoaWQsIHBhcmFtcywgZGVmYXVsdHMsIGJvZHkpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFN5bnRheC5GdW5jdGlvbkV4cHJlc3Npb247XG4gICAgICAgICAgICB0aGlzLmlkID0gaWQ7XG4gICAgICAgICAgICB0aGlzLnBhcmFtcyA9IHBhcmFtcztcbiAgICAgICAgICAgIHRoaXMuZGVmYXVsdHMgPSBkZWZhdWx0cztcbiAgICAgICAgICAgIHRoaXMuYm9keSA9IGJvZHk7XG4gICAgICAgICAgICB0aGlzLmdlbmVyYXRvciA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5leHByZXNzaW9uID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLmZpbmlzaCgpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZmluaXNoSWRlbnRpZmllcjogZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFN5bnRheC5JZGVudGlmaWVyO1xuICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICAgICAgICAgIHRoaXMuZmluaXNoKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICBmaW5pc2hJZlN0YXRlbWVudDogZnVuY3Rpb24gKHRlc3QsIGNvbnNlcXVlbnQsIGFsdGVybmF0ZSkge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gU3ludGF4LklmU3RhdGVtZW50O1xuICAgICAgICAgICAgdGhpcy50ZXN0ID0gdGVzdDtcbiAgICAgICAgICAgIHRoaXMuY29uc2VxdWVudCA9IGNvbnNlcXVlbnQ7XG4gICAgICAgICAgICB0aGlzLmFsdGVybmF0ZSA9IGFsdGVybmF0ZTtcbiAgICAgICAgICAgIHRoaXMuZmluaXNoKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICBmaW5pc2hMYWJlbGVkU3RhdGVtZW50OiBmdW5jdGlvbiAobGFiZWwsIGJvZHkpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFN5bnRheC5MYWJlbGVkU3RhdGVtZW50O1xuICAgICAgICAgICAgdGhpcy5sYWJlbCA9IGxhYmVsO1xuICAgICAgICAgICAgdGhpcy5ib2R5ID0gYm9keTtcbiAgICAgICAgICAgIHRoaXMuZmluaXNoKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICBmaW5pc2hMaXRlcmFsOiBmdW5jdGlvbiAodG9rZW4pIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFN5bnRheC5MaXRlcmFsO1xuICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHRva2VuLnZhbHVlO1xuICAgICAgICAgICAgdGhpcy5yYXcgPSBzb3VyY2Uuc2xpY2UodG9rZW4uc3RhcnQsIHRva2VuLmVuZCk7XG4gICAgICAgICAgICBpZiAodG9rZW4ucmVnZXgpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlZ2V4ID0gdG9rZW4ucmVnZXg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmZpbmlzaCgpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZmluaXNoTWVtYmVyRXhwcmVzc2lvbjogZnVuY3Rpb24gKGFjY2Vzc29yLCBvYmplY3QsIHByb3BlcnR5KSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBTeW50YXguTWVtYmVyRXhwcmVzc2lvbjtcbiAgICAgICAgICAgIHRoaXMuY29tcHV0ZWQgPSBhY2Nlc3NvciA9PT0gJ1snO1xuICAgICAgICAgICAgdGhpcy5vYmplY3QgPSBvYmplY3Q7XG4gICAgICAgICAgICB0aGlzLnByb3BlcnR5ID0gcHJvcGVydHk7XG4gICAgICAgICAgICB0aGlzLmZpbmlzaCgpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZmluaXNoTmV3RXhwcmVzc2lvbjogZnVuY3Rpb24gKGNhbGxlZSwgYXJncykge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gU3ludGF4Lk5ld0V4cHJlc3Npb247XG4gICAgICAgICAgICB0aGlzLmNhbGxlZSA9IGNhbGxlZTtcbiAgICAgICAgICAgIHRoaXMuYXJndW1lbnRzID0gYXJncztcbiAgICAgICAgICAgIHRoaXMuZmluaXNoKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICBmaW5pc2hPYmplY3RFeHByZXNzaW9uOiBmdW5jdGlvbiAocHJvcGVydGllcykge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gU3ludGF4Lk9iamVjdEV4cHJlc3Npb247XG4gICAgICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzO1xuICAgICAgICAgICAgdGhpcy5maW5pc2goKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuXG4gICAgICAgIGZpbmlzaE9iamVjdFBhdHRlcm46IGZ1bmN0aW9uIChwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBTeW50YXguT2JqZWN0UGF0dGVybjtcbiAgICAgICAgICAgIHRoaXMucHJvcGVydGllcyA9IHByb3BlcnRpZXM7XG4gICAgICAgICAgICB0aGlzLmZpbmlzaCgpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZmluaXNoUG9zdGZpeEV4cHJlc3Npb246IGZ1bmN0aW9uIChvcGVyYXRvciwgYXJndW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFN5bnRheC5VcGRhdGVFeHByZXNzaW9uO1xuICAgICAgICAgICAgdGhpcy5vcGVyYXRvciA9IG9wZXJhdG9yO1xuICAgICAgICAgICAgdGhpcy5hcmd1bWVudCA9IGFyZ3VtZW50O1xuICAgICAgICAgICAgdGhpcy5wcmVmaXggPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuZmluaXNoKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICBmaW5pc2hQcm9ncmFtOiBmdW5jdGlvbiAoYm9keSkge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gU3ludGF4LlByb2dyYW07XG4gICAgICAgICAgICB0aGlzLmJvZHkgPSBib2R5O1xuICAgICAgICAgICAgaWYgKHNvdXJjZVR5cGUgPT09ICdtb2R1bGUnKSB7XG4gICAgICAgICAgICAgICAgLy8gdmVyeSByZXN0cmljdGl2ZSBmb3Igbm93XG4gICAgICAgICAgICAgICAgdGhpcy5zb3VyY2VUeXBlID0gc291cmNlVHlwZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZmluaXNoKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICBmaW5pc2hQcm9wZXJ0eTogZnVuY3Rpb24gKGtpbmQsIGtleSwgY29tcHV0ZWQsIHZhbHVlLCBtZXRob2QsIHNob3J0aGFuZCkge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gU3ludGF4LlByb3BlcnR5O1xuICAgICAgICAgICAgdGhpcy5rZXkgPSBrZXk7XG4gICAgICAgICAgICB0aGlzLmNvbXB1dGVkID0gY29tcHV0ZWQ7XG4gICAgICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgICAgICAgICB0aGlzLmtpbmQgPSBraW5kO1xuICAgICAgICAgICAgdGhpcy5tZXRob2QgPSBtZXRob2Q7XG4gICAgICAgICAgICB0aGlzLnNob3J0aGFuZCA9IHNob3J0aGFuZDtcbiAgICAgICAgICAgIHRoaXMuZmluaXNoKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICBmaW5pc2hSZXN0RWxlbWVudDogZnVuY3Rpb24gKGFyZ3VtZW50KSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBTeW50YXguUmVzdEVsZW1lbnQ7XG4gICAgICAgICAgICB0aGlzLmFyZ3VtZW50ID0gYXJndW1lbnQ7XG4gICAgICAgICAgICB0aGlzLmZpbmlzaCgpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZmluaXNoUmV0dXJuU3RhdGVtZW50OiBmdW5jdGlvbiAoYXJndW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFN5bnRheC5SZXR1cm5TdGF0ZW1lbnQ7XG4gICAgICAgICAgICB0aGlzLmFyZ3VtZW50ID0gYXJndW1lbnQ7XG4gICAgICAgICAgICB0aGlzLmZpbmlzaCgpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZmluaXNoU2VxdWVuY2VFeHByZXNzaW9uOiBmdW5jdGlvbiAoZXhwcmVzc2lvbnMpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFN5bnRheC5TZXF1ZW5jZUV4cHJlc3Npb247XG4gICAgICAgICAgICB0aGlzLmV4cHJlc3Npb25zID0gZXhwcmVzc2lvbnM7XG4gICAgICAgICAgICB0aGlzLmZpbmlzaCgpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZmluaXNoU3ByZWFkRWxlbWVudDogZnVuY3Rpb24gKGFyZ3VtZW50KSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBTeW50YXguU3ByZWFkRWxlbWVudDtcbiAgICAgICAgICAgIHRoaXMuYXJndW1lbnQgPSBhcmd1bWVudDtcbiAgICAgICAgICAgIHRoaXMuZmluaXNoKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICBmaW5pc2hTd2l0Y2hDYXNlOiBmdW5jdGlvbiAodGVzdCwgY29uc2VxdWVudCkge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gU3ludGF4LlN3aXRjaENhc2U7XG4gICAgICAgICAgICB0aGlzLnRlc3QgPSB0ZXN0O1xuICAgICAgICAgICAgdGhpcy5jb25zZXF1ZW50ID0gY29uc2VxdWVudDtcbiAgICAgICAgICAgIHRoaXMuZmluaXNoKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICBmaW5pc2hTdXBlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gU3ludGF4LlN1cGVyO1xuICAgICAgICAgICAgdGhpcy5maW5pc2goKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuXG4gICAgICAgIGZpbmlzaFN3aXRjaFN0YXRlbWVudDogZnVuY3Rpb24gKGRpc2NyaW1pbmFudCwgY2FzZXMpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFN5bnRheC5Td2l0Y2hTdGF0ZW1lbnQ7XG4gICAgICAgICAgICB0aGlzLmRpc2NyaW1pbmFudCA9IGRpc2NyaW1pbmFudDtcbiAgICAgICAgICAgIHRoaXMuY2FzZXMgPSBjYXNlcztcbiAgICAgICAgICAgIHRoaXMuZmluaXNoKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICBmaW5pc2hUYWdnZWRUZW1wbGF0ZUV4cHJlc3Npb246IGZ1bmN0aW9uICh0YWcsIHF1YXNpKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBTeW50YXguVGFnZ2VkVGVtcGxhdGVFeHByZXNzaW9uO1xuICAgICAgICAgICAgdGhpcy50YWcgPSB0YWc7XG4gICAgICAgICAgICB0aGlzLnF1YXNpID0gcXVhc2k7XG4gICAgICAgICAgICB0aGlzLmZpbmlzaCgpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZmluaXNoVGVtcGxhdGVFbGVtZW50OiBmdW5jdGlvbiAodmFsdWUsIHRhaWwpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFN5bnRheC5UZW1wbGF0ZUVsZW1lbnQ7XG4gICAgICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgICAgICAgICB0aGlzLnRhaWwgPSB0YWlsO1xuICAgICAgICAgICAgdGhpcy5maW5pc2goKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuXG4gICAgICAgIGZpbmlzaFRlbXBsYXRlTGl0ZXJhbDogZnVuY3Rpb24gKHF1YXNpcywgZXhwcmVzc2lvbnMpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFN5bnRheC5UZW1wbGF0ZUxpdGVyYWw7XG4gICAgICAgICAgICB0aGlzLnF1YXNpcyA9IHF1YXNpcztcbiAgICAgICAgICAgIHRoaXMuZXhwcmVzc2lvbnMgPSBleHByZXNzaW9ucztcbiAgICAgICAgICAgIHRoaXMuZmluaXNoKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICBmaW5pc2hUaGlzRXhwcmVzc2lvbjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gU3ludGF4LlRoaXNFeHByZXNzaW9uO1xuICAgICAgICAgICAgdGhpcy5maW5pc2goKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuXG4gICAgICAgIGZpbmlzaFRocm93U3RhdGVtZW50OiBmdW5jdGlvbiAoYXJndW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFN5bnRheC5UaHJvd1N0YXRlbWVudDtcbiAgICAgICAgICAgIHRoaXMuYXJndW1lbnQgPSBhcmd1bWVudDtcbiAgICAgICAgICAgIHRoaXMuZmluaXNoKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICBmaW5pc2hUcnlTdGF0ZW1lbnQ6IGZ1bmN0aW9uIChibG9jaywgaGFuZGxlciwgZmluYWxpemVyKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBTeW50YXguVHJ5U3RhdGVtZW50O1xuICAgICAgICAgICAgdGhpcy5ibG9jayA9IGJsb2NrO1xuICAgICAgICAgICAgdGhpcy5ndWFyZGVkSGFuZGxlcnMgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlcnMgPSBoYW5kbGVyID8gWyBoYW5kbGVyIF0gOiBbXTtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlciA9IGhhbmRsZXI7XG4gICAgICAgICAgICB0aGlzLmZpbmFsaXplciA9IGZpbmFsaXplcjtcbiAgICAgICAgICAgIHRoaXMuZmluaXNoKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICBmaW5pc2hVbmFyeUV4cHJlc3Npb246IGZ1bmN0aW9uIChvcGVyYXRvciwgYXJndW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IChvcGVyYXRvciA9PT0gJysrJyB8fCBvcGVyYXRvciA9PT0gJy0tJykgPyBTeW50YXguVXBkYXRlRXhwcmVzc2lvbiA6IFN5bnRheC5VbmFyeUV4cHJlc3Npb247XG4gICAgICAgICAgICB0aGlzLm9wZXJhdG9yID0gb3BlcmF0b3I7XG4gICAgICAgICAgICB0aGlzLmFyZ3VtZW50ID0gYXJndW1lbnQ7XG4gICAgICAgICAgICB0aGlzLnByZWZpeCA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLmZpbmlzaCgpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZmluaXNoVmFyaWFibGVEZWNsYXJhdGlvbjogZnVuY3Rpb24gKGRlY2xhcmF0aW9ucykge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gU3ludGF4LlZhcmlhYmxlRGVjbGFyYXRpb247XG4gICAgICAgICAgICB0aGlzLmRlY2xhcmF0aW9ucyA9IGRlY2xhcmF0aW9ucztcbiAgICAgICAgICAgIHRoaXMua2luZCA9ICd2YXInO1xuICAgICAgICAgICAgdGhpcy5maW5pc2goKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuXG4gICAgICAgIGZpbmlzaExleGljYWxEZWNsYXJhdGlvbjogZnVuY3Rpb24gKGRlY2xhcmF0aW9ucywga2luZCkge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gU3ludGF4LlZhcmlhYmxlRGVjbGFyYXRpb247XG4gICAgICAgICAgICB0aGlzLmRlY2xhcmF0aW9ucyA9IGRlY2xhcmF0aW9ucztcbiAgICAgICAgICAgIHRoaXMua2luZCA9IGtpbmQ7XG4gICAgICAgICAgICB0aGlzLmZpbmlzaCgpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZmluaXNoVmFyaWFibGVEZWNsYXJhdG9yOiBmdW5jdGlvbiAoaWQsIGluaXQpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFN5bnRheC5WYXJpYWJsZURlY2xhcmF0b3I7XG4gICAgICAgICAgICB0aGlzLmlkID0gaWQ7XG4gICAgICAgICAgICB0aGlzLmluaXQgPSBpbml0O1xuICAgICAgICAgICAgdGhpcy5maW5pc2goKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuXG4gICAgICAgIGZpbmlzaFdoaWxlU3RhdGVtZW50OiBmdW5jdGlvbiAodGVzdCwgYm9keSkge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gU3ludGF4LldoaWxlU3RhdGVtZW50O1xuICAgICAgICAgICAgdGhpcy50ZXN0ID0gdGVzdDtcbiAgICAgICAgICAgIHRoaXMuYm9keSA9IGJvZHk7XG4gICAgICAgICAgICB0aGlzLmZpbmlzaCgpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZmluaXNoV2l0aFN0YXRlbWVudDogZnVuY3Rpb24gKG9iamVjdCwgYm9keSkge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gU3ludGF4LldpdGhTdGF0ZW1lbnQ7XG4gICAgICAgICAgICB0aGlzLm9iamVjdCA9IG9iamVjdDtcbiAgICAgICAgICAgIHRoaXMuYm9keSA9IGJvZHk7XG4gICAgICAgICAgICB0aGlzLmZpbmlzaCgpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZmluaXNoRXhwb3J0U3BlY2lmaWVyOiBmdW5jdGlvbiAobG9jYWwsIGV4cG9ydGVkKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBTeW50YXguRXhwb3J0U3BlY2lmaWVyO1xuICAgICAgICAgICAgdGhpcy5leHBvcnRlZCA9IGV4cG9ydGVkIHx8IGxvY2FsO1xuICAgICAgICAgICAgdGhpcy5sb2NhbCA9IGxvY2FsO1xuICAgICAgICAgICAgdGhpcy5maW5pc2goKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuXG4gICAgICAgIGZpbmlzaEltcG9ydERlZmF1bHRTcGVjaWZpZXI6IGZ1bmN0aW9uIChsb2NhbCkge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gU3ludGF4LkltcG9ydERlZmF1bHRTcGVjaWZpZXI7XG4gICAgICAgICAgICB0aGlzLmxvY2FsID0gbG9jYWw7XG4gICAgICAgICAgICB0aGlzLmZpbmlzaCgpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZmluaXNoSW1wb3J0TmFtZXNwYWNlU3BlY2lmaWVyOiBmdW5jdGlvbiAobG9jYWwpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFN5bnRheC5JbXBvcnROYW1lc3BhY2VTcGVjaWZpZXI7XG4gICAgICAgICAgICB0aGlzLmxvY2FsID0gbG9jYWw7XG4gICAgICAgICAgICB0aGlzLmZpbmlzaCgpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZmluaXNoRXhwb3J0TmFtZWREZWNsYXJhdGlvbjogZnVuY3Rpb24gKGRlY2xhcmF0aW9uLCBzcGVjaWZpZXJzLCBzcmMpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFN5bnRheC5FeHBvcnROYW1lZERlY2xhcmF0aW9uO1xuICAgICAgICAgICAgdGhpcy5kZWNsYXJhdGlvbiA9IGRlY2xhcmF0aW9uO1xuICAgICAgICAgICAgdGhpcy5zcGVjaWZpZXJzID0gc3BlY2lmaWVycztcbiAgICAgICAgICAgIHRoaXMuc291cmNlID0gc3JjO1xuICAgICAgICAgICAgdGhpcy5maW5pc2goKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuXG4gICAgICAgIGZpbmlzaEV4cG9ydERlZmF1bHREZWNsYXJhdGlvbjogZnVuY3Rpb24gKGRlY2xhcmF0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBTeW50YXguRXhwb3J0RGVmYXVsdERlY2xhcmF0aW9uO1xuICAgICAgICAgICAgdGhpcy5kZWNsYXJhdGlvbiA9IGRlY2xhcmF0aW9uO1xuICAgICAgICAgICAgdGhpcy5maW5pc2goKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuXG4gICAgICAgIGZpbmlzaEV4cG9ydEFsbERlY2xhcmF0aW9uOiBmdW5jdGlvbiAoc3JjKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBTeW50YXguRXhwb3J0QWxsRGVjbGFyYXRpb247XG4gICAgICAgICAgICB0aGlzLnNvdXJjZSA9IHNyYztcbiAgICAgICAgICAgIHRoaXMuZmluaXNoKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICBmaW5pc2hJbXBvcnRTcGVjaWZpZXI6IGZ1bmN0aW9uIChsb2NhbCwgaW1wb3J0ZWQpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFN5bnRheC5JbXBvcnRTcGVjaWZpZXI7XG4gICAgICAgICAgICB0aGlzLmxvY2FsID0gbG9jYWwgfHwgaW1wb3J0ZWQ7XG4gICAgICAgICAgICB0aGlzLmltcG9ydGVkID0gaW1wb3J0ZWQ7XG4gICAgICAgICAgICB0aGlzLmZpbmlzaCgpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZmluaXNoSW1wb3J0RGVjbGFyYXRpb246IGZ1bmN0aW9uIChzcGVjaWZpZXJzLCBzcmMpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFN5bnRheC5JbXBvcnREZWNsYXJhdGlvbjtcbiAgICAgICAgICAgIHRoaXMuc3BlY2lmaWVycyA9IHNwZWNpZmllcnM7XG4gICAgICAgICAgICB0aGlzLnNvdXJjZSA9IHNyYztcbiAgICAgICAgICAgIHRoaXMuZmluaXNoKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgIH07XG5cblxuICAgIGZ1bmN0aW9uIHJlY29yZEVycm9yKGVycm9yKSB7XG4gICAgICAgIHZhciBlLCBleGlzdGluZztcblxuICAgICAgICBmb3IgKGUgPSAwOyBlIDwgZXh0cmEuZXJyb3JzLmxlbmd0aDsgZSsrKSB7XG4gICAgICAgICAgICBleGlzdGluZyA9IGV4dHJhLmVycm9yc1tlXTtcbiAgICAgICAgICAgIC8vIFByZXZlbnQgZHVwbGljYXRlZCBlcnJvci5cbiAgICAgICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgICAgICBpZiAoZXhpc3RpbmcuaW5kZXggPT09IGVycm9yLmluZGV4ICYmIGV4aXN0aW5nLm1lc3NhZ2UgPT09IGVycm9yLm1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBleHRyYS5lcnJvcnMucHVzaChlcnJvcik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlRXJyb3IobGluZSwgcG9zLCBkZXNjcmlwdGlvbikge1xuICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0xpbmUgJyArIGxpbmUgKyAnOiAnICsgZGVzY3JpcHRpb24pO1xuICAgICAgICBlcnJvci5pbmRleCA9IHBvcztcbiAgICAgICAgZXJyb3IubGluZU51bWJlciA9IGxpbmU7XG4gICAgICAgIGVycm9yLmNvbHVtbiA9IHBvcyAtIChzY2FubmluZyA/IGxpbmVTdGFydCA6IGxhc3RMaW5lU3RhcnQpICsgMTtcbiAgICAgICAgZXJyb3IuZGVzY3JpcHRpb24gPSBkZXNjcmlwdGlvbjtcbiAgICAgICAgcmV0dXJuIGVycm9yO1xuICAgIH1cblxuICAgIC8vIFRocm93IGFuIGV4Y2VwdGlvblxuXG4gICAgZnVuY3Rpb24gdGhyb3dFcnJvcihtZXNzYWdlRm9ybWF0KSB7XG4gICAgICAgIHZhciBhcmdzLCBtc2c7XG5cbiAgICAgICAgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICAgIG1zZyA9IG1lc3NhZ2VGb3JtYXQucmVwbGFjZSgvJShcXGQpL2csXG4gICAgICAgICAgICBmdW5jdGlvbiAod2hvbGUsIGlkeCkge1xuICAgICAgICAgICAgICAgIGFzc2VydChpZHggPCBhcmdzLmxlbmd0aCwgJ01lc3NhZ2UgcmVmZXJlbmNlIG11c3QgYmUgaW4gcmFuZ2UnKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXJnc1tpZHhdO1xuICAgICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICAgIHRocm93IGNyZWF0ZUVycm9yKGxhc3RMaW5lTnVtYmVyLCBsYXN0SW5kZXgsIG1zZyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdG9sZXJhdGVFcnJvcihtZXNzYWdlRm9ybWF0KSB7XG4gICAgICAgIHZhciBhcmdzLCBtc2csIGVycm9yO1xuXG4gICAgICAgIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICBtc2cgPSBtZXNzYWdlRm9ybWF0LnJlcGxhY2UoLyUoXFxkKS9nLFxuICAgICAgICAgICAgZnVuY3Rpb24gKHdob2xlLCBpZHgpIHtcbiAgICAgICAgICAgICAgICBhc3NlcnQoaWR4IDwgYXJncy5sZW5ndGgsICdNZXNzYWdlIHJlZmVyZW5jZSBtdXN0IGJlIGluIHJhbmdlJyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFyZ3NbaWR4XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICBlcnJvciA9IGNyZWF0ZUVycm9yKGxpbmVOdW1iZXIsIGxhc3RJbmRleCwgbXNnKTtcbiAgICAgICAgaWYgKGV4dHJhLmVycm9ycykge1xuICAgICAgICAgICAgcmVjb3JkRXJyb3IoZXJyb3IpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUaHJvdyBhbiBleGNlcHRpb24gYmVjYXVzZSBvZiB0aGUgdG9rZW4uXG5cbiAgICBmdW5jdGlvbiB1bmV4cGVjdGVkVG9rZW5FcnJvcih0b2tlbiwgbWVzc2FnZSkge1xuICAgICAgICB2YXIgdmFsdWUsIG1zZyA9IG1lc3NhZ2UgfHwgTWVzc2FnZXMuVW5leHBlY3RlZFRva2VuO1xuXG4gICAgICAgIGlmICh0b2tlbikge1xuICAgICAgICAgICAgaWYgKCFtZXNzYWdlKSB7XG4gICAgICAgICAgICAgICAgbXNnID0gKHRva2VuLnR5cGUgPT09IFRva2VuLkVPRikgPyBNZXNzYWdlcy5VbmV4cGVjdGVkRU9TIDpcbiAgICAgICAgICAgICAgICAgICAgKHRva2VuLnR5cGUgPT09IFRva2VuLklkZW50aWZpZXIpID8gTWVzc2FnZXMuVW5leHBlY3RlZElkZW50aWZpZXIgOlxuICAgICAgICAgICAgICAgICAgICAodG9rZW4udHlwZSA9PT0gVG9rZW4uTnVtZXJpY0xpdGVyYWwpID8gTWVzc2FnZXMuVW5leHBlY3RlZE51bWJlciA6XG4gICAgICAgICAgICAgICAgICAgICh0b2tlbi50eXBlID09PSBUb2tlbi5TdHJpbmdMaXRlcmFsKSA/IE1lc3NhZ2VzLlVuZXhwZWN0ZWRTdHJpbmcgOlxuICAgICAgICAgICAgICAgICAgICAodG9rZW4udHlwZSA9PT0gVG9rZW4uVGVtcGxhdGUpID8gTWVzc2FnZXMuVW5leHBlY3RlZFRlbXBsYXRlIDpcbiAgICAgICAgICAgICAgICAgICAgTWVzc2FnZXMuVW5leHBlY3RlZFRva2VuO1xuXG4gICAgICAgICAgICAgICAgaWYgKHRva2VuLnR5cGUgPT09IFRva2VuLktleXdvcmQpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzRnV0dXJlUmVzZXJ2ZWRXb3JkKHRva2VuLnZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbXNnID0gTWVzc2FnZXMuVW5leHBlY3RlZFJlc2VydmVkO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHN0cmljdCAmJiBpc1N0cmljdE1vZGVSZXNlcnZlZFdvcmQodG9rZW4udmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cgPSBNZXNzYWdlcy5TdHJpY3RSZXNlcnZlZFdvcmQ7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhbHVlID0gKHRva2VuLnR5cGUgPT09IFRva2VuLlRlbXBsYXRlKSA/IHRva2VuLnZhbHVlLnJhdyA6IHRva2VuLnZhbHVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFsdWUgPSAnSUxMRUdBTCc7XG4gICAgICAgIH1cblxuICAgICAgICBtc2cgPSBtc2cucmVwbGFjZSgnJTAnLCB2YWx1ZSk7XG5cbiAgICAgICAgcmV0dXJuICh0b2tlbiAmJiB0eXBlb2YgdG9rZW4ubGluZU51bWJlciA9PT0gJ251bWJlcicpID9cbiAgICAgICAgICAgIGNyZWF0ZUVycm9yKHRva2VuLmxpbmVOdW1iZXIsIHRva2VuLnN0YXJ0LCBtc2cpIDpcbiAgICAgICAgICAgIGNyZWF0ZUVycm9yKHNjYW5uaW5nID8gbGluZU51bWJlciA6IGxhc3RMaW5lTnVtYmVyLCBzY2FubmluZyA/IGluZGV4IDogbGFzdEluZGV4LCBtc2cpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHRocm93VW5leHBlY3RlZFRva2VuKHRva2VuLCBtZXNzYWdlKSB7XG4gICAgICAgIHRocm93IHVuZXhwZWN0ZWRUb2tlbkVycm9yKHRva2VuLCBtZXNzYWdlKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0b2xlcmF0ZVVuZXhwZWN0ZWRUb2tlbih0b2tlbiwgbWVzc2FnZSkge1xuICAgICAgICB2YXIgZXJyb3IgPSB1bmV4cGVjdGVkVG9rZW5FcnJvcih0b2tlbiwgbWVzc2FnZSk7XG4gICAgICAgIGlmIChleHRyYS5lcnJvcnMpIHtcbiAgICAgICAgICAgIHJlY29yZEVycm9yKGVycm9yKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gRXhwZWN0IHRoZSBuZXh0IHRva2VuIHRvIG1hdGNoIHRoZSBzcGVjaWZpZWQgcHVuY3R1YXRvci5cbiAgICAvLyBJZiBub3QsIGFuIGV4Y2VwdGlvbiB3aWxsIGJlIHRocm93bi5cblxuICAgIGZ1bmN0aW9uIGV4cGVjdCh2YWx1ZSkge1xuICAgICAgICB2YXIgdG9rZW4gPSBsZXgoKTtcbiAgICAgICAgaWYgKHRva2VuLnR5cGUgIT09IFRva2VuLlB1bmN0dWF0b3IgfHwgdG9rZW4udmFsdWUgIT09IHZhbHVlKSB7XG4gICAgICAgICAgICB0aHJvd1VuZXhwZWN0ZWRUb2tlbih0b2tlbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAbmFtZSBleHBlY3RDb21tYVNlcGFyYXRvclxuICAgICAqIEBkZXNjcmlwdGlvbiBRdWlldGx5IGV4cGVjdCBhIGNvbW1hIHdoZW4gaW4gdG9sZXJhbnQgbW9kZSwgb3RoZXJ3aXNlIGRlbGVnYXRlc1xuICAgICAqIHRvIDxjb2RlPmV4cGVjdCh2YWx1ZSk8L2NvZGU+XG4gICAgICogQHNpbmNlIDIuMFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGV4cGVjdENvbW1hU2VwYXJhdG9yKCkge1xuICAgICAgICB2YXIgdG9rZW47XG5cbiAgICAgICAgaWYgKGV4dHJhLmVycm9ycykge1xuICAgICAgICAgICAgdG9rZW4gPSBsb29rYWhlYWQ7XG4gICAgICAgICAgICBpZiAodG9rZW4udHlwZSA9PT0gVG9rZW4uUHVuY3R1YXRvciAmJiB0b2tlbi52YWx1ZSA9PT0gJywnKSB7XG4gICAgICAgICAgICAgICAgbGV4KCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRva2VuLnR5cGUgPT09IFRva2VuLlB1bmN0dWF0b3IgJiYgdG9rZW4udmFsdWUgPT09ICc7Jykge1xuICAgICAgICAgICAgICAgIGxleCgpO1xuICAgICAgICAgICAgICAgIHRvbGVyYXRlVW5leHBlY3RlZFRva2VuKHRva2VuKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdG9sZXJhdGVVbmV4cGVjdGVkVG9rZW4odG9rZW4sIE1lc3NhZ2VzLlVuZXhwZWN0ZWRUb2tlbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBleHBlY3QoJywnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIEV4cGVjdCB0aGUgbmV4dCB0b2tlbiB0byBtYXRjaCB0aGUgc3BlY2lmaWVkIGtleXdvcmQuXG4gICAgLy8gSWYgbm90LCBhbiBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24uXG5cbiAgICBmdW5jdGlvbiBleHBlY3RLZXl3b3JkKGtleXdvcmQpIHtcbiAgICAgICAgdmFyIHRva2VuID0gbGV4KCk7XG4gICAgICAgIGlmICh0b2tlbi50eXBlICE9PSBUb2tlbi5LZXl3b3JkIHx8IHRva2VuLnZhbHVlICE9PSBrZXl3b3JkKSB7XG4gICAgICAgICAgICB0aHJvd1VuZXhwZWN0ZWRUb2tlbih0b2tlbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgbmV4dCB0b2tlbiBtYXRjaGVzIHRoZSBzcGVjaWZpZWQgcHVuY3R1YXRvci5cblxuICAgIGZ1bmN0aW9uIG1hdGNoKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBsb29rYWhlYWQudHlwZSA9PT0gVG9rZW4uUHVuY3R1YXRvciAmJiBsb29rYWhlYWQudmFsdWUgPT09IHZhbHVlO1xuICAgIH1cblxuICAgIC8vIFJldHVybiB0cnVlIGlmIHRoZSBuZXh0IHRva2VuIG1hdGNoZXMgdGhlIHNwZWNpZmllZCBrZXl3b3JkXG5cbiAgICBmdW5jdGlvbiBtYXRjaEtleXdvcmQoa2V5d29yZCkge1xuICAgICAgICByZXR1cm4gbG9va2FoZWFkLnR5cGUgPT09IFRva2VuLktleXdvcmQgJiYgbG9va2FoZWFkLnZhbHVlID09PSBrZXl3b3JkO1xuICAgIH1cblxuICAgIC8vIFJldHVybiB0cnVlIGlmIHRoZSBuZXh0IHRva2VuIG1hdGNoZXMgdGhlIHNwZWNpZmllZCBjb250ZXh0dWFsIGtleXdvcmRcbiAgICAvLyAod2hlcmUgYW4gaWRlbnRpZmllciBpcyBzb21ldGltZXMgYSBrZXl3b3JkIGRlcGVuZGluZyBvbiB0aGUgY29udGV4dClcblxuICAgIGZ1bmN0aW9uIG1hdGNoQ29udGV4dHVhbEtleXdvcmQoa2V5d29yZCkge1xuICAgICAgICByZXR1cm4gbG9va2FoZWFkLnR5cGUgPT09IFRva2VuLklkZW50aWZpZXIgJiYgbG9va2FoZWFkLnZhbHVlID09PSBrZXl3b3JkO1xuICAgIH1cblxuICAgIC8vIFJldHVybiB0cnVlIGlmIHRoZSBuZXh0IHRva2VuIGlzIGFuIGFzc2lnbm1lbnQgb3BlcmF0b3JcblxuICAgIGZ1bmN0aW9uIG1hdGNoQXNzaWduKCkge1xuICAgICAgICB2YXIgb3A7XG5cbiAgICAgICAgaWYgKGxvb2thaGVhZC50eXBlICE9PSBUb2tlbi5QdW5jdHVhdG9yKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgb3AgPSBsb29rYWhlYWQudmFsdWU7XG4gICAgICAgIHJldHVybiBvcCA9PT0gJz0nIHx8XG4gICAgICAgICAgICBvcCA9PT0gJyo9JyB8fFxuICAgICAgICAgICAgb3AgPT09ICcvPScgfHxcbiAgICAgICAgICAgIG9wID09PSAnJT0nIHx8XG4gICAgICAgICAgICBvcCA9PT0gJys9JyB8fFxuICAgICAgICAgICAgb3AgPT09ICctPScgfHxcbiAgICAgICAgICAgIG9wID09PSAnPDw9JyB8fFxuICAgICAgICAgICAgb3AgPT09ICc+Pj0nIHx8XG4gICAgICAgICAgICBvcCA9PT0gJz4+Pj0nIHx8XG4gICAgICAgICAgICBvcCA9PT0gJyY9JyB8fFxuICAgICAgICAgICAgb3AgPT09ICdePScgfHxcbiAgICAgICAgICAgIG9wID09PSAnfD0nO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNvbnN1bWVTZW1pY29sb24oKSB7XG4gICAgICAgIC8vIENhdGNoIHRoZSB2ZXJ5IGNvbW1vbiBjYXNlIGZpcnN0OiBpbW1lZGlhdGVseSBhIHNlbWljb2xvbiAoVSswMDNCKS5cbiAgICAgICAgaWYgKHNvdXJjZS5jaGFyQ29kZUF0KHN0YXJ0SW5kZXgpID09PSAweDNCIHx8IG1hdGNoKCc7JykpIHtcbiAgICAgICAgICAgIGxleCgpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGhhc0xpbmVUZXJtaW5hdG9yKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGSVhNRShpa2FyaWVuYXRvcik6IHRoaXMgaXMgc2VlbWluZ2x5IGFuIGlzc3VlIGluIHRoZSBwcmV2aW91cyBsb2NhdGlvbiBpbmZvIGNvbnZlbnRpb24uXG4gICAgICAgIGxhc3RJbmRleCA9IHN0YXJ0SW5kZXg7XG4gICAgICAgIGxhc3RMaW5lTnVtYmVyID0gc3RhcnRMaW5lTnVtYmVyO1xuICAgICAgICBsYXN0TGluZVN0YXJ0ID0gc3RhcnRMaW5lU3RhcnQ7XG5cbiAgICAgICAgaWYgKGxvb2thaGVhZC50eXBlICE9PSBUb2tlbi5FT0YgJiYgIW1hdGNoKCd9JykpIHtcbiAgICAgICAgICAgIHRocm93VW5leHBlY3RlZFRva2VuKGxvb2thaGVhZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBDb3ZlciBncmFtbWFyIHN1cHBvcnQuXG4gICAgLy9cbiAgICAvLyBXaGVuIGFuIGFzc2lnbm1lbnQgZXhwcmVzc2lvbiBwb3NpdGlvbiBzdGFydHMgd2l0aCBhbiBsZWZ0IHBhcmVudGhlc2lzLCB0aGUgZGV0ZXJtaW5hdGlvbiBvZiB0aGUgdHlwZVxuICAgIC8vIG9mIHRoZSBzeW50YXggaXMgdG8gYmUgZGVmZXJyZWQgYXJiaXRyYXJpbHkgbG9uZyB1bnRpbCB0aGUgZW5kIG9mIHRoZSBwYXJlbnRoZXNlcyBwYWlyIChwbHVzIGEgbG9va2FoZWFkKVxuICAgIC8vIG9yIHRoZSBmaXJzdCBjb21tYS4gVGhpcyBzaXR1YXRpb24gYWxzbyBkZWZlcnMgdGhlIGRldGVybWluYXRpb24gb2YgYWxsIHRoZSBleHByZXNzaW9ucyBuZXN0ZWQgaW4gdGhlIHBhaXIuXG4gICAgLy9cbiAgICAvLyBUaGVyZSBhcmUgdGhyZWUgcHJvZHVjdGlvbnMgdGhhdCBjYW4gYmUgcGFyc2VkIGluIGEgcGFyZW50aGVzZXMgcGFpciB0aGF0IG5lZWRzIHRvIGJlIGRldGVybWluZWRcbiAgICAvLyBhZnRlciB0aGUgb3V0ZXJtb3N0IHBhaXIgaXMgY2xvc2VkLiBUaGV5IGFyZTpcbiAgICAvL1xuICAgIC8vICAgMS4gQXNzaWdubWVudEV4cHJlc3Npb25cbiAgICAvLyAgIDIuIEJpbmRpbmdFbGVtZW50c1xuICAgIC8vICAgMy4gQXNzaWdubWVudFRhcmdldHNcbiAgICAvL1xuICAgIC8vIEluIG9yZGVyIHRvIGF2b2lkIGV4cG9uZW50aWFsIGJhY2t0cmFja2luZywgd2UgdXNlIHR3byBmbGFncyB0byBkZW5vdGUgaWYgdGhlIHByb2R1Y3Rpb24gY2FuIGJlXG4gICAgLy8gYmluZGluZyBlbGVtZW50IG9yIGFzc2lnbm1lbnQgdGFyZ2V0LlxuICAgIC8vXG4gICAgLy8gVGhlIHRocmVlIHByb2R1Y3Rpb25zIGhhdmUgdGhlIHJlbGF0aW9uc2hpcDpcbiAgICAvL1xuICAgIC8vICAgQmluZGluZ0VsZW1lbnRzIOKKhiBBc3NpZ25tZW50VGFyZ2V0cyDiioYgQXNzaWdubWVudEV4cHJlc3Npb25cbiAgICAvL1xuICAgIC8vIHdpdGggYSBzaW5nbGUgZXhjZXB0aW9uIHRoYXQgQ292ZXJJbml0aWFsaXplZE5hbWUgd2hlbiB1c2VkIGRpcmVjdGx5IGluIGFuIEV4cHJlc3Npb24sIGdlbmVyYXRlc1xuICAgIC8vIGFuIGVhcmx5IGVycm9yLiBUaGVyZWZvcmUsIHdlIG5lZWQgdGhlIHRoaXJkIHN0YXRlLCBmaXJzdENvdmVySW5pdGlhbGl6ZWROYW1lRXJyb3IsIHRvIHRyYWNrIHRoZVxuICAgIC8vIGZpcnN0IHVzYWdlIG9mIENvdmVySW5pdGlhbGl6ZWROYW1lIGFuZCByZXBvcnQgaXQgd2hlbiB3ZSByZWFjaGVkIHRoZSBlbmQgb2YgdGhlIHBhcmVudGhlc2VzIHBhaXIuXG4gICAgLy9cbiAgICAvLyBpc29sYXRlQ292ZXJHcmFtbWFyIGZ1bmN0aW9uIHJ1bnMgdGhlIGdpdmVuIHBhcnNlciBmdW5jdGlvbiB3aXRoIGEgbmV3IGNvdmVyIGdyYW1tYXIgY29udGV4dCwgYW5kIGl0IGRvZXMgbm90XG4gICAgLy8gZWZmZWN0IHRoZSBjdXJyZW50IGZsYWdzLiBUaGlzIG1lYW5zIHRoZSBwcm9kdWN0aW9uIHRoZSBwYXJzZXIgcGFyc2VzIGlzIG9ubHkgdXNlZCBhcyBhbiBleHByZXNzaW9uLiBUaGVyZWZvcmVcbiAgICAvLyB0aGUgQ292ZXJJbml0aWFsaXplZE5hbWUgY2hlY2sgaXMgY29uZHVjdGVkLlxuICAgIC8vXG4gICAgLy8gaW5oZXJpdENvdmVyR3JhbW1hciBmdW5jdGlvbiBydW5zIHRoZSBnaXZlbiBwYXJzZSBmdW5jdGlvbiB3aXRoIGEgbmV3IGNvdmVyIGdyYW1tYXIgY29udGV4dCwgYW5kIGl0IHByb3BhZ2F0ZXNcbiAgICAvLyB0aGUgZmxhZ3Mgb3V0c2lkZSBvZiB0aGUgcGFyc2VyLiBUaGlzIG1lYW5zIHRoZSBwcm9kdWN0aW9uIHRoZSBwYXJzZXIgcGFyc2VzIGlzIHVzZWQgYXMgYSBwYXJ0IG9mIGEgcG90ZW50aWFsXG4gICAgLy8gcGF0dGVybi4gVGhlIENvdmVySW5pdGlhbGl6ZWROYW1lIGNoZWNrIGlzIGRlZmVycmVkLlxuICAgIGZ1bmN0aW9uIGlzb2xhdGVDb3ZlckdyYW1tYXIocGFyc2VyKSB7XG4gICAgICAgIHZhciBvbGRJc0JpbmRpbmdFbGVtZW50ID0gaXNCaW5kaW5nRWxlbWVudCxcbiAgICAgICAgICAgIG9sZElzQXNzaWdubWVudFRhcmdldCA9IGlzQXNzaWdubWVudFRhcmdldCxcbiAgICAgICAgICAgIG9sZEZpcnN0Q292ZXJJbml0aWFsaXplZE5hbWVFcnJvciA9IGZpcnN0Q292ZXJJbml0aWFsaXplZE5hbWVFcnJvcixcbiAgICAgICAgICAgIHJlc3VsdDtcbiAgICAgICAgaXNCaW5kaW5nRWxlbWVudCA9IHRydWU7XG4gICAgICAgIGlzQXNzaWdubWVudFRhcmdldCA9IHRydWU7XG4gICAgICAgIGZpcnN0Q292ZXJJbml0aWFsaXplZE5hbWVFcnJvciA9IG51bGw7XG4gICAgICAgIHJlc3VsdCA9IHBhcnNlcigpO1xuICAgICAgICBpZiAoZmlyc3RDb3ZlckluaXRpYWxpemVkTmFtZUVycm9yICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvd1VuZXhwZWN0ZWRUb2tlbihmaXJzdENvdmVySW5pdGlhbGl6ZWROYW1lRXJyb3IpO1xuICAgICAgICB9XG4gICAgICAgIGlzQmluZGluZ0VsZW1lbnQgPSBvbGRJc0JpbmRpbmdFbGVtZW50O1xuICAgICAgICBpc0Fzc2lnbm1lbnRUYXJnZXQgPSBvbGRJc0Fzc2lnbm1lbnRUYXJnZXQ7XG4gICAgICAgIGZpcnN0Q292ZXJJbml0aWFsaXplZE5hbWVFcnJvciA9IG9sZEZpcnN0Q292ZXJJbml0aWFsaXplZE5hbWVFcnJvcjtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbmhlcml0Q292ZXJHcmFtbWFyKHBhcnNlcikge1xuICAgICAgICB2YXIgb2xkSXNCaW5kaW5nRWxlbWVudCA9IGlzQmluZGluZ0VsZW1lbnQsXG4gICAgICAgICAgICBvbGRJc0Fzc2lnbm1lbnRUYXJnZXQgPSBpc0Fzc2lnbm1lbnRUYXJnZXQsXG4gICAgICAgICAgICBvbGRGaXJzdENvdmVySW5pdGlhbGl6ZWROYW1lRXJyb3IgPSBmaXJzdENvdmVySW5pdGlhbGl6ZWROYW1lRXJyb3IsXG4gICAgICAgICAgICByZXN1bHQ7XG4gICAgICAgIGlzQmluZGluZ0VsZW1lbnQgPSB0cnVlO1xuICAgICAgICBpc0Fzc2lnbm1lbnRUYXJnZXQgPSB0cnVlO1xuICAgICAgICBmaXJzdENvdmVySW5pdGlhbGl6ZWROYW1lRXJyb3IgPSBudWxsO1xuICAgICAgICByZXN1bHQgPSBwYXJzZXIoKTtcbiAgICAgICAgaXNCaW5kaW5nRWxlbWVudCA9IGlzQmluZGluZ0VsZW1lbnQgJiYgb2xkSXNCaW5kaW5nRWxlbWVudDtcbiAgICAgICAgaXNBc3NpZ25tZW50VGFyZ2V0ID0gaXNBc3NpZ25tZW50VGFyZ2V0ICYmIG9sZElzQXNzaWdubWVudFRhcmdldDtcbiAgICAgICAgZmlyc3RDb3ZlckluaXRpYWxpemVkTmFtZUVycm9yID0gb2xkRmlyc3RDb3ZlckluaXRpYWxpemVkTmFtZUVycm9yIHx8IGZpcnN0Q292ZXJJbml0aWFsaXplZE5hbWVFcnJvcjtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZUFycmF5UGF0dGVybigpIHtcbiAgICAgICAgdmFyIG5vZGUgPSBuZXcgTm9kZSgpLCBlbGVtZW50cyA9IFtdLCByZXN0LCByZXN0Tm9kZTtcbiAgICAgICAgZXhwZWN0KCdbJyk7XG5cbiAgICAgICAgd2hpbGUgKCFtYXRjaCgnXScpKSB7XG4gICAgICAgICAgICBpZiAobWF0Y2goJywnKSkge1xuICAgICAgICAgICAgICAgIGxleCgpO1xuICAgICAgICAgICAgICAgIGVsZW1lbnRzLnB1c2gobnVsbCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChtYXRjaCgnLi4uJykpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdE5vZGUgPSBuZXcgTm9kZSgpO1xuICAgICAgICAgICAgICAgICAgICBsZXgoKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzdCA9IHBhcnNlVmFyaWFibGVJZGVudGlmaWVyKCk7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnRzLnB1c2gocmVzdE5vZGUuZmluaXNoUmVzdEVsZW1lbnQocmVzdCkpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50cy5wdXNoKHBhcnNlUGF0dGVybldpdGhEZWZhdWx0KCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIW1hdGNoKCddJykpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KCcsJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgIH1cblxuICAgICAgICBleHBlY3QoJ10nKTtcblxuICAgICAgICByZXR1cm4gbm9kZS5maW5pc2hBcnJheVBhdHRlcm4oZWxlbWVudHMpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlUHJvcGVydHlQYXR0ZXJuKCkge1xuICAgICAgICB2YXIgbm9kZSA9IG5ldyBOb2RlKCksIGtleSwgY29tcHV0ZWQgPSBtYXRjaCgnWycpLCBpbml0O1xuICAgICAgICBpZiAobG9va2FoZWFkLnR5cGUgPT09IFRva2VuLklkZW50aWZpZXIpIHtcbiAgICAgICAgICAgIGtleSA9IHBhcnNlVmFyaWFibGVJZGVudGlmaWVyKCk7XG4gICAgICAgICAgICBpZiAobWF0Y2goJz0nKSkge1xuICAgICAgICAgICAgICAgIGxleCgpO1xuICAgICAgICAgICAgICAgIGluaXQgPSBwYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5vZGUuZmluaXNoUHJvcGVydHkoXG4gICAgICAgICAgICAgICAgICAgICdpbml0Jywga2V5LCBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgbmV3IFdyYXBwaW5nTm9kZShrZXkpLmZpbmlzaEFzc2lnbm1lbnRQYXR0ZXJuKGtleSwgaW5pdCksIGZhbHNlLCBmYWxzZSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKCFtYXRjaCgnOicpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5vZGUuZmluaXNoUHJvcGVydHkoJ2luaXQnLCBrZXksIGZhbHNlLCBrZXksIGZhbHNlLCB0cnVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGtleSA9IHBhcnNlT2JqZWN0UHJvcGVydHlLZXkoKTtcbiAgICAgICAgfVxuICAgICAgICBleHBlY3QoJzonKTtcbiAgICAgICAgaW5pdCA9IHBhcnNlUGF0dGVybldpdGhEZWZhdWx0KCk7XG4gICAgICAgIHJldHVybiBub2RlLmZpbmlzaFByb3BlcnR5KCdpbml0Jywga2V5LCBjb21wdXRlZCwgaW5pdCwgZmFsc2UsIGZhbHNlKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZU9iamVjdFBhdHRlcm4oKSB7XG4gICAgICAgIHZhciBub2RlID0gbmV3IE5vZGUoKSwgcHJvcGVydGllcyA9IFtdO1xuXG4gICAgICAgIGV4cGVjdCgneycpO1xuXG4gICAgICAgIHdoaWxlICghbWF0Y2goJ30nKSkge1xuICAgICAgICAgICAgcHJvcGVydGllcy5wdXNoKHBhcnNlUHJvcGVydHlQYXR0ZXJuKCkpO1xuICAgICAgICAgICAgaWYgKCFtYXRjaCgnfScpKSB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KCcsJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBsZXgoKTtcblxuICAgICAgICByZXR1cm4gbm9kZS5maW5pc2hPYmplY3RQYXR0ZXJuKHByb3BlcnRpZXMpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlUGF0dGVybigpIHtcbiAgICAgICAgaWYgKGxvb2thaGVhZC50eXBlID09PSBUb2tlbi5JZGVudGlmaWVyKSB7XG4gICAgICAgICAgICByZXR1cm4gcGFyc2VWYXJpYWJsZUlkZW50aWZpZXIoKTtcbiAgICAgICAgfSBlbHNlIGlmIChtYXRjaCgnWycpKSB7XG4gICAgICAgICAgICByZXR1cm4gcGFyc2VBcnJheVBhdHRlcm4oKTtcbiAgICAgICAgfSBlbHNlIGlmIChtYXRjaCgneycpKSB7XG4gICAgICAgICAgICByZXR1cm4gcGFyc2VPYmplY3RQYXR0ZXJuKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3dVbmV4cGVjdGVkVG9rZW4obG9va2FoZWFkKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZVBhdHRlcm5XaXRoRGVmYXVsdCgpIHtcbiAgICAgICAgdmFyIHN0YXJ0VG9rZW4gPSBsb29rYWhlYWQsIHBhdHRlcm4sIHJpZ2h0O1xuICAgICAgICBwYXR0ZXJuID0gcGFyc2VQYXR0ZXJuKCk7XG4gICAgICAgIGlmIChtYXRjaCgnPScpKSB7XG4gICAgICAgICAgICBsZXgoKTtcbiAgICAgICAgICAgIHJpZ2h0ID0gaXNvbGF0ZUNvdmVyR3JhbW1hcihwYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uKTtcbiAgICAgICAgICAgIHBhdHRlcm4gPSBuZXcgV3JhcHBpbmdOb2RlKHN0YXJ0VG9rZW4pLmZpbmlzaEFzc2lnbm1lbnRQYXR0ZXJuKHBhdHRlcm4sIHJpZ2h0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcGF0dGVybjtcbiAgICB9XG5cbiAgICAvLyAxMS4xLjQgQXJyYXkgSW5pdGlhbGlzZXJcblxuICAgIGZ1bmN0aW9uIHBhcnNlQXJyYXlJbml0aWFsaXNlcigpIHtcbiAgICAgICAgdmFyIGVsZW1lbnRzID0gW10sIG5vZGUgPSBuZXcgTm9kZSgpLCByZXN0U3ByZWFkO1xuXG4gICAgICAgIGV4cGVjdCgnWycpO1xuXG4gICAgICAgIHdoaWxlICghbWF0Y2goJ10nKSkge1xuICAgICAgICAgICAgaWYgKG1hdGNoKCcsJykpIHtcbiAgICAgICAgICAgICAgICBsZXgoKTtcbiAgICAgICAgICAgICAgICBlbGVtZW50cy5wdXNoKG51bGwpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChtYXRjaCgnLi4uJykpIHtcbiAgICAgICAgICAgICAgICByZXN0U3ByZWFkID0gbmV3IE5vZGUoKTtcbiAgICAgICAgICAgICAgICBsZXgoKTtcbiAgICAgICAgICAgICAgICByZXN0U3ByZWFkLmZpbmlzaFNwcmVhZEVsZW1lbnQoaW5oZXJpdENvdmVyR3JhbW1hcihwYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uKSk7XG5cbiAgICAgICAgICAgICAgICBpZiAoIW1hdGNoKCddJykpIHtcbiAgICAgICAgICAgICAgICAgICAgaXNBc3NpZ25tZW50VGFyZ2V0ID0gaXNCaW5kaW5nRWxlbWVudCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoJywnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxlbWVudHMucHVzaChyZXN0U3ByZWFkKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZWxlbWVudHMucHVzaChpbmhlcml0Q292ZXJHcmFtbWFyKHBhcnNlQXNzaWdubWVudEV4cHJlc3Npb24pKTtcblxuICAgICAgICAgICAgICAgIGlmICghbWF0Y2goJ10nKSkge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoJywnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBsZXgoKTtcblxuICAgICAgICByZXR1cm4gbm9kZS5maW5pc2hBcnJheUV4cHJlc3Npb24oZWxlbWVudHMpO1xuICAgIH1cblxuICAgIC8vIDExLjEuNSBPYmplY3QgSW5pdGlhbGlzZXJcblxuICAgIGZ1bmN0aW9uIHBhcnNlUHJvcGVydHlGdW5jdGlvbihub2RlLCBwYXJhbUluZm8pIHtcbiAgICAgICAgdmFyIHByZXZpb3VzU3RyaWN0LCBib2R5O1xuXG4gICAgICAgIGlzQXNzaWdubWVudFRhcmdldCA9IGlzQmluZGluZ0VsZW1lbnQgPSBmYWxzZTtcblxuICAgICAgICBwcmV2aW91c1N0cmljdCA9IHN0cmljdDtcbiAgICAgICAgYm9keSA9IGlzb2xhdGVDb3ZlckdyYW1tYXIocGFyc2VGdW5jdGlvblNvdXJjZUVsZW1lbnRzKTtcblxuICAgICAgICBpZiAoc3RyaWN0ICYmIHBhcmFtSW5mby5maXJzdFJlc3RyaWN0ZWQpIHtcbiAgICAgICAgICAgIHRvbGVyYXRlVW5leHBlY3RlZFRva2VuKHBhcmFtSW5mby5maXJzdFJlc3RyaWN0ZWQsIHBhcmFtSW5mby5tZXNzYWdlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc3RyaWN0ICYmIHBhcmFtSW5mby5zdHJpY3RlZCkge1xuICAgICAgICAgICAgdG9sZXJhdGVVbmV4cGVjdGVkVG9rZW4ocGFyYW1JbmZvLnN0cmljdGVkLCBwYXJhbUluZm8ubWVzc2FnZSk7XG4gICAgICAgIH1cblxuICAgICAgICBzdHJpY3QgPSBwcmV2aW91c1N0cmljdDtcbiAgICAgICAgcmV0dXJuIG5vZGUuZmluaXNoRnVuY3Rpb25FeHByZXNzaW9uKG51bGwsIHBhcmFtSW5mby5wYXJhbXMsIHBhcmFtSW5mby5kZWZhdWx0cywgYm9keSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VQcm9wZXJ0eU1ldGhvZEZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgcGFyYW1zLCBtZXRob2QsIG5vZGUgPSBuZXcgTm9kZSgpO1xuXG4gICAgICAgIHBhcmFtcyA9IHBhcnNlUGFyYW1zKCk7XG4gICAgICAgIG1ldGhvZCA9IHBhcnNlUHJvcGVydHlGdW5jdGlvbihub2RlLCBwYXJhbXMpO1xuXG4gICAgICAgIHJldHVybiBtZXRob2Q7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VPYmplY3RQcm9wZXJ0eUtleSgpIHtcbiAgICAgICAgdmFyIHRva2VuLCBub2RlID0gbmV3IE5vZGUoKSwgZXhwcjtcblxuICAgICAgICB0b2tlbiA9IGxleCgpO1xuXG4gICAgICAgIC8vIE5vdGU6IFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIG9ubHkgZnJvbSBwYXJzZU9iamVjdFByb3BlcnR5KCksIHdoZXJlXG4gICAgICAgIC8vIEVPRiBhbmQgUHVuY3R1YXRvciB0b2tlbnMgYXJlIGFscmVhZHkgZmlsdGVyZWQgb3V0LlxuXG4gICAgICAgIHN3aXRjaCAodG9rZW4udHlwZSkge1xuICAgICAgICBjYXNlIFRva2VuLlN0cmluZ0xpdGVyYWw6XG4gICAgICAgIGNhc2UgVG9rZW4uTnVtZXJpY0xpdGVyYWw6XG4gICAgICAgICAgICBpZiAoc3RyaWN0ICYmIHRva2VuLm9jdGFsKSB7XG4gICAgICAgICAgICAgICAgdG9sZXJhdGVVbmV4cGVjdGVkVG9rZW4odG9rZW4sIE1lc3NhZ2VzLlN0cmljdE9jdGFsTGl0ZXJhbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbm9kZS5maW5pc2hMaXRlcmFsKHRva2VuKTtcbiAgICAgICAgY2FzZSBUb2tlbi5JZGVudGlmaWVyOlxuICAgICAgICBjYXNlIFRva2VuLkJvb2xlYW5MaXRlcmFsOlxuICAgICAgICBjYXNlIFRva2VuLk51bGxMaXRlcmFsOlxuICAgICAgICBjYXNlIFRva2VuLktleXdvcmQ6XG4gICAgICAgICAgICByZXR1cm4gbm9kZS5maW5pc2hJZGVudGlmaWVyKHRva2VuLnZhbHVlKTtcbiAgICAgICAgY2FzZSBUb2tlbi5QdW5jdHVhdG9yOlxuICAgICAgICAgICAgaWYgKHRva2VuLnZhbHVlID09PSAnWycpIHtcbiAgICAgICAgICAgICAgICBleHByID0gaXNvbGF0ZUNvdmVyR3JhbW1hcihwYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uKTtcbiAgICAgICAgICAgICAgICBleHBlY3QoJ10nKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZXhwcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHRocm93VW5leHBlY3RlZFRva2VuKHRva2VuKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsb29rYWhlYWRQcm9wZXJ0eU5hbWUoKSB7XG4gICAgICAgIHN3aXRjaCAobG9va2FoZWFkLnR5cGUpIHtcbiAgICAgICAgY2FzZSBUb2tlbi5JZGVudGlmaWVyOlxuICAgICAgICBjYXNlIFRva2VuLlN0cmluZ0xpdGVyYWw6XG4gICAgICAgIGNhc2UgVG9rZW4uQm9vbGVhbkxpdGVyYWw6XG4gICAgICAgIGNhc2UgVG9rZW4uTnVsbExpdGVyYWw6XG4gICAgICAgIGNhc2UgVG9rZW4uTnVtZXJpY0xpdGVyYWw6XG4gICAgICAgIGNhc2UgVG9rZW4uS2V5d29yZDpcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICBjYXNlIFRva2VuLlB1bmN0dWF0b3I6XG4gICAgICAgICAgICByZXR1cm4gbG9va2FoZWFkLnZhbHVlID09PSAnWyc7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIFRoaXMgZnVuY3Rpb24gaXMgdG8gdHJ5IHRvIHBhcnNlIGEgTWV0aG9kRGVmaW5pdGlvbiBhcyBkZWZpbmVkIGluIDE0LjMuIEJ1dCBpbiB0aGUgY2FzZSBvZiBvYmplY3QgbGl0ZXJhbHMsXG4gICAgLy8gaXQgbWlnaHQgYmUgY2FsbGVkIGF0IGEgcG9zaXRpb24gd2hlcmUgdGhlcmUgaXMgaW4gZmFjdCBhIHNob3J0IGhhbmQgaWRlbnRpZmllciBwYXR0ZXJuIG9yIGEgZGF0YSBwcm9wZXJ0eS5cbiAgICAvLyBUaGlzIGNhbiBvbmx5IGJlIGRldGVybWluZWQgYWZ0ZXIgd2UgY29uc3VtZWQgdXAgdG8gdGhlIGxlZnQgcGFyZW50aGVzZXMuXG4gICAgLy9cbiAgICAvLyBJbiBvcmRlciB0byBhdm9pZCBiYWNrIHRyYWNraW5nLCBpdCByZXR1cm5zIGBudWxsYCBpZiB0aGUgcG9zaXRpb24gaXMgbm90IGEgTWV0aG9kRGVmaW5pdGlvbiBhbmQgdGhlIGNhbGxlclxuICAgIC8vIGlzIHJlc3BvbnNpYmxlIHRvIHZpc2l0IG90aGVyIG9wdGlvbnMuXG4gICAgZnVuY3Rpb24gdHJ5UGFyc2VNZXRob2REZWZpbml0aW9uKHRva2VuLCBrZXksIGNvbXB1dGVkLCBub2RlKSB7XG4gICAgICAgIHZhciB2YWx1ZSwgb3B0aW9ucywgbWV0aG9kTm9kZTtcblxuICAgICAgICBpZiAodG9rZW4udHlwZSA9PT0gVG9rZW4uSWRlbnRpZmllcikge1xuICAgICAgICAgICAgLy8gY2hlY2sgZm9yIGBnZXRgIGFuZCBgc2V0YDtcblxuICAgICAgICAgICAgaWYgKHRva2VuLnZhbHVlID09PSAnZ2V0JyAmJiBsb29rYWhlYWRQcm9wZXJ0eU5hbWUoKSkge1xuICAgICAgICAgICAgICAgIGNvbXB1dGVkID0gbWF0Y2goJ1snKTtcbiAgICAgICAgICAgICAgICBrZXkgPSBwYXJzZU9iamVjdFByb3BlcnR5S2V5KCk7XG4gICAgICAgICAgICAgICAgbWV0aG9kTm9kZSA9IG5ldyBOb2RlKCk7XG4gICAgICAgICAgICAgICAgZXhwZWN0KCcoJyk7XG4gICAgICAgICAgICAgICAgZXhwZWN0KCcpJyk7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBwYXJzZVByb3BlcnR5RnVuY3Rpb24obWV0aG9kTm9kZSwge1xuICAgICAgICAgICAgICAgICAgICBwYXJhbXM6IFtdLFxuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0czogW10sXG4gICAgICAgICAgICAgICAgICAgIHN0cmljdGVkOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICBmaXJzdFJlc3RyaWN0ZWQ6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IG51bGxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbm9kZS5maW5pc2hQcm9wZXJ0eSgnZ2V0Jywga2V5LCBjb21wdXRlZCwgdmFsdWUsIGZhbHNlLCBmYWxzZSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRva2VuLnZhbHVlID09PSAnc2V0JyAmJiBsb29rYWhlYWRQcm9wZXJ0eU5hbWUoKSkge1xuICAgICAgICAgICAgICAgIGNvbXB1dGVkID0gbWF0Y2goJ1snKTtcbiAgICAgICAgICAgICAgICBrZXkgPSBwYXJzZU9iamVjdFByb3BlcnR5S2V5KCk7XG4gICAgICAgICAgICAgICAgbWV0aG9kTm9kZSA9IG5ldyBOb2RlKCk7XG4gICAgICAgICAgICAgICAgZXhwZWN0KCcoJyk7XG5cbiAgICAgICAgICAgICAgICBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBwYXJhbXM6IFtdLFxuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0Q291bnQ6IDAsXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHRzOiBbXSxcbiAgICAgICAgICAgICAgICAgICAgZmlyc3RSZXN0cmljdGVkOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICBwYXJhbVNldDoge31cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGlmIChtYXRjaCgnKScpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRvbGVyYXRlVW5leHBlY3RlZFRva2VuKGxvb2thaGVhZCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcGFyc2VQYXJhbShvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdENvdW50ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLmRlZmF1bHRzID0gW107XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZXhwZWN0KCcpJyk7XG5cbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHBhcnNlUHJvcGVydHlGdW5jdGlvbihtZXRob2ROb2RlLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbm9kZS5maW5pc2hQcm9wZXJ0eSgnc2V0Jywga2V5LCBjb21wdXRlZCwgdmFsdWUsIGZhbHNlLCBmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobWF0Y2goJygnKSkge1xuICAgICAgICAgICAgdmFsdWUgPSBwYXJzZVByb3BlcnR5TWV0aG9kRnVuY3Rpb24oKTtcbiAgICAgICAgICAgIHJldHVybiBub2RlLmZpbmlzaFByb3BlcnR5KCdpbml0Jywga2V5LCBjb21wdXRlZCwgdmFsdWUsIHRydWUsIGZhbHNlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIE5vdCBhIE1ldGhvZERlZmluaXRpb24uXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNoZWNrUHJvdG8oa2V5LCBjb21wdXRlZCwgaGFzUHJvdG8pIHtcbiAgICAgICAgaWYgKGNvbXB1dGVkID09PSBmYWxzZSAmJiAoa2V5LnR5cGUgPT09IFN5bnRheC5JZGVudGlmaWVyICYmIGtleS5uYW1lID09PSAnX19wcm90b19fJyB8fFxuICAgICAgICAgICAga2V5LnR5cGUgPT09IFN5bnRheC5MaXRlcmFsICYmIGtleS52YWx1ZSA9PT0gJ19fcHJvdG9fXycpKSB7XG4gICAgICAgICAgICBpZiAoaGFzUHJvdG8udmFsdWUpIHtcbiAgICAgICAgICAgICAgICB0b2xlcmF0ZUVycm9yKE1lc3NhZ2VzLkR1cGxpY2F0ZVByb3RvUHJvcGVydHkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBoYXNQcm90by52YWx1ZSA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZU9iamVjdFByb3BlcnR5KGhhc1Byb3RvKSB7XG4gICAgICAgIHZhciB0b2tlbiA9IGxvb2thaGVhZCwgbm9kZSA9IG5ldyBOb2RlKCksIGNvbXB1dGVkLCBrZXksIG1heWJlTWV0aG9kLCB2YWx1ZTtcblxuICAgICAgICBjb21wdXRlZCA9IG1hdGNoKCdbJyk7XG4gICAgICAgIGtleSA9IHBhcnNlT2JqZWN0UHJvcGVydHlLZXkoKTtcbiAgICAgICAgbWF5YmVNZXRob2QgPSB0cnlQYXJzZU1ldGhvZERlZmluaXRpb24odG9rZW4sIGtleSwgY29tcHV0ZWQsIG5vZGUpO1xuXG4gICAgICAgIGlmIChtYXliZU1ldGhvZCkge1xuICAgICAgICAgICAgY2hlY2tQcm90byhtYXliZU1ldGhvZC5rZXksIG1heWJlTWV0aG9kLmNvbXB1dGVkLCBoYXNQcm90byk7XG4gICAgICAgICAgICAvLyBmaW5pc2hlZFxuICAgICAgICAgICAgcmV0dXJuIG1heWJlTWV0aG9kO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gaW5pdCBwcm9wZXJ0eSBvciBzaG9ydCBoYW5kIHByb3BlcnR5LlxuICAgICAgICBjaGVja1Byb3RvKGtleSwgY29tcHV0ZWQsIGhhc1Byb3RvKTtcblxuICAgICAgICBpZiAobWF0Y2goJzonKSkge1xuICAgICAgICAgICAgbGV4KCk7XG4gICAgICAgICAgICB2YWx1ZSA9IGluaGVyaXRDb3ZlckdyYW1tYXIocGFyc2VBc3NpZ25tZW50RXhwcmVzc2lvbik7XG4gICAgICAgICAgICByZXR1cm4gbm9kZS5maW5pc2hQcm9wZXJ0eSgnaW5pdCcsIGtleSwgY29tcHV0ZWQsIHZhbHVlLCBmYWxzZSwgZmFsc2UpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRva2VuLnR5cGUgPT09IFRva2VuLklkZW50aWZpZXIpIHtcbiAgICAgICAgICAgIGlmIChtYXRjaCgnPScpKSB7XG4gICAgICAgICAgICAgICAgZmlyc3RDb3ZlckluaXRpYWxpemVkTmFtZUVycm9yID0gbG9va2FoZWFkO1xuICAgICAgICAgICAgICAgIGxleCgpO1xuICAgICAgICAgICAgICAgIHZhbHVlID0gaXNvbGF0ZUNvdmVyR3JhbW1hcihwYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbm9kZS5maW5pc2hQcm9wZXJ0eSgnaW5pdCcsIGtleSwgY29tcHV0ZWQsXG4gICAgICAgICAgICAgICAgICAgIG5ldyBXcmFwcGluZ05vZGUodG9rZW4pLmZpbmlzaEFzc2lnbm1lbnRQYXR0ZXJuKGtleSwgdmFsdWUpLCBmYWxzZSwgdHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbm9kZS5maW5pc2hQcm9wZXJ0eSgnaW5pdCcsIGtleSwgY29tcHV0ZWQsIGtleSwgZmFsc2UsIHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhyb3dVbmV4cGVjdGVkVG9rZW4obG9va2FoZWFkKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZU9iamVjdEluaXRpYWxpc2VyKCkge1xuICAgICAgICB2YXIgcHJvcGVydGllcyA9IFtdLCBoYXNQcm90byA9IHt2YWx1ZTogZmFsc2V9LCBub2RlID0gbmV3IE5vZGUoKTtcblxuICAgICAgICBleHBlY3QoJ3snKTtcblxuICAgICAgICB3aGlsZSAoIW1hdGNoKCd9JykpIHtcbiAgICAgICAgICAgIHByb3BlcnRpZXMucHVzaChwYXJzZU9iamVjdFByb3BlcnR5KGhhc1Byb3RvKSk7XG5cbiAgICAgICAgICAgIGlmICghbWF0Y2goJ30nKSkge1xuICAgICAgICAgICAgICAgIGV4cGVjdENvbW1hU2VwYXJhdG9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBleHBlY3QoJ30nKTtcblxuICAgICAgICByZXR1cm4gbm9kZS5maW5pc2hPYmplY3RFeHByZXNzaW9uKHByb3BlcnRpZXMpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJlaW50ZXJwcmV0RXhwcmVzc2lvbkFzUGF0dGVybihleHByKSB7XG4gICAgICAgIHZhciBpO1xuICAgICAgICBzd2l0Y2ggKGV4cHIudHlwZSkge1xuICAgICAgICBjYXNlIFN5bnRheC5JZGVudGlmaWVyOlxuICAgICAgICBjYXNlIFN5bnRheC5NZW1iZXJFeHByZXNzaW9uOlxuICAgICAgICBjYXNlIFN5bnRheC5SZXN0RWxlbWVudDpcbiAgICAgICAgY2FzZSBTeW50YXguQXNzaWdubWVudFBhdHRlcm46XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBTeW50YXguU3ByZWFkRWxlbWVudDpcbiAgICAgICAgICAgIGV4cHIudHlwZSA9IFN5bnRheC5SZXN0RWxlbWVudDtcbiAgICAgICAgICAgIHJlaW50ZXJwcmV0RXhwcmVzc2lvbkFzUGF0dGVybihleHByLmFyZ3VtZW50KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFN5bnRheC5BcnJheUV4cHJlc3Npb246XG4gICAgICAgICAgICBleHByLnR5cGUgPSBTeW50YXguQXJyYXlQYXR0ZXJuO1xuICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGV4cHIuZWxlbWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoZXhwci5lbGVtZW50c1tpXSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICByZWludGVycHJldEV4cHJlc3Npb25Bc1BhdHRlcm4oZXhwci5lbGVtZW50c1tpXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgU3ludGF4Lk9iamVjdEV4cHJlc3Npb246XG4gICAgICAgICAgICBleHByLnR5cGUgPSBTeW50YXguT2JqZWN0UGF0dGVybjtcbiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBleHByLnByb3BlcnRpZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICByZWludGVycHJldEV4cHJlc3Npb25Bc1BhdHRlcm4oZXhwci5wcm9wZXJ0aWVzW2ldLnZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFN5bnRheC5Bc3NpZ25tZW50RXhwcmVzc2lvbjpcbiAgICAgICAgICAgIGV4cHIudHlwZSA9IFN5bnRheC5Bc3NpZ25tZW50UGF0dGVybjtcbiAgICAgICAgICAgIHJlaW50ZXJwcmV0RXhwcmVzc2lvbkFzUGF0dGVybihleHByLmxlZnQpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAvLyBBbGxvdyBvdGhlciBub2RlIHR5cGUgZm9yIHRvbGVyYW50IHBhcnNpbmcuXG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlVGVtcGxhdGVFbGVtZW50KG9wdGlvbikge1xuICAgICAgICB2YXIgbm9kZSwgdG9rZW47XG5cbiAgICAgICAgaWYgKGxvb2thaGVhZC50eXBlICE9PSBUb2tlbi5UZW1wbGF0ZSB8fCAob3B0aW9uLmhlYWQgJiYgIWxvb2thaGVhZC5oZWFkKSkge1xuICAgICAgICAgICAgdGhyb3dVbmV4cGVjdGVkVG9rZW4oKTtcbiAgICAgICAgfVxuXG4gICAgICAgIG5vZGUgPSBuZXcgTm9kZSgpO1xuICAgICAgICB0b2tlbiA9IGxleCgpO1xuXG4gICAgICAgIHJldHVybiBub2RlLmZpbmlzaFRlbXBsYXRlRWxlbWVudCh7IHJhdzogdG9rZW4udmFsdWUucmF3LCBjb29rZWQ6IHRva2VuLnZhbHVlLmNvb2tlZCB9LCB0b2tlbi50YWlsKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZVRlbXBsYXRlTGl0ZXJhbCgpIHtcbiAgICAgICAgdmFyIHF1YXNpLCBxdWFzaXMsIGV4cHJlc3Npb25zLCBub2RlID0gbmV3IE5vZGUoKTtcblxuICAgICAgICBxdWFzaSA9IHBhcnNlVGVtcGxhdGVFbGVtZW50KHsgaGVhZDogdHJ1ZSB9KTtcbiAgICAgICAgcXVhc2lzID0gWyBxdWFzaSBdO1xuICAgICAgICBleHByZXNzaW9ucyA9IFtdO1xuXG4gICAgICAgIHdoaWxlICghcXVhc2kudGFpbCkge1xuICAgICAgICAgICAgZXhwcmVzc2lvbnMucHVzaChwYXJzZUV4cHJlc3Npb24oKSk7XG4gICAgICAgICAgICBxdWFzaSA9IHBhcnNlVGVtcGxhdGVFbGVtZW50KHsgaGVhZDogZmFsc2UgfSk7XG4gICAgICAgICAgICBxdWFzaXMucHVzaChxdWFzaSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbm9kZS5maW5pc2hUZW1wbGF0ZUxpdGVyYWwocXVhc2lzLCBleHByZXNzaW9ucyk7XG4gICAgfVxuXG4gICAgLy8gMTEuMS42IFRoZSBHcm91cGluZyBPcGVyYXRvclxuXG4gICAgZnVuY3Rpb24gcGFyc2VHcm91cEV4cHJlc3Npb24oKSB7XG4gICAgICAgIHZhciBleHByLCBleHByZXNzaW9ucywgc3RhcnRUb2tlbiwgaTtcblxuICAgICAgICBleHBlY3QoJygnKTtcblxuICAgICAgICBpZiAobWF0Y2goJyknKSkge1xuICAgICAgICAgICAgbGV4KCk7XG4gICAgICAgICAgICBpZiAoIW1hdGNoKCc9PicpKSB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KCc9PicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBQbGFjZUhvbGRlcnMuQXJyb3dQYXJhbWV0ZXJQbGFjZUhvbGRlcixcbiAgICAgICAgICAgICAgICBwYXJhbXM6IFtdXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgc3RhcnRUb2tlbiA9IGxvb2thaGVhZDtcbiAgICAgICAgaWYgKG1hdGNoKCcuLi4nKSkge1xuICAgICAgICAgICAgZXhwciA9IHBhcnNlUmVzdEVsZW1lbnQoKTtcbiAgICAgICAgICAgIGV4cGVjdCgnKScpO1xuICAgICAgICAgICAgaWYgKCFtYXRjaCgnPT4nKSkge1xuICAgICAgICAgICAgICAgIGV4cGVjdCgnPT4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgdHlwZTogUGxhY2VIb2xkZXJzLkFycm93UGFyYW1ldGVyUGxhY2VIb2xkZXIsXG4gICAgICAgICAgICAgICAgcGFyYW1zOiBbZXhwcl1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICBpc0JpbmRpbmdFbGVtZW50ID0gdHJ1ZTtcbiAgICAgICAgZXhwciA9IGluaGVyaXRDb3ZlckdyYW1tYXIocGFyc2VBc3NpZ25tZW50RXhwcmVzc2lvbik7XG5cbiAgICAgICAgaWYgKG1hdGNoKCcsJykpIHtcbiAgICAgICAgICAgIGlzQXNzaWdubWVudFRhcmdldCA9IGZhbHNlO1xuICAgICAgICAgICAgZXhwcmVzc2lvbnMgPSBbZXhwcl07XG5cbiAgICAgICAgICAgIHdoaWxlIChzdGFydEluZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFtYXRjaCgnLCcpKSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXgoKTtcblxuICAgICAgICAgICAgICAgIGlmIChtYXRjaCgnLi4uJykpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc0JpbmRpbmdFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvd1VuZXhwZWN0ZWRUb2tlbihsb29rYWhlYWQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb25zLnB1c2gocGFyc2VSZXN0RWxlbWVudCgpKTtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KCcpJyk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghbWF0Y2goJz0+JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdCgnPT4nKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpc0JpbmRpbmdFbGVtZW50ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBleHByZXNzaW9ucy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVpbnRlcnByZXRFeHByZXNzaW9uQXNQYXR0ZXJuKGV4cHJlc3Npb25zW2ldKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogUGxhY2VIb2xkZXJzLkFycm93UGFyYW1ldGVyUGxhY2VIb2xkZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJhbXM6IGV4cHJlc3Npb25zXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZXhwcmVzc2lvbnMucHVzaChpbmhlcml0Q292ZXJHcmFtbWFyKHBhcnNlQXNzaWdubWVudEV4cHJlc3Npb24pKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZXhwciA9IG5ldyBXcmFwcGluZ05vZGUoc3RhcnRUb2tlbikuZmluaXNoU2VxdWVuY2VFeHByZXNzaW9uKGV4cHJlc3Npb25zKTtcbiAgICAgICAgfVxuXG5cbiAgICAgICAgZXhwZWN0KCcpJyk7XG5cbiAgICAgICAgaWYgKG1hdGNoKCc9PicpKSB7XG4gICAgICAgICAgICBpZiAoIWlzQmluZGluZ0VsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICB0aHJvd1VuZXhwZWN0ZWRUb2tlbihsb29rYWhlYWQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoZXhwci50eXBlID09PSBTeW50YXguU2VxdWVuY2VFeHByZXNzaW9uKSB7XG4gICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGV4cHIuZXhwcmVzc2lvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgcmVpbnRlcnByZXRFeHByZXNzaW9uQXNQYXR0ZXJuKGV4cHIuZXhwcmVzc2lvbnNbaV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVpbnRlcnByZXRFeHByZXNzaW9uQXNQYXR0ZXJuKGV4cHIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBleHByID0ge1xuICAgICAgICAgICAgICAgIHR5cGU6IFBsYWNlSG9sZGVycy5BcnJvd1BhcmFtZXRlclBsYWNlSG9sZGVyLFxuICAgICAgICAgICAgICAgIHBhcmFtczogZXhwci50eXBlID09PSBTeW50YXguU2VxdWVuY2VFeHByZXNzaW9uID8gZXhwci5leHByZXNzaW9ucyA6IFtleHByXVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBpc0JpbmRpbmdFbGVtZW50ID0gZmFsc2U7XG4gICAgICAgIHJldHVybiBleHByO1xuICAgIH1cblxuXG4gICAgLy8gMTEuMSBQcmltYXJ5IEV4cHJlc3Npb25zXG5cbiAgICBmdW5jdGlvbiBwYXJzZVByaW1hcnlFeHByZXNzaW9uKCkge1xuICAgICAgICB2YXIgdHlwZSwgdG9rZW4sIGV4cHIsIG5vZGU7XG5cbiAgICAgICAgaWYgKG1hdGNoKCcoJykpIHtcbiAgICAgICAgICAgIGlzQmluZGluZ0VsZW1lbnQgPSBmYWxzZTtcbiAgICAgICAgICAgIHJldHVybiBpbmhlcml0Q292ZXJHcmFtbWFyKHBhcnNlR3JvdXBFeHByZXNzaW9uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChtYXRjaCgnWycpKSB7XG4gICAgICAgICAgICByZXR1cm4gaW5oZXJpdENvdmVyR3JhbW1hcihwYXJzZUFycmF5SW5pdGlhbGlzZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG1hdGNoKCd7JykpIHtcbiAgICAgICAgICAgIHJldHVybiBpbmhlcml0Q292ZXJHcmFtbWFyKHBhcnNlT2JqZWN0SW5pdGlhbGlzZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgdHlwZSA9IGxvb2thaGVhZC50eXBlO1xuICAgICAgICBub2RlID0gbmV3IE5vZGUoKTtcblxuICAgICAgICBpZiAodHlwZSA9PT0gVG9rZW4uSWRlbnRpZmllcikge1xuICAgICAgICAgICAgZXhwciA9IG5vZGUuZmluaXNoSWRlbnRpZmllcihsZXgoKS52YWx1ZSk7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gVG9rZW4uU3RyaW5nTGl0ZXJhbCB8fCB0eXBlID09PSBUb2tlbi5OdW1lcmljTGl0ZXJhbCkge1xuICAgICAgICAgICAgaXNBc3NpZ25tZW50VGFyZ2V0ID0gaXNCaW5kaW5nRWxlbWVudCA9IGZhbHNlO1xuICAgICAgICAgICAgaWYgKHN0cmljdCAmJiBsb29rYWhlYWQub2N0YWwpIHtcbiAgICAgICAgICAgICAgICB0b2xlcmF0ZVVuZXhwZWN0ZWRUb2tlbihsb29rYWhlYWQsIE1lc3NhZ2VzLlN0cmljdE9jdGFsTGl0ZXJhbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBleHByID0gbm9kZS5maW5pc2hMaXRlcmFsKGxleCgpKTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlID09PSBUb2tlbi5LZXl3b3JkKSB7XG4gICAgICAgICAgICBpc0Fzc2lnbm1lbnRUYXJnZXQgPSBpc0JpbmRpbmdFbGVtZW50ID0gZmFsc2U7XG4gICAgICAgICAgICBpZiAobWF0Y2hLZXl3b3JkKCdmdW5jdGlvbicpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlRnVuY3Rpb25FeHByZXNzaW9uKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWF0Y2hLZXl3b3JkKCd0aGlzJykpIHtcbiAgICAgICAgICAgICAgICBsZXgoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbm9kZS5maW5pc2hUaGlzRXhwcmVzc2lvbigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1hdGNoS2V5d29yZCgnY2xhc3MnKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZUNsYXNzRXhwcmVzc2lvbigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3dVbmV4cGVjdGVkVG9rZW4obGV4KCkpO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09IFRva2VuLkJvb2xlYW5MaXRlcmFsKSB7XG4gICAgICAgICAgICBpc0Fzc2lnbm1lbnRUYXJnZXQgPSBpc0JpbmRpbmdFbGVtZW50ID0gZmFsc2U7XG4gICAgICAgICAgICB0b2tlbiA9IGxleCgpO1xuICAgICAgICAgICAgdG9rZW4udmFsdWUgPSAodG9rZW4udmFsdWUgPT09ICd0cnVlJyk7XG4gICAgICAgICAgICBleHByID0gbm9kZS5maW5pc2hMaXRlcmFsKHRva2VuKTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlID09PSBUb2tlbi5OdWxsTGl0ZXJhbCkge1xuICAgICAgICAgICAgaXNBc3NpZ25tZW50VGFyZ2V0ID0gaXNCaW5kaW5nRWxlbWVudCA9IGZhbHNlO1xuICAgICAgICAgICAgdG9rZW4gPSBsZXgoKTtcbiAgICAgICAgICAgIHRva2VuLnZhbHVlID0gbnVsbDtcbiAgICAgICAgICAgIGV4cHIgPSBub2RlLmZpbmlzaExpdGVyYWwodG9rZW4pO1xuICAgICAgICB9IGVsc2UgaWYgKG1hdGNoKCcvJykgfHwgbWF0Y2goJy89JykpIHtcbiAgICAgICAgICAgIGlzQXNzaWdubWVudFRhcmdldCA9IGlzQmluZGluZ0VsZW1lbnQgPSBmYWxzZTtcbiAgICAgICAgICAgIGluZGV4ID0gc3RhcnRJbmRleDtcblxuICAgICAgICAgICAgaWYgKHR5cGVvZiBleHRyYS50b2tlbnMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgdG9rZW4gPSBjb2xsZWN0UmVnZXgoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdG9rZW4gPSBzY2FuUmVnRXhwKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXgoKTtcbiAgICAgICAgICAgIGV4cHIgPSBub2RlLmZpbmlzaExpdGVyYWwodG9rZW4pO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09IFRva2VuLlRlbXBsYXRlKSB7XG4gICAgICAgICAgICBleHByID0gcGFyc2VUZW1wbGF0ZUxpdGVyYWwoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93VW5leHBlY3RlZFRva2VuKGxleCgpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBleHByO1xuICAgIH1cblxuICAgIC8vIDExLjIgTGVmdC1IYW5kLVNpZGUgRXhwcmVzc2lvbnNcblxuICAgIGZ1bmN0aW9uIHBhcnNlQXJndW1lbnRzKCkge1xuICAgICAgICB2YXIgYXJncyA9IFtdO1xuXG4gICAgICAgIGV4cGVjdCgnKCcpO1xuXG4gICAgICAgIGlmICghbWF0Y2goJyknKSkge1xuICAgICAgICAgICAgd2hpbGUgKHN0YXJ0SW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBhcmdzLnB1c2goaXNvbGF0ZUNvdmVyR3JhbW1hcihwYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uKSk7XG4gICAgICAgICAgICAgICAgaWYgKG1hdGNoKCcpJykpIHtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGV4cGVjdENvbW1hU2VwYXJhdG9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBleHBlY3QoJyknKTtcblxuICAgICAgICByZXR1cm4gYXJncztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZU5vbkNvbXB1dGVkUHJvcGVydHkoKSB7XG4gICAgICAgIHZhciB0b2tlbiwgbm9kZSA9IG5ldyBOb2RlKCk7XG5cbiAgICAgICAgdG9rZW4gPSBsZXgoKTtcblxuICAgICAgICBpZiAoIWlzSWRlbnRpZmllck5hbWUodG9rZW4pKSB7XG4gICAgICAgICAgICB0aHJvd1VuZXhwZWN0ZWRUb2tlbih0b2tlbik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbm9kZS5maW5pc2hJZGVudGlmaWVyKHRva2VuLnZhbHVlKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZU5vbkNvbXB1dGVkTWVtYmVyKCkge1xuICAgICAgICBleHBlY3QoJy4nKTtcblxuICAgICAgICByZXR1cm4gcGFyc2VOb25Db21wdXRlZFByb3BlcnR5KCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VDb21wdXRlZE1lbWJlcigpIHtcbiAgICAgICAgdmFyIGV4cHI7XG5cbiAgICAgICAgZXhwZWN0KCdbJyk7XG5cbiAgICAgICAgZXhwciA9IGlzb2xhdGVDb3ZlckdyYW1tYXIocGFyc2VFeHByZXNzaW9uKTtcblxuICAgICAgICBleHBlY3QoJ10nKTtcblxuICAgICAgICByZXR1cm4gZXhwcjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZU5ld0V4cHJlc3Npb24oKSB7XG4gICAgICAgIHZhciBjYWxsZWUsIGFyZ3MsIG5vZGUgPSBuZXcgTm9kZSgpO1xuXG4gICAgICAgIGV4cGVjdEtleXdvcmQoJ25ldycpO1xuICAgICAgICBjYWxsZWUgPSBpc29sYXRlQ292ZXJHcmFtbWFyKHBhcnNlTGVmdEhhbmRTaWRlRXhwcmVzc2lvbik7XG4gICAgICAgIGFyZ3MgPSBtYXRjaCgnKCcpID8gcGFyc2VBcmd1bWVudHMoKSA6IFtdO1xuXG4gICAgICAgIGlzQXNzaWdubWVudFRhcmdldCA9IGlzQmluZGluZ0VsZW1lbnQgPSBmYWxzZTtcblxuICAgICAgICByZXR1cm4gbm9kZS5maW5pc2hOZXdFeHByZXNzaW9uKGNhbGxlZSwgYXJncyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VMZWZ0SGFuZFNpZGVFeHByZXNzaW9uQWxsb3dDYWxsKCkge1xuICAgICAgICB2YXIgcXVhc2ksIGV4cHIsIGFyZ3MsIHByb3BlcnR5LCBzdGFydFRva2VuLCBwcmV2aW91c0FsbG93SW4gPSBzdGF0ZS5hbGxvd0luO1xuXG4gICAgICAgIHN0YXJ0VG9rZW4gPSBsb29rYWhlYWQ7XG4gICAgICAgIHN0YXRlLmFsbG93SW4gPSB0cnVlO1xuXG4gICAgICAgIGlmIChtYXRjaEtleXdvcmQoJ3N1cGVyJykgJiYgc3RhdGUuaW5GdW5jdGlvbkJvZHkpIHtcbiAgICAgICAgICAgIGV4cHIgPSBuZXcgTm9kZSgpO1xuICAgICAgICAgICAgbGV4KCk7XG4gICAgICAgICAgICBleHByID0gZXhwci5maW5pc2hTdXBlcigpO1xuICAgICAgICAgICAgaWYgKCFtYXRjaCgnKCcpICYmICFtYXRjaCgnLicpICYmICFtYXRjaCgnWycpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3dVbmV4cGVjdGVkVG9rZW4obG9va2FoZWFkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGV4cHIgPSBpbmhlcml0Q292ZXJHcmFtbWFyKG1hdGNoS2V5d29yZCgnbmV3JykgPyBwYXJzZU5ld0V4cHJlc3Npb24gOiBwYXJzZVByaW1hcnlFeHByZXNzaW9uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoOzspIHtcbiAgICAgICAgICAgIGlmIChtYXRjaCgnLicpKSB7XG4gICAgICAgICAgICAgICAgaXNCaW5kaW5nRWxlbWVudCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGlzQXNzaWdubWVudFRhcmdldCA9IHRydWU7XG4gICAgICAgICAgICAgICAgcHJvcGVydHkgPSBwYXJzZU5vbkNvbXB1dGVkTWVtYmVyKCk7XG4gICAgICAgICAgICAgICAgZXhwciA9IG5ldyBXcmFwcGluZ05vZGUoc3RhcnRUb2tlbikuZmluaXNoTWVtYmVyRXhwcmVzc2lvbignLicsIGV4cHIsIHByb3BlcnR5KTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAobWF0Y2goJygnKSkge1xuICAgICAgICAgICAgICAgIGlzQmluZGluZ0VsZW1lbnQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBpc0Fzc2lnbm1lbnRUYXJnZXQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBhcmdzID0gcGFyc2VBcmd1bWVudHMoKTtcbiAgICAgICAgICAgICAgICBleHByID0gbmV3IFdyYXBwaW5nTm9kZShzdGFydFRva2VuKS5maW5pc2hDYWxsRXhwcmVzc2lvbihleHByLCBhcmdzKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAobWF0Y2goJ1snKSkge1xuICAgICAgICAgICAgICAgIGlzQmluZGluZ0VsZW1lbnQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBpc0Fzc2lnbm1lbnRUYXJnZXQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHByb3BlcnR5ID0gcGFyc2VDb21wdXRlZE1lbWJlcigpO1xuICAgICAgICAgICAgICAgIGV4cHIgPSBuZXcgV3JhcHBpbmdOb2RlKHN0YXJ0VG9rZW4pLmZpbmlzaE1lbWJlckV4cHJlc3Npb24oJ1snLCBleHByLCBwcm9wZXJ0eSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGxvb2thaGVhZC50eXBlID09PSBUb2tlbi5UZW1wbGF0ZSAmJiBsb29rYWhlYWQuaGVhZCkge1xuICAgICAgICAgICAgICAgIHF1YXNpID0gcGFyc2VUZW1wbGF0ZUxpdGVyYWwoKTtcbiAgICAgICAgICAgICAgICBleHByID0gbmV3IFdyYXBwaW5nTm9kZShzdGFydFRva2VuKS5maW5pc2hUYWdnZWRUZW1wbGF0ZUV4cHJlc3Npb24oZXhwciwgcXVhc2kpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzdGF0ZS5hbGxvd0luID0gcHJldmlvdXNBbGxvd0luO1xuXG4gICAgICAgIHJldHVybiBleHByO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlTGVmdEhhbmRTaWRlRXhwcmVzc2lvbigpIHtcbiAgICAgICAgdmFyIHF1YXNpLCBleHByLCBwcm9wZXJ0eSwgc3RhcnRUb2tlbjtcbiAgICAgICAgYXNzZXJ0KHN0YXRlLmFsbG93SW4sICdjYWxsZWUgb2YgbmV3IGV4cHJlc3Npb24gYWx3YXlzIGFsbG93IGluIGtleXdvcmQuJyk7XG5cbiAgICAgICAgc3RhcnRUb2tlbiA9IGxvb2thaGVhZDtcblxuICAgICAgICBpZiAobWF0Y2hLZXl3b3JkKCdzdXBlcicpICYmIHN0YXRlLmluRnVuY3Rpb25Cb2R5KSB7XG4gICAgICAgICAgICBleHByID0gbmV3IE5vZGUoKTtcbiAgICAgICAgICAgIGxleCgpO1xuICAgICAgICAgICAgZXhwciA9IGV4cHIuZmluaXNoU3VwZXIoKTtcbiAgICAgICAgICAgIGlmICghbWF0Y2goJ1snKSAmJiAhbWF0Y2goJy4nKSkge1xuICAgICAgICAgICAgICAgIHRocm93VW5leHBlY3RlZFRva2VuKGxvb2thaGVhZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBleHByID0gaW5oZXJpdENvdmVyR3JhbW1hcihtYXRjaEtleXdvcmQoJ25ldycpID8gcGFyc2VOZXdFeHByZXNzaW9uIDogcGFyc2VQcmltYXJ5RXhwcmVzc2lvbik7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKDs7KSB7XG4gICAgICAgICAgICBpZiAobWF0Y2goJ1snKSkge1xuICAgICAgICAgICAgICAgIGlzQmluZGluZ0VsZW1lbnQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBpc0Fzc2lnbm1lbnRUYXJnZXQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHByb3BlcnR5ID0gcGFyc2VDb21wdXRlZE1lbWJlcigpO1xuICAgICAgICAgICAgICAgIGV4cHIgPSBuZXcgV3JhcHBpbmdOb2RlKHN0YXJ0VG9rZW4pLmZpbmlzaE1lbWJlckV4cHJlc3Npb24oJ1snLCBleHByLCBwcm9wZXJ0eSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKG1hdGNoKCcuJykpIHtcbiAgICAgICAgICAgICAgICBpc0JpbmRpbmdFbGVtZW50ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgaXNBc3NpZ25tZW50VGFyZ2V0ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBwcm9wZXJ0eSA9IHBhcnNlTm9uQ29tcHV0ZWRNZW1iZXIoKTtcbiAgICAgICAgICAgICAgICBleHByID0gbmV3IFdyYXBwaW5nTm9kZShzdGFydFRva2VuKS5maW5pc2hNZW1iZXJFeHByZXNzaW9uKCcuJywgZXhwciwgcHJvcGVydHkpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChsb29rYWhlYWQudHlwZSA9PT0gVG9rZW4uVGVtcGxhdGUgJiYgbG9va2FoZWFkLmhlYWQpIHtcbiAgICAgICAgICAgICAgICBxdWFzaSA9IHBhcnNlVGVtcGxhdGVMaXRlcmFsKCk7XG4gICAgICAgICAgICAgICAgZXhwciA9IG5ldyBXcmFwcGluZ05vZGUoc3RhcnRUb2tlbikuZmluaXNoVGFnZ2VkVGVtcGxhdGVFeHByZXNzaW9uKGV4cHIsIHF1YXNpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGV4cHI7XG4gICAgfVxuXG4gICAgLy8gMTEuMyBQb3N0Zml4IEV4cHJlc3Npb25zXG5cbiAgICBmdW5jdGlvbiBwYXJzZVBvc3RmaXhFeHByZXNzaW9uKCkge1xuICAgICAgICB2YXIgZXhwciwgdG9rZW4sIHN0YXJ0VG9rZW4gPSBsb29rYWhlYWQ7XG5cbiAgICAgICAgZXhwciA9IGluaGVyaXRDb3ZlckdyYW1tYXIocGFyc2VMZWZ0SGFuZFNpZGVFeHByZXNzaW9uQWxsb3dDYWxsKTtcblxuICAgICAgICBpZiAoIWhhc0xpbmVUZXJtaW5hdG9yICYmIGxvb2thaGVhZC50eXBlID09PSBUb2tlbi5QdW5jdHVhdG9yKSB7XG4gICAgICAgICAgICBpZiAobWF0Y2goJysrJykgfHwgbWF0Y2goJy0tJykpIHtcbiAgICAgICAgICAgICAgICAvLyAxMS4zLjEsIDExLjMuMlxuICAgICAgICAgICAgICAgIGlmIChzdHJpY3QgJiYgZXhwci50eXBlID09PSBTeW50YXguSWRlbnRpZmllciAmJiBpc1Jlc3RyaWN0ZWRXb3JkKGV4cHIubmFtZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdG9sZXJhdGVFcnJvcihNZXNzYWdlcy5TdHJpY3RMSFNQb3N0Zml4KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoIWlzQXNzaWdubWVudFRhcmdldCkge1xuICAgICAgICAgICAgICAgICAgICB0b2xlcmF0ZUVycm9yKE1lc3NhZ2VzLkludmFsaWRMSFNJbkFzc2lnbm1lbnQpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlzQXNzaWdubWVudFRhcmdldCA9IGlzQmluZGluZ0VsZW1lbnQgPSBmYWxzZTtcblxuICAgICAgICAgICAgICAgIHRva2VuID0gbGV4KCk7XG4gICAgICAgICAgICAgICAgZXhwciA9IG5ldyBXcmFwcGluZ05vZGUoc3RhcnRUb2tlbikuZmluaXNoUG9zdGZpeEV4cHJlc3Npb24odG9rZW4udmFsdWUsIGV4cHIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGV4cHI7XG4gICAgfVxuXG4gICAgLy8gMTEuNCBVbmFyeSBPcGVyYXRvcnNcblxuICAgIGZ1bmN0aW9uIHBhcnNlVW5hcnlFeHByZXNzaW9uKCkge1xuICAgICAgICB2YXIgdG9rZW4sIGV4cHIsIHN0YXJ0VG9rZW47XG5cbiAgICAgICAgaWYgKGxvb2thaGVhZC50eXBlICE9PSBUb2tlbi5QdW5jdHVhdG9yICYmIGxvb2thaGVhZC50eXBlICE9PSBUb2tlbi5LZXl3b3JkKSB7XG4gICAgICAgICAgICBleHByID0gcGFyc2VQb3N0Zml4RXhwcmVzc2lvbigpO1xuICAgICAgICB9IGVsc2UgaWYgKG1hdGNoKCcrKycpIHx8IG1hdGNoKCctLScpKSB7XG4gICAgICAgICAgICBzdGFydFRva2VuID0gbG9va2FoZWFkO1xuICAgICAgICAgICAgdG9rZW4gPSBsZXgoKTtcbiAgICAgICAgICAgIGV4cHIgPSBpbmhlcml0Q292ZXJHcmFtbWFyKHBhcnNlVW5hcnlFeHByZXNzaW9uKTtcbiAgICAgICAgICAgIC8vIDExLjQuNCwgMTEuNC41XG4gICAgICAgICAgICBpZiAoc3RyaWN0ICYmIGV4cHIudHlwZSA9PT0gU3ludGF4LklkZW50aWZpZXIgJiYgaXNSZXN0cmljdGVkV29yZChleHByLm5hbWUpKSB7XG4gICAgICAgICAgICAgICAgdG9sZXJhdGVFcnJvcihNZXNzYWdlcy5TdHJpY3RMSFNQcmVmaXgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIWlzQXNzaWdubWVudFRhcmdldCkge1xuICAgICAgICAgICAgICAgIHRvbGVyYXRlRXJyb3IoTWVzc2FnZXMuSW52YWxpZExIU0luQXNzaWdubWVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBleHByID0gbmV3IFdyYXBwaW5nTm9kZShzdGFydFRva2VuKS5maW5pc2hVbmFyeUV4cHJlc3Npb24odG9rZW4udmFsdWUsIGV4cHIpO1xuICAgICAgICAgICAgaXNBc3NpZ25tZW50VGFyZ2V0ID0gaXNCaW5kaW5nRWxlbWVudCA9IGZhbHNlO1xuICAgICAgICB9IGVsc2UgaWYgKG1hdGNoKCcrJykgfHwgbWF0Y2goJy0nKSB8fCBtYXRjaCgnficpIHx8IG1hdGNoKCchJykpIHtcbiAgICAgICAgICAgIHN0YXJ0VG9rZW4gPSBsb29rYWhlYWQ7XG4gICAgICAgICAgICB0b2tlbiA9IGxleCgpO1xuICAgICAgICAgICAgZXhwciA9IGluaGVyaXRDb3ZlckdyYW1tYXIocGFyc2VVbmFyeUV4cHJlc3Npb24pO1xuICAgICAgICAgICAgZXhwciA9IG5ldyBXcmFwcGluZ05vZGUoc3RhcnRUb2tlbikuZmluaXNoVW5hcnlFeHByZXNzaW9uKHRva2VuLnZhbHVlLCBleHByKTtcbiAgICAgICAgICAgIGlzQXNzaWdubWVudFRhcmdldCA9IGlzQmluZGluZ0VsZW1lbnQgPSBmYWxzZTtcbiAgICAgICAgfSBlbHNlIGlmIChtYXRjaEtleXdvcmQoJ2RlbGV0ZScpIHx8IG1hdGNoS2V5d29yZCgndm9pZCcpIHx8IG1hdGNoS2V5d29yZCgndHlwZW9mJykpIHtcbiAgICAgICAgICAgIHN0YXJ0VG9rZW4gPSBsb29rYWhlYWQ7XG4gICAgICAgICAgICB0b2tlbiA9IGxleCgpO1xuICAgICAgICAgICAgZXhwciA9IGluaGVyaXRDb3ZlckdyYW1tYXIocGFyc2VVbmFyeUV4cHJlc3Npb24pO1xuICAgICAgICAgICAgZXhwciA9IG5ldyBXcmFwcGluZ05vZGUoc3RhcnRUb2tlbikuZmluaXNoVW5hcnlFeHByZXNzaW9uKHRva2VuLnZhbHVlLCBleHByKTtcbiAgICAgICAgICAgIGlmIChzdHJpY3QgJiYgZXhwci5vcGVyYXRvciA9PT0gJ2RlbGV0ZScgJiYgZXhwci5hcmd1bWVudC50eXBlID09PSBTeW50YXguSWRlbnRpZmllcikge1xuICAgICAgICAgICAgICAgIHRvbGVyYXRlRXJyb3IoTWVzc2FnZXMuU3RyaWN0RGVsZXRlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlzQXNzaWdubWVudFRhcmdldCA9IGlzQmluZGluZ0VsZW1lbnQgPSBmYWxzZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGV4cHIgPSBwYXJzZVBvc3RmaXhFeHByZXNzaW9uKCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZXhwcjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBiaW5hcnlQcmVjZWRlbmNlKHRva2VuLCBhbGxvd0luKSB7XG4gICAgICAgIHZhciBwcmVjID0gMDtcblxuICAgICAgICBpZiAodG9rZW4udHlwZSAhPT0gVG9rZW4uUHVuY3R1YXRvciAmJiB0b2tlbi50eXBlICE9PSBUb2tlbi5LZXl3b3JkKSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIHN3aXRjaCAodG9rZW4udmFsdWUpIHtcbiAgICAgICAgY2FzZSAnfHwnOlxuICAgICAgICAgICAgcHJlYyA9IDE7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlICcmJic6XG4gICAgICAgICAgICBwcmVjID0gMjtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgJ3wnOlxuICAgICAgICAgICAgcHJlYyA9IDM7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlICdeJzpcbiAgICAgICAgICAgIHByZWMgPSA0O1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSAnJic6XG4gICAgICAgICAgICBwcmVjID0gNTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgJz09JzpcbiAgICAgICAgY2FzZSAnIT0nOlxuICAgICAgICBjYXNlICc9PT0nOlxuICAgICAgICBjYXNlICchPT0nOlxuICAgICAgICAgICAgcHJlYyA9IDY7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlICc8JzpcbiAgICAgICAgY2FzZSAnPic6XG4gICAgICAgIGNhc2UgJzw9JzpcbiAgICAgICAgY2FzZSAnPj0nOlxuICAgICAgICBjYXNlICdpbnN0YW5jZW9mJzpcbiAgICAgICAgICAgIHByZWMgPSA3O1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSAnaW4nOlxuICAgICAgICAgICAgcHJlYyA9IGFsbG93SW4gPyA3IDogMDtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgJzw8JzpcbiAgICAgICAgY2FzZSAnPj4nOlxuICAgICAgICBjYXNlICc+Pj4nOlxuICAgICAgICAgICAgcHJlYyA9IDg7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlICcrJzpcbiAgICAgICAgY2FzZSAnLSc6XG4gICAgICAgICAgICBwcmVjID0gOTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgJyonOlxuICAgICAgICBjYXNlICcvJzpcbiAgICAgICAgY2FzZSAnJSc6XG4gICAgICAgICAgICBwcmVjID0gMTE7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcHJlYztcbiAgICB9XG5cbiAgICAvLyAxMS41IE11bHRpcGxpY2F0aXZlIE9wZXJhdG9yc1xuICAgIC8vIDExLjYgQWRkaXRpdmUgT3BlcmF0b3JzXG4gICAgLy8gMTEuNyBCaXR3aXNlIFNoaWZ0IE9wZXJhdG9yc1xuICAgIC8vIDExLjggUmVsYXRpb25hbCBPcGVyYXRvcnNcbiAgICAvLyAxMS45IEVxdWFsaXR5IE9wZXJhdG9yc1xuICAgIC8vIDExLjEwIEJpbmFyeSBCaXR3aXNlIE9wZXJhdG9yc1xuICAgIC8vIDExLjExIEJpbmFyeSBMb2dpY2FsIE9wZXJhdG9yc1xuXG4gICAgZnVuY3Rpb24gcGFyc2VCaW5hcnlFeHByZXNzaW9uKCkge1xuICAgICAgICB2YXIgbWFya2VyLCBtYXJrZXJzLCBleHByLCB0b2tlbiwgcHJlYywgc3RhY2ssIHJpZ2h0LCBvcGVyYXRvciwgbGVmdCwgaTtcblxuICAgICAgICBtYXJrZXIgPSBsb29rYWhlYWQ7XG4gICAgICAgIGxlZnQgPSBpbmhlcml0Q292ZXJHcmFtbWFyKHBhcnNlVW5hcnlFeHByZXNzaW9uKTtcblxuICAgICAgICB0b2tlbiA9IGxvb2thaGVhZDtcbiAgICAgICAgcHJlYyA9IGJpbmFyeVByZWNlZGVuY2UodG9rZW4sIHN0YXRlLmFsbG93SW4pO1xuICAgICAgICBpZiAocHJlYyA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIGxlZnQ7XG4gICAgICAgIH1cbiAgICAgICAgaXNBc3NpZ25tZW50VGFyZ2V0ID0gaXNCaW5kaW5nRWxlbWVudCA9IGZhbHNlO1xuICAgICAgICB0b2tlbi5wcmVjID0gcHJlYztcbiAgICAgICAgbGV4KCk7XG5cbiAgICAgICAgbWFya2VycyA9IFttYXJrZXIsIGxvb2thaGVhZF07XG4gICAgICAgIHJpZ2h0ID0gaXNvbGF0ZUNvdmVyR3JhbW1hcihwYXJzZVVuYXJ5RXhwcmVzc2lvbik7XG5cbiAgICAgICAgc3RhY2sgPSBbbGVmdCwgdG9rZW4sIHJpZ2h0XTtcblxuICAgICAgICB3aGlsZSAoKHByZWMgPSBiaW5hcnlQcmVjZWRlbmNlKGxvb2thaGVhZCwgc3RhdGUuYWxsb3dJbikpID4gMCkge1xuXG4gICAgICAgICAgICAvLyBSZWR1Y2U6IG1ha2UgYSBiaW5hcnkgZXhwcmVzc2lvbiBmcm9tIHRoZSB0aHJlZSB0b3Btb3N0IGVudHJpZXMuXG4gICAgICAgICAgICB3aGlsZSAoKHN0YWNrLmxlbmd0aCA+IDIpICYmIChwcmVjIDw9IHN0YWNrW3N0YWNrLmxlbmd0aCAtIDJdLnByZWMpKSB7XG4gICAgICAgICAgICAgICAgcmlnaHQgPSBzdGFjay5wb3AoKTtcbiAgICAgICAgICAgICAgICBvcGVyYXRvciA9IHN0YWNrLnBvcCgpLnZhbHVlO1xuICAgICAgICAgICAgICAgIGxlZnQgPSBzdGFjay5wb3AoKTtcbiAgICAgICAgICAgICAgICBtYXJrZXJzLnBvcCgpO1xuICAgICAgICAgICAgICAgIGV4cHIgPSBuZXcgV3JhcHBpbmdOb2RlKG1hcmtlcnNbbWFya2Vycy5sZW5ndGggLSAxXSkuZmluaXNoQmluYXJ5RXhwcmVzc2lvbihvcGVyYXRvciwgbGVmdCwgcmlnaHQpO1xuICAgICAgICAgICAgICAgIHN0YWNrLnB1c2goZXhwcik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFNoaWZ0LlxuICAgICAgICAgICAgdG9rZW4gPSBsZXgoKTtcbiAgICAgICAgICAgIHRva2VuLnByZWMgPSBwcmVjO1xuICAgICAgICAgICAgc3RhY2sucHVzaCh0b2tlbik7XG4gICAgICAgICAgICBtYXJrZXJzLnB1c2gobG9va2FoZWFkKTtcbiAgICAgICAgICAgIGV4cHIgPSBpc29sYXRlQ292ZXJHcmFtbWFyKHBhcnNlVW5hcnlFeHByZXNzaW9uKTtcbiAgICAgICAgICAgIHN0YWNrLnB1c2goZXhwcik7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGaW5hbCByZWR1Y2UgdG8gY2xlYW4tdXAgdGhlIHN0YWNrLlxuICAgICAgICBpID0gc3RhY2subGVuZ3RoIC0gMTtcbiAgICAgICAgZXhwciA9IHN0YWNrW2ldO1xuICAgICAgICBtYXJrZXJzLnBvcCgpO1xuICAgICAgICB3aGlsZSAoaSA+IDEpIHtcbiAgICAgICAgICAgIGV4cHIgPSBuZXcgV3JhcHBpbmdOb2RlKG1hcmtlcnMucG9wKCkpLmZpbmlzaEJpbmFyeUV4cHJlc3Npb24oc3RhY2tbaSAtIDFdLnZhbHVlLCBzdGFja1tpIC0gMl0sIGV4cHIpO1xuICAgICAgICAgICAgaSAtPSAyO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGV4cHI7XG4gICAgfVxuXG5cbiAgICAvLyAxMS4xMiBDb25kaXRpb25hbCBPcGVyYXRvclxuXG4gICAgZnVuY3Rpb24gcGFyc2VDb25kaXRpb25hbEV4cHJlc3Npb24oKSB7XG4gICAgICAgIHZhciBleHByLCBwcmV2aW91c0FsbG93SW4sIGNvbnNlcXVlbnQsIGFsdGVybmF0ZSwgc3RhcnRUb2tlbjtcblxuICAgICAgICBzdGFydFRva2VuID0gbG9va2FoZWFkO1xuXG4gICAgICAgIGV4cHIgPSBpbmhlcml0Q292ZXJHcmFtbWFyKHBhcnNlQmluYXJ5RXhwcmVzc2lvbik7XG4gICAgICAgIGlmIChtYXRjaCgnPycpKSB7XG4gICAgICAgICAgICBsZXgoKTtcbiAgICAgICAgICAgIHByZXZpb3VzQWxsb3dJbiA9IHN0YXRlLmFsbG93SW47XG4gICAgICAgICAgICBzdGF0ZS5hbGxvd0luID0gdHJ1ZTtcbiAgICAgICAgICAgIGNvbnNlcXVlbnQgPSBpc29sYXRlQ292ZXJHcmFtbWFyKHBhcnNlQXNzaWdubWVudEV4cHJlc3Npb24pO1xuICAgICAgICAgICAgc3RhdGUuYWxsb3dJbiA9IHByZXZpb3VzQWxsb3dJbjtcbiAgICAgICAgICAgIGV4cGVjdCgnOicpO1xuICAgICAgICAgICAgYWx0ZXJuYXRlID0gaXNvbGF0ZUNvdmVyR3JhbW1hcihwYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uKTtcblxuICAgICAgICAgICAgZXhwciA9IG5ldyBXcmFwcGluZ05vZGUoc3RhcnRUb2tlbikuZmluaXNoQ29uZGl0aW9uYWxFeHByZXNzaW9uKGV4cHIsIGNvbnNlcXVlbnQsIGFsdGVybmF0ZSk7XG4gICAgICAgICAgICBpc0Fzc2lnbm1lbnRUYXJnZXQgPSBpc0JpbmRpbmdFbGVtZW50ID0gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZXhwcjtcbiAgICB9XG5cbiAgICAvLyBbRVM2XSAxNC4yIEFycm93IEZ1bmN0aW9uXG5cbiAgICBmdW5jdGlvbiBwYXJzZUNvbmNpc2VCb2R5KCkge1xuICAgICAgICBpZiAobWF0Y2goJ3snKSkge1xuICAgICAgICAgICAgcmV0dXJuIHBhcnNlRnVuY3Rpb25Tb3VyY2VFbGVtZW50cygpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpc29sYXRlQ292ZXJHcmFtbWFyKHBhcnNlQXNzaWdubWVudEV4cHJlc3Npb24pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNoZWNrUGF0dGVyblBhcmFtKG9wdGlvbnMsIHBhcmFtKSB7XG4gICAgICAgIHZhciBpO1xuICAgICAgICBzd2l0Y2ggKHBhcmFtLnR5cGUpIHtcbiAgICAgICAgY2FzZSBTeW50YXguSWRlbnRpZmllcjpcbiAgICAgICAgICAgIHZhbGlkYXRlUGFyYW0ob3B0aW9ucywgcGFyYW0sIHBhcmFtLm5hbWUpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgU3ludGF4LlJlc3RFbGVtZW50OlxuICAgICAgICAgICAgY2hlY2tQYXR0ZXJuUGFyYW0ob3B0aW9ucywgcGFyYW0uYXJndW1lbnQpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgU3ludGF4LkFzc2lnbm1lbnRQYXR0ZXJuOlxuICAgICAgICAgICAgY2hlY2tQYXR0ZXJuUGFyYW0ob3B0aW9ucywgcGFyYW0ubGVmdCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBTeW50YXguQXJyYXlQYXR0ZXJuOlxuICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IHBhcmFtLmVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKHBhcmFtLmVsZW1lbnRzW2ldICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGNoZWNrUGF0dGVyblBhcmFtKG9wdGlvbnMsIHBhcmFtLmVsZW1lbnRzW2ldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGFzc2VydChwYXJhbS50eXBlID09PSBTeW50YXguT2JqZWN0UGF0dGVybiwgJ0ludmFsaWQgdHlwZScpO1xuICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IHBhcmFtLnByb3BlcnRpZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBjaGVja1BhdHRlcm5QYXJhbShvcHRpb25zLCBwYXJhbS5wcm9wZXJ0aWVzW2ldLnZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICAgIGZ1bmN0aW9uIHJlaW50ZXJwcmV0QXNDb3ZlckZvcm1hbHNMaXN0KGV4cHIpIHtcbiAgICAgICAgdmFyIGksIGxlbiwgcGFyYW0sIHBhcmFtcywgZGVmYXVsdHMsIGRlZmF1bHRDb3VudCwgb3B0aW9ucywgdG9rZW47XG5cbiAgICAgICAgZGVmYXVsdHMgPSBbXTtcbiAgICAgICAgZGVmYXVsdENvdW50ID0gMDtcbiAgICAgICAgcGFyYW1zID0gW2V4cHJdO1xuXG4gICAgICAgIHN3aXRjaCAoZXhwci50eXBlKSB7XG4gICAgICAgIGNhc2UgU3ludGF4LklkZW50aWZpZXI6XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBQbGFjZUhvbGRlcnMuQXJyb3dQYXJhbWV0ZXJQbGFjZUhvbGRlcjpcbiAgICAgICAgICAgIHBhcmFtcyA9IGV4cHIucGFyYW1zO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIG9wdGlvbnMgPSB7XG4gICAgICAgICAgICBwYXJhbVNldDoge31cbiAgICAgICAgfTtcblxuICAgICAgICBmb3IgKGkgPSAwLCBsZW4gPSBwYXJhbXMubGVuZ3RoOyBpIDwgbGVuOyBpICs9IDEpIHtcbiAgICAgICAgICAgIHBhcmFtID0gcGFyYW1zW2ldO1xuICAgICAgICAgICAgc3dpdGNoIChwYXJhbS50eXBlKSB7XG4gICAgICAgICAgICBjYXNlIFN5bnRheC5Bc3NpZ25tZW50UGF0dGVybjpcbiAgICAgICAgICAgICAgICBwYXJhbXNbaV0gPSBwYXJhbS5sZWZ0O1xuICAgICAgICAgICAgICAgIGRlZmF1bHRzLnB1c2gocGFyYW0ucmlnaHQpO1xuICAgICAgICAgICAgICAgICsrZGVmYXVsdENvdW50O1xuICAgICAgICAgICAgICAgIGNoZWNrUGF0dGVyblBhcmFtKG9wdGlvbnMsIHBhcmFtLmxlZnQpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBjaGVja1BhdHRlcm5QYXJhbShvcHRpb25zLCBwYXJhbSk7XG4gICAgICAgICAgICAgICAgcGFyYW1zW2ldID0gcGFyYW07XG4gICAgICAgICAgICAgICAgZGVmYXVsdHMucHVzaChudWxsKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChvcHRpb25zLm1lc3NhZ2UgPT09IE1lc3NhZ2VzLlN0cmljdFBhcmFtRHVwZSkge1xuICAgICAgICAgICAgdG9rZW4gPSBzdHJpY3QgPyBvcHRpb25zLnN0cmljdGVkIDogb3B0aW9ucy5maXJzdFJlc3RyaWN0ZWQ7XG4gICAgICAgICAgICB0aHJvd1VuZXhwZWN0ZWRUb2tlbih0b2tlbiwgb3B0aW9ucy5tZXNzYWdlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChkZWZhdWx0Q291bnQgPT09IDApIHtcbiAgICAgICAgICAgIGRlZmF1bHRzID0gW107XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcGFyYW1zOiBwYXJhbXMsXG4gICAgICAgICAgICBkZWZhdWx0czogZGVmYXVsdHMsXG4gICAgICAgICAgICBzdHJpY3RlZDogb3B0aW9ucy5zdHJpY3RlZCxcbiAgICAgICAgICAgIGZpcnN0UmVzdHJpY3RlZDogb3B0aW9ucy5maXJzdFJlc3RyaWN0ZWQsXG4gICAgICAgICAgICBtZXNzYWdlOiBvcHRpb25zLm1lc3NhZ2VcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZUFycm93RnVuY3Rpb25FeHByZXNzaW9uKG9wdGlvbnMsIG5vZGUpIHtcbiAgICAgICAgdmFyIHByZXZpb3VzU3RyaWN0LCBib2R5O1xuXG4gICAgICAgIGlmIChoYXNMaW5lVGVybWluYXRvcikge1xuICAgICAgICAgICAgdG9sZXJhdGVVbmV4cGVjdGVkVG9rZW4obG9va2FoZWFkKTtcbiAgICAgICAgfVxuICAgICAgICBleHBlY3QoJz0+Jyk7XG4gICAgICAgIHByZXZpb3VzU3RyaWN0ID0gc3RyaWN0O1xuXG4gICAgICAgIGJvZHkgPSBwYXJzZUNvbmNpc2VCb2R5KCk7XG5cbiAgICAgICAgaWYgKHN0cmljdCAmJiBvcHRpb25zLmZpcnN0UmVzdHJpY3RlZCkge1xuICAgICAgICAgICAgdGhyb3dVbmV4cGVjdGVkVG9rZW4ob3B0aW9ucy5maXJzdFJlc3RyaWN0ZWQsIG9wdGlvbnMubWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHN0cmljdCAmJiBvcHRpb25zLnN0cmljdGVkKSB7XG4gICAgICAgICAgICB0b2xlcmF0ZVVuZXhwZWN0ZWRUb2tlbihvcHRpb25zLnN0cmljdGVkLCBvcHRpb25zLm1lc3NhZ2UpO1xuICAgICAgICB9XG5cbiAgICAgICAgc3RyaWN0ID0gcHJldmlvdXNTdHJpY3Q7XG5cbiAgICAgICAgcmV0dXJuIG5vZGUuZmluaXNoQXJyb3dGdW5jdGlvbkV4cHJlc3Npb24ob3B0aW9ucy5wYXJhbXMsIG9wdGlvbnMuZGVmYXVsdHMsIGJvZHksIGJvZHkudHlwZSAhPT0gU3ludGF4LkJsb2NrU3RhdGVtZW50KTtcbiAgICB9XG5cbiAgICAvLyAxMS4xMyBBc3NpZ25tZW50IE9wZXJhdG9yc1xuXG4gICAgZnVuY3Rpb24gcGFyc2VBc3NpZ25tZW50RXhwcmVzc2lvbigpIHtcbiAgICAgICAgdmFyIHRva2VuLCBleHByLCByaWdodCwgbGlzdCwgc3RhcnRUb2tlbjtcblxuICAgICAgICBzdGFydFRva2VuID0gbG9va2FoZWFkO1xuICAgICAgICB0b2tlbiA9IGxvb2thaGVhZDtcblxuICAgICAgICBleHByID0gcGFyc2VDb25kaXRpb25hbEV4cHJlc3Npb24oKTtcblxuICAgICAgICBpZiAoZXhwci50eXBlID09PSBQbGFjZUhvbGRlcnMuQXJyb3dQYXJhbWV0ZXJQbGFjZUhvbGRlciB8fCBtYXRjaCgnPT4nKSkge1xuICAgICAgICAgICAgaXNBc3NpZ25tZW50VGFyZ2V0ID0gaXNCaW5kaW5nRWxlbWVudCA9IGZhbHNlO1xuICAgICAgICAgICAgbGlzdCA9IHJlaW50ZXJwcmV0QXNDb3ZlckZvcm1hbHNMaXN0KGV4cHIpO1xuXG4gICAgICAgICAgICBpZiAobGlzdCkge1xuICAgICAgICAgICAgICAgIGZpcnN0Q292ZXJJbml0aWFsaXplZE5hbWVFcnJvciA9IG51bGw7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlQXJyb3dGdW5jdGlvbkV4cHJlc3Npb24obGlzdCwgbmV3IFdyYXBwaW5nTm9kZShzdGFydFRva2VuKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBleHByO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG1hdGNoQXNzaWduKCkpIHtcbiAgICAgICAgICAgIGlmICghaXNBc3NpZ25tZW50VGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgdG9sZXJhdGVFcnJvcihNZXNzYWdlcy5JbnZhbGlkTEhTSW5Bc3NpZ25tZW50KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gMTEuMTMuMVxuICAgICAgICAgICAgaWYgKHN0cmljdCAmJiBleHByLnR5cGUgPT09IFN5bnRheC5JZGVudGlmaWVyICYmIGlzUmVzdHJpY3RlZFdvcmQoZXhwci5uYW1lKSkge1xuICAgICAgICAgICAgICAgIHRvbGVyYXRlVW5leHBlY3RlZFRva2VuKHRva2VuLCBNZXNzYWdlcy5TdHJpY3RMSFNBc3NpZ25tZW50KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCFtYXRjaCgnPScpKSB7XG4gICAgICAgICAgICAgICAgaXNBc3NpZ25tZW50VGFyZ2V0ID0gaXNCaW5kaW5nRWxlbWVudCA9IGZhbHNlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWludGVycHJldEV4cHJlc3Npb25Bc1BhdHRlcm4oZXhwcik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRva2VuID0gbGV4KCk7XG4gICAgICAgICAgICByaWdodCA9IGlzb2xhdGVDb3ZlckdyYW1tYXIocGFyc2VBc3NpZ25tZW50RXhwcmVzc2lvbik7XG4gICAgICAgICAgICBleHByID0gbmV3IFdyYXBwaW5nTm9kZShzdGFydFRva2VuKS5maW5pc2hBc3NpZ25tZW50RXhwcmVzc2lvbih0b2tlbi52YWx1ZSwgZXhwciwgcmlnaHQpO1xuICAgICAgICAgICAgZmlyc3RDb3ZlckluaXRpYWxpemVkTmFtZUVycm9yID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBleHByO1xuICAgIH1cblxuICAgIC8vIDExLjE0IENvbW1hIE9wZXJhdG9yXG5cbiAgICBmdW5jdGlvbiBwYXJzZUV4cHJlc3Npb24oKSB7XG4gICAgICAgIHZhciBleHByLCBzdGFydFRva2VuID0gbG9va2FoZWFkLCBleHByZXNzaW9ucztcblxuICAgICAgICBleHByID0gaXNvbGF0ZUNvdmVyR3JhbW1hcihwYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uKTtcblxuICAgICAgICBpZiAobWF0Y2goJywnKSkge1xuICAgICAgICAgICAgZXhwcmVzc2lvbnMgPSBbZXhwcl07XG5cbiAgICAgICAgICAgIHdoaWxlIChzdGFydEluZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFtYXRjaCgnLCcpKSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXgoKTtcbiAgICAgICAgICAgICAgICBleHByZXNzaW9ucy5wdXNoKGlzb2xhdGVDb3ZlckdyYW1tYXIocGFyc2VBc3NpZ25tZW50RXhwcmVzc2lvbikpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBleHByID0gbmV3IFdyYXBwaW5nTm9kZShzdGFydFRva2VuKS5maW5pc2hTZXF1ZW5jZUV4cHJlc3Npb24oZXhwcmVzc2lvbnMpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGV4cHI7XG4gICAgfVxuXG4gICAgLy8gMTIuMSBCbG9ja1xuXG4gICAgZnVuY3Rpb24gcGFyc2VTdGF0ZW1lbnRMaXN0SXRlbSgpIHtcbiAgICAgICAgaWYgKGxvb2thaGVhZC50eXBlID09PSBUb2tlbi5LZXl3b3JkKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKGxvb2thaGVhZC52YWx1ZSkge1xuICAgICAgICAgICAgY2FzZSAnZXhwb3J0JzpcbiAgICAgICAgICAgICAgICBpZiAoc291cmNlVHlwZSAhPT0gJ21vZHVsZScpIHtcbiAgICAgICAgICAgICAgICAgICAgdG9sZXJhdGVVbmV4cGVjdGVkVG9rZW4obG9va2FoZWFkLCBNZXNzYWdlcy5JbGxlZ2FsRXhwb3J0RGVjbGFyYXRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VFeHBvcnREZWNsYXJhdGlvbigpO1xuICAgICAgICAgICAgY2FzZSAnaW1wb3J0JzpcbiAgICAgICAgICAgICAgICBpZiAoc291cmNlVHlwZSAhPT0gJ21vZHVsZScpIHtcbiAgICAgICAgICAgICAgICAgICAgdG9sZXJhdGVVbmV4cGVjdGVkVG9rZW4obG9va2FoZWFkLCBNZXNzYWdlcy5JbGxlZ2FsSW1wb3J0RGVjbGFyYXRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VJbXBvcnREZWNsYXJhdGlvbigpO1xuICAgICAgICAgICAgY2FzZSAnY29uc3QnOlxuICAgICAgICAgICAgY2FzZSAnbGV0JzpcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VMZXhpY2FsRGVjbGFyYXRpb24oe2luRm9yOiBmYWxzZX0pO1xuICAgICAgICAgICAgY2FzZSAnZnVuY3Rpb24nOlxuICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZUZ1bmN0aW9uRGVjbGFyYXRpb24obmV3IE5vZGUoKSk7XG4gICAgICAgICAgICBjYXNlICdjbGFzcyc6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlQ2xhc3NEZWNsYXJhdGlvbigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHBhcnNlU3RhdGVtZW50KCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VTdGF0ZW1lbnRMaXN0KCkge1xuICAgICAgICB2YXIgbGlzdCA9IFtdO1xuICAgICAgICB3aGlsZSAoc3RhcnRJbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgICAgaWYgKG1hdGNoKCd9JykpIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxpc3QucHVzaChwYXJzZVN0YXRlbWVudExpc3RJdGVtKCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGxpc3Q7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VCbG9jaygpIHtcbiAgICAgICAgdmFyIGJsb2NrLCBub2RlID0gbmV3IE5vZGUoKTtcblxuICAgICAgICBleHBlY3QoJ3snKTtcblxuICAgICAgICBibG9jayA9IHBhcnNlU3RhdGVtZW50TGlzdCgpO1xuXG4gICAgICAgIGV4cGVjdCgnfScpO1xuXG4gICAgICAgIHJldHVybiBub2RlLmZpbmlzaEJsb2NrU3RhdGVtZW50KGJsb2NrKTtcbiAgICB9XG5cbiAgICAvLyAxMi4yIFZhcmlhYmxlIFN0YXRlbWVudFxuXG4gICAgZnVuY3Rpb24gcGFyc2VWYXJpYWJsZUlkZW50aWZpZXIoKSB7XG4gICAgICAgIHZhciB0b2tlbiwgbm9kZSA9IG5ldyBOb2RlKCk7XG5cbiAgICAgICAgdG9rZW4gPSBsZXgoKTtcblxuICAgICAgICBpZiAodG9rZW4udHlwZSAhPT0gVG9rZW4uSWRlbnRpZmllcikge1xuICAgICAgICAgICAgaWYgKHN0cmljdCAmJiB0b2tlbi50eXBlID09PSBUb2tlbi5LZXl3b3JkICYmIGlzU3RyaWN0TW9kZVJlc2VydmVkV29yZCh0b2tlbi52YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB0b2xlcmF0ZVVuZXhwZWN0ZWRUb2tlbih0b2tlbiwgTWVzc2FnZXMuU3RyaWN0UmVzZXJ2ZWRXb3JkKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhyb3dVbmV4cGVjdGVkVG9rZW4odG9rZW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5vZGUuZmluaXNoSWRlbnRpZmllcih0b2tlbi52YWx1ZSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VWYXJpYWJsZURlY2xhcmF0aW9uKCkge1xuICAgICAgICB2YXIgaW5pdCA9IG51bGwsIGlkLCBub2RlID0gbmV3IE5vZGUoKTtcblxuICAgICAgICBpZCA9IHBhcnNlUGF0dGVybigpO1xuXG4gICAgICAgIC8vIDEyLjIuMVxuICAgICAgICBpZiAoc3RyaWN0ICYmIGlzUmVzdHJpY3RlZFdvcmQoaWQubmFtZSkpIHtcbiAgICAgICAgICAgIHRvbGVyYXRlRXJyb3IoTWVzc2FnZXMuU3RyaWN0VmFyTmFtZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobWF0Y2goJz0nKSkge1xuICAgICAgICAgICAgbGV4KCk7XG4gICAgICAgICAgICBpbml0ID0gaXNvbGF0ZUNvdmVyR3JhbW1hcihwYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uKTtcbiAgICAgICAgfSBlbHNlIGlmIChpZC50eXBlICE9PSBTeW50YXguSWRlbnRpZmllcikge1xuICAgICAgICAgICAgZXhwZWN0KCc9Jyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbm9kZS5maW5pc2hWYXJpYWJsZURlY2xhcmF0b3IoaWQsIGluaXQpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlVmFyaWFibGVEZWNsYXJhdGlvbkxpc3QoKSB7XG4gICAgICAgIHZhciBsaXN0ID0gW107XG5cbiAgICAgICAgZG8ge1xuICAgICAgICAgICAgbGlzdC5wdXNoKHBhcnNlVmFyaWFibGVEZWNsYXJhdGlvbigpKTtcbiAgICAgICAgICAgIGlmICghbWF0Y2goJywnKSkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV4KCk7XG4gICAgICAgIH0gd2hpbGUgKHN0YXJ0SW5kZXggPCBsZW5ndGgpO1xuXG4gICAgICAgIHJldHVybiBsaXN0O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlVmFyaWFibGVTdGF0ZW1lbnQobm9kZSkge1xuICAgICAgICB2YXIgZGVjbGFyYXRpb25zO1xuXG4gICAgICAgIGV4cGVjdEtleXdvcmQoJ3ZhcicpO1xuXG4gICAgICAgIGRlY2xhcmF0aW9ucyA9IHBhcnNlVmFyaWFibGVEZWNsYXJhdGlvbkxpc3QoKTtcblxuICAgICAgICBjb25zdW1lU2VtaWNvbG9uKCk7XG5cbiAgICAgICAgcmV0dXJuIG5vZGUuZmluaXNoVmFyaWFibGVEZWNsYXJhdGlvbihkZWNsYXJhdGlvbnMpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlTGV4aWNhbEJpbmRpbmcoa2luZCwgb3B0aW9ucykge1xuICAgICAgICB2YXIgaW5pdCA9IG51bGwsIGlkLCBub2RlID0gbmV3IE5vZGUoKTtcblxuICAgICAgICBpZCA9IHBhcnNlUGF0dGVybigpO1xuXG4gICAgICAgIC8vIDEyLjIuMVxuICAgICAgICBpZiAoc3RyaWN0ICYmIGlkLnR5cGUgPT09IFN5bnRheC5JZGVudGlmaWVyICYmIGlzUmVzdHJpY3RlZFdvcmQoaWQubmFtZSkpIHtcbiAgICAgICAgICAgIHRvbGVyYXRlRXJyb3IoTWVzc2FnZXMuU3RyaWN0VmFyTmFtZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoa2luZCA9PT0gJ2NvbnN0Jykge1xuICAgICAgICAgICAgaWYgKCFtYXRjaEtleXdvcmQoJ2luJykpIHtcbiAgICAgICAgICAgICAgICBleHBlY3QoJz0nKTtcbiAgICAgICAgICAgICAgICBpbml0ID0gaXNvbGF0ZUNvdmVyR3JhbW1hcihwYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICgoIW9wdGlvbnMuaW5Gb3IgJiYgaWQudHlwZSAhPT0gU3ludGF4LklkZW50aWZpZXIpIHx8IG1hdGNoKCc9JykpIHtcbiAgICAgICAgICAgIGV4cGVjdCgnPScpO1xuICAgICAgICAgICAgaW5pdCA9IGlzb2xhdGVDb3ZlckdyYW1tYXIocGFyc2VBc3NpZ25tZW50RXhwcmVzc2lvbik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbm9kZS5maW5pc2hWYXJpYWJsZURlY2xhcmF0b3IoaWQsIGluaXQpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlQmluZGluZ0xpc3Qoa2luZCwgb3B0aW9ucykge1xuICAgICAgICB2YXIgbGlzdCA9IFtdO1xuXG4gICAgICAgIGRvIHtcbiAgICAgICAgICAgIGxpc3QucHVzaChwYXJzZUxleGljYWxCaW5kaW5nKGtpbmQsIG9wdGlvbnMpKTtcbiAgICAgICAgICAgIGlmICghbWF0Y2goJywnKSkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV4KCk7XG4gICAgICAgIH0gd2hpbGUgKHN0YXJ0SW5kZXggPCBsZW5ndGgpO1xuXG4gICAgICAgIHJldHVybiBsaXN0O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlTGV4aWNhbERlY2xhcmF0aW9uKG9wdGlvbnMpIHtcbiAgICAgICAgdmFyIGtpbmQsIGRlY2xhcmF0aW9ucywgbm9kZSA9IG5ldyBOb2RlKCk7XG5cbiAgICAgICAga2luZCA9IGxleCgpLnZhbHVlO1xuICAgICAgICBhc3NlcnQoa2luZCA9PT0gJ2xldCcgfHwga2luZCA9PT0gJ2NvbnN0JywgJ0xleGljYWwgZGVjbGFyYXRpb24gbXVzdCBiZSBlaXRoZXIgbGV0IG9yIGNvbnN0Jyk7XG5cbiAgICAgICAgZGVjbGFyYXRpb25zID0gcGFyc2VCaW5kaW5nTGlzdChraW5kLCBvcHRpb25zKTtcblxuICAgICAgICBjb25zdW1lU2VtaWNvbG9uKCk7XG5cbiAgICAgICAgcmV0dXJuIG5vZGUuZmluaXNoTGV4aWNhbERlY2xhcmF0aW9uKGRlY2xhcmF0aW9ucywga2luZCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VSZXN0RWxlbWVudCgpIHtcbiAgICAgICAgdmFyIHBhcmFtLCBub2RlID0gbmV3IE5vZGUoKTtcblxuICAgICAgICBsZXgoKTtcblxuICAgICAgICBpZiAobWF0Y2goJ3snKSkge1xuICAgICAgICAgICAgdGhyb3dFcnJvcihNZXNzYWdlcy5PYmplY3RQYXR0ZXJuQXNSZXN0UGFyYW1ldGVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHBhcmFtID0gcGFyc2VWYXJpYWJsZUlkZW50aWZpZXIoKTtcblxuICAgICAgICBpZiAobWF0Y2goJz0nKSkge1xuICAgICAgICAgICAgdGhyb3dFcnJvcihNZXNzYWdlcy5EZWZhdWx0UmVzdFBhcmFtZXRlcik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIW1hdGNoKCcpJykpIHtcbiAgICAgICAgICAgIHRocm93RXJyb3IoTWVzc2FnZXMuUGFyYW1ldGVyQWZ0ZXJSZXN0UGFyYW1ldGVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBub2RlLmZpbmlzaFJlc3RFbGVtZW50KHBhcmFtKTtcbiAgICB9XG5cbiAgICAvLyAxMi4zIEVtcHR5IFN0YXRlbWVudFxuXG4gICAgZnVuY3Rpb24gcGFyc2VFbXB0eVN0YXRlbWVudChub2RlKSB7XG4gICAgICAgIGV4cGVjdCgnOycpO1xuICAgICAgICByZXR1cm4gbm9kZS5maW5pc2hFbXB0eVN0YXRlbWVudCgpO1xuICAgIH1cblxuICAgIC8vIDEyLjQgRXhwcmVzc2lvbiBTdGF0ZW1lbnRcblxuICAgIGZ1bmN0aW9uIHBhcnNlRXhwcmVzc2lvblN0YXRlbWVudChub2RlKSB7XG4gICAgICAgIHZhciBleHByID0gcGFyc2VFeHByZXNzaW9uKCk7XG4gICAgICAgIGNvbnN1bWVTZW1pY29sb24oKTtcbiAgICAgICAgcmV0dXJuIG5vZGUuZmluaXNoRXhwcmVzc2lvblN0YXRlbWVudChleHByKTtcbiAgICB9XG5cbiAgICAvLyAxMi41IElmIHN0YXRlbWVudFxuXG4gICAgZnVuY3Rpb24gcGFyc2VJZlN0YXRlbWVudChub2RlKSB7XG4gICAgICAgIHZhciB0ZXN0LCBjb25zZXF1ZW50LCBhbHRlcm5hdGU7XG5cbiAgICAgICAgZXhwZWN0S2V5d29yZCgnaWYnKTtcblxuICAgICAgICBleHBlY3QoJygnKTtcblxuICAgICAgICB0ZXN0ID0gcGFyc2VFeHByZXNzaW9uKCk7XG5cbiAgICAgICAgZXhwZWN0KCcpJyk7XG5cbiAgICAgICAgY29uc2VxdWVudCA9IHBhcnNlU3RhdGVtZW50KCk7XG5cbiAgICAgICAgaWYgKG1hdGNoS2V5d29yZCgnZWxzZScpKSB7XG4gICAgICAgICAgICBsZXgoKTtcbiAgICAgICAgICAgIGFsdGVybmF0ZSA9IHBhcnNlU3RhdGVtZW50KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhbHRlcm5hdGUgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5vZGUuZmluaXNoSWZTdGF0ZW1lbnQodGVzdCwgY29uc2VxdWVudCwgYWx0ZXJuYXRlKTtcbiAgICB9XG5cbiAgICAvLyAxMi42IEl0ZXJhdGlvbiBTdGF0ZW1lbnRzXG5cbiAgICBmdW5jdGlvbiBwYXJzZURvV2hpbGVTdGF0ZW1lbnQobm9kZSkge1xuICAgICAgICB2YXIgYm9keSwgdGVzdCwgb2xkSW5JdGVyYXRpb247XG5cbiAgICAgICAgZXhwZWN0S2V5d29yZCgnZG8nKTtcblxuICAgICAgICBvbGRJbkl0ZXJhdGlvbiA9IHN0YXRlLmluSXRlcmF0aW9uO1xuICAgICAgICBzdGF0ZS5pbkl0ZXJhdGlvbiA9IHRydWU7XG5cbiAgICAgICAgYm9keSA9IHBhcnNlU3RhdGVtZW50KCk7XG5cbiAgICAgICAgc3RhdGUuaW5JdGVyYXRpb24gPSBvbGRJbkl0ZXJhdGlvbjtcblxuICAgICAgICBleHBlY3RLZXl3b3JkKCd3aGlsZScpO1xuXG4gICAgICAgIGV4cGVjdCgnKCcpO1xuXG4gICAgICAgIHRlc3QgPSBwYXJzZUV4cHJlc3Npb24oKTtcblxuICAgICAgICBleHBlY3QoJyknKTtcblxuICAgICAgICBpZiAobWF0Y2goJzsnKSkge1xuICAgICAgICAgICAgbGV4KCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbm9kZS5maW5pc2hEb1doaWxlU3RhdGVtZW50KGJvZHksIHRlc3QpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlV2hpbGVTdGF0ZW1lbnQobm9kZSkge1xuICAgICAgICB2YXIgdGVzdCwgYm9keSwgb2xkSW5JdGVyYXRpb247XG5cbiAgICAgICAgZXhwZWN0S2V5d29yZCgnd2hpbGUnKTtcblxuICAgICAgICBleHBlY3QoJygnKTtcblxuICAgICAgICB0ZXN0ID0gcGFyc2VFeHByZXNzaW9uKCk7XG5cbiAgICAgICAgZXhwZWN0KCcpJyk7XG5cbiAgICAgICAgb2xkSW5JdGVyYXRpb24gPSBzdGF0ZS5pbkl0ZXJhdGlvbjtcbiAgICAgICAgc3RhdGUuaW5JdGVyYXRpb24gPSB0cnVlO1xuXG4gICAgICAgIGJvZHkgPSBwYXJzZVN0YXRlbWVudCgpO1xuXG4gICAgICAgIHN0YXRlLmluSXRlcmF0aW9uID0gb2xkSW5JdGVyYXRpb247XG5cbiAgICAgICAgcmV0dXJuIG5vZGUuZmluaXNoV2hpbGVTdGF0ZW1lbnQodGVzdCwgYm9keSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VGb3JTdGF0ZW1lbnQobm9kZSkge1xuICAgICAgICB2YXIgaW5pdCwgaW5pdFNlcSwgaW5pdFN0YXJ0VG9rZW4sIHRlc3QsIHVwZGF0ZSwgbGVmdCwgcmlnaHQsIGtpbmQsIGRlY2xhcmF0aW9ucyxcbiAgICAgICAgICAgIGJvZHksIG9sZEluSXRlcmF0aW9uLCBwcmV2aW91c0FsbG93SW4gPSBzdGF0ZS5hbGxvd0luO1xuXG4gICAgICAgIGluaXQgPSB0ZXN0ID0gdXBkYXRlID0gbnVsbDtcblxuICAgICAgICBleHBlY3RLZXl3b3JkKCdmb3InKTtcblxuICAgICAgICBleHBlY3QoJygnKTtcblxuICAgICAgICBpZiAobWF0Y2goJzsnKSkge1xuICAgICAgICAgICAgbGV4KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAobWF0Y2hLZXl3b3JkKCd2YXInKSkge1xuICAgICAgICAgICAgICAgIGluaXQgPSBuZXcgTm9kZSgpO1xuICAgICAgICAgICAgICAgIGxleCgpO1xuXG4gICAgICAgICAgICAgICAgc3RhdGUuYWxsb3dJbiA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGluaXQgPSBpbml0LmZpbmlzaFZhcmlhYmxlRGVjbGFyYXRpb24ocGFyc2VWYXJpYWJsZURlY2xhcmF0aW9uTGlzdCgpKTtcbiAgICAgICAgICAgICAgICBzdGF0ZS5hbGxvd0luID0gcHJldmlvdXNBbGxvd0luO1xuXG4gICAgICAgICAgICAgICAgaWYgKGluaXQuZGVjbGFyYXRpb25zLmxlbmd0aCA9PT0gMSAmJiBtYXRjaEtleXdvcmQoJ2luJykpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV4KCk7XG4gICAgICAgICAgICAgICAgICAgIGxlZnQgPSBpbml0O1xuICAgICAgICAgICAgICAgICAgICByaWdodCA9IHBhcnNlRXhwcmVzc2lvbigpO1xuICAgICAgICAgICAgICAgICAgICBpbml0ID0gbnVsbDtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3QoJzsnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKG1hdGNoS2V5d29yZCgnY29uc3QnKSB8fCBtYXRjaEtleXdvcmQoJ2xldCcpKSB7XG4gICAgICAgICAgICAgICAgaW5pdCA9IG5ldyBOb2RlKCk7XG4gICAgICAgICAgICAgICAga2luZCA9IGxleCgpLnZhbHVlO1xuXG4gICAgICAgICAgICAgICAgc3RhdGUuYWxsb3dJbiA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGRlY2xhcmF0aW9ucyA9IHBhcnNlQmluZGluZ0xpc3Qoa2luZCwge2luRm9yOiB0cnVlfSk7XG4gICAgICAgICAgICAgICAgc3RhdGUuYWxsb3dJbiA9IHByZXZpb3VzQWxsb3dJbjtcblxuICAgICAgICAgICAgICAgIGlmIChkZWNsYXJhdGlvbnMubGVuZ3RoID09PSAxICYmIGRlY2xhcmF0aW9uc1swXS5pbml0ID09PSBudWxsICYmIG1hdGNoS2V5d29yZCgnaW4nKSkge1xuICAgICAgICAgICAgICAgICAgICBpbml0ID0gaW5pdC5maW5pc2hMZXhpY2FsRGVjbGFyYXRpb24oZGVjbGFyYXRpb25zLCBraW5kKTtcbiAgICAgICAgICAgICAgICAgICAgbGV4KCk7XG4gICAgICAgICAgICAgICAgICAgIGxlZnQgPSBpbml0O1xuICAgICAgICAgICAgICAgICAgICByaWdodCA9IHBhcnNlRXhwcmVzc2lvbigpO1xuICAgICAgICAgICAgICAgICAgICBpbml0ID0gbnVsbDtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zdW1lU2VtaWNvbG9uKCk7XG4gICAgICAgICAgICAgICAgICAgIGluaXQgPSBpbml0LmZpbmlzaExleGljYWxEZWNsYXJhdGlvbihkZWNsYXJhdGlvbnMsIGtpbmQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaW5pdFN0YXJ0VG9rZW4gPSBsb29rYWhlYWQ7XG4gICAgICAgICAgICAgICAgc3RhdGUuYWxsb3dJbiA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGluaXQgPSBpbmhlcml0Q292ZXJHcmFtbWFyKHBhcnNlQXNzaWdubWVudEV4cHJlc3Npb24pO1xuICAgICAgICAgICAgICAgIHN0YXRlLmFsbG93SW4gPSBwcmV2aW91c0FsbG93SW47XG5cbiAgICAgICAgICAgICAgICBpZiAobWF0Y2hLZXl3b3JkKCdpbicpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghaXNBc3NpZ25tZW50VGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b2xlcmF0ZUVycm9yKE1lc3NhZ2VzLkludmFsaWRMSFNJbkZvckluKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGxleCgpO1xuICAgICAgICAgICAgICAgICAgICByZWludGVycHJldEV4cHJlc3Npb25Bc1BhdHRlcm4oaW5pdCk7XG4gICAgICAgICAgICAgICAgICAgIGxlZnQgPSBpbml0O1xuICAgICAgICAgICAgICAgICAgICByaWdodCA9IHBhcnNlRXhwcmVzc2lvbigpO1xuICAgICAgICAgICAgICAgICAgICBpbml0ID0gbnVsbDtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpZiAobWF0Y2goJywnKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaW5pdFNlcSA9IFtpbml0XTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChtYXRjaCgnLCcpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV4KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5pdFNlcS5wdXNoKGlzb2xhdGVDb3ZlckdyYW1tYXIocGFyc2VBc3NpZ25tZW50RXhwcmVzc2lvbikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaW5pdCA9IG5ldyBXcmFwcGluZ05vZGUoaW5pdFN0YXJ0VG9rZW4pLmZpbmlzaFNlcXVlbmNlRXhwcmVzc2lvbihpbml0U2VxKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBleHBlY3QoJzsnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIGxlZnQgPT09ICd1bmRlZmluZWQnKSB7XG5cbiAgICAgICAgICAgIGlmICghbWF0Y2goJzsnKSkge1xuICAgICAgICAgICAgICAgIHRlc3QgPSBwYXJzZUV4cHJlc3Npb24oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGV4cGVjdCgnOycpO1xuXG4gICAgICAgICAgICBpZiAoIW1hdGNoKCcpJykpIHtcbiAgICAgICAgICAgICAgICB1cGRhdGUgPSBwYXJzZUV4cHJlc3Npb24oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGV4cGVjdCgnKScpO1xuXG4gICAgICAgIG9sZEluSXRlcmF0aW9uID0gc3RhdGUuaW5JdGVyYXRpb247XG4gICAgICAgIHN0YXRlLmluSXRlcmF0aW9uID0gdHJ1ZTtcblxuICAgICAgICBib2R5ID0gaXNvbGF0ZUNvdmVyR3JhbW1hcihwYXJzZVN0YXRlbWVudCk7XG5cbiAgICAgICAgc3RhdGUuaW5JdGVyYXRpb24gPSBvbGRJbkl0ZXJhdGlvbjtcblxuICAgICAgICByZXR1cm4gKHR5cGVvZiBsZWZ0ID09PSAndW5kZWZpbmVkJykgP1xuICAgICAgICAgICAgICAgIG5vZGUuZmluaXNoRm9yU3RhdGVtZW50KGluaXQsIHRlc3QsIHVwZGF0ZSwgYm9keSkgOlxuICAgICAgICAgICAgICAgIG5vZGUuZmluaXNoRm9ySW5TdGF0ZW1lbnQobGVmdCwgcmlnaHQsIGJvZHkpO1xuICAgIH1cblxuICAgIC8vIDEyLjcgVGhlIGNvbnRpbnVlIHN0YXRlbWVudFxuXG4gICAgZnVuY3Rpb24gcGFyc2VDb250aW51ZVN0YXRlbWVudChub2RlKSB7XG4gICAgICAgIHZhciBsYWJlbCA9IG51bGwsIGtleTtcblxuICAgICAgICBleHBlY3RLZXl3b3JkKCdjb250aW51ZScpO1xuXG4gICAgICAgIC8vIE9wdGltaXplIHRoZSBtb3N0IGNvbW1vbiBmb3JtOiAnY29udGludWU7Jy5cbiAgICAgICAgaWYgKHNvdXJjZS5jaGFyQ29kZUF0KHN0YXJ0SW5kZXgpID09PSAweDNCKSB7XG4gICAgICAgICAgICBsZXgoKTtcblxuICAgICAgICAgICAgaWYgKCFzdGF0ZS5pbkl0ZXJhdGlvbikge1xuICAgICAgICAgICAgICAgIHRocm93RXJyb3IoTWVzc2FnZXMuSWxsZWdhbENvbnRpbnVlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIG5vZGUuZmluaXNoQ29udGludWVTdGF0ZW1lbnQobnVsbCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaGFzTGluZVRlcm1pbmF0b3IpIHtcbiAgICAgICAgICAgIGlmICghc3RhdGUuaW5JdGVyYXRpb24pIHtcbiAgICAgICAgICAgICAgICB0aHJvd0Vycm9yKE1lc3NhZ2VzLklsbGVnYWxDb250aW51ZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBub2RlLmZpbmlzaENvbnRpbnVlU3RhdGVtZW50KG51bGwpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGxvb2thaGVhZC50eXBlID09PSBUb2tlbi5JZGVudGlmaWVyKSB7XG4gICAgICAgICAgICBsYWJlbCA9IHBhcnNlVmFyaWFibGVJZGVudGlmaWVyKCk7XG5cbiAgICAgICAgICAgIGtleSA9ICckJyArIGxhYmVsLm5hbWU7XG4gICAgICAgICAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzdGF0ZS5sYWJlbFNldCwga2V5KSkge1xuICAgICAgICAgICAgICAgIHRocm93RXJyb3IoTWVzc2FnZXMuVW5rbm93bkxhYmVsLCBsYWJlbC5uYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN1bWVTZW1pY29sb24oKTtcblxuICAgICAgICBpZiAobGFiZWwgPT09IG51bGwgJiYgIXN0YXRlLmluSXRlcmF0aW9uKSB7XG4gICAgICAgICAgICB0aHJvd0Vycm9yKE1lc3NhZ2VzLklsbGVnYWxDb250aW51ZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbm9kZS5maW5pc2hDb250aW51ZVN0YXRlbWVudChsYWJlbCk7XG4gICAgfVxuXG4gICAgLy8gMTIuOCBUaGUgYnJlYWsgc3RhdGVtZW50XG5cbiAgICBmdW5jdGlvbiBwYXJzZUJyZWFrU3RhdGVtZW50KG5vZGUpIHtcbiAgICAgICAgdmFyIGxhYmVsID0gbnVsbCwga2V5O1xuXG4gICAgICAgIGV4cGVjdEtleXdvcmQoJ2JyZWFrJyk7XG5cbiAgICAgICAgLy8gQ2F0Y2ggdGhlIHZlcnkgY29tbW9uIGNhc2UgZmlyc3Q6IGltbWVkaWF0ZWx5IGEgc2VtaWNvbG9uIChVKzAwM0IpLlxuICAgICAgICBpZiAoc291cmNlLmNoYXJDb2RlQXQobGFzdEluZGV4KSA9PT0gMHgzQikge1xuICAgICAgICAgICAgbGV4KCk7XG5cbiAgICAgICAgICAgIGlmICghKHN0YXRlLmluSXRlcmF0aW9uIHx8IHN0YXRlLmluU3dpdGNoKSkge1xuICAgICAgICAgICAgICAgIHRocm93RXJyb3IoTWVzc2FnZXMuSWxsZWdhbEJyZWFrKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIG5vZGUuZmluaXNoQnJlYWtTdGF0ZW1lbnQobnVsbCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaGFzTGluZVRlcm1pbmF0b3IpIHtcbiAgICAgICAgICAgIGlmICghKHN0YXRlLmluSXRlcmF0aW9uIHx8IHN0YXRlLmluU3dpdGNoKSkge1xuICAgICAgICAgICAgICAgIHRocm93RXJyb3IoTWVzc2FnZXMuSWxsZWdhbEJyZWFrKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIG5vZGUuZmluaXNoQnJlYWtTdGF0ZW1lbnQobnVsbCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobG9va2FoZWFkLnR5cGUgPT09IFRva2VuLklkZW50aWZpZXIpIHtcbiAgICAgICAgICAgIGxhYmVsID0gcGFyc2VWYXJpYWJsZUlkZW50aWZpZXIoKTtcblxuICAgICAgICAgICAga2V5ID0gJyQnICsgbGFiZWwubmFtZTtcbiAgICAgICAgICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHN0YXRlLmxhYmVsU2V0LCBrZXkpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3dFcnJvcihNZXNzYWdlcy5Vbmtub3duTGFiZWwsIGxhYmVsLm5hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3VtZVNlbWljb2xvbigpO1xuXG4gICAgICAgIGlmIChsYWJlbCA9PT0gbnVsbCAmJiAhKHN0YXRlLmluSXRlcmF0aW9uIHx8IHN0YXRlLmluU3dpdGNoKSkge1xuICAgICAgICAgICAgdGhyb3dFcnJvcihNZXNzYWdlcy5JbGxlZ2FsQnJlYWspO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5vZGUuZmluaXNoQnJlYWtTdGF0ZW1lbnQobGFiZWwpO1xuICAgIH1cblxuICAgIC8vIDEyLjkgVGhlIHJldHVybiBzdGF0ZW1lbnRcblxuICAgIGZ1bmN0aW9uIHBhcnNlUmV0dXJuU3RhdGVtZW50KG5vZGUpIHtcbiAgICAgICAgdmFyIGFyZ3VtZW50ID0gbnVsbDtcblxuICAgICAgICBleHBlY3RLZXl3b3JkKCdyZXR1cm4nKTtcblxuICAgICAgICBpZiAoIXN0YXRlLmluRnVuY3Rpb25Cb2R5KSB7XG4gICAgICAgICAgICB0b2xlcmF0ZUVycm9yKE1lc3NhZ2VzLklsbGVnYWxSZXR1cm4pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gJ3JldHVybicgZm9sbG93ZWQgYnkgYSBzcGFjZSBhbmQgYW4gaWRlbnRpZmllciBpcyB2ZXJ5IGNvbW1vbi5cbiAgICAgICAgaWYgKHNvdXJjZS5jaGFyQ29kZUF0KGxhc3RJbmRleCkgPT09IDB4MjApIHtcbiAgICAgICAgICAgIGlmIChpc0lkZW50aWZpZXJTdGFydChzb3VyY2UuY2hhckNvZGVBdChsYXN0SW5kZXggKyAxKSkpIHtcbiAgICAgICAgICAgICAgICBhcmd1bWVudCA9IHBhcnNlRXhwcmVzc2lvbigpO1xuICAgICAgICAgICAgICAgIGNvbnN1bWVTZW1pY29sb24oKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbm9kZS5maW5pc2hSZXR1cm5TdGF0ZW1lbnQoYXJndW1lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGhhc0xpbmVUZXJtaW5hdG9yKSB7XG4gICAgICAgICAgICAvLyBIQUNLXG4gICAgICAgICAgICByZXR1cm4gbm9kZS5maW5pc2hSZXR1cm5TdGF0ZW1lbnQobnVsbCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIW1hdGNoKCc7JykpIHtcbiAgICAgICAgICAgIGlmICghbWF0Y2goJ30nKSAmJiBsb29rYWhlYWQudHlwZSAhPT0gVG9rZW4uRU9GKSB7XG4gICAgICAgICAgICAgICAgYXJndW1lbnQgPSBwYXJzZUV4cHJlc3Npb24oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN1bWVTZW1pY29sb24oKTtcblxuICAgICAgICByZXR1cm4gbm9kZS5maW5pc2hSZXR1cm5TdGF0ZW1lbnQoYXJndW1lbnQpO1xuICAgIH1cblxuICAgIC8vIDEyLjEwIFRoZSB3aXRoIHN0YXRlbWVudFxuXG4gICAgZnVuY3Rpb24gcGFyc2VXaXRoU3RhdGVtZW50KG5vZGUpIHtcbiAgICAgICAgdmFyIG9iamVjdCwgYm9keTtcblxuICAgICAgICBpZiAoc3RyaWN0KSB7XG4gICAgICAgICAgICB0b2xlcmF0ZUVycm9yKE1lc3NhZ2VzLlN0cmljdE1vZGVXaXRoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGV4cGVjdEtleXdvcmQoJ3dpdGgnKTtcblxuICAgICAgICBleHBlY3QoJygnKTtcblxuICAgICAgICBvYmplY3QgPSBwYXJzZUV4cHJlc3Npb24oKTtcblxuICAgICAgICBleHBlY3QoJyknKTtcblxuICAgICAgICBib2R5ID0gcGFyc2VTdGF0ZW1lbnQoKTtcblxuICAgICAgICByZXR1cm4gbm9kZS5maW5pc2hXaXRoU3RhdGVtZW50KG9iamVjdCwgYm9keSk7XG4gICAgfVxuXG4gICAgLy8gMTIuMTAgVGhlIHN3aXRoIHN0YXRlbWVudFxuXG4gICAgZnVuY3Rpb24gcGFyc2VTd2l0Y2hDYXNlKCkge1xuICAgICAgICB2YXIgdGVzdCwgY29uc2VxdWVudCA9IFtdLCBzdGF0ZW1lbnQsIG5vZGUgPSBuZXcgTm9kZSgpO1xuXG4gICAgICAgIGlmIChtYXRjaEtleXdvcmQoJ2RlZmF1bHQnKSkge1xuICAgICAgICAgICAgbGV4KCk7XG4gICAgICAgICAgICB0ZXN0ID0gbnVsbDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGV4cGVjdEtleXdvcmQoJ2Nhc2UnKTtcbiAgICAgICAgICAgIHRlc3QgPSBwYXJzZUV4cHJlc3Npb24oKTtcbiAgICAgICAgfVxuICAgICAgICBleHBlY3QoJzonKTtcblxuICAgICAgICB3aGlsZSAoc3RhcnRJbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgICAgaWYgKG1hdGNoKCd9JykgfHwgbWF0Y2hLZXl3b3JkKCdkZWZhdWx0JykgfHwgbWF0Y2hLZXl3b3JkKCdjYXNlJykpIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN0YXRlbWVudCA9IHBhcnNlU3RhdGVtZW50TGlzdEl0ZW0oKTtcbiAgICAgICAgICAgIGNvbnNlcXVlbnQucHVzaChzdGF0ZW1lbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5vZGUuZmluaXNoU3dpdGNoQ2FzZSh0ZXN0LCBjb25zZXF1ZW50KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZVN3aXRjaFN0YXRlbWVudChub2RlKSB7XG4gICAgICAgIHZhciBkaXNjcmltaW5hbnQsIGNhc2VzLCBjbGF1c2UsIG9sZEluU3dpdGNoLCBkZWZhdWx0Rm91bmQ7XG5cbiAgICAgICAgZXhwZWN0S2V5d29yZCgnc3dpdGNoJyk7XG5cbiAgICAgICAgZXhwZWN0KCcoJyk7XG5cbiAgICAgICAgZGlzY3JpbWluYW50ID0gcGFyc2VFeHByZXNzaW9uKCk7XG5cbiAgICAgICAgZXhwZWN0KCcpJyk7XG5cbiAgICAgICAgZXhwZWN0KCd7Jyk7XG5cbiAgICAgICAgY2FzZXMgPSBbXTtcblxuICAgICAgICBpZiAobWF0Y2goJ30nKSkge1xuICAgICAgICAgICAgbGV4KCk7XG4gICAgICAgICAgICByZXR1cm4gbm9kZS5maW5pc2hTd2l0Y2hTdGF0ZW1lbnQoZGlzY3JpbWluYW50LCBjYXNlcyk7XG4gICAgICAgIH1cblxuICAgICAgICBvbGRJblN3aXRjaCA9IHN0YXRlLmluU3dpdGNoO1xuICAgICAgICBzdGF0ZS5pblN3aXRjaCA9IHRydWU7XG4gICAgICAgIGRlZmF1bHRGb3VuZCA9IGZhbHNlO1xuXG4gICAgICAgIHdoaWxlIChzdGFydEluZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAobWF0Y2goJ30nKSkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2xhdXNlID0gcGFyc2VTd2l0Y2hDYXNlKCk7XG4gICAgICAgICAgICBpZiAoY2xhdXNlLnRlc3QgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAoZGVmYXVsdEZvdW5kKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93RXJyb3IoTWVzc2FnZXMuTXVsdGlwbGVEZWZhdWx0c0luU3dpdGNoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVmYXVsdEZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2VzLnB1c2goY2xhdXNlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHN0YXRlLmluU3dpdGNoID0gb2xkSW5Td2l0Y2g7XG5cbiAgICAgICAgZXhwZWN0KCd9Jyk7XG5cbiAgICAgICAgcmV0dXJuIG5vZGUuZmluaXNoU3dpdGNoU3RhdGVtZW50KGRpc2NyaW1pbmFudCwgY2FzZXMpO1xuICAgIH1cblxuICAgIC8vIDEyLjEzIFRoZSB0aHJvdyBzdGF0ZW1lbnRcblxuICAgIGZ1bmN0aW9uIHBhcnNlVGhyb3dTdGF0ZW1lbnQobm9kZSkge1xuICAgICAgICB2YXIgYXJndW1lbnQ7XG5cbiAgICAgICAgZXhwZWN0S2V5d29yZCgndGhyb3cnKTtcblxuICAgICAgICBpZiAoaGFzTGluZVRlcm1pbmF0b3IpIHtcbiAgICAgICAgICAgIHRocm93RXJyb3IoTWVzc2FnZXMuTmV3bGluZUFmdGVyVGhyb3cpO1xuICAgICAgICB9XG5cbiAgICAgICAgYXJndW1lbnQgPSBwYXJzZUV4cHJlc3Npb24oKTtcblxuICAgICAgICBjb25zdW1lU2VtaWNvbG9uKCk7XG5cbiAgICAgICAgcmV0dXJuIG5vZGUuZmluaXNoVGhyb3dTdGF0ZW1lbnQoYXJndW1lbnQpO1xuICAgIH1cblxuICAgIC8vIDEyLjE0IFRoZSB0cnkgc3RhdGVtZW50XG5cbiAgICBmdW5jdGlvbiBwYXJzZUNhdGNoQ2xhdXNlKCkge1xuICAgICAgICB2YXIgcGFyYW0sIGJvZHksIG5vZGUgPSBuZXcgTm9kZSgpO1xuXG4gICAgICAgIGV4cGVjdEtleXdvcmQoJ2NhdGNoJyk7XG5cbiAgICAgICAgZXhwZWN0KCcoJyk7XG4gICAgICAgIGlmIChtYXRjaCgnKScpKSB7XG4gICAgICAgICAgICB0aHJvd1VuZXhwZWN0ZWRUb2tlbihsb29rYWhlYWQpO1xuICAgICAgICB9XG5cbiAgICAgICAgcGFyYW0gPSBwYXJzZVBhdHRlcm4oKTtcblxuICAgICAgICAvLyAxMi4xNC4xXG4gICAgICAgIGlmIChzdHJpY3QgJiYgaXNSZXN0cmljdGVkV29yZChwYXJhbS5uYW1lKSkge1xuICAgICAgICAgICAgdG9sZXJhdGVFcnJvcihNZXNzYWdlcy5TdHJpY3RDYXRjaFZhcmlhYmxlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGV4cGVjdCgnKScpO1xuICAgICAgICBib2R5ID0gcGFyc2VCbG9jaygpO1xuICAgICAgICByZXR1cm4gbm9kZS5maW5pc2hDYXRjaENsYXVzZShwYXJhbSwgYm9keSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VUcnlTdGF0ZW1lbnQobm9kZSkge1xuICAgICAgICB2YXIgYmxvY2ssIGhhbmRsZXIgPSBudWxsLCBmaW5hbGl6ZXIgPSBudWxsO1xuXG4gICAgICAgIGV4cGVjdEtleXdvcmQoJ3RyeScpO1xuXG4gICAgICAgIGJsb2NrID0gcGFyc2VCbG9jaygpO1xuXG4gICAgICAgIGlmIChtYXRjaEtleXdvcmQoJ2NhdGNoJykpIHtcbiAgICAgICAgICAgIGhhbmRsZXIgPSBwYXJzZUNhdGNoQ2xhdXNlKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobWF0Y2hLZXl3b3JkKCdmaW5hbGx5JykpIHtcbiAgICAgICAgICAgIGxleCgpO1xuICAgICAgICAgICAgZmluYWxpemVyID0gcGFyc2VCbG9jaygpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFoYW5kbGVyICYmICFmaW5hbGl6ZXIpIHtcbiAgICAgICAgICAgIHRocm93RXJyb3IoTWVzc2FnZXMuTm9DYXRjaE9yRmluYWxseSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbm9kZS5maW5pc2hUcnlTdGF0ZW1lbnQoYmxvY2ssIGhhbmRsZXIsIGZpbmFsaXplcik7XG4gICAgfVxuXG4gICAgLy8gMTIuMTUgVGhlIGRlYnVnZ2VyIHN0YXRlbWVudFxuXG4gICAgZnVuY3Rpb24gcGFyc2VEZWJ1Z2dlclN0YXRlbWVudChub2RlKSB7XG4gICAgICAgIGV4cGVjdEtleXdvcmQoJ2RlYnVnZ2VyJyk7XG5cbiAgICAgICAgY29uc3VtZVNlbWljb2xvbigpO1xuXG4gICAgICAgIHJldHVybiBub2RlLmZpbmlzaERlYnVnZ2VyU3RhdGVtZW50KCk7XG4gICAgfVxuXG4gICAgLy8gMTIgU3RhdGVtZW50c1xuXG4gICAgZnVuY3Rpb24gcGFyc2VTdGF0ZW1lbnQoKSB7XG4gICAgICAgIHZhciB0eXBlID0gbG9va2FoZWFkLnR5cGUsXG4gICAgICAgICAgICBleHByLFxuICAgICAgICAgICAgbGFiZWxlZEJvZHksXG4gICAgICAgICAgICBrZXksXG4gICAgICAgICAgICBub2RlO1xuXG4gICAgICAgIGlmICh0eXBlID09PSBUb2tlbi5FT0YpIHtcbiAgICAgICAgICAgIHRocm93VW5leHBlY3RlZFRva2VuKGxvb2thaGVhZCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZSA9PT0gVG9rZW4uUHVuY3R1YXRvciAmJiBsb29rYWhlYWQudmFsdWUgPT09ICd7Jykge1xuICAgICAgICAgICAgcmV0dXJuIHBhcnNlQmxvY2soKTtcbiAgICAgICAgfVxuICAgICAgICBpc0Fzc2lnbm1lbnRUYXJnZXQgPSBpc0JpbmRpbmdFbGVtZW50ID0gdHJ1ZTtcbiAgICAgICAgbm9kZSA9IG5ldyBOb2RlKCk7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09IFRva2VuLlB1bmN0dWF0b3IpIHtcbiAgICAgICAgICAgIHN3aXRjaCAobG9va2FoZWFkLnZhbHVlKSB7XG4gICAgICAgICAgICBjYXNlICc7JzpcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VFbXB0eVN0YXRlbWVudChub2RlKTtcbiAgICAgICAgICAgIGNhc2UgJygnOlxuICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZUV4cHJlc3Npb25TdGF0ZW1lbnQobm9kZSk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09IFRva2VuLktleXdvcmQpIHtcbiAgICAgICAgICAgIHN3aXRjaCAobG9va2FoZWFkLnZhbHVlKSB7XG4gICAgICAgICAgICBjYXNlICdicmVhayc6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlQnJlYWtTdGF0ZW1lbnQobm9kZSk7XG4gICAgICAgICAgICBjYXNlICdjb250aW51ZSc6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlQ29udGludWVTdGF0ZW1lbnQobm9kZSk7XG4gICAgICAgICAgICBjYXNlICdkZWJ1Z2dlcic6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlRGVidWdnZXJTdGF0ZW1lbnQobm9kZSk7XG4gICAgICAgICAgICBjYXNlICdkbyc6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlRG9XaGlsZVN0YXRlbWVudChub2RlKTtcbiAgICAgICAgICAgIGNhc2UgJ2Zvcic6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlRm9yU3RhdGVtZW50KG5vZGUpO1xuICAgICAgICAgICAgY2FzZSAnZnVuY3Rpb24nOlxuICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZUZ1bmN0aW9uRGVjbGFyYXRpb24obm9kZSk7XG4gICAgICAgICAgICBjYXNlICdpZic6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlSWZTdGF0ZW1lbnQobm9kZSk7XG4gICAgICAgICAgICBjYXNlICdyZXR1cm4nOlxuICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZVJldHVyblN0YXRlbWVudChub2RlKTtcbiAgICAgICAgICAgIGNhc2UgJ3N3aXRjaCc6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlU3dpdGNoU3RhdGVtZW50KG5vZGUpO1xuICAgICAgICAgICAgY2FzZSAndGhyb3cnOlxuICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZVRocm93U3RhdGVtZW50KG5vZGUpO1xuICAgICAgICAgICAgY2FzZSAndHJ5JzpcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VUcnlTdGF0ZW1lbnQobm9kZSk7XG4gICAgICAgICAgICBjYXNlICd2YXInOlxuICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZVZhcmlhYmxlU3RhdGVtZW50KG5vZGUpO1xuICAgICAgICAgICAgY2FzZSAnd2hpbGUnOlxuICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZVdoaWxlU3RhdGVtZW50KG5vZGUpO1xuICAgICAgICAgICAgY2FzZSAnd2l0aCc6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlV2l0aFN0YXRlbWVudChub2RlKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBleHByID0gcGFyc2VFeHByZXNzaW9uKCk7XG5cbiAgICAgICAgLy8gMTIuMTIgTGFiZWxsZWQgU3RhdGVtZW50c1xuICAgICAgICBpZiAoKGV4cHIudHlwZSA9PT0gU3ludGF4LklkZW50aWZpZXIpICYmIG1hdGNoKCc6JykpIHtcbiAgICAgICAgICAgIGxleCgpO1xuXG4gICAgICAgICAgICBrZXkgPSAnJCcgKyBleHByLm5hbWU7XG4gICAgICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHN0YXRlLmxhYmVsU2V0LCBrZXkpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3dFcnJvcihNZXNzYWdlcy5SZWRlY2xhcmF0aW9uLCAnTGFiZWwnLCBleHByLm5hbWUpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBzdGF0ZS5sYWJlbFNldFtrZXldID0gdHJ1ZTtcbiAgICAgICAgICAgIGxhYmVsZWRCb2R5ID0gcGFyc2VTdGF0ZW1lbnQoKTtcbiAgICAgICAgICAgIGRlbGV0ZSBzdGF0ZS5sYWJlbFNldFtrZXldO1xuICAgICAgICAgICAgcmV0dXJuIG5vZGUuZmluaXNoTGFiZWxlZFN0YXRlbWVudChleHByLCBsYWJlbGVkQm9keSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdW1lU2VtaWNvbG9uKCk7XG5cbiAgICAgICAgcmV0dXJuIG5vZGUuZmluaXNoRXhwcmVzc2lvblN0YXRlbWVudChleHByKTtcbiAgICB9XG5cbiAgICAvLyAxMyBGdW5jdGlvbiBEZWZpbml0aW9uXG5cbiAgICBmdW5jdGlvbiBwYXJzZUZ1bmN0aW9uU291cmNlRWxlbWVudHMoKSB7XG4gICAgICAgIHZhciBzdGF0ZW1lbnQsIGJvZHkgPSBbXSwgdG9rZW4sIGRpcmVjdGl2ZSwgZmlyc3RSZXN0cmljdGVkLFxuICAgICAgICAgICAgb2xkTGFiZWxTZXQsIG9sZEluSXRlcmF0aW9uLCBvbGRJblN3aXRjaCwgb2xkSW5GdW5jdGlvbkJvZHksIG9sZFBhcmVudGhlc2lzQ291bnQsXG4gICAgICAgICAgICBub2RlID0gbmV3IE5vZGUoKTtcblxuICAgICAgICBleHBlY3QoJ3snKTtcblxuICAgICAgICB3aGlsZSAoc3RhcnRJbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgICAgaWYgKGxvb2thaGVhZC50eXBlICE9PSBUb2tlbi5TdHJpbmdMaXRlcmFsKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0b2tlbiA9IGxvb2thaGVhZDtcblxuICAgICAgICAgICAgc3RhdGVtZW50ID0gcGFyc2VTdGF0ZW1lbnRMaXN0SXRlbSgpO1xuICAgICAgICAgICAgYm9keS5wdXNoKHN0YXRlbWVudCk7XG4gICAgICAgICAgICBpZiAoc3RhdGVtZW50LmV4cHJlc3Npb24udHlwZSAhPT0gU3ludGF4LkxpdGVyYWwpIHtcbiAgICAgICAgICAgICAgICAvLyB0aGlzIGlzIG5vdCBkaXJlY3RpdmVcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRpcmVjdGl2ZSA9IHNvdXJjZS5zbGljZSh0b2tlbi5zdGFydCArIDEsIHRva2VuLmVuZCAtIDEpO1xuICAgICAgICAgICAgaWYgKGRpcmVjdGl2ZSA9PT0gJ3VzZSBzdHJpY3QnKSB7XG4gICAgICAgICAgICAgICAgc3RyaWN0ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBpZiAoZmlyc3RSZXN0cmljdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRvbGVyYXRlVW5leHBlY3RlZFRva2VuKGZpcnN0UmVzdHJpY3RlZCwgTWVzc2FnZXMuU3RyaWN0T2N0YWxMaXRlcmFsKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmICghZmlyc3RSZXN0cmljdGVkICYmIHRva2VuLm9jdGFsKSB7XG4gICAgICAgICAgICAgICAgICAgIGZpcnN0UmVzdHJpY3RlZCA9IHRva2VuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIG9sZExhYmVsU2V0ID0gc3RhdGUubGFiZWxTZXQ7XG4gICAgICAgIG9sZEluSXRlcmF0aW9uID0gc3RhdGUuaW5JdGVyYXRpb247XG4gICAgICAgIG9sZEluU3dpdGNoID0gc3RhdGUuaW5Td2l0Y2g7XG4gICAgICAgIG9sZEluRnVuY3Rpb25Cb2R5ID0gc3RhdGUuaW5GdW5jdGlvbkJvZHk7XG4gICAgICAgIG9sZFBhcmVudGhlc2lzQ291bnQgPSBzdGF0ZS5wYXJlbnRoZXNpemVkQ291bnQ7XG5cbiAgICAgICAgc3RhdGUubGFiZWxTZXQgPSB7fTtcbiAgICAgICAgc3RhdGUuaW5JdGVyYXRpb24gPSBmYWxzZTtcbiAgICAgICAgc3RhdGUuaW5Td2l0Y2ggPSBmYWxzZTtcbiAgICAgICAgc3RhdGUuaW5GdW5jdGlvbkJvZHkgPSB0cnVlO1xuICAgICAgICBzdGF0ZS5wYXJlbnRoZXNpemVkQ291bnQgPSAwO1xuXG4gICAgICAgIHdoaWxlIChzdGFydEluZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAobWF0Y2goJ30nKSkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYm9keS5wdXNoKHBhcnNlU3RhdGVtZW50TGlzdEl0ZW0oKSk7XG4gICAgICAgIH1cblxuICAgICAgICBleHBlY3QoJ30nKTtcblxuICAgICAgICBzdGF0ZS5sYWJlbFNldCA9IG9sZExhYmVsU2V0O1xuICAgICAgICBzdGF0ZS5pbkl0ZXJhdGlvbiA9IG9sZEluSXRlcmF0aW9uO1xuICAgICAgICBzdGF0ZS5pblN3aXRjaCA9IG9sZEluU3dpdGNoO1xuICAgICAgICBzdGF0ZS5pbkZ1bmN0aW9uQm9keSA9IG9sZEluRnVuY3Rpb25Cb2R5O1xuICAgICAgICBzdGF0ZS5wYXJlbnRoZXNpemVkQ291bnQgPSBvbGRQYXJlbnRoZXNpc0NvdW50O1xuXG4gICAgICAgIHJldHVybiBub2RlLmZpbmlzaEJsb2NrU3RhdGVtZW50KGJvZHkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHZhbGlkYXRlUGFyYW0ob3B0aW9ucywgcGFyYW0sIG5hbWUpIHtcbiAgICAgICAgdmFyIGtleSA9ICckJyArIG5hbWU7XG4gICAgICAgIGlmIChzdHJpY3QpIHtcbiAgICAgICAgICAgIGlmIChpc1Jlc3RyaWN0ZWRXb3JkKG5hbWUpKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucy5zdHJpY3RlZCA9IHBhcmFtO1xuICAgICAgICAgICAgICAgIG9wdGlvbnMubWVzc2FnZSA9IE1lc3NhZ2VzLlN0cmljdFBhcmFtTmFtZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob3B0aW9ucy5wYXJhbVNldCwga2V5KSkge1xuICAgICAgICAgICAgICAgIG9wdGlvbnMuc3RyaWN0ZWQgPSBwYXJhbTtcbiAgICAgICAgICAgICAgICBvcHRpb25zLm1lc3NhZ2UgPSBNZXNzYWdlcy5TdHJpY3RQYXJhbUR1cGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoIW9wdGlvbnMuZmlyc3RSZXN0cmljdGVkKSB7XG4gICAgICAgICAgICBpZiAoaXNSZXN0cmljdGVkV29yZChuYW1lKSkge1xuICAgICAgICAgICAgICAgIG9wdGlvbnMuZmlyc3RSZXN0cmljdGVkID0gcGFyYW07XG4gICAgICAgICAgICAgICAgb3B0aW9ucy5tZXNzYWdlID0gTWVzc2FnZXMuU3RyaWN0UGFyYW1OYW1lO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChpc1N0cmljdE1vZGVSZXNlcnZlZFdvcmQobmFtZSkpIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zLmZpcnN0UmVzdHJpY3RlZCA9IHBhcmFtO1xuICAgICAgICAgICAgICAgIG9wdGlvbnMubWVzc2FnZSA9IE1lc3NhZ2VzLlN0cmljdFJlc2VydmVkV29yZDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9wdGlvbnMucGFyYW1TZXQsIGtleSkpIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zLmZpcnN0UmVzdHJpY3RlZCA9IHBhcmFtO1xuICAgICAgICAgICAgICAgIG9wdGlvbnMubWVzc2FnZSA9IE1lc3NhZ2VzLlN0cmljdFBhcmFtRHVwZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBvcHRpb25zLnBhcmFtU2V0W2tleV0gPSB0cnVlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlUGFyYW0ob3B0aW9ucykge1xuICAgICAgICB2YXIgdG9rZW4sIHBhcmFtLCBkZWY7XG5cbiAgICAgICAgdG9rZW4gPSBsb29rYWhlYWQ7XG4gICAgICAgIGlmICh0b2tlbi52YWx1ZSA9PT0gJy4uLicpIHtcbiAgICAgICAgICAgIHBhcmFtID0gcGFyc2VSZXN0RWxlbWVudCgpO1xuICAgICAgICAgICAgdmFsaWRhdGVQYXJhbShvcHRpb25zLCBwYXJhbS5hcmd1bWVudCwgcGFyYW0uYXJndW1lbnQubmFtZSk7XG4gICAgICAgICAgICBvcHRpb25zLnBhcmFtcy5wdXNoKHBhcmFtKTtcbiAgICAgICAgICAgIG9wdGlvbnMuZGVmYXVsdHMucHVzaChudWxsKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHBhcmFtID0gcGFyc2VQYXR0ZXJuV2l0aERlZmF1bHQoKTtcbiAgICAgICAgdmFsaWRhdGVQYXJhbShvcHRpb25zLCB0b2tlbiwgdG9rZW4udmFsdWUpO1xuXG4gICAgICAgIGlmIChwYXJhbS50eXBlID09PSBTeW50YXguQXNzaWdubWVudFBhdHRlcm4pIHtcbiAgICAgICAgICAgIGRlZiA9IHBhcmFtLnJpZ2h0O1xuICAgICAgICAgICAgcGFyYW0gPSBwYXJhbS5sZWZ0O1xuICAgICAgICAgICAgKytvcHRpb25zLmRlZmF1bHRDb3VudDtcbiAgICAgICAgfVxuXG4gICAgICAgIG9wdGlvbnMucGFyYW1zLnB1c2gocGFyYW0pO1xuICAgICAgICBvcHRpb25zLmRlZmF1bHRzLnB1c2goZGVmKTtcblxuICAgICAgICByZXR1cm4gIW1hdGNoKCcpJyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VQYXJhbXMoZmlyc3RSZXN0cmljdGVkKSB7XG4gICAgICAgIHZhciBvcHRpb25zO1xuXG4gICAgICAgIG9wdGlvbnMgPSB7XG4gICAgICAgICAgICBwYXJhbXM6IFtdLFxuICAgICAgICAgICAgZGVmYXVsdENvdW50OiAwLFxuICAgICAgICAgICAgZGVmYXVsdHM6IFtdLFxuICAgICAgICAgICAgZmlyc3RSZXN0cmljdGVkOiBmaXJzdFJlc3RyaWN0ZWRcbiAgICAgICAgfTtcblxuICAgICAgICBleHBlY3QoJygnKTtcblxuICAgICAgICBpZiAoIW1hdGNoKCcpJykpIHtcbiAgICAgICAgICAgIG9wdGlvbnMucGFyYW1TZXQgPSB7fTtcbiAgICAgICAgICAgIHdoaWxlIChzdGFydEluZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFwYXJzZVBhcmFtKG9wdGlvbnMpKSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBleHBlY3QoJywnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGV4cGVjdCgnKScpO1xuXG4gICAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRDb3VudCA9PT0gMCkge1xuICAgICAgICAgICAgb3B0aW9ucy5kZWZhdWx0cyA9IFtdO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHBhcmFtczogb3B0aW9ucy5wYXJhbXMsXG4gICAgICAgICAgICBkZWZhdWx0czogb3B0aW9ucy5kZWZhdWx0cyxcbiAgICAgICAgICAgIHN0cmljdGVkOiBvcHRpb25zLnN0cmljdGVkLFxuICAgICAgICAgICAgZmlyc3RSZXN0cmljdGVkOiBvcHRpb25zLmZpcnN0UmVzdHJpY3RlZCxcbiAgICAgICAgICAgIG1lc3NhZ2U6IG9wdGlvbnMubWVzc2FnZVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlRnVuY3Rpb25EZWNsYXJhdGlvbihub2RlLCBpZGVudGlmaWVySXNPcHRpb25hbCkge1xuICAgICAgICB2YXIgaWQgPSBudWxsLCBwYXJhbXMgPSBbXSwgZGVmYXVsdHMgPSBbXSwgYm9keSwgdG9rZW4sIHN0cmljdGVkLCB0bXAsIGZpcnN0UmVzdHJpY3RlZCwgbWVzc2FnZSwgcHJldmlvdXNTdHJpY3Q7XG5cbiAgICAgICAgZXhwZWN0S2V5d29yZCgnZnVuY3Rpb24nKTtcbiAgICAgICAgaWYgKCFpZGVudGlmaWVySXNPcHRpb25hbCB8fCAhbWF0Y2goJygnKSkge1xuICAgICAgICAgICAgdG9rZW4gPSBsb29rYWhlYWQ7XG4gICAgICAgICAgICBpZCA9IHBhcnNlVmFyaWFibGVJZGVudGlmaWVyKCk7XG4gICAgICAgICAgICBpZiAoc3RyaWN0KSB7XG4gICAgICAgICAgICAgICAgaWYgKGlzUmVzdHJpY3RlZFdvcmQodG9rZW4udmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRvbGVyYXRlVW5leHBlY3RlZFRva2VuKHRva2VuLCBNZXNzYWdlcy5TdHJpY3RGdW5jdGlvbk5hbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKGlzUmVzdHJpY3RlZFdvcmQodG9rZW4udmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGZpcnN0UmVzdHJpY3RlZCA9IHRva2VuO1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gTWVzc2FnZXMuU3RyaWN0RnVuY3Rpb25OYW1lO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNTdHJpY3RNb2RlUmVzZXJ2ZWRXb3JkKHRva2VuLnZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICBmaXJzdFJlc3RyaWN0ZWQgPSB0b2tlbjtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IE1lc3NhZ2VzLlN0cmljdFJlc2VydmVkV29yZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0bXAgPSBwYXJzZVBhcmFtcyhmaXJzdFJlc3RyaWN0ZWQpO1xuICAgICAgICBwYXJhbXMgPSB0bXAucGFyYW1zO1xuICAgICAgICBkZWZhdWx0cyA9IHRtcC5kZWZhdWx0cztcbiAgICAgICAgc3RyaWN0ZWQgPSB0bXAuc3RyaWN0ZWQ7XG4gICAgICAgIGZpcnN0UmVzdHJpY3RlZCA9IHRtcC5maXJzdFJlc3RyaWN0ZWQ7XG4gICAgICAgIGlmICh0bXAubWVzc2FnZSkge1xuICAgICAgICAgICAgbWVzc2FnZSA9IHRtcC5tZXNzYWdlO1xuICAgICAgICB9XG5cbiAgICAgICAgcHJldmlvdXNTdHJpY3QgPSBzdHJpY3Q7XG4gICAgICAgIGJvZHkgPSBwYXJzZUZ1bmN0aW9uU291cmNlRWxlbWVudHMoKTtcbiAgICAgICAgaWYgKHN0cmljdCAmJiBmaXJzdFJlc3RyaWN0ZWQpIHtcbiAgICAgICAgICAgIHRocm93VW5leHBlY3RlZFRva2VuKGZpcnN0UmVzdHJpY3RlZCwgbWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHN0cmljdCAmJiBzdHJpY3RlZCkge1xuICAgICAgICAgICAgdG9sZXJhdGVVbmV4cGVjdGVkVG9rZW4oc3RyaWN0ZWQsIG1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgICAgIHN0cmljdCA9IHByZXZpb3VzU3RyaWN0O1xuXG4gICAgICAgIHJldHVybiBub2RlLmZpbmlzaEZ1bmN0aW9uRGVjbGFyYXRpb24oaWQsIHBhcmFtcywgZGVmYXVsdHMsIGJvZHkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlRnVuY3Rpb25FeHByZXNzaW9uKCkge1xuICAgICAgICB2YXIgdG9rZW4sIGlkID0gbnVsbCwgc3RyaWN0ZWQsIGZpcnN0UmVzdHJpY3RlZCwgbWVzc2FnZSwgdG1wLFxuICAgICAgICAgICAgcGFyYW1zID0gW10sIGRlZmF1bHRzID0gW10sIGJvZHksIHByZXZpb3VzU3RyaWN0LCBub2RlID0gbmV3IE5vZGUoKTtcblxuICAgICAgICBleHBlY3RLZXl3b3JkKCdmdW5jdGlvbicpO1xuXG4gICAgICAgIGlmICghbWF0Y2goJygnKSkge1xuICAgICAgICAgICAgdG9rZW4gPSBsb29rYWhlYWQ7XG4gICAgICAgICAgICBpZCA9IHBhcnNlVmFyaWFibGVJZGVudGlmaWVyKCk7XG4gICAgICAgICAgICBpZiAoc3RyaWN0KSB7XG4gICAgICAgICAgICAgICAgaWYgKGlzUmVzdHJpY3RlZFdvcmQodG9rZW4udmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRvbGVyYXRlVW5leHBlY3RlZFRva2VuKHRva2VuLCBNZXNzYWdlcy5TdHJpY3RGdW5jdGlvbk5hbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKGlzUmVzdHJpY3RlZFdvcmQodG9rZW4udmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGZpcnN0UmVzdHJpY3RlZCA9IHRva2VuO1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gTWVzc2FnZXMuU3RyaWN0RnVuY3Rpb25OYW1lO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNTdHJpY3RNb2RlUmVzZXJ2ZWRXb3JkKHRva2VuLnZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICBmaXJzdFJlc3RyaWN0ZWQgPSB0b2tlbjtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IE1lc3NhZ2VzLlN0cmljdFJlc2VydmVkV29yZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0bXAgPSBwYXJzZVBhcmFtcyhmaXJzdFJlc3RyaWN0ZWQpO1xuICAgICAgICBwYXJhbXMgPSB0bXAucGFyYW1zO1xuICAgICAgICBkZWZhdWx0cyA9IHRtcC5kZWZhdWx0cztcbiAgICAgICAgc3RyaWN0ZWQgPSB0bXAuc3RyaWN0ZWQ7XG4gICAgICAgIGZpcnN0UmVzdHJpY3RlZCA9IHRtcC5maXJzdFJlc3RyaWN0ZWQ7XG4gICAgICAgIGlmICh0bXAubWVzc2FnZSkge1xuICAgICAgICAgICAgbWVzc2FnZSA9IHRtcC5tZXNzYWdlO1xuICAgICAgICB9XG5cbiAgICAgICAgcHJldmlvdXNTdHJpY3QgPSBzdHJpY3Q7XG4gICAgICAgIGJvZHkgPSBwYXJzZUZ1bmN0aW9uU291cmNlRWxlbWVudHMoKTtcbiAgICAgICAgaWYgKHN0cmljdCAmJiBmaXJzdFJlc3RyaWN0ZWQpIHtcbiAgICAgICAgICAgIHRocm93VW5leHBlY3RlZFRva2VuKGZpcnN0UmVzdHJpY3RlZCwgbWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHN0cmljdCAmJiBzdHJpY3RlZCkge1xuICAgICAgICAgICAgdG9sZXJhdGVVbmV4cGVjdGVkVG9rZW4oc3RyaWN0ZWQsIG1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgICAgIHN0cmljdCA9IHByZXZpb3VzU3RyaWN0O1xuXG4gICAgICAgIHJldHVybiBub2RlLmZpbmlzaEZ1bmN0aW9uRXhwcmVzc2lvbihpZCwgcGFyYW1zLCBkZWZhdWx0cywgYm9keSk7XG4gICAgfVxuXG5cbiAgICBmdW5jdGlvbiBwYXJzZUNsYXNzQm9keSgpIHtcbiAgICAgICAgdmFyIGNsYXNzQm9keSwgdG9rZW4sIGlzU3RhdGljLCBoYXNDb25zdHJ1Y3RvciA9IGZhbHNlLCBib2R5LCBtZXRob2QsIGNvbXB1dGVkLCBrZXk7XG5cbiAgICAgICAgY2xhc3NCb2R5ID0gbmV3IE5vZGUoKTtcblxuICAgICAgICBleHBlY3QoJ3snKTtcbiAgICAgICAgYm9keSA9IFtdO1xuICAgICAgICB3aGlsZSAoIW1hdGNoKCd9JykpIHtcbiAgICAgICAgICAgIGlmIChtYXRjaCgnOycpKSB7XG4gICAgICAgICAgICAgICAgbGV4KCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG1ldGhvZCA9IG5ldyBOb2RlKCk7XG4gICAgICAgICAgICAgICAgdG9rZW4gPSBsb29rYWhlYWQ7XG4gICAgICAgICAgICAgICAgaXNTdGF0aWMgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBjb21wdXRlZCA9IG1hdGNoKCdbJyk7XG4gICAgICAgICAgICAgICAga2V5ID0gcGFyc2VPYmplY3RQcm9wZXJ0eUtleSgpO1xuICAgICAgICAgICAgICAgIGlmIChrZXkubmFtZSA9PT0gJ3N0YXRpYycgJiYgbG9va2FoZWFkUHJvcGVydHlOYW1lKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdG9rZW4gPSBsb29rYWhlYWQ7XG4gICAgICAgICAgICAgICAgICAgIGlzU3RhdGljID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgY29tcHV0ZWQgPSBtYXRjaCgnWycpO1xuICAgICAgICAgICAgICAgICAgICBrZXkgPSBwYXJzZU9iamVjdFByb3BlcnR5S2V5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG1ldGhvZCA9IHRyeVBhcnNlTWV0aG9kRGVmaW5pdGlvbih0b2tlbiwga2V5LCBjb21wdXRlZCwgbWV0aG9kKTtcbiAgICAgICAgICAgICAgICBpZiAobWV0aG9kKSB7XG4gICAgICAgICAgICAgICAgICAgIG1ldGhvZFsnc3RhdGljJ10gPSBpc1N0YXRpYztcbiAgICAgICAgICAgICAgICAgICAgaWYgKG1ldGhvZC5raW5kID09PSAnaW5pdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZC5raW5kID0gJ21ldGhvZCc7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc1N0YXRpYykge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFtZXRob2QuY29tcHV0ZWQgJiYgKG1ldGhvZC5rZXkubmFtZSB8fCBtZXRob2Qua2V5LnZhbHVlLnRvU3RyaW5nKCkpID09PSAnY29uc3RydWN0b3InKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1ldGhvZC5raW5kICE9PSAnbWV0aG9kJyB8fCAhbWV0aG9kLm1ldGhvZCB8fCBtZXRob2QudmFsdWUuZ2VuZXJhdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93VW5leHBlY3RlZFRva2VuKHRva2VuLCBNZXNzYWdlcy5Db25zdHJ1Y3RvclNwZWNpYWxNZXRob2QpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaGFzQ29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dVbmV4cGVjdGVkVG9rZW4odG9rZW4sIE1lc3NhZ2VzLkR1cGxpY2F0ZUNvbnN0cnVjdG9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYXNDb25zdHJ1Y3RvciA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZC5raW5kID0gJ2NvbnN0cnVjdG9yJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbWV0aG9kLmNvbXB1dGVkICYmIChtZXRob2Qua2V5Lm5hbWUgfHwgbWV0aG9kLmtleS52YWx1ZS50b1N0cmluZygpKSA9PT0gJ3Byb3RvdHlwZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd1VuZXhwZWN0ZWRUb2tlbih0b2tlbiwgTWVzc2FnZXMuU3RhdGljUHJvdG90eXBlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBtZXRob2QudHlwZSA9IFN5bnRheC5NZXRob2REZWZpbml0aW9uO1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgbWV0aG9kLm1ldGhvZDtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIG1ldGhvZC5zaG9ydGhhbmQ7XG4gICAgICAgICAgICAgICAgICAgIGJvZHkucHVzaChtZXRob2QpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93VW5leHBlY3RlZFRva2VuKGxvb2thaGVhZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxleCgpO1xuICAgICAgICByZXR1cm4gY2xhc3NCb2R5LmZpbmlzaENsYXNzQm9keShib2R5KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZUNsYXNzRGVjbGFyYXRpb24oaWRlbnRpZmllcklzT3B0aW9uYWwpIHtcbiAgICAgICAgdmFyIGlkID0gbnVsbCwgc3VwZXJDbGFzcyA9IG51bGwsIGNsYXNzTm9kZSA9IG5ldyBOb2RlKCksIGNsYXNzQm9keSwgcHJldmlvdXNTdHJpY3QgPSBzdHJpY3Q7XG4gICAgICAgIHN0cmljdCA9IHRydWU7XG5cbiAgICAgICAgZXhwZWN0S2V5d29yZCgnY2xhc3MnKTtcblxuICAgICAgICBpZiAoIWlkZW50aWZpZXJJc09wdGlvbmFsIHx8IGxvb2thaGVhZC50eXBlID09PSBUb2tlbi5JZGVudGlmaWVyKSB7XG4gICAgICAgICAgICBpZCA9IHBhcnNlVmFyaWFibGVJZGVudGlmaWVyKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobWF0Y2hLZXl3b3JkKCdleHRlbmRzJykpIHtcbiAgICAgICAgICAgIGxleCgpO1xuICAgICAgICAgICAgc3VwZXJDbGFzcyA9IGlzb2xhdGVDb3ZlckdyYW1tYXIocGFyc2VMZWZ0SGFuZFNpZGVFeHByZXNzaW9uQWxsb3dDYWxsKTtcbiAgICAgICAgfVxuICAgICAgICBjbGFzc0JvZHkgPSBwYXJzZUNsYXNzQm9keSgpO1xuICAgICAgICBzdHJpY3QgPSBwcmV2aW91c1N0cmljdDtcblxuICAgICAgICByZXR1cm4gY2xhc3NOb2RlLmZpbmlzaENsYXNzRGVjbGFyYXRpb24oaWQsIHN1cGVyQ2xhc3MsIGNsYXNzQm9keSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VDbGFzc0V4cHJlc3Npb24oKSB7XG4gICAgICAgIHZhciBpZCA9IG51bGwsIHN1cGVyQ2xhc3MgPSBudWxsLCBjbGFzc05vZGUgPSBuZXcgTm9kZSgpLCBjbGFzc0JvZHksIHByZXZpb3VzU3RyaWN0ID0gc3RyaWN0O1xuICAgICAgICBzdHJpY3QgPSB0cnVlO1xuXG4gICAgICAgIGV4cGVjdEtleXdvcmQoJ2NsYXNzJyk7XG5cbiAgICAgICAgaWYgKGxvb2thaGVhZC50eXBlID09PSBUb2tlbi5JZGVudGlmaWVyKSB7XG4gICAgICAgICAgICBpZCA9IHBhcnNlVmFyaWFibGVJZGVudGlmaWVyKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobWF0Y2hLZXl3b3JkKCdleHRlbmRzJykpIHtcbiAgICAgICAgICAgIGxleCgpO1xuICAgICAgICAgICAgc3VwZXJDbGFzcyA9IGlzb2xhdGVDb3ZlckdyYW1tYXIocGFyc2VMZWZ0SGFuZFNpZGVFeHByZXNzaW9uQWxsb3dDYWxsKTtcbiAgICAgICAgfVxuICAgICAgICBjbGFzc0JvZHkgPSBwYXJzZUNsYXNzQm9keSgpO1xuICAgICAgICBzdHJpY3QgPSBwcmV2aW91c1N0cmljdDtcblxuICAgICAgICByZXR1cm4gY2xhc3NOb2RlLmZpbmlzaENsYXNzRXhwcmVzc2lvbihpZCwgc3VwZXJDbGFzcywgY2xhc3NCb2R5KTtcbiAgICB9XG5cbiAgICAvLyBNb2R1bGVzIGdyYW1tYXIgZnJvbTpcbiAgICAvLyBwZW9wbGUubW96aWxsYS5vcmcvfmpvcmVuZG9yZmYvZXM2LWRyYWZ0Lmh0bWxcblxuICAgIGZ1bmN0aW9uIHBhcnNlTW9kdWxlU3BlY2lmaWVyKCkge1xuICAgICAgICB2YXIgbm9kZSA9IG5ldyBOb2RlKCk7XG5cbiAgICAgICAgaWYgKGxvb2thaGVhZC50eXBlICE9PSBUb2tlbi5TdHJpbmdMaXRlcmFsKSB7XG4gICAgICAgICAgICB0aHJvd0Vycm9yKE1lc3NhZ2VzLkludmFsaWRNb2R1bGVTcGVjaWZpZXIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBub2RlLmZpbmlzaExpdGVyYWwobGV4KCkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlRXhwb3J0U3BlY2lmaWVyKCkge1xuICAgICAgICB2YXIgZXhwb3J0ZWQsIGxvY2FsLCBub2RlID0gbmV3IE5vZGUoKSwgZGVmO1xuICAgICAgICBpZiAobWF0Y2hLZXl3b3JkKCdkZWZhdWx0JykpIHtcbiAgICAgICAgICAgIC8vIGV4cG9ydCB7ZGVmYXVsdH0gZnJvbSAnc29tZXRoaW5nJztcbiAgICAgICAgICAgIGRlZiA9IG5ldyBOb2RlKCk7XG4gICAgICAgICAgICBsZXgoKTtcbiAgICAgICAgICAgIGxvY2FsID0gZGVmLmZpbmlzaElkZW50aWZpZXIoJ2RlZmF1bHQnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxvY2FsID0gcGFyc2VWYXJpYWJsZUlkZW50aWZpZXIoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobWF0Y2hDb250ZXh0dWFsS2V5d29yZCgnYXMnKSkge1xuICAgICAgICAgICAgbGV4KCk7XG4gICAgICAgICAgICBleHBvcnRlZCA9IHBhcnNlTm9uQ29tcHV0ZWRQcm9wZXJ0eSgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBub2RlLmZpbmlzaEV4cG9ydFNwZWNpZmllcihsb2NhbCwgZXhwb3J0ZWQpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlRXhwb3J0TmFtZWREZWNsYXJhdGlvbihub2RlKSB7XG4gICAgICAgIHZhciBkZWNsYXJhdGlvbiA9IG51bGwsXG4gICAgICAgICAgICBpc0V4cG9ydEZyb21JZGVudGlmaWVyLFxuICAgICAgICAgICAgc3JjID0gbnVsbCwgc3BlY2lmaWVycyA9IFtdO1xuXG4gICAgICAgIC8vIG5vbi1kZWZhdWx0IGV4cG9ydFxuICAgICAgICBpZiAobG9va2FoZWFkLnR5cGUgPT09IFRva2VuLktleXdvcmQpIHtcbiAgICAgICAgICAgIC8vIGNvdmVyczpcbiAgICAgICAgICAgIC8vIGV4cG9ydCB2YXIgZiA9IDE7XG4gICAgICAgICAgICBzd2l0Y2ggKGxvb2thaGVhZC52YWx1ZSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ2xldCc6XG4gICAgICAgICAgICAgICAgY2FzZSAnY29uc3QnOlxuICAgICAgICAgICAgICAgIGNhc2UgJ3Zhcic6XG4gICAgICAgICAgICAgICAgY2FzZSAnY2xhc3MnOlxuICAgICAgICAgICAgICAgIGNhc2UgJ2Z1bmN0aW9uJzpcbiAgICAgICAgICAgICAgICAgICAgZGVjbGFyYXRpb24gPSBwYXJzZVN0YXRlbWVudExpc3RJdGVtKCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBub2RlLmZpbmlzaEV4cG9ydE5hbWVkRGVjbGFyYXRpb24oZGVjbGFyYXRpb24sIHNwZWNpZmllcnMsIG51bGwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZXhwZWN0KCd7Jyk7XG4gICAgICAgIGlmICghbWF0Y2goJ30nKSkge1xuICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICAgIGlzRXhwb3J0RnJvbUlkZW50aWZpZXIgPSBpc0V4cG9ydEZyb21JZGVudGlmaWVyIHx8IG1hdGNoS2V5d29yZCgnZGVmYXVsdCcpO1xuICAgICAgICAgICAgICAgIHNwZWNpZmllcnMucHVzaChwYXJzZUV4cG9ydFNwZWNpZmllcigpKTtcbiAgICAgICAgICAgIH0gd2hpbGUgKG1hdGNoKCcsJykgJiYgbGV4KCkpO1xuICAgICAgICB9XG4gICAgICAgIGV4cGVjdCgnfScpO1xuXG4gICAgICAgIGlmIChtYXRjaENvbnRleHR1YWxLZXl3b3JkKCdmcm9tJykpIHtcbiAgICAgICAgICAgIC8vIGNvdmVyaW5nOlxuICAgICAgICAgICAgLy8gZXhwb3J0IHtkZWZhdWx0fSBmcm9tICdmb28nO1xuICAgICAgICAgICAgLy8gZXhwb3J0IHtmb299IGZyb20gJ2Zvbyc7XG4gICAgICAgICAgICBsZXgoKTtcbiAgICAgICAgICAgIHNyYyA9IHBhcnNlTW9kdWxlU3BlY2lmaWVyKCk7XG4gICAgICAgICAgICBjb25zdW1lU2VtaWNvbG9uKCk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNFeHBvcnRGcm9tSWRlbnRpZmllcikge1xuICAgICAgICAgICAgLy8gY292ZXJpbmc6XG4gICAgICAgICAgICAvLyBleHBvcnQge2RlZmF1bHR9OyAvLyBtaXNzaW5nIGZyb21DbGF1c2VcbiAgICAgICAgICAgIHRocm93RXJyb3IobG9va2FoZWFkLnZhbHVlID9cbiAgICAgICAgICAgICAgICAgICAgTWVzc2FnZXMuVW5leHBlY3RlZFRva2VuIDogTWVzc2FnZXMuTWlzc2luZ0Zyb21DbGF1c2UsIGxvb2thaGVhZC52YWx1ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBjb3ZlclxuICAgICAgICAgICAgLy8gZXhwb3J0IHtmb299O1xuICAgICAgICAgICAgY29uc3VtZVNlbWljb2xvbigpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBub2RlLmZpbmlzaEV4cG9ydE5hbWVkRGVjbGFyYXRpb24oZGVjbGFyYXRpb24sIHNwZWNpZmllcnMsIHNyYyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VFeHBvcnREZWZhdWx0RGVjbGFyYXRpb24obm9kZSkge1xuICAgICAgICB2YXIgZGVjbGFyYXRpb24gPSBudWxsLFxuICAgICAgICAgICAgZXhwcmVzc2lvbiA9IG51bGw7XG5cbiAgICAgICAgLy8gY292ZXJzOlxuICAgICAgICAvLyBleHBvcnQgZGVmYXVsdCAuLi5cbiAgICAgICAgZXhwZWN0S2V5d29yZCgnZGVmYXVsdCcpO1xuXG4gICAgICAgIGlmIChtYXRjaEtleXdvcmQoJ2Z1bmN0aW9uJykpIHtcbiAgICAgICAgICAgIC8vIGNvdmVyczpcbiAgICAgICAgICAgIC8vIGV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGZvbyAoKSB7fVxuICAgICAgICAgICAgLy8gZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKCkge31cbiAgICAgICAgICAgIGRlY2xhcmF0aW9uID0gcGFyc2VGdW5jdGlvbkRlY2xhcmF0aW9uKG5ldyBOb2RlKCksIHRydWUpO1xuICAgICAgICAgICAgcmV0dXJuIG5vZGUuZmluaXNoRXhwb3J0RGVmYXVsdERlY2xhcmF0aW9uKGRlY2xhcmF0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobWF0Y2hLZXl3b3JkKCdjbGFzcycpKSB7XG4gICAgICAgICAgICBkZWNsYXJhdGlvbiA9IHBhcnNlQ2xhc3NEZWNsYXJhdGlvbih0cnVlKTtcbiAgICAgICAgICAgIHJldHVybiBub2RlLmZpbmlzaEV4cG9ydERlZmF1bHREZWNsYXJhdGlvbihkZWNsYXJhdGlvbik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobWF0Y2hDb250ZXh0dWFsS2V5d29yZCgnZnJvbScpKSB7XG4gICAgICAgICAgICB0aHJvd0Vycm9yKE1lc3NhZ2VzLlVuZXhwZWN0ZWRUb2tlbiwgbG9va2FoZWFkLnZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNvdmVyczpcbiAgICAgICAgLy8gZXhwb3J0IGRlZmF1bHQge307XG4gICAgICAgIC8vIGV4cG9ydCBkZWZhdWx0IFtdO1xuICAgICAgICAvLyBleHBvcnQgZGVmYXVsdCAoMSArIDIpO1xuICAgICAgICBpZiAobWF0Y2goJ3snKSkge1xuICAgICAgICAgICAgZXhwcmVzc2lvbiA9IHBhcnNlT2JqZWN0SW5pdGlhbGlzZXIoKTtcbiAgICAgICAgfSBlbHNlIGlmIChtYXRjaCgnWycpKSB7XG4gICAgICAgICAgICBleHByZXNzaW9uID0gcGFyc2VBcnJheUluaXRpYWxpc2VyKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBleHByZXNzaW9uID0gcGFyc2VBc3NpZ25tZW50RXhwcmVzc2lvbigpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN1bWVTZW1pY29sb24oKTtcbiAgICAgICAgcmV0dXJuIG5vZGUuZmluaXNoRXhwb3J0RGVmYXVsdERlY2xhcmF0aW9uKGV4cHJlc3Npb24pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlRXhwb3J0QWxsRGVjbGFyYXRpb24obm9kZSkge1xuICAgICAgICB2YXIgc3JjO1xuXG4gICAgICAgIC8vIGNvdmVyczpcbiAgICAgICAgLy8gZXhwb3J0ICogZnJvbSAnZm9vJztcbiAgICAgICAgZXhwZWN0KCcqJyk7XG4gICAgICAgIGlmICghbWF0Y2hDb250ZXh0dWFsS2V5d29yZCgnZnJvbScpKSB7XG4gICAgICAgICAgICB0aHJvd0Vycm9yKGxvb2thaGVhZC52YWx1ZSA/XG4gICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VzLlVuZXhwZWN0ZWRUb2tlbiA6IE1lc3NhZ2VzLk1pc3NpbmdGcm9tQ2xhdXNlLCBsb29rYWhlYWQudmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGxleCgpO1xuICAgICAgICBzcmMgPSBwYXJzZU1vZHVsZVNwZWNpZmllcigpO1xuICAgICAgICBjb25zdW1lU2VtaWNvbG9uKCk7XG5cbiAgICAgICAgcmV0dXJuIG5vZGUuZmluaXNoRXhwb3J0QWxsRGVjbGFyYXRpb24oc3JjKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZUV4cG9ydERlY2xhcmF0aW9uKCkge1xuICAgICAgICB2YXIgbm9kZSA9IG5ldyBOb2RlKCk7XG4gICAgICAgIGlmIChzdGF0ZS5pbkZ1bmN0aW9uQm9keSkge1xuICAgICAgICAgICAgdGhyb3dFcnJvcihNZXNzYWdlcy5JbGxlZ2FsRXhwb3J0RGVjbGFyYXRpb24pO1xuICAgICAgICB9XG5cbiAgICAgICAgZXhwZWN0S2V5d29yZCgnZXhwb3J0Jyk7XG5cbiAgICAgICAgaWYgKG1hdGNoS2V5d29yZCgnZGVmYXVsdCcpKSB7XG4gICAgICAgICAgICByZXR1cm4gcGFyc2VFeHBvcnREZWZhdWx0RGVjbGFyYXRpb24obm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1hdGNoKCcqJykpIHtcbiAgICAgICAgICAgIHJldHVybiBwYXJzZUV4cG9ydEFsbERlY2xhcmF0aW9uKG5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwYXJzZUV4cG9ydE5hbWVkRGVjbGFyYXRpb24obm9kZSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VJbXBvcnRTcGVjaWZpZXIoKSB7XG4gICAgICAgIC8vIGltcG9ydCB7PGZvbyBhcyBiYXI+fSAuLi47XG4gICAgICAgIHZhciBsb2NhbCwgaW1wb3J0ZWQsIG5vZGUgPSBuZXcgTm9kZSgpO1xuXG4gICAgICAgIGltcG9ydGVkID0gcGFyc2VOb25Db21wdXRlZFByb3BlcnR5KCk7XG4gICAgICAgIGlmIChtYXRjaENvbnRleHR1YWxLZXl3b3JkKCdhcycpKSB7XG4gICAgICAgICAgICBsZXgoKTtcbiAgICAgICAgICAgIGxvY2FsID0gcGFyc2VWYXJpYWJsZUlkZW50aWZpZXIoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBub2RlLmZpbmlzaEltcG9ydFNwZWNpZmllcihsb2NhbCwgaW1wb3J0ZWQpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlTmFtZWRJbXBvcnRzKCkge1xuICAgICAgICB2YXIgc3BlY2lmaWVycyA9IFtdO1xuICAgICAgICAvLyB7Zm9vLCBiYXIgYXMgYmFzfVxuICAgICAgICBleHBlY3QoJ3snKTtcbiAgICAgICAgaWYgKCFtYXRjaCgnfScpKSB7XG4gICAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAgICAgc3BlY2lmaWVycy5wdXNoKHBhcnNlSW1wb3J0U3BlY2lmaWVyKCkpO1xuICAgICAgICAgICAgfSB3aGlsZSAobWF0Y2goJywnKSAmJiBsZXgoKSk7XG4gICAgICAgIH1cbiAgICAgICAgZXhwZWN0KCd9Jyk7XG4gICAgICAgIHJldHVybiBzcGVjaWZpZXJzO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlSW1wb3J0RGVmYXVsdFNwZWNpZmllcigpIHtcbiAgICAgICAgLy8gaW1wb3J0IDxmb28+IC4uLjtcbiAgICAgICAgdmFyIGxvY2FsLCBub2RlID0gbmV3IE5vZGUoKTtcblxuICAgICAgICBsb2NhbCA9IHBhcnNlTm9uQ29tcHV0ZWRQcm9wZXJ0eSgpO1xuXG4gICAgICAgIHJldHVybiBub2RlLmZpbmlzaEltcG9ydERlZmF1bHRTcGVjaWZpZXIobG9jYWwpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlSW1wb3J0TmFtZXNwYWNlU3BlY2lmaWVyKCkge1xuICAgICAgICAvLyBpbXBvcnQgPCogYXMgZm9vPiAuLi47XG4gICAgICAgIHZhciBsb2NhbCwgbm9kZSA9IG5ldyBOb2RlKCk7XG5cbiAgICAgICAgZXhwZWN0KCcqJyk7XG4gICAgICAgIGlmICghbWF0Y2hDb250ZXh0dWFsS2V5d29yZCgnYXMnKSkge1xuICAgICAgICAgICAgdGhyb3dFcnJvcihNZXNzYWdlcy5Ob0FzQWZ0ZXJJbXBvcnROYW1lc3BhY2UpO1xuICAgICAgICB9XG4gICAgICAgIGxleCgpO1xuICAgICAgICBsb2NhbCA9IHBhcnNlTm9uQ29tcHV0ZWRQcm9wZXJ0eSgpO1xuXG4gICAgICAgIHJldHVybiBub2RlLmZpbmlzaEltcG9ydE5hbWVzcGFjZVNwZWNpZmllcihsb2NhbCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VJbXBvcnREZWNsYXJhdGlvbigpIHtcbiAgICAgICAgdmFyIHNwZWNpZmllcnMsIHNyYywgbm9kZSA9IG5ldyBOb2RlKCk7XG5cbiAgICAgICAgaWYgKHN0YXRlLmluRnVuY3Rpb25Cb2R5KSB7XG4gICAgICAgICAgICB0aHJvd0Vycm9yKE1lc3NhZ2VzLklsbGVnYWxJbXBvcnREZWNsYXJhdGlvbik7XG4gICAgICAgIH1cblxuICAgICAgICBleHBlY3RLZXl3b3JkKCdpbXBvcnQnKTtcbiAgICAgICAgc3BlY2lmaWVycyA9IFtdO1xuXG4gICAgICAgIGlmIChsb29rYWhlYWQudHlwZSA9PT0gVG9rZW4uU3RyaW5nTGl0ZXJhbCkge1xuICAgICAgICAgICAgLy8gY292ZXJzOlxuICAgICAgICAgICAgLy8gaW1wb3J0ICdmb28nO1xuICAgICAgICAgICAgc3JjID0gcGFyc2VNb2R1bGVTcGVjaWZpZXIoKTtcbiAgICAgICAgICAgIGNvbnN1bWVTZW1pY29sb24oKTtcbiAgICAgICAgICAgIHJldHVybiBub2RlLmZpbmlzaEltcG9ydERlY2xhcmF0aW9uKHNwZWNpZmllcnMsIHNyYyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIW1hdGNoS2V5d29yZCgnZGVmYXVsdCcpICYmIGlzSWRlbnRpZmllck5hbWUobG9va2FoZWFkKSkge1xuICAgICAgICAgICAgLy8gY292ZXJzOlxuICAgICAgICAgICAgLy8gaW1wb3J0IGZvb1xuICAgICAgICAgICAgLy8gaW1wb3J0IGZvbywgLi4uXG4gICAgICAgICAgICBzcGVjaWZpZXJzLnB1c2gocGFyc2VJbXBvcnREZWZhdWx0U3BlY2lmaWVyKCkpO1xuICAgICAgICAgICAgaWYgKG1hdGNoKCcsJykpIHtcbiAgICAgICAgICAgICAgICBsZXgoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAobWF0Y2goJyonKSkge1xuICAgICAgICAgICAgLy8gY292ZXJzOlxuICAgICAgICAgICAgLy8gaW1wb3J0IGZvbywgKiBhcyBmb29cbiAgICAgICAgICAgIC8vIGltcG9ydCAqIGFzIGZvb1xuICAgICAgICAgICAgc3BlY2lmaWVycy5wdXNoKHBhcnNlSW1wb3J0TmFtZXNwYWNlU3BlY2lmaWVyKCkpO1xuICAgICAgICB9IGVsc2UgaWYgKG1hdGNoKCd7JykpIHtcbiAgICAgICAgICAgIC8vIGNvdmVyczpcbiAgICAgICAgICAgIC8vIGltcG9ydCBmb28sIHtiYXJ9XG4gICAgICAgICAgICAvLyBpbXBvcnQge2Jhcn1cbiAgICAgICAgICAgIHNwZWNpZmllcnMgPSBzcGVjaWZpZXJzLmNvbmNhdChwYXJzZU5hbWVkSW1wb3J0cygpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghbWF0Y2hDb250ZXh0dWFsS2V5d29yZCgnZnJvbScpKSB7XG4gICAgICAgICAgICB0aHJvd0Vycm9yKGxvb2thaGVhZC52YWx1ZSA/XG4gICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VzLlVuZXhwZWN0ZWRUb2tlbiA6IE1lc3NhZ2VzLk1pc3NpbmdGcm9tQ2xhdXNlLCBsb29rYWhlYWQudmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGxleCgpO1xuICAgICAgICBzcmMgPSBwYXJzZU1vZHVsZVNwZWNpZmllcigpO1xuICAgICAgICBjb25zdW1lU2VtaWNvbG9uKCk7XG5cbiAgICAgICAgcmV0dXJuIG5vZGUuZmluaXNoSW1wb3J0RGVjbGFyYXRpb24oc3BlY2lmaWVycywgc3JjKTtcbiAgICB9XG5cbiAgICAvLyAxNCBQcm9ncmFtXG5cbiAgICBmdW5jdGlvbiBwYXJzZVNjcmlwdEJvZHkoKSB7XG4gICAgICAgIHZhciBzdGF0ZW1lbnQsIGJvZHkgPSBbXSwgdG9rZW4sIGRpcmVjdGl2ZSwgZmlyc3RSZXN0cmljdGVkO1xuXG4gICAgICAgIHdoaWxlIChzdGFydEluZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgICB0b2tlbiA9IGxvb2thaGVhZDtcbiAgICAgICAgICAgIGlmICh0b2tlbi50eXBlICE9PSBUb2tlbi5TdHJpbmdMaXRlcmFsKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHN0YXRlbWVudCA9IHBhcnNlU3RhdGVtZW50TGlzdEl0ZW0oKTtcbiAgICAgICAgICAgIGJvZHkucHVzaChzdGF0ZW1lbnQpO1xuICAgICAgICAgICAgaWYgKHN0YXRlbWVudC5leHByZXNzaW9uLnR5cGUgIT09IFN5bnRheC5MaXRlcmFsKSB7XG4gICAgICAgICAgICAgICAgLy8gdGhpcyBpcyBub3QgZGlyZWN0aXZlXG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkaXJlY3RpdmUgPSBzb3VyY2Uuc2xpY2UodG9rZW4uc3RhcnQgKyAxLCB0b2tlbi5lbmQgLSAxKTtcbiAgICAgICAgICAgIGlmIChkaXJlY3RpdmUgPT09ICd1c2Ugc3RyaWN0Jykge1xuICAgICAgICAgICAgICAgIHN0cmljdCA9IHRydWU7XG4gICAgICAgICAgICAgICAgaWYgKGZpcnN0UmVzdHJpY3RlZCkge1xuICAgICAgICAgICAgICAgICAgICB0b2xlcmF0ZVVuZXhwZWN0ZWRUb2tlbihmaXJzdFJlc3RyaWN0ZWQsIE1lc3NhZ2VzLlN0cmljdE9jdGFsTGl0ZXJhbCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAoIWZpcnN0UmVzdHJpY3RlZCAmJiB0b2tlbi5vY3RhbCkge1xuICAgICAgICAgICAgICAgICAgICBmaXJzdFJlc3RyaWN0ZWQgPSB0b2tlbjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB3aGlsZSAoc3RhcnRJbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgICAgc3RhdGVtZW50ID0gcGFyc2VTdGF0ZW1lbnRMaXN0SXRlbSgpO1xuICAgICAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICAgICAgICBpZiAodHlwZW9mIHN0YXRlbWVudCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJvZHkucHVzaChzdGF0ZW1lbnQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBib2R5O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlUHJvZ3JhbSgpIHtcbiAgICAgICAgdmFyIGJvZHksIG5vZGU7XG5cbiAgICAgICAgcGVlaygpO1xuICAgICAgICBub2RlID0gbmV3IE5vZGUoKTtcblxuICAgICAgICBib2R5ID0gcGFyc2VTY3JpcHRCb2R5KCk7XG4gICAgICAgIHJldHVybiBub2RlLmZpbmlzaFByb2dyYW0oYm9keSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZmlsdGVyVG9rZW5Mb2NhdGlvbigpIHtcbiAgICAgICAgdmFyIGksIGVudHJ5LCB0b2tlbiwgdG9rZW5zID0gW107XG5cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGV4dHJhLnRva2Vucy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgZW50cnkgPSBleHRyYS50b2tlbnNbaV07XG4gICAgICAgICAgICB0b2tlbiA9IHtcbiAgICAgICAgICAgICAgICB0eXBlOiBlbnRyeS50eXBlLFxuICAgICAgICAgICAgICAgIHZhbHVlOiBlbnRyeS52YWx1ZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmIChlbnRyeS5yZWdleCkge1xuICAgICAgICAgICAgICAgIHRva2VuLnJlZ2V4ID0ge1xuICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuOiBlbnRyeS5yZWdleC5wYXR0ZXJuLFxuICAgICAgICAgICAgICAgICAgICBmbGFnczogZW50cnkucmVnZXguZmxhZ3NcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGV4dHJhLnJhbmdlKSB7XG4gICAgICAgICAgICAgICAgdG9rZW4ucmFuZ2UgPSBlbnRyeS5yYW5nZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChleHRyYS5sb2MpIHtcbiAgICAgICAgICAgICAgICB0b2tlbi5sb2MgPSBlbnRyeS5sb2M7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0b2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgIH1cblxuICAgICAgICBleHRyYS50b2tlbnMgPSB0b2tlbnM7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdG9rZW5pemUoY29kZSwgb3B0aW9ucykge1xuICAgICAgICB2YXIgdG9TdHJpbmcsXG4gICAgICAgICAgICB0b2tlbnM7XG5cbiAgICAgICAgdG9TdHJpbmcgPSBTdHJpbmc7XG4gICAgICAgIGlmICh0eXBlb2YgY29kZSAhPT0gJ3N0cmluZycgJiYgIShjb2RlIGluc3RhbmNlb2YgU3RyaW5nKSkge1xuICAgICAgICAgICAgY29kZSA9IHRvU3RyaW5nKGNvZGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgc291cmNlID0gY29kZTtcbiAgICAgICAgaW5kZXggPSAwO1xuICAgICAgICBsaW5lTnVtYmVyID0gKHNvdXJjZS5sZW5ndGggPiAwKSA/IDEgOiAwO1xuICAgICAgICBsaW5lU3RhcnQgPSAwO1xuICAgICAgICBzdGFydEluZGV4ID0gaW5kZXg7XG4gICAgICAgIHN0YXJ0TGluZU51bWJlciA9IGxpbmVOdW1iZXI7XG4gICAgICAgIHN0YXJ0TGluZVN0YXJ0ID0gbGluZVN0YXJ0O1xuICAgICAgICBsZW5ndGggPSBzb3VyY2UubGVuZ3RoO1xuICAgICAgICBsb29rYWhlYWQgPSBudWxsO1xuICAgICAgICBzdGF0ZSA9IHtcbiAgICAgICAgICAgIGFsbG93SW46IHRydWUsXG4gICAgICAgICAgICBsYWJlbFNldDoge30sXG4gICAgICAgICAgICBpbkZ1bmN0aW9uQm9keTogZmFsc2UsXG4gICAgICAgICAgICBpbkl0ZXJhdGlvbjogZmFsc2UsXG4gICAgICAgICAgICBpblN3aXRjaDogZmFsc2UsXG4gICAgICAgICAgICBsYXN0Q29tbWVudFN0YXJ0OiAtMSxcbiAgICAgICAgICAgIGN1cmx5U3RhY2s6IFtdXG4gICAgICAgIH07XG5cbiAgICAgICAgZXh0cmEgPSB7fTtcblxuICAgICAgICAvLyBPcHRpb25zIG1hdGNoaW5nLlxuICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAgICAgICAvLyBPZiBjb3Vyc2Ugd2UgY29sbGVjdCB0b2tlbnMgaGVyZS5cbiAgICAgICAgb3B0aW9ucy50b2tlbnMgPSB0cnVlO1xuICAgICAgICBleHRyYS50b2tlbnMgPSBbXTtcbiAgICAgICAgZXh0cmEudG9rZW5pemUgPSB0cnVlO1xuICAgICAgICAvLyBUaGUgZm9sbG93aW5nIHR3byBmaWVsZHMgYXJlIG5lY2Vzc2FyeSB0byBjb21wdXRlIHRoZSBSZWdleCB0b2tlbnMuXG4gICAgICAgIGV4dHJhLm9wZW5QYXJlblRva2VuID0gLTE7XG4gICAgICAgIGV4dHJhLm9wZW5DdXJseVRva2VuID0gLTE7XG5cbiAgICAgICAgZXh0cmEucmFuZ2UgPSAodHlwZW9mIG9wdGlvbnMucmFuZ2UgPT09ICdib29sZWFuJykgJiYgb3B0aW9ucy5yYW5nZTtcbiAgICAgICAgZXh0cmEubG9jID0gKHR5cGVvZiBvcHRpb25zLmxvYyA9PT0gJ2Jvb2xlYW4nKSAmJiBvcHRpb25zLmxvYztcblxuICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMuY29tbWVudCA9PT0gJ2Jvb2xlYW4nICYmIG9wdGlvbnMuY29tbWVudCkge1xuICAgICAgICAgICAgZXh0cmEuY29tbWVudHMgPSBbXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMudG9sZXJhbnQgPT09ICdib29sZWFuJyAmJiBvcHRpb25zLnRvbGVyYW50KSB7XG4gICAgICAgICAgICBleHRyYS5lcnJvcnMgPSBbXTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBwZWVrKCk7XG4gICAgICAgICAgICBpZiAobG9va2FoZWFkLnR5cGUgPT09IFRva2VuLkVPRikge1xuICAgICAgICAgICAgICAgIHJldHVybiBleHRyYS50b2tlbnM7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxleCgpO1xuICAgICAgICAgICAgd2hpbGUgKGxvb2thaGVhZC50eXBlICE9PSBUb2tlbi5FT0YpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBsZXgoKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChsZXhFcnJvcikge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXh0cmEuZXJyb3JzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWNvcmRFcnJvcihsZXhFcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBXZSBoYXZlIHRvIGJyZWFrIG9uIHRoZSBmaXJzdCBlcnJvclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gdG8gYXZvaWQgaW5maW5pdGUgbG9vcHMuXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGxleEVycm9yO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmaWx0ZXJUb2tlbkxvY2F0aW9uKCk7XG4gICAgICAgICAgICB0b2tlbnMgPSBleHRyYS50b2tlbnM7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGV4dHJhLmNvbW1lbnRzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgIHRva2Vucy5jb21tZW50cyA9IGV4dHJhLmNvbW1lbnRzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGVvZiBleHRyYS5lcnJvcnMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgdG9rZW5zLmVycm9ycyA9IGV4dHJhLmVycm9ycztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIGV4dHJhID0ge307XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRva2VucztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZShjb2RlLCBvcHRpb25zKSB7XG4gICAgICAgIHZhciBwcm9ncmFtLCB0b1N0cmluZztcblxuICAgICAgICB0b1N0cmluZyA9IFN0cmluZztcbiAgICAgICAgaWYgKHR5cGVvZiBjb2RlICE9PSAnc3RyaW5nJyAmJiAhKGNvZGUgaW5zdGFuY2VvZiBTdHJpbmcpKSB7XG4gICAgICAgICAgICBjb2RlID0gdG9TdHJpbmcoY29kZSk7XG4gICAgICAgIH1cblxuICAgICAgICBzb3VyY2UgPSBjb2RlO1xuICAgICAgICBpbmRleCA9IDA7XG4gICAgICAgIGxpbmVOdW1iZXIgPSAoc291cmNlLmxlbmd0aCA+IDApID8gMSA6IDA7XG4gICAgICAgIGxpbmVTdGFydCA9IDA7XG4gICAgICAgIHN0YXJ0SW5kZXggPSBpbmRleDtcbiAgICAgICAgc3RhcnRMaW5lTnVtYmVyID0gbGluZU51bWJlcjtcbiAgICAgICAgc3RhcnRMaW5lU3RhcnQgPSBsaW5lU3RhcnQ7XG4gICAgICAgIGxlbmd0aCA9IHNvdXJjZS5sZW5ndGg7XG4gICAgICAgIGxvb2thaGVhZCA9IG51bGw7XG4gICAgICAgIHN0YXRlID0ge1xuICAgICAgICAgICAgYWxsb3dJbjogdHJ1ZSxcbiAgICAgICAgICAgIGxhYmVsU2V0OiB7fSxcbiAgICAgICAgICAgIGluRnVuY3Rpb25Cb2R5OiBmYWxzZSxcbiAgICAgICAgICAgIGluSXRlcmF0aW9uOiBmYWxzZSxcbiAgICAgICAgICAgIGluU3dpdGNoOiBmYWxzZSxcbiAgICAgICAgICAgIGxhc3RDb21tZW50U3RhcnQ6IC0xLFxuICAgICAgICAgICAgY3VybHlTdGFjazogW11cbiAgICAgICAgfTtcbiAgICAgICAgc291cmNlVHlwZSA9ICdzY3JpcHQnO1xuICAgICAgICBzdHJpY3QgPSBmYWxzZTtcblxuICAgICAgICBleHRyYSA9IHt9O1xuICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBleHRyYS5yYW5nZSA9ICh0eXBlb2Ygb3B0aW9ucy5yYW5nZSA9PT0gJ2Jvb2xlYW4nKSAmJiBvcHRpb25zLnJhbmdlO1xuICAgICAgICAgICAgZXh0cmEubG9jID0gKHR5cGVvZiBvcHRpb25zLmxvYyA9PT0gJ2Jvb2xlYW4nKSAmJiBvcHRpb25zLmxvYztcbiAgICAgICAgICAgIGV4dHJhLmF0dGFjaENvbW1lbnQgPSAodHlwZW9mIG9wdGlvbnMuYXR0YWNoQ29tbWVudCA9PT0gJ2Jvb2xlYW4nKSAmJiBvcHRpb25zLmF0dGFjaENvbW1lbnQ7XG5cbiAgICAgICAgICAgIGlmIChleHRyYS5sb2MgJiYgb3B0aW9ucy5zb3VyY2UgIT09IG51bGwgJiYgb3B0aW9ucy5zb3VyY2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGV4dHJhLnNvdXJjZSA9IHRvU3RyaW5nKG9wdGlvbnMuc291cmNlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLnRva2VucyA9PT0gJ2Jvb2xlYW4nICYmIG9wdGlvbnMudG9rZW5zKSB7XG4gICAgICAgICAgICAgICAgZXh0cmEudG9rZW5zID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMuY29tbWVudCA9PT0gJ2Jvb2xlYW4nICYmIG9wdGlvbnMuY29tbWVudCkge1xuICAgICAgICAgICAgICAgIGV4dHJhLmNvbW1lbnRzID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMudG9sZXJhbnQgPT09ICdib29sZWFuJyAmJiBvcHRpb25zLnRvbGVyYW50KSB7XG4gICAgICAgICAgICAgICAgZXh0cmEuZXJyb3JzID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZXh0cmEuYXR0YWNoQ29tbWVudCkge1xuICAgICAgICAgICAgICAgIGV4dHJhLnJhbmdlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBleHRyYS5jb21tZW50cyA9IFtdO1xuICAgICAgICAgICAgICAgIGV4dHJhLmJvdHRvbVJpZ2h0U3RhY2sgPSBbXTtcbiAgICAgICAgICAgICAgICBleHRyYS50cmFpbGluZ0NvbW1lbnRzID0gW107XG4gICAgICAgICAgICAgICAgZXh0cmEubGVhZGluZ0NvbW1lbnRzID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5zb3VyY2VUeXBlID09PSAnbW9kdWxlJykge1xuICAgICAgICAgICAgICAgIC8vIHZlcnkgcmVzdHJpY3RpdmUgY29uZGl0aW9uIGZvciBub3dcbiAgICAgICAgICAgICAgICBzb3VyY2VUeXBlID0gb3B0aW9ucy5zb3VyY2VUeXBlO1xuICAgICAgICAgICAgICAgIHN0cmljdCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcHJvZ3JhbSA9IHBhcnNlUHJvZ3JhbSgpO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBleHRyYS5jb21tZW50cyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICBwcm9ncmFtLmNvbW1lbnRzID0gZXh0cmEuY29tbWVudHM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodHlwZW9mIGV4dHJhLnRva2VucyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICBmaWx0ZXJUb2tlbkxvY2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgcHJvZ3JhbS50b2tlbnMgPSBleHRyYS50b2tlbnM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodHlwZW9mIGV4dHJhLmVycm9ycyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICBwcm9ncmFtLmVycm9ycyA9IGV4dHJhLmVycm9ycztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIGV4dHJhID0ge307XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcHJvZ3JhbTtcbiAgICB9XG5cbiAgICAvLyBTeW5jIHdpdGggKi5qc29uIG1hbmlmZXN0cy5cbiAgICBleHBvcnRzLnZlcnNpb24gPSAnMi4yLjAnO1xuXG4gICAgZXhwb3J0cy50b2tlbml6ZSA9IHRva2VuaXplO1xuXG4gICAgZXhwb3J0cy5wYXJzZSA9IHBhcnNlO1xuXG4gICAgLy8gRGVlcCBjb3B5LlxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgZXhwb3J0cy5TeW50YXggPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbmFtZSwgdHlwZXMgPSB7fTtcblxuICAgICAgICBpZiAodHlwZW9mIE9iamVjdC5jcmVhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHR5cGVzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAobmFtZSBpbiBTeW50YXgpIHtcbiAgICAgICAgICAgIGlmIChTeW50YXguaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICAgICAgICAgICAgICB0eXBlc1tuYW1lXSA9IFN5bnRheFtuYW1lXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgT2JqZWN0LmZyZWV6ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgT2JqZWN0LmZyZWV6ZSh0eXBlcyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHlwZXM7XG4gICAgfSgpKTtcblxufSkpO1xuLyogdmltOiBzZXQgc3c9NCB0cz00IGV0IHR3PTgwIDogKi9cbiIsInZhciBiYXNlSW5kZXhPZiA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2Jhc2VJbmRleE9mJyksXG4gICAgYmluYXJ5SW5kZXggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iaW5hcnlJbmRleCcpO1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4O1xuXG4vKipcbiAqIEdldHMgdGhlIGluZGV4IGF0IHdoaWNoIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIGB2YWx1ZWAgaXMgZm91bmQgaW4gYGFycmF5YFxuICogdXNpbmcgW2BTYW1lVmFsdWVaZXJvYF0oaHR0cHM6Ly9wZW9wbGUubW96aWxsYS5vcmcvfmpvcmVuZG9yZmYvZXM2LWRyYWZ0Lmh0bWwjc2VjLXNhbWV2YWx1ZXplcm8pXG4gKiBmb3IgZXF1YWxpdHkgY29tcGFyaXNvbnMuIElmIGBmcm9tSW5kZXhgIGlzIG5lZ2F0aXZlLCBpdCBpcyB1c2VkIGFzIHRoZSBvZmZzZXRcbiAqIGZyb20gdGhlIGVuZCBvZiBgYXJyYXlgLiBJZiBgYXJyYXlgIGlzIHNvcnRlZCBwcm92aWRpbmcgYHRydWVgIGZvciBgZnJvbUluZGV4YFxuICogcGVyZm9ybXMgYSBmYXN0ZXIgYmluYXJ5IHNlYXJjaC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IEFycmF5XG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gc2VhcmNoLlxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAqIEBwYXJhbSB7Ym9vbGVhbnxudW1iZXJ9IFtmcm9tSW5kZXg9MF0gVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tIG9yIGB0cnVlYFxuICogIHRvIHBlcmZvcm0gYSBiaW5hcnkgc2VhcmNoIG9uIGEgc29ydGVkIGFycmF5LlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIG1hdGNoZWQgdmFsdWUsIGVsc2UgYC0xYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pbmRleE9mKFsxLCAyLCAxLCAyXSwgMik7XG4gKiAvLyA9PiAxXG4gKlxuICogLy8gdXNpbmcgYGZyb21JbmRleGBcbiAqIF8uaW5kZXhPZihbMSwgMiwgMSwgMl0sIDIsIDIpO1xuICogLy8gPT4gM1xuICpcbiAqIC8vIHBlcmZvcm1pbmcgYSBiaW5hcnkgc2VhcmNoXG4gKiBfLmluZGV4T2YoWzEsIDEsIDIsIDJdLCAyLCB0cnVlKTtcbiAqIC8vID0+IDJcbiAqL1xuZnVuY3Rpb24gaW5kZXhPZihhcnJheSwgdmFsdWUsIGZyb21JbmRleCkge1xuICB2YXIgbGVuZ3RoID0gYXJyYXkgPyBhcnJheS5sZW5ndGggOiAwO1xuICBpZiAoIWxlbmd0aCkge1xuICAgIHJldHVybiAtMTtcbiAgfVxuICBpZiAodHlwZW9mIGZyb21JbmRleCA9PSAnbnVtYmVyJykge1xuICAgIGZyb21JbmRleCA9IGZyb21JbmRleCA8IDAgPyBuYXRpdmVNYXgobGVuZ3RoICsgZnJvbUluZGV4LCAwKSA6IGZyb21JbmRleDtcbiAgfSBlbHNlIGlmIChmcm9tSW5kZXgpIHtcbiAgICB2YXIgaW5kZXggPSBiaW5hcnlJbmRleChhcnJheSwgdmFsdWUpLFxuICAgICAgICBvdGhlciA9IGFycmF5W2luZGV4XTtcblxuICAgIGlmICh2YWx1ZSA9PT0gdmFsdWUgPyAodmFsdWUgPT09IG90aGVyKSA6IChvdGhlciAhPT0gb3RoZXIpKSB7XG4gICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuICAgIHJldHVybiAtMTtcbiAgfVxuICByZXR1cm4gYmFzZUluZGV4T2YoYXJyYXksIHZhbHVlLCBmcm9tSW5kZXggfHwgMCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaW5kZXhPZjtcbiIsIi8qKlxuICogR2V0cyB0aGUgbGFzdCBlbGVtZW50IG9mIGBhcnJheWAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBBcnJheVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGxhc3QgZWxlbWVudCBvZiBgYXJyYXlgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmxhc3QoWzEsIDIsIDNdKTtcbiAqIC8vID0+IDNcbiAqL1xuZnVuY3Rpb24gbGFzdChhcnJheSkge1xuICB2YXIgbGVuZ3RoID0gYXJyYXkgPyBhcnJheS5sZW5ndGggOiAwO1xuICByZXR1cm4gbGVuZ3RoID8gYXJyYXlbbGVuZ3RoIC0gMV0gOiB1bmRlZmluZWQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbGFzdDtcbiIsInZhciBMYXp5V3JhcHBlciA9IHJlcXVpcmUoJy4uL2ludGVybmFsL0xhenlXcmFwcGVyJyksXG4gICAgTG9kYXNoV3JhcHBlciA9IHJlcXVpcmUoJy4uL2ludGVybmFsL0xvZGFzaFdyYXBwZXInKSxcbiAgICBiYXNlTG9kYXNoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZUxvZGFzaCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc09iamVjdExpa2UnKSxcbiAgICB3cmFwcGVyQ2xvbmUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC93cmFwcGVyQ2xvbmUnKTtcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGBsb2Rhc2hgIG9iamVjdCB3aGljaCB3cmFwcyBgdmFsdWVgIHRvIGVuYWJsZSBpbXBsaWNpdCBjaGFpbmluZy5cbiAqIE1ldGhvZHMgdGhhdCBvcGVyYXRlIG9uIGFuZCByZXR1cm4gYXJyYXlzLCBjb2xsZWN0aW9ucywgYW5kIGZ1bmN0aW9ucyBjYW5cbiAqIGJlIGNoYWluZWQgdG9nZXRoZXIuIE1ldGhvZHMgdGhhdCByZXR1cm4gYSBib29sZWFuIG9yIHNpbmdsZSB2YWx1ZSB3aWxsXG4gKiBhdXRvbWF0aWNhbGx5IGVuZCB0aGUgY2hhaW4gcmV0dXJuaW5nIHRoZSB1bndyYXBwZWQgdmFsdWUuIEV4cGxpY2l0IGNoYWluaW5nXG4gKiBtYXkgYmUgZW5hYmxlZCB1c2luZyBgXy5jaGFpbmAuIFRoZSBleGVjdXRpb24gb2YgY2hhaW5lZCBtZXRob2RzIGlzIGxhenksXG4gKiB0aGF0IGlzLCBleGVjdXRpb24gaXMgZGVmZXJyZWQgdW50aWwgYF8jdmFsdWVgIGlzIGltcGxpY2l0bHkgb3IgZXhwbGljaXRseVxuICogY2FsbGVkLlxuICpcbiAqIExhenkgZXZhbHVhdGlvbiBhbGxvd3Mgc2V2ZXJhbCBtZXRob2RzIHRvIHN1cHBvcnQgc2hvcnRjdXQgZnVzaW9uLiBTaG9ydGN1dFxuICogZnVzaW9uIGlzIGFuIG9wdGltaXphdGlvbiB0aGF0IG1lcmdlcyBpdGVyYXRlZXMgdG8gYXZvaWQgY3JlYXRpbmcgaW50ZXJtZWRpYXRlXG4gKiBhcnJheXMgYW5kIHJlZHVjZSB0aGUgbnVtYmVyIG9mIGl0ZXJhdGVlIGV4ZWN1dGlvbnMuXG4gKlxuICogQ2hhaW5pbmcgaXMgc3VwcG9ydGVkIGluIGN1c3RvbSBidWlsZHMgYXMgbG9uZyBhcyB0aGUgYF8jdmFsdWVgIG1ldGhvZCBpc1xuICogZGlyZWN0bHkgb3IgaW5kaXJlY3RseSBpbmNsdWRlZCBpbiB0aGUgYnVpbGQuXG4gKlxuICogSW4gYWRkaXRpb24gdG8gbG9kYXNoIG1ldGhvZHMsIHdyYXBwZXJzIGhhdmUgYEFycmF5YCBhbmQgYFN0cmluZ2AgbWV0aG9kcy5cbiAqXG4gKiBUaGUgd3JhcHBlciBgQXJyYXlgIG1ldGhvZHMgYXJlOlxuICogYGNvbmNhdGAsIGBqb2luYCwgYHBvcGAsIGBwdXNoYCwgYHJldmVyc2VgLCBgc2hpZnRgLCBgc2xpY2VgLCBgc29ydGAsXG4gKiBgc3BsaWNlYCwgYW5kIGB1bnNoaWZ0YFxuICpcbiAqIFRoZSB3cmFwcGVyIGBTdHJpbmdgIG1ldGhvZHMgYXJlOlxuICogYHJlcGxhY2VgIGFuZCBgc3BsaXRgXG4gKlxuICogVGhlIHdyYXBwZXIgbWV0aG9kcyB0aGF0IHN1cHBvcnQgc2hvcnRjdXQgZnVzaW9uIGFyZTpcbiAqIGBjb21wYWN0YCwgYGRyb3BgLCBgZHJvcFJpZ2h0YCwgYGRyb3BSaWdodFdoaWxlYCwgYGRyb3BXaGlsZWAsIGBmaWx0ZXJgLFxuICogYGZpcnN0YCwgYGluaXRpYWxgLCBgbGFzdGAsIGBtYXBgLCBgcGx1Y2tgLCBgcmVqZWN0YCwgYHJlc3RgLCBgcmV2ZXJzZWAsXG4gKiBgc2xpY2VgLCBgdGFrZWAsIGB0YWtlUmlnaHRgLCBgdGFrZVJpZ2h0V2hpbGVgLCBgdGFrZVdoaWxlYCwgYHRvQXJyYXlgLFxuICogYW5kIGB3aGVyZWBcbiAqXG4gKiBUaGUgY2hhaW5hYmxlIHdyYXBwZXIgbWV0aG9kcyBhcmU6XG4gKiBgYWZ0ZXJgLCBgYXJ5YCwgYGFzc2lnbmAsIGBhdGAsIGBiZWZvcmVgLCBgYmluZGAsIGBiaW5kQWxsYCwgYGJpbmRLZXlgLFxuICogYGNhbGxiYWNrYCwgYGNoYWluYCwgYGNodW5rYCwgYGNvbW1pdGAsIGBjb21wYWN0YCwgYGNvbmNhdGAsIGBjb25zdGFudGAsXG4gKiBgY291bnRCeWAsIGBjcmVhdGVgLCBgY3VycnlgLCBgZGVib3VuY2VgLCBgZGVmYXVsdHNgLCBgZGVmZXJgLCBgZGVsYXlgLFxuICogYGRpZmZlcmVuY2VgLCBgZHJvcGAsIGBkcm9wUmlnaHRgLCBgZHJvcFJpZ2h0V2hpbGVgLCBgZHJvcFdoaWxlYCwgYGZpbGxgLFxuICogYGZpbHRlcmAsIGBmbGF0dGVuYCwgYGZsYXR0ZW5EZWVwYCwgYGZsb3dgLCBgZmxvd1JpZ2h0YCwgYGZvckVhY2hgLFxuICogYGZvckVhY2hSaWdodGAsIGBmb3JJbmAsIGBmb3JJblJpZ2h0YCwgYGZvck93bmAsIGBmb3JPd25SaWdodGAsIGBmdW5jdGlvbnNgLFxuICogYGdyb3VwQnlgLCBgaW5kZXhCeWAsIGBpbml0aWFsYCwgYGludGVyc2VjdGlvbmAsIGBpbnZlcnRgLCBgaW52b2tlYCwgYGtleXNgLFxuICogYGtleXNJbmAsIGBtYXBgLCBgbWFwS2V5c2AsIGBtYXBWYWx1ZXNgLCBgbWF0Y2hlc2AsIGBtYXRjaGVzUHJvcGVydHlgLFxuICogYG1lbW9pemVgLCBgbWVyZ2VgLCBgbWV0aG9kYCwgYG1ldGhvZE9mYCwgYG1peGluYCwgYG5lZ2F0ZWAsIGBvbWl0YCwgYG9uY2VgLFxuICogYHBhaXJzYCwgYHBhcnRpYWxgLCBgcGFydGlhbFJpZ2h0YCwgYHBhcnRpdGlvbmAsIGBwaWNrYCwgYHBsYW50YCwgYHBsdWNrYCxcbiAqIGBwcm9wZXJ0eWAsIGBwcm9wZXJ0eU9mYCwgYHB1bGxgLCBgcHVsbEF0YCwgYHB1c2hgLCBgcmFuZ2VgLCBgcmVhcmdgLFxuICogYHJlamVjdGAsIGByZW1vdmVgLCBgcmVzdGAsIGByZXN0UGFyYW1gLCBgcmV2ZXJzZWAsIGBzZXRgLCBgc2h1ZmZsZWAsXG4gKiBgc2xpY2VgLCBgc29ydGAsIGBzb3J0QnlgLCBgc29ydEJ5QWxsYCwgYHNvcnRCeU9yZGVyYCwgYHNwbGljZWAsIGBzcHJlYWRgLFxuICogYHRha2VgLCBgdGFrZVJpZ2h0YCwgYHRha2VSaWdodFdoaWxlYCwgYHRha2VXaGlsZWAsIGB0YXBgLCBgdGhyb3R0bGVgLFxuICogYHRocnVgLCBgdGltZXNgLCBgdG9BcnJheWAsIGB0b1BsYWluT2JqZWN0YCwgYHRyYW5zZm9ybWAsIGB1bmlvbmAsIGB1bmlxYCxcbiAqIGB1bnNoaWZ0YCwgYHVuemlwYCwgYHVuemlwV2l0aGAsIGB2YWx1ZXNgLCBgdmFsdWVzSW5gLCBgd2hlcmVgLCBgd2l0aG91dGAsXG4gKiBgd3JhcGAsIGB4b3JgLCBgemlwYCwgYHppcE9iamVjdGAsIGB6aXBXaXRoYFxuICpcbiAqIFRoZSB3cmFwcGVyIG1ldGhvZHMgdGhhdCBhcmUgKipub3QqKiBjaGFpbmFibGUgYnkgZGVmYXVsdCBhcmU6XG4gKiBgYWRkYCwgYGF0dGVtcHRgLCBgY2FtZWxDYXNlYCwgYGNhcGl0YWxpemVgLCBgY2xvbmVgLCBgY2xvbmVEZWVwYCwgYGRlYnVycmAsXG4gKiBgZW5kc1dpdGhgLCBgZXNjYXBlYCwgYGVzY2FwZVJlZ0V4cGAsIGBldmVyeWAsIGBmaW5kYCwgYGZpbmRJbmRleGAsIGBmaW5kS2V5YCxcbiAqIGBmaW5kTGFzdGAsIGBmaW5kTGFzdEluZGV4YCwgYGZpbmRMYXN0S2V5YCwgYGZpbmRXaGVyZWAsIGBmaXJzdGAsIGBnZXRgLFxuICogYGd0YCwgYGd0ZWAsIGBoYXNgLCBgaWRlbnRpdHlgLCBgaW5jbHVkZXNgLCBgaW5kZXhPZmAsIGBpblJhbmdlYCwgYGlzQXJndW1lbnRzYCxcbiAqIGBpc0FycmF5YCwgYGlzQm9vbGVhbmAsIGBpc0RhdGVgLCBgaXNFbGVtZW50YCwgYGlzRW1wdHlgLCBgaXNFcXVhbGAsIGBpc0Vycm9yYCxcbiAqIGBpc0Zpbml0ZWAgYGlzRnVuY3Rpb25gLCBgaXNNYXRjaGAsIGBpc05hdGl2ZWAsIGBpc05hTmAsIGBpc051bGxgLCBgaXNOdW1iZXJgLFxuICogYGlzT2JqZWN0YCwgYGlzUGxhaW5PYmplY3RgLCBgaXNSZWdFeHBgLCBgaXNTdHJpbmdgLCBgaXNVbmRlZmluZWRgLFxuICogYGlzVHlwZWRBcnJheWAsIGBqb2luYCwgYGtlYmFiQ2FzZWAsIGBsYXN0YCwgYGxhc3RJbmRleE9mYCwgYGx0YCwgYGx0ZWAsXG4gKiBgbWF4YCwgYG1pbmAsIGBub0NvbmZsaWN0YCwgYG5vb3BgLCBgbm93YCwgYHBhZGAsIGBwYWRMZWZ0YCwgYHBhZFJpZ2h0YCxcbiAqIGBwYXJzZUludGAsIGBwb3BgLCBgcmFuZG9tYCwgYHJlZHVjZWAsIGByZWR1Y2VSaWdodGAsIGByZXBlYXRgLCBgcmVzdWx0YCxcbiAqIGBydW5JbkNvbnRleHRgLCBgc2hpZnRgLCBgc2l6ZWAsIGBzbmFrZUNhc2VgLCBgc29tZWAsIGBzb3J0ZWRJbmRleGAsXG4gKiBgc29ydGVkTGFzdEluZGV4YCwgYHN0YXJ0Q2FzZWAsIGBzdGFydHNXaXRoYCwgYHN1bWAsIGB0ZW1wbGF0ZWAsIGB0cmltYCxcbiAqIGB0cmltTGVmdGAsIGB0cmltUmlnaHRgLCBgdHJ1bmNgLCBgdW5lc2NhcGVgLCBgdW5pcXVlSWRgLCBgdmFsdWVgLCBhbmQgYHdvcmRzYFxuICpcbiAqIFRoZSB3cmFwcGVyIG1ldGhvZCBgc2FtcGxlYCB3aWxsIHJldHVybiBhIHdyYXBwZWQgdmFsdWUgd2hlbiBgbmAgaXMgcHJvdmlkZWQsXG4gKiBvdGhlcndpc2UgYW4gdW53cmFwcGVkIHZhbHVlIGlzIHJldHVybmVkLlxuICpcbiAqIEBuYW1lIF9cbiAqIEBjb25zdHJ1Y3RvclxuICogQGNhdGVnb3J5IENoYWluXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB3cmFwIGluIGEgYGxvZGFzaGAgaW5zdGFuY2UuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgYGxvZGFzaGAgd3JhcHBlciBpbnN0YW5jZS5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIHdyYXBwZWQgPSBfKFsxLCAyLCAzXSk7XG4gKlxuICogLy8gcmV0dXJucyBhbiB1bndyYXBwZWQgdmFsdWVcbiAqIHdyYXBwZWQucmVkdWNlKGZ1bmN0aW9uKHRvdGFsLCBuKSB7XG4gKiAgIHJldHVybiB0b3RhbCArIG47XG4gKiB9KTtcbiAqIC8vID0+IDZcbiAqXG4gKiAvLyByZXR1cm5zIGEgd3JhcHBlZCB2YWx1ZVxuICogdmFyIHNxdWFyZXMgPSB3cmFwcGVkLm1hcChmdW5jdGlvbihuKSB7XG4gKiAgIHJldHVybiBuICogbjtcbiAqIH0pO1xuICpcbiAqIF8uaXNBcnJheShzcXVhcmVzKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc0FycmF5KHNxdWFyZXMudmFsdWUoKSk7XG4gKiAvLyA9PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGxvZGFzaCh2YWx1ZSkge1xuICBpZiAoaXNPYmplY3RMaWtlKHZhbHVlKSAmJiAhaXNBcnJheSh2YWx1ZSkgJiYgISh2YWx1ZSBpbnN0YW5jZW9mIExhenlXcmFwcGVyKSkge1xuICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIExvZGFzaFdyYXBwZXIpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsICdfX2NoYWluX18nKSAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCAnX193cmFwcGVkX18nKSkge1xuICAgICAgcmV0dXJuIHdyYXBwZXJDbG9uZSh2YWx1ZSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBuZXcgTG9kYXNoV3JhcHBlcih2YWx1ZSk7XG59XG5cbi8vIEVuc3VyZSB3cmFwcGVycyBhcmUgaW5zdGFuY2VzIG9mIGBiYXNlTG9kYXNoYC5cbmxvZGFzaC5wcm90b3R5cGUgPSBiYXNlTG9kYXNoLnByb3RvdHlwZTtcblxubW9kdWxlLmV4cG9ydHMgPSBsb2Rhc2g7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vZm9yRWFjaCcpO1xuIiwidmFyIGJhc2VFYWNoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZUVhY2gnKSxcbiAgICBjcmVhdGVGaW5kID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvY3JlYXRlRmluZCcpO1xuXG4vKipcbiAqIEl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2YgYGNvbGxlY3Rpb25gLCByZXR1cm5pbmcgdGhlIGZpcnN0IGVsZW1lbnRcbiAqIGBwcmVkaWNhdGVgIHJldHVybnMgdHJ1dGh5IGZvci4gVGhlIHByZWRpY2F0ZSBpcyBib3VuZCB0byBgdGhpc0FyZ2AgYW5kXG4gKiBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuXG4gKlxuICogSWYgYSBwcm9wZXJ0eSBuYW1lIGlzIHByb3ZpZGVkIGZvciBgcHJlZGljYXRlYCB0aGUgY3JlYXRlZCBgXy5wcm9wZXJ0eWBcbiAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlIG9mIHRoZSBnaXZlbiBlbGVtZW50LlxuICpcbiAqIElmIGEgdmFsdWUgaXMgYWxzbyBwcm92aWRlZCBmb3IgYHRoaXNBcmdgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNQcm9wZXJ0eWBcbiAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgYSBtYXRjaGluZyBwcm9wZXJ0eVxuICogdmFsdWUsIGVsc2UgYGZhbHNlYC5cbiAqXG4gKiBJZiBhbiBvYmplY3QgaXMgcHJvdmlkZWQgZm9yIGBwcmVkaWNhdGVgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNgIHN0eWxlXG4gKiBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBoYXZlIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBnaXZlblxuICogb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBhbGlhcyBkZXRlY3RcbiAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gc2VhcmNoLlxuICogQHBhcmFtIHtGdW5jdGlvbnxPYmplY3R8c3RyaW5nfSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkXG4gKiAgcGVyIGl0ZXJhdGlvbi5cbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgcHJlZGljYXRlYC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBtYXRjaGVkIGVsZW1lbnQsIGVsc2UgYHVuZGVmaW5lZGAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciB1c2VycyA9IFtcbiAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FnZSc6IDM2LCAnYWN0aXZlJzogdHJ1ZSB9LFxuICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICAnYWdlJzogNDAsICdhY3RpdmUnOiBmYWxzZSB9LFxuICogICB7ICd1c2VyJzogJ3BlYmJsZXMnLCAnYWdlJzogMSwgICdhY3RpdmUnOiB0cnVlIH1cbiAqIF07XG4gKlxuICogXy5yZXN1bHQoXy5maW5kKHVzZXJzLCBmdW5jdGlvbihjaHIpIHtcbiAqICAgcmV0dXJuIGNoci5hZ2UgPCA0MDtcbiAqIH0pLCAndXNlcicpO1xuICogLy8gPT4gJ2Jhcm5leSdcbiAqXG4gKiAvLyB1c2luZyB0aGUgYF8ubWF0Y2hlc2AgY2FsbGJhY2sgc2hvcnRoYW5kXG4gKiBfLnJlc3VsdChfLmZpbmQodXNlcnMsIHsgJ2FnZSc6IDEsICdhY3RpdmUnOiB0cnVlIH0pLCAndXNlcicpO1xuICogLy8gPT4gJ3BlYmJsZXMnXG4gKlxuICogLy8gdXNpbmcgdGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgY2FsbGJhY2sgc2hvcnRoYW5kXG4gKiBfLnJlc3VsdChfLmZpbmQodXNlcnMsICdhY3RpdmUnLCBmYWxzZSksICd1c2VyJyk7XG4gKiAvLyA9PiAnZnJlZCdcbiAqXG4gKiAvLyB1c2luZyB0aGUgYF8ucHJvcGVydHlgIGNhbGxiYWNrIHNob3J0aGFuZFxuICogXy5yZXN1bHQoXy5maW5kKHVzZXJzLCAnYWN0aXZlJyksICd1c2VyJyk7XG4gKiAvLyA9PiAnYmFybmV5J1xuICovXG52YXIgZmluZCA9IGNyZWF0ZUZpbmQoYmFzZUVhY2gpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZpbmQ7XG4iLCJ2YXIgYXJyYXlFYWNoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYXJyYXlFYWNoJyksXG4gICAgYmFzZUVhY2ggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlRWFjaCcpLFxuICAgIGNyZWF0ZUZvckVhY2ggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9jcmVhdGVGb3JFYWNoJyk7XG5cbi8qKlxuICogSXRlcmF0ZXMgb3ZlciBlbGVtZW50cyBvZiBgY29sbGVjdGlvbmAgaW52b2tpbmcgYGl0ZXJhdGVlYCBmb3IgZWFjaCBlbGVtZW50LlxuICogVGhlIGBpdGVyYXRlZWAgaXMgYm91bmQgdG8gYHRoaXNBcmdgIGFuZCBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOlxuICogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLiBJdGVyYXRlZSBmdW5jdGlvbnMgbWF5IGV4aXQgaXRlcmF0aW9uIGVhcmx5XG4gKiBieSBleHBsaWNpdGx5IHJldHVybmluZyBgZmFsc2VgLlxuICpcbiAqICoqTm90ZToqKiBBcyB3aXRoIG90aGVyIFwiQ29sbGVjdGlvbnNcIiBtZXRob2RzLCBvYmplY3RzIHdpdGggYSBcImxlbmd0aFwiIHByb3BlcnR5XG4gKiBhcmUgaXRlcmF0ZWQgbGlrZSBhcnJheXMuIFRvIGF2b2lkIHRoaXMgYmVoYXZpb3IgYF8uZm9ySW5gIG9yIGBfLmZvck93bmBcbiAqIG1heSBiZSB1c2VkIGZvciBvYmplY3QgaXRlcmF0aW9uLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAYWxpYXMgZWFjaFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgaXRlcmF0ZWVgLlxuICogQHJldHVybnMge0FycmF5fE9iamVjdHxzdHJpbmd9IFJldHVybnMgYGNvbGxlY3Rpb25gLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfKFsxLCAyXSkuZm9yRWFjaChmdW5jdGlvbihuKSB7XG4gKiAgIGNvbnNvbGUubG9nKG4pO1xuICogfSkudmFsdWUoKTtcbiAqIC8vID0+IGxvZ3MgZWFjaCB2YWx1ZSBmcm9tIGxlZnQgdG8gcmlnaHQgYW5kIHJldHVybnMgdGhlIGFycmF5XG4gKlxuICogXy5mb3JFYWNoKHsgJ2EnOiAxLCAnYic6IDIgfSwgZnVuY3Rpb24obiwga2V5KSB7XG4gKiAgIGNvbnNvbGUubG9nKG4sIGtleSk7XG4gKiB9KTtcbiAqIC8vID0+IGxvZ3MgZWFjaCB2YWx1ZS1rZXkgcGFpciBhbmQgcmV0dXJucyB0aGUgb2JqZWN0IChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gKi9cbnZhciBmb3JFYWNoID0gY3JlYXRlRm9yRWFjaChhcnJheUVhY2gsIGJhc2VFYWNoKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmb3JFYWNoO1xuIiwidmFyIGJhc2VJbmRleE9mID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZUluZGV4T2YnKSxcbiAgICBnZXRMZW5ndGggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9nZXRMZW5ndGgnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FycmF5JyksXG4gICAgaXNJdGVyYXRlZUNhbGwgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0l0ZXJhdGVlQ2FsbCcpLFxuICAgIGlzTGVuZ3RoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNMZW5ndGgnKSxcbiAgICBpc1N0cmluZyA9IHJlcXVpcmUoJy4uL2xhbmcvaXNTdHJpbmcnKSxcbiAgICB2YWx1ZXMgPSByZXF1aXJlKCcuLi9vYmplY3QvdmFsdWVzJyk7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlTWF4ID0gTWF0aC5tYXg7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgaW4gYGNvbGxlY3Rpb25gIHVzaW5nXG4gKiBbYFNhbWVWYWx1ZVplcm9gXShodHRwczovL3Blb3BsZS5tb3ppbGxhLm9yZy9+am9yZW5kb3JmZi9lczYtZHJhZnQuaHRtbCNzZWMtc2FtZXZhbHVlemVybylcbiAqIGZvciBlcXVhbGl0eSBjb21wYXJpc29ucy4gSWYgYGZyb21JbmRleGAgaXMgbmVnYXRpdmUsIGl0IGlzIHVzZWQgYXMgdGhlIG9mZnNldFxuICogZnJvbSB0aGUgZW5kIG9mIGBjb2xsZWN0aW9uYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGFsaWFzIGNvbnRhaW5zLCBpbmNsdWRlXG4gKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHNlYXJjaC5cbiAqIEBwYXJhbSB7Kn0gdGFyZ2V0IFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICogQHBhcmFtIHtudW1iZXJ9IFtmcm9tSW5kZXg9MF0gVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGEgY2FsbGJhY2sgZm9yIGZ1bmN0aW9ucyBsaWtlIGBfLnJlZHVjZWAuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYSBtYXRjaGluZyBlbGVtZW50IGlzIGZvdW5kLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaW5jbHVkZXMoWzEsIDIsIDNdLCAxKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmluY2x1ZGVzKFsxLCAyLCAzXSwgMSwgMik7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uaW5jbHVkZXMoeyAndXNlcic6ICdmcmVkJywgJ2FnZSc6IDQwIH0sICdmcmVkJyk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pbmNsdWRlcygncGViYmxlcycsICdlYicpO1xuICogLy8gPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBpbmNsdWRlcyhjb2xsZWN0aW9uLCB0YXJnZXQsIGZyb21JbmRleCwgZ3VhcmQpIHtcbiAgdmFyIGxlbmd0aCA9IGNvbGxlY3Rpb24gPyBnZXRMZW5ndGgoY29sbGVjdGlvbikgOiAwO1xuICBpZiAoIWlzTGVuZ3RoKGxlbmd0aCkpIHtcbiAgICBjb2xsZWN0aW9uID0gdmFsdWVzKGNvbGxlY3Rpb24pO1xuICAgIGxlbmd0aCA9IGNvbGxlY3Rpb24ubGVuZ3RoO1xuICB9XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmICh0eXBlb2YgZnJvbUluZGV4ICE9ICdudW1iZXInIHx8IChndWFyZCAmJiBpc0l0ZXJhdGVlQ2FsbCh0YXJnZXQsIGZyb21JbmRleCwgZ3VhcmQpKSkge1xuICAgIGZyb21JbmRleCA9IDA7XG4gIH0gZWxzZSB7XG4gICAgZnJvbUluZGV4ID0gZnJvbUluZGV4IDwgMCA/IG5hdGl2ZU1heChsZW5ndGggKyBmcm9tSW5kZXgsIDApIDogKGZyb21JbmRleCB8fCAwKTtcbiAgfVxuICByZXR1cm4gKHR5cGVvZiBjb2xsZWN0aW9uID09ICdzdHJpbmcnIHx8ICFpc0FycmF5KGNvbGxlY3Rpb24pICYmIGlzU3RyaW5nKGNvbGxlY3Rpb24pKVxuICAgID8gKGZyb21JbmRleCA8IGxlbmd0aCAmJiBjb2xsZWN0aW9uLmluZGV4T2YodGFyZ2V0LCBmcm9tSW5kZXgpID4gLTEpXG4gICAgOiAoYmFzZUluZGV4T2YoY29sbGVjdGlvbiwgdGFyZ2V0LCBmcm9tSW5kZXgpID4gLTEpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGluY2x1ZGVzO1xuIiwidmFyIGFycmF5TWFwID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYXJyYXlNYXAnKSxcbiAgICBiYXNlQ2FsbGJhY2sgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlQ2FsbGJhY2snKSxcbiAgICBiYXNlTWFwID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZU1hcCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IG9mIHZhbHVlcyBieSBydW5uaW5nIGVhY2ggZWxlbWVudCBpbiBgY29sbGVjdGlvbmAgdGhyb3VnaFxuICogYGl0ZXJhdGVlYC4gVGhlIGBpdGVyYXRlZWAgaXMgYm91bmQgdG8gYHRoaXNBcmdgIGFuZCBpbnZva2VkIHdpdGggdGhyZWVcbiAqIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLlxuICpcbiAqIElmIGEgcHJvcGVydHkgbmFtZSBpcyBwcm92aWRlZCBmb3IgYGl0ZXJhdGVlYCB0aGUgY3JlYXRlZCBgXy5wcm9wZXJ0eWBcbiAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlIG9mIHRoZSBnaXZlbiBlbGVtZW50LlxuICpcbiAqIElmIGEgdmFsdWUgaXMgYWxzbyBwcm92aWRlZCBmb3IgYHRoaXNBcmdgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNQcm9wZXJ0eWBcbiAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgYSBtYXRjaGluZyBwcm9wZXJ0eVxuICogdmFsdWUsIGVsc2UgYGZhbHNlYC5cbiAqXG4gKiBJZiBhbiBvYmplY3QgaXMgcHJvdmlkZWQgZm9yIGBpdGVyYXRlZWAgdGhlIGNyZWF0ZWQgYF8ubWF0Y2hlc2Agc3R5bGVcbiAqIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgdGhlIHByb3BlcnRpZXMgb2YgdGhlIGdpdmVuXG4gKiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqXG4gKiBNYW55IGxvZGFzaCBtZXRob2RzIGFyZSBndWFyZGVkIHRvIHdvcmsgYXMgaXRlcmF0ZWVzIGZvciBtZXRob2RzIGxpa2VcbiAqIGBfLmV2ZXJ5YCwgYF8uZmlsdGVyYCwgYF8ubWFwYCwgYF8ubWFwVmFsdWVzYCwgYF8ucmVqZWN0YCwgYW5kIGBfLnNvbWVgLlxuICpcbiAqIFRoZSBndWFyZGVkIG1ldGhvZHMgYXJlOlxuICogYGFyeWAsIGBjYWxsYmFja2AsIGBjaHVua2AsIGBjbG9uZWAsIGBjcmVhdGVgLCBgY3VycnlgLCBgY3VycnlSaWdodGAsXG4gKiBgZHJvcGAsIGBkcm9wUmlnaHRgLCBgZXZlcnlgLCBgZmlsbGAsIGBmbGF0dGVuYCwgYGludmVydGAsIGBtYXhgLCBgbWluYCxcbiAqIGBwYXJzZUludGAsIGBzbGljZWAsIGBzb3J0QnlgLCBgdGFrZWAsIGB0YWtlUmlnaHRgLCBgdGVtcGxhdGVgLCBgdHJpbWAsXG4gKiBgdHJpbUxlZnRgLCBgdHJpbVJpZ2h0YCwgYHRydW5jYCwgYHJhbmRvbWAsIGByYW5nZWAsIGBzYW1wbGVgLCBgc29tZWAsXG4gKiBgc3VtYCwgYHVuaXFgLCBhbmQgYHdvcmRzYFxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAYWxpYXMgY29sbGVjdFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdHxzdHJpbmd9IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZFxuICogIHBlciBpdGVyYXRpb24uXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGl0ZXJhdGVlYC5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IG1hcHBlZCBhcnJheS5cbiAqIEBleGFtcGxlXG4gKlxuICogZnVuY3Rpb24gdGltZXNUaHJlZShuKSB7XG4gKiAgIHJldHVybiBuICogMztcbiAqIH1cbiAqXG4gKiBfLm1hcChbMSwgMl0sIHRpbWVzVGhyZWUpO1xuICogLy8gPT4gWzMsIDZdXG4gKlxuICogXy5tYXAoeyAnYSc6IDEsICdiJzogMiB9LCB0aW1lc1RocmVlKTtcbiAqIC8vID0+IFszLCA2XSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICpcbiAqIHZhciB1c2VycyA9IFtcbiAqICAgeyAndXNlcic6ICdiYXJuZXknIH0sXG4gKiAgIHsgJ3VzZXInOiAnZnJlZCcgfVxuICogXTtcbiAqXG4gKiAvLyB1c2luZyB0aGUgYF8ucHJvcGVydHlgIGNhbGxiYWNrIHNob3J0aGFuZFxuICogXy5tYXAodXNlcnMsICd1c2VyJyk7XG4gKiAvLyA9PiBbJ2Jhcm5leScsICdmcmVkJ11cbiAqL1xuZnVuY3Rpb24gbWFwKGNvbGxlY3Rpb24sIGl0ZXJhdGVlLCB0aGlzQXJnKSB7XG4gIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5TWFwIDogYmFzZU1hcDtcbiAgaXRlcmF0ZWUgPSBiYXNlQ2FsbGJhY2soaXRlcmF0ZWUsIHRoaXNBcmcsIDMpO1xuICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBpdGVyYXRlZSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWFwO1xuIiwidmFyIGdldE5hdGl2ZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2dldE5hdGl2ZScpO1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU5vdyA9IGdldE5hdGl2ZShEYXRlLCAnbm93Jyk7XG5cbi8qKlxuICogR2V0cyB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0aGF0IGhhdmUgZWxhcHNlZCBzaW5jZSB0aGUgVW5peCBlcG9jaFxuICogKDEgSmFudWFyeSAxOTcwIDAwOjAwOjAwIFVUQykuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBEYXRlXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uZGVmZXIoZnVuY3Rpb24oc3RhbXApIHtcbiAqICAgY29uc29sZS5sb2coXy5ub3coKSAtIHN0YW1wKTtcbiAqIH0sIF8ubm93KCkpO1xuICogLy8gPT4gbG9ncyB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBpdCB0b29rIGZvciB0aGUgZGVmZXJyZWQgZnVuY3Rpb24gdG8gYmUgaW52b2tlZFxuICovXG52YXIgbm93ID0gbmF0aXZlTm93IHx8IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5vdztcbiIsInZhciBjcmVhdGVXcmFwcGVyID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvY3JlYXRlV3JhcHBlcicpLFxuICAgIHJlcGxhY2VIb2xkZXJzID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvcmVwbGFjZUhvbGRlcnMnKSxcbiAgICByZXN0UGFyYW0gPSByZXF1aXJlKCcuL3Jlc3RQYXJhbScpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB3cmFwcGVyIG1ldGFkYXRhLiAqL1xudmFyIEJJTkRfRkxBRyA9IDEsXG4gICAgUEFSVElBTF9GTEFHID0gMzI7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgYHRoaXNBcmdgXG4gKiBhbmQgcHJlcGVuZHMgYW55IGFkZGl0aW9uYWwgYF8uYmluZGAgYXJndW1lbnRzIHRvIHRob3NlIHByb3ZpZGVkIHRvIHRoZVxuICogYm91bmQgZnVuY3Rpb24uXG4gKlxuICogVGhlIGBfLmJpbmQucGxhY2Vob2xkZXJgIHZhbHVlLCB3aGljaCBkZWZhdWx0cyB0byBgX2AgaW4gbW9ub2xpdGhpYyBidWlsZHMsXG4gKiBtYXkgYmUgdXNlZCBhcyBhIHBsYWNlaG9sZGVyIGZvciBwYXJ0aWFsbHkgYXBwbGllZCBhcmd1bWVudHMuXG4gKlxuICogKipOb3RlOioqIFVubGlrZSBuYXRpdmUgYEZ1bmN0aW9uI2JpbmRgIHRoaXMgbWV0aG9kIGRvZXMgbm90IHNldCB0aGUgXCJsZW5ndGhcIlxuICogcHJvcGVydHkgb2YgYm91bmQgZnVuY3Rpb25zLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGJpbmQuXG4gKiBAcGFyYW0geyp9IHRoaXNBcmcgVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7Li4uKn0gW3BhcnRpYWxzXSBUaGUgYXJndW1lbnRzIHRvIGJlIHBhcnRpYWxseSBhcHBsaWVkLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYm91bmQgZnVuY3Rpb24uXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBncmVldCA9IGZ1bmN0aW9uKGdyZWV0aW5nLCBwdW5jdHVhdGlvbikge1xuICogICByZXR1cm4gZ3JlZXRpbmcgKyAnICcgKyB0aGlzLnVzZXIgKyBwdW5jdHVhdGlvbjtcbiAqIH07XG4gKlxuICogdmFyIG9iamVjdCA9IHsgJ3VzZXInOiAnZnJlZCcgfTtcbiAqXG4gKiB2YXIgYm91bmQgPSBfLmJpbmQoZ3JlZXQsIG9iamVjdCwgJ2hpJyk7XG4gKiBib3VuZCgnIScpO1xuICogLy8gPT4gJ2hpIGZyZWQhJ1xuICpcbiAqIC8vIHVzaW5nIHBsYWNlaG9sZGVyc1xuICogdmFyIGJvdW5kID0gXy5iaW5kKGdyZWV0LCBvYmplY3QsIF8sICchJyk7XG4gKiBib3VuZCgnaGknKTtcbiAqIC8vID0+ICdoaSBmcmVkISdcbiAqL1xudmFyIGJpbmQgPSByZXN0UGFyYW0oZnVuY3Rpb24oZnVuYywgdGhpc0FyZywgcGFydGlhbHMpIHtcbiAgdmFyIGJpdG1hc2sgPSBCSU5EX0ZMQUc7XG4gIGlmIChwYXJ0aWFscy5sZW5ndGgpIHtcbiAgICB2YXIgaG9sZGVycyA9IHJlcGxhY2VIb2xkZXJzKHBhcnRpYWxzLCBiaW5kLnBsYWNlaG9sZGVyKTtcbiAgICBiaXRtYXNrIHw9IFBBUlRJQUxfRkxBRztcbiAgfVxuICByZXR1cm4gY3JlYXRlV3JhcHBlcihmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscywgaG9sZGVycyk7XG59KTtcblxuLy8gQXNzaWduIGRlZmF1bHQgcGxhY2Vob2xkZXJzLlxuYmluZC5wbGFjZWhvbGRlciA9IHt9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJpbmQ7XG4iLCIvKiogVXNlZCBhcyB0aGUgYFR5cGVFcnJvcmAgbWVzc2FnZSBmb3IgXCJGdW5jdGlvbnNcIiBtZXRob2RzLiAqL1xudmFyIEZVTkNfRVJST1JfVEVYVCA9ICdFeHBlY3RlZCBhIGZ1bmN0aW9uJztcblxuLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heDtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBmdW5jYCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBvZiB0aGVcbiAqIGNyZWF0ZWQgZnVuY3Rpb24gYW5kIGFyZ3VtZW50cyBmcm9tIGBzdGFydGAgYW5kIGJleW9uZCBwcm92aWRlZCBhcyBhbiBhcnJheS5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgYmFzZWQgb24gdGhlIFtyZXN0IHBhcmFtZXRlcl0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvRnVuY3Rpb25zL3Jlc3RfcGFyYW1ldGVycykuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYXBwbHkgYSByZXN0IHBhcmFtZXRlciB0by5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9ZnVuYy5sZW5ndGgtMV0gVGhlIHN0YXJ0IHBvc2l0aW9uIG9mIHRoZSByZXN0IHBhcmFtZXRlci5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgc2F5ID0gXy5yZXN0UGFyYW0oZnVuY3Rpb24od2hhdCwgbmFtZXMpIHtcbiAqICAgcmV0dXJuIHdoYXQgKyAnICcgKyBfLmluaXRpYWwobmFtZXMpLmpvaW4oJywgJykgK1xuICogICAgIChfLnNpemUobmFtZXMpID4gMSA/ICcsICYgJyA6ICcnKSArIF8ubGFzdChuYW1lcyk7XG4gKiB9KTtcbiAqXG4gKiBzYXkoJ2hlbGxvJywgJ2ZyZWQnLCAnYmFybmV5JywgJ3BlYmJsZXMnKTtcbiAqIC8vID0+ICdoZWxsbyBmcmVkLCBiYXJuZXksICYgcGViYmxlcydcbiAqL1xuZnVuY3Rpb24gcmVzdFBhcmFtKGZ1bmMsIHN0YXJ0KSB7XG4gIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICB9XG4gIHN0YXJ0ID0gbmF0aXZlTWF4KHN0YXJ0ID09PSB1bmRlZmluZWQgPyAoZnVuYy5sZW5ndGggLSAxKSA6ICgrc3RhcnQgfHwgMCksIDApO1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGFyZ3MgPSBhcmd1bWVudHMsXG4gICAgICAgIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IG5hdGl2ZU1heChhcmdzLmxlbmd0aCAtIHN0YXJ0LCAwKSxcbiAgICAgICAgcmVzdCA9IEFycmF5KGxlbmd0aCk7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgcmVzdFtpbmRleF0gPSBhcmdzW3N0YXJ0ICsgaW5kZXhdO1xuICAgIH1cbiAgICBzd2l0Y2ggKHN0YXJ0KSB7XG4gICAgICBjYXNlIDA6IHJldHVybiBmdW5jLmNhbGwodGhpcywgcmVzdCk7XG4gICAgICBjYXNlIDE6IHJldHVybiBmdW5jLmNhbGwodGhpcywgYXJnc1swXSwgcmVzdCk7XG4gICAgICBjYXNlIDI6IHJldHVybiBmdW5jLmNhbGwodGhpcywgYXJnc1swXSwgYXJnc1sxXSwgcmVzdCk7XG4gICAgfVxuICAgIHZhciBvdGhlckFyZ3MgPSBBcnJheShzdGFydCArIDEpO1xuICAgIGluZGV4ID0gLTE7XG4gICAgd2hpbGUgKCsraW5kZXggPCBzdGFydCkge1xuICAgICAgb3RoZXJBcmdzW2luZGV4XSA9IGFyZ3NbaW5kZXhdO1xuICAgIH1cbiAgICBvdGhlckFyZ3Nbc3RhcnRdID0gcmVzdDtcbiAgICByZXR1cm4gZnVuYy5hcHBseSh0aGlzLCBvdGhlckFyZ3MpO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlc3RQYXJhbTtcbiIsInZhciBiYXNlQ3JlYXRlID0gcmVxdWlyZSgnLi9iYXNlQ3JlYXRlJyksXG4gICAgYmFzZUxvZGFzaCA9IHJlcXVpcmUoJy4vYmFzZUxvZGFzaCcpO1xuXG4vKiogVXNlZCBhcyByZWZlcmVuY2VzIGZvciBgLUluZmluaXR5YCBhbmQgYEluZmluaXR5YC4gKi9cbnZhciBQT1NJVElWRV9JTkZJTklUWSA9IE51bWJlci5QT1NJVElWRV9JTkZJTklUWTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbGF6eSB3cmFwcGVyIG9iamVjdCB3aGljaCB3cmFwcyBgdmFsdWVgIHRvIGVuYWJsZSBsYXp5IGV2YWx1YXRpb24uXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHdyYXAuXG4gKi9cbmZ1bmN0aW9uIExhenlXcmFwcGVyKHZhbHVlKSB7XG4gIHRoaXMuX193cmFwcGVkX18gPSB2YWx1ZTtcbiAgdGhpcy5fX2FjdGlvbnNfXyA9IG51bGw7XG4gIHRoaXMuX19kaXJfXyA9IDE7XG4gIHRoaXMuX19kcm9wQ291bnRfXyA9IDA7XG4gIHRoaXMuX19maWx0ZXJlZF9fID0gZmFsc2U7XG4gIHRoaXMuX19pdGVyYXRlZXNfXyA9IG51bGw7XG4gIHRoaXMuX190YWtlQ291bnRfXyA9IFBPU0lUSVZFX0lORklOSVRZO1xuICB0aGlzLl9fdmlld3NfXyA9IG51bGw7XG59XG5cbkxhenlXcmFwcGVyLnByb3RvdHlwZSA9IGJhc2VDcmVhdGUoYmFzZUxvZGFzaC5wcm90b3R5cGUpO1xuTGF6eVdyYXBwZXIucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gTGF6eVdyYXBwZXI7XG5cbm1vZHVsZS5leHBvcnRzID0gTGF6eVdyYXBwZXI7XG4iLCJ2YXIgYmFzZUNyZWF0ZSA9IHJlcXVpcmUoJy4vYmFzZUNyZWF0ZScpLFxuICAgIGJhc2VMb2Rhc2ggPSByZXF1aXJlKCcuL2Jhc2VMb2Rhc2gnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBjb25zdHJ1Y3RvciBmb3IgY3JlYXRpbmcgYGxvZGFzaGAgd3JhcHBlciBvYmplY3RzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB3cmFwLlxuICogQHBhcmFtIHtib29sZWFufSBbY2hhaW5BbGxdIEVuYWJsZSBjaGFpbmluZyBmb3IgYWxsIHdyYXBwZXIgbWV0aG9kcy5cbiAqIEBwYXJhbSB7QXJyYXl9IFthY3Rpb25zPVtdXSBBY3Rpb25zIHRvIHBlZm9ybSB0byByZXNvbHZlIHRoZSB1bndyYXBwZWQgdmFsdWUuXG4gKi9cbmZ1bmN0aW9uIExvZGFzaFdyYXBwZXIodmFsdWUsIGNoYWluQWxsLCBhY3Rpb25zKSB7XG4gIHRoaXMuX193cmFwcGVkX18gPSB2YWx1ZTtcbiAgdGhpcy5fX2FjdGlvbnNfXyA9IGFjdGlvbnMgfHwgW107XG4gIHRoaXMuX19jaGFpbl9fID0gISFjaGFpbkFsbDtcbn1cblxuTG9kYXNoV3JhcHBlci5wcm90b3R5cGUgPSBiYXNlQ3JlYXRlKGJhc2VMb2Rhc2gucHJvdG90eXBlKTtcbkxvZGFzaFdyYXBwZXIucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gTG9kYXNoV3JhcHBlcjtcblxubW9kdWxlLmV4cG9ydHMgPSBMb2Rhc2hXcmFwcGVyO1xuIiwiLyoqXG4gKiBDb3BpZXMgdGhlIHZhbHVlcyBvZiBgc291cmNlYCB0byBgYXJyYXlgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBzb3VyY2UgVGhlIGFycmF5IHRvIGNvcHkgdmFsdWVzIGZyb20uXG4gKiBAcGFyYW0ge0FycmF5fSBbYXJyYXk9W11dIFRoZSBhcnJheSB0byBjb3B5IHZhbHVlcyB0by5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICovXG5mdW5jdGlvbiBhcnJheUNvcHkoc291cmNlLCBhcnJheSkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IHNvdXJjZS5sZW5ndGg7XG5cbiAgYXJyYXkgfHwgKGFycmF5ID0gQXJyYXkobGVuZ3RoKSk7XG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgYXJyYXlbaW5kZXhdID0gc291cmNlW2luZGV4XTtcbiAgfVxuICByZXR1cm4gYXJyYXk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYXJyYXlDb3B5O1xuIiwiLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uZm9yRWFjaGAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gKiBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAqL1xuZnVuY3Rpb24gYXJyYXlFYWNoKGFycmF5LCBpdGVyYXRlZSkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGlmIChpdGVyYXRlZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSkgPT09IGZhbHNlKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGFycmF5O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFycmF5RWFjaDtcbiIsIi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLm1hcGAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gKiBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBtYXBwZWQgYXJyYXkuXG4gKi9cbmZ1bmN0aW9uIGFycmF5TWFwKGFycmF5LCBpdGVyYXRlZSkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIHJlc3VsdCA9IEFycmF5KGxlbmd0aCk7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICByZXN1bHRbaW5kZXhdID0gaXRlcmF0ZWUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYXJyYXlNYXA7XG4iLCIvKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5zb21lYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3IgY2FsbGJhY2tcbiAqIHNob3J0aGFuZHMgYW5kIGB0aGlzYCBiaW5kaW5nLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW55IGVsZW1lbnQgcGFzc2VzIHRoZSBwcmVkaWNhdGUgY2hlY2ssXG4gKiAgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBhcnJheVNvbWUoYXJyYXksIHByZWRpY2F0ZSkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGlmIChwcmVkaWNhdGUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFycmF5U29tZTtcbiIsInZhciBiYXNlQ29weSA9IHJlcXVpcmUoJy4vYmFzZUNvcHknKSxcbiAgICBrZXlzID0gcmVxdWlyZSgnLi4vb2JqZWN0L2tleXMnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5hc3NpZ25gIHdpdGhvdXQgc3VwcG9ydCBmb3IgYXJndW1lbnQganVnZ2xpbmcsXG4gKiBtdWx0aXBsZSBzb3VyY2VzLCBhbmQgYGN1c3RvbWl6ZXJgIGZ1bmN0aW9ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgc291cmNlIG9iamVjdC5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VBc3NpZ24ob2JqZWN0LCBzb3VyY2UpIHtcbiAgcmV0dXJuIHNvdXJjZSA9PSBudWxsXG4gICAgPyBvYmplY3RcbiAgICA6IGJhc2VDb3B5KHNvdXJjZSwga2V5cyhzb3VyY2UpLCBvYmplY3QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VBc3NpZ247XG4iLCJ2YXIgYmFzZU1hdGNoZXMgPSByZXF1aXJlKCcuL2Jhc2VNYXRjaGVzJyksXG4gICAgYmFzZU1hdGNoZXNQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vYmFzZU1hdGNoZXNQcm9wZXJ0eScpLFxuICAgIGJpbmRDYWxsYmFjayA9IHJlcXVpcmUoJy4vYmluZENhbGxiYWNrJyksXG4gICAgaWRlbnRpdHkgPSByZXF1aXJlKCcuLi91dGlsaXR5L2lkZW50aXR5JyksXG4gICAgcHJvcGVydHkgPSByZXF1aXJlKCcuLi91dGlsaXR5L3Byb3BlcnR5Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uY2FsbGJhY2tgIHdoaWNoIHN1cHBvcnRzIHNwZWNpZnlpbmcgdGhlXG4gKiBudW1iZXIgb2YgYXJndW1lbnRzIHRvIHByb3ZpZGUgdG8gYGZ1bmNgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IFtmdW5jPV8uaWRlbnRpdHldIFRoZSB2YWx1ZSB0byBjb252ZXJ0IHRvIGEgY2FsbGJhY2suXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHBhcmFtIHtudW1iZXJ9IFthcmdDb3VudF0gVGhlIG51bWJlciBvZiBhcmd1bWVudHMgdG8gcHJvdmlkZSB0byBgZnVuY2AuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIGNhbGxiYWNrLlxuICovXG5mdW5jdGlvbiBiYXNlQ2FsbGJhY2soZnVuYywgdGhpc0FyZywgYXJnQ291bnQpIHtcbiAgdmFyIHR5cGUgPSB0eXBlb2YgZnVuYztcbiAgaWYgKHR5cGUgPT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiB0aGlzQXJnID09PSB1bmRlZmluZWRcbiAgICAgID8gZnVuY1xuICAgICAgOiBiaW5kQ2FsbGJhY2soZnVuYywgdGhpc0FyZywgYXJnQ291bnQpO1xuICB9XG4gIGlmIChmdW5jID09IG51bGwpIHtcbiAgICByZXR1cm4gaWRlbnRpdHk7XG4gIH1cbiAgaWYgKHR5cGUgPT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm4gYmFzZU1hdGNoZXMoZnVuYyk7XG4gIH1cbiAgcmV0dXJuIHRoaXNBcmcgPT09IHVuZGVmaW5lZFxuICAgID8gcHJvcGVydHkoZnVuYylcbiAgICA6IGJhc2VNYXRjaGVzUHJvcGVydHkoZnVuYywgdGhpc0FyZyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUNhbGxiYWNrO1xuIiwidmFyIGFycmF5Q29weSA9IHJlcXVpcmUoJy4vYXJyYXlDb3B5JyksXG4gICAgYXJyYXlFYWNoID0gcmVxdWlyZSgnLi9hcnJheUVhY2gnKSxcbiAgICBiYXNlQXNzaWduID0gcmVxdWlyZSgnLi9iYXNlQXNzaWduJyksXG4gICAgYmFzZUZvck93biA9IHJlcXVpcmUoJy4vYmFzZUZvck93bicpLFxuICAgIGluaXRDbG9uZUFycmF5ID0gcmVxdWlyZSgnLi9pbml0Q2xvbmVBcnJheScpLFxuICAgIGluaXRDbG9uZUJ5VGFnID0gcmVxdWlyZSgnLi9pbml0Q2xvbmVCeVRhZycpLFxuICAgIGluaXRDbG9uZU9iamVjdCA9IHJlcXVpcmUoJy4vaW5pdENsb25lT2JqZWN0JyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcnJheScpLFxuICAgIGlzSG9zdE9iamVjdCA9IHJlcXVpcmUoJy4vaXNIb3N0T2JqZWN0JyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0Jyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBhcmdzVGFnID0gJ1tvYmplY3QgQXJndW1lbnRzXScsXG4gICAgYXJyYXlUYWcgPSAnW29iamVjdCBBcnJheV0nLFxuICAgIGJvb2xUYWcgPSAnW29iamVjdCBCb29sZWFuXScsXG4gICAgZGF0ZVRhZyA9ICdbb2JqZWN0IERhdGVdJyxcbiAgICBlcnJvclRhZyA9ICdbb2JqZWN0IEVycm9yXScsXG4gICAgZnVuY1RhZyA9ICdbb2JqZWN0IEZ1bmN0aW9uXScsXG4gICAgbWFwVGFnID0gJ1tvYmplY3QgTWFwXScsXG4gICAgbnVtYmVyVGFnID0gJ1tvYmplY3QgTnVtYmVyXScsXG4gICAgb2JqZWN0VGFnID0gJ1tvYmplY3QgT2JqZWN0XScsXG4gICAgcmVnZXhwVGFnID0gJ1tvYmplY3QgUmVnRXhwXScsXG4gICAgc2V0VGFnID0gJ1tvYmplY3QgU2V0XScsXG4gICAgc3RyaW5nVGFnID0gJ1tvYmplY3QgU3RyaW5nXScsXG4gICAgd2Vha01hcFRhZyA9ICdbb2JqZWN0IFdlYWtNYXBdJztcblxudmFyIGFycmF5QnVmZmVyVGFnID0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJyxcbiAgICBmbG9hdDMyVGFnID0gJ1tvYmplY3QgRmxvYXQzMkFycmF5XScsXG4gICAgZmxvYXQ2NFRhZyA9ICdbb2JqZWN0IEZsb2F0NjRBcnJheV0nLFxuICAgIGludDhUYWcgPSAnW29iamVjdCBJbnQ4QXJyYXldJyxcbiAgICBpbnQxNlRhZyA9ICdbb2JqZWN0IEludDE2QXJyYXldJyxcbiAgICBpbnQzMlRhZyA9ICdbb2JqZWN0IEludDMyQXJyYXldJyxcbiAgICB1aW50OFRhZyA9ICdbb2JqZWN0IFVpbnQ4QXJyYXldJyxcbiAgICB1aW50OENsYW1wZWRUYWcgPSAnW29iamVjdCBVaW50OENsYW1wZWRBcnJheV0nLFxuICAgIHVpbnQxNlRhZyA9ICdbb2JqZWN0IFVpbnQxNkFycmF5XScsXG4gICAgdWludDMyVGFnID0gJ1tvYmplY3QgVWludDMyQXJyYXldJztcblxuLyoqIFVzZWQgdG8gaWRlbnRpZnkgYHRvU3RyaW5nVGFnYCB2YWx1ZXMgc3VwcG9ydGVkIGJ5IGBfLmNsb25lYC4gKi9cbnZhciBjbG9uZWFibGVUYWdzID0ge307XG5jbG9uZWFibGVUYWdzW2FyZ3NUYWddID0gY2xvbmVhYmxlVGFnc1thcnJheVRhZ10gPVxuY2xvbmVhYmxlVGFnc1thcnJheUJ1ZmZlclRhZ10gPSBjbG9uZWFibGVUYWdzW2Jvb2xUYWddID1cbmNsb25lYWJsZVRhZ3NbZGF0ZVRhZ10gPSBjbG9uZWFibGVUYWdzW2Zsb2F0MzJUYWddID1cbmNsb25lYWJsZVRhZ3NbZmxvYXQ2NFRhZ10gPSBjbG9uZWFibGVUYWdzW2ludDhUYWddID1cbmNsb25lYWJsZVRhZ3NbaW50MTZUYWddID0gY2xvbmVhYmxlVGFnc1tpbnQzMlRhZ10gPVxuY2xvbmVhYmxlVGFnc1tudW1iZXJUYWddID0gY2xvbmVhYmxlVGFnc1tvYmplY3RUYWddID1cbmNsb25lYWJsZVRhZ3NbcmVnZXhwVGFnXSA9IGNsb25lYWJsZVRhZ3Nbc3RyaW5nVGFnXSA9XG5jbG9uZWFibGVUYWdzW3VpbnQ4VGFnXSA9IGNsb25lYWJsZVRhZ3NbdWludDhDbGFtcGVkVGFnXSA9XG5jbG9uZWFibGVUYWdzW3VpbnQxNlRhZ10gPSBjbG9uZWFibGVUYWdzW3VpbnQzMlRhZ10gPSB0cnVlO1xuY2xvbmVhYmxlVGFnc1tlcnJvclRhZ10gPSBjbG9uZWFibGVUYWdzW2Z1bmNUYWddID1cbmNsb25lYWJsZVRhZ3NbbWFwVGFnXSA9IGNsb25lYWJsZVRhZ3Nbc2V0VGFnXSA9XG5jbG9uZWFibGVUYWdzW3dlYWtNYXBUYWddID0gZmFsc2U7XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgW2B0b1N0cmluZ1RhZ2BdKGh0dHBzOi8vcGVvcGxlLm1vemlsbGEub3JnL35qb3JlbmRvcmZmL2VzNi1kcmFmdC5odG1sI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5jbG9uZWAgd2l0aG91dCBzdXBwb3J0IGZvciBhcmd1bWVudCBqdWdnbGluZ1xuICogYW5kIGB0aGlzYCBiaW5kaW5nIGBjdXN0b21pemVyYCBmdW5jdGlvbnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNsb25lLlxuICogQHBhcmFtIHtib29sZWFufSBbaXNEZWVwXSBTcGVjaWZ5IGEgZGVlcCBjbG9uZS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNsb25pbmcgdmFsdWVzLlxuICogQHBhcmFtIHtzdHJpbmd9IFtrZXldIFRoZSBrZXkgb2YgYHZhbHVlYC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0XSBUaGUgb2JqZWN0IGB2YWx1ZWAgYmVsb25ncyB0by5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0E9W11dIFRyYWNrcyB0cmF2ZXJzZWQgc291cmNlIG9iamVjdHMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tCPVtdXSBBc3NvY2lhdGVzIGNsb25lcyB3aXRoIHNvdXJjZSBjb3VudGVycGFydHMuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgY2xvbmVkIHZhbHVlLlxuICovXG5mdW5jdGlvbiBiYXNlQ2xvbmUodmFsdWUsIGlzRGVlcCwgY3VzdG9taXplciwga2V5LCBvYmplY3QsIHN0YWNrQSwgc3RhY2tCKSB7XG4gIHZhciByZXN1bHQ7XG4gIGlmIChjdXN0b21pemVyKSB7XG4gICAgcmVzdWx0ID0gb2JqZWN0ID8gY3VzdG9taXplcih2YWx1ZSwga2V5LCBvYmplY3QpIDogY3VzdG9taXplcih2YWx1ZSk7XG4gIH1cbiAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICBpZiAoIWlzT2JqZWN0KHZhbHVlKSkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuICB2YXIgaXNBcnIgPSBpc0FycmF5KHZhbHVlKTtcbiAgaWYgKGlzQXJyKSB7XG4gICAgcmVzdWx0ID0gaW5pdENsb25lQXJyYXkodmFsdWUpO1xuICAgIGlmICghaXNEZWVwKSB7XG4gICAgICByZXR1cm4gYXJyYXlDb3B5KHZhbHVlLCByZXN1bHQpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgdGFnID0gb2JqVG9TdHJpbmcuY2FsbCh2YWx1ZSksXG4gICAgICAgIGlzRnVuYyA9IHRhZyA9PSBmdW5jVGFnO1xuXG4gICAgaWYgKHRhZyA9PSBvYmplY3RUYWcgfHwgdGFnID09IGFyZ3NUYWcgfHwgKGlzRnVuYyAmJiAhb2JqZWN0KSkge1xuICAgICAgaWYgKGlzSG9zdE9iamVjdCh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIG9iamVjdCA/IHZhbHVlIDoge307XG4gICAgICB9XG4gICAgICByZXN1bHQgPSBpbml0Q2xvbmVPYmplY3QoaXNGdW5jID8ge30gOiB2YWx1ZSk7XG4gICAgICBpZiAoIWlzRGVlcCkge1xuICAgICAgICByZXR1cm4gYmFzZUFzc2lnbihyZXN1bHQsIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGNsb25lYWJsZVRhZ3NbdGFnXVxuICAgICAgICA/IGluaXRDbG9uZUJ5VGFnKHZhbHVlLCB0YWcsIGlzRGVlcClcbiAgICAgICAgOiAob2JqZWN0ID8gdmFsdWUgOiB7fSk7XG4gICAgfVxuICB9XG4gIC8vIENoZWNrIGZvciBjaXJjdWxhciByZWZlcmVuY2VzIGFuZCByZXR1cm4gY29ycmVzcG9uZGluZyBjbG9uZS5cbiAgc3RhY2tBIHx8IChzdGFja0EgPSBbXSk7XG4gIHN0YWNrQiB8fCAoc3RhY2tCID0gW10pO1xuXG4gIHZhciBsZW5ndGggPSBzdGFja0EubGVuZ3RoO1xuICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICBpZiAoc3RhY2tBW2xlbmd0aF0gPT0gdmFsdWUpIHtcbiAgICAgIHJldHVybiBzdGFja0JbbGVuZ3RoXTtcbiAgICB9XG4gIH1cbiAgLy8gQWRkIHRoZSBzb3VyY2UgdmFsdWUgdG8gdGhlIHN0YWNrIG9mIHRyYXZlcnNlZCBvYmplY3RzIGFuZCBhc3NvY2lhdGUgaXQgd2l0aCBpdHMgY2xvbmUuXG4gIHN0YWNrQS5wdXNoKHZhbHVlKTtcbiAgc3RhY2tCLnB1c2gocmVzdWx0KTtcblxuICAvLyBSZWN1cnNpdmVseSBwb3B1bGF0ZSBjbG9uZSAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAoaXNBcnIgPyBhcnJheUVhY2ggOiBiYXNlRm9yT3duKSh2YWx1ZSwgZnVuY3Rpb24oc3ViVmFsdWUsIGtleSkge1xuICAgIHJlc3VsdFtrZXldID0gYmFzZUNsb25lKHN1YlZhbHVlLCBpc0RlZXAsIGN1c3RvbWl6ZXIsIGtleSwgdmFsdWUsIHN0YWNrQSwgc3RhY2tCKTtcbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUNsb25lO1xuIiwiLyoqXG4gKiBDb3BpZXMgcHJvcGVydGllcyBvZiBgc291cmNlYCB0byBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgb2JqZWN0IHRvIGNvcHkgcHJvcGVydGllcyBmcm9tLlxuICogQHBhcmFtIHtBcnJheX0gcHJvcHMgVGhlIHByb3BlcnR5IG5hbWVzIHRvIGNvcHkuXG4gKiBAcGFyYW0ge09iamVjdH0gW29iamVjdD17fV0gVGhlIG9iamVjdCB0byBjb3B5IHByb3BlcnRpZXMgdG8uXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICovXG5mdW5jdGlvbiBiYXNlQ29weShzb3VyY2UsIHByb3BzLCBvYmplY3QpIHtcbiAgb2JqZWN0IHx8IChvYmplY3QgPSB7fSk7XG5cbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBwcm9wcy5sZW5ndGg7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICB2YXIga2V5ID0gcHJvcHNbaW5kZXhdO1xuICAgIG9iamVjdFtrZXldID0gc291cmNlW2tleV07XG4gIH1cbiAgcmV0dXJuIG9iamVjdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlQ29weTtcbiIsInZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4uL2xhbmcvaXNPYmplY3QnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5jcmVhdGVgIHdpdGhvdXQgc3VwcG9ydCBmb3IgYXNzaWduaW5nXG4gKiBwcm9wZXJ0aWVzIHRvIHRoZSBjcmVhdGVkIG9iamVjdC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHByb3RvdHlwZSBUaGUgb2JqZWN0IHRvIGluaGVyaXQgZnJvbS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBvYmplY3QuXG4gKi9cbnZhciBiYXNlQ3JlYXRlID0gKGZ1bmN0aW9uKCkge1xuICBmdW5jdGlvbiBvYmplY3QoKSB7fVxuICByZXR1cm4gZnVuY3Rpb24ocHJvdG90eXBlKSB7XG4gICAgaWYgKGlzT2JqZWN0KHByb3RvdHlwZSkpIHtcbiAgICAgIG9iamVjdC5wcm90b3R5cGUgPSBwcm90b3R5cGU7XG4gICAgICB2YXIgcmVzdWx0ID0gbmV3IG9iamVjdDtcbiAgICAgIG9iamVjdC5wcm90b3R5cGUgPSBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0IHx8IHt9O1xuICB9O1xufSgpKTtcblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlQ3JlYXRlO1xuIiwidmFyIGJhc2VGb3JPd24gPSByZXF1aXJlKCcuL2Jhc2VGb3JPd24nKSxcbiAgICBjcmVhdGVCYXNlRWFjaCA9IHJlcXVpcmUoJy4vY3JlYXRlQmFzZUVhY2gnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mb3JFYWNoYCB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gKiBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fHN0cmluZ30gUmV0dXJucyBgY29sbGVjdGlvbmAuXG4gKi9cbnZhciBiYXNlRWFjaCA9IGNyZWF0ZUJhc2VFYWNoKGJhc2VGb3JPd24pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VFYWNoO1xuIiwiLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5maW5kYCwgYF8uZmluZExhc3RgLCBgXy5maW5kS2V5YCwgYW5kIGBfLmZpbmRMYXN0S2V5YCxcbiAqIHdpdGhvdXQgc3VwcG9ydCBmb3IgY2FsbGJhY2sgc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcsIHdoaWNoIGl0ZXJhdGVzXG4gKiBvdmVyIGBjb2xsZWN0aW9uYCB1c2luZyB0aGUgcHJvdmlkZWQgYGVhY2hGdW5jYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHNlYXJjaC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZWFjaEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBgY29sbGVjdGlvbmAuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtyZXRLZXldIFNwZWNpZnkgcmV0dXJuaW5nIHRoZSBrZXkgb2YgdGhlIGZvdW5kIGVsZW1lbnRcbiAqICBpbnN0ZWFkIG9mIHRoZSBlbGVtZW50IGl0c2VsZi5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBmb3VuZCBlbGVtZW50IG9yIGl0cyBrZXksIGVsc2UgYHVuZGVmaW5lZGAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VGaW5kKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgZWFjaEZ1bmMsIHJldEtleSkge1xuICB2YXIgcmVzdWx0O1xuICBlYWNoRnVuYyhjb2xsZWN0aW9uLCBmdW5jdGlvbih2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKSB7XG4gICAgaWYgKHByZWRpY2F0ZSh2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKSkge1xuICAgICAgcmVzdWx0ID0gcmV0S2V5ID8ga2V5IDogdmFsdWU7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlRmluZDtcbiIsIi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZmluZEluZGV4YCBhbmQgYF8uZmluZExhc3RJbmRleGAgd2l0aG91dFxuICogc3VwcG9ydCBmb3IgY2FsbGJhY2sgc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzZWFyY2guXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIG1hdGNoZWQgdmFsdWUsIGVsc2UgYC0xYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUZpbmRJbmRleChhcnJheSwgcHJlZGljYXRlLCBmcm9tUmlnaHQpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIGluZGV4ID0gZnJvbVJpZ2h0ID8gbGVuZ3RoIDogLTE7XG5cbiAgd2hpbGUgKChmcm9tUmlnaHQgPyBpbmRleC0tIDogKytpbmRleCA8IGxlbmd0aCkpIHtcbiAgICBpZiAocHJlZGljYXRlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KSkge1xuICAgICAgcmV0dXJuIGluZGV4O1xuICAgIH1cbiAgfVxuICByZXR1cm4gLTE7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUZpbmRJbmRleDtcbiIsInZhciBjcmVhdGVCYXNlRm9yID0gcmVxdWlyZSgnLi9jcmVhdGVCYXNlRm9yJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGJhc2VGb3JJbmAgYW5kIGBiYXNlRm9yT3duYCB3aGljaCBpdGVyYXRlc1xuICogb3ZlciBgb2JqZWN0YCBwcm9wZXJ0aWVzIHJldHVybmVkIGJ5IGBrZXlzRnVuY2AgaW52b2tpbmcgYGl0ZXJhdGVlYCBmb3JcbiAqIGVhY2ggcHJvcGVydHkuIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdCBpdGVyYXRpb24gZWFybHkgYnkgZXhwbGljaXRseVxuICogcmV0dXJuaW5nIGBmYWxzZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHtGdW5jdGlvbn0ga2V5c0Z1bmMgVGhlIGZ1bmN0aW9uIHRvIGdldCB0aGUga2V5cyBvZiBgb2JqZWN0YC5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gKi9cbnZhciBiYXNlRm9yID0gY3JlYXRlQmFzZUZvcigpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VGb3I7XG4iLCJ2YXIgYmFzZUZvciA9IHJlcXVpcmUoJy4vYmFzZUZvcicpLFxuICAgIGtleXNJbiA9IHJlcXVpcmUoJy4uL29iamVjdC9rZXlzSW4nKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mb3JJbmAgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gYmFzZUZvckluKG9iamVjdCwgaXRlcmF0ZWUpIHtcbiAgcmV0dXJuIGJhc2VGb3Iob2JqZWN0LCBpdGVyYXRlZSwga2V5c0luKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlRm9ySW47XG4iLCJ2YXIgYmFzZUZvciA9IHJlcXVpcmUoJy4vYmFzZUZvcicpLFxuICAgIGtleXMgPSByZXF1aXJlKCcuLi9vYmplY3Qva2V5cycpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZvck93bmAgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gYmFzZUZvck93bihvYmplY3QsIGl0ZXJhdGVlKSB7XG4gIHJldHVybiBiYXNlRm9yKG9iamVjdCwgaXRlcmF0ZWUsIGtleXMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VGb3JPd247XG4iLCJ2YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL3RvT2JqZWN0Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGdldGAgd2l0aG91dCBzdXBwb3J0IGZvciBzdHJpbmcgcGF0aHNcbiAqIGFuZCBkZWZhdWx0IHZhbHVlcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtBcnJheX0gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHBhcmFtIHtzdHJpbmd9IFtwYXRoS2V5XSBUaGUga2V5IHJlcHJlc2VudGF0aW9uIG9mIHBhdGguXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmVzb2x2ZWQgdmFsdWUuXG4gKi9cbmZ1bmN0aW9uIGJhc2VHZXQob2JqZWN0LCBwYXRoLCBwYXRoS2V5KSB7XG4gIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgIHJldHVybjtcbiAgfVxuICBvYmplY3QgPSB0b09iamVjdChvYmplY3QpO1xuICBpZiAocGF0aEtleSAhPT0gdW5kZWZpbmVkICYmIHBhdGhLZXkgaW4gb2JqZWN0KSB7XG4gICAgcGF0aCA9IFtwYXRoS2V5XTtcbiAgfVxuICB2YXIgaW5kZXggPSAwLFxuICAgICAgbGVuZ3RoID0gcGF0aC5sZW5ndGg7XG5cbiAgd2hpbGUgKG9iamVjdCAhPSBudWxsICYmIGluZGV4IDwgbGVuZ3RoKSB7XG4gICAgb2JqZWN0ID0gdG9PYmplY3Qob2JqZWN0KVtwYXRoW2luZGV4KytdXTtcbiAgfVxuICByZXR1cm4gKGluZGV4ICYmIGluZGV4ID09IGxlbmd0aCkgPyBvYmplY3QgOiB1bmRlZmluZWQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUdldDtcbiIsInZhciBpbmRleE9mTmFOID0gcmVxdWlyZSgnLi9pbmRleE9mTmFOJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaW5kZXhPZmAgd2l0aG91dCBzdXBwb3J0IGZvciBiaW5hcnkgc2VhcmNoZXMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzZWFyY2guXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICogQHBhcmFtIHtudW1iZXJ9IGZyb21JbmRleCBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICovXG5mdW5jdGlvbiBiYXNlSW5kZXhPZihhcnJheSwgdmFsdWUsIGZyb21JbmRleCkge1xuICBpZiAodmFsdWUgIT09IHZhbHVlKSB7XG4gICAgcmV0dXJuIGluZGV4T2ZOYU4oYXJyYXksIGZyb21JbmRleCk7XG4gIH1cbiAgdmFyIGluZGV4ID0gZnJvbUluZGV4IC0gMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGlmIChhcnJheVtpbmRleF0gPT09IHZhbHVlKSB7XG4gICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuICB9XG4gIHJldHVybiAtMTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSW5kZXhPZjtcbiIsInZhciBiYXNlSXNFcXVhbERlZXAgPSByZXF1aXJlKCcuL2Jhc2VJc0VxdWFsRGVlcCcpLFxuICAgIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vbGFuZy9pc09iamVjdCcpLFxuICAgIGlzT2JqZWN0TGlrZSA9IHJlcXVpcmUoJy4vaXNPYmplY3RMaWtlJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNFcXVhbGAgd2l0aG91dCBzdXBwb3J0IGZvciBgdGhpc2AgYmluZGluZ1xuICogYGN1c3RvbWl6ZXJgIGZ1bmN0aW9ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpbmcgdmFsdWVzLlxuICogQHBhcmFtIHtib29sZWFufSBbaXNMb29zZV0gU3BlY2lmeSBwZXJmb3JtaW5nIHBhcnRpYWwgY29tcGFyaXNvbnMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tBXSBUcmFja3MgdHJhdmVyc2VkIGB2YWx1ZWAgb2JqZWN0cy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0JdIFRyYWNrcyB0cmF2ZXJzZWQgYG90aGVyYCBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUlzRXF1YWwodmFsdWUsIG90aGVyLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQikge1xuICBpZiAodmFsdWUgPT09IG90aGVyKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKHZhbHVlID09IG51bGwgfHwgb3RoZXIgPT0gbnVsbCB8fCAoIWlzT2JqZWN0KHZhbHVlKSAmJiAhaXNPYmplY3RMaWtlKG90aGVyKSkpIHtcbiAgICByZXR1cm4gdmFsdWUgIT09IHZhbHVlICYmIG90aGVyICE9PSBvdGhlcjtcbiAgfVxuICByZXR1cm4gYmFzZUlzRXF1YWxEZWVwKHZhbHVlLCBvdGhlciwgYmFzZUlzRXF1YWwsIGN1c3RvbWl6ZXIsIGlzTG9vc2UsIHN0YWNrQSwgc3RhY2tCKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNFcXVhbDtcbiIsInZhciBlcXVhbEFycmF5cyA9IHJlcXVpcmUoJy4vZXF1YWxBcnJheXMnKSxcbiAgICBlcXVhbEJ5VGFnID0gcmVxdWlyZSgnLi9lcXVhbEJ5VGFnJyksXG4gICAgZXF1YWxPYmplY3RzID0gcmVxdWlyZSgnLi9lcXVhbE9iamVjdHMnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FycmF5JyksXG4gICAgaXNIb3N0T2JqZWN0ID0gcmVxdWlyZSgnLi9pc0hvc3RPYmplY3QnKSxcbiAgICBpc1R5cGVkQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzVHlwZWRBcnJheScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYXJnc1RhZyA9ICdbb2JqZWN0IEFyZ3VtZW50c10nLFxuICAgIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJyxcbiAgICBvYmplY3RUYWcgPSAnW29iamVjdCBPYmplY3RdJztcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cHM6Ly9wZW9wbGUubW96aWxsYS5vcmcvfmpvcmVuZG9yZmYvZXM2LWRyYWZ0Lmh0bWwjc2VjLW9iamVjdC5wcm90b3R5cGUudG9zdHJpbmcpXG4gKiBvZiB2YWx1ZXMuXG4gKi9cbnZhciBvYmpUb1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxgIGZvciBhcnJheXMgYW5kIG9iamVjdHMgd2hpY2ggcGVyZm9ybXNcbiAqIGRlZXAgY29tcGFyaXNvbnMgYW5kIHRyYWNrcyB0cmF2ZXJzZWQgb2JqZWN0cyBlbmFibGluZyBvYmplY3RzIHdpdGggY2lyY3VsYXJcbiAqIHJlZmVyZW5jZXMgdG8gYmUgY29tcGFyZWQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtPYmplY3R9IG90aGVyIFRoZSBvdGhlciBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGVxdWFsRnVuYyBUaGUgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIGVxdWl2YWxlbnRzIG9mIHZhbHVlcy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmluZyBvYmplY3RzLlxuICogQHBhcmFtIHtib29sZWFufSBbaXNMb29zZV0gU3BlY2lmeSBwZXJmb3JtaW5nIHBhcnRpYWwgY29tcGFyaXNvbnMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tBPVtdXSBUcmFja3MgdHJhdmVyc2VkIGB2YWx1ZWAgb2JqZWN0cy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0I9W11dIFRyYWNrcyB0cmF2ZXJzZWQgYG90aGVyYCBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBvYmplY3RzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VJc0VxdWFsRGVlcChvYmplY3QsIG90aGVyLCBlcXVhbEZ1bmMsIGN1c3RvbWl6ZXIsIGlzTG9vc2UsIHN0YWNrQSwgc3RhY2tCKSB7XG4gIHZhciBvYmpJc0FyciA9IGlzQXJyYXkob2JqZWN0KSxcbiAgICAgIG90aElzQXJyID0gaXNBcnJheShvdGhlciksXG4gICAgICBvYmpUYWcgPSBhcnJheVRhZyxcbiAgICAgIG90aFRhZyA9IGFycmF5VGFnO1xuXG4gIGlmICghb2JqSXNBcnIpIHtcbiAgICBvYmpUYWcgPSBvYmpUb1N0cmluZy5jYWxsKG9iamVjdCk7XG4gICAgaWYgKG9ialRhZyA9PSBhcmdzVGFnKSB7XG4gICAgICBvYmpUYWcgPSBvYmplY3RUYWc7XG4gICAgfSBlbHNlIGlmIChvYmpUYWcgIT0gb2JqZWN0VGFnKSB7XG4gICAgICBvYmpJc0FyciA9IGlzVHlwZWRBcnJheShvYmplY3QpO1xuICAgIH1cbiAgfVxuICBpZiAoIW90aElzQXJyKSB7XG4gICAgb3RoVGFnID0gb2JqVG9TdHJpbmcuY2FsbChvdGhlcik7XG4gICAgaWYgKG90aFRhZyA9PSBhcmdzVGFnKSB7XG4gICAgICBvdGhUYWcgPSBvYmplY3RUYWc7XG4gICAgfSBlbHNlIGlmIChvdGhUYWcgIT0gb2JqZWN0VGFnKSB7XG4gICAgICBvdGhJc0FyciA9IGlzVHlwZWRBcnJheShvdGhlcik7XG4gICAgfVxuICB9XG4gIHZhciBvYmpJc09iaiA9IG9ialRhZyA9PSBvYmplY3RUYWcgJiYgIWlzSG9zdE9iamVjdChvYmplY3QpLFxuICAgICAgb3RoSXNPYmogPSBvdGhUYWcgPT0gb2JqZWN0VGFnICYmICFpc0hvc3RPYmplY3Qob3RoZXIpLFxuICAgICAgaXNTYW1lVGFnID0gb2JqVGFnID09IG90aFRhZztcblxuICBpZiAoaXNTYW1lVGFnICYmICEob2JqSXNBcnIgfHwgb2JqSXNPYmopKSB7XG4gICAgcmV0dXJuIGVxdWFsQnlUYWcob2JqZWN0LCBvdGhlciwgb2JqVGFnKTtcbiAgfVxuICBpZiAoIWlzTG9vc2UpIHtcbiAgICB2YXIgb2JqSXNXcmFwcGVkID0gb2JqSXNPYmogJiYgaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsICdfX3dyYXBwZWRfXycpLFxuICAgICAgICBvdGhJc1dyYXBwZWQgPSBvdGhJc09iaiAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKG90aGVyLCAnX193cmFwcGVkX18nKTtcblxuICAgIGlmIChvYmpJc1dyYXBwZWQgfHwgb3RoSXNXcmFwcGVkKSB7XG4gICAgICByZXR1cm4gZXF1YWxGdW5jKG9iaklzV3JhcHBlZCA/IG9iamVjdC52YWx1ZSgpIDogb2JqZWN0LCBvdGhJc1dyYXBwZWQgPyBvdGhlci52YWx1ZSgpIDogb3RoZXIsIGN1c3RvbWl6ZXIsIGlzTG9vc2UsIHN0YWNrQSwgc3RhY2tCKTtcbiAgICB9XG4gIH1cbiAgaWYgKCFpc1NhbWVUYWcpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy8gQXNzdW1lIGN5Y2xpYyB2YWx1ZXMgYXJlIGVxdWFsLlxuICAvLyBGb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiBkZXRlY3RpbmcgY2lyY3VsYXIgcmVmZXJlbmNlcyBzZWUgaHR0cHM6Ly9lczUuZ2l0aHViLmlvLyNKTy5cbiAgc3RhY2tBIHx8IChzdGFja0EgPSBbXSk7XG4gIHN0YWNrQiB8fCAoc3RhY2tCID0gW10pO1xuXG4gIHZhciBsZW5ndGggPSBzdGFja0EubGVuZ3RoO1xuICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICBpZiAoc3RhY2tBW2xlbmd0aF0gPT0gb2JqZWN0KSB7XG4gICAgICByZXR1cm4gc3RhY2tCW2xlbmd0aF0gPT0gb3RoZXI7XG4gICAgfVxuICB9XG4gIC8vIEFkZCBgb2JqZWN0YCBhbmQgYG90aGVyYCB0byB0aGUgc3RhY2sgb2YgdHJhdmVyc2VkIG9iamVjdHMuXG4gIHN0YWNrQS5wdXNoKG9iamVjdCk7XG4gIHN0YWNrQi5wdXNoKG90aGVyKTtcblxuICB2YXIgcmVzdWx0ID0gKG9iaklzQXJyID8gZXF1YWxBcnJheXMgOiBlcXVhbE9iamVjdHMpKG9iamVjdCwgb3RoZXIsIGVxdWFsRnVuYywgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpO1xuXG4gIHN0YWNrQS5wb3AoKTtcbiAgc3RhY2tCLnBvcCgpO1xuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUlzRXF1YWxEZWVwO1xuIiwiLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc0Z1bmN0aW9uYCB3aXRob3V0IHN1cHBvcnQgZm9yIGVudmlyb25tZW50c1xuICogd2l0aCBpbmNvcnJlY3QgYHR5cGVvZmAgcmVzdWx0cy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBiYXNlSXNGdW5jdGlvbih2YWx1ZSkge1xuICAvLyBBdm9pZCBhIENoYWtyYSBKSVQgYnVnIGluIGNvbXBhdGliaWxpdHkgbW9kZXMgb2YgSUUgMTEuXG4gIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vamFzaGtlbmFzL3VuZGVyc2NvcmUvaXNzdWVzLzE2MjEgZm9yIG1vcmUgZGV0YWlscy5cbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnZnVuY3Rpb24nIHx8IGZhbHNlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VJc0Z1bmN0aW9uO1xuIiwidmFyIGJhc2VJc0VxdWFsID0gcmVxdWlyZSgnLi9iYXNlSXNFcXVhbCcpLFxuICAgIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi90b09iamVjdCcpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzTWF0Y2hgIHdpdGhvdXQgc3VwcG9ydCBmb3IgY2FsbGJhY2tcbiAqIHNob3J0aGFuZHMgYW5kIGB0aGlzYCBiaW5kaW5nLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaW5zcGVjdC5cbiAqIEBwYXJhbSB7QXJyYXl9IG1hdGNoRGF0YSBUaGUgcHJvcGVyeSBuYW1lcywgdmFsdWVzLCBhbmQgY29tcGFyZSBmbGFncyB0byBtYXRjaC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmluZyBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBvYmplY3RgIGlzIGEgbWF0Y2gsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUlzTWF0Y2gob2JqZWN0LCBtYXRjaERhdGEsIGN1c3RvbWl6ZXIpIHtcbiAgdmFyIGluZGV4ID0gbWF0Y2hEYXRhLmxlbmd0aCxcbiAgICAgIGxlbmd0aCA9IGluZGV4LFxuICAgICAgbm9DdXN0b21pemVyID0gIWN1c3RvbWl6ZXI7XG5cbiAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgcmV0dXJuICFsZW5ndGg7XG4gIH1cbiAgb2JqZWN0ID0gdG9PYmplY3Qob2JqZWN0KTtcbiAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICB2YXIgZGF0YSA9IG1hdGNoRGF0YVtpbmRleF07XG4gICAgaWYgKChub0N1c3RvbWl6ZXIgJiYgZGF0YVsyXSlcbiAgICAgICAgICA/IGRhdGFbMV0gIT09IG9iamVjdFtkYXRhWzBdXVxuICAgICAgICAgIDogIShkYXRhWzBdIGluIG9iamVjdClcbiAgICAgICAgKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgZGF0YSA9IG1hdGNoRGF0YVtpbmRleF07XG4gICAgdmFyIGtleSA9IGRhdGFbMF0sXG4gICAgICAgIG9ialZhbHVlID0gb2JqZWN0W2tleV0sXG4gICAgICAgIHNyY1ZhbHVlID0gZGF0YVsxXTtcblxuICAgIGlmIChub0N1c3RvbWl6ZXIgJiYgZGF0YVsyXSkge1xuICAgICAgaWYgKG9ialZhbHVlID09PSB1bmRlZmluZWQgJiYgIShrZXkgaW4gb2JqZWN0KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciByZXN1bHQgPSBjdXN0b21pemVyID8gY3VzdG9taXplcihvYmpWYWx1ZSwgc3JjVmFsdWUsIGtleSkgOiB1bmRlZmluZWQ7XG4gICAgICBpZiAoIShyZXN1bHQgPT09IHVuZGVmaW5lZCA/IGJhc2VJc0VxdWFsKHNyY1ZhbHVlLCBvYmpWYWx1ZSwgY3VzdG9taXplciwgdHJ1ZSkgOiByZXN1bHQpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUlzTWF0Y2g7XG4iLCIvKipcbiAqIFRoZSBmdW5jdGlvbiB3aG9zZSBwcm90b3R5cGUgYWxsIGNoYWluaW5nIHdyYXBwZXJzIGluaGVyaXQgZnJvbS5cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBiYXNlTG9kYXNoKCkge1xuICAvLyBObyBvcGVyYXRpb24gcGVyZm9ybWVkLlxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VMb2Rhc2g7XG4iLCJ2YXIgYmFzZUVhY2ggPSByZXF1aXJlKCcuL2Jhc2VFYWNoJyksXG4gICAgaXNBcnJheUxpa2UgPSByZXF1aXJlKCcuL2lzQXJyYXlMaWtlJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ubWFwYCB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrIHNob3J0aGFuZHNcbiAqIGFuZCBgdGhpc2AgYmluZGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBtYXBwZWQgYXJyYXkuXG4gKi9cbmZ1bmN0aW9uIGJhc2VNYXAoY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICByZXN1bHQgPSBpc0FycmF5TGlrZShjb2xsZWN0aW9uKSA/IEFycmF5KGNvbGxlY3Rpb24ubGVuZ3RoKSA6IFtdO1xuXG4gIGJhc2VFYWNoKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBrZXksIGNvbGxlY3Rpb24pIHtcbiAgICByZXN1bHRbKytpbmRleF0gPSBpdGVyYXRlZSh2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKTtcbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZU1hcDtcbiIsInZhciBiYXNlSXNNYXRjaCA9IHJlcXVpcmUoJy4vYmFzZUlzTWF0Y2gnKSxcbiAgICBnZXRNYXRjaERhdGEgPSByZXF1aXJlKCcuL2dldE1hdGNoRGF0YScpLFxuICAgIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi90b09iamVjdCcpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm1hdGNoZXNgIHdoaWNoIGRvZXMgbm90IGNsb25lIGBzb3VyY2VgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3Qgb2YgcHJvcGVydHkgdmFsdWVzIHRvIG1hdGNoLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGJhc2VNYXRjaGVzKHNvdXJjZSkge1xuICB2YXIgbWF0Y2hEYXRhID0gZ2V0TWF0Y2hEYXRhKHNvdXJjZSk7XG4gIGlmIChtYXRjaERhdGEubGVuZ3RoID09IDEgJiYgbWF0Y2hEYXRhWzBdWzJdKSB7XG4gICAgdmFyIGtleSA9IG1hdGNoRGF0YVswXVswXSxcbiAgICAgICAgdmFsdWUgPSBtYXRjaERhdGFbMF1bMV07XG5cbiAgICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgb2JqZWN0ID0gdG9PYmplY3Qob2JqZWN0KTtcbiAgICAgIHJldHVybiBvYmplY3Rba2V5XSA9PT0gdmFsdWUgJiYgKHZhbHVlICE9PSB1bmRlZmluZWQgfHwgKGtleSBpbiBvYmplY3QpKTtcbiAgICB9O1xuICB9XG4gIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICByZXR1cm4gYmFzZUlzTWF0Y2gob2JqZWN0LCBtYXRjaERhdGEpO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VNYXRjaGVzO1xuIiwidmFyIGJhc2VHZXQgPSByZXF1aXJlKCcuL2Jhc2VHZXQnKSxcbiAgICBiYXNlSXNFcXVhbCA9IHJlcXVpcmUoJy4vYmFzZUlzRXF1YWwnKSxcbiAgICBiYXNlU2xpY2UgPSByZXF1aXJlKCcuL2Jhc2VTbGljZScpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICBpc0tleSA9IHJlcXVpcmUoJy4vaXNLZXknKSxcbiAgICBpc1N0cmljdENvbXBhcmFibGUgPSByZXF1aXJlKCcuL2lzU3RyaWN0Q29tcGFyYWJsZScpLFxuICAgIGxhc3QgPSByZXF1aXJlKCcuLi9hcnJheS9sYXN0JyksXG4gICAgdG9PYmplY3QgPSByZXF1aXJlKCcuL3RvT2JqZWN0JyksXG4gICAgdG9QYXRoID0gcmVxdWlyZSgnLi90b1BhdGgnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5tYXRjaGVzUHJvcGVydHlgIHdoaWNoIGRvZXMgbm90IGNsb25lIGBzcmNWYWx1ZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gKiBAcGFyYW0geyp9IHNyY1ZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGJhc2VNYXRjaGVzUHJvcGVydHkocGF0aCwgc3JjVmFsdWUpIHtcbiAgdmFyIGlzQXJyID0gaXNBcnJheShwYXRoKSxcbiAgICAgIGlzQ29tbW9uID0gaXNLZXkocGF0aCkgJiYgaXNTdHJpY3RDb21wYXJhYmxlKHNyY1ZhbHVlKSxcbiAgICAgIHBhdGhLZXkgPSAocGF0aCArICcnKTtcblxuICBwYXRoID0gdG9QYXRoKHBhdGgpO1xuICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHZhciBrZXkgPSBwYXRoS2V5O1xuICAgIG9iamVjdCA9IHRvT2JqZWN0KG9iamVjdCk7XG4gICAgaWYgKChpc0FyciB8fCAhaXNDb21tb24pICYmICEoa2V5IGluIG9iamVjdCkpIHtcbiAgICAgIG9iamVjdCA9IHBhdGgubGVuZ3RoID09IDEgPyBvYmplY3QgOiBiYXNlR2V0KG9iamVjdCwgYmFzZVNsaWNlKHBhdGgsIDAsIC0xKSk7XG4gICAgICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAga2V5ID0gbGFzdChwYXRoKTtcbiAgICAgIG9iamVjdCA9IHRvT2JqZWN0KG9iamVjdCk7XG4gICAgfVxuICAgIHJldHVybiBvYmplY3Rba2V5XSA9PT0gc3JjVmFsdWVcbiAgICAgID8gKHNyY1ZhbHVlICE9PSB1bmRlZmluZWQgfHwgKGtleSBpbiBvYmplY3QpKVxuICAgICAgOiBiYXNlSXNFcXVhbChzcmNWYWx1ZSwgb2JqZWN0W2tleV0sIHVuZGVmaW5lZCwgdHJ1ZSk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZU1hdGNoZXNQcm9wZXJ0eTtcbiIsInZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5wcm9wZXJ0eWAgd2l0aG91dCBzdXBwb3J0IGZvciBkZWVwIHBhdGhzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHByb3BlcnR5IHRvIGdldC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBiYXNlUHJvcGVydHkoa2V5KSB7XG4gIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiB0b09iamVjdChvYmplY3QpW2tleV07XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZVByb3BlcnR5O1xuIiwidmFyIGJhc2VHZXQgPSByZXF1aXJlKCcuL2Jhc2VHZXQnKSxcbiAgICB0b1BhdGggPSByZXF1aXJlKCcuL3RvUGF0aCcpO1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZVByb3BlcnR5YCB3aGljaCBzdXBwb3J0cyBkZWVwIHBhdGhzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGJhc2VQcm9wZXJ0eURlZXAocGF0aCkge1xuICB2YXIgcGF0aEtleSA9IChwYXRoICsgJycpO1xuICBwYXRoID0gdG9QYXRoKHBhdGgpO1xuICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgcmV0dXJuIGJhc2VHZXQob2JqZWN0LCBwYXRoLCBwYXRoS2V5KTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlUHJvcGVydHlEZWVwO1xuIiwidmFyIGlkZW50aXR5ID0gcmVxdWlyZSgnLi4vdXRpbGl0eS9pZGVudGl0eScpLFxuICAgIG1ldGFNYXAgPSByZXF1aXJlKCcuL21ldGFNYXAnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgc2V0RGF0YWAgd2l0aG91dCBzdXBwb3J0IGZvciBob3QgbG9vcCBkZXRlY3Rpb24uXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFzc29jaWF0ZSBtZXRhZGF0YSB3aXRoLlxuICogQHBhcmFtIHsqfSBkYXRhIFRoZSBtZXRhZGF0YS5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBgZnVuY2AuXG4gKi9cbnZhciBiYXNlU2V0RGF0YSA9ICFtZXRhTWFwID8gaWRlbnRpdHkgOiBmdW5jdGlvbihmdW5jLCBkYXRhKSB7XG4gIG1ldGFNYXAuc2V0KGZ1bmMsIGRhdGEpO1xuICByZXR1cm4gZnVuYztcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZVNldERhdGE7XG4iLCIvKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnNsaWNlYCB3aXRob3V0IGFuIGl0ZXJhdGVlIGNhbGwgZ3VhcmQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzbGljZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9MF0gVGhlIHN0YXJ0IHBvc2l0aW9uLlxuICogQHBhcmFtIHtudW1iZXJ9IFtlbmQ9YXJyYXkubGVuZ3RoXSBUaGUgZW5kIHBvc2l0aW9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBzbGljZSBvZiBgYXJyYXlgLlxuICovXG5mdW5jdGlvbiBiYXNlU2xpY2UoYXJyYXksIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgc3RhcnQgPSBzdGFydCA9PSBudWxsID8gMCA6ICgrc3RhcnQgfHwgMCk7XG4gIGlmIChzdGFydCA8IDApIHtcbiAgICBzdGFydCA9IC1zdGFydCA+IGxlbmd0aCA/IDAgOiAobGVuZ3RoICsgc3RhcnQpO1xuICB9XG4gIGVuZCA9IChlbmQgPT09IHVuZGVmaW5lZCB8fCBlbmQgPiBsZW5ndGgpID8gbGVuZ3RoIDogKCtlbmQgfHwgMCk7XG4gIGlmIChlbmQgPCAwKSB7XG4gICAgZW5kICs9IGxlbmd0aDtcbiAgfVxuICBsZW5ndGggPSBzdGFydCA+IGVuZCA/IDAgOiAoKGVuZCAtIHN0YXJ0KSA+Pj4gMCk7XG4gIHN0YXJ0ID4+Pj0gMDtcblxuICB2YXIgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKTtcbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICByZXN1bHRbaW5kZXhdID0gYXJyYXlbaW5kZXggKyBzdGFydF07XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlU2xpY2U7XG4iLCIvKipcbiAqIENvbnZlcnRzIGB2YWx1ZWAgdG8gYSBzdHJpbmcgaWYgaXQncyBub3Qgb25lLiBBbiBlbXB0eSBzdHJpbmcgaXMgcmV0dXJuZWRcbiAqIGZvciBgbnVsbGAgb3IgYHVuZGVmaW5lZGAgdmFsdWVzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm9jZXNzLlxuICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgc3RyaW5nLlxuICovXG5mdW5jdGlvbiBiYXNlVG9TdHJpbmcodmFsdWUpIHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJykge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuICByZXR1cm4gdmFsdWUgPT0gbnVsbCA/ICcnIDogKHZhbHVlICsgJycpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VUb1N0cmluZztcbiIsIi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8udmFsdWVzYCBhbmQgYF8udmFsdWVzSW5gIHdoaWNoIGNyZWF0ZXMgYW5cbiAqIGFycmF5IG9mIGBvYmplY3RgIHByb3BlcnR5IHZhbHVlcyBjb3JyZXNwb25kaW5nIHRvIHRoZSBwcm9wZXJ0eSBuYW1lc1xuICogb2YgYHByb3BzYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtBcnJheX0gcHJvcHMgVGhlIHByb3BlcnR5IG5hbWVzIHRvIGdldCB2YWx1ZXMgZm9yLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgdmFsdWVzLlxuICovXG5mdW5jdGlvbiBiYXNlVmFsdWVzKG9iamVjdCwgcHJvcHMpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBwcm9wcy5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBBcnJheShsZW5ndGgpO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgcmVzdWx0W2luZGV4XSA9IG9iamVjdFtwcm9wc1tpbmRleF1dO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZVZhbHVlcztcbiIsInZhciBiaW5hcnlJbmRleEJ5ID0gcmVxdWlyZSgnLi9iaW5hcnlJbmRleEJ5JyksXG4gICAgaWRlbnRpdHkgPSByZXF1aXJlKCcuLi91dGlsaXR5L2lkZW50aXR5Jyk7XG5cbi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHRoZSBtYXhpbXVtIGxlbmd0aCBhbmQgaW5kZXggb2YgYW4gYXJyYXkuICovXG52YXIgTUFYX0FSUkFZX0xFTkdUSCA9IDQyOTQ5NjcyOTUsXG4gICAgSEFMRl9NQVhfQVJSQVlfTEVOR1RIID0gTUFYX0FSUkFZX0xFTkdUSCA+Pj4gMTtcblxuLyoqXG4gKiBQZXJmb3JtcyBhIGJpbmFyeSBzZWFyY2ggb2YgYGFycmF5YCB0byBkZXRlcm1pbmUgdGhlIGluZGV4IGF0IHdoaWNoIGB2YWx1ZWBcbiAqIHNob3VsZCBiZSBpbnNlcnRlZCBpbnRvIGBhcnJheWAgaW4gb3JkZXIgdG8gbWFpbnRhaW4gaXRzIHNvcnQgb3JkZXIuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBzb3J0ZWQgYXJyYXkgdG8gaW5zcGVjdC5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGV2YWx1YXRlLlxuICogQHBhcmFtIHtib29sZWFufSBbcmV0SGlnaGVzdF0gU3BlY2lmeSByZXR1cm5pbmcgdGhlIGhpZ2hlc3QgcXVhbGlmaWVkIGluZGV4LlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggYXQgd2hpY2ggYHZhbHVlYCBzaG91bGQgYmUgaW5zZXJ0ZWRcbiAqICBpbnRvIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGJpbmFyeUluZGV4KGFycmF5LCB2YWx1ZSwgcmV0SGlnaGVzdCkge1xuICB2YXIgbG93ID0gMCxcbiAgICAgIGhpZ2ggPSBhcnJheSA/IGFycmF5Lmxlbmd0aCA6IGxvdztcblxuICBpZiAodHlwZW9mIHZhbHVlID09ICdudW1iZXInICYmIHZhbHVlID09PSB2YWx1ZSAmJiBoaWdoIDw9IEhBTEZfTUFYX0FSUkFZX0xFTkdUSCkge1xuICAgIHdoaWxlIChsb3cgPCBoaWdoKSB7XG4gICAgICB2YXIgbWlkID0gKGxvdyArIGhpZ2gpID4+PiAxLFxuICAgICAgICAgIGNvbXB1dGVkID0gYXJyYXlbbWlkXTtcblxuICAgICAgaWYgKChyZXRIaWdoZXN0ID8gKGNvbXB1dGVkIDw9IHZhbHVlKSA6IChjb21wdXRlZCA8IHZhbHVlKSkgJiYgY29tcHV0ZWQgIT09IG51bGwpIHtcbiAgICAgICAgbG93ID0gbWlkICsgMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGhpZ2ggPSBtaWQ7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBoaWdoO1xuICB9XG4gIHJldHVybiBiaW5hcnlJbmRleEJ5KGFycmF5LCB2YWx1ZSwgaWRlbnRpdHksIHJldEhpZ2hlc3QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJpbmFyeUluZGV4O1xuIiwiLyoqIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBmbG9vciA9IE1hdGguZmxvb3I7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlTWluID0gTWF0aC5taW47XG5cbi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHRoZSBtYXhpbXVtIGxlbmd0aCBhbmQgaW5kZXggb2YgYW4gYXJyYXkuICovXG52YXIgTUFYX0FSUkFZX0xFTkdUSCA9IDQyOTQ5NjcyOTUsXG4gICAgTUFYX0FSUkFZX0lOREVYID0gTUFYX0FSUkFZX0xFTkdUSCAtIDE7XG5cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBpcyBsaWtlIGBiaW5hcnlJbmRleGAgZXhjZXB0IHRoYXQgaXQgaW52b2tlcyBgaXRlcmF0ZWVgIGZvclxuICogYHZhbHVlYCBhbmQgZWFjaCBlbGVtZW50IG9mIGBhcnJheWAgdG8gY29tcHV0ZSB0aGVpciBzb3J0IHJhbmtpbmcuIFRoZVxuICogaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDsgKHZhbHVlKS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIHNvcnRlZCBhcnJheSB0byBpbnNwZWN0LlxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gZXZhbHVhdGUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHtib29sZWFufSBbcmV0SGlnaGVzdF0gU3BlY2lmeSByZXR1cm5pbmcgdGhlIGhpZ2hlc3QgcXVhbGlmaWVkIGluZGV4LlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggYXQgd2hpY2ggYHZhbHVlYCBzaG91bGQgYmUgaW5zZXJ0ZWRcbiAqICBpbnRvIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGJpbmFyeUluZGV4QnkoYXJyYXksIHZhbHVlLCBpdGVyYXRlZSwgcmV0SGlnaGVzdCkge1xuICB2YWx1ZSA9IGl0ZXJhdGVlKHZhbHVlKTtcblxuICB2YXIgbG93ID0gMCxcbiAgICAgIGhpZ2ggPSBhcnJheSA/IGFycmF5Lmxlbmd0aCA6IDAsXG4gICAgICB2YWxJc05hTiA9IHZhbHVlICE9PSB2YWx1ZSxcbiAgICAgIHZhbElzTnVsbCA9IHZhbHVlID09PSBudWxsLFxuICAgICAgdmFsSXNVbmRlZiA9IHZhbHVlID09PSB1bmRlZmluZWQ7XG5cbiAgd2hpbGUgKGxvdyA8IGhpZ2gpIHtcbiAgICB2YXIgbWlkID0gZmxvb3IoKGxvdyArIGhpZ2gpIC8gMiksXG4gICAgICAgIGNvbXB1dGVkID0gaXRlcmF0ZWUoYXJyYXlbbWlkXSksXG4gICAgICAgIGlzRGVmID0gY29tcHV0ZWQgIT09IHVuZGVmaW5lZCxcbiAgICAgICAgaXNSZWZsZXhpdmUgPSBjb21wdXRlZCA9PT0gY29tcHV0ZWQ7XG5cbiAgICBpZiAodmFsSXNOYU4pIHtcbiAgICAgIHZhciBzZXRMb3cgPSBpc1JlZmxleGl2ZSB8fCByZXRIaWdoZXN0O1xuICAgIH0gZWxzZSBpZiAodmFsSXNOdWxsKSB7XG4gICAgICBzZXRMb3cgPSBpc1JlZmxleGl2ZSAmJiBpc0RlZiAmJiAocmV0SGlnaGVzdCB8fCBjb21wdXRlZCAhPSBudWxsKTtcbiAgICB9IGVsc2UgaWYgKHZhbElzVW5kZWYpIHtcbiAgICAgIHNldExvdyA9IGlzUmVmbGV4aXZlICYmIChyZXRIaWdoZXN0IHx8IGlzRGVmKTtcbiAgICB9IGVsc2UgaWYgKGNvbXB1dGVkID09IG51bGwpIHtcbiAgICAgIHNldExvdyA9IGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICBzZXRMb3cgPSByZXRIaWdoZXN0ID8gKGNvbXB1dGVkIDw9IHZhbHVlKSA6IChjb21wdXRlZCA8IHZhbHVlKTtcbiAgICB9XG4gICAgaWYgKHNldExvdykge1xuICAgICAgbG93ID0gbWlkICsgMTtcbiAgICB9IGVsc2Uge1xuICAgICAgaGlnaCA9IG1pZDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG5hdGl2ZU1pbihoaWdoLCBNQVhfQVJSQVlfSU5ERVgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJpbmFyeUluZGV4Qnk7XG4iLCJ2YXIgaWRlbnRpdHkgPSByZXF1aXJlKCcuLi91dGlsaXR5L2lkZW50aXR5Jyk7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlQ2FsbGJhY2tgIHdoaWNoIG9ubHkgc3VwcG9ydHMgYHRoaXNgIGJpbmRpbmdcbiAqIGFuZCBzcGVjaWZ5aW5nIHRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHRvIHByb3ZpZGUgdG8gYGZ1bmNgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBiaW5kLlxuICogQHBhcmFtIHsqfSB0aGlzQXJnIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge251bWJlcn0gW2FyZ0NvdW50XSBUaGUgbnVtYmVyIG9mIGFyZ3VtZW50cyB0byBwcm92aWRlIHRvIGBmdW5jYC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgY2FsbGJhY2suXG4gKi9cbmZ1bmN0aW9uIGJpbmRDYWxsYmFjayhmdW5jLCB0aGlzQXJnLCBhcmdDb3VudCkge1xuICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBpZGVudGl0eTtcbiAgfVxuICBpZiAodGhpc0FyZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGZ1bmM7XG4gIH1cbiAgc3dpdGNoIChhcmdDb3VudCkge1xuICAgIGNhc2UgMTogcmV0dXJuIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIHZhbHVlKTtcbiAgICB9O1xuICAgIGNhc2UgMzogcmV0dXJuIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikge1xuICAgICAgcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnLCB2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pO1xuICAgIH07XG4gICAgY2FzZSA0OiByZXR1cm4gZnVuY3Rpb24oYWNjdW11bGF0b3IsIHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikge1xuICAgICAgcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnLCBhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKTtcbiAgICB9O1xuICAgIGNhc2UgNTogcmV0dXJuIGZ1bmN0aW9uKHZhbHVlLCBvdGhlciwga2V5LCBvYmplY3QsIHNvdXJjZSkge1xuICAgICAgcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnLCB2YWx1ZSwgb3RoZXIsIGtleSwgb2JqZWN0LCBzb3VyY2UpO1xuICAgIH07XG4gIH1cbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBmdW5jLmFwcGx5KHRoaXNBcmcsIGFyZ3VtZW50cyk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmluZENhbGxiYWNrO1xuIiwidmFyIGNvbnN0YW50ID0gcmVxdWlyZSgnLi4vdXRpbGl0eS9jb25zdGFudCcpLFxuICAgIGdldE5hdGl2ZSA9IHJlcXVpcmUoJy4vZ2V0TmF0aXZlJyk7XG5cbi8qKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgQXJyYXlCdWZmZXIgPSBnZXROYXRpdmUoZ2xvYmFsLCAnQXJyYXlCdWZmZXInKSxcbiAgICBidWZmZXJTbGljZSA9IGdldE5hdGl2ZShBcnJheUJ1ZmZlciAmJiBuZXcgQXJyYXlCdWZmZXIoMCksICdzbGljZScpLFxuICAgIGZsb29yID0gTWF0aC5mbG9vcixcbiAgICBVaW50OEFycmF5ID0gZ2V0TmF0aXZlKGdsb2JhbCwgJ1VpbnQ4QXJyYXknKTtcblxuLyoqIFVzZWQgdG8gY2xvbmUgYXJyYXkgYnVmZmVycy4gKi9cbnZhciBGbG9hdDY0QXJyYXkgPSAoZnVuY3Rpb24oKSB7XG4gIC8vIFNhZmFyaSA1IGVycm9ycyB3aGVuIHVzaW5nIGFuIGFycmF5IGJ1ZmZlciB0byBpbml0aWFsaXplIGEgdHlwZWQgYXJyYXlcbiAgLy8gd2hlcmUgdGhlIGFycmF5IGJ1ZmZlcidzIGBieXRlTGVuZ3RoYCBpcyBub3QgYSBtdWx0aXBsZSBvZiB0aGUgdHlwZWRcbiAgLy8gYXJyYXkncyBgQllURVNfUEVSX0VMRU1FTlRgLlxuICB0cnkge1xuICAgIHZhciBmdW5jID0gZ2V0TmF0aXZlKGdsb2JhbCwgJ0Zsb2F0NjRBcnJheScpLFxuICAgICAgICByZXN1bHQgPSBuZXcgZnVuYyhuZXcgQXJyYXlCdWZmZXIoMTApLCAwLCAxKSAmJiBmdW5jO1xuICB9IGNhdGNoKGUpIHt9XG4gIHJldHVybiByZXN1bHQgfHwgbnVsbDtcbn0oKSk7XG5cbi8qKiBVc2VkIGFzIHRoZSBzaXplLCBpbiBieXRlcywgb2YgZWFjaCBgRmxvYXQ2NEFycmF5YCBlbGVtZW50LiAqL1xudmFyIEZMT0FUNjRfQllURVNfUEVSX0VMRU1FTlQgPSBGbG9hdDY0QXJyYXkgPyBGbG9hdDY0QXJyYXkuQllURVNfUEVSX0VMRU1FTlQgOiAwO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBjbG9uZSBvZiB0aGUgZ2l2ZW4gYXJyYXkgYnVmZmVyLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5QnVmZmVyfSBidWZmZXIgVGhlIGFycmF5IGJ1ZmZlciB0byBjbG9uZS5cbiAqIEByZXR1cm5zIHtBcnJheUJ1ZmZlcn0gUmV0dXJucyB0aGUgY2xvbmVkIGFycmF5IGJ1ZmZlci5cbiAqL1xuZnVuY3Rpb24gYnVmZmVyQ2xvbmUoYnVmZmVyKSB7XG4gIHJldHVybiBidWZmZXJTbGljZS5jYWxsKGJ1ZmZlciwgMCk7XG59XG5pZiAoIWJ1ZmZlclNsaWNlKSB7XG4gIC8vIFBoYW50b21KUyBoYXMgYEFycmF5QnVmZmVyYCBhbmQgYFVpbnQ4QXJyYXlgIGJ1dCBub3QgYEZsb2F0NjRBcnJheWAuXG4gIGJ1ZmZlckNsb25lID0gIShBcnJheUJ1ZmZlciAmJiBVaW50OEFycmF5KSA/IGNvbnN0YW50KG51bGwpIDogZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgdmFyIGJ5dGVMZW5ndGggPSBidWZmZXIuYnl0ZUxlbmd0aCxcbiAgICAgICAgZmxvYXRMZW5ndGggPSBGbG9hdDY0QXJyYXkgPyBmbG9vcihieXRlTGVuZ3RoIC8gRkxPQVQ2NF9CWVRFU19QRVJfRUxFTUVOVCkgOiAwLFxuICAgICAgICBvZmZzZXQgPSBmbG9hdExlbmd0aCAqIEZMT0FUNjRfQllURVNfUEVSX0VMRU1FTlQsXG4gICAgICAgIHJlc3VsdCA9IG5ldyBBcnJheUJ1ZmZlcihieXRlTGVuZ3RoKTtcblxuICAgIGlmIChmbG9hdExlbmd0aCkge1xuICAgICAgdmFyIHZpZXcgPSBuZXcgRmxvYXQ2NEFycmF5KHJlc3VsdCwgMCwgZmxvYXRMZW5ndGgpO1xuICAgICAgdmlldy5zZXQobmV3IEZsb2F0NjRBcnJheShidWZmZXIsIDAsIGZsb2F0TGVuZ3RoKSk7XG4gICAgfVxuICAgIGlmIChieXRlTGVuZ3RoICE9IG9mZnNldCkge1xuICAgICAgdmlldyA9IG5ldyBVaW50OEFycmF5KHJlc3VsdCwgb2Zmc2V0KTtcbiAgICAgIHZpZXcuc2V0KG5ldyBVaW50OEFycmF5KGJ1ZmZlciwgb2Zmc2V0KSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYnVmZmVyQ2xvbmU7XG4iLCIvKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4O1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgdGhhdCBpcyB0aGUgY29tcG9zaXRpb24gb2YgcGFydGlhbGx5IGFwcGxpZWQgYXJndW1lbnRzLFxuICogcGxhY2Vob2xkZXJzLCBhbmQgcHJvdmlkZWQgYXJndW1lbnRzIGludG8gYSBzaW5nbGUgYXJyYXkgb2YgYXJndW1lbnRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gYXJncyBUaGUgcHJvdmlkZWQgYXJndW1lbnRzLlxuICogQHBhcmFtIHtBcnJheX0gcGFydGlhbHMgVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkLlxuICogQHBhcmFtIHtBcnJheX0gaG9sZGVycyBUaGUgYHBhcnRpYWxzYCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgY29tcG9zZWQgYXJndW1lbnRzLlxuICovXG5mdW5jdGlvbiBjb21wb3NlQXJncyhhcmdzLCBwYXJ0aWFscywgaG9sZGVycykge1xuICB2YXIgaG9sZGVyc0xlbmd0aCA9IGhvbGRlcnMubGVuZ3RoLFxuICAgICAgYXJnc0luZGV4ID0gLTEsXG4gICAgICBhcmdzTGVuZ3RoID0gbmF0aXZlTWF4KGFyZ3MubGVuZ3RoIC0gaG9sZGVyc0xlbmd0aCwgMCksXG4gICAgICBsZWZ0SW5kZXggPSAtMSxcbiAgICAgIGxlZnRMZW5ndGggPSBwYXJ0aWFscy5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBBcnJheShhcmdzTGVuZ3RoICsgbGVmdExlbmd0aCk7XG5cbiAgd2hpbGUgKCsrbGVmdEluZGV4IDwgbGVmdExlbmd0aCkge1xuICAgIHJlc3VsdFtsZWZ0SW5kZXhdID0gcGFydGlhbHNbbGVmdEluZGV4XTtcbiAgfVxuICB3aGlsZSAoKythcmdzSW5kZXggPCBob2xkZXJzTGVuZ3RoKSB7XG4gICAgcmVzdWx0W2hvbGRlcnNbYXJnc0luZGV4XV0gPSBhcmdzW2FyZ3NJbmRleF07XG4gIH1cbiAgd2hpbGUgKGFyZ3NMZW5ndGgtLSkge1xuICAgIHJlc3VsdFtsZWZ0SW5kZXgrK10gPSBhcmdzW2FyZ3NJbmRleCsrXTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvbXBvc2VBcmdzO1xuIiwiLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heDtcblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2UgYGNvbXBvc2VBcmdzYCBleGNlcHQgdGhhdCB0aGUgYXJndW1lbnRzIGNvbXBvc2l0aW9uXG4gKiBpcyB0YWlsb3JlZCBmb3IgYF8ucGFydGlhbFJpZ2h0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGFyZ3MgVGhlIHByb3ZpZGVkIGFyZ3VtZW50cy5cbiAqIEBwYXJhbSB7QXJyYXl9IHBhcnRpYWxzIFRoZSBhcmd1bWVudHMgdG8gYXBwZW5kIHRvIHRob3NlIHByb3ZpZGVkLlxuICogQHBhcmFtIHtBcnJheX0gaG9sZGVycyBUaGUgYHBhcnRpYWxzYCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgY29tcG9zZWQgYXJndW1lbnRzLlxuICovXG5mdW5jdGlvbiBjb21wb3NlQXJnc1JpZ2h0KGFyZ3MsIHBhcnRpYWxzLCBob2xkZXJzKSB7XG4gIHZhciBob2xkZXJzSW5kZXggPSAtMSxcbiAgICAgIGhvbGRlcnNMZW5ndGggPSBob2xkZXJzLmxlbmd0aCxcbiAgICAgIGFyZ3NJbmRleCA9IC0xLFxuICAgICAgYXJnc0xlbmd0aCA9IG5hdGl2ZU1heChhcmdzLmxlbmd0aCAtIGhvbGRlcnNMZW5ndGgsIDApLFxuICAgICAgcmlnaHRJbmRleCA9IC0xLFxuICAgICAgcmlnaHRMZW5ndGggPSBwYXJ0aWFscy5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBBcnJheShhcmdzTGVuZ3RoICsgcmlnaHRMZW5ndGgpO1xuXG4gIHdoaWxlICgrK2FyZ3NJbmRleCA8IGFyZ3NMZW5ndGgpIHtcbiAgICByZXN1bHRbYXJnc0luZGV4XSA9IGFyZ3NbYXJnc0luZGV4XTtcbiAgfVxuICB2YXIgb2Zmc2V0ID0gYXJnc0luZGV4O1xuICB3aGlsZSAoKytyaWdodEluZGV4IDwgcmlnaHRMZW5ndGgpIHtcbiAgICByZXN1bHRbb2Zmc2V0ICsgcmlnaHRJbmRleF0gPSBwYXJ0aWFsc1tyaWdodEluZGV4XTtcbiAgfVxuICB3aGlsZSAoKytob2xkZXJzSW5kZXggPCBob2xkZXJzTGVuZ3RoKSB7XG4gICAgcmVzdWx0W29mZnNldCArIGhvbGRlcnNbaG9sZGVyc0luZGV4XV0gPSBhcmdzW2FyZ3NJbmRleCsrXTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvbXBvc2VBcmdzUmlnaHQ7XG4iLCJ2YXIgZ2V0TGVuZ3RoID0gcmVxdWlyZSgnLi9nZXRMZW5ndGgnKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4vaXNMZW5ndGgnKSxcbiAgICB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgYGJhc2VFYWNoYCBvciBgYmFzZUVhY2hSaWdodGAgZnVuY3Rpb24uXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGVhY2hGdW5jIFRoZSBmdW5jdGlvbiB0byBpdGVyYXRlIG92ZXIgYSBjb2xsZWN0aW9uLlxuICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBiYXNlIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVCYXNlRWFjaChlYWNoRnVuYywgZnJvbVJpZ2h0KSB7XG4gIHJldHVybiBmdW5jdGlvbihjb2xsZWN0aW9uLCBpdGVyYXRlZSkge1xuICAgIHZhciBsZW5ndGggPSBjb2xsZWN0aW9uID8gZ2V0TGVuZ3RoKGNvbGxlY3Rpb24pIDogMDtcbiAgICBpZiAoIWlzTGVuZ3RoKGxlbmd0aCkpIHtcbiAgICAgIHJldHVybiBlYWNoRnVuYyhjb2xsZWN0aW9uLCBpdGVyYXRlZSk7XG4gICAgfVxuICAgIHZhciBpbmRleCA9IGZyb21SaWdodCA/IGxlbmd0aCA6IC0xLFxuICAgICAgICBpdGVyYWJsZSA9IHRvT2JqZWN0KGNvbGxlY3Rpb24pO1xuXG4gICAgd2hpbGUgKChmcm9tUmlnaHQgPyBpbmRleC0tIDogKytpbmRleCA8IGxlbmd0aCkpIHtcbiAgICAgIGlmIChpdGVyYXRlZShpdGVyYWJsZVtpbmRleF0sIGluZGV4LCBpdGVyYWJsZSkgPT09IGZhbHNlKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gY29sbGVjdGlvbjtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVCYXNlRWFjaDtcbiIsInZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgYmFzZSBmdW5jdGlvbiBmb3IgYF8uZm9ySW5gIG9yIGBfLmZvckluUmlnaHRgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtmcm9tUmlnaHRdIFNwZWNpZnkgaXRlcmF0aW5nIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGJhc2UgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJhc2VGb3IoZnJvbVJpZ2h0KSB7XG4gIHJldHVybiBmdW5jdGlvbihvYmplY3QsIGl0ZXJhdGVlLCBrZXlzRnVuYykge1xuICAgIHZhciBpdGVyYWJsZSA9IHRvT2JqZWN0KG9iamVjdCksXG4gICAgICAgIHByb3BzID0ga2V5c0Z1bmMob2JqZWN0KSxcbiAgICAgICAgbGVuZ3RoID0gcHJvcHMubGVuZ3RoLFxuICAgICAgICBpbmRleCA9IGZyb21SaWdodCA/IGxlbmd0aCA6IC0xO1xuXG4gICAgd2hpbGUgKChmcm9tUmlnaHQgPyBpbmRleC0tIDogKytpbmRleCA8IGxlbmd0aCkpIHtcbiAgICAgIHZhciBrZXkgPSBwcm9wc1tpbmRleF07XG4gICAgICBpZiAoaXRlcmF0ZWUoaXRlcmFibGVba2V5XSwga2V5LCBpdGVyYWJsZSkgPT09IGZhbHNlKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0O1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUJhc2VGb3I7XG4iLCJ2YXIgY3JlYXRlQ3RvcldyYXBwZXIgPSByZXF1aXJlKCcuL2NyZWF0ZUN0b3JXcmFwcGVyJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYGZ1bmNgIGFuZCBpbnZva2VzIGl0IHdpdGggdGhlIGB0aGlzYFxuICogYmluZGluZyBvZiBgdGhpc0FyZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGJpbmQuXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYm91bmQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJpbmRXcmFwcGVyKGZ1bmMsIHRoaXNBcmcpIHtcbiAgdmFyIEN0b3IgPSBjcmVhdGVDdG9yV3JhcHBlcihmdW5jKTtcblxuICBmdW5jdGlvbiB3cmFwcGVyKCkge1xuICAgIHZhciBmbiA9ICh0aGlzICYmIHRoaXMgIT09IGdsb2JhbCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikgPyBDdG9yIDogZnVuYztcbiAgICByZXR1cm4gZm4uYXBwbHkodGhpc0FyZywgYXJndW1lbnRzKTtcbiAgfVxuICByZXR1cm4gd3JhcHBlcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVCaW5kV3JhcHBlcjtcbiIsInZhciBiYXNlQ3JlYXRlID0gcmVxdWlyZSgnLi9iYXNlQ3JlYXRlJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcHJvZHVjZXMgYW4gaW5zdGFuY2Ugb2YgYEN0b3JgIHJlZ2FyZGxlc3Mgb2ZcbiAqIHdoZXRoZXIgaXQgd2FzIGludm9rZWQgYXMgcGFydCBvZiBhIGBuZXdgIGV4cHJlc3Npb24gb3IgYnkgYGNhbGxgIG9yIGBhcHBseWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IEN0b3IgVGhlIGNvbnN0cnVjdG9yIHRvIHdyYXAuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVDdG9yV3JhcHBlcihDdG9yKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAvLyBVc2UgYSBgc3dpdGNoYCBzdGF0ZW1lbnQgdG8gd29yayB3aXRoIGNsYXNzIGNvbnN0cnVjdG9ycy5cbiAgICAvLyBTZWUgaHR0cHM6Ly9wZW9wbGUubW96aWxsYS5vcmcvfmpvcmVuZG9yZmYvZXM2LWRyYWZ0Lmh0bWwjc2VjLWVjbWFzY3JpcHQtZnVuY3Rpb24tb2JqZWN0cy1jYWxsLXRoaXNhcmd1bWVudC1hcmd1bWVudHNsaXN0XG4gICAgLy8gZm9yIG1vcmUgZGV0YWlscy5cbiAgICB2YXIgYXJncyA9IGFyZ3VtZW50cztcbiAgICBzd2l0Y2ggKGFyZ3MubGVuZ3RoKSB7XG4gICAgICBjYXNlIDA6IHJldHVybiBuZXcgQ3RvcjtcbiAgICAgIGNhc2UgMTogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0pO1xuICAgICAgY2FzZSAyOiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSwgYXJnc1sxXSk7XG4gICAgICBjYXNlIDM6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgIGNhc2UgNDogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10pO1xuICAgICAgY2FzZSA1OiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSwgYXJnc1s0XSk7XG4gICAgfVxuICAgIHZhciB0aGlzQmluZGluZyA9IGJhc2VDcmVhdGUoQ3Rvci5wcm90b3R5cGUpLFxuICAgICAgICByZXN1bHQgPSBDdG9yLmFwcGx5KHRoaXNCaW5kaW5nLCBhcmdzKTtcblxuICAgIC8vIE1pbWljIHRoZSBjb25zdHJ1Y3RvcidzIGByZXR1cm5gIGJlaGF2aW9yLlxuICAgIC8vIFNlZSBodHRwczovL2VzNS5naXRodWIuaW8vI3gxMy4yLjIgZm9yIG1vcmUgZGV0YWlscy5cbiAgICByZXR1cm4gaXNPYmplY3QocmVzdWx0KSA/IHJlc3VsdCA6IHRoaXNCaW5kaW5nO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUN0b3JXcmFwcGVyO1xuIiwidmFyIGJhc2VDYWxsYmFjayA9IHJlcXVpcmUoJy4vYmFzZUNhbGxiYWNrJyksXG4gICAgYmFzZUZpbmQgPSByZXF1aXJlKCcuL2Jhc2VGaW5kJyksXG4gICAgYmFzZUZpbmRJbmRleCA9IHJlcXVpcmUoJy4vYmFzZUZpbmRJbmRleCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgYF8uZmluZGAgb3IgYF8uZmluZExhc3RgIGZ1bmN0aW9uLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBlYWNoRnVuYyBUaGUgZnVuY3Rpb24gdG8gaXRlcmF0ZSBvdmVyIGEgY29sbGVjdGlvbi5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZmluZCBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlRmluZChlYWNoRnVuYywgZnJvbVJpZ2h0KSB7XG4gIHJldHVybiBmdW5jdGlvbihjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIHRoaXNBcmcpIHtcbiAgICBwcmVkaWNhdGUgPSBiYXNlQ2FsbGJhY2socHJlZGljYXRlLCB0aGlzQXJnLCAzKTtcbiAgICBpZiAoaXNBcnJheShjb2xsZWN0aW9uKSkge1xuICAgICAgdmFyIGluZGV4ID0gYmFzZUZpbmRJbmRleChjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIGZyb21SaWdodCk7XG4gICAgICByZXR1cm4gaW5kZXggPiAtMSA/IGNvbGxlY3Rpb25baW5kZXhdIDogdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4gYmFzZUZpbmQoY29sbGVjdGlvbiwgcHJlZGljYXRlLCBlYWNoRnVuYyk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlRmluZDtcbiIsInZhciBiaW5kQ2FsbGJhY2sgPSByZXF1aXJlKCcuL2JpbmRDYWxsYmFjaycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gZm9yIGBfLmZvckVhY2hgIG9yIGBfLmZvckVhY2hSaWdodGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGFycmF5RnVuYyBUaGUgZnVuY3Rpb24gdG8gaXRlcmF0ZSBvdmVyIGFuIGFycmF5LlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZWFjaEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBhIGNvbGxlY3Rpb24uXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBlYWNoIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVGb3JFYWNoKGFycmF5RnVuYywgZWFjaEZ1bmMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGNvbGxlY3Rpb24sIGl0ZXJhdGVlLCB0aGlzQXJnKSB7XG4gICAgcmV0dXJuICh0eXBlb2YgaXRlcmF0ZWUgPT0gJ2Z1bmN0aW9uJyAmJiB0aGlzQXJnID09PSB1bmRlZmluZWQgJiYgaXNBcnJheShjb2xsZWN0aW9uKSlcbiAgICAgID8gYXJyYXlGdW5jKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKVxuICAgICAgOiBlYWNoRnVuYyhjb2xsZWN0aW9uLCBiaW5kQ2FsbGJhY2soaXRlcmF0ZWUsIHRoaXNBcmcsIDMpKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVGb3JFYWNoO1xuIiwidmFyIGFycmF5Q29weSA9IHJlcXVpcmUoJy4vYXJyYXlDb3B5JyksXG4gICAgY29tcG9zZUFyZ3MgPSByZXF1aXJlKCcuL2NvbXBvc2VBcmdzJyksXG4gICAgY29tcG9zZUFyZ3NSaWdodCA9IHJlcXVpcmUoJy4vY29tcG9zZUFyZ3NSaWdodCcpLFxuICAgIGNyZWF0ZUN0b3JXcmFwcGVyID0gcmVxdWlyZSgnLi9jcmVhdGVDdG9yV3JhcHBlcicpLFxuICAgIGlzTGF6aWFibGUgPSByZXF1aXJlKCcuL2lzTGF6aWFibGUnKSxcbiAgICByZW9yZGVyID0gcmVxdWlyZSgnLi9yZW9yZGVyJyksXG4gICAgcmVwbGFjZUhvbGRlcnMgPSByZXF1aXJlKCcuL3JlcGxhY2VIb2xkZXJzJyksXG4gICAgc2V0RGF0YSA9IHJlcXVpcmUoJy4vc2V0RGF0YScpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB3cmFwcGVyIG1ldGFkYXRhLiAqL1xudmFyIEJJTkRfRkxBRyA9IDEsXG4gICAgQklORF9LRVlfRkxBRyA9IDIsXG4gICAgQ1VSUllfQk9VTkRfRkxBRyA9IDQsXG4gICAgQ1VSUllfRkxBRyA9IDgsXG4gICAgQ1VSUllfUklHSFRfRkxBRyA9IDE2LFxuICAgIFBBUlRJQUxfRkxBRyA9IDMyLFxuICAgIFBBUlRJQUxfUklHSFRfRkxBRyA9IDY0LFxuICAgIEFSWV9GTEFHID0gMTI4O1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHdyYXBzIGBmdW5jYCBhbmQgaW52b2tlcyBpdCB3aXRoIG9wdGlvbmFsIGB0aGlzYFxuICogYmluZGluZyBvZiwgcGFydGlhbCBhcHBsaWNhdGlvbiwgYW5kIGN1cnJ5aW5nLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufHN0cmluZ30gZnVuYyBUaGUgZnVuY3Rpb24gb3IgbWV0aG9kIG5hbWUgdG8gcmVmZXJlbmNlLlxuICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgb2YgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcHBlcmAgZm9yIG1vcmUgZGV0YWlscy5cbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge0FycmF5fSBbcGFydGlhbHNdIFRoZSBhcmd1bWVudHMgdG8gcHJlcGVuZCB0byB0aG9zZSBwcm92aWRlZCB0byB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNdIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gKiBAcGFyYW0ge0FycmF5fSBbcGFydGlhbHNSaWdodF0gVGhlIGFyZ3VtZW50cyB0byBhcHBlbmQgdG8gdGhvc2UgcHJvdmlkZWQgdG8gdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7QXJyYXl9IFtob2xkZXJzUmlnaHRdIFRoZSBgcGFydGlhbHNSaWdodGAgcGxhY2Vob2xkZXIgaW5kZXhlcy5cbiAqIEBwYXJhbSB7QXJyYXl9IFthcmdQb3NdIFRoZSBhcmd1bWVudCBwb3NpdGlvbnMgb2YgdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJ5XSBUaGUgYXJpdHkgY2FwIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJpdHldIFRoZSBhcml0eSBvZiBgZnVuY2AuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVIeWJyaWRXcmFwcGVyKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzLCBwYXJ0aWFsc1JpZ2h0LCBob2xkZXJzUmlnaHQsIGFyZ1BvcywgYXJ5LCBhcml0eSkge1xuICB2YXIgaXNBcnkgPSBiaXRtYXNrICYgQVJZX0ZMQUcsXG4gICAgICBpc0JpbmQgPSBiaXRtYXNrICYgQklORF9GTEFHLFxuICAgICAgaXNCaW5kS2V5ID0gYml0bWFzayAmIEJJTkRfS0VZX0ZMQUcsXG4gICAgICBpc0N1cnJ5ID0gYml0bWFzayAmIENVUlJZX0ZMQUcsXG4gICAgICBpc0N1cnJ5Qm91bmQgPSBiaXRtYXNrICYgQ1VSUllfQk9VTkRfRkxBRyxcbiAgICAgIGlzQ3VycnlSaWdodCA9IGJpdG1hc2sgJiBDVVJSWV9SSUdIVF9GTEFHLFxuICAgICAgQ3RvciA9IGlzQmluZEtleSA/IG51bGwgOiBjcmVhdGVDdG9yV3JhcHBlcihmdW5jKTtcblxuICBmdW5jdGlvbiB3cmFwcGVyKCkge1xuICAgIC8vIEF2b2lkIGBhcmd1bWVudHNgIG9iamVjdCB1c2UgZGlzcXVhbGlmeWluZyBvcHRpbWl6YXRpb25zIGJ5XG4gICAgLy8gY29udmVydGluZyBpdCB0byBhbiBhcnJheSBiZWZvcmUgcHJvdmlkaW5nIGl0IHRvIG90aGVyIGZ1bmN0aW9ucy5cbiAgICB2YXIgbGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aCxcbiAgICAgICAgaW5kZXggPSBsZW5ndGgsXG4gICAgICAgIGFyZ3MgPSBBcnJheShsZW5ndGgpO1xuXG4gICAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICAgIGFyZ3NbaW5kZXhdID0gYXJndW1lbnRzW2luZGV4XTtcbiAgICB9XG4gICAgaWYgKHBhcnRpYWxzKSB7XG4gICAgICBhcmdzID0gY29tcG9zZUFyZ3MoYXJncywgcGFydGlhbHMsIGhvbGRlcnMpO1xuICAgIH1cbiAgICBpZiAocGFydGlhbHNSaWdodCkge1xuICAgICAgYXJncyA9IGNvbXBvc2VBcmdzUmlnaHQoYXJncywgcGFydGlhbHNSaWdodCwgaG9sZGVyc1JpZ2h0KTtcbiAgICB9XG4gICAgaWYgKGlzQ3VycnkgfHwgaXNDdXJyeVJpZ2h0KSB7XG4gICAgICB2YXIgcGxhY2Vob2xkZXIgPSB3cmFwcGVyLnBsYWNlaG9sZGVyLFxuICAgICAgICAgIGFyZ3NIb2xkZXJzID0gcmVwbGFjZUhvbGRlcnMoYXJncywgcGxhY2Vob2xkZXIpO1xuXG4gICAgICBsZW5ndGggLT0gYXJnc0hvbGRlcnMubGVuZ3RoO1xuICAgICAgaWYgKGxlbmd0aCA8IGFyaXR5KSB7XG4gICAgICAgIHZhciBuZXdBcmdQb3MgPSBhcmdQb3MgPyBhcnJheUNvcHkoYXJnUG9zKSA6IG51bGwsXG4gICAgICAgICAgICBuZXdBcml0eSA9IG5hdGl2ZU1heChhcml0eSAtIGxlbmd0aCwgMCksXG4gICAgICAgICAgICBuZXdzSG9sZGVycyA9IGlzQ3VycnkgPyBhcmdzSG9sZGVycyA6IG51bGwsXG4gICAgICAgICAgICBuZXdIb2xkZXJzUmlnaHQgPSBpc0N1cnJ5ID8gbnVsbCA6IGFyZ3NIb2xkZXJzLFxuICAgICAgICAgICAgbmV3UGFydGlhbHMgPSBpc0N1cnJ5ID8gYXJncyA6IG51bGwsXG4gICAgICAgICAgICBuZXdQYXJ0aWFsc1JpZ2h0ID0gaXNDdXJyeSA/IG51bGwgOiBhcmdzO1xuXG4gICAgICAgIGJpdG1hc2sgfD0gKGlzQ3VycnkgPyBQQVJUSUFMX0ZMQUcgOiBQQVJUSUFMX1JJR0hUX0ZMQUcpO1xuICAgICAgICBiaXRtYXNrICY9IH4oaXNDdXJyeSA/IFBBUlRJQUxfUklHSFRfRkxBRyA6IFBBUlRJQUxfRkxBRyk7XG5cbiAgICAgICAgaWYgKCFpc0N1cnJ5Qm91bmQpIHtcbiAgICAgICAgICBiaXRtYXNrICY9IH4oQklORF9GTEFHIHwgQklORF9LRVlfRkxBRyk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIG5ld0RhdGEgPSBbZnVuYywgYml0bWFzaywgdGhpc0FyZywgbmV3UGFydGlhbHMsIG5ld3NIb2xkZXJzLCBuZXdQYXJ0aWFsc1JpZ2h0LCBuZXdIb2xkZXJzUmlnaHQsIG5ld0FyZ1BvcywgYXJ5LCBuZXdBcml0eV0sXG4gICAgICAgICAgICByZXN1bHQgPSBjcmVhdGVIeWJyaWRXcmFwcGVyLmFwcGx5KHVuZGVmaW5lZCwgbmV3RGF0YSk7XG5cbiAgICAgICAgaWYgKGlzTGF6aWFibGUoZnVuYykpIHtcbiAgICAgICAgICBzZXREYXRhKHJlc3VsdCwgbmV3RGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzdWx0LnBsYWNlaG9sZGVyID0gcGxhY2Vob2xkZXI7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgfVxuICAgIHZhciB0aGlzQmluZGluZyA9IGlzQmluZCA/IHRoaXNBcmcgOiB0aGlzLFxuICAgICAgICBmbiA9IGlzQmluZEtleSA/IHRoaXNCaW5kaW5nW2Z1bmNdIDogZnVuYztcblxuICAgIGlmIChhcmdQb3MpIHtcbiAgICAgIGFyZ3MgPSByZW9yZGVyKGFyZ3MsIGFyZ1Bvcyk7XG4gICAgfVxuICAgIGlmIChpc0FyeSAmJiBhcnkgPCBhcmdzLmxlbmd0aCkge1xuICAgICAgYXJncy5sZW5ndGggPSBhcnk7XG4gICAgfVxuICAgIGlmICh0aGlzICYmIHRoaXMgIT09IGdsb2JhbCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikge1xuICAgICAgZm4gPSBDdG9yIHx8IGNyZWF0ZUN0b3JXcmFwcGVyKGZ1bmMpO1xuICAgIH1cbiAgICByZXR1cm4gZm4uYXBwbHkodGhpc0JpbmRpbmcsIGFyZ3MpO1xuICB9XG4gIHJldHVybiB3cmFwcGVyO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUh5YnJpZFdyYXBwZXI7XG4iLCJ2YXIgY3JlYXRlQ3RvcldyYXBwZXIgPSByZXF1aXJlKCcuL2NyZWF0ZUN0b3JXcmFwcGVyJyk7XG5cbi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHdyYXBwZXIgbWV0YWRhdGEuICovXG52YXIgQklORF9GTEFHID0gMTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCB3cmFwcyBgZnVuY2AgYW5kIGludm9rZXMgaXQgd2l0aCB0aGUgb3B0aW9uYWwgYHRoaXNgXG4gKiBiaW5kaW5nIG9mIGB0aGlzQXJnYCBhbmQgdGhlIGBwYXJ0aWFsc2AgcHJlcGVuZGVkIHRvIHRob3NlIHByb3ZpZGVkIHRvXG4gKiB0aGUgd3JhcHBlci5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcGFydGlhbGx5IGFwcGx5IGFyZ3VtZW50cyB0by5cbiAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIG9mIGZsYWdzLiBTZWUgYGNyZWF0ZVdyYXBwZXJgIGZvciBtb3JlIGRldGFpbHMuXG4gKiBAcGFyYW0geyp9IHRoaXNBcmcgVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7QXJyYXl9IHBhcnRpYWxzIFRoZSBhcmd1bWVudHMgdG8gcHJlcGVuZCB0byB0aG9zZSBwcm92aWRlZCB0byB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYm91bmQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZVBhcnRpYWxXcmFwcGVyKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzKSB7XG4gIHZhciBpc0JpbmQgPSBiaXRtYXNrICYgQklORF9GTEFHLFxuICAgICAgQ3RvciA9IGNyZWF0ZUN0b3JXcmFwcGVyKGZ1bmMpO1xuXG4gIGZ1bmN0aW9uIHdyYXBwZXIoKSB7XG4gICAgLy8gQXZvaWQgYGFyZ3VtZW50c2Agb2JqZWN0IHVzZSBkaXNxdWFsaWZ5aW5nIG9wdGltaXphdGlvbnMgYnlcbiAgICAvLyBjb252ZXJ0aW5nIGl0IHRvIGFuIGFycmF5IGJlZm9yZSBwcm92aWRpbmcgaXQgYGZ1bmNgLlxuICAgIHZhciBhcmdzSW5kZXggPSAtMSxcbiAgICAgICAgYXJnc0xlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGgsXG4gICAgICAgIGxlZnRJbmRleCA9IC0xLFxuICAgICAgICBsZWZ0TGVuZ3RoID0gcGFydGlhbHMubGVuZ3RoLFxuICAgICAgICBhcmdzID0gQXJyYXkoYXJnc0xlbmd0aCArIGxlZnRMZW5ndGgpO1xuXG4gICAgd2hpbGUgKCsrbGVmdEluZGV4IDwgbGVmdExlbmd0aCkge1xuICAgICAgYXJnc1tsZWZ0SW5kZXhdID0gcGFydGlhbHNbbGVmdEluZGV4XTtcbiAgICB9XG4gICAgd2hpbGUgKGFyZ3NMZW5ndGgtLSkge1xuICAgICAgYXJnc1tsZWZ0SW5kZXgrK10gPSBhcmd1bWVudHNbKythcmdzSW5kZXhdO1xuICAgIH1cbiAgICB2YXIgZm4gPSAodGhpcyAmJiB0aGlzICE9PSBnbG9iYWwgJiYgdGhpcyBpbnN0YW5jZW9mIHdyYXBwZXIpID8gQ3RvciA6IGZ1bmM7XG4gICAgcmV0dXJuIGZuLmFwcGx5KGlzQmluZCA/IHRoaXNBcmcgOiB0aGlzLCBhcmdzKTtcbiAgfVxuICByZXR1cm4gd3JhcHBlcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVQYXJ0aWFsV3JhcHBlcjtcbiIsInZhciBiYXNlU2V0RGF0YSA9IHJlcXVpcmUoJy4vYmFzZVNldERhdGEnKSxcbiAgICBjcmVhdGVCaW5kV3JhcHBlciA9IHJlcXVpcmUoJy4vY3JlYXRlQmluZFdyYXBwZXInKSxcbiAgICBjcmVhdGVIeWJyaWRXcmFwcGVyID0gcmVxdWlyZSgnLi9jcmVhdGVIeWJyaWRXcmFwcGVyJyksXG4gICAgY3JlYXRlUGFydGlhbFdyYXBwZXIgPSByZXF1aXJlKCcuL2NyZWF0ZVBhcnRpYWxXcmFwcGVyJyksXG4gICAgZ2V0RGF0YSA9IHJlcXVpcmUoJy4vZ2V0RGF0YScpLFxuICAgIG1lcmdlRGF0YSA9IHJlcXVpcmUoJy4vbWVyZ2VEYXRhJyksXG4gICAgc2V0RGF0YSA9IHJlcXVpcmUoJy4vc2V0RGF0YScpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB3cmFwcGVyIG1ldGFkYXRhLiAqL1xudmFyIEJJTkRfRkxBRyA9IDEsXG4gICAgQklORF9LRVlfRkxBRyA9IDIsXG4gICAgUEFSVElBTF9GTEFHID0gMzIsXG4gICAgUEFSVElBTF9SSUdIVF9GTEFHID0gNjQ7XG5cbi8qKiBVc2VkIGFzIHRoZSBgVHlwZUVycm9yYCBtZXNzYWdlIGZvciBcIkZ1bmN0aW9uc1wiIG1ldGhvZHMuICovXG52YXIgRlVOQ19FUlJPUl9URVhUID0gJ0V4cGVjdGVkIGEgZnVuY3Rpb24nO1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGVpdGhlciBjdXJyaWVzIG9yIGludm9rZXMgYGZ1bmNgIHdpdGggb3B0aW9uYWxcbiAqIGB0aGlzYCBiaW5kaW5nIGFuZCBwYXJ0aWFsbHkgYXBwbGllZCBhcmd1bWVudHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb258c3RyaW5nfSBmdW5jIFRoZSBmdW5jdGlvbiBvciBtZXRob2QgbmFtZSB0byByZWZlcmVuY2UuXG4gKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBvZiBmbGFncy5cbiAqICBUaGUgYml0bWFzayBtYXkgYmUgY29tcG9zZWQgb2YgdGhlIGZvbGxvd2luZyBmbGFnczpcbiAqICAgICAxIC0gYF8uYmluZGBcbiAqICAgICAyIC0gYF8uYmluZEtleWBcbiAqICAgICA0IC0gYF8uY3VycnlgIG9yIGBfLmN1cnJ5UmlnaHRgIG9mIGEgYm91bmQgZnVuY3Rpb25cbiAqICAgICA4IC0gYF8uY3VycnlgXG4gKiAgICAxNiAtIGBfLmN1cnJ5UmlnaHRgXG4gKiAgICAzMiAtIGBfLnBhcnRpYWxgXG4gKiAgICA2NCAtIGBfLnBhcnRpYWxSaWdodGBcbiAqICAgMTI4IC0gYF8ucmVhcmdgXG4gKiAgIDI1NiAtIGBfLmFyeWBcbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge0FycmF5fSBbcGFydGlhbHNdIFRoZSBhcmd1bWVudHMgdG8gYmUgcGFydGlhbGx5IGFwcGxpZWQuXG4gKiBAcGFyYW0ge0FycmF5fSBbaG9sZGVyc10gVGhlIGBwYXJ0aWFsc2AgcGxhY2Vob2xkZXIgaW5kZXhlcy5cbiAqIEBwYXJhbSB7QXJyYXl9IFthcmdQb3NdIFRoZSBhcmd1bWVudCBwb3NpdGlvbnMgb2YgdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJ5XSBUaGUgYXJpdHkgY2FwIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJpdHldIFRoZSBhcml0eSBvZiBgZnVuY2AuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVXcmFwcGVyKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzLCBhcmdQb3MsIGFyeSwgYXJpdHkpIHtcbiAgdmFyIGlzQmluZEtleSA9IGJpdG1hc2sgJiBCSU5EX0tFWV9GTEFHO1xuICBpZiAoIWlzQmluZEtleSAmJiB0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICB9XG4gIHZhciBsZW5ndGggPSBwYXJ0aWFscyA/IHBhcnRpYWxzLmxlbmd0aCA6IDA7XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgYml0bWFzayAmPSB+KFBBUlRJQUxfRkxBRyB8IFBBUlRJQUxfUklHSFRfRkxBRyk7XG4gICAgcGFydGlhbHMgPSBob2xkZXJzID0gbnVsbDtcbiAgfVxuICBsZW5ndGggLT0gKGhvbGRlcnMgPyBob2xkZXJzLmxlbmd0aCA6IDApO1xuICBpZiAoYml0bWFzayAmIFBBUlRJQUxfUklHSFRfRkxBRykge1xuICAgIHZhciBwYXJ0aWFsc1JpZ2h0ID0gcGFydGlhbHMsXG4gICAgICAgIGhvbGRlcnNSaWdodCA9IGhvbGRlcnM7XG5cbiAgICBwYXJ0aWFscyA9IGhvbGRlcnMgPSBudWxsO1xuICB9XG4gIHZhciBkYXRhID0gaXNCaW5kS2V5ID8gbnVsbCA6IGdldERhdGEoZnVuYyksXG4gICAgICBuZXdEYXRhID0gW2Z1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzLCBwYXJ0aWFsc1JpZ2h0LCBob2xkZXJzUmlnaHQsIGFyZ1BvcywgYXJ5LCBhcml0eV07XG5cbiAgaWYgKGRhdGEpIHtcbiAgICBtZXJnZURhdGEobmV3RGF0YSwgZGF0YSk7XG4gICAgYml0bWFzayA9IG5ld0RhdGFbMV07XG4gICAgYXJpdHkgPSBuZXdEYXRhWzldO1xuICB9XG4gIG5ld0RhdGFbOV0gPSBhcml0eSA9PSBudWxsXG4gICAgPyAoaXNCaW5kS2V5ID8gMCA6IGZ1bmMubGVuZ3RoKVxuICAgIDogKG5hdGl2ZU1heChhcml0eSAtIGxlbmd0aCwgMCkgfHwgMCk7XG5cbiAgaWYgKGJpdG1hc2sgPT0gQklORF9GTEFHKSB7XG4gICAgdmFyIHJlc3VsdCA9IGNyZWF0ZUJpbmRXcmFwcGVyKG5ld0RhdGFbMF0sIG5ld0RhdGFbMl0pO1xuICB9IGVsc2UgaWYgKChiaXRtYXNrID09IFBBUlRJQUxfRkxBRyB8fCBiaXRtYXNrID09IChCSU5EX0ZMQUcgfCBQQVJUSUFMX0ZMQUcpKSAmJiAhbmV3RGF0YVs0XS5sZW5ndGgpIHtcbiAgICByZXN1bHQgPSBjcmVhdGVQYXJ0aWFsV3JhcHBlci5hcHBseSh1bmRlZmluZWQsIG5ld0RhdGEpO1xuICB9IGVsc2Uge1xuICAgIHJlc3VsdCA9IGNyZWF0ZUh5YnJpZFdyYXBwZXIuYXBwbHkodW5kZWZpbmVkLCBuZXdEYXRhKTtcbiAgfVxuICB2YXIgc2V0dGVyID0gZGF0YSA/IGJhc2VTZXREYXRhIDogc2V0RGF0YTtcbiAgcmV0dXJuIHNldHRlcihyZXN1bHQsIG5ld0RhdGEpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZVdyYXBwZXI7XG4iLCJ2YXIgYXJyYXlTb21lID0gcmVxdWlyZSgnLi9hcnJheVNvbWUnKTtcblxuLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VJc0VxdWFsRGVlcGAgZm9yIGFycmF5cyB3aXRoIHN1cHBvcnQgZm9yXG4gKiBwYXJ0aWFsIGRlZXAgY29tcGFyaXNvbnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBjb21wYXJlLlxuICogQHBhcmFtIHtBcnJheX0gb3RoZXIgVGhlIG90aGVyIGFycmF5IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBlcXVhbEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRldGVybWluZSBlcXVpdmFsZW50cyBvZiB2YWx1ZXMuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpbmcgYXJyYXlzLlxuICogQHBhcmFtIHtib29sZWFufSBbaXNMb29zZV0gU3BlY2lmeSBwZXJmb3JtaW5nIHBhcnRpYWwgY29tcGFyaXNvbnMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tBXSBUcmFja3MgdHJhdmVyc2VkIGB2YWx1ZWAgb2JqZWN0cy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0JdIFRyYWNrcyB0cmF2ZXJzZWQgYG90aGVyYCBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBhcnJheXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gZXF1YWxBcnJheXMoYXJyYXksIG90aGVyLCBlcXVhbEZ1bmMsIGN1c3RvbWl6ZXIsIGlzTG9vc2UsIHN0YWNrQSwgc3RhY2tCKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgYXJyTGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgb3RoTGVuZ3RoID0gb3RoZXIubGVuZ3RoO1xuXG4gIGlmIChhcnJMZW5ndGggIT0gb3RoTGVuZ3RoICYmICEoaXNMb29zZSAmJiBvdGhMZW5ndGggPiBhcnJMZW5ndGgpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIC8vIElnbm9yZSBub24taW5kZXggcHJvcGVydGllcy5cbiAgd2hpbGUgKCsraW5kZXggPCBhcnJMZW5ndGgpIHtcbiAgICB2YXIgYXJyVmFsdWUgPSBhcnJheVtpbmRleF0sXG4gICAgICAgIG90aFZhbHVlID0gb3RoZXJbaW5kZXhdLFxuICAgICAgICByZXN1bHQgPSBjdXN0b21pemVyID8gY3VzdG9taXplcihpc0xvb3NlID8gb3RoVmFsdWUgOiBhcnJWYWx1ZSwgaXNMb29zZSA/IGFyclZhbHVlIDogb3RoVmFsdWUsIGluZGV4KSA6IHVuZGVmaW5lZDtcblxuICAgIGlmIChyZXN1bHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgLy8gUmVjdXJzaXZlbHkgY29tcGFyZSBhcnJheXMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgICBpZiAoaXNMb29zZSkge1xuICAgICAgaWYgKCFhcnJheVNvbWUob3RoZXIsIGZ1bmN0aW9uKG90aFZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm4gYXJyVmFsdWUgPT09IG90aFZhbHVlIHx8IGVxdWFsRnVuYyhhcnJWYWx1ZSwgb3RoVmFsdWUsIGN1c3RvbWl6ZXIsIGlzTG9vc2UsIHN0YWNrQSwgc3RhY2tCKTtcbiAgICAgICAgICB9KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICghKGFyclZhbHVlID09PSBvdGhWYWx1ZSB8fCBlcXVhbEZ1bmMoYXJyVmFsdWUsIG90aFZhbHVlLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQikpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGVxdWFsQXJyYXlzO1xuIiwiLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGJvb2xUYWcgPSAnW29iamVjdCBCb29sZWFuXScsXG4gICAgZGF0ZVRhZyA9ICdbb2JqZWN0IERhdGVdJyxcbiAgICBlcnJvclRhZyA9ICdbb2JqZWN0IEVycm9yXScsXG4gICAgbnVtYmVyVGFnID0gJ1tvYmplY3QgTnVtYmVyXScsXG4gICAgcmVnZXhwVGFnID0gJ1tvYmplY3QgUmVnRXhwXScsXG4gICAgc3RyaW5nVGFnID0gJ1tvYmplY3QgU3RyaW5nXSc7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbERlZXBgIGZvciBjb21wYXJpbmcgb2JqZWN0cyBvZlxuICogdGhlIHNhbWUgYHRvU3RyaW5nVGFnYC5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBvbmx5IHN1cHBvcnRzIGNvbXBhcmluZyB2YWx1ZXMgd2l0aCB0YWdzIG9mXG4gKiBgQm9vbGVhbmAsIGBEYXRlYCwgYEVycm9yYCwgYE51bWJlcmAsIGBSZWdFeHBgLCBvciBgU3RyaW5nYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHZhbHVlIFRoZSBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvdGhlciBUaGUgb3RoZXIgb2JqZWN0IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge3N0cmluZ30gdGFnIFRoZSBgdG9TdHJpbmdUYWdgIG9mIHRoZSBvYmplY3RzIHRvIGNvbXBhcmUuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gZXF1YWxCeVRhZyhvYmplY3QsIG90aGVyLCB0YWcpIHtcbiAgc3dpdGNoICh0YWcpIHtcbiAgICBjYXNlIGJvb2xUYWc6XG4gICAgY2FzZSBkYXRlVGFnOlxuICAgICAgLy8gQ29lcmNlIGRhdGVzIGFuZCBib29sZWFucyB0byBudW1iZXJzLCBkYXRlcyB0byBtaWxsaXNlY29uZHMgYW5kIGJvb2xlYW5zXG4gICAgICAvLyB0byBgMWAgb3IgYDBgIHRyZWF0aW5nIGludmFsaWQgZGF0ZXMgY29lcmNlZCB0byBgTmFOYCBhcyBub3QgZXF1YWwuXG4gICAgICByZXR1cm4gK29iamVjdCA9PSArb3RoZXI7XG5cbiAgICBjYXNlIGVycm9yVGFnOlxuICAgICAgcmV0dXJuIG9iamVjdC5uYW1lID09IG90aGVyLm5hbWUgJiYgb2JqZWN0Lm1lc3NhZ2UgPT0gb3RoZXIubWVzc2FnZTtcblxuICAgIGNhc2UgbnVtYmVyVGFnOlxuICAgICAgLy8gVHJlYXQgYE5hTmAgdnMuIGBOYU5gIGFzIGVxdWFsLlxuICAgICAgcmV0dXJuIChvYmplY3QgIT0gK29iamVjdClcbiAgICAgICAgPyBvdGhlciAhPSArb3RoZXJcbiAgICAgICAgOiBvYmplY3QgPT0gK290aGVyO1xuXG4gICAgY2FzZSByZWdleHBUYWc6XG4gICAgY2FzZSBzdHJpbmdUYWc6XG4gICAgICAvLyBDb2VyY2UgcmVnZXhlcyB0byBzdHJpbmdzIGFuZCB0cmVhdCBzdHJpbmdzIHByaW1pdGl2ZXMgYW5kIHN0cmluZ1xuICAgICAgLy8gb2JqZWN0cyBhcyBlcXVhbC4gU2VlIGh0dHBzOi8vZXM1LmdpdGh1Yi5pby8jeDE1LjEwLjYuNCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAgcmV0dXJuIG9iamVjdCA9PSAob3RoZXIgKyAnJyk7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGVxdWFsQnlUYWc7XG4iLCJ2YXIga2V5cyA9IHJlcXVpcmUoJy4uL29iamVjdC9rZXlzJyk7XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxEZWVwYCBmb3Igb2JqZWN0cyB3aXRoIHN1cHBvcnQgZm9yXG4gKiBwYXJ0aWFsIGRlZXAgY29tcGFyaXNvbnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtPYmplY3R9IG90aGVyIFRoZSBvdGhlciBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGVxdWFsRnVuYyBUaGUgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIGVxdWl2YWxlbnRzIG9mIHZhbHVlcy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmluZyB2YWx1ZXMuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0xvb3NlXSBTcGVjaWZ5IHBlcmZvcm1pbmcgcGFydGlhbCBjb21wYXJpc29ucy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0FdIFRyYWNrcyB0cmF2ZXJzZWQgYHZhbHVlYCBvYmplY3RzLlxuICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQl0gVHJhY2tzIHRyYXZlcnNlZCBgb3RoZXJgIG9iamVjdHMuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gZXF1YWxPYmplY3RzKG9iamVjdCwgb3RoZXIsIGVxdWFsRnVuYywgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpIHtcbiAgdmFyIG9ialByb3BzID0ga2V5cyhvYmplY3QpLFxuICAgICAgb2JqTGVuZ3RoID0gb2JqUHJvcHMubGVuZ3RoLFxuICAgICAgb3RoUHJvcHMgPSBrZXlzKG90aGVyKSxcbiAgICAgIG90aExlbmd0aCA9IG90aFByb3BzLmxlbmd0aDtcblxuICBpZiAob2JqTGVuZ3RoICE9IG90aExlbmd0aCAmJiAhaXNMb29zZSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB2YXIgaW5kZXggPSBvYmpMZW5ndGg7XG4gIHdoaWxlIChpbmRleC0tKSB7XG4gICAgdmFyIGtleSA9IG9ialByb3BzW2luZGV4XTtcbiAgICBpZiAoIShpc0xvb3NlID8ga2V5IGluIG90aGVyIDogaGFzT3duUHJvcGVydHkuY2FsbChvdGhlciwga2V5KSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgdmFyIHNraXBDdG9yID0gaXNMb29zZTtcbiAgd2hpbGUgKCsraW5kZXggPCBvYmpMZW5ndGgpIHtcbiAgICBrZXkgPSBvYmpQcm9wc1tpbmRleF07XG4gICAgdmFyIG9ialZhbHVlID0gb2JqZWN0W2tleV0sXG4gICAgICAgIG90aFZhbHVlID0gb3RoZXJba2V5XSxcbiAgICAgICAgcmVzdWx0ID0gY3VzdG9taXplciA/IGN1c3RvbWl6ZXIoaXNMb29zZSA/IG90aFZhbHVlIDogb2JqVmFsdWUsIGlzTG9vc2U/IG9ialZhbHVlIDogb3RoVmFsdWUsIGtleSkgOiB1bmRlZmluZWQ7XG5cbiAgICAvLyBSZWN1cnNpdmVseSBjb21wYXJlIG9iamVjdHMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgICBpZiAoIShyZXN1bHQgPT09IHVuZGVmaW5lZCA/IGVxdWFsRnVuYyhvYmpWYWx1ZSwgb3RoVmFsdWUsIGN1c3RvbWl6ZXIsIGlzTG9vc2UsIHN0YWNrQSwgc3RhY2tCKSA6IHJlc3VsdCkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgc2tpcEN0b3IgfHwgKHNraXBDdG9yID0ga2V5ID09ICdjb25zdHJ1Y3RvcicpO1xuICB9XG4gIGlmICghc2tpcEN0b3IpIHtcbiAgICB2YXIgb2JqQ3RvciA9IG9iamVjdC5jb25zdHJ1Y3RvcixcbiAgICAgICAgb3RoQ3RvciA9IG90aGVyLmNvbnN0cnVjdG9yO1xuXG4gICAgLy8gTm9uIGBPYmplY3RgIG9iamVjdCBpbnN0YW5jZXMgd2l0aCBkaWZmZXJlbnQgY29uc3RydWN0b3JzIGFyZSBub3QgZXF1YWwuXG4gICAgaWYgKG9iakN0b3IgIT0gb3RoQ3RvciAmJlxuICAgICAgICAoJ2NvbnN0cnVjdG9yJyBpbiBvYmplY3QgJiYgJ2NvbnN0cnVjdG9yJyBpbiBvdGhlcikgJiZcbiAgICAgICAgISh0eXBlb2Ygb2JqQ3RvciA9PSAnZnVuY3Rpb24nICYmIG9iakN0b3IgaW5zdGFuY2VvZiBvYmpDdG9yICYmXG4gICAgICAgICAgdHlwZW9mIG90aEN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBvdGhDdG9yIGluc3RhbmNlb2Ygb3RoQ3RvcikpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZXF1YWxPYmplY3RzO1xuIiwidmFyIG1ldGFNYXAgPSByZXF1aXJlKCcuL21ldGFNYXAnKSxcbiAgICBub29wID0gcmVxdWlyZSgnLi4vdXRpbGl0eS9ub29wJyk7XG5cbi8qKlxuICogR2V0cyBtZXRhZGF0YSBmb3IgYGZ1bmNgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBtZXRhZGF0YSBmb3IgYGZ1bmNgLlxuICovXG52YXIgZ2V0RGF0YSA9ICFtZXRhTWFwID8gbm9vcCA6IGZ1bmN0aW9uKGZ1bmMpIHtcbiAgcmV0dXJuIG1ldGFNYXAuZ2V0KGZ1bmMpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBnZXREYXRhO1xuIiwidmFyIHJlYWxOYW1lcyA9IHJlcXVpcmUoJy4vcmVhbE5hbWVzJyk7XG5cbi8qKlxuICogR2V0cyB0aGUgbmFtZSBvZiBgZnVuY2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHF1ZXJ5LlxuICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgZnVuY3Rpb24gbmFtZS5cbiAqL1xuZnVuY3Rpb24gZ2V0RnVuY05hbWUoZnVuYykge1xuICB2YXIgcmVzdWx0ID0gZnVuYy5uYW1lLFxuICAgICAgYXJyYXkgPSByZWFsTmFtZXNbcmVzdWx0XSxcbiAgICAgIGxlbmd0aCA9IGFycmF5ID8gYXJyYXkubGVuZ3RoIDogMDtcblxuICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICB2YXIgZGF0YSA9IGFycmF5W2xlbmd0aF0sXG4gICAgICAgIG90aGVyRnVuYyA9IGRhdGEuZnVuYztcbiAgICBpZiAob3RoZXJGdW5jID09IG51bGwgfHwgb3RoZXJGdW5jID09IGZ1bmMpIHtcbiAgICAgIHJldHVybiBkYXRhLm5hbWU7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0RnVuY05hbWU7XG4iLCJ2YXIgYmFzZVByb3BlcnR5ID0gcmVxdWlyZSgnLi9iYXNlUHJvcGVydHknKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBcImxlbmd0aFwiIHByb3BlcnR5IHZhbHVlIG9mIGBvYmplY3RgLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gYXZvaWQgYSBbSklUIGJ1Z10oaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTE0Mjc5MilcbiAqIHRoYXQgYWZmZWN0cyBTYWZhcmkgb24gYXQgbGVhc3QgaU9TIDguMS04LjMgQVJNNjQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBcImxlbmd0aFwiIHZhbHVlLlxuICovXG52YXIgZ2V0TGVuZ3RoID0gYmFzZVByb3BlcnR5KCdsZW5ndGgnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBnZXRMZW5ndGg7XG4iLCJ2YXIgaXNTdHJpY3RDb21wYXJhYmxlID0gcmVxdWlyZSgnLi9pc1N0cmljdENvbXBhcmFibGUnKSxcbiAgICBwYWlycyA9IHJlcXVpcmUoJy4uL29iamVjdC9wYWlycycpO1xuXG4vKipcbiAqIEdldHMgdGhlIHByb3BlcnkgbmFtZXMsIHZhbHVlcywgYW5kIGNvbXBhcmUgZmxhZ3Mgb2YgYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbWF0Y2ggZGF0YSBvZiBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gZ2V0TWF0Y2hEYXRhKG9iamVjdCkge1xuICB2YXIgcmVzdWx0ID0gcGFpcnMob2JqZWN0KSxcbiAgICAgIGxlbmd0aCA9IHJlc3VsdC5sZW5ndGg7XG5cbiAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgcmVzdWx0W2xlbmd0aF1bMl0gPSBpc1N0cmljdENvbXBhcmFibGUocmVzdWx0W2xlbmd0aF1bMV0pO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0TWF0Y2hEYXRhO1xuIiwidmFyIGlzTmF0aXZlID0gcmVxdWlyZSgnLi4vbGFuZy9pc05hdGl2ZScpO1xuXG4vKipcbiAqIEdldHMgdGhlIG5hdGl2ZSBmdW5jdGlvbiBhdCBga2V5YCBvZiBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBtZXRob2QgdG8gZ2V0LlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGZ1bmN0aW9uIGlmIGl0J3MgbmF0aXZlLCBlbHNlIGB1bmRlZmluZWRgLlxuICovXG5mdW5jdGlvbiBnZXROYXRpdmUob2JqZWN0LCBrZXkpIHtcbiAgdmFyIHZhbHVlID0gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBvYmplY3Rba2V5XTtcbiAgcmV0dXJuIGlzTmF0aXZlKHZhbHVlKSA/IHZhbHVlIDogdW5kZWZpbmVkO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldE5hdGl2ZTtcbiIsIi8qKlxuICogR2V0cyB0aGUgaW5kZXggYXQgd2hpY2ggdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgYE5hTmAgaXMgZm91bmQgaW4gYGFycmF5YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNlYXJjaC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBmcm9tSW5kZXggVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCBgTmFOYCwgZWxzZSBgLTFgLlxuICovXG5mdW5jdGlvbiBpbmRleE9mTmFOKGFycmF5LCBmcm9tSW5kZXgsIGZyb21SaWdodCkge1xuICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgaW5kZXggPSBmcm9tSW5kZXggKyAoZnJvbVJpZ2h0ID8gMCA6IC0xKTtcblxuICB3aGlsZSAoKGZyb21SaWdodCA/IGluZGV4LS0gOiArK2luZGV4IDwgbGVuZ3RoKSkge1xuICAgIHZhciBvdGhlciA9IGFycmF5W2luZGV4XTtcbiAgICBpZiAob3RoZXIgIT09IG90aGVyKSB7XG4gICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuICB9XG4gIHJldHVybiAtMTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpbmRleE9mTmFOO1xuIiwiLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogSW5pdGlhbGl6ZXMgYW4gYXJyYXkgY2xvbmUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBjbG9uZS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgaW5pdGlhbGl6ZWQgY2xvbmUuXG4gKi9cbmZ1bmN0aW9uIGluaXRDbG9uZUFycmF5KGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBuZXcgYXJyYXkuY29uc3RydWN0b3IobGVuZ3RoKTtcblxuICAvLyBBZGQgYXJyYXkgcHJvcGVydGllcyBhc3NpZ25lZCBieSBgUmVnRXhwI2V4ZWNgLlxuICBpZiAobGVuZ3RoICYmIHR5cGVvZiBhcnJheVswXSA9PSAnc3RyaW5nJyAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKGFycmF5LCAnaW5kZXgnKSkge1xuICAgIHJlc3VsdC5pbmRleCA9IGFycmF5LmluZGV4O1xuICAgIHJlc3VsdC5pbnB1dCA9IGFycmF5LmlucHV0O1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaW5pdENsb25lQXJyYXk7XG4iLCJ2YXIgYnVmZmVyQ2xvbmUgPSByZXF1aXJlKCcuL2J1ZmZlckNsb25lJyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgbnVtYmVyVGFnID0gJ1tvYmplY3QgTnVtYmVyXScsXG4gICAgcmVnZXhwVGFnID0gJ1tvYmplY3QgUmVnRXhwXScsXG4gICAgc3RyaW5nVGFnID0gJ1tvYmplY3QgU3RyaW5nXSc7XG5cbnZhciBhcnJheUJ1ZmZlclRhZyA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsXG4gICAgZmxvYXQzMlRhZyA9ICdbb2JqZWN0IEZsb2F0MzJBcnJheV0nLFxuICAgIGZsb2F0NjRUYWcgPSAnW29iamVjdCBGbG9hdDY0QXJyYXldJyxcbiAgICBpbnQ4VGFnID0gJ1tvYmplY3QgSW50OEFycmF5XScsXG4gICAgaW50MTZUYWcgPSAnW29iamVjdCBJbnQxNkFycmF5XScsXG4gICAgaW50MzJUYWcgPSAnW29iamVjdCBJbnQzMkFycmF5XScsXG4gICAgdWludDhUYWcgPSAnW29iamVjdCBVaW50OEFycmF5XScsXG4gICAgdWludDhDbGFtcGVkVGFnID0gJ1tvYmplY3QgVWludDhDbGFtcGVkQXJyYXldJyxcbiAgICB1aW50MTZUYWcgPSAnW29iamVjdCBVaW50MTZBcnJheV0nLFxuICAgIHVpbnQzMlRhZyA9ICdbb2JqZWN0IFVpbnQzMkFycmF5XSc7XG5cbi8qKiBVc2VkIHRvIG1hdGNoIGBSZWdFeHBgIGZsYWdzIGZyb20gdGhlaXIgY29lcmNlZCBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlRmxhZ3MgPSAvXFx3KiQvO1xuXG4vKiogVXNlZCB0byBsb29rdXAgYSB0eXBlIGFycmF5IGNvbnN0cnVjdG9ycyBieSBgdG9TdHJpbmdUYWdgLiAqL1xudmFyIGN0b3JCeVRhZyA9IHt9O1xuY3RvckJ5VGFnW2Zsb2F0MzJUYWddID0gZ2xvYmFsLkZsb2F0MzJBcnJheTtcbmN0b3JCeVRhZ1tmbG9hdDY0VGFnXSA9IGdsb2JhbC5GbG9hdDY0QXJyYXk7XG5jdG9yQnlUYWdbaW50OFRhZ10gPSBnbG9iYWwuSW50OEFycmF5O1xuY3RvckJ5VGFnW2ludDE2VGFnXSA9IGdsb2JhbC5JbnQxNkFycmF5O1xuY3RvckJ5VGFnW2ludDMyVGFnXSA9IGdsb2JhbC5JbnQzMkFycmF5O1xuY3RvckJ5VGFnW3VpbnQ4VGFnXSA9IGdsb2JhbC5VaW50OEFycmF5O1xuY3RvckJ5VGFnW3VpbnQ4Q2xhbXBlZFRhZ10gPSBnbG9iYWwuVWludDhDbGFtcGVkQXJyYXk7XG5jdG9yQnlUYWdbdWludDE2VGFnXSA9IGdsb2JhbC5VaW50MTZBcnJheTtcbmN0b3JCeVRhZ1t1aW50MzJUYWddID0gZ2xvYmFsLlVpbnQzMkFycmF5O1xuXG4vKipcbiAqIEluaXRpYWxpemVzIGFuIG9iamVjdCBjbG9uZSBiYXNlZCBvbiBpdHMgYHRvU3RyaW5nVGFnYC5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBvbmx5IHN1cHBvcnRzIGNsb25pbmcgdmFsdWVzIHdpdGggdGFncyBvZlxuICogYEJvb2xlYW5gLCBgRGF0ZWAsIGBFcnJvcmAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgb3IgYFN0cmluZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjbG9uZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0YWcgVGhlIGB0b1N0cmluZ1RhZ2Agb2YgdGhlIG9iamVjdCB0byBjbG9uZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzRGVlcF0gU3BlY2lmeSBhIGRlZXAgY2xvbmUuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAqL1xuZnVuY3Rpb24gaW5pdENsb25lQnlUYWcob2JqZWN0LCB0YWcsIGlzRGVlcCkge1xuICB2YXIgQ3RvciA9IG9iamVjdC5jb25zdHJ1Y3RvcjtcbiAgc3dpdGNoICh0YWcpIHtcbiAgICBjYXNlIGFycmF5QnVmZmVyVGFnOlxuICAgICAgcmV0dXJuIGJ1ZmZlckNsb25lKG9iamVjdCk7XG5cbiAgICBjYXNlIGJvb2xUYWc6XG4gICAgY2FzZSBkYXRlVGFnOlxuICAgICAgcmV0dXJuIG5ldyBDdG9yKCtvYmplY3QpO1xuXG4gICAgY2FzZSBmbG9hdDMyVGFnOiBjYXNlIGZsb2F0NjRUYWc6XG4gICAgY2FzZSBpbnQ4VGFnOiBjYXNlIGludDE2VGFnOiBjYXNlIGludDMyVGFnOlxuICAgIGNhc2UgdWludDhUYWc6IGNhc2UgdWludDhDbGFtcGVkVGFnOiBjYXNlIHVpbnQxNlRhZzogY2FzZSB1aW50MzJUYWc6XG4gICAgICAvLyBTYWZhcmkgNSBtb2JpbGUgaW5jb3JyZWN0bHkgaGFzIGBPYmplY3RgIGFzIHRoZSBjb25zdHJ1Y3RvciBvZiB0eXBlZCBhcnJheXMuXG4gICAgICBpZiAoQ3RvciBpbnN0YW5jZW9mIEN0b3IpIHtcbiAgICAgICAgQ3RvciA9IGN0b3JCeVRhZ1t0YWddO1xuICAgICAgfVxuICAgICAgdmFyIGJ1ZmZlciA9IG9iamVjdC5idWZmZXI7XG4gICAgICByZXR1cm4gbmV3IEN0b3IoaXNEZWVwID8gYnVmZmVyQ2xvbmUoYnVmZmVyKSA6IGJ1ZmZlciwgb2JqZWN0LmJ5dGVPZmZzZXQsIG9iamVjdC5sZW5ndGgpO1xuXG4gICAgY2FzZSBudW1iZXJUYWc6XG4gICAgY2FzZSBzdHJpbmdUYWc6XG4gICAgICByZXR1cm4gbmV3IEN0b3Iob2JqZWN0KTtcblxuICAgIGNhc2UgcmVnZXhwVGFnOlxuICAgICAgdmFyIHJlc3VsdCA9IG5ldyBDdG9yKG9iamVjdC5zb3VyY2UsIHJlRmxhZ3MuZXhlYyhvYmplY3QpKTtcbiAgICAgIHJlc3VsdC5sYXN0SW5kZXggPSBvYmplY3QubGFzdEluZGV4O1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaW5pdENsb25lQnlUYWc7XG4iLCIvKipcbiAqIEluaXRpYWxpemVzIGFuIG9iamVjdCBjbG9uZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGNsb25lLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgaW5pdGlhbGl6ZWQgY2xvbmUuXG4gKi9cbmZ1bmN0aW9uIGluaXRDbG9uZU9iamVjdChvYmplY3QpIHtcbiAgdmFyIEN0b3IgPSBvYmplY3QuY29uc3RydWN0b3I7XG4gIGlmICghKHR5cGVvZiBDdG9yID09ICdmdW5jdGlvbicgJiYgQ3RvciBpbnN0YW5jZW9mIEN0b3IpKSB7XG4gICAgQ3RvciA9IE9iamVjdDtcbiAgfVxuICByZXR1cm4gbmV3IEN0b3I7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaW5pdENsb25lT2JqZWN0O1xuIiwidmFyIGdldExlbmd0aCA9IHJlcXVpcmUoJy4vZ2V0TGVuZ3RoJyksXG4gICAgaXNMZW5ndGggPSByZXF1aXJlKCcuL2lzTGVuZ3RoJyk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYXJyYXktbGlrZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhcnJheS1saWtlLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzQXJyYXlMaWtlKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSAhPSBudWxsICYmIGlzTGVuZ3RoKGdldExlbmd0aCh2YWx1ZSkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzQXJyYXlMaWtlO1xuIiwiLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIGhvc3Qgb2JqZWN0IGluIElFIDwgOS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIGhvc3Qgb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gKi9cbnZhciBpc0hvc3RPYmplY3QgPSAoZnVuY3Rpb24oKSB7XG4gIHRyeSB7XG4gICAgT2JqZWN0KHsgJ3RvU3RyaW5nJzogMCB9ICsgJycpO1xuICB9IGNhdGNoKGUpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7IHJldHVybiBmYWxzZTsgfTtcbiAgfVxuICByZXR1cm4gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAvLyBJRSA8IDkgcHJlc2VudHMgbWFueSBob3N0IG9iamVjdHMgYXMgYE9iamVjdGAgb2JqZWN0cyB0aGF0IGNhbiBjb2VyY2VcbiAgICAvLyB0byBzdHJpbmdzIGRlc3BpdGUgaGF2aW5nIGltcHJvcGVybHkgZGVmaW5lZCBgdG9TdHJpbmdgIG1ldGhvZHMuXG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZS50b1N0cmluZyAhPSAnZnVuY3Rpb24nICYmIHR5cGVvZiAodmFsdWUgKyAnJykgPT0gJ3N0cmluZyc7XG4gIH07XG59KCkpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGlzSG9zdE9iamVjdDtcbiIsIi8qKiBVc2VkIHRvIGRldGVjdCB1bnNpZ25lZCBpbnRlZ2VyIHZhbHVlcy4gKi9cbnZhciByZUlzVWludCA9IC9eXFxkKyQvO1xuXG4vKipcbiAqIFVzZWQgYXMgdGhlIFttYXhpbXVtIGxlbmd0aF0oaHR0cHM6Ly9wZW9wbGUubW96aWxsYS5vcmcvfmpvcmVuZG9yZmYvZXM2LWRyYWZ0Lmh0bWwjc2VjLW51bWJlci5tYXhfc2FmZV9pbnRlZ2VyKVxuICogb2YgYW4gYXJyYXktbGlrZSB2YWx1ZS5cbiAqL1xudmFyIE1BWF9TQUZFX0lOVEVHRVIgPSA5MDA3MTk5MjU0NzQwOTkxO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgYXJyYXktbGlrZSBpbmRleC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aD1NQVhfU0FGRV9JTlRFR0VSXSBUaGUgdXBwZXIgYm91bmRzIG9mIGEgdmFsaWQgaW5kZXguXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGluZGV4LCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzSW5kZXgodmFsdWUsIGxlbmd0aCkge1xuICB2YWx1ZSA9ICh0eXBlb2YgdmFsdWUgPT0gJ251bWJlcicgfHwgcmVJc1VpbnQudGVzdCh2YWx1ZSkpID8gK3ZhbHVlIDogLTE7XG4gIGxlbmd0aCA9IGxlbmd0aCA9PSBudWxsID8gTUFYX1NBRkVfSU5URUdFUiA6IGxlbmd0aDtcbiAgcmV0dXJuIHZhbHVlID4gLTEgJiYgdmFsdWUgJSAxID09IDAgJiYgdmFsdWUgPCBsZW5ndGg7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNJbmRleDtcbiIsInZhciBpc0FycmF5TGlrZSA9IHJlcXVpcmUoJy4vaXNBcnJheUxpa2UnKSxcbiAgICBpc0luZGV4ID0gcmVxdWlyZSgnLi9pc0luZGV4JyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0Jyk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBwcm92aWRlZCBhcmd1bWVudHMgYXJlIGZyb20gYW4gaXRlcmF0ZWUgY2FsbC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgcG90ZW50aWFsIGl0ZXJhdGVlIHZhbHVlIGFyZ3VtZW50LlxuICogQHBhcmFtIHsqfSBpbmRleCBUaGUgcG90ZW50aWFsIGl0ZXJhdGVlIGluZGV4IG9yIGtleSBhcmd1bWVudC5cbiAqIEBwYXJhbSB7Kn0gb2JqZWN0IFRoZSBwb3RlbnRpYWwgaXRlcmF0ZWUgb2JqZWN0IGFyZ3VtZW50LlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBhcmd1bWVudHMgYXJlIGZyb20gYW4gaXRlcmF0ZWUgY2FsbCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0l0ZXJhdGVlQ2FsbCh2YWx1ZSwgaW5kZXgsIG9iamVjdCkge1xuICBpZiAoIWlzT2JqZWN0KG9iamVjdCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIHR5cGUgPSB0eXBlb2YgaW5kZXg7XG4gIGlmICh0eXBlID09ICdudW1iZXInXG4gICAgICA/IChpc0FycmF5TGlrZShvYmplY3QpICYmIGlzSW5kZXgoaW5kZXgsIG9iamVjdC5sZW5ndGgpKVxuICAgICAgOiAodHlwZSA9PSAnc3RyaW5nJyAmJiBpbmRleCBpbiBvYmplY3QpKSB7XG4gICAgdmFyIG90aGVyID0gb2JqZWN0W2luZGV4XTtcbiAgICByZXR1cm4gdmFsdWUgPT09IHZhbHVlID8gKHZhbHVlID09PSBvdGhlcikgOiAob3RoZXIgIT09IG90aGVyKTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNJdGVyYXRlZUNhbGw7XG4iLCJ2YXIgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcnJheScpLFxuICAgIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi90b09iamVjdCcpO1xuXG4vKiogVXNlZCB0byBtYXRjaCBwcm9wZXJ0eSBuYW1lcyB3aXRoaW4gcHJvcGVydHkgcGF0aHMuICovXG52YXIgcmVJc0RlZXBQcm9wID0gL1xcLnxcXFsoPzpbXltcXF1dKnwoW1wiJ10pKD86KD8hXFwxKVteXFxuXFxcXF18XFxcXC4pKj9cXDEpXFxdLyxcbiAgICByZUlzUGxhaW5Qcm9wID0gL15cXHcqJC87XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBwcm9wZXJ0eSBuYW1lIGFuZCBub3QgYSBwcm9wZXJ0eSBwYXRoLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0XSBUaGUgb2JqZWN0IHRvIHF1ZXJ5IGtleXMgb24uXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHByb3BlcnR5IG5hbWUsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNLZXkodmFsdWUsIG9iamVjdCkge1xuICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgaWYgKCh0eXBlID09ICdzdHJpbmcnICYmIHJlSXNQbGFpblByb3AudGVzdCh2YWx1ZSkpIHx8IHR5cGUgPT0gJ251bWJlcicpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIHJlc3VsdCA9ICFyZUlzRGVlcFByb3AudGVzdCh2YWx1ZSk7XG4gIHJldHVybiByZXN1bHQgfHwgKG9iamVjdCAhPSBudWxsICYmIHZhbHVlIGluIHRvT2JqZWN0KG9iamVjdCkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzS2V5O1xuIiwidmFyIExhenlXcmFwcGVyID0gcmVxdWlyZSgnLi9MYXp5V3JhcHBlcicpLFxuICAgIGdldERhdGEgPSByZXF1aXJlKCcuL2dldERhdGEnKSxcbiAgICBnZXRGdW5jTmFtZSA9IHJlcXVpcmUoJy4vZ2V0RnVuY05hbWUnKSxcbiAgICBsb2Rhc2ggPSByZXF1aXJlKCcuLi9jaGFpbi9sb2Rhc2gnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYGZ1bmNgIGhhcyBhIGxhenkgY291bnRlcnBhcnQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBmdW5jYCBoYXMgYSBsYXp5IGNvdW50ZXJwYXJ0LCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzTGF6aWFibGUoZnVuYykge1xuICB2YXIgZnVuY05hbWUgPSBnZXRGdW5jTmFtZShmdW5jKTtcbiAgaWYgKCEoZnVuY05hbWUgaW4gTGF6eVdyYXBwZXIucHJvdG90eXBlKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB2YXIgb3RoZXIgPSBsb2Rhc2hbZnVuY05hbWVdO1xuICBpZiAoZnVuYyA9PT0gb3RoZXIpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICB2YXIgZGF0YSA9IGdldERhdGEob3RoZXIpO1xuICByZXR1cm4gISFkYXRhICYmIGZ1bmMgPT09IGRhdGFbMF07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNMYXppYWJsZTtcbiIsIi8qKlxuICogVXNlZCBhcyB0aGUgW21heGltdW0gbGVuZ3RoXShodHRwczovL3Blb3BsZS5tb3ppbGxhLm9yZy9+am9yZW5kb3JmZi9lczYtZHJhZnQuaHRtbCNzZWMtbnVtYmVyLm1heF9zYWZlX2ludGVnZXIpXG4gKiBvZiBhbiBhcnJheS1saWtlIHZhbHVlLlxuICovXG52YXIgTUFYX1NBRkVfSU5URUdFUiA9IDkwMDcxOTkyNTQ3NDA5OTE7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBhcnJheS1saWtlIGxlbmd0aC5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBpcyBiYXNlZCBvbiBbYFRvTGVuZ3RoYF0oaHR0cHM6Ly9wZW9wbGUubW96aWxsYS5vcmcvfmpvcmVuZG9yZmYvZXM2LWRyYWZ0Lmh0bWwjc2VjLXRvbGVuZ3RoKS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGxlbmd0aCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0xlbmd0aCh2YWx1ZSkge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09ICdudW1iZXInICYmIHZhbHVlID4gLTEgJiYgdmFsdWUgJSAxID09IDAgJiYgdmFsdWUgPD0gTUFYX1NBRkVfSU5URUdFUjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0xlbmd0aDtcbiIsIi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNPYmplY3RMaWtlKHZhbHVlKSB7XG4gIHJldHVybiAhIXZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PSAnb2JqZWN0Jztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc09iamVjdExpa2U7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0Jyk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgc3VpdGFibGUgZm9yIHN0cmljdCBlcXVhbGl0eSBjb21wYXJpc29ucywgaS5lLiBgPT09YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpZiBzdWl0YWJsZSBmb3Igc3RyaWN0XG4gKiAgZXF1YWxpdHkgY29tcGFyaXNvbnMsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNTdHJpY3RDb21wYXJhYmxlKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSA9PT0gdmFsdWUgJiYgIWlzT2JqZWN0KHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1N0cmljdENvbXBhcmFibGU7XG4iLCJ2YXIgYXJyYXlDb3B5ID0gcmVxdWlyZSgnLi9hcnJheUNvcHknKSxcbiAgICBjb21wb3NlQXJncyA9IHJlcXVpcmUoJy4vY29tcG9zZUFyZ3MnKSxcbiAgICBjb21wb3NlQXJnc1JpZ2h0ID0gcmVxdWlyZSgnLi9jb21wb3NlQXJnc1JpZ2h0JyksXG4gICAgcmVwbGFjZUhvbGRlcnMgPSByZXF1aXJlKCcuL3JlcGxhY2VIb2xkZXJzJyk7XG5cbi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHdyYXBwZXIgbWV0YWRhdGEuICovXG52YXIgQklORF9GTEFHID0gMSxcbiAgICBDVVJSWV9CT1VORF9GTEFHID0gNCxcbiAgICBDVVJSWV9GTEFHID0gOCxcbiAgICBBUllfRkxBRyA9IDEyOCxcbiAgICBSRUFSR19GTEFHID0gMjU2O1xuXG4vKiogVXNlZCBhcyB0aGUgaW50ZXJuYWwgYXJndW1lbnQgcGxhY2Vob2xkZXIuICovXG52YXIgUExBQ0VIT0xERVIgPSAnX19sb2Rhc2hfcGxhY2Vob2xkZXJfXyc7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlTWluID0gTWF0aC5taW47XG5cbi8qKlxuICogTWVyZ2VzIHRoZSBmdW5jdGlvbiBtZXRhZGF0YSBvZiBgc291cmNlYCBpbnRvIGBkYXRhYC5cbiAqXG4gKiBNZXJnaW5nIG1ldGFkYXRhIHJlZHVjZXMgdGhlIG51bWJlciBvZiB3cmFwcGVycyByZXF1aXJlZCB0byBpbnZva2UgYSBmdW5jdGlvbi5cbiAqIFRoaXMgaXMgcG9zc2libGUgYmVjYXVzZSBtZXRob2RzIGxpa2UgYF8uYmluZGAsIGBfLmN1cnJ5YCwgYW5kIGBfLnBhcnRpYWxgXG4gKiBtYXkgYmUgYXBwbGllZCByZWdhcmRsZXNzIG9mIGV4ZWN1dGlvbiBvcmRlci4gTWV0aG9kcyBsaWtlIGBfLmFyeWAgYW5kIGBfLnJlYXJnYFxuICogYXVnbWVudCBmdW5jdGlvbiBhcmd1bWVudHMsIG1ha2luZyB0aGUgb3JkZXIgaW4gd2hpY2ggdGhleSBhcmUgZXhlY3V0ZWQgaW1wb3J0YW50LFxuICogcHJldmVudGluZyB0aGUgbWVyZ2luZyBvZiBtZXRhZGF0YS4gSG93ZXZlciwgd2UgbWFrZSBhbiBleGNlcHRpb24gZm9yIGEgc2FmZVxuICogY29tbW9uIGNhc2Ugd2hlcmUgY3VycmllZCBmdW5jdGlvbnMgaGF2ZSBgXy5hcnlgIGFuZCBvciBgXy5yZWFyZ2AgYXBwbGllZC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gZGF0YSBUaGUgZGVzdGluYXRpb24gbWV0YWRhdGEuXG4gKiBAcGFyYW0ge0FycmF5fSBzb3VyY2UgVGhlIHNvdXJjZSBtZXRhZGF0YS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgZGF0YWAuXG4gKi9cbmZ1bmN0aW9uIG1lcmdlRGF0YShkYXRhLCBzb3VyY2UpIHtcbiAgdmFyIGJpdG1hc2sgPSBkYXRhWzFdLFxuICAgICAgc3JjQml0bWFzayA9IHNvdXJjZVsxXSxcbiAgICAgIG5ld0JpdG1hc2sgPSBiaXRtYXNrIHwgc3JjQml0bWFzayxcbiAgICAgIGlzQ29tbW9uID0gbmV3Qml0bWFzayA8IEFSWV9GTEFHO1xuXG4gIHZhciBpc0NvbWJvID1cbiAgICAoc3JjQml0bWFzayA9PSBBUllfRkxBRyAmJiBiaXRtYXNrID09IENVUlJZX0ZMQUcpIHx8XG4gICAgKHNyY0JpdG1hc2sgPT0gQVJZX0ZMQUcgJiYgYml0bWFzayA9PSBSRUFSR19GTEFHICYmIGRhdGFbN10ubGVuZ3RoIDw9IHNvdXJjZVs4XSkgfHxcbiAgICAoc3JjQml0bWFzayA9PSAoQVJZX0ZMQUcgfCBSRUFSR19GTEFHKSAmJiBiaXRtYXNrID09IENVUlJZX0ZMQUcpO1xuXG4gIC8vIEV4aXQgZWFybHkgaWYgbWV0YWRhdGEgY2FuJ3QgYmUgbWVyZ2VkLlxuICBpZiAoIShpc0NvbW1vbiB8fCBpc0NvbWJvKSkge1xuICAgIHJldHVybiBkYXRhO1xuICB9XG4gIC8vIFVzZSBzb3VyY2UgYHRoaXNBcmdgIGlmIGF2YWlsYWJsZS5cbiAgaWYgKHNyY0JpdG1hc2sgJiBCSU5EX0ZMQUcpIHtcbiAgICBkYXRhWzJdID0gc291cmNlWzJdO1xuICAgIC8vIFNldCB3aGVuIGN1cnJ5aW5nIGEgYm91bmQgZnVuY3Rpb24uXG4gICAgbmV3Qml0bWFzayB8PSAoYml0bWFzayAmIEJJTkRfRkxBRykgPyAwIDogQ1VSUllfQk9VTkRfRkxBRztcbiAgfVxuICAvLyBDb21wb3NlIHBhcnRpYWwgYXJndW1lbnRzLlxuICB2YXIgdmFsdWUgPSBzb3VyY2VbM107XG4gIGlmICh2YWx1ZSkge1xuICAgIHZhciBwYXJ0aWFscyA9IGRhdGFbM107XG4gICAgZGF0YVszXSA9IHBhcnRpYWxzID8gY29tcG9zZUFyZ3MocGFydGlhbHMsIHZhbHVlLCBzb3VyY2VbNF0pIDogYXJyYXlDb3B5KHZhbHVlKTtcbiAgICBkYXRhWzRdID0gcGFydGlhbHMgPyByZXBsYWNlSG9sZGVycyhkYXRhWzNdLCBQTEFDRUhPTERFUikgOiBhcnJheUNvcHkoc291cmNlWzRdKTtcbiAgfVxuICAvLyBDb21wb3NlIHBhcnRpYWwgcmlnaHQgYXJndW1lbnRzLlxuICB2YWx1ZSA9IHNvdXJjZVs1XTtcbiAgaWYgKHZhbHVlKSB7XG4gICAgcGFydGlhbHMgPSBkYXRhWzVdO1xuICAgIGRhdGFbNV0gPSBwYXJ0aWFscyA/IGNvbXBvc2VBcmdzUmlnaHQocGFydGlhbHMsIHZhbHVlLCBzb3VyY2VbNl0pIDogYXJyYXlDb3B5KHZhbHVlKTtcbiAgICBkYXRhWzZdID0gcGFydGlhbHMgPyByZXBsYWNlSG9sZGVycyhkYXRhWzVdLCBQTEFDRUhPTERFUikgOiBhcnJheUNvcHkoc291cmNlWzZdKTtcbiAgfVxuICAvLyBVc2Ugc291cmNlIGBhcmdQb3NgIGlmIGF2YWlsYWJsZS5cbiAgdmFsdWUgPSBzb3VyY2VbN107XG4gIGlmICh2YWx1ZSkge1xuICAgIGRhdGFbN10gPSBhcnJheUNvcHkodmFsdWUpO1xuICB9XG4gIC8vIFVzZSBzb3VyY2UgYGFyeWAgaWYgaXQncyBzbWFsbGVyLlxuICBpZiAoc3JjQml0bWFzayAmIEFSWV9GTEFHKSB7XG4gICAgZGF0YVs4XSA9IGRhdGFbOF0gPT0gbnVsbCA/IHNvdXJjZVs4XSA6IG5hdGl2ZU1pbihkYXRhWzhdLCBzb3VyY2VbOF0pO1xuICB9XG4gIC8vIFVzZSBzb3VyY2UgYGFyaXR5YCBpZiBvbmUgaXMgbm90IHByb3ZpZGVkLlxuICBpZiAoZGF0YVs5XSA9PSBudWxsKSB7XG4gICAgZGF0YVs5XSA9IHNvdXJjZVs5XTtcbiAgfVxuICAvLyBVc2Ugc291cmNlIGBmdW5jYCBhbmQgbWVyZ2UgYml0bWFza3MuXG4gIGRhdGFbMF0gPSBzb3VyY2VbMF07XG4gIGRhdGFbMV0gPSBuZXdCaXRtYXNrO1xuXG4gIHJldHVybiBkYXRhO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG1lcmdlRGF0YTtcbiIsInZhciBnZXROYXRpdmUgPSByZXF1aXJlKCcuL2dldE5hdGl2ZScpO1xuXG4vKiogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIFdlYWtNYXAgPSBnZXROYXRpdmUoZ2xvYmFsLCAnV2Vha01hcCcpO1xuXG4vKiogVXNlZCB0byBzdG9yZSBmdW5jdGlvbiBtZXRhZGF0YS4gKi9cbnZhciBtZXRhTWFwID0gV2Vha01hcCAmJiBuZXcgV2Vha01hcDtcblxubW9kdWxlLmV4cG9ydHMgPSBtZXRhTWFwO1xuIiwiLyoqIFVzZWQgdG8gbG9va3VwIHVubWluaWZpZWQgZnVuY3Rpb24gbmFtZXMuICovXG52YXIgcmVhbE5hbWVzID0ge307XG5cbm1vZHVsZS5leHBvcnRzID0gcmVhbE5hbWVzO1xuIiwidmFyIGFycmF5Q29weSA9IHJlcXVpcmUoJy4vYXJyYXlDb3B5JyksXG4gICAgaXNJbmRleCA9IHJlcXVpcmUoJy4vaXNJbmRleCcpO1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1pbiA9IE1hdGgubWluO1xuXG4vKipcbiAqIFJlb3JkZXIgYGFycmF5YCBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmllZCBpbmRleGVzIHdoZXJlIHRoZSBlbGVtZW50IGF0XG4gKiB0aGUgZmlyc3QgaW5kZXggaXMgYXNzaWduZWQgYXMgdGhlIGZpcnN0IGVsZW1lbnQsIHRoZSBlbGVtZW50IGF0XG4gKiB0aGUgc2Vjb25kIGluZGV4IGlzIGFzc2lnbmVkIGFzIHRoZSBzZWNvbmQgZWxlbWVudCwgYW5kIHNvIG9uLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcmVvcmRlci5cbiAqIEBwYXJhbSB7QXJyYXl9IGluZGV4ZXMgVGhlIGFycmFuZ2VkIGFycmF5IGluZGV4ZXMuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAqL1xuZnVuY3Rpb24gcmVvcmRlcihhcnJheSwgaW5kZXhlcykge1xuICB2YXIgYXJyTGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgbGVuZ3RoID0gbmF0aXZlTWluKGluZGV4ZXMubGVuZ3RoLCBhcnJMZW5ndGgpLFxuICAgICAgb2xkQXJyYXkgPSBhcnJheUNvcHkoYXJyYXkpO1xuXG4gIHdoaWxlIChsZW5ndGgtLSkge1xuICAgIHZhciBpbmRleCA9IGluZGV4ZXNbbGVuZ3RoXTtcbiAgICBhcnJheVtsZW5ndGhdID0gaXNJbmRleChpbmRleCwgYXJyTGVuZ3RoKSA/IG9sZEFycmF5W2luZGV4XSA6IHVuZGVmaW5lZDtcbiAgfVxuICByZXR1cm4gYXJyYXk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcmVvcmRlcjtcbiIsIi8qKiBVc2VkIGFzIHRoZSBpbnRlcm5hbCBhcmd1bWVudCBwbGFjZWhvbGRlci4gKi9cbnZhciBQTEFDRUhPTERFUiA9ICdfX2xvZGFzaF9wbGFjZWhvbGRlcl9fJztcblxuLyoqXG4gKiBSZXBsYWNlcyBhbGwgYHBsYWNlaG9sZGVyYCBlbGVtZW50cyBpbiBgYXJyYXlgIHdpdGggYW4gaW50ZXJuYWwgcGxhY2Vob2xkZXJcbiAqIGFuZCByZXR1cm5zIGFuIGFycmF5IG9mIHRoZWlyIGluZGV4ZXMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuXG4gKiBAcGFyYW0geyp9IHBsYWNlaG9sZGVyIFRoZSBwbGFjZWhvbGRlciB0byByZXBsYWNlLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgcGxhY2Vob2xkZXIgaW5kZXhlcy5cbiAqL1xuZnVuY3Rpb24gcmVwbGFjZUhvbGRlcnMoYXJyYXksIHBsYWNlaG9sZGVyKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgcmVzSW5kZXggPSAtMSxcbiAgICAgIHJlc3VsdCA9IFtdO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgaWYgKGFycmF5W2luZGV4XSA9PT0gcGxhY2Vob2xkZXIpIHtcbiAgICAgIGFycmF5W2luZGV4XSA9IFBMQUNFSE9MREVSO1xuICAgICAgcmVzdWx0WysrcmVzSW5kZXhdID0gaW5kZXg7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcmVwbGFjZUhvbGRlcnM7XG4iLCJ2YXIgYmFzZVNldERhdGEgPSByZXF1aXJlKCcuL2Jhc2VTZXREYXRhJyksXG4gICAgbm93ID0gcmVxdWlyZSgnLi4vZGF0ZS9ub3cnKTtcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IHdoZW4gYSBmdW5jdGlvbiBiZWNvbWVzIGhvdC4gKi9cbnZhciBIT1RfQ09VTlQgPSAxNTAsXG4gICAgSE9UX1NQQU4gPSAxNjtcblxuLyoqXG4gKiBTZXRzIG1ldGFkYXRhIGZvciBgZnVuY2AuXG4gKlxuICogKipOb3RlOioqIElmIHRoaXMgZnVuY3Rpb24gYmVjb21lcyBob3QsIGkuZS4gaXMgaW52b2tlZCBhIGxvdCBpbiBhIHNob3J0XG4gKiBwZXJpb2Qgb2YgdGltZSwgaXQgd2lsbCB0cmlwIGl0cyBicmVha2VyIGFuZCB0cmFuc2l0aW9uIHRvIGFuIGlkZW50aXR5IGZ1bmN0aW9uXG4gKiB0byBhdm9pZCBnYXJiYWdlIGNvbGxlY3Rpb24gcGF1c2VzIGluIFY4LiBTZWUgW1Y4IGlzc3VlIDIwNzBdKGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0yMDcwKVxuICogZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYXNzb2NpYXRlIG1ldGFkYXRhIHdpdGguXG4gKiBAcGFyYW0geyp9IGRhdGEgVGhlIG1ldGFkYXRhLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGBmdW5jYC5cbiAqL1xudmFyIHNldERhdGEgPSAoZnVuY3Rpb24oKSB7XG4gIHZhciBjb3VudCA9IDAsXG4gICAgICBsYXN0Q2FsbGVkID0gMDtcblxuICByZXR1cm4gZnVuY3Rpb24oa2V5LCB2YWx1ZSkge1xuICAgIHZhciBzdGFtcCA9IG5vdygpLFxuICAgICAgICByZW1haW5pbmcgPSBIT1RfU1BBTiAtIChzdGFtcCAtIGxhc3RDYWxsZWQpO1xuXG4gICAgbGFzdENhbGxlZCA9IHN0YW1wO1xuICAgIGlmIChyZW1haW5pbmcgPiAwKSB7XG4gICAgICBpZiAoKytjb3VudCA+PSBIT1RfQ09VTlQpIHtcbiAgICAgICAgcmV0dXJuIGtleTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY291bnQgPSAwO1xuICAgIH1cbiAgICByZXR1cm4gYmFzZVNldERhdGEoa2V5LCB2YWx1ZSk7XG4gIH07XG59KCkpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHNldERhdGE7XG4iLCJ2YXIgYmFzZUZvckluID0gcmVxdWlyZSgnLi9iYXNlRm9ySW4nKSxcbiAgICBpc0FyZ3VtZW50cyA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcmd1bWVudHMnKSxcbiAgICBpc0hvc3RPYmplY3QgPSByZXF1aXJlKCcuL2lzSG9zdE9iamVjdCcpLFxuICAgIGlzT2JqZWN0TGlrZSA9IHJlcXVpcmUoJy4vaXNPYmplY3RMaWtlJyksXG4gICAgc3VwcG9ydCA9IHJlcXVpcmUoJy4uL3N1cHBvcnQnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwczovL3Blb3BsZS5tb3ppbGxhLm9yZy9+am9yZW5kb3JmZi9lczYtZHJhZnQuaHRtbCNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKlxuICogQSBmYWxsYmFjayBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc1BsYWluT2JqZWN0YCB3aGljaCBjaGVja3MgaWYgYHZhbHVlYFxuICogaXMgYW4gb2JqZWN0IGNyZWF0ZWQgYnkgdGhlIGBPYmplY3RgIGNvbnN0cnVjdG9yIG9yIGhhcyBhIGBbW1Byb3RvdHlwZV1dYFxuICogb2YgYG51bGxgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgcGxhaW4gb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIHNoaW1Jc1BsYWluT2JqZWN0KHZhbHVlKSB7XG4gIHZhciBDdG9yO1xuXG4gIC8vIEV4aXQgZWFybHkgZm9yIG5vbiBgT2JqZWN0YCBvYmplY3RzLlxuICBpZiAoIShpc09iamVjdExpa2UodmFsdWUpICYmIG9ialRvU3RyaW5nLmNhbGwodmFsdWUpID09IG9iamVjdFRhZyAmJiAhaXNIb3N0T2JqZWN0KHZhbHVlKSkgfHxcbiAgICAgICghaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgJ2NvbnN0cnVjdG9yJykgJiZcbiAgICAgICAgKEN0b3IgPSB2YWx1ZS5jb25zdHJ1Y3RvciwgdHlwZW9mIEN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiAhKEN0b3IgaW5zdGFuY2VvZiBDdG9yKSkpIHx8XG4gICAgICAoIXN1cHBvcnQuYXJnc1RhZyAmJiBpc0FyZ3VtZW50cyh2YWx1ZSkpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIC8vIElFIDwgOSBpdGVyYXRlcyBpbmhlcml0ZWQgcHJvcGVydGllcyBiZWZvcmUgb3duIHByb3BlcnRpZXMuIElmIHRoZSBmaXJzdFxuICAvLyBpdGVyYXRlZCBwcm9wZXJ0eSBpcyBhbiBvYmplY3QncyBvd24gcHJvcGVydHkgdGhlbiB0aGVyZSBhcmUgbm8gaW5oZXJpdGVkXG4gIC8vIGVudW1lcmFibGUgcHJvcGVydGllcy5cbiAgdmFyIHJlc3VsdDtcbiAgaWYgKHN1cHBvcnQub3duTGFzdCkge1xuICAgIGJhc2VGb3JJbih2YWx1ZSwgZnVuY3Rpb24oc3ViVmFsdWUsIGtleSwgb2JqZWN0KSB7XG4gICAgICByZXN1bHQgPSBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0ICE9PSBmYWxzZTtcbiAgfVxuICAvLyBJbiBtb3N0IGVudmlyb25tZW50cyBhbiBvYmplY3QncyBvd24gcHJvcGVydGllcyBhcmUgaXRlcmF0ZWQgYmVmb3JlXG4gIC8vIGl0cyBpbmhlcml0ZWQgcHJvcGVydGllcy4gSWYgdGhlIGxhc3QgaXRlcmF0ZWQgcHJvcGVydHkgaXMgYW4gb2JqZWN0J3NcbiAgLy8gb3duIHByb3BlcnR5IHRoZW4gdGhlcmUgYXJlIG5vIGluaGVyaXRlZCBlbnVtZXJhYmxlIHByb3BlcnRpZXMuXG4gIGJhc2VGb3JJbih2YWx1ZSwgZnVuY3Rpb24oc3ViVmFsdWUsIGtleSkge1xuICAgIHJlc3VsdCA9IGtleTtcbiAgfSk7XG4gIHJldHVybiByZXN1bHQgPT09IHVuZGVmaW5lZCB8fCBoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCByZXN1bHQpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNoaW1Jc1BsYWluT2JqZWN0O1xuIiwidmFyIGlzQXJndW1lbnRzID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FyZ3VtZW50cycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICBpc0luZGV4ID0gcmVxdWlyZSgnLi9pc0luZGV4JyksXG4gICAgaXNMZW5ndGggPSByZXF1aXJlKCcuL2lzTGVuZ3RoJyksXG4gICAgaXNTdHJpbmcgPSByZXF1aXJlKCcuLi9sYW5nL2lzU3RyaW5nJyksXG4gICAga2V5c0luID0gcmVxdWlyZSgnLi4vb2JqZWN0L2tleXNJbicpO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBBIGZhbGxiYWNrIGltcGxlbWVudGF0aW9uIG9mIGBPYmplY3Qua2V5c2Agd2hpY2ggY3JlYXRlcyBhbiBhcnJheSBvZiB0aGVcbiAqIG93biBlbnVtZXJhYmxlIHByb3BlcnR5IG5hbWVzIG9mIGBvYmplY3RgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICovXG5mdW5jdGlvbiBzaGltS2V5cyhvYmplY3QpIHtcbiAgdmFyIHByb3BzID0ga2V5c0luKG9iamVjdCksXG4gICAgICBwcm9wc0xlbmd0aCA9IHByb3BzLmxlbmd0aCxcbiAgICAgIGxlbmd0aCA9IHByb3BzTGVuZ3RoICYmIG9iamVjdC5sZW5ndGg7XG5cbiAgdmFyIGFsbG93SW5kZXhlcyA9ICEhbGVuZ3RoICYmIGlzTGVuZ3RoKGxlbmd0aCkgJiZcbiAgICAoaXNBcnJheShvYmplY3QpIHx8IGlzQXJndW1lbnRzKG9iamVjdCkgfHwgaXNTdHJpbmcob2JqZWN0KSk7XG5cbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICByZXN1bHQgPSBbXTtcblxuICB3aGlsZSAoKytpbmRleCA8IHByb3BzTGVuZ3RoKSB7XG4gICAgdmFyIGtleSA9IHByb3BzW2luZGV4XTtcbiAgICBpZiAoKGFsbG93SW5kZXhlcyAmJiBpc0luZGV4KGtleSwgbGVuZ3RoKSkgfHwgaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkpIHtcbiAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc2hpbUtleXM7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0JyksXG4gICAgaXNTdHJpbmcgPSByZXF1aXJlKCcuLi9sYW5nL2lzU3RyaW5nJyksXG4gICAgc3VwcG9ydCA9IHJlcXVpcmUoJy4uL3N1cHBvcnQnKTtcblxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGFuIG9iamVjdCBpZiBpdCdzIG5vdCBvbmUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb2Nlc3MuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBvYmplY3QuXG4gKi9cbmZ1bmN0aW9uIHRvT2JqZWN0KHZhbHVlKSB7XG4gIGlmIChzdXBwb3J0LnVuaW5kZXhlZENoYXJzICYmIGlzU3RyaW5nKHZhbHVlKSkge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSB2YWx1ZS5sZW5ndGgsXG4gICAgICAgIHJlc3VsdCA9IE9iamVjdCh2YWx1ZSk7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgcmVzdWx0W2luZGV4XSA9IHZhbHVlLmNoYXJBdChpbmRleCk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgcmV0dXJuIGlzT2JqZWN0KHZhbHVlKSA/IHZhbHVlIDogT2JqZWN0KHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0b09iamVjdDtcbiIsInZhciBiYXNlVG9TdHJpbmcgPSByZXF1aXJlKCcuL2Jhc2VUb1N0cmluZycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKTtcblxuLyoqIFVzZWQgdG8gbWF0Y2ggcHJvcGVydHkgbmFtZXMgd2l0aGluIHByb3BlcnR5IHBhdGhzLiAqL1xudmFyIHJlUHJvcE5hbWUgPSAvW14uW1xcXV0rfFxcWyg/OigtP1xcZCsoPzpcXC5cXGQrKT8pfChbXCInXSkoKD86KD8hXFwyKVteXFxuXFxcXF18XFxcXC4pKj8pXFwyKVxcXS9nO1xuXG4vKiogVXNlZCB0byBtYXRjaCBiYWNrc2xhc2hlcyBpbiBwcm9wZXJ0eSBwYXRocy4gKi9cbnZhciByZUVzY2FwZUNoYXIgPSAvXFxcXChcXFxcKT8vZztcblxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIHByb3BlcnR5IHBhdGggYXJyYXkgaWYgaXQncyBub3Qgb25lLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm9jZXNzLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBwcm9wZXJ0eSBwYXRoIGFycmF5LlxuICovXG5mdW5jdGlvbiB0b1BhdGgodmFsdWUpIHtcbiAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgYmFzZVRvU3RyaW5nKHZhbHVlKS5yZXBsYWNlKHJlUHJvcE5hbWUsIGZ1bmN0aW9uKG1hdGNoLCBudW1iZXIsIHF1b3RlLCBzdHJpbmcpIHtcbiAgICByZXN1bHQucHVzaChxdW90ZSA/IHN0cmluZy5yZXBsYWNlKHJlRXNjYXBlQ2hhciwgJyQxJykgOiAobnVtYmVyIHx8IG1hdGNoKSk7XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHRvUGF0aDtcbiIsInZhciBMYXp5V3JhcHBlciA9IHJlcXVpcmUoJy4vTGF6eVdyYXBwZXInKSxcbiAgICBMb2Rhc2hXcmFwcGVyID0gcmVxdWlyZSgnLi9Mb2Rhc2hXcmFwcGVyJyksXG4gICAgYXJyYXlDb3B5ID0gcmVxdWlyZSgnLi9hcnJheUNvcHknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgY2xvbmUgb2YgYHdyYXBwZXJgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gd3JhcHBlciBUaGUgd3JhcHBlciB0byBjbG9uZS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNsb25lZCB3cmFwcGVyLlxuICovXG5mdW5jdGlvbiB3cmFwcGVyQ2xvbmUod3JhcHBlcikge1xuICByZXR1cm4gd3JhcHBlciBpbnN0YW5jZW9mIExhenlXcmFwcGVyXG4gICAgPyB3cmFwcGVyLmNsb25lKClcbiAgICA6IG5ldyBMb2Rhc2hXcmFwcGVyKHdyYXBwZXIuX193cmFwcGVkX18sIHdyYXBwZXIuX19jaGFpbl9fLCBhcnJheUNvcHkod3JhcHBlci5fX2FjdGlvbnNfXykpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHdyYXBwZXJDbG9uZTtcbiIsInZhciBiYXNlQ2xvbmUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlQ2xvbmUnKSxcbiAgICBiaW5kQ2FsbGJhY2sgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iaW5kQ2FsbGJhY2snKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZGVlcCBjbG9uZSBvZiBgdmFsdWVgLiBJZiBgY3VzdG9taXplcmAgaXMgcHJvdmlkZWQgaXQgaXMgaW52b2tlZFxuICogdG8gcHJvZHVjZSB0aGUgY2xvbmVkIHZhbHVlcy4gSWYgYGN1c3RvbWl6ZXJgIHJldHVybnMgYHVuZGVmaW5lZGAgY2xvbmluZ1xuICogaXMgaGFuZGxlZCBieSB0aGUgbWV0aG9kIGluc3RlYWQuIFRoZSBgY3VzdG9taXplcmAgaXMgYm91bmQgdG8gYHRoaXNBcmdgXG4gKiBhbmQgaW52b2tlZCB3aXRoIHR3byBhcmd1bWVudDsgKHZhbHVlIFssIGluZGV4fGtleSwgb2JqZWN0XSkuXG4gKlxuICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGxvb3NlbHkgYmFzZWQgb24gdGhlXG4gKiBbc3RydWN0dXJlZCBjbG9uZSBhbGdvcml0aG1dKGh0dHA6Ly93d3cudzMub3JnL1RSL2h0bWw1L2luZnJhc3RydWN0dXJlLmh0bWwjaW50ZXJuYWwtc3RydWN0dXJlZC1jbG9uaW5nLWFsZ29yaXRobSkuXG4gKiBUaGUgZW51bWVyYWJsZSBwcm9wZXJ0aWVzIG9mIGBhcmd1bWVudHNgIG9iamVjdHMgYW5kIG9iamVjdHMgY3JlYXRlZCBieVxuICogY29uc3RydWN0b3JzIG90aGVyIHRoYW4gYE9iamVjdGAgYXJlIGNsb25lZCB0byBwbGFpbiBgT2JqZWN0YCBvYmplY3RzLiBBblxuICogZW1wdHkgb2JqZWN0IGlzIHJldHVybmVkIGZvciB1bmNsb25lYWJsZSB2YWx1ZXMgc3VjaCBhcyBmdW5jdGlvbnMsIERPTSBub2RlcyxcbiAqIE1hcHMsIFNldHMsIGFuZCBXZWFrTWFwcy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGRlZXAgY2xvbmUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjbG9uaW5nIHZhbHVlcy5cbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgY3VzdG9taXplcmAuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZGVlcCBjbG9uZWQgdmFsdWUuXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciB1c2VycyA9IFtcbiAqICAgeyAndXNlcic6ICdiYXJuZXknIH0sXG4gKiAgIHsgJ3VzZXInOiAnZnJlZCcgfVxuICogXTtcbiAqXG4gKiB2YXIgZGVlcCA9IF8uY2xvbmVEZWVwKHVzZXJzKTtcbiAqIGRlZXBbMF0gPT09IHVzZXJzWzBdO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiAvLyB1c2luZyBhIGN1c3RvbWl6ZXIgY2FsbGJhY2tcbiAqIHZhciBlbCA9IF8uY2xvbmVEZWVwKGRvY3VtZW50LmJvZHksIGZ1bmN0aW9uKHZhbHVlKSB7XG4gKiAgIGlmIChfLmlzRWxlbWVudCh2YWx1ZSkpIHtcbiAqICAgICByZXR1cm4gdmFsdWUuY2xvbmVOb2RlKHRydWUpO1xuICogICB9XG4gKiB9KTtcbiAqXG4gKiBlbCA9PT0gZG9jdW1lbnQuYm9keVxuICogLy8gPT4gZmFsc2VcbiAqIGVsLm5vZGVOYW1lXG4gKiAvLyA9PiBCT0RZXG4gKiBlbC5jaGlsZE5vZGVzLmxlbmd0aDtcbiAqIC8vID0+IDIwXG4gKi9cbmZ1bmN0aW9uIGNsb25lRGVlcCh2YWx1ZSwgY3VzdG9taXplciwgdGhpc0FyZykge1xuICByZXR1cm4gdHlwZW9mIGN1c3RvbWl6ZXIgPT0gJ2Z1bmN0aW9uJ1xuICAgID8gYmFzZUNsb25lKHZhbHVlLCB0cnVlLCBiaW5kQ2FsbGJhY2soY3VzdG9taXplciwgdGhpc0FyZywgMSkpXG4gICAgOiBiYXNlQ2xvbmUodmFsdWUsIHRydWUpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNsb25lRGVlcDtcbiIsInZhciBpc0FycmF5TGlrZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzQXJyYXlMaWtlJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNPYmplY3RMaWtlJyksXG4gICAgc3VwcG9ydCA9IHJlcXVpcmUoJy4uL3N1cHBvcnQnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGFyZ3NUYWcgPSAnW29iamVjdCBBcmd1bWVudHNdJztcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cHM6Ly9wZW9wbGUubW96aWxsYS5vcmcvfmpvcmVuZG9yZmYvZXM2LWRyYWZ0Lmh0bWwjc2VjLW9iamVjdC5wcm90b3R5cGUudG9zdHJpbmcpXG4gKiBvZiB2YWx1ZXMuXG4gKi9cbnZhciBvYmpUb1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4vKiogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIHByb3BlcnR5SXNFbnVtZXJhYmxlID0gb2JqZWN0UHJvdG8ucHJvcGVydHlJc0VudW1lcmFibGU7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhbiBgYXJndW1lbnRzYCBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGNvcnJlY3RseSBjbGFzc2lmaWVkLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNBcmd1bWVudHMoZnVuY3Rpb24oKSB7IHJldHVybiBhcmd1bWVudHM7IH0oKSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0FyZ3VtZW50cyhbMSwgMiwgM10pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNBcmd1bWVudHModmFsdWUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaXNBcnJheUxpa2UodmFsdWUpICYmIG9ialRvU3RyaW5nLmNhbGwodmFsdWUpID09IGFyZ3NUYWc7XG59XG4vLyBGYWxsYmFjayBmb3IgZW52aXJvbm1lbnRzIHdpdGhvdXQgYSBgdG9TdHJpbmdUYWdgIGZvciBgYXJndW1lbnRzYCBvYmplY3RzLlxuaWYgKCFzdXBwb3J0LmFyZ3NUYWcpIHtcbiAgaXNBcmd1bWVudHMgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGlzQXJyYXlMaWtlKHZhbHVlKSAmJlxuICAgICAgaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgJ2NhbGxlZScpICYmICFwcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHZhbHVlLCAnY2FsbGVlJyk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNBcmd1bWVudHM7XG4iLCJ2YXIgZ2V0TmF0aXZlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvZ2V0TmF0aXZlJyksXG4gICAgaXNMZW5ndGggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0xlbmd0aCcpLFxuICAgIGlzT2JqZWN0TGlrZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzT2JqZWN0TGlrZScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYXJyYXlUYWcgPSAnW29iamVjdCBBcnJheV0nO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwczovL3Blb3BsZS5tb3ppbGxhLm9yZy9+am9yZW5kb3JmZi9lczYtZHJhZnQuaHRtbCNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlSXNBcnJheSA9IGdldE5hdGl2ZShBcnJheSwgJ2lzQXJyYXknKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGFuIGBBcnJheWAgb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzQXJyYXkoWzEsIDIsIDNdKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzQXJyYXkoZnVuY3Rpb24oKSB7IHJldHVybiBhcmd1bWVudHM7IH0oKSk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG52YXIgaXNBcnJheSA9IG5hdGl2ZUlzQXJyYXkgfHwgZnVuY3Rpb24odmFsdWUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaXNMZW5ndGgodmFsdWUubGVuZ3RoKSAmJiBvYmpUb1N0cmluZy5jYWxsKHZhbHVlKSA9PSBhcnJheVRhZztcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gaXNBcnJheTtcbiIsInZhciBpc0FyZ3VtZW50cyA9IHJlcXVpcmUoJy4vaXNBcmd1bWVudHMnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi9pc0FycmF5JyksXG4gICAgaXNBcnJheUxpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0FycmF5TGlrZScpLFxuICAgIGlzRnVuY3Rpb24gPSByZXF1aXJlKCcuL2lzRnVuY3Rpb24nKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc09iamVjdExpa2UnKSxcbiAgICBpc1N0cmluZyA9IHJlcXVpcmUoJy4vaXNTdHJpbmcnKSxcbiAgICBrZXlzID0gcmVxdWlyZSgnLi4vb2JqZWN0L2tleXMnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBlbXB0eS4gQSB2YWx1ZSBpcyBjb25zaWRlcmVkIGVtcHR5IHVubGVzcyBpdCBpcyBhblxuICogYGFyZ3VtZW50c2Agb2JqZWN0LCBhcnJheSwgc3RyaW5nLCBvciBqUXVlcnktbGlrZSBjb2xsZWN0aW9uIHdpdGggYSBsZW5ndGhcbiAqIGdyZWF0ZXIgdGhhbiBgMGAgb3IgYW4gb2JqZWN0IHdpdGggb3duIGVudW1lcmFibGUgcHJvcGVydGllcy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gdmFsdWUgVGhlIHZhbHVlIHRvIGluc3BlY3QuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBlbXB0eSwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzRW1wdHkobnVsbCk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0VtcHR5KHRydWUpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNFbXB0eSgxKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzRW1wdHkoWzEsIDIsIDNdKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc0VtcHR5KHsgJ2EnOiAxIH0pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNFbXB0eSh2YWx1ZSkge1xuICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGlmIChpc0FycmF5TGlrZSh2YWx1ZSkgJiYgKGlzQXJyYXkodmFsdWUpIHx8IGlzU3RyaW5nKHZhbHVlKSB8fCBpc0FyZ3VtZW50cyh2YWx1ZSkgfHxcbiAgICAgIChpc09iamVjdExpa2UodmFsdWUpICYmIGlzRnVuY3Rpb24odmFsdWUuc3BsaWNlKSkpKSB7XG4gICAgcmV0dXJuICF2YWx1ZS5sZW5ndGg7XG4gIH1cbiAgcmV0dXJuICFrZXlzKHZhbHVlKS5sZW5ndGg7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNFbXB0eTtcbiIsInZhciBiYXNlSXNGdW5jdGlvbiA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2Jhc2VJc0Z1bmN0aW9uJyksXG4gICAgZ2V0TmF0aXZlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvZ2V0TmF0aXZlJyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBmdW5jVGFnID0gJ1tvYmplY3QgRnVuY3Rpb25dJztcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cHM6Ly9wZW9wbGUubW96aWxsYS5vcmcvfmpvcmVuZG9yZmYvZXM2LWRyYWZ0Lmh0bWwjc2VjLW9iamVjdC5wcm90b3R5cGUudG9zdHJpbmcpXG4gKiBvZiB2YWx1ZXMuXG4gKi9cbnZhciBvYmpUb1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4vKiogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIFVpbnQ4QXJyYXkgPSBnZXROYXRpdmUoZ2xvYmFsLCAnVWludDhBcnJheScpO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgRnVuY3Rpb25gIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgY29ycmVjdGx5IGNsYXNzaWZpZWQsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc0Z1bmN0aW9uKF8pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNGdW5jdGlvbigvYWJjLyk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG52YXIgaXNGdW5jdGlvbiA9ICEoYmFzZUlzRnVuY3Rpb24oL3gvKSB8fCAoVWludDhBcnJheSAmJiAhYmFzZUlzRnVuY3Rpb24oVWludDhBcnJheSkpKSA/IGJhc2VJc0Z1bmN0aW9uIDogZnVuY3Rpb24odmFsdWUpIHtcbiAgLy8gVGhlIHVzZSBvZiBgT2JqZWN0I3RvU3RyaW5nYCBhdm9pZHMgaXNzdWVzIHdpdGggdGhlIGB0eXBlb2ZgIG9wZXJhdG9yXG4gIC8vIGluIG9sZGVyIHZlcnNpb25zIG9mIENocm9tZSBhbmQgU2FmYXJpIHdoaWNoIHJldHVybiAnZnVuY3Rpb24nIGZvciByZWdleGVzXG4gIC8vIGFuZCBTYWZhcmkgOCBlcXVpdmFsZW50cyB3aGljaCByZXR1cm4gJ29iamVjdCcgZm9yIHR5cGVkIGFycmF5IGNvbnN0cnVjdG9ycy5cbiAgcmV0dXJuIG9ialRvU3RyaW5nLmNhbGwodmFsdWUpID09IGZ1bmNUYWc7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGlzRnVuY3Rpb247XG4iLCJ2YXIgZXNjYXBlUmVnRXhwID0gcmVxdWlyZSgnLi4vc3RyaW5nL2VzY2FwZVJlZ0V4cCcpLFxuICAgIGlzSG9zdE9iamVjdCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzSG9zdE9iamVjdCcpLFxuICAgIGlzT2JqZWN0TGlrZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzT2JqZWN0TGlrZScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgZnVuY1RhZyA9ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBob3N0IGNvbnN0cnVjdG9ycyAoU2FmYXJpID4gNSkuICovXG52YXIgcmVJc0hvc3RDdG9yID0gL15cXFtvYmplY3QgLis/Q29uc3RydWN0b3JcXF0kLztcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIHJlc29sdmUgdGhlIGRlY29tcGlsZWQgc291cmNlIG9mIGZ1bmN0aW9ucy4gKi9cbnZhciBmblRvU3RyaW5nID0gRnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgW2B0b1N0cmluZ1RhZ2BdKGh0dHBzOi8vcGVvcGxlLm1vemlsbGEub3JnL35qb3JlbmRvcmZmL2VzNi1kcmFmdC5odG1sI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IGlmIGEgbWV0aG9kIGlzIG5hdGl2ZS4gKi9cbnZhciByZUlzTmF0aXZlID0gUmVnRXhwKCdeJyArXG4gIGVzY2FwZVJlZ0V4cChmblRvU3RyaW5nLmNhbGwoaGFzT3duUHJvcGVydHkpKVxuICAucmVwbGFjZSgvaGFzT3duUHJvcGVydHl8KGZ1bmN0aW9uKS4qPyg/PVxcXFxcXCgpfCBmb3IgLis/KD89XFxcXFxcXSkvZywgJyQxLio/JykgKyAnJCdcbik7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBuYXRpdmUgZnVuY3Rpb24uXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgbmF0aXZlIGZ1bmN0aW9uLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNOYXRpdmUoQXJyYXkucHJvdG90eXBlLnB1c2gpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNOYXRpdmUoXyk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc05hdGl2ZSh2YWx1ZSkge1xuICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAob2JqVG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT0gZnVuY1RhZykge1xuICAgIHJldHVybiByZUlzTmF0aXZlLnRlc3QoZm5Ub1N0cmluZy5jYWxsKHZhbHVlKSk7XG4gIH1cbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgKGlzSG9zdE9iamVjdCh2YWx1ZSkgPyByZUlzTmF0aXZlIDogcmVJc0hvc3RDdG9yKS50ZXN0KHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc05hdGl2ZTtcbiIsIi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgdGhlIFtsYW5ndWFnZSB0eXBlXShodHRwczovL2VzNS5naXRodWIuaW8vI3g4KSBvZiBgT2JqZWN0YC5cbiAqIChlLmcuIGFycmF5cywgZnVuY3Rpb25zLCBvYmplY3RzLCByZWdleGVzLCBgbmV3IE51bWJlcigwKWAsIGFuZCBgbmV3IFN0cmluZygnJylgKVxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc09iamVjdCh7fSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdChbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3QoMSk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc09iamVjdCh2YWx1ZSkge1xuICAvLyBBdm9pZCBhIFY4IEpJVCBidWcgaW4gQ2hyb21lIDE5LTIwLlxuICAvLyBTZWUgaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC92OC9pc3N1ZXMvZGV0YWlsP2lkPTIyOTEgZm9yIG1vcmUgZGV0YWlscy5cbiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gIHJldHVybiAhIXZhbHVlICYmICh0eXBlID09ICdvYmplY3QnIHx8IHR5cGUgPT0gJ2Z1bmN0aW9uJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNPYmplY3Q7XG4iLCJ2YXIgZ2V0TmF0aXZlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvZ2V0TmF0aXZlJyksXG4gICAgaXNBcmd1bWVudHMgPSByZXF1aXJlKCcuL2lzQXJndW1lbnRzJyksXG4gICAgc2hpbUlzUGxhaW5PYmplY3QgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9zaGltSXNQbGFpbk9iamVjdCcpLFxuICAgIHN1cHBvcnQgPSByZXF1aXJlKCcuLi9zdXBwb3J0Jyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RUYWcgPSAnW29iamVjdCBPYmplY3RdJztcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cHM6Ly9wZW9wbGUubW96aWxsYS5vcmcvfmpvcmVuZG9yZmYvZXM2LWRyYWZ0Lmh0bWwjc2VjLW9iamVjdC5wcm90b3R5cGUudG9zdHJpbmcpXG4gKiBvZiB2YWx1ZXMuXG4gKi9cbnZhciBvYmpUb1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4vKiogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIGdldFByb3RvdHlwZU9mID0gZ2V0TmF0aXZlKE9iamVjdCwgJ2dldFByb3RvdHlwZU9mJyk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBwbGFpbiBvYmplY3QsIHRoYXQgaXMsIGFuIG9iamVjdCBjcmVhdGVkIGJ5IHRoZVxuICogYE9iamVjdGAgY29uc3RydWN0b3Igb3Igb25lIHdpdGggYSBgW1tQcm90b3R5cGVdXWAgb2YgYG51bGxgLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBhc3N1bWVzIG9iamVjdHMgY3JlYXRlZCBieSB0aGUgYE9iamVjdGAgY29uc3RydWN0b3JcbiAqIGhhdmUgbm8gaW5oZXJpdGVkIGVudW1lcmFibGUgcHJvcGVydGllcy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBwbGFpbiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogZnVuY3Rpb24gRm9vKCkge1xuICogICB0aGlzLmEgPSAxO1xuICogfVxuICpcbiAqIF8uaXNQbGFpbk9iamVjdChuZXcgRm9vKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc1BsYWluT2JqZWN0KFsxLCAyLCAzXSk7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uaXNQbGFpbk9iamVjdCh7ICd4JzogMCwgJ3knOiAwIH0pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNQbGFpbk9iamVjdChPYmplY3QuY3JlYXRlKG51bGwpKTtcbiAqIC8vID0+IHRydWVcbiAqL1xudmFyIGlzUGxhaW5PYmplY3QgPSAhZ2V0UHJvdG90eXBlT2YgPyBzaGltSXNQbGFpbk9iamVjdCA6IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIGlmICghKHZhbHVlICYmIG9ialRvU3RyaW5nLmNhbGwodmFsdWUpID09IG9iamVjdFRhZykgfHwgKCFzdXBwb3J0LmFyZ3NUYWcgJiYgaXNBcmd1bWVudHModmFsdWUpKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB2YXIgdmFsdWVPZiA9IGdldE5hdGl2ZSh2YWx1ZSwgJ3ZhbHVlT2YnKSxcbiAgICAgIG9ialByb3RvID0gdmFsdWVPZiAmJiAob2JqUHJvdG8gPSBnZXRQcm90b3R5cGVPZih2YWx1ZU9mKSkgJiYgZ2V0UHJvdG90eXBlT2Yob2JqUHJvdG8pO1xuXG4gIHJldHVybiBvYmpQcm90b1xuICAgID8gKHZhbHVlID09IG9ialByb3RvIHx8IGdldFByb3RvdHlwZU9mKHZhbHVlKSA9PSBvYmpQcm90bylcbiAgICA6IHNoaW1Jc1BsYWluT2JqZWN0KHZhbHVlKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gaXNQbGFpbk9iamVjdDtcbiIsInZhciBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc09iamVjdExpa2UnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwczovL3Blb3BsZS5tb3ppbGxhLm9yZy9+am9yZW5kb3JmZi9lczYtZHJhZnQuaHRtbCNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBTdHJpbmdgIHByaW1pdGl2ZSBvciBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGNvcnJlY3RseSBjbGFzc2lmaWVkLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNTdHJpbmcoJ2FiYycpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNTdHJpbmcoMSk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc1N0cmluZyh2YWx1ZSkge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09ICdzdHJpbmcnIHx8IChpc09iamVjdExpa2UodmFsdWUpICYmIG9ialRvU3RyaW5nLmNhbGwodmFsdWUpID09IHN0cmluZ1RhZyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNTdHJpbmc7XG4iLCJ2YXIgaXNMZW5ndGggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0xlbmd0aCcpLFxuICAgIGlzT2JqZWN0TGlrZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzT2JqZWN0TGlrZScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYXJnc1RhZyA9ICdbb2JqZWN0IEFyZ3VtZW50c10nLFxuICAgIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJyxcbiAgICBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgZXJyb3JUYWcgPSAnW29iamVjdCBFcnJvcl0nLFxuICAgIGZ1bmNUYWcgPSAnW29iamVjdCBGdW5jdGlvbl0nLFxuICAgIG1hcFRhZyA9ICdbb2JqZWN0IE1hcF0nLFxuICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nLFxuICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLFxuICAgIHNldFRhZyA9ICdbb2JqZWN0IFNldF0nLFxuICAgIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nLFxuICAgIHdlYWtNYXBUYWcgPSAnW29iamVjdCBXZWFrTWFwXSc7XG5cbnZhciBhcnJheUJ1ZmZlclRhZyA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsXG4gICAgZmxvYXQzMlRhZyA9ICdbb2JqZWN0IEZsb2F0MzJBcnJheV0nLFxuICAgIGZsb2F0NjRUYWcgPSAnW29iamVjdCBGbG9hdDY0QXJyYXldJyxcbiAgICBpbnQ4VGFnID0gJ1tvYmplY3QgSW50OEFycmF5XScsXG4gICAgaW50MTZUYWcgPSAnW29iamVjdCBJbnQxNkFycmF5XScsXG4gICAgaW50MzJUYWcgPSAnW29iamVjdCBJbnQzMkFycmF5XScsXG4gICAgdWludDhUYWcgPSAnW29iamVjdCBVaW50OEFycmF5XScsXG4gICAgdWludDhDbGFtcGVkVGFnID0gJ1tvYmplY3QgVWludDhDbGFtcGVkQXJyYXldJyxcbiAgICB1aW50MTZUYWcgPSAnW29iamVjdCBVaW50MTZBcnJheV0nLFxuICAgIHVpbnQzMlRhZyA9ICdbb2JqZWN0IFVpbnQzMkFycmF5XSc7XG5cbi8qKiBVc2VkIHRvIGlkZW50aWZ5IGB0b1N0cmluZ1RhZ2AgdmFsdWVzIG9mIHR5cGVkIGFycmF5cy4gKi9cbnZhciB0eXBlZEFycmF5VGFncyA9IHt9O1xudHlwZWRBcnJheVRhZ3NbZmxvYXQzMlRhZ10gPSB0eXBlZEFycmF5VGFnc1tmbG9hdDY0VGFnXSA9XG50eXBlZEFycmF5VGFnc1tpbnQ4VGFnXSA9IHR5cGVkQXJyYXlUYWdzW2ludDE2VGFnXSA9XG50eXBlZEFycmF5VGFnc1tpbnQzMlRhZ10gPSB0eXBlZEFycmF5VGFnc1t1aW50OFRhZ10gPVxudHlwZWRBcnJheVRhZ3NbdWludDhDbGFtcGVkVGFnXSA9IHR5cGVkQXJyYXlUYWdzW3VpbnQxNlRhZ10gPVxudHlwZWRBcnJheVRhZ3NbdWludDMyVGFnXSA9IHRydWU7XG50eXBlZEFycmF5VGFnc1thcmdzVGFnXSA9IHR5cGVkQXJyYXlUYWdzW2FycmF5VGFnXSA9XG50eXBlZEFycmF5VGFnc1thcnJheUJ1ZmZlclRhZ10gPSB0eXBlZEFycmF5VGFnc1tib29sVGFnXSA9XG50eXBlZEFycmF5VGFnc1tkYXRlVGFnXSA9IHR5cGVkQXJyYXlUYWdzW2Vycm9yVGFnXSA9XG50eXBlZEFycmF5VGFnc1tmdW5jVGFnXSA9IHR5cGVkQXJyYXlUYWdzW21hcFRhZ10gPVxudHlwZWRBcnJheVRhZ3NbbnVtYmVyVGFnXSA9IHR5cGVkQXJyYXlUYWdzW29iamVjdFRhZ10gPVxudHlwZWRBcnJheVRhZ3NbcmVnZXhwVGFnXSA9IHR5cGVkQXJyYXlUYWdzW3NldFRhZ10gPVxudHlwZWRBcnJheVRhZ3Nbc3RyaW5nVGFnXSA9IHR5cGVkQXJyYXlUYWdzW3dlYWtNYXBUYWddID0gZmFsc2U7XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgW2B0b1N0cmluZ1RhZ2BdKGh0dHBzOi8vcGVvcGxlLm1vemlsbGEub3JnL35qb3JlbmRvcmZmL2VzNi1kcmFmdC5odG1sI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgdHlwZWQgYXJyYXkuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGNvcnJlY3RseSBjbGFzc2lmaWVkLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNUeXBlZEFycmF5KG5ldyBVaW50OEFycmF5KTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzVHlwZWRBcnJheShbXSk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc1R5cGVkQXJyYXkodmFsdWUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaXNMZW5ndGgodmFsdWUubGVuZ3RoKSAmJiAhIXR5cGVkQXJyYXlUYWdzW29ialRvU3RyaW5nLmNhbGwodmFsdWUpXTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1R5cGVkQXJyYXk7XG4iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGB1bmRlZmluZWRgLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBgdW5kZWZpbmVkYCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzVW5kZWZpbmVkKHZvaWQgMCk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1VuZGVmaW5lZChudWxsKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzVW5kZWZpbmVkKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSA9PT0gdW5kZWZpbmVkO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzVW5kZWZpbmVkO1xuIiwidmFyIGdldE5hdGl2ZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2dldE5hdGl2ZScpLFxuICAgIGlzQXJyYXlMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNBcnJheUxpa2UnKSxcbiAgICBpc09iamVjdCA9IHJlcXVpcmUoJy4uL2xhbmcvaXNPYmplY3QnKSxcbiAgICBzaGltS2V5cyA9IHJlcXVpcmUoJy4uL2ludGVybmFsL3NoaW1LZXlzJyksXG4gICAgc3VwcG9ydCA9IHJlcXVpcmUoJy4uL3N1cHBvcnQnKTtcblxuLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVLZXlzID0gZ2V0TmF0aXZlKE9iamVjdCwgJ2tleXMnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IG9mIHRoZSBvd24gZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBvZiBgb2JqZWN0YC5cbiAqXG4gKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy4gU2VlIHRoZVxuICogW0VTIHNwZWNdKGh0dHBzOi8vcGVvcGxlLm1vemlsbGEub3JnL35qb3JlbmRvcmZmL2VzNi1kcmFmdC5odG1sI3NlYy1vYmplY3Qua2V5cylcbiAqIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBPYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gKiBAZXhhbXBsZVxuICpcbiAqIGZ1bmN0aW9uIEZvbygpIHtcbiAqICAgdGhpcy5hID0gMTtcbiAqICAgdGhpcy5iID0gMjtcbiAqIH1cbiAqXG4gKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICpcbiAqIF8ua2V5cyhuZXcgRm9vKTtcbiAqIC8vID0+IFsnYScsICdiJ10gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAqXG4gKiBfLmtleXMoJ2hpJyk7XG4gKiAvLyA9PiBbJzAnLCAnMSddXG4gKi9cbnZhciBrZXlzID0gIW5hdGl2ZUtleXMgPyBzaGltS2V5cyA6IGZ1bmN0aW9uKG9iamVjdCkge1xuICB2YXIgQ3RvciA9IG9iamVjdCA9PSBudWxsID8gbnVsbCA6IG9iamVjdC5jb25zdHJ1Y3RvcjtcbiAgaWYgKCh0eXBlb2YgQ3RvciA9PSAnZnVuY3Rpb24nICYmIEN0b3IucHJvdG90eXBlID09PSBvYmplY3QpIHx8XG4gICAgICAodHlwZW9mIG9iamVjdCA9PSAnZnVuY3Rpb24nID8gc3VwcG9ydC5lbnVtUHJvdG90eXBlcyA6IGlzQXJyYXlMaWtlKG9iamVjdCkpKSB7XG4gICAgcmV0dXJuIHNoaW1LZXlzKG9iamVjdCk7XG4gIH1cbiAgcmV0dXJuIGlzT2JqZWN0KG9iamVjdCkgPyBuYXRpdmVLZXlzKG9iamVjdCkgOiBbXTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ga2V5cztcbiIsInZhciBhcnJheUVhY2ggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9hcnJheUVhY2gnKSxcbiAgICBpc0FyZ3VtZW50cyA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcmd1bWVudHMnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FycmF5JyksXG4gICAgaXNGdW5jdGlvbiA9IHJlcXVpcmUoJy4uL2xhbmcvaXNGdW5jdGlvbicpLFxuICAgIGlzSW5kZXggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0luZGV4JyksXG4gICAgaXNMZW5ndGggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0xlbmd0aCcpLFxuICAgIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vbGFuZy9pc09iamVjdCcpLFxuICAgIGlzU3RyaW5nID0gcmVxdWlyZSgnLi4vbGFuZy9pc1N0cmluZycpLFxuICAgIHN1cHBvcnQgPSByZXF1aXJlKCcuLi9zdXBwb3J0Jyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBhcnJheVRhZyA9ICdbb2JqZWN0IEFycmF5XScsXG4gICAgYm9vbFRhZyA9ICdbb2JqZWN0IEJvb2xlYW5dJyxcbiAgICBkYXRlVGFnID0gJ1tvYmplY3QgRGF0ZV0nLFxuICAgIGVycm9yVGFnID0gJ1tvYmplY3QgRXJyb3JdJyxcbiAgICBmdW5jVGFnID0gJ1tvYmplY3QgRnVuY3Rpb25dJyxcbiAgICBudW1iZXJUYWcgPSAnW29iamVjdCBOdW1iZXJdJyxcbiAgICBvYmplY3RUYWcgPSAnW29iamVjdCBPYmplY3RdJyxcbiAgICByZWdleHBUYWcgPSAnW29iamVjdCBSZWdFeHBdJyxcbiAgICBzdHJpbmdUYWcgPSAnW29iamVjdCBTdHJpbmddJztcblxuLyoqIFVzZWQgdG8gZml4IHRoZSBKU2NyaXB0IGBbW0RvbnRFbnVtXV1gIGJ1Zy4gKi9cbnZhciBzaGFkb3dQcm9wcyA9IFtcbiAgJ2NvbnN0cnVjdG9yJywgJ2hhc093blByb3BlcnR5JywgJ2lzUHJvdG90eXBlT2YnLCAncHJvcGVydHlJc0VudW1lcmFibGUnLFxuICAndG9Mb2NhbGVTdHJpbmcnLCAndG9TdHJpbmcnLCAndmFsdWVPZidcbl07XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgZXJyb3JQcm90byA9IEVycm9yLnByb3RvdHlwZSxcbiAgICBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGUsXG4gICAgc3RyaW5nUHJvdG8gPSBTdHJpbmcucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgW2B0b1N0cmluZ1RhZ2BdKGh0dHBzOi8vcGVvcGxlLm1vemlsbGEub3JnL35qb3JlbmRvcmZmL2VzNi1kcmFmdC5odG1sI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqIFVzZWQgdG8gYXZvaWQgaXRlcmF0aW5nIG92ZXIgbm9uLWVudW1lcmFibGUgcHJvcGVydGllcyBpbiBJRSA8IDkuICovXG52YXIgbm9uRW51bVByb3BzID0ge307XG5ub25FbnVtUHJvcHNbYXJyYXlUYWddID0gbm9uRW51bVByb3BzW2RhdGVUYWddID0gbm9uRW51bVByb3BzW251bWJlclRhZ10gPSB7ICdjb25zdHJ1Y3Rvcic6IHRydWUsICd0b0xvY2FsZVN0cmluZyc6IHRydWUsICd0b1N0cmluZyc6IHRydWUsICd2YWx1ZU9mJzogdHJ1ZSB9O1xubm9uRW51bVByb3BzW2Jvb2xUYWddID0gbm9uRW51bVByb3BzW3N0cmluZ1RhZ10gPSB7ICdjb25zdHJ1Y3Rvcic6IHRydWUsICd0b1N0cmluZyc6IHRydWUsICd2YWx1ZU9mJzogdHJ1ZSB9O1xubm9uRW51bVByb3BzW2Vycm9yVGFnXSA9IG5vbkVudW1Qcm9wc1tmdW5jVGFnXSA9IG5vbkVudW1Qcm9wc1tyZWdleHBUYWddID0geyAnY29uc3RydWN0b3InOiB0cnVlLCAndG9TdHJpbmcnOiB0cnVlIH07XG5ub25FbnVtUHJvcHNbb2JqZWN0VGFnXSA9IHsgJ2NvbnN0cnVjdG9yJzogdHJ1ZSB9O1xuXG5hcnJheUVhY2goc2hhZG93UHJvcHMsIGZ1bmN0aW9uKGtleSkge1xuICBmb3IgKHZhciB0YWcgaW4gbm9uRW51bVByb3BzKSB7XG4gICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwobm9uRW51bVByb3BzLCB0YWcpKSB7XG4gICAgICB2YXIgcHJvcHMgPSBub25FbnVtUHJvcHNbdGFnXTtcbiAgICAgIHByb3BzW2tleV0gPSBoYXNPd25Qcm9wZXJ0eS5jYWxsKHByb3BzLCBrZXkpO1xuICAgIH1cbiAgfVxufSk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGFuZCBpbmhlcml0ZWQgZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBvZiBgb2JqZWN0YC5cbiAqXG4gKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IE9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAqIEBleGFtcGxlXG4gKlxuICogZnVuY3Rpb24gRm9vKCkge1xuICogICB0aGlzLmEgPSAxO1xuICogICB0aGlzLmIgPSAyO1xuICogfVxuICpcbiAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gKlxuICogXy5rZXlzSW4obmV3IEZvbyk7XG4gKiAvLyA9PiBbJ2EnLCAnYicsICdjJ10gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAqL1xuZnVuY3Rpb24ga2V5c0luKG9iamVjdCkge1xuICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICByZXR1cm4gW107XG4gIH1cbiAgaWYgKCFpc09iamVjdChvYmplY3QpKSB7XG4gICAgb2JqZWN0ID0gT2JqZWN0KG9iamVjdCk7XG4gIH1cbiAgdmFyIGxlbmd0aCA9IG9iamVjdC5sZW5ndGg7XG5cbiAgbGVuZ3RoID0gKGxlbmd0aCAmJiBpc0xlbmd0aChsZW5ndGgpICYmXG4gICAgKGlzQXJyYXkob2JqZWN0KSB8fCBpc0FyZ3VtZW50cyhvYmplY3QpIHx8IGlzU3RyaW5nKG9iamVjdCkpICYmIGxlbmd0aCkgfHwgMDtcblxuICB2YXIgQ3RvciA9IG9iamVjdC5jb25zdHJ1Y3RvcixcbiAgICAgIGluZGV4ID0gLTEsXG4gICAgICBwcm90byA9IChpc0Z1bmN0aW9uKEN0b3IpICYmIEN0b3IucHJvdG90eXBlKSB8fCBvYmplY3RQcm90byxcbiAgICAgIGlzUHJvdG8gPSBwcm90byA9PT0gb2JqZWN0LFxuICAgICAgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKSxcbiAgICAgIHNraXBJbmRleGVzID0gbGVuZ3RoID4gMCxcbiAgICAgIHNraXBFcnJvclByb3BzID0gc3VwcG9ydC5lbnVtRXJyb3JQcm9wcyAmJiAob2JqZWN0ID09PSBlcnJvclByb3RvIHx8IG9iamVjdCBpbnN0YW5jZW9mIEVycm9yKSxcbiAgICAgIHNraXBQcm90byA9IHN1cHBvcnQuZW51bVByb3RvdHlwZXMgJiYgaXNGdW5jdGlvbihvYmplY3QpO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgcmVzdWx0W2luZGV4XSA9IChpbmRleCArICcnKTtcbiAgfVxuICAvLyBsb2Rhc2ggc2tpcHMgdGhlIGBjb25zdHJ1Y3RvcmAgcHJvcGVydHkgd2hlbiBpdCBpbmZlcnMgaXQgaXMgaXRlcmF0aW5nXG4gIC8vIG92ZXIgYSBgcHJvdG90eXBlYCBvYmplY3QgYmVjYXVzZSBJRSA8IDkgY2FuJ3Qgc2V0IHRoZSBgW1tFbnVtZXJhYmxlXV1gXG4gIC8vIGF0dHJpYnV0ZSBvZiBhbiBleGlzdGluZyBwcm9wZXJ0eSBhbmQgdGhlIGBjb25zdHJ1Y3RvcmAgcHJvcGVydHkgb2YgYVxuICAvLyBwcm90b3R5cGUgZGVmYXVsdHMgdG8gbm9uLWVudW1lcmFibGUuXG4gIGZvciAodmFyIGtleSBpbiBvYmplY3QpIHtcbiAgICBpZiAoIShza2lwUHJvdG8gJiYga2V5ID09ICdwcm90b3R5cGUnKSAmJlxuICAgICAgICAhKHNraXBFcnJvclByb3BzICYmIChrZXkgPT0gJ21lc3NhZ2UnIHx8IGtleSA9PSAnbmFtZScpKSAmJlxuICAgICAgICAhKHNraXBJbmRleGVzICYmIGlzSW5kZXgoa2V5LCBsZW5ndGgpKSAmJlxuICAgICAgICAhKGtleSA9PSAnY29uc3RydWN0b3InICYmIChpc1Byb3RvIHx8ICFoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSkpKSB7XG4gICAgICByZXN1bHQucHVzaChrZXkpO1xuICAgIH1cbiAgfVxuICBpZiAoc3VwcG9ydC5ub25FbnVtU2hhZG93cyAmJiBvYmplY3QgIT09IG9iamVjdFByb3RvKSB7XG4gICAgdmFyIHRhZyA9IG9iamVjdCA9PT0gc3RyaW5nUHJvdG8gPyBzdHJpbmdUYWcgOiAob2JqZWN0ID09PSBlcnJvclByb3RvID8gZXJyb3JUYWcgOiBvYmpUb1N0cmluZy5jYWxsKG9iamVjdCkpLFxuICAgICAgICBub25FbnVtcyA9IG5vbkVudW1Qcm9wc1t0YWddIHx8IG5vbkVudW1Qcm9wc1tvYmplY3RUYWddO1xuXG4gICAgaWYgKHRhZyA9PSBvYmplY3RUYWcpIHtcbiAgICAgIHByb3RvID0gb2JqZWN0UHJvdG87XG4gICAgfVxuICAgIGxlbmd0aCA9IHNoYWRvd1Byb3BzLmxlbmd0aDtcbiAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgIGtleSA9IHNoYWRvd1Byb3BzW2xlbmd0aF07XG4gICAgICB2YXIgbm9uRW51bSA9IG5vbkVudW1zW2tleV07XG4gICAgICBpZiAoIShpc1Byb3RvICYmIG5vbkVudW0pICYmXG4gICAgICAgICAgKG5vbkVudW0gPyBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSA6IG9iamVjdFtrZXldICE9PSBwcm90b1trZXldKSkge1xuICAgICAgICByZXN1bHQucHVzaChrZXkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGtleXNJbjtcbiIsInZhciBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyksXG4gICAgdG9PYmplY3QgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC90b09iamVjdCcpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSB0d28gZGltZW5zaW9uYWwgYXJyYXkgb2YgdGhlIGtleS12YWx1ZSBwYWlycyBmb3IgYG9iamVjdGAsXG4gKiBlLmcuIGBbW2tleTEsIHZhbHVlMV0sIFtrZXkyLCB2YWx1ZTJdXWAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBPYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGtleS12YWx1ZSBwYWlycy5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5wYWlycyh7ICdiYXJuZXknOiAzNiwgJ2ZyZWQnOiA0MCB9KTtcbiAqIC8vID0+IFtbJ2Jhcm5leScsIDM2XSwgWydmcmVkJywgNDBdXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICovXG5mdW5jdGlvbiBwYWlycyhvYmplY3QpIHtcbiAgb2JqZWN0ID0gdG9PYmplY3Qob2JqZWN0KTtcblxuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIHByb3BzID0ga2V5cyhvYmplY3QpLFxuICAgICAgbGVuZ3RoID0gcHJvcHMubGVuZ3RoLFxuICAgICAgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKTtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHZhciBrZXkgPSBwcm9wc1tpbmRleF07XG4gICAgcmVzdWx0W2luZGV4XSA9IFtrZXksIG9iamVjdFtrZXldXTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHBhaXJzO1xuIiwidmFyIGJhc2VWYWx1ZXMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlVmFsdWVzJyksXG4gICAga2V5cyA9IHJlcXVpcmUoJy4va2V5cycpO1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBlbnVtZXJhYmxlIHByb3BlcnR5IHZhbHVlcyBvZiBgb2JqZWN0YC5cbiAqXG4gKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IE9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSB2YWx1ZXMuXG4gKiBAZXhhbXBsZVxuICpcbiAqIGZ1bmN0aW9uIEZvbygpIHtcbiAqICAgdGhpcy5hID0gMTtcbiAqICAgdGhpcy5iID0gMjtcbiAqIH1cbiAqXG4gKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICpcbiAqIF8udmFsdWVzKG5ldyBGb28pO1xuICogLy8gPT4gWzEsIDJdIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gKlxuICogXy52YWx1ZXMoJ2hpJyk7XG4gKiAvLyA9PiBbJ2gnLCAnaSddXG4gKi9cbmZ1bmN0aW9uIHZhbHVlcyhvYmplY3QpIHtcbiAgcmV0dXJuIGJhc2VWYWx1ZXMob2JqZWN0LCBrZXlzKG9iamVjdCkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHZhbHVlcztcbiIsInZhciBiYXNlVG9TdHJpbmcgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlVG9TdHJpbmcnKTtcblxuLyoqXG4gKiBVc2VkIHRvIG1hdGNoIGBSZWdFeHBgIFtzcGVjaWFsIGNoYXJhY3RlcnNdKGh0dHA6Ly93d3cucmVndWxhci1leHByZXNzaW9ucy5pbmZvL2NoYXJhY3RlcnMuaHRtbCNzcGVjaWFsKS5cbiAqIEluIGFkZGl0aW9uIHRvIHNwZWNpYWwgY2hhcmFjdGVycyB0aGUgZm9yd2FyZCBzbGFzaCBpcyBlc2NhcGVkIHRvIGFsbG93IGZvclxuICogZWFzaWVyIGBldmFsYCB1c2UgYW5kIGBGdW5jdGlvbmAgY29tcGlsYXRpb24uXG4gKi9cbnZhciByZVJlZ0V4cENoYXJzID0gL1suKis/XiR7fSgpfFtcXF1cXC9cXFxcXS9nLFxuICAgIHJlSGFzUmVnRXhwQ2hhcnMgPSBSZWdFeHAocmVSZWdFeHBDaGFycy5zb3VyY2UpO1xuXG4vKipcbiAqIEVzY2FwZXMgdGhlIGBSZWdFeHBgIHNwZWNpYWwgY2hhcmFjdGVycyBcIlxcXCIsIFwiL1wiLCBcIl5cIiwgXCIkXCIsIFwiLlwiLCBcInxcIiwgXCI/XCIsXG4gKiBcIipcIiwgXCIrXCIsIFwiKFwiLCBcIilcIiwgXCJbXCIsIFwiXVwiLCBcIntcIiBhbmQgXCJ9XCIgaW4gYHN0cmluZ2AuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBTdHJpbmdcbiAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGVzY2FwZS5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGVzY2FwZWQgc3RyaW5nLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmVzY2FwZVJlZ0V4cCgnW2xvZGFzaF0oaHR0cHM6Ly9sb2Rhc2guY29tLyknKTtcbiAqIC8vID0+ICdcXFtsb2Rhc2hcXF1cXChodHRwczpcXC9cXC9sb2Rhc2hcXC5jb21cXC9cXCknXG4gKi9cbmZ1bmN0aW9uIGVzY2FwZVJlZ0V4cChzdHJpbmcpIHtcbiAgc3RyaW5nID0gYmFzZVRvU3RyaW5nKHN0cmluZyk7XG4gIHJldHVybiAoc3RyaW5nICYmIHJlSGFzUmVnRXhwQ2hhcnMudGVzdChzdHJpbmcpKVxuICAgID8gc3RyaW5nLnJlcGxhY2UocmVSZWdFeHBDaGFycywgJ1xcXFwkJicpXG4gICAgOiBzdHJpbmc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZXNjYXBlUmVnRXhwO1xuIiwiLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGFyZ3NUYWcgPSAnW29iamVjdCBBcmd1bWVudHNdJyxcbiAgICBvYmplY3RUYWcgPSAnW29iamVjdCBPYmplY3RdJztcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBhcnJheVByb3RvID0gQXJyYXkucHJvdG90eXBlLFxuICAgIGVycm9yUHJvdG8gPSBFcnJvci5wcm90b3R5cGUsXG4gICAgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBkZXRlY3QgRE9NIHN1cHBvcnQuICovXG52YXIgZG9jdW1lbnQgPSAoZG9jdW1lbnQgPSBnbG9iYWwud2luZG93KSA/IGRvY3VtZW50LmRvY3VtZW50IDogbnVsbDtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwczovL3Blb3BsZS5tb3ppbGxhLm9yZy9+am9yZW5kb3JmZi9lczYtZHJhZnQuaHRtbCNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgcHJvcGVydHlJc0VudW1lcmFibGUgPSBvYmplY3RQcm90by5wcm9wZXJ0eUlzRW51bWVyYWJsZSxcbiAgICBzcGxpY2UgPSBhcnJheVByb3RvLnNwbGljZTtcblxuLyoqXG4gKiBBbiBvYmplY3QgZW52aXJvbm1lbnQgZmVhdHVyZSBmbGFncy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHR5cGUgT2JqZWN0XG4gKi9cbnZhciBzdXBwb3J0ID0ge307XG5cbihmdW5jdGlvbih4KSB7XG4gIHZhciBDdG9yID0gZnVuY3Rpb24oKSB7IHRoaXMueCA9IHg7IH0sXG4gICAgICBvYmplY3QgPSB7ICcwJzogeCwgJ2xlbmd0aCc6IHggfSxcbiAgICAgIHByb3BzID0gW107XG5cbiAgQ3Rvci5wcm90b3R5cGUgPSB7ICd2YWx1ZU9mJzogeCwgJ3knOiB4IH07XG4gIGZvciAodmFyIGtleSBpbiBuZXcgQ3RvcikgeyBwcm9wcy5wdXNoKGtleSk7IH1cblxuICAvKipcbiAgICogRGV0ZWN0IGlmIHRoZSBgdG9TdHJpbmdUYWdgIG9mIGBhcmd1bWVudHNgIG9iamVjdHMgaXMgcmVzb2x2YWJsZVxuICAgKiAoYWxsIGJ1dCBGaXJlZm94IDwgNCwgSUUgPCA5KS5cbiAgICpcbiAgICogQG1lbWJlck9mIF8uc3VwcG9ydFxuICAgKiBAdHlwZSBib29sZWFuXG4gICAqL1xuICBzdXBwb3J0LmFyZ3NUYWcgPSBvYmpUb1N0cmluZy5jYWxsKGFyZ3VtZW50cykgPT0gYXJnc1RhZztcblxuICAvKipcbiAgICogRGV0ZWN0IGlmIGBuYW1lYCBvciBgbWVzc2FnZWAgcHJvcGVydGllcyBvZiBgRXJyb3IucHJvdG90eXBlYCBhcmVcbiAgICogZW51bWVyYWJsZSBieSBkZWZhdWx0IChJRSA8IDksIFNhZmFyaSA8IDUuMSkuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBfLnN1cHBvcnRcbiAgICogQHR5cGUgYm9vbGVhblxuICAgKi9cbiAgc3VwcG9ydC5lbnVtRXJyb3JQcm9wcyA9IHByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwoZXJyb3JQcm90bywgJ21lc3NhZ2UnKSB8fFxuICAgIHByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwoZXJyb3JQcm90bywgJ25hbWUnKTtcblxuICAvKipcbiAgICogRGV0ZWN0IGlmIGBwcm90b3R5cGVgIHByb3BlcnRpZXMgYXJlIGVudW1lcmFibGUgYnkgZGVmYXVsdC5cbiAgICpcbiAgICogRmlyZWZveCA8IDMuNiwgT3BlcmEgPiA5LjUwIC0gT3BlcmEgPCAxMS42MCwgYW5kIFNhZmFyaSA8IDUuMVxuICAgKiAoaWYgdGhlIHByb3RvdHlwZSBvciBhIHByb3BlcnR5IG9uIHRoZSBwcm90b3R5cGUgaGFzIGJlZW4gc2V0KVxuICAgKiBpbmNvcnJlY3RseSBzZXQgdGhlIGBbW0VudW1lcmFibGVdXWAgdmFsdWUgb2YgYSBmdW5jdGlvbidzIGBwcm90b3R5cGVgXG4gICAqIHByb3BlcnR5IHRvIGB0cnVlYC5cbiAgICpcbiAgICogQG1lbWJlck9mIF8uc3VwcG9ydFxuICAgKiBAdHlwZSBib29sZWFuXG4gICAqL1xuICBzdXBwb3J0LmVudW1Qcm90b3R5cGVzID0gcHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChDdG9yLCAncHJvdG90eXBlJyk7XG5cbiAgLyoqXG4gICAqIERldGVjdCBpZiB0aGUgYHRvU3RyaW5nVGFnYCBvZiBET00gbm9kZXMgaXMgcmVzb2x2YWJsZSAoYWxsIGJ1dCBJRSA8IDkpLlxuICAgKlxuICAgKiBAbWVtYmVyT2YgXy5zdXBwb3J0XG4gICAqIEB0eXBlIGJvb2xlYW5cbiAgICovXG4gIHN1cHBvcnQubm9kZVRhZyA9IG9ialRvU3RyaW5nLmNhbGwoZG9jdW1lbnQpICE9IG9iamVjdFRhZztcblxuICAvKipcbiAgICogRGV0ZWN0IGlmIHByb3BlcnRpZXMgc2hhZG93aW5nIHRob3NlIG9uIGBPYmplY3QucHJvdG90eXBlYCBhcmUgbm9uLWVudW1lcmFibGUuXG4gICAqXG4gICAqIEluIElFIDwgOSBhbiBvYmplY3QncyBvd24gcHJvcGVydGllcywgc2hhZG93aW5nIG5vbi1lbnVtZXJhYmxlIG9uZXMsXG4gICAqIGFyZSBtYWRlIG5vbi1lbnVtZXJhYmxlIGFzIHdlbGwgKGEuay5hIHRoZSBKU2NyaXB0IGBbW0RvbnRFbnVtXV1gIGJ1ZykuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBfLnN1cHBvcnRcbiAgICogQHR5cGUgYm9vbGVhblxuICAgKi9cbiAgc3VwcG9ydC5ub25FbnVtU2hhZG93cyA9ICEvdmFsdWVPZi8udGVzdChwcm9wcyk7XG5cbiAgLyoqXG4gICAqIERldGVjdCBpZiBvd24gcHJvcGVydGllcyBhcmUgaXRlcmF0ZWQgYWZ0ZXIgaW5oZXJpdGVkIHByb3BlcnRpZXMgKElFIDwgOSkuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBfLnN1cHBvcnRcbiAgICogQHR5cGUgYm9vbGVhblxuICAgKi9cbiAgc3VwcG9ydC5vd25MYXN0ID0gcHJvcHNbMF0gIT0gJ3gnO1xuXG4gIC8qKlxuICAgKiBEZXRlY3QgaWYgYEFycmF5I3NoaWZ0YCBhbmQgYEFycmF5I3NwbGljZWAgYXVnbWVudCBhcnJheS1saWtlIG9iamVjdHNcbiAgICogY29ycmVjdGx5LlxuICAgKlxuICAgKiBGaXJlZm94IDwgMTAsIGNvbXBhdGliaWxpdHkgbW9kZXMgb2YgSUUgOCwgYW5kIElFIDwgOSBoYXZlIGJ1Z2d5IEFycmF5XG4gICAqIGBzaGlmdCgpYCBhbmQgYHNwbGljZSgpYCBmdW5jdGlvbnMgdGhhdCBmYWlsIHRvIHJlbW92ZSB0aGUgbGFzdCBlbGVtZW50LFxuICAgKiBgdmFsdWVbMF1gLCBvZiBhcnJheS1saWtlIG9iamVjdHMgZXZlbiB0aG91Z2ggdGhlIFwibGVuZ3RoXCIgcHJvcGVydHkgaXNcbiAgICogc2V0IHRvIGAwYC4gVGhlIGBzaGlmdCgpYCBtZXRob2QgaXMgYnVnZ3kgaW4gY29tcGF0aWJpbGl0eSBtb2RlcyBvZiBJRSA4LFxuICAgKiB3aGlsZSBgc3BsaWNlKClgIGlzIGJ1Z2d5IHJlZ2FyZGxlc3Mgb2YgbW9kZSBpbiBJRSA8IDkuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBfLnN1cHBvcnRcbiAgICogQHR5cGUgYm9vbGVhblxuICAgKi9cbiAgc3VwcG9ydC5zcGxpY2VPYmplY3RzID0gKHNwbGljZS5jYWxsKG9iamVjdCwgMCwgMSksICFvYmplY3RbMF0pO1xuXG4gIC8qKlxuICAgKiBEZXRlY3QgbGFjayBvZiBzdXBwb3J0IGZvciBhY2Nlc3Npbmcgc3RyaW5nIGNoYXJhY3RlcnMgYnkgaW5kZXguXG4gICAqXG4gICAqIElFIDwgOCBjYW4ndCBhY2Nlc3MgY2hhcmFjdGVycyBieSBpbmRleC4gSUUgOCBjYW4gb25seSBhY2Nlc3MgY2hhcmFjdGVyc1xuICAgKiBieSBpbmRleCBvbiBzdHJpbmcgbGl0ZXJhbHMsIG5vdCBzdHJpbmcgb2JqZWN0cy5cbiAgICpcbiAgICogQG1lbWJlck9mIF8uc3VwcG9ydFxuICAgKiBAdHlwZSBib29sZWFuXG4gICAqL1xuICBzdXBwb3J0LnVuaW5kZXhlZENoYXJzID0gKCd4J1swXSArIE9iamVjdCgneCcpWzBdKSAhPSAneHgnO1xuXG4gIC8qKlxuICAgKiBEZXRlY3QgaWYgdGhlIERPTSBpcyBzdXBwb3J0ZWQuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBfLnN1cHBvcnRcbiAgICogQHR5cGUgYm9vbGVhblxuICAgKi9cbiAgdHJ5IHtcbiAgICBzdXBwb3J0LmRvbSA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKS5ub2RlVHlwZSA9PT0gMTE7XG4gIH0gY2F0Y2goZSkge1xuICAgIHN1cHBvcnQuZG9tID0gZmFsc2U7XG4gIH1cbn0oMSwgMCkpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHN1cHBvcnQ7XG4iLCIvKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgYHZhbHVlYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IFV0aWxpdHlcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHJldHVybiBmcm9tIHRoZSBuZXcgZnVuY3Rpb24uXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIG9iamVjdCA9IHsgJ3VzZXInOiAnZnJlZCcgfTtcbiAqIHZhciBnZXR0ZXIgPSBfLmNvbnN0YW50KG9iamVjdCk7XG4gKlxuICogZ2V0dGVyKCkgPT09IG9iamVjdDtcbiAqIC8vID0+IHRydWVcbiAqL1xuZnVuY3Rpb24gY29uc3RhbnQodmFsdWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjb25zdGFudDtcbiIsIi8qKlxuICogVGhpcyBtZXRob2QgcmV0dXJucyB0aGUgZmlyc3QgYXJndW1lbnQgcHJvdmlkZWQgdG8gaXQuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBVdGlsaXR5XG4gKiBAcGFyYW0geyp9IHZhbHVlIEFueSB2YWx1ZS5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIGB2YWx1ZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBvYmplY3QgPSB7ICd1c2VyJzogJ2ZyZWQnIH07XG4gKlxuICogXy5pZGVudGl0eShvYmplY3QpID09PSBvYmplY3Q7XG4gKiAvLyA9PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGlkZW50aXR5KHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpZGVudGl0eTtcbiIsIi8qKlxuICogQSBuby1vcGVyYXRpb24gZnVuY3Rpb24gdGhhdCByZXR1cm5zIGB1bmRlZmluZWRgIHJlZ2FyZGxlc3Mgb2YgdGhlXG4gKiBhcmd1bWVudHMgaXQgcmVjZWl2ZXMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBVdGlsaXR5XG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBvYmplY3QgPSB7ICd1c2VyJzogJ2ZyZWQnIH07XG4gKlxuICogXy5ub29wKG9iamVjdCkgPT09IHVuZGVmaW5lZDtcbiAqIC8vID0+IHRydWVcbiAqL1xuZnVuY3Rpb24gbm9vcCgpIHtcbiAgLy8gTm8gb3BlcmF0aW9uIHBlcmZvcm1lZC5cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBub29wO1xuIiwidmFyIGJhc2VQcm9wZXJ0eSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2Jhc2VQcm9wZXJ0eScpLFxuICAgIGJhc2VQcm9wZXJ0eURlZXAgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlUHJvcGVydHlEZWVwJyksXG4gICAgaXNLZXkgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0tleScpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlIGF0IGBwYXRoYCBvbiBhXG4gKiBnaXZlbiBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBVdGlsaXR5XG4gKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBvYmplY3RzID0gW1xuICogICB7ICdhJzogeyAnYic6IHsgJ2MnOiAyIH0gfSB9LFxuICogICB7ICdhJzogeyAnYic6IHsgJ2MnOiAxIH0gfSB9XG4gKiBdO1xuICpcbiAqIF8ubWFwKG9iamVjdHMsIF8ucHJvcGVydHkoJ2EuYi5jJykpO1xuICogLy8gPT4gWzIsIDFdXG4gKlxuICogXy5wbHVjayhfLnNvcnRCeShvYmplY3RzLCBfLnByb3BlcnR5KFsnYScsICdiJywgJ2MnXSkpLCAnYS5iLmMnKTtcbiAqIC8vID0+IFsxLCAyXVxuICovXG5mdW5jdGlvbiBwcm9wZXJ0eShwYXRoKSB7XG4gIHJldHVybiBpc0tleShwYXRoKSA/IGJhc2VQcm9wZXJ0eShwYXRoKSA6IGJhc2VQcm9wZXJ0eURlZXAocGF0aCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcHJvcGVydHk7XG4iLCIvKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxudmFyIEVtaXR0ZXIgPSByZXF1aXJlKCdlbWl0dGVyJyk7XG52YXIgcmVkdWNlID0gcmVxdWlyZSgncmVkdWNlJyk7XG5cbi8qKlxuICogUm9vdCByZWZlcmVuY2UgZm9yIGlmcmFtZXMuXG4gKi9cblxudmFyIHJvb3QgPSAndW5kZWZpbmVkJyA9PSB0eXBlb2Ygd2luZG93XG4gID8gKHRoaXMgfHwgc2VsZilcbiAgOiB3aW5kb3c7XG5cbi8qKlxuICogTm9vcC5cbiAqL1xuXG5mdW5jdGlvbiBub29wKCl7fTtcblxuLyoqXG4gKiBDaGVjayBpZiBgb2JqYCBpcyBhIGhvc3Qgb2JqZWN0LFxuICogd2UgZG9uJ3Qgd2FudCB0byBzZXJpYWxpemUgdGhlc2UgOilcbiAqXG4gKiBUT0RPOiBmdXR1cmUgcHJvb2YsIG1vdmUgdG8gY29tcG9lbnQgbGFuZFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBpc0hvc3Qob2JqKSB7XG4gIHZhciBzdHIgPSB7fS50b1N0cmluZy5jYWxsKG9iaik7XG5cbiAgc3dpdGNoIChzdHIpIHtcbiAgICBjYXNlICdbb2JqZWN0IEZpbGVdJzpcbiAgICBjYXNlICdbb2JqZWN0IEJsb2JdJzpcbiAgICBjYXNlICdbb2JqZWN0IEZvcm1EYXRhXSc6XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIFhIUi5cbiAqL1xuXG5yZXF1ZXN0LmdldFhIUiA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHJvb3QuWE1MSHR0cFJlcXVlc3RcbiAgICAgICYmICghcm9vdC5sb2NhdGlvbiB8fCAnZmlsZTonICE9IHJvb3QubG9jYXRpb24ucHJvdG9jb2xcbiAgICAgICAgICB8fCAhcm9vdC5BY3RpdmVYT2JqZWN0KSkge1xuICAgIHJldHVybiBuZXcgWE1MSHR0cFJlcXVlc3Q7XG4gIH0gZWxzZSB7XG4gICAgdHJ5IHsgcmV0dXJuIG5ldyBBY3RpdmVYT2JqZWN0KCdNaWNyb3NvZnQuWE1MSFRUUCcpOyB9IGNhdGNoKGUpIHt9XG4gICAgdHJ5IHsgcmV0dXJuIG5ldyBBY3RpdmVYT2JqZWN0KCdNc3htbDIuWE1MSFRUUC42LjAnKTsgfSBjYXRjaChlKSB7fVxuICAgIHRyeSB7IHJldHVybiBuZXcgQWN0aXZlWE9iamVjdCgnTXN4bWwyLlhNTEhUVFAuMy4wJyk7IH0gY2F0Y2goZSkge31cbiAgICB0cnkgeyByZXR1cm4gbmV3IEFjdGl2ZVhPYmplY3QoJ01zeG1sMi5YTUxIVFRQJyk7IH0gY2F0Y2goZSkge31cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59O1xuXG4vKipcbiAqIFJlbW92ZXMgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZSwgYWRkZWQgdG8gc3VwcG9ydCBJRS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc1xuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxudmFyIHRyaW0gPSAnJy50cmltXG4gID8gZnVuY3Rpb24ocykgeyByZXR1cm4gcy50cmltKCk7IH1cbiAgOiBmdW5jdGlvbihzKSB7IHJldHVybiBzLnJlcGxhY2UoLyheXFxzKnxcXHMqJCkvZywgJycpOyB9O1xuXG4vKipcbiAqIENoZWNrIGlmIGBvYmpgIGlzIGFuIG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gaXNPYmplY3Qob2JqKSB7XG4gIHJldHVybiBvYmogPT09IE9iamVjdChvYmopO1xufVxuXG4vKipcbiAqIFNlcmlhbGl6ZSB0aGUgZ2l2ZW4gYG9iamAuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gc2VyaWFsaXplKG9iaikge1xuICBpZiAoIWlzT2JqZWN0KG9iaikpIHJldHVybiBvYmo7XG4gIHZhciBwYWlycyA9IFtdO1xuICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgaWYgKG51bGwgIT0gb2JqW2tleV0pIHtcbiAgICAgIHBhaXJzLnB1c2goZW5jb2RlVVJJQ29tcG9uZW50KGtleSlcbiAgICAgICAgKyAnPScgKyBlbmNvZGVVUklDb21wb25lbnQob2JqW2tleV0pKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHBhaXJzLmpvaW4oJyYnKTtcbn1cblxuLyoqXG4gKiBFeHBvc2Ugc2VyaWFsaXphdGlvbiBtZXRob2QuXG4gKi9cblxuIHJlcXVlc3Quc2VyaWFsaXplT2JqZWN0ID0gc2VyaWFsaXplO1xuXG4gLyoqXG4gICogUGFyc2UgdGhlIGdpdmVuIHgtd3d3LWZvcm0tdXJsZW5jb2RlZCBgc3RyYC5cbiAgKlxuICAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAgKiBAcmV0dXJuIHtPYmplY3R9XG4gICogQGFwaSBwcml2YXRlXG4gICovXG5cbmZ1bmN0aW9uIHBhcnNlU3RyaW5nKHN0cikge1xuICB2YXIgb2JqID0ge307XG4gIHZhciBwYWlycyA9IHN0ci5zcGxpdCgnJicpO1xuICB2YXIgcGFydHM7XG4gIHZhciBwYWlyO1xuXG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBwYWlycy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgIHBhaXIgPSBwYWlyc1tpXTtcbiAgICBwYXJ0cyA9IHBhaXIuc3BsaXQoJz0nKTtcbiAgICBvYmpbZGVjb2RlVVJJQ29tcG9uZW50KHBhcnRzWzBdKV0gPSBkZWNvZGVVUklDb21wb25lbnQocGFydHNbMV0pO1xuICB9XG5cbiAgcmV0dXJuIG9iajtcbn1cblxuLyoqXG4gKiBFeHBvc2UgcGFyc2VyLlxuICovXG5cbnJlcXVlc3QucGFyc2VTdHJpbmcgPSBwYXJzZVN0cmluZztcblxuLyoqXG4gKiBEZWZhdWx0IE1JTUUgdHlwZSBtYXAuXG4gKlxuICogICAgIHN1cGVyYWdlbnQudHlwZXMueG1sID0gJ2FwcGxpY2F0aW9uL3htbCc7XG4gKlxuICovXG5cbnJlcXVlc3QudHlwZXMgPSB7XG4gIGh0bWw6ICd0ZXh0L2h0bWwnLFxuICBqc29uOiAnYXBwbGljYXRpb24vanNvbicsXG4gIHhtbDogJ2FwcGxpY2F0aW9uL3htbCcsXG4gIHVybGVuY29kZWQ6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnLFxuICAnZm9ybSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnLFxuICAnZm9ybS1kYXRhJzogJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCdcbn07XG5cbi8qKlxuICogRGVmYXVsdCBzZXJpYWxpemF0aW9uIG1hcC5cbiAqXG4gKiAgICAgc3VwZXJhZ2VudC5zZXJpYWxpemVbJ2FwcGxpY2F0aW9uL3htbCddID0gZnVuY3Rpb24ob2JqKXtcbiAqICAgICAgIHJldHVybiAnZ2VuZXJhdGVkIHhtbCBoZXJlJztcbiAqICAgICB9O1xuICpcbiAqL1xuXG4gcmVxdWVzdC5zZXJpYWxpemUgPSB7XG4gICAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJzogc2VyaWFsaXplLFxuICAgJ2FwcGxpY2F0aW9uL2pzb24nOiBKU09OLnN0cmluZ2lmeVxuIH07XG5cbiAvKipcbiAgKiBEZWZhdWx0IHBhcnNlcnMuXG4gICpcbiAgKiAgICAgc3VwZXJhZ2VudC5wYXJzZVsnYXBwbGljYXRpb24veG1sJ10gPSBmdW5jdGlvbihzdHIpe1xuICAqICAgICAgIHJldHVybiB7IG9iamVjdCBwYXJzZWQgZnJvbSBzdHIgfTtcbiAgKiAgICAgfTtcbiAgKlxuICAqL1xuXG5yZXF1ZXN0LnBhcnNlID0ge1xuICAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJzogcGFyc2VTdHJpbmcsXG4gICdhcHBsaWNhdGlvbi9qc29uJzogSlNPTi5wYXJzZVxufTtcblxuLyoqXG4gKiBQYXJzZSB0aGUgZ2l2ZW4gaGVhZGVyIGBzdHJgIGludG9cbiAqIGFuIG9iamVjdCBjb250YWluaW5nIHRoZSBtYXBwZWQgZmllbGRzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHBhcnNlSGVhZGVyKHN0cikge1xuICB2YXIgbGluZXMgPSBzdHIuc3BsaXQoL1xccj9cXG4vKTtcbiAgdmFyIGZpZWxkcyA9IHt9O1xuICB2YXIgaW5kZXg7XG4gIHZhciBsaW5lO1xuICB2YXIgZmllbGQ7XG4gIHZhciB2YWw7XG5cbiAgbGluZXMucG9wKCk7IC8vIHRyYWlsaW5nIENSTEZcblxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gbGluZXMubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICBsaW5lID0gbGluZXNbaV07XG4gICAgaW5kZXggPSBsaW5lLmluZGV4T2YoJzonKTtcbiAgICBmaWVsZCA9IGxpbmUuc2xpY2UoMCwgaW5kZXgpLnRvTG93ZXJDYXNlKCk7XG4gICAgdmFsID0gdHJpbShsaW5lLnNsaWNlKGluZGV4ICsgMSkpO1xuICAgIGZpZWxkc1tmaWVsZF0gPSB2YWw7XG4gIH1cblxuICByZXR1cm4gZmllbGRzO1xufVxuXG4vKipcbiAqIFJldHVybiB0aGUgbWltZSB0eXBlIGZvciB0aGUgZ2l2ZW4gYHN0cmAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gdHlwZShzdHIpe1xuICByZXR1cm4gc3RyLnNwbGl0KC8gKjsgKi8pLnNoaWZ0KCk7XG59O1xuXG4vKipcbiAqIFJldHVybiBoZWFkZXIgZmllbGQgcGFyYW1ldGVycy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBwYXJhbXMoc3RyKXtcbiAgcmV0dXJuIHJlZHVjZShzdHIuc3BsaXQoLyAqOyAqLyksIGZ1bmN0aW9uKG9iaiwgc3RyKXtcbiAgICB2YXIgcGFydHMgPSBzdHIuc3BsaXQoLyAqPSAqLylcbiAgICAgICwga2V5ID0gcGFydHMuc2hpZnQoKVxuICAgICAgLCB2YWwgPSBwYXJ0cy5zaGlmdCgpO1xuXG4gICAgaWYgKGtleSAmJiB2YWwpIG9ialtrZXldID0gdmFsO1xuICAgIHJldHVybiBvYmo7XG4gIH0sIHt9KTtcbn07XG5cbi8qKlxuICogSW5pdGlhbGl6ZSBhIG5ldyBgUmVzcG9uc2VgIHdpdGggdGhlIGdpdmVuIGB4aHJgLlxuICpcbiAqICAtIHNldCBmbGFncyAoLm9rLCAuZXJyb3IsIGV0YylcbiAqICAtIHBhcnNlIGhlYWRlclxuICpcbiAqIEV4YW1wbGVzOlxuICpcbiAqICBBbGlhc2luZyBgc3VwZXJhZ2VudGAgYXMgYHJlcXVlc3RgIGlzIG5pY2U6XG4gKlxuICogICAgICByZXF1ZXN0ID0gc3VwZXJhZ2VudDtcbiAqXG4gKiAgV2UgY2FuIHVzZSB0aGUgcHJvbWlzZS1saWtlIEFQSSwgb3IgcGFzcyBjYWxsYmFja3M6XG4gKlxuICogICAgICByZXF1ZXN0LmdldCgnLycpLmVuZChmdW5jdGlvbihyZXMpe30pO1xuICogICAgICByZXF1ZXN0LmdldCgnLycsIGZ1bmN0aW9uKHJlcyl7fSk7XG4gKlxuICogIFNlbmRpbmcgZGF0YSBjYW4gYmUgY2hhaW5lZDpcbiAqXG4gKiAgICAgIHJlcXVlc3RcbiAqICAgICAgICAucG9zdCgnL3VzZXInKVxuICogICAgICAgIC5zZW5kKHsgbmFtZTogJ3RqJyB9KVxuICogICAgICAgIC5lbmQoZnVuY3Rpb24ocmVzKXt9KTtcbiAqXG4gKiAgT3IgcGFzc2VkIHRvIGAuc2VuZCgpYDpcbiAqXG4gKiAgICAgIHJlcXVlc3RcbiAqICAgICAgICAucG9zdCgnL3VzZXInKVxuICogICAgICAgIC5zZW5kKHsgbmFtZTogJ3RqJyB9LCBmdW5jdGlvbihyZXMpe30pO1xuICpcbiAqICBPciBwYXNzZWQgdG8gYC5wb3N0KClgOlxuICpcbiAqICAgICAgcmVxdWVzdFxuICogICAgICAgIC5wb3N0KCcvdXNlcicsIHsgbmFtZTogJ3RqJyB9KVxuICogICAgICAgIC5lbmQoZnVuY3Rpb24ocmVzKXt9KTtcbiAqXG4gKiBPciBmdXJ0aGVyIHJlZHVjZWQgdG8gYSBzaW5nbGUgY2FsbCBmb3Igc2ltcGxlIGNhc2VzOlxuICpcbiAqICAgICAgcmVxdWVzdFxuICogICAgICAgIC5wb3N0KCcvdXNlcicsIHsgbmFtZTogJ3RqJyB9LCBmdW5jdGlvbihyZXMpe30pO1xuICpcbiAqIEBwYXJhbSB7WE1MSFRUUFJlcXVlc3R9IHhoclxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIFJlc3BvbnNlKHJlcSwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgdGhpcy5yZXEgPSByZXE7XG4gIHRoaXMueGhyID0gdGhpcy5yZXEueGhyO1xuICAvLyByZXNwb25zZVRleHQgaXMgYWNjZXNzaWJsZSBvbmx5IGlmIHJlc3BvbnNlVHlwZSBpcyAnJyBvciAndGV4dCcgYW5kIG9uIG9sZGVyIGJyb3dzZXJzXG4gIHRoaXMudGV4dCA9ICgodGhpcy5yZXEubWV0aG9kICE9J0hFQUQnICYmICh0aGlzLnhoci5yZXNwb25zZVR5cGUgPT09ICcnIHx8IHRoaXMueGhyLnJlc3BvbnNlVHlwZSA9PT0gJ3RleHQnKSkgfHwgdHlwZW9mIHRoaXMueGhyLnJlc3BvbnNlVHlwZSA9PT0gJ3VuZGVmaW5lZCcpXG4gICAgID8gdGhpcy54aHIucmVzcG9uc2VUZXh0XG4gICAgIDogbnVsbDtcbiAgdGhpcy5zdGF0dXNUZXh0ID0gdGhpcy5yZXEueGhyLnN0YXR1c1RleHQ7XG4gIHRoaXMuc2V0U3RhdHVzUHJvcGVydGllcyh0aGlzLnhoci5zdGF0dXMpO1xuICB0aGlzLmhlYWRlciA9IHRoaXMuaGVhZGVycyA9IHBhcnNlSGVhZGVyKHRoaXMueGhyLmdldEFsbFJlc3BvbnNlSGVhZGVycygpKTtcbiAgLy8gZ2V0QWxsUmVzcG9uc2VIZWFkZXJzIHNvbWV0aW1lcyBmYWxzZWx5IHJldHVybnMgXCJcIiBmb3IgQ09SUyByZXF1ZXN0cywgYnV0XG4gIC8vIGdldFJlc3BvbnNlSGVhZGVyIHN0aWxsIHdvcmtzLiBzbyB3ZSBnZXQgY29udGVudC10eXBlIGV2ZW4gaWYgZ2V0dGluZ1xuICAvLyBvdGhlciBoZWFkZXJzIGZhaWxzLlxuICB0aGlzLmhlYWRlclsnY29udGVudC10eXBlJ10gPSB0aGlzLnhoci5nZXRSZXNwb25zZUhlYWRlcignY29udGVudC10eXBlJyk7XG4gIHRoaXMuc2V0SGVhZGVyUHJvcGVydGllcyh0aGlzLmhlYWRlcik7XG4gIHRoaXMuYm9keSA9IHRoaXMucmVxLm1ldGhvZCAhPSAnSEVBRCdcbiAgICA/IHRoaXMucGFyc2VCb2R5KHRoaXMudGV4dCA/IHRoaXMudGV4dCA6IHRoaXMueGhyLnJlc3BvbnNlKVxuICAgIDogbnVsbDtcbn1cblxuLyoqXG4gKiBHZXQgY2FzZS1pbnNlbnNpdGl2ZSBgZmllbGRgIHZhbHVlLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBmaWVsZFxuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXNwb25zZS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24oZmllbGQpe1xuICByZXR1cm4gdGhpcy5oZWFkZXJbZmllbGQudG9Mb3dlckNhc2UoKV07XG59O1xuXG4vKipcbiAqIFNldCBoZWFkZXIgcmVsYXRlZCBwcm9wZXJ0aWVzOlxuICpcbiAqICAgLSBgLnR5cGVgIHRoZSBjb250ZW50IHR5cGUgd2l0aG91dCBwYXJhbXNcbiAqXG4gKiBBIHJlc3BvbnNlIG9mIFwiQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04XCJcbiAqIHdpbGwgcHJvdmlkZSB5b3Ugd2l0aCBhIGAudHlwZWAgb2YgXCJ0ZXh0L3BsYWluXCIuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGhlYWRlclxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVzcG9uc2UucHJvdG90eXBlLnNldEhlYWRlclByb3BlcnRpZXMgPSBmdW5jdGlvbihoZWFkZXIpe1xuICAvLyBjb250ZW50LXR5cGVcbiAgdmFyIGN0ID0gdGhpcy5oZWFkZXJbJ2NvbnRlbnQtdHlwZSddIHx8ICcnO1xuICB0aGlzLnR5cGUgPSB0eXBlKGN0KTtcblxuICAvLyBwYXJhbXNcbiAgdmFyIG9iaiA9IHBhcmFtcyhjdCk7XG4gIGZvciAodmFyIGtleSBpbiBvYmopIHRoaXNba2V5XSA9IG9ialtrZXldO1xufTtcblxuLyoqXG4gKiBQYXJzZSB0aGUgZ2l2ZW4gYm9keSBgc3RyYC5cbiAqXG4gKiBVc2VkIGZvciBhdXRvLXBhcnNpbmcgb2YgYm9kaWVzLiBQYXJzZXJzXG4gKiBhcmUgZGVmaW5lZCBvbiB0aGUgYHN1cGVyYWdlbnQucGFyc2VgIG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gKiBAcmV0dXJuIHtNaXhlZH1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlc3BvbnNlLnByb3RvdHlwZS5wYXJzZUJvZHkgPSBmdW5jdGlvbihzdHIpe1xuICB2YXIgcGFyc2UgPSByZXF1ZXN0LnBhcnNlW3RoaXMudHlwZV07XG4gIHJldHVybiBwYXJzZSAmJiBzdHIgJiYgKHN0ci5sZW5ndGggfHwgc3RyIGluc3RhbmNlb2YgT2JqZWN0KVxuICAgID8gcGFyc2Uoc3RyKVxuICAgIDogbnVsbDtcbn07XG5cbi8qKlxuICogU2V0IGZsYWdzIHN1Y2ggYXMgYC5va2AgYmFzZWQgb24gYHN0YXR1c2AuXG4gKlxuICogRm9yIGV4YW1wbGUgYSAyeHggcmVzcG9uc2Ugd2lsbCBnaXZlIHlvdSBhIGAub2tgIG9mIF9fdHJ1ZV9fXG4gKiB3aGVyZWFzIDV4eCB3aWxsIGJlIF9fZmFsc2VfXyBhbmQgYC5lcnJvcmAgd2lsbCBiZSBfX3RydWVfXy4gVGhlXG4gKiBgLmNsaWVudEVycm9yYCBhbmQgYC5zZXJ2ZXJFcnJvcmAgYXJlIGFsc28gYXZhaWxhYmxlIHRvIGJlIG1vcmVcbiAqIHNwZWNpZmljLCBhbmQgYC5zdGF0dXNUeXBlYCBpcyB0aGUgY2xhc3Mgb2YgZXJyb3IgcmFuZ2luZyBmcm9tIDEuLjVcbiAqIHNvbWV0aW1lcyB1c2VmdWwgZm9yIG1hcHBpbmcgcmVzcG9uZCBjb2xvcnMgZXRjLlxuICpcbiAqIFwic3VnYXJcIiBwcm9wZXJ0aWVzIGFyZSBhbHNvIGRlZmluZWQgZm9yIGNvbW1vbiBjYXNlcy4gQ3VycmVudGx5IHByb3ZpZGluZzpcbiAqXG4gKiAgIC0gLm5vQ29udGVudFxuICogICAtIC5iYWRSZXF1ZXN0XG4gKiAgIC0gLnVuYXV0aG9yaXplZFxuICogICAtIC5ub3RBY2NlcHRhYmxlXG4gKiAgIC0gLm5vdEZvdW5kXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IHN0YXR1c1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVzcG9uc2UucHJvdG90eXBlLnNldFN0YXR1c1Byb3BlcnRpZXMgPSBmdW5jdGlvbihzdGF0dXMpe1xuICAvLyBoYW5kbGUgSUU5IGJ1ZzogaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8xMDA0Njk3Mi9tc2llLXJldHVybnMtc3RhdHVzLWNvZGUtb2YtMTIyMy1mb3ItYWpheC1yZXF1ZXN0XG4gIGlmIChzdGF0dXMgPT09IDEyMjMpIHtcbiAgICBzdGF0dXMgPSAyMDQ7XG4gIH1cblxuICB2YXIgdHlwZSA9IHN0YXR1cyAvIDEwMCB8IDA7XG5cbiAgLy8gc3RhdHVzIC8gY2xhc3NcbiAgdGhpcy5zdGF0dXMgPSBzdGF0dXM7XG4gIHRoaXMuc3RhdHVzVHlwZSA9IHR5cGU7XG5cbiAgLy8gYmFzaWNzXG4gIHRoaXMuaW5mbyA9IDEgPT0gdHlwZTtcbiAgdGhpcy5vayA9IDIgPT0gdHlwZTtcbiAgdGhpcy5jbGllbnRFcnJvciA9IDQgPT0gdHlwZTtcbiAgdGhpcy5zZXJ2ZXJFcnJvciA9IDUgPT0gdHlwZTtcbiAgdGhpcy5lcnJvciA9ICg0ID09IHR5cGUgfHwgNSA9PSB0eXBlKVxuICAgID8gdGhpcy50b0Vycm9yKClcbiAgICA6IGZhbHNlO1xuXG4gIC8vIHN1Z2FyXG4gIHRoaXMuYWNjZXB0ZWQgPSAyMDIgPT0gc3RhdHVzO1xuICB0aGlzLm5vQ29udGVudCA9IDIwNCA9PSBzdGF0dXM7XG4gIHRoaXMuYmFkUmVxdWVzdCA9IDQwMCA9PSBzdGF0dXM7XG4gIHRoaXMudW5hdXRob3JpemVkID0gNDAxID09IHN0YXR1cztcbiAgdGhpcy5ub3RBY2NlcHRhYmxlID0gNDA2ID09IHN0YXR1cztcbiAgdGhpcy5ub3RGb3VuZCA9IDQwNCA9PSBzdGF0dXM7XG4gIHRoaXMuZm9yYmlkZGVuID0gNDAzID09IHN0YXR1cztcbn07XG5cbi8qKlxuICogUmV0dXJuIGFuIGBFcnJvcmAgcmVwcmVzZW50YXRpdmUgb2YgdGhpcyByZXNwb25zZS5cbiAqXG4gKiBAcmV0dXJuIHtFcnJvcn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVzcG9uc2UucHJvdG90eXBlLnRvRXJyb3IgPSBmdW5jdGlvbigpe1xuICB2YXIgcmVxID0gdGhpcy5yZXE7XG4gIHZhciBtZXRob2QgPSByZXEubWV0aG9kO1xuICB2YXIgdXJsID0gcmVxLnVybDtcblxuICB2YXIgbXNnID0gJ2Nhbm5vdCAnICsgbWV0aG9kICsgJyAnICsgdXJsICsgJyAoJyArIHRoaXMuc3RhdHVzICsgJyknO1xuICB2YXIgZXJyID0gbmV3IEVycm9yKG1zZyk7XG4gIGVyci5zdGF0dXMgPSB0aGlzLnN0YXR1cztcbiAgZXJyLm1ldGhvZCA9IG1ldGhvZDtcbiAgZXJyLnVybCA9IHVybDtcblxuICByZXR1cm4gZXJyO1xufTtcblxuLyoqXG4gKiBFeHBvc2UgYFJlc3BvbnNlYC5cbiAqL1xuXG5yZXF1ZXN0LlJlc3BvbnNlID0gUmVzcG9uc2U7XG5cbi8qKlxuICogSW5pdGlhbGl6ZSBhIG5ldyBgUmVxdWVzdGAgd2l0aCB0aGUgZ2l2ZW4gYG1ldGhvZGAgYW5kIGB1cmxgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2RcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmxcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gUmVxdWVzdChtZXRob2QsIHVybCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIEVtaXR0ZXIuY2FsbCh0aGlzKTtcbiAgdGhpcy5fcXVlcnkgPSB0aGlzLl9xdWVyeSB8fCBbXTtcbiAgdGhpcy5tZXRob2QgPSBtZXRob2Q7XG4gIHRoaXMudXJsID0gdXJsO1xuICB0aGlzLmhlYWRlciA9IHt9O1xuICB0aGlzLl9oZWFkZXIgPSB7fTtcbiAgdGhpcy5vbignZW5kJywgZnVuY3Rpb24oKXtcbiAgICB2YXIgZXJyID0gbnVsbDtcbiAgICB2YXIgcmVzID0gbnVsbDtcblxuICAgIHRyeSB7XG4gICAgICByZXMgPSBuZXcgUmVzcG9uc2Uoc2VsZik7XG4gICAgfSBjYXRjaChlKSB7XG4gICAgICBlcnIgPSBuZXcgRXJyb3IoJ1BhcnNlciBpcyB1bmFibGUgdG8gcGFyc2UgdGhlIHJlc3BvbnNlJyk7XG4gICAgICBlcnIucGFyc2UgPSB0cnVlO1xuICAgICAgZXJyLm9yaWdpbmFsID0gZTtcbiAgICAgIHJldHVybiBzZWxmLmNhbGxiYWNrKGVycik7XG4gICAgfVxuXG4gICAgc2VsZi5lbWl0KCdyZXNwb25zZScsIHJlcyk7XG5cbiAgICBpZiAoZXJyKSB7XG4gICAgICByZXR1cm4gc2VsZi5jYWxsYmFjayhlcnIsIHJlcyk7XG4gICAgfVxuXG4gICAgaWYgKHJlcy5zdGF0dXMgPj0gMjAwICYmIHJlcy5zdGF0dXMgPCAzMDApIHtcbiAgICAgIHJldHVybiBzZWxmLmNhbGxiYWNrKGVyciwgcmVzKTtcbiAgICB9XG5cbiAgICB2YXIgbmV3X2VyciA9IG5ldyBFcnJvcihyZXMuc3RhdHVzVGV4dCB8fCAnVW5zdWNjZXNzZnVsIEhUVFAgcmVzcG9uc2UnKTtcbiAgICBuZXdfZXJyLm9yaWdpbmFsID0gZXJyO1xuICAgIG5ld19lcnIucmVzcG9uc2UgPSByZXM7XG4gICAgbmV3X2Vyci5zdGF0dXMgPSByZXMuc3RhdHVzO1xuXG4gICAgc2VsZi5jYWxsYmFjayhlcnIgfHwgbmV3X2VyciwgcmVzKTtcbiAgfSk7XG59XG5cbi8qKlxuICogTWl4aW4gYEVtaXR0ZXJgLlxuICovXG5cbkVtaXR0ZXIoUmVxdWVzdC5wcm90b3R5cGUpO1xuXG4vKipcbiAqIEFsbG93IGZvciBleHRlbnNpb25cbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS51c2UgPSBmdW5jdGlvbihmbikge1xuICBmbih0aGlzKTtcbiAgcmV0dXJuIHRoaXM7XG59XG5cbi8qKlxuICogU2V0IHRpbWVvdXQgdG8gYG1zYC5cbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gbXNcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS50aW1lb3V0ID0gZnVuY3Rpb24obXMpe1xuICB0aGlzLl90aW1lb3V0ID0gbXM7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBDbGVhciBwcmV2aW91cyB0aW1lb3V0LlxuICpcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5jbGVhclRpbWVvdXQgPSBmdW5jdGlvbigpe1xuICB0aGlzLl90aW1lb3V0ID0gMDtcbiAgY2xlYXJUaW1lb3V0KHRoaXMuX3RpbWVyKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEFib3J0IHRoZSByZXF1ZXN0LCBhbmQgY2xlYXIgcG90ZW50aWFsIHRpbWVvdXQuXG4gKlxuICogQHJldHVybiB7UmVxdWVzdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuYWJvcnQgPSBmdW5jdGlvbigpe1xuICBpZiAodGhpcy5hYm9ydGVkKSByZXR1cm47XG4gIHRoaXMuYWJvcnRlZCA9IHRydWU7XG4gIHRoaXMueGhyLmFib3J0KCk7XG4gIHRoaXMuY2xlYXJUaW1lb3V0KCk7XG4gIHRoaXMuZW1pdCgnYWJvcnQnKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldCBoZWFkZXIgYGZpZWxkYCB0byBgdmFsYCwgb3IgbXVsdGlwbGUgZmllbGRzIHdpdGggb25lIG9iamVjdC5cbiAqXG4gKiBFeGFtcGxlczpcbiAqXG4gKiAgICAgIHJlcS5nZXQoJy8nKVxuICogICAgICAgIC5zZXQoJ0FjY2VwdCcsICdhcHBsaWNhdGlvbi9qc29uJylcbiAqICAgICAgICAuc2V0KCdYLUFQSS1LZXknLCAnZm9vYmFyJylcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiAgICAgIHJlcS5nZXQoJy8nKVxuICogICAgICAgIC5zZXQoeyBBY2NlcHQ6ICdhcHBsaWNhdGlvbi9qc29uJywgJ1gtQVBJLUtleSc6ICdmb29iYXInIH0pXG4gKiAgICAgICAgLmVuZChjYWxsYmFjayk7XG4gKlxuICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fSBmaWVsZFxuICogQHBhcmFtIHtTdHJpbmd9IHZhbFxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uKGZpZWxkLCB2YWwpe1xuICBpZiAoaXNPYmplY3QoZmllbGQpKSB7XG4gICAgZm9yICh2YXIga2V5IGluIGZpZWxkKSB7XG4gICAgICB0aGlzLnNldChrZXksIGZpZWxkW2tleV0pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICB0aGlzLl9oZWFkZXJbZmllbGQudG9Mb3dlckNhc2UoKV0gPSB2YWw7XG4gIHRoaXMuaGVhZGVyW2ZpZWxkXSA9IHZhbDtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFJlbW92ZSBoZWFkZXIgYGZpZWxkYC5cbiAqXG4gKiBFeGFtcGxlOlxuICpcbiAqICAgICAgcmVxLmdldCgnLycpXG4gKiAgICAgICAgLnVuc2V0KCdVc2VyLUFnZW50JylcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZmllbGRcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS51bnNldCA9IGZ1bmN0aW9uKGZpZWxkKXtcbiAgZGVsZXRlIHRoaXMuX2hlYWRlcltmaWVsZC50b0xvd2VyQ2FzZSgpXTtcbiAgZGVsZXRlIHRoaXMuaGVhZGVyW2ZpZWxkXTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEdldCBjYXNlLWluc2Vuc2l0aXZlIGhlYWRlciBgZmllbGRgIHZhbHVlLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBmaWVsZFxuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuZ2V0SGVhZGVyID0gZnVuY3Rpb24oZmllbGQpe1xuICByZXR1cm4gdGhpcy5faGVhZGVyW2ZpZWxkLnRvTG93ZXJDYXNlKCldO1xufTtcblxuLyoqXG4gKiBTZXQgQ29udGVudC1UeXBlIHRvIGB0eXBlYCwgbWFwcGluZyB2YWx1ZXMgZnJvbSBgcmVxdWVzdC50eXBlc2AuXG4gKlxuICogRXhhbXBsZXM6XG4gKlxuICogICAgICBzdXBlcmFnZW50LnR5cGVzLnhtbCA9ICdhcHBsaWNhdGlvbi94bWwnO1xuICpcbiAqICAgICAgcmVxdWVzdC5wb3N0KCcvJylcbiAqICAgICAgICAudHlwZSgneG1sJylcbiAqICAgICAgICAuc2VuZCh4bWxzdHJpbmcpXG4gKiAgICAgICAgLmVuZChjYWxsYmFjayk7XG4gKlxuICogICAgICByZXF1ZXN0LnBvc3QoJy8nKVxuICogICAgICAgIC50eXBlKCdhcHBsaWNhdGlvbi94bWwnKVxuICogICAgICAgIC5zZW5kKHhtbHN0cmluZylcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLnR5cGUgPSBmdW5jdGlvbih0eXBlKXtcbiAgdGhpcy5zZXQoJ0NvbnRlbnQtVHlwZScsIHJlcXVlc3QudHlwZXNbdHlwZV0gfHwgdHlwZSk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZXQgQWNjZXB0IHRvIGB0eXBlYCwgbWFwcGluZyB2YWx1ZXMgZnJvbSBgcmVxdWVzdC50eXBlc2AuXG4gKlxuICogRXhhbXBsZXM6XG4gKlxuICogICAgICBzdXBlcmFnZW50LnR5cGVzLmpzb24gPSAnYXBwbGljYXRpb24vanNvbic7XG4gKlxuICogICAgICByZXF1ZXN0LmdldCgnL2FnZW50JylcbiAqICAgICAgICAuYWNjZXB0KCdqc29uJylcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiAgICAgIHJlcXVlc3QuZ2V0KCcvYWdlbnQnKVxuICogICAgICAgIC5hY2NlcHQoJ2FwcGxpY2F0aW9uL2pzb24nKVxuICogICAgICAgIC5lbmQoY2FsbGJhY2spO1xuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBhY2NlcHRcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5hY2NlcHQgPSBmdW5jdGlvbih0eXBlKXtcbiAgdGhpcy5zZXQoJ0FjY2VwdCcsIHJlcXVlc3QudHlwZXNbdHlwZV0gfHwgdHlwZSk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZXQgQXV0aG9yaXphdGlvbiBmaWVsZCB2YWx1ZSB3aXRoIGB1c2VyYCBhbmQgYHBhc3NgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1c2VyXG4gKiBAcGFyYW0ge1N0cmluZ30gcGFzc1xuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmF1dGggPSBmdW5jdGlvbih1c2VyLCBwYXNzKXtcbiAgdmFyIHN0ciA9IGJ0b2EodXNlciArICc6JyArIHBhc3MpO1xuICB0aGlzLnNldCgnQXV0aG9yaXphdGlvbicsICdCYXNpYyAnICsgc3RyKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiogQWRkIHF1ZXJ5LXN0cmluZyBgdmFsYC5cbipcbiogRXhhbXBsZXM6XG4qXG4qICAgcmVxdWVzdC5nZXQoJy9zaG9lcycpXG4qICAgICAucXVlcnkoJ3NpemU9MTAnKVxuKiAgICAgLnF1ZXJ5KHsgY29sb3I6ICdibHVlJyB9KVxuKlxuKiBAcGFyYW0ge09iamVjdHxTdHJpbmd9IHZhbFxuKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiogQGFwaSBwdWJsaWNcbiovXG5cblJlcXVlc3QucHJvdG90eXBlLnF1ZXJ5ID0gZnVuY3Rpb24odmFsKXtcbiAgaWYgKCdzdHJpbmcnICE9IHR5cGVvZiB2YWwpIHZhbCA9IHNlcmlhbGl6ZSh2YWwpO1xuICBpZiAodmFsKSB0aGlzLl9xdWVyeS5wdXNoKHZhbCk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBXcml0ZSB0aGUgZmllbGQgYG5hbWVgIGFuZCBgdmFsYCBmb3IgXCJtdWx0aXBhcnQvZm9ybS1kYXRhXCJcbiAqIHJlcXVlc3QgYm9kaWVzLlxuICpcbiAqIGBgYCBqc1xuICogcmVxdWVzdC5wb3N0KCcvdXBsb2FkJylcbiAqICAgLmZpZWxkKCdmb28nLCAnYmFyJylcbiAqICAgLmVuZChjYWxsYmFjayk7XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICogQHBhcmFtIHtTdHJpbmd8QmxvYnxGaWxlfSB2YWxcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5maWVsZCA9IGZ1bmN0aW9uKG5hbWUsIHZhbCl7XG4gIGlmICghdGhpcy5fZm9ybURhdGEpIHRoaXMuX2Zvcm1EYXRhID0gbmV3IHJvb3QuRm9ybURhdGEoKTtcbiAgdGhpcy5fZm9ybURhdGEuYXBwZW5kKG5hbWUsIHZhbCk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBRdWV1ZSB0aGUgZ2l2ZW4gYGZpbGVgIGFzIGFuIGF0dGFjaG1lbnQgdG8gdGhlIHNwZWNpZmllZCBgZmllbGRgLFxuICogd2l0aCBvcHRpb25hbCBgZmlsZW5hbWVgLlxuICpcbiAqIGBgYCBqc1xuICogcmVxdWVzdC5wb3N0KCcvdXBsb2FkJylcbiAqICAgLmF0dGFjaChuZXcgQmxvYihbJzxhIGlkPVwiYVwiPjxiIGlkPVwiYlwiPmhleSE8L2I+PC9hPiddLCB7IHR5cGU6IFwidGV4dC9odG1sXCJ9KSlcbiAqICAgLmVuZChjYWxsYmFjayk7XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZmllbGRcbiAqIEBwYXJhbSB7QmxvYnxGaWxlfSBmaWxlXG4gKiBAcGFyYW0ge1N0cmluZ30gZmlsZW5hbWVcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5hdHRhY2ggPSBmdW5jdGlvbihmaWVsZCwgZmlsZSwgZmlsZW5hbWUpe1xuICBpZiAoIXRoaXMuX2Zvcm1EYXRhKSB0aGlzLl9mb3JtRGF0YSA9IG5ldyByb290LkZvcm1EYXRhKCk7XG4gIHRoaXMuX2Zvcm1EYXRhLmFwcGVuZChmaWVsZCwgZmlsZSwgZmlsZW5hbWUpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2VuZCBgZGF0YWAsIGRlZmF1bHRpbmcgdGhlIGAudHlwZSgpYCB0byBcImpzb25cIiB3aGVuXG4gKiBhbiBvYmplY3QgaXMgZ2l2ZW4uXG4gKlxuICogRXhhbXBsZXM6XG4gKlxuICogICAgICAgLy8gcXVlcnlzdHJpbmdcbiAqICAgICAgIHJlcXVlc3QuZ2V0KCcvc2VhcmNoJylcbiAqICAgICAgICAgLmVuZChjYWxsYmFjaylcbiAqXG4gKiAgICAgICAvLyBtdWx0aXBsZSBkYXRhIFwid3JpdGVzXCJcbiAqICAgICAgIHJlcXVlc3QuZ2V0KCcvc2VhcmNoJylcbiAqICAgICAgICAgLnNlbmQoeyBzZWFyY2g6ICdxdWVyeScgfSlcbiAqICAgICAgICAgLnNlbmQoeyByYW5nZTogJzEuLjUnIH0pXG4gKiAgICAgICAgIC5zZW5kKHsgb3JkZXI6ICdkZXNjJyB9KVxuICogICAgICAgICAuZW5kKGNhbGxiYWNrKVxuICpcbiAqICAgICAgIC8vIG1hbnVhbCBqc29uXG4gKiAgICAgICByZXF1ZXN0LnBvc3QoJy91c2VyJylcbiAqICAgICAgICAgLnR5cGUoJ2pzb24nKVxuICogICAgICAgICAuc2VuZCgne1wibmFtZVwiOlwidGpcIn0pXG4gKiAgICAgICAgIC5lbmQoY2FsbGJhY2spXG4gKlxuICogICAgICAgLy8gYXV0byBqc29uXG4gKiAgICAgICByZXF1ZXN0LnBvc3QoJy91c2VyJylcbiAqICAgICAgICAgLnNlbmQoeyBuYW1lOiAndGonIH0pXG4gKiAgICAgICAgIC5lbmQoY2FsbGJhY2spXG4gKlxuICogICAgICAgLy8gbWFudWFsIHgtd3d3LWZvcm0tdXJsZW5jb2RlZFxuICogICAgICAgcmVxdWVzdC5wb3N0KCcvdXNlcicpXG4gKiAgICAgICAgIC50eXBlKCdmb3JtJylcbiAqICAgICAgICAgLnNlbmQoJ25hbWU9dGonKVxuICogICAgICAgICAuZW5kKGNhbGxiYWNrKVxuICpcbiAqICAgICAgIC8vIGF1dG8geC13d3ctZm9ybS11cmxlbmNvZGVkXG4gKiAgICAgICByZXF1ZXN0LnBvc3QoJy91c2VyJylcbiAqICAgICAgICAgLnR5cGUoJ2Zvcm0nKVxuICogICAgICAgICAuc2VuZCh7IG5hbWU6ICd0aicgfSlcbiAqICAgICAgICAgLmVuZChjYWxsYmFjaylcbiAqXG4gKiAgICAgICAvLyBkZWZhdWx0cyB0byB4LXd3dy1mb3JtLXVybGVuY29kZWRcbiAgKiAgICAgIHJlcXVlc3QucG9zdCgnL3VzZXInKVxuICAqICAgICAgICAuc2VuZCgnbmFtZT10b2JpJylcbiAgKiAgICAgICAgLnNlbmQoJ3NwZWNpZXM9ZmVycmV0JylcbiAgKiAgICAgICAgLmVuZChjYWxsYmFjaylcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xPYmplY3R9IGRhdGFcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24oZGF0YSl7XG4gIHZhciBvYmogPSBpc09iamVjdChkYXRhKTtcbiAgdmFyIHR5cGUgPSB0aGlzLmdldEhlYWRlcignQ29udGVudC1UeXBlJyk7XG5cbiAgLy8gbWVyZ2VcbiAgaWYgKG9iaiAmJiBpc09iamVjdCh0aGlzLl9kYXRhKSkge1xuICAgIGZvciAodmFyIGtleSBpbiBkYXRhKSB7XG4gICAgICB0aGlzLl9kYXRhW2tleV0gPSBkYXRhW2tleV07XG4gICAgfVxuICB9IGVsc2UgaWYgKCdzdHJpbmcnID09IHR5cGVvZiBkYXRhKSB7XG4gICAgaWYgKCF0eXBlKSB0aGlzLnR5cGUoJ2Zvcm0nKTtcbiAgICB0eXBlID0gdGhpcy5nZXRIZWFkZXIoJ0NvbnRlbnQtVHlwZScpO1xuICAgIGlmICgnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyA9PSB0eXBlKSB7XG4gICAgICB0aGlzLl9kYXRhID0gdGhpcy5fZGF0YVxuICAgICAgICA/IHRoaXMuX2RhdGEgKyAnJicgKyBkYXRhXG4gICAgICAgIDogZGF0YTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fZGF0YSA9ICh0aGlzLl9kYXRhIHx8ICcnKSArIGRhdGE7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRoaXMuX2RhdGEgPSBkYXRhO1xuICB9XG5cbiAgaWYgKCFvYmogfHwgaXNIb3N0KGRhdGEpKSByZXR1cm4gdGhpcztcbiAgaWYgKCF0eXBlKSB0aGlzLnR5cGUoJ2pzb24nKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEludm9rZSB0aGUgY2FsbGJhY2sgd2l0aCBgZXJyYCBhbmQgYHJlc2BcbiAqIGFuZCBoYW5kbGUgYXJpdHkgY2hlY2suXG4gKlxuICogQHBhcmFtIHtFcnJvcn0gZXJyXG4gKiBAcGFyYW0ge1Jlc3BvbnNlfSByZXNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmNhbGxiYWNrID0gZnVuY3Rpb24oZXJyLCByZXMpe1xuICB2YXIgZm4gPSB0aGlzLl9jYWxsYmFjaztcbiAgdGhpcy5jbGVhclRpbWVvdXQoKTtcbiAgZm4oZXJyLCByZXMpO1xufTtcblxuLyoqXG4gKiBJbnZva2UgY2FsbGJhY2sgd2l0aCB4LWRvbWFpbiBlcnJvci5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5jcm9zc0RvbWFpbkVycm9yID0gZnVuY3Rpb24oKXtcbiAgdmFyIGVyciA9IG5ldyBFcnJvcignT3JpZ2luIGlzIG5vdCBhbGxvd2VkIGJ5IEFjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpbicpO1xuICBlcnIuY3Jvc3NEb21haW4gPSB0cnVlO1xuICB0aGlzLmNhbGxiYWNrKGVycik7XG59O1xuXG4vKipcbiAqIEludm9rZSBjYWxsYmFjayB3aXRoIHRpbWVvdXQgZXJyb3IuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUudGltZW91dEVycm9yID0gZnVuY3Rpb24oKXtcbiAgdmFyIHRpbWVvdXQgPSB0aGlzLl90aW1lb3V0O1xuICB2YXIgZXJyID0gbmV3IEVycm9yKCd0aW1lb3V0IG9mICcgKyB0aW1lb3V0ICsgJ21zIGV4Y2VlZGVkJyk7XG4gIGVyci50aW1lb3V0ID0gdGltZW91dDtcbiAgdGhpcy5jYWxsYmFjayhlcnIpO1xufTtcblxuLyoqXG4gKiBFbmFibGUgdHJhbnNtaXNzaW9uIG9mIGNvb2tpZXMgd2l0aCB4LWRvbWFpbiByZXF1ZXN0cy5cbiAqXG4gKiBOb3RlIHRoYXQgZm9yIHRoaXMgdG8gd29yayB0aGUgb3JpZ2luIG11c3Qgbm90IGJlXG4gKiB1c2luZyBcIkFjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpblwiIHdpdGggYSB3aWxkY2FyZCxcbiAqIGFuZCBhbHNvIG11c3Qgc2V0IFwiQWNjZXNzLUNvbnRyb2wtQWxsb3ctQ3JlZGVudGlhbHNcIlxuICogdG8gXCJ0cnVlXCIuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS53aXRoQ3JlZGVudGlhbHMgPSBmdW5jdGlvbigpe1xuICB0aGlzLl93aXRoQ3JlZGVudGlhbHMgPSB0cnVlO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogSW5pdGlhdGUgcmVxdWVzdCwgaW52b2tpbmcgY2FsbGJhY2sgYGZuKHJlcylgXG4gKiB3aXRoIGFuIGluc3RhbmNlb2YgYFJlc3BvbnNlYC5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uKGZuKXtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgeGhyID0gdGhpcy54aHIgPSByZXF1ZXN0LmdldFhIUigpO1xuICB2YXIgcXVlcnkgPSB0aGlzLl9xdWVyeS5qb2luKCcmJyk7XG4gIHZhciB0aW1lb3V0ID0gdGhpcy5fdGltZW91dDtcbiAgdmFyIGRhdGEgPSB0aGlzLl9mb3JtRGF0YSB8fCB0aGlzLl9kYXRhO1xuXG4gIC8vIHN0b3JlIGNhbGxiYWNrXG4gIHRoaXMuX2NhbGxiYWNrID0gZm4gfHwgbm9vcDtcblxuICAvLyBzdGF0ZSBjaGFuZ2VcbiAgeGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCl7XG4gICAgaWYgKDQgIT0geGhyLnJlYWR5U3RhdGUpIHJldHVybjtcblxuICAgIC8vIEluIElFOSwgcmVhZHMgdG8gYW55IHByb3BlcnR5IChlLmcuIHN0YXR1cykgb2ZmIG9mIGFuIGFib3J0ZWQgWEhSIHdpbGxcbiAgICAvLyByZXN1bHQgaW4gdGhlIGVycm9yIFwiQ291bGQgbm90IGNvbXBsZXRlIHRoZSBvcGVyYXRpb24gZHVlIHRvIGVycm9yIGMwMGMwMjNmXCJcbiAgICB2YXIgc3RhdHVzO1xuICAgIHRyeSB7IHN0YXR1cyA9IHhoci5zdGF0dXMgfSBjYXRjaChlKSB7IHN0YXR1cyA9IDA7IH1cblxuICAgIGlmICgwID09IHN0YXR1cykge1xuICAgICAgaWYgKHNlbGYudGltZWRvdXQpIHJldHVybiBzZWxmLnRpbWVvdXRFcnJvcigpO1xuICAgICAgaWYgKHNlbGYuYWJvcnRlZCkgcmV0dXJuO1xuICAgICAgcmV0dXJuIHNlbGYuY3Jvc3NEb21haW5FcnJvcigpO1xuICAgIH1cbiAgICBzZWxmLmVtaXQoJ2VuZCcpO1xuICB9O1xuXG4gIC8vIHByb2dyZXNzXG4gIHZhciBoYW5kbGVQcm9ncmVzcyA9IGZ1bmN0aW9uKGUpe1xuICAgIGlmIChlLnRvdGFsID4gMCkge1xuICAgICAgZS5wZXJjZW50ID0gZS5sb2FkZWQgLyBlLnRvdGFsICogMTAwO1xuICAgIH1cbiAgICBzZWxmLmVtaXQoJ3Byb2dyZXNzJywgZSk7XG4gIH07XG4gIGlmICh0aGlzLmhhc0xpc3RlbmVycygncHJvZ3Jlc3MnKSkge1xuICAgIHhoci5vbnByb2dyZXNzID0gaGFuZGxlUHJvZ3Jlc3M7XG4gIH1cbiAgdHJ5IHtcbiAgICBpZiAoeGhyLnVwbG9hZCAmJiB0aGlzLmhhc0xpc3RlbmVycygncHJvZ3Jlc3MnKSkge1xuICAgICAgeGhyLnVwbG9hZC5vbnByb2dyZXNzID0gaGFuZGxlUHJvZ3Jlc3M7XG4gICAgfVxuICB9IGNhdGNoKGUpIHtcbiAgICAvLyBBY2Nlc3NpbmcgeGhyLnVwbG9hZCBmYWlscyBpbiBJRSBmcm9tIGEgd2ViIHdvcmtlciwgc28ganVzdCBwcmV0ZW5kIGl0IGRvZXNuJ3QgZXhpc3QuXG4gICAgLy8gUmVwb3J0ZWQgaGVyZTpcbiAgICAvLyBodHRwczovL2Nvbm5lY3QubWljcm9zb2Z0LmNvbS9JRS9mZWVkYmFjay9kZXRhaWxzLzgzNzI0NS94bWxodHRwcmVxdWVzdC11cGxvYWQtdGhyb3dzLWludmFsaWQtYXJndW1lbnQtd2hlbi11c2VkLWZyb20td2ViLXdvcmtlci1jb250ZXh0XG4gIH1cblxuICAvLyB0aW1lb3V0XG4gIGlmICh0aW1lb3V0ICYmICF0aGlzLl90aW1lcikge1xuICAgIHRoaXMuX3RpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbigpe1xuICAgICAgc2VsZi50aW1lZG91dCA9IHRydWU7XG4gICAgICBzZWxmLmFib3J0KCk7XG4gICAgfSwgdGltZW91dCk7XG4gIH1cblxuICAvLyBxdWVyeXN0cmluZ1xuICBpZiAocXVlcnkpIHtcbiAgICBxdWVyeSA9IHJlcXVlc3Quc2VyaWFsaXplT2JqZWN0KHF1ZXJ5KTtcbiAgICB0aGlzLnVybCArPSB+dGhpcy51cmwuaW5kZXhPZignPycpXG4gICAgICA/ICcmJyArIHF1ZXJ5XG4gICAgICA6ICc/JyArIHF1ZXJ5O1xuICB9XG5cbiAgLy8gaW5pdGlhdGUgcmVxdWVzdFxuICB4aHIub3Blbih0aGlzLm1ldGhvZCwgdGhpcy51cmwsIHRydWUpO1xuXG4gIC8vIENPUlNcbiAgaWYgKHRoaXMuX3dpdGhDcmVkZW50aWFscykgeGhyLndpdGhDcmVkZW50aWFscyA9IHRydWU7XG5cbiAgLy8gYm9keVxuICBpZiAoJ0dFVCcgIT0gdGhpcy5tZXRob2QgJiYgJ0hFQUQnICE9IHRoaXMubWV0aG9kICYmICdzdHJpbmcnICE9IHR5cGVvZiBkYXRhICYmICFpc0hvc3QoZGF0YSkpIHtcbiAgICAvLyBzZXJpYWxpemUgc3R1ZmZcbiAgICB2YXIgc2VyaWFsaXplID0gcmVxdWVzdC5zZXJpYWxpemVbdGhpcy5nZXRIZWFkZXIoJ0NvbnRlbnQtVHlwZScpXTtcbiAgICBpZiAoc2VyaWFsaXplKSBkYXRhID0gc2VyaWFsaXplKGRhdGEpO1xuICB9XG5cbiAgLy8gc2V0IGhlYWRlciBmaWVsZHNcbiAgZm9yICh2YXIgZmllbGQgaW4gdGhpcy5oZWFkZXIpIHtcbiAgICBpZiAobnVsbCA9PSB0aGlzLmhlYWRlcltmaWVsZF0pIGNvbnRpbnVlO1xuICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKGZpZWxkLCB0aGlzLmhlYWRlcltmaWVsZF0pO1xuICB9XG5cbiAgLy8gc2VuZCBzdHVmZlxuICB0aGlzLmVtaXQoJ3JlcXVlc3QnLCB0aGlzKTtcbiAgeGhyLnNlbmQoZGF0YSk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBFeHBvc2UgYFJlcXVlc3RgLlxuICovXG5cbnJlcXVlc3QuUmVxdWVzdCA9IFJlcXVlc3Q7XG5cbi8qKlxuICogSXNzdWUgYSByZXF1ZXN0OlxuICpcbiAqIEV4YW1wbGVzOlxuICpcbiAqICAgIHJlcXVlc3QoJ0dFVCcsICcvdXNlcnMnKS5lbmQoY2FsbGJhY2spXG4gKiAgICByZXF1ZXN0KCcvdXNlcnMnKS5lbmQoY2FsbGJhY2spXG4gKiAgICByZXF1ZXN0KCcvdXNlcnMnLCBjYWxsYmFjaylcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kXG4gKiBAcGFyYW0ge1N0cmluZ3xGdW5jdGlvbn0gdXJsIG9yIGNhbGxiYWNrXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiByZXF1ZXN0KG1ldGhvZCwgdXJsKSB7XG4gIC8vIGNhbGxiYWNrXG4gIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiB1cmwpIHtcbiAgICByZXR1cm4gbmV3IFJlcXVlc3QoJ0dFVCcsIG1ldGhvZCkuZW5kKHVybCk7XG4gIH1cblxuICAvLyB1cmwgZmlyc3RcbiAgaWYgKDEgPT0gYXJndW1lbnRzLmxlbmd0aCkge1xuICAgIHJldHVybiBuZXcgUmVxdWVzdCgnR0VUJywgbWV0aG9kKTtcbiAgfVxuXG4gIHJldHVybiBuZXcgUmVxdWVzdChtZXRob2QsIHVybCk7XG59XG5cbi8qKlxuICogR0VUIGB1cmxgIHdpdGggb3B0aW9uYWwgY2FsbGJhY2sgYGZuKHJlcylgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmxcbiAqIEBwYXJhbSB7TWl4ZWR8RnVuY3Rpb259IGRhdGEgb3IgZm5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5yZXF1ZXN0LmdldCA9IGZ1bmN0aW9uKHVybCwgZGF0YSwgZm4pe1xuICB2YXIgcmVxID0gcmVxdWVzdCgnR0VUJywgdXJsKTtcbiAgaWYgKCdmdW5jdGlvbicgPT0gdHlwZW9mIGRhdGEpIGZuID0gZGF0YSwgZGF0YSA9IG51bGw7XG4gIGlmIChkYXRhKSByZXEucXVlcnkoZGF0YSk7XG4gIGlmIChmbikgcmVxLmVuZChmbik7XG4gIHJldHVybiByZXE7XG59O1xuXG4vKipcbiAqIEhFQUQgYHVybGAgd2l0aCBvcHRpb25hbCBjYWxsYmFjayBgZm4ocmVzKWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHVybFxuICogQHBhcmFtIHtNaXhlZHxGdW5jdGlvbn0gZGF0YSBvciBmblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge1JlcXVlc3R9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbnJlcXVlc3QuaGVhZCA9IGZ1bmN0aW9uKHVybCwgZGF0YSwgZm4pe1xuICB2YXIgcmVxID0gcmVxdWVzdCgnSEVBRCcsIHVybCk7XG4gIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiBkYXRhKSBmbiA9IGRhdGEsIGRhdGEgPSBudWxsO1xuICBpZiAoZGF0YSkgcmVxLnNlbmQoZGF0YSk7XG4gIGlmIChmbikgcmVxLmVuZChmbik7XG4gIHJldHVybiByZXE7XG59O1xuXG4vKipcbiAqIERFTEVURSBgdXJsYCB3aXRoIG9wdGlvbmFsIGNhbGxiYWNrIGBmbihyZXMpYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJsXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHJldHVybiB7UmVxdWVzdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxucmVxdWVzdC5kZWwgPSBmdW5jdGlvbih1cmwsIGZuKXtcbiAgdmFyIHJlcSA9IHJlcXVlc3QoJ0RFTEVURScsIHVybCk7XG4gIGlmIChmbikgcmVxLmVuZChmbik7XG4gIHJldHVybiByZXE7XG59O1xuXG4vKipcbiAqIFBBVENIIGB1cmxgIHdpdGggb3B0aW9uYWwgYGRhdGFgIGFuZCBjYWxsYmFjayBgZm4ocmVzKWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHVybFxuICogQHBhcmFtIHtNaXhlZH0gZGF0YVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge1JlcXVlc3R9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbnJlcXVlc3QucGF0Y2ggPSBmdW5jdGlvbih1cmwsIGRhdGEsIGZuKXtcbiAgdmFyIHJlcSA9IHJlcXVlc3QoJ1BBVENIJywgdXJsKTtcbiAgaWYgKCdmdW5jdGlvbicgPT0gdHlwZW9mIGRhdGEpIGZuID0gZGF0YSwgZGF0YSA9IG51bGw7XG4gIGlmIChkYXRhKSByZXEuc2VuZChkYXRhKTtcbiAgaWYgKGZuKSByZXEuZW5kKGZuKTtcbiAgcmV0dXJuIHJlcTtcbn07XG5cbi8qKlxuICogUE9TVCBgdXJsYCB3aXRoIG9wdGlvbmFsIGBkYXRhYCBhbmQgY2FsbGJhY2sgYGZuKHJlcylgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmxcbiAqIEBwYXJhbSB7TWl4ZWR9IGRhdGFcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5yZXF1ZXN0LnBvc3QgPSBmdW5jdGlvbih1cmwsIGRhdGEsIGZuKXtcbiAgdmFyIHJlcSA9IHJlcXVlc3QoJ1BPU1QnLCB1cmwpO1xuICBpZiAoJ2Z1bmN0aW9uJyA9PSB0eXBlb2YgZGF0YSkgZm4gPSBkYXRhLCBkYXRhID0gbnVsbDtcbiAgaWYgKGRhdGEpIHJlcS5zZW5kKGRhdGEpO1xuICBpZiAoZm4pIHJlcS5lbmQoZm4pO1xuICByZXR1cm4gcmVxO1xufTtcblxuLyoqXG4gKiBQVVQgYHVybGAgd2l0aCBvcHRpb25hbCBgZGF0YWAgYW5kIGNhbGxiYWNrIGBmbihyZXMpYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJsXG4gKiBAcGFyYW0ge01peGVkfEZ1bmN0aW9ufSBkYXRhIG9yIGZuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHJldHVybiB7UmVxdWVzdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxucmVxdWVzdC5wdXQgPSBmdW5jdGlvbih1cmwsIGRhdGEsIGZuKXtcbiAgdmFyIHJlcSA9IHJlcXVlc3QoJ1BVVCcsIHVybCk7XG4gIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiBkYXRhKSBmbiA9IGRhdGEsIGRhdGEgPSBudWxsO1xuICBpZiAoZGF0YSkgcmVxLnNlbmQoZGF0YSk7XG4gIGlmIChmbikgcmVxLmVuZChmbik7XG4gIHJldHVybiByZXE7XG59O1xuXG4vKipcbiAqIEV4cG9zZSBgcmVxdWVzdGAuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSByZXF1ZXN0O1xuIiwiXG4vKipcbiAqIEV4cG9zZSBgRW1pdHRlcmAuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBFbWl0dGVyO1xuXG4vKipcbiAqIEluaXRpYWxpemUgYSBuZXcgYEVtaXR0ZXJgLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gRW1pdHRlcihvYmopIHtcbiAgaWYgKG9iaikgcmV0dXJuIG1peGluKG9iaik7XG59O1xuXG4vKipcbiAqIE1peGluIHRoZSBlbWl0dGVyIHByb3BlcnRpZXMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICogQHJldHVybiB7T2JqZWN0fVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gbWl4aW4ob2JqKSB7XG4gIGZvciAodmFyIGtleSBpbiBFbWl0dGVyLnByb3RvdHlwZSkge1xuICAgIG9ialtrZXldID0gRW1pdHRlci5wcm90b3R5cGVba2V5XTtcbiAgfVxuICByZXR1cm4gb2JqO1xufVxuXG4vKipcbiAqIExpc3RlbiBvbiB0aGUgZ2l2ZW4gYGV2ZW50YCB3aXRoIGBmbmAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHJldHVybiB7RW1pdHRlcn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuRW1pdHRlci5wcm90b3R5cGUub24gPVxuRW1pdHRlci5wcm90b3R5cGUuYWRkRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50LCBmbil7XG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcbiAgKHRoaXMuX2NhbGxiYWNrc1tldmVudF0gPSB0aGlzLl9jYWxsYmFja3NbZXZlbnRdIHx8IFtdKVxuICAgIC5wdXNoKGZuKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEFkZHMgYW4gYGV2ZW50YCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBhIHNpbmdsZVxuICogdGltZSB0aGVuIGF1dG9tYXRpY2FsbHkgcmVtb3ZlZC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtFbWl0dGVyfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5FbWl0dGVyLnByb3RvdHlwZS5vbmNlID0gZnVuY3Rpb24oZXZlbnQsIGZuKXtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB0aGlzLl9jYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3MgfHwge307XG5cbiAgZnVuY3Rpb24gb24oKSB7XG4gICAgc2VsZi5vZmYoZXZlbnQsIG9uKTtcbiAgICBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgb24uZm4gPSBmbjtcbiAgdGhpcy5vbihldmVudCwgb24pO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogUmVtb3ZlIHRoZSBnaXZlbiBjYWxsYmFjayBmb3IgYGV2ZW50YCBvciBhbGxcbiAqIHJlZ2lzdGVyZWQgY2FsbGJhY2tzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge0VtaXR0ZXJ9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkVtaXR0ZXIucHJvdG90eXBlLm9mZiA9XG5FbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9XG5FbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPVxuRW1pdHRlci5wcm90b3R5cGUucmVtb3ZlRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50LCBmbil7XG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcblxuICAvLyBhbGxcbiAgaWYgKDAgPT0gYXJndW1lbnRzLmxlbmd0aCkge1xuICAgIHRoaXMuX2NhbGxiYWNrcyA9IHt9O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gc3BlY2lmaWMgZXZlbnRcbiAgdmFyIGNhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrc1tldmVudF07XG4gIGlmICghY2FsbGJhY2tzKSByZXR1cm4gdGhpcztcblxuICAvLyByZW1vdmUgYWxsIGhhbmRsZXJzXG4gIGlmICgxID09IGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICBkZWxldGUgdGhpcy5fY2FsbGJhY2tzW2V2ZW50XTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIHJlbW92ZSBzcGVjaWZpYyBoYW5kbGVyXG4gIHZhciBjYjtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBjYWxsYmFja3MubGVuZ3RoOyBpKyspIHtcbiAgICBjYiA9IGNhbGxiYWNrc1tpXTtcbiAgICBpZiAoY2IgPT09IGZuIHx8IGNiLmZuID09PSBmbikge1xuICAgICAgY2FsbGJhY2tzLnNwbGljZShpLCAxKTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogRW1pdCBgZXZlbnRgIHdpdGggdGhlIGdpdmVuIGFyZ3MuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XG4gKiBAcGFyYW0ge01peGVkfSAuLi5cbiAqIEByZXR1cm4ge0VtaXR0ZXJ9XG4gKi9cblxuRW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uKGV2ZW50KXtcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuICB2YXIgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKVxuICAgICwgY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzW2V2ZW50XTtcblxuICBpZiAoY2FsbGJhY2tzKSB7XG4gICAgY2FsbGJhY2tzID0gY2FsbGJhY2tzLnNsaWNlKDApO1xuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBjYWxsYmFja3MubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgIGNhbGxiYWNrc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogUmV0dXJuIGFycmF5IG9mIGNhbGxiYWNrcyBmb3IgYGV2ZW50YC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEByZXR1cm4ge0FycmF5fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5FbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lcnMgPSBmdW5jdGlvbihldmVudCl7XG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcbiAgcmV0dXJuIHRoaXMuX2NhbGxiYWNrc1tldmVudF0gfHwgW107XG59O1xuXG4vKipcbiAqIENoZWNrIGlmIHRoaXMgZW1pdHRlciBoYXMgYGV2ZW50YCBoYW5kbGVycy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkVtaXR0ZXIucHJvdG90eXBlLmhhc0xpc3RlbmVycyA9IGZ1bmN0aW9uKGV2ZW50KXtcbiAgcmV0dXJuICEhIHRoaXMubGlzdGVuZXJzKGV2ZW50KS5sZW5ndGg7XG59O1xuIiwiXG4vKipcbiAqIFJlZHVjZSBgYXJyYCB3aXRoIGBmbmAuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gYXJyXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHBhcmFtIHtNaXhlZH0gaW5pdGlhbFxuICpcbiAqIFRPRE86IGNvbWJhdGlibGUgZXJyb3IgaGFuZGxpbmc/XG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihhcnIsIGZuLCBpbml0aWFsKXsgIFxuICB2YXIgaWR4ID0gMDtcbiAgdmFyIGxlbiA9IGFyci5sZW5ndGg7XG4gIHZhciBjdXJyID0gYXJndW1lbnRzLmxlbmd0aCA9PSAzXG4gICAgPyBpbml0aWFsXG4gICAgOiBhcnJbaWR4KytdO1xuXG4gIHdoaWxlIChpZHggPCBsZW4pIHtcbiAgICBjdXJyID0gZm4uY2FsbChudWxsLCBjdXJyLCBhcnJbaWR4XSwgKytpZHgsIGFycik7XG4gIH1cbiAgXG4gIHJldHVybiBjdXJyO1xufTsiXX0= |
| 30575 | |
| 30576 | 'use strict'; |
| 30577 | |
| 30578 | window.SwaggerUi = Backbone.Router.extend({ |
| 30579 | |
| 30580 | dom_id: 'swagger_ui', |
| 30581 | |
| 30582 | // Attributes |
| 30583 | options: null, |
| 30584 | api: null, |
| 30585 | headerView: null, |
| 30586 | mainView: null, |
| 30587 | |
| 30588 | // SwaggerUi accepts all the same options as SwaggerApi |
| 30589 | initialize: function(options) { |
| 30590 | options = options || {}; |
| 30591 | if(!options.highlightSizeThreshold) { |
| 30592 | options.highlightSizeThreshold = 100000; |
| 30593 | } |
| 30594 | |
| 30595 | // Allow dom_id to be overridden |
| 30596 | if (options.dom_id) { |
| 30597 | this.dom_id = options.dom_id; |
| 30598 | delete options.dom_id; |
| 30599 | } |
| 30600 | |
| 30601 | if (!options.supportedSubmitMethods){ |
| 30602 | options.supportedSubmitMethods = [ |
| 30603 | 'get', |
| 30604 | 'put', |
| 30605 | 'post', |
| 30606 | 'delete', |
| 30607 | 'head', |
| 30608 | 'options', |
| 30609 | 'patch' |
| 30610 | ]; |
| 30611 | } |
| 30612 | |
| 30613 | if (typeof options.oauth2RedirectUrl === 'string') { |
| 30614 | window.oAuthRedirectUrl = options.redirectUrl; |
| 30615 | } |
| 30616 | |
| 30617 | // Create an empty div which contains the dom_id |
| 30618 | if (! $('#' + this.dom_id).length){ |
| 30619 | $('body').append('<div id="' + this.dom_id + '"></div>') ; |
| 30620 | } |
| 30621 | |
| 30622 | this.options = options; |
| 30623 | |
| 30624 | // set marked options |
| 30625 | marked.setOptions({gfm: true}); |
| 30626 | |
| 30627 | // Set the callbacks |
| 30628 | var that = this; |
| 30629 | this.options.success = function() { return that.render(); }; |
| 30630 | this.options.progress = function(d) { return that.showMessage(d); }; |
| 30631 | this.options.failure = function(d) { return that.onLoadFailure(d); }; |
| 30632 | |
| 30633 | // Create view to handle the header inputs |
| 30634 | this.headerView = new SwaggerUi.Views.HeaderView({el: $('#header')}); |
| 30635 | |
| 30636 | // Event handler for when the baseUrl/apiKey is entered by user |
| 30637 | this.headerView.on('update-swagger-ui', function(data) { |
| 30638 | return that.updateSwaggerUi(data); |
| 30639 | }); |
| 30640 | }, |
| 30641 | |
| 30642 | // Set an option after initializing |
| 30643 | setOption: function(option, value) { |
| 30644 | this.options[option] = value; |
| 30645 | }, |
| 30646 | |
| 30647 | // Get the value of a previously set option |
| 30648 | getOption: function(option) { |
| 30649 | return this.options[option]; |
| 30650 | }, |
| 30651 | |
| 30652 | // Event handler for when url/key is received from user |
| 30653 | updateSwaggerUi: function(data){ |
| 30654 | this.options.url = data.url; |
| 30655 | this.load(); |
| 30656 | }, |
| 30657 | |
| 30658 | // Create an api and render |
| 30659 | load: function(){ |
| 30660 | // Initialize the API object |
| 30661 | if (this.mainView) { |
| 30662 | this.mainView.clear(); |
| 30663 | } |
| 30664 | var url = this.options.url; |
| 30665 | if (url && url.indexOf('http') !== 0) { |
| 30666 | url = this.buildUrl(window.location.href.toString(), url); |
| 30667 | } |
| 30668 | if(this.api) { |
| 30669 | this.options.authorizations = this.api.clientAuthorizations.authz; |
| 30670 | } |
| 30671 | this.options.url = url; |
| 30672 | this.headerView.update(url); |
| 30673 | |
| 30674 | this.api = new SwaggerClient(this.options); |
| 30675 | }, |
| 30676 | |
| 30677 | // collapse all sections |
| 30678 | collapseAll: function(){ |
| 30679 | Docs.collapseEndpointListForResource(''); |
| 30680 | }, |
| 30681 | |
| 30682 | // list operations for all sections |
| 30683 | listAll: function(){ |
| 30684 | Docs.collapseOperationsForResource(''); |
| 30685 | }, |
| 30686 | |
| 30687 | // expand operations for all sections |
| 30688 | expandAll: function(){ |
| 30689 | Docs.expandOperationsForResource(''); |
| 30690 | }, |
| 30691 | |
| 30692 | // This is bound to success handler for SwaggerApi |
| 30693 | // so it gets called when SwaggerApi completes loading |
| 30694 | render: function(){ |
| 30695 | this.showMessage('Finished Loading Resource Information. Rendering Swagger UI...'); |
| 30696 | this.mainView = new SwaggerUi.Views.MainView({ |
| 30697 | model: this.api, |
| 30698 | el: $('#' + this.dom_id), |
| 30699 | swaggerOptions: this.options, |
| 30700 | router: this |
| 30701 | }).render(); |
| 30702 | this.showMessage(); |
| 30703 | switch (this.options.docExpansion) { |
| 30704 | case 'full': |
| 30705 | this.expandAll(); break; |
| 30706 | case 'list': |
| 30707 | this.listAll(); break; |
| 30708 | default: |
| 30709 | break; |
| 30710 | } |
| 30711 | this.renderGFM(); |
| 30712 | |
| 30713 | if (this.options.onComplete){ |
| 30714 | this.options.onComplete(this.api, this); |
| 30715 | } |
| 30716 | |
| 30717 | setTimeout(Docs.shebang.bind(this), 100); |
| 30718 | }, |
| 30719 | |
| 30720 | buildUrl: function(base, url){ |
| 30721 | if (url.indexOf('/') === 0) { |
| 30722 | var parts = base.split('/'); |
| 30723 | base = parts[0] + '//' + parts[2]; |
| 30724 | return base + url; |
| 30725 | } else { |
| 30726 | var endOfPath = base.length; |
| 30727 | |
| 30728 | if (base.indexOf('?') > -1){ |
| 30729 | endOfPath = Math.min(endOfPath, base.indexOf('?')); |
| 30730 | } |
| 30731 | |
| 30732 | if (base.indexOf('#') > -1){ |
| 30733 | endOfPath = Math.min(endOfPath, base.indexOf('#')); |
| 30734 | } |
| 30735 | |
| 30736 | base = base.substring(0, endOfPath); |
| 30737 | |
| 30738 | if (base.indexOf('/', base.length - 1 ) !== -1){ |
| 30739 | return base + url; |
| 30740 | } |
| 30741 | |
| 30742 | return base + '/' + url; |
| 30743 | } |
| 30744 | }, |
| 30745 | |
| 30746 | // Shows message on topbar of the ui |
| 30747 | showMessage: function(data){ |
| 30748 | if (data === undefined) { |
| 30749 | data = ''; |
| 30750 | } |
| 30751 | $('#message-bar').removeClass('message-fail'); |
| 30752 | $('#message-bar').addClass('message-success'); |
| 30753 | $('#message-bar').text(data); |
| 30754 | }, |
| 30755 | |
| 30756 | // shows message in red |
| 30757 | onLoadFailure: function(data){ |
| 30758 | if (data === undefined) { |
| 30759 | data = ''; |
| 30760 | } |
| 30761 | $('#message-bar').removeClass('message-success'); |
| 30762 | $('#message-bar').addClass('message-fail'); |
| 30763 | |
| 30764 | var val = $('#message-bar').text(data); |
| 30765 | |
| 30766 | if (this.options.onFailure) { |
| 30767 | this.options.onFailure(data); |
| 30768 | } |
| 30769 | |
| 30770 | return val; |
| 30771 | }, |
| 30772 | |
| 30773 | // Renders GFM for elements with 'markdown' class |
| 30774 | renderGFM: function(){ |
| 30775 | $('.markdown').each(function(){ |
| 30776 | $(this).html(marked($(this).html())); |
| 30777 | }); |
| 30778 | |
| 30779 | $('.propDesc', '.model-signature .description').each(function () { |
| 30780 | $(this).html(marked($(this).html())).addClass('markdown'); |
| 30781 | }); |
| 30782 | } |
| 30783 | |
| 30784 | }); |
| 30785 | |
| 30786 | window.SwaggerUi.Views = {}; |
| 30787 | |
| 30788 | // don't break backward compatibility with previous versions and warn users to upgrade their code |
| 30789 | (function(){ |
| 30790 | window.authorizations = { |
| 30791 | add: function() { |
| 30792 | warn('Using window.authorizations is deprecated. Please use SwaggerUi.api.clientAuthorizations.add().'); |
| 30793 | |
| 30794 | if (typeof window.swaggerUi === 'undefined') { |
| 30795 | throw new TypeError('window.swaggerUi is not defined'); |
| 30796 | } |
| 30797 | |
| 30798 | if (window.swaggerUi instanceof SwaggerUi) { |
| 30799 | window.swaggerUi.api.clientAuthorizations.add.apply(window.swaggerUi.api.clientAuthorizations, arguments); |
| 30800 | } |
| 30801 | } |
| 30802 | }; |
| 30803 | |
| 30804 | window.ApiKeyAuthorization = function() { |
| 30805 | warn('window.ApiKeyAuthorization is deprecated. Please use SwaggerClient.ApiKeyAuthorization.'); |
| 30806 | SwaggerClient.ApiKeyAuthorization.apply(window, arguments); |
| 30807 | }; |
| 30808 | |
| 30809 | window.PasswordAuthorization = function() { |
| 30810 | warn('window.PasswordAuthorization is deprecated. Please use SwaggerClient.PasswordAuthorization.'); |
| 30811 | SwaggerClient.PasswordAuthorization.apply(window, arguments); |
| 30812 | }; |
| 30813 | |
| 30814 | function warn(message) { |
| 30815 | if ('console' in window && typeof window.console.warn === 'function') { |
| 30816 | console.warn(message); |
| 30817 | } |
| 30818 | } |
| 30819 | })(); |
| 30820 | |
| 30821 | |
| 30822 | // UMD |
| 30823 | (function (root, factory) { |
| 30824 | if (typeof define === 'function' && define.amd) { |
| 30825 | // AMD. Register as an anonymous module. |
| 30826 | define(['b'], function (b) { |
| 30827 | return (root.SwaggerUi = factory(b)); |
| 30828 | }); |
| 30829 | } else if (typeof exports === 'object') { |
| 30830 | // Node. Does not work with strict CommonJS, but |
| 30831 | // only CommonJS-like enviroments that support module.exports, |
| 30832 | // like Node. |
| 30833 | module.exports = factory(require('b')); |
| 30834 | } else { |
| 30835 | // Browser globals |
| 30836 | root.SwaggerUi = factory(root.b); |
| 30837 | } |
| 30838 | }(this, function () { |
| 30839 | return SwaggerUi; |
| 30840 | })); |
| 30841 | |
| 30842 | 'use strict'; |
| 30843 | |
| 30844 | SwaggerUi.Views.ApiKeyButton = Backbone.View.extend({ // TODO: append this to global SwaggerUi |
| 30845 | |
| 30846 | events:{ |
| 30847 | 'click #apikey_button' : 'toggleApiKeyContainer', |
| 30848 | 'click #apply_api_key' : 'applyApiKey' |
| 30849 | }, |
| 30850 | |
| 30851 | initialize: function(opts){ |
| 30852 | this.options = opts || {}; |
| 30853 | this.router = this.options.router; |
| 30854 | }, |
| 30855 | |
| 30856 | render: function(){ |
| 30857 | var template = this.template(); |
| 30858 | $(this.el).html(template(this.model)); |
| 30859 | |
| 30860 | return this; |
| 30861 | }, |
| 30862 | |
| 30863 | |
| 30864 | applyApiKey: function(){ |
| 30865 | var keyAuth = new SwaggerClient.ApiKeyAuthorization( |
| 30866 | this.model.name, |
| 30867 | $('#input_apiKey_entry').val(), |
| 30868 | this.model.in |
| 30869 | ); |
| 30870 | this.router.api.clientAuthorizations.add(this.model.name, keyAuth); |
| 30871 | this.router.load(); |
| 30872 | $('#apikey_container').show(); |
| 30873 | }, |
| 30874 | |
| 30875 | toggleApiKeyContainer: function(){ |
| 30876 | if ($('#apikey_container').length) { |
| 30877 | |
| 30878 | var elem = $('#apikey_container').first(); |
| 30879 | |
| 30880 | if (elem.is(':visible')){ |
| 30881 | elem.hide(); |
| 30882 | } else { |
| 30883 | |
| 30884 | // hide others |
| 30885 | $('.auth_container').hide(); |
| 30886 | elem.show(); |
| 30887 | } |
| 30888 | } |
| 30889 | }, |
| 30890 | |
| 30891 | template: function(){ |
| 30892 | return Handlebars.templates.apikey_button_view; |
| 30893 | } |
| 30894 | |
| 30895 | }); |
| 30896 | 'use strict'; |
| 30897 | |
| 30898 | SwaggerUi.Views.BasicAuthButton = Backbone.View.extend({ |
| 30899 | |
| 30900 | |
| 30901 | initialize: function (opts) { |
| 30902 | this.options = opts || {}; |
| 30903 | this.router = this.options.router; |
| 30904 | }, |
| 30905 | |
| 30906 | render: function(){ |
| 30907 | var template = this.template(); |
| 30908 | $(this.el).html(template(this.model)); |
| 30909 | |
| 30910 | return this; |
| 30911 | }, |
| 30912 | |
| 30913 | events: { |
| 30914 | 'click #basic_auth_button' : 'togglePasswordContainer', |
| 30915 | 'click #apply_basic_auth' : 'applyPassword' |
| 30916 | }, |
| 30917 | |
| 30918 | applyPassword: function(){ |
| 30919 | var username = $('.input_username').val(); |
| 30920 | var password = $('.input_password').val(); |
| 30921 | var basicAuth = new SwaggerClient.PasswordAuthorization('basic', username, password); |
| 30922 | this.router.api.clientAuthorizations.add(this.model.type, basicAuth); |
| 30923 | this.router.load(); |
| 30924 | $('#basic_auth_container').hide(); |
| 30925 | }, |
| 30926 | |
| 30927 | togglePasswordContainer: function(){ |
| 30928 | if ($('#basic_auth_container').length) { |
| 30929 | var elem = $('#basic_auth_container').show(); |
| 30930 | if (elem.is(':visible')){ |
| 30931 | elem.slideUp(); |
| 30932 | } else { |
| 30933 | // hide others |
| 30934 | $('.auth_container').hide(); |
| 30935 | elem.show(); |
| 30936 | } |
| 30937 | } |
| 30938 | }, |
| 30939 | |
| 30940 | template: function(){ |
| 30941 | return Handlebars.templates.basic_auth_button_view; |
| 30942 | } |
| 30943 | |
| 30944 | }); |
| 30945 | 'use strict'; |
| 30946 | |
| 30947 | SwaggerUi.Views.ContentTypeView = Backbone.View.extend({ |
| 30948 | initialize: function() {}, |
| 30949 | |
| 30950 | render: function(){ |
| 30951 | this.model.contentTypeId = 'ct' + Math.random(); |
| 30952 | $(this.el).html(Handlebars.templates.content_type(this.model)); |
| 30953 | return this; |
| 30954 | } |
| 30955 | }); |
| 30956 | 'use strict'; |
| 30957 | |
| 30958 | SwaggerUi.Views.HeaderView = Backbone.View.extend({ |
| 30959 | events: { |
| 30960 | 'click #show-pet-store-icon' : 'showPetStore', |
| 30961 | 'click #explore' : 'showCustom', |
| 30962 | 'keyup #input_baseUrl' : 'showCustomOnKeyup', |
| 30963 | 'keyup #input_apiKey' : 'showCustomOnKeyup' |
| 30964 | }, |
| 30965 | |
| 30966 | initialize: function(){}, |
| 30967 | |
| 30968 | showPetStore: function(){ |
| 30969 | this.trigger('update-swagger-ui', { |
| 30970 | url:'http://petstore.swagger.io/v2/swagger.json' |
| 30971 | }); |
| 30972 | }, |
| 30973 | |
| 30974 | showCustomOnKeyup: function(e){ |
| 30975 | if (e.keyCode === 13) { |
| 30976 | this.showCustom(); |
| 30977 | } |
| 30978 | }, |
| 30979 | |
| 30980 | showCustom: function(e){ |
| 30981 | if (e) { |
| 30982 | e.preventDefault(); |
| 30983 | } |
| 30984 | |
| 30985 | this.trigger('update-swagger-ui', { |
| 30986 | url: $('#input_baseUrl').val(), |
| 30987 | apiKey: $('#input_apiKey').val() |
| 30988 | }); |
| 30989 | }, |
| 30990 | |
| 30991 | update: function(url, apiKey, trigger){ |
| 30992 | if (trigger === undefined) { |
| 30993 | trigger = false; |
| 30994 | } |
| 30995 | |
| 30996 | $('#input_baseUrl').val(url); |
| 30997 | |
| 30998 | //$('#input_apiKey').val(apiKey); |
| 30999 | if (trigger) { |
| 31000 | this.trigger('update-swagger-ui', {url:url}); |
| 31001 | } |
| 31002 | } |
| 31003 | }); |
| 31004 | |
| 31005 | 'use strict'; |
| 31006 | |
| 31007 | SwaggerUi.Views.MainView = Backbone.View.extend({ |
| 31008 | apisSorter : { |
| 31009 | alpha : function(a,b){ return a.name.localeCompare(b.name); } |
| 31010 | }, |
| 31011 | operationsSorters : { |
| 31012 | alpha : function(a,b){ return a.path.localeCompare(b.path); }, |
| 31013 | method : function(a,b){ return a.method.localeCompare(b.method); } |
| 31014 | }, |
| 31015 | initialize: function(opts){ |
| 31016 | var sorterOption, sorterFn, key, value; |
| 31017 | opts = opts || {}; |
| 31018 | |
| 31019 | this.router = opts.router; |
| 31020 | |
| 31021 | // Sort APIs |
| 31022 | if (opts.swaggerOptions.apisSorter) { |
| 31023 | sorterOption = opts.swaggerOptions.apisSorter; |
| 31024 | if (_.isFunction(sorterOption)) { |
| 31025 | sorterFn = sorterOption; |
| 31026 | } else { |
| 31027 | sorterFn = this.apisSorter[sorterOption]; |
| 31028 | } |
| 31029 | if (_.isFunction(sorterFn)) { |
| 31030 | this.model.apisArray.sort(sorterFn); |
| 31031 | } |
| 31032 | } |
| 31033 | // Sort operations of each API |
| 31034 | if (opts.swaggerOptions.operationsSorter) { |
| 31035 | sorterOption = opts.swaggerOptions.operationsSorter; |
| 31036 | if (_.isFunction(sorterOption)) { |
| 31037 | sorterFn = sorterOption; |
| 31038 | } else { |
| 31039 | sorterFn = this.operationsSorters[sorterOption]; |
| 31040 | } |
| 31041 | if (_.isFunction(sorterFn)) { |
| 31042 | for (key in this.model.apisArray) { |
| 31043 | this.model.apisArray[key].operationsArray.sort(sorterFn); |
| 31044 | } |
| 31045 | } |
| 31046 | } |
| 31047 | |
| 31048 | // set up the UI for input |
| 31049 | this.model.auths = []; |
| 31050 | |
| 31051 | for (key in this.model.securityDefinitions) { |
| 31052 | value = this.model.securityDefinitions[key]; |
| 31053 | |
| 31054 | this.model.auths.push({ |
| 31055 | name: key, |
| 31056 | type: value.type, |
| 31057 | value: value |
| 31058 | }); |
| 31059 | } |
| 31060 | |
| 31061 | if ('validatorUrl' in opts.swaggerOptions) { |
| 31062 | // Validator URL specified explicitly |
| 31063 | this.model.validatorUrl = opts.swaggerOptions.validatorUrl; |
| 31064 | } else if (this.model.url.indexOf('localhost') > 0) { |
| 31065 | // Localhost override |
| 31066 | this.model.validatorUrl = null; |
| 31067 | } else { |
| 31068 | // Default validator |
| 31069 | if(window.location.protocol === 'https') { |
| 31070 | this.model.validatorUrl = 'https://online.swagger.io/validator'; |
| 31071 | } |
| 31072 | else { |
| 31073 | this.model.validatorUrl = 'http://online.swagger.io/validator'; |
| 31074 | } |
| 31075 | } |
| 31076 | }, |
| 31077 | |
| 31078 | render: function(){ |
| 31079 | if (this.model.securityDefinitions) { |
| 31080 | for (var name in this.model.securityDefinitions) { |
| 31081 | var auth = this.model.securityDefinitions[name]; |
| 31082 | var button; |
| 31083 | |
| 31084 | if (auth.type === 'apiKey' && $('#apikey_button').length === 0) { |
| 31085 | button = new SwaggerUi.Views.ApiKeyButton({model: auth, router: this.router}).render().el; |
| 31086 | $('.auth_main_container').append(button); |
| 31087 | } |
| 31088 | |
| 31089 | if (auth.type === 'basicAuth' && $('#basic_auth_button').length === 0) { |
| 31090 | button = new SwaggerUi.Views.BasicAuthButton({model: auth, router: this.router}).render().el; |
| 31091 | $('.auth_main_container').append(button); |
| 31092 | } |
| 31093 | } |
| 31094 | } |
| 31095 | |
| 31096 | // Render the outer container for resources |
| 31097 | $(this.el).html(Handlebars.templates.main(this.model)); |
| 31098 | |
| 31099 | // Render each resource |
| 31100 | |
| 31101 | var resources = {}; |
| 31102 | var counter = 0; |
| 31103 | for (var i = 0; i < this.model.apisArray.length; i++) { |
| 31104 | var resource = this.model.apisArray[i]; |
| 31105 | var id = resource.name; |
| 31106 | while (typeof resources[id] !== 'undefined') { |
| 31107 | id = id + '_' + counter; |
| 31108 | counter += 1; |
| 31109 | } |
| 31110 | resource.id = id; |
| 31111 | resources[id] = resource; |
| 31112 | this.addResource(resource, this.model.auths); |
| 31113 | } |
| 31114 | |
| 31115 | $('.propWrap').hover(function onHover(){ |
| 31116 | $('.optionsWrapper', $(this)).show(); |
| 31117 | }, function offhover(){ |
| 31118 | $('.optionsWrapper', $(this)).hide(); |
| 31119 | }); |
| 31120 | return this; |
| 31121 | }, |
| 31122 | |
| 31123 | addResource: function(resource, auths){ |
| 31124 | // Render a resource and add it to resources li |
| 31125 | resource.id = resource.id.replace(/\s/g, '_'); |
| 31126 | var resourceView = new SwaggerUi.Views.ResourceView({ |
| 31127 | model: resource, |
| 31128 | router: this.router, |
| 31129 | tagName: 'li', |
| 31130 | id: 'resource_' + resource.id, |
| 31131 | className: 'resource', |
| 31132 | auths: auths, |
| 31133 | swaggerOptions: this.options.swaggerOptions |
| 31134 | }); |
| 31135 | $('#resources', this.el).append(resourceView.render().el); |
| 31136 | }, |
| 31137 | |
| 31138 | clear: function(){ |
| 31139 | $(this.el).html(''); |
| 31140 | } |
| 31141 | }); |
| 31142 | |
| 31143 | 'use strict'; |
| 31144 | |
| 31145 | SwaggerUi.Views.OperationView = Backbone.View.extend({ |
| 31146 | invocationUrl: null, |
| 31147 | |
| 31148 | events: { |
| 31149 | 'submit .sandbox' : 'submitOperation', |
| 31150 | 'click .submit' : 'submitOperation', |
| 31151 | 'click .response_hider' : 'hideResponse', |
| 31152 | 'click .toggleOperation' : 'toggleOperationContent', |
| 31153 | 'mouseenter .api-ic' : 'mouseEnter', |
| 31154 | 'mouseout .api-ic' : 'mouseExit', |
| 31155 | 'dblclick .curl' : 'selectText', |
| 31156 | }, |
| 31157 | |
| 31158 | initialize: function(opts) { |
| 31159 | opts = opts || {}; |
| 31160 | this.router = opts.router; |
| 31161 | this.auths = opts.auths; |
| 31162 | this.parentId = this.model.parentId; |
| 31163 | this.nickname = this.model.nickname; |
| 31164 | this.model.encodedParentId = encodeURIComponent(this.parentId); |
| 31165 | return this; |
| 31166 | }, |
| 31167 | |
| 31168 | selectText: function(event) { |
| 31169 | var doc = document, |
| 31170 | text = event.target.firstChild, |
| 31171 | range, |
| 31172 | selection; |
| 31173 | if (doc.body.createTextRange) { |
| 31174 | range = document.body.createTextRange(); |
| 31175 | range.moveToElementText(text); |
| 31176 | range.select(); |
| 31177 | } else if (window.getSelection) { |
| 31178 | selection = window.getSelection(); |
| 31179 | range = document.createRange(); |
| 31180 | range.selectNodeContents(text); |
| 31181 | selection.removeAllRanges(); |
| 31182 | selection.addRange(range); |
| 31183 | } |
| 31184 | }, |
| 31185 | |
| 31186 | mouseEnter: function(e) { |
| 31187 | var elem = $(this.el).find('.content'); |
| 31188 | var x = e.pageX; |
| 31189 | var y = e.pageY; |
| 31190 | var scX = $(window).scrollLeft(); |
| 31191 | var scY = $(window).scrollTop(); |
| 31192 | var scMaxX = scX + $(window).width(); |
| 31193 | var scMaxY = scY + $(window).height(); |
| 31194 | var wd = elem.width(); |
| 31195 | var hgh = elem.height(); |
| 31196 | |
| 31197 | if (x + wd > scMaxX) { |
| 31198 | x = scMaxX - wd; |
| 31199 | } |
| 31200 | |
| 31201 | if (x < scX) { |
| 31202 | x = scX; |
| 31203 | } |
| 31204 | |
| 31205 | if (y + hgh > scMaxY) { |
| 31206 | y = scMaxY - hgh; |
| 31207 | } |
| 31208 | |
| 31209 | if (y < scY) { |
| 31210 | y = scY; |
| 31211 | } |
| 31212 | |
| 31213 | var pos = {}; |
| 31214 | pos.top = y; |
| 31215 | pos.left = x; |
| 31216 | elem.css(pos); |
| 31217 | $(e.currentTarget.parentNode).find('#api_information_panel').show(); |
| 31218 | }, |
| 31219 | |
| 31220 | mouseExit: function(e) { |
| 31221 | $(e.currentTarget.parentNode).find('#api_information_panel').hide(); |
| 31222 | }, |
| 31223 | |
| 31224 | // Note: copied from CoffeeScript compiled file |
| 31225 | // TODO: redactor |
| 31226 | render: function() { |
| 31227 | 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; |
| 31228 | isMethodSubmissionSupported = jQuery.inArray(this.model.method, this.model.supportedSubmitMethods()) >= 0; |
| 31229 | if (!isMethodSubmissionSupported) { |
| 31230 | this.model.isReadOnly = true; |
| 31231 | } |
| 31232 | this.model.description = this.model.description || this.model.notes; |
| 31233 | this.model.oauth = null; |
| 31234 | modelAuths = this.model.authorizations || this.model.security; |
| 31235 | if (modelAuths) { |
| 31236 | if (Array.isArray(modelAuths)) { |
| 31237 | for (l = 0, len = modelAuths.length; l < len; l++) { |
| 31238 | auths = modelAuths[l]; |
| 31239 | for (key in auths) { |
| 31240 | auth = auths[key]; |
| 31241 | for (a in this.auths) { |
| 31242 | auth = this.auths[a]; |
| 31243 | if (auth.type === 'oauth2') { |
| 31244 | this.model.oauth = {}; |
| 31245 | this.model.oauth.scopes = []; |
| 31246 | ref1 = auth.value.scopes; |
| 31247 | for (k in ref1) { |
| 31248 | v = ref1[k]; |
| 31249 | scopeIndex = auths[key].indexOf(k); |
| 31250 | if (scopeIndex >= 0) { |
| 31251 | o = { |
| 31252 | scope: k, |
| 31253 | description: v |
| 31254 | }; |
| 31255 | this.model.oauth.scopes.push(o); |
| 31256 | } |
| 31257 | } |
| 31258 | } |
| 31259 | } |
| 31260 | } |
| 31261 | } |
| 31262 | } else { |
| 31263 | for (k in modelAuths) { |
| 31264 | v = modelAuths[k]; |
| 31265 | if (k === 'oauth2') { |
| 31266 | if (this.model.oauth === null) { |
| 31267 | this.model.oauth = {}; |
| 31268 | } |
| 31269 | if (this.model.oauth.scopes === void 0) { |
| 31270 | this.model.oauth.scopes = []; |
| 31271 | } |
| 31272 | for (m = 0, len1 = v.length; m < len1; m++) { |
| 31273 | o = v[m]; |
| 31274 | this.model.oauth.scopes.push(o); |
| 31275 | } |
| 31276 | } |
| 31277 | } |
| 31278 | } |
| 31279 | } |
| 31280 | if (typeof this.model.responses !== 'undefined') { |
| 31281 | this.model.responseMessages = []; |
| 31282 | ref2 = this.model.responses; |
| 31283 | for (code in ref2) { |
| 31284 | value = ref2[code]; |
| 31285 | schema = null; |
| 31286 | schemaObj = this.model.responses[code].schema; |
| 31287 | if (schemaObj && schemaObj.$ref) { |
| 31288 | schema = schemaObj.$ref; |
| 31289 | if (schema.indexOf('#/definitions/') === 0) { |
| 31290 | schema = schema.substring('#/definitions/'.length); |
| 31291 | } |
| 31292 | } |
| 31293 | this.model.responseMessages.push({ |
| 31294 | code: code, |
| 31295 | message: value.description, |
| 31296 | responseModel: schema |
| 31297 | }); |
| 31298 | } |
| 31299 | } |
| 31300 | if (typeof this.model.responseMessages === 'undefined') { |
| 31301 | this.model.responseMessages = []; |
| 31302 | } |
| 31303 | signatureModel = null; |
| 31304 | if (this.model.successResponse) { |
| 31305 | successResponse = this.model.successResponse; |
| 31306 | for (key in successResponse) { |
| 31307 | value = successResponse[key]; |
| 31308 | this.model.successCode = key; |
| 31309 | if (typeof value === 'object' && typeof value.createJSONSample === 'function') { |
| 31310 | signatureModel = { |
| 31311 | sampleJSON: JSON.stringify(value.createJSONSample(), void 0, 2), |
| 31312 | isParam: false, |
| 31313 | signature: value.getMockSignature() |
| 31314 | }; |
| 31315 | } |
| 31316 | } |
| 31317 | } else if (this.model.responseClassSignature && this.model.responseClassSignature !== 'string') { |
| 31318 | signatureModel = { |
| 31319 | sampleJSON: this.model.responseSampleJSON, |
| 31320 | isParam: false, |
| 31321 | signature: this.model.responseClassSignature |
| 31322 | }; |
| 31323 | } |
| 31324 | var opts = this.options.swaggerOptions; |
| 31325 | if (opts.showRequestHeaders) { |
| 31326 | this.model.showRequestHeaders = true; |
| 31327 | } |
| 31328 | $(this.el).html(Handlebars.templates.operation(this.model)); |
| 31329 | if (signatureModel) { |
| 31330 | responseSignatureView = new SwaggerUi.Views.SignatureView({ |
| 31331 | model: signatureModel, |
| 31332 | router: this.router, |
| 31333 | tagName: 'div' |
| 31334 | }); |
| 31335 | $('.model-signature', $(this.el)).append(responseSignatureView.render().el); |
| 31336 | } else { |
| 31337 | this.model.responseClassSignature = 'string'; |
| 31338 | $('.model-signature', $(this.el)).html(this.model.type); |
| 31339 | } |
| 31340 | contentTypeModel = { |
| 31341 | isParam: false |
| 31342 | }; |
| 31343 | contentTypeModel.consumes = this.model.consumes; |
| 31344 | contentTypeModel.produces = this.model.produces; |
| 31345 | ref3 = this.model.parameters; |
| 31346 | for (n = 0, len2 = ref3.length; n < len2; n++) { |
| 31347 | param = ref3[n]; |
| 31348 | type = param.type || param.dataType || ''; |
| 31349 | if (typeof type === 'undefined') { |
| 31350 | schema = param.schema; |
| 31351 | if (schema && schema.$ref) { |
| 31352 | ref = schema.$ref; |
| 31353 | if (ref.indexOf('#/definitions/') === 0) { |
| 31354 | type = ref.substring('#/definitions/'.length); |
| 31355 | } else { |
| 31356 | type = ref; |
| 31357 | } |
| 31358 | } |
| 31359 | } |
| 31360 | if (type && type.toLowerCase() === 'file') { |
| 31361 | if (!contentTypeModel.consumes) { |
| 31362 | contentTypeModel.consumes = 'multipart/form-data'; |
| 31363 | } |
| 31364 | } |
| 31365 | param.type = type; |
| 31366 | } |
| 31367 | responseContentTypeView = new SwaggerUi.Views.ResponseContentTypeView({ |
| 31368 | model: contentTypeModel, |
| 31369 | router: this.router |
| 31370 | }); |
| 31371 | $('.response-content-type', $(this.el)).append(responseContentTypeView.render().el); |
| 31372 | ref4 = this.model.parameters; |
| 31373 | for (p = 0, len3 = ref4.length; p < len3; p++) { |
| 31374 | param = ref4[p]; |
| 31375 | this.addParameter(param, contentTypeModel.consumes); |
| 31376 | } |
| 31377 | ref5 = this.model.responseMessages; |
| 31378 | for (q = 0, len4 = ref5.length; q < len4; q++) { |
| 31379 | statusCode = ref5[q]; |
| 31380 | this.addStatusCode(statusCode); |
| 31381 | } |
| 31382 | return this; |
| 31383 | }, |
| 31384 | |
| 31385 | addParameter: function(param, consumes) { |
| 31386 | // Render a parameter |
| 31387 | param.consumes = consumes; |
| 31388 | var paramView = new SwaggerUi.Views.ParameterView({ |
| 31389 | model: param, |
| 31390 | tagName: 'tr', |
| 31391 | readOnly: this.model.isReadOnly |
| 31392 | }); |
| 31393 | $('.operation-params', $(this.el)).append(paramView.render().el); |
| 31394 | }, |
| 31395 | |
| 31396 | addStatusCode: function(statusCode) { |
| 31397 | // Render status codes |
| 31398 | var statusCodeView = new SwaggerUi.Views.StatusCodeView({ |
| 31399 | model: statusCode, |
| 31400 | tagName: 'tr', |
| 31401 | router: this.router |
| 31402 | }); |
| 31403 | $('.operation-status', $(this.el)).append(statusCodeView.render().el); |
| 31404 | }, |
| 31405 | |
| 31406 | // Note: copied from CoffeeScript compiled file |
| 31407 | // TODO: redactor |
| 31408 | submitOperation: function(e) { |
| 31409 | var error_free, form, isFileUpload, map, opts; |
| 31410 | if (e !== null) { |
| 31411 | e.preventDefault(); |
| 31412 | } |
| 31413 | form = $('.sandbox', $(this.el)); |
| 31414 | error_free = true; |
| 31415 | form.find('input.required').each(function() { |
| 31416 | $(this).removeClass('error'); |
| 31417 | if (jQuery.trim($(this).val()) === '') { |
| 31418 | $(this).addClass('error'); |
| 31419 | $(this).wiggle({ |
| 31420 | callback: (function(_this) { |
| 31421 | return function() { |
| 31422 | $(_this).focus(); |
| 31423 | }; |
| 31424 | })(this) |
| 31425 | }); |
| 31426 | error_free = false; |
| 31427 | } |
| 31428 | }); |
| 31429 | form.find('textarea.required').each(function() { |
| 31430 | $(this).removeClass('error'); |
| 31431 | if (jQuery.trim($(this).val()) === '') { |
| 31432 | $(this).addClass('error'); |
| 31433 | $(this).wiggle({ |
| 31434 | callback: (function(_this) { |
| 31435 | return function() { |
| 31436 | return $(_this).focus(); |
| 31437 | }; |
| 31438 | })(this) |
| 31439 | }); |
| 31440 | error_free = false; |
| 31441 | } |
| 31442 | }); |
| 31443 | form.find('select.required').each(function() { |
| 31444 | $(this).removeClass('error'); |
| 31445 | if (this.selectedIndex === -1) { |
| 31446 | $(this).addClass('error'); |
| 31447 | $(this).wiggle({ |
| 31448 | callback: (function(_this) { |
| 31449 | return function() { |
| 31450 | $(_this).focus(); |
| 31451 | }; |
| 31452 | })(this) |
| 31453 | }); |
| 31454 | error_free = false; |
| 31455 | } |
| 31456 | }); |
| 31457 | if (error_free) { |
| 31458 | map = this.getInputMap(form); |
| 31459 | isFileUpload = this.isFileUpload(form); |
| 31460 | opts = { |
| 31461 | parent: this |
| 31462 | }; |
| 31463 | if (this.options.swaggerOptions) { |
| 31464 | for(var key in this.options.swaggerOptions) { |
| 31465 | opts[key] = this.options.swaggerOptions[key]; |
| 31466 | } |
| 31467 | } |
| 31468 | opts.responseContentType = $('div select[name=responseContentType]', $(this.el)).val(); |
| 31469 | opts.requestContentType = $('div select[name=parameterContentType]', $(this.el)).val(); |
| 31470 | $('.response_throbber', $(this.el)).show(); |
| 31471 | if (isFileUpload) { |
| 31472 | $('.request_url', $(this.el)).html('<pre></pre>'); |
| 31473 | $('.request_url pre', $(this.el)).text(this.invocationUrl); |
| 31474 | |
| 31475 | opts.useJQuery = true; |
| 31476 | map.parameterContentType = 'multipart/form-data'; |
| 31477 | |
| 31478 | return this.model.execute(map, opts, this.showCompleteStatus, this.showErrorStatus, this); |
| 31479 | } else { |
| 31480 | this.map = map; |
| 31481 | return this.model.execute(map, opts, this.showCompleteStatus, this.showErrorStatus, this); |
| 31482 | } |
| 31483 | } |
| 31484 | }, |
| 31485 | |
| 31486 | getInputMap: function (form) { |
| 31487 | var map, ref1, l, len, o, ref2, m, len1, val, ref3, n, len2; |
| 31488 | map = {}; |
| 31489 | ref1 = form.find('input'); |
| 31490 | for (l = 0, len = ref1.length; l < len; l++) { |
| 31491 | o = ref1[l]; |
| 31492 | if ((o.value !== null) && jQuery.trim(o.value).length > 0) { |
| 31493 | map[o.name] = o.value; |
| 31494 | } |
| 31495 | if (o.type === 'file') { |
| 31496 | map[o.name] = o.files[0]; |
| 31497 | } |
| 31498 | } |
| 31499 | ref2 = form.find('textarea'); |
| 31500 | for (m = 0, len1 = ref2.length; m < len1; m++) { |
| 31501 | o = ref2[m]; |
| 31502 | val = this.getTextAreaValue(o); |
| 31503 | if ((val !== null) && jQuery.trim(val).length > 0) { |
| 31504 | map[o.name] = val; |
| 31505 | } |
| 31506 | } |
| 31507 | ref3 = form.find('select'); |
| 31508 | for (n = 0, len2 = ref3.length; n < len2; n++) { |
| 31509 | o = ref3[n]; |
| 31510 | val = this.getSelectedValue(o); |
| 31511 | if ((val !== null) && jQuery.trim(val).length > 0) { |
| 31512 | map[o.name] = val; |
| 31513 | } |
| 31514 | } |
| 31515 | return map; |
| 31516 | }, |
| 31517 | |
| 31518 | isFileUpload: function (form) { |
| 31519 | var ref1, l, len, o; |
| 31520 | var isFileUpload = false; |
| 31521 | ref1 = form.find('input'); |
| 31522 | for (l = 0, len = ref1.length; l < len; l++) { |
| 31523 | o = ref1[l]; |
| 31524 | if (o.type === 'file') { |
| 31525 | isFileUpload = true; |
| 31526 | } |
| 31527 | } |
| 31528 | return isFileUpload; |
| 31529 | }, |
| 31530 | |
| 31531 | success: function(response, parent) { |
| 31532 | parent.showCompleteStatus(response); |
| 31533 | }, |
| 31534 | |
| 31535 | // wraps a jquery response as a shred response |
| 31536 | wrap: function(data) { |
| 31537 | var h, headerArray, headers, i, l, len, o; |
| 31538 | headers = {}; |
| 31539 | headerArray = data.getAllResponseHeaders().split('\r'); |
| 31540 | for (l = 0, len = headerArray.length; l < len; l++) { |
| 31541 | i = headerArray[l]; |
| 31542 | h = i.match(/^([^:]*?):(.*)$/); |
| 31543 | if (!h) { |
| 31544 | h = []; |
| 31545 | } |
| 31546 | h.shift(); |
| 31547 | if (h[0] !== void 0 && h[1] !== void 0) { |
| 31548 | headers[h[0].trim()] = h[1].trim(); |
| 31549 | } |
| 31550 | } |
| 31551 | o = {}; |
| 31552 | o.content = {}; |
| 31553 | o.content.data = data.responseText; |
| 31554 | o.headers = headers; |
| 31555 | o.request = {}; |
| 31556 | o.request.url = this.invocationUrl; |
| 31557 | o.status = data.status; |
| 31558 | return o; |
| 31559 | }, |
| 31560 | |
| 31561 | getSelectedValue: function(select) { |
| 31562 | if (!select.multiple) { |
| 31563 | return select.value; |
| 31564 | } else { |
| 31565 | var options = []; |
| 31566 | for (var l = 0, len = select.options.length; l < len; l++) { |
| 31567 | var opt = select.options[l]; |
| 31568 | if (opt.selected) { |
| 31569 | options.push(opt.value); |
| 31570 | } |
| 31571 | } |
| 31572 | if (options.length > 0) { |
| 31573 | return options; |
| 31574 | } else { |
| 31575 | return null; |
| 31576 | } |
| 31577 | } |
| 31578 | }, |
| 31579 | |
| 31580 | // handler for hide response link |
| 31581 | hideResponse: function(e) { |
| 31582 | if (e) { e.preventDefault(); } |
| 31583 | $('.response', $(this.el)).slideUp(); |
| 31584 | $('.response_hider', $(this.el)).fadeOut(); |
| 31585 | }, |
| 31586 | |
| 31587 | // Show response from server |
| 31588 | showResponse: function(response) { |
| 31589 | var prettyJson = JSON.stringify(response, null, '\t').replace(/\n/g, '<br>'); |
| 31590 | $('.response_body', $(this.el)).html(_.escape(prettyJson)); |
| 31591 | }, |
| 31592 | |
| 31593 | // Show error from server |
| 31594 | showErrorStatus: function(data, parent) { |
| 31595 | parent.showStatus(data); |
| 31596 | }, |
| 31597 | |
| 31598 | // show the status codes |
| 31599 | showCompleteStatus: function(data, parent){ |
| 31600 | parent.showStatus(data); |
| 31601 | }, |
| 31602 | |
| 31603 | // Adapted from http://stackoverflow.com/a/2893259/454004 |
| 31604 | // Note: directly ported from CoffeeScript |
| 31605 | // TODO: Cleanup CoffeeScript artifacts |
| 31606 | formatXml: function(xml) { |
| 31607 | var contexp, fn, formatted, indent, l, lastType, len, lines, ln, pad, reg, transitions, wsexp; |
| 31608 | reg = /(>)(<)(\/*)/g; |
| 31609 | wsexp = /[ ]*(.*)[ ]+\n/g; |
| 31610 | contexp = /(<.+>)(.+\n)/g; |
| 31611 | xml = xml.replace(reg, '$1\n$2$3').replace(wsexp, '$1\n').replace(contexp, '$1\n$2'); |
| 31612 | pad = 0; |
| 31613 | formatted = ''; |
| 31614 | lines = xml.split('\n'); |
| 31615 | indent = 0; |
| 31616 | lastType = 'other'; |
| 31617 | transitions = { |
| 31618 | 'single->single': 0, |
| 31619 | 'single->closing': -1, |
| 31620 | 'single->opening': 0, |
| 31621 | 'single->other': 0, |
| 31622 | 'closing->single': 0, |
| 31623 | 'closing->closing': -1, |
| 31624 | 'closing->opening': 0, |
| 31625 | 'closing->other': 0, |
| 31626 | 'opening->single': 1, |
| 31627 | 'opening->closing': 0, |
| 31628 | 'opening->opening': 1, |
| 31629 | 'opening->other': 1, |
| 31630 | 'other->single': 0, |
| 31631 | 'other->closing': -1, |
| 31632 | 'other->opening': 0, |
| 31633 | 'other->other': 0 |
| 31634 | }; |
| 31635 | fn = function(ln) { |
| 31636 | var fromTo, j, key, padding, type, types, value; |
| 31637 | types = { |
| 31638 | single: Boolean(ln.match(/<.+\/>/)), |
| 31639 | closing: Boolean(ln.match(/<\/.+>/)), |
| 31640 | opening: Boolean(ln.match(/<[^!?].*>/)) |
| 31641 | }; |
| 31642 | type = ((function() { |
| 31643 | var results; |
| 31644 | results = []; |
| 31645 | for (key in types) { |
| 31646 | value = types[key]; |
| 31647 | if (value) { |
| 31648 | results.push(key); |
| 31649 | } |
| 31650 | } |
| 31651 | return results; |
| 31652 | })())[0]; |
| 31653 | type = type === void 0 ? 'other' : type; |
| 31654 | fromTo = lastType + '->' + type; |
| 31655 | lastType = type; |
| 31656 | padding = ''; |
| 31657 | indent += transitions[fromTo]; |
| 31658 | padding = ((function() { |
| 31659 | var m, ref1, results; |
| 31660 | results = []; |
| 31661 | for (j = m = 0, ref1 = indent; 0 <= ref1 ? m < ref1 : m > ref1; j = 0 <= ref1 ? ++m : --m) { |
| 31662 | results.push(' '); |
| 31663 | } |
| 31664 | return results; |
| 31665 | })()).join(''); |
| 31666 | if (fromTo === 'opening->closing') { |
| 31667 | formatted = formatted.substr(0, formatted.length - 1) + ln + '\n'; |
| 31668 | } else { |
| 31669 | formatted += padding + ln + '\n'; |
| 31670 | } |
| 31671 | }; |
| 31672 | for (l = 0, len = lines.length; l < len; l++) { |
| 31673 | ln = lines[l]; |
| 31674 | fn(ln); |
| 31675 | } |
| 31676 | return formatted; |
| 31677 | }, |
| 31678 | |
| 31679 | // puts the response data in UI |
| 31680 | showStatus: function(response) { |
| 31681 | var url, content; |
| 31682 | if (response.content === undefined) { |
| 31683 | content = response.data; |
| 31684 | url = response.url; |
| 31685 | } else { |
| 31686 | content = response.content.data; |
| 31687 | url = response.request.url; |
| 31688 | } |
| 31689 | var headers = response.headers; |
| 31690 | content = jQuery.trim(content); |
| 31691 | |
| 31692 | // if server is nice, and sends content-type back, we can use it |
| 31693 | var contentType = null; |
| 31694 | if (headers) { |
| 31695 | contentType = headers['Content-Type'] || headers['content-type']; |
| 31696 | if (contentType) { |
| 31697 | contentType = contentType.split(';')[0].trim(); |
| 31698 | } |
| 31699 | } |
| 31700 | $('.response_body', $(this.el)).removeClass('json'); |
| 31701 | $('.response_body', $(this.el)).removeClass('xml'); |
| 31702 | |
| 31703 | var supportsAudioPlayback = function(contentType){ |
| 31704 | var audioElement = document.createElement('audio'); |
| 31705 | return !!(audioElement.canPlayType && audioElement.canPlayType(contentType).replace(/no/, '')); |
| 31706 | }; |
| 31707 | |
| 31708 | var pre; |
| 31709 | var code; |
| 31710 | if (!content) { |
| 31711 | code = $('<code />').text('no content'); |
| 31712 | pre = $('<pre class="json" />').append(code); |
| 31713 | |
| 31714 | // JSON |
| 31715 | } else if (contentType === 'application/json' || /\+json$/.test(contentType)) { |
| 31716 | var json = null; |
| 31717 | try { |
| 31718 | json = JSON.stringify(JSON.parse(content), null, ' '); |
| 31719 | } catch (_error) { |
| 31720 | json = 'can\'t parse JSON. Raw result:\n\n' + content; |
| 31721 | } |
| 31722 | code = $('<code />').text(json); |
| 31723 | pre = $('<pre class="json" />').append(code); |
| 31724 | |
| 31725 | // XML |
| 31726 | } else if (contentType === 'application/xml' || /\+xml$/.test(contentType)) { |
| 31727 | code = $('<code />').text(this.formatXml(content)); |
| 31728 | pre = $('<pre class="xml" />').append(code); |
| 31729 | |
| 31730 | // HTML |
| 31731 | } else if (contentType === 'text/html') { |
| 31732 | code = $('<code />').html(_.escape(content)); |
| 31733 | pre = $('<pre class="xml" />').append(code); |
| 31734 | |
| 31735 | // Plain Text |
| 31736 | } else if (/text\/plain/.test(contentType)) { |
| 31737 | code = $('<code />').text(content); |
| 31738 | pre = $('<pre class="plain" />').append(code); |
| 31739 | |
| 31740 | |
| 31741 | // Image |
| 31742 | } else if (/^image\//.test(contentType)) { |
| 31743 | pre = $('<img>').attr('src', url); |
| 31744 | |
| 31745 | // Audio |
| 31746 | } else if (/^audio\//.test(contentType) && supportsAudioPlayback(contentType)) { |
| 31747 | pre = $('<audio controls>').append($('<source>').attr('src', url).attr('type', contentType)); |
| 31748 | |
| 31749 | // Download |
| 31750 | } else if (headers['Content-Disposition'] && (/attachment/).test(headers['Content-Disposition']) || |
| 31751 | headers['content-disposition'] && (/attachment/).test(headers['content-disposition']) || |
| 31752 | headers['Content-Description'] && (/File Transfer/).test(headers['Content-Description']) || |
| 31753 | headers['content-description'] && (/File Transfer/).test(headers['content-description'])) { |
| 31754 | |
| 31755 | if ('Blob' in window) { |
| 31756 | var type = contentType || 'text/html'; |
| 31757 | var blob = new Blob([content], {type: type}); |
| 31758 | var a = document.createElement('a'); |
| 31759 | var href = window.URL.createObjectURL(blob); |
| 31760 | var fileName = response.url.substr(response.url.lastIndexOf('/') + 1); |
| 31761 | var download = [type, fileName, href].join(':'); |
| 31762 | |
| 31763 | a.setAttribute('href', href); |
| 31764 | a.setAttribute('download', download); |
| 31765 | a.innerText = 'Download ' + fileName; |
| 31766 | |
| 31767 | pre = $('<div/>').append(a); |
| 31768 | } else { |
| 31769 | pre = $('<pre class="json" />').append('Download headers detected but your browser does not support downloading binary via XHR (Blob).'); |
| 31770 | } |
| 31771 | |
| 31772 | // Location header based redirect download |
| 31773 | } else if(headers.location || headers.Location) { |
| 31774 | window.location = response.url; |
| 31775 | |
| 31776 | // Anything else (CORS) |
| 31777 | } else { |
| 31778 | code = $('<code />').text(content); |
| 31779 | pre = $('<pre class="json" />').append(code); |
| 31780 | } |
| 31781 | var response_body = pre; |
| 31782 | $('.request_url', $(this.el)).html('<pre></pre>'); |
| 31783 | $('.request_url pre', $(this.el)).text(url); |
| 31784 | $('.response_code', $(this.el)).html('<pre>' + response.status + '</pre>'); |
| 31785 | $('.response_body', $(this.el)).html(response_body); |
| 31786 | $('.response_headers', $(this.el)).html('<pre>' + _.escape(JSON.stringify(response.headers, null, ' ')).replace(/\n/g, '<br>') + '</pre>'); |
| 31787 | $('.response', $(this.el)).slideDown(); |
| 31788 | $('.response_hider', $(this.el)).show(); |
| 31789 | $('.response_throbber', $(this.el)).hide(); |
| 31790 | |
| 31791 | |
| 31792 | //adds curl output |
| 31793 | var curlCommand = this.model.asCurl(this.map); |
| 31794 | curlCommand = curlCommand.replace('!', '!'); |
| 31795 | $( '.curl', $(this.el)).html('<pre>' + curlCommand + '</pre>'); |
| 31796 | |
| 31797 | // only highlight the response if response is less than threshold, default state is highlight response |
| 31798 | var opts = this.options.swaggerOptions; |
| 31799 | |
| 31800 | if (opts.showRequestHeaders) { |
| 31801 | var form = $('.sandbox', $(this.el)), |
| 31802 | map = this.getInputMap(form), |
| 31803 | requestHeaders = this.model.getHeaderParams(map); |
| 31804 | delete requestHeaders['Content-Type']; |
| 31805 | $('.request_headers', $(this.el)).html('<pre>' + _.escape(JSON.stringify(requestHeaders, null, ' ')).replace(/\n/g, '<br>') + '</pre>'); |
| 31806 | } |
| 31807 | |
| 31808 | var response_body_el = $('.response_body', $(this.el))[0]; |
| 31809 | // only highlight the response if response is less than threshold, default state is highlight response |
| 31810 | if (opts.highlightSizeThreshold && typeof response.data !== 'undefined' && response.data.length > opts.highlightSizeThreshold) { |
| 31811 | return response_body_el; |
| 31812 | } else { |
| 31813 | return hljs.highlightBlock(response_body_el); |
| 31814 | } |
| 31815 | }, |
| 31816 | |
| 31817 | toggleOperationContent: function (event) { |
| 31818 | var elem = $('#' + Docs.escapeResourceName(this.parentId + '_' + this.nickname + '_content')); |
| 31819 | if (elem.is(':visible')){ |
| 31820 | event.preventDefault(); |
| 31821 | $.bbq.pushState('#/', 2); |
| 31822 | Docs.collapseOperation(elem); |
| 31823 | } else { |
| 31824 | Docs.expandOperation(elem); |
| 31825 | } |
| 31826 | }, |
| 31827 | |
| 31828 | getTextAreaValue: function(textArea) { |
| 31829 | var param, parsed, result, i; |
| 31830 | if (textArea.value === null || jQuery.trim(textArea.value).length === 0) { |
| 31831 | return null; |
| 31832 | } |
| 31833 | param = this.getParamByName(textArea.name); |
| 31834 | if (param && param.type && param.type.toLowerCase() === 'array') { |
| 31835 | parsed = textArea.value.split('\n'); |
| 31836 | result = []; |
| 31837 | for (i = 0; i < parsed.length; i++) { |
| 31838 | if (parsed[i] !== null && jQuery.trim(parsed[i]).length > 0) { |
| 31839 | result.push(parsed[i]); |
| 31840 | } |
| 31841 | } |
| 31842 | return result.length > 0 ? result : null; |
| 31843 | } else { |
| 31844 | return textArea.value; |
| 31845 | } |
| 31846 | }, |
| 31847 | |
| 31848 | getParamByName: function(name) { |
| 31849 | var i; |
| 31850 | if (this.model.parameters) { |
| 31851 | for(i = 0; i < this.model.parameters.length; i++) { |
| 31852 | if (this.model.parameters[i].name === name) { |
| 31853 | return this.model.parameters[i]; |
| 31854 | } |
| 31855 | } |
| 31856 | } |
| 31857 | return null; |
| 31858 | } |
| 31859 | |
| 31860 | }); |
| 31861 | |
| 31862 | 'use strict'; |
| 31863 | |
| 31864 | SwaggerUi.Views.ParameterContentTypeView = Backbone.View.extend({ |
| 31865 | initialize: function () {}, |
| 31866 | |
| 31867 | render: function(){ |
| 31868 | this.model.parameterContentTypeId = 'pct' + Math.random(); |
| 31869 | $(this.el).html(Handlebars.templates.parameter_content_type(this.model)); |
| 31870 | return this; |
| 31871 | } |
| 31872 | |
| 31873 | }); |
| 31874 | 'use strict'; |
| 31875 | |
| 31876 | SwaggerUi.Views.ParameterView = Backbone.View.extend({ |
| 31877 | initialize: function(){ |
| 31878 | Handlebars.registerHelper('isArray', function(param, opts) { |
| 31879 | if (param.type.toLowerCase() === 'array' || param.allowMultiple) { |
| 31880 | return opts.fn(this); |
| 31881 | } else { |
| 31882 | return opts.inverse(this); |
| 31883 | } |
| 31884 | }); |
| 31885 | }, |
| 31886 | |
| 31887 | render: function() { |
| 31888 | var type = this.model.type || this.model.dataType; |
| 31889 | |
| 31890 | if (typeof type === 'undefined') { |
| 31891 | var schema = this.model.schema; |
| 31892 | if (schema && schema.$ref) { |
| 31893 | var ref = schema.$ref; |
| 31894 | if (ref.indexOf('#/definitions/') === 0) { |
| 31895 | type = ref.substring('#/definitions/'.length); |
| 31896 | } else { |
| 31897 | type = ref; |
| 31898 | } |
| 31899 | } |
| 31900 | } |
| 31901 | |
| 31902 | this.model.type = type; |
| 31903 | this.model.paramType = this.model.in || this.model.paramType; |
| 31904 | this.model.isBody = this.model.paramType === 'body' || this.model.in === 'body'; |
| 31905 | this.model.isFile = type && type.toLowerCase() === 'file'; |
| 31906 | |
| 31907 | // Allow for default === false |
| 31908 | if(typeof this.model.default === 'undefined') { |
| 31909 | this.model.default = this.model.defaultValue; |
| 31910 | } |
| 31911 | |
| 31912 | this.model.hasDefault = (typeof this.model.default !== 'undefined'); |
| 31913 | this.model.valueId = 'm' + this.model.name + Math.random(); |
| 31914 | |
| 31915 | if (this.model.allowableValues) { |
| 31916 | this.model.isList = true; |
| 31917 | } |
| 31918 | |
| 31919 | var template = this.template(); |
| 31920 | $(this.el).html(template(this.model)); |
| 31921 | |
| 31922 | var signatureModel = { |
| 31923 | sampleJSON: this.model.sampleJSON, |
| 31924 | isParam: true, |
| 31925 | signature: this.model.signature |
| 31926 | }; |
| 31927 | |
| 31928 | if (this.model.sampleJSON) { |
| 31929 | var signatureView = new SwaggerUi.Views.SignatureView({model: signatureModel, tagName: 'div'}); |
| 31930 | $('.model-signature', $(this.el)).append(signatureView.render().el); |
| 31931 | } |
| 31932 | else { |
| 31933 | $('.model-signature', $(this.el)).html(this.model.signature); |
| 31934 | } |
| 31935 | |
| 31936 | var isParam = false; |
| 31937 | |
| 31938 | if (this.model.isBody) { |
| 31939 | isParam = true; |
| 31940 | } |
| 31941 | |
| 31942 | var contentTypeModel = { |
| 31943 | isParam: isParam |
| 31944 | }; |
| 31945 | |
| 31946 | contentTypeModel.consumes = this.model.consumes; |
| 31947 | |
| 31948 | if (isParam) { |
| 31949 | var parameterContentTypeView = new SwaggerUi.Views.ParameterContentTypeView({model: contentTypeModel}); |
| 31950 | $('.parameter-content-type', $(this.el)).append(parameterContentTypeView.render().el); |
| 31951 | } |
| 31952 | |
| 31953 | else { |
| 31954 | var responseContentTypeView = new SwaggerUi.Views.ResponseContentTypeView({model: contentTypeModel}); |
| 31955 | $('.response-content-type', $(this.el)).append(responseContentTypeView.render().el); |
| 31956 | } |
| 31957 | |
| 31958 | return this; |
| 31959 | }, |
| 31960 | |
| 31961 | // Return an appropriate template based on if the parameter is a list, readonly, required |
| 31962 | template: function(){ |
| 31963 | if (this.model.isList) { |
| 31964 | return Handlebars.templates.param_list; |
| 31965 | } else { |
| 31966 | if (this.options.readOnly) { |
| 31967 | if (this.model.required) { |
| 31968 | return Handlebars.templates.param_readonly_required; |
| 31969 | } else { |
| 31970 | return Handlebars.templates.param_readonly; |
| 31971 | } |
| 31972 | } else { |
| 31973 | if (this.model.required) { |
| 31974 | return Handlebars.templates.param_required; |
| 31975 | } else { |
| 31976 | return Handlebars.templates.param; |
| 31977 | } |
| 31978 | } |
| 31979 | } |
| 31980 | } |
| 31981 | }); |
| 31982 | |
| 31983 | 'use strict'; |
| 31984 | |
| 31985 | SwaggerUi.Views.ResourceView = Backbone.View.extend({ |
| 31986 | initialize: function(opts) { |
| 31987 | opts = opts || {}; |
| 31988 | this.router = opts.router; |
| 31989 | this.auths = opts.auths; |
| 31990 | if ('' === this.model.description) { |
| 31991 | this.model.description = null; |
| 31992 | } |
| 31993 | if (this.model.description) { |
| 31994 | this.model.summary = this.model.description; |
| 31995 | } |
| 31996 | }, |
| 31997 | |
| 31998 | render: function(){ |
| 31999 | var methods = {}; |
| 32000 | |
| 32001 | |
| 32002 | $(this.el).html(Handlebars.templates.resource(this.model)); |
| 32003 | |
| 32004 | // Render each operation |
| 32005 | for (var i = 0; i < this.model.operationsArray.length; i++) { |
| 32006 | var operation = this.model.operationsArray[i]; |
| 32007 | var counter = 0; |
| 32008 | var id = operation.nickname; |
| 32009 | |
| 32010 | while (typeof methods[id] !== 'undefined') { |
| 32011 | id = id + '_' + counter; |
| 32012 | counter += 1; |
| 32013 | } |
| 32014 | |
| 32015 | methods[id] = operation; |
| 32016 | |
| 32017 | operation.nickname = id; |
| 32018 | operation.parentId = this.model.id; |
| 32019 | this.addOperation(operation); |
| 32020 | } |
| 32021 | |
| 32022 | $('.toggleEndpointList', this.el).click(this.callDocs.bind(this, 'toggleEndpointListForResource')); |
| 32023 | $('.collapseResource', this.el).click(this.callDocs.bind(this, 'collapseOperationsForResource')); |
| 32024 | $('.expandResource', this.el).click(this.callDocs.bind(this, 'expandOperationsForResource')); |
| 32025 | |
| 32026 | return this; |
| 32027 | }, |
| 32028 | |
| 32029 | addOperation: function(operation) { |
| 32030 | |
| 32031 | operation.number = this.number; |
| 32032 | |
| 32033 | // Render an operation and add it to operations li |
| 32034 | var operationView = new SwaggerUi.Views.OperationView({ |
| 32035 | model: operation, |
| 32036 | router: this.router, |
| 32037 | tagName: 'li', |
| 32038 | className: 'endpoint', |
| 32039 | swaggerOptions: this.options.swaggerOptions, |
| 32040 | auths: this.auths |
| 32041 | }); |
| 32042 | |
| 32043 | $('.endpoints', $(this.el)).append(operationView.render().el); |
| 32044 | |
| 32045 | this.number++; |
| 32046 | |
| 32047 | }, |
| 32048 | // Generic Event handler (`Docs` is global) |
| 32049 | |
| 32050 | |
| 32051 | callDocs: function(fnName, e) { |
| 32052 | e.preventDefault(); |
| 32053 | Docs[fnName](e.currentTarget.getAttribute('data-id')); |
| 32054 | } |
| 32055 | }); |
| 32056 | 'use strict'; |
| 32057 | |
| 32058 | SwaggerUi.Views.ResponseContentTypeView = Backbone.View.extend({ |
| 32059 | initialize: function(){}, |
| 32060 | |
| 32061 | render: function(){ |
| 32062 | this.model.responseContentTypeId = 'rct' + Math.random(); |
| 32063 | $(this.el).html(Handlebars.templates.response_content_type(this.model)); |
| 32064 | return this; |
| 32065 | } |
| 32066 | }); |
| 32067 | 'use strict'; |
| 32068 | |
| 32069 | SwaggerUi.Views.SignatureView = Backbone.View.extend({ |
| 32070 | events: { |
| 32071 | 'click a.description-link' : 'switchToDescription', |
| 32072 | 'click a.snippet-link' : 'switchToSnippet', |
| 32073 | 'mousedown .snippet' : 'snippetToTextArea' |
| 32074 | }, |
| 32075 | |
| 32076 | initialize: function () { |
| 32077 | |
| 32078 | }, |
| 32079 | |
| 32080 | render: function(){ |
| 32081 | |
| 32082 | $(this.el).html(Handlebars.templates.signature(this.model)); |
| 32083 | |
| 32084 | this.switchToSnippet(); |
| 32085 | |
| 32086 | this.isParam = this.model.isParam; |
| 32087 | |
| 32088 | if (this.isParam) { |
| 32089 | $('.notice', $(this.el)).text('Click to set as parameter value'); |
| 32090 | } |
| 32091 | |
| 32092 | return this; |
| 32093 | }, |
| 32094 | |
| 32095 | // handler for show signature |
| 32096 | switchToDescription: function(e){ |
| 32097 | if (e) { e.preventDefault(); } |
| 32098 | |
| 32099 | $('.snippet', $(this.el)).hide(); |
| 32100 | $('.description', $(this.el)).show(); |
| 32101 | $('.description-link', $(this.el)).addClass('selected'); |
| 32102 | $('.snippet-link', $(this.el)).removeClass('selected'); |
| 32103 | }, |
| 32104 | |
| 32105 | // handler for show sample |
| 32106 | switchToSnippet: function(e){ |
| 32107 | if (e) { e.preventDefault(); } |
| 32108 | |
| 32109 | $('.description', $(this.el)).hide(); |
| 32110 | $('.snippet', $(this.el)).show(); |
| 32111 | $('.snippet-link', $(this.el)).addClass('selected'); |
| 32112 | $('.description-link', $(this.el)).removeClass('selected'); |
| 32113 | }, |
| 32114 | |
| 32115 | // handler for snippet to text area |
| 32116 | snippetToTextArea: function(e) { |
| 32117 | if (this.isParam) { |
| 32118 | if (e) { e.preventDefault(); } |
| 32119 | |
| 32120 | var textArea = $('textarea', $(this.el.parentNode.parentNode.parentNode)); |
| 32121 | if ($.trim(textArea.val()) === '') { |
| 32122 | textArea.val(this.model.sampleJSON); |
| 32123 | } |
| 32124 | } |
| 32125 | } |
| 32126 | }); |
| 32127 | 'use strict'; |
| 32128 | |
| 32129 | SwaggerUi.Views.StatusCodeView = Backbone.View.extend({ |
| 32130 | initialize: function (opts) { |
| 32131 | this.options = opts || {}; |
| 32132 | this.router = this.options.router; |
| 32133 | }, |
| 32134 | |
| 32135 | render: function(){ |
| 32136 | $(this.el).html(Handlebars.templates.status_code(this.model)); |
| 32137 | |
| 32138 | if (this.router.api.models.hasOwnProperty(this.model.responseModel)) { |
| 32139 | var responseModel = { |
| 32140 | sampleJSON: JSON.stringify(this.router.api.models[this.model.responseModel].createJSONSample(), null, 2), |
| 32141 | isParam: false, |
| 32142 | signature: this.router.api.models[this.model.responseModel].getMockSignature(), |
| 32143 | }; |
| 32144 | |
| 32145 | var responseModelView = new SwaggerUi.Views.SignatureView({model: responseModel, tagName: 'div'}); |
| 32146 | $('.model-signature', this.$el).append(responseModelView.render().el); |
| 32147 | } else { |
| 32148 | $('.model-signature', this.$el).html(''); |
| 32149 | } |
| 32150 | return this; |
| 32151 | } |
| 32152 | });}).call(this); |