Restore "Add VlantagApi Functional Component""
[ccsdk/apps.git] / ms / vlantag-api / src / main / resources / META-INF / resources / swagger-ui / dist / swagger-ui.js
1 /**\r
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\r
3  * @version v2.1.4\r
4  * @link http://swagger.io\r
5  * @license Apache-2.0\r
6  */\r
7 (function(){this["Handlebars"] = this["Handlebars"] || {};\r
8 this["Handlebars"]["templates"] = this["Handlebars"]["templates"] || {};\r
9 this["Handlebars"]["templates"]["apikey_auth"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {\r
10   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;\r
11   return "                <span class=\"key_auth__value\">"\r
12     + 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)))\r
13     + "</span>\n";\r
14 },"3":function(depth0,helpers,partials,data) {\r
15   return "                <input placeholder=\"api_key\" class=\"auth_input input_apiKey_entry\" name=\"apiKey\" type=\"text\"/>\n";\r
16   },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {\r
17   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<div class=\"key_input_container\">\n    <h3 class=\"auth__title\">Api key authorization</h3>\n    <div class=\"auth__description\">"\r
18     + escapeExpression(((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper)))\r
19     + "</div>\n    <div>\n        <div class=\"key_auth__field\">\n            <span class=\"key_auth__label\">name:</span>\n            <span class=\"key_auth__value\">"\r
20     + 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)))\r
21     + "</span>\n        </div>\n        <div class=\"key_auth__field\">\n            <span class=\"key_auth__label\">in:</span>\n            <span class=\"key_auth__value\">"\r
22     + escapeExpression(((helper = (helper = helpers['in'] || (depth0 != null ? depth0['in'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"in","hash":{},"data":data}) : helper)))\r
23     + "</span>\n        </div>\n        <div class=\"key_auth__field\">\n            <span class=\"key_auth__label\">value:</span>\n";\r
24   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isLogout : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(3, data),"data":data});\r
25   if (stack1 != null) { buffer += stack1; }\r
26   return buffer + "        </div>\n    </div>\n</div>\n";\r
27 },"useData":true});\r
28 this["Handlebars"]["templates"]["auth_button_operation"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {\r
29   return "        authorize__btn_operation_login\n";\r
30   },"3":function(depth0,helpers,partials,data) {\r
31   return "        authorize__btn_operation_logout\n";\r
32   },"5":function(depth0,helpers,partials,data) {\r
33   var stack1, buffer = "        <ul class=\"authorize-scopes\">\n";\r
34   stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.scopes : depth0), {"name":"each","hash":{},"fn":this.program(6, data),"inverse":this.noop,"data":data});\r
35   if (stack1 != null) { buffer += stack1; }\r
36   return buffer + "        </ul>\n";\r
37 },"6":function(depth0,helpers,partials,data) {\r
38   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;\r
39   return "                <li class=\"authorize__scope\" title=\""\r
40     + escapeExpression(((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper)))\r
41     + "\">"\r
42     + escapeExpression(((helper = (helper = helpers.scope || (depth0 != null ? depth0.scope : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"scope","hash":{},"data":data}) : helper)))\r
43     + "</li>\n";\r
44 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {\r
45   var stack1, buffer = "<div class=\"authorize__btn authorize__btn_operation\n";\r
46   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isLogout : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(3, data),"data":data});\r
47   if (stack1 != null) { buffer += stack1; }\r
48   buffer += "\">\n";\r
49   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.scopes : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.noop,"data":data});\r
50   if (stack1 != null) { buffer += stack1; }\r
51   return buffer + "</div>\n";\r
52 },"useData":true});\r
53 this["Handlebars"]["templates"]["auth_button"] = Handlebars.template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {\r
54   return "<a class='authorize__btn' href=\"#\">Authorize</a>\n";\r
55   },"useData":true});\r
56 this["Handlebars"]["templates"]["auth_view"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {\r
57   return "            <button type=\"button\" class=\"auth__button auth_submit__button\" data-sw-translate>Authorize</button>\n";\r
58   },"3":function(depth0,helpers,partials,data) {\r
59   return "            <button type=\"button\" class=\"auth__button auth_logout__button\" data-sw-translate>Logout</button>\n";\r
60   },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {\r
61   var stack1, buffer = "<div class=\"auth_container\">\n\n    <div class=\"auth_inner\"></div>\n    <div class=\"auth_submit\">\n";\r
62   stack1 = helpers.unless.call(depth0, (depth0 != null ? depth0.isLogout : depth0), {"name":"unless","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});\r
63   if (stack1 != null) { buffer += stack1; }\r
64   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isAuthorized : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data});\r
65   if (stack1 != null) { buffer += stack1; }\r
66   return buffer + "    </div>\n\n</div>\n";\r
67 },"useData":true});\r
68 this["Handlebars"]["templates"]["basic_auth"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {\r
69   return " - authorized";\r
70   },"3":function(depth0,helpers,partials,data) {\r
71   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;\r
72   return "                <span class=\"basic_auth__value\">"\r
73     + escapeExpression(((helper = (helper = helpers.username || (depth0 != null ? depth0.username : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"username","hash":{},"data":data}) : helper)))\r
74     + "</span>\n";\r
75 },"5":function(depth0,helpers,partials,data) {\r
76   return "                <input required placeholder=\"username\" class=\"basic_auth__username auth_input\" name=\"username\" type=\"text\"/>\n";\r
77   },"7":function(depth0,helpers,partials,data) {\r
78   return "            <div class=\"auth_label\">\n                <span class=\"basic_auth__label\" data-sw-translate>password:</span>\n                <input required placeholder=\"password\" class=\"basic_auth__password auth_input\" name=\"password\" type=\"password\"/></label>\n            </div>\n";\r
79   },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {\r
80   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<div class='basic_auth_container'>\n    <h3 class=\"auth__title\">Basic authentication";\r
81   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isLogout : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});\r
82   if (stack1 != null) { buffer += stack1; }\r
83   buffer += "</h3>\n    <form class=\"basic_input_container\">\n        <div class=\"auth__description\">"\r
84     + escapeExpression(((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper)))\r
85     + "</div>\n        <div class=\"auth_label\">\n            <span class=\"basic_auth__label\" data-sw-translate>username:</span>\n";\r
86   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isLogout : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.program(5, data),"data":data});\r
87   if (stack1 != null) { buffer += stack1; }\r
88   buffer += "        </div>\n";\r
89   stack1 = helpers.unless.call(depth0, (depth0 != null ? depth0.isLogout : depth0), {"name":"unless","hash":{},"fn":this.program(7, data),"inverse":this.noop,"data":data});\r
90   if (stack1 != null) { buffer += stack1; }\r
91   return buffer + "    </form>\n</div>\n";\r
92 },"useData":true});\r
93 this["Handlebars"]["templates"]["content_type"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {\r
94   var stack1, buffer = "";\r
95   stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.produces : depth0), {"name":"each","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data});\r
96   if (stack1 != null) { buffer += stack1; }\r
97   return buffer;\r
98 },"2":function(depth0,helpers,partials,data) {\r
99   var lambda=this.lambda, escapeExpression=this.escapeExpression;\r
100   return "      <option value=\""\r
101     + escapeExpression(lambda(depth0, depth0))\r
102     + "\">"\r
103     + escapeExpression(lambda(depth0, depth0))\r
104     + "</option>\n";\r
105 },"4":function(depth0,helpers,partials,data) {\r
106   return "  <option value=\"application/json\">application/json</option>\n";\r
107   },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {\r
108   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<label data-sw-translate for=\""\r
109     + 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)))\r
110     + "\">Response Content Type</label>\n<select name=\"contentType\" id=\""\r
111     + 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)))\r
112     + "\">\n";\r
113   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});\r
114   if (stack1 != null) { buffer += stack1; }\r
115   return buffer + "</select>\n";\r
116 },"useData":true});\r
117 'use strict';\r
118 \r
119 \r
120 $(function() {\r
121 \r
122         // Helper function for vertically aligning DOM elements\r
123         // http://www.seodenver.com/simple-vertical-align-plugin-for-jquery/\r
124         $.fn.vAlign = function() {\r
125                 return this.each(function(){\r
126                         var ah = $(this).height();\r
127                         var ph = $(this).parent().height();\r
128                         var mh = (ph - ah) / 2;\r
129                         $(this).css('margin-top', mh);\r
130                 });\r
131         };\r
132 \r
133         $.fn.stretchFormtasticInputWidthToParent = function() {\r
134                 return this.each(function(){\r
135                         var p_width = $(this).closest("form").innerWidth();\r
136                         var p_padding = parseInt($(this).closest("form").css('padding-left') ,10) + parseInt($(this).closest('form').css('padding-right'), 10);\r
137                         var this_padding = parseInt($(this).css('padding-left'), 10) + parseInt($(this).css('padding-right'), 10);\r
138                         $(this).css('width', p_width - p_padding - this_padding);\r
139                 });\r
140         };\r
141 \r
142         $('form.formtastic li.string input, form.formtastic textarea').stretchFormtasticInputWidthToParent();\r
143 \r
144         // Vertically center these paragraphs\r
145         // Parent may need a min-height for this to work..\r
146         $('ul.downplayed li div.content p').vAlign();\r
147 \r
148         // When a sandbox form is submitted..\r
149         $("form.sandbox").submit(function(){\r
150 \r
151                 var error_free = true;\r
152 \r
153                 // Cycle through the forms required inputs\r
154                 $(this).find("input.required").each(function() {\r
155 \r
156                         // Remove any existing error styles from the input\r
157                         $(this).removeClass('error');\r
158 \r
159                         // Tack the error style on if the input is empty..\r
160                         if ($(this).val() === '') {\r
161                                 $(this).addClass('error');\r
162                                 $(this).wiggle();\r
163                                 error_free = false;\r
164                         }\r
165 \r
166                 });\r
167 \r
168                 return error_free;\r
169         });\r
170 \r
171 });\r
172 \r
173 function clippyCopiedCallback() {\r
174   $('#api_key_copied').fadeIn().delay(1000).fadeOut();\r
175 \r
176   // var b = $("#clippy_tooltip_" + a);\r
177   // b.length != 0 && (b.attr("title", "copied!").trigger("tipsy.reload"), setTimeout(function() {\r
178   //   b.attr("title", "copy to clipboard")\r
179   // },\r
180   // 500))\r
181 }\r
182 \r
183 // Logging function that accounts for browsers that don't have window.console\r
184 function log(){\r
185   log.history = log.history || [];\r
186   log.history.push(arguments);\r
187   if(this.console){\r
188     console.log( Array.prototype.slice.call(arguments)[0] );\r
189   }\r
190 }\r
191 \r
192 // Handle browsers that do console incorrectly (IE9 and below, see http://stackoverflow.com/a/5539378/7913)\r
193 if (Function.prototype.bind && console && typeof console.log === "object") {\r
194     [\r
195       "log","info","warn","error","assert","dir","clear","profile","profileEnd"\r
196     ].forEach(function (method) {\r
197         console[method] = this.bind(console[method], console);\r
198     }, Function.prototype.call);\r
199 }\r
200 \r
201 window.Docs = {\r
202 \r
203         shebang: function() {\r
204 \r
205                 // If shebang has an operation nickname in it..\r
206                 // e.g. /docs/#!/words/get_search\r
207                 var fragments = $.param.fragment().split('/');\r
208                 fragments.shift(); // get rid of the bang\r
209 \r
210                 switch (fragments.length) {\r
211                         case 1:\r
212         if (fragments[0].length > 0) { // prevent matching "#/"\r
213           // Expand all operations for the resource and scroll to it\r
214           var dom_id = 'resource_' + fragments[0];\r
215 \r
216           Docs.expandEndpointListForResource(fragments[0]);\r
217           $("#"+dom_id).slideto({highlight: false});\r
218         }\r
219                                 break;\r
220                         case 2:\r
221                                 // Refer to the endpoint DOM element, e.g. #words_get_search\r
222 \r
223         // Expand Resource\r
224         Docs.expandEndpointListForResource(fragments[0]);\r
225         $("#"+dom_id).slideto({highlight: false});\r
226 \r
227             // Expand operation\r
228             var li_dom_id = fragments.join('_');\r
229             var li_content_dom_id = li_dom_id + "_content";\r
230 \r
231 \r
232             Docs.expandOperation($('#'+li_content_dom_id));\r
233             $('#'+li_dom_id).slideto({highlight: false});\r
234             break;\r
235                 }\r
236         },\r
237 \r
238         toggleEndpointListForResource: function(resource) {\r
239                 var elem = $('li#resource_' + Docs.escapeResourceName(resource) + ' ul.endpoints');\r
240                 if (elem.is(':visible')) {\r
241                         $.bbq.pushState('#/', 2);\r
242                         Docs.collapseEndpointListForResource(resource);\r
243                 } else {\r
244             $.bbq.pushState('#/' + resource, 2);\r
245                         Docs.expandEndpointListForResource(resource);\r
246                 }\r
247         },\r
248 \r
249         // Expand resource\r
250         expandEndpointListForResource: function(resource) {\r
251                 var resource = Docs.escapeResourceName(resource);\r
252                 if (resource == '') {\r
253                         $('.resource ul.endpoints').slideDown();\r
254                         return;\r
255                 }\r
256 \r
257                 $('li#resource_' + resource).addClass('active');\r
258 \r
259                 var elem = $('li#resource_' + resource + ' ul.endpoints');\r
260                 elem.slideDown();\r
261         },\r
262 \r
263         // Collapse resource and mark as explicitly closed\r
264         collapseEndpointListForResource: function(resource) {\r
265                 var resource = Docs.escapeResourceName(resource);\r
266                 if (resource == '') {\r
267                         $('.resource ul.endpoints').slideUp();\r
268                         return;\r
269                 }\r
270 \r
271                 $('li#resource_' + resource).removeClass('active');\r
272 \r
273                 var elem = $('li#resource_' + resource + ' ul.endpoints');\r
274                 elem.slideUp();\r
275         },\r
276 \r
277         expandOperationsForResource: function(resource) {\r
278                 // Make sure the resource container is open..\r
279                 Docs.expandEndpointListForResource(resource);\r
280 \r
281                 if (resource == '') {\r
282                         $('.resource ul.endpoints li.operation div.content').slideDown();\r
283                         return;\r
284                 }\r
285 \r
286                 $('li#resource_' + Docs.escapeResourceName(resource) + ' li.operation div.content').each(function() {\r
287                         Docs.expandOperation($(this));\r
288                 });\r
289         },\r
290 \r
291         collapseOperationsForResource: function(resource) {\r
292                 // Make sure the resource container is open..\r
293                 Docs.expandEndpointListForResource(resource);\r
294 \r
295                 if (resource == '') {\r
296                         $('.resource ul.endpoints li.operation div.content').slideUp();\r
297                         return;\r
298                 }\r
299 \r
300                 $('li#resource_' + Docs.escapeResourceName(resource) + ' li.operation div.content').each(function() {\r
301                         Docs.collapseOperation($(this));\r
302                 });\r
303         },\r
304 \r
305         escapeResourceName: function(resource) {\r
306                 return resource.replace(/[!"#$%&'()*+,.\/:;<=>?@\[\\\]\^`{|}~]/g, "\\$&");\r
307         },\r
308 \r
309         expandOperation: function(elem) {\r
310                 elem.slideDown();\r
311         },\r
312 \r
313         collapseOperation: function(elem) {\r
314                 elem.slideUp();\r
315         }\r
316 };\r
317 \r
318 'use strict';\r
319 /*jslint eqeq: true*/\r
320 \r
321 Handlebars.registerHelper('sanitize', function(html) {\r
322     // Strip the script tags from the html, and return it as a Handlebars.SafeString\r
323     html = html.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');\r
324     return new Handlebars.SafeString(html);\r
325 });\r
326 \r
327 Handlebars.registerHelper('renderTextParam', function(param) {\r
328     var result, type = 'text', idAtt = '';\r
329     var paramType = param.type || param.schema.type || '';\r
330     var isArray = paramType.toLowerCase() === 'array' || param.allowMultiple;\r
331     var defaultValue = isArray && Array.isArray(param.default) ? param.default.join('\n') : param.default;\r
332 \r
333     var dataVendorExtensions = Object.keys(param).filter(function(property) {\r
334         // filter X-data- properties\r
335         return property.match(/^X-data-/i) !== null;\r
336     }).reduce(function(result, property) {\r
337         // remove X- from property name, so it results in html attributes like data-foo='bar'\r
338         return result += ' ' + property.substring(2, property.length) + '=\'' + param[property] + '\'';\r
339     }, '');\r
340 \r
341     if (typeof defaultValue === 'undefined') {\r
342         defaultValue = '';\r
343     }\r
344 \r
345     if(param.format && param.format === 'password') {\r
346         type = 'password';\r
347     }\r
348 \r
349     if(param.valueId) {\r
350         idAtt = ' id=\'' + param.valueId + '\'';\r
351     }\r
352 \r
353     if (typeof defaultValue === 'string' || defaultValue instanceof String) {\r
354         defaultValue = defaultValue.replace(/'/g,'&apos;');\r
355     }\r
356 \r
357     if(isArray) {\r
358         result = '<textarea class=\'body-textarea' + (param.required ? ' required' : '') + '\' name=\'' + param.name + '\'' + idAtt + dataVendorExtensions;\r
359         result += ' placeholder=\'Provide multiple values in new lines' + (param.required ? ' (at least one required).' : '.') + '\'>';\r
360         result += defaultValue + '</textarea>';\r
361     } else {\r
362         var parameterClass = 'parameter';\r
363         if(param.required) {\r
364           parameterClass += ' required';\r
365         }\r
366         result = '<input class=\'' + parameterClass + '\' minlength=\'' + (param.required ? 1 : 0) + '\'';\r
367         result += ' name=\'' + param.name +'\' placeholder=\'' + (param.required ? '(required)' : '') + '\'' + idAtt + dataVendorExtensions;\r
368         result += ' type=\'' + type + '\' value=\'' + defaultValue + '\'/>';\r
369     }\r
370     return new Handlebars.SafeString(result);\r
371 });\r
372 \r
373 Handlebars.registerHelper('ifCond', function (v1, operator, v2, options) {\r
374 \r
375     switch (operator) {\r
376         case '==':\r
377             return (v1 == v2) ? options.fn(this) : options.inverse(this);\r
378         case '===':\r
379             return (v1 === v2) ? options.fn(this) : options.inverse(this);\r
380         case '<':\r
381             return (v1 < v2) ? options.fn(this) : options.inverse(this);\r
382         case '<=':\r
383             return (v1 <= v2) ? options.fn(this) : options.inverse(this);\r
384         case '>':\r
385             return (v1 > v2) ? options.fn(this) : options.inverse(this);\r
386         case '>=':\r
387             return (v1 >= v2) ? options.fn(this) : options.inverse(this);\r
388         case '&&':\r
389             return (v1 && v2) ? options.fn(this) : options.inverse(this);\r
390         case '||':\r
391             return (v1 || v2) ? options.fn(this) : options.inverse(this);\r
392         default:\r
393             return options.inverse(this);\r
394     }\r
395 });\r
396 this["Handlebars"]["templates"]["main"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {\r
397   var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression, buffer = "  <div class=\"info_title\">"\r
398     + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.title : stack1), depth0))\r
399     + "</div>\n  <div class=\"info_description markdown\">";\r
400   stack1 = lambda(((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.description : stack1), depth0);\r
401   if (stack1 != null) { buffer += stack1; }\r
402   buffer += "</div>\n";\r
403   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.externalDocs : depth0), {"name":"if","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data});\r
404   if (stack1 != null) { buffer += stack1; }\r
405   buffer += "  ";\r
406   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});\r
407   if (stack1 != null) { buffer += stack1; }\r
408   buffer += "\n  ";\r
409   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});\r
410   if (stack1 != null) { buffer += stack1; }\r
411   buffer += "\n  ";\r
412   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});\r
413   if (stack1 != null) { buffer += stack1; }\r
414   buffer += "\n  ";\r
415   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});\r
416   if (stack1 != null) { buffer += stack1; }\r
417   buffer += "\n  ";\r
418   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});\r
419   if (stack1 != null) { buffer += stack1; }\r
420   return buffer + "\n";\r
421 },"2":function(depth0,helpers,partials,data) {\r
422   var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression;\r
423   return "  <p>"\r
424     + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0.externalDocs : depth0)) != null ? stack1.description : stack1), depth0))\r
425     + "</p>\n  <a href=\""\r
426     + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0.externalDocs : depth0)) != null ? stack1.url : stack1), depth0))\r
427     + "\" target=\"_blank\">"\r
428     + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0.externalDocs : depth0)) != null ? stack1.url : stack1), depth0))\r
429     + "</a>\n";\r
430 },"4":function(depth0,helpers,partials,data) {\r
431   var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression;\r
432   return "<div class=\"info_tos\"><a target=\"_blank\" href=\""\r
433     + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.termsOfServiceUrl : stack1), depth0))\r
434     + "\" data-sw-translate>Terms of service</a></div>";\r
435 },"6":function(depth0,helpers,partials,data) {\r
436   var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression;\r
437   return "<div class='info_name' data-sw-translate>Created by "\r
438     + escapeExpression(lambda(((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.name : stack1), depth0))\r
439     + "</div>";\r
440 },"8":function(depth0,helpers,partials,data) {\r
441   var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression;\r
442   return "<div class='info_url' data-sw-translate>See more at <a href=\""\r
443     + escapeExpression(lambda(((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.url : stack1), depth0))\r
444     + "\">"\r
445     + escapeExpression(lambda(((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.url : stack1), depth0))\r
446     + "</a></div>";\r
447 },"10":function(depth0,helpers,partials,data) {\r
448   var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression;\r
449   return "<div class='info_email'><a target=\"_parent\" href=\"mailto:"\r
450     + escapeExpression(lambda(((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.email : stack1), depth0))\r
451     + "?subject="\r
452     + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.title : stack1), depth0))\r
453     + "\" data-sw-translate>Contact the developer</a></div>";\r
454 },"12":function(depth0,helpers,partials,data) {\r
455   var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression;\r
456   return "<div class='info_license'><a target=\"_blank\" href='"\r
457     + escapeExpression(lambda(((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.license : stack1)) != null ? stack1.url : stack1), depth0))\r
458     + "'>"\r
459     + escapeExpression(lambda(((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.license : stack1)) != null ? stack1.name : stack1), depth0))\r
460     + "</a></div>";\r
461 },"14":function(depth0,helpers,partials,data) {\r
462   var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression;\r
463   return "  , <span style=\"font-variant: small-caps\" data-sw-translate>api version</span>: "\r
464     + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.version : stack1), depth0))\r
465     + "\n    ";\r
466 },"16":function(depth0,helpers,partials,data) {\r
467   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;\r
468   return "    <span style=\"float:right\"><a target=\"_blank\" href=\""\r
469     + 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)))\r
470     + "/debug?url="\r
471     + 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)))\r
472     + "\"><img id=\"validator\" src=\""\r
473     + 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)))\r
474     + "?url="\r
475     + 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)))\r
476     + "\"></a>\n    </span>\n";\r
477 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {\r
478   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<div class='info' id='api_info'>\n";\r
479   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.info : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});\r
480   if (stack1 != null) { buffer += stack1; }\r
481   buffer += "</div>\n<div class='container' id='resources_container'>\n  <div class='authorize-wrapper'></div>\n\n  <ul id='resources'></ul>\n\n  <div class=\"footer\">\n    <h4 style=\"color: #999\">[ <span style=\"font-variant: small-caps\">base url</span>: "\r
482     + 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)))\r
483     + "\n";\r
484   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});\r
485   if (stack1 != null) { buffer += stack1; }\r
486   buffer += "]\n";\r
487   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.validatorUrl : depth0), {"name":"if","hash":{},"fn":this.program(16, data),"inverse":this.noop,"data":data});\r
488   if (stack1 != null) { buffer += stack1; }\r
489   return buffer + "    </h4>\n    </div>\n</div>\n";\r
490 },"useData":true});\r
491 this["Handlebars"]["templates"]["oauth2"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {\r
492   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "            <li>\n                <input class=\"oauth-scope\" type=\"checkbox\" data-scope=\""\r
493     + escapeExpression(((helper = (helper = helpers.scope || (depth0 != null ? depth0.scope : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"scope","hash":{},"data":data}) : helper)))\r
494     + "\" oauthtype=\""\r
495     + escapeExpression(((helper = (helper = helpers.OAuthSchemeKey || (depth0 != null ? depth0.OAuthSchemeKey : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"OAuthSchemeKey","hash":{},"data":data}) : helper)))\r
496     + "\"/>\n                <label>"\r
497     + escapeExpression(((helper = (helper = helpers.scope || (depth0 != null ? depth0.scope : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"scope","hash":{},"data":data}) : helper)))\r
498     + "</label><br/>\n                <span class=\"api-scope-desc\">"\r
499     + escapeExpression(((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper)))\r
500     + "\n";\r
501   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.OAuthSchemeKey : depth0), {"name":"if","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data});\r
502   if (stack1 != null) { buffer += stack1; }\r
503   return buffer + "                </span>\n            </li>\n";\r
504 },"2":function(depth0,helpers,partials,data) {\r
505   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;\r
506   return "                        ("\r
507     + escapeExpression(((helper = (helper = helpers.OAuthSchemeKey || (depth0 != null ? depth0.OAuthSchemeKey : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"OAuthSchemeKey","hash":{},"data":data}) : helper)))\r
508     + ")\n";\r
509 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {\r
510   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<div>\n    <h3 class=\"auth__title\">Select OAuth2.0 Scopes</h3>\n    <p>"\r
511     + escapeExpression(((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper)))\r
512     + "</p>\n    <p>Scopes are used to grant an application different levels of access to data on behalf of the end user. Each API may declare one or more scopes.\n        <a href=\"#\">Learn how to use</a>\n    </p>\n    <p><strong> "\r
513     + escapeExpression(((helper = (helper = helpers.appName || (depth0 != null ? depth0.appName : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"appName","hash":{},"data":data}) : helper)))\r
514     + " </strong> API requires the following scopes. Select which ones you want to grant to Swagger UI.</p>\n    <p>Authorization URL: "\r
515     + escapeExpression(((helper = (helper = helpers.authorizationUrl || (depth0 != null ? depth0.authorizationUrl : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"authorizationUrl","hash":{},"data":data}) : helper)))\r
516     + "</p>\n    <p>flow: "\r
517     + escapeExpression(((helper = (helper = helpers.flow || (depth0 != null ? depth0.flow : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"flow","hash":{},"data":data}) : helper)))\r
518     + "</p>\n    <ul class=\"api-popup-scopes\">\n";\r
519   stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.scopes : depth0), {"name":"each","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});\r
520   if (stack1 != null) { buffer += stack1; }\r
521   return buffer + "    </ul>\n</div>";\r
522 },"useData":true});\r
523 this["Handlebars"]["templates"]["operation"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {\r
524   return "deprecated";\r
525   },"3":function(depth0,helpers,partials,data) {\r
526   return "            <h4><span data-sw-translate>Warning: Deprecated</span></h4>\n";\r
527   },"5":function(depth0,helpers,partials,data) {\r
528   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, buffer = "        <h4><span data-sw-translate>Implementation Notes</span></h4>\n        <div class=\"markdown\">";\r
529   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));\r
530   if (stack1 != null) { buffer += stack1; }\r
531   return buffer + "</div>\n";\r
532 },"7":function(depth0,helpers,partials,data) {\r
533   return "            <div class='authorize-wrapper authorize-wrapper_operation'></div>\n";\r
534   },"9":function(depth0,helpers,partials,data) {\r
535   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "          <div class=\"response-class\">\n            <h4><span data-sw-translate>Response Class</span> (<span data-sw-translate>Status</span> "\r
536     + 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)))\r
537     + ")</h4>\n              ";\r
538   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.successDescription : depth0), {"name":"if","hash":{},"fn":this.program(10, data),"inverse":this.noop,"data":data});\r
539   if (stack1 != null) { buffer += stack1; }\r
540   return buffer + "\n            <p><span class=\"model-signature\" /></p>\n            <br/>\n            <div class=\"response-content-type\" />\n            </div>\n";\r
541 },"10":function(depth0,helpers,partials,data) {\r
542   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, buffer = "<div class=\"markdown\">";\r
543   stack1 = ((helper = (helper = helpers.successDescription || (depth0 != null ? depth0.successDescription : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"successDescription","hash":{},"data":data}) : helper));\r
544   if (stack1 != null) { buffer += stack1; }\r
545   return buffer + "</div>";\r
546 },"12":function(depth0,helpers,partials,data) {\r
547   var stack1, buffer = "          <h4 data-sw-translate>Headers</h4>\n          <table class=\"headers\">\n            <thead>\n              <tr>\n                <th style=\"width: 100px; max-width: 100px\" data-sw-translate>Header</th>\n                <th style=\"width: 310px; max-width: 310px\" data-sw-translate>Description</th>\n                <th style=\"width: 200px; max-width: 200px\" data-sw-translate>Type</th>\n                <th style=\"width: 320px; max-width: 320px\" data-sw-translate>Other</th>\n              </tr>\n            </thead>\n            <tbody>\n";\r
548   stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.headers : depth0), {"name":"each","hash":{},"fn":this.program(13, data),"inverse":this.noop,"data":data});\r
549   if (stack1 != null) { buffer += stack1; }\r
550   return buffer + "            </tbody>\n          </table>\n";\r
551 },"13":function(depth0,helpers,partials,data) {\r
552   var lambda=this.lambda, escapeExpression=this.escapeExpression;\r
553   return "              <tr>\n                <td>"\r
554     + escapeExpression(lambda((data && data.key), depth0))\r
555     + "</td>\n                <td>"\r
556     + escapeExpression(lambda((depth0 != null ? depth0.description : depth0), depth0))\r
557     + "</td>\n                <td>"\r
558     + escapeExpression(lambda((depth0 != null ? depth0.type : depth0), depth0))\r
559     + "</td>\n                <td>"\r
560     + escapeExpression(lambda((depth0 != null ? depth0.other : depth0), depth0))\r
561     + "</td>\n              </tr>\n";\r
562 },"15":function(depth0,helpers,partials,data) {\r
563   return "          <h4 data-sw-translate>Parameters</h4>\n          <table class='fullwidth'>\n          <thead>\n            <tr>\n            <th style=\"width: 100px; max-width: 100px\" data-sw-translate>Parameter</th>\n            <th style=\"width: 310px; max-width: 310px\" data-sw-translate>Value</th>\n            <th style=\"width: 200px; max-width: 200px\" data-sw-translate>Description</th>\n            <th style=\"width: 100px; max-width: 100px\" data-sw-translate>Parameter Type</th>\n            <th style=\"width: 220px; max-width: 230px\" data-sw-translate>Data Type</th>\n            </tr>\n          </thead>\n          <tbody class=\"operation-params\">\n\n          </tbody>\n          </table>\n";\r
564   },"17":function(depth0,helpers,partials,data) {\r
565   return "          <div style='margin:0;padding:0;display:inline'></div>\n          <h4 data-sw-translate>Response Messages</h4>\n          <table class='fullwidth'>\n            <thead>\n            <tr>\n              <th data-sw-translate>HTTP Status Code</th>\n              <th data-sw-translate>Reason</th>\n              <th data-sw-translate>Response Model</th>\n              <th data-sw-translate>Headers</th>\n            </tr>\n            </thead>\n            <tbody class=\"operation-status\">\n            </tbody>\n          </table>\n";\r
566   },"19":function(depth0,helpers,partials,data) {\r
567   return "";\r
568 },"21":function(depth0,helpers,partials,data) {\r
569   return "          <div class='sandbox_header'>\n            <input class='submit' type='submit' value='Try it out!' data-sw-translate/>\n            <a href='#' class='response_hider' style='display:none' data-sw-translate>Hide Response</a>\n            <span class='response_throbber' style='display:none'></span>\n          </div>\n";\r
570   },"23":function(depth0,helpers,partials,data) {\r
571   return "          <h4 data-sw-translate>Request Headers</h4>\n          <div class='block request_headers'></div>\n";\r
572   },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {\r
573   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "  <ul class='operations' >\n    <li class='"\r
574     + 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)))\r
575     + " operation' id='"\r
576     + 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)))\r
577     + "_"\r
578     + 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)))\r
579     + "'>\n      <div class='heading'>\n        <h3>\n          <span class='http_method'>\n          <a href='#!/"\r
580     + 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)))\r
581     + "/"\r
582     + 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)))\r
583     + "' class=\"toggleOperation\">"\r
584     + 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)))\r
585     + "</a>\n          </span>\n          <span class='path'>\n          <a href='#!/"\r
586     + 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)))\r
587     + "/"\r
588     + 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)))\r
589     + "' class=\"toggleOperation ";\r
590   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.deprecated : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});\r
591   if (stack1 != null) { buffer += stack1; }\r
592   buffer += "\">"\r
593     + 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)))\r
594     + "</a>\n          </span>\n        </h3>\n        <ul class='options'>\n          <li>\n          <a href='#!/"\r
595     + 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)))\r
596     + "/"\r
597     + 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)))\r
598     + "' class=\"toggleOperation\">";\r
599   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));\r
600   if (stack1 != null) { buffer += stack1; }\r
601   buffer += "</a>\n          </li>\n        </ul>\n      </div>\n      <div class='content' id='"\r
602     + 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)))\r
603     + "_"\r
604     + 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)))\r
605     + "_content' style='display:none'>\n";\r
606   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.deprecated : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data});\r
607   if (stack1 != null) { buffer += stack1; }\r
608   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.description : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.noop,"data":data});\r
609   if (stack1 != null) { buffer += stack1; }\r
610   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.security : depth0), {"name":"if","hash":{},"fn":this.program(7, data),"inverse":this.noop,"data":data});\r
611   if (stack1 != null) { buffer += stack1; }\r
612   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.type : depth0), {"name":"if","hash":{},"fn":this.program(9, data),"inverse":this.noop,"data":data});\r
613   if (stack1 != null) { buffer += stack1; }\r
614   buffer += "\n";\r
615   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.headers : depth0), {"name":"if","hash":{},"fn":this.program(12, data),"inverse":this.noop,"data":data});\r
616   if (stack1 != null) { buffer += stack1; }\r
617   buffer += "\n        <form accept-charset='UTF-8' class='sandbox'>\n          <div style='margin:0;padding:0;display:inline'></div>\n";\r
618   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.parameters : depth0), {"name":"if","hash":{},"fn":this.program(15, data),"inverse":this.noop,"data":data});\r
619   if (stack1 != null) { buffer += stack1; }\r
620   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.responseMessages : depth0), {"name":"if","hash":{},"fn":this.program(17, data),"inverse":this.noop,"data":data});\r
621   if (stack1 != null) { buffer += stack1; }\r
622   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isReadOnly : depth0), {"name":"if","hash":{},"fn":this.program(19, data),"inverse":this.program(21, data),"data":data});\r
623   if (stack1 != null) { buffer += stack1; }\r
624   buffer += "        </form>\n        <div class='response' style='display:none'>\n          <h4 class='curl'>Curl</h4>\n          <div class='block curl'></div>\n          <h4 data-sw-translate>Request URL</h4>\n          <div class='block request_url'></div>\n";\r
625   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.showRequestHeaders : depth0), {"name":"if","hash":{},"fn":this.program(23, data),"inverse":this.noop,"data":data});\r
626   if (stack1 != null) { buffer += stack1; }\r
627   return buffer + "          <h4 data-sw-translate>Response Body</h4>\n          <div class='block response_body'></div>\n          <h4 data-sw-translate>Response Code</h4>\n          <div class='block response_code'></div>\n          <h4 data-sw-translate>Response Headers</h4>\n          <div class='block response_headers'></div>\n        </div>\n      </div>\n    </li>\n  </ul>\n";\r
628 },"useData":true});\r
629 this["Handlebars"]["templates"]["param_list"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {\r
630   return " required";\r
631   },"3":function(depth0,helpers,partials,data) {\r
632   return " multiple=\"multiple\"";\r
633   },"5":function(depth0,helpers,partials,data) {\r
634   return " required ";\r
635   },"7":function(depth0,helpers,partials,data) {\r
636   var stack1, buffer = "      <option ";\r
637   stack1 = helpers.unless.call(depth0, (depth0 != null ? depth0.hasDefault : depth0), {"name":"unless","hash":{},"fn":this.program(8, data),"inverse":this.noop,"data":data});\r
638   if (stack1 != null) { buffer += stack1; }\r
639   return buffer + " value=''></option>\n";\r
640 },"8":function(depth0,helpers,partials,data) {\r
641   return "  selected=\"\" ";\r
642   },"10":function(depth0,helpers,partials,data) {\r
643   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "\n      <option ";\r
644   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isDefault : depth0), {"name":"if","hash":{},"fn":this.program(11, data),"inverse":this.noop,"data":data});\r
645   if (stack1 != null) { buffer += stack1; }\r
646   buffer += "  value='"\r
647     + 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)))\r
648     + "'> "\r
649     + 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)))\r
650     + " ";\r
651   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isDefault : depth0), {"name":"if","hash":{},"fn":this.program(13, data),"inverse":this.noop,"data":data});\r
652   if (stack1 != null) { buffer += stack1; }\r
653   return buffer + " </option>\n\n";\r
654 },"11":function(depth0,helpers,partials,data) {\r
655   return " selected=\"\"  ";\r
656   },"13":function(depth0,helpers,partials,data) {\r
657   return " (default) ";\r
658   },"15":function(depth0,helpers,partials,data) {\r
659   return "<strong>";\r
660   },"17":function(depth0,helpers,partials,data) {\r
661   return "</strong>";\r
662   },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {\r
663   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<td class='code";\r
664   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.required : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});\r
665   if (stack1 != null) { buffer += stack1; }\r
666   buffer += "'><label for='"\r
667     + 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)))\r
668     + "'>"\r
669     + 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)))\r
670     + "</label></td>\n<td>\n  <select ";\r
671   stack1 = ((helpers.isArray || (depth0 && depth0.isArray) || helperMissing).call(depth0, depth0, {"name":"isArray","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data}));\r
672   if (stack1 != null) { buffer += stack1; }\r
673   buffer += " class=\"parameter ";\r
674   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.required : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.noop,"data":data});\r
675   if (stack1 != null) { buffer += stack1; }\r
676   buffer += "\" name=\""\r
677     + 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)))\r
678     + "\" id=\""\r
679     + 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)))\r
680     + "\">\n\n";\r
681   stack1 = helpers.unless.call(depth0, (depth0 != null ? depth0.required : depth0), {"name":"unless","hash":{},"fn":this.program(7, data),"inverse":this.noop,"data":data});\r
682   if (stack1 != null) { buffer += stack1; }\r
683   buffer += "\n";\r
684   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});\r
685   if (stack1 != null) { buffer += stack1; }\r
686   buffer += "\n  </select>\n</td>\n<td class=\"markdown\">";\r
687   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.required : depth0), {"name":"if","hash":{},"fn":this.program(15, data),"inverse":this.noop,"data":data});\r
688   if (stack1 != null) { buffer += stack1; }\r
689   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));\r
690   if (stack1 != null) { buffer += stack1; }\r
691   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.required : depth0), {"name":"if","hash":{},"fn":this.program(17, data),"inverse":this.noop,"data":data});\r
692   if (stack1 != null) { buffer += stack1; }\r
693   buffer += "</td>\n<td>";\r
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));\r
695   if (stack1 != null) { buffer += stack1; }\r
696   return buffer + "</td>\n<td><span class=\"model-signature\"></span></td>\n";\r
697 },"useData":true});\r
698 this["Handlebars"]["templates"]["param_readonly_required"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {\r
699   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;\r
700   return "        <textarea class='body-textarea' readonly='readonly' placeholder='(required)' name='"\r
701     + 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)))\r
702     + "' id='"\r
703     + 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)))\r
704     + "'>"\r
705     + 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)))\r
706     + "</textarea>\n";\r
707 },"3":function(depth0,helpers,partials,data) {\r
708   var stack1, buffer = "";\r
709   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});\r
710   if (stack1 != null) { buffer += stack1; }\r
711   return buffer;\r
712 },"4":function(depth0,helpers,partials,data) {\r
713   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;\r
714   return "            "\r
715     + 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)))\r
716     + "\n";\r
717 },"6":function(depth0,helpers,partials,data) {\r
718   return "            (empty)\n";\r
719   },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {\r
720   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<td class='code required'><label for='"\r
721     + 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)))\r
722     + "'>"\r
723     + 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)))\r
724     + "</label></td>\n<td>\n";\r
725   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});\r
726   if (stack1 != null) { buffer += stack1; }\r
727   buffer += "</td>\n<td class=\"markdown\">";\r
728   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));\r
729   if (stack1 != null) { buffer += stack1; }\r
730   buffer += "</td>\n<td>";\r
731   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));\r
732   if (stack1 != null) { buffer += stack1; }\r
733   return buffer + "</td>\n<td><span class=\"model-signature\"></span></td>\n";\r
734 },"useData":true});\r
735 this["Handlebars"]["templates"]["param_readonly"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {\r
736   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;\r
737   return "        <textarea class='body-textarea' readonly='readonly' name='"\r
738     + 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)))\r
739     + "' id='"\r
740     + 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)))\r
741     + "'>"\r
742     + 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)))\r
743     + "</textarea>\n        <div class=\"parameter-content-type\" />\n";\r
744 },"3":function(depth0,helpers,partials,data) {\r
745   var stack1, buffer = "";\r
746   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});\r
747   if (stack1 != null) { buffer += stack1; }\r
748   return buffer;\r
749 },"4":function(depth0,helpers,partials,data) {\r
750   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;\r
751   return "            "\r
752     + 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)))\r
753     + "\n";\r
754 },"6":function(depth0,helpers,partials,data) {\r
755   return "            (empty)\n";\r
756   },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {\r
757   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<td class='code'><label for='"\r
758     + 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)))\r
759     + "'>"\r
760     + 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)))\r
761     + "</label></td>\n<td>\n";\r
762   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});\r
763   if (stack1 != null) { buffer += stack1; }\r
764   buffer += "</td>\n<td class=\"markdown\">";\r
765   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));\r
766   if (stack1 != null) { buffer += stack1; }\r
767   buffer += "</td>\n<td>";\r
768   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));\r
769   if (stack1 != null) { buffer += stack1; }\r
770   return buffer + "</td>\n<td><span class=\"model-signature\"></span></td>\n";\r
771 },"useData":true});\r
772 this["Handlebars"]["templates"]["param_required"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {\r
773   var stack1, buffer = "";\r
774   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});\r
775   if (stack1 != null) { buffer += stack1; }\r
776   return buffer;\r
777 },"2":function(depth0,helpers,partials,data) {\r
778   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;\r
779   return "                      <input type=\"file\" name='"\r
780     + 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)))\r
781     + "' id='"\r
782     + 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)))\r
783     + "'/>\n";\r
784 },"4":function(depth0,helpers,partials,data) {\r
785   var stack1, buffer = "";\r
786   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});\r
787   if (stack1 != null) { buffer += stack1; }\r
788   return buffer;\r
789 },"5":function(depth0,helpers,partials,data) {\r
790   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;\r
791   return "                              <div class=\"editor_holder\"></div>\n                           <textarea class='body-textarea required' placeholder='(required)' name='"\r
792     + 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)))\r
793     + "' id=\""\r
794     + 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)))\r
795     + "\">"\r
796     + 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)))\r
797     + "</textarea>\n        <br />\n        <div class=\"parameter-content-type\" />\n";\r
798 },"7":function(depth0,helpers,partials,data) {\r
799   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;\r
800   return "                              <textarea class='body-textarea required' placeholder='(required)' name='"\r
801     + 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)))\r
802     + "' id='"\r
803     + 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)))\r
804     + "'></textarea>\n                          <div class=\"editor_holder\"></div>\n                           <br />\n                                <div class=\"parameter-content-type\" />\n";\r
805 },"9":function(depth0,helpers,partials,data) {\r
806   var stack1, buffer = "";\r
807   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});\r
808   if (stack1 != null) { buffer += stack1; }\r
809   return buffer;\r
810 },"10":function(depth0,helpers,partials,data) {\r
811   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;\r
812   return "                      <input class='parameter' class='required' type='file' name='"\r
813     + 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)))\r
814     + "' id='"\r
815     + 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)))\r
816     + "'/>\n";\r
817 },"12":function(depth0,helpers,partials,data) {\r
818   var stack1, helperMissing=helpers.helperMissing, buffer = "";\r
819   stack1 = ((helpers.renderTextParam || (depth0 && depth0.renderTextParam) || helperMissing).call(depth0, depth0, {"name":"renderTextParam","hash":{},"fn":this.program(13, data),"inverse":this.noop,"data":data}));\r
820   if (stack1 != null) { buffer += stack1; }\r
821   return buffer;\r
822 },"13":function(depth0,helpers,partials,data) {\r
823   return "";\r
824 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {\r
825   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<td class='code required'><label for='"\r
826     + 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)))\r
827     + "'>"\r
828     + 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)))\r
829     + "</label></td>\n<td>\n";\r
830   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});\r
831   if (stack1 != null) { buffer += stack1; }\r
832   buffer += "</td>\n<td>\n      <strong><span class=\"markdown\">";\r
833   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));\r
834   if (stack1 != null) { buffer += stack1; }\r
835   buffer += "</span></strong>\n</td>\n<td>";\r
836   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));\r
837   if (stack1 != null) { buffer += stack1; }\r
838   return buffer + "</td>\n<td><span class=\"model-signature\"></span></td>\n";\r
839 },"useData":true});\r
840 this["Handlebars"]["templates"]["param"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {\r
841   var stack1, buffer = "";\r
842   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});\r
843   if (stack1 != null) { buffer += stack1; }\r
844   return buffer;\r
845 },"2":function(depth0,helpers,partials,data) {\r
846   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;\r
847   return "                      <input type=\"file\" name='"\r
848     + 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)))\r
849     + "' id='"\r
850     + 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)))\r
851     + "'/>\n                    <div class=\"parameter-content-type\" />\n";\r
852 },"4":function(depth0,helpers,partials,data) {\r
853   var stack1, buffer = "";\r
854   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});\r
855   if (stack1 != null) { buffer += stack1; }\r
856   return buffer;\r
857 },"5":function(depth0,helpers,partials,data) {\r
858   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;\r
859   return "                              <div class=\"editor_holder\"></div>\n                           <textarea class='body-textarea' name='"\r
860     + 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)))\r
861     + "' id='"\r
862     + 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)))\r
863     + "'>"\r
864     + 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)))\r
865     + "</textarea>\n        <br />\n        <div class=\"parameter-content-type\" />\n";\r
866 },"7":function(depth0,helpers,partials,data) {\r
867   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;\r
868   return "                              <textarea class='body-textarea' name='"\r
869     + 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)))\r
870     + "' id='"\r
871     + 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)))\r
872     + "'></textarea>\n                          <div class=\"editor_holder\"></div>\n                           <br />\n                                <div class=\"parameter-content-type\" />\n";\r
873 },"9":function(depth0,helpers,partials,data) {\r
874   var stack1, buffer = "";\r
875   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});\r
876   if (stack1 != null) { buffer += stack1; }\r
877   return buffer;\r
878 },"10":function(depth0,helpers,partials,data) {\r
879   var stack1, helperMissing=helpers.helperMissing, buffer = "";\r
880   stack1 = ((helpers.renderTextParam || (depth0 && depth0.renderTextParam) || helperMissing).call(depth0, depth0, {"name":"renderTextParam","hash":{},"fn":this.program(11, data),"inverse":this.noop,"data":data}));\r
881   if (stack1 != null) { buffer += stack1; }\r
882   return buffer;\r
883 },"11":function(depth0,helpers,partials,data) {\r
884   return "";\r
885 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {\r
886   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<td class='code'><label for='"\r
887     + 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)))\r
888     + "'>"\r
889     + 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)))\r
890     + "</label></td>\n<td>\n\n";\r
891   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});\r
892   if (stack1 != null) { buffer += stack1; }\r
893   buffer += "\n</td>\n<td class=\"markdown\">";\r
894   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));\r
895   if (stack1 != null) { buffer += stack1; }\r
896   buffer += "</td>\n<td>";\r
897   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));\r
898   if (stack1 != null) { buffer += stack1; }\r
899   return buffer + "</td>\n<td>\n        <span class=\"model-signature\"></span>\n</td>\n";\r
900 },"useData":true});\r
901 this["Handlebars"]["templates"]["parameter_content_type"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {\r
902   var stack1, buffer = "";\r
903   stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.consumes : depth0), {"name":"each","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data});\r
904   if (stack1 != null) { buffer += stack1; }\r
905   return buffer;\r
906 },"2":function(depth0,helpers,partials,data) {\r
907   var lambda=this.lambda, escapeExpression=this.escapeExpression;\r
908   return "  <option value=\""\r
909     + escapeExpression(lambda(depth0, depth0))\r
910     + "\">"\r
911     + escapeExpression(lambda(depth0, depth0))\r
912     + "</option>\n";\r
913 },"4":function(depth0,helpers,partials,data) {\r
914   return "  <option value=\"application/json\">application/json</option>\n";\r
915   },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {\r
916   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<label for=\""\r
917     + 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)))\r
918     + "\" data-sw-translate>Parameter content type:</label>\n<select name=\"parameterContentType\" id=\""\r
919     + 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)))\r
920     + "\">\n";\r
921   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});\r
922   if (stack1 != null) { buffer += stack1; }\r
923   return buffer + "</select>\n";\r
924 },"useData":true});\r
925 this["Handlebars"]["templates"]["popup"] = Handlebars.template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {\r
926   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;\r
927   return "<div class=\"api-popup-dialog-wrapper\">\n    <div class=\"api-popup-title\">"\r
928     + escapeExpression(((helper = (helper = helpers.title || (depth0 != null ? depth0.title : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"title","hash":{},"data":data}) : helper)))\r
929     + "</div>\n    <div class=\"api-popup-content\"></div>\n    <p class=\"error-msg\"></p>\n    <div class=\"api-popup-actions\">\n        <button class=\"api-popup-cancel api-button gray\" type=\"button\">Cancel</button>\n    </div>\n</div>\n<div class=\"api-popup-dialog-shadow\"></div>";\r
930 },"useData":true});\r
931 this["Handlebars"]["templates"]["resource"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {\r
932   return " : ";\r
933   },"3":function(depth0,helpers,partials,data) {\r
934   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;\r
935   return "    <li>\n      <a href='"\r
936     + 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)))\r
937     + "' data-sw-translate>Raw</a>\n    </li>\n";\r
938 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {\r
939   var stack1, helper, options, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, blockHelperMissing=helpers.blockHelperMissing, buffer = "<div class='heading'>\n  <h2>\n    <a href='#!/"\r
940     + 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)))\r
941     + "' class=\"toggleEndpointList\" data-id=\""\r
942     + 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)))\r
943     + "\">"\r
944     + 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)))\r
945     + "</a> ";\r
946   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));\r
947   if (!helpers.summary) { stack1 = blockHelperMissing.call(depth0, stack1, options); }\r
948   if (stack1 != null) { buffer += stack1; }\r
949   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));\r
950   if (stack1 != null) { buffer += stack1; }\r
951   buffer += "\n  </h2>\n  <ul class='options'>\n    <li>\n      <a href='#!/"\r
952     + 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)))\r
953     + "' id='endpointListTogger_"\r
954     + 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)))\r
955     + "' class=\"toggleEndpointList\" data-id=\""\r
956     + 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)))\r
957     + "\" data-sw-translate>Show/Hide</a>\n    </li>\n    <li>\n      <a href='#' class=\"collapseResource\" data-id=\""\r
958     + 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)))\r
959     + "\" data-sw-translate>\n        List Operations\n      </a>\n    </li>\n    <li>\n      <a href='#' class=\"expandResource\" data-id=\""\r
960     + 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)))\r
961     + "\" data-sw-translate>\n        Expand Operations\n      </a>\n    </li>\n";\r
962   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.url : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data});\r
963   if (stack1 != null) { buffer += stack1; }\r
964   return buffer + "  </ul>\n</div>\n<ul class='endpoints' id='"\r
965     + 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)))\r
966     + "_endpoint_list' style='display:none'>\n\n</ul>\n";\r
967 },"useData":true});\r
968 this["Handlebars"]["templates"]["response_content_type"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {\r
969   var stack1, buffer = "";\r
970   stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.produces : depth0), {"name":"each","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data});\r
971   if (stack1 != null) { buffer += stack1; }\r
972   return buffer;\r
973 },"2":function(depth0,helpers,partials,data) {\r
974   var lambda=this.lambda, escapeExpression=this.escapeExpression;\r
975   return "  <option value=\""\r
976     + escapeExpression(lambda(depth0, depth0))\r
977     + "\">"\r
978     + escapeExpression(lambda(depth0, depth0))\r
979     + "</option>\n";\r
980 },"4":function(depth0,helpers,partials,data) {\r
981   return "  <option value=\"application/json\">application/json</option>\n";\r
982   },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {\r
983   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<label data-sw-translate for=\""\r
984     + 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)))\r
985     + "\">Response Content Type</label>\n<select name=\"responseContentType\" id=\""\r
986     + 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)))\r
987     + "\">\n";\r
988   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});\r
989   if (stack1 != null) { buffer += stack1; }\r
990   return buffer + "</select>\n";\r
991 },"useData":true});\r
992 this["Handlebars"]["templates"]["signature"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {\r
993   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, buffer = "\n<div>\n<ul class=\"signature-nav\">\n  <li><a class=\"description-link\" href=\"#\" data-sw-translate>Model</a></li>\n  <li><a class=\"snippet-link\" href=\"#\" data-sw-translate>Example Value</a></li>\n</ul>\n<div>\n\n<div class=\"signature-container\">\n  <div class=\"description\">\n    ";\r
994   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));\r
995   if (stack1 != null) { buffer += stack1; }\r
996   buffer += "\n  </div>\n\n  <div class=\"snippet\">\n";\r
997   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.sampleJSON : depth0), {"name":"if","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data});\r
998   if (stack1 != null) { buffer += stack1; }\r
999   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.sampleXML : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.noop,"data":data});\r
1000   if (stack1 != null) { buffer += stack1; }\r
1001   return buffer + "  </div>\n</div>\n";\r
1002 },"2":function(depth0,helpers,partials,data) {\r
1003   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "      <div class=\"snippet_json\">\n        <pre><code>"\r
1004     + 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)))\r
1005     + "</code></pre>\n        ";\r
1006   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isParam : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data});\r
1007   if (stack1 != null) { buffer += stack1; }\r
1008   return buffer + "\n      </div>\n";\r
1009 },"3":function(depth0,helpers,partials,data) {\r
1010   return "<small class=\"notice\" data-sw-translate></small>";\r
1011   },"5":function(depth0,helpers,partials,data) {\r
1012   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "    <div class=\"snippet_xml\">\n      <pre><code>"\r
1013     + escapeExpression(((helper = (helper = helpers.sampleXML || (depth0 != null ? depth0.sampleXML : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"sampleXML","hash":{},"data":data}) : helper)))\r
1014     + "</code></pre>\n      ";\r
1015   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isParam : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data});\r
1016   if (stack1 != null) { buffer += stack1; }\r
1017   return buffer + "\n    </div>\n";\r
1018 },"7":function(depth0,helpers,partials,data) {\r
1019   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;\r
1020   return "    "\r
1021     + escapeExpression(((helper = (helper = helpers.signature || (depth0 != null ? depth0.signature : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"signature","hash":{},"data":data}) : helper)))\r
1022     + "\n";\r
1023 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {\r
1024   var stack1, helperMissing=helpers.helperMissing;\r
1025   stack1 = ((helpers.ifCond || (depth0 && depth0.ifCond) || helperMissing).call(depth0, (depth0 != null ? depth0.sampleJSON : depth0), "||", (depth0 != null ? depth0.sampleXML : depth0), {"name":"ifCond","hash":{},"fn":this.program(1, data),"inverse":this.program(7, data),"data":data}));\r
1026   if (stack1 != null) { return stack1; }\r
1027   else { return ''; }\r
1028   },"useData":true});\r
1029 this["Handlebars"]["templates"]["status_code"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {\r
1030   var lambda=this.lambda, escapeExpression=this.escapeExpression;\r
1031   return "      <tr>\n        <td>"\r
1032     + escapeExpression(lambda((data && data.key), depth0))\r
1033     + "</td>\n        <td>"\r
1034     + escapeExpression(lambda((depth0 != null ? depth0.description : depth0), depth0))\r
1035     + "</td>\n        <td>"\r
1036     + escapeExpression(lambda((depth0 != null ? depth0.type : depth0), depth0))\r
1037     + "</td>\n      </tr>\n";\r
1038 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {\r
1039   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<td width='15%' class='code'>"\r
1040     + 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)))\r
1041     + "</td>\n<td class=\"markdown\">";\r
1042   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));\r
1043   if (stack1 != null) { buffer += stack1; }\r
1044   buffer += "</td>\n<td width='50%'><span class=\"model-signature\" /></td>\n<td class=\"headers\">\n  <table>\n    <tbody>\n";\r
1045   stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.headers : depth0), {"name":"each","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});\r
1046   if (stack1 != null) { buffer += stack1; }\r
1047   return buffer + "    </tbody>\n  </table>\n</td>";\r
1048 },"useData":true});\r
1049 /**\r
1050  * swagger-client - swagger-client is a javascript client for use with swaggering APIs.\r
1051  * @version v2.1.14\r
1052  * @link http://swagger.io\r
1053  * @license Apache-2.0\r
1054  */\r
1055 (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){\r
1056 'use strict';\r
1057 \r
1058 var auth = require('./lib/auth');\r
1059 var helpers = require('./lib/helpers');\r
1060 var SwaggerClient = require('./lib/client');\r
1061 var deprecationWrapper = function (url, options) {\r
1062   helpers.log('This is deprecated, use "new SwaggerClient" instead.');\r
1063 \r
1064   return new SwaggerClient(url, options);\r
1065 };\r
1066 \r
1067 /* Here for IE8 Support */\r
1068 if (!Array.prototype.indexOf) {\r
1069   Array.prototype.indexOf = function(obj, start) {\r
1070     for (var i = (start || 0), j = this.length; i < j; i++) {\r
1071       if (this[i] === obj) { return i; }\r
1072     }\r
1073     return -1;\r
1074   };\r
1075 }\r
1076 \r
1077 /* Here for IE8 Support */\r
1078 if (!String.prototype.trim) {\r
1079   String.prototype.trim = function () {\r
1080     return this.replace(/^\s+|\s+$/g, '');\r
1081   };\r
1082 }\r
1083 \r
1084 /* Here for node 10.x support */\r
1085 if (!String.prototype.endsWith) {\r
1086   String.prototype.endsWith = function(suffix) {\r
1087     return this.indexOf(suffix, this.length - suffix.length) !== -1;\r
1088   };\r
1089 }\r
1090 \r
1091 module.exports = SwaggerClient;\r
1092 \r
1093 SwaggerClient.ApiKeyAuthorization = auth.ApiKeyAuthorization;\r
1094 SwaggerClient.PasswordAuthorization = auth.PasswordAuthorization;\r
1095 SwaggerClient.CookieAuthorization = auth.CookieAuthorization;\r
1096 SwaggerClient.SwaggerApi = deprecationWrapper;\r
1097 SwaggerClient.SwaggerClient = deprecationWrapper;\r
1098 SwaggerClient.SchemaMarkup = require('./lib/schema-markup');\r
1099 \r
1100 },{"./lib/auth":2,"./lib/client":3,"./lib/helpers":4,"./lib/schema-markup":7}],2:[function(require,module,exports){\r
1101 'use strict';\r
1102 \r
1103 var helpers = require('./helpers');\r
1104 var btoa = require('btoa'); // jshint ignore:line\r
1105 var CookieJar = require('cookiejar').CookieJar;\r
1106 var _ = {\r
1107   each: require('lodash-compat/collection/each'),\r
1108   includes: require('lodash-compat/collection/includes'),\r
1109   isObject: require('lodash-compat/lang/isObject'),\r
1110   isArray: require('lodash-compat/lang/isArray')\r
1111 };\r
1112 \r
1113 /**\r
1114  * SwaggerAuthorizations applys the correct authorization to an operation being executed\r
1115  */\r
1116 var SwaggerAuthorizations = module.exports.SwaggerAuthorizations = function (authz) {\r
1117   this.authz = authz || {};\r
1118 };\r
1119 \r
1120 /**\r
1121  * Add auths to the hash\r
1122  * Will overwrite any existing\r
1123  *\r
1124  */\r
1125 SwaggerAuthorizations.prototype.add = function (name, auth) {\r
1126   if(_.isObject(name)) {\r
1127     for (var key in name) {\r
1128       this.authz[key] = name[key];\r
1129     }\r
1130   } else if(typeof name === 'string' ){\r
1131     this.authz[name] = auth;\r
1132   }\r
1133 \r
1134   return auth;\r
1135 };\r
1136 \r
1137 SwaggerAuthorizations.prototype.remove = function (name) {\r
1138   return delete this.authz[name];\r
1139 };\r
1140 \r
1141 SwaggerAuthorizations.prototype.apply = function (obj, securities) {\r
1142   var status = true;\r
1143   var applyAll = !securities;\r
1144   var flattenedSecurities = [];\r
1145 \r
1146   // favor the object-level authorizations over global\r
1147   var authz = obj.clientAuthorizations || this.authz;\r
1148 \r
1149   // Securities could be [ {} ]\r
1150   _.each(securities, function (obj, key) {\r
1151 \r
1152     // Make sure we account for securities being [ str ]\r
1153     if(typeof key === 'string') {\r
1154       flattenedSecurities.push(key);\r
1155     }\r
1156 \r
1157     // Flatten keys in to our array\r
1158     _.each(obj, function (val, key) {\r
1159       flattenedSecurities.push(key);\r
1160     });\r
1161   });\r
1162 \r
1163   _.each(authz, function (auth, authName) {\r
1164     if(applyAll || _.includes(flattenedSecurities, authName)) {\r
1165       var newStatus = auth.apply(obj);\r
1166       status = status && !!newStatus; // logical ORs regarding status\r
1167     }\r
1168   });\r
1169 \r
1170   return status;\r
1171 };\r
1172 \r
1173 /**\r
1174  * ApiKeyAuthorization allows a query param or header to be injected\r
1175  */\r
1176 var ApiKeyAuthorization = module.exports.ApiKeyAuthorization = function (name, value, type) {\r
1177   this.name = name;\r
1178   this.value = value;\r
1179   this.type = type;\r
1180 };\r
1181 \r
1182 ApiKeyAuthorization.prototype.apply = function (obj) {\r
1183   if (this.type === 'query') {\r
1184     // see if already applied.  If so, don't do it again\r
1185 \r
1186     var qp;\r
1187     if (obj.url.indexOf('?') > 0) {\r
1188       qp = obj.url.substring(obj.url.indexOf('?') + 1);\r
1189       var parts = qp.split('&');\r
1190       if(parts && parts.length > 0) {\r
1191         for(var i = 0; i < parts.length; i++) {\r
1192           var kv = parts[i].split('=');\r
1193           if(kv && kv.length > 0) {\r
1194             if (kv[0] === this.name) {\r
1195               // skip it\r
1196               return false;\r
1197             }\r
1198           }\r
1199         }\r
1200       }\r
1201     }\r
1202 \r
1203     if (obj.url.indexOf('?') > 0) {\r
1204       obj.url = obj.url + '&' + this.name + '=' + this.value;\r
1205     } else {\r
1206       obj.url = obj.url + '?' + this.name + '=' + this.value;\r
1207     }\r
1208 \r
1209     return true;\r
1210   } else if (this.type === 'header') {\r
1211     if(typeof obj.headers[this.name] === 'undefined') {\r
1212       obj.headers[this.name] = this.value;\r
1213     }\r
1214 \r
1215     return true;\r
1216   }\r
1217 };\r
1218 \r
1219 var CookieAuthorization = module.exports.CookieAuthorization = function (cookie) {\r
1220   this.cookie = cookie;\r
1221 };\r
1222 \r
1223 CookieAuthorization.prototype.apply = function (obj) {\r
1224   obj.cookieJar = obj.cookieJar || new CookieJar();\r
1225   obj.cookieJar.setCookie(this.cookie);\r
1226 \r
1227   return true;\r
1228 };\r
1229 \r
1230 /**\r
1231  * Password Authorization is a basic auth implementation\r
1232  */\r
1233 var PasswordAuthorization = module.exports.PasswordAuthorization = function (username, password) {\r
1234   if (arguments.length === 3) {\r
1235     helpers.log('PasswordAuthorization: the \'name\' argument has been removed, pass only username and password');\r
1236     username = arguments[1];\r
1237     password = arguments[2];\r
1238   }\r
1239   this.username = username;\r
1240   this.password = password;\r
1241 };\r
1242 \r
1243 PasswordAuthorization.prototype.apply = function (obj) {\r
1244   if(typeof obj.headers.Authorization === 'undefined') {\r
1245     obj.headers.Authorization = 'Basic ' + btoa(this.username + ':' + this.password);\r
1246   }\r
1247 \r
1248   return true;\r
1249 };\r
1250 \r
1251 },{"./helpers":4,"btoa":14,"cookiejar":20,"lodash-compat/collection/each":54,"lodash-compat/collection/includes":57,"lodash-compat/lang/isArray":142,"lodash-compat/lang/isObject":146}],3:[function(require,module,exports){\r
1252 'use strict';\r
1253 \r
1254 var _ = {\r
1255   bind: require('lodash-compat/function/bind'),\r
1256   cloneDeep: require('lodash-compat/lang/cloneDeep'),\r
1257   find: require('lodash-compat/collection/find'),\r
1258   forEach: require('lodash-compat/collection/forEach'),\r
1259   indexOf: require('lodash-compat/array/indexOf'),\r
1260   isArray: require('lodash-compat/lang/isArray'),\r
1261   isObject: require('lodash-compat/lang/isObject'),\r
1262   isFunction: require('lodash-compat/lang/isFunction'),\r
1263   isPlainObject: require('lodash-compat/lang/isPlainObject'),\r
1264   isUndefined: require('lodash-compat/lang/isUndefined')\r
1265 };\r
1266 var auth = require('./auth');\r
1267 var helpers = require('./helpers');\r
1268 var Model = require('./types/model');\r
1269 var Operation = require('./types/operation');\r
1270 var OperationGroup = require('./types/operationGroup');\r
1271 var Resolver = require('./resolver');\r
1272 var SwaggerHttp = require('./http');\r
1273 var SwaggerSpecConverter = require('./spec-converter');\r
1274 var Q = require('q');\r
1275 \r
1276 // We have to keep track of the function/property names to avoid collisions for tag names which are used to allow the\r
1277 // following usage: 'client.{tagName}'\r
1278 var reservedClientTags = [\r
1279   'apis',\r
1280   'authorizationScheme',\r
1281   'authorizations',\r
1282   'basePath',\r
1283   'build',\r
1284   'buildFrom1_1Spec',\r
1285   'buildFrom1_2Spec',\r
1286   'buildFromSpec',\r
1287   'clientAuthorizations',\r
1288   'convertInfo',\r
1289   'debug',\r
1290   'defaultErrorCallback',\r
1291   'defaultSuccessCallback',\r
1292   'enableCookies',\r
1293   'fail',\r
1294   'failure',\r
1295   'finish',\r
1296   'help',\r
1297   'host',\r
1298   'idFromOp',\r
1299   'info',\r
1300   'initialize',\r
1301   'isBuilt',\r
1302   'isValid',\r
1303   'modelPropertyMacro',\r
1304   'models',\r
1305   'modelsArray',\r
1306   'options',\r
1307   'parameterMacro',\r
1308   'parseUri',\r
1309   'progress',\r
1310   'resourceCount',\r
1311   'sampleModels',\r
1312   'selfReflect',\r
1313   'setConsolidatedModels',\r
1314   'spec',\r
1315   'supportedSubmitMethods',\r
1316   'swaggerRequestHeaders',\r
1317   'tagFromLabel',\r
1318   'title',\r
1319   'url',\r
1320   'useJQuery'\r
1321 ];\r
1322 // We have to keep track of the function/property names to avoid collisions for tag names which are used to allow the\r
1323 // following usage: 'client.apis.{tagName}'\r
1324 var reservedApiTags = [\r
1325   'apis',\r
1326   'asCurl',\r
1327   'description',\r
1328   'externalDocs',\r
1329   'help',\r
1330   'label',\r
1331   'name',\r
1332   'operation',\r
1333   'operations',\r
1334   'operationsArray',\r
1335   'path',\r
1336   'tag'\r
1337 ];\r
1338 var supportedOperationMethods = ['delete', 'get', 'head', 'options', 'patch', 'post', 'put'];\r
1339 var SwaggerClient = module.exports = function (url, options) {\r
1340   this.authorizations = null;\r
1341   this.authorizationScheme = null;\r
1342   this.basePath = null;\r
1343   this.debug = false;\r
1344   this.enableCookies = false;\r
1345   this.info = null;\r
1346   this.isBuilt = false;\r
1347   this.isValid = false;\r
1348   this.modelsArray = [];\r
1349   this.resourceCount = 0;\r
1350   this.url = null;\r
1351   this.useJQuery = false;\r
1352   this.swaggerObject = {};\r
1353   this.deferredClient = undefined;\r
1354 \r
1355   this.clientAuthorizations = new auth.SwaggerAuthorizations();\r
1356 \r
1357   if (typeof url !== 'undefined') {\r
1358     return this.initialize(url, options);\r
1359   } else {\r
1360     return this;\r
1361   }\r
1362 };\r
1363 \r
1364 SwaggerClient.prototype.initialize = function (url, options) {\r
1365   this.models = {};\r
1366   this.sampleModels = {};\r
1367 \r
1368   if (typeof url === 'string') {\r
1369     this.url = url;\r
1370   } else if (_.isObject(url)) {\r
1371     options = url;\r
1372     this.url = options.url;\r
1373   }\r
1374 \r
1375   options = options || {};\r
1376   this.clientAuthorizations.add(options.authorizations);\r
1377   this.swaggerRequestHeaders = options.swaggerRequestHeaders || 'application/json;charset=utf-8,*/*';\r
1378   this.defaultSuccessCallback = options.defaultSuccessCallback || null;\r
1379   this.defaultErrorCallback = options.defaultErrorCallback || null;\r
1380   this.modelPropertyMacro = options.modelPropertyMacro || null;\r
1381   this.parameterMacro = options.parameterMacro || null;\r
1382   this.usePromise = options.usePromise || null;\r
1383 \r
1384 \r
1385   if(this.usePromise) {\r
1386     this.deferredClient = Q.defer();\r
1387   }\r
1388 \r
1389   if (typeof options.success === 'function') {\r
1390     this.success = options.success;\r
1391   }\r
1392 \r
1393   if (options.useJQuery) {\r
1394     this.useJQuery = options.useJQuery;\r
1395   }\r
1396 \r
1397   if (options.enableCookies) {\r
1398     this.enableCookies = options.enableCookies;\r
1399   }\r
1400 \r
1401   this.options = options || {};\r
1402 \r
1403   this.supportedSubmitMethods = options.supportedSubmitMethods || [];\r
1404   this.failure = options.failure || function (err) { throw err; };\r
1405   this.progress = options.progress || function () {};\r
1406   this.spec = _.cloneDeep(options.spec); // Clone so we do not alter the provided document\r
1407 \r
1408   if (options.scheme) {\r
1409     this.scheme = options.scheme;\r
1410   }\r
1411 \r
1412   if (this.usePromise || typeof options.success === 'function') {\r
1413     this.ready = true;\r
1414     return this.build();\r
1415   }\r
1416 };\r
1417 \r
1418 SwaggerClient.prototype.build = function (mock) {\r
1419   if (this.isBuilt) {\r
1420     return this;\r
1421   }\r
1422 \r
1423   var self = this;\r
1424 \r
1425   this.progress('fetching resource list: ' + this.url + '; Please wait.');\r
1426 \r
1427   var obj = {\r
1428     useJQuery: this.useJQuery,\r
1429     url: this.url,\r
1430     method: 'get',\r
1431     headers: {\r
1432       accept: this.swaggerRequestHeaders\r
1433     },\r
1434     on: {\r
1435       error: function (response) {\r
1436         if (self.url.substring(0, 4) !== 'http') {\r
1437           return self.fail('Please specify the protocol for ' + self.url);\r
1438         } else if (response.status === 0) {\r
1439           return self.fail('Can\'t read from server.  It may not have the appropriate access-control-origin settings.');\r
1440         } else if (response.status === 404) {\r
1441           return self.fail('Can\'t read swagger JSON from ' + self.url);\r
1442         } else {\r
1443           return self.fail(response.status + ' : ' + response.statusText + ' ' + self.url);\r
1444         }\r
1445       },\r
1446       response: function (resp) {\r
1447 \r
1448         var responseObj = resp.obj;\r
1449         if(!responseObj) {\r
1450           return self.fail('failed to parse JSON/YAML response');\r
1451         }\r
1452 \r
1453         self.swaggerVersion = responseObj.swaggerVersion;\r
1454         self.swaggerObject = responseObj;\r
1455 \r
1456         if (responseObj.swagger && parseInt(responseObj.swagger) === 2) {\r
1457           self.swaggerVersion = responseObj.swagger;\r
1458 \r
1459           new Resolver().resolve(responseObj, self.url, self.buildFromSpec, self);\r
1460 \r
1461           self.isValid = true;\r
1462         } else {\r
1463           var converter = new SwaggerSpecConverter();\r
1464           self.oldSwaggerObject = self.swaggerObject;\r
1465 \r
1466           converter.setDocumentationLocation(self.url);\r
1467           converter.convert(responseObj, self.clientAuthorizations, self.options, function(spec) {\r
1468             self.swaggerObject = spec;\r
1469             new Resolver().resolve(spec, self.url, self.buildFromSpec, self);\r
1470             self.isValid = true;\r
1471           });\r
1472         }\r
1473       }\r
1474     }\r
1475   };\r
1476 \r
1477   if (this.spec) {\r
1478     self.swaggerObject = this.spec;\r
1479     setTimeout(function () {\r
1480       new Resolver().resolve(self.spec, self.url, self.buildFromSpec, self);\r
1481     }, 10);\r
1482   } else {\r
1483     this.clientAuthorizations.apply(obj);\r
1484 \r
1485     if (mock) {\r
1486       return obj;\r
1487     }\r
1488 \r
1489     new SwaggerHttp().execute(obj, this.options);\r
1490   }\r
1491 \r
1492   return (this.usePromise) ? this.deferredClient.promise : this;\r
1493 };\r
1494 \r
1495 SwaggerClient.prototype.buildFromSpec = function (response) {\r
1496   if (this.isBuilt) {\r
1497     return this;\r
1498   }\r
1499 \r
1500   this.apis = {};\r
1501   this.apisArray = [];\r
1502   this.basePath = response.basePath || '';\r
1503   this.consumes = response.consumes;\r
1504   this.host = response.host || '';\r
1505   this.info = response.info || {};\r
1506   this.produces = response.produces;\r
1507   this.schemes = response.schemes || [];\r
1508   this.securityDefinitions = response.securityDefinitions;\r
1509   this.security = response.security;\r
1510   this.title = response.title || '';\r
1511 \r
1512   if (response.externalDocs) {\r
1513     this.externalDocs = response.externalDocs;\r
1514   }\r
1515 \r
1516   // legacy support\r
1517   this.authSchemes = response.securityDefinitions;\r
1518 \r
1519   var definedTags = {};\r
1520   var k;\r
1521 \r
1522   if (Array.isArray(response.tags)) {\r
1523     definedTags = {};\r
1524 \r
1525     for (k = 0; k < response.tags.length; k++) {\r
1526       var t = response.tags[k];\r
1527       definedTags[t.name] = t;\r
1528     }\r
1529   }\r
1530 \r
1531   var location;\r
1532 \r
1533   if (typeof this.url === 'string') {\r
1534     location = this.parseUri(this.url);\r
1535     if (typeof this.scheme === 'undefined' && typeof this.schemes === 'undefined' || this.schemes.length === 0) {\r
1536       this.scheme = location.scheme || 'http';\r
1537     } else if (typeof this.scheme === 'undefined') {\r
1538       this.scheme = this.schemes[0] || location.scheme;\r
1539     }\r
1540 \r
1541     if (typeof this.host === 'undefined' || this.host === '') {\r
1542       this.host = location.host;\r
1543 \r
1544       if (location.port) {\r
1545         this.host = this.host + ':' + location.port;\r
1546       }\r
1547     }\r
1548   }\r
1549   else {\r
1550     if (typeof this.schemes === 'undefined' || this.schemes.length === 0) {\r
1551       this.scheme = 'http';\r
1552     }\r
1553     else if (typeof this.scheme === 'undefined') {\r
1554       this.scheme = this.schemes[0];\r
1555     }\r
1556   }\r
1557 \r
1558   this.definitions = response.definitions;\r
1559 \r
1560   var key;\r
1561 \r
1562   for (key in this.definitions) {\r
1563     var model = new Model(key, this.definitions[key], this.models, this.modelPropertyMacro);\r
1564 \r
1565     if (model) {\r
1566       this.models[key] = model;\r
1567     }\r
1568   }\r
1569 \r
1570   // get paths, create functions for each operationId\r
1571   var self = this;\r
1572 \r
1573   // Bind help to 'client.apis'\r
1574   self.apis.help = _.bind(self.help, self);\r
1575 \r
1576   _.forEach(response.paths, function (pathObj, path) {\r
1577     // Only process a path if it's an object\r
1578     if (!_.isPlainObject(pathObj)) {\r
1579       return;\r
1580     }\r
1581 \r
1582     _.forEach(supportedOperationMethods, function (method) {\r
1583       var operation = pathObj[method];\r
1584 \r
1585       if (_.isUndefined(operation)) {\r
1586         // Operation does not exist\r
1587         return;\r
1588       } else if (!_.isPlainObject(operation)) {\r
1589         // Operation exists but it is not an Operation Object.  Since this is invalid, log it.\r
1590         helpers.log('The \'' + method + '\' operation for \'' + path + '\' path is not an Operation Object');\r
1591 \r
1592         return;\r
1593       }\r
1594 \r
1595       var tags = operation.tags;\r
1596 \r
1597       if (_.isUndefined(tags) || !_.isArray(tags) || tags.length === 0) {\r
1598         tags = operation.tags = [ 'default' ];\r
1599       }\r
1600 \r
1601       var operationId = self.idFromOp(path, method, operation);\r
1602 \r
1603       var operationObject = new Operation(self,\r
1604         operation.scheme,\r
1605         operationId,\r
1606         method,\r
1607         path,\r
1608         operation,\r
1609         self.definitions,\r
1610         self.models,\r
1611         self.clientAuthorizations);\r
1612 \r
1613       // bind self operation's execute command to the api\r
1614       _.forEach(tags, function (tag) {\r
1615         var clientProperty = _.indexOf(reservedClientTags, tag) > -1 ? '_' + tag : tag;\r
1616         var apiProperty = _.indexOf(reservedApiTags, tag) > -1 ? '_' + tag : tag;\r
1617         var operationGroup = self[clientProperty];\r
1618 \r
1619         if (clientProperty !== tag) {\r
1620           helpers.log('The \'' + tag + '\' tag conflicts with a SwaggerClient function/property name.  Use \'client.' +\r
1621                       clientProperty + '\' or \'client.apis.' + tag + '\' instead of \'client.' + tag + '\'.');\r
1622         }\r
1623 \r
1624         if (apiProperty !== tag) {\r
1625           helpers.log('The \'' + tag + '\' tag conflicts with a SwaggerClient operation function/property name.  Use ' +\r
1626                       '\'client.apis.' + apiProperty + '\' instead of \'client.apis.' + tag + '\'.');\r
1627         }\r
1628 \r
1629         if (_.indexOf(reservedApiTags, operationId) > -1) {\r
1630           helpers.log('The \'' + operationId + '\' operationId conflicts with a SwaggerClient operation ' +\r
1631                       'function/property name.  Use \'client.apis.' + apiProperty + '._' + operationId +\r
1632                       '\' instead of \'client.apis.' + apiProperty + '.' + operationId + '\'.');\r
1633 \r
1634           operationId = '_' + operationId;\r
1635           operationObject.nickname = operationId; // So 'client.apis.[tag].operationId.help() works properly\r
1636         }\r
1637 \r
1638         if (_.isUndefined(operationGroup)) {\r
1639           operationGroup = self[clientProperty] = self.apis[apiProperty] = {};\r
1640 \r
1641           operationGroup.operations = {};\r
1642           operationGroup.label = apiProperty;\r
1643           operationGroup.apis = {};\r
1644 \r
1645           var tagDef = definedTags[tag];\r
1646 \r
1647           if (!_.isUndefined(tagDef)) {\r
1648             operationGroup.description = tagDef.description;\r
1649             operationGroup.externalDocs = tagDef.externalDocs;\r
1650           }\r
1651 \r
1652           self[clientProperty].help = _.bind(self.help, operationGroup);\r
1653           self.apisArray.push(new OperationGroup(tag, operationGroup.description, operationGroup.externalDocs, operationObject));\r
1654         }\r
1655 \r
1656         operationId = self.makeUniqueOperationId(operationId, self.apis[apiProperty]);\r
1657 \r
1658         // Bind tag help\r
1659         if (!_.isFunction(operationGroup.help)) {\r
1660           operationGroup.help = _.bind(self.help, operationGroup);\r
1661         }\r
1662 \r
1663         // bind to the apis object\r
1664         self.apis[apiProperty][operationId] = operationGroup[operationId] = _.bind(operationObject.execute,\r
1665                                                                                   operationObject);\r
1666         self.apis[apiProperty][operationId].help = operationGroup[operationId].help = _.bind(operationObject.help,\r
1667                                                                                              operationObject);\r
1668         self.apis[apiProperty][operationId].asCurl = operationGroup[operationId].asCurl = _.bind(operationObject.asCurl,\r
1669                                                                                                  operationObject);\r
1670 \r
1671         operationGroup.apis[operationId] = operationGroup.operations[operationId] = operationObject;\r
1672 \r
1673         // legacy UI feature\r
1674         var api = _.find(self.apisArray, function (api) {\r
1675           return api.tag === tag;\r
1676         });\r
1677 \r
1678         if (api) {\r
1679           api.operationsArray.push(operationObject);\r
1680         }\r
1681       });\r
1682     });\r
1683   });\r
1684 \r
1685   // sort the apisArray according to the tags\r
1686   var sortedApis = [];\r
1687   _.forEach(Object.keys(definedTags), function (tag) {\r
1688     var _apiToAdd;\r
1689     var pos;\r
1690     for(pos in self.apisArray) {\r
1691       var _api = self.apisArray[pos];\r
1692       if(_api && tag === _api.name) {\r
1693         sortedApis.push(_api);\r
1694         self.apisArray[pos] = null;\r
1695       }\r
1696     }\r
1697   });\r
1698   // add anything left\r
1699   _.forEach(self.apisArray, function (api) {\r
1700     if(api) {\r
1701       sortedApis.push(api);\r
1702     }\r
1703   });\r
1704   self.apisArray = sortedApis;\r
1705 \r
1706   _.forEach(response.definitions, function (definitionObj, definition) {\r
1707     definitionObj['id'] = definition.toLowerCase();\r
1708     definitionObj['name'] = definition;\r
1709     self.modelsArray.push(definitionObj);\r
1710   });\r
1711 \r
1712   this.isBuilt = true;\r
1713 \r
1714   if (this.usePromise) {\r
1715     this.isValid = true;\r
1716     this.isBuilt = true;\r
1717     this.deferredClient.resolve(this);\r
1718 \r
1719     return this.deferredClient.promise;\r
1720   }\r
1721 \r
1722   if (this.success) {\r
1723     this.success();\r
1724   }\r
1725 \r
1726   return this;\r
1727 };\r
1728 \r
1729 SwaggerClient.prototype.makeUniqueOperationId = function(operationId, api) {\r
1730   var count = 0;\r
1731   var name = operationId;\r
1732 \r
1733   // make unique across this operation group\r
1734   while(true) {\r
1735     var matched = false;\r
1736     _.forEach(api.operations, function (operation) {\r
1737       if(operation.nickname === name) {\r
1738         matched = true;\r
1739       }\r
1740     });\r
1741     if(!matched) {\r
1742       return name;\r
1743     }\r
1744     name = operationId + '_' + count;\r
1745     count ++;\r
1746   }\r
1747 \r
1748   return operationId;\r
1749 };\r
1750 \r
1751 SwaggerClient.prototype.parseUri = function (uri) {\r
1752   var urlParseRE = /^(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/;\r
1753   var parts = urlParseRE.exec(uri);\r
1754 \r
1755   return {\r
1756     scheme: parts[4] ? parts[4].replace(':','') : undefined,\r
1757     host: parts[11],\r
1758     port: parts[12],\r
1759     path: parts[15]\r
1760   };\r
1761 };\r
1762 \r
1763 SwaggerClient.prototype.help = function (dontPrint) {\r
1764   var output = '';\r
1765 \r
1766   if (this instanceof SwaggerClient) {\r
1767     _.forEach(this.apis, function (api, name) {\r
1768       if (_.isPlainObject(api)) {\r
1769         output += 'operations for the \'' + name + '\' tag\n';\r
1770 \r
1771         _.forEach(api.operations, function (operation, name) {\r
1772           output += '  * ' + name + ': ' + operation.summary + '\n';\r
1773         });\r
1774       }\r
1775     });\r
1776   } else if (this instanceof OperationGroup || _.isPlainObject(this)) {\r
1777     output += 'operations for the \'' + this.label + '\' tag\n';\r
1778 \r
1779     _.forEach(this.apis, function (operation, name) {\r
1780       output += '  * ' + name + ': ' + operation.summary + '\n';\r
1781     });\r
1782   }\r
1783 \r
1784   if (dontPrint) {\r
1785     return output;\r
1786   } else {\r
1787     helpers.log(output);\r
1788 \r
1789     return output;\r
1790   }\r
1791 };\r
1792 \r
1793 SwaggerClient.prototype.tagFromLabel = function (label) {\r
1794   return label;\r
1795 };\r
1796 \r
1797 SwaggerClient.prototype.idFromOp = function (path, httpMethod, op) {\r
1798   if(!op || !op.operationId) {\r
1799     op = op || {};\r
1800     op.operationId = httpMethod + '_' + path;\r
1801   }\r
1802   var opId = op.operationId.replace(/[\s!@#$%^&*()_+=\[{\]};:<>|.\/?,\\'""-]/g, '_') || (path.substring(1) + '_' + httpMethod);\r
1803 \r
1804   opId = opId.replace(/((_){2,})/g, '_');\r
1805   opId = opId.replace(/^(_)*/g, '');\r
1806   opId = opId.replace(/([_])*$/g, '');\r
1807 \r
1808   return opId;\r
1809 };\r
1810 \r
1811 SwaggerClient.prototype.setHost = function (host) {\r
1812   this.host = host;\r
1813 \r
1814   if(this.apis) {\r
1815     _.forEach(this.apis, function(api) {\r
1816       if(api.operations) {\r
1817         _.forEach(api.operations, function(operation) {\r
1818           operation.host = host;\r
1819         });\r
1820       }\r
1821     });\r
1822   }\r
1823 };\r
1824 \r
1825 SwaggerClient.prototype.setBasePath = function (basePath) {\r
1826   this.basePath = basePath;\r
1827 \r
1828   if(this.apis) {\r
1829     _.forEach(this.apis, function(api) {\r
1830       if(api.operations) {\r
1831         _.forEach(api.operations, function(operation) {\r
1832           operation.basePath = basePath;\r
1833         });\r
1834       }\r
1835     });\r
1836   }\r
1837 };\r
1838 \r
1839 SwaggerClient.prototype.setSchemes = function (schemes) {\r
1840   this.schemes = schemes;\r
1841 \r
1842   if(schemes && schemes.length > 0) {\r
1843     if(this.apis) {\r
1844       _.forEach(this.apis, function (api) {\r
1845         if (api.operations) {\r
1846           _.forEach(api.operations, function (operation) {\r
1847             operation.scheme = schemes[0];\r
1848           });\r
1849         }\r
1850       });\r
1851     }\r
1852   }\r
1853 };\r
1854 \r
1855 \r
1856 SwaggerClient.prototype.fail = function (message) {\r
1857   if (this.usePromise) {\r
1858     this.deferredClient.reject(message);\r
1859     return this.deferredClient.promise;\r
1860   } else {\r
1861     if (this.failure) {\r
1862       this.failure(message);\r
1863     }\r
1864     else {\r
1865       this.failure(message);\r
1866     }\r
1867   }\r
1868 };\r
1869 \r
1870 },{"./auth":2,"./helpers":4,"./http":5,"./resolver":6,"./spec-converter":8,"./types/model":9,"./types/operation":10,"./types/operationGroup":11,"lodash-compat/array/indexOf":51,"lodash-compat/collection/find":55,"lodash-compat/collection/forEach":56,"lodash-compat/function/bind":60,"lodash-compat/lang/cloneDeep":140,"lodash-compat/lang/isArray":142,"lodash-compat/lang/isFunction":144,"lodash-compat/lang/isObject":146,"lodash-compat/lang/isPlainObject":147,"lodash-compat/lang/isUndefined":150,"q":159}],4:[function(require,module,exports){\r
1871 (function (process){\r
1872 'use strict';\r
1873 \r
1874 var _ = {\r
1875   isPlainObject: require('lodash-compat/lang/isPlainObject'),\r
1876   indexOf: require('lodash-compat/array/indexOf')\r
1877 };\r
1878 \r
1879 module.exports.__bind = function (fn, me) {\r
1880   return function(){\r
1881     return fn.apply(me, arguments);\r
1882   };\r
1883 };\r
1884 \r
1885 var log = module.exports.log = function() {\r
1886   // Only log if available and we're not testing\r
1887   if (console && process.env.NODE_ENV !== 'test') {\r
1888     console.log(Array.prototype.slice.call(arguments)[0]);\r
1889   }\r
1890 };\r
1891 \r
1892 module.exports.fail = function (message) {\r
1893   log(message);\r
1894 };\r
1895 \r
1896 var optionHtml = module.exports.optionHtml = function (label, value) {\r
1897   return '<tr><td class="optionName">' + label + ':</td><td>' + value + '</td></tr>';\r
1898 };\r
1899 \r
1900 var resolveSchema = module.exports.resolveSchema = function (schema) {\r
1901   if (_.isPlainObject(schema.schema)) {\r
1902     schema = resolveSchema(schema.schema);\r
1903   }\r
1904 \r
1905   return schema;\r
1906 };\r
1907 \r
1908 var simpleRef = module.exports.simpleRef = function (name) {\r
1909   if (typeof name === 'undefined') {\r
1910     return null;\r
1911   }\r
1912 \r
1913   if (name.indexOf('#/definitions/') === 0) {\r
1914     return name.substring('#/definitions/'.length);\r
1915   } else {\r
1916     return name;\r
1917   }\r
1918 };\r
1919 \r
1920 \r
1921 }).call(this,require('_process'))\r
1922 //# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9oZWxwZXJzLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgXyA9IHtcbiAgaXNQbGFpbk9iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzUGxhaW5PYmplY3QnKSxcbiAgaW5kZXhPZjogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9hcnJheS9pbmRleE9mJylcbn07XG5cbm1vZHVsZS5leHBvcnRzLl9fYmluZCA9IGZ1bmN0aW9uIChmbiwgbWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCl7XG4gICAgcmV0dXJuIGZuLmFwcGx5KG1lLCBhcmd1bWVudHMpO1xuICB9O1xufTtcblxudmFyIGxvZyA9IG1vZHVsZS5leHBvcnRzLmxvZyA9IGZ1bmN0aW9uKCkge1xuICAvLyBPbmx5IGxvZyBpZiBhdmFpbGFibGUgYW5kIHdlJ3JlIG5vdCB0ZXN0aW5nXG4gIGlmIChjb25zb2xlICYmIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAndGVzdCcpIHtcbiAgICBjb25zb2xlLmxvZyhBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpWzBdKTtcbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMuZmFpbCA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gIGxvZyhtZXNzYWdlKTtcbn07XG5cbnZhciBvcHRpb25IdG1sID0gbW9kdWxlLmV4cG9ydHMub3B0aW9uSHRtbCA9IGZ1bmN0aW9uIChsYWJlbCwgdmFsdWUpIHtcbiAgcmV0dXJuICc8dHI+PHRkIGNsYXNzPVwib3B0aW9uTmFtZVwiPicgKyBsYWJlbCArICc6PC90ZD48dGQ+JyArIHZhbHVlICsgJzwvdGQ+PC90cj4nO1xufTtcblxudmFyIHJlc29sdmVTY2hlbWEgPSBtb2R1bGUuZXhwb3J0cy5yZXNvbHZlU2NoZW1hID0gZnVuY3Rpb24gKHNjaGVtYSkge1xuICBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5zY2hlbWEpKSB7XG4gICAgc2NoZW1hID0gcmVzb2x2ZVNjaGVtYShzY2hlbWEuc2NoZW1hKTtcbiAgfVxuXG4gIHJldHVybiBzY2hlbWE7XG59O1xuXG52YXIgc2ltcGxlUmVmID0gbW9kdWxlLmV4cG9ydHMuc2ltcGxlUmVmID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgaWYgKHR5cGVvZiBuYW1lID09PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKG5hbWUuaW5kZXhPZignIy9kZWZpbml0aW9ucy8nKSA9PT0gMCkge1xuICAgIHJldHVybiBuYW1lLnN1YnN0cmluZygnIy9kZWZpbml0aW9ucy8nLmxlbmd0aCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG5hbWU7XG4gIH1cbn07XG5cbiJdfQ==\r
1923 },{"_process":13,"lodash-compat/array/indexOf":51,"lodash-compat/lang/isPlainObject":147}],5:[function(require,module,exports){\r
1924 'use strict';\r
1925 \r
1926 var helpers = require('./helpers');\r
1927 var request = require('superagent');\r
1928 var jsyaml = require('js-yaml');\r
1929 var _ = {\r
1930   isObject: require('lodash-compat/lang/isObject')\r
1931 };\r
1932 \r
1933 /*\r
1934  * JQueryHttpClient is a light-weight, node or browser HTTP client\r
1935  */\r
1936 var JQueryHttpClient = function () {\r
1937   this.type = 'JQueryHttpClient';\r
1938 };\r
1939 \r
1940 /*\r
1941  * SuperagentHttpClient is a light-weight, node or browser HTTP client\r
1942  */\r
1943 var SuperagentHttpClient = function () {\r
1944   this.type = 'SuperagentHttpClient';\r
1945 };\r
1946 \r
1947 /**\r
1948  * SwaggerHttp is a wrapper for executing requests\r
1949  */\r
1950 var SwaggerHttp = module.exports = function () {};\r
1951 \r
1952 SwaggerHttp.prototype.execute = function (obj, opts) {\r
1953   var client;\r
1954 \r
1955   if(opts && opts.client) {\r
1956     client = opts.client;\r
1957   }\r
1958   else {\r
1959     client = new SuperagentHttpClient(opts);\r
1960   }\r
1961   client.opts = opts || {};\r
1962 \r
1963   // legacy support\r
1964   var hasJQuery = false;\r
1965   if(typeof window !== 'undefined') {\r
1966     if(typeof window.jQuery !== 'undefined') {\r
1967       hasJQuery = true;\r
1968     }\r
1969   }\r
1970   // OPTIONS support\r
1971   if(obj.method.toLowerCase() === 'options' && client.type === 'SuperagentHttpClient') {\r
1972     log('forcing jQuery as OPTIONS are not supported by SuperAgent');\r
1973     obj.useJQuery = true;\r
1974   }\r
1975   if(this.isInternetExplorer() && (obj.useJQuery === false || !hasJQuery )) {\r
1976     throw new Error('Unsupported configuration! JQuery is required but not available');\r
1977   }\r
1978   if ((obj && obj.useJQuery === true) || this.isInternetExplorer() && hasJQuery) {\r
1979     client = new JQueryHttpClient(opts);\r
1980   }\r
1981 \r
1982   var success = obj.on.response;\r
1983 \r
1984   var requestInterceptor = function(data) {\r
1985     if(opts && opts.requestInterceptor) {\r
1986       data = opts.requestInterceptor.apply(data);\r
1987     }\r
1988     return data;\r
1989   };\r
1990 \r
1991   var responseInterceptor = function(data) {\r
1992     if(opts && opts.responseInterceptor) {\r
1993       data = opts.responseInterceptor.apply(data);\r
1994     }\r
1995     return success(data);\r
1996   };\r
1997 \r
1998   obj.on.response = function(data) {\r
1999     responseInterceptor(data);\r
2000   };\r
2001 \r
2002   if (_.isObject(obj) && _.isObject(obj.body)) {\r
2003     // special processing for file uploads via jquery\r
2004     if (obj.body.type && obj.body.type === 'formData'){\r
2005       obj.contentType = false;\r
2006       obj.processData = false;\r
2007 \r
2008       delete obj.headers['Content-Type'];\r
2009     } else {\r
2010       obj.body = JSON.stringify(obj.body);\r
2011     }\r
2012   }\r
2013 \r
2014   obj = requestInterceptor(obj) || obj;\r
2015   if (obj.beforeSend) {\r
2016     obj.beforeSend(function(_obj) {\r
2017       client.execute(_obj || obj);\r
2018     });\r
2019   } else {\r
2020     client.execute(obj);\r
2021   }\r
2022 \r
2023   return (obj.deferred) ? obj.deferred.promise : obj;\r
2024 };\r
2025 \r
2026 SwaggerHttp.prototype.isInternetExplorer = function () {\r
2027   var detectedIE = false;\r
2028 \r
2029   if (typeof navigator !== 'undefined' && navigator.userAgent) {\r
2030     var nav = navigator.userAgent.toLowerCase();\r
2031 \r
2032     if (nav.indexOf('msie') !== -1) {\r
2033       var version = parseInt(nav.split('msie')[1]);\r
2034 \r
2035       if (version <= 8) {\r
2036         detectedIE = true;\r
2037       }\r
2038     }\r
2039   }\r
2040 \r
2041   return detectedIE;\r
2042 };\r
2043 \r
2044 JQueryHttpClient.prototype.execute = function (obj) {\r
2045   var jq = this.jQuery || (typeof window !== 'undefined' && window.jQuery);\r
2046   var cb = obj.on;\r
2047   var request = obj;\r
2048 \r
2049   if(typeof jq === 'undefined' || jq === false) {\r
2050     throw new Error('Unsupported configuration! JQuery is required but not available');\r
2051   }\r
2052 \r
2053   obj.type = obj.method;\r
2054   obj.cache = false;\r
2055   obj.data = obj.body;\r
2056   delete obj.useJQuery;\r
2057   delete obj.body;\r
2058 \r
2059   obj.complete = function (response) {\r
2060     var headers = {};\r
2061     var headerArray = response.getAllResponseHeaders().split('\n');\r
2062 \r
2063     for (var i = 0; i < headerArray.length; i++) {\r
2064       var toSplit = headerArray[i].trim();\r
2065 \r
2066       if (toSplit.length === 0) {\r
2067         continue;\r
2068       }\r
2069 \r
2070       var separator = toSplit.indexOf(':');\r
2071 \r
2072       if (separator === -1) {\r
2073         // Name but no value in the header\r
2074         headers[toSplit] = null;\r
2075 \r
2076         continue;\r
2077       }\r
2078 \r
2079       var name = toSplit.substring(0, separator).trim();\r
2080       var value = toSplit.substring(separator + 1).trim();\r
2081 \r
2082       headers[name] = value;\r
2083     }\r
2084 \r
2085     var out = {\r
2086       url: request.url,\r
2087       method: request.method,\r
2088       status: response.status,\r
2089       statusText: response.statusText,\r
2090       data: response.responseText,\r
2091       headers: headers\r
2092     };\r
2093 \r
2094     try {\r
2095       var possibleObj =  response.responseJSON || jsyaml.safeLoad(response.responseText);\r
2096       out.obj = (typeof possibleObj === 'string') ? {} : possibleObj;\r
2097     } catch (ex) {\r
2098       // do not set out.obj\r
2099       helpers.log('unable to parse JSON/YAML content');\r
2100     }\r
2101 \r
2102     // I can throw, or parse null?\r
2103     out.obj = out.obj || null;\r
2104 \r
2105     if (response.status >= 200 && response.status < 300) {\r
2106       cb.response(out);\r
2107     } else if (response.status === 0 || (response.status >= 400 && response.status < 599)) {\r
2108       cb.error(out);\r
2109     } else {\r
2110       return cb.response(out);\r
2111     }\r
2112   };\r
2113 \r
2114   jq.support.cors = true;\r
2115 \r
2116   return jq.ajax(obj);\r
2117 };\r
2118 \r
2119 SuperagentHttpClient.prototype.execute = function (obj) {\r
2120   var method = obj.method.toLowerCase();\r
2121 \r
2122   if (method === 'delete') {\r
2123     method = 'del';\r
2124   }\r
2125   var headers = obj.headers || {};\r
2126   var r = request[method](obj.url);\r
2127   var name;\r
2128   for (name in headers) {\r
2129     r.set(name, headers[name]);\r
2130   }\r
2131 \r
2132   if (obj.enableCookies) {\r
2133     r.withCredentials();\r
2134   }\r
2135 \r
2136   if (obj.body) {\r
2137     r.send(obj.body);\r
2138   }\r
2139 \r
2140   if(typeof r.buffer === 'function') {\r
2141     r.buffer(); // force superagent to populate res.text with the raw response data\r
2142   }\r
2143 \r
2144   r.end(function (err, res) {\r
2145     res = res || {\r
2146       status: 0,\r
2147       headers: {error: 'no response from server'}\r
2148     };\r
2149     var response = {\r
2150       url: obj.url,\r
2151       method: obj.method,\r
2152       headers: res.headers\r
2153     };\r
2154     var cb;\r
2155 \r
2156     if (!err && res.error) {\r
2157       err = res.error;\r
2158     }\r
2159 \r
2160     if (err && obj.on && obj.on.error) {\r
2161       response.errObj = err;\r
2162       response.status = res ? res.status : 500;\r
2163       response.statusText = res ? res.text : err.message;\r
2164       if(res.headers && res.headers['content-type']) {\r
2165         if(res.headers['content-type'].indexOf('application/json') >= 0) {\r
2166           try {\r
2167             response.obj = JSON.parse(response.statusText);\r
2168           }\r
2169           catch (e) {\r
2170             response.obj = null;\r
2171           }\r
2172         }\r
2173       }\r
2174       cb = obj.on.error;\r
2175     } else if (res && obj.on && obj.on.response) {\r
2176       var possibleObj;\r
2177 \r
2178       // Already parsed by by superagent?\r
2179       if(res.body && Object.keys(res.body).length > 0) {\r
2180         possibleObj = res.body;\r
2181       } else {\r
2182           try {\r
2183             possibleObj = jsyaml.safeLoad(res.text);\r
2184             // can parse into a string... which we don't need running around in the system\r
2185             possibleObj = (typeof possibleObj === 'string') ? null : possibleObj;\r
2186           } catch(e) {\r
2187             helpers.log('cannot parse JSON/YAML content');\r
2188           }\r
2189       }\r
2190 \r
2191       // null means we can't parse into object\r
2192       response.obj = (typeof possibleObj === 'object') ? possibleObj : null;\r
2193 \r
2194       response.status = res.status;\r
2195       response.statusText = res.text;\r
2196       cb = obj.on.response;\r
2197     }\r
2198     response.data = response.statusText;\r
2199 \r
2200     if (cb) {\r
2201       cb(response);\r
2202     }\r
2203   });\r
2204 };\r
2205 \r
2206 },{"./helpers":4,"js-yaml":21,"lodash-compat/lang/isObject":146,"superagent":161}],6:[function(require,module,exports){\r
2207 'use strict';\r
2208 \r
2209 var SwaggerHttp = require('./http');\r
2210 var _ = {\r
2211   isObject: require('lodash-compat/lang/isObject'),\r
2212   cloneDeep: require('lodash-compat/lang/cloneDeep'),\r
2213   isArray: require('lodash-compat/lang/isArray')\r
2214 };\r
2215 \r
2216 \r
2217 /**\r
2218  * Resolves a spec's remote references\r
2219  */\r
2220 var Resolver = module.exports = function () {\r
2221   this.failedUrls = [];\r
2222 };\r
2223 \r
2224 Resolver.prototype.processAllOf = function(root, name, definition, resolutionTable, unresolvedRefs, spec) {\r
2225   var i, location, property;\r
2226 \r
2227   definition['x-resolved-from'] = [ '#/definitions/' + name ];\r
2228   var allOf = definition.allOf;\r
2229   // the refs go first\r
2230   allOf.sort(function(a, b) {\r
2231     if(a.$ref && b.$ref) { return 0; }\r
2232     else if(a.$ref) { return -1; }\r
2233     else { return 1; }\r
2234   });\r
2235   for (i = 0; i < allOf.length; i++) {\r
2236     property = allOf[i];\r
2237     location = '/definitions/' + name + '/allOf';\r
2238     this.resolveInline(root, spec, property, resolutionTable, unresolvedRefs, location);\r
2239   }\r
2240 };\r
2241 \r
2242 Resolver.prototype.resolve = function (spec, arg1, arg2, arg3) {\r
2243   this.spec = spec;\r
2244   var root = arg1, callback = arg2, scope = arg3, opts = {}, location, i;\r
2245   if(typeof arg1 === 'function') {\r
2246     root = null;\r
2247     callback = arg1;\r
2248     scope = arg2;\r
2249   }\r
2250   var _root = root;\r
2251   this.scope = (scope || this);\r
2252   this.iteration = this.iteration || 0;\r
2253 \r
2254   if(this.scope.options && this.scope.options.requestInterceptor){\r
2255     opts.requestInterceptor = this.scope.options.requestInterceptor;\r
2256   }\r
2257 \r
2258   if(this.scope.options && this.scope.options.responseInterceptor){\r
2259     opts.responseInterceptor = this.scope.options.responseInterceptor;\r
2260   }\r
2261 \r
2262   var name, path, property, propertyName;\r
2263   var processedCalls = 0, resolvedRefs = {}, unresolvedRefs = {};\r
2264   var resolutionTable = []; // store objects for dereferencing\r
2265 \r
2266   spec.definitions = spec.definitions || {};\r
2267   // definitions\r
2268   for (name in spec.definitions) {\r
2269     var definition = spec.definitions[name];\r
2270     if(definition['$ref']) {\r
2271       this.resolveInline(root, spec, definition, resolutionTable, unresolvedRefs, definition);\r
2272     }\r
2273     else {\r
2274       for (propertyName in definition.properties) {\r
2275         property = definition.properties[propertyName];\r
2276         if (_.isArray(property.allOf)) {\r
2277           this.processAllOf(root, name, property, resolutionTable, unresolvedRefs, spec);\r
2278         }\r
2279         else {\r
2280           this.resolveTo(root, property, resolutionTable, '/definitions');\r
2281         }\r
2282       }\r
2283 \r
2284       if (definition.allOf) {\r
2285         this.processAllOf(root, name, definition, resolutionTable, unresolvedRefs, spec);\r
2286       }\r
2287     }\r
2288   }\r
2289 \r
2290   // shared parameters\r
2291   spec.parameters = spec.parameters || {};\r
2292   for(name in spec.parameters) {\r
2293     var parameter = spec.parameters[name];\r
2294     if (parameter.in === 'body' && parameter.schema) {\r
2295       if(_.isArray(parameter.schema.allOf)) {\r
2296         // move to a definition\r
2297         var modelName = 'inline_model';\r
2298         var name = modelName;\r
2299         var done = false; var counter = 0;\r
2300         while(!done) {\r
2301           if(typeof spec.definitions[name] === 'undefined') {\r
2302             done = true;\r
2303             break;\r
2304           }\r
2305           name = modelName + '_' + counter;\r
2306           counter ++;\r
2307         }\r
2308         spec.definitions[name] = { allOf: parameter.schema.allOf };\r
2309         delete parameter.schema.allOf;\r
2310         parameter.schema.$ref = '#/definitions/' + name;\r
2311         this.processAllOf(root, name, spec.definitions[name], resolutionTable, unresolvedRefs, spec);\r
2312       }\r
2313       else {\r
2314         this.resolveTo(root, parameter.schema, resolutionTable, location);\r
2315       }\r
2316     }\r
2317 \r
2318     if (parameter.$ref) {\r
2319       // parameter reference\r
2320       this.resolveInline(root, spec, parameter, resolutionTable, unresolvedRefs, parameter.$ref);\r
2321     }\r
2322   }\r
2323 \r
2324   // operations\r
2325   for (name in spec.paths) {\r
2326     var method, operation, responseCode;\r
2327     path = spec.paths[name];\r
2328 \r
2329     for (method in path) {\r
2330       // operation reference\r
2331       if(method === '$ref') {\r
2332         // location = path[method];\r
2333         location = '/paths' + name;\r
2334         this.resolveInline(root, spec, path, resolutionTable, unresolvedRefs, location);\r
2335       }\r
2336       else {\r
2337         operation = path[method];\r
2338         var sharedParameters = path.parameters || [];\r
2339         var parameters = operation.parameters || [];\r
2340 \r
2341         for (i in sharedParameters) {\r
2342           var parameter = sharedParameters[i];\r
2343           parameters.unshift(parameter);\r
2344         }\r
2345         if(method !== 'parameters' && _.isObject(operation)) {\r
2346           operation.parameters = operation.parameters || parameters;\r
2347         }\r
2348 \r
2349         for (i in parameters) {\r
2350           var parameter = parameters[i];\r
2351           location = '/paths' + name + '/' + method + '/parameters';\r
2352 \r
2353           if (parameter.in === 'body' && parameter.schema) {\r
2354             if(_.isArray(parameter.schema.allOf)) {\r
2355               // move to a definition\r
2356               var modelName = 'inline_model';\r
2357               var name = modelName;\r
2358               var done = false; var counter = 0;\r
2359               while(!done) {\r
2360                 if(typeof spec.definitions[name] === 'undefined') {\r
2361                   done = true;\r
2362                   break;\r
2363                 }\r
2364                 name = modelName + '_' + counter;\r
2365                 counter ++;\r
2366               }\r
2367               spec.definitions[name] = { allOf: parameter.schema.allOf };\r
2368               delete parameter.schema.allOf;\r
2369               parameter.schema.$ref = '#/definitions/' + name;\r
2370               this.processAllOf(root, name, spec.definitions[name], resolutionTable, unresolvedRefs, spec);\r
2371             }\r
2372             else {\r
2373               this.resolveTo(root, parameter.schema, resolutionTable, location);\r
2374             }\r
2375           }\r
2376 \r
2377           if (parameter.$ref) {\r
2378             // parameter reference\r
2379             this.resolveInline(root, spec, parameter, resolutionTable, unresolvedRefs, parameter.$ref);\r
2380           }\r
2381         }\r
2382 \r
2383         for (responseCode in operation.responses) {\r
2384           var response = operation.responses[responseCode];\r
2385           location = '/paths' + name + '/' + method + '/responses/' + responseCode;\r
2386 \r
2387           if(_.isObject(response)) {\r
2388             if(response.$ref) {\r
2389               // response reference\r
2390               this.resolveInline(root, spec, response, resolutionTable, unresolvedRefs, location);\r
2391             }\r
2392             if (response.schema) {\r
2393               var responseObj = response;\r
2394               if(_.isArray(responseObj.schema.allOf)) {\r
2395                 // move to a definition\r
2396                 var modelName = 'inline_model';\r
2397                 var name = modelName;\r
2398                 var done = false; var counter = 0;\r
2399                 while(!done) {\r
2400                   if(typeof spec.definitions[name] === 'undefined') {\r
2401                     done = true;\r
2402                     break;\r
2403                   }\r
2404                   name = modelName + '_' + counter;\r
2405                   counter ++;\r
2406                 }\r
2407                 spec.definitions[name] = { allOf: responseObj.schema.allOf };\r
2408                 delete responseObj.schema.allOf;\r
2409                 delete responseObj.schema.type;\r
2410                 responseObj.schema.$ref = '#/definitions/' + name;\r
2411                 this.processAllOf(root, name, spec.definitions[name], resolutionTable, unresolvedRefs, spec);\r
2412               }\r
2413               else if('array' === responseObj.schema.type) {\r
2414                 if(responseObj.schema.items && responseObj.schema.items.$ref) {\r
2415                   // response reference\r
2416                   this.resolveInline(root, spec, responseObj.schema.items, resolutionTable, unresolvedRefs, location);\r
2417                 }\r
2418               }\r
2419               else {\r
2420                 this.resolveTo(root, response.schema, resolutionTable, location);\r
2421               }\r
2422             }\r
2423           }\r
2424         }\r
2425       }\r
2426     }\r
2427     // clear them out to avoid multiple resolutions\r
2428     path.parameters = [];\r
2429   }\r
2430 \r
2431   var expectedCalls = 0, toResolve = [];\r
2432   // if the root is same as obj[i].root we can resolve locally\r
2433   var all = resolutionTable;\r
2434 \r
2435   var parts;\r
2436   for(i = 0; i < all.length; i++) {\r
2437     var a = all[i];\r
2438     if(root === a.root) {\r
2439       if(a.resolveAs === 'ref') {\r
2440         // resolve any path walking\r
2441         var joined = ((a.root || '') + '/' + a.key).split('/');\r
2442         var normalized = [];\r
2443         var url = '';\r
2444         var k;\r
2445 \r
2446         if(a.key.indexOf('../') >= 0) {\r
2447           for(var j = 0; j < joined.length; j++) {\r
2448             if(joined[j] === '..') {\r
2449               normalized = normalized.slice(0, normalized.length-1);\r
2450             }\r
2451             else {\r
2452               normalized.push(joined[j]);\r
2453             }\r
2454           }\r
2455           for(k = 0; k < normalized.length; k ++) {\r
2456             if(k > 0) {\r
2457               url += '/';\r
2458             }\r
2459             url += normalized[k];\r
2460           }\r
2461           // we now have to remote resolve this because the path has changed\r
2462           a.root = url;\r
2463           toResolve.push(a);\r
2464         }\r
2465         else {\r
2466           parts = a.key.split('#');\r
2467           if(parts.length === 2) {\r
2468             if(parts[0].indexOf('http://') === 0 || parts[0].indexOf('https://') === 0) {\r
2469               a.root = parts[0];\r
2470             }\r
2471             location = parts[1].split('/');\r
2472             var r;\r
2473             var s = spec;\r
2474             for(k = 0; k < location.length; k++) {\r
2475               var part = location[k];\r
2476               if(part !== '') {\r
2477                 s = s[part];\r
2478                 if(typeof s !== 'undefined') {\r
2479                   r = s;\r
2480                 }\r
2481                 else {\r
2482                   r = null;\r
2483                   break;\r
2484                 }\r
2485               }\r
2486             }\r
2487             if(r === null) {\r
2488               // must resolve this too\r
2489               toResolve.push(a);\r
2490             }\r
2491           }\r
2492         }\r
2493       }\r
2494       else {\r
2495         if (a.resolveAs === 'inline') {\r
2496           if(a.key && a.key.indexOf('#') === -1 && a.key.charAt(0) !== '/') {\r
2497             // handle relative schema\r
2498             parts = a.root.split('/');\r
2499             location = '';\r
2500             for(i = 0; i < parts.length - 1; i++) {\r
2501               location += parts[i] + '/';\r
2502             }\r
2503             location += a.key;\r
2504             a.root = location;\r
2505             a.location = '';\r
2506           }\r
2507           toResolve.push(a);\r
2508         }\r
2509       }\r
2510     }\r
2511     else {\r
2512       toResolve.push(a);\r
2513     }\r
2514   }\r
2515   expectedCalls = toResolve.length;\r
2516 \r
2517   // resolve anything that is local\r
2518   for(var ii = 0; ii < toResolve.length; ii++) {\r
2519     (function(item, spec, self) {\r
2520       // NOTE: this used to be item.root === null, but I (@ponelat) have added a guard against .split, which means item.root can be ''\r
2521       if(!item.root || item.root === root) {\r
2522         // local resolve\r
2523         self.resolveItem(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, item);\r
2524         processedCalls += 1;\r
2525 \r
2526         if(processedCalls === expectedCalls) {\r
2527           self.finish(spec, root, resolutionTable, resolvedRefs, unresolvedRefs, callback, true);\r
2528         }\r
2529       }\r
2530       else if(self.failedUrls.indexOf(item.root) === -1) {\r
2531         var obj = {\r
2532           useJQuery: false,  // TODO\r
2533           url: item.root,\r
2534           method: 'get',\r
2535           headers: {\r
2536             accept: self.scope.swaggerRequestHeaders || 'application/json'\r
2537           },\r
2538           on: {\r
2539             error: function (error) {\r
2540               processedCalls += 1;\r
2541               console.log('failed url: ' + obj.url);\r
2542               self.failedUrls.push(obj.url);\r
2543               unresolvedRefs[item.key] = {\r
2544                 root: item.root,\r
2545                 location: item.location\r
2546               };\r
2547 \r
2548               if (processedCalls === expectedCalls) {\r
2549                 self.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback);\r
2550               }\r
2551             },  // jshint ignore:line\r
2552             response: function (response) {\r
2553               var swagger = response.obj;\r
2554               self.resolveItem(swagger, item.root, resolutionTable, resolvedRefs, unresolvedRefs, item);\r
2555               processedCalls += 1;\r
2556 \r
2557               if (processedCalls === expectedCalls) {\r
2558                 self.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback);\r
2559               }\r
2560             }\r
2561           } // jshint ignore:line\r
2562         };\r
2563 \r
2564         if (scope && scope.clientAuthorizations) {\r
2565           scope.clientAuthorizations.apply(obj);\r
2566         }\r
2567 \r
2568         new SwaggerHttp().execute(obj, opts);\r
2569       }\r
2570       else {\r
2571         processedCalls += 1;\r
2572         unresolvedRefs[item.key] = {\r
2573           root: item.root,\r
2574           location: item.location\r
2575         };\r
2576         if (processedCalls === expectedCalls) {\r
2577           self.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback);\r
2578         }\r
2579       }\r
2580     }(toResolve[ii], spec, this));\r
2581   }\r
2582 \r
2583   if (Object.keys(toResolve).length === 0) {\r
2584     this.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback);\r
2585   }\r
2586 };\r
2587 \r
2588 Resolver.prototype.resolveItem = function(spec, root, resolutionTable, resolvedRefs, unresolvedRefs, item) {\r
2589   var path = item.location;\r
2590   var location = spec, parts = path.split('/');\r
2591   if(path !== '') {\r
2592     for (var j = 0; j < parts.length; j++) {\r
2593       var segment = parts[j];\r
2594       if (segment.indexOf('~1') !== -1) {\r
2595         segment = parts[j].replace(/~0/g, '~').replace(/~1/g, '/');\r
2596         if (segment.charAt(0) !== '/') {\r
2597           segment = '/' + segment;\r
2598         }\r
2599       }\r
2600       if (typeof location === 'undefined' || location === null) {\r
2601         break;\r
2602       }\r
2603       if (segment === '' && j === (parts.length - 1) && parts.length > 1) {\r
2604         location = null;\r
2605         break;\r
2606       }\r
2607       if (segment.length > 0) {\r
2608         location = location[segment];\r
2609       }\r
2610     }\r
2611   }\r
2612   var resolved = item.key;\r
2613   parts = item.key.split('/');\r
2614   var resolvedName = parts[parts.length-1];\r
2615 \r
2616   if(resolvedName.indexOf('#') >= 0) {\r
2617     resolvedName = resolvedName.split('#')[1];\r
2618   }\r
2619 \r
2620   if (location !== null && typeof location !== 'undefined') {\r
2621     resolvedRefs[resolved] = {\r
2622       name: resolvedName,\r
2623       obj: location,\r
2624       key: item.key,\r
2625       root: item.root\r
2626     };\r
2627   } else {\r
2628     unresolvedRefs[resolved] = {\r
2629       root: item.root,\r
2630       location: item.location\r
2631     };\r
2632   }\r
2633 };\r
2634 \r
2635 Resolver.prototype.finish = function (spec, root, resolutionTable, resolvedRefs, unresolvedRefs, callback, localResolve) {\r
2636   // walk resolution table and replace with resolved refs\r
2637   var ref;\r
2638   for (ref in resolutionTable) {\r
2639     var item = resolutionTable[ref];\r
2640 \r
2641     var key = item.key;\r
2642     var resolvedTo = resolvedRefs[key];\r
2643     if (resolvedTo) {\r
2644       spec.definitions = spec.definitions || {};\r
2645       if (item.resolveAs === 'ref') {\r
2646         if (localResolve !== true) {\r
2647           // don't retain root for local definitions\r
2648           for (key in resolvedTo.obj) {\r
2649             var abs = this.retainRoot(resolvedTo.obj[key], item.root);\r
2650           }\r
2651         }\r
2652         spec.definitions[resolvedTo.name] = resolvedTo.obj;\r
2653         item.obj.$ref = '#/definitions/' + resolvedTo.name;\r
2654       } else if (item.resolveAs === 'inline') {\r
2655         var targetObj = item.obj;\r
2656         targetObj['x-resolved-from'] = [ item.key ];\r
2657         delete targetObj.$ref;\r
2658 \r
2659         for (key in resolvedTo.obj) {\r
2660           var abs = resolvedTo.obj[key];\r
2661           \r
2662           if (localResolve !== true) {\r
2663             // don't retain root for local definitions\r
2664             abs = this.retainRoot(resolvedTo.obj[key], item.root);\r
2665           }\r
2666           targetObj[key] = abs;\r
2667         }\r
2668       }\r
2669     }\r
2670   }\r
2671   var existingUnresolved = this.countUnresolvedRefs(spec);\r
2672 \r
2673   if(existingUnresolved === 0 || this.iteration > 5) {\r
2674     this.resolveAllOf(spec.definitions);\r
2675     callback.call(this.scope, spec, unresolvedRefs);\r
2676   }\r
2677   else {\r
2678     this.iteration += 1;\r
2679     this.resolve(spec, root, callback, this.scope);\r
2680   }\r
2681 };\r
2682 \r
2683 Resolver.prototype.countUnresolvedRefs = function(spec) {\r
2684   var i;\r
2685   var refs = this.getRefs(spec);\r
2686   var keys = [];\r
2687   var unresolvedKeys = [];\r
2688   for(i in refs) {\r
2689     if(i.indexOf('#') === 0) {\r
2690       keys.push(i.substring(1));\r
2691     }\r
2692     else {\r
2693       unresolvedKeys.push(i);\r
2694     }\r
2695   }\r
2696 \r
2697   // verify possible keys\r
2698   for (i = 0; i < keys.length; i++) {\r
2699     var part = keys[i];\r
2700     var parts = part.split('/');\r
2701     var obj = spec;\r
2702 \r
2703     for (var k = 0; k < parts.length; k++) {\r
2704       var key = parts[k];\r
2705       if(key !== '') {\r
2706         obj = obj[key];\r
2707         if(typeof obj === 'undefined') {\r
2708           unresolvedKeys.push(part);\r
2709           break;\r
2710         }\r
2711       }\r
2712     }\r
2713   }\r
2714   return unresolvedKeys.length;\r
2715 };\r
2716 \r
2717 Resolver.prototype.getRefs = function(spec, obj) {\r
2718   obj = obj || spec;\r
2719   var output = {};\r
2720   for(var key in obj) {\r
2721     if (!obj.hasOwnProperty(key)) {\r
2722       continue;\r
2723     }\r
2724     var item = obj[key];\r
2725     if(key === '$ref' && typeof item === 'string') {\r
2726       output[item] = null;\r
2727     }\r
2728     else if(_.isObject(item)) {\r
2729       var o = this.getRefs(item);\r
2730       for(var k in o) {\r
2731         output[k] = null;\r
2732       }\r
2733     }\r
2734   }\r
2735   return output;\r
2736 };\r
2737 \r
2738 Resolver.prototype.retainRoot = function(obj, root) {\r
2739   // walk object and look for relative $refs\r
2740   for(var key in obj) {\r
2741     var item = obj[key];\r
2742     if(key === '$ref' && typeof item === 'string') {\r
2743       // stop and inspect\r
2744       if(item.indexOf('http://') !== 0 && item.indexOf('https://') !== 0) {\r
2745         // TODO: check if root ends in '/'.  If not, AND item has no protocol, make relative\r
2746         var appendHash = true;\r
2747         var oldRoot = root;\r
2748         if(root) {\r
2749           var lastChar = root.slice(-1);\r
2750           if(lastChar !== '/' && (item.indexOf('#') !== 0 && item.indexOf('http://') !== 0 && item.indexOf('https://'))) {\r
2751             console.log('working with ' + item);\r
2752             appendHash = false;\r
2753             var parts = root.split('\/');\r
2754             parts = parts.splice(0, parts.length - 1);\r
2755             root = '';\r
2756             for(var i = 0; i < parts.length; i++) {\r
2757               root += parts[i] + '/';\r
2758             }\r
2759           }\r
2760         }\r
2761         if(item.indexOf('#') !== 0 && appendHash) {\r
2762           item = '#' + item;\r
2763         }\r
2764 \r
2765         item = (root || '') + item;\r
2766         obj[key] = item;\r
2767       }\r
2768     }\r
2769     else if(_.isObject(item)) {\r
2770       this.retainRoot(item, root);\r
2771     }\r
2772   }\r
2773   return obj;\r
2774 };\r
2775 \r
2776 /**\r
2777  * immediately in-lines local refs, queues remote refs\r
2778  * for inline resolution\r
2779  */\r
2780 Resolver.prototype.resolveInline = function (root, spec, property, resolutionTable, unresolvedRefs, location) {\r
2781   var key = property.$ref, ref = property.$ref, i, p, p2, rs;\r
2782   var rootTrimmed = false;\r
2783 \r
2784   root = root || '' // Guard against .split. @fehguy, you'll need to check if this logic fits\r
2785   // More imporantly is how do we gracefully handle relative urls, when provided just a 'spec', not a 'url' ?\r
2786 \r
2787   if (ref) {\r
2788     if(ref.indexOf('../') === 0) {\r
2789       // reset root\r
2790       p = ref.split('../');\r
2791       p2 = root.split('/');\r
2792       ref = '';\r
2793       for(i = 0; i < p.length; i++) {\r
2794         if(p[i] === '') {\r
2795           p2 = p2.slice(0, p2.length-1);\r
2796         }\r
2797         else {\r
2798           ref += p[i];\r
2799         }\r
2800       }\r
2801       root = '';\r
2802       for(i = 0; i < p2.length - 1; i++) {\r
2803         if(i > 0) { root += '/'; }\r
2804         root += p2[i];\r
2805       }\r
2806       rootTrimmed = true;\r
2807     }\r
2808     if(ref.indexOf('#') >= 0) {\r
2809       if(ref.indexOf('/') === 0) {\r
2810         rs = ref.split('#');\r
2811         p  = root.split('//');\r
2812         p2 = p[1].split('/');\r
2813         root = p[0] + '//' + p2[0] + rs[0];\r
2814         location = rs[1];\r
2815       }\r
2816       else {\r
2817         rs = ref.split('#');\r
2818         if(rs[0] !== '') {\r
2819           p2 = root.split('/');\r
2820           p2 = p2.slice(0, p2.length - 1);\r
2821           if(!rootTrimmed) {\r
2822             root = '';\r
2823             for (var k = 0; k < p2.length; k++) {\r
2824               if(k > 0) { root += '/'; }\r
2825               root += p2[k];\r
2826             }\r
2827           }\r
2828           root += '/' + ref.split('#')[0];\r
2829         }\r
2830         location = rs[1];\r
2831       }\r
2832     }\r
2833     if (ref.indexOf('http') === 0) {\r
2834       if(ref.indexOf('#') >= 0) {\r
2835         root = ref.split('#')[0];\r
2836         location = ref.split('#')[1];\r
2837       }\r
2838       else {\r
2839         root = ref;\r
2840         location = '';\r
2841       }\r
2842       resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location});\r
2843     } else if (ref.indexOf('#') === 0) {\r
2844       location = ref.split('#')[1];\r
2845       resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location});\r
2846     } else if (ref.indexOf('/') === 0 && ref.indexOf('#') === -1) {\r
2847       location = ref;\r
2848       var matches = root.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);\r
2849       if(matches) {\r
2850         root = matches[0] + ref.substring(1);\r
2851         location = '';\r
2852       }\r
2853       resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location});\r
2854     }\r
2855     else {\r
2856       resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location});\r
2857     }\r
2858   }\r
2859   else if (property.type === 'array') {\r
2860     this.resolveTo(root, property.items, resolutionTable, location);\r
2861   }\r
2862 };\r
2863 \r
2864 Resolver.prototype.resolveTo = function (root, property, resolutionTable, location) {\r
2865   var sp, i;\r
2866   var ref = property.$ref;\r
2867   var lroot = root;\r
2868   if ((typeof ref !== 'undefined') && (ref !== null)) {\r
2869     if(ref.indexOf('#') >= 0) {\r
2870       var parts = ref.split('#');\r
2871 \r
2872       // #/definitions/foo\r
2873       // foo.json#/bar\r
2874       if(parts[0] && ref.indexOf('/') === 0) {\r
2875 \r
2876       }\r
2877       else if(parts[0] && parts[0].indexOf('http') === 0) {\r
2878         lroot = parts[0];\r
2879         ref = parts[1];\r
2880       }\r
2881       else if(parts[0] && parts[0].length > 0) {\r
2882         // relative file\r
2883         sp = root.split('/');\r
2884         lroot = '';\r
2885         for(i = 0; i < sp.length - 1; i++) {\r
2886           lroot += sp[i] + '/';\r
2887         }\r
2888         lroot += parts[0];\r
2889       }\r
2890       else {\r
2891 \r
2892       }\r
2893 \r
2894       location = parts[1];\r
2895     }\r
2896     else if (ref.indexOf('http://') === 0 || ref.indexOf('https://') === 0) {\r
2897       lroot = ref;\r
2898       location = '';\r
2899     }\r
2900     else {\r
2901       // relative file\r
2902       sp = root.split('/');\r
2903       lroot = '';\r
2904       for(i = 0; i < sp.length - 1; i++) {\r
2905         lroot += sp[i] + '/';\r
2906       }\r
2907       lroot += ref;\r
2908       location = '';\r
2909     }\r
2910     resolutionTable.push({\r
2911       obj: property, resolveAs: 'ref', root: lroot, key: ref, location: location\r
2912     });\r
2913   } else if (property.type === 'array') {\r
2914     var items = property.items;\r
2915     this.resolveTo(root, items, resolutionTable, location);\r
2916   } else {\r
2917     if(property && property.properties) {\r
2918       var name = this.uniqueName('inline_model');\r
2919       if (property.title) {\r
2920         name = this.uniqueName(property.title);\r
2921       }\r
2922       delete property.title;\r
2923       this.spec.definitions[name] = _.cloneDeep(property);\r
2924       property['$ref'] = '#/definitions/' + name;\r
2925       delete property.type;\r
2926       delete property.properties;\r
2927     }\r
2928   }\r
2929 };\r
2930 \r
2931 Resolver.prototype.uniqueName = function(base) {\r
2932   var name = base;\r
2933   var count = 0;\r
2934   while(true) {\r
2935     if(!_.isObject(this.spec.definitions[name])) {\r
2936       return name;\r
2937     }\r
2938     name = base + '_' + count;\r
2939     count++;\r
2940   }\r
2941 };\r
2942 \r
2943 Resolver.prototype.resolveAllOf = function(spec, obj, depth) {\r
2944   depth = depth || 0;\r
2945   obj = obj || spec;\r
2946   var name;\r
2947   for(var key in obj) {\r
2948     if (!obj.hasOwnProperty(key)) {\r
2949       continue;\r
2950     }\r
2951     var item = obj[key];\r
2952     if(item === null) {\r
2953       throw new TypeError('Swagger 2.0 does not support null types (' + obj + ').  See https://github.com/swagger-api/swagger-spec/issues/229.');\r
2954     }\r
2955     if(typeof item === 'object') {\r
2956       this.resolveAllOf(spec, item, depth + 1);\r
2957     }\r
2958     if(item && typeof item.allOf !== 'undefined') {\r
2959       var allOf = item.allOf;\r
2960       if(_.isArray(allOf)) {\r
2961         var output = _.cloneDeep(item);\r
2962         delete output.allOf;\r
2963 \r
2964         output['x-composed'] = true;\r
2965         if (typeof item['x-resolved-from'] !== 'undefined') {\r
2966           output['x-resolved-from'] = item['x-resolved-from'];\r
2967         }\r
2968 \r
2969         for(var i = 0; i < allOf.length; i++) {\r
2970           var component = allOf[i];\r
2971           var source = 'self';\r
2972           if(typeof component['x-resolved-from'] !== 'undefined') {\r
2973             source = component['x-resolved-from'][0];\r
2974           }\r
2975 \r
2976           for(var part in component) {\r
2977             if(!output.hasOwnProperty(part)) {\r
2978               output[part] = _.cloneDeep(component[part]);\r
2979               if(part === 'properties') {\r
2980                 for(name in output[part]) {\r
2981                   output[part][name]['x-resolved-from'] = source;\r
2982                 }\r
2983               }\r
2984             }\r
2985             else {\r
2986               if(part === 'properties') {\r
2987                 var properties = component[part];\r
2988                 for(name in properties) {\r
2989                   output.properties[name] = _.cloneDeep(properties[name]);\r
2990                   var resolvedFrom = properties[name]['x-resolved-from'];\r
2991                   if (typeof resolvedFrom === 'undefined' || resolvedFrom === 'self') {\r
2992                     resolvedFrom = source;\r
2993                   }\r
2994                   output.properties[name]['x-resolved-from'] = resolvedFrom;\r
2995                 }\r
2996               }\r
2997               else if(part === 'required') {\r
2998                 // merge & dedup the required array\r
2999                 var a = output.required.concat(component[part]);\r
3000                 for(var k = 0; k < a.length; ++k) {\r
3001                   for(var j = k + 1; j < a.length; ++j) {\r
3002                     if(a[k] === a[j]) { a.splice(j--, 1); }\r
3003                   }\r
3004                 }\r
3005                 output.required = a;\r
3006               }\r
3007               else if(part === 'x-resolved-from') {\r
3008                 output['x-resolved-from'].push(source);\r
3009               }\r
3010               else {\r
3011                 // TODO: need to merge this property\r
3012                 // console.log('what to do with ' + part)\r
3013               }\r
3014             }\r
3015           }\r
3016         }\r
3017         obj[key] = output;\r
3018       }\r
3019     }\r
3020   }\r
3021 };\r
3022 \r
3023 },{"./http":5,"lodash-compat/lang/cloneDeep":140,"lodash-compat/lang/isArray":142,"lodash-compat/lang/isObject":146}],7:[function(require,module,exports){\r
3024 'use strict';\r
3025 \r
3026 var Helpers = require('./helpers');\r
3027 \r
3028 var _ = {\r
3029   isPlainObject: require('lodash-compat/lang/isPlainObject'),\r
3030   isUndefined: require('lodash-compat/lang/isUndefined'),\r
3031   isArray: require('lodash-compat/lang/isArray'),\r
3032   isObject: require('lodash-compat/lang/isObject'),\r
3033   isEmpty: require('lodash-compat/lang/isEmpty'),\r
3034   map: require('lodash-compat/collection/map'),\r
3035   indexOf: require('lodash-compat/array/indexOf'),\r
3036   cloneDeep: require('lodash-compat/lang/cloneDeep'),\r
3037   keys: require('lodash-compat/object/keys'),\r
3038   forEach: require('lodash-compat/collection/forEach')\r
3039 };\r
3040 \r
3041 module.exports.optionHtml = optionHtml;\r
3042 module.exports.typeFromJsonSchema = typeFromJsonSchema;\r
3043 module.exports.getStringSignature = getStringSignature;\r
3044 module.exports.schemaToHTML = schemaToHTML;\r
3045 module.exports.schemaToJSON = schemaToJSON;\r
3046 \r
3047 function optionHtml(label, value) {\r
3048   return '<tr><td class="optionName">' + label + ':</td><td>' + value + '</td></tr>';\r
3049 }\r
3050 \r
3051 function typeFromJsonSchema(type, format) {\r
3052   var str;\r
3053 \r
3054   if (type === 'integer' && format === 'int32') {\r
3055     str = 'integer';\r
3056   } else if (type === 'integer' && format === 'int64') {\r
3057     str = 'long';\r
3058   } else if (type === 'integer' && typeof format === 'undefined') {\r
3059     str = 'long';\r
3060   } else if (type === 'string' && format === 'date-time') {\r
3061     str = 'date-time';\r
3062   } else if (type === 'string' && format === 'date') {\r
3063     str = 'date';\r
3064   } else if (type === 'number' && format === 'float') {\r
3065     str = 'float';\r
3066   } else if (type === 'number' && format === 'double') {\r
3067     str = 'double';\r
3068   } else if (type === 'number' && typeof format === 'undefined') {\r
3069     str = 'double';\r
3070   } else if (type === 'boolean') {\r
3071     str = 'boolean';\r
3072   } else if (type === 'string') {\r
3073     str = 'string';\r
3074   }\r
3075 \r
3076   return str;\r
3077 }\r
3078 \r
3079 function getStringSignature(obj, baseComponent) {\r
3080   var str = '';\r
3081 \r
3082   if (typeof obj.$ref !== 'undefined') {\r
3083     str += Helpers.simpleRef(obj.$ref);\r
3084   } else if (typeof obj.type === 'undefined') {\r
3085     str += 'object';\r
3086   } else if (obj.type === 'array') {\r
3087     if (baseComponent) {\r
3088       str += getStringSignature((obj.items || obj.$ref || {}));\r
3089     } else {\r
3090       str += 'Array[';\r
3091       str += getStringSignature((obj.items || obj.$ref || {}));\r
3092       str += ']';\r
3093     }\r
3094   } else if (obj.type === 'integer' && obj.format === 'int32') {\r
3095     str += 'integer';\r
3096   } else if (obj.type === 'integer' && obj.format === 'int64') {\r
3097     str += 'long';\r
3098   } else if (obj.type === 'integer' && typeof obj.format === 'undefined') {\r
3099     str += 'long';\r
3100   } else if (obj.type === 'string' && obj.format === 'date-time') {\r
3101     str += 'date-time';\r
3102   } else if (obj.type === 'string' && obj.format === 'date') {\r
3103     str += 'date';\r
3104   } else if (obj.type === 'string' && typeof obj.format === 'undefined') {\r
3105     str += 'string';\r
3106   } else if (obj.type === 'number' && obj.format === 'float') {\r
3107     str += 'float';\r
3108   } else if (obj.type === 'number' && obj.format === 'double') {\r
3109     str += 'double';\r
3110   } else if (obj.type === 'number' && typeof obj.format === 'undefined') {\r
3111     str += 'double';\r
3112   } else if (obj.type === 'boolean') {\r
3113     str += 'boolean';\r
3114   } else if (obj.$ref) {\r
3115     str += Helpers.simpleRef(obj.$ref);\r
3116   } else {\r
3117     str += obj.type;\r
3118   }\r
3119 \r
3120   return str;\r
3121 }\r
3122 \r
3123 function schemaToJSON(schema, models, modelsToIgnore, modelPropertyMacro) {\r
3124   // Resolve the schema (Handle nested schemas)\r
3125   schema = Helpers.resolveSchema(schema);\r
3126 \r
3127   if(typeof modelPropertyMacro !== 'function') {\r
3128     modelPropertyMacro = function(prop){\r
3129       return (prop || {}).default;\r
3130     };\r
3131   }\r
3132 \r
3133   modelsToIgnore= modelsToIgnore || {};\r
3134 \r
3135   var type = schema.type || 'object';\r
3136   var format = schema.format;\r
3137   var model;\r
3138   var output;\r
3139 \r
3140   if (!_.isUndefined(schema.example)) {\r
3141     output = schema.example;\r
3142   } else if (_.isUndefined(schema.items) && _.isArray(schema.enum)) {\r
3143     output = schema.enum[0];\r
3144   }\r
3145 \r
3146   if (_.isUndefined(output)) {\r
3147     if (schema.$ref) {\r
3148       model = models[Helpers.simpleRef(schema.$ref)];\r
3149 \r
3150       if (!_.isUndefined(model)) {\r
3151         if (_.isUndefined(modelsToIgnore[model.name])) {\r
3152           modelsToIgnore[model.name] = model;\r
3153           output = schemaToJSON(model.definition, models, modelsToIgnore, modelPropertyMacro);\r
3154           delete modelsToIgnore[model.name];\r
3155         } else {\r
3156           if (model.type === 'array') {\r
3157             output = [];\r
3158           } else {\r
3159             output = {};\r
3160           }\r
3161         }\r
3162       }\r
3163     } else if (!_.isUndefined(schema.default)) {\r
3164       output = schema.default;\r
3165     } else if (type === 'string') {\r
3166       if (format === 'date-time') {\r
3167         output = new Date().toISOString();\r
3168       } else if (format === 'date') {\r
3169         output = new Date().toISOString().split('T')[0];\r
3170       } else {\r
3171         output = 'string';\r
3172       }\r
3173     } else if (type === 'integer') {\r
3174       output = 0;\r
3175     } else if (type === 'number') {\r
3176       output = 0.0;\r
3177     } else if (type === 'boolean') {\r
3178       output = true;\r
3179     } else if (type === 'object') {\r
3180       output = {};\r
3181 \r
3182       _.forEach(schema.properties, function (property, name) {\r
3183         var cProperty = _.cloneDeep(property);\r
3184 \r
3185         // Allow macro to set the default value\r
3186         cProperty.default = modelPropertyMacro(property);\r
3187 \r
3188         output[name] = schemaToJSON(cProperty, models, modelsToIgnore, modelPropertyMacro);\r
3189       });\r
3190     } else if (type === 'array') {\r
3191       output = [];\r
3192 \r
3193       if (_.isArray(schema.items)) {\r
3194         _.forEach(schema.items, function (item) {\r
3195           output.push(schemaToJSON(item, models, modelsToIgnore, modelPropertyMacro));\r
3196         });\r
3197       } else if (_.isPlainObject(schema.items)) {\r
3198         output.push(schemaToJSON(schema.items, models, modelsToIgnore, modelPropertyMacro));\r
3199       } else if (_.isUndefined(schema.items)) {\r
3200         output.push({});\r
3201       } else {\r
3202         Helpers.log('Array type\'s \'items\' property is not an array or an object, cannot process');\r
3203       }\r
3204     }\r
3205   }\r
3206 \r
3207   return output;\r
3208 }\r
3209 \r
3210 function schemaToHTML(name, schema, models, modelPropertyMacro) {\r
3211 \r
3212   var strongOpen = '<span class="strong">';\r
3213   var strongClose = '</span>';\r
3214 \r
3215   // Allow for ignoring the 'name' argument.... shifting the rest\r
3216   if(_.isObject(arguments[0])) {\r
3217     name = void 0;\r
3218     schema = arguments[0];\r
3219     models = arguments[1];\r
3220     modelPropertyMacro = arguments[2];\r
3221   }\r
3222 \r
3223   models = models || {};\r
3224 \r
3225   // Resolve the schema (Handle nested schemas)\r
3226   schema = Helpers.resolveSchema(schema);\r
3227 \r
3228   // Return for empty object\r
3229   if(_.isEmpty(schema)) {\r
3230     return strongOpen + 'Empty' + strongClose;\r
3231   }\r
3232 \r
3233   // Dereference $ref from 'models'\r
3234   if(typeof schema.$ref === 'string') {\r
3235     name = Helpers.simpleRef(schema.$ref);\r
3236     schema = models[name];\r
3237     if(typeof schema === 'undefined')\r
3238     {\r
3239       return strongOpen + name + ' is not defined!' + strongClose;\r
3240     }\r
3241   }\r
3242 \r
3243   if(typeof name !== 'string') {\r
3244     name = schema.title || 'Inline Model';\r
3245   }\r
3246 \r
3247   // If we are a Model object... adjust accordingly\r
3248   if(schema.definition) {\r
3249     schema = schema.definition;\r
3250   }\r
3251 \r
3252   if(typeof modelPropertyMacro !== 'function') {\r
3253     modelPropertyMacro = function(prop){\r
3254       return (prop || {}).default;\r
3255     };\r
3256   }\r
3257 \r
3258   var references = {};\r
3259   var seenModels = [];\r
3260   var inlineModels = 0;\r
3261 \r
3262 \r
3263 \r
3264   // Generate current HTML\r
3265   var html = processModel(schema, name);\r
3266 \r
3267   // Generate references HTML\r
3268   while (_.keys(references).length > 0) {\r
3269     /* jshint ignore:start */\r
3270     _.forEach(references, function (schema, name) {\r
3271       var seenModel = _.indexOf(seenModels, name) > -1;\r
3272 \r
3273       delete references[name];\r
3274 \r
3275       if (!seenModel) {\r
3276         seenModels.push(name);\r
3277 \r
3278         html += '<br />' + processModel(schema, name);\r
3279       }\r
3280     });\r
3281     /* jshint ignore:end */\r
3282   }\r
3283 \r
3284   return html;\r
3285 \r
3286   /////////////////////////////////\r
3287 \r
3288   function addReference(schema, name, skipRef) {\r
3289     var modelName = name;\r
3290     var model;\r
3291 \r
3292     if (schema.$ref) {\r
3293       modelName = schema.title || Helpers.simpleRef(schema.$ref);\r
3294       model = models[modelName];\r
3295     } else if (_.isUndefined(name)) {\r
3296       modelName = schema.title || 'Inline Model ' + (++inlineModels);\r
3297       model = {definition: schema};\r
3298     }\r
3299 \r
3300     if (skipRef !== true) {\r
3301       references[modelName] = _.isUndefined(model) ? {} : model.definition;\r
3302     }\r
3303 \r
3304     return modelName;\r
3305   }\r
3306 \r
3307   function primitiveToHTML(schema) {\r
3308     var html = '<span class="propType">';\r
3309     var type = schema.type || 'object';\r
3310 \r
3311     if (schema.$ref) {\r
3312       html += addReference(schema, Helpers.simpleRef(schema.$ref));\r
3313     } else if (type === 'object') {\r
3314       if (!_.isUndefined(schema.properties)) {\r
3315         html += addReference(schema);\r
3316       } else {\r
3317         html += 'object';\r
3318       }\r
3319     } else if (type === 'array') {\r
3320       html += 'Array[';\r
3321 \r
3322       if (_.isArray(schema.items)) {\r
3323         html += _.map(schema.items, addReference).join(',');\r
3324       } else if (_.isPlainObject(schema.items)) {\r
3325         if (_.isUndefined(schema.items.$ref)) {\r
3326           if (!_.isUndefined(schema.items.type) && _.indexOf(['array', 'object'], schema.items.type) === -1) {\r
3327             html += schema.items.type;\r
3328           } else {\r
3329             html += addReference(schema.items);\r
3330           }\r
3331         } else {\r
3332           html += addReference(schema.items, Helpers.simpleRef(schema.items.$ref));\r
3333         }\r
3334       } else {\r
3335         Helpers.log('Array type\'s \'items\' schema is not an array or an object, cannot process');\r
3336         html += 'object';\r
3337       }\r
3338 \r
3339       html += ']';\r
3340     } else {\r
3341       html += schema.type;\r
3342     }\r
3343 \r
3344     html += '</span>';\r
3345 \r
3346     return html;\r
3347   }\r
3348 \r
3349   function primitiveToOptionsHTML(schema, html) {\r
3350     var options = '';\r
3351     var type = schema.type || 'object';\r
3352     var isArray = type === 'array';\r
3353 \r
3354     if (isArray) {\r
3355       if (_.isPlainObject(schema.items) && !_.isUndefined(schema.items.type)) {\r
3356         type = schema.items.type;\r
3357       } else {\r
3358         type = 'object';\r
3359       }\r
3360     }\r
3361 \r
3362     if (!_.isUndefined(schema.default)) {\r
3363       options += optionHtml('Default', schema.default);\r
3364     }\r
3365 \r
3366     switch (type) {\r
3367     case 'string':\r
3368       if (schema.minLength) {\r
3369         options += optionHtml('Min. Length', schema.minLength);\r
3370       }\r
3371 \r
3372       if (schema.maxLength) {\r
3373         options += optionHtml('Max. Length', schema.maxLength);\r
3374       }\r
3375 \r
3376       if (schema.pattern) {\r
3377         options += optionHtml('Reg. Exp.', schema.pattern);\r
3378       }\r
3379       break;\r
3380     case 'integer':\r
3381     case 'number':\r
3382       if (schema.minimum) {\r
3383         options += optionHtml('Min. Value', schema.minimum);\r
3384       }\r
3385 \r
3386       if (schema.exclusiveMinimum) {\r
3387         options += optionHtml('Exclusive Min.', 'true');\r
3388       }\r
3389 \r
3390       if (schema.maximum) {\r
3391         options += optionHtml('Max. Value', schema.maximum);\r
3392       }\r
3393 \r
3394       if (schema.exclusiveMaximum) {\r
3395         options += optionHtml('Exclusive Max.', 'true');\r
3396       }\r
3397 \r
3398       if (schema.multipleOf) {\r
3399         options += optionHtml('Multiple Of', schema.multipleOf);\r
3400       }\r
3401 \r
3402       break;\r
3403     }\r
3404 \r
3405     if (isArray) {\r
3406       if (schema.minItems) {\r
3407         options += optionHtml('Min. Items', schema.minItems);\r
3408       }\r
3409 \r
3410       if (schema.maxItems) {\r
3411         options += optionHtml('Max. Items', schema.maxItems);\r
3412       }\r
3413 \r
3414       if (schema.uniqueItems) {\r
3415         options += optionHtml('Unique Items', 'true');\r
3416       }\r
3417 \r
3418       if (schema.collectionFormat) {\r
3419         options += optionHtml('Coll. Format', schema.collectionFormat);\r
3420       }\r
3421     }\r
3422 \r
3423     if (_.isUndefined(schema.items)) {\r
3424       if (_.isArray(schema.enum)) {\r
3425         var enumString;\r
3426 \r
3427         if (type === 'number' || type === 'integer') {\r
3428           enumString = schema.enum.join(', ');\r
3429         } else {\r
3430           enumString = '"' + schema.enum.join('", "') + '"';\r
3431         }\r
3432 \r
3433         options += optionHtml('Enum', enumString);\r
3434       }\r
3435     }\r
3436 \r
3437     if (options.length > 0) {\r
3438       html = '<span class="propWrap">' + html + '<table class="optionsWrapper"><tr><th colspan="2">' + type + '</th></tr>' + options + '</table></span>';\r
3439     }\r
3440 \r
3441     return html;\r
3442   }\r
3443 \r
3444   function processModel(schema, name) {\r
3445     var type = schema.type || 'object';\r
3446     var isArray = schema.type === 'array';\r
3447     var html = strongOpen + name + ' ' + (isArray ? '[' : '{') + strongClose;\r
3448 \r
3449     if (name) {\r
3450       seenModels.push(name);\r
3451     }\r
3452 \r
3453     if (isArray) {\r
3454       if (_.isArray(schema.items)) {\r
3455         html += '<div>' + _.map(schema.items, function (item) {\r
3456           var type = item.type || 'object';\r
3457 \r
3458           if (_.isUndefined(item.$ref)) {\r
3459             if (_.indexOf(['array', 'object'], type) > -1) {\r
3460               if (type === 'object' && _.isUndefined(item.properties)) {\r
3461                 return 'object';\r
3462               } else {\r
3463                 return addReference(item);\r
3464               }\r
3465             } else {\r
3466               return primitiveToOptionsHTML(item, type);\r
3467             }\r
3468           } else {\r
3469             return addReference(item, Helpers.simpleRef(item.$ref));\r
3470           }\r
3471         }).join(',</div><div>');\r
3472       } else if (_.isPlainObject(schema.items)) {\r
3473         if (_.isUndefined(schema.items.$ref)) {\r
3474           if (_.indexOf(['array', 'object'], schema.items.type || 'object') > -1) {\r
3475             if ((_.isUndefined(schema.items.type) || schema.items.type === 'object') && _.isUndefined(schema.items.properties)) {\r
3476               html += '<div>object</div>';\r
3477             } else {\r
3478               html += '<div>' + addReference(schema.items) + '</div>';\r
3479             }\r
3480           } else {\r
3481             html += '<div>' + primitiveToOptionsHTML(schema.items, schema.items.type) + '</div>';\r
3482           }\r
3483         } else {\r
3484           html += '<div>' + addReference(schema.items, Helpers.simpleRef(schema.items.$ref)) + '</div>';\r
3485         }\r
3486       } else {\r
3487         Helpers.log('Array type\'s \'items\' property is not an array or an object, cannot process');\r
3488         html += '<div>object</div>';\r
3489       }\r
3490     } else {\r
3491       if (schema.$ref) {\r
3492         html += '<div>' + addReference(schema, name) + '</div>';\r
3493       } else if (type === 'object') {\r
3494         if (_.isPlainObject(schema.properties)) {\r
3495           var contents = _.map(schema.properties, function (property, name) {\r
3496             var propertyIsRequired = (_.indexOf(schema.required, name) >= 0);\r
3497             var cProperty = _.cloneDeep(property);\r
3498 \r
3499             var requiredClass = propertyIsRequired ? 'required' : '';\r
3500             var html = '<span class="propName ' + requiredClass + '">' + name + '</span> (';\r
3501             var model;\r
3502             var propDescription;\r
3503 \r
3504             // Allow macro to set the default value\r
3505             cProperty.default = modelPropertyMacro(cProperty);\r
3506 \r
3507             // Resolve the schema (Handle nested schemas)\r
3508             cProperty = Helpers.resolveSchema(cProperty);\r
3509 \r
3510             propDescription = property.description || cProperty.description;\r
3511 \r
3512             // We need to handle property references to primitives (Issue 339)\r
3513             if (!_.isUndefined(cProperty.$ref)) {\r
3514               model = models[Helpers.simpleRef(cProperty.$ref)];\r
3515 \r
3516               if (!_.isUndefined(model) && _.indexOf([undefined, 'array', 'object'], model.definition.type) === -1) {\r
3517                 // Use referenced schema\r
3518                 cProperty = Helpers.resolveSchema(model.definition);\r
3519               }\r
3520             }\r
3521 \r
3522             html += primitiveToHTML(cProperty);\r
3523 \r
3524             if(!propertyIsRequired) {\r
3525               html += ', <span class="propOptKey">optional</span>';\r
3526             }\r
3527 \r
3528             if(property.readOnly) {\r
3529                 html += ', <span class="propReadOnly">read only</span>';\r
3530             }\r
3531 \r
3532             html += ')';\r
3533 \r
3534             if (!_.isUndefined(propDescription)) {\r
3535               html += ': ' + '<span class="propDesc">' + propDescription + '</span>';\r
3536             }\r
3537 \r
3538             if (cProperty.enum) {\r
3539               html += ' = <span class="propVals">[\'' + cProperty.enum.join('\', \'') + '\']</span>';\r
3540             }\r
3541 \r
3542             return '<div' + (property.readOnly ? ' class="readOnly"' : '') + '>' + primitiveToOptionsHTML(cProperty, html);\r
3543           }).join(',</div>');\r
3544 \r
3545           if (contents) {\r
3546             html += contents + '</div>';\r
3547           }\r
3548         }\r
3549       } else {\r
3550         html += '<div>' + primitiveToOptionsHTML(schema, type) + '</div>';\r
3551       }\r
3552     }\r
3553 \r
3554     return html + strongOpen + (isArray ? ']' : '}') + strongClose;\r
3555   }\r
3556 }\r
3557 \r
3558 },{"./helpers":4,"lodash-compat/array/indexOf":51,"lodash-compat/collection/forEach":56,"lodash-compat/collection/map":58,"lodash-compat/lang/cloneDeep":140,"lodash-compat/lang/isArray":142,"lodash-compat/lang/isEmpty":143,"lodash-compat/lang/isObject":146,"lodash-compat/lang/isPlainObject":147,"lodash-compat/lang/isUndefined":150,"lodash-compat/object/keys":151}],8:[function(require,module,exports){\r
3559 'use strict';\r
3560 \r
3561 var SwaggerHttp = require('./http');\r
3562 var _ = {\r
3563   isObject: require('lodash-compat/lang/isObject')\r
3564 };\r
3565 \r
3566 var SwaggerSpecConverter = module.exports = function () {\r
3567   this.errors = [];\r
3568   this.warnings = [];\r
3569   this.modelMap = {};\r
3570 };\r
3571 \r
3572 SwaggerSpecConverter.prototype.setDocumentationLocation = function (location) {\r
3573   this.docLocation = location;\r
3574 };\r
3575 \r
3576 /**\r
3577  * converts a resource listing OR api declaration\r
3578  **/\r
3579 SwaggerSpecConverter.prototype.convert = function (obj, clientAuthorizations, opts, callback) {\r
3580   // not a valid spec\r
3581   if(!obj || !Array.isArray(obj.apis)) {\r
3582     return this.finish(callback, null);\r
3583   }\r
3584   this.clientAuthorizations = clientAuthorizations;\r
3585 \r
3586   // create a new swagger object to return\r
3587   var swagger = { swagger: '2.0' };\r
3588 \r
3589   swagger.originalVersion = obj.swaggerVersion;\r
3590 \r
3591   // add the info\r
3592   this.apiInfo(obj, swagger);\r
3593 \r
3594   // add security definitions\r
3595   this.securityDefinitions(obj, swagger);\r
3596 \r
3597   // take basePath into account\r
3598   if (obj.basePath) {\r
3599     this.setDocumentationLocation(obj.basePath);\r
3600   }\r
3601 \r
3602   // see if this is a single-file swagger definition\r
3603   var isSingleFileSwagger = false;\r
3604   var i;\r
3605   for(i = 0; i < obj.apis.length; i++) {\r
3606     var api = obj.apis[i];\r
3607     if(Array.isArray(api.operations)) {\r
3608       isSingleFileSwagger = true;\r
3609     }\r
3610   }\r
3611   if(isSingleFileSwagger) {\r
3612     this.declaration(obj, swagger);\r
3613     this.finish(callback, swagger);\r
3614   }\r
3615   else {\r
3616     this.resourceListing(obj, swagger, opts, callback);\r
3617   }\r
3618 };\r
3619 \r
3620 SwaggerSpecConverter.prototype.declaration = function(obj, swagger) {\r
3621   var name, i, p, pos;\r
3622   if(!obj.apis) {\r
3623     return;\r
3624   }\r
3625 \r
3626   if (obj.basePath.indexOf('http://') === 0) {\r
3627     p = obj.basePath.substring('http://'.length);\r
3628     pos = p.indexOf('/');\r
3629     if (pos > 0) {\r
3630       swagger.host = p.substring(0, pos);\r
3631       swagger.basePath = p.substring(pos);\r
3632     }\r
3633     else {\r
3634       swagger.host = p;\r
3635       swagger.basePath = '/';\r
3636     }\r
3637   } else if (obj.basePath.indexOf('https://') === 0) {\r
3638     p = obj.basePath.substring('https://'.length);\r
3639     pos = p.indexOf('/');\r
3640     if (pos > 0) {\r
3641       swagger.host = p.substring(0, pos);\r
3642       swagger.basePath = p.substring(pos);\r
3643     }\r
3644     else {\r
3645       swagger.host = p;\r
3646       swagger.basePath = '/';\r
3647     }\r
3648   } else {\r
3649     swagger.basePath = obj.basePath;\r
3650   }\r
3651 \r
3652   var resourceLevelAuth;\r
3653   if(obj.authorizations) {\r
3654     resourceLevelAuth = obj.authorizations;\r
3655   }\r
3656   if(obj.consumes) {\r
3657     swagger.consumes = obj.consumes;\r
3658   }\r
3659   if(obj.produces) {\r
3660     swagger.produces = obj.produces;\r
3661   }\r
3662 \r
3663   // build a mapping of id to name for 1.0 model resolutions\r
3664   if(_.isObject(obj)) {\r
3665     for(name in obj.models) {\r
3666       var existingModel = obj.models[name];\r
3667       var key = (existingModel.id || name);\r
3668       this.modelMap[key] = name;\r
3669     }\r
3670   }\r
3671 \r
3672   for(i = 0; i < obj.apis.length; i++) {\r
3673     var api = obj.apis[i];\r
3674     var path = api.path;\r
3675     var operations = api.operations;\r
3676     this.operations(path, obj.resourcePath, operations, resourceLevelAuth, swagger);\r
3677   }\r
3678 \r
3679   var models = obj.models || {};\r
3680   this.models(models, swagger);\r
3681 };\r
3682 \r
3683 SwaggerSpecConverter.prototype.models = function(obj, swagger) {\r
3684   if(!_.isObject(obj)) {\r
3685     return;\r
3686   }\r
3687   var name;\r
3688 \r
3689   swagger.definitions = swagger.definitions || {};\r
3690   for(name in obj) {\r
3691     var existingModel = obj[name];\r
3692     var _required = [];\r
3693     var schema = { properties: {}};\r
3694     var propertyName;\r
3695     for(propertyName in existingModel.properties) {\r
3696       var existingProperty = existingModel.properties[propertyName];\r
3697       var property = {};\r
3698       this.dataType(existingProperty, property);\r
3699       if(existingProperty.description) {\r
3700         property.description = existingProperty.description;\r
3701       }\r
3702       if(existingProperty['enum']) {\r
3703         property['enum'] = existingProperty['enum'];\r
3704       }\r
3705       if(typeof existingProperty.required === 'boolean' && existingProperty.required === true) {\r
3706         _required.push(propertyName);\r
3707       }\r
3708       if(typeof existingProperty.required === 'string' && existingProperty.required === 'true') {\r
3709         _required.push(propertyName);\r
3710       }\r
3711       schema.properties[propertyName] = property;\r
3712     }\r
3713     if(_required.length > 0) {\r
3714       schema.required = _required;\r
3715     } else {\r
3716       schema.required = existingModel.required;\r
3717     }\r
3718     swagger.definitions[name] = schema;\r
3719   }\r
3720 };\r
3721 \r
3722 SwaggerSpecConverter.prototype.extractTag = function(resourcePath) {\r
3723   var pathString = resourcePath || 'default';\r
3724   if(pathString.indexOf('http:') === 0 || pathString.indexOf('https:') === 0) {\r
3725     pathString = pathString.split(['/']);\r
3726     pathString = pathString[pathString.length -1].substring();\r
3727   }\r
3728   if(pathString.endsWith('.json')) {\r
3729     pathString = pathString.substring(0, pathString.length - '.json'.length);\r
3730   }\r
3731   return pathString.replace('/','');\r
3732 };\r
3733 \r
3734 SwaggerSpecConverter.prototype.operations = function(path, resourcePath, obj, resourceLevelAuth, swagger) {\r
3735   if(!Array.isArray(obj)) {\r
3736     return;\r
3737   }\r
3738   var i;\r
3739 \r
3740   if(!swagger.paths) {\r
3741     swagger.paths = {};\r
3742   }\r
3743 \r
3744   var pathObj = swagger.paths[path] || {};\r
3745   var tag = this.extractTag(resourcePath);\r
3746   swagger.tags = swagger.tags || [];\r
3747   var matched = false;\r
3748   for(i = 0; i < swagger.tags.length; i++) {\r
3749     var tagObject = swagger.tags[i];\r
3750     if(tagObject.name === tag) {\r
3751       matched = true;\r
3752     }\r
3753   }\r
3754   if(!matched) {\r
3755     swagger.tags.push({name: tag});\r
3756   }\r
3757 \r
3758   for(i = 0; i < obj.length; i++) {\r
3759     var existingOperation = obj[i];\r
3760     var method = (existingOperation.method || existingOperation.httpMethod).toLowerCase();\r
3761     var operation = {tags: [tag]};\r
3762     var existingAuthorizations = existingOperation.authorizations;\r
3763 \r
3764     if(existingAuthorizations && Object.keys(existingAuthorizations).length === 0) {\r
3765       existingAuthorizations = resourceLevelAuth;\r
3766     }\r
3767 \r
3768     if(typeof existingAuthorizations !== 'undefined') {\r
3769       var scopesObject;\r
3770       for(var key in existingAuthorizations) {\r
3771         operation.security = operation.security || [];\r
3772         var scopes = existingAuthorizations[key];\r
3773         if(scopes) {\r
3774           var securityScopes = [];\r
3775           for(var j in scopes) {\r
3776             securityScopes.push(scopes[j].scope);\r
3777           }\r
3778           scopesObject = {};\r
3779           scopesObject[key] = securityScopes;\r
3780           operation.security.push(scopesObject);\r
3781         }\r
3782         else {\r
3783           scopesObject = {};\r
3784           scopesObject[key] = [];\r
3785           operation.security.push(scopesObject);\r
3786         }\r
3787       }\r
3788     }\r
3789 \r
3790     if(existingOperation.consumes) {\r
3791       operation.consumes = existingOperation.consumes;\r
3792     }\r
3793     else if(swagger.consumes) {\r
3794       operation.consumes = swagger.consumes;\r
3795     }\r
3796     if(existingOperation.produces) {\r
3797       operation.produces = existingOperation.produces;\r
3798     }\r
3799     else if(swagger.produces) {\r
3800       operation.produces = swagger.produces;\r
3801     }\r
3802     if(existingOperation.summary) {\r
3803       operation.summary = existingOperation.summary;\r
3804     }\r
3805     if(existingOperation.notes) {\r
3806       operation.description = existingOperation.notes;\r
3807     }\r
3808     if(existingOperation.nickname) {\r
3809       operation.operationId = existingOperation.nickname;\r
3810     }\r
3811     if(existingOperation.deprecated) {\r
3812       operation.deprecated = existingOperation.deprecated;\r
3813     }\r
3814 \r
3815     this.authorizations(existingAuthorizations, swagger);\r
3816     this.parameters(operation, existingOperation.parameters, swagger);\r
3817     this.responseMessages(operation, existingOperation, swagger);\r
3818 \r
3819     pathObj[method] = operation;\r
3820   }\r
3821 \r
3822   swagger.paths[path] = pathObj;\r
3823 };\r
3824 \r
3825 SwaggerSpecConverter.prototype.responseMessages = function(operation, existingOperation) {\r
3826   if(!_.isObject(existingOperation)) {\r
3827     return;\r
3828   }\r
3829   // build default response from the operation (1.x)\r
3830   var defaultResponse = {};\r
3831   this.dataType(existingOperation, defaultResponse);\r
3832   // TODO: look into the real problem of rendering responses in swagger-ui\r
3833   // ....should reponseType have an implicit schema?\r
3834   if(!defaultResponse.schema && defaultResponse.type) {\r
3835     defaultResponse = {schema: defaultResponse};\r
3836   }\r
3837 \r
3838   operation.responses = operation.responses || {};\r
3839 \r
3840   // grab from responseMessages (1.2)\r
3841   var has200 = false;\r
3842   if(Array.isArray(existingOperation.responseMessages)) {\r
3843     var i;\r
3844     var existingResponses = existingOperation.responseMessages;\r
3845     for(i = 0; i < existingResponses.length; i++) {\r
3846       var existingResponse = existingResponses[i];\r
3847       var response = { description: existingResponse.message };\r
3848       if(existingResponse.code === 200) {\r
3849         has200 = true;\r
3850       }\r
3851       // Convert responseModel -> schema{$ref: responseModel}\r
3852       if(existingResponse.responseModel) {\r
3853         response.schema = {'$ref': '#/definitions/' + existingResponse.responseModel};\r
3854       }\r
3855       operation.responses['' + existingResponse.code] = response;\r
3856     }\r
3857   }\r
3858 \r
3859   if(has200) {\r
3860     operation.responses['default'] = defaultResponse;\r
3861   }\r
3862   else {\r
3863     operation.responses['200'] = defaultResponse;\r
3864   }\r
3865 };\r
3866 \r
3867 SwaggerSpecConverter.prototype.authorizations = function(obj) {\r
3868   // TODO\r
3869   if(!_.isObject(obj)) {\r
3870     return;\r
3871   }\r
3872 };\r
3873 \r
3874 SwaggerSpecConverter.prototype.parameters = function(operation, obj) {\r
3875   if(!Array.isArray(obj)) {\r
3876     return;\r
3877   }\r
3878   var i;\r
3879   for(i = 0; i < obj.length; i++) {\r
3880     var existingParameter = obj[i];\r
3881     var parameter = {};\r
3882     parameter.name = existingParameter.name;\r
3883     parameter.description = existingParameter.description;\r
3884     parameter.required = existingParameter.required;\r
3885     parameter.in = existingParameter.paramType;\r
3886 \r
3887     // per #168\r
3888     if(parameter.in === 'body') {\r
3889       parameter.name = 'body';\r
3890     }\r
3891     if(parameter.in === 'form') {\r
3892       parameter.in = 'formData';\r
3893     }\r
3894 \r
3895     if(existingParameter.enum) {\r
3896       parameter.enum = existingParameter.enum;\r
3897     }\r
3898 \r
3899     if(existingParameter.allowMultiple === true || existingParameter.allowMultiple === 'true') {\r
3900       var innerType = {};\r
3901       this.dataType(existingParameter, innerType);\r
3902       parameter.type = 'array';\r
3903       parameter.items = innerType;\r
3904 \r
3905       if(existingParameter.allowableValues) {\r
3906         var av = existingParameter.allowableValues;\r
3907         if(av.valueType === 'LIST') {\r
3908           parameter['enum'] = av.values;\r
3909         }\r
3910       }\r
3911     }\r
3912     else {\r
3913       this.dataType(existingParameter, parameter);\r
3914     }\r
3915     if(typeof existingParameter.defaultValue !== 'undefined') {\r
3916       parameter.default = existingParameter.defaultValue;\r
3917     }\r
3918 \r
3919     operation.parameters = operation.parameters || [];\r
3920     operation.parameters.push(parameter);\r
3921   }\r
3922 };\r
3923 \r
3924 SwaggerSpecConverter.prototype.dataType = function(source, target) {\r
3925   if(!_.isObject(source)) {\r
3926     return;\r
3927   }\r
3928 \r
3929   if(source.minimum) {\r
3930     target.minimum = source.minimum;\r
3931   }\r
3932   if(source.maximum) {\r
3933     target.maximum = source.maximum;\r
3934   }\r
3935   if (source.format) {\r
3936     target.format = source.format;\r
3937   }\r
3938 \r
3939   // default can be 'false'\r
3940   if(typeof source.defaultValue !== 'undefined') {\r
3941     target.default = source.defaultValue;\r
3942   }\r
3943 \r
3944   var jsonSchemaType = this.toJsonSchema(source);\r
3945   if(jsonSchemaType) {\r
3946     target = target || {};\r
3947     if(jsonSchemaType.type) {\r
3948       target.type = jsonSchemaType.type;\r
3949     }\r
3950     if(jsonSchemaType.format) {\r
3951       target.format = jsonSchemaType.format;\r
3952     }\r
3953     if(jsonSchemaType.$ref) {\r
3954       target.schema = {$ref: jsonSchemaType.$ref};\r
3955     }\r
3956     if(jsonSchemaType.items) {\r
3957       target.items = jsonSchemaType.items;\r
3958     }\r
3959   }\r
3960 };\r
3961 \r
3962 SwaggerSpecConverter.prototype.toJsonSchema = function(source) {\r
3963   if(!source) {\r
3964     return 'object';\r
3965   }\r
3966   var detectedType = (source.type || source.dataType || source.responseClass || '');\r
3967   var lcType = detectedType.toLowerCase();\r
3968   var format = (source.format || '').toLowerCase();\r
3969 \r
3970   if(lcType.indexOf('list[') === 0) {\r
3971     var innerType = detectedType.substring(5, detectedType.length - 1);\r
3972     var jsonType = this.toJsonSchema({type: innerType});\r
3973     return {type: 'array', items: jsonType};\r
3974   } else if(lcType === 'int' || (lcType === 'integer' && format === 'int32')) {\r
3975     {return {type: 'integer', format: 'int32'};}\r
3976   } else if(lcType === 'long' || (lcType === 'integer' && format === 'int64')) {\r
3977     {return {type: 'integer', format: 'int64'};}\r
3978   } else if(lcType === 'integer') {\r
3979     {return {type: 'integer', format: 'int64'};}\r
3980   } else if(lcType === 'float' || (lcType === 'number' && format === 'float')) {\r
3981     {return {type: 'number', format: 'float'};}\r
3982   } else if(lcType === 'double' || (lcType === 'number' && format === 'double')) {\r
3983     {return {type: 'number', format: 'double'};}\r
3984   } else if((lcType === 'string' && format === 'date-time') || (lcType === 'date')) {\r
3985     {return {type: 'string', format: 'date-time'};}\r
3986   } else if(lcType === 'string') {\r
3987     {return {type: 'string'};}\r
3988   } else if(lcType === 'file') {\r
3989     {return {type: 'file'};}\r
3990   } else if(lcType === 'boolean') {\r
3991     {return {type: 'boolean'};}\r
3992   } else if(lcType === 'boolean') {\r
3993     {return {type: 'boolean'};}\r
3994   } else if(lcType === 'array' || lcType === 'list') {\r
3995     if(source.items) {\r
3996       var it = this.toJsonSchema(source.items);\r
3997       return {type: 'array', items: it};\r
3998     }\r
3999     else {\r
4000       return {type: 'array', items: {type: 'object'}};\r
4001     }\r
4002   } else if(source.$ref) {\r
4003     return {$ref: this.modelMap[source.$ref] ? '#/definitions/' + this.modelMap[source.$ref] : source.$ref};\r
4004   } else if(lcType === 'void' || lcType === '') {\r
4005     {return {};}\r
4006   } else if (this.modelMap[source.type]) {\r
4007     // If this a model using `type` instead of `$ref`, that's fine.\r
4008     return {$ref: '#/definitions/' + this.modelMap[source.type]};\r
4009   } else {\r
4010     // Unknown model type or 'object', pass it along.\r
4011     return {type: source.type};\r
4012   }\r
4013 };\r
4014 \r
4015 SwaggerSpecConverter.prototype.resourceListing = function(obj, swagger, opts, callback) {\r
4016   var i;\r
4017   var processedCount = 0;   // jshint ignore:line\r
4018   var self = this;          // jshint ignore:line\r
4019   var expectedCount = obj.apis.length;\r
4020   var _swagger = swagger;   // jshint ignore:line\r
4021   var _opts = {};\r
4022 \r
4023   if(opts && opts.requestInterceptor){\r
4024     _opts.requestInterceptor = opts.requestInterceptor;\r
4025   }\r
4026 \r
4027   if(opts && opts.responseInterceptor){\r
4028     _opts.responseInterceptor = opts.responseInterceptor;\r
4029   }\r
4030 \r
4031   var swaggerRequestHeaders = 'application/json';\r
4032 \r
4033   if(opts && opts.swaggerRequestHeaders) {\r
4034     swaggerRequestHeaders = opts.swaggerRequestHeaders;\r
4035   }\r
4036 \r
4037   if(expectedCount === 0) {\r
4038     this.finish(callback, swagger);\r
4039   }\r
4040 \r
4041   for(i = 0; i < expectedCount; i++) {\r
4042     var api = obj.apis[i];\r
4043     var path = api.path;\r
4044     var absolutePath = this.getAbsolutePath(obj.swaggerVersion, this.docLocation, path);\r
4045 \r
4046     if(api.description) {\r
4047       swagger.tags = swagger.tags || [];\r
4048       swagger.tags.push({\r
4049         name : this.extractTag(api.path),\r
4050         description : api.description || ''\r
4051       });\r
4052     }\r
4053     var http = {\r
4054       url: absolutePath,\r
4055       headers: { accept: swaggerRequestHeaders },\r
4056       on: {},\r
4057       method: 'get'\r
4058     };\r
4059     /* jshint ignore:start */\r
4060     http.on.response = function(data) {\r
4061       processedCount += 1;\r
4062       var obj = data.obj;\r
4063       if(obj) {\r
4064         self.declaration(obj, _swagger);\r
4065       }\r
4066       if(processedCount === expectedCount) {\r
4067         self.finish(callback, _swagger);\r
4068       }\r
4069     };\r
4070     http.on.error = function(data) {\r
4071       console.error(data);\r
4072       processedCount += 1;\r
4073       if(processedCount === expectedCount) {\r
4074         self.finish(callback, _swagger);\r
4075       }\r
4076     };\r
4077     /* jshint ignore:end */\r
4078 \r
4079     if(this.clientAuthorizations && typeof this.clientAuthorizations.apply === 'function') {\r
4080       this.clientAuthorizations.apply(http);\r
4081     }\r
4082 \r
4083     new SwaggerHttp().execute(http, _opts);\r
4084   }\r
4085 };\r
4086 \r
4087 SwaggerSpecConverter.prototype.getAbsolutePath = function(version, docLocation, path)  {\r
4088   if(version === '1.0') {\r
4089     if(docLocation.endsWith('.json')) {\r
4090       // get root path\r
4091       var pos = docLocation.lastIndexOf('/');\r
4092       if(pos > 0) {\r
4093         docLocation = docLocation.substring(0, pos);\r
4094       }\r
4095     }\r
4096   }\r
4097 \r
4098   var location = docLocation;\r
4099   if(path.indexOf('http://') === 0 || path.indexOf('https://') === 0) {\r
4100     location = path;\r
4101   }\r
4102   else {\r
4103     if(docLocation.endsWith('/')) {\r
4104       location = docLocation.substring(0, docLocation.length - 1);\r
4105     }\r
4106     location += path;\r
4107   }\r
4108   location = location.replace('{format}', 'json');\r
4109   return location;\r
4110 };\r
4111 \r
4112 SwaggerSpecConverter.prototype.securityDefinitions = function(obj, swagger) {\r
4113   if(obj.authorizations) {\r
4114     var name;\r
4115     for(name in obj.authorizations) {\r
4116       var isValid = false;\r
4117       var securityDefinition = {};\r
4118       var definition = obj.authorizations[name];\r
4119       if(definition.type === 'apiKey') {\r
4120         securityDefinition.type = 'apiKey';\r
4121         securityDefinition.in = definition.passAs;\r
4122         securityDefinition.name = definition.keyname || name;\r
4123         isValid = true;\r
4124       }\r
4125       else if(definition.type === 'basicAuth') {\r
4126         securityDefinition.type = 'basicAuth';\r
4127         isValid = true;\r
4128       }\r
4129       else if(definition.type === 'oauth2') {\r
4130         var existingScopes = definition.scopes || [];\r
4131         var scopes = {};\r
4132         var i;\r
4133         for(i in existingScopes) {\r
4134           var scope = existingScopes[i];\r
4135           scopes[scope.scope] = scope.description;\r
4136         }\r
4137         securityDefinition.type = 'oauth2';\r
4138         if(i > 0) {\r
4139           securityDefinition.scopes = scopes;\r
4140         }\r
4141         if(definition.grantTypes) {\r
4142           if(definition.grantTypes.implicit) {\r
4143             var implicit = definition.grantTypes.implicit;\r
4144             securityDefinition.flow = 'implicit';\r
4145             securityDefinition.authorizationUrl = implicit.loginEndpoint;\r
4146             isValid = true;\r
4147           }\r
4148           /* jshint ignore:start */\r
4149           if(definition.grantTypes['authorization_code']) {\r
4150             if(!securityDefinition.flow) {\r
4151               // cannot set if flow is already defined\r
4152               var authCode = definition.grantTypes['authorization_code'];\r
4153               securityDefinition.flow = 'accessCode';\r
4154               securityDefinition.authorizationUrl = authCode.tokenRequestEndpoint.url;\r
4155               securityDefinition.tokenUrl = authCode.tokenEndpoint.url;\r
4156               isValid = true;\r
4157             }\r
4158           }\r
4159           /* jshint ignore:end */\r
4160         }\r
4161       }\r
4162       if(isValid) {\r
4163         swagger.securityDefinitions = swagger.securityDefinitions || {};\r
4164         swagger.securityDefinitions[name] = securityDefinition;\r
4165       }\r
4166     }\r
4167   }\r
4168 };\r
4169 \r
4170 SwaggerSpecConverter.prototype.apiInfo = function(obj, swagger) {\r
4171   // info section\r
4172   if(obj.info) {\r
4173     var info = obj.info;\r
4174     swagger.info = {};\r
4175 \r
4176     if(info.contact) {\r
4177       swagger.info.contact = {};\r
4178       swagger.info.contact.email = info.contact;\r
4179     }\r
4180     if(info.description) {\r
4181       swagger.info.description = info.description;\r
4182     }\r
4183     if(info.title) {\r
4184       swagger.info.title = info.title;\r
4185     }\r
4186     if(info.termsOfServiceUrl) {\r
4187       swagger.info.termsOfService = info.termsOfServiceUrl;\r
4188     }\r
4189     if(info.license || info.licenseUrl) {\r
4190       swagger.license = {};\r
4191       if(info.license) {\r
4192         swagger.license.name = info.license;\r
4193       }\r
4194       if(info.licenseUrl) {\r
4195         swagger.license.url = info.licenseUrl;\r
4196       }\r
4197     }\r
4198   }\r
4199   else {\r
4200     this.warnings.push('missing info section');\r
4201   }\r
4202 };\r
4203 \r
4204 SwaggerSpecConverter.prototype.finish = function (callback, obj) {\r
4205   callback(obj);\r
4206 };\r
4207 \r
4208 },{"./http":5,"lodash-compat/lang/isObject":146}],9:[function(require,module,exports){\r
4209 'use strict';\r
4210 \r
4211 var log = require('../helpers').log;\r
4212 var _ = {\r
4213   isPlainObject: require('lodash-compat/lang/isPlainObject'),\r
4214   isString: require('lodash-compat/lang/isString'),\r
4215 };\r
4216 \r
4217 var SchemaMarkup = require('../schema-markup.js');\r
4218 var jsyaml = require('js-yaml');\r
4219 \r
4220 var Model = module.exports = function (name, definition, models, modelPropertyMacro) {\r
4221   this.definition = definition || {};\r
4222   this.isArray = definition.type === 'array';\r
4223   this.models = models || {};\r
4224   this.name = name || definition.title || 'Inline Model';\r
4225   this.modelPropertyMacro = modelPropertyMacro || function (property) {\r
4226     return property.default;\r
4227   };\r
4228 \r
4229   return this;\r
4230 };\r
4231 \r
4232 // Note!  This function will be removed in 2.2.x!\r
4233 Model.prototype.createJSONSample = Model.prototype.getSampleValue = function (modelsToIgnore) {\r
4234   modelsToIgnore = modelsToIgnore || {};\r
4235 \r
4236   modelsToIgnore[this.name] = this;\r
4237 \r
4238   // Response support\r
4239   if (this.examples && _.isPlainObject(this.examples) && this.examples['application/json']) {\r
4240     this.definition.example = this.examples['application/json'];\r
4241 \r
4242     if (_.isString(this.definition.example)) {\r
4243       this.definition.example = jsyaml.safeLoad(this.definition.example);\r
4244     }\r
4245   } else if (!this.definition.example) {\r
4246     this.definition.example = this.examples;\r
4247   }\r
4248 \r
4249   return SchemaMarkup.schemaToJSON(this.definition, this.models, modelsToIgnore, this.modelPropertyMacro);\r
4250 };\r
4251 \r
4252 Model.prototype.getMockSignature = function () {\r
4253   return SchemaMarkup.schemaToHTML(this.name, this.definition, this.models, this.modelPropertyMacro);\r
4254 };\r
4255 \r
4256 },{"../helpers":4,"../schema-markup.js":7,"js-yaml":21,"lodash-compat/lang/isPlainObject":147,"lodash-compat/lang/isString":148}],10:[function(require,module,exports){\r
4257 'use strict';\r
4258 \r
4259 var _ = {\r
4260   cloneDeep: require('lodash-compat/lang/cloneDeep'),\r
4261   isUndefined: require('lodash-compat/lang/isUndefined'),\r
4262   isEmpty: require('lodash-compat/lang/isEmpty'),\r
4263   isObject: require('lodash-compat/lang/isObject')\r
4264 };\r
4265 var helpers = require('../helpers');\r
4266 var Model = require('./model');\r
4267 var SwaggerHttp = require('../http');\r
4268 var Q = require('q');\r
4269 \r
4270 var Operation = module.exports = function (parent, scheme, operationId, httpMethod, path, args, definitions, models, clientAuthorizations) {\r
4271   var errors = [];\r
4272 \r
4273   parent = parent || {};\r
4274   args = args || {};\r
4275 \r
4276   if(parent && parent.options) {\r
4277     this.client = parent.options.client || null;\r
4278     this.requestInterceptor = parent.options.requestInterceptor || null;\r
4279     this.responseInterceptor = parent.options.responseInterceptor || null;\r
4280   }\r
4281   this.authorizations = args.security;\r
4282   this.basePath = parent.basePath || '/';\r
4283   this.clientAuthorizations = clientAuthorizations;\r
4284   this.consumes = args.consumes || parent.consumes || ['application/json'];\r
4285   this.produces = args.produces || parent.produces || ['application/json'];\r
4286   this.deprecated = args.deprecated;\r
4287   this.description = args.description;\r
4288   this.host = parent.host || 'localhost';\r
4289   this.method = (httpMethod || errors.push('Operation ' + operationId + ' is missing method.'));\r
4290   this.models = models || {};\r
4291   this.nickname = (operationId || errors.push('Operations must have a nickname.'));\r
4292   this.operation = args;\r
4293   this.operations = {};\r
4294   this.parameters = args !== null ? (args.parameters || []) : {};\r
4295   this.parent = parent;\r
4296   this.path = (path || errors.push('Operation ' + this.nickname + ' is missing path.'));\r
4297   this.responses = (args.responses || {});\r
4298   this.scheme = scheme || parent.scheme || 'http';\r
4299   this.schemes = args.schemes || parent.schemes;\r
4300   this.security = args.security || parent.security;\r
4301   this.summary = args.summary || '';\r
4302   this.type = null;\r
4303   this.useJQuery = parent.useJQuery;\r
4304   this.enableCookies = parent.enableCookies;\r
4305   this.parameterMacro = parent.parameterMacro || function (operation, parameter) {\r
4306     return parameter.default;\r
4307   };\r
4308 \r
4309   this.inlineModels = [];\r
4310 \r
4311   if (typeof this.deprecated === 'string') {\r
4312     switch(this.deprecated.toLowerCase()) {\r
4313       case 'true': case 'yes': case '1': {\r
4314         this.deprecated = true;\r
4315         break;\r
4316       }\r
4317 \r
4318       case 'false': case 'no': case '0': case null: {\r
4319         this.deprecated = false;\r
4320         break;\r
4321       }\r
4322 \r
4323       default: this.deprecated = Boolean(this.deprecated);\r
4324     }\r
4325   }\r
4326 \r
4327   var i, model;\r
4328 \r
4329   if (definitions) {\r
4330     // add to global models\r
4331     var key;\r
4332 \r
4333     for (key in definitions) {\r
4334       model = new Model(key, definitions[key], this.models, parent.modelPropertyMacro);\r
4335 \r
4336       if (model) {\r
4337         this.models[key] = model;\r
4338       }\r
4339     }\r
4340   }\r
4341   else {\r
4342     definitions = {};\r
4343   }\r
4344 \r
4345   for (i = 0; i < this.parameters.length; i++) {\r
4346     var param = this.parameters[i];\r
4347 \r
4348     // Allow macro to set the default value\r
4349     param.default = this.parameterMacro(this, param);\r
4350 \r
4351     if (param.type === 'array') {\r
4352       param.isList = true;\r
4353       param.allowMultiple = true;\r
4354       // the enum can be defined at the items level\r
4355       //if (param.items && param.items.enum) {\r
4356       //  param['enum'] = param.items.enum;\r
4357       //}\r
4358     }\r
4359 \r
4360     var innerType = this.getType(param);\r
4361 \r
4362     if (innerType && innerType.toString().toLowerCase() === 'boolean') {\r
4363       param.allowableValues = {};\r
4364       param.isList = true;\r
4365       param['enum'] = [true, false]; // use actual primitives\r
4366     }\r
4367 \r
4368     if(typeof param['x-example'] !== 'undefined') {\r
4369       var d = param['x-example'];\r
4370       param.default = d;\r
4371     }\r
4372     if(param['x-examples']) {\r
4373       var d = param['x-examples'].default;\r
4374       if(typeof d !== 'undefined') {\r
4375         param.default = d;\r
4376       }\r
4377     }\r
4378 \r
4379     var enumValues = param['enum'] || (param.items && param.items['enum']);\r
4380 \r
4381     if (typeof enumValues !== 'undefined') {\r
4382       var id;\r
4383 \r
4384       param.allowableValues = {};\r
4385       param.allowableValues.values = [];\r
4386       param.allowableValues.descriptiveValues = [];\r
4387 \r
4388       for (id = 0; id < enumValues.length; id++) {\r
4389         var value = enumValues[id];\r
4390         var isDefault = (value === param.default || value+'' === param.default);\r
4391 \r
4392         param.allowableValues.values.push(value);\r
4393         // Always have string for descriptive values....\r
4394         param.allowableValues.descriptiveValues.push({value : value+'', isDefault: isDefault});\r
4395       }\r
4396     }\r
4397 \r
4398     if (param.type === 'array') {\r
4399       innerType = [innerType];\r
4400 \r
4401       if (typeof param.allowableValues === 'undefined') {\r
4402         // can't show as a list if no values to select from\r
4403         delete param.isList;\r
4404         delete param.allowMultiple;\r
4405       }\r
4406     }\r
4407 \r
4408     param.modelSignature = {type: innerType, definitions: this.models};\r
4409     param.signature = this.getModelSignature(innerType, this.models).toString();\r
4410     param.sampleJSON = this.getModelSampleJSON(innerType, this.models);\r
4411     param.responseClassSignature = param.signature;\r
4412   }\r
4413 \r
4414   var defaultResponseCode, response, responses = this.responses;\r
4415 \r
4416   if (responses['200']) {\r
4417     response = responses['200'];\r
4418     defaultResponseCode = '200';\r
4419   } else if (responses['201']) {\r
4420     response = responses['201'];\r
4421     defaultResponseCode = '201';\r
4422   } else if (responses['202']) {\r
4423     response = responses['202'];\r
4424     defaultResponseCode = '202';\r
4425   } else if (responses['203']) {\r
4426     response = responses['203'];\r
4427     defaultResponseCode = '203';\r
4428   } else if (responses['204']) {\r
4429     response = responses['204'];\r
4430     defaultResponseCode = '204';\r
4431   } else if (responses['205']) {\r
4432     response = responses['205'];\r
4433     defaultResponseCode = '205';\r
4434   } else if (responses['206']) {\r
4435     response = responses['206'];\r
4436     defaultResponseCode = '206';\r
4437   } else if (responses['default']) {\r
4438     response = responses['default'];\r
4439     defaultResponseCode = 'default';\r
4440   }\r
4441 \r
4442   if (response && response.schema) {\r
4443     var resolvedModel = this.resolveModel(response.schema, definitions);\r
4444     var successResponse;\r
4445 \r
4446     delete responses[defaultResponseCode];\r
4447 \r
4448     if (resolvedModel) {\r
4449       this.successResponse = {};\r
4450       successResponse = this.successResponse[defaultResponseCode] = resolvedModel;\r
4451     } else if (!response.schema.type || response.schema.type === 'object' || response.schema.type === 'array') {\r
4452       // Inline model\r
4453       this.successResponse = {};\r
4454       successResponse = this.successResponse[defaultResponseCode] = new Model(undefined, response.schema || {}, this.models, parent.modelPropertyMacro);\r
4455     } else {\r
4456       // Primitive\r
4457       this.successResponse = {};\r
4458       successResponse = this.successResponse[defaultResponseCode] = response.schema;\r
4459     }\r
4460 \r
4461     if (successResponse) {\r
4462       // Attach response properties\r
4463       if (response.description) {\r
4464         successResponse.description = response.description;\r
4465       }\r
4466 \r
4467       if (response.examples) {\r
4468         successResponse.examples = response.examples;\r
4469       }\r
4470 \r
4471       if (response.headers) {\r
4472         successResponse.headers = response.headers;\r
4473       }\r
4474     }\r
4475 \r
4476     this.type = response;\r
4477   }\r
4478 \r
4479   if (errors.length > 0) {\r
4480     if (this.resource && this.resource.api && this.resource.api.fail) {\r
4481       this.resource.api.fail(errors);\r
4482     }\r
4483   }\r
4484 \r
4485   return this;\r
4486 };\r
4487 \r
4488 Operation.prototype.isDefaultArrayItemValue = function(value, param) {\r
4489   if (param.default && Array.isArray(param.default)) {\r
4490     return param.default.indexOf(value) !== -1;\r
4491   }\r
4492   return value === param.default;\r
4493 };\r
4494 \r
4495 Operation.prototype.getType = function (param) {\r
4496   var type = param.type;\r
4497   var format = param.format;\r
4498   var isArray = false;\r
4499   var str;\r
4500 \r
4501   if (type === 'integer' && format === 'int32') {\r
4502     str = 'integer';\r
4503   } else if (type === 'integer' && format === 'int64') {\r
4504     str = 'long';\r
4505   } else if (type === 'integer') {\r
4506     str = 'integer';\r
4507   } else if (type === 'string') {\r
4508     if (format === 'date-time') {\r
4509       str = 'date-time';\r
4510     } else if (format === 'date') {\r
4511       str = 'date';\r
4512     } else {\r
4513       str = 'string';\r
4514     }\r
4515   } else if (type === 'number' && format === 'float') {\r
4516     str = 'float';\r
4517   } else if (type === 'number' && format === 'double') {\r
4518     str = 'double';\r
4519   } else if (type === 'number') {\r
4520     str = 'double';\r
4521   } else if (type === 'boolean') {\r
4522     str = 'boolean';\r
4523   } else if (type === 'array') {\r
4524     isArray = true;\r
4525 \r
4526     if (param.items) {\r
4527       str = this.getType(param.items);\r
4528     }\r
4529   } else if (type === 'file') {\r
4530     str = 'file';\r
4531   }\r
4532 \r
4533   if (param.$ref) {\r
4534     str = helpers.simpleRef(param.$ref);\r
4535   }\r
4536 \r
4537   var schema = param.schema;\r
4538 \r
4539   if (schema) {\r
4540     var ref = schema.$ref;\r
4541 \r
4542     if (ref) {\r
4543       ref = helpers.simpleRef(ref);\r
4544 \r
4545       if (isArray) {\r
4546         return [ ref ];\r
4547       } else {\r
4548         return ref;\r
4549       }\r
4550     } else {\r
4551       // If inline schema, we add it our interal hash -> which gives us it's ID (int)\r
4552       if(schema.type === 'object') {\r
4553         return this.addInlineModel(schema);\r
4554       }\r
4555       return this.getType(schema);\r
4556     }\r
4557   }\r
4558   if (isArray) {\r
4559     return [ str ];\r
4560   } else {\r
4561     return str;\r
4562   }\r
4563 };\r
4564 \r
4565 /**\r
4566  * adds an inline schema (model) to a hash, where we can ref it later\r
4567  * @param {object} schema a schema\r
4568  * @return {number} the ID of the schema being added, or null\r
4569  **/\r
4570 Operation.prototype.addInlineModel = function (schema) {\r
4571   var len = this.inlineModels.length;\r
4572   var model = this.resolveModel(schema, {});\r
4573   if(model) {\r
4574     this.inlineModels.push(model);\r
4575     return 'Inline Model '+len; // return string ref of the inline model (used with #getInlineModel)\r
4576   }\r
4577   return null; // report errors?\r
4578 };\r
4579 \r
4580 /**\r
4581  * gets the internal ref to an inline model\r
4582  * @param {string} inline_str a string reference to an inline model\r
4583  * @return {Model} the model being referenced. Or null\r
4584  **/\r
4585 Operation.prototype.getInlineModel = function(inlineStr) {\r
4586   if(/^Inline Model \d+$/.test(inlineStr)) {\r
4587     var id = parseInt(inlineStr.substr('Inline Model'.length).trim(),10); //\r
4588     var model = this.inlineModels[id];\r
4589     return model;\r
4590   }\r
4591   // I'm returning null here, should I rather throw an error?\r
4592   return null;\r
4593 };\r
4594 \r
4595 Operation.prototype.resolveModel = function (schema, definitions) {\r
4596   if (typeof schema.$ref !== 'undefined') {\r
4597     var ref = schema.$ref;\r
4598 \r
4599     if (ref.indexOf('#/definitions/') === 0) {\r
4600       ref = ref.substring('#/definitions/'.length);\r
4601     }\r
4602 \r
4603     if (definitions[ref]) {\r
4604       return new Model(ref, definitions[ref], this.models, this.parent.modelPropertyMacro);\r
4605     }\r
4606   // schema must at least be an object to get resolved to an inline Model\r
4607   } else if (schema && typeof schema === 'object' &&\r
4608             (schema.type === 'object' || _.isUndefined(schema.type))) {\r
4609     return new Model(undefined, schema, this.models, this.parent.modelPropertyMacro);\r
4610   }\r
4611 \r
4612   return null;\r
4613 };\r
4614 \r
4615 Operation.prototype.help = function (dontPrint) {\r
4616   var out = this.nickname + ': ' + this.summary + '\n';\r
4617 \r
4618   for (var i = 0; i < this.parameters.length; i++) {\r
4619     var param = this.parameters[i];\r
4620     var typeInfo = param.signature;\r
4621 \r
4622     out += '\n  * ' + param.name + ' (' + typeInfo + '): ' + param.description;\r
4623   }\r
4624 \r
4625   if (typeof dontPrint === 'undefined') {\r
4626     helpers.log(out);\r
4627   }\r
4628 \r
4629   return out;\r
4630 };\r
4631 \r
4632 Operation.prototype.getModelSignature = function (type, definitions) {\r
4633   var isPrimitive, listType;\r
4634 \r
4635   if (type instanceof Array) {\r
4636     listType = true;\r
4637     type = type[0];\r
4638   }\r
4639 \r
4640   // Convert undefined to string of 'undefined'\r
4641   if (typeof type === 'undefined') {\r
4642     type = 'undefined';\r
4643     isPrimitive = true;\r
4644 \r
4645   } else if (definitions[type]){\r
4646     // a model def exists?\r
4647     type = definitions[type]; /* Model */\r
4648     isPrimitive = false;\r
4649 \r
4650   } else if (this.getInlineModel(type)) {\r
4651     type = this.getInlineModel(type); /* Model */\r
4652     isPrimitive = false;\r
4653 \r
4654   } else {\r
4655     // We default to primitive\r
4656     isPrimitive = true;\r
4657   }\r
4658 \r
4659   if (isPrimitive) {\r
4660     if (listType) {\r
4661       return 'Array[' + type + ']';\r
4662     } else {\r
4663       return type.toString();\r
4664     }\r
4665   } else {\r
4666     if (listType) {\r
4667       return 'Array[' + type.getMockSignature() + ']';\r
4668     } else {\r
4669       return type.getMockSignature();\r
4670     }\r
4671   }\r
4672 };\r
4673 \r
4674 Operation.prototype.supportHeaderParams = function () {\r
4675   return true;\r
4676 };\r
4677 \r
4678 Operation.prototype.supportedSubmitMethods = function () {\r
4679   return this.parent.supportedSubmitMethods;\r
4680 };\r
4681 \r
4682 Operation.prototype.getHeaderParams = function (args) {\r
4683   var headers = this.setContentTypes(args, {});\r
4684 \r
4685   for (var i = 0; i < this.parameters.length; i++) {\r
4686     var param = this.parameters[i];\r
4687 \r
4688     if (typeof args[param.name] !== 'undefined') {\r
4689       if (param.in === 'header') {\r
4690         var value = args[param.name];\r
4691 \r
4692         if (Array.isArray(value)) {\r
4693           value = value.toString();\r
4694         }\r
4695 \r
4696         headers[param.name] = value;\r
4697       }\r
4698     }\r
4699   }\r
4700 \r
4701   return headers;\r
4702 };\r
4703 \r
4704 Operation.prototype.urlify = function (args) {\r
4705   var formParams = {};\r
4706   var requestUrl = this.path;\r
4707   var querystring = ''; // grab params from the args, build the querystring along the way\r
4708 \r
4709   for (var i = 0; i < this.parameters.length; i++) {\r
4710     var param = this.parameters[i];\r
4711 \r
4712     if (typeof args[param.name] !== 'undefined') {\r
4713       if (param.in === 'path') {\r
4714         var reg = new RegExp('\{' + param.name + '\}', 'gi');\r
4715         var value = args[param.name];\r
4716 \r
4717         if (Array.isArray(value)) {\r
4718           value = this.encodePathCollection(param.collectionFormat, param.name, value);\r
4719         } else {\r
4720           value = this.encodePathParam(value);\r
4721         }\r
4722 \r
4723         requestUrl = requestUrl.replace(reg, value);\r
4724       } else if (param.in === 'query' && typeof args[param.name] !== 'undefined') {\r
4725         if (querystring === '') {\r
4726           querystring += '?';\r
4727         } else {\r
4728           querystring += '&';\r
4729         }\r
4730 \r
4731         if (typeof param.collectionFormat !== 'undefined') {\r
4732           var qp = args[param.name];\r
4733 \r
4734           if (Array.isArray(qp)) {\r
4735             querystring += this.encodeQueryCollection(param.collectionFormat, param.name, qp);\r
4736           } else {\r
4737             querystring += this.encodeQueryParam(param.name) + '=' + this.encodeQueryParam(args[param.name]);\r
4738           }\r
4739         } else {\r
4740           querystring += this.encodeQueryParam(param.name) + '=' + this.encodeQueryParam(args[param.name]);\r
4741         }\r
4742       } else if (param.in === 'formData') {\r
4743         formParams[param.name] = args[param.name];\r
4744       }\r
4745     }\r
4746   }\r
4747   var url = this.scheme + '://' + this.host;\r
4748 \r
4749   if (this.basePath !== '/') {\r
4750     url += this.basePath;\r
4751   }\r
4752   return url + requestUrl + querystring;\r
4753 };\r
4754 \r
4755 Operation.prototype.getMissingParams = function (args) {\r
4756   var missingParams = []; // check required params, track the ones that are missing\r
4757   var i;\r
4758 \r
4759   for (i = 0; i < this.parameters.length; i++) {\r
4760     var param = this.parameters[i];\r
4761 \r
4762     if (param.required === true) {\r
4763       if (typeof args[param.name] === 'undefined') {\r
4764         missingParams = param.name;\r
4765       }\r
4766     }\r
4767   }\r
4768 \r
4769   return missingParams;\r
4770 };\r
4771 \r
4772 Operation.prototype.getBody = function (headers, args, opts) {\r
4773   var formParams = {}, hasFormParams, body, key, value, hasBody = false;\r
4774 \r
4775   // look at each param and put form params in an object\r
4776   for (var i = 0; i < this.parameters.length; i++) {\r
4777     var param = this.parameters[i];\r
4778     if (typeof args[param.name] !== 'undefined') {\r
4779       if (param.in === 'body') {\r
4780         body = args[param.name];\r
4781       } else if (param.in === 'formData') {\r
4782         formParams[param.name] = args[param.name];\r
4783         hasFormParams = true;\r
4784       }\r
4785     }\r
4786     else {\r
4787       if(param.in === 'body') {\r
4788         hasBody = true;\r
4789       }\r
4790     }\r
4791   }\r
4792 \r
4793   // if body is null and hasBody is true, AND a JSON body is requested, send empty {}\r
4794   if(hasBody && typeof body === 'undefined') {\r
4795     var contentType = headers['Content-Type'];\r
4796     if(contentType && contentType.indexOf('application/json') === 0) {\r
4797       body = '{}';\r
4798     }\r
4799   }\r
4800 \r
4801   var isMultiPart = false;\r
4802   if(headers['Content-Type'] && headers['Content-Type'].indexOf('multipart/form-data') >= 0) {\r
4803     isMultiPart = true;\r
4804   }\r
4805 \r
4806   // handle form params\r
4807   if (hasFormParams && !isMultiPart) {\r
4808     var encoded = '';\r
4809 \r
4810     for (key in formParams) {\r
4811       value = formParams[key];\r
4812 \r
4813       if (typeof value !== 'undefined') {\r
4814         if (encoded !== '') {\r
4815           encoded += '&';\r
4816         }\r
4817 \r
4818         encoded += encodeURIComponent(key) + '=' + encodeURIComponent(value);\r
4819       }\r
4820     }\r
4821 \r
4822     body = encoded;\r
4823   } else if (isMultiPart) {\r
4824     if (opts.useJQuery) {\r
4825       var bodyParam = new FormData();\r
4826 \r
4827       bodyParam.type = 'formData';\r
4828 \r
4829       for (key in formParams) {\r
4830         value = args[key];\r
4831 \r
4832         if (typeof value !== 'undefined') {\r
4833           // required for jquery file upload\r
4834           if (value.type === 'file' && value.value) {\r
4835             delete headers['Content-Type'];\r
4836 \r
4837             bodyParam.append(key, value.value);\r
4838           } else {\r
4839             bodyParam.append(key, value);\r
4840           }\r
4841         }\r
4842       }\r
4843 \r
4844       body = bodyParam;\r
4845     }\r
4846   }\r
4847 \r
4848   return body;\r
4849 };\r
4850 \r
4851 /**\r
4852  * gets sample response for a single operation\r
4853  **/\r
4854 Operation.prototype.getModelSampleJSON = function (type, models) {\r
4855   var listType, sampleJson, innerType;\r
4856   models = models || {};\r
4857 \r
4858   listType = (type instanceof Array);\r
4859   innerType = listType ? type[0] : type;\r
4860 \r
4861   if(models[innerType]) {\r
4862     sampleJson = models[innerType].createJSONSample();\r
4863   } else if (this.getInlineModel(innerType)){\r
4864     sampleJson = this.getInlineModel(innerType).createJSONSample(); // may return null, if type isn't correct\r
4865   }\r
4866 \r
4867 \r
4868   if (sampleJson) {\r
4869     sampleJson = listType ? [sampleJson] : sampleJson;\r
4870 \r
4871     if (typeof sampleJson === 'string') {\r
4872       return sampleJson;\r
4873     } else if (_.isObject(sampleJson)) {\r
4874       var t = sampleJson;\r
4875 \r
4876       if (sampleJson instanceof Array && sampleJson.length > 0) {\r
4877         t = sampleJson[0];\r
4878       }\r
4879 \r
4880       if (t.nodeName && typeof t === 'Node') {\r
4881         var xmlString = new XMLSerializer().serializeToString(t);\r
4882 \r
4883         return this.formatXml(xmlString);\r
4884       } else {\r
4885         return JSON.stringify(sampleJson, null, 2);\r
4886       }\r
4887     } else {\r
4888       return sampleJson;\r
4889     }\r
4890   }\r
4891 };\r
4892 \r
4893 /**\r
4894  * legacy binding\r
4895  **/\r
4896 Operation.prototype.do = function (args, opts, callback, error, parent) {\r
4897   return this.execute(args, opts, callback, error, parent);\r
4898 };\r
4899 \r
4900 /**\r
4901  * executes an operation\r
4902  **/\r
4903 Operation.prototype.execute = function (arg1, arg2, arg3, arg4, parent) {\r
4904   var args = arg1 || {};\r
4905   var opts = {}, success, error, deferred;\r
4906 \r
4907   if (_.isObject(arg2)) {\r
4908     opts = arg2;\r
4909     success = arg3;\r
4910     error = arg4;\r
4911   }\r
4912 \r
4913   if(this.client) {\r
4914     opts.client = this.client;\r
4915   }\r
4916 \r
4917   // add the request interceptor from parent, if none sent from client\r
4918   if(!opts.requestInterceptor && this.requestInterceptor ) {\r
4919     opts.requestInterceptor = this.requestInterceptor ;\r
4920   }\r
4921 \r
4922   if(!opts.responseInterceptor && this.responseInterceptor) {\r
4923     opts.responseInterceptor = this.responseInterceptor;\r
4924   }\r
4925 \r
4926   if (typeof arg2 === 'function') {\r
4927     success = arg2;\r
4928     error = arg3;\r
4929   }\r
4930 \r
4931   if (this.parent.usePromise) {\r
4932     deferred = Q.defer();\r
4933   } else {\r
4934     success = (success || this.parent.defaultSuccessCallback || helpers.log);\r
4935     error = (error || this.parent.defaultErrorCallback || helpers.log);\r
4936   }\r
4937 \r
4938 \r
4939   if (typeof opts.useJQuery === 'undefined') {\r
4940     opts.useJQuery = this.useJQuery;\r
4941   }\r
4942 \r
4943   if (typeof opts.enableCookies === 'undefined') {\r
4944     opts.enableCookies = this.enableCookies;\r
4945   }\r
4946 \r
4947   var missingParams = this.getMissingParams(args);\r
4948 \r
4949   if (missingParams.length > 0) {\r
4950     var message = 'missing required params: ' + missingParams;\r
4951 \r
4952     helpers.fail(message);\r
4953 \r
4954     if (this.parent.usePromise) {\r
4955       deferred.reject(message);\r
4956       return deferred.promise;\r
4957     } else {\r
4958       error(message, parent);\r
4959       return {};\r
4960     }\r
4961   }\r
4962 \r
4963   var allHeaders = this.getHeaderParams(args);\r
4964   var contentTypeHeaders = this.setContentTypes(args, opts);\r
4965   var headers = {}, attrname;\r
4966 \r
4967   for (attrname in allHeaders) { headers[attrname] = allHeaders[attrname]; }\r
4968   for (attrname in contentTypeHeaders) { headers[attrname] = contentTypeHeaders[attrname]; }\r
4969 \r
4970   var body = this.getBody(contentTypeHeaders, args, opts);\r
4971   var url = this.urlify(args);\r
4972 \r
4973   if(url.indexOf('.{format}') > 0) {\r
4974     if(headers) {\r
4975       var format = headers.Accept || headers.accept;\r
4976       if(format && format.indexOf('json') > 0) {\r
4977         url = url.replace('.{format}', '.json');\r
4978       }\r
4979       else if(format && format.indexOf('xml') > 0) {\r
4980         url = url.replace('.{format}', '.xml');\r
4981       }\r
4982     }\r
4983   }\r
4984 \r
4985   var obj = {\r
4986     url: url,\r
4987     method: this.method.toUpperCase(),\r
4988     body: body,\r
4989     enableCookies: opts.enableCookies,\r
4990     useJQuery: opts.useJQuery,\r
4991     deferred: deferred,\r
4992     headers: headers,\r
4993     clientAuthorizations: opts.clientAuthorizations,\r
4994     on: {\r
4995       response: function (response) {\r
4996         if (deferred) {\r
4997           deferred.resolve(response);\r
4998           return deferred.promise;\r
4999         } else {\r
5000           return success(response, parent);\r
5001         }\r
5002       },\r
5003       error: function (response) {\r
5004         if (deferred) {\r
5005           deferred.reject(response);\r
5006           return deferred.promise;\r
5007         } else {\r
5008           return error(response, parent);\r
5009         }\r
5010       }\r
5011     }\r
5012   };\r
5013 \r
5014   this.clientAuthorizations.apply(obj, this.operation.security);\r
5015   if (opts.mock === true) {\r
5016     return obj;\r
5017   } else {\r
5018     return new SwaggerHttp().execute(obj, opts);\r
5019   }\r
5020 };\r
5021 \r
5022 function itemByPriority(col, itemPriority) {\r
5023 \r
5024   // No priorities? return first...\r
5025   if(_.isEmpty(itemPriority)) {\r
5026     return col[0];\r
5027   }\r
5028 \r
5029   for (var i = 0, len = itemPriority.length; i < len; i++) {\r
5030     if(col.indexOf(itemPriority[i]) > -1) {\r
5031       return itemPriority[i];\r
5032     }\r
5033   }\r
5034 \r
5035   // Otherwise return first\r
5036   return col[0];\r
5037 }\r
5038 \r
5039 Operation.prototype.setContentTypes = function (args, opts) {\r
5040   // default type\r
5041   var allDefinedParams = this.parameters;\r
5042   var body;\r
5043   var consumes = args.parameterContentType || itemByPriority(this.consumes, ['application/json', 'application/yaml']);\r
5044   var accepts = opts.responseContentType || itemByPriority(this.produces, ['application/json', 'application/yaml']);\r
5045   var definedFileParams = [];\r
5046   var definedFormParams = [];\r
5047   var headers = {};\r
5048   var i;\r
5049 \r
5050   // get params from the operation and set them in definedFileParams, definedFormParams, headers\r
5051   for (i = 0; i < allDefinedParams.length; i++) {\r
5052     var param = allDefinedParams[i];\r
5053 \r
5054     if (param.in === 'formData') {\r
5055       if (param.type === 'file') {\r
5056         definedFileParams.push(param);\r
5057       } else {\r
5058         definedFormParams.push(param);\r
5059       }\r
5060     } else if (param.in === 'header' && opts) {\r
5061       var key = param.name;\r
5062       var headerValue = opts[param.name];\r
5063 \r
5064       if (typeof opts[param.name] !== 'undefined') {\r
5065         headers[key] = headerValue;\r
5066       }\r
5067     } else if (param.in === 'body' && typeof args[param.name] !== 'undefined') {\r
5068       body = args[param.name];\r
5069     }\r
5070   }\r
5071 \r
5072   // if there's a body, need to set the consumes header via requestContentType\r
5073   if (this.method === 'post' || this.method === 'put' || this.method === 'patch' ||\r
5074       ((this.method === 'delete' || this.method === 'get') && body) ) {\r
5075     if (opts.requestContentType) {\r
5076       consumes = opts.requestContentType;\r
5077     }\r
5078     // if any form params, content type must be set\r
5079     if (definedFormParams.length > 0) {\r
5080       if (opts.requestContentType) {             // override if set\r
5081         consumes = opts.requestContentType;\r
5082       } else if (definedFileParams.length > 0) { // if a file, must be multipart/form-data\r
5083         consumes = 'multipart/form-data';\r
5084       } else {                                   // default to x-www-from-urlencoded\r
5085         consumes = 'application/x-www-form-urlencoded';\r
5086       }\r
5087     }\r
5088   }\r
5089   else {\r
5090     consumes = null;\r
5091   }\r
5092 \r
5093   if (consumes && this.consumes) {\r
5094     if (this.consumes.indexOf(consumes) === -1) {\r
5095       helpers.log('server doesn\'t consume ' + consumes + ', try ' + JSON.stringify(this.consumes));\r
5096     }\r
5097   }\r
5098 \r
5099   if (!this.matchesAccept(accepts)) {\r
5100     helpers.log('server can\'t produce ' + accepts);\r
5101   }\r
5102 \r
5103   if ((consumes && body !== '') || (consumes === 'application/x-www-form-urlencoded')) {\r
5104     headers['Content-Type'] = consumes;\r
5105   }\r
5106 \r
5107   if (accepts) {\r
5108     headers.Accept = accepts;\r
5109   }\r
5110 \r
5111   return headers;\r
5112 };\r
5113 \r
5114 /**\r
5115  * Returns true if the request accepts header matches anything in this.produces.\r
5116  *  If this.produces contains * / *, ignore the accept header.\r
5117  * @param {string=} accepts The client request accept header.\r
5118  * @return {boolean}\r
5119  */\r
5120 Operation.prototype.matchesAccept = function(accepts) {\r
5121   // no accepts or produces, no problem!\r
5122   if (!accepts || !this.produces) {\r
5123     return true;\r
5124   }\r
5125   return this.produces.indexOf(accepts) !== -1 || this.produces.indexOf('*/*') !== -1;\r
5126 };\r
5127 \r
5128 Operation.prototype.asCurl = function (args1, args2) {\r
5129   var opts = {mock: true};\r
5130   if (typeof args2 === 'object') {\r
5131     for (var argKey in args2) {\r
5132       opts[argKey] = args2[argKey];\r
5133     }\r
5134   }\r
5135   var obj = this.execute(args1, opts);\r
5136 \r
5137   this.clientAuthorizations.apply(obj, this.operation.security);\r
5138 \r
5139   var results = [];\r
5140 \r
5141   results.push('-X ' + this.method.toUpperCase());\r
5142 \r
5143   if (typeof obj.headers !== 'undefined') {\r
5144     var key;\r
5145 \r
5146     for (key in obj.headers) {\r
5147       var value = obj.headers[key];\r
5148       if(typeof value === 'string'){\r
5149         value = value.replace(/\'/g, '\\u0027');\r
5150       }\r
5151       results.push('--header \'' + key + ': ' + value + '\'');\r
5152     }\r
5153   }\r
5154 \r
5155   if (obj.body) {\r
5156     var body;\r
5157 \r
5158     if (_.isObject(obj.body)) {\r
5159       body = JSON.stringify(obj.body);\r
5160     } else {\r
5161       body = obj.body;\r
5162     }\r
5163 \r
5164     results.push('-d \'' + body.replace(/\'/g, '\\u0027') + '\'');\r
5165   }\r
5166 \r
5167   return 'curl ' + (results.join(' ')) + ' \'' + obj.url + '\'';\r
5168 };\r
5169 \r
5170 Operation.prototype.encodePathCollection = function (type, name, value) {\r
5171   var encoded = '';\r
5172   var i;\r
5173   var separator = '';\r
5174 \r
5175   if (type === 'ssv') {\r
5176     separator = '%20';\r
5177   } else if (type === 'tsv') {\r
5178     separator = '\\t';\r
5179   } else if (type === 'pipes') {\r
5180     separator = '|';\r
5181   } else {\r
5182     separator = ',';\r
5183   }\r
5184 \r
5185   for (i = 0; i < value.length; i++) {\r
5186     if (i === 0) {\r
5187       encoded = this.encodeQueryParam(value[i]);\r
5188     } else {\r
5189       encoded += separator + this.encodeQueryParam(value[i]);\r
5190     }\r
5191   }\r
5192 \r
5193   return encoded;\r
5194 };\r
5195 \r
5196 Operation.prototype.encodeQueryCollection = function (type, name, value) {\r
5197   var encoded = '';\r
5198   var i;\r
5199 \r
5200   if (type === 'default' || type === 'multi') {\r
5201     for (i = 0; i < value.length; i++) {\r
5202       if (i > 0) {encoded += '&';}\r
5203 \r
5204       encoded += this.encodeQueryParam(name) + '=' + this.encodeQueryParam(value[i]);\r
5205     }\r
5206   } else {\r
5207     var separator = '';\r
5208 \r
5209     if (type === 'csv') {\r
5210       separator = ',';\r
5211     } else if (type === 'ssv') {\r
5212       separator = '%20';\r
5213     } else if (type === 'tsv') {\r
5214       separator = '\\t';\r
5215     } else if (type === 'pipes') {\r
5216       separator = '|';\r
5217     } else if (type === 'brackets') {\r
5218       for (i = 0; i < value.length; i++) {\r
5219         if (i !== 0) {\r
5220           encoded += '&';\r
5221         }\r
5222 \r
5223         encoded += this.encodeQueryParam(name) + '[]=' + this.encodeQueryParam(value[i]);\r
5224       }\r
5225     }\r
5226 \r
5227     if (separator !== '') {\r
5228       for (i = 0; i < value.length; i++) {\r
5229         if (i === 0) {\r
5230           encoded = this.encodeQueryParam(name) + '=' + this.encodeQueryParam(value[i]);\r
5231         } else {\r
5232           encoded += separator + this.encodeQueryParam(value[i]);\r
5233         }\r
5234       }\r
5235     }\r
5236   }\r
5237 \r
5238   return encoded;\r
5239 };\r
5240 \r
5241 Operation.prototype.encodeQueryParam = function (arg) {\r
5242   return encodeURIComponent(arg);\r
5243 };\r
5244 \r
5245 /**\r
5246  * TODO revisit, might not want to leave '/'\r
5247  **/\r
5248 Operation.prototype.encodePathParam = function (pathParam) {\r
5249   return encodeURIComponent(pathParam);\r
5250 };\r
5251 \r
5252 },{"../helpers":4,"../http":5,"./model":9,"lodash-compat/lang/cloneDeep":140,"lodash-compat/lang/isEmpty":143,"lodash-compat/lang/isObject":146,"lodash-compat/lang/isUndefined":150,"q":159}],11:[function(require,module,exports){\r
5253 'use strict';\r
5254 \r
5255 var OperationGroup = module.exports = function (tag, description, externalDocs, operation) {\r
5256   this.description = description;\r
5257   this.externalDocs = externalDocs;\r
5258   this.name = tag;\r
5259   this.operation = operation;\r
5260   this.operationsArray = [];\r
5261   this.path = tag;\r
5262   this.tag = tag;\r
5263 };\r
5264 \r
5265 OperationGroup.prototype.sort = function () {\r
5266 \r
5267 };\r
5268 \r
5269 \r
5270 },{}],12:[function(require,module,exports){\r
5271 \r
5272 },{}],13:[function(require,module,exports){\r
5273 // shim for using process in browser\r
5274 \r
5275 var process = module.exports = {};\r
5276 var queue = [];\r
5277 var draining = false;\r
5278 \r
5279 function drainQueue() {\r
5280     if (draining) {\r
5281         return;\r
5282     }\r
5283     draining = true;\r
5284     var currentQueue;\r
5285     var len = queue.length;\r
5286     while(len) {\r
5287         currentQueue = queue;\r
5288         queue = [];\r
5289         var i = -1;\r
5290         while (++i < len) {\r
5291             currentQueue[i]();\r
5292         }\r
5293         len = queue.length;\r
5294     }\r
5295     draining = false;\r
5296 }\r
5297 process.nextTick = function (fun) {\r
5298     queue.push(fun);\r
5299     if (!draining) {\r
5300         setTimeout(drainQueue, 0);\r
5301     }\r
5302 };\r
5303 \r
5304 process.title = 'browser';\r
5305 process.browser = true;\r
5306 process.env = {};\r
5307 process.argv = [];\r
5308 process.version = ''; // empty string to avoid regexp issues\r
5309 process.versions = {};\r
5310 \r
5311 function noop() {}\r
5312 \r
5313 process.on = noop;\r
5314 process.addListener = noop;\r
5315 process.once = noop;\r
5316 process.off = noop;\r
5317 process.removeListener = noop;\r
5318 process.removeAllListeners = noop;\r
5319 process.emit = noop;\r
5320 \r
5321 process.binding = function (name) {\r
5322     throw new Error('process.binding is not supported');\r
5323 };\r
5324 \r
5325 // TODO(shtylman)\r
5326 process.cwd = function () { return '/' };\r
5327 process.chdir = function (dir) {\r
5328     throw new Error('process.chdir is not supported');\r
5329 };\r
5330 process.umask = function() { return 0; };\r
5331 \r
5332 },{}],14:[function(require,module,exports){\r
5333 (function (Buffer){\r
5334 (function () {\r
5335   "use strict";\r
5336 \r
5337   function btoa(str) {\r
5338     var buffer\r
5339       ;\r
5340 \r
5341     if (str instanceof Buffer) {\r
5342       buffer = str;\r
5343     } else {\r
5344       buffer = new Buffer(str.toString(), 'binary');\r
5345     }\r
5346 \r
5347     return buffer.toString('base64');\r
5348   }\r
5349 \r
5350   module.exports = btoa;\r
5351 }());\r
5352 \r
5353 }).call(this,require("buffer").Buffer)\r
5354 //# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9idG9hL2luZGV4LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uICgpIHtcbiAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgZnVuY3Rpb24gYnRvYShzdHIpIHtcbiAgICB2YXIgYnVmZmVyXG4gICAgICA7XG5cbiAgICBpZiAoc3RyIGluc3RhbmNlb2YgQnVmZmVyKSB7XG4gICAgICBidWZmZXIgPSBzdHI7XG4gICAgfSBlbHNlIHtcbiAgICAgIGJ1ZmZlciA9IG5ldyBCdWZmZXIoc3RyLnRvU3RyaW5nKCksICdiaW5hcnknKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYnVmZmVyLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgfVxuXG4gIG1vZHVsZS5leHBvcnRzID0gYnRvYTtcbn0oKSk7XG4iXX0=\r
5355 },{"buffer":15}],15:[function(require,module,exports){\r
5356 /*!\r
5357  * The buffer module from node.js, for the browser.\r
5358  *\r
5359  * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>\r
5360  * @license  MIT\r
5361  */\r
5362 \r
5363 var base64 = require('base64-js')\r
5364 var ieee754 = require('ieee754')\r
5365 var isArray = require('is-array')\r
5366 \r
5367 exports.Buffer = Buffer\r
5368 exports.SlowBuffer = SlowBuffer\r
5369 exports.INSPECT_MAX_BYTES = 50\r
5370 Buffer.poolSize = 8192 // not used by this implementation\r
5371 \r
5372 var rootParent = {}\r
5373 \r
5374 /**\r
5375  * If `Buffer.TYPED_ARRAY_SUPPORT`:\r
5376  *   === true    Use Uint8Array implementation (fastest)\r
5377  *   === false   Use Object implementation (most compatible, even IE6)\r
5378  *\r
5379  * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\r
5380  * Opera 11.6+, iOS 4.2+.\r
5381  *\r
5382  * Due to various browser bugs, sometimes the Object implementation will be used even\r
5383  * when the browser supports typed arrays.\r
5384  *\r
5385  * Note:\r
5386  *\r
5387  *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,\r
5388  *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.\r
5389  *\r
5390  *   - Safari 5-7 lacks support for changing the `Object.prototype.constructor` property\r
5391  *     on objects.\r
5392  *\r
5393  *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.\r
5394  *\r
5395  *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of\r
5396  *     incorrect length in some situations.\r
5397 \r
5398  * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they\r
5399  * get the Object implementation, which is slower but behaves correctly.\r
5400  */\r
5401 Buffer.TYPED_ARRAY_SUPPORT = (function () {\r
5402   function Bar () {}\r
5403   try {\r
5404     var arr = new Uint8Array(1)\r
5405     arr.foo = function () { return 42 }\r
5406     arr.constructor = Bar\r
5407     return arr.foo() === 42 && // typed array instances can be augmented\r
5408         arr.constructor === Bar && // constructor can be set\r
5409         typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`\r
5410         arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`\r
5411   } catch (e) {\r
5412     return false\r
5413   }\r
5414 })()\r
5415 \r
5416 function kMaxLength () {\r
5417   return Buffer.TYPED_ARRAY_SUPPORT\r
5418     ? 0x7fffffff\r
5419     : 0x3fffffff\r
5420 }\r
5421 \r
5422 /**\r
5423  * Class: Buffer\r
5424  * =============\r
5425  *\r
5426  * The Buffer constructor returns instances of `Uint8Array` that are augmented\r
5427  * with function properties for all the node `Buffer` API functions. We use\r
5428  * `Uint8Array` so that square bracket notation works as expected -- it returns\r
5429  * a single octet.\r
5430  *\r
5431  * By augmenting the instances, we can avoid modifying the `Uint8Array`\r
5432  * prototype.\r
5433  */\r
5434 function Buffer (arg) {\r
5435   if (!(this instanceof Buffer)) {\r
5436     // Avoid going through an ArgumentsAdaptorTrampoline in the common case.\r
5437     if (arguments.length > 1) return new Buffer(arg, arguments[1])\r
5438     return new Buffer(arg)\r
5439   }\r
5440 \r
5441   this.length = 0\r
5442   this.parent = undefined\r
5443 \r
5444   // Common case.\r
5445   if (typeof arg === 'number') {\r
5446     return fromNumber(this, arg)\r
5447   }\r
5448 \r
5449   // Slightly less common case.\r
5450   if (typeof arg === 'string') {\r
5451     return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8')\r
5452   }\r
5453 \r
5454   // Unusual.\r
5455   return fromObject(this, arg)\r
5456 }\r
5457 \r
5458 function fromNumber (that, length) {\r
5459   that = allocate(that, length < 0 ? 0 : checked(length) | 0)\r
5460   if (!Buffer.TYPED_ARRAY_SUPPORT) {\r
5461     for (var i = 0; i < length; i++) {\r
5462       that[i] = 0\r
5463     }\r
5464   }\r
5465   return that\r
5466 }\r
5467 \r
5468 function fromString (that, string, encoding) {\r
5469   if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8'\r
5470 \r
5471   // Assumption: byteLength() return value is always < kMaxLength.\r
5472   var length = byteLength(string, encoding) | 0\r
5473   that = allocate(that, length)\r
5474 \r
5475   that.write(string, encoding)\r
5476   return that\r
5477 }\r
5478 \r
5479 function fromObject (that, object) {\r
5480   if (Buffer.isBuffer(object)) return fromBuffer(that, object)\r
5481 \r
5482   if (isArray(object)) return fromArray(that, object)\r
5483 \r
5484   if (object == null) {\r
5485     throw new TypeError('must start with number, buffer, array or string')\r
5486   }\r
5487 \r
5488   if (typeof ArrayBuffer !== 'undefined') {\r
5489     if (object.buffer instanceof ArrayBuffer) {\r
5490       return fromTypedArray(that, object)\r
5491     }\r
5492     if (object instanceof ArrayBuffer) {\r
5493       return fromArrayBuffer(that, object)\r
5494     }\r
5495   }\r
5496 \r
5497   if (object.length) return fromArrayLike(that, object)\r
5498 \r
5499   return fromJsonObject(that, object)\r
5500 }\r
5501 \r
5502 function fromBuffer (that, buffer) {\r
5503   var length = checked(buffer.length) | 0\r
5504   that = allocate(that, length)\r
5505   buffer.copy(that, 0, 0, length)\r
5506   return that\r
5507 }\r
5508 \r
5509 function fromArray (that, array) {\r
5510   var length = checked(array.length) | 0\r
5511   that = allocate(that, length)\r
5512   for (var i = 0; i < length; i += 1) {\r
5513     that[i] = array[i] & 255\r
5514   }\r
5515   return that\r
5516 }\r
5517 \r
5518 // Duplicate of fromArray() to keep fromArray() monomorphic.\r
5519 function fromTypedArray (that, array) {\r
5520   var length = checked(array.length) | 0\r
5521   that = allocate(that, length)\r
5522   // Truncating the elements is probably not what people expect from typed\r
5523   // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior\r
5524   // of the old Buffer constructor.\r
5525   for (var i = 0; i < length; i += 1) {\r
5526     that[i] = array[i] & 255\r
5527   }\r
5528   return that\r
5529 }\r
5530 \r
5531 function fromArrayBuffer (that, array) {\r
5532   if (Buffer.TYPED_ARRAY_SUPPORT) {\r
5533     // Return an augmented `Uint8Array` instance, for best performance\r
5534     array.byteLength\r
5535     that = Buffer._augment(new Uint8Array(array))\r
5536   } else {\r
5537     // Fallback: Return an object instance of the Buffer class\r
5538     that = fromTypedArray(that, new Uint8Array(array))\r
5539   }\r
5540   return that\r
5541 }\r
5542 \r
5543 function fromArrayLike (that, array) {\r
5544   var length = checked(array.length) | 0\r
5545   that = allocate(that, length)\r
5546   for (var i = 0; i < length; i += 1) {\r
5547     that[i] = array[i] & 255\r
5548   }\r
5549   return that\r
5550 }\r
5551 \r
5552 // Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object.\r
5553 // Returns a zero-length buffer for inputs that don't conform to the spec.\r
5554 function fromJsonObject (that, object) {\r
5555   var array\r
5556   var length = 0\r
5557 \r
5558   if (object.type === 'Buffer' && isArray(object.data)) {\r
5559     array = object.data\r
5560     length = checked(array.length) | 0\r
5561   }\r
5562   that = allocate(that, length)\r
5563 \r
5564   for (var i = 0; i < length; i += 1) {\r
5565     that[i] = array[i] & 255\r
5566   }\r
5567   return that\r
5568 }\r
5569 \r
5570 function allocate (that, length) {\r
5571   if (Buffer.TYPED_ARRAY_SUPPORT) {\r
5572     // Return an augmented `Uint8Array` instance, for best performance\r
5573     that = Buffer._augment(new Uint8Array(length))\r
5574   } else {\r
5575     // Fallback: Return an object instance of the Buffer class\r
5576     that.length = length\r
5577     that._isBuffer = true\r
5578   }\r
5579 \r
5580   var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1\r
5581   if (fromPool) that.parent = rootParent\r
5582 \r
5583   return that\r
5584 }\r
5585 \r
5586 function checked (length) {\r
5587   // Note: cannot use `length < kMaxLength` here because that fails when\r
5588   // length is NaN (which is otherwise coerced to zero.)\r
5589   if (length >= kMaxLength()) {\r
5590     throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\r
5591                          'size: 0x' + kMaxLength().toString(16) + ' bytes')\r
5592   }\r
5593   return length | 0\r
5594 }\r
5595 \r
5596 function SlowBuffer (subject, encoding) {\r
5597   if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding)\r
5598 \r
5599   var buf = new Buffer(subject, encoding)\r
5600   delete buf.parent\r
5601   return buf\r
5602 }\r
5603 \r
5604 Buffer.isBuffer = function isBuffer (b) {\r
5605   return !!(b != null && b._isBuffer)\r
5606 }\r
5607 \r
5608 Buffer.compare = function compare (a, b) {\r
5609   if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {\r
5610     throw new TypeError('Arguments must be Buffers')\r
5611   }\r
5612 \r
5613   if (a === b) return 0\r
5614 \r
5615   var x = a.length\r
5616   var y = b.length\r
5617 \r
5618   var i = 0\r
5619   var len = Math.min(x, y)\r
5620   while (i < len) {\r
5621     if (a[i] !== b[i]) break\r
5622 \r
5623     ++i\r
5624   }\r
5625 \r
5626   if (i !== len) {\r
5627     x = a[i]\r
5628     y = b[i]\r
5629   }\r
5630 \r
5631   if (x < y) return -1\r
5632   if (y < x) return 1\r
5633   return 0\r
5634 }\r
5635 \r
5636 Buffer.isEncoding = function isEncoding (encoding) {\r
5637   switch (String(encoding).toLowerCase()) {\r
5638     case 'hex':\r
5639     case 'utf8':\r
5640     case 'utf-8':\r
5641     case 'ascii':\r
5642     case 'binary':\r
5643     case 'base64':\r
5644     case 'raw':\r
5645     case 'ucs2':\r
5646     case 'ucs-2':\r
5647     case 'utf16le':\r
5648     case 'utf-16le':\r
5649       return true\r
5650     default:\r
5651       return false\r
5652   }\r
5653 }\r
5654 \r
5655 Buffer.concat = function concat (list, length) {\r
5656   if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.')\r
5657 \r
5658   if (list.length === 0) {\r
5659     return new Buffer(0)\r
5660   }\r
5661 \r
5662   var i\r
5663   if (length === undefined) {\r
5664     length = 0\r
5665     for (i = 0; i < list.length; i++) {\r
5666       length += list[i].length\r
5667     }\r
5668   }\r
5669 \r
5670   var buf = new Buffer(length)\r
5671   var pos = 0\r
5672   for (i = 0; i < list.length; i++) {\r
5673     var item = list[i]\r
5674     item.copy(buf, pos)\r
5675     pos += item.length\r
5676   }\r
5677   return buf\r
5678 }\r
5679 \r
5680 function byteLength (string, encoding) {\r
5681   if (typeof string !== 'string') string = '' + string\r
5682 \r
5683   var len = string.length\r
5684   if (len === 0) return 0\r
5685 \r
5686   // Use a for loop to avoid recursion\r
5687   var loweredCase = false\r
5688   for (;;) {\r
5689     switch (encoding) {\r
5690       case 'ascii':\r
5691       case 'binary':\r
5692       // Deprecated\r
5693       case 'raw':\r
5694       case 'raws':\r
5695         return len\r
5696       case 'utf8':\r
5697       case 'utf-8':\r
5698         return utf8ToBytes(string).length\r
5699       case 'ucs2':\r
5700       case 'ucs-2':\r
5701       case 'utf16le':\r
5702       case 'utf-16le':\r
5703         return len * 2\r
5704       case 'hex':\r
5705         return len >>> 1\r
5706       case 'base64':\r
5707         return base64ToBytes(string).length\r
5708       default:\r
5709         if (loweredCase) return utf8ToBytes(string).length // assume utf8\r
5710         encoding = ('' + encoding).toLowerCase()\r
5711         loweredCase = true\r
5712     }\r
5713   }\r
5714 }\r
5715 Buffer.byteLength = byteLength\r
5716 \r
5717 // pre-set for values that may exist in the future\r
5718 Buffer.prototype.length = undefined\r
5719 Buffer.prototype.parent = undefined\r
5720 \r
5721 function slowToString (encoding, start, end) {\r
5722   var loweredCase = false\r
5723 \r
5724   start = start | 0\r
5725   end = end === undefined || end === Infinity ? this.length : end | 0\r
5726 \r
5727   if (!encoding) encoding = 'utf8'\r
5728   if (start < 0) start = 0\r
5729   if (end > this.length) end = this.length\r
5730   if (end <= start) return ''\r
5731 \r
5732   while (true) {\r
5733     switch (encoding) {\r
5734       case 'hex':\r
5735         return hexSlice(this, start, end)\r
5736 \r
5737       case 'utf8':\r
5738       case 'utf-8':\r
5739         return utf8Slice(this, start, end)\r
5740 \r
5741       case 'ascii':\r
5742         return asciiSlice(this, start, end)\r
5743 \r
5744       case 'binary':\r
5745         return binarySlice(this, start, end)\r
5746 \r
5747       case 'base64':\r
5748         return base64Slice(this, start, end)\r
5749 \r
5750       case 'ucs2':\r
5751       case 'ucs-2':\r
5752       case 'utf16le':\r
5753       case 'utf-16le':\r
5754         return utf16leSlice(this, start, end)\r
5755 \r
5756       default:\r
5757         if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\r
5758         encoding = (encoding + '').toLowerCase()\r
5759         loweredCase = true\r
5760     }\r
5761   }\r
5762 }\r
5763 \r
5764 Buffer.prototype.toString = function toString () {\r
5765   var length = this.length | 0\r
5766   if (length === 0) return ''\r
5767   if (arguments.length === 0) return utf8Slice(this, 0, length)\r
5768   return slowToString.apply(this, arguments)\r
5769 }\r
5770 \r
5771 Buffer.prototype.equals = function equals (b) {\r
5772   if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\r
5773   if (this === b) return true\r
5774   return Buffer.compare(this, b) === 0\r
5775 }\r
5776 \r
5777 Buffer.prototype.inspect = function inspect () {\r
5778   var str = ''\r
5779   var max = exports.INSPECT_MAX_BYTES\r
5780   if (this.length > 0) {\r
5781     str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')\r
5782     if (this.length > max) str += ' ... '\r
5783   }\r
5784   return '<Buffer ' + str + '>'\r
5785 }\r
5786 \r
5787 Buffer.prototype.compare = function compare (b) {\r
5788   if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\r
5789   if (this === b) return 0\r
5790   return Buffer.compare(this, b)\r
5791 }\r
5792 \r
5793 Buffer.prototype.indexOf = function indexOf (val, byteOffset) {\r
5794   if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff\r
5795   else if (byteOffset < -0x80000000) byteOffset = -0x80000000\r
5796   byteOffset >>= 0\r
5797 \r
5798   if (this.length === 0) return -1\r
5799   if (byteOffset >= this.length) return -1\r
5800 \r
5801   // Negative offsets start from the end of the buffer\r
5802   if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0)\r
5803 \r
5804   if (typeof val === 'string') {\r
5805     if (val.length === 0) return -1 // special case: looking for empty string always fails\r
5806     return String.prototype.indexOf.call(this, val, byteOffset)\r
5807   }\r
5808   if (Buffer.isBuffer(val)) {\r
5809     return arrayIndexOf(this, val, byteOffset)\r
5810   }\r
5811   if (typeof val === 'number') {\r
5812     if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') {\r
5813       return Uint8Array.prototype.indexOf.call(this, val, byteOffset)\r
5814     }\r
5815     return arrayIndexOf(this, [ val ], byteOffset)\r
5816   }\r
5817 \r
5818   function arrayIndexOf (arr, val, byteOffset) {\r
5819     var foundIndex = -1\r
5820     for (var i = 0; byteOffset + i < arr.length; i++) {\r
5821       if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) {\r
5822         if (foundIndex === -1) foundIndex = i\r
5823         if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex\r
5824       } else {\r
5825         foundIndex = -1\r
5826       }\r
5827     }\r
5828     return -1\r
5829   }\r
5830 \r
5831   throw new TypeError('val must be string, number or Buffer')\r
5832 }\r
5833 \r
5834 // `get` is deprecated\r
5835 Buffer.prototype.get = function get (offset) {\r
5836   console.log('.get() is deprecated. Access using array indexes instead.')\r
5837   return this.readUInt8(offset)\r
5838 }\r
5839 \r
5840 // `set` is deprecated\r
5841 Buffer.prototype.set = function set (v, offset) {\r
5842   console.log('.set() is deprecated. Access using array indexes instead.')\r
5843   return this.writeUInt8(v, offset)\r
5844 }\r
5845 \r
5846 function hexWrite (buf, string, offset, length) {\r
5847   offset = Number(offset) || 0\r
5848   var remaining = buf.length - offset\r
5849   if (!length) {\r
5850     length = remaining\r
5851   } else {\r
5852     length = Number(length)\r
5853     if (length > remaining) {\r
5854       length = remaining\r
5855     }\r
5856   }\r
5857 \r
5858   // must be an even number of digits\r
5859   var strLen = string.length\r
5860   if (strLen % 2 !== 0) throw new Error('Invalid hex string')\r
5861 \r
5862   if (length > strLen / 2) {\r
5863     length = strLen / 2\r
5864   }\r
5865   for (var i = 0; i < length; i++) {\r
5866     var parsed = parseInt(string.substr(i * 2, 2), 16)\r
5867     if (isNaN(parsed)) throw new Error('Invalid hex string')\r
5868     buf[offset + i] = parsed\r
5869   }\r
5870   return i\r
5871 }\r
5872 \r
5873 function utf8Write (buf, string, offset, length) {\r
5874   return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)\r
5875 }\r
5876 \r
5877 function asciiWrite (buf, string, offset, length) {\r
5878   return blitBuffer(asciiToBytes(string), buf, offset, length)\r
5879 }\r
5880 \r
5881 function binaryWrite (buf, string, offset, length) {\r
5882   return asciiWrite(buf, string, offset, length)\r
5883 }\r
5884 \r
5885 function base64Write (buf, string, offset, length) {\r
5886   return blitBuffer(base64ToBytes(string), buf, offset, length)\r
5887 }\r
5888 \r
5889 function ucs2Write (buf, string, offset, length) {\r
5890   return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)\r
5891 }\r
5892 \r
5893 Buffer.prototype.write = function write (string, offset, length, encoding) {\r
5894   // Buffer#write(string)\r
5895   if (offset === undefined) {\r
5896     encoding = 'utf8'\r
5897     length = this.length\r
5898     offset = 0\r
5899   // Buffer#write(string, encoding)\r
5900   } else if (length === undefined && typeof offset === 'string') {\r
5901     encoding = offset\r
5902     length = this.length\r
5903     offset = 0\r
5904   // Buffer#write(string, offset[, length][, encoding])\r
5905   } else if (isFinite(offset)) {\r
5906     offset = offset | 0\r
5907     if (isFinite(length)) {\r
5908       length = length | 0\r
5909       if (encoding === undefined) encoding = 'utf8'\r
5910     } else {\r
5911       encoding = length\r
5912       length = undefined\r
5913     }\r
5914   // legacy write(string, encoding, offset, length) - remove in v0.13\r
5915   } else {\r
5916     var swap = encoding\r
5917     encoding = offset\r
5918     offset = length | 0\r
5919     length = swap\r
5920   }\r
5921 \r
5922   var remaining = this.length - offset\r
5923   if (length === undefined || length > remaining) length = remaining\r
5924 \r
5925   if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {\r
5926     throw new RangeError('attempt to write outside buffer bounds')\r
5927   }\r
5928 \r
5929   if (!encoding) encoding = 'utf8'\r
5930 \r
5931   var loweredCase = false\r
5932   for (;;) {\r
5933     switch (encoding) {\r
5934       case 'hex':\r
5935         return hexWrite(this, string, offset, length)\r
5936 \r
5937       case 'utf8':\r
5938       case 'utf-8':\r
5939         return utf8Write(this, string, offset, length)\r
5940 \r
5941       case 'ascii':\r
5942         return asciiWrite(this, string, offset, length)\r
5943 \r
5944       case 'binary':\r
5945         return binaryWrite(this, string, offset, length)\r
5946 \r
5947       case 'base64':\r
5948         // Warning: maxLength not taken into account in base64Write\r
5949         return base64Write(this, string, offset, length)\r
5950 \r
5951       case 'ucs2':\r
5952       case 'ucs-2':\r
5953       case 'utf16le':\r
5954       case 'utf-16le':\r
5955         return ucs2Write(this, string, offset, length)\r
5956 \r
5957       default:\r
5958         if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\r
5959         encoding = ('' + encoding).toLowerCase()\r
5960         loweredCase = true\r
5961     }\r
5962   }\r
5963 }\r
5964 \r
5965 Buffer.prototype.toJSON = function toJSON () {\r
5966   return {\r
5967     type: 'Buffer',\r
5968     data: Array.prototype.slice.call(this._arr || this, 0)\r
5969   }\r
5970 }\r
5971 \r
5972 function base64Slice (buf, start, end) {\r
5973   if (start === 0 && end === buf.length) {\r
5974     return base64.fromByteArray(buf)\r
5975   } else {\r
5976     return base64.fromByteArray(buf.slice(start, end))\r
5977   }\r
5978 }\r
5979 \r
5980 function utf8Slice (buf, start, end) {\r
5981   end = Math.min(buf.length, end)\r
5982   var res = []\r
5983 \r
5984   var i = start\r
5985   while (i < end) {\r
5986     var firstByte = buf[i]\r
5987     var codePoint = null\r
5988     var bytesPerSequence = (firstByte > 0xEF) ? 4\r
5989       : (firstByte > 0xDF) ? 3\r
5990       : (firstByte > 0xBF) ? 2\r
5991       : 1\r
5992 \r
5993     if (i + bytesPerSequence <= end) {\r
5994       var secondByte, thirdByte, fourthByte, tempCodePoint\r
5995 \r
5996       switch (bytesPerSequence) {\r
5997         case 1:\r
5998           if (firstByte < 0x80) {\r
5999             codePoint = firstByte\r
6000           }\r
6001           break\r
6002         case 2:\r
6003           secondByte = buf[i + 1]\r
6004           if ((secondByte & 0xC0) === 0x80) {\r
6005             tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)\r
6006             if (tempCodePoint > 0x7F) {\r
6007               codePoint = tempCodePoint\r
6008             }\r
6009           }\r
6010           break\r
6011         case 3:\r
6012           secondByte = buf[i + 1]\r
6013           thirdByte = buf[i + 2]\r
6014           if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {\r
6015             tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)\r
6016             if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {\r
6017               codePoint = tempCodePoint\r
6018             }\r
6019           }\r
6020           break\r
6021         case 4:\r
6022           secondByte = buf[i + 1]\r
6023           thirdByte = buf[i + 2]\r
6024           fourthByte = buf[i + 3]\r
6025           if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {\r
6026             tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)\r
6027             if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {\r
6028               codePoint = tempCodePoint\r
6029             }\r
6030           }\r
6031       }\r
6032     }\r
6033 \r
6034     if (codePoint === null) {\r
6035       // we did not generate a valid codePoint so insert a\r
6036       // replacement char (U+FFFD) and advance only 1 byte\r
6037       codePoint = 0xFFFD\r
6038       bytesPerSequence = 1\r
6039     } else if (codePoint > 0xFFFF) {\r
6040       // encode to utf16 (surrogate pair dance)\r
6041       codePoint -= 0x10000\r
6042       res.push(codePoint >>> 10 & 0x3FF | 0xD800)\r
6043       codePoint = 0xDC00 | codePoint & 0x3FF\r
6044     }\r
6045 \r
6046     res.push(codePoint)\r
6047     i += bytesPerSequence\r
6048   }\r
6049 \r
6050   return decodeCodePointsArray(res)\r
6051 }\r
6052 \r
6053 // Based on http://stackoverflow.com/a/22747272/680742, the browser with\r
6054 // the lowest limit is Chrome, with 0x10000 args.\r
6055 // We go 1 magnitude less, for safety\r
6056 var MAX_ARGUMENTS_LENGTH = 0x1000\r
6057 \r
6058 function decodeCodePointsArray (codePoints) {\r
6059   var len = codePoints.length\r
6060   if (len <= MAX_ARGUMENTS_LENGTH) {\r
6061     return String.fromCharCode.apply(String, codePoints) // avoid extra slice()\r
6062   }\r
6063 \r
6064   // Decode in chunks to avoid "call stack size exceeded".\r
6065   var res = ''\r
6066   var i = 0\r
6067   while (i < len) {\r
6068     res += String.fromCharCode.apply(\r
6069       String,\r
6070       codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)\r
6071     )\r
6072   }\r
6073   return res\r
6074 }\r
6075 \r
6076 function asciiSlice (buf, start, end) {\r
6077   var ret = ''\r
6078   end = Math.min(buf.length, end)\r
6079 \r
6080   for (var i = start; i < end; i++) {\r
6081     ret += String.fromCharCode(buf[i] & 0x7F)\r
6082   }\r
6083   return ret\r
6084 }\r
6085 \r
6086 function binarySlice (buf, start, end) {\r
6087   var ret = ''\r
6088   end = Math.min(buf.length, end)\r
6089 \r
6090   for (var i = start; i < end; i++) {\r
6091     ret += String.fromCharCode(buf[i])\r
6092   }\r
6093   return ret\r
6094 }\r
6095 \r
6096 function hexSlice (buf, start, end) {\r
6097   var len = buf.length\r
6098 \r
6099   if (!start || start < 0) start = 0\r
6100   if (!end || end < 0 || end > len) end = len\r
6101 \r
6102   var out = ''\r
6103   for (var i = start; i < end; i++) {\r
6104     out += toHex(buf[i])\r
6105   }\r
6106   return out\r
6107 }\r
6108 \r
6109 function utf16leSlice (buf, start, end) {\r
6110   var bytes = buf.slice(start, end)\r
6111   var res = ''\r
6112   for (var i = 0; i < bytes.length; i += 2) {\r
6113     res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)\r
6114   }\r
6115   return res\r
6116 }\r
6117 \r
6118 Buffer.prototype.slice = function slice (start, end) {\r
6119   var len = this.length\r
6120   start = ~~start\r
6121   end = end === undefined ? len : ~~end\r
6122 \r
6123   if (start < 0) {\r
6124     start += len\r
6125     if (start < 0) start = 0\r
6126   } else if (start > len) {\r
6127     start = len\r
6128   }\r
6129 \r
6130   if (end < 0) {\r
6131     end += len\r
6132     if (end < 0) end = 0\r
6133   } else if (end > len) {\r
6134     end = len\r
6135   }\r
6136 \r
6137   if (end < start) end = start\r
6138 \r
6139   var newBuf\r
6140   if (Buffer.TYPED_ARRAY_SUPPORT) {\r
6141     newBuf = Buffer._augment(this.subarray(start, end))\r
6142   } else {\r
6143     var sliceLen = end - start\r
6144     newBuf = new Buffer(sliceLen, undefined)\r
6145     for (var i = 0; i < sliceLen; i++) {\r
6146       newBuf[i] = this[i + start]\r
6147     }\r
6148   }\r
6149 \r
6150   if (newBuf.length) newBuf.parent = this.parent || this\r
6151 \r
6152   return newBuf\r
6153 }\r
6154 \r
6155 /*\r
6156  * Need to make sure that buffer isn't trying to write out of bounds.\r
6157  */\r
6158 function checkOffset (offset, ext, length) {\r
6159   if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')\r
6160   if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')\r
6161 }\r
6162 \r
6163 Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {\r
6164   offset = offset | 0\r
6165   byteLength = byteLength | 0\r
6166   if (!noAssert) checkOffset(offset, byteLength, this.length)\r
6167 \r
6168   var val = this[offset]\r
6169   var mul = 1\r
6170   var i = 0\r
6171   while (++i < byteLength && (mul *= 0x100)) {\r
6172     val += this[offset + i] * mul\r
6173   }\r
6174 \r
6175   return val\r
6176 }\r
6177 \r
6178 Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {\r
6179   offset = offset | 0\r
6180   byteLength = byteLength | 0\r
6181   if (!noAssert) {\r
6182     checkOffset(offset, byteLength, this.length)\r
6183   }\r
6184 \r
6185   var val = this[offset + --byteLength]\r
6186   var mul = 1\r
6187   while (byteLength > 0 && (mul *= 0x100)) {\r
6188     val += this[offset + --byteLength] * mul\r
6189   }\r
6190 \r
6191   return val\r
6192 }\r
6193 \r
6194 Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {\r
6195   if (!noAssert) checkOffset(offset, 1, this.length)\r
6196   return this[offset]\r
6197 }\r
6198 \r
6199 Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {\r
6200   if (!noAssert) checkOffset(offset, 2, this.length)\r
6201   return this[offset] | (this[offset + 1] << 8)\r
6202 }\r
6203 \r
6204 Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {\r
6205   if (!noAssert) checkOffset(offset, 2, this.length)\r
6206   return (this[offset] << 8) | this[offset + 1]\r
6207 }\r
6208 \r
6209 Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {\r
6210   if (!noAssert) checkOffset(offset, 4, this.length)\r
6211 \r
6212   return ((this[offset]) |\r
6213       (this[offset + 1] << 8) |\r
6214       (this[offset + 2] << 16)) +\r
6215       (this[offset + 3] * 0x1000000)\r
6216 }\r
6217 \r
6218 Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {\r
6219   if (!noAssert) checkOffset(offset, 4, this.length)\r
6220 \r
6221   return (this[offset] * 0x1000000) +\r
6222     ((this[offset + 1] << 16) |\r
6223     (this[offset + 2] << 8) |\r
6224     this[offset + 3])\r
6225 }\r
6226 \r
6227 Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {\r
6228   offset = offset | 0\r
6229   byteLength = byteLength | 0\r
6230   if (!noAssert) checkOffset(offset, byteLength, this.length)\r
6231 \r
6232   var val = this[offset]\r
6233   var mul = 1\r
6234   var i = 0\r
6235   while (++i < byteLength && (mul *= 0x100)) {\r
6236     val += this[offset + i] * mul\r
6237   }\r
6238   mul *= 0x80\r
6239 \r
6240   if (val >= mul) val -= Math.pow(2, 8 * byteLength)\r
6241 \r
6242   return val\r
6243 }\r
6244 \r
6245 Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {\r
6246   offset = offset | 0\r
6247   byteLength = byteLength | 0\r
6248   if (!noAssert) checkOffset(offset, byteLength, this.length)\r
6249 \r
6250   var i = byteLength\r
6251   var mul = 1\r
6252   var val = this[offset + --i]\r
6253   while (i > 0 && (mul *= 0x100)) {\r
6254     val += this[offset + --i] * mul\r
6255   }\r
6256   mul *= 0x80\r
6257 \r
6258   if (val >= mul) val -= Math.pow(2, 8 * byteLength)\r
6259 \r
6260   return val\r
6261 }\r
6262 \r
6263 Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {\r
6264   if (!noAssert) checkOffset(offset, 1, this.length)\r
6265   if (!(this[offset] & 0x80)) return (this[offset])\r
6266   return ((0xff - this[offset] + 1) * -1)\r
6267 }\r
6268 \r
6269 Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {\r
6270   if (!noAssert) checkOffset(offset, 2, this.length)\r
6271   var val = this[offset] | (this[offset + 1] << 8)\r
6272   return (val & 0x8000) ? val | 0xFFFF0000 : val\r
6273 }\r
6274 \r
6275 Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {\r
6276   if (!noAssert) checkOffset(offset, 2, this.length)\r
6277   var val = this[offset + 1] | (this[offset] << 8)\r
6278   return (val & 0x8000) ? val | 0xFFFF0000 : val\r
6279 }\r
6280 \r
6281 Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {\r
6282   if (!noAssert) checkOffset(offset, 4, this.length)\r
6283 \r
6284   return (this[offset]) |\r
6285     (this[offset + 1] << 8) |\r
6286     (this[offset + 2] << 16) |\r
6287     (this[offset + 3] << 24)\r
6288 }\r
6289 \r
6290 Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {\r
6291   if (!noAssert) checkOffset(offset, 4, this.length)\r
6292 \r
6293   return (this[offset] << 24) |\r
6294     (this[offset + 1] << 16) |\r
6295     (this[offset + 2] << 8) |\r
6296     (this[offset + 3])\r
6297 }\r
6298 \r
6299 Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {\r
6300   if (!noAssert) checkOffset(offset, 4, this.length)\r
6301   return ieee754.read(this, offset, true, 23, 4)\r
6302 }\r
6303 \r
6304 Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {\r
6305   if (!noAssert) checkOffset(offset, 4, this.length)\r
6306   return ieee754.read(this, offset, false, 23, 4)\r
6307 }\r
6308 \r
6309 Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {\r
6310   if (!noAssert) checkOffset(offset, 8, this.length)\r
6311   return ieee754.read(this, offset, true, 52, 8)\r
6312 }\r
6313 \r
6314 Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {\r
6315   if (!noAssert) checkOffset(offset, 8, this.length)\r
6316   return ieee754.read(this, offset, false, 52, 8)\r
6317 }\r
6318 \r
6319 function checkInt (buf, value, offset, ext, max, min) {\r
6320   if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance')\r
6321   if (value > max || value < min) throw new RangeError('value is out of bounds')\r
6322   if (offset + ext > buf.length) throw new RangeError('index out of range')\r
6323 }\r
6324 \r
6325 Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {\r
6326   value = +value\r
6327   offset = offset | 0\r
6328   byteLength = byteLength | 0\r
6329   if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)\r
6330 \r
6331   var mul = 1\r
6332   var i = 0\r
6333   this[offset] = value & 0xFF\r
6334   while (++i < byteLength && (mul *= 0x100)) {\r
6335     this[offset + i] = (value / mul) & 0xFF\r
6336   }\r
6337 \r
6338   return offset + byteLength\r
6339 }\r
6340 \r
6341 Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {\r
6342   value = +value\r
6343   offset = offset | 0\r
6344   byteLength = byteLength | 0\r
6345   if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)\r
6346 \r
6347   var i = byteLength - 1\r
6348   var mul = 1\r
6349   this[offset + i] = value & 0xFF\r
6350   while (--i >= 0 && (mul *= 0x100)) {\r
6351     this[offset + i] = (value / mul) & 0xFF\r
6352   }\r
6353 \r
6354   return offset + byteLength\r
6355 }\r
6356 \r
6357 Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {\r
6358   value = +value\r
6359   offset = offset | 0\r
6360   if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)\r
6361   if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\r
6362   this[offset] = value\r
6363   return offset + 1\r
6364 }\r
6365 \r
6366 function objectWriteUInt16 (buf, value, offset, littleEndian) {\r
6367   if (value < 0) value = 0xffff + value + 1\r
6368   for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) {\r
6369     buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\r
6370       (littleEndian ? i : 1 - i) * 8\r
6371   }\r
6372 }\r
6373 \r
6374 Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {\r
6375   value = +value\r
6376   offset = offset | 0\r
6377   if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\r
6378   if (Buffer.TYPED_ARRAY_SUPPORT) {\r
6379     this[offset] = value\r
6380     this[offset + 1] = (value >>> 8)\r
6381   } else {\r
6382     objectWriteUInt16(this, value, offset, true)\r
6383   }\r
6384   return offset + 2\r
6385 }\r
6386 \r
6387 Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {\r
6388   value = +value\r
6389   offset = offset | 0\r
6390   if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\r
6391   if (Buffer.TYPED_ARRAY_SUPPORT) {\r
6392     this[offset] = (value >>> 8)\r
6393     this[offset + 1] = value\r
6394   } else {\r
6395     objectWriteUInt16(this, value, offset, false)\r
6396   }\r
6397   return offset + 2\r
6398 }\r
6399 \r
6400 function objectWriteUInt32 (buf, value, offset, littleEndian) {\r
6401   if (value < 0) value = 0xffffffff + value + 1\r
6402   for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) {\r
6403     buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\r
6404   }\r
6405 }\r
6406 \r
6407 Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {\r
6408   value = +value\r
6409   offset = offset | 0\r
6410   if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\r
6411   if (Buffer.TYPED_ARRAY_SUPPORT) {\r
6412     this[offset + 3] = (value >>> 24)\r
6413     this[offset + 2] = (value >>> 16)\r
6414     this[offset + 1] = (value >>> 8)\r
6415     this[offset] = value\r
6416   } else {\r
6417     objectWriteUInt32(this, value, offset, true)\r
6418   }\r
6419   return offset + 4\r
6420 }\r
6421 \r
6422 Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {\r
6423   value = +value\r
6424   offset = offset | 0\r
6425   if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\r
6426   if (Buffer.TYPED_ARRAY_SUPPORT) {\r
6427     this[offset] = (value >>> 24)\r
6428     this[offset + 1] = (value >>> 16)\r
6429     this[offset + 2] = (value >>> 8)\r
6430     this[offset + 3] = value\r
6431   } else {\r
6432     objectWriteUInt32(this, value, offset, false)\r
6433   }\r
6434   return offset + 4\r
6435 }\r
6436 \r
6437 Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {\r
6438   value = +value\r
6439   offset = offset | 0\r
6440   if (!noAssert) {\r
6441     var limit = Math.pow(2, 8 * byteLength - 1)\r
6442 \r
6443     checkInt(this, value, offset, byteLength, limit - 1, -limit)\r
6444   }\r
6445 \r
6446   var i = 0\r
6447   var mul = 1\r
6448   var sub = value < 0 ? 1 : 0\r
6449   this[offset] = value & 0xFF\r
6450   while (++i < byteLength && (mul *= 0x100)) {\r
6451     this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\r
6452   }\r
6453 \r
6454   return offset + byteLength\r
6455 }\r
6456 \r
6457 Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {\r
6458   value = +value\r
6459   offset = offset | 0\r
6460   if (!noAssert) {\r
6461     var limit = Math.pow(2, 8 * byteLength - 1)\r
6462 \r
6463     checkInt(this, value, offset, byteLength, limit - 1, -limit)\r
6464   }\r
6465 \r
6466   var i = byteLength - 1\r
6467   var mul = 1\r
6468   var sub = value < 0 ? 1 : 0\r
6469   this[offset + i] = value & 0xFF\r
6470   while (--i >= 0 && (mul *= 0x100)) {\r
6471     this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\r
6472   }\r
6473 \r
6474   return offset + byteLength\r
6475 }\r
6476 \r
6477 Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {\r
6478   value = +value\r
6479   offset = offset | 0\r
6480   if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)\r
6481   if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\r
6482   if (value < 0) value = 0xff + value + 1\r
6483   this[offset] = value\r
6484   return offset + 1\r
6485 }\r
6486 \r
6487 Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {\r
6488   value = +value\r
6489   offset = offset | 0\r
6490   if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\r
6491   if (Buffer.TYPED_ARRAY_SUPPORT) {\r
6492     this[offset] = value\r
6493     this[offset + 1] = (value >>> 8)\r
6494   } else {\r
6495     objectWriteUInt16(this, value, offset, true)\r
6496   }\r
6497   return offset + 2\r
6498 }\r
6499 \r
6500 Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {\r
6501   value = +value\r
6502   offset = offset | 0\r
6503   if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\r
6504   if (Buffer.TYPED_ARRAY_SUPPORT) {\r
6505     this[offset] = (value >>> 8)\r
6506     this[offset + 1] = value\r
6507   } else {\r
6508     objectWriteUInt16(this, value, offset, false)\r
6509   }\r
6510   return offset + 2\r
6511 }\r
6512 \r
6513 Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {\r
6514   value = +value\r
6515   offset = offset | 0\r
6516   if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\r
6517   if (Buffer.TYPED_ARRAY_SUPPORT) {\r
6518     this[offset] = value\r
6519     this[offset + 1] = (value >>> 8)\r
6520     this[offset + 2] = (value >>> 16)\r
6521     this[offset + 3] = (value >>> 24)\r
6522   } else {\r
6523     objectWriteUInt32(this, value, offset, true)\r
6524   }\r
6525   return offset + 4\r
6526 }\r
6527 \r
6528 Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {\r
6529   value = +value\r
6530   offset = offset | 0\r
6531   if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\r
6532   if (value < 0) value = 0xffffffff + value + 1\r
6533   if (Buffer.TYPED_ARRAY_SUPPORT) {\r
6534     this[offset] = (value >>> 24)\r
6535     this[offset + 1] = (value >>> 16)\r
6536     this[offset + 2] = (value >>> 8)\r
6537     this[offset + 3] = value\r
6538   } else {\r
6539     objectWriteUInt32(this, value, offset, false)\r
6540   }\r
6541   return offset + 4\r
6542 }\r
6543 \r
6544 function checkIEEE754 (buf, value, offset, ext, max, min) {\r
6545   if (value > max || value < min) throw new RangeError('value is out of bounds')\r
6546   if (offset + ext > buf.length) throw new RangeError('index out of range')\r
6547   if (offset < 0) throw new RangeError('index out of range')\r
6548 }\r
6549 \r
6550 function writeFloat (buf, value, offset, littleEndian, noAssert) {\r
6551   if (!noAssert) {\r
6552     checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)\r
6553   }\r
6554   ieee754.write(buf, value, offset, littleEndian, 23, 4)\r
6555   return offset + 4\r
6556 }\r
6557 \r
6558 Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {\r
6559   return writeFloat(this, value, offset, true, noAssert)\r
6560 }\r
6561 \r
6562 Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {\r
6563   return writeFloat(this, value, offset, false, noAssert)\r
6564 }\r
6565 \r
6566 function writeDouble (buf, value, offset, littleEndian, noAssert) {\r
6567   if (!noAssert) {\r
6568     checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)\r
6569   }\r
6570   ieee754.write(buf, value, offset, littleEndian, 52, 8)\r
6571   return offset + 8\r
6572 }\r
6573 \r
6574 Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {\r
6575   return writeDouble(this, value, offset, true, noAssert)\r
6576 }\r
6577 \r
6578 Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {\r
6579   return writeDouble(this, value, offset, false, noAssert)\r
6580 }\r
6581 \r
6582 // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\r
6583 Buffer.prototype.copy = function copy (target, targetStart, start, end) {\r
6584   if (!start) start = 0\r
6585   if (!end && end !== 0) end = this.length\r
6586   if (targetStart >= target.length) targetStart = target.length\r
6587   if (!targetStart) targetStart = 0\r
6588   if (end > 0 && end < start) end = start\r
6589 \r
6590   // Copy 0 bytes; we're done\r
6591   if (end === start) return 0\r
6592   if (target.length === 0 || this.length === 0) return 0\r
6593 \r
6594   // Fatal error conditions\r
6595   if (targetStart < 0) {\r
6596     throw new RangeError('targetStart out of bounds')\r
6597   }\r
6598   if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')\r
6599   if (end < 0) throw new RangeError('sourceEnd out of bounds')\r
6600 \r
6601   // Are we oob?\r
6602   if (end > this.length) end = this.length\r
6603   if (target.length - targetStart < end - start) {\r
6604     end = target.length - targetStart + start\r
6605   }\r
6606 \r
6607   var len = end - start\r
6608   var i\r
6609 \r
6610   if (this === target && start < targetStart && targetStart < end) {\r
6611     // descending copy from end\r
6612     for (i = len - 1; i >= 0; i--) {\r
6613       target[i + targetStart] = this[i + start]\r
6614     }\r
6615   } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {\r
6616     // ascending copy from start\r
6617     for (i = 0; i < len; i++) {\r
6618       target[i + targetStart] = this[i + start]\r
6619     }\r
6620   } else {\r
6621     target._set(this.subarray(start, start + len), targetStart)\r
6622   }\r
6623 \r
6624   return len\r
6625 }\r
6626 \r
6627 // fill(value, start=0, end=buffer.length)\r
6628 Buffer.prototype.fill = function fill (value, start, end) {\r
6629   if (!value) value = 0\r
6630   if (!start) start = 0\r
6631   if (!end) end = this.length\r
6632 \r
6633   if (end < start) throw new RangeError('end < start')\r
6634 \r
6635   // Fill 0 bytes; we're done\r
6636   if (end === start) return\r
6637   if (this.length === 0) return\r
6638 \r
6639   if (start < 0 || start >= this.length) throw new RangeError('start out of bounds')\r
6640   if (end < 0 || end > this.length) throw new RangeError('end out of bounds')\r
6641 \r
6642   var i\r
6643   if (typeof value === 'number') {\r
6644     for (i = start; i < end; i++) {\r
6645       this[i] = value\r
6646     }\r
6647   } else {\r
6648     var bytes = utf8ToBytes(value.toString())\r
6649     var len = bytes.length\r
6650     for (i = start; i < end; i++) {\r
6651       this[i] = bytes[i % len]\r
6652     }\r
6653   }\r
6654 \r
6655   return this\r
6656 }\r
6657 \r
6658 /**\r
6659  * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance.\r
6660  * Added in Node 0.12. Only available in browsers that support ArrayBuffer.\r
6661  */\r
6662 Buffer.prototype.toArrayBuffer = function toArrayBuffer () {\r
6663   if (typeof Uint8Array !== 'undefined') {\r
6664     if (Buffer.TYPED_ARRAY_SUPPORT) {\r
6665       return (new Buffer(this)).buffer\r
6666     } else {\r
6667       var buf = new Uint8Array(this.length)\r
6668       for (var i = 0, len = buf.length; i < len; i += 1) {\r
6669         buf[i] = this[i]\r
6670       }\r
6671       return buf.buffer\r
6672     }\r
6673   } else {\r
6674     throw new TypeError('Buffer.toArrayBuffer not supported in this browser')\r
6675   }\r
6676 }\r
6677 \r
6678 // HELPER FUNCTIONS\r
6679 // ================\r
6680 \r
6681 var BP = Buffer.prototype\r
6682 \r
6683 /**\r
6684  * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods\r
6685  */\r
6686 Buffer._augment = function _augment (arr) {\r
6687   arr.constructor = Buffer\r
6688   arr._isBuffer = true\r
6689 \r
6690   // save reference to original Uint8Array set method before overwriting\r
6691   arr._set = arr.set\r
6692 \r
6693   // deprecated\r
6694   arr.get = BP.get\r
6695   arr.set = BP.set\r
6696 \r
6697   arr.write = BP.write\r
6698   arr.toString = BP.toString\r
6699   arr.toLocaleString = BP.toString\r
6700   arr.toJSON = BP.toJSON\r
6701   arr.equals = BP.equals\r
6702   arr.compare = BP.compare\r
6703   arr.indexOf = BP.indexOf\r
6704   arr.copy = BP.copy\r
6705   arr.slice = BP.slice\r
6706   arr.readUIntLE = BP.readUIntLE\r
6707   arr.readUIntBE = BP.readUIntBE\r
6708   arr.readUInt8 = BP.readUInt8\r
6709   arr.readUInt16LE = BP.readUInt16LE\r
6710   arr.readUInt16BE = BP.readUInt16BE\r
6711   arr.readUInt32LE = BP.readUInt32LE\r
6712   arr.readUInt32BE = BP.readUInt32BE\r
6713   arr.readIntLE = BP.readIntLE\r
6714   arr.readIntBE = BP.readIntBE\r
6715   arr.readInt8 = BP.readInt8\r
6716   arr.readInt16LE = BP.readInt16LE\r
6717   arr.readInt16BE = BP.readInt16BE\r
6718   arr.readInt32LE = BP.readInt32LE\r
6719   arr.readInt32BE = BP.readInt32BE\r
6720   arr.readFloatLE = BP.readFloatLE\r
6721   arr.readFloatBE = BP.readFloatBE\r
6722   arr.readDoubleLE = BP.readDoubleLE\r
6723   arr.readDoubleBE = BP.readDoubleBE\r
6724   arr.writeUInt8 = BP.writeUInt8\r
6725   arr.writeUIntLE = BP.writeUIntLE\r
6726   arr.writeUIntBE = BP.writeUIntBE\r
6727   arr.writeUInt16LE = BP.writeUInt16LE\r
6728   arr.writeUInt16BE = BP.writeUInt16BE\r
6729   arr.writeUInt32LE = BP.writeUInt32LE\r
6730   arr.writeUInt32BE = BP.writeUInt32BE\r
6731   arr.writeIntLE = BP.writeIntLE\r
6732   arr.writeIntBE = BP.writeIntBE\r
6733   arr.writeInt8 = BP.writeInt8\r
6734   arr.writeInt16LE = BP.writeInt16LE\r
6735   arr.writeInt16BE = BP.writeInt16BE\r
6736   arr.writeInt32LE = BP.writeInt32LE\r
6737   arr.writeInt32BE = BP.writeInt32BE\r
6738   arr.writeFloatLE = BP.writeFloatLE\r
6739   arr.writeFloatBE = BP.writeFloatBE\r
6740   arr.writeDoubleLE = BP.writeDoubleLE\r
6741   arr.writeDoubleBE = BP.writeDoubleBE\r
6742   arr.fill = BP.fill\r
6743   arr.inspect = BP.inspect\r
6744   arr.toArrayBuffer = BP.toArrayBuffer\r
6745 \r
6746   return arr\r
6747 }\r
6748 \r
6749 var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g\r
6750 \r
6751 function base64clean (str) {\r
6752   // Node strips out invalid characters like \n and \t from the string, base64-js does not\r
6753   str = stringtrim(str).replace(INVALID_BASE64_RE, '')\r
6754   // Node converts strings with length < 2 to ''\r
6755   if (str.length < 2) return ''\r
6756   // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not\r
6757   while (str.length % 4 !== 0) {\r
6758     str = str + '='\r
6759   }\r
6760   return str\r
6761 }\r
6762 \r
6763 function stringtrim (str) {\r
6764   if (str.trim) return str.trim()\r
6765   return str.replace(/^\s+|\s+$/g, '')\r
6766 }\r
6767 \r
6768 function toHex (n) {\r
6769   if (n < 16) return '0' + n.toString(16)\r
6770   return n.toString(16)\r
6771 }\r
6772 \r
6773 function utf8ToBytes (string, units) {\r
6774   units = units || Infinity\r
6775   var codePoint\r
6776   var length = string.length\r
6777   var leadSurrogate = null\r
6778   var bytes = []\r
6779 \r
6780   for (var i = 0; i < length; i++) {\r
6781     codePoint = string.charCodeAt(i)\r
6782 \r
6783     // is surrogate component\r
6784     if (codePoint > 0xD7FF && codePoint < 0xE000) {\r
6785       // last char was a lead\r
6786       if (!leadSurrogate) {\r
6787         // no lead yet\r
6788         if (codePoint > 0xDBFF) {\r
6789           // unexpected trail\r
6790           if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\r
6791           continue\r
6792         } else if (i + 1 === length) {\r
6793           // unpaired lead\r
6794           if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\r
6795           continue\r
6796         }\r
6797 \r
6798         // valid lead\r
6799         leadSurrogate = codePoint\r
6800 \r
6801         continue\r
6802       }\r
6803 \r
6804       // 2 leads in a row\r
6805       if (codePoint < 0xDC00) {\r
6806         if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\r
6807         leadSurrogate = codePoint\r
6808         continue\r
6809       }\r
6810 \r
6811       // valid surrogate pair\r
6812       codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000\r
6813     } else if (leadSurrogate) {\r
6814       // valid bmp char, but last char was a lead\r
6815       if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\r
6816     }\r
6817 \r
6818     leadSurrogate = null\r
6819 \r
6820     // encode utf8\r
6821     if (codePoint < 0x80) {\r
6822       if ((units -= 1) < 0) break\r
6823       bytes.push(codePoint)\r
6824     } else if (codePoint < 0x800) {\r
6825       if ((units -= 2) < 0) break\r
6826       bytes.push(\r
6827         codePoint >> 0x6 | 0xC0,\r
6828         codePoint & 0x3F | 0x80\r
6829       )\r
6830     } else if (codePoint < 0x10000) {\r
6831       if ((units -= 3) < 0) break\r
6832       bytes.push(\r
6833         codePoint >> 0xC | 0xE0,\r
6834         codePoint >> 0x6 & 0x3F | 0x80,\r
6835         codePoint & 0x3F | 0x80\r
6836       )\r
6837     } else if (codePoint < 0x110000) {\r
6838       if ((units -= 4) < 0) break\r
6839       bytes.push(\r
6840         codePoint >> 0x12 | 0xF0,\r
6841         codePoint >> 0xC & 0x3F | 0x80,\r
6842         codePoint >> 0x6 & 0x3F | 0x80,\r
6843         codePoint & 0x3F | 0x80\r
6844       )\r
6845     } else {\r
6846       throw new Error('Invalid code point')\r
6847     }\r
6848   }\r
6849 \r
6850   return bytes\r
6851 }\r
6852 \r
6853 function asciiToBytes (str) {\r
6854   var byteArray = []\r
6855   for (var i = 0; i < str.length; i++) {\r
6856     // Node's code seems to be doing this and not & 0x7F..\r
6857     byteArray.push(str.charCodeAt(i) & 0xFF)\r
6858   }\r
6859   return byteArray\r
6860 }\r
6861 \r
6862 function utf16leToBytes (str, units) {\r
6863   var c, hi, lo\r
6864   var byteArray = []\r
6865   for (var i = 0; i < str.length; i++) {\r
6866     if ((units -= 2) < 0) break\r
6867 \r
6868     c = str.charCodeAt(i)\r
6869     hi = c >> 8\r
6870     lo = c % 256\r
6871     byteArray.push(lo)\r
6872     byteArray.push(hi)\r
6873   }\r
6874 \r
6875   return byteArray\r
6876 }\r
6877 \r
6878 function base64ToBytes (str) {\r
6879   return base64.toByteArray(base64clean(str))\r
6880 }\r
6881 \r
6882 function blitBuffer (src, dst, offset, length) {\r
6883   for (var i = 0; i < length; i++) {\r
6884     if ((i + offset >= dst.length) || (i >= src.length)) break\r
6885     dst[i + offset] = src[i]\r
6886   }\r
6887   return i\r
6888 }\r
6889 \r
6890 },{"base64-js":16,"ieee754":17,"is-array":18}],16:[function(require,module,exports){\r
6891 var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\r
6892 \r
6893 ;(function (exports) {\r
6894         'use strict';\r
6895 \r
6896   var Arr = (typeof Uint8Array !== 'undefined')\r
6897     ? Uint8Array\r
6898     : Array\r
6899 \r
6900         var PLUS   = '+'.charCodeAt(0)\r
6901         var SLASH  = '/'.charCodeAt(0)\r
6902         var NUMBER = '0'.charCodeAt(0)\r
6903         var LOWER  = 'a'.charCodeAt(0)\r
6904         var UPPER  = 'A'.charCodeAt(0)\r
6905         var PLUS_URL_SAFE = '-'.charCodeAt(0)\r
6906         var SLASH_URL_SAFE = '_'.charCodeAt(0)\r
6907 \r
6908         function decode (elt) {\r
6909                 var code = elt.charCodeAt(0)\r
6910                 if (code === PLUS ||\r
6911                     code === PLUS_URL_SAFE)\r
6912                         return 62 // '+'\r
6913                 if (code === SLASH ||\r
6914                     code === SLASH_URL_SAFE)\r
6915                         return 63 // '/'\r
6916                 if (code < NUMBER)\r
6917                         return -1 //no match\r
6918                 if (code < NUMBER + 10)\r
6919                         return code - NUMBER + 26 + 26\r
6920                 if (code < UPPER + 26)\r
6921                         return code - UPPER\r
6922                 if (code < LOWER + 26)\r
6923                         return code - LOWER + 26\r
6924         }\r
6925 \r
6926         function b64ToByteArray (b64) {\r
6927                 var i, j, l, tmp, placeHolders, arr\r
6928 \r
6929                 if (b64.length % 4 > 0) {\r
6930                         throw new Error('Invalid string. Length must be a multiple of 4')\r
6931                 }\r
6932 \r
6933                 // the number of equal signs (place holders)\r
6934                 // if there are two placeholders, than the two characters before it\r
6935                 // represent one byte\r
6936                 // if there is only one, then the three characters before it represent 2 bytes\r
6937                 // this is just a cheap hack to not do indexOf twice\r
6938                 var len = b64.length\r
6939                 placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0\r
6940 \r
6941                 // base64 is 4/3 + up to two characters of the original data\r
6942                 arr = new Arr(b64.length * 3 / 4 - placeHolders)\r
6943 \r
6944                 // if there are placeholders, only get up to the last complete 4 chars\r
6945                 l = placeHolders > 0 ? b64.length - 4 : b64.length\r
6946 \r
6947                 var L = 0\r
6948 \r
6949                 function push (v) {\r
6950                         arr[L++] = v\r
6951                 }\r
6952 \r
6953                 for (i = 0, j = 0; i < l; i += 4, j += 3) {\r
6954                         tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3))\r
6955                         push((tmp & 0xFF0000) >> 16)\r
6956                         push((tmp & 0xFF00) >> 8)\r
6957                         push(tmp & 0xFF)\r
6958                 }\r
6959 \r
6960                 if (placeHolders === 2) {\r
6961                         tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4)\r
6962                         push(tmp & 0xFF)\r
6963                 } else if (placeHolders === 1) {\r
6964                         tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2)\r
6965                         push((tmp >> 8) & 0xFF)\r
6966                         push(tmp & 0xFF)\r
6967                 }\r
6968 \r
6969                 return arr\r
6970         }\r
6971 \r
6972         function uint8ToBase64 (uint8) {\r
6973                 var i,\r
6974                         extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes\r
6975                         output = "",\r
6976                         temp, length\r
6977 \r
6978                 function encode (num) {\r
6979                         return lookup.charAt(num)\r
6980                 }\r
6981 \r
6982                 function tripletToBase64 (num) {\r
6983                         return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F)\r
6984                 }\r
6985 \r
6986                 // go through the array every three bytes, we'll deal with trailing stuff later\r
6987                 for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {\r
6988                         temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])\r
6989                         output += tripletToBase64(temp)\r
6990                 }\r
6991 \r
6992                 // pad the end with zeros, but make sure to not forget the extra bytes\r
6993                 switch (extraBytes) {\r
6994                         case 1:\r
6995                                 temp = uint8[uint8.length - 1]\r
6996                                 output += encode(temp >> 2)\r
6997                                 output += encode((temp << 4) & 0x3F)\r
6998                                 output += '=='\r
6999                                 break\r
7000                         case 2:\r
7001                                 temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1])\r
7002                                 output += encode(temp >> 10)\r
7003                                 output += encode((temp >> 4) & 0x3F)\r
7004                                 output += encode((temp << 2) & 0x3F)\r
7005                                 output += '='\r
7006                                 break\r
7007                 }\r
7008 \r
7009                 return output\r
7010         }\r
7011 \r
7012         exports.toByteArray = b64ToByteArray\r
7013         exports.fromByteArray = uint8ToBase64\r
7014 }(typeof exports === 'undefined' ? (this.base64js = {}) : exports))\r
7015 \r
7016 },{}],17:[function(require,module,exports){\r
7017 exports.read = function (buffer, offset, isLE, mLen, nBytes) {\r
7018   var e, m\r
7019   var eLen = nBytes * 8 - mLen - 1\r
7020   var eMax = (1 << eLen) - 1\r
7021   var eBias = eMax >> 1\r
7022   var nBits = -7\r
7023   var i = isLE ? (nBytes - 1) : 0\r
7024   var d = isLE ? -1 : 1\r
7025   var s = buffer[offset + i]\r
7026 \r
7027   i += d\r
7028 \r
7029   e = s & ((1 << (-nBits)) - 1)\r
7030   s >>= (-nBits)\r
7031   nBits += eLen\r
7032   for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}\r
7033 \r
7034   m = e & ((1 << (-nBits)) - 1)\r
7035   e >>= (-nBits)\r
7036   nBits += mLen\r
7037   for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}\r
7038 \r
7039   if (e === 0) {\r
7040     e = 1 - eBias\r
7041   } else if (e === eMax) {\r
7042     return m ? NaN : ((s ? -1 : 1) * Infinity)\r
7043   } else {\r
7044     m = m + Math.pow(2, mLen)\r
7045     e = e - eBias\r
7046   }\r
7047   return (s ? -1 : 1) * m * Math.pow(2, e - mLen)\r
7048 }\r
7049 \r
7050 exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\r
7051   var e, m, c\r
7052   var eLen = nBytes * 8 - mLen - 1\r
7053   var eMax = (1 << eLen) - 1\r
7054   var eBias = eMax >> 1\r
7055   var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)\r
7056   var i = isLE ? 0 : (nBytes - 1)\r
7057   var d = isLE ? 1 : -1\r
7058   var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0\r
7059 \r
7060   value = Math.abs(value)\r
7061 \r
7062   if (isNaN(value) || value === Infinity) {\r
7063     m = isNaN(value) ? 1 : 0\r
7064     e = eMax\r
7065   } else {\r
7066     e = Math.floor(Math.log(value) / Math.LN2)\r
7067     if (value * (c = Math.pow(2, -e)) < 1) {\r
7068       e--\r
7069       c *= 2\r
7070     }\r
7071     if (e + eBias >= 1) {\r
7072       value += rt / c\r
7073     } else {\r
7074       value += rt * Math.pow(2, 1 - eBias)\r
7075     }\r
7076     if (value * c >= 2) {\r
7077       e++\r
7078       c /= 2\r
7079     }\r
7080 \r
7081     if (e + eBias >= eMax) {\r
7082       m = 0\r
7083       e = eMax\r
7084     } else if (e + eBias >= 1) {\r
7085       m = (value * c - 1) * Math.pow(2, mLen)\r
7086       e = e + eBias\r
7087     } else {\r
7088       m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)\r
7089       e = 0\r
7090     }\r
7091   }\r
7092 \r
7093   for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\r
7094 \r
7095   e = (e << mLen) | m\r
7096   eLen += mLen\r
7097   for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\r
7098 \r
7099   buffer[offset + i - d] |= s * 128\r
7100 }\r
7101 \r
7102 },{}],18:[function(require,module,exports){\r
7103 \r
7104 /**\r
7105  * isArray\r
7106  */\r
7107 \r
7108 var isArray = Array.isArray;\r
7109 \r
7110 /**\r
7111  * toString\r
7112  */\r
7113 \r
7114 var str = Object.prototype.toString;\r
7115 \r
7116 /**\r
7117  * Whether or not the given `val`\r
7118  * is an array.\r
7119  *\r
7120  * example:\r
7121  *\r
7122  *        isArray([]);\r
7123  *        // > true\r
7124  *        isArray(arguments);\r
7125  *        // > false\r
7126  *        isArray('');\r
7127  *        // > false\r
7128  *\r
7129  * @param {mixed} val\r
7130  * @return {bool}\r
7131  */\r
7132 \r
7133 module.exports = isArray || function (val) {\r
7134   return !! val && '[object Array]' == str.call(val);\r
7135 };\r
7136 \r
7137 },{}],19:[function(require,module,exports){\r
7138 \r
7139 /**\r
7140  * Expose `Emitter`.\r
7141  */\r
7142 \r
7143 module.exports = Emitter;\r
7144 \r
7145 /**\r
7146  * Initialize a new `Emitter`.\r
7147  *\r
7148  * @api public\r
7149  */\r
7150 \r
7151 function Emitter(obj) {\r
7152   if (obj) return mixin(obj);\r
7153 };\r
7154 \r
7155 /**\r
7156  * Mixin the emitter properties.\r
7157  *\r
7158  * @param {Object} obj\r
7159  * @return {Object}\r
7160  * @api private\r
7161  */\r
7162 \r
7163 function mixin(obj) {\r
7164   for (var key in Emitter.prototype) {\r
7165     obj[key] = Emitter.prototype[key];\r
7166   }\r
7167   return obj;\r
7168 }\r
7169 \r
7170 /**\r
7171  * Listen on the given `event` with `fn`.\r
7172  *\r
7173  * @param {String} event\r
7174  * @param {Function} fn\r
7175  * @return {Emitter}\r
7176  * @api public\r
7177  */\r
7178 \r
7179 Emitter.prototype.on =\r
7180 Emitter.prototype.addEventListener = function(event, fn){\r
7181   this._callbacks = this._callbacks || {};\r
7182   (this._callbacks['$' + event] = this._callbacks['$' + event] || [])\r
7183     .push(fn);\r
7184   return this;\r
7185 };\r
7186 \r
7187 /**\r
7188  * Adds an `event` listener that will be invoked a single\r
7189  * time then automatically removed.\r
7190  *\r
7191  * @param {String} event\r
7192  * @param {Function} fn\r
7193  * @return {Emitter}\r
7194  * @api public\r
7195  */\r
7196 \r
7197 Emitter.prototype.once = function(event, fn){\r
7198   function on() {\r
7199     this.off(event, on);\r
7200     fn.apply(this, arguments);\r
7201   }\r
7202 \r
7203   on.fn = fn;\r
7204   this.on(event, on);\r
7205   return this;\r
7206 };\r
7207 \r
7208 /**\r
7209  * Remove the given callback for `event` or all\r
7210  * registered callbacks.\r
7211  *\r
7212  * @param {String} event\r
7213  * @param {Function} fn\r
7214  * @return {Emitter}\r
7215  * @api public\r
7216  */\r
7217 \r
7218 Emitter.prototype.off =\r
7219 Emitter.prototype.removeListener =\r
7220 Emitter.prototype.removeAllListeners =\r
7221 Emitter.prototype.removeEventListener = function(event, fn){\r
7222   this._callbacks = this._callbacks || {};\r
7223 \r
7224   // all\r
7225   if (0 == arguments.length) {\r
7226     this._callbacks = {};\r
7227     return this;\r
7228   }\r
7229 \r
7230   // specific event\r
7231   var callbacks = this._callbacks['$' + event];\r
7232   if (!callbacks) return this;\r
7233 \r
7234   // remove all handlers\r
7235   if (1 == arguments.length) {\r
7236     delete this._callbacks['$' + event];\r
7237     return this;\r
7238   }\r
7239 \r
7240   // remove specific handler\r
7241   var cb;\r
7242   for (var i = 0; i < callbacks.length; i++) {\r
7243     cb = callbacks[i];\r
7244     if (cb === fn || cb.fn === fn) {\r
7245       callbacks.splice(i, 1);\r
7246       break;\r
7247     }\r
7248   }\r
7249   return this;\r
7250 };\r
7251 \r
7252 /**\r
7253  * Emit `event` with the given args.\r
7254  *\r
7255  * @param {String} event\r
7256  * @param {Mixed} ...\r
7257  * @return {Emitter}\r
7258  */\r
7259 \r
7260 Emitter.prototype.emit = function(event){\r
7261   this._callbacks = this._callbacks || {};\r
7262   var args = [].slice.call(arguments, 1)\r
7263     , callbacks = this._callbacks['$' + event];\r
7264 \r
7265   if (callbacks) {\r
7266     callbacks = callbacks.slice(0);\r
7267     for (var i = 0, len = callbacks.length; i < len; ++i) {\r
7268       callbacks[i].apply(this, args);\r
7269     }\r
7270   }\r
7271 \r
7272   return this;\r
7273 };\r
7274 \r
7275 /**\r
7276  * Return array of callbacks for `event`.\r
7277  *\r
7278  * @param {String} event\r
7279  * @return {Array}\r
7280  * @api public\r
7281  */\r
7282 \r
7283 Emitter.prototype.listeners = function(event){\r
7284   this._callbacks = this._callbacks || {};\r
7285   return this._callbacks['$' + event] || [];\r
7286 };\r
7287 \r
7288 /**\r
7289  * Check if this emitter has `event` handlers.\r
7290  *\r
7291  * @param {String} event\r
7292  * @return {Boolean}\r
7293  * @api public\r
7294  */\r
7295 \r
7296 Emitter.prototype.hasListeners = function(event){\r
7297   return !! this.listeners(event).length;\r
7298 };\r
7299 \r
7300 },{}],20:[function(require,module,exports){\r
7301 /* jshint node: true */\r
7302 (function () {\r
7303     "use strict";\r
7304 \r
7305     function CookieAccessInfo(domain, path, secure, script) {\r
7306         if (this instanceof CookieAccessInfo) {\r
7307             this.domain = domain || undefined;\r
7308             this.path = path || "/";\r
7309             this.secure = !!secure;\r
7310             this.script = !!script;\r
7311             return this;\r
7312         }\r
7313         return new CookieAccessInfo(domain, path, secure, script);\r
7314     }\r
7315     exports.CookieAccessInfo = CookieAccessInfo;\r
7316 \r
7317     function Cookie(cookiestr, request_domain, request_path) {\r
7318         if (cookiestr instanceof Cookie) {\r
7319             return cookiestr;\r
7320         }\r
7321         if (this instanceof Cookie) {\r
7322             this.name = null;\r
7323             this.value = null;\r
7324             this.expiration_date = Infinity;\r
7325             this.path = String(request_path || "/");\r
7326             this.explicit_path = false;\r
7327             this.domain = request_domain || null;\r
7328             this.explicit_domain = false;\r
7329             this.secure = false; //how to define default?\r
7330             this.noscript = false; //httponly\r
7331             if (cookiestr) {\r
7332                 this.parse(cookiestr, request_domain, request_path);\r
7333             }\r
7334             return this;\r
7335         }\r
7336         return new Cookie(cookiestr, request_domain, request_path);\r
7337     }\r
7338     exports.Cookie = Cookie;\r
7339 \r
7340     Cookie.prototype.toString = function toString() {\r
7341         var str = [this.name + "=" + this.value];\r
7342         if (this.expiration_date !== Infinity) {\r
7343             str.push("expires=" + (new Date(this.expiration_date)).toGMTString());\r
7344         }\r
7345         if (this.domain) {\r
7346             str.push("domain=" + this.domain);\r
7347         }\r
7348         if (this.path) {\r
7349             str.push("path=" + this.path);\r
7350         }\r
7351         if (this.secure) {\r
7352             str.push("secure");\r
7353         }\r
7354         if (this.noscript) {\r
7355             str.push("httponly");\r
7356         }\r
7357         return str.join("; ");\r
7358     };\r
7359 \r
7360     Cookie.prototype.toValueString = function toValueString() {\r
7361         return this.name + "=" + this.value;\r
7362     };\r
7363 \r
7364     var cookie_str_splitter = /[:](?=\s*[a-zA-Z0-9_\-]+\s*[=])/g;\r
7365     Cookie.prototype.parse = function parse(str, request_domain, request_path) {\r
7366         if (this instanceof Cookie) {\r
7367             var parts = str.split(";").filter(function (value) {\r
7368                     return !!value;\r
7369                 }),\r
7370                 pair = parts[0].match(/([^=]+)=([\s\S]*)/),\r
7371                 key = pair[1],\r
7372                 value = pair[2],\r
7373                 i;\r
7374             this.name = key;\r
7375             this.value = value;\r
7376 \r
7377             for (i = 1; i < parts.length; i += 1) {\r
7378                 pair = parts[i].match(/([^=]+)(?:=([\s\S]*))?/);\r
7379                 key = pair[1].trim().toLowerCase();\r
7380                 value = pair[2];\r
7381                 switch (key) {\r
7382                 case "httponly":\r
7383                     this.noscript = true;\r
7384                     break;\r
7385                 case "expires":\r
7386                     this.expiration_date = value ?\r
7387                             Number(Date.parse(value)) :\r
7388                             Infinity;\r
7389                     break;\r
7390                 case "path":\r
7391                     this.path = value ?\r
7392                             value.trim() :\r
7393                             "";\r
7394                     this.explicit_path = true;\r
7395                     break;\r
7396                 case "domain":\r
7397                     this.domain = value ?\r
7398                             value.trim() :\r
7399                             "";\r
7400                     this.explicit_domain = !!this.domain;\r
7401                     break;\r
7402                 case "secure":\r
7403                     this.secure = true;\r
7404                     break;\r
7405                 }\r
7406             }\r
7407 \r
7408             if (!this.explicit_path) {\r
7409                this.path = request_path || "/";\r
7410             }\r
7411             if (!this.explicit_domain) {\r
7412                this.domain = request_domain;\r
7413             }\r
7414 \r
7415             return this;\r
7416         }\r
7417         return new Cookie().parse(str, request_domain, request_path);\r
7418     };\r
7419 \r
7420     Cookie.prototype.matches = function matches(access_info) {\r
7421         if (this.noscript && access_info.script ||\r
7422                 this.secure && !access_info.secure ||\r
7423                 !this.collidesWith(access_info)) {\r
7424             return false;\r
7425         }\r
7426         return true;\r
7427     };\r
7428 \r
7429     Cookie.prototype.collidesWith = function collidesWith(access_info) {\r
7430         if ((this.path && !access_info.path) || (this.domain && !access_info.domain)) {\r
7431             return false;\r
7432         }\r
7433         if (this.path && access_info.path.indexOf(this.path) !== 0) {\r
7434             return false;\r
7435         }\r
7436         if (this.explicit_path && access_info.path.indexOf( this.path ) !== 0) {\r
7437            return false;\r
7438         }\r
7439         var access_domain = access_info.domain && access_info.domain.replace(/^[\.]/,'');\r
7440         var cookie_domain = this.domain && this.domain.replace(/^[\.]/,'');\r
7441         if (cookie_domain === access_domain) {\r
7442             return true;\r
7443         }\r
7444         if (cookie_domain) {\r
7445             if (!this.explicit_domain) {\r
7446                 return false; // we already checked if the domains were exactly the same\r
7447             }\r
7448             var wildcard = access_domain.indexOf(cookie_domain);\r
7449             if (wildcard === -1 || wildcard !== access_domain.length - cookie_domain.length) {\r
7450                 return false;\r
7451             }\r
7452             return true;\r
7453         }\r
7454         return true;\r
7455     };\r
7456 \r
7457     function CookieJar() {\r
7458         var cookies, cookies_list, collidable_cookie;\r
7459         if (this instanceof CookieJar) {\r
7460             cookies = Object.create(null); //name: [Cookie]\r
7461 \r
7462             this.setCookie = function setCookie(cookie, request_domain, request_path) {\r
7463                 var remove, i;\r
7464                 cookie = new Cookie(cookie, request_domain, request_path);\r
7465                 //Delete the cookie if the set is past the current time\r
7466                 remove = cookie.expiration_date <= Date.now();\r
7467                 if (cookies[cookie.name] !== undefined) {\r
7468                     cookies_list = cookies[cookie.name];\r
7469                     for (i = 0; i < cookies_list.length; i += 1) {\r
7470                         collidable_cookie = cookies_list[i];\r
7471                         if (collidable_cookie.collidesWith(cookie)) {\r
7472                             if (remove) {\r
7473                                 cookies_list.splice(i, 1);\r
7474                                 if (cookies_list.length === 0) {\r
7475                                     delete cookies[cookie.name];\r
7476                                 }\r
7477                                 return false;\r
7478                             }\r
7479                             cookies_list[i] = cookie;\r
7480                             return cookie;\r
7481                         }\r
7482                     }\r
7483                     if (remove) {\r
7484                         return false;\r
7485                     }\r
7486                     cookies_list.push(cookie);\r
7487                     return cookie;\r
7488                 }\r
7489                 if (remove) {\r
7490                     return false;\r
7491                 }\r
7492                 cookies[cookie.name] = [cookie];\r
7493                 return cookies[cookie.name];\r
7494             };\r
7495             //returns a cookie\r
7496             this.getCookie = function getCookie(cookie_name, access_info) {\r
7497                 var cookie, i;\r
7498                 cookies_list = cookies[cookie_name];\r
7499                 if (!cookies_list) {\r
7500                     return;\r
7501                 }\r
7502                 for (i = 0; i < cookies_list.length; i += 1) {\r
7503                     cookie = cookies_list[i];\r
7504                     if (cookie.expiration_date <= Date.now()) {\r
7505                         if (cookies_list.length === 0) {\r
7506                             delete cookies[cookie.name];\r
7507                         }\r
7508                         continue;\r
7509                     }\r
7510 \r
7511                     if (cookie.matches(access_info)) {\r
7512                         return cookie;\r
7513                     }\r
7514                 }\r
7515             };\r
7516             //returns a list of cookies\r
7517             this.getCookies = function getCookies(access_info) {\r
7518                 var matches = [], cookie_name, cookie;\r
7519                 for (cookie_name in cookies) {\r
7520                     cookie = this.getCookie(cookie_name, access_info);\r
7521                     if (cookie) {\r
7522                         matches.push(cookie);\r
7523                     }\r
7524                 }\r
7525                 matches.toString = function toString() {\r
7526                     return matches.join(":");\r
7527                 };\r
7528                 matches.toValueString = function toValueString() {\r
7529                     return matches.map(function (c) {\r
7530                         return c.toValueString();\r
7531                     }).join(';');\r
7532                 };\r
7533                 return matches;\r
7534             };\r
7535 \r
7536             return this;\r
7537         }\r
7538         return new CookieJar();\r
7539     }\r
7540     exports.CookieJar = CookieJar;\r
7541 \r
7542     //returns list of cookies that were set correctly. Cookies that are expired and removed are not returned.\r
7543     CookieJar.prototype.setCookies = function setCookies(cookies, request_domain, request_path) {\r
7544         cookies = Array.isArray(cookies) ?\r
7545                 cookies :\r
7546                 cookies.split(cookie_str_splitter);\r
7547         var successful = [],\r
7548             i,\r
7549             cookie;\r
7550         cookies = cookies.map(function(item){\r
7551             return new Cookie(item, request_domain, request_path);\r
7552         });\r
7553         for (i = 0; i < cookies.length; i += 1) {\r
7554             cookie = cookies[i];\r
7555             if (this.setCookie(cookie, request_domain, request_path)) {\r
7556                 successful.push(cookie);\r
7557             }\r
7558         }\r
7559         return successful;\r
7560     };\r
7561 }());\r
7562 \r
7563 },{}],21:[function(require,module,exports){\r
7564 'use strict';\r
7565 \r
7566 \r
7567 var yaml = require('./lib/js-yaml.js');\r
7568 \r
7569 \r
7570 module.exports = yaml;\r
7571 \r
7572 },{"./lib/js-yaml.js":22}],22:[function(require,module,exports){\r
7573 'use strict';\r
7574 \r
7575 \r
7576 var loader = require('./js-yaml/loader');\r
7577 var dumper = require('./js-yaml/dumper');\r
7578 \r
7579 \r
7580 function deprecated(name) {\r
7581   return function () {\r
7582     throw new Error('Function ' + name + ' is deprecated and cannot be used.');\r
7583   };\r
7584 }\r
7585 \r
7586 \r
7587 module.exports.Type                = require('./js-yaml/type');\r
7588 module.exports.Schema              = require('./js-yaml/schema');\r
7589 module.exports.FAILSAFE_SCHEMA     = require('./js-yaml/schema/failsafe');\r
7590 module.exports.JSON_SCHEMA         = require('./js-yaml/schema/json');\r
7591 module.exports.CORE_SCHEMA         = require('./js-yaml/schema/core');\r
7592 module.exports.DEFAULT_SAFE_SCHEMA = require('./js-yaml/schema/default_safe');\r
7593 module.exports.DEFAULT_FULL_SCHEMA = require('./js-yaml/schema/default_full');\r
7594 module.exports.load                = loader.load;\r
7595 module.exports.loadAll             = loader.loadAll;\r
7596 module.exports.safeLoad            = loader.safeLoad;\r
7597 module.exports.safeLoadAll         = loader.safeLoadAll;\r
7598 module.exports.dump                = dumper.dump;\r
7599 module.exports.safeDump            = dumper.safeDump;\r
7600 module.exports.YAMLException       = require('./js-yaml/exception');\r
7601 \r
7602 // Deprecated schema names from JS-YAML 2.0.x\r
7603 module.exports.MINIMAL_SCHEMA = require('./js-yaml/schema/failsafe');\r
7604 module.exports.SAFE_SCHEMA    = require('./js-yaml/schema/default_safe');\r
7605 module.exports.DEFAULT_SCHEMA = require('./js-yaml/schema/default_full');\r
7606 \r
7607 // Deprecated functions from JS-YAML 1.x.x\r
7608 module.exports.scan           = deprecated('scan');\r
7609 module.exports.parse          = deprecated('parse');\r
7610 module.exports.compose        = deprecated('compose');\r
7611 module.exports.addConstructor = deprecated('addConstructor');\r
7612 \r
7613 },{"./js-yaml/dumper":24,"./js-yaml/exception":25,"./js-yaml/loader":26,"./js-yaml/schema":28,"./js-yaml/schema/core":29,"./js-yaml/schema/default_full":30,"./js-yaml/schema/default_safe":31,"./js-yaml/schema/failsafe":32,"./js-yaml/schema/json":33,"./js-yaml/type":34}],23:[function(require,module,exports){\r
7614 'use strict';\r
7615 \r
7616 \r
7617 function isNothing(subject) {\r
7618   return (typeof subject === 'undefined') || (subject === null);\r
7619 }\r
7620 \r
7621 \r
7622 function isObject(subject) {\r
7623   return (typeof subject === 'object') && (subject !== null);\r
7624 }\r
7625 \r
7626 \r
7627 function toArray(sequence) {\r
7628   if (Array.isArray(sequence)) return sequence;\r
7629   else if (isNothing(sequence)) return [];\r
7630 \r
7631   return [ sequence ];\r
7632 }\r
7633 \r
7634 \r
7635 function extend(target, source) {\r
7636   var index, length, key, sourceKeys;\r
7637 \r
7638   if (source) {\r
7639     sourceKeys = Object.keys(source);\r
7640 \r
7641     for (index = 0, length = sourceKeys.length; index < length; index += 1) {\r
7642       key = sourceKeys[index];\r
7643       target[key] = source[key];\r
7644     }\r
7645   }\r
7646 \r
7647   return target;\r
7648 }\r
7649 \r
7650 \r
7651 function repeat(string, count) {\r
7652   var result = '', cycle;\r
7653 \r
7654   for (cycle = 0; cycle < count; cycle += 1) {\r
7655     result += string;\r
7656   }\r
7657 \r
7658   return result;\r
7659 }\r
7660 \r
7661 \r
7662 function isNegativeZero(number) {\r
7663   return (number === 0) && (Number.NEGATIVE_INFINITY === 1 / number);\r
7664 }\r
7665 \r
7666 \r
7667 module.exports.isNothing      = isNothing;\r
7668 module.exports.isObject       = isObject;\r
7669 module.exports.toArray        = toArray;\r
7670 module.exports.repeat         = repeat;\r
7671 module.exports.isNegativeZero = isNegativeZero;\r
7672 module.exports.extend         = extend;\r
7673 \r
7674 },{}],24:[function(require,module,exports){\r
7675 'use strict';\r
7676 \r
7677 /*eslint-disable no-use-before-define*/\r
7678 \r
7679 var common              = require('./common');\r
7680 var YAMLException       = require('./exception');\r
7681 var DEFAULT_FULL_SCHEMA = require('./schema/default_full');\r
7682 var DEFAULT_SAFE_SCHEMA = require('./schema/default_safe');\r
7683 \r
7684 var _toString       = Object.prototype.toString;\r
7685 var _hasOwnProperty = Object.prototype.hasOwnProperty;\r
7686 \r
7687 var CHAR_TAB                  = 0x09; /* Tab */\r
7688 var CHAR_LINE_FEED            = 0x0A; /* LF */\r
7689 var CHAR_CARRIAGE_RETURN      = 0x0D; /* CR */\r
7690 var CHAR_SPACE                = 0x20; /* Space */\r
7691 var CHAR_EXCLAMATION          = 0x21; /* ! */\r
7692 var CHAR_DOUBLE_QUOTE         = 0x22; /* " */\r
7693 var CHAR_SHARP                = 0x23; /* # */\r
7694 var CHAR_PERCENT              = 0x25; /* % */\r
7695 var CHAR_AMPERSAND            = 0x26; /* & */\r
7696 var CHAR_SINGLE_QUOTE         = 0x27; /* ' */\r
7697 var CHAR_ASTERISK             = 0x2A; /* * */\r
7698 var CHAR_COMMA                = 0x2C; /* , */\r
7699 var CHAR_MINUS                = 0x2D; /* - */\r
7700 var CHAR_COLON                = 0x3A; /* : */\r
7701 var CHAR_GREATER_THAN         = 0x3E; /* > */\r
7702 var CHAR_QUESTION             = 0x3F; /* ? */\r
7703 var CHAR_COMMERCIAL_AT        = 0x40; /* @ */\r
7704 var CHAR_LEFT_SQUARE_BRACKET  = 0x5B; /* [ */\r
7705 var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */\r
7706 var CHAR_GRAVE_ACCENT         = 0x60; /* ` */\r
7707 var CHAR_LEFT_CURLY_BRACKET   = 0x7B; /* { */\r
7708 var CHAR_VERTICAL_LINE        = 0x7C; /* | */\r
7709 var CHAR_RIGHT_CURLY_BRACKET  = 0x7D; /* } */\r
7710 \r
7711 var ESCAPE_SEQUENCES = {};\r
7712 \r
7713 ESCAPE_SEQUENCES[0x00]   = '\\0';\r
7714 ESCAPE_SEQUENCES[0x07]   = '\\a';\r
7715 ESCAPE_SEQUENCES[0x08]   = '\\b';\r
7716 ESCAPE_SEQUENCES[0x09]   = '\\t';\r
7717 ESCAPE_SEQUENCES[0x0A]   = '\\n';\r
7718 ESCAPE_SEQUENCES[0x0B]   = '\\v';\r
7719 ESCAPE_SEQUENCES[0x0C]   = '\\f';\r
7720 ESCAPE_SEQUENCES[0x0D]   = '\\r';\r
7721 ESCAPE_SEQUENCES[0x1B]   = '\\e';\r
7722 ESCAPE_SEQUENCES[0x22]   = '\\"';\r
7723 ESCAPE_SEQUENCES[0x5C]   = '\\\\';\r
7724 ESCAPE_SEQUENCES[0x85]   = '\\N';\r
7725 ESCAPE_SEQUENCES[0xA0]   = '\\_';\r
7726 ESCAPE_SEQUENCES[0x2028] = '\\L';\r
7727 ESCAPE_SEQUENCES[0x2029] = '\\P';\r
7728 \r
7729 var DEPRECATED_BOOLEANS_SYNTAX = [\r
7730   'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON',\r
7731   'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF'\r
7732 ];\r
7733 \r
7734 function compileStyleMap(schema, map) {\r
7735   var result, keys, index, length, tag, style, type;\r
7736 \r
7737   if (map === null) return {};\r
7738 \r
7739   result = {};\r
7740   keys = Object.keys(map);\r
7741 \r
7742   for (index = 0, length = keys.length; index < length; index += 1) {\r
7743     tag = keys[index];\r
7744     style = String(map[tag]);\r
7745 \r
7746     if (tag.slice(0, 2) === '!!') {\r
7747       tag = 'tag:yaml.org,2002:' + tag.slice(2);\r
7748     }\r
7749 \r
7750     type = schema.compiledTypeMap[tag];\r
7751 \r
7752     if (type && _hasOwnProperty.call(type.styleAliases, style)) {\r
7753       style = type.styleAliases[style];\r
7754     }\r
7755 \r
7756     result[tag] = style;\r
7757   }\r
7758 \r
7759   return result;\r
7760 }\r
7761 \r
7762 function encodeHex(character) {\r
7763   var string, handle, length;\r
7764 \r
7765   string = character.toString(16).toUpperCase();\r
7766 \r
7767   if (character <= 0xFF) {\r
7768     handle = 'x';\r
7769     length = 2;\r
7770   } else if (character <= 0xFFFF) {\r
7771     handle = 'u';\r
7772     length = 4;\r
7773   } else if (character <= 0xFFFFFFFF) {\r
7774     handle = 'U';\r
7775     length = 8;\r
7776   } else {\r
7777     throw new YAMLException('code point within a string may not be greater than 0xFFFFFFFF');\r
7778   }\r
7779 \r
7780   return '\\' + handle + common.repeat('0', length - string.length) + string;\r
7781 }\r
7782 \r
7783 function State(options) {\r
7784   this.schema      = options['schema'] || DEFAULT_FULL_SCHEMA;\r
7785   this.indent      = Math.max(1, (options['indent'] || 2));\r
7786   this.skipInvalid = options['skipInvalid'] || false;\r
7787   this.flowLevel   = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']);\r
7788   this.styleMap    = compileStyleMap(this.schema, options['styles'] || null);\r
7789   this.sortKeys    = options['sortKeys'] || false;\r
7790   this.lineWidth   = options['lineWidth'] || 80;\r
7791   this.noRefs      = options['noRefs'] || false;\r
7792 \r
7793   this.implicitTypes = this.schema.compiledImplicit;\r
7794   this.explicitTypes = this.schema.compiledExplicit;\r
7795 \r
7796   this.tag = null;\r
7797   this.result = '';\r
7798 \r
7799   this.duplicates = [];\r
7800   this.usedDuplicates = null;\r
7801 }\r
7802 \r
7803 function indentString(string, spaces) {\r
7804   var ind = common.repeat(' ', spaces),\r
7805       position = 0,\r
7806       next = -1,\r
7807       result = '',\r
7808       line,\r
7809       length = string.length;\r
7810 \r
7811   while (position < length) {\r
7812     next = string.indexOf('\n', position);\r
7813     if (next === -1) {\r
7814       line = string.slice(position);\r
7815       position = length;\r
7816     } else {\r
7817       line = string.slice(position, next + 1);\r
7818       position = next + 1;\r
7819     }\r
7820 \r
7821     if (line.length && line !== '\n') result += ind;\r
7822 \r
7823     result += line;\r
7824   }\r
7825 \r
7826   return result;\r
7827 }\r
7828 \r
7829 function generateNextLine(state, level) {\r
7830   return '\n' + common.repeat(' ', state.indent * level);\r
7831 }\r
7832 \r
7833 function testImplicitResolving(state, str) {\r
7834   var index, length, type;\r
7835 \r
7836   for (index = 0, length = state.implicitTypes.length; index < length; index += 1) {\r
7837     type = state.implicitTypes[index];\r
7838 \r
7839     if (type.resolve(str)) {\r
7840       return true;\r
7841     }\r
7842   }\r
7843 \r
7844   return false;\r
7845 }\r
7846 \r
7847 function StringBuilder(source) {\r
7848   this.source = source;\r
7849   this.result = '';\r
7850   this.checkpoint = 0;\r
7851 }\r
7852 \r
7853 StringBuilder.prototype.takeUpTo = function (position) {\r
7854   var er;\r
7855 \r
7856   if (position < this.checkpoint) {\r
7857     er = new Error('position should be > checkpoint');\r
7858     er.position = position;\r
7859     er.checkpoint = this.checkpoint;\r
7860     throw er;\r
7861   }\r
7862 \r
7863   this.result += this.source.slice(this.checkpoint, position);\r
7864   this.checkpoint = position;\r
7865   return this;\r
7866 };\r
7867 \r
7868 StringBuilder.prototype.escapeChar = function () {\r
7869   var character, esc;\r
7870 \r
7871   character = this.source.charCodeAt(this.checkpoint);\r
7872   esc = ESCAPE_SEQUENCES[character] || encodeHex(character);\r
7873   this.result += esc;\r
7874   this.checkpoint += 1;\r
7875 \r
7876   return this;\r
7877 };\r
7878 \r
7879 StringBuilder.prototype.finish = function () {\r
7880   if (this.source.length > this.checkpoint) {\r
7881     this.takeUpTo(this.source.length);\r
7882   }\r
7883 };\r
7884 \r
7885 function writeScalar(state, object, level, iskey) {\r
7886   var simple, first, spaceWrap, folded, literal, single, double,\r
7887       sawLineFeed, linePosition, longestLine, indent, max, character,\r
7888       position, escapeSeq, hexEsc, previous, lineLength, modifier,\r
7889       trailingLineBreaks, result;\r
7890 \r
7891   if (object.length === 0) {\r
7892     state.dump = "''";\r
7893     return;\r
7894   }\r
7895 \r
7896   if (DEPRECATED_BOOLEANS_SYNTAX.indexOf(object) !== -1) {\r
7897     state.dump = "'" + object + "'";\r
7898     return;\r
7899   }\r
7900 \r
7901   simple = true;\r
7902   first = object.length ? object.charCodeAt(0) : 0;\r
7903   spaceWrap = (CHAR_SPACE === first ||\r
7904                CHAR_SPACE === object.charCodeAt(object.length - 1));\r
7905 \r
7906   // Simplified check for restricted first characters\r
7907   // http://www.yaml.org/spec/1.2/spec.html#ns-plain-first%28c%29\r
7908   if (CHAR_MINUS         === first ||\r
7909       CHAR_QUESTION      === first ||\r
7910       CHAR_COMMERCIAL_AT === first ||\r
7911       CHAR_GRAVE_ACCENT  === first) {\r
7912     simple = false;\r
7913   }\r
7914 \r
7915   // Can only use > and | if not wrapped in spaces or is not a key.\r
7916   // Also, don't use if in flow mode.\r
7917   if (spaceWrap || (state.flowLevel > -1 && state.flowLevel <= level)) {\r
7918     if (spaceWrap) simple = false;\r
7919 \r
7920     folded = false;\r
7921     literal = false;\r
7922   } else {\r
7923     folded = !iskey;\r
7924     literal = !iskey;\r
7925   }\r
7926 \r
7927   single = true;\r
7928   double = new StringBuilder(object);\r
7929 \r
7930   sawLineFeed = false;\r
7931   linePosition = 0;\r
7932   longestLine = 0;\r
7933 \r
7934   indent = state.indent * level;\r
7935   max = state.lineWidth;\r
7936 \r
7937   // Replace -1 with biggest ingeger number according to\r
7938   // http://ecma262-5.com/ELS5_HTML.htm#Section_8.5\r
7939   if (max === -1) max = 9007199254740991;\r
7940 \r
7941   if (indent < 40) max -= indent;\r
7942   else max = 40;\r
7943 \r
7944   for (position = 0; position < object.length; position++) {\r
7945     character = object.charCodeAt(position);\r
7946     if (simple) {\r
7947       // Characters that can never appear in the simple scalar\r
7948       if (!simpleChar(character)) {\r
7949         simple = false;\r
7950       } else {\r
7951         // Still simple.  If we make it all the way through like\r
7952         // this, then we can just dump the string as-is.\r
7953         continue;\r
7954       }\r
7955     }\r
7956 \r
7957     if (single && character === CHAR_SINGLE_QUOTE) {\r
7958       single = false;\r
7959     }\r
7960 \r
7961     escapeSeq = ESCAPE_SEQUENCES[character];\r
7962     hexEsc = needsHexEscape(character);\r
7963 \r
7964     if (!escapeSeq && !hexEsc) {\r
7965       continue;\r
7966     }\r
7967 \r
7968     if (character !== CHAR_LINE_FEED &&\r
7969         character !== CHAR_DOUBLE_QUOTE &&\r
7970         character !== CHAR_SINGLE_QUOTE) {\r
7971       folded = false;\r
7972       literal = false;\r
7973     } else if (character === CHAR_LINE_FEED) {\r
7974       sawLineFeed = true;\r
7975       single = false;\r
7976       if (position > 0) {\r
7977         previous = object.charCodeAt(position - 1);\r
7978         if (previous === CHAR_SPACE) {\r
7979           literal = false;\r
7980           folded = false;\r
7981         }\r
7982       }\r
7983       if (folded) {\r
7984         lineLength = position - linePosition;\r
7985         linePosition = position;\r
7986         if (lineLength > longestLine) longestLine = lineLength;\r
7987       }\r
7988     }\r
7989 \r
7990     if (character !== CHAR_DOUBLE_QUOTE) single = false;\r
7991 \r
7992     double.takeUpTo(position);\r
7993     double.escapeChar();\r
7994   }\r
7995 \r
7996   if (simple && testImplicitResolving(state, object)) simple = false;\r
7997 \r
7998   modifier = '';\r
7999   if (folded || literal) {\r
8000     trailingLineBreaks = 0;\r
8001     if (object.charCodeAt(object.length - 1) === CHAR_LINE_FEED) {\r
8002       trailingLineBreaks += 1;\r
8003       if (object.charCodeAt(object.length - 2) === CHAR_LINE_FEED) {\r
8004         trailingLineBreaks += 1;\r
8005       }\r
8006     }\r
8007 \r
8008     if (trailingLineBreaks === 0) modifier = '-';\r
8009     else if (trailingLineBreaks === 2) modifier = '+';\r
8010   }\r
8011 \r
8012   if (literal && longestLine < max || state.tag !== null) {\r
8013     folded = false;\r
8014   }\r
8015 \r
8016   // If it's literally one line, then don't bother with the literal.\r
8017   // We may still want to do a fold, though, if it's a super long line.\r
8018   if (!sawLineFeed) literal = false;\r
8019 \r
8020   if (simple) {\r
8021     state.dump = object;\r
8022   } else if (single) {\r
8023     state.dump = '\'' + object + '\'';\r
8024   } else if (folded) {\r
8025     result = fold(object, max);\r
8026     state.dump = '>' + modifier + '\n' + indentString(result, indent);\r
8027   } else if (literal) {\r
8028     if (!modifier) object = object.replace(/\n$/, '');\r
8029     state.dump = '|' + modifier + '\n' + indentString(object, indent);\r
8030   } else if (double) {\r
8031     double.finish();\r
8032     state.dump = '"' + double.result + '"';\r
8033   } else {\r
8034     throw new Error('Failed to dump scalar value');\r
8035   }\r
8036 \r
8037   return;\r
8038 }\r
8039 \r
8040 // The `trailing` var is a regexp match of any trailing `\n` characters.\r
8041 //\r
8042 // There are three cases we care about:\r
8043 //\r
8044 // 1. One trailing `\n` on the string.  Just use `|` or `>`.\r
8045 //    This is the assumed default. (trailing = null)\r
8046 // 2. No trailing `\n` on the string.  Use `|-` or `>-` to "chomp" the end.\r
8047 // 3. More than one trailing `\n` on the string.  Use `|+` or `>+`.\r
8048 //\r
8049 // In the case of `>+`, these line breaks are *not* doubled (like the line\r
8050 // breaks within the string), so it's important to only end with the exact\r
8051 // same number as we started.\r
8052 function fold(object, max) {\r
8053   var result = '',\r
8054       position = 0,\r
8055       length = object.length,\r
8056       trailing = /\n+$/.exec(object),\r
8057       newLine;\r
8058 \r
8059   if (trailing) {\r
8060     length = trailing.index + 1;\r
8061   }\r
8062 \r
8063   while (position < length) {\r
8064     newLine = object.indexOf('\n', position);\r
8065     if (newLine > length || newLine === -1) {\r
8066       if (result) result += '\n\n';\r
8067       result += foldLine(object.slice(position, length), max);\r
8068       position = length;\r
8069 \r
8070     } else {\r
8071       if (result) result += '\n\n';\r
8072       result += foldLine(object.slice(position, newLine), max);\r
8073       position = newLine + 1;\r
8074     }\r
8075   }\r
8076 \r
8077   if (trailing && trailing[0] !== '\n') result += trailing[0];\r
8078 \r
8079   return result;\r
8080 }\r
8081 \r
8082 function foldLine(line, max) {\r
8083   if (line === '') return line;\r
8084 \r
8085   var foldRe = /[^\s] [^\s]/g,\r
8086       result = '',\r
8087       prevMatch = 0,\r
8088       foldStart = 0,\r
8089       match = foldRe.exec(line),\r
8090       index,\r
8091       foldEnd,\r
8092       folded;\r
8093 \r
8094   while (match) {\r
8095     index = match.index;\r
8096 \r
8097     // when we cross the max len, if the previous match would've\r
8098     // been ok, use that one, and carry on.  If there was no previous\r
8099     // match on this fold section, then just have a long line.\r
8100     if (index - foldStart > max) {\r
8101       if (prevMatch !== foldStart) foldEnd = prevMatch;\r
8102       else foldEnd = index;\r
8103 \r
8104       if (result) result += '\n';\r
8105       folded = line.slice(foldStart, foldEnd);\r
8106       result += folded;\r
8107       foldStart = foldEnd + 1;\r
8108     }\r
8109     prevMatch = index + 1;\r
8110     match = foldRe.exec(line);\r
8111   }\r
8112 \r
8113   if (result) result += '\n';\r
8114 \r
8115   // if we end up with one last word at the end, then the last bit might\r
8116   // be slightly bigger than we wanted, because we exited out of the loop.\r
8117   if (foldStart !== prevMatch && line.length - foldStart > max) {\r
8118     result += line.slice(foldStart, prevMatch) + '\n' +\r
8119               line.slice(prevMatch + 1);\r
8120   } else {\r
8121     result += line.slice(foldStart);\r
8122   }\r
8123 \r
8124   return result;\r
8125 }\r
8126 \r
8127 // Returns true if character can be found in a simple scalar\r
8128 function simpleChar(character) {\r
8129   return CHAR_TAB                  !== character &&\r
8130          CHAR_LINE_FEED            !== character &&\r
8131          CHAR_CARRIAGE_RETURN      !== character &&\r
8132          CHAR_COMMA                !== character &&\r
8133          CHAR_LEFT_SQUARE_BRACKET  !== character &&\r
8134          CHAR_RIGHT_SQUARE_BRACKET !== character &&\r
8135          CHAR_LEFT_CURLY_BRACKET   !== character &&\r
8136          CHAR_RIGHT_CURLY_BRACKET  !== character &&\r
8137          CHAR_SHARP                !== character &&\r
8138          CHAR_AMPERSAND            !== character &&\r
8139          CHAR_ASTERISK             !== character &&\r
8140          CHAR_EXCLAMATION          !== character &&\r
8141          CHAR_VERTICAL_LINE        !== character &&\r
8142          CHAR_GREATER_THAN         !== character &&\r
8143          CHAR_SINGLE_QUOTE         !== character &&\r
8144          CHAR_DOUBLE_QUOTE         !== character &&\r
8145          CHAR_PERCENT              !== character &&\r
8146          CHAR_COLON                !== character &&\r
8147          !ESCAPE_SEQUENCES[character]            &&\r
8148          !needsHexEscape(character);\r
8149 }\r
8150 \r
8151 // Returns true if the character code needs to be escaped.\r
8152 function needsHexEscape(character) {\r
8153   return !((0x00020 <= character && character <= 0x00007E) ||\r
8154            (character === 0x00085)                         ||\r
8155            (0x000A0 <= character && character <= 0x00D7FF) ||\r
8156            (0x0E000 <= character && character <= 0x00FFFD) ||\r
8157            (0x10000 <= character && character <= 0x10FFFF));\r
8158 }\r
8159 \r
8160 function writeFlowSequence(state, level, object) {\r
8161   var _result = '',\r
8162       _tag    = state.tag,\r
8163       index,\r
8164       length;\r
8165 \r
8166   for (index = 0, length = object.length; index < length; index += 1) {\r
8167     // Write only valid elements.\r
8168     if (writeNode(state, level, object[index], false, false)) {\r
8169       if (index !== 0) _result += ', ';\r
8170       _result += state.dump;\r
8171     }\r
8172   }\r
8173 \r
8174   state.tag = _tag;\r
8175   state.dump = '[' + _result + ']';\r
8176 }\r
8177 \r
8178 function writeBlockSequence(state, level, object, compact) {\r
8179   var _result = '',\r
8180       _tag    = state.tag,\r
8181       index,\r
8182       length;\r
8183 \r
8184   for (index = 0, length = object.length; index < length; index += 1) {\r
8185     // Write only valid elements.\r
8186     if (writeNode(state, level + 1, object[index], true, true)) {\r
8187       if (!compact || index !== 0) {\r
8188         _result += generateNextLine(state, level);\r
8189       }\r
8190       _result += '- ' + state.dump;\r
8191     }\r
8192   }\r
8193 \r
8194   state.tag = _tag;\r
8195   state.dump = _result || '[]'; // Empty sequence if no valid values.\r
8196 }\r
8197 \r
8198 function writeFlowMapping(state, level, object) {\r
8199   var _result       = '',\r
8200       _tag          = state.tag,\r
8201       objectKeyList = Object.keys(object),\r
8202       index,\r
8203       length,\r
8204       objectKey,\r
8205       objectValue,\r
8206       pairBuffer;\r
8207 \r
8208   for (index = 0, length = objectKeyList.length; index < length; index += 1) {\r
8209     pairBuffer = '';\r
8210 \r
8211     if (index !== 0) pairBuffer += ', ';\r
8212 \r
8213     objectKey = objectKeyList[index];\r
8214     objectValue = object[objectKey];\r
8215 \r
8216     if (!writeNode(state, level, objectKey, false, false)) {\r
8217       continue; // Skip this pair because of invalid key;\r
8218     }\r
8219 \r
8220     if (state.dump.length > 1024) pairBuffer += '? ';\r
8221 \r
8222     pairBuffer += state.dump + ': ';\r
8223 \r
8224     if (!writeNode(state, level, objectValue, false, false)) {\r
8225       continue; // Skip this pair because of invalid value.\r
8226     }\r
8227 \r
8228     pairBuffer += state.dump;\r
8229 \r
8230     // Both key and value are valid.\r
8231     _result += pairBuffer;\r
8232   }\r
8233 \r
8234   state.tag = _tag;\r
8235   state.dump = '{' + _result + '}';\r
8236 }\r
8237 \r
8238 function writeBlockMapping(state, level, object, compact) {\r
8239   var _result       = '',\r
8240       _tag          = state.tag,\r
8241       objectKeyList = Object.keys(object),\r
8242       index,\r
8243       length,\r
8244       objectKey,\r
8245       objectValue,\r
8246       explicitPair,\r
8247       pairBuffer;\r
8248 \r
8249   // Allow sorting keys so that the output file is deterministic\r
8250   if (state.sortKeys === true) {\r
8251     // Default sorting\r
8252     objectKeyList.sort();\r
8253   } else if (typeof state.sortKeys === 'function') {\r
8254     // Custom sort function\r
8255     objectKeyList.sort(state.sortKeys);\r
8256   } else if (state.sortKeys) {\r
8257     // Something is wrong\r
8258     throw new YAMLException('sortKeys must be a boolean or a function');\r
8259   }\r
8260 \r
8261   for (index = 0, length = objectKeyList.length; index < length; index += 1) {\r
8262     pairBuffer = '';\r
8263 \r
8264     if (!compact || index !== 0) {\r
8265       pairBuffer += generateNextLine(state, level);\r
8266     }\r
8267 \r
8268     objectKey = objectKeyList[index];\r
8269     objectValue = object[objectKey];\r
8270 \r
8271     if (!writeNode(state, level + 1, objectKey, true, true, true)) {\r
8272       continue; // Skip this pair because of invalid key.\r
8273     }\r
8274 \r
8275     explicitPair = (state.tag !== null && state.tag !== '?') ||\r
8276                    (state.dump && state.dump.length > 1024);\r
8277 \r
8278     if (explicitPair) {\r
8279       if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\r
8280         pairBuffer += '?';\r
8281       } else {\r
8282         pairBuffer += '? ';\r
8283       }\r
8284     }\r
8285 \r
8286     pairBuffer += state.dump;\r
8287 \r
8288     if (explicitPair) {\r
8289       pairBuffer += generateNextLine(state, level);\r
8290     }\r
8291 \r
8292     if (!writeNode(state, level + 1, objectValue, true, explicitPair)) {\r
8293       continue; // Skip this pair because of invalid value.\r
8294     }\r
8295 \r
8296     if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\r
8297       pairBuffer += ':';\r
8298     } else {\r
8299       pairBuffer += ': ';\r
8300     }\r
8301 \r
8302     pairBuffer += state.dump;\r
8303 \r
8304     // Both key and value are valid.\r
8305     _result += pairBuffer;\r
8306   }\r
8307 \r
8308   state.tag = _tag;\r
8309   state.dump = _result || '{}'; // Empty mapping if no valid pairs.\r
8310 }\r
8311 \r
8312 function detectType(state, object, explicit) {\r
8313   var _result, typeList, index, length, type, style;\r
8314 \r
8315   typeList = explicit ? state.explicitTypes : state.implicitTypes;\r
8316 \r
8317   for (index = 0, length = typeList.length; index < length; index += 1) {\r
8318     type = typeList[index];\r
8319 \r
8320     if ((type.instanceOf  || type.predicate) &&\r
8321         (!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) &&\r
8322         (!type.predicate  || type.predicate(object))) {\r
8323 \r
8324       state.tag = explicit ? type.tag : '?';\r
8325 \r
8326       if (type.represent) {\r
8327         style = state.styleMap[type.tag] || type.defaultStyle;\r
8328 \r
8329         if (_toString.call(type.represent) === '[object Function]') {\r
8330           _result = type.represent(object, style);\r
8331         } else if (_hasOwnProperty.call(type.represent, style)) {\r
8332           _result = type.represent[style](object, style);\r
8333         } else {\r
8334           throw new YAMLException('!<' + type.tag + '> tag resolver accepts not "' + style + '" style');\r
8335         }\r
8336 \r
8337         state.dump = _result;\r
8338       }\r
8339 \r
8340       return true;\r
8341     }\r
8342   }\r
8343 \r
8344   return false;\r
8345 }\r
8346 \r
8347 // Serializes `object` and writes it to global `result`.\r
8348 // Returns true on success, or false on invalid object.\r
8349 //\r
8350 function writeNode(state, level, object, block, compact, iskey) {\r
8351   state.tag = null;\r
8352   state.dump = object;\r
8353 \r
8354   if (!detectType(state, object, false)) {\r
8355     detectType(state, object, true);\r
8356   }\r
8357 \r
8358   var type = _toString.call(state.dump);\r
8359 \r
8360   if (block) {\r
8361     block = (state.flowLevel < 0 || state.flowLevel > level);\r
8362   }\r
8363 \r
8364   var objectOrArray = type === '[object Object]' || type === '[object Array]',\r
8365       duplicateIndex,\r
8366       duplicate;\r
8367 \r
8368   if (objectOrArray) {\r
8369     duplicateIndex = state.duplicates.indexOf(object);\r
8370     duplicate = duplicateIndex !== -1;\r
8371   }\r
8372 \r
8373   if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) {\r
8374     compact = false;\r
8375   }\r
8376 \r
8377   if (duplicate && state.usedDuplicates[duplicateIndex]) {\r
8378     state.dump = '*ref_' + duplicateIndex;\r
8379   } else {\r
8380     if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) {\r
8381       state.usedDuplicates[duplicateIndex] = true;\r
8382     }\r
8383     if (type === '[object Object]') {\r
8384       if (block && (Object.keys(state.dump).length !== 0)) {\r
8385         writeBlockMapping(state, level, state.dump, compact);\r
8386         if (duplicate) {\r
8387           state.dump = '&ref_' + duplicateIndex + state.dump;\r
8388         }\r
8389       } else {\r
8390         writeFlowMapping(state, level, state.dump);\r
8391         if (duplicate) {\r
8392           state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;\r
8393         }\r
8394       }\r
8395     } else if (type === '[object Array]') {\r
8396       if (block && (state.dump.length !== 0)) {\r
8397         writeBlockSequence(state, level, state.dump, compact);\r
8398         if (duplicate) {\r
8399           state.dump = '&ref_' + duplicateIndex + state.dump;\r
8400         }\r
8401       } else {\r
8402         writeFlowSequence(state, level, state.dump);\r
8403         if (duplicate) {\r
8404           state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;\r
8405         }\r
8406       }\r
8407     } else if (type === '[object String]') {\r
8408       if (state.tag !== '?') {\r
8409         writeScalar(state, state.dump, level, iskey);\r
8410       }\r
8411     } else {\r
8412       if (state.skipInvalid) return false;\r
8413       throw new YAMLException('unacceptable kind of an object to dump ' + type);\r
8414     }\r
8415 \r
8416     if (state.tag !== null && state.tag !== '?') {\r
8417       state.dump = '!<' + state.tag + '> ' + state.dump;\r
8418     }\r
8419   }\r
8420 \r
8421   return true;\r
8422 }\r
8423 \r
8424 function getDuplicateReferences(object, state) {\r
8425   var objects = [],\r
8426       duplicatesIndexes = [],\r
8427       index,\r
8428       length;\r
8429 \r
8430   inspectNode(object, objects, duplicatesIndexes);\r
8431 \r
8432   for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) {\r
8433     state.duplicates.push(objects[duplicatesIndexes[index]]);\r
8434   }\r
8435   state.usedDuplicates = new Array(length);\r
8436 }\r
8437 \r
8438 function inspectNode(object, objects, duplicatesIndexes) {\r
8439   var objectKeyList,\r
8440       index,\r
8441       length;\r
8442 \r
8443   if (object !== null && typeof object === 'object') {\r
8444     index = objects.indexOf(object);\r
8445     if (index !== -1) {\r
8446       if (duplicatesIndexes.indexOf(index) === -1) {\r
8447         duplicatesIndexes.push(index);\r
8448       }\r
8449     } else {\r
8450       objects.push(object);\r
8451 \r
8452       if (Array.isArray(object)) {\r
8453         for (index = 0, length = object.length; index < length; index += 1) {\r
8454           inspectNode(object[index], objects, duplicatesIndexes);\r
8455         }\r
8456       } else {\r
8457         objectKeyList = Object.keys(object);\r
8458 \r
8459         for (index = 0, length = objectKeyList.length; index < length; index += 1) {\r
8460           inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes);\r
8461         }\r
8462       }\r
8463     }\r
8464   }\r
8465 }\r
8466 \r
8467 function dump(input, options) {\r
8468   options = options || {};\r
8469 \r
8470   var state = new State(options);\r
8471 \r
8472   if (!state.noRefs) getDuplicateReferences(input, state);\r
8473 \r
8474   if (writeNode(state, 0, input, true, true)) return state.dump + '\n';\r
8475 \r
8476   return '';\r
8477 }\r
8478 \r
8479 function safeDump(input, options) {\r
8480   return dump(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options));\r
8481 }\r
8482 \r
8483 module.exports.dump     = dump;\r
8484 module.exports.safeDump = safeDump;\r
8485 \r
8486 },{"./common":23,"./exception":25,"./schema/default_full":30,"./schema/default_safe":31}],25:[function(require,module,exports){\r
8487 // YAML error class. http://stackoverflow.com/questions/8458984\r
8488 //\r
8489 'use strict';\r
8490 \r
8491 function YAMLException(reason, mark) {\r
8492   // Super constructor\r
8493   Error.call(this);\r
8494 \r
8495   // Include stack trace in error object\r
8496   if (Error.captureStackTrace) {\r
8497     // Chrome and NodeJS\r
8498     Error.captureStackTrace(this, this.constructor);\r
8499   } else {\r
8500     // FF, IE 10+ and Safari 6+. Fallback for others\r
8501     this.stack = (new Error()).stack || '';\r
8502   }\r
8503 \r
8504   this.name = 'YAMLException';\r
8505   this.reason = reason;\r
8506   this.mark = mark;\r
8507   this.message = (this.reason || '(unknown reason)') + (this.mark ? ' ' + this.mark.toString() : '');\r
8508 }\r
8509 \r
8510 \r
8511 // Inherit from Error\r
8512 YAMLException.prototype = Object.create(Error.prototype);\r
8513 YAMLException.prototype.constructor = YAMLException;\r
8514 \r
8515 \r
8516 YAMLException.prototype.toString = function toString(compact) {\r
8517   var result = this.name + ': ';\r
8518 \r
8519   result += this.reason || '(unknown reason)';\r
8520 \r
8521   if (!compact && this.mark) {\r
8522     result += ' ' + this.mark.toString();\r
8523   }\r
8524 \r
8525   return result;\r
8526 };\r
8527 \r
8528 \r
8529 module.exports = YAMLException;\r
8530 \r
8531 },{}],26:[function(require,module,exports){\r
8532 'use strict';\r
8533 \r
8534 /*eslint-disable max-len,no-use-before-define*/\r
8535 \r
8536 var common              = require('./common');\r
8537 var YAMLException       = require('./exception');\r
8538 var Mark                = require('./mark');\r
8539 var DEFAULT_SAFE_SCHEMA = require('./schema/default_safe');\r
8540 var DEFAULT_FULL_SCHEMA = require('./schema/default_full');\r
8541 \r
8542 \r
8543 var _hasOwnProperty = Object.prototype.hasOwnProperty;\r
8544 \r
8545 \r
8546 var CONTEXT_FLOW_IN   = 1;\r
8547 var CONTEXT_FLOW_OUT  = 2;\r
8548 var CONTEXT_BLOCK_IN  = 3;\r
8549 var CONTEXT_BLOCK_OUT = 4;\r
8550 \r
8551 \r
8552 var CHOMPING_CLIP  = 1;\r
8553 var CHOMPING_STRIP = 2;\r
8554 var CHOMPING_KEEP  = 3;\r
8555 \r
8556 \r
8557 var PATTERN_NON_PRINTABLE         = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/;\r
8558 var PATTERN_NON_ASCII_LINE_BREAKS = /[\x85\u2028\u2029]/;\r
8559 var PATTERN_FLOW_INDICATORS       = /[,\[\]\{\}]/;\r
8560 var PATTERN_TAG_HANDLE            = /^(?:!|!!|![a-z\-]+!)$/i;\r
8561 var PATTERN_TAG_URI               = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;\r
8562 \r
8563 \r
8564 function is_EOL(c) {\r
8565   return (c === 0x0A/* LF */) || (c === 0x0D/* CR */);\r
8566 }\r
8567 \r
8568 function is_WHITE_SPACE(c) {\r
8569   return (c === 0x09/* Tab */) || (c === 0x20/* Space */);\r
8570 }\r
8571 \r
8572 function is_WS_OR_EOL(c) {\r
8573   return (c === 0x09/* Tab */) ||\r
8574          (c === 0x20/* Space */) ||\r
8575          (c === 0x0A/* LF */) ||\r
8576          (c === 0x0D/* CR */);\r
8577 }\r
8578 \r
8579 function is_FLOW_INDICATOR(c) {\r
8580   return c === 0x2C/* , */ ||\r
8581          c === 0x5B/* [ */ ||\r
8582          c === 0x5D/* ] */ ||\r
8583          c === 0x7B/* { */ ||\r
8584          c === 0x7D/* } */;\r
8585 }\r
8586 \r
8587 function fromHexCode(c) {\r
8588   var lc;\r
8589 \r
8590   if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {\r
8591     return c - 0x30;\r
8592   }\r
8593 \r
8594   /*eslint-disable no-bitwise*/\r
8595   lc = c | 0x20;\r
8596 \r
8597   if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) {\r
8598     return lc - 0x61 + 10;\r
8599   }\r
8600 \r
8601   return -1;\r
8602 }\r
8603 \r
8604 function escapedHexLen(c) {\r
8605   if (c === 0x78/* x */) { return 2; }\r
8606   if (c === 0x75/* u */) { return 4; }\r
8607   if (c === 0x55/* U */) { return 8; }\r
8608   return 0;\r
8609 }\r
8610 \r
8611 function fromDecimalCode(c) {\r
8612   if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {\r
8613     return c - 0x30;\r
8614   }\r
8615 \r
8616   return -1;\r
8617 }\r
8618 \r
8619 function simpleEscapeSequence(c) {\r
8620   return (c === 0x30/* 0 */) ? '\x00' :\r
8621         (c === 0x61/* a */) ? '\x07' :\r
8622         (c === 0x62/* b */) ? '\x08' :\r
8623         (c === 0x74/* t */) ? '\x09' :\r
8624         (c === 0x09/* Tab */) ? '\x09' :\r
8625         (c === 0x6E/* n */) ? '\x0A' :\r
8626         (c === 0x76/* v */) ? '\x0B' :\r
8627         (c === 0x66/* f */) ? '\x0C' :\r
8628         (c === 0x72/* r */) ? '\x0D' :\r
8629         (c === 0x65/* e */) ? '\x1B' :\r
8630         (c === 0x20/* Space */) ? ' ' :\r
8631         (c === 0x22/* " */) ? '\x22' :\r
8632         (c === 0x2F/* / */) ? '/' :\r
8633         (c === 0x5C/* \ */) ? '\x5C' :\r
8634         (c === 0x4E/* N */) ? '\x85' :\r
8635         (c === 0x5F/* _ */) ? '\xA0' :\r
8636         (c === 0x4C/* L */) ? '\u2028' :\r
8637         (c === 0x50/* P */) ? '\u2029' : '';\r
8638 }\r
8639 \r
8640 function charFromCodepoint(c) {\r
8641   if (c <= 0xFFFF) {\r
8642     return String.fromCharCode(c);\r
8643   }\r
8644   // Encode UTF-16 surrogate pair\r
8645   // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF\r
8646   return String.fromCharCode(((c - 0x010000) >> 10) + 0xD800,\r
8647                              ((c - 0x010000) & 0x03FF) + 0xDC00);\r
8648 }\r
8649 \r
8650 var simpleEscapeCheck = new Array(256); // integer, for fast access\r
8651 var simpleEscapeMap = new Array(256);\r
8652 for (var i = 0; i < 256; i++) {\r
8653   simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0;\r
8654   simpleEscapeMap[i] = simpleEscapeSequence(i);\r
8655 }\r
8656 \r
8657 \r
8658 function State(input, options) {\r
8659   this.input = input;\r
8660 \r
8661   this.filename  = options['filename']  || null;\r
8662   this.schema    = options['schema']    || DEFAULT_FULL_SCHEMA;\r
8663   this.onWarning = options['onWarning'] || null;\r
8664   this.legacy    = options['legacy']    || false;\r
8665   this.json      = options['json']      || false;\r
8666   this.listener  = options['listener']  || null;\r
8667 \r
8668   this.implicitTypes = this.schema.compiledImplicit;\r
8669   this.typeMap       = this.schema.compiledTypeMap;\r
8670 \r
8671   this.length     = input.length;\r
8672   this.position   = 0;\r
8673   this.line       = 0;\r
8674   this.lineStart  = 0;\r
8675   this.lineIndent = 0;\r
8676 \r
8677   this.documents = [];\r
8678 \r
8679   /*\r
8680   this.version;\r
8681   this.checkLineBreaks;\r
8682   this.tagMap;\r
8683   this.anchorMap;\r
8684   this.tag;\r
8685   this.anchor;\r
8686   this.kind;\r
8687   this.result;*/\r
8688 \r
8689 }\r
8690 \r
8691 \r
8692 function generateError(state, message) {\r
8693   return new YAMLException(\r
8694     message,\r
8695     new Mark(state.filename, state.input, state.position, state.line, (state.position - state.lineStart)));\r
8696 }\r
8697 \r
8698 function throwError(state, message) {\r
8699   throw generateError(state, message);\r
8700 }\r
8701 \r
8702 function throwWarning(state, message) {\r
8703   if (state.onWarning) {\r
8704     state.onWarning.call(null, generateError(state, message));\r
8705   }\r
8706 }\r
8707 \r
8708 \r
8709 var directiveHandlers = {\r
8710 \r
8711   YAML: function handleYamlDirective(state, name, args) {\r
8712 \r
8713     var match, major, minor;\r
8714 \r
8715     if (state.version !== null) {\r
8716       throwError(state, 'duplication of %YAML directive');\r
8717     }\r
8718 \r
8719     if (args.length !== 1) {\r
8720       throwError(state, 'YAML directive accepts exactly one argument');\r
8721     }\r
8722 \r
8723     match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]);\r
8724 \r
8725     if (match === null) {\r
8726       throwError(state, 'ill-formed argument of the YAML directive');\r
8727     }\r
8728 \r
8729     major = parseInt(match[1], 10);\r
8730     minor = parseInt(match[2], 10);\r
8731 \r
8732     if (major !== 1) {\r
8733       throwError(state, 'unacceptable YAML version of the document');\r
8734     }\r
8735 \r
8736     state.version = args[0];\r
8737     state.checkLineBreaks = (minor < 2);\r
8738 \r
8739     if (minor !== 1 && minor !== 2) {\r
8740       throwWarning(state, 'unsupported YAML version of the document');\r
8741     }\r
8742   },\r
8743 \r
8744   TAG: function handleTagDirective(state, name, args) {\r
8745 \r
8746     var handle, prefix;\r
8747 \r
8748     if (args.length !== 2) {\r
8749       throwError(state, 'TAG directive accepts exactly two arguments');\r
8750     }\r
8751 \r
8752     handle = args[0];\r
8753     prefix = args[1];\r
8754 \r
8755     if (!PATTERN_TAG_HANDLE.test(handle)) {\r
8756       throwError(state, 'ill-formed tag handle (first argument) of the TAG directive');\r
8757     }\r
8758 \r
8759     if (_hasOwnProperty.call(state.tagMap, handle)) {\r
8760       throwError(state, 'there is a previously declared suffix for "' + handle + '" tag handle');\r
8761     }\r
8762 \r
8763     if (!PATTERN_TAG_URI.test(prefix)) {\r
8764       throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive');\r
8765     }\r
8766 \r
8767     state.tagMap[handle] = prefix;\r
8768   }\r
8769 };\r
8770 \r
8771 \r
8772 function captureSegment(state, start, end, checkJson) {\r
8773   var _position, _length, _character, _result;\r
8774 \r
8775   if (start < end) {\r
8776     _result = state.input.slice(start, end);\r
8777 \r
8778     if (checkJson) {\r
8779       for (_position = 0, _length = _result.length;\r
8780            _position < _length;\r
8781            _position += 1) {\r
8782         _character = _result.charCodeAt(_position);\r
8783         if (!(_character === 0x09 ||\r
8784               (0x20 <= _character && _character <= 0x10FFFF))) {\r
8785           throwError(state, 'expected valid JSON character');\r
8786         }\r
8787       }\r
8788     } else if (PATTERN_NON_PRINTABLE.test(_result)) {\r
8789       throwError(state, 'the stream contains non-printable characters');\r
8790     }\r
8791 \r
8792     state.result += _result;\r
8793   }\r
8794 }\r
8795 \r
8796 function mergeMappings(state, destination, source, overridableKeys) {\r
8797   var sourceKeys, key, index, quantity;\r
8798 \r
8799   if (!common.isObject(source)) {\r
8800     throwError(state, 'cannot merge mappings; the provided source object is unacceptable');\r
8801   }\r
8802 \r
8803   sourceKeys = Object.keys(source);\r
8804 \r
8805   for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) {\r
8806     key = sourceKeys[index];\r
8807 \r
8808     if (!_hasOwnProperty.call(destination, key)) {\r
8809       destination[key] = source[key];\r
8810       overridableKeys[key] = true;\r
8811     }\r
8812   }\r
8813 }\r
8814 \r
8815 function storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode) {\r
8816   var index, quantity;\r
8817 \r
8818   keyNode = String(keyNode);\r
8819 \r
8820   if (_result === null) {\r
8821     _result = {};\r
8822   }\r
8823 \r
8824   if (keyTag === 'tag:yaml.org,2002:merge') {\r
8825     if (Array.isArray(valueNode)) {\r
8826       for (index = 0, quantity = valueNode.length; index < quantity; index += 1) {\r
8827         mergeMappings(state, _result, valueNode[index], overridableKeys);\r
8828       }\r
8829     } else {\r
8830       mergeMappings(state, _result, valueNode, overridableKeys);\r
8831     }\r
8832   } else {\r
8833     if (!state.json &&\r
8834         !_hasOwnProperty.call(overridableKeys, keyNode) &&\r
8835         _hasOwnProperty.call(_result, keyNode)) {\r
8836       throwError(state, 'duplicated mapping key');\r
8837     }\r
8838     _result[keyNode] = valueNode;\r
8839     delete overridableKeys[keyNode];\r
8840   }\r
8841 \r
8842   return _result;\r
8843 }\r
8844 \r
8845 function readLineBreak(state) {\r
8846   var ch;\r
8847 \r
8848   ch = state.input.charCodeAt(state.position);\r
8849 \r
8850   if (ch === 0x0A/* LF */) {\r
8851     state.position++;\r
8852   } else if (ch === 0x0D/* CR */) {\r
8853     state.position++;\r
8854     if (state.input.charCodeAt(state.position) === 0x0A/* LF */) {\r
8855       state.position++;\r
8856     }\r
8857   } else {\r
8858     throwError(state, 'a line break is expected');\r
8859   }\r
8860 \r
8861   state.line += 1;\r
8862   state.lineStart = state.position;\r
8863 }\r
8864 \r
8865 function skipSeparationSpace(state, allowComments, checkIndent) {\r
8866   var lineBreaks = 0,\r
8867       ch = state.input.charCodeAt(state.position);\r
8868 \r
8869   while (ch !== 0) {\r
8870     while (is_WHITE_SPACE(ch)) {\r
8871       ch = state.input.charCodeAt(++state.position);\r
8872     }\r
8873 \r
8874     if (allowComments && ch === 0x23/* # */) {\r
8875       do {\r
8876         ch = state.input.charCodeAt(++state.position);\r
8877       } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && ch !== 0);\r
8878     }\r
8879 \r
8880     if (is_EOL(ch)) {\r
8881       readLineBreak(state);\r
8882 \r
8883       ch = state.input.charCodeAt(state.position);\r
8884       lineBreaks++;\r
8885       state.lineIndent = 0;\r
8886 \r
8887       while (ch === 0x20/* Space */) {\r
8888         state.lineIndent++;\r
8889         ch = state.input.charCodeAt(++state.position);\r
8890       }\r
8891     } else {\r
8892       break;\r
8893     }\r
8894   }\r
8895 \r
8896   if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) {\r
8897     throwWarning(state, 'deficient indentation');\r
8898   }\r
8899 \r
8900   return lineBreaks;\r
8901 }\r
8902 \r
8903 function testDocumentSeparator(state) {\r
8904   var _position = state.position,\r
8905       ch;\r
8906 \r
8907   ch = state.input.charCodeAt(_position);\r
8908 \r
8909   // Condition state.position === state.lineStart is tested\r
8910   // in parent on each call, for efficiency. No needs to test here again.\r
8911   if ((ch === 0x2D/* - */ || ch === 0x2E/* . */) &&\r
8912       ch === state.input.charCodeAt(_position + 1) &&\r
8913       ch === state.input.charCodeAt(_position + 2)) {\r
8914 \r
8915     _position += 3;\r
8916 \r
8917     ch = state.input.charCodeAt(_position);\r
8918 \r
8919     if (ch === 0 || is_WS_OR_EOL(ch)) {\r
8920       return true;\r
8921     }\r
8922   }\r
8923 \r
8924   return false;\r
8925 }\r
8926 \r
8927 function writeFoldedLines(state, count) {\r
8928   if (count === 1) {\r
8929     state.result += ' ';\r
8930   } else if (count > 1) {\r
8931     state.result += common.repeat('\n', count - 1);\r
8932   }\r
8933 }\r
8934 \r
8935 \r
8936 function readPlainScalar(state, nodeIndent, withinFlowCollection) {\r
8937   var preceding,\r
8938       following,\r
8939       captureStart,\r
8940       captureEnd,\r
8941       hasPendingContent,\r
8942       _line,\r
8943       _lineStart,\r
8944       _lineIndent,\r
8945       _kind = state.kind,\r
8946       _result = state.result,\r
8947       ch;\r
8948 \r
8949   ch = state.input.charCodeAt(state.position);\r
8950 \r
8951   if (is_WS_OR_EOL(ch)      ||\r
8952       is_FLOW_INDICATOR(ch) ||\r
8953       ch === 0x23/* # */    ||\r
8954       ch === 0x26/* & */    ||\r
8955       ch === 0x2A/* * */    ||\r
8956       ch === 0x21/* ! */    ||\r
8957       ch === 0x7C/* | */    ||\r
8958       ch === 0x3E/* > */    ||\r
8959       ch === 0x27/* ' */    ||\r
8960       ch === 0x22/* " */    ||\r
8961       ch === 0x25/* % */    ||\r
8962       ch === 0x40/* @ */    ||\r
8963       ch === 0x60/* ` */) {\r
8964     return false;\r
8965   }\r
8966 \r
8967   if (ch === 0x3F/* ? */ || ch === 0x2D/* - */) {\r
8968     following = state.input.charCodeAt(state.position + 1);\r
8969 \r
8970     if (is_WS_OR_EOL(following) ||\r
8971         withinFlowCollection && is_FLOW_INDICATOR(following)) {\r
8972       return false;\r
8973     }\r
8974   }\r
8975 \r
8976   state.kind = 'scalar';\r
8977   state.result = '';\r
8978   captureStart = captureEnd = state.position;\r
8979   hasPendingContent = false;\r
8980 \r
8981   while (ch !== 0) {\r
8982     if (ch === 0x3A/* : */) {\r
8983       following = state.input.charCodeAt(state.position + 1);\r
8984 \r
8985       if (is_WS_OR_EOL(following) ||\r
8986           withinFlowCollection && is_FLOW_INDICATOR(following)) {\r
8987         break;\r
8988       }\r
8989 \r
8990     } else if (ch === 0x23/* # */) {\r
8991       preceding = state.input.charCodeAt(state.position - 1);\r
8992 \r
8993       if (is_WS_OR_EOL(preceding)) {\r
8994         break;\r
8995       }\r
8996 \r
8997     } else if ((state.position === state.lineStart && testDocumentSeparator(state)) ||\r
8998                withinFlowCollection && is_FLOW_INDICATOR(ch)) {\r
8999       break;\r
9000 \r
9001     } else if (is_EOL(ch)) {\r
9002       _line = state.line;\r
9003       _lineStart = state.lineStart;\r
9004       _lineIndent = state.lineIndent;\r
9005       skipSeparationSpace(state, false, -1);\r
9006 \r
9007       if (state.lineIndent >= nodeIndent) {\r
9008         hasPendingContent = true;\r
9009         ch = state.input.charCodeAt(state.position);\r
9010         continue;\r
9011       } else {\r
9012         state.position = captureEnd;\r
9013         state.line = _line;\r
9014         state.lineStart = _lineStart;\r
9015         state.lineIndent = _lineIndent;\r
9016         break;\r
9017       }\r
9018     }\r
9019 \r
9020     if (hasPendingContent) {\r
9021       captureSegment(state, captureStart, captureEnd, false);\r
9022       writeFoldedLines(state, state.line - _line);\r
9023       captureStart = captureEnd = state.position;\r
9024       hasPendingContent = false;\r
9025     }\r
9026 \r
9027     if (!is_WHITE_SPACE(ch)) {\r
9028       captureEnd = state.position + 1;\r
9029     }\r
9030 \r
9031     ch = state.input.charCodeAt(++state.position);\r
9032   }\r
9033 \r
9034   captureSegment(state, captureStart, captureEnd, false);\r
9035 \r
9036   if (state.result) {\r
9037     return true;\r
9038   }\r
9039 \r
9040   state.kind = _kind;\r
9041   state.result = _result;\r
9042   return false;\r
9043 }\r
9044 \r
9045 function readSingleQuotedScalar(state, nodeIndent) {\r
9046   var ch,\r
9047       captureStart, captureEnd;\r
9048 \r
9049   ch = state.input.charCodeAt(state.position);\r
9050 \r
9051   if (ch !== 0x27/* ' */) {\r
9052     return false;\r
9053   }\r
9054 \r
9055   state.kind = 'scalar';\r
9056   state.result = '';\r
9057   state.position++;\r
9058   captureStart = captureEnd = state.position;\r
9059 \r
9060   while ((ch = state.input.charCodeAt(state.position)) !== 0) {\r
9061     if (ch === 0x27/* ' */) {\r
9062       captureSegment(state, captureStart, state.position, true);\r
9063       ch = state.input.charCodeAt(++state.position);\r
9064 \r
9065       if (ch === 0x27/* ' */) {\r
9066         captureStart = captureEnd = state.position;\r
9067         state.position++;\r
9068       } else {\r
9069         return true;\r
9070       }\r
9071 \r
9072     } else if (is_EOL(ch)) {\r
9073       captureSegment(state, captureStart, captureEnd, true);\r
9074       writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));\r
9075       captureStart = captureEnd = state.position;\r
9076 \r
9077     } else if (state.position === state.lineStart && testDocumentSeparator(state)) {\r
9078       throwError(state, 'unexpected end of the document within a single quoted scalar');\r
9079 \r
9080     } else {\r
9081       state.position++;\r
9082       captureEnd = state.position;\r
9083     }\r
9084   }\r
9085 \r
9086   throwError(state, 'unexpected end of the stream within a single quoted scalar');\r
9087 }\r
9088 \r
9089 function readDoubleQuotedScalar(state, nodeIndent) {\r
9090   var captureStart,\r
9091       captureEnd,\r
9092       hexLength,\r
9093       hexResult,\r
9094       tmp,\r
9095       ch;\r
9096 \r
9097   ch = state.input.charCodeAt(state.position);\r
9098 \r
9099   if (ch !== 0x22/* " */) {\r
9100     return false;\r
9101   }\r
9102 \r
9103   state.kind = 'scalar';\r
9104   state.result = '';\r
9105   state.position++;\r
9106   captureStart = captureEnd = state.position;\r
9107 \r
9108   while ((ch = state.input.charCodeAt(state.position)) !== 0) {\r
9109     if (ch === 0x22/* " */) {\r
9110       captureSegment(state, captureStart, state.position, true);\r
9111       state.position++;\r
9112       return true;\r
9113 \r
9114     } else if (ch === 0x5C/* \ */) {\r
9115       captureSegment(state, captureStart, state.position, true);\r
9116       ch = state.input.charCodeAt(++state.position);\r
9117 \r
9118       if (is_EOL(ch)) {\r
9119         skipSeparationSpace(state, false, nodeIndent);\r
9120 \r
9121         // TODO: rework to inline fn with no type cast?\r
9122       } else if (ch < 256 && simpleEscapeCheck[ch]) {\r
9123         state.result += simpleEscapeMap[ch];\r
9124         state.position++;\r
9125 \r
9126       } else if ((tmp = escapedHexLen(ch)) > 0) {\r
9127         hexLength = tmp;\r
9128         hexResult = 0;\r
9129 \r
9130         for (; hexLength > 0; hexLength--) {\r
9131           ch = state.input.charCodeAt(++state.position);\r
9132 \r
9133           if ((tmp = fromHexCode(ch)) >= 0) {\r
9134             hexResult = (hexResult << 4) + tmp;\r
9135 \r
9136           } else {\r
9137             throwError(state, 'expected hexadecimal character');\r
9138           }\r
9139         }\r
9140 \r
9141         state.result += charFromCodepoint(hexResult);\r
9142 \r
9143         state.position++;\r
9144 \r
9145       } else {\r
9146         throwError(state, 'unknown escape sequence');\r
9147       }\r
9148 \r
9149       captureStart = captureEnd = state.position;\r
9150 \r
9151     } else if (is_EOL(ch)) {\r
9152       captureSegment(state, captureStart, captureEnd, true);\r
9153       writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));\r
9154       captureStart = captureEnd = state.position;\r
9155 \r
9156     } else if (state.position === state.lineStart && testDocumentSeparator(state)) {\r
9157       throwError(state, 'unexpected end of the document within a double quoted scalar');\r
9158 \r
9159     } else {\r
9160       state.position++;\r
9161       captureEnd = state.position;\r
9162     }\r
9163   }\r
9164 \r
9165   throwError(state, 'unexpected end of the stream within a double quoted scalar');\r
9166 }\r
9167 \r
9168 function readFlowCollection(state, nodeIndent) {\r
9169   var readNext = true,\r
9170       _line,\r
9171       _tag     = state.tag,\r
9172       _result,\r
9173       _anchor  = state.anchor,\r
9174       following,\r
9175       terminator,\r
9176       isPair,\r
9177       isExplicitPair,\r
9178       isMapping,\r
9179       overridableKeys = {},\r
9180       keyNode,\r
9181       keyTag,\r
9182       valueNode,\r
9183       ch;\r
9184 \r
9185   ch = state.input.charCodeAt(state.position);\r
9186 \r
9187   if (ch === 0x5B/* [ */) {\r
9188     terminator = 0x5D;/* ] */\r
9189     isMapping = false;\r
9190     _result = [];\r
9191   } else if (ch === 0x7B/* { */) {\r
9192     terminator = 0x7D;/* } */\r
9193     isMapping = true;\r
9194     _result = {};\r
9195   } else {\r
9196     return false;\r
9197   }\r
9198 \r
9199   if (state.anchor !== null) {\r
9200     state.anchorMap[state.anchor] = _result;\r
9201   }\r
9202 \r
9203   ch = state.input.charCodeAt(++state.position);\r
9204 \r
9205   while (ch !== 0) {\r
9206     skipSeparationSpace(state, true, nodeIndent);\r
9207 \r
9208     ch = state.input.charCodeAt(state.position);\r
9209 \r
9210     if (ch === terminator) {\r
9211       state.position++;\r
9212       state.tag = _tag;\r
9213       state.anchor = _anchor;\r
9214       state.kind = isMapping ? 'mapping' : 'sequence';\r
9215       state.result = _result;\r
9216       return true;\r
9217     } else if (!readNext) {\r
9218       throwError(state, 'missed comma between flow collection entries');\r
9219     }\r
9220 \r
9221     keyTag = keyNode = valueNode = null;\r
9222     isPair = isExplicitPair = false;\r
9223 \r
9224     if (ch === 0x3F/* ? */) {\r
9225       following = state.input.charCodeAt(state.position + 1);\r
9226 \r
9227       if (is_WS_OR_EOL(following)) {\r
9228         isPair = isExplicitPair = true;\r
9229         state.position++;\r
9230         skipSeparationSpace(state, true, nodeIndent);\r
9231       }\r
9232     }\r
9233 \r
9234     _line = state.line;\r
9235     composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);\r
9236     keyTag = state.tag;\r
9237     keyNode = state.result;\r
9238     skipSeparationSpace(state, true, nodeIndent);\r
9239 \r
9240     ch = state.input.charCodeAt(state.position);\r
9241 \r
9242     if ((isExplicitPair || state.line === _line) && ch === 0x3A/* : */) {\r
9243       isPair = true;\r
9244       ch = state.input.charCodeAt(++state.position);\r
9245       skipSeparationSpace(state, true, nodeIndent);\r
9246       composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);\r
9247       valueNode = state.result;\r
9248     }\r
9249 \r
9250     if (isMapping) {\r
9251       storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode);\r
9252     } else if (isPair) {\r
9253       _result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode));\r
9254     } else {\r
9255       _result.push(keyNode);\r
9256     }\r
9257 \r
9258     skipSeparationSpace(state, true, nodeIndent);\r
9259 \r
9260     ch = state.input.charCodeAt(state.position);\r
9261 \r
9262     if (ch === 0x2C/* , */) {\r
9263       readNext = true;\r
9264       ch = state.input.charCodeAt(++state.position);\r
9265     } else {\r
9266       readNext = false;\r
9267     }\r
9268   }\r
9269 \r
9270   throwError(state, 'unexpected end of the stream within a flow collection');\r
9271 }\r
9272 \r
9273 function readBlockScalar(state, nodeIndent) {\r
9274   var captureStart,\r
9275       folding,\r
9276       chomping       = CHOMPING_CLIP,\r
9277       detectedIndent = false,\r
9278       textIndent     = nodeIndent,\r
9279       emptyLines     = 0,\r
9280       atMoreIndented = false,\r
9281       tmp,\r
9282       ch;\r
9283 \r
9284   ch = state.input.charCodeAt(state.position);\r
9285 \r
9286   if (ch === 0x7C/* | */) {\r
9287     folding = false;\r
9288   } else if (ch === 0x3E/* > */) {\r
9289     folding = true;\r
9290   } else {\r
9291     return false;\r
9292   }\r
9293 \r
9294   state.kind = 'scalar';\r
9295   state.result = '';\r
9296 \r
9297   while (ch !== 0) {\r
9298     ch = state.input.charCodeAt(++state.position);\r
9299 \r
9300     if (ch === 0x2B/* + */ || ch === 0x2D/* - */) {\r
9301       if (CHOMPING_CLIP === chomping) {\r
9302         chomping = (ch === 0x2B/* + */) ? CHOMPING_KEEP : CHOMPING_STRIP;\r
9303       } else {\r
9304         throwError(state, 'repeat of a chomping mode identifier');\r
9305       }\r
9306 \r
9307     } else if ((tmp = fromDecimalCode(ch)) >= 0) {\r
9308       if (tmp === 0) {\r
9309         throwError(state, 'bad explicit indentation width of a block scalar; it cannot be less than one');\r
9310       } else if (!detectedIndent) {\r
9311         textIndent = nodeIndent + tmp - 1;\r
9312         detectedIndent = true;\r
9313       } else {\r
9314         throwError(state, 'repeat of an indentation width identifier');\r
9315       }\r
9316 \r
9317     } else {\r
9318       break;\r
9319     }\r
9320   }\r
9321 \r
9322   if (is_WHITE_SPACE(ch)) {\r
9323     do { ch = state.input.charCodeAt(++state.position); }\r
9324     while (is_WHITE_SPACE(ch));\r
9325 \r
9326     if (ch === 0x23/* # */) {\r
9327       do { ch = state.input.charCodeAt(++state.position); }\r
9328       while (!is_EOL(ch) && (ch !== 0));\r
9329     }\r
9330   }\r
9331 \r
9332   while (ch !== 0) {\r
9333     readLineBreak(state);\r
9334     state.lineIndent = 0;\r
9335 \r
9336     ch = state.input.charCodeAt(state.position);\r
9337 \r
9338     while ((!detectedIndent || state.lineIndent < textIndent) &&\r
9339            (ch === 0x20/* Space */)) {\r
9340       state.lineIndent++;\r
9341       ch = state.input.charCodeAt(++state.position);\r
9342     }\r
9343 \r
9344     if (!detectedIndent && state.lineIndent > textIndent) {\r
9345       textIndent = state.lineIndent;\r
9346     }\r
9347 \r
9348     if (is_EOL(ch)) {\r
9349       emptyLines++;\r
9350       continue;\r
9351     }\r
9352 \r
9353     // End of the scalar.\r
9354     if (state.lineIndent < textIndent) {\r
9355 \r
9356       // Perform the chomping.\r
9357       if (chomping === CHOMPING_KEEP) {\r
9358         state.result += common.repeat('\n', emptyLines);\r
9359       } else if (chomping === CHOMPING_CLIP) {\r
9360         if (detectedIndent) { // i.e. only if the scalar is not empty.\r
9361           state.result += '\n';\r
9362         }\r
9363       }\r
9364 \r
9365       // Break this `while` cycle and go to the funciton's epilogue.\r
9366       break;\r
9367     }\r
9368 \r
9369     // Folded style: use fancy rules to handle line breaks.\r
9370     if (folding) {\r
9371 \r
9372       // Lines starting with white space characters (more-indented lines) are not folded.\r
9373       if (is_WHITE_SPACE(ch)) {\r
9374         atMoreIndented = true;\r
9375         state.result += common.repeat('\n', emptyLines + 1);\r
9376 \r
9377       // End of more-indented block.\r
9378       } else if (atMoreIndented) {\r
9379         atMoreIndented = false;\r
9380         state.result += common.repeat('\n', emptyLines + 1);\r
9381 \r
9382       // Just one line break - perceive as the same line.\r
9383       } else if (emptyLines === 0) {\r
9384         if (detectedIndent) { // i.e. only if we have already read some scalar content.\r
9385           state.result += ' ';\r
9386         }\r
9387 \r
9388       // Several line breaks - perceive as different lines.\r
9389       } else {\r
9390         state.result += common.repeat('\n', emptyLines);\r
9391       }\r
9392 \r
9393     // Literal style: just add exact number of line breaks between content lines.\r
9394     } else if (detectedIndent) {\r
9395       // If current line isn't the first one - count line break from the last content line.\r
9396       state.result += common.repeat('\n', emptyLines + 1);\r
9397     } else {\r
9398       // In case of the first content line - count only empty lines.\r
9399       state.result += common.repeat('\n', emptyLines);\r
9400     }\r
9401 \r
9402     detectedIndent = true;\r
9403     emptyLines = 0;\r
9404     captureStart = state.position;\r
9405 \r
9406     while (!is_EOL(ch) && (ch !== 0)) {\r
9407       ch = state.input.charCodeAt(++state.position);\r
9408     }\r
9409 \r
9410     captureSegment(state, captureStart, state.position, false);\r
9411   }\r
9412 \r
9413   return true;\r
9414 }\r
9415 \r
9416 function readBlockSequence(state, nodeIndent) {\r
9417   var _line,\r
9418       _tag      = state.tag,\r
9419       _anchor   = state.anchor,\r
9420       _result   = [],\r
9421       following,\r
9422       detected  = false,\r
9423       ch;\r
9424 \r
9425   if (state.anchor !== null) {\r
9426     state.anchorMap[state.anchor] = _result;\r
9427   }\r
9428 \r
9429   ch = state.input.charCodeAt(state.position);\r
9430 \r
9431   while (ch !== 0) {\r
9432 \r
9433     if (ch !== 0x2D/* - */) {\r
9434       break;\r
9435     }\r
9436 \r
9437     following = state.input.charCodeAt(state.position + 1);\r
9438 \r
9439     if (!is_WS_OR_EOL(following)) {\r
9440       break;\r
9441     }\r
9442 \r
9443     detected = true;\r
9444     state.position++;\r
9445 \r
9446     if (skipSeparationSpace(state, true, -1)) {\r
9447       if (state.lineIndent <= nodeIndent) {\r
9448         _result.push(null);\r
9449         ch = state.input.charCodeAt(state.position);\r
9450         continue;\r
9451       }\r
9452     }\r
9453 \r
9454     _line = state.line;\r
9455     composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true);\r
9456     _result.push(state.result);\r
9457     skipSeparationSpace(state, true, -1);\r
9458 \r
9459     ch = state.input.charCodeAt(state.position);\r
9460 \r
9461     if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) {\r
9462       throwError(state, 'bad indentation of a sequence entry');\r
9463     } else if (state.lineIndent < nodeIndent) {\r
9464       break;\r
9465     }\r
9466   }\r
9467 \r
9468   if (detected) {\r
9469     state.tag = _tag;\r
9470     state.anchor = _anchor;\r
9471     state.kind = 'sequence';\r
9472     state.result = _result;\r
9473     return true;\r
9474   }\r
9475   return false;\r
9476 }\r
9477 \r
9478 function readBlockMapping(state, nodeIndent, flowIndent) {\r
9479   var following,\r
9480       allowCompact,\r
9481       _line,\r
9482       _tag          = state.tag,\r
9483       _anchor       = state.anchor,\r
9484       _result       = {},\r
9485       overridableKeys = {},\r
9486       keyTag        = null,\r
9487       keyNode       = null,\r
9488       valueNode     = null,\r
9489       atExplicitKey = false,\r
9490       detected      = false,\r
9491       ch;\r
9492 \r
9493   if (state.anchor !== null) {\r
9494     state.anchorMap[state.anchor] = _result;\r
9495   }\r
9496 \r
9497   ch = state.input.charCodeAt(state.position);\r
9498 \r
9499   while (ch !== 0) {\r
9500     following = state.input.charCodeAt(state.position + 1);\r
9501     _line = state.line; // Save the current line.\r
9502 \r
9503     //\r
9504     // Explicit notation case. There are two separate blocks:\r
9505     // first for the key (denoted by "?") and second for the value (denoted by ":")\r
9506     //\r
9507     if ((ch === 0x3F/* ? */ || ch === 0x3A/* : */) && is_WS_OR_EOL(following)) {\r
9508 \r
9509       if (ch === 0x3F/* ? */) {\r
9510         if (atExplicitKey) {\r
9511           storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null);\r
9512           keyTag = keyNode = valueNode = null;\r
9513         }\r
9514 \r
9515         detected = true;\r
9516         atExplicitKey = true;\r
9517         allowCompact = true;\r
9518 \r
9519       } else if (atExplicitKey) {\r
9520         // i.e. 0x3A/* : */ === character after the explicit key.\r
9521         atExplicitKey = false;\r
9522         allowCompact = true;\r
9523 \r
9524       } else {\r
9525         throwError(state, 'incomplete explicit mapping pair; a key node is missed');\r
9526       }\r
9527 \r
9528       state.position += 1;\r
9529       ch = following;\r
9530 \r
9531     //\r
9532     // Implicit notation case. Flow-style node as the key first, then ":", and the value.\r
9533     //\r
9534     } else if (composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) {\r
9535 \r
9536       if (state.line === _line) {\r
9537         ch = state.input.charCodeAt(state.position);\r
9538 \r
9539         while (is_WHITE_SPACE(ch)) {\r
9540           ch = state.input.charCodeAt(++state.position);\r
9541         }\r
9542 \r
9543         if (ch === 0x3A/* : */) {\r
9544           ch = state.input.charCodeAt(++state.position);\r
9545 \r
9546           if (!is_WS_OR_EOL(ch)) {\r
9547             throwError(state, 'a whitespace character is expected after the key-value separator within a block mapping');\r
9548           }\r
9549 \r
9550           if (atExplicitKey) {\r
9551             storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null);\r
9552             keyTag = keyNode = valueNode = null;\r
9553           }\r
9554 \r
9555           detected = true;\r
9556           atExplicitKey = false;\r
9557           allowCompact = false;\r
9558           keyTag = state.tag;\r
9559           keyNode = state.result;\r
9560 \r
9561         } else if (detected) {\r
9562           throwError(state, 'can not read an implicit mapping pair; a colon is missed');\r
9563 \r
9564         } else {\r
9565           state.tag = _tag;\r
9566           state.anchor = _anchor;\r
9567           return true; // Keep the result of `composeNode`.\r
9568         }\r
9569 \r
9570       } else if (detected) {\r
9571         throwError(state, 'can not read a block mapping entry; a multiline key may not be an implicit key');\r
9572 \r
9573       } else {\r
9574         state.tag = _tag;\r
9575         state.anchor = _anchor;\r
9576         return true; // Keep the result of `composeNode`.\r
9577       }\r
9578 \r
9579     } else {\r
9580       break; // Reading is done. Go to the epilogue.\r
9581     }\r
9582 \r
9583     //\r
9584     // Common reading code for both explicit and implicit notations.\r
9585     //\r
9586     if (state.line === _line || state.lineIndent > nodeIndent) {\r
9587       if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) {\r
9588         if (atExplicitKey) {\r
9589           keyNode = state.result;\r
9590         } else {\r
9591           valueNode = state.result;\r
9592         }\r
9593       }\r
9594 \r
9595       if (!atExplicitKey) {\r
9596         storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode);\r
9597         keyTag = keyNode = valueNode = null;\r
9598       }\r
9599 \r
9600       skipSeparationSpace(state, true, -1);\r
9601       ch = state.input.charCodeAt(state.position);\r
9602     }\r
9603 \r
9604     if (state.lineIndent > nodeIndent && (ch !== 0)) {\r
9605       throwError(state, 'bad indentation of a mapping entry');\r
9606     } else if (state.lineIndent < nodeIndent) {\r
9607       break;\r
9608     }\r
9609   }\r
9610 \r
9611   //\r
9612   // Epilogue.\r
9613   //\r
9614 \r
9615   // Special case: last mapping's node contains only the key in explicit notation.\r
9616   if (atExplicitKey) {\r
9617     storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null);\r
9618   }\r
9619 \r
9620   // Expose the resulting mapping.\r
9621   if (detected) {\r
9622     state.tag = _tag;\r
9623     state.anchor = _anchor;\r
9624     state.kind = 'mapping';\r
9625     state.result = _result;\r
9626   }\r
9627 \r
9628   return detected;\r
9629 }\r
9630 \r
9631 function readTagProperty(state) {\r
9632   var _position,\r
9633       isVerbatim = false,\r
9634       isNamed    = false,\r
9635       tagHandle,\r
9636       tagName,\r
9637       ch;\r
9638 \r
9639   ch = state.input.charCodeAt(state.position);\r
9640 \r
9641   if (ch !== 0x21/* ! */) return false;\r
9642 \r
9643   if (state.tag !== null) {\r
9644     throwError(state, 'duplication of a tag property');\r
9645   }\r
9646 \r
9647   ch = state.input.charCodeAt(++state.position);\r
9648 \r
9649   if (ch === 0x3C/* < */) {\r
9650     isVerbatim = true;\r
9651     ch = state.input.charCodeAt(++state.position);\r
9652 \r
9653   } else if (ch === 0x21/* ! */) {\r
9654     isNamed = true;\r
9655     tagHandle = '!!';\r
9656     ch = state.input.charCodeAt(++state.position);\r
9657 \r
9658   } else {\r
9659     tagHandle = '!';\r
9660   }\r
9661 \r
9662   _position = state.position;\r
9663 \r
9664   if (isVerbatim) {\r
9665     do { ch = state.input.charCodeAt(++state.position); }\r
9666     while (ch !== 0 && ch !== 0x3E/* > */);\r
9667 \r
9668     if (state.position < state.length) {\r
9669       tagName = state.input.slice(_position, state.position);\r
9670       ch = state.input.charCodeAt(++state.position);\r
9671     } else {\r
9672       throwError(state, 'unexpected end of the stream within a verbatim tag');\r
9673     }\r
9674   } else {\r
9675     while (ch !== 0 && !is_WS_OR_EOL(ch)) {\r
9676 \r
9677       if (ch === 0x21/* ! */) {\r
9678         if (!isNamed) {\r
9679           tagHandle = state.input.slice(_position - 1, state.position + 1);\r
9680 \r
9681           if (!PATTERN_TAG_HANDLE.test(tagHandle)) {\r
9682             throwError(state, 'named tag handle cannot contain such characters');\r
9683           }\r
9684 \r
9685           isNamed = true;\r
9686           _position = state.position + 1;\r
9687         } else {\r
9688           throwError(state, 'tag suffix cannot contain exclamation marks');\r
9689         }\r
9690       }\r
9691 \r
9692       ch = state.input.charCodeAt(++state.position);\r
9693     }\r
9694 \r
9695     tagName = state.input.slice(_position, state.position);\r
9696 \r
9697     if (PATTERN_FLOW_INDICATORS.test(tagName)) {\r
9698       throwError(state, 'tag suffix cannot contain flow indicator characters');\r
9699     }\r
9700   }\r
9701 \r
9702   if (tagName && !PATTERN_TAG_URI.test(tagName)) {\r
9703     throwError(state, 'tag name cannot contain such characters: ' + tagName);\r
9704   }\r
9705 \r
9706   if (isVerbatim) {\r
9707     state.tag = tagName;\r
9708 \r
9709   } else if (_hasOwnProperty.call(state.tagMap, tagHandle)) {\r
9710     state.tag = state.tagMap[tagHandle] + tagName;\r
9711 \r
9712   } else if (tagHandle === '!') {\r
9713     state.tag = '!' + tagName;\r
9714 \r
9715   } else if (tagHandle === '!!') {\r
9716     state.tag = 'tag:yaml.org,2002:' + tagName;\r
9717 \r
9718   } else {\r
9719     throwError(state, 'undeclared tag handle "' + tagHandle + '"');\r
9720   }\r
9721 \r
9722   return true;\r
9723 }\r
9724 \r
9725 function readAnchorProperty(state) {\r
9726   var _position,\r
9727       ch;\r
9728 \r
9729   ch = state.input.charCodeAt(state.position);\r
9730 \r
9731   if (ch !== 0x26/* & */) return false;\r
9732 \r
9733   if (state.anchor !== null) {\r
9734     throwError(state, 'duplication of an anchor property');\r
9735   }\r
9736 \r
9737   ch = state.input.charCodeAt(++state.position);\r
9738   _position = state.position;\r
9739 \r
9740   while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {\r
9741     ch = state.input.charCodeAt(++state.position);\r
9742   }\r
9743 \r
9744   if (state.position === _position) {\r
9745     throwError(state, 'name of an anchor node must contain at least one character');\r
9746   }\r
9747 \r
9748   state.anchor = state.input.slice(_position, state.position);\r
9749   return true;\r
9750 }\r
9751 \r
9752 function readAlias(state) {\r
9753   var _position, alias,\r
9754       ch;\r
9755 \r
9756   ch = state.input.charCodeAt(state.position);\r
9757 \r
9758   if (ch !== 0x2A/* * */) return false;\r
9759 \r
9760   ch = state.input.charCodeAt(++state.position);\r
9761   _position = state.position;\r
9762 \r
9763   while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {\r
9764     ch = state.input.charCodeAt(++state.position);\r
9765   }\r
9766 \r
9767   if (state.position === _position) {\r
9768     throwError(state, 'name of an alias node must contain at least one character');\r
9769   }\r
9770 \r
9771   alias = state.input.slice(_position, state.position);\r
9772 \r
9773   if (!state.anchorMap.hasOwnProperty(alias)) {\r
9774     throwError(state, 'unidentified alias "' + alias + '"');\r
9775   }\r
9776 \r
9777   state.result = state.anchorMap[alias];\r
9778   skipSeparationSpace(state, true, -1);\r
9779   return true;\r
9780 }\r
9781 \r
9782 function composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) {\r
9783   var allowBlockStyles,\r
9784       allowBlockScalars,\r
9785       allowBlockCollections,\r
9786       indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this<parent\r
9787       atNewLine  = false,\r
9788       hasContent = false,\r
9789       typeIndex,\r
9790       typeQuantity,\r
9791       type,\r
9792       flowIndent,\r
9793       blockIndent;\r
9794 \r
9795   if (state.listener !== null) {\r
9796     state.listener('open', state);\r
9797   }\r
9798 \r
9799   state.tag    = null;\r
9800   state.anchor = null;\r
9801   state.kind   = null;\r
9802   state.result = null;\r
9803 \r
9804   allowBlockStyles = allowBlockScalars = allowBlockCollections =\r
9805     CONTEXT_BLOCK_OUT === nodeContext ||\r
9806     CONTEXT_BLOCK_IN  === nodeContext;\r
9807 \r
9808   if (allowToSeek) {\r
9809     if (skipSeparationSpace(state, true, -1)) {\r
9810       atNewLine = true;\r
9811 \r
9812       if (state.lineIndent > parentIndent) {\r
9813         indentStatus = 1;\r
9814       } else if (state.lineIndent === parentIndent) {\r
9815         indentStatus = 0;\r
9816       } else if (state.lineIndent < parentIndent) {\r
9817         indentStatus = -1;\r
9818       }\r
9819     }\r
9820   }\r
9821 \r
9822   if (indentStatus === 1) {\r
9823     while (readTagProperty(state) || readAnchorProperty(state)) {\r
9824       if (skipSeparationSpace(state, true, -1)) {\r
9825         atNewLine = true;\r
9826         allowBlockCollections = allowBlockStyles;\r
9827 \r
9828         if (state.lineIndent > parentIndent) {\r
9829           indentStatus = 1;\r
9830         } else if (state.lineIndent === parentIndent) {\r
9831           indentStatus = 0;\r
9832         } else if (state.lineIndent < parentIndent) {\r
9833           indentStatus = -1;\r
9834         }\r
9835       } else {\r
9836         allowBlockCollections = false;\r
9837       }\r
9838     }\r
9839   }\r
9840 \r
9841   if (allowBlockCollections) {\r
9842     allowBlockCollections = atNewLine || allowCompact;\r
9843   }\r
9844 \r
9845   if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) {\r
9846     if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) {\r
9847       flowIndent = parentIndent;\r
9848     } else {\r
9849       flowIndent = parentIndent + 1;\r
9850     }\r
9851 \r
9852     blockIndent = state.position - state.lineStart;\r
9853 \r
9854     if (indentStatus === 1) {\r
9855       if (allowBlockCollections &&\r
9856           (readBlockSequence(state, blockIndent) ||\r
9857            readBlockMapping(state, blockIndent, flowIndent)) ||\r
9858           readFlowCollection(state, flowIndent)) {\r
9859         hasContent = true;\r
9860       } else {\r
9861         if ((allowBlockScalars && readBlockScalar(state, flowIndent)) ||\r
9862             readSingleQuotedScalar(state, flowIndent) ||\r
9863             readDoubleQuotedScalar(state, flowIndent)) {\r
9864           hasContent = true;\r
9865 \r
9866         } else if (readAlias(state)) {\r
9867           hasContent = true;\r
9868 \r
9869           if (state.tag !== null || state.anchor !== null) {\r
9870             throwError(state, 'alias node should not have any properties');\r
9871           }\r
9872 \r
9873         } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) {\r
9874           hasContent = true;\r
9875 \r
9876           if (state.tag === null) {\r
9877             state.tag = '?';\r
9878           }\r
9879         }\r
9880 \r
9881         if (state.anchor !== null) {\r
9882           state.anchorMap[state.anchor] = state.result;\r
9883         }\r
9884       }\r
9885     } else if (indentStatus === 0) {\r
9886       // Special case: block sequences are allowed to have same indentation level as the parent.\r
9887       // http://www.yaml.org/spec/1.2/spec.html#id2799784\r
9888       hasContent = allowBlockCollections && readBlockSequence(state, blockIndent);\r
9889     }\r
9890   }\r
9891 \r
9892   if (state.tag !== null && state.tag !== '!') {\r
9893     if (state.tag === '?') {\r
9894       for (typeIndex = 0, typeQuantity = state.implicitTypes.length;\r
9895            typeIndex < typeQuantity;\r
9896            typeIndex += 1) {\r
9897         type = state.implicitTypes[typeIndex];\r
9898 \r
9899         // Implicit resolving is not allowed for non-scalar types, and '?'\r
9900         // non-specific tag is only assigned to plain scalars. So, it isn't\r
9901         // needed to check for 'kind' conformity.\r
9902 \r
9903         if (type.resolve(state.result)) { // `state.result` updated in resolver if matched\r
9904           state.result = type.construct(state.result);\r
9905           state.tag = type.tag;\r
9906           if (state.anchor !== null) {\r
9907             state.anchorMap[state.anchor] = state.result;\r
9908           }\r
9909           break;\r
9910         }\r
9911       }\r
9912     } else if (_hasOwnProperty.call(state.typeMap, state.tag)) {\r
9913       type = state.typeMap[state.tag];\r
9914 \r
9915       if (state.result !== null && type.kind !== state.kind) {\r
9916         throwError(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be "' + type.kind + '", not "' + state.kind + '"');\r
9917       }\r
9918 \r
9919       if (!type.resolve(state.result)) { // `state.result` updated in resolver if matched\r
9920         throwError(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag');\r
9921       } else {\r
9922         state.result = type.construct(state.result);\r
9923         if (state.anchor !== null) {\r
9924           state.anchorMap[state.anchor] = state.result;\r
9925         }\r
9926       }\r
9927     } else {\r
9928       throwError(state, 'unknown tag !<' + state.tag + '>');\r
9929     }\r
9930   }\r
9931 \r
9932   if (state.listener !== null) {\r
9933     state.listener('close', state);\r
9934   }\r
9935   return state.tag !== null ||  state.anchor !== null || hasContent;\r
9936 }\r
9937 \r
9938 function readDocument(state) {\r
9939   var documentStart = state.position,\r
9940       _position,\r
9941       directiveName,\r
9942       directiveArgs,\r
9943       hasDirectives = false,\r
9944       ch;\r
9945 \r
9946   state.version = null;\r
9947   state.checkLineBreaks = state.legacy;\r
9948   state.tagMap = {};\r
9949   state.anchorMap = {};\r
9950 \r
9951   while ((ch = state.input.charCodeAt(state.position)) !== 0) {\r
9952     skipSeparationSpace(state, true, -1);\r
9953 \r
9954     ch = state.input.charCodeAt(state.position);\r
9955 \r
9956     if (state.lineIndent > 0 || ch !== 0x25/* % */) {\r
9957       break;\r
9958     }\r
9959 \r
9960     hasDirectives = true;\r
9961     ch = state.input.charCodeAt(++state.position);\r
9962     _position = state.position;\r
9963 \r
9964     while (ch !== 0 && !is_WS_OR_EOL(ch)) {\r
9965       ch = state.input.charCodeAt(++state.position);\r
9966     }\r
9967 \r
9968     directiveName = state.input.slice(_position, state.position);\r
9969     directiveArgs = [];\r
9970 \r
9971     if (directiveName.length < 1) {\r
9972       throwError(state, 'directive name must not be less than one character in length');\r
9973     }\r
9974 \r
9975     while (ch !== 0) {\r
9976       while (is_WHITE_SPACE(ch)) {\r
9977         ch = state.input.charCodeAt(++state.position);\r
9978       }\r
9979 \r
9980       if (ch === 0x23/* # */) {\r
9981         do { ch = state.input.charCodeAt(++state.position); }\r
9982         while (ch !== 0 && !is_EOL(ch));\r
9983         break;\r
9984       }\r
9985 \r
9986       if (is_EOL(ch)) break;\r
9987 \r
9988       _position = state.position;\r
9989 \r
9990       while (ch !== 0 && !is_WS_OR_EOL(ch)) {\r
9991         ch = state.input.charCodeAt(++state.position);\r
9992       }\r
9993 \r
9994       directiveArgs.push(state.input.slice(_position, state.position));\r
9995     }\r
9996 \r
9997     if (ch !== 0) readLineBreak(state);\r
9998 \r
9999     if (_hasOwnProperty.call(directiveHandlers, directiveName)) {\r
10000       directiveHandlers[directiveName](state, directiveName, directiveArgs);\r
10001     } else {\r
10002       throwWarning(state, 'unknown document directive "' + directiveName + '"');\r
10003     }\r
10004   }\r
10005 \r
10006   skipSeparationSpace(state, true, -1);\r
10007 \r
10008   if (state.lineIndent === 0 &&\r
10009       state.input.charCodeAt(state.position)     === 0x2D/* - */ &&\r
10010       state.input.charCodeAt(state.position + 1) === 0x2D/* - */ &&\r
10011       state.input.charCodeAt(state.position + 2) === 0x2D/* - */) {\r
10012     state.position += 3;\r
10013     skipSeparationSpace(state, true, -1);\r
10014 \r
10015   } else if (hasDirectives) {\r
10016     throwError(state, 'directives end mark is expected');\r
10017   }\r
10018 \r
10019   composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true);\r
10020   skipSeparationSpace(state, true, -1);\r
10021 \r
10022   if (state.checkLineBreaks &&\r
10023       PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) {\r
10024     throwWarning(state, 'non-ASCII line breaks are interpreted as content');\r
10025   }\r
10026 \r
10027   state.documents.push(state.result);\r
10028 \r
10029   if (state.position === state.lineStart && testDocumentSeparator(state)) {\r
10030 \r
10031     if (state.input.charCodeAt(state.position) === 0x2E/* . */) {\r
10032       state.position += 3;\r
10033       skipSeparationSpace(state, true, -1);\r
10034     }\r
10035     return;\r
10036   }\r
10037 \r
10038   if (state.position < (state.length - 1)) {\r
10039     throwError(state, 'end of the stream or a document separator is expected');\r
10040   } else {\r
10041     return;\r
10042   }\r
10043 }\r
10044 \r
10045 \r
10046 function loadDocuments(input, options) {\r
10047   input = String(input);\r
10048   options = options || {};\r
10049 \r
10050   if (input.length !== 0) {\r
10051 \r
10052     // Add tailing `\n` if not exists\r
10053     if (input.charCodeAt(input.length - 1) !== 0x0A/* LF */ &&\r
10054         input.charCodeAt(input.length - 1) !== 0x0D/* CR */) {\r
10055       input += '\n';\r
10056     }\r
10057 \r
10058     // Strip BOM\r
10059     if (input.charCodeAt(0) === 0xFEFF) {\r
10060       input = input.slice(1);\r
10061     }\r
10062   }\r
10063 \r
10064   var state = new State(input, options);\r
10065 \r
10066   // Use 0 as string terminator. That significantly simplifies bounds check.\r
10067   state.input += '\0';\r
10068 \r
10069   while (state.input.charCodeAt(state.position) === 0x20/* Space */) {\r
10070     state.lineIndent += 1;\r
10071     state.position += 1;\r
10072   }\r
10073 \r
10074   while (state.position < (state.length - 1)) {\r
10075     readDocument(state);\r
10076   }\r
10077 \r
10078   return state.documents;\r
10079 }\r
10080 \r
10081 \r
10082 function loadAll(input, iterator, options) {\r
10083   var documents = loadDocuments(input, options), index, length;\r
10084 \r
10085   for (index = 0, length = documents.length; index < length; index += 1) {\r
10086     iterator(documents[index]);\r
10087   }\r
10088 }\r
10089 \r
10090 \r
10091 function load(input, options) {\r
10092   var documents = loadDocuments(input, options);\r
10093 \r
10094   if (documents.length === 0) {\r
10095     /*eslint-disable no-undefined*/\r
10096     return undefined;\r
10097   } else if (documents.length === 1) {\r
10098     return documents[0];\r
10099   }\r
10100   throw new YAMLException('expected a single document in the stream, but found more');\r
10101 }\r
10102 \r
10103 \r
10104 function safeLoadAll(input, output, options) {\r
10105   loadAll(input, output, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options));\r
10106 }\r
10107 \r
10108 \r
10109 function safeLoad(input, options) {\r
10110   return load(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options));\r
10111 }\r
10112 \r
10113 \r
10114 module.exports.loadAll     = loadAll;\r
10115 module.exports.load        = load;\r
10116 module.exports.safeLoadAll = safeLoadAll;\r
10117 module.exports.safeLoad    = safeLoad;\r
10118 \r
10119 },{"./common":23,"./exception":25,"./mark":27,"./schema/default_full":30,"./schema/default_safe":31}],27:[function(require,module,exports){\r
10120 'use strict';\r
10121 \r
10122 \r
10123 var common = require('./common');\r
10124 \r
10125 \r
10126 function Mark(name, buffer, position, line, column) {\r
10127   this.name     = name;\r
10128   this.buffer   = buffer;\r
10129   this.position = position;\r
10130   this.line     = line;\r
10131   this.column   = column;\r
10132 }\r
10133 \r
10134 \r
10135 Mark.prototype.getSnippet = function getSnippet(indent, maxLength) {\r
10136   var head, start, tail, end, snippet;\r
10137 \r
10138   if (!this.buffer) return null;\r
10139 \r
10140   indent = indent || 4;\r
10141   maxLength = maxLength || 75;\r
10142 \r
10143   head = '';\r
10144   start = this.position;\r
10145 \r
10146   while (start > 0 && '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(start - 1)) === -1) {\r
10147     start -= 1;\r
10148     if (this.position - start > (maxLength / 2 - 1)) {\r
10149       head = ' ... ';\r
10150       start += 5;\r
10151       break;\r
10152     }\r
10153   }\r
10154 \r
10155   tail = '';\r
10156   end = this.position;\r
10157 \r
10158   while (end < this.buffer.length && '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(end)) === -1) {\r
10159     end += 1;\r
10160     if (end - this.position > (maxLength / 2 - 1)) {\r
10161       tail = ' ... ';\r
10162       end -= 5;\r
10163       break;\r
10164     }\r
10165   }\r
10166 \r
10167   snippet = this.buffer.slice(start, end);\r
10168 \r
10169   return common.repeat(' ', indent) + head + snippet + tail + '\n' +\r
10170          common.repeat(' ', indent + this.position - start + head.length) + '^';\r
10171 };\r
10172 \r
10173 \r
10174 Mark.prototype.toString = function toString(compact) {\r
10175   var snippet, where = '';\r
10176 \r
10177   if (this.name) {\r
10178     where += 'in "' + this.name + '" ';\r
10179   }\r
10180 \r
10181   where += 'at line ' + (this.line + 1) + ', column ' + (this.column + 1);\r
10182 \r
10183   if (!compact) {\r
10184     snippet = this.getSnippet();\r
10185 \r
10186     if (snippet) {\r
10187       where += ':\n' + snippet;\r
10188     }\r
10189   }\r
10190 \r
10191   return where;\r
10192 };\r
10193 \r
10194 \r
10195 module.exports = Mark;\r
10196 \r
10197 },{"./common":23}],28:[function(require,module,exports){\r
10198 'use strict';\r
10199 \r
10200 /*eslint-disable max-len*/\r
10201 \r
10202 var common        = require('./common');\r
10203 var YAMLException = require('./exception');\r
10204 var Type          = require('./type');\r
10205 \r
10206 \r
10207 function compileList(schema, name, result) {\r
10208   var exclude = [];\r
10209 \r
10210   schema.include.forEach(function (includedSchema) {\r
10211     result = compileList(includedSchema, name, result);\r
10212   });\r
10213 \r
10214   schema[name].forEach(function (currentType) {\r
10215     result.forEach(function (previousType, previousIndex) {\r
10216       if (previousType.tag === currentType.tag) {\r
10217         exclude.push(previousIndex);\r
10218       }\r
10219     });\r
10220 \r
10221     result.push(currentType);\r
10222   });\r
10223 \r
10224   return result.filter(function (type, index) {\r
10225     return exclude.indexOf(index) === -1;\r
10226   });\r
10227 }\r
10228 \r
10229 \r
10230 function compileMap(/* lists... */) {\r
10231   var result = {}, index, length;\r
10232 \r
10233   function collectType(type) {\r
10234     result[type.tag] = type;\r
10235   }\r
10236 \r
10237   for (index = 0, length = arguments.length; index < length; index += 1) {\r
10238     arguments[index].forEach(collectType);\r
10239   }\r
10240 \r
10241   return result;\r
10242 }\r
10243 \r
10244 \r
10245 function Schema(definition) {\r
10246   this.include  = definition.include  || [];\r
10247   this.implicit = definition.implicit || [];\r
10248   this.explicit = definition.explicit || [];\r
10249 \r
10250   this.implicit.forEach(function (type) {\r
10251     if (type.loadKind && type.loadKind !== 'scalar') {\r
10252       throw new YAMLException('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.');\r
10253     }\r
10254   });\r
10255 \r
10256   this.compiledImplicit = compileList(this, 'implicit', []);\r
10257   this.compiledExplicit = compileList(this, 'explicit', []);\r
10258   this.compiledTypeMap  = compileMap(this.compiledImplicit, this.compiledExplicit);\r
10259 }\r
10260 \r
10261 \r
10262 Schema.DEFAULT = null;\r
10263 \r
10264 \r
10265 Schema.create = function createSchema() {\r
10266   var schemas, types;\r
10267 \r
10268   switch (arguments.length) {\r
10269     case 1:\r
10270       schemas = Schema.DEFAULT;\r
10271       types = arguments[0];\r
10272       break;\r
10273 \r
10274     case 2:\r
10275       schemas = arguments[0];\r
10276       types = arguments[1];\r
10277       break;\r
10278 \r
10279     default:\r
10280       throw new YAMLException('Wrong number of arguments for Schema.create function');\r
10281   }\r
10282 \r
10283   schemas = common.toArray(schemas);\r
10284   types = common.toArray(types);\r
10285 \r
10286   if (!schemas.every(function (schema) { return schema instanceof Schema; })) {\r
10287     throw new YAMLException('Specified list of super schemas (or a single Schema object) contains a non-Schema object.');\r
10288   }\r
10289 \r
10290   if (!types.every(function (type) { return type instanceof Type; })) {\r
10291     throw new YAMLException('Specified list of YAML types (or a single Type object) contains a non-Type object.');\r
10292   }\r
10293 \r
10294   return new Schema({\r
10295     include: schemas,\r
10296     explicit: types\r
10297   });\r
10298 };\r
10299 \r
10300 \r
10301 module.exports = Schema;\r
10302 \r
10303 },{"./common":23,"./exception":25,"./type":34}],29:[function(require,module,exports){\r
10304 // Standard YAML's Core schema.\r
10305 // http://www.yaml.org/spec/1.2/spec.html#id2804923\r
10306 //\r
10307 // NOTE: JS-YAML does not support schema-specific tag resolution restrictions.\r
10308 // So, Core schema has no distinctions from JSON schema is JS-YAML.\r
10309 \r
10310 \r
10311 'use strict';\r
10312 \r
10313 \r
10314 var Schema = require('../schema');\r
10315 \r
10316 \r
10317 module.exports = new Schema({\r
10318   include: [\r
10319     require('./json')\r
10320   ]\r
10321 });\r
10322 \r
10323 },{"../schema":28,"./json":33}],30:[function(require,module,exports){\r
10324 // JS-YAML's default schema for `load` function.\r
10325 // It is not described in the YAML specification.\r
10326 //\r
10327 // This schema is based on JS-YAML's default safe schema and includes\r
10328 // JavaScript-specific types: !!js/undefined, !!js/regexp and !!js/function.\r
10329 //\r
10330 // Also this schema is used as default base schema at `Schema.create` function.\r
10331 \r
10332 \r
10333 'use strict';\r
10334 \r
10335 \r
10336 var Schema = require('../schema');\r
10337 \r
10338 \r
10339 module.exports = Schema.DEFAULT = new Schema({\r
10340   include: [\r
10341     require('./default_safe')\r
10342   ],\r
10343   explicit: [\r
10344     require('../type/js/undefined'),\r
10345     require('../type/js/regexp'),\r
10346     require('../type/js/function')\r
10347   ]\r
10348 });\r
10349 \r
10350 },{"../schema":28,"../type/js/function":39,"../type/js/regexp":40,"../type/js/undefined":41,"./default_safe":31}],31:[function(require,module,exports){\r
10351 // JS-YAML's default schema for `safeLoad` function.\r
10352 // It is not described in the YAML specification.\r
10353 //\r
10354 // This schema is based on standard YAML's Core schema and includes most of\r
10355 // extra types described at YAML tag repository. (http://yaml.org/type/)\r
10356 \r
10357 \r
10358 'use strict';\r
10359 \r
10360 \r
10361 var Schema = require('../schema');\r
10362 \r
10363 \r
10364 module.exports = new Schema({\r
10365   include: [\r
10366     require('./core')\r
10367   ],\r
10368   implicit: [\r
10369     require('../type/timestamp'),\r
10370     require('../type/merge')\r
10371   ],\r
10372   explicit: [\r
10373     require('../type/binary'),\r
10374     require('../type/omap'),\r
10375     require('../type/pairs'),\r
10376     require('../type/set')\r
10377   ]\r
10378 });\r
10379 \r
10380 },{"../schema":28,"../type/binary":35,"../type/merge":43,"../type/omap":45,"../type/pairs":46,"../type/set":48,"../type/timestamp":50,"./core":29}],32:[function(require,module,exports){\r
10381 // Standard YAML's Failsafe schema.\r
10382 // http://www.yaml.org/spec/1.2/spec.html#id2802346\r
10383 \r
10384 \r
10385 'use strict';\r
10386 \r
10387 \r
10388 var Schema = require('../schema');\r
10389 \r
10390 \r
10391 module.exports = new Schema({\r
10392   explicit: [\r
10393     require('../type/str'),\r
10394     require('../type/seq'),\r
10395     require('../type/map')\r
10396   ]\r
10397 });\r
10398 \r
10399 },{"../schema":28,"../type/map":42,"../type/seq":47,"../type/str":49}],33:[function(require,module,exports){\r
10400 // Standard YAML's JSON schema.\r
10401 // http://www.yaml.org/spec/1.2/spec.html#id2803231\r
10402 //\r
10403 // NOTE: JS-YAML does not support schema-specific tag resolution restrictions.\r
10404 // So, this schema is not such strict as defined in the YAML specification.\r
10405 // It allows numbers in binary notaion, use `Null` and `NULL` as `null`, etc.\r
10406 \r
10407 \r
10408 'use strict';\r
10409 \r
10410 \r
10411 var Schema = require('../schema');\r
10412 \r
10413 \r
10414 module.exports = new Schema({\r
10415   include: [\r
10416     require('./failsafe')\r
10417   ],\r
10418   implicit: [\r
10419     require('../type/null'),\r
10420     require('../type/bool'),\r
10421     require('../type/int'),\r
10422     require('../type/float')\r
10423   ]\r
10424 });\r
10425 \r
10426 },{"../schema":28,"../type/bool":36,"../type/float":37,"../type/int":38,"../type/null":44,"./failsafe":32}],34:[function(require,module,exports){\r
10427 'use strict';\r
10428 \r
10429 var YAMLException = require('./exception');\r
10430 \r
10431 var TYPE_CONSTRUCTOR_OPTIONS = [\r
10432   'kind',\r
10433   'resolve',\r
10434   'construct',\r
10435   'instanceOf',\r
10436   'predicate',\r
10437   'represent',\r
10438   'defaultStyle',\r
10439   'styleAliases'\r
10440 ];\r
10441 \r
10442 var YAML_NODE_KINDS = [\r
10443   'scalar',\r
10444   'sequence',\r
10445   'mapping'\r
10446 ];\r
10447 \r
10448 function compileStyleAliases(map) {\r
10449   var result = {};\r
10450 \r
10451   if (map !== null) {\r
10452     Object.keys(map).forEach(function (style) {\r
10453       map[style].forEach(function (alias) {\r
10454         result[String(alias)] = style;\r
10455       });\r
10456     });\r
10457   }\r
10458 \r
10459   return result;\r
10460 }\r
10461 \r
10462 function Type(tag, options) {\r
10463   options = options || {};\r
10464 \r
10465   Object.keys(options).forEach(function (name) {\r
10466     if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) {\r
10467       throw new YAMLException('Unknown option "' + name + '" is met in definition of "' + tag + '" YAML type.');\r
10468     }\r
10469   });\r
10470 \r
10471   // TODO: Add tag format check.\r
10472   this.tag          = tag;\r
10473   this.kind         = options['kind']         || null;\r
10474   this.resolve      = options['resolve']      || function () { return true; };\r
10475   this.construct    = options['construct']    || function (data) { return data; };\r
10476   this.instanceOf   = options['instanceOf']   || null;\r
10477   this.predicate    = options['predicate']    || null;\r
10478   this.represent    = options['represent']    || null;\r
10479   this.defaultStyle = options['defaultStyle'] || null;\r
10480   this.styleAliases = compileStyleAliases(options['styleAliases'] || null);\r
10481 \r
10482   if (YAML_NODE_KINDS.indexOf(this.kind) === -1) {\r
10483     throw new YAMLException('Unknown kind "' + this.kind + '" is specified for "' + tag + '" YAML type.');\r
10484   }\r
10485 }\r
10486 \r
10487 module.exports = Type;\r
10488 \r
10489 },{"./exception":25}],35:[function(require,module,exports){\r
10490 'use strict';\r
10491 \r
10492 /*eslint-disable no-bitwise*/\r
10493 \r
10494 // A trick for browserified version.\r
10495 // Since we make browserifier to ignore `buffer` module, NodeBuffer will be undefined\r
10496 var NodeBuffer = require('buffer').Buffer;\r
10497 var Type       = require('../type');\r
10498 \r
10499 \r
10500 // [ 64, 65, 66 ] -> [ padding, CR, LF ]\r
10501 var BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r';\r
10502 \r
10503 \r
10504 function resolveYamlBinary(data) {\r
10505   if (data === null) return false;\r
10506 \r
10507   var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP;\r
10508 \r
10509   // Convert one by one.\r
10510   for (idx = 0; idx < max; idx++) {\r
10511     code = map.indexOf(data.charAt(idx));\r
10512 \r
10513     // Skip CR/LF\r
10514     if (code > 64) continue;\r
10515 \r
10516     // Fail on illegal characters\r
10517     if (code < 0) return false;\r
10518 \r
10519     bitlen += 6;\r
10520   }\r
10521 \r
10522   // If there are any bits left, source was corrupted\r
10523   return (bitlen % 8) === 0;\r
10524 }\r
10525 \r
10526 function constructYamlBinary(data) {\r
10527   var idx, tailbits,\r
10528       input = data.replace(/[\r\n=]/g, ''), // remove CR/LF & padding to simplify scan\r
10529       max = input.length,\r
10530       map = BASE64_MAP,\r
10531       bits = 0,\r
10532       result = [];\r
10533 \r
10534   // Collect by 6*4 bits (3 bytes)\r
10535 \r
10536   for (idx = 0; idx < max; idx++) {\r
10537     if ((idx % 4 === 0) && idx) {\r
10538       result.push((bits >> 16) & 0xFF);\r
10539       result.push((bits >> 8) & 0xFF);\r
10540       result.push(bits & 0xFF);\r
10541     }\r
10542 \r
10543     bits = (bits << 6) | map.indexOf(input.charAt(idx));\r
10544   }\r
10545 \r
10546   // Dump tail\r
10547 \r
10548   tailbits = (max % 4) * 6;\r
10549 \r
10550   if (tailbits === 0) {\r
10551     result.push((bits >> 16) & 0xFF);\r
10552     result.push((bits >> 8) & 0xFF);\r
10553     result.push(bits & 0xFF);\r
10554   } else if (tailbits === 18) {\r
10555     result.push((bits >> 10) & 0xFF);\r
10556     result.push((bits >> 2) & 0xFF);\r
10557   } else if (tailbits === 12) {\r
10558     result.push((bits >> 4) & 0xFF);\r
10559   }\r
10560 \r
10561   // Wrap into Buffer for NodeJS and leave Array for browser\r
10562   if (NodeBuffer) return new NodeBuffer(result);\r
10563 \r
10564   return result;\r
10565 }\r
10566 \r
10567 function representYamlBinary(object /*, style*/) {\r
10568   var result = '', bits = 0, idx, tail,\r
10569       max = object.length,\r
10570       map = BASE64_MAP;\r
10571 \r
10572   // Convert every three bytes to 4 ASCII characters.\r
10573 \r
10574   for (idx = 0; idx < max; idx++) {\r
10575     if ((idx % 3 === 0) && idx) {\r
10576       result += map[(bits >> 18) & 0x3F];\r
10577       result += map[(bits >> 12) & 0x3F];\r
10578       result += map[(bits >> 6) & 0x3F];\r
10579       result += map[bits & 0x3F];\r
10580     }\r
10581 \r
10582     bits = (bits << 8) + object[idx];\r
10583   }\r
10584 \r
10585   // Dump tail\r
10586 \r
10587   tail = max % 3;\r
10588 \r
10589   if (tail === 0) {\r
10590     result += map[(bits >> 18) & 0x3F];\r
10591     result += map[(bits >> 12) & 0x3F];\r
10592     result += map[(bits >> 6) & 0x3F];\r
10593     result += map[bits & 0x3F];\r
10594   } else if (tail === 2) {\r
10595     result += map[(bits >> 10) & 0x3F];\r
10596     result += map[(bits >> 4) & 0x3F];\r
10597     result += map[(bits << 2) & 0x3F];\r
10598     result += map[64];\r
10599   } else if (tail === 1) {\r
10600     result += map[(bits >> 2) & 0x3F];\r
10601     result += map[(bits << 4) & 0x3F];\r
10602     result += map[64];\r
10603     result += map[64];\r
10604   }\r
10605 \r
10606   return result;\r
10607 }\r
10608 \r
10609 function isBinary(object) {\r
10610   return NodeBuffer && NodeBuffer.isBuffer(object);\r
10611 }\r
10612 \r
10613 module.exports = new Type('tag:yaml.org,2002:binary', {\r
10614   kind: 'scalar',\r
10615   resolve: resolveYamlBinary,\r
10616   construct: constructYamlBinary,\r
10617   predicate: isBinary,\r
10618   represent: representYamlBinary\r
10619 });\r
10620 \r
10621 },{"../type":34,"buffer":12}],36:[function(require,module,exports){\r
10622 'use strict';\r
10623 \r
10624 var Type = require('../type');\r
10625 \r
10626 function resolveYamlBoolean(data) {\r
10627   if (data === null) return false;\r
10628 \r
10629   var max = data.length;\r
10630 \r
10631   return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) ||\r
10632          (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE'));\r
10633 }\r
10634 \r
10635 function constructYamlBoolean(data) {\r
10636   return data === 'true' ||\r
10637          data === 'True' ||\r
10638          data === 'TRUE';\r
10639 }\r
10640 \r
10641 function isBoolean(object) {\r
10642   return Object.prototype.toString.call(object) === '[object Boolean]';\r
10643 }\r
10644 \r
10645 module.exports = new Type('tag:yaml.org,2002:bool', {\r
10646   kind: 'scalar',\r
10647   resolve: resolveYamlBoolean,\r
10648   construct: constructYamlBoolean,\r
10649   predicate: isBoolean,\r
10650   represent: {\r
10651     lowercase: function (object) { return object ? 'true' : 'false'; },\r
10652     uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; },\r
10653     camelcase: function (object) { return object ? 'True' : 'False'; }\r
10654   },\r
10655   defaultStyle: 'lowercase'\r
10656 });\r
10657 \r
10658 },{"../type":34}],37:[function(require,module,exports){\r
10659 'use strict';\r
10660 \r
10661 var common = require('../common');\r
10662 var Type   = require('../type');\r
10663 \r
10664 var YAML_FLOAT_PATTERN = new RegExp(\r
10665   '^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?' +\r
10666   '|\\.[0-9_]+(?:[eE][-+][0-9]+)?' +\r
10667   '|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*' +\r
10668   '|[-+]?\\.(?:inf|Inf|INF)' +\r
10669   '|\\.(?:nan|NaN|NAN))$');\r
10670 \r
10671 function resolveYamlFloat(data) {\r
10672   if (data === null) return false;\r
10673 \r
10674   if (!YAML_FLOAT_PATTERN.test(data)) return false;\r
10675 \r
10676   return true;\r
10677 }\r
10678 \r
10679 function constructYamlFloat(data) {\r
10680   var value, sign, base, digits;\r
10681 \r
10682   value  = data.replace(/_/g, '').toLowerCase();\r
10683   sign   = value[0] === '-' ? -1 : 1;\r
10684   digits = [];\r
10685 \r
10686   if ('+-'.indexOf(value[0]) >= 0) {\r
10687     value = value.slice(1);\r
10688   }\r
10689 \r
10690   if (value === '.inf') {\r
10691     return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;\r
10692 \r
10693   } else if (value === '.nan') {\r
10694     return NaN;\r
10695 \r
10696   } else if (value.indexOf(':') >= 0) {\r
10697     value.split(':').forEach(function (v) {\r
10698       digits.unshift(parseFloat(v, 10));\r
10699     });\r
10700 \r
10701     value = 0.0;\r
10702     base = 1;\r
10703 \r
10704     digits.forEach(function (d) {\r
10705       value += d * base;\r
10706       base *= 60;\r
10707     });\r
10708 \r
10709     return sign * value;\r
10710 \r
10711   }\r
10712   return sign * parseFloat(value, 10);\r
10713 }\r
10714 \r
10715 \r
10716 var SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/;\r
10717 \r
10718 function representYamlFloat(object, style) {\r
10719   var res;\r
10720 \r
10721   if (isNaN(object)) {\r
10722     switch (style) {\r
10723       case 'lowercase': return '.nan';\r
10724       case 'uppercase': return '.NAN';\r
10725       case 'camelcase': return '.NaN';\r
10726     }\r
10727   } else if (Number.POSITIVE_INFINITY === object) {\r
10728     switch (style) {\r
10729       case 'lowercase': return '.inf';\r
10730       case 'uppercase': return '.INF';\r
10731       case 'camelcase': return '.Inf';\r
10732     }\r
10733   } else if (Number.NEGATIVE_INFINITY === object) {\r
10734     switch (style) {\r
10735       case 'lowercase': return '-.inf';\r
10736       case 'uppercase': return '-.INF';\r
10737       case 'camelcase': return '-.Inf';\r
10738     }\r
10739   } else if (common.isNegativeZero(object)) {\r
10740     return '-0.0';\r
10741   }\r
10742 \r
10743   res = object.toString(10);\r
10744 \r
10745   // JS stringifier can build scientific format without dots: 5e-100,\r
10746   // while YAML requres dot: 5.e-100. Fix it with simple hack\r
10747 \r
10748   return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res;\r
10749 }\r
10750 \r
10751 function isFloat(object) {\r
10752   return (Object.prototype.toString.call(object) === '[object Number]') &&\r
10753          (object % 1 !== 0 || common.isNegativeZero(object));\r
10754 }\r
10755 \r
10756 module.exports = new Type('tag:yaml.org,2002:float', {\r
10757   kind: 'scalar',\r
10758   resolve: resolveYamlFloat,\r
10759   construct: constructYamlFloat,\r
10760   predicate: isFloat,\r
10761   represent: representYamlFloat,\r
10762   defaultStyle: 'lowercase'\r
10763 });\r
10764 \r
10765 },{"../common":23,"../type":34}],38:[function(require,module,exports){\r
10766 'use strict';\r
10767 \r
10768 var common = require('../common');\r
10769 var Type   = require('../type');\r
10770 \r
10771 function isHexCode(c) {\r
10772   return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) ||\r
10773          ((0x41/* A */ <= c) && (c <= 0x46/* F */)) ||\r
10774          ((0x61/* a */ <= c) && (c <= 0x66/* f */));\r
10775 }\r
10776 \r
10777 function isOctCode(c) {\r
10778   return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */));\r
10779 }\r
10780 \r
10781 function isDecCode(c) {\r
10782   return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */));\r
10783 }\r
10784 \r
10785 function resolveYamlInteger(data) {\r
10786   if (data === null) return false;\r
10787 \r
10788   var max = data.length,\r
10789       index = 0,\r
10790       hasDigits = false,\r
10791       ch;\r
10792 \r
10793   if (!max) return false;\r
10794 \r
10795   ch = data[index];\r
10796 \r
10797   // sign\r
10798   if (ch === '-' || ch === '+') {\r
10799     ch = data[++index];\r
10800   }\r
10801 \r
10802   if (ch === '0') {\r
10803     // 0\r
10804     if (index + 1 === max) return true;\r
10805     ch = data[++index];\r
10806 \r
10807     // base 2, base 8, base 16\r
10808 \r
10809     if (ch === 'b') {\r
10810       // base 2\r
10811       index++;\r
10812 \r
10813       for (; index < max; index++) {\r
10814         ch = data[index];\r
10815         if (ch === '_') continue;\r
10816         if (ch !== '0' && ch !== '1') return false;\r
10817         hasDigits = true;\r
10818       }\r
10819       return hasDigits;\r
10820     }\r
10821 \r
10822 \r
10823     if (ch === 'x') {\r
10824       // base 16\r
10825       index++;\r
10826 \r
10827       for (; index < max; index++) {\r
10828         ch = data[index];\r
10829         if (ch === '_') continue;\r
10830         if (!isHexCode(data.charCodeAt(index))) return false;\r
10831         hasDigits = true;\r
10832       }\r
10833       return hasDigits;\r
10834     }\r
10835 \r
10836     // base 8\r
10837     for (; index < max; index++) {\r
10838       ch = data[index];\r
10839       if (ch === '_') continue;\r
10840       if (!isOctCode(data.charCodeAt(index))) return false;\r
10841       hasDigits = true;\r
10842     }\r
10843     return hasDigits;\r
10844   }\r
10845 \r
10846   // base 10 (except 0) or base 60\r
10847 \r
10848   for (; index < max; index++) {\r
10849     ch = data[index];\r
10850     if (ch === '_') continue;\r
10851     if (ch === ':') break;\r
10852     if (!isDecCode(data.charCodeAt(index))) {\r
10853       return false;\r
10854     }\r
10855     hasDigits = true;\r
10856   }\r
10857 \r
10858   if (!hasDigits) return false;\r
10859 \r
10860   // if !base60 - done;\r
10861   if (ch !== ':') return true;\r
10862 \r
10863   // base60 almost not used, no needs to optimize\r
10864   return /^(:[0-5]?[0-9])+$/.test(data.slice(index));\r
10865 }\r
10866 \r
10867 function constructYamlInteger(data) {\r
10868   var value = data, sign = 1, ch, base, digits = [];\r
10869 \r
10870   if (value.indexOf('_') !== -1) {\r
10871     value = value.replace(/_/g, '');\r
10872   }\r
10873 \r
10874   ch = value[0];\r
10875 \r
10876   if (ch === '-' || ch === '+') {\r
10877     if (ch === '-') sign = -1;\r
10878     value = value.slice(1);\r
10879     ch = value[0];\r
10880   }\r
10881 \r
10882   if (value === '0') return 0;\r
10883 \r
10884   if (ch === '0') {\r
10885     if (value[1] === 'b') return sign * parseInt(value.slice(2), 2);\r
10886     if (value[1] === 'x') return sign * parseInt(value, 16);\r
10887     return sign * parseInt(value, 8);\r
10888   }\r
10889 \r
10890   if (value.indexOf(':') !== -1) {\r
10891     value.split(':').forEach(function (v) {\r
10892       digits.unshift(parseInt(v, 10));\r
10893     });\r
10894 \r
10895     value = 0;\r
10896     base = 1;\r
10897 \r
10898     digits.forEach(function (d) {\r
10899       value += (d * base);\r
10900       base *= 60;\r
10901     });\r
10902 \r
10903     return sign * value;\r
10904 \r
10905   }\r
10906 \r
10907   return sign * parseInt(value, 10);\r
10908 }\r
10909 \r
10910 function isInteger(object) {\r
10911   return (Object.prototype.toString.call(object)) === '[object Number]' &&\r
10912          (object % 1 === 0 && !common.isNegativeZero(object));\r
10913 }\r
10914 \r
10915 module.exports = new Type('tag:yaml.org,2002:int', {\r
10916   kind: 'scalar',\r
10917   resolve: resolveYamlInteger,\r
10918   construct: constructYamlInteger,\r
10919   predicate: isInteger,\r
10920   represent: {\r
10921     binary:      function (object) { return '0b' + object.toString(2); },\r
10922     octal:       function (object) { return '0'  + object.toString(8); },\r
10923     decimal:     function (object) { return        object.toString(10); },\r
10924     hexadecimal: function (object) { return '0x' + object.toString(16).toUpperCase(); }\r
10925   },\r
10926   defaultStyle: 'decimal',\r
10927   styleAliases: {\r
10928     binary:      [ 2,  'bin' ],\r
10929     octal:       [ 8,  'oct' ],\r
10930     decimal:     [ 10, 'dec' ],\r
10931     hexadecimal: [ 16, 'hex' ]\r
10932   }\r
10933 });\r
10934 \r
10935 },{"../common":23,"../type":34}],39:[function(require,module,exports){\r
10936 'use strict';\r
10937 \r
10938 var esprima;\r
10939 \r
10940 // Browserified version does not have esprima\r
10941 //\r
10942 // 1. For node.js just require module as deps\r
10943 // 2. For browser try to require mudule via external AMD system.\r
10944 //    If not found - try to fallback to window.esprima. If not\r
10945 //    found too - then fail to parse.\r
10946 //\r
10947 try {\r
10948   // workaround to exclude package from browserify list.\r
10949   var _require = require;\r
10950   esprima = _require('esprima');\r
10951 } catch (_) {\r
10952   /*global window */\r
10953   if (typeof window !== 'undefined') esprima = window.esprima;\r
10954 }\r
10955 \r
10956 var Type = require('../../type');\r
10957 \r
10958 function resolveJavascriptFunction(data) {\r
10959   if (data === null) return false;\r
10960 \r
10961   try {\r
10962     var source = '(' + data + ')',\r
10963         ast    = esprima.parse(source, { range: true });\r
10964 \r
10965     if (ast.type                    !== 'Program'             ||\r
10966         ast.body.length             !== 1                     ||\r
10967         ast.body[0].type            !== 'ExpressionStatement' ||\r
10968         ast.body[0].expression.type !== 'FunctionExpression') {\r
10969       return false;\r
10970     }\r
10971 \r
10972     return true;\r
10973   } catch (err) {\r
10974     return false;\r
10975   }\r
10976 }\r
10977 \r
10978 function constructJavascriptFunction(data) {\r
10979   /*jslint evil:true*/\r
10980 \r
10981   var source = '(' + data + ')',\r
10982       ast    = esprima.parse(source, { range: true }),\r
10983       params = [],\r
10984       body;\r
10985 \r
10986   if (ast.type                    !== 'Program'             ||\r
10987       ast.body.length             !== 1                     ||\r
10988       ast.body[0].type            !== 'ExpressionStatement' ||\r
10989       ast.body[0].expression.type !== 'FunctionExpression') {\r
10990     throw new Error('Failed to resolve function');\r
10991   }\r
10992 \r
10993   ast.body[0].expression.params.forEach(function (param) {\r
10994     params.push(param.name);\r
10995   });\r
10996 \r
10997   body = ast.body[0].expression.body.range;\r
10998 \r
10999   // Esprima's ranges include the first '{' and the last '}' characters on\r
11000   // function expressions. So cut them out.\r
11001   /*eslint-disable no-new-func*/\r
11002   return new Function(params, source.slice(body[0] + 1, body[1] - 1));\r
11003 }\r
11004 \r
11005 function representJavascriptFunction(object /*, style*/) {\r
11006   return object.toString();\r
11007 }\r
11008 \r
11009 function isFunction(object) {\r
11010   return Object.prototype.toString.call(object) === '[object Function]';\r
11011 }\r
11012 \r
11013 module.exports = new Type('tag:yaml.org,2002:js/function', {\r
11014   kind: 'scalar',\r
11015   resolve: resolveJavascriptFunction,\r
11016   construct: constructJavascriptFunction,\r
11017   predicate: isFunction,\r
11018   represent: representJavascriptFunction\r
11019 });\r
11020 \r
11021 },{"../../type":34}],40:[function(require,module,exports){\r
11022 'use strict';\r
11023 \r
11024 var Type = require('../../type');\r
11025 \r
11026 function resolveJavascriptRegExp(data) {\r
11027   if (data === null) return false;\r
11028   if (data.length === 0) return false;\r
11029 \r
11030   var regexp = data,\r
11031       tail   = /\/([gim]*)$/.exec(data),\r
11032       modifiers = '';\r
11033 \r
11034   // if regexp starts with '/' it can have modifiers and must be properly closed\r
11035   // `/foo/gim` - modifiers tail can be maximum 3 chars\r
11036   if (regexp[0] === '/') {\r
11037     if (tail) modifiers = tail[1];\r
11038 \r
11039     if (modifiers.length > 3) return false;\r
11040     // if expression starts with /, is should be properly terminated\r
11041     if (regexp[regexp.length - modifiers.length - 1] !== '/') return false;\r
11042   }\r
11043 \r
11044   return true;\r
11045 }\r
11046 \r
11047 function constructJavascriptRegExp(data) {\r
11048   var regexp = data,\r
11049       tail   = /\/([gim]*)$/.exec(data),\r
11050       modifiers = '';\r
11051 \r
11052   // `/foo/gim` - tail can be maximum 4 chars\r
11053   if (regexp[0] === '/') {\r
11054     if (tail) modifiers = tail[1];\r
11055     regexp = regexp.slice(1, regexp.length - modifiers.length - 1);\r
11056   }\r
11057 \r
11058   return new RegExp(regexp, modifiers);\r
11059 }\r
11060 \r
11061 function representJavascriptRegExp(object /*, style*/) {\r
11062   var result = '/' + object.source + '/';\r
11063 \r
11064   if (object.global) result += 'g';\r
11065   if (object.multiline) result += 'm';\r
11066   if (object.ignoreCase) result += 'i';\r
11067 \r
11068   return result;\r
11069 }\r
11070 \r
11071 function isRegExp(object) {\r
11072   return Object.prototype.toString.call(object) === '[object RegExp]';\r
11073 }\r
11074 \r
11075 module.exports = new Type('tag:yaml.org,2002:js/regexp', {\r
11076   kind: 'scalar',\r
11077   resolve: resolveJavascriptRegExp,\r
11078   construct: constructJavascriptRegExp,\r
11079   predicate: isRegExp,\r
11080   represent: representJavascriptRegExp\r
11081 });\r
11082 \r
11083 },{"../../type":34}],41:[function(require,module,exports){\r
11084 'use strict';\r
11085 \r
11086 var Type = require('../../type');\r
11087 \r
11088 function resolveJavascriptUndefined() {\r
11089   return true;\r
11090 }\r
11091 \r
11092 function constructJavascriptUndefined() {\r
11093   /*eslint-disable no-undefined*/\r
11094   return undefined;\r
11095 }\r
11096 \r
11097 function representJavascriptUndefined() {\r
11098   return '';\r
11099 }\r
11100 \r
11101 function isUndefined(object) {\r
11102   return typeof object === 'undefined';\r
11103 }\r
11104 \r
11105 module.exports = new Type('tag:yaml.org,2002:js/undefined', {\r
11106   kind: 'scalar',\r
11107   resolve: resolveJavascriptUndefined,\r
11108   construct: constructJavascriptUndefined,\r
11109   predicate: isUndefined,\r
11110   represent: representJavascriptUndefined\r
11111 });\r
11112 \r
11113 },{"../../type":34}],42:[function(require,module,exports){\r
11114 'use strict';\r
11115 \r
11116 var Type = require('../type');\r
11117 \r
11118 module.exports = new Type('tag:yaml.org,2002:map', {\r
11119   kind: 'mapping',\r
11120   construct: function (data) { return data !== null ? data : {}; }\r
11121 });\r
11122 \r
11123 },{"../type":34}],43:[function(require,module,exports){\r
11124 'use strict';\r
11125 \r
11126 var Type = require('../type');\r
11127 \r
11128 function resolveYamlMerge(data) {\r
11129   return data === '<<' || data === null;\r
11130 }\r
11131 \r
11132 module.exports = new Type('tag:yaml.org,2002:merge', {\r
11133   kind: 'scalar',\r
11134   resolve: resolveYamlMerge\r
11135 });\r
11136 \r
11137 },{"../type":34}],44:[function(require,module,exports){\r
11138 'use strict';\r
11139 \r
11140 var Type = require('../type');\r
11141 \r
11142 function resolveYamlNull(data) {\r
11143   if (data === null) return true;\r
11144 \r
11145   var max = data.length;\r
11146 \r
11147   return (max === 1 && data === '~') ||\r
11148          (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL'));\r
11149 }\r
11150 \r
11151 function constructYamlNull() {\r
11152   return null;\r
11153 }\r
11154 \r
11155 function isNull(object) {\r
11156   return object === null;\r
11157 }\r
11158 \r
11159 module.exports = new Type('tag:yaml.org,2002:null', {\r
11160   kind: 'scalar',\r
11161   resolve: resolveYamlNull,\r
11162   construct: constructYamlNull,\r
11163   predicate: isNull,\r
11164   represent: {\r
11165     canonical: function () { return '~';    },\r
11166     lowercase: function () { return 'null'; },\r
11167     uppercase: function () { return 'NULL'; },\r
11168     camelcase: function () { return 'Null'; }\r
11169   },\r
11170   defaultStyle: 'lowercase'\r
11171 });\r
11172 \r
11173 },{"../type":34}],45:[function(require,module,exports){\r
11174 'use strict';\r
11175 \r
11176 var Type = require('../type');\r
11177 \r
11178 var _hasOwnProperty = Object.prototype.hasOwnProperty;\r
11179 var _toString       = Object.prototype.toString;\r
11180 \r
11181 function resolveYamlOmap(data) {\r
11182   if (data === null) return true;\r
11183 \r
11184   var objectKeys = [], index, length, pair, pairKey, pairHasKey,\r
11185       object = data;\r
11186 \r
11187   for (index = 0, length = object.length; index < length; index += 1) {\r
11188     pair = object[index];\r
11189     pairHasKey = false;\r
11190 \r
11191     if (_toString.call(pair) !== '[object Object]') return false;\r
11192 \r
11193     for (pairKey in pair) {\r
11194       if (_hasOwnProperty.call(pair, pairKey)) {\r
11195         if (!pairHasKey) pairHasKey = true;\r
11196         else return false;\r
11197       }\r
11198     }\r
11199 \r
11200     if (!pairHasKey) return false;\r
11201 \r
11202     if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey);\r
11203     else return false;\r
11204   }\r
11205 \r
11206   return true;\r
11207 }\r
11208 \r
11209 function constructYamlOmap(data) {\r
11210   return data !== null ? data : [];\r
11211 }\r
11212 \r
11213 module.exports = new Type('tag:yaml.org,2002:omap', {\r
11214   kind: 'sequence',\r
11215   resolve: resolveYamlOmap,\r
11216   construct: constructYamlOmap\r
11217 });\r
11218 \r
11219 },{"../type":34}],46:[function(require,module,exports){\r
11220 'use strict';\r
11221 \r
11222 var Type = require('../type');\r
11223 \r
11224 var _toString = Object.prototype.toString;\r
11225 \r
11226 function resolveYamlPairs(data) {\r
11227   if (data === null) return true;\r
11228 \r
11229   var index, length, pair, keys, result,\r
11230       object = data;\r
11231 \r
11232   result = new Array(object.length);\r
11233 \r
11234   for (index = 0, length = object.length; index < length; index += 1) {\r
11235     pair = object[index];\r
11236 \r
11237     if (_toString.call(pair) !== '[object Object]') return false;\r
11238 \r
11239     keys = Object.keys(pair);\r
11240 \r
11241     if (keys.length !== 1) return false;\r
11242 \r
11243     result[index] = [ keys[0], pair[keys[0]] ];\r
11244   }\r
11245 \r
11246   return true;\r
11247 }\r
11248 \r
11249 function constructYamlPairs(data) {\r
11250   if (data === null) return [];\r
11251 \r
11252   var index, length, pair, keys, result,\r
11253       object = data;\r
11254 \r
11255   result = new Array(object.length);\r
11256 \r
11257   for (index = 0, length = object.length; index < length; index += 1) {\r
11258     pair = object[index];\r
11259 \r
11260     keys = Object.keys(pair);\r
11261 \r
11262     result[index] = [ keys[0], pair[keys[0]] ];\r
11263   }\r
11264 \r
11265   return result;\r
11266 }\r
11267 \r
11268 module.exports = new Type('tag:yaml.org,2002:pairs', {\r
11269   kind: 'sequence',\r
11270   resolve: resolveYamlPairs,\r
11271   construct: constructYamlPairs\r
11272 });\r
11273 \r
11274 },{"../type":34}],47:[function(require,module,exports){\r
11275 'use strict';\r
11276 \r
11277 var Type = require('../type');\r
11278 \r
11279 module.exports = new Type('tag:yaml.org,2002:seq', {\r
11280   kind: 'sequence',\r
11281   construct: function (data) { return data !== null ? data : []; }\r
11282 });\r
11283 \r
11284 },{"../type":34}],48:[function(require,module,exports){\r
11285 'use strict';\r
11286 \r
11287 var Type = require('../type');\r
11288 \r
11289 var _hasOwnProperty = Object.prototype.hasOwnProperty;\r
11290 \r
11291 function resolveYamlSet(data) {\r
11292   if (data === null) return true;\r
11293 \r
11294   var key, object = data;\r
11295 \r
11296   for (key in object) {\r
11297     if (_hasOwnProperty.call(object, key)) {\r
11298       if (object[key] !== null) return false;\r
11299     }\r
11300   }\r
11301 \r
11302   return true;\r
11303 }\r
11304 \r
11305 function constructYamlSet(data) {\r
11306   return data !== null ? data : {};\r
11307 }\r
11308 \r
11309 module.exports = new Type('tag:yaml.org,2002:set', {\r
11310   kind: 'mapping',\r
11311   resolve: resolveYamlSet,\r
11312   construct: constructYamlSet\r
11313 });\r
11314 \r
11315 },{"../type":34}],49:[function(require,module,exports){\r
11316 'use strict';\r
11317 \r
11318 var Type = require('../type');\r
11319 \r
11320 module.exports = new Type('tag:yaml.org,2002:str', {\r
11321   kind: 'scalar',\r
11322   construct: function (data) { return data !== null ? data : ''; }\r
11323 });\r
11324 \r
11325 },{"../type":34}],50:[function(require,module,exports){\r
11326 'use strict';\r
11327 \r
11328 var Type = require('../type');\r
11329 \r
11330 var YAML_TIMESTAMP_REGEXP = new RegExp(\r
11331   '^([0-9][0-9][0-9][0-9])'          + // [1] year\r
11332   '-([0-9][0-9]?)'                   + // [2] month\r
11333   '-([0-9][0-9]?)'                   + // [3] day\r
11334   '(?:(?:[Tt]|[ \\t]+)'              + // ...\r
11335   '([0-9][0-9]?)'                    + // [4] hour\r
11336   ':([0-9][0-9])'                    + // [5] minute\r
11337   ':([0-9][0-9])'                    + // [6] second\r
11338   '(?:\\.([0-9]*))?'                 + // [7] fraction\r
11339   '(?:[ \\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour\r
11340   '(?::([0-9][0-9]))?))?)?$');         // [11] tz_minute\r
11341 \r
11342 function resolveYamlTimestamp(data) {\r
11343   if (data === null) return false;\r
11344   if (YAML_TIMESTAMP_REGEXP.exec(data) === null) return false;\r
11345   return true;\r
11346 }\r
11347 \r
11348 function constructYamlTimestamp(data) {\r
11349   var match, year, month, day, hour, minute, second, fraction = 0,\r
11350       delta = null, tz_hour, tz_minute, date;\r
11351 \r
11352   match = YAML_TIMESTAMP_REGEXP.exec(data);\r
11353 \r
11354   if (match === null) throw new Error('Date resolve error');\r
11355 \r
11356   // match: [1] year [2] month [3] day\r
11357 \r
11358   year = +(match[1]);\r
11359   month = +(match[2]) - 1; // JS month starts with 0\r
11360   day = +(match[3]);\r
11361 \r
11362   if (!match[4]) { // no hour\r
11363     return new Date(Date.UTC(year, month, day));\r
11364   }\r
11365 \r
11366   // match: [4] hour [5] minute [6] second [7] fraction\r
11367 \r
11368   hour = +(match[4]);\r
11369   minute = +(match[5]);\r
11370   second = +(match[6]);\r
11371 \r
11372   if (match[7]) {\r
11373     fraction = match[7].slice(0, 3);\r
11374     while (fraction.length < 3) { // milli-seconds\r
11375       fraction += '0';\r
11376     }\r
11377     fraction = +fraction;\r
11378   }\r
11379 \r
11380   // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute\r
11381 \r
11382   if (match[9]) {\r
11383     tz_hour = +(match[10]);\r
11384     tz_minute = +(match[11] || 0);\r
11385     delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds\r
11386     if (match[9] === '-') delta = -delta;\r
11387   }\r
11388 \r
11389   date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction));\r
11390 \r
11391   if (delta) date.setTime(date.getTime() - delta);\r
11392 \r
11393   return date;\r
11394 }\r
11395 \r
11396 function representYamlTimestamp(object /*, style*/) {\r
11397   return object.toISOString();\r
11398 }\r
11399 \r
11400 module.exports = new Type('tag:yaml.org,2002:timestamp', {\r
11401   kind: 'scalar',\r
11402   resolve: resolveYamlTimestamp,\r
11403   construct: constructYamlTimestamp,\r
11404   instanceOf: Date,\r
11405   represent: representYamlTimestamp\r
11406 });\r
11407 \r
11408 },{"../type":34}],51:[function(require,module,exports){\r
11409 var baseIndexOf = require('../internal/baseIndexOf'),\r
11410     binaryIndex = require('../internal/binaryIndex');\r
11411 \r
11412 /* Native method references for those with the same name as other `lodash` methods. */\r
11413 var nativeMax = Math.max;\r
11414 \r
11415 /**\r
11416  * Gets the index at which the first occurrence of `value` is found in `array`\r
11417  * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\r
11418  * for equality comparisons. If `fromIndex` is negative, it's used as the offset\r
11419  * from the end of `array`. If `array` is sorted providing `true` for `fromIndex`\r
11420  * performs a faster binary search.\r
11421  *\r
11422  * @static\r
11423  * @memberOf _\r
11424  * @category Array\r
11425  * @param {Array} array The array to search.\r
11426  * @param {*} value The value to search for.\r
11427  * @param {boolean|number} [fromIndex=0] The index to search from or `true`\r
11428  *  to perform a binary search on a sorted array.\r
11429  * @returns {number} Returns the index of the matched value, else `-1`.\r
11430  * @example\r
11431  *\r
11432  * _.indexOf([1, 2, 1, 2], 2);\r
11433  * // => 1\r
11434  *\r
11435  * // using `fromIndex`\r
11436  * _.indexOf([1, 2, 1, 2], 2, 2);\r
11437  * // => 3\r
11438  *\r
11439  * // performing a binary search\r
11440  * _.indexOf([1, 1, 2, 2], 2, true);\r
11441  * // => 2\r
11442  */\r
11443 function indexOf(array, value, fromIndex) {\r
11444   var length = array ? array.length : 0;\r
11445   if (!length) {\r
11446     return -1;\r
11447   }\r
11448   if (typeof fromIndex == 'number') {\r
11449     fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex;\r
11450   } else if (fromIndex) {\r
11451     var index = binaryIndex(array, value);\r
11452     if (index < length &&\r
11453         (value === value ? (value === array[index]) : (array[index] !== array[index]))) {\r
11454       return index;\r
11455     }\r
11456     return -1;\r
11457   }\r
11458   return baseIndexOf(array, value, fromIndex || 0);\r
11459 }\r
11460 \r
11461 module.exports = indexOf;\r
11462 \r
11463 },{"../internal/baseIndexOf":80,"../internal/binaryIndex":94}],52:[function(require,module,exports){\r
11464 /**\r
11465  * Gets the last element of `array`.\r
11466  *\r
11467  * @static\r
11468  * @memberOf _\r
11469  * @category Array\r
11470  * @param {Array} array The array to query.\r
11471  * @returns {*} Returns the last element of `array`.\r
11472  * @example\r
11473  *\r
11474  * _.last([1, 2, 3]);\r
11475  * // => 3\r
11476  */\r
11477 function last(array) {\r
11478   var length = array ? array.length : 0;\r
11479   return length ? array[length - 1] : undefined;\r
11480 }\r
11481 \r
11482 module.exports = last;\r
11483 \r
11484 },{}],53:[function(require,module,exports){\r
11485 var LazyWrapper = require('../internal/LazyWrapper'),\r
11486     LodashWrapper = require('../internal/LodashWrapper'),\r
11487     baseLodash = require('../internal/baseLodash'),\r
11488     isArray = require('../lang/isArray'),\r
11489     isObjectLike = require('../internal/isObjectLike'),\r
11490     wrapperClone = require('../internal/wrapperClone');\r
11491 \r
11492 /** Used for native method references. */\r
11493 var objectProto = Object.prototype;\r
11494 \r
11495 /** Used to check objects for own properties. */\r
11496 var hasOwnProperty = objectProto.hasOwnProperty;\r
11497 \r
11498 /**\r
11499  * Creates a `lodash` object which wraps `value` to enable implicit chaining.\r
11500  * Methods that operate on and return arrays, collections, and functions can\r
11501  * be chained together. Methods that retrieve a single value or may return a\r
11502  * primitive value will automatically end the chain returning the unwrapped\r
11503  * value. Explicit chaining may be enabled using `_.chain`. The execution of\r
11504  * chained methods is lazy, that is, execution is deferred until `_#value`\r
11505  * is implicitly or explicitly called.\r
11506  *\r
11507  * Lazy evaluation allows several methods to support shortcut fusion. Shortcut\r
11508  * fusion is an optimization strategy which merge iteratee calls; this can help\r
11509  * to avoid the creation of intermediate data structures and greatly reduce the\r
11510  * number of iteratee executions.\r
11511  *\r
11512  * Chaining is supported in custom builds as long as the `_#value` method is\r
11513  * directly or indirectly included in the build.\r
11514  *\r
11515  * In addition to lodash methods, wrappers have `Array` and `String` methods.\r
11516  *\r
11517  * The wrapper `Array` methods are:\r
11518  * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`,\r
11519  * `splice`, and `unshift`\r
11520  *\r
11521  * The wrapper `String` methods are:\r
11522  * `replace` and `split`\r
11523  *\r
11524  * The wrapper methods that support shortcut fusion are:\r
11525  * `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`,\r
11526  * `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`,\r
11527  * `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`,\r
11528  * and `where`\r
11529  *\r
11530  * The chainable wrapper methods are:\r
11531  * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`,\r
11532  * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`,\r
11533  * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defaultsDeep`,\r
11534  * `defer`, `delay`, `difference`, `drop`, `dropRight`, `dropRightWhile`,\r
11535  * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`,\r
11536  * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,\r
11537  * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,\r
11538  * `invoke`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`,\r
11539  * `matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`,\r
11540  * `modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`,\r
11541  * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`,\r
11542  * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`,\r
11543  * `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`,\r
11544  * `sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`,\r
11545  * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`,\r
11546  * `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`,\r
11547  * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWith`\r
11548  *\r
11549  * The wrapper methods that are **not** chainable by default are:\r
11550  * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`,\r
11551  * `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`,\r
11552  * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`,\r
11553  * `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`,\r
11554  * `inRange`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,\r
11555  * `isEmpty`, `isEqual`, `isError`, `isFinite` `isFunction`, `isMatch`,\r
11556  * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`,\r
11557  * `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`,\r
11558  * `last`, `lastIndexOf`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`,\r
11559  * `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`,\r
11560  * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`,\r
11561  * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`,\r
11562  * `startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`,\r
11563  * `unescape`, `uniqueId`, `value`, and `words`\r
11564  *\r
11565  * The wrapper method `sample` will return a wrapped value when `n` is provided,\r
11566  * otherwise an unwrapped value is returned.\r
11567  *\r
11568  * @name _\r
11569  * @constructor\r
11570  * @category Chain\r
11571  * @param {*} value The value to wrap in a `lodash` instance.\r
11572  * @returns {Object} Returns the new `lodash` wrapper instance.\r
11573  * @example\r
11574  *\r
11575  * var wrapped = _([1, 2, 3]);\r
11576  *\r
11577  * // returns an unwrapped value\r
11578  * wrapped.reduce(function(total, n) {\r
11579  *   return total + n;\r
11580  * });\r
11581  * // => 6\r
11582  *\r
11583  * // returns a wrapped value\r
11584  * var squares = wrapped.map(function(n) {\r
11585  *   return n * n;\r
11586  * });\r
11587  *\r
11588  * _.isArray(squares);\r
11589  * // => false\r
11590  *\r
11591  * _.isArray(squares.value());\r
11592  * // => true\r
11593  */\r
11594 function lodash(value) {\r
11595   if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {\r
11596     if (value instanceof LodashWrapper) {\r
11597       return value;\r
11598     }\r
11599     if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) {\r
11600       return wrapperClone(value);\r
11601     }\r
11602   }\r
11603   return new LodashWrapper(value);\r
11604 }\r
11605 \r
11606 // Ensure wrappers are instances of `baseLodash`.\r
11607 lodash.prototype = baseLodash.prototype;\r
11608 \r
11609 module.exports = lodash;\r
11610 \r
11611 },{"../internal/LazyWrapper":62,"../internal/LodashWrapper":63,"../internal/baseLodash":84,"../internal/isObjectLike":128,"../internal/wrapperClone":139,"../lang/isArray":142}],54:[function(require,module,exports){\r
11612 module.exports = require('./forEach');\r
11613 \r
11614 },{"./forEach":56}],55:[function(require,module,exports){\r
11615 var baseEach = require('../internal/baseEach'),\r
11616     createFind = require('../internal/createFind');\r
11617 \r
11618 /**\r
11619  * Iterates over elements of `collection`, returning the first element\r
11620  * `predicate` returns truthy for. The predicate is bound to `thisArg` and\r
11621  * invoked with three arguments: (value, index|key, collection).\r
11622  *\r
11623  * If a property name is provided for `predicate` the created `_.property`\r
11624  * style callback returns the property value of the given element.\r
11625  *\r
11626  * If a value is also provided for `thisArg` the created `_.matchesProperty`\r
11627  * style callback returns `true` for elements that have a matching property\r
11628  * value, else `false`.\r
11629  *\r
11630  * If an object is provided for `predicate` the created `_.matches` style\r
11631  * callback returns `true` for elements that have the properties of the given\r
11632  * object, else `false`.\r
11633  *\r
11634  * @static\r
11635  * @memberOf _\r
11636  * @alias detect\r
11637  * @category Collection\r
11638  * @param {Array|Object|string} collection The collection to search.\r
11639  * @param {Function|Object|string} [predicate=_.identity] The function invoked\r
11640  *  per iteration.\r
11641  * @param {*} [thisArg] The `this` binding of `predicate`.\r
11642  * @returns {*} Returns the matched element, else `undefined`.\r
11643  * @example\r
11644  *\r
11645  * var users = [\r
11646  *   { 'user': 'barney',  'age': 36, 'active': true },\r
11647  *   { 'user': 'fred',    'age': 40, 'active': false },\r
11648  *   { 'user': 'pebbles', 'age': 1,  'active': true }\r
11649  * ];\r
11650  *\r
11651  * _.result(_.find(users, function(chr) {\r
11652  *   return chr.age < 40;\r
11653  * }), 'user');\r
11654  * // => 'barney'\r
11655  *\r
11656  * // using the `_.matches` callback shorthand\r
11657  * _.result(_.find(users, { 'age': 1, 'active': true }), 'user');\r
11658  * // => 'pebbles'\r
11659  *\r
11660  * // using the `_.matchesProperty` callback shorthand\r
11661  * _.result(_.find(users, 'active', false), 'user');\r
11662  * // => 'fred'\r
11663  *\r
11664  * // using the `_.property` callback shorthand\r
11665  * _.result(_.find(users, 'active'), 'user');\r
11666  * // => 'barney'\r
11667  */\r
11668 var find = createFind(baseEach);\r
11669 \r
11670 module.exports = find;\r
11671 \r
11672 },{"../internal/baseEach":73,"../internal/createFind":104}],56:[function(require,module,exports){\r
11673 var arrayEach = require('../internal/arrayEach'),\r
11674     baseEach = require('../internal/baseEach'),\r
11675     createForEach = require('../internal/createForEach');\r
11676 \r
11677 /**\r
11678  * Iterates over elements of `collection` invoking `iteratee` for each element.\r
11679  * The `iteratee` is bound to `thisArg` and invoked with three arguments:\r
11680  * (value, index|key, collection). Iteratee functions may exit iteration early\r
11681  * by explicitly returning `false`.\r
11682  *\r
11683  * **Note:** As with other "Collections" methods, objects with a "length" property\r
11684  * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`\r
11685  * may be used for object iteration.\r
11686  *\r
11687  * @static\r
11688  * @memberOf _\r
11689  * @alias each\r
11690  * @category Collection\r
11691  * @param {Array|Object|string} collection The collection to iterate over.\r
11692  * @param {Function} [iteratee=_.identity] The function invoked per iteration.\r
11693  * @param {*} [thisArg] The `this` binding of `iteratee`.\r
11694  * @returns {Array|Object|string} Returns `collection`.\r
11695  * @example\r
11696  *\r
11697  * _([1, 2]).forEach(function(n) {\r
11698  *   console.log(n);\r
11699  * }).value();\r
11700  * // => logs each value from left to right and returns the array\r
11701  *\r
11702  * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) {\r
11703  *   console.log(n, key);\r
11704  * });\r
11705  * // => logs each value-key pair and returns the object (iteration order is not guaranteed)\r
11706  */\r
11707 var forEach = createForEach(arrayEach, baseEach);\r
11708 \r
11709 module.exports = forEach;\r
11710 \r
11711 },{"../internal/arrayEach":65,"../internal/baseEach":73,"../internal/createForEach":105}],57:[function(require,module,exports){\r
11712 var baseIndexOf = require('../internal/baseIndexOf'),\r
11713     getLength = require('../internal/getLength'),\r
11714     isArray = require('../lang/isArray'),\r
11715     isIterateeCall = require('../internal/isIterateeCall'),\r
11716     isLength = require('../internal/isLength'),\r
11717     isString = require('../lang/isString'),\r
11718     values = require('../object/values');\r
11719 \r
11720 /* Native method references for those with the same name as other `lodash` methods. */\r
11721 var nativeMax = Math.max;\r
11722 \r
11723 /**\r
11724  * Checks if `target` is in `collection` using\r
11725  * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\r
11726  * for equality comparisons. If `fromIndex` is negative, it's used as the offset\r
11727  * from the end of `collection`.\r
11728  *\r
11729  * @static\r
11730  * @memberOf _\r
11731  * @alias contains, include\r
11732  * @category Collection\r
11733  * @param {Array|Object|string} collection The collection to search.\r
11734  * @param {*} target The value to search for.\r
11735  * @param {number} [fromIndex=0] The index to search from.\r
11736  * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`.\r
11737  * @returns {boolean} Returns `true` if a matching element is found, else `false`.\r
11738  * @example\r
11739  *\r
11740  * _.includes([1, 2, 3], 1);\r
11741  * // => true\r
11742  *\r
11743  * _.includes([1, 2, 3], 1, 2);\r
11744  * // => false\r
11745  *\r
11746  * _.includes({ 'user': 'fred', 'age': 40 }, 'fred');\r
11747  * // => true\r
11748  *\r
11749  * _.includes('pebbles', 'eb');\r
11750  * // => true\r
11751  */\r
11752 function includes(collection, target, fromIndex, guard) {\r
11753   var length = collection ? getLength(collection) : 0;\r
11754   if (!isLength(length)) {\r
11755     collection = values(collection);\r
11756     length = collection.length;\r
11757   }\r
11758   if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) {\r
11759     fromIndex = 0;\r
11760   } else {\r
11761     fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0);\r
11762   }\r
11763   return (typeof collection == 'string' || !isArray(collection) && isString(collection))\r
11764     ? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1)\r
11765     : (!!length && baseIndexOf(collection, target, fromIndex) > -1);\r
11766 }\r
11767 \r
11768 module.exports = includes;\r
11769 \r
11770 },{"../internal/baseIndexOf":80,"../internal/getLength":114,"../internal/isIterateeCall":124,"../internal/isLength":127,"../lang/isArray":142,"../lang/isString":148,"../object/values":154}],58:[function(require,module,exports){\r
11771 var arrayMap = require('../internal/arrayMap'),\r
11772     baseCallback = require('../internal/baseCallback'),\r
11773     baseMap = require('../internal/baseMap'),\r
11774     isArray = require('../lang/isArray');\r
11775 \r
11776 /**\r
11777  * Creates an array of values by running each element in `collection` through\r
11778  * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three\r
11779  * arguments: (value, index|key, collection).\r
11780  *\r
11781  * If a property name is provided for `iteratee` the created `_.property`\r
11782  * style callback returns the property value of the given element.\r
11783  *\r
11784  * If a value is also provided for `thisArg` the created `_.matchesProperty`\r
11785  * style callback returns `true` for elements that have a matching property\r
11786  * value, else `false`.\r
11787  *\r
11788  * If an object is provided for `iteratee` the created `_.matches` style\r
11789  * callback returns `true` for elements that have the properties of the given\r
11790  * object, else `false`.\r
11791  *\r
11792  * Many lodash methods are guarded to work as iteratees for methods like\r
11793  * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.\r
11794  *\r
11795  * The guarded methods are:\r
11796  * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`,\r
11797  * `drop`, `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`,\r
11798  * `parseInt`, `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`,\r
11799  * `trimLeft`, `trimRight`, `trunc`, `random`, `range`, `sample`, `some`,\r
11800  * `sum`, `uniq`, and `words`\r
11801  *\r
11802  * @static\r
11803  * @memberOf _\r
11804  * @alias collect\r
11805  * @category Collection\r
11806  * @param {Array|Object|string} collection The collection to iterate over.\r
11807  * @param {Function|Object|string} [iteratee=_.identity] The function invoked\r
11808  *  per iteration.\r
11809  * @param {*} [thisArg] The `this` binding of `iteratee`.\r
11810  * @returns {Array} Returns the new mapped array.\r
11811  * @example\r
11812  *\r
11813  * function timesThree(n) {\r
11814  *   return n * 3;\r
11815  * }\r
11816  *\r
11817  * _.map([1, 2], timesThree);\r
11818  * // => [3, 6]\r
11819  *\r
11820  * _.map({ 'a': 1, 'b': 2 }, timesThree);\r
11821  * // => [3, 6] (iteration order is not guaranteed)\r
11822  *\r
11823  * var users = [\r
11824  *   { 'user': 'barney' },\r
11825  *   { 'user': 'fred' }\r
11826  * ];\r
11827  *\r
11828  * // using the `_.property` callback shorthand\r
11829  * _.map(users, 'user');\r
11830  * // => ['barney', 'fred']\r
11831  */\r
11832 function map(collection, iteratee, thisArg) {\r
11833   var func = isArray(collection) ? arrayMap : baseMap;\r
11834   iteratee = baseCallback(iteratee, thisArg, 3);\r
11835   return func(collection, iteratee);\r
11836 }\r
11837 \r
11838 module.exports = map;\r
11839 \r
11840 },{"../internal/arrayMap":66,"../internal/baseCallback":69,"../internal/baseMap":85,"../lang/isArray":142}],59:[function(require,module,exports){\r
11841 var getNative = require('../internal/getNative');\r
11842 \r
11843 /* Native method references for those with the same name as other `lodash` methods. */\r
11844 var nativeNow = getNative(Date, 'now');\r
11845 \r
11846 /**\r
11847  * Gets the number of milliseconds that have elapsed since the Unix epoch\r
11848  * (1 January 1970 00:00:00 UTC).\r
11849  *\r
11850  * @static\r
11851  * @memberOf _\r
11852  * @category Date\r
11853  * @example\r
11854  *\r
11855  * _.defer(function(stamp) {\r
11856  *   console.log(_.now() - stamp);\r
11857  * }, _.now());\r
11858  * // => logs the number of milliseconds it took for the deferred function to be invoked\r
11859  */\r
11860 var now = nativeNow || function() {\r
11861   return new Date().getTime();\r
11862 };\r
11863 \r
11864 module.exports = now;\r
11865 \r
11866 },{"../internal/getNative":116}],60:[function(require,module,exports){\r
11867 var createWrapper = require('../internal/createWrapper'),\r
11868     replaceHolders = require('../internal/replaceHolders'),\r
11869     restParam = require('./restParam');\r
11870 \r
11871 /** Used to compose bitmasks for wrapper metadata. */\r
11872 var BIND_FLAG = 1,\r
11873     PARTIAL_FLAG = 32;\r
11874 \r
11875 /**\r
11876  * Creates a function that invokes `func` with the `this` binding of `thisArg`\r
11877  * and prepends any additional `_.bind` arguments to those provided to the\r
11878  * bound function.\r
11879  *\r
11880  * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,\r
11881  * may be used as a placeholder for partially applied arguments.\r
11882  *\r
11883  * **Note:** Unlike native `Function#bind` this method does not set the "length"\r
11884  * property of bound functions.\r
11885  *\r
11886  * @static\r
11887  * @memberOf _\r
11888  * @category Function\r
11889  * @param {Function} func The function to bind.\r
11890  * @param {*} thisArg The `this` binding of `func`.\r
11891  * @param {...*} [partials] The arguments to be partially applied.\r
11892  * @returns {Function} Returns the new bound function.\r
11893  * @example\r
11894  *\r
11895  * var greet = function(greeting, punctuation) {\r
11896  *   return greeting + ' ' + this.user + punctuation;\r
11897  * };\r
11898  *\r
11899  * var object = { 'user': 'fred' };\r
11900  *\r
11901  * var bound = _.bind(greet, object, 'hi');\r
11902  * bound('!');\r
11903  * // => 'hi fred!'\r
11904  *\r
11905  * // using placeholders\r
11906  * var bound = _.bind(greet, object, _, '!');\r
11907  * bound('hi');\r
11908  * // => 'hi fred!'\r
11909  */\r
11910 var bind = restParam(function(func, thisArg, partials) {\r
11911   var bitmask = BIND_FLAG;\r
11912   if (partials.length) {\r
11913     var holders = replaceHolders(partials, bind.placeholder);\r
11914     bitmask |= PARTIAL_FLAG;\r
11915   }\r
11916   return createWrapper(func, bitmask, thisArg, partials, holders);\r
11917 });\r
11918 \r
11919 // Assign default placeholders.\r
11920 bind.placeholder = {};\r
11921 \r
11922 module.exports = bind;\r
11923 \r
11924 },{"../internal/createWrapper":108,"../internal/replaceHolders":134,"./restParam":61}],61:[function(require,module,exports){\r
11925 /** Used as the `TypeError` message for "Functions" methods. */\r
11926 var FUNC_ERROR_TEXT = 'Expected a function';\r
11927 \r
11928 /* Native method references for those with the same name as other `lodash` methods. */\r
11929 var nativeMax = Math.max;\r
11930 \r
11931 /**\r
11932  * Creates a function that invokes `func` with the `this` binding of the\r
11933  * created function and arguments from `start` and beyond provided as an array.\r
11934  *\r
11935  * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/Web/JavaScript/Reference/Functions/rest_parameters).\r
11936  *\r
11937  * @static\r
11938  * @memberOf _\r
11939  * @category Function\r
11940  * @param {Function} func The function to apply a rest parameter to.\r
11941  * @param {number} [start=func.length-1] The start position of the rest parameter.\r
11942  * @returns {Function} Returns the new function.\r
11943  * @example\r
11944  *\r
11945  * var say = _.restParam(function(what, names) {\r
11946  *   return what + ' ' + _.initial(names).join(', ') +\r
11947  *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);\r
11948  * });\r
11949  *\r
11950  * say('hello', 'fred', 'barney', 'pebbles');\r
11951  * // => 'hello fred, barney, & pebbles'\r
11952  */\r
11953 function restParam(func, start) {\r
11954   if (typeof func != 'function') {\r
11955     throw new TypeError(FUNC_ERROR_TEXT);\r
11956   }\r
11957   start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0);\r
11958   return function() {\r
11959     var args = arguments,\r
11960         index = -1,\r
11961         length = nativeMax(args.length - start, 0),\r
11962         rest = Array(length);\r
11963 \r
11964     while (++index < length) {\r
11965       rest[index] = args[start + index];\r
11966     }\r
11967     switch (start) {\r
11968       case 0: return func.call(this, rest);\r
11969       case 1: return func.call(this, args[0], rest);\r
11970       case 2: return func.call(this, args[0], args[1], rest);\r
11971     }\r
11972     var otherArgs = Array(start + 1);\r
11973     index = -1;\r
11974     while (++index < start) {\r
11975       otherArgs[index] = args[index];\r
11976     }\r
11977     otherArgs[start] = rest;\r
11978     return func.apply(this, otherArgs);\r
11979   };\r
11980 }\r
11981 \r
11982 module.exports = restParam;\r
11983 \r
11984 },{}],62:[function(require,module,exports){\r
11985 var baseCreate = require('./baseCreate'),\r
11986     baseLodash = require('./baseLodash');\r
11987 \r
11988 /** Used as references for `-Infinity` and `Infinity`. */\r
11989 var POSITIVE_INFINITY = Number.POSITIVE_INFINITY;\r
11990 \r
11991 /**\r
11992  * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.\r
11993  *\r
11994  * @private\r
11995  * @param {*} value The value to wrap.\r
11996  */\r
11997 function LazyWrapper(value) {\r
11998   this.__wrapped__ = value;\r
11999   this.__actions__ = [];\r
12000   this.__dir__ = 1;\r
12001   this.__filtered__ = false;\r
12002   this.__iteratees__ = [];\r
12003   this.__takeCount__ = POSITIVE_INFINITY;\r
12004   this.__views__ = [];\r
12005 }\r
12006 \r
12007 LazyWrapper.prototype = baseCreate(baseLodash.prototype);\r
12008 LazyWrapper.prototype.constructor = LazyWrapper;\r
12009 \r
12010 module.exports = LazyWrapper;\r
12011 \r
12012 },{"./baseCreate":72,"./baseLodash":84}],63:[function(require,module,exports){\r
12013 var baseCreate = require('./baseCreate'),\r
12014     baseLodash = require('./baseLodash');\r
12015 \r
12016 /**\r
12017  * The base constructor for creating `lodash` wrapper objects.\r
12018  *\r
12019  * @private\r
12020  * @param {*} value The value to wrap.\r
12021  * @param {boolean} [chainAll] Enable chaining for all wrapper methods.\r
12022  * @param {Array} [actions=[]] Actions to peform to resolve the unwrapped value.\r
12023  */\r
12024 function LodashWrapper(value, chainAll, actions) {\r
12025   this.__wrapped__ = value;\r
12026   this.__actions__ = actions || [];\r
12027   this.__chain__ = !!chainAll;\r
12028 }\r
12029 \r
12030 LodashWrapper.prototype = baseCreate(baseLodash.prototype);\r
12031 LodashWrapper.prototype.constructor = LodashWrapper;\r
12032 \r
12033 module.exports = LodashWrapper;\r
12034 \r
12035 },{"./baseCreate":72,"./baseLodash":84}],64:[function(require,module,exports){\r
12036 /**\r
12037  * Copies the values of `source` to `array`.\r
12038  *\r
12039  * @private\r
12040  * @param {Array} source The array to copy values from.\r
12041  * @param {Array} [array=[]] The array to copy values to.\r
12042  * @returns {Array} Returns `array`.\r
12043  */\r
12044 function arrayCopy(source, array) {\r
12045   var index = -1,\r
12046       length = source.length;\r
12047 \r
12048   array || (array = Array(length));\r
12049   while (++index < length) {\r
12050     array[index] = source[index];\r
12051   }\r
12052   return array;\r
12053 }\r
12054 \r
12055 module.exports = arrayCopy;\r
12056 \r
12057 },{}],65:[function(require,module,exports){\r
12058 /**\r
12059  * A specialized version of `_.forEach` for arrays without support for callback\r
12060  * shorthands and `this` binding.\r
12061  *\r
12062  * @private\r
12063  * @param {Array} array The array to iterate over.\r
12064  * @param {Function} iteratee The function invoked per iteration.\r
12065  * @returns {Array} Returns `array`.\r
12066  */\r
12067 function arrayEach(array, iteratee) {\r
12068   var index = -1,\r
12069       length = array.length;\r
12070 \r
12071   while (++index < length) {\r
12072     if (iteratee(array[index], index, array) === false) {\r
12073       break;\r
12074     }\r
12075   }\r
12076   return array;\r
12077 }\r
12078 \r
12079 module.exports = arrayEach;\r
12080 \r
12081 },{}],66:[function(require,module,exports){\r
12082 /**\r
12083  * A specialized version of `_.map` for arrays without support for callback\r
12084  * shorthands and `this` binding.\r
12085  *\r
12086  * @private\r
12087  * @param {Array} array The array to iterate over.\r
12088  * @param {Function} iteratee The function invoked per iteration.\r
12089  * @returns {Array} Returns the new mapped array.\r
12090  */\r
12091 function arrayMap(array, iteratee) {\r
12092   var index = -1,\r
12093       length = array.length,\r
12094       result = Array(length);\r
12095 \r
12096   while (++index < length) {\r
12097     result[index] = iteratee(array[index], index, array);\r
12098   }\r
12099   return result;\r
12100 }\r
12101 \r
12102 module.exports = arrayMap;\r
12103 \r
12104 },{}],67:[function(require,module,exports){\r
12105 /**\r
12106  * A specialized version of `_.some` for arrays without support for callback\r
12107  * shorthands and `this` binding.\r
12108  *\r
12109  * @private\r
12110  * @param {Array} array The array to iterate over.\r
12111  * @param {Function} predicate The function invoked per iteration.\r
12112  * @returns {boolean} Returns `true` if any element passes the predicate check,\r
12113  *  else `false`.\r
12114  */\r
12115 function arraySome(array, predicate) {\r
12116   var index = -1,\r
12117       length = array.length;\r
12118 \r
12119   while (++index < length) {\r
12120     if (predicate(array[index], index, array)) {\r
12121       return true;\r
12122     }\r
12123   }\r
12124   return false;\r
12125 }\r
12126 \r
12127 module.exports = arraySome;\r
12128 \r
12129 },{}],68:[function(require,module,exports){\r
12130 var baseCopy = require('./baseCopy'),\r
12131     keys = require('../object/keys');\r
12132 \r
12133 /**\r
12134  * The base implementation of `_.assign` without support for argument juggling,\r
12135  * multiple sources, and `customizer` functions.\r
12136  *\r
12137  * @private\r
12138  * @param {Object} object The destination object.\r
12139  * @param {Object} source The source object.\r
12140  * @returns {Object} Returns `object`.\r
12141  */\r
12142 function baseAssign(object, source) {\r
12143   return source == null\r
12144     ? object\r
12145     : baseCopy(source, keys(source), object);\r
12146 }\r
12147 \r
12148 module.exports = baseAssign;\r
12149 \r
12150 },{"../object/keys":151,"./baseCopy":71}],69:[function(require,module,exports){\r
12151 var baseMatches = require('./baseMatches'),\r
12152     baseMatchesProperty = require('./baseMatchesProperty'),\r
12153     bindCallback = require('./bindCallback'),\r
12154     identity = require('../utility/identity'),\r
12155     property = require('../utility/property');\r
12156 \r
12157 /**\r
12158  * The base implementation of `_.callback` which supports specifying the\r
12159  * number of arguments to provide to `func`.\r
12160  *\r
12161  * @private\r
12162  * @param {*} [func=_.identity] The value to convert to a callback.\r
12163  * @param {*} [thisArg] The `this` binding of `func`.\r
12164  * @param {number} [argCount] The number of arguments to provide to `func`.\r
12165  * @returns {Function} Returns the callback.\r
12166  */\r
12167 function baseCallback(func, thisArg, argCount) {\r
12168   var type = typeof func;\r
12169   if (type == 'function') {\r
12170     return thisArg === undefined\r
12171       ? func\r
12172       : bindCallback(func, thisArg, argCount);\r
12173   }\r
12174   if (func == null) {\r
12175     return identity;\r
12176   }\r
12177   if (type == 'object') {\r
12178     return baseMatches(func);\r
12179   }\r
12180   return thisArg === undefined\r
12181     ? property(func)\r
12182     : baseMatchesProperty(func, thisArg);\r
12183 }\r
12184 \r
12185 module.exports = baseCallback;\r
12186 \r
12187 },{"../utility/identity":156,"../utility/property":158,"./baseMatches":86,"./baseMatchesProperty":87,"./bindCallback":96}],70:[function(require,module,exports){\r
12188 var arrayCopy = require('./arrayCopy'),\r
12189     arrayEach = require('./arrayEach'),\r
12190     baseAssign = require('./baseAssign'),\r
12191     baseForOwn = require('./baseForOwn'),\r
12192     initCloneArray = require('./initCloneArray'),\r
12193     initCloneByTag = require('./initCloneByTag'),\r
12194     initCloneObject = require('./initCloneObject'),\r
12195     isArray = require('../lang/isArray'),\r
12196     isHostObject = require('./isHostObject'),\r
12197     isObject = require('../lang/isObject');\r
12198 \r
12199 /** `Object#toString` result references. */\r
12200 var argsTag = '[object Arguments]',\r
12201     arrayTag = '[object Array]',\r
12202     boolTag = '[object Boolean]',\r
12203     dateTag = '[object Date]',\r
12204     errorTag = '[object Error]',\r
12205     funcTag = '[object Function]',\r
12206     mapTag = '[object Map]',\r
12207     numberTag = '[object Number]',\r
12208     objectTag = '[object Object]',\r
12209     regexpTag = '[object RegExp]',\r
12210     setTag = '[object Set]',\r
12211     stringTag = '[object String]',\r
12212     weakMapTag = '[object WeakMap]';\r
12213 \r
12214 var arrayBufferTag = '[object ArrayBuffer]',\r
12215     float32Tag = '[object Float32Array]',\r
12216     float64Tag = '[object Float64Array]',\r
12217     int8Tag = '[object Int8Array]',\r
12218     int16Tag = '[object Int16Array]',\r
12219     int32Tag = '[object Int32Array]',\r
12220     uint8Tag = '[object Uint8Array]',\r
12221     uint8ClampedTag = '[object Uint8ClampedArray]',\r
12222     uint16Tag = '[object Uint16Array]',\r
12223     uint32Tag = '[object Uint32Array]';\r
12224 \r
12225 /** Used to identify `toStringTag` values supported by `_.clone`. */\r
12226 var cloneableTags = {};\r
12227 cloneableTags[argsTag] = cloneableTags[arrayTag] =\r
12228 cloneableTags[arrayBufferTag] = cloneableTags[boolTag] =\r
12229 cloneableTags[dateTag] = cloneableTags[float32Tag] =\r
12230 cloneableTags[float64Tag] = cloneableTags[int8Tag] =\r
12231 cloneableTags[int16Tag] = cloneableTags[int32Tag] =\r
12232 cloneableTags[numberTag] = cloneableTags[objectTag] =\r
12233 cloneableTags[regexpTag] = cloneableTags[stringTag] =\r
12234 cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =\r
12235 cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;\r
12236 cloneableTags[errorTag] = cloneableTags[funcTag] =\r
12237 cloneableTags[mapTag] = cloneableTags[setTag] =\r
12238 cloneableTags[weakMapTag] = false;\r
12239 \r
12240 /** Used for native method references. */\r
12241 var objectProto = Object.prototype;\r
12242 \r
12243 /**\r
12244  * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\r
12245  * of values.\r
12246  */\r
12247 var objToString = objectProto.toString;\r
12248 \r
12249 /**\r
12250  * The base implementation of `_.clone` without support for argument juggling\r
12251  * and `this` binding `customizer` functions.\r
12252  *\r
12253  * @private\r
12254  * @param {*} value The value to clone.\r
12255  * @param {boolean} [isDeep] Specify a deep clone.\r
12256  * @param {Function} [customizer] The function to customize cloning values.\r
12257  * @param {string} [key] The key of `value`.\r
12258  * @param {Object} [object] The object `value` belongs to.\r
12259  * @param {Array} [stackA=[]] Tracks traversed source objects.\r
12260  * @param {Array} [stackB=[]] Associates clones with source counterparts.\r
12261  * @returns {*} Returns the cloned value.\r
12262  */\r
12263 function baseClone(value, isDeep, customizer, key, object, stackA, stackB) {\r
12264   var result;\r
12265   if (customizer) {\r
12266     result = object ? customizer(value, key, object) : customizer(value);\r
12267   }\r
12268   if (result !== undefined) {\r
12269     return result;\r
12270   }\r
12271   if (!isObject(value)) {\r
12272     return value;\r
12273   }\r
12274   var isArr = isArray(value);\r
12275   if (isArr) {\r
12276     result = initCloneArray(value);\r
12277     if (!isDeep) {\r
12278       return arrayCopy(value, result);\r
12279     }\r
12280   } else {\r
12281     var tag = objToString.call(value),\r
12282         isFunc = tag == funcTag;\r
12283 \r
12284     if (tag == objectTag || tag == argsTag || (isFunc && !object)) {\r
12285       if (isHostObject(value)) {\r
12286         return object ? value : {};\r
12287       }\r
12288       result = initCloneObject(isFunc ? {} : value);\r
12289       if (!isDeep) {\r
12290         return baseAssign(result, value);\r
12291       }\r
12292     } else {\r
12293       return cloneableTags[tag]\r
12294         ? initCloneByTag(value, tag, isDeep)\r
12295         : (object ? value : {});\r
12296     }\r
12297   }\r
12298   // Check for circular references and return its corresponding clone.\r
12299   stackA || (stackA = []);\r
12300   stackB || (stackB = []);\r
12301 \r
12302   var length = stackA.length;\r
12303   while (length--) {\r
12304     if (stackA[length] == value) {\r
12305       return stackB[length];\r
12306     }\r
12307   }\r
12308   // Add the source value to the stack of traversed objects and associate it with its clone.\r
12309   stackA.push(value);\r
12310   stackB.push(result);\r
12311 \r
12312   // Recursively populate clone (susceptible to call stack limits).\r
12313   (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {\r
12314     result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB);\r
12315   });\r
12316   return result;\r
12317 }\r
12318 \r
12319 module.exports = baseClone;\r
12320 \r
12321 },{"../lang/isArray":142,"../lang/isObject":146,"./arrayCopy":64,"./arrayEach":65,"./baseAssign":68,"./baseForOwn":78,"./initCloneArray":118,"./initCloneByTag":119,"./initCloneObject":120,"./isHostObject":122}],71:[function(require,module,exports){\r
12322 /**\r
12323  * Copies properties of `source` to `object`.\r
12324  *\r
12325  * @private\r
12326  * @param {Object} source The object to copy properties from.\r
12327  * @param {Array} props The property names to copy.\r
12328  * @param {Object} [object={}] The object to copy properties to.\r
12329  * @returns {Object} Returns `object`.\r
12330  */\r
12331 function baseCopy(source, props, object) {\r
12332   object || (object = {});\r
12333 \r
12334   var index = -1,\r
12335       length = props.length;\r
12336 \r
12337   while (++index < length) {\r
12338     var key = props[index];\r
12339     object[key] = source[key];\r
12340   }\r
12341   return object;\r
12342 }\r
12343 \r
12344 module.exports = baseCopy;\r
12345 \r
12346 },{}],72:[function(require,module,exports){\r
12347 var isObject = require('../lang/isObject');\r
12348 \r
12349 /**\r
12350  * The base implementation of `_.create` without support for assigning\r
12351  * properties to the created object.\r
12352  *\r
12353  * @private\r
12354  * @param {Object} prototype The object to inherit from.\r
12355  * @returns {Object} Returns the new object.\r
12356  */\r
12357 var baseCreate = (function() {\r
12358   function object() {}\r
12359   return function(prototype) {\r
12360     if (isObject(prototype)) {\r
12361       object.prototype = prototype;\r
12362       var result = new object;\r
12363       object.prototype = undefined;\r
12364     }\r
12365     return result || {};\r
12366   };\r
12367 }());\r
12368 \r
12369 module.exports = baseCreate;\r
12370 \r
12371 },{"../lang/isObject":146}],73:[function(require,module,exports){\r
12372 var baseForOwn = require('./baseForOwn'),\r
12373     createBaseEach = require('./createBaseEach');\r
12374 \r
12375 /**\r
12376  * The base implementation of `_.forEach` without support for callback\r
12377  * shorthands and `this` binding.\r
12378  *\r
12379  * @private\r
12380  * @param {Array|Object|string} collection The collection to iterate over.\r
12381  * @param {Function} iteratee The function invoked per iteration.\r
12382  * @returns {Array|Object|string} Returns `collection`.\r
12383  */\r
12384 var baseEach = createBaseEach(baseForOwn);\r
12385 \r
12386 module.exports = baseEach;\r
12387 \r
12388 },{"./baseForOwn":78,"./createBaseEach":100}],74:[function(require,module,exports){\r
12389 /**\r
12390  * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.findLastKey`,\r
12391  * without support for callback shorthands and `this` binding, which iterates\r
12392  * over `collection` using the provided `eachFunc`.\r
12393  *\r
12394  * @private\r
12395  * @param {Array|Object|string} collection The collection to search.\r
12396  * @param {Function} predicate The function invoked per iteration.\r
12397  * @param {Function} eachFunc The function to iterate over `collection`.\r
12398  * @param {boolean} [retKey] Specify returning the key of the found element\r
12399  *  instead of the element itself.\r
12400  * @returns {*} Returns the found element or its key, else `undefined`.\r
12401  */\r
12402 function baseFind(collection, predicate, eachFunc, retKey) {\r
12403   var result;\r
12404   eachFunc(collection, function(value, key, collection) {\r
12405     if (predicate(value, key, collection)) {\r
12406       result = retKey ? key : value;\r
12407       return false;\r
12408     }\r
12409   });\r
12410   return result;\r
12411 }\r
12412 \r
12413 module.exports = baseFind;\r
12414 \r
12415 },{}],75:[function(require,module,exports){\r
12416 /**\r
12417  * The base implementation of `_.findIndex` and `_.findLastIndex` without\r
12418  * support for callback shorthands and `this` binding.\r
12419  *\r
12420  * @private\r
12421  * @param {Array} array The array to search.\r
12422  * @param {Function} predicate The function invoked per iteration.\r
12423  * @param {boolean} [fromRight] Specify iterating from right to left.\r
12424  * @returns {number} Returns the index of the matched value, else `-1`.\r
12425  */\r
12426 function baseFindIndex(array, predicate, fromRight) {\r
12427   var length = array.length,\r
12428       index = fromRight ? length : -1;\r
12429 \r
12430   while ((fromRight ? index-- : ++index < length)) {\r
12431     if (predicate(array[index], index, array)) {\r
12432       return index;\r
12433     }\r
12434   }\r
12435   return -1;\r
12436 }\r
12437 \r
12438 module.exports = baseFindIndex;\r
12439 \r
12440 },{}],76:[function(require,module,exports){\r
12441 var createBaseFor = require('./createBaseFor');\r
12442 \r
12443 /**\r
12444  * The base implementation of `baseForIn` and `baseForOwn` which iterates\r
12445  * over `object` properties returned by `keysFunc` invoking `iteratee` for\r
12446  * each property. Iteratee functions may exit iteration early by explicitly\r
12447  * returning `false`.\r
12448  *\r
12449  * @private\r
12450  * @param {Object} object The object to iterate over.\r
12451  * @param {Function} iteratee The function invoked per iteration.\r
12452  * @param {Function} keysFunc The function to get the keys of `object`.\r
12453  * @returns {Object} Returns `object`.\r
12454  */\r
12455 var baseFor = createBaseFor();\r
12456 \r
12457 module.exports = baseFor;\r
12458 \r
12459 },{"./createBaseFor":101}],77:[function(require,module,exports){\r
12460 var baseFor = require('./baseFor'),\r
12461     keysIn = require('../object/keysIn');\r
12462 \r
12463 /**\r
12464  * The base implementation of `_.forIn` without support for callback\r
12465  * shorthands and `this` binding.\r
12466  *\r
12467  * @private\r
12468  * @param {Object} object The object to iterate over.\r
12469  * @param {Function} iteratee The function invoked per iteration.\r
12470  * @returns {Object} Returns `object`.\r
12471  */\r
12472 function baseForIn(object, iteratee) {\r
12473   return baseFor(object, iteratee, keysIn);\r
12474 }\r
12475 \r
12476 module.exports = baseForIn;\r
12477 \r
12478 },{"../object/keysIn":152,"./baseFor":76}],78:[function(require,module,exports){\r
12479 var baseFor = require('./baseFor'),\r
12480     keys = require('../object/keys');\r
12481 \r
12482 /**\r
12483  * The base implementation of `_.forOwn` without support for callback\r
12484  * shorthands and `this` binding.\r
12485  *\r
12486  * @private\r
12487  * @param {Object} object The object to iterate over.\r
12488  * @param {Function} iteratee The function invoked per iteration.\r
12489  * @returns {Object} Returns `object`.\r
12490  */\r
12491 function baseForOwn(object, iteratee) {\r
12492   return baseFor(object, iteratee, keys);\r
12493 }\r
12494 \r
12495 module.exports = baseForOwn;\r
12496 \r
12497 },{"../object/keys":151,"./baseFor":76}],79:[function(require,module,exports){\r
12498 var toObject = require('./toObject');\r
12499 \r
12500 /**\r
12501  * The base implementation of `get` without support for string paths\r
12502  * and default values.\r
12503  *\r
12504  * @private\r
12505  * @param {Object} object The object to query.\r
12506  * @param {Array} path The path of the property to get.\r
12507  * @param {string} [pathKey] The key representation of path.\r
12508  * @returns {*} Returns the resolved value.\r
12509  */\r
12510 function baseGet(object, path, pathKey) {\r
12511   if (object == null) {\r
12512     return;\r
12513   }\r
12514   object = toObject(object);\r
12515   if (pathKey !== undefined && pathKey in object) {\r
12516     path = [pathKey];\r
12517   }\r
12518   var index = 0,\r
12519       length = path.length;\r
12520 \r
12521   while (object != null && index < length) {\r
12522     object = toObject(object)[path[index++]];\r
12523   }\r
12524   return (index && index == length) ? object : undefined;\r
12525 }\r
12526 \r
12527 module.exports = baseGet;\r
12528 \r
12529 },{"./toObject":137}],80:[function(require,module,exports){\r
12530 var indexOfNaN = require('./indexOfNaN');\r
12531 \r
12532 /**\r
12533  * The base implementation of `_.indexOf` without support for binary searches.\r
12534  *\r
12535  * @private\r
12536  * @param {Array} array The array to search.\r
12537  * @param {*} value The value to search for.\r
12538  * @param {number} fromIndex The index to search from.\r
12539  * @returns {number} Returns the index of the matched value, else `-1`.\r
12540  */\r
12541 function baseIndexOf(array, value, fromIndex) {\r
12542   if (value !== value) {\r
12543     return indexOfNaN(array, fromIndex);\r
12544   }\r
12545   var index = fromIndex - 1,\r
12546       length = array.length;\r
12547 \r
12548   while (++index < length) {\r
12549     if (array[index] === value) {\r
12550       return index;\r
12551     }\r
12552   }\r
12553   return -1;\r
12554 }\r
12555 \r
12556 module.exports = baseIndexOf;\r
12557 \r
12558 },{"./indexOfNaN":117}],81:[function(require,module,exports){\r
12559 var baseIsEqualDeep = require('./baseIsEqualDeep'),\r
12560     isObject = require('../lang/isObject'),\r
12561     isObjectLike = require('./isObjectLike');\r
12562 \r
12563 /**\r
12564  * The base implementation of `_.isEqual` without support for `this` binding\r
12565  * `customizer` functions.\r
12566  *\r
12567  * @private\r
12568  * @param {*} value The value to compare.\r
12569  * @param {*} other The other value to compare.\r
12570  * @param {Function} [customizer] The function to customize comparing values.\r
12571  * @param {boolean} [isLoose] Specify performing partial comparisons.\r
12572  * @param {Array} [stackA] Tracks traversed `value` objects.\r
12573  * @param {Array} [stackB] Tracks traversed `other` objects.\r
12574  * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\r
12575  */\r
12576 function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) {\r
12577   if (value === other) {\r
12578     return true;\r
12579   }\r
12580   if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {\r
12581     return value !== value && other !== other;\r
12582   }\r
12583   return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB);\r
12584 }\r
12585 \r
12586 module.exports = baseIsEqual;\r
12587 \r
12588 },{"../lang/isObject":146,"./baseIsEqualDeep":82,"./isObjectLike":128}],82:[function(require,module,exports){\r
12589 var equalArrays = require('./equalArrays'),\r
12590     equalByTag = require('./equalByTag'),\r
12591     equalObjects = require('./equalObjects'),\r
12592     isArray = require('../lang/isArray'),\r
12593     isHostObject = require('./isHostObject'),\r
12594     isTypedArray = require('../lang/isTypedArray');\r
12595 \r
12596 /** `Object#toString` result references. */\r
12597 var argsTag = '[object Arguments]',\r
12598     arrayTag = '[object Array]',\r
12599     objectTag = '[object Object]';\r
12600 \r
12601 /** Used for native method references. */\r
12602 var objectProto = Object.prototype;\r
12603 \r
12604 /** Used to check objects for own properties. */\r
12605 var hasOwnProperty = objectProto.hasOwnProperty;\r
12606 \r
12607 /**\r
12608  * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\r
12609  * of values.\r
12610  */\r
12611 var objToString = objectProto.toString;\r
12612 \r
12613 /**\r
12614  * A specialized version of `baseIsEqual` for arrays and objects which performs\r
12615  * deep comparisons and tracks traversed objects enabling objects with circular\r
12616  * references to be compared.\r
12617  *\r
12618  * @private\r
12619  * @param {Object} object The object to compare.\r
12620  * @param {Object} other The other object to compare.\r
12621  * @param {Function} equalFunc The function to determine equivalents of values.\r
12622  * @param {Function} [customizer] The function to customize comparing objects.\r
12623  * @param {boolean} [isLoose] Specify performing partial comparisons.\r
12624  * @param {Array} [stackA=[]] Tracks traversed `value` objects.\r
12625  * @param {Array} [stackB=[]] Tracks traversed `other` objects.\r
12626  * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\r
12627  */\r
12628 function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) {\r
12629   var objIsArr = isArray(object),\r
12630       othIsArr = isArray(other),\r
12631       objTag = arrayTag,\r
12632       othTag = arrayTag;\r
12633 \r
12634   if (!objIsArr) {\r
12635     objTag = objToString.call(object);\r
12636     if (objTag == argsTag) {\r
12637       objTag = objectTag;\r
12638     } else if (objTag != objectTag) {\r
12639       objIsArr = isTypedArray(object);\r
12640     }\r
12641   }\r
12642   if (!othIsArr) {\r
12643     othTag = objToString.call(other);\r
12644     if (othTag == argsTag) {\r
12645       othTag = objectTag;\r
12646     } else if (othTag != objectTag) {\r
12647       othIsArr = isTypedArray(other);\r
12648     }\r
12649   }\r
12650   var objIsObj = objTag == objectTag && !isHostObject(object),\r
12651       othIsObj = othTag == objectTag && !isHostObject(other),\r
12652       isSameTag = objTag == othTag;\r
12653 \r
12654   if (isSameTag && !(objIsArr || objIsObj)) {\r
12655     return equalByTag(object, other, objTag);\r
12656   }\r
12657   if (!isLoose) {\r
12658     var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),\r
12659         othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');\r
12660 \r
12661     if (objIsWrapped || othIsWrapped) {\r
12662       return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB);\r
12663     }\r
12664   }\r
12665   if (!isSameTag) {\r
12666     return false;\r
12667   }\r
12668   // Assume cyclic values are equal.\r
12669   // For more information on detecting circular references see https://es5.github.io/#JO.\r
12670   stackA || (stackA = []);\r
12671   stackB || (stackB = []);\r
12672 \r
12673   var length = stackA.length;\r
12674   while (length--) {\r
12675     if (stackA[length] == object) {\r
12676       return stackB[length] == other;\r
12677     }\r
12678   }\r
12679   // Add `object` and `other` to the stack of traversed objects.\r
12680   stackA.push(object);\r
12681   stackB.push(other);\r
12682 \r
12683   var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB);\r
12684 \r
12685   stackA.pop();\r
12686   stackB.pop();\r
12687 \r
12688   return result;\r
12689 }\r
12690 \r
12691 module.exports = baseIsEqualDeep;\r
12692 \r
12693 },{"../lang/isArray":142,"../lang/isTypedArray":149,"./equalArrays":109,"./equalByTag":110,"./equalObjects":111,"./isHostObject":122}],83:[function(require,module,exports){\r
12694 var baseIsEqual = require('./baseIsEqual'),\r
12695     toObject = require('./toObject');\r
12696 \r
12697 /**\r
12698  * The base implementation of `_.isMatch` without support for callback\r
12699  * shorthands and `this` binding.\r
12700  *\r
12701  * @private\r
12702  * @param {Object} object The object to inspect.\r
12703  * @param {Array} matchData The propery names, values, and compare flags to match.\r
12704  * @param {Function} [customizer] The function to customize comparing objects.\r
12705  * @returns {boolean} Returns `true` if `object` is a match, else `false`.\r
12706  */\r
12707 function baseIsMatch(object, matchData, customizer) {\r
12708   var index = matchData.length,\r
12709       length = index,\r
12710       noCustomizer = !customizer;\r
12711 \r
12712   if (object == null) {\r
12713     return !length;\r
12714   }\r
12715   object = toObject(object);\r
12716   while (index--) {\r
12717     var data = matchData[index];\r
12718     if ((noCustomizer && data[2])\r
12719           ? data[1] !== object[data[0]]\r
12720           : !(data[0] in object)\r
12721         ) {\r
12722       return false;\r
12723     }\r
12724   }\r
12725   while (++index < length) {\r
12726     data = matchData[index];\r
12727     var key = data[0],\r
12728         objValue = object[key],\r
12729         srcValue = data[1];\r
12730 \r
12731     if (noCustomizer && data[2]) {\r
12732       if (objValue === undefined && !(key in object)) {\r
12733         return false;\r
12734       }\r
12735     } else {\r
12736       var result = customizer ? customizer(objValue, srcValue, key) : undefined;\r
12737       if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) {\r
12738         return false;\r
12739       }\r
12740     }\r
12741   }\r
12742   return true;\r
12743 }\r
12744 \r
12745 module.exports = baseIsMatch;\r
12746 \r
12747 },{"./baseIsEqual":81,"./toObject":137}],84:[function(require,module,exports){\r
12748 /**\r
12749  * The function whose prototype all chaining wrappers inherit from.\r
12750  *\r
12751  * @private\r
12752  */\r
12753 function baseLodash() {\r
12754   // No operation performed.\r
12755 }\r
12756 \r
12757 module.exports = baseLodash;\r
12758 \r
12759 },{}],85:[function(require,module,exports){\r
12760 var baseEach = require('./baseEach'),\r
12761     isArrayLike = require('./isArrayLike');\r
12762 \r
12763 /**\r
12764  * The base implementation of `_.map` without support for callback shorthands\r
12765  * and `this` binding.\r
12766  *\r
12767  * @private\r
12768  * @param {Array|Object|string} collection The collection to iterate over.\r
12769  * @param {Function} iteratee The function invoked per iteration.\r
12770  * @returns {Array} Returns the new mapped array.\r
12771  */\r
12772 function baseMap(collection, iteratee) {\r
12773   var index = -1,\r
12774       result = isArrayLike(collection) ? Array(collection.length) : [];\r
12775 \r
12776   baseEach(collection, function(value, key, collection) {\r
12777     result[++index] = iteratee(value, key, collection);\r
12778   });\r
12779   return result;\r
12780 }\r
12781 \r
12782 module.exports = baseMap;\r
12783 \r
12784 },{"./baseEach":73,"./isArrayLike":121}],86:[function(require,module,exports){\r
12785 var baseIsMatch = require('./baseIsMatch'),\r
12786     getMatchData = require('./getMatchData'),\r
12787     toObject = require('./toObject');\r
12788 \r
12789 /**\r
12790  * The base implementation of `_.matches` which does not clone `source`.\r
12791  *\r
12792  * @private\r
12793  * @param {Object} source The object of property values to match.\r
12794  * @returns {Function} Returns the new function.\r
12795  */\r
12796 function baseMatches(source) {\r
12797   var matchData = getMatchData(source);\r
12798   if (matchData.length == 1 && matchData[0][2]) {\r
12799     var key = matchData[0][0],\r
12800         value = matchData[0][1];\r
12801 \r
12802     return function(object) {\r
12803       if (object == null) {\r
12804         return false;\r
12805       }\r
12806       object = toObject(object);\r
12807       return object[key] === value && (value !== undefined || (key in object));\r
12808     };\r
12809   }\r
12810   return function(object) {\r
12811     return baseIsMatch(object, matchData);\r
12812   };\r
12813 }\r
12814 \r
12815 module.exports = baseMatches;\r
12816 \r
12817 },{"./baseIsMatch":83,"./getMatchData":115,"./toObject":137}],87:[function(require,module,exports){\r
12818 var baseGet = require('./baseGet'),\r
12819     baseIsEqual = require('./baseIsEqual'),\r
12820     baseSlice = require('./baseSlice'),\r
12821     isArray = require('../lang/isArray'),\r
12822     isKey = require('./isKey'),\r
12823     isStrictComparable = require('./isStrictComparable'),\r
12824     last = require('../array/last'),\r
12825     toObject = require('./toObject'),\r
12826     toPath = require('./toPath');\r
12827 \r
12828 /**\r
12829  * The base implementation of `_.matchesProperty` which does not clone `srcValue`.\r
12830  *\r
12831  * @private\r
12832  * @param {string} path The path of the property to get.\r
12833  * @param {*} srcValue The value to compare.\r
12834  * @returns {Function} Returns the new function.\r
12835  */\r
12836 function baseMatchesProperty(path, srcValue) {\r
12837   var isArr = isArray(path),\r
12838       isCommon = isKey(path) && isStrictComparable(srcValue),\r
12839       pathKey = (path + '');\r
12840 \r
12841   path = toPath(path);\r
12842   return function(object) {\r
12843     if (object == null) {\r
12844       return false;\r
12845     }\r
12846     var key = pathKey;\r
12847     object = toObject(object);\r
12848     if ((isArr || !isCommon) && !(key in object)) {\r
12849       object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));\r
12850       if (object == null) {\r
12851         return false;\r
12852       }\r
12853       key = last(path);\r
12854       object = toObject(object);\r
12855     }\r
12856     return object[key] === srcValue\r
12857       ? (srcValue !== undefined || (key in object))\r
12858       : baseIsEqual(srcValue, object[key], undefined, true);\r
12859   };\r
12860 }\r
12861 \r
12862 module.exports = baseMatchesProperty;\r
12863 \r
12864 },{"../array/last":52,"../lang/isArray":142,"./baseGet":79,"./baseIsEqual":81,"./baseSlice":91,"./isKey":125,"./isStrictComparable":129,"./toObject":137,"./toPath":138}],88:[function(require,module,exports){\r
12865 var toObject = require('./toObject');\r
12866 \r
12867 /**\r
12868  * The base implementation of `_.property` without support for deep paths.\r
12869  *\r
12870  * @private\r
12871  * @param {string} key The key of the property to get.\r
12872  * @returns {Function} Returns the new function.\r
12873  */\r
12874 function baseProperty(key) {\r
12875   return function(object) {\r
12876     return object == null ? undefined : toObject(object)[key];\r
12877   };\r
12878 }\r
12879 \r
12880 module.exports = baseProperty;\r
12881 \r
12882 },{"./toObject":137}],89:[function(require,module,exports){\r
12883 var baseGet = require('./baseGet'),\r
12884     toPath = require('./toPath');\r
12885 \r
12886 /**\r
12887  * A specialized version of `baseProperty` which supports deep paths.\r
12888  *\r
12889  * @private\r
12890  * @param {Array|string} path The path of the property to get.\r
12891  * @returns {Function} Returns the new function.\r
12892  */\r
12893 function basePropertyDeep(path) {\r
12894   var pathKey = (path + '');\r
12895   path = toPath(path);\r
12896   return function(object) {\r
12897     return baseGet(object, path, pathKey);\r
12898   };\r
12899 }\r
12900 \r
12901 module.exports = basePropertyDeep;\r
12902 \r
12903 },{"./baseGet":79,"./toPath":138}],90:[function(require,module,exports){\r
12904 var identity = require('../utility/identity'),\r
12905     metaMap = require('./metaMap');\r
12906 \r
12907 /**\r
12908  * The base implementation of `setData` without support for hot loop detection.\r
12909  *\r
12910  * @private\r
12911  * @param {Function} func The function to associate metadata with.\r
12912  * @param {*} data The metadata.\r
12913  * @returns {Function} Returns `func`.\r
12914  */\r
12915 var baseSetData = !metaMap ? identity : function(func, data) {\r
12916   metaMap.set(func, data);\r
12917   return func;\r
12918 };\r
12919 \r
12920 module.exports = baseSetData;\r
12921 \r
12922 },{"../utility/identity":156,"./metaMap":131}],91:[function(require,module,exports){\r
12923 /**\r
12924  * The base implementation of `_.slice` without an iteratee call guard.\r
12925  *\r
12926  * @private\r
12927  * @param {Array} array The array to slice.\r
12928  * @param {number} [start=0] The start position.\r
12929  * @param {number} [end=array.length] The end position.\r
12930  * @returns {Array} Returns the slice of `array`.\r
12931  */\r
12932 function baseSlice(array, start, end) {\r
12933   var index = -1,\r
12934       length = array.length;\r
12935 \r
12936   start = start == null ? 0 : (+start || 0);\r
12937   if (start < 0) {\r
12938     start = -start > length ? 0 : (length + start);\r
12939   }\r
12940   end = (end === undefined || end > length) ? length : (+end || 0);\r
12941   if (end < 0) {\r
12942     end += length;\r
12943   }\r
12944   length = start > end ? 0 : ((end - start) >>> 0);\r
12945   start >>>= 0;\r
12946 \r
12947   var result = Array(length);\r
12948   while (++index < length) {\r
12949     result[index] = array[index + start];\r
12950   }\r
12951   return result;\r
12952 }\r
12953 \r
12954 module.exports = baseSlice;\r
12955 \r
12956 },{}],92:[function(require,module,exports){\r
12957 /**\r
12958  * Converts `value` to a string if it's not one. An empty string is returned\r
12959  * for `null` or `undefined` values.\r
12960  *\r
12961  * @private\r
12962  * @param {*} value The value to process.\r
12963  * @returns {string} Returns the string.\r
12964  */\r
12965 function baseToString(value) {\r
12966   return value == null ? '' : (value + '');\r
12967 }\r
12968 \r
12969 module.exports = baseToString;\r
12970 \r
12971 },{}],93:[function(require,module,exports){\r
12972 /**\r
12973  * The base implementation of `_.values` and `_.valuesIn` which creates an\r
12974  * array of `object` property values corresponding to the property names\r
12975  * of `props`.\r
12976  *\r
12977  * @private\r
12978  * @param {Object} object The object to query.\r
12979  * @param {Array} props The property names to get values for.\r
12980  * @returns {Object} Returns the array of property values.\r
12981  */\r
12982 function baseValues(object, props) {\r
12983   var index = -1,\r
12984       length = props.length,\r
12985       result = Array(length);\r
12986 \r
12987   while (++index < length) {\r
12988     result[index] = object[props[index]];\r
12989   }\r
12990   return result;\r
12991 }\r
12992 \r
12993 module.exports = baseValues;\r
12994 \r
12995 },{}],94:[function(require,module,exports){\r
12996 var binaryIndexBy = require('./binaryIndexBy'),\r
12997     identity = require('../utility/identity');\r
12998 \r
12999 /** Used as references for the maximum length and index of an array. */\r
13000 var MAX_ARRAY_LENGTH = 4294967295,\r
13001     HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;\r
13002 \r
13003 /**\r
13004  * Performs a binary search of `array` to determine the index at which `value`\r
13005  * should be inserted into `array` in order to maintain its sort order.\r
13006  *\r
13007  * @private\r
13008  * @param {Array} array The sorted array to inspect.\r
13009  * @param {*} value The value to evaluate.\r
13010  * @param {boolean} [retHighest] Specify returning the highest qualified index.\r
13011  * @returns {number} Returns the index at which `value` should be inserted\r
13012  *  into `array`.\r
13013  */\r
13014 function binaryIndex(array, value, retHighest) {\r
13015   var low = 0,\r
13016       high = array ? array.length : low;\r
13017 \r
13018   if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {\r
13019     while (low < high) {\r
13020       var mid = (low + high) >>> 1,\r
13021           computed = array[mid];\r
13022 \r
13023       if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) {\r
13024         low = mid + 1;\r
13025       } else {\r
13026         high = mid;\r
13027       }\r
13028     }\r
13029     return high;\r
13030   }\r
13031   return binaryIndexBy(array, value, identity, retHighest);\r
13032 }\r
13033 \r
13034 module.exports = binaryIndex;\r
13035 \r
13036 },{"../utility/identity":156,"./binaryIndexBy":95}],95:[function(require,module,exports){\r
13037 /* Native method references for those with the same name as other `lodash` methods. */\r
13038 var nativeFloor = Math.floor,\r
13039     nativeMin = Math.min;\r
13040 \r
13041 /** Used as references for the maximum length and index of an array. */\r
13042 var MAX_ARRAY_LENGTH = 4294967295,\r
13043     MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1;\r
13044 \r
13045 /**\r
13046  * This function is like `binaryIndex` except that it invokes `iteratee` for\r
13047  * `value` and each element of `array` to compute their sort ranking. The\r
13048  * iteratee is invoked with one argument; (value).\r
13049  *\r
13050  * @private\r
13051  * @param {Array} array The sorted array to inspect.\r
13052  * @param {*} value The value to evaluate.\r
13053  * @param {Function} iteratee The function invoked per iteration.\r
13054  * @param {boolean} [retHighest] Specify returning the highest qualified index.\r
13055  * @returns {number} Returns the index at which `value` should be inserted\r
13056  *  into `array`.\r
13057  */\r
13058 function binaryIndexBy(array, value, iteratee, retHighest) {\r
13059   value = iteratee(value);\r
13060 \r
13061   var low = 0,\r
13062       high = array ? array.length : 0,\r
13063       valIsNaN = value !== value,\r
13064       valIsNull = value === null,\r
13065       valIsUndef = value === undefined;\r
13066 \r
13067   while (low < high) {\r
13068     var mid = nativeFloor((low + high) / 2),\r
13069         computed = iteratee(array[mid]),\r
13070         isDef = computed !== undefined,\r
13071         isReflexive = computed === computed;\r
13072 \r
13073     if (valIsNaN) {\r
13074       var setLow = isReflexive || retHighest;\r
13075     } else if (valIsNull) {\r
13076       setLow = isReflexive && isDef && (retHighest || computed != null);\r
13077     } else if (valIsUndef) {\r
13078       setLow = isReflexive && (retHighest || isDef);\r
13079     } else if (computed == null) {\r
13080       setLow = false;\r
13081     } else {\r
13082       setLow = retHighest ? (computed <= value) : (computed < value);\r
13083     }\r
13084     if (setLow) {\r
13085       low = mid + 1;\r
13086     } else {\r
13087       high = mid;\r
13088     }\r
13089   }\r
13090   return nativeMin(high, MAX_ARRAY_INDEX);\r
13091 }\r
13092 \r
13093 module.exports = binaryIndexBy;\r
13094 \r
13095 },{}],96:[function(require,module,exports){\r
13096 var identity = require('../utility/identity');\r
13097 \r
13098 /**\r
13099  * A specialized version of `baseCallback` which only supports `this` binding\r
13100  * and specifying the number of arguments to provide to `func`.\r
13101  *\r
13102  * @private\r
13103  * @param {Function} func The function to bind.\r
13104  * @param {*} thisArg The `this` binding of `func`.\r
13105  * @param {number} [argCount] The number of arguments to provide to `func`.\r
13106  * @returns {Function} Returns the callback.\r
13107  */\r
13108 function bindCallback(func, thisArg, argCount) {\r
13109   if (typeof func != 'function') {\r
13110     return identity;\r
13111   }\r
13112   if (thisArg === undefined) {\r
13113     return func;\r
13114   }\r
13115   switch (argCount) {\r
13116     case 1: return function(value) {\r
13117       return func.call(thisArg, value);\r
13118     };\r
13119     case 3: return function(value, index, collection) {\r
13120       return func.call(thisArg, value, index, collection);\r
13121     };\r
13122     case 4: return function(accumulator, value, index, collection) {\r
13123       return func.call(thisArg, accumulator, value, index, collection);\r
13124     };\r
13125     case 5: return function(value, other, key, object, source) {\r
13126       return func.call(thisArg, value, other, key, object, source);\r
13127     };\r
13128   }\r
13129   return function() {\r
13130     return func.apply(thisArg, arguments);\r
13131   };\r
13132 }\r
13133 \r
13134 module.exports = bindCallback;\r
13135 \r
13136 },{"../utility/identity":156}],97:[function(require,module,exports){\r
13137 (function (global){\r
13138 /** Native method references. */\r
13139 var ArrayBuffer = global.ArrayBuffer,\r
13140     Uint8Array = global.Uint8Array;\r
13141 \r
13142 /**\r
13143  * Creates a clone of the given array buffer.\r
13144  *\r
13145  * @private\r
13146  * @param {ArrayBuffer} buffer The array buffer to clone.\r
13147  * @returns {ArrayBuffer} Returns the cloned array buffer.\r
13148  */\r
13149 function bufferClone(buffer) {\r
13150   var result = new ArrayBuffer(buffer.byteLength),\r
13151       view = new Uint8Array(result);\r
13152 \r
13153   view.set(new Uint8Array(buffer));\r
13154   return result;\r
13155 }\r
13156 \r
13157 module.exports = bufferClone;\r
13158 \r
13159 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})\r
13160 //# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2J1ZmZlckNsb25lLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIi8qKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgQXJyYXlCdWZmZXIgPSBnbG9iYWwuQXJyYXlCdWZmZXIsXG4gICAgVWludDhBcnJheSA9IGdsb2JhbC5VaW50OEFycmF5O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBjbG9uZSBvZiB0aGUgZ2l2ZW4gYXJyYXkgYnVmZmVyLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5QnVmZmVyfSBidWZmZXIgVGhlIGFycmF5IGJ1ZmZlciB0byBjbG9uZS5cbiAqIEByZXR1cm5zIHtBcnJheUJ1ZmZlcn0gUmV0dXJucyB0aGUgY2xvbmVkIGFycmF5IGJ1ZmZlci5cbiAqL1xuZnVuY3Rpb24gYnVmZmVyQ2xvbmUoYnVmZmVyKSB7XG4gIHZhciByZXN1bHQgPSBuZXcgQXJyYXlCdWZmZXIoYnVmZmVyLmJ5dGVMZW5ndGgpLFxuICAgICAgdmlldyA9IG5ldyBVaW50OEFycmF5KHJlc3VsdCk7XG5cbiAgdmlldy5zZXQobmV3IFVpbnQ4QXJyYXkoYnVmZmVyKSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYnVmZmVyQ2xvbmU7XG4iXX0=\r
13161 },{}],98:[function(require,module,exports){\r
13162 /* Native method references for those with the same name as other `lodash` methods. */\r
13163 var nativeMax = Math.max;\r
13164 \r
13165 /**\r
13166  * Creates an array that is the composition of partially applied arguments,\r
13167  * placeholders, and provided arguments into a single array of arguments.\r
13168  *\r
13169  * @private\r
13170  * @param {Array|Object} args The provided arguments.\r
13171  * @param {Array} partials The arguments to prepend to those provided.\r
13172  * @param {Array} holders The `partials` placeholder indexes.\r
13173  * @returns {Array} Returns the new array of composed arguments.\r
13174  */\r
13175 function composeArgs(args, partials, holders) {\r
13176   var holdersLength = holders.length,\r
13177       argsIndex = -1,\r
13178       argsLength = nativeMax(args.length - holdersLength, 0),\r
13179       leftIndex = -1,\r
13180       leftLength = partials.length,\r
13181       result = Array(leftLength + argsLength);\r
13182 \r
13183   while (++leftIndex < leftLength) {\r
13184     result[leftIndex] = partials[leftIndex];\r
13185   }\r
13186   while (++argsIndex < holdersLength) {\r
13187     result[holders[argsIndex]] = args[argsIndex];\r
13188   }\r
13189   while (argsLength--) {\r
13190     result[leftIndex++] = args[argsIndex++];\r
13191   }\r
13192   return result;\r
13193 }\r
13194 \r
13195 module.exports = composeArgs;\r
13196 \r
13197 },{}],99:[function(require,module,exports){\r
13198 /* Native method references for those with the same name as other `lodash` methods. */\r
13199 var nativeMax = Math.max;\r
13200 \r
13201 /**\r
13202  * This function is like `composeArgs` except that the arguments composition\r
13203  * is tailored for `_.partialRight`.\r
13204  *\r
13205  * @private\r
13206  * @param {Array|Object} args The provided arguments.\r
13207  * @param {Array} partials The arguments to append to those provided.\r
13208  * @param {Array} holders The `partials` placeholder indexes.\r
13209  * @returns {Array} Returns the new array of composed arguments.\r
13210  */\r
13211 function composeArgsRight(args, partials, holders) {\r
13212   var holdersIndex = -1,\r
13213       holdersLength = holders.length,\r
13214       argsIndex = -1,\r
13215       argsLength = nativeMax(args.length - holdersLength, 0),\r
13216       rightIndex = -1,\r
13217       rightLength = partials.length,\r
13218       result = Array(argsLength + rightLength);\r
13219 \r
13220   while (++argsIndex < argsLength) {\r
13221     result[argsIndex] = args[argsIndex];\r
13222   }\r
13223   var offset = argsIndex;\r
13224   while (++rightIndex < rightLength) {\r
13225     result[offset + rightIndex] = partials[rightIndex];\r
13226   }\r
13227   while (++holdersIndex < holdersLength) {\r
13228     result[offset + holders[holdersIndex]] = args[argsIndex++];\r
13229   }\r
13230   return result;\r
13231 }\r
13232 \r
13233 module.exports = composeArgsRight;\r
13234 \r
13235 },{}],100:[function(require,module,exports){\r
13236 var getLength = require('./getLength'),\r
13237     isLength = require('./isLength'),\r
13238     toObject = require('./toObject');\r
13239 \r
13240 /**\r
13241  * Creates a `baseEach` or `baseEachRight` function.\r
13242  *\r
13243  * @private\r
13244  * @param {Function} eachFunc The function to iterate over a collection.\r
13245  * @param {boolean} [fromRight] Specify iterating from right to left.\r
13246  * @returns {Function} Returns the new base function.\r
13247  */\r
13248 function createBaseEach(eachFunc, fromRight) {\r
13249   return function(collection, iteratee) {\r
13250     var length = collection ? getLength(collection) : 0;\r
13251     if (!isLength(length)) {\r
13252       return eachFunc(collection, iteratee);\r
13253     }\r
13254     var index = fromRight ? length : -1,\r
13255         iterable = toObject(collection);\r
13256 \r
13257     while ((fromRight ? index-- : ++index < length)) {\r
13258       if (iteratee(iterable[index], index, iterable) === false) {\r
13259         break;\r
13260       }\r
13261     }\r
13262     return collection;\r
13263   };\r
13264 }\r
13265 \r
13266 module.exports = createBaseEach;\r
13267 \r
13268 },{"./getLength":114,"./isLength":127,"./toObject":137}],101:[function(require,module,exports){\r
13269 var toObject = require('./toObject');\r
13270 \r
13271 /**\r
13272  * Creates a base function for `_.forIn` or `_.forInRight`.\r
13273  *\r
13274  * @private\r
13275  * @param {boolean} [fromRight] Specify iterating from right to left.\r
13276  * @returns {Function} Returns the new base function.\r
13277  */\r
13278 function createBaseFor(fromRight) {\r
13279   return function(object, iteratee, keysFunc) {\r
13280     var iterable = toObject(object),\r
13281         props = keysFunc(object),\r
13282         length = props.length,\r
13283         index = fromRight ? length : -1;\r
13284 \r
13285     while ((fromRight ? index-- : ++index < length)) {\r
13286       var key = props[index];\r
13287       if (iteratee(iterable[key], key, iterable) === false) {\r
13288         break;\r
13289       }\r
13290     }\r
13291     return object;\r
13292   };\r
13293 }\r
13294 \r
13295 module.exports = createBaseFor;\r
13296 \r
13297 },{"./toObject":137}],102:[function(require,module,exports){\r
13298 (function (global){\r
13299 var createCtorWrapper = require('./createCtorWrapper');\r
13300 \r
13301 /**\r
13302  * Creates a function that wraps `func` and invokes it with the `this`\r
13303  * binding of `thisArg`.\r
13304  *\r
13305  * @private\r
13306  * @param {Function} func The function to bind.\r
13307  * @param {*} [thisArg] The `this` binding of `func`.\r
13308  * @returns {Function} Returns the new bound function.\r
13309  */\r
13310 function createBindWrapper(func, thisArg) {\r
13311   var Ctor = createCtorWrapper(func);\r
13312 \r
13313   function wrapper() {\r
13314     var fn = (this && this !== global && this instanceof wrapper) ? Ctor : func;\r
13315     return fn.apply(thisArg, arguments);\r
13316   }\r
13317   return wrapper;\r
13318 }\r
13319 \r
13320 module.exports = createBindWrapper;\r
13321 \r
13322 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})\r
13323 //# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NyZWF0ZUJpbmRXcmFwcGVyLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgY3JlYXRlQ3RvcldyYXBwZXIgPSByZXF1aXJlKCcuL2NyZWF0ZUN0b3JXcmFwcGVyJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYGZ1bmNgIGFuZCBpbnZva2VzIGl0IHdpdGggdGhlIGB0aGlzYFxuICogYmluZGluZyBvZiBgdGhpc0FyZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGJpbmQuXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYm91bmQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJpbmRXcmFwcGVyKGZ1bmMsIHRoaXNBcmcpIHtcbiAgdmFyIEN0b3IgPSBjcmVhdGVDdG9yV3JhcHBlcihmdW5jKTtcblxuICBmdW5jdGlvbiB3cmFwcGVyKCkge1xuICAgIHZhciBmbiA9ICh0aGlzICYmIHRoaXMgIT09IGdsb2JhbCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikgPyBDdG9yIDogZnVuYztcbiAgICByZXR1cm4gZm4uYXBwbHkodGhpc0FyZywgYXJndW1lbnRzKTtcbiAgfVxuICByZXR1cm4gd3JhcHBlcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVCaW5kV3JhcHBlcjtcbiJdfQ==\r
13324 },{"./createCtorWrapper":103}],103:[function(require,module,exports){\r
13325 var baseCreate = require('./baseCreate'),\r
13326     isObject = require('../lang/isObject');\r
13327 \r
13328 /**\r
13329  * Creates a function that produces an instance of `Ctor` regardless of\r
13330  * whether it was invoked as part of a `new` expression or by `call` or `apply`.\r
13331  *\r
13332  * @private\r
13333  * @param {Function} Ctor The constructor to wrap.\r
13334  * @returns {Function} Returns the new wrapped function.\r
13335  */\r
13336 function createCtorWrapper(Ctor) {\r
13337   return function() {\r
13338     // Use a `switch` statement to work with class constructors.\r
13339     // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist\r
13340     // for more details.\r
13341     var args = arguments;\r
13342     switch (args.length) {\r
13343       case 0: return new Ctor;\r
13344       case 1: return new Ctor(args[0]);\r
13345       case 2: return new Ctor(args[0], args[1]);\r
13346       case 3: return new Ctor(args[0], args[1], args[2]);\r
13347       case 4: return new Ctor(args[0], args[1], args[2], args[3]);\r
13348       case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);\r
13349       case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);\r
13350       case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);\r
13351     }\r
13352     var thisBinding = baseCreate(Ctor.prototype),\r
13353         result = Ctor.apply(thisBinding, args);\r
13354 \r
13355     // Mimic the constructor's `return` behavior.\r
13356     // See https://es5.github.io/#x13.2.2 for more details.\r
13357     return isObject(result) ? result : thisBinding;\r
13358   };\r
13359 }\r
13360 \r
13361 module.exports = createCtorWrapper;\r
13362 \r
13363 },{"../lang/isObject":146,"./baseCreate":72}],104:[function(require,module,exports){\r
13364 var baseCallback = require('./baseCallback'),\r
13365     baseFind = require('./baseFind'),\r
13366     baseFindIndex = require('./baseFindIndex'),\r
13367     isArray = require('../lang/isArray');\r
13368 \r
13369 /**\r
13370  * Creates a `_.find` or `_.findLast` function.\r
13371  *\r
13372  * @private\r
13373  * @param {Function} eachFunc The function to iterate over a collection.\r
13374  * @param {boolean} [fromRight] Specify iterating from right to left.\r
13375  * @returns {Function} Returns the new find function.\r
13376  */\r
13377 function createFind(eachFunc, fromRight) {\r
13378   return function(collection, predicate, thisArg) {\r
13379     predicate = baseCallback(predicate, thisArg, 3);\r
13380     if (isArray(collection)) {\r
13381       var index = baseFindIndex(collection, predicate, fromRight);\r
13382       return index > -1 ? collection[index] : undefined;\r
13383     }\r
13384     return baseFind(collection, predicate, eachFunc);\r
13385   };\r
13386 }\r
13387 \r
13388 module.exports = createFind;\r
13389 \r
13390 },{"../lang/isArray":142,"./baseCallback":69,"./baseFind":74,"./baseFindIndex":75}],105:[function(require,module,exports){\r
13391 var bindCallback = require('./bindCallback'),\r
13392     isArray = require('../lang/isArray');\r
13393 \r
13394 /**\r
13395  * Creates a function for `_.forEach` or `_.forEachRight`.\r
13396  *\r
13397  * @private\r
13398  * @param {Function} arrayFunc The function to iterate over an array.\r
13399  * @param {Function} eachFunc The function to iterate over a collection.\r
13400  * @returns {Function} Returns the new each function.\r
13401  */\r
13402 function createForEach(arrayFunc, eachFunc) {\r
13403   return function(collection, iteratee, thisArg) {\r
13404     return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection))\r
13405       ? arrayFunc(collection, iteratee)\r
13406       : eachFunc(collection, bindCallback(iteratee, thisArg, 3));\r
13407   };\r
13408 }\r
13409 \r
13410 module.exports = createForEach;\r
13411 \r
13412 },{"../lang/isArray":142,"./bindCallback":96}],106:[function(require,module,exports){\r
13413 (function (global){\r
13414 var arrayCopy = require('./arrayCopy'),\r
13415     composeArgs = require('./composeArgs'),\r
13416     composeArgsRight = require('./composeArgsRight'),\r
13417     createCtorWrapper = require('./createCtorWrapper'),\r
13418     isLaziable = require('./isLaziable'),\r
13419     reorder = require('./reorder'),\r
13420     replaceHolders = require('./replaceHolders'),\r
13421     setData = require('./setData');\r
13422 \r
13423 /** Used to compose bitmasks for wrapper metadata. */\r
13424 var BIND_FLAG = 1,\r
13425     BIND_KEY_FLAG = 2,\r
13426     CURRY_BOUND_FLAG = 4,\r
13427     CURRY_FLAG = 8,\r
13428     CURRY_RIGHT_FLAG = 16,\r
13429     PARTIAL_FLAG = 32,\r
13430     PARTIAL_RIGHT_FLAG = 64,\r
13431     ARY_FLAG = 128;\r
13432 \r
13433 /* Native method references for those with the same name as other `lodash` methods. */\r
13434 var nativeMax = Math.max;\r
13435 \r
13436 /**\r
13437  * Creates a function that wraps `func` and invokes it with optional `this`\r
13438  * binding of, partial application, and currying.\r
13439  *\r
13440  * @private\r
13441  * @param {Function|string} func The function or method name to reference.\r
13442  * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details.\r
13443  * @param {*} [thisArg] The `this` binding of `func`.\r
13444  * @param {Array} [partials] The arguments to prepend to those provided to the new function.\r
13445  * @param {Array} [holders] The `partials` placeholder indexes.\r
13446  * @param {Array} [partialsRight] The arguments to append to those provided to the new function.\r
13447  * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.\r
13448  * @param {Array} [argPos] The argument positions of the new function.\r
13449  * @param {number} [ary] The arity cap of `func`.\r
13450  * @param {number} [arity] The arity of `func`.\r
13451  * @returns {Function} Returns the new wrapped function.\r
13452  */\r
13453 function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {\r
13454   var isAry = bitmask & ARY_FLAG,\r
13455       isBind = bitmask & BIND_FLAG,\r
13456       isBindKey = bitmask & BIND_KEY_FLAG,\r
13457       isCurry = bitmask & CURRY_FLAG,\r
13458       isCurryBound = bitmask & CURRY_BOUND_FLAG,\r
13459       isCurryRight = bitmask & CURRY_RIGHT_FLAG,\r
13460       Ctor = isBindKey ? undefined : createCtorWrapper(func);\r
13461 \r
13462   function wrapper() {\r
13463     // Avoid `arguments` object use disqualifying optimizations by\r
13464     // converting it to an array before providing it to other functions.\r
13465     var length = arguments.length,\r
13466         index = length,\r
13467         args = Array(length);\r
13468 \r
13469     while (index--) {\r
13470       args[index] = arguments[index];\r
13471     }\r
13472     if (partials) {\r
13473       args = composeArgs(args, partials, holders);\r
13474     }\r
13475     if (partialsRight) {\r
13476       args = composeArgsRight(args, partialsRight, holdersRight);\r
13477     }\r
13478     if (isCurry || isCurryRight) {\r
13479       var placeholder = wrapper.placeholder,\r
13480           argsHolders = replaceHolders(args, placeholder);\r
13481 \r
13482       length -= argsHolders.length;\r
13483       if (length < arity) {\r
13484         var newArgPos = argPos ? arrayCopy(argPos) : undefined,\r
13485             newArity = nativeMax(arity - length, 0),\r
13486             newsHolders = isCurry ? argsHolders : undefined,\r
13487             newHoldersRight = isCurry ? undefined : argsHolders,\r
13488             newPartials = isCurry ? args : undefined,\r
13489             newPartialsRight = isCurry ? undefined : args;\r
13490 \r
13491         bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);\r
13492         bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);\r
13493 \r
13494         if (!isCurryBound) {\r
13495           bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);\r
13496         }\r
13497         var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity],\r
13498             result = createHybridWrapper.apply(undefined, newData);\r
13499 \r
13500         if (isLaziable(func)) {\r
13501           setData(result, newData);\r
13502         }\r
13503         result.placeholder = placeholder;\r
13504         return result;\r
13505       }\r
13506     }\r
13507     var thisBinding = isBind ? thisArg : this,\r
13508         fn = isBindKey ? thisBinding[func] : func;\r
13509 \r
13510     if (argPos) {\r
13511       args = reorder(args, argPos);\r
13512     }\r
13513     if (isAry && ary < args.length) {\r
13514       args.length = ary;\r
13515     }\r
13516     if (this && this !== global && this instanceof wrapper) {\r
13517       fn = Ctor || createCtorWrapper(func);\r
13518     }\r
13519     return fn.apply(thisBinding, args);\r
13520   }\r
13521   return wrapper;\r
13522 }\r
13523 \r
13524 module.exports = createHybridWrapper;\r
13525 \r
13526 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})\r
13527 //# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NyZWF0ZUh5YnJpZFdyYXBwZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgYXJyYXlDb3B5ID0gcmVxdWlyZSgnLi9hcnJheUNvcHknKSxcbiAgICBjb21wb3NlQXJncyA9IHJlcXVpcmUoJy4vY29tcG9zZUFyZ3MnKSxcbiAgICBjb21wb3NlQXJnc1JpZ2h0ID0gcmVxdWlyZSgnLi9jb21wb3NlQXJnc1JpZ2h0JyksXG4gICAgY3JlYXRlQ3RvcldyYXBwZXIgPSByZXF1aXJlKCcuL2NyZWF0ZUN0b3JXcmFwcGVyJyksXG4gICAgaXNMYXppYWJsZSA9IHJlcXVpcmUoJy4vaXNMYXppYWJsZScpLFxuICAgIHJlb3JkZXIgPSByZXF1aXJlKCcuL3Jlb3JkZXInKSxcbiAgICByZXBsYWNlSG9sZGVycyA9IHJlcXVpcmUoJy4vcmVwbGFjZUhvbGRlcnMnKSxcbiAgICBzZXREYXRhID0gcmVxdWlyZSgnLi9zZXREYXRhJyk7XG5cbi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHdyYXBwZXIgbWV0YWRhdGEuICovXG52YXIgQklORF9GTEFHID0gMSxcbiAgICBCSU5EX0tFWV9GTEFHID0gMixcbiAgICBDVVJSWV9CT1VORF9GTEFHID0gNCxcbiAgICBDVVJSWV9GTEFHID0gOCxcbiAgICBDVVJSWV9SSUdIVF9GTEFHID0gMTYsXG4gICAgUEFSVElBTF9GTEFHID0gMzIsXG4gICAgUEFSVElBTF9SSUdIVF9GTEFHID0gNjQsXG4gICAgQVJZX0ZMQUcgPSAxMjg7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlTWF4ID0gTWF0aC5tYXg7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYGZ1bmNgIGFuZCBpbnZva2VzIGl0IHdpdGggb3B0aW9uYWwgYHRoaXNgXG4gKiBiaW5kaW5nIG9mLCBwYXJ0aWFsIGFwcGxpY2F0aW9uLCBhbmQgY3VycnlpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb258c3RyaW5nfSBmdW5jIFRoZSBmdW5jdGlvbiBvciBtZXRob2QgbmFtZSB0byByZWZlcmVuY2UuXG4gKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBvZiBmbGFncy4gU2VlIGBjcmVhdGVXcmFwcGVyYCBmb3IgbW9yZSBkZXRhaWxzLlxuICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7QXJyYXl9IFtwYXJ0aWFsc10gVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkIHRvIHRoZSBuZXcgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge0FycmF5fSBbaG9sZGVyc10gVGhlIGBwYXJ0aWFsc2AgcGxhY2Vob2xkZXIgaW5kZXhlcy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtwYXJ0aWFsc1JpZ2h0XSBUaGUgYXJndW1lbnRzIHRvIGFwcGVuZCB0byB0aG9zZSBwcm92aWRlZCB0byB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNSaWdodF0gVGhlIGBwYXJ0aWFsc1JpZ2h0YCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICogQHBhcmFtIHtBcnJheX0gW2FyZ1Bvc10gVGhlIGFyZ3VtZW50IHBvc2l0aW9ucyBvZiB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHBhcmFtIHtudW1iZXJ9IFthcnldIFRoZSBhcml0eSBjYXAgb2YgYGZ1bmNgLlxuICogQHBhcmFtIHtudW1iZXJ9IFthcml0eV0gVGhlIGFyaXR5IG9mIGBmdW5jYC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUh5YnJpZFdyYXBwZXIoZnVuYywgYml0bWFzaywgdGhpc0FyZywgcGFydGlhbHMsIGhvbGRlcnMsIHBhcnRpYWxzUmlnaHQsIGhvbGRlcnNSaWdodCwgYXJnUG9zLCBhcnksIGFyaXR5KSB7XG4gIHZhciBpc0FyeSA9IGJpdG1hc2sgJiBBUllfRkxBRyxcbiAgICAgIGlzQmluZCA9IGJpdG1hc2sgJiBCSU5EX0ZMQUcsXG4gICAgICBpc0JpbmRLZXkgPSBiaXRtYXNrICYgQklORF9LRVlfRkxBRyxcbiAgICAgIGlzQ3VycnkgPSBiaXRtYXNrICYgQ1VSUllfRkxBRyxcbiAgICAgIGlzQ3VycnlCb3VuZCA9IGJpdG1hc2sgJiBDVVJSWV9CT1VORF9GTEFHLFxuICAgICAgaXNDdXJyeVJpZ2h0ID0gYml0bWFzayAmIENVUlJZX1JJR0hUX0ZMQUcsXG4gICAgICBDdG9yID0gaXNCaW5kS2V5ID8gdW5kZWZpbmVkIDogY3JlYXRlQ3RvcldyYXBwZXIoZnVuYyk7XG5cbiAgZnVuY3Rpb24gd3JhcHBlcigpIHtcbiAgICAvLyBBdm9pZCBgYXJndW1lbnRzYCBvYmplY3QgdXNlIGRpc3F1YWxpZnlpbmcgb3B0aW1pemF0aW9ucyBieVxuICAgIC8vIGNvbnZlcnRpbmcgaXQgdG8gYW4gYXJyYXkgYmVmb3JlIHByb3ZpZGluZyBpdCB0byBvdGhlciBmdW5jdGlvbnMuXG4gICAgdmFyIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGgsXG4gICAgICAgIGluZGV4ID0gbGVuZ3RoLFxuICAgICAgICBhcmdzID0gQXJyYXkobGVuZ3RoKTtcblxuICAgIHdoaWxlIChpbmRleC0tKSB7XG4gICAgICBhcmdzW2luZGV4XSA9IGFyZ3VtZW50c1tpbmRleF07XG4gICAgfVxuICAgIGlmIChwYXJ0aWFscykge1xuICAgICAgYXJncyA9IGNvbXBvc2VBcmdzKGFyZ3MsIHBhcnRpYWxzLCBob2xkZXJzKTtcbiAgICB9XG4gICAgaWYgKHBhcnRpYWxzUmlnaHQpIHtcbiAgICAgIGFyZ3MgPSBjb21wb3NlQXJnc1JpZ2h0KGFyZ3MsIHBhcnRpYWxzUmlnaHQsIGhvbGRlcnNSaWdodCk7XG4gICAgfVxuICAgIGlmIChpc0N1cnJ5IHx8IGlzQ3VycnlSaWdodCkge1xuICAgICAgdmFyIHBsYWNlaG9sZGVyID0gd3JhcHBlci5wbGFjZWhvbGRlcixcbiAgICAgICAgICBhcmdzSG9sZGVycyA9IHJlcGxhY2VIb2xkZXJzKGFyZ3MsIHBsYWNlaG9sZGVyKTtcblxuICAgICAgbGVuZ3RoIC09IGFyZ3NIb2xkZXJzLmxlbmd0aDtcbiAgICAgIGlmIChsZW5ndGggPCBhcml0eSkge1xuICAgICAgICB2YXIgbmV3QXJnUG9zID0gYXJnUG9zID8gYXJyYXlDb3B5KGFyZ1BvcykgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBuZXdBcml0eSA9IG5hdGl2ZU1heChhcml0eSAtIGxlbmd0aCwgMCksXG4gICAgICAgICAgICBuZXdzSG9sZGVycyA9IGlzQ3VycnkgPyBhcmdzSG9sZGVycyA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIG5ld0hvbGRlcnNSaWdodCA9IGlzQ3VycnkgPyB1bmRlZmluZWQgOiBhcmdzSG9sZGVycyxcbiAgICAgICAgICAgIG5ld1BhcnRpYWxzID0gaXNDdXJyeSA/IGFyZ3MgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBuZXdQYXJ0aWFsc1JpZ2h0ID0gaXNDdXJyeSA/IHVuZGVmaW5lZCA6IGFyZ3M7XG5cbiAgICAgICAgYml0bWFzayB8PSAoaXNDdXJyeSA/IFBBUlRJQUxfRkxBRyA6IFBBUlRJQUxfUklHSFRfRkxBRyk7XG4gICAgICAgIGJpdG1hc2sgJj0gfihpc0N1cnJ5ID8gUEFSVElBTF9SSUdIVF9GTEFHIDogUEFSVElBTF9GTEFHKTtcblxuICAgICAgICBpZiAoIWlzQ3VycnlCb3VuZCkge1xuICAgICAgICAgIGJpdG1hc2sgJj0gfihCSU5EX0ZMQUcgfCBCSU5EX0tFWV9GTEFHKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbmV3RGF0YSA9IFtmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBuZXdQYXJ0aWFscywgbmV3c0hvbGRlcnMsIG5ld1BhcnRpYWxzUmlnaHQsIG5ld0hvbGRlcnNSaWdodCwgbmV3QXJnUG9zLCBhcnksIG5ld0FyaXR5XSxcbiAgICAgICAgICAgIHJlc3VsdCA9IGNyZWF0ZUh5YnJpZFdyYXBwZXIuYXBwbHkodW5kZWZpbmVkLCBuZXdEYXRhKTtcblxuICAgICAgICBpZiAoaXNMYXppYWJsZShmdW5jKSkge1xuICAgICAgICAgIHNldERhdGEocmVzdWx0LCBuZXdEYXRhKTtcbiAgICAgICAgfVxuICAgICAgICByZXN1bHQucGxhY2Vob2xkZXIgPSBwbGFjZWhvbGRlcjtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICB9XG4gICAgdmFyIHRoaXNCaW5kaW5nID0gaXNCaW5kID8gdGhpc0FyZyA6IHRoaXMsXG4gICAgICAgIGZuID0gaXNCaW5kS2V5ID8gdGhpc0JpbmRpbmdbZnVuY10gOiBmdW5jO1xuXG4gICAgaWYgKGFyZ1Bvcykge1xuICAgICAgYXJncyA9IHJlb3JkZXIoYXJncywgYXJnUG9zKTtcbiAgICB9XG4gICAgaWYgKGlzQXJ5ICYmIGFyeSA8IGFyZ3MubGVuZ3RoKSB7XG4gICAgICBhcmdzLmxlbmd0aCA9IGFyeTtcbiAgICB9XG4gICAgaWYgKHRoaXMgJiYgdGhpcyAhPT0gZ2xvYmFsICYmIHRoaXMgaW5zdGFuY2VvZiB3cmFwcGVyKSB7XG4gICAgICBmbiA9IEN0b3IgfHwgY3JlYXRlQ3RvcldyYXBwZXIoZnVuYyk7XG4gICAgfVxuICAgIHJldHVybiBmbi5hcHBseSh0aGlzQmluZGluZywgYXJncyk7XG4gIH1cbiAgcmV0dXJuIHdyYXBwZXI7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlSHlicmlkV3JhcHBlcjtcbiJdfQ==\r
13528 },{"./arrayCopy":64,"./composeArgs":98,"./composeArgsRight":99,"./createCtorWrapper":103,"./isLaziable":126,"./reorder":133,"./replaceHolders":134,"./setData":135}],107:[function(require,module,exports){\r
13529 (function (global){\r
13530 var createCtorWrapper = require('./createCtorWrapper');\r
13531 \r
13532 /** Used to compose bitmasks for wrapper metadata. */\r
13533 var BIND_FLAG = 1;\r
13534 \r
13535 /**\r
13536  * Creates a function that wraps `func` and invokes it with the optional `this`\r
13537  * binding of `thisArg` and the `partials` prepended to those provided to\r
13538  * the wrapper.\r
13539  *\r
13540  * @private\r
13541  * @param {Function} func The function to partially apply arguments to.\r
13542  * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details.\r
13543  * @param {*} thisArg The `this` binding of `func`.\r
13544  * @param {Array} partials The arguments to prepend to those provided to the new function.\r
13545  * @returns {Function} Returns the new bound function.\r
13546  */\r
13547 function createPartialWrapper(func, bitmask, thisArg, partials) {\r
13548   var isBind = bitmask & BIND_FLAG,\r
13549       Ctor = createCtorWrapper(func);\r
13550 \r
13551   function wrapper() {\r
13552     // Avoid `arguments` object use disqualifying optimizations by\r
13553     // converting it to an array before providing it `func`.\r
13554     var argsIndex = -1,\r
13555         argsLength = arguments.length,\r
13556         leftIndex = -1,\r
13557         leftLength = partials.length,\r
13558         args = Array(leftLength + argsLength);\r
13559 \r
13560     while (++leftIndex < leftLength) {\r
13561       args[leftIndex] = partials[leftIndex];\r
13562     }\r
13563     while (argsLength--) {\r
13564       args[leftIndex++] = arguments[++argsIndex];\r
13565     }\r
13566     var fn = (this && this !== global && this instanceof wrapper) ? Ctor : func;\r
13567     return fn.apply(isBind ? thisArg : this, args);\r
13568   }\r
13569   return wrapper;\r
13570 }\r
13571 \r
13572 module.exports = createPartialWrapper;\r
13573 \r
13574 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})\r
13575 //# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NyZWF0ZVBhcnRpYWxXcmFwcGVyLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgY3JlYXRlQ3RvcldyYXBwZXIgPSByZXF1aXJlKCcuL2NyZWF0ZUN0b3JXcmFwcGVyJyk7XG5cbi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHdyYXBwZXIgbWV0YWRhdGEuICovXG52YXIgQklORF9GTEFHID0gMTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCB3cmFwcyBgZnVuY2AgYW5kIGludm9rZXMgaXQgd2l0aCB0aGUgb3B0aW9uYWwgYHRoaXNgXG4gKiBiaW5kaW5nIG9mIGB0aGlzQXJnYCBhbmQgdGhlIGBwYXJ0aWFsc2AgcHJlcGVuZGVkIHRvIHRob3NlIHByb3ZpZGVkIHRvXG4gKiB0aGUgd3JhcHBlci5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcGFydGlhbGx5IGFwcGx5IGFyZ3VtZW50cyB0by5cbiAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIG9mIGZsYWdzLiBTZWUgYGNyZWF0ZVdyYXBwZXJgIGZvciBtb3JlIGRldGFpbHMuXG4gKiBAcGFyYW0geyp9IHRoaXNBcmcgVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7QXJyYXl9IHBhcnRpYWxzIFRoZSBhcmd1bWVudHMgdG8gcHJlcGVuZCB0byB0aG9zZSBwcm92aWRlZCB0byB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYm91bmQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZVBhcnRpYWxXcmFwcGVyKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzKSB7XG4gIHZhciBpc0JpbmQgPSBiaXRtYXNrICYgQklORF9GTEFHLFxuICAgICAgQ3RvciA9IGNyZWF0ZUN0b3JXcmFwcGVyKGZ1bmMpO1xuXG4gIGZ1bmN0aW9uIHdyYXBwZXIoKSB7XG4gICAgLy8gQXZvaWQgYGFyZ3VtZW50c2Agb2JqZWN0IHVzZSBkaXNxdWFsaWZ5aW5nIG9wdGltaXphdGlvbnMgYnlcbiAgICAvLyBjb252ZXJ0aW5nIGl0IHRvIGFuIGFycmF5IGJlZm9yZSBwcm92aWRpbmcgaXQgYGZ1bmNgLlxuICAgIHZhciBhcmdzSW5kZXggPSAtMSxcbiAgICAgICAgYXJnc0xlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGgsXG4gICAgICAgIGxlZnRJbmRleCA9IC0xLFxuICAgICAgICBsZWZ0TGVuZ3RoID0gcGFydGlhbHMubGVuZ3RoLFxuICAgICAgICBhcmdzID0gQXJyYXkobGVmdExlbmd0aCArIGFyZ3NMZW5ndGgpO1xuXG4gICAgd2hpbGUgKCsrbGVmdEluZGV4IDwgbGVmdExlbmd0aCkge1xuICAgICAgYXJnc1tsZWZ0SW5kZXhdID0gcGFydGlhbHNbbGVmdEluZGV4XTtcbiAgICB9XG4gICAgd2hpbGUgKGFyZ3NMZW5ndGgtLSkge1xuICAgICAgYXJnc1tsZWZ0SW5kZXgrK10gPSBhcmd1bWVudHNbKythcmdzSW5kZXhdO1xuICAgIH1cbiAgICB2YXIgZm4gPSAodGhpcyAmJiB0aGlzICE9PSBnbG9iYWwgJiYgdGhpcyBpbnN0YW5jZW9mIHdyYXBwZXIpID8gQ3RvciA6IGZ1bmM7XG4gICAgcmV0dXJuIGZuLmFwcGx5KGlzQmluZCA/IHRoaXNBcmcgOiB0aGlzLCBhcmdzKTtcbiAgfVxuICByZXR1cm4gd3JhcHBlcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVQYXJ0aWFsV3JhcHBlcjtcbiJdfQ==\r
13576 },{"./createCtorWrapper":103}],108:[function(require,module,exports){\r
13577 var baseSetData = require('./baseSetData'),\r
13578     createBindWrapper = require('./createBindWrapper'),\r
13579     createHybridWrapper = require('./createHybridWrapper'),\r
13580     createPartialWrapper = require('./createPartialWrapper'),\r
13581     getData = require('./getData'),\r
13582     mergeData = require('./mergeData'),\r
13583     setData = require('./setData');\r
13584 \r
13585 /** Used to compose bitmasks for wrapper metadata. */\r
13586 var BIND_FLAG = 1,\r
13587     BIND_KEY_FLAG = 2,\r
13588     PARTIAL_FLAG = 32,\r
13589     PARTIAL_RIGHT_FLAG = 64;\r
13590 \r
13591 /** Used as the `TypeError` message for "Functions" methods. */\r
13592 var FUNC_ERROR_TEXT = 'Expected a function';\r
13593 \r
13594 /* Native method references for those with the same name as other `lodash` methods. */\r
13595 var nativeMax = Math.max;\r
13596 \r
13597 /**\r
13598  * Creates a function that either curries or invokes `func` with optional\r
13599  * `this` binding and partially applied arguments.\r
13600  *\r
13601  * @private\r
13602  * @param {Function|string} func The function or method name to reference.\r
13603  * @param {number} bitmask The bitmask of flags.\r
13604  *  The bitmask may be composed of the following flags:\r
13605  *     1 - `_.bind`\r
13606  *     2 - `_.bindKey`\r
13607  *     4 - `_.curry` or `_.curryRight` of a bound function\r
13608  *     8 - `_.curry`\r
13609  *    16 - `_.curryRight`\r
13610  *    32 - `_.partial`\r
13611  *    64 - `_.partialRight`\r
13612  *   128 - `_.rearg`\r
13613  *   256 - `_.ary`\r
13614  * @param {*} [thisArg] The `this` binding of `func`.\r
13615  * @param {Array} [partials] The arguments to be partially applied.\r
13616  * @param {Array} [holders] The `partials` placeholder indexes.\r
13617  * @param {Array} [argPos] The argument positions of the new function.\r
13618  * @param {number} [ary] The arity cap of `func`.\r
13619  * @param {number} [arity] The arity of `func`.\r
13620  * @returns {Function} Returns the new wrapped function.\r
13621  */\r
13622 function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {\r
13623   var isBindKey = bitmask & BIND_KEY_FLAG;\r
13624   if (!isBindKey && typeof func != 'function') {\r
13625     throw new TypeError(FUNC_ERROR_TEXT);\r
13626   }\r
13627   var length = partials ? partials.length : 0;\r
13628   if (!length) {\r
13629     bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);\r
13630     partials = holders = undefined;\r
13631   }\r
13632   length -= (holders ? holders.length : 0);\r
13633   if (bitmask & PARTIAL_RIGHT_FLAG) {\r
13634     var partialsRight = partials,\r
13635         holdersRight = holders;\r
13636 \r
13637     partials = holders = undefined;\r
13638   }\r
13639   var data = isBindKey ? undefined : getData(func),\r
13640       newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity];\r
13641 \r
13642   if (data) {\r
13643     mergeData(newData, data);\r
13644     bitmask = newData[1];\r
13645     arity = newData[9];\r
13646   }\r
13647   newData[9] = arity == null\r
13648     ? (isBindKey ? 0 : func.length)\r
13649     : (nativeMax(arity - length, 0) || 0);\r
13650 \r
13651   if (bitmask == BIND_FLAG) {\r
13652     var result = createBindWrapper(newData[0], newData[2]);\r
13653   } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) {\r
13654     result = createPartialWrapper.apply(undefined, newData);\r
13655   } else {\r
13656     result = createHybridWrapper.apply(undefined, newData);\r
13657   }\r
13658   var setter = data ? baseSetData : setData;\r
13659   return setter(result, newData);\r
13660 }\r
13661 \r
13662 module.exports = createWrapper;\r
13663 \r
13664 },{"./baseSetData":90,"./createBindWrapper":102,"./createHybridWrapper":106,"./createPartialWrapper":107,"./getData":112,"./mergeData":130,"./setData":135}],109:[function(require,module,exports){\r
13665 var arraySome = require('./arraySome');\r
13666 \r
13667 /**\r
13668  * A specialized version of `baseIsEqualDeep` for arrays with support for\r
13669  * partial deep comparisons.\r
13670  *\r
13671  * @private\r
13672  * @param {Array} array The array to compare.\r
13673  * @param {Array} other The other array to compare.\r
13674  * @param {Function} equalFunc The function to determine equivalents of values.\r
13675  * @param {Function} [customizer] The function to customize comparing arrays.\r
13676  * @param {boolean} [isLoose] Specify performing partial comparisons.\r
13677  * @param {Array} [stackA] Tracks traversed `value` objects.\r
13678  * @param {Array} [stackB] Tracks traversed `other` objects.\r
13679  * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.\r
13680  */\r
13681 function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) {\r
13682   var index = -1,\r
13683       arrLength = array.length,\r
13684       othLength = other.length;\r
13685 \r
13686   if (arrLength != othLength && !(isLoose && othLength > arrLength)) {\r
13687     return false;\r
13688   }\r
13689   // Ignore non-index properties.\r
13690   while (++index < arrLength) {\r
13691     var arrValue = array[index],\r
13692         othValue = other[index],\r
13693         result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined;\r
13694 \r
13695     if (result !== undefined) {\r
13696       if (result) {\r
13697         continue;\r
13698       }\r
13699       return false;\r
13700     }\r
13701     // Recursively compare arrays (susceptible to call stack limits).\r
13702     if (isLoose) {\r
13703       if (!arraySome(other, function(othValue) {\r
13704             return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB);\r
13705           })) {\r
13706         return false;\r
13707       }\r
13708     } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) {\r
13709       return false;\r
13710     }\r
13711   }\r
13712   return true;\r
13713 }\r
13714 \r
13715 module.exports = equalArrays;\r
13716 \r
13717 },{"./arraySome":67}],110:[function(require,module,exports){\r
13718 /** `Object#toString` result references. */\r
13719 var boolTag = '[object Boolean]',\r
13720     dateTag = '[object Date]',\r
13721     errorTag = '[object Error]',\r
13722     numberTag = '[object Number]',\r
13723     regexpTag = '[object RegExp]',\r
13724     stringTag = '[object String]';\r
13725 \r
13726 /**\r
13727  * A specialized version of `baseIsEqualDeep` for comparing objects of\r
13728  * the same `toStringTag`.\r
13729  *\r
13730  * **Note:** This function only supports comparing values with tags of\r
13731  * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\r
13732  *\r
13733  * @private\r
13734  * @param {Object} object The object to compare.\r
13735  * @param {Object} other The other object to compare.\r
13736  * @param {string} tag The `toStringTag` of the objects to compare.\r
13737  * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\r
13738  */\r
13739 function equalByTag(object, other, tag) {\r
13740   switch (tag) {\r
13741     case boolTag:\r
13742     case dateTag:\r
13743       // Coerce dates and booleans to numbers, dates to milliseconds and booleans\r
13744       // to `1` or `0` treating invalid dates coerced to `NaN` as not equal.\r
13745       return +object == +other;\r
13746 \r
13747     case errorTag:\r
13748       return object.name == other.name && object.message == other.message;\r
13749 \r
13750     case numberTag:\r
13751       // Treat `NaN` vs. `NaN` as equal.\r
13752       return (object != +object)\r
13753         ? other != +other\r
13754         : object == +other;\r
13755 \r
13756     case regexpTag:\r
13757     case stringTag:\r
13758       // Coerce regexes to strings and treat strings primitives and string\r
13759       // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details.\r
13760       return object == (other + '');\r
13761   }\r
13762   return false;\r
13763 }\r
13764 \r
13765 module.exports = equalByTag;\r
13766 \r
13767 },{}],111:[function(require,module,exports){\r
13768 var keys = require('../object/keys');\r
13769 \r
13770 /** Used for native method references. */\r
13771 var objectProto = Object.prototype;\r
13772 \r
13773 /** Used to check objects for own properties. */\r
13774 var hasOwnProperty = objectProto.hasOwnProperty;\r
13775 \r
13776 /**\r
13777  * A specialized version of `baseIsEqualDeep` for objects with support for\r
13778  * partial deep comparisons.\r
13779  *\r
13780  * @private\r
13781  * @param {Object} object The object to compare.\r
13782  * @param {Object} other The other object to compare.\r
13783  * @param {Function} equalFunc The function to determine equivalents of values.\r
13784  * @param {Function} [customizer] The function to customize comparing values.\r
13785  * @param {boolean} [isLoose] Specify performing partial comparisons.\r
13786  * @param {Array} [stackA] Tracks traversed `value` objects.\r
13787  * @param {Array} [stackB] Tracks traversed `other` objects.\r
13788  * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\r
13789  */\r
13790 function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) {\r
13791   var objProps = keys(object),\r
13792       objLength = objProps.length,\r
13793       othProps = keys(other),\r
13794       othLength = othProps.length;\r
13795 \r
13796   if (objLength != othLength && !isLoose) {\r
13797     return false;\r
13798   }\r
13799   var index = objLength;\r
13800   while (index--) {\r
13801     var key = objProps[index];\r
13802     if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) {\r
13803       return false;\r
13804     }\r
13805   }\r
13806   var skipCtor = isLoose;\r
13807   while (++index < objLength) {\r
13808     key = objProps[index];\r
13809     var objValue = object[key],\r
13810         othValue = other[key],\r
13811         result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined;\r
13812 \r
13813     // Recursively compare objects (susceptible to call stack limits).\r
13814     if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) {\r
13815       return false;\r
13816     }\r
13817     skipCtor || (skipCtor = key == 'constructor');\r
13818   }\r
13819   if (!skipCtor) {\r
13820     var objCtor = object.constructor,\r
13821         othCtor = other.constructor;\r
13822 \r
13823     // Non `Object` object instances with different constructors are not equal.\r
13824     if (objCtor != othCtor &&\r
13825         ('constructor' in object && 'constructor' in other) &&\r
13826         !(typeof objCtor == 'function' && objCtor instanceof objCtor &&\r
13827           typeof othCtor == 'function' && othCtor instanceof othCtor)) {\r
13828       return false;\r
13829     }\r
13830   }\r
13831   return true;\r
13832 }\r
13833 \r
13834 module.exports = equalObjects;\r
13835 \r
13836 },{"../object/keys":151}],112:[function(require,module,exports){\r
13837 var metaMap = require('./metaMap'),\r
13838     noop = require('../utility/noop');\r
13839 \r
13840 /**\r
13841  * Gets metadata for `func`.\r
13842  *\r
13843  * @private\r
13844  * @param {Function} func The function to query.\r
13845  * @returns {*} Returns the metadata for `func`.\r
13846  */\r
13847 var getData = !metaMap ? noop : function(func) {\r
13848   return metaMap.get(func);\r
13849 };\r
13850 \r
13851 module.exports = getData;\r
13852 \r
13853 },{"../utility/noop":157,"./metaMap":131}],113:[function(require,module,exports){\r
13854 var realNames = require('./realNames');\r
13855 \r
13856 /**\r
13857  * Gets the name of `func`.\r
13858  *\r
13859  * @private\r
13860  * @param {Function} func The function to query.\r
13861  * @returns {string} Returns the function name.\r
13862  */\r
13863 function getFuncName(func) {\r
13864   var result = (func.name + ''),\r
13865       array = realNames[result],\r
13866       length = array ? array.length : 0;\r
13867 \r
13868   while (length--) {\r
13869     var data = array[length],\r
13870         otherFunc = data.func;\r
13871     if (otherFunc == null || otherFunc == func) {\r
13872       return data.name;\r
13873     }\r
13874   }\r
13875   return result;\r
13876 }\r
13877 \r
13878 module.exports = getFuncName;\r
13879 \r
13880 },{"./realNames":132}],114:[function(require,module,exports){\r
13881 var baseProperty = require('./baseProperty');\r
13882 \r
13883 /**\r
13884  * Gets the "length" property value of `object`.\r
13885  *\r
13886  * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)\r
13887  * that affects Safari on at least iOS 8.1-8.3 ARM64.\r
13888  *\r
13889  * @private\r
13890  * @param {Object} object The object to query.\r
13891  * @returns {*} Returns the "length" value.\r
13892  */\r
13893 var getLength = baseProperty('length');\r
13894 \r
13895 module.exports = getLength;\r
13896 \r
13897 },{"./baseProperty":88}],115:[function(require,module,exports){\r
13898 var isStrictComparable = require('./isStrictComparable'),\r
13899     pairs = require('../object/pairs');\r
13900 \r
13901 /**\r
13902  * Gets the propery names, values, and compare flags of `object`.\r
13903  *\r
13904  * @private\r
13905  * @param {Object} object The object to query.\r
13906  * @returns {Array} Returns the match data of `object`.\r
13907  */\r
13908 function getMatchData(object) {\r
13909   var result = pairs(object),\r
13910       length = result.length;\r
13911 \r
13912   while (length--) {\r
13913     result[length][2] = isStrictComparable(result[length][1]);\r
13914   }\r
13915   return result;\r
13916 }\r
13917 \r
13918 module.exports = getMatchData;\r
13919 \r
13920 },{"../object/pairs":153,"./isStrictComparable":129}],116:[function(require,module,exports){\r
13921 var isNative = require('../lang/isNative');\r
13922 \r
13923 /**\r
13924  * Gets the native function at `key` of `object`.\r
13925  *\r
13926  * @private\r
13927  * @param {Object} object The object to query.\r
13928  * @param {string} key The key of the method to get.\r
13929  * @returns {*} Returns the function if it's native, else `undefined`.\r
13930  */\r
13931 function getNative(object, key) {\r
13932   var value = object == null ? undefined : object[key];\r
13933   return isNative(value) ? value : undefined;\r
13934 }\r
13935 \r
13936 module.exports = getNative;\r
13937 \r
13938 },{"../lang/isNative":145}],117:[function(require,module,exports){\r
13939 /**\r
13940  * Gets the index at which the first occurrence of `NaN` is found in `array`.\r
13941  *\r
13942  * @private\r
13943  * @param {Array} array The array to search.\r
13944  * @param {number} fromIndex The index to search from.\r
13945  * @param {boolean} [fromRight] Specify iterating from right to left.\r
13946  * @returns {number} Returns the index of the matched `NaN`, else `-1`.\r
13947  */\r
13948 function indexOfNaN(array, fromIndex, fromRight) {\r
13949   var length = array.length,\r
13950       index = fromIndex + (fromRight ? 0 : -1);\r
13951 \r
13952   while ((fromRight ? index-- : ++index < length)) {\r
13953     var other = array[index];\r
13954     if (other !== other) {\r
13955       return index;\r
13956     }\r
13957   }\r
13958   return -1;\r
13959 }\r
13960 \r
13961 module.exports = indexOfNaN;\r
13962 \r
13963 },{}],118:[function(require,module,exports){\r
13964 /** Used for native method references. */\r
13965 var objectProto = Object.prototype;\r
13966 \r
13967 /** Used to check objects for own properties. */\r
13968 var hasOwnProperty = objectProto.hasOwnProperty;\r
13969 \r
13970 /**\r
13971  * Initializes an array clone.\r
13972  *\r
13973  * @private\r
13974  * @param {Array} array The array to clone.\r
13975  * @returns {Array} Returns the initialized clone.\r
13976  */\r
13977 function initCloneArray(array) {\r
13978   var length = array.length,\r
13979       result = new array.constructor(length);\r
13980 \r
13981   // Add array properties assigned by `RegExp#exec`.\r
13982   if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {\r
13983     result.index = array.index;\r
13984     result.input = array.input;\r
13985   }\r
13986   return result;\r
13987 }\r
13988 \r
13989 module.exports = initCloneArray;\r
13990 \r
13991 },{}],119:[function(require,module,exports){\r
13992 (function (global){\r
13993 var bufferClone = require('./bufferClone');\r
13994 \r
13995 /** `Object#toString` result references. */\r
13996 var boolTag = '[object Boolean]',\r
13997     dateTag = '[object Date]',\r
13998     numberTag = '[object Number]',\r
13999     regexpTag = '[object RegExp]',\r
14000     stringTag = '[object String]';\r
14001 \r
14002 var arrayBufferTag = '[object ArrayBuffer]',\r
14003     float32Tag = '[object Float32Array]',\r
14004     float64Tag = '[object Float64Array]',\r
14005     int8Tag = '[object Int8Array]',\r
14006     int16Tag = '[object Int16Array]',\r
14007     int32Tag = '[object Int32Array]',\r
14008     uint8Tag = '[object Uint8Array]',\r
14009     uint8ClampedTag = '[object Uint8ClampedArray]',\r
14010     uint16Tag = '[object Uint16Array]',\r
14011     uint32Tag = '[object Uint32Array]';\r
14012 \r
14013 /** Used to match `RegExp` flags from their coerced string values. */\r
14014 var reFlags = /\w*$/;\r
14015 \r
14016 /** Native method references. */\r
14017 var Uint8Array = global.Uint8Array;\r
14018 \r
14019 /** Used to lookup a type array constructors by `toStringTag`. */\r
14020 var ctorByTag = {};\r
14021 ctorByTag[float32Tag] = global.Float32Array;\r
14022 ctorByTag[float64Tag] = global.Float64Array;\r
14023 ctorByTag[int8Tag] = global.Int8Array;\r
14024 ctorByTag[int16Tag] = global.Int16Array;\r
14025 ctorByTag[int32Tag] = global.Int32Array;\r
14026 ctorByTag[uint8Tag] = Uint8Array;\r
14027 ctorByTag[uint8ClampedTag] = global.Uint8ClampedArray;\r
14028 ctorByTag[uint16Tag] = global.Uint16Array;\r
14029 ctorByTag[uint32Tag] = global.Uint32Array;\r
14030 \r
14031 /**\r
14032  * Initializes an object clone based on its `toStringTag`.\r
14033  *\r
14034  * **Note:** This function only supports cloning values with tags of\r
14035  * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\r
14036  *\r
14037  * @private\r
14038  * @param {Object} object The object to clone.\r
14039  * @param {string} tag The `toStringTag` of the object to clone.\r
14040  * @param {boolean} [isDeep] Specify a deep clone.\r
14041  * @returns {Object} Returns the initialized clone.\r
14042  */\r
14043 function initCloneByTag(object, tag, isDeep) {\r
14044   var Ctor = object.constructor;\r
14045   switch (tag) {\r
14046     case arrayBufferTag:\r
14047       return bufferClone(object);\r
14048 \r
14049     case boolTag:\r
14050     case dateTag:\r
14051       return new Ctor(+object);\r
14052 \r
14053     case float32Tag: case float64Tag:\r
14054     case int8Tag: case int16Tag: case int32Tag:\r
14055     case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:\r
14056       // Safari 5 mobile incorrectly has `Object` as the constructor of typed arrays.\r
14057       if (Ctor instanceof Ctor) {\r
14058         Ctor = ctorByTag[tag];\r
14059       }\r
14060       var buffer = object.buffer;\r
14061       return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length);\r
14062 \r
14063     case numberTag:\r
14064     case stringTag:\r
14065       return new Ctor(object);\r
14066 \r
14067     case regexpTag:\r
14068       var result = new Ctor(object.source, reFlags.exec(object));\r
14069       result.lastIndex = object.lastIndex;\r
14070   }\r
14071   return result;\r
14072 }\r
14073 \r
14074 module.exports = initCloneByTag;\r
14075 \r
14076 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})\r
14077 //# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2luaXRDbG9uZUJ5VGFnLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgYnVmZmVyQ2xvbmUgPSByZXF1aXJlKCcuL2J1ZmZlckNsb25lJyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgbnVtYmVyVGFnID0gJ1tvYmplY3QgTnVtYmVyXScsXG4gICAgcmVnZXhwVGFnID0gJ1tvYmplY3QgUmVnRXhwXScsXG4gICAgc3RyaW5nVGFnID0gJ1tvYmplY3QgU3RyaW5nXSc7XG5cbnZhciBhcnJheUJ1ZmZlclRhZyA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsXG4gICAgZmxvYXQzMlRhZyA9ICdbb2JqZWN0IEZsb2F0MzJBcnJheV0nLFxuICAgIGZsb2F0NjRUYWcgPSAnW29iamVjdCBGbG9hdDY0QXJyYXldJyxcbiAgICBpbnQ4VGFnID0gJ1tvYmplY3QgSW50OEFycmF5XScsXG4gICAgaW50MTZUYWcgPSAnW29iamVjdCBJbnQxNkFycmF5XScsXG4gICAgaW50MzJUYWcgPSAnW29iamVjdCBJbnQzMkFycmF5XScsXG4gICAgdWludDhUYWcgPSAnW29iamVjdCBVaW50OEFycmF5XScsXG4gICAgdWludDhDbGFtcGVkVGFnID0gJ1tvYmplY3QgVWludDhDbGFtcGVkQXJyYXldJyxcbiAgICB1aW50MTZUYWcgPSAnW29iamVjdCBVaW50MTZBcnJheV0nLFxuICAgIHVpbnQzMlRhZyA9ICdbb2JqZWN0IFVpbnQzMkFycmF5XSc7XG5cbi8qKiBVc2VkIHRvIG1hdGNoIGBSZWdFeHBgIGZsYWdzIGZyb20gdGhlaXIgY29lcmNlZCBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlRmxhZ3MgPSAvXFx3KiQvO1xuXG4vKiogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIFVpbnQ4QXJyYXkgPSBnbG9iYWwuVWludDhBcnJheTtcblxuLyoqIFVzZWQgdG8gbG9va3VwIGEgdHlwZSBhcnJheSBjb25zdHJ1Y3RvcnMgYnkgYHRvU3RyaW5nVGFnYC4gKi9cbnZhciBjdG9yQnlUYWcgPSB7fTtcbmN0b3JCeVRhZ1tmbG9hdDMyVGFnXSA9IGdsb2JhbC5GbG9hdDMyQXJyYXk7XG5jdG9yQnlUYWdbZmxvYXQ2NFRhZ10gPSBnbG9iYWwuRmxvYXQ2NEFycmF5O1xuY3RvckJ5VGFnW2ludDhUYWddID0gZ2xvYmFsLkludDhBcnJheTtcbmN0b3JCeVRhZ1tpbnQxNlRhZ10gPSBnbG9iYWwuSW50MTZBcnJheTtcbmN0b3JCeVRhZ1tpbnQzMlRhZ10gPSBnbG9iYWwuSW50MzJBcnJheTtcbmN0b3JCeVRhZ1t1aW50OFRhZ10gPSBVaW50OEFycmF5O1xuY3RvckJ5VGFnW3VpbnQ4Q2xhbXBlZFRhZ10gPSBnbG9iYWwuVWludDhDbGFtcGVkQXJyYXk7XG5jdG9yQnlUYWdbdWludDE2VGFnXSA9IGdsb2JhbC5VaW50MTZBcnJheTtcbmN0b3JCeVRhZ1t1aW50MzJUYWddID0gZ2xvYmFsLlVpbnQzMkFycmF5O1xuXG4vKipcbiAqIEluaXRpYWxpemVzIGFuIG9iamVjdCBjbG9uZSBiYXNlZCBvbiBpdHMgYHRvU3RyaW5nVGFnYC5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBvbmx5IHN1cHBvcnRzIGNsb25pbmcgdmFsdWVzIHdpdGggdGFncyBvZlxuICogYEJvb2xlYW5gLCBgRGF0ZWAsIGBFcnJvcmAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgb3IgYFN0cmluZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjbG9uZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0YWcgVGhlIGB0b1N0cmluZ1RhZ2Agb2YgdGhlIG9iamVjdCB0byBjbG9uZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzRGVlcF0gU3BlY2lmeSBhIGRlZXAgY2xvbmUuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAqL1xuZnVuY3Rpb24gaW5pdENsb25lQnlUYWcob2JqZWN0LCB0YWcsIGlzRGVlcCkge1xuICB2YXIgQ3RvciA9IG9iamVjdC5jb25zdHJ1Y3RvcjtcbiAgc3dpdGNoICh0YWcpIHtcbiAgICBjYXNlIGFycmF5QnVmZmVyVGFnOlxuICAgICAgcmV0dXJuIGJ1ZmZlckNsb25lKG9iamVjdCk7XG5cbiAgICBjYXNlIGJvb2xUYWc6XG4gICAgY2FzZSBkYXRlVGFnOlxuICAgICAgcmV0dXJuIG5ldyBDdG9yKCtvYmplY3QpO1xuXG4gICAgY2FzZSBmbG9hdDMyVGFnOiBjYXNlIGZsb2F0NjRUYWc6XG4gICAgY2FzZSBpbnQ4VGFnOiBjYXNlIGludDE2VGFnOiBjYXNlIGludDMyVGFnOlxuICAgIGNhc2UgdWludDhUYWc6IGNhc2UgdWludDhDbGFtcGVkVGFnOiBjYXNlIHVpbnQxNlRhZzogY2FzZSB1aW50MzJUYWc6XG4gICAgICAvLyBTYWZhcmkgNSBtb2JpbGUgaW5jb3JyZWN0bHkgaGFzIGBPYmplY3RgIGFzIHRoZSBjb25zdHJ1Y3RvciBvZiB0eXBlZCBhcnJheXMuXG4gICAgICBpZiAoQ3RvciBpbnN0YW5jZW9mIEN0b3IpIHtcbiAgICAgICAgQ3RvciA9IGN0b3JCeVRhZ1t0YWddO1xuICAgICAgfVxuICAgICAgdmFyIGJ1ZmZlciA9IG9iamVjdC5idWZmZXI7XG4gICAgICByZXR1cm4gbmV3IEN0b3IoaXNEZWVwID8gYnVmZmVyQ2xvbmUoYnVmZmVyKSA6IGJ1ZmZlciwgb2JqZWN0LmJ5dGVPZmZzZXQsIG9iamVjdC5sZW5ndGgpO1xuXG4gICAgY2FzZSBudW1iZXJUYWc6XG4gICAgY2FzZSBzdHJpbmdUYWc6XG4gICAgICByZXR1cm4gbmV3IEN0b3Iob2JqZWN0KTtcblxuICAgIGNhc2UgcmVnZXhwVGFnOlxuICAgICAgdmFyIHJlc3VsdCA9IG5ldyBDdG9yKG9iamVjdC5zb3VyY2UsIHJlRmxhZ3MuZXhlYyhvYmplY3QpKTtcbiAgICAgIHJlc3VsdC5sYXN0SW5kZXggPSBvYmplY3QubGFzdEluZGV4O1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaW5pdENsb25lQnlUYWc7XG4iXX0=\r
14078 },{"./bufferClone":97}],120:[function(require,module,exports){\r
14079 /**\r
14080  * Initializes an object clone.\r
14081  *\r
14082  * @private\r
14083  * @param {Object} object The object to clone.\r
14084  * @returns {Object} Returns the initialized clone.\r
14085  */\r
14086 function initCloneObject(object) {\r
14087   var Ctor = object.constructor;\r
14088   if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) {\r
14089     Ctor = Object;\r
14090   }\r
14091   return new Ctor;\r
14092 }\r
14093 \r
14094 module.exports = initCloneObject;\r
14095 \r
14096 },{}],121:[function(require,module,exports){\r
14097 var getLength = require('./getLength'),\r
14098     isLength = require('./isLength');\r
14099 \r
14100 /**\r
14101  * Checks if `value` is array-like.\r
14102  *\r
14103  * @private\r
14104  * @param {*} value The value to check.\r
14105  * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\r
14106  */\r
14107 function isArrayLike(value) {\r
14108   return value != null && isLength(getLength(value));\r
14109 }\r
14110 \r
14111 module.exports = isArrayLike;\r
14112 \r
14113 },{"./getLength":114,"./isLength":127}],122:[function(require,module,exports){\r
14114 /**\r
14115  * Checks if `value` is a host object in IE < 9.\r
14116  *\r
14117  * @private\r
14118  * @param {*} value The value to check.\r
14119  * @returns {boolean} Returns `true` if `value` is a host object, else `false`.\r
14120  */\r
14121 var isHostObject = (function() {\r
14122   try {\r
14123     Object({ 'toString': 0 } + '');\r
14124   } catch(e) {\r
14125     return function() { return false; };\r
14126   }\r
14127   return function(value) {\r
14128     // IE < 9 presents many host objects as `Object` objects that can coerce\r
14129     // to strings despite having improperly defined `toString` methods.\r
14130     return typeof value.toString != 'function' && typeof (value + '') == 'string';\r
14131   };\r
14132 }());\r
14133 \r
14134 module.exports = isHostObject;\r
14135 \r
14136 },{}],123:[function(require,module,exports){\r
14137 /** Used to detect unsigned integer values. */\r
14138 var reIsUint = /^\d+$/;\r
14139 \r
14140 /**\r
14141  * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)\r
14142  * of an array-like value.\r
14143  */\r
14144 var MAX_SAFE_INTEGER = 9007199254740991;\r
14145 \r
14146 /**\r
14147  * Checks if `value` is a valid array-like index.\r
14148  *\r
14149  * @private\r
14150  * @param {*} value The value to check.\r
14151  * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\r
14152  * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\r
14153  */\r
14154 function isIndex(value, length) {\r
14155   value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;\r
14156   length = length == null ? MAX_SAFE_INTEGER : length;\r
14157   return value > -1 && value % 1 == 0 && value < length;\r
14158 }\r
14159 \r
14160 module.exports = isIndex;\r
14161 \r
14162 },{}],124:[function(require,module,exports){\r
14163 var isArrayLike = require('./isArrayLike'),\r
14164     isIndex = require('./isIndex'),\r
14165     isObject = require('../lang/isObject');\r
14166 \r
14167 /**\r
14168  * Checks if the provided arguments are from an iteratee call.\r
14169  *\r
14170  * @private\r
14171  * @param {*} value The potential iteratee value argument.\r
14172  * @param {*} index The potential iteratee index or key argument.\r
14173  * @param {*} object The potential iteratee object argument.\r
14174  * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.\r
14175  */\r
14176 function isIterateeCall(value, index, object) {\r
14177   if (!isObject(object)) {\r
14178     return false;\r
14179   }\r
14180   var type = typeof index;\r
14181   if (type == 'number'\r
14182       ? (isArrayLike(object) && isIndex(index, object.length))\r
14183       : (type == 'string' && index in object)) {\r
14184     var other = object[index];\r
14185     return value === value ? (value === other) : (other !== other);\r
14186   }\r
14187   return false;\r
14188 }\r
14189 \r
14190 module.exports = isIterateeCall;\r
14191 \r
14192 },{"../lang/isObject":146,"./isArrayLike":121,"./isIndex":123}],125:[function(require,module,exports){\r
14193 var isArray = require('../lang/isArray'),\r
14194     toObject = require('./toObject');\r
14195 \r
14196 /** Used to match property names within property paths. */\r
14197 var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,\r
14198     reIsPlainProp = /^\w*$/;\r
14199 \r
14200 /**\r
14201  * Checks if `value` is a property name and not a property path.\r
14202  *\r
14203  * @private\r
14204  * @param {*} value The value to check.\r
14205  * @param {Object} [object] The object to query keys on.\r
14206  * @returns {boolean} Returns `true` if `value` is a property name, else `false`.\r
14207  */\r
14208 function isKey(value, object) {\r
14209   var type = typeof value;\r
14210   if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') {\r
14211     return true;\r
14212   }\r
14213   if (isArray(value)) {\r
14214     return false;\r
14215   }\r
14216   var result = !reIsDeepProp.test(value);\r
14217   return result || (object != null && value in toObject(object));\r
14218 }\r
14219 \r
14220 module.exports = isKey;\r
14221 \r
14222 },{"../lang/isArray":142,"./toObject":137}],126:[function(require,module,exports){\r
14223 var LazyWrapper = require('./LazyWrapper'),\r
14224     getData = require('./getData'),\r
14225     getFuncName = require('./getFuncName'),\r
14226     lodash = require('../chain/lodash');\r
14227 \r
14228 /**\r
14229  * Checks if `func` has a lazy counterpart.\r
14230  *\r
14231  * @private\r
14232  * @param {Function} func The function to check.\r
14233  * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`.\r
14234  */\r
14235 function isLaziable(func) {\r
14236   var funcName = getFuncName(func),\r
14237       other = lodash[funcName];\r
14238 \r
14239   if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {\r
14240     return false;\r
14241   }\r
14242   if (func === other) {\r
14243     return true;\r
14244   }\r
14245   var data = getData(other);\r
14246   return !!data && func === data[0];\r
14247 }\r
14248 \r
14249 module.exports = isLaziable;\r
14250 \r
14251 },{"../chain/lodash":53,"./LazyWrapper":62,"./getData":112,"./getFuncName":113}],127:[function(require,module,exports){\r
14252 /**\r
14253  * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)\r
14254  * of an array-like value.\r
14255  */\r
14256 var MAX_SAFE_INTEGER = 9007199254740991;\r
14257 \r
14258 /**\r
14259  * Checks if `value` is a valid array-like length.\r
14260  *\r
14261  * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).\r
14262  *\r
14263  * @private\r
14264  * @param {*} value The value to check.\r
14265  * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\r
14266  */\r
14267 function isLength(value) {\r
14268   return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\r
14269 }\r
14270 \r
14271 module.exports = isLength;\r
14272 \r
14273 },{}],128:[function(require,module,exports){\r
14274 /**\r
14275  * Checks if `value` is object-like.\r
14276  *\r
14277  * @private\r
14278  * @param {*} value The value to check.\r
14279  * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\r
14280  */\r
14281 function isObjectLike(value) {\r
14282   return !!value && typeof value == 'object';\r
14283 }\r
14284 \r
14285 module.exports = isObjectLike;\r
14286 \r
14287 },{}],129:[function(require,module,exports){\r
14288 var isObject = require('../lang/isObject');\r
14289 \r
14290 /**\r
14291  * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.\r
14292  *\r
14293  * @private\r
14294  * @param {*} value The value to check.\r
14295  * @returns {boolean} Returns `true` if `value` if suitable for strict\r
14296  *  equality comparisons, else `false`.\r
14297  */\r
14298 function isStrictComparable(value) {\r
14299   return value === value && !isObject(value);\r
14300 }\r
14301 \r
14302 module.exports = isStrictComparable;\r
14303 \r
14304 },{"../lang/isObject":146}],130:[function(require,module,exports){\r
14305 var arrayCopy = require('./arrayCopy'),\r
14306     composeArgs = require('./composeArgs'),\r
14307     composeArgsRight = require('./composeArgsRight'),\r
14308     replaceHolders = require('./replaceHolders');\r
14309 \r
14310 /** Used to compose bitmasks for wrapper metadata. */\r
14311 var BIND_FLAG = 1,\r
14312     CURRY_BOUND_FLAG = 4,\r
14313     CURRY_FLAG = 8,\r
14314     ARY_FLAG = 128,\r
14315     REARG_FLAG = 256;\r
14316 \r
14317 /** Used as the internal argument placeholder. */\r
14318 var PLACEHOLDER = '__lodash_placeholder__';\r
14319 \r
14320 /* Native method references for those with the same name as other `lodash` methods. */\r
14321 var nativeMin = Math.min;\r
14322 \r
14323 /**\r
14324  * Merges the function metadata of `source` into `data`.\r
14325  *\r
14326  * Merging metadata reduces the number of wrappers required to invoke a function.\r
14327  * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`\r
14328  * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg`\r
14329  * augment function arguments, making the order in which they are executed important,\r
14330  * preventing the merging of metadata. However, we make an exception for a safe\r
14331  * common case where curried functions have `_.ary` and or `_.rearg` applied.\r
14332  *\r
14333  * @private\r
14334  * @param {Array} data The destination metadata.\r
14335  * @param {Array} source The source metadata.\r
14336  * @returns {Array} Returns `data`.\r
14337  */\r
14338 function mergeData(data, source) {\r
14339   var bitmask = data[1],\r
14340       srcBitmask = source[1],\r
14341       newBitmask = bitmask | srcBitmask,\r
14342       isCommon = newBitmask < ARY_FLAG;\r
14343 \r
14344   var isCombo =\r
14345     (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) ||\r
14346     (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) ||\r
14347     (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG);\r
14348 \r
14349   // Exit early if metadata can't be merged.\r
14350   if (!(isCommon || isCombo)) {\r
14351     return data;\r
14352   }\r
14353   // Use source `thisArg` if available.\r
14354   if (srcBitmask & BIND_FLAG) {\r
14355     data[2] = source[2];\r
14356     // Set when currying a bound function.\r
14357     newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG;\r
14358   }\r
14359   // Compose partial arguments.\r
14360   var value = source[3];\r
14361   if (value) {\r
14362     var partials = data[3];\r
14363     data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value);\r
14364     data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]);\r
14365   }\r
14366   // Compose partial right arguments.\r
14367   value = source[5];\r
14368   if (value) {\r
14369     partials = data[5];\r
14370     data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value);\r
14371     data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]);\r
14372   }\r
14373   // Use source `argPos` if available.\r
14374   value = source[7];\r
14375   if (value) {\r
14376     data[7] = arrayCopy(value);\r
14377   }\r
14378   // Use source `ary` if it's smaller.\r
14379   if (srcBitmask & ARY_FLAG) {\r
14380     data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);\r
14381   }\r
14382   // Use source `arity` if one is not provided.\r
14383   if (data[9] == null) {\r
14384     data[9] = source[9];\r
14385   }\r
14386   // Use source `func` and merge bitmasks.\r
14387   data[0] = source[0];\r
14388   data[1] = newBitmask;\r
14389 \r
14390   return data;\r
14391 }\r
14392 \r
14393 module.exports = mergeData;\r
14394 \r
14395 },{"./arrayCopy":64,"./composeArgs":98,"./composeArgsRight":99,"./replaceHolders":134}],131:[function(require,module,exports){\r
14396 (function (global){\r
14397 var getNative = require('./getNative');\r
14398 \r
14399 /** Native method references. */\r
14400 var WeakMap = getNative(global, 'WeakMap');\r
14401 \r
14402 /** Used to store function metadata. */\r
14403 var metaMap = WeakMap && new WeakMap;\r
14404 \r
14405 module.exports = metaMap;\r
14406 \r
14407 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})\r
14408 //# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL21ldGFNYXAuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgZ2V0TmF0aXZlID0gcmVxdWlyZSgnLi9nZXROYXRpdmUnKTtcblxuLyoqIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBXZWFrTWFwID0gZ2V0TmF0aXZlKGdsb2JhbCwgJ1dlYWtNYXAnKTtcblxuLyoqIFVzZWQgdG8gc3RvcmUgZnVuY3Rpb24gbWV0YWRhdGEuICovXG52YXIgbWV0YU1hcCA9IFdlYWtNYXAgJiYgbmV3IFdlYWtNYXA7XG5cbm1vZHVsZS5leHBvcnRzID0gbWV0YU1hcDtcbiJdfQ==\r
14409 },{"./getNative":116}],132:[function(require,module,exports){\r
14410 /** Used to lookup unminified function names. */\r
14411 var realNames = {};\r
14412 \r
14413 module.exports = realNames;\r
14414 \r
14415 },{}],133:[function(require,module,exports){\r
14416 var arrayCopy = require('./arrayCopy'),\r
14417     isIndex = require('./isIndex');\r
14418 \r
14419 /* Native method references for those with the same name as other `lodash` methods. */\r
14420 var nativeMin = Math.min;\r
14421 \r
14422 /**\r
14423  * Reorder `array` according to the specified indexes where the element at\r
14424  * the first index is assigned as the first element, the element at\r
14425  * the second index is assigned as the second element, and so on.\r
14426  *\r
14427  * @private\r
14428  * @param {Array} array The array to reorder.\r
14429  * @param {Array} indexes The arranged array indexes.\r
14430  * @returns {Array} Returns `array`.\r
14431  */\r
14432 function reorder(array, indexes) {\r
14433   var arrLength = array.length,\r
14434       length = nativeMin(indexes.length, arrLength),\r
14435       oldArray = arrayCopy(array);\r
14436 \r
14437   while (length--) {\r
14438     var index = indexes[length];\r
14439     array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;\r
14440   }\r
14441   return array;\r
14442 }\r
14443 \r
14444 module.exports = reorder;\r
14445 \r
14446 },{"./arrayCopy":64,"./isIndex":123}],134:[function(require,module,exports){\r
14447 /** Used as the internal argument placeholder. */\r
14448 var PLACEHOLDER = '__lodash_placeholder__';\r
14449 \r
14450 /**\r
14451  * Replaces all `placeholder` elements in `array` with an internal placeholder\r
14452  * and returns an array of their indexes.\r
14453  *\r
14454  * @private\r
14455  * @param {Array} array The array to modify.\r
14456  * @param {*} placeholder The placeholder to replace.\r
14457  * @returns {Array} Returns the new array of placeholder indexes.\r
14458  */\r
14459 function replaceHolders(array, placeholder) {\r
14460   var index = -1,\r
14461       length = array.length,\r
14462       resIndex = -1,\r
14463       result = [];\r
14464 \r
14465   while (++index < length) {\r
14466     if (array[index] === placeholder) {\r
14467       array[index] = PLACEHOLDER;\r
14468       result[++resIndex] = index;\r
14469     }\r
14470   }\r
14471   return result;\r
14472 }\r
14473 \r
14474 module.exports = replaceHolders;\r
14475 \r
14476 },{}],135:[function(require,module,exports){\r
14477 var baseSetData = require('./baseSetData'),\r
14478     now = require('../date/now');\r
14479 \r
14480 /** Used to detect when a function becomes hot. */\r
14481 var HOT_COUNT = 150,\r
14482     HOT_SPAN = 16;\r
14483 \r
14484 /**\r
14485  * Sets metadata for `func`.\r
14486  *\r
14487  * **Note:** If this function becomes hot, i.e. is invoked a lot in a short\r
14488  * period of time, it will trip its breaker and transition to an identity function\r
14489  * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070)\r
14490  * for more details.\r
14491  *\r
14492  * @private\r
14493  * @param {Function} func The function to associate metadata with.\r
14494  * @param {*} data The metadata.\r
14495  * @returns {Function} Returns `func`.\r
14496  */\r
14497 var setData = (function() {\r
14498   var count = 0,\r
14499       lastCalled = 0;\r
14500 \r
14501   return function(key, value) {\r
14502     var stamp = now(),\r
14503         remaining = HOT_SPAN - (stamp - lastCalled);\r
14504 \r
14505     lastCalled = stamp;\r
14506     if (remaining > 0) {\r
14507       if (++count >= HOT_COUNT) {\r
14508         return key;\r
14509       }\r
14510     } else {\r
14511       count = 0;\r
14512     }\r
14513     return baseSetData(key, value);\r
14514   };\r
14515 }());\r
14516 \r
14517 module.exports = setData;\r
14518 \r
14519 },{"../date/now":59,"./baseSetData":90}],136:[function(require,module,exports){\r
14520 var isArguments = require('../lang/isArguments'),\r
14521     isArray = require('../lang/isArray'),\r
14522     isIndex = require('./isIndex'),\r
14523     isLength = require('./isLength'),\r
14524     isString = require('../lang/isString'),\r
14525     keysIn = require('../object/keysIn');\r
14526 \r
14527 /** Used for native method references. */\r
14528 var objectProto = Object.prototype;\r
14529 \r
14530 /** Used to check objects for own properties. */\r
14531 var hasOwnProperty = objectProto.hasOwnProperty;\r
14532 \r
14533 /**\r
14534  * A fallback implementation of `Object.keys` which creates an array of the\r
14535  * own enumerable property names of `object`.\r
14536  *\r
14537  * @private\r
14538  * @param {Object} object The object to query.\r
14539  * @returns {Array} Returns the array of property names.\r
14540  */\r
14541 function shimKeys(object) {\r
14542   var props = keysIn(object),\r
14543       propsLength = props.length,\r
14544       length = propsLength && object.length;\r
14545 \r
14546   var allowIndexes = !!length && isLength(length) &&\r
14547     (isArray(object) || isArguments(object) || isString(object));\r
14548 \r
14549   var index = -1,\r
14550       result = [];\r
14551 \r
14552   while (++index < propsLength) {\r
14553     var key = props[index];\r
14554     if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {\r
14555       result.push(key);\r
14556     }\r
14557   }\r
14558   return result;\r
14559 }\r
14560 \r
14561 module.exports = shimKeys;\r
14562 \r
14563 },{"../lang/isArguments":141,"../lang/isArray":142,"../lang/isString":148,"../object/keysIn":152,"./isIndex":123,"./isLength":127}],137:[function(require,module,exports){\r
14564 var isObject = require('../lang/isObject'),\r
14565     isString = require('../lang/isString'),\r
14566     support = require('../support');\r
14567 \r
14568 /**\r
14569  * Converts `value` to an object if it's not one.\r
14570  *\r
14571  * @private\r
14572  * @param {*} value The value to process.\r
14573  * @returns {Object} Returns the object.\r
14574  */\r
14575 function toObject(value) {\r
14576   if (support.unindexedChars && isString(value)) {\r
14577     var index = -1,\r
14578         length = value.length,\r
14579         result = Object(value);\r
14580 \r
14581     while (++index < length) {\r
14582       result[index] = value.charAt(index);\r
14583     }\r
14584     return result;\r
14585   }\r
14586   return isObject(value) ? value : Object(value);\r
14587 }\r
14588 \r
14589 module.exports = toObject;\r
14590 \r
14591 },{"../lang/isObject":146,"../lang/isString":148,"../support":155}],138:[function(require,module,exports){\r
14592 var baseToString = require('./baseToString'),\r
14593     isArray = require('../lang/isArray');\r
14594 \r
14595 /** Used to match property names within property paths. */\r
14596 var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g;\r
14597 \r
14598 /** Used to match backslashes in property paths. */\r
14599 var reEscapeChar = /\\(\\)?/g;\r
14600 \r
14601 /**\r
14602  * Converts `value` to property path array if it's not one.\r
14603  *\r
14604  * @private\r
14605  * @param {*} value The value to process.\r
14606  * @returns {Array} Returns the property path array.\r
14607  */\r
14608 function toPath(value) {\r
14609   if (isArray(value)) {\r
14610     return value;\r
14611   }\r
14612   var result = [];\r
14613   baseToString(value).replace(rePropName, function(match, number, quote, string) {\r
14614     result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));\r
14615   });\r
14616   return result;\r
14617 }\r
14618 \r
14619 module.exports = toPath;\r
14620 \r
14621 },{"../lang/isArray":142,"./baseToString":92}],139:[function(require,module,exports){\r
14622 var LazyWrapper = require('./LazyWrapper'),\r
14623     LodashWrapper = require('./LodashWrapper'),\r
14624     arrayCopy = require('./arrayCopy');\r
14625 \r
14626 /**\r
14627  * Creates a clone of `wrapper`.\r
14628  *\r
14629  * @private\r
14630  * @param {Object} wrapper The wrapper to clone.\r
14631  * @returns {Object} Returns the cloned wrapper.\r
14632  */\r
14633 function wrapperClone(wrapper) {\r
14634   return wrapper instanceof LazyWrapper\r
14635     ? wrapper.clone()\r
14636     : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__));\r
14637 }\r
14638 \r
14639 module.exports = wrapperClone;\r
14640 \r
14641 },{"./LazyWrapper":62,"./LodashWrapper":63,"./arrayCopy":64}],140:[function(require,module,exports){\r
14642 var baseClone = require('../internal/baseClone'),\r
14643     bindCallback = require('../internal/bindCallback');\r
14644 \r
14645 /**\r
14646  * Creates a deep clone of `value`. If `customizer` is provided it's invoked\r
14647  * to produce the cloned values. If `customizer` returns `undefined` cloning\r
14648  * is handled by the method instead. The `customizer` is bound to `thisArg`\r
14649  * and invoked with up to three argument; (value [, index|key, object]).\r
14650  *\r
14651  * **Note:** This method is loosely based on the\r
14652  * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm).\r
14653  * The enumerable properties of `arguments` objects and objects created by\r
14654  * constructors other than `Object` are cloned to plain `Object` objects. An\r
14655  * empty object is returned for uncloneable values such as functions, DOM nodes,\r
14656  * Maps, Sets, and WeakMaps.\r
14657  *\r
14658  * @static\r
14659  * @memberOf _\r
14660  * @category Lang\r
14661  * @param {*} value The value to deep clone.\r
14662  * @param {Function} [customizer] The function to customize cloning values.\r
14663  * @param {*} [thisArg] The `this` binding of `customizer`.\r
14664  * @returns {*} Returns the deep cloned value.\r
14665  * @example\r
14666  *\r
14667  * var users = [\r
14668  *   { 'user': 'barney' },\r
14669  *   { 'user': 'fred' }\r
14670  * ];\r
14671  *\r
14672  * var deep = _.cloneDeep(users);\r
14673  * deep[0] === users[0];\r
14674  * // => false\r
14675  *\r
14676  * // using a customizer callback\r
14677  * var el = _.cloneDeep(document.body, function(value) {\r
14678  *   if (_.isElement(value)) {\r
14679  *     return value.cloneNode(true);\r
14680  *   }\r
14681  * });\r
14682  *\r
14683  * el === document.body\r
14684  * // => false\r
14685  * el.nodeName\r
14686  * // => BODY\r
14687  * el.childNodes.length;\r
14688  * // => 20\r
14689  */\r
14690 function cloneDeep(value, customizer, thisArg) {\r
14691   return typeof customizer == 'function'\r
14692     ? baseClone(value, true, bindCallback(customizer, thisArg, 3))\r
14693     : baseClone(value, true);\r
14694 }\r
14695 \r
14696 module.exports = cloneDeep;\r
14697 \r
14698 },{"../internal/baseClone":70,"../internal/bindCallback":96}],141:[function(require,module,exports){\r
14699 var isArrayLike = require('../internal/isArrayLike'),\r
14700     isObjectLike = require('../internal/isObjectLike');\r
14701 \r
14702 /** Used for native method references. */\r
14703 var objectProto = Object.prototype;\r
14704 \r
14705 /** Used to check objects for own properties. */\r
14706 var hasOwnProperty = objectProto.hasOwnProperty;\r
14707 \r
14708 /** Native method references. */\r
14709 var propertyIsEnumerable = objectProto.propertyIsEnumerable;\r
14710 \r
14711 /**\r
14712  * Checks if `value` is classified as an `arguments` object.\r
14713  *\r
14714  * @static\r
14715  * @memberOf _\r
14716  * @category Lang\r
14717  * @param {*} value The value to check.\r
14718  * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\r
14719  * @example\r
14720  *\r
14721  * _.isArguments(function() { return arguments; }());\r
14722  * // => true\r
14723  *\r
14724  * _.isArguments([1, 2, 3]);\r
14725  * // => false\r
14726  */\r
14727 function isArguments(value) {\r
14728   return isObjectLike(value) && isArrayLike(value) &&\r
14729     hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee');\r
14730 }\r
14731 \r
14732 module.exports = isArguments;\r
14733 \r
14734 },{"../internal/isArrayLike":121,"../internal/isObjectLike":128}],142:[function(require,module,exports){\r
14735 var getNative = require('../internal/getNative'),\r
14736     isLength = require('../internal/isLength'),\r
14737     isObjectLike = require('../internal/isObjectLike');\r
14738 \r
14739 /** `Object#toString` result references. */\r
14740 var arrayTag = '[object Array]';\r
14741 \r
14742 /** Used for native method references. */\r
14743 var objectProto = Object.prototype;\r
14744 \r
14745 /**\r
14746  * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\r
14747  * of values.\r
14748  */\r
14749 var objToString = objectProto.toString;\r
14750 \r
14751 /* Native method references for those with the same name as other `lodash` methods. */\r
14752 var nativeIsArray = getNative(Array, 'isArray');\r
14753 \r
14754 /**\r
14755  * Checks if `value` is classified as an `Array` object.\r
14756  *\r
14757  * @static\r
14758  * @memberOf _\r
14759  * @category Lang\r
14760  * @param {*} value The value to check.\r
14761  * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\r
14762  * @example\r
14763  *\r
14764  * _.isArray([1, 2, 3]);\r
14765  * // => true\r
14766  *\r
14767  * _.isArray(function() { return arguments; }());\r
14768  * // => false\r
14769  */\r
14770 var isArray = nativeIsArray || function(value) {\r
14771   return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;\r
14772 };\r
14773 \r
14774 module.exports = isArray;\r
14775 \r
14776 },{"../internal/getNative":116,"../internal/isLength":127,"../internal/isObjectLike":128}],143:[function(require,module,exports){\r
14777 var isArguments = require('./isArguments'),\r
14778     isArray = require('./isArray'),\r
14779     isArrayLike = require('../internal/isArrayLike'),\r
14780     isFunction = require('./isFunction'),\r
14781     isObjectLike = require('../internal/isObjectLike'),\r
14782     isString = require('./isString'),\r
14783     keys = require('../object/keys');\r
14784 \r
14785 /**\r
14786  * Checks if `value` is empty. A value is considered empty unless it's an\r
14787  * `arguments` object, array, string, or jQuery-like collection with a length\r
14788  * greater than `0` or an object with own enumerable properties.\r
14789  *\r
14790  * @static\r
14791  * @memberOf _\r
14792  * @category Lang\r
14793  * @param {Array|Object|string} value The value to inspect.\r
14794  * @returns {boolean} Returns `true` if `value` is empty, else `false`.\r
14795  * @example\r
14796  *\r
14797  * _.isEmpty(null);\r
14798  * // => true\r
14799  *\r
14800  * _.isEmpty(true);\r
14801  * // => true\r
14802  *\r
14803  * _.isEmpty(1);\r
14804  * // => true\r
14805  *\r
14806  * _.isEmpty([1, 2, 3]);\r
14807  * // => false\r
14808  *\r
14809  * _.isEmpty({ 'a': 1 });\r
14810  * // => false\r
14811  */\r
14812 function isEmpty(value) {\r
14813   if (value == null) {\r
14814     return true;\r
14815   }\r
14816   if (isArrayLike(value) && (isArray(value) || isString(value) || isArguments(value) ||\r
14817       (isObjectLike(value) && isFunction(value.splice)))) {\r
14818     return !value.length;\r
14819   }\r
14820   return !keys(value).length;\r
14821 }\r
14822 \r
14823 module.exports = isEmpty;\r
14824 \r
14825 },{"../internal/isArrayLike":121,"../internal/isObjectLike":128,"../object/keys":151,"./isArguments":141,"./isArray":142,"./isFunction":144,"./isString":148}],144:[function(require,module,exports){\r
14826 var isObject = require('./isObject');\r
14827 \r
14828 /** `Object#toString` result references. */\r
14829 var funcTag = '[object Function]';\r
14830 \r
14831 /** Used for native method references. */\r
14832 var objectProto = Object.prototype;\r
14833 \r
14834 /**\r
14835  * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\r
14836  * of values.\r
14837  */\r
14838 var objToString = objectProto.toString;\r
14839 \r
14840 /**\r
14841  * Checks if `value` is classified as a `Function` object.\r
14842  *\r
14843  * @static\r
14844  * @memberOf _\r
14845  * @category Lang\r
14846  * @param {*} value The value to check.\r
14847  * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\r
14848  * @example\r
14849  *\r
14850  * _.isFunction(_);\r
14851  * // => true\r
14852  *\r
14853  * _.isFunction(/abc/);\r
14854  * // => false\r
14855  */\r
14856 function isFunction(value) {\r
14857   // The use of `Object#toString` avoids issues with the `typeof` operator\r
14858   // in older versions of Chrome and Safari which return 'function' for regexes\r
14859   // and Safari 8 which returns 'object' for typed array constructors.\r
14860   return isObject(value) && objToString.call(value) == funcTag;\r
14861 }\r
14862 \r
14863 module.exports = isFunction;\r
14864 \r
14865 },{"./isObject":146}],145:[function(require,module,exports){\r
14866 var isFunction = require('./isFunction'),\r
14867     isHostObject = require('../internal/isHostObject'),\r
14868     isObjectLike = require('../internal/isObjectLike');\r
14869 \r
14870 /** Used to detect host constructors (Safari > 5). */\r
14871 var reIsHostCtor = /^\[object .+?Constructor\]$/;\r
14872 \r
14873 /** Used for native method references. */\r
14874 var objectProto = Object.prototype;\r
14875 \r
14876 /** Used to resolve the decompiled source of functions. */\r
14877 var fnToString = Function.prototype.toString;\r
14878 \r
14879 /** Used to check objects for own properties. */\r
14880 var hasOwnProperty = objectProto.hasOwnProperty;\r
14881 \r
14882 /** Used to detect if a method is native. */\r
14883 var reIsNative = RegExp('^' +\r
14884   fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')\r
14885   .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'\r
14886 );\r
14887 \r
14888 /**\r
14889  * Checks if `value` is a native function.\r
14890  *\r
14891  * @static\r
14892  * @memberOf _\r
14893  * @category Lang\r
14894  * @param {*} value The value to check.\r
14895  * @returns {boolean} Returns `true` if `value` is a native function, else `false`.\r
14896  * @example\r
14897  *\r
14898  * _.isNative(Array.prototype.push);\r
14899  * // => true\r
14900  *\r
14901  * _.isNative(_);\r
14902  * // => false\r
14903  */\r
14904 function isNative(value) {\r
14905   if (value == null) {\r
14906     return false;\r
14907   }\r
14908   if (isFunction(value)) {\r
14909     return reIsNative.test(fnToString.call(value));\r
14910   }\r
14911   return isObjectLike(value) && (isHostObject(value) ? reIsNative : reIsHostCtor).test(value);\r
14912 }\r
14913 \r
14914 module.exports = isNative;\r
14915 \r
14916 },{"../internal/isHostObject":122,"../internal/isObjectLike":128,"./isFunction":144}],146:[function(require,module,exports){\r
14917 /**\r
14918  * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\r
14919  * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\r
14920  *\r
14921  * @static\r
14922  * @memberOf _\r
14923  * @category Lang\r
14924  * @param {*} value The value to check.\r
14925  * @returns {boolean} Returns `true` if `value` is an object, else `false`.\r
14926  * @example\r
14927  *\r
14928  * _.isObject({});\r
14929  * // => true\r
14930  *\r
14931  * _.isObject([1, 2, 3]);\r
14932  * // => true\r
14933  *\r
14934  * _.isObject(1);\r
14935  * // => false\r
14936  */\r
14937 function isObject(value) {\r
14938   // Avoid a V8 JIT bug in Chrome 19-20.\r
14939   // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\r
14940   var type = typeof value;\r
14941   return !!value && (type == 'object' || type == 'function');\r
14942 }\r
14943 \r
14944 module.exports = isObject;\r
14945 \r
14946 },{}],147:[function(require,module,exports){\r
14947 var baseForIn = require('../internal/baseForIn'),\r
14948     isArguments = require('./isArguments'),\r
14949     isHostObject = require('../internal/isHostObject'),\r
14950     isObjectLike = require('../internal/isObjectLike'),\r
14951     support = require('../support');\r
14952 \r
14953 /** `Object#toString` result references. */\r
14954 var objectTag = '[object Object]';\r
14955 \r
14956 /** Used for native method references. */\r
14957 var objectProto = Object.prototype;\r
14958 \r
14959 /** Used to check objects for own properties. */\r
14960 var hasOwnProperty = objectProto.hasOwnProperty;\r
14961 \r
14962 /**\r
14963  * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\r
14964  * of values.\r
14965  */\r
14966 var objToString = objectProto.toString;\r
14967 \r
14968 /**\r
14969  * Checks if `value` is a plain object, that is, an object created by the\r
14970  * `Object` constructor or one with a `[[Prototype]]` of `null`.\r
14971  *\r
14972  * **Note:** This method assumes objects created by the `Object` constructor\r
14973  * have no inherited enumerable properties.\r
14974  *\r
14975  * @static\r
14976  * @memberOf _\r
14977  * @category Lang\r
14978  * @param {*} value The value to check.\r
14979  * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.\r
14980  * @example\r
14981  *\r
14982  * function Foo() {\r
14983  *   this.a = 1;\r
14984  * }\r
14985  *\r
14986  * _.isPlainObject(new Foo);\r
14987  * // => false\r
14988  *\r
14989  * _.isPlainObject([1, 2, 3]);\r
14990  * // => false\r
14991  *\r
14992  * _.isPlainObject({ 'x': 0, 'y': 0 });\r
14993  * // => true\r
14994  *\r
14995  * _.isPlainObject(Object.create(null));\r
14996  * // => true\r
14997  */\r
14998 function isPlainObject(value) {\r
14999   var Ctor;\r
15000 \r
15001   // Exit early for non `Object` objects.\r
15002   if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isHostObject(value) && !isArguments(value)) ||\r
15003       (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) {\r
15004     return false;\r
15005   }\r
15006   // IE < 9 iterates inherited properties before own properties. If the first\r
15007   // iterated property is an object's own property then there are no inherited\r
15008   // enumerable properties.\r
15009   var result;\r
15010   if (support.ownLast) {\r
15011     baseForIn(value, function(subValue, key, object) {\r
15012       result = hasOwnProperty.call(object, key);\r
15013       return false;\r
15014     });\r
15015     return result !== false;\r
15016   }\r
15017   // In most environments an object's own properties are iterated before\r
15018   // its inherited properties. If the last iterated property is an object's\r
15019   // own property then there are no inherited enumerable properties.\r
15020   baseForIn(value, function(subValue, key) {\r
15021     result = key;\r
15022   });\r
15023   return result === undefined || hasOwnProperty.call(value, result);\r
15024 }\r
15025 \r
15026 module.exports = isPlainObject;\r
15027 \r
15028 },{"../internal/baseForIn":77,"../internal/isHostObject":122,"../internal/isObjectLike":128,"../support":155,"./isArguments":141}],148:[function(require,module,exports){\r
15029 var isObjectLike = require('../internal/isObjectLike');\r
15030 \r
15031 /** `Object#toString` result references. */\r
15032 var stringTag = '[object String]';\r
15033 \r
15034 /** Used for native method references. */\r
15035 var objectProto = Object.prototype;\r
15036 \r
15037 /**\r
15038  * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\r
15039  * of values.\r
15040  */\r
15041 var objToString = objectProto.toString;\r
15042 \r
15043 /**\r
15044  * Checks if `value` is classified as a `String` primitive or object.\r
15045  *\r
15046  * @static\r
15047  * @memberOf _\r
15048  * @category Lang\r
15049  * @param {*} value The value to check.\r
15050  * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\r
15051  * @example\r
15052  *\r
15053  * _.isString('abc');\r
15054  * // => true\r
15055  *\r
15056  * _.isString(1);\r
15057  * // => false\r
15058  */\r
15059 function isString(value) {\r
15060   return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag);\r
15061 }\r
15062 \r
15063 module.exports = isString;\r
15064 \r
15065 },{"../internal/isObjectLike":128}],149:[function(require,module,exports){\r
15066 var isLength = require('../internal/isLength'),\r
15067     isObjectLike = require('../internal/isObjectLike');\r
15068 \r
15069 /** `Object#toString` result references. */\r
15070 var argsTag = '[object Arguments]',\r
15071     arrayTag = '[object Array]',\r
15072     boolTag = '[object Boolean]',\r
15073     dateTag = '[object Date]',\r
15074     errorTag = '[object Error]',\r
15075     funcTag = '[object Function]',\r
15076     mapTag = '[object Map]',\r
15077     numberTag = '[object Number]',\r
15078     objectTag = '[object Object]',\r
15079     regexpTag = '[object RegExp]',\r
15080     setTag = '[object Set]',\r
15081     stringTag = '[object String]',\r
15082     weakMapTag = '[object WeakMap]';\r
15083 \r
15084 var arrayBufferTag = '[object ArrayBuffer]',\r
15085     float32Tag = '[object Float32Array]',\r
15086     float64Tag = '[object Float64Array]',\r
15087     int8Tag = '[object Int8Array]',\r
15088     int16Tag = '[object Int16Array]',\r
15089     int32Tag = '[object Int32Array]',\r
15090     uint8Tag = '[object Uint8Array]',\r
15091     uint8ClampedTag = '[object Uint8ClampedArray]',\r
15092     uint16Tag = '[object Uint16Array]',\r
15093     uint32Tag = '[object Uint32Array]';\r
15094 \r
15095 /** Used to identify `toStringTag` values of typed arrays. */\r
15096 var typedArrayTags = {};\r
15097 typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =\r
15098 typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =\r
15099 typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =\r
15100 typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =\r
15101 typedArrayTags[uint32Tag] = true;\r
15102 typedArrayTags[argsTag] = typedArrayTags[arrayTag] =\r
15103 typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =\r
15104 typedArrayTags[dateTag] = typedArrayTags[errorTag] =\r
15105 typedArrayTags[funcTag] = typedArrayTags[mapTag] =\r
15106 typedArrayTags[numberTag] = typedArrayTags[objectTag] =\r
15107 typedArrayTags[regexpTag] = typedArrayTags[setTag] =\r
15108 typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;\r
15109 \r
15110 /** Used for native method references. */\r
15111 var objectProto = Object.prototype;\r
15112 \r
15113 /**\r
15114  * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\r
15115  * of values.\r
15116  */\r
15117 var objToString = objectProto.toString;\r
15118 \r
15119 /**\r
15120  * Checks if `value` is classified as a typed array.\r
15121  *\r
15122  * @static\r
15123  * @memberOf _\r
15124  * @category Lang\r
15125  * @param {*} value The value to check.\r
15126  * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\r
15127  * @example\r
15128  *\r
15129  * _.isTypedArray(new Uint8Array);\r
15130  * // => true\r
15131  *\r
15132  * _.isTypedArray([]);\r
15133  * // => false\r
15134  */\r
15135 function isTypedArray(value) {\r
15136   return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];\r
15137 }\r
15138 \r
15139 module.exports = isTypedArray;\r
15140 \r
15141 },{"../internal/isLength":127,"../internal/isObjectLike":128}],150:[function(require,module,exports){\r
15142 /**\r
15143  * Checks if `value` is `undefined`.\r
15144  *\r
15145  * @static\r
15146  * @memberOf _\r
15147  * @category Lang\r
15148  * @param {*} value The value to check.\r
15149  * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.\r
15150  * @example\r
15151  *\r
15152  * _.isUndefined(void 0);\r
15153  * // => true\r
15154  *\r
15155  * _.isUndefined(null);\r
15156  * // => false\r
15157  */\r
15158 function isUndefined(value) {\r
15159   return value === undefined;\r
15160 }\r
15161 \r
15162 module.exports = isUndefined;\r
15163 \r
15164 },{}],151:[function(require,module,exports){\r
15165 var getNative = require('../internal/getNative'),\r
15166     isArrayLike = require('../internal/isArrayLike'),\r
15167     isObject = require('../lang/isObject'),\r
15168     shimKeys = require('../internal/shimKeys'),\r
15169     support = require('../support');\r
15170 \r
15171 /* Native method references for those with the same name as other `lodash` methods. */\r
15172 var nativeKeys = getNative(Object, 'keys');\r
15173 \r
15174 /**\r
15175  * Creates an array of the own enumerable property names of `object`.\r
15176  *\r
15177  * **Note:** Non-object values are coerced to objects. See the\r
15178  * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)\r
15179  * for more details.\r
15180  *\r
15181  * @static\r
15182  * @memberOf _\r
15183  * @category Object\r
15184  * @param {Object} object The object to query.\r
15185  * @returns {Array} Returns the array of property names.\r
15186  * @example\r
15187  *\r
15188  * function Foo() {\r
15189  *   this.a = 1;\r
15190  *   this.b = 2;\r
15191  * }\r
15192  *\r
15193  * Foo.prototype.c = 3;\r
15194  *\r
15195  * _.keys(new Foo);\r
15196  * // => ['a', 'b'] (iteration order is not guaranteed)\r
15197  *\r
15198  * _.keys('hi');\r
15199  * // => ['0', '1']\r
15200  */\r
15201 var keys = !nativeKeys ? shimKeys : function(object) {\r
15202   var Ctor = object == null ? undefined : object.constructor;\r
15203   if ((typeof Ctor == 'function' && Ctor.prototype === object) ||\r
15204       (typeof object == 'function' ? support.enumPrototypes : isArrayLike(object))) {\r
15205     return shimKeys(object);\r
15206   }\r
15207   return isObject(object) ? nativeKeys(object) : [];\r
15208 };\r
15209 \r
15210 module.exports = keys;\r
15211 \r
15212 },{"../internal/getNative":116,"../internal/isArrayLike":121,"../internal/shimKeys":136,"../lang/isObject":146,"../support":155}],152:[function(require,module,exports){\r
15213 var arrayEach = require('../internal/arrayEach'),\r
15214     isArguments = require('../lang/isArguments'),\r
15215     isArray = require('../lang/isArray'),\r
15216     isFunction = require('../lang/isFunction'),\r
15217     isIndex = require('../internal/isIndex'),\r
15218     isLength = require('../internal/isLength'),\r
15219     isObject = require('../lang/isObject'),\r
15220     isString = require('../lang/isString'),\r
15221     support = require('../support');\r
15222 \r
15223 /** `Object#toString` result references. */\r
15224 var arrayTag = '[object Array]',\r
15225     boolTag = '[object Boolean]',\r
15226     dateTag = '[object Date]',\r
15227     errorTag = '[object Error]',\r
15228     funcTag = '[object Function]',\r
15229     numberTag = '[object Number]',\r
15230     objectTag = '[object Object]',\r
15231     regexpTag = '[object RegExp]',\r
15232     stringTag = '[object String]';\r
15233 \r
15234 /** Used to fix the JScript `[[DontEnum]]` bug. */\r
15235 var shadowProps = [\r
15236   'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',\r
15237   'toLocaleString', 'toString', 'valueOf'\r
15238 ];\r
15239 \r
15240 /** Used for native method references. */\r
15241 var errorProto = Error.prototype,\r
15242     objectProto = Object.prototype,\r
15243     stringProto = String.prototype;\r
15244 \r
15245 /** Used to check objects for own properties. */\r
15246 var hasOwnProperty = objectProto.hasOwnProperty;\r
15247 \r
15248 /**\r
15249  * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\r
15250  * of values.\r
15251  */\r
15252 var objToString = objectProto.toString;\r
15253 \r
15254 /** Used to avoid iterating over non-enumerable properties in IE < 9. */\r
15255 var nonEnumProps = {};\r
15256 nonEnumProps[arrayTag] = nonEnumProps[dateTag] = nonEnumProps[numberTag] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true };\r
15257 nonEnumProps[boolTag] = nonEnumProps[stringTag] = { 'constructor': true, 'toString': true, 'valueOf': true };\r
15258 nonEnumProps[errorTag] = nonEnumProps[funcTag] = nonEnumProps[regexpTag] = { 'constructor': true, 'toString': true };\r
15259 nonEnumProps[objectTag] = { 'constructor': true };\r
15260 \r
15261 arrayEach(shadowProps, function(key) {\r
15262   for (var tag in nonEnumProps) {\r
15263     if (hasOwnProperty.call(nonEnumProps, tag)) {\r
15264       var props = nonEnumProps[tag];\r
15265       props[key] = hasOwnProperty.call(props, key);\r
15266     }\r
15267   }\r
15268 });\r
15269 \r
15270 /**\r
15271  * Creates an array of the own and inherited enumerable property names of `object`.\r
15272  *\r
15273  * **Note:** Non-object values are coerced to objects.\r
15274  *\r
15275  * @static\r
15276  * @memberOf _\r
15277  * @category Object\r
15278  * @param {Object} object The object to query.\r
15279  * @returns {Array} Returns the array of property names.\r
15280  * @example\r
15281  *\r
15282  * function Foo() {\r
15283  *   this.a = 1;\r
15284  *   this.b = 2;\r
15285  * }\r
15286  *\r
15287  * Foo.prototype.c = 3;\r
15288  *\r
15289  * _.keysIn(new Foo);\r
15290  * // => ['a', 'b', 'c'] (iteration order is not guaranteed)\r
15291  */\r
15292 function keysIn(object) {\r
15293   if (object == null) {\r
15294     return [];\r
15295   }\r
15296   if (!isObject(object)) {\r
15297     object = Object(object);\r
15298   }\r
15299   var length = object.length;\r
15300 \r
15301   length = (length && isLength(length) &&\r
15302     (isArray(object) || isArguments(object) || isString(object)) && length) || 0;\r
15303 \r
15304   var Ctor = object.constructor,\r
15305       index = -1,\r
15306       proto = (isFunction(Ctor) && Ctor.prototype) || objectProto,\r
15307       isProto = proto === object,\r
15308       result = Array(length),\r
15309       skipIndexes = length > 0,\r
15310       skipErrorProps = support.enumErrorProps && (object === errorProto || object instanceof Error),\r
15311       skipProto = support.enumPrototypes && isFunction(object);\r
15312 \r
15313   while (++index < length) {\r
15314     result[index] = (index + '');\r
15315   }\r
15316   // lodash skips the `constructor` property when it infers it's iterating\r
15317   // over a `prototype` object because IE < 9 can't set the `[[Enumerable]]`\r
15318   // attribute of an existing property and the `constructor` property of a\r
15319   // prototype defaults to non-enumerable.\r
15320   for (var key in object) {\r
15321     if (!(skipProto && key == 'prototype') &&\r
15322         !(skipErrorProps && (key == 'message' || key == 'name')) &&\r
15323         !(skipIndexes && isIndex(key, length)) &&\r
15324         !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {\r
15325       result.push(key);\r
15326     }\r
15327   }\r
15328   if (support.nonEnumShadows && object !== objectProto) {\r
15329     var tag = object === stringProto ? stringTag : (object === errorProto ? errorTag : objToString.call(object)),\r
15330         nonEnums = nonEnumProps[tag] || nonEnumProps[objectTag];\r
15331 \r
15332     if (tag == objectTag) {\r
15333       proto = objectProto;\r
15334     }\r
15335     length = shadowProps.length;\r
15336     while (length--) {\r
15337       key = shadowProps[length];\r
15338       var nonEnum = nonEnums[key];\r
15339       if (!(isProto && nonEnum) &&\r
15340           (nonEnum ? hasOwnProperty.call(object, key) : object[key] !== proto[key])) {\r
15341         result.push(key);\r
15342       }\r
15343     }\r
15344   }\r
15345   return result;\r
15346 }\r
15347 \r
15348 module.exports = keysIn;\r
15349 \r
15350 },{"../internal/arrayEach":65,"../internal/isIndex":123,"../internal/isLength":127,"../lang/isArguments":141,"../lang/isArray":142,"../lang/isFunction":144,"../lang/isObject":146,"../lang/isString":148,"../support":155}],153:[function(require,module,exports){\r
15351 var keys = require('./keys'),\r
15352     toObject = require('../internal/toObject');\r
15353 \r
15354 /**\r
15355  * Creates a two dimensional array of the key-value pairs for `object`,\r
15356  * e.g. `[[key1, value1], [key2, value2]]`.\r
15357  *\r
15358  * @static\r
15359  * @memberOf _\r
15360  * @category Object\r
15361  * @param {Object} object The object to query.\r
15362  * @returns {Array} Returns the new array of key-value pairs.\r
15363  * @example\r
15364  *\r
15365  * _.pairs({ 'barney': 36, 'fred': 40 });\r
15366  * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed)\r
15367  */\r
15368 function pairs(object) {\r
15369   object = toObject(object);\r
15370 \r
15371   var index = -1,\r
15372       props = keys(object),\r
15373       length = props.length,\r
15374       result = Array(length);\r
15375 \r
15376   while (++index < length) {\r
15377     var key = props[index];\r
15378     result[index] = [key, object[key]];\r
15379   }\r
15380   return result;\r
15381 }\r
15382 \r
15383 module.exports = pairs;\r
15384 \r
15385 },{"../internal/toObject":137,"./keys":151}],154:[function(require,module,exports){\r
15386 var baseValues = require('../internal/baseValues'),\r
15387     keys = require('./keys');\r
15388 \r
15389 /**\r
15390  * Creates an array of the own enumerable property values of `object`.\r
15391  *\r
15392  * **Note:** Non-object values are coerced to objects.\r
15393  *\r
15394  * @static\r
15395  * @memberOf _\r
15396  * @category Object\r
15397  * @param {Object} object The object to query.\r
15398  * @returns {Array} Returns the array of property values.\r
15399  * @example\r
15400  *\r
15401  * function Foo() {\r
15402  *   this.a = 1;\r
15403  *   this.b = 2;\r
15404  * }\r
15405  *\r
15406  * Foo.prototype.c = 3;\r
15407  *\r
15408  * _.values(new Foo);\r
15409  * // => [1, 2] (iteration order is not guaranteed)\r
15410  *\r
15411  * _.values('hi');\r
15412  * // => ['h', 'i']\r
15413  */\r
15414 function values(object) {\r
15415   return baseValues(object, keys(object));\r
15416 }\r
15417 \r
15418 module.exports = values;\r
15419 \r
15420 },{"../internal/baseValues":93,"./keys":151}],155:[function(require,module,exports){\r
15421 /** Used for native method references. */\r
15422 var arrayProto = Array.prototype,\r
15423     errorProto = Error.prototype,\r
15424     objectProto = Object.prototype;\r
15425 \r
15426 /** Native method references. */\r
15427 var propertyIsEnumerable = objectProto.propertyIsEnumerable,\r
15428     splice = arrayProto.splice;\r
15429 \r
15430 /**\r
15431  * An object environment feature flags.\r
15432  *\r
15433  * @static\r
15434  * @memberOf _\r
15435  * @type Object\r
15436  */\r
15437 var support = {};\r
15438 \r
15439 (function(x) {\r
15440   var Ctor = function() { this.x = x; },\r
15441       object = { '0': x, 'length': x },\r
15442       props = [];\r
15443 \r
15444   Ctor.prototype = { 'valueOf': x, 'y': x };\r
15445   for (var key in new Ctor) { props.push(key); }\r
15446 \r
15447   /**\r
15448    * Detect if `name` or `message` properties of `Error.prototype` are\r
15449    * enumerable by default (IE < 9, Safari < 5.1).\r
15450    *\r
15451    * @memberOf _.support\r
15452    * @type boolean\r
15453    */\r
15454   support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') ||\r
15455     propertyIsEnumerable.call(errorProto, 'name');\r
15456 \r
15457   /**\r
15458    * Detect if `prototype` properties are enumerable by default.\r
15459    *\r
15460    * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1\r
15461    * (if the prototype or a property on the prototype has been set)\r
15462    * incorrectly set the `[[Enumerable]]` value of a function's `prototype`\r
15463    * property to `true`.\r
15464    *\r
15465    * @memberOf _.support\r
15466    * @type boolean\r
15467    */\r
15468   support.enumPrototypes = propertyIsEnumerable.call(Ctor, 'prototype');\r
15469 \r
15470   /**\r
15471    * Detect if properties shadowing those on `Object.prototype` are non-enumerable.\r
15472    *\r
15473    * In IE < 9 an object's own properties, shadowing non-enumerable ones,\r
15474    * are made non-enumerable as well (a.k.a the JScript `[[DontEnum]]` bug).\r
15475    *\r
15476    * @memberOf _.support\r
15477    * @type boolean\r
15478    */\r
15479   support.nonEnumShadows = !/valueOf/.test(props);\r
15480 \r
15481   /**\r
15482    * Detect if own properties are iterated after inherited properties (IE < 9).\r
15483    *\r
15484    * @memberOf _.support\r
15485    * @type boolean\r
15486    */\r
15487   support.ownLast = props[0] != 'x';\r
15488 \r
15489   /**\r
15490    * Detect if `Array#shift` and `Array#splice` augment array-like objects\r
15491    * correctly.\r
15492    *\r
15493    * Firefox < 10, compatibility modes of IE 8, and IE < 9 have buggy Array\r
15494    * `shift()` and `splice()` functions that fail to remove the last element,\r
15495    * `value[0]`, of array-like objects even though the "length" property is\r
15496    * set to `0`. The `shift()` method is buggy in compatibility modes of IE 8,\r
15497    * while `splice()` is buggy regardless of mode in IE < 9.\r
15498    *\r
15499    * @memberOf _.support\r
15500    * @type boolean\r
15501    */\r
15502   support.spliceObjects = (splice.call(object, 0, 1), !object[0]);\r
15503 \r
15504   /**\r
15505    * Detect lack of support for accessing string characters by index.\r
15506    *\r
15507    * IE < 8 can't access characters by index. IE 8 can only access characters\r
15508    * by index on string literals, not string objects.\r
15509    *\r
15510    * @memberOf _.support\r
15511    * @type boolean\r
15512    */\r
15513   support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx';\r
15514 }(1, 0));\r
15515 \r
15516 module.exports = support;\r
15517 \r
15518 },{}],156:[function(require,module,exports){\r
15519 /**\r
15520  * This method returns the first argument provided to it.\r
15521  *\r
15522  * @static\r
15523  * @memberOf _\r
15524  * @category Utility\r
15525  * @param {*} value Any value.\r
15526  * @returns {*} Returns `value`.\r
15527  * @example\r
15528  *\r
15529  * var object = { 'user': 'fred' };\r
15530  *\r
15531  * _.identity(object) === object;\r
15532  * // => true\r
15533  */\r
15534 function identity(value) {\r
15535   return value;\r
15536 }\r
15537 \r
15538 module.exports = identity;\r
15539 \r
15540 },{}],157:[function(require,module,exports){\r
15541 /**\r
15542  * A no-operation function that returns `undefined` regardless of the\r
15543  * arguments it receives.\r
15544  *\r
15545  * @static\r
15546  * @memberOf _\r
15547  * @category Utility\r
15548  * @example\r
15549  *\r
15550  * var object = { 'user': 'fred' };\r
15551  *\r
15552  * _.noop(object) === undefined;\r
15553  * // => true\r
15554  */\r
15555 function noop() {\r
15556   // No operation performed.\r
15557 }\r
15558 \r
15559 module.exports = noop;\r
15560 \r
15561 },{}],158:[function(require,module,exports){\r
15562 var baseProperty = require('../internal/baseProperty'),\r
15563     basePropertyDeep = require('../internal/basePropertyDeep'),\r
15564     isKey = require('../internal/isKey');\r
15565 \r
15566 /**\r
15567  * Creates a function that returns the property value at `path` on a\r
15568  * given object.\r
15569  *\r
15570  * @static\r
15571  * @memberOf _\r
15572  * @category Utility\r
15573  * @param {Array|string} path The path of the property to get.\r
15574  * @returns {Function} Returns the new function.\r
15575  * @example\r
15576  *\r
15577  * var objects = [\r
15578  *   { 'a': { 'b': { 'c': 2 } } },\r
15579  *   { 'a': { 'b': { 'c': 1 } } }\r
15580  * ];\r
15581  *\r
15582  * _.map(objects, _.property('a.b.c'));\r
15583  * // => [2, 1]\r
15584  *\r
15585  * _.pluck(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c');\r
15586  * // => [1, 2]\r
15587  */\r
15588 function property(path) {\r
15589   return isKey(path) ? baseProperty(path) : basePropertyDeep(path);\r
15590 }\r
15591 \r
15592 module.exports = property;\r
15593 \r
15594 },{"../internal/baseProperty":88,"../internal/basePropertyDeep":89,"../internal/isKey":125}],159:[function(require,module,exports){\r
15595 (function (process){\r
15596 // vim:ts=4:sts=4:sw=4:\r
15597 /*!\r
15598  *\r
15599  * Copyright 2009-2012 Kris Kowal under the terms of the MIT\r
15600  * license found at http://github.com/kriskowal/q/raw/master/LICENSE\r
15601  *\r
15602  * With parts by Tyler Close\r
15603  * Copyright 2007-2009 Tyler Close under the terms of the MIT X license found\r
15604  * at http://www.opensource.org/licenses/mit-license.html\r
15605  * Forked at ref_send.js version: 2009-05-11\r
15606  *\r
15607  * With parts by Mark Miller\r
15608  * Copyright (C) 2011 Google Inc.\r
15609  *\r
15610  * Licensed under the Apache License, Version 2.0 (the "License");\r
15611  * you may not use this file except in compliance with the License.\r
15612  * You may obtain a copy of the License at\r
15613  *\r
15614  * http://www.apache.org/licenses/LICENSE-2.0\r
15615  *\r
15616  * Unless required by applicable law or agreed to in writing, software\r
15617  * distributed under the License is distributed on an "AS IS" BASIS,\r
15618  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
15619  * See the License for the specific language governing permissions and\r
15620  * limitations under the License.\r
15621  *\r
15622  */\r
15623 \r
15624 (function (definition) {\r
15625     "use strict";\r
15626 \r
15627     // This file will function properly as a <script> tag, or a module\r
15628     // using CommonJS and NodeJS or RequireJS module formats.  In\r
15629     // Common/Node/RequireJS, the module exports the Q API and when\r
15630     // executed as a simple <script>, it creates a Q global instead.\r
15631 \r
15632     // Montage Require\r
15633     if (typeof bootstrap === "function") {\r
15634         bootstrap("promise", definition);\r
15635 \r
15636     // CommonJS\r
15637     } else if (typeof exports === "object" && typeof module === "object") {\r
15638         module.exports = definition();\r
15639 \r
15640     // RequireJS\r
15641     } else if (typeof define === "function" && define.amd) {\r
15642         define(definition);\r
15643 \r
15644     // SES (Secure EcmaScript)\r
15645     } else if (typeof ses !== "undefined") {\r
15646         if (!ses.ok()) {\r
15647             return;\r
15648         } else {\r
15649             ses.makeQ = definition;\r
15650         }\r
15651 \r
15652     // <script>\r
15653     } else if (typeof window !== "undefined" || typeof self !== "undefined") {\r
15654         // Prefer window over self for add-on scripts. Use self for\r
15655         // non-windowed contexts.\r
15656         var global = typeof window !== "undefined" ? window : self;\r
15657 \r
15658         // Get the `window` object, save the previous Q global\r
15659         // and initialize Q as a global.\r
15660         var previousQ = global.Q;\r
15661         global.Q = definition();\r
15662 \r
15663         // Add a noConflict function so Q can be removed from the\r
15664         // global namespace.\r
15665         global.Q.noConflict = function () {\r
15666             global.Q = previousQ;\r
15667             return this;\r
15668         };\r
15669 \r
15670     } else {\r
15671         throw new Error("This environment was not anticipated by Q. Please file a bug.");\r
15672     }\r
15673 \r
15674 })(function () {\r
15675 "use strict";\r
15676 \r
15677 var hasStacks = false;\r
15678 try {\r
15679     throw new Error();\r
15680 } catch (e) {\r
15681     hasStacks = !!e.stack;\r
15682 }\r
15683 \r
15684 // All code after this point will be filtered from stack traces reported\r
15685 // by Q.\r
15686 var qStartingLine = captureLine();\r
15687 var qFileName;\r
15688 \r
15689 // shims\r
15690 \r
15691 // used for fallback in "allResolved"\r
15692 var noop = function () {};\r
15693 \r
15694 // Use the fastest possible means to execute a task in a future turn\r
15695 // of the event loop.\r
15696 var nextTick =(function () {\r
15697     // linked list of tasks (single, with head node)\r
15698     var head = {task: void 0, next: null};\r
15699     var tail = head;\r
15700     var flushing = false;\r
15701     var requestTick = void 0;\r
15702     var isNodeJS = false;\r
15703     // queue for late tasks, used by unhandled rejection tracking\r
15704     var laterQueue = [];\r
15705 \r
15706     function flush() {\r
15707         /* jshint loopfunc: true */\r
15708         var task, domain;\r
15709 \r
15710         while (head.next) {\r
15711             head = head.next;\r
15712             task = head.task;\r
15713             head.task = void 0;\r
15714             domain = head.domain;\r
15715 \r
15716             if (domain) {\r
15717                 head.domain = void 0;\r
15718                 domain.enter();\r
15719             }\r
15720             runSingle(task, domain);\r
15721 \r
15722         }\r
15723         while (laterQueue.length) {\r
15724             task = laterQueue.pop();\r
15725             runSingle(task);\r
15726         }\r
15727         flushing = false;\r
15728     }\r
15729     // runs a single function in the async queue\r
15730     function runSingle(task, domain) {\r
15731         try {\r
15732             task();\r
15733 \r
15734         } catch (e) {\r
15735             if (isNodeJS) {\r
15736                 // In node, uncaught exceptions are considered fatal errors.\r
15737                 // Re-throw them synchronously to interrupt flushing!\r
15738 \r
15739                 // Ensure continuation if the uncaught exception is suppressed\r
15740                 // listening "uncaughtException" events (as domains does).\r
15741                 // Continue in next event to avoid tick recursion.\r
15742                 if (domain) {\r
15743                     domain.exit();\r
15744                 }\r
15745                 setTimeout(flush, 0);\r
15746                 if (domain) {\r
15747                     domain.enter();\r
15748                 }\r
15749 \r
15750                 throw e;\r
15751 \r
15752             } else {\r
15753                 // In browsers, uncaught exceptions are not fatal.\r
15754                 // Re-throw them asynchronously to avoid slow-downs.\r
15755                 setTimeout(function () {\r
15756                     throw e;\r
15757                 }, 0);\r
15758             }\r
15759         }\r
15760 \r
15761         if (domain) {\r
15762             domain.exit();\r
15763         }\r
15764     }\r
15765 \r
15766     nextTick = function (task) {\r
15767         tail = tail.next = {\r
15768             task: task,\r
15769             domain: isNodeJS && process.domain,\r
15770             next: null\r
15771         };\r
15772 \r
15773         if (!flushing) {\r
15774             flushing = true;\r
15775             requestTick();\r
15776         }\r
15777     };\r
15778 \r
15779     if (typeof process === "object" &&\r
15780         process.toString() === "[object process]" && process.nextTick) {\r
15781         // Ensure Q is in a real Node environment, with a `process.nextTick`.\r
15782         // To see through fake Node environments:\r
15783         // * Mocha test runner - exposes a `process` global without a `nextTick`\r
15784         // * Browserify - exposes a `process.nexTick` function that uses\r
15785         //   `setTimeout`. In this case `setImmediate` is preferred because\r
15786         //    it is faster. Browserify's `process.toString()` yields\r
15787         //   "[object Object]", while in a real Node environment\r
15788         //   `process.nextTick()` yields "[object process]".\r
15789         isNodeJS = true;\r
15790 \r
15791         requestTick = function () {\r
15792             process.nextTick(flush);\r
15793         };\r
15794 \r
15795     } else if (typeof setImmediate === "function") {\r
15796         // In IE10, Node.js 0.9+, or https://github.com/NobleJS/setImmediate\r
15797         if (typeof window !== "undefined") {\r
15798             requestTick = setImmediate.bind(window, flush);\r
15799         } else {\r
15800             requestTick = function () {\r
15801                 setImmediate(flush);\r
15802             };\r
15803         }\r
15804 \r
15805     } else if (typeof MessageChannel !== "undefined") {\r
15806         // modern browsers\r
15807         // http://www.nonblocking.io/2011/06/windownexttick.html\r
15808         var channel = new MessageChannel();\r
15809         // At least Safari Version 6.0.5 (8536.30.1) intermittently cannot create\r
15810         // working message ports the first time a page loads.\r
15811         channel.port1.onmessage = function () {\r
15812             requestTick = requestPortTick;\r
15813             channel.port1.onmessage = flush;\r
15814             flush();\r
15815         };\r
15816         var requestPortTick = function () {\r
15817             // Opera requires us to provide a message payload, regardless of\r
15818             // whether we use it.\r
15819             channel.port2.postMessage(0);\r
15820         };\r
15821         requestTick = function () {\r
15822             setTimeout(flush, 0);\r
15823             requestPortTick();\r
15824         };\r
15825 \r
15826     } else {\r
15827         // old browsers\r
15828         requestTick = function () {\r
15829             setTimeout(flush, 0);\r
15830         };\r
15831     }\r
15832     // runs a task after all other tasks have been run\r
15833     // this is useful for unhandled rejection tracking that needs to happen\r
15834     // after all `then`d tasks have been run.\r
15835     nextTick.runAfter = function (task) {\r
15836         laterQueue.push(task);\r
15837         if (!flushing) {\r
15838             flushing = true;\r
15839             requestTick();\r
15840         }\r
15841     };\r
15842     return nextTick;\r
15843 })();\r
15844 \r
15845 // Attempt to make generics safe in the face of downstream\r
15846 // modifications.\r
15847 // There is no situation where this is necessary.\r
15848 // If you need a security guarantee, these primordials need to be\r
15849 // deeply frozen anyway, and if you don’t need a security guarantee,\r
15850 // this is just plain paranoid.\r
15851 // However, this **might** have the nice side-effect of reducing the size of\r
15852 // the minified code by reducing x.call() to merely x()\r
15853 // See Mark Miller’s explanation of what this does.\r
15854 // http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming\r
15855 var call = Function.call;\r
15856 function uncurryThis(f) {\r
15857     return function () {\r
15858         return call.apply(f, arguments);\r
15859     };\r
15860 }\r
15861 // This is equivalent, but slower:\r
15862 // uncurryThis = Function_bind.bind(Function_bind.call);\r
15863 // http://jsperf.com/uncurrythis\r
15864 \r
15865 var array_slice = uncurryThis(Array.prototype.slice);\r
15866 \r
15867 var array_reduce = uncurryThis(\r
15868     Array.prototype.reduce || function (callback, basis) {\r
15869         var index = 0,\r
15870             length = this.length;\r
15871         // concerning the initial value, if one is not provided\r
15872         if (arguments.length === 1) {\r
15873             // seek to the first value in the array, accounting\r
15874             // for the possibility that is is a sparse array\r
15875             do {\r
15876                 if (index in this) {\r
15877                     basis = this[index++];\r
15878                     break;\r
15879                 }\r
15880                 if (++index >= length) {\r
15881                     throw new TypeError();\r
15882                 }\r
15883             } while (1);\r
15884         }\r
15885         // reduce\r
15886         for (; index < length; index++) {\r
15887             // account for the possibility that the array is sparse\r
15888             if (index in this) {\r
15889                 basis = callback(basis, this[index], index);\r
15890             }\r
15891         }\r
15892         return basis;\r
15893     }\r
15894 );\r
15895 \r
15896 var array_indexOf = uncurryThis(\r
15897     Array.prototype.indexOf || function (value) {\r
15898         // not a very good shim, but good enough for our one use of it\r
15899         for (var i = 0; i < this.length; i++) {\r
15900             if (this[i] === value) {\r
15901                 return i;\r
15902             }\r
15903         }\r
15904         return -1;\r
15905     }\r
15906 );\r
15907 \r
15908 var array_map = uncurryThis(\r
15909     Array.prototype.map || function (callback, thisp) {\r
15910         var self = this;\r
15911         var collect = [];\r
15912         array_reduce(self, function (undefined, value, index) {\r
15913             collect.push(callback.call(thisp, value, index, self));\r
15914         }, void 0);\r
15915         return collect;\r
15916     }\r
15917 );\r
15918 \r
15919 var object_create = Object.create || function (prototype) {\r
15920     function Type() { }\r
15921     Type.prototype = prototype;\r
15922     return new Type();\r
15923 };\r
15924 \r
15925 var object_hasOwnProperty = uncurryThis(Object.prototype.hasOwnProperty);\r
15926 \r
15927 var object_keys = Object.keys || function (object) {\r
15928     var keys = [];\r
15929     for (var key in object) {\r
15930         if (object_hasOwnProperty(object, key)) {\r
15931             keys.push(key);\r
15932         }\r
15933     }\r
15934     return keys;\r
15935 };\r
15936 \r
15937 var object_toString = uncurryThis(Object.prototype.toString);\r
15938 \r
15939 function isObject(value) {\r
15940     return value === Object(value);\r
15941 }\r
15942 \r
15943 // generator related shims\r
15944 \r
15945 // FIXME: Remove this function once ES6 generators are in SpiderMonkey.\r
15946 function isStopIteration(exception) {\r
15947     return (\r
15948         object_toString(exception) === "[object StopIteration]" ||\r
15949         exception instanceof QReturnValue\r
15950     );\r
15951 }\r
15952 \r
15953 // FIXME: Remove this helper and Q.return once ES6 generators are in\r
15954 // SpiderMonkey.\r
15955 var QReturnValue;\r
15956 if (typeof ReturnValue !== "undefined") {\r
15957     QReturnValue = ReturnValue;\r
15958 } else {\r
15959     QReturnValue = function (value) {\r
15960         this.value = value;\r
15961     };\r
15962 }\r
15963 \r
15964 // long stack traces\r
15965 \r
15966 var STACK_JUMP_SEPARATOR = "From previous event:";\r
15967 \r
15968 function makeStackTraceLong(error, promise) {\r
15969     // If possible, transform the error stack trace by removing Node and Q\r
15970     // cruft, then concatenating with the stack trace of `promise`. See #57.\r
15971     if (hasStacks &&\r
15972         promise.stack &&\r
15973         typeof error === "object" &&\r
15974         error !== null &&\r
15975         error.stack &&\r
15976         error.stack.indexOf(STACK_JUMP_SEPARATOR) === -1\r
15977     ) {\r
15978         var stacks = [];\r
15979         for (var p = promise; !!p; p = p.source) {\r
15980             if (p.stack) {\r
15981                 stacks.unshift(p.stack);\r
15982             }\r
15983         }\r
15984         stacks.unshift(error.stack);\r
15985 \r
15986         var concatedStacks = stacks.join("\n" + STACK_JUMP_SEPARATOR + "\n");\r
15987         error.stack = filterStackString(concatedStacks);\r
15988     }\r
15989 }\r
15990 \r
15991 function filterStackString(stackString) {\r
15992     var lines = stackString.split("\n");\r
15993     var desiredLines = [];\r
15994     for (var i = 0; i < lines.length; ++i) {\r
15995         var line = lines[i];\r
15996 \r
15997         if (!isInternalFrame(line) && !isNodeFrame(line) && line) {\r
15998             desiredLines.push(line);\r
15999         }\r
16000     }\r
16001     return desiredLines.join("\n");\r
16002 }\r
16003 \r
16004 function isNodeFrame(stackLine) {\r
16005     return stackLine.indexOf("(module.js:") !== -1 ||\r
16006            stackLine.indexOf("(node.js:") !== -1;\r
16007 }\r
16008 \r
16009 function getFileNameAndLineNumber(stackLine) {\r
16010     // Named functions: "at functionName (filename:lineNumber:columnNumber)"\r
16011     // In IE10 function name can have spaces ("Anonymous function") O_o\r
16012     var attempt1 = /at .+ \((.+):(\d+):(?:\d+)\)$/.exec(stackLine);\r
16013     if (attempt1) {\r
16014         return [attempt1[1], Number(attempt1[2])];\r
16015     }\r
16016 \r
16017     // Anonymous functions: "at filename:lineNumber:columnNumber"\r
16018     var attempt2 = /at ([^ ]+):(\d+):(?:\d+)$/.exec(stackLine);\r
16019     if (attempt2) {\r
16020         return [attempt2[1], Number(attempt2[2])];\r
16021     }\r
16022 \r
16023     // Firefox style: "function@filename:lineNumber or @filename:lineNumber"\r
16024     var attempt3 = /.*@(.+):(\d+)$/.exec(stackLine);\r
16025     if (attempt3) {\r
16026         return [attempt3[1], Number(attempt3[2])];\r
16027     }\r
16028 }\r
16029 \r
16030 function isInternalFrame(stackLine) {\r
16031     var fileNameAndLineNumber = getFileNameAndLineNumber(stackLine);\r
16032 \r
16033     if (!fileNameAndLineNumber) {\r
16034         return false;\r
16035     }\r
16036 \r
16037     var fileName = fileNameAndLineNumber[0];\r
16038     var lineNumber = fileNameAndLineNumber[1];\r
16039 \r
16040     return fileName === qFileName &&\r
16041         lineNumber >= qStartingLine &&\r
16042         lineNumber <= qEndingLine;\r
16043 }\r
16044 \r
16045 // discover own file name and line number range for filtering stack\r
16046 // traces\r
16047 function captureLine() {\r
16048     if (!hasStacks) {\r
16049         return;\r
16050     }\r
16051 \r
16052     try {\r
16053         throw new Error();\r
16054     } catch (e) {\r
16055         var lines = e.stack.split("\n");\r
16056         var firstLine = lines[0].indexOf("@") > 0 ? lines[1] : lines[2];\r
16057         var fileNameAndLineNumber = getFileNameAndLineNumber(firstLine);\r
16058         if (!fileNameAndLineNumber) {\r
16059             return;\r
16060         }\r
16061 \r
16062         qFileName = fileNameAndLineNumber[0];\r
16063         return fileNameAndLineNumber[1];\r
16064     }\r
16065 }\r
16066 \r
16067 function deprecate(callback, name, alternative) {\r
16068     return function () {\r
16069         if (typeof console !== "undefined" &&\r
16070             typeof console.warn === "function") {\r
16071             console.warn(name + " is deprecated, use " + alternative +\r
16072                          " instead.", new Error("").stack);\r
16073         }\r
16074         return callback.apply(callback, arguments);\r
16075     };\r
16076 }\r
16077 \r
16078 // end of shims\r
16079 // beginning of real work\r
16080 \r
16081 /**\r
16082  * Constructs a promise for an immediate reference, passes promises through, or\r
16083  * coerces promises from different systems.\r
16084  * @param value immediate reference or promise\r
16085  */\r
16086 function Q(value) {\r
16087     // If the object is already a Promise, return it directly.  This enables\r
16088     // the resolve function to both be used to created references from objects,\r
16089     // but to tolerably coerce non-promises to promises.\r
16090     if (value instanceof Promise) {\r
16091         return value;\r
16092     }\r
16093 \r
16094     // assimilate thenables\r
16095     if (isPromiseAlike(value)) {\r
16096         return coerce(value);\r
16097     } else {\r
16098         return fulfill(value);\r
16099     }\r
16100 }\r
16101 Q.resolve = Q;\r
16102 \r
16103 /**\r
16104  * Performs a task in a future turn of the event loop.\r
16105  * @param {Function} task\r
16106  */\r
16107 Q.nextTick = nextTick;\r
16108 \r
16109 /**\r
16110  * Controls whether or not long stack traces will be on\r
16111  */\r
16112 Q.longStackSupport = false;\r
16113 \r
16114 // enable long stacks if Q_DEBUG is set\r
16115 if (typeof process === "object" && process && process.env && process.env.Q_DEBUG) {\r
16116     Q.longStackSupport = true;\r
16117 }\r
16118 \r
16119 /**\r
16120  * Constructs a {promise, resolve, reject} object.\r
16121  *\r
16122  * `resolve` is a callback to invoke with a more resolved value for the\r
16123  * promise. To fulfill the promise, invoke `resolve` with any value that is\r
16124  * not a thenable. To reject the promise, invoke `resolve` with a rejected\r
16125  * thenable, or invoke `reject` with the reason directly. To resolve the\r
16126  * promise to another thenable, thus putting it in the same state, invoke\r
16127  * `resolve` with that other thenable.\r
16128  */\r
16129 Q.defer = defer;\r
16130 function defer() {\r
16131     // if "messages" is an "Array", that indicates that the promise has not yet\r
16132     // been resolved.  If it is "undefined", it has been resolved.  Each\r
16133     // element of the messages array is itself an array of complete arguments to\r
16134     // forward to the resolved promise.  We coerce the resolution value to a\r
16135     // promise using the `resolve` function because it handles both fully\r
16136     // non-thenable values and other thenables gracefully.\r
16137     var messages = [], progressListeners = [], resolvedPromise;\r
16138 \r
16139     var deferred = object_create(defer.prototype);\r
16140     var promise = object_create(Promise.prototype);\r
16141 \r
16142     promise.promiseDispatch = function (resolve, op, operands) {\r
16143         var args = array_slice(arguments);\r
16144         if (messages) {\r
16145             messages.push(args);\r
16146             if (op === "when" && operands[1]) { // progress operand\r
16147                 progressListeners.push(operands[1]);\r
16148             }\r
16149         } else {\r
16150             Q.nextTick(function () {\r
16151                 resolvedPromise.promiseDispatch.apply(resolvedPromise, args);\r
16152             });\r
16153         }\r
16154     };\r
16155 \r
16156     // XXX deprecated\r
16157     promise.valueOf = function () {\r
16158         if (messages) {\r
16159             return promise;\r
16160         }\r
16161         var nearerValue = nearer(resolvedPromise);\r
16162         if (isPromise(nearerValue)) {\r
16163             resolvedPromise = nearerValue; // shorten chain\r
16164         }\r
16165         return nearerValue;\r
16166     };\r
16167 \r
16168     promise.inspect = function () {\r
16169         if (!resolvedPromise) {\r
16170             return { state: "pending" };\r
16171         }\r
16172         return resolvedPromise.inspect();\r
16173     };\r
16174 \r
16175     if (Q.longStackSupport && hasStacks) {\r
16176         try {\r
16177             throw new Error();\r
16178         } catch (e) {\r
16179             // NOTE: don't try to use `Error.captureStackTrace` or transfer the\r
16180             // accessor around; that causes memory leaks as per GH-111. Just\r
16181             // reify the stack trace as a string ASAP.\r
16182             //\r
16183             // At the same time, cut off the first line; it's always just\r
16184             // "[object Promise]\n", as per the `toString`.\r
16185             promise.stack = e.stack.substring(e.stack.indexOf("\n") + 1);\r
16186         }\r
16187     }\r
16188 \r
16189     // NOTE: we do the checks for `resolvedPromise` in each method, instead of\r
16190     // consolidating them into `become`, since otherwise we'd create new\r
16191     // promises with the lines `become(whatever(value))`. See e.g. GH-252.\r
16192 \r
16193     function become(newPromise) {\r
16194         resolvedPromise = newPromise;\r
16195         promise.source = newPromise;\r
16196 \r
16197         array_reduce(messages, function (undefined, message) {\r
16198             Q.nextTick(function () {\r
16199                 newPromise.promiseDispatch.apply(newPromise, message);\r
16200             });\r
16201         }, void 0);\r
16202 \r
16203         messages = void 0;\r
16204         progressListeners = void 0;\r
16205     }\r
16206 \r
16207     deferred.promise = promise;\r
16208     deferred.resolve = function (value) {\r
16209         if (resolvedPromise) {\r
16210             return;\r
16211         }\r
16212 \r
16213         become(Q(value));\r
16214     };\r
16215 \r
16216     deferred.fulfill = function (value) {\r
16217         if (resolvedPromise) {\r
16218             return;\r
16219         }\r
16220 \r
16221         become(fulfill(value));\r
16222     };\r
16223     deferred.reject = function (reason) {\r
16224         if (resolvedPromise) {\r
16225             return;\r
16226         }\r
16227 \r
16228         become(reject(reason));\r
16229     };\r
16230     deferred.notify = function (progress) {\r
16231         if (resolvedPromise) {\r
16232             return;\r
16233         }\r
16234 \r
16235         array_reduce(progressListeners, function (undefined, progressListener) {\r
16236             Q.nextTick(function () {\r
16237                 progressListener(progress);\r
16238             });\r
16239         }, void 0);\r
16240     };\r
16241 \r
16242     return deferred;\r
16243 }\r
16244 \r
16245 /**\r
16246  * Creates a Node-style callback that will resolve or reject the deferred\r
16247  * promise.\r
16248  * @returns a nodeback\r
16249  */\r
16250 defer.prototype.makeNodeResolver = function () {\r
16251     var self = this;\r
16252     return function (error, value) {\r
16253         if (error) {\r
16254             self.reject(error);\r
16255         } else if (arguments.length > 2) {\r
16256             self.resolve(array_slice(arguments, 1));\r
16257         } else {\r
16258             self.resolve(value);\r
16259         }\r
16260     };\r
16261 };\r
16262 \r
16263 /**\r
16264  * @param resolver {Function} a function that returns nothing and accepts\r
16265  * the resolve, reject, and notify functions for a deferred.\r
16266  * @returns a promise that may be resolved with the given resolve and reject\r
16267  * functions, or rejected by a thrown exception in resolver\r
16268  */\r
16269 Q.Promise = promise; // ES6\r
16270 Q.promise = promise;\r
16271 function promise(resolver) {\r
16272     if (typeof resolver !== "function") {\r
16273         throw new TypeError("resolver must be a function.");\r
16274     }\r
16275     var deferred = defer();\r
16276     try {\r
16277         resolver(deferred.resolve, deferred.reject, deferred.notify);\r
16278     } catch (reason) {\r
16279         deferred.reject(reason);\r
16280     }\r
16281     return deferred.promise;\r
16282 }\r
16283 \r
16284 promise.race = race; // ES6\r
16285 promise.all = all; // ES6\r
16286 promise.reject = reject; // ES6\r
16287 promise.resolve = Q; // ES6\r
16288 \r
16289 // XXX experimental.  This method is a way to denote that a local value is\r
16290 // serializable and should be immediately dispatched to a remote upon request,\r
16291 // instead of passing a reference.\r
16292 Q.passByCopy = function (object) {\r
16293     //freeze(object);\r
16294     //passByCopies.set(object, true);\r
16295     return object;\r
16296 };\r
16297 \r
16298 Promise.prototype.passByCopy = function () {\r
16299     //freeze(object);\r
16300     //passByCopies.set(object, true);\r
16301     return this;\r
16302 };\r
16303 \r
16304 /**\r
16305  * If two promises eventually fulfill to the same value, promises that value,\r
16306  * but otherwise rejects.\r
16307  * @param x {Any*}\r
16308  * @param y {Any*}\r
16309  * @returns {Any*} a promise for x and y if they are the same, but a rejection\r
16310  * otherwise.\r
16311  *\r
16312  */\r
16313 Q.join = function (x, y) {\r
16314     return Q(x).join(y);\r
16315 };\r
16316 \r
16317 Promise.prototype.join = function (that) {\r
16318     return Q([this, that]).spread(function (x, y) {\r
16319         if (x === y) {\r
16320             // TODO: "===" should be Object.is or equiv\r
16321             return x;\r
16322         } else {\r
16323             throw new Error("Can't join: not the same: " + x + " " + y);\r
16324         }\r
16325     });\r
16326 };\r
16327 \r
16328 /**\r
16329  * Returns a promise for the first of an array of promises to become settled.\r
16330  * @param answers {Array[Any*]} promises to race\r
16331  * @returns {Any*} the first promise to be settled\r
16332  */\r
16333 Q.race = race;\r
16334 function race(answerPs) {\r
16335     return promise(function (resolve, reject) {\r
16336         // Switch to this once we can assume at least ES5\r
16337         // answerPs.forEach(function (answerP) {\r
16338         //     Q(answerP).then(resolve, reject);\r
16339         // });\r
16340         // Use this in the meantime\r
16341         for (var i = 0, len = answerPs.length; i < len; i++) {\r
16342             Q(answerPs[i]).then(resolve, reject);\r
16343         }\r
16344     });\r
16345 }\r
16346 \r
16347 Promise.prototype.race = function () {\r
16348     return this.then(Q.race);\r
16349 };\r
16350 \r
16351 /**\r
16352  * Constructs a Promise with a promise descriptor object and optional fallback\r
16353  * function.  The descriptor contains methods like when(rejected), get(name),\r
16354  * set(name, value), post(name, args), and delete(name), which all\r
16355  * return either a value, a promise for a value, or a rejection.  The fallback\r
16356  * accepts the operation name, a resolver, and any further arguments that would\r
16357  * have been forwarded to the appropriate method above had a method been\r
16358  * provided with the proper name.  The API makes no guarantees about the nature\r
16359  * of the returned object, apart from that it is usable whereever promises are\r
16360  * bought and sold.\r
16361  */\r
16362 Q.makePromise = Promise;\r
16363 function Promise(descriptor, fallback, inspect) {\r
16364     if (fallback === void 0) {\r
16365         fallback = function (op) {\r
16366             return reject(new Error(\r
16367                 "Promise does not support operation: " + op\r
16368             ));\r
16369         };\r
16370     }\r
16371     if (inspect === void 0) {\r
16372         inspect = function () {\r
16373             return {state: "unknown"};\r
16374         };\r
16375     }\r
16376 \r
16377     var promise = object_create(Promise.prototype);\r
16378 \r
16379     promise.promiseDispatch = function (resolve, op, args) {\r
16380         var result;\r
16381         try {\r
16382             if (descriptor[op]) {\r
16383                 result = descriptor[op].apply(promise, args);\r
16384             } else {\r
16385                 result = fallback.call(promise, op, args);\r
16386             }\r
16387         } catch (exception) {\r
16388             result = reject(exception);\r
16389         }\r
16390         if (resolve) {\r
16391             resolve(result);\r
16392         }\r
16393     };\r
16394 \r
16395     promise.inspect = inspect;\r
16396 \r
16397     // XXX deprecated `valueOf` and `exception` support\r
16398     if (inspect) {\r
16399         var inspected = inspect();\r
16400         if (inspected.state === "rejected") {\r
16401             promise.exception = inspected.reason;\r
16402         }\r
16403 \r
16404         promise.valueOf = function () {\r
16405             var inspected = inspect();\r
16406             if (inspected.state === "pending" ||\r
16407                 inspected.state === "rejected") {\r
16408                 return promise;\r
16409             }\r
16410             return inspected.value;\r
16411         };\r
16412     }\r
16413 \r
16414     return promise;\r
16415 }\r
16416 \r
16417 Promise.prototype.toString = function () {\r
16418     return "[object Promise]";\r
16419 };\r
16420 \r
16421 Promise.prototype.then = function (fulfilled, rejected, progressed) {\r
16422     var self = this;\r
16423     var deferred = defer();\r
16424     var done = false;   // ensure the untrusted promise makes at most a\r
16425                         // single call to one of the callbacks\r
16426 \r
16427     function _fulfilled(value) {\r
16428         try {\r
16429             return typeof fulfilled === "function" ? fulfilled(value) : value;\r
16430         } catch (exception) {\r
16431             return reject(exception);\r
16432         }\r
16433     }\r
16434 \r
16435     function _rejected(exception) {\r
16436         if (typeof rejected === "function") {\r
16437             makeStackTraceLong(exception, self);\r
16438             try {\r
16439                 return rejected(exception);\r
16440             } catch (newException) {\r
16441                 return reject(newException);\r
16442             }\r
16443         }\r
16444         return reject(exception);\r
16445     }\r
16446 \r
16447     function _progressed(value) {\r
16448         return typeof progressed === "function" ? progressed(value) : value;\r
16449     }\r
16450 \r
16451     Q.nextTick(function () {\r
16452         self.promiseDispatch(function (value) {\r
16453             if (done) {\r
16454                 return;\r
16455             }\r
16456             done = true;\r
16457 \r
16458             deferred.resolve(_fulfilled(value));\r
16459         }, "when", [function (exception) {\r
16460             if (done) {\r
16461                 return;\r
16462             }\r
16463             done = true;\r
16464 \r
16465             deferred.resolve(_rejected(exception));\r
16466         }]);\r
16467     });\r
16468 \r
16469     // Progress propagator need to be attached in the current tick.\r
16470     self.promiseDispatch(void 0, "when", [void 0, function (value) {\r
16471         var newValue;\r
16472         var threw = false;\r
16473         try {\r
16474             newValue = _progressed(value);\r
16475         } catch (e) {\r
16476             threw = true;\r
16477             if (Q.onerror) {\r
16478                 Q.onerror(e);\r
16479             } else {\r
16480                 throw e;\r
16481             }\r
16482         }\r
16483 \r
16484         if (!threw) {\r
16485             deferred.notify(newValue);\r
16486         }\r
16487     }]);\r
16488 \r
16489     return deferred.promise;\r
16490 };\r
16491 \r
16492 Q.tap = function (promise, callback) {\r
16493     return Q(promise).tap(callback);\r
16494 };\r
16495 \r
16496 /**\r
16497  * Works almost like "finally", but not called for rejections.\r
16498  * Original resolution value is passed through callback unaffected.\r
16499  * Callback may return a promise that will be awaited for.\r
16500  * @param {Function} callback\r
16501  * @returns {Q.Promise}\r
16502  * @example\r
16503  * doSomething()\r
16504  *   .then(...)\r
16505  *   .tap(console.log)\r
16506  *   .then(...);\r
16507  */\r
16508 Promise.prototype.tap = function (callback) {\r
16509     callback = Q(callback);\r
16510 \r
16511     return this.then(function (value) {\r
16512         return callback.fcall(value).thenResolve(value);\r
16513     });\r
16514 };\r
16515 \r
16516 /**\r
16517  * Registers an observer on a promise.\r
16518  *\r
16519  * Guarantees:\r
16520  *\r
16521  * 1. that fulfilled and rejected will be called only once.\r
16522  * 2. that either the fulfilled callback or the rejected callback will be\r
16523  *    called, but not both.\r
16524  * 3. that fulfilled and rejected will not be called in this turn.\r
16525  *\r
16526  * @param value      promise or immediate reference to observe\r
16527  * @param fulfilled  function to be called with the fulfilled value\r
16528  * @param rejected   function to be called with the rejection exception\r
16529  * @param progressed function to be called on any progress notifications\r
16530  * @return promise for the return value from the invoked callback\r
16531  */\r
16532 Q.when = when;\r
16533 function when(value, fulfilled, rejected, progressed) {\r
16534     return Q(value).then(fulfilled, rejected, progressed);\r
16535 }\r
16536 \r
16537 Promise.prototype.thenResolve = function (value) {\r
16538     return this.then(function () { return value; });\r
16539 };\r
16540 \r
16541 Q.thenResolve = function (promise, value) {\r
16542     return Q(promise).thenResolve(value);\r
16543 };\r
16544 \r
16545 Promise.prototype.thenReject = function (reason) {\r
16546     return this.then(function () { throw reason; });\r
16547 };\r
16548 \r
16549 Q.thenReject = function (promise, reason) {\r
16550     return Q(promise).thenReject(reason);\r
16551 };\r
16552 \r
16553 /**\r
16554  * If an object is not a promise, it is as "near" as possible.\r
16555  * If a promise is rejected, it is as "near" as possible too.\r
16556  * If it’s a fulfilled promise, the fulfillment value is nearer.\r
16557  * If it’s a deferred promise and the deferred has been resolved, the\r
16558  * resolution is "nearer".\r
16559  * @param object\r
16560  * @returns most resolved (nearest) form of the object\r
16561  */\r
16562 \r
16563 // XXX should we re-do this?\r
16564 Q.nearer = nearer;\r
16565 function nearer(value) {\r
16566     if (isPromise(value)) {\r
16567         var inspected = value.inspect();\r
16568         if (inspected.state === "fulfilled") {\r
16569             return inspected.value;\r
16570         }\r
16571     }\r
16572     return value;\r
16573 }\r
16574 \r
16575 /**\r
16576  * @returns whether the given object is a promise.\r
16577  * Otherwise it is a fulfilled value.\r
16578  */\r
16579 Q.isPromise = isPromise;\r
16580 function isPromise(object) {\r
16581     return object instanceof Promise;\r
16582 }\r
16583 \r
16584 Q.isPromiseAlike = isPromiseAlike;\r
16585 function isPromiseAlike(object) {\r
16586     return isObject(object) && typeof object.then === "function";\r
16587 }\r
16588 \r
16589 /**\r
16590  * @returns whether the given object is a pending promise, meaning not\r
16591  * fulfilled or rejected.\r
16592  */\r
16593 Q.isPending = isPending;\r
16594 function isPending(object) {\r
16595     return isPromise(object) && object.inspect().state === "pending";\r
16596 }\r
16597 \r
16598 Promise.prototype.isPending = function () {\r
16599     return this.inspect().state === "pending";\r
16600 };\r
16601 \r
16602 /**\r
16603  * @returns whether the given object is a value or fulfilled\r
16604  * promise.\r
16605  */\r
16606 Q.isFulfilled = isFulfilled;\r
16607 function isFulfilled(object) {\r
16608     return !isPromise(object) || object.inspect().state === "fulfilled";\r
16609 }\r
16610 \r
16611 Promise.prototype.isFulfilled = function () {\r
16612     return this.inspect().state === "fulfilled";\r
16613 };\r
16614 \r
16615 /**\r
16616  * @returns whether the given object is a rejected promise.\r
16617  */\r
16618 Q.isRejected = isRejected;\r
16619 function isRejected(object) {\r
16620     return isPromise(object) && object.inspect().state === "rejected";\r
16621 }\r
16622 \r
16623 Promise.prototype.isRejected = function () {\r
16624     return this.inspect().state === "rejected";\r
16625 };\r
16626 \r
16627 //// BEGIN UNHANDLED REJECTION TRACKING\r
16628 \r
16629 // This promise library consumes exceptions thrown in handlers so they can be\r
16630 // handled by a subsequent promise.  The exceptions get added to this array when\r
16631 // they are created, and removed when they are handled.  Note that in ES6 or\r
16632 // shimmed environments, this would naturally be a `Set`.\r
16633 var unhandledReasons = [];\r
16634 var unhandledRejections = [];\r
16635 var reportedUnhandledRejections = [];\r
16636 var trackUnhandledRejections = true;\r
16637 \r
16638 function resetUnhandledRejections() {\r
16639     unhandledReasons.length = 0;\r
16640     unhandledRejections.length = 0;\r
16641 \r
16642     if (!trackUnhandledRejections) {\r
16643         trackUnhandledRejections = true;\r
16644     }\r
16645 }\r
16646 \r
16647 function trackRejection(promise, reason) {\r
16648     if (!trackUnhandledRejections) {\r
16649         return;\r
16650     }\r
16651     if (typeof process === "object" && typeof process.emit === "function") {\r
16652         Q.nextTick.runAfter(function () {\r
16653             if (array_indexOf(unhandledRejections, promise) !== -1) {\r
16654                 process.emit("unhandledRejection", reason, promise);\r
16655                 reportedUnhandledRejections.push(promise);\r
16656             }\r
16657         });\r
16658     }\r
16659 \r
16660     unhandledRejections.push(promise);\r
16661     if (reason && typeof reason.stack !== "undefined") {\r
16662         unhandledReasons.push(reason.stack);\r
16663     } else {\r
16664         unhandledReasons.push("(no stack) " + reason);\r
16665     }\r
16666 }\r
16667 \r
16668 function untrackRejection(promise) {\r
16669     if (!trackUnhandledRejections) {\r
16670         return;\r
16671     }\r
16672 \r
16673     var at = array_indexOf(unhandledRejections, promise);\r
16674     if (at !== -1) {\r
16675         if (typeof process === "object" && typeof process.emit === "function") {\r
16676             Q.nextTick.runAfter(function () {\r
16677                 var atReport = array_indexOf(reportedUnhandledRejections, promise);\r
16678                 if (atReport !== -1) {\r
16679                     process.emit("rejectionHandled", unhandledReasons[at], promise);\r
16680                     reportedUnhandledRejections.splice(atReport, 1);\r
16681                 }\r
16682             });\r
16683         }\r
16684         unhandledRejections.splice(at, 1);\r
16685         unhandledReasons.splice(at, 1);\r
16686     }\r
16687 }\r
16688 \r
16689 Q.resetUnhandledRejections = resetUnhandledRejections;\r
16690 \r
16691 Q.getUnhandledReasons = function () {\r
16692     // Make a copy so that consumers can't interfere with our internal state.\r
16693     return unhandledReasons.slice();\r
16694 };\r
16695 \r
16696 Q.stopUnhandledRejectionTracking = function () {\r
16697     resetUnhandledRejections();\r
16698     trackUnhandledRejections = false;\r
16699 };\r
16700 \r
16701 resetUnhandledRejections();\r
16702 \r
16703 //// END UNHANDLED REJECTION TRACKING\r
16704 \r
16705 /**\r
16706  * Constructs a rejected promise.\r
16707  * @param reason value describing the failure\r
16708  */\r
16709 Q.reject = reject;\r
16710 function reject(reason) {\r
16711     var rejection = Promise({\r
16712         "when": function (rejected) {\r
16713             // note that the error has been handled\r
16714             if (rejected) {\r
16715                 untrackRejection(this);\r
16716             }\r
16717             return rejected ? rejected(reason) : this;\r
16718         }\r
16719     }, function fallback() {\r
16720         return this;\r
16721     }, function inspect() {\r
16722         return { state: "rejected", reason: reason };\r
16723     });\r
16724 \r
16725     // Note that the reason has not been handled.\r
16726     trackRejection(rejection, reason);\r
16727 \r
16728     return rejection;\r
16729 }\r
16730 \r
16731 /**\r
16732  * Constructs a fulfilled promise for an immediate reference.\r
16733  * @param value immediate reference\r
16734  */\r
16735 Q.fulfill = fulfill;\r
16736 function fulfill(value) {\r
16737     return Promise({\r
16738         "when": function () {\r
16739             return value;\r
16740         },\r
16741         "get": function (name) {\r
16742             return value[name];\r
16743         },\r
16744         "set": function (name, rhs) {\r
16745             value[name] = rhs;\r
16746         },\r
16747         "delete": function (name) {\r
16748             delete value[name];\r
16749         },\r
16750         "post": function (name, args) {\r
16751             // Mark Miller proposes that post with no name should apply a\r
16752             // promised function.\r
16753             if (name === null || name === void 0) {\r
16754                 return value.apply(void 0, args);\r
16755             } else {\r
16756                 return value[name].apply(value, args);\r
16757             }\r
16758         },\r
16759         "apply": function (thisp, args) {\r
16760             return value.apply(thisp, args);\r
16761         },\r
16762         "keys": function () {\r
16763             return object_keys(value);\r
16764         }\r
16765     }, void 0, function inspect() {\r
16766         return { state: "fulfilled", value: value };\r
16767     });\r
16768 }\r
16769 \r
16770 /**\r
16771  * Converts thenables to Q promises.\r
16772  * @param promise thenable promise\r
16773  * @returns a Q promise\r
16774  */\r
16775 function coerce(promise) {\r
16776     var deferred = defer();\r
16777     Q.nextTick(function () {\r
16778         try {\r
16779             promise.then(deferred.resolve, deferred.reject, deferred.notify);\r
16780         } catch (exception) {\r
16781             deferred.reject(exception);\r
16782         }\r
16783     });\r
16784     return deferred.promise;\r
16785 }\r
16786 \r
16787 /**\r
16788  * Annotates an object such that it will never be\r
16789  * transferred away from this process over any promise\r
16790  * communication channel.\r
16791  * @param object\r
16792  * @returns promise a wrapping of that object that\r
16793  * additionally responds to the "isDef" message\r
16794  * without a rejection.\r
16795  */\r
16796 Q.master = master;\r
16797 function master(object) {\r
16798     return Promise({\r
16799         "isDef": function () {}\r
16800     }, function fallback(op, args) {\r
16801         return dispatch(object, op, args);\r
16802     }, function () {\r
16803         return Q(object).inspect();\r
16804     });\r
16805 }\r
16806 \r
16807 /**\r
16808  * Spreads the values of a promised array of arguments into the\r
16809  * fulfillment callback.\r
16810  * @param fulfilled callback that receives variadic arguments from the\r
16811  * promised array\r
16812  * @param rejected callback that receives the exception if the promise\r
16813  * is rejected.\r
16814  * @returns a promise for the return value or thrown exception of\r
16815  * either callback.\r
16816  */\r
16817 Q.spread = spread;\r
16818 function spread(value, fulfilled, rejected) {\r
16819     return Q(value).spread(fulfilled, rejected);\r
16820 }\r
16821 \r
16822 Promise.prototype.spread = function (fulfilled, rejected) {\r
16823     return this.all().then(function (array) {\r
16824         return fulfilled.apply(void 0, array);\r
16825     }, rejected);\r
16826 };\r
16827 \r
16828 /**\r
16829  * The async function is a decorator for generator functions, turning\r
16830  * them into asynchronous generators.  Although generators are only part\r
16831  * of the newest ECMAScript 6 drafts, this code does not cause syntax\r
16832  * errors in older engines.  This code should continue to work and will\r
16833  * in fact improve over time as the language improves.\r
16834  *\r
16835  * ES6 generators are currently part of V8 version 3.19 with the\r
16836  * --harmony-generators runtime flag enabled.  SpiderMonkey has had them\r
16837  * for longer, but under an older Python-inspired form.  This function\r
16838  * works on both kinds of generators.\r
16839  *\r
16840  * Decorates a generator function such that:\r
16841  *  - it may yield promises\r
16842  *  - execution will continue when that promise is fulfilled\r
16843  *  - the value of the yield expression will be the fulfilled value\r
16844  *  - it returns a promise for the return value (when the generator\r
16845  *    stops iterating)\r
16846  *  - the decorated function returns a promise for the return value\r
16847  *    of the generator or the first rejected promise among those\r
16848  *    yielded.\r
16849  *  - if an error is thrown in the generator, it propagates through\r
16850  *    every following yield until it is caught, or until it escapes\r
16851  *    the generator function altogether, and is translated into a\r
16852  *    rejection for the promise returned by the decorated generator.\r
16853  */\r
16854 Q.async = async;\r
16855 function async(makeGenerator) {\r
16856     return function () {\r
16857         // when verb is "send", arg is a value\r
16858         // when verb is "throw", arg is an exception\r
16859         function continuer(verb, arg) {\r
16860             var result;\r
16861 \r
16862             // Until V8 3.19 / Chromium 29 is released, SpiderMonkey is the only\r
16863             // engine that has a deployed base of browsers that support generators.\r
16864             // However, SM's generators use the Python-inspired semantics of\r
16865             // outdated ES6 drafts.  We would like to support ES6, but we'd also\r
16866             // like to make it possible to use generators in deployed browsers, so\r
16867             // we also support Python-style generators.  At some point we can remove\r
16868             // this block.\r
16869 \r
16870             if (typeof StopIteration === "undefined") {\r
16871                 // ES6 Generators\r
16872                 try {\r
16873                     result = generator[verb](arg);\r
16874                 } catch (exception) {\r
16875                     return reject(exception);\r
16876                 }\r
16877                 if (result.done) {\r
16878                     return Q(result.value);\r
16879                 } else {\r
16880                     return when(result.value, callback, errback);\r
16881                 }\r
16882             } else {\r
16883                 // SpiderMonkey Generators\r
16884                 // FIXME: Remove this case when SM does ES6 generators.\r
16885                 try {\r
16886                     result = generator[verb](arg);\r
16887                 } catch (exception) {\r
16888                     if (isStopIteration(exception)) {\r
16889                         return Q(exception.value);\r
16890                     } else {\r
16891                         return reject(exception);\r
16892                     }\r
16893                 }\r
16894                 return when(result, callback, errback);\r
16895             }\r
16896         }\r
16897         var generator = makeGenerator.apply(this, arguments);\r
16898         var callback = continuer.bind(continuer, "next");\r
16899         var errback = continuer.bind(continuer, "throw");\r
16900         return callback();\r
16901     };\r
16902 }\r
16903 \r
16904 /**\r
16905  * The spawn function is a small wrapper around async that immediately\r
16906  * calls the generator and also ends the promise chain, so that any\r
16907  * unhandled errors are thrown instead of forwarded to the error\r
16908  * handler. This is useful because it's extremely common to run\r
16909  * generators at the top-level to work with libraries.\r
16910  */\r
16911 Q.spawn = spawn;\r
16912 function spawn(makeGenerator) {\r
16913     Q.done(Q.async(makeGenerator)());\r
16914 }\r
16915 \r
16916 // FIXME: Remove this interface once ES6 generators are in SpiderMonkey.\r
16917 /**\r
16918  * Throws a ReturnValue exception to stop an asynchronous generator.\r
16919  *\r
16920  * This interface is a stop-gap measure to support generator return\r
16921  * values in older Firefox/SpiderMonkey.  In browsers that support ES6\r
16922  * generators like Chromium 29, just use "return" in your generator\r
16923  * functions.\r
16924  *\r
16925  * @param value the return value for the surrounding generator\r
16926  * @throws ReturnValue exception with the value.\r
16927  * @example\r
16928  * // ES6 style\r
16929  * Q.async(function* () {\r
16930  *      var foo = yield getFooPromise();\r
16931  *      var bar = yield getBarPromise();\r
16932  *      return foo + bar;\r
16933  * })\r
16934  * // Older SpiderMonkey style\r
16935  * Q.async(function () {\r
16936  *      var foo = yield getFooPromise();\r
16937  *      var bar = yield getBarPromise();\r
16938  *      Q.return(foo + bar);\r
16939  * })\r
16940  */\r
16941 Q["return"] = _return;\r
16942 function _return(value) {\r
16943     throw new QReturnValue(value);\r
16944 }\r
16945 \r
16946 /**\r
16947  * The promised function decorator ensures that any promise arguments\r
16948  * are settled and passed as values (`this` is also settled and passed\r
16949  * as a value).  It will also ensure that the result of a function is\r
16950  * always a promise.\r
16951  *\r
16952  * @example\r
16953  * var add = Q.promised(function (a, b) {\r
16954  *     return a + b;\r
16955  * });\r
16956  * add(Q(a), Q(B));\r
16957  *\r
16958  * @param {function} callback The function to decorate\r
16959  * @returns {function} a function that has been decorated.\r
16960  */\r
16961 Q.promised = promised;\r
16962 function promised(callback) {\r
16963     return function () {\r
16964         return spread([this, all(arguments)], function (self, args) {\r
16965             return callback.apply(self, args);\r
16966         });\r
16967     };\r
16968 }\r
16969 \r
16970 /**\r
16971  * sends a message to a value in a future turn\r
16972  * @param object* the recipient\r
16973  * @param op the name of the message operation, e.g., "when",\r
16974  * @param args further arguments to be forwarded to the operation\r
16975  * @returns result {Promise} a promise for the result of the operation\r
16976  */\r
16977 Q.dispatch = dispatch;\r
16978 function dispatch(object, op, args) {\r
16979     return Q(object).dispatch(op, args);\r
16980 }\r
16981 \r
16982 Promise.prototype.dispatch = function (op, args) {\r
16983     var self = this;\r
16984     var deferred = defer();\r
16985     Q.nextTick(function () {\r
16986         self.promiseDispatch(deferred.resolve, op, args);\r
16987     });\r
16988     return deferred.promise;\r
16989 };\r
16990 \r
16991 /**\r
16992  * Gets the value of a property in a future turn.\r
16993  * @param object    promise or immediate reference for target object\r
16994  * @param name      name of property to get\r
16995  * @return promise for the property value\r
16996  */\r
16997 Q.get = function (object, key) {\r
16998     return Q(object).dispatch("get", [key]);\r
16999 };\r
17000 \r
17001 Promise.prototype.get = function (key) {\r
17002     return this.dispatch("get", [key]);\r
17003 };\r
17004 \r
17005 /**\r
17006  * Sets the value of a property in a future turn.\r
17007  * @param object    promise or immediate reference for object object\r
17008  * @param name      name of property to set\r
17009  * @param value     new value of property\r
17010  * @return promise for the return value\r
17011  */\r
17012 Q.set = function (object, key, value) {\r
17013     return Q(object).dispatch("set", [key, value]);\r
17014 };\r
17015 \r
17016 Promise.prototype.set = function (key, value) {\r
17017     return this.dispatch("set", [key, value]);\r
17018 };\r
17019 \r
17020 /**\r
17021  * Deletes a property in a future turn.\r
17022  * @param object    promise or immediate reference for target object\r
17023  * @param name      name of property to delete\r
17024  * @return promise for the return value\r
17025  */\r
17026 Q.del = // XXX legacy\r
17027 Q["delete"] = function (object, key) {\r
17028     return Q(object).dispatch("delete", [key]);\r
17029 };\r
17030 \r
17031 Promise.prototype.del = // XXX legacy\r
17032 Promise.prototype["delete"] = function (key) {\r
17033     return this.dispatch("delete", [key]);\r
17034 };\r
17035 \r
17036 /**\r
17037  * Invokes a method in a future turn.\r
17038  * @param object    promise or immediate reference for target object\r
17039  * @param name      name of method to invoke\r
17040  * @param value     a value to post, typically an array of\r
17041  *                  invocation arguments for promises that\r
17042  *                  are ultimately backed with `resolve` values,\r
17043  *                  as opposed to those backed with URLs\r
17044  *                  wherein the posted value can be any\r
17045  *                  JSON serializable object.\r
17046  * @return promise for the return value\r
17047  */\r
17048 // bound locally because it is used by other methods\r
17049 Q.mapply = // XXX As proposed by "Redsandro"\r
17050 Q.post = function (object, name, args) {\r
17051     return Q(object).dispatch("post", [name, args]);\r
17052 };\r
17053 \r
17054 Promise.prototype.mapply = // XXX As proposed by "Redsandro"\r
17055 Promise.prototype.post = function (name, args) {\r
17056     return this.dispatch("post", [name, args]);\r
17057 };\r
17058 \r
17059 /**\r
17060  * Invokes a method in a future turn.\r
17061  * @param object    promise or immediate reference for target object\r
17062  * @param name      name of method to invoke\r
17063  * @param ...args   array of invocation arguments\r
17064  * @return promise for the return value\r
17065  */\r
17066 Q.send = // XXX Mark Miller's proposed parlance\r
17067 Q.mcall = // XXX As proposed by "Redsandro"\r
17068 Q.invoke = function (object, name /*...args*/) {\r
17069     return Q(object).dispatch("post", [name, array_slice(arguments, 2)]);\r
17070 };\r
17071 \r
17072 Promise.prototype.send = // XXX Mark Miller's proposed parlance\r
17073 Promise.prototype.mcall = // XXX As proposed by "Redsandro"\r
17074 Promise.prototype.invoke = function (name /*...args*/) {\r
17075     return this.dispatch("post", [name, array_slice(arguments, 1)]);\r
17076 };\r
17077 \r
17078 /**\r
17079  * Applies the promised function in a future turn.\r
17080  * @param object    promise or immediate reference for target function\r
17081  * @param args      array of application arguments\r
17082  */\r
17083 Q.fapply = function (object, args) {\r
17084     return Q(object).dispatch("apply", [void 0, args]);\r
17085 };\r
17086 \r
17087 Promise.prototype.fapply = function (args) {\r
17088     return this.dispatch("apply", [void 0, args]);\r
17089 };\r
17090 \r
17091 /**\r
17092  * Calls the promised function in a future turn.\r
17093  * @param object    promise or immediate reference for target function\r
17094  * @param ...args   array of application arguments\r
17095  */\r
17096 Q["try"] =\r
17097 Q.fcall = function (object /* ...args*/) {\r
17098     return Q(object).dispatch("apply", [void 0, array_slice(arguments, 1)]);\r
17099 };\r
17100 \r
17101 Promise.prototype.fcall = function (/*...args*/) {\r
17102     return this.dispatch("apply", [void 0, array_slice(arguments)]);\r
17103 };\r
17104 \r
17105 /**\r
17106  * Binds the promised function, transforming return values into a fulfilled\r
17107  * promise and thrown errors into a rejected one.\r
17108  * @param object    promise or immediate reference for target function\r
17109  * @param ...args   array of application arguments\r
17110  */\r
17111 Q.fbind = function (object /*...args*/) {\r
17112     var promise = Q(object);\r
17113     var args = array_slice(arguments, 1);\r
17114     return function fbound() {\r
17115         return promise.dispatch("apply", [\r
17116             this,\r
17117             args.concat(array_slice(arguments))\r
17118         ]);\r
17119     };\r
17120 };\r
17121 Promise.prototype.fbind = function (/*...args*/) {\r
17122     var promise = this;\r
17123     var args = array_slice(arguments);\r
17124     return function fbound() {\r
17125         return promise.dispatch("apply", [\r
17126             this,\r
17127             args.concat(array_slice(arguments))\r
17128         ]);\r
17129     };\r
17130 };\r
17131 \r
17132 /**\r
17133  * Requests the names of the owned properties of a promised\r
17134  * object in a future turn.\r
17135  * @param object    promise or immediate reference for target object\r
17136  * @return promise for the keys of the eventually settled object\r
17137  */\r
17138 Q.keys = function (object) {\r
17139     return Q(object).dispatch("keys", []);\r
17140 };\r
17141 \r
17142 Promise.prototype.keys = function () {\r
17143     return this.dispatch("keys", []);\r
17144 };\r
17145 \r
17146 /**\r
17147  * Turns an array of promises into a promise for an array.  If any of\r
17148  * the promises gets rejected, the whole array is rejected immediately.\r
17149  * @param {Array*} an array (or promise for an array) of values (or\r
17150  * promises for values)\r
17151  * @returns a promise for an array of the corresponding values\r
17152  */\r
17153 // By Mark Miller\r
17154 // http://wiki.ecmascript.org/doku.php?id=strawman:concurrency&rev=1308776521#allfulfilled\r
17155 Q.all = all;\r
17156 function all(promises) {\r
17157     return when(promises, function (promises) {\r
17158         var pendingCount = 0;\r
17159         var deferred = defer();\r
17160         array_reduce(promises, function (undefined, promise, index) {\r
17161             var snapshot;\r
17162             if (\r
17163                 isPromise(promise) &&\r
17164                 (snapshot = promise.inspect()).state === "fulfilled"\r
17165             ) {\r
17166                 promises[index] = snapshot.value;\r
17167             } else {\r
17168                 ++pendingCount;\r
17169                 when(\r
17170                     promise,\r
17171                     function (value) {\r
17172                         promises[index] = value;\r
17173                         if (--pendingCount === 0) {\r
17174                             deferred.resolve(promises);\r
17175                         }\r
17176                     },\r
17177                     deferred.reject,\r
17178                     function (progress) {\r
17179                         deferred.notify({ index: index, value: progress });\r
17180                     }\r
17181                 );\r
17182             }\r
17183         }, void 0);\r
17184         if (pendingCount === 0) {\r
17185             deferred.resolve(promises);\r
17186         }\r
17187         return deferred.promise;\r
17188     });\r
17189 }\r
17190 \r
17191 Promise.prototype.all = function () {\r
17192     return all(this);\r
17193 };\r
17194 \r
17195 /**\r
17196  * Returns the first resolved promise of an array. Prior rejected promises are\r
17197  * ignored.  Rejects only if all promises are rejected.\r
17198  * @param {Array*} an array containing values or promises for values\r
17199  * @returns a promise fulfilled with the value of the first resolved promise,\r
17200  * or a rejected promise if all promises are rejected.\r
17201  */\r
17202 Q.any = any;\r
17203 \r
17204 function any(promises) {\r
17205     if (promises.length === 0) {\r
17206         return Q.resolve();\r
17207     }\r
17208 \r
17209     var deferred = Q.defer();\r
17210     var pendingCount = 0;\r
17211     array_reduce(promises, function (prev, current, index) {\r
17212         var promise = promises[index];\r
17213 \r
17214         pendingCount++;\r
17215 \r
17216         when(promise, onFulfilled, onRejected, onProgress);\r
17217         function onFulfilled(result) {\r
17218             deferred.resolve(result);\r
17219         }\r
17220         function onRejected() {\r
17221             pendingCount--;\r
17222             if (pendingCount === 0) {\r
17223                 deferred.reject(new Error(\r
17224                     "Can't get fulfillment value from any promise, all " +\r
17225                     "promises were rejected."\r
17226                 ));\r
17227             }\r
17228         }\r
17229         function onProgress(progress) {\r
17230             deferred.notify({\r
17231                 index: index,\r
17232                 value: progress\r
17233             });\r
17234         }\r
17235     }, undefined);\r
17236 \r
17237     return deferred.promise;\r
17238 }\r
17239 \r
17240 Promise.prototype.any = function () {\r
17241     return any(this);\r
17242 };\r
17243 \r
17244 /**\r
17245  * Waits for all promises to be settled, either fulfilled or\r
17246  * rejected.  This is distinct from `all` since that would stop\r
17247  * waiting at the first rejection.  The promise returned by\r
17248  * `allResolved` will never be rejected.\r
17249  * @param promises a promise for an array (or an array) of promises\r
17250  * (or values)\r
17251  * @return a promise for an array of promises\r
17252  */\r
17253 Q.allResolved = deprecate(allResolved, "allResolved", "allSettled");\r
17254 function allResolved(promises) {\r
17255     return when(promises, function (promises) {\r
17256         promises = array_map(promises, Q);\r
17257         return when(all(array_map(promises, function (promise) {\r
17258             return when(promise, noop, noop);\r
17259         })), function () {\r
17260             return promises;\r
17261         });\r
17262     });\r
17263 }\r
17264 \r
17265 Promise.prototype.allResolved = function () {\r
17266     return allResolved(this);\r
17267 };\r
17268 \r
17269 /**\r
17270  * @see Promise#allSettled\r
17271  */\r
17272 Q.allSettled = allSettled;\r
17273 function allSettled(promises) {\r
17274     return Q(promises).allSettled();\r
17275 }\r
17276 \r
17277 /**\r
17278  * Turns an array of promises into a promise for an array of their states (as\r
17279  * returned by `inspect`) when they have all settled.\r
17280  * @param {Array[Any*]} values an array (or promise for an array) of values (or\r
17281  * promises for values)\r
17282  * @returns {Array[State]} an array of states for the respective values.\r
17283  */\r
17284 Promise.prototype.allSettled = function () {\r
17285     return this.then(function (promises) {\r
17286         return all(array_map(promises, function (promise) {\r
17287             promise = Q(promise);\r
17288             function regardless() {\r
17289                 return promise.inspect();\r
17290             }\r
17291             return promise.then(regardless, regardless);\r
17292         }));\r
17293     });\r
17294 };\r
17295 \r
17296 /**\r
17297  * Captures the failure of a promise, giving an oportunity to recover\r
17298  * with a callback.  If the given promise is fulfilled, the returned\r
17299  * promise is fulfilled.\r
17300  * @param {Any*} promise for something\r
17301  * @param {Function} callback to fulfill the returned promise if the\r
17302  * given promise is rejected\r
17303  * @returns a promise for the return value of the callback\r
17304  */\r
17305 Q.fail = // XXX legacy\r
17306 Q["catch"] = function (object, rejected) {\r
17307     return Q(object).then(void 0, rejected);\r
17308 };\r
17309 \r
17310 Promise.prototype.fail = // XXX legacy\r
17311 Promise.prototype["catch"] = function (rejected) {\r
17312     return this.then(void 0, rejected);\r
17313 };\r
17314 \r
17315 /**\r
17316  * Attaches a listener that can respond to progress notifications from a\r
17317  * promise's originating deferred. This listener receives the exact arguments\r
17318  * passed to ``deferred.notify``.\r
17319  * @param {Any*} promise for something\r
17320  * @param {Function} callback to receive any progress notifications\r
17321  * @returns the given promise, unchanged\r
17322  */\r
17323 Q.progress = progress;\r
17324 function progress(object, progressed) {\r
17325     return Q(object).then(void 0, void 0, progressed);\r
17326 }\r
17327 \r
17328 Promise.prototype.progress = function (progressed) {\r
17329     return this.then(void 0, void 0, progressed);\r
17330 };\r
17331 \r
17332 /**\r
17333  * Provides an opportunity to observe the settling of a promise,\r
17334  * regardless of whether the promise is fulfilled or rejected.  Forwards\r
17335  * the resolution to the returned promise when the callback is done.\r
17336  * The callback can return a promise to defer completion.\r
17337  * @param {Any*} promise\r
17338  * @param {Function} callback to observe the resolution of the given\r
17339  * promise, takes no arguments.\r
17340  * @returns a promise for the resolution of the given promise when\r
17341  * ``fin`` is done.\r
17342  */\r
17343 Q.fin = // XXX legacy\r
17344 Q["finally"] = function (object, callback) {\r
17345     return Q(object)["finally"](callback);\r
17346 };\r
17347 \r
17348 Promise.prototype.fin = // XXX legacy\r
17349 Promise.prototype["finally"] = function (callback) {\r
17350     callback = Q(callback);\r
17351     return this.then(function (value) {\r
17352         return callback.fcall().then(function () {\r
17353             return value;\r
17354         });\r
17355     }, function (reason) {\r
17356         // TODO attempt to recycle the rejection with "this".\r
17357         return callback.fcall().then(function () {\r
17358             throw reason;\r
17359         });\r
17360     });\r
17361 };\r
17362 \r
17363 /**\r
17364  * Terminates a chain of promises, forcing rejections to be\r
17365  * thrown as exceptions.\r
17366  * @param {Any*} promise at the end of a chain of promises\r
17367  * @returns nothing\r
17368  */\r
17369 Q.done = function (object, fulfilled, rejected, progress) {\r
17370     return Q(object).done(fulfilled, rejected, progress);\r
17371 };\r
17372 \r
17373 Promise.prototype.done = function (fulfilled, rejected, progress) {\r
17374     var onUnhandledError = function (error) {\r
17375         // forward to a future turn so that ``when``\r
17376         // does not catch it and turn it into a rejection.\r
17377         Q.nextTick(function () {\r
17378             makeStackTraceLong(error, promise);\r
17379             if (Q.onerror) {\r
17380                 Q.onerror(error);\r
17381             } else {\r
17382                 throw error;\r
17383             }\r
17384         });\r
17385     };\r
17386 \r
17387     // Avoid unnecessary `nextTick`ing via an unnecessary `when`.\r
17388     var promise = fulfilled || rejected || progress ?\r
17389         this.then(fulfilled, rejected, progress) :\r
17390         this;\r
17391 \r
17392     if (typeof process === "object" && process && process.domain) {\r
17393         onUnhandledError = process.domain.bind(onUnhandledError);\r
17394     }\r
17395 \r
17396     promise.then(void 0, onUnhandledError);\r
17397 };\r
17398 \r
17399 /**\r
17400  * Causes a promise to be rejected if it does not get fulfilled before\r
17401  * some milliseconds time out.\r
17402  * @param {Any*} promise\r
17403  * @param {Number} milliseconds timeout\r
17404  * @param {Any*} custom error message or Error object (optional)\r
17405  * @returns a promise for the resolution of the given promise if it is\r
17406  * fulfilled before the timeout, otherwise rejected.\r
17407  */\r
17408 Q.timeout = function (object, ms, error) {\r
17409     return Q(object).timeout(ms, error);\r
17410 };\r
17411 \r
17412 Promise.prototype.timeout = function (ms, error) {\r
17413     var deferred = defer();\r
17414     var timeoutId = setTimeout(function () {\r
17415         if (!error || "string" === typeof error) {\r
17416             error = new Error(error || "Timed out after " + ms + " ms");\r
17417             error.code = "ETIMEDOUT";\r
17418         }\r
17419         deferred.reject(error);\r
17420     }, ms);\r
17421 \r
17422     this.then(function (value) {\r
17423         clearTimeout(timeoutId);\r
17424         deferred.resolve(value);\r
17425     }, function (exception) {\r
17426         clearTimeout(timeoutId);\r
17427         deferred.reject(exception);\r
17428     }, deferred.notify);\r
17429 \r
17430     return deferred.promise;\r
17431 };\r
17432 \r
17433 /**\r
17434  * Returns a promise for the given value (or promised value), some\r
17435  * milliseconds after it resolved. Passes rejections immediately.\r
17436  * @param {Any*} promise\r
17437  * @param {Number} milliseconds\r
17438  * @returns a promise for the resolution of the given promise after milliseconds\r
17439  * time has elapsed since the resolution of the given promise.\r
17440  * If the given promise rejects, that is passed immediately.\r
17441  */\r
17442 Q.delay = function (object, timeout) {\r
17443     if (timeout === void 0) {\r
17444         timeout = object;\r
17445         object = void 0;\r
17446     }\r
17447     return Q(object).delay(timeout);\r
17448 };\r
17449 \r
17450 Promise.prototype.delay = function (timeout) {\r
17451     return this.then(function (value) {\r
17452         var deferred = defer();\r
17453         setTimeout(function () {\r
17454             deferred.resolve(value);\r
17455         }, timeout);\r
17456         return deferred.promise;\r
17457     });\r
17458 };\r
17459 \r
17460 /**\r
17461  * Passes a continuation to a Node function, which is called with the given\r
17462  * arguments provided as an array, and returns a promise.\r
17463  *\r
17464  *      Q.nfapply(FS.readFile, [__filename])\r
17465  *      .then(function (content) {\r
17466  *      })\r
17467  *\r
17468  */\r
17469 Q.nfapply = function (callback, args) {\r
17470     return Q(callback).nfapply(args);\r
17471 };\r
17472 \r
17473 Promise.prototype.nfapply = function (args) {\r
17474     var deferred = defer();\r
17475     var nodeArgs = array_slice(args);\r
17476     nodeArgs.push(deferred.makeNodeResolver());\r
17477     this.fapply(nodeArgs).fail(deferred.reject);\r
17478     return deferred.promise;\r
17479 };\r
17480 \r
17481 /**\r
17482  * Passes a continuation to a Node function, which is called with the given\r
17483  * arguments provided individually, and returns a promise.\r
17484  * @example\r
17485  * Q.nfcall(FS.readFile, __filename)\r
17486  * .then(function (content) {\r
17487  * })\r
17488  *\r
17489  */\r
17490 Q.nfcall = function (callback /*...args*/) {\r
17491     var args = array_slice(arguments, 1);\r
17492     return Q(callback).nfapply(args);\r
17493 };\r
17494 \r
17495 Promise.prototype.nfcall = function (/*...args*/) {\r
17496     var nodeArgs = array_slice(arguments);\r
17497     var deferred = defer();\r
17498     nodeArgs.push(deferred.makeNodeResolver());\r
17499     this.fapply(nodeArgs).fail(deferred.reject);\r
17500     return deferred.promise;\r
17501 };\r
17502 \r
17503 /**\r
17504  * Wraps a NodeJS continuation passing function and returns an equivalent\r
17505  * version that returns a promise.\r
17506  * @example\r
17507  * Q.nfbind(FS.readFile, __filename)("utf-8")\r
17508  * .then(console.log)\r
17509  * .done()\r
17510  */\r
17511 Q.nfbind =\r
17512 Q.denodeify = function (callback /*...args*/) {\r
17513     var baseArgs = array_slice(arguments, 1);\r
17514     return function () {\r
17515         var nodeArgs = baseArgs.concat(array_slice(arguments));\r
17516         var deferred = defer();\r
17517         nodeArgs.push(deferred.makeNodeResolver());\r
17518         Q(callback).fapply(nodeArgs).fail(deferred.reject);\r
17519         return deferred.promise;\r
17520     };\r
17521 };\r
17522 \r
17523 Promise.prototype.nfbind =\r
17524 Promise.prototype.denodeify = function (/*...args*/) {\r
17525     var args = array_slice(arguments);\r
17526     args.unshift(this);\r
17527     return Q.denodeify.apply(void 0, args);\r
17528 };\r
17529 \r
17530 Q.nbind = function (callback, thisp /*...args*/) {\r
17531     var baseArgs = array_slice(arguments, 2);\r
17532     return function () {\r
17533         var nodeArgs = baseArgs.concat(array_slice(arguments));\r
17534         var deferred = defer();\r
17535         nodeArgs.push(deferred.makeNodeResolver());\r
17536         function bound() {\r
17537             return callback.apply(thisp, arguments);\r
17538         }\r
17539         Q(bound).fapply(nodeArgs).fail(deferred.reject);\r
17540         return deferred.promise;\r
17541     };\r
17542 };\r
17543 \r
17544 Promise.prototype.nbind = function (/*thisp, ...args*/) {\r
17545     var args = array_slice(arguments, 0);\r
17546     args.unshift(this);\r
17547     return Q.nbind.apply(void 0, args);\r
17548 };\r
17549 \r
17550 /**\r
17551  * Calls a method of a Node-style object that accepts a Node-style\r
17552  * callback with a given array of arguments, plus a provided callback.\r
17553  * @param object an object that has the named method\r
17554  * @param {String} name name of the method of object\r
17555  * @param {Array} args arguments to pass to the method; the callback\r
17556  * will be provided by Q and appended to these arguments.\r
17557  * @returns a promise for the value or error\r
17558  */\r
17559 Q.nmapply = // XXX As proposed by "Redsandro"\r
17560 Q.npost = function (object, name, args) {\r
17561     return Q(object).npost(name, args);\r
17562 };\r
17563 \r
17564 Promise.prototype.nmapply = // XXX As proposed by "Redsandro"\r
17565 Promise.prototype.npost = function (name, args) {\r
17566     var nodeArgs = array_slice(args || []);\r
17567     var deferred = defer();\r
17568     nodeArgs.push(deferred.makeNodeResolver());\r
17569     this.dispatch("post", [name, nodeArgs]).fail(deferred.reject);\r
17570     return deferred.promise;\r
17571 };\r
17572 \r
17573 /**\r
17574  * Calls a method of a Node-style object that accepts a Node-style\r
17575  * callback, forwarding the given variadic arguments, plus a provided\r
17576  * callback argument.\r
17577  * @param object an object that has the named method\r
17578  * @param {String} name name of the method of object\r
17579  * @param ...args arguments to pass to the method; the callback will\r
17580  * be provided by Q and appended to these arguments.\r
17581  * @returns a promise for the value or error\r
17582  */\r
17583 Q.nsend = // XXX Based on Mark Miller's proposed "send"\r
17584 Q.nmcall = // XXX Based on "Redsandro's" proposal\r
17585 Q.ninvoke = function (object, name /*...args*/) {\r
17586     var nodeArgs = array_slice(arguments, 2);\r
17587     var deferred = defer();\r
17588     nodeArgs.push(deferred.makeNodeResolver());\r
17589     Q(object).dispatch("post", [name, nodeArgs]).fail(deferred.reject);\r
17590     return deferred.promise;\r
17591 };\r
17592 \r
17593 Promise.prototype.nsend = // XXX Based on Mark Miller's proposed "send"\r
17594 Promise.prototype.nmcall = // XXX Based on "Redsandro's" proposal\r
17595 Promise.prototype.ninvoke = function (name /*...args*/) {\r
17596     var nodeArgs = array_slice(arguments, 1);\r
17597     var deferred = defer();\r
17598     nodeArgs.push(deferred.makeNodeResolver());\r
17599     this.dispatch("post", [name, nodeArgs]).fail(deferred.reject);\r
17600     return deferred.promise;\r
17601 };\r
17602 \r
17603 /**\r
17604  * If a function would like to support both Node continuation-passing-style and\r
17605  * promise-returning-style, it can end its internal promise chain with\r
17606  * `nodeify(nodeback)`, forwarding the optional nodeback argument.  If the user\r
17607  * elects to use a nodeback, the result will be sent there.  If they do not\r
17608  * pass a nodeback, they will receive the result promise.\r
17609  * @param object a result (or a promise for a result)\r
17610  * @param {Function} nodeback a Node.js-style callback\r
17611  * @returns either the promise or nothing\r
17612  */\r
17613 Q.nodeify = nodeify;\r
17614 function nodeify(object, nodeback) {\r
17615     return Q(object).nodeify(nodeback);\r
17616 }\r
17617 \r
17618 Promise.prototype.nodeify = function (nodeback) {\r
17619     if (nodeback) {\r
17620         this.then(function (value) {\r
17621             Q.nextTick(function () {\r
17622                 nodeback(null, value);\r
17623             });\r
17624         }, function (error) {\r
17625             Q.nextTick(function () {\r
17626                 nodeback(error);\r
17627             });\r
17628         });\r
17629     } else {\r
17630         return this;\r
17631     }\r
17632 };\r
17633 \r
17634 Q.noConflict = function() {\r
17635     throw new Error("Q.noConflict only works when Q is used as a global");\r
17636 };\r
17637 \r
17638 // All code before this point will be filtered from stack traces.\r
17639 var qEndingLine = captureLine();\r
17640 \r
17641 return Q;\r
17642 \r
17643 });\r
17644 \r
17645 }).call(this,require('_process'))\r
17646 //# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9xL3EuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiLy8gdmltOnRzPTQ6c3RzPTQ6c3c9NDpcbi8qIVxuICpcbiAqIENvcHlyaWdodCAyMDA5LTIwMTIgS3JpcyBLb3dhbCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIE1JVFxuICogbGljZW5zZSBmb3VuZCBhdCBodHRwOi8vZ2l0aHViLmNvbS9rcmlza293YWwvcS9yYXcvbWFzdGVyL0xJQ0VOU0VcbiAqXG4gKiBXaXRoIHBhcnRzIGJ5IFR5bGVyIENsb3NlXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDA5IFR5bGVyIENsb3NlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgTUlUIFggbGljZW5zZSBmb3VuZFxuICogYXQgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5odG1sXG4gKiBGb3JrZWQgYXQgcmVmX3NlbmQuanMgdmVyc2lvbjogMjAwOS0wNS0xMVxuICpcbiAqIFdpdGggcGFydHMgYnkgTWFyayBNaWxsZXJcbiAqIENvcHlyaWdodCAoQykgMjAxMSBHb29nbGUgSW5jLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4oZnVuY3Rpb24gKGRlZmluaXRpb24pIHtcbiAgICBcInVzZSBzdHJpY3RcIjtcblxuICAgIC8vIFRoaXMgZmlsZSB3aWxsIGZ1bmN0aW9uIHByb3Blcmx5IGFzIGEgPHNjcmlwdD4gdGFnLCBvciBhIG1vZHVsZVxuICAgIC8vIHVzaW5nIENvbW1vbkpTIGFuZCBOb2RlSlMgb3IgUmVxdWlyZUpTIG1vZHVsZSBmb3JtYXRzLiAgSW5cbiAgICAvLyBDb21tb24vTm9kZS9SZXF1aXJlSlMsIHRoZSBtb2R1bGUgZXhwb3J0cyB0aGUgUSBBUEkgYW5kIHdoZW5cbiAgICAvLyBleGVjdXRlZCBhcyBhIHNpbXBsZSA8c2NyaXB0PiwgaXQgY3JlYXRlcyBhIFEgZ2xvYmFsIGluc3RlYWQuXG5cbiAgICAvLyBNb250YWdlIFJlcXVpcmVcbiAgICBpZiAodHlwZW9mIGJvb3RzdHJhcCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGJvb3RzdHJhcChcInByb21pc2VcIiwgZGVmaW5pdGlvbik7XG5cbiAgICAvLyBDb21tb25KU1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG1vZHVsZSA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGRlZmluaXRpb24oKTtcblxuICAgIC8vIFJlcXVpcmVKU1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcbiAgICAgICAgZGVmaW5lKGRlZmluaXRpb24pO1xuXG4gICAgLy8gU0VTIChTZWN1cmUgRWNtYVNjcmlwdClcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBzZXMgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgaWYgKCFzZXMub2soKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VzLm1ha2VRID0gZGVmaW5pdGlvbjtcbiAgICAgICAgfVxuXG4gICAgLy8gPHNjcmlwdD5cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgfHwgdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgLy8gUHJlZmVyIHdpbmRvdyBvdmVyIHNlbGYgZm9yIGFkZC1vbiBzY3JpcHRzLiBVc2Ugc2VsZiBmb3JcbiAgICAgICAgLy8gbm9uLXdpbmRvd2VkIGNvbnRleHRzLlxuICAgICAgICB2YXIgZ2xvYmFsID0gdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHNlbGY7XG5cbiAgICAgICAgLy8gR2V0IHRoZSBgd2luZG93YCBvYmplY3QsIHNhdmUgdGhlIHByZXZpb3VzIFEgZ2xvYmFsXG4gICAgICAgIC8vIGFuZCBpbml0aWFsaXplIFEgYXMgYSBnbG9iYWwuXG4gICAgICAgIHZhciBwcmV2aW91c1EgPSBnbG9iYWwuUTtcbiAgICAgICAgZ2xvYmFsLlEgPSBkZWZpbml0aW9uKCk7XG5cbiAgICAgICAgLy8gQWRkIGEgbm9Db25mbGljdCBmdW5jdGlvbiBzbyBRIGNhbiBiZSByZW1vdmVkIGZyb20gdGhlXG4gICAgICAgIC8vIGdsb2JhbCBuYW1lc3BhY2UuXG4gICAgICAgIGdsb2JhbC5RLm5vQ29uZmxpY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBnbG9iYWwuUSA9IHByZXZpb3VzUTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9O1xuXG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBlbnZpcm9ubWVudCB3YXMgbm90IGFudGljaXBhdGVkIGJ5IFEuIFBsZWFzZSBmaWxlIGEgYnVnLlwiKTtcbiAgICB9XG5cbn0pKGZ1bmN0aW9uICgpIHtcblwidXNlIHN0cmljdFwiO1xuXG52YXIgaGFzU3RhY2tzID0gZmFsc2U7XG50cnkge1xuICAgIHRocm93IG5ldyBFcnJvcigpO1xufSBjYXRjaCAoZSkge1xuICAgIGhhc1N0YWNrcyA9ICEhZS5zdGFjaztcbn1cblxuLy8gQWxsIGNvZGUgYWZ0ZXIgdGhpcyBwb2ludCB3aWxsIGJlIGZpbHRlcmVkIGZyb20gc3RhY2sgdHJhY2VzIHJlcG9ydGVkXG4vLyBieSBRLlxudmFyIHFTdGFydGluZ0xpbmUgPSBjYXB0dXJlTGluZSgpO1xudmFyIHFGaWxlTmFtZTtcblxuLy8gc2hpbXNcblxuLy8gdXNlZCBmb3IgZmFsbGJhY2sgaW4gXCJhbGxSZXNvbHZlZFwiXG52YXIgbm9vcCA9IGZ1bmN0aW9uICgpIHt9O1xuXG4vLyBVc2UgdGhlIGZhc3Rlc3QgcG9zc2libGUgbWVhbnMgdG8gZXhlY3V0ZSBhIHRhc2sgaW4gYSBmdXR1cmUgdHVyblxuLy8gb2YgdGhlIGV2ZW50IGxvb3AuXG52YXIgbmV4dFRpY2sgPShmdW5jdGlvbiAoKSB7XG4gICAgLy8gbGlua2VkIGxpc3Qgb2YgdGFza3MgKHNpbmdsZSwgd2l0aCBoZWFkIG5vZGUpXG4gICAgdmFyIGhlYWQgPSB7dGFzazogdm9pZCAwLCBuZXh0OiBudWxsfTtcbiAgICB2YXIgdGFpbCA9IGhlYWQ7XG4gICAgdmFyIGZsdXNoaW5nID0gZmFsc2U7XG4gICAgdmFyIHJlcXVlc3RUaWNrID0gdm9pZCAwO1xuICAgIHZhciBpc05vZGVKUyA9IGZhbHNlO1xuICAgIC8vIHF1ZXVlIGZvciBsYXRlIHRhc2tzLCB1c2VkIGJ5IHVuaGFuZGxlZCByZWplY3Rpb24gdHJhY2tpbmdcbiAgICB2YXIgbGF0ZXJRdWV1ZSA9IFtdO1xuXG4gICAgZnVuY3Rpb24gZmx1c2goKSB7XG4gICAgICAgIC8qIGpzaGludCBsb29wZnVuYzogdHJ1ZSAqL1xuICAgICAgICB2YXIgdGFzaywgZG9tYWluO1xuXG4gICAgICAgIHdoaWxlIChoZWFkLm5leHQpIHtcbiAgICAgICAgICAgIGhlYWQgPSBoZWFkLm5leHQ7XG4gICAgICAgICAgICB0YXNrID0gaGVhZC50YXNrO1xuICAgICAgICAgICAgaGVhZC50YXNrID0gdm9pZCAwO1xuICAgICAgICAgICAgZG9tYWluID0gaGVhZC5kb21haW47XG5cbiAgICAgICAgICAgIGlmIChkb21haW4pIHtcbiAgICAgICAgICAgICAgICBoZWFkLmRvbWFpbiA9IHZvaWQgMDtcbiAgICAgICAgICAgICAgICBkb21haW4uZW50ZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJ1blNpbmdsZSh0YXNrLCBkb21haW4pO1xuXG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKGxhdGVyUXVldWUubGVuZ3RoKSB7XG4gICAgICAgICAgICB0YXNrID0gbGF0ZXJRdWV1ZS5wb3AoKTtcbiAgICAgICAgICAgIHJ1blNpbmdsZSh0YXNrKTtcbiAgICAgICAgfVxuICAgICAgICBmbHVzaGluZyA9IGZhbHNlO1xuICAgIH1cbiAgICAvLyBydW5zIGEgc2luZ2xlIGZ1bmN0aW9uIGluIHRoZSBhc3luYyBxdWV1ZVxuICAgIGZ1bmN0aW9uIHJ1blNpbmdsZSh0YXNrLCBkb21haW4pIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRhc2soKTtcblxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBpZiAoaXNOb2RlSlMpIHtcbiAgICAgICAgICAgICAgICAvLyBJbiBub2RlLCB1bmNhdWdodCBleGNlcHRpb25zIGFyZSBjb25zaWRlcmVkIGZhdGFsIGVycm9ycy5cbiAgICAgICAgICAgICAgICAvLyBSZS10aHJvdyB0aGVtIHN5bmNocm9ub3VzbHkgdG8gaW50ZXJydXB0IGZsdXNoaW5nIVxuXG4gICAgICAgICAgICAgICAgLy8gRW5zdXJlIGNvbnRpbnVhdGlvbiBpZiB0aGUgdW5jYXVnaHQgZXhjZXB0aW9uIGlzIHN1cHByZXNzZWRcbiAgICAgICAgICAgICAgICAvLyBsaXN0ZW5pbmcgXCJ1bmNhdWdodEV4Y2VwdGlvblwiIGV2ZW50cyAoYXMgZG9tYWlucyBkb2VzKS5cbiAgICAgICAgICAgICAgICAvLyBDb250aW51ZSBpbiBuZXh0IGV2ZW50IHRvIGF2b2lkIHRpY2sgcmVjdXJzaW9uLlxuICAgICAgICAgICAgICAgIGlmIChkb21haW4pIHtcbiAgICAgICAgICAgICAgICAgICAgZG9tYWluLmV4aXQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dChmbHVzaCwgMCk7XG4gICAgICAgICAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgICAgICAgICBkb21haW4uZW50ZXIoKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBlO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIEluIGJyb3dzZXJzLCB1bmNhdWdodCBleGNlcHRpb25zIGFyZSBub3QgZmF0YWwuXG4gICAgICAgICAgICAgICAgLy8gUmUtdGhyb3cgdGhlbSBhc3luY2hyb25vdXNseSB0byBhdm9pZCBzbG93LWRvd25zLlxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgICAgICAgIH0sIDApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgZG9tYWluLmV4aXQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5leHRUaWNrID0gZnVuY3Rpb24gKHRhc2spIHtcbiAgICAgICAgdGFpbCA9IHRhaWwubmV4dCA9IHtcbiAgICAgICAgICAgIHRhc2s6IHRhc2ssXG4gICAgICAgICAgICBkb21haW46IGlzTm9kZUpTICYmIHByb2Nlc3MuZG9tYWluLFxuICAgICAgICAgICAgbmV4dDogbnVsbFxuICAgICAgICB9O1xuXG4gICAgICAgIGlmICghZmx1c2hpbmcpIHtcbiAgICAgICAgICAgIGZsdXNoaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIHJlcXVlc3RUaWNrKCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgIHByb2Nlc3MudG9TdHJpbmcoKSA9PT0gXCJbb2JqZWN0IHByb2Nlc3NdXCIgJiYgcHJvY2Vzcy5uZXh0VGljaykge1xuICAgICAgICAvLyBFbnN1cmUgUSBpcyBpbiBhIHJlYWwgTm9kZSBlbnZpcm9ubWVudCwgd2l0aCBhIGBwcm9jZXNzLm5leHRUaWNrYC5cbiAgICAgICAgLy8gVG8gc2VlIHRocm91Z2ggZmFrZSBOb2RlIGVudmlyb25tZW50czpcbiAgICAgICAgLy8gKiBNb2NoYSB0ZXN0IHJ1bm5lciAtIGV4cG9zZXMgYSBgcHJvY2Vzc2AgZ2xvYmFsIHdpdGhvdXQgYSBgbmV4dFRpY2tgXG4gICAgICAgIC8vICogQnJvd3NlcmlmeSAtIGV4cG9zZXMgYSBgcHJvY2Vzcy5uZXhUaWNrYCBmdW5jdGlvbiB0aGF0IHVzZXNcbiAgICAgICAgLy8gICBgc2V0VGltZW91dGAuIEluIHRoaXMgY2FzZSBgc2V0SW1tZWRpYXRlYCBpcyBwcmVmZXJyZWQgYmVjYXVzZVxuICAgICAgICAvLyAgICBpdCBpcyBmYXN0ZXIuIEJyb3dzZXJpZnkncyBgcHJvY2Vzcy50b1N0cmluZygpYCB5aWVsZHNcbiAgICAgICAgLy8gICBcIltvYmplY3QgT2JqZWN0XVwiLCB3aGlsZSBpbiBhIHJlYWwgTm9kZSBlbnZpcm9ubWVudFxuICAgICAgICAvLyAgIGBwcm9jZXNzLm5leHRUaWNrKClgIHlpZWxkcyBcIltvYmplY3QgcHJvY2Vzc11cIi5cbiAgICAgICAgaXNOb2RlSlMgPSB0cnVlO1xuXG4gICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcHJvY2Vzcy5uZXh0VGljayhmbHVzaCk7XG4gICAgICAgIH07XG5cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBzZXRJbW1lZGlhdGUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAvLyBJbiBJRTEwLCBOb2RlLmpzIDAuOSssIG9yIGh0dHBzOi8vZ2l0aHViLmNvbS9Ob2JsZUpTL3NldEltbWVkaWF0ZVxuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgcmVxdWVzdFRpY2sgPSBzZXRJbW1lZGlhdGUuYmluZCh3aW5kb3csIGZsdXNoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHNldEltbWVkaWF0ZShmbHVzaCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBNZXNzYWdlQ2hhbm5lbCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAvLyBtb2Rlcm4gYnJvd3NlcnNcbiAgICAgICAgLy8gaHR0cDovL3d3dy5ub25ibG9ja2luZy5pby8yMDExLzA2L3dpbmRvd25leHR0aWNrLmh0bWxcbiAgICAgICAgdmFyIGNoYW5uZWwgPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcbiAgICAgICAgLy8gQXQgbGVhc3QgU2FmYXJpIFZlcnNpb24gNi4wLjUgKDg1MzYuMzAuMSkgaW50ZXJtaXR0ZW50bHkgY2Fubm90IGNyZWF0ZVxuICAgICAgICAvLyB3b3JraW5nIG1lc3NhZ2UgcG9ydHMgdGhlIGZpcnN0IHRpbWUgYSBwYWdlIGxvYWRzLlxuICAgICAgICBjaGFubmVsLnBvcnQxLm9ubWVzc2FnZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJlcXVlc3RUaWNrID0gcmVxdWVzdFBvcnRUaWNrO1xuICAgICAgICAgICAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSBmbHVzaDtcbiAgICAgICAgICAgIGZsdXNoKCk7XG4gICAgICAgIH07XG4gICAgICAgIHZhciByZXF1ZXN0UG9ydFRpY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAvLyBPcGVyYSByZXF1aXJlcyB1cyB0byBwcm92aWRlIGEgbWVzc2FnZSBwYXlsb2FkLCByZWdhcmRsZXNzIG9mXG4gICAgICAgICAgICAvLyB3aGV0aGVyIHdlIHVzZSBpdC5cbiAgICAgICAgICAgIGNoYW5uZWwucG9ydDIucG9zdE1lc3NhZ2UoMCk7XG4gICAgICAgIH07XG4gICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgc2V0VGltZW91dChmbHVzaCwgMCk7XG4gICAgICAgICAgICByZXF1ZXN0UG9ydFRpY2soKTtcbiAgICAgICAgfTtcblxuICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG9sZCBicm93c2Vyc1xuICAgICAgICByZXF1ZXN0VGljayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoZmx1c2gsIDApO1xuICAgICAgICB9O1xuICAgIH1cbiAgICAvLyBydW5zIGEgdGFzayBhZnRlciBhbGwgb3RoZXIgdGFza3MgaGF2ZSBiZWVuIHJ1blxuICAgIC8vIHRoaXMgaXMgdXNlZnVsIGZvciB1bmhhbmRsZWQgcmVqZWN0aW9uIHRyYWNraW5nIHRoYXQgbmVlZHMgdG8gaGFwcGVuXG4gICAgLy8gYWZ0ZXIgYWxsIGB0aGVuYGQgdGFza3MgaGF2ZSBiZWVuIHJ1bi5cbiAgICBuZXh0VGljay5ydW5BZnRlciA9IGZ1bmN0aW9uICh0YXNrKSB7XG4gICAgICAgIGxhdGVyUXVldWUucHVzaCh0YXNrKTtcbiAgICAgICAgaWYgKCFmbHVzaGluZykge1xuICAgICAgICAgICAgZmx1c2hpbmcgPSB0cnVlO1xuICAgICAgICAgICAgcmVxdWVzdFRpY2soKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIG5leHRUaWNrO1xufSkoKTtcblxuLy8gQXR0ZW1wdCB0byBtYWtlIGdlbmVyaWNzIHNhZmUgaW4gdGhlIGZhY2Ugb2YgZG93bnN0cmVhbVxuLy8gbW9kaWZpY2F0aW9ucy5cbi8vIFRoZXJlIGlzIG5vIHNpdHVhdGlvbiB3aGVyZSB0aGlzIGlzIG5lY2Vzc2FyeS5cbi8vIElmIHlvdSBuZWVkIGEgc2VjdXJpdHkgZ3VhcmFudGVlLCB0aGVzZSBwcmltb3JkaWFscyBuZWVkIHRvIGJlXG4vLyBkZWVwbHkgZnJvemVuIGFueXdheSwgYW5kIGlmIHlvdSBkb27igJl0IG5lZWQgYSBzZWN1cml0eSBndWFyYW50ZWUsXG4vLyB0aGlzIGlzIGp1c3QgcGxhaW4gcGFyYW5vaWQuXG4vLyBIb3dldmVyLCB0aGlzICoqbWlnaHQqKiBoYXZlIHRoZSBuaWNlIHNpZGUtZWZmZWN0IG9mIHJlZHVjaW5nIHRoZSBzaXplIG9mXG4vLyB0aGUgbWluaWZpZWQgY29kZSBieSByZWR1Y2luZyB4LmNhbGwoKSB0byBtZXJlbHkgeCgpXG4vLyBTZWUgTWFyayBNaWxsZXLigJlzIGV4cGxhbmF0aW9uIG9mIHdoYXQgdGhpcyBkb2VzLlxuLy8gaHR0cDovL3dpa2kuZWNtYXNjcmlwdC5vcmcvZG9rdS5waHA/aWQ9Y29udmVudGlvbnM6c2FmZV9tZXRhX3Byb2dyYW1taW5nXG52YXIgY2FsbCA9IEZ1bmN0aW9uLmNhbGw7XG5mdW5jdGlvbiB1bmN1cnJ5VGhpcyhmKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGNhbGwuYXBwbHkoZiwgYXJndW1lbnRzKTtcbiAgICB9O1xufVxuLy8gVGhpcyBpcyBlcXVpdmFsZW50LCBidXQgc2xvd2VyOlxuLy8gdW5jdXJyeVRoaXMgPSBGdW5jdGlvbl9iaW5kLmJpbmQoRnVuY3Rpb25fYmluZC5jYWxsKTtcbi8vIGh0dHA6Ly9qc3BlcmYuY29tL3VuY3Vycnl0aGlzXG5cbnZhciBhcnJheV9zbGljZSA9IHVuY3VycnlUaGlzKEFycmF5LnByb3RvdHlwZS5zbGljZSk7XG5cbnZhciBhcnJheV9yZWR1Y2UgPSB1bmN1cnJ5VGhpcyhcbiAgICBBcnJheS5wcm90b3R5cGUucmVkdWNlIHx8IGZ1bmN0aW9uIChjYWxsYmFjaywgYmFzaXMpIHtcbiAgICAgICAgdmFyIGluZGV4ID0gMCxcbiAgICAgICAgICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoO1xuICAgICAgICAvLyBjb25jZXJuaW5nIHRoZSBpbml0aWFsIHZhbHVlLCBpZiBvbmUgaXMgbm90IHByb3ZpZGVkXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAvLyBzZWVrIHRvIHRoZSBmaXJzdCB2YWx1ZSBpbiB0aGUgYXJyYXksIGFjY291bnRpbmdcbiAgICAgICAgICAgIC8vIGZvciB0aGUgcG9zc2liaWxpdHkgdGhhdCBpcyBpcyBhIHNwYXJzZSBhcnJheVxuICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICAgIGlmIChpbmRleCBpbiB0aGlzKSB7XG4gICAgICAgICAgICAgICAgICAgIGJhc2lzID0gdGhpc1tpbmRleCsrXTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICgrK2luZGV4ID49IGxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSB3aGlsZSAoMSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gcmVkdWNlXG4gICAgICAgIGZvciAoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgICAgLy8gYWNjb3VudCBmb3IgdGhlIHBvc3NpYmlsaXR5IHRoYXQgdGhlIGFycmF5IGlzIHNwYXJzZVxuICAgICAgICAgICAgaWYgKGluZGV4IGluIHRoaXMpIHtcbiAgICAgICAgICAgICAgICBiYXNpcyA9IGNhbGxiYWNrKGJhc2lzLCB0aGlzW2luZGV4XSwgaW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBiYXNpcztcbiAgICB9XG4pO1xuXG52YXIgYXJyYXlfaW5kZXhPZiA9IHVuY3VycnlUaGlzKFxuICAgIEFycmF5LnByb3RvdHlwZS5pbmRleE9mIHx8IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAvLyBub3QgYSB2ZXJ5IGdvb2Qgc2hpbSwgYnV0IGdvb2QgZW5vdWdoIGZvciBvdXIgb25lIHVzZSBvZiBpdFxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0aGlzW2ldID09PSB2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiAtMTtcbiAgICB9XG4pO1xuXG52YXIgYXJyYXlfbWFwID0gdW5jdXJyeVRoaXMoXG4gICAgQXJyYXkucHJvdG90eXBlLm1hcCB8fCBmdW5jdGlvbiAoY2FsbGJhY2ssIHRoaXNwKSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgdmFyIGNvbGxlY3QgPSBbXTtcbiAgICAgICAgYXJyYXlfcmVkdWNlKHNlbGYsIGZ1bmN0aW9uICh1bmRlZmluZWQsIHZhbHVlLCBpbmRleCkge1xuICAgICAgICAgICAgY29sbGVjdC5wdXNoKGNhbGxiYWNrLmNhbGwodGhpc3AsIHZhbHVlLCBpbmRleCwgc2VsZikpO1xuICAgICAgICB9LCB2b2lkIDApO1xuICAgICAgICByZXR1cm4gY29sbGVjdDtcbiAgICB9XG4pO1xuXG52YXIgb2JqZWN0X2NyZWF0ZSA9IE9iamVjdC5jcmVhdGUgfHwgZnVuY3Rpb24gKHByb3RvdHlwZSkge1xuICAgIGZ1bmN0aW9uIFR5cGUoKSB7IH1cbiAgICBUeXBlLnByb3RvdHlwZSA9IHByb3RvdHlwZTtcbiAgICByZXR1cm4gbmV3IFR5cGUoKTtcbn07XG5cbnZhciBvYmplY3RfaGFzT3duUHJvcGVydHkgPSB1bmN1cnJ5VGhpcyhPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5KTtcblxudmFyIG9iamVjdF9rZXlzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24gKG9iamVjdCkge1xuICAgIHZhciBrZXlzID0gW107XG4gICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAgICBpZiAob2JqZWN0X2hhc093blByb3BlcnR5KG9iamVjdCwga2V5KSkge1xuICAgICAgICAgICAga2V5cy5wdXNoKGtleSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGtleXM7XG59O1xuXG52YXIgb2JqZWN0X3RvU3RyaW5nID0gdW5jdXJyeVRoaXMoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZyk7XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSBPYmplY3QodmFsdWUpO1xufVxuXG4vLyBnZW5lcmF0b3IgcmVsYXRlZCBzaGltc1xuXG4vLyBGSVhNRTogUmVtb3ZlIHRoaXMgZnVuY3Rpb24gb25jZSBFUzYgZ2VuZXJhdG9ycyBhcmUgaW4gU3BpZGVyTW9ua2V5LlxuZnVuY3Rpb24gaXNTdG9wSXRlcmF0aW9uKGV4Y2VwdGlvbikge1xuICAgIHJldHVybiAoXG4gICAgICAgIG9iamVjdF90b1N0cmluZyhleGNlcHRpb24pID09PSBcIltvYmplY3QgU3RvcEl0ZXJhdGlvbl1cIiB8fFxuICAgICAgICBleGNlcHRpb24gaW5zdGFuY2VvZiBRUmV0dXJuVmFsdWVcbiAgICApO1xufVxuXG4vLyBGSVhNRTogUmVtb3ZlIHRoaXMgaGVscGVyIGFuZCBRLnJldHVybiBvbmNlIEVTNiBnZW5lcmF0b3JzIGFyZSBpblxuLy8gU3BpZGVyTW9ua2V5LlxudmFyIFFSZXR1cm5WYWx1ZTtcbmlmICh0eXBlb2YgUmV0dXJuVmFsdWUgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICBRUmV0dXJuVmFsdWUgPSBSZXR1cm5WYWx1ZTtcbn0gZWxzZSB7XG4gICAgUVJldHVyblZhbHVlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB9O1xufVxuXG4vLyBsb25nIHN0YWNrIHRyYWNlc1xuXG52YXIgU1RBQ0tfSlVNUF9TRVBBUkFUT1IgPSBcIkZyb20gcHJldmlvdXMgZXZlbnQ6XCI7XG5cbmZ1bmN0aW9uIG1ha2VTdGFja1RyYWNlTG9uZyhlcnJvciwgcHJvbWlzZSkge1xuICAgIC8vIElmIHBvc3NpYmxlLCB0cmFuc2Zvcm0gdGhlIGVycm9yIHN0YWNrIHRyYWNlIGJ5IHJlbW92aW5nIE5vZGUgYW5kIFFcbiAgICAvLyBjcnVmdCwgdGhlbiBjb25jYXRlbmF0aW5nIHdpdGggdGhlIHN0YWNrIHRyYWNlIG9mIGBwcm9taXNlYC4gU2VlICM1Ny5cbiAgICBpZiAoaGFzU3RhY2tzICYmXG4gICAgICAgIHByb21pc2Uuc3RhY2sgJiZcbiAgICAgICAgdHlwZW9mIGVycm9yID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgIGVycm9yICE9PSBudWxsICYmXG4gICAgICAgIGVycm9yLnN0YWNrICYmXG4gICAgICAgIGVycm9yLnN0YWNrLmluZGV4T2YoU1RBQ0tfSlVNUF9TRVBBUkFUT1IpID09PSAtMVxuICAgICkge1xuICAgICAgICB2YXIgc3RhY2tzID0gW107XG4gICAgICAgIGZvciAodmFyIHAgPSBwcm9taXNlOyAhIXA7IHAgPSBwLnNvdXJjZSkge1xuICAgICAgICAgICAgaWYgKHAuc3RhY2spIHtcbiAgICAgICAgICAgICAgICBzdGFja3MudW5zaGlmdChwLnN0YWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzdGFja3MudW5zaGlmdChlcnJvci5zdGFjayk7XG5cbiAgICAgICAgdmFyIGNvbmNhdGVkU3RhY2tzID0gc3RhY2tzLmpvaW4oXCJcXG5cIiArIFNUQUNLX0pVTVBfU0VQQVJBVE9SICsgXCJcXG5cIik7XG4gICAgICAgIGVycm9yLnN0YWNrID0gZmlsdGVyU3RhY2tTdHJpbmcoY29uY2F0ZWRTdGFja3MpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZmlsdGVyU3RhY2tTdHJpbmcoc3RhY2tTdHJpbmcpIHtcbiAgICB2YXIgbGluZXMgPSBzdGFja1N0cmluZy5zcGxpdChcIlxcblwiKTtcbiAgICB2YXIgZGVzaXJlZExpbmVzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgbGluZSA9IGxpbmVzW2ldO1xuXG4gICAgICAgIGlmICghaXNJbnRlcm5hbEZyYW1lKGxpbmUpICYmICFpc05vZGVGcmFtZShsaW5lKSAmJiBsaW5lKSB7XG4gICAgICAgICAgICBkZXNpcmVkTGluZXMucHVzaChsaW5lKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGVzaXJlZExpbmVzLmpvaW4oXCJcXG5cIik7XG59XG5cbmZ1bmN0aW9uIGlzTm9kZUZyYW1lKHN0YWNrTGluZSkge1xuICAgIHJldHVybiBzdGFja0xpbmUuaW5kZXhPZihcIihtb2R1bGUuanM6XCIpICE9PSAtMSB8fFxuICAgICAgICAgICBzdGFja0xpbmUuaW5kZXhPZihcIihub2RlLmpzOlwiKSAhPT0gLTE7XG59XG5cbmZ1bmN0aW9uIGdldEZpbGVOYW1lQW5kTGluZU51bWJlcihzdGFja0xpbmUpIHtcbiAgICAvLyBOYW1lZCBmdW5jdGlvbnM6IFwiYXQgZnVuY3Rpb25OYW1lIChmaWxlbmFtZTpsaW5lTnVtYmVyOmNvbHVtbk51bWJlcilcIlxuICAgIC8vIEluIElFMTAgZnVuY3Rpb24gbmFtZSBjYW4gaGF2ZSBzcGFjZXMgKFwiQW5vbnltb3VzIGZ1bmN0aW9uXCIpIE9fb1xuICAgIHZhciBhdHRlbXB0MSA9IC9hdCAuKyBcXCgoLispOihcXGQrKTooPzpcXGQrKVxcKSQvLmV4ZWMoc3RhY2tMaW5lKTtcbiAgICBpZiAoYXR0ZW1wdDEpIHtcbiAgICAgICAgcmV0dXJuIFthdHRlbXB0MVsxXSwgTnVtYmVyKGF0dGVtcHQxWzJdKV07XG4gICAgfVxuXG4gICAgLy8gQW5vbnltb3VzIGZ1bmN0aW9uczogXCJhdCBmaWxlbmFtZTpsaW5lTnVtYmVyOmNvbHVtbk51bWJlclwiXG4gICAgdmFyIGF0dGVtcHQyID0gL2F0IChbXiBdKyk6KFxcZCspOig/OlxcZCspJC8uZXhlYyhzdGFja0xpbmUpO1xuICAgIGlmIChhdHRlbXB0Mikge1xuICAgICAgICByZXR1cm4gW2F0dGVtcHQyWzFdLCBOdW1iZXIoYXR0ZW1wdDJbMl0pXTtcbiAgICB9XG5cbiAgICAvLyBGaXJlZm94IHN0eWxlOiBcImZ1bmN0aW9uQGZpbGVuYW1lOmxpbmVOdW1iZXIgb3IgQGZpbGVuYW1lOmxpbmVOdW1iZXJcIlxuICAgIHZhciBhdHRlbXB0MyA9IC8uKkAoLispOihcXGQrKSQvLmV4ZWMoc3RhY2tMaW5lKTtcbiAgICBpZiAoYXR0ZW1wdDMpIHtcbiAgICAgICAgcmV0dXJuIFthdHRlbXB0M1sxXSwgTnVtYmVyKGF0dGVtcHQzWzJdKV07XG4gICAgfVxufVxuXG5mdW5jdGlvbiBpc0ludGVybmFsRnJhbWUoc3RhY2tMaW5lKSB7XG4gICAgdmFyIGZpbGVOYW1lQW5kTGluZU51bWJlciA9IGdldEZpbGVOYW1lQW5kTGluZU51bWJlcihzdGFja0xpbmUpO1xuXG4gICAgaWYgKCFmaWxlTmFtZUFuZExpbmVOdW1iZXIpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHZhciBmaWxlTmFtZSA9IGZpbGVOYW1lQW5kTGluZU51bWJlclswXTtcbiAgICB2YXIgbGluZU51bWJlciA9IGZpbGVOYW1lQW5kTGluZU51bWJlclsxXTtcblxuICAgIHJldHVybiBmaWxlTmFtZSA9PT0gcUZpbGVOYW1lICYmXG4gICAgICAgIGxpbmVOdW1iZXIgPj0gcVN0YXJ0aW5nTGluZSAmJlxuICAgICAgICBsaW5lTnVtYmVyIDw9IHFFbmRpbmdMaW5lO1xufVxuXG4vLyBkaXNjb3ZlciBvd24gZmlsZSBuYW1lIGFuZCBsaW5lIG51bWJlciByYW5nZSBmb3IgZmlsdGVyaW5nIHN0YWNrXG4vLyB0cmFjZXNcbmZ1bmN0aW9uIGNhcHR1cmVMaW5lKCkge1xuICAgIGlmICghaGFzU3RhY2tzKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHZhciBsaW5lcyA9IGUuc3RhY2suc3BsaXQoXCJcXG5cIik7XG4gICAgICAgIHZhciBmaXJzdExpbmUgPSBsaW5lc1swXS5pbmRleE9mKFwiQFwiKSA+IDAgPyBsaW5lc1sxXSA6IGxpbmVzWzJdO1xuICAgICAgICB2YXIgZmlsZU5hbWVBbmRMaW5lTnVtYmVyID0gZ2V0RmlsZU5hbWVBbmRMaW5lTnVtYmVyKGZpcnN0TGluZSk7XG4gICAgICAgIGlmICghZmlsZU5hbWVBbmRMaW5lTnVtYmVyKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBxRmlsZU5hbWUgPSBmaWxlTmFtZUFuZExpbmVOdW1iZXJbMF07XG4gICAgICAgIHJldHVybiBmaWxlTmFtZUFuZExpbmVOdW1iZXJbMV07XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkZXByZWNhdGUoY2FsbGJhY2ssIG5hbWUsIGFsdGVybmF0aXZlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjb25zb2xlICE9PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgICB0eXBlb2YgY29uc29sZS53YXJuID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihuYW1lICsgXCIgaXMgZGVwcmVjYXRlZCwgdXNlIFwiICsgYWx0ZXJuYXRpdmUgK1xuICAgICAgICAgICAgICAgICAgICAgICAgIFwiIGluc3RlYWQuXCIsIG5ldyBFcnJvcihcIlwiKS5zdGFjayk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KGNhbGxiYWNrLCBhcmd1bWVudHMpO1xuICAgIH07XG59XG5cbi8vIGVuZCBvZiBzaGltc1xuLy8gYmVnaW5uaW5nIG9mIHJlYWwgd29ya1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBwcm9taXNlIGZvciBhbiBpbW1lZGlhdGUgcmVmZXJlbmNlLCBwYXNzZXMgcHJvbWlzZXMgdGhyb3VnaCwgb3JcbiAqIGNvZXJjZXMgcHJvbWlzZXMgZnJvbSBkaWZmZXJlbnQgc3lzdGVtcy5cbiAqIEBwYXJhbSB2YWx1ZSBpbW1lZGlhdGUgcmVmZXJlbmNlIG9yIHByb21pc2VcbiAqL1xuZnVuY3Rpb24gUSh2YWx1ZSkge1xuICAgIC8vIElmIHRoZSBvYmplY3QgaXMgYWxyZWFkeSBhIFByb21pc2UsIHJldHVybiBpdCBkaXJlY3RseS4gIFRoaXMgZW5hYmxlc1xuICAgIC8vIHRoZSByZXNvbHZlIGZ1bmN0aW9uIHRvIGJvdGggYmUgdXNlZCB0byBjcmVhdGVkIHJlZmVyZW5jZXMgZnJvbSBvYmplY3RzLFxuICAgIC8vIGJ1dCB0byB0b2xlcmFibHkgY29lcmNlIG5vbi1wcm9taXNlcyB0byBwcm9taXNlcy5cbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICAvLyBhc3NpbWlsYXRlIHRoZW5hYmxlc1xuICAgIGlmIChpc1Byb21pc2VBbGlrZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGNvZXJjZSh2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZ1bGZpbGwodmFsdWUpO1xuICAgIH1cbn1cblEucmVzb2x2ZSA9IFE7XG5cbi8qKlxuICogUGVyZm9ybXMgYSB0YXNrIGluIGEgZnV0dXJlIHR1cm4gb2YgdGhlIGV2ZW50IGxvb3AuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB0YXNrXG4gKi9cblEubmV4dFRpY2sgPSBuZXh0VGljaztcblxuLyoqXG4gKiBDb250cm9scyB3aGV0aGVyIG9yIG5vdCBsb25nIHN0YWNrIHRyYWNlcyB3aWxsIGJlIG9uXG4gKi9cblEubG9uZ1N0YWNrU3VwcG9ydCA9IGZhbHNlO1xuXG4vLyBlbmFibGUgbG9uZyBzdGFja3MgaWYgUV9ERUJVRyBpcyBzZXRcbmlmICh0eXBlb2YgcHJvY2VzcyA9PT0gXCJvYmplY3RcIiAmJiBwcm9jZXNzICYmIHByb2Nlc3MuZW52ICYmIHByb2Nlc3MuZW52LlFfREVCVUcpIHtcbiAgICBRLmxvbmdTdGFja1N1cHBvcnQgPSB0cnVlO1xufVxuXG4vKipcbiAqIENvbnN0cnVjdHMgYSB7cHJvbWlzZSwgcmVzb2x2ZSwgcmVqZWN0fSBvYmplY3QuXG4gKlxuICogYHJlc29sdmVgIGlzIGEgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggYSBtb3JlIHJlc29sdmVkIHZhbHVlIGZvciB0aGVcbiAqIHByb21pc2UuIFRvIGZ1bGZpbGwgdGhlIHByb21pc2UsIGludm9rZSBgcmVzb2x2ZWAgd2l0aCBhbnkgdmFsdWUgdGhhdCBpc1xuICogbm90IGEgdGhlbmFibGUuIFRvIHJlamVjdCB0aGUgcHJvbWlzZSwgaW52b2tlIGByZXNvbHZlYCB3aXRoIGEgcmVqZWN0ZWRcbiAqIHRoZW5hYmxlLCBvciBpbnZva2UgYHJlamVjdGAgd2l0aCB0aGUgcmVhc29uIGRpcmVjdGx5LiBUbyByZXNvbHZlIHRoZVxuICogcHJvbWlzZSB0byBhbm90aGVyIHRoZW5hYmxlLCB0aHVzIHB1dHRpbmcgaXQgaW4gdGhlIHNhbWUgc3RhdGUsIGludm9rZVxuICogYHJlc29sdmVgIHdpdGggdGhhdCBvdGhlciB0aGVuYWJsZS5cbiAqL1xuUS5kZWZlciA9IGRlZmVyO1xuZnVuY3Rpb24gZGVmZXIoKSB7XG4gICAgLy8gaWYgXCJtZXNzYWdlc1wiIGlzIGFuIFwiQXJyYXlcIiwgdGhhdCBpbmRpY2F0ZXMgdGhhdCB0aGUgcHJvbWlzZSBoYXMgbm90IHlldFxuICAgIC8vIGJlZW4gcmVzb2x2ZWQuICBJZiBpdCBpcyBcInVuZGVmaW5lZFwiLCBpdCBoYXMgYmVlbiByZXNvbHZlZC4gIEVhY2hcbiAgICAvLyBlbGVtZW50IG9mIHRoZSBtZXNzYWdlcyBhcnJheSBpcyBpdHNlbGYgYW4gYXJyYXkgb2YgY29tcGxldGUgYXJndW1lbnRzIHRvXG4gICAgLy8gZm9yd2FyZCB0byB0aGUgcmVzb2x2ZWQgcHJvbWlzZS4gIFdlIGNvZXJjZSB0aGUgcmVzb2x1dGlvbiB2YWx1ZSB0byBhXG4gICAgLy8gcHJvbWlzZSB1c2luZyB0aGUgYHJlc29sdmVgIGZ1bmN0aW9uIGJlY2F1c2UgaXQgaGFuZGxlcyBib3RoIGZ1bGx5XG4gICAgLy8gbm9uLXRoZW5hYmxlIHZhbHVlcyBhbmQgb3RoZXIgdGhlbmFibGVzIGdyYWNlZnVsbHkuXG4gICAgdmFyIG1lc3NhZ2VzID0gW10sIHByb2dyZXNzTGlzdGVuZXJzID0gW10sIHJlc29sdmVkUHJvbWlzZTtcblxuICAgIHZhciBkZWZlcnJlZCA9IG9iamVjdF9jcmVhdGUoZGVmZXIucHJvdG90eXBlKTtcbiAgICB2YXIgcHJvbWlzZSA9IG9iamVjdF9jcmVhdGUoUHJvbWlzZS5wcm90b3R5cGUpO1xuXG4gICAgcHJvbWlzZS5wcm9taXNlRGlzcGF0Y2ggPSBmdW5jdGlvbiAocmVzb2x2ZSwgb3AsIG9wZXJhbmRzKSB7XG4gICAgICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICAgICAgaWYgKG1lc3NhZ2VzKSB7XG4gICAgICAgICAgICBtZXNzYWdlcy5wdXNoKGFyZ3MpO1xuICAgICAgICAgICAgaWYgKG9wID09PSBcIndoZW5cIiAmJiBvcGVyYW5kc1sxXSkgeyAvLyBwcm9ncmVzcyBvcGVyYW5kXG4gICAgICAgICAgICAgICAgcHJvZ3Jlc3NMaXN0ZW5lcnMucHVzaChvcGVyYW5kc1sxXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBRLm5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlZFByb21pc2UucHJvbWlzZURpc3BhdGNoLmFwcGx5KHJlc29sdmVkUHJvbWlzZSwgYXJncyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvLyBYWFggZGVwcmVjYXRlZFxuICAgIHByb21pc2UudmFsdWVPZiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKG1lc3NhZ2VzKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbmVhcmVyVmFsdWUgPSBuZWFyZXIocmVzb2x2ZWRQcm9taXNlKTtcbiAgICAgICAgaWYgKGlzUHJvbWlzZShuZWFyZXJWYWx1ZSkpIHtcbiAgICAgICAgICAgIHJlc29sdmVkUHJvbWlzZSA9IG5lYXJlclZhbHVlOyAvLyBzaG9ydGVuIGNoYWluXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5lYXJlclZhbHVlO1xuICAgIH07XG5cbiAgICBwcm9taXNlLmluc3BlY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghcmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm4geyBzdGF0ZTogXCJwZW5kaW5nXCIgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzb2x2ZWRQcm9taXNlLmluc3BlY3QoKTtcbiAgICB9O1xuXG4gICAgaWYgKFEubG9uZ1N0YWNrU3VwcG9ydCAmJiBoYXNTdGFja3MpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBOT1RFOiBkb24ndCB0cnkgdG8gdXNlIGBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZWAgb3IgdHJhbnNmZXIgdGhlXG4gICAgICAgICAgICAvLyBhY2Nlc3NvciBhcm91bmQ7IHRoYXQgY2F1c2VzIG1lbW9yeSBsZWFrcyBhcyBwZXIgR0gtMTExLiBKdXN0XG4gICAgICAgICAgICAvLyByZWlmeSB0aGUgc3RhY2sgdHJhY2UgYXMgYSBzdHJpbmcgQVNBUC5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBBdCB0aGUgc2FtZSB0aW1lLCBjdXQgb2ZmIHRoZSBmaXJzdCBsaW5lOyBpdCdzIGFsd2F5cyBqdXN0XG4gICAgICAgICAgICAvLyBcIltvYmplY3QgUHJvbWlzZV1cXG5cIiwgYXMgcGVyIHRoZSBgdG9TdHJpbmdgLlxuICAgICAgICAgICAgcHJvbWlzZS5zdGFjayA9IGUuc3RhY2suc3Vic3RyaW5nKGUuc3RhY2suaW5kZXhPZihcIlxcblwiKSArIDEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gTk9URTogd2UgZG8gdGhlIGNoZWNrcyBmb3IgYHJlc29sdmVkUHJvbWlzZWAgaW4gZWFjaCBtZXRob2QsIGluc3RlYWQgb2ZcbiAgICAvLyBjb25zb2xpZGF0aW5nIHRoZW0gaW50byBgYmVjb21lYCwgc2luY2Ugb3RoZXJ3aXNlIHdlJ2QgY3JlYXRlIG5ld1xuICAgIC8vIHByb21pc2VzIHdpdGggdGhlIGxpbmVzIGBiZWNvbWUod2hhdGV2ZXIodmFsdWUpKWAuIFNlZSBlLmcuIEdILTI1Mi5cblxuICAgIGZ1bmN0aW9uIGJlY29tZShuZXdQcm9taXNlKSB7XG4gICAgICAgIHJlc29sdmVkUHJvbWlzZSA9IG5ld1Byb21pc2U7XG4gICAgICAgIHByb21pc2Uuc291cmNlID0gbmV3UHJvbWlzZTtcblxuICAgICAgICBhcnJheV9yZWR1Y2UobWVzc2FnZXMsIGZ1bmN0aW9uICh1bmRlZmluZWQsIG1lc3NhZ2UpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIG5ld1Byb21pc2UucHJvbWlzZURpc3BhdGNoLmFwcGx5KG5ld1Byb21pc2UsIG1lc3NhZ2UpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sIHZvaWQgMCk7XG5cbiAgICAgICAgbWVzc2FnZXMgPSB2b2lkIDA7XG4gICAgICAgIHByb2dyZXNzTGlzdGVuZXJzID0gdm9pZCAwO1xuICAgIH1cblxuICAgIGRlZmVycmVkLnByb21pc2UgPSBwcm9taXNlO1xuICAgIGRlZmVycmVkLnJlc29sdmUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgaWYgKHJlc29sdmVkUHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgYmVjb21lKFEodmFsdWUpKTtcbiAgICB9O1xuXG4gICAgZGVmZXJyZWQuZnVsZmlsbCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICBpZiAocmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBiZWNvbWUoZnVsZmlsbCh2YWx1ZSkpO1xuICAgIH07XG4gICAgZGVmZXJyZWQucmVqZWN0ID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgICBpZiAocmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBiZWNvbWUocmVqZWN0KHJlYXNvbikpO1xuICAgIH07XG4gICAgZGVmZXJyZWQubm90aWZ5ID0gZnVuY3Rpb24gKHByb2dyZXNzKSB7XG4gICAgICAgIGlmIChyZXNvbHZlZFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGFycmF5X3JlZHVjZShwcm9ncmVzc0xpc3RlbmVycywgZnVuY3Rpb24gKHVuZGVmaW5lZCwgcHJvZ3Jlc3NMaXN0ZW5lcikge1xuICAgICAgICAgICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcHJvZ3Jlc3NMaXN0ZW5lcihwcm9ncmVzcyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSwgdm9pZCAwKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIGRlZmVycmVkO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBOb2RlLXN0eWxlIGNhbGxiYWNrIHRoYXQgd2lsbCByZXNvbHZlIG9yIHJlamVjdCB0aGUgZGVmZXJyZWRcbiAqIHByb21pc2UuXG4gKiBAcmV0dXJucyBhIG5vZGViYWNrXG4gKi9cbmRlZmVyLnByb3RvdHlwZS5tYWtlTm9kZVJlc29sdmVyID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICByZXR1cm4gZnVuY3Rpb24gKGVycm9yLCB2YWx1ZSkge1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgIHNlbGYucmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMikge1xuICAgICAgICAgICAgc2VsZi5yZXNvbHZlKGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VsZi5yZXNvbHZlKHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuXG4vKipcbiAqIEBwYXJhbSByZXNvbHZlciB7RnVuY3Rpb259IGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIG5vdGhpbmcgYW5kIGFjY2VwdHNcbiAqIHRoZSByZXNvbHZlLCByZWplY3QsIGFuZCBub3RpZnkgZnVuY3Rpb25zIGZvciBhIGRlZmVycmVkLlxuICogQHJldHVybnMgYSBwcm9taXNlIHRoYXQgbWF5IGJlIHJlc29sdmVkIHdpdGggdGhlIGdpdmVuIHJlc29sdmUgYW5kIHJlamVjdFxuICogZnVuY3Rpb25zLCBvciByZWplY3RlZCBieSBhIHRocm93biBleGNlcHRpb24gaW4gcmVzb2x2ZXJcbiAqL1xuUS5Qcm9taXNlID0gcHJvbWlzZTsgLy8gRVM2XG5RLnByb21pc2UgPSBwcm9taXNlO1xuZnVuY3Rpb24gcHJvbWlzZShyZXNvbHZlcikge1xuICAgIGlmICh0eXBlb2YgcmVzb2x2ZXIgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwicmVzb2x2ZXIgbXVzdCBiZSBhIGZ1bmN0aW9uLlwiKTtcbiAgICB9XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB0cnkge1xuICAgICAgICByZXNvbHZlcihkZWZlcnJlZC5yZXNvbHZlLCBkZWZlcnJlZC5yZWplY3QsIGRlZmVycmVkLm5vdGlmeSk7XG4gICAgfSBjYXRjaCAocmVhc29uKSB7XG4gICAgICAgIGRlZmVycmVkLnJlamVjdChyZWFzb24pO1xuICAgIH1cbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn1cblxucHJvbWlzZS5yYWNlID0gcmFjZTsgLy8gRVM2XG5wcm9taXNlLmFsbCA9IGFsbDsgLy8gRVM2XG5wcm9taXNlLnJlamVjdCA9IHJlamVjdDsgLy8gRVM2XG5wcm9taXNlLnJlc29sdmUgPSBROyAvLyBFUzZcblxuLy8gWFhYIGV4cGVyaW1lbnRhbC4gIFRoaXMgbWV0aG9kIGlzIGEgd2F5IHRvIGRlbm90ZSB0aGF0IGEgbG9jYWwgdmFsdWUgaXNcbi8vIHNlcmlhbGl6YWJsZSBhbmQgc2hvdWxkIGJlIGltbWVkaWF0ZWx5IGRpc3BhdGNoZWQgdG8gYSByZW1vdGUgdXBvbiByZXF1ZXN0LFxuLy8gaW5zdGVhZCBvZiBwYXNzaW5nIGEgcmVmZXJlbmNlLlxuUS5wYXNzQnlDb3B5ID0gZnVuY3Rpb24gKG9iamVjdCkge1xuICAgIC8vZnJlZXplKG9iamVjdCk7XG4gICAgLy9wYXNzQnlDb3BpZXMuc2V0KG9iamVjdCwgdHJ1ZSk7XG4gICAgcmV0dXJuIG9iamVjdDtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnBhc3NCeUNvcHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgLy9mcmVlemUob2JqZWN0KTtcbiAgICAvL3Bhc3NCeUNvcGllcy5zZXQob2JqZWN0LCB0cnVlKTtcbiAgICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogSWYgdHdvIHByb21pc2VzIGV2ZW50dWFsbHkgZnVsZmlsbCB0byB0aGUgc2FtZSB2YWx1ZSwgcHJvbWlzZXMgdGhhdCB2YWx1ZSxcbiAqIGJ1dCBvdGhlcndpc2UgcmVqZWN0cy5cbiAqIEBwYXJhbSB4IHtBbnkqfVxuICogQHBhcmFtIHkge0FueSp9XG4gKiBAcmV0dXJucyB7QW55Kn0gYSBwcm9taXNlIGZvciB4IGFuZCB5IGlmIHRoZXkgYXJlIHRoZSBzYW1lLCBidXQgYSByZWplY3Rpb25cbiAqIG90aGVyd2lzZS5cbiAqXG4gKi9cblEuam9pbiA9IGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgcmV0dXJuIFEoeCkuam9pbih5KTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmpvaW4gPSBmdW5jdGlvbiAodGhhdCkge1xuICAgIHJldHVybiBRKFt0aGlzLCB0aGF0XSkuc3ByZWFkKGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgICAgIGlmICh4ID09PSB5KSB7XG4gICAgICAgICAgICAvLyBUT0RPOiBcIj09PVwiIHNob3VsZCBiZSBPYmplY3QuaXMgb3IgZXF1aXZcbiAgICAgICAgICAgIHJldHVybiB4O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FuJ3Qgam9pbjogbm90IHRoZSBzYW1lOiBcIiArIHggKyBcIiBcIiArIHkpO1xuICAgICAgICB9XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgZmlyc3Qgb2YgYW4gYXJyYXkgb2YgcHJvbWlzZXMgdG8gYmVjb21lIHNldHRsZWQuXG4gKiBAcGFyYW0gYW5zd2VycyB7QXJyYXlbQW55Kl19IHByb21pc2VzIHRvIHJhY2VcbiAqIEByZXR1cm5zIHtBbnkqfSB0aGUgZmlyc3QgcHJvbWlzZSB0byBiZSBzZXR0bGVkXG4gKi9cblEucmFjZSA9IHJhY2U7XG5mdW5jdGlvbiByYWNlKGFuc3dlclBzKSB7XG4gICAgcmV0dXJuIHByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAvLyBTd2l0Y2ggdG8gdGhpcyBvbmNlIHdlIGNhbiBhc3N1bWUgYXQgbGVhc3QgRVM1XG4gICAgICAgIC8vIGFuc3dlclBzLmZvckVhY2goZnVuY3Rpb24gKGFuc3dlclApIHtcbiAgICAgICAgLy8gICAgIFEoYW5zd2VyUCkudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAvLyB9KTtcbiAgICAgICAgLy8gVXNlIHRoaXMgaW4gdGhlIG1lYW50aW1lXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBhbnN3ZXJQcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgUShhbnN3ZXJQc1tpXSkudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5cblByb21pc2UucHJvdG90eXBlLnJhY2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbihRLnJhY2UpO1xufTtcblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgUHJvbWlzZSB3aXRoIGEgcHJvbWlzZSBkZXNjcmlwdG9yIG9iamVjdCBhbmQgb3B0aW9uYWwgZmFsbGJhY2tcbiAqIGZ1bmN0aW9uLiAgVGhlIGRlc2NyaXB0b3IgY29udGFpbnMgbWV0aG9kcyBsaWtlIHdoZW4ocmVqZWN0ZWQpLCBnZXQobmFtZSksXG4gKiBzZXQobmFtZSwgdmFsdWUpLCBwb3N0KG5hbWUsIGFyZ3MpLCBhbmQgZGVsZXRlKG5hbWUpLCB3aGljaCBhbGxcbiAqIHJldHVybiBlaXRoZXIgYSB2YWx1ZSwgYSBwcm9taXNlIGZvciBhIHZhbHVlLCBvciBhIHJlamVjdGlvbi4gIFRoZSBmYWxsYmFja1xuICogYWNjZXB0cyB0aGUgb3BlcmF0aW9uIG5hbWUsIGEgcmVzb2x2ZXIsIGFuZCBhbnkgZnVydGhlciBhcmd1bWVudHMgdGhhdCB3b3VsZFxuICogaGF2ZSBiZWVuIGZvcndhcmRlZCB0byB0aGUgYXBwcm9wcmlhdGUgbWV0aG9kIGFib3ZlIGhhZCBhIG1ldGhvZCBiZWVuXG4gKiBwcm92aWRlZCB3aXRoIHRoZSBwcm9wZXIgbmFtZS4gIFRoZSBBUEkgbWFrZXMgbm8gZ3VhcmFudGVlcyBhYm91dCB0aGUgbmF0dXJlXG4gKiBvZiB0aGUgcmV0dXJuZWQgb2JqZWN0LCBhcGFydCBmcm9tIHRoYXQgaXQgaXMgdXNhYmxlIHdoZXJlZXZlciBwcm9taXNlcyBhcmVcbiAqIGJvdWdodCBhbmQgc29sZC5cbiAqL1xuUS5tYWtlUHJvbWlzZSA9IFByb21pc2U7XG5mdW5jdGlvbiBQcm9taXNlKGRlc2NyaXB0b3IsIGZhbGxiYWNrLCBpbnNwZWN0KSB7XG4gICAgaWYgKGZhbGxiYWNrID09PSB2b2lkIDApIHtcbiAgICAgICAgZmFsbGJhY2sgPSBmdW5jdGlvbiAob3ApIHtcbiAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKFxuICAgICAgICAgICAgICAgIFwiUHJvbWlzZSBkb2VzIG5vdCBzdXBwb3J0IG9wZXJhdGlvbjogXCIgKyBvcFxuICAgICAgICAgICAgKSk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIGlmIChpbnNwZWN0ID09PSB2b2lkIDApIHtcbiAgICAgICAgaW5zcGVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB7c3RhdGU6IFwidW5rbm93blwifTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICB2YXIgcHJvbWlzZSA9IG9iamVjdF9jcmVhdGUoUHJvbWlzZS5wcm90b3R5cGUpO1xuXG4gICAgcHJvbWlzZS5wcm9taXNlRGlzcGF0Y2ggPSBmdW5jdGlvbiAocmVzb2x2ZSwgb3AsIGFyZ3MpIHtcbiAgICAgICAgdmFyIHJlc3VsdDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmIChkZXNjcmlwdG9yW29wXSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGRlc2NyaXB0b3Jbb3BdLmFwcGx5KHByb21pc2UsIGFyZ3MpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBmYWxsYmFjay5jYWxsKHByb21pc2UsIG9wLCBhcmdzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICByZXN1bHQgPSByZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVzb2x2ZSkge1xuICAgICAgICAgICAgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHByb21pc2UuaW5zcGVjdCA9IGluc3BlY3Q7XG5cbiAgICAvLyBYWFggZGVwcmVjYXRlZCBgdmFsdWVPZmAgYW5kIGBleGNlcHRpb25gIHN1cHBvcnRcbiAgICBpZiAoaW5zcGVjdCkge1xuICAgICAgICB2YXIgaW5zcGVjdGVkID0gaW5zcGVjdCgpO1xuICAgICAgICBpZiAoaW5zcGVjdGVkLnN0YXRlID09PSBcInJlamVjdGVkXCIpIHtcbiAgICAgICAgICAgIHByb21pc2UuZXhjZXB0aW9uID0gaW5zcGVjdGVkLnJlYXNvbjtcbiAgICAgICAgfVxuXG4gICAgICAgIHByb21pc2UudmFsdWVPZiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBpbnNwZWN0ZWQgPSBpbnNwZWN0KCk7XG4gICAgICAgICAgICBpZiAoaW5zcGVjdGVkLnN0YXRlID09PSBcInBlbmRpbmdcIiB8fFxuICAgICAgICAgICAgICAgIGluc3BlY3RlZC5zdGF0ZSA9PT0gXCJyZWplY3RlZFwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gaW5zcGVjdGVkLnZhbHVlO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiBwcm9taXNlO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gXCJbb2JqZWN0IFByb21pc2VdXCI7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50aGVuID0gZnVuY3Rpb24gKGZ1bGZpbGxlZCwgcmVqZWN0ZWQsIHByb2dyZXNzZWQpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB2YXIgZG9uZSA9IGZhbHNlOyAgIC8vIGVuc3VyZSB0aGUgdW50cnVzdGVkIHByb21pc2UgbWFrZXMgYXQgbW9zdCBhXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBzaW5nbGUgY2FsbCB0byBvbmUgb2YgdGhlIGNhbGxiYWNrc1xuXG4gICAgZnVuY3Rpb24gX2Z1bGZpbGxlZCh2YWx1ZSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiBmdWxmaWxsZWQgPT09IFwiZnVuY3Rpb25cIiA/IGZ1bGZpbGxlZCh2YWx1ZSkgOiB2YWx1ZTtcbiAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVqZWN0KGV4Y2VwdGlvbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfcmVqZWN0ZWQoZXhjZXB0aW9uKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcmVqZWN0ZWQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgbWFrZVN0YWNrVHJhY2VMb25nKGV4Y2VwdGlvbiwgc2VsZik7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3RlZChleGNlcHRpb24pO1xuICAgICAgICAgICAgfSBjYXRjaCAobmV3RXhjZXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXdFeGNlcHRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZWplY3QoZXhjZXB0aW9uKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfcHJvZ3Jlc3NlZCh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdHlwZW9mIHByb2dyZXNzZWQgPT09IFwiZnVuY3Rpb25cIiA/IHByb2dyZXNzZWQodmFsdWUpIDogdmFsdWU7XG4gICAgfVxuXG4gICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlbGYucHJvbWlzZURpc3BhdGNoKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkb25lID0gdHJ1ZTtcblxuICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZShfZnVsZmlsbGVkKHZhbHVlKSk7XG4gICAgICAgIH0sIFwid2hlblwiLCBbZnVuY3Rpb24gKGV4Y2VwdGlvbikge1xuICAgICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkb25lID0gdHJ1ZTtcblxuICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZShfcmVqZWN0ZWQoZXhjZXB0aW9uKSk7XG4gICAgICAgIH1dKTtcbiAgICB9KTtcblxuICAgIC8vIFByb2dyZXNzIHByb3BhZ2F0b3IgbmVlZCB0byBiZSBhdHRhY2hlZCBpbiB0aGUgY3VycmVudCB0aWNrLlxuICAgIHNlbGYucHJvbWlzZURpc3BhdGNoKHZvaWQgMCwgXCJ3aGVuXCIsIFt2b2lkIDAsIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgbmV3VmFsdWU7XG4gICAgICAgIHZhciB0aHJldyA9IGZhbHNlO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbmV3VmFsdWUgPSBfcHJvZ3Jlc3NlZCh2YWx1ZSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHRocmV3ID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChRLm9uZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBRLm9uZXJyb3IoZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRocmV3KSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5ub3RpZnkobmV3VmFsdWUpO1xuICAgICAgICB9XG4gICAgfV0pO1xuXG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG5RLnRhcCA9IGZ1bmN0aW9uIChwcm9taXNlLCBjYWxsYmFjaykge1xuICAgIHJldHVybiBRKHByb21pc2UpLnRhcChjYWxsYmFjayk7XG59O1xuXG4vKipcbiAqIFdvcmtzIGFsbW9zdCBsaWtlIFwiZmluYWxseVwiLCBidXQgbm90IGNhbGxlZCBmb3IgcmVqZWN0aW9ucy5cbiAqIE9yaWdpbmFsIHJlc29sdXRpb24gdmFsdWUgaXMgcGFzc2VkIHRocm91Z2ggY2FsbGJhY2sgdW5hZmZlY3RlZC5cbiAqIENhbGxiYWNrIG1heSByZXR1cm4gYSBwcm9taXNlIHRoYXQgd2lsbCBiZSBhd2FpdGVkIGZvci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gKiBAcmV0dXJucyB7US5Qcm9taXNlfVxuICogQGV4YW1wbGVcbiAqIGRvU29tZXRoaW5nKClcbiAqICAgLnRoZW4oLi4uKVxuICogICAudGFwKGNvbnNvbGUubG9nKVxuICogICAudGhlbiguLi4pO1xuICovXG5Qcm9taXNlLnByb3RvdHlwZS50YXAgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjayA9IFEoY2FsbGJhY2spO1xuXG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmZjYWxsKHZhbHVlKS50aGVuUmVzb2x2ZSh2YWx1ZSk7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhbiBvYnNlcnZlciBvbiBhIHByb21pc2UuXG4gKlxuICogR3VhcmFudGVlczpcbiAqXG4gKiAxLiB0aGF0IGZ1bGZpbGxlZCBhbmQgcmVqZWN0ZWQgd2lsbCBiZSBjYWxsZWQgb25seSBvbmNlLlxuICogMi4gdGhhdCBlaXRoZXIgdGhlIGZ1bGZpbGxlZCBjYWxsYmFjayBvciB0aGUgcmVqZWN0ZWQgY2FsbGJhY2sgd2lsbCBiZVxuICogICAgY2FsbGVkLCBidXQgbm90IGJvdGguXG4gKiAzLiB0aGF0IGZ1bGZpbGxlZCBhbmQgcmVqZWN0ZWQgd2lsbCBub3QgYmUgY2FsbGVkIGluIHRoaXMgdHVybi5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgICAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgdG8gb2JzZXJ2ZVxuICogQHBhcmFtIGZ1bGZpbGxlZCAgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdpdGggdGhlIGZ1bGZpbGxlZCB2YWx1ZVxuICogQHBhcmFtIHJlamVjdGVkICAgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdpdGggdGhlIHJlamVjdGlvbiBleGNlcHRpb25cbiAqIEBwYXJhbSBwcm9ncmVzc2VkIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCBvbiBhbnkgcHJvZ3Jlc3Mgbm90aWZpY2F0aW9uc1xuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlIGZyb20gdGhlIGludm9rZWQgY2FsbGJhY2tcbiAqL1xuUS53aGVuID0gd2hlbjtcbmZ1bmN0aW9uIHdoZW4odmFsdWUsIGZ1bGZpbGxlZCwgcmVqZWN0ZWQsIHByb2dyZXNzZWQpIHtcbiAgICByZXR1cm4gUSh2YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzc2VkKTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUudGhlblJlc29sdmUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHZhbHVlOyB9KTtcbn07XG5cblEudGhlblJlc29sdmUgPSBmdW5jdGlvbiAocHJvbWlzZSwgdmFsdWUpIHtcbiAgICByZXR1cm4gUShwcm9taXNlKS50aGVuUmVzb2x2ZSh2YWx1ZSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50aGVuUmVqZWN0ID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICAgIHJldHVybiB0aGlzLnRoZW4oZnVuY3Rpb24gKCkgeyB0aHJvdyByZWFzb247IH0pO1xufTtcblxuUS50aGVuUmVqZWN0ID0gZnVuY3Rpb24gKHByb21pc2UsIHJlYXNvbikge1xuICAgIHJldHVybiBRKHByb21pc2UpLnRoZW5SZWplY3QocmVhc29uKTtcbn07XG5cbi8qKlxuICogSWYgYW4gb2JqZWN0IGlzIG5vdCBhIHByb21pc2UsIGl0IGlzIGFzIFwibmVhclwiIGFzIHBvc3NpYmxlLlxuICogSWYgYSBwcm9taXNlIGlzIHJlamVjdGVkLCBpdCBpcyBhcyBcIm5lYXJcIiBhcyBwb3NzaWJsZSB0b28uXG4gKiBJZiBpdOKAmXMgYSBmdWxmaWxsZWQgcHJvbWlzZSwgdGhlIGZ1bGZpbGxtZW50IHZhbHVlIGlzIG5lYXJlci5cbiAqIElmIGl04oCZcyBhIGRlZmVycmVkIHByb21pc2UgYW5kIHRoZSBkZWZlcnJlZCBoYXMgYmVlbiByZXNvbHZlZCwgdGhlXG4gKiByZXNvbHV0aW9uIGlzIFwibmVhcmVyXCIuXG4gKiBAcGFyYW0gb2JqZWN0XG4gKiBAcmV0dXJucyBtb3N0IHJlc29sdmVkIChuZWFyZXN0KSBmb3JtIG9mIHRoZSBvYmplY3RcbiAqL1xuXG4vLyBYWFggc2hvdWxkIHdlIHJlLWRvIHRoaXM/XG5RLm5lYXJlciA9IG5lYXJlcjtcbmZ1bmN0aW9uIG5lYXJlcih2YWx1ZSkge1xuICAgIGlmIChpc1Byb21pc2UodmFsdWUpKSB7XG4gICAgICAgIHZhciBpbnNwZWN0ZWQgPSB2YWx1ZS5pbnNwZWN0KCk7XG4gICAgICAgIGlmIChpbnNwZWN0ZWQuc3RhdGUgPT09IFwiZnVsZmlsbGVkXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBpbnNwZWN0ZWQudmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xufVxuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHByb21pc2UuXG4gKiBPdGhlcndpc2UgaXQgaXMgYSBmdWxmaWxsZWQgdmFsdWUuXG4gKi9cblEuaXNQcm9taXNlID0gaXNQcm9taXNlO1xuZnVuY3Rpb24gaXNQcm9taXNlKG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgaW5zdGFuY2VvZiBQcm9taXNlO1xufVxuXG5RLmlzUHJvbWlzZUFsaWtlID0gaXNQcm9taXNlQWxpa2U7XG5mdW5jdGlvbiBpc1Byb21pc2VBbGlrZShvYmplY3QpIHtcbiAgICByZXR1cm4gaXNPYmplY3Qob2JqZWN0KSAmJiB0eXBlb2Ygb2JqZWN0LnRoZW4gPT09IFwiZnVuY3Rpb25cIjtcbn1cblxuLyoqXG4gKiBAcmV0dXJucyB3aGV0aGVyIHRoZSBnaXZlbiBvYmplY3QgaXMgYSBwZW5kaW5nIHByb21pc2UsIG1lYW5pbmcgbm90XG4gKiBmdWxmaWxsZWQgb3IgcmVqZWN0ZWQuXG4gKi9cblEuaXNQZW5kaW5nID0gaXNQZW5kaW5nO1xuZnVuY3Rpb24gaXNQZW5kaW5nKG9iamVjdCkge1xuICAgIHJldHVybiBpc1Byb21pc2Uob2JqZWN0KSAmJiBvYmplY3QuaW5zcGVjdCgpLnN0YXRlID09PSBcInBlbmRpbmdcIjtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuaXNQZW5kaW5nID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmluc3BlY3QoKS5zdGF0ZSA9PT0gXCJwZW5kaW5nXCI7XG59O1xuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHZhbHVlIG9yIGZ1bGZpbGxlZFxuICogcHJvbWlzZS5cbiAqL1xuUS5pc0Z1bGZpbGxlZCA9IGlzRnVsZmlsbGVkO1xuZnVuY3Rpb24gaXNGdWxmaWxsZWQob2JqZWN0KSB7XG4gICAgcmV0dXJuICFpc1Byb21pc2Uob2JqZWN0KSB8fCBvYmplY3QuaW5zcGVjdCgpLnN0YXRlID09PSBcImZ1bGZpbGxlZFwiO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5pc0Z1bGZpbGxlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5pbnNwZWN0KCkuc3RhdGUgPT09IFwiZnVsZmlsbGVkXCI7XG59O1xuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHJlamVjdGVkIHByb21pc2UuXG4gKi9cblEuaXNSZWplY3RlZCA9IGlzUmVqZWN0ZWQ7XG5mdW5jdGlvbiBpc1JlamVjdGVkKG9iamVjdCkge1xuICAgIHJldHVybiBpc1Byb21pc2Uob2JqZWN0KSAmJiBvYmplY3QuaW5zcGVjdCgpLnN0YXRlID09PSBcInJlamVjdGVkXCI7XG59XG5cblByb21pc2UucHJvdG90eXBlLmlzUmVqZWN0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuaW5zcGVjdCgpLnN0YXRlID09PSBcInJlamVjdGVkXCI7XG59O1xuXG4vLy8vIEJFR0lOIFVOSEFORExFRCBSRUpFQ1RJT04gVFJBQ0tJTkdcblxuLy8gVGhpcyBwcm9taXNlIGxpYnJhcnkgY29uc3VtZXMgZXhjZXB0aW9ucyB0aHJvd24gaW4gaGFuZGxlcnMgc28gdGhleSBjYW4gYmVcbi8vIGhhbmRsZWQgYnkgYSBzdWJzZXF1ZW50IHByb21pc2UuICBUaGUgZXhjZXB0aW9ucyBnZXQgYWRkZWQgdG8gdGhpcyBhcnJheSB3aGVuXG4vLyB0aGV5IGFyZSBjcmVhdGVkLCBhbmQgcmVtb3ZlZCB3aGVuIHRoZXkgYXJlIGhhbmRsZWQuICBOb3RlIHRoYXQgaW4gRVM2IG9yXG4vLyBzaGltbWVkIGVudmlyb25tZW50cywgdGhpcyB3b3VsZCBuYXR1cmFsbHkgYmUgYSBgU2V0YC5cbnZhciB1bmhhbmRsZWRSZWFzb25zID0gW107XG52YXIgdW5oYW5kbGVkUmVqZWN0aW9ucyA9IFtdO1xudmFyIHJlcG9ydGVkVW5oYW5kbGVkUmVqZWN0aW9ucyA9IFtdO1xudmFyIHRyYWNrVW5oYW5kbGVkUmVqZWN0aW9ucyA9IHRydWU7XG5cbmZ1bmN0aW9uIHJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucygpIHtcbiAgICB1bmhhbmRsZWRSZWFzb25zLmxlbmd0aCA9IDA7XG4gICAgdW5oYW5kbGVkUmVqZWN0aW9ucy5sZW5ndGggPSAwO1xuXG4gICAgaWYgKCF0cmFja1VuaGFuZGxlZFJlamVjdGlvbnMpIHtcbiAgICAgICAgdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zID0gdHJ1ZTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHRyYWNrUmVqZWN0aW9uKHByb21pc2UsIHJlYXNvbikge1xuICAgIGlmICghdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBwcm9jZXNzLmVtaXQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBRLm5leHRUaWNrLnJ1bkFmdGVyKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChhcnJheV9pbmRleE9mKHVuaGFuZGxlZFJlamVjdGlvbnMsIHByb21pc2UpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIHByb2Nlc3MuZW1pdChcInVuaGFuZGxlZFJlamVjdGlvblwiLCByZWFzb24sIHByb21pc2UpO1xuICAgICAgICAgICAgICAgIHJlcG9ydGVkVW5oYW5kbGVkUmVqZWN0aW9ucy5wdXNoKHByb21pc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICB1bmhhbmRsZWRSZWplY3Rpb25zLnB1c2gocHJvbWlzZSk7XG4gICAgaWYgKHJlYXNvbiAmJiB0eXBlb2YgcmVhc29uLnN0YWNrICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIHVuaGFuZGxlZFJlYXNvbnMucHVzaChyZWFzb24uc3RhY2spO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHVuaGFuZGxlZFJlYXNvbnMucHVzaChcIihubyBzdGFjaykgXCIgKyByZWFzb24pO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gdW50cmFja1JlamVjdGlvbihwcm9taXNlKSB7XG4gICAgaWYgKCF0cmFja1VuaGFuZGxlZFJlamVjdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBhdCA9IGFycmF5X2luZGV4T2YodW5oYW5kbGVkUmVqZWN0aW9ucywgcHJvbWlzZSk7XG4gICAgaWYgKGF0ICE9PSAtMSkge1xuICAgICAgICBpZiAodHlwZW9mIHByb2Nlc3MgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHByb2Nlc3MuZW1pdCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICBRLm5leHRUaWNrLnJ1bkFmdGVyKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgYXRSZXBvcnQgPSBhcnJheV9pbmRleE9mKHJlcG9ydGVkVW5oYW5kbGVkUmVqZWN0aW9ucywgcHJvbWlzZSk7XG4gICAgICAgICAgICAgICAgaWYgKGF0UmVwb3J0ICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICBwcm9jZXNzLmVtaXQoXCJyZWplY3Rpb25IYW5kbGVkXCIsIHVuaGFuZGxlZFJlYXNvbnNbYXRdLCBwcm9taXNlKTtcbiAgICAgICAgICAgICAgICAgICAgcmVwb3J0ZWRVbmhhbmRsZWRSZWplY3Rpb25zLnNwbGljZShhdFJlcG9ydCwgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdW5oYW5kbGVkUmVqZWN0aW9ucy5zcGxpY2UoYXQsIDEpO1xuICAgICAgICB1bmhhbmRsZWRSZWFzb25zLnNwbGljZShhdCwgMSk7XG4gICAgfVxufVxuXG5RLnJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucyA9IHJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucztcblxuUS5nZXRVbmhhbmRsZWRSZWFzb25zID0gZnVuY3Rpb24gKCkge1xuICAgIC8vIE1ha2UgYSBjb3B5IHNvIHRoYXQgY29uc3VtZXJzIGNhbid0IGludGVyZmVyZSB3aXRoIG91ciBpbnRlcm5hbCBzdGF0ZS5cbiAgICByZXR1cm4gdW5oYW5kbGVkUmVhc29ucy5zbGljZSgpO1xufTtcblxuUS5zdG9wVW5oYW5kbGVkUmVqZWN0aW9uVHJhY2tpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmVzZXRVbmhhbmRsZWRSZWplY3Rpb25zKCk7XG4gICAgdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zID0gZmFsc2U7XG59O1xuXG5yZXNldFVuaGFuZGxlZFJlamVjdGlvbnMoKTtcblxuLy8vLyBFTkQgVU5IQU5ETEVEIFJFSkVDVElPTiBUUkFDS0lOR1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSByZWplY3RlZCBwcm9taXNlLlxuICogQHBhcmFtIHJlYXNvbiB2YWx1ZSBkZXNjcmliaW5nIHRoZSBmYWlsdXJlXG4gKi9cblEucmVqZWN0ID0gcmVqZWN0O1xuZnVuY3Rpb24gcmVqZWN0KHJlYXNvbikge1xuICAgIHZhciByZWplY3Rpb24gPSBQcm9taXNlKHtcbiAgICAgICAgXCJ3aGVuXCI6IGZ1bmN0aW9uIChyZWplY3RlZCkge1xuICAgICAgICAgICAgLy8gbm90ZSB0aGF0IHRoZSBlcnJvciBoYXMgYmVlbiBoYW5kbGVkXG4gICAgICAgICAgICBpZiAocmVqZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICB1bnRyYWNrUmVqZWN0aW9uKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlamVjdGVkID8gcmVqZWN0ZWQocmVhc29uKSA6IHRoaXM7XG4gICAgICAgIH1cbiAgICB9LCBmdW5jdGlvbiBmYWxsYmFjaygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSwgZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgICAgICAgcmV0dXJuIHsgc3RhdGU6IFwicmVqZWN0ZWRcIiwgcmVhc29uOiByZWFzb24gfTtcbiAgICB9KTtcblxuICAgIC8vIE5vdGUgdGhhdCB0aGUgcmVhc29uIGhhcyBub3QgYmVlbiBoYW5kbGVkLlxuICAgIHRyYWNrUmVqZWN0aW9uKHJlamVjdGlvbiwgcmVhc29uKTtcblxuICAgIHJldHVybiByZWplY3Rpb247XG59XG5cbi8qKlxuICogQ29uc3RydWN0cyBhIGZ1bGZpbGxlZCBwcm9taXNlIGZvciBhbiBpbW1lZGlhdGUgcmVmZXJlbmNlLlxuICogQHBhcmFtIHZhbHVlIGltbWVkaWF0ZSByZWZlcmVuY2VcbiAqL1xuUS5mdWxmaWxsID0gZnVsZmlsbDtcbmZ1bmN0aW9uIGZ1bGZpbGwodmFsdWUpIHtcbiAgICByZXR1cm4gUHJvbWlzZSh7XG4gICAgICAgIFwid2hlblwiOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH0sXG4gICAgICAgIFwiZ2V0XCI6IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWVbbmFtZV07XG4gICAgICAgIH0sXG4gICAgICAgIFwic2V0XCI6IGZ1bmN0aW9uIChuYW1lLCByaHMpIHtcbiAgICAgICAgICAgIHZhbHVlW25hbWVdID0gcmhzO1xuICAgICAgICB9LFxuICAgICAgICBcImRlbGV0ZVwiOiBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICAgICAgZGVsZXRlIHZhbHVlW25hbWVdO1xuICAgICAgICB9LFxuICAgICAgICBcInBvc3RcIjogZnVuY3Rpb24gKG5hbWUsIGFyZ3MpIHtcbiAgICAgICAgICAgIC8vIE1hcmsgTWlsbGVyIHByb3Bvc2VzIHRoYXQgcG9zdCB3aXRoIG5vIG5hbWUgc2hvdWxkIGFwcGx5IGFcbiAgICAgICAgICAgIC8vIHByb21pc2VkIGZ1bmN0aW9uLlxuICAgICAgICAgICAgaWYgKG5hbWUgPT09IG51bGwgfHwgbmFtZSA9PT0gdm9pZCAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLmFwcGx5KHZvaWQgMCwgYXJncyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZVtuYW1lXS5hcHBseSh2YWx1ZSwgYXJncyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIFwiYXBwbHlcIjogZnVuY3Rpb24gKHRoaXNwLCBhcmdzKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWUuYXBwbHkodGhpc3AsIGFyZ3MpO1xuICAgICAgICB9LFxuICAgICAgICBcImtleXNcIjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIG9iamVjdF9rZXlzKHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH0sIHZvaWQgMCwgZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgICAgICAgcmV0dXJuIHsgc3RhdGU6IFwiZnVsZmlsbGVkXCIsIHZhbHVlOiB2YWx1ZSB9O1xuICAgIH0pO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIHRoZW5hYmxlcyB0byBRIHByb21pc2VzLlxuICogQHBhcmFtIHByb21pc2UgdGhlbmFibGUgcHJvbWlzZVxuICogQHJldHVybnMgYSBRIHByb21pc2VcbiAqL1xuZnVuY3Rpb24gY29lcmNlKHByb21pc2UpIHtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcHJvbWlzZS50aGVuKGRlZmVycmVkLnJlc29sdmUsIGRlZmVycmVkLnJlamVjdCwgZGVmZXJyZWQubm90aWZ5KTtcbiAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufVxuXG4vKipcbiAqIEFubm90YXRlcyBhbiBvYmplY3Qgc3VjaCB0aGF0IGl0IHdpbGwgbmV2ZXIgYmVcbiAqIHRyYW5zZmVycmVkIGF3YXkgZnJvbSB0aGlzIHByb2Nlc3Mgb3ZlciBhbnkgcHJvbWlzZVxuICogY29tbXVuaWNhdGlvbiBjaGFubmVsLlxuICogQHBhcmFtIG9iamVjdFxuICogQHJldHVybnMgcHJvbWlzZSBhIHdyYXBwaW5nIG9mIHRoYXQgb2JqZWN0IHRoYXRcbiAqIGFkZGl0aW9uYWxseSByZXNwb25kcyB0byB0aGUgXCJpc0RlZlwiIG1lc3NhZ2VcbiAqIHdpdGhvdXQgYSByZWplY3Rpb24uXG4gKi9cblEubWFzdGVyID0gbWFzdGVyO1xuZnVuY3Rpb24gbWFzdGVyKG9iamVjdCkge1xuICAgIHJldHVybiBQcm9taXNlKHtcbiAgICAgICAgXCJpc0RlZlwiOiBmdW5jdGlvbiAoKSB7fVxuICAgIH0sIGZ1bmN0aW9uIGZhbGxiYWNrKG9wLCBhcmdzKSB7XG4gICAgICAgIHJldHVybiBkaXNwYXRjaChvYmplY3QsIG9wLCBhcmdzKTtcbiAgICB9LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBRKG9iamVjdCkuaW5zcGVjdCgpO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIFNwcmVhZHMgdGhlIHZhbHVlcyBvZiBhIHByb21pc2VkIGFycmF5IG9mIGFyZ3VtZW50cyBpbnRvIHRoZVxuICogZnVsZmlsbG1lbnQgY2FsbGJhY2suXG4gKiBAcGFyYW0gZnVsZmlsbGVkIGNhbGxiYWNrIHRoYXQgcmVjZWl2ZXMgdmFyaWFkaWMgYXJndW1lbnRzIGZyb20gdGhlXG4gKiBwcm9taXNlZCBhcnJheVxuICogQHBhcmFtIHJlamVjdGVkIGNhbGxiYWNrIHRoYXQgcmVjZWl2ZXMgdGhlIGV4Y2VwdGlvbiBpZiB0aGUgcHJvbWlzZVxuICogaXMgcmVqZWN0ZWQuXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWUgb3IgdGhyb3duIGV4Y2VwdGlvbiBvZlxuICogZWl0aGVyIGNhbGxiYWNrLlxuICovXG5RLnNwcmVhZCA9IHNwcmVhZDtcbmZ1bmN0aW9uIHNwcmVhZCh2YWx1ZSwgZnVsZmlsbGVkLCByZWplY3RlZCkge1xuICAgIHJldHVybiBRKHZhbHVlKS5zcHJlYWQoZnVsZmlsbGVkLCByZWplY3RlZCk7XG59XG5cblByb21pc2UucHJvdG90eXBlLnNwcmVhZCA9IGZ1bmN0aW9uIChmdWxmaWxsZWQsIHJlamVjdGVkKSB7XG4gICAgcmV0dXJuIHRoaXMuYWxsKCkudGhlbihmdW5jdGlvbiAoYXJyYXkpIHtcbiAgICAgICAgcmV0dXJuIGZ1bGZpbGxlZC5hcHBseSh2b2lkIDAsIGFycmF5KTtcbiAgICB9LCByZWplY3RlZCk7XG59O1xuXG4vKipcbiAqIFRoZSBhc3luYyBmdW5jdGlvbiBpcyBhIGRlY29yYXRvciBmb3IgZ2VuZXJhdG9yIGZ1bmN0aW9ucywgdHVybmluZ1xuICogdGhlbSBpbnRvIGFzeW5jaHJvbm91cyBnZW5lcmF0b3JzLiAgQWx0aG91Z2ggZ2VuZXJhdG9ycyBhcmUgb25seSBwYXJ0XG4gKiBvZiB0aGUgbmV3ZXN0IEVDTUFTY3JpcHQgNiBkcmFmdHMsIHRoaXMgY29kZSBkb2VzIG5vdCBjYXVzZSBzeW50YXhcbiAqIGVycm9ycyBpbiBvbGRlciBlbmdpbmVzLiAgVGhpcyBjb2RlIHNob3VsZCBjb250aW51ZSB0byB3b3JrIGFuZCB3aWxsXG4gKiBpbiBmYWN0IGltcHJvdmUgb3ZlciB0aW1lIGFzIHRoZSBsYW5ndWFnZSBpbXByb3Zlcy5cbiAqXG4gKiBFUzYgZ2VuZXJhdG9ycyBhcmUgY3VycmVudGx5IHBhcnQgb2YgVjggdmVyc2lvbiAzLjE5IHdpdGggdGhlXG4gKiAtLWhhcm1vbnktZ2VuZXJhdG9ycyBydW50aW1lIGZsYWcgZW5hYmxlZC4gIFNwaWRlck1vbmtleSBoYXMgaGFkIHRoZW1cbiAqIGZvciBsb25nZXIsIGJ1dCB1bmRlciBhbiBvbGRlciBQeXRob24taW5zcGlyZWQgZm9ybS4gIFRoaXMgZnVuY3Rpb25cbiAqIHdvcmtzIG9uIGJvdGgga2luZHMgb2YgZ2VuZXJhdG9ycy5cbiAqXG4gKiBEZWNvcmF0ZXMgYSBnZW5lcmF0b3IgZnVuY3Rpb24gc3VjaCB0aGF0OlxuICogIC0gaXQgbWF5IHlpZWxkIHByb21pc2VzXG4gKiAgLSBleGVjdXRpb24gd2lsbCBjb250aW51ZSB3aGVuIHRoYXQgcHJvbWlzZSBpcyBmdWxmaWxsZWRcbiAqICAtIHRoZSB2YWx1ZSBvZiB0aGUgeWllbGQgZXhwcmVzc2lvbiB3aWxsIGJlIHRoZSBmdWxmaWxsZWQgdmFsdWVcbiAqICAtIGl0IHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlICh3aGVuIHRoZSBnZW5lcmF0b3JcbiAqICAgIHN0b3BzIGl0ZXJhdGluZylcbiAqICAtIHRoZSBkZWNvcmF0ZWQgZnVuY3Rpb24gcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqICAgIG9mIHRoZSBnZW5lcmF0b3Igb3IgdGhlIGZpcnN0IHJlamVjdGVkIHByb21pc2UgYW1vbmcgdGhvc2VcbiAqICAgIHlpZWxkZWQuXG4gKiAgLSBpZiBhbiBlcnJvciBpcyB0aHJvd24gaW4gdGhlIGdlbmVyYXRvciwgaXQgcHJvcGFnYXRlcyB0aHJvdWdoXG4gKiAgICBldmVyeSBmb2xsb3dpbmcgeWllbGQgdW50aWwgaXQgaXMgY2F1Z2h0LCBvciB1bnRpbCBpdCBlc2NhcGVzXG4gKiAgICB0aGUgZ2VuZXJhdG9yIGZ1bmN0aW9uIGFsdG9nZXRoZXIsIGFuZCBpcyB0cmFuc2xhdGVkIGludG8gYVxuICogICAgcmVqZWN0aW9uIGZvciB0aGUgcHJvbWlzZSByZXR1cm5lZCBieSB0aGUgZGVjb3JhdGVkIGdlbmVyYXRvci5cbiAqL1xuUS5hc3luYyA9IGFzeW5jO1xuZnVuY3Rpb24gYXN5bmMobWFrZUdlbmVyYXRvcikge1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIHdoZW4gdmVyYiBpcyBcInNlbmRcIiwgYXJnIGlzIGEgdmFsdWVcbiAgICAgICAgLy8gd2hlbiB2ZXJiIGlzIFwidGhyb3dcIiwgYXJnIGlzIGFuIGV4Y2VwdGlvblxuICAgICAgICBmdW5jdGlvbiBjb250aW51ZXIodmVyYiwgYXJnKSB7XG4gICAgICAgICAgICB2YXIgcmVzdWx0O1xuXG4gICAgICAgICAgICAvLyBVbnRpbCBWOCAzLjE5IC8gQ2hyb21pdW0gMjkgaXMgcmVsZWFzZWQsIFNwaWRlck1vbmtleSBpcyB0aGUgb25seVxuICAgICAgICAgICAgLy8gZW5naW5lIHRoYXQgaGFzIGEgZGVwbG95ZWQgYmFzZSBvZiBicm93c2VycyB0aGF0IHN1cHBvcnQgZ2VuZXJhdG9ycy5cbiAgICAgICAgICAgIC8vIEhvd2V2ZXIsIFNNJ3MgZ2VuZXJhdG9ycyB1c2UgdGhlIFB5dGhvbi1pbnNwaXJlZCBzZW1hbnRpY3Mgb2ZcbiAgICAgICAgICAgIC8vIG91dGRhdGVkIEVTNiBkcmFmdHMuICBXZSB3b3VsZCBsaWtlIHRvIHN1cHBvcnQgRVM2LCBidXQgd2UnZCBhbHNvXG4gICAgICAgICAgICAvLyBsaWtlIHRvIG1ha2UgaXQgcG9zc2libGUgdG8gdXNlIGdlbmVyYXRvcnMgaW4gZGVwbG95ZWQgYnJvd3NlcnMsIHNvXG4gICAgICAgICAgICAvLyB3ZSBhbHNvIHN1cHBvcnQgUHl0aG9uLXN0eWxlIGdlbmVyYXRvcnMuICBBdCBzb21lIHBvaW50IHdlIGNhbiByZW1vdmVcbiAgICAgICAgICAgIC8vIHRoaXMgYmxvY2suXG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgU3RvcEl0ZXJhdGlvbiA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgICAgIC8vIEVTNiBHZW5lcmF0b3JzXG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gZ2VuZXJhdG9yW3ZlcmJdKGFyZyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5kb25lKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBRKHJlc3VsdC52YWx1ZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHdoZW4ocmVzdWx0LnZhbHVlLCBjYWxsYmFjaywgZXJyYmFjayk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBTcGlkZXJNb25rZXkgR2VuZXJhdG9yc1xuICAgICAgICAgICAgICAgIC8vIEZJWE1FOiBSZW1vdmUgdGhpcyBjYXNlIHdoZW4gU00gZG9lcyBFUzYgZ2VuZXJhdG9ycy5cbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBnZW5lcmF0b3JbdmVyYl0oYXJnKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzU3RvcEl0ZXJhdGlvbihleGNlcHRpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUShleGNlcHRpb24udmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChleGNlcHRpb24pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB3aGVuKHJlc3VsdCwgY2FsbGJhY2ssIGVycmJhY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHZhciBnZW5lcmF0b3IgPSBtYWtlR2VuZXJhdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIHZhciBjYWxsYmFjayA9IGNvbnRpbnVlci5iaW5kKGNvbnRpbnVlciwgXCJuZXh0XCIpO1xuICAgICAgICB2YXIgZXJyYmFjayA9IGNvbnRpbnVlci5iaW5kKGNvbnRpbnVlciwgXCJ0aHJvd1wiKTtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgfTtcbn1cblxuLyoqXG4gKiBUaGUgc3Bhd24gZnVuY3Rpb24gaXMgYSBzbWFsbCB3cmFwcGVyIGFyb3VuZCBhc3luYyB0aGF0IGltbWVkaWF0ZWx5XG4gKiBjYWxscyB0aGUgZ2VuZXJhdG9yIGFuZCBhbHNvIGVuZHMgdGhlIHByb21pc2UgY2hhaW4sIHNvIHRoYXQgYW55XG4gKiB1bmhhbmRsZWQgZXJyb3JzIGFyZSB0aHJvd24gaW5zdGVhZCBvZiBmb3J3YXJkZWQgdG8gdGhlIGVycm9yXG4gKiBoYW5kbGVyLiBUaGlzIGlzIHVzZWZ1bCBiZWNhdXNlIGl0J3MgZXh0cmVtZWx5IGNvbW1vbiB0byBydW5cbiAqIGdlbmVyYXRvcnMgYXQgdGhlIHRvcC1sZXZlbCB0byB3b3JrIHdpdGggbGlicmFyaWVzLlxuICovXG5RLnNwYXduID0gc3Bhd247XG5mdW5jdGlvbiBzcGF3bihtYWtlR2VuZXJhdG9yKSB7XG4gICAgUS5kb25lKFEuYXN5bmMobWFrZUdlbmVyYXRvcikoKSk7XG59XG5cbi8vIEZJWE1FOiBSZW1vdmUgdGhpcyBpbnRlcmZhY2Ugb25jZSBFUzYgZ2VuZXJhdG9ycyBhcmUgaW4gU3BpZGVyTW9ua2V5LlxuLyoqXG4gKiBUaHJvd3MgYSBSZXR1cm5WYWx1ZSBleGNlcHRpb24gdG8gc3RvcCBhbiBhc3luY2hyb25vdXMgZ2VuZXJhdG9yLlxuICpcbiAqIFRoaXMgaW50ZXJmYWNlIGlzIGEgc3RvcC1nYXAgbWVhc3VyZSB0byBzdXBwb3J0IGdlbmVyYXRvciByZXR1cm5cbiAqIHZhbHVlcyBpbiBvbGRlciBGaXJlZm94L1NwaWRlck1vbmtleS4gIEluIGJyb3dzZXJzIHRoYXQgc3VwcG9ydCBFUzZcbiAqIGdlbmVyYXRvcnMgbGlrZSBDaHJvbWl1bSAyOSwganVzdCB1c2UgXCJyZXR1cm5cIiBpbiB5b3VyIGdlbmVyYXRvclxuICogZnVuY3Rpb25zLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSB0aGUgcmV0dXJuIHZhbHVlIGZvciB0aGUgc3Vycm91bmRpbmcgZ2VuZXJhdG9yXG4gKiBAdGhyb3dzIFJldHVyblZhbHVlIGV4Y2VwdGlvbiB3aXRoIHRoZSB2YWx1ZS5cbiAqIEBleGFtcGxlXG4gKiAvLyBFUzYgc3R5bGVcbiAqIFEuYXN5bmMoZnVuY3Rpb24qICgpIHtcbiAqICAgICAgdmFyIGZvbyA9IHlpZWxkIGdldEZvb1Byb21pc2UoKTtcbiAqICAgICAgdmFyIGJhciA9IHlpZWxkIGdldEJhclByb21pc2UoKTtcbiAqICAgICAgcmV0dXJuIGZvbyArIGJhcjtcbiAqIH0pXG4gKiAvLyBPbGRlciBTcGlkZXJNb25rZXkgc3R5bGVcbiAqIFEuYXN5bmMoZnVuY3Rpb24gKCkge1xuICogICAgICB2YXIgZm9vID0geWllbGQgZ2V0Rm9vUHJvbWlzZSgpO1xuICogICAgICB2YXIgYmFyID0geWllbGQgZ2V0QmFyUHJvbWlzZSgpO1xuICogICAgICBRLnJldHVybihmb28gKyBiYXIpO1xuICogfSlcbiAqL1xuUVtcInJldHVyblwiXSA9IF9yZXR1cm47XG5mdW5jdGlvbiBfcmV0dXJuKHZhbHVlKSB7XG4gICAgdGhyb3cgbmV3IFFSZXR1cm5WYWx1ZSh2YWx1ZSk7XG59XG5cbi8qKlxuICogVGhlIHByb21pc2VkIGZ1bmN0aW9uIGRlY29yYXRvciBlbnN1cmVzIHRoYXQgYW55IHByb21pc2UgYXJndW1lbnRzXG4gKiBhcmUgc2V0dGxlZCBhbmQgcGFzc2VkIGFzIHZhbHVlcyAoYHRoaXNgIGlzIGFsc28gc2V0dGxlZCBhbmQgcGFzc2VkXG4gKiBhcyBhIHZhbHVlKS4gIEl0IHdpbGwgYWxzbyBlbnN1cmUgdGhhdCB0aGUgcmVzdWx0IG9mIGEgZnVuY3Rpb24gaXNcbiAqIGFsd2F5cyBhIHByb21pc2UuXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBhZGQgPSBRLnByb21pc2VkKGZ1bmN0aW9uIChhLCBiKSB7XG4gKiAgICAgcmV0dXJuIGEgKyBiO1xuICogfSk7XG4gKiBhZGQoUShhKSwgUShCKSk7XG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIHRvIGRlY29yYXRlXG4gKiBAcmV0dXJucyB7ZnVuY3Rpb259IGEgZnVuY3Rpb24gdGhhdCBoYXMgYmVlbiBkZWNvcmF0ZWQuXG4gKi9cblEucHJvbWlzZWQgPSBwcm9taXNlZDtcbmZ1bmN0aW9uIHByb21pc2VkKGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHNwcmVhZChbdGhpcywgYWxsKGFyZ3VtZW50cyldLCBmdW5jdGlvbiAoc2VsZiwgYXJncykge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KHNlbGYsIGFyZ3MpO1xuICAgICAgICB9KTtcbiAgICB9O1xufVxuXG4vKipcbiAqIHNlbmRzIGEgbWVzc2FnZSB0byBhIHZhbHVlIGluIGEgZnV0dXJlIHR1cm5cbiAqIEBwYXJhbSBvYmplY3QqIHRoZSByZWNpcGllbnRcbiAqIEBwYXJhbSBvcCB0aGUgbmFtZSBvZiB0aGUgbWVzc2FnZSBvcGVyYXRpb24sIGUuZy4sIFwid2hlblwiLFxuICogQHBhcmFtIGFyZ3MgZnVydGhlciBhcmd1bWVudHMgdG8gYmUgZm9yd2FyZGVkIHRvIHRoZSBvcGVyYXRpb25cbiAqIEByZXR1cm5zIHJlc3VsdCB7UHJvbWlzZX0gYSBwcm9taXNlIGZvciB0aGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb25cbiAqL1xuUS5kaXNwYXRjaCA9IGRpc3BhdGNoO1xuZnVuY3Rpb24gZGlzcGF0Y2gob2JqZWN0LCBvcCwgYXJncykge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2gob3AsIGFyZ3MpO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5kaXNwYXRjaCA9IGZ1bmN0aW9uIChvcCwgYXJncykge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICBzZWxmLnByb21pc2VEaXNwYXRjaChkZWZlcnJlZC5yZXNvbHZlLCBvcCwgYXJncyk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIEdldHMgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgcHJvcGVydHkgdG8gZ2V0XG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSBwcm9wZXJ0eSB2YWx1ZVxuICovXG5RLmdldCA9IGZ1bmN0aW9uIChvYmplY3QsIGtleSkge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2goXCJnZXRcIiwgW2tleV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKGtleSkge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwiZ2V0XCIsIFtrZXldKTtcbn07XG5cbi8qKlxuICogU2V0cyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eSBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIG9iamVjdCBvYmplY3RcbiAqIEBwYXJhbSBuYW1lICAgICAgbmFtZSBvZiBwcm9wZXJ0eSB0byBzZXRcbiAqIEBwYXJhbSB2YWx1ZSAgICAgbmV3IHZhbHVlIG9mIHByb3BlcnR5XG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqL1xuUS5zZXQgPSBmdW5jdGlvbiAob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcInNldFwiLCBba2V5LCB2YWx1ZV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcInNldFwiLCBba2V5LCB2YWx1ZV0pO1xufTtcblxuLyoqXG4gKiBEZWxldGVzIGEgcHJvcGVydHkgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgcHJvcGVydHkgdG8gZGVsZXRlXG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqL1xuUS5kZWwgPSAvLyBYWFggbGVnYWN5XG5RW1wiZGVsZXRlXCJdID0gZnVuY3Rpb24gKG9iamVjdCwga2V5KSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImRlbGV0ZVwiLCBba2V5XSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5kZWwgPSAvLyBYWFggbGVnYWN5XG5Qcm9taXNlLnByb3RvdHlwZVtcImRlbGV0ZVwiXSA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImRlbGV0ZVwiLCBba2V5XSk7XG59O1xuXG4vKipcbiAqIEludm9rZXMgYSBtZXRob2QgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgbWV0aG9kIHRvIGludm9rZVxuICogQHBhcmFtIHZhbHVlICAgICBhIHZhbHVlIHRvIHBvc3QsIHR5cGljYWxseSBhbiBhcnJheSBvZlxuICogICAgICAgICAgICAgICAgICBpbnZvY2F0aW9uIGFyZ3VtZW50cyBmb3IgcHJvbWlzZXMgdGhhdFxuICogICAgICAgICAgICAgICAgICBhcmUgdWx0aW1hdGVseSBiYWNrZWQgd2l0aCBgcmVzb2x2ZWAgdmFsdWVzLFxuICogICAgICAgICAgICAgICAgICBhcyBvcHBvc2VkIHRvIHRob3NlIGJhY2tlZCB3aXRoIFVSTHNcbiAqICAgICAgICAgICAgICAgICAgd2hlcmVpbiB0aGUgcG9zdGVkIHZhbHVlIGNhbiBiZSBhbnlcbiAqICAgICAgICAgICAgICAgICAgSlNPTiBzZXJpYWxpemFibGUgb2JqZWN0LlxuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlXG4gKi9cbi8vIGJvdW5kIGxvY2FsbHkgYmVjYXVzZSBpdCBpcyB1c2VkIGJ5IG90aGVyIG1ldGhvZHNcblEubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblEucG9zdCA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWUsIGFyZ3MpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJnc10pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblByb21pc2UucHJvdG90eXBlLnBvc3QgPSBmdW5jdGlvbiAobmFtZSwgYXJncykge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJnc10pO1xufTtcblxuLyoqXG4gKiBJbnZva2VzIGEgbWV0aG9kIGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IG9iamVjdFxuICogQHBhcmFtIG5hbWUgICAgICBuYW1lIG9mIG1ldGhvZCB0byBpbnZva2VcbiAqIEBwYXJhbSAuLi5hcmdzICAgYXJyYXkgb2YgaW52b2NhdGlvbiBhcmd1bWVudHNcbiAqIEByZXR1cm4gcHJvbWlzZSBmb3IgdGhlIHJldHVybiB2YWx1ZVxuICovXG5RLnNlbmQgPSAvLyBYWFggTWFyayBNaWxsZXIncyBwcm9wb3NlZCBwYXJsYW5jZVxuUS5tY2FsbCA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5RLmludm9rZSA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWUgLyouLi5hcmdzKi8pIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAyKV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuc2VuZCA9IC8vIFhYWCBNYXJrIE1pbGxlcidzIHByb3Bvc2VkIHBhcmxhbmNlXG5Qcm9taXNlLnByb3RvdHlwZS5tY2FsbCA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5Qcm9taXNlLnByb3RvdHlwZS5pbnZva2UgPSBmdW5jdGlvbiAobmFtZSAvKi4uLmFyZ3MqLykge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKV0pO1xufTtcblxuLyoqXG4gKiBBcHBsaWVzIHRoZSBwcm9taXNlZCBmdW5jdGlvbiBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBmdW5jdGlvblxuICogQHBhcmFtIGFyZ3MgICAgICBhcnJheSBvZiBhcHBsaWNhdGlvbiBhcmd1bWVudHNcbiAqL1xuUS5mYXBwbHkgPSBmdW5jdGlvbiAob2JqZWN0LCBhcmdzKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImFwcGx5XCIsIFt2b2lkIDAsIGFyZ3NdKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmZhcHBseSA9IGZ1bmN0aW9uIChhcmdzKSB7XG4gICAgcmV0dXJuIHRoaXMuZGlzcGF0Y2goXCJhcHBseVwiLCBbdm9pZCAwLCBhcmdzXSk7XG59O1xuXG4vKipcbiAqIENhbGxzIHRoZSBwcm9taXNlZCBmdW5jdGlvbiBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBmdW5jdGlvblxuICogQHBhcmFtIC4uLmFyZ3MgICBhcnJheSBvZiBhcHBsaWNhdGlvbiBhcmd1bWVudHNcbiAqL1xuUVtcInRyeVwiXSA9XG5RLmZjYWxsID0gZnVuY3Rpb24gKG9iamVjdCAvKiAuLi5hcmdzKi8pIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwiYXBwbHlcIiwgW3ZvaWQgMCwgYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZmNhbGwgPSBmdW5jdGlvbiAoLyouLi5hcmdzKi8pIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImFwcGx5XCIsIFt2b2lkIDAsIGFycmF5X3NsaWNlKGFyZ3VtZW50cyldKTtcbn07XG5cbi8qKlxuICogQmluZHMgdGhlIHByb21pc2VkIGZ1bmN0aW9uLCB0cmFuc2Zvcm1pbmcgcmV0dXJuIHZhbHVlcyBpbnRvIGEgZnVsZmlsbGVkXG4gKiBwcm9taXNlIGFuZCB0aHJvd24gZXJyb3JzIGludG8gYSByZWplY3RlZCBvbmUuXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IGZ1bmN0aW9uXG4gKiBAcGFyYW0gLi4uYXJncyAgIGFycmF5IG9mIGFwcGxpY2F0aW9uIGFyZ3VtZW50c1xuICovXG5RLmZiaW5kID0gZnVuY3Rpb24gKG9iamVjdCAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBwcm9taXNlID0gUShvYmplY3QpO1xuICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gZmJvdW5kKCkge1xuICAgICAgICByZXR1cm4gcHJvbWlzZS5kaXNwYXRjaChcImFwcGx5XCIsIFtcbiAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICBhcmdzLmNvbmNhdChhcnJheV9zbGljZShhcmd1bWVudHMpKVxuICAgICAgICBdKTtcbiAgICB9O1xufTtcblByb21pc2UucHJvdG90eXBlLmZiaW5kID0gZnVuY3Rpb24gKC8qLi4uYXJncyovKSB7XG4gICAgdmFyIHByb21pc2UgPSB0aGlzO1xuICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gZmJvdW5kKCkge1xuICAgICAgICByZXR1cm4gcHJvbWlzZS5kaXNwYXRjaChcImFwcGx5XCIsIFtcbiAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICBhcmdzLmNvbmNhdChhcnJheV9zbGljZShhcmd1bWVudHMpKVxuICAgICAgICBdKTtcbiAgICB9O1xufTtcblxuLyoqXG4gKiBSZXF1ZXN0cyB0aGUgbmFtZXMgb2YgdGhlIG93bmVkIHByb3BlcnRpZXMgb2YgYSBwcm9taXNlZFxuICogb2JqZWN0IGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IG9iamVjdFxuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUga2V5cyBvZiB0aGUgZXZlbnR1YWxseSBzZXR0bGVkIG9iamVjdFxuICovXG5RLmtleXMgPSBmdW5jdGlvbiAob2JqZWN0KSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImtleXNcIiwgW10pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUua2V5cyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImtleXNcIiwgW10pO1xufTtcblxuLyoqXG4gKiBUdXJucyBhbiBhcnJheSBvZiBwcm9taXNlcyBpbnRvIGEgcHJvbWlzZSBmb3IgYW4gYXJyYXkuICBJZiBhbnkgb2ZcbiAqIHRoZSBwcm9taXNlcyBnZXRzIHJlamVjdGVkLCB0aGUgd2hvbGUgYXJyYXkgaXMgcmVqZWN0ZWQgaW1tZWRpYXRlbHkuXG4gKiBAcGFyYW0ge0FycmF5Kn0gYW4gYXJyYXkgKG9yIHByb21pc2UgZm9yIGFuIGFycmF5KSBvZiB2YWx1ZXMgKG9yXG4gKiBwcm9taXNlcyBmb3IgdmFsdWVzKVxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciBhbiBhcnJheSBvZiB0aGUgY29ycmVzcG9uZGluZyB2YWx1ZXNcbiAqL1xuLy8gQnkgTWFyayBNaWxsZXJcbi8vIGh0dHA6Ly93aWtpLmVjbWFzY3JpcHQub3JnL2Rva3UucGhwP2lkPXN0cmF3bWFuOmNvbmN1cnJlbmN5JnJldj0xMzA4Nzc2NTIxI2FsbGZ1bGZpbGxlZFxuUS5hbGwgPSBhbGw7XG5mdW5jdGlvbiBhbGwocHJvbWlzZXMpIHtcbiAgICByZXR1cm4gd2hlbihwcm9taXNlcywgZnVuY3Rpb24gKHByb21pc2VzKSB7XG4gICAgICAgIHZhciBwZW5kaW5nQ291bnQgPSAwO1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBhcnJheV9yZWR1Y2UocHJvbWlzZXMsIGZ1bmN0aW9uICh1bmRlZmluZWQsIHByb21pc2UsIGluZGV4KSB7XG4gICAgICAgICAgICB2YXIgc25hcHNob3Q7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgaXNQcm9taXNlKHByb21pc2UpICYmXG4gICAgICAgICAgICAgICAgKHNuYXBzaG90ID0gcHJvbWlzZS5pbnNwZWN0KCkpLnN0YXRlID09PSBcImZ1bGZpbGxlZFwiXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBwcm9taXNlc1tpbmRleF0gPSBzbmFwc2hvdC52YWx1ZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgKytwZW5kaW5nQ291bnQ7XG4gICAgICAgICAgICAgICAgd2hlbihcbiAgICAgICAgICAgICAgICAgICAgcHJvbWlzZSxcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9taXNlc1tpbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgtLXBlbmRpbmdDb3VudCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUocHJvbWlzZXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBkZWZlcnJlZC5yZWplY3QsXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIChwcm9ncmVzcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVmZXJyZWQubm90aWZ5KHsgaW5kZXg6IGluZGV4LCB2YWx1ZTogcHJvZ3Jlc3MgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCB2b2lkIDApO1xuICAgICAgICBpZiAocGVuZGluZ0NvdW50ID09PSAwKSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHByb21pc2VzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9KTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuYWxsID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBhbGwodGhpcyk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGZpcnN0IHJlc29sdmVkIHByb21pc2Ugb2YgYW4gYXJyYXkuIFByaW9yIHJlamVjdGVkIHByb21pc2VzIGFyZVxuICogaWdub3JlZC4gIFJlamVjdHMgb25seSBpZiBhbGwgcHJvbWlzZXMgYXJlIHJlamVjdGVkLlxuICogQHBhcmFtIHtBcnJheSp9IGFuIGFycmF5IGNvbnRhaW5pbmcgdmFsdWVzIG9yIHByb21pc2VzIGZvciB2YWx1ZXNcbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmdWxmaWxsZWQgd2l0aCB0aGUgdmFsdWUgb2YgdGhlIGZpcnN0IHJlc29sdmVkIHByb21pc2UsXG4gKiBvciBhIHJlamVjdGVkIHByb21pc2UgaWYgYWxsIHByb21pc2VzIGFyZSByZWplY3RlZC5cbiAqL1xuUS5hbnkgPSBhbnk7XG5cbmZ1bmN0aW9uIGFueShwcm9taXNlcykge1xuICAgIGlmIChwcm9taXNlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIFEucmVzb2x2ZSgpO1xuICAgIH1cblxuICAgIHZhciBkZWZlcnJlZCA9IFEuZGVmZXIoKTtcbiAgICB2YXIgcGVuZGluZ0NvdW50ID0gMDtcbiAgICBhcnJheV9yZWR1Y2UocHJvbWlzZXMsIGZ1bmN0aW9uIChwcmV2LCBjdXJyZW50LCBpbmRleCkge1xuICAgICAgICB2YXIgcHJvbWlzZSA9IHByb21pc2VzW2luZGV4XTtcblxuICAgICAgICBwZW5kaW5nQ291bnQrKztcblxuICAgICAgICB3aGVuKHByb21pc2UsIG9uRnVsZmlsbGVkLCBvblJlamVjdGVkLCBvblByb2dyZXNzKTtcbiAgICAgICAgZnVuY3Rpb24gb25GdWxmaWxsZWQocmVzdWx0KSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gb25SZWplY3RlZCgpIHtcbiAgICAgICAgICAgIHBlbmRpbmdDb3VudC0tO1xuICAgICAgICAgICAgaWYgKHBlbmRpbmdDb3VudCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlamVjdChuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIFwiQ2FuJ3QgZ2V0IGZ1bGZpbGxtZW50IHZhbHVlIGZyb20gYW55IHByb21pc2UsIGFsbCBcIiArXG4gICAgICAgICAgICAgICAgICAgIFwicHJvbWlzZXMgd2VyZSByZWplY3RlZC5cIlxuICAgICAgICAgICAgICAgICkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIG9uUHJvZ3Jlc3MocHJvZ3Jlc3MpIHtcbiAgICAgICAgICAgIGRlZmVycmVkLm5vdGlmeSh7XG4gICAgICAgICAgICAgICAgaW5kZXg6IGluZGV4LFxuICAgICAgICAgICAgICAgIHZhbHVlOiBwcm9ncmVzc1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9LCB1bmRlZmluZWQpO1xuXG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59XG5cblByb21pc2UucHJvdG90eXBlLmFueSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYW55KHRoaXMpO1xufTtcblxuLyoqXG4gKiBXYWl0cyBmb3IgYWxsIHByb21pc2VzIHRvIGJlIHNldHRsZWQsIGVpdGhlciBmdWxmaWxsZWQgb3JcbiAqIHJlamVjdGVkLiAgVGhpcyBpcyBkaXN0aW5jdCBmcm9tIGBhbGxgIHNpbmNlIHRoYXQgd291bGQgc3RvcFxuICogd2FpdGluZyBhdCB0aGUgZmlyc3QgcmVqZWN0aW9uLiAgVGhlIHByb21pc2UgcmV0dXJuZWQgYnlcbiAqIGBhbGxSZXNvbHZlZGAgd2lsbCBuZXZlciBiZSByZWplY3RlZC5cbiAqIEBwYXJhbSBwcm9taXNlcyBhIHByb21pc2UgZm9yIGFuIGFycmF5IChvciBhbiBhcnJheSkgb2YgcHJvbWlzZXNcbiAqIChvciB2YWx1ZXMpXG4gKiBAcmV0dXJuIGEgcHJvbWlzZSBmb3IgYW4gYXJyYXkgb2YgcHJvbWlzZXNcbiAqL1xuUS5hbGxSZXNvbHZlZCA9IGRlcHJlY2F0ZShhbGxSZXNvbHZlZCwgXCJhbGxSZXNvbHZlZFwiLCBcImFsbFNldHRsZWRcIik7XG5mdW5jdGlvbiBhbGxSZXNvbHZlZChwcm9taXNlcykge1xuICAgIHJldHVybiB3aGVuKHByb21pc2VzLCBmdW5jdGlvbiAocHJvbWlzZXMpIHtcbiAgICAgICAgcHJvbWlzZXMgPSBhcnJheV9tYXAocHJvbWlzZXMsIFEpO1xuICAgICAgICByZXR1cm4gd2hlbihhbGwoYXJyYXlfbWFwKHByb21pc2VzLCBmdW5jdGlvbiAocHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuIHdoZW4ocHJvbWlzZSwgbm9vcCwgbm9vcCk7XG4gICAgICAgIH0pKSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VzO1xuICAgICAgICB9KTtcbiAgICB9KTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuYWxsUmVzb2x2ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGFsbFJlc29sdmVkKHRoaXMpO1xufTtcblxuLyoqXG4gKiBAc2VlIFByb21pc2UjYWxsU2V0dGxlZFxuICovXG5RLmFsbFNldHRsZWQgPSBhbGxTZXR0bGVkO1xuZnVuY3Rpb24gYWxsU2V0dGxlZChwcm9taXNlcykge1xuICAgIHJldHVybiBRKHByb21pc2VzKS5hbGxTZXR0bGVkKCk7XG59XG5cbi8qKlxuICogVHVybnMgYW4gYXJyYXkgb2YgcHJvbWlzZXMgaW50byBhIHByb21pc2UgZm9yIGFuIGFycmF5IG9mIHRoZWlyIHN0YXRlcyAoYXNcbiAqIHJldHVybmVkIGJ5IGBpbnNwZWN0YCkgd2hlbiB0aGV5IGhhdmUgYWxsIHNldHRsZWQuXG4gKiBAcGFyYW0ge0FycmF5W0FueSpdfSB2YWx1ZXMgYW4gYXJyYXkgKG9yIHByb21pc2UgZm9yIGFuIGFycmF5KSBvZiB2YWx1ZXMgKG9yXG4gKiBwcm9taXNlcyBmb3IgdmFsdWVzKVxuICogQHJldHVybnMge0FycmF5W1N0YXRlXX0gYW4gYXJyYXkgb2Ygc3RhdGVzIGZvciB0aGUgcmVzcGVjdGl2ZSB2YWx1ZXMuXG4gKi9cblByb21pc2UucHJvdG90eXBlLmFsbFNldHRsZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAocHJvbWlzZXMpIHtcbiAgICAgICAgcmV0dXJuIGFsbChhcnJheV9tYXAocHJvbWlzZXMsIGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gICAgICAgICAgICBwcm9taXNlID0gUShwcm9taXNlKTtcbiAgICAgICAgICAgIGZ1bmN0aW9uIHJlZ2FyZGxlc3MoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2UuaW5zcGVjdCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHByb21pc2UudGhlbihyZWdhcmRsZXNzLCByZWdhcmRsZXNzKTtcbiAgICAgICAgfSkpO1xuICAgIH0pO1xufTtcblxuLyoqXG4gKiBDYXB0dXJlcyB0aGUgZmFpbHVyZSBvZiBhIHByb21pc2UsIGdpdmluZyBhbiBvcG9ydHVuaXR5IHRvIHJlY292ZXJcbiAqIHdpdGggYSBjYWxsYmFjay4gIElmIHRoZSBnaXZlbiBwcm9taXNlIGlzIGZ1bGZpbGxlZCwgdGhlIHJldHVybmVkXG4gKiBwcm9taXNlIGlzIGZ1bGZpbGxlZC5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZSBmb3Igc29tZXRoaW5nXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayB0byBmdWxmaWxsIHRoZSByZXR1cm5lZCBwcm9taXNlIGlmIHRoZVxuICogZ2l2ZW4gcHJvbWlzZSBpcyByZWplY3RlZFxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBjYWxsYmFja1xuICovXG5RLmZhaWwgPSAvLyBYWFggbGVnYWN5XG5RW1wiY2F0Y2hcIl0gPSBmdW5jdGlvbiAob2JqZWN0LCByZWplY3RlZCkge1xuICAgIHJldHVybiBRKG9iamVjdCkudGhlbih2b2lkIDAsIHJlamVjdGVkKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmZhaWwgPSAvLyBYWFggbGVnYWN5XG5Qcm9taXNlLnByb3RvdHlwZVtcImNhdGNoXCJdID0gZnVuY3Rpb24gKHJlamVjdGVkKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbih2b2lkIDAsIHJlamVjdGVkKTtcbn07XG5cbi8qKlxuICogQXR0YWNoZXMgYSBsaXN0ZW5lciB0aGF0IGNhbiByZXNwb25kIHRvIHByb2dyZXNzIG5vdGlmaWNhdGlvbnMgZnJvbSBhXG4gKiBwcm9taXNlJ3Mgb3JpZ2luYXRpbmcgZGVmZXJyZWQuIFRoaXMgbGlzdGVuZXIgcmVjZWl2ZXMgdGhlIGV4YWN0IGFyZ3VtZW50c1xuICogcGFzc2VkIHRvIGBgZGVmZXJyZWQubm90aWZ5YGAuXG4gKiBAcGFyYW0ge0FueSp9IHByb21pc2UgZm9yIHNvbWV0aGluZ1xuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgdG8gcmVjZWl2ZSBhbnkgcHJvZ3Jlc3Mgbm90aWZpY2F0aW9uc1xuICogQHJldHVybnMgdGhlIGdpdmVuIHByb21pc2UsIHVuY2hhbmdlZFxuICovXG5RLnByb2dyZXNzID0gcHJvZ3Jlc3M7XG5mdW5jdGlvbiBwcm9ncmVzcyhvYmplY3QsIHByb2dyZXNzZWQpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLnRoZW4odm9pZCAwLCB2b2lkIDAsIHByb2dyZXNzZWQpO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5wcm9ncmVzcyA9IGZ1bmN0aW9uIChwcm9ncmVzc2VkKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbih2b2lkIDAsIHZvaWQgMCwgcHJvZ3Jlc3NlZCk7XG59O1xuXG4vKipcbiAqIFByb3ZpZGVzIGFuIG9wcG9ydHVuaXR5IHRvIG9ic2VydmUgdGhlIHNldHRsaW5nIG9mIGEgcHJvbWlzZSxcbiAqIHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciB0aGUgcHJvbWlzZSBpcyBmdWxmaWxsZWQgb3IgcmVqZWN0ZWQuICBGb3J3YXJkc1xuICogdGhlIHJlc29sdXRpb24gdG8gdGhlIHJldHVybmVkIHByb21pc2Ugd2hlbiB0aGUgY2FsbGJhY2sgaXMgZG9uZS5cbiAqIFRoZSBjYWxsYmFjayBjYW4gcmV0dXJuIGEgcHJvbWlzZSB0byBkZWZlciBjb21wbGV0aW9uLlxuICogQHBhcmFtIHtBbnkqfSBwcm9taXNlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayB0byBvYnNlcnZlIHRoZSByZXNvbHV0aW9uIG9mIHRoZSBnaXZlblxuICogcHJvbWlzZSwgdGFrZXMgbm8gYXJndW1lbnRzLlxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmVzb2x1dGlvbiBvZiB0aGUgZ2l2ZW4gcHJvbWlzZSB3aGVuXG4gKiBgYGZpbmBgIGlzIGRvbmUuXG4gKi9cblEuZmluID0gLy8gWFhYIGxlZ2FjeVxuUVtcImZpbmFsbHlcIl0gPSBmdW5jdGlvbiAob2JqZWN0LCBjYWxsYmFjaykge1xuICAgIHJldHVybiBRKG9iamVjdClbXCJmaW5hbGx5XCJdKGNhbGxiYWNrKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmZpbiA9IC8vIFhYWCBsZWdhY3lcblByb21pc2UucHJvdG90eXBlW1wiZmluYWxseVwiXSA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gUShjYWxsYmFjayk7XG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmZjYWxsKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH0pO1xuICAgIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgICAgLy8gVE9ETyBhdHRlbXB0IHRvIHJlY3ljbGUgdGhlIHJlamVjdGlvbiB3aXRoIFwidGhpc1wiLlxuICAgICAgICByZXR1cm4gY2FsbGJhY2suZmNhbGwoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRocm93IHJlYXNvbjtcbiAgICAgICAgfSk7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFRlcm1pbmF0ZXMgYSBjaGFpbiBvZiBwcm9taXNlcywgZm9yY2luZyByZWplY3Rpb25zIHRvIGJlXG4gKiB0aHJvd24gYXMgZXhjZXB0aW9ucy5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZSBhdCB0aGUgZW5kIG9mIGEgY2hhaW4gb2YgcHJvbWlzZXNcbiAqIEByZXR1cm5zIG5vdGhpbmdcbiAqL1xuUS5kb25lID0gZnVuY3Rpb24gKG9iamVjdCwgZnVsZmlsbGVkLCByZWplY3RlZCwgcHJvZ3Jlc3MpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRvbmUoZnVsZmlsbGVkLCByZWplY3RlZCwgcHJvZ3Jlc3MpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZG9uZSA9IGZ1bmN0aW9uIChmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzcykge1xuICAgIHZhciBvblVuaGFuZGxlZEVycm9yID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgIC8vIGZvcndhcmQgdG8gYSBmdXR1cmUgdHVybiBzbyB0aGF0IGBgd2hlbmBgXG4gICAgICAgIC8vIGRvZXMgbm90IGNhdGNoIGl0IGFuZCB0dXJuIGl0IGludG8gYSByZWplY3Rpb24uXG4gICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbWFrZVN0YWNrVHJhY2VMb25nKGVycm9yLCBwcm9taXNlKTtcbiAgICAgICAgICAgIGlmIChRLm9uZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBRLm9uZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8vIEF2b2lkIHVubmVjZXNzYXJ5IGBuZXh0VGlja2BpbmcgdmlhIGFuIHVubmVjZXNzYXJ5IGB3aGVuYC5cbiAgICB2YXIgcHJvbWlzZSA9IGZ1bGZpbGxlZCB8fCByZWplY3RlZCB8fCBwcm9ncmVzcyA/XG4gICAgICAgIHRoaXMudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzcykgOlxuICAgICAgICB0aGlzO1xuXG4gICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmIHByb2Nlc3MgJiYgcHJvY2Vzcy5kb21haW4pIHtcbiAgICAgICAgb25VbmhhbmRsZWRFcnJvciA9IHByb2Nlc3MuZG9tYWluLmJpbmQob25VbmhhbmRsZWRFcnJvcik7XG4gICAgfVxuXG4gICAgcHJvbWlzZS50aGVuKHZvaWQgMCwgb25VbmhhbmRsZWRFcnJvcik7XG59O1xuXG4vKipcbiAqIENhdXNlcyBhIHByb21pc2UgdG8gYmUgcmVqZWN0ZWQgaWYgaXQgZG9lcyBub3QgZ2V0IGZ1bGZpbGxlZCBiZWZvcmVcbiAqIHNvbWUgbWlsbGlzZWNvbmRzIHRpbWUgb3V0LlxuICogQHBhcmFtIHtBbnkqfSBwcm9taXNlXG4gKiBAcGFyYW0ge051bWJlcn0gbWlsbGlzZWNvbmRzIHRpbWVvdXRcbiAqIEBwYXJhbSB7QW55Kn0gY3VzdG9tIGVycm9yIG1lc3NhZ2Ugb3IgRXJyb3Igb2JqZWN0IChvcHRpb25hbClcbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHJlc29sdXRpb24gb2YgdGhlIGdpdmVuIHByb21pc2UgaWYgaXQgaXNcbiAqIGZ1bGZpbGxlZCBiZWZvcmUgdGhlIHRpbWVvdXQsIG90aGVyd2lzZSByZWplY3RlZC5cbiAqL1xuUS50aW1lb3V0ID0gZnVuY3Rpb24gKG9iamVjdCwgbXMsIGVycm9yKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS50aW1lb3V0KG1zLCBlcnJvcik7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50aW1lb3V0ID0gZnVuY3Rpb24gKG1zLCBlcnJvcikge1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgdmFyIHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIWVycm9yIHx8IFwic3RyaW5nXCIgPT09IHR5cGVvZiBlcnJvcikge1xuICAgICAgICAgICAgZXJyb3IgPSBuZXcgRXJyb3IoZXJyb3IgfHwgXCJUaW1lZCBvdXQgYWZ0ZXIgXCIgKyBtcyArIFwiIG1zXCIpO1xuICAgICAgICAgICAgZXJyb3IuY29kZSA9IFwiRVRJTUVET1VUXCI7XG4gICAgICAgIH1cbiAgICAgICAgZGVmZXJyZWQucmVqZWN0KGVycm9yKTtcbiAgICB9LCBtcyk7XG5cbiAgICB0aGlzLnRoZW4oZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHZhbHVlKTtcbiAgICB9LCBmdW5jdGlvbiAoZXhjZXB0aW9uKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgICBkZWZlcnJlZC5yZWplY3QoZXhjZXB0aW9uKTtcbiAgICB9LCBkZWZlcnJlZC5ub3RpZnkpO1xuXG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIFJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgZ2l2ZW4gdmFsdWUgKG9yIHByb21pc2VkIHZhbHVlKSwgc29tZVxuICogbWlsbGlzZWNvbmRzIGFmdGVyIGl0IHJlc29sdmVkLiBQYXNzZXMgcmVqZWN0aW9ucyBpbW1lZGlhdGVseS5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZVxuICogQHBhcmFtIHtOdW1iZXJ9IG1pbGxpc2Vjb25kc1xuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmVzb2x1dGlvbiBvZiB0aGUgZ2l2ZW4gcHJvbWlzZSBhZnRlciBtaWxsaXNlY29uZHNcbiAqIHRpbWUgaGFzIGVsYXBzZWQgc2luY2UgdGhlIHJlc29sdXRpb24gb2YgdGhlIGdpdmVuIHByb21pc2UuXG4gKiBJZiB0aGUgZ2l2ZW4gcHJvbWlzZSByZWplY3RzLCB0aGF0IGlzIHBhc3NlZCBpbW1lZGlhdGVseS5cbiAqL1xuUS5kZWxheSA9IGZ1bmN0aW9uIChvYmplY3QsIHRpbWVvdXQpIHtcbiAgICBpZiAodGltZW91dCA9PT0gdm9pZCAwKSB7XG4gICAgICAgIHRpbWVvdXQgPSBvYmplY3Q7XG4gICAgICAgIG9iamVjdCA9IHZvaWQgMDtcbiAgICB9XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kZWxheSh0aW1lb3V0KTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmRlbGF5ID0gZnVuY3Rpb24gKHRpbWVvdXQpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUodmFsdWUpO1xuICAgICAgICB9LCB0aW1lb3V0KTtcbiAgICAgICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFBhc3NlcyBhIGNvbnRpbnVhdGlvbiB0byBhIE5vZGUgZnVuY3Rpb24sIHdoaWNoIGlzIGNhbGxlZCB3aXRoIHRoZSBnaXZlblxuICogYXJndW1lbnRzIHByb3ZpZGVkIGFzIGFuIGFycmF5LCBhbmQgcmV0dXJucyBhIHByb21pc2UuXG4gKlxuICogICAgICBRLm5mYXBwbHkoRlMucmVhZEZpbGUsIFtfX2ZpbGVuYW1lXSlcbiAqICAgICAgLnRoZW4oZnVuY3Rpb24gKGNvbnRlbnQpIHtcbiAqICAgICAgfSlcbiAqXG4gKi9cblEubmZhcHBseSA9IGZ1bmN0aW9uIChjYWxsYmFjaywgYXJncykge1xuICAgIHJldHVybiBRKGNhbGxiYWNrKS5uZmFwcGx5KGFyZ3MpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmZhcHBseSA9IGZ1bmN0aW9uIChhcmdzKSB7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmdzKTtcbiAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgdGhpcy5mYXBwbHkobm9kZUFyZ3MpLmZhaWwoZGVmZXJyZWQucmVqZWN0KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cbi8qKlxuICogUGFzc2VzIGEgY29udGludWF0aW9uIHRvIGEgTm9kZSBmdW5jdGlvbiwgd2hpY2ggaXMgY2FsbGVkIHdpdGggdGhlIGdpdmVuXG4gKiBhcmd1bWVudHMgcHJvdmlkZWQgaW5kaXZpZHVhbGx5LCBhbmQgcmV0dXJucyBhIHByb21pc2UuXG4gKiBAZXhhbXBsZVxuICogUS5uZmNhbGwoRlMucmVhZEZpbGUsIF9fZmlsZW5hbWUpXG4gKiAudGhlbihmdW5jdGlvbiAoY29udGVudCkge1xuICogfSlcbiAqXG4gKi9cblEubmZjYWxsID0gZnVuY3Rpb24gKGNhbGxiYWNrIC8qLi4uYXJncyovKSB7XG4gICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDEpO1xuICAgIHJldHVybiBRKGNhbGxiYWNrKS5uZmFwcGx5KGFyZ3MpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmZjYWxsID0gZnVuY3Rpb24gKC8qLi4uYXJncyovKSB7XG4gICAgdmFyIG5vZGVBcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICB0aGlzLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufTtcblxuLyoqXG4gKiBXcmFwcyBhIE5vZGVKUyBjb250aW51YXRpb24gcGFzc2luZyBmdW5jdGlvbiBhbmQgcmV0dXJucyBhbiBlcXVpdmFsZW50XG4gKiB2ZXJzaW9uIHRoYXQgcmV0dXJucyBhIHByb21pc2UuXG4gKiBAZXhhbXBsZVxuICogUS5uZmJpbmQoRlMucmVhZEZpbGUsIF9fZmlsZW5hbWUpKFwidXRmLThcIilcbiAqIC50aGVuKGNvbnNvbGUubG9nKVxuICogLmRvbmUoKVxuICovXG5RLm5mYmluZCA9XG5RLmRlbm9kZWlmeSA9IGZ1bmN0aW9uIChjYWxsYmFjayAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBiYXNlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMSk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG5vZGVBcmdzID0gYmFzZUFyZ3MuY29uY2F0KGFycmF5X3NsaWNlKGFyZ3VtZW50cykpO1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgICAgIFEoY2FsbGJhY2spLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmZiaW5kID1cblByb21pc2UucHJvdG90eXBlLmRlbm9kZWlmeSA9IGZ1bmN0aW9uICgvKi4uLmFyZ3MqLykge1xuICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICBhcmdzLnVuc2hpZnQodGhpcyk7XG4gICAgcmV0dXJuIFEuZGVub2RlaWZ5LmFwcGx5KHZvaWQgMCwgYXJncyk7XG59O1xuXG5RLm5iaW5kID0gZnVuY3Rpb24gKGNhbGxiYWNrLCB0aGlzcCAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBiYXNlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMik7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG5vZGVBcmdzID0gYmFzZUFyZ3MuY29uY2F0KGFycmF5X3NsaWNlKGFyZ3VtZW50cykpO1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgICAgIGZ1bmN0aW9uIGJvdW5kKCkge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KHRoaXNwLCBhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgICAgIFEoYm91bmQpLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmJpbmQgPSBmdW5jdGlvbiAoLyp0aGlzcCwgLi4uYXJncyovKSB7XG4gICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDApO1xuICAgIGFyZ3MudW5zaGlmdCh0aGlzKTtcbiAgICByZXR1cm4gUS5uYmluZC5hcHBseSh2b2lkIDAsIGFyZ3MpO1xufTtcblxuLyoqXG4gKiBDYWxscyBhIG1ldGhvZCBvZiBhIE5vZGUtc3R5bGUgb2JqZWN0IHRoYXQgYWNjZXB0cyBhIE5vZGUtc3R5bGVcbiAqIGNhbGxiYWNrIHdpdGggYSBnaXZlbiBhcnJheSBvZiBhcmd1bWVudHMsIHBsdXMgYSBwcm92aWRlZCBjYWxsYmFjay5cbiAqIEBwYXJhbSBvYmplY3QgYW4gb2JqZWN0IHRoYXQgaGFzIHRoZSBuYW1lZCBtZXRob2RcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG5hbWUgb2YgdGhlIG1ldGhvZCBvZiBvYmplY3RcbiAqIEBwYXJhbSB7QXJyYXl9IGFyZ3MgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIG1ldGhvZDsgdGhlIGNhbGxiYWNrXG4gKiB3aWxsIGJlIHByb3ZpZGVkIGJ5IFEgYW5kIGFwcGVuZGVkIHRvIHRoZXNlIGFyZ3VtZW50cy5cbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHZhbHVlIG9yIGVycm9yXG4gKi9cblEubm1hcHBseSA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5RLm5wb3N0ID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSwgYXJncykge1xuICAgIHJldHVybiBRKG9iamVjdCkubnBvc3QobmFtZSwgYXJncyk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5ubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblByb21pc2UucHJvdG90eXBlLm5wb3N0ID0gZnVuY3Rpb24gKG5hbWUsIGFyZ3MpIHtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmdzIHx8IFtdKTtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICB0aGlzLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgbm9kZUFyZ3NdKS5mYWlsKGRlZmVycmVkLnJlamVjdCk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIENhbGxzIGEgbWV0aG9kIG9mIGEgTm9kZS1zdHlsZSBvYmplY3QgdGhhdCBhY2NlcHRzIGEgTm9kZS1zdHlsZVxuICogY2FsbGJhY2ssIGZvcndhcmRpbmcgdGhlIGdpdmVuIHZhcmlhZGljIGFyZ3VtZW50cywgcGx1cyBhIHByb3ZpZGVkXG4gKiBjYWxsYmFjayBhcmd1bWVudC5cbiAqIEBwYXJhbSBvYmplY3QgYW4gb2JqZWN0IHRoYXQgaGFzIHRoZSBuYW1lZCBtZXRob2RcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG5hbWUgb2YgdGhlIG1ldGhvZCBvZiBvYmplY3RcbiAqIEBwYXJhbSAuLi5hcmdzIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBtZXRob2Q7IHRoZSBjYWxsYmFjayB3aWxsXG4gKiBiZSBwcm92aWRlZCBieSBRIGFuZCBhcHBlbmRlZCB0byB0aGVzZSBhcmd1bWVudHMuXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSB2YWx1ZSBvciBlcnJvclxuICovXG5RLm5zZW5kID0gLy8gWFhYIEJhc2VkIG9uIE1hcmsgTWlsbGVyJ3MgcHJvcG9zZWQgXCJzZW5kXCJcblEubm1jYWxsID0gLy8gWFhYIEJhc2VkIG9uIFwiUmVkc2FuZHJvJ3NcIiBwcm9wb3NhbFxuUS5uaW52b2tlID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBub2RlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMik7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgUShvYmplY3QpLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgbm9kZUFyZ3NdKS5mYWlsKGRlZmVycmVkLnJlamVjdCk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5uc2VuZCA9IC8vIFhYWCBCYXNlZCBvbiBNYXJrIE1pbGxlcidzIHByb3Bvc2VkIFwic2VuZFwiXG5Qcm9taXNlLnByb3RvdHlwZS5ubWNhbGwgPSAvLyBYWFggQmFzZWQgb24gXCJSZWRzYW5kcm8nc1wiIHByb3Bvc2FsXG5Qcm9taXNlLnByb3RvdHlwZS5uaW52b2tlID0gZnVuY3Rpb24gKG5hbWUgLyouLi5hcmdzKi8pIHtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDEpO1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgbm9kZUFyZ3MucHVzaChkZWZlcnJlZC5tYWtlTm9kZVJlc29sdmVyKCkpO1xuICAgIHRoaXMuZGlzcGF0Y2goXCJwb3N0XCIsIFtuYW1lLCBub2RlQXJnc10pLmZhaWwoZGVmZXJyZWQucmVqZWN0KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cbi8qKlxuICogSWYgYSBmdW5jdGlvbiB3b3VsZCBsaWtlIHRvIHN1cHBvcnQgYm90aCBOb2RlIGNvbnRpbnVhdGlvbi1wYXNzaW5nLXN0eWxlIGFuZFxuICogcHJvbWlzZS1yZXR1cm5pbmctc3R5bGUsIGl0IGNhbiBlbmQgaXRzIGludGVybmFsIHByb21pc2UgY2hhaW4gd2l0aFxuICogYG5vZGVpZnkobm9kZWJhY2spYCwgZm9yd2FyZGluZyB0aGUgb3B0aW9uYWwgbm9kZWJhY2sgYXJndW1lbnQuICBJZiB0aGUgdXNlclxuICogZWxlY3RzIHRvIHVzZSBhIG5vZGViYWNrLCB0aGUgcmVzdWx0IHdpbGwgYmUgc2VudCB0aGVyZS4gIElmIHRoZXkgZG8gbm90XG4gKiBwYXNzIGEgbm9kZWJhY2ssIHRoZXkgd2lsbCByZWNlaXZlIHRoZSByZXN1bHQgcHJvbWlzZS5cbiAqIEBwYXJhbSBvYmplY3QgYSByZXN1bHQgKG9yIGEgcHJvbWlzZSBmb3IgYSByZXN1bHQpXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBub2RlYmFjayBhIE5vZGUuanMtc3R5bGUgY2FsbGJhY2tcbiAqIEByZXR1cm5zIGVpdGhlciB0aGUgcHJvbWlzZSBvciBub3RoaW5nXG4gKi9cblEubm9kZWlmeSA9IG5vZGVpZnk7XG5mdW5jdGlvbiBub2RlaWZ5KG9iamVjdCwgbm9kZWJhY2spIHtcbiAgICByZXR1cm4gUShvYmplY3QpLm5vZGVpZnkobm9kZWJhY2spO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5ub2RlaWZ5ID0gZnVuY3Rpb24gKG5vZGViYWNrKSB7XG4gICAgaWYgKG5vZGViYWNrKSB7XG4gICAgICAgIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIG5vZGViYWNrKG51bGwsIHZhbHVlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIG5vZGViYWNrKGVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59O1xuXG5RLm5vQ29uZmxpY3QgPSBmdW5jdGlvbigpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJRLm5vQ29uZmxpY3Qgb25seSB3b3JrcyB3aGVuIFEgaXMgdXNlZCBhcyBhIGdsb2JhbFwiKTtcbn07XG5cbi8vIEFsbCBjb2RlIGJlZm9yZSB0aGlzIHBvaW50IHdpbGwgYmUgZmlsdGVyZWQgZnJvbSBzdGFjayB0cmFjZXMuXG52YXIgcUVuZGluZ0xpbmUgPSBjYXB0dXJlTGluZSgpO1xuXG5yZXR1cm4gUTtcblxufSk7XG4iXX0=\r
17647 },{"_process":13}],160:[function(require,module,exports){\r
17648 \r
17649 /**\r
17650  * Reduce `arr` with `fn`.\r
17651  *\r
17652  * @param {Array} arr\r
17653  * @param {Function} fn\r
17654  * @param {Mixed} initial\r
17655  *\r
17656  * TODO: combatible error handling?\r
17657  */\r
17658 \r
17659 module.exports = function(arr, fn, initial){  \r
17660   var idx = 0;\r
17661   var len = arr.length;\r
17662   var curr = arguments.length == 3\r
17663     ? initial\r
17664     : arr[idx++];\r
17665 \r
17666   while (idx < len) {\r
17667     curr = fn.call(null, curr, arr[idx], ++idx, arr);\r
17668   }\r
17669   \r
17670   return curr;\r
17671 };\r
17672 },{}],161:[function(require,module,exports){\r
17673 /**\r
17674  * Module dependencies.\r
17675  */\r
17676 \r
17677 var Emitter = require('emitter');\r
17678 var reduce = require('reduce');\r
17679 \r
17680 /**\r
17681  * Root reference for iframes.\r
17682  */\r
17683 \r
17684 var root;\r
17685 if (typeof window !== 'undefined') { // Browser window\r
17686   root = window;\r
17687 } else if (typeof self !== 'undefined') { // Web Worker\r
17688   root = self;\r
17689 } else { // Other environments\r
17690   root = this;\r
17691 }\r
17692 \r
17693 /**\r
17694  * Noop.\r
17695  */\r
17696 \r
17697 function noop(){};\r
17698 \r
17699 /**\r
17700  * Check if `obj` is a host object,\r
17701  * we don't want to serialize these :)\r
17702  *\r
17703  * TODO: future proof, move to compoent land\r
17704  *\r
17705  * @param {Object} obj\r
17706  * @return {Boolean}\r
17707  * @api private\r
17708  */\r
17709 \r
17710 function isHost(obj) {\r
17711   var str = {}.toString.call(obj);\r
17712 \r
17713   switch (str) {\r
17714     case '[object File]':\r
17715     case '[object Blob]':\r
17716     case '[object FormData]':\r
17717       return true;\r
17718     default:\r
17719       return false;\r
17720   }\r
17721 }\r
17722 \r
17723 /**\r
17724  * Determine XHR.\r
17725  */\r
17726 \r
17727 request.getXHR = function () {\r
17728   if (root.XMLHttpRequest\r
17729       && (!root.location || 'file:' != root.location.protocol\r
17730           || !root.ActiveXObject)) {\r
17731     return new XMLHttpRequest;\r
17732   } else {\r
17733     try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {}\r
17734     try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {}\r
17735     try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {}\r
17736     try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {}\r
17737   }\r
17738   return false;\r
17739 };\r
17740 \r
17741 /**\r
17742  * Removes leading and trailing whitespace, added to support IE.\r
17743  *\r
17744  * @param {String} s\r
17745  * @return {String}\r
17746  * @api private\r
17747  */\r
17748 \r
17749 var trim = ''.trim\r
17750   ? function(s) { return s.trim(); }\r
17751   : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); };\r
17752 \r
17753 /**\r
17754  * Check if `obj` is an object.\r
17755  *\r
17756  * @param {Object} obj\r
17757  * @return {Boolean}\r
17758  * @api private\r
17759  */\r
17760 \r
17761 function isObject(obj) {\r
17762   return obj === Object(obj);\r
17763 }\r
17764 \r
17765 /**\r
17766  * Serialize the given `obj`.\r
17767  *\r
17768  * @param {Object} obj\r
17769  * @return {String}\r
17770  * @api private\r
17771  */\r
17772 \r
17773 function serialize(obj) {\r
17774   if (!isObject(obj)) return obj;\r
17775   var pairs = [];\r
17776   for (var key in obj) {\r
17777     if (null != obj[key]) {\r
17778       pushEncodedKeyValuePair(pairs, key, obj[key]);\r
17779         }\r
17780       }\r
17781   return pairs.join('&');\r
17782 }\r
17783 \r
17784 /**\r
17785  * Helps 'serialize' with serializing arrays.\r
17786  * Mutates the pairs array.\r
17787  *\r
17788  * @param {Array} pairs\r
17789  * @param {String} key\r
17790  * @param {Mixed} val\r
17791  */\r
17792 \r
17793 function pushEncodedKeyValuePair(pairs, key, val) {\r
17794   if (Array.isArray(val)) {\r
17795     return val.forEach(function(v) {\r
17796       pushEncodedKeyValuePair(pairs, key, v);\r
17797     });\r
17798   }\r
17799   pairs.push(encodeURIComponent(key)\r
17800     + '=' + encodeURIComponent(val));\r
17801 }\r
17802 \r
17803 /**\r
17804  * Expose serialization method.\r
17805  */\r
17806 \r
17807  request.serializeObject = serialize;\r
17808 \r
17809  /**\r
17810   * Parse the given x-www-form-urlencoded `str`.\r
17811   *\r
17812   * @param {String} str\r
17813   * @return {Object}\r
17814   * @api private\r
17815   */\r
17816 \r
17817 function parseString(str) {\r
17818   var obj = {};\r
17819   var pairs = str.split('&');\r
17820   var parts;\r
17821   var pair;\r
17822 \r
17823   for (var i = 0, len = pairs.length; i < len; ++i) {\r
17824     pair = pairs[i];\r
17825     parts = pair.split('=');\r
17826     obj[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);\r
17827   }\r
17828 \r
17829   return obj;\r
17830 }\r
17831 \r
17832 /**\r
17833  * Expose parser.\r
17834  */\r
17835 \r
17836 request.parseString = parseString;\r
17837 \r
17838 /**\r
17839  * Default MIME type map.\r
17840  *\r
17841  *     superagent.types.xml = 'application/xml';\r
17842  *\r
17843  */\r
17844 \r
17845 request.types = {\r
17846   html: 'text/html',\r
17847   json: 'application/json',\r
17848   xml: 'application/xml',\r
17849   urlencoded: 'application/x-www-form-urlencoded',\r
17850   'form': 'application/x-www-form-urlencoded',\r
17851   'form-data': 'application/x-www-form-urlencoded'\r
17852 };\r
17853 \r
17854 /**\r
17855  * Default serialization map.\r
17856  *\r
17857  *     superagent.serialize['application/xml'] = function(obj){\r
17858  *       return 'generated xml here';\r
17859  *     };\r
17860  *\r
17861  */\r
17862 \r
17863  request.serialize = {\r
17864    'application/x-www-form-urlencoded': serialize,\r
17865    'application/json': JSON.stringify\r
17866  };\r
17867 \r
17868  /**\r
17869   * Default parsers.\r
17870   *\r
17871   *     superagent.parse['application/xml'] = function(str){\r
17872   *       return { object parsed from str };\r
17873   *     };\r
17874   *\r
17875   */\r
17876 \r
17877 request.parse = {\r
17878   'application/x-www-form-urlencoded': parseString,\r
17879   'application/json': JSON.parse\r
17880 };\r
17881 \r
17882 /**\r
17883  * Parse the given header `str` into\r
17884  * an object containing the mapped fields.\r
17885  *\r
17886  * @param {String} str\r
17887  * @return {Object}\r
17888  * @api private\r
17889  */\r
17890 \r
17891 function parseHeader(str) {\r
17892   var lines = str.split(/\r?\n/);\r
17893   var fields = {};\r
17894   var index;\r
17895   var line;\r
17896   var field;\r
17897   var val;\r
17898 \r
17899   lines.pop(); // trailing CRLF\r
17900 \r
17901   for (var i = 0, len = lines.length; i < len; ++i) {\r
17902     line = lines[i];\r
17903     index = line.indexOf(':');\r
17904     field = line.slice(0, index).toLowerCase();\r
17905     val = trim(line.slice(index + 1));\r
17906     fields[field] = val;\r
17907   }\r
17908 \r
17909   return fields;\r
17910 }\r
17911 \r
17912 /**\r
17913  * Check if `mime` is json or has +json structured syntax suffix.\r
17914  *\r
17915  * @param {String} mime\r
17916  * @return {Boolean}\r
17917  * @api private\r
17918  */\r
17919 \r
17920 function isJSON(mime) {\r
17921   return /[\/+]json\b/.test(mime);\r
17922 }\r
17923 \r
17924 /**\r
17925  * Return the mime type for the given `str`.\r
17926  *\r
17927  * @param {String} str\r
17928  * @return {String}\r
17929  * @api private\r
17930  */\r
17931 \r
17932 function type(str){\r
17933   return str.split(/ *; */).shift();\r
17934 };\r
17935 \r
17936 /**\r
17937  * Return header field parameters.\r
17938  *\r
17939  * @param {String} str\r
17940  * @return {Object}\r
17941  * @api private\r
17942  */\r
17943 \r
17944 function params(str){\r
17945   return reduce(str.split(/ *; */), function(obj, str){\r
17946     var parts = str.split(/ *= */)\r
17947       , key = parts.shift()\r
17948       , val = parts.shift();\r
17949 \r
17950     if (key && val) obj[key] = val;\r
17951     return obj;\r
17952   }, {});\r
17953 };\r
17954 \r
17955 /**\r
17956  * Initialize a new `Response` with the given `xhr`.\r
17957  *\r
17958  *  - set flags (.ok, .error, etc)\r
17959  *  - parse header\r
17960  *\r
17961  * Examples:\r
17962  *\r
17963  *  Aliasing `superagent` as `request` is nice:\r
17964  *\r
17965  *      request = superagent;\r
17966  *\r
17967  *  We can use the promise-like API, or pass callbacks:\r
17968  *\r
17969  *      request.get('/').end(function(res){});\r
17970  *      request.get('/', function(res){});\r
17971  *\r
17972  *  Sending data can be chained:\r
17973  *\r
17974  *      request\r
17975  *        .post('/user')\r
17976  *        .send({ name: 'tj' })\r
17977  *        .end(function(res){});\r
17978  *\r
17979  *  Or passed to `.send()`:\r
17980  *\r
17981  *      request\r
17982  *        .post('/user')\r
17983  *        .send({ name: 'tj' }, function(res){});\r
17984  *\r
17985  *  Or passed to `.post()`:\r
17986  *\r
17987  *      request\r
17988  *        .post('/user', { name: 'tj' })\r
17989  *        .end(function(res){});\r
17990  *\r
17991  * Or further reduced to a single call for simple cases:\r
17992  *\r
17993  *      request\r
17994  *        .post('/user', { name: 'tj' }, function(res){});\r
17995  *\r
17996  * @param {XMLHTTPRequest} xhr\r
17997  * @param {Object} options\r
17998  * @api private\r
17999  */\r
18000 \r
18001 function Response(req, options) {\r
18002   options = options || {};\r
18003   this.req = req;\r
18004   this.xhr = this.req.xhr;\r
18005   // responseText is accessible only if responseType is '' or 'text' and on older browsers\r
18006   this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined')\r
18007      ? this.xhr.responseText\r
18008      : null;\r
18009   this.statusText = this.req.xhr.statusText;\r
18010   this.setStatusProperties(this.xhr.status);\r
18011   this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders());\r
18012   // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but\r
18013   // getResponseHeader still works. so we get content-type even if getting\r
18014   // other headers fails.\r
18015   this.header['content-type'] = this.xhr.getResponseHeader('content-type');\r
18016   this.setHeaderProperties(this.header);\r
18017   this.body = this.req.method != 'HEAD'\r
18018     ? this.parseBody(this.text ? this.text : this.xhr.response)\r
18019     : null;\r
18020 }\r
18021 \r
18022 /**\r
18023  * Get case-insensitive `field` value.\r
18024  *\r
18025  * @param {String} field\r
18026  * @return {String}\r
18027  * @api public\r
18028  */\r
18029 \r
18030 Response.prototype.get = function(field){\r
18031   return this.header[field.toLowerCase()];\r
18032 };\r
18033 \r
18034 /**\r
18035  * Set header related properties:\r
18036  *\r
18037  *   - `.type` the content type without params\r
18038  *\r
18039  * A response of "Content-Type: text/plain; charset=utf-8"\r
18040  * will provide you with a `.type` of "text/plain".\r
18041  *\r
18042  * @param {Object} header\r
18043  * @api private\r
18044  */\r
18045 \r
18046 Response.prototype.setHeaderProperties = function(header){\r
18047   // content-type\r
18048   var ct = this.header['content-type'] || '';\r
18049   this.type = type(ct);\r
18050 \r
18051   // params\r
18052   var obj = params(ct);\r
18053   for (var key in obj) this[key] = obj[key];\r
18054 };\r
18055 \r
18056 /**\r
18057  * Parse the given body `str`.\r
18058  *\r
18059  * Used for auto-parsing of bodies. Parsers\r
18060  * are defined on the `superagent.parse` object.\r
18061  *\r
18062  * @param {String} str\r
18063  * @return {Mixed}\r
18064  * @api private\r
18065  */\r
18066 \r
18067 Response.prototype.parseBody = function(str){\r
18068   var parse = request.parse[this.type];\r
18069   return parse && str && (str.length || str instanceof Object)\r
18070     ? parse(str)\r
18071     : null;\r
18072 };\r
18073 \r
18074 /**\r
18075  * Set flags such as `.ok` based on `status`.\r
18076  *\r
18077  * For example a 2xx response will give you a `.ok` of __true__\r
18078  * whereas 5xx will be __false__ and `.error` will be __true__. The\r
18079  * `.clientError` and `.serverError` are also available to be more\r
18080  * specific, and `.statusType` is the class of error ranging from 1..5\r
18081  * sometimes useful for mapping respond colors etc.\r
18082  *\r
18083  * "sugar" properties are also defined for common cases. Currently providing:\r
18084  *\r
18085  *   - .noContent\r
18086  *   - .badRequest\r
18087  *   - .unauthorized\r
18088  *   - .notAcceptable\r
18089  *   - .notFound\r
18090  *\r
18091  * @param {Number} status\r
18092  * @api private\r
18093  */\r
18094 \r
18095 Response.prototype.setStatusProperties = function(status){\r
18096   // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request\r
18097   if (status === 1223) {\r
18098     status = 204;\r
18099   }\r
18100 \r
18101   var type = status / 100 | 0;\r
18102 \r
18103   // status / class\r
18104   this.status = this.statusCode = status;\r
18105   this.statusType = type;\r
18106 \r
18107   // basics\r
18108   this.info = 1 == type;\r
18109   this.ok = 2 == type;\r
18110   this.clientError = 4 == type;\r
18111   this.serverError = 5 == type;\r
18112   this.error = (4 == type || 5 == type)\r
18113     ? this.toError()\r
18114     : false;\r
18115 \r
18116   // sugar\r
18117   this.accepted = 202 == status;\r
18118   this.noContent = 204 == status;\r
18119   this.badRequest = 400 == status;\r
18120   this.unauthorized = 401 == status;\r
18121   this.notAcceptable = 406 == status;\r
18122   this.notFound = 404 == status;\r
18123   this.forbidden = 403 == status;\r
18124 };\r
18125 \r
18126 /**\r
18127  * Return an `Error` representative of this response.\r
18128  *\r
18129  * @return {Error}\r
18130  * @api public\r
18131  */\r
18132 \r
18133 Response.prototype.toError = function(){\r
18134   var req = this.req;\r
18135   var method = req.method;\r
18136   var url = req.url;\r
18137 \r
18138   var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')';\r
18139   var err = new Error(msg);\r
18140   err.status = this.status;\r
18141   err.method = method;\r
18142   err.url = url;\r
18143 \r
18144   return err;\r
18145 };\r
18146 \r
18147 /**\r
18148  * Expose `Response`.\r
18149  */\r
18150 \r
18151 request.Response = Response;\r
18152 \r
18153 /**\r
18154  * Initialize a new `Request` with the given `method` and `url`.\r
18155  *\r
18156  * @param {String} method\r
18157  * @param {String} url\r
18158  * @api public\r
18159  */\r
18160 \r
18161 function Request(method, url) {\r
18162   var self = this;\r
18163   Emitter.call(this);\r
18164   this._query = this._query || [];\r
18165   this.method = method;\r
18166   this.url = url;\r
18167   this.header = {};\r
18168   this._header = {};\r
18169   this.on('end', function(){\r
18170     var err = null;\r
18171     var res = null;\r
18172 \r
18173     try {\r
18174       res = new Response(self);\r
18175     } catch(e) {\r
18176       err = new Error('Parser is unable to parse the response');\r
18177       err.parse = true;\r
18178       err.original = e;\r
18179       // issue #675: return the raw response if the response parsing fails\r
18180       err.rawResponse = self.xhr && self.xhr.responseText ? self.xhr.responseText : null;\r
18181       return self.callback(err);\r
18182     }\r
18183 \r
18184     self.emit('response', res);\r
18185 \r
18186     if (err) {\r
18187       return self.callback(err, res);\r
18188     }\r
18189 \r
18190     if (res.status >= 200 && res.status < 300) {\r
18191       return self.callback(err, res);\r
18192     }\r
18193 \r
18194     var new_err = new Error(res.statusText || 'Unsuccessful HTTP response');\r
18195     new_err.original = err;\r
18196     new_err.response = res;\r
18197     new_err.status = res.status;\r
18198 \r
18199     self.callback(new_err, res);\r
18200   });\r
18201 }\r
18202 \r
18203 /**\r
18204  * Mixin `Emitter`.\r
18205  */\r
18206 \r
18207 Emitter(Request.prototype);\r
18208 \r
18209 /**\r
18210  * Allow for extension\r
18211  */\r
18212 \r
18213 Request.prototype.use = function(fn) {\r
18214   fn(this);\r
18215   return this;\r
18216 }\r
18217 \r
18218 /**\r
18219  * Set timeout to `ms`.\r
18220  *\r
18221  * @param {Number} ms\r
18222  * @return {Request} for chaining\r
18223  * @api public\r
18224  */\r
18225 \r
18226 Request.prototype.timeout = function(ms){\r
18227   this._timeout = ms;\r
18228   return this;\r
18229 };\r
18230 \r
18231 /**\r
18232  * Clear previous timeout.\r
18233  *\r
18234  * @return {Request} for chaining\r
18235  * @api public\r
18236  */\r
18237 \r
18238 Request.prototype.clearTimeout = function(){\r
18239   this._timeout = 0;\r
18240   clearTimeout(this._timer);\r
18241   return this;\r
18242 };\r
18243 \r
18244 /**\r
18245  * Abort the request, and clear potential timeout.\r
18246  *\r
18247  * @return {Request}\r
18248  * @api public\r
18249  */\r
18250 \r
18251 Request.prototype.abort = function(){\r
18252   if (this.aborted) return;\r
18253   this.aborted = true;\r
18254   this.xhr.abort();\r
18255   this.clearTimeout();\r
18256   this.emit('abort');\r
18257   return this;\r
18258 };\r
18259 \r
18260 /**\r
18261  * Set header `field` to `val`, or multiple fields with one object.\r
18262  *\r
18263  * Examples:\r
18264  *\r
18265  *      req.get('/')\r
18266  *        .set('Accept', 'application/json')\r
18267  *        .set('X-API-Key', 'foobar')\r
18268  *        .end(callback);\r
18269  *\r
18270  *      req.get('/')\r
18271  *        .set({ Accept: 'application/json', 'X-API-Key': 'foobar' })\r
18272  *        .end(callback);\r
18273  *\r
18274  * @param {String|Object} field\r
18275  * @param {String} val\r
18276  * @return {Request} for chaining\r
18277  * @api public\r
18278  */\r
18279 \r
18280 Request.prototype.set = function(field, val){\r
18281   if (isObject(field)) {\r
18282     for (var key in field) {\r
18283       this.set(key, field[key]);\r
18284     }\r
18285     return this;\r
18286   }\r
18287   this._header[field.toLowerCase()] = val;\r
18288   this.header[field] = val;\r
18289   return this;\r
18290 };\r
18291 \r
18292 /**\r
18293  * Remove header `field`.\r
18294  *\r
18295  * Example:\r
18296  *\r
18297  *      req.get('/')\r
18298  *        .unset('User-Agent')\r
18299  *        .end(callback);\r
18300  *\r
18301  * @param {String} field\r
18302  * @return {Request} for chaining\r
18303  * @api public\r
18304  */\r
18305 \r
18306 Request.prototype.unset = function(field){\r
18307   delete this._header[field.toLowerCase()];\r
18308   delete this.header[field];\r
18309   return this;\r
18310 };\r
18311 \r
18312 /**\r
18313  * Get case-insensitive header `field` value.\r
18314  *\r
18315  * @param {String} field\r
18316  * @return {String}\r
18317  * @api private\r
18318  */\r
18319 \r
18320 Request.prototype.getHeader = function(field){\r
18321   return this._header[field.toLowerCase()];\r
18322 };\r
18323 \r
18324 /**\r
18325  * Set Content-Type to `type`, mapping values from `request.types`.\r
18326  *\r
18327  * Examples:\r
18328  *\r
18329  *      superagent.types.xml = 'application/xml';\r
18330  *\r
18331  *      request.post('/')\r
18332  *        .type('xml')\r
18333  *        .send(xmlstring)\r
18334  *        .end(callback);\r
18335  *\r
18336  *      request.post('/')\r
18337  *        .type('application/xml')\r
18338  *        .send(xmlstring)\r
18339  *        .end(callback);\r
18340  *\r
18341  * @param {String} type\r
18342  * @return {Request} for chaining\r
18343  * @api public\r
18344  */\r
18345 \r
18346 Request.prototype.type = function(type){\r
18347   this.set('Content-Type', request.types[type] || type);\r
18348   return this;\r
18349 };\r
18350 \r
18351 /**\r
18352  * Force given parser\r
18353  *\r
18354  * Sets the body parser no matter type.\r
18355  *\r
18356  * @param {Function}\r
18357  * @api public\r
18358  */\r
18359 \r
18360 Request.prototype.parse = function(fn){\r
18361   this._parser = fn;\r
18362   return this;\r
18363 };\r
18364 \r
18365 /**\r
18366  * Set Accept to `type`, mapping values from `request.types`.\r
18367  *\r
18368  * Examples:\r
18369  *\r
18370  *      superagent.types.json = 'application/json';\r
18371  *\r
18372  *      request.get('/agent')\r
18373  *        .accept('json')\r
18374  *        .end(callback);\r
18375  *\r
18376  *      request.get('/agent')\r
18377  *        .accept('application/json')\r
18378  *        .end(callback);\r
18379  *\r
18380  * @param {String} accept\r
18381  * @return {Request} for chaining\r
18382  * @api public\r
18383  */\r
18384 \r
18385 Request.prototype.accept = function(type){\r
18386   this.set('Accept', request.types[type] || type);\r
18387   return this;\r
18388 };\r
18389 \r
18390 /**\r
18391  * Set Authorization field value with `user` and `pass`.\r
18392  *\r
18393  * @param {String} user\r
18394  * @param {String} pass\r
18395  * @return {Request} for chaining\r
18396  * @api public\r
18397  */\r
18398 \r
18399 Request.prototype.auth = function(user, pass){\r
18400   var str = btoa(user + ':' + pass);\r
18401   this.set('Authorization', 'Basic ' + str);\r
18402   return this;\r
18403 };\r
18404 \r
18405 /**\r
18406 * Add query-string `val`.\r
18407 *\r
18408 * Examples:\r
18409 *\r
18410 *   request.get('/shoes')\r
18411 *     .query('size=10')\r
18412 *     .query({ color: 'blue' })\r
18413 *\r
18414 * @param {Object|String} val\r
18415 * @return {Request} for chaining\r
18416 * @api public\r
18417 */\r
18418 \r
18419 Request.prototype.query = function(val){\r
18420   if ('string' != typeof val) val = serialize(val);\r
18421   if (val) this._query.push(val);\r
18422   return this;\r
18423 };\r
18424 \r
18425 /**\r
18426  * Write the field `name` and `val` for "multipart/form-data"\r
18427  * request bodies.\r
18428  *\r
18429  * ``` js\r
18430  * request.post('/upload')\r
18431  *   .field('foo', 'bar')\r
18432  *   .end(callback);\r
18433  * ```\r
18434  *\r
18435  * @param {String} name\r
18436  * @param {String|Blob|File} val\r
18437  * @return {Request} for chaining\r
18438  * @api public\r
18439  */\r
18440 \r
18441 Request.prototype.field = function(name, val){\r
18442   if (!this._formData) this._formData = new root.FormData();\r
18443   this._formData.append(name, val);\r
18444   return this;\r
18445 };\r
18446 \r
18447 /**\r
18448  * Queue the given `file` as an attachment to the specified `field`,\r
18449  * with optional `filename`.\r
18450  *\r
18451  * ``` js\r
18452  * request.post('/upload')\r
18453  *   .attach(new Blob(['<a id="a"><b id="b">hey!</b></a>'], { type: "text/html"}))\r
18454  *   .end(callback);\r
18455  * ```\r
18456  *\r
18457  * @param {String} field\r
18458  * @param {Blob|File} file\r
18459  * @param {String} filename\r
18460  * @return {Request} for chaining\r
18461  * @api public\r
18462  */\r
18463 \r
18464 Request.prototype.attach = function(field, file, filename){\r
18465   if (!this._formData) this._formData = new root.FormData();\r
18466   this._formData.append(field, file, filename || file.name);\r
18467   return this;\r
18468 };\r
18469 \r
18470 /**\r
18471  * Send `data` as the request body, defaulting the `.type()` to "json" when\r
18472  * an object is given.\r
18473  *\r
18474  * Examples:\r
18475  *\r
18476  *       // manual json\r
18477  *       request.post('/user')\r
18478  *         .type('json')\r
18479  *         .send('{"name":"tj"}')\r
18480  *         .end(callback)\r
18481  *\r
18482  *       // auto json\r
18483  *       request.post('/user')\r
18484  *         .send({ name: 'tj' })\r
18485  *         .end(callback)\r
18486  *\r
18487  *       // manual x-www-form-urlencoded\r
18488  *       request.post('/user')\r
18489  *         .type('form')\r
18490  *         .send('name=tj')\r
18491  *         .end(callback)\r
18492  *\r
18493  *       // auto x-www-form-urlencoded\r
18494  *       request.post('/user')\r
18495  *         .type('form')\r
18496  *         .send({ name: 'tj' })\r
18497  *         .end(callback)\r
18498  *\r
18499  *       // defaults to x-www-form-urlencoded\r
18500   *      request.post('/user')\r
18501   *        .send('name=tobi')\r
18502   *        .send('species=ferret')\r
18503   *        .end(callback)\r
18504  *\r
18505  * @param {String|Object} data\r
18506  * @return {Request} for chaining\r
18507  * @api public\r
18508  */\r
18509 \r
18510 Request.prototype.send = function(data){\r
18511   var obj = isObject(data);\r
18512   var type = this.getHeader('Content-Type');\r
18513 \r
18514   // merge\r
18515   if (obj && isObject(this._data)) {\r
18516     for (var key in data) {\r
18517       this._data[key] = data[key];\r
18518     }\r
18519   } else if ('string' == typeof data) {\r
18520     if (!type) this.type('form');\r
18521     type = this.getHeader('Content-Type');\r
18522     if ('application/x-www-form-urlencoded' == type) {\r
18523       this._data = this._data\r
18524         ? this._data + '&' + data\r
18525         : data;\r
18526     } else {\r
18527       this._data = (this._data || '') + data;\r
18528     }\r
18529   } else {\r
18530     this._data = data;\r
18531   }\r
18532 \r
18533   if (!obj || isHost(data)) return this;\r
18534   if (!type) this.type('json');\r
18535   return this;\r
18536 };\r
18537 \r
18538 /**\r
18539  * Invoke the callback with `err` and `res`\r
18540  * and handle arity check.\r
18541  *\r
18542  * @param {Error} err\r
18543  * @param {Response} res\r
18544  * @api private\r
18545  */\r
18546 \r
18547 Request.prototype.callback = function(err, res){\r
18548   var fn = this._callback;\r
18549   this.clearTimeout();\r
18550   fn(err, res);\r
18551 };\r
18552 \r
18553 /**\r
18554  * Invoke callback with x-domain error.\r
18555  *\r
18556  * @api private\r
18557  */\r
18558 \r
18559 Request.prototype.crossDomainError = function(){\r
18560   var err = new Error('Request has been terminated\nPossible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.');\r
18561   err.crossDomain = true;\r
18562 \r
18563   err.status = this.status;\r
18564   err.method = this.method;\r
18565   err.url = this.url;\r
18566 \r
18567   this.callback(err);\r
18568 };\r
18569 \r
18570 /**\r
18571  * Invoke callback with timeout error.\r
18572  *\r
18573  * @api private\r
18574  */\r
18575 \r
18576 Request.prototype.timeoutError = function(){\r
18577   var timeout = this._timeout;\r
18578   var err = new Error('timeout of ' + timeout + 'ms exceeded');\r
18579   err.timeout = timeout;\r
18580   this.callback(err);\r
18581 };\r
18582 \r
18583 /**\r
18584  * Enable transmission of cookies with x-domain requests.\r
18585  *\r
18586  * Note that for this to work the origin must not be\r
18587  * using "Access-Control-Allow-Origin" with a wildcard,\r
18588  * and also must set "Access-Control-Allow-Credentials"\r
18589  * to "true".\r
18590  *\r
18591  * @api public\r
18592  */\r
18593 \r
18594 Request.prototype.withCredentials = function(){\r
18595   this._withCredentials = true;\r
18596   return this;\r
18597 };\r
18598 \r
18599 /**\r
18600  * Initiate request, invoking callback `fn(res)`\r
18601  * with an instanceof `Response`.\r
18602  *\r
18603  * @param {Function} fn\r
18604  * @return {Request} for chaining\r
18605  * @api public\r
18606  */\r
18607 \r
18608 Request.prototype.end = function(fn){\r
18609   var self = this;\r
18610   var xhr = this.xhr = request.getXHR();\r
18611   var query = this._query.join('&');\r
18612   var timeout = this._timeout;\r
18613   var data = this._formData || this._data;\r
18614 \r
18615   // store callback\r
18616   this._callback = fn || noop;\r
18617 \r
18618   // state change\r
18619   xhr.onreadystatechange = function(){\r
18620     if (4 != xhr.readyState) return;\r
18621 \r
18622     // In IE9, reads to any property (e.g. status) off of an aborted XHR will\r
18623     // result in the error "Could not complete the operation due to error c00c023f"\r
18624     var status;\r
18625     try { status = xhr.status } catch(e) { status = 0; }\r
18626 \r
18627     if (0 == status) {\r
18628       if (self.timedout) return self.timeoutError();\r
18629       if (self.aborted) return;\r
18630       return self.crossDomainError();\r
18631     }\r
18632     self.emit('end');\r
18633   };\r
18634 \r
18635   // progress\r
18636   var handleProgress = function(e){\r
18637     if (e.total > 0) {\r
18638       e.percent = e.loaded / e.total * 100;\r
18639     }\r
18640     e.direction = 'download';\r
18641     self.emit('progress', e);\r
18642   };\r
18643   if (this.hasListeners('progress')) {\r
18644     xhr.onprogress = handleProgress;\r
18645   }\r
18646   try {\r
18647     if (xhr.upload && this.hasListeners('progress')) {\r
18648       xhr.upload.onprogress = handleProgress;\r
18649     }\r
18650   } catch(e) {\r
18651     // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist.\r
18652     // Reported here:\r
18653     // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context\r
18654   }\r
18655 \r
18656   // timeout\r
18657   if (timeout && !this._timer) {\r
18658     this._timer = setTimeout(function(){\r
18659       self.timedout = true;\r
18660       self.abort();\r
18661     }, timeout);\r
18662   }\r
18663 \r
18664   // querystring\r
18665   if (query) {\r
18666     query = request.serializeObject(query);\r
18667     this.url += ~this.url.indexOf('?')\r
18668       ? '&' + query\r
18669       : '?' + query;\r
18670   }\r
18671 \r
18672   // initiate request\r
18673   xhr.open(this.method, this.url, true);\r
18674 \r
18675   // CORS\r
18676   if (this._withCredentials) xhr.withCredentials = true;\r
18677 \r
18678   // body\r
18679   if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !isHost(data)) {\r
18680     // serialize stuff\r
18681     var contentType = this.getHeader('Content-Type');\r
18682     var serialize = this._parser || request.serialize[contentType ? contentType.split(';')[0] : ''];\r
18683     if (!serialize && isJSON(contentType)) serialize = request.serialize['application/json'];\r
18684     if (serialize) data = serialize(data);\r
18685   }\r
18686 \r
18687   // set header fields\r
18688   for (var field in this.header) {\r
18689     if (null == this.header[field]) continue;\r
18690     xhr.setRequestHeader(field, this.header[field]);\r
18691   }\r
18692 \r
18693   // send stuff\r
18694   this.emit('request', this);\r
18695 \r
18696   // IE11 xhr.send(undefined) sends 'undefined' string as POST payload (instead of nothing)\r
18697   // We need null here if data is undefined\r
18698   xhr.send(typeof data !== 'undefined' ? data : null);\r
18699   return this;\r
18700 };\r
18701 \r
18702 /**\r
18703  * Faux promise support\r
18704  *\r
18705  * @param {Function} fulfill\r
18706  * @param {Function} reject\r
18707  * @return {Request}\r
18708  */\r
18709 \r
18710 Request.prototype.then = function (fulfill, reject) {\r
18711   return this.end(function(err, res) {\r
18712     err ? reject(err) : fulfill(res);\r
18713   });\r
18714 }\r
18715 \r
18716 /**\r
18717  * Expose `Request`.\r
18718  */\r
18719 \r
18720 request.Request = Request;\r
18721 \r
18722 /**\r
18723  * Issue a request:\r
18724  *\r
18725  * Examples:\r
18726  *\r
18727  *    request('GET', '/users').end(callback)\r
18728  *    request('/users').end(callback)\r
18729  *    request('/users', callback)\r
18730  *\r
18731  * @param {String} method\r
18732  * @param {String|Function} url or callback\r
18733  * @return {Request}\r
18734  * @api public\r
18735  */\r
18736 \r
18737 function request(method, url) {\r
18738   // callback\r
18739   if ('function' == typeof url) {\r
18740     return new Request('GET', method).end(url);\r
18741   }\r
18742 \r
18743   // url first\r
18744   if (1 == arguments.length) {\r
18745     return new Request('GET', method);\r
18746   }\r
18747 \r
18748   return new Request(method, url);\r
18749 }\r
18750 \r
18751 /**\r
18752  * GET `url` with optional callback `fn(res)`.\r
18753  *\r
18754  * @param {String} url\r
18755  * @param {Mixed|Function} data or fn\r
18756  * @param {Function} fn\r
18757  * @return {Request}\r
18758  * @api public\r
18759  */\r
18760 \r
18761 request.get = function(url, data, fn){\r
18762   var req = request('GET', url);\r
18763   if ('function' == typeof data) fn = data, data = null;\r
18764   if (data) req.query(data);\r
18765   if (fn) req.end(fn);\r
18766   return req;\r
18767 };\r
18768 \r
18769 /**\r
18770  * HEAD `url` with optional callback `fn(res)`.\r
18771  *\r
18772  * @param {String} url\r
18773  * @param {Mixed|Function} data or fn\r
18774  * @param {Function} fn\r
18775  * @return {Request}\r
18776  * @api public\r
18777  */\r
18778 \r
18779 request.head = function(url, data, fn){\r
18780   var req = request('HEAD', url);\r
18781   if ('function' == typeof data) fn = data, data = null;\r
18782   if (data) req.send(data);\r
18783   if (fn) req.end(fn);\r
18784   return req;\r
18785 };\r
18786 \r
18787 /**\r
18788  * DELETE `url` with optional callback `fn(res)`.\r
18789  *\r
18790  * @param {String} url\r
18791  * @param {Function} fn\r
18792  * @return {Request}\r
18793  * @api public\r
18794  */\r
18795 \r
18796 function del(url, fn){\r
18797   var req = request('DELETE', url);\r
18798   if (fn) req.end(fn);\r
18799   return req;\r
18800 };\r
18801 \r
18802 request['del'] = del;\r
18803 request['delete'] = del;\r
18804 \r
18805 /**\r
18806  * PATCH `url` with optional `data` and callback `fn(res)`.\r
18807  *\r
18808  * @param {String} url\r
18809  * @param {Mixed} data\r
18810  * @param {Function} fn\r
18811  * @return {Request}\r
18812  * @api public\r
18813  */\r
18814 \r
18815 request.patch = function(url, data, fn){\r
18816   var req = request('PATCH', url);\r
18817   if ('function' == typeof data) fn = data, data = null;\r
18818   if (data) req.send(data);\r
18819   if (fn) req.end(fn);\r
18820   return req;\r
18821 };\r
18822 \r
18823 /**\r
18824  * POST `url` with optional `data` and callback `fn(res)`.\r
18825  *\r
18826  * @param {String} url\r
18827  * @param {Mixed} data\r
18828  * @param {Function} fn\r
18829  * @return {Request}\r
18830  * @api public\r
18831  */\r
18832 \r
18833 request.post = function(url, data, fn){\r
18834   var req = request('POST', url);\r
18835   if ('function' == typeof data) fn = data, data = null;\r
18836   if (data) req.send(data);\r
18837   if (fn) req.end(fn);\r
18838   return req;\r
18839 };\r
18840 \r
18841 /**\r
18842  * PUT `url` with optional `data` and callback `fn(res)`.\r
18843  *\r
18844  * @param {String} url\r
18845  * @param {Mixed|Function} data or fn\r
18846  * @param {Function} fn\r
18847  * @return {Request}\r
18848  * @api public\r
18849  */\r
18850 \r
18851 request.put = function(url, data, fn){\r
18852   var req = request('PUT', url);\r
18853   if ('function' == typeof data) fn = data, data = null;\r
18854   if (data) req.send(data);\r
18855   if (fn) req.end(fn);\r
18856   return req;\r
18857 };\r
18858 \r
18859 /**\r
18860  * Expose `request`.\r
18861  */\r
18862 \r
18863 module.exports = request;\r
18864 \r
18865 },{"emitter":19,"reduce":160}]},{},[1])(1)\r
18866 });\r
18867 //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJpbmRleC5qcyIsImxpYi9hdXRoLmpzIiwibGliL2NsaWVudC5qcyIsImxpYi9oZWxwZXJzLmpzIiwibGliL2h0dHAuanMiLCJsaWIvcmVzb2x2ZXIuanMiLCJsaWIvc2NoZW1hLW1hcmt1cC5qcyIsImxpYi9zcGVjLWNvbnZlcnRlci5qcyIsImxpYi90eXBlcy9tb2RlbC5qcyIsImxpYi90eXBlcy9vcGVyYXRpb24uanMiLCJsaWIvdHlwZXMvb3BlcmF0aW9uR3JvdXAuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1yZXNvbHZlL2VtcHR5LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9idG9hL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2J1ZmZlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9idWZmZXIvbm9kZV9tb2R1bGVzL2Jhc2U2NC1qcy9saWIvYjY0LmpzIiwibm9kZV9tb2R1bGVzL2J1ZmZlci9ub2RlX21vZHVsZXMvaWVlZTc1NC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9idWZmZXIvbm9kZV9tb2R1bGVzL2lzLWFycmF5L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2NvbXBvbmVudC1lbWl0dGVyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Nvb2tpZWphci9jb29raWVqYXIuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvY29tbW9uLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvZHVtcGVyLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvZXhjZXB0aW9uLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvbG9hZGVyLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvbWFyay5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3NjaGVtYS5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3NjaGVtYS9jb3JlLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvc2NoZW1hL2RlZmF1bHRfZnVsbC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3NjaGVtYS9kZWZhdWx0X3NhZmUuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC9zY2hlbWEvZmFpbHNhZmUuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC9zY2hlbWEvanNvbi5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL2JpbmFyeS5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvYm9vbC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvZmxvYXQuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL2ludC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvanMvZnVuY3Rpb24uanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL2pzL3JlZ2V4cC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvanMvdW5kZWZpbmVkLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9tYXAuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL21lcmdlLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9udWxsLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9vbWFwLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9wYWlycy5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvc2VxLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9zZXQuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL3N0ci5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvdGltZXN0YW1wLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvYXJyYXkvaW5kZXhPZi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2FycmF5L2xhc3QuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jaGFpbi9sb2Rhc2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2VhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2ZpbmQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2ZvckVhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2luY2x1ZGVzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9tYXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9kYXRlL25vdy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2Z1bmN0aW9uL2JpbmQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9mdW5jdGlvbi9yZXN0UGFyYW0uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9MYXp5V3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL0xvZGFzaFdyYXBwZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9hcnJheUNvcHkuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9hcnJheUVhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9hcnJheU1hcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2FycmF5U29tZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VBc3NpZ24uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlQ2FsbGJhY2suanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlQ2xvbmUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlQ29weS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VDcmVhdGUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlRWFjaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VGaW5kLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUZpbmRJbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VGb3IuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlRm9ySW4uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlRm9yT3duLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUdldC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VJbmRleE9mLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUlzRXF1YWwuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlSXNFcXVhbERlZXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlSXNNYXRjaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VMb2Rhc2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlTWFwLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZU1hdGNoZXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlTWF0Y2hlc1Byb3BlcnR5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVByb3BlcnR5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVByb3BlcnR5RGVlcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VTZXREYXRhLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVNsaWNlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVRvU3RyaW5nLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVZhbHVlcy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2JpbmFyeUluZGV4LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmluYXJ5SW5kZXhCeS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2JpbmRDYWxsYmFjay5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2J1ZmZlckNsb25lLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY29tcG9zZUFyZ3MuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jb21wb3NlQXJnc1JpZ2h0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlQmFzZUVhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jcmVhdGVCYXNlRm9yLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlQmluZFdyYXBwZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jcmVhdGVDdG9yV3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NyZWF0ZUZpbmQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jcmVhdGVGb3JFYWNoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlSHlicmlkV3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NyZWF0ZVBhcnRpYWxXcmFwcGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlV3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2VxdWFsQXJyYXlzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvZXF1YWxCeVRhZy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2VxdWFsT2JqZWN0cy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldERhdGEuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9nZXRGdW5jTmFtZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldExlbmd0aC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldE1hdGNoRGF0YS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldE5hdGl2ZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2luZGV4T2ZOYU4uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pbml0Q2xvbmVBcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2luaXRDbG9uZUJ5VGFnLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaW5pdENsb25lT2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaXNBcnJheUxpa2UuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0hvc3RPYmplY3QuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaXNJdGVyYXRlZUNhbGwuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0tleS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2lzTGF6aWFibGUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0xlbmd0aC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2lzT2JqZWN0TGlrZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2lzU3RyaWN0Q29tcGFyYWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL21lcmdlRGF0YS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL21ldGFNYXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9yZWFsTmFtZXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9yZW9yZGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvcmVwbGFjZUhvbGRlcnMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9zZXREYXRhLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvc2hpbUtleXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC90b09iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL3RvUGF0aC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL3dyYXBwZXJDbG9uZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvY2xvbmVEZWVwLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc0FyZ3VtZW50cy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNBcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNFbXB0eS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNGdW5jdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNOYXRpdmUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9sYW5nL2lzT2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc1BsYWluT2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc1N0cmluZy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNUeXBlZEFycmF5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc1VuZGVmaW5lZC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L29iamVjdC9rZXlzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvb2JqZWN0L2tleXNJbi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L29iamVjdC9wYWlycy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L29iamVjdC92YWx1ZXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9zdXBwb3J0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvdXRpbGl0eS9pZGVudGl0eS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L3V0aWxpdHkvbm9vcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L3V0aWxpdHkvcHJvcGVydHkuanMiLCJub2RlX21vZHVsZXMvcS9xLmpzIiwibm9kZV9tb2R1bGVzL3JlZHVjZS1jb21wb25lbnQvaW5kZXguanMiLCJub2RlX21vZHVsZXMvc3VwZXJhZ2VudC9saWIvY2xpZW50LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDem1CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL3lCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcmhCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4b0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbCtCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNy9DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDclFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMXlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbGpEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbElBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3SEE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbmdFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIid1c2Ugc3RyaWN0JztcblxudmFyIGF1dGggPSByZXF1aXJlKCcuL2xpYi9hdXRoJyk7XG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4vbGliL2hlbHBlcnMnKTtcbnZhciBTd2FnZ2VyQ2xpZW50ID0gcmVxdWlyZSgnLi9saWIvY2xpZW50Jyk7XG52YXIgZGVwcmVjYXRpb25XcmFwcGVyID0gZnVuY3Rpb24gKHVybCwgb3B0aW9ucykge1xuICBoZWxwZXJzLmxvZygnVGhpcyBpcyBkZXByZWNhdGVkLCB1c2UgXCJuZXcgU3dhZ2dlckNsaWVudFwiIGluc3RlYWQuJyk7XG5cbiAgcmV0dXJuIG5ldyBTd2FnZ2VyQ2xpZW50KHVybCwgb3B0aW9ucyk7XG59O1xuXG4vKiBIZXJlIGZvciBJRTggU3VwcG9ydCAqL1xuaWYgKCFBcnJheS5wcm90b3R5cGUuaW5kZXhPZikge1xuICBBcnJheS5wcm90b3R5cGUuaW5kZXhPZiA9IGZ1bmN0aW9uKG9iaiwgc3RhcnQpIHtcbiAgICBmb3IgKHZhciBpID0gKHN0YXJ0IHx8IDApLCBqID0gdGhpcy5sZW5ndGg7IGkgPCBqOyBpKyspIHtcbiAgICAgIGlmICh0aGlzW2ldID09PSBvYmopIHsgcmV0dXJuIGk7IH1cbiAgICB9XG4gICAgcmV0dXJuIC0xO1xuICB9O1xufVxuXG4vKiBIZXJlIGZvciBJRTggU3VwcG9ydCAqL1xuaWYgKCFTdHJpbmcucHJvdG90eXBlLnRyaW0pIHtcbiAgU3RyaW5nLnByb3RvdHlwZS50cmltID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnJlcGxhY2UoL15cXHMrfFxccyskL2csICcnKTtcbiAgfTtcbn1cblxuLyogSGVyZSBmb3Igbm9kZSAxMC54IHN1cHBvcnQgKi9cbmlmICghU3RyaW5nLnByb3RvdHlwZS5lbmRzV2l0aCkge1xuICBTdHJpbmcucHJvdG90eXBlLmVuZHNXaXRoID0gZnVuY3Rpb24oc3VmZml4KSB7XG4gICAgcmV0dXJuIHRoaXMuaW5kZXhPZihzdWZmaXgsIHRoaXMubGVuZ3RoIC0gc3VmZml4Lmxlbmd0aCkgIT09IC0xO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFN3YWdnZXJDbGllbnQ7XG5cblN3YWdnZXJDbGllbnQuQXBpS2V5QXV0aG9yaXphdGlvbiA9IGF1dGguQXBpS2V5QXV0aG9yaXphdGlvbjtcblN3YWdnZXJDbGllbnQuUGFzc3dvcmRBdXRob3JpemF0aW9uID0gYXV0aC5QYXNzd29yZEF1dGhvcml6YXRpb247XG5Td2FnZ2VyQ2xpZW50LkNvb2tpZUF1dGhvcml6YXRpb24gPSBhdXRoLkNvb2tpZUF1dGhvcml6YXRpb247XG5Td2FnZ2VyQ2xpZW50LlN3YWdnZXJBcGkgPSBkZXByZWNhdGlvbldyYXBwZXI7XG5Td2FnZ2VyQ2xpZW50LlN3YWdnZXJDbGllbnQgPSBkZXByZWNhdGlvbldyYXBwZXI7XG5Td2FnZ2VyQ2xpZW50LlNjaGVtYU1hcmt1cCA9IHJlcXVpcmUoJy4vbGliL3NjaGVtYS1tYXJrdXAnKTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGhlbHBlcnMgPSByZXF1aXJlKCcuL2hlbHBlcnMnKTtcbnZhciBidG9hID0gcmVxdWlyZSgnYnRvYScpOyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbnZhciBDb29raWVKYXIgPSByZXF1aXJlKCdjb29raWVqYXInKS5Db29raWVKYXI7XG52YXIgXyA9IHtcbiAgZWFjaDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2VhY2gnKSxcbiAgaW5jbHVkZXM6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9pbmNsdWRlcycpLFxuICBpc09iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzT2JqZWN0JyksXG4gIGlzQXJyYXk6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc0FycmF5Jylcbn07XG5cbi8qKlxuICogU3dhZ2dlckF1dGhvcml6YXRpb25zIGFwcGx5cyB0aGUgY29ycmVjdCBhdXRob3JpemF0aW9uIHRvIGFuIG9wZXJhdGlvbiBiZWluZyBleGVjdXRlZFxuICovXG52YXIgU3dhZ2dlckF1dGhvcml6YXRpb25zID0gbW9kdWxlLmV4cG9ydHMuU3dhZ2dlckF1dGhvcml6YXRpb25zID0gZnVuY3Rpb24gKGF1dGh6KSB7XG4gIHRoaXMuYXV0aHogPSBhdXRoeiB8fCB7fTtcbn07XG5cbi8qKlxuICogQWRkIGF1dGhzIHRvIHRoZSBoYXNoXG4gKiBXaWxsIG92ZXJ3cml0ZSBhbnkgZXhpc3RpbmdcbiAqXG4gKi9cblN3YWdnZXJBdXRob3JpemF0aW9ucy5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gKG5hbWUsIGF1dGgpIHtcbiAgaWYoXy5pc09iamVjdChuYW1lKSkge1xuICAgIGZvciAodmFyIGtleSBpbiBuYW1lKSB7XG4gICAgICB0aGlzLmF1dGh6W2tleV0gPSBuYW1lW2tleV07XG4gICAgfVxuICB9IGVsc2UgaWYodHlwZW9mIG5hbWUgPT09ICdzdHJpbmcnICl7XG4gICAgdGhpcy5hdXRoeltuYW1lXSA9IGF1dGg7XG4gIH1cblxuICByZXR1cm4gYXV0aDtcbn07XG5cblN3YWdnZXJBdXRob3JpemF0aW9ucy5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgcmV0dXJuIGRlbGV0ZSB0aGlzLmF1dGh6W25hbWVdO1xufTtcblxuU3dhZ2dlckF1dGhvcml6YXRpb25zLnByb3RvdHlwZS5hcHBseSA9IGZ1bmN0aW9uIChvYmosIHNlY3VyaXRpZXMpIHtcbiAgdmFyIHN0YXR1cyA9IHRydWU7XG4gIHZhciBhcHBseUFsbCA9ICFzZWN1cml0aWVzO1xuICB2YXIgZmxhdHRlbmVkU2VjdXJpdGllcyA9IFtdO1xuXG4gIC8vIGZhdm9yIHRoZSBvYmplY3QtbGV2ZWwgYXV0aG9yaXphdGlvbnMgb3ZlciBnbG9iYWxcbiAgdmFyIGF1dGh6ID0gb2JqLmNsaWVudEF1dGhvcml6YXRpb25zIHx8IHRoaXMuYXV0aHo7XG5cbiAgLy8gU2VjdXJpdGllcyBjb3VsZCBiZSBbIHt9IF1cbiAgXy5lYWNoKHNlY3VyaXRpZXMsIGZ1bmN0aW9uIChvYmosIGtleSkge1xuXG4gICAgLy8gTWFrZSBzdXJlIHdlIGFjY291bnQgZm9yIHNlY3VyaXRpZXMgYmVpbmcgWyBzdHIgXVxuICAgIGlmKHR5cGVvZiBrZXkgPT09ICdzdHJpbmcnKSB7XG4gICAgICBmbGF0dGVuZWRTZWN1cml0aWVzLnB1c2goa2V5KTtcbiAgICB9XG5cbiAgICAvLyBGbGF0dGVuIGtleXMgaW4gdG8gb3VyIGFycmF5XG4gICAgXy5lYWNoKG9iaiwgZnVuY3Rpb24gKHZhbCwga2V5KSB7XG4gICAgICBmbGF0dGVuZWRTZWN1cml0aWVzLnB1c2goa2V5KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgXy5lYWNoKGF1dGh6LCBmdW5jdGlvbiAoYXV0aCwgYXV0aE5hbWUpIHtcbiAgICBpZihhcHBseUFsbCB8fCBfLmluY2x1ZGVzKGZsYXR0ZW5lZFNlY3VyaXRpZXMsIGF1dGhOYW1lKSkge1xuICAgICAgdmFyIG5ld1N0YXR1cyA9IGF1dGguYXBwbHkob2JqKTtcbiAgICAgIHN0YXR1cyA9IHN0YXR1cyAmJiAhIW5ld1N0YXR1czsgLy8gbG9naWNhbCBPUnMgcmVnYXJkaW5nIHN0YXR1c1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHN0YXR1cztcbn07XG5cbi8qKlxuICogQXBpS2V5QXV0aG9yaXphdGlvbiBhbGxvd3MgYSBxdWVyeSBwYXJhbSBvciBoZWFkZXIgdG8gYmUgaW5qZWN0ZWRcbiAqL1xudmFyIEFwaUtleUF1dGhvcml6YXRpb24gPSBtb2R1bGUuZXhwb3J0cy5BcGlLZXlBdXRob3JpemF0aW9uID0gZnVuY3Rpb24gKG5hbWUsIHZhbHVlLCB0eXBlKSB7XG4gIHRoaXMubmFtZSA9IG5hbWU7XG4gIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgdGhpcy50eXBlID0gdHlwZTtcbn07XG5cbkFwaUtleUF1dGhvcml6YXRpb24ucHJvdG90eXBlLmFwcGx5ID0gZnVuY3Rpb24gKG9iaikge1xuICBpZiAodGhpcy50eXBlID09PSAncXVlcnknKSB7XG4gICAgLy8gc2VlIGlmIGFscmVhZHkgYXBwbGllZC4gIElmIHNvLCBkb24ndCBkbyBpdCBhZ2FpblxuXG4gICAgdmFyIHFwO1xuICAgIGlmIChvYmoudXJsLmluZGV4T2YoJz8nKSA+IDApIHtcbiAgICAgIHFwID0gb2JqLnVybC5zdWJzdHJpbmcob2JqLnVybC5pbmRleE9mKCc/JykgKyAxKTtcbiAgICAgIHZhciBwYXJ0cyA9IHFwLnNwbGl0KCcmJyk7XG4gICAgICBpZihwYXJ0cyAmJiBwYXJ0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBwYXJ0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIHZhciBrdiA9IHBhcnRzW2ldLnNwbGl0KCc9Jyk7XG4gICAgICAgICAgaWYoa3YgJiYga3YubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgaWYgKGt2WzBdID09PSB0aGlzLm5hbWUpIHtcbiAgICAgICAgICAgICAgLy8gc2tpcCBpdFxuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG9iai51cmwuaW5kZXhPZignPycpID4gMCkge1xuICAgICAgb2JqLnVybCA9IG9iai51cmwgKyAnJicgKyB0aGlzLm5hbWUgKyAnPScgKyB0aGlzLnZhbHVlO1xuICAgIH0gZWxzZSB7XG4gICAgICBvYmoudXJsID0gb2JqLnVybCArICc/JyArIHRoaXMubmFtZSArICc9JyArIHRoaXMudmFsdWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH0gZWxzZSBpZiAodGhpcy50eXBlID09PSAnaGVhZGVyJykge1xuICAgIGlmKHR5cGVvZiBvYmouaGVhZGVyc1t0aGlzLm5hbWVdID09PSAndW5kZWZpbmVkJykge1xuICAgICAgb2JqLmhlYWRlcnNbdGhpcy5uYW1lXSA9IHRoaXMudmFsdWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbn07XG5cbnZhciBDb29raWVBdXRob3JpemF0aW9uID0gbW9kdWxlLmV4cG9ydHMuQ29va2llQXV0aG9yaXphdGlvbiA9IGZ1bmN0aW9uIChjb29raWUpIHtcbiAgdGhpcy5jb29raWUgPSBjb29raWU7XG59O1xuXG5Db29raWVBdXRob3JpemF0aW9uLnByb3RvdHlwZS5hcHBseSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgb2JqLmNvb2tpZUphciA9IG9iai5jb29raWVKYXIgfHwgbmV3IENvb2tpZUphcigpO1xuICBvYmouY29va2llSmFyLnNldENvb2tpZSh0aGlzLmNvb2tpZSk7XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG4vKipcbiAqIFBhc3N3b3JkIEF1dGhvcml6YXRpb24gaXMgYSBiYXNpYyBhdXRoIGltcGxlbWVudGF0aW9uXG4gKi9cbnZhciBQYXNzd29yZEF1dGhvcml6YXRpb24gPSBtb2R1bGUuZXhwb3J0cy5QYXNzd29yZEF1dGhvcml6YXRpb24gPSBmdW5jdGlvbiAodXNlcm5hbWUsIHBhc3N3b3JkKSB7XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAzKSB7XG4gICAgaGVscGVycy5sb2coJ1Bhc3N3b3JkQXV0aG9yaXphdGlvbjogdGhlIFxcJ25hbWVcXCcgYXJndW1lbnQgaGFzIGJlZW4gcmVtb3ZlZCwgcGFzcyBvbmx5IHVzZXJuYW1lIGFuZCBwYXNzd29yZCcpO1xuICAgIHVzZXJuYW1lID0gYXJndW1lbnRzWzFdO1xuICAgIHBhc3N3b3JkID0gYXJndW1lbnRzWzJdO1xuICB9XG4gIHRoaXMudXNlcm5hbWUgPSB1c2VybmFtZTtcbiAgdGhpcy5wYXNzd29yZCA9IHBhc3N3b3JkO1xufTtcblxuUGFzc3dvcmRBdXRob3JpemF0aW9uLnByb3RvdHlwZS5hcHBseSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgaWYodHlwZW9mIG9iai5oZWFkZXJzLkF1dGhvcml6YXRpb24gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgb2JqLmhlYWRlcnMuQXV0aG9yaXphdGlvbiA9ICdCYXNpYyAnICsgYnRvYSh0aGlzLnVzZXJuYW1lICsgJzonICsgdGhpcy5wYXNzd29yZCk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBfID0ge1xuICBiaW5kOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2Z1bmN0aW9uL2JpbmQnKSxcbiAgY2xvbmVEZWVwOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvY2xvbmVEZWVwJyksXG4gIGZpbmQ6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9maW5kJyksXG4gIGZvckVhY2g6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9mb3JFYWNoJyksXG4gIGluZGV4T2Y6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvYXJyYXkvaW5kZXhPZicpLFxuICBpc0FycmF5OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNBcnJheScpLFxuICBpc09iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzT2JqZWN0JyksXG4gIGlzRnVuY3Rpb246IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc0Z1bmN0aW9uJyksXG4gIGlzUGxhaW5PYmplY3Q6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc1BsYWluT2JqZWN0JyksXG4gIGlzVW5kZWZpbmVkOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNVbmRlZmluZWQnKVxufTtcbnZhciBhdXRoID0gcmVxdWlyZSgnLi9hdXRoJyk7XG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4vaGVscGVycycpO1xudmFyIE1vZGVsID0gcmVxdWlyZSgnLi90eXBlcy9tb2RlbCcpO1xudmFyIE9wZXJhdGlvbiA9IHJlcXVpcmUoJy4vdHlwZXMvb3BlcmF0aW9uJyk7XG52YXIgT3BlcmF0aW9uR3JvdXAgPSByZXF1aXJlKCcuL3R5cGVzL29wZXJhdGlvbkdyb3VwJyk7XG52YXIgUmVzb2x2ZXIgPSByZXF1aXJlKCcuL3Jlc29sdmVyJyk7XG52YXIgU3dhZ2dlckh0dHAgPSByZXF1aXJlKCcuL2h0dHAnKTtcbnZhciBTd2FnZ2VyU3BlY0NvbnZlcnRlciA9IHJlcXVpcmUoJy4vc3BlYy1jb252ZXJ0ZXInKTtcbnZhciBRID0gcmVxdWlyZSgncScpO1xuXG4vLyBXZSBoYXZlIHRvIGtlZXAgdHJhY2sgb2YgdGhlIGZ1bmN0aW9uL3Byb3BlcnR5IG5hbWVzIHRvIGF2b2lkIGNvbGxpc2lvbnMgZm9yIHRhZyBuYW1lcyB3aGljaCBhcmUgdXNlZCB0byBhbGxvdyB0aGVcbi8vIGZvbGxvd2luZyB1c2FnZTogJ2NsaWVudC57dGFnTmFtZX0nXG52YXIgcmVzZXJ2ZWRDbGllbnRUYWdzID0gW1xuICAnYXBpcycsXG4gICdhdXRob3JpemF0aW9uU2NoZW1lJyxcbiAgJ2F1dGhvcml6YXRpb25zJyxcbiAgJ2Jhc2VQYXRoJyxcbiAgJ2J1aWxkJyxcbiAgJ2J1aWxkRnJvbTFfMVNwZWMnLFxuICAnYnVpbGRGcm9tMV8yU3BlYycsXG4gICdidWlsZEZyb21TcGVjJyxcbiAgJ2NsaWVudEF1dGhvcml6YXRpb25zJyxcbiAgJ2NvbnZlcnRJbmZvJyxcbiAgJ2RlYnVnJyxcbiAgJ2RlZmF1bHRFcnJvckNhbGxiYWNrJyxcbiAgJ2RlZmF1bHRTdWNjZXNzQ2FsbGJhY2snLFxuICAnZW5hYmxlQ29va2llcycsXG4gICdmYWlsJyxcbiAgJ2ZhaWx1cmUnLFxuICAnZmluaXNoJyxcbiAgJ2hlbHAnLFxuICAnaG9zdCcsXG4gICdpZEZyb21PcCcsXG4gICdpbmZvJyxcbiAgJ2luaXRpYWxpemUnLFxuICAnaXNCdWlsdCcsXG4gICdpc1ZhbGlkJyxcbiAgJ21vZGVsUHJvcGVydHlNYWNybycsXG4gICdtb2RlbHMnLFxuICAnbW9kZWxzQXJyYXknLFxuICAnb3B0aW9ucycsXG4gICdwYXJhbWV0ZXJNYWNybycsXG4gICdwYXJzZVVyaScsXG4gICdwcm9ncmVzcycsXG4gICdyZXNvdXJjZUNvdW50JyxcbiAgJ3NhbXBsZU1vZGVscycsXG4gICdzZWxmUmVmbGVjdCcsXG4gICdzZXRDb25zb2xpZGF0ZWRNb2RlbHMnLFxuICAnc3BlYycsXG4gICdzdXBwb3J0ZWRTdWJtaXRNZXRob2RzJyxcbiAgJ3N3YWdnZXJSZXF1ZXN0SGVhZGVycycsXG4gICd0YWdGcm9tTGFiZWwnLFxuICAndGl0bGUnLFxuICAndXJsJyxcbiAgJ3VzZUpRdWVyeSdcbl07XG4vLyBXZSBoYXZlIHRvIGtlZXAgdHJhY2sgb2YgdGhlIGZ1bmN0aW9uL3Byb3BlcnR5IG5hbWVzIHRvIGF2b2lkIGNvbGxpc2lvbnMgZm9yIHRhZyBuYW1lcyB3aGljaCBhcmUgdXNlZCB0byBhbGxvdyB0aGVcbi8vIGZvbGxvd2luZyB1c2FnZTogJ2NsaWVudC5hcGlzLnt0YWdOYW1lfSdcbnZhciByZXNlcnZlZEFwaVRhZ3MgPSBbXG4gICdhcGlzJyxcbiAgJ2FzQ3VybCcsXG4gICdkZXNjcmlwdGlvbicsXG4gICdleHRlcm5hbERvY3MnLFxuICAnaGVscCcsXG4gICdsYWJlbCcsXG4gICduYW1lJyxcbiAgJ29wZXJhdGlvbicsXG4gICdvcGVyYXRpb25zJyxcbiAgJ29wZXJhdGlvbnNBcnJheScsXG4gICdwYXRoJyxcbiAgJ3RhZydcbl07XG52YXIgc3VwcG9ydGVkT3BlcmF0aW9uTWV0aG9kcyA9IFsnZGVsZXRlJywgJ2dldCcsICdoZWFkJywgJ29wdGlvbnMnLCAncGF0Y2gnLCAncG9zdCcsICdwdXQnXTtcbnZhciBTd2FnZ2VyQ2xpZW50ID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAodXJsLCBvcHRpb25zKSB7XG4gIHRoaXMuYXV0aG9yaXphdGlvbnMgPSBudWxsO1xuICB0aGlzLmF1dGhvcml6YXRpb25TY2hlbWUgPSBudWxsO1xuICB0aGlzLmJhc2VQYXRoID0gbnVsbDtcbiAgdGhpcy5kZWJ1ZyA9IGZhbHNlO1xuICB0aGlzLmVuYWJsZUNvb2tpZXMgPSBmYWxzZTtcbiAgdGhpcy5pbmZvID0gbnVsbDtcbiAgdGhpcy5pc0J1aWx0ID0gZmFsc2U7XG4gIHRoaXMuaXNWYWxpZCA9IGZhbHNlO1xuICB0aGlzLm1vZGVsc0FycmF5ID0gW107XG4gIHRoaXMucmVzb3VyY2VDb3VudCA9IDA7XG4gIHRoaXMudXJsID0gbnVsbDtcbiAgdGhpcy51c2VKUXVlcnkgPSBmYWxzZTtcbiAgdGhpcy5zd2FnZ2VyT2JqZWN0ID0ge307XG4gIHRoaXMuZGVmZXJyZWRDbGllbnQgPSB1bmRlZmluZWQ7XG5cbiAgdGhpcy5jbGllbnRBdXRob3JpemF0aW9ucyA9IG5ldyBhdXRoLlN3YWdnZXJBdXRob3JpemF0aW9ucygpO1xuXG4gIGlmICh0eXBlb2YgdXJsICE9PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiB0aGlzLmluaXRpYWxpemUodXJsLCBvcHRpb25zKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxufTtcblxuU3dhZ2dlckNsaWVudC5wcm90b3R5cGUuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uICh1cmwsIG9wdGlvbnMpIHtcbiAgdGhpcy5tb2RlbHMgPSB7fTtcbiAgdGhpcy5zYW1wbGVNb2RlbHMgPSB7fTtcblxuICBpZiAodHlwZW9mIHVybCA9PT0gJ3N0cmluZycpIHtcbiAgICB0aGlzLnVybCA9IHVybDtcbiAgfSBlbHNlIGlmIChfLmlzT2JqZWN0KHVybCkpIHtcbiAgICBvcHRpb25zID0gdXJsO1xuICAgIHRoaXMudXJsID0gb3B0aW9ucy51cmw7XG4gIH1cblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgdGhpcy5jbGllbnRBdXRob3JpemF0aW9ucy5hZGQob3B0aW9ucy5hdXRob3JpemF0aW9ucyk7XG4gIHRoaXMuc3dhZ2dlclJlcXVlc3RIZWFkZXJzID0gb3B0aW9ucy5zd2FnZ2VyUmVxdWVzdEhlYWRlcnMgfHwgJ2FwcGxpY2F0aW9uL2pzb247Y2hhcnNldD11dGYtOCwqLyonO1xuICB0aGlzLmRlZmF1bHRTdWNjZXNzQ2FsbGJhY2sgPSBvcHRpb25zLmRlZmF1bHRTdWNjZXNzQ2FsbGJhY2sgfHwgbnVsbDtcbiAgdGhpcy5kZWZhdWx0RXJyb3JDYWxsYmFjayA9IG9wdGlvbnMuZGVmYXVsdEVycm9yQ2FsbGJhY2sgfHwgbnVsbDtcbiAgdGhpcy5tb2RlbFByb3BlcnR5TWFjcm8gPSBvcHRpb25zLm1vZGVsUHJvcGVydHlNYWNybyB8fCBudWxsO1xuICB0aGlzLnBhcmFtZXRlck1hY3JvID0gb3B0aW9ucy5wYXJhbWV0ZXJNYWNybyB8fCBudWxsO1xuICB0aGlzLnVzZVByb21pc2UgPSBvcHRpb25zLnVzZVByb21pc2UgfHwgbnVsbDtcblxuXG4gIGlmKHRoaXMudXNlUHJvbWlzZSkge1xuICAgIHRoaXMuZGVmZXJyZWRDbGllbnQgPSBRLmRlZmVyKCk7XG4gIH1cblxuICBpZiAodHlwZW9mIG9wdGlvbnMuc3VjY2VzcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHRoaXMuc3VjY2VzcyA9IG9wdGlvbnMuc3VjY2VzcztcbiAgfVxuXG4gIGlmIChvcHRpb25zLnVzZUpRdWVyeSkge1xuICAgIHRoaXMudXNlSlF1ZXJ5ID0gb3B0aW9ucy51c2VKUXVlcnk7XG4gIH1cblxuICBpZiAob3B0aW9ucy5lbmFibGVDb29raWVzKSB7XG4gICAgdGhpcy5lbmFibGVDb29raWVzID0gb3B0aW9ucy5lbmFibGVDb29raWVzO1xuICB9XG5cbiAgdGhpcy5vcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB0aGlzLnN1cHBvcnRlZFN1Ym1pdE1ldGhvZHMgPSBvcHRpb25zLnN1cHBvcnRlZFN1Ym1pdE1ldGhvZHMgfHwgW107XG4gIHRoaXMuZmFpbHVyZSA9IG9wdGlvbnMuZmFpbHVyZSB8fCBmdW5jdGlvbiAoZXJyKSB7IHRocm93IGVycjsgfTtcbiAgdGhpcy5wcm9ncmVzcyA9IG9wdGlvbnMucHJvZ3Jlc3MgfHwgZnVuY3Rpb24gKCkge307XG4gIHRoaXMuc3BlYyA9IF8uY2xvbmVEZWVwKG9wdGlvbnMuc3BlYyk7IC8vIENsb25lIHNvIHdlIGRvIG5vdCBhbHRlciB0aGUgcHJvdmlkZWQgZG9jdW1lbnRcblxuICBpZiAob3B0aW9ucy5zY2hlbWUpIHtcbiAgICB0aGlzLnNjaGVtZSA9IG9wdGlvbnMuc2NoZW1lO1xuICB9XG5cbiAgaWYgKHRoaXMudXNlUHJvbWlzZSB8fCB0eXBlb2Ygb3B0aW9ucy5zdWNjZXNzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhpcy5yZWFkeSA9IHRydWU7XG4gICAgcmV0dXJuIHRoaXMuYnVpbGQoKTtcbiAgfVxufTtcblxuU3dhZ2dlckNsaWVudC5wcm90b3R5cGUuYnVpbGQgPSBmdW5jdGlvbiAobW9jaykge1xuICBpZiAodGhpcy5pc0J1aWx0KSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy5wcm9ncmVzcygnZmV0Y2hpbmcgcmVzb3VyY2UgbGlzdDogJyArIHRoaXMudXJsICsgJzsgUGxlYXNlIHdhaXQuJyk7XG5cbiAgdmFyIG9iaiA9IHtcbiAgICB1c2VKUXVlcnk6IHRoaXMudXNlSlF1ZXJ5LFxuICAgIHVybDogdGhpcy51cmwsXG4gICAgbWV0aG9kOiAnZ2V0JyxcbiAgICBoZWFkZXJzOiB7XG4gICAgICBhY2NlcHQ6IHRoaXMuc3dhZ2dlclJlcXVlc3RIZWFkZXJzXG4gICAgfSxcbiAgICBvbjoge1xuICAgICAgZXJyb3I6IGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgICBpZiAoc2VsZi51cmwuc3Vic3RyaW5nKDAsIDQpICE9PSAnaHR0cCcpIHtcbiAgICAgICAgICByZXR1cm4gc2VsZi5mYWlsKCdQbGVhc2Ugc3BlY2lmeSB0aGUgcHJvdG9jb2wgZm9yICcgKyBzZWxmLnVybCk7XG4gICAgICAgIH0gZWxzZSBpZiAocmVzcG9uc2Uuc3RhdHVzID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuIHNlbGYuZmFpbCgnQ2FuXFwndCByZWFkIGZyb20gc2VydmVyLiAgSXQgbWF5IG5vdCBoYXZlIHRoZSBhcHByb3ByaWF0ZSBhY2Nlc3MtY29udHJvbC1vcmlnaW4gc2V0dGluZ3MuJyk7XG4gICAgICAgIH0gZWxzZSBpZiAocmVzcG9uc2Uuc3RhdHVzID09PSA0MDQpIHtcbiAgICAgICAgICByZXR1cm4gc2VsZi5mYWlsKCdDYW5cXCd0IHJlYWQgc3dhZ2dlciBKU09OIGZyb20gJyArIHNlbGYudXJsKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gc2VsZi5mYWlsKHJlc3BvbnNlLnN0YXR1cyArICcgOiAnICsgcmVzcG9uc2Uuc3RhdHVzVGV4dCArICcgJyArIHNlbGYudXJsKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHJlc3BvbnNlOiBmdW5jdGlvbiAocmVzcCkge1xuXG4gICAgICAgIHZhciByZXNwb25zZU9iaiA9IHJlc3Aub2JqO1xuICAgICAgICBpZighcmVzcG9uc2VPYmopIHtcbiAgICAgICAgICByZXR1cm4gc2VsZi5mYWlsKCdmYWlsZWQgdG8gcGFyc2UgSlNPTi9ZQU1MIHJlc3BvbnNlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBzZWxmLnN3YWdnZXJWZXJzaW9uID0gcmVzcG9uc2VPYmouc3dhZ2dlclZlcnNpb247XG4gICAgICAgIHNlbGYuc3dhZ2dlck9iamVjdCA9IHJlc3BvbnNlT2JqO1xuXG4gICAgICAgIGlmIChyZXNwb25zZU9iai5zd2FnZ2VyICYmIHBhcnNlSW50KHJlc3BvbnNlT2JqLnN3YWdnZXIpID09PSAyKSB7XG4gICAgICAgICAgc2VsZi5zd2FnZ2VyVmVyc2lvbiA9IHJlc3BvbnNlT2JqLnN3YWdnZXI7XG5cbiAgICAgICAgICBuZXcgUmVzb2x2ZXIoKS5yZXNvbHZlKHJlc3BvbnNlT2JqLCBzZWxmLnVybCwgc2VsZi5idWlsZEZyb21TcGVjLCBzZWxmKTtcblxuICAgICAgICAgIHNlbGYuaXNWYWxpZCA9IHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFyIGNvbnZlcnRlciA9IG5ldyBTd2FnZ2VyU3BlY0NvbnZlcnRlcigpO1xuICAgICAgICAgIHNlbGYub2xkU3dhZ2dlck9iamVjdCA9IHNlbGYuc3dhZ2dlck9iamVjdDtcblxuICAgICAgICAgIGNvbnZlcnRlci5zZXREb2N1bWVudGF0aW9uTG9jYXRpb24oc2VsZi51cmwpO1xuICAgICAgICAgIGNvbnZlcnRlci5jb252ZXJ0KHJlc3BvbnNlT2JqLCBzZWxmLmNsaWVudEF1dGhvcml6YXRpb25zLCBzZWxmLm9wdGlvbnMsIGZ1bmN0aW9uKHNwZWMpIHtcbiAgICAgICAgICAgIHNlbGYuc3dhZ2dlck9iamVjdCA9IHNwZWM7XG4gICAgICAgICAgICBuZXcgUmVzb2x2ZXIoKS5yZXNvbHZlKHNwZWMsIHNlbGYudXJsLCBzZWxmLmJ1aWxkRnJvbVNwZWMsIHNlbGYpO1xuICAgICAgICAgICAgc2VsZi5pc1ZhbGlkID0gdHJ1ZTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBpZiAodGhpcy5zcGVjKSB7XG4gICAgc2VsZi5zd2FnZ2VyT2JqZWN0ID0gdGhpcy5zcGVjO1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgbmV3IFJlc29sdmVyKCkucmVzb2x2ZShzZWxmLnNwZWMsIHNlbGYudXJsLCBzZWxmLmJ1aWxkRnJvbVNwZWMsIHNlbGYpO1xuICAgIH0sIDEwKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zLmFwcGx5KG9iaik7XG5cbiAgICBpZiAobW9jaykge1xuICAgICAgcmV0dXJuIG9iajtcbiAgICB9XG5cbiAgICBuZXcgU3dhZ2dlckh0dHAoKS5leGVjdXRlKG9iaiwgdGhpcy5vcHRpb25zKTtcbiAgfVxuXG4gIHJldHVybiAodGhpcy51c2VQcm9taXNlKSA/IHRoaXMuZGVmZXJyZWRDbGllbnQucHJvbWlzZSA6IHRoaXM7XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5idWlsZEZyb21TcGVjID0gZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gIGlmICh0aGlzLmlzQnVpbHQpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHRoaXMuYXBpcyA9IHt9O1xuICB0aGlzLmFwaXNBcnJheSA9IFtdO1xuICB0aGlzLmJhc2VQYXRoID0gcmVzcG9uc2UuYmFzZVBhdGggfHwgJyc7XG4gIHRoaXMuY29uc3VtZXMgPSByZXNwb25zZS5jb25zdW1lcztcbiAgdGhpcy5ob3N0ID0gcmVzcG9uc2UuaG9zdCB8fCAnJztcbiAgdGhpcy5pbmZvID0gcmVzcG9uc2UuaW5mbyB8fCB7fTtcbiAgdGhpcy5wcm9kdWNlcyA9IHJlc3BvbnNlLnByb2R1Y2VzO1xuICB0aGlzLnNjaGVtZXMgPSByZXNwb25zZS5zY2hlbWVzIHx8IFtdO1xuICB0aGlzLnNlY3VyaXR5RGVmaW5pdGlvbnMgPSByZXNwb25zZS5zZWN1cml0eURlZmluaXRpb25zO1xuICB0aGlzLnNlY3VyaXR5ID0gcmVzcG9uc2Uuc2VjdXJpdHk7XG4gIHRoaXMudGl0bGUgPSByZXNwb25zZS50aXRsZSB8fCAnJztcblxuICBpZiAocmVzcG9uc2UuZXh0ZXJuYWxEb2NzKSB7XG4gICAgdGhpcy5leHRlcm5hbERvY3MgPSByZXNwb25zZS5leHRlcm5hbERvY3M7XG4gIH1cblxuICAvLyBsZWdhY3kgc3VwcG9ydFxuICB0aGlzLmF1dGhTY2hlbWVzID0gcmVzcG9uc2Uuc2VjdXJpdHlEZWZpbml0aW9ucztcblxuICB2YXIgZGVmaW5lZFRhZ3MgPSB7fTtcbiAgdmFyIGs7XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkocmVzcG9uc2UudGFncykpIHtcbiAgICBkZWZpbmVkVGFncyA9IHt9O1xuXG4gICAgZm9yIChrID0gMDsgayA8IHJlc3BvbnNlLnRhZ3MubGVuZ3RoOyBrKyspIHtcbiAgICAgIHZhciB0ID0gcmVzcG9uc2UudGFnc1trXTtcbiAgICAgIGRlZmluZWRUYWdzW3QubmFtZV0gPSB0O1xuICAgIH1cbiAgfVxuXG4gIHZhciBsb2NhdGlvbjtcblxuICBpZiAodHlwZW9mIHRoaXMudXJsID09PSAnc3RyaW5nJykge1xuICAgIGxvY2F0aW9uID0gdGhpcy5wYXJzZVVyaSh0aGlzLnVybCk7XG4gICAgaWYgKHR5cGVvZiB0aGlzLnNjaGVtZSA9PT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIHRoaXMuc2NoZW1lcyA9PT0gJ3VuZGVmaW5lZCcgfHwgdGhpcy5zY2hlbWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5zY2hlbWUgPSBsb2NhdGlvbi5zY2hlbWUgfHwgJ2h0dHAnO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHRoaXMuc2NoZW1lID09PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhpcy5zY2hlbWUgPSB0aGlzLnNjaGVtZXNbMF0gfHwgbG9jYXRpb24uc2NoZW1lO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdGhpcy5ob3N0ID09PSAndW5kZWZpbmVkJyB8fCB0aGlzLmhvc3QgPT09ICcnKSB7XG4gICAgICB0aGlzLmhvc3QgPSBsb2NhdGlvbi5ob3N0O1xuXG4gICAgICBpZiAobG9jYXRpb24ucG9ydCkge1xuICAgICAgICB0aGlzLmhvc3QgPSB0aGlzLmhvc3QgKyAnOicgKyBsb2NhdGlvbi5wb3J0O1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBlbHNlIHtcbiAgICBpZiAodHlwZW9mIHRoaXMuc2NoZW1lcyA9PT0gJ3VuZGVmaW5lZCcgfHwgdGhpcy5zY2hlbWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5zY2hlbWUgPSAnaHR0cCc7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGVvZiB0aGlzLnNjaGVtZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRoaXMuc2NoZW1lID0gdGhpcy5zY2hlbWVzWzBdO1xuICAgIH1cbiAgfVxuXG4gIHRoaXMuZGVmaW5pdGlvbnMgPSByZXNwb25zZS5kZWZpbml0aW9ucztcblxuICB2YXIga2V5O1xuXG4gIGZvciAoa2V5IGluIHRoaXMuZGVmaW5pdGlvbnMpIHtcbiAgICB2YXIgbW9kZWwgPSBuZXcgTW9kZWwoa2V5LCB0aGlzLmRlZmluaXRpb25zW2tleV0sIHRoaXMubW9kZWxzLCB0aGlzLm1vZGVsUHJvcGVydHlNYWNybyk7XG5cbiAgICBpZiAobW9kZWwpIHtcbiAgICAgIHRoaXMubW9kZWxzW2tleV0gPSBtb2RlbDtcbiAgICB9XG4gIH1cblxuICAvLyBnZXQgcGF0aHMsIGNyZWF0ZSBmdW5jdGlvbnMgZm9yIGVhY2ggb3BlcmF0aW9uSWRcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIC8vIEJpbmQgaGVscCB0byAnY2xpZW50LmFwaXMnXG4gIHNlbGYuYXBpcy5oZWxwID0gXy5iaW5kKHNlbGYuaGVscCwgc2VsZik7XG5cbiAgXy5mb3JFYWNoKHJlc3BvbnNlLnBhdGhzLCBmdW5jdGlvbiAocGF0aE9iaiwgcGF0aCkge1xuICAgIC8vIE9ubHkgcHJvY2VzcyBhIHBhdGggaWYgaXQncyBhbiBvYmplY3RcbiAgICBpZiAoIV8uaXNQbGFpbk9iamVjdChwYXRoT2JqKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIF8uZm9yRWFjaChzdXBwb3J0ZWRPcGVyYXRpb25NZXRob2RzLCBmdW5jdGlvbiAobWV0aG9kKSB7XG4gICAgICB2YXIgb3BlcmF0aW9uID0gcGF0aE9ialttZXRob2RdO1xuXG4gICAgICBpZiAoXy5pc1VuZGVmaW5lZChvcGVyYXRpb24pKSB7XG4gICAgICAgIC8vIE9wZXJhdGlvbiBkb2VzIG5vdCBleGlzdFxuICAgICAgICByZXR1cm47XG4gICAgICB9IGVsc2UgaWYgKCFfLmlzUGxhaW5PYmplY3Qob3BlcmF0aW9uKSkge1xuICAgICAgICAvLyBPcGVyYXRpb24gZXhpc3RzIGJ1dCBpdCBpcyBub3QgYW4gT3BlcmF0aW9uIE9iamVjdC4gIFNpbmNlIHRoaXMgaXMgaW52YWxpZCwgbG9nIGl0LlxuICAgICAgICBoZWxwZXJzLmxvZygnVGhlIFxcJycgKyBtZXRob2QgKyAnXFwnIG9wZXJhdGlvbiBmb3IgXFwnJyArIHBhdGggKyAnXFwnIHBhdGggaXMgbm90IGFuIE9wZXJhdGlvbiBPYmplY3QnKTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciB0YWdzID0gb3BlcmF0aW9uLnRhZ3M7XG5cbiAgICAgIGlmIChfLmlzVW5kZWZpbmVkKHRhZ3MpIHx8ICFfLmlzQXJyYXkodGFncykgfHwgdGFncy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGFncyA9IG9wZXJhdGlvbi50YWdzID0gWyAnZGVmYXVsdCcgXTtcbiAgICAgIH1cblxuICAgICAgdmFyIG9wZXJhdGlvbklkID0gc2VsZi5pZEZyb21PcChwYXRoLCBtZXRob2QsIG9wZXJhdGlvbik7XG5cbiAgICAgIHZhciBvcGVyYXRpb25PYmplY3QgPSBuZXcgT3BlcmF0aW9uKHNlbGYsXG4gICAgICAgIG9wZXJhdGlvbi5zY2hlbWUsXG4gICAgICAgIG9wZXJhdGlvbklkLFxuICAgICAgICBtZXRob2QsXG4gICAgICAgIHBhdGgsXG4gICAgICAgIG9wZXJhdGlvbixcbiAgICAgICAgc2VsZi5kZWZpbml0aW9ucyxcbiAgICAgICAgc2VsZi5tb2RlbHMsXG4gICAgICAgIHNlbGYuY2xpZW50QXV0aG9yaXphdGlvbnMpO1xuXG4gICAgICAvLyBiaW5kIHNlbGYgb3BlcmF0aW9uJ3MgZXhlY3V0ZSBjb21tYW5kIHRvIHRoZSBhcGlcbiAgICAgIF8uZm9yRWFjaCh0YWdzLCBmdW5jdGlvbiAodGFnKSB7XG4gICAgICAgIHZhciBjbGllbnRQcm9wZXJ0eSA9IF8uaW5kZXhPZihyZXNlcnZlZENsaWVudFRhZ3MsIHRhZykgPiAtMSA/ICdfJyArIHRhZyA6IHRhZztcbiAgICAgICAgdmFyIGFwaVByb3BlcnR5ID0gXy5pbmRleE9mKHJlc2VydmVkQXBpVGFncywgdGFnKSA+IC0xID8gJ18nICsgdGFnIDogdGFnO1xuICAgICAgICB2YXIgb3BlcmF0aW9uR3JvdXAgPSBzZWxmW2NsaWVudFByb3BlcnR5XTtcblxuICAgICAgICBpZiAoY2xpZW50UHJvcGVydHkgIT09IHRhZykge1xuICAgICAgICAgIGhlbHBlcnMubG9nKCdUaGUgXFwnJyArIHRhZyArICdcXCcgdGFnIGNvbmZsaWN0cyB3aXRoIGEgU3dhZ2dlckNsaWVudCBmdW5jdGlvbi9wcm9wZXJ0eSBuYW1lLiAgVXNlIFxcJ2NsaWVudC4nICtcbiAgICAgICAgICAgICAgICAgICAgICBjbGllbnRQcm9wZXJ0eSArICdcXCcgb3IgXFwnY2xpZW50LmFwaXMuJyArIHRhZyArICdcXCcgaW5zdGVhZCBvZiBcXCdjbGllbnQuJyArIHRhZyArICdcXCcuJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYXBpUHJvcGVydHkgIT09IHRhZykge1xuICAgICAgICAgIGhlbHBlcnMubG9nKCdUaGUgXFwnJyArIHRhZyArICdcXCcgdGFnIGNvbmZsaWN0cyB3aXRoIGEgU3dhZ2dlckNsaWVudCBvcGVyYXRpb24gZnVuY3Rpb24vcHJvcGVydHkgbmFtZS4gIFVzZSAnICtcbiAgICAgICAgICAgICAgICAgICAgICAnXFwnY2xpZW50LmFwaXMuJyArIGFwaVByb3BlcnR5ICsgJ1xcJyBpbnN0ZWFkIG9mIFxcJ2NsaWVudC5hcGlzLicgKyB0YWcgKyAnXFwnLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKF8uaW5kZXhPZihyZXNlcnZlZEFwaVRhZ3MsIG9wZXJhdGlvbklkKSA+IC0xKSB7XG4gICAgICAgICAgaGVscGVycy5sb2coJ1RoZSBcXCcnICsgb3BlcmF0aW9uSWQgKyAnXFwnIG9wZXJhdGlvbklkIGNvbmZsaWN0cyB3aXRoIGEgU3dhZ2dlckNsaWVudCBvcGVyYXRpb24gJyArXG4gICAgICAgICAgICAgICAgICAgICAgJ2Z1bmN0aW9uL3Byb3BlcnR5IG5hbWUuICBVc2UgXFwnY2xpZW50LmFwaXMuJyArIGFwaVByb3BlcnR5ICsgJy5fJyArIG9wZXJhdGlvbklkICtcbiAgICAgICAgICAgICAgICAgICAgICAnXFwnIGluc3RlYWQgb2YgXFwnY2xpZW50LmFwaXMuJyArIGFwaVByb3BlcnR5ICsgJy4nICsgb3BlcmF0aW9uSWQgKyAnXFwnLicpO1xuXG4gICAgICAgICAgb3BlcmF0aW9uSWQgPSAnXycgKyBvcGVyYXRpb25JZDtcbiAgICAgICAgICBvcGVyYXRpb25PYmplY3Qubmlja25hbWUgPSBvcGVyYXRpb25JZDsgLy8gU28gJ2NsaWVudC5hcGlzLlt0YWddLm9wZXJhdGlvbklkLmhlbHAoKSB3b3JrcyBwcm9wZXJseVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKF8uaXNVbmRlZmluZWQob3BlcmF0aW9uR3JvdXApKSB7XG4gICAgICAgICAgb3BlcmF0aW9uR3JvdXAgPSBzZWxmW2NsaWVudFByb3BlcnR5XSA9IHNlbGYuYXBpc1thcGlQcm9wZXJ0eV0gPSB7fTtcblxuICAgICAgICAgIG9wZXJhdGlvbkdyb3VwLm9wZXJhdGlvbnMgPSB7fTtcbiAgICAgICAgICBvcGVyYXRpb25Hcm91cC5sYWJlbCA9IGFwaVByb3BlcnR5O1xuICAgICAgICAgIG9wZXJhdGlvbkdyb3VwLmFwaXMgPSB7fTtcblxuICAgICAgICAgIHZhciB0YWdEZWYgPSBkZWZpbmVkVGFnc1t0YWddO1xuXG4gICAgICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKHRhZ0RlZikpIHtcbiAgICAgICAgICAgIG9wZXJhdGlvbkdyb3VwLmRlc2NyaXB0aW9uID0gdGFnRGVmLmRlc2NyaXB0aW9uO1xuICAgICAgICAgICAgb3BlcmF0aW9uR3JvdXAuZXh0ZXJuYWxEb2NzID0gdGFnRGVmLmV4dGVybmFsRG9jcztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBzZWxmW2NsaWVudFByb3BlcnR5XS5oZWxwID0gXy5iaW5kKHNlbGYuaGVscCwgb3BlcmF0aW9uR3JvdXApO1xuICAgICAgICAgIHNlbGYuYXBpc0FycmF5LnB1c2gobmV3IE9wZXJhdGlvbkdyb3VwKHRhZywgb3BlcmF0aW9uR3JvdXAuZGVzY3JpcHRpb24sIG9wZXJhdGlvbkdyb3VwLmV4dGVybmFsRG9jcywgb3BlcmF0aW9uT2JqZWN0KSk7XG4gICAgICAgIH1cblxuICAgICAgICBvcGVyYXRpb25JZCA9IHNlbGYubWFrZVVuaXF1ZU9wZXJhdGlvbklkKG9wZXJhdGlvbklkLCBzZWxmLmFwaXNbYXBpUHJvcGVydHldKTtcblxuICAgICAgICAvLyBCaW5kIHRhZyBoZWxwXG4gICAgICAgIGlmICghXy5pc0Z1bmN0aW9uKG9wZXJhdGlvbkdyb3VwLmhlbHApKSB7XG4gICAgICAgICAgb3BlcmF0aW9uR3JvdXAuaGVscCA9IF8uYmluZChzZWxmLmhlbHAsIG9wZXJhdGlvbkdyb3VwKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGJpbmQgdG8gdGhlIGFwaXMgb2JqZWN0XG4gICAgICAgIHNlbGYuYXBpc1thcGlQcm9wZXJ0eV1bb3BlcmF0aW9uSWRdID0gb3BlcmF0aW9uR3JvdXBbb3BlcmF0aW9uSWRdID0gXy5iaW5kKG9wZXJhdGlvbk9iamVjdC5leGVjdXRlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbk9iamVjdCk7XG4gICAgICAgIHNlbGYuYXBpc1thcGlQcm9wZXJ0eV1bb3BlcmF0aW9uSWRdLmhlbHAgPSBvcGVyYXRpb25Hcm91cFtvcGVyYXRpb25JZF0uaGVscCA9IF8uYmluZChvcGVyYXRpb25PYmplY3QuaGVscCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbk9iamVjdCk7XG4gICAgICAgIHNlbGYuYXBpc1thcGlQcm9wZXJ0eV1bb3BlcmF0aW9uSWRdLmFzQ3VybCA9IG9wZXJhdGlvbkdyb3VwW29wZXJhdGlvbklkXS5hc0N1cmwgPSBfLmJpbmQob3BlcmF0aW9uT2JqZWN0LmFzQ3VybCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRpb25PYmplY3QpO1xuXG4gICAgICAgIG9wZXJhdGlvbkdyb3VwLmFwaXNbb3BlcmF0aW9uSWRdID0gb3BlcmF0aW9uR3JvdXAub3BlcmF0aW9uc1tvcGVyYXRpb25JZF0gPSBvcGVyYXRpb25PYmplY3Q7XG5cbiAgICAgICAgLy8gbGVnYWN5IFVJIGZlYXR1cmVcbiAgICAgICAgdmFyIGFwaSA9IF8uZmluZChzZWxmLmFwaXNBcnJheSwgZnVuY3Rpb24gKGFwaSkge1xuICAgICAgICAgIHJldHVybiBhcGkudGFnID09PSB0YWc7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChhcGkpIHtcbiAgICAgICAgICBhcGkub3BlcmF0aW9uc0FycmF5LnB1c2gob3BlcmF0aW9uT2JqZWN0KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vIHNvcnQgdGhlIGFwaXNBcnJheSBhY2NvcmRpbmcgdG8gdGhlIHRhZ3NcbiAgdmFyIHNvcnRlZEFwaXMgPSBbXTtcbiAgXy5mb3JFYWNoKE9iamVjdC5rZXlzKGRlZmluZWRUYWdzKSwgZnVuY3Rpb24gKHRhZykge1xuICAgIHZhciBfYXBpVG9BZGQ7XG4gICAgdmFyIHBvcztcbiAgICBmb3IocG9zIGluIHNlbGYuYXBpc0FycmF5KSB7XG4gICAgICB2YXIgX2FwaSA9IHNlbGYuYXBpc0FycmF5W3Bvc107XG4gICAgICBpZihfYXBpICYmIHRhZyA9PT0gX2FwaS5uYW1lKSB7XG4gICAgICAgIHNvcnRlZEFwaXMucHVzaChfYXBpKTtcbiAgICAgICAgc2VsZi5hcGlzQXJyYXlbcG9zXSA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgLy8gYWRkIGFueXRoaW5nIGxlZnRcbiAgXy5mb3JFYWNoKHNlbGYuYXBpc0FycmF5LCBmdW5jdGlvbiAoYXBpKSB7XG4gICAgaWYoYXBpKSB7XG4gICAgICBzb3J0ZWRBcGlzLnB1c2goYXBpKTtcbiAgICB9XG4gIH0pO1xuICBzZWxmLmFwaXNBcnJheSA9IHNvcnRlZEFwaXM7XG5cbiAgXy5mb3JFYWNoKHJlc3BvbnNlLmRlZmluaXRpb25zLCBmdW5jdGlvbiAoZGVmaW5pdGlvbk9iaiwgZGVmaW5pdGlvbikge1xuICAgIGRlZmluaXRpb25PYmpbJ2lkJ10gPSBkZWZpbml0aW9uLnRvTG93ZXJDYXNlKCk7XG4gICAgZGVmaW5pdGlvbk9ialsnbmFtZSddID0gZGVmaW5pdGlvbjtcbiAgICBzZWxmLm1vZGVsc0FycmF5LnB1c2goZGVmaW5pdGlvbk9iaik7XG4gIH0pO1xuXG4gIHRoaXMuaXNCdWlsdCA9IHRydWU7XG5cbiAgaWYgKHRoaXMudXNlUHJvbWlzZSkge1xuICAgIHRoaXMuaXNWYWxpZCA9IHRydWU7XG4gICAgdGhpcy5pc0J1aWx0ID0gdHJ1ZTtcbiAgICB0aGlzLmRlZmVycmVkQ2xpZW50LnJlc29sdmUodGhpcyk7XG5cbiAgICByZXR1cm4gdGhpcy5kZWZlcnJlZENsaWVudC5wcm9taXNlO1xuICB9XG5cbiAgaWYgKHRoaXMuc3VjY2Vzcykge1xuICAgIHRoaXMuc3VjY2VzcygpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5tYWtlVW5pcXVlT3BlcmF0aW9uSWQgPSBmdW5jdGlvbihvcGVyYXRpb25JZCwgYXBpKSB7XG4gIHZhciBjb3VudCA9IDA7XG4gIHZhciBuYW1lID0gb3BlcmF0aW9uSWQ7XG5cbiAgLy8gbWFrZSB1bmlxdWUgYWNyb3NzIHRoaXMgb3BlcmF0aW9uIGdyb3VwXG4gIHdoaWxlKHRydWUpIHtcbiAgICB2YXIgbWF0Y2hlZCA9IGZhbHNlO1xuICAgIF8uZm9yRWFjaChhcGkub3BlcmF0aW9ucywgZnVuY3Rpb24gKG9wZXJhdGlvbikge1xuICAgICAgaWYob3BlcmF0aW9uLm5pY2tuYW1lID09PSBuYW1lKSB7XG4gICAgICAgIG1hdGNoZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGlmKCFtYXRjaGVkKSB7XG4gICAgICByZXR1cm4gbmFtZTtcbiAgICB9XG4gICAgbmFtZSA9IG9wZXJhdGlvbklkICsgJ18nICsgY291bnQ7XG4gICAgY291bnQgKys7XG4gIH1cblxuICByZXR1cm4gb3BlcmF0aW9uSWQ7XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5wYXJzZVVyaSA9IGZ1bmN0aW9uICh1cmkpIHtcbiAgdmFyIHVybFBhcnNlUkUgPSAvXigoKChbXjpcXC8jXFw/XSs6KT8oPzooXFwvXFwvKSgoPzooKFteOkBcXC8jXFw/XSspKD86XFw6KFteOkBcXC8jXFw/XSspKT8pQCk/KChbXjpcXC8jXFw/XFxdXFxbXSt8XFxbW15cXC9cXF1AIz9dK1xcXSkoPzpcXDooWzAtOV0rKSk/KSk/KT8pPygoXFwvPyg/OlteXFwvXFw/I10rXFwvKykqKShbXlxcPyNdKikpKT8oXFw/W14jXSspPykoIy4qKT8vO1xuICB2YXIgcGFydHMgPSB1cmxQYXJzZVJFLmV4ZWModXJpKTtcblxuICByZXR1cm4ge1xuICAgIHNjaGVtZTogcGFydHNbNF0gPyBwYXJ0c1s0XS5yZXBsYWNlKCc6JywnJykgOiB1bmRlZmluZWQsXG4gICAgaG9zdDogcGFydHNbMTFdLFxuICAgIHBvcnQ6IHBhcnRzWzEyXSxcbiAgICBwYXRoOiBwYXJ0c1sxNV1cbiAgfTtcbn07XG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLmhlbHAgPSBmdW5jdGlvbiAoZG9udFByaW50KSB7XG4gIHZhciBvdXRwdXQgPSAnJztcblxuICBpZiAodGhpcyBpbnN0YW5jZW9mIFN3YWdnZXJDbGllbnQpIHtcbiAgICBfLmZvckVhY2godGhpcy5hcGlzLCBmdW5jdGlvbiAoYXBpLCBuYW1lKSB7XG4gICAgICBpZiAoXy5pc1BsYWluT2JqZWN0KGFwaSkpIHtcbiAgICAgICAgb3V0cHV0ICs9ICdvcGVyYXRpb25zIGZvciB0aGUgXFwnJyArIG5hbWUgKyAnXFwnIHRhZ1xcbic7XG5cbiAgICAgICAgXy5mb3JFYWNoKGFwaS5vcGVyYXRpb25zLCBmdW5jdGlvbiAob3BlcmF0aW9uLCBuYW1lKSB7XG4gICAgICAgICAgb3V0cHV0ICs9ICcgICogJyArIG5hbWUgKyAnOiAnICsgb3BlcmF0aW9uLnN1bW1hcnkgKyAnXFxuJztcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0gZWxzZSBpZiAodGhpcyBpbnN0YW5jZW9mIE9wZXJhdGlvbkdyb3VwIHx8IF8uaXNQbGFpbk9iamVjdCh0aGlzKSkge1xuICAgIG91dHB1dCArPSAnb3BlcmF0aW9ucyBmb3IgdGhlIFxcJycgKyB0aGlzLmxhYmVsICsgJ1xcJyB0YWdcXG4nO1xuXG4gICAgXy5mb3JFYWNoKHRoaXMuYXBpcywgZnVuY3Rpb24gKG9wZXJhdGlvbiwgbmFtZSkge1xuICAgICAgb3V0cHV0ICs9ICcgICogJyArIG5hbWUgKyAnOiAnICsgb3BlcmF0aW9uLnN1bW1hcnkgKyAnXFxuJztcbiAgICB9KTtcbiAgfVxuXG4gIGlmIChkb250UHJpbnQpIHtcbiAgICByZXR1cm4gb3V0cHV0O1xuICB9IGVsc2Uge1xuICAgIGhlbHBlcnMubG9nKG91dHB1dCk7XG5cbiAgICByZXR1cm4gb3V0cHV0O1xuICB9XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS50YWdGcm9tTGFiZWwgPSBmdW5jdGlvbiAobGFiZWwpIHtcbiAgcmV0dXJuIGxhYmVsO1xufTtcblxuU3dhZ2dlckNsaWVudC5wcm90b3R5cGUuaWRGcm9tT3AgPSBmdW5jdGlvbiAocGF0aCwgaHR0cE1ldGhvZCwgb3ApIHtcbiAgaWYoIW9wIHx8ICFvcC5vcGVyYXRpb25JZCkge1xuICAgIG9wID0gb3AgfHwge307XG4gICAgb3Aub3BlcmF0aW9uSWQgPSBodHRwTWV0aG9kICsgJ18nICsgcGF0aDtcbiAgfVxuICB2YXIgb3BJZCA9IG9wLm9wZXJhdGlvbklkLnJlcGxhY2UoL1tcXHMhQCMkJV4mKigpXys9XFxbe1xcXX07Ojw+fC5cXC8/LFxcXFwnXCJcIi1dL2csICdfJykgfHwgKHBhdGguc3Vic3RyaW5nKDEpICsgJ18nICsgaHR0cE1ldGhvZCk7XG5cbiAgb3BJZCA9IG9wSWQucmVwbGFjZSgvKChfKXsyLH0pL2csICdfJyk7XG4gIG9wSWQgPSBvcElkLnJlcGxhY2UoL14oXykqL2csICcnKTtcbiAgb3BJZCA9IG9wSWQucmVwbGFjZSgvKFtfXSkqJC9nLCAnJyk7XG5cbiAgcmV0dXJuIG9wSWQ7XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5zZXRIb3N0ID0gZnVuY3Rpb24gKGhvc3QpIHtcbiAgdGhpcy5ob3N0ID0gaG9zdDtcblxuICBpZih0aGlzLmFwaXMpIHtcbiAgICBfLmZvckVhY2godGhpcy5hcGlzLCBmdW5jdGlvbihhcGkpIHtcbiAgICAgIGlmKGFwaS5vcGVyYXRpb25zKSB7XG4gICAgICAgIF8uZm9yRWFjaChhcGkub3BlcmF0aW9ucywgZnVuY3Rpb24ob3BlcmF0aW9uKSB7XG4gICAgICAgICAgb3BlcmF0aW9uLmhvc3QgPSBob3N0O1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufTtcblxuU3dhZ2dlckNsaWVudC5wcm90b3R5cGUuc2V0QmFzZVBhdGggPSBmdW5jdGlvbiAoYmFzZVBhdGgpIHtcbiAgdGhpcy5iYXNlUGF0aCA9IGJhc2VQYXRoO1xuXG4gIGlmKHRoaXMuYXBpcykge1xuICAgIF8uZm9yRWFjaCh0aGlzLmFwaXMsIGZ1bmN0aW9uKGFwaSkge1xuICAgICAgaWYoYXBpLm9wZXJhdGlvbnMpIHtcbiAgICAgICAgXy5mb3JFYWNoKGFwaS5vcGVyYXRpb25zLCBmdW5jdGlvbihvcGVyYXRpb24pIHtcbiAgICAgICAgICBvcGVyYXRpb24uYmFzZVBhdGggPSBiYXNlUGF0aDtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn07XG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLnNldFNjaGVtZXMgPSBmdW5jdGlvbiAoc2NoZW1lcykge1xuICB0aGlzLnNjaGVtZXMgPSBzY2hlbWVzO1xuXG4gIGlmKHNjaGVtZXMgJiYgc2NoZW1lcy5sZW5ndGggPiAwKSB7XG4gICAgaWYodGhpcy5hcGlzKSB7XG4gICAgICBfLmZvckVhY2godGhpcy5hcGlzLCBmdW5jdGlvbiAoYXBpKSB7XG4gICAgICAgIGlmIChhcGkub3BlcmF0aW9ucykge1xuICAgICAgICAgIF8uZm9yRWFjaChhcGkub3BlcmF0aW9ucywgZnVuY3Rpb24gKG9wZXJhdGlvbikge1xuICAgICAgICAgICAgb3BlcmF0aW9uLnNjaGVtZSA9IHNjaGVtZXNbMF07XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufTtcblxuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5mYWlsID0gZnVuY3Rpb24gKG1lc3NhZ2UpIHtcbiAgaWYgKHRoaXMudXNlUHJvbWlzZSkge1xuICAgIHRoaXMuZGVmZXJyZWRDbGllbnQucmVqZWN0KG1lc3NhZ2UpO1xuICAgIHJldHVybiB0aGlzLmRlZmVycmVkQ2xpZW50LnByb21pc2U7XG4gIH0gZWxzZSB7XG4gICAgaWYgKHRoaXMuZmFpbHVyZSkge1xuICAgICAgdGhpcy5mYWlsdXJlKG1lc3NhZ2UpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHRoaXMuZmFpbHVyZShtZXNzYWdlKTtcbiAgICB9XG4gIH1cbn07XG4iLCIoZnVuY3Rpb24gKHByb2Nlc3Mpe1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgXyA9IHtcbiAgaXNQbGFpbk9iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzUGxhaW5PYmplY3QnKSxcbiAgaW5kZXhPZjogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9hcnJheS9pbmRleE9mJylcbn07XG5cbm1vZHVsZS5leHBvcnRzLl9fYmluZCA9IGZ1bmN0aW9uIChmbiwgbWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCl7XG4gICAgcmV0dXJuIGZuLmFwcGx5KG1lLCBhcmd1bWVudHMpO1xuICB9O1xufTtcblxudmFyIGxvZyA9IG1vZHVsZS5leHBvcnRzLmxvZyA9IGZ1bmN0aW9uKCkge1xuICAvLyBPbmx5IGxvZyBpZiBhdmFpbGFibGUgYW5kIHdlJ3JlIG5vdCB0ZXN0aW5nXG4gIGlmIChjb25zb2xlICYmIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAndGVzdCcpIHtcbiAgICBjb25zb2xlLmxvZyhBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpWzBdKTtcbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMuZmFpbCA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gIGxvZyhtZXNzYWdlKTtcbn07XG5cbnZhciBvcHRpb25IdG1sID0gbW9kdWxlLmV4cG9ydHMub3B0aW9uSHRtbCA9IGZ1bmN0aW9uIChsYWJlbCwgdmFsdWUpIHtcbiAgcmV0dXJuICc8dHI+PHRkIGNsYXNzPVwib3B0aW9uTmFtZVwiPicgKyBsYWJlbCArICc6PC90ZD48dGQ+JyArIHZhbHVlICsgJzwvdGQ+PC90cj4nO1xufTtcblxudmFyIHJlc29sdmVTY2hlbWEgPSBtb2R1bGUuZXhwb3J0cy5yZXNvbHZlU2NoZW1hID0gZnVuY3Rpb24gKHNjaGVtYSkge1xuICBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5zY2hlbWEpKSB7XG4gICAgc2NoZW1hID0gcmVzb2x2ZVNjaGVtYShzY2hlbWEuc2NoZW1hKTtcbiAgfVxuXG4gIHJldHVybiBzY2hlbWE7XG59O1xuXG52YXIgc2ltcGxlUmVmID0gbW9kdWxlLmV4cG9ydHMuc2ltcGxlUmVmID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgaWYgKHR5cGVvZiBuYW1lID09PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKG5hbWUuaW5kZXhPZignIy9kZWZpbml0aW9ucy8nKSA9PT0gMCkge1xuICAgIHJldHVybiBuYW1lLnN1YnN0cmluZygnIy9kZWZpbml0aW9ucy8nLmxlbmd0aCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG5hbWU7XG4gIH1cbn07XG5cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoJ19wcm9jZXNzJykpXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbXhwWWk5b1pXeHdaWEp6TG1weklsMHNJbTVoYldWeklqcGJYU3dpYldGd2NHbHVaM01pT2lJN1FVRkJRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFTSXNJbVpwYkdVaU9pSm5aVzVsY21GMFpXUXVhbk1pTENKemIzVnlZMlZTYjI5MElqb2lJaXdpYzI5MWNtTmxjME52Ym5SbGJuUWlPbHNpSjNWelpTQnpkSEpwWTNRbk8xeHVYRzUyWVhJZ1h5QTlJSHRjYmlBZ2FYTlFiR0ZwYms5aWFtVmpkRG9nY21WeGRXbHlaU2duYkc5a1lYTm9MV052YlhCaGRDOXNZVzVuTDJselVHeGhhVzVQWW1wbFkzUW5LU3hjYmlBZ2FXNWtaWGhQWmpvZ2NtVnhkV2x5WlNnbmJHOWtZWE5vTFdOdmJYQmhkQzloY25KaGVTOXBibVJsZUU5bUp5bGNibjA3WEc1Y2JtMXZaSFZzWlM1bGVIQnZjblJ6TGw5ZlltbHVaQ0E5SUdaMWJtTjBhVzl1SUNobWJpd2diV1VwSUh0Y2JpQWdjbVYwZFhKdUlHWjFibU4wYVc5dUtDbDdYRzRnSUNBZ2NtVjBkWEp1SUdadUxtRndjR3g1S0cxbExDQmhjbWQxYldWdWRITXBPMXh1SUNCOU8xeHVmVHRjYmx4dWRtRnlJR3h2WnlBOUlHMXZaSFZzWlM1bGVIQnZjblJ6TG14dlp5QTlJR1oxYm1OMGFXOXVLQ2tnZTF4dUlDQXZMeUJQYm14NUlHeHZaeUJwWmlCaGRtRnBiR0ZpYkdVZ1lXNWtJSGRsSjNKbElHNXZkQ0IwWlhOMGFXNW5YRzRnSUdsbUlDaGpiMjV6YjJ4bElDWW1JSEJ5YjJObGMzTXVaVzUyTGs1UFJFVmZSVTVXSUNFOVBTQW5kR1Z6ZENjcElIdGNiaUFnSUNCamIyNXpiMnhsTG14dlp5aEJjbkpoZVM1d2NtOTBiM1I1Y0dVdWMyeHBZMlV1WTJGc2JDaGhjbWQxYldWdWRITXBXekJkS1R0Y2JpQWdmVnh1ZlR0Y2JseHViVzlrZFd4bExtVjRjRzl5ZEhNdVptRnBiQ0E5SUdaMWJtTjBhVzl1SUNodFpYTnpZV2RsS1NCN1hHNGdJR3h2WnlodFpYTnpZV2RsS1R0Y2JuMDdYRzVjYm5aaGNpQnZjSFJwYjI1SWRHMXNJRDBnYlc5a2RXeGxMbVY0Y0c5eWRITXViM0IwYVc5dVNIUnRiQ0E5SUdaMWJtTjBhVzl1SUNoc1lXSmxiQ3dnZG1Gc2RXVXBJSHRjYmlBZ2NtVjBkWEp1SUNjOGRISStQSFJrSUdOc1lYTnpQVndpYjNCMGFXOXVUbUZ0WlZ3aVBpY2dLeUJzWVdKbGJDQXJJQ2M2UEM5MFpENDhkR1ErSnlBcklIWmhiSFZsSUNzZ0p6d3ZkR1ErUEM5MGNqNG5PMXh1ZlR0Y2JseHVkbUZ5SUhKbGMyOXNkbVZUWTJobGJXRWdQU0J0YjJSMWJHVXVaWGh3YjNKMGN5NXlaWE52YkhabFUyTm9aVzFoSUQwZ1puVnVZM1JwYjI0Z0tITmphR1Z0WVNrZ2UxeHVJQ0JwWmlBb1h5NXBjMUJzWVdsdVQySnFaV04wS0hOamFHVnRZUzV6WTJobGJXRXBLU0I3WEc0Z0lDQWdjMk5vWlcxaElEMGdjbVZ6YjJ4MlpWTmphR1Z0WVNoelkyaGxiV0V1YzJOb1pXMWhLVHRjYmlBZ2ZWeHVYRzRnSUhKbGRIVnliaUJ6WTJobGJXRTdYRzU5TzF4dVhHNTJZWElnYzJsdGNHeGxVbVZtSUQwZ2JXOWtkV3hsTG1WNGNHOXlkSE11YzJsdGNHeGxVbVZtSUQwZ1puVnVZM1JwYjI0Z0tHNWhiV1VwSUh0Y2JpQWdhV1lnS0hSNWNHVnZaaUJ1WVcxbElEMDlQU0FuZFc1a1pXWnBibVZrSnlrZ2UxeHVJQ0FnSUhKbGRIVnliaUJ1ZFd4c08xeHVJQ0I5WEc1Y2JpQWdhV1lnS0c1aGJXVXVhVzVrWlhoUFppZ25JeTlrWldacGJtbDBhVzl1Y3k4bktTQTlQVDBnTUNrZ2UxeHVJQ0FnSUhKbGRIVnliaUJ1WVcxbExuTjFZbk4wY21sdVp5Z25JeTlrWldacGJtbDBhVzl1Y3k4bkxteGxibWQwYUNrN1hHNGdJSDBnWld4elpTQjdYRzRnSUNBZ2NtVjBkWEp1SUc1aGJXVTdYRzRnSUgxY2JuMDdYRzVjYmlKZGZRPT0iLCIndXNlIHN0cmljdCc7XG5cbnZhciBoZWxwZXJzID0gcmVxdWlyZSgnLi9oZWxwZXJzJyk7XG52YXIgcmVxdWVzdCA9IHJlcXVpcmUoJ3N1cGVyYWdlbnQnKTtcbnZhciBqc3lhbWwgPSByZXF1aXJlKCdqcy15YW1sJyk7XG52YXIgXyA9IHtcbiAgaXNPYmplY3Q6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc09iamVjdCcpXG59O1xuXG4vKlxuICogSlF1ZXJ5SHR0cENsaWVudCBpcyBhIGxpZ2h0LXdlaWdodCwgbm9kZSBvciBicm93c2VyIEhUVFAgY2xpZW50XG4gKi9cbnZhciBKUXVlcnlIdHRwQ2xpZW50ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLnR5cGUgPSAnSlF1ZXJ5SHR0cENsaWVudCc7XG59O1xuXG4vKlxuICogU3VwZXJhZ2VudEh0dHBDbGllbnQgaXMgYSBsaWdodC13ZWlnaHQsIG5vZGUgb3IgYnJvd3NlciBIVFRQIGNsaWVudFxuICovXG52YXIgU3VwZXJhZ2VudEh0dHBDbGllbnQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMudHlwZSA9ICdTdXBlcmFnZW50SHR0cENsaWVudCc7XG59O1xuXG4vKipcbiAqIFN3YWdnZXJIdHRwIGlzIGEgd3JhcHBlciBmb3IgZXhlY3V0aW5nIHJlcXVlc3RzXG4gKi9cbnZhciBTd2FnZ2VySHR0cCA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge307XG5cblN3YWdnZXJIdHRwLnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24gKG9iaiwgb3B0cykge1xuICB2YXIgY2xpZW50O1xuXG4gIGlmKG9wdHMgJiYgb3B0cy5jbGllbnQpIHtcbiAgICBjbGllbnQgPSBvcHRzLmNsaWVudDtcbiAgfVxuICBlbHNlIHtcbiAgICBjbGllbnQgPSBuZXcgU3VwZXJhZ2VudEh0dHBDbGllbnQob3B0cyk7XG4gIH1cbiAgY2xpZW50Lm9wdHMgPSBvcHRzIHx8IHt9O1xuXG4gIC8vIGxlZ2FjeSBzdXBwb3J0XG4gIHZhciBoYXNKUXVlcnkgPSBmYWxzZTtcbiAgaWYodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBpZih0eXBlb2Ygd2luZG93LmpRdWVyeSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGhhc0pRdWVyeSA9IHRydWU7XG4gICAgfVxuICB9XG4gIC8vIE9QVElPTlMgc3VwcG9ydFxuICBpZihvYmoubWV0aG9kLnRvTG93ZXJDYXNlKCkgPT09ICdvcHRpb25zJyAmJiBjbGllbnQudHlwZSA9PT0gJ1N1cGVyYWdlbnRIdHRwQ2xpZW50Jykge1xuICAgIGxvZygnZm9yY2luZyBqUXVlcnkgYXMgT1BUSU9OUyBhcmUgbm90IHN1cHBvcnRlZCBieSBTdXBlckFnZW50Jyk7XG4gICAgb2JqLnVzZUpRdWVyeSA9IHRydWU7XG4gIH1cbiAgaWYodGhpcy5pc0ludGVybmV0RXhwbG9yZXIoKSAmJiAob2JqLnVzZUpRdWVyeSA9PT0gZmFsc2UgfHwgIWhhc0pRdWVyeSApKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBjb25maWd1cmF0aW9uISBKUXVlcnkgaXMgcmVxdWlyZWQgYnV0IG5vdCBhdmFpbGFibGUnKTtcbiAgfVxuICBpZiAoKG9iaiAmJiBvYmoudXNlSlF1ZXJ5ID09PSB0cnVlKSB8fCB0aGlzLmlzSW50ZXJuZXRFeHBsb3JlcigpICYmIGhhc0pRdWVyeSkge1xuICAgIGNsaWVudCA9IG5ldyBKUXVlcnlIdHRwQ2xpZW50KG9wdHMpO1xuICB9XG5cbiAgdmFyIHN1Y2Nlc3MgPSBvYmoub24ucmVzcG9uc2U7XG5cbiAgdmFyIHJlcXVlc3RJbnRlcmNlcHRvciA9IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICBpZihvcHRzICYmIG9wdHMucmVxdWVzdEludGVyY2VwdG9yKSB7XG4gICAgICBkYXRhID0gb3B0cy5yZXF1ZXN0SW50ZXJjZXB0b3IuYXBwbHkoZGF0YSk7XG4gICAgfVxuICAgIHJldHVybiBkYXRhO1xuICB9O1xuXG4gIHZhciByZXNwb25zZUludGVyY2VwdG9yID0gZnVuY3Rpb24oZGF0YSkge1xuICAgIGlmKG9wdHMgJiYgb3B0cy5yZXNwb25zZUludGVyY2VwdG9yKSB7XG4gICAgICBkYXRhID0gb3B0cy5yZXNwb25zZUludGVyY2VwdG9yLmFwcGx5KGRhdGEpO1xuICAgIH1cbiAgICByZXR1cm4gc3VjY2VzcyhkYXRhKTtcbiAgfTtcblxuICBvYmoub24ucmVzcG9uc2UgPSBmdW5jdGlvbihkYXRhKSB7XG4gICAgcmVzcG9uc2VJbnRlcmNlcHRvcihkYXRhKTtcbiAgfTtcblxuICBpZiAoXy5pc09iamVjdChvYmopICYmIF8uaXNPYmplY3Qob2JqLmJvZHkpKSB7XG4gICAgLy8gc3BlY2lhbCBwcm9jZXNzaW5nIGZvciBmaWxlIHVwbG9hZHMgdmlhIGpxdWVyeVxuICAgIGlmIChvYmouYm9keS50eXBlICYmIG9iai5ib2R5LnR5cGUgPT09ICdmb3JtRGF0YScpe1xuICAgICAgb2JqLmNvbnRlbnRUeXBlID0gZmFsc2U7XG4gICAgICBvYmoucHJvY2Vzc0RhdGEgPSBmYWxzZTtcblxuICAgICAgZGVsZXRlIG9iai5oZWFkZXJzWydDb250ZW50LVR5cGUnXTtcbiAgICB9IGVsc2Uge1xuICAgICAgb2JqLmJvZHkgPSBKU09OLnN0cmluZ2lmeShvYmouYm9keSk7XG4gICAgfVxuICB9XG5cbiAgb2JqID0gcmVxdWVzdEludGVyY2VwdG9yKG9iaikgfHwgb2JqO1xuICBpZiAob2JqLmJlZm9yZVNlbmQpIHtcbiAgICBvYmouYmVmb3JlU2VuZChmdW5jdGlvbihfb2JqKSB7XG4gICAgICBjbGllbnQuZXhlY3V0ZShfb2JqIHx8IG9iaik7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgY2xpZW50LmV4ZWN1dGUob2JqKTtcbiAgfVxuXG4gIHJldHVybiAob2JqLmRlZmVycmVkKSA/IG9iai5kZWZlcnJlZC5wcm9taXNlIDogb2JqO1xufTtcblxuU3dhZ2dlckh0dHAucHJvdG90eXBlLmlzSW50ZXJuZXRFeHBsb3JlciA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGRldGVjdGVkSUUgPSBmYWxzZTtcblxuICBpZiAodHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcgJiYgbmF2aWdhdG9yLnVzZXJBZ2VudCkge1xuICAgIHZhciBuYXYgPSBuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCk7XG5cbiAgICBpZiAobmF2LmluZGV4T2YoJ21zaWUnKSAhPT0gLTEpIHtcbiAgICAgIHZhciB2ZXJzaW9uID0gcGFyc2VJbnQobmF2LnNwbGl0KCdtc2llJylbMV0pO1xuXG4gICAgICBpZiAodmVyc2lvbiA8PSA4KSB7XG4gICAgICAgIGRldGVjdGVkSUUgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBkZXRlY3RlZElFO1xufTtcblxuSlF1ZXJ5SHR0cENsaWVudC5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgdmFyIGpxID0gdGhpcy5qUXVlcnkgfHwgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdy5qUXVlcnkpO1xuICB2YXIgY2IgPSBvYmoub247XG4gIHZhciByZXF1ZXN0ID0gb2JqO1xuXG4gIGlmKHR5cGVvZiBqcSA9PT0gJ3VuZGVmaW5lZCcgfHwganEgPT09IGZhbHNlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBjb25maWd1cmF0aW9uISBKUXVlcnkgaXMgcmVxdWlyZWQgYnV0IG5vdCBhdmFpbGFibGUnKTtcbiAgfVxuXG4gIG9iai50eXBlID0gb2JqLm1ldGhvZDtcbiAgb2JqLmNhY2hlID0gZmFsc2U7XG4gIG9iai5kYXRhID0gb2JqLmJvZHk7XG4gIGRlbGV0ZSBvYmoudXNlSlF1ZXJ5O1xuICBkZWxldGUgb2JqLmJvZHk7XG5cbiAgb2JqLmNvbXBsZXRlID0gZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgdmFyIGhlYWRlcnMgPSB7fTtcbiAgICB2YXIgaGVhZGVyQXJyYXkgPSByZXNwb25zZS5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKS5zcGxpdCgnXFxuJyk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGhlYWRlckFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgdG9TcGxpdCA9IGhlYWRlckFycmF5W2ldLnRyaW0oKTtcblxuICAgICAgaWYgKHRvU3BsaXQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICB2YXIgc2VwYXJhdG9yID0gdG9TcGxpdC5pbmRleE9mKCc6Jyk7XG5cbiAgICAgIGlmIChzZXBhcmF0b3IgPT09IC0xKSB7XG4gICAgICAgIC8vIE5hbWUgYnV0IG5vIHZhbHVlIGluIHRoZSBoZWFkZXJcbiAgICAgICAgaGVhZGVyc1t0b1NwbGl0XSA9IG51bGw7XG5cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHZhciBuYW1lID0gdG9TcGxpdC5zdWJzdHJpbmcoMCwgc2VwYXJhdG9yKS50cmltKCk7XG4gICAgICB2YXIgdmFsdWUgPSB0b1NwbGl0LnN1YnN0cmluZyhzZXBhcmF0b3IgKyAxKS50cmltKCk7XG5cbiAgICAgIGhlYWRlcnNbbmFtZV0gPSB2YWx1ZTtcbiAgICB9XG5cbiAgICB2YXIgb3V0ID0ge1xuICAgICAgdXJsOiByZXF1ZXN0LnVybCxcbiAgICAgIG1ldGhvZDogcmVxdWVzdC5tZXRob2QsXG4gICAgICBzdGF0dXM6IHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgIHN0YXR1c1RleHQ6IHJlc3BvbnNlLnN0YXR1c1RleHQsXG4gICAgICBkYXRhOiByZXNwb25zZS5yZXNwb25zZVRleHQsXG4gICAgICBoZWFkZXJzOiBoZWFkZXJzXG4gICAgfTtcblxuICAgIHRyeSB7XG4gICAgICB2YXIgcG9zc2libGVPYmogPSAgcmVzcG9uc2UucmVzcG9uc2VKU09OIHx8IGpzeWFtbC5zYWZlTG9hZChyZXNwb25zZS5yZXNwb25zZVRleHQpO1xuICAgICAgb3V0Lm9iaiA9ICh0eXBlb2YgcG9zc2libGVPYmogPT09ICdzdHJpbmcnKSA/IHt9IDogcG9zc2libGVPYmo7XG4gICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgIC8vIGRvIG5vdCBzZXQgb3V0Lm9ialxuICAgICAgaGVscGVycy5sb2coJ3VuYWJsZSB0byBwYXJzZSBKU09OL1lBTUwgY29udGVudCcpO1xuICAgIH1cblxuICAgIC8vIEkgY2FuIHRocm93LCBvciBwYXJzZSBudWxsP1xuICAgIG91dC5vYmogPSBvdXQub2JqIHx8IG51bGw7XG5cbiAgICBpZiAocmVzcG9uc2Uuc3RhdHVzID49IDIwMCAmJiByZXNwb25zZS5zdGF0dXMgPCAzMDApIHtcbiAgICAgIGNiLnJlc3BvbnNlKG91dCk7XG4gICAgfSBlbHNlIGlmIChyZXNwb25zZS5zdGF0dXMgPT09IDAgfHwgKHJlc3BvbnNlLnN0YXR1cyA+PSA0MDAgJiYgcmVzcG9uc2Uuc3RhdHVzIDwgNTk5KSkge1xuICAgICAgY2IuZXJyb3Iob3V0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGNiLnJlc3BvbnNlKG91dCk7XG4gICAgfVxuICB9O1xuXG4gIGpxLnN1cHBvcnQuY29ycyA9IHRydWU7XG5cbiAgcmV0dXJuIGpxLmFqYXgob2JqKTtcbn07XG5cblN1cGVyYWdlbnRIdHRwQ2xpZW50LnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24gKG9iaikge1xuICB2YXIgbWV0aG9kID0gb2JqLm1ldGhvZC50b0xvd2VyQ2FzZSgpO1xuXG4gIGlmIChtZXRob2QgPT09ICdkZWxldGUnKSB7XG4gICAgbWV0aG9kID0gJ2RlbCc7XG4gIH1cbiAgdmFyIGhlYWRlcnMgPSBvYmouaGVhZGVycyB8fCB7fTtcbiAgdmFyIHIgPSByZXF1ZXN0W21ldGhvZF0ob2JqLnVybCk7XG4gIHZhciBuYW1lO1xuICBmb3IgKG5hbWUgaW4gaGVhZGVycykge1xuICAgIHIuc2V0KG5hbWUsIGhlYWRlcnNbbmFtZV0pO1xuICB9XG5cbiAgaWYgKG9iai5lbmFibGVDb29raWVzKSB7XG4gICAgci53aXRoQ3JlZGVudGlhbHMoKTtcbiAgfVxuXG4gIGlmIChvYmouYm9keSkge1xuICAgIHIuc2VuZChvYmouYm9keSk7XG4gIH1cblxuICBpZih0eXBlb2Ygci5idWZmZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICByLmJ1ZmZlcigpOyAvLyBmb3JjZSBzdXBlcmFnZW50IHRvIHBvcHVsYXRlIHJlcy50ZXh0IHdpdGggdGhlIHJhdyByZXNwb25zZSBkYXRhXG4gIH1cblxuICByLmVuZChmdW5jdGlvbiAoZXJyLCByZXMpIHtcbiAgICByZXMgPSByZXMgfHwge1xuICAgICAgc3RhdHVzOiAwLFxuICAgICAgaGVhZGVyczoge2Vycm9yOiAnbm8gcmVzcG9uc2UgZnJvbSBzZXJ2ZXInfVxuICAgIH07XG4gICAgdmFyIHJlc3BvbnNlID0ge1xuICAgICAgdXJsOiBvYmoudXJsLFxuICAgICAgbWV0aG9kOiBvYmoubWV0aG9kLFxuICAgICAgaGVhZGVyczogcmVzLmhlYWRlcnNcbiAgICB9O1xuICAgIHZhciBjYjtcblxuICAgIGlmICghZXJyICYmIHJlcy5lcnJvcikge1xuICAgICAgZXJyID0gcmVzLmVycm9yO1xuICAgIH1cblxuICAgIGlmIChlcnIgJiYgb2JqLm9uICYmIG9iai5vbi5lcnJvcikge1xuICAgICAgcmVzcG9uc2UuZXJyT2JqID0gZXJyO1xuICAgICAgcmVzcG9uc2Uuc3RhdHVzID0gcmVzID8gcmVzLnN0YXR1cyA6IDUwMDtcbiAgICAgIHJlc3BvbnNlLnN0YXR1c1RleHQgPSByZXMgPyByZXMudGV4dCA6IGVyci5tZXNzYWdlO1xuICAgICAgaWYocmVzLmhlYWRlcnMgJiYgcmVzLmhlYWRlcnNbJ2NvbnRlbnQtdHlwZSddKSB7XG4gICAgICAgIGlmKHJlcy5oZWFkZXJzWydjb250ZW50LXR5cGUnXS5pbmRleE9mKCdhcHBsaWNhdGlvbi9qc29uJykgPj0gMCkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXNwb25zZS5vYmogPSBKU09OLnBhcnNlKHJlc3BvbnNlLnN0YXR1c1RleHQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcmVzcG9uc2Uub2JqID0gbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNiID0gb2JqLm9uLmVycm9yO1xuICAgIH0gZWxzZSBpZiAocmVzICYmIG9iai5vbiAmJiBvYmoub24ucmVzcG9uc2UpIHtcbiAgICAgIHZhciBwb3NzaWJsZU9iajtcblxuICAgICAgLy8gQWxyZWFkeSBwYXJzZWQgYnkgYnkgc3VwZXJhZ2VudD9cbiAgICAgIGlmKHJlcy5ib2R5ICYmIE9iamVjdC5rZXlzKHJlcy5ib2R5KS5sZW5ndGggPiAwKSB7XG4gICAgICAgIHBvc3NpYmxlT2JqID0gcmVzLmJvZHk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBwb3NzaWJsZU9iaiA9IGpzeWFtbC5zYWZlTG9hZChyZXMudGV4dCk7XG4gICAgICAgICAgICAvLyBjYW4gcGFyc2UgaW50byBhIHN0cmluZy4uLiB3aGljaCB3ZSBkb24ndCBuZWVkIHJ1bm5pbmcgYXJvdW5kIGluIHRoZSBzeXN0ZW1cbiAgICAgICAgICAgIHBvc3NpYmxlT2JqID0gKHR5cGVvZiBwb3NzaWJsZU9iaiA9PT0gJ3N0cmluZycpID8gbnVsbCA6IHBvc3NpYmxlT2JqO1xuICAgICAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICAgICAgaGVscGVycy5sb2coJ2Nhbm5vdCBwYXJzZSBKU09OL1lBTUwgY29udGVudCcpO1xuICAgICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gbnVsbCBtZWFucyB3ZSBjYW4ndCBwYXJzZSBpbnRvIG9iamVjdFxuICAgICAgcmVzcG9uc2Uub2JqID0gKHR5cGVvZiBwb3NzaWJsZU9iaiA9PT0gJ29iamVjdCcpID8gcG9zc2libGVPYmogOiBudWxsO1xuXG4gICAgICByZXNwb25zZS5zdGF0dXMgPSByZXMuc3RhdHVzO1xuICAgICAgcmVzcG9uc2Uuc3RhdHVzVGV4dCA9IHJlcy50ZXh0O1xuICAgICAgY2IgPSBvYmoub24ucmVzcG9uc2U7XG4gICAgfVxuICAgIHJlc3BvbnNlLmRhdGEgPSByZXNwb25zZS5zdGF0dXNUZXh0O1xuXG4gICAgaWYgKGNiKSB7XG4gICAgICBjYihyZXNwb25zZSk7XG4gICAgfVxuICB9KTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBTd2FnZ2VySHR0cCA9IHJlcXVpcmUoJy4vaHR0cCcpO1xudmFyIF8gPSB7XG4gIGlzT2JqZWN0OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNPYmplY3QnKSxcbiAgY2xvbmVEZWVwOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvY2xvbmVEZWVwJyksXG4gIGlzQXJyYXk6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc0FycmF5Jylcbn07XG5cblxuLyoqXG4gKiBSZXNvbHZlcyBhIHNwZWMncyByZW1vdGUgcmVmZXJlbmNlc1xuICovXG52YXIgUmVzb2x2ZXIgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5mYWlsZWRVcmxzID0gW107XG59O1xuXG5SZXNvbHZlci5wcm90b3R5cGUucHJvY2Vzc0FsbE9mID0gZnVuY3Rpb24ocm9vdCwgbmFtZSwgZGVmaW5pdGlvbiwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgc3BlYykge1xuICB2YXIgaSwgbG9jYXRpb24sIHByb3BlcnR5O1xuXG4gIGRlZmluaXRpb25bJ3gtcmVzb2x2ZWQtZnJvbSddID0gWyAnIy9kZWZpbml0aW9ucy8nICsgbmFtZSBdO1xuICB2YXIgYWxsT2YgPSBkZWZpbml0aW9uLmFsbE9mO1xuICAvLyB0aGUgcmVmcyBnbyBmaXJzdFxuICBhbGxPZi5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcbiAgICBpZihhLiRyZWYgJiYgYi4kcmVmKSB7IHJldHVybiAwOyB9XG4gICAgZWxzZSBpZihhLiRyZWYpIHsgcmV0dXJuIC0xOyB9XG4gICAgZWxzZSB7IHJldHVybiAxOyB9XG4gIH0pO1xuICBmb3IgKGkgPSAwOyBpIDwgYWxsT2YubGVuZ3RoOyBpKyspIHtcbiAgICBwcm9wZXJ0eSA9IGFsbE9mW2ldO1xuICAgIGxvY2F0aW9uID0gJy9kZWZpbml0aW9ucy8nICsgbmFtZSArICcvYWxsT2YnO1xuICAgIHRoaXMucmVzb2x2ZUlubGluZShyb290LCBzcGVjLCBwcm9wZXJ0eSwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgbG9jYXRpb24pO1xuICB9XG59O1xuXG5SZXNvbHZlci5wcm90b3R5cGUucmVzb2x2ZSA9IGZ1bmN0aW9uIChzcGVjLCBhcmcxLCBhcmcyLCBhcmczKSB7XG4gIHRoaXMuc3BlYyA9IHNwZWM7XG4gIHZhciByb290ID0gYXJnMSwgY2FsbGJhY2sgPSBhcmcyLCBzY29wZSA9IGFyZzMsIG9wdHMgPSB7fSwgbG9jYXRpb24sIGk7XG4gIGlmKHR5cGVvZiBhcmcxID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcm9vdCA9IG51bGw7XG4gICAgY2FsbGJhY2sgPSBhcmcxO1xuICAgIHNjb3BlID0gYXJnMjtcbiAgfVxuICB2YXIgX3Jvb3QgPSByb290O1xuICB0aGlzLnNjb3BlID0gKHNjb3BlIHx8IHRoaXMpO1xuICB0aGlzLml0ZXJhdGlvbiA9IHRoaXMuaXRlcmF0aW9uIHx8IDA7XG5cbiAgaWYodGhpcy5zY29wZS5vcHRpb25zICYmIHRoaXMuc2NvcGUub3B0aW9ucy5yZXF1ZXN0SW50ZXJjZXB0b3Ipe1xuICAgIG9wdHMucmVxdWVzdEludGVyY2VwdG9yID0gdGhpcy5zY29wZS5vcHRpb25zLnJlcXVlc3RJbnRlcmNlcHRvcjtcbiAgfVxuXG4gIGlmKHRoaXMuc2NvcGUub3B0aW9ucyAmJiB0aGlzLnNjb3BlLm9wdGlvbnMucmVzcG9uc2VJbnRlcmNlcHRvcil7XG4gICAgb3B0cy5yZXNwb25zZUludGVyY2VwdG9yID0gdGhpcy5zY29wZS5vcHRpb25zLnJlc3BvbnNlSW50ZXJjZXB0b3I7XG4gIH1cblxuICB2YXIgbmFtZSwgcGF0aCwgcHJvcGVydHksIHByb3BlcnR5TmFtZTtcbiAgdmFyIHByb2Nlc3NlZENhbGxzID0gMCwgcmVzb2x2ZWRSZWZzID0ge30sIHVucmVzb2x2ZWRSZWZzID0ge307XG4gIHZhciByZXNvbHV0aW9uVGFibGUgPSBbXTsgLy8gc3RvcmUgb2JqZWN0cyBmb3IgZGVyZWZlcmVuY2luZ1xuXG4gIHNwZWMuZGVmaW5pdGlvbnMgPSBzcGVjLmRlZmluaXRpb25zIHx8IHt9O1xuICAvLyBkZWZpbml0aW9uc1xuICBmb3IgKG5hbWUgaW4gc3BlYy5kZWZpbml0aW9ucykge1xuICAgIHZhciBkZWZpbml0aW9uID0gc3BlYy5kZWZpbml0aW9uc1tuYW1lXTtcbiAgICBpZihkZWZpbml0aW9uWyckcmVmJ10pIHtcbiAgICAgIHRoaXMucmVzb2x2ZUlubGluZShyb290LCBzcGVjLCBkZWZpbml0aW9uLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBkZWZpbml0aW9uKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBmb3IgKHByb3BlcnR5TmFtZSBpbiBkZWZpbml0aW9uLnByb3BlcnRpZXMpIHtcbiAgICAgICAgcHJvcGVydHkgPSBkZWZpbml0aW9uLnByb3BlcnRpZXNbcHJvcGVydHlOYW1lXTtcbiAgICAgICAgaWYgKF8uaXNBcnJheShwcm9wZXJ0eS5hbGxPZikpIHtcbiAgICAgICAgICB0aGlzLnByb2Nlc3NBbGxPZihyb290LCBuYW1lLCBwcm9wZXJ0eSwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgc3BlYyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgdGhpcy5yZXNvbHZlVG8ocm9vdCwgcHJvcGVydHksIHJlc29sdXRpb25UYWJsZSwgJy9kZWZpbml0aW9ucycpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChkZWZpbml0aW9uLmFsbE9mKSB7XG4gICAgICAgIHRoaXMucHJvY2Vzc0FsbE9mKHJvb3QsIG5hbWUsIGRlZmluaXRpb24sIHJlc29sdXRpb25UYWJsZSwgdW5yZXNvbHZlZFJlZnMsIHNwZWMpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIHNoYXJlZCBwYXJhbWV0ZXJzXG4gIHNwZWMucGFyYW1ldGVycyA9IHNwZWMucGFyYW1ldGVycyB8fCB7fTtcbiAgZm9yKG5hbWUgaW4gc3BlYy5wYXJhbWV0ZXJzKSB7XG4gICAgdmFyIHBhcmFtZXRlciA9IHNwZWMucGFyYW1ldGVyc1tuYW1lXTtcbiAgICBpZiAocGFyYW1ldGVyLmluID09PSAnYm9keScgJiYgcGFyYW1ldGVyLnNjaGVtYSkge1xuICAgICAgaWYoXy5pc0FycmF5KHBhcmFtZXRlci5zY2hlbWEuYWxsT2YpKSB7XG4gICAgICAgIC8vIG1vdmUgdG8gYSBkZWZpbml0aW9uXG4gICAgICAgIHZhciBtb2RlbE5hbWUgPSAnaW5saW5lX21vZGVsJztcbiAgICAgICAgdmFyIG5hbWUgPSBtb2RlbE5hbWU7XG4gICAgICAgIHZhciBkb25lID0gZmFsc2U7IHZhciBjb3VudGVyID0gMDtcbiAgICAgICAgd2hpbGUoIWRvbmUpIHtcbiAgICAgICAgICBpZih0eXBlb2Ygc3BlYy5kZWZpbml0aW9uc1tuYW1lXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIGRvbmUgPSB0cnVlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIG5hbWUgPSBtb2RlbE5hbWUgKyAnXycgKyBjb3VudGVyO1xuICAgICAgICAgIGNvdW50ZXIgKys7XG4gICAgICAgIH1cbiAgICAgICAgc3BlYy5kZWZpbml0aW9uc1tuYW1lXSA9IHsgYWxsT2Y6IHBhcmFtZXRlci5zY2hlbWEuYWxsT2YgfTtcbiAgICAgICAgZGVsZXRlIHBhcmFtZXRlci5zY2hlbWEuYWxsT2Y7XG4gICAgICAgIHBhcmFtZXRlci5zY2hlbWEuJHJlZiA9ICcjL2RlZmluaXRpb25zLycgKyBuYW1lO1xuICAgICAgICB0aGlzLnByb2Nlc3NBbGxPZihyb290LCBuYW1lLCBzcGVjLmRlZmluaXRpb25zW25hbWVdLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBzcGVjKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICB0aGlzLnJlc29sdmVUbyhyb290LCBwYXJhbWV0ZXIuc2NoZW1hLCByZXNvbHV0aW9uVGFibGUsIGxvY2F0aW9uKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocGFyYW1ldGVyLiRyZWYpIHtcbiAgICAgIC8vIHBhcmFtZXRlciByZWZlcmVuY2VcbiAgICAgIHRoaXMucmVzb2x2ZUlubGluZShyb290LCBzcGVjLCBwYXJhbWV0ZXIsIHJlc29sdXRpb25UYWJsZSwgdW5yZXNvbHZlZFJlZnMsIHBhcmFtZXRlci4kcmVmKTtcbiAgICB9XG4gIH1cblxuICAvLyBvcGVyYXRpb25zXG4gIGZvciAobmFtZSBpbiBzcGVjLnBhdGhzKSB7XG4gICAgdmFyIG1ldGhvZCwgb3BlcmF0aW9uLCByZXNwb25zZUNvZGU7XG4gICAgcGF0aCA9IHNwZWMucGF0aHNbbmFtZV07XG5cbiAgICBmb3IgKG1ldGhvZCBpbiBwYXRoKSB7XG4gICAgICAvLyBvcGVyYXRpb24gcmVmZXJlbmNlXG4gICAgICBpZihtZXRob2QgPT09ICckcmVmJykge1xuICAgICAgICAvLyBsb2NhdGlvbiA9IHBhdGhbbWV0aG9kXTtcbiAgICAgICAgbG9jYXRpb24gPSAnL3BhdGhzJyArIG5hbWU7XG4gICAgICAgIHRoaXMucmVzb2x2ZUlubGluZShyb290LCBzcGVjLCBwYXRoLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBsb2NhdGlvbik7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgb3BlcmF0aW9uID0gcGF0aFttZXRob2RdO1xuICAgICAgICB2YXIgc2hhcmVkUGFyYW1ldGVycyA9IHBhdGgucGFyYW1ldGVycyB8fCBbXTtcbiAgICAgICAgdmFyIHBhcmFtZXRlcnMgPSBvcGVyYXRpb24ucGFyYW1ldGVycyB8fCBbXTtcblxuICAgICAgICBmb3IgKGkgaW4gc2hhcmVkUGFyYW1ldGVycykge1xuICAgICAgICAgIHZhciBwYXJhbWV0ZXIgPSBzaGFyZWRQYXJhbWV0ZXJzW2ldO1xuICAgICAgICAgIHBhcmFtZXRlcnMudW5zaGlmdChwYXJhbWV0ZXIpO1xuICAgICAgICB9XG4gICAgICAgIGlmKG1ldGhvZCAhPT0gJ3BhcmFtZXRlcnMnICYmIF8uaXNPYmplY3Qob3BlcmF0aW9uKSkge1xuICAgICAgICAgIG9wZXJhdGlvbi5wYXJhbWV0ZXJzID0gb3BlcmF0aW9uLnBhcmFtZXRlcnMgfHwgcGFyYW1ldGVycztcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoaSBpbiBwYXJhbWV0ZXJzKSB7XG4gICAgICAgICAgdmFyIHBhcmFtZXRlciA9IHBhcmFtZXRlcnNbaV07XG4gICAgICAgICAgbG9jYXRpb24gPSAnL3BhdGhzJyArIG5hbWUgKyAnLycgKyBtZXRob2QgKyAnL3BhcmFtZXRlcnMnO1xuXG4gICAgICAgICAgaWYgKHBhcmFtZXRlci5pbiA9PT0gJ2JvZHknICYmIHBhcmFtZXRlci5zY2hlbWEpIHtcbiAgICAgICAgICAgIGlmKF8uaXNBcnJheShwYXJhbWV0ZXIuc2NoZW1hLmFsbE9mKSkge1xuICAgICAgICAgICAgICAvLyBtb3ZlIHRvIGEgZGVmaW5pdGlvblxuICAgICAgICAgICAgICB2YXIgbW9kZWxOYW1lID0gJ2lubGluZV9tb2RlbCc7XG4gICAgICAgICAgICAgIHZhciBuYW1lID0gbW9kZWxOYW1lO1xuICAgICAgICAgICAgICB2YXIgZG9uZSA9IGZhbHNlOyB2YXIgY291bnRlciA9IDA7XG4gICAgICAgICAgICAgIHdoaWxlKCFkb25lKSB7XG4gICAgICAgICAgICAgICAgaWYodHlwZW9mIHNwZWMuZGVmaW5pdGlvbnNbbmFtZV0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBuYW1lID0gbW9kZWxOYW1lICsgJ18nICsgY291bnRlcjtcbiAgICAgICAgICAgICAgICBjb3VudGVyICsrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHNwZWMuZGVmaW5pdGlvbnNbbmFtZV0gPSB7IGFsbE9mOiBwYXJhbWV0ZXIuc2NoZW1hLmFsbE9mIH07XG4gICAgICAgICAgICAgIGRlbGV0ZSBwYXJhbWV0ZXIuc2NoZW1hLmFsbE9mO1xuICAgICAgICAgICAgICBwYXJhbWV0ZXIuc2NoZW1hLiRyZWYgPSAnIy9kZWZpbml0aW9ucy8nICsgbmFtZTtcbiAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzQWxsT2Yocm9vdCwgbmFtZSwgc3BlYy5kZWZpbml0aW9uc1tuYW1lXSwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgc3BlYyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgdGhpcy5yZXNvbHZlVG8ocm9vdCwgcGFyYW1ldGVyLnNjaGVtYSwgcmVzb2x1dGlvblRhYmxlLCBsb2NhdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHBhcmFtZXRlci4kcmVmKSB7XG4gICAgICAgICAgICAvLyBwYXJhbWV0ZXIgcmVmZXJlbmNlXG4gICAgICAgICAgICB0aGlzLnJlc29sdmVJbmxpbmUocm9vdCwgc3BlYywgcGFyYW1ldGVyLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBwYXJhbWV0ZXIuJHJlZik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChyZXNwb25zZUNvZGUgaW4gb3BlcmF0aW9uLnJlc3BvbnNlcykge1xuICAgICAgICAgIHZhciByZXNwb25zZSA9IG9wZXJhdGlvbi5yZXNwb25zZXNbcmVzcG9uc2VDb2RlXTtcbiAgICAgICAgICBsb2NhdGlvbiA9ICcvcGF0aHMnICsgbmFtZSArICcvJyArIG1ldGhvZCArICcvcmVzcG9uc2VzLycgKyByZXNwb25zZUNvZGU7XG5cbiAgICAgICAgICBpZihfLmlzT2JqZWN0KHJlc3BvbnNlKSkge1xuICAgICAgICAgICAgaWYocmVzcG9uc2UuJHJlZikge1xuICAgICAgICAgICAgICAvLyByZXNwb25zZSByZWZlcmVuY2VcbiAgICAgICAgICAgICAgdGhpcy5yZXNvbHZlSW5saW5lKHJvb3QsIHNwZWMsIHJlc3BvbnNlLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBsb2NhdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocmVzcG9uc2Uuc2NoZW1hKSB7XG4gICAgICAgICAgICAgIHZhciByZXNwb25zZU9iaiA9IHJlc3BvbnNlO1xuICAgICAgICAgICAgICBpZihfLmlzQXJyYXkocmVzcG9uc2VPYmouc2NoZW1hLmFsbE9mKSkge1xuICAgICAgICAgICAgICAgIC8vIG1vdmUgdG8gYSBkZWZpbml0aW9uXG4gICAgICAgICAgICAgICAgdmFyIG1vZGVsTmFtZSA9ICdpbmxpbmVfbW9kZWwnO1xuICAgICAgICAgICAgICAgIHZhciBuYW1lID0gbW9kZWxOYW1lO1xuICAgICAgICAgICAgICAgIHZhciBkb25lID0gZmFsc2U7IHZhciBjb3VudGVyID0gMDtcbiAgICAgICAgICAgICAgICB3aGlsZSghZG9uZSkge1xuICAgICAgICAgICAgICAgICAgaWYodHlwZW9mIHNwZWMuZGVmaW5pdGlvbnNbbmFtZV0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIG5hbWUgPSBtb2RlbE5hbWUgKyAnXycgKyBjb3VudGVyO1xuICAgICAgICAgICAgICAgICAgY291bnRlciArKztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc3BlYy5kZWZpbml0aW9uc1tuYW1lXSA9IHsgYWxsT2Y6IHJlc3BvbnNlT2JqLnNjaGVtYS5hbGxPZiB9O1xuICAgICAgICAgICAgICAgIGRlbGV0ZSByZXNwb25zZU9iai5zY2hlbWEuYWxsT2Y7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHJlc3BvbnNlT2JqLnNjaGVtYS50eXBlO1xuICAgICAgICAgICAgICAgIHJlc3BvbnNlT2JqLnNjaGVtYS4kcmVmID0gJyMvZGVmaW5pdGlvbnMvJyArIG5hbWU7XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzQWxsT2Yocm9vdCwgbmFtZSwgc3BlYy5kZWZpbml0aW9uc1tuYW1lXSwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgc3BlYyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZWxzZSBpZignYXJyYXknID09PSByZXNwb25zZU9iai5zY2hlbWEudHlwZSkge1xuICAgICAgICAgICAgICAgIGlmKHJlc3BvbnNlT2JqLnNjaGVtYS5pdGVtcyAmJiByZXNwb25zZU9iai5zY2hlbWEuaXRlbXMuJHJlZikge1xuICAgICAgICAgICAgICAgICAgLy8gcmVzcG9uc2UgcmVmZXJlbmNlXG4gICAgICAgICAgICAgICAgICB0aGlzLnJlc29sdmVJbmxpbmUocm9vdCwgc3BlYywgcmVzcG9uc2VPYmouc2NoZW1hLml0ZW1zLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBsb2NhdGlvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMucmVzb2x2ZVRvKHJvb3QsIHJlc3BvbnNlLnNjaGVtYSwgcmVzb2x1dGlvblRhYmxlLCBsb2NhdGlvbik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgLy8gY2xlYXIgdGhlbSBvdXQgdG8gYXZvaWQgbXVsdGlwbGUgcmVzb2x1dGlvbnNcbiAgICBwYXRoLnBhcmFtZXRlcnMgPSBbXTtcbiAgfVxuXG4gIHZhciBleHBlY3RlZENhbGxzID0gMCwgdG9SZXNvbHZlID0gW107XG4gIC8vIGlmIHRoZSByb290IGlzIHNhbWUgYXMgb2JqW2ldLnJvb3Qgd2UgY2FuIHJlc29sdmUgbG9jYWxseVxuICB2YXIgYWxsID0gcmVzb2x1dGlvblRhYmxlO1xuXG4gIHZhciBwYXJ0cztcbiAgZm9yKGkgPSAwOyBpIDwgYWxsLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGEgPSBhbGxbaV07XG4gICAgaWYocm9vdCA9PT0gYS5yb290KSB7XG4gICAgICBpZihhLnJlc29sdmVBcyA9PT0gJ3JlZicpIHtcbiAgICAgICAgLy8gcmVzb2x2ZSBhbnkgcGF0aCB3YWxraW5nXG4gICAgICAgIHZhciBqb2luZWQgPSAoKGEucm9vdCB8fCAnJykgKyAnLycgKyBhLmtleSkuc3BsaXQoJy8nKTtcbiAgICAgICAgdmFyIG5vcm1hbGl6ZWQgPSBbXTtcbiAgICAgICAgdmFyIHVybCA9ICcnO1xuICAgICAgICB2YXIgaztcblxuICAgICAgICBpZihhLmtleS5pbmRleE9mKCcuLi8nKSA+PSAwKSB7XG4gICAgICAgICAgZm9yKHZhciBqID0gMDsgaiA8IGpvaW5lZC5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgaWYoam9pbmVkW2pdID09PSAnLi4nKSB7XG4gICAgICAgICAgICAgIG5vcm1hbGl6ZWQgPSBub3JtYWxpemVkLnNsaWNlKDAsIG5vcm1hbGl6ZWQubGVuZ3RoLTEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgIG5vcm1hbGl6ZWQucHVzaChqb2luZWRbal0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBmb3IoayA9IDA7IGsgPCBub3JtYWxpemVkLmxlbmd0aDsgayArKykge1xuICAgICAgICAgICAgaWYoayA+IDApIHtcbiAgICAgICAgICAgICAgdXJsICs9ICcvJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHVybCArPSBub3JtYWxpemVkW2tdO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyB3ZSBub3cgaGF2ZSB0byByZW1vdGUgcmVzb2x2ZSB0aGlzIGJlY2F1c2UgdGhlIHBhdGggaGFzIGNoYW5nZWRcbiAgICAgICAgICBhLnJvb3QgPSB1cmw7XG4gICAgICAgICAgdG9SZXNvbHZlLnB1c2goYSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgcGFydHMgPSBhLmtleS5zcGxpdCgnIycpO1xuICAgICAgICAgIGlmKHBhcnRzLmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgICAgaWYocGFydHNbMF0uaW5kZXhPZignaHR0cDovLycpID09PSAwIHx8IHBhcnRzWzBdLmluZGV4T2YoJ2h0dHBzOi8vJykgPT09IDApIHtcbiAgICAgICAgICAgICAgYS5yb290ID0gcGFydHNbMF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsb2NhdGlvbiA9IHBhcnRzWzFdLnNwbGl0KCcvJyk7XG4gICAgICAgICAgICB2YXIgcjtcbiAgICAgICAgICAgIHZhciBzID0gc3BlYztcbiAgICAgICAgICAgIGZvcihrID0gMDsgayA8IGxvY2F0aW9uLmxlbmd0aDsgaysrKSB7XG4gICAgICAgICAgICAgIHZhciBwYXJ0ID0gbG9jYXRpb25ba107XG4gICAgICAgICAgICAgIGlmKHBhcnQgIT09ICcnKSB7XG4gICAgICAgICAgICAgICAgcyA9IHNbcGFydF07XG4gICAgICAgICAgICAgICAgaWYodHlwZW9mIHMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICByID0gcztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICByID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYociA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAvLyBtdXN0IHJlc29sdmUgdGhpcyB0b29cbiAgICAgICAgICAgICAgdG9SZXNvbHZlLnB1c2goYSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgaWYgKGEucmVzb2x2ZUFzID09PSAnaW5saW5lJykge1xuICAgICAgICAgIGlmKGEua2V5ICYmIGEua2V5LmluZGV4T2YoJyMnKSA9PT0gLTEgJiYgYS5rZXkuY2hhckF0KDApICE9PSAnLycpIHtcbiAgICAgICAgICAgIC8vIGhhbmRsZSByZWxhdGl2ZSBzY2hlbWFcbiAgICAgICAgICAgIHBhcnRzID0gYS5yb290LnNwbGl0KCcvJyk7XG4gICAgICAgICAgICBsb2NhdGlvbiA9ICcnO1xuICAgICAgICAgICAgZm9yKGkgPSAwOyBpIDwgcGFydHMubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgICAgICAgIGxvY2F0aW9uICs9IHBhcnRzW2ldICsgJy8nO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbG9jYXRpb24gKz0gYS5rZXk7XG4gICAgICAgICAgICBhLnJvb3QgPSBsb2NhdGlvbjtcbiAgICAgICAgICAgIGEubG9jYXRpb24gPSAnJztcbiAgICAgICAgICB9XG4gICAgICAgICAgdG9SZXNvbHZlLnB1c2goYSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB0b1Jlc29sdmUucHVzaChhKTtcbiAgICB9XG4gIH1cbiAgZXhwZWN0ZWRDYWxscyA9IHRvUmVzb2x2ZS5sZW5ndGg7XG5cbiAgLy8gcmVzb2x2ZSBhbnl0aGluZyB0aGF0IGlzIGxvY2FsXG4gIGZvcih2YXIgaWkgPSAwOyBpaSA8IHRvUmVzb2x2ZS5sZW5ndGg7IGlpKyspIHtcbiAgICAoZnVuY3Rpb24oaXRlbSwgc3BlYywgc2VsZikge1xuICAgICAgLy8gTk9URTogdGhpcyB1c2VkIHRvIGJlIGl0ZW0ucm9vdCA9PT0gbnVsbCwgYnV0IEkgKEBwb25lbGF0KSBoYXZlIGFkZGVkIGEgZ3VhcmQgYWdhaW5zdCAuc3BsaXQsIHdoaWNoIG1lYW5zIGl0ZW0ucm9vdCBjYW4gYmUgJydcbiAgICAgIGlmKCFpdGVtLnJvb3QgfHwgaXRlbS5yb290ID09PSByb290KSB7XG4gICAgICAgIC8vIGxvY2FsIHJlc29sdmVcbiAgICAgICAgc2VsZi5yZXNvbHZlSXRlbShzcGVjLCBfcm9vdCwgcmVzb2x1dGlvblRhYmxlLCByZXNvbHZlZFJlZnMsIHVucmVzb2x2ZWRSZWZzLCBpdGVtKTtcbiAgICAgICAgcHJvY2Vzc2VkQ2FsbHMgKz0gMTtcblxuICAgICAgICBpZihwcm9jZXNzZWRDYWxscyA9PT0gZXhwZWN0ZWRDYWxscykge1xuICAgICAgICAgIHNlbGYuZmluaXNoKHNwZWMsIHJvb3QsIHJlc29sdXRpb25UYWJsZSwgcmVzb2x2ZWRSZWZzLCB1bnJlc29sdmVkUmVmcywgY2FsbGJhY2ssIHRydWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBlbHNlIGlmKHNlbGYuZmFpbGVkVXJscy5pbmRleE9mKGl0ZW0ucm9vdCkgPT09IC0xKSB7XG4gICAgICAgIHZhciBvYmogPSB7XG4gICAgICAgICAgdXNlSlF1ZXJ5OiBmYWxzZSwgIC8vIFRPRE9cbiAgICAgICAgICB1cmw6IGl0ZW0ucm9vdCxcbiAgICAgICAgICBtZXRob2Q6ICdnZXQnLFxuICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgIGFjY2VwdDogc2VsZi5zY29wZS5zd2FnZ2VyUmVxdWVzdEhlYWRlcnMgfHwgJ2FwcGxpY2F0aW9uL2pzb24nXG4gICAgICAgICAgfSxcbiAgICAgICAgICBvbjoge1xuICAgICAgICAgICAgZXJyb3I6IGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICAgICAgICBwcm9jZXNzZWRDYWxscyArPSAxO1xuICAgICAgICAgICAgICBjb25zb2xlLmxvZygnZmFpbGVkIHVybDogJyArIG9iai51cmwpO1xuICAgICAgICAgICAgICBzZWxmLmZhaWxlZFVybHMucHVzaChvYmoudXJsKTtcbiAgICAgICAgICAgICAgdW5yZXNvbHZlZFJlZnNbaXRlbS5rZXldID0ge1xuICAgICAgICAgICAgICAgIHJvb3Q6IGl0ZW0ucm9vdCxcbiAgICAgICAgICAgICAgICBsb2NhdGlvbjogaXRlbS5sb2NhdGlvblxuICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgIGlmIChwcm9jZXNzZWRDYWxscyA9PT0gZXhwZWN0ZWRDYWxscykge1xuICAgICAgICAgICAgICAgIHNlbGYuZmluaXNoKHNwZWMsIF9yb290LCByZXNvbHV0aW9uVGFibGUsIHJlc29sdmVkUmVmcywgdW5yZXNvbHZlZFJlZnMsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgIC8vIGpzaGludCBpZ25vcmU6bGluZVxuICAgICAgICAgICAgcmVzcG9uc2U6IGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgICAgICAgICB2YXIgc3dhZ2dlciA9IHJlc3BvbnNlLm9iajtcbiAgICAgICAgICAgICAgc2VsZi5yZXNvbHZlSXRlbShzd2FnZ2VyLCBpdGVtLnJvb3QsIHJlc29sdXRpb25UYWJsZSwgcmVzb2x2ZWRSZWZzLCB1bnJlc29sdmVkUmVmcywgaXRlbSk7XG4gICAgICAgICAgICAgIHByb2Nlc3NlZENhbGxzICs9IDE7XG5cbiAgICAgICAgICAgICAgaWYgKHByb2Nlc3NlZENhbGxzID09PSBleHBlY3RlZENhbGxzKSB7XG4gICAgICAgICAgICAgICAgc2VsZi5maW5pc2goc3BlYywgX3Jvb3QsIHJlc29sdXRpb25UYWJsZSwgcmVzb2x2ZWRSZWZzLCB1bnJlc29sdmVkUmVmcywgY2FsbGJhY2spO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAoc2NvcGUgJiYgc2NvcGUuY2xpZW50QXV0aG9yaXphdGlvbnMpIHtcbiAgICAgICAgICBzY29wZS5jbGllbnRBdXRob3JpemF0aW9ucy5hcHBseShvYmopO1xuICAgICAgICB9XG5cbiAgICAgICAgbmV3IFN3YWdnZXJIdHRwKCkuZXhlY3V0ZShvYmosIG9wdHMpO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHByb2Nlc3NlZENhbGxzICs9IDE7XG4gICAgICAgIHVucmVzb2x2ZWRSZWZzW2l0ZW0ua2V5XSA9IHtcbiAgICAgICAgICByb290OiBpdGVtLnJvb3QsXG4gICAgICAgICAgbG9jYXRpb246IGl0ZW0ubG9jYXRpb25cbiAgICAgICAgfTtcbiAgICAgICAgaWYgKHByb2Nlc3NlZENhbGxzID09PSBleHBlY3RlZENhbGxzKSB7XG4gICAgICAgICAgc2VsZi5maW5pc2goc3BlYywgX3Jvb3QsIHJlc29sdXRpb25UYWJsZSwgcmVzb2x2ZWRSZWZzLCB1bnJlc29sdmVkUmVmcywgY2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSh0b1Jlc29sdmVbaWldLCBzcGVjLCB0aGlzKSk7XG4gIH1cblxuICBpZiAoT2JqZWN0LmtleXModG9SZXNvbHZlKS5sZW5ndGggPT09IDApIHtcbiAgICB0aGlzLmZpbmlzaChzcGVjLCBfcm9vdCwgcmVzb2x1dGlvblRhYmxlLCByZXNvbHZlZFJlZnMsIHVucmVzb2x2ZWRSZWZzLCBjYWxsYmFjayk7XG4gIH1cbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS5yZXNvbHZlSXRlbSA9IGZ1bmN0aW9uKHNwZWMsIHJvb3QsIHJlc29sdXRpb25UYWJsZSwgcmVzb2x2ZWRSZWZzLCB1bnJlc29sdmVkUmVmcywgaXRlbSkge1xuICB2YXIgcGF0aCA9IGl0ZW0ubG9jYXRpb247XG4gIHZhciBsb2NhdGlvbiA9IHNwZWMsIHBhcnRzID0gcGF0aC5zcGxpdCgnLycpO1xuICBpZihwYXRoICE9PSAnJykge1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgcGFydHMubGVuZ3RoOyBqKyspIHtcbiAgICAgIHZhciBzZWdtZW50ID0gcGFydHNbal07XG4gICAgICBpZiAoc2VnbWVudC5pbmRleE9mKCd+MScpICE9PSAtMSkge1xuICAgICAgICBzZWdtZW50ID0gcGFydHNbal0ucmVwbGFjZSgvfjAvZywgJ34nKS5yZXBsYWNlKC9+MS9nLCAnLycpO1xuICAgICAgICBpZiAoc2VnbWVudC5jaGFyQXQoMCkgIT09ICcvJykge1xuICAgICAgICAgIHNlZ21lbnQgPSAnLycgKyBzZWdtZW50O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIGxvY2F0aW9uID09PSAndW5kZWZpbmVkJyB8fCBsb2NhdGlvbiA9PT0gbnVsbCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmIChzZWdtZW50ID09PSAnJyAmJiBqID09PSAocGFydHMubGVuZ3RoIC0gMSkgJiYgcGFydHMubGVuZ3RoID4gMSkge1xuICAgICAgICBsb2NhdGlvbiA9IG51bGw7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgaWYgKHNlZ21lbnQubGVuZ3RoID4gMCkge1xuICAgICAgICBsb2NhdGlvbiA9IGxvY2F0aW9uW3NlZ21lbnRdO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICB2YXIgcmVzb2x2ZWQgPSBpdGVtLmtleTtcbiAgcGFydHMgPSBpdGVtLmtleS5zcGxpdCgnLycpO1xuICB2YXIgcmVzb2x2ZWROYW1lID0gcGFydHNbcGFydHMubGVuZ3RoLTFdO1xuXG4gIGlmKHJlc29sdmVkTmFtZS5pbmRleE9mKCcjJykgPj0gMCkge1xuICAgIHJlc29sdmVkTmFtZSA9IHJlc29sdmVkTmFtZS5zcGxpdCgnIycpWzFdO1xuICB9XG5cbiAgaWYgKGxvY2F0aW9uICE9PSBudWxsICYmIHR5cGVvZiBsb2NhdGlvbiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXNvbHZlZFJlZnNbcmVzb2x2ZWRdID0ge1xuICAgICAgbmFtZTogcmVzb2x2ZWROYW1lLFxuICAgICAgb2JqOiBsb2NhdGlvbixcbiAgICAgIGtleTogaXRlbS5rZXksXG4gICAgICByb290OiBpdGVtLnJvb3RcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIHVucmVzb2x2ZWRSZWZzW3Jlc29sdmVkXSA9IHtcbiAgICAgIHJvb3Q6IGl0ZW0ucm9vdCxcbiAgICAgIGxvY2F0aW9uOiBpdGVtLmxvY2F0aW9uXG4gICAgfTtcbiAgfVxufTtcblxuUmVzb2x2ZXIucHJvdG90eXBlLmZpbmlzaCA9IGZ1bmN0aW9uIChzcGVjLCByb290LCByZXNvbHV0aW9uVGFibGUsIHJlc29sdmVkUmVmcywgdW5yZXNvbHZlZFJlZnMsIGNhbGxiYWNrLCBsb2NhbFJlc29sdmUpIHtcbiAgLy8gd2FsayByZXNvbHV0aW9uIHRhYmxlIGFuZCByZXBsYWNlIHdpdGggcmVzb2x2ZWQgcmVmc1xuICB2YXIgcmVmO1xuICBmb3IgKHJlZiBpbiByZXNvbHV0aW9uVGFibGUpIHtcbiAgICB2YXIgaXRlbSA9IHJlc29sdXRpb25UYWJsZVtyZWZdO1xuXG4gICAgdmFyIGtleSA9IGl0ZW0ua2V5O1xuICAgIHZhciByZXNvbHZlZFRvID0gcmVzb2x2ZWRSZWZzW2tleV07XG4gICAgaWYgKHJlc29sdmVkVG8pIHtcbiAgICAgIHNwZWMuZGVmaW5pdGlvbnMgPSBzcGVjLmRlZmluaXRpb25zIHx8IHt9O1xuICAgICAgaWYgKGl0ZW0ucmVzb2x2ZUFzID09PSAncmVmJykge1xuICAgICAgICBpZiAobG9jYWxSZXNvbHZlICE9PSB0cnVlKSB7XG4gICAgICAgICAgLy8gZG9uJ3QgcmV0YWluIHJvb3QgZm9yIGxvY2FsIGRlZmluaXRpb25zXG4gICAgICAgICAgZm9yIChrZXkgaW4gcmVzb2x2ZWRUby5vYmopIHtcbiAgICAgICAgICAgIHZhciBhYnMgPSB0aGlzLnJldGFpblJvb3QocmVzb2x2ZWRUby5vYmpba2V5XSwgaXRlbS5yb290KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc3BlYy5kZWZpbml0aW9uc1tyZXNvbHZlZFRvLm5hbWVdID0gcmVzb2x2ZWRUby5vYmo7XG4gICAgICAgIGl0ZW0ub2JqLiRyZWYgPSAnIy9kZWZpbml0aW9ucy8nICsgcmVzb2x2ZWRUby5uYW1lO1xuICAgICAgfSBlbHNlIGlmIChpdGVtLnJlc29sdmVBcyA9PT0gJ2lubGluZScpIHtcbiAgICAgICAgdmFyIHRhcmdldE9iaiA9IGl0ZW0ub2JqO1xuICAgICAgICB0YXJnZXRPYmpbJ3gtcmVzb2x2ZWQtZnJvbSddID0gWyBpdGVtLmtleSBdO1xuICAgICAgICBkZWxldGUgdGFyZ2V0T2JqLiRyZWY7XG5cbiAgICAgICAgZm9yIChrZXkgaW4gcmVzb2x2ZWRUby5vYmopIHtcbiAgICAgICAgICB2YXIgYWJzID0gcmVzb2x2ZWRUby5vYmpba2V5XTtcbiAgICAgICAgICBcbiAgICAgICAgICBpZiAobG9jYWxSZXNvbHZlICE9PSB0cnVlKSB7XG4gICAgICAgICAgICAvLyBkb24ndCByZXRhaW4gcm9vdCBmb3IgbG9jYWwgZGVmaW5pdGlvbnNcbiAgICAgICAgICAgIGFicyA9IHRoaXMucmV0YWluUm9vdChyZXNvbHZlZFRvLm9ialtrZXldLCBpdGVtLnJvb3QpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0YXJnZXRPYmpba2V5XSA9IGFicztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuICB2YXIgZXhpc3RpbmdVbnJlc29sdmVkID0gdGhpcy5jb3VudFVucmVzb2x2ZWRSZWZzKHNwZWMpO1xuXG4gIGlmKGV4aXN0aW5nVW5yZXNvbHZlZCA9PT0gMCB8fCB0aGlzLml0ZXJhdGlvbiA+IDUpIHtcbiAgICB0aGlzLnJlc29sdmVBbGxPZihzcGVjLmRlZmluaXRpb25zKTtcbiAgICBjYWxsYmFjay5jYWxsKHRoaXMuc2NvcGUsIHNwZWMsIHVucmVzb2x2ZWRSZWZzKTtcbiAgfVxuICBlbHNlIHtcbiAgICB0aGlzLml0ZXJhdGlvbiArPSAxO1xuICAgIHRoaXMucmVzb2x2ZShzcGVjLCByb290LCBjYWxsYmFjaywgdGhpcy5zY29wZSk7XG4gIH1cbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS5jb3VudFVucmVzb2x2ZWRSZWZzID0gZnVuY3Rpb24oc3BlYykge1xuICB2YXIgaTtcbiAgdmFyIHJlZnMgPSB0aGlzLmdldFJlZnMoc3BlYyk7XG4gIHZhciBrZXlzID0gW107XG4gIHZhciB1bnJlc29sdmVkS2V5cyA9IFtdO1xuICBmb3IoaSBpbiByZWZzKSB7XG4gICAgaWYoaS5pbmRleE9mKCcjJykgPT09IDApIHtcbiAgICAgIGtleXMucHVzaChpLnN1YnN0cmluZygxKSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgdW5yZXNvbHZlZEtleXMucHVzaChpKTtcbiAgICB9XG4gIH1cblxuICAvLyB2ZXJpZnkgcG9zc2libGUga2V5c1xuICBmb3IgKGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwYXJ0ID0ga2V5c1tpXTtcbiAgICB2YXIgcGFydHMgPSBwYXJ0LnNwbGl0KCcvJyk7XG4gICAgdmFyIG9iaiA9IHNwZWM7XG5cbiAgICBmb3IgKHZhciBrID0gMDsgayA8IHBhcnRzLmxlbmd0aDsgaysrKSB7XG4gICAgICB2YXIga2V5ID0gcGFydHNba107XG4gICAgICBpZihrZXkgIT09ICcnKSB7XG4gICAgICAgIG9iaiA9IG9ialtrZXldO1xuICAgICAgICBpZih0eXBlb2Ygb2JqID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIHVucmVzb2x2ZWRLZXlzLnB1c2gocGFydCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHVucmVzb2x2ZWRLZXlzLmxlbmd0aDtcbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS5nZXRSZWZzID0gZnVuY3Rpb24oc3BlYywgb2JqKSB7XG4gIG9iaiA9IG9iaiB8fCBzcGVjO1xuICB2YXIgb3V0cHV0ID0ge307XG4gIGZvcih2YXIga2V5IGluIG9iaikge1xuICAgIGlmICghb2JqLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICB2YXIgaXRlbSA9IG9ialtrZXldO1xuICAgIGlmKGtleSA9PT0gJyRyZWYnICYmIHR5cGVvZiBpdGVtID09PSAnc3RyaW5nJykge1xuICAgICAgb3V0cHV0W2l0ZW1dID0gbnVsbDtcbiAgICB9XG4gICAgZWxzZSBpZihfLmlzT2JqZWN0KGl0ZW0pKSB7XG4gICAgICB2YXIgbyA9IHRoaXMuZ2V0UmVmcyhpdGVtKTtcbiAgICAgIGZvcih2YXIgayBpbiBvKSB7XG4gICAgICAgIG91dHB1dFtrXSA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBvdXRwdXQ7XG59O1xuXG5SZXNvbHZlci5wcm90b3R5cGUucmV0YWluUm9vdCA9IGZ1bmN0aW9uKG9iaiwgcm9vdCkge1xuICAvLyB3YWxrIG9iamVjdCBhbmQgbG9vayBmb3IgcmVsYXRpdmUgJHJlZnNcbiAgZm9yKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgdmFyIGl0ZW0gPSBvYmpba2V5XTtcbiAgICBpZihrZXkgPT09ICckcmVmJyAmJiB0eXBlb2YgaXRlbSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIC8vIHN0b3AgYW5kIGluc3BlY3RcbiAgICAgIGlmKGl0ZW0uaW5kZXhPZignaHR0cDovLycpICE9PSAwICYmIGl0ZW0uaW5kZXhPZignaHR0cHM6Ly8nKSAhPT0gMCkge1xuICAgICAgICAvLyBUT0RPOiBjaGVjayBpZiByb290IGVuZHMgaW4gJy8nLiAgSWYgbm90LCBBTkQgaXRlbSBoYXMgbm8gcHJvdG9jb2wsIG1ha2UgcmVsYXRpdmVcbiAgICAgICAgdmFyIGFwcGVuZEhhc2ggPSB0cnVlO1xuICAgICAgICB2YXIgb2xkUm9vdCA9IHJvb3Q7XG4gICAgICAgIGlmKHJvb3QpIHtcbiAgICAgICAgICB2YXIgbGFzdENoYXIgPSByb290LnNsaWNlKC0xKTtcbiAgICAgICAgICBpZihsYXN0Q2hhciAhPT0gJy8nICYmIChpdGVtLmluZGV4T2YoJyMnKSAhPT0gMCAmJiBpdGVtLmluZGV4T2YoJ2h0dHA6Ly8nKSAhPT0gMCAmJiBpdGVtLmluZGV4T2YoJ2h0dHBzOi8vJykpKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnd29ya2luZyB3aXRoICcgKyBpdGVtKTtcbiAgICAgICAgICAgIGFwcGVuZEhhc2ggPSBmYWxzZTtcbiAgICAgICAgICAgIHZhciBwYXJ0cyA9IHJvb3Quc3BsaXQoJ1xcLycpO1xuICAgICAgICAgICAgcGFydHMgPSBwYXJ0cy5zcGxpY2UoMCwgcGFydHMubGVuZ3RoIC0gMSk7XG4gICAgICAgICAgICByb290ID0gJyc7XG4gICAgICAgICAgICBmb3IodmFyIGkgPSAwOyBpIDwgcGFydHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgcm9vdCArPSBwYXJ0c1tpXSArICcvJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYoaXRlbS5pbmRleE9mKCcjJykgIT09IDAgJiYgYXBwZW5kSGFzaCkge1xuICAgICAgICAgIGl0ZW0gPSAnIycgKyBpdGVtO1xuICAgICAgICB9XG5cbiAgICAgICAgaXRlbSA9IChyb290IHx8ICcnKSArIGl0ZW07XG4gICAgICAgIG9ialtrZXldID0gaXRlbTtcbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSBpZihfLmlzT2JqZWN0KGl0ZW0pKSB7XG4gICAgICB0aGlzLnJldGFpblJvb3QoaXRlbSwgcm9vdCk7XG4gICAgfVxuICB9XG4gIHJldHVybiBvYmo7XG59O1xuXG4vKipcbiAqIGltbWVkaWF0ZWx5IGluLWxpbmVzIGxvY2FsIHJlZnMsIHF1ZXVlcyByZW1vdGUgcmVmc1xuICogZm9yIGlubGluZSByZXNvbHV0aW9uXG4gKi9cblJlc29sdmVyLnByb3RvdHlwZS5yZXNvbHZlSW5saW5lID0gZnVuY3Rpb24gKHJvb3QsIHNwZWMsIHByb3BlcnR5LCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBsb2NhdGlvbikge1xuICB2YXIga2V5ID0gcHJvcGVydHkuJHJlZiwgcmVmID0gcHJvcGVydHkuJHJlZiwgaSwgcCwgcDIsIHJzO1xuICB2YXIgcm9vdFRyaW1tZWQgPSBmYWxzZTtcblxuICByb290ID0gcm9vdCB8fCAnJyAvLyBHdWFyZCBhZ2FpbnN0IC5zcGxpdC4gQGZlaGd1eSwgeW91J2xsIG5lZWQgdG8gY2hlY2sgaWYgdGhpcyBsb2dpYyBmaXRzXG4gIC8vIE1vcmUgaW1wb3JhbnRseSBpcyBob3cgZG8gd2UgZ3JhY2VmdWxseSBoYW5kbGUgcmVsYXRpdmUgdXJscywgd2hlbiBwcm92aWRlZCBqdXN0IGEgJ3NwZWMnLCBub3QgYSAndXJsJyA/XG5cbiAgaWYgKHJlZikge1xuICAgIGlmKHJlZi5pbmRleE9mKCcuLi8nKSA9PT0gMCkge1xuICAgICAgLy8gcmVzZXQgcm9vdFxuICAgICAgcCA9IHJlZi5zcGxpdCgnLi4vJyk7XG4gICAgICBwMiA9IHJvb3Quc3BsaXQoJy8nKTtcbiAgICAgIHJlZiA9ICcnO1xuICAgICAgZm9yKGkgPSAwOyBpIDwgcC5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZihwW2ldID09PSAnJykge1xuICAgICAgICAgIHAyID0gcDIuc2xpY2UoMCwgcDIubGVuZ3RoLTEpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHJlZiArPSBwW2ldO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByb290ID0gJyc7XG4gICAgICBmb3IoaSA9IDA7IGkgPCBwMi5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgaWYoaSA+IDApIHsgcm9vdCArPSAnLyc7IH1cbiAgICAgICAgcm9vdCArPSBwMltpXTtcbiAgICAgIH1cbiAgICAgIHJvb3RUcmltbWVkID0gdHJ1ZTtcbiAgICB9XG4gICAgaWYocmVmLmluZGV4T2YoJyMnKSA+PSAwKSB7XG4gICAgICBpZihyZWYuaW5kZXhPZignLycpID09PSAwKSB7XG4gICAgICAgIHJzID0gcmVmLnNwbGl0KCcjJyk7XG4gICAgICAgIHAgID0gcm9vdC5zcGxpdCgnLy8nKTtcbiAgICAgICAgcDIgPSBwWzFdLnNwbGl0KCcvJyk7XG4gICAgICAgIHJvb3QgPSBwWzBdICsgJy8vJyArIHAyWzBdICsgcnNbMF07XG4gICAgICAgIGxvY2F0aW9uID0gcnNbMV07XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgcnMgPSByZWYuc3BsaXQoJyMnKTtcbiAgICAgICAgaWYocnNbMF0gIT09ICcnKSB7XG4gICAgICAgICAgcDIgPSByb290LnNwbGl0KCcvJyk7XG4gICAgICAgICAgcDIgPSBwMi5zbGljZSgwLCBwMi5sZW5ndGggLSAxKTtcbiAgICAgICAgICBpZighcm9vdFRyaW1tZWQpIHtcbiAgICAgICAgICAgIHJvb3QgPSAnJztcbiAgICAgICAgICAgIGZvciAodmFyIGsgPSAwOyBrIDwgcDIubGVuZ3RoOyBrKyspIHtcbiAgICAgICAgICAgICAgaWYoayA+IDApIHsgcm9vdCArPSAnLyc7IH1cbiAgICAgICAgICAgICAgcm9vdCArPSBwMltrXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcm9vdCArPSAnLycgKyByZWYuc3BsaXQoJyMnKVswXTtcbiAgICAgICAgfVxuICAgICAgICBsb2NhdGlvbiA9IHJzWzFdO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAocmVmLmluZGV4T2YoJ2h0dHAnKSA9PT0gMCkge1xuICAgICAgaWYocmVmLmluZGV4T2YoJyMnKSA+PSAwKSB7XG4gICAgICAgIHJvb3QgPSByZWYuc3BsaXQoJyMnKVswXTtcbiAgICAgICAgbG9jYXRpb24gPSByZWYuc3BsaXQoJyMnKVsxXTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICByb290ID0gcmVmO1xuICAgICAgICBsb2NhdGlvbiA9ICcnO1xuICAgICAgfVxuICAgICAgcmVzb2x1dGlvblRhYmxlLnB1c2goe29iajogcHJvcGVydHksIHJlc29sdmVBczogJ2lubGluZScsIHJvb3Q6IHJvb3QsIGtleToga2V5LCBsb2NhdGlvbjogbG9jYXRpb259KTtcbiAgICB9IGVsc2UgaWYgKHJlZi5pbmRleE9mKCcjJykgPT09IDApIHtcbiAgICAgIGxvY2F0aW9uID0gcmVmLnNwbGl0KCcjJylbMV07XG4gICAgICByZXNvbHV0aW9uVGFibGUucHVzaCh7b2JqOiBwcm9wZXJ0eSwgcmVzb2x2ZUFzOiAnaW5saW5lJywgcm9vdDogcm9vdCwga2V5OiBrZXksIGxvY2F0aW9uOiBsb2NhdGlvbn0pO1xuICAgIH0gZWxzZSBpZiAocmVmLmluZGV4T2YoJy8nKSA9PT0gMCAmJiByZWYuaW5kZXhPZignIycpID09PSAtMSkge1xuICAgICAgbG9jYXRpb24gPSByZWY7XG4gICAgICB2YXIgbWF0Y2hlcyA9IHJvb3QubWF0Y2goL15odHRwcz9cXDpcXC9cXC8oW15cXC8/I10rKSg/OltcXC8/I118JCkvaSk7XG4gICAgICBpZihtYXRjaGVzKSB7XG4gICAgICAgIHJvb3QgPSBtYXRjaGVzWzBdICsgcmVmLnN1YnN0cmluZygxKTtcbiAgICAgICAgbG9jYXRpb24gPSAnJztcbiAgICAgIH1cbiAgICAgIHJlc29sdXRpb25UYWJsZS5wdXNoKHtvYmo6IHByb3BlcnR5LCByZXNvbHZlQXM6ICdpbmxpbmUnLCByb290OiByb290LCBrZXk6IGtleSwgbG9jYXRpb246IGxvY2F0aW9ufSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgcmVzb2x1dGlvblRhYmxlLnB1c2goe29iajogcHJvcGVydHksIHJlc29sdmVBczogJ2lubGluZScsIHJvb3Q6IHJvb3QsIGtleToga2V5LCBsb2NhdGlvbjogbG9jYXRpb259KTtcbiAgICB9XG4gIH1cbiAgZWxzZSBpZiAocHJvcGVydHkudHlwZSA9PT0gJ2FycmF5Jykge1xuICAgIHRoaXMucmVzb2x2ZVRvKHJvb3QsIHByb3BlcnR5Lml0ZW1zLCByZXNvbHV0aW9uVGFibGUsIGxvY2F0aW9uKTtcbiAgfVxufTtcblxuUmVzb2x2ZXIucHJvdG90eXBlLnJlc29sdmVUbyA9IGZ1bmN0aW9uIChyb290LCBwcm9wZXJ0eSwgcmVzb2x1dGlvblRhYmxlLCBsb2NhdGlvbikge1xuICB2YXIgc3AsIGk7XG4gIHZhciByZWYgPSBwcm9wZXJ0eS4kcmVmO1xuICB2YXIgbHJvb3QgPSByb290O1xuICBpZiAoKHR5cGVvZiByZWYgIT09ICd1bmRlZmluZWQnKSAmJiAocmVmICE9PSBudWxsKSkge1xuICAgIGlmKHJlZi5pbmRleE9mKCcjJykgPj0gMCkge1xuICAgICAgdmFyIHBhcnRzID0gcmVmLnNwbGl0KCcjJyk7XG5cbiAgICAgIC8vICMvZGVmaW5pdGlvbnMvZm9vXG4gICAgICAvLyBmb28uanNvbiMvYmFyXG4gICAgICBpZihwYXJ0c1swXSAmJiByZWYuaW5kZXhPZignLycpID09PSAwKSB7XG5cbiAgICAgIH1cbiAgICAgIGVsc2UgaWYocGFydHNbMF0gJiYgcGFydHNbMF0uaW5kZXhPZignaHR0cCcpID09PSAwKSB7XG4gICAgICAgIGxyb290ID0gcGFydHNbMF07XG4gICAgICAgIHJlZiA9IHBhcnRzWzFdO1xuICAgICAgfVxuICAgICAgZWxzZSBpZihwYXJ0c1swXSAmJiBwYXJ0c1swXS5sZW5ndGggPiAwKSB7XG4gICAgICAgIC8vIHJlbGF0aXZlIGZpbGVcbiAgICAgICAgc3AgPSByb290LnNwbGl0KCcvJyk7XG4gICAgICAgIGxyb290ID0gJyc7XG4gICAgICAgIGZvcihpID0gMDsgaSA8IHNwLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgICAgIGxyb290ICs9IHNwW2ldICsgJy8nO1xuICAgICAgICB9XG4gICAgICAgIGxyb290ICs9IHBhcnRzWzBdO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG5cbiAgICAgIH1cblxuICAgICAgbG9jYXRpb24gPSBwYXJ0c1sxXTtcbiAgICB9XG4gICAgZWxzZSBpZiAocmVmLmluZGV4T2YoJ2h0dHA6Ly8nKSA9PT0gMCB8fCByZWYuaW5kZXhPZignaHR0cHM6Ly8nKSA9PT0gMCkge1xuICAgICAgbHJvb3QgPSByZWY7XG4gICAgICBsb2NhdGlvbiA9ICcnO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIC8vIHJlbGF0aXZlIGZpbGVcbiAgICAgIHNwID0gcm9vdC5zcGxpdCgnLycpO1xuICAgICAgbHJvb3QgPSAnJztcbiAgICAgIGZvcihpID0gMDsgaSA8IHNwLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgICBscm9vdCArPSBzcFtpXSArICcvJztcbiAgICAgIH1cbiAgICAgIGxyb290ICs9IHJlZjtcbiAgICAgIGxvY2F0aW9uID0gJyc7XG4gICAgfVxuICAgIHJlc29sdXRpb25UYWJsZS5wdXNoKHtcbiAgICAgIG9iajogcHJvcGVydHksIHJlc29sdmVBczogJ3JlZicsIHJvb3Q6IGxyb290LCBrZXk6IHJlZiwgbG9jYXRpb246IGxvY2F0aW9uXG4gICAgfSk7XG4gIH0gZWxzZSBpZiAocHJvcGVydHkudHlwZSA9PT0gJ2FycmF5Jykge1xuICAgIHZhciBpdGVtcyA9IHByb3BlcnR5Lml0ZW1zO1xuICAgIHRoaXMucmVzb2x2ZVRvKHJvb3QsIGl0ZW1zLCByZXNvbHV0aW9uVGFibGUsIGxvY2F0aW9uKTtcbiAgfSBlbHNlIHtcbiAgICBpZihwcm9wZXJ0eSAmJiBwcm9wZXJ0eS5wcm9wZXJ0aWVzKSB7XG4gICAgICB2YXIgbmFtZSA9IHRoaXMudW5pcXVlTmFtZSgnaW5saW5lX21vZGVsJyk7XG4gICAgICBpZiAocHJvcGVydHkudGl0bGUpIHtcbiAgICAgICAgbmFtZSA9IHRoaXMudW5pcXVlTmFtZShwcm9wZXJ0eS50aXRsZSk7XG4gICAgICB9XG4gICAgICBkZWxldGUgcHJvcGVydHkudGl0bGU7XG4gICAgICB0aGlzLnNwZWMuZGVmaW5pdGlvbnNbbmFtZV0gPSBfLmNsb25lRGVlcChwcm9wZXJ0eSk7XG4gICAgICBwcm9wZXJ0eVsnJHJlZiddID0gJyMvZGVmaW5pdGlvbnMvJyArIG5hbWU7XG4gICAgICBkZWxldGUgcHJvcGVydHkudHlwZTtcbiAgICAgIGRlbGV0ZSBwcm9wZXJ0eS5wcm9wZXJ0aWVzO1xuICAgIH1cbiAgfVxufTtcblxuUmVzb2x2ZXIucHJvdG90eXBlLnVuaXF1ZU5hbWUgPSBmdW5jdGlvbihiYXNlKSB7XG4gIHZhciBuYW1lID0gYmFzZTtcbiAgdmFyIGNvdW50ID0gMDtcbiAgd2hpbGUodHJ1ZSkge1xuICAgIGlmKCFfLmlzT2JqZWN0KHRoaXMuc3BlYy5kZWZpbml0aW9uc1tuYW1lXSkpIHtcbiAgICAgIHJldHVybiBuYW1lO1xuICAgIH1cbiAgICBuYW1lID0gYmFzZSArICdfJyArIGNvdW50O1xuICAgIGNvdW50Kys7XG4gIH1cbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS5yZXNvbHZlQWxsT2YgPSBmdW5jdGlvbihzcGVjLCBvYmosIGRlcHRoKSB7XG4gIGRlcHRoID0gZGVwdGggfHwgMDtcbiAgb2JqID0gb2JqIHx8IHNwZWM7XG4gIHZhciBuYW1lO1xuICBmb3IodmFyIGtleSBpbiBvYmopIHtcbiAgICBpZiAoIW9iai5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgdmFyIGl0ZW0gPSBvYmpba2V5XTtcbiAgICBpZihpdGVtID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdTd2FnZ2VyIDIuMCBkb2VzIG5vdCBzdXBwb3J0IG51bGwgdHlwZXMgKCcgKyBvYmogKyAnKS4gIFNlZSBodHRwczovL2dpdGh1Yi5jb20vc3dhZ2dlci1hcGkvc3dhZ2dlci1zcGVjL2lzc3Vlcy8yMjkuJyk7XG4gICAgfVxuICAgIGlmKHR5cGVvZiBpdGVtID09PSAnb2JqZWN0Jykge1xuICAgICAgdGhpcy5yZXNvbHZlQWxsT2Yoc3BlYywgaXRlbSwgZGVwdGggKyAxKTtcbiAgICB9XG4gICAgaWYoaXRlbSAmJiB0eXBlb2YgaXRlbS5hbGxPZiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHZhciBhbGxPZiA9IGl0ZW0uYWxsT2Y7XG4gICAgICBpZihfLmlzQXJyYXkoYWxsT2YpKSB7XG4gICAgICAgIHZhciBvdXRwdXQgPSBfLmNsb25lRGVlcChpdGVtKTtcbiAgICAgICAgZGVsZXRlIG91dHB1dC5hbGxPZjtcblxuICAgICAgICBvdXRwdXRbJ3gtY29tcG9zZWQnXSA9IHRydWU7XG4gICAgICAgIGlmICh0eXBlb2YgaXRlbVsneC1yZXNvbHZlZC1mcm9tJ10gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgb3V0cHV0Wyd4LXJlc29sdmVkLWZyb20nXSA9IGl0ZW1bJ3gtcmVzb2x2ZWQtZnJvbSddO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yKHZhciBpID0gMDsgaSA8IGFsbE9mLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdmFyIGNvbXBvbmVudCA9IGFsbE9mW2ldO1xuICAgICAgICAgIHZhciBzb3VyY2UgPSAnc2VsZic7XG4gICAgICAgICAgaWYodHlwZW9mIGNvbXBvbmVudFsneC1yZXNvbHZlZC1mcm9tJ10gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBzb3VyY2UgPSBjb21wb25lbnRbJ3gtcmVzb2x2ZWQtZnJvbSddWzBdO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGZvcih2YXIgcGFydCBpbiBjb21wb25lbnQpIHtcbiAgICAgICAgICAgIGlmKCFvdXRwdXQuaGFzT3duUHJvcGVydHkocGFydCkpIHtcbiAgICAgICAgICAgICAgb3V0cHV0W3BhcnRdID0gXy5jbG9uZURlZXAoY29tcG9uZW50W3BhcnRdKTtcbiAgICAgICAgICAgICAgaWYocGFydCA9PT0gJ3Byb3BlcnRpZXMnKSB7XG4gICAgICAgICAgICAgICAgZm9yKG5hbWUgaW4gb3V0cHV0W3BhcnRdKSB7XG4gICAgICAgICAgICAgICAgICBvdXRwdXRbcGFydF1bbmFtZV1bJ3gtcmVzb2x2ZWQtZnJvbSddID0gc291cmNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgIGlmKHBhcnQgPT09ICdwcm9wZXJ0aWVzJykge1xuICAgICAgICAgICAgICAgIHZhciBwcm9wZXJ0aWVzID0gY29tcG9uZW50W3BhcnRdO1xuICAgICAgICAgICAgICAgIGZvcihuYW1lIGluIHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgICAgICAgIG91dHB1dC5wcm9wZXJ0aWVzW25hbWVdID0gXy5jbG9uZURlZXAocHJvcGVydGllc1tuYW1lXSk7XG4gICAgICAgICAgICAgICAgICB2YXIgcmVzb2x2ZWRGcm9tID0gcHJvcGVydGllc1tuYW1lXVsneC1yZXNvbHZlZC1mcm9tJ107XG4gICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHJlc29sdmVkRnJvbSA9PT0gJ3VuZGVmaW5lZCcgfHwgcmVzb2x2ZWRGcm9tID09PSAnc2VsZicpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZWRGcm9tID0gc291cmNlO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgb3V0cHV0LnByb3BlcnRpZXNbbmFtZV1bJ3gtcmVzb2x2ZWQtZnJvbSddID0gcmVzb2x2ZWRGcm9tO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBlbHNlIGlmKHBhcnQgPT09ICdyZXF1aXJlZCcpIHtcbiAgICAgICAgICAgICAgICAvLyBtZXJnZSAmIGRlZHVwIHRoZSByZXF1aXJlZCBhcnJheVxuICAgICAgICAgICAgICAgIHZhciBhID0gb3V0cHV0LnJlcXVpcmVkLmNvbmNhdChjb21wb25lbnRbcGFydF0pO1xuICAgICAgICAgICAgICAgIGZvcih2YXIgayA9IDA7IGsgPCBhLmxlbmd0aDsgKytrKSB7XG4gICAgICAgICAgICAgICAgICBmb3IodmFyIGogPSBrICsgMTsgaiA8IGEubGVuZ3RoOyArK2opIHtcbiAgICAgICAgICAgICAgICAgICAgaWYoYVtrXSA9PT0gYVtqXSkgeyBhLnNwbGljZShqLS0sIDEpOyB9XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG91dHB1dC5yZXF1aXJlZCA9IGE7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZWxzZSBpZihwYXJ0ID09PSAneC1yZXNvbHZlZC1mcm9tJykge1xuICAgICAgICAgICAgICAgIG91dHB1dFsneC1yZXNvbHZlZC1mcm9tJ10ucHVzaChzb3VyY2UpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFRPRE86IG5lZWQgdG8gbWVyZ2UgdGhpcyBwcm9wZXJ0eVxuICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCd3aGF0IHRvIGRvIHdpdGggJyArIHBhcnQpXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgb2JqW2tleV0gPSBvdXRwdXQ7XG4gICAgICB9XG4gICAgfVxuICB9XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgSGVscGVycyA9IHJlcXVpcmUoJy4vaGVscGVycycpO1xuXG52YXIgXyA9IHtcbiAgaXNQbGFpbk9iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzUGxhaW5PYmplY3QnKSxcbiAgaXNVbmRlZmluZWQ6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc1VuZGVmaW5lZCcpLFxuICBpc0FycmF5OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNBcnJheScpLFxuICBpc09iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzT2JqZWN0JyksXG4gIGlzRW1wdHk6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc0VtcHR5JyksXG4gIG1hcDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL21hcCcpLFxuICBpbmRleE9mOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2FycmF5L2luZGV4T2YnKSxcbiAgY2xvbmVEZWVwOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvY2xvbmVEZWVwJyksXG4gIGtleXM6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvb2JqZWN0L2tleXMnKSxcbiAgZm9yRWFjaDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2ZvckVhY2gnKVxufTtcblxubW9kdWxlLmV4cG9ydHMub3B0aW9uSHRtbCA9IG9wdGlvbkh0bWw7XG5tb2R1bGUuZXhwb3J0cy50eXBlRnJvbUpzb25TY2hlbWEgPSB0eXBlRnJvbUpzb25TY2hlbWE7XG5tb2R1bGUuZXhwb3J0cy5nZXRTdHJpbmdTaWduYXR1cmUgPSBnZXRTdHJpbmdTaWduYXR1cmU7XG5tb2R1bGUuZXhwb3J0cy5zY2hlbWFUb0hUTUwgPSBzY2hlbWFUb0hUTUw7XG5tb2R1bGUuZXhwb3J0cy5zY2hlbWFUb0pTT04gPSBzY2hlbWFUb0pTT047XG5cbmZ1bmN0aW9uIG9wdGlvbkh0bWwobGFiZWwsIHZhbHVlKSB7XG4gIHJldHVybiAnPHRyPjx0ZCBjbGFzcz1cIm9wdGlvbk5hbWVcIj4nICsgbGFiZWwgKyAnOjwvdGQ+PHRkPicgKyB2YWx1ZSArICc8L3RkPjwvdHI+Jztcbn1cblxuZnVuY3Rpb24gdHlwZUZyb21Kc29uU2NoZW1hKHR5cGUsIGZvcm1hdCkge1xuICB2YXIgc3RyO1xuXG4gIGlmICh0eXBlID09PSAnaW50ZWdlcicgJiYgZm9ybWF0ID09PSAnaW50MzInKSB7XG4gICAgc3RyID0gJ2ludGVnZXInO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdpbnRlZ2VyJyAmJiBmb3JtYXQgPT09ICdpbnQ2NCcpIHtcbiAgICBzdHIgPSAnbG9uZyc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2ludGVnZXInICYmIHR5cGVvZiBmb3JtYXQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgc3RyID0gJ2xvbmcnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdzdHJpbmcnICYmIGZvcm1hdCA9PT0gJ2RhdGUtdGltZScpIHtcbiAgICBzdHIgPSAnZGF0ZS10aW1lJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnc3RyaW5nJyAmJiBmb3JtYXQgPT09ICdkYXRlJykge1xuICAgIHN0ciA9ICdkYXRlJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJyAmJiBmb3JtYXQgPT09ICdmbG9hdCcpIHtcbiAgICBzdHIgPSAnZmxvYXQnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdudW1iZXInICYmIGZvcm1hdCA9PT0gJ2RvdWJsZScpIHtcbiAgICBzdHIgPSAnZG91YmxlJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJyAmJiB0eXBlb2YgZm9ybWF0ID09PSAndW5kZWZpbmVkJykge1xuICAgIHN0ciA9ICdkb3VibGUnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdib29sZWFuJykge1xuICAgIHN0ciA9ICdib29sZWFuJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgIHN0ciA9ICdzdHJpbmcnO1xuICB9XG5cbiAgcmV0dXJuIHN0cjtcbn1cblxuZnVuY3Rpb24gZ2V0U3RyaW5nU2lnbmF0dXJlKG9iaiwgYmFzZUNvbXBvbmVudCkge1xuICB2YXIgc3RyID0gJyc7XG5cbiAgaWYgKHR5cGVvZiBvYmouJHJlZiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBzdHIgKz0gSGVscGVycy5zaW1wbGVSZWYob2JqLiRyZWYpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBvYmoudHlwZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBzdHIgKz0gJ29iamVjdCc7XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdhcnJheScpIHtcbiAgICBpZiAoYmFzZUNvbXBvbmVudCkge1xuICAgICAgc3RyICs9IGdldFN0cmluZ1NpZ25hdHVyZSgob2JqLml0ZW1zIHx8IG9iai4kcmVmIHx8IHt9KSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ciArPSAnQXJyYXlbJztcbiAgICAgIHN0ciArPSBnZXRTdHJpbmdTaWduYXR1cmUoKG9iai5pdGVtcyB8fCBvYmouJHJlZiB8fCB7fSkpO1xuICAgICAgc3RyICs9ICddJztcbiAgICB9XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdpbnRlZ2VyJyAmJiBvYmouZm9ybWF0ID09PSAnaW50MzInKSB7XG4gICAgc3RyICs9ICdpbnRlZ2VyJztcbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ2ludGVnZXInICYmIG9iai5mb3JtYXQgPT09ICdpbnQ2NCcpIHtcbiAgICBzdHIgKz0gJ2xvbmcnO1xuICB9IGVsc2UgaWYgKG9iai50eXBlID09PSAnaW50ZWdlcicgJiYgdHlwZW9mIG9iai5mb3JtYXQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgc3RyICs9ICdsb25nJztcbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ3N0cmluZycgJiYgb2JqLmZvcm1hdCA9PT0gJ2RhdGUtdGltZScpIHtcbiAgICBzdHIgKz0gJ2RhdGUtdGltZSc7XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdzdHJpbmcnICYmIG9iai5mb3JtYXQgPT09ICdkYXRlJykge1xuICAgIHN0ciArPSAnZGF0ZSc7XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdzdHJpbmcnICYmIHR5cGVvZiBvYmouZm9ybWF0ID09PSAndW5kZWZpbmVkJykge1xuICAgIHN0ciArPSAnc3RyaW5nJztcbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ251bWJlcicgJiYgb2JqLmZvcm1hdCA9PT0gJ2Zsb2F0Jykge1xuICAgIHN0ciArPSAnZmxvYXQnO1xuICB9IGVsc2UgaWYgKG9iai50eXBlID09PSAnbnVtYmVyJyAmJiBvYmouZm9ybWF0ID09PSAnZG91YmxlJykge1xuICAgIHN0ciArPSAnZG91YmxlJztcbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ251bWJlcicgJiYgdHlwZW9mIG9iai5mb3JtYXQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgc3RyICs9ICdkb3VibGUnO1xuICB9IGVsc2UgaWYgKG9iai50eXBlID09PSAnYm9vbGVhbicpIHtcbiAgICBzdHIgKz0gJ2Jvb2xlYW4nO1xuICB9IGVsc2UgaWYgKG9iai4kcmVmKSB7XG4gICAgc3RyICs9IEhlbHBlcnMuc2ltcGxlUmVmKG9iai4kcmVmKTtcbiAgfSBlbHNlIHtcbiAgICBzdHIgKz0gb2JqLnR5cGU7XG4gIH1cblxuICByZXR1cm4gc3RyO1xufVxuXG5mdW5jdGlvbiBzY2hlbWFUb0pTT04oc2NoZW1hLCBtb2RlbHMsIG1vZGVsc1RvSWdub3JlLCBtb2RlbFByb3BlcnR5TWFjcm8pIHtcbiAgLy8gUmVzb2x2ZSB0aGUgc2NoZW1hIChIYW5kbGUgbmVzdGVkIHNjaGVtYXMpXG4gIHNjaGVtYSA9IEhlbHBlcnMucmVzb2x2ZVNjaGVtYShzY2hlbWEpO1xuXG4gIGlmKHR5cGVvZiBtb2RlbFByb3BlcnR5TWFjcm8gIT09ICdmdW5jdGlvbicpIHtcbiAgICBtb2RlbFByb3BlcnR5TWFjcm8gPSBmdW5jdGlvbihwcm9wKXtcbiAgICAgIHJldHVybiAocHJvcCB8fCB7fSkuZGVmYXVsdDtcbiAgICB9O1xuICB9XG5cbiAgbW9kZWxzVG9JZ25vcmU9IG1vZGVsc1RvSWdub3JlIHx8IHt9O1xuXG4gIHZhciB0eXBlID0gc2NoZW1hLnR5cGUgfHwgJ29iamVjdCc7XG4gIHZhciBmb3JtYXQgPSBzY2hlbWEuZm9ybWF0O1xuICB2YXIgbW9kZWw7XG4gIHZhciBvdXRwdXQ7XG5cbiAgaWYgKCFfLmlzVW5kZWZpbmVkKHNjaGVtYS5leGFtcGxlKSkge1xuICAgIG91dHB1dCA9IHNjaGVtYS5leGFtcGxlO1xuICB9IGVsc2UgaWYgKF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zKSAmJiBfLmlzQXJyYXkoc2NoZW1hLmVudW0pKSB7XG4gICAgb3V0cHV0ID0gc2NoZW1hLmVudW1bMF07XG4gIH1cblxuICBpZiAoXy5pc1VuZGVmaW5lZChvdXRwdXQpKSB7XG4gICAgaWYgKHNjaGVtYS4kcmVmKSB7XG4gICAgICBtb2RlbCA9IG1vZGVsc1tIZWxwZXJzLnNpbXBsZVJlZihzY2hlbWEuJHJlZildO1xuXG4gICAgICBpZiAoIV8uaXNVbmRlZmluZWQobW9kZWwpKSB7XG4gICAgICAgIGlmIChfLmlzVW5kZWZpbmVkKG1vZGVsc1RvSWdub3JlW21vZGVsLm5hbWVdKSkge1xuICAgICAgICAgIG1vZGVsc1RvSWdub3JlW21vZGVsLm5hbWVdID0gbW9kZWw7XG4gICAgICAgICAgb3V0cHV0ID0gc2NoZW1hVG9KU09OKG1vZGVsLmRlZmluaXRpb24sIG1vZGVscywgbW9kZWxzVG9JZ25vcmUsIG1vZGVsUHJvcGVydHlNYWNybyk7XG4gICAgICAgICAgZGVsZXRlIG1vZGVsc1RvSWdub3JlW21vZGVsLm5hbWVdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChtb2RlbC50eXBlID09PSAnYXJyYXknKSB7XG4gICAgICAgICAgICBvdXRwdXQgPSBbXTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgb3V0cHV0ID0ge307XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICghXy5pc1VuZGVmaW5lZChzY2hlbWEuZGVmYXVsdCkpIHtcbiAgICAgIG91dHB1dCA9IHNjaGVtYS5kZWZhdWx0O1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGlmIChmb3JtYXQgPT09ICdkYXRlLXRpbWUnKSB7XG4gICAgICAgIG91dHB1dCA9IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKTtcbiAgICAgIH0gZWxzZSBpZiAoZm9ybWF0ID09PSAnZGF0ZScpIHtcbiAgICAgICAgb3V0cHV0ID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpLnNwbGl0KCdUJylbMF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvdXRwdXQgPSAnc3RyaW5nJztcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdpbnRlZ2VyJykge1xuICAgICAgb3V0cHV0ID0gMDtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdudW1iZXInKSB7XG4gICAgICBvdXRwdXQgPSAwLjA7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnYm9vbGVhbicpIHtcbiAgICAgIG91dHB1dCA9IHRydWU7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnb2JqZWN0Jykge1xuICAgICAgb3V0cHV0ID0ge307XG5cbiAgICAgIF8uZm9yRWFjaChzY2hlbWEucHJvcGVydGllcywgZnVuY3Rpb24gKHByb3BlcnR5LCBuYW1lKSB7XG4gICAgICAgIHZhciBjUHJvcGVydHkgPSBfLmNsb25lRGVlcChwcm9wZXJ0eSk7XG5cbiAgICAgICAgLy8gQWxsb3cgbWFjcm8gdG8gc2V0IHRoZSBkZWZhdWx0IHZhbHVlXG4gICAgICAgIGNQcm9wZXJ0eS5kZWZhdWx0ID0gbW9kZWxQcm9wZXJ0eU1hY3JvKHByb3BlcnR5KTtcblxuICAgICAgICBvdXRwdXRbbmFtZV0gPSBzY2hlbWFUb0pTT04oY1Byb3BlcnR5LCBtb2RlbHMsIG1vZGVsc1RvSWdub3JlLCBtb2RlbFByb3BlcnR5TWFjcm8pO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnYXJyYXknKSB7XG4gICAgICBvdXRwdXQgPSBbXTtcblxuICAgICAgaWYgKF8uaXNBcnJheShzY2hlbWEuaXRlbXMpKSB7XG4gICAgICAgIF8uZm9yRWFjaChzY2hlbWEuaXRlbXMsIGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgb3V0cHV0LnB1c2goc2NoZW1hVG9KU09OKGl0ZW0sIG1vZGVscywgbW9kZWxzVG9JZ25vcmUsIG1vZGVsUHJvcGVydHlNYWNybykpO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgb3V0cHV0LnB1c2goc2NoZW1hVG9KU09OKHNjaGVtYS5pdGVtcywgbW9kZWxzLCBtb2RlbHNUb0lnbm9yZSwgbW9kZWxQcm9wZXJ0eU1hY3JvKSk7XG4gICAgICB9IGVsc2UgaWYgKF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICBvdXRwdXQucHVzaCh7fSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBIZWxwZXJzLmxvZygnQXJyYXkgdHlwZVxcJ3MgXFwnaXRlbXNcXCcgcHJvcGVydHkgaXMgbm90IGFuIGFycmF5IG9yIGFuIG9iamVjdCwgY2Fubm90IHByb2Nlc3MnKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gb3V0cHV0O1xufVxuXG5mdW5jdGlvbiBzY2hlbWFUb0hUTUwobmFtZSwgc2NoZW1hLCBtb2RlbHMsIG1vZGVsUHJvcGVydHlNYWNybykge1xuXG4gIHZhciBzdHJvbmdPcGVuID0gJzxzcGFuIGNsYXNzPVwic3Ryb25nXCI+JztcbiAgdmFyIHN0cm9uZ0Nsb3NlID0gJzwvc3Bhbj4nO1xuXG4gIC8vIEFsbG93IGZvciBpZ25vcmluZyB0aGUgJ25hbWUnIGFyZ3VtZW50Li4uLiBzaGlmdGluZyB0aGUgcmVzdFxuICBpZihfLmlzT2JqZWN0KGFyZ3VtZW50c1swXSkpIHtcbiAgICBuYW1lID0gdm9pZCAwO1xuICAgIHNjaGVtYSA9IGFyZ3VtZW50c1swXTtcbiAgICBtb2RlbHMgPSBhcmd1bWVudHNbMV07XG4gICAgbW9kZWxQcm9wZXJ0eU1hY3JvID0gYXJndW1lbnRzWzJdO1xuICB9XG5cbiAgbW9kZWxzID0gbW9kZWxzIHx8IHt9O1xuXG4gIC8vIFJlc29sdmUgdGhlIHNjaGVtYSAoSGFuZGxlIG5lc3RlZCBzY2hlbWFzKVxuICBzY2hlbWEgPSBIZWxwZXJzLnJlc29sdmVTY2hlbWEoc2NoZW1hKTtcblxuICAvLyBSZXR1cm4gZm9yIGVtcHR5IG9iamVjdFxuICBpZihfLmlzRW1wdHkoc2NoZW1hKSkge1xuICAgIHJldHVybiBzdHJvbmdPcGVuICsgJ0VtcHR5JyArIHN0cm9uZ0Nsb3NlO1xuICB9XG5cbiAgLy8gRGVyZWZlcmVuY2UgJHJlZiBmcm9tICdtb2RlbHMnXG4gIGlmKHR5cGVvZiBzY2hlbWEuJHJlZiA9PT0gJ3N0cmluZycpIHtcbiAgICBuYW1lID0gSGVscGVycy5zaW1wbGVSZWYoc2NoZW1hLiRyZWYpO1xuICAgIHNjaGVtYSA9IG1vZGVsc1tuYW1lXTtcbiAgICBpZih0eXBlb2Ygc2NoZW1hID09PSAndW5kZWZpbmVkJylcbiAgICB7XG4gICAgICByZXR1cm4gc3Ryb25nT3BlbiArIG5hbWUgKyAnIGlzIG5vdCBkZWZpbmVkIScgKyBzdHJvbmdDbG9zZTtcbiAgICB9XG4gIH1cblxuICBpZih0eXBlb2YgbmFtZSAhPT0gJ3N0cmluZycpIHtcbiAgICBuYW1lID0gc2NoZW1hLnRpdGxlIHx8ICdJbmxpbmUgTW9kZWwnO1xuICB9XG5cbiAgLy8gSWYgd2UgYXJlIGEgTW9kZWwgb2JqZWN0Li4uIGFkanVzdCBhY2NvcmRpbmdseVxuICBpZihzY2hlbWEuZGVmaW5pdGlvbikge1xuICAgIHNjaGVtYSA9IHNjaGVtYS5kZWZpbml0aW9uO1xuICB9XG5cbiAgaWYodHlwZW9mIG1vZGVsUHJvcGVydHlNYWNybyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIG1vZGVsUHJvcGVydHlNYWNybyA9IGZ1bmN0aW9uKHByb3Ape1xuICAgICAgcmV0dXJuIChwcm9wIHx8IHt9KS5kZWZhdWx0O1xuICAgIH07XG4gIH1cblxuICB2YXIgcmVmZXJlbmNlcyA9IHt9O1xuICB2YXIgc2Vlbk1vZGVscyA9IFtdO1xuICB2YXIgaW5saW5lTW9kZWxzID0gMDtcblxuXG5cbiAgLy8gR2VuZXJhdGUgY3VycmVudCBIVE1MXG4gIHZhciBodG1sID0gcHJvY2Vzc01vZGVsKHNjaGVtYSwgbmFtZSk7XG5cbiAgLy8gR2VuZXJhdGUgcmVmZXJlbmNlcyBIVE1MXG4gIHdoaWxlIChfLmtleXMocmVmZXJlbmNlcykubGVuZ3RoID4gMCkge1xuICAgIC8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cbiAgICBfLmZvckVhY2gocmVmZXJlbmNlcywgZnVuY3Rpb24gKHNjaGVtYSwgbmFtZSkge1xuICAgICAgdmFyIHNlZW5Nb2RlbCA9IF8uaW5kZXhPZihzZWVuTW9kZWxzLCBuYW1lKSA+IC0xO1xuXG4gICAgICBkZWxldGUgcmVmZXJlbmNlc1tuYW1lXTtcblxuICAgICAgaWYgKCFzZWVuTW9kZWwpIHtcbiAgICAgICAgc2Vlbk1vZGVscy5wdXNoKG5hbWUpO1xuXG4gICAgICAgIGh0bWwgKz0gJzxiciAvPicgKyBwcm9jZXNzTW9kZWwoc2NoZW1hLCBuYW1lKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICAvKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuICB9XG5cbiAgcmV0dXJuIGh0bWw7XG5cbiAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbiAgZnVuY3Rpb24gYWRkUmVmZXJlbmNlKHNjaGVtYSwgbmFtZSwgc2tpcFJlZikge1xuICAgIHZhciBtb2RlbE5hbWUgPSBuYW1lO1xuICAgIHZhciBtb2RlbDtcblxuICAgIGlmIChzY2hlbWEuJHJlZikge1xuICAgICAgbW9kZWxOYW1lID0gc2NoZW1hLnRpdGxlIHx8IEhlbHBlcnMuc2ltcGxlUmVmKHNjaGVtYS4kcmVmKTtcbiAgICAgIG1vZGVsID0gbW9kZWxzW21vZGVsTmFtZV07XG4gICAgfSBlbHNlIGlmIChfLmlzVW5kZWZpbmVkKG5hbWUpKSB7XG4gICAgICBtb2RlbE5hbWUgPSBzY2hlbWEudGl0bGUgfHwgJ0lubGluZSBNb2RlbCAnICsgKCsraW5saW5lTW9kZWxzKTtcbiAgICAgIG1vZGVsID0ge2RlZmluaXRpb246IHNjaGVtYX07XG4gICAgfVxuXG4gICAgaWYgKHNraXBSZWYgIT09IHRydWUpIHtcbiAgICAgIHJlZmVyZW5jZXNbbW9kZWxOYW1lXSA9IF8uaXNVbmRlZmluZWQobW9kZWwpID8ge30gOiBtb2RlbC5kZWZpbml0aW9uO1xuICAgIH1cblxuICAgIHJldHVybiBtb2RlbE5hbWU7XG4gIH1cblxuICBmdW5jdGlvbiBwcmltaXRpdmVUb0hUTUwoc2NoZW1hKSB7XG4gICAgdmFyIGh0bWwgPSAnPHNwYW4gY2xhc3M9XCJwcm9wVHlwZVwiPic7XG4gICAgdmFyIHR5cGUgPSBzY2hlbWEudHlwZSB8fCAnb2JqZWN0JztcblxuICAgIGlmIChzY2hlbWEuJHJlZikge1xuICAgICAgaHRtbCArPSBhZGRSZWZlcmVuY2Uoc2NoZW1hLCBIZWxwZXJzLnNpbXBsZVJlZihzY2hlbWEuJHJlZikpO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGlmICghXy5pc1VuZGVmaW5lZChzY2hlbWEucHJvcGVydGllcykpIHtcbiAgICAgICAgaHRtbCArPSBhZGRSZWZlcmVuY2Uoc2NoZW1hKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGh0bWwgKz0gJ29iamVjdCc7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnYXJyYXknKSB7XG4gICAgICBodG1sICs9ICdBcnJheVsnO1xuXG4gICAgICBpZiAoXy5pc0FycmF5KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgaHRtbCArPSBfLm1hcChzY2hlbWEuaXRlbXMsIGFkZFJlZmVyZW5jZSkuam9pbignLCcpO1xuICAgICAgfSBlbHNlIGlmIChfLmlzUGxhaW5PYmplY3Qoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICBpZiAoXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMuJHJlZikpIHtcbiAgICAgICAgICBpZiAoIV8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zLnR5cGUpICYmIF8uaW5kZXhPZihbJ2FycmF5JywgJ29iamVjdCddLCBzY2hlbWEuaXRlbXMudHlwZSkgPT09IC0xKSB7XG4gICAgICAgICAgICBodG1sICs9IHNjaGVtYS5pdGVtcy50eXBlO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBodG1sICs9IGFkZFJlZmVyZW5jZShzY2hlbWEuaXRlbXMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBodG1sICs9IGFkZFJlZmVyZW5jZShzY2hlbWEuaXRlbXMsIEhlbHBlcnMuc2ltcGxlUmVmKHNjaGVtYS5pdGVtcy4kcmVmKSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIEhlbHBlcnMubG9nKCdBcnJheSB0eXBlXFwncyBcXCdpdGVtc1xcJyBzY2hlbWEgaXMgbm90IGFuIGFycmF5IG9yIGFuIG9iamVjdCwgY2Fubm90IHByb2Nlc3MnKTtcbiAgICAgICAgaHRtbCArPSAnb2JqZWN0JztcbiAgICAgIH1cblxuICAgICAgaHRtbCArPSAnXSc7XG4gICAgfSBlbHNlIHtcbiAgICAgIGh0bWwgKz0gc2NoZW1hLnR5cGU7XG4gICAgfVxuXG4gICAgaHRtbCArPSAnPC9zcGFuPic7XG5cbiAgICByZXR1cm4gaHRtbDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHByaW1pdGl2ZVRvT3B0aW9uc0hUTUwoc2NoZW1hLCBodG1sKSB7XG4gICAgdmFyIG9wdGlvbnMgPSAnJztcbiAgICB2YXIgdHlwZSA9IHNjaGVtYS50eXBlIHx8ICdvYmplY3QnO1xuICAgIHZhciBpc0FycmF5ID0gdHlwZSA9PT0gJ2FycmF5JztcblxuICAgIGlmIChpc0FycmF5KSB7XG4gICAgICBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5pdGVtcykgJiYgIV8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zLnR5cGUpKSB7XG4gICAgICAgIHR5cGUgPSBzY2hlbWEuaXRlbXMudHlwZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHR5cGUgPSAnb2JqZWN0JztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIV8uaXNVbmRlZmluZWQoc2NoZW1hLmRlZmF1bHQpKSB7XG4gICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ0RlZmF1bHQnLCBzY2hlbWEuZGVmYXVsdCk7XG4gICAgfVxuXG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSAnc3RyaW5nJzpcbiAgICAgIGlmIChzY2hlbWEubWluTGVuZ3RoKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnTWluLiBMZW5ndGgnLCBzY2hlbWEubWluTGVuZ3RoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjaGVtYS5tYXhMZW5ndGgpIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdNYXguIExlbmd0aCcsIHNjaGVtYS5tYXhMZW5ndGgpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLnBhdHRlcm4pIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdSZWcuIEV4cC4nLCBzY2hlbWEucGF0dGVybik7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICBjYXNlICdpbnRlZ2VyJzpcbiAgICBjYXNlICdudW1iZXInOlxuICAgICAgaWYgKHNjaGVtYS5taW5pbXVtKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnTWluLiBWYWx1ZScsIHNjaGVtYS5taW5pbXVtKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjaGVtYS5leGNsdXNpdmVNaW5pbXVtKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnRXhjbHVzaXZlIE1pbi4nLCAndHJ1ZScpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLm1heGltdW0pIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdNYXguIFZhbHVlJywgc2NoZW1hLm1heGltdW0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLmV4Y2x1c2l2ZU1heGltdW0pIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdFeGNsdXNpdmUgTWF4LicsICd0cnVlJyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2hlbWEubXVsdGlwbGVPZikge1xuICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ011bHRpcGxlIE9mJywgc2NoZW1hLm11bHRpcGxlT2YpO1xuICAgICAgfVxuXG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBpZiAoaXNBcnJheSkge1xuICAgICAgaWYgKHNjaGVtYS5taW5JdGVtcykge1xuICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ01pbi4gSXRlbXMnLCBzY2hlbWEubWluSXRlbXMpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLm1heEl0ZW1zKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnTWF4LiBJdGVtcycsIHNjaGVtYS5tYXhJdGVtcyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2hlbWEudW5pcXVlSXRlbXMpIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdVbmlxdWUgSXRlbXMnLCAndHJ1ZScpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLmNvbGxlY3Rpb25Gb3JtYXQpIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdDb2xsLiBGb3JtYXQnLCBzY2hlbWEuY29sbGVjdGlvbkZvcm1hdCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgaWYgKF8uaXNBcnJheShzY2hlbWEuZW51bSkpIHtcbiAgICAgICAgdmFyIGVudW1TdHJpbmc7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdudW1iZXInIHx8IHR5cGUgPT09ICdpbnRlZ2VyJykge1xuICAgICAgICAgIGVudW1TdHJpbmcgPSBzY2hlbWEuZW51bS5qb2luKCcsICcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVudW1TdHJpbmcgPSAnXCInICsgc2NoZW1hLmVudW0uam9pbignXCIsIFwiJykgKyAnXCInO1xuICAgICAgICB9XG5cbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdFbnVtJywgZW51bVN0cmluZyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMubGVuZ3RoID4gMCkge1xuICAgICAgaHRtbCA9ICc8c3BhbiBjbGFzcz1cInByb3BXcmFwXCI+JyArIGh0bWwgKyAnPHRhYmxlIGNsYXNzPVwib3B0aW9uc1dyYXBwZXJcIj48dHI+PHRoIGNvbHNwYW49XCIyXCI+JyArIHR5cGUgKyAnPC90aD48L3RyPicgKyBvcHRpb25zICsgJzwvdGFibGU+PC9zcGFuPic7XG4gICAgfVxuXG4gICAgcmV0dXJuIGh0bWw7XG4gIH1cblxuICBmdW5jdGlvbiBwcm9jZXNzTW9kZWwoc2NoZW1hLCBuYW1lKSB7XG4gICAgdmFyIHR5cGUgPSBzY2hlbWEudHlwZSB8fCAnb2JqZWN0JztcbiAgICB2YXIgaXNBcnJheSA9IHNjaGVtYS50eXBlID09PSAnYXJyYXknO1xuICAgIHZhciBodG1sID0gc3Ryb25nT3BlbiArIG5hbWUgKyAnICcgKyAoaXNBcnJheSA/ICdbJyA6ICd7JykgKyBzdHJvbmdDbG9zZTtcblxuICAgIGlmIChuYW1lKSB7XG4gICAgICBzZWVuTW9kZWxzLnB1c2gobmFtZSk7XG4gICAgfVxuXG4gICAgaWYgKGlzQXJyYXkpIHtcbiAgICAgIGlmIChfLmlzQXJyYXkoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICBodG1sICs9ICc8ZGl2PicgKyBfLm1hcChzY2hlbWEuaXRlbXMsIGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgdmFyIHR5cGUgPSBpdGVtLnR5cGUgfHwgJ29iamVjdCc7XG5cbiAgICAgICAgICBpZiAoXy5pc1VuZGVmaW5lZChpdGVtLiRyZWYpKSB7XG4gICAgICAgICAgICBpZiAoXy5pbmRleE9mKFsnYXJyYXknLCAnb2JqZWN0J10sIHR5cGUpID4gLTEpIHtcbiAgICAgICAgICAgICAgaWYgKHR5cGUgPT09ICdvYmplY3QnICYmIF8uaXNVbmRlZmluZWQoaXRlbS5wcm9wZXJ0aWVzKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiAnb2JqZWN0JztcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYWRkUmVmZXJlbmNlKGl0ZW0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXR1cm4gcHJpbWl0aXZlVG9PcHRpb25zSFRNTChpdGVtLCB0eXBlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGFkZFJlZmVyZW5jZShpdGVtLCBIZWxwZXJzLnNpbXBsZVJlZihpdGVtLiRyZWYpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pLmpvaW4oJyw8L2Rpdj48ZGl2PicpO1xuICAgICAgfSBlbHNlIGlmIChfLmlzUGxhaW5PYmplY3Qoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICBpZiAoXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMuJHJlZikpIHtcbiAgICAgICAgICBpZiAoXy5pbmRleE9mKFsnYXJyYXknLCAnb2JqZWN0J10sIHNjaGVtYS5pdGVtcy50eXBlIHx8ICdvYmplY3QnKSA+IC0xKSB7XG4gICAgICAgICAgICBpZiAoKF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zLnR5cGUpIHx8IHNjaGVtYS5pdGVtcy50eXBlID09PSAnb2JqZWN0JykgJiYgXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMucHJvcGVydGllcykpIHtcbiAgICAgICAgICAgICAgaHRtbCArPSAnPGRpdj5vYmplY3Q8L2Rpdj4nO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgaHRtbCArPSAnPGRpdj4nICsgYWRkUmVmZXJlbmNlKHNjaGVtYS5pdGVtcykgKyAnPC9kaXY+JztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaHRtbCArPSAnPGRpdj4nICsgcHJpbWl0aXZlVG9PcHRpb25zSFRNTChzY2hlbWEuaXRlbXMsIHNjaGVtYS5pdGVtcy50eXBlKSArICc8L2Rpdj4nO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBodG1sICs9ICc8ZGl2PicgKyBhZGRSZWZlcmVuY2Uoc2NoZW1hLml0ZW1zLCBIZWxwZXJzLnNpbXBsZVJlZihzY2hlbWEuaXRlbXMuJHJlZikpICsgJzwvZGl2Pic7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIEhlbHBlcnMubG9nKCdBcnJheSB0eXBlXFwncyBcXCdpdGVtc1xcJyBwcm9wZXJ0eSBpcyBub3QgYW4gYXJyYXkgb3IgYW4gb2JqZWN0LCBjYW5ub3QgcHJvY2VzcycpO1xuICAgICAgICBodG1sICs9ICc8ZGl2Pm9iamVjdDwvZGl2Pic7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChzY2hlbWEuJHJlZikge1xuICAgICAgICBodG1sICs9ICc8ZGl2PicgKyBhZGRSZWZlcmVuY2Uoc2NoZW1hLCBuYW1lKSArICc8L2Rpdj4nO1xuICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnb2JqZWN0Jykge1xuICAgICAgICBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5wcm9wZXJ0aWVzKSkge1xuICAgICAgICAgIHZhciBjb250ZW50cyA9IF8ubWFwKHNjaGVtYS5wcm9wZXJ0aWVzLCBmdW5jdGlvbiAocHJvcGVydHksIG5hbWUpIHtcbiAgICAgICAgICAgIHZhciBwcm9wZXJ0eUlzUmVxdWlyZWQgPSAoXy5pbmRleE9mKHNjaGVtYS5yZXF1aXJlZCwgbmFtZSkgPj0gMCk7XG4gICAgICAgICAgICB2YXIgY1Byb3BlcnR5ID0gXy5jbG9uZURlZXAocHJvcGVydHkpO1xuXG4gICAgICAgICAgICB2YXIgcmVxdWlyZWRDbGFzcyA9IHByb3BlcnR5SXNSZXF1aXJlZCA/ICdyZXF1aXJlZCcgOiAnJztcbiAgICAgICAgICAgIHZhciBodG1sID0gJzxzcGFuIGNsYXNzPVwicHJvcE5hbWUgJyArIHJlcXVpcmVkQ2xhc3MgKyAnXCI+JyArIG5hbWUgKyAnPC9zcGFuPiAoJztcbiAgICAgICAgICAgIHZhciBtb2RlbDtcbiAgICAgICAgICAgIHZhciBwcm9wRGVzY3JpcHRpb247XG5cbiAgICAgICAgICAgIC8vIEFsbG93IG1hY3JvIHRvIHNldCB0aGUgZGVmYXVsdCB2YWx1ZVxuICAgICAgICAgICAgY1Byb3BlcnR5LmRlZmF1bHQgPSBtb2RlbFByb3BlcnR5TWFjcm8oY1Byb3BlcnR5KTtcblxuICAgICAgICAgICAgLy8gUmVzb2x2ZSB0aGUgc2NoZW1hIChIYW5kbGUgbmVzdGVkIHNjaGVtYXMpXG4gICAgICAgICAgICBjUHJvcGVydHkgPSBIZWxwZXJzLnJlc29sdmVTY2hlbWEoY1Byb3BlcnR5KTtcblxuICAgICAgICAgICAgcHJvcERlc2NyaXB0aW9uID0gcHJvcGVydHkuZGVzY3JpcHRpb24gfHwgY1Byb3BlcnR5LmRlc2NyaXB0aW9uO1xuXG4gICAgICAgICAgICAvLyBXZSBuZWVkIHRvIGhhbmRsZSBwcm9wZXJ0eSByZWZlcmVuY2VzIHRvIHByaW1pdGl2ZXMgKElzc3VlIDMzOSlcbiAgICAgICAgICAgIGlmICghXy5pc1VuZGVmaW5lZChjUHJvcGVydHkuJHJlZikpIHtcbiAgICAgICAgICAgICAgbW9kZWwgPSBtb2RlbHNbSGVscGVycy5zaW1wbGVSZWYoY1Byb3BlcnR5LiRyZWYpXTtcblxuICAgICAgICAgICAgICBpZiAoIV8uaXNVbmRlZmluZWQobW9kZWwpICYmIF8uaW5kZXhPZihbdW5kZWZpbmVkLCAnYXJyYXknLCAnb2JqZWN0J10sIG1vZGVsLmRlZmluaXRpb24udHlwZSkgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgLy8gVXNlIHJlZmVyZW5jZWQgc2NoZW1hXG4gICAgICAgICAgICAgICAgY1Byb3BlcnR5ID0gSGVscGVycy5yZXNvbHZlU2NoZW1hKG1vZGVsLmRlZmluaXRpb24pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGh0bWwgKz0gcHJpbWl0aXZlVG9IVE1MKGNQcm9wZXJ0eSk7XG5cbiAgICAgICAgICAgIGlmKCFwcm9wZXJ0eUlzUmVxdWlyZWQpIHtcbiAgICAgICAgICAgICAgaHRtbCArPSAnLCA8c3BhbiBjbGFzcz1cInByb3BPcHRLZXlcIj5vcHRpb25hbDwvc3Bhbj4nO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZihwcm9wZXJ0eS5yZWFkT25seSkge1xuICAgICAgICAgICAgICAgIGh0bWwgKz0gJywgPHNwYW4gY2xhc3M9XCJwcm9wUmVhZE9ubHlcIj5yZWFkIG9ubHk8L3NwYW4+JztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaHRtbCArPSAnKSc7XG5cbiAgICAgICAgICAgIGlmICghXy5pc1VuZGVmaW5lZChwcm9wRGVzY3JpcHRpb24pKSB7XG4gICAgICAgICAgICAgIGh0bWwgKz0gJzogJyArICc8c3BhbiBjbGFzcz1cInByb3BEZXNjXCI+JyArIHByb3BEZXNjcmlwdGlvbiArICc8L3NwYW4+JztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGNQcm9wZXJ0eS5lbnVtKSB7XG4gICAgICAgICAgICAgIGh0bWwgKz0gJyA9IDxzcGFuIGNsYXNzPVwicHJvcFZhbHNcIj5bXFwnJyArIGNQcm9wZXJ0eS5lbnVtLmpvaW4oJ1xcJywgXFwnJykgKyAnXFwnXTwvc3Bhbj4nO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gJzxkaXYnICsgKHByb3BlcnR5LnJlYWRPbmx5ID8gJyBjbGFzcz1cInJlYWRPbmx5XCInIDogJycpICsgJz4nICsgcHJpbWl0aXZlVG9PcHRpb25zSFRNTChjUHJvcGVydHksIGh0bWwpO1xuICAgICAgICAgIH0pLmpvaW4oJyw8L2Rpdj4nKTtcblxuICAgICAgICAgIGlmIChjb250ZW50cykge1xuICAgICAgICAgICAgaHRtbCArPSBjb250ZW50cyArICc8L2Rpdj4nO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaHRtbCArPSAnPGRpdj4nICsgcHJpbWl0aXZlVG9PcHRpb25zSFRNTChzY2hlbWEsIHR5cGUpICsgJzwvZGl2Pic7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGh0bWwgKyBzdHJvbmdPcGVuICsgKGlzQXJyYXkgPyAnXScgOiAnfScpICsgc3Ryb25nQ2xvc2U7XG4gIH1cbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFN3YWdnZXJIdHRwID0gcmVxdWlyZSgnLi9odHRwJyk7XG52YXIgXyA9IHtcbiAgaXNPYmplY3Q6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc09iamVjdCcpXG59O1xuXG52YXIgU3dhZ2dlclNwZWNDb252ZXJ0ZXIgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5lcnJvcnMgPSBbXTtcbiAgdGhpcy53YXJuaW5ncyA9IFtdO1xuICB0aGlzLm1vZGVsTWFwID0ge307XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuc2V0RG9jdW1lbnRhdGlvbkxvY2F0aW9uID0gZnVuY3Rpb24gKGxvY2F0aW9uKSB7XG4gIHRoaXMuZG9jTG9jYXRpb24gPSBsb2NhdGlvbjtcbn07XG5cbi8qKlxuICogY29udmVydHMgYSByZXNvdXJjZSBsaXN0aW5nIE9SIGFwaSBkZWNsYXJhdGlvblxuICoqL1xuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLmNvbnZlcnQgPSBmdW5jdGlvbiAob2JqLCBjbGllbnRBdXRob3JpemF0aW9ucywgb3B0cywgY2FsbGJhY2spIHtcbiAgLy8gbm90IGEgdmFsaWQgc3BlY1xuICBpZighb2JqIHx8ICFBcnJheS5pc0FycmF5KG9iai5hcGlzKSkge1xuICAgIHJldHVybiB0aGlzLmZpbmlzaChjYWxsYmFjaywgbnVsbCk7XG4gIH1cbiAgdGhpcy5jbGllbnRBdXRob3JpemF0aW9ucyA9IGNsaWVudEF1dGhvcml6YXRpb25zO1xuXG4gIC8vIGNyZWF0ZSBhIG5ldyBzd2FnZ2VyIG9iamVjdCB0byByZXR1cm5cbiAgdmFyIHN3YWdnZXIgPSB7IHN3YWdnZXI6ICcyLjAnIH07XG5cbiAgc3dhZ2dlci5vcmlnaW5hbFZlcnNpb24gPSBvYmouc3dhZ2dlclZlcnNpb247XG5cbiAgLy8gYWRkIHRoZSBpbmZvXG4gIHRoaXMuYXBpSW5mbyhvYmosIHN3YWdnZXIpO1xuXG4gIC8vIGFkZCBzZWN1cml0eSBkZWZpbml0aW9uc1xuICB0aGlzLnNlY3VyaXR5RGVmaW5pdGlvbnMob2JqLCBzd2FnZ2VyKTtcblxuICAvLyB0YWtlIGJhc2VQYXRoIGludG8gYWNjb3VudFxuICBpZiAob2JqLmJhc2VQYXRoKSB7XG4gICAgdGhpcy5zZXREb2N1bWVudGF0aW9uTG9jYXRpb24ob2JqLmJhc2VQYXRoKTtcbiAgfVxuXG4gIC8vIHNlZSBpZiB0aGlzIGlzIGEgc2luZ2xlLWZpbGUgc3dhZ2dlciBkZWZpbml0aW9uXG4gIHZhciBpc1NpbmdsZUZpbGVTd2FnZ2VyID0gZmFsc2U7XG4gIHZhciBpO1xuICBmb3IoaSA9IDA7IGkgPCBvYmouYXBpcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBhcGkgPSBvYmouYXBpc1tpXTtcbiAgICBpZihBcnJheS5pc0FycmF5KGFwaS5vcGVyYXRpb25zKSkge1xuICAgICAgaXNTaW5nbGVGaWxlU3dhZ2dlciA9IHRydWU7XG4gICAgfVxuICB9XG4gIGlmKGlzU2luZ2xlRmlsZVN3YWdnZXIpIHtcbiAgICB0aGlzLmRlY2xhcmF0aW9uKG9iaiwgc3dhZ2dlcik7XG4gICAgdGhpcy5maW5pc2goY2FsbGJhY2ssIHN3YWdnZXIpO1xuICB9XG4gIGVsc2Uge1xuICAgIHRoaXMucmVzb3VyY2VMaXN0aW5nKG9iaiwgc3dhZ2dlciwgb3B0cywgY2FsbGJhY2spO1xuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuZGVjbGFyYXRpb24gPSBmdW5jdGlvbihvYmosIHN3YWdnZXIpIHtcbiAgdmFyIG5hbWUsIGksIHAsIHBvcztcbiAgaWYoIW9iai5hcGlzKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKG9iai5iYXNlUGF0aC5pbmRleE9mKCdodHRwOi8vJykgPT09IDApIHtcbiAgICBwID0gb2JqLmJhc2VQYXRoLnN1YnN0cmluZygnaHR0cDovLycubGVuZ3RoKTtcbiAgICBwb3MgPSBwLmluZGV4T2YoJy8nKTtcbiAgICBpZiAocG9zID4gMCkge1xuICAgICAgc3dhZ2dlci5ob3N0ID0gcC5zdWJzdHJpbmcoMCwgcG9zKTtcbiAgICAgIHN3YWdnZXIuYmFzZVBhdGggPSBwLnN1YnN0cmluZyhwb3MpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHN3YWdnZXIuaG9zdCA9IHA7XG4gICAgICBzd2FnZ2VyLmJhc2VQYXRoID0gJy8nO1xuICAgIH1cbiAgfSBlbHNlIGlmIChvYmouYmFzZVBhdGguaW5kZXhPZignaHR0cHM6Ly8nKSA9PT0gMCkge1xuICAgIHAgPSBvYmouYmFzZVBhdGguc3Vic3RyaW5nKCdodHRwczovLycubGVuZ3RoKTtcbiAgICBwb3MgPSBwLmluZGV4T2YoJy8nKTtcbiAgICBpZiAocG9zID4gMCkge1xuICAgICAgc3dhZ2dlci5ob3N0ID0gcC5zdWJzdHJpbmcoMCwgcG9zKTtcbiAgICAgIHN3YWdnZXIuYmFzZVBhdGggPSBwLnN1YnN0cmluZyhwb3MpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHN3YWdnZXIuaG9zdCA9IHA7XG4gICAgICBzd2FnZ2VyLmJhc2VQYXRoID0gJy8nO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBzd2FnZ2VyLmJhc2VQYXRoID0gb2JqLmJhc2VQYXRoO1xuICB9XG5cbiAgdmFyIHJlc291cmNlTGV2ZWxBdXRoO1xuICBpZihvYmouYXV0aG9yaXphdGlvbnMpIHtcbiAgICByZXNvdXJjZUxldmVsQXV0aCA9IG9iai5hdXRob3JpemF0aW9ucztcbiAgfVxuICBpZihvYmouY29uc3VtZXMpIHtcbiAgICBzd2FnZ2VyLmNvbnN1bWVzID0gb2JqLmNvbnN1bWVzO1xuICB9XG4gIGlmKG9iai5wcm9kdWNlcykge1xuICAgIHN3YWdnZXIucHJvZHVjZXMgPSBvYmoucHJvZHVjZXM7XG4gIH1cblxuICAvLyBidWlsZCBhIG1hcHBpbmcgb2YgaWQgdG8gbmFtZSBmb3IgMS4wIG1vZGVsIHJlc29sdXRpb25zXG4gIGlmKF8uaXNPYmplY3Qob2JqKSkge1xuICAgIGZvcihuYW1lIGluIG9iai5tb2RlbHMpIHtcbiAgICAgIHZhciBleGlzdGluZ01vZGVsID0gb2JqLm1vZGVsc1tuYW1lXTtcbiAgICAgIHZhciBrZXkgPSAoZXhpc3RpbmdNb2RlbC5pZCB8fCBuYW1lKTtcbiAgICAgIHRoaXMubW9kZWxNYXBba2V5XSA9IG5hbWU7XG4gICAgfVxuICB9XG5cbiAgZm9yKGkgPSAwOyBpIDwgb2JqLmFwaXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgYXBpID0gb2JqLmFwaXNbaV07XG4gICAgdmFyIHBhdGggPSBhcGkucGF0aDtcbiAgICB2YXIgb3BlcmF0aW9ucyA9IGFwaS5vcGVyYXRpb25zO1xuICAgIHRoaXMub3BlcmF0aW9ucyhwYXRoLCBvYmoucmVzb3VyY2VQYXRoLCBvcGVyYXRpb25zLCByZXNvdXJjZUxldmVsQXV0aCwgc3dhZ2dlcik7XG4gIH1cblxuICB2YXIgbW9kZWxzID0gb2JqLm1vZGVscyB8fCB7fTtcbiAgdGhpcy5tb2RlbHMobW9kZWxzLCBzd2FnZ2VyKTtcbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5tb2RlbHMgPSBmdW5jdGlvbihvYmosIHN3YWdnZXIpIHtcbiAgaWYoIV8uaXNPYmplY3Qob2JqKSkge1xuICAgIHJldHVybjtcbiAgfVxuICB2YXIgbmFtZTtcblxuICBzd2FnZ2VyLmRlZmluaXRpb25zID0gc3dhZ2dlci5kZWZpbml0aW9ucyB8fCB7fTtcbiAgZm9yKG5hbWUgaW4gb2JqKSB7XG4gICAgdmFyIGV4aXN0aW5nTW9kZWwgPSBvYmpbbmFtZV07XG4gICAgdmFyIF9yZXF1aXJlZCA9IFtdO1xuICAgIHZhciBzY2hlbWEgPSB7IHByb3BlcnRpZXM6IHt9fTtcbiAgICB2YXIgcHJvcGVydHlOYW1lO1xuICAgIGZvcihwcm9wZXJ0eU5hbWUgaW4gZXhpc3RpbmdNb2RlbC5wcm9wZXJ0aWVzKSB7XG4gICAgICB2YXIgZXhpc3RpbmdQcm9wZXJ0eSA9IGV4aXN0aW5nTW9kZWwucHJvcGVydGllc1twcm9wZXJ0eU5hbWVdO1xuICAgICAgdmFyIHByb3BlcnR5ID0ge307XG4gICAgICB0aGlzLmRhdGFUeXBlKGV4aXN0aW5nUHJvcGVydHksIHByb3BlcnR5KTtcbiAgICAgIGlmKGV4aXN0aW5nUHJvcGVydHkuZGVzY3JpcHRpb24pIHtcbiAgICAgICAgcHJvcGVydHkuZGVzY3JpcHRpb24gPSBleGlzdGluZ1Byb3BlcnR5LmRlc2NyaXB0aW9uO1xuICAgICAgfVxuICAgICAgaWYoZXhpc3RpbmdQcm9wZXJ0eVsnZW51bSddKSB7XG4gICAgICAgIHByb3BlcnR5WydlbnVtJ10gPSBleGlzdGluZ1Byb3BlcnR5WydlbnVtJ107XG4gICAgICB9XG4gICAgICBpZih0eXBlb2YgZXhpc3RpbmdQcm9wZXJ0eS5yZXF1aXJlZCA9PT0gJ2Jvb2xlYW4nICYmIGV4aXN0aW5nUHJvcGVydHkucmVxdWlyZWQgPT09IHRydWUpIHtcbiAgICAgICAgX3JlcXVpcmVkLnB1c2gocHJvcGVydHlOYW1lKTtcbiAgICAgIH1cbiAgICAgIGlmKHR5cGVvZiBleGlzdGluZ1Byb3BlcnR5LnJlcXVpcmVkID09PSAnc3RyaW5nJyAmJiBleGlzdGluZ1Byb3BlcnR5LnJlcXVpcmVkID09PSAndHJ1ZScpIHtcbiAgICAgICAgX3JlcXVpcmVkLnB1c2gocHJvcGVydHlOYW1lKTtcbiAgICAgIH1cbiAgICAgIHNjaGVtYS5wcm9wZXJ0aWVzW3Byb3BlcnR5TmFtZV0gPSBwcm9wZXJ0eTtcbiAgICB9XG4gICAgaWYoX3JlcXVpcmVkLmxlbmd0aCA+IDApIHtcbiAgICAgIHNjaGVtYS5yZXF1aXJlZCA9IF9yZXF1aXJlZDtcbiAgICB9IGVsc2Uge1xuICAgICAgc2NoZW1hLnJlcXVpcmVkID0gZXhpc3RpbmdNb2RlbC5yZXF1aXJlZDtcbiAgICB9XG4gICAgc3dhZ2dlci5kZWZpbml0aW9uc1tuYW1lXSA9IHNjaGVtYTtcbiAgfVxufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLmV4dHJhY3RUYWcgPSBmdW5jdGlvbihyZXNvdXJjZVBhdGgpIHtcbiAgdmFyIHBhdGhTdHJpbmcgPSByZXNvdXJjZVBhdGggfHwgJ2RlZmF1bHQnO1xuICBpZihwYXRoU3RyaW5nLmluZGV4T2YoJ2h0dHA6JykgPT09IDAgfHwgcGF0aFN0cmluZy5pbmRleE9mKCdodHRwczonKSA9PT0gMCkge1xuICAgIHBhdGhTdHJpbmcgPSBwYXRoU3RyaW5nLnNwbGl0KFsnLyddKTtcbiAgICBwYXRoU3RyaW5nID0gcGF0aFN0cmluZ1twYXRoU3RyaW5nLmxlbmd0aCAtMV0uc3Vic3RyaW5nKCk7XG4gIH1cbiAgaWYocGF0aFN0cmluZy5lbmRzV2l0aCgnLmpzb24nKSkge1xuICAgIHBhdGhTdHJpbmcgPSBwYXRoU3RyaW5nLnN1YnN0cmluZygwLCBwYXRoU3RyaW5nLmxlbmd0aCAtICcuanNvbicubGVuZ3RoKTtcbiAgfVxuICByZXR1cm4gcGF0aFN0cmluZy5yZXBsYWNlKCcvJywnJyk7XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUub3BlcmF0aW9ucyA9IGZ1bmN0aW9uKHBhdGgsIHJlc291cmNlUGF0aCwgb2JqLCByZXNvdXJjZUxldmVsQXV0aCwgc3dhZ2dlcikge1xuICBpZighQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciBpO1xuXG4gIGlmKCFzd2FnZ2VyLnBhdGhzKSB7XG4gICAgc3dhZ2dlci5wYXRocyA9IHt9O1xuICB9XG5cbiAgdmFyIHBhdGhPYmogPSBzd2FnZ2VyLnBhdGhzW3BhdGhdIHx8IHt9O1xuICB2YXIgdGFnID0gdGhpcy5leHRyYWN0VGFnKHJlc291cmNlUGF0aCk7XG4gIHN3YWdnZXIudGFncyA9IHN3YWdnZXIudGFncyB8fCBbXTtcbiAgdmFyIG1hdGNoZWQgPSBmYWxzZTtcbiAgZm9yKGkgPSAwOyBpIDwgc3dhZ2dlci50YWdzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHRhZ09iamVjdCA9IHN3YWdnZXIudGFnc1tpXTtcbiAgICBpZih0YWdPYmplY3QubmFtZSA9PT0gdGFnKSB7XG4gICAgICBtYXRjaGVkID0gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgaWYoIW1hdGNoZWQpIHtcbiAgICBzd2FnZ2VyLnRhZ3MucHVzaCh7bmFtZTogdGFnfSk7XG4gIH1cblxuICBmb3IoaSA9IDA7IGkgPCBvYmoubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZXhpc3RpbmdPcGVyYXRpb24gPSBvYmpbaV07XG4gICAgdmFyIG1ldGhvZCA9IChleGlzdGluZ09wZXJhdGlvbi5tZXRob2QgfHwgZXhpc3RpbmdPcGVyYXRpb24uaHR0cE1ldGhvZCkudG9Mb3dlckNhc2UoKTtcbiAgICB2YXIgb3BlcmF0aW9uID0ge3RhZ3M6IFt0YWddfTtcbiAgICB2YXIgZXhpc3RpbmdBdXRob3JpemF0aW9ucyA9IGV4aXN0aW5nT3BlcmF0aW9uLmF1dGhvcml6YXRpb25zO1xuXG4gICAgaWYoZXhpc3RpbmdBdXRob3JpemF0aW9ucyAmJiBPYmplY3Qua2V5cyhleGlzdGluZ0F1dGhvcml6YXRpb25zKS5sZW5ndGggPT09IDApIHtcbiAgICAgIGV4aXN0aW5nQXV0aG9yaXphdGlvbnMgPSByZXNvdXJjZUxldmVsQXV0aDtcbiAgICB9XG5cbiAgICBpZih0eXBlb2YgZXhpc3RpbmdBdXRob3JpemF0aW9ucyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHZhciBzY29wZXNPYmplY3Q7XG4gICAgICBmb3IodmFyIGtleSBpbiBleGlzdGluZ0F1dGhvcml6YXRpb25zKSB7XG4gICAgICAgIG9wZXJhdGlvbi5zZWN1cml0eSA9IG9wZXJhdGlvbi5zZWN1cml0eSB8fCBbXTtcbiAgICAgICAgdmFyIHNjb3BlcyA9IGV4aXN0aW5nQXV0aG9yaXphdGlvbnNba2V5XTtcbiAgICAgICAgaWYoc2NvcGVzKSB7XG4gICAgICAgICAgdmFyIHNlY3VyaXR5U2NvcGVzID0gW107XG4gICAgICAgICAgZm9yKHZhciBqIGluIHNjb3Blcykge1xuICAgICAgICAgICAgc2VjdXJpdHlTY29wZXMucHVzaChzY29wZXNbal0uc2NvcGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBzY29wZXNPYmplY3QgPSB7fTtcbiAgICAgICAgICBzY29wZXNPYmplY3Rba2V5XSA9IHNlY3VyaXR5U2NvcGVzO1xuICAgICAgICAgIG9wZXJhdGlvbi5zZWN1cml0eS5wdXNoKHNjb3Blc09iamVjdCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgc2NvcGVzT2JqZWN0ID0ge307XG4gICAgICAgICAgc2NvcGVzT2JqZWN0W2tleV0gPSBbXTtcbiAgICAgICAgICBvcGVyYXRpb24uc2VjdXJpdHkucHVzaChzY29wZXNPYmplY3QpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYoZXhpc3RpbmdPcGVyYXRpb24uY29uc3VtZXMpIHtcbiAgICAgIG9wZXJhdGlvbi5jb25zdW1lcyA9IGV4aXN0aW5nT3BlcmF0aW9uLmNvbnN1bWVzO1xuICAgIH1cbiAgICBlbHNlIGlmKHN3YWdnZXIuY29uc3VtZXMpIHtcbiAgICAgIG9wZXJhdGlvbi5jb25zdW1lcyA9IHN3YWdnZXIuY29uc3VtZXM7XG4gICAgfVxuICAgIGlmKGV4aXN0aW5nT3BlcmF0aW9uLnByb2R1Y2VzKSB7XG4gICAgICBvcGVyYXRpb24ucHJvZHVjZXMgPSBleGlzdGluZ09wZXJhdGlvbi5wcm9kdWNlcztcbiAgICB9XG4gICAgZWxzZSBpZihzd2FnZ2VyLnByb2R1Y2VzKSB7XG4gICAgICBvcGVyYXRpb24ucHJvZHVjZXMgPSBzd2FnZ2VyLnByb2R1Y2VzO1xuICAgIH1cbiAgICBpZihleGlzdGluZ09wZXJhdGlvbi5zdW1tYXJ5KSB7XG4gICAgICBvcGVyYXRpb24uc3VtbWFyeSA9IGV4aXN0aW5nT3BlcmF0aW9uLnN1bW1hcnk7XG4gICAgfVxuICAgIGlmKGV4aXN0aW5nT3BlcmF0aW9uLm5vdGVzKSB7XG4gICAgICBvcGVyYXRpb24uZGVzY3JpcHRpb24gPSBleGlzdGluZ09wZXJhdGlvbi5ub3RlcztcbiAgICB9XG4gICAgaWYoZXhpc3RpbmdPcGVyYXRpb24ubmlja25hbWUpIHtcbiAgICAgIG9wZXJhdGlvbi5vcGVyYXRpb25JZCA9IGV4aXN0aW5nT3BlcmF0aW9uLm5pY2tuYW1lO1xuICAgIH1cbiAgICBpZihleGlzdGluZ09wZXJhdGlvbi5kZXByZWNhdGVkKSB7XG4gICAgICBvcGVyYXRpb24uZGVwcmVjYXRlZCA9IGV4aXN0aW5nT3BlcmF0aW9uLmRlcHJlY2F0ZWQ7XG4gICAgfVxuXG4gICAgdGhpcy5hdXRob3JpemF0aW9ucyhleGlzdGluZ0F1dGhvcml6YXRpb25zLCBzd2FnZ2VyKTtcbiAgICB0aGlzLnBhcmFtZXRlcnMob3BlcmF0aW9uLCBleGlzdGluZ09wZXJhdGlvbi5wYXJhbWV0ZXJzLCBzd2FnZ2VyKTtcbiAgICB0aGlzLnJlc3BvbnNlTWVzc2FnZXMob3BlcmF0aW9uLCBleGlzdGluZ09wZXJhdGlvbiwgc3dhZ2dlcik7XG5cbiAgICBwYXRoT2JqW21ldGhvZF0gPSBvcGVyYXRpb247XG4gIH1cblxuICBzd2FnZ2VyLnBhdGhzW3BhdGhdID0gcGF0aE9iajtcbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5yZXNwb25zZU1lc3NhZ2VzID0gZnVuY3Rpb24ob3BlcmF0aW9uLCBleGlzdGluZ09wZXJhdGlvbikge1xuICBpZighXy5pc09iamVjdChleGlzdGluZ09wZXJhdGlvbikpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgLy8gYnVpbGQgZGVmYXVsdCByZXNwb25zZSBmcm9tIHRoZSBvcGVyYXRpb24gKDEueClcbiAgdmFyIGRlZmF1bHRSZXNwb25zZSA9IHt9O1xuICB0aGlzLmRhdGFUeXBlKGV4aXN0aW5nT3BlcmF0aW9uLCBkZWZhdWx0UmVzcG9uc2UpO1xuICAvLyBUT0RPOiBsb29rIGludG8gdGhlIHJlYWwgcHJvYmxlbSBvZiByZW5kZXJpbmcgcmVzcG9uc2VzIGluIHN3YWdnZXItdWlcbiAgLy8gLi4uLnNob3VsZCByZXBvbnNlVHlwZSBoYXZlIGFuIGltcGxpY2l0IHNjaGVtYT9cbiAgaWYoIWRlZmF1bHRSZXNwb25zZS5zY2hlbWEgJiYgZGVmYXVsdFJlc3BvbnNlLnR5cGUpIHtcbiAgICBkZWZhdWx0UmVzcG9uc2UgPSB7c2NoZW1hOiBkZWZhdWx0UmVzcG9uc2V9O1xuICB9XG5cbiAgb3BlcmF0aW9uLnJlc3BvbnNlcyA9IG9wZXJhdGlvbi5yZXNwb25zZXMgfHwge307XG5cbiAgLy8gZ3JhYiBmcm9tIHJlc3BvbnNlTWVzc2FnZXMgKDEuMilcbiAgdmFyIGhhczIwMCA9IGZhbHNlO1xuICBpZihBcnJheS5pc0FycmF5KGV4aXN0aW5nT3BlcmF0aW9uLnJlc3BvbnNlTWVzc2FnZXMpKSB7XG4gICAgdmFyIGk7XG4gICAgdmFyIGV4aXN0aW5nUmVzcG9uc2VzID0gZXhpc3RpbmdPcGVyYXRpb24ucmVzcG9uc2VNZXNzYWdlcztcbiAgICBmb3IoaSA9IDA7IGkgPCBleGlzdGluZ1Jlc3BvbnNlcy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGV4aXN0aW5nUmVzcG9uc2UgPSBleGlzdGluZ1Jlc3BvbnNlc1tpXTtcbiAgICAgIHZhciByZXNwb25zZSA9IHsgZGVzY3JpcHRpb246IGV4aXN0aW5nUmVzcG9uc2UubWVzc2FnZSB9O1xuICAgICAgaWYoZXhpc3RpbmdSZXNwb25zZS5jb2RlID09PSAyMDApIHtcbiAgICAgICAgaGFzMjAwID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIC8vIENvbnZlcnQgcmVzcG9uc2VNb2RlbCAtPiBzY2hlbWF7JHJlZjogcmVzcG9uc2VNb2RlbH1cbiAgICAgIGlmKGV4aXN0aW5nUmVzcG9uc2UucmVzcG9uc2VNb2RlbCkge1xuICAgICAgICByZXNwb25zZS5zY2hlbWEgPSB7JyRyZWYnOiAnIy9kZWZpbml0aW9ucy8nICsgZXhpc3RpbmdSZXNwb25zZS5yZXNwb25zZU1vZGVsfTtcbiAgICAgIH1cbiAgICAgIG9wZXJhdGlvbi5yZXNwb25zZXNbJycgKyBleGlzdGluZ1Jlc3BvbnNlLmNvZGVdID0gcmVzcG9uc2U7XG4gICAgfVxuICB9XG5cbiAgaWYoaGFzMjAwKSB7XG4gICAgb3BlcmF0aW9uLnJlc3BvbnNlc1snZGVmYXVsdCddID0gZGVmYXVsdFJlc3BvbnNlO1xuICB9XG4gIGVsc2Uge1xuICAgIG9wZXJhdGlvbi5yZXNwb25zZXNbJzIwMCddID0gZGVmYXVsdFJlc3BvbnNlO1xuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuYXV0aG9yaXphdGlvbnMgPSBmdW5jdGlvbihvYmopIHtcbiAgLy8gVE9ET1xuICBpZighXy5pc09iamVjdChvYmopKSB7XG4gICAgcmV0dXJuO1xuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUucGFyYW1ldGVycyA9IGZ1bmN0aW9uKG9wZXJhdGlvbiwgb2JqKSB7XG4gIGlmKCFBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgdmFyIGk7XG4gIGZvcihpID0gMDsgaSA8IG9iai5sZW5ndGg7IGkrKykge1xuICAgIHZhciBleGlzdGluZ1BhcmFtZXRlciA9IG9ialtpXTtcbiAgICB2YXIgcGFyYW1ldGVyID0ge307XG4gICAgcGFyYW1ldGVyLm5hbWUgPSBleGlzdGluZ1BhcmFtZXRlci5uYW1lO1xuICAgIHBhcmFtZXRlci5kZXNjcmlwdGlvbiA9IGV4aXN0aW5nUGFyYW1ldGVyLmRlc2NyaXB0aW9uO1xuICAgIHBhcmFtZXRlci5yZXF1aXJlZCA9IGV4aXN0aW5nUGFyYW1ldGVyLnJlcXVpcmVkO1xuICAgIHBhcmFtZXRlci5pbiA9IGV4aXN0aW5nUGFyYW1ldGVyLnBhcmFtVHlwZTtcblxuICAgIC8vIHBlciAjMTY4XG4gICAgaWYocGFyYW1ldGVyLmluID09PSAnYm9keScpIHtcbiAgICAgIHBhcmFtZXRlci5uYW1lID0gJ2JvZHknO1xuICAgIH1cbiAgICBpZihwYXJhbWV0ZXIuaW4gPT09ICdmb3JtJykge1xuICAgICAgcGFyYW1ldGVyLmluID0gJ2Zvcm1EYXRhJztcbiAgICB9XG5cbiAgICBpZihleGlzdGluZ1BhcmFtZXRlci5lbnVtKSB7XG4gICAgICBwYXJhbWV0ZXIuZW51bSA9IGV4aXN0aW5nUGFyYW1ldGVyLmVudW07XG4gICAgfVxuXG4gICAgaWYoZXhpc3RpbmdQYXJhbWV0ZXIuYWxsb3dNdWx0aXBsZSA9PT0gdHJ1ZSB8fCBleGlzdGluZ1BhcmFtZXRlci5hbGxvd011bHRpcGxlID09PSAndHJ1ZScpIHtcbiAgICAgIHZhciBpbm5lclR5cGUgPSB7fTtcbiAgICAgIHRoaXMuZGF0YVR5cGUoZXhpc3RpbmdQYXJhbWV0ZXIsIGlubmVyVHlwZSk7XG4gICAgICBwYXJhbWV0ZXIudHlwZSA9ICdhcnJheSc7XG4gICAgICBwYXJhbWV0ZXIuaXRlbXMgPSBpbm5lclR5cGU7XG5cbiAgICAgIGlmKGV4aXN0aW5nUGFyYW1ldGVyLmFsbG93YWJsZVZhbHVlcykge1xuICAgICAgICB2YXIgYXYgPSBleGlzdGluZ1BhcmFtZXRlci5hbGxvd2FibGVWYWx1ZXM7XG4gICAgICAgIGlmKGF2LnZhbHVlVHlwZSA9PT0gJ0xJU1QnKSB7XG4gICAgICAgICAgcGFyYW1ldGVyWydlbnVtJ10gPSBhdi52YWx1ZXM7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB0aGlzLmRhdGFUeXBlKGV4aXN0aW5nUGFyYW1ldGVyLCBwYXJhbWV0ZXIpO1xuICAgIH1cbiAgICBpZih0eXBlb2YgZXhpc3RpbmdQYXJhbWV0ZXIuZGVmYXVsdFZhbHVlICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgcGFyYW1ldGVyLmRlZmF1bHQgPSBleGlzdGluZ1BhcmFtZXRlci5kZWZhdWx0VmFsdWU7XG4gICAgfVxuXG4gICAgb3BlcmF0aW9uLnBhcmFtZXRlcnMgPSBvcGVyYXRpb24ucGFyYW1ldGVycyB8fCBbXTtcbiAgICBvcGVyYXRpb24ucGFyYW1ldGVycy5wdXNoKHBhcmFtZXRlcik7XG4gIH1cbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5kYXRhVHlwZSA9IGZ1bmN0aW9uKHNvdXJjZSwgdGFyZ2V0KSB7XG4gIGlmKCFfLmlzT2JqZWN0KHNvdXJjZSkpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZihzb3VyY2UubWluaW11bSkge1xuICAgIHRhcmdldC5taW5pbXVtID0gc291cmNlLm1pbmltdW07XG4gIH1cbiAgaWYoc291cmNlLm1heGltdW0pIHtcbiAgICB0YXJnZXQubWF4aW11bSA9IHNvdXJjZS5tYXhpbXVtO1xuICB9XG4gIGlmIChzb3VyY2UuZm9ybWF0KSB7XG4gICAgdGFyZ2V0LmZvcm1hdCA9IHNvdXJjZS5mb3JtYXQ7XG4gIH1cblxuICAvLyBkZWZhdWx0IGNhbiBiZSAnZmFsc2UnXG4gIGlmKHR5cGVvZiBzb3VyY2UuZGVmYXVsdFZhbHVlICE9PSAndW5kZWZpbmVkJykge1xuICAgIHRhcmdldC5kZWZhdWx0ID0gc291cmNlLmRlZmF1bHRWYWx1ZTtcbiAgfVxuXG4gIHZhciBqc29uU2NoZW1hVHlwZSA9IHRoaXMudG9Kc29uU2NoZW1hKHNvdXJjZSk7XG4gIGlmKGpzb25TY2hlbWFUeXBlKSB7XG4gICAgdGFyZ2V0ID0gdGFyZ2V0IHx8IHt9O1xuICAgIGlmKGpzb25TY2hlbWFUeXBlLnR5cGUpIHtcbiAgICAgIHRhcmdldC50eXBlID0ganNvblNjaGVtYVR5cGUudHlwZTtcbiAgICB9XG4gICAgaWYoanNvblNjaGVtYVR5cGUuZm9ybWF0KSB7XG4gICAgICB0YXJnZXQuZm9ybWF0ID0ganNvblNjaGVtYVR5cGUuZm9ybWF0O1xuICAgIH1cbiAgICBpZihqc29uU2NoZW1hVHlwZS4kcmVmKSB7XG4gICAgICB0YXJnZXQuc2NoZW1hID0geyRyZWY6IGpzb25TY2hlbWFUeXBlLiRyZWZ9O1xuICAgIH1cbiAgICBpZihqc29uU2NoZW1hVHlwZS5pdGVtcykge1xuICAgICAgdGFyZ2V0Lml0ZW1zID0ganNvblNjaGVtYVR5cGUuaXRlbXM7XG4gICAgfVxuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUudG9Kc29uU2NoZW1hID0gZnVuY3Rpb24oc291cmNlKSB7XG4gIGlmKCFzb3VyY2UpIHtcbiAgICByZXR1cm4gJ29iamVjdCc7XG4gIH1cbiAgdmFyIGRldGVjdGVkVHlwZSA9IChzb3VyY2UudHlwZSB8fCBzb3VyY2UuZGF0YVR5cGUgfHwgc291cmNlLnJlc3BvbnNlQ2xhc3MgfHwgJycpO1xuICB2YXIgbGNUeXBlID0gZGV0ZWN0ZWRUeXBlLnRvTG93ZXJDYXNlKCk7XG4gIHZhciBmb3JtYXQgPSAoc291cmNlLmZvcm1hdCB8fCAnJykudG9Mb3dlckNhc2UoKTtcblxuICBpZihsY1R5cGUuaW5kZXhPZignbGlzdFsnKSA9PT0gMCkge1xuICAgIHZhciBpbm5lclR5cGUgPSBkZXRlY3RlZFR5cGUuc3Vic3RyaW5nKDUsIGRldGVjdGVkVHlwZS5sZW5ndGggLSAxKTtcbiAgICB2YXIganNvblR5cGUgPSB0aGlzLnRvSnNvblNjaGVtYSh7dHlwZTogaW5uZXJUeXBlfSk7XG4gICAgcmV0dXJuIHt0eXBlOiAnYXJyYXknLCBpdGVtczoganNvblR5cGV9O1xuICB9IGVsc2UgaWYobGNUeXBlID09PSAnaW50JyB8fCAobGNUeXBlID09PSAnaW50ZWdlcicgJiYgZm9ybWF0ID09PSAnaW50MzInKSkge1xuICAgIHtyZXR1cm4ge3R5cGU6ICdpbnRlZ2VyJywgZm9ybWF0OiAnaW50MzInfTt9XG4gIH0gZWxzZSBpZihsY1R5cGUgPT09ICdsb25nJyB8fCAobGNUeXBlID09PSAnaW50ZWdlcicgJiYgZm9ybWF0ID09PSAnaW50NjQnKSkge1xuICAgIHtyZXR1cm4ge3R5cGU6ICdpbnRlZ2VyJywgZm9ybWF0OiAnaW50NjQnfTt9XG4gIH0gZWxzZSBpZihsY1R5cGUgPT09ICdpbnRlZ2VyJykge1xuICAgIHtyZXR1cm4ge3R5cGU6ICdpbnRlZ2VyJywgZm9ybWF0OiAnaW50NjQnfTt9XG4gIH0gZWxzZSBpZihsY1R5cGUgPT09ICdmbG9hdCcgfHwgKGxjVHlwZSA9PT0gJ251bWJlcicgJiYgZm9ybWF0ID09PSAnZmxvYXQnKSkge1xuICAgIHtyZXR1cm4ge3R5cGU6ICdudW1iZXInLCBmb3JtYXQ6ICdmbG9hdCd9O31cbiAgfSBlbHNlIGlmKGxjVHlwZSA9PT0gJ2RvdWJsZScgfHwgKGxjVHlwZSA9PT0gJ251bWJlcicgJiYgZm9ybWF0ID09PSAnZG91YmxlJykpIHtcbiAgICB7cmV0dXJuIHt0eXBlOiAnbnVtYmVyJywgZm9ybWF0OiAnZG91YmxlJ307fVxuICB9IGVsc2UgaWYoKGxjVHlwZSA9PT0gJ3N0cmluZycgJiYgZm9ybWF0ID09PSAnZGF0ZS10aW1lJykgfHwgKGxjVHlwZSA9PT0gJ2RhdGUnKSkge1xuICAgIHtyZXR1cm4ge3R5cGU6ICdzdHJpbmcnLCBmb3JtYXQ6ICdkYXRlLXRpbWUnfTt9XG4gIH0gZWxzZSBpZihsY1R5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAge3JldHVybiB7dHlwZTogJ3N0cmluZyd9O31cbiAgfSBlbHNlIGlmKGxjVHlwZSA9PT0gJ2ZpbGUnKSB7XG4gICAge3JldHVybiB7dHlwZTogJ2ZpbGUnfTt9XG4gIH0gZWxzZSBpZihsY1R5cGUgPT09ICdib29sZWFuJykge1xuICAgIHtyZXR1cm4ge3R5cGU6ICdib29sZWFuJ307fVxuICB9IGVsc2UgaWYobGNUeXBlID09PSAnYm9vbGVhbicpIHtcbiAgICB7cmV0dXJuIHt0eXBlOiAnYm9vbGVhbid9O31cbiAgfSBlbHNlIGlmKGxjVHlwZSA9PT0gJ2FycmF5JyB8fCBsY1R5cGUgPT09ICdsaXN0Jykge1xuICAgIGlmKHNvdXJjZS5pdGVtcykge1xuICAgICAgdmFyIGl0ID0gdGhpcy50b0pzb25TY2hlbWEoc291cmNlLml0ZW1zKTtcbiAgICAgIHJldHVybiB7dHlwZTogJ2FycmF5JywgaXRlbXM6IGl0fTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICByZXR1cm4ge3R5cGU6ICdhcnJheScsIGl0ZW1zOiB7dHlwZTogJ29iamVjdCd9fTtcbiAgICB9XG4gIH0gZWxzZSBpZihzb3VyY2UuJHJlZikge1xuICAgIHJldHVybiB7JHJlZjogdGhpcy5tb2RlbE1hcFtzb3VyY2UuJHJlZl0gPyAnIy9kZWZpbml0aW9ucy8nICsgdGhpcy5tb2RlbE1hcFtzb3VyY2UuJHJlZl0gOiBzb3VyY2UuJHJlZn07XG4gIH0gZWxzZSBpZihsY1R5cGUgPT09ICd2b2lkJyB8fCBsY1R5cGUgPT09ICcnKSB7XG4gICAge3JldHVybiB7fTt9XG4gIH0gZWxzZSBpZiAodGhpcy5tb2RlbE1hcFtzb3VyY2UudHlwZV0pIHtcbiAgICAvLyBJZiB0aGlzIGEgbW9kZWwgdXNpbmcgYHR5cGVgIGluc3RlYWQgb2YgYCRyZWZgLCB0aGF0J3MgZmluZS5cbiAgICByZXR1cm4geyRyZWY6ICcjL2RlZmluaXRpb25zLycgKyB0aGlzLm1vZGVsTWFwW3NvdXJjZS50eXBlXX07XG4gIH0gZWxzZSB7XG4gICAgLy8gVW5rbm93biBtb2RlbCB0eXBlIG9yICdvYmplY3QnLCBwYXNzIGl0IGFsb25nLlxuICAgIHJldHVybiB7dHlwZTogc291cmNlLnR5cGV9O1xuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUucmVzb3VyY2VMaXN0aW5nID0gZnVuY3Rpb24ob2JqLCBzd2FnZ2VyLCBvcHRzLCBjYWxsYmFjaykge1xuICB2YXIgaTtcbiAgdmFyIHByb2Nlc3NlZENvdW50ID0gMDsgICAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbiAgdmFyIHNlbGYgPSB0aGlzOyAgICAgICAgICAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbiAgdmFyIGV4cGVjdGVkQ291bnQgPSBvYmouYXBpcy5sZW5ndGg7XG4gIHZhciBfc3dhZ2dlciA9IHN3YWdnZXI7ICAgLy8ganNoaW50IGlnbm9yZTpsaW5lXG4gIHZhciBfb3B0cyA9IHt9O1xuXG4gIGlmKG9wdHMgJiYgb3B0cy5yZXF1ZXN0SW50ZXJjZXB0b3Ipe1xuICAgIF9vcHRzLnJlcXVlc3RJbnRlcmNlcHRvciA9IG9wdHMucmVxdWVzdEludGVyY2VwdG9yO1xuICB9XG5cbiAgaWYob3B0cyAmJiBvcHRzLnJlc3BvbnNlSW50ZXJjZXB0b3Ipe1xuICAgIF9vcHRzLnJlc3BvbnNlSW50ZXJjZXB0b3IgPSBvcHRzLnJlc3BvbnNlSW50ZXJjZXB0b3I7XG4gIH1cblxuICB2YXIgc3dhZ2dlclJlcXVlc3RIZWFkZXJzID0gJ2FwcGxpY2F0aW9uL2pzb24nO1xuXG4gIGlmKG9wdHMgJiYgb3B0cy5zd2FnZ2VyUmVxdWVzdEhlYWRlcnMpIHtcbiAgICBzd2FnZ2VyUmVxdWVzdEhlYWRlcnMgPSBvcHRzLnN3YWdnZXJSZXF1ZXN0SGVhZGVycztcbiAgfVxuXG4gIGlmKGV4cGVjdGVkQ291bnQgPT09IDApIHtcbiAgICB0aGlzLmZpbmlzaChjYWxsYmFjaywgc3dhZ2dlcik7XG4gIH1cblxuICBmb3IoaSA9IDA7IGkgPCBleHBlY3RlZENvdW50OyBpKyspIHtcbiAgICB2YXIgYXBpID0gb2JqLmFwaXNbaV07XG4gICAgdmFyIHBhdGggPSBhcGkucGF0aDtcbiAgICB2YXIgYWJzb2x1dGVQYXRoID0gdGhpcy5nZXRBYnNvbHV0ZVBhdGgob2JqLnN3YWdnZXJWZXJzaW9uLCB0aGlzLmRvY0xvY2F0aW9uLCBwYXRoKTtcblxuICAgIGlmKGFwaS5kZXNjcmlwdGlvbikge1xuICAgICAgc3dhZ2dlci50YWdzID0gc3dhZ2dlci50YWdzIHx8IFtdO1xuICAgICAgc3dhZ2dlci50YWdzLnB1c2goe1xuICAgICAgICBuYW1lIDogdGhpcy5leHRyYWN0VGFnKGFwaS5wYXRoKSxcbiAgICAgICAgZGVzY3JpcHRpb24gOiBhcGkuZGVzY3JpcHRpb24gfHwgJydcbiAgICAgIH0pO1xuICAgIH1cbiAgICB2YXIgaHR0cCA9IHtcbiAgICAgIHVybDogYWJzb2x1dGVQYXRoLFxuICAgICAgaGVhZGVyczogeyBhY2NlcHQ6IHN3YWdnZXJSZXF1ZXN0SGVhZGVycyB9LFxuICAgICAgb246IHt9LFxuICAgICAgbWV0aG9kOiAnZ2V0J1xuICAgIH07XG4gICAgLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuICAgIGh0dHAub24ucmVzcG9uc2UgPSBmdW5jdGlvbihkYXRhKSB7XG4gICAgICBwcm9jZXNzZWRDb3VudCArPSAxO1xuICAgICAgdmFyIG9iaiA9IGRhdGEub2JqO1xuICAgICAgaWYob2JqKSB7XG4gICAgICAgIHNlbGYuZGVjbGFyYXRpb24ob2JqLCBfc3dhZ2dlcik7XG4gICAgICB9XG4gICAgICBpZihwcm9jZXNzZWRDb3VudCA9PT0gZXhwZWN0ZWRDb3VudCkge1xuICAgICAgICBzZWxmLmZpbmlzaChjYWxsYmFjaywgX3N3YWdnZXIpO1xuICAgICAgfVxuICAgIH07XG4gICAgaHR0cC5vbi5lcnJvciA9IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZGF0YSk7XG4gICAgICBwcm9jZXNzZWRDb3VudCArPSAxO1xuICAgICAgaWYocHJvY2Vzc2VkQ291bnQgPT09IGV4cGVjdGVkQ291bnQpIHtcbiAgICAgICAgc2VsZi5maW5pc2goY2FsbGJhY2ssIF9zd2FnZ2VyKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIC8qIGpzaGludCBpZ25vcmU6ZW5kICovXG5cbiAgICBpZih0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zICYmIHR5cGVvZiB0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zLmFwcGx5ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zLmFwcGx5KGh0dHApO1xuICAgIH1cblxuICAgIG5ldyBTd2FnZ2VySHR0cCgpLmV4ZWN1dGUoaHR0cCwgX29wdHMpO1xuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuZ2V0QWJzb2x1dGVQYXRoID0gZnVuY3Rpb24odmVyc2lvbiwgZG9jTG9jYXRpb24sIHBhdGgpICB7XG4gIGlmKHZlcnNpb24gPT09ICcxLjAnKSB7XG4gICAgaWYoZG9jTG9jYXRpb24uZW5kc1dpdGgoJy5qc29uJykpIHtcbiAgICAgIC8vIGdldCByb290IHBhdGhcbiAgICAgIHZhciBwb3MgPSBkb2NMb2NhdGlvbi5sYXN0SW5kZXhPZignLycpO1xuICAgICAgaWYocG9zID4gMCkge1xuICAgICAgICBkb2NMb2NhdGlvbiA9IGRvY0xvY2F0aW9uLnN1YnN0cmluZygwLCBwb3MpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHZhciBsb2NhdGlvbiA9IGRvY0xvY2F0aW9uO1xuICBpZihwYXRoLmluZGV4T2YoJ2h0dHA6Ly8nKSA9PT0gMCB8fCBwYXRoLmluZGV4T2YoJ2h0dHBzOi8vJykgPT09IDApIHtcbiAgICBsb2NhdGlvbiA9IHBhdGg7XG4gIH1cbiAgZWxzZSB7XG4gICAgaWYoZG9jTG9jYXRpb24uZW5kc1dpdGgoJy8nKSkge1xuICAgICAgbG9jYXRpb24gPSBkb2NMb2NhdGlvbi5zdWJzdHJpbmcoMCwgZG9jTG9jYXRpb24ubGVuZ3RoIC0gMSk7XG4gICAgfVxuICAgIGxvY2F0aW9uICs9IHBhdGg7XG4gIH1cbiAgbG9jYXRpb24gPSBsb2NhdGlvbi5yZXBsYWNlKCd7Zm9ybWF0fScsICdqc29uJyk7XG4gIHJldHVybiBsb2NhdGlvbjtcbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5zZWN1cml0eURlZmluaXRpb25zID0gZnVuY3Rpb24ob2JqLCBzd2FnZ2VyKSB7XG4gIGlmKG9iai5hdXRob3JpemF0aW9ucykge1xuICAgIHZhciBuYW1lO1xuICAgIGZvcihuYW1lIGluIG9iai5hdXRob3JpemF0aW9ucykge1xuICAgICAgdmFyIGlzVmFsaWQgPSBmYWxzZTtcbiAgICAgIHZhciBzZWN1cml0eURlZmluaXRpb24gPSB7fTtcbiAgICAgIHZhciBkZWZpbml0aW9uID0gb2JqLmF1dGhvcml6YXRpb25zW25hbWVdO1xuICAgICAgaWYoZGVmaW5pdGlvbi50eXBlID09PSAnYXBpS2V5Jykge1xuICAgICAgICBzZWN1cml0eURlZmluaXRpb24udHlwZSA9ICdhcGlLZXknO1xuICAgICAgICBzZWN1cml0eURlZmluaXRpb24uaW4gPSBkZWZpbml0aW9uLnBhc3NBcztcbiAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLm5hbWUgPSBkZWZpbml0aW9uLmtleW5hbWUgfHwgbmFtZTtcbiAgICAgICAgaXNWYWxpZCA9IHRydWU7XG4gICAgICB9XG4gICAgICBlbHNlIGlmKGRlZmluaXRpb24udHlwZSA9PT0gJ2Jhc2ljQXV0aCcpIHtcbiAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLnR5cGUgPSAnYmFzaWNBdXRoJztcbiAgICAgICAgaXNWYWxpZCA9IHRydWU7XG4gICAgICB9XG4gICAgICBlbHNlIGlmKGRlZmluaXRpb24udHlwZSA9PT0gJ29hdXRoMicpIHtcbiAgICAgICAgdmFyIGV4aXN0aW5nU2NvcGVzID0gZGVmaW5pdGlvbi5zY29wZXMgfHwgW107XG4gICAgICAgIHZhciBzY29wZXMgPSB7fTtcbiAgICAgICAgdmFyIGk7XG4gICAgICAgIGZvcihpIGluIGV4aXN0aW5nU2NvcGVzKSB7XG4gICAgICAgICAgdmFyIHNjb3BlID0gZXhpc3RpbmdTY29wZXNbaV07XG4gICAgICAgICAgc2NvcGVzW3Njb3BlLnNjb3BlXSA9IHNjb3BlLmRlc2NyaXB0aW9uO1xuICAgICAgICB9XG4gICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi50eXBlID0gJ29hdXRoMic7XG4gICAgICAgIGlmKGkgPiAwKSB7XG4gICAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLnNjb3BlcyA9IHNjb3BlcztcbiAgICAgICAgfVxuICAgICAgICBpZihkZWZpbml0aW9uLmdyYW50VHlwZXMpIHtcbiAgICAgICAgICBpZihkZWZpbml0aW9uLmdyYW50VHlwZXMuaW1wbGljaXQpIHtcbiAgICAgICAgICAgIHZhciBpbXBsaWNpdCA9IGRlZmluaXRpb24uZ3JhbnRUeXBlcy5pbXBsaWNpdDtcbiAgICAgICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi5mbG93ID0gJ2ltcGxpY2l0JztcbiAgICAgICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi5hdXRob3JpemF0aW9uVXJsID0gaW1wbGljaXQubG9naW5FbmRwb2ludDtcbiAgICAgICAgICAgIGlzVmFsaWQgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXG4gICAgICAgICAgaWYoZGVmaW5pdGlvbi5ncmFudFR5cGVzWydhdXRob3JpemF0aW9uX2NvZGUnXSkge1xuICAgICAgICAgICAgaWYoIXNlY3VyaXR5RGVmaW5pdGlvbi5mbG93KSB7XG4gICAgICAgICAgICAgIC8vIGNhbm5vdCBzZXQgaWYgZmxvdyBpcyBhbHJlYWR5IGRlZmluZWRcbiAgICAgICAgICAgICAgdmFyIGF1dGhDb2RlID0gZGVmaW5pdGlvbi5ncmFudFR5cGVzWydhdXRob3JpemF0aW9uX2NvZGUnXTtcbiAgICAgICAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLmZsb3cgPSAnYWNjZXNzQ29kZSc7XG4gICAgICAgICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi5hdXRob3JpemF0aW9uVXJsID0gYXV0aENvZGUudG9rZW5SZXF1ZXN0RW5kcG9pbnQudXJsO1xuICAgICAgICAgICAgICBzZWN1cml0eURlZmluaXRpb24udG9rZW5VcmwgPSBhdXRoQ29kZS50b2tlbkVuZHBvaW50LnVybDtcbiAgICAgICAgICAgICAgaXNWYWxpZCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIC8qIGpzaGludCBpZ25vcmU6ZW5kICovXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmKGlzVmFsaWQpIHtcbiAgICAgICAgc3dhZ2dlci5zZWN1cml0eURlZmluaXRpb25zID0gc3dhZ2dlci5zZWN1cml0eURlZmluaXRpb25zIHx8IHt9O1xuICAgICAgICBzd2FnZ2VyLnNlY3VyaXR5RGVmaW5pdGlvbnNbbmFtZV0gPSBzZWN1cml0eURlZmluaXRpb247XG4gICAgICB9XG4gICAgfVxuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuYXBpSW5mbyA9IGZ1bmN0aW9uKG9iaiwgc3dhZ2dlcikge1xuICAvLyBpbmZvIHNlY3Rpb25cbiAgaWYob2JqLmluZm8pIHtcbiAgICB2YXIgaW5mbyA9IG9iai5pbmZvO1xuICAgIHN3YWdnZXIuaW5mbyA9IHt9O1xuXG4gICAgaWYoaW5mby5jb250YWN0KSB7XG4gICAgICBzd2FnZ2VyLmluZm8uY29udGFjdCA9IHt9O1xuICAgICAgc3dhZ2dlci5pbmZvLmNvbnRhY3QuZW1haWwgPSBpbmZvLmNvbnRhY3Q7XG4gICAgfVxuICAgIGlmKGluZm8uZGVzY3JpcHRpb24pIHtcbiAgICAgIHN3YWdnZXIuaW5mby5kZXNjcmlwdGlvbiA9IGluZm8uZGVzY3JpcHRpb247XG4gICAgfVxuICAgIGlmKGluZm8udGl0bGUpIHtcbiAgICAgIHN3YWdnZXIuaW5mby50aXRsZSA9IGluZm8udGl0bGU7XG4gICAgfVxuICAgIGlmKGluZm8udGVybXNPZlNlcnZpY2VVcmwpIHtcbiAgICAgIHN3YWdnZXIuaW5mby50ZXJtc09mU2VydmljZSA9IGluZm8udGVybXNPZlNlcnZpY2VVcmw7XG4gICAgfVxuICAgIGlmKGluZm8ubGljZW5zZSB8fCBpbmZvLmxpY2Vuc2VVcmwpIHtcbiAgICAgIHN3YWdnZXIubGljZW5zZSA9IHt9O1xuICAgICAgaWYoaW5mby5saWNlbnNlKSB7XG4gICAgICAgIHN3YWdnZXIubGljZW5zZS5uYW1lID0gaW5mby5saWNlbnNlO1xuICAgICAgfVxuICAgICAgaWYoaW5mby5saWNlbnNlVXJsKSB7XG4gICAgICAgIHN3YWdnZXIubGljZW5zZS51cmwgPSBpbmZvLmxpY2Vuc2VVcmw7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGVsc2Uge1xuICAgIHRoaXMud2FybmluZ3MucHVzaCgnbWlzc2luZyBpbmZvIHNlY3Rpb24nKTtcbiAgfVxufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLmZpbmlzaCA9IGZ1bmN0aW9uIChjYWxsYmFjaywgb2JqKSB7XG4gIGNhbGxiYWNrKG9iaik7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgbG9nID0gcmVxdWlyZSgnLi4vaGVscGVycycpLmxvZztcbnZhciBfID0ge1xuICBpc1BsYWluT2JqZWN0OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNQbGFpbk9iamVjdCcpLFxuICBpc1N0cmluZzogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzU3RyaW5nJyksXG59O1xuXG52YXIgU2NoZW1hTWFya3VwID0gcmVxdWlyZSgnLi4vc2NoZW1hLW1hcmt1cC5qcycpO1xudmFyIGpzeWFtbCA9IHJlcXVpcmUoJ2pzLXlhbWwnKTtcblxudmFyIE1vZGVsID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAobmFtZSwgZGVmaW5pdGlvbiwgbW9kZWxzLCBtb2RlbFByb3BlcnR5TWFjcm8pIHtcbiAgdGhpcy5kZWZpbml0aW9uID0gZGVmaW5pdGlvbiB8fCB7fTtcbiAgdGhpcy5pc0FycmF5ID0gZGVmaW5pdGlvbi50eXBlID09PSAnYXJyYXknO1xuICB0aGlzLm1vZGVscyA9IG1vZGVscyB8fCB7fTtcbiAgdGhpcy5uYW1lID0gbmFtZSB8fCBkZWZpbml0aW9uLnRpdGxlIHx8ICdJbmxpbmUgTW9kZWwnO1xuICB0aGlzLm1vZGVsUHJvcGVydHlNYWNybyA9IG1vZGVsUHJvcGVydHlNYWNybyB8fCBmdW5jdGlvbiAocHJvcGVydHkpIHtcbiAgICByZXR1cm4gcHJvcGVydHkuZGVmYXVsdDtcbiAgfTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIE5vdGUhICBUaGlzIGZ1bmN0aW9uIHdpbGwgYmUgcmVtb3ZlZCBpbiAyLjIueCFcbk1vZGVsLnByb3RvdHlwZS5jcmVhdGVKU09OU2FtcGxlID0gTW9kZWwucHJvdG90eXBlLmdldFNhbXBsZVZhbHVlID0gZnVuY3Rpb24gKG1vZGVsc1RvSWdub3JlKSB7XG4gIG1vZGVsc1RvSWdub3JlID0gbW9kZWxzVG9JZ25vcmUgfHwge307XG5cbiAgbW9kZWxzVG9JZ25vcmVbdGhpcy5uYW1lXSA9IHRoaXM7XG5cbiAgLy8gUmVzcG9uc2Ugc3VwcG9ydFxuICBpZiAodGhpcy5leGFtcGxlcyAmJiBfLmlzUGxhaW5PYmplY3QodGhpcy5leGFtcGxlcykgJiYgdGhpcy5leGFtcGxlc1snYXBwbGljYXRpb24vanNvbiddKSB7XG4gICAgdGhpcy5kZWZpbml0aW9uLmV4YW1wbGUgPSB0aGlzLmV4YW1wbGVzWydhcHBsaWNhdGlvbi9qc29uJ107XG5cbiAgICBpZiAoXy5pc1N0cmluZyh0aGlzLmRlZmluaXRpb24uZXhhbXBsZSkpIHtcbiAgICAgIHRoaXMuZGVmaW5pdGlvbi5leGFtcGxlID0ganN5YW1sLnNhZmVMb2FkKHRoaXMuZGVmaW5pdGlvbi5leGFtcGxlKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoIXRoaXMuZGVmaW5pdGlvbi5leGFtcGxlKSB7XG4gICAgdGhpcy5kZWZpbml0aW9uLmV4YW1wbGUgPSB0aGlzLmV4YW1wbGVzO1xuICB9XG5cbiAgcmV0dXJuIFNjaGVtYU1hcmt1cC5zY2hlbWFUb0pTT04odGhpcy5kZWZpbml0aW9uLCB0aGlzLm1vZGVscywgbW9kZWxzVG9JZ25vcmUsIHRoaXMubW9kZWxQcm9wZXJ0eU1hY3JvKTtcbn07XG5cbk1vZGVsLnByb3RvdHlwZS5nZXRNb2NrU2lnbmF0dXJlID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gU2NoZW1hTWFya3VwLnNjaGVtYVRvSFRNTCh0aGlzLm5hbWUsIHRoaXMuZGVmaW5pdGlvbiwgdGhpcy5tb2RlbHMsIHRoaXMubW9kZWxQcm9wZXJ0eU1hY3JvKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBfID0ge1xuICBjbG9uZURlZXA6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9jbG9uZURlZXAnKSxcbiAgaXNVbmRlZmluZWQ6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc1VuZGVmaW5lZCcpLFxuICBpc0VtcHR5OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNFbXB0eScpLFxuICBpc09iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzT2JqZWN0Jylcbn07XG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4uL2hlbHBlcnMnKTtcbnZhciBNb2RlbCA9IHJlcXVpcmUoJy4vbW9kZWwnKTtcbnZhciBTd2FnZ2VySHR0cCA9IHJlcXVpcmUoJy4uL2h0dHAnKTtcbnZhciBRID0gcmVxdWlyZSgncScpO1xuXG52YXIgT3BlcmF0aW9uID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAocGFyZW50LCBzY2hlbWUsIG9wZXJhdGlvbklkLCBodHRwTWV0aG9kLCBwYXRoLCBhcmdzLCBkZWZpbml0aW9ucywgbW9kZWxzLCBjbGllbnRBdXRob3JpemF0aW9ucykge1xuICB2YXIgZXJyb3JzID0gW107XG5cbiAgcGFyZW50ID0gcGFyZW50IHx8IHt9O1xuICBhcmdzID0gYXJncyB8fCB7fTtcblxuICBpZihwYXJlbnQgJiYgcGFyZW50Lm9wdGlvbnMpIHtcbiAgICB0aGlzLmNsaWVudCA9IHBhcmVudC5vcHRpb25zLmNsaWVudCB8fCBudWxsO1xuICAgIHRoaXMucmVxdWVzdEludGVyY2VwdG9yID0gcGFyZW50Lm9wdGlvbnMucmVxdWVzdEludGVyY2VwdG9yIHx8IG51bGw7XG4gICAgdGhpcy5yZXNwb25zZUludGVyY2VwdG9yID0gcGFyZW50Lm9wdGlvbnMucmVzcG9uc2VJbnRlcmNlcHRvciB8fCBudWxsO1xuICB9XG4gIHRoaXMuYXV0aG9yaXphdGlvbnMgPSBhcmdzLnNlY3VyaXR5O1xuICB0aGlzLmJhc2VQYXRoID0gcGFyZW50LmJhc2VQYXRoIHx8ICcvJztcbiAgdGhpcy5jbGllbnRBdXRob3JpemF0aW9ucyA9IGNsaWVudEF1dGhvcml6YXRpb25zO1xuICB0aGlzLmNvbnN1bWVzID0gYXJncy5jb25zdW1lcyB8fCBwYXJlbnQuY29uc3VtZXMgfHwgWydhcHBsaWNhdGlvbi9qc29uJ107XG4gIHRoaXMucHJvZHVjZXMgPSBhcmdzLnByb2R1Y2VzIHx8IHBhcmVudC5wcm9kdWNlcyB8fCBbJ2FwcGxpY2F0aW9uL2pzb24nXTtcbiAgdGhpcy5kZXByZWNhdGVkID0gYXJncy5kZXByZWNhdGVkO1xuICB0aGlzLmRlc2NyaXB0aW9uID0gYXJncy5kZXNjcmlwdGlvbjtcbiAgdGhpcy5ob3N0ID0gcGFyZW50Lmhvc3QgfHwgJ2xvY2FsaG9zdCc7XG4gIHRoaXMubWV0aG9kID0gKGh0dHBNZXRob2QgfHwgZXJyb3JzLnB1c2goJ09wZXJhdGlvbiAnICsgb3BlcmF0aW9uSWQgKyAnIGlzIG1pc3NpbmcgbWV0aG9kLicpKTtcbiAgdGhpcy5tb2RlbHMgPSBtb2RlbHMgfHwge307XG4gIHRoaXMubmlja25hbWUgPSAob3BlcmF0aW9uSWQgfHwgZXJyb3JzLnB1c2goJ09wZXJhdGlvbnMgbXVzdCBoYXZlIGEgbmlja25hbWUuJykpO1xuICB0aGlzLm9wZXJhdGlvbiA9IGFyZ3M7XG4gIHRoaXMub3BlcmF0aW9ucyA9IHt9O1xuICB0aGlzLnBhcmFtZXRlcnMgPSBhcmdzICE9PSBudWxsID8gKGFyZ3MucGFyYW1ldGVycyB8fCBbXSkgOiB7fTtcbiAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7XG4gIHRoaXMucGF0aCA9IChwYXRoIHx8IGVycm9ycy5wdXNoKCdPcGVyYXRpb24gJyArIHRoaXMubmlja25hbWUgKyAnIGlzIG1pc3NpbmcgcGF0aC4nKSk7XG4gIHRoaXMucmVzcG9uc2VzID0gKGFyZ3MucmVzcG9uc2VzIHx8IHt9KTtcbiAgdGhpcy5zY2hlbWUgPSBzY2hlbWUgfHwgcGFyZW50LnNjaGVtZSB8fCAnaHR0cCc7XG4gIHRoaXMuc2NoZW1lcyA9IGFyZ3Muc2NoZW1lcyB8fCBwYXJlbnQuc2NoZW1lcztcbiAgdGhpcy5zZWN1cml0eSA9IGFyZ3Muc2VjdXJpdHkgfHwgcGFyZW50LnNlY3VyaXR5O1xuICB0aGlzLnN1bW1hcnkgPSBhcmdzLnN1bW1hcnkgfHwgJyc7XG4gIHRoaXMudHlwZSA9IG51bGw7XG4gIHRoaXMudXNlSlF1ZXJ5ID0gcGFyZW50LnVzZUpRdWVyeTtcbiAgdGhpcy5lbmFibGVDb29raWVzID0gcGFyZW50LmVuYWJsZUNvb2tpZXM7XG4gIHRoaXMucGFyYW1ldGVyTWFjcm8gPSBwYXJlbnQucGFyYW1ldGVyTWFjcm8gfHwgZnVuY3Rpb24gKG9wZXJhdGlvbiwgcGFyYW1ldGVyKSB7XG4gICAgcmV0dXJuIHBhcmFtZXRlci5kZWZhdWx0O1xuICB9O1xuXG4gIHRoaXMuaW5saW5lTW9kZWxzID0gW107XG5cbiAgaWYgKHR5cGVvZiB0aGlzLmRlcHJlY2F0ZWQgPT09ICdzdHJpbmcnKSB7XG4gICAgc3dpdGNoKHRoaXMuZGVwcmVjYXRlZC50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICBjYXNlICd0cnVlJzogY2FzZSAneWVzJzogY2FzZSAnMSc6IHtcbiAgICAgICAgdGhpcy5kZXByZWNhdGVkID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGNhc2UgJ2ZhbHNlJzogY2FzZSAnbm8nOiBjYXNlICcwJzogY2FzZSBudWxsOiB7XG4gICAgICAgIHRoaXMuZGVwcmVjYXRlZCA9IGZhbHNlO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgZGVmYXVsdDogdGhpcy5kZXByZWNhdGVkID0gQm9vbGVhbih0aGlzLmRlcHJlY2F0ZWQpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBpLCBtb2RlbDtcblxuICBpZiAoZGVmaW5pdGlvbnMpIHtcbiAgICAvLyBhZGQgdG8gZ2xvYmFsIG1vZGVsc1xuICAgIHZhciBrZXk7XG5cbiAgICBmb3IgKGtleSBpbiBkZWZpbml0aW9ucykge1xuICAgICAgbW9kZWwgPSBuZXcgTW9kZWwoa2V5LCBkZWZpbml0aW9uc1trZXldLCB0aGlzLm1vZGVscywgcGFyZW50Lm1vZGVsUHJvcGVydHlNYWNybyk7XG5cbiAgICAgIGlmIChtb2RlbCkge1xuICAgICAgICB0aGlzLm1vZGVsc1trZXldID0gbW9kZWw7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGVsc2Uge1xuICAgIGRlZmluaXRpb25zID0ge307XG4gIH1cblxuICBmb3IgKGkgPSAwOyBpIDwgdGhpcy5wYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcmFtID0gdGhpcy5wYXJhbWV0ZXJzW2ldO1xuXG4gICAgLy8gQWxsb3cgbWFjcm8gdG8gc2V0IHRoZSBkZWZhdWx0IHZhbHVlXG4gICAgcGFyYW0uZGVmYXVsdCA9IHRoaXMucGFyYW1ldGVyTWFjcm8odGhpcywgcGFyYW0pO1xuXG4gICAgaWYgKHBhcmFtLnR5cGUgPT09ICdhcnJheScpIHtcbiAgICAgIHBhcmFtLmlzTGlzdCA9IHRydWU7XG4gICAgICBwYXJhbS5hbGxvd011bHRpcGxlID0gdHJ1ZTtcbiAgICAgIC8vIHRoZSBlbnVtIGNhbiBiZSBkZWZpbmVkIGF0IHRoZSBpdGVtcyBsZXZlbFxuICAgICAgLy9pZiAocGFyYW0uaXRlbXMgJiYgcGFyYW0uaXRlbXMuZW51bSkge1xuICAgICAgLy8gIHBhcmFtWydlbnVtJ10gPSBwYXJhbS5pdGVtcy5lbnVtO1xuICAgICAgLy99XG4gICAgfVxuXG4gICAgdmFyIGlubmVyVHlwZSA9IHRoaXMuZ2V0VHlwZShwYXJhbSk7XG5cbiAgICBpZiAoaW5uZXJUeXBlICYmIGlubmVyVHlwZS50b1N0cmluZygpLnRvTG93ZXJDYXNlKCkgPT09ICdib29sZWFuJykge1xuICAgICAgcGFyYW0uYWxsb3dhYmxlVmFsdWVzID0ge307XG4gICAgICBwYXJhbS5pc0xpc3QgPSB0cnVlO1xuICAgICAgcGFyYW1bJ2VudW0nXSA9IFt0cnVlLCBmYWxzZV07IC8vIHVzZSBhY3R1YWwgcHJpbWl0aXZlc1xuICAgIH1cblxuICAgIGlmKHR5cGVvZiBwYXJhbVsneC1leGFtcGxlJ10gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB2YXIgZCA9IHBhcmFtWyd4LWV4YW1wbGUnXTtcbiAgICAgIHBhcmFtLmRlZmF1bHQgPSBkO1xuICAgIH1cbiAgICBpZihwYXJhbVsneC1leGFtcGxlcyddKSB7XG4gICAgICB2YXIgZCA9IHBhcmFtWyd4LWV4YW1wbGVzJ10uZGVmYXVsdDtcbiAgICAgIGlmKHR5cGVvZiBkICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBwYXJhbS5kZWZhdWx0ID0gZDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgZW51bVZhbHVlcyA9IHBhcmFtWydlbnVtJ10gfHwgKHBhcmFtLml0ZW1zICYmIHBhcmFtLml0ZW1zWydlbnVtJ10pO1xuXG4gICAgaWYgKHR5cGVvZiBlbnVtVmFsdWVzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdmFyIGlkO1xuXG4gICAgICBwYXJhbS5hbGxvd2FibGVWYWx1ZXMgPSB7fTtcbiAgICAgIHBhcmFtLmFsbG93YWJsZVZhbHVlcy52YWx1ZXMgPSBbXTtcbiAgICAgIHBhcmFtLmFsbG93YWJsZVZhbHVlcy5kZXNjcmlwdGl2ZVZhbHVlcyA9IFtdO1xuXG4gICAgICBmb3IgKGlkID0gMDsgaWQgPCBlbnVtVmFsdWVzLmxlbmd0aDsgaWQrKykge1xuICAgICAgICB2YXIgdmFsdWUgPSBlbnVtVmFsdWVzW2lkXTtcbiAgICAgICAgdmFyIGlzRGVmYXVsdCA9ICh2YWx1ZSA9PT0gcGFyYW0uZGVmYXVsdCB8fCB2YWx1ZSsnJyA9PT0gcGFyYW0uZGVmYXVsdCk7XG5cbiAgICAgICAgcGFyYW0uYWxsb3dhYmxlVmFsdWVzLnZhbHVlcy5wdXNoKHZhbHVlKTtcbiAgICAgICAgLy8gQWx3YXlzIGhhdmUgc3RyaW5nIGZvciBkZXNjcmlwdGl2ZSB2YWx1ZXMuLi4uXG4gICAgICAgIHBhcmFtLmFsbG93YWJsZVZhbHVlcy5kZXNjcmlwdGl2ZVZhbHVlcy5wdXNoKHt2YWx1ZSA6IHZhbHVlKycnLCBpc0RlZmF1bHQ6IGlzRGVmYXVsdH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChwYXJhbS50eXBlID09PSAnYXJyYXknKSB7XG4gICAgICBpbm5lclR5cGUgPSBbaW5uZXJUeXBlXTtcblxuICAgICAgaWYgKHR5cGVvZiBwYXJhbS5hbGxvd2FibGVWYWx1ZXMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIC8vIGNhbid0IHNob3cgYXMgYSBsaXN0IGlmIG5vIHZhbHVlcyB0byBzZWxlY3QgZnJvbVxuICAgICAgICBkZWxldGUgcGFyYW0uaXNMaXN0O1xuICAgICAgICBkZWxldGUgcGFyYW0uYWxsb3dNdWx0aXBsZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBwYXJhbS5tb2RlbFNpZ25hdHVyZSA9IHt0eXBlOiBpbm5lclR5cGUsIGRlZmluaXRpb25zOiB0aGlzLm1vZGVsc307XG4gICAgcGFyYW0uc2lnbmF0dXJlID0gdGhpcy5nZXRNb2RlbFNpZ25hdHVyZShpbm5lclR5cGUsIHRoaXMubW9kZWxzKS50b1N0cmluZygpO1xuICAgIHBhcmFtLnNhbXBsZUpTT04gPSB0aGlzLmdldE1vZGVsU2FtcGxlSlNPTihpbm5lclR5cGUsIHRoaXMubW9kZWxzKTtcbiAgICBwYXJhbS5yZXNwb25zZUNsYXNzU2lnbmF0dXJlID0gcGFyYW0uc2lnbmF0dXJlO1xuICB9XG5cbiAgdmFyIGRlZmF1bHRSZXNwb25zZUNvZGUsIHJlc3BvbnNlLCByZXNwb25zZXMgPSB0aGlzLnJlc3BvbnNlcztcblxuICBpZiAocmVzcG9uc2VzWycyMDAnXSkge1xuICAgIHJlc3BvbnNlID0gcmVzcG9uc2VzWycyMDAnXTtcbiAgICBkZWZhdWx0UmVzcG9uc2VDb2RlID0gJzIwMCc7XG4gIH0gZWxzZSBpZiAocmVzcG9uc2VzWycyMDEnXSkge1xuICAgIHJlc3BvbnNlID0gcmVzcG9uc2VzWycyMDEnXTtcbiAgICBkZWZhdWx0UmVzcG9uc2VDb2RlID0gJzIwMSc7XG4gIH0gZWxzZSBpZiAocmVzcG9uc2VzWycyMDInXSkge1xuICAgIHJlc3BvbnNlID0gcmVzcG9uc2VzWycyMDInXTtcbiAgICBkZWZhdWx0UmVzcG9uc2VDb2RlID0gJzIwMic7XG4gIH0gZWxzZSBpZiAocmVzcG9uc2VzWycyMDMnXSkge1xuICAgIHJlc3BvbnNlID0gcmVzcG9uc2VzWycyMDMnXTtcbiAgICBkZWZhdWx0UmVzcG9uc2VDb2RlID0gJzIwMyc7XG4gIH0gZWxzZSBpZiAocmVzcG9uc2VzWycyMDQnXSkge1xuICAgIHJlc3BvbnNlID0gcmVzcG9uc2VzWycyMDQnXTtcbiAgICBkZWZhdWx0UmVzcG9uc2VDb2RlID0gJzIwNCc7XG4gIH0gZWxzZSBpZiAocmVzcG9uc2VzWycyMDUnXSkge1xuICAgIHJlc3BvbnNlID0gcmVzcG9uc2VzWycyMDUnXTtcbiAgICBkZWZhdWx0UmVzcG9uc2VDb2RlID0gJzIwNSc7XG4gIH0gZWxzZSBpZiAocmVzcG9uc2VzWycyMDYnXSkge1xuICAgIHJlc3BvbnNlID0gcmVzcG9uc2VzWycyMDYnXTtcbiAgICBkZWZhdWx0UmVzcG9uc2VDb2RlID0gJzIwNic7XG4gIH0gZWxzZSBpZiAocmVzcG9uc2VzWydkZWZhdWx0J10pIHtcbiAgICByZXNwb25zZSA9IHJlc3BvbnNlc1snZGVmYXVsdCddO1xuICAgIGRlZmF1bHRSZXNwb25zZUNvZGUgPSAnZGVmYXVsdCc7XG4gIH1cblxuICBpZiAocmVzcG9uc2UgJiYgcmVzcG9uc2Uuc2NoZW1hKSB7XG4gICAgdmFyIHJlc29sdmVkTW9kZWwgPSB0aGlzLnJlc29sdmVNb2RlbChyZXNwb25zZS5zY2hlbWEsIGRlZmluaXRpb25zKTtcbiAgICB2YXIgc3VjY2Vzc1Jlc3BvbnNlO1xuXG4gICAgZGVsZXRlIHJlc3BvbnNlc1tkZWZhdWx0UmVzcG9uc2VDb2RlXTtcblxuICAgIGlmIChyZXNvbHZlZE1vZGVsKSB7XG4gICAgICB0aGlzLnN1Y2Nlc3NSZXNwb25zZSA9IHt9O1xuICAgICAgc3VjY2Vzc1Jlc3BvbnNlID0gdGhpcy5zdWNjZXNzUmVzcG9uc2VbZGVmYXVsdFJlc3BvbnNlQ29kZV0gPSByZXNvbHZlZE1vZGVsO1xuICAgIH0gZWxzZSBpZiAoIXJlc3BvbnNlLnNjaGVtYS50eXBlIHx8IHJlc3BvbnNlLnNjaGVtYS50eXBlID09PSAnb2JqZWN0JyB8fCByZXNwb25zZS5zY2hlbWEudHlwZSA9PT0gJ2FycmF5Jykge1xuICAgICAgLy8gSW5saW5lIG1vZGVsXG4gICAgICB0aGlzLnN1Y2Nlc3NSZXNwb25zZSA9IHt9O1xuICAgICAgc3VjY2Vzc1Jlc3BvbnNlID0gdGhpcy5zdWNjZXNzUmVzcG9uc2VbZGVmYXVsdFJlc3BvbnNlQ29kZV0gPSBuZXcgTW9kZWwodW5kZWZpbmVkLCByZXNwb25zZS5zY2hlbWEgfHwge30sIHRoaXMubW9kZWxzLCBwYXJlbnQubW9kZWxQcm9wZXJ0eU1hY3JvKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gUHJpbWl0aXZlXG4gICAgICB0aGlzLnN1Y2Nlc3NSZXNwb25zZSA9IHt9O1xuICAgICAgc3VjY2Vzc1Jlc3BvbnNlID0gdGhpcy5zdWNjZXNzUmVzcG9uc2VbZGVmYXVsdFJlc3BvbnNlQ29kZV0gPSByZXNwb25zZS5zY2hlbWE7XG4gICAgfVxuXG4gICAgaWYgKHN1Y2Nlc3NSZXNwb25zZSkge1xuICAgICAgLy8gQXR0YWNoIHJlc3BvbnNlIHByb3BlcnRpZXNcbiAgICAgIGlmIChyZXNwb25zZS5kZXNjcmlwdGlvbikge1xuICAgICAgICBzdWNjZXNzUmVzcG9uc2UuZGVzY3JpcHRpb24gPSByZXNwb25zZS5kZXNjcmlwdGlvbjtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlc3BvbnNlLmV4YW1wbGVzKSB7XG4gICAgICAgIHN1Y2Nlc3NSZXNwb25zZS5leGFtcGxlcyA9IHJlc3BvbnNlLmV4YW1wbGVzO1xuICAgICAgfVxuXG4gICAgICBpZiAocmVzcG9uc2UuaGVhZGVycykge1xuICAgICAgICBzdWNjZXNzUmVzcG9uc2UuaGVhZGVycyA9IHJlc3BvbnNlLmhlYWRlcnM7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy50eXBlID0gcmVzcG9uc2U7XG4gIH1cblxuICBpZiAoZXJyb3JzLmxlbmd0aCA+IDApIHtcbiAgICBpZiAodGhpcy5yZXNvdXJjZSAmJiB0aGlzLnJlc291cmNlLmFwaSAmJiB0aGlzLnJlc291cmNlLmFwaS5mYWlsKSB7XG4gICAgICB0aGlzLnJlc291cmNlLmFwaS5mYWlsKGVycm9ycyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmlzRGVmYXVsdEFycmF5SXRlbVZhbHVlID0gZnVuY3Rpb24odmFsdWUsIHBhcmFtKSB7XG4gIGlmIChwYXJhbS5kZWZhdWx0ICYmIEFycmF5LmlzQXJyYXkocGFyYW0uZGVmYXVsdCkpIHtcbiAgICByZXR1cm4gcGFyYW0uZGVmYXVsdC5pbmRleE9mKHZhbHVlKSAhPT0gLTE7XG4gIH1cbiAgcmV0dXJuIHZhbHVlID09PSBwYXJhbS5kZWZhdWx0O1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5nZXRUeXBlID0gZnVuY3Rpb24gKHBhcmFtKSB7XG4gIHZhciB0eXBlID0gcGFyYW0udHlwZTtcbiAgdmFyIGZvcm1hdCA9IHBhcmFtLmZvcm1hdDtcbiAgdmFyIGlzQXJyYXkgPSBmYWxzZTtcbiAgdmFyIHN0cjtcblxuICBpZiAodHlwZSA9PT0gJ2ludGVnZXInICYmIGZvcm1hdCA9PT0gJ2ludDMyJykge1xuICAgIHN0ciA9ICdpbnRlZ2VyJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnaW50ZWdlcicgJiYgZm9ybWF0ID09PSAnaW50NjQnKSB7XG4gICAgc3RyID0gJ2xvbmcnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdpbnRlZ2VyJykge1xuICAgIHN0ciA9ICdpbnRlZ2VyJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgIGlmIChmb3JtYXQgPT09ICdkYXRlLXRpbWUnKSB7XG4gICAgICBzdHIgPSAnZGF0ZS10aW1lJztcbiAgICB9IGVsc2UgaWYgKGZvcm1hdCA9PT0gJ2RhdGUnKSB7XG4gICAgICBzdHIgPSAnZGF0ZSc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ciA9ICdzdHJpbmcnO1xuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJyAmJiBmb3JtYXQgPT09ICdmbG9hdCcpIHtcbiAgICBzdHIgPSAnZmxvYXQnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdudW1iZXInICYmIGZvcm1hdCA9PT0gJ2RvdWJsZScpIHtcbiAgICBzdHIgPSAnZG91YmxlJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJykge1xuICAgIHN0ciA9ICdkb3VibGUnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdib29sZWFuJykge1xuICAgIHN0ciA9ICdib29sZWFuJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnYXJyYXknKSB7XG4gICAgaXNBcnJheSA9IHRydWU7XG5cbiAgICBpZiAocGFyYW0uaXRlbXMpIHtcbiAgICAgIHN0ciA9IHRoaXMuZ2V0VHlwZShwYXJhbS5pdGVtcyk7XG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdmaWxlJykge1xuICAgIHN0ciA9ICdmaWxlJztcbiAgfVxuXG4gIGlmIChwYXJhbS4kcmVmKSB7XG4gICAgc3RyID0gaGVscGVycy5zaW1wbGVSZWYocGFyYW0uJHJlZik7XG4gIH1cblxuICB2YXIgc2NoZW1hID0gcGFyYW0uc2NoZW1hO1xuXG4gIGlmIChzY2hlbWEpIHtcbiAgICB2YXIgcmVmID0gc2NoZW1hLiRyZWY7XG5cbiAgICBpZiAocmVmKSB7XG4gICAgICByZWYgPSBoZWxwZXJzLnNpbXBsZVJlZihyZWYpO1xuXG4gICAgICBpZiAoaXNBcnJheSkge1xuICAgICAgICByZXR1cm4gWyByZWYgXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiByZWY7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElmIGlubGluZSBzY2hlbWEsIHdlIGFkZCBpdCBvdXIgaW50ZXJhbCBoYXNoIC0+IHdoaWNoIGdpdmVzIHVzIGl0J3MgSUQgKGludClcbiAgICAgIGlmKHNjaGVtYS50eXBlID09PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gdGhpcy5hZGRJbmxpbmVNb2RlbChzY2hlbWEpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuZ2V0VHlwZShzY2hlbWEpO1xuICAgIH1cbiAgfVxuICBpZiAoaXNBcnJheSkge1xuICAgIHJldHVybiBbIHN0ciBdO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBzdHI7XG4gIH1cbn07XG5cbi8qKlxuICogYWRkcyBhbiBpbmxpbmUgc2NoZW1hIChtb2RlbCkgdG8gYSBoYXNoLCB3aGVyZSB3ZSBjYW4gcmVmIGl0IGxhdGVyXG4gKiBAcGFyYW0ge29iamVjdH0gc2NoZW1hIGEgc2NoZW1hXG4gKiBAcmV0dXJuIHtudW1iZXJ9IHRoZSBJRCBvZiB0aGUgc2NoZW1hIGJlaW5nIGFkZGVkLCBvciBudWxsXG4gKiovXG5PcGVyYXRpb24ucHJvdG90eXBlLmFkZElubGluZU1vZGVsID0gZnVuY3Rpb24gKHNjaGVtYSkge1xuICB2YXIgbGVuID0gdGhpcy5pbmxpbmVNb2RlbHMubGVuZ3RoO1xuICB2YXIgbW9kZWwgPSB0aGlzLnJlc29sdmVNb2RlbChzY2hlbWEsIHt9KTtcbiAgaWYobW9kZWwpIHtcbiAgICB0aGlzLmlubGluZU1vZGVscy5wdXNoKG1vZGVsKTtcbiAgICByZXR1cm4gJ0lubGluZSBNb2RlbCAnK2xlbjsgLy8gcmV0dXJuIHN0cmluZyByZWYgb2YgdGhlIGlubGluZSBtb2RlbCAodXNlZCB3aXRoICNnZXRJbmxpbmVNb2RlbClcbiAgfVxuICByZXR1cm4gbnVsbDsgLy8gcmVwb3J0IGVycm9ycz9cbn07XG5cbi8qKlxuICogZ2V0cyB0aGUgaW50ZXJuYWwgcmVmIHRvIGFuIGlubGluZSBtb2RlbFxuICogQHBhcmFtIHtzdHJpbmd9IGlubGluZV9zdHIgYSBzdHJpbmcgcmVmZXJlbmNlIHRvIGFuIGlubGluZSBtb2RlbFxuICogQHJldHVybiB7TW9kZWx9IHRoZSBtb2RlbCBiZWluZyByZWZlcmVuY2VkLiBPciBudWxsXG4gKiovXG5PcGVyYXRpb24ucHJvdG90eXBlLmdldElubGluZU1vZGVsID0gZnVuY3Rpb24oaW5saW5lU3RyKSB7XG4gIGlmKC9eSW5saW5lIE1vZGVsIFxcZCskLy50ZXN0KGlubGluZVN0cikpIHtcbiAgICB2YXIgaWQgPSBwYXJzZUludChpbmxpbmVTdHIuc3Vic3RyKCdJbmxpbmUgTW9kZWwnLmxlbmd0aCkudHJpbSgpLDEwKTsgLy9cbiAgICB2YXIgbW9kZWwgPSB0aGlzLmlubGluZU1vZGVsc1tpZF07XG4gICAgcmV0dXJuIG1vZGVsO1xuICB9XG4gIC8vIEknbSByZXR1cm5pbmcgbnVsbCBoZXJlLCBzaG91bGQgSSByYXRoZXIgdGhyb3cgYW4gZXJyb3I/XG4gIHJldHVybiBudWxsO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5yZXNvbHZlTW9kZWwgPSBmdW5jdGlvbiAoc2NoZW1hLCBkZWZpbml0aW9ucykge1xuICBpZiAodHlwZW9mIHNjaGVtYS4kcmVmICE9PSAndW5kZWZpbmVkJykge1xuICAgIHZhciByZWYgPSBzY2hlbWEuJHJlZjtcblxuICAgIGlmIChyZWYuaW5kZXhPZignIy9kZWZpbml0aW9ucy8nKSA9PT0gMCkge1xuICAgICAgcmVmID0gcmVmLnN1YnN0cmluZygnIy9kZWZpbml0aW9ucy8nLmxlbmd0aCk7XG4gICAgfVxuXG4gICAgaWYgKGRlZmluaXRpb25zW3JlZl0pIHtcbiAgICAgIHJldHVybiBuZXcgTW9kZWwocmVmLCBkZWZpbml0aW9uc1tyZWZdLCB0aGlzLm1vZGVscywgdGhpcy5wYXJlbnQubW9kZWxQcm9wZXJ0eU1hY3JvKTtcbiAgICB9XG4gIC8vIHNjaGVtYSBtdXN0IGF0IGxlYXN0IGJlIGFuIG9iamVjdCB0byBnZXQgcmVzb2x2ZWQgdG8gYW4gaW5saW5lIE1vZGVsXG4gIH0gZWxzZSBpZiAoc2NoZW1hICYmIHR5cGVvZiBzY2hlbWEgPT09ICdvYmplY3QnICYmXG4gICAgICAgICAgICAoc2NoZW1hLnR5cGUgPT09ICdvYmplY3QnIHx8IF8uaXNVbmRlZmluZWQoc2NoZW1hLnR5cGUpKSkge1xuICAgIHJldHVybiBuZXcgTW9kZWwodW5kZWZpbmVkLCBzY2hlbWEsIHRoaXMubW9kZWxzLCB0aGlzLnBhcmVudC5tb2RlbFByb3BlcnR5TWFjcm8pO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmhlbHAgPSBmdW5jdGlvbiAoZG9udFByaW50KSB7XG4gIHZhciBvdXQgPSB0aGlzLm5pY2tuYW1lICsgJzogJyArIHRoaXMuc3VtbWFyeSArICdcXG4nO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5wYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcmFtID0gdGhpcy5wYXJhbWV0ZXJzW2ldO1xuICAgIHZhciB0eXBlSW5mbyA9IHBhcmFtLnNpZ25hdHVyZTtcblxuICAgIG91dCArPSAnXFxuICAqICcgKyBwYXJhbS5uYW1lICsgJyAoJyArIHR5cGVJbmZvICsgJyk6ICcgKyBwYXJhbS5kZXNjcmlwdGlvbjtcbiAgfVxuXG4gIGlmICh0eXBlb2YgZG9udFByaW50ID09PSAndW5kZWZpbmVkJykge1xuICAgIGhlbHBlcnMubG9nKG91dCk7XG4gIH1cblxuICByZXR1cm4gb3V0O1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5nZXRNb2RlbFNpZ25hdHVyZSA9IGZ1bmN0aW9uICh0eXBlLCBkZWZpbml0aW9ucykge1xuICB2YXIgaXNQcmltaXRpdmUsIGxpc3RUeXBlO1xuXG4gIGlmICh0eXBlIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICBsaXN0VHlwZSA9IHRydWU7XG4gICAgdHlwZSA9IHR5cGVbMF07XG4gIH1cblxuICAvLyBDb252ZXJ0IHVuZGVmaW5lZCB0byBzdHJpbmcgb2YgJ3VuZGVmaW5lZCdcbiAgaWYgKHR5cGVvZiB0eXBlID09PSAndW5kZWZpbmVkJykge1xuICAgIHR5cGUgPSAndW5kZWZpbmVkJztcbiAgICBpc1ByaW1pdGl2ZSA9IHRydWU7XG5cbiAgfSBlbHNlIGlmIChkZWZpbml0aW9uc1t0eXBlXSl7XG4gICAgLy8gYSBtb2RlbCBkZWYgZXhpc3RzP1xuICAgIHR5cGUgPSBkZWZpbml0aW9uc1t0eXBlXTsgLyogTW9kZWwgKi9cbiAgICBpc1ByaW1pdGl2ZSA9IGZhbHNlO1xuXG4gIH0gZWxzZSBpZiAodGhpcy5nZXRJbmxpbmVNb2RlbCh0eXBlKSkge1xuICAgIHR5cGUgPSB0aGlzLmdldElubGluZU1vZGVsKHR5cGUpOyAvKiBNb2RlbCAqL1xuICAgIGlzUHJpbWl0aXZlID0gZmFsc2U7XG5cbiAgfSBlbHNlIHtcbiAgICAvLyBXZSBkZWZhdWx0IHRvIHByaW1pdGl2ZVxuICAgIGlzUHJpbWl0aXZlID0gdHJ1ZTtcbiAgfVxuXG4gIGlmIChpc1ByaW1pdGl2ZSkge1xuICAgIGlmIChsaXN0VHlwZSkge1xuICAgICAgcmV0dXJuICdBcnJheVsnICsgdHlwZSArICddJztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHR5cGUudG9TdHJpbmcoKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGxpc3RUeXBlKSB7XG4gICAgICByZXR1cm4gJ0FycmF5WycgKyB0eXBlLmdldE1vY2tTaWduYXR1cmUoKSArICddJztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHR5cGUuZ2V0TW9ja1NpZ25hdHVyZSgpO1xuICAgIH1cbiAgfVxufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5zdXBwb3J0SGVhZGVyUGFyYW1zID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdHJ1ZTtcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuc3VwcG9ydGVkU3VibWl0TWV0aG9kcyA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMucGFyZW50LnN1cHBvcnRlZFN1Ym1pdE1ldGhvZHM7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmdldEhlYWRlclBhcmFtcyA9IGZ1bmN0aW9uIChhcmdzKSB7XG4gIHZhciBoZWFkZXJzID0gdGhpcy5zZXRDb250ZW50VHlwZXMoYXJncywge30pO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5wYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcmFtID0gdGhpcy5wYXJhbWV0ZXJzW2ldO1xuXG4gICAgaWYgKHR5cGVvZiBhcmdzW3BhcmFtLm5hbWVdICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgaWYgKHBhcmFtLmluID09PSAnaGVhZGVyJykge1xuICAgICAgICB2YXIgdmFsdWUgPSBhcmdzW3BhcmFtLm5hbWVdO1xuXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgIHZhbHVlID0gdmFsdWUudG9TdHJpbmcoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGhlYWRlcnNbcGFyYW0ubmFtZV0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gaGVhZGVycztcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUudXJsaWZ5ID0gZnVuY3Rpb24gKGFyZ3MpIHtcbiAgdmFyIGZvcm1QYXJhbXMgPSB7fTtcbiAgdmFyIHJlcXVlc3RVcmwgPSB0aGlzLnBhdGg7XG4gIHZhciBxdWVyeXN0cmluZyA9ICcnOyAvLyBncmFiIHBhcmFtcyBmcm9tIHRoZSBhcmdzLCBidWlsZCB0aGUgcXVlcnlzdHJpbmcgYWxvbmcgdGhlIHdheVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5wYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcmFtID0gdGhpcy5wYXJhbWV0ZXJzW2ldO1xuXG4gICAgaWYgKHR5cGVvZiBhcmdzW3BhcmFtLm5hbWVdICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgaWYgKHBhcmFtLmluID09PSAncGF0aCcpIHtcbiAgICAgICAgdmFyIHJlZyA9IG5ldyBSZWdFeHAoJ1xceycgKyBwYXJhbS5uYW1lICsgJ1xcfScsICdnaScpO1xuICAgICAgICB2YXIgdmFsdWUgPSBhcmdzW3BhcmFtLm5hbWVdO1xuXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgIHZhbHVlID0gdGhpcy5lbmNvZGVQYXRoQ29sbGVjdGlvbihwYXJhbS5jb2xsZWN0aW9uRm9ybWF0LCBwYXJhbS5uYW1lLCB2YWx1ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFsdWUgPSB0aGlzLmVuY29kZVBhdGhQYXJhbSh2YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXF1ZXN0VXJsID0gcmVxdWVzdFVybC5yZXBsYWNlKHJlZywgdmFsdWUpO1xuICAgICAgfSBlbHNlIGlmIChwYXJhbS5pbiA9PT0gJ3F1ZXJ5JyAmJiB0eXBlb2YgYXJnc1twYXJhbS5uYW1lXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgaWYgKHF1ZXJ5c3RyaW5nID09PSAnJykge1xuICAgICAgICAgIHF1ZXJ5c3RyaW5nICs9ICc/JztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBxdWVyeXN0cmluZyArPSAnJic7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHBhcmFtLmNvbGxlY3Rpb25Gb3JtYXQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgdmFyIHFwID0gYXJnc1twYXJhbS5uYW1lXTtcblxuICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHFwKSkge1xuICAgICAgICAgICAgcXVlcnlzdHJpbmcgKz0gdGhpcy5lbmNvZGVRdWVyeUNvbGxlY3Rpb24ocGFyYW0uY29sbGVjdGlvbkZvcm1hdCwgcGFyYW0ubmFtZSwgcXApO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBxdWVyeXN0cmluZyArPSB0aGlzLmVuY29kZVF1ZXJ5UGFyYW0ocGFyYW0ubmFtZSkgKyAnPScgKyB0aGlzLmVuY29kZVF1ZXJ5UGFyYW0oYXJnc1twYXJhbS5uYW1lXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHF1ZXJ5c3RyaW5nICs9IHRoaXMuZW5jb2RlUXVlcnlQYXJhbShwYXJhbS5uYW1lKSArICc9JyArIHRoaXMuZW5jb2RlUXVlcnlQYXJhbShhcmdzW3BhcmFtLm5hbWVdKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChwYXJhbS5pbiA9PT0gJ2Zvcm1EYXRhJykge1xuICAgICAgICBmb3JtUGFyYW1zW3BhcmFtLm5hbWVdID0gYXJnc1twYXJhbS5uYW1lXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgdmFyIHVybCA9IHRoaXMuc2NoZW1lICsgJzovLycgKyB0aGlzLmhvc3Q7XG5cbiAgaWYgKHRoaXMuYmFzZVBhdGggIT09ICcvJykge1xuICAgIHVybCArPSB0aGlzLmJhc2VQYXRoO1xuICB9XG4gIHJldHVybiB1cmwgKyByZXF1ZXN0VXJsICsgcXVlcnlzdHJpbmc7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmdldE1pc3NpbmdQYXJhbXMgPSBmdW5jdGlvbiAoYXJncykge1xuICB2YXIgbWlzc2luZ1BhcmFtcyA9IFtdOyAvLyBjaGVjayByZXF1aXJlZCBwYXJhbXMsIHRyYWNrIHRoZSBvbmVzIHRoYXQgYXJlIG1pc3NpbmdcbiAgdmFyIGk7XG5cbiAgZm9yIChpID0gMDsgaSA8IHRoaXMucGFyYW1ldGVycy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwYXJhbSA9IHRoaXMucGFyYW1ldGVyc1tpXTtcblxuICAgIGlmIChwYXJhbS5yZXF1aXJlZCA9PT0gdHJ1ZSkge1xuICAgICAgaWYgKHR5cGVvZiBhcmdzW3BhcmFtLm5hbWVdID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICBtaXNzaW5nUGFyYW1zID0gcGFyYW0ubmFtZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbWlzc2luZ1BhcmFtcztcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuZ2V0Qm9keSA9IGZ1bmN0aW9uIChoZWFkZXJzLCBhcmdzLCBvcHRzKSB7XG4gIHZhciBmb3JtUGFyYW1zID0ge30sIGhhc0Zvcm1QYXJhbXMsIGJvZHksIGtleSwgdmFsdWUsIGhhc0JvZHkgPSBmYWxzZTtcblxuICAvLyBsb29rIGF0IGVhY2ggcGFyYW0gYW5kIHB1dCBmb3JtIHBhcmFtcyBpbiBhbiBvYmplY3RcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnBhcmFtZXRlcnMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcGFyYW0gPSB0aGlzLnBhcmFtZXRlcnNbaV07XG4gICAgaWYgKHR5cGVvZiBhcmdzW3BhcmFtLm5hbWVdICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgaWYgKHBhcmFtLmluID09PSAnYm9keScpIHtcbiAgICAgICAgYm9keSA9IGFyZ3NbcGFyYW0ubmFtZV07XG4gICAgICB9IGVsc2UgaWYgKHBhcmFtLmluID09PSAnZm9ybURhdGEnKSB7XG4gICAgICAgIGZvcm1QYXJhbXNbcGFyYW0ubmFtZV0gPSBhcmdzW3BhcmFtLm5hbWVdO1xuICAgICAgICBoYXNGb3JtUGFyYW1zID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBpZihwYXJhbS5pbiA9PT0gJ2JvZHknKSB7XG4gICAgICAgIGhhc0JvZHkgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIGlmIGJvZHkgaXMgbnVsbCBhbmQgaGFzQm9keSBpcyB0cnVlLCBBTkQgYSBKU09OIGJvZHkgaXMgcmVxdWVzdGVkLCBzZW5kIGVtcHR5IHt9XG4gIGlmKGhhc0JvZHkgJiYgdHlwZW9mIGJvZHkgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgdmFyIGNvbnRlbnRUeXBlID0gaGVhZGVyc1snQ29udGVudC1UeXBlJ107XG4gICAgaWYoY29udGVudFR5cGUgJiYgY29udGVudFR5cGUuaW5kZXhPZignYXBwbGljYXRpb24vanNvbicpID09PSAwKSB7XG4gICAgICBib2R5ID0gJ3t9JztcbiAgICB9XG4gIH1cblxuICB2YXIgaXNNdWx0aVBhcnQgPSBmYWxzZTtcbiAgaWYoaGVhZGVyc1snQ29udGVudC1UeXBlJ10gJiYgaGVhZGVyc1snQ29udGVudC1UeXBlJ10uaW5kZXhPZignbXVsdGlwYXJ0L2Zvcm0tZGF0YScpID49IDApIHtcbiAgICBpc011bHRpUGFydCA9IHRydWU7XG4gIH1cblxuICAvLyBoYW5kbGUgZm9ybSBwYXJhbXNcbiAgaWYgKGhhc0Zvcm1QYXJhbXMgJiYgIWlzTXVsdGlQYXJ0KSB7XG4gICAgdmFyIGVuY29kZWQgPSAnJztcblxuICAgIGZvciAoa2V5IGluIGZvcm1QYXJhbXMpIHtcbiAgICAgIHZhbHVlID0gZm9ybVBhcmFtc1trZXldO1xuXG4gICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBpZiAoZW5jb2RlZCAhPT0gJycpIHtcbiAgICAgICAgICBlbmNvZGVkICs9ICcmJztcbiAgICAgICAgfVxuXG4gICAgICAgIGVuY29kZWQgKz0gZW5jb2RlVVJJQ29tcG9uZW50KGtleSkgKyAnPScgKyBlbmNvZGVVUklDb21wb25lbnQodmFsdWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGJvZHkgPSBlbmNvZGVkO1xuICB9IGVsc2UgaWYgKGlzTXVsdGlQYXJ0KSB7XG4gICAgaWYgKG9wdHMudXNlSlF1ZXJ5KSB7XG4gICAgICB2YXIgYm9keVBhcmFtID0gbmV3IEZvcm1EYXRhKCk7XG5cbiAgICAgIGJvZHlQYXJhbS50eXBlID0gJ2Zvcm1EYXRhJztcblxuICAgICAgZm9yIChrZXkgaW4gZm9ybVBhcmFtcykge1xuICAgICAgICB2YWx1ZSA9IGFyZ3Nba2V5XTtcblxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIC8vIHJlcXVpcmVkIGZvciBqcXVlcnkgZmlsZSB1cGxvYWRcbiAgICAgICAgICBpZiAodmFsdWUudHlwZSA9PT0gJ2ZpbGUnICYmIHZhbHVlLnZhbHVlKSB7XG4gICAgICAgICAgICBkZWxldGUgaGVhZGVyc1snQ29udGVudC1UeXBlJ107XG5cbiAgICAgICAgICAgIGJvZHlQYXJhbS5hcHBlbmQoa2V5LCB2YWx1ZS52YWx1ZSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGJvZHlQYXJhbS5hcHBlbmQoa2V5LCB2YWx1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGJvZHkgPSBib2R5UGFyYW07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGJvZHk7XG59O1xuXG4vKipcbiAqIGdldHMgc2FtcGxlIHJlc3BvbnNlIGZvciBhIHNpbmdsZSBvcGVyYXRpb25cbiAqKi9cbk9wZXJhdGlvbi5wcm90b3R5cGUuZ2V0TW9kZWxTYW1wbGVKU09OID0gZnVuY3Rpb24gKHR5cGUsIG1vZGVscykge1xuICB2YXIgbGlzdFR5cGUsIHNhbXBsZUpzb24sIGlubmVyVHlwZTtcbiAgbW9kZWxzID0gbW9kZWxzIHx8IHt9O1xuXG4gIGxpc3RUeXBlID0gKHR5cGUgaW5zdGFuY2VvZiBBcnJheSk7XG4gIGlubmVyVHlwZSA9IGxpc3RUeXBlID8gdHlwZVswXSA6IHR5cGU7XG5cbiAgaWYobW9kZWxzW2lubmVyVHlwZV0pIHtcbiAgICBzYW1wbGVKc29uID0gbW9kZWxzW2lubmVyVHlwZV0uY3JlYXRlSlNPTlNhbXBsZSgpO1xuICB9IGVsc2UgaWYgKHRoaXMuZ2V0SW5saW5lTW9kZWwoaW5uZXJUeXBlKSl7XG4gICAgc2FtcGxlSnNvbiA9IHRoaXMuZ2V0SW5saW5lTW9kZWwoaW5uZXJUeXBlKS5jcmVhdGVKU09OU2FtcGxlKCk7IC8vIG1heSByZXR1cm4gbnVsbCwgaWYgdHlwZSBpc24ndCBjb3JyZWN0XG4gIH1cblxuXG4gIGlmIChzYW1wbGVKc29uKSB7XG4gICAgc2FtcGxlSnNvbiA9IGxpc3RUeXBlID8gW3NhbXBsZUpzb25dIDogc2FtcGxlSnNvbjtcblxuICAgIGlmICh0eXBlb2Ygc2FtcGxlSnNvbiA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiBzYW1wbGVKc29uO1xuICAgIH0gZWxzZSBpZiAoXy5pc09iamVjdChzYW1wbGVKc29uKSkge1xuICAgICAgdmFyIHQgPSBzYW1wbGVKc29uO1xuXG4gICAgICBpZiAoc2FtcGxlSnNvbiBpbnN0YW5jZW9mIEFycmF5ICYmIHNhbXBsZUpzb24ubGVuZ3RoID4gMCkge1xuICAgICAgICB0ID0gc2FtcGxlSnNvblswXTtcbiAgICAgIH1cblxuICAgICAgaWYgKHQubm9kZU5hbWUgJiYgdHlwZW9mIHQgPT09ICdOb2RlJykge1xuICAgICAgICB2YXIgeG1sU3RyaW5nID0gbmV3IFhNTFNlcmlhbGl6ZXIoKS5zZXJpYWxpemVUb1N0cmluZyh0KTtcblxuICAgICAgICByZXR1cm4gdGhpcy5mb3JtYXRYbWwoeG1sU3RyaW5nKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShzYW1wbGVKc29uLCBudWxsLCAyKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHNhbXBsZUpzb247XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIGxlZ2FjeSBiaW5kaW5nXG4gKiovXG5PcGVyYXRpb24ucHJvdG90eXBlLmRvID0gZnVuY3Rpb24gKGFyZ3MsIG9wdHMsIGNhbGxiYWNrLCBlcnJvciwgcGFyZW50KSB7XG4gIHJldHVybiB0aGlzLmV4ZWN1dGUoYXJncywgb3B0cywgY2FsbGJhY2ssIGVycm9yLCBwYXJlbnQpO1xufTtcblxuLyoqXG4gKiBleGVjdXRlcyBhbiBvcGVyYXRpb25cbiAqKi9cbk9wZXJhdGlvbi5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uIChhcmcxLCBhcmcyLCBhcmczLCBhcmc0LCBwYXJlbnQpIHtcbiAgdmFyIGFyZ3MgPSBhcmcxIHx8IHt9O1xuICB2YXIgb3B0cyA9IHt9LCBzdWNjZXNzLCBlcnJvciwgZGVmZXJyZWQ7XG5cbiAgaWYgKF8uaXNPYmplY3QoYXJnMikpIHtcbiAgICBvcHRzID0gYXJnMjtcbiAgICBzdWNjZXNzID0gYXJnMztcbiAgICBlcnJvciA9IGFyZzQ7XG4gIH1cblxuICBpZih0aGlzLmNsaWVudCkge1xuICAgIG9wdHMuY2xpZW50ID0gdGhpcy5jbGllbnQ7XG4gIH1cblxuICAvLyBhZGQgdGhlIHJlcXVlc3QgaW50ZXJjZXB0b3IgZnJvbSBwYXJlbnQsIGlmIG5vbmUgc2VudCBmcm9tIGNsaWVudFxuICBpZighb3B0cy5yZXF1ZXN0SW50ZXJjZXB0b3IgJiYgdGhpcy5yZXF1ZXN0SW50ZXJjZXB0b3IgKSB7XG4gICAgb3B0cy5yZXF1ZXN0SW50ZXJjZXB0b3IgPSB0aGlzLnJlcXVlc3RJbnRlcmNlcHRvciA7XG4gIH1cblxuICBpZighb3B0cy5yZXNwb25zZUludGVyY2VwdG9yICYmIHRoaXMucmVzcG9uc2VJbnRlcmNlcHRvcikge1xuICAgIG9wdHMucmVzcG9uc2VJbnRlcmNlcHRvciA9IHRoaXMucmVzcG9uc2VJbnRlcmNlcHRvcjtcbiAgfVxuXG4gIGlmICh0eXBlb2YgYXJnMiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHN1Y2Nlc3MgPSBhcmcyO1xuICAgIGVycm9yID0gYXJnMztcbiAgfVxuXG4gIGlmICh0aGlzLnBhcmVudC51c2VQcm9taXNlKSB7XG4gICAgZGVmZXJyZWQgPSBRLmRlZmVyKCk7XG4gIH0gZWxzZSB7XG4gICAgc3VjY2VzcyA9IChzdWNjZXNzIHx8IHRoaXMucGFyZW50LmRlZmF1bHRTdWNjZXNzQ2FsbGJhY2sgfHwgaGVscGVycy5sb2cpO1xuICAgIGVycm9yID0gKGVycm9yIHx8IHRoaXMucGFyZW50LmRlZmF1bHRFcnJvckNhbGxiYWNrIHx8IGhlbHBlcnMubG9nKTtcbiAgfVxuXG5cbiAgaWYgKHR5cGVvZiBvcHRzLnVzZUpRdWVyeSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBvcHRzLnVzZUpRdWVyeSA9IHRoaXMudXNlSlF1ZXJ5O1xuICB9XG5cbiAgaWYgKHR5cGVvZiBvcHRzLmVuYWJsZUNvb2tpZXMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgb3B0cy5lbmFibGVDb29raWVzID0gdGhpcy5lbmFibGVDb29raWVzO1xuICB9XG5cbiAgdmFyIG1pc3NpbmdQYXJhbXMgPSB0aGlzLmdldE1pc3NpbmdQYXJhbXMoYXJncyk7XG5cbiAgaWYgKG1pc3NpbmdQYXJhbXMubGVuZ3RoID4gMCkge1xuICAgIHZhciBtZXNzYWdlID0gJ21pc3NpbmcgcmVxdWlyZWQgcGFyYW1zOiAnICsgbWlzc2luZ1BhcmFtcztcblxuICAgIGhlbHBlcnMuZmFpbChtZXNzYWdlKTtcblxuICAgIGlmICh0aGlzLnBhcmVudC51c2VQcm9taXNlKSB7XG4gICAgICBkZWZlcnJlZC5yZWplY3QobWVzc2FnZSk7XG4gICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXJyb3IobWVzc2FnZSwgcGFyZW50KTtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gIH1cblxuICB2YXIgYWxsSGVhZGVycyA9IHRoaXMuZ2V0SGVhZGVyUGFyYW1zKGFyZ3MpO1xuICB2YXIgY29udGVudFR5cGVIZWFkZXJzID0gdGhpcy5zZXRDb250ZW50VHlwZXMoYXJncywgb3B0cyk7XG4gIHZhciBoZWFkZXJzID0ge30sIGF0dHJuYW1lO1xuXG4gIGZvciAoYXR0cm5hbWUgaW4gYWxsSGVhZGVycykgeyBoZWFkZXJzW2F0dHJuYW1lXSA9IGFsbEhlYWRlcnNbYXR0cm5hbWVdOyB9XG4gIGZvciAoYXR0cm5hbWUgaW4gY29udGVudFR5cGVIZWFkZXJzKSB7IGhlYWRlcnNbYXR0cm5hbWVdID0gY29udGVudFR5cGVIZWFkZXJzW2F0dHJuYW1lXTsgfVxuXG4gIHZhciBib2R5ID0gdGhpcy5nZXRCb2R5KGNvbnRlbnRUeXBlSGVhZGVycywgYXJncywgb3B0cyk7XG4gIHZhciB1cmwgPSB0aGlzLnVybGlmeShhcmdzKTtcblxuICBpZih1cmwuaW5kZXhPZignLntmb3JtYXR9JykgPiAwKSB7XG4gICAgaWYoaGVhZGVycykge1xuICAgICAgdmFyIGZvcm1hdCA9IGhlYWRlcnMuQWNjZXB0IHx8IGhlYWRlcnMuYWNjZXB0O1xuICAgICAgaWYoZm9ybWF0ICYmIGZvcm1hdC5pbmRleE9mKCdqc29uJykgPiAwKSB7XG4gICAgICAgIHVybCA9IHVybC5yZXBsYWNlKCcue2Zvcm1hdH0nLCAnLmpzb24nKTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYoZm9ybWF0ICYmIGZvcm1hdC5pbmRleE9mKCd4bWwnKSA+IDApIHtcbiAgICAgICAgdXJsID0gdXJsLnJlcGxhY2UoJy57Zm9ybWF0fScsICcueG1sJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIG9iaiA9IHtcbiAgICB1cmw6IHVybCxcbiAgICBtZXRob2Q6IHRoaXMubWV0aG9kLnRvVXBwZXJDYXNlKCksXG4gICAgYm9keTogYm9keSxcbiAgICBlbmFibGVDb29raWVzOiBvcHRzLmVuYWJsZUNvb2tpZXMsXG4gICAgdXNlSlF1ZXJ5OiBvcHRzLnVzZUpRdWVyeSxcbiAgICBkZWZlcnJlZDogZGVmZXJyZWQsXG4gICAgaGVhZGVyczogaGVhZGVycyxcbiAgICBjbGllbnRBdXRob3JpemF0aW9uczogb3B0cy5jbGllbnRBdXRob3JpemF0aW9ucyxcbiAgICBvbjoge1xuICAgICAgcmVzcG9uc2U6IGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgICBpZiAoZGVmZXJyZWQpIHtcbiAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHJlc3BvbnNlKTtcbiAgICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gc3VjY2VzcyhyZXNwb25zZSwgcGFyZW50KTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGVycm9yOiBmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgICAgaWYgKGRlZmVycmVkKSB7XG4gICAgICAgICAgZGVmZXJyZWQucmVqZWN0KHJlc3BvbnNlKTtcbiAgICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gZXJyb3IocmVzcG9uc2UsIHBhcmVudCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgdGhpcy5jbGllbnRBdXRob3JpemF0aW9ucy5hcHBseShvYmosIHRoaXMub3BlcmF0aW9uLnNlY3VyaXR5KTtcbiAgaWYgKG9wdHMubW9jayA9PT0gdHJ1ZSkge1xuICAgIHJldHVybiBvYmo7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG5ldyBTd2FnZ2VySHR0cCgpLmV4ZWN1dGUob2JqLCBvcHRzKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gaXRlbUJ5UHJpb3JpdHkoY29sLCBpdGVtUHJpb3JpdHkpIHtcblxuICAvLyBObyBwcmlvcml0aWVzPyByZXR1cm4gZmlyc3QuLi5cbiAgaWYoXy5pc0VtcHR5KGl0ZW1Qcmlvcml0eSkpIHtcbiAgICByZXR1cm4gY29sWzBdO1xuICB9XG5cbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGl0ZW1Qcmlvcml0eS5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGlmKGNvbC5pbmRleE9mKGl0ZW1Qcmlvcml0eVtpXSkgPiAtMSkge1xuICAgICAgcmV0dXJuIGl0ZW1Qcmlvcml0eVtpXTtcbiAgICB9XG4gIH1cblxuICAvLyBPdGhlcndpc2UgcmV0dXJuIGZpcnN0XG4gIHJldHVybiBjb2xbMF07XG59XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuc2V0Q29udGVudFR5cGVzID0gZnVuY3Rpb24gKGFyZ3MsIG9wdHMpIHtcbiAgLy8gZGVmYXVsdCB0eXBlXG4gIHZhciBhbGxEZWZpbmVkUGFyYW1zID0gdGhpcy5wYXJhbWV0ZXJzO1xuICB2YXIgYm9keTtcbiAgdmFyIGNvbnN1bWVzID0gYXJncy5wYXJhbWV0ZXJDb250ZW50VHlwZSB8fCBpdGVtQnlQcmlvcml0eSh0aGlzLmNvbnN1bWVzLCBbJ2FwcGxpY2F0aW9uL2pzb24nLCAnYXBwbGljYXRpb24veWFtbCddKTtcbiAgdmFyIGFjY2VwdHMgPSBvcHRzLnJlc3BvbnNlQ29udGVudFR5cGUgfHwgaXRlbUJ5UHJpb3JpdHkodGhpcy5wcm9kdWNlcywgWydhcHBsaWNhdGlvbi9qc29uJywgJ2FwcGxpY2F0aW9uL3lhbWwnXSk7XG4gIHZhciBkZWZpbmVkRmlsZVBhcmFtcyA9IFtdO1xuICB2YXIgZGVmaW5lZEZvcm1QYXJhbXMgPSBbXTtcbiAgdmFyIGhlYWRlcnMgPSB7fTtcbiAgdmFyIGk7XG5cbiAgLy8gZ2V0IHBhcmFtcyBmcm9tIHRoZSBvcGVyYXRpb24gYW5kIHNldCB0aGVtIGluIGRlZmluZWRGaWxlUGFyYW1zLCBkZWZpbmVkRm9ybVBhcmFtcywgaGVhZGVyc1xuICBmb3IgKGkgPSAwOyBpIDwgYWxsRGVmaW5lZFBhcmFtcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwYXJhbSA9IGFsbERlZmluZWRQYXJhbXNbaV07XG5cbiAgICBpZiAocGFyYW0uaW4gPT09ICdmb3JtRGF0YScpIHtcbiAgICAgIGlmIChwYXJhbS50eXBlID09PSAnZmlsZScpIHtcbiAgICAgICAgZGVmaW5lZEZpbGVQYXJhbXMucHVzaChwYXJhbSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkZWZpbmVkRm9ybVBhcmFtcy5wdXNoKHBhcmFtKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHBhcmFtLmluID09PSAnaGVhZGVyJyAmJiBvcHRzKSB7XG4gICAgICB2YXIga2V5ID0gcGFyYW0ubmFtZTtcbiAgICAgIHZhciBoZWFkZXJWYWx1ZSA9IG9wdHNbcGFyYW0ubmFtZV07XG5cbiAgICAgIGlmICh0eXBlb2Ygb3B0c1twYXJhbS5uYW1lXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgaGVhZGVyc1trZXldID0gaGVhZGVyVmFsdWU7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChwYXJhbS5pbiA9PT0gJ2JvZHknICYmIHR5cGVvZiBhcmdzW3BhcmFtLm5hbWVdICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgYm9keSA9IGFyZ3NbcGFyYW0ubmFtZV07XG4gICAgfVxuICB9XG5cbiAgLy8gaWYgdGhlcmUncyBhIGJvZHksIG5lZWQgdG8gc2V0IHRoZSBjb25zdW1lcyBoZWFkZXIgdmlhIHJlcXVlc3RDb250ZW50VHlwZVxuICBpZiAodGhpcy5tZXRob2QgPT09ICdwb3N0JyB8fCB0aGlzLm1ldGhvZCA9PT0gJ3B1dCcgfHwgdGhpcy5tZXRob2QgPT09ICdwYXRjaCcgfHxcbiAgICAgICgodGhpcy5tZXRob2QgPT09ICdkZWxldGUnIHx8IHRoaXMubWV0aG9kID09PSAnZ2V0JykgJiYgYm9keSkgKSB7XG4gICAgaWYgKG9wdHMucmVxdWVzdENvbnRlbnRUeXBlKSB7XG4gICAgICBjb25zdW1lcyA9IG9wdHMucmVxdWVzdENvbnRlbnRUeXBlO1xuICAgIH1cbiAgICAvLyBpZiBhbnkgZm9ybSBwYXJhbXMsIGNvbnRlbnQgdHlwZSBtdXN0IGJlIHNldFxuICAgIGlmIChkZWZpbmVkRm9ybVBhcmFtcy5sZW5ndGggPiAwKSB7XG4gICAgICBpZiAob3B0cy5yZXF1ZXN0Q29udGVudFR5cGUpIHsgICAgICAgICAgICAgLy8gb3ZlcnJpZGUgaWYgc2V0XG4gICAgICAgIGNvbnN1bWVzID0gb3B0cy5yZXF1ZXN0Q29udGVudFR5cGU7XG4gICAgICB9IGVsc2UgaWYgKGRlZmluZWRGaWxlUGFyYW1zLmxlbmd0aCA+IDApIHsgLy8gaWYgYSBmaWxlLCBtdXN0IGJlIG11bHRpcGFydC9mb3JtLWRhdGFcbiAgICAgICAgY29uc3VtZXMgPSAnbXVsdGlwYXJ0L2Zvcm0tZGF0YSc7XG4gICAgICB9IGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGVmYXVsdCB0byB4LXd3dy1mcm9tLXVybGVuY29kZWRcbiAgICAgICAgY29uc3VtZXMgPSAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJztcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgZWxzZSB7XG4gICAgY29uc3VtZXMgPSBudWxsO1xuICB9XG5cbiAgaWYgKGNvbnN1bWVzICYmIHRoaXMuY29uc3VtZXMpIHtcbiAgICBpZiAodGhpcy5jb25zdW1lcy5pbmRleE9mKGNvbnN1bWVzKSA9PT0gLTEpIHtcbiAgICAgIGhlbHBlcnMubG9nKCdzZXJ2ZXIgZG9lc25cXCd0IGNvbnN1bWUgJyArIGNvbnN1bWVzICsgJywgdHJ5ICcgKyBKU09OLnN0cmluZ2lmeSh0aGlzLmNvbnN1bWVzKSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKCF0aGlzLm1hdGNoZXNBY2NlcHQoYWNjZXB0cykpIHtcbiAgICBoZWxwZXJzLmxvZygnc2VydmVyIGNhblxcJ3QgcHJvZHVjZSAnICsgYWNjZXB0cyk7XG4gIH1cblxuICBpZiAoKGNvbnN1bWVzICYmIGJvZHkgIT09ICcnKSB8fCAoY29uc3VtZXMgPT09ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnKSkge1xuICAgIGhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddID0gY29uc3VtZXM7XG4gIH1cblxuICBpZiAoYWNjZXB0cykge1xuICAgIGhlYWRlcnMuQWNjZXB0ID0gYWNjZXB0cztcbiAgfVxuXG4gIHJldHVybiBoZWFkZXJzO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHJlcXVlc3QgYWNjZXB0cyBoZWFkZXIgbWF0Y2hlcyBhbnl0aGluZyBpbiB0aGlzLnByb2R1Y2VzLlxuICogIElmIHRoaXMucHJvZHVjZXMgY29udGFpbnMgKiAvICosIGlnbm9yZSB0aGUgYWNjZXB0IGhlYWRlci5cbiAqIEBwYXJhbSB7c3RyaW5nPX0gYWNjZXB0cyBUaGUgY2xpZW50IHJlcXVlc3QgYWNjZXB0IGhlYWRlci5cbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbk9wZXJhdGlvbi5wcm90b3R5cGUubWF0Y2hlc0FjY2VwdCA9IGZ1bmN0aW9uKGFjY2VwdHMpIHtcbiAgLy8gbm8gYWNjZXB0cyBvciBwcm9kdWNlcywgbm8gcHJvYmxlbSFcbiAgaWYgKCFhY2NlcHRzIHx8ICF0aGlzLnByb2R1Y2VzKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIHRoaXMucHJvZHVjZXMuaW5kZXhPZihhY2NlcHRzKSAhPT0gLTEgfHwgdGhpcy5wcm9kdWNlcy5pbmRleE9mKCcqLyonKSAhPT0gLTE7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmFzQ3VybCA9IGZ1bmN0aW9uIChhcmdzMSwgYXJnczIpIHtcbiAgdmFyIG9wdHMgPSB7bW9jazogdHJ1ZX07XG4gIGlmICh0eXBlb2YgYXJnczIgPT09ICdvYmplY3QnKSB7XG4gICAgZm9yICh2YXIgYXJnS2V5IGluIGFyZ3MyKSB7XG4gICAgICBvcHRzW2FyZ0tleV0gPSBhcmdzMlthcmdLZXldO1xuICAgIH1cbiAgfVxuICB2YXIgb2JqID0gdGhpcy5leGVjdXRlKGFyZ3MxLCBvcHRzKTtcblxuICB0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zLmFwcGx5KG9iaiwgdGhpcy5vcGVyYXRpb24uc2VjdXJpdHkpO1xuXG4gIHZhciByZXN1bHRzID0gW107XG5cbiAgcmVzdWx0cy5wdXNoKCctWCAnICsgdGhpcy5tZXRob2QudG9VcHBlckNhc2UoKSk7XG5cbiAgaWYgKHR5cGVvZiBvYmouaGVhZGVycyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB2YXIga2V5O1xuXG4gICAgZm9yIChrZXkgaW4gb2JqLmhlYWRlcnMpIHtcbiAgICAgIHZhciB2YWx1ZSA9IG9iai5oZWFkZXJzW2tleV07XG4gICAgICBpZih0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKXtcbiAgICAgICAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKC9cXCcvZywgJ1xcXFx1MDAyNycpO1xuICAgICAgfVxuICAgICAgcmVzdWx0cy5wdXNoKCctLWhlYWRlciBcXCcnICsga2V5ICsgJzogJyArIHZhbHVlICsgJ1xcJycpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChvYmouYm9keSkge1xuICAgIHZhciBib2R5O1xuXG4gICAgaWYgKF8uaXNPYmplY3Qob2JqLmJvZHkpKSB7XG4gICAgICBib2R5ID0gSlNPTi5zdHJpbmdpZnkob2JqLmJvZHkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBib2R5ID0gb2JqLmJvZHk7XG4gICAgfVxuXG4gICAgcmVzdWx0cy5wdXNoKCctZCBcXCcnICsgYm9keS5yZXBsYWNlKC9cXCcvZywgJ1xcXFx1MDAyNycpICsgJ1xcJycpO1xuICB9XG5cbiAgcmV0dXJuICdjdXJsICcgKyAocmVzdWx0cy5qb2luKCcgJykpICsgJyBcXCcnICsgb2JqLnVybCArICdcXCcnO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5lbmNvZGVQYXRoQ29sbGVjdGlvbiA9IGZ1bmN0aW9uICh0eXBlLCBuYW1lLCB2YWx1ZSkge1xuICB2YXIgZW5jb2RlZCA9ICcnO1xuICB2YXIgaTtcbiAgdmFyIHNlcGFyYXRvciA9ICcnO1xuXG4gIGlmICh0eXBlID09PSAnc3N2Jykge1xuICAgIHNlcGFyYXRvciA9ICclMjAnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICd0c3YnKSB7XG4gICAgc2VwYXJhdG9yID0gJ1xcXFx0JztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAncGlwZXMnKSB7XG4gICAgc2VwYXJhdG9yID0gJ3wnO1xuICB9IGVsc2Uge1xuICAgIHNlcGFyYXRvciA9ICcsJztcbiAgfVxuXG4gIGZvciAoaSA9IDA7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKykge1xuICAgIGlmIChpID09PSAwKSB7XG4gICAgICBlbmNvZGVkID0gdGhpcy5lbmNvZGVRdWVyeVBhcmFtKHZhbHVlW2ldKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZW5jb2RlZCArPSBzZXBhcmF0b3IgKyB0aGlzLmVuY29kZVF1ZXJ5UGFyYW0odmFsdWVbaV0pO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBlbmNvZGVkO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5lbmNvZGVRdWVyeUNvbGxlY3Rpb24gPSBmdW5jdGlvbiAodHlwZSwgbmFtZSwgdmFsdWUpIHtcbiAgdmFyIGVuY29kZWQgPSAnJztcbiAgdmFyIGk7XG5cbiAgaWYgKHR5cGUgPT09ICdkZWZhdWx0JyB8fCB0eXBlID09PSAnbXVsdGknKSB7XG4gICAgZm9yIChpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoaSA+IDApIHtlbmNvZGVkICs9ICcmJzt9XG5cbiAgICAgIGVuY29kZWQgKz0gdGhpcy5lbmNvZGVRdWVyeVBhcmFtKG5hbWUpICsgJz0nICsgdGhpcy5lbmNvZGVRdWVyeVBhcmFtKHZhbHVlW2ldKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIHNlcGFyYXRvciA9ICcnO1xuXG4gICAgaWYgKHR5cGUgPT09ICdjc3YnKSB7XG4gICAgICBzZXBhcmF0b3IgPSAnLCc7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnc3N2Jykge1xuICAgICAgc2VwYXJhdG9yID0gJyUyMCc7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAndHN2Jykge1xuICAgICAgc2VwYXJhdG9yID0gJ1xcXFx0JztcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdwaXBlcycpIHtcbiAgICAgIHNlcGFyYXRvciA9ICd8JztcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdicmFja2V0cycpIHtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoaSAhPT0gMCkge1xuICAgICAgICAgIGVuY29kZWQgKz0gJyYnO1xuICAgICAgICB9XG5cbiAgICAgICAgZW5jb2RlZCArPSB0aGlzLmVuY29kZVF1ZXJ5UGFyYW0obmFtZSkgKyAnW109JyArIHRoaXMuZW5jb2RlUXVlcnlQYXJhbSh2YWx1ZVtpXSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHNlcGFyYXRvciAhPT0gJycpIHtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoaSA9PT0gMCkge1xuICAgICAgICAgIGVuY29kZWQgPSB0aGlzLmVuY29kZVF1ZXJ5UGFyYW0obmFtZSkgKyAnPScgKyB0aGlzLmVuY29kZVF1ZXJ5UGFyYW0odmFsdWVbaV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVuY29kZWQgKz0gc2VwYXJhdG9yICsgdGhpcy5lbmNvZGVRdWVyeVBhcmFtKHZhbHVlW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBlbmNvZGVkO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5lbmNvZGVRdWVyeVBhcmFtID0gZnVuY3Rpb24gKGFyZykge1xuICByZXR1cm4gZW5jb2RlVVJJQ29tcG9uZW50KGFyZyk7XG59O1xuXG4vKipcbiAqIFRPRE8gcmV2aXNpdCwgbWlnaHQgbm90IHdhbnQgdG8gbGVhdmUgJy8nXG4gKiovXG5PcGVyYXRpb24ucHJvdG90eXBlLmVuY29kZVBhdGhQYXJhbSA9IGZ1bmN0aW9uIChwYXRoUGFyYW0pIHtcbiAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudChwYXRoUGFyYW0pO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIE9wZXJhdGlvbkdyb3VwID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAodGFnLCBkZXNjcmlwdGlvbiwgZXh0ZXJuYWxEb2NzLCBvcGVyYXRpb24pIHtcbiAgdGhpcy5kZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uO1xuICB0aGlzLmV4dGVybmFsRG9jcyA9IGV4dGVybmFsRG9jcztcbiAgdGhpcy5uYW1lID0gdGFnO1xuICB0aGlzLm9wZXJhdGlvbiA9IG9wZXJhdGlvbjtcbiAgdGhpcy5vcGVyYXRpb25zQXJyYXkgPSBbXTtcbiAgdGhpcy5wYXRoID0gdGFnO1xuICB0aGlzLnRhZyA9IHRhZztcbn07XG5cbk9wZXJhdGlvbkdyb3VwLnByb3RvdHlwZS5zb3J0ID0gZnVuY3Rpb24gKCkge1xuXG59O1xuXG4iLG51bGwsIi8vIHNoaW0gZm9yIHVzaW5nIHByb2Nlc3MgaW4gYnJvd3NlclxuXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG52YXIgcXVldWUgPSBbXTtcbnZhciBkcmFpbmluZyA9IGZhbHNlO1xuXG5mdW5jdGlvbiBkcmFpblF1ZXVlKCkge1xuICAgIGlmIChkcmFpbmluZykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGRyYWluaW5nID0gdHJ1ZTtcbiAgICB2YXIgY3VycmVudFF1ZXVlO1xuICAgIHZhciBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgd2hpbGUobGVuKSB7XG4gICAgICAgIGN1cnJlbnRRdWV1ZSA9IHF1ZXVlO1xuICAgICAgICBxdWV1ZSA9IFtdO1xuICAgICAgICB2YXIgaSA9IC0xO1xuICAgICAgICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgICAgICAgICBjdXJyZW50UXVldWVbaV0oKTtcbiAgICAgICAgfVxuICAgICAgICBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgfVxuICAgIGRyYWluaW5nID0gZmFsc2U7XG59XG5wcm9jZXNzLm5leHRUaWNrID0gZnVuY3Rpb24gKGZ1bikge1xuICAgIHF1ZXVlLnB1c2goZnVuKTtcbiAgICBpZiAoIWRyYWluaW5nKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZHJhaW5RdWV1ZSwgMCk7XG4gICAgfVxufTtcblxucHJvY2Vzcy50aXRsZSA9ICdicm93c2VyJztcbnByb2Nlc3MuYnJvd3NlciA9IHRydWU7XG5wcm9jZXNzLmVudiA9IHt9O1xucHJvY2Vzcy5hcmd2ID0gW107XG5wcm9jZXNzLnZlcnNpb24gPSAnJzsgLy8gZW1wdHkgc3RyaW5nIHRvIGF2b2lkIHJlZ2V4cCBpc3N1ZXNcbnByb2Nlc3MudmVyc2lvbnMgPSB7fTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnByb2Nlc3Mub24gPSBub29wO1xucHJvY2Vzcy5hZGRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLm9uY2UgPSBub29wO1xucHJvY2Vzcy5vZmYgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUFsbExpc3RlbmVycyA9IG5vb3A7XG5wcm9jZXNzLmVtaXQgPSBub29wO1xuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5cbi8vIFRPRE8oc2h0eWxtYW4pXG5wcm9jZXNzLmN3ZCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuICcvJyB9O1xucHJvY2Vzcy5jaGRpciA9IGZ1bmN0aW9uIChkaXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuY2hkaXIgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcbnByb2Nlc3MudW1hc2sgPSBmdW5jdGlvbigpIHsgcmV0dXJuIDA7IH07XG4iLCIoZnVuY3Rpb24gKEJ1ZmZlcil7XG4oZnVuY3Rpb24gKCkge1xuICBcInVzZSBzdHJpY3RcIjtcblxuICBmdW5jdGlvbiBidG9hKHN0cikge1xuICAgIHZhciBidWZmZXJcbiAgICAgIDtcblxuICAgIGlmIChzdHIgaW5zdGFuY2VvZiBCdWZmZXIpIHtcbiAgICAgIGJ1ZmZlciA9IHN0cjtcbiAgICB9IGVsc2Uge1xuICAgICAgYnVmZmVyID0gbmV3IEJ1ZmZlcihzdHIudG9TdHJpbmcoKSwgJ2JpbmFyeScpO1xuICAgIH1cblxuICAgIHJldHVybiBidWZmZXIudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICB9XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBidG9hO1xufSgpKTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyKVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ6dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiSW01dlpHVmZiVzlrZFd4bGN5OWlkRzloTDJsdVpHVjRMbXB6SWwwc0ltNWhiV1Z6SWpwYlhTd2liV0Z3Y0dsdVozTWlPaUk3UVVGQlFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFTSXNJbVpwYkdVaU9pSm5aVzVsY21GMFpXUXVhbk1pTENKemIzVnlZMlZTYjI5MElqb2lJaXdpYzI5MWNtTmxjME52Ym5SbGJuUWlPbHNpS0daMWJtTjBhVzl1SUNncElIdGNiaUFnWENKMWMyVWdjM1J5YVdOMFhDSTdYRzVjYmlBZ1puVnVZM1JwYjI0Z1luUnZZU2h6ZEhJcElIdGNiaUFnSUNCMllYSWdZblZtWm1WeVhHNGdJQ0FnSUNBN1hHNWNiaUFnSUNCcFppQW9jM1J5SUdsdWMzUmhibU5sYjJZZ1FuVm1abVZ5S1NCN1hHNGdJQ0FnSUNCaWRXWm1aWElnUFNCemRISTdYRzRnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUdKMVptWmxjaUE5SUc1bGR5QkNkV1ptWlhJb2MzUnlMblJ2VTNSeWFXNW5LQ2tzSUNkaWFXNWhjbmtuS1R0Y2JpQWdJQ0I5WEc1Y2JpQWdJQ0J5WlhSMWNtNGdZblZtWm1WeUxuUnZVM1J5YVc1bktDZGlZWE5sTmpRbktUdGNiaUFnZlZ4dVhHNGdJRzF2WkhWc1pTNWxlSEJ2Y25SeklEMGdZblJ2WVR0Y2JuMG9LU2s3WEc0aVhYMD0iLCIvKiFcbiAqIFRoZSBidWZmZXIgbW9kdWxlIGZyb20gbm9kZS5qcywgZm9yIHRoZSBicm93c2VyLlxuICpcbiAqIEBhdXRob3IgICBGZXJvc3MgQWJvdWtoYWRpamVoIDxmZXJvc3NAZmVyb3NzLm9yZz4gPGh0dHA6Ly9mZXJvc3Mub3JnPlxuICogQGxpY2Vuc2UgIE1JVFxuICovXG5cbnZhciBiYXNlNjQgPSByZXF1aXJlKCdiYXNlNjQtanMnKVxudmFyIGllZWU3NTQgPSByZXF1aXJlKCdpZWVlNzU0JylcbnZhciBpc0FycmF5ID0gcmVxdWlyZSgnaXMtYXJyYXknKVxuXG5leHBvcnRzLkJ1ZmZlciA9IEJ1ZmZlclxuZXhwb3J0cy5TbG93QnVmZmVyID0gU2xvd0J1ZmZlclxuZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUyA9IDUwXG5CdWZmZXIucG9vbFNpemUgPSA4MTkyIC8vIG5vdCB1c2VkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb25cblxudmFyIHJvb3RQYXJlbnQgPSB7fVxuXG4vKipcbiAqIElmIGBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVGA6XG4gKiAgID09PSB0cnVlICAgIFVzZSBVaW50OEFycmF5IGltcGxlbWVudGF0aW9uIChmYXN0ZXN0KVxuICogICA9PT0gZmFsc2UgICBVc2UgT2JqZWN0IGltcGxlbWVudGF0aW9uIChtb3N0IGNvbXBhdGlibGUsIGV2ZW4gSUU2KVxuICpcbiAqIEJyb3dzZXJzIHRoYXQgc3VwcG9ydCB0eXBlZCBhcnJheXMgYXJlIElFIDEwKywgRmlyZWZveCA0KywgQ2hyb21lIDcrLCBTYWZhcmkgNS4xKyxcbiAqIE9wZXJhIDExLjYrLCBpT1MgNC4yKy5cbiAqXG4gKiBEdWUgdG8gdmFyaW91cyBicm93c2VyIGJ1Z3MsIHNvbWV0aW1lcyB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uIHdpbGwgYmUgdXNlZCBldmVuXG4gKiB3aGVuIHRoZSBicm93c2VyIHN1cHBvcnRzIHR5cGVkIGFycmF5cy5cbiAqXG4gKiBOb3RlOlxuICpcbiAqICAgLSBGaXJlZm94IDQtMjkgbGFja3Mgc3VwcG9ydCBmb3IgYWRkaW5nIG5ldyBwcm9wZXJ0aWVzIHRvIGBVaW50OEFycmF5YCBpbnN0YW5jZXMsXG4gKiAgICAgU2VlOiBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD02OTU0MzguXG4gKlxuICogICAtIFNhZmFyaSA1LTcgbGFja3Mgc3VwcG9ydCBmb3IgY2hhbmdpbmcgdGhlIGBPYmplY3QucHJvdG90eXBlLmNvbnN0cnVjdG9yYCBwcm9wZXJ0eVxuICogICAgIG9uIG9iamVjdHMuXG4gKlxuICogICAtIENocm9tZSA5LTEwIGlzIG1pc3NpbmcgdGhlIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24uXG4gKlxuICogICAtIElFMTAgaGFzIGEgYnJva2VuIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyBhcnJheXMgb2ZcbiAqICAgICBpbmNvcnJlY3QgbGVuZ3RoIGluIHNvbWUgc2l0dWF0aW9ucy5cblxuICogV2UgZGV0ZWN0IHRoZXNlIGJ1Z2d5IGJyb3dzZXJzIGFuZCBzZXQgYEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUYCB0byBgZmFsc2VgIHNvIHRoZXlcbiAqIGdldCB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uLCB3aGljaCBpcyBzbG93ZXIgYnV0IGJlaGF2ZXMgY29ycmVjdGx5LlxuICovXG5CdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCA9IChmdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIEJhciAoKSB7fVxuICB0cnkge1xuICAgIHZhciBhcnIgPSBuZXcgVWludDhBcnJheSgxKVxuICAgIGFyci5mb28gPSBmdW5jdGlvbiAoKSB7IHJldHVybiA0MiB9XG4gICAgYXJyLmNvbnN0cnVjdG9yID0gQmFyXG4gICAgcmV0dXJuIGFyci5mb28oKSA9PT0gNDIgJiYgLy8gdHlwZWQgYXJyYXkgaW5zdGFuY2VzIGNhbiBiZSBhdWdtZW50ZWRcbiAgICAgICAgYXJyLmNvbnN0cnVjdG9yID09PSBCYXIgJiYgLy8gY29uc3RydWN0b3IgY2FuIGJlIHNldFxuICAgICAgICB0eXBlb2YgYXJyLnN1YmFycmF5ID09PSAnZnVuY3Rpb24nICYmIC8vIGNocm9tZSA5LTEwIGxhY2sgYHN1YmFycmF5YFxuICAgICAgICBhcnIuc3ViYXJyYXkoMSwgMSkuYnl0ZUxlbmd0aCA9PT0gMCAvLyBpZTEwIGhhcyBicm9rZW4gYHN1YmFycmF5YFxuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbn0pKClcblxuZnVuY3Rpb24ga01heExlbmd0aCAoKSB7XG4gIHJldHVybiBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVFxuICAgID8gMHg3ZmZmZmZmZlxuICAgIDogMHgzZmZmZmZmZlxufVxuXG4vKipcbiAqIENsYXNzOiBCdWZmZXJcbiAqID09PT09PT09PT09PT1cbiAqXG4gKiBUaGUgQnVmZmVyIGNvbnN0cnVjdG9yIHJldHVybnMgaW5zdGFuY2VzIG9mIGBVaW50OEFycmF5YCB0aGF0IGFyZSBhdWdtZW50ZWRcbiAqIHdpdGggZnVuY3Rpb24gcHJvcGVydGllcyBmb3IgYWxsIHRoZSBub2RlIGBCdWZmZXJgIEFQSSBmdW5jdGlvbnMuIFdlIHVzZVxuICogYFVpbnQ4QXJyYXlgIHNvIHRoYXQgc3F1YXJlIGJyYWNrZXQgbm90YXRpb24gd29ya3MgYXMgZXhwZWN0ZWQgLS0gaXQgcmV0dXJuc1xuICogYSBzaW5nbGUgb2N0ZXQuXG4gKlxuICogQnkgYXVnbWVudGluZyB0aGUgaW5zdGFuY2VzLCB3ZSBjYW4gYXZvaWQgbW9kaWZ5aW5nIHRoZSBgVWludDhBcnJheWBcbiAqIHByb3RvdHlwZS5cbiAqL1xuZnVuY3Rpb24gQnVmZmVyIChhcmcpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEJ1ZmZlcikpIHtcbiAgICAvLyBBdm9pZCBnb2luZyB0aHJvdWdoIGFuIEFyZ3VtZW50c0FkYXB0b3JUcmFtcG9saW5lIGluIHRoZSBjb21tb24gY2FzZS5cbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHJldHVybiBuZXcgQnVmZmVyKGFyZywgYXJndW1lbnRzWzFdKVxuICAgIHJldHVybiBuZXcgQnVmZmVyKGFyZylcbiAgfVxuXG4gIHRoaXMubGVuZ3RoID0gMFxuICB0aGlzLnBhcmVudCA9IHVuZGVmaW5lZFxuXG4gIC8vIENvbW1vbiBjYXNlLlxuICBpZiAodHlwZW9mIGFyZyA9PT0gJ251bWJlcicpIHtcbiAgICByZXR1cm4gZnJvbU51bWJlcih0aGlzLCBhcmcpXG4gIH1cblxuICAvLyBTbGlnaHRseSBsZXNzIGNvbW1vbiBjYXNlLlxuICBpZiAodHlwZW9mIGFyZyA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZnJvbVN0cmluZyh0aGlzLCBhcmcsIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogJ3V0ZjgnKVxuICB9XG5cbiAgLy8gVW51c3VhbC5cbiAgcmV0dXJuIGZyb21PYmplY3QodGhpcywgYXJnKVxufVxuXG5mdW5jdGlvbiBmcm9tTnVtYmVyICh0aGF0LCBsZW5ndGgpIHtcbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aCA8IDAgPyAwIDogY2hlY2tlZChsZW5ndGgpIHwgMClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoYXRbaV0gPSAwXG4gICAgfVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21TdHJpbmcgKHRoYXQsIHN0cmluZywgZW5jb2RpbmcpIHtcbiAgaWYgKHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycgfHwgZW5jb2RpbmcgPT09ICcnKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIC8vIEFzc3VtcHRpb246IGJ5dGVMZW5ndGgoKSByZXR1cm4gdmFsdWUgaXMgYWx3YXlzIDwga01heExlbmd0aC5cbiAgdmFyIGxlbmd0aCA9IGJ5dGVMZW5ndGgoc3RyaW5nLCBlbmNvZGluZykgfCAwXG4gIHRoYXQgPSBhbGxvY2F0ZSh0aGF0LCBsZW5ndGgpXG5cbiAgdGhhdC53cml0ZShzdHJpbmcsIGVuY29kaW5nKVxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tT2JqZWN0ICh0aGF0LCBvYmplY3QpIHtcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihvYmplY3QpKSByZXR1cm4gZnJvbUJ1ZmZlcih0aGF0LCBvYmplY3QpXG5cbiAgaWYgKGlzQXJyYXkob2JqZWN0KSkgcmV0dXJuIGZyb21BcnJheSh0aGF0LCBvYmplY3QpXG5cbiAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignbXVzdCBzdGFydCB3aXRoIG51bWJlciwgYnVmZmVyLCBhcnJheSBvciBzdHJpbmcnKVxuICB9XG5cbiAgaWYgKHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBpZiAob2JqZWN0LmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgICByZXR1cm4gZnJvbVR5cGVkQXJyYXkodGhhdCwgb2JqZWN0KVxuICAgIH1cbiAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICAgIHJldHVybiBmcm9tQXJyYXlCdWZmZXIodGhhdCwgb2JqZWN0KVxuICAgIH1cbiAgfVxuXG4gIGlmIChvYmplY3QubGVuZ3RoKSByZXR1cm4gZnJvbUFycmF5TGlrZSh0aGF0LCBvYmplY3QpXG5cbiAgcmV0dXJuIGZyb21Kc29uT2JqZWN0KHRoYXQsIG9iamVjdClcbn1cblxuZnVuY3Rpb24gZnJvbUJ1ZmZlciAodGhhdCwgYnVmZmVyKSB7XG4gIHZhciBsZW5ndGggPSBjaGVja2VkKGJ1ZmZlci5sZW5ndGgpIHwgMFxuICB0aGF0ID0gYWxsb2NhdGUodGhhdCwgbGVuZ3RoKVxuICBidWZmZXIuY29weSh0aGF0LCAwLCAwLCBsZW5ndGgpXG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheSAodGhhdCwgYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGNoZWNrZWQoYXJyYXkubGVuZ3RoKSB8IDBcbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aClcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgIHRoYXRbaV0gPSBhcnJheVtpXSAmIDI1NVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbi8vIER1cGxpY2F0ZSBvZiBmcm9tQXJyYXkoKSB0byBrZWVwIGZyb21BcnJheSgpIG1vbm9tb3JwaGljLlxuZnVuY3Rpb24gZnJvbVR5cGVkQXJyYXkgKHRoYXQsIGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIHRoYXQgPSBhbGxvY2F0ZSh0aGF0LCBsZW5ndGgpXG4gIC8vIFRydW5jYXRpbmcgdGhlIGVsZW1lbnRzIGlzIHByb2JhYmx5IG5vdCB3aGF0IHBlb3BsZSBleHBlY3QgZnJvbSB0eXBlZFxuICAvLyBhcnJheXMgd2l0aCBCWVRFU19QRVJfRUxFTUVOVCA+IDEgYnV0IGl0J3MgY29tcGF0aWJsZSB3aXRoIHRoZSBiZWhhdmlvclxuICAvLyBvZiB0aGUgb2xkIEJ1ZmZlciBjb25zdHJ1Y3Rvci5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgIHRoYXRbaV0gPSBhcnJheVtpXSAmIDI1NVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUJ1ZmZlciAodGhhdCwgYXJyYXkpIHtcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2UsIGZvciBiZXN0IHBlcmZvcm1hbmNlXG4gICAgYXJyYXkuYnl0ZUxlbmd0aFxuICAgIHRoYXQgPSBCdWZmZXIuX2F1Z21lbnQobmV3IFVpbnQ4QXJyYXkoYXJyYXkpKVxuICB9IGVsc2Uge1xuICAgIC8vIEZhbGxiYWNrOiBSZXR1cm4gYW4gb2JqZWN0IGluc3RhbmNlIG9mIHRoZSBCdWZmZXIgY2xhc3NcbiAgICB0aGF0ID0gZnJvbVR5cGVkQXJyYXkodGhhdCwgbmV3IFVpbnQ4QXJyYXkoYXJyYXkpKVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUxpa2UgKHRoYXQsIGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIHRoYXQgPSBhbGxvY2F0ZSh0aGF0LCBsZW5ndGgpXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICB0aGF0W2ldID0gYXJyYXlbaV0gJiAyNTVcbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG4vLyBEZXNlcmlhbGl6ZSB7IHR5cGU6ICdCdWZmZXInLCBkYXRhOiBbMSwyLDMsLi4uXSB9IGludG8gYSBCdWZmZXIgb2JqZWN0LlxuLy8gUmV0dXJucyBhIHplcm8tbGVuZ3RoIGJ1ZmZlciBmb3IgaW5wdXRzIHRoYXQgZG9uJ3QgY29uZm9ybSB0byB0aGUgc3BlYy5cbmZ1bmN0aW9uIGZyb21Kc29uT2JqZWN0ICh0aGF0LCBvYmplY3QpIHtcbiAgdmFyIGFycmF5XG4gIHZhciBsZW5ndGggPSAwXG5cbiAgaWYgKG9iamVjdC50eXBlID09PSAnQnVmZmVyJyAmJiBpc0FycmF5KG9iamVjdC5kYXRhKSkge1xuICAgIGFycmF5ID0gb2JqZWN0LmRhdGFcbiAgICBsZW5ndGggPSBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIH1cbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aClcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgdGhhdFtpXSA9IGFycmF5W2ldICYgMjU1XG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gYWxsb2NhdGUgKHRoYXQsIGxlbmd0aCkge1xuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZSwgZm9yIGJlc3QgcGVyZm9ybWFuY2VcbiAgICB0aGF0ID0gQnVmZmVyLl9hdWdtZW50KG5ldyBVaW50OEFycmF5KGxlbmd0aCkpXG4gIH0gZWxzZSB7XG4gICAgLy8gRmFsbGJhY2s6IFJldHVybiBhbiBvYmplY3QgaW5zdGFuY2Ugb2YgdGhlIEJ1ZmZlciBjbGFzc1xuICAgIHRoYXQubGVuZ3RoID0gbGVuZ3RoXG4gICAgdGhhdC5faXNCdWZmZXIgPSB0cnVlXG4gIH1cblxuICB2YXIgZnJvbVBvb2wgPSBsZW5ndGggIT09IDAgJiYgbGVuZ3RoIDw9IEJ1ZmZlci5wb29sU2l6ZSA+Pj4gMVxuICBpZiAoZnJvbVBvb2wpIHRoYXQucGFyZW50ID0gcm9vdFBhcmVudFxuXG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGNoZWNrZWQgKGxlbmd0aCkge1xuICAvLyBOb3RlOiBjYW5ub3QgdXNlIGBsZW5ndGggPCBrTWF4TGVuZ3RoYCBoZXJlIGJlY2F1c2UgdGhhdCBmYWlscyB3aGVuXG4gIC8vIGxlbmd0aCBpcyBOYU4gKHdoaWNoIGlzIG90aGVyd2lzZSBjb2VyY2VkIHRvIHplcm8uKVxuICBpZiAobGVuZ3RoID49IGtNYXhMZW5ndGgoKSkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdBdHRlbXB0IHRvIGFsbG9jYXRlIEJ1ZmZlciBsYXJnZXIgdGhhbiBtYXhpbXVtICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICdzaXplOiAweCcgKyBrTWF4TGVuZ3RoKCkudG9TdHJpbmcoMTYpICsgJyBieXRlcycpXG4gIH1cbiAgcmV0dXJuIGxlbmd0aCB8IDBcbn1cblxuZnVuY3Rpb24gU2xvd0J1ZmZlciAoc3ViamVjdCwgZW5jb2RpbmcpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFNsb3dCdWZmZXIpKSByZXR1cm4gbmV3IFNsb3dCdWZmZXIoc3ViamVjdCwgZW5jb2RpbmcpXG5cbiAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIoc3ViamVjdCwgZW5jb2RpbmcpXG4gIGRlbGV0ZSBidWYucGFyZW50XG4gIHJldHVybiBidWZcbn1cblxuQnVmZmVyLmlzQnVmZmVyID0gZnVuY3Rpb24gaXNCdWZmZXIgKGIpIHtcbiAgcmV0dXJuICEhKGIgIT0gbnVsbCAmJiBiLl9pc0J1ZmZlcilcbn1cblxuQnVmZmVyLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlIChhLCBiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGEpIHx8ICFCdWZmZXIuaXNCdWZmZXIoYikpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudHMgbXVzdCBiZSBCdWZmZXJzJylcbiAgfVxuXG4gIGlmIChhID09PSBiKSByZXR1cm4gMFxuXG4gIHZhciB4ID0gYS5sZW5ndGhcbiAgdmFyIHkgPSBiLmxlbmd0aFxuXG4gIHZhciBpID0gMFxuICB2YXIgbGVuID0gTWF0aC5taW4oeCwgeSlcbiAgd2hpbGUgKGkgPCBsZW4pIHtcbiAgICBpZiAoYVtpXSAhPT0gYltpXSkgYnJlYWtcblxuICAgICsraVxuICB9XG5cbiAgaWYgKGkgIT09IGxlbikge1xuICAgIHggPSBhW2ldXG4gICAgeSA9IGJbaV1cbiAgfVxuXG4gIGlmICh4IDwgeSkgcmV0dXJuIC0xXG4gIGlmICh5IDwgeCkgcmV0dXJuIDFcbiAgcmV0dXJuIDBcbn1cblxuQnVmZmVyLmlzRW5jb2RpbmcgPSBmdW5jdGlvbiBpc0VuY29kaW5nIChlbmNvZGluZykge1xuICBzd2l0Y2ggKFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKSkge1xuICAgIGNhc2UgJ2hleCc6XG4gICAgY2FzZSAndXRmOCc6XG4gICAgY2FzZSAndXRmLTgnOlxuICAgIGNhc2UgJ2FzY2lpJzpcbiAgICBjYXNlICdiaW5hcnknOlxuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgY2FzZSAncmF3JzpcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgcmV0dXJuIHRydWVcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuQnVmZmVyLmNvbmNhdCA9IGZ1bmN0aW9uIGNvbmNhdCAobGlzdCwgbGVuZ3RoKSB7XG4gIGlmICghaXNBcnJheShsaXN0KSkgdGhyb3cgbmV3IFR5cGVFcnJvcignbGlzdCBhcmd1bWVudCBtdXN0IGJlIGFuIEFycmF5IG9mIEJ1ZmZlcnMuJylcblxuICBpZiAobGlzdC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gbmV3IEJ1ZmZlcigwKVxuICB9XG5cbiAgdmFyIGlcbiAgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbGVuZ3RoID0gMFxuICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBsZW5ndGggKz0gbGlzdFtpXS5sZW5ndGhcbiAgICB9XG4gIH1cblxuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcihsZW5ndGgpXG4gIHZhciBwb3MgPSAwXG4gIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGl0ZW0gPSBsaXN0W2ldXG4gICAgaXRlbS5jb3B5KGJ1ZiwgcG9zKVxuICAgIHBvcyArPSBpdGVtLmxlbmd0aFxuICB9XG4gIHJldHVybiBidWZcbn1cblxuZnVuY3Rpb24gYnl0ZUxlbmd0aCAoc3RyaW5nLCBlbmNvZGluZykge1xuICBpZiAodHlwZW9mIHN0cmluZyAhPT0gJ3N0cmluZycpIHN0cmluZyA9ICcnICsgc3RyaW5nXG5cbiAgdmFyIGxlbiA9IHN0cmluZy5sZW5ndGhcbiAgaWYgKGxlbiA9PT0gMCkgcmV0dXJuIDBcblxuICAvLyBVc2UgYSBmb3IgbG9vcCB0byBhdm9pZCByZWN1cnNpb25cbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcbiAgZm9yICg7Oykge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAvLyBEZXByZWNhdGVkXG4gICAgICBjYXNlICdyYXcnOlxuICAgICAgY2FzZSAncmF3cyc6XG4gICAgICAgIHJldHVybiBsZW5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGhcbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiBsZW4gKiAyXG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gbGVuID4+PiAxXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICByZXR1cm4gYmFzZTY0VG9CeXRlcyhzdHJpbmcpLmxlbmd0aFxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSByZXR1cm4gdXRmOFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGggLy8gYXNzdW1lIHV0ZjhcbiAgICAgICAgZW5jb2RpbmcgPSAoJycgKyBlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cbkJ1ZmZlci5ieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aFxuXG4vLyBwcmUtc2V0IGZvciB2YWx1ZXMgdGhhdCBtYXkgZXhpc3QgaW4gdGhlIGZ1dHVyZVxuQnVmZmVyLnByb3RvdHlwZS5sZW5ndGggPSB1bmRlZmluZWRcbkJ1ZmZlci5wcm90b3R5cGUucGFyZW50ID0gdW5kZWZpbmVkXG5cbmZ1bmN0aW9uIHNsb3dUb1N0cmluZyAoZW5jb2RpbmcsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcblxuICBzdGFydCA9IHN0YXJ0IHwgMFxuICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCB8fCBlbmQgPT09IEluZmluaXR5ID8gdGhpcy5sZW5ndGggOiBlbmQgfCAwXG5cbiAgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSAndXRmOCdcbiAgaWYgKHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIGlmIChlbmQgPiB0aGlzLmxlbmd0aCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKGVuZCA8PSBzdGFydCkgcmV0dXJuICcnXG5cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gaGV4U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgICByZXR1cm4gYXNjaWlTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gYmluYXJ5U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgcmV0dXJuIGJhc2U2NFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiB1dGYxNmxlU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgICAgIGVuY29kaW5nID0gKGVuY29kaW5nICsgJycpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZyAoKSB7XG4gIHZhciBsZW5ndGggPSB0aGlzLmxlbmd0aCB8IDBcbiAgaWYgKGxlbmd0aCA9PT0gMCkgcmV0dXJuICcnXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSByZXR1cm4gdXRmOFNsaWNlKHRoaXMsIDAsIGxlbmd0aClcbiAgcmV0dXJuIHNsb3dUb1N0cmluZy5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gZXF1YWxzIChiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyJylcbiAgaWYgKHRoaXMgPT09IGIpIHJldHVybiB0cnVlXG4gIHJldHVybiBCdWZmZXIuY29tcGFyZSh0aGlzLCBiKSA9PT0gMFxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluc3BlY3QgPSBmdW5jdGlvbiBpbnNwZWN0ICgpIHtcbiAgdmFyIHN0ciA9ICcnXG4gIHZhciBtYXggPSBleHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTXG4gIGlmICh0aGlzLmxlbmd0aCA+IDApIHtcbiAgICBzdHIgPSB0aGlzLnRvU3RyaW5nKCdoZXgnLCAwLCBtYXgpLm1hdGNoKC8uezJ9L2cpLmpvaW4oJyAnKVxuICAgIGlmICh0aGlzLmxlbmd0aCA+IG1heCkgc3RyICs9ICcgLi4uICdcbiAgfVxuICByZXR1cm4gJzxCdWZmZXIgJyArIHN0ciArICc+J1xufVxuXG5CdWZmZXIucHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlIChiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyJylcbiAgaWYgKHRoaXMgPT09IGIpIHJldHVybiAwXG4gIHJldHVybiBCdWZmZXIuY29tcGFyZSh0aGlzLCBiKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluZGV4T2YgPSBmdW5jdGlvbiBpbmRleE9mICh2YWwsIGJ5dGVPZmZzZXQpIHtcbiAgaWYgKGJ5dGVPZmZzZXQgPiAweDdmZmZmZmZmKSBieXRlT2Zmc2V0ID0gMHg3ZmZmZmZmZlxuICBlbHNlIGlmIChieXRlT2Zmc2V0IDwgLTB4ODAwMDAwMDApIGJ5dGVPZmZzZXQgPSAtMHg4MDAwMDAwMFxuICBieXRlT2Zmc2V0ID4+PSAwXG5cbiAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gLTFcbiAgaWYgKGJ5dGVPZmZzZXQgPj0gdGhpcy5sZW5ndGgpIHJldHVybiAtMVxuXG4gIC8vIE5lZ2F0aXZlIG9mZnNldHMgc3RhcnQgZnJvbSB0aGUgZW5kIG9mIHRoZSBidWZmZXJcbiAgaWYgKGJ5dGVPZmZzZXQgPCAwKSBieXRlT2Zmc2V0ID0gTWF0aC5tYXgodGhpcy5sZW5ndGggKyBieXRlT2Zmc2V0LCAwKVxuXG4gIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgIGlmICh2YWwubGVuZ3RoID09PSAwKSByZXR1cm4gLTEgLy8gc3BlY2lhbCBjYXNlOiBsb29raW5nIGZvciBlbXB0eSBzdHJpbmcgYWx3YXlzIGZhaWxzXG4gICAgcmV0dXJuIFN0cmluZy5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKHRoaXMsIHZhbCwgYnl0ZU9mZnNldClcbiAgfVxuICBpZiAoQnVmZmVyLmlzQnVmZmVyKHZhbCkpIHtcbiAgICByZXR1cm4gYXJyYXlJbmRleE9mKHRoaXMsIHZhbCwgYnl0ZU9mZnNldClcbiAgfVxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgJiYgVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIFVpbnQ4QXJyYXkucHJvdG90eXBlLmluZGV4T2YuY2FsbCh0aGlzLCB2YWwsIGJ5dGVPZmZzZXQpXG4gICAgfVxuICAgIHJldHVybiBhcnJheUluZGV4T2YodGhpcywgWyB2YWwgXSwgYnl0ZU9mZnNldClcbiAgfVxuXG4gIGZ1bmN0aW9uIGFycmF5SW5kZXhPZiAoYXJyLCB2YWwsIGJ5dGVPZmZzZXQpIHtcbiAgICB2YXIgZm91bmRJbmRleCA9IC0xXG4gICAgZm9yICh2YXIgaSA9IDA7IGJ5dGVPZmZzZXQgKyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoYXJyW2J5dGVPZmZzZXQgKyBpXSA9PT0gdmFsW2ZvdW5kSW5kZXggPT09IC0xID8gMCA6IGkgLSBmb3VuZEluZGV4XSkge1xuICAgICAgICBpZiAoZm91bmRJbmRleCA9PT0gLTEpIGZvdW5kSW5kZXggPSBpXG4gICAgICAgIGlmIChpIC0gZm91bmRJbmRleCArIDEgPT09IHZhbC5sZW5ndGgpIHJldHVybiBieXRlT2Zmc2V0ICsgZm91bmRJbmRleFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm91bmRJbmRleCA9IC0xXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiAtMVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcigndmFsIG11c3QgYmUgc3RyaW5nLCBudW1iZXIgb3IgQnVmZmVyJylcbn1cblxuLy8gYGdldGAgaXMgZGVwcmVjYXRlZFxuQnVmZmVyLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiBnZXQgKG9mZnNldCkge1xuICBjb25zb2xlLmxvZygnLmdldCgpIGlzIGRlcHJlY2F0ZWQuIEFjY2VzcyB1c2luZyBhcnJheSBpbmRleGVzIGluc3RlYWQuJylcbiAgcmV0dXJuIHRoaXMucmVhZFVJbnQ4KG9mZnNldClcbn1cblxuLy8gYHNldGAgaXMgZGVwcmVjYXRlZFxuQnVmZmVyLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiBzZXQgKHYsIG9mZnNldCkge1xuICBjb25zb2xlLmxvZygnLnNldCgpIGlzIGRlcHJlY2F0ZWQuIEFjY2VzcyB1c2luZyBhcnJheSBpbmRleGVzIGluc3RlYWQuJylcbiAgcmV0dXJuIHRoaXMud3JpdGVVSW50OCh2LCBvZmZzZXQpXG59XG5cbmZ1bmN0aW9uIGhleFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgb2Zmc2V0ID0gTnVtYmVyKG9mZnNldCkgfHwgMFxuICB2YXIgcmVtYWluaW5nID0gYnVmLmxlbmd0aCAtIG9mZnNldFxuICBpZiAoIWxlbmd0aCkge1xuICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICB9IGVsc2Uge1xuICAgIGxlbmd0aCA9IE51bWJlcihsZW5ndGgpXG4gICAgaWYgKGxlbmd0aCA+IHJlbWFpbmluZykge1xuICAgICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gICAgfVxuICB9XG5cbiAgLy8gbXVzdCBiZSBhbiBldmVuIG51bWJlciBvZiBkaWdpdHNcbiAgdmFyIHN0ckxlbiA9IHN0cmluZy5sZW5ndGhcbiAgaWYgKHN0ckxlbiAlIDIgIT09IDApIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBoZXggc3RyaW5nJylcblxuICBpZiAobGVuZ3RoID4gc3RyTGVuIC8gMikge1xuICAgIGxlbmd0aCA9IHN0ckxlbiAvIDJcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcnNlZCA9IHBhcnNlSW50KHN0cmluZy5zdWJzdHIoaSAqIDIsIDIpLCAxNilcbiAgICBpZiAoaXNOYU4ocGFyc2VkKSkgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGhleCBzdHJpbmcnKVxuICAgIGJ1ZltvZmZzZXQgKyBpXSA9IHBhcnNlZFxuICB9XG4gIHJldHVybiBpXG59XG5cbmZ1bmN0aW9uIHV0ZjhXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKHV0ZjhUb0J5dGVzKHN0cmluZywgYnVmLmxlbmd0aCAtIG9mZnNldCksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGFzY2lpV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcihhc2NpaVRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYmluYXJ5V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYXNjaWlXcml0ZShidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGJhc2U2NFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIoYmFzZTY0VG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiB1Y3MyV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcih1dGYxNmxlVG9CeXRlcyhzdHJpbmcsIGJ1Zi5sZW5ndGggLSBvZmZzZXQpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gd3JpdGUgKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgsIGVuY29kaW5nKSB7XG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcpXG4gIGlmIChvZmZzZXQgPT09IHVuZGVmaW5lZCkge1xuICAgIGVuY29kaW5nID0gJ3V0ZjgnXG4gICAgbGVuZ3RoID0gdGhpcy5sZW5ndGhcbiAgICBvZmZzZXQgPSAwXG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcsIGVuY29kaW5nKVxuICB9IGVsc2UgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkICYmIHR5cGVvZiBvZmZzZXQgPT09ICdzdHJpbmcnKSB7XG4gICAgZW5jb2RpbmcgPSBvZmZzZXRcbiAgICBsZW5ndGggPSB0aGlzLmxlbmd0aFxuICAgIG9mZnNldCA9IDBcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZywgb2Zmc2V0WywgbGVuZ3RoXVssIGVuY29kaW5nXSlcbiAgfSBlbHNlIGlmIChpc0Zpbml0ZShvZmZzZXQpKSB7XG4gICAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICAgIGlmIChpc0Zpbml0ZShsZW5ndGgpKSB7XG4gICAgICBsZW5ndGggPSBsZW5ndGggfCAwXG4gICAgICBpZiAoZW5jb2RpbmcgPT09IHVuZGVmaW5lZCkgZW5jb2RpbmcgPSAndXRmOCdcbiAgICB9IGVsc2Uge1xuICAgICAgZW5jb2RpbmcgPSBsZW5ndGhcbiAgICAgIGxlbmd0aCA9IHVuZGVmaW5lZFxuICAgIH1cbiAgLy8gbGVnYWN5IHdyaXRlKHN0cmluZywgZW5jb2RpbmcsIG9mZnNldCwgbGVuZ3RoKSAtIHJlbW92ZSBpbiB2MC4xM1xuICB9IGVsc2Uge1xuICAgIHZhciBzd2FwID0gZW5jb2RpbmdcbiAgICBlbmNvZGluZyA9IG9mZnNldFxuICAgIG9mZnNldCA9IGxlbmd0aCB8IDBcbiAgICBsZW5ndGggPSBzd2FwXG4gIH1cblxuICB2YXIgcmVtYWluaW5nID0gdGhpcy5sZW5ndGggLSBvZmZzZXRcbiAgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkIHx8IGxlbmd0aCA+IHJlbWFpbmluZykgbGVuZ3RoID0gcmVtYWluaW5nXG5cbiAgaWYgKChzdHJpbmcubGVuZ3RoID4gMCAmJiAobGVuZ3RoIDwgMCB8fCBvZmZzZXQgPCAwKSkgfHwgb2Zmc2V0ID4gdGhpcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignYXR0ZW1wdCB0byB3cml0ZSBvdXRzaWRlIGJ1ZmZlciBib3VuZHMnKVxuICB9XG5cbiAgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSAndXRmOCdcblxuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuICBmb3IgKDs7KSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGhleFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgICAgcmV0dXJuIGFzY2lpV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGJpbmFyeVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIC8vIFdhcm5pbmc6IG1heExlbmd0aCBub3QgdGFrZW4gaW50byBhY2NvdW50IGluIGJhc2U2NFdyaXRlXG4gICAgICAgIHJldHVybiBiYXNlNjRXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gdWNzMldyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgICAgICBlbmNvZGluZyA9ICgnJyArIGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTiAoKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogJ0J1ZmZlcicsXG4gICAgZGF0YTogQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwodGhpcy5fYXJyIHx8IHRoaXMsIDApXG4gIH1cbn1cblxuZnVuY3Rpb24gYmFzZTY0U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICBpZiAoc3RhcnQgPT09IDAgJiYgZW5kID09PSBidWYubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1ZilcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmLnNsaWNlKHN0YXJ0LCBlbmQpKVxuICB9XG59XG5cbmZ1bmN0aW9uIHV0ZjhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcbiAgdmFyIHJlcyA9IFtdXG5cbiAgdmFyIGkgPSBzdGFydFxuICB3aGlsZSAoaSA8IGVuZCkge1xuICAgIHZhciBmaXJzdEJ5dGUgPSBidWZbaV1cbiAgICB2YXIgY29kZVBvaW50ID0gbnVsbFxuICAgIHZhciBieXRlc1BlclNlcXVlbmNlID0gKGZpcnN0Qnl0ZSA+IDB4RUYpID8gNFxuICAgICAgOiAoZmlyc3RCeXRlID4gMHhERikgPyAzXG4gICAgICA6IChmaXJzdEJ5dGUgPiAweEJGKSA/IDJcbiAgICAgIDogMVxuXG4gICAgaWYgKGkgKyBieXRlc1BlclNlcXVlbmNlIDw9IGVuZCkge1xuICAgICAgdmFyIHNlY29uZEJ5dGUsIHRoaXJkQnl0ZSwgZm91cnRoQnl0ZSwgdGVtcENvZGVQb2ludFxuXG4gICAgICBzd2l0Y2ggKGJ5dGVzUGVyU2VxdWVuY2UpIHtcbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgIGlmIChmaXJzdEJ5dGUgPCAweDgwKSB7XG4gICAgICAgICAgICBjb2RlUG9pbnQgPSBmaXJzdEJ5dGVcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHgxRikgPDwgMHg2IHwgKHNlY29uZEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweDdGKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgdGhpcmRCeXRlID0gYnVmW2kgKyAyXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwICYmICh0aGlyZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweEYpIDw8IDB4QyB8IChzZWNvbmRCeXRlICYgMHgzRikgPDwgMHg2IHwgKHRoaXJkQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4N0ZGICYmICh0ZW1wQ29kZVBvaW50IDwgMHhEODAwIHx8IHRlbXBDb2RlUG9pbnQgPiAweERGRkYpKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSA0OlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgdGhpcmRCeXRlID0gYnVmW2kgKyAyXVxuICAgICAgICAgIGZvdXJ0aEJ5dGUgPSBidWZbaSArIDNdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKHRoaXJkQnl0ZSAmIDB4QzApID09PSAweDgwICYmIChmb3VydGhCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHhGKSA8PCAweDEyIHwgKHNlY29uZEJ5dGUgJiAweDNGKSA8PCAweEMgfCAodGhpcmRCeXRlICYgMHgzRikgPDwgMHg2IHwgKGZvdXJ0aEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweEZGRkYgJiYgdGVtcENvZGVQb2ludCA8IDB4MTEwMDAwKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNvZGVQb2ludCA9PT0gbnVsbCkge1xuICAgICAgLy8gd2UgZGlkIG5vdCBnZW5lcmF0ZSBhIHZhbGlkIGNvZGVQb2ludCBzbyBpbnNlcnQgYVxuICAgICAgLy8gcmVwbGFjZW1lbnQgY2hhciAoVStGRkZEKSBhbmQgYWR2YW5jZSBvbmx5IDEgYnl0ZVxuICAgICAgY29kZVBvaW50ID0gMHhGRkZEXG4gICAgICBieXRlc1BlclNlcXVlbmNlID0gMVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50ID4gMHhGRkZGKSB7XG4gICAgICAvLyBlbmNvZGUgdG8gdXRmMTYgKHN1cnJvZ2F0ZSBwYWlyIGRhbmNlKVxuICAgICAgY29kZVBvaW50IC09IDB4MTAwMDBcbiAgICAgIHJlcy5wdXNoKGNvZGVQb2ludCA+Pj4gMTAgJiAweDNGRiB8IDB4RDgwMClcbiAgICAgIGNvZGVQb2ludCA9IDB4REMwMCB8IGNvZGVQb2ludCAmIDB4M0ZGXG4gICAgfVxuXG4gICAgcmVzLnB1c2goY29kZVBvaW50KVxuICAgIGkgKz0gYnl0ZXNQZXJTZXF1ZW5jZVxuICB9XG5cbiAgcmV0dXJuIGRlY29kZUNvZGVQb2ludHNBcnJheShyZXMpXG59XG5cbi8vIEJhc2VkIG9uIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzIyNzQ3MjcyLzY4MDc0MiwgdGhlIGJyb3dzZXIgd2l0aFxuLy8gdGhlIGxvd2VzdCBsaW1pdCBpcyBDaHJvbWUsIHdpdGggMHgxMDAwMCBhcmdzLlxuLy8gV2UgZ28gMSBtYWduaXR1ZGUgbGVzcywgZm9yIHNhZmV0eVxudmFyIE1BWF9BUkdVTUVOVFNfTEVOR1RIID0gMHgxMDAwXG5cbmZ1bmN0aW9uIGRlY29kZUNvZGVQb2ludHNBcnJheSAoY29kZVBvaW50cykge1xuICB2YXIgbGVuID0gY29kZVBvaW50cy5sZW5ndGhcbiAgaWYgKGxlbiA8PSBNQVhfQVJHVU1FTlRTX0xFTkdUSCkge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZywgY29kZVBvaW50cykgLy8gYXZvaWQgZXh0cmEgc2xpY2UoKVxuICB9XG5cbiAgLy8gRGVjb2RlIGluIGNodW5rcyB0byBhdm9pZCBcImNhbGwgc3RhY2sgc2l6ZSBleGNlZWRlZFwiLlxuICB2YXIgcmVzID0gJydcbiAgdmFyIGkgPSAwXG4gIHdoaWxlIChpIDwgbGVuKSB7XG4gICAgcmVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoXG4gICAgICBTdHJpbmcsXG4gICAgICBjb2RlUG9pbnRzLnNsaWNlKGksIGkgKz0gTUFYX0FSR1VNRU5UU19MRU5HVEgpXG4gICAgKVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuZnVuY3Rpb24gYXNjaWlTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0gJiAweDdGKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gYmluYXJ5U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgcmV0ID0gJydcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gaGV4U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuXG4gIGlmICghc3RhcnQgfHwgc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgaWYgKCFlbmQgfHwgZW5kIDwgMCB8fCBlbmQgPiBsZW4pIGVuZCA9IGxlblxuXG4gIHZhciBvdXQgPSAnJ1xuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgIG91dCArPSB0b0hleChidWZbaV0pXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuXG5mdW5jdGlvbiB1dGYxNmxlU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgYnl0ZXMgPSBidWYuc2xpY2Uoc3RhcnQsIGVuZClcbiAgdmFyIHJlcyA9ICcnXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpICs9IDIpIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSArIGJ5dGVzW2kgKyAxXSAqIDI1NilcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc2xpY2UgPSBmdW5jdGlvbiBzbGljZSAoc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgc3RhcnQgPSB+fnN0YXJ0XG4gIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkID8gbGVuIDogfn5lbmRcblxuICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgc3RhcnQgKz0gbGVuXG4gICAgaWYgKHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIH0gZWxzZSBpZiAoc3RhcnQgPiBsZW4pIHtcbiAgICBzdGFydCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IDApIHtcbiAgICBlbmQgKz0gbGVuXG4gICAgaWYgKGVuZCA8IDApIGVuZCA9IDBcbiAgfSBlbHNlIGlmIChlbmQgPiBsZW4pIHtcbiAgICBlbmQgPSBsZW5cbiAgfVxuXG4gIGlmIChlbmQgPCBzdGFydCkgZW5kID0gc3RhcnRcblxuICB2YXIgbmV3QnVmXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIG5ld0J1ZiA9IEJ1ZmZlci5fYXVnbWVudCh0aGlzLnN1YmFycmF5KHN0YXJ0LCBlbmQpKVxuICB9IGVsc2Uge1xuICAgIHZhciBzbGljZUxlbiA9IGVuZCAtIHN0YXJ0XG4gICAgbmV3QnVmID0gbmV3IEJ1ZmZlcihzbGljZUxlbiwgdW5kZWZpbmVkKVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2xpY2VMZW47IGkrKykge1xuICAgICAgbmV3QnVmW2ldID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9XG5cbiAgaWYgKG5ld0J1Zi5sZW5ndGgpIG5ld0J1Zi5wYXJlbnQgPSB0aGlzLnBhcmVudCB8fCB0aGlzXG5cbiAgcmV0dXJuIG5ld0J1ZlxufVxuXG4vKlxuICogTmVlZCB0byBtYWtlIHN1cmUgdGhhdCBidWZmZXIgaXNuJ3QgdHJ5aW5nIHRvIHdyaXRlIG91dCBvZiBib3VuZHMuXG4gKi9cbmZ1bmN0aW9uIGNoZWNrT2Zmc2V0IChvZmZzZXQsIGV4dCwgbGVuZ3RoKSB7XG4gIGlmICgob2Zmc2V0ICUgMSkgIT09IDAgfHwgb2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ29mZnNldCBpcyBub3QgdWludCcpXG4gIGlmIChvZmZzZXQgKyBleHQgPiBsZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdUcnlpbmcgdG8gYWNjZXNzIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludExFID0gZnVuY3Rpb24gcmVhZFVJbnRMRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludEJFID0gZnVuY3Rpb24gcmVhZFVJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcbiAgfVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIC0tYnl0ZUxlbmd0aF1cbiAgdmFyIG11bCA9IDFcbiAgd2hpbGUgKGJ5dGVMZW5ndGggPiAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXSAqIG11bFxuICB9XG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50OCA9IGZ1bmN0aW9uIHJlYWRVSW50OCAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDEsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gdGhpc1tvZmZzZXRdXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkxFID0gZnVuY3Rpb24gcmVhZFVJbnQxNkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiB0aGlzW29mZnNldF0gfCAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZCRSA9IGZ1bmN0aW9uIHJlYWRVSW50MTZCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSA8PCA4KSB8IHRoaXNbb2Zmc2V0ICsgMV1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyTEUgPSBmdW5jdGlvbiByZWFkVUludDMyTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKCh0aGlzW29mZnNldF0pIHxcbiAgICAgICh0aGlzW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAgICh0aGlzW29mZnNldCArIDJdIDw8IDE2KSkgK1xuICAgICAgKHRoaXNbb2Zmc2V0ICsgM10gKiAweDEwMDAwMDApXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkJFID0gZnVuY3Rpb24gcmVhZFVJbnQzMkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0gKiAweDEwMDAwMDApICtcbiAgICAoKHRoaXNbb2Zmc2V0ICsgMV0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCA4KSB8XG4gICAgdGhpc1tvZmZzZXQgKyAzXSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50TEUgPSBmdW5jdGlvbiByZWFkSW50TEUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIGldICogbXVsXG4gIH1cbiAgbXVsICo9IDB4ODBcblxuICBpZiAodmFsID49IG11bCkgdmFsIC09IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50QkUgPSBmdW5jdGlvbiByZWFkSW50QkUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgaSA9IGJ5dGVMZW5ndGhcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1pXVxuICB3aGlsZSAoaSA+IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyAtLWldICogbXVsXG4gIH1cbiAgbXVsICo9IDB4ODBcblxuICBpZiAodmFsID49IG11bCkgdmFsIC09IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50OCA9IGZ1bmN0aW9uIHJlYWRJbnQ4IChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIGlmICghKHRoaXNbb2Zmc2V0XSAmIDB4ODApKSByZXR1cm4gKHRoaXNbb2Zmc2V0XSlcbiAgcmV0dXJuICgoMHhmZiAtIHRoaXNbb2Zmc2V0XSArIDEpICogLTEpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2TEUgPSBmdW5jdGlvbiByZWFkSW50MTZMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdIHwgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOClcbiAgcmV0dXJuICh2YWwgJiAweDgwMDApID8gdmFsIHwgMHhGRkZGMDAwMCA6IHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkJFID0gZnVuY3Rpb24gcmVhZEludDE2QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgMV0gfCAodGhpc1tvZmZzZXRdIDw8IDgpXG4gIHJldHVybiAodmFsICYgMHg4MDAwKSA/IHZhbCB8IDB4RkZGRjAwMDAgOiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJMRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0pIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSA8PCAyNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJCRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0gPDwgMjQpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRMRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdExFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRCRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdEJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCBmYWxzZSwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUxFID0gZnVuY3Rpb24gcmVhZERvdWJsZUxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgOCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCA1MiwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlQkUgPSBmdW5jdGlvbiByZWFkRG91YmxlQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA4LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCA1MiwgOClcbn1cblxuZnVuY3Rpb24gY2hlY2tJbnQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihidWYpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdidWZmZXIgbXVzdCBiZSBhIEJ1ZmZlciBpbnN0YW5jZScpXG4gIGlmICh2YWx1ZSA+IG1heCB8fCB2YWx1ZSA8IG1pbikgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3ZhbHVlIGlzIG91dCBvZiBib3VuZHMnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnRMRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpLCAwKVxuXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50QkUgPSBmdW5jdGlvbiB3cml0ZVVJbnRCRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpLCAwKVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdGhpc1tvZmZzZXQgKyBpXSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoLS1pID49IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50OCA9IGZ1bmN0aW9uIHdyaXRlVUludDggKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMSwgMHhmZiwgMClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkgdmFsdWUgPSBNYXRoLmZsb29yKHZhbHVlKVxuICB0aGlzW29mZnNldF0gPSB2YWx1ZVxuICByZXR1cm4gb2Zmc2V0ICsgMVxufVxuXG5mdW5jdGlvbiBvYmplY3RXcml0ZVVJbnQxNiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmYgKyB2YWx1ZSArIDFcbiAgZm9yICh2YXIgaSA9IDAsIGogPSBNYXRoLm1pbihidWYubGVuZ3RoIC0gb2Zmc2V0LCAyKTsgaSA8IGo7IGkrKykge1xuICAgIGJ1ZltvZmZzZXQgKyBpXSA9ICh2YWx1ZSAmICgweGZmIDw8ICg4ICogKGxpdHRsZUVuZGlhbiA/IGkgOiAxIC0gaSkpKSkgPj4+XG4gICAgICAobGl0dGxlRW5kaWFuID8gaSA6IDEgLSBpKSAqIDhcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQxNkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gdmFsdWVcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVVSW50MTZCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweGZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDFdID0gdmFsdWVcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5mdW5jdGlvbiBvYmplY3RXcml0ZVVJbnQzMiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmZmZmZmICsgdmFsdWUgKyAxXG4gIGZvciAodmFyIGkgPSAwLCBqID0gTWF0aC5taW4oYnVmLmxlbmd0aCAtIG9mZnNldCwgNCk7IGkgPCBqOyBpKyspIHtcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSAodmFsdWUgPj4+IChsaXR0bGVFbmRpYW4gPyBpIDogMyAtIGkpICogOCkgJiAweGZmXG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkxFID0gZnVuY3Rpb24gd3JpdGVVSW50MzJMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweGZmZmZmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0XSA9IHZhbHVlXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDNdID0gdmFsdWVcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50TEUgPSBmdW5jdGlvbiB3cml0ZUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gMFxuICB2YXIgbXVsID0gMVxuICB2YXIgc3ViID0gdmFsdWUgPCAwID8gMSA6IDBcbiAgdGhpc1tvZmZzZXRdID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICgodmFsdWUgLyBtdWwpID4+IDApIC0gc3ViICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludEJFID0gZnVuY3Rpb24gd3JpdGVJbnRCRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIGxpbWl0ID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGggLSAxKVxuXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbGltaXQgLSAxLCAtbGltaXQpXG4gIH1cblxuICB2YXIgaSA9IGJ5dGVMZW5ndGggLSAxXG4gIHZhciBtdWwgPSAxXG4gIHZhciBzdWIgPSB2YWx1ZSA8IDAgPyAxIDogMFxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAoKHZhbHVlIC8gbXVsKSA+PiAwKSAtIHN1YiAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQ4ID0gZnVuY3Rpb24gd3JpdGVJbnQ4ICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDEsIDB4N2YsIC0weDgwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB2YWx1ZSA9IE1hdGguZmxvb3IodmFsdWUpXG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZiArIHZhbHVlICsgMVxuICB0aGlzW29mZnNldF0gPSB2YWx1ZVxuICByZXR1cm4gb2Zmc2V0ICsgMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZMRSA9IGZ1bmN0aW9uIHdyaXRlSW50MTZMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweDdmZmYsIC0weDgwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9IHZhbHVlXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVJbnQxNkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4N2ZmZiwgLTB4ODAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSB2YWx1ZVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkxFID0gZnVuY3Rpb24gd3JpdGVJbnQzMkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSB2YWx1ZVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSA+Pj4gMjQpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJCRSA9IGZ1bmN0aW9uIHdyaXRlSW50MzJCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmZmZmZmICsgdmFsdWUgKyAxXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDNdID0gdmFsdWVcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5mdW5jdGlvbiBjaGVja0lFRUU3NTQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAodmFsdWUgPiBtYXggfHwgdmFsdWUgPCBtaW4pIHRocm93IG5ldyBSYW5nZUVycm9yKCd2YWx1ZSBpcyBvdXQgb2YgYm91bmRzJylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGJ1Zi5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdpbmRleCBvdXQgb2YgcmFuZ2UnKVxuICBpZiAob2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbmZ1bmN0aW9uIHdyaXRlRmxvYXQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgNCwgMy40MDI4MjM0NjYzODUyODg2ZSszOCwgLTMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgpXG4gIH1cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgMjMsIDQpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdExFID0gZnVuY3Rpb24gd3JpdGVGbG9hdExFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0QkUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gd3JpdGVEb3VibGUgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgOCwgMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgsIC0xLjc5NzY5MzEzNDg2MjMxNTdFKzMwOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCA1MiwgOClcbiAgcmV0dXJuIG9mZnNldCArIDhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUxFID0gZnVuY3Rpb24gd3JpdGVEb3VibGVMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlQkUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG4vLyBjb3B5KHRhcmdldEJ1ZmZlciwgdGFyZ2V0U3RhcnQ9MCwgc291cmNlU3RhcnQ9MCwgc291cmNlRW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbiBjb3B5ICh0YXJnZXQsIHRhcmdldFN0YXJ0LCBzdGFydCwgZW5kKSB7XG4gIGlmICghc3RhcnQpIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCAmJiBlbmQgIT09IDApIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXRTdGFydCA+PSB0YXJnZXQubGVuZ3RoKSB0YXJnZXRTdGFydCA9IHRhcmdldC5sZW5ndGhcbiAgaWYgKCF0YXJnZXRTdGFydCkgdGFyZ2V0U3RhcnQgPSAwXG4gIGlmIChlbmQgPiAwICYmIGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIC8vIENvcHkgMCBieXRlczsgd2UncmUgZG9uZVxuICBpZiAoZW5kID09PSBzdGFydCkgcmV0dXJuIDBcbiAgaWYgKHRhcmdldC5sZW5ndGggPT09IDAgfHwgdGhpcy5sZW5ndGggPT09IDApIHJldHVybiAwXG5cbiAgLy8gRmF0YWwgZXJyb3IgY29uZGl0aW9uc1xuICBpZiAodGFyZ2V0U3RhcnQgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3RhcmdldFN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICB9XG4gIGlmIChzdGFydCA8IDAgfHwgc3RhcnQgPj0gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgaWYgKGVuZCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VFbmQgb3V0IG9mIGJvdW5kcycpXG5cbiAgLy8gQXJlIHdlIG9vYj9cbiAgaWYgKGVuZCA+IHRoaXMubGVuZ3RoKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0Lmxlbmd0aCAtIHRhcmdldFN0YXJ0IDwgZW5kIC0gc3RhcnQpIHtcbiAgICBlbmQgPSB0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0U3RhcnQgKyBzdGFydFxuICB9XG5cbiAgdmFyIGxlbiA9IGVuZCAtIHN0YXJ0XG4gIHZhciBpXG5cbiAgaWYgKHRoaXMgPT09IHRhcmdldCAmJiBzdGFydCA8IHRhcmdldFN0YXJ0ICYmIHRhcmdldFN0YXJ0IDwgZW5kKSB7XG4gICAgLy8gZGVzY2VuZGluZyBjb3B5IGZyb20gZW5kXG4gICAgZm9yIChpID0gbGVuIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIHRhcmdldFtpICsgdGFyZ2V0U3RhcnRdID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9IGVsc2UgaWYgKGxlbiA8IDEwMDAgfHwgIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gYXNjZW5kaW5nIGNvcHkgZnJvbSBzdGFydFxuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRTdGFydF0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGFyZ2V0Ll9zZXQodGhpcy5zdWJhcnJheShzdGFydCwgc3RhcnQgKyBsZW4pLCB0YXJnZXRTdGFydClcbiAgfVxuXG4gIHJldHVybiBsZW5cbn1cblxuLy8gZmlsbCh2YWx1ZSwgc3RhcnQ9MCwgZW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLmZpbGwgPSBmdW5jdGlvbiBmaWxsICh2YWx1ZSwgc3RhcnQsIGVuZCkge1xuICBpZiAoIXZhbHVlKSB2YWx1ZSA9IDBcbiAgaWYgKCFzdGFydCkgc3RhcnQgPSAwXG4gIGlmICghZW5kKSBlbmQgPSB0aGlzLmxlbmd0aFxuXG4gIGlmIChlbmQgPCBzdGFydCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2VuZCA8IHN0YXJ0JylcblxuICAvLyBGaWxsIDAgYnl0ZXM7IHdlJ3JlIGRvbmVcbiAgaWYgKGVuZCA9PT0gc3RhcnQpIHJldHVyblxuICBpZiAodGhpcy5sZW5ndGggPT09IDApIHJldHVyblxuXG4gIGlmIChzdGFydCA8IDAgfHwgc3RhcnQgPj0gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdzdGFydCBvdXQgb2YgYm91bmRzJylcbiAgaWYgKGVuZCA8IDAgfHwgZW5kID4gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdlbmQgb3V0IG9mIGJvdW5kcycpXG5cbiAgdmFyIGlcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgICB0aGlzW2ldID0gdmFsdWVcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIGJ5dGVzID0gdXRmOFRvQnl0ZXModmFsdWUudG9TdHJpbmcoKSlcbiAgICB2YXIgbGVuID0gYnl0ZXMubGVuZ3RoXG4gICAgZm9yIChpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgICAgdGhpc1tpXSA9IGJ5dGVzW2kgJSBsZW5dXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGBBcnJheUJ1ZmZlcmAgd2l0aCB0aGUgKmNvcGllZCogbWVtb3J5IG9mIHRoZSBidWZmZXIgaW5zdGFuY2UuXG4gKiBBZGRlZCBpbiBOb2RlIDAuMTIuIE9ubHkgYXZhaWxhYmxlIGluIGJyb3dzZXJzIHRoYXQgc3VwcG9ydCBBcnJheUJ1ZmZlci5cbiAqL1xuQnVmZmVyLnByb3RvdHlwZS50b0FycmF5QnVmZmVyID0gZnVuY3Rpb24gdG9BcnJheUJ1ZmZlciAoKSB7XG4gIGlmICh0eXBlb2YgVWludDhBcnJheSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAgIHJldHVybiAobmV3IEJ1ZmZlcih0aGlzKSkuYnVmZmVyXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBidWYgPSBuZXcgVWludDhBcnJheSh0aGlzLmxlbmd0aClcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBidWYubGVuZ3RoOyBpIDwgbGVuOyBpICs9IDEpIHtcbiAgICAgICAgYnVmW2ldID0gdGhpc1tpXVxuICAgICAgfVxuICAgICAgcmV0dXJuIGJ1Zi5idWZmZXJcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQnVmZmVyLnRvQXJyYXlCdWZmZXIgbm90IHN1cHBvcnRlZCBpbiB0aGlzIGJyb3dzZXInKVxuICB9XG59XG5cbi8vIEhFTFBFUiBGVU5DVElPTlNcbi8vID09PT09PT09PT09PT09PT1cblxudmFyIEJQID0gQnVmZmVyLnByb3RvdHlwZVxuXG4vKipcbiAqIEF1Z21lbnQgYSBVaW50OEFycmF5ICppbnN0YW5jZSogKG5vdCB0aGUgVWludDhBcnJheSBjbGFzcyEpIHdpdGggQnVmZmVyIG1ldGhvZHNcbiAqL1xuQnVmZmVyLl9hdWdtZW50ID0gZnVuY3Rpb24gX2F1Z21lbnQgKGFycikge1xuICBhcnIuY29uc3RydWN0b3IgPSBCdWZmZXJcbiAgYXJyLl9pc0J1ZmZlciA9IHRydWVcblxuICAvLyBzYXZlIHJlZmVyZW5jZSB0byBvcmlnaW5hbCBVaW50OEFycmF5IHNldCBtZXRob2QgYmVmb3JlIG92ZXJ3cml0aW5nXG4gIGFyci5fc2V0ID0gYXJyLnNldFxuXG4gIC8vIGRlcHJlY2F0ZWRcbiAgYXJyLmdldCA9IEJQLmdldFxuICBhcnIuc2V0ID0gQlAuc2V0XG5cbiAgYXJyLndyaXRlID0gQlAud3JpdGVcbiAgYXJyLnRvU3RyaW5nID0gQlAudG9TdHJpbmdcbiAgYXJyLnRvTG9jYWxlU3RyaW5nID0gQlAudG9TdHJpbmdcbiAgYXJyLnRvSlNPTiA9IEJQLnRvSlNPTlxuICBhcnIuZXF1YWxzID0gQlAuZXF1YWxzXG4gIGFyci5jb21wYXJlID0gQlAuY29tcGFyZVxuICBhcnIuaW5kZXhPZiA9IEJQLmluZGV4T2ZcbiAgYXJyLmNvcHkgPSBCUC5jb3B5XG4gIGFyci5zbGljZSA9IEJQLnNsaWNlXG4gIGFyci5yZWFkVUludExFID0gQlAucmVhZFVJbnRMRVxuICBhcnIucmVhZFVJbnRCRSA9IEJQLnJlYWRVSW50QkVcbiAgYXJyLnJlYWRVSW50OCA9IEJQLnJlYWRVSW50OFxuICBhcnIucmVhZFVJbnQxNkxFID0gQlAucmVhZFVJbnQxNkxFXG4gIGFyci5yZWFkVUludDE2QkUgPSBCUC5yZWFkVUludDE2QkVcbiAgYXJyLnJlYWRVSW50MzJMRSA9IEJQLnJlYWRVSW50MzJMRVxuICBhcnIucmVhZFVJbnQzMkJFID0gQlAucmVhZFVJbnQzMkJFXG4gIGFyci5yZWFkSW50TEUgPSBCUC5yZWFkSW50TEVcbiAgYXJyLnJlYWRJbnRCRSA9IEJQLnJlYWRJbnRCRVxuICBhcnIucmVhZEludDggPSBCUC5yZWFkSW50OFxuICBhcnIucmVhZEludDE2TEUgPSBCUC5yZWFkSW50MTZMRVxuICBhcnIucmVhZEludDE2QkUgPSBCUC5yZWFkSW50MTZCRVxuICBhcnIucmVhZEludDMyTEUgPSBCUC5yZWFkSW50MzJMRVxuICBhcnIucmVhZEludDMyQkUgPSBCUC5yZWFkSW50MzJCRVxuICBhcnIucmVhZEZsb2F0TEUgPSBCUC5yZWFkRmxvYXRMRVxuICBhcnIucmVhZEZsb2F0QkUgPSBCUC5yZWFkRmxvYXRCRVxuICBhcnIucmVhZERvdWJsZUxFID0gQlAucmVhZERvdWJsZUxFXG4gIGFyci5yZWFkRG91YmxlQkUgPSBCUC5yZWFkRG91YmxlQkVcbiAgYXJyLndyaXRlVUludDggPSBCUC53cml0ZVVJbnQ4XG4gIGFyci53cml0ZVVJbnRMRSA9IEJQLndyaXRlVUludExFXG4gIGFyci53cml0ZVVJbnRCRSA9IEJQLndyaXRlVUludEJFXG4gIGFyci53cml0ZVVJbnQxNkxFID0gQlAud3JpdGVVSW50MTZMRVxuICBhcnIud3JpdGVVSW50MTZCRSA9IEJQLndyaXRlVUludDE2QkVcbiAgYXJyLndyaXRlVUludDMyTEUgPSBCUC53cml0ZVVJbnQzMkxFXG4gIGFyci53cml0ZVVJbnQzMkJFID0gQlAud3JpdGVVSW50MzJCRVxuICBhcnIud3JpdGVJbnRMRSA9IEJQLndyaXRlSW50TEVcbiAgYXJyLndyaXRlSW50QkUgPSBCUC53cml0ZUludEJFXG4gIGFyci53cml0ZUludDggPSBCUC53cml0ZUludDhcbiAgYXJyLndyaXRlSW50MTZMRSA9IEJQLndyaXRlSW50MTZMRVxuICBhcnIud3JpdGVJbnQxNkJFID0gQlAud3JpdGVJbnQxNkJFXG4gIGFyci53cml0ZUludDMyTEUgPSBCUC53cml0ZUludDMyTEVcbiAgYXJyLndyaXRlSW50MzJCRSA9IEJQLndyaXRlSW50MzJCRVxuICBhcnIud3JpdGVGbG9hdExFID0gQlAud3JpdGVGbG9hdExFXG4gIGFyci53cml0ZUZsb2F0QkUgPSBCUC53cml0ZUZsb2F0QkVcbiAgYXJyLndyaXRlRG91YmxlTEUgPSBCUC53cml0ZURvdWJsZUxFXG4gIGFyci53cml0ZURvdWJsZUJFID0gQlAud3JpdGVEb3VibGVCRVxuICBhcnIuZmlsbCA9IEJQLmZpbGxcbiAgYXJyLmluc3BlY3QgPSBCUC5pbnNwZWN0XG4gIGFyci50b0FycmF5QnVmZmVyID0gQlAudG9BcnJheUJ1ZmZlclxuXG4gIHJldHVybiBhcnJcbn1cblxudmFyIElOVkFMSURfQkFTRTY0X1JFID0gL1teK1xcLzAtOUEtWmEtei1fXS9nXG5cbmZ1bmN0aW9uIGJhc2U2NGNsZWFuIChzdHIpIHtcbiAgLy8gTm9kZSBzdHJpcHMgb3V0IGludmFsaWQgY2hhcmFjdGVycyBsaWtlIFxcbiBhbmQgXFx0IGZyb20gdGhlIHN0cmluZywgYmFzZTY0LWpzIGRvZXMgbm90XG4gIHN0ciA9IHN0cmluZ3RyaW0oc3RyKS5yZXBsYWNlKElOVkFMSURfQkFTRTY0X1JFLCAnJylcbiAgLy8gTm9kZSBjb252ZXJ0cyBzdHJpbmdzIHdpdGggbGVuZ3RoIDwgMiB0byAnJ1xuICBpZiAoc3RyLmxlbmd0aCA8IDIpIHJldHVybiAnJ1xuICAvLyBOb2RlIGFsbG93cyBmb3Igbm9uLXBhZGRlZCBiYXNlNjQgc3RyaW5ncyAobWlzc2luZyB0cmFpbGluZyA9PT0pLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgd2hpbGUgKHN0ci5sZW5ndGggJSA0ICE9PSAwKSB7XG4gICAgc3RyID0gc3RyICsgJz0nXG4gIH1cbiAgcmV0dXJuIHN0clxufVxuXG5mdW5jdGlvbiBzdHJpbmd0cmltIChzdHIpIHtcbiAgaWYgKHN0ci50cmltKSByZXR1cm4gc3RyLnRyaW0oKVxuICByZXR1cm4gc3RyLnJlcGxhY2UoL15cXHMrfFxccyskL2csICcnKVxufVxuXG5mdW5jdGlvbiB0b0hleCAobikge1xuICBpZiAobiA8IDE2KSByZXR1cm4gJzAnICsgbi50b1N0cmluZygxNilcbiAgcmV0dXJuIG4udG9TdHJpbmcoMTYpXG59XG5cbmZ1bmN0aW9uIHV0ZjhUb0J5dGVzIChzdHJpbmcsIHVuaXRzKSB7XG4gIHVuaXRzID0gdW5pdHMgfHwgSW5maW5pdHlcbiAgdmFyIGNvZGVQb2ludFxuICB2YXIgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aFxuICB2YXIgbGVhZFN1cnJvZ2F0ZSA9IG51bGxcbiAgdmFyIGJ5dGVzID0gW11cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgY29kZVBvaW50ID0gc3RyaW5nLmNoYXJDb2RlQXQoaSlcblxuICAgIC8vIGlzIHN1cnJvZ2F0ZSBjb21wb25lbnRcbiAgICBpZiAoY29kZVBvaW50ID4gMHhEN0ZGICYmIGNvZGVQb2ludCA8IDB4RTAwMCkge1xuICAgICAgLy8gbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICghbGVhZFN1cnJvZ2F0ZSkge1xuICAgICAgICAvLyBubyBsZWFkIHlldFxuICAgICAgICBpZiAoY29kZVBvaW50ID4gMHhEQkZGKSB7XG4gICAgICAgICAgLy8gdW5leHBlY3RlZCB0cmFpbFxuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH0gZWxzZSBpZiAoaSArIDEgPT09IGxlbmd0aCkge1xuICAgICAgICAgIC8vIHVucGFpcmVkIGxlYWRcbiAgICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gdmFsaWQgbGVhZFxuICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG5cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgLy8gMiBsZWFkcyBpbiBhIHJvd1xuICAgICAgaWYgKGNvZGVQb2ludCA8IDB4REMwMCkge1xuICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgbGVhZFN1cnJvZ2F0ZSA9IGNvZGVQb2ludFxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvLyB2YWxpZCBzdXJyb2dhdGUgcGFpclxuICAgICAgY29kZVBvaW50ID0gbGVhZFN1cnJvZ2F0ZSAtIDB4RDgwMCA8PCAxMCB8IGNvZGVQb2ludCAtIDB4REMwMCB8IDB4MTAwMDBcbiAgICB9IGVsc2UgaWYgKGxlYWRTdXJyb2dhdGUpIHtcbiAgICAgIC8vIHZhbGlkIGJtcCBjaGFyLCBidXQgbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgIH1cblxuICAgIGxlYWRTdXJyb2dhdGUgPSBudWxsXG5cbiAgICAvLyBlbmNvZGUgdXRmOFxuICAgIGlmIChjb2RlUG9pbnQgPCAweDgwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDEpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goY29kZVBvaW50KVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHg4MDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMikgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiB8IDB4QzAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDEwMDAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDMpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgfCAweEUwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2ICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDExMDAwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSA0KSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHgxMiB8IDB4RjAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY29kZSBwb2ludCcpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVzXG59XG5cbmZ1bmN0aW9uIGFzY2lpVG9CeXRlcyAoc3RyKSB7XG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykge1xuICAgIC8vIE5vZGUncyBjb2RlIHNlZW1zIHRvIGJlIGRvaW5nIHRoaXMgYW5kIG5vdCAmIDB4N0YuLlxuICAgIGJ5dGVBcnJheS5wdXNoKHN0ci5jaGFyQ29kZUF0KGkpICYgMHhGRilcbiAgfVxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVUb0J5dGVzIChzdHIsIHVuaXRzKSB7XG4gIHZhciBjLCBoaSwgbG9cbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKCh1bml0cyAtPSAyKSA8IDApIGJyZWFrXG5cbiAgICBjID0gc3RyLmNoYXJDb2RlQXQoaSlcbiAgICBoaSA9IGMgPj4gOFxuICAgIGxvID0gYyAlIDI1NlxuICAgIGJ5dGVBcnJheS5wdXNoKGxvKVxuICAgIGJ5dGVBcnJheS5wdXNoKGhpKVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiBiYXNlNjRUb0J5dGVzIChzdHIpIHtcbiAgcmV0dXJuIGJhc2U2NC50b0J5dGVBcnJheShiYXNlNjRjbGVhbihzdHIpKVxufVxuXG5mdW5jdGlvbiBibGl0QnVmZmVyIChzcmMsIGRzdCwgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgIGlmICgoaSArIG9mZnNldCA+PSBkc3QubGVuZ3RoKSB8fCAoaSA+PSBzcmMubGVuZ3RoKSkgYnJlYWtcbiAgICBkc3RbaSArIG9mZnNldF0gPSBzcmNbaV1cbiAgfVxuICByZXR1cm4gaVxufVxuIiwidmFyIGxvb2t1cCA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvJztcblxuOyhmdW5jdGlvbiAoZXhwb3J0cykge1xuXHQndXNlIHN0cmljdCc7XG5cbiAgdmFyIEFyciA9ICh0eXBlb2YgVWludDhBcnJheSAhPT0gJ3VuZGVmaW5lZCcpXG4gICAgPyBVaW50OEFycmF5XG4gICAgOiBBcnJheVxuXG5cdHZhciBQTFVTICAgPSAnKycuY2hhckNvZGVBdCgwKVxuXHR2YXIgU0xBU0ggID0gJy8nLmNoYXJDb2RlQXQoMClcblx0dmFyIE5VTUJFUiA9ICcwJy5jaGFyQ29kZUF0KDApXG5cdHZhciBMT1dFUiAgPSAnYScuY2hhckNvZGVBdCgwKVxuXHR2YXIgVVBQRVIgID0gJ0EnLmNoYXJDb2RlQXQoMClcblx0dmFyIFBMVVNfVVJMX1NBRkUgPSAnLScuY2hhckNvZGVBdCgwKVxuXHR2YXIgU0xBU0hfVVJMX1NBRkUgPSAnXycuY2hhckNvZGVBdCgwKVxuXG5cdGZ1bmN0aW9uIGRlY29kZSAoZWx0KSB7XG5cdFx0dmFyIGNvZGUgPSBlbHQuY2hhckNvZGVBdCgwKVxuXHRcdGlmIChjb2RlID09PSBQTFVTIHx8XG5cdFx0ICAgIGNvZGUgPT09IFBMVVNfVVJMX1NBRkUpXG5cdFx0XHRyZXR1cm4gNjIgLy8gJysnXG5cdFx0aWYgKGNvZGUgPT09IFNMQVNIIHx8XG5cdFx0ICAgIGNvZGUgPT09IFNMQVNIX1VSTF9TQUZFKVxuXHRcdFx0cmV0dXJuIDYzIC8vICcvJ1xuXHRcdGlmIChjb2RlIDwgTlVNQkVSKVxuXHRcdFx0cmV0dXJuIC0xIC8vbm8gbWF0Y2hcblx0XHRpZiAoY29kZSA8IE5VTUJFUiArIDEwKVxuXHRcdFx0cmV0dXJuIGNvZGUgLSBOVU1CRVIgKyAyNiArIDI2XG5cdFx0aWYgKGNvZGUgPCBVUFBFUiArIDI2KVxuXHRcdFx0cmV0dXJuIGNvZGUgLSBVUFBFUlxuXHRcdGlmIChjb2RlIDwgTE9XRVIgKyAyNilcblx0XHRcdHJldHVybiBjb2RlIC0gTE9XRVIgKyAyNlxuXHR9XG5cblx0ZnVuY3Rpb24gYjY0VG9CeXRlQXJyYXkgKGI2NCkge1xuXHRcdHZhciBpLCBqLCBsLCB0bXAsIHBsYWNlSG9sZGVycywgYXJyXG5cblx0XHRpZiAoYjY0Lmxlbmd0aCAlIDQgPiAwKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc3RyaW5nLiBMZW5ndGggbXVzdCBiZSBhIG11bHRpcGxlIG9mIDQnKVxuXHRcdH1cblxuXHRcdC8vIHRoZSBudW1iZXIgb2YgZXF1YWwgc2lnbnMgKHBsYWNlIGhvbGRlcnMpXG5cdFx0Ly8gaWYgdGhlcmUgYXJlIHR3byBwbGFjZWhvbGRlcnMsIHRoYW4gdGhlIHR3byBjaGFyYWN0ZXJzIGJlZm9yZSBpdFxuXHRcdC8vIHJlcHJlc2VudCBvbmUgYnl0ZVxuXHRcdC8vIGlmIHRoZXJlIGlzIG9ubHkgb25lLCB0aGVuIHRoZSB0aHJlZSBjaGFyYWN0ZXJzIGJlZm9yZSBpdCByZXByZXNlbnQgMiBieXRlc1xuXHRcdC8vIHRoaXMgaXMganVzdCBhIGNoZWFwIGhhY2sgdG8gbm90IGRvIGluZGV4T2YgdHdpY2Vcblx0XHR2YXIgbGVuID0gYjY0Lmxlbmd0aFxuXHRcdHBsYWNlSG9sZGVycyA9ICc9JyA9PT0gYjY0LmNoYXJBdChsZW4gLSAyKSA/IDIgOiAnPScgPT09IGI2NC5jaGFyQXQobGVuIC0gMSkgPyAxIDogMFxuXG5cdFx0Ly8gYmFzZTY0IGlzIDQvMyArIHVwIHRvIHR3byBjaGFyYWN0ZXJzIG9mIHRoZSBvcmlnaW5hbCBkYXRhXG5cdFx0YXJyID0gbmV3IEFycihiNjQubGVuZ3RoICogMyAvIDQgLSBwbGFjZUhvbGRlcnMpXG5cblx0XHQvLyBpZiB0aGVyZSBhcmUgcGxhY2Vob2xkZXJzLCBvbmx5IGdldCB1cCB0byB0aGUgbGFzdCBjb21wbGV0ZSA0IGNoYXJzXG5cdFx0bCA9IHBsYWNlSG9sZGVycyA+IDAgPyBiNjQubGVuZ3RoIC0gNCA6IGI2NC5sZW5ndGhcblxuXHRcdHZhciBMID0gMFxuXG5cdFx0ZnVuY3Rpb24gcHVzaCAodikge1xuXHRcdFx0YXJyW0wrK10gPSB2XG5cdFx0fVxuXG5cdFx0Zm9yIChpID0gMCwgaiA9IDA7IGkgPCBsOyBpICs9IDQsIGogKz0gMykge1xuXHRcdFx0dG1wID0gKGRlY29kZShiNjQuY2hhckF0KGkpKSA8PCAxOCkgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDEpKSA8PCAxMikgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDIpKSA8PCA2KSB8IGRlY29kZShiNjQuY2hhckF0KGkgKyAzKSlcblx0XHRcdHB1c2goKHRtcCAmIDB4RkYwMDAwKSA+PiAxNilcblx0XHRcdHB1c2goKHRtcCAmIDB4RkYwMCkgPj4gOClcblx0XHRcdHB1c2godG1wICYgMHhGRilcblx0XHR9XG5cblx0XHRpZiAocGxhY2VIb2xkZXJzID09PSAyKSB7XG5cdFx0XHR0bXAgPSAoZGVjb2RlKGI2NC5jaGFyQXQoaSkpIDw8IDIpIHwgKGRlY29kZShiNjQuY2hhckF0KGkgKyAxKSkgPj4gNClcblx0XHRcdHB1c2godG1wICYgMHhGRilcblx0XHR9IGVsc2UgaWYgKHBsYWNlSG9sZGVycyA9PT0gMSkge1xuXHRcdFx0dG1wID0gKGRlY29kZShiNjQuY2hhckF0KGkpKSA8PCAxMCkgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDEpKSA8PCA0KSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMikpID4+IDIpXG5cdFx0XHRwdXNoKCh0bXAgPj4gOCkgJiAweEZGKVxuXHRcdFx0cHVzaCh0bXAgJiAweEZGKVxuXHRcdH1cblxuXHRcdHJldHVybiBhcnJcblx0fVxuXG5cdGZ1bmN0aW9uIHVpbnQ4VG9CYXNlNjQgKHVpbnQ4KSB7XG5cdFx0dmFyIGksXG5cdFx0XHRleHRyYUJ5dGVzID0gdWludDgubGVuZ3RoICUgMywgLy8gaWYgd2UgaGF2ZSAxIGJ5dGUgbGVmdCwgcGFkIDIgYnl0ZXNcblx0XHRcdG91dHB1dCA9IFwiXCIsXG5cdFx0XHR0ZW1wLCBsZW5ndGhcblxuXHRcdGZ1bmN0aW9uIGVuY29kZSAobnVtKSB7XG5cdFx0XHRyZXR1cm4gbG9va3VwLmNoYXJBdChudW0pXG5cdFx0fVxuXG5cdFx0ZnVuY3Rpb24gdHJpcGxldFRvQmFzZTY0IChudW0pIHtcblx0XHRcdHJldHVybiBlbmNvZGUobnVtID4+IDE4ICYgMHgzRikgKyBlbmNvZGUobnVtID4+IDEyICYgMHgzRikgKyBlbmNvZGUobnVtID4+IDYgJiAweDNGKSArIGVuY29kZShudW0gJiAweDNGKVxuXHRcdH1cblxuXHRcdC8vIGdvIHRocm91Z2ggdGhlIGFycmF5IGV2ZXJ5IHRocmVlIGJ5dGVzLCB3ZSdsbCBkZWFsIHdpdGggdHJhaWxpbmcgc3R1ZmYgbGF0ZXJcblx0XHRmb3IgKGkgPSAwLCBsZW5ndGggPSB1aW50OC5sZW5ndGggLSBleHRyYUJ5dGVzOyBpIDwgbGVuZ3RoOyBpICs9IDMpIHtcblx0XHRcdHRlbXAgPSAodWludDhbaV0gPDwgMTYpICsgKHVpbnQ4W2kgKyAxXSA8PCA4KSArICh1aW50OFtpICsgMl0pXG5cdFx0XHRvdXRwdXQgKz0gdHJpcGxldFRvQmFzZTY0KHRlbXApXG5cdFx0fVxuXG5cdFx0Ly8gcGFkIHRoZSBlbmQgd2l0aCB6ZXJvcywgYnV0IG1ha2Ugc3VyZSB0byBub3QgZm9yZ2V0IHRoZSBleHRyYSBieXRlc1xuXHRcdHN3aXRjaCAoZXh0cmFCeXRlcykge1xuXHRcdFx0Y2FzZSAxOlxuXHRcdFx0XHR0ZW1wID0gdWludDhbdWludDgubGVuZ3RoIC0gMV1cblx0XHRcdFx0b3V0cHV0ICs9IGVuY29kZSh0ZW1wID4+IDIpXG5cdFx0XHRcdG91dHB1dCArPSBlbmNvZGUoKHRlbXAgPDwgNCkgJiAweDNGKVxuXHRcdFx0XHRvdXRwdXQgKz0gJz09J1xuXHRcdFx0XHRicmVha1xuXHRcdFx0Y2FzZSAyOlxuXHRcdFx0XHR0ZW1wID0gKHVpbnQ4W3VpbnQ4Lmxlbmd0aCAtIDJdIDw8IDgpICsgKHVpbnQ4W3VpbnQ4Lmxlbmd0aCAtIDFdKVxuXHRcdFx0XHRvdXRwdXQgKz0gZW5jb2RlKHRlbXAgPj4gMTApXG5cdFx0XHRcdG91dHB1dCArPSBlbmNvZGUoKHRlbXAgPj4gNCkgJiAweDNGKVxuXHRcdFx0XHRvdXRwdXQgKz0gZW5jb2RlKCh0ZW1wIDw8IDIpICYgMHgzRilcblx0XHRcdFx0b3V0cHV0ICs9ICc9J1xuXHRcdFx0XHRicmVha1xuXHRcdH1cblxuXHRcdHJldHVybiBvdXRwdXRcblx0fVxuXG5cdGV4cG9ydHMudG9CeXRlQXJyYXkgPSBiNjRUb0J5dGVBcnJheVxuXHRleHBvcnRzLmZyb21CeXRlQXJyYXkgPSB1aW50OFRvQmFzZTY0XG59KHR5cGVvZiBleHBvcnRzID09PSAndW5kZWZpbmVkJyA/ICh0aGlzLmJhc2U2NGpzID0ge30pIDogZXhwb3J0cykpXG4iLCJleHBvcnRzLnJlYWQgPSBmdW5jdGlvbiAoYnVmZmVyLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbVxuICB2YXIgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIG5CaXRzID0gLTdcbiAgdmFyIGkgPSBpc0xFID8gKG5CeXRlcyAtIDEpIDogMFxuICB2YXIgZCA9IGlzTEUgPyAtMSA6IDFcbiAgdmFyIHMgPSBidWZmZXJbb2Zmc2V0ICsgaV1cblxuICBpICs9IGRcblxuICBlID0gcyAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBzID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBlTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IGUgPSBlICogMjU2ICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XG5cbiAgbSA9IGUgJiAoKDEgPDwgKC1uQml0cykpIC0gMSlcbiAgZSA+Pj0gKC1uQml0cylcbiAgbkJpdHMgKz0gbUxlblxuICBmb3IgKDsgbkJpdHMgPiAwOyBtID0gbSAqIDI1NiArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIGlmIChlID09PSAwKSB7XG4gICAgZSA9IDEgLSBlQmlhc1xuICB9IGVsc2UgaWYgKGUgPT09IGVNYXgpIHtcbiAgICByZXR1cm4gbSA/IE5hTiA6ICgocyA/IC0xIDogMSkgKiBJbmZpbml0eSlcbiAgfSBlbHNlIHtcbiAgICBtID0gbSArIE1hdGgucG93KDIsIG1MZW4pXG4gICAgZSA9IGUgLSBlQmlhc1xuICB9XG4gIHJldHVybiAocyA/IC0xIDogMSkgKiBtICogTWF0aC5wb3coMiwgZSAtIG1MZW4pXG59XG5cbmV4cG9ydHMud3JpdGUgPSBmdW5jdGlvbiAoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG0sIGNcbiAgdmFyIGVMZW4gPSBuQnl0ZXMgKiA4IC0gbUxlbiAtIDFcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDFcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxXG4gIHZhciBydCA9IChtTGVuID09PSAyMyA/IE1hdGgucG93KDIsIC0yNCkgLSBNYXRoLnBvdygyLCAtNzcpIDogMClcbiAgdmFyIGkgPSBpc0xFID8gMCA6IChuQnl0ZXMgLSAxKVxuICB2YXIgZCA9IGlzTEUgPyAxIDogLTFcbiAgdmFyIHMgPSB2YWx1ZSA8IDAgfHwgKHZhbHVlID09PSAwICYmIDEgLyB2YWx1ZSA8IDApID8gMSA6IDBcblxuICB2YWx1ZSA9IE1hdGguYWJzKHZhbHVlKVxuXG4gIGlmIChpc05hTih2YWx1ZSkgfHwgdmFsdWUgPT09IEluZmluaXR5KSB7XG4gICAgbSA9IGlzTmFOKHZhbHVlKSA/IDEgOiAwXG4gICAgZSA9IGVNYXhcbiAgfSBlbHNlIHtcbiAgICBlID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMilcbiAgICBpZiAodmFsdWUgKiAoYyA9IE1hdGgucG93KDIsIC1lKSkgPCAxKSB7XG4gICAgICBlLS1cbiAgICAgIGMgKj0gMlxuICAgIH1cbiAgICBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIHZhbHVlICs9IHJ0IC8gY1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSArPSBydCAqIE1hdGgucG93KDIsIDEgLSBlQmlhcylcbiAgICB9XG4gICAgaWYgKHZhbHVlICogYyA+PSAyKSB7XG4gICAgICBlKytcbiAgICAgIGMgLz0gMlxuICAgIH1cblxuICAgIGlmIChlICsgZUJpYXMgPj0gZU1heCkge1xuICAgICAgbSA9IDBcbiAgICAgIGUgPSBlTWF4XG4gICAgfSBlbHNlIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgbSA9ICh2YWx1ZSAqIGMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gZSArIGVCaWFzXG4gICAgfSBlbHNlIHtcbiAgICAgIG0gPSB2YWx1ZSAqIE1hdGgucG93KDIsIGVCaWFzIC0gMSkgKiBNYXRoLnBvdygyLCBtTGVuKVxuICAgICAgZSA9IDBcbiAgICB9XG4gIH1cblxuICBmb3IgKDsgbUxlbiA+PSA4OyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBtICYgMHhmZiwgaSArPSBkLCBtIC89IDI1NiwgbUxlbiAtPSA4KSB7fVxuXG4gIGUgPSAoZSA8PCBtTGVuKSB8IG1cbiAgZUxlbiArPSBtTGVuXG4gIGZvciAoOyBlTGVuID4gMDsgYnVmZmVyW29mZnNldCArIGldID0gZSAmIDB4ZmYsIGkgKz0gZCwgZSAvPSAyNTYsIGVMZW4gLT0gOCkge31cblxuICBidWZmZXJbb2Zmc2V0ICsgaSAtIGRdIHw9IHMgKiAxMjhcbn1cbiIsIlxuLyoqXG4gKiBpc0FycmF5XG4gKi9cblxudmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5O1xuXG4vKipcbiAqIHRvU3RyaW5nXG4gKi9cblxudmFyIHN0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbi8qKlxuICogV2hldGhlciBvciBub3QgdGhlIGdpdmVuIGB2YWxgXG4gKiBpcyBhbiBhcnJheS5cbiAqXG4gKiBleGFtcGxlOlxuICpcbiAqICAgICAgICBpc0FycmF5KFtdKTtcbiAqICAgICAgICAvLyA+IHRydWVcbiAqICAgICAgICBpc0FycmF5KGFyZ3VtZW50cyk7XG4gKiAgICAgICAgLy8gPiBmYWxzZVxuICogICAgICAgIGlzQXJyYXkoJycpO1xuICogICAgICAgIC8vID4gZmFsc2VcbiAqXG4gKiBAcGFyYW0ge21peGVkfSB2YWxcbiAqIEByZXR1cm4ge2Jvb2x9XG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBpc0FycmF5IHx8IGZ1bmN0aW9uICh2YWwpIHtcbiAgcmV0dXJuICEhIHZhbCAmJiAnW29iamVjdCBBcnJheV0nID09IHN0ci5jYWxsKHZhbCk7XG59O1xuIiwiXG4vKipcbiAqIEV4cG9zZSBgRW1pdHRlcmAuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBFbWl0dGVyO1xuXG4vKipcbiAqIEluaXRpYWxpemUgYSBuZXcgYEVtaXR0ZXJgLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gRW1pdHRlcihvYmopIHtcbiAgaWYgKG9iaikgcmV0dXJuIG1peGluKG9iaik7XG59O1xuXG4vKipcbiAqIE1peGluIHRoZSBlbWl0dGVyIHByb3BlcnRpZXMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICogQHJldHVybiB7T2JqZWN0fVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gbWl4aW4ob2JqKSB7XG4gIGZvciAodmFyIGtleSBpbiBFbWl0dGVyLnByb3RvdHlwZSkge1xuICAgIG9ialtrZXldID0gRW1pdHRlci5wcm90b3R5cGVba2V5XTtcbiAgfVxuICByZXR1cm4gb2JqO1xufVxuXG4vKipcbiAqIExpc3RlbiBvbiB0aGUgZ2l2ZW4gYGV2ZW50YCB3aXRoIGBmbmAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHJldHVybiB7RW1pdHRlcn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuRW1pdHRlci5wcm90b3R5cGUub24gPVxuRW1pdHRlci5wcm90b3R5cGUuYWRkRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50LCBmbil7XG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcbiAgKHRoaXMuX2NhbGxiYWNrc1snJCcgKyBldmVudF0gPSB0aGlzLl9jYWxsYmFja3NbJyQnICsgZXZlbnRdIHx8IFtdKVxuICAgIC5wdXNoKGZuKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEFkZHMgYW4gYGV2ZW50YCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBhIHNpbmdsZVxuICogdGltZSB0aGVuIGF1dG9tYXRpY2FsbHkgcmVtb3ZlZC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtFbWl0dGVyfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5FbWl0dGVyLnByb3RvdHlwZS5vbmNlID0gZnVuY3Rpb24oZXZlbnQsIGZuKXtcbiAgZnVuY3Rpb24gb24oKSB7XG4gICAgdGhpcy5vZmYoZXZlbnQsIG9uKTtcbiAgICBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgb24uZm4gPSBmbjtcbiAgdGhpcy5vbihldmVudCwgb24pO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogUmVtb3ZlIHRoZSBnaXZlbiBjYWxsYmFjayBmb3IgYGV2ZW50YCBvciBhbGxcbiAqIHJlZ2lzdGVyZWQgY2FsbGJhY2tzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge0VtaXR0ZXJ9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkVtaXR0ZXIucHJvdG90eXBlLm9mZiA9XG5FbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9XG5FbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPVxuRW1pdHRlci5wcm90b3R5cGUucmVtb3ZlRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50LCBmbil7XG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcblxuICAvLyBhbGxcbiAgaWYgKDAgPT0gYXJndW1lbnRzLmxlbmd0aCkge1xuICAgIHRoaXMuX2NhbGxiYWNrcyA9IHt9O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gc3BlY2lmaWMgZXZlbnRcbiAgdmFyIGNhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrc1snJCcgKyBldmVudF07XG4gIGlmICghY2FsbGJhY2tzKSByZXR1cm4gdGhpcztcblxuICAvLyByZW1vdmUgYWxsIGhhbmRsZXJzXG4gIGlmICgxID09IGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICBkZWxldGUgdGhpcy5fY2FsbGJhY2tzWyckJyArIGV2ZW50XTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIHJlbW92ZSBzcGVjaWZpYyBoYW5kbGVyXG4gIHZhciBjYjtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBjYWxsYmFja3MubGVuZ3RoOyBpKyspIHtcbiAgICBjYiA9IGNhbGxiYWNrc1tpXTtcbiAgICBpZiAoY2IgPT09IGZuIHx8IGNiLmZuID09PSBmbikge1xuICAgICAgY2FsbGJhY2tzLnNwbGljZShpLCAxKTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogRW1pdCBgZXZlbnRgIHdpdGggdGhlIGdpdmVuIGFyZ3MuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XG4gKiBAcGFyYW0ge01peGVkfSAuLi5cbiAqIEByZXR1cm4ge0VtaXR0ZXJ9XG4gKi9cblxuRW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uKGV2ZW50KXtcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuICB2YXIgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKVxuICAgICwgY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzWyckJyArIGV2ZW50XTtcblxuICBpZiAoY2FsbGJhY2tzKSB7XG4gICAgY2FsbGJhY2tzID0gY2FsbGJhY2tzLnNsaWNlKDApO1xuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBjYWxsYmFja3MubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgIGNhbGxiYWNrc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogUmV0dXJuIGFycmF5IG9mIGNhbGxiYWNrcyBmb3IgYGV2ZW50YC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEByZXR1cm4ge0FycmF5fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5FbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lcnMgPSBmdW5jdGlvbihldmVudCl7XG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcbiAgcmV0dXJuIHRoaXMuX2NhbGxiYWNrc1snJCcgKyBldmVudF0gfHwgW107XG59O1xuXG4vKipcbiAqIENoZWNrIGlmIHRoaXMgZW1pdHRlciBoYXMgYGV2ZW50YCBoYW5kbGVycy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkVtaXR0ZXIucHJvdG90eXBlLmhhc0xpc3RlbmVycyA9IGZ1bmN0aW9uKGV2ZW50KXtcbiAgcmV0dXJuICEhIHRoaXMubGlzdGVuZXJzKGV2ZW50KS5sZW5ndGg7XG59O1xuIiwiLyoganNoaW50IG5vZGU6IHRydWUgKi9cbihmdW5jdGlvbiAoKSB7XG4gICAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgICBmdW5jdGlvbiBDb29raWVBY2Nlc3NJbmZvKGRvbWFpbiwgcGF0aCwgc2VjdXJlLCBzY3JpcHQpIHtcbiAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBDb29raWVBY2Nlc3NJbmZvKSB7XG4gICAgICAgICAgICB0aGlzLmRvbWFpbiA9IGRvbWFpbiB8fCB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0aGlzLnBhdGggPSBwYXRoIHx8IFwiL1wiO1xuICAgICAgICAgICAgdGhpcy5zZWN1cmUgPSAhIXNlY3VyZTtcbiAgICAgICAgICAgIHRoaXMuc2NyaXB0ID0gISFzY3JpcHQ7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IENvb2tpZUFjY2Vzc0luZm8oZG9tYWluLCBwYXRoLCBzZWN1cmUsIHNjcmlwdCk7XG4gICAgfVxuICAgIGV4cG9ydHMuQ29va2llQWNjZXNzSW5mbyA9IENvb2tpZUFjY2Vzc0luZm87XG5cbiAgICBmdW5jdGlvbiBDb29raWUoY29va2llc3RyLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKSB7XG4gICAgICAgIGlmIChjb29raWVzdHIgaW5zdGFuY2VvZiBDb29raWUpIHtcbiAgICAgICAgICAgIHJldHVybiBjb29raWVzdHI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBDb29raWUpIHtcbiAgICAgICAgICAgIHRoaXMubmFtZSA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLnZhbHVlID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuZXhwaXJhdGlvbl9kYXRlID0gSW5maW5pdHk7XG4gICAgICAgICAgICB0aGlzLnBhdGggPSBTdHJpbmcocmVxdWVzdF9wYXRoIHx8IFwiL1wiKTtcbiAgICAgICAgICAgIHRoaXMuZXhwbGljaXRfcGF0aCA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5kb21haW4gPSByZXF1ZXN0X2RvbWFpbiB8fCBudWxsO1xuICAgICAgICAgICAgdGhpcy5leHBsaWNpdF9kb21haW4gPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuc2VjdXJlID0gZmFsc2U7IC8vaG93IHRvIGRlZmluZSBkZWZhdWx0P1xuICAgICAgICAgICAgdGhpcy5ub3NjcmlwdCA9IGZhbHNlOyAvL2h0dHBvbmx5XG4gICAgICAgICAgICBpZiAoY29va2llc3RyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wYXJzZShjb29raWVzdHIsIHJlcXVlc3RfZG9tYWluLCByZXF1ZXN0X3BhdGgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBDb29raWUoY29va2llc3RyLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKTtcbiAgICB9XG4gICAgZXhwb3J0cy5Db29raWUgPSBDb29raWU7XG5cbiAgICBDb29raWUucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gICAgICAgIHZhciBzdHIgPSBbdGhpcy5uYW1lICsgXCI9XCIgKyB0aGlzLnZhbHVlXTtcbiAgICAgICAgaWYgKHRoaXMuZXhwaXJhdGlvbl9kYXRlICE9PSBJbmZpbml0eSkge1xuICAgICAgICAgICAgc3RyLnB1c2goXCJleHBpcmVzPVwiICsgKG5ldyBEYXRlKHRoaXMuZXhwaXJhdGlvbl9kYXRlKSkudG9HTVRTdHJpbmcoKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuZG9tYWluKSB7XG4gICAgICAgICAgICBzdHIucHVzaChcImRvbWFpbj1cIiArIHRoaXMuZG9tYWluKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5wYXRoKSB7XG4gICAgICAgICAgICBzdHIucHVzaChcInBhdGg9XCIgKyB0aGlzLnBhdGgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnNlY3VyZSkge1xuICAgICAgICAgICAgc3RyLnB1c2goXCJzZWN1cmVcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMubm9zY3JpcHQpIHtcbiAgICAgICAgICAgIHN0ci5wdXNoKFwiaHR0cG9ubHlcIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHN0ci5qb2luKFwiOyBcIik7XG4gICAgfTtcblxuICAgIENvb2tpZS5wcm90b3R5cGUudG9WYWx1ZVN0cmluZyA9IGZ1bmN0aW9uIHRvVmFsdWVTdHJpbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm5hbWUgKyBcIj1cIiArIHRoaXMudmFsdWU7XG4gICAgfTtcblxuICAgIHZhciBjb29raWVfc3RyX3NwbGl0dGVyID0gL1s6XSg/PVxccypbYS16QS1aMC05X1xcLV0rXFxzKls9XSkvZztcbiAgICBDb29raWUucHJvdG90eXBlLnBhcnNlID0gZnVuY3Rpb24gcGFyc2Uoc3RyLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKSB7XG4gICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgQ29va2llKSB7XG4gICAgICAgICAgICB2YXIgcGFydHMgPSBzdHIuc3BsaXQoXCI7XCIpLmZpbHRlcihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICEhdmFsdWU7XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgcGFpciA9IHBhcnRzWzBdLm1hdGNoKC8oW149XSspPShbXFxzXFxTXSopLyksXG4gICAgICAgICAgICAgICAga2V5ID0gcGFpclsxXSxcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHBhaXJbMl0sXG4gICAgICAgICAgICAgICAgaTtcbiAgICAgICAgICAgIHRoaXMubmFtZSA9IGtleTtcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcblxuICAgICAgICAgICAgZm9yIChpID0gMTsgaSA8IHBhcnRzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgcGFpciA9IHBhcnRzW2ldLm1hdGNoKC8oW149XSspKD86PShbXFxzXFxTXSopKT8vKTtcbiAgICAgICAgICAgICAgICBrZXkgPSBwYWlyWzFdLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgICAgICAgIHZhbHVlID0gcGFpclsyXTtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGtleSkge1xuICAgICAgICAgICAgICAgIGNhc2UgXCJodHRwb25seVwiOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLm5vc2NyaXB0ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcImV4cGlyZXNcIjpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5leHBpcmF0aW9uX2RhdGUgPSB2YWx1ZSA/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgTnVtYmVyKERhdGUucGFyc2UodmFsdWUpKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5maW5pdHk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJwYXRoXCI6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGF0aCA9IHZhbHVlID9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZS50cmltKCkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiXCI7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXhwbGljaXRfcGF0aCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJkb21haW5cIjpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kb21haW4gPSB2YWx1ZSA/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUudHJpbSgpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIlwiO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmV4cGxpY2l0X2RvbWFpbiA9ICEhdGhpcy5kb21haW47XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJzZWN1cmVcIjpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWN1cmUgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5leHBsaWNpdF9wYXRoKSB7XG4gICAgICAgICAgICAgICB0aGlzLnBhdGggPSByZXF1ZXN0X3BhdGggfHwgXCIvXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRoaXMuZXhwbGljaXRfZG9tYWluKSB7XG4gICAgICAgICAgICAgICB0aGlzLmRvbWFpbiA9IHJlcXVlc3RfZG9tYWluO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IENvb2tpZSgpLnBhcnNlKHN0ciwgcmVxdWVzdF9kb21haW4sIHJlcXVlc3RfcGF0aCk7XG4gICAgfTtcblxuICAgIENvb2tpZS5wcm90b3R5cGUubWF0Y2hlcyA9IGZ1bmN0aW9uIG1hdGNoZXMoYWNjZXNzX2luZm8pIHtcbiAgICAgICAgaWYgKHRoaXMubm9zY3JpcHQgJiYgYWNjZXNzX2luZm8uc2NyaXB0IHx8XG4gICAgICAgICAgICAgICAgdGhpcy5zZWN1cmUgJiYgIWFjY2Vzc19pbmZvLnNlY3VyZSB8fFxuICAgICAgICAgICAgICAgICF0aGlzLmNvbGxpZGVzV2l0aChhY2Nlc3NfaW5mbykpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuXG4gICAgQ29va2llLnByb3RvdHlwZS5jb2xsaWRlc1dpdGggPSBmdW5jdGlvbiBjb2xsaWRlc1dpdGgoYWNjZXNzX2luZm8pIHtcbiAgICAgICAgaWYgKCh0aGlzLnBhdGggJiYgIWFjY2Vzc19pbmZvLnBhdGgpIHx8ICh0aGlzLmRvbWFpbiAmJiAhYWNjZXNzX2luZm8uZG9tYWluKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnBhdGggJiYgYWNjZXNzX2luZm8ucGF0aC5pbmRleE9mKHRoaXMucGF0aCkgIT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5leHBsaWNpdF9wYXRoICYmIGFjY2Vzc19pbmZvLnBhdGguaW5kZXhPZiggdGhpcy5wYXRoICkgIT09IDApIHtcbiAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBhY2Nlc3NfZG9tYWluID0gYWNjZXNzX2luZm8uZG9tYWluICYmIGFjY2Vzc19pbmZvLmRvbWFpbi5yZXBsYWNlKC9eW1xcLl0vLCcnKTtcbiAgICAgICAgdmFyIGNvb2tpZV9kb21haW4gPSB0aGlzLmRvbWFpbiAmJiB0aGlzLmRvbWFpbi5yZXBsYWNlKC9eW1xcLl0vLCcnKTtcbiAgICAgICAgaWYgKGNvb2tpZV9kb21haW4gPT09IGFjY2Vzc19kb21haW4pIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb29raWVfZG9tYWluKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuZXhwbGljaXRfZG9tYWluKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyB3ZSBhbHJlYWR5IGNoZWNrZWQgaWYgdGhlIGRvbWFpbnMgd2VyZSBleGFjdGx5IHRoZSBzYW1lXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgd2lsZGNhcmQgPSBhY2Nlc3NfZG9tYWluLmluZGV4T2YoY29va2llX2RvbWFpbik7XG4gICAgICAgICAgICBpZiAod2lsZGNhcmQgPT09IC0xIHx8IHdpbGRjYXJkICE9PSBhY2Nlc3NfZG9tYWluLmxlbmd0aCAtIGNvb2tpZV9kb21haW4ubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIENvb2tpZUphcigpIHtcbiAgICAgICAgdmFyIGNvb2tpZXMsIGNvb2tpZXNfbGlzdCwgY29sbGlkYWJsZV9jb29raWU7XG4gICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgQ29va2llSmFyKSB7XG4gICAgICAgICAgICBjb29raWVzID0gT2JqZWN0LmNyZWF0ZShudWxsKTsgLy9uYW1lOiBbQ29va2llXVxuXG4gICAgICAgICAgICB0aGlzLnNldENvb2tpZSA9IGZ1bmN0aW9uIHNldENvb2tpZShjb29raWUsIHJlcXVlc3RfZG9tYWluLCByZXF1ZXN0X3BhdGgpIHtcbiAgICAgICAgICAgICAgICB2YXIgcmVtb3ZlLCBpO1xuICAgICAgICAgICAgICAgIGNvb2tpZSA9IG5ldyBDb29raWUoY29va2llLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKTtcbiAgICAgICAgICAgICAgICAvL0RlbGV0ZSB0aGUgY29va2llIGlmIHRoZSBzZXQgaXMgcGFzdCB0aGUgY3VycmVudCB0aW1lXG4gICAgICAgICAgICAgICAgcmVtb3ZlID0gY29va2llLmV4cGlyYXRpb25fZGF0ZSA8PSBEYXRlLm5vdygpO1xuICAgICAgICAgICAgICAgIGlmIChjb29raWVzW2Nvb2tpZS5uYW1lXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvb2tpZXNfbGlzdCA9IGNvb2tpZXNbY29va2llLm5hbWVdO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY29va2llc19saXN0Lmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2xsaWRhYmxlX2Nvb2tpZSA9IGNvb2tpZXNfbGlzdFtpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb2xsaWRhYmxlX2Nvb2tpZS5jb2xsaWRlc1dpdGgoY29va2llKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZW1vdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29va2llc19saXN0LnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvb2tpZXNfbGlzdC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBjb29raWVzW2Nvb2tpZS5uYW1lXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvb2tpZXNfbGlzdFtpXSA9IGNvb2tpZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29va2llO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZW1vdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb29raWVzX2xpc3QucHVzaChjb29raWUpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29va2llO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAocmVtb3ZlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29va2llc1tjb29raWUubmFtZV0gPSBbY29va2llXTtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29va2llc1tjb29raWUubmFtZV07XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgLy9yZXR1cm5zIGEgY29va2llXG4gICAgICAgICAgICB0aGlzLmdldENvb2tpZSA9IGZ1bmN0aW9uIGdldENvb2tpZShjb29raWVfbmFtZSwgYWNjZXNzX2luZm8pIHtcbiAgICAgICAgICAgICAgICB2YXIgY29va2llLCBpO1xuICAgICAgICAgICAgICAgIGNvb2tpZXNfbGlzdCA9IGNvb2tpZXNbY29va2llX25hbWVdO1xuICAgICAgICAgICAgICAgIGlmICghY29va2llc19saXN0KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvb2tpZXNfbGlzdC5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICBjb29raWUgPSBjb29raWVzX2xpc3RbaV07XG4gICAgICAgICAgICAgICAgICAgIGlmIChjb29raWUuZXhwaXJhdGlvbl9kYXRlIDw9IERhdGUubm93KCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb29raWVzX2xpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGNvb2tpZXNbY29va2llLm5hbWVdO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoY29va2llLm1hdGNoZXMoYWNjZXNzX2luZm8pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29va2llO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vcmV0dXJucyBhIGxpc3Qgb2YgY29va2llc1xuICAgICAgICAgICAgdGhpcy5nZXRDb29raWVzID0gZnVuY3Rpb24gZ2V0Q29va2llcyhhY2Nlc3NfaW5mbykge1xuICAgICAgICAgICAgICAgIHZhciBtYXRjaGVzID0gW10sIGNvb2tpZV9uYW1lLCBjb29raWU7XG4gICAgICAgICAgICAgICAgZm9yIChjb29raWVfbmFtZSBpbiBjb29raWVzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvb2tpZSA9IHRoaXMuZ2V0Q29va2llKGNvb2tpZV9uYW1lLCBhY2Nlc3NfaW5mbyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjb29raWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoZXMucHVzaChjb29raWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG1hdGNoZXMudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoZXMuam9pbihcIjpcIik7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBtYXRjaGVzLnRvVmFsdWVTdHJpbmcgPSBmdW5jdGlvbiB0b1ZhbHVlU3RyaW5nKCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbWF0Y2hlcy5tYXAoZnVuY3Rpb24gKGMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjLnRvVmFsdWVTdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgfSkuam9pbignOycpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoZXM7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IENvb2tpZUphcigpO1xuICAgIH1cbiAgICBleHBvcnRzLkNvb2tpZUphciA9IENvb2tpZUphcjtcblxuICAgIC8vcmV0dXJucyBsaXN0IG9mIGNvb2tpZXMgdGhhdCB3ZXJlIHNldCBjb3JyZWN0bHkuIENvb2tpZXMgdGhhdCBhcmUgZXhwaXJlZCBhbmQgcmVtb3ZlZCBhcmUgbm90IHJldHVybmVkLlxuICAgIENvb2tpZUphci5wcm90b3R5cGUuc2V0Q29va2llcyA9IGZ1bmN0aW9uIHNldENvb2tpZXMoY29va2llcywgcmVxdWVzdF9kb21haW4sIHJlcXVlc3RfcGF0aCkge1xuICAgICAgICBjb29raWVzID0gQXJyYXkuaXNBcnJheShjb29raWVzKSA/XG4gICAgICAgICAgICAgICAgY29va2llcyA6XG4gICAgICAgICAgICAgICAgY29va2llcy5zcGxpdChjb29raWVfc3RyX3NwbGl0dGVyKTtcbiAgICAgICAgdmFyIHN1Y2Nlc3NmdWwgPSBbXSxcbiAgICAgICAgICAgIGksXG4gICAgICAgICAgICBjb29raWU7XG4gICAgICAgIGNvb2tpZXMgPSBjb29raWVzLm1hcChmdW5jdGlvbihpdGVtKXtcbiAgICAgICAgICAgIHJldHVybiBuZXcgQ29va2llKGl0ZW0sIHJlcXVlc3RfZG9tYWluLCByZXF1ZXN0X3BhdGgpO1xuICAgICAgICB9KTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvb2tpZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGNvb2tpZSA9IGNvb2tpZXNbaV07XG4gICAgICAgICAgICBpZiAodGhpcy5zZXRDb29raWUoY29va2llLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKSkge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3NmdWwucHVzaChjb29raWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdWNjZXNzZnVsO1xuICAgIH07XG59KCkpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciB5YW1sID0gcmVxdWlyZSgnLi9saWIvanMteWFtbC5qcycpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0geWFtbDtcbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgbG9hZGVyID0gcmVxdWlyZSgnLi9qcy15YW1sL2xvYWRlcicpO1xudmFyIGR1bXBlciA9IHJlcXVpcmUoJy4vanMteWFtbC9kdW1wZXInKTtcblxuXG5mdW5jdGlvbiBkZXByZWNhdGVkKG5hbWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0Z1bmN0aW9uICcgKyBuYW1lICsgJyBpcyBkZXByZWNhdGVkIGFuZCBjYW5ub3QgYmUgdXNlZC4nKTtcbiAgfTtcbn1cblxuXG5tb2R1bGUuZXhwb3J0cy5UeXBlICAgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9qcy15YW1sL3R5cGUnKTtcbm1vZHVsZS5leHBvcnRzLlNjaGVtYSAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL2pzLXlhbWwvc2NoZW1hJyk7XG5tb2R1bGUuZXhwb3J0cy5GQUlMU0FGRV9TQ0hFTUEgICAgID0gcmVxdWlyZSgnLi9qcy15YW1sL3NjaGVtYS9mYWlsc2FmZScpO1xubW9kdWxlLmV4cG9ydHMuSlNPTl9TQ0hFTUEgICAgICAgICA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvanNvbicpO1xubW9kdWxlLmV4cG9ydHMuQ09SRV9TQ0hFTUEgICAgICAgICA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvY29yZScpO1xubW9kdWxlLmV4cG9ydHMuREVGQVVMVF9TQUZFX1NDSEVNQSA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvZGVmYXVsdF9zYWZlJyk7XG5tb2R1bGUuZXhwb3J0cy5ERUZBVUxUX0ZVTExfU0NIRU1BID0gcmVxdWlyZSgnLi9qcy15YW1sL3NjaGVtYS9kZWZhdWx0X2Z1bGwnKTtcbm1vZHVsZS5leHBvcnRzLmxvYWQgICAgICAgICAgICAgICAgPSBsb2FkZXIubG9hZDtcbm1vZHVsZS5leHBvcnRzLmxvYWRBbGwgICAgICAgICAgICAgPSBsb2FkZXIubG9hZEFsbDtcbm1vZHVsZS5leHBvcnRzLnNhZmVMb2FkICAgICAgICAgICAgPSBsb2FkZXIuc2FmZUxvYWQ7XG5tb2R1bGUuZXhwb3J0cy5zYWZlTG9hZEFsbCAgICAgICAgID0gbG9hZGVyLnNhZmVMb2FkQWxsO1xubW9kdWxlLmV4cG9ydHMuZHVtcCAgICAgICAgICAgICAgICA9IGR1bXBlci5kdW1wO1xubW9kdWxlLmV4cG9ydHMuc2FmZUR1bXAgICAgICAgICAgICA9IGR1bXBlci5zYWZlRHVtcDtcbm1vZHVsZS5leHBvcnRzLllBTUxFeGNlcHRpb24gICAgICAgPSByZXF1aXJlKCcuL2pzLXlhbWwvZXhjZXB0aW9uJyk7XG5cbi8vIERlcHJlY2F0ZWQgc2NoZW1hIG5hbWVzIGZyb20gSlMtWUFNTCAyLjAueFxubW9kdWxlLmV4cG9ydHMuTUlOSU1BTF9TQ0hFTUEgPSByZXF1aXJlKCcuL2pzLXlhbWwvc2NoZW1hL2ZhaWxzYWZlJyk7XG5tb2R1bGUuZXhwb3J0cy5TQUZFX1NDSEVNQSAgICA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvZGVmYXVsdF9zYWZlJyk7XG5tb2R1bGUuZXhwb3J0cy5ERUZBVUxUX1NDSEVNQSA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvZGVmYXVsdF9mdWxsJyk7XG5cbi8vIERlcHJlY2F0ZWQgZnVuY3Rpb25zIGZyb20gSlMtWUFNTCAxLngueFxubW9kdWxlLmV4cG9ydHMuc2NhbiAgICAgICAgICAgPSBkZXByZWNhdGVkKCdzY2FuJyk7XG5tb2R1bGUuZXhwb3J0cy5wYXJzZSAgICAgICAgICA9IGRlcHJlY2F0ZWQoJ3BhcnNlJyk7XG5tb2R1bGUuZXhwb3J0cy5jb21wb3NlICAgICAgICA9IGRlcHJlY2F0ZWQoJ2NvbXBvc2UnKTtcbm1vZHVsZS5leHBvcnRzLmFkZENvbnN0cnVjdG9yID0gZGVwcmVjYXRlZCgnYWRkQ29uc3RydWN0b3InKTtcbiIsIid1c2Ugc3RyaWN0JztcblxuXG5mdW5jdGlvbiBpc05vdGhpbmcoc3ViamVjdCkge1xuICByZXR1cm4gKHR5cGVvZiBzdWJqZWN0ID09PSAndW5kZWZpbmVkJykgfHwgKHN1YmplY3QgPT09IG51bGwpO1xufVxuXG5cbmZ1bmN0aW9uIGlzT2JqZWN0KHN1YmplY3QpIHtcbiAgcmV0dXJuICh0eXBlb2Ygc3ViamVjdCA9PT0gJ29iamVjdCcpICYmIChzdWJqZWN0ICE9PSBudWxsKTtcbn1cblxuXG5mdW5jdGlvbiB0b0FycmF5KHNlcXVlbmNlKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KHNlcXVlbmNlKSkgcmV0dXJuIHNlcXVlbmNlO1xuICBlbHNlIGlmIChpc05vdGhpbmcoc2VxdWVuY2UpKSByZXR1cm4gW107XG5cbiAgcmV0dXJuIFsgc2VxdWVuY2UgXTtcbn1cblxuXG5mdW5jdGlvbiBleHRlbmQodGFyZ2V0LCBzb3VyY2UpIHtcbiAgdmFyIGluZGV4LCBsZW5ndGgsIGtleSwgc291cmNlS2V5cztcblxuICBpZiAoc291cmNlKSB7XG4gICAgc291cmNlS2V5cyA9IE9iamVjdC5rZXlzKHNvdXJjZSk7XG5cbiAgICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gc291cmNlS2V5cy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgICBrZXkgPSBzb3VyY2VLZXlzW2luZGV4XTtcbiAgICAgIHRhcmdldFtrZXldID0gc291cmNlW2tleV07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRhcmdldDtcbn1cblxuXG5mdW5jdGlvbiByZXBlYXQoc3RyaW5nLCBjb3VudCkge1xuICB2YXIgcmVzdWx0ID0gJycsIGN5Y2xlO1xuXG4gIGZvciAoY3ljbGUgPSAwOyBjeWNsZSA8IGNvdW50OyBjeWNsZSArPSAxKSB7XG4gICAgcmVzdWx0ICs9IHN0cmluZztcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cblxuZnVuY3Rpb24gaXNOZWdhdGl2ZVplcm8obnVtYmVyKSB7XG4gIHJldHVybiAobnVtYmVyID09PSAwKSAmJiAoTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZID09PSAxIC8gbnVtYmVyKTtcbn1cblxuXG5tb2R1bGUuZXhwb3J0cy5pc05vdGhpbmcgICAgICA9IGlzTm90aGluZztcbm1vZHVsZS5leHBvcnRzLmlzT2JqZWN0ICAgICAgID0gaXNPYmplY3Q7XG5tb2R1bGUuZXhwb3J0cy50b0FycmF5ICAgICAgICA9IHRvQXJyYXk7XG5tb2R1bGUuZXhwb3J0cy5yZXBlYXQgICAgICAgICA9IHJlcGVhdDtcbm1vZHVsZS5leHBvcnRzLmlzTmVnYXRpdmVaZXJvID0gaXNOZWdhdGl2ZVplcm87XG5tb2R1bGUuZXhwb3J0cy5leHRlbmQgICAgICAgICA9IGV4dGVuZDtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyplc2xpbnQtZGlzYWJsZSBuby11c2UtYmVmb3JlLWRlZmluZSovXG5cbnZhciBjb21tb24gICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9jb21tb24nKTtcbnZhciBZQU1MRXhjZXB0aW9uICAgICAgID0gcmVxdWlyZSgnLi9leGNlcHRpb24nKTtcbnZhciBERUZBVUxUX0ZVTExfU0NIRU1BID0gcmVxdWlyZSgnLi9zY2hlbWEvZGVmYXVsdF9mdWxsJyk7XG52YXIgREVGQVVMVF9TQUZFX1NDSEVNQSA9IHJlcXVpcmUoJy4vc2NoZW1hL2RlZmF1bHRfc2FmZScpO1xuXG52YXIgX3RvU3RyaW5nICAgICAgID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcbnZhciBfaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG52YXIgQ0hBUl9UQUIgICAgICAgICAgICAgICAgICA9IDB4MDk7IC8qIFRhYiAqL1xudmFyIENIQVJfTElORV9GRUVEICAgICAgICAgICAgPSAweDBBOyAvKiBMRiAqL1xudmFyIENIQVJfQ0FSUklBR0VfUkVUVVJOICAgICAgPSAweDBEOyAvKiBDUiAqL1xudmFyIENIQVJfU1BBQ0UgICAgICAgICAgICAgICAgPSAweDIwOyAvKiBTcGFjZSAqL1xudmFyIENIQVJfRVhDTEFNQVRJT04gICAgICAgICAgPSAweDIxOyAvKiAhICovXG52YXIgQ0hBUl9ET1VCTEVfUVVPVEUgICAgICAgICA9IDB4MjI7IC8qIFwiICovXG52YXIgQ0hBUl9TSEFSUCAgICAgICAgICAgICAgICA9IDB4MjM7IC8qICMgKi9cbnZhciBDSEFSX1BFUkNFTlQgICAgICAgICAgICAgID0gMHgyNTsgLyogJSAqL1xudmFyIENIQVJfQU1QRVJTQU5EICAgICAgICAgICAgPSAweDI2OyAvKiAmICovXG52YXIgQ0hBUl9TSU5HTEVfUVVPVEUgICAgICAgICA9IDB4Mjc7IC8qICcgKi9cbnZhciBDSEFSX0FTVEVSSVNLICAgICAgICAgICAgID0gMHgyQTsgLyogKiAqL1xudmFyIENIQVJfQ09NTUEgICAgICAgICAgICAgICAgPSAweDJDOyAvKiAsICovXG52YXIgQ0hBUl9NSU5VUyAgICAgICAgICAgICAgICA9IDB4MkQ7IC8qIC0gKi9cbnZhciBDSEFSX0NPTE9OICAgICAgICAgICAgICAgID0gMHgzQTsgLyogOiAqL1xudmFyIENIQVJfR1JFQVRFUl9USEFOICAgICAgICAgPSAweDNFOyAvKiA+ICovXG52YXIgQ0hBUl9RVUVTVElPTiAgICAgICAgICAgICA9IDB4M0Y7IC8qID8gKi9cbnZhciBDSEFSX0NPTU1FUkNJQUxfQVQgICAgICAgID0gMHg0MDsgLyogQCAqL1xudmFyIENIQVJfTEVGVF9TUVVBUkVfQlJBQ0tFVCAgPSAweDVCOyAvKiBbICovXG52YXIgQ0hBUl9SSUdIVF9TUVVBUkVfQlJBQ0tFVCA9IDB4NUQ7IC8qIF0gKi9cbnZhciBDSEFSX0dSQVZFX0FDQ0VOVCAgICAgICAgID0gMHg2MDsgLyogYCAqL1xudmFyIENIQVJfTEVGVF9DVVJMWV9CUkFDS0VUICAgPSAweDdCOyAvKiB7ICovXG52YXIgQ0hBUl9WRVJUSUNBTF9MSU5FICAgICAgICA9IDB4N0M7IC8qIHwgKi9cbnZhciBDSEFSX1JJR0hUX0NVUkxZX0JSQUNLRVQgID0gMHg3RDsgLyogfSAqL1xuXG52YXIgRVNDQVBFX1NFUVVFTkNFUyA9IHt9O1xuXG5FU0NBUEVfU0VRVUVOQ0VTWzB4MDBdICAgPSAnXFxcXDAnO1xuRVNDQVBFX1NFUVVFTkNFU1sweDA3XSAgID0gJ1xcXFxhJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgwOF0gICA9ICdcXFxcYic7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MDldICAgPSAnXFxcXHQnO1xuRVNDQVBFX1NFUVVFTkNFU1sweDBBXSAgID0gJ1xcXFxuJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgwQl0gICA9ICdcXFxcdic7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MENdICAgPSAnXFxcXGYnO1xuRVNDQVBFX1NFUVVFTkNFU1sweDBEXSAgID0gJ1xcXFxyJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgxQl0gICA9ICdcXFxcZSc7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MjJdICAgPSAnXFxcXFwiJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHg1Q10gICA9ICdcXFxcXFxcXCc7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4ODVdICAgPSAnXFxcXE4nO1xuRVNDQVBFX1NFUVVFTkNFU1sweEEwXSAgID0gJ1xcXFxfJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgyMDI4XSA9ICdcXFxcTCc7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MjAyOV0gPSAnXFxcXFAnO1xuXG52YXIgREVQUkVDQVRFRF9CT09MRUFOU19TWU5UQVggPSBbXG4gICd5JywgJ1knLCAneWVzJywgJ1llcycsICdZRVMnLCAnb24nLCAnT24nLCAnT04nLFxuICAnbicsICdOJywgJ25vJywgJ05vJywgJ05PJywgJ29mZicsICdPZmYnLCAnT0ZGJ1xuXTtcblxuZnVuY3Rpb24gY29tcGlsZVN0eWxlTWFwKHNjaGVtYSwgbWFwKSB7XG4gIHZhciByZXN1bHQsIGtleXMsIGluZGV4LCBsZW5ndGgsIHRhZywgc3R5bGUsIHR5cGU7XG5cbiAgaWYgKG1hcCA9PT0gbnVsbCkgcmV0dXJuIHt9O1xuXG4gIHJlc3VsdCA9IHt9O1xuICBrZXlzID0gT2JqZWN0LmtleXMobWFwKTtcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0ga2V5cy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgdGFnID0ga2V5c1tpbmRleF07XG4gICAgc3R5bGUgPSBTdHJpbmcobWFwW3RhZ10pO1xuXG4gICAgaWYgKHRhZy5zbGljZSgwLCAyKSA9PT0gJyEhJykge1xuICAgICAgdGFnID0gJ3RhZzp5YW1sLm9yZywyMDAyOicgKyB0YWcuc2xpY2UoMik7XG4gICAgfVxuXG4gICAgdHlwZSA9IHNjaGVtYS5jb21waWxlZFR5cGVNYXBbdGFnXTtcblxuICAgIGlmICh0eXBlICYmIF9oYXNPd25Qcm9wZXJ0eS5jYWxsKHR5cGUuc3R5bGVBbGlhc2VzLCBzdHlsZSkpIHtcbiAgICAgIHN0eWxlID0gdHlwZS5zdHlsZUFsaWFzZXNbc3R5bGVdO1xuICAgIH1cblxuICAgIHJlc3VsdFt0YWddID0gc3R5bGU7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBlbmNvZGVIZXgoY2hhcmFjdGVyKSB7XG4gIHZhciBzdHJpbmcsIGhhbmRsZSwgbGVuZ3RoO1xuXG4gIHN0cmluZyA9IGNoYXJhY3Rlci50b1N0cmluZygxNikudG9VcHBlckNhc2UoKTtcblxuICBpZiAoY2hhcmFjdGVyIDw9IDB4RkYpIHtcbiAgICBoYW5kbGUgPSAneCc7XG4gICAgbGVuZ3RoID0gMjtcbiAgfSBlbHNlIGlmIChjaGFyYWN0ZXIgPD0gMHhGRkZGKSB7XG4gICAgaGFuZGxlID0gJ3UnO1xuICAgIGxlbmd0aCA9IDQ7XG4gIH0gZWxzZSBpZiAoY2hhcmFjdGVyIDw9IDB4RkZGRkZGRkYpIHtcbiAgICBoYW5kbGUgPSAnVSc7XG4gICAgbGVuZ3RoID0gODtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignY29kZSBwb2ludCB3aXRoaW4gYSBzdHJpbmcgbWF5IG5vdCBiZSBncmVhdGVyIHRoYW4gMHhGRkZGRkZGRicpO1xuICB9XG5cbiAgcmV0dXJuICdcXFxcJyArIGhhbmRsZSArIGNvbW1vbi5yZXBlYXQoJzAnLCBsZW5ndGggLSBzdHJpbmcubGVuZ3RoKSArIHN0cmluZztcbn1cblxuZnVuY3Rpb24gU3RhdGUob3B0aW9ucykge1xuICB0aGlzLnNjaGVtYSAgICAgID0gb3B0aW9uc1snc2NoZW1hJ10gfHwgREVGQVVMVF9GVUxMX1NDSEVNQTtcbiAgdGhpcy5pbmRlbnQgICAgICA9IE1hdGgubWF4KDEsIChvcHRpb25zWydpbmRlbnQnXSB8fCAyKSk7XG4gIHRoaXMuc2tpcEludmFsaWQgPSBvcHRpb25zWydza2lwSW52YWxpZCddIHx8IGZhbHNlO1xuICB0aGlzLmZsb3dMZXZlbCAgID0gKGNvbW1vbi5pc05vdGhpbmcob3B0aW9uc1snZmxvd0xldmVsJ10pID8gLTEgOiBvcHRpb25zWydmbG93TGV2ZWwnXSk7XG4gIHRoaXMuc3R5bGVNYXAgICAgPSBjb21waWxlU3R5bGVNYXAodGhpcy5zY2hlbWEsIG9wdGlvbnNbJ3N0eWxlcyddIHx8IG51bGwpO1xuICB0aGlzLnNvcnRLZXlzICAgID0gb3B0aW9uc1snc29ydEtleXMnXSB8fCBmYWxzZTtcbiAgdGhpcy5saW5lV2lkdGggICA9IG9wdGlvbnNbJ2xpbmVXaWR0aCddIHx8IDgwO1xuICB0aGlzLm5vUmVmcyAgICAgID0gb3B0aW9uc1snbm9SZWZzJ10gfHwgZmFsc2U7XG5cbiAgdGhpcy5pbXBsaWNpdFR5cGVzID0gdGhpcy5zY2hlbWEuY29tcGlsZWRJbXBsaWNpdDtcbiAgdGhpcy5leHBsaWNpdFR5cGVzID0gdGhpcy5zY2hlbWEuY29tcGlsZWRFeHBsaWNpdDtcblxuICB0aGlzLnRhZyA9IG51bGw7XG4gIHRoaXMucmVzdWx0ID0gJyc7XG5cbiAgdGhpcy5kdXBsaWNhdGVzID0gW107XG4gIHRoaXMudXNlZER1cGxpY2F0ZXMgPSBudWxsO1xufVxuXG5mdW5jdGlvbiBpbmRlbnRTdHJpbmcoc3RyaW5nLCBzcGFjZXMpIHtcbiAgdmFyIGluZCA9IGNvbW1vbi5yZXBlYXQoJyAnLCBzcGFjZXMpLFxuICAgICAgcG9zaXRpb24gPSAwLFxuICAgICAgbmV4dCA9IC0xLFxuICAgICAgcmVzdWx0ID0gJycsXG4gICAgICBsaW5lLFxuICAgICAgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aDtcblxuICB3aGlsZSAocG9zaXRpb24gPCBsZW5ndGgpIHtcbiAgICBuZXh0ID0gc3RyaW5nLmluZGV4T2YoJ1xcbicsIHBvc2l0aW9uKTtcbiAgICBpZiAobmV4dCA9PT0gLTEpIHtcbiAgICAgIGxpbmUgPSBzdHJpbmcuc2xpY2UocG9zaXRpb24pO1xuICAgICAgcG9zaXRpb24gPSBsZW5ndGg7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxpbmUgPSBzdHJpbmcuc2xpY2UocG9zaXRpb24sIG5leHQgKyAxKTtcbiAgICAgIHBvc2l0aW9uID0gbmV4dCArIDE7XG4gICAgfVxuXG4gICAgaWYgKGxpbmUubGVuZ3RoICYmIGxpbmUgIT09ICdcXG4nKSByZXN1bHQgKz0gaW5kO1xuXG4gICAgcmVzdWx0ICs9IGxpbmU7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBnZW5lcmF0ZU5leHRMaW5lKHN0YXRlLCBsZXZlbCkge1xuICByZXR1cm4gJ1xcbicgKyBjb21tb24ucmVwZWF0KCcgJywgc3RhdGUuaW5kZW50ICogbGV2ZWwpO1xufVxuXG5mdW5jdGlvbiB0ZXN0SW1wbGljaXRSZXNvbHZpbmcoc3RhdGUsIHN0cikge1xuICB2YXIgaW5kZXgsIGxlbmd0aCwgdHlwZTtcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gc3RhdGUuaW1wbGljaXRUeXBlcy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgdHlwZSA9IHN0YXRlLmltcGxpY2l0VHlwZXNbaW5kZXhdO1xuXG4gICAgaWYgKHR5cGUucmVzb2x2ZShzdHIpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIFN0cmluZ0J1aWxkZXIoc291cmNlKSB7XG4gIHRoaXMuc291cmNlID0gc291cmNlO1xuICB0aGlzLnJlc3VsdCA9ICcnO1xuICB0aGlzLmNoZWNrcG9pbnQgPSAwO1xufVxuXG5TdHJpbmdCdWlsZGVyLnByb3RvdHlwZS50YWtlVXBUbyA9IGZ1bmN0aW9uIChwb3NpdGlvbikge1xuICB2YXIgZXI7XG5cbiAgaWYgKHBvc2l0aW9uIDwgdGhpcy5jaGVja3BvaW50KSB7XG4gICAgZXIgPSBuZXcgRXJyb3IoJ3Bvc2l0aW9uIHNob3VsZCBiZSA+IGNoZWNrcG9pbnQnKTtcbiAgICBlci5wb3NpdGlvbiA9IHBvc2l0aW9uO1xuICAgIGVyLmNoZWNrcG9pbnQgPSB0aGlzLmNoZWNrcG9pbnQ7XG4gICAgdGhyb3cgZXI7XG4gIH1cblxuICB0aGlzLnJlc3VsdCArPSB0aGlzLnNvdXJjZS5zbGljZSh0aGlzLmNoZWNrcG9pbnQsIHBvc2l0aW9uKTtcbiAgdGhpcy5jaGVja3BvaW50ID0gcG9zaXRpb247XG4gIHJldHVybiB0aGlzO1xufTtcblxuU3RyaW5nQnVpbGRlci5wcm90b3R5cGUuZXNjYXBlQ2hhciA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGNoYXJhY3RlciwgZXNjO1xuXG4gIGNoYXJhY3RlciA9IHRoaXMuc291cmNlLmNoYXJDb2RlQXQodGhpcy5jaGVja3BvaW50KTtcbiAgZXNjID0gRVNDQVBFX1NFUVVFTkNFU1tjaGFyYWN0ZXJdIHx8IGVuY29kZUhleChjaGFyYWN0ZXIpO1xuICB0aGlzLnJlc3VsdCArPSBlc2M7XG4gIHRoaXMuY2hlY2twb2ludCArPSAxO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuU3RyaW5nQnVpbGRlci5wcm90b3R5cGUuZmluaXNoID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5zb3VyY2UubGVuZ3RoID4gdGhpcy5jaGVja3BvaW50KSB7XG4gICAgdGhpcy50YWtlVXBUbyh0aGlzLnNvdXJjZS5sZW5ndGgpO1xuICB9XG59O1xuXG5mdW5jdGlvbiB3cml0ZVNjYWxhcihzdGF0ZSwgb2JqZWN0LCBsZXZlbCwgaXNrZXkpIHtcbiAgdmFyIHNpbXBsZSwgZmlyc3QsIHNwYWNlV3JhcCwgZm9sZGVkLCBsaXRlcmFsLCBzaW5nbGUsIGRvdWJsZSxcbiAgICAgIHNhd0xpbmVGZWVkLCBsaW5lUG9zaXRpb24sIGxvbmdlc3RMaW5lLCBpbmRlbnQsIG1heCwgY2hhcmFjdGVyLFxuICAgICAgcG9zaXRpb24sIGVzY2FwZVNlcSwgaGV4RXNjLCBwcmV2aW91cywgbGluZUxlbmd0aCwgbW9kaWZpZXIsXG4gICAgICB0cmFpbGluZ0xpbmVCcmVha3MsIHJlc3VsdDtcblxuICBpZiAob2JqZWN0Lmxlbmd0aCA9PT0gMCkge1xuICAgIHN0YXRlLmR1bXAgPSBcIicnXCI7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKERFUFJFQ0FURURfQk9PTEVBTlNfU1lOVEFYLmluZGV4T2Yob2JqZWN0KSAhPT0gLTEpIHtcbiAgICBzdGF0ZS5kdW1wID0gXCInXCIgKyBvYmplY3QgKyBcIidcIjtcbiAgICByZXR1cm47XG4gIH1cblxuICBzaW1wbGUgPSB0cnVlO1xuICBmaXJzdCA9IG9iamVjdC5sZW5ndGggPyBvYmplY3QuY2hhckNvZGVBdCgwKSA6IDA7XG4gIHNwYWNlV3JhcCA9IChDSEFSX1NQQUNFID09PSBmaXJzdCB8fFxuICAgICAgICAgICAgICAgQ0hBUl9TUEFDRSA9PT0gb2JqZWN0LmNoYXJDb2RlQXQob2JqZWN0Lmxlbmd0aCAtIDEpKTtcblxuICAvLyBTaW1wbGlmaWVkIGNoZWNrIGZvciByZXN0cmljdGVkIGZpcnN0IGNoYXJhY3RlcnNcbiAgLy8gaHR0cDovL3d3dy55YW1sLm9yZy9zcGVjLzEuMi9zcGVjLmh0bWwjbnMtcGxhaW4tZmlyc3QlMjhjJTI5XG4gIGlmIChDSEFSX01JTlVTICAgICAgICAgPT09IGZpcnN0IHx8XG4gICAgICBDSEFSX1FVRVNUSU9OICAgICAgPT09IGZpcnN0IHx8XG4gICAgICBDSEFSX0NPTU1FUkNJQUxfQVQgPT09IGZpcnN0IHx8XG4gICAgICBDSEFSX0dSQVZFX0FDQ0VOVCAgPT09IGZpcnN0KSB7XG4gICAgc2ltcGxlID0gZmFsc2U7XG4gIH1cblxuICAvLyBDYW4gb25seSB1c2UgPiBhbmQgfCBpZiBub3Qgd3JhcHBlZCBpbiBzcGFjZXMgb3IgaXMgbm90IGEga2V5LlxuICAvLyBBbHNvLCBkb24ndCB1c2UgaWYgaW4gZmxvdyBtb2RlLlxuICBpZiAoc3BhY2VXcmFwIHx8IChzdGF0ZS5mbG93TGV2ZWwgPiAtMSAmJiBzdGF0ZS5mbG93TGV2ZWwgPD0gbGV2ZWwpKSB7XG4gICAgaWYgKHNwYWNlV3JhcCkgc2ltcGxlID0gZmFsc2U7XG5cbiAgICBmb2xkZWQgPSBmYWxzZTtcbiAgICBsaXRlcmFsID0gZmFsc2U7XG4gIH0gZWxzZSB7XG4gICAgZm9sZGVkID0gIWlza2V5O1xuICAgIGxpdGVyYWwgPSAhaXNrZXk7XG4gIH1cblxuICBzaW5nbGUgPSB0cnVlO1xuICBkb3VibGUgPSBuZXcgU3RyaW5nQnVpbGRlcihvYmplY3QpO1xuXG4gIHNhd0xpbmVGZWVkID0gZmFsc2U7XG4gIGxpbmVQb3NpdGlvbiA9IDA7XG4gIGxvbmdlc3RMaW5lID0gMDtcblxuICBpbmRlbnQgPSBzdGF0ZS5pbmRlbnQgKiBsZXZlbDtcbiAgbWF4ID0gc3RhdGUubGluZVdpZHRoO1xuXG4gIC8vIFJlcGxhY2UgLTEgd2l0aCBiaWdnZXN0IGluZ2VnZXIgbnVtYmVyIGFjY29yZGluZyB0b1xuICAvLyBodHRwOi8vZWNtYTI2Mi01LmNvbS9FTFM1X0hUTUwuaHRtI1NlY3Rpb25fOC41XG4gIGlmIChtYXggPT09IC0xKSBtYXggPSA5MDA3MTk5MjU0NzQwOTkxO1xuXG4gIGlmIChpbmRlbnQgPCA0MCkgbWF4IC09IGluZGVudDtcbiAgZWxzZSBtYXggPSA0MDtcblxuICBmb3IgKHBvc2l0aW9uID0gMDsgcG9zaXRpb24gPCBvYmplY3QubGVuZ3RoOyBwb3NpdGlvbisrKSB7XG4gICAgY2hhcmFjdGVyID0gb2JqZWN0LmNoYXJDb2RlQXQocG9zaXRpb24pO1xuICAgIGlmIChzaW1wbGUpIHtcbiAgICAgIC8vIENoYXJhY3RlcnMgdGhhdCBjYW4gbmV2ZXIgYXBwZWFyIGluIHRoZSBzaW1wbGUgc2NhbGFyXG4gICAgICBpZiAoIXNpbXBsZUNoYXIoY2hhcmFjdGVyKSkge1xuICAgICAgICBzaW1wbGUgPSBmYWxzZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFN0aWxsIHNpbXBsZS4gIElmIHdlIG1ha2UgaXQgYWxsIHRoZSB3YXkgdGhyb3VnaCBsaWtlXG4gICAgICAgIC8vIHRoaXMsIHRoZW4gd2UgY2FuIGp1c3QgZHVtcCB0aGUgc3RyaW5nIGFzLWlzLlxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc2luZ2xlICYmIGNoYXJhY3RlciA9PT0gQ0hBUl9TSU5HTEVfUVVPVEUpIHtcbiAgICAgIHNpbmdsZSA9IGZhbHNlO1xuICAgIH1cblxuICAgIGVzY2FwZVNlcSA9IEVTQ0FQRV9TRVFVRU5DRVNbY2hhcmFjdGVyXTtcbiAgICBoZXhFc2MgPSBuZWVkc0hleEVzY2FwZShjaGFyYWN0ZXIpO1xuXG4gICAgaWYgKCFlc2NhcGVTZXEgJiYgIWhleEVzYykge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKGNoYXJhY3RlciAhPT0gQ0hBUl9MSU5FX0ZFRUQgJiZcbiAgICAgICAgY2hhcmFjdGVyICE9PSBDSEFSX0RPVUJMRV9RVU9URSAmJlxuICAgICAgICBjaGFyYWN0ZXIgIT09IENIQVJfU0lOR0xFX1FVT1RFKSB7XG4gICAgICBmb2xkZWQgPSBmYWxzZTtcbiAgICAgIGxpdGVyYWwgPSBmYWxzZTtcbiAgICB9IGVsc2UgaWYgKGNoYXJhY3RlciA9PT0gQ0hBUl9MSU5FX0ZFRUQpIHtcbiAgICAgIHNhd0xpbmVGZWVkID0gdHJ1ZTtcbiAgICAgIHNpbmdsZSA9IGZhbHNlO1xuICAgICAgaWYgKHBvc2l0aW9uID4gMCkge1xuICAgICAgICBwcmV2aW91cyA9IG9iamVjdC5jaGFyQ29kZUF0KHBvc2l0aW9uIC0gMSk7XG4gICAgICAgIGlmIChwcmV2aW91cyA9PT0gQ0hBUl9TUEFDRSkge1xuICAgICAgICAgIGxpdGVyYWwgPSBmYWxzZTtcbiAgICAgICAgICBmb2xkZWQgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGZvbGRlZCkge1xuICAgICAgICBsaW5lTGVuZ3RoID0gcG9zaXRpb24gLSBsaW5lUG9zaXRpb247XG4gICAgICAgIGxpbmVQb3NpdGlvbiA9IHBvc2l0aW9uO1xuICAgICAgICBpZiAobGluZUxlbmd0aCA+IGxvbmdlc3RMaW5lKSBsb25nZXN0TGluZSA9IGxpbmVMZW5ndGg7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNoYXJhY3RlciAhPT0gQ0hBUl9ET1VCTEVfUVVPVEUpIHNpbmdsZSA9IGZhbHNlO1xuXG4gICAgZG91YmxlLnRha2VVcFRvKHBvc2l0aW9uKTtcbiAgICBkb3VibGUuZXNjYXBlQ2hhcigpO1xuICB9XG5cbiAgaWYgKHNpbXBsZSAmJiB0ZXN0SW1wbGljaXRSZXNvbHZpbmcoc3RhdGUsIG9iamVjdCkpIHNpbXBsZSA9IGZhbHNlO1xuXG4gIG1vZGlmaWVyID0gJyc7XG4gIGlmIChmb2xkZWQgfHwgbGl0ZXJhbCkge1xuICAgIHRyYWlsaW5nTGluZUJyZWFrcyA9IDA7XG4gICAgaWYgKG9iamVjdC5jaGFyQ29kZUF0KG9iamVjdC5sZW5ndGggLSAxKSA9PT0gQ0hBUl9MSU5FX0ZFRUQpIHtcbiAgICAgIHRyYWlsaW5nTGluZUJyZWFrcyArPSAxO1xuICAgICAgaWYgKG9iamVjdC5jaGFyQ29kZUF0KG9iamVjdC5sZW5ndGggLSAyKSA9PT0gQ0hBUl9MSU5FX0ZFRUQpIHtcbiAgICAgICAgdHJhaWxpbmdMaW5lQnJlYWtzICs9IDE7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRyYWlsaW5nTGluZUJyZWFrcyA9PT0gMCkgbW9kaWZpZXIgPSAnLSc7XG4gICAgZWxzZSBpZiAodHJhaWxpbmdMaW5lQnJlYWtzID09PSAyKSBtb2RpZmllciA9ICcrJztcbiAgfVxuXG4gIGlmIChsaXRlcmFsICYmIGxvbmdlc3RMaW5lIDwgbWF4IHx8IHN0YXRlLnRhZyAhPT0gbnVsbCkge1xuICAgIGZvbGRlZCA9IGZhbHNlO1xuICB9XG5cbiAgLy8gSWYgaXQncyBsaXRlcmFsbHkgb25lIGxpbmUsIHRoZW4gZG9uJ3QgYm90aGVyIHdpdGggdGhlIGxpdGVyYWwuXG4gIC8vIFdlIG1heSBzdGlsbCB3YW50IHRvIGRvIGEgZm9sZCwgdGhvdWdoLCBpZiBpdCdzIGEgc3VwZXIgbG9uZyBsaW5lLlxuICBpZiAoIXNhd0xpbmVGZWVkKSBsaXRlcmFsID0gZmFsc2U7XG5cbiAgaWYgKHNpbXBsZSkge1xuICAgIHN0YXRlLmR1bXAgPSBvYmplY3Q7XG4gIH0gZWxzZSBpZiAoc2luZ2xlKSB7XG4gICAgc3RhdGUuZHVtcCA9ICdcXCcnICsgb2JqZWN0ICsgJ1xcJyc7XG4gIH0gZWxzZSBpZiAoZm9sZGVkKSB7XG4gICAgcmVzdWx0ID0gZm9sZChvYmplY3QsIG1heCk7XG4gICAgc3RhdGUuZHVtcCA9ICc+JyArIG1vZGlmaWVyICsgJ1xcbicgKyBpbmRlbnRTdHJpbmcocmVzdWx0LCBpbmRlbnQpO1xuICB9IGVsc2UgaWYgKGxpdGVyYWwpIHtcbiAgICBpZiAoIW1vZGlmaWVyKSBvYmplY3QgPSBvYmplY3QucmVwbGFjZSgvXFxuJC8sICcnKTtcbiAgICBzdGF0ZS5kdW1wID0gJ3wnICsgbW9kaWZpZXIgKyAnXFxuJyArIGluZGVudFN0cmluZyhvYmplY3QsIGluZGVudCk7XG4gIH0gZWxzZSBpZiAoZG91YmxlKSB7XG4gICAgZG91YmxlLmZpbmlzaCgpO1xuICAgIHN0YXRlLmR1bXAgPSAnXCInICsgZG91YmxlLnJlc3VsdCArICdcIic7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gZHVtcCBzY2FsYXIgdmFsdWUnKTtcbiAgfVxuXG4gIHJldHVybjtcbn1cblxuLy8gVGhlIGB0cmFpbGluZ2AgdmFyIGlzIGEgcmVnZXhwIG1hdGNoIG9mIGFueSB0cmFpbGluZyBgXFxuYCBjaGFyYWN0ZXJzLlxuLy9cbi8vIFRoZXJlIGFyZSB0aHJlZSBjYXNlcyB3ZSBjYXJlIGFib3V0OlxuLy9cbi8vIDEuIE9uZSB0cmFpbGluZyBgXFxuYCBvbiB0aGUgc3RyaW5nLiAgSnVzdCB1c2UgYHxgIG9yIGA+YC5cbi8vICAgIFRoaXMgaXMgdGhlIGFzc3VtZWQgZGVmYXVsdC4gKHRyYWlsaW5nID0gbnVsbClcbi8vIDIuIE5vIHRyYWlsaW5nIGBcXG5gIG9uIHRoZSBzdHJpbmcuICBVc2UgYHwtYCBvciBgPi1gIHRvIFwiY2hvbXBcIiB0aGUgZW5kLlxuLy8gMy4gTW9yZSB0aGFuIG9uZSB0cmFpbGluZyBgXFxuYCBvbiB0aGUgc3RyaW5nLiAgVXNlIGB8K2Agb3IgYD4rYC5cbi8vXG4vLyBJbiB0aGUgY2FzZSBvZiBgPitgLCB0aGVzZSBsaW5lIGJyZWFrcyBhcmUgKm5vdCogZG91YmxlZCAobGlrZSB0aGUgbGluZVxuLy8gYnJlYWtzIHdpdGhpbiB0aGUgc3RyaW5nKSwgc28gaXQncyBpbXBvcnRhbnQgdG8gb25seSBlbmQgd2l0aCB0aGUgZXhhY3Rcbi8vIHNhbWUgbnVtYmVyIGFzIHdlIHN0YXJ0ZWQuXG5mdW5jdGlvbiBmb2xkKG9iamVjdCwgbWF4KSB7XG4gIHZhciByZXN1bHQgPSAnJyxcbiAgICAgIHBvc2l0aW9uID0gMCxcbiAgICAgIGxlbmd0aCA9IG9iamVjdC5sZW5ndGgsXG4gICAgICB0cmFpbGluZyA9IC9cXG4rJC8uZXhlYyhvYmplY3QpLFxuICAgICAgbmV3TGluZTtcblxuICBpZiAodHJhaWxpbmcpIHtcbiAgICBsZW5ndGggPSB0cmFpbGluZy5pbmRleCArIDE7XG4gIH1cblxuICB3aGlsZSAocG9zaXRpb24gPCBsZW5ndGgpIHtcbiAgICBuZXdMaW5lID0gb2JqZWN0LmluZGV4T2YoJ1xcbicsIHBvc2l0aW9uKTtcbiAgICBpZiAobmV3TGluZSA+IGxlbmd0aCB8fCBuZXdMaW5lID09PSAtMSkge1xuICAgICAgaWYgKHJlc3VsdCkgcmVzdWx0ICs9ICdcXG5cXG4nO1xuICAgICAgcmVzdWx0ICs9IGZvbGRMaW5lKG9iamVjdC5zbGljZShwb3NpdGlvbiwgbGVuZ3RoKSwgbWF4KTtcbiAgICAgIHBvc2l0aW9uID0gbGVuZ3RoO1xuXG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChyZXN1bHQpIHJlc3VsdCArPSAnXFxuXFxuJztcbiAgICAgIHJlc3VsdCArPSBmb2xkTGluZShvYmplY3Quc2xpY2UocG9zaXRpb24sIG5ld0xpbmUpLCBtYXgpO1xuICAgICAgcG9zaXRpb24gPSBuZXdMaW5lICsgMTtcbiAgICB9XG4gIH1cblxuICBpZiAodHJhaWxpbmcgJiYgdHJhaWxpbmdbMF0gIT09ICdcXG4nKSByZXN1bHQgKz0gdHJhaWxpbmdbMF07XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gZm9sZExpbmUobGluZSwgbWF4KSB7XG4gIGlmIChsaW5lID09PSAnJykgcmV0dXJuIGxpbmU7XG5cbiAgdmFyIGZvbGRSZSA9IC9bXlxcc10gW15cXHNdL2csXG4gICAgICByZXN1bHQgPSAnJyxcbiAgICAgIHByZXZNYXRjaCA9IDAsXG4gICAgICBmb2xkU3RhcnQgPSAwLFxuICAgICAgbWF0Y2ggPSBmb2xkUmUuZXhlYyhsaW5lKSxcbiAgICAgIGluZGV4LFxuICAgICAgZm9sZEVuZCxcbiAgICAgIGZvbGRlZDtcblxuICB3aGlsZSAobWF0Y2gpIHtcbiAgICBpbmRleCA9IG1hdGNoLmluZGV4O1xuXG4gICAgLy8gd2hlbiB3ZSBjcm9zcyB0aGUgbWF4IGxlbiwgaWYgdGhlIHByZXZpb3VzIG1hdGNoIHdvdWxkJ3ZlXG4gICAgLy8gYmVlbiBvaywgdXNlIHRoYXQgb25lLCBhbmQgY2Fycnkgb24uICBJZiB0aGVyZSB3YXMgbm8gcHJldmlvdXNcbiAgICAvLyBtYXRjaCBvbiB0aGlzIGZvbGQgc2VjdGlvbiwgdGhlbiBqdXN0IGhhdmUgYSBsb25nIGxpbmUuXG4gICAgaWYgKGluZGV4IC0gZm9sZFN0YXJ0ID4gbWF4KSB7XG4gICAgICBpZiAocHJldk1hdGNoICE9PSBmb2xkU3RhcnQpIGZvbGRFbmQgPSBwcmV2TWF0Y2g7XG4gICAgICBlbHNlIGZvbGRFbmQgPSBpbmRleDtcblxuICAgICAgaWYgKHJlc3VsdCkgcmVzdWx0ICs9ICdcXG4nO1xuICAgICAgZm9sZGVkID0gbGluZS5zbGljZShmb2xkU3RhcnQsIGZvbGRFbmQpO1xuICAgICAgcmVzdWx0ICs9IGZvbGRlZDtcbiAgICAgIGZvbGRTdGFydCA9IGZvbGRFbmQgKyAxO1xuICAgIH1cbiAgICBwcmV2TWF0Y2ggPSBpbmRleCArIDE7XG4gICAgbWF0Y2ggPSBmb2xkUmUuZXhlYyhsaW5lKTtcbiAgfVxuXG4gIGlmIChyZXN1bHQpIHJlc3VsdCArPSAnXFxuJztcblxuICAvLyBpZiB3ZSBlbmQgdXAgd2l0aCBvbmUgbGFzdCB3b3JkIGF0IHRoZSBlbmQsIHRoZW4gdGhlIGxhc3QgYml0IG1pZ2h0XG4gIC8vIGJlIHNsaWdodGx5IGJpZ2dlciB0aGFuIHdlIHdhbnRlZCwgYmVjYXVzZSB3ZSBleGl0ZWQgb3V0IG9mIHRoZSBsb29wLlxuICBpZiAoZm9sZFN0YXJ0ICE9PSBwcmV2TWF0Y2ggJiYgbGluZS5sZW5ndGggLSBmb2xkU3RhcnQgPiBtYXgpIHtcbiAgICByZXN1bHQgKz0gbGluZS5zbGljZShmb2xkU3RhcnQsIHByZXZNYXRjaCkgKyAnXFxuJyArXG4gICAgICAgICAgICAgIGxpbmUuc2xpY2UocHJldk1hdGNoICsgMSk7XG4gIH0gZWxzZSB7XG4gICAgcmVzdWx0ICs9IGxpbmUuc2xpY2UoZm9sZFN0YXJ0KTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8vIFJldHVybnMgdHJ1ZSBpZiBjaGFyYWN0ZXIgY2FuIGJlIGZvdW5kIGluIGEgc2ltcGxlIHNjYWxhclxuZnVuY3Rpb24gc2ltcGxlQ2hhcihjaGFyYWN0ZXIpIHtcbiAgcmV0dXJuIENIQVJfVEFCICAgICAgICAgICAgICAgICAgIT09IGNoYXJhY3RlciAmJlxuICAgICAgICAgQ0hBUl9MSU5FX0ZFRUQgICAgICAgICAgICAhPT0gY2hhcmFjdGVyICYmXG4gICAgICAgICBDSEFSX0NBUlJJQUdFX1JFVFVSTiAgICAgICE9PSBjaGFyYWN0ZXIgJiZcbiAgICAgICAgIENIQVJfQ09NTUEgICAgICAgICAgICAgICAgIT09IGNoYXJhY3RlciAmJlxuICAgICAgICAgQ0hBUl9MRUZUX1NRVUFSRV9CUkFDS0VUICAhPT0gY2hhcmFjdGVyICYmXG4gICAgICAgICBDSEFSX1JJR0hUX1NRVUFSRV9CUkFDS0VUICE9PSBjaGFyYWN0ZXIgJiZcbiAgICAgICAgIENIQVJfTEVGVF9DVVJMWV9CUkFDS0VUICAgIT09IGNoYXJhY3RlciAmJlxuICAgICAgICAgQ0hBUl9SSUdIVF9DVVJMWV9CUkFDS0VUICAhPT0gY2hhcmFjdGVyICYmXG4gICAgICAgICBDSEFSX1NIQVJQICAgICAgICAgICAgICAgICE9PSBjaGFyYWN0ZXIgJiZcbiAgICAgICAgIENIQVJfQU1QRVJTQU5EICAgICAgICAgICAgIT09IGNoYXJhY3RlciAmJlxuICAgICAgICAgQ0hBUl9BU1RFUklTSyAgICAgICAgICAgICAhPT0gY2hhcmFjdGVyICYmXG4gICAgICAgICBDSEFSX0VYQ0xBTUFUSU9OICAgICAgICAgICE9PSBjaGFyYWN0ZXIgJiZcbiAgICAgICAgIENIQVJfVkVSVElDQUxfTElORSAgICAgICAgIT09IGNoYXJhY3RlciAmJlxuICAgICAgICAgQ0hBUl9HUkVBVEVSX1RIQU4gICAgICAgICAhPT0gY2hhcmFjdGVyICYmXG4gICAgICAgICBDSEFSX1NJTkdMRV9RVU9URSAgICAgICAgICE9PSBjaGFyYWN0ZXIgJiZcbiAgICAgICAgIENIQVJfRE9VQkxFX1FVT1RFICAgICAgICAgIT09IGNoYXJhY3RlciAmJlxuICAgICAgICAgQ0hBUl9QRVJDRU5UICAgICAgICAgICAgICAhPT0gY2hhcmFjdGVyICYmXG4gICAgICAgICBDSEFSX0NPTE9OICAgICAgICAgICAgICAgICE9PSBjaGFyYWN0ZXIgJiZcbiAgICAgICAgICFFU0NBUEVfU0VRVUVOQ0VTW2NoYXJhY3Rlcl0gICAgICAgICAgICAmJlxuICAgICAgICAgIW5lZWRzSGV4RXNjYXBlKGNoYXJhY3Rlcik7XG59XG5cbi8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgY2hhcmFjdGVyIGNvZGUgbmVlZHMgdG8gYmUgZXNjYXBlZC5cbmZ1bmN0aW9uIG5lZWRzSGV4RXNjYXBlKGNoYXJhY3Rlcikge1xuICByZXR1cm4gISgoMHgwMDAyMCA8PSBjaGFyYWN0ZXIgJiYgY2hhcmFjdGVyIDw9IDB4MDAwMDdFKSB8fFxuICAgICAgICAgICAoY2hhcmFjdGVyID09PSAweDAwMDg1KSAgICAgICAgICAgICAgICAgICAgICAgICB8fFxuICAgICAgICAgICAoMHgwMDBBMCA8PSBjaGFyYWN0ZXIgJiYgY2hhcmFjdGVyIDw9IDB4MDBEN0ZGKSB8fFxuICAgICAgICAgICAoMHgwRTAwMCA8PSBjaGFyYWN0ZXIgJiYgY2hhcmFjdGVyIDw9IDB4MDBGRkZEKSB8fFxuICAgICAgICAgICAoMHgxMDAwMCA8PSBjaGFyYWN0ZXIgJiYgY2hhcmFjdGVyIDw9IDB4MTBGRkZGKSk7XG59XG5cbmZ1bmN0aW9uIHdyaXRlRmxvd1NlcXVlbmNlKHN0YXRlLCBsZXZlbCwgb2JqZWN0KSB7XG4gIHZhciBfcmVzdWx0ID0gJycsXG4gICAgICBfdGFnICAgID0gc3RhdGUudGFnLFxuICAgICAgaW5kZXgsXG4gICAgICBsZW5ndGg7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IG9iamVjdC5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgLy8gV3JpdGUgb25seSB2YWxpZCBlbGVtZW50cy5cbiAgICBpZiAod3JpdGVOb2RlKHN0YXRlLCBsZXZlbCwgb2JqZWN0W2luZGV4XSwgZmFsc2UsIGZhbHNlKSkge1xuICAgICAgaWYgKGluZGV4ICE9PSAwKSBfcmVzdWx0ICs9ICcsICc7XG4gICAgICBfcmVzdWx0ICs9IHN0YXRlLmR1bXA7XG4gICAgfVxuICB9XG5cbiAgc3RhdGUudGFnID0gX3RhZztcbiAgc3RhdGUuZHVtcCA9ICdbJyArIF9yZXN1bHQgKyAnXSc7XG59XG5cbmZ1bmN0aW9uIHdyaXRlQmxvY2tTZXF1ZW5jZShzdGF0ZSwgbGV2ZWwsIG9iamVjdCwgY29tcGFjdCkge1xuICB2YXIgX3Jlc3VsdCA9ICcnLFxuICAgICAgX3RhZyAgICA9IHN0YXRlLnRhZyxcbiAgICAgIGluZGV4LFxuICAgICAgbGVuZ3RoO1xuXG4gIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIC8vIFdyaXRlIG9ubHkgdmFsaWQgZWxlbWVudHMuXG4gICAgaWYgKHdyaXRlTm9kZShzdGF0ZSwgbGV2ZWwgKyAxLCBvYmplY3RbaW5kZXhdLCB0cnVlLCB0cnVlKSkge1xuICAgICAgaWYgKCFjb21wYWN0IHx8IGluZGV4ICE9PSAwKSB7XG4gICAgICAgIF9yZXN1bHQgKz0gZ2VuZXJhdGVOZXh0TGluZShzdGF0ZSwgbGV2ZWwpO1xuICAgICAgfVxuICAgICAgX3Jlc3VsdCArPSAnLSAnICsgc3RhdGUuZHVtcDtcbiAgICB9XG4gIH1cblxuICBzdGF0ZS50YWcgPSBfdGFnO1xuICBzdGF0ZS5kdW1wID0gX3Jlc3VsdCB8fCAnW10nOyAvLyBFbXB0eSBzZXF1ZW5jZSBpZiBubyB2YWxpZCB2YWx1ZXMuXG59XG5cbmZ1bmN0aW9uIHdyaXRlRmxvd01hcHBpbmcoc3RhdGUsIGxldmVsLCBvYmplY3QpIHtcbiAgdmFyIF9yZXN1bHQgICAgICAgPSAnJyxcbiAgICAgIF90YWcgICAgICAgICAgPSBzdGF0ZS50YWcsXG4gICAgICBvYmplY3RLZXlMaXN0ID0gT2JqZWN0LmtleXMob2JqZWN0KSxcbiAgICAgIGluZGV4LFxuICAgICAgbGVuZ3RoLFxuICAgICAgb2JqZWN0S2V5LFxuICAgICAgb2JqZWN0VmFsdWUsXG4gICAgICBwYWlyQnVmZmVyO1xuXG4gIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3RLZXlMaXN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICBwYWlyQnVmZmVyID0gJyc7XG5cbiAgICBpZiAoaW5kZXggIT09IDApIHBhaXJCdWZmZXIgKz0gJywgJztcblxuICAgIG9iamVjdEtleSA9IG9iamVjdEtleUxpc3RbaW5kZXhdO1xuICAgIG9iamVjdFZhbHVlID0gb2JqZWN0W29iamVjdEtleV07XG5cbiAgICBpZiAoIXdyaXRlTm9kZShzdGF0ZSwgbGV2ZWwsIG9iamVjdEtleSwgZmFsc2UsIGZhbHNlKSkge1xuICAgICAgY29udGludWU7IC8vIFNraXAgdGhpcyBwYWlyIGJlY2F1c2Ugb2YgaW52YWxpZCBrZXk7XG4gICAgfVxuXG4gICAgaWYgKHN0YXRlLmR1bXAubGVuZ3RoID4gMTAyNCkgcGFpckJ1ZmZlciArPSAnPyAnO1xuXG4gICAgcGFpckJ1ZmZlciArPSBzdGF0ZS5kdW1wICsgJzogJztcblxuICAgIGlmICghd3JpdGVOb2RlKHN0YXRlLCBsZXZlbCwgb2JqZWN0VmFsdWUsIGZhbHNlLCBmYWxzZSkpIHtcbiAgICAgIGNvbnRpbnVlOyAvLyBTa2lwIHRoaXMgcGFpciBiZWNhdXNlIG9mIGludmFsaWQgdmFsdWUuXG4gICAgfVxuXG4gICAgcGFpckJ1ZmZlciArPSBzdGF0ZS5kdW1wO1xuXG4gICAgLy8gQm90aCBrZXkgYW5kIHZhbHVlIGFyZSB2YWxpZC5cbiAgICBfcmVzdWx0ICs9IHBhaXJCdWZmZXI7XG4gIH1cblxuICBzdGF0ZS50YWcgPSBfdGFnO1xuICBzdGF0ZS5kdW1wID0gJ3snICsgX3Jlc3VsdCArICd9Jztcbn1cblxuZnVuY3Rpb24gd3JpdGVCbG9ja01hcHBpbmcoc3RhdGUsIGxldmVsLCBvYmplY3QsIGNvbXBhY3QpIHtcbiAgdmFyIF9yZXN1bHQgICAgICAgPSAnJyxcbiAgICAgIF90YWcgICAgICAgICAgPSBzdGF0ZS50YWcsXG4gICAgICBvYmplY3RLZXlMaXN0ID0gT2JqZWN0LmtleXMob2JqZWN0KSxcbiAgICAgIGluZGV4LFxuICAgICAgbGVuZ3RoLFxuICAgICAgb2JqZWN0S2V5LFxuICAgICAgb2JqZWN0VmFsdWUsXG4gICAgICBleHBsaWNpdFBhaXIsXG4gICAgICBwYWlyQnVmZmVyO1xuXG4gIC8vIEFsbG93IHNvcnRpbmcga2V5cyBzbyB0aGF0IHRoZSBvdXRwdXQgZmlsZSBpcyBkZXRlcm1pbmlzdGljXG4gIGlmIChzdGF0ZS5zb3J0S2V5cyA9PT0gdHJ1ZSkge1xuICAgIC8vIERlZmF1bHQgc29ydGluZ1xuICAgIG9iamVjdEtleUxpc3Quc29ydCgpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBzdGF0ZS5zb3J0S2V5cyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIC8vIEN1c3RvbSBzb3J0IGZ1bmN0aW9uXG4gICAgb2JqZWN0S2V5TGlzdC5zb3J0KHN0YXRlLnNvcnRLZXlzKTtcbiAgfSBlbHNlIGlmIChzdGF0ZS5zb3J0S2V5cykge1xuICAgIC8vIFNvbWV0aGluZyBpcyB3cm9uZ1xuICAgIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdzb3J0S2V5cyBtdXN0IGJlIGEgYm9vbGVhbiBvciBhIGZ1bmN0aW9uJyk7XG4gIH1cblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gb2JqZWN0S2V5TGlzdC5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgcGFpckJ1ZmZlciA9ICcnO1xuXG4gICAgaWYgKCFjb21wYWN0IHx8IGluZGV4ICE9PSAwKSB7XG4gICAgICBwYWlyQnVmZmVyICs9IGdlbmVyYXRlTmV4dExpbmUoc3RhdGUsIGxldmVsKTtcbiAgICB9XG5cbiAgICBvYmplY3RLZXkgPSBvYmplY3RLZXlMaXN0W2luZGV4XTtcbiAgICBvYmplY3RWYWx1ZSA9IG9iamVjdFtvYmplY3RLZXldO1xuXG4gICAgaWYgKCF3cml0ZU5vZGUoc3RhdGUsIGxldmVsICsgMSwgb2JqZWN0S2V5LCB0cnVlLCB0cnVlLCB0cnVlKSkge1xuICAgICAgY29udGludWU7IC8vIFNraXAgdGhpcyBwYWlyIGJlY2F1c2Ugb2YgaW52YWxpZCBrZXkuXG4gICAgfVxuXG4gICAgZXhwbGljaXRQYWlyID0gKHN0YXRlLnRhZyAhPT0gbnVsbCAmJiBzdGF0ZS50YWcgIT09ICc/JykgfHxcbiAgICAgICAgICAgICAgICAgICAoc3RhdGUuZHVtcCAmJiBzdGF0ZS5kdW1wLmxlbmd0aCA+IDEwMjQpO1xuXG4gICAgaWYgKGV4cGxpY2l0UGFpcikge1xuICAgICAgaWYgKHN0YXRlLmR1bXAgJiYgQ0hBUl9MSU5FX0ZFRUQgPT09IHN0YXRlLmR1bXAuY2hhckNvZGVBdCgwKSkge1xuICAgICAgICBwYWlyQnVmZmVyICs9ICc/JztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBhaXJCdWZmZXIgKz0gJz8gJztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBwYWlyQnVmZmVyICs9IHN0YXRlLmR1bXA7XG5cbiAgICBpZiAoZXhwbGljaXRQYWlyKSB7XG4gICAgICBwYWlyQnVmZmVyICs9IGdlbmVyYXRlTmV4dExpbmUoc3RhdGUsIGxldmVsKTtcbiAgICB9XG5cbiAgICBpZiAoIXdyaXRlTm9kZShzdGF0ZSwgbGV2ZWwgKyAxLCBvYmplY3RWYWx1ZSwgdHJ1ZSwgZXhwbGljaXRQYWlyKSkge1xuICAgICAgY29udGludWU7IC8vIFNraXAgdGhpcyBwYWlyIGJlY2F1c2Ugb2YgaW52YWxpZCB2YWx1ZS5cbiAgICB9XG5cbiAgICBpZiAoc3RhdGUuZHVtcCAmJiBDSEFSX0xJTkVfRkVFRCA9PT0gc3RhdGUuZHVtcC5jaGFyQ29kZUF0KDApKSB7XG4gICAgICBwYWlyQnVmZmVyICs9ICc6JztcbiAgICB9IGVsc2Uge1xuICAgICAgcGFpckJ1ZmZlciArPSAnOiAnO1xuICAgIH1cblxuICAgIHBhaXJCdWZmZXIgKz0gc3RhdGUuZHVtcDtcblxuICAgIC8vIEJvdGgga2V5IGFuZCB2YWx1ZSBhcmUgdmFsaWQuXG4gICAgX3Jlc3VsdCArPSBwYWlyQnVmZmVyO1xuICB9XG5cbiAgc3RhdGUudGFnID0gX3RhZztcbiAgc3RhdGUuZHVtcCA9IF9yZXN1bHQgfHwgJ3t9JzsgLy8gRW1wdHkgbWFwcGluZyBpZiBubyB2YWxpZCBwYWlycy5cbn1cblxuZnVuY3Rpb24gZGV0ZWN0VHlwZShzdGF0ZSwgb2JqZWN0LCBleHBsaWNpdCkge1xuICB2YXIgX3Jlc3VsdCwgdHlwZUxpc3QsIGluZGV4LCBsZW5ndGgsIHR5cGUsIHN0eWxlO1xuXG4gIHR5cGVMaXN0ID0gZXhwbGljaXQgPyBzdGF0ZS5leHBsaWNpdFR5cGVzIDogc3RhdGUuaW1wbGljaXRUeXBlcztcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gdHlwZUxpc3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIHR5cGUgPSB0eXBlTGlzdFtpbmRleF07XG5cbiAgICBpZiAoKHR5cGUuaW5zdGFuY2VPZiAgfHwgdHlwZS5wcmVkaWNhdGUpICYmXG4gICAgICAgICghdHlwZS5pbnN0YW5jZU9mIHx8ICgodHlwZW9mIG9iamVjdCA9PT0gJ29iamVjdCcpICYmIChvYmplY3QgaW5zdGFuY2VvZiB0eXBlLmluc3RhbmNlT2YpKSkgJiZcbiAgICAgICAgKCF0eXBlLnByZWRpY2F0ZSAgfHwgdHlwZS5wcmVkaWNhdGUob2JqZWN0KSkpIHtcblxuICAgICAgc3RhdGUudGFnID0gZXhwbGljaXQgPyB0eXBlLnRhZyA6ICc/JztcblxuICAgICAgaWYgKHR5cGUucmVwcmVzZW50KSB7XG4gICAgICAgIHN0eWxlID0gc3RhdGUuc3R5bGVNYXBbdHlwZS50YWddIHx8IHR5cGUuZGVmYXVsdFN0eWxlO1xuXG4gICAgICAgIGlmIChfdG9TdHJpbmcuY2FsbCh0eXBlLnJlcHJlc2VudCkgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXScpIHtcbiAgICAgICAgICBfcmVzdWx0ID0gdHlwZS5yZXByZXNlbnQob2JqZWN0LCBzdHlsZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoX2hhc093blByb3BlcnR5LmNhbGwodHlwZS5yZXByZXNlbnQsIHN0eWxlKSkge1xuICAgICAgICAgIF9yZXN1bHQgPSB0eXBlLnJlcHJlc2VudFtzdHlsZV0ob2JqZWN0LCBzdHlsZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJyE8JyArIHR5cGUudGFnICsgJz4gdGFnIHJlc29sdmVyIGFjY2VwdHMgbm90IFwiJyArIHN0eWxlICsgJ1wiIHN0eWxlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBzdGF0ZS5kdW1wID0gX3Jlc3VsdDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vLyBTZXJpYWxpemVzIGBvYmplY3RgIGFuZCB3cml0ZXMgaXQgdG8gZ2xvYmFsIGByZXN1bHRgLlxuLy8gUmV0dXJucyB0cnVlIG9uIHN1Y2Nlc3MsIG9yIGZhbHNlIG9uIGludmFsaWQgb2JqZWN0LlxuLy9cbmZ1bmN0aW9uIHdyaXRlTm9kZShzdGF0ZSwgbGV2ZWwsIG9iamVjdCwgYmxvY2ssIGNvbXBhY3QsIGlza2V5KSB7XG4gIHN0YXRlLnRhZyA9IG51bGw7XG4gIHN0YXRlLmR1bXAgPSBvYmplY3Q7XG5cbiAgaWYgKCFkZXRlY3RUeXBlKHN0YXRlLCBvYmplY3QsIGZhbHNlKSkge1xuICAgIGRldGVjdFR5cGUoc3RhdGUsIG9iamVjdCwgdHJ1ZSk7XG4gIH1cblxuICB2YXIgdHlwZSA9IF90b1N0cmluZy5jYWxsKHN0YXRlLmR1bXApO1xuXG4gIGlmIChibG9jaykge1xuICAgIGJsb2NrID0gKHN0YXRlLmZsb3dMZXZlbCA8IDAgfHwgc3RhdGUuZmxvd0xldmVsID4gbGV2ZWwpO1xuICB9XG5cbiAgdmFyIG9iamVjdE9yQXJyYXkgPSB0eXBlID09PSAnW29iamVjdCBPYmplY3RdJyB8fCB0eXBlID09PSAnW29iamVjdCBBcnJheV0nLFxuICAgICAgZHVwbGljYXRlSW5kZXgsXG4gICAgICBkdXBsaWNhdGU7XG5cbiAgaWYgKG9iamVjdE9yQXJyYXkpIHtcbiAgICBkdXBsaWNhdGVJbmRleCA9IHN0YXRlLmR1cGxpY2F0ZXMuaW5kZXhPZihvYmplY3QpO1xuICAgIGR1cGxpY2F0ZSA9IGR1cGxpY2F0ZUluZGV4ICE9PSAtMTtcbiAgfVxuXG4gIGlmICgoc3RhdGUudGFnICE9PSBudWxsICYmIHN0YXRlLnRhZyAhPT0gJz8nKSB8fCBkdXBsaWNhdGUgfHwgKHN0YXRlLmluZGVudCAhPT0gMiAmJiBsZXZlbCA+IDApKSB7XG4gICAgY29tcGFjdCA9IGZhbHNlO1xuICB9XG5cbiAgaWYgKGR1cGxpY2F0ZSAmJiBzdGF0ZS51c2VkRHVwbGljYXRlc1tkdXBsaWNhdGVJbmRleF0pIHtcbiAgICBzdGF0ZS5kdW1wID0gJypyZWZfJyArIGR1cGxpY2F0ZUluZGV4O1xuICB9IGVsc2Uge1xuICAgIGlmIChvYmplY3RPckFycmF5ICYmIGR1cGxpY2F0ZSAmJiAhc3RhdGUudXNlZER1cGxpY2F0ZXNbZHVwbGljYXRlSW5kZXhdKSB7XG4gICAgICBzdGF0ZS51c2VkRHVwbGljYXRlc1tkdXBsaWNhdGVJbmRleF0gPSB0cnVlO1xuICAgIH1cbiAgICBpZiAodHlwZSA9PT0gJ1tvYmplY3QgT2JqZWN0XScpIHtcbiAgICAgIGlmIChibG9jayAmJiAoT2JqZWN0LmtleXMoc3RhdGUuZHVtcCkubGVuZ3RoICE9PSAwKSkge1xuICAgICAgICB3cml0ZUJsb2NrTWFwcGluZyhzdGF0ZSwgbGV2ZWwsIHN0YXRlLmR1bXAsIGNvbXBhY3QpO1xuICAgICAgICBpZiAoZHVwbGljYXRlKSB7XG4gICAgICAgICAgc3RhdGUuZHVtcCA9ICcmcmVmXycgKyBkdXBsaWNhdGVJbmRleCArIHN0YXRlLmR1bXA7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHdyaXRlRmxvd01hcHBpbmcoc3RhdGUsIGxldmVsLCBzdGF0ZS5kdW1wKTtcbiAgICAgICAgaWYgKGR1cGxpY2F0ZSkge1xuICAgICAgICAgIHN0YXRlLmR1bXAgPSAnJnJlZl8nICsgZHVwbGljYXRlSW5kZXggKyAnICcgKyBzdGF0ZS5kdW1wO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnW29iamVjdCBBcnJheV0nKSB7XG4gICAgICBpZiAoYmxvY2sgJiYgKHN0YXRlLmR1bXAubGVuZ3RoICE9PSAwKSkge1xuICAgICAgICB3cml0ZUJsb2NrU2VxdWVuY2Uoc3RhdGUsIGxldmVsLCBzdGF0ZS5kdW1wLCBjb21wYWN0KTtcbiAgICAgICAgaWYgKGR1cGxpY2F0ZSkge1xuICAgICAgICAgIHN0YXRlLmR1bXAgPSAnJnJlZl8nICsgZHVwbGljYXRlSW5kZXggKyBzdGF0ZS5kdW1wO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB3cml0ZUZsb3dTZXF1ZW5jZShzdGF0ZSwgbGV2ZWwsIHN0YXRlLmR1bXApO1xuICAgICAgICBpZiAoZHVwbGljYXRlKSB7XG4gICAgICAgICAgc3RhdGUuZHVtcCA9ICcmcmVmXycgKyBkdXBsaWNhdGVJbmRleCArICcgJyArIHN0YXRlLmR1bXA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdbb2JqZWN0IFN0cmluZ10nKSB7XG4gICAgICBpZiAoc3RhdGUudGFnICE9PSAnPycpIHtcbiAgICAgICAgd3JpdGVTY2FsYXIoc3RhdGUsIHN0YXRlLmR1bXAsIGxldmVsLCBpc2tleSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChzdGF0ZS5za2lwSW52YWxpZCkgcmV0dXJuIGZhbHNlO1xuICAgICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ3VuYWNjZXB0YWJsZSBraW5kIG9mIGFuIG9iamVjdCB0byBkdW1wICcgKyB0eXBlKTtcbiAgICB9XG5cbiAgICBpZiAoc3RhdGUudGFnICE9PSBudWxsICYmIHN0YXRlLnRhZyAhPT0gJz8nKSB7XG4gICAgICBzdGF0ZS5kdW1wID0gJyE8JyArIHN0YXRlLnRhZyArICc+ICcgKyBzdGF0ZS5kdW1wO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBnZXREdXBsaWNhdGVSZWZlcmVuY2VzKG9iamVjdCwgc3RhdGUpIHtcbiAgdmFyIG9iamVjdHMgPSBbXSxcbiAgICAgIGR1cGxpY2F0ZXNJbmRleGVzID0gW10sXG4gICAgICBpbmRleCxcbiAgICAgIGxlbmd0aDtcblxuICBpbnNwZWN0Tm9kZShvYmplY3QsIG9iamVjdHMsIGR1cGxpY2F0ZXNJbmRleGVzKTtcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gZHVwbGljYXRlc0luZGV4ZXMubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIHN0YXRlLmR1cGxpY2F0ZXMucHVzaChvYmplY3RzW2R1cGxpY2F0ZXNJbmRleGVzW2luZGV4XV0pO1xuICB9XG4gIHN0YXRlLnVzZWREdXBsaWNhdGVzID0gbmV3IEFycmF5KGxlbmd0aCk7XG59XG5cbmZ1bmN0aW9uIGluc3BlY3ROb2RlKG9iamVjdCwgb2JqZWN0cywgZHVwbGljYXRlc0luZGV4ZXMpIHtcbiAgdmFyIG9iamVjdEtleUxpc3QsXG4gICAgICBpbmRleCxcbiAgICAgIGxlbmd0aDtcblxuICBpZiAob2JqZWN0ICE9PSBudWxsICYmIHR5cGVvZiBvYmplY3QgPT09ICdvYmplY3QnKSB7XG4gICAgaW5kZXggPSBvYmplY3RzLmluZGV4T2Yob2JqZWN0KTtcbiAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICBpZiAoZHVwbGljYXRlc0luZGV4ZXMuaW5kZXhPZihpbmRleCkgPT09IC0xKSB7XG4gICAgICAgIGR1cGxpY2F0ZXNJbmRleGVzLnB1c2goaW5kZXgpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBvYmplY3RzLnB1c2gob2JqZWN0KTtcblxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkob2JqZWN0KSkge1xuICAgICAgICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gb2JqZWN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICAgICAgICBpbnNwZWN0Tm9kZShvYmplY3RbaW5kZXhdLCBvYmplY3RzLCBkdXBsaWNhdGVzSW5kZXhlcyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9iamVjdEtleUxpc3QgPSBPYmplY3Qua2V5cyhvYmplY3QpO1xuXG4gICAgICAgIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3RLZXlMaXN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICAgICAgICBpbnNwZWN0Tm9kZShvYmplY3Rbb2JqZWN0S2V5TGlzdFtpbmRleF1dLCBvYmplY3RzLCBkdXBsaWNhdGVzSW5kZXhlcyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZHVtcChpbnB1dCwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgc3RhdGUgPSBuZXcgU3RhdGUob3B0aW9ucyk7XG5cbiAgaWYgKCFzdGF0ZS5ub1JlZnMpIGdldER1cGxpY2F0ZVJlZmVyZW5jZXMoaW5wdXQsIHN0YXRlKTtcblxuICBpZiAod3JpdGVOb2RlKHN0YXRlLCAwLCBpbnB1dCwgdHJ1ZSwgdHJ1ZSkpIHJldHVybiBzdGF0ZS5kdW1wICsgJ1xcbic7XG5cbiAgcmV0dXJuICcnO1xufVxuXG5mdW5jdGlvbiBzYWZlRHVtcChpbnB1dCwgb3B0aW9ucykge1xuICByZXR1cm4gZHVtcChpbnB1dCwgY29tbW9uLmV4dGVuZCh7IHNjaGVtYTogREVGQVVMVF9TQUZFX1NDSEVNQSB9LCBvcHRpb25zKSk7XG59XG5cbm1vZHVsZS5leHBvcnRzLmR1bXAgICAgID0gZHVtcDtcbm1vZHVsZS5leHBvcnRzLnNhZmVEdW1wID0gc2FmZUR1bXA7XG4iLCIvLyBZQU1MIGVycm9yIGNsYXNzLiBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzg0NTg5ODRcbi8vXG4ndXNlIHN0cmljdCc7XG5cbmZ1bmN0aW9uIFlBTUxFeGNlcHRpb24ocmVhc29uLCBtYXJrKSB7XG4gIC8vIFN1cGVyIGNvbnN0cnVjdG9yXG4gIEVycm9yLmNhbGwodGhpcyk7XG5cbiAgLy8gSW5jbHVkZSBzdGFjayB0cmFjZSBpbiBlcnJvciBvYmplY3RcbiAgaWYgKEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKSB7XG4gICAgLy8gQ2hyb21lIGFuZCBOb2RlSlNcbiAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCB0aGlzLmNvbnN0cnVjdG9yKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBGRiwgSUUgMTArIGFuZCBTYWZhcmkgNisuIEZhbGxiYWNrIGZvciBvdGhlcnNcbiAgICB0aGlzLnN0YWNrID0gKG5ldyBFcnJvcigpKS5zdGFjayB8fCAnJztcbiAgfVxuXG4gIHRoaXMubmFtZSA9ICdZQU1MRXhjZXB0aW9uJztcbiAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gIHRoaXMubWFyayA9IG1hcms7XG4gIHRoaXMubWVzc2FnZSA9ICh0aGlzLnJlYXNvbiB8fCAnKHVua25vd24gcmVhc29uKScpICsgKHRoaXMubWFyayA/ICcgJyArIHRoaXMubWFyay50b1N0cmluZygpIDogJycpO1xufVxuXG5cbi8vIEluaGVyaXQgZnJvbSBFcnJvclxuWUFNTEV4Y2VwdGlvbi5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEVycm9yLnByb3RvdHlwZSk7XG5ZQU1MRXhjZXB0aW9uLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFlBTUxFeGNlcHRpb247XG5cblxuWUFNTEV4Y2VwdGlvbi5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZyhjb21wYWN0KSB7XG4gIHZhciByZXN1bHQgPSB0aGlzLm5hbWUgKyAnOiAnO1xuXG4gIHJlc3VsdCArPSB0aGlzLnJlYXNvbiB8fCAnKHVua25vd24gcmVhc29uKSc7XG5cbiAgaWYgKCFjb21wYWN0ICYmIHRoaXMubWFyaykge1xuICAgIHJlc3VsdCArPSAnICcgKyB0aGlzLm1hcmsudG9TdHJpbmcoKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gWUFNTEV4Y2VwdGlvbjtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyplc2xpbnQtZGlzYWJsZSBtYXgtbGVuLG5vLXVzZS1iZWZvcmUtZGVmaW5lKi9cblxudmFyIGNvbW1vbiAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIFlBTUxFeGNlcHRpb24gICAgICAgPSByZXF1aXJlKCcuL2V4Y2VwdGlvbicpO1xudmFyIE1hcmsgICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL21hcmsnKTtcbnZhciBERUZBVUxUX1NBRkVfU0NIRU1BID0gcmVxdWlyZSgnLi9zY2hlbWEvZGVmYXVsdF9zYWZlJyk7XG52YXIgREVGQVVMVF9GVUxMX1NDSEVNQSA9IHJlcXVpcmUoJy4vc2NoZW1hL2RlZmF1bHRfZnVsbCcpO1xuXG5cbnZhciBfaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG5cbnZhciBDT05URVhUX0ZMT1dfSU4gICA9IDE7XG52YXIgQ09OVEVYVF9GTE9XX09VVCAgPSAyO1xudmFyIENPTlRFWFRfQkxPQ0tfSU4gID0gMztcbnZhciBDT05URVhUX0JMT0NLX09VVCA9IDQ7XG5cblxudmFyIENIT01QSU5HX0NMSVAgID0gMTtcbnZhciBDSE9NUElOR19TVFJJUCA9IDI7XG52YXIgQ0hPTVBJTkdfS0VFUCAgPSAzO1xuXG5cbnZhciBQQVRURVJOX05PTl9QUklOVEFCTEUgICAgICAgICA9IC9bXFx4MDAtXFx4MDhcXHgwQlxceDBDXFx4MEUtXFx4MUZcXHg3Ri1cXHg4NFxceDg2LVxceDlGXFx1RkZGRVxcdUZGRkZdfFtcXHVEODAwLVxcdURCRkZdKD8hW1xcdURDMDAtXFx1REZGRl0pfCg/OlteXFx1RDgwMC1cXHVEQkZGXXxeKVtcXHVEQzAwLVxcdURGRkZdLztcbnZhciBQQVRURVJOX05PTl9BU0NJSV9MSU5FX0JSRUFLUyA9IC9bXFx4ODVcXHUyMDI4XFx1MjAyOV0vO1xudmFyIFBBVFRFUk5fRkxPV19JTkRJQ0FUT1JTICAgICAgID0gL1ssXFxbXFxdXFx7XFx9XS87XG52YXIgUEFUVEVSTl9UQUdfSEFORExFICAgICAgICAgICAgPSAvXig/OiF8ISF8IVthLXpcXC1dKyEpJC9pO1xudmFyIFBBVFRFUk5fVEFHX1VSSSAgICAgICAgICAgICAgID0gL14oPzohfFteLFxcW1xcXVxce1xcfV0pKD86JVswLTlhLWZdezJ9fFswLTlhLXpcXC0jO1xcL1xcPzpAJj1cXCtcXCQsX1xcLiF+XFwqJ1xcKFxcKVxcW1xcXV0pKiQvaTtcblxuXG5mdW5jdGlvbiBpc19FT0woYykge1xuICByZXR1cm4gKGMgPT09IDB4MEEvKiBMRiAqLykgfHwgKGMgPT09IDB4MEQvKiBDUiAqLyk7XG59XG5cbmZ1bmN0aW9uIGlzX1dISVRFX1NQQUNFKGMpIHtcbiAgcmV0dXJuIChjID09PSAweDA5LyogVGFiICovKSB8fCAoYyA9PT0gMHgyMC8qIFNwYWNlICovKTtcbn1cblxuZnVuY3Rpb24gaXNfV1NfT1JfRU9MKGMpIHtcbiAgcmV0dXJuIChjID09PSAweDA5LyogVGFiICovKSB8fFxuICAgICAgICAgKGMgPT09IDB4MjAvKiBTcGFjZSAqLykgfHxcbiAgICAgICAgIChjID09PSAweDBBLyogTEYgKi8pIHx8XG4gICAgICAgICAoYyA9PT0gMHgwRC8qIENSICovKTtcbn1cblxuZnVuY3Rpb24gaXNfRkxPV19JTkRJQ0FUT1IoYykge1xuICByZXR1cm4gYyA9PT0gMHgyQy8qICwgKi8gfHxcbiAgICAgICAgIGMgPT09IDB4NUIvKiBbICovIHx8XG4gICAgICAgICBjID09PSAweDVELyogXSAqLyB8fFxuICAgICAgICAgYyA9PT0gMHg3Qi8qIHsgKi8gfHxcbiAgICAgICAgIGMgPT09IDB4N0QvKiB9ICovO1xufVxuXG5mdW5jdGlvbiBmcm9tSGV4Q29kZShjKSB7XG4gIHZhciBsYztcblxuICBpZiAoKDB4MzAvKiAwICovIDw9IGMpICYmIChjIDw9IDB4MzkvKiA5ICovKSkge1xuICAgIHJldHVybiBjIC0gMHgzMDtcbiAgfVxuXG4gIC8qZXNsaW50LWRpc2FibGUgbm8tYml0d2lzZSovXG4gIGxjID0gYyB8IDB4MjA7XG5cbiAgaWYgKCgweDYxLyogYSAqLyA8PSBsYykgJiYgKGxjIDw9IDB4NjYvKiBmICovKSkge1xuICAgIHJldHVybiBsYyAtIDB4NjEgKyAxMDtcbiAgfVxuXG4gIHJldHVybiAtMTtcbn1cblxuZnVuY3Rpb24gZXNjYXBlZEhleExlbihjKSB7XG4gIGlmIChjID09PSAweDc4LyogeCAqLykgeyByZXR1cm4gMjsgfVxuICBpZiAoYyA9PT0gMHg3NS8qIHUgKi8pIHsgcmV0dXJuIDQ7IH1cbiAgaWYgKGMgPT09IDB4NTUvKiBVICovKSB7IHJldHVybiA4OyB9XG4gIHJldHVybiAwO1xufVxuXG5mdW5jdGlvbiBmcm9tRGVjaW1hbENvZGUoYykge1xuICBpZiAoKDB4MzAvKiAwICovIDw9IGMpICYmIChjIDw9IDB4MzkvKiA5ICovKSkge1xuICAgIHJldHVybiBjIC0gMHgzMDtcbiAgfVxuXG4gIHJldHVybiAtMTtcbn1cblxuZnVuY3Rpb24gc2ltcGxlRXNjYXBlU2VxdWVuY2UoYykge1xuICByZXR1cm4gKGMgPT09IDB4MzAvKiAwICovKSA/ICdcXHgwMCcgOlxuICAgICAgICAoYyA9PT0gMHg2MS8qIGEgKi8pID8gJ1xceDA3JyA6XG4gICAgICAgIChjID09PSAweDYyLyogYiAqLykgPyAnXFx4MDgnIDpcbiAgICAgICAgKGMgPT09IDB4NzQvKiB0ICovKSA/ICdcXHgwOScgOlxuICAgICAgICAoYyA9PT0gMHgwOS8qIFRhYiAqLykgPyAnXFx4MDknIDpcbiAgICAgICAgKGMgPT09IDB4NkUvKiBuICovKSA/ICdcXHgwQScgOlxuICAgICAgICAoYyA9PT0gMHg3Ni8qIHYgKi8pID8gJ1xceDBCJyA6XG4gICAgICAgIChjID09PSAweDY2LyogZiAqLykgPyAnXFx4MEMnIDpcbiAgICAgICAgKGMgPT09IDB4NzIvKiByICovKSA/ICdcXHgwRCcgOlxuICAgICAgICAoYyA9PT0gMHg2NS8qIGUgKi8pID8gJ1xceDFCJyA6XG4gICAgICAgIChjID09PSAweDIwLyogU3BhY2UgKi8pID8gJyAnIDpcbiAgICAgICAgKGMgPT09IDB4MjIvKiBcIiAqLykgPyAnXFx4MjInIDpcbiAgICAgICAgKGMgPT09IDB4MkYvKiAvICovKSA/ICcvJyA6XG4gICAgICAgIChjID09PSAweDVDLyogXFwgKi8pID8gJ1xceDVDJyA6XG4gICAgICAgIChjID09PSAweDRFLyogTiAqLykgPyAnXFx4ODUnIDpcbiAgICAgICAgKGMgPT09IDB4NUYvKiBfICovKSA/ICdcXHhBMCcgOlxuICAgICAgICAoYyA9PT0gMHg0Qy8qIEwgKi8pID8gJ1xcdTIwMjgnIDpcbiAgICAgICAgKGMgPT09IDB4NTAvKiBQICovKSA/ICdcXHUyMDI5JyA6ICcnO1xufVxuXG5mdW5jdGlvbiBjaGFyRnJvbUNvZGVwb2ludChjKSB7XG4gIGlmIChjIDw9IDB4RkZGRikge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKGMpO1xuICB9XG4gIC8vIEVuY29kZSBVVEYtMTYgc3Vycm9nYXRlIHBhaXJcbiAgLy8gaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvVVRGLTE2I0NvZGVfcG9pbnRzX1UuMkIwMTAwMDBfdG9fVS4yQjEwRkZGRlxuICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZSgoKGMgLSAweDAxMDAwMCkgPj4gMTApICsgMHhEODAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKGMgLSAweDAxMDAwMCkgJiAweDAzRkYpICsgMHhEQzAwKTtcbn1cblxudmFyIHNpbXBsZUVzY2FwZUNoZWNrID0gbmV3IEFycmF5KDI1Nik7IC8vIGludGVnZXIsIGZvciBmYXN0IGFjY2Vzc1xudmFyIHNpbXBsZUVzY2FwZU1hcCA9IG5ldyBBcnJheSgyNTYpO1xuZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7IGkrKykge1xuICBzaW1wbGVFc2NhcGVDaGVja1tpXSA9IHNpbXBsZUVzY2FwZVNlcXVlbmNlKGkpID8gMSA6IDA7XG4gIHNpbXBsZUVzY2FwZU1hcFtpXSA9IHNpbXBsZUVzY2FwZVNlcXVlbmNlKGkpO1xufVxuXG5cbmZ1bmN0aW9uIFN0YXRlKGlucHV0LCBvcHRpb25zKSB7XG4gIHRoaXMuaW5wdXQgPSBpbnB1dDtcblxuICB0aGlzLmZpbGVuYW1lICA9IG9wdGlvbnNbJ2ZpbGVuYW1lJ10gIHx8IG51bGw7XG4gIHRoaXMuc2NoZW1hICAgID0gb3B0aW9uc1snc2NoZW1hJ10gICAgfHwgREVGQVVMVF9GVUxMX1NDSEVNQTtcbiAgdGhpcy5vbldhcm5pbmcgPSBvcHRpb25zWydvbldhcm5pbmcnXSB8fCBudWxsO1xuICB0aGlzLmxlZ2FjeSAgICA9IG9wdGlvbnNbJ2xlZ2FjeSddICAgIHx8IGZhbHNlO1xuICB0aGlzLmpzb24gICAgICA9IG9wdGlvbnNbJ2pzb24nXSAgICAgIHx8IGZhbHNlO1xuICB0aGlzLmxpc3RlbmVyICA9IG9wdGlvbnNbJ2xpc3RlbmVyJ10gIHx8IG51bGw7XG5cbiAgdGhpcy5pbXBsaWNpdFR5cGVzID0gdGhpcy5zY2hlbWEuY29tcGlsZWRJbXBsaWNpdDtcbiAgdGhpcy50eXBlTWFwICAgICAgID0gdGhpcy5zY2hlbWEuY29tcGlsZWRUeXBlTWFwO1xuXG4gIHRoaXMubGVuZ3RoICAgICA9IGlucHV0Lmxlbmd0aDtcbiAgdGhpcy5wb3NpdGlvbiAgID0gMDtcbiAgdGhpcy5saW5lICAgICAgID0gMDtcbiAgdGhpcy5saW5lU3RhcnQgID0gMDtcbiAgdGhpcy5saW5lSW5kZW50ID0gMDtcblxuICB0aGlzLmRvY3VtZW50cyA9IFtdO1xuXG4gIC8qXG4gIHRoaXMudmVyc2lvbjtcbiAgdGhpcy5jaGVja0xpbmVCcmVha3M7XG4gIHRoaXMudGFnTWFwO1xuICB0aGlzLmFuY2hvck1hcDtcbiAgdGhpcy50YWc7XG4gIHRoaXMuYW5jaG9yO1xuICB0aGlzLmtpbmQ7XG4gIHRoaXMucmVzdWx0OyovXG5cbn1cblxuXG5mdW5jdGlvbiBnZW5lcmF0ZUVycm9yKHN0YXRlLCBtZXNzYWdlKSB7XG4gIHJldHVybiBuZXcgWUFNTEV4Y2VwdGlvbihcbiAgICBtZXNzYWdlLFxuICAgIG5ldyBNYXJrKHN0YXRlLmZpbGVuYW1lLCBzdGF0ZS5pbnB1dCwgc3RhdGUucG9zaXRpb24sIHN0YXRlLmxpbmUsIChzdGF0ZS5wb3NpdGlvbiAtIHN0YXRlLmxpbmVTdGFydCkpKTtcbn1cblxuZnVuY3Rpb24gdGhyb3dFcnJvcihzdGF0ZSwgbWVzc2FnZSkge1xuICB0aHJvdyBnZW5lcmF0ZUVycm9yKHN0YXRlLCBtZXNzYWdlKTtcbn1cblxuZnVuY3Rpb24gdGhyb3dXYXJuaW5nKHN0YXRlLCBtZXNzYWdlKSB7XG4gIGlmIChzdGF0ZS5vbldhcm5pbmcpIHtcbiAgICBzdGF0ZS5vbldhcm5pbmcuY2FsbChudWxsLCBnZW5lcmF0ZUVycm9yKHN0YXRlLCBtZXNzYWdlKSk7XG4gIH1cbn1cblxuXG52YXIgZGlyZWN0aXZlSGFuZGxlcnMgPSB7XG5cbiAgWUFNTDogZnVuY3Rpb24gaGFuZGxlWWFtbERpcmVjdGl2ZShzdGF0ZSwgbmFtZSwgYXJncykge1xuXG4gICAgdmFyIG1hdGNoLCBtYWpvciwgbWlub3I7XG5cbiAgICBpZiAoc3RhdGUudmVyc2lvbiAhPT0gbnVsbCkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2R1cGxpY2F0aW9uIG9mICVZQU1MIGRpcmVjdGl2ZScpO1xuICAgIH1cblxuICAgIGlmIChhcmdzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ1lBTUwgZGlyZWN0aXZlIGFjY2VwdHMgZXhhY3RseSBvbmUgYXJndW1lbnQnKTtcbiAgICB9XG5cbiAgICBtYXRjaCA9IC9eKFswLTldKylcXC4oWzAtOV0rKSQvLmV4ZWMoYXJnc1swXSk7XG5cbiAgICBpZiAobWF0Y2ggPT09IG51bGwpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdpbGwtZm9ybWVkIGFyZ3VtZW50IG9mIHRoZSBZQU1MIGRpcmVjdGl2ZScpO1xuICAgIH1cblxuICAgIG1ham9yID0gcGFyc2VJbnQobWF0Y2hbMV0sIDEwKTtcbiAgICBtaW5vciA9IHBhcnNlSW50KG1hdGNoWzJdLCAxMCk7XG5cbiAgICBpZiAobWFqb3IgIT09IDEpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd1bmFjY2VwdGFibGUgWUFNTCB2ZXJzaW9uIG9mIHRoZSBkb2N1bWVudCcpO1xuICAgIH1cblxuICAgIHN0YXRlLnZlcnNpb24gPSBhcmdzWzBdO1xuICAgIHN0YXRlLmNoZWNrTGluZUJyZWFrcyA9IChtaW5vciA8IDIpO1xuXG4gICAgaWYgKG1pbm9yICE9PSAxICYmIG1pbm9yICE9PSAyKSB7XG4gICAgICB0aHJvd1dhcm5pbmcoc3RhdGUsICd1bnN1cHBvcnRlZCBZQU1MIHZlcnNpb24gb2YgdGhlIGRvY3VtZW50Jyk7XG4gICAgfVxuICB9LFxuXG4gIFRBRzogZnVuY3Rpb24gaGFuZGxlVGFnRGlyZWN0aXZlKHN0YXRlLCBuYW1lLCBhcmdzKSB7XG5cbiAgICB2YXIgaGFuZGxlLCBwcmVmaXg7XG5cbiAgICBpZiAoYXJncy5sZW5ndGggIT09IDIpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdUQUcgZGlyZWN0aXZlIGFjY2VwdHMgZXhhY3RseSB0d28gYXJndW1lbnRzJyk7XG4gICAgfVxuXG4gICAgaGFuZGxlID0gYXJnc1swXTtcbiAgICBwcmVmaXggPSBhcmdzWzFdO1xuXG4gICAgaWYgKCFQQVRURVJOX1RBR19IQU5ETEUudGVzdChoYW5kbGUpKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnaWxsLWZvcm1lZCB0YWcgaGFuZGxlIChmaXJzdCBhcmd1bWVudCkgb2YgdGhlIFRBRyBkaXJlY3RpdmUnKTtcbiAgICB9XG5cbiAgICBpZiAoX2hhc093blByb3BlcnR5LmNhbGwoc3RhdGUudGFnTWFwLCBoYW5kbGUpKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndGhlcmUgaXMgYSBwcmV2aW91c2x5IGRlY2xhcmVkIHN1ZmZpeCBmb3IgXCInICsgaGFuZGxlICsgJ1wiIHRhZyBoYW5kbGUnKTtcbiAgICB9XG5cbiAgICBpZiAoIVBBVFRFUk5fVEFHX1VSSS50ZXN0KHByZWZpeCkpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdpbGwtZm9ybWVkIHRhZyBwcmVmaXggKHNlY29uZCBhcmd1bWVudCkgb2YgdGhlIFRBRyBkaXJlY3RpdmUnKTtcbiAgICB9XG5cbiAgICBzdGF0ZS50YWdNYXBbaGFuZGxlXSA9IHByZWZpeDtcbiAgfVxufTtcblxuXG5mdW5jdGlvbiBjYXB0dXJlU2VnbWVudChzdGF0ZSwgc3RhcnQsIGVuZCwgY2hlY2tKc29uKSB7XG4gIHZhciBfcG9zaXRpb24sIF9sZW5ndGgsIF9jaGFyYWN0ZXIsIF9yZXN1bHQ7XG5cbiAgaWYgKHN0YXJ0IDwgZW5kKSB7XG4gICAgX3Jlc3VsdCA9IHN0YXRlLmlucHV0LnNsaWNlKHN0YXJ0LCBlbmQpO1xuXG4gICAgaWYgKGNoZWNrSnNvbikge1xuICAgICAgZm9yIChfcG9zaXRpb24gPSAwLCBfbGVuZ3RoID0gX3Jlc3VsdC5sZW5ndGg7XG4gICAgICAgICAgIF9wb3NpdGlvbiA8IF9sZW5ndGg7XG4gICAgICAgICAgIF9wb3NpdGlvbiArPSAxKSB7XG4gICAgICAgIF9jaGFyYWN0ZXIgPSBfcmVzdWx0LmNoYXJDb2RlQXQoX3Bvc2l0aW9uKTtcbiAgICAgICAgaWYgKCEoX2NoYXJhY3RlciA9PT0gMHgwOSB8fFxuICAgICAgICAgICAgICAoMHgyMCA8PSBfY2hhcmFjdGVyICYmIF9jaGFyYWN0ZXIgPD0gMHgxMEZGRkYpKSkge1xuICAgICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdleHBlY3RlZCB2YWxpZCBKU09OIGNoYXJhY3RlcicpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChQQVRURVJOX05PTl9QUklOVEFCTEUudGVzdChfcmVzdWx0KSkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3RoZSBzdHJlYW0gY29udGFpbnMgbm9uLXByaW50YWJsZSBjaGFyYWN0ZXJzJyk7XG4gICAgfVxuXG4gICAgc3RhdGUucmVzdWx0ICs9IF9yZXN1bHQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gbWVyZ2VNYXBwaW5ncyhzdGF0ZSwgZGVzdGluYXRpb24sIHNvdXJjZSwgb3ZlcnJpZGFibGVLZXlzKSB7XG4gIHZhciBzb3VyY2VLZXlzLCBrZXksIGluZGV4LCBxdWFudGl0eTtcblxuICBpZiAoIWNvbW1vbi5pc09iamVjdChzb3VyY2UpKSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2Nhbm5vdCBtZXJnZSBtYXBwaW5nczsgdGhlIHByb3ZpZGVkIHNvdXJjZSBvYmplY3QgaXMgdW5hY2NlcHRhYmxlJyk7XG4gIH1cblxuICBzb3VyY2VLZXlzID0gT2JqZWN0LmtleXMoc291cmNlKTtcblxuICBmb3IgKGluZGV4ID0gMCwgcXVhbnRpdHkgPSBzb3VyY2VLZXlzLmxlbmd0aDsgaW5kZXggPCBxdWFudGl0eTsgaW5kZXggKz0gMSkge1xuICAgIGtleSA9IHNvdXJjZUtleXNbaW5kZXhdO1xuXG4gICAgaWYgKCFfaGFzT3duUHJvcGVydHkuY2FsbChkZXN0aW5hdGlvbiwga2V5KSkge1xuICAgICAgZGVzdGluYXRpb25ba2V5XSA9IHNvdXJjZVtrZXldO1xuICAgICAgb3ZlcnJpZGFibGVLZXlzW2tleV0gPSB0cnVlO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBzdG9yZU1hcHBpbmdQYWlyKHN0YXRlLCBfcmVzdWx0LCBvdmVycmlkYWJsZUtleXMsIGtleVRhZywga2V5Tm9kZSwgdmFsdWVOb2RlKSB7XG4gIHZhciBpbmRleCwgcXVhbnRpdHk7XG5cbiAga2V5Tm9kZSA9IFN0cmluZyhrZXlOb2RlKTtcblxuICBpZiAoX3Jlc3VsdCA9PT0gbnVsbCkge1xuICAgIF9yZXN1bHQgPSB7fTtcbiAgfVxuXG4gIGlmIChrZXlUYWcgPT09ICd0YWc6eWFtbC5vcmcsMjAwMjptZXJnZScpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZU5vZGUpKSB7XG4gICAgICBmb3IgKGluZGV4ID0gMCwgcXVhbnRpdHkgPSB2YWx1ZU5vZGUubGVuZ3RoOyBpbmRleCA8IHF1YW50aXR5OyBpbmRleCArPSAxKSB7XG4gICAgICAgIG1lcmdlTWFwcGluZ3Moc3RhdGUsIF9yZXN1bHQsIHZhbHVlTm9kZVtpbmRleF0sIG92ZXJyaWRhYmxlS2V5cyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIG1lcmdlTWFwcGluZ3Moc3RhdGUsIF9yZXN1bHQsIHZhbHVlTm9kZSwgb3ZlcnJpZGFibGVLZXlzKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKCFzdGF0ZS5qc29uICYmXG4gICAgICAgICFfaGFzT3duUHJvcGVydHkuY2FsbChvdmVycmlkYWJsZUtleXMsIGtleU5vZGUpICYmXG4gICAgICAgIF9oYXNPd25Qcm9wZXJ0eS5jYWxsKF9yZXN1bHQsIGtleU5vZGUpKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZHVwbGljYXRlZCBtYXBwaW5nIGtleScpO1xuICAgIH1cbiAgICBfcmVzdWx0W2tleU5vZGVdID0gdmFsdWVOb2RlO1xuICAgIGRlbGV0ZSBvdmVycmlkYWJsZUtleXNba2V5Tm9kZV07XG4gIH1cblxuICByZXR1cm4gX3Jlc3VsdDtcbn1cblxuZnVuY3Rpb24gcmVhZExpbmVCcmVhayhzdGF0ZSkge1xuICB2YXIgY2g7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoY2ggPT09IDB4MEEvKiBMRiAqLykge1xuICAgIHN0YXRlLnBvc2l0aW9uKys7XG4gIH0gZWxzZSBpZiAoY2ggPT09IDB4MEQvKiBDUiAqLykge1xuICAgIHN0YXRlLnBvc2l0aW9uKys7XG4gICAgaWYgKHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pID09PSAweDBBLyogTEYgKi8pIHtcbiAgICAgIHN0YXRlLnBvc2l0aW9uKys7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICdhIGxpbmUgYnJlYWsgaXMgZXhwZWN0ZWQnKTtcbiAgfVxuXG4gIHN0YXRlLmxpbmUgKz0gMTtcbiAgc3RhdGUubGluZVN0YXJ0ID0gc3RhdGUucG9zaXRpb247XG59XG5cbmZ1bmN0aW9uIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIGFsbG93Q29tbWVudHMsIGNoZWNrSW5kZW50KSB7XG4gIHZhciBsaW5lQnJlYWtzID0gMCxcbiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgd2hpbGUgKGNoICE9PSAwKSB7XG4gICAgd2hpbGUgKGlzX1dISVRFX1NQQUNFKGNoKSkge1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgIH1cblxuICAgIGlmIChhbGxvd0NvbW1lbnRzICYmIGNoID09PSAweDIzLyogIyAqLykge1xuICAgICAgZG8ge1xuICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgICB9IHdoaWxlIChjaCAhPT0gMHgwQS8qIExGICovICYmIGNoICE9PSAweDBELyogQ1IgKi8gJiYgY2ggIT09IDApO1xuICAgIH1cblxuICAgIGlmIChpc19FT0woY2gpKSB7XG4gICAgICByZWFkTGluZUJyZWFrKHN0YXRlKTtcblxuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcbiAgICAgIGxpbmVCcmVha3MrKztcbiAgICAgIHN0YXRlLmxpbmVJbmRlbnQgPSAwO1xuXG4gICAgICB3aGlsZSAoY2ggPT09IDB4MjAvKiBTcGFjZSAqLykge1xuICAgICAgICBzdGF0ZS5saW5lSW5kZW50Kys7XG4gICAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgaWYgKGNoZWNrSW5kZW50ICE9PSAtMSAmJiBsaW5lQnJlYWtzICE9PSAwICYmIHN0YXRlLmxpbmVJbmRlbnQgPCBjaGVja0luZGVudCkge1xuICAgIHRocm93V2FybmluZyhzdGF0ZSwgJ2RlZmljaWVudCBpbmRlbnRhdGlvbicpO1xuICB9XG5cbiAgcmV0dXJuIGxpbmVCcmVha3M7XG59XG5cbmZ1bmN0aW9uIHRlc3REb2N1bWVudFNlcGFyYXRvcihzdGF0ZSkge1xuICB2YXIgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb24sXG4gICAgICBjaDtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoX3Bvc2l0aW9uKTtcblxuICAvLyBDb25kaXRpb24gc3RhdGUucG9zaXRpb24gPT09IHN0YXRlLmxpbmVTdGFydCBpcyB0ZXN0ZWRcbiAgLy8gaW4gcGFyZW50IG9uIGVhY2ggY2FsbCwgZm9yIGVmZmljaWVuY3kuIE5vIG5lZWRzIHRvIHRlc3QgaGVyZSBhZ2Fpbi5cbiAgaWYgKChjaCA9PT0gMHgyRC8qIC0gKi8gfHwgY2ggPT09IDB4MkUvKiAuICovKSAmJlxuICAgICAgY2ggPT09IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoX3Bvc2l0aW9uICsgMSkgJiZcbiAgICAgIGNoID09PSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KF9wb3NpdGlvbiArIDIpKSB7XG5cbiAgICBfcG9zaXRpb24gKz0gMztcblxuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChfcG9zaXRpb24pO1xuXG4gICAgaWYgKGNoID09PSAwIHx8IGlzX1dTX09SX0VPTChjaCkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gd3JpdGVGb2xkZWRMaW5lcyhzdGF0ZSwgY291bnQpIHtcbiAgaWYgKGNvdW50ID09PSAxKSB7XG4gICAgc3RhdGUucmVzdWx0ICs9ICcgJztcbiAgfSBlbHNlIGlmIChjb3VudCA+IDEpIHtcbiAgICBzdGF0ZS5yZXN1bHQgKz0gY29tbW9uLnJlcGVhdCgnXFxuJywgY291bnQgLSAxKTtcbiAgfVxufVxuXG5cbmZ1bmN0aW9uIHJlYWRQbGFpblNjYWxhcihzdGF0ZSwgbm9kZUluZGVudCwgd2l0aGluRmxvd0NvbGxlY3Rpb24pIHtcbiAgdmFyIHByZWNlZGluZyxcbiAgICAgIGZvbGxvd2luZyxcbiAgICAgIGNhcHR1cmVTdGFydCxcbiAgICAgIGNhcHR1cmVFbmQsXG4gICAgICBoYXNQZW5kaW5nQ29udGVudCxcbiAgICAgIF9saW5lLFxuICAgICAgX2xpbmVTdGFydCxcbiAgICAgIF9saW5lSW5kZW50LFxuICAgICAgX2tpbmQgPSBzdGF0ZS5raW5kLFxuICAgICAgX3Jlc3VsdCA9IHN0YXRlLnJlc3VsdCxcbiAgICAgIGNoO1xuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgaWYgKGlzX1dTX09SX0VPTChjaCkgICAgICB8fFxuICAgICAgaXNfRkxPV19JTkRJQ0FUT1IoY2gpIHx8XG4gICAgICBjaCA9PT0gMHgyMy8qICMgKi8gICAgfHxcbiAgICAgIGNoID09PSAweDI2LyogJiAqLyAgICB8fFxuICAgICAgY2ggPT09IDB4MkEvKiAqICovICAgIHx8XG4gICAgICBjaCA9PT0gMHgyMS8qICEgKi8gICAgfHxcbiAgICAgIGNoID09PSAweDdDLyogfCAqLyAgICB8fFxuICAgICAgY2ggPT09IDB4M0UvKiA+ICovICAgIHx8XG4gICAgICBjaCA9PT0gMHgyNy8qICcgKi8gICAgfHxcbiAgICAgIGNoID09PSAweDIyLyogXCIgKi8gICAgfHxcbiAgICAgIGNoID09PSAweDI1LyogJSAqLyAgICB8fFxuICAgICAgY2ggPT09IDB4NDAvKiBAICovICAgIHx8XG4gICAgICBjaCA9PT0gMHg2MC8qIGAgKi8pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAoY2ggPT09IDB4M0YvKiA/ICovIHx8IGNoID09PSAweDJELyogLSAqLykge1xuICAgIGZvbGxvd2luZyA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24gKyAxKTtcblxuICAgIGlmIChpc19XU19PUl9FT0woZm9sbG93aW5nKSB8fFxuICAgICAgICB3aXRoaW5GbG93Q29sbGVjdGlvbiAmJiBpc19GTE9XX0lORElDQVRPUihmb2xsb3dpbmcpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgc3RhdGUua2luZCA9ICdzY2FsYXInO1xuICBzdGF0ZS5yZXN1bHQgPSAnJztcbiAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuICBoYXNQZW5kaW5nQ29udGVudCA9IGZhbHNlO1xuXG4gIHdoaWxlIChjaCAhPT0gMCkge1xuICAgIGlmIChjaCA9PT0gMHgzQS8qIDogKi8pIHtcbiAgICAgIGZvbGxvd2luZyA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24gKyAxKTtcblxuICAgICAgaWYgKGlzX1dTX09SX0VPTChmb2xsb3dpbmcpIHx8XG4gICAgICAgICAgd2l0aGluRmxvd0NvbGxlY3Rpb24gJiYgaXNfRkxPV19JTkRJQ0FUT1IoZm9sbG93aW5nKSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIH0gZWxzZSBpZiAoY2ggPT09IDB4MjMvKiAjICovKSB7XG4gICAgICBwcmVjZWRpbmcgPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uIC0gMSk7XG5cbiAgICAgIGlmIChpc19XU19PUl9FT0wocHJlY2VkaW5nKSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIH0gZWxzZSBpZiAoKHN0YXRlLnBvc2l0aW9uID09PSBzdGF0ZS5saW5lU3RhcnQgJiYgdGVzdERvY3VtZW50U2VwYXJhdG9yKHN0YXRlKSkgfHxcbiAgICAgICAgICAgICAgIHdpdGhpbkZsb3dDb2xsZWN0aW9uICYmIGlzX0ZMT1dfSU5ESUNBVE9SKGNoKSkge1xuICAgICAgYnJlYWs7XG5cbiAgICB9IGVsc2UgaWYgKGlzX0VPTChjaCkpIHtcbiAgICAgIF9saW5lID0gc3RhdGUubGluZTtcbiAgICAgIF9saW5lU3RhcnQgPSBzdGF0ZS5saW5lU3RhcnQ7XG4gICAgICBfbGluZUluZGVudCA9IHN0YXRlLmxpbmVJbmRlbnQ7XG4gICAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCBmYWxzZSwgLTEpO1xuXG4gICAgICBpZiAoc3RhdGUubGluZUluZGVudCA+PSBub2RlSW5kZW50KSB7XG4gICAgICAgIGhhc1BlbmRpbmdDb250ZW50ID0gdHJ1ZTtcbiAgICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdGF0ZS5wb3NpdGlvbiA9IGNhcHR1cmVFbmQ7XG4gICAgICAgIHN0YXRlLmxpbmUgPSBfbGluZTtcbiAgICAgICAgc3RhdGUubGluZVN0YXJ0ID0gX2xpbmVTdGFydDtcbiAgICAgICAgc3RhdGUubGluZUluZGVudCA9IF9saW5lSW5kZW50O1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaGFzUGVuZGluZ0NvbnRlbnQpIHtcbiAgICAgIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIGNhcHR1cmVFbmQsIGZhbHNlKTtcbiAgICAgIHdyaXRlRm9sZGVkTGluZXMoc3RhdGUsIHN0YXRlLmxpbmUgLSBfbGluZSk7XG4gICAgICBjYXB0dXJlU3RhcnQgPSBjYXB0dXJlRW5kID0gc3RhdGUucG9zaXRpb247XG4gICAgICBoYXNQZW5kaW5nQ29udGVudCA9IGZhbHNlO1xuICAgIH1cblxuICAgIGlmICghaXNfV0hJVEVfU1BBQ0UoY2gpKSB7XG4gICAgICBjYXB0dXJlRW5kID0gc3RhdGUucG9zaXRpb24gKyAxO1xuICAgIH1cblxuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgfVxuXG4gIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIGNhcHR1cmVFbmQsIGZhbHNlKTtcblxuICBpZiAoc3RhdGUucmVzdWx0KSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBzdGF0ZS5raW5kID0gX2tpbmQ7XG4gIHN0YXRlLnJlc3VsdCA9IF9yZXN1bHQ7XG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gcmVhZFNpbmdsZVF1b3RlZFNjYWxhcihzdGF0ZSwgbm9kZUluZGVudCkge1xuICB2YXIgY2gsXG4gICAgICBjYXB0dXJlU3RhcnQsIGNhcHR1cmVFbmQ7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoY2ggIT09IDB4MjcvKiAnICovKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgc3RhdGUua2luZCA9ICdzY2FsYXInO1xuICBzdGF0ZS5yZXN1bHQgPSAnJztcbiAgc3RhdGUucG9zaXRpb24rKztcbiAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gIHdoaWxlICgoY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKSkgIT09IDApIHtcbiAgICBpZiAoY2ggPT09IDB4MjcvKiAnICovKSB7XG4gICAgICBjYXB0dXJlU2VnbWVudChzdGF0ZSwgY2FwdHVyZVN0YXJ0LCBzdGF0ZS5wb3NpdGlvbiwgdHJ1ZSk7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICAgIGlmIChjaCA9PT0gMHgyNy8qICcgKi8pIHtcbiAgICAgICAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuICAgICAgICBzdGF0ZS5wb3NpdGlvbisrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICB9IGVsc2UgaWYgKGlzX0VPTChjaCkpIHtcbiAgICAgIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIGNhcHR1cmVFbmQsIHRydWUpO1xuICAgICAgd3JpdGVGb2xkZWRMaW5lcyhzdGF0ZSwgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgZmFsc2UsIG5vZGVJbmRlbnQpKTtcbiAgICAgIGNhcHR1cmVTdGFydCA9IGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbjtcblxuICAgIH0gZWxzZSBpZiAoc3RhdGUucG9zaXRpb24gPT09IHN0YXRlLmxpbmVTdGFydCAmJiB0ZXN0RG9jdW1lbnRTZXBhcmF0b3Ioc3RhdGUpKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndW5leHBlY3RlZCBlbmQgb2YgdGhlIGRvY3VtZW50IHdpdGhpbiBhIHNpbmdsZSBxdW90ZWQgc2NhbGFyJyk7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgc3RhdGUucG9zaXRpb24rKztcbiAgICAgIGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbjtcbiAgICB9XG4gIH1cblxuICB0aHJvd0Vycm9yKHN0YXRlLCAndW5leHBlY3RlZCBlbmQgb2YgdGhlIHN0cmVhbSB3aXRoaW4gYSBzaW5nbGUgcXVvdGVkIHNjYWxhcicpO1xufVxuXG5mdW5jdGlvbiByZWFkRG91YmxlUXVvdGVkU2NhbGFyKHN0YXRlLCBub2RlSW5kZW50KSB7XG4gIHZhciBjYXB0dXJlU3RhcnQsXG4gICAgICBjYXB0dXJlRW5kLFxuICAgICAgaGV4TGVuZ3RoLFxuICAgICAgaGV4UmVzdWx0LFxuICAgICAgdG1wLFxuICAgICAgY2g7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoY2ggIT09IDB4MjIvKiBcIiAqLykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHN0YXRlLmtpbmQgPSAnc2NhbGFyJztcbiAgc3RhdGUucmVzdWx0ID0gJyc7XG4gIHN0YXRlLnBvc2l0aW9uKys7XG4gIGNhcHR1cmVTdGFydCA9IGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbjtcblxuICB3aGlsZSAoKGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbikpICE9PSAwKSB7XG4gICAgaWYgKGNoID09PSAweDIyLyogXCIgKi8pIHtcbiAgICAgIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIHN0YXRlLnBvc2l0aW9uLCB0cnVlKTtcbiAgICAgIHN0YXRlLnBvc2l0aW9uKys7XG4gICAgICByZXR1cm4gdHJ1ZTtcblxuICAgIH0gZWxzZSBpZiAoY2ggPT09IDB4NUMvKiBcXCAqLykge1xuICAgICAgY2FwdHVyZVNlZ21lbnQoc3RhdGUsIGNhcHR1cmVTdGFydCwgc3RhdGUucG9zaXRpb24sIHRydWUpO1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuXG4gICAgICBpZiAoaXNfRU9MKGNoKSkge1xuICAgICAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCBmYWxzZSwgbm9kZUluZGVudCk7XG5cbiAgICAgICAgLy8gVE9ETzogcmV3b3JrIHRvIGlubGluZSBmbiB3aXRoIG5vIHR5cGUgY2FzdD9cbiAgICAgIH0gZWxzZSBpZiAoY2ggPCAyNTYgJiYgc2ltcGxlRXNjYXBlQ2hlY2tbY2hdKSB7XG4gICAgICAgIHN0YXRlLnJlc3VsdCArPSBzaW1wbGVFc2NhcGVNYXBbY2hdO1xuICAgICAgICBzdGF0ZS5wb3NpdGlvbisrO1xuXG4gICAgICB9IGVsc2UgaWYgKCh0bXAgPSBlc2NhcGVkSGV4TGVuKGNoKSkgPiAwKSB7XG4gICAgICAgIGhleExlbmd0aCA9IHRtcDtcbiAgICAgICAgaGV4UmVzdWx0ID0gMDtcblxuICAgICAgICBmb3IgKDsgaGV4TGVuZ3RoID4gMDsgaGV4TGVuZ3RoLS0pIHtcbiAgICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICAgICAgICBpZiAoKHRtcCA9IGZyb21IZXhDb2RlKGNoKSkgPj0gMCkge1xuICAgICAgICAgICAgaGV4UmVzdWx0ID0gKGhleFJlc3VsdCA8PCA0KSArIHRtcDtcblxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZXhwZWN0ZWQgaGV4YWRlY2ltYWwgY2hhcmFjdGVyJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgc3RhdGUucmVzdWx0ICs9IGNoYXJGcm9tQ29kZXBvaW50KGhleFJlc3VsdCk7XG5cbiAgICAgICAgc3RhdGUucG9zaXRpb24rKztcblxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3Vua25vd24gZXNjYXBlIHNlcXVlbmNlJyk7XG4gICAgICB9XG5cbiAgICAgIGNhcHR1cmVTdGFydCA9IGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbjtcblxuICAgIH0gZWxzZSBpZiAoaXNfRU9MKGNoKSkge1xuICAgICAgY2FwdHVyZVNlZ21lbnQoc3RhdGUsIGNhcHR1cmVTdGFydCwgY2FwdHVyZUVuZCwgdHJ1ZSk7XG4gICAgICB3cml0ZUZvbGRlZExpbmVzKHN0YXRlLCBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCBmYWxzZSwgbm9kZUluZGVudCkpO1xuICAgICAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gICAgfSBlbHNlIGlmIChzdGF0ZS5wb3NpdGlvbiA9PT0gc3RhdGUubGluZVN0YXJ0ICYmIHRlc3REb2N1bWVudFNlcGFyYXRvcihzdGF0ZSkpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd1bmV4cGVjdGVkIGVuZCBvZiB0aGUgZG9jdW1lbnQgd2l0aGluIGEgZG91YmxlIHF1b3RlZCBzY2FsYXInKTtcblxuICAgIH0gZWxzZSB7XG4gICAgICBzdGF0ZS5wb3NpdGlvbisrO1xuICAgICAgY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuICAgIH1cbiAgfVxuXG4gIHRocm93RXJyb3Ioc3RhdGUsICd1bmV4cGVjdGVkIGVuZCBvZiB0aGUgc3RyZWFtIHdpdGhpbiBhIGRvdWJsZSBxdW90ZWQgc2NhbGFyJyk7XG59XG5cbmZ1bmN0aW9uIHJlYWRGbG93Q29sbGVjdGlvbihzdGF0ZSwgbm9kZUluZGVudCkge1xuICB2YXIgcmVhZE5leHQgPSB0cnVlLFxuICAgICAgX2xpbmUsXG4gICAgICBfdGFnICAgICA9IHN0YXRlLnRhZyxcbiAgICAgIF9yZXN1bHQsXG4gICAgICBfYW5jaG9yICA9IHN0YXRlLmFuY2hvcixcbiAgICAgIGZvbGxvd2luZyxcbiAgICAgIHRlcm1pbmF0b3IsXG4gICAgICBpc1BhaXIsXG4gICAgICBpc0V4cGxpY2l0UGFpcixcbiAgICAgIGlzTWFwcGluZyxcbiAgICAgIG92ZXJyaWRhYmxlS2V5cyA9IHt9LFxuICAgICAga2V5Tm9kZSxcbiAgICAgIGtleVRhZyxcbiAgICAgIHZhbHVlTm9kZSxcbiAgICAgIGNoO1xuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgaWYgKGNoID09PSAweDVCLyogWyAqLykge1xuICAgIHRlcm1pbmF0b3IgPSAweDVEOy8qIF0gKi9cbiAgICBpc01hcHBpbmcgPSBmYWxzZTtcbiAgICBfcmVzdWx0ID0gW107XG4gIH0gZWxzZSBpZiAoY2ggPT09IDB4N0IvKiB7ICovKSB7XG4gICAgdGVybWluYXRvciA9IDB4N0Q7LyogfSAqL1xuICAgIGlzTWFwcGluZyA9IHRydWU7XG4gICAgX3Jlc3VsdCA9IHt9O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChzdGF0ZS5hbmNob3IgIT09IG51bGwpIHtcbiAgICBzdGF0ZS5hbmNob3JNYXBbc3RhdGUuYW5jaG9yXSA9IF9yZXN1bHQ7XG4gIH1cblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgd2hpbGUgKGNoICE9PSAwKSB7XG4gICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgbm9kZUluZGVudCk7XG5cbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gICAgaWYgKGNoID09PSB0ZXJtaW5hdG9yKSB7XG4gICAgICBzdGF0ZS5wb3NpdGlvbisrO1xuICAgICAgc3RhdGUudGFnID0gX3RhZztcbiAgICAgIHN0YXRlLmFuY2hvciA9IF9hbmNob3I7XG4gICAgICBzdGF0ZS5raW5kID0gaXNNYXBwaW5nID8gJ21hcHBpbmcnIDogJ3NlcXVlbmNlJztcbiAgICAgIHN0YXRlLnJlc3VsdCA9IF9yZXN1bHQ7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKCFyZWFkTmV4dCkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ21pc3NlZCBjb21tYSBiZXR3ZWVuIGZsb3cgY29sbGVjdGlvbiBlbnRyaWVzJyk7XG4gICAgfVxuXG4gICAga2V5VGFnID0ga2V5Tm9kZSA9IHZhbHVlTm9kZSA9IG51bGw7XG4gICAgaXNQYWlyID0gaXNFeHBsaWNpdFBhaXIgPSBmYWxzZTtcblxuICAgIGlmIChjaCA9PT0gMHgzRi8qID8gKi8pIHtcbiAgICAgIGZvbGxvd2luZyA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24gKyAxKTtcblxuICAgICAgaWYgKGlzX1dTX09SX0VPTChmb2xsb3dpbmcpKSB7XG4gICAgICAgIGlzUGFpciA9IGlzRXhwbGljaXRQYWlyID0gdHJ1ZTtcbiAgICAgICAgc3RhdGUucG9zaXRpb24rKztcbiAgICAgICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgbm9kZUluZGVudCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgX2xpbmUgPSBzdGF0ZS5saW5lO1xuICAgIGNvbXBvc2VOb2RlKHN0YXRlLCBub2RlSW5kZW50LCBDT05URVhUX0ZMT1dfSU4sIGZhbHNlLCB0cnVlKTtcbiAgICBrZXlUYWcgPSBzdGF0ZS50YWc7XG4gICAga2V5Tm9kZSA9IHN0YXRlLnJlc3VsdDtcbiAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCBub2RlSW5kZW50KTtcblxuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICBpZiAoKGlzRXhwbGljaXRQYWlyIHx8IHN0YXRlLmxpbmUgPT09IF9saW5lKSAmJiBjaCA9PT0gMHgzQS8qIDogKi8pIHtcbiAgICAgIGlzUGFpciA9IHRydWU7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCBub2RlSW5kZW50KTtcbiAgICAgIGNvbXBvc2VOb2RlKHN0YXRlLCBub2RlSW5kZW50LCBDT05URVhUX0ZMT1dfSU4sIGZhbHNlLCB0cnVlKTtcbiAgICAgIHZhbHVlTm9kZSA9IHN0YXRlLnJlc3VsdDtcbiAgICB9XG5cbiAgICBpZiAoaXNNYXBwaW5nKSB7XG4gICAgICBzdG9yZU1hcHBpbmdQYWlyKHN0YXRlLCBfcmVzdWx0LCBvdmVycmlkYWJsZUtleXMsIGtleVRhZywga2V5Tm9kZSwgdmFsdWVOb2RlKTtcbiAgICB9IGVsc2UgaWYgKGlzUGFpcikge1xuICAgICAgX3Jlc3VsdC5wdXNoKHN0b3JlTWFwcGluZ1BhaXIoc3RhdGUsIG51bGwsIG92ZXJyaWRhYmxlS2V5cywga2V5VGFnLCBrZXlOb2RlLCB2YWx1ZU5vZGUpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgX3Jlc3VsdC5wdXNoKGtleU5vZGUpO1xuICAgIH1cblxuICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIG5vZGVJbmRlbnQpO1xuXG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICAgIGlmIChjaCA9PT0gMHgyQy8qICwgKi8pIHtcbiAgICAgIHJlYWROZXh0ID0gdHJ1ZTtcbiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVhZE5leHQgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICB0aHJvd0Vycm9yKHN0YXRlLCAndW5leHBlY3RlZCBlbmQgb2YgdGhlIHN0cmVhbSB3aXRoaW4gYSBmbG93IGNvbGxlY3Rpb24nKTtcbn1cblxuZnVuY3Rpb24gcmVhZEJsb2NrU2NhbGFyKHN0YXRlLCBub2RlSW5kZW50KSB7XG4gIHZhciBjYXB0dXJlU3RhcnQsXG4gICAgICBmb2xkaW5nLFxuICAgICAgY2hvbXBpbmcgICAgICAgPSBDSE9NUElOR19DTElQLFxuICAgICAgZGV0ZWN0ZWRJbmRlbnQgPSBmYWxzZSxcbiAgICAgIHRleHRJbmRlbnQgICAgID0gbm9kZUluZGVudCxcbiAgICAgIGVtcHR5TGluZXMgICAgID0gMCxcbiAgICAgIGF0TW9yZUluZGVudGVkID0gZmFsc2UsXG4gICAgICB0bXAsXG4gICAgICBjaDtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmIChjaCA9PT0gMHg3Qy8qIHwgKi8pIHtcbiAgICBmb2xkaW5nID0gZmFsc2U7XG4gIH0gZWxzZSBpZiAoY2ggPT09IDB4M0UvKiA+ICovKSB7XG4gICAgZm9sZGluZyA9IHRydWU7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgc3RhdGUua2luZCA9ICdzY2FsYXInO1xuICBzdGF0ZS5yZXN1bHQgPSAnJztcblxuICB3aGlsZSAoY2ggIT09IDApIHtcbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICBpZiAoY2ggPT09IDB4MkIvKiArICovIHx8IGNoID09PSAweDJELyogLSAqLykge1xuICAgICAgaWYgKENIT01QSU5HX0NMSVAgPT09IGNob21waW5nKSB7XG4gICAgICAgIGNob21waW5nID0gKGNoID09PSAweDJCLyogKyAqLykgPyBDSE9NUElOR19LRUVQIDogQ0hPTVBJTkdfU1RSSVA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAncmVwZWF0IG9mIGEgY2hvbXBpbmcgbW9kZSBpZGVudGlmaWVyJyk7XG4gICAgICB9XG5cbiAgICB9IGVsc2UgaWYgKCh0bXAgPSBmcm9tRGVjaW1hbENvZGUoY2gpKSA+PSAwKSB7XG4gICAgICBpZiAodG1wID09PSAwKSB7XG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdiYWQgZXhwbGljaXQgaW5kZW50YXRpb24gd2lkdGggb2YgYSBibG9jayBzY2FsYXI7IGl0IGNhbm5vdCBiZSBsZXNzIHRoYW4gb25lJyk7XG4gICAgICB9IGVsc2UgaWYgKCFkZXRlY3RlZEluZGVudCkge1xuICAgICAgICB0ZXh0SW5kZW50ID0gbm9kZUluZGVudCArIHRtcCAtIDE7XG4gICAgICAgIGRldGVjdGVkSW5kZW50ID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdyZXBlYXQgb2YgYW4gaW5kZW50YXRpb24gd2lkdGggaWRlbnRpZmllcicpO1xuICAgICAgfVxuXG4gICAgfSBlbHNlIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIGlmIChpc19XSElURV9TUEFDRShjaCkpIHtcbiAgICBkbyB7IGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTsgfVxuICAgIHdoaWxlIChpc19XSElURV9TUEFDRShjaCkpO1xuXG4gICAgaWYgKGNoID09PSAweDIzLyogIyAqLykge1xuICAgICAgZG8geyBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7IH1cbiAgICAgIHdoaWxlICghaXNfRU9MKGNoKSAmJiAoY2ggIT09IDApKTtcbiAgICB9XG4gIH1cblxuICB3aGlsZSAoY2ggIT09IDApIHtcbiAgICByZWFkTGluZUJyZWFrKHN0YXRlKTtcbiAgICBzdGF0ZS5saW5lSW5kZW50ID0gMDtcblxuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICB3aGlsZSAoKCFkZXRlY3RlZEluZGVudCB8fCBzdGF0ZS5saW5lSW5kZW50IDwgdGV4dEluZGVudCkgJiZcbiAgICAgICAgICAgKGNoID09PSAweDIwLyogU3BhY2UgKi8pKSB7XG4gICAgICBzdGF0ZS5saW5lSW5kZW50Kys7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgfVxuXG4gICAgaWYgKCFkZXRlY3RlZEluZGVudCAmJiBzdGF0ZS5saW5lSW5kZW50ID4gdGV4dEluZGVudCkge1xuICAgICAgdGV4dEluZGVudCA9IHN0YXRlLmxpbmVJbmRlbnQ7XG4gICAgfVxuXG4gICAgaWYgKGlzX0VPTChjaCkpIHtcbiAgICAgIGVtcHR5TGluZXMrKztcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIEVuZCBvZiB0aGUgc2NhbGFyLlxuICAgIGlmIChzdGF0ZS5saW5lSW5kZW50IDwgdGV4dEluZGVudCkge1xuXG4gICAgICAvLyBQZXJmb3JtIHRoZSBjaG9tcGluZy5cbiAgICAgIGlmIChjaG9tcGluZyA9PT0gQ0hPTVBJTkdfS0VFUCkge1xuICAgICAgICBzdGF0ZS5yZXN1bHQgKz0gY29tbW9uLnJlcGVhdCgnXFxuJywgZW1wdHlMaW5lcyk7XG4gICAgICB9IGVsc2UgaWYgKGNob21waW5nID09PSBDSE9NUElOR19DTElQKSB7XG4gICAgICAgIGlmIChkZXRlY3RlZEluZGVudCkgeyAvLyBpLmUuIG9ubHkgaWYgdGhlIHNjYWxhciBpcyBub3QgZW1wdHkuXG4gICAgICAgICAgc3RhdGUucmVzdWx0ICs9ICdcXG4nO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIEJyZWFrIHRoaXMgYHdoaWxlYCBjeWNsZSBhbmQgZ28gdG8gdGhlIGZ1bmNpdG9uJ3MgZXBpbG9ndWUuXG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICAvLyBGb2xkZWQgc3R5bGU6IHVzZSBmYW5jeSBydWxlcyB0byBoYW5kbGUgbGluZSBicmVha3MuXG4gICAgaWYgKGZvbGRpbmcpIHtcblxuICAgICAgLy8gTGluZXMgc3RhcnRpbmcgd2l0aCB3aGl0ZSBzcGFjZSBjaGFyYWN0ZXJzIChtb3JlLWluZGVudGVkIGxpbmVzKSBhcmUgbm90IGZvbGRlZC5cbiAgICAgIGlmIChpc19XSElURV9TUEFDRShjaCkpIHtcbiAgICAgICAgYXRNb3JlSW5kZW50ZWQgPSB0cnVlO1xuICAgICAgICBzdGF0ZS5yZXN1bHQgKz0gY29tbW9uLnJlcGVhdCgnXFxuJywgZW1wdHlMaW5lcyArIDEpO1xuXG4gICAgICAvLyBFbmQgb2YgbW9yZS1pbmRlbnRlZCBibG9jay5cbiAgICAgIH0gZWxzZSBpZiAoYXRNb3JlSW5kZW50ZWQpIHtcbiAgICAgICAgYXRNb3JlSW5kZW50ZWQgPSBmYWxzZTtcbiAgICAgICAgc3RhdGUucmVzdWx0ICs9IGNvbW1vbi5yZXBlYXQoJ1xcbicsIGVtcHR5TGluZXMgKyAxKTtcblxuICAgICAgLy8gSnVzdCBvbmUgbGluZSBicmVhayAtIHBlcmNlaXZlIGFzIHRoZSBzYW1lIGxpbmUuXG4gICAgICB9IGVsc2UgaWYgKGVtcHR5TGluZXMgPT09IDApIHtcbiAgICAgICAgaWYgKGRldGVjdGVkSW5kZW50KSB7IC8vIGkuZS4gb25seSBpZiB3ZSBoYXZlIGFscmVhZHkgcmVhZCBzb21lIHNjYWxhciBjb250ZW50LlxuICAgICAgICAgIHN0YXRlLnJlc3VsdCArPSAnICc7XG4gICAgICAgIH1cblxuICAgICAgLy8gU2V2ZXJhbCBsaW5lIGJyZWFrcyAtIHBlcmNlaXZlIGFzIGRpZmZlcmVudCBsaW5lcy5cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXRlLnJlc3VsdCArPSBjb21tb24ucmVwZWF0KCdcXG4nLCBlbXB0eUxpbmVzKTtcbiAgICAgIH1cblxuICAgIC8vIExpdGVyYWwgc3R5bGU6IGp1c3QgYWRkIGV4YWN0IG51bWJlciBvZiBsaW5lIGJyZWFrcyBiZXR3ZWVuIGNvbnRlbnQgbGluZXMuXG4gICAgfSBlbHNlIGlmIChkZXRlY3RlZEluZGVudCkge1xuICAgICAgLy8gSWYgY3VycmVudCBsaW5lIGlzbid0IHRoZSBmaXJzdCBvbmUgLSBjb3VudCBsaW5lIGJyZWFrIGZyb20gdGhlIGxhc3QgY29udGVudCBsaW5lLlxuICAgICAgc3RhdGUucmVzdWx0ICs9IGNvbW1vbi5yZXBlYXQoJ1xcbicsIGVtcHR5TGluZXMgKyAxKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSW4gY2FzZSBvZiB0aGUgZmlyc3QgY29udGVudCBsaW5lIC0gY291bnQgb25seSBlbXB0eSBsaW5lcy5cbiAgICAgIHN0YXRlLnJlc3VsdCArPSBjb21tb24ucmVwZWF0KCdcXG4nLCBlbXB0eUxpbmVzKTtcbiAgICB9XG5cbiAgICBkZXRlY3RlZEluZGVudCA9IHRydWU7XG4gICAgZW1wdHlMaW5lcyA9IDA7XG4gICAgY2FwdHVyZVN0YXJ0ID0gc3RhdGUucG9zaXRpb247XG5cbiAgICB3aGlsZSAoIWlzX0VPTChjaCkgJiYgKGNoICE9PSAwKSkge1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgIH1cblxuICAgIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIHN0YXRlLnBvc2l0aW9uLCBmYWxzZSk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gcmVhZEJsb2NrU2VxdWVuY2Uoc3RhdGUsIG5vZGVJbmRlbnQpIHtcbiAgdmFyIF9saW5lLFxuICAgICAgX3RhZyAgICAgID0gc3RhdGUudGFnLFxuICAgICAgX2FuY2hvciAgID0gc3RhdGUuYW5jaG9yLFxuICAgICAgX3Jlc3VsdCAgID0gW10sXG4gICAgICBmb2xsb3dpbmcsXG4gICAgICBkZXRlY3RlZCAgPSBmYWxzZSxcbiAgICAgIGNoO1xuXG4gIGlmIChzdGF0ZS5hbmNob3IgIT09IG51bGwpIHtcbiAgICBzdGF0ZS5hbmNob3JNYXBbc3RhdGUuYW5jaG9yXSA9IF9yZXN1bHQ7XG4gIH1cblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gIHdoaWxlIChjaCAhPT0gMCkge1xuXG4gICAgaWYgKGNoICE9PSAweDJELyogLSAqLykge1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgZm9sbG93aW5nID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbiArIDEpO1xuXG4gICAgaWYgKCFpc19XU19PUl9FT0woZm9sbG93aW5nKSkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgZGV0ZWN0ZWQgPSB0cnVlO1xuICAgIHN0YXRlLnBvc2l0aW9uKys7XG5cbiAgICBpZiAoc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpKSB7XG4gICAgICBpZiAoc3RhdGUubGluZUluZGVudCA8PSBub2RlSW5kZW50KSB7XG4gICAgICAgIF9yZXN1bHQucHVzaChudWxsKTtcbiAgICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgX2xpbmUgPSBzdGF0ZS5saW5lO1xuICAgIGNvbXBvc2VOb2RlKHN0YXRlLCBub2RlSW5kZW50LCBDT05URVhUX0JMT0NLX0lOLCBmYWxzZSwgdHJ1ZSk7XG4gICAgX3Jlc3VsdC5wdXNoKHN0YXRlLnJlc3VsdCk7XG4gICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpO1xuXG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICAgIGlmICgoc3RhdGUubGluZSA9PT0gX2xpbmUgfHwgc3RhdGUubGluZUluZGVudCA+IG5vZGVJbmRlbnQpICYmIChjaCAhPT0gMCkpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdiYWQgaW5kZW50YXRpb24gb2YgYSBzZXF1ZW5jZSBlbnRyeScpO1xuICAgIH0gZWxzZSBpZiAoc3RhdGUubGluZUluZGVudCA8IG5vZGVJbmRlbnQpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIGlmIChkZXRlY3RlZCkge1xuICAgIHN0YXRlLnRhZyA9IF90YWc7XG4gICAgc3RhdGUuYW5jaG9yID0gX2FuY2hvcjtcbiAgICBzdGF0ZS5raW5kID0gJ3NlcXVlbmNlJztcbiAgICBzdGF0ZS5yZXN1bHQgPSBfcmVzdWx0O1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gcmVhZEJsb2NrTWFwcGluZyhzdGF0ZSwgbm9kZUluZGVudCwgZmxvd0luZGVudCkge1xuICB2YXIgZm9sbG93aW5nLFxuICAgICAgYWxsb3dDb21wYWN0LFxuICAgICAgX2xpbmUsXG4gICAgICBfdGFnICAgICAgICAgID0gc3RhdGUudGFnLFxuICAgICAgX2FuY2hvciAgICAgICA9IHN0YXRlLmFuY2hvcixcbiAgICAgIF9yZXN1bHQgICAgICAgPSB7fSxcbiAgICAgIG92ZXJyaWRhYmxlS2V5cyA9IHt9LFxuICAgICAga2V5VGFnICAgICAgICA9IG51bGwsXG4gICAgICBrZXlOb2RlICAgICAgID0gbnVsbCxcbiAgICAgIHZhbHVlTm9kZSAgICAgPSBudWxsLFxuICAgICAgYXRFeHBsaWNpdEtleSA9IGZhbHNlLFxuICAgICAgZGV0ZWN0ZWQgICAgICA9IGZhbHNlLFxuICAgICAgY2g7XG5cbiAgaWYgKHN0YXRlLmFuY2hvciAhPT0gbnVsbCkge1xuICAgIHN0YXRlLmFuY2hvck1hcFtzdGF0ZS5hbmNob3JdID0gX3Jlc3VsdDtcbiAgfVxuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgd2hpbGUgKGNoICE9PSAwKSB7XG4gICAgZm9sbG93aW5nID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbiArIDEpO1xuICAgIF9saW5lID0gc3RhdGUubGluZTsgLy8gU2F2ZSB0aGUgY3VycmVudCBsaW5lLlxuXG4gICAgLy9cbiAgICAvLyBFeHBsaWNpdCBub3RhdGlvbiBjYXNlLiBUaGVyZSBhcmUgdHdvIHNlcGFyYXRlIGJsb2NrczpcbiAgICAvLyBmaXJzdCBmb3IgdGhlIGtleSAoZGVub3RlZCBieSBcIj9cIikgYW5kIHNlY29uZCBmb3IgdGhlIHZhbHVlIChkZW5vdGVkIGJ5IFwiOlwiKVxuICAgIC8vXG4gICAgaWYgKChjaCA9PT0gMHgzRi8qID8gKi8gfHwgY2ggPT09IDB4M0EvKiA6ICovKSAmJiBpc19XU19PUl9FT0woZm9sbG93aW5nKSkge1xuXG4gICAgICBpZiAoY2ggPT09IDB4M0YvKiA/ICovKSB7XG4gICAgICAgIGlmIChhdEV4cGxpY2l0S2V5KSB7XG4gICAgICAgICAgc3RvcmVNYXBwaW5nUGFpcihzdGF0ZSwgX3Jlc3VsdCwgb3ZlcnJpZGFibGVLZXlzLCBrZXlUYWcsIGtleU5vZGUsIG51bGwpO1xuICAgICAgICAgIGtleVRhZyA9IGtleU5vZGUgPSB2YWx1ZU5vZGUgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgZGV0ZWN0ZWQgPSB0cnVlO1xuICAgICAgICBhdEV4cGxpY2l0S2V5ID0gdHJ1ZTtcbiAgICAgICAgYWxsb3dDb21wYWN0ID0gdHJ1ZTtcblxuICAgICAgfSBlbHNlIGlmIChhdEV4cGxpY2l0S2V5KSB7XG4gICAgICAgIC8vIGkuZS4gMHgzQS8qIDogKi8gPT09IGNoYXJhY3RlciBhZnRlciB0aGUgZXhwbGljaXQga2V5LlxuICAgICAgICBhdEV4cGxpY2l0S2V5ID0gZmFsc2U7XG4gICAgICAgIGFsbG93Q29tcGFjdCA9IHRydWU7XG5cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdpbmNvbXBsZXRlIGV4cGxpY2l0IG1hcHBpbmcgcGFpcjsgYSBrZXkgbm9kZSBpcyBtaXNzZWQnKTtcbiAgICAgIH1cblxuICAgICAgc3RhdGUucG9zaXRpb24gKz0gMTtcbiAgICAgIGNoID0gZm9sbG93aW5nO1xuXG4gICAgLy9cbiAgICAvLyBJbXBsaWNpdCBub3RhdGlvbiBjYXNlLiBGbG93LXN0eWxlIG5vZGUgYXMgdGhlIGtleSBmaXJzdCwgdGhlbiBcIjpcIiwgYW5kIHRoZSB2YWx1ZS5cbiAgICAvL1xuICAgIH0gZWxzZSBpZiAoY29tcG9zZU5vZGUoc3RhdGUsIGZsb3dJbmRlbnQsIENPTlRFWFRfRkxPV19PVVQsIGZhbHNlLCB0cnVlKSkge1xuXG4gICAgICBpZiAoc3RhdGUubGluZSA9PT0gX2xpbmUpIHtcbiAgICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICAgICAgICB3aGlsZSAoaXNfV0hJVEVfU1BBQ0UoY2gpKSB7XG4gICAgICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNoID09PSAweDNBLyogOiAqLykge1xuICAgICAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcblxuICAgICAgICAgIGlmICghaXNfV1NfT1JfRU9MKGNoKSkge1xuICAgICAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2Egd2hpdGVzcGFjZSBjaGFyYWN0ZXIgaXMgZXhwZWN0ZWQgYWZ0ZXIgdGhlIGtleS12YWx1ZSBzZXBhcmF0b3Igd2l0aGluIGEgYmxvY2sgbWFwcGluZycpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChhdEV4cGxpY2l0S2V5KSB7XG4gICAgICAgICAgICBzdG9yZU1hcHBpbmdQYWlyKHN0YXRlLCBfcmVzdWx0LCBvdmVycmlkYWJsZUtleXMsIGtleVRhZywga2V5Tm9kZSwgbnVsbCk7XG4gICAgICAgICAgICBrZXlUYWcgPSBrZXlOb2RlID0gdmFsdWVOb2RlID0gbnVsbDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBkZXRlY3RlZCA9IHRydWU7XG4gICAgICAgICAgYXRFeHBsaWNpdEtleSA9IGZhbHNlO1xuICAgICAgICAgIGFsbG93Q29tcGFjdCA9IGZhbHNlO1xuICAgICAgICAgIGtleVRhZyA9IHN0YXRlLnRhZztcbiAgICAgICAgICBrZXlOb2RlID0gc3RhdGUucmVzdWx0O1xuXG4gICAgICAgIH0gZWxzZSBpZiAoZGV0ZWN0ZWQpIHtcbiAgICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnY2FuIG5vdCByZWFkIGFuIGltcGxpY2l0IG1hcHBpbmcgcGFpcjsgYSBjb2xvbiBpcyBtaXNzZWQnKTtcblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN0YXRlLnRhZyA9IF90YWc7XG4gICAgICAgICAgc3RhdGUuYW5jaG9yID0gX2FuY2hvcjtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTsgLy8gS2VlcCB0aGUgcmVzdWx0IG9mIGBjb21wb3NlTm9kZWAuXG4gICAgICAgIH1cblxuICAgICAgfSBlbHNlIGlmIChkZXRlY3RlZCkge1xuICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnY2FuIG5vdCByZWFkIGEgYmxvY2sgbWFwcGluZyBlbnRyeTsgYSBtdWx0aWxpbmUga2V5IG1heSBub3QgYmUgYW4gaW1wbGljaXQga2V5Jyk7XG5cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXRlLnRhZyA9IF90YWc7XG4gICAgICAgIHN0YXRlLmFuY2hvciA9IF9hbmNob3I7XG4gICAgICAgIHJldHVybiB0cnVlOyAvLyBLZWVwIHRoZSByZXN1bHQgb2YgYGNvbXBvc2VOb2RlYC5cbiAgICAgIH1cblxuICAgIH0gZWxzZSB7XG4gICAgICBicmVhazsgLy8gUmVhZGluZyBpcyBkb25lLiBHbyB0byB0aGUgZXBpbG9ndWUuXG4gICAgfVxuXG4gICAgLy9cbiAgICAvLyBDb21tb24gcmVhZGluZyBjb2RlIGZvciBib3RoIGV4cGxpY2l0IGFuZCBpbXBsaWNpdCBub3RhdGlvbnMuXG4gICAgLy9cbiAgICBpZiAoc3RhdGUubGluZSA9PT0gX2xpbmUgfHwgc3RhdGUubGluZUluZGVudCA+IG5vZGVJbmRlbnQpIHtcbiAgICAgIGlmIChjb21wb3NlTm9kZShzdGF0ZSwgbm9kZUluZGVudCwgQ09OVEVYVF9CTE9DS19PVVQsIHRydWUsIGFsbG93Q29tcGFjdCkpIHtcbiAgICAgICAgaWYgKGF0RXhwbGljaXRLZXkpIHtcbiAgICAgICAgICBrZXlOb2RlID0gc3RhdGUucmVzdWx0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhbHVlTm9kZSA9IHN0YXRlLnJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoIWF0RXhwbGljaXRLZXkpIHtcbiAgICAgICAgc3RvcmVNYXBwaW5nUGFpcihzdGF0ZSwgX3Jlc3VsdCwgb3ZlcnJpZGFibGVLZXlzLCBrZXlUYWcsIGtleU5vZGUsIHZhbHVlTm9kZSk7XG4gICAgICAgIGtleVRhZyA9IGtleU5vZGUgPSB2YWx1ZU5vZGUgPSBudWxsO1xuICAgICAgfVxuXG4gICAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCAtMSk7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuICAgIH1cblxuICAgIGlmIChzdGF0ZS5saW5lSW5kZW50ID4gbm9kZUluZGVudCAmJiAoY2ggIT09IDApKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnYmFkIGluZGVudGF0aW9uIG9mIGEgbWFwcGluZyBlbnRyeScpO1xuICAgIH0gZWxzZSBpZiAoc3RhdGUubGluZUluZGVudCA8IG5vZGVJbmRlbnQpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIC8vXG4gIC8vIEVwaWxvZ3VlLlxuICAvL1xuXG4gIC8vIFNwZWNpYWwgY2FzZTogbGFzdCBtYXBwaW5nJ3Mgbm9kZSBjb250YWlucyBvbmx5IHRoZSBrZXkgaW4gZXhwbGljaXQgbm90YXRpb24uXG4gIGlmIChhdEV4cGxpY2l0S2V5KSB7XG4gICAgc3RvcmVNYXBwaW5nUGFpcihzdGF0ZSwgX3Jlc3VsdCwgb3ZlcnJpZGFibGVLZXlzLCBrZXlUYWcsIGtleU5vZGUsIG51bGwpO1xuICB9XG5cbiAgLy8gRXhwb3NlIHRoZSByZXN1bHRpbmcgbWFwcGluZy5cbiAgaWYgKGRldGVjdGVkKSB7XG4gICAgc3RhdGUudGFnID0gX3RhZztcbiAgICBzdGF0ZS5hbmNob3IgPSBfYW5jaG9yO1xuICAgIHN0YXRlLmtpbmQgPSAnbWFwcGluZyc7XG4gICAgc3RhdGUucmVzdWx0ID0gX3Jlc3VsdDtcbiAgfVxuXG4gIHJldHVybiBkZXRlY3RlZDtcbn1cblxuZnVuY3Rpb24gcmVhZFRhZ1Byb3BlcnR5KHN0YXRlKSB7XG4gIHZhciBfcG9zaXRpb24sXG4gICAgICBpc1ZlcmJhdGltID0gZmFsc2UsXG4gICAgICBpc05hbWVkICAgID0gZmFsc2UsXG4gICAgICB0YWdIYW5kbGUsXG4gICAgICB0YWdOYW1lLFxuICAgICAgY2g7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoY2ggIT09IDB4MjEvKiAhICovKSByZXR1cm4gZmFsc2U7XG5cbiAgaWYgKHN0YXRlLnRhZyAhPT0gbnVsbCkge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICdkdXBsaWNhdGlvbiBvZiBhIHRhZyBwcm9wZXJ0eScpO1xuICB9XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmIChjaCA9PT0gMHgzQy8qIDwgKi8pIHtcbiAgICBpc1ZlcmJhdGltID0gdHJ1ZTtcbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgfSBlbHNlIGlmIChjaCA9PT0gMHgyMS8qICEgKi8pIHtcbiAgICBpc05hbWVkID0gdHJ1ZTtcbiAgICB0YWdIYW5kbGUgPSAnISEnO1xuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcblxuICB9IGVsc2Uge1xuICAgIHRhZ0hhbmRsZSA9ICchJztcbiAgfVxuXG4gIF9wb3NpdGlvbiA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gIGlmIChpc1ZlcmJhdGltKSB7XG4gICAgZG8geyBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7IH1cbiAgICB3aGlsZSAoY2ggIT09IDAgJiYgY2ggIT09IDB4M0UvKiA+ICovKTtcblxuICAgIGlmIChzdGF0ZS5wb3NpdGlvbiA8IHN0YXRlLmxlbmd0aCkge1xuICAgICAgdGFnTmFtZSA9IHN0YXRlLmlucHV0LnNsaWNlKF9wb3NpdGlvbiwgc3RhdGUucG9zaXRpb24pO1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndW5leHBlY3RlZCBlbmQgb2YgdGhlIHN0cmVhbSB3aXRoaW4gYSB2ZXJiYXRpbSB0YWcnKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgd2hpbGUgKGNoICE9PSAwICYmICFpc19XU19PUl9FT0woY2gpKSB7XG5cbiAgICAgIGlmIChjaCA9PT0gMHgyMS8qICEgKi8pIHtcbiAgICAgICAgaWYgKCFpc05hbWVkKSB7XG4gICAgICAgICAgdGFnSGFuZGxlID0gc3RhdGUuaW5wdXQuc2xpY2UoX3Bvc2l0aW9uIC0gMSwgc3RhdGUucG9zaXRpb24gKyAxKTtcblxuICAgICAgICAgIGlmICghUEFUVEVSTl9UQUdfSEFORExFLnRlc3QodGFnSGFuZGxlKSkge1xuICAgICAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ25hbWVkIHRhZyBoYW5kbGUgY2Fubm90IGNvbnRhaW4gc3VjaCBjaGFyYWN0ZXJzJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaXNOYW1lZCA9IHRydWU7XG4gICAgICAgICAgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb24gKyAxO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd0YWcgc3VmZml4IGNhbm5vdCBjb250YWluIGV4Y2xhbWF0aW9uIG1hcmtzJyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgIH1cblxuICAgIHRhZ05hbWUgPSBzdGF0ZS5pbnB1dC5zbGljZShfcG9zaXRpb24sIHN0YXRlLnBvc2l0aW9uKTtcblxuICAgIGlmIChQQVRURVJOX0ZMT1dfSU5ESUNBVE9SUy50ZXN0KHRhZ05hbWUpKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndGFnIHN1ZmZpeCBjYW5ub3QgY29udGFpbiBmbG93IGluZGljYXRvciBjaGFyYWN0ZXJzJyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHRhZ05hbWUgJiYgIVBBVFRFUk5fVEFHX1VSSS50ZXN0KHRhZ05hbWUpKSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3RhZyBuYW1lIGNhbm5vdCBjb250YWluIHN1Y2ggY2hhcmFjdGVyczogJyArIHRhZ05hbWUpO1xuICB9XG5cbiAgaWYgKGlzVmVyYmF0aW0pIHtcbiAgICBzdGF0ZS50YWcgPSB0YWdOYW1lO1xuXG4gIH0gZWxzZSBpZiAoX2hhc093blByb3BlcnR5LmNhbGwoc3RhdGUudGFnTWFwLCB0YWdIYW5kbGUpKSB7XG4gICAgc3RhdGUudGFnID0gc3RhdGUudGFnTWFwW3RhZ0hhbmRsZV0gKyB0YWdOYW1lO1xuXG4gIH0gZWxzZSBpZiAodGFnSGFuZGxlID09PSAnIScpIHtcbiAgICBzdGF0ZS50YWcgPSAnIScgKyB0YWdOYW1lO1xuXG4gIH0gZWxzZSBpZiAodGFnSGFuZGxlID09PSAnISEnKSB7XG4gICAgc3RhdGUudGFnID0gJ3RhZzp5YW1sLm9yZywyMDAyOicgKyB0YWdOYW1lO1xuXG4gIH0gZWxzZSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3VuZGVjbGFyZWQgdGFnIGhhbmRsZSBcIicgKyB0YWdIYW5kbGUgKyAnXCInKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiByZWFkQW5jaG9yUHJvcGVydHkoc3RhdGUpIHtcbiAgdmFyIF9wb3NpdGlvbixcbiAgICAgIGNoO1xuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgaWYgKGNoICE9PSAweDI2LyogJiAqLykgcmV0dXJuIGZhbHNlO1xuXG4gIGlmIChzdGF0ZS5hbmNob3IgIT09IG51bGwpIHtcbiAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZHVwbGljYXRpb24gb2YgYW4gYW5jaG9yIHByb3BlcnR5Jyk7XG4gIH1cblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gIF9wb3NpdGlvbiA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gIHdoaWxlIChjaCAhPT0gMCAmJiAhaXNfV1NfT1JfRU9MKGNoKSAmJiAhaXNfRkxPV19JTkRJQ0FUT1IoY2gpKSB7XG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICB9XG5cbiAgaWYgKHN0YXRlLnBvc2l0aW9uID09PSBfcG9zaXRpb24pIHtcbiAgICB0aHJvd0Vycm9yKHN0YXRlLCAnbmFtZSBvZiBhbiBhbmNob3Igbm9kZSBtdXN0IGNvbnRhaW4gYXQgbGVhc3Qgb25lIGNoYXJhY3RlcicpO1xuICB9XG5cbiAgc3RhdGUuYW5jaG9yID0gc3RhdGUuaW5wdXQuc2xpY2UoX3Bvc2l0aW9uLCBzdGF0ZS5wb3NpdGlvbik7XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiByZWFkQWxpYXMoc3RhdGUpIHtcbiAgdmFyIF9wb3NpdGlvbiwgYWxpYXMsXG4gICAgICBjaDtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmIChjaCAhPT0gMHgyQS8qICogKi8pIHJldHVybiBmYWxzZTtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gIF9wb3NpdGlvbiA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gIHdoaWxlIChjaCAhPT0gMCAmJiAhaXNfV1NfT1JfRU9MKGNoKSAmJiAhaXNfRkxPV19JTkRJQ0FUT1IoY2gpKSB7XG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICB9XG5cbiAgaWYgKHN0YXRlLnBvc2l0aW9uID09PSBfcG9zaXRpb24pIHtcbiAgICB0aHJvd0Vycm9yKHN0YXRlLCAnbmFtZSBvZiBhbiBhbGlhcyBub2RlIG11c3QgY29udGFpbiBhdCBsZWFzdCBvbmUgY2hhcmFjdGVyJyk7XG4gIH1cblxuICBhbGlhcyA9IHN0YXRlLmlucHV0LnNsaWNlKF9wb3NpdGlvbiwgc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmICghc3RhdGUuYW5jaG9yTWFwLmhhc093blByb3BlcnR5KGFsaWFzKSkge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICd1bmlkZW50aWZpZWQgYWxpYXMgXCInICsgYWxpYXMgKyAnXCInKTtcbiAgfVxuXG4gIHN0YXRlLnJlc3VsdCA9IHN0YXRlLmFuY2hvck1hcFthbGlhc107XG4gIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTtcbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGNvbXBvc2VOb2RlKHN0YXRlLCBwYXJlbnRJbmRlbnQsIG5vZGVDb250ZXh0LCBhbGxvd1RvU2VlaywgYWxsb3dDb21wYWN0KSB7XG4gIHZhciBhbGxvd0Jsb2NrU3R5bGVzLFxuICAgICAgYWxsb3dCbG9ja1NjYWxhcnMsXG4gICAgICBhbGxvd0Jsb2NrQ29sbGVjdGlvbnMsXG4gICAgICBpbmRlbnRTdGF0dXMgPSAxLCAvLyAxOiB0aGlzPnBhcmVudCwgMDogdGhpcz1wYXJlbnQsIC0xOiB0aGlzPHBhcmVudFxuICAgICAgYXROZXdMaW5lICA9IGZhbHNlLFxuICAgICAgaGFzQ29udGVudCA9IGZhbHNlLFxuICAgICAgdHlwZUluZGV4LFxuICAgICAgdHlwZVF1YW50aXR5LFxuICAgICAgdHlwZSxcbiAgICAgIGZsb3dJbmRlbnQsXG4gICAgICBibG9ja0luZGVudDtcblxuICBpZiAoc3RhdGUubGlzdGVuZXIgIT09IG51bGwpIHtcbiAgICBzdGF0ZS5saXN0ZW5lcignb3BlbicsIHN0YXRlKTtcbiAgfVxuXG4gIHN0YXRlLnRhZyAgICA9IG51bGw7XG4gIHN0YXRlLmFuY2hvciA9IG51bGw7XG4gIHN0YXRlLmtpbmQgICA9IG51bGw7XG4gIHN0YXRlLnJlc3VsdCA9IG51bGw7XG5cbiAgYWxsb3dCbG9ja1N0eWxlcyA9IGFsbG93QmxvY2tTY2FsYXJzID0gYWxsb3dCbG9ja0NvbGxlY3Rpb25zID1cbiAgICBDT05URVhUX0JMT0NLX09VVCA9PT0gbm9kZUNvbnRleHQgfHxcbiAgICBDT05URVhUX0JMT0NLX0lOICA9PT0gbm9kZUNvbnRleHQ7XG5cbiAgaWYgKGFsbG93VG9TZWVrKSB7XG4gICAgaWYgKHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKSkge1xuICAgICAgYXROZXdMaW5lID0gdHJ1ZTtcblxuICAgICAgaWYgKHN0YXRlLmxpbmVJbmRlbnQgPiBwYXJlbnRJbmRlbnQpIHtcbiAgICAgICAgaW5kZW50U3RhdHVzID0gMTtcbiAgICAgIH0gZWxzZSBpZiAoc3RhdGUubGluZUluZGVudCA9PT0gcGFyZW50SW5kZW50KSB7XG4gICAgICAgIGluZGVudFN0YXR1cyA9IDA7XG4gICAgICB9IGVsc2UgaWYgKHN0YXRlLmxpbmVJbmRlbnQgPCBwYXJlbnRJbmRlbnQpIHtcbiAgICAgICAgaW5kZW50U3RhdHVzID0gLTE7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKGluZGVudFN0YXR1cyA9PT0gMSkge1xuICAgIHdoaWxlIChyZWFkVGFnUHJvcGVydHkoc3RhdGUpIHx8IHJlYWRBbmNob3JQcm9wZXJ0eShzdGF0ZSkpIHtcbiAgICAgIGlmIChza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCAtMSkpIHtcbiAgICAgICAgYXROZXdMaW5lID0gdHJ1ZTtcbiAgICAgICAgYWxsb3dCbG9ja0NvbGxlY3Rpb25zID0gYWxsb3dCbG9ja1N0eWxlcztcblxuICAgICAgICBpZiAoc3RhdGUubGluZUluZGVudCA+IHBhcmVudEluZGVudCkge1xuICAgICAgICAgIGluZGVudFN0YXR1cyA9IDE7XG4gICAgICAgIH0gZWxzZSBpZiAoc3RhdGUubGluZUluZGVudCA9PT0gcGFyZW50SW5kZW50KSB7XG4gICAgICAgICAgaW5kZW50U3RhdHVzID0gMDtcbiAgICAgICAgfSBlbHNlIGlmIChzdGF0ZS5saW5lSW5kZW50IDwgcGFyZW50SW5kZW50KSB7XG4gICAgICAgICAgaW5kZW50U3RhdHVzID0gLTE7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFsbG93QmxvY2tDb2xsZWN0aW9ucyA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChhbGxvd0Jsb2NrQ29sbGVjdGlvbnMpIHtcbiAgICBhbGxvd0Jsb2NrQ29sbGVjdGlvbnMgPSBhdE5ld0xpbmUgfHwgYWxsb3dDb21wYWN0O1xuICB9XG5cbiAgaWYgKGluZGVudFN0YXR1cyA9PT0gMSB8fCBDT05URVhUX0JMT0NLX09VVCA9PT0gbm9kZUNvbnRleHQpIHtcbiAgICBpZiAoQ09OVEVYVF9GTE9XX0lOID09PSBub2RlQ29udGV4dCB8fCBDT05URVhUX0ZMT1dfT1VUID09PSBub2RlQ29udGV4dCkge1xuICAgICAgZmxvd0luZGVudCA9IHBhcmVudEluZGVudDtcbiAgICB9IGVsc2Uge1xuICAgICAgZmxvd0luZGVudCA9IHBhcmVudEluZGVudCArIDE7XG4gICAgfVxuXG4gICAgYmxvY2tJbmRlbnQgPSBzdGF0ZS5wb3NpdGlvbiAtIHN0YXRlLmxpbmVTdGFydDtcblxuICAgIGlmIChpbmRlbnRTdGF0dXMgPT09IDEpIHtcbiAgICAgIGlmIChhbGxvd0Jsb2NrQ29sbGVjdGlvbnMgJiZcbiAgICAgICAgICAocmVhZEJsb2NrU2VxdWVuY2Uoc3RhdGUsIGJsb2NrSW5kZW50KSB8fFxuICAgICAgICAgICByZWFkQmxvY2tNYXBwaW5nKHN0YXRlLCBibG9ja0luZGVudCwgZmxvd0luZGVudCkpIHx8XG4gICAgICAgICAgcmVhZEZsb3dDb2xsZWN0aW9uKHN0YXRlLCBmbG93SW5kZW50KSkge1xuICAgICAgICBoYXNDb250ZW50ID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICgoYWxsb3dCbG9ja1NjYWxhcnMgJiYgcmVhZEJsb2NrU2NhbGFyKHN0YXRlLCBmbG93SW5kZW50KSkgfHxcbiAgICAgICAgICAgIHJlYWRTaW5nbGVRdW90ZWRTY2FsYXIoc3RhdGUsIGZsb3dJbmRlbnQpIHx8XG4gICAgICAgICAgICByZWFkRG91YmxlUXVvdGVkU2NhbGFyKHN0YXRlLCBmbG93SW5kZW50KSkge1xuICAgICAgICAgIGhhc0NvbnRlbnQgPSB0cnVlO1xuXG4gICAgICAgIH0gZWxzZSBpZiAocmVhZEFsaWFzKHN0YXRlKSkge1xuICAgICAgICAgIGhhc0NvbnRlbnQgPSB0cnVlO1xuXG4gICAgICAgICAgaWYgKHN0YXRlLnRhZyAhPT0gbnVsbCB8fCBzdGF0ZS5hbmNob3IgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdhbGlhcyBub2RlIHNob3VsZCBub3QgaGF2ZSBhbnkgcHJvcGVydGllcycpO1xuICAgICAgICAgIH1cblxuICAgICAgICB9IGVsc2UgaWYgKHJlYWRQbGFpblNjYWxhcihzdGF0ZSwgZmxvd0luZGVudCwgQ09OVEVYVF9GTE9XX0lOID09PSBub2RlQ29udGV4dCkpIHtcbiAgICAgICAgICBoYXNDb250ZW50ID0gdHJ1ZTtcblxuICAgICAgICAgIGlmIChzdGF0ZS50YWcgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHN0YXRlLnRhZyA9ICc/JztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc3RhdGUuYW5jaG9yICE9PSBudWxsKSB7XG4gICAgICAgICAgc3RhdGUuYW5jaG9yTWFwW3N0YXRlLmFuY2hvcl0gPSBzdGF0ZS5yZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGluZGVudFN0YXR1cyA9PT0gMCkge1xuICAgICAgLy8gU3BlY2lhbCBjYXNlOiBibG9jayBzZXF1ZW5jZXMgYXJlIGFsbG93ZWQgdG8gaGF2ZSBzYW1lIGluZGVudGF0aW9uIGxldmVsIGFzIHRoZSBwYXJlbnQuXG4gICAgICAvLyBodHRwOi8vd3d3LnlhbWwub3JnL3NwZWMvMS4yL3NwZWMuaHRtbCNpZDI3OTk3ODRcbiAgICAgIGhhc0NvbnRlbnQgPSBhbGxvd0Jsb2NrQ29sbGVjdGlvbnMgJiYgcmVhZEJsb2NrU2VxdWVuY2Uoc3RhdGUsIGJsb2NrSW5kZW50KTtcbiAgICB9XG4gIH1cblxuICBpZiAoc3RhdGUudGFnICE9PSBudWxsICYmIHN0YXRlLnRhZyAhPT0gJyEnKSB7XG4gICAgaWYgKHN0YXRlLnRhZyA9PT0gJz8nKSB7XG4gICAgICBmb3IgKHR5cGVJbmRleCA9IDAsIHR5cGVRdWFudGl0eSA9IHN0YXRlLmltcGxpY2l0VHlwZXMubGVuZ3RoO1xuICAgICAgICAgICB0eXBlSW5kZXggPCB0eXBlUXVhbnRpdHk7XG4gICAgICAgICAgIHR5cGVJbmRleCArPSAxKSB7XG4gICAgICAgIHR5cGUgPSBzdGF0ZS5pbXBsaWNpdFR5cGVzW3R5cGVJbmRleF07XG5cbiAgICAgICAgLy8gSW1wbGljaXQgcmVzb2x2aW5nIGlzIG5vdCBhbGxvd2VkIGZvciBub24tc2NhbGFyIHR5cGVzLCBhbmQgJz8nXG4gICAgICAgIC8vIG5vbi1zcGVjaWZpYyB0YWcgaXMgb25seSBhc3NpZ25lZCB0byBwbGFpbiBzY2FsYXJzLiBTbywgaXQgaXNuJ3RcbiAgICAgICAgLy8gbmVlZGVkIHRvIGNoZWNrIGZvciAna2luZCcgY29uZm9ybWl0eS5cblxuICAgICAgICBpZiAodHlwZS5yZXNvbHZlKHN0YXRlLnJlc3VsdCkpIHsgLy8gYHN0YXRlLnJlc3VsdGAgdXBkYXRlZCBpbiByZXNvbHZlciBpZiBtYXRjaGVkXG4gICAgICAgICAgc3RhdGUucmVzdWx0ID0gdHlwZS5jb25zdHJ1Y3Qoc3RhdGUucmVzdWx0KTtcbiAgICAgICAgICBzdGF0ZS50YWcgPSB0eXBlLnRhZztcbiAgICAgICAgICBpZiAoc3RhdGUuYW5jaG9yICE9PSBudWxsKSB7XG4gICAgICAgICAgICBzdGF0ZS5hbmNob3JNYXBbc3RhdGUuYW5jaG9yXSA9IHN0YXRlLnJlc3VsdDtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKF9oYXNPd25Qcm9wZXJ0eS5jYWxsKHN0YXRlLnR5cGVNYXAsIHN0YXRlLnRhZykpIHtcbiAgICAgIHR5cGUgPSBzdGF0ZS50eXBlTWFwW3N0YXRlLnRhZ107XG5cbiAgICAgIGlmIChzdGF0ZS5yZXN1bHQgIT09IG51bGwgJiYgdHlwZS5raW5kICE9PSBzdGF0ZS5raW5kKSB7XG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd1bmFjY2VwdGFibGUgbm9kZSBraW5kIGZvciAhPCcgKyBzdGF0ZS50YWcgKyAnPiB0YWc7IGl0IHNob3VsZCBiZSBcIicgKyB0eXBlLmtpbmQgKyAnXCIsIG5vdCBcIicgKyBzdGF0ZS5raW5kICsgJ1wiJyk7XG4gICAgICB9XG5cbiAgICAgIGlmICghdHlwZS5yZXNvbHZlKHN0YXRlLnJlc3VsdCkpIHsgLy8gYHN0YXRlLnJlc3VsdGAgdXBkYXRlZCBpbiByZXNvbHZlciBpZiBtYXRjaGVkXG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdjYW5ub3QgcmVzb2x2ZSBhIG5vZGUgd2l0aCAhPCcgKyBzdGF0ZS50YWcgKyAnPiBleHBsaWNpdCB0YWcnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXRlLnJlc3VsdCA9IHR5cGUuY29uc3RydWN0KHN0YXRlLnJlc3VsdCk7XG4gICAgICAgIGlmIChzdGF0ZS5hbmNob3IgIT09IG51bGwpIHtcbiAgICAgICAgICBzdGF0ZS5hbmNob3JNYXBbc3RhdGUuYW5jaG9yXSA9IHN0YXRlLnJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndW5rbm93biB0YWcgITwnICsgc3RhdGUudGFnICsgJz4nKTtcbiAgICB9XG4gIH1cblxuICBpZiAoc3RhdGUubGlzdGVuZXIgIT09IG51bGwpIHtcbiAgICBzdGF0ZS5saXN0ZW5lcignY2xvc2UnLCBzdGF0ZSk7XG4gIH1cbiAgcmV0dXJuIHN0YXRlLnRhZyAhPT0gbnVsbCB8fCAgc3RhdGUuYW5jaG9yICE9PSBudWxsIHx8IGhhc0NvbnRlbnQ7XG59XG5cbmZ1bmN0aW9uIHJlYWREb2N1bWVudChzdGF0ZSkge1xuICB2YXIgZG9jdW1lbnRTdGFydCA9IHN0YXRlLnBvc2l0aW9uLFxuICAgICAgX3Bvc2l0aW9uLFxuICAgICAgZGlyZWN0aXZlTmFtZSxcbiAgICAgIGRpcmVjdGl2ZUFyZ3MsXG4gICAgICBoYXNEaXJlY3RpdmVzID0gZmFsc2UsXG4gICAgICBjaDtcblxuICBzdGF0ZS52ZXJzaW9uID0gbnVsbDtcbiAgc3RhdGUuY2hlY2tMaW5lQnJlYWtzID0gc3RhdGUubGVnYWN5O1xuICBzdGF0ZS50YWdNYXAgPSB7fTtcbiAgc3RhdGUuYW5jaG9yTWFwID0ge307XG5cbiAgd2hpbGUgKChjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pKSAhPT0gMCkge1xuICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTtcblxuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICBpZiAoc3RhdGUubGluZUluZGVudCA+IDAgfHwgY2ggIT09IDB4MjUvKiAlICovKSB7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBoYXNEaXJlY3RpdmVzID0gdHJ1ZTtcbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb247XG5cbiAgICB3aGlsZSAoY2ggIT09IDAgJiYgIWlzX1dTX09SX0VPTChjaCkpIHtcbiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgICB9XG5cbiAgICBkaXJlY3RpdmVOYW1lID0gc3RhdGUuaW5wdXQuc2xpY2UoX3Bvc2l0aW9uLCBzdGF0ZS5wb3NpdGlvbik7XG4gICAgZGlyZWN0aXZlQXJncyA9IFtdO1xuXG4gICAgaWYgKGRpcmVjdGl2ZU5hbWUubGVuZ3RoIDwgMSkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2RpcmVjdGl2ZSBuYW1lIG11c3Qgbm90IGJlIGxlc3MgdGhhbiBvbmUgY2hhcmFjdGVyIGluIGxlbmd0aCcpO1xuICAgIH1cblxuICAgIHdoaWxlIChjaCAhPT0gMCkge1xuICAgICAgd2hpbGUgKGlzX1dISVRFX1NQQUNFKGNoKSkge1xuICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgICB9XG5cbiAgICAgIGlmIChjaCA9PT0gMHgyMy8qICMgKi8pIHtcbiAgICAgICAgZG8geyBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7IH1cbiAgICAgICAgd2hpbGUgKGNoICE9PSAwICYmICFpc19FT0woY2gpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc19FT0woY2gpKSBicmVhaztcblxuICAgICAgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb247XG5cbiAgICAgIHdoaWxlIChjaCAhPT0gMCAmJiAhaXNfV1NfT1JfRU9MKGNoKSkge1xuICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgICB9XG5cbiAgICAgIGRpcmVjdGl2ZUFyZ3MucHVzaChzdGF0ZS5pbnB1dC5zbGljZShfcG9zaXRpb24sIHN0YXRlLnBvc2l0aW9uKSk7XG4gICAgfVxuXG4gICAgaWYgKGNoICE9PSAwKSByZWFkTGluZUJyZWFrKHN0YXRlKTtcblxuICAgIGlmIChfaGFzT3duUHJvcGVydHkuY2FsbChkaXJlY3RpdmVIYW5kbGVycywgZGlyZWN0aXZlTmFtZSkpIHtcbiAgICAgIGRpcmVjdGl2ZUhhbmRsZXJzW2RpcmVjdGl2ZU5hbWVdKHN0YXRlLCBkaXJlY3RpdmVOYW1lLCBkaXJlY3RpdmVBcmdzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3dXYXJuaW5nKHN0YXRlLCAndW5rbm93biBkb2N1bWVudCBkaXJlY3RpdmUgXCInICsgZGlyZWN0aXZlTmFtZSArICdcIicpO1xuICAgIH1cbiAgfVxuXG4gIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTtcblxuICBpZiAoc3RhdGUubGluZUluZGVudCA9PT0gMCAmJlxuICAgICAgc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbikgICAgID09PSAweDJELyogLSAqLyAmJlxuICAgICAgc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbiArIDEpID09PSAweDJELyogLSAqLyAmJlxuICAgICAgc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbiArIDIpID09PSAweDJELyogLSAqLykge1xuICAgIHN0YXRlLnBvc2l0aW9uICs9IDM7XG4gICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpO1xuXG4gIH0gZWxzZSBpZiAoaGFzRGlyZWN0aXZlcykge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICdkaXJlY3RpdmVzIGVuZCBtYXJrIGlzIGV4cGVjdGVkJyk7XG4gIH1cblxuICBjb21wb3NlTm9kZShzdGF0ZSwgc3RhdGUubGluZUluZGVudCAtIDEsIENPTlRFWFRfQkxPQ0tfT1VULCBmYWxzZSwgdHJ1ZSk7XG4gIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTtcblxuICBpZiAoc3RhdGUuY2hlY2tMaW5lQnJlYWtzICYmXG4gICAgICBQQVRURVJOX05PTl9BU0NJSV9MSU5FX0JSRUFLUy50ZXN0KHN0YXRlLmlucHV0LnNsaWNlKGRvY3VtZW50U3RhcnQsIHN0YXRlLnBvc2l0aW9uKSkpIHtcbiAgICB0aHJvd1dhcm5pbmcoc3RhdGUsICdub24tQVNDSUkgbGluZSBicmVha3MgYXJlIGludGVycHJldGVkIGFzIGNvbnRlbnQnKTtcbiAgfVxuXG4gIHN0YXRlLmRvY3VtZW50cy5wdXNoKHN0YXRlLnJlc3VsdCk7XG5cbiAgaWYgKHN0YXRlLnBvc2l0aW9uID09PSBzdGF0ZS5saW5lU3RhcnQgJiYgdGVzdERvY3VtZW50U2VwYXJhdG9yKHN0YXRlKSkge1xuXG4gICAgaWYgKHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pID09PSAweDJFLyogLiAqLykge1xuICAgICAgc3RhdGUucG9zaXRpb24gKz0gMztcbiAgICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTtcbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKHN0YXRlLnBvc2l0aW9uIDwgKHN0YXRlLmxlbmd0aCAtIDEpKSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2VuZCBvZiB0aGUgc3RyZWFtIG9yIGEgZG9jdW1lbnQgc2VwYXJhdG9yIGlzIGV4cGVjdGVkJyk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuO1xuICB9XG59XG5cblxuZnVuY3Rpb24gbG9hZERvY3VtZW50cyhpbnB1dCwgb3B0aW9ucykge1xuICBpbnB1dCA9IFN0cmluZyhpbnB1dCk7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIGlmIChpbnB1dC5sZW5ndGggIT09IDApIHtcblxuICAgIC8vIEFkZCB0YWlsaW5nIGBcXG5gIGlmIG5vdCBleGlzdHNcbiAgICBpZiAoaW5wdXQuY2hhckNvZGVBdChpbnB1dC5sZW5ndGggLSAxKSAhPT0gMHgwQS8qIExGICovICYmXG4gICAgICAgIGlucHV0LmNoYXJDb2RlQXQoaW5wdXQubGVuZ3RoIC0gMSkgIT09IDB4MEQvKiBDUiAqLykge1xuICAgICAgaW5wdXQgKz0gJ1xcbic7XG4gICAgfVxuXG4gICAgLy8gU3RyaXAgQk9NXG4gICAgaWYgKGlucHV0LmNoYXJDb2RlQXQoMCkgPT09IDB4RkVGRikge1xuICAgICAgaW5wdXQgPSBpbnB1dC5zbGljZSgxKTtcbiAgICB9XG4gIH1cblxuICB2YXIgc3RhdGUgPSBuZXcgU3RhdGUoaW5wdXQsIG9wdGlvbnMpO1xuXG4gIC8vIFVzZSAwIGFzIHN0cmluZyB0ZXJtaW5hdG9yLiBUaGF0IHNpZ25pZmljYW50bHkgc2ltcGxpZmllcyBib3VuZHMgY2hlY2suXG4gIHN0YXRlLmlucHV0ICs9ICdcXDAnO1xuXG4gIHdoaWxlIChzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKSA9PT0gMHgyMC8qIFNwYWNlICovKSB7XG4gICAgc3RhdGUubGluZUluZGVudCArPSAxO1xuICAgIHN0YXRlLnBvc2l0aW9uICs9IDE7XG4gIH1cblxuICB3aGlsZSAoc3RhdGUucG9zaXRpb24gPCAoc3RhdGUubGVuZ3RoIC0gMSkpIHtcbiAgICByZWFkRG9jdW1lbnQoc3RhdGUpO1xuICB9XG5cbiAgcmV0dXJuIHN0YXRlLmRvY3VtZW50cztcbn1cblxuXG5mdW5jdGlvbiBsb2FkQWxsKGlucHV0LCBpdGVyYXRvciwgb3B0aW9ucykge1xuICB2YXIgZG9jdW1lbnRzID0gbG9hZERvY3VtZW50cyhpbnB1dCwgb3B0aW9ucyksIGluZGV4LCBsZW5ndGg7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IGRvY3VtZW50cy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgaXRlcmF0b3IoZG9jdW1lbnRzW2luZGV4XSk7XG4gIH1cbn1cblxuXG5mdW5jdGlvbiBsb2FkKGlucHV0LCBvcHRpb25zKSB7XG4gIHZhciBkb2N1bWVudHMgPSBsb2FkRG9jdW1lbnRzKGlucHV0LCBvcHRpb25zKTtcblxuICBpZiAoZG9jdW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgIC8qZXNsaW50LWRpc2FibGUgbm8tdW5kZWZpbmVkKi9cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9IGVsc2UgaWYgKGRvY3VtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICByZXR1cm4gZG9jdW1lbnRzWzBdO1xuICB9XG4gIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdleHBlY3RlZCBhIHNpbmdsZSBkb2N1bWVudCBpbiB0aGUgc3RyZWFtLCBidXQgZm91bmQgbW9yZScpO1xufVxuXG5cbmZ1bmN0aW9uIHNhZmVMb2FkQWxsKGlucHV0LCBvdXRwdXQsIG9wdGlvbnMpIHtcbiAgbG9hZEFsbChpbnB1dCwgb3V0cHV0LCBjb21tb24uZXh0ZW5kKHsgc2NoZW1hOiBERUZBVUxUX1NBRkVfU0NIRU1BIH0sIG9wdGlvbnMpKTtcbn1cblxuXG5mdW5jdGlvbiBzYWZlTG9hZChpbnB1dCwgb3B0aW9ucykge1xuICByZXR1cm4gbG9hZChpbnB1dCwgY29tbW9uLmV4dGVuZCh7IHNjaGVtYTogREVGQVVMVF9TQUZFX1NDSEVNQSB9LCBvcHRpb25zKSk7XG59XG5cblxubW9kdWxlLmV4cG9ydHMubG9hZEFsbCAgICAgPSBsb2FkQWxsO1xubW9kdWxlLmV4cG9ydHMubG9hZCAgICAgICAgPSBsb2FkO1xubW9kdWxlLmV4cG9ydHMuc2FmZUxvYWRBbGwgPSBzYWZlTG9hZEFsbDtcbm1vZHVsZS5leHBvcnRzLnNhZmVMb2FkICAgID0gc2FmZUxvYWQ7XG4iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG5cblxuZnVuY3Rpb24gTWFyayhuYW1lLCBidWZmZXIsIHBvc2l0aW9uLCBsaW5lLCBjb2x1bW4pIHtcbiAgdGhpcy5uYW1lICAgICA9IG5hbWU7XG4gIHRoaXMuYnVmZmVyICAgPSBidWZmZXI7XG4gIHRoaXMucG9zaXRpb24gPSBwb3NpdGlvbjtcbiAgdGhpcy5saW5lICAgICA9IGxpbmU7XG4gIHRoaXMuY29sdW1uICAgPSBjb2x1bW47XG59XG5cblxuTWFyay5wcm90b3R5cGUuZ2V0U25pcHBldCA9IGZ1bmN0aW9uIGdldFNuaXBwZXQoaW5kZW50LCBtYXhMZW5ndGgpIHtcbiAgdmFyIGhlYWQsIHN0YXJ0LCB0YWlsLCBlbmQsIHNuaXBwZXQ7XG5cbiAgaWYgKCF0aGlzLmJ1ZmZlcikgcmV0dXJuIG51bGw7XG5cbiAgaW5kZW50ID0gaW5kZW50IHx8IDQ7XG4gIG1heExlbmd0aCA9IG1heExlbmd0aCB8fCA3NTtcblxuICBoZWFkID0gJyc7XG4gIHN0YXJ0ID0gdGhpcy5wb3NpdGlvbjtcblxuICB3aGlsZSAoc3RhcnQgPiAwICYmICdcXHgwMFxcclxcblxceDg1XFx1MjAyOFxcdTIwMjknLmluZGV4T2YodGhpcy5idWZmZXIuY2hhckF0KHN0YXJ0IC0gMSkpID09PSAtMSkge1xuICAgIHN0YXJ0IC09IDE7XG4gICAgaWYgKHRoaXMucG9zaXRpb24gLSBzdGFydCA+IChtYXhMZW5ndGggLyAyIC0gMSkpIHtcbiAgICAgIGhlYWQgPSAnIC4uLiAnO1xuICAgICAgc3RhcnQgKz0gNTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHRhaWwgPSAnJztcbiAgZW5kID0gdGhpcy5wb3NpdGlvbjtcblxuICB3aGlsZSAoZW5kIDwgdGhpcy5idWZmZXIubGVuZ3RoICYmICdcXHgwMFxcclxcblxceDg1XFx1MjAyOFxcdTIwMjknLmluZGV4T2YodGhpcy5idWZmZXIuY2hhckF0KGVuZCkpID09PSAtMSkge1xuICAgIGVuZCArPSAxO1xuICAgIGlmIChlbmQgLSB0aGlzLnBvc2l0aW9uID4gKG1heExlbmd0aCAvIDIgLSAxKSkge1xuICAgICAgdGFpbCA9ICcgLi4uICc7XG4gICAgICBlbmQgLT0gNTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHNuaXBwZXQgPSB0aGlzLmJ1ZmZlci5zbGljZShzdGFydCwgZW5kKTtcblxuICByZXR1cm4gY29tbW9uLnJlcGVhdCgnICcsIGluZGVudCkgKyBoZWFkICsgc25pcHBldCArIHRhaWwgKyAnXFxuJyArXG4gICAgICAgICBjb21tb24ucmVwZWF0KCcgJywgaW5kZW50ICsgdGhpcy5wb3NpdGlvbiAtIHN0YXJ0ICsgaGVhZC5sZW5ndGgpICsgJ14nO1xufTtcblxuXG5NYXJrLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKGNvbXBhY3QpIHtcbiAgdmFyIHNuaXBwZXQsIHdoZXJlID0gJyc7XG5cbiAgaWYgKHRoaXMubmFtZSkge1xuICAgIHdoZXJlICs9ICdpbiBcIicgKyB0aGlzLm5hbWUgKyAnXCIgJztcbiAgfVxuXG4gIHdoZXJlICs9ICdhdCBsaW5lICcgKyAodGhpcy5saW5lICsgMSkgKyAnLCBjb2x1bW4gJyArICh0aGlzLmNvbHVtbiArIDEpO1xuXG4gIGlmICghY29tcGFjdCkge1xuICAgIHNuaXBwZXQgPSB0aGlzLmdldFNuaXBwZXQoKTtcblxuICAgIGlmIChzbmlwcGV0KSB7XG4gICAgICB3aGVyZSArPSAnOlxcbicgKyBzbmlwcGV0O1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB3aGVyZTtcbn07XG5cblxubW9kdWxlLmV4cG9ydHMgPSBNYXJrO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKmVzbGludC1kaXNhYmxlIG1heC1sZW4qL1xuXG52YXIgY29tbW9uICAgICAgICA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgWUFNTEV4Y2VwdGlvbiA9IHJlcXVpcmUoJy4vZXhjZXB0aW9uJyk7XG52YXIgVHlwZSAgICAgICAgICA9IHJlcXVpcmUoJy4vdHlwZScpO1xuXG5cbmZ1bmN0aW9uIGNvbXBpbGVMaXN0KHNjaGVtYSwgbmFtZSwgcmVzdWx0KSB7XG4gIHZhciBleGNsdWRlID0gW107XG5cbiAgc2NoZW1hLmluY2x1ZGUuZm9yRWFjaChmdW5jdGlvbiAoaW5jbHVkZWRTY2hlbWEpIHtcbiAgICByZXN1bHQgPSBjb21waWxlTGlzdChpbmNsdWRlZFNjaGVtYSwgbmFtZSwgcmVzdWx0KTtcbiAgfSk7XG5cbiAgc2NoZW1hW25hbWVdLmZvckVhY2goZnVuY3Rpb24gKGN1cnJlbnRUeXBlKSB7XG4gICAgcmVzdWx0LmZvckVhY2goZnVuY3Rpb24gKHByZXZpb3VzVHlwZSwgcHJldmlvdXNJbmRleCkge1xuICAgICAgaWYgKHByZXZpb3VzVHlwZS50YWcgPT09IGN1cnJlbnRUeXBlLnRhZykge1xuICAgICAgICBleGNsdWRlLnB1c2gocHJldmlvdXNJbmRleCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXN1bHQucHVzaChjdXJyZW50VHlwZSk7XG4gIH0pO1xuXG4gIHJldHVybiByZXN1bHQuZmlsdGVyKGZ1bmN0aW9uICh0eXBlLCBpbmRleCkge1xuICAgIHJldHVybiBleGNsdWRlLmluZGV4T2YoaW5kZXgpID09PSAtMTtcbiAgfSk7XG59XG5cblxuZnVuY3Rpb24gY29tcGlsZU1hcCgvKiBsaXN0cy4uLiAqLykge1xuICB2YXIgcmVzdWx0ID0ge30sIGluZGV4LCBsZW5ndGg7XG5cbiAgZnVuY3Rpb24gY29sbGVjdFR5cGUodHlwZSkge1xuICAgIHJlc3VsdFt0eXBlLnRhZ10gPSB0eXBlO1xuICB9XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgYXJndW1lbnRzW2luZGV4XS5mb3JFYWNoKGNvbGxlY3RUeXBlKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cblxuZnVuY3Rpb24gU2NoZW1hKGRlZmluaXRpb24pIHtcbiAgdGhpcy5pbmNsdWRlICA9IGRlZmluaXRpb24uaW5jbHVkZSAgfHwgW107XG4gIHRoaXMuaW1wbGljaXQgPSBkZWZpbml0aW9uLmltcGxpY2l0IHx8IFtdO1xuICB0aGlzLmV4cGxpY2l0ID0gZGVmaW5pdGlvbi5leHBsaWNpdCB8fCBbXTtcblxuICB0aGlzLmltcGxpY2l0LmZvckVhY2goZnVuY3Rpb24gKHR5cGUpIHtcbiAgICBpZiAodHlwZS5sb2FkS2luZCAmJiB0eXBlLmxvYWRLaW5kICE9PSAnc2NhbGFyJykge1xuICAgICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ1RoZXJlIGlzIGEgbm9uLXNjYWxhciB0eXBlIGluIHRoZSBpbXBsaWNpdCBsaXN0IG9mIGEgc2NoZW1hLiBJbXBsaWNpdCByZXNvbHZpbmcgb2Ygc3VjaCB0eXBlcyBpcyBub3Qgc3VwcG9ydGVkLicpO1xuICAgIH1cbiAgfSk7XG5cbiAgdGhpcy5jb21waWxlZEltcGxpY2l0ID0gY29tcGlsZUxpc3QodGhpcywgJ2ltcGxpY2l0JywgW10pO1xuICB0aGlzLmNvbXBpbGVkRXhwbGljaXQgPSBjb21waWxlTGlzdCh0aGlzLCAnZXhwbGljaXQnLCBbXSk7XG4gIHRoaXMuY29tcGlsZWRUeXBlTWFwICA9IGNvbXBpbGVNYXAodGhpcy5jb21waWxlZEltcGxpY2l0LCB0aGlzLmNvbXBpbGVkRXhwbGljaXQpO1xufVxuXG5cblNjaGVtYS5ERUZBVUxUID0gbnVsbDtcblxuXG5TY2hlbWEuY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlU2NoZW1hKCkge1xuICB2YXIgc2NoZW1hcywgdHlwZXM7XG5cbiAgc3dpdGNoIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgY2FzZSAxOlxuICAgICAgc2NoZW1hcyA9IFNjaGVtYS5ERUZBVUxUO1xuICAgICAgdHlwZXMgPSBhcmd1bWVudHNbMF07XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgMjpcbiAgICAgIHNjaGVtYXMgPSBhcmd1bWVudHNbMF07XG4gICAgICB0eXBlcyA9IGFyZ3VtZW50c1sxXTtcbiAgICAgIGJyZWFrO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdXcm9uZyBudW1iZXIgb2YgYXJndW1lbnRzIGZvciBTY2hlbWEuY3JlYXRlIGZ1bmN0aW9uJyk7XG4gIH1cblxuICBzY2hlbWFzID0gY29tbW9uLnRvQXJyYXkoc2NoZW1hcyk7XG4gIHR5cGVzID0gY29tbW9uLnRvQXJyYXkodHlwZXMpO1xuXG4gIGlmICghc2NoZW1hcy5ldmVyeShmdW5jdGlvbiAoc2NoZW1hKSB7IHJldHVybiBzY2hlbWEgaW5zdGFuY2VvZiBTY2hlbWE7IH0pKSB7XG4gICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ1NwZWNpZmllZCBsaXN0IG9mIHN1cGVyIHNjaGVtYXMgKG9yIGEgc2luZ2xlIFNjaGVtYSBvYmplY3QpIGNvbnRhaW5zIGEgbm9uLVNjaGVtYSBvYmplY3QuJyk7XG4gIH1cblxuICBpZiAoIXR5cGVzLmV2ZXJ5KGZ1bmN0aW9uICh0eXBlKSB7IHJldHVybiB0eXBlIGluc3RhbmNlb2YgVHlwZTsgfSkpIHtcbiAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignU3BlY2lmaWVkIGxpc3Qgb2YgWUFNTCB0eXBlcyAob3IgYSBzaW5nbGUgVHlwZSBvYmplY3QpIGNvbnRhaW5zIGEgbm9uLVR5cGUgb2JqZWN0LicpO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBTY2hlbWEoe1xuICAgIGluY2x1ZGU6IHNjaGVtYXMsXG4gICAgZXhwbGljaXQ6IHR5cGVzXG4gIH0pO1xufTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IFNjaGVtYTtcbiIsIi8vIFN0YW5kYXJkIFlBTUwncyBDb3JlIHNjaGVtYS5cbi8vIGh0dHA6Ly93d3cueWFtbC5vcmcvc3BlYy8xLjIvc3BlYy5odG1sI2lkMjgwNDkyM1xuLy9cbi8vIE5PVEU6IEpTLVlBTUwgZG9lcyBub3Qgc3VwcG9ydCBzY2hlbWEtc3BlY2lmaWMgdGFnIHJlc29sdXRpb24gcmVzdHJpY3Rpb25zLlxuLy8gU28sIENvcmUgc2NoZW1hIGhhcyBubyBkaXN0aW5jdGlvbnMgZnJvbSBKU09OIHNjaGVtYSBpcyBKUy1ZQU1MLlxuXG5cbid1c2Ugc3RyaWN0JztcblxuXG52YXIgU2NoZW1hID0gcmVxdWlyZSgnLi4vc2NoZW1hJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgU2NoZW1hKHtcbiAgaW5jbHVkZTogW1xuICAgIHJlcXVpcmUoJy4vanNvbicpXG4gIF1cbn0pO1xuIiwiLy8gSlMtWUFNTCdzIGRlZmF1bHQgc2NoZW1hIGZvciBgbG9hZGAgZnVuY3Rpb24uXG4vLyBJdCBpcyBub3QgZGVzY3JpYmVkIGluIHRoZSBZQU1MIHNwZWNpZmljYXRpb24uXG4vL1xuLy8gVGhpcyBzY2hlbWEgaXMgYmFzZWQgb24gSlMtWUFNTCdzIGRlZmF1bHQgc2FmZSBzY2hlbWEgYW5kIGluY2x1ZGVzXG4vLyBKYXZhU2NyaXB0LXNwZWNpZmljIHR5cGVzOiAhIWpzL3VuZGVmaW5lZCwgISFqcy9yZWdleHAgYW5kICEhanMvZnVuY3Rpb24uXG4vL1xuLy8gQWxzbyB0aGlzIHNjaGVtYSBpcyB1c2VkIGFzIGRlZmF1bHQgYmFzZSBzY2hlbWEgYXQgYFNjaGVtYS5jcmVhdGVgIGZ1bmN0aW9uLlxuXG5cbid1c2Ugc3RyaWN0JztcblxuXG52YXIgU2NoZW1hID0gcmVxdWlyZSgnLi4vc2NoZW1hJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBTY2hlbWEuREVGQVVMVCA9IG5ldyBTY2hlbWEoe1xuICBpbmNsdWRlOiBbXG4gICAgcmVxdWlyZSgnLi9kZWZhdWx0X3NhZmUnKVxuICBdLFxuICBleHBsaWNpdDogW1xuICAgIHJlcXVpcmUoJy4uL3R5cGUvanMvdW5kZWZpbmVkJyksXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9qcy9yZWdleHAnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL2pzL2Z1bmN0aW9uJylcbiAgXVxufSk7XG4iLCIvLyBKUy1ZQU1MJ3MgZGVmYXVsdCBzY2hlbWEgZm9yIGBzYWZlTG9hZGAgZnVuY3Rpb24uXG4vLyBJdCBpcyBub3QgZGVzY3JpYmVkIGluIHRoZSBZQU1MIHNwZWNpZmljYXRpb24uXG4vL1xuLy8gVGhpcyBzY2hlbWEgaXMgYmFzZWQgb24gc3RhbmRhcmQgWUFNTCdzIENvcmUgc2NoZW1hIGFuZCBpbmNsdWRlcyBtb3N0IG9mXG4vLyBleHRyYSB0eXBlcyBkZXNjcmliZWQgYXQgWUFNTCB0YWcgcmVwb3NpdG9yeS4gKGh0dHA6Ly95YW1sLm9yZy90eXBlLylcblxuXG4ndXNlIHN0cmljdCc7XG5cblxudmFyIFNjaGVtYSA9IHJlcXVpcmUoJy4uL3NjaGVtYScpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFNjaGVtYSh7XG4gIGluY2x1ZGU6IFtcbiAgICByZXF1aXJlKCcuL2NvcmUnKVxuICBdLFxuICBpbXBsaWNpdDogW1xuICAgIHJlcXVpcmUoJy4uL3R5cGUvdGltZXN0YW1wJyksXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9tZXJnZScpXG4gIF0sXG4gIGV4cGxpY2l0OiBbXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9iaW5hcnknKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL29tYXAnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL3BhaXJzJyksXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9zZXQnKVxuICBdXG59KTtcbiIsIi8vIFN0YW5kYXJkIFlBTUwncyBGYWlsc2FmZSBzY2hlbWEuXG4vLyBodHRwOi8vd3d3LnlhbWwub3JnL3NwZWMvMS4yL3NwZWMuaHRtbCNpZDI4MDIzNDZcblxuXG4ndXNlIHN0cmljdCc7XG5cblxudmFyIFNjaGVtYSA9IHJlcXVpcmUoJy4uL3NjaGVtYScpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFNjaGVtYSh7XG4gIGV4cGxpY2l0OiBbXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9zdHInKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL3NlcScpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvbWFwJylcbiAgXVxufSk7XG4iLCIvLyBTdGFuZGFyZCBZQU1MJ3MgSlNPTiBzY2hlbWEuXG4vLyBodHRwOi8vd3d3LnlhbWwub3JnL3NwZWMvMS4yL3NwZWMuaHRtbCNpZDI4MDMyMzFcbi8vXG4vLyBOT1RFOiBKUy1ZQU1MIGRvZXMgbm90IHN1cHBvcnQgc2NoZW1hLXNwZWNpZmljIHRhZyByZXNvbHV0aW9uIHJlc3RyaWN0aW9ucy5cbi8vIFNvLCB0aGlzIHNjaGVtYSBpcyBub3Qgc3VjaCBzdHJpY3QgYXMgZGVmaW5lZCBpbiB0aGUgWUFNTCBzcGVjaWZpY2F0aW9uLlxuLy8gSXQgYWxsb3dzIG51bWJlcnMgaW4gYmluYXJ5IG5vdGFpb24sIHVzZSBgTnVsbGAgYW5kIGBOVUxMYCBhcyBgbnVsbGAsIGV0Yy5cblxuXG4ndXNlIHN0cmljdCc7XG5cblxudmFyIFNjaGVtYSA9IHJlcXVpcmUoJy4uL3NjaGVtYScpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFNjaGVtYSh7XG4gIGluY2x1ZGU6IFtcbiAgICByZXF1aXJlKCcuL2ZhaWxzYWZlJylcbiAgXSxcbiAgaW1wbGljaXQ6IFtcbiAgICByZXF1aXJlKCcuLi90eXBlL251bGwnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL2Jvb2wnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL2ludCcpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvZmxvYXQnKVxuICBdXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFlBTUxFeGNlcHRpb24gPSByZXF1aXJlKCcuL2V4Y2VwdGlvbicpO1xuXG52YXIgVFlQRV9DT05TVFJVQ1RPUl9PUFRJT05TID0gW1xuICAna2luZCcsXG4gICdyZXNvbHZlJyxcbiAgJ2NvbnN0cnVjdCcsXG4gICdpbnN0YW5jZU9mJyxcbiAgJ3ByZWRpY2F0ZScsXG4gICdyZXByZXNlbnQnLFxuICAnZGVmYXVsdFN0eWxlJyxcbiAgJ3N0eWxlQWxpYXNlcydcbl07XG5cbnZhciBZQU1MX05PREVfS0lORFMgPSBbXG4gICdzY2FsYXInLFxuICAnc2VxdWVuY2UnLFxuICAnbWFwcGluZydcbl07XG5cbmZ1bmN0aW9uIGNvbXBpbGVTdHlsZUFsaWFzZXMobWFwKSB7XG4gIHZhciByZXN1bHQgPSB7fTtcblxuICBpZiAobWFwICE9PSBudWxsKSB7XG4gICAgT2JqZWN0LmtleXMobWFwKS5mb3JFYWNoKGZ1bmN0aW9uIChzdHlsZSkge1xuICAgICAgbWFwW3N0eWxlXS5mb3JFYWNoKGZ1bmN0aW9uIChhbGlhcykge1xuICAgICAgICByZXN1bHRbU3RyaW5nKGFsaWFzKV0gPSBzdHlsZTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gVHlwZSh0YWcsIG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgT2JqZWN0LmtleXMob3B0aW9ucykuZm9yRWFjaChmdW5jdGlvbiAobmFtZSkge1xuICAgIGlmIChUWVBFX0NPTlNUUlVDVE9SX09QVElPTlMuaW5kZXhPZihuYW1lKSA9PT0gLTEpIHtcbiAgICAgIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdVbmtub3duIG9wdGlvbiBcIicgKyBuYW1lICsgJ1wiIGlzIG1ldCBpbiBkZWZpbml0aW9uIG9mIFwiJyArIHRhZyArICdcIiBZQU1MIHR5cGUuJyk7XG4gICAgfVxuICB9KTtcblxuICAvLyBUT0RPOiBBZGQgdGFnIGZvcm1hdCBjaGVjay5cbiAgdGhpcy50YWcgICAgICAgICAgPSB0YWc7XG4gIHRoaXMua2luZCAgICAgICAgID0gb3B0aW9uc1sna2luZCddICAgICAgICAgfHwgbnVsbDtcbiAgdGhpcy5yZXNvbHZlICAgICAgPSBvcHRpb25zWydyZXNvbHZlJ10gICAgICB8fCBmdW5jdGlvbiAoKSB7IHJldHVybiB0cnVlOyB9O1xuICB0aGlzLmNvbnN0cnVjdCAgICA9IG9wdGlvbnNbJ2NvbnN0cnVjdCddICAgIHx8IGZ1bmN0aW9uIChkYXRhKSB7IHJldHVybiBkYXRhOyB9O1xuICB0aGlzLmluc3RhbmNlT2YgICA9IG9wdGlvbnNbJ2luc3RhbmNlT2YnXSAgIHx8IG51bGw7XG4gIHRoaXMucHJlZGljYXRlICAgID0gb3B0aW9uc1sncHJlZGljYXRlJ10gICAgfHwgbnVsbDtcbiAgdGhpcy5yZXByZXNlbnQgICAgPSBvcHRpb25zWydyZXByZXNlbnQnXSAgICB8fCBudWxsO1xuICB0aGlzLmRlZmF1bHRTdHlsZSA9IG9wdGlvbnNbJ2RlZmF1bHRTdHlsZSddIHx8IG51bGw7XG4gIHRoaXMuc3R5bGVBbGlhc2VzID0gY29tcGlsZVN0eWxlQWxpYXNlcyhvcHRpb25zWydzdHlsZUFsaWFzZXMnXSB8fCBudWxsKTtcblxuICBpZiAoWUFNTF9OT0RFX0tJTkRTLmluZGV4T2YodGhpcy5raW5kKSA9PT0gLTEpIHtcbiAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignVW5rbm93biBraW5kIFwiJyArIHRoaXMua2luZCArICdcIiBpcyBzcGVjaWZpZWQgZm9yIFwiJyArIHRhZyArICdcIiBZQU1MIHR5cGUuJyk7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBUeXBlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKmVzbGludC1kaXNhYmxlIG5vLWJpdHdpc2UqL1xuXG4vLyBBIHRyaWNrIGZvciBicm93c2VyaWZpZWQgdmVyc2lvbi5cbi8vIFNpbmNlIHdlIG1ha2UgYnJvd3NlcmlmaWVyIHRvIGlnbm9yZSBgYnVmZmVyYCBtb2R1bGUsIE5vZGVCdWZmZXIgd2lsbCBiZSB1bmRlZmluZWRcbnZhciBOb2RlQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xudmFyIFR5cGUgICAgICAgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cblxuLy8gWyA2NCwgNjUsIDY2IF0gLT4gWyBwYWRkaW5nLCBDUiwgTEYgXVxudmFyIEJBU0U2NF9NQVAgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLz1cXG5cXHInO1xuXG5cbmZ1bmN0aW9uIHJlc29sdmVZYW1sQmluYXJ5KGRhdGEpIHtcbiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiBmYWxzZTtcblxuICB2YXIgY29kZSwgaWR4LCBiaXRsZW4gPSAwLCBtYXggPSBkYXRhLmxlbmd0aCwgbWFwID0gQkFTRTY0X01BUDtcblxuICAvLyBDb252ZXJ0IG9uZSBieSBvbmUuXG4gIGZvciAoaWR4ID0gMDsgaWR4IDwgbWF4OyBpZHgrKykge1xuICAgIGNvZGUgPSBtYXAuaW5kZXhPZihkYXRhLmNoYXJBdChpZHgpKTtcblxuICAgIC8vIFNraXAgQ1IvTEZcbiAgICBpZiAoY29kZSA+IDY0KSBjb250aW51ZTtcblxuICAgIC8vIEZhaWwgb24gaWxsZWdhbCBjaGFyYWN0ZXJzXG4gICAgaWYgKGNvZGUgPCAwKSByZXR1cm4gZmFsc2U7XG5cbiAgICBiaXRsZW4gKz0gNjtcbiAgfVxuXG4gIC8vIElmIHRoZXJlIGFyZSBhbnkgYml0cyBsZWZ0LCBzb3VyY2Ugd2FzIGNvcnJ1cHRlZFxuICByZXR1cm4gKGJpdGxlbiAlIDgpID09PSAwO1xufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RZYW1sQmluYXJ5KGRhdGEpIHtcbiAgdmFyIGlkeCwgdGFpbGJpdHMsXG4gICAgICBpbnB1dCA9IGRhdGEucmVwbGFjZSgvW1xcclxcbj1dL2csICcnKSwgLy8gcmVtb3ZlIENSL0xGICYgcGFkZGluZyB0byBzaW1wbGlmeSBzY2FuXG4gICAgICBtYXggPSBpbnB1dC5sZW5ndGgsXG4gICAgICBtYXAgPSBCQVNFNjRfTUFQLFxuICAgICAgYml0cyA9IDAsXG4gICAgICByZXN1bHQgPSBbXTtcblxuICAvLyBDb2xsZWN0IGJ5IDYqNCBiaXRzICgzIGJ5dGVzKVxuXG4gIGZvciAoaWR4ID0gMDsgaWR4IDwgbWF4OyBpZHgrKykge1xuICAgIGlmICgoaWR4ICUgNCA9PT0gMCkgJiYgaWR4KSB7XG4gICAgICByZXN1bHQucHVzaCgoYml0cyA+PiAxNikgJiAweEZGKTtcbiAgICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDgpICYgMHhGRik7XG4gICAgICByZXN1bHQucHVzaChiaXRzICYgMHhGRik7XG4gICAgfVxuXG4gICAgYml0cyA9IChiaXRzIDw8IDYpIHwgbWFwLmluZGV4T2YoaW5wdXQuY2hhckF0KGlkeCkpO1xuICB9XG5cbiAgLy8gRHVtcCB0YWlsXG5cbiAgdGFpbGJpdHMgPSAobWF4ICUgNCkgKiA2O1xuXG4gIGlmICh0YWlsYml0cyA9PT0gMCkge1xuICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDE2KSAmIDB4RkYpO1xuICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDgpICYgMHhGRik7XG4gICAgcmVzdWx0LnB1c2goYml0cyAmIDB4RkYpO1xuICB9IGVsc2UgaWYgKHRhaWxiaXRzID09PSAxOCkge1xuICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDEwKSAmIDB4RkYpO1xuICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDIpICYgMHhGRik7XG4gIH0gZWxzZSBpZiAodGFpbGJpdHMgPT09IDEyKSB7XG4gICAgcmVzdWx0LnB1c2goKGJpdHMgPj4gNCkgJiAweEZGKTtcbiAgfVxuXG4gIC8vIFdyYXAgaW50byBCdWZmZXIgZm9yIE5vZGVKUyBhbmQgbGVhdmUgQXJyYXkgZm9yIGJyb3dzZXJcbiAgaWYgKE5vZGVCdWZmZXIpIHJldHVybiBuZXcgTm9kZUJ1ZmZlcihyZXN1bHQpO1xuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIHJlcHJlc2VudFlhbWxCaW5hcnkob2JqZWN0IC8qLCBzdHlsZSovKSB7XG4gIHZhciByZXN1bHQgPSAnJywgYml0cyA9IDAsIGlkeCwgdGFpbCxcbiAgICAgIG1heCA9IG9iamVjdC5sZW5ndGgsXG4gICAgICBtYXAgPSBCQVNFNjRfTUFQO1xuXG4gIC8vIENvbnZlcnQgZXZlcnkgdGhyZWUgYnl0ZXMgdG8gNCBBU0NJSSBjaGFyYWN0ZXJzLlxuXG4gIGZvciAoaWR4ID0gMDsgaWR4IDwgbWF4OyBpZHgrKykge1xuICAgIGlmICgoaWR4ICUgMyA9PT0gMCkgJiYgaWR4KSB7XG4gICAgICByZXN1bHQgKz0gbWFwWyhiaXRzID4+IDE4KSAmIDB4M0ZdO1xuICAgICAgcmVzdWx0ICs9IG1hcFsoYml0cyA+PiAxMikgJiAweDNGXTtcbiAgICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gNikgJiAweDNGXTtcbiAgICAgIHJlc3VsdCArPSBtYXBbYml0cyAmIDB4M0ZdO1xuICAgIH1cblxuICAgIGJpdHMgPSAoYml0cyA8PCA4KSArIG9iamVjdFtpZHhdO1xuICB9XG5cbiAgLy8gRHVtcCB0YWlsXG5cbiAgdGFpbCA9IG1heCAlIDM7XG5cbiAgaWYgKHRhaWwgPT09IDApIHtcbiAgICByZXN1bHQgKz0gbWFwWyhiaXRzID4+IDE4KSAmIDB4M0ZdO1xuICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gMTIpICYgMHgzRl07XG4gICAgcmVzdWx0ICs9IG1hcFsoYml0cyA+PiA2KSAmIDB4M0ZdO1xuICAgIHJlc3VsdCArPSBtYXBbYml0cyAmIDB4M0ZdO1xuICB9IGVsc2UgaWYgKHRhaWwgPT09IDIpIHtcbiAgICByZXN1bHQgKz0gbWFwWyhiaXRzID4+IDEwKSAmIDB4M0ZdO1xuICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gNCkgJiAweDNGXTtcbiAgICByZXN1bHQgKz0gbWFwWyhiaXRzIDw8IDIpICYgMHgzRl07XG4gICAgcmVzdWx0ICs9IG1hcFs2NF07XG4gIH0gZWxzZSBpZiAodGFpbCA9PT0gMSkge1xuICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gMikgJiAweDNGXTtcbiAgICByZXN1bHQgKz0gbWFwWyhiaXRzIDw8IDQpICYgMHgzRl07XG4gICAgcmVzdWx0ICs9IG1hcFs2NF07XG4gICAgcmVzdWx0ICs9IG1hcFs2NF07XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBpc0JpbmFyeShvYmplY3QpIHtcbiAgcmV0dXJuIE5vZGVCdWZmZXIgJiYgTm9kZUJ1ZmZlci5pc0J1ZmZlcihvYmplY3QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpiaW5hcnknLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICByZXNvbHZlOiByZXNvbHZlWWFtbEJpbmFyeSxcbiAgY29uc3RydWN0OiBjb25zdHJ1Y3RZYW1sQmluYXJ5LFxuICBwcmVkaWNhdGU6IGlzQmluYXJ5LFxuICByZXByZXNlbnQ6IHJlcHJlc2VudFlhbWxCaW5hcnlcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxCb29sZWFuKGRhdGEpIHtcbiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiBmYWxzZTtcblxuICB2YXIgbWF4ID0gZGF0YS5sZW5ndGg7XG5cbiAgcmV0dXJuIChtYXggPT09IDQgJiYgKGRhdGEgPT09ICd0cnVlJyB8fCBkYXRhID09PSAnVHJ1ZScgfHwgZGF0YSA9PT0gJ1RSVUUnKSkgfHxcbiAgICAgICAgIChtYXggPT09IDUgJiYgKGRhdGEgPT09ICdmYWxzZScgfHwgZGF0YSA9PT0gJ0ZhbHNlJyB8fCBkYXRhID09PSAnRkFMU0UnKSk7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxCb29sZWFuKGRhdGEpIHtcbiAgcmV0dXJuIGRhdGEgPT09ICd0cnVlJyB8fFxuICAgICAgICAgZGF0YSA9PT0gJ1RydWUnIHx8XG4gICAgICAgICBkYXRhID09PSAnVFJVRSc7XG59XG5cbmZ1bmN0aW9uIGlzQm9vbGVhbihvYmplY3QpIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmplY3QpID09PSAnW29iamVjdCBCb29sZWFuXSc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOmJvb2wnLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICByZXNvbHZlOiByZXNvbHZlWWFtbEJvb2xlYW4sXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbEJvb2xlYW4sXG4gIHByZWRpY2F0ZTogaXNCb29sZWFuLFxuICByZXByZXNlbnQ6IHtcbiAgICBsb3dlcmNhc2U6IGZ1bmN0aW9uIChvYmplY3QpIHsgcmV0dXJuIG9iamVjdCA/ICd0cnVlJyA6ICdmYWxzZSc7IH0sXG4gICAgdXBwZXJjYXNlOiBmdW5jdGlvbiAob2JqZWN0KSB7IHJldHVybiBvYmplY3QgPyAnVFJVRScgOiAnRkFMU0UnOyB9LFxuICAgIGNhbWVsY2FzZTogZnVuY3Rpb24gKG9iamVjdCkgeyByZXR1cm4gb2JqZWN0ID8gJ1RydWUnIDogJ0ZhbHNlJzsgfVxuICB9LFxuICBkZWZhdWx0U3R5bGU6ICdsb3dlcmNhc2UnXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4uL2NvbW1vbicpO1xudmFyIFR5cGUgICA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxudmFyIFlBTUxfRkxPQVRfUEFUVEVSTiA9IG5ldyBSZWdFeHAoXG4gICdeKD86Wy0rXT8oPzpbMC05XVswLTlfXSopXFxcXC5bMC05X10qKD86W2VFXVstK11bMC05XSspPycgK1xuICAnfFxcXFwuWzAtOV9dKyg/OltlRV1bLStdWzAtOV0rKT8nICtcbiAgJ3xbLStdP1swLTldWzAtOV9dKig/OjpbMC01XT9bMC05XSkrXFxcXC5bMC05X10qJyArXG4gICd8Wy0rXT9cXFxcLig/OmluZnxJbmZ8SU5GKScgK1xuICAnfFxcXFwuKD86bmFufE5hTnxOQU4pKSQnKTtcblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxGbG9hdChkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gZmFsc2U7XG5cbiAgaWYgKCFZQU1MX0ZMT0FUX1BBVFRFUk4udGVzdChkYXRhKSkgcmV0dXJuIGZhbHNlO1xuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RZYW1sRmxvYXQoZGF0YSkge1xuICB2YXIgdmFsdWUsIHNpZ24sIGJhc2UsIGRpZ2l0cztcblxuICB2YWx1ZSAgPSBkYXRhLnJlcGxhY2UoL18vZywgJycpLnRvTG93ZXJDYXNlKCk7XG4gIHNpZ24gICA9IHZhbHVlWzBdID09PSAnLScgPyAtMSA6IDE7XG4gIGRpZ2l0cyA9IFtdO1xuXG4gIGlmICgnKy0nLmluZGV4T2YodmFsdWVbMF0pID49IDApIHtcbiAgICB2YWx1ZSA9IHZhbHVlLnNsaWNlKDEpO1xuICB9XG5cbiAgaWYgKHZhbHVlID09PSAnLmluZicpIHtcbiAgICByZXR1cm4gKHNpZ24gPT09IDEpID8gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZIDogTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZO1xuXG4gIH0gZWxzZSBpZiAodmFsdWUgPT09ICcubmFuJykge1xuICAgIHJldHVybiBOYU47XG5cbiAgfSBlbHNlIGlmICh2YWx1ZS5pbmRleE9mKCc6JykgPj0gMCkge1xuICAgIHZhbHVlLnNwbGl0KCc6JykuZm9yRWFjaChmdW5jdGlvbiAodikge1xuICAgICAgZGlnaXRzLnVuc2hpZnQocGFyc2VGbG9hdCh2LCAxMCkpO1xuICAgIH0pO1xuXG4gICAgdmFsdWUgPSAwLjA7XG4gICAgYmFzZSA9IDE7XG5cbiAgICBkaWdpdHMuZm9yRWFjaChmdW5jdGlvbiAoZCkge1xuICAgICAgdmFsdWUgKz0gZCAqIGJhc2U7XG4gICAgICBiYXNlICo9IDYwO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHNpZ24gKiB2YWx1ZTtcblxuICB9XG4gIHJldHVybiBzaWduICogcGFyc2VGbG9hdCh2YWx1ZSwgMTApO1xufVxuXG5cbnZhciBTQ0lFTlRJRklDX1dJVEhPVVRfRE9UID0gL15bLStdP1swLTldK2UvO1xuXG5mdW5jdGlvbiByZXByZXNlbnRZYW1sRmxvYXQob2JqZWN0LCBzdHlsZSkge1xuICB2YXIgcmVzO1xuXG4gIGlmIChpc05hTihvYmplY3QpKSB7XG4gICAgc3dpdGNoIChzdHlsZSkge1xuICAgICAgY2FzZSAnbG93ZXJjYXNlJzogcmV0dXJuICcubmFuJztcbiAgICAgIGNhc2UgJ3VwcGVyY2FzZSc6IHJldHVybiAnLk5BTic7XG4gICAgICBjYXNlICdjYW1lbGNhc2UnOiByZXR1cm4gJy5OYU4nO1xuICAgIH1cbiAgfSBlbHNlIGlmIChOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkgPT09IG9iamVjdCkge1xuICAgIHN3aXRjaCAoc3R5bGUpIHtcbiAgICAgIGNhc2UgJ2xvd2VyY2FzZSc6IHJldHVybiAnLmluZic7XG4gICAgICBjYXNlICd1cHBlcmNhc2UnOiByZXR1cm4gJy5JTkYnO1xuICAgICAgY2FzZSAnY2FtZWxjYXNlJzogcmV0dXJuICcuSW5mJztcbiAgICB9XG4gIH0gZWxzZSBpZiAoTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZID09PSBvYmplY3QpIHtcbiAgICBzd2l0Y2ggKHN0eWxlKSB7XG4gICAgICBjYXNlICdsb3dlcmNhc2UnOiByZXR1cm4gJy0uaW5mJztcbiAgICAgIGNhc2UgJ3VwcGVyY2FzZSc6IHJldHVybiAnLS5JTkYnO1xuICAgICAgY2FzZSAnY2FtZWxjYXNlJzogcmV0dXJuICctLkluZic7XG4gICAgfVxuICB9IGVsc2UgaWYgKGNvbW1vbi5pc05lZ2F0aXZlWmVybyhvYmplY3QpKSB7XG4gICAgcmV0dXJuICctMC4wJztcbiAgfVxuXG4gIHJlcyA9IG9iamVjdC50b1N0cmluZygxMCk7XG5cbiAgLy8gSlMgc3RyaW5naWZpZXIgY2FuIGJ1aWxkIHNjaWVudGlmaWMgZm9ybWF0IHdpdGhvdXQgZG90czogNWUtMTAwLFxuICAvLyB3aGlsZSBZQU1MIHJlcXVyZXMgZG90OiA1LmUtMTAwLiBGaXggaXQgd2l0aCBzaW1wbGUgaGFja1xuXG4gIHJldHVybiBTQ0lFTlRJRklDX1dJVEhPVVRfRE9ULnRlc3QocmVzKSA/IHJlcy5yZXBsYWNlKCdlJywgJy5lJykgOiByZXM7XG59XG5cbmZ1bmN0aW9uIGlzRmxvYXQob2JqZWN0KSB7XG4gIHJldHVybiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iamVjdCkgPT09ICdbb2JqZWN0IE51bWJlcl0nKSAmJlxuICAgICAgICAgKG9iamVjdCAlIDEgIT09IDAgfHwgY29tbW9uLmlzTmVnYXRpdmVaZXJvKG9iamVjdCkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpmbG9hdCcsIHtcbiAga2luZDogJ3NjYWxhcicsXG4gIHJlc29sdmU6IHJlc29sdmVZYW1sRmxvYXQsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbEZsb2F0LFxuICBwcmVkaWNhdGU6IGlzRmxvYXQsXG4gIHJlcHJlc2VudDogcmVwcmVzZW50WWFtbEZsb2F0LFxuICBkZWZhdWx0U3R5bGU6ICdsb3dlcmNhc2UnXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4uL2NvbW1vbicpO1xudmFyIFR5cGUgICA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxuZnVuY3Rpb24gaXNIZXhDb2RlKGMpIHtcbiAgcmV0dXJuICgoMHgzMC8qIDAgKi8gPD0gYykgJiYgKGMgPD0gMHgzOS8qIDkgKi8pKSB8fFxuICAgICAgICAgKCgweDQxLyogQSAqLyA8PSBjKSAmJiAoYyA8PSAweDQ2LyogRiAqLykpIHx8XG4gICAgICAgICAoKDB4NjEvKiBhICovIDw9IGMpICYmIChjIDw9IDB4NjYvKiBmICovKSk7XG59XG5cbmZ1bmN0aW9uIGlzT2N0Q29kZShjKSB7XG4gIHJldHVybiAoKDB4MzAvKiAwICovIDw9IGMpICYmIChjIDw9IDB4MzcvKiA3ICovKSk7XG59XG5cbmZ1bmN0aW9uIGlzRGVjQ29kZShjKSB7XG4gIHJldHVybiAoKDB4MzAvKiAwICovIDw9IGMpICYmIChjIDw9IDB4MzkvKiA5ICovKSk7XG59XG5cbmZ1bmN0aW9uIHJlc29sdmVZYW1sSW50ZWdlcihkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gZmFsc2U7XG5cbiAgdmFyIG1heCA9IGRhdGEubGVuZ3RoLFxuICAgICAgaW5kZXggPSAwLFxuICAgICAgaGFzRGlnaXRzID0gZmFsc2UsXG4gICAgICBjaDtcblxuICBpZiAoIW1heCkgcmV0dXJuIGZhbHNlO1xuXG4gIGNoID0gZGF0YVtpbmRleF07XG5cbiAgLy8gc2lnblxuICBpZiAoY2ggPT09ICctJyB8fCBjaCA9PT0gJysnKSB7XG4gICAgY2ggPSBkYXRhWysraW5kZXhdO1xuICB9XG5cbiAgaWYgKGNoID09PSAnMCcpIHtcbiAgICAvLyAwXG4gICAgaWYgKGluZGV4ICsgMSA9PT0gbWF4KSByZXR1cm4gdHJ1ZTtcbiAgICBjaCA9IGRhdGFbKytpbmRleF07XG5cbiAgICAvLyBiYXNlIDIsIGJhc2UgOCwgYmFzZSAxNlxuXG4gICAgaWYgKGNoID09PSAnYicpIHtcbiAgICAgIC8vIGJhc2UgMlxuICAgICAgaW5kZXgrKztcblxuICAgICAgZm9yICg7IGluZGV4IDwgbWF4OyBpbmRleCsrKSB7XG4gICAgICAgIGNoID0gZGF0YVtpbmRleF07XG4gICAgICAgIGlmIChjaCA9PT0gJ18nKSBjb250aW51ZTtcbiAgICAgICAgaWYgKGNoICE9PSAnMCcgJiYgY2ggIT09ICcxJykgcmV0dXJuIGZhbHNlO1xuICAgICAgICBoYXNEaWdpdHMgPSB0cnVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGhhc0RpZ2l0cztcbiAgICB9XG5cblxuICAgIGlmIChjaCA9PT0gJ3gnKSB7XG4gICAgICAvLyBiYXNlIDE2XG4gICAgICBpbmRleCsrO1xuXG4gICAgICBmb3IgKDsgaW5kZXggPCBtYXg7IGluZGV4KyspIHtcbiAgICAgICAgY2ggPSBkYXRhW2luZGV4XTtcbiAgICAgICAgaWYgKGNoID09PSAnXycpIGNvbnRpbnVlO1xuICAgICAgICBpZiAoIWlzSGV4Q29kZShkYXRhLmNoYXJDb2RlQXQoaW5kZXgpKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICBoYXNEaWdpdHMgPSB0cnVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGhhc0RpZ2l0cztcbiAgICB9XG5cbiAgICAvLyBiYXNlIDhcbiAgICBmb3IgKDsgaW5kZXggPCBtYXg7IGluZGV4KyspIHtcbiAgICAgIGNoID0gZGF0YVtpbmRleF07XG4gICAgICBpZiAoY2ggPT09ICdfJykgY29udGludWU7XG4gICAgICBpZiAoIWlzT2N0Q29kZShkYXRhLmNoYXJDb2RlQXQoaW5kZXgpKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgaGFzRGlnaXRzID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGhhc0RpZ2l0cztcbiAgfVxuXG4gIC8vIGJhc2UgMTAgKGV4Y2VwdCAwKSBvciBiYXNlIDYwXG5cbiAgZm9yICg7IGluZGV4IDwgbWF4OyBpbmRleCsrKSB7XG4gICAgY2ggPSBkYXRhW2luZGV4XTtcbiAgICBpZiAoY2ggPT09ICdfJykgY29udGludWU7XG4gICAgaWYgKGNoID09PSAnOicpIGJyZWFrO1xuICAgIGlmICghaXNEZWNDb2RlKGRhdGEuY2hhckNvZGVBdChpbmRleCkpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGhhc0RpZ2l0cyA9IHRydWU7XG4gIH1cblxuICBpZiAoIWhhc0RpZ2l0cykgcmV0dXJuIGZhbHNlO1xuXG4gIC8vIGlmICFiYXNlNjAgLSBkb25lO1xuICBpZiAoY2ggIT09ICc6JykgcmV0dXJuIHRydWU7XG5cbiAgLy8gYmFzZTYwIGFsbW9zdCBub3QgdXNlZCwgbm8gbmVlZHMgdG8gb3B0aW1pemVcbiAgcmV0dXJuIC9eKDpbMC01XT9bMC05XSkrJC8udGVzdChkYXRhLnNsaWNlKGluZGV4KSk7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxJbnRlZ2VyKGRhdGEpIHtcbiAgdmFyIHZhbHVlID0gZGF0YSwgc2lnbiA9IDEsIGNoLCBiYXNlLCBkaWdpdHMgPSBbXTtcblxuICBpZiAodmFsdWUuaW5kZXhPZignXycpICE9PSAtMSkge1xuICAgIHZhbHVlID0gdmFsdWUucmVwbGFjZSgvXy9nLCAnJyk7XG4gIH1cblxuICBjaCA9IHZhbHVlWzBdO1xuXG4gIGlmIChjaCA9PT0gJy0nIHx8IGNoID09PSAnKycpIHtcbiAgICBpZiAoY2ggPT09ICctJykgc2lnbiA9IC0xO1xuICAgIHZhbHVlID0gdmFsdWUuc2xpY2UoMSk7XG4gICAgY2ggPSB2YWx1ZVswXTtcbiAgfVxuXG4gIGlmICh2YWx1ZSA9PT0gJzAnKSByZXR1cm4gMDtcblxuICBpZiAoY2ggPT09ICcwJykge1xuICAgIGlmICh2YWx1ZVsxXSA9PT0gJ2InKSByZXR1cm4gc2lnbiAqIHBhcnNlSW50KHZhbHVlLnNsaWNlKDIpLCAyKTtcbiAgICBpZiAodmFsdWVbMV0gPT09ICd4JykgcmV0dXJuIHNpZ24gKiBwYXJzZUludCh2YWx1ZSwgMTYpO1xuICAgIHJldHVybiBzaWduICogcGFyc2VJbnQodmFsdWUsIDgpO1xuICB9XG5cbiAgaWYgKHZhbHVlLmluZGV4T2YoJzonKSAhPT0gLTEpIHtcbiAgICB2YWx1ZS5zcGxpdCgnOicpLmZvckVhY2goZnVuY3Rpb24gKHYpIHtcbiAgICAgIGRpZ2l0cy51bnNoaWZ0KHBhcnNlSW50KHYsIDEwKSk7XG4gICAgfSk7XG5cbiAgICB2YWx1ZSA9IDA7XG4gICAgYmFzZSA9IDE7XG5cbiAgICBkaWdpdHMuZm9yRWFjaChmdW5jdGlvbiAoZCkge1xuICAgICAgdmFsdWUgKz0gKGQgKiBiYXNlKTtcbiAgICAgIGJhc2UgKj0gNjA7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gc2lnbiAqIHZhbHVlO1xuXG4gIH1cblxuICByZXR1cm4gc2lnbiAqIHBhcnNlSW50KHZhbHVlLCAxMCk7XG59XG5cbmZ1bmN0aW9uIGlzSW50ZWdlcihvYmplY3QpIHtcbiAgcmV0dXJuIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqZWN0KSkgPT09ICdbb2JqZWN0IE51bWJlcl0nICYmXG4gICAgICAgICAob2JqZWN0ICUgMSA9PT0gMCAmJiAhY29tbW9uLmlzTmVnYXRpdmVaZXJvKG9iamVjdCkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjppbnQnLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICByZXNvbHZlOiByZXNvbHZlWWFtbEludGVnZXIsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbEludGVnZXIsXG4gIHByZWRpY2F0ZTogaXNJbnRlZ2VyLFxuICByZXByZXNlbnQ6IHtcbiAgICBiaW5hcnk6ICAgICAgZnVuY3Rpb24gKG9iamVjdCkgeyByZXR1cm4gJzBiJyArIG9iamVjdC50b1N0cmluZygyKTsgfSxcbiAgICBvY3RhbDogICAgICAgZnVuY3Rpb24gKG9iamVjdCkgeyByZXR1cm4gJzAnICArIG9iamVjdC50b1N0cmluZyg4KTsgfSxcbiAgICBkZWNpbWFsOiAgICAgZnVuY3Rpb24gKG9iamVjdCkgeyByZXR1cm4gICAgICAgIG9iamVjdC50b1N0cmluZygxMCk7IH0sXG4gICAgaGV4YWRlY2ltYWw6IGZ1bmN0aW9uIChvYmplY3QpIHsgcmV0dXJuICcweCcgKyBvYmplY3QudG9TdHJpbmcoMTYpLnRvVXBwZXJDYXNlKCk7IH1cbiAgfSxcbiAgZGVmYXVsdFN0eWxlOiAnZGVjaW1hbCcsXG4gIHN0eWxlQWxpYXNlczoge1xuICAgIGJpbmFyeTogICAgICBbIDIsICAnYmluJyBdLFxuICAgIG9jdGFsOiAgICAgICBbIDgsICAnb2N0JyBdLFxuICAgIGRlY2ltYWw6ICAgICBbIDEwLCAnZGVjJyBdLFxuICAgIGhleGFkZWNpbWFsOiBbIDE2LCAnaGV4JyBdXG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZXNwcmltYTtcblxuLy8gQnJvd3NlcmlmaWVkIHZlcnNpb24gZG9lcyBub3QgaGF2ZSBlc3ByaW1hXG4vL1xuLy8gMS4gRm9yIG5vZGUuanMganVzdCByZXF1aXJlIG1vZHVsZSBhcyBkZXBzXG4vLyAyLiBGb3IgYnJvd3NlciB0cnkgdG8gcmVxdWlyZSBtdWR1bGUgdmlhIGV4dGVybmFsIEFNRCBzeXN0ZW0uXG4vLyAgICBJZiBub3QgZm91bmQgLSB0cnkgdG8gZmFsbGJhY2sgdG8gd2luZG93LmVzcHJpbWEuIElmIG5vdFxuLy8gICAgZm91bmQgdG9vIC0gdGhlbiBmYWlsIHRvIHBhcnNlLlxuLy9cbnRyeSB7XG4gIC8vIHdvcmthcm91bmQgdG8gZXhjbHVkZSBwYWNrYWdlIGZyb20gYnJvd3NlcmlmeSBsaXN0LlxuICB2YXIgX3JlcXVpcmUgPSByZXF1aXJlO1xuICBlc3ByaW1hID0gX3JlcXVpcmUoJ2VzcHJpbWEnKTtcbn0gY2F0Y2ggKF8pIHtcbiAgLypnbG9iYWwgd2luZG93ICovXG4gIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykgZXNwcmltYSA9IHdpbmRvdy5lc3ByaW1hO1xufVxuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uLy4uL3R5cGUnKTtcblxuZnVuY3Rpb24gcmVzb2x2ZUphdmFzY3JpcHRGdW5jdGlvbihkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gZmFsc2U7XG5cbiAgdHJ5IHtcbiAgICB2YXIgc291cmNlID0gJygnICsgZGF0YSArICcpJyxcbiAgICAgICAgYXN0ICAgID0gZXNwcmltYS5wYXJzZShzb3VyY2UsIHsgcmFuZ2U6IHRydWUgfSk7XG5cbiAgICBpZiAoYXN0LnR5cGUgICAgICAgICAgICAgICAgICAgICE9PSAnUHJvZ3JhbScgICAgICAgICAgICAgfHxcbiAgICAgICAgYXN0LmJvZHkubGVuZ3RoICAgICAgICAgICAgICE9PSAxICAgICAgICAgICAgICAgICAgICAgfHxcbiAgICAgICAgYXN0LmJvZHlbMF0udHlwZSAgICAgICAgICAgICE9PSAnRXhwcmVzc2lvblN0YXRlbWVudCcgfHxcbiAgICAgICAgYXN0LmJvZHlbMF0uZXhwcmVzc2lvbi50eXBlICE9PSAnRnVuY3Rpb25FeHByZXNzaW9uJykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29uc3RydWN0SmF2YXNjcmlwdEZ1bmN0aW9uKGRhdGEpIHtcbiAgLypqc2xpbnQgZXZpbDp0cnVlKi9cblxuICB2YXIgc291cmNlID0gJygnICsgZGF0YSArICcpJyxcbiAgICAgIGFzdCAgICA9IGVzcHJpbWEucGFyc2Uoc291cmNlLCB7IHJhbmdlOiB0cnVlIH0pLFxuICAgICAgcGFyYW1zID0gW10sXG4gICAgICBib2R5O1xuXG4gIGlmIChhc3QudHlwZSAgICAgICAgICAgICAgICAgICAgIT09ICdQcm9ncmFtJyAgICAgICAgICAgICB8fFxuICAgICAgYXN0LmJvZHkubGVuZ3RoICAgICAgICAgICAgICE9PSAxICAgICAgICAgICAgICAgICAgICAgfHxcbiAgICAgIGFzdC5ib2R5WzBdLnR5cGUgICAgICAgICAgICAhPT0gJ0V4cHJlc3Npb25TdGF0ZW1lbnQnIHx8XG4gICAgICBhc3QuYm9keVswXS5leHByZXNzaW9uLnR5cGUgIT09ICdGdW5jdGlvbkV4cHJlc3Npb24nKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gcmVzb2x2ZSBmdW5jdGlvbicpO1xuICB9XG5cbiAgYXN0LmJvZHlbMF0uZXhwcmVzc2lvbi5wYXJhbXMuZm9yRWFjaChmdW5jdGlvbiAocGFyYW0pIHtcbiAgICBwYXJhbXMucHVzaChwYXJhbS5uYW1lKTtcbiAgfSk7XG5cbiAgYm9keSA9IGFzdC5ib2R5WzBdLmV4cHJlc3Npb24uYm9keS5yYW5nZTtcblxuICAvLyBFc3ByaW1hJ3MgcmFuZ2VzIGluY2x1ZGUgdGhlIGZpcnN0ICd7JyBhbmQgdGhlIGxhc3QgJ30nIGNoYXJhY3RlcnMgb25cbiAgLy8gZnVuY3Rpb24gZXhwcmVzc2lvbnMuIFNvIGN1dCB0aGVtIG91dC5cbiAgLyplc2xpbnQtZGlzYWJsZSBuby1uZXctZnVuYyovXG4gIHJldHVybiBuZXcgRnVuY3Rpb24ocGFyYW1zLCBzb3VyY2Uuc2xpY2UoYm9keVswXSArIDEsIGJvZHlbMV0gLSAxKSk7XG59XG5cbmZ1bmN0aW9uIHJlcHJlc2VudEphdmFzY3JpcHRGdW5jdGlvbihvYmplY3QgLyosIHN0eWxlKi8pIHtcbiAgcmV0dXJuIG9iamVjdC50b1N0cmluZygpO1xufVxuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKG9iamVjdCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iamVjdCkgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOmpzL2Z1bmN0aW9uJywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZUphdmFzY3JpcHRGdW5jdGlvbixcbiAgY29uc3RydWN0OiBjb25zdHJ1Y3RKYXZhc2NyaXB0RnVuY3Rpb24sXG4gIHByZWRpY2F0ZTogaXNGdW5jdGlvbixcbiAgcmVwcmVzZW50OiByZXByZXNlbnRKYXZhc2NyaXB0RnVuY3Rpb25cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uLy4uL3R5cGUnKTtcblxuZnVuY3Rpb24gcmVzb2x2ZUphdmFzY3JpcHRSZWdFeHAoZGF0YSkge1xuICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuICBpZiAoZGF0YS5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTtcblxuICB2YXIgcmVnZXhwID0gZGF0YSxcbiAgICAgIHRhaWwgICA9IC9cXC8oW2dpbV0qKSQvLmV4ZWMoZGF0YSksXG4gICAgICBtb2RpZmllcnMgPSAnJztcblxuICAvLyBpZiByZWdleHAgc3RhcnRzIHdpdGggJy8nIGl0IGNhbiBoYXZlIG1vZGlmaWVycyBhbmQgbXVzdCBiZSBwcm9wZXJseSBjbG9zZWRcbiAgLy8gYC9mb28vZ2ltYCAtIG1vZGlmaWVycyB0YWlsIGNhbiBiZSBtYXhpbXVtIDMgY2hhcnNcbiAgaWYgKHJlZ2V4cFswXSA9PT0gJy8nKSB7XG4gICAgaWYgKHRhaWwpIG1vZGlmaWVycyA9IHRhaWxbMV07XG5cbiAgICBpZiAobW9kaWZpZXJzLmxlbmd0aCA+IDMpIHJldHVybiBmYWxzZTtcbiAgICAvLyBpZiBleHByZXNzaW9uIHN0YXJ0cyB3aXRoIC8sIGlzIHNob3VsZCBiZSBwcm9wZXJseSB0ZXJtaW5hdGVkXG4gICAgaWYgKHJlZ2V4cFtyZWdleHAubGVuZ3RoIC0gbW9kaWZpZXJzLmxlbmd0aCAtIDFdICE9PSAnLycpIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RKYXZhc2NyaXB0UmVnRXhwKGRhdGEpIHtcbiAgdmFyIHJlZ2V4cCA9IGRhdGEsXG4gICAgICB0YWlsICAgPSAvXFwvKFtnaW1dKikkLy5leGVjKGRhdGEpLFxuICAgICAgbW9kaWZpZXJzID0gJyc7XG5cbiAgLy8gYC9mb28vZ2ltYCAtIHRhaWwgY2FuIGJlIG1heGltdW0gNCBjaGFyc1xuICBpZiAocmVnZXhwWzBdID09PSAnLycpIHtcbiAgICBpZiAodGFpbCkgbW9kaWZpZXJzID0gdGFpbFsxXTtcbiAgICByZWdleHAgPSByZWdleHAuc2xpY2UoMSwgcmVnZXhwLmxlbmd0aCAtIG1vZGlmaWVycy5sZW5ndGggLSAxKTtcbiAgfVxuXG4gIHJldHVybiBuZXcgUmVnRXhwKHJlZ2V4cCwgbW9kaWZpZXJzKTtcbn1cblxuZnVuY3Rpb24gcmVwcmVzZW50SmF2YXNjcmlwdFJlZ0V4cChvYmplY3QgLyosIHN0eWxlKi8pIHtcbiAgdmFyIHJlc3VsdCA9ICcvJyArIG9iamVjdC5zb3VyY2UgKyAnLyc7XG5cbiAgaWYgKG9iamVjdC5nbG9iYWwpIHJlc3VsdCArPSAnZyc7XG4gIGlmIChvYmplY3QubXVsdGlsaW5lKSByZXN1bHQgKz0gJ20nO1xuICBpZiAob2JqZWN0Lmlnbm9yZUNhc2UpIHJlc3VsdCArPSAnaSc7XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gaXNSZWdFeHAob2JqZWN0KSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqZWN0KSA9PT0gJ1tvYmplY3QgUmVnRXhwXSc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOmpzL3JlZ2V4cCcsIHtcbiAga2luZDogJ3NjYWxhcicsXG4gIHJlc29sdmU6IHJlc29sdmVKYXZhc2NyaXB0UmVnRXhwLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdEphdmFzY3JpcHRSZWdFeHAsXG4gIHByZWRpY2F0ZTogaXNSZWdFeHAsXG4gIHJlcHJlc2VudDogcmVwcmVzZW50SmF2YXNjcmlwdFJlZ0V4cFxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vLi4vdHlwZScpO1xuXG5mdW5jdGlvbiByZXNvbHZlSmF2YXNjcmlwdFVuZGVmaW5lZCgpIHtcbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdEphdmFzY3JpcHRVbmRlZmluZWQoKSB7XG4gIC8qZXNsaW50LWRpc2FibGUgbm8tdW5kZWZpbmVkKi9cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gcmVwcmVzZW50SmF2YXNjcmlwdFVuZGVmaW5lZCgpIHtcbiAgcmV0dXJuICcnO1xufVxuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChvYmplY3QpIHtcbiAgcmV0dXJuIHR5cGVvZiBvYmplY3QgPT09ICd1bmRlZmluZWQnO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpqcy91bmRlZmluZWQnLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICByZXNvbHZlOiByZXNvbHZlSmF2YXNjcmlwdFVuZGVmaW5lZCxcbiAgY29uc3RydWN0OiBjb25zdHJ1Y3RKYXZhc2NyaXB0VW5kZWZpbmVkLFxuICBwcmVkaWNhdGU6IGlzVW5kZWZpbmVkLFxuICByZXByZXNlbnQ6IHJlcHJlc2VudEphdmFzY3JpcHRVbmRlZmluZWRcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6bWFwJywge1xuICBraW5kOiAnbWFwcGluZycsXG4gIGNvbnN0cnVjdDogZnVuY3Rpb24gKGRhdGEpIHsgcmV0dXJuIGRhdGEgIT09IG51bGwgPyBkYXRhIDoge307IH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxNZXJnZShkYXRhKSB7XG4gIHJldHVybiBkYXRhID09PSAnPDwnIHx8IGRhdGEgPT09IG51bGw7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOm1lcmdlJywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxNZXJnZVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG5mdW5jdGlvbiByZXNvbHZlWWFtbE51bGwoZGF0YSkge1xuICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIHRydWU7XG5cbiAgdmFyIG1heCA9IGRhdGEubGVuZ3RoO1xuXG4gIHJldHVybiAobWF4ID09PSAxICYmIGRhdGEgPT09ICd+JykgfHxcbiAgICAgICAgIChtYXggPT09IDQgJiYgKGRhdGEgPT09ICdudWxsJyB8fCBkYXRhID09PSAnTnVsbCcgfHwgZGF0YSA9PT0gJ05VTEwnKSk7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxOdWxsKCkge1xuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gaXNOdWxsKG9iamVjdCkge1xuICByZXR1cm4gb2JqZWN0ID09PSBudWxsO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpudWxsJywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxOdWxsLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdFlhbWxOdWxsLFxuICBwcmVkaWNhdGU6IGlzTnVsbCxcbiAgcmVwcmVzZW50OiB7XG4gICAgY2Fub25pY2FsOiBmdW5jdGlvbiAoKSB7IHJldHVybiAnfic7ICAgIH0sXG4gICAgbG93ZXJjYXNlOiBmdW5jdGlvbiAoKSB7IHJldHVybiAnbnVsbCc7IH0sXG4gICAgdXBwZXJjYXNlOiBmdW5jdGlvbiAoKSB7IHJldHVybiAnTlVMTCc7IH0sXG4gICAgY2FtZWxjYXNlOiBmdW5jdGlvbiAoKSB7IHJldHVybiAnTnVsbCc7IH1cbiAgfSxcbiAgZGVmYXVsdFN0eWxlOiAnbG93ZXJjYXNlJ1xufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG52YXIgX2hhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbnZhciBfdG9TdHJpbmcgICAgICAgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG5mdW5jdGlvbiByZXNvbHZlWWFtbE9tYXAoZGF0YSkge1xuICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIHRydWU7XG5cbiAgdmFyIG9iamVjdEtleXMgPSBbXSwgaW5kZXgsIGxlbmd0aCwgcGFpciwgcGFpcktleSwgcGFpckhhc0tleSxcbiAgICAgIG9iamVjdCA9IGRhdGE7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IG9iamVjdC5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgcGFpciA9IG9iamVjdFtpbmRleF07XG4gICAgcGFpckhhc0tleSA9IGZhbHNlO1xuXG4gICAgaWYgKF90b1N0cmluZy5jYWxsKHBhaXIpICE9PSAnW29iamVjdCBPYmplY3RdJykgcmV0dXJuIGZhbHNlO1xuXG4gICAgZm9yIChwYWlyS2V5IGluIHBhaXIpIHtcbiAgICAgIGlmIChfaGFzT3duUHJvcGVydHkuY2FsbChwYWlyLCBwYWlyS2V5KSkge1xuICAgICAgICBpZiAoIXBhaXJIYXNLZXkpIHBhaXJIYXNLZXkgPSB0cnVlO1xuICAgICAgICBlbHNlIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXBhaXJIYXNLZXkpIHJldHVybiBmYWxzZTtcblxuICAgIGlmIChvYmplY3RLZXlzLmluZGV4T2YocGFpcktleSkgPT09IC0xKSBvYmplY3RLZXlzLnB1c2gocGFpcktleSk7XG4gICAgZWxzZSByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0WWFtbE9tYXAoZGF0YSkge1xuICByZXR1cm4gZGF0YSAhPT0gbnVsbCA/IGRhdGEgOiBbXTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6b21hcCcsIHtcbiAga2luZDogJ3NlcXVlbmNlJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxPbWFwLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdFlhbWxPbWFwXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbnZhciBfdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG5mdW5jdGlvbiByZXNvbHZlWWFtbFBhaXJzKGRhdGEpIHtcbiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiB0cnVlO1xuXG4gIHZhciBpbmRleCwgbGVuZ3RoLCBwYWlyLCBrZXlzLCByZXN1bHQsXG4gICAgICBvYmplY3QgPSBkYXRhO1xuXG4gIHJlc3VsdCA9IG5ldyBBcnJheShvYmplY3QubGVuZ3RoKTtcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gb2JqZWN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICBwYWlyID0gb2JqZWN0W2luZGV4XTtcblxuICAgIGlmIChfdG9TdHJpbmcuY2FsbChwYWlyKSAhPT0gJ1tvYmplY3QgT2JqZWN0XScpIHJldHVybiBmYWxzZTtcblxuICAgIGtleXMgPSBPYmplY3Qua2V5cyhwYWlyKTtcblxuICAgIGlmIChrZXlzLmxlbmd0aCAhPT0gMSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgcmVzdWx0W2luZGV4XSA9IFsga2V5c1swXSwgcGFpcltrZXlzWzBdXSBdO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxQYWlycyhkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gW107XG5cbiAgdmFyIGluZGV4LCBsZW5ndGgsIHBhaXIsIGtleXMsIHJlc3VsdCxcbiAgICAgIG9iamVjdCA9IGRhdGE7XG5cbiAgcmVzdWx0ID0gbmV3IEFycmF5KG9iamVjdC5sZW5ndGgpO1xuXG4gIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIHBhaXIgPSBvYmplY3RbaW5kZXhdO1xuXG4gICAga2V5cyA9IE9iamVjdC5rZXlzKHBhaXIpO1xuXG4gICAgcmVzdWx0W2luZGV4XSA9IFsga2V5c1swXSwgcGFpcltrZXlzWzBdXSBdO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6cGFpcnMnLCB7XG4gIGtpbmQ6ICdzZXF1ZW5jZScsXG4gIHJlc29sdmU6IHJlc29sdmVZYW1sUGFpcnMsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbFBhaXJzXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOnNlcScsIHtcbiAga2luZDogJ3NlcXVlbmNlJyxcbiAgY29uc3RydWN0OiBmdW5jdGlvbiAoZGF0YSkgeyByZXR1cm4gZGF0YSAhPT0gbnVsbCA/IGRhdGEgOiBbXTsgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG52YXIgX2hhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxTZXQoZGF0YSkge1xuICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIHRydWU7XG5cbiAgdmFyIGtleSwgb2JqZWN0ID0gZGF0YTtcblxuICBmb3IgKGtleSBpbiBvYmplY3QpIHtcbiAgICBpZiAoX2hhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSB7XG4gICAgICBpZiAob2JqZWN0W2tleV0gIT09IG51bGwpIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0WWFtbFNldChkYXRhKSB7XG4gIHJldHVybiBkYXRhICE9PSBudWxsID8gZGF0YSA6IHt9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpzZXQnLCB7XG4gIGtpbmQ6ICdtYXBwaW5nJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxTZXQsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbFNldFxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpzdHInLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICBjb25zdHJ1Y3Q6IGZ1bmN0aW9uIChkYXRhKSB7IHJldHVybiBkYXRhICE9PSBudWxsID8gZGF0YSA6ICcnOyB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbnZhciBZQU1MX1RJTUVTVEFNUF9SRUdFWFAgPSBuZXcgUmVnRXhwKFxuICAnXihbMC05XVswLTldWzAtOV1bMC05XSknICAgICAgICAgICsgLy8gWzFdIHllYXJcbiAgJy0oWzAtOV1bMC05XT8pJyAgICAgICAgICAgICAgICAgICArIC8vIFsyXSBtb250aFxuICAnLShbMC05XVswLTldPyknICAgICAgICAgICAgICAgICAgICsgLy8gWzNdIGRheVxuICAnKD86KD86W1R0XXxbIFxcXFx0XSspJyAgICAgICAgICAgICAgKyAvLyAuLi5cbiAgJyhbMC05XVswLTldPyknICAgICAgICAgICAgICAgICAgICArIC8vIFs0XSBob3VyXG4gICc6KFswLTldWzAtOV0pJyAgICAgICAgICAgICAgICAgICAgKyAvLyBbNV0gbWludXRlXG4gICc6KFswLTldWzAtOV0pJyAgICAgICAgICAgICAgICAgICAgKyAvLyBbNl0gc2Vjb25kXG4gICcoPzpcXFxcLihbMC05XSopKT8nICAgICAgICAgICAgICAgICArIC8vIFs3XSBmcmFjdGlvblxuICAnKD86WyBcXFxcdF0qKFp8KFstK10pKFswLTldWzAtOV0/KScgKyAvLyBbOF0gdHogWzldIHR6X3NpZ24gWzEwXSB0el9ob3VyXG4gICcoPzo6KFswLTldWzAtOV0pKT8pKT8pPyQnKTsgICAgICAgICAvLyBbMTFdIHR6X21pbnV0ZVxuXG5mdW5jdGlvbiByZXNvbHZlWWFtbFRpbWVzdGFtcChkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gZmFsc2U7XG4gIGlmIChZQU1MX1RJTUVTVEFNUF9SRUdFWFAuZXhlYyhkYXRhKSA9PT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0WWFtbFRpbWVzdGFtcChkYXRhKSB7XG4gIHZhciBtYXRjaCwgeWVhciwgbW9udGgsIGRheSwgaG91ciwgbWludXRlLCBzZWNvbmQsIGZyYWN0aW9uID0gMCxcbiAgICAgIGRlbHRhID0gbnVsbCwgdHpfaG91ciwgdHpfbWludXRlLCBkYXRlO1xuXG4gIG1hdGNoID0gWUFNTF9USU1FU1RBTVBfUkVHRVhQLmV4ZWMoZGF0YSk7XG5cbiAgaWYgKG1hdGNoID09PSBudWxsKSB0aHJvdyBuZXcgRXJyb3IoJ0RhdGUgcmVzb2x2ZSBlcnJvcicpO1xuXG4gIC8vIG1hdGNoOiBbMV0geWVhciBbMl0gbW9udGggWzNdIGRheVxuXG4gIHllYXIgPSArKG1hdGNoWzFdKTtcbiAgbW9udGggPSArKG1hdGNoWzJdKSAtIDE7IC8vIEpTIG1vbnRoIHN0YXJ0cyB3aXRoIDBcbiAgZGF5ID0gKyhtYXRjaFszXSk7XG5cbiAgaWYgKCFtYXRjaFs0XSkgeyAvLyBubyBob3VyXG4gICAgcmV0dXJuIG5ldyBEYXRlKERhdGUuVVRDKHllYXIsIG1vbnRoLCBkYXkpKTtcbiAgfVxuXG4gIC8vIG1hdGNoOiBbNF0gaG91ciBbNV0gbWludXRlIFs2XSBzZWNvbmQgWzddIGZyYWN0aW9uXG5cbiAgaG91ciA9ICsobWF0Y2hbNF0pO1xuICBtaW51dGUgPSArKG1hdGNoWzVdKTtcbiAgc2Vjb25kID0gKyhtYXRjaFs2XSk7XG5cbiAgaWYgKG1hdGNoWzddKSB7XG4gICAgZnJhY3Rpb24gPSBtYXRjaFs3XS5zbGljZSgwLCAzKTtcbiAgICB3aGlsZSAoZnJhY3Rpb24ubGVuZ3RoIDwgMykgeyAvLyBtaWxsaS1zZWNvbmRzXG4gICAgICBmcmFjdGlvbiArPSAnMCc7XG4gICAgfVxuICAgIGZyYWN0aW9uID0gK2ZyYWN0aW9uO1xuICB9XG5cbiAgLy8gbWF0Y2g6IFs4XSB0eiBbOV0gdHpfc2lnbiBbMTBdIHR6X2hvdXIgWzExXSB0el9taW51dGVcblxuICBpZiAobWF0Y2hbOV0pIHtcbiAgICB0el9ob3VyID0gKyhtYXRjaFsxMF0pO1xuICAgIHR6X21pbnV0ZSA9ICsobWF0Y2hbMTFdIHx8IDApO1xuICAgIGRlbHRhID0gKHR6X2hvdXIgKiA2MCArIHR6X21pbnV0ZSkgKiA2MDAwMDsgLy8gZGVsdGEgaW4gbWlsaS1zZWNvbmRzXG4gICAgaWYgKG1hdGNoWzldID09PSAnLScpIGRlbHRhID0gLWRlbHRhO1xuICB9XG5cbiAgZGF0ZSA9IG5ldyBEYXRlKERhdGUuVVRDKHllYXIsIG1vbnRoLCBkYXksIGhvdXIsIG1pbnV0ZSwgc2Vjb25kLCBmcmFjdGlvbikpO1xuXG4gIGlmIChkZWx0YSkgZGF0ZS5zZXRUaW1lKGRhdGUuZ2V0VGltZSgpIC0gZGVsdGEpO1xuXG4gIHJldHVybiBkYXRlO1xufVxuXG5mdW5jdGlvbiByZXByZXNlbnRZYW1sVGltZXN0YW1wKG9iamVjdCAvKiwgc3R5bGUqLykge1xuICByZXR1cm4gb2JqZWN0LnRvSVNPU3RyaW5nKCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOnRpbWVzdGFtcCcsIHtcbiAga2luZDogJ3NjYWxhcicsXG4gIHJlc29sdmU6IHJlc29sdmVZYW1sVGltZXN0YW1wLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdFlhbWxUaW1lc3RhbXAsXG4gIGluc3RhbmNlT2Y6IERhdGUsXG4gIHJlcHJlc2VudDogcmVwcmVzZW50WWFtbFRpbWVzdGFtcFxufSk7XG4iLCJ2YXIgYmFzZUluZGV4T2YgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlSW5kZXhPZicpLFxuICAgIGJpbmFyeUluZGV4ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmluYXJ5SW5kZXgnKTtcblxuLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heDtcblxuLyoqXG4gKiBHZXRzIHRoZSBpbmRleCBhdCB3aGljaCB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiBgdmFsdWVgIGlzIGZvdW5kIGluIGBhcnJheWBcbiAqIHVzaW5nIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXNhbWV2YWx1ZXplcm8pXG4gKiBmb3IgZXF1YWxpdHkgY29tcGFyaXNvbnMuIElmIGBmcm9tSW5kZXhgIGlzIG5lZ2F0aXZlLCBpdCdzIHVzZWQgYXMgdGhlIG9mZnNldFxuICogZnJvbSB0aGUgZW5kIG9mIGBhcnJheWAuIElmIGBhcnJheWAgaXMgc29ydGVkIHByb3ZpZGluZyBgdHJ1ZWAgZm9yIGBmcm9tSW5kZXhgXG4gKiBwZXJmb3JtcyBhIGZhc3RlciBiaW5hcnkgc2VhcmNoLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgQXJyYXlcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzZWFyY2guXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICogQHBhcmFtIHtib29sZWFufG51bWJlcn0gW2Zyb21JbmRleD0wXSBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20gb3IgYHRydWVgXG4gKiAgdG8gcGVyZm9ybSBhIGJpbmFyeSBzZWFyY2ggb24gYSBzb3J0ZWQgYXJyYXkuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmluZGV4T2YoWzEsIDIsIDEsIDJdLCAyKTtcbiAqIC8vID0+IDFcbiAqXG4gKiAvLyB1c2luZyBgZnJvbUluZGV4YFxuICogXy5pbmRleE9mKFsxLCAyLCAxLCAyXSwgMiwgMik7XG4gKiAvLyA9PiAzXG4gKlxuICogLy8gcGVyZm9ybWluZyBhIGJpbmFyeSBzZWFyY2hcbiAqIF8uaW5kZXhPZihbMSwgMSwgMiwgMl0sIDIsIHRydWUpO1xuICogLy8gPT4gMlxuICovXG5mdW5jdGlvbiBpbmRleE9mKGFycmF5LCB2YWx1ZSwgZnJvbUluZGV4KSB7XG4gIHZhciBsZW5ndGggPSBhcnJheSA/IGFycmF5Lmxlbmd0aCA6IDA7XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgcmV0dXJuIC0xO1xuICB9XG4gIGlmICh0eXBlb2YgZnJvbUluZGV4ID09ICdudW1iZXInKSB7XG4gICAgZnJvbUluZGV4ID0gZnJvbUluZGV4IDwgMCA/IG5hdGl2ZU1heChsZW5ndGggKyBmcm9tSW5kZXgsIDApIDogZnJvbUluZGV4O1xuICB9IGVsc2UgaWYgKGZyb21JbmRleCkge1xuICAgIHZhciBpbmRleCA9IGJpbmFyeUluZGV4KGFycmF5LCB2YWx1ZSk7XG4gICAgaWYgKGluZGV4IDwgbGVuZ3RoICYmXG4gICAgICAgICh2YWx1ZSA9PT0gdmFsdWUgPyAodmFsdWUgPT09IGFycmF5W2luZGV4XSkgOiAoYXJyYXlbaW5kZXhdICE9PSBhcnJheVtpbmRleF0pKSkge1xuICAgICAgcmV0dXJuIGluZGV4O1xuICAgIH1cbiAgICByZXR1cm4gLTE7XG4gIH1cbiAgcmV0dXJuIGJhc2VJbmRleE9mKGFycmF5LCB2YWx1ZSwgZnJvbUluZGV4IHx8IDApO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGluZGV4T2Y7XG4iLCIvKipcbiAqIEdldHMgdGhlIGxhc3QgZWxlbWVudCBvZiBgYXJyYXlgLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgQXJyYXlcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBsYXN0IGVsZW1lbnQgb2YgYGFycmF5YC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5sYXN0KFsxLCAyLCAzXSk7XG4gKiAvLyA9PiAzXG4gKi9cbmZ1bmN0aW9uIGxhc3QoYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5ID8gYXJyYXkubGVuZ3RoIDogMDtcbiAgcmV0dXJuIGxlbmd0aCA/IGFycmF5W2xlbmd0aCAtIDFdIDogdW5kZWZpbmVkO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGxhc3Q7XG4iLCJ2YXIgTGF6eVdyYXBwZXIgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9MYXp5V3JhcHBlcicpLFxuICAgIExvZGFzaFdyYXBwZXIgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9Mb2Rhc2hXcmFwcGVyJyksXG4gICAgYmFzZUxvZGFzaCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2Jhc2VMb2Rhc2gnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FycmF5JyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNPYmplY3RMaWtlJyksXG4gICAgd3JhcHBlckNsb25lID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvd3JhcHBlckNsb25lJyk7XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBgbG9kYXNoYCBvYmplY3Qgd2hpY2ggd3JhcHMgYHZhbHVlYCB0byBlbmFibGUgaW1wbGljaXQgY2hhaW5pbmcuXG4gKiBNZXRob2RzIHRoYXQgb3BlcmF0ZSBvbiBhbmQgcmV0dXJuIGFycmF5cywgY29sbGVjdGlvbnMsIGFuZCBmdW5jdGlvbnMgY2FuXG4gKiBiZSBjaGFpbmVkIHRvZ2V0aGVyLiBNZXRob2RzIHRoYXQgcmV0cmlldmUgYSBzaW5nbGUgdmFsdWUgb3IgbWF5IHJldHVybiBhXG4gKiBwcmltaXRpdmUgdmFsdWUgd2lsbCBhdXRvbWF0aWNhbGx5IGVuZCB0aGUgY2hhaW4gcmV0dXJuaW5nIHRoZSB1bndyYXBwZWRcbiAqIHZhbHVlLiBFeHBsaWNpdCBjaGFpbmluZyBtYXkgYmUgZW5hYmxlZCB1c2luZyBgXy5jaGFpbmAuIFRoZSBleGVjdXRpb24gb2ZcbiAqIGNoYWluZWQgbWV0aG9kcyBpcyBsYXp5LCB0aGF0IGlzLCBleGVjdXRpb24gaXMgZGVmZXJyZWQgdW50aWwgYF8jdmFsdWVgXG4gKiBpcyBpbXBsaWNpdGx5IG9yIGV4cGxpY2l0bHkgY2FsbGVkLlxuICpcbiAqIExhenkgZXZhbHVhdGlvbiBhbGxvd3Mgc2V2ZXJhbCBtZXRob2RzIHRvIHN1cHBvcnQgc2hvcnRjdXQgZnVzaW9uLiBTaG9ydGN1dFxuICogZnVzaW9uIGlzIGFuIG9wdGltaXphdGlvbiBzdHJhdGVneSB3aGljaCBtZXJnZSBpdGVyYXRlZSBjYWxsczsgdGhpcyBjYW4gaGVscFxuICogdG8gYXZvaWQgdGhlIGNyZWF0aW9uIG9mIGludGVybWVkaWF0ZSBkYXRhIHN0cnVjdHVyZXMgYW5kIGdyZWF0bHkgcmVkdWNlIHRoZVxuICogbnVtYmVyIG9mIGl0ZXJhdGVlIGV4ZWN1dGlvbnMuXG4gKlxuICogQ2hhaW5pbmcgaXMgc3VwcG9ydGVkIGluIGN1c3RvbSBidWlsZHMgYXMgbG9uZyBhcyB0aGUgYF8jdmFsdWVgIG1ldGhvZCBpc1xuICogZGlyZWN0bHkgb3IgaW5kaXJlY3RseSBpbmNsdWRlZCBpbiB0aGUgYnVpbGQuXG4gKlxuICogSW4gYWRkaXRpb24gdG8gbG9kYXNoIG1ldGhvZHMsIHdyYXBwZXJzIGhhdmUgYEFycmF5YCBhbmQgYFN0cmluZ2AgbWV0aG9kcy5cbiAqXG4gKiBUaGUgd3JhcHBlciBgQXJyYXlgIG1ldGhvZHMgYXJlOlxuICogYGNvbmNhdGAsIGBqb2luYCwgYHBvcGAsIGBwdXNoYCwgYHJldmVyc2VgLCBgc2hpZnRgLCBgc2xpY2VgLCBgc29ydGAsXG4gKiBgc3BsaWNlYCwgYW5kIGB1bnNoaWZ0YFxuICpcbiAqIFRoZSB3cmFwcGVyIGBTdHJpbmdgIG1ldGhvZHMgYXJlOlxuICogYHJlcGxhY2VgIGFuZCBgc3BsaXRgXG4gKlxuICogVGhlIHdyYXBwZXIgbWV0aG9kcyB0aGF0IHN1cHBvcnQgc2hvcnRjdXQgZnVzaW9uIGFyZTpcbiAqIGBjb21wYWN0YCwgYGRyb3BgLCBgZHJvcFJpZ2h0YCwgYGRyb3BSaWdodFdoaWxlYCwgYGRyb3BXaGlsZWAsIGBmaWx0ZXJgLFxuICogYGZpcnN0YCwgYGluaXRpYWxgLCBgbGFzdGAsIGBtYXBgLCBgcGx1Y2tgLCBgcmVqZWN0YCwgYHJlc3RgLCBgcmV2ZXJzZWAsXG4gKiBgc2xpY2VgLCBgdGFrZWAsIGB0YWtlUmlnaHRgLCBgdGFrZVJpZ2h0V2hpbGVgLCBgdGFrZVdoaWxlYCwgYHRvQXJyYXlgLFxuICogYW5kIGB3aGVyZWBcbiAqXG4gKiBUaGUgY2hhaW5hYmxlIHdyYXBwZXIgbWV0aG9kcyBhcmU6XG4gKiBgYWZ0ZXJgLCBgYXJ5YCwgYGFzc2lnbmAsIGBhdGAsIGBiZWZvcmVgLCBgYmluZGAsIGBiaW5kQWxsYCwgYGJpbmRLZXlgLFxuICogYGNhbGxiYWNrYCwgYGNoYWluYCwgYGNodW5rYCwgYGNvbW1pdGAsIGBjb21wYWN0YCwgYGNvbmNhdGAsIGBjb25zdGFudGAsXG4gKiBgY291bnRCeWAsIGBjcmVhdGVgLCBgY3VycnlgLCBgZGVib3VuY2VgLCBgZGVmYXVsdHNgLCBgZGVmYXVsdHNEZWVwYCxcbiAqIGBkZWZlcmAsIGBkZWxheWAsIGBkaWZmZXJlbmNlYCwgYGRyb3BgLCBgZHJvcFJpZ2h0YCwgYGRyb3BSaWdodFdoaWxlYCxcbiAqIGBkcm9wV2hpbGVgLCBgZmlsbGAsIGBmaWx0ZXJgLCBgZmxhdHRlbmAsIGBmbGF0dGVuRGVlcGAsIGBmbG93YCwgYGZsb3dSaWdodGAsXG4gKiBgZm9yRWFjaGAsIGBmb3JFYWNoUmlnaHRgLCBgZm9ySW5gLCBgZm9ySW5SaWdodGAsIGBmb3JPd25gLCBgZm9yT3duUmlnaHRgLFxuICogYGZ1bmN0aW9uc2AsIGBncm91cEJ5YCwgYGluZGV4QnlgLCBgaW5pdGlhbGAsIGBpbnRlcnNlY3Rpb25gLCBgaW52ZXJ0YCxcbiAqIGBpbnZva2VgLCBga2V5c2AsIGBrZXlzSW5gLCBgbWFwYCwgYG1hcEtleXNgLCBgbWFwVmFsdWVzYCwgYG1hdGNoZXNgLFxuICogYG1hdGNoZXNQcm9wZXJ0eWAsIGBtZW1vaXplYCwgYG1lcmdlYCwgYG1ldGhvZGAsIGBtZXRob2RPZmAsIGBtaXhpbmAsXG4gKiBgbW9kQXJnc2AsIGBuZWdhdGVgLCBgb21pdGAsIGBvbmNlYCwgYHBhaXJzYCwgYHBhcnRpYWxgLCBgcGFydGlhbFJpZ2h0YCxcbiAqIGBwYXJ0aXRpb25gLCBgcGlja2AsIGBwbGFudGAsIGBwbHVja2AsIGBwcm9wZXJ0eWAsIGBwcm9wZXJ0eU9mYCwgYHB1bGxgLFxuICogYHB1bGxBdGAsIGBwdXNoYCwgYHJhbmdlYCwgYHJlYXJnYCwgYHJlamVjdGAsIGByZW1vdmVgLCBgcmVzdGAsIGByZXN0UGFyYW1gLFxuICogYHJldmVyc2VgLCBgc2V0YCwgYHNodWZmbGVgLCBgc2xpY2VgLCBgc29ydGAsIGBzb3J0QnlgLCBgc29ydEJ5QWxsYCxcbiAqIGBzb3J0QnlPcmRlcmAsIGBzcGxpY2VgLCBgc3ByZWFkYCwgYHRha2VgLCBgdGFrZVJpZ2h0YCwgYHRha2VSaWdodFdoaWxlYCxcbiAqIGB0YWtlV2hpbGVgLCBgdGFwYCwgYHRocm90dGxlYCwgYHRocnVgLCBgdGltZXNgLCBgdG9BcnJheWAsIGB0b1BsYWluT2JqZWN0YCxcbiAqIGB0cmFuc2Zvcm1gLCBgdW5pb25gLCBgdW5pcWAsIGB1bnNoaWZ0YCwgYHVuemlwYCwgYHVuemlwV2l0aGAsIGB2YWx1ZXNgLFxuICogYHZhbHVlc0luYCwgYHdoZXJlYCwgYHdpdGhvdXRgLCBgd3JhcGAsIGB4b3JgLCBgemlwYCwgYHppcE9iamVjdGAsIGB6aXBXaXRoYFxuICpcbiAqIFRoZSB3cmFwcGVyIG1ldGhvZHMgdGhhdCBhcmUgKipub3QqKiBjaGFpbmFibGUgYnkgZGVmYXVsdCBhcmU6XG4gKiBgYWRkYCwgYGF0dGVtcHRgLCBgY2FtZWxDYXNlYCwgYGNhcGl0YWxpemVgLCBgY2VpbGAsIGBjbG9uZWAsIGBjbG9uZURlZXBgLFxuICogYGRlYnVycmAsIGBlbmRzV2l0aGAsIGBlc2NhcGVgLCBgZXNjYXBlUmVnRXhwYCwgYGV2ZXJ5YCwgYGZpbmRgLCBgZmluZEluZGV4YCxcbiAqIGBmaW5kS2V5YCwgYGZpbmRMYXN0YCwgYGZpbmRMYXN0SW5kZXhgLCBgZmluZExhc3RLZXlgLCBgZmluZFdoZXJlYCwgYGZpcnN0YCxcbiAqIGBmbG9vcmAsIGBnZXRgLCBgZ3RgLCBgZ3RlYCwgYGhhc2AsIGBpZGVudGl0eWAsIGBpbmNsdWRlc2AsIGBpbmRleE9mYCxcbiAqIGBpblJhbmdlYCwgYGlzQXJndW1lbnRzYCwgYGlzQXJyYXlgLCBgaXNCb29sZWFuYCwgYGlzRGF0ZWAsIGBpc0VsZW1lbnRgLFxuICogYGlzRW1wdHlgLCBgaXNFcXVhbGAsIGBpc0Vycm9yYCwgYGlzRmluaXRlYCBgaXNGdW5jdGlvbmAsIGBpc01hdGNoYCxcbiAqIGBpc05hdGl2ZWAsIGBpc05hTmAsIGBpc051bGxgLCBgaXNOdW1iZXJgLCBgaXNPYmplY3RgLCBgaXNQbGFpbk9iamVjdGAsXG4gKiBgaXNSZWdFeHBgLCBgaXNTdHJpbmdgLCBgaXNVbmRlZmluZWRgLCBgaXNUeXBlZEFycmF5YCwgYGpvaW5gLCBga2ViYWJDYXNlYCxcbiAqIGBsYXN0YCwgYGxhc3RJbmRleE9mYCwgYGx0YCwgYGx0ZWAsIGBtYXhgLCBgbWluYCwgYG5vQ29uZmxpY3RgLCBgbm9vcGAsXG4gKiBgbm93YCwgYHBhZGAsIGBwYWRMZWZ0YCwgYHBhZFJpZ2h0YCwgYHBhcnNlSW50YCwgYHBvcGAsIGByYW5kb21gLCBgcmVkdWNlYCxcbiAqIGByZWR1Y2VSaWdodGAsIGByZXBlYXRgLCBgcmVzdWx0YCwgYHJvdW5kYCwgYHJ1bkluQ29udGV4dGAsIGBzaGlmdGAsIGBzaXplYCxcbiAqIGBzbmFrZUNhc2VgLCBgc29tZWAsIGBzb3J0ZWRJbmRleGAsIGBzb3J0ZWRMYXN0SW5kZXhgLCBgc3RhcnRDYXNlYCxcbiAqIGBzdGFydHNXaXRoYCwgYHN1bWAsIGB0ZW1wbGF0ZWAsIGB0cmltYCwgYHRyaW1MZWZ0YCwgYHRyaW1SaWdodGAsIGB0cnVuY2AsXG4gKiBgdW5lc2NhcGVgLCBgdW5pcXVlSWRgLCBgdmFsdWVgLCBhbmQgYHdvcmRzYFxuICpcbiAqIFRoZSB3cmFwcGVyIG1ldGhvZCBgc2FtcGxlYCB3aWxsIHJldHVybiBhIHdyYXBwZWQgdmFsdWUgd2hlbiBgbmAgaXMgcHJvdmlkZWQsXG4gKiBvdGhlcndpc2UgYW4gdW53cmFwcGVkIHZhbHVlIGlzIHJldHVybmVkLlxuICpcbiAqIEBuYW1lIF9cbiAqIEBjb25zdHJ1Y3RvclxuICogQGNhdGVnb3J5IENoYWluXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB3cmFwIGluIGEgYGxvZGFzaGAgaW5zdGFuY2UuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgYGxvZGFzaGAgd3JhcHBlciBpbnN0YW5jZS5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIHdyYXBwZWQgPSBfKFsxLCAyLCAzXSk7XG4gKlxuICogLy8gcmV0dXJucyBhbiB1bndyYXBwZWQgdmFsdWVcbiAqIHdyYXBwZWQucmVkdWNlKGZ1bmN0aW9uKHRvdGFsLCBuKSB7XG4gKiAgIHJldHVybiB0b3RhbCArIG47XG4gKiB9KTtcbiAqIC8vID0+IDZcbiAqXG4gKiAvLyByZXR1cm5zIGEgd3JhcHBlZCB2YWx1ZVxuICogdmFyIHNxdWFyZXMgPSB3cmFwcGVkLm1hcChmdW5jdGlvbihuKSB7XG4gKiAgIHJldHVybiBuICogbjtcbiAqIH0pO1xuICpcbiAqIF8uaXNBcnJheShzcXVhcmVzKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc0FycmF5KHNxdWFyZXMudmFsdWUoKSk7XG4gKiAvLyA9PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGxvZGFzaCh2YWx1ZSkge1xuICBpZiAoaXNPYmplY3RMaWtlKHZhbHVlKSAmJiAhaXNBcnJheSh2YWx1ZSkgJiYgISh2YWx1ZSBpbnN0YW5jZW9mIExhenlXcmFwcGVyKSkge1xuICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIExvZGFzaFdyYXBwZXIpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsICdfX2NoYWluX18nKSAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCAnX193cmFwcGVkX18nKSkge1xuICAgICAgcmV0dXJuIHdyYXBwZXJDbG9uZSh2YWx1ZSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBuZXcgTG9kYXNoV3JhcHBlcih2YWx1ZSk7XG59XG5cbi8vIEVuc3VyZSB3cmFwcGVycyBhcmUgaW5zdGFuY2VzIG9mIGBiYXNlTG9kYXNoYC5cbmxvZGFzaC5wcm90b3R5cGUgPSBiYXNlTG9kYXNoLnByb3RvdHlwZTtcblxubW9kdWxlLmV4cG9ydHMgPSBsb2Rhc2g7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vZm9yRWFjaCcpO1xuIiwidmFyIGJhc2VFYWNoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZUVhY2gnKSxcbiAgICBjcmVhdGVGaW5kID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvY3JlYXRlRmluZCcpO1xuXG4vKipcbiAqIEl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2YgYGNvbGxlY3Rpb25gLCByZXR1cm5pbmcgdGhlIGZpcnN0IGVsZW1lbnRcbiAqIGBwcmVkaWNhdGVgIHJldHVybnMgdHJ1dGh5IGZvci4gVGhlIHByZWRpY2F0ZSBpcyBib3VuZCB0byBgdGhpc0FyZ2AgYW5kXG4gKiBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuXG4gKlxuICogSWYgYSBwcm9wZXJ0eSBuYW1lIGlzIHByb3ZpZGVkIGZvciBgcHJlZGljYXRlYCB0aGUgY3JlYXRlZCBgXy5wcm9wZXJ0eWBcbiAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlIG9mIHRoZSBnaXZlbiBlbGVtZW50LlxuICpcbiAqIElmIGEgdmFsdWUgaXMgYWxzbyBwcm92aWRlZCBmb3IgYHRoaXNBcmdgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNQcm9wZXJ0eWBcbiAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgYSBtYXRjaGluZyBwcm9wZXJ0eVxuICogdmFsdWUsIGVsc2UgYGZhbHNlYC5cbiAqXG4gKiBJZiBhbiBvYmplY3QgaXMgcHJvdmlkZWQgZm9yIGBwcmVkaWNhdGVgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNgIHN0eWxlXG4gKiBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBoYXZlIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBnaXZlblxuICogb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBhbGlhcyBkZXRlY3RcbiAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gc2VhcmNoLlxuICogQHBhcmFtIHtGdW5jdGlvbnxPYmplY3R8c3RyaW5nfSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkXG4gKiAgcGVyIGl0ZXJhdGlvbi5cbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgcHJlZGljYXRlYC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBtYXRjaGVkIGVsZW1lbnQsIGVsc2UgYHVuZGVmaW5lZGAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciB1c2VycyA9IFtcbiAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FnZSc6IDM2LCAnYWN0aXZlJzogdHJ1ZSB9LFxuICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICAnYWdlJzogNDAsICdhY3RpdmUnOiBmYWxzZSB9LFxuICogICB7ICd1c2VyJzogJ3BlYmJsZXMnLCAnYWdlJzogMSwgICdhY3RpdmUnOiB0cnVlIH1cbiAqIF07XG4gKlxuICogXy5yZXN1bHQoXy5maW5kKHVzZXJzLCBmdW5jdGlvbihjaHIpIHtcbiAqICAgcmV0dXJuIGNoci5hZ2UgPCA0MDtcbiAqIH0pLCAndXNlcicpO1xuICogLy8gPT4gJ2Jhcm5leSdcbiAqXG4gKiAvLyB1c2luZyB0aGUgYF8ubWF0Y2hlc2AgY2FsbGJhY2sgc2hvcnRoYW5kXG4gKiBfLnJlc3VsdChfLmZpbmQodXNlcnMsIHsgJ2FnZSc6IDEsICdhY3RpdmUnOiB0cnVlIH0pLCAndXNlcicpO1xuICogLy8gPT4gJ3BlYmJsZXMnXG4gKlxuICogLy8gdXNpbmcgdGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgY2FsbGJhY2sgc2hvcnRoYW5kXG4gKiBfLnJlc3VsdChfLmZpbmQodXNlcnMsICdhY3RpdmUnLCBmYWxzZSksICd1c2VyJyk7XG4gKiAvLyA9PiAnZnJlZCdcbiAqXG4gKiAvLyB1c2luZyB0aGUgYF8ucHJvcGVydHlgIGNhbGxiYWNrIHNob3J0aGFuZFxuICogXy5yZXN1bHQoXy5maW5kKHVzZXJzLCAnYWN0aXZlJyksICd1c2VyJyk7XG4gKiAvLyA9PiAnYmFybmV5J1xuICovXG52YXIgZmluZCA9IGNyZWF0ZUZpbmQoYmFzZUVhY2gpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZpbmQ7XG4iLCJ2YXIgYXJyYXlFYWNoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYXJyYXlFYWNoJyksXG4gICAgYmFzZUVhY2ggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlRWFjaCcpLFxuICAgIGNyZWF0ZUZvckVhY2ggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9jcmVhdGVGb3JFYWNoJyk7XG5cbi8qKlxuICogSXRlcmF0ZXMgb3ZlciBlbGVtZW50cyBvZiBgY29sbGVjdGlvbmAgaW52b2tpbmcgYGl0ZXJhdGVlYCBmb3IgZWFjaCBlbGVtZW50LlxuICogVGhlIGBpdGVyYXRlZWAgaXMgYm91bmQgdG8gYHRoaXNBcmdgIGFuZCBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOlxuICogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLiBJdGVyYXRlZSBmdW5jdGlvbnMgbWF5IGV4aXQgaXRlcmF0aW9uIGVhcmx5XG4gKiBieSBleHBsaWNpdGx5IHJldHVybmluZyBgZmFsc2VgLlxuICpcbiAqICoqTm90ZToqKiBBcyB3aXRoIG90aGVyIFwiQ29sbGVjdGlvbnNcIiBtZXRob2RzLCBvYmplY3RzIHdpdGggYSBcImxlbmd0aFwiIHByb3BlcnR5XG4gKiBhcmUgaXRlcmF0ZWQgbGlrZSBhcnJheXMuIFRvIGF2b2lkIHRoaXMgYmVoYXZpb3IgYF8uZm9ySW5gIG9yIGBfLmZvck93bmBcbiAqIG1heSBiZSB1c2VkIGZvciBvYmplY3QgaXRlcmF0aW9uLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAYWxpYXMgZWFjaFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgaXRlcmF0ZWVgLlxuICogQHJldHVybnMge0FycmF5fE9iamVjdHxzdHJpbmd9IFJldHVybnMgYGNvbGxlY3Rpb25gLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfKFsxLCAyXSkuZm9yRWFjaChmdW5jdGlvbihuKSB7XG4gKiAgIGNvbnNvbGUubG9nKG4pO1xuICogfSkudmFsdWUoKTtcbiAqIC8vID0+IGxvZ3MgZWFjaCB2YWx1ZSBmcm9tIGxlZnQgdG8gcmlnaHQgYW5kIHJldHVybnMgdGhlIGFycmF5XG4gKlxuICogXy5mb3JFYWNoKHsgJ2EnOiAxLCAnYic6IDIgfSwgZnVuY3Rpb24obiwga2V5KSB7XG4gKiAgIGNvbnNvbGUubG9nKG4sIGtleSk7XG4gKiB9KTtcbiAqIC8vID0+IGxvZ3MgZWFjaCB2YWx1ZS1rZXkgcGFpciBhbmQgcmV0dXJucyB0aGUgb2JqZWN0IChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gKi9cbnZhciBmb3JFYWNoID0gY3JlYXRlRm9yRWFjaChhcnJheUVhY2gsIGJhc2VFYWNoKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmb3JFYWNoO1xuIiwidmFyIGJhc2VJbmRleE9mID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZUluZGV4T2YnKSxcbiAgICBnZXRMZW5ndGggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9nZXRMZW5ndGgnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FycmF5JyksXG4gICAgaXNJdGVyYXRlZUNhbGwgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0l0ZXJhdGVlQ2FsbCcpLFxuICAgIGlzTGVuZ3RoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNMZW5ndGgnKSxcbiAgICBpc1N0cmluZyA9IHJlcXVpcmUoJy4uL2xhbmcvaXNTdHJpbmcnKSxcbiAgICB2YWx1ZXMgPSByZXF1aXJlKCcuLi9vYmplY3QvdmFsdWVzJyk7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlTWF4ID0gTWF0aC5tYXg7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB0YXJnZXRgIGlzIGluIGBjb2xsZWN0aW9uYCB1c2luZ1xuICogW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAqIGZvciBlcXVhbGl0eSBjb21wYXJpc29ucy4gSWYgYGZyb21JbmRleGAgaXMgbmVnYXRpdmUsIGl0J3MgdXNlZCBhcyB0aGUgb2Zmc2V0XG4gKiBmcm9tIHRoZSBlbmQgb2YgYGNvbGxlY3Rpb25gLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAYWxpYXMgY29udGFpbnMsIGluY2x1ZGVcbiAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gc2VhcmNoLlxuICogQHBhcmFtIHsqfSB0YXJnZXQgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gKiBAcGFyYW0ge251bWJlcn0gW2Zyb21JbmRleD0wXSBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYSBjYWxsYmFjayBmb3IgZnVuY3Rpb25zIGxpa2UgYF8ucmVkdWNlYC5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhIG1hdGNoaW5nIGVsZW1lbnQgaXMgZm91bmQsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pbmNsdWRlcyhbMSwgMiwgM10sIDEpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaW5jbHVkZXMoWzEsIDIsIDNdLCAxLCAyKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pbmNsdWRlcyh7ICd1c2VyJzogJ2ZyZWQnLCAnYWdlJzogNDAgfSwgJ2ZyZWQnKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmluY2x1ZGVzKCdwZWJibGVzJywgJ2ViJyk7XG4gKiAvLyA9PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGluY2x1ZGVzKGNvbGxlY3Rpb24sIHRhcmdldCwgZnJvbUluZGV4LCBndWFyZCkge1xuICB2YXIgbGVuZ3RoID0gY29sbGVjdGlvbiA/IGdldExlbmd0aChjb2xsZWN0aW9uKSA6IDA7XG4gIGlmICghaXNMZW5ndGgobGVuZ3RoKSkge1xuICAgIGNvbGxlY3Rpb24gPSB2YWx1ZXMoY29sbGVjdGlvbik7XG4gICAgbGVuZ3RoID0gY29sbGVjdGlvbi5sZW5ndGg7XG4gIH1cbiAgaWYgKHR5cGVvZiBmcm9tSW5kZXggIT0gJ251bWJlcicgfHwgKGd1YXJkICYmIGlzSXRlcmF0ZWVDYWxsKHRhcmdldCwgZnJvbUluZGV4LCBndWFyZCkpKSB7XG4gICAgZnJvbUluZGV4ID0gMDtcbiAgfSBlbHNlIHtcbiAgICBmcm9tSW5kZXggPSBmcm9tSW5kZXggPCAwID8gbmF0aXZlTWF4KGxlbmd0aCArIGZyb21JbmRleCwgMCkgOiAoZnJvbUluZGV4IHx8IDApO1xuICB9XG4gIHJldHVybiAodHlwZW9mIGNvbGxlY3Rpb24gPT0gJ3N0cmluZycgfHwgIWlzQXJyYXkoY29sbGVjdGlvbikgJiYgaXNTdHJpbmcoY29sbGVjdGlvbikpXG4gICAgPyAoZnJvbUluZGV4IDw9IGxlbmd0aCAmJiBjb2xsZWN0aW9uLmluZGV4T2YodGFyZ2V0LCBmcm9tSW5kZXgpID4gLTEpXG4gICAgOiAoISFsZW5ndGggJiYgYmFzZUluZGV4T2YoY29sbGVjdGlvbiwgdGFyZ2V0LCBmcm9tSW5kZXgpID4gLTEpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGluY2x1ZGVzO1xuIiwidmFyIGFycmF5TWFwID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYXJyYXlNYXAnKSxcbiAgICBiYXNlQ2FsbGJhY2sgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlQ2FsbGJhY2snKSxcbiAgICBiYXNlTWFwID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZU1hcCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IG9mIHZhbHVlcyBieSBydW5uaW5nIGVhY2ggZWxlbWVudCBpbiBgY29sbGVjdGlvbmAgdGhyb3VnaFxuICogYGl0ZXJhdGVlYC4gVGhlIGBpdGVyYXRlZWAgaXMgYm91bmQgdG8gYHRoaXNBcmdgIGFuZCBpbnZva2VkIHdpdGggdGhyZWVcbiAqIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLlxuICpcbiAqIElmIGEgcHJvcGVydHkgbmFtZSBpcyBwcm92aWRlZCBmb3IgYGl0ZXJhdGVlYCB0aGUgY3JlYXRlZCBgXy5wcm9wZXJ0eWBcbiAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlIG9mIHRoZSBnaXZlbiBlbGVtZW50LlxuICpcbiAqIElmIGEgdmFsdWUgaXMgYWxzbyBwcm92aWRlZCBmb3IgYHRoaXNBcmdgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNQcm9wZXJ0eWBcbiAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgYSBtYXRjaGluZyBwcm9wZXJ0eVxuICogdmFsdWUsIGVsc2UgYGZhbHNlYC5cbiAqXG4gKiBJZiBhbiBvYmplY3QgaXMgcHJvdmlkZWQgZm9yIGBpdGVyYXRlZWAgdGhlIGNyZWF0ZWQgYF8ubWF0Y2hlc2Agc3R5bGVcbiAqIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgdGhlIHByb3BlcnRpZXMgb2YgdGhlIGdpdmVuXG4gKiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqXG4gKiBNYW55IGxvZGFzaCBtZXRob2RzIGFyZSBndWFyZGVkIHRvIHdvcmsgYXMgaXRlcmF0ZWVzIGZvciBtZXRob2RzIGxpa2VcbiAqIGBfLmV2ZXJ5YCwgYF8uZmlsdGVyYCwgYF8ubWFwYCwgYF8ubWFwVmFsdWVzYCwgYF8ucmVqZWN0YCwgYW5kIGBfLnNvbWVgLlxuICpcbiAqIFRoZSBndWFyZGVkIG1ldGhvZHMgYXJlOlxuICogYGFyeWAsIGBjYWxsYmFja2AsIGBjaHVua2AsIGBjbG9uZWAsIGBjcmVhdGVgLCBgY3VycnlgLCBgY3VycnlSaWdodGAsXG4gKiBgZHJvcGAsIGBkcm9wUmlnaHRgLCBgZXZlcnlgLCBgZmlsbGAsIGBmbGF0dGVuYCwgYGludmVydGAsIGBtYXhgLCBgbWluYCxcbiAqIGBwYXJzZUludGAsIGBzbGljZWAsIGBzb3J0QnlgLCBgdGFrZWAsIGB0YWtlUmlnaHRgLCBgdGVtcGxhdGVgLCBgdHJpbWAsXG4gKiBgdHJpbUxlZnRgLCBgdHJpbVJpZ2h0YCwgYHRydW5jYCwgYHJhbmRvbWAsIGByYW5nZWAsIGBzYW1wbGVgLCBgc29tZWAsXG4gKiBgc3VtYCwgYHVuaXFgLCBhbmQgYHdvcmRzYFxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAYWxpYXMgY29sbGVjdFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdHxzdHJpbmd9IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZFxuICogIHBlciBpdGVyYXRpb24uXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGl0ZXJhdGVlYC5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IG1hcHBlZCBhcnJheS5cbiAqIEBleGFtcGxlXG4gKlxuICogZnVuY3Rpb24gdGltZXNUaHJlZShuKSB7XG4gKiAgIHJldHVybiBuICogMztcbiAqIH1cbiAqXG4gKiBfLm1hcChbMSwgMl0sIHRpbWVzVGhyZWUpO1xuICogLy8gPT4gWzMsIDZdXG4gKlxuICogXy5tYXAoeyAnYSc6IDEsICdiJzogMiB9LCB0aW1lc1RocmVlKTtcbiAqIC8vID0+IFszLCA2XSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICpcbiAqIHZhciB1c2VycyA9IFtcbiAqICAgeyAndXNlcic6ICdiYXJuZXknIH0sXG4gKiAgIHsgJ3VzZXInOiAnZnJlZCcgfVxuICogXTtcbiAqXG4gKiAvLyB1c2luZyB0aGUgYF8ucHJvcGVydHlgIGNhbGxiYWNrIHNob3J0aGFuZFxuICogXy5tYXAodXNlcnMsICd1c2VyJyk7XG4gKiAvLyA9PiBbJ2Jhcm5leScsICdmcmVkJ11cbiAqL1xuZnVuY3Rpb24gbWFwKGNvbGxlY3Rpb24sIGl0ZXJhdGVlLCB0aGlzQXJnKSB7XG4gIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5TWFwIDogYmFzZU1hcDtcbiAgaXRlcmF0ZWUgPSBiYXNlQ2FsbGJhY2soaXRlcmF0ZWUsIHRoaXNBcmcsIDMpO1xuICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBpdGVyYXRlZSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWFwO1xuIiwidmFyIGdldE5hdGl2ZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2dldE5hdGl2ZScpO1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU5vdyA9IGdldE5hdGl2ZShEYXRlLCAnbm93Jyk7XG5cbi8qKlxuICogR2V0cyB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0aGF0IGhhdmUgZWxhcHNlZCBzaW5jZSB0aGUgVW5peCBlcG9jaFxuICogKDEgSmFudWFyeSAxOTcwIDAwOjAwOjAwIFVUQykuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBEYXRlXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uZGVmZXIoZnVuY3Rpb24oc3RhbXApIHtcbiAqICAgY29uc29sZS5sb2coXy5ub3coKSAtIHN0YW1wKTtcbiAqIH0sIF8ubm93KCkpO1xuICogLy8gPT4gbG9ncyB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBpdCB0b29rIGZvciB0aGUgZGVmZXJyZWQgZnVuY3Rpb24gdG8gYmUgaW52b2tlZFxuICovXG52YXIgbm93ID0gbmF0aXZlTm93IHx8IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5vdztcbiIsInZhciBjcmVhdGVXcmFwcGVyID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvY3JlYXRlV3JhcHBlcicpLFxuICAgIHJlcGxhY2VIb2xkZXJzID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvcmVwbGFjZUhvbGRlcnMnKSxcbiAgICByZXN0UGFyYW0gPSByZXF1aXJlKCcuL3Jlc3RQYXJhbScpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB3cmFwcGVyIG1ldGFkYXRhLiAqL1xudmFyIEJJTkRfRkxBRyA9IDEsXG4gICAgUEFSVElBTF9GTEFHID0gMzI7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgYHRoaXNBcmdgXG4gKiBhbmQgcHJlcGVuZHMgYW55IGFkZGl0aW9uYWwgYF8uYmluZGAgYXJndW1lbnRzIHRvIHRob3NlIHByb3ZpZGVkIHRvIHRoZVxuICogYm91bmQgZnVuY3Rpb24uXG4gKlxuICogVGhlIGBfLmJpbmQucGxhY2Vob2xkZXJgIHZhbHVlLCB3aGljaCBkZWZhdWx0cyB0byBgX2AgaW4gbW9ub2xpdGhpYyBidWlsZHMsXG4gKiBtYXkgYmUgdXNlZCBhcyBhIHBsYWNlaG9sZGVyIGZvciBwYXJ0aWFsbHkgYXBwbGllZCBhcmd1bWVudHMuXG4gKlxuICogKipOb3RlOioqIFVubGlrZSBuYXRpdmUgYEZ1bmN0aW9uI2JpbmRgIHRoaXMgbWV0aG9kIGRvZXMgbm90IHNldCB0aGUgXCJsZW5ndGhcIlxuICogcHJvcGVydHkgb2YgYm91bmQgZnVuY3Rpb25zLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGJpbmQuXG4gKiBAcGFyYW0geyp9IHRoaXNBcmcgVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7Li4uKn0gW3BhcnRpYWxzXSBUaGUgYXJndW1lbnRzIHRvIGJlIHBhcnRpYWxseSBhcHBsaWVkLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYm91bmQgZnVuY3Rpb24uXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBncmVldCA9IGZ1bmN0aW9uKGdyZWV0aW5nLCBwdW5jdHVhdGlvbikge1xuICogICByZXR1cm4gZ3JlZXRpbmcgKyAnICcgKyB0aGlzLnVzZXIgKyBwdW5jdHVhdGlvbjtcbiAqIH07XG4gKlxuICogdmFyIG9iamVjdCA9IHsgJ3VzZXInOiAnZnJlZCcgfTtcbiAqXG4gKiB2YXIgYm91bmQgPSBfLmJpbmQoZ3JlZXQsIG9iamVjdCwgJ2hpJyk7XG4gKiBib3VuZCgnIScpO1xuICogLy8gPT4gJ2hpIGZyZWQhJ1xuICpcbiAqIC8vIHVzaW5nIHBsYWNlaG9sZGVyc1xuICogdmFyIGJvdW5kID0gXy5iaW5kKGdyZWV0LCBvYmplY3QsIF8sICchJyk7XG4gKiBib3VuZCgnaGknKTtcbiAqIC8vID0+ICdoaSBmcmVkISdcbiAqL1xudmFyIGJpbmQgPSByZXN0UGFyYW0oZnVuY3Rpb24oZnVuYywgdGhpc0FyZywgcGFydGlhbHMpIHtcbiAgdmFyIGJpdG1hc2sgPSBCSU5EX0ZMQUc7XG4gIGlmIChwYXJ0aWFscy5sZW5ndGgpIHtcbiAgICB2YXIgaG9sZGVycyA9IHJlcGxhY2VIb2xkZXJzKHBhcnRpYWxzLCBiaW5kLnBsYWNlaG9sZGVyKTtcbiAgICBiaXRtYXNrIHw9IFBBUlRJQUxfRkxBRztcbiAgfVxuICByZXR1cm4gY3JlYXRlV3JhcHBlcihmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscywgaG9sZGVycyk7XG59KTtcblxuLy8gQXNzaWduIGRlZmF1bHQgcGxhY2Vob2xkZXJzLlxuYmluZC5wbGFjZWhvbGRlciA9IHt9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJpbmQ7XG4iLCIvKiogVXNlZCBhcyB0aGUgYFR5cGVFcnJvcmAgbWVzc2FnZSBmb3IgXCJGdW5jdGlvbnNcIiBtZXRob2RzLiAqL1xudmFyIEZVTkNfRVJST1JfVEVYVCA9ICdFeHBlY3RlZCBhIGZ1bmN0aW9uJztcblxuLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heDtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBmdW5jYCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBvZiB0aGVcbiAqIGNyZWF0ZWQgZnVuY3Rpb24gYW5kIGFyZ3VtZW50cyBmcm9tIGBzdGFydGAgYW5kIGJleW9uZCBwcm92aWRlZCBhcyBhbiBhcnJheS5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgYmFzZWQgb24gdGhlIFtyZXN0IHBhcmFtZXRlcl0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0Z1bmN0aW9ucy9yZXN0X3BhcmFtZXRlcnMpLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFwcGx5IGEgcmVzdCBwYXJhbWV0ZXIgdG8uXG4gKiBAcGFyYW0ge251bWJlcn0gW3N0YXJ0PWZ1bmMubGVuZ3RoLTFdIFRoZSBzdGFydCBwb3NpdGlvbiBvZiB0aGUgcmVzdCBwYXJhbWV0ZXIuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIHNheSA9IF8ucmVzdFBhcmFtKGZ1bmN0aW9uKHdoYXQsIG5hbWVzKSB7XG4gKiAgIHJldHVybiB3aGF0ICsgJyAnICsgXy5pbml0aWFsKG5hbWVzKS5qb2luKCcsICcpICtcbiAqICAgICAoXy5zaXplKG5hbWVzKSA+IDEgPyAnLCAmICcgOiAnJykgKyBfLmxhc3QobmFtZXMpO1xuICogfSk7XG4gKlxuICogc2F5KCdoZWxsbycsICdmcmVkJywgJ2Jhcm5leScsICdwZWJibGVzJyk7XG4gKiAvLyA9PiAnaGVsbG8gZnJlZCwgYmFybmV5LCAmIHBlYmJsZXMnXG4gKi9cbmZ1bmN0aW9uIHJlc3RQYXJhbShmdW5jLCBzdGFydCkge1xuICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgfVxuICBzdGFydCA9IG5hdGl2ZU1heChzdGFydCA9PT0gdW5kZWZpbmVkID8gKGZ1bmMubGVuZ3RoIC0gMSkgOiAoK3N0YXJ0IHx8IDApLCAwKTtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciBhcmdzID0gYXJndW1lbnRzLFxuICAgICAgICBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSBuYXRpdmVNYXgoYXJncy5sZW5ndGggLSBzdGFydCwgMCksXG4gICAgICAgIHJlc3QgPSBBcnJheShsZW5ndGgpO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIHJlc3RbaW5kZXhdID0gYXJnc1tzdGFydCArIGluZGV4XTtcbiAgICB9XG4gICAgc3dpdGNoIChzdGFydCkge1xuICAgICAgY2FzZSAwOiByZXR1cm4gZnVuYy5jYWxsKHRoaXMsIHJlc3QpO1xuICAgICAgY2FzZSAxOiByZXR1cm4gZnVuYy5jYWxsKHRoaXMsIGFyZ3NbMF0sIHJlc3QpO1xuICAgICAgY2FzZSAyOiByZXR1cm4gZnVuYy5jYWxsKHRoaXMsIGFyZ3NbMF0sIGFyZ3NbMV0sIHJlc3QpO1xuICAgIH1cbiAgICB2YXIgb3RoZXJBcmdzID0gQXJyYXkoc3RhcnQgKyAxKTtcbiAgICBpbmRleCA9IC0xO1xuICAgIHdoaWxlICgrK2luZGV4IDwgc3RhcnQpIHtcbiAgICAgIG90aGVyQXJnc1tpbmRleF0gPSBhcmdzW2luZGV4XTtcbiAgICB9XG4gICAgb3RoZXJBcmdzW3N0YXJ0XSA9IHJlc3Q7XG4gICAgcmV0dXJuIGZ1bmMuYXBwbHkodGhpcywgb3RoZXJBcmdzKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSByZXN0UGFyYW07XG4iLCJ2YXIgYmFzZUNyZWF0ZSA9IHJlcXVpcmUoJy4vYmFzZUNyZWF0ZScpLFxuICAgIGJhc2VMb2Rhc2ggPSByZXF1aXJlKCcuL2Jhc2VMb2Rhc2gnKTtcblxuLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgYC1JbmZpbml0eWAgYW5kIGBJbmZpbml0eWAuICovXG52YXIgUE9TSVRJVkVfSU5GSU5JVFkgPSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGxhenkgd3JhcHBlciBvYmplY3Qgd2hpY2ggd3JhcHMgYHZhbHVlYCB0byBlbmFibGUgbGF6eSBldmFsdWF0aW9uLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB3cmFwLlxuICovXG5mdW5jdGlvbiBMYXp5V3JhcHBlcih2YWx1ZSkge1xuICB0aGlzLl9fd3JhcHBlZF9fID0gdmFsdWU7XG4gIHRoaXMuX19hY3Rpb25zX18gPSBbXTtcbiAgdGhpcy5fX2Rpcl9fID0gMTtcbiAgdGhpcy5fX2ZpbHRlcmVkX18gPSBmYWxzZTtcbiAgdGhpcy5fX2l0ZXJhdGVlc19fID0gW107XG4gIHRoaXMuX190YWtlQ291bnRfXyA9IFBPU0lUSVZFX0lORklOSVRZO1xuICB0aGlzLl9fdmlld3NfXyA9IFtdO1xufVxuXG5MYXp5V3JhcHBlci5wcm90b3R5cGUgPSBiYXNlQ3JlYXRlKGJhc2VMb2Rhc2gucHJvdG90eXBlKTtcbkxhenlXcmFwcGVyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IExhenlXcmFwcGVyO1xuXG5tb2R1bGUuZXhwb3J0cyA9IExhenlXcmFwcGVyO1xuIiwidmFyIGJhc2VDcmVhdGUgPSByZXF1aXJlKCcuL2Jhc2VDcmVhdGUnKSxcbiAgICBiYXNlTG9kYXNoID0gcmVxdWlyZSgnLi9iYXNlTG9kYXNoJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgY29uc3RydWN0b3IgZm9yIGNyZWF0aW5nIGBsb2Rhc2hgIHdyYXBwZXIgb2JqZWN0cy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gd3JhcC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2NoYWluQWxsXSBFbmFibGUgY2hhaW5pbmcgZm9yIGFsbCB3cmFwcGVyIG1ldGhvZHMuXG4gKiBAcGFyYW0ge0FycmF5fSBbYWN0aW9ucz1bXV0gQWN0aW9ucyB0byBwZWZvcm0gdG8gcmVzb2x2ZSB0aGUgdW53cmFwcGVkIHZhbHVlLlxuICovXG5mdW5jdGlvbiBMb2Rhc2hXcmFwcGVyKHZhbHVlLCBjaGFpbkFsbCwgYWN0aW9ucykge1xuICB0aGlzLl9fd3JhcHBlZF9fID0gdmFsdWU7XG4gIHRoaXMuX19hY3Rpb25zX18gPSBhY3Rpb25zIHx8IFtdO1xuICB0aGlzLl9fY2hhaW5fXyA9ICEhY2hhaW5BbGw7XG59XG5cbkxvZGFzaFdyYXBwZXIucHJvdG90eXBlID0gYmFzZUNyZWF0ZShiYXNlTG9kYXNoLnByb3RvdHlwZSk7XG5Mb2Rhc2hXcmFwcGVyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IExvZGFzaFdyYXBwZXI7XG5cbm1vZHVsZS5leHBvcnRzID0gTG9kYXNoV3JhcHBlcjtcbiIsIi8qKlxuICogQ29waWVzIHRoZSB2YWx1ZXMgb2YgYHNvdXJjZWAgdG8gYGFycmF5YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gc291cmNlIFRoZSBhcnJheSB0byBjb3B5IHZhbHVlcyBmcm9tLlxuICogQHBhcmFtIHtBcnJheX0gW2FycmF5PVtdXSBUaGUgYXJyYXkgdG8gY29weSB2YWx1ZXMgdG8uXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAqL1xuZnVuY3Rpb24gYXJyYXlDb3B5KHNvdXJjZSwgYXJyYXkpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBzb3VyY2UubGVuZ3RoO1xuXG4gIGFycmF5IHx8IChhcnJheSA9IEFycmF5KGxlbmd0aCkpO1xuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGFycmF5W2luZGV4XSA9IHNvdXJjZVtpbmRleF07XG4gIH1cbiAgcmV0dXJuIGFycmF5O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFycmF5Q29weTtcbiIsIi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmZvckVhY2hgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGFycmF5RWFjaChhcnJheSwgaXRlcmF0ZWUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBpZiAoaXRlcmF0ZWUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpID09PSBmYWxzZSkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHJldHVybiBhcnJheTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcnJheUVhY2g7XG4iLCIvKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5tYXBgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgbWFwcGVkIGFycmF5LlxuICovXG5mdW5jdGlvbiBhcnJheU1hcChhcnJheSwgaXRlcmF0ZWUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBBcnJheShsZW5ndGgpO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgcmVzdWx0W2luZGV4XSA9IGl0ZXJhdGVlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFycmF5TWFwO1xuIiwiLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uc29tZWAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gKiBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFueSBlbGVtZW50IHBhc3NlcyB0aGUgcHJlZGljYXRlIGNoZWNrLFxuICogIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYXJyYXlTb21lKGFycmF5LCBwcmVkaWNhdGUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBpZiAocHJlZGljYXRlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcnJheVNvbWU7XG4iLCJ2YXIgYmFzZUNvcHkgPSByZXF1aXJlKCcuL2Jhc2VDb3B5JyksXG4gICAga2V5cyA9IHJlcXVpcmUoJy4uL29iamVjdC9rZXlzJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uYXNzaWduYCB3aXRob3V0IHN1cHBvcnQgZm9yIGFyZ3VtZW50IGp1Z2dsaW5nLFxuICogbXVsdGlwbGUgc291cmNlcywgYW5kIGBjdXN0b21pemVyYCBmdW5jdGlvbnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIHNvdXJjZSBvYmplY3QuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICovXG5mdW5jdGlvbiBiYXNlQXNzaWduKG9iamVjdCwgc291cmNlKSB7XG4gIHJldHVybiBzb3VyY2UgPT0gbnVsbFxuICAgID8gb2JqZWN0XG4gICAgOiBiYXNlQ29weShzb3VyY2UsIGtleXMoc291cmNlKSwgb2JqZWN0KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlQXNzaWduO1xuIiwidmFyIGJhc2VNYXRjaGVzID0gcmVxdWlyZSgnLi9iYXNlTWF0Y2hlcycpLFxuICAgIGJhc2VNYXRjaGVzUHJvcGVydHkgPSByZXF1aXJlKCcuL2Jhc2VNYXRjaGVzUHJvcGVydHknKSxcbiAgICBiaW5kQ2FsbGJhY2sgPSByZXF1aXJlKCcuL2JpbmRDYWxsYmFjaycpLFxuICAgIGlkZW50aXR5ID0gcmVxdWlyZSgnLi4vdXRpbGl0eS9pZGVudGl0eScpLFxuICAgIHByb3BlcnR5ID0gcmVxdWlyZSgnLi4vdXRpbGl0eS9wcm9wZXJ0eScpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmNhbGxiYWNrYCB3aGljaCBzdXBwb3J0cyBzcGVjaWZ5aW5nIHRoZVxuICogbnVtYmVyIG9mIGFyZ3VtZW50cyB0byBwcm92aWRlIHRvIGBmdW5jYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSBbZnVuYz1fLmlkZW50aXR5XSBUaGUgdmFsdWUgdG8gY29udmVydCB0byBhIGNhbGxiYWNrLlxuICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJnQ291bnRdIFRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHRvIHByb3ZpZGUgdG8gYGZ1bmNgLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBjYWxsYmFjay5cbiAqL1xuZnVuY3Rpb24gYmFzZUNhbGxiYWNrKGZ1bmMsIHRoaXNBcmcsIGFyZ0NvdW50KSB7XG4gIHZhciB0eXBlID0gdHlwZW9mIGZ1bmM7XG4gIGlmICh0eXBlID09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gdGhpc0FyZyA9PT0gdW5kZWZpbmVkXG4gICAgICA/IGZ1bmNcbiAgICAgIDogYmluZENhbGxiYWNrKGZ1bmMsIHRoaXNBcmcsIGFyZ0NvdW50KTtcbiAgfVxuICBpZiAoZnVuYyA9PSBudWxsKSB7XG4gICAgcmV0dXJuIGlkZW50aXR5O1xuICB9XG4gIGlmICh0eXBlID09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIGJhc2VNYXRjaGVzKGZ1bmMpO1xuICB9XG4gIHJldHVybiB0aGlzQXJnID09PSB1bmRlZmluZWRcbiAgICA/IHByb3BlcnR5KGZ1bmMpXG4gICAgOiBiYXNlTWF0Y2hlc1Byb3BlcnR5KGZ1bmMsIHRoaXNBcmcpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VDYWxsYmFjaztcbiIsInZhciBhcnJheUNvcHkgPSByZXF1aXJlKCcuL2FycmF5Q29weScpLFxuICAgIGFycmF5RWFjaCA9IHJlcXVpcmUoJy4vYXJyYXlFYWNoJyksXG4gICAgYmFzZUFzc2lnbiA9IHJlcXVpcmUoJy4vYmFzZUFzc2lnbicpLFxuICAgIGJhc2VGb3JPd24gPSByZXF1aXJlKCcuL2Jhc2VGb3JPd24nKSxcbiAgICBpbml0Q2xvbmVBcnJheSA9IHJlcXVpcmUoJy4vaW5pdENsb25lQXJyYXknKSxcbiAgICBpbml0Q2xvbmVCeVRhZyA9IHJlcXVpcmUoJy4vaW5pdENsb25lQnlUYWcnKSxcbiAgICBpbml0Q2xvbmVPYmplY3QgPSByZXF1aXJlKCcuL2luaXRDbG9uZU9iamVjdCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICBpc0hvc3RPYmplY3QgPSByZXF1aXJlKCcuL2lzSG9zdE9iamVjdCcpLFxuICAgIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vbGFuZy9pc09iamVjdCcpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYXJnc1RhZyA9ICdbb2JqZWN0IEFyZ3VtZW50c10nLFxuICAgIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJyxcbiAgICBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgZXJyb3JUYWcgPSAnW29iamVjdCBFcnJvcl0nLFxuICAgIGZ1bmNUYWcgPSAnW29iamVjdCBGdW5jdGlvbl0nLFxuICAgIG1hcFRhZyA9ICdbb2JqZWN0IE1hcF0nLFxuICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nLFxuICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLFxuICAgIHNldFRhZyA9ICdbb2JqZWN0IFNldF0nLFxuICAgIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nLFxuICAgIHdlYWtNYXBUYWcgPSAnW29iamVjdCBXZWFrTWFwXSc7XG5cbnZhciBhcnJheUJ1ZmZlclRhZyA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsXG4gICAgZmxvYXQzMlRhZyA9ICdbb2JqZWN0IEZsb2F0MzJBcnJheV0nLFxuICAgIGZsb2F0NjRUYWcgPSAnW29iamVjdCBGbG9hdDY0QXJyYXldJyxcbiAgICBpbnQ4VGFnID0gJ1tvYmplY3QgSW50OEFycmF5XScsXG4gICAgaW50MTZUYWcgPSAnW29iamVjdCBJbnQxNkFycmF5XScsXG4gICAgaW50MzJUYWcgPSAnW29iamVjdCBJbnQzMkFycmF5XScsXG4gICAgdWludDhUYWcgPSAnW29iamVjdCBVaW50OEFycmF5XScsXG4gICAgdWludDhDbGFtcGVkVGFnID0gJ1tvYmplY3QgVWludDhDbGFtcGVkQXJyYXldJyxcbiAgICB1aW50MTZUYWcgPSAnW29iamVjdCBVaW50MTZBcnJheV0nLFxuICAgIHVpbnQzMlRhZyA9ICdbb2JqZWN0IFVpbnQzMkFycmF5XSc7XG5cbi8qKiBVc2VkIHRvIGlkZW50aWZ5IGB0b1N0cmluZ1RhZ2AgdmFsdWVzIHN1cHBvcnRlZCBieSBgXy5jbG9uZWAuICovXG52YXIgY2xvbmVhYmxlVGFncyA9IHt9O1xuY2xvbmVhYmxlVGFnc1thcmdzVGFnXSA9IGNsb25lYWJsZVRhZ3NbYXJyYXlUYWddID1cbmNsb25lYWJsZVRhZ3NbYXJyYXlCdWZmZXJUYWddID0gY2xvbmVhYmxlVGFnc1tib29sVGFnXSA9XG5jbG9uZWFibGVUYWdzW2RhdGVUYWddID0gY2xvbmVhYmxlVGFnc1tmbG9hdDMyVGFnXSA9XG5jbG9uZWFibGVUYWdzW2Zsb2F0NjRUYWddID0gY2xvbmVhYmxlVGFnc1tpbnQ4VGFnXSA9XG5jbG9uZWFibGVUYWdzW2ludDE2VGFnXSA9IGNsb25lYWJsZVRhZ3NbaW50MzJUYWddID1cbmNsb25lYWJsZVRhZ3NbbnVtYmVyVGFnXSA9IGNsb25lYWJsZVRhZ3Nbb2JqZWN0VGFnXSA9XG5jbG9uZWFibGVUYWdzW3JlZ2V4cFRhZ10gPSBjbG9uZWFibGVUYWdzW3N0cmluZ1RhZ10gPVxuY2xvbmVhYmxlVGFnc1t1aW50OFRhZ10gPSBjbG9uZWFibGVUYWdzW3VpbnQ4Q2xhbXBlZFRhZ10gPVxuY2xvbmVhYmxlVGFnc1t1aW50MTZUYWddID0gY2xvbmVhYmxlVGFnc1t1aW50MzJUYWddID0gdHJ1ZTtcbmNsb25lYWJsZVRhZ3NbZXJyb3JUYWddID0gY2xvbmVhYmxlVGFnc1tmdW5jVGFnXSA9XG5jbG9uZWFibGVUYWdzW21hcFRhZ10gPSBjbG9uZWFibGVUYWdzW3NldFRhZ10gPVxuY2xvbmVhYmxlVGFnc1t3ZWFrTWFwVGFnXSA9IGZhbHNlO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5jbG9uZWAgd2l0aG91dCBzdXBwb3J0IGZvciBhcmd1bWVudCBqdWdnbGluZ1xuICogYW5kIGB0aGlzYCBiaW5kaW5nIGBjdXN0b21pemVyYCBmdW5jdGlvbnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNsb25lLlxuICogQHBhcmFtIHtib29sZWFufSBbaXNEZWVwXSBTcGVjaWZ5IGEgZGVlcCBjbG9uZS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNsb25pbmcgdmFsdWVzLlxuICogQHBhcmFtIHtzdHJpbmd9IFtrZXldIFRoZSBrZXkgb2YgYHZhbHVlYC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0XSBUaGUgb2JqZWN0IGB2YWx1ZWAgYmVsb25ncyB0by5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0E9W11dIFRyYWNrcyB0cmF2ZXJzZWQgc291cmNlIG9iamVjdHMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tCPVtdXSBBc3NvY2lhdGVzIGNsb25lcyB3aXRoIHNvdXJjZSBjb3VudGVycGFydHMuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgY2xvbmVkIHZhbHVlLlxuICovXG5mdW5jdGlvbiBiYXNlQ2xvbmUodmFsdWUsIGlzRGVlcCwgY3VzdG9taXplciwga2V5LCBvYmplY3QsIHN0YWNrQSwgc3RhY2tCKSB7XG4gIHZhciByZXN1bHQ7XG4gIGlmIChjdXN0b21pemVyKSB7XG4gICAgcmVzdWx0ID0gb2JqZWN0ID8gY3VzdG9taXplcih2YWx1ZSwga2V5LCBvYmplY3QpIDogY3VzdG9taXplcih2YWx1ZSk7XG4gIH1cbiAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICBpZiAoIWlzT2JqZWN0KHZhbHVlKSkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuICB2YXIgaXNBcnIgPSBpc0FycmF5KHZhbHVlKTtcbiAgaWYgKGlzQXJyKSB7XG4gICAgcmVzdWx0ID0gaW5pdENsb25lQXJyYXkodmFsdWUpO1xuICAgIGlmICghaXNEZWVwKSB7XG4gICAgICByZXR1cm4gYXJyYXlDb3B5KHZhbHVlLCByZXN1bHQpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgdGFnID0gb2JqVG9TdHJpbmcuY2FsbCh2YWx1ZSksXG4gICAgICAgIGlzRnVuYyA9IHRhZyA9PSBmdW5jVGFnO1xuXG4gICAgaWYgKHRhZyA9PSBvYmplY3RUYWcgfHwgdGFnID09IGFyZ3NUYWcgfHwgKGlzRnVuYyAmJiAhb2JqZWN0KSkge1xuICAgICAgaWYgKGlzSG9zdE9iamVjdCh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIG9iamVjdCA/IHZhbHVlIDoge307XG4gICAgICB9XG4gICAgICByZXN1bHQgPSBpbml0Q2xvbmVPYmplY3QoaXNGdW5jID8ge30gOiB2YWx1ZSk7XG4gICAgICBpZiAoIWlzRGVlcCkge1xuICAgICAgICByZXR1cm4gYmFzZUFzc2lnbihyZXN1bHQsIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGNsb25lYWJsZVRhZ3NbdGFnXVxuICAgICAgICA/IGluaXRDbG9uZUJ5VGFnKHZhbHVlLCB0YWcsIGlzRGVlcClcbiAgICAgICAgOiAob2JqZWN0ID8gdmFsdWUgOiB7fSk7XG4gICAgfVxuICB9XG4gIC8vIENoZWNrIGZvciBjaXJjdWxhciByZWZlcmVuY2VzIGFuZCByZXR1cm4gaXRzIGNvcnJlc3BvbmRpbmcgY2xvbmUuXG4gIHN0YWNrQSB8fCAoc3RhY2tBID0gW10pO1xuICBzdGFja0IgfHwgKHN0YWNrQiA9IFtdKTtcblxuICB2YXIgbGVuZ3RoID0gc3RhY2tBLmxlbmd0aDtcbiAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgaWYgKHN0YWNrQVtsZW5ndGhdID09IHZhbHVlKSB7XG4gICAgICByZXR1cm4gc3RhY2tCW2xlbmd0aF07XG4gICAgfVxuICB9XG4gIC8vIEFkZCB0aGUgc291cmNlIHZhbHVlIHRvIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgb2JqZWN0cyBhbmQgYXNzb2NpYXRlIGl0IHdpdGggaXRzIGNsb25lLlxuICBzdGFja0EucHVzaCh2YWx1ZSk7XG4gIHN0YWNrQi5wdXNoKHJlc3VsdCk7XG5cbiAgLy8gUmVjdXJzaXZlbHkgcG9wdWxhdGUgY2xvbmUgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgKGlzQXJyID8gYXJyYXlFYWNoIDogYmFzZUZvck93bikodmFsdWUsIGZ1bmN0aW9uKHN1YlZhbHVlLCBrZXkpIHtcbiAgICByZXN1bHRba2V5XSA9IGJhc2VDbG9uZShzdWJWYWx1ZSwgaXNEZWVwLCBjdXN0b21pemVyLCBrZXksIHZhbHVlLCBzdGFja0EsIHN0YWNrQik7XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VDbG9uZTtcbiIsIi8qKlxuICogQ29waWVzIHByb3BlcnRpZXMgb2YgYHNvdXJjZWAgdG8gYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCB0byBjb3B5IHByb3BlcnRpZXMgZnJvbS5cbiAqIEBwYXJhbSB7QXJyYXl9IHByb3BzIFRoZSBwcm9wZXJ0eSBuYW1lcyB0byBjb3B5LlxuICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3Q9e31dIFRoZSBvYmplY3QgdG8gY29weSBwcm9wZXJ0aWVzIHRvLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gYmFzZUNvcHkoc291cmNlLCBwcm9wcywgb2JqZWN0KSB7XG4gIG9iamVjdCB8fCAob2JqZWN0ID0ge30pO1xuXG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gcHJvcHMubGVuZ3RoO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgdmFyIGtleSA9IHByb3BzW2luZGV4XTtcbiAgICBvYmplY3Rba2V5XSA9IHNvdXJjZVtrZXldO1xuICB9XG4gIHJldHVybiBvYmplY3Q7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUNvcHk7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uY3JlYXRlYCB3aXRob3V0IHN1cHBvcnQgZm9yIGFzc2lnbmluZ1xuICogcHJvcGVydGllcyB0byB0aGUgY3JlYXRlZCBvYmplY3QuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBwcm90b3R5cGUgVGhlIG9iamVjdCB0byBpbmhlcml0IGZyb20uXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICovXG52YXIgYmFzZUNyZWF0ZSA9IChmdW5jdGlvbigpIHtcbiAgZnVuY3Rpb24gb2JqZWN0KCkge31cbiAgcmV0dXJuIGZ1bmN0aW9uKHByb3RvdHlwZSkge1xuICAgIGlmIChpc09iamVjdChwcm90b3R5cGUpKSB7XG4gICAgICBvYmplY3QucHJvdG90eXBlID0gcHJvdG90eXBlO1xuICAgICAgdmFyIHJlc3VsdCA9IG5ldyBvYmplY3Q7XG4gICAgICBvYmplY3QucHJvdG90eXBlID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0IHx8IHt9O1xuICB9O1xufSgpKTtcblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlQ3JlYXRlO1xuIiwidmFyIGJhc2VGb3JPd24gPSByZXF1aXJlKCcuL2Jhc2VGb3JPd24nKSxcbiAgICBjcmVhdGVCYXNlRWFjaCA9IHJlcXVpcmUoJy4vY3JlYXRlQmFzZUVhY2gnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mb3JFYWNoYCB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gKiBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fHN0cmluZ30gUmV0dXJucyBgY29sbGVjdGlvbmAuXG4gKi9cbnZhciBiYXNlRWFjaCA9IGNyZWF0ZUJhc2VFYWNoKGJhc2VGb3JPd24pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VFYWNoO1xuIiwiLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5maW5kYCwgYF8uZmluZExhc3RgLCBgXy5maW5kS2V5YCwgYW5kIGBfLmZpbmRMYXN0S2V5YCxcbiAqIHdpdGhvdXQgc3VwcG9ydCBmb3IgY2FsbGJhY2sgc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcsIHdoaWNoIGl0ZXJhdGVzXG4gKiBvdmVyIGBjb2xsZWN0aW9uYCB1c2luZyB0aGUgcHJvdmlkZWQgYGVhY2hGdW5jYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHNlYXJjaC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZWFjaEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBgY29sbGVjdGlvbmAuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtyZXRLZXldIFNwZWNpZnkgcmV0dXJuaW5nIHRoZSBrZXkgb2YgdGhlIGZvdW5kIGVsZW1lbnRcbiAqICBpbnN0ZWFkIG9mIHRoZSBlbGVtZW50IGl0c2VsZi5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBmb3VuZCBlbGVtZW50IG9yIGl0cyBrZXksIGVsc2UgYHVuZGVmaW5lZGAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VGaW5kKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgZWFjaEZ1bmMsIHJldEtleSkge1xuICB2YXIgcmVzdWx0O1xuICBlYWNoRnVuYyhjb2xsZWN0aW9uLCBmdW5jdGlvbih2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKSB7XG4gICAgaWYgKHByZWRpY2F0ZSh2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKSkge1xuICAgICAgcmVzdWx0ID0gcmV0S2V5ID8ga2V5IDogdmFsdWU7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlRmluZDtcbiIsIi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZmluZEluZGV4YCBhbmQgYF8uZmluZExhc3RJbmRleGAgd2l0aG91dFxuICogc3VwcG9ydCBmb3IgY2FsbGJhY2sgc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzZWFyY2guXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIG1hdGNoZWQgdmFsdWUsIGVsc2UgYC0xYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUZpbmRJbmRleChhcnJheSwgcHJlZGljYXRlLCBmcm9tUmlnaHQpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIGluZGV4ID0gZnJvbVJpZ2h0ID8gbGVuZ3RoIDogLTE7XG5cbiAgd2hpbGUgKChmcm9tUmlnaHQgPyBpbmRleC0tIDogKytpbmRleCA8IGxlbmd0aCkpIHtcbiAgICBpZiAocHJlZGljYXRlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KSkge1xuICAgICAgcmV0dXJuIGluZGV4O1xuICAgIH1cbiAgfVxuICByZXR1cm4gLTE7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUZpbmRJbmRleDtcbiIsInZhciBjcmVhdGVCYXNlRm9yID0gcmVxdWlyZSgnLi9jcmVhdGVCYXNlRm9yJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGJhc2VGb3JJbmAgYW5kIGBiYXNlRm9yT3duYCB3aGljaCBpdGVyYXRlc1xuICogb3ZlciBgb2JqZWN0YCBwcm9wZXJ0aWVzIHJldHVybmVkIGJ5IGBrZXlzRnVuY2AgaW52b2tpbmcgYGl0ZXJhdGVlYCBmb3JcbiAqIGVhY2ggcHJvcGVydHkuIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdCBpdGVyYXRpb24gZWFybHkgYnkgZXhwbGljaXRseVxuICogcmV0dXJuaW5nIGBmYWxzZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHtGdW5jdGlvbn0ga2V5c0Z1bmMgVGhlIGZ1bmN0aW9uIHRvIGdldCB0aGUga2V5cyBvZiBgb2JqZWN0YC5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gKi9cbnZhciBiYXNlRm9yID0gY3JlYXRlQmFzZUZvcigpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VGb3I7XG4iLCJ2YXIgYmFzZUZvciA9IHJlcXVpcmUoJy4vYmFzZUZvcicpLFxuICAgIGtleXNJbiA9IHJlcXVpcmUoJy4uL29iamVjdC9rZXlzSW4nKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mb3JJbmAgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gYmFzZUZvckluKG9iamVjdCwgaXRlcmF0ZWUpIHtcbiAgcmV0dXJuIGJhc2VGb3Iob2JqZWN0LCBpdGVyYXRlZSwga2V5c0luKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlRm9ySW47XG4iLCJ2YXIgYmFzZUZvciA9IHJlcXVpcmUoJy4vYmFzZUZvcicpLFxuICAgIGtleXMgPSByZXF1aXJlKCcuLi9vYmplY3Qva2V5cycpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZvck93bmAgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gYmFzZUZvck93bihvYmplY3QsIGl0ZXJhdGVlKSB7XG4gIHJldHVybiBiYXNlRm9yKG9iamVjdCwgaXRlcmF0ZWUsIGtleXMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VGb3JPd247XG4iLCJ2YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL3RvT2JqZWN0Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGdldGAgd2l0aG91dCBzdXBwb3J0IGZvciBzdHJpbmcgcGF0aHNcbiAqIGFuZCBkZWZhdWx0IHZhbHVlcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtBcnJheX0gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHBhcmFtIHtzdHJpbmd9IFtwYXRoS2V5XSBUaGUga2V5IHJlcHJlc2VudGF0aW9uIG9mIHBhdGguXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmVzb2x2ZWQgdmFsdWUuXG4gKi9cbmZ1bmN0aW9uIGJhc2VHZXQob2JqZWN0LCBwYXRoLCBwYXRoS2V5KSB7XG4gIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgIHJldHVybjtcbiAgfVxuICBvYmplY3QgPSB0b09iamVjdChvYmplY3QpO1xuICBpZiAocGF0aEtleSAhPT0gdW5kZWZpbmVkICYmIHBhdGhLZXkgaW4gb2JqZWN0KSB7XG4gICAgcGF0aCA9IFtwYXRoS2V5XTtcbiAgfVxuICB2YXIgaW5kZXggPSAwLFxuICAgICAgbGVuZ3RoID0gcGF0aC5sZW5ndGg7XG5cbiAgd2hpbGUgKG9iamVjdCAhPSBudWxsICYmIGluZGV4IDwgbGVuZ3RoKSB7XG4gICAgb2JqZWN0ID0gdG9PYmplY3Qob2JqZWN0KVtwYXRoW2luZGV4KytdXTtcbiAgfVxuICByZXR1cm4gKGluZGV4ICYmIGluZGV4ID09IGxlbmd0aCkgPyBvYmplY3QgOiB1bmRlZmluZWQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUdldDtcbiIsInZhciBpbmRleE9mTmFOID0gcmVxdWlyZSgnLi9pbmRleE9mTmFOJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaW5kZXhPZmAgd2l0aG91dCBzdXBwb3J0IGZvciBiaW5hcnkgc2VhcmNoZXMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzZWFyY2guXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICogQHBhcmFtIHtudW1iZXJ9IGZyb21JbmRleCBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICovXG5mdW5jdGlvbiBiYXNlSW5kZXhPZihhcnJheSwgdmFsdWUsIGZyb21JbmRleCkge1xuICBpZiAodmFsdWUgIT09IHZhbHVlKSB7XG4gICAgcmV0dXJuIGluZGV4T2ZOYU4oYXJyYXksIGZyb21JbmRleCk7XG4gIH1cbiAgdmFyIGluZGV4ID0gZnJvbUluZGV4IC0gMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGlmIChhcnJheVtpbmRleF0gPT09IHZhbHVlKSB7XG4gICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuICB9XG4gIHJldHVybiAtMTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSW5kZXhPZjtcbiIsInZhciBiYXNlSXNFcXVhbERlZXAgPSByZXF1aXJlKCcuL2Jhc2VJc0VxdWFsRGVlcCcpLFxuICAgIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vbGFuZy9pc09iamVjdCcpLFxuICAgIGlzT2JqZWN0TGlrZSA9IHJlcXVpcmUoJy4vaXNPYmplY3RMaWtlJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNFcXVhbGAgd2l0aG91dCBzdXBwb3J0IGZvciBgdGhpc2AgYmluZGluZ1xuICogYGN1c3RvbWl6ZXJgIGZ1bmN0aW9ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpbmcgdmFsdWVzLlxuICogQHBhcmFtIHtib29sZWFufSBbaXNMb29zZV0gU3BlY2lmeSBwZXJmb3JtaW5nIHBhcnRpYWwgY29tcGFyaXNvbnMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tBXSBUcmFja3MgdHJhdmVyc2VkIGB2YWx1ZWAgb2JqZWN0cy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0JdIFRyYWNrcyB0cmF2ZXJzZWQgYG90aGVyYCBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUlzRXF1YWwodmFsdWUsIG90aGVyLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQikge1xuICBpZiAodmFsdWUgPT09IG90aGVyKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKHZhbHVlID09IG51bGwgfHwgb3RoZXIgPT0gbnVsbCB8fCAoIWlzT2JqZWN0KHZhbHVlKSAmJiAhaXNPYmplY3RMaWtlKG90aGVyKSkpIHtcbiAgICByZXR1cm4gdmFsdWUgIT09IHZhbHVlICYmIG90aGVyICE9PSBvdGhlcjtcbiAgfVxuICByZXR1cm4gYmFzZUlzRXF1YWxEZWVwKHZhbHVlLCBvdGhlciwgYmFzZUlzRXF1YWwsIGN1c3RvbWl6ZXIsIGlzTG9vc2UsIHN0YWNrQSwgc3RhY2tCKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNFcXVhbDtcbiIsInZhciBlcXVhbEFycmF5cyA9IHJlcXVpcmUoJy4vZXF1YWxBcnJheXMnKSxcbiAgICBlcXVhbEJ5VGFnID0gcmVxdWlyZSgnLi9lcXVhbEJ5VGFnJyksXG4gICAgZXF1YWxPYmplY3RzID0gcmVxdWlyZSgnLi9lcXVhbE9iamVjdHMnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FycmF5JyksXG4gICAgaXNIb3N0T2JqZWN0ID0gcmVxdWlyZSgnLi9pc0hvc3RPYmplY3QnKSxcbiAgICBpc1R5cGVkQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzVHlwZWRBcnJheScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYXJnc1RhZyA9ICdbb2JqZWN0IEFyZ3VtZW50c10nLFxuICAgIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJyxcbiAgICBvYmplY3RUYWcgPSAnW29iamVjdCBPYmplY3RdJztcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbGAgZm9yIGFycmF5cyBhbmQgb2JqZWN0cyB3aGljaCBwZXJmb3Jtc1xuICogZGVlcCBjb21wYXJpc29ucyBhbmQgdHJhY2tzIHRyYXZlcnNlZCBvYmplY3RzIGVuYWJsaW5nIG9iamVjdHMgd2l0aCBjaXJjdWxhclxuICogcmVmZXJlbmNlcyB0byBiZSBjb21wYXJlZC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge09iamVjdH0gb3RoZXIgVGhlIG90aGVyIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaW5nIG9iamVjdHMuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0xvb3NlXSBTcGVjaWZ5IHBlcmZvcm1pbmcgcGFydGlhbCBjb21wYXJpc29ucy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0E9W11dIFRyYWNrcyB0cmF2ZXJzZWQgYHZhbHVlYCBvYmplY3RzLlxuICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQj1bXV0gVHJhY2tzIHRyYXZlcnNlZCBgb3RoZXJgIG9iamVjdHMuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUlzRXF1YWxEZWVwKG9iamVjdCwgb3RoZXIsIGVxdWFsRnVuYywgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpIHtcbiAgdmFyIG9iaklzQXJyID0gaXNBcnJheShvYmplY3QpLFxuICAgICAgb3RoSXNBcnIgPSBpc0FycmF5KG90aGVyKSxcbiAgICAgIG9ialRhZyA9IGFycmF5VGFnLFxuICAgICAgb3RoVGFnID0gYXJyYXlUYWc7XG5cbiAgaWYgKCFvYmpJc0Fycikge1xuICAgIG9ialRhZyA9IG9ialRvU3RyaW5nLmNhbGwob2JqZWN0KTtcbiAgICBpZiAob2JqVGFnID09IGFyZ3NUYWcpIHtcbiAgICAgIG9ialRhZyA9IG9iamVjdFRhZztcbiAgICB9IGVsc2UgaWYgKG9ialRhZyAhPSBvYmplY3RUYWcpIHtcbiAgICAgIG9iaklzQXJyID0gaXNUeXBlZEFycmF5KG9iamVjdCk7XG4gICAgfVxuICB9XG4gIGlmICghb3RoSXNBcnIpIHtcbiAgICBvdGhUYWcgPSBvYmpUb1N0cmluZy5jYWxsKG90aGVyKTtcbiAgICBpZiAob3RoVGFnID09IGFyZ3NUYWcpIHtcbiAgICAgIG90aFRhZyA9IG9iamVjdFRhZztcbiAgICB9IGVsc2UgaWYgKG90aFRhZyAhPSBvYmplY3RUYWcpIHtcbiAgICAgIG90aElzQXJyID0gaXNUeXBlZEFycmF5KG90aGVyKTtcbiAgICB9XG4gIH1cbiAgdmFyIG9iaklzT2JqID0gb2JqVGFnID09IG9iamVjdFRhZyAmJiAhaXNIb3N0T2JqZWN0KG9iamVjdCksXG4gICAgICBvdGhJc09iaiA9IG90aFRhZyA9PSBvYmplY3RUYWcgJiYgIWlzSG9zdE9iamVjdChvdGhlciksXG4gICAgICBpc1NhbWVUYWcgPSBvYmpUYWcgPT0gb3RoVGFnO1xuXG4gIGlmIChpc1NhbWVUYWcgJiYgIShvYmpJc0FyciB8fCBvYmpJc09iaikpIHtcbiAgICByZXR1cm4gZXF1YWxCeVRhZyhvYmplY3QsIG90aGVyLCBvYmpUYWcpO1xuICB9XG4gIGlmICghaXNMb29zZSkge1xuICAgIHZhciBvYmpJc1dyYXBwZWQgPSBvYmpJc09iaiAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgJ19fd3JhcHBlZF9fJyksXG4gICAgICAgIG90aElzV3JhcHBlZCA9IG90aElzT2JqICYmIGhhc093blByb3BlcnR5LmNhbGwob3RoZXIsICdfX3dyYXBwZWRfXycpO1xuXG4gICAgaWYgKG9iaklzV3JhcHBlZCB8fCBvdGhJc1dyYXBwZWQpIHtcbiAgICAgIHJldHVybiBlcXVhbEZ1bmMob2JqSXNXcmFwcGVkID8gb2JqZWN0LnZhbHVlKCkgOiBvYmplY3QsIG90aElzV3JhcHBlZCA/IG90aGVyLnZhbHVlKCkgOiBvdGhlciwgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpO1xuICAgIH1cbiAgfVxuICBpZiAoIWlzU2FtZVRhZykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvLyBBc3N1bWUgY3ljbGljIHZhbHVlcyBhcmUgZXF1YWwuXG4gIC8vIEZvciBtb3JlIGluZm9ybWF0aW9uIG9uIGRldGVjdGluZyBjaXJjdWxhciByZWZlcmVuY2VzIHNlZSBodHRwczovL2VzNS5naXRodWIuaW8vI0pPLlxuICBzdGFja0EgfHwgKHN0YWNrQSA9IFtdKTtcbiAgc3RhY2tCIHx8IChzdGFja0IgPSBbXSk7XG5cbiAgdmFyIGxlbmd0aCA9IHN0YWNrQS5sZW5ndGg7XG4gIHdoaWxlIChsZW5ndGgtLSkge1xuICAgIGlmIChzdGFja0FbbGVuZ3RoXSA9PSBvYmplY3QpIHtcbiAgICAgIHJldHVybiBzdGFja0JbbGVuZ3RoXSA9PSBvdGhlcjtcbiAgICB9XG4gIH1cbiAgLy8gQWRkIGBvYmplY3RgIGFuZCBgb3RoZXJgIHRvIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgb2JqZWN0cy5cbiAgc3RhY2tBLnB1c2gob2JqZWN0KTtcbiAgc3RhY2tCLnB1c2gob3RoZXIpO1xuXG4gIHZhciByZXN1bHQgPSAob2JqSXNBcnIgPyBlcXVhbEFycmF5cyA6IGVxdWFsT2JqZWN0cykob2JqZWN0LCBvdGhlciwgZXF1YWxGdW5jLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQik7XG5cbiAgc3RhY2tBLnBvcCgpO1xuICBzdGFja0IucG9wKCk7XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNFcXVhbERlZXA7XG4iLCJ2YXIgYmFzZUlzRXF1YWwgPSByZXF1aXJlKCcuL2Jhc2VJc0VxdWFsJyksXG4gICAgdG9PYmplY3QgPSByZXF1aXJlKCcuL3RvT2JqZWN0Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNNYXRjaGAgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICogQHBhcmFtIHtBcnJheX0gbWF0Y2hEYXRhIFRoZSBwcm9wZXJ5IG5hbWVzLCB2YWx1ZXMsIGFuZCBjb21wYXJlIGZsYWdzIHRvIG1hdGNoLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaW5nIG9iamVjdHMuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYG9iamVjdGAgaXMgYSBtYXRjaCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBiYXNlSXNNYXRjaChvYmplY3QsIG1hdGNoRGF0YSwgY3VzdG9taXplcikge1xuICB2YXIgaW5kZXggPSBtYXRjaERhdGEubGVuZ3RoLFxuICAgICAgbGVuZ3RoID0gaW5kZXgsXG4gICAgICBub0N1c3RvbWl6ZXIgPSAhY3VzdG9taXplcjtcblxuICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICByZXR1cm4gIWxlbmd0aDtcbiAgfVxuICBvYmplY3QgPSB0b09iamVjdChvYmplY3QpO1xuICB3aGlsZSAoaW5kZXgtLSkge1xuICAgIHZhciBkYXRhID0gbWF0Y2hEYXRhW2luZGV4XTtcbiAgICBpZiAoKG5vQ3VzdG9taXplciAmJiBkYXRhWzJdKVxuICAgICAgICAgID8gZGF0YVsxXSAhPT0gb2JqZWN0W2RhdGFbMF1dXG4gICAgICAgICAgOiAhKGRhdGFbMF0gaW4gb2JqZWN0KVxuICAgICAgICApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBkYXRhID0gbWF0Y2hEYXRhW2luZGV4XTtcbiAgICB2YXIga2V5ID0gZGF0YVswXSxcbiAgICAgICAgb2JqVmFsdWUgPSBvYmplY3Rba2V5XSxcbiAgICAgICAgc3JjVmFsdWUgPSBkYXRhWzFdO1xuXG4gICAgaWYgKG5vQ3VzdG9taXplciAmJiBkYXRhWzJdKSB7XG4gICAgICBpZiAob2JqVmFsdWUgPT09IHVuZGVmaW5lZCAmJiAhKGtleSBpbiBvYmplY3QpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHJlc3VsdCA9IGN1c3RvbWl6ZXIgPyBjdXN0b21pemVyKG9ialZhbHVlLCBzcmNWYWx1ZSwga2V5KSA6IHVuZGVmaW5lZDtcbiAgICAgIGlmICghKHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gYmFzZUlzRXF1YWwoc3JjVmFsdWUsIG9ialZhbHVlLCBjdXN0b21pemVyLCB0cnVlKSA6IHJlc3VsdCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNNYXRjaDtcbiIsIi8qKlxuICogVGhlIGZ1bmN0aW9uIHdob3NlIHByb3RvdHlwZSBhbGwgY2hhaW5pbmcgd3JhcHBlcnMgaW5oZXJpdCBmcm9tLlxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGJhc2VMb2Rhc2goKSB7XG4gIC8vIE5vIG9wZXJhdGlvbiBwZXJmb3JtZWQuXG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUxvZGFzaDtcbiIsInZhciBiYXNlRWFjaCA9IHJlcXVpcmUoJy4vYmFzZUVhY2gnKSxcbiAgICBpc0FycmF5TGlrZSA9IHJlcXVpcmUoJy4vaXNBcnJheUxpa2UnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5tYXBgIHdpdGhvdXQgc3VwcG9ydCBmb3IgY2FsbGJhY2sgc2hvcnRoYW5kc1xuICogYW5kIGB0aGlzYCBiaW5kaW5nLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IG1hcHBlZCBhcnJheS5cbiAqL1xuZnVuY3Rpb24gYmFzZU1hcChjb2xsZWN0aW9uLCBpdGVyYXRlZSkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIHJlc3VsdCA9IGlzQXJyYXlMaWtlKGNvbGxlY3Rpb24pID8gQXJyYXkoY29sbGVjdGlvbi5sZW5ndGgpIDogW107XG5cbiAgYmFzZUVhY2goY29sbGVjdGlvbiwgZnVuY3Rpb24odmFsdWUsIGtleSwgY29sbGVjdGlvbikge1xuICAgIHJlc3VsdFsrK2luZGV4XSA9IGl0ZXJhdGVlKHZhbHVlLCBrZXksIGNvbGxlY3Rpb24pO1xuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlTWFwO1xuIiwidmFyIGJhc2VJc01hdGNoID0gcmVxdWlyZSgnLi9iYXNlSXNNYXRjaCcpLFxuICAgIGdldE1hdGNoRGF0YSA9IHJlcXVpcmUoJy4vZ2V0TWF0Y2hEYXRhJyksXG4gICAgdG9PYmplY3QgPSByZXF1aXJlKCcuL3RvT2JqZWN0Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ubWF0Y2hlc2Agd2hpY2ggZG9lcyBub3QgY2xvbmUgYHNvdXJjZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBwcm9wZXJ0eSB2YWx1ZXMgdG8gbWF0Y2guXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gYmFzZU1hdGNoZXMoc291cmNlKSB7XG4gIHZhciBtYXRjaERhdGEgPSBnZXRNYXRjaERhdGEoc291cmNlKTtcbiAgaWYgKG1hdGNoRGF0YS5sZW5ndGggPT0gMSAmJiBtYXRjaERhdGFbMF1bMl0pIHtcbiAgICB2YXIga2V5ID0gbWF0Y2hEYXRhWzBdWzBdLFxuICAgICAgICB2YWx1ZSA9IG1hdGNoRGF0YVswXVsxXTtcblxuICAgIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBvYmplY3QgPSB0b09iamVjdChvYmplY3QpO1xuICAgICAgcmV0dXJuIG9iamVjdFtrZXldID09PSB2YWx1ZSAmJiAodmFsdWUgIT09IHVuZGVmaW5lZCB8fCAoa2V5IGluIG9iamVjdCkpO1xuICAgIH07XG4gIH1cbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIHJldHVybiBiYXNlSXNNYXRjaChvYmplY3QsIG1hdGNoRGF0YSk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZU1hdGNoZXM7XG4iLCJ2YXIgYmFzZUdldCA9IHJlcXVpcmUoJy4vYmFzZUdldCcpLFxuICAgIGJhc2VJc0VxdWFsID0gcmVxdWlyZSgnLi9iYXNlSXNFcXVhbCcpLFxuICAgIGJhc2VTbGljZSA9IHJlcXVpcmUoJy4vYmFzZVNsaWNlJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcnJheScpLFxuICAgIGlzS2V5ID0gcmVxdWlyZSgnLi9pc0tleScpLFxuICAgIGlzU3RyaWN0Q29tcGFyYWJsZSA9IHJlcXVpcmUoJy4vaXNTdHJpY3RDb21wYXJhYmxlJyksXG4gICAgbGFzdCA9IHJlcXVpcmUoJy4uL2FycmF5L2xhc3QnKSxcbiAgICB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKSxcbiAgICB0b1BhdGggPSByZXF1aXJlKCcuL3RvUGF0aCcpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm1hdGNoZXNQcm9wZXJ0eWAgd2hpY2ggZG9lcyBub3QgY2xvbmUgYHNyY1ZhbHVlYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIGdldC5cbiAqIEBwYXJhbSB7Kn0gc3JjVmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gYmFzZU1hdGNoZXNQcm9wZXJ0eShwYXRoLCBzcmNWYWx1ZSkge1xuICB2YXIgaXNBcnIgPSBpc0FycmF5KHBhdGgpLFxuICAgICAgaXNDb21tb24gPSBpc0tleShwYXRoKSAmJiBpc1N0cmljdENvbXBhcmFibGUoc3JjVmFsdWUpLFxuICAgICAgcGF0aEtleSA9IChwYXRoICsgJycpO1xuXG4gIHBhdGggPSB0b1BhdGgocGF0aCk7XG4gIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdmFyIGtleSA9IHBhdGhLZXk7XG4gICAgb2JqZWN0ID0gdG9PYmplY3Qob2JqZWN0KTtcbiAgICBpZiAoKGlzQXJyIHx8ICFpc0NvbW1vbikgJiYgIShrZXkgaW4gb2JqZWN0KSkge1xuICAgICAgb2JqZWN0ID0gcGF0aC5sZW5ndGggPT0gMSA/IG9iamVjdCA6IGJhc2VHZXQob2JqZWN0LCBiYXNlU2xpY2UocGF0aCwgMCwgLTEpKTtcbiAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBrZXkgPSBsYXN0KHBhdGgpO1xuICAgICAgb2JqZWN0ID0gdG9PYmplY3Qob2JqZWN0KTtcbiAgICB9XG4gICAgcmV0dXJuIG9iamVjdFtrZXldID09PSBzcmNWYWx1ZVxuICAgICAgPyAoc3JjVmFsdWUgIT09IHVuZGVmaW5lZCB8fCAoa2V5IGluIG9iamVjdCkpXG4gICAgICA6IGJhc2VJc0VxdWFsKHNyY1ZhbHVlLCBvYmplY3Rba2V5XSwgdW5kZWZpbmVkLCB0cnVlKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlTWF0Y2hlc1Byb3BlcnR5O1xuIiwidmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi90b09iamVjdCcpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnByb3BlcnR5YCB3aXRob3V0IHN1cHBvcnQgZm9yIGRlZXAgcGF0aHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGJhc2VQcm9wZXJ0eShrZXkpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IHRvT2JqZWN0KG9iamVjdClba2V5XTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlUHJvcGVydHk7XG4iLCJ2YXIgYmFzZUdldCA9IHJlcXVpcmUoJy4vYmFzZUdldCcpLFxuICAgIHRvUGF0aCA9IHJlcXVpcmUoJy4vdG9QYXRoJyk7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlUHJvcGVydHlgIHdoaWNoIHN1cHBvcnRzIGRlZXAgcGF0aHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gYmFzZVByb3BlcnR5RGVlcChwYXRoKSB7XG4gIHZhciBwYXRoS2V5ID0gKHBhdGggKyAnJyk7XG4gIHBhdGggPSB0b1BhdGgocGF0aCk7XG4gIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICByZXR1cm4gYmFzZUdldChvYmplY3QsIHBhdGgsIHBhdGhLZXkpO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VQcm9wZXJ0eURlZXA7XG4iLCJ2YXIgaWRlbnRpdHkgPSByZXF1aXJlKCcuLi91dGlsaXR5L2lkZW50aXR5JyksXG4gICAgbWV0YU1hcCA9IHJlcXVpcmUoJy4vbWV0YU1hcCcpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBzZXREYXRhYCB3aXRob3V0IHN1cHBvcnQgZm9yIGhvdCBsb29wIGRldGVjdGlvbi5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYXNzb2NpYXRlIG1ldGFkYXRhIHdpdGguXG4gKiBAcGFyYW0geyp9IGRhdGEgVGhlIG1ldGFkYXRhLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGBmdW5jYC5cbiAqL1xudmFyIGJhc2VTZXREYXRhID0gIW1ldGFNYXAgPyBpZGVudGl0eSA6IGZ1bmN0aW9uKGZ1bmMsIGRhdGEpIHtcbiAgbWV0YU1hcC5zZXQoZnVuYywgZGF0YSk7XG4gIHJldHVybiBmdW5jO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlU2V0RGF0YTtcbiIsIi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uc2xpY2VgIHdpdGhvdXQgYW4gaXRlcmF0ZWUgY2FsbCBndWFyZC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNsaWNlLlxuICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD0wXSBUaGUgc3RhcnQgcG9zaXRpb24uXG4gKiBAcGFyYW0ge251bWJlcn0gW2VuZD1hcnJheS5sZW5ndGhdIFRoZSBlbmQgcG9zaXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VTbGljZShhcnJheSwgc3RhcnQsIGVuZCkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICBzdGFydCA9IHN0YXJ0ID09IG51bGwgPyAwIDogKCtzdGFydCB8fCAwKTtcbiAgaWYgKHN0YXJ0IDwgMCkge1xuICAgIHN0YXJ0ID0gLXN0YXJ0ID4gbGVuZ3RoID8gMCA6IChsZW5ndGggKyBzdGFydCk7XG4gIH1cbiAgZW5kID0gKGVuZCA9PT0gdW5kZWZpbmVkIHx8IGVuZCA+IGxlbmd0aCkgPyBsZW5ndGggOiAoK2VuZCB8fCAwKTtcbiAgaWYgKGVuZCA8IDApIHtcbiAgICBlbmQgKz0gbGVuZ3RoO1xuICB9XG4gIGxlbmd0aCA9IHN0YXJ0ID4gZW5kID8gMCA6ICgoZW5kIC0gc3RhcnQpID4+PiAwKTtcbiAgc3RhcnQgPj4+PSAwO1xuXG4gIHZhciByZXN1bHQgPSBBcnJheShsZW5ndGgpO1xuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHJlc3VsdFtpbmRleF0gPSBhcnJheVtpbmRleCArIHN0YXJ0XTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VTbGljZTtcbiIsIi8qKlxuICogQ29udmVydHMgYHZhbHVlYCB0byBhIHN0cmluZyBpZiBpdCdzIG5vdCBvbmUuIEFuIGVtcHR5IHN0cmluZyBpcyByZXR1cm5lZFxuICogZm9yIGBudWxsYCBvciBgdW5kZWZpbmVkYCB2YWx1ZXMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb2Nlc3MuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIGJhc2VUb1N0cmluZyh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgPT0gbnVsbCA/ICcnIDogKHZhbHVlICsgJycpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VUb1N0cmluZztcbiIsIi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8udmFsdWVzYCBhbmQgYF8udmFsdWVzSW5gIHdoaWNoIGNyZWF0ZXMgYW5cbiAqIGFycmF5IG9mIGBvYmplY3RgIHByb3BlcnR5IHZhbHVlcyBjb3JyZXNwb25kaW5nIHRvIHRoZSBwcm9wZXJ0eSBuYW1lc1xuICogb2YgYHByb3BzYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtBcnJheX0gcHJvcHMgVGhlIHByb3BlcnR5IG5hbWVzIHRvIGdldCB2YWx1ZXMgZm9yLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgdmFsdWVzLlxuICovXG5mdW5jdGlvbiBiYXNlVmFsdWVzKG9iamVjdCwgcHJvcHMpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBwcm9wcy5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBBcnJheShsZW5ndGgpO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgcmVzdWx0W2luZGV4XSA9IG9iamVjdFtwcm9wc1tpbmRleF1dO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZVZhbHVlcztcbiIsInZhciBiaW5hcnlJbmRleEJ5ID0gcmVxdWlyZSgnLi9iaW5hcnlJbmRleEJ5JyksXG4gICAgaWRlbnRpdHkgPSByZXF1aXJlKCcuLi91dGlsaXR5L2lkZW50aXR5Jyk7XG5cbi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHRoZSBtYXhpbXVtIGxlbmd0aCBhbmQgaW5kZXggb2YgYW4gYXJyYXkuICovXG52YXIgTUFYX0FSUkFZX0xFTkdUSCA9IDQyOTQ5NjcyOTUsXG4gICAgSEFMRl9NQVhfQVJSQVlfTEVOR1RIID0gTUFYX0FSUkFZX0xFTkdUSCA+Pj4gMTtcblxuLyoqXG4gKiBQZXJmb3JtcyBhIGJpbmFyeSBzZWFyY2ggb2YgYGFycmF5YCB0byBkZXRlcm1pbmUgdGhlIGluZGV4IGF0IHdoaWNoIGB2YWx1ZWBcbiAqIHNob3VsZCBiZSBpbnNlcnRlZCBpbnRvIGBhcnJheWAgaW4gb3JkZXIgdG8gbWFpbnRhaW4gaXRzIHNvcnQgb3JkZXIuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBzb3J0ZWQgYXJyYXkgdG8gaW5zcGVjdC5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGV2YWx1YXRlLlxuICogQHBhcmFtIHtib29sZWFufSBbcmV0SGlnaGVzdF0gU3BlY2lmeSByZXR1cm5pbmcgdGhlIGhpZ2hlc3QgcXVhbGlmaWVkIGluZGV4LlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggYXQgd2hpY2ggYHZhbHVlYCBzaG91bGQgYmUgaW5zZXJ0ZWRcbiAqICBpbnRvIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGJpbmFyeUluZGV4KGFycmF5LCB2YWx1ZSwgcmV0SGlnaGVzdCkge1xuICB2YXIgbG93ID0gMCxcbiAgICAgIGhpZ2ggPSBhcnJheSA/IGFycmF5Lmxlbmd0aCA6IGxvdztcblxuICBpZiAodHlwZW9mIHZhbHVlID09ICdudW1iZXInICYmIHZhbHVlID09PSB2YWx1ZSAmJiBoaWdoIDw9IEhBTEZfTUFYX0FSUkFZX0xFTkdUSCkge1xuICAgIHdoaWxlIChsb3cgPCBoaWdoKSB7XG4gICAgICB2YXIgbWlkID0gKGxvdyArIGhpZ2gpID4+PiAxLFxuICAgICAgICAgIGNvbXB1dGVkID0gYXJyYXlbbWlkXTtcblxuICAgICAgaWYgKChyZXRIaWdoZXN0ID8gKGNvbXB1dGVkIDw9IHZhbHVlKSA6IChjb21wdXRlZCA8IHZhbHVlKSkgJiYgY29tcHV0ZWQgIT09IG51bGwpIHtcbiAgICAgICAgbG93ID0gbWlkICsgMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGhpZ2ggPSBtaWQ7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBoaWdoO1xuICB9XG4gIHJldHVybiBiaW5hcnlJbmRleEJ5KGFycmF5LCB2YWx1ZSwgaWRlbnRpdHksIHJldEhpZ2hlc3QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJpbmFyeUluZGV4O1xuIiwiLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVGbG9vciA9IE1hdGguZmxvb3IsXG4gICAgbmF0aXZlTWluID0gTWF0aC5taW47XG5cbi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHRoZSBtYXhpbXVtIGxlbmd0aCBhbmQgaW5kZXggb2YgYW4gYXJyYXkuICovXG52YXIgTUFYX0FSUkFZX0xFTkdUSCA9IDQyOTQ5NjcyOTUsXG4gICAgTUFYX0FSUkFZX0lOREVYID0gTUFYX0FSUkFZX0xFTkdUSCAtIDE7XG5cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBpcyBsaWtlIGBiaW5hcnlJbmRleGAgZXhjZXB0IHRoYXQgaXQgaW52b2tlcyBgaXRlcmF0ZWVgIGZvclxuICogYHZhbHVlYCBhbmQgZWFjaCBlbGVtZW50IG9mIGBhcnJheWAgdG8gY29tcHV0ZSB0aGVpciBzb3J0IHJhbmtpbmcuIFRoZVxuICogaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDsgKHZhbHVlKS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIHNvcnRlZCBhcnJheSB0byBpbnNwZWN0LlxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gZXZhbHVhdGUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHtib29sZWFufSBbcmV0SGlnaGVzdF0gU3BlY2lmeSByZXR1cm5pbmcgdGhlIGhpZ2hlc3QgcXVhbGlmaWVkIGluZGV4LlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggYXQgd2hpY2ggYHZhbHVlYCBzaG91bGQgYmUgaW5zZXJ0ZWRcbiAqICBpbnRvIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGJpbmFyeUluZGV4QnkoYXJyYXksIHZhbHVlLCBpdGVyYXRlZSwgcmV0SGlnaGVzdCkge1xuICB2YWx1ZSA9IGl0ZXJhdGVlKHZhbHVlKTtcblxuICB2YXIgbG93ID0gMCxcbiAgICAgIGhpZ2ggPSBhcnJheSA/IGFycmF5Lmxlbmd0aCA6IDAsXG4gICAgICB2YWxJc05hTiA9IHZhbHVlICE9PSB2YWx1ZSxcbiAgICAgIHZhbElzTnVsbCA9IHZhbHVlID09PSBudWxsLFxuICAgICAgdmFsSXNVbmRlZiA9IHZhbHVlID09PSB1bmRlZmluZWQ7XG5cbiAgd2hpbGUgKGxvdyA8IGhpZ2gpIHtcbiAgICB2YXIgbWlkID0gbmF0aXZlRmxvb3IoKGxvdyArIGhpZ2gpIC8gMiksXG4gICAgICAgIGNvbXB1dGVkID0gaXRlcmF0ZWUoYXJyYXlbbWlkXSksXG4gICAgICAgIGlzRGVmID0gY29tcHV0ZWQgIT09IHVuZGVmaW5lZCxcbiAgICAgICAgaXNSZWZsZXhpdmUgPSBjb21wdXRlZCA9PT0gY29tcHV0ZWQ7XG5cbiAgICBpZiAodmFsSXNOYU4pIHtcbiAgICAgIHZhciBzZXRMb3cgPSBpc1JlZmxleGl2ZSB8fCByZXRIaWdoZXN0O1xuICAgIH0gZWxzZSBpZiAodmFsSXNOdWxsKSB7XG4gICAgICBzZXRMb3cgPSBpc1JlZmxleGl2ZSAmJiBpc0RlZiAmJiAocmV0SGlnaGVzdCB8fCBjb21wdXRlZCAhPSBudWxsKTtcbiAgICB9IGVsc2UgaWYgKHZhbElzVW5kZWYpIHtcbiAgICAgIHNldExvdyA9IGlzUmVmbGV4aXZlICYmIChyZXRIaWdoZXN0IHx8IGlzRGVmKTtcbiAgICB9IGVsc2UgaWYgKGNvbXB1dGVkID09IG51bGwpIHtcbiAgICAgIHNldExvdyA9IGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICBzZXRMb3cgPSByZXRIaWdoZXN0ID8gKGNvbXB1dGVkIDw9IHZhbHVlKSA6IChjb21wdXRlZCA8IHZhbHVlKTtcbiAgICB9XG4gICAgaWYgKHNldExvdykge1xuICAgICAgbG93ID0gbWlkICsgMTtcbiAgICB9IGVsc2Uge1xuICAgICAgaGlnaCA9IG1pZDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG5hdGl2ZU1pbihoaWdoLCBNQVhfQVJSQVlfSU5ERVgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJpbmFyeUluZGV4Qnk7XG4iLCJ2YXIgaWRlbnRpdHkgPSByZXF1aXJlKCcuLi91dGlsaXR5L2lkZW50aXR5Jyk7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlQ2FsbGJhY2tgIHdoaWNoIG9ubHkgc3VwcG9ydHMgYHRoaXNgIGJpbmRpbmdcbiAqIGFuZCBzcGVjaWZ5aW5nIHRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHRvIHByb3ZpZGUgdG8gYGZ1bmNgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBiaW5kLlxuICogQHBhcmFtIHsqfSB0aGlzQXJnIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge251bWJlcn0gW2FyZ0NvdW50XSBUaGUgbnVtYmVyIG9mIGFyZ3VtZW50cyB0byBwcm92aWRlIHRvIGBmdW5jYC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgY2FsbGJhY2suXG4gKi9cbmZ1bmN0aW9uIGJpbmRDYWxsYmFjayhmdW5jLCB0aGlzQXJnLCBhcmdDb3VudCkge1xuICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBpZGVudGl0eTtcbiAgfVxuICBpZiAodGhpc0FyZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGZ1bmM7XG4gIH1cbiAgc3dpdGNoIChhcmdDb3VudCkge1xuICAgIGNhc2UgMTogcmV0dXJuIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIHZhbHVlKTtcbiAgICB9O1xuICAgIGNhc2UgMzogcmV0dXJuIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikge1xuICAgICAgcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnLCB2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pO1xuICAgIH07XG4gICAgY2FzZSA0OiByZXR1cm4gZnVuY3Rpb24oYWNjdW11bGF0b3IsIHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikge1xuICAgICAgcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnLCBhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKTtcbiAgICB9O1xuICAgIGNhc2UgNTogcmV0dXJuIGZ1bmN0aW9uKHZhbHVlLCBvdGhlciwga2V5LCBvYmplY3QsIHNvdXJjZSkge1xuICAgICAgcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnLCB2YWx1ZSwgb3RoZXIsIGtleSwgb2JqZWN0LCBzb3VyY2UpO1xuICAgIH07XG4gIH1cbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBmdW5jLmFwcGx5KHRoaXNBcmcsIGFyZ3VtZW50cyk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmluZENhbGxiYWNrO1xuIiwiKGZ1bmN0aW9uIChnbG9iYWwpe1xuLyoqIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBBcnJheUJ1ZmZlciA9IGdsb2JhbC5BcnJheUJ1ZmZlcixcbiAgICBVaW50OEFycmF5ID0gZ2xvYmFsLlVpbnQ4QXJyYXk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGNsb25lIG9mIHRoZSBnaXZlbiBhcnJheSBidWZmZXIuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXlCdWZmZXJ9IGJ1ZmZlciBUaGUgYXJyYXkgYnVmZmVyIHRvIGNsb25lLlxuICogQHJldHVybnMge0FycmF5QnVmZmVyfSBSZXR1cm5zIHRoZSBjbG9uZWQgYXJyYXkgYnVmZmVyLlxuICovXG5mdW5jdGlvbiBidWZmZXJDbG9uZShidWZmZXIpIHtcbiAgdmFyIHJlc3VsdCA9IG5ldyBBcnJheUJ1ZmZlcihidWZmZXIuYnl0ZUxlbmd0aCksXG4gICAgICB2aWV3ID0gbmV3IFVpbnQ4QXJyYXkocmVzdWx0KTtcblxuICB2aWV3LnNldChuZXcgVWludDhBcnJheShidWZmZXIpKTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBidWZmZXJDbG9uZTtcblxufSkuY2FsbCh0aGlzLHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30pXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbTV2WkdWZmJXOWtkV3hsY3k5c2IyUmhjMmd0WTI5dGNHRjBMMmx1ZEdWeWJtRnNMMkoxWm1abGNrTnNiMjVsTG1weklsMHNJbTVoYldWeklqcGJYU3dpYldGd2NHbHVaM01pT2lJN1FVRkJRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEVpTENKbWFXeGxJam9pWjJWdVpYSmhkR1ZrTG1weklpd2ljMjkxY21ObFVtOXZkQ0k2SWlJc0luTnZkWEpqWlhORGIyNTBaVzUwSWpwYklpOHFLaUJPWVhScGRtVWdiV1YwYUc5a0lISmxabVZ5Wlc1alpYTXVJQ292WEc1MllYSWdRWEp5WVhsQ2RXWm1aWElnUFNCbmJHOWlZV3d1UVhKeVlYbENkV1ptWlhJc1hHNGdJQ0FnVldsdWREaEJjbkpoZVNBOUlHZHNiMkpoYkM1VmFXNTBPRUZ5Y21GNU8xeHVYRzR2S2lwY2JpQXFJRU55WldGMFpYTWdZU0JqYkc5dVpTQnZaaUIwYUdVZ1oybDJaVzRnWVhKeVlYa2dZblZtWm1WeUxseHVJQ3BjYmlBcUlFQndjbWwyWVhSbFhHNGdLaUJBY0dGeVlXMGdlMEZ5Y21GNVFuVm1abVZ5ZlNCaWRXWm1aWElnVkdobElHRnljbUY1SUdKMVptWmxjaUIwYnlCamJHOXVaUzVjYmlBcUlFQnlaWFIxY201eklIdEJjbkpoZVVKMVptWmxjbjBnVW1WMGRYSnVjeUIwYUdVZ1kyeHZibVZrSUdGeWNtRjVJR0oxWm1abGNpNWNiaUFxTDF4dVpuVnVZM1JwYjI0Z1luVm1abVZ5UTJ4dmJtVW9ZblZtWm1WeUtTQjdYRzRnSUhaaGNpQnlaWE4xYkhRZ1BTQnVaWGNnUVhKeVlYbENkV1ptWlhJb1luVm1abVZ5TG1KNWRHVk1aVzVuZEdncExGeHVJQ0FnSUNBZ2RtbGxkeUE5SUc1bGR5QlZhVzUwT0VGeWNtRjVLSEpsYzNWc2RDazdYRzVjYmlBZ2RtbGxkeTV6WlhRb2JtVjNJRlZwYm5RNFFYSnlZWGtvWW5WbVptVnlLU2s3WEc0Z0lISmxkSFZ5YmlCeVpYTjFiSFE3WEc1OVhHNWNibTF2WkhWc1pTNWxlSEJ2Y25SeklEMGdZblZtWm1WeVEyeHZibVU3WEc0aVhYMD0iLCIvKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4O1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgdGhhdCBpcyB0aGUgY29tcG9zaXRpb24gb2YgcGFydGlhbGx5IGFwcGxpZWQgYXJndW1lbnRzLFxuICogcGxhY2Vob2xkZXJzLCBhbmQgcHJvdmlkZWQgYXJndW1lbnRzIGludG8gYSBzaW5nbGUgYXJyYXkgb2YgYXJndW1lbnRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gYXJncyBUaGUgcHJvdmlkZWQgYXJndW1lbnRzLlxuICogQHBhcmFtIHtBcnJheX0gcGFydGlhbHMgVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkLlxuICogQHBhcmFtIHtBcnJheX0gaG9sZGVycyBUaGUgYHBhcnRpYWxzYCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgY29tcG9zZWQgYXJndW1lbnRzLlxuICovXG5mdW5jdGlvbiBjb21wb3NlQXJncyhhcmdzLCBwYXJ0aWFscywgaG9sZGVycykge1xuICB2YXIgaG9sZGVyc0xlbmd0aCA9IGhvbGRlcnMubGVuZ3RoLFxuICAgICAgYXJnc0luZGV4ID0gLTEsXG4gICAgICBhcmdzTGVuZ3RoID0gbmF0aXZlTWF4KGFyZ3MubGVuZ3RoIC0gaG9sZGVyc0xlbmd0aCwgMCksXG4gICAgICBsZWZ0SW5kZXggPSAtMSxcbiAgICAgIGxlZnRMZW5ndGggPSBwYXJ0aWFscy5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBBcnJheShsZWZ0TGVuZ3RoICsgYXJnc0xlbmd0aCk7XG5cbiAgd2hpbGUgKCsrbGVmdEluZGV4IDwgbGVmdExlbmd0aCkge1xuICAgIHJlc3VsdFtsZWZ0SW5kZXhdID0gcGFydGlhbHNbbGVmdEluZGV4XTtcbiAgfVxuICB3aGlsZSAoKythcmdzSW5kZXggPCBob2xkZXJzTGVuZ3RoKSB7XG4gICAgcmVzdWx0W2hvbGRlcnNbYXJnc0luZGV4XV0gPSBhcmdzW2FyZ3NJbmRleF07XG4gIH1cbiAgd2hpbGUgKGFyZ3NMZW5ndGgtLSkge1xuICAgIHJlc3VsdFtsZWZ0SW5kZXgrK10gPSBhcmdzW2FyZ3NJbmRleCsrXTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvbXBvc2VBcmdzO1xuIiwiLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heDtcblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2UgYGNvbXBvc2VBcmdzYCBleGNlcHQgdGhhdCB0aGUgYXJndW1lbnRzIGNvbXBvc2l0aW9uXG4gKiBpcyB0YWlsb3JlZCBmb3IgYF8ucGFydGlhbFJpZ2h0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGFyZ3MgVGhlIHByb3ZpZGVkIGFyZ3VtZW50cy5cbiAqIEBwYXJhbSB7QXJyYXl9IHBhcnRpYWxzIFRoZSBhcmd1bWVudHMgdG8gYXBwZW5kIHRvIHRob3NlIHByb3ZpZGVkLlxuICogQHBhcmFtIHtBcnJheX0gaG9sZGVycyBUaGUgYHBhcnRpYWxzYCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgY29tcG9zZWQgYXJndW1lbnRzLlxuICovXG5mdW5jdGlvbiBjb21wb3NlQXJnc1JpZ2h0KGFyZ3MsIHBhcnRpYWxzLCBob2xkZXJzKSB7XG4gIHZhciBob2xkZXJzSW5kZXggPSAtMSxcbiAgICAgIGhvbGRlcnNMZW5ndGggPSBob2xkZXJzLmxlbmd0aCxcbiAgICAgIGFyZ3NJbmRleCA9IC0xLFxuICAgICAgYXJnc0xlbmd0aCA9IG5hdGl2ZU1heChhcmdzLmxlbmd0aCAtIGhvbGRlcnNMZW5ndGgsIDApLFxuICAgICAgcmlnaHRJbmRleCA9IC0xLFxuICAgICAgcmlnaHRMZW5ndGggPSBwYXJ0aWFscy5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBBcnJheShhcmdzTGVuZ3RoICsgcmlnaHRMZW5ndGgpO1xuXG4gIHdoaWxlICgrK2FyZ3NJbmRleCA8IGFyZ3NMZW5ndGgpIHtcbiAgICByZXN1bHRbYXJnc0luZGV4XSA9IGFyZ3NbYXJnc0luZGV4XTtcbiAgfVxuICB2YXIgb2Zmc2V0ID0gYXJnc0luZGV4O1xuICB3aGlsZSAoKytyaWdodEluZGV4IDwgcmlnaHRMZW5ndGgpIHtcbiAgICByZXN1bHRbb2Zmc2V0ICsgcmlnaHRJbmRleF0gPSBwYXJ0aWFsc1tyaWdodEluZGV4XTtcbiAgfVxuICB3aGlsZSAoKytob2xkZXJzSW5kZXggPCBob2xkZXJzTGVuZ3RoKSB7XG4gICAgcmVzdWx0W29mZnNldCArIGhvbGRlcnNbaG9sZGVyc0luZGV4XV0gPSBhcmdzW2FyZ3NJbmRleCsrXTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvbXBvc2VBcmdzUmlnaHQ7XG4iLCJ2YXIgZ2V0TGVuZ3RoID0gcmVxdWlyZSgnLi9nZXRMZW5ndGgnKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4vaXNMZW5ndGgnKSxcbiAgICB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgYGJhc2VFYWNoYCBvciBgYmFzZUVhY2hSaWdodGAgZnVuY3Rpb24uXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGVhY2hGdW5jIFRoZSBmdW5jdGlvbiB0byBpdGVyYXRlIG92ZXIgYSBjb2xsZWN0aW9uLlxuICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBiYXNlIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVCYXNlRWFjaChlYWNoRnVuYywgZnJvbVJpZ2h0KSB7XG4gIHJldHVybiBmdW5jdGlvbihjb2xsZWN0aW9uLCBpdGVyYXRlZSkge1xuICAgIHZhciBsZW5ndGggPSBjb2xsZWN0aW9uID8gZ2V0TGVuZ3RoKGNvbGxlY3Rpb24pIDogMDtcbiAgICBpZiAoIWlzTGVuZ3RoKGxlbmd0aCkpIHtcbiAgICAgIHJldHVybiBlYWNoRnVuYyhjb2xsZWN0aW9uLCBpdGVyYXRlZSk7XG4gICAgfVxuICAgIHZhciBpbmRleCA9IGZyb21SaWdodCA/IGxlbmd0aCA6IC0xLFxuICAgICAgICBpdGVyYWJsZSA9IHRvT2JqZWN0KGNvbGxlY3Rpb24pO1xuXG4gICAgd2hpbGUgKChmcm9tUmlnaHQgPyBpbmRleC0tIDogKytpbmRleCA8IGxlbmd0aCkpIHtcbiAgICAgIGlmIChpdGVyYXRlZShpdGVyYWJsZVtpbmRleF0sIGluZGV4LCBpdGVyYWJsZSkgPT09IGZhbHNlKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gY29sbGVjdGlvbjtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVCYXNlRWFjaDtcbiIsInZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgYmFzZSBmdW5jdGlvbiBmb3IgYF8uZm9ySW5gIG9yIGBfLmZvckluUmlnaHRgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtmcm9tUmlnaHRdIFNwZWNpZnkgaXRlcmF0aW5nIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGJhc2UgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJhc2VGb3IoZnJvbVJpZ2h0KSB7XG4gIHJldHVybiBmdW5jdGlvbihvYmplY3QsIGl0ZXJhdGVlLCBrZXlzRnVuYykge1xuICAgIHZhciBpdGVyYWJsZSA9IHRvT2JqZWN0KG9iamVjdCksXG4gICAgICAgIHByb3BzID0ga2V5c0Z1bmMob2JqZWN0KSxcbiAgICAgICAgbGVuZ3RoID0gcHJvcHMubGVuZ3RoLFxuICAgICAgICBpbmRleCA9IGZyb21SaWdodCA/IGxlbmd0aCA6IC0xO1xuXG4gICAgd2hpbGUgKChmcm9tUmlnaHQgPyBpbmRleC0tIDogKytpbmRleCA8IGxlbmd0aCkpIHtcbiAgICAgIHZhciBrZXkgPSBwcm9wc1tpbmRleF07XG4gICAgICBpZiAoaXRlcmF0ZWUoaXRlcmFibGVba2V5XSwga2V5LCBpdGVyYWJsZSkgPT09IGZhbHNlKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0O1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUJhc2VGb3I7XG4iLCIoZnVuY3Rpb24gKGdsb2JhbCl7XG52YXIgY3JlYXRlQ3RvcldyYXBwZXIgPSByZXF1aXJlKCcuL2NyZWF0ZUN0b3JXcmFwcGVyJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYGZ1bmNgIGFuZCBpbnZva2VzIGl0IHdpdGggdGhlIGB0aGlzYFxuICogYmluZGluZyBvZiBgdGhpc0FyZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGJpbmQuXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYm91bmQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJpbmRXcmFwcGVyKGZ1bmMsIHRoaXNBcmcpIHtcbiAgdmFyIEN0b3IgPSBjcmVhdGVDdG9yV3JhcHBlcihmdW5jKTtcblxuICBmdW5jdGlvbiB3cmFwcGVyKCkge1xuICAgIHZhciBmbiA9ICh0aGlzICYmIHRoaXMgIT09IGdsb2JhbCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikgPyBDdG9yIDogZnVuYztcbiAgICByZXR1cm4gZm4uYXBwbHkodGhpc0FyZywgYXJndW1lbnRzKTtcbiAgfVxuICByZXR1cm4gd3JhcHBlcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVCaW5kV3JhcHBlcjtcblxufSkuY2FsbCh0aGlzLHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30pXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbTV2WkdWZmJXOWtkV3hsY3k5c2IyUmhjMmd0WTI5dGNHRjBMMmx1ZEdWeWJtRnNMMk55WldGMFpVSnBibVJYY21Gd2NHVnlMbXB6SWwwc0ltNWhiV1Z6SWpwYlhTd2liV0Z3Y0dsdVozTWlPaUk3UVVGQlFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJJaXdpWm1sc1pTSTZJbWRsYm1WeVlYUmxaQzVxY3lJc0luTnZkWEpqWlZKdmIzUWlPaUlpTENKemIzVnlZMlZ6UTI5dWRHVnVkQ0k2V3lKMllYSWdZM0psWVhSbFEzUnZjbGR5WVhCd1pYSWdQU0J5WlhGMWFYSmxLQ2N1TDJOeVpXRjBaVU4wYjNKWGNtRndjR1Z5SnlrN1hHNWNiaThxS2x4dUlDb2dRM0psWVhSbGN5QmhJR1oxYm1OMGFXOXVJSFJvWVhRZ2QzSmhjSE1nWUdaMWJtTmdJR0Z1WkNCcGJuWnZhMlZ6SUdsMElIZHBkR2dnZEdobElHQjBhR2x6WUZ4dUlDb2dZbWx1WkdsdVp5QnZaaUJnZEdocGMwRnlaMkF1WEc0Z0tseHVJQ29nUUhCeWFYWmhkR1ZjYmlBcUlFQndZWEpoYlNCN1JuVnVZM1JwYjI1OUlHWjFibU1nVkdobElHWjFibU4wYVc5dUlIUnZJR0pwYm1RdVhHNGdLaUJBY0dGeVlXMGdleXA5SUZ0MGFHbHpRWEpuWFNCVWFHVWdZSFJvYVhOZ0lHSnBibVJwYm1jZ2IyWWdZR1oxYm1OZ0xseHVJQ29nUUhKbGRIVnlibk1nZTBaMWJtTjBhVzl1ZlNCU1pYUjFjbTV6SUhSb1pTQnVaWGNnWW05MWJtUWdablZ1WTNScGIyNHVYRzRnS2k5Y2JtWjFibU4wYVc5dUlHTnlaV0YwWlVKcGJtUlhjbUZ3Y0dWeUtHWjFibU1zSUhSb2FYTkJjbWNwSUh0Y2JpQWdkbUZ5SUVOMGIzSWdQU0JqY21WaGRHVkRkRzl5VjNKaGNIQmxjaWhtZFc1aktUdGNibHh1SUNCbWRXNWpkR2x2YmlCM2NtRndjR1Z5S0NrZ2UxeHVJQ0FnSUhaaGNpQm1iaUE5SUNoMGFHbHpJQ1ltSUhSb2FYTWdJVDA5SUdkc2IySmhiQ0FtSmlCMGFHbHpJR2x1YzNSaGJtTmxiMllnZDNKaGNIQmxjaWtnUHlCRGRHOXlJRG9nWm5WdVl6dGNiaUFnSUNCeVpYUjFjbTRnWm00dVlYQndiSGtvZEdocGMwRnlaeXdnWVhKbmRXMWxiblJ6S1R0Y2JpQWdmVnh1SUNCeVpYUjFjbTRnZDNKaGNIQmxjanRjYm4xY2JseHViVzlrZFd4bExtVjRjRzl5ZEhNZ1BTQmpjbVZoZEdWQ2FXNWtWM0poY0hCbGNqdGNiaUpkZlE9PSIsInZhciBiYXNlQ3JlYXRlID0gcmVxdWlyZSgnLi9iYXNlQ3JlYXRlJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcHJvZHVjZXMgYW4gaW5zdGFuY2Ugb2YgYEN0b3JgIHJlZ2FyZGxlc3Mgb2ZcbiAqIHdoZXRoZXIgaXQgd2FzIGludm9rZWQgYXMgcGFydCBvZiBhIGBuZXdgIGV4cHJlc3Npb24gb3IgYnkgYGNhbGxgIG9yIGBhcHBseWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IEN0b3IgVGhlIGNvbnN0cnVjdG9yIHRvIHdyYXAuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVDdG9yV3JhcHBlcihDdG9yKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAvLyBVc2UgYSBgc3dpdGNoYCBzdGF0ZW1lbnQgdG8gd29yayB3aXRoIGNsYXNzIGNvbnN0cnVjdG9ycy5cbiAgICAvLyBTZWUgaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtZWNtYXNjcmlwdC1mdW5jdGlvbi1vYmplY3RzLWNhbGwtdGhpc2FyZ3VtZW50LWFyZ3VtZW50c2xpc3RcbiAgICAvLyBmb3IgbW9yZSBkZXRhaWxzLlxuICAgIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICAgIHN3aXRjaCAoYXJncy5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDogcmV0dXJuIG5ldyBDdG9yO1xuICAgICAgY2FzZSAxOiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSk7XG4gICAgICBjYXNlIDI6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdKTtcbiAgICAgIGNhc2UgMzogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgY2FzZSA0OiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSk7XG4gICAgICBjYXNlIDU6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdLCBhcmdzWzRdKTtcbiAgICAgIGNhc2UgNjogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10sIGFyZ3NbNF0sIGFyZ3NbNV0pO1xuICAgICAgY2FzZSA3OiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSwgYXJnc1s0XSwgYXJnc1s1XSwgYXJnc1s2XSk7XG4gICAgfVxuICAgIHZhciB0aGlzQmluZGluZyA9IGJhc2VDcmVhdGUoQ3Rvci5wcm90b3R5cGUpLFxuICAgICAgICByZXN1bHQgPSBDdG9yLmFwcGx5KHRoaXNCaW5kaW5nLCBhcmdzKTtcblxuICAgIC8vIE1pbWljIHRoZSBjb25zdHJ1Y3RvcidzIGByZXR1cm5gIGJlaGF2aW9yLlxuICAgIC8vIFNlZSBodHRwczovL2VzNS5naXRodWIuaW8vI3gxMy4yLjIgZm9yIG1vcmUgZGV0YWlscy5cbiAgICByZXR1cm4gaXNPYmplY3QocmVzdWx0KSA/IHJlc3VsdCA6IHRoaXNCaW5kaW5nO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUN0b3JXcmFwcGVyO1xuIiwidmFyIGJhc2VDYWxsYmFjayA9IHJlcXVpcmUoJy4vYmFzZUNhbGxiYWNrJyksXG4gICAgYmFzZUZpbmQgPSByZXF1aXJlKCcuL2Jhc2VGaW5kJyksXG4gICAgYmFzZUZpbmRJbmRleCA9IHJlcXVpcmUoJy4vYmFzZUZpbmRJbmRleCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgYF8uZmluZGAgb3IgYF8uZmluZExhc3RgIGZ1bmN0aW9uLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBlYWNoRnVuYyBUaGUgZnVuY3Rpb24gdG8gaXRlcmF0ZSBvdmVyIGEgY29sbGVjdGlvbi5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZmluZCBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlRmluZChlYWNoRnVuYywgZnJvbVJpZ2h0KSB7XG4gIHJldHVybiBmdW5jdGlvbihjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIHRoaXNBcmcpIHtcbiAgICBwcmVkaWNhdGUgPSBiYXNlQ2FsbGJhY2socHJlZGljYXRlLCB0aGlzQXJnLCAzKTtcbiAgICBpZiAoaXNBcnJheShjb2xsZWN0aW9uKSkge1xuICAgICAgdmFyIGluZGV4ID0gYmFzZUZpbmRJbmRleChjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIGZyb21SaWdodCk7XG4gICAgICByZXR1cm4gaW5kZXggPiAtMSA/IGNvbGxlY3Rpb25baW5kZXhdIDogdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4gYmFzZUZpbmQoY29sbGVjdGlvbiwgcHJlZGljYXRlLCBlYWNoRnVuYyk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlRmluZDtcbiIsInZhciBiaW5kQ2FsbGJhY2sgPSByZXF1aXJlKCcuL2JpbmRDYWxsYmFjaycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gZm9yIGBfLmZvckVhY2hgIG9yIGBfLmZvckVhY2hSaWdodGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGFycmF5RnVuYyBUaGUgZnVuY3Rpb24gdG8gaXRlcmF0ZSBvdmVyIGFuIGFycmF5LlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZWFjaEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBhIGNvbGxlY3Rpb24uXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBlYWNoIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVGb3JFYWNoKGFycmF5RnVuYywgZWFjaEZ1bmMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGNvbGxlY3Rpb24sIGl0ZXJhdGVlLCB0aGlzQXJnKSB7XG4gICAgcmV0dXJuICh0eXBlb2YgaXRlcmF0ZWUgPT0gJ2Z1bmN0aW9uJyAmJiB0aGlzQXJnID09PSB1bmRlZmluZWQgJiYgaXNBcnJheShjb2xsZWN0aW9uKSlcbiAgICAgID8gYXJyYXlGdW5jKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKVxuICAgICAgOiBlYWNoRnVuYyhjb2xsZWN0aW9uLCBiaW5kQ2FsbGJhY2soaXRlcmF0ZWUsIHRoaXNBcmcsIDMpKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVGb3JFYWNoO1xuIiwiKGZ1bmN0aW9uIChnbG9iYWwpe1xudmFyIGFycmF5Q29weSA9IHJlcXVpcmUoJy4vYXJyYXlDb3B5JyksXG4gICAgY29tcG9zZUFyZ3MgPSByZXF1aXJlKCcuL2NvbXBvc2VBcmdzJyksXG4gICAgY29tcG9zZUFyZ3NSaWdodCA9IHJlcXVpcmUoJy4vY29tcG9zZUFyZ3NSaWdodCcpLFxuICAgIGNyZWF0ZUN0b3JXcmFwcGVyID0gcmVxdWlyZSgnLi9jcmVhdGVDdG9yV3JhcHBlcicpLFxuICAgIGlzTGF6aWFibGUgPSByZXF1aXJlKCcuL2lzTGF6aWFibGUnKSxcbiAgICByZW9yZGVyID0gcmVxdWlyZSgnLi9yZW9yZGVyJyksXG4gICAgcmVwbGFjZUhvbGRlcnMgPSByZXF1aXJlKCcuL3JlcGxhY2VIb2xkZXJzJyksXG4gICAgc2V0RGF0YSA9IHJlcXVpcmUoJy4vc2V0RGF0YScpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB3cmFwcGVyIG1ldGFkYXRhLiAqL1xudmFyIEJJTkRfRkxBRyA9IDEsXG4gICAgQklORF9LRVlfRkxBRyA9IDIsXG4gICAgQ1VSUllfQk9VTkRfRkxBRyA9IDQsXG4gICAgQ1VSUllfRkxBRyA9IDgsXG4gICAgQ1VSUllfUklHSFRfRkxBRyA9IDE2LFxuICAgIFBBUlRJQUxfRkxBRyA9IDMyLFxuICAgIFBBUlRJQUxfUklHSFRfRkxBRyA9IDY0LFxuICAgIEFSWV9GTEFHID0gMTI4O1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHdyYXBzIGBmdW5jYCBhbmQgaW52b2tlcyBpdCB3aXRoIG9wdGlvbmFsIGB0aGlzYFxuICogYmluZGluZyBvZiwgcGFydGlhbCBhcHBsaWNhdGlvbiwgYW5kIGN1cnJ5aW5nLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufHN0cmluZ30gZnVuYyBUaGUgZnVuY3Rpb24gb3IgbWV0aG9kIG5hbWUgdG8gcmVmZXJlbmNlLlxuICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgb2YgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcHBlcmAgZm9yIG1vcmUgZGV0YWlscy5cbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge0FycmF5fSBbcGFydGlhbHNdIFRoZSBhcmd1bWVudHMgdG8gcHJlcGVuZCB0byB0aG9zZSBwcm92aWRlZCB0byB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNdIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gKiBAcGFyYW0ge0FycmF5fSBbcGFydGlhbHNSaWdodF0gVGhlIGFyZ3VtZW50cyB0byBhcHBlbmQgdG8gdGhvc2UgcHJvdmlkZWQgdG8gdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7QXJyYXl9IFtob2xkZXJzUmlnaHRdIFRoZSBgcGFydGlhbHNSaWdodGAgcGxhY2Vob2xkZXIgaW5kZXhlcy5cbiAqIEBwYXJhbSB7QXJyYXl9IFthcmdQb3NdIFRoZSBhcmd1bWVudCBwb3NpdGlvbnMgb2YgdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJ5XSBUaGUgYXJpdHkgY2FwIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJpdHldIFRoZSBhcml0eSBvZiBgZnVuY2AuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVIeWJyaWRXcmFwcGVyKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzLCBwYXJ0aWFsc1JpZ2h0LCBob2xkZXJzUmlnaHQsIGFyZ1BvcywgYXJ5LCBhcml0eSkge1xuICB2YXIgaXNBcnkgPSBiaXRtYXNrICYgQVJZX0ZMQUcsXG4gICAgICBpc0JpbmQgPSBiaXRtYXNrICYgQklORF9GTEFHLFxuICAgICAgaXNCaW5kS2V5ID0gYml0bWFzayAmIEJJTkRfS0VZX0ZMQUcsXG4gICAgICBpc0N1cnJ5ID0gYml0bWFzayAmIENVUlJZX0ZMQUcsXG4gICAgICBpc0N1cnJ5Qm91bmQgPSBiaXRtYXNrICYgQ1VSUllfQk9VTkRfRkxBRyxcbiAgICAgIGlzQ3VycnlSaWdodCA9IGJpdG1hc2sgJiBDVVJSWV9SSUdIVF9GTEFHLFxuICAgICAgQ3RvciA9IGlzQmluZEtleSA/IHVuZGVmaW5lZCA6IGNyZWF0ZUN0b3JXcmFwcGVyKGZ1bmMpO1xuXG4gIGZ1bmN0aW9uIHdyYXBwZXIoKSB7XG4gICAgLy8gQXZvaWQgYGFyZ3VtZW50c2Agb2JqZWN0IHVzZSBkaXNxdWFsaWZ5aW5nIG9wdGltaXphdGlvbnMgYnlcbiAgICAvLyBjb252ZXJ0aW5nIGl0IHRvIGFuIGFycmF5IGJlZm9yZSBwcm92aWRpbmcgaXQgdG8gb3RoZXIgZnVuY3Rpb25zLlxuICAgIHZhciBsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoLFxuICAgICAgICBpbmRleCA9IGxlbmd0aCxcbiAgICAgICAgYXJncyA9IEFycmF5KGxlbmd0aCk7XG5cbiAgICB3aGlsZSAoaW5kZXgtLSkge1xuICAgICAgYXJnc1tpbmRleF0gPSBhcmd1bWVudHNbaW5kZXhdO1xuICAgIH1cbiAgICBpZiAocGFydGlhbHMpIHtcbiAgICAgIGFyZ3MgPSBjb21wb3NlQXJncyhhcmdzLCBwYXJ0aWFscywgaG9sZGVycyk7XG4gICAgfVxuICAgIGlmIChwYXJ0aWFsc1JpZ2h0KSB7XG4gICAgICBhcmdzID0gY29tcG9zZUFyZ3NSaWdodChhcmdzLCBwYXJ0aWFsc1JpZ2h0LCBob2xkZXJzUmlnaHQpO1xuICAgIH1cbiAgICBpZiAoaXNDdXJyeSB8fCBpc0N1cnJ5UmlnaHQpIHtcbiAgICAgIHZhciBwbGFjZWhvbGRlciA9IHdyYXBwZXIucGxhY2Vob2xkZXIsXG4gICAgICAgICAgYXJnc0hvbGRlcnMgPSByZXBsYWNlSG9sZGVycyhhcmdzLCBwbGFjZWhvbGRlcik7XG5cbiAgICAgIGxlbmd0aCAtPSBhcmdzSG9sZGVycy5sZW5ndGg7XG4gICAgICBpZiAobGVuZ3RoIDwgYXJpdHkpIHtcbiAgICAgICAgdmFyIG5ld0FyZ1BvcyA9IGFyZ1BvcyA/IGFycmF5Q29weShhcmdQb3MpIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgbmV3QXJpdHkgPSBuYXRpdmVNYXgoYXJpdHkgLSBsZW5ndGgsIDApLFxuICAgICAgICAgICAgbmV3c0hvbGRlcnMgPSBpc0N1cnJ5ID8gYXJnc0hvbGRlcnMgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBuZXdIb2xkZXJzUmlnaHQgPSBpc0N1cnJ5ID8gdW5kZWZpbmVkIDogYXJnc0hvbGRlcnMsXG4gICAgICAgICAgICBuZXdQYXJ0aWFscyA9IGlzQ3VycnkgPyBhcmdzIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgbmV3UGFydGlhbHNSaWdodCA9IGlzQ3VycnkgPyB1bmRlZmluZWQgOiBhcmdzO1xuXG4gICAgICAgIGJpdG1hc2sgfD0gKGlzQ3VycnkgPyBQQVJUSUFMX0ZMQUcgOiBQQVJUSUFMX1JJR0hUX0ZMQUcpO1xuICAgICAgICBiaXRtYXNrICY9IH4oaXNDdXJyeSA/IFBBUlRJQUxfUklHSFRfRkxBRyA6IFBBUlRJQUxfRkxBRyk7XG5cbiAgICAgICAgaWYgKCFpc0N1cnJ5Qm91bmQpIHtcbiAgICAgICAgICBiaXRtYXNrICY9IH4oQklORF9GTEFHIHwgQklORF9LRVlfRkxBRyk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIG5ld0RhdGEgPSBbZnVuYywgYml0bWFzaywgdGhpc0FyZywgbmV3UGFydGlhbHMsIG5ld3NIb2xkZXJzLCBuZXdQYXJ0aWFsc1JpZ2h0LCBuZXdIb2xkZXJzUmlnaHQsIG5ld0FyZ1BvcywgYXJ5LCBuZXdBcml0eV0sXG4gICAgICAgICAgICByZXN1bHQgPSBjcmVhdGVIeWJyaWRXcmFwcGVyLmFwcGx5KHVuZGVmaW5lZCwgbmV3RGF0YSk7XG5cbiAgICAgICAgaWYgKGlzTGF6aWFibGUoZnVuYykpIHtcbiAgICAgICAgICBzZXREYXRhKHJlc3VsdCwgbmV3RGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzdWx0LnBsYWNlaG9sZGVyID0gcGxhY2Vob2xkZXI7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgfVxuICAgIHZhciB0aGlzQmluZGluZyA9IGlzQmluZCA/IHRoaXNBcmcgOiB0aGlzLFxuICAgICAgICBmbiA9IGlzQmluZEtleSA/IHRoaXNCaW5kaW5nW2Z1bmNdIDogZnVuYztcblxuICAgIGlmIChhcmdQb3MpIHtcbiAgICAgIGFyZ3MgPSByZW9yZGVyKGFyZ3MsIGFyZ1Bvcyk7XG4gICAgfVxuICAgIGlmIChpc0FyeSAmJiBhcnkgPCBhcmdzLmxlbmd0aCkge1xuICAgICAgYXJncy5sZW5ndGggPSBhcnk7XG4gICAgfVxuICAgIGlmICh0aGlzICYmIHRoaXMgIT09IGdsb2JhbCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikge1xuICAgICAgZm4gPSBDdG9yIHx8IGNyZWF0ZUN0b3JXcmFwcGVyKGZ1bmMpO1xuICAgIH1cbiAgICByZXR1cm4gZm4uYXBwbHkodGhpc0JpbmRpbmcsIGFyZ3MpO1xuICB9XG4gIHJldHVybiB3cmFwcGVyO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUh5YnJpZFdyYXBwZXI7XG5cbn0pLmNhbGwodGhpcyx0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDogdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9KVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ6dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiSW01dlpHVmZiVzlrZFd4bGN5OXNiMlJoYzJndFkyOXRjR0YwTDJsdWRHVnlibUZzTDJOeVpXRjBaVWg1WW5KcFpGZHlZWEJ3WlhJdWFuTWlYU3dpYm1GdFpYTWlPbHRkTENKdFlYQndhVzVuY3lJNklqdEJRVUZCTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJJaXdpWm1sc1pTSTZJbWRsYm1WeVlYUmxaQzVxY3lJc0luTnZkWEpqWlZKdmIzUWlPaUlpTENKemIzVnlZMlZ6UTI5dWRHVnVkQ0k2V3lKMllYSWdZWEp5WVhsRGIzQjVJRDBnY21WeGRXbHlaU2duTGk5aGNuSmhlVU52Y0hrbktTeGNiaUFnSUNCamIyMXdiM05sUVhKbmN5QTlJSEpsY1hWcGNtVW9KeTR2WTI5dGNHOXpaVUZ5WjNNbktTeGNiaUFnSUNCamIyMXdiM05sUVhKbmMxSnBaMmgwSUQwZ2NtVnhkV2x5WlNnbkxpOWpiMjF3YjNObFFYSm5jMUpwWjJoMEp5a3NYRzRnSUNBZ1kzSmxZWFJsUTNSdmNsZHlZWEJ3WlhJZ1BTQnlaWEYxYVhKbEtDY3VMMk55WldGMFpVTjBiM0pYY21Gd2NHVnlKeWtzWEc0Z0lDQWdhWE5NWVhwcFlXSnNaU0E5SUhKbGNYVnBjbVVvSnk0dmFYTk1ZWHBwWVdKc1pTY3BMRnh1SUNBZ0lISmxiM0prWlhJZ1BTQnlaWEYxYVhKbEtDY3VMM0psYjNKa1pYSW5LU3hjYmlBZ0lDQnlaWEJzWVdObFNHOXNaR1Z5Y3lBOUlISmxjWFZwY21Vb0p5NHZjbVZ3YkdGalpVaHZiR1JsY25NbktTeGNiaUFnSUNCelpYUkVZWFJoSUQwZ2NtVnhkV2x5WlNnbkxpOXpaWFJFWVhSaEp5azdYRzVjYmk4cUtpQlZjMlZrSUhSdklHTnZiWEJ2YzJVZ1ltbDBiV0Z6YTNNZ1ptOXlJSGR5WVhCd1pYSWdiV1YwWVdSaGRHRXVJQ292WEc1MllYSWdRa2xPUkY5R1RFRkhJRDBnTVN4Y2JpQWdJQ0JDU1U1RVgwdEZXVjlHVEVGSElEMGdNaXhjYmlBZ0lDQkRWVkpTV1Y5Q1QxVk9SRjlHVEVGSElEMGdOQ3hjYmlBZ0lDQkRWVkpTV1Y5R1RFRkhJRDBnT0N4Y2JpQWdJQ0JEVlZKU1dWOVNTVWRJVkY5R1RFRkhJRDBnTVRZc1hHNGdJQ0FnVUVGU1ZFbEJURjlHVEVGSElEMGdNeklzWEc0Z0lDQWdVRUZTVkVsQlRGOVNTVWRJVkY5R1RFRkhJRDBnTmpRc1hHNGdJQ0FnUVZKWlgwWk1RVWNnUFNBeE1qZzdYRzVjYmk4cUlFNWhkR2wyWlNCdFpYUm9iMlFnY21WbVpYSmxibU5sY3lCbWIzSWdkR2h2YzJVZ2QybDBhQ0IwYUdVZ2MyRnRaU0J1WVcxbElHRnpJRzkwYUdWeUlHQnNiMlJoYzJoZ0lHMWxkR2h2WkhNdUlDb3ZYRzUyWVhJZ2JtRjBhWFpsVFdGNElEMGdUV0YwYUM1dFlYZzdYRzVjYmk4cUtseHVJQ29nUTNKbFlYUmxjeUJoSUdaMWJtTjBhVzl1SUhSb1lYUWdkM0poY0hNZ1lHWjFibU5nSUdGdVpDQnBiblp2YTJWeklHbDBJSGRwZEdnZ2IzQjBhVzl1WVd3Z1lIUm9hWE5nWEc0Z0tpQmlhVzVrYVc1bklHOW1MQ0J3WVhKMGFXRnNJR0Z3Y0d4cFkyRjBhVzl1TENCaGJtUWdZM1Z5Y25scGJtY3VYRzRnS2x4dUlDb2dRSEJ5YVhaaGRHVmNiaUFxSUVCd1lYSmhiU0I3Um5WdVkzUnBiMjU4YzNSeWFXNW5mU0JtZFc1aklGUm9aU0JtZFc1amRHbHZiaUJ2Y2lCdFpYUm9iMlFnYm1GdFpTQjBieUJ5WldabGNtVnVZMlV1WEc0Z0tpQkFjR0Z5WVcwZ2UyNTFiV0psY24wZ1ltbDBiV0Z6YXlCVWFHVWdZbWwwYldGemF5QnZaaUJtYkdGbmN5NGdVMlZsSUdCamNtVmhkR1ZYY21Gd2NHVnlZQ0JtYjNJZ2JXOXlaU0JrWlhSaGFXeHpMbHh1SUNvZ1FIQmhjbUZ0SUhzcWZTQmJkR2hwYzBGeVoxMGdWR2hsSUdCMGFHbHpZQ0JpYVc1a2FXNW5JRzltSUdCbWRXNWpZQzVjYmlBcUlFQndZWEpoYlNCN1FYSnlZWGw5SUZ0d1lYSjBhV0ZzYzEwZ1ZHaGxJR0Z5WjNWdFpXNTBjeUIwYnlCd2NtVndaVzVrSUhSdklIUm9iM05sSUhCeWIzWnBaR1ZrSUhSdklIUm9aU0J1WlhjZ1puVnVZM1JwYjI0dVhHNGdLaUJBY0dGeVlXMGdlMEZ5Y21GNWZTQmJhRzlzWkdWeWMxMGdWR2hsSUdCd1lYSjBhV0ZzYzJBZ2NHeGhZMlZvYjJ4a1pYSWdhVzVrWlhobGN5NWNiaUFxSUVCd1lYSmhiU0I3UVhKeVlYbDlJRnR3WVhKMGFXRnNjMUpwWjJoMFhTQlVhR1VnWVhKbmRXMWxiblJ6SUhSdklHRndjR1Z1WkNCMGJ5QjBhRzl6WlNCd2NtOTJhV1JsWkNCMGJ5QjBhR1VnYm1WM0lHWjFibU4wYVc5dUxseHVJQ29nUUhCaGNtRnRJSHRCY25KaGVYMGdXMmh2YkdSbGNuTlNhV2RvZEYwZ1ZHaGxJR0J3WVhKMGFXRnNjMUpwWjJoMFlDQndiR0ZqWldodmJHUmxjaUJwYm1SbGVHVnpMbHh1SUNvZ1FIQmhjbUZ0SUh0QmNuSmhlWDBnVzJGeVoxQnZjMTBnVkdobElHRnlaM1Z0Wlc1MElIQnZjMmwwYVc5dWN5QnZaaUIwYUdVZ2JtVjNJR1oxYm1OMGFXOXVMbHh1SUNvZ1FIQmhjbUZ0SUh0dWRXMWlaWEo5SUZ0aGNubGRJRlJvWlNCaGNtbDBlU0JqWVhBZ2IyWWdZR1oxYm1OZ0xseHVJQ29nUUhCaGNtRnRJSHR1ZFcxaVpYSjlJRnRoY21sMGVWMGdWR2hsSUdGeWFYUjVJRzltSUdCbWRXNWpZQzVjYmlBcUlFQnlaWFIxY201eklIdEdkVzVqZEdsdmJuMGdVbVYwZFhKdWN5QjBhR1VnYm1WM0lIZHlZWEJ3WldRZ1puVnVZM1JwYjI0dVhHNGdLaTljYm1aMWJtTjBhVzl1SUdOeVpXRjBaVWg1WW5KcFpGZHlZWEJ3WlhJb1puVnVZeXdnWW1sMGJXRnpheXdnZEdocGMwRnlaeXdnY0dGeWRHbGhiSE1zSUdodmJHUmxjbk1zSUhCaGNuUnBZV3h6VW1sbmFIUXNJR2h2YkdSbGNuTlNhV2RvZEN3Z1lYSm5VRzl6TENCaGNua3NJR0Z5YVhSNUtTQjdYRzRnSUhaaGNpQnBjMEZ5ZVNBOUlHSnBkRzFoYzJzZ0ppQkJVbGxmUmt4QlJ5eGNiaUFnSUNBZ0lHbHpRbWx1WkNBOUlHSnBkRzFoYzJzZ0ppQkNTVTVFWDBaTVFVY3NYRzRnSUNBZ0lDQnBjMEpwYm1STFpYa2dQU0JpYVhSdFlYTnJJQ1lnUWtsT1JGOUxSVmxmUmt4QlJ5eGNiaUFnSUNBZ0lHbHpRM1Z5Y25rZ1BTQmlhWFJ0WVhOcklDWWdRMVZTVWxsZlJreEJSeXhjYmlBZ0lDQWdJR2x6UTNWeWNubENiM1Z1WkNBOUlHSnBkRzFoYzJzZ0ppQkRWVkpTV1Y5Q1QxVk9SRjlHVEVGSExGeHVJQ0FnSUNBZ2FYTkRkWEp5ZVZKcFoyaDBJRDBnWW1sMGJXRnpheUFtSUVOVlVsSlpYMUpKUjBoVVgwWk1RVWNzWEc0Z0lDQWdJQ0JEZEc5eUlEMGdhWE5DYVc1a1MyVjVJRDhnZFc1a1pXWnBibVZrSURvZ1kzSmxZWFJsUTNSdmNsZHlZWEJ3WlhJb1puVnVZeWs3WEc1Y2JpQWdablZ1WTNScGIyNGdkM0poY0hCbGNpZ3BJSHRjYmlBZ0lDQXZMeUJCZG05cFpDQmdZWEpuZFcxbGJuUnpZQ0J2WW1wbFkzUWdkWE5sSUdScGMzRjFZV3hwWm5scGJtY2diM0IwYVcxcGVtRjBhVzl1Y3lCaWVWeHVJQ0FnSUM4dklHTnZiblpsY25ScGJtY2dhWFFnZEc4Z1lXNGdZWEp5WVhrZ1ltVm1iM0psSUhCeWIzWnBaR2x1WnlCcGRDQjBieUJ2ZEdobGNpQm1kVzVqZEdsdmJuTXVYRzRnSUNBZ2RtRnlJR3hsYm1kMGFDQTlJR0Z5WjNWdFpXNTBjeTVzWlc1bmRHZ3NYRzRnSUNBZ0lDQWdJR2x1WkdWNElEMGdiR1Z1WjNSb0xGeHVJQ0FnSUNBZ0lDQmhjbWR6SUQwZ1FYSnlZWGtvYkdWdVozUm9LVHRjYmx4dUlDQWdJSGRvYVd4bElDaHBibVJsZUMwdEtTQjdYRzRnSUNBZ0lDQmhjbWR6VzJsdVpHVjRYU0E5SUdGeVozVnRaVzUwYzF0cGJtUmxlRjA3WEc0Z0lDQWdmVnh1SUNBZ0lHbG1JQ2h3WVhKMGFXRnNjeWtnZTF4dUlDQWdJQ0FnWVhKbmN5QTlJR052YlhCdmMyVkJjbWR6S0dGeVozTXNJSEJoY25ScFlXeHpMQ0JvYjJ4a1pYSnpLVHRjYmlBZ0lDQjlYRzRnSUNBZ2FXWWdLSEJoY25ScFlXeHpVbWxuYUhRcElIdGNiaUFnSUNBZ0lHRnlaM01nUFNCamIyMXdiM05sUVhKbmMxSnBaMmgwS0dGeVozTXNJSEJoY25ScFlXeHpVbWxuYUhRc0lHaHZiR1JsY25OU2FXZG9kQ2s3WEc0Z0lDQWdmVnh1SUNBZ0lHbG1JQ2hwYzBOMWNuSjVJSHg4SUdselEzVnljbmxTYVdkb2RDa2dlMXh1SUNBZ0lDQWdkbUZ5SUhCc1lXTmxhRzlzWkdWeUlEMGdkM0poY0hCbGNpNXdiR0ZqWldodmJHUmxjaXhjYmlBZ0lDQWdJQ0FnSUNCaGNtZHpTRzlzWkdWeWN5QTlJSEpsY0d4aFkyVkliMnhrWlhKektHRnlaM01zSUhCc1lXTmxhRzlzWkdWeUtUdGNibHh1SUNBZ0lDQWdiR1Z1WjNSb0lDMDlJR0Z5WjNOSWIyeGtaWEp6TG14bGJtZDBhRHRjYmlBZ0lDQWdJR2xtSUNoc1pXNW5kR2dnUENCaGNtbDBlU2tnZTF4dUlDQWdJQ0FnSUNCMllYSWdibVYzUVhKblVHOXpJRDBnWVhKblVHOXpJRDhnWVhKeVlYbERiM0I1S0dGeVoxQnZjeWtnT2lCMWJtUmxabWx1WldRc1hHNGdJQ0FnSUNBZ0lDQWdJQ0J1WlhkQmNtbDBlU0E5SUc1aGRHbDJaVTFoZUNoaGNtbDBlU0F0SUd4bGJtZDBhQ3dnTUNrc1hHNGdJQ0FnSUNBZ0lDQWdJQ0J1WlhkelNHOXNaR1Z5Y3lBOUlHbHpRM1Z5Y25rZ1B5QmhjbWR6U0c5c1pHVnljeUE2SUhWdVpHVm1hVzVsWkN4Y2JpQWdJQ0FnSUNBZ0lDQWdJRzVsZDBodmJHUmxjbk5TYVdkb2RDQTlJR2x6UTNWeWNua2dQeUIxYm1SbFptbHVaV1FnT2lCaGNtZHpTRzlzWkdWeWN5eGNiaUFnSUNBZ0lDQWdJQ0FnSUc1bGQxQmhjblJwWVd4eklEMGdhWE5EZFhKeWVTQS9JR0Z5WjNNZ09pQjFibVJsWm1sdVpXUXNYRzRnSUNBZ0lDQWdJQ0FnSUNCdVpYZFFZWEowYVdGc2MxSnBaMmgwSUQwZ2FYTkRkWEp5ZVNBL0lIVnVaR1ZtYVc1bFpDQTZJR0Z5WjNNN1hHNWNiaUFnSUNBZ0lDQWdZbWwwYldGemF5QjhQU0FvYVhORGRYSnllU0EvSUZCQlVsUkpRVXhmUmt4QlJ5QTZJRkJCVWxSSlFVeGZVa2xIU0ZSZlJreEJSeWs3WEc0Z0lDQWdJQ0FnSUdKcGRHMWhjMnNnSmowZ2ZpaHBjME4xY25KNUlEOGdVRUZTVkVsQlRGOVNTVWRJVkY5R1RFRkhJRG9nVUVGU1ZFbEJURjlHVEVGSEtUdGNibHh1SUNBZ0lDQWdJQ0JwWmlBb0lXbHpRM1Z5Y25sQ2IzVnVaQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lHSnBkRzFoYzJzZ0pqMGdmaWhDU1U1RVgwWk1RVWNnZkNCQ1NVNUVYMHRGV1Y5R1RFRkhLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCMllYSWdibVYzUkdGMFlTQTlJRnRtZFc1akxDQmlhWFJ0WVhOckxDQjBhR2x6UVhKbkxDQnVaWGRRWVhKMGFXRnNjeXdnYm1WM2MwaHZiR1JsY25Nc0lHNWxkMUJoY25ScFlXeHpVbWxuYUhRc0lHNWxkMGh2YkdSbGNuTlNhV2RvZEN3Z2JtVjNRWEpuVUc5ekxDQmhjbmtzSUc1bGQwRnlhWFI1WFN4Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsYzNWc2RDQTlJR055WldGMFpVaDVZbkpwWkZkeVlYQndaWEl1WVhCd2JIa29kVzVrWldacGJtVmtMQ0J1WlhkRVlYUmhLVHRjYmx4dUlDQWdJQ0FnSUNCcFppQW9hWE5NWVhwcFlXSnNaU2htZFc1aktTa2dlMXh1SUNBZ0lDQWdJQ0FnSUhObGRFUmhkR0VvY21WemRXeDBMQ0J1WlhkRVlYUmhLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCeVpYTjFiSFF1Y0d4aFkyVm9iMnhrWlhJZ1BTQndiR0ZqWldodmJHUmxjanRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJSEpsYzNWc2REdGNiaUFnSUNBZ0lIMWNiaUFnSUNCOVhHNGdJQ0FnZG1GeUlIUm9hWE5DYVc1a2FXNW5JRDBnYVhOQ2FXNWtJRDhnZEdocGMwRnlaeUE2SUhSb2FYTXNYRzRnSUNBZ0lDQWdJR1p1SUQwZ2FYTkNhVzVrUzJWNUlEOGdkR2hwYzBKcGJtUnBibWRiWm5WdVkxMGdPaUJtZFc1ak8xeHVYRzRnSUNBZ2FXWWdLR0Z5WjFCdmN5a2dlMXh1SUNBZ0lDQWdZWEpuY3lBOUlISmxiM0prWlhJb1lYSm5jeXdnWVhKblVHOXpLVHRjYmlBZ0lDQjlYRzRnSUNBZ2FXWWdLR2x6UVhKNUlDWW1JR0Z5ZVNBOElHRnlaM011YkdWdVozUm9LU0I3WEc0Z0lDQWdJQ0JoY21kekxteGxibWQwYUNBOUlHRnllVHRjYmlBZ0lDQjlYRzRnSUNBZ2FXWWdLSFJvYVhNZ0ppWWdkR2hwY3lBaFBUMGdaMnh2WW1Gc0lDWW1JSFJvYVhNZ2FXNXpkR0Z1WTJWdlppQjNjbUZ3Y0dWeUtTQjdYRzRnSUNBZ0lDQm1iaUE5SUVOMGIzSWdmSHdnWTNKbFlYUmxRM1J2Y2xkeVlYQndaWElvWm5WdVl5azdYRzRnSUNBZ2ZWeHVJQ0FnSUhKbGRIVnliaUJtYmk1aGNIQnNlU2gwYUdselFtbHVaR2x1Wnl3Z1lYSm5jeWs3WEc0Z0lIMWNiaUFnY21WMGRYSnVJSGR5WVhCd1pYSTdYRzU5WEc1Y2JtMXZaSFZzWlM1bGVIQnZjblJ6SUQwZ1kzSmxZWFJsU0hsaWNtbGtWM0poY0hCbGNqdGNiaUpkZlE9PSIsIihmdW5jdGlvbiAoZ2xvYmFsKXtcbnZhciBjcmVhdGVDdG9yV3JhcHBlciA9IHJlcXVpcmUoJy4vY3JlYXRlQ3RvcldyYXBwZXInKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3Igd3JhcHBlciBtZXRhZGF0YS4gKi9cbnZhciBCSU5EX0ZMQUcgPSAxO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHdyYXBzIGBmdW5jYCBhbmQgaW52b2tlcyBpdCB3aXRoIHRoZSBvcHRpb25hbCBgdGhpc2BcbiAqIGJpbmRpbmcgb2YgYHRoaXNBcmdgIGFuZCB0aGUgYHBhcnRpYWxzYCBwcmVwZW5kZWQgdG8gdGhvc2UgcHJvdmlkZWQgdG9cbiAqIHRoZSB3cmFwcGVyLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBwYXJ0aWFsbHkgYXBwbHkgYXJndW1lbnRzIHRvLlxuICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgb2YgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcHBlcmAgZm9yIG1vcmUgZGV0YWlscy5cbiAqIEBwYXJhbSB7Kn0gdGhpc0FyZyBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHBhcmFtIHtBcnJheX0gcGFydGlhbHMgVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkIHRvIHRoZSBuZXcgZnVuY3Rpb24uXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBib3VuZCBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlUGFydGlhbFdyYXBwZXIoZnVuYywgYml0bWFzaywgdGhpc0FyZywgcGFydGlhbHMpIHtcbiAgdmFyIGlzQmluZCA9IGJpdG1hc2sgJiBCSU5EX0ZMQUcsXG4gICAgICBDdG9yID0gY3JlYXRlQ3RvcldyYXBwZXIoZnVuYyk7XG5cbiAgZnVuY3Rpb24gd3JhcHBlcigpIHtcbiAgICAvLyBBdm9pZCBgYXJndW1lbnRzYCBvYmplY3QgdXNlIGRpc3F1YWxpZnlpbmcgb3B0aW1pemF0aW9ucyBieVxuICAgIC8vIGNvbnZlcnRpbmcgaXQgdG8gYW4gYXJyYXkgYmVmb3JlIHByb3ZpZGluZyBpdCBgZnVuY2AuXG4gICAgdmFyIGFyZ3NJbmRleCA9IC0xLFxuICAgICAgICBhcmdzTGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aCxcbiAgICAgICAgbGVmdEluZGV4ID0gLTEsXG4gICAgICAgIGxlZnRMZW5ndGggPSBwYXJ0aWFscy5sZW5ndGgsXG4gICAgICAgIGFyZ3MgPSBBcnJheShsZWZ0TGVuZ3RoICsgYXJnc0xlbmd0aCk7XG5cbiAgICB3aGlsZSAoKytsZWZ0SW5kZXggPCBsZWZ0TGVuZ3RoKSB7XG4gICAgICBhcmdzW2xlZnRJbmRleF0gPSBwYXJ0aWFsc1tsZWZ0SW5kZXhdO1xuICAgIH1cbiAgICB3aGlsZSAoYXJnc0xlbmd0aC0tKSB7XG4gICAgICBhcmdzW2xlZnRJbmRleCsrXSA9IGFyZ3VtZW50c1srK2FyZ3NJbmRleF07XG4gICAgfVxuICAgIHZhciBmbiA9ICh0aGlzICYmIHRoaXMgIT09IGdsb2JhbCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikgPyBDdG9yIDogZnVuYztcbiAgICByZXR1cm4gZm4uYXBwbHkoaXNCaW5kID8gdGhpc0FyZyA6IHRoaXMsIGFyZ3MpO1xuICB9XG4gIHJldHVybiB3cmFwcGVyO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZVBhcnRpYWxXcmFwcGVyO1xuXG59KS5jYWxsKHRoaXMsdHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIiA/IGdsb2JhbCA6IHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSlcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0OnV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKemIzVnlZMlZ6SWpwYkltNXZaR1ZmYlc5a2RXeGxjeTlzYjJSaGMyZ3RZMjl0Y0dGMEwybHVkR1Z5Ym1Gc0wyTnlaV0YwWlZCaGNuUnBZV3hYY21Gd2NHVnlMbXB6SWwwc0ltNWhiV1Z6SWpwYlhTd2liV0Z3Y0dsdVozTWlPaUk3UVVGQlFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQklpd2labWxzWlNJNkltZGxibVZ5WVhSbFpDNXFjeUlzSW5OdmRYSmpaVkp2YjNRaU9pSWlMQ0p6YjNWeVkyVnpRMjl1ZEdWdWRDSTZXeUoyWVhJZ1kzSmxZWFJsUTNSdmNsZHlZWEJ3WlhJZ1BTQnlaWEYxYVhKbEtDY3VMMk55WldGMFpVTjBiM0pYY21Gd2NHVnlKeWs3WEc1Y2JpOHFLaUJWYzJWa0lIUnZJR052YlhCdmMyVWdZbWwwYldGemEzTWdabTl5SUhkeVlYQndaWElnYldWMFlXUmhkR0V1SUNvdlhHNTJZWElnUWtsT1JGOUdURUZISUQwZ01UdGNibHh1THlvcVhHNGdLaUJEY21WaGRHVnpJR0VnWm5WdVkzUnBiMjRnZEdoaGRDQjNjbUZ3Y3lCZ1puVnVZMkFnWVc1a0lHbHVkbTlyWlhNZ2FYUWdkMmwwYUNCMGFHVWdiM0IwYVc5dVlXd2dZSFJvYVhOZ1hHNGdLaUJpYVc1a2FXNW5JRzltSUdCMGFHbHpRWEpuWUNCaGJtUWdkR2hsSUdCd1lYSjBhV0ZzYzJBZ2NISmxjR1Z1WkdWa0lIUnZJSFJvYjNObElIQnliM1pwWkdWa0lIUnZYRzRnS2lCMGFHVWdkM0poY0hCbGNpNWNiaUFxWEc0Z0tpQkFjSEpwZG1GMFpWeHVJQ29nUUhCaGNtRnRJSHRHZFc1amRHbHZibjBnWm5WdVl5QlVhR1VnWm5WdVkzUnBiMjRnZEc4Z2NHRnlkR2xoYkd4NUlHRndjR3g1SUdGeVozVnRaVzUwY3lCMGJ5NWNiaUFxSUVCd1lYSmhiU0I3Ym5WdFltVnlmU0JpYVhSdFlYTnJJRlJvWlNCaWFYUnRZWE5ySUc5bUlHWnNZV2R6TGlCVFpXVWdZR055WldGMFpWZHlZWEJ3WlhKZ0lHWnZjaUJ0YjNKbElHUmxkR0ZwYkhNdVhHNGdLaUJBY0dGeVlXMGdleXA5SUhSb2FYTkJjbWNnVkdobElHQjBhR2x6WUNCaWFXNWthVzVuSUc5bUlHQm1kVzVqWUM1Y2JpQXFJRUJ3WVhKaGJTQjdRWEp5WVhsOUlIQmhjblJwWVd4eklGUm9aU0JoY21kMWJXVnVkSE1nZEc4Z2NISmxjR1Z1WkNCMGJ5QjBhRzl6WlNCd2NtOTJhV1JsWkNCMGJ5QjBhR1VnYm1WM0lHWjFibU4wYVc5dUxseHVJQ29nUUhKbGRIVnlibk1nZTBaMWJtTjBhVzl1ZlNCU1pYUjFjbTV6SUhSb1pTQnVaWGNnWW05MWJtUWdablZ1WTNScGIyNHVYRzRnS2k5Y2JtWjFibU4wYVc5dUlHTnlaV0YwWlZCaGNuUnBZV3hYY21Gd2NHVnlLR1oxYm1Nc0lHSnBkRzFoYzJzc0lIUm9hWE5CY21jc0lIQmhjblJwWVd4ektTQjdYRzRnSUhaaGNpQnBjMEpwYm1RZ1BTQmlhWFJ0WVhOcklDWWdRa2xPUkY5R1RFRkhMRnh1SUNBZ0lDQWdRM1J2Y2lBOUlHTnlaV0YwWlVOMGIzSlhjbUZ3Y0dWeUtHWjFibU1wTzF4dVhHNGdJR1oxYm1OMGFXOXVJSGR5WVhCd1pYSW9LU0I3WEc0Z0lDQWdMeThnUVhadmFXUWdZR0Z5WjNWdFpXNTBjMkFnYjJKcVpXTjBJSFZ6WlNCa2FYTnhkV0ZzYVdaNWFXNW5JRzl3ZEdsdGFYcGhkR2x2Ym5NZ1lubGNiaUFnSUNBdkx5QmpiMjUyWlhKMGFXNW5JR2wwSUhSdklHRnVJR0Z5Y21GNUlHSmxabTl5WlNCd2NtOTJhV1JwYm1jZ2FYUWdZR1oxYm1OZ0xseHVJQ0FnSUhaaGNpQmhjbWR6U1c1a1pYZ2dQU0F0TVN4Y2JpQWdJQ0FnSUNBZ1lYSm5jMHhsYm1kMGFDQTlJR0Z5WjNWdFpXNTBjeTVzWlc1bmRHZ3NYRzRnSUNBZ0lDQWdJR3hsWm5SSmJtUmxlQ0E5SUMweExGeHVJQ0FnSUNBZ0lDQnNaV1owVEdWdVozUm9JRDBnY0dGeWRHbGhiSE11YkdWdVozUm9MRnh1SUNBZ0lDQWdJQ0JoY21keklEMGdRWEp5WVhrb2JHVm1kRXhsYm1kMGFDQXJJR0Z5WjNOTVpXNW5kR2dwTzF4dVhHNGdJQ0FnZDJocGJHVWdLQ3NyYkdWbWRFbHVaR1Y0SUR3Z2JHVm1kRXhsYm1kMGFDa2dlMXh1SUNBZ0lDQWdZWEpuYzF0c1pXWjBTVzVrWlhoZElEMGdjR0Z5ZEdsaGJITmJiR1ZtZEVsdVpHVjRYVHRjYmlBZ0lDQjlYRzRnSUNBZ2QyaHBiR1VnS0dGeVozTk1aVzVuZEdndExTa2dlMXh1SUNBZ0lDQWdZWEpuYzF0c1pXWjBTVzVrWlhncksxMGdQU0JoY21kMWJXVnVkSE5iS3l0aGNtZHpTVzVrWlhoZE8xeHVJQ0FnSUgxY2JpQWdJQ0IyWVhJZ1ptNGdQU0FvZEdocGN5QW1KaUIwYUdseklDRTlQU0JuYkc5aVlXd2dKaVlnZEdocGN5QnBibk4wWVc1alpXOW1JSGR5WVhCd1pYSXBJRDhnUTNSdmNpQTZJR1oxYm1NN1hHNGdJQ0FnY21WMGRYSnVJR1p1TG1Gd2NHeDVLR2x6UW1sdVpDQS9JSFJvYVhOQmNtY2dPaUIwYUdsekxDQmhjbWR6S1R0Y2JpQWdmVnh1SUNCeVpYUjFjbTRnZDNKaGNIQmxjanRjYm4xY2JseHViVzlrZFd4bExtVjRjRzl5ZEhNZ1BTQmpjbVZoZEdWUVlYSjBhV0ZzVjNKaGNIQmxjanRjYmlKZGZRPT0iLCJ2YXIgYmFzZVNldERhdGEgPSByZXF1aXJlKCcuL2Jhc2VTZXREYXRhJyksXG4gICAgY3JlYXRlQmluZFdyYXBwZXIgPSByZXF1aXJlKCcuL2NyZWF0ZUJpbmRXcmFwcGVyJyksXG4gICAgY3JlYXRlSHlicmlkV3JhcHBlciA9IHJlcXVpcmUoJy4vY3JlYXRlSHlicmlkV3JhcHBlcicpLFxuICAgIGNyZWF0ZVBhcnRpYWxXcmFwcGVyID0gcmVxdWlyZSgnLi9jcmVhdGVQYXJ0aWFsV3JhcHBlcicpLFxuICAgIGdldERhdGEgPSByZXF1aXJlKCcuL2dldERhdGEnKSxcbiAgICBtZXJnZURhdGEgPSByZXF1aXJlKCcuL21lcmdlRGF0YScpLFxuICAgIHNldERhdGEgPSByZXF1aXJlKCcuL3NldERhdGEnKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3Igd3JhcHBlciBtZXRhZGF0YS4gKi9cbnZhciBCSU5EX0ZMQUcgPSAxLFxuICAgIEJJTkRfS0VZX0ZMQUcgPSAyLFxuICAgIFBBUlRJQUxfRkxBRyA9IDMyLFxuICAgIFBBUlRJQUxfUklHSFRfRkxBRyA9IDY0O1xuXG4vKiogVXNlZCBhcyB0aGUgYFR5cGVFcnJvcmAgbWVzc2FnZSBmb3IgXCJGdW5jdGlvbnNcIiBtZXRob2RzLiAqL1xudmFyIEZVTkNfRVJST1JfVEVYVCA9ICdFeHBlY3RlZCBhIGZ1bmN0aW9uJztcblxuLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heDtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBlaXRoZXIgY3VycmllcyBvciBpbnZva2VzIGBmdW5jYCB3aXRoIG9wdGlvbmFsXG4gKiBgdGhpc2AgYmluZGluZyBhbmQgcGFydGlhbGx5IGFwcGxpZWQgYXJndW1lbnRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufHN0cmluZ30gZnVuYyBUaGUgZnVuY3Rpb24gb3IgbWV0aG9kIG5hbWUgdG8gcmVmZXJlbmNlLlxuICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgb2YgZmxhZ3MuXG4gKiAgVGhlIGJpdG1hc2sgbWF5IGJlIGNvbXBvc2VkIG9mIHRoZSBmb2xsb3dpbmcgZmxhZ3M6XG4gKiAgICAgMSAtIGBfLmJpbmRgXG4gKiAgICAgMiAtIGBfLmJpbmRLZXlgXG4gKiAgICAgNCAtIGBfLmN1cnJ5YCBvciBgXy5jdXJyeVJpZ2h0YCBvZiBhIGJvdW5kIGZ1bmN0aW9uXG4gKiAgICAgOCAtIGBfLmN1cnJ5YFxuICogICAgMTYgLSBgXy5jdXJyeVJpZ2h0YFxuICogICAgMzIgLSBgXy5wYXJ0aWFsYFxuICogICAgNjQgLSBgXy5wYXJ0aWFsUmlnaHRgXG4gKiAgIDEyOCAtIGBfLnJlYXJnYFxuICogICAyNTYgLSBgXy5hcnlgXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHBhcmFtIHtBcnJheX0gW3BhcnRpYWxzXSBUaGUgYXJndW1lbnRzIHRvIGJlIHBhcnRpYWxseSBhcHBsaWVkLlxuICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNdIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gKiBAcGFyYW0ge0FycmF5fSBbYXJnUG9zXSBUaGUgYXJndW1lbnQgcG9zaXRpb25zIG9mIHRoZSBuZXcgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge251bWJlcn0gW2FyeV0gVGhlIGFyaXR5IGNhcCBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge251bWJlcn0gW2FyaXR5XSBUaGUgYXJpdHkgb2YgYGZ1bmNgLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgd3JhcHBlZCBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlV3JhcHBlcihmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscywgaG9sZGVycywgYXJnUG9zLCBhcnksIGFyaXR5KSB7XG4gIHZhciBpc0JpbmRLZXkgPSBiaXRtYXNrICYgQklORF9LRVlfRkxBRztcbiAgaWYgKCFpc0JpbmRLZXkgJiYgdHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgfVxuICB2YXIgbGVuZ3RoID0gcGFydGlhbHMgPyBwYXJ0aWFscy5sZW5ndGggOiAwO1xuICBpZiAoIWxlbmd0aCkge1xuICAgIGJpdG1hc2sgJj0gfihQQVJUSUFMX0ZMQUcgfCBQQVJUSUFMX1JJR0hUX0ZMQUcpO1xuICAgIHBhcnRpYWxzID0gaG9sZGVycyA9IHVuZGVmaW5lZDtcbiAgfVxuICBsZW5ndGggLT0gKGhvbGRlcnMgPyBob2xkZXJzLmxlbmd0aCA6IDApO1xuICBpZiAoYml0bWFzayAmIFBBUlRJQUxfUklHSFRfRkxBRykge1xuICAgIHZhciBwYXJ0aWFsc1JpZ2h0ID0gcGFydGlhbHMsXG4gICAgICAgIGhvbGRlcnNSaWdodCA9IGhvbGRlcnM7XG5cbiAgICBwYXJ0aWFscyA9IGhvbGRlcnMgPSB1bmRlZmluZWQ7XG4gIH1cbiAgdmFyIGRhdGEgPSBpc0JpbmRLZXkgPyB1bmRlZmluZWQgOiBnZXREYXRhKGZ1bmMpLFxuICAgICAgbmV3RGF0YSA9IFtmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscywgaG9sZGVycywgcGFydGlhbHNSaWdodCwgaG9sZGVyc1JpZ2h0LCBhcmdQb3MsIGFyeSwgYXJpdHldO1xuXG4gIGlmIChkYXRhKSB7XG4gICAgbWVyZ2VEYXRhKG5ld0RhdGEsIGRhdGEpO1xuICAgIGJpdG1hc2sgPSBuZXdEYXRhWzFdO1xuICAgIGFyaXR5ID0gbmV3RGF0YVs5XTtcbiAgfVxuICBuZXdEYXRhWzldID0gYXJpdHkgPT0gbnVsbFxuICAgID8gKGlzQmluZEtleSA/IDAgOiBmdW5jLmxlbmd0aClcbiAgICA6IChuYXRpdmVNYXgoYXJpdHkgLSBsZW5ndGgsIDApIHx8IDApO1xuXG4gIGlmIChiaXRtYXNrID09IEJJTkRfRkxBRykge1xuICAgIHZhciByZXN1bHQgPSBjcmVhdGVCaW5kV3JhcHBlcihuZXdEYXRhWzBdLCBuZXdEYXRhWzJdKTtcbiAgfSBlbHNlIGlmICgoYml0bWFzayA9PSBQQVJUSUFMX0ZMQUcgfHwgYml0bWFzayA9PSAoQklORF9GTEFHIHwgUEFSVElBTF9GTEFHKSkgJiYgIW5ld0RhdGFbNF0ubGVuZ3RoKSB7XG4gICAgcmVzdWx0ID0gY3JlYXRlUGFydGlhbFdyYXBwZXIuYXBwbHkodW5kZWZpbmVkLCBuZXdEYXRhKTtcbiAgfSBlbHNlIHtcbiAgICByZXN1bHQgPSBjcmVhdGVIeWJyaWRXcmFwcGVyLmFwcGx5KHVuZGVmaW5lZCwgbmV3RGF0YSk7XG4gIH1cbiAgdmFyIHNldHRlciA9IGRhdGEgPyBiYXNlU2V0RGF0YSA6IHNldERhdGE7XG4gIHJldHVybiBzZXR0ZXIocmVzdWx0LCBuZXdEYXRhKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVXcmFwcGVyO1xuIiwidmFyIGFycmF5U29tZSA9IHJlcXVpcmUoJy4vYXJyYXlTb21lJyk7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbERlZXBgIGZvciBhcnJheXMgd2l0aCBzdXBwb3J0IGZvclxuICogcGFydGlhbCBkZWVwIGNvbXBhcmlzb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7QXJyYXl9IG90aGVyIFRoZSBvdGhlciBhcnJheSB0byBjb21wYXJlLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaW5nIGFycmF5cy5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzTG9vc2VdIFNwZWNpZnkgcGVyZm9ybWluZyBwYXJ0aWFsIGNvbXBhcmlzb25zLlxuICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQV0gVHJhY2tzIHRyYXZlcnNlZCBgdmFsdWVgIG9iamVjdHMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tCXSBUcmFja3MgdHJhdmVyc2VkIGBvdGhlcmAgb2JqZWN0cy5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgYXJyYXlzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGVxdWFsQXJyYXlzKGFycmF5LCBvdGhlciwgZXF1YWxGdW5jLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQikge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGFyckxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIG90aExlbmd0aCA9IG90aGVyLmxlbmd0aDtcblxuICBpZiAoYXJyTGVuZ3RoICE9IG90aExlbmd0aCAmJiAhKGlzTG9vc2UgJiYgb3RoTGVuZ3RoID4gYXJyTGVuZ3RoKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvLyBJZ25vcmUgbm9uLWluZGV4IHByb3BlcnRpZXMuXG4gIHdoaWxlICgrK2luZGV4IDwgYXJyTGVuZ3RoKSB7XG4gICAgdmFyIGFyclZhbHVlID0gYXJyYXlbaW5kZXhdLFxuICAgICAgICBvdGhWYWx1ZSA9IG90aGVyW2luZGV4XSxcbiAgICAgICAgcmVzdWx0ID0gY3VzdG9taXplciA/IGN1c3RvbWl6ZXIoaXNMb29zZSA/IG90aFZhbHVlIDogYXJyVmFsdWUsIGlzTG9vc2UgPyBhcnJWYWx1ZSA6IG90aFZhbHVlLCBpbmRleCkgOiB1bmRlZmluZWQ7XG5cbiAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIC8vIFJlY3Vyc2l2ZWx5IGNvbXBhcmUgYXJyYXlzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgaWYgKGlzTG9vc2UpIHtcbiAgICAgIGlmICghYXJyYXlTb21lKG90aGVyLCBmdW5jdGlvbihvdGhWYWx1ZSkge1xuICAgICAgICAgICAgcmV0dXJuIGFyclZhbHVlID09PSBvdGhWYWx1ZSB8fCBlcXVhbEZ1bmMoYXJyVmFsdWUsIG90aFZhbHVlLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQik7XG4gICAgICAgICAgfSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIShhcnJWYWx1ZSA9PT0gb3RoVmFsdWUgfHwgZXF1YWxGdW5jKGFyclZhbHVlLCBvdGhWYWx1ZSwgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlcXVhbEFycmF5cztcbiIsIi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgZXJyb3JUYWcgPSAnW29iamVjdCBFcnJvcl0nLFxuICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLFxuICAgIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nO1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxEZWVwYCBmb3IgY29tcGFyaW5nIG9iamVjdHMgb2ZcbiAqIHRoZSBzYW1lIGB0b1N0cmluZ1RhZ2AuXG4gKlxuICogKipOb3RlOioqIFRoaXMgZnVuY3Rpb24gb25seSBzdXBwb3J0cyBjb21wYXJpbmcgdmFsdWVzIHdpdGggdGFncyBvZlxuICogYEJvb2xlYW5gLCBgRGF0ZWAsIGBFcnJvcmAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgb3IgYFN0cmluZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtPYmplY3R9IG90aGVyIFRoZSBvdGhlciBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0YWcgVGhlIGB0b1N0cmluZ1RhZ2Agb2YgdGhlIG9iamVjdHMgdG8gY29tcGFyZS5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBlcXVhbEJ5VGFnKG9iamVjdCwgb3RoZXIsIHRhZykge1xuICBzd2l0Y2ggKHRhZykge1xuICAgIGNhc2UgYm9vbFRhZzpcbiAgICBjYXNlIGRhdGVUYWc6XG4gICAgICAvLyBDb2VyY2UgZGF0ZXMgYW5kIGJvb2xlYW5zIHRvIG51bWJlcnMsIGRhdGVzIHRvIG1pbGxpc2Vjb25kcyBhbmQgYm9vbGVhbnNcbiAgICAgIC8vIHRvIGAxYCBvciBgMGAgdHJlYXRpbmcgaW52YWxpZCBkYXRlcyBjb2VyY2VkIHRvIGBOYU5gIGFzIG5vdCBlcXVhbC5cbiAgICAgIHJldHVybiArb2JqZWN0ID09ICtvdGhlcjtcblxuICAgIGNhc2UgZXJyb3JUYWc6XG4gICAgICByZXR1cm4gb2JqZWN0Lm5hbWUgPT0gb3RoZXIubmFtZSAmJiBvYmplY3QubWVzc2FnZSA9PSBvdGhlci5tZXNzYWdlO1xuXG4gICAgY2FzZSBudW1iZXJUYWc6XG4gICAgICAvLyBUcmVhdCBgTmFOYCB2cy4gYE5hTmAgYXMgZXF1YWwuXG4gICAgICByZXR1cm4gKG9iamVjdCAhPSArb2JqZWN0KVxuICAgICAgICA/IG90aGVyICE9ICtvdGhlclxuICAgICAgICA6IG9iamVjdCA9PSArb3RoZXI7XG5cbiAgICBjYXNlIHJlZ2V4cFRhZzpcbiAgICBjYXNlIHN0cmluZ1RhZzpcbiAgICAgIC8vIENvZXJjZSByZWdleGVzIHRvIHN0cmluZ3MgYW5kIHRyZWF0IHN0cmluZ3MgcHJpbWl0aXZlcyBhbmQgc3RyaW5nXG4gICAgICAvLyBvYmplY3RzIGFzIGVxdWFsLiBTZWUgaHR0cHM6Ly9lczUuZ2l0aHViLmlvLyN4MTUuMTAuNi40IGZvciBtb3JlIGRldGFpbHMuXG4gICAgICByZXR1cm4gb2JqZWN0ID09IChvdGhlciArICcnKTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZXF1YWxCeVRhZztcbiIsInZhciBrZXlzID0gcmVxdWlyZSgnLi4vb2JqZWN0L2tleXMnKTtcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbERlZXBgIGZvciBvYmplY3RzIHdpdGggc3VwcG9ydCBmb3JcbiAqIHBhcnRpYWwgZGVlcCBjb21wYXJpc29ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge09iamVjdH0gb3RoZXIgVGhlIG90aGVyIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaW5nIHZhbHVlcy5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzTG9vc2VdIFNwZWNpZnkgcGVyZm9ybWluZyBwYXJ0aWFsIGNvbXBhcmlzb25zLlxuICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQV0gVHJhY2tzIHRyYXZlcnNlZCBgdmFsdWVgIG9iamVjdHMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tCXSBUcmFja3MgdHJhdmVyc2VkIGBvdGhlcmAgb2JqZWN0cy5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBlcXVhbE9iamVjdHMob2JqZWN0LCBvdGhlciwgZXF1YWxGdW5jLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQikge1xuICB2YXIgb2JqUHJvcHMgPSBrZXlzKG9iamVjdCksXG4gICAgICBvYmpMZW5ndGggPSBvYmpQcm9wcy5sZW5ndGgsXG4gICAgICBvdGhQcm9wcyA9IGtleXMob3RoZXIpLFxuICAgICAgb3RoTGVuZ3RoID0gb3RoUHJvcHMubGVuZ3RoO1xuXG4gIGlmIChvYmpMZW5ndGggIT0gb3RoTGVuZ3RoICYmICFpc0xvb3NlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciBpbmRleCA9IG9iakxlbmd0aDtcbiAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICB2YXIga2V5ID0gb2JqUHJvcHNbaW5kZXhdO1xuICAgIGlmICghKGlzTG9vc2UgPyBrZXkgaW4gb3RoZXIgOiBoYXNPd25Qcm9wZXJ0eS5jYWxsKG90aGVyLCBrZXkpKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICB2YXIgc2tpcEN0b3IgPSBpc0xvb3NlO1xuICB3aGlsZSAoKytpbmRleCA8IG9iakxlbmd0aCkge1xuICAgIGtleSA9IG9ialByb3BzW2luZGV4XTtcbiAgICB2YXIgb2JqVmFsdWUgPSBvYmplY3Rba2V5XSxcbiAgICAgICAgb3RoVmFsdWUgPSBvdGhlcltrZXldLFxuICAgICAgICByZXN1bHQgPSBjdXN0b21pemVyID8gY3VzdG9taXplcihpc0xvb3NlID8gb3RoVmFsdWUgOiBvYmpWYWx1ZSwgaXNMb29zZT8gb2JqVmFsdWUgOiBvdGhWYWx1ZSwga2V5KSA6IHVuZGVmaW5lZDtcblxuICAgIC8vIFJlY3Vyc2l2ZWx5IGNvbXBhcmUgb2JqZWN0cyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAgIGlmICghKHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gZXF1YWxGdW5jKG9ialZhbHVlLCBvdGhWYWx1ZSwgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpIDogcmVzdWx0KSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBza2lwQ3RvciB8fCAoc2tpcEN0b3IgPSBrZXkgPT0gJ2NvbnN0cnVjdG9yJyk7XG4gIH1cbiAgaWYgKCFza2lwQ3Rvcikge1xuICAgIHZhciBvYmpDdG9yID0gb2JqZWN0LmNvbnN0cnVjdG9yLFxuICAgICAgICBvdGhDdG9yID0gb3RoZXIuY29uc3RydWN0b3I7XG5cbiAgICAvLyBOb24gYE9iamVjdGAgb2JqZWN0IGluc3RhbmNlcyB3aXRoIGRpZmZlcmVudCBjb25zdHJ1Y3RvcnMgYXJlIG5vdCBlcXVhbC5cbiAgICBpZiAob2JqQ3RvciAhPSBvdGhDdG9yICYmXG4gICAgICAgICgnY29uc3RydWN0b3InIGluIG9iamVjdCAmJiAnY29uc3RydWN0b3InIGluIG90aGVyKSAmJlxuICAgICAgICAhKHR5cGVvZiBvYmpDdG9yID09ICdmdW5jdGlvbicgJiYgb2JqQ3RvciBpbnN0YW5jZW9mIG9iakN0b3IgJiZcbiAgICAgICAgICB0eXBlb2Ygb3RoQ3RvciA9PSAnZnVuY3Rpb24nICYmIG90aEN0b3IgaW5zdGFuY2VvZiBvdGhDdG9yKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlcXVhbE9iamVjdHM7XG4iLCJ2YXIgbWV0YU1hcCA9IHJlcXVpcmUoJy4vbWV0YU1hcCcpLFxuICAgIG5vb3AgPSByZXF1aXJlKCcuLi91dGlsaXR5L25vb3AnKTtcblxuLyoqXG4gKiBHZXRzIG1ldGFkYXRhIGZvciBgZnVuY2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHF1ZXJ5LlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1ldGFkYXRhIGZvciBgZnVuY2AuXG4gKi9cbnZhciBnZXREYXRhID0gIW1ldGFNYXAgPyBub29wIDogZnVuY3Rpb24oZnVuYykge1xuICByZXR1cm4gbWV0YU1hcC5nZXQoZnVuYyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGdldERhdGE7XG4iLCJ2YXIgcmVhbE5hbWVzID0gcmVxdWlyZSgnLi9yZWFsTmFtZXMnKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBuYW1lIG9mIGBmdW5jYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBmdW5jdGlvbiBuYW1lLlxuICovXG5mdW5jdGlvbiBnZXRGdW5jTmFtZShmdW5jKSB7XG4gIHZhciByZXN1bHQgPSAoZnVuYy5uYW1lICsgJycpLFxuICAgICAgYXJyYXkgPSByZWFsTmFtZXNbcmVzdWx0XSxcbiAgICAgIGxlbmd0aCA9IGFycmF5ID8gYXJyYXkubGVuZ3RoIDogMDtcblxuICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICB2YXIgZGF0YSA9IGFycmF5W2xlbmd0aF0sXG4gICAgICAgIG90aGVyRnVuYyA9IGRhdGEuZnVuYztcbiAgICBpZiAob3RoZXJGdW5jID09IG51bGwgfHwgb3RoZXJGdW5jID09IGZ1bmMpIHtcbiAgICAgIHJldHVybiBkYXRhLm5hbWU7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0RnVuY05hbWU7XG4iLCJ2YXIgYmFzZVByb3BlcnR5ID0gcmVxdWlyZSgnLi9iYXNlUHJvcGVydHknKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBcImxlbmd0aFwiIHByb3BlcnR5IHZhbHVlIG9mIGBvYmplY3RgLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gYXZvaWQgYSBbSklUIGJ1Z10oaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTE0Mjc5MilcbiAqIHRoYXQgYWZmZWN0cyBTYWZhcmkgb24gYXQgbGVhc3QgaU9TIDguMS04LjMgQVJNNjQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBcImxlbmd0aFwiIHZhbHVlLlxuICovXG52YXIgZ2V0TGVuZ3RoID0gYmFzZVByb3BlcnR5KCdsZW5ndGgnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBnZXRMZW5ndGg7XG4iLCJ2YXIgaXNTdHJpY3RDb21wYXJhYmxlID0gcmVxdWlyZSgnLi9pc1N0cmljdENvbXBhcmFibGUnKSxcbiAgICBwYWlycyA9IHJlcXVpcmUoJy4uL29iamVjdC9wYWlycycpO1xuXG4vKipcbiAqIEdldHMgdGhlIHByb3BlcnkgbmFtZXMsIHZhbHVlcywgYW5kIGNvbXBhcmUgZmxhZ3Mgb2YgYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbWF0Y2ggZGF0YSBvZiBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gZ2V0TWF0Y2hEYXRhKG9iamVjdCkge1xuICB2YXIgcmVzdWx0ID0gcGFpcnMob2JqZWN0KSxcbiAgICAgIGxlbmd0aCA9IHJlc3VsdC5sZW5ndGg7XG5cbiAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgcmVzdWx0W2xlbmd0aF1bMl0gPSBpc1N0cmljdENvbXBhcmFibGUocmVzdWx0W2xlbmd0aF1bMV0pO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0TWF0Y2hEYXRhO1xuIiwidmFyIGlzTmF0aXZlID0gcmVxdWlyZSgnLi4vbGFuZy9pc05hdGl2ZScpO1xuXG4vKipcbiAqIEdldHMgdGhlIG5hdGl2ZSBmdW5jdGlvbiBhdCBga2V5YCBvZiBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBtZXRob2QgdG8gZ2V0LlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGZ1bmN0aW9uIGlmIGl0J3MgbmF0aXZlLCBlbHNlIGB1bmRlZmluZWRgLlxuICovXG5mdW5jdGlvbiBnZXROYXRpdmUob2JqZWN0LCBrZXkpIHtcbiAgdmFyIHZhbHVlID0gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBvYmplY3Rba2V5XTtcbiAgcmV0dXJuIGlzTmF0aXZlKHZhbHVlKSA/IHZhbHVlIDogdW5kZWZpbmVkO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldE5hdGl2ZTtcbiIsIi8qKlxuICogR2V0cyB0aGUgaW5kZXggYXQgd2hpY2ggdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgYE5hTmAgaXMgZm91bmQgaW4gYGFycmF5YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNlYXJjaC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBmcm9tSW5kZXggVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCBgTmFOYCwgZWxzZSBgLTFgLlxuICovXG5mdW5jdGlvbiBpbmRleE9mTmFOKGFycmF5LCBmcm9tSW5kZXgsIGZyb21SaWdodCkge1xuICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgaW5kZXggPSBmcm9tSW5kZXggKyAoZnJvbVJpZ2h0ID8gMCA6IC0xKTtcblxuICB3aGlsZSAoKGZyb21SaWdodCA/IGluZGV4LS0gOiArK2luZGV4IDwgbGVuZ3RoKSkge1xuICAgIHZhciBvdGhlciA9IGFycmF5W2luZGV4XTtcbiAgICBpZiAob3RoZXIgIT09IG90aGVyKSB7XG4gICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuICB9XG4gIHJldHVybiAtMTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpbmRleE9mTmFOO1xuIiwiLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogSW5pdGlhbGl6ZXMgYW4gYXJyYXkgY2xvbmUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBjbG9uZS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgaW5pdGlhbGl6ZWQgY2xvbmUuXG4gKi9cbmZ1bmN0aW9uIGluaXRDbG9uZUFycmF5KGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBuZXcgYXJyYXkuY29uc3RydWN0b3IobGVuZ3RoKTtcblxuICAvLyBBZGQgYXJyYXkgcHJvcGVydGllcyBhc3NpZ25lZCBieSBgUmVnRXhwI2V4ZWNgLlxuICBpZiAobGVuZ3RoICYmIHR5cGVvZiBhcnJheVswXSA9PSAnc3RyaW5nJyAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKGFycmF5LCAnaW5kZXgnKSkge1xuICAgIHJlc3VsdC5pbmRleCA9IGFycmF5LmluZGV4O1xuICAgIHJlc3VsdC5pbnB1dCA9IGFycmF5LmlucHV0O1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaW5pdENsb25lQXJyYXk7XG4iLCIoZnVuY3Rpb24gKGdsb2JhbCl7XG52YXIgYnVmZmVyQ2xvbmUgPSByZXF1aXJlKCcuL2J1ZmZlckNsb25lJyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgbnVtYmVyVGFnID0gJ1tvYmplY3QgTnVtYmVyXScsXG4gICAgcmVnZXhwVGFnID0gJ1tvYmplY3QgUmVnRXhwXScsXG4gICAgc3RyaW5nVGFnID0gJ1tvYmplY3QgU3RyaW5nXSc7XG5cbnZhciBhcnJheUJ1ZmZlclRhZyA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsXG4gICAgZmxvYXQzMlRhZyA9ICdbb2JqZWN0IEZsb2F0MzJBcnJheV0nLFxuICAgIGZsb2F0NjRUYWcgPSAnW29iamVjdCBGbG9hdDY0QXJyYXldJyxcbiAgICBpbnQ4VGFnID0gJ1tvYmplY3QgSW50OEFycmF5XScsXG4gICAgaW50MTZUYWcgPSAnW29iamVjdCBJbnQxNkFycmF5XScsXG4gICAgaW50MzJUYWcgPSAnW29iamVjdCBJbnQzMkFycmF5XScsXG4gICAgdWludDhUYWcgPSAnW29iamVjdCBVaW50OEFycmF5XScsXG4gICAgdWludDhDbGFtcGVkVGFnID0gJ1tvYmplY3QgVWludDhDbGFtcGVkQXJyYXldJyxcbiAgICB1aW50MTZUYWcgPSAnW29iamVjdCBVaW50MTZBcnJheV0nLFxuICAgIHVpbnQzMlRhZyA9ICdbb2JqZWN0IFVpbnQzMkFycmF5XSc7XG5cbi8qKiBVc2VkIHRvIG1hdGNoIGBSZWdFeHBgIGZsYWdzIGZyb20gdGhlaXIgY29lcmNlZCBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlRmxhZ3MgPSAvXFx3KiQvO1xuXG4vKiogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIFVpbnQ4QXJyYXkgPSBnbG9iYWwuVWludDhBcnJheTtcblxuLyoqIFVzZWQgdG8gbG9va3VwIGEgdHlwZSBhcnJheSBjb25zdHJ1Y3RvcnMgYnkgYHRvU3RyaW5nVGFnYC4gKi9cbnZhciBjdG9yQnlUYWcgPSB7fTtcbmN0b3JCeVRhZ1tmbG9hdDMyVGFnXSA9IGdsb2JhbC5GbG9hdDMyQXJyYXk7XG5jdG9yQnlUYWdbZmxvYXQ2NFRhZ10gPSBnbG9iYWwuRmxvYXQ2NEFycmF5O1xuY3RvckJ5VGFnW2ludDhUYWddID0gZ2xvYmFsLkludDhBcnJheTtcbmN0b3JCeVRhZ1tpbnQxNlRhZ10gPSBnbG9iYWwuSW50MTZBcnJheTtcbmN0b3JCeVRhZ1tpbnQzMlRhZ10gPSBnbG9iYWwuSW50MzJBcnJheTtcbmN0b3JCeVRhZ1t1aW50OFRhZ10gPSBVaW50OEFycmF5O1xuY3RvckJ5VGFnW3VpbnQ4Q2xhbXBlZFRhZ10gPSBnbG9iYWwuVWludDhDbGFtcGVkQXJyYXk7XG5jdG9yQnlUYWdbdWludDE2VGFnXSA9IGdsb2JhbC5VaW50MTZBcnJheTtcbmN0b3JCeVRhZ1t1aW50MzJUYWddID0gZ2xvYmFsLlVpbnQzMkFycmF5O1xuXG4vKipcbiAqIEluaXRpYWxpemVzIGFuIG9iamVjdCBjbG9uZSBiYXNlZCBvbiBpdHMgYHRvU3RyaW5nVGFnYC5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBvbmx5IHN1cHBvcnRzIGNsb25pbmcgdmFsdWVzIHdpdGggdGFncyBvZlxuICogYEJvb2xlYW5gLCBgRGF0ZWAsIGBFcnJvcmAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgb3IgYFN0cmluZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjbG9uZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0YWcgVGhlIGB0b1N0cmluZ1RhZ2Agb2YgdGhlIG9iamVjdCB0byBjbG9uZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzRGVlcF0gU3BlY2lmeSBhIGRlZXAgY2xvbmUuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAqL1xuZnVuY3Rpb24gaW5pdENsb25lQnlUYWcob2JqZWN0LCB0YWcsIGlzRGVlcCkge1xuICB2YXIgQ3RvciA9IG9iamVjdC5jb25zdHJ1Y3RvcjtcbiAgc3dpdGNoICh0YWcpIHtcbiAgICBjYXNlIGFycmF5QnVmZmVyVGFnOlxuICAgICAgcmV0dXJuIGJ1ZmZlckNsb25lKG9iamVjdCk7XG5cbiAgICBjYXNlIGJvb2xUYWc6XG4gICAgY2FzZSBkYXRlVGFnOlxuICAgICAgcmV0dXJuIG5ldyBDdG9yKCtvYmplY3QpO1xuXG4gICAgY2FzZSBmbG9hdDMyVGFnOiBjYXNlIGZsb2F0NjRUYWc6XG4gICAgY2FzZSBpbnQ4VGFnOiBjYXNlIGludDE2VGFnOiBjYXNlIGludDMyVGFnOlxuICAgIGNhc2UgdWludDhUYWc6IGNhc2UgdWludDhDbGFtcGVkVGFnOiBjYXNlIHVpbnQxNlRhZzogY2FzZSB1aW50MzJUYWc6XG4gICAgICAvLyBTYWZhcmkgNSBtb2JpbGUgaW5jb3JyZWN0bHkgaGFzIGBPYmplY3RgIGFzIHRoZSBjb25zdHJ1Y3RvciBvZiB0eXBlZCBhcnJheXMuXG4gICAgICBpZiAoQ3RvciBpbnN0YW5jZW9mIEN0b3IpIHtcbiAgICAgICAgQ3RvciA9IGN0b3JCeVRhZ1t0YWddO1xuICAgICAgfVxuICAgICAgdmFyIGJ1ZmZlciA9IG9iamVjdC5idWZmZXI7XG4gICAgICByZXR1cm4gbmV3IEN0b3IoaXNEZWVwID8gYnVmZmVyQ2xvbmUoYnVmZmVyKSA6IGJ1ZmZlciwgb2JqZWN0LmJ5dGVPZmZzZXQsIG9iamVjdC5sZW5ndGgpO1xuXG4gICAgY2FzZSBudW1iZXJUYWc6XG4gICAgY2FzZSBzdHJpbmdUYWc6XG4gICAgICByZXR1cm4gbmV3IEN0b3Iob2JqZWN0KTtcblxuICAgIGNhc2UgcmVnZXhwVGFnOlxuICAgICAgdmFyIHJlc3VsdCA9IG5ldyBDdG9yKG9iamVjdC5zb3VyY2UsIHJlRmxhZ3MuZXhlYyhvYmplY3QpKTtcbiAgICAgIHJlc3VsdC5sYXN0SW5kZXggPSBvYmplY3QubGFzdEluZGV4O1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaW5pdENsb25lQnlUYWc7XG5cbn0pLmNhbGwodGhpcyx0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDogdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9KVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ6dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiSW01dlpHVmZiVzlrZFd4bGN5OXNiMlJoYzJndFkyOXRjR0YwTDJsdWRHVnlibUZzTDJsdWFYUkRiRzl1WlVKNVZHRm5MbXB6SWwwc0ltNWhiV1Z6SWpwYlhTd2liV0Z3Y0dsdVozTWlPaUk3UVVGQlFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CSWl3aVptbHNaU0k2SW1kbGJtVnlZWFJsWkM1cWN5SXNJbk52ZFhKalpWSnZiM1FpT2lJaUxDSnpiM1Z5WTJWelEyOXVkR1Z1ZENJNld5SjJZWElnWW5WbVptVnlRMnh2Ym1VZ1BTQnlaWEYxYVhKbEtDY3VMMkoxWm1abGNrTnNiMjVsSnlrN1hHNWNiaThxS2lCZ1QySnFaV04wSTNSdlUzUnlhVzVuWUNCeVpYTjFiSFFnY21WbVpYSmxibU5sY3k0Z0tpOWNiblpoY2lCaWIyOXNWR0ZuSUQwZ0oxdHZZbXBsWTNRZ1FtOXZiR1ZoYmwwbkxGeHVJQ0FnSUdSaGRHVlVZV2NnUFNBblcyOWlhbVZqZENCRVlYUmxYU2NzWEc0Z0lDQWdiblZ0WW1WeVZHRm5JRDBnSjF0dlltcGxZM1FnVG5WdFltVnlYU2NzWEc0Z0lDQWdjbVZuWlhod1ZHRm5JRDBnSjF0dlltcGxZM1FnVW1WblJYaHdYU2NzWEc0Z0lDQWdjM1J5YVc1blZHRm5JRDBnSjF0dlltcGxZM1FnVTNSeWFXNW5YU2M3WEc1Y2JuWmhjaUJoY25KaGVVSjFabVpsY2xSaFp5QTlJQ2RiYjJKcVpXTjBJRUZ5Y21GNVFuVm1abVZ5WFNjc1hHNGdJQ0FnWm14dllYUXpNbFJoWnlBOUlDZGJiMkpxWldOMElFWnNiMkYwTXpKQmNuSmhlVjBuTEZ4dUlDQWdJR1pzYjJGME5qUlVZV2NnUFNBblcyOWlhbVZqZENCR2JHOWhkRFkwUVhKeVlYbGRKeXhjYmlBZ0lDQnBiblE0VkdGbklEMGdKMXR2WW1wbFkzUWdTVzUwT0VGeWNtRjVYU2NzWEc0Z0lDQWdhVzUwTVRaVVlXY2dQU0FuVzI5aWFtVmpkQ0JKYm5ReE5rRnljbUY1WFNjc1hHNGdJQ0FnYVc1ME16SlVZV2NnUFNBblcyOWlhbVZqZENCSmJuUXpNa0Z5Y21GNVhTY3NYRzRnSUNBZ2RXbHVkRGhVWVdjZ1BTQW5XMjlpYW1WamRDQlZhVzUwT0VGeWNtRjVYU2NzWEc0Z0lDQWdkV2x1ZERoRGJHRnRjR1ZrVkdGbklEMGdKMXR2WW1wbFkzUWdWV2x1ZERoRGJHRnRjR1ZrUVhKeVlYbGRKeXhjYmlBZ0lDQjFhVzUwTVRaVVlXY2dQU0FuVzI5aWFtVmpkQ0JWYVc1ME1UWkJjbkpoZVYwbkxGeHVJQ0FnSUhWcGJuUXpNbFJoWnlBOUlDZGJiMkpxWldOMElGVnBiblF6TWtGeWNtRjVYU2M3WEc1Y2JpOHFLaUJWYzJWa0lIUnZJRzFoZEdOb0lHQlNaV2RGZUhCZ0lHWnNZV2R6SUdaeWIyMGdkR2hsYVhJZ1kyOWxjbU5sWkNCemRISnBibWNnZG1Gc2RXVnpMaUFxTDF4dWRtRnlJSEpsUm14aFozTWdQU0F2WEZ4M0tpUXZPMXh1WEc0dktpb2dUbUYwYVhabElHMWxkR2h2WkNCeVpXWmxjbVZ1WTJWekxpQXFMMXh1ZG1GeUlGVnBiblE0UVhKeVlYa2dQU0JuYkc5aVlXd3VWV2x1ZERoQmNuSmhlVHRjYmx4dUx5b3FJRlZ6WldRZ2RHOGdiRzl2YTNWd0lHRWdkSGx3WlNCaGNuSmhlU0JqYjI1emRISjFZM1J2Y25NZ1lua2dZSFJ2VTNSeWFXNW5WR0ZuWUM0Z0tpOWNiblpoY2lCamRHOXlRbmxVWVdjZ1BTQjdmVHRjYm1OMGIzSkNlVlJoWjF0bWJHOWhkRE15VkdGblhTQTlJR2RzYjJKaGJDNUdiRzloZERNeVFYSnlZWGs3WEc1amRHOXlRbmxVWVdkYlpteHZZWFEyTkZSaFoxMGdQU0JuYkc5aVlXd3VSbXh2WVhRMk5FRnljbUY1TzF4dVkzUnZja0o1VkdGblcybHVkRGhVWVdkZElEMGdaMnh2WW1Gc0xrbHVkRGhCY25KaGVUdGNibU4wYjNKQ2VWUmhaMXRwYm5ReE5sUmhaMTBnUFNCbmJHOWlZV3d1U1c1ME1UWkJjbkpoZVR0Y2JtTjBiM0pDZVZSaFoxdHBiblF6TWxSaFoxMGdQU0JuYkc5aVlXd3VTVzUwTXpKQmNuSmhlVHRjYm1OMGIzSkNlVlJoWjF0MWFXNTBPRlJoWjEwZ1BTQlZhVzUwT0VGeWNtRjVPMXh1WTNSdmNrSjVWR0ZuVzNWcGJuUTRRMnhoYlhCbFpGUmhaMTBnUFNCbmJHOWlZV3d1VldsdWREaERiR0Z0Y0dWa1FYSnlZWGs3WEc1amRHOXlRbmxVWVdkYmRXbHVkREUyVkdGblhTQTlJR2RzYjJKaGJDNVZhVzUwTVRaQmNuSmhlVHRjYm1OMGIzSkNlVlJoWjF0MWFXNTBNekpVWVdkZElEMGdaMnh2WW1Gc0xsVnBiblF6TWtGeWNtRjVPMXh1WEc0dktpcGNiaUFxSUVsdWFYUnBZV3hwZW1WeklHRnVJRzlpYW1WamRDQmpiRzl1WlNCaVlYTmxaQ0J2YmlCcGRITWdZSFJ2VTNSeWFXNW5WR0ZuWUM1Y2JpQXFYRzRnS2lBcUtrNXZkR1U2S2lvZ1ZHaHBjeUJtZFc1amRHbHZiaUJ2Ym14NUlITjFjSEJ2Y25SeklHTnNiMjVwYm1jZ2RtRnNkV1Z6SUhkcGRHZ2dkR0ZuY3lCdlpseHVJQ29nWUVKdmIyeGxZVzVnTENCZ1JHRjBaV0FzSUdCRmNuSnZjbUFzSUdCT2RXMWlaWEpnTENCZ1VtVm5SWGh3WUN3Z2IzSWdZRk4wY21sdVoyQXVYRzRnS2x4dUlDb2dRSEJ5YVhaaGRHVmNiaUFxSUVCd1lYSmhiU0I3VDJKcVpXTjBmU0J2WW1wbFkzUWdWR2hsSUc5aWFtVmpkQ0IwYnlCamJHOXVaUzVjYmlBcUlFQndZWEpoYlNCN2MzUnlhVzVuZlNCMFlXY2dWR2hsSUdCMGIxTjBjbWx1WjFSaFoyQWdiMllnZEdobElHOWlhbVZqZENCMGJ5QmpiRzl1WlM1Y2JpQXFJRUJ3WVhKaGJTQjdZbTl2YkdWaGJuMGdXMmx6UkdWbGNGMGdVM0JsWTJsbWVTQmhJR1JsWlhBZ1kyeHZibVV1WEc0Z0tpQkFjbVYwZFhKdWN5QjdUMkpxWldOMGZTQlNaWFIxY201eklIUm9aU0JwYm1sMGFXRnNhWHBsWkNCamJHOXVaUzVjYmlBcUwxeHVablZ1WTNScGIyNGdhVzVwZEVOc2IyNWxRbmxVWVdjb2IySnFaV04wTENCMFlXY3NJR2x6UkdWbGNDa2dlMXh1SUNCMllYSWdRM1J2Y2lBOUlHOWlhbVZqZEM1amIyNXpkSEoxWTNSdmNqdGNiaUFnYzNkcGRHTm9JQ2gwWVdjcElIdGNiaUFnSUNCallYTmxJR0Z5Y21GNVFuVm1abVZ5VkdGbk9seHVJQ0FnSUNBZ2NtVjBkWEp1SUdKMVptWmxja05zYjI1bEtHOWlhbVZqZENrN1hHNWNiaUFnSUNCallYTmxJR0p2YjJ4VVlXYzZYRzRnSUNBZ1kyRnpaU0JrWVhSbFZHRm5PbHh1SUNBZ0lDQWdjbVYwZFhKdUlHNWxkeUJEZEc5eUtDdHZZbXBsWTNRcE8xeHVYRzRnSUNBZ1kyRnpaU0JtYkc5aGRETXlWR0ZuT2lCallYTmxJR1pzYjJGME5qUlVZV2M2WEc0Z0lDQWdZMkZ6WlNCcGJuUTRWR0ZuT2lCallYTmxJR2x1ZERFMlZHRm5PaUJqWVhObElHbHVkRE15VkdGbk9seHVJQ0FnSUdOaGMyVWdkV2x1ZERoVVlXYzZJR05oYzJVZ2RXbHVkRGhEYkdGdGNHVmtWR0ZuT2lCallYTmxJSFZwYm5ReE5sUmhaem9nWTJGelpTQjFhVzUwTXpKVVlXYzZYRzRnSUNBZ0lDQXZMeUJUWVdaaGNta2dOU0J0YjJKcGJHVWdhVzVqYjNKeVpXTjBiSGtnYUdGeklHQlBZbXBsWTNSZ0lHRnpJSFJvWlNCamIyNXpkSEoxWTNSdmNpQnZaaUIwZVhCbFpDQmhjbkpoZVhNdVhHNGdJQ0FnSUNCcFppQW9RM1J2Y2lCcGJuTjBZVzVqWlc5bUlFTjBiM0lwSUh0Y2JpQWdJQ0FnSUNBZ1EzUnZjaUE5SUdOMGIzSkNlVlJoWjF0MFlXZGRPMXh1SUNBZ0lDQWdmVnh1SUNBZ0lDQWdkbUZ5SUdKMVptWmxjaUE5SUc5aWFtVmpkQzVpZFdabVpYSTdYRzRnSUNBZ0lDQnlaWFIxY200Z2JtVjNJRU4wYjNJb2FYTkVaV1Z3SUQ4Z1luVm1abVZ5UTJ4dmJtVW9ZblZtWm1WeUtTQTZJR0oxWm1abGNpd2diMkpxWldOMExtSjVkR1ZQWm1aelpYUXNJRzlpYW1WamRDNXNaVzVuZEdncE8xeHVYRzRnSUNBZ1kyRnpaU0J1ZFcxaVpYSlVZV2M2WEc0Z0lDQWdZMkZ6WlNCemRISnBibWRVWVdjNlhHNGdJQ0FnSUNCeVpYUjFjbTRnYm1WM0lFTjBiM0lvYjJKcVpXTjBLVHRjYmx4dUlDQWdJR05oYzJVZ2NtVm5aWGh3VkdGbk9seHVJQ0FnSUNBZ2RtRnlJSEpsYzNWc2RDQTlJRzVsZHlCRGRHOXlLRzlpYW1WamRDNXpiM1Z5WTJVc0lISmxSbXhoWjNNdVpYaGxZeWh2WW1wbFkzUXBLVHRjYmlBZ0lDQWdJSEpsYzNWc2RDNXNZWE4wU1c1a1pYZ2dQU0J2WW1wbFkzUXViR0Z6ZEVsdVpHVjRPMXh1SUNCOVhHNGdJSEpsZEhWeWJpQnlaWE4xYkhRN1hHNTlYRzVjYm0xdlpIVnNaUzVsZUhCdmNuUnpJRDBnYVc1cGRFTnNiMjVsUW5sVVlXYzdYRzRpWFgwPSIsIi8qKlxuICogSW5pdGlhbGl6ZXMgYW4gb2JqZWN0IGNsb25lLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY2xvbmUuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAqL1xuZnVuY3Rpb24gaW5pdENsb25lT2JqZWN0KG9iamVjdCkge1xuICB2YXIgQ3RvciA9IG9iamVjdC5jb25zdHJ1Y3RvcjtcbiAgaWYgKCEodHlwZW9mIEN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBDdG9yIGluc3RhbmNlb2YgQ3RvcikpIHtcbiAgICBDdG9yID0gT2JqZWN0O1xuICB9XG4gIHJldHVybiBuZXcgQ3Rvcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpbml0Q2xvbmVPYmplY3Q7XG4iLCJ2YXIgZ2V0TGVuZ3RoID0gcmVxdWlyZSgnLi9nZXRMZW5ndGgnKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4vaXNMZW5ndGgnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhcnJheS1saWtlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFycmF5LWxpa2UsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNBcnJheUxpa2UodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlICE9IG51bGwgJiYgaXNMZW5ndGgoZ2V0TGVuZ3RoKHZhbHVlKSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNBcnJheUxpa2U7XG4iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgaG9zdCBvYmplY3QgaW4gSUUgPCA5LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgaG9zdCBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqL1xudmFyIGlzSG9zdE9iamVjdCA9IChmdW5jdGlvbigpIHtcbiAgdHJ5IHtcbiAgICBPYmplY3QoeyAndG9TdHJpbmcnOiAwIH0gKyAnJyk7XG4gIH0gY2F0Y2goZSkge1xuICAgIHJldHVybiBmdW5jdGlvbigpIHsgcmV0dXJuIGZhbHNlOyB9O1xuICB9XG4gIHJldHVybiBmdW5jdGlvbih2YWx1ZSkge1xuICAgIC8vIElFIDwgOSBwcmVzZW50cyBtYW55IGhvc3Qgb2JqZWN0cyBhcyBgT2JqZWN0YCBvYmplY3RzIHRoYXQgY2FuIGNvZXJjZVxuICAgIC8vIHRvIHN0cmluZ3MgZGVzcGl0ZSBoYXZpbmcgaW1wcm9wZXJseSBkZWZpbmVkIGB0b1N0cmluZ2AgbWV0aG9kcy5cbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlLnRvU3RyaW5nICE9ICdmdW5jdGlvbicgJiYgdHlwZW9mICh2YWx1ZSArICcnKSA9PSAnc3RyaW5nJztcbiAgfTtcbn0oKSk7XG5cbm1vZHVsZS5leHBvcnRzID0gaXNIb3N0T2JqZWN0O1xuIiwiLyoqIFVzZWQgdG8gZGV0ZWN0IHVuc2lnbmVkIGludGVnZXIgdmFsdWVzLiAqL1xudmFyIHJlSXNVaW50ID0gL15cXGQrJC87XG5cbi8qKlxuICogVXNlZCBhcyB0aGUgW21heGltdW0gbGVuZ3RoXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1udW1iZXIubWF4X3NhZmVfaW50ZWdlcilcbiAqIG9mIGFuIGFycmF5LWxpa2UgdmFsdWUuXG4gKi9cbnZhciBNQVhfU0FGRV9JTlRFR0VSID0gOTAwNzE5OTI1NDc0MDk5MTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgaW5kZXguXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGg9TUFYX1NBRkVfSU5URUdFUl0gVGhlIHVwcGVyIGJvdW5kcyBvZiBhIHZhbGlkIGluZGV4LlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBpbmRleCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0luZGV4KHZhbHVlLCBsZW5ndGgpIHtcbiAgdmFsdWUgPSAodHlwZW9mIHZhbHVlID09ICdudW1iZXInIHx8IHJlSXNVaW50LnRlc3QodmFsdWUpKSA/ICt2YWx1ZSA6IC0xO1xuICBsZW5ndGggPSBsZW5ndGggPT0gbnVsbCA/IE1BWF9TQUZFX0lOVEVHRVIgOiBsZW5ndGg7XG4gIHJldHVybiB2YWx1ZSA+IC0xICYmIHZhbHVlICUgMSA9PSAwICYmIHZhbHVlIDwgbGVuZ3RoO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzSW5kZXg7XG4iLCJ2YXIgaXNBcnJheUxpa2UgPSByZXF1aXJlKCcuL2lzQXJyYXlMaWtlJyksXG4gICAgaXNJbmRleCA9IHJlcXVpcmUoJy4vaXNJbmRleCcpLFxuICAgIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vbGFuZy9pc09iamVjdCcpO1xuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgcHJvdmlkZWQgYXJndW1lbnRzIGFyZSBmcm9tIGFuIGl0ZXJhdGVlIGNhbGwuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHBvdGVudGlhbCBpdGVyYXRlZSB2YWx1ZSBhcmd1bWVudC5cbiAqIEBwYXJhbSB7Kn0gaW5kZXggVGhlIHBvdGVudGlhbCBpdGVyYXRlZSBpbmRleCBvciBrZXkgYXJndW1lbnQuXG4gKiBAcGFyYW0geyp9IG9iamVjdCBUaGUgcG90ZW50aWFsIGl0ZXJhdGVlIG9iamVjdCBhcmd1bWVudC5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgYXJndW1lbnRzIGFyZSBmcm9tIGFuIGl0ZXJhdGVlIGNhbGwsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNJdGVyYXRlZUNhbGwodmFsdWUsIGluZGV4LCBvYmplY3QpIHtcbiAgaWYgKCFpc09iamVjdChvYmplY3QpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciB0eXBlID0gdHlwZW9mIGluZGV4O1xuICBpZiAodHlwZSA9PSAnbnVtYmVyJ1xuICAgICAgPyAoaXNBcnJheUxpa2Uob2JqZWN0KSAmJiBpc0luZGV4KGluZGV4LCBvYmplY3QubGVuZ3RoKSlcbiAgICAgIDogKHR5cGUgPT0gJ3N0cmluZycgJiYgaW5kZXggaW4gb2JqZWN0KSkge1xuICAgIHZhciBvdGhlciA9IG9iamVjdFtpbmRleF07XG4gICAgcmV0dXJuIHZhbHVlID09PSB2YWx1ZSA/ICh2YWx1ZSA9PT0gb3RoZXIpIDogKG90aGVyICE9PSBvdGhlcik7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzSXRlcmF0ZWVDYWxsO1xuIiwidmFyIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKTtcblxuLyoqIFVzZWQgdG8gbWF0Y2ggcHJvcGVydHkgbmFtZXMgd2l0aGluIHByb3BlcnR5IHBhdGhzLiAqL1xudmFyIHJlSXNEZWVwUHJvcCA9IC9cXC58XFxbKD86W15bXFxdXSp8KFtcIiddKSg/Oig/IVxcMSlbXlxcblxcXFxdfFxcXFwuKSo/XFwxKVxcXS8sXG4gICAgcmVJc1BsYWluUHJvcCA9IC9eXFx3KiQvO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgcHJvcGVydHkgbmFtZSBhbmQgbm90IGEgcHJvcGVydHkgcGF0aC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIG9iamVjdCB0byBxdWVyeSBrZXlzIG9uLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBwcm9wZXJ0eSBuYW1lLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzS2V5KHZhbHVlLCBvYmplY3QpIHtcbiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gIGlmICgodHlwZSA9PSAnc3RyaW5nJyAmJiByZUlzUGxhaW5Qcm9wLnRlc3QodmFsdWUpKSB8fCB0eXBlID09ICdudW1iZXInKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciByZXN1bHQgPSAhcmVJc0RlZXBQcm9wLnRlc3QodmFsdWUpO1xuICByZXR1cm4gcmVzdWx0IHx8IChvYmplY3QgIT0gbnVsbCAmJiB2YWx1ZSBpbiB0b09iamVjdChvYmplY3QpKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0tleTtcbiIsInZhciBMYXp5V3JhcHBlciA9IHJlcXVpcmUoJy4vTGF6eVdyYXBwZXInKSxcbiAgICBnZXREYXRhID0gcmVxdWlyZSgnLi9nZXREYXRhJyksXG4gICAgZ2V0RnVuY05hbWUgPSByZXF1aXJlKCcuL2dldEZ1bmNOYW1lJyksXG4gICAgbG9kYXNoID0gcmVxdWlyZSgnLi4vY2hhaW4vbG9kYXNoJyk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGBmdW5jYCBoYXMgYSBsYXp5IGNvdW50ZXJwYXJ0LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgZnVuY2AgaGFzIGEgbGF6eSBjb3VudGVycGFydCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0xhemlhYmxlKGZ1bmMpIHtcbiAgdmFyIGZ1bmNOYW1lID0gZ2V0RnVuY05hbWUoZnVuYyksXG4gICAgICBvdGhlciA9IGxvZGFzaFtmdW5jTmFtZV07XG5cbiAgaWYgKHR5cGVvZiBvdGhlciAhPSAnZnVuY3Rpb24nIHx8ICEoZnVuY05hbWUgaW4gTGF6eVdyYXBwZXIucHJvdG90eXBlKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoZnVuYyA9PT0gb3RoZXIpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICB2YXIgZGF0YSA9IGdldERhdGEob3RoZXIpO1xuICByZXR1cm4gISFkYXRhICYmIGZ1bmMgPT09IGRhdGFbMF07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNMYXppYWJsZTtcbiIsIi8qKlxuICogVXNlZCBhcyB0aGUgW21heGltdW0gbGVuZ3RoXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1udW1iZXIubWF4X3NhZmVfaW50ZWdlcilcbiAqIG9mIGFuIGFycmF5LWxpa2UgdmFsdWUuXG4gKi9cbnZhciBNQVhfU0FGRV9JTlRFR0VSID0gOTAwNzE5OTI1NDc0MDk5MTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgbGVuZ3RoLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIGZ1bmN0aW9uIGlzIGJhc2VkIG9uIFtgVG9MZW5ndGhgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy10b2xlbmd0aCkuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBsZW5ndGgsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNMZW5ndGgodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyAmJiB2YWx1ZSA+IC0xICYmIHZhbHVlICUgMSA9PSAwICYmIHZhbHVlIDw9IE1BWF9TQUZFX0lOVEVHRVI7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNMZW5ndGg7XG4iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0TGlrZSh2YWx1ZSkge1xuICByZXR1cm4gISF2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNPYmplY3RMaWtlO1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vbGFuZy9pc09iamVjdCcpO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHN1aXRhYmxlIGZvciBzdHJpY3QgZXF1YWxpdHkgY29tcGFyaXNvbnMsIGkuZS4gYD09PWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaWYgc3VpdGFibGUgZm9yIHN0cmljdFxuICogIGVxdWFsaXR5IGNvbXBhcmlzb25zLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzU3RyaWN0Q29tcGFyYWJsZSh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgPT09IHZhbHVlICYmICFpc09iamVjdCh2YWx1ZSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNTdHJpY3RDb21wYXJhYmxlO1xuIiwidmFyIGFycmF5Q29weSA9IHJlcXVpcmUoJy4vYXJyYXlDb3B5JyksXG4gICAgY29tcG9zZUFyZ3MgPSByZXF1aXJlKCcuL2NvbXBvc2VBcmdzJyksXG4gICAgY29tcG9zZUFyZ3NSaWdodCA9IHJlcXVpcmUoJy4vY29tcG9zZUFyZ3NSaWdodCcpLFxuICAgIHJlcGxhY2VIb2xkZXJzID0gcmVxdWlyZSgnLi9yZXBsYWNlSG9sZGVycycpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB3cmFwcGVyIG1ldGFkYXRhLiAqL1xudmFyIEJJTkRfRkxBRyA9IDEsXG4gICAgQ1VSUllfQk9VTkRfRkxBRyA9IDQsXG4gICAgQ1VSUllfRkxBRyA9IDgsXG4gICAgQVJZX0ZMQUcgPSAxMjgsXG4gICAgUkVBUkdfRkxBRyA9IDI1NjtcblxuLyoqIFVzZWQgYXMgdGhlIGludGVybmFsIGFyZ3VtZW50IHBsYWNlaG9sZGVyLiAqL1xudmFyIFBMQUNFSE9MREVSID0gJ19fbG9kYXNoX3BsYWNlaG9sZGVyX18nO1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1pbiA9IE1hdGgubWluO1xuXG4vKipcbiAqIE1lcmdlcyB0aGUgZnVuY3Rpb24gbWV0YWRhdGEgb2YgYHNvdXJjZWAgaW50byBgZGF0YWAuXG4gKlxuICogTWVyZ2luZyBtZXRhZGF0YSByZWR1Y2VzIHRoZSBudW1iZXIgb2Ygd3JhcHBlcnMgcmVxdWlyZWQgdG8gaW52b2tlIGEgZnVuY3Rpb24uXG4gKiBUaGlzIGlzIHBvc3NpYmxlIGJlY2F1c2UgbWV0aG9kcyBsaWtlIGBfLmJpbmRgLCBgXy5jdXJyeWAsIGFuZCBgXy5wYXJ0aWFsYFxuICogbWF5IGJlIGFwcGxpZWQgcmVnYXJkbGVzcyBvZiBleGVjdXRpb24gb3JkZXIuIE1ldGhvZHMgbGlrZSBgXy5hcnlgIGFuZCBgXy5yZWFyZ2BcbiAqIGF1Z21lbnQgZnVuY3Rpb24gYXJndW1lbnRzLCBtYWtpbmcgdGhlIG9yZGVyIGluIHdoaWNoIHRoZXkgYXJlIGV4ZWN1dGVkIGltcG9ydGFudCxcbiAqIHByZXZlbnRpbmcgdGhlIG1lcmdpbmcgb2YgbWV0YWRhdGEuIEhvd2V2ZXIsIHdlIG1ha2UgYW4gZXhjZXB0aW9uIGZvciBhIHNhZmVcbiAqIGNvbW1vbiBjYXNlIHdoZXJlIGN1cnJpZWQgZnVuY3Rpb25zIGhhdmUgYF8uYXJ5YCBhbmQgb3IgYF8ucmVhcmdgIGFwcGxpZWQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGRhdGEgVGhlIGRlc3RpbmF0aW9uIG1ldGFkYXRhLlxuICogQHBhcmFtIHtBcnJheX0gc291cmNlIFRoZSBzb3VyY2UgbWV0YWRhdGEuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGRhdGFgLlxuICovXG5mdW5jdGlvbiBtZXJnZURhdGEoZGF0YSwgc291cmNlKSB7XG4gIHZhciBiaXRtYXNrID0gZGF0YVsxXSxcbiAgICAgIHNyY0JpdG1hc2sgPSBzb3VyY2VbMV0sXG4gICAgICBuZXdCaXRtYXNrID0gYml0bWFzayB8IHNyY0JpdG1hc2ssXG4gICAgICBpc0NvbW1vbiA9IG5ld0JpdG1hc2sgPCBBUllfRkxBRztcblxuICB2YXIgaXNDb21ibyA9XG4gICAgKHNyY0JpdG1hc2sgPT0gQVJZX0ZMQUcgJiYgYml0bWFzayA9PSBDVVJSWV9GTEFHKSB8fFxuICAgIChzcmNCaXRtYXNrID09IEFSWV9GTEFHICYmIGJpdG1hc2sgPT0gUkVBUkdfRkxBRyAmJiBkYXRhWzddLmxlbmd0aCA8PSBzb3VyY2VbOF0pIHx8XG4gICAgKHNyY0JpdG1hc2sgPT0gKEFSWV9GTEFHIHwgUkVBUkdfRkxBRykgJiYgYml0bWFzayA9PSBDVVJSWV9GTEFHKTtcblxuICAvLyBFeGl0IGVhcmx5IGlmIG1ldGFkYXRhIGNhbid0IGJlIG1lcmdlZC5cbiAgaWYgKCEoaXNDb21tb24gfHwgaXNDb21ibykpIHtcbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuICAvLyBVc2Ugc291cmNlIGB0aGlzQXJnYCBpZiBhdmFpbGFibGUuXG4gIGlmIChzcmNCaXRtYXNrICYgQklORF9GTEFHKSB7XG4gICAgZGF0YVsyXSA9IHNvdXJjZVsyXTtcbiAgICAvLyBTZXQgd2hlbiBjdXJyeWluZyBhIGJvdW5kIGZ1bmN0aW9uLlxuICAgIG5ld0JpdG1hc2sgfD0gKGJpdG1hc2sgJiBCSU5EX0ZMQUcpID8gMCA6IENVUlJZX0JPVU5EX0ZMQUc7XG4gIH1cbiAgLy8gQ29tcG9zZSBwYXJ0aWFsIGFyZ3VtZW50cy5cbiAgdmFyIHZhbHVlID0gc291cmNlWzNdO1xuICBpZiAodmFsdWUpIHtcbiAgICB2YXIgcGFydGlhbHMgPSBkYXRhWzNdO1xuICAgIGRhdGFbM10gPSBwYXJ0aWFscyA/IGNvbXBvc2VBcmdzKHBhcnRpYWxzLCB2YWx1ZSwgc291cmNlWzRdKSA6IGFycmF5Q29weSh2YWx1ZSk7XG4gICAgZGF0YVs0XSA9IHBhcnRpYWxzID8gcmVwbGFjZUhvbGRlcnMoZGF0YVszXSwgUExBQ0VIT0xERVIpIDogYXJyYXlDb3B5KHNvdXJjZVs0XSk7XG4gIH1cbiAgLy8gQ29tcG9zZSBwYXJ0aWFsIHJpZ2h0IGFyZ3VtZW50cy5cbiAgdmFsdWUgPSBzb3VyY2VbNV07XG4gIGlmICh2YWx1ZSkge1xuICAgIHBhcnRpYWxzID0gZGF0YVs1XTtcbiAgICBkYXRhWzVdID0gcGFydGlhbHMgPyBjb21wb3NlQXJnc1JpZ2h0KHBhcnRpYWxzLCB2YWx1ZSwgc291cmNlWzZdKSA6IGFycmF5Q29weSh2YWx1ZSk7XG4gICAgZGF0YVs2XSA9IHBhcnRpYWxzID8gcmVwbGFjZUhvbGRlcnMoZGF0YVs1XSwgUExBQ0VIT0xERVIpIDogYXJyYXlDb3B5KHNvdXJjZVs2XSk7XG4gIH1cbiAgLy8gVXNlIHNvdXJjZSBgYXJnUG9zYCBpZiBhdmFpbGFibGUuXG4gIHZhbHVlID0gc291cmNlWzddO1xuICBpZiAodmFsdWUpIHtcbiAgICBkYXRhWzddID0gYXJyYXlDb3B5KHZhbHVlKTtcbiAgfVxuICAvLyBVc2Ugc291cmNlIGBhcnlgIGlmIGl0J3Mgc21hbGxlci5cbiAgaWYgKHNyY0JpdG1hc2sgJiBBUllfRkxBRykge1xuICAgIGRhdGFbOF0gPSBkYXRhWzhdID09IG51bGwgPyBzb3VyY2VbOF0gOiBuYXRpdmVNaW4oZGF0YVs4XSwgc291cmNlWzhdKTtcbiAgfVxuICAvLyBVc2Ugc291cmNlIGBhcml0eWAgaWYgb25lIGlzIG5vdCBwcm92aWRlZC5cbiAgaWYgKGRhdGFbOV0gPT0gbnVsbCkge1xuICAgIGRhdGFbOV0gPSBzb3VyY2VbOV07XG4gIH1cbiAgLy8gVXNlIHNvdXJjZSBgZnVuY2AgYW5kIG1lcmdlIGJpdG1hc2tzLlxuICBkYXRhWzBdID0gc291cmNlWzBdO1xuICBkYXRhWzFdID0gbmV3Qml0bWFzaztcblxuICByZXR1cm4gZGF0YTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBtZXJnZURhdGE7XG4iLCIoZnVuY3Rpb24gKGdsb2JhbCl7XG52YXIgZ2V0TmF0aXZlID0gcmVxdWlyZSgnLi9nZXROYXRpdmUnKTtcblxuLyoqIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBXZWFrTWFwID0gZ2V0TmF0aXZlKGdsb2JhbCwgJ1dlYWtNYXAnKTtcblxuLyoqIFVzZWQgdG8gc3RvcmUgZnVuY3Rpb24gbWV0YWRhdGEuICovXG52YXIgbWV0YU1hcCA9IFdlYWtNYXAgJiYgbmV3IFdlYWtNYXA7XG5cbm1vZHVsZS5leHBvcnRzID0gbWV0YU1hcDtcblxufSkuY2FsbCh0aGlzLHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30pXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbTV2WkdWZmJXOWtkV3hsY3k5c2IyUmhjMmd0WTI5dGNHRjBMMmx1ZEdWeWJtRnNMMjFsZEdGTllYQXVhbk1pWFN3aWJtRnRaWE1pT2x0ZExDSnRZWEJ3YVc1bmN5STZJanRCUVVGQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQklpd2labWxzWlNJNkltZGxibVZ5WVhSbFpDNXFjeUlzSW5OdmRYSmpaVkp2YjNRaU9pSWlMQ0p6YjNWeVkyVnpRMjl1ZEdWdWRDSTZXeUoyWVhJZ1oyVjBUbUYwYVhabElEMGdjbVZ4ZFdseVpTZ25MaTluWlhST1lYUnBkbVVuS1R0Y2JseHVMeW9xSUU1aGRHbDJaU0J0WlhSb2IyUWdjbVZtWlhKbGJtTmxjeTRnS2k5Y2JuWmhjaUJYWldGclRXRndJRDBnWjJWMFRtRjBhWFpsS0dkc2IySmhiQ3dnSjFkbFlXdE5ZWEFuS1R0Y2JseHVMeW9xSUZWelpXUWdkRzhnYzNSdmNtVWdablZ1WTNScGIyNGdiV1YwWVdSaGRHRXVJQ292WEc1MllYSWdiV1YwWVUxaGNDQTlJRmRsWVd0TllYQWdKaVlnYm1WM0lGZGxZV3ROWVhBN1hHNWNibTF2WkhWc1pTNWxlSEJ2Y25SeklEMGdiV1YwWVUxaGNEdGNiaUpkZlE9PSIsIi8qKiBVc2VkIHRvIGxvb2t1cCB1bm1pbmlmaWVkIGZ1bmN0aW9uIG5hbWVzLiAqL1xudmFyIHJlYWxOYW1lcyA9IHt9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlYWxOYW1lcztcbiIsInZhciBhcnJheUNvcHkgPSByZXF1aXJlKCcuL2FycmF5Q29weScpLFxuICAgIGlzSW5kZXggPSByZXF1aXJlKCcuL2lzSW5kZXgnKTtcblxuLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNaW4gPSBNYXRoLm1pbjtcblxuLyoqXG4gKiBSZW9yZGVyIGBhcnJheWAgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpZWQgaW5kZXhlcyB3aGVyZSB0aGUgZWxlbWVudCBhdFxuICogdGhlIGZpcnN0IGluZGV4IGlzIGFzc2lnbmVkIGFzIHRoZSBmaXJzdCBlbGVtZW50LCB0aGUgZWxlbWVudCBhdFxuICogdGhlIHNlY29uZCBpbmRleCBpcyBhc3NpZ25lZCBhcyB0aGUgc2Vjb25kIGVsZW1lbnQsIGFuZCBzbyBvbi5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHJlb3JkZXIuXG4gKiBAcGFyYW0ge0FycmF5fSBpbmRleGVzIFRoZSBhcnJhbmdlZCBhcnJheSBpbmRleGVzLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIHJlb3JkZXIoYXJyYXksIGluZGV4ZXMpIHtcbiAgdmFyIGFyckxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIGxlbmd0aCA9IG5hdGl2ZU1pbihpbmRleGVzLmxlbmd0aCwgYXJyTGVuZ3RoKSxcbiAgICAgIG9sZEFycmF5ID0gYXJyYXlDb3B5KGFycmF5KTtcblxuICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICB2YXIgaW5kZXggPSBpbmRleGVzW2xlbmd0aF07XG4gICAgYXJyYXlbbGVuZ3RoXSA9IGlzSW5kZXgoaW5kZXgsIGFyckxlbmd0aCkgPyBvbGRBcnJheVtpbmRleF0gOiB1bmRlZmluZWQ7XG4gIH1cbiAgcmV0dXJuIGFycmF5O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlb3JkZXI7XG4iLCIvKiogVXNlZCBhcyB0aGUgaW50ZXJuYWwgYXJndW1lbnQgcGxhY2Vob2xkZXIuICovXG52YXIgUExBQ0VIT0xERVIgPSAnX19sb2Rhc2hfcGxhY2Vob2xkZXJfXyc7XG5cbi8qKlxuICogUmVwbGFjZXMgYWxsIGBwbGFjZWhvbGRlcmAgZWxlbWVudHMgaW4gYGFycmF5YCB3aXRoIGFuIGludGVybmFsIHBsYWNlaG9sZGVyXG4gKiBhbmQgcmV0dXJucyBhbiBhcnJheSBvZiB0aGVpciBpbmRleGVzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gbW9kaWZ5LlxuICogQHBhcmFtIHsqfSBwbGFjZWhvbGRlciBUaGUgcGxhY2Vob2xkZXIgdG8gcmVwbGFjZS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gKi9cbmZ1bmN0aW9uIHJlcGxhY2VIb2xkZXJzKGFycmF5LCBwbGFjZWhvbGRlcikge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIHJlc0luZGV4ID0gLTEsXG4gICAgICByZXN1bHQgPSBbXTtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGlmIChhcnJheVtpbmRleF0gPT09IHBsYWNlaG9sZGVyKSB7XG4gICAgICBhcnJheVtpbmRleF0gPSBQTEFDRUhPTERFUjtcbiAgICAgIHJlc3VsdFsrK3Jlc0luZGV4XSA9IGluZGV4O1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcGxhY2VIb2xkZXJzO1xuIiwidmFyIGJhc2VTZXREYXRhID0gcmVxdWlyZSgnLi9iYXNlU2V0RGF0YScpLFxuICAgIG5vdyA9IHJlcXVpcmUoJy4uL2RhdGUvbm93Jyk7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCB3aGVuIGEgZnVuY3Rpb24gYmVjb21lcyBob3QuICovXG52YXIgSE9UX0NPVU5UID0gMTUwLFxuICAgIEhPVF9TUEFOID0gMTY7XG5cbi8qKlxuICogU2V0cyBtZXRhZGF0YSBmb3IgYGZ1bmNgLlxuICpcbiAqICoqTm90ZToqKiBJZiB0aGlzIGZ1bmN0aW9uIGJlY29tZXMgaG90LCBpLmUuIGlzIGludm9rZWQgYSBsb3QgaW4gYSBzaG9ydFxuICogcGVyaW9kIG9mIHRpbWUsIGl0IHdpbGwgdHJpcCBpdHMgYnJlYWtlciBhbmQgdHJhbnNpdGlvbiB0byBhbiBpZGVudGl0eSBmdW5jdGlvblxuICogdG8gYXZvaWQgZ2FyYmFnZSBjb2xsZWN0aW9uIHBhdXNlcyBpbiBWOC4gU2VlIFtWOCBpc3N1ZSAyMDcwXShodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MjA3MClcbiAqIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFzc29jaWF0ZSBtZXRhZGF0YSB3aXRoLlxuICogQHBhcmFtIHsqfSBkYXRhIFRoZSBtZXRhZGF0YS5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBgZnVuY2AuXG4gKi9cbnZhciBzZXREYXRhID0gKGZ1bmN0aW9uKCkge1xuICB2YXIgY291bnQgPSAwLFxuICAgICAgbGFzdENhbGxlZCA9IDA7XG5cbiAgcmV0dXJuIGZ1bmN0aW9uKGtleSwgdmFsdWUpIHtcbiAgICB2YXIgc3RhbXAgPSBub3coKSxcbiAgICAgICAgcmVtYWluaW5nID0gSE9UX1NQQU4gLSAoc3RhbXAgLSBsYXN0Q2FsbGVkKTtcblxuICAgIGxhc3RDYWxsZWQgPSBzdGFtcDtcbiAgICBpZiAocmVtYWluaW5nID4gMCkge1xuICAgICAgaWYgKCsrY291bnQgPj0gSE9UX0NPVU5UKSB7XG4gICAgICAgIHJldHVybiBrZXk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvdW50ID0gMDtcbiAgICB9XG4gICAgcmV0dXJuIGJhc2VTZXREYXRhKGtleSwgdmFsdWUpO1xuICB9O1xufSgpKTtcblxubW9kdWxlLmV4cG9ydHMgPSBzZXREYXRhO1xuIiwidmFyIGlzQXJndW1lbnRzID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FyZ3VtZW50cycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICBpc0luZGV4ID0gcmVxdWlyZSgnLi9pc0luZGV4JyksXG4gICAgaXNMZW5ndGggPSByZXF1aXJlKCcuL2lzTGVuZ3RoJyksXG4gICAgaXNTdHJpbmcgPSByZXF1aXJlKCcuLi9sYW5nL2lzU3RyaW5nJyksXG4gICAga2V5c0luID0gcmVxdWlyZSgnLi4vb2JqZWN0L2tleXNJbicpO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBBIGZhbGxiYWNrIGltcGxlbWVudGF0aW9uIG9mIGBPYmplY3Qua2V5c2Agd2hpY2ggY3JlYXRlcyBhbiBhcnJheSBvZiB0aGVcbiAqIG93biBlbnVtZXJhYmxlIHByb3BlcnR5IG5hbWVzIG9mIGBvYmplY3RgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICovXG5mdW5jdGlvbiBzaGltS2V5cyhvYmplY3QpIHtcbiAgdmFyIHByb3BzID0ga2V5c0luKG9iamVjdCksXG4gICAgICBwcm9wc0xlbmd0aCA9IHByb3BzLmxlbmd0aCxcbiAgICAgIGxlbmd0aCA9IHByb3BzTGVuZ3RoICYmIG9iamVjdC5sZW5ndGg7XG5cbiAgdmFyIGFsbG93SW5kZXhlcyA9ICEhbGVuZ3RoICYmIGlzTGVuZ3RoKGxlbmd0aCkgJiZcbiAgICAoaXNBcnJheShvYmplY3QpIHx8IGlzQXJndW1lbnRzKG9iamVjdCkgfHwgaXNTdHJpbmcob2JqZWN0KSk7XG5cbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICByZXN1bHQgPSBbXTtcblxuICB3aGlsZSAoKytpbmRleCA8IHByb3BzTGVuZ3RoKSB7XG4gICAgdmFyIGtleSA9IHByb3BzW2luZGV4XTtcbiAgICBpZiAoKGFsbG93SW5kZXhlcyAmJiBpc0luZGV4KGtleSwgbGVuZ3RoKSkgfHwgaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkpIHtcbiAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc2hpbUtleXM7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0JyksXG4gICAgaXNTdHJpbmcgPSByZXF1aXJlKCcuLi9sYW5nL2lzU3RyaW5nJyksXG4gICAgc3VwcG9ydCA9IHJlcXVpcmUoJy4uL3N1cHBvcnQnKTtcblxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGFuIG9iamVjdCBpZiBpdCdzIG5vdCBvbmUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb2Nlc3MuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBvYmplY3QuXG4gKi9cbmZ1bmN0aW9uIHRvT2JqZWN0KHZhbHVlKSB7XG4gIGlmIChzdXBwb3J0LnVuaW5kZXhlZENoYXJzICYmIGlzU3RyaW5nKHZhbHVlKSkge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSB2YWx1ZS5sZW5ndGgsXG4gICAgICAgIHJlc3VsdCA9IE9iamVjdCh2YWx1ZSk7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgcmVzdWx0W2luZGV4XSA9IHZhbHVlLmNoYXJBdChpbmRleCk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgcmV0dXJuIGlzT2JqZWN0KHZhbHVlKSA/IHZhbHVlIDogT2JqZWN0KHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0b09iamVjdDtcbiIsInZhciBiYXNlVG9TdHJpbmcgPSByZXF1aXJlKCcuL2Jhc2VUb1N0cmluZycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKTtcblxuLyoqIFVzZWQgdG8gbWF0Y2ggcHJvcGVydHkgbmFtZXMgd2l0aGluIHByb3BlcnR5IHBhdGhzLiAqL1xudmFyIHJlUHJvcE5hbWUgPSAvW14uW1xcXV0rfFxcWyg/OigtP1xcZCsoPzpcXC5cXGQrKT8pfChbXCInXSkoKD86KD8hXFwyKVteXFxuXFxcXF18XFxcXC4pKj8pXFwyKVxcXS9nO1xuXG4vKiogVXNlZCB0byBtYXRjaCBiYWNrc2xhc2hlcyBpbiBwcm9wZXJ0eSBwYXRocy4gKi9cbnZhciByZUVzY2FwZUNoYXIgPSAvXFxcXChcXFxcKT8vZztcblxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIHByb3BlcnR5IHBhdGggYXJyYXkgaWYgaXQncyBub3Qgb25lLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm9jZXNzLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBwcm9wZXJ0eSBwYXRoIGFycmF5LlxuICovXG5mdW5jdGlvbiB0b1BhdGgodmFsdWUpIHtcbiAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgYmFzZVRvU3RyaW5nKHZhbHVlKS5yZXBsYWNlKHJlUHJvcE5hbWUsIGZ1bmN0aW9uKG1hdGNoLCBudW1iZXIsIHF1b3RlLCBzdHJpbmcpIHtcbiAgICByZXN1bHQucHVzaChxdW90ZSA/IHN0cmluZy5yZXBsYWNlKHJlRXNjYXBlQ2hhciwgJyQxJykgOiAobnVtYmVyIHx8IG1hdGNoKSk7XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHRvUGF0aDtcbiIsInZhciBMYXp5V3JhcHBlciA9IHJlcXVpcmUoJy4vTGF6eVdyYXBwZXInKSxcbiAgICBMb2Rhc2hXcmFwcGVyID0gcmVxdWlyZSgnLi9Mb2Rhc2hXcmFwcGVyJyksXG4gICAgYXJyYXlDb3B5ID0gcmVxdWlyZSgnLi9hcnJheUNvcHknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgY2xvbmUgb2YgYHdyYXBwZXJgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gd3JhcHBlciBUaGUgd3JhcHBlciB0byBjbG9uZS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNsb25lZCB3cmFwcGVyLlxuICovXG5mdW5jdGlvbiB3cmFwcGVyQ2xvbmUod3JhcHBlcikge1xuICByZXR1cm4gd3JhcHBlciBpbnN0YW5jZW9mIExhenlXcmFwcGVyXG4gICAgPyB3cmFwcGVyLmNsb25lKClcbiAgICA6IG5ldyBMb2Rhc2hXcmFwcGVyKHdyYXBwZXIuX193cmFwcGVkX18sIHdyYXBwZXIuX19jaGFpbl9fLCBhcnJheUNvcHkod3JhcHBlci5fX2FjdGlvbnNfXykpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHdyYXBwZXJDbG9uZTtcbiIsInZhciBiYXNlQ2xvbmUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlQ2xvbmUnKSxcbiAgICBiaW5kQ2FsbGJhY2sgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iaW5kQ2FsbGJhY2snKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZGVlcCBjbG9uZSBvZiBgdmFsdWVgLiBJZiBgY3VzdG9taXplcmAgaXMgcHJvdmlkZWQgaXQncyBpbnZva2VkXG4gKiB0byBwcm9kdWNlIHRoZSBjbG9uZWQgdmFsdWVzLiBJZiBgY3VzdG9taXplcmAgcmV0dXJucyBgdW5kZWZpbmVkYCBjbG9uaW5nXG4gKiBpcyBoYW5kbGVkIGJ5IHRoZSBtZXRob2QgaW5zdGVhZC4gVGhlIGBjdXN0b21pemVyYCBpcyBib3VuZCB0byBgdGhpc0FyZ2BcbiAqIGFuZCBpbnZva2VkIHdpdGggdXAgdG8gdGhyZWUgYXJndW1lbnQ7ICh2YWx1ZSBbLCBpbmRleHxrZXksIG9iamVjdF0pLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBsb29zZWx5IGJhc2VkIG9uIHRoZVxuICogW3N0cnVjdHVyZWQgY2xvbmUgYWxnb3JpdGhtXShodHRwOi8vd3d3LnczLm9yZy9UUi9odG1sNS9pbmZyYXN0cnVjdHVyZS5odG1sI2ludGVybmFsLXN0cnVjdHVyZWQtY2xvbmluZy1hbGdvcml0aG0pLlxuICogVGhlIGVudW1lcmFibGUgcHJvcGVydGllcyBvZiBgYXJndW1lbnRzYCBvYmplY3RzIGFuZCBvYmplY3RzIGNyZWF0ZWQgYnlcbiAqIGNvbnN0cnVjdG9ycyBvdGhlciB0aGFuIGBPYmplY3RgIGFyZSBjbG9uZWQgdG8gcGxhaW4gYE9iamVjdGAgb2JqZWN0cy4gQW5cbiAqIGVtcHR5IG9iamVjdCBpcyByZXR1cm5lZCBmb3IgdW5jbG9uZWFibGUgdmFsdWVzIHN1Y2ggYXMgZnVuY3Rpb25zLCBET00gbm9kZXMsXG4gKiBNYXBzLCBTZXRzLCBhbmQgV2Vha01hcHMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBkZWVwIGNsb25lLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY2xvbmluZyB2YWx1ZXMuXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGN1c3RvbWl6ZXJgLlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGRlZXAgY2xvbmVkIHZhbHVlLlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgdXNlcnMgPSBbXG4gKiAgIHsgJ3VzZXInOiAnYmFybmV5JyB9LFxuICogICB7ICd1c2VyJzogJ2ZyZWQnIH1cbiAqIF07XG4gKlxuICogdmFyIGRlZXAgPSBfLmNsb25lRGVlcCh1c2Vycyk7XG4gKiBkZWVwWzBdID09PSB1c2Vyc1swXTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogLy8gdXNpbmcgYSBjdXN0b21pemVyIGNhbGxiYWNrXG4gKiB2YXIgZWwgPSBfLmNsb25lRGVlcChkb2N1bWVudC5ib2R5LCBmdW5jdGlvbih2YWx1ZSkge1xuICogICBpZiAoXy5pc0VsZW1lbnQodmFsdWUpKSB7XG4gKiAgICAgcmV0dXJuIHZhbHVlLmNsb25lTm9kZSh0cnVlKTtcbiAqICAgfVxuICogfSk7XG4gKlxuICogZWwgPT09IGRvY3VtZW50LmJvZHlcbiAqIC8vID0+IGZhbHNlXG4gKiBlbC5ub2RlTmFtZVxuICogLy8gPT4gQk9EWVxuICogZWwuY2hpbGROb2Rlcy5sZW5ndGg7XG4gKiAvLyA9PiAyMFxuICovXG5mdW5jdGlvbiBjbG9uZURlZXAodmFsdWUsIGN1c3RvbWl6ZXIsIHRoaXNBcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBjdXN0b21pemVyID09ICdmdW5jdGlvbidcbiAgICA/IGJhc2VDbG9uZSh2YWx1ZSwgdHJ1ZSwgYmluZENhbGxiYWNrKGN1c3RvbWl6ZXIsIHRoaXNBcmcsIDMpKVxuICAgIDogYmFzZUNsb25lKHZhbHVlLCB0cnVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjbG9uZURlZXA7XG4iLCJ2YXIgaXNBcnJheUxpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0FycmF5TGlrZScpLFxuICAgIGlzT2JqZWN0TGlrZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzT2JqZWN0TGlrZScpO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBwcm9wZXJ0eUlzRW51bWVyYWJsZSA9IG9iamVjdFByb3RvLnByb3BlcnR5SXNFbnVtZXJhYmxlO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYW4gYGFyZ3VtZW50c2Agb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzQXJndW1lbnRzKGZ1bmN0aW9uKCkgeyByZXR1cm4gYXJndW1lbnRzOyB9KCkpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNBcmd1bWVudHMoWzEsIDIsIDNdKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzQXJndW1lbnRzKHZhbHVlKSB7XG4gIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGlzQXJyYXlMaWtlKHZhbHVlKSAmJlxuICAgIGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsICdjYWxsZWUnKSAmJiAhcHJvcGVydHlJc0VudW1lcmFibGUuY2FsbCh2YWx1ZSwgJ2NhbGxlZScpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzQXJndW1lbnRzO1xuIiwidmFyIGdldE5hdGl2ZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2dldE5hdGl2ZScpLFxuICAgIGlzTGVuZ3RoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNMZW5ndGgnKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc09iamVjdExpa2UnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJztcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlSXNBcnJheSA9IGdldE5hdGl2ZShBcnJheSwgJ2lzQXJyYXknKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGFuIGBBcnJheWAgb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzQXJyYXkoWzEsIDIsIDNdKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzQXJyYXkoZnVuY3Rpb24oKSB7IHJldHVybiBhcmd1bWVudHM7IH0oKSk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG52YXIgaXNBcnJheSA9IG5hdGl2ZUlzQXJyYXkgfHwgZnVuY3Rpb24odmFsdWUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaXNMZW5ndGgodmFsdWUubGVuZ3RoKSAmJiBvYmpUb1N0cmluZy5jYWxsKHZhbHVlKSA9PSBhcnJheVRhZztcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gaXNBcnJheTtcbiIsInZhciBpc0FyZ3VtZW50cyA9IHJlcXVpcmUoJy4vaXNBcmd1bWVudHMnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi9pc0FycmF5JyksXG4gICAgaXNBcnJheUxpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0FycmF5TGlrZScpLFxuICAgIGlzRnVuY3Rpb24gPSByZXF1aXJlKCcuL2lzRnVuY3Rpb24nKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc09iamVjdExpa2UnKSxcbiAgICBpc1N0cmluZyA9IHJlcXVpcmUoJy4vaXNTdHJpbmcnKSxcbiAgICBrZXlzID0gcmVxdWlyZSgnLi4vb2JqZWN0L2tleXMnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBlbXB0eS4gQSB2YWx1ZSBpcyBjb25zaWRlcmVkIGVtcHR5IHVubGVzcyBpdCdzIGFuXG4gKiBgYXJndW1lbnRzYCBvYmplY3QsIGFycmF5LCBzdHJpbmcsIG9yIGpRdWVyeS1saWtlIGNvbGxlY3Rpb24gd2l0aCBhIGxlbmd0aFxuICogZ3JlYXRlciB0aGFuIGAwYCBvciBhbiBvYmplY3Qgd2l0aCBvd24gZW51bWVyYWJsZSBwcm9wZXJ0aWVzLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSB2YWx1ZSBUaGUgdmFsdWUgdG8gaW5zcGVjdC5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGVtcHR5LCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNFbXB0eShudWxsKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzRW1wdHkodHJ1ZSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0VtcHR5KDEpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNFbXB0eShbMSwgMiwgM10pO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzRW1wdHkoeyAnYSc6IDEgfSk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0VtcHR5KHZhbHVlKSB7XG4gIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKGlzQXJyYXlMaWtlKHZhbHVlKSAmJiAoaXNBcnJheSh2YWx1ZSkgfHwgaXNTdHJpbmcodmFsdWUpIHx8IGlzQXJndW1lbnRzKHZhbHVlKSB8fFxuICAgICAgKGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaXNGdW5jdGlvbih2YWx1ZS5zcGxpY2UpKSkpIHtcbiAgICByZXR1cm4gIXZhbHVlLmxlbmd0aDtcbiAgfVxuICByZXR1cm4gIWtleXModmFsdWUpLmxlbmd0aDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0VtcHR5O1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9pc09iamVjdCcpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgZnVuY1RhZyA9ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgW2B0b1N0cmluZ1RhZ2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW9iamVjdC5wcm90b3R5cGUudG9zdHJpbmcpXG4gKiBvZiB2YWx1ZXMuXG4gKi9cbnZhciBvYmpUb1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgRnVuY3Rpb25gIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgY29ycmVjdGx5IGNsYXNzaWZpZWQsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc0Z1bmN0aW9uKF8pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNGdW5jdGlvbigvYWJjLyk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKHZhbHVlKSB7XG4gIC8vIFRoZSB1c2Ugb2YgYE9iamVjdCN0b1N0cmluZ2AgYXZvaWRzIGlzc3VlcyB3aXRoIHRoZSBgdHlwZW9mYCBvcGVyYXRvclxuICAvLyBpbiBvbGRlciB2ZXJzaW9ucyBvZiBDaHJvbWUgYW5kIFNhZmFyaSB3aGljaCByZXR1cm4gJ2Z1bmN0aW9uJyBmb3IgcmVnZXhlc1xuICAvLyBhbmQgU2FmYXJpIDggd2hpY2ggcmV0dXJucyAnb2JqZWN0JyBmb3IgdHlwZWQgYXJyYXkgY29uc3RydWN0b3JzLlxuICByZXR1cm4gaXNPYmplY3QodmFsdWUpICYmIG9ialRvU3RyaW5nLmNhbGwodmFsdWUpID09IGZ1bmNUYWc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNGdW5jdGlvbjtcbiIsInZhciBpc0Z1bmN0aW9uID0gcmVxdWlyZSgnLi9pc0Z1bmN0aW9uJyksXG4gICAgaXNIb3N0T2JqZWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNIb3N0T2JqZWN0JyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNPYmplY3RMaWtlJyk7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBob3N0IGNvbnN0cnVjdG9ycyAoU2FmYXJpID4gNSkuICovXG52YXIgcmVJc0hvc3RDdG9yID0gL15cXFtvYmplY3QgLis/Q29uc3RydWN0b3JcXF0kLztcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIHJlc29sdmUgdGhlIGRlY29tcGlsZWQgc291cmNlIG9mIGZ1bmN0aW9ucy4gKi9cbnZhciBmblRvU3RyaW5nID0gRnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKiogVXNlZCB0byBkZXRlY3QgaWYgYSBtZXRob2QgaXMgbmF0aXZlLiAqL1xudmFyIHJlSXNOYXRpdmUgPSBSZWdFeHAoJ14nICtcbiAgZm5Ub1N0cmluZy5jYWxsKGhhc093blByb3BlcnR5KS5yZXBsYWNlKC9bXFxcXF4kLiorPygpW1xcXXt9fF0vZywgJ1xcXFwkJicpXG4gIC5yZXBsYWNlKC9oYXNPd25Qcm9wZXJ0eXwoZnVuY3Rpb24pLio/KD89XFxcXFxcKCl8IGZvciAuKz8oPz1cXFxcXFxdKS9nLCAnJDEuKj8nKSArICckJ1xuKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIG5hdGl2ZSBmdW5jdGlvbi5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBuYXRpdmUgZnVuY3Rpb24sIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc05hdGl2ZShBcnJheS5wcm90b3R5cGUucHVzaCk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc05hdGl2ZShfKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzTmF0aXZlKHZhbHVlKSB7XG4gIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgIHJldHVybiByZUlzTmF0aXZlLnRlc3QoZm5Ub1N0cmluZy5jYWxsKHZhbHVlKSk7XG4gIH1cbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgKGlzSG9zdE9iamVjdCh2YWx1ZSkgPyByZUlzTmF0aXZlIDogcmVJc0hvc3RDdG9yKS50ZXN0KHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc05hdGl2ZTtcbiIsIi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgdGhlIFtsYW5ndWFnZSB0eXBlXShodHRwczovL2VzNS5naXRodWIuaW8vI3g4KSBvZiBgT2JqZWN0YC5cbiAqIChlLmcuIGFycmF5cywgZnVuY3Rpb25zLCBvYmplY3RzLCByZWdleGVzLCBgbmV3IE51bWJlcigwKWAsIGFuZCBgbmV3IFN0cmluZygnJylgKVxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc09iamVjdCh7fSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdChbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3QoMSk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc09iamVjdCh2YWx1ZSkge1xuICAvLyBBdm9pZCBhIFY4IEpJVCBidWcgaW4gQ2hyb21lIDE5LTIwLlxuICAvLyBTZWUgaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC92OC9pc3N1ZXMvZGV0YWlsP2lkPTIyOTEgZm9yIG1vcmUgZGV0YWlscy5cbiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gIHJldHVybiAhIXZhbHVlICYmICh0eXBlID09ICdvYmplY3QnIHx8IHR5cGUgPT0gJ2Z1bmN0aW9uJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNPYmplY3Q7XG4iLCJ2YXIgYmFzZUZvckluID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZUZvckluJyksXG4gICAgaXNBcmd1bWVudHMgPSByZXF1aXJlKCcuL2lzQXJndW1lbnRzJyksXG4gICAgaXNIb3N0T2JqZWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNIb3N0T2JqZWN0JyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNPYmplY3RMaWtlJyksXG4gICAgc3VwcG9ydCA9IHJlcXVpcmUoJy4uL3N1cHBvcnQnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHBsYWluIG9iamVjdCwgdGhhdCBpcywgYW4gb2JqZWN0IGNyZWF0ZWQgYnkgdGhlXG4gKiBgT2JqZWN0YCBjb25zdHJ1Y3RvciBvciBvbmUgd2l0aCBhIGBbW1Byb3RvdHlwZV1dYCBvZiBgbnVsbGAuXG4gKlxuICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGFzc3VtZXMgb2JqZWN0cyBjcmVhdGVkIGJ5IHRoZSBgT2JqZWN0YCBjb25zdHJ1Y3RvclxuICogaGF2ZSBubyBpbmhlcml0ZWQgZW51bWVyYWJsZSBwcm9wZXJ0aWVzLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHBsYWluIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBmdW5jdGlvbiBGb28oKSB7XG4gKiAgIHRoaXMuYSA9IDE7XG4gKiB9XG4gKlxuICogXy5pc1BsYWluT2JqZWN0KG5ldyBGb28pO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzUGxhaW5PYmplY3QoWzEsIDIsIDNdKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc1BsYWluT2JqZWN0KHsgJ3gnOiAwLCAneSc6IDAgfSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1BsYWluT2JqZWN0KE9iamVjdC5jcmVhdGUobnVsbCkpO1xuICogLy8gPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBpc1BsYWluT2JqZWN0KHZhbHVlKSB7XG4gIHZhciBDdG9yO1xuXG4gIC8vIEV4aXQgZWFybHkgZm9yIG5vbiBgT2JqZWN0YCBvYmplY3RzLlxuICBpZiAoIShpc09iamVjdExpa2UodmFsdWUpICYmIG9ialRvU3RyaW5nLmNhbGwodmFsdWUpID09IG9iamVjdFRhZyAmJiAhaXNIb3N0T2JqZWN0KHZhbHVlKSAmJiAhaXNBcmd1bWVudHModmFsdWUpKSB8fFxuICAgICAgKCFoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCAnY29uc3RydWN0b3InKSAmJiAoQ3RvciA9IHZhbHVlLmNvbnN0cnVjdG9yLCB0eXBlb2YgQ3RvciA9PSAnZnVuY3Rpb24nICYmICEoQ3RvciBpbnN0YW5jZW9mIEN0b3IpKSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy8gSUUgPCA5IGl0ZXJhdGVzIGluaGVyaXRlZCBwcm9wZXJ0aWVzIGJlZm9yZSBvd24gcHJvcGVydGllcy4gSWYgdGhlIGZpcnN0XG4gIC8vIGl0ZXJhdGVkIHByb3BlcnR5IGlzIGFuIG9iamVjdCdzIG93biBwcm9wZXJ0eSB0aGVuIHRoZXJlIGFyZSBubyBpbmhlcml0ZWRcbiAgLy8gZW51bWVyYWJsZSBwcm9wZXJ0aWVzLlxuICB2YXIgcmVzdWx0O1xuICBpZiAoc3VwcG9ydC5vd25MYXN0KSB7XG4gICAgYmFzZUZvckluKHZhbHVlLCBmdW5jdGlvbihzdWJWYWx1ZSwga2V5LCBvYmplY3QpIHtcbiAgICAgIHJlc3VsdCA9IGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQgIT09IGZhbHNlO1xuICB9XG4gIC8vIEluIG1vc3QgZW52aXJvbm1lbnRzIGFuIG9iamVjdCdzIG93biBwcm9wZXJ0aWVzIGFyZSBpdGVyYXRlZCBiZWZvcmVcbiAgLy8gaXRzIGluaGVyaXRlZCBwcm9wZXJ0aWVzLiBJZiB0aGUgbGFzdCBpdGVyYXRlZCBwcm9wZXJ0eSBpcyBhbiBvYmplY3Qnc1xuICAvLyBvd24gcHJvcGVydHkgdGhlbiB0aGVyZSBhcmUgbm8gaW5oZXJpdGVkIGVudW1lcmFibGUgcHJvcGVydGllcy5cbiAgYmFzZUZvckluKHZhbHVlLCBmdW5jdGlvbihzdWJWYWx1ZSwga2V5KSB7XG4gICAgcmVzdWx0ID0ga2V5O1xuICB9KTtcbiAgcmV0dXJuIHJlc3VsdCA9PT0gdW5kZWZpbmVkIHx8IGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsIHJlc3VsdCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNQbGFpbk9iamVjdDtcbiIsInZhciBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc09iamVjdExpa2UnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFN0cmluZ2AgcHJpbWl0aXZlIG9yIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgY29ycmVjdGx5IGNsYXNzaWZpZWQsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc1N0cmluZygnYWJjJyk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1N0cmluZygxKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzU3RyaW5nKHZhbHVlKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycgfHwgKGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgb2JqVG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT0gc3RyaW5nVGFnKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1N0cmluZztcbiIsInZhciBpc0xlbmd0aCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzTGVuZ3RoJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNPYmplY3RMaWtlJyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBhcmdzVGFnID0gJ1tvYmplY3QgQXJndW1lbnRzXScsXG4gICAgYXJyYXlUYWcgPSAnW29iamVjdCBBcnJheV0nLFxuICAgIGJvb2xUYWcgPSAnW29iamVjdCBCb29sZWFuXScsXG4gICAgZGF0ZVRhZyA9ICdbb2JqZWN0IERhdGVdJyxcbiAgICBlcnJvclRhZyA9ICdbb2JqZWN0IEVycm9yXScsXG4gICAgZnVuY1RhZyA9ICdbb2JqZWN0IEZ1bmN0aW9uXScsXG4gICAgbWFwVGFnID0gJ1tvYmplY3QgTWFwXScsXG4gICAgbnVtYmVyVGFnID0gJ1tvYmplY3QgTnVtYmVyXScsXG4gICAgb2JqZWN0VGFnID0gJ1tvYmplY3QgT2JqZWN0XScsXG4gICAgcmVnZXhwVGFnID0gJ1tvYmplY3QgUmVnRXhwXScsXG4gICAgc2V0VGFnID0gJ1tvYmplY3QgU2V0XScsXG4gICAgc3RyaW5nVGFnID0gJ1tvYmplY3QgU3RyaW5nXScsXG4gICAgd2Vha01hcFRhZyA9ICdbb2JqZWN0IFdlYWtNYXBdJztcblxudmFyIGFycmF5QnVmZmVyVGFnID0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJyxcbiAgICBmbG9hdDMyVGFnID0gJ1tvYmplY3QgRmxvYXQzMkFycmF5XScsXG4gICAgZmxvYXQ2NFRhZyA9ICdbb2JqZWN0IEZsb2F0NjRBcnJheV0nLFxuICAgIGludDhUYWcgPSAnW29iamVjdCBJbnQ4QXJyYXldJyxcbiAgICBpbnQxNlRhZyA9ICdbb2JqZWN0IEludDE2QXJyYXldJyxcbiAgICBpbnQzMlRhZyA9ICdbb2JqZWN0IEludDMyQXJyYXldJyxcbiAgICB1aW50OFRhZyA9ICdbb2JqZWN0IFVpbnQ4QXJyYXldJyxcbiAgICB1aW50OENsYW1wZWRUYWcgPSAnW29iamVjdCBVaW50OENsYW1wZWRBcnJheV0nLFxuICAgIHVpbnQxNlRhZyA9ICdbb2JqZWN0IFVpbnQxNkFycmF5XScsXG4gICAgdWludDMyVGFnID0gJ1tvYmplY3QgVWludDMyQXJyYXldJztcblxuLyoqIFVzZWQgdG8gaWRlbnRpZnkgYHRvU3RyaW5nVGFnYCB2YWx1ZXMgb2YgdHlwZWQgYXJyYXlzLiAqL1xudmFyIHR5cGVkQXJyYXlUYWdzID0ge307XG50eXBlZEFycmF5VGFnc1tmbG9hdDMyVGFnXSA9IHR5cGVkQXJyYXlUYWdzW2Zsb2F0NjRUYWddID1cbnR5cGVkQXJyYXlUYWdzW2ludDhUYWddID0gdHlwZWRBcnJheVRhZ3NbaW50MTZUYWddID1cbnR5cGVkQXJyYXlUYWdzW2ludDMyVGFnXSA9IHR5cGVkQXJyYXlUYWdzW3VpbnQ4VGFnXSA9XG50eXBlZEFycmF5VGFnc1t1aW50OENsYW1wZWRUYWddID0gdHlwZWRBcnJheVRhZ3NbdWludDE2VGFnXSA9XG50eXBlZEFycmF5VGFnc1t1aW50MzJUYWddID0gdHJ1ZTtcbnR5cGVkQXJyYXlUYWdzW2FyZ3NUYWddID0gdHlwZWRBcnJheVRhZ3NbYXJyYXlUYWddID1cbnR5cGVkQXJyYXlUYWdzW2FycmF5QnVmZmVyVGFnXSA9IHR5cGVkQXJyYXlUYWdzW2Jvb2xUYWddID1cbnR5cGVkQXJyYXlUYWdzW2RhdGVUYWddID0gdHlwZWRBcnJheVRhZ3NbZXJyb3JUYWddID1cbnR5cGVkQXJyYXlUYWdzW2Z1bmNUYWddID0gdHlwZWRBcnJheVRhZ3NbbWFwVGFnXSA9XG50eXBlZEFycmF5VGFnc1tudW1iZXJUYWddID0gdHlwZWRBcnJheVRhZ3Nbb2JqZWN0VGFnXSA9XG50eXBlZEFycmF5VGFnc1tyZWdleHBUYWddID0gdHlwZWRBcnJheVRhZ3Nbc2V0VGFnXSA9XG50eXBlZEFycmF5VGFnc1tzdHJpbmdUYWddID0gdHlwZWRBcnJheVRhZ3Nbd2Vha01hcFRhZ10gPSBmYWxzZTtcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIHR5cGVkIGFycmF5LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzVHlwZWRBcnJheShuZXcgVWludDhBcnJheSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1R5cGVkQXJyYXkoW10pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNUeXBlZEFycmF5KHZhbHVlKSB7XG4gIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGlzTGVuZ3RoKHZhbHVlLmxlbmd0aCkgJiYgISF0eXBlZEFycmF5VGFnc1tvYmpUb1N0cmluZy5jYWxsKHZhbHVlKV07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNUeXBlZEFycmF5O1xuIiwiLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBgdW5kZWZpbmVkYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYHVuZGVmaW5lZGAsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc1VuZGVmaW5lZCh2b2lkIDApO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNVbmRlZmluZWQobnVsbCk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc1VuZGVmaW5lZCh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1VuZGVmaW5lZDtcbiIsInZhciBnZXROYXRpdmUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9nZXROYXRpdmUnKSxcbiAgICBpc0FycmF5TGlrZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzQXJyYXlMaWtlJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0JyksXG4gICAgc2hpbUtleXMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9zaGltS2V5cycpLFxuICAgIHN1cHBvcnQgPSByZXF1aXJlKCcuLi9zdXBwb3J0Jyk7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlS2V5cyA9IGdldE5hdGl2ZShPYmplY3QsICdrZXlzJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgYG9iamVjdGAuXG4gKlxuICogKipOb3RlOioqIE5vbi1vYmplY3QgdmFsdWVzIGFyZSBjb2VyY2VkIHRvIG9iamVjdHMuIFNlZSB0aGVcbiAqIFtFUyBzcGVjXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3Qua2V5cylcbiAqIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBPYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gKiBAZXhhbXBsZVxuICpcbiAqIGZ1bmN0aW9uIEZvbygpIHtcbiAqICAgdGhpcy5hID0gMTtcbiAqICAgdGhpcy5iID0gMjtcbiAqIH1cbiAqXG4gKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICpcbiAqIF8ua2V5cyhuZXcgRm9vKTtcbiAqIC8vID0+IFsnYScsICdiJ10gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAqXG4gKiBfLmtleXMoJ2hpJyk7XG4gKiAvLyA9PiBbJzAnLCAnMSddXG4gKi9cbnZhciBrZXlzID0gIW5hdGl2ZUtleXMgPyBzaGltS2V5cyA6IGZ1bmN0aW9uKG9iamVjdCkge1xuICB2YXIgQ3RvciA9IG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogb2JqZWN0LmNvbnN0cnVjdG9yO1xuICBpZiAoKHR5cGVvZiBDdG9yID09ICdmdW5jdGlvbicgJiYgQ3Rvci5wcm90b3R5cGUgPT09IG9iamVjdCkgfHxcbiAgICAgICh0eXBlb2Ygb2JqZWN0ID09ICdmdW5jdGlvbicgPyBzdXBwb3J0LmVudW1Qcm90b3R5cGVzIDogaXNBcnJheUxpa2Uob2JqZWN0KSkpIHtcbiAgICByZXR1cm4gc2hpbUtleXMob2JqZWN0KTtcbiAgfVxuICByZXR1cm4gaXNPYmplY3Qob2JqZWN0KSA/IG5hdGl2ZUtleXMob2JqZWN0KSA6IFtdO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBrZXlzO1xuIiwidmFyIGFycmF5RWFjaCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2FycmF5RWFjaCcpLFxuICAgIGlzQXJndW1lbnRzID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FyZ3VtZW50cycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICBpc0Z1bmN0aW9uID0gcmVxdWlyZSgnLi4vbGFuZy9pc0Z1bmN0aW9uJyksXG4gICAgaXNJbmRleCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzSW5kZXgnKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzTGVuZ3RoJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0JyksXG4gICAgaXNTdHJpbmcgPSByZXF1aXJlKCcuLi9sYW5nL2lzU3RyaW5nJyksXG4gICAgc3VwcG9ydCA9IHJlcXVpcmUoJy4uL3N1cHBvcnQnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJyxcbiAgICBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgZXJyb3JUYWcgPSAnW29iamVjdCBFcnJvcl0nLFxuICAgIGZ1bmNUYWcgPSAnW29iamVjdCBGdW5jdGlvbl0nLFxuICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nLFxuICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLFxuICAgIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nO1xuXG4vKiogVXNlZCB0byBmaXggdGhlIEpTY3JpcHQgYFtbRG9udEVudW1dXWAgYnVnLiAqL1xudmFyIHNoYWRvd1Byb3BzID0gW1xuICAnY29uc3RydWN0b3InLCAnaGFzT3duUHJvcGVydHknLCAnaXNQcm90b3R5cGVPZicsICdwcm9wZXJ0eUlzRW51bWVyYWJsZScsXG4gICd0b0xvY2FsZVN0cmluZycsICd0b1N0cmluZycsICd2YWx1ZU9mJ1xuXTtcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBlcnJvclByb3RvID0gRXJyb3IucHJvdG90eXBlLFxuICAgIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZSxcbiAgICBzdHJpbmdQcm90byA9IFN0cmluZy5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKiBVc2VkIHRvIGF2b2lkIGl0ZXJhdGluZyBvdmVyIG5vbi1lbnVtZXJhYmxlIHByb3BlcnRpZXMgaW4gSUUgPCA5LiAqL1xudmFyIG5vbkVudW1Qcm9wcyA9IHt9O1xubm9uRW51bVByb3BzW2FycmF5VGFnXSA9IG5vbkVudW1Qcm9wc1tkYXRlVGFnXSA9IG5vbkVudW1Qcm9wc1tudW1iZXJUYWddID0geyAnY29uc3RydWN0b3InOiB0cnVlLCAndG9Mb2NhbGVTdHJpbmcnOiB0cnVlLCAndG9TdHJpbmcnOiB0cnVlLCAndmFsdWVPZic6IHRydWUgfTtcbm5vbkVudW1Qcm9wc1tib29sVGFnXSA9IG5vbkVudW1Qcm9wc1tzdHJpbmdUYWddID0geyAnY29uc3RydWN0b3InOiB0cnVlLCAndG9TdHJpbmcnOiB0cnVlLCAndmFsdWVPZic6IHRydWUgfTtcbm5vbkVudW1Qcm9wc1tlcnJvclRhZ10gPSBub25FbnVtUHJvcHNbZnVuY1RhZ10gPSBub25FbnVtUHJvcHNbcmVnZXhwVGFnXSA9IHsgJ2NvbnN0cnVjdG9yJzogdHJ1ZSwgJ3RvU3RyaW5nJzogdHJ1ZSB9O1xubm9uRW51bVByb3BzW29iamVjdFRhZ10gPSB7ICdjb25zdHJ1Y3Rvcic6IHRydWUgfTtcblxuYXJyYXlFYWNoKHNoYWRvd1Byb3BzLCBmdW5jdGlvbihrZXkpIHtcbiAgZm9yICh2YXIgdGFnIGluIG5vbkVudW1Qcm9wcykge1xuICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKG5vbkVudW1Qcm9wcywgdGFnKSkge1xuICAgICAgdmFyIHByb3BzID0gbm9uRW51bVByb3BzW3RhZ107XG4gICAgICBwcm9wc1trZXldID0gaGFzT3duUHJvcGVydHkuY2FsbChwcm9wcywga2V5KTtcbiAgICB9XG4gIH1cbn0pO1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgYG9iamVjdGAuXG4gKlxuICogKipOb3RlOioqIE5vbi1vYmplY3QgdmFsdWVzIGFyZSBjb2VyY2VkIHRvIG9iamVjdHMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBPYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gKiBAZXhhbXBsZVxuICpcbiAqIGZ1bmN0aW9uIEZvbygpIHtcbiAqICAgdGhpcy5hID0gMTtcbiAqICAgdGhpcy5iID0gMjtcbiAqIH1cbiAqXG4gKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICpcbiAqIF8ua2V5c0luKG5ldyBGb28pO1xuICogLy8gPT4gWydhJywgJ2InLCAnYyddIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gKi9cbmZ1bmN0aW9uIGtleXNJbihvYmplY3QpIHtcbiAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG4gIGlmICghaXNPYmplY3Qob2JqZWN0KSkge1xuICAgIG9iamVjdCA9IE9iamVjdChvYmplY3QpO1xuICB9XG4gIHZhciBsZW5ndGggPSBvYmplY3QubGVuZ3RoO1xuXG4gIGxlbmd0aCA9IChsZW5ndGggJiYgaXNMZW5ndGgobGVuZ3RoKSAmJlxuICAgIChpc0FycmF5KG9iamVjdCkgfHwgaXNBcmd1bWVudHMob2JqZWN0KSB8fCBpc1N0cmluZyhvYmplY3QpKSAmJiBsZW5ndGgpIHx8IDA7XG5cbiAgdmFyIEN0b3IgPSBvYmplY3QuY29uc3RydWN0b3IsXG4gICAgICBpbmRleCA9IC0xLFxuICAgICAgcHJvdG8gPSAoaXNGdW5jdGlvbihDdG9yKSAmJiBDdG9yLnByb3RvdHlwZSkgfHwgb2JqZWN0UHJvdG8sXG4gICAgICBpc1Byb3RvID0gcHJvdG8gPT09IG9iamVjdCxcbiAgICAgIHJlc3VsdCA9IEFycmF5KGxlbmd0aCksXG4gICAgICBza2lwSW5kZXhlcyA9IGxlbmd0aCA+IDAsXG4gICAgICBza2lwRXJyb3JQcm9wcyA9IHN1cHBvcnQuZW51bUVycm9yUHJvcHMgJiYgKG9iamVjdCA9PT0gZXJyb3JQcm90byB8fCBvYmplY3QgaW5zdGFuY2VvZiBFcnJvciksXG4gICAgICBza2lwUHJvdG8gPSBzdXBwb3J0LmVudW1Qcm90b3R5cGVzICYmIGlzRnVuY3Rpb24ob2JqZWN0KTtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHJlc3VsdFtpbmRleF0gPSAoaW5kZXggKyAnJyk7XG4gIH1cbiAgLy8gbG9kYXNoIHNraXBzIHRoZSBgY29uc3RydWN0b3JgIHByb3BlcnR5IHdoZW4gaXQgaW5mZXJzIGl0J3MgaXRlcmF0aW5nXG4gIC8vIG92ZXIgYSBgcHJvdG90eXBlYCBvYmplY3QgYmVjYXVzZSBJRSA8IDkgY2FuJ3Qgc2V0IHRoZSBgW1tFbnVtZXJhYmxlXV1gXG4gIC8vIGF0dHJpYnV0ZSBvZiBhbiBleGlzdGluZyBwcm9wZXJ0eSBhbmQgdGhlIGBjb25zdHJ1Y3RvcmAgcHJvcGVydHkgb2YgYVxuICAvLyBwcm90b3R5cGUgZGVmYXVsdHMgdG8gbm9uLWVudW1lcmFibGUuXG4gIGZvciAodmFyIGtleSBpbiBvYmplY3QpIHtcbiAgICBpZiAoIShza2lwUHJvdG8gJiYga2V5ID09ICdwcm90b3R5cGUnKSAmJlxuICAgICAgICAhKHNraXBFcnJvclByb3BzICYmIChrZXkgPT0gJ21lc3NhZ2UnIHx8IGtleSA9PSAnbmFtZScpKSAmJlxuICAgICAgICAhKHNraXBJbmRleGVzICYmIGlzSW5kZXgoa2V5LCBsZW5ndGgpKSAmJlxuICAgICAgICAhKGtleSA9PSAnY29uc3RydWN0b3InICYmIChpc1Byb3RvIHx8ICFoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSkpKSB7XG4gICAgICByZXN1bHQucHVzaChrZXkpO1xuICAgIH1cbiAgfVxuICBpZiAoc3VwcG9ydC5ub25FbnVtU2hhZG93cyAmJiBvYmplY3QgIT09IG9iamVjdFByb3RvKSB7XG4gICAgdmFyIHRhZyA9IG9iamVjdCA9PT0gc3RyaW5nUHJvdG8gPyBzdHJpbmdUYWcgOiAob2JqZWN0ID09PSBlcnJvclByb3RvID8gZXJyb3JUYWcgOiBvYmpUb1N0cmluZy5jYWxsKG9iamVjdCkpLFxuICAgICAgICBub25FbnVtcyA9IG5vbkVudW1Qcm9wc1t0YWddIHx8IG5vbkVudW1Qcm9wc1tvYmplY3RUYWddO1xuXG4gICAgaWYgKHRhZyA9PSBvYmplY3RUYWcpIHtcbiAgICAgIHByb3RvID0gb2JqZWN0UHJvdG87XG4gICAgfVxuICAgIGxlbmd0aCA9IHNoYWRvd1Byb3BzLmxlbmd0aDtcbiAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgIGtleSA9IHNoYWRvd1Byb3BzW2xlbmd0aF07XG4gICAgICB2YXIgbm9uRW51bSA9IG5vbkVudW1zW2tleV07XG4gICAgICBpZiAoIShpc1Byb3RvICYmIG5vbkVudW0pICYmXG4gICAgICAgICAgKG5vbkVudW0gPyBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSA6IG9iamVjdFtrZXldICE9PSBwcm90b1trZXldKSkge1xuICAgICAgICByZXN1bHQucHVzaChrZXkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGtleXNJbjtcbiIsInZhciBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyksXG4gICAgdG9PYmplY3QgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC90b09iamVjdCcpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSB0d28gZGltZW5zaW9uYWwgYXJyYXkgb2YgdGhlIGtleS12YWx1ZSBwYWlycyBmb3IgYG9iamVjdGAsXG4gKiBlLmcuIGBbW2tleTEsIHZhbHVlMV0sIFtrZXkyLCB2YWx1ZTJdXWAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBPYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGtleS12YWx1ZSBwYWlycy5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5wYWlycyh7ICdiYXJuZXknOiAzNiwgJ2ZyZWQnOiA0MCB9KTtcbiAqIC8vID0+IFtbJ2Jhcm5leScsIDM2XSwgWydmcmVkJywgNDBdXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICovXG5mdW5jdGlvbiBwYWlycyhvYmplY3QpIHtcbiAgb2JqZWN0ID0gdG9PYmplY3Qob2JqZWN0KTtcblxuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIHByb3BzID0ga2V5cyhvYmplY3QpLFxuICAgICAgbGVuZ3RoID0gcHJvcHMubGVuZ3RoLFxuICAgICAgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKTtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHZhciBrZXkgPSBwcm9wc1tpbmRleF07XG4gICAgcmVzdWx0W2luZGV4XSA9IFtrZXksIG9iamVjdFtrZXldXTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHBhaXJzO1xuIiwidmFyIGJhc2VWYWx1ZXMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlVmFsdWVzJyksXG4gICAga2V5cyA9IHJlcXVpcmUoJy4va2V5cycpO1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBlbnVtZXJhYmxlIHByb3BlcnR5IHZhbHVlcyBvZiBgb2JqZWN0YC5cbiAqXG4gKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IE9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSB2YWx1ZXMuXG4gKiBAZXhhbXBsZVxuICpcbiAqIGZ1bmN0aW9uIEZvbygpIHtcbiAqICAgdGhpcy5hID0gMTtcbiAqICAgdGhpcy5iID0gMjtcbiAqIH1cbiAqXG4gKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICpcbiAqIF8udmFsdWVzKG5ldyBGb28pO1xuICogLy8gPT4gWzEsIDJdIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gKlxuICogXy52YWx1ZXMoJ2hpJyk7XG4gKiAvLyA9PiBbJ2gnLCAnaSddXG4gKi9cbmZ1bmN0aW9uIHZhbHVlcyhvYmplY3QpIHtcbiAgcmV0dXJuIGJhc2VWYWx1ZXMob2JqZWN0LCBrZXlzKG9iamVjdCkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHZhbHVlcztcbiIsIi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgYXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZSxcbiAgICBlcnJvclByb3RvID0gRXJyb3IucHJvdG90eXBlLFxuICAgIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBwcm9wZXJ0eUlzRW51bWVyYWJsZSA9IG9iamVjdFByb3RvLnByb3BlcnR5SXNFbnVtZXJhYmxlLFxuICAgIHNwbGljZSA9IGFycmF5UHJvdG8uc3BsaWNlO1xuXG4vKipcbiAqIEFuIG9iamVjdCBlbnZpcm9ubWVudCBmZWF0dXJlIGZsYWdzLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAdHlwZSBPYmplY3RcbiAqL1xudmFyIHN1cHBvcnQgPSB7fTtcblxuKGZ1bmN0aW9uKHgpIHtcbiAgdmFyIEN0b3IgPSBmdW5jdGlvbigpIHsgdGhpcy54ID0geDsgfSxcbiAgICAgIG9iamVjdCA9IHsgJzAnOiB4LCAnbGVuZ3RoJzogeCB9LFxuICAgICAgcHJvcHMgPSBbXTtcblxuICBDdG9yLnByb3RvdHlwZSA9IHsgJ3ZhbHVlT2YnOiB4LCAneSc6IHggfTtcbiAgZm9yICh2YXIga2V5IGluIG5ldyBDdG9yKSB7IHByb3BzLnB1c2goa2V5KTsgfVxuXG4gIC8qKlxuICAgKiBEZXRlY3QgaWYgYG5hbWVgIG9yIGBtZXNzYWdlYCBwcm9wZXJ0aWVzIG9mIGBFcnJvci5wcm90b3R5cGVgIGFyZVxuICAgKiBlbnVtZXJhYmxlIGJ5IGRlZmF1bHQgKElFIDwgOSwgU2FmYXJpIDwgNS4xKS5cbiAgICpcbiAgICogQG1lbWJlck9mIF8uc3VwcG9ydFxuICAgKiBAdHlwZSBib29sZWFuXG4gICAqL1xuICBzdXBwb3J0LmVudW1FcnJvclByb3BzID0gcHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChlcnJvclByb3RvLCAnbWVzc2FnZScpIHx8XG4gICAgcHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChlcnJvclByb3RvLCAnbmFtZScpO1xuXG4gIC8qKlxuICAgKiBEZXRlY3QgaWYgYHByb3RvdHlwZWAgcHJvcGVydGllcyBhcmUgZW51bWVyYWJsZSBieSBkZWZhdWx0LlxuICAgKlxuICAgKiBGaXJlZm94IDwgMy42LCBPcGVyYSA+IDkuNTAgLSBPcGVyYSA8IDExLjYwLCBhbmQgU2FmYXJpIDwgNS4xXG4gICAqIChpZiB0aGUgcHJvdG90eXBlIG9yIGEgcHJvcGVydHkgb24gdGhlIHByb3RvdHlwZSBoYXMgYmVlbiBzZXQpXG4gICAqIGluY29ycmVjdGx5IHNldCB0aGUgYFtbRW51bWVyYWJsZV1dYCB2YWx1ZSBvZiBhIGZ1bmN0aW9uJ3MgYHByb3RvdHlwZWBcbiAgICogcHJvcGVydHkgdG8gYHRydWVgLlxuICAgKlxuICAgKiBAbWVtYmVyT2YgXy5zdXBwb3J0XG4gICAqIEB0eXBlIGJvb2xlYW5cbiAgICovXG4gIHN1cHBvcnQuZW51bVByb3RvdHlwZXMgPSBwcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKEN0b3IsICdwcm90b3R5cGUnKTtcblxuICAvKipcbiAgICogRGV0ZWN0IGlmIHByb3BlcnRpZXMgc2hhZG93aW5nIHRob3NlIG9uIGBPYmplY3QucHJvdG90eXBlYCBhcmUgbm9uLWVudW1lcmFibGUuXG4gICAqXG4gICAqIEluIElFIDwgOSBhbiBvYmplY3QncyBvd24gcHJvcGVydGllcywgc2hhZG93aW5nIG5vbi1lbnVtZXJhYmxlIG9uZXMsXG4gICAqIGFyZSBtYWRlIG5vbi1lbnVtZXJhYmxlIGFzIHdlbGwgKGEuay5hIHRoZSBKU2NyaXB0IGBbW0RvbnRFbnVtXV1gIGJ1ZykuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBfLnN1cHBvcnRcbiAgICogQHR5cGUgYm9vbGVhblxuICAgKi9cbiAgc3VwcG9ydC5ub25FbnVtU2hhZG93cyA9ICEvdmFsdWVPZi8udGVzdChwcm9wcyk7XG5cbiAgLyoqXG4gICAqIERldGVjdCBpZiBvd24gcHJvcGVydGllcyBhcmUgaXRlcmF0ZWQgYWZ0ZXIgaW5oZXJpdGVkIHByb3BlcnRpZXMgKElFIDwgOSkuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBfLnN1cHBvcnRcbiAgICogQHR5cGUgYm9vbGVhblxuICAgKi9cbiAgc3VwcG9ydC5vd25MYXN0ID0gcHJvcHNbMF0gIT0gJ3gnO1xuXG4gIC8qKlxuICAgKiBEZXRlY3QgaWYgYEFycmF5I3NoaWZ0YCBhbmQgYEFycmF5I3NwbGljZWAgYXVnbWVudCBhcnJheS1saWtlIG9iamVjdHNcbiAgICogY29ycmVjdGx5LlxuICAgKlxuICAgKiBGaXJlZm94IDwgMTAsIGNvbXBhdGliaWxpdHkgbW9kZXMgb2YgSUUgOCwgYW5kIElFIDwgOSBoYXZlIGJ1Z2d5IEFycmF5XG4gICAqIGBzaGlmdCgpYCBhbmQgYHNwbGljZSgpYCBmdW5jdGlvbnMgdGhhdCBmYWlsIHRvIHJlbW92ZSB0aGUgbGFzdCBlbGVtZW50LFxuICAgKiBgdmFsdWVbMF1gLCBvZiBhcnJheS1saWtlIG9iamVjdHMgZXZlbiB0aG91Z2ggdGhlIFwibGVuZ3RoXCIgcHJvcGVydHkgaXNcbiAgICogc2V0IHRvIGAwYC4gVGhlIGBzaGlmdCgpYCBtZXRob2QgaXMgYnVnZ3kgaW4gY29tcGF0aWJpbGl0eSBtb2RlcyBvZiBJRSA4LFxuICAgKiB3aGlsZSBgc3BsaWNlKClgIGlzIGJ1Z2d5IHJlZ2FyZGxlc3Mgb2YgbW9kZSBpbiBJRSA8IDkuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBfLnN1cHBvcnRcbiAgICogQHR5cGUgYm9vbGVhblxuICAgKi9cbiAgc3VwcG9ydC5zcGxpY2VPYmplY3RzID0gKHNwbGljZS5jYWxsKG9iamVjdCwgMCwgMSksICFvYmplY3RbMF0pO1xuXG4gIC8qKlxuICAgKiBEZXRlY3QgbGFjayBvZiBzdXBwb3J0IGZvciBhY2Nlc3Npbmcgc3RyaW5nIGNoYXJhY3RlcnMgYnkgaW5kZXguXG4gICAqXG4gICAqIElFIDwgOCBjYW4ndCBhY2Nlc3MgY2hhcmFjdGVycyBieSBpbmRleC4gSUUgOCBjYW4gb25seSBhY2Nlc3MgY2hhcmFjdGVyc1xuICAgKiBieSBpbmRleCBvbiBzdHJpbmcgbGl0ZXJhbHMsIG5vdCBzdHJpbmcgb2JqZWN0cy5cbiAgICpcbiAgICogQG1lbWJlck9mIF8uc3VwcG9ydFxuICAgKiBAdHlwZSBib29sZWFuXG4gICAqL1xuICBzdXBwb3J0LnVuaW5kZXhlZENoYXJzID0gKCd4J1swXSArIE9iamVjdCgneCcpWzBdKSAhPSAneHgnO1xufSgxLCAwKSk7XG5cbm1vZHVsZS5leHBvcnRzID0gc3VwcG9ydDtcbiIsIi8qKlxuICogVGhpcyBtZXRob2QgcmV0dXJucyB0aGUgZmlyc3QgYXJndW1lbnQgcHJvdmlkZWQgdG8gaXQuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBVdGlsaXR5XG4gKiBAcGFyYW0geyp9IHZhbHVlIEFueSB2YWx1ZS5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIGB2YWx1ZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBvYmplY3QgPSB7ICd1c2VyJzogJ2ZyZWQnIH07XG4gKlxuICogXy5pZGVudGl0eShvYmplY3QpID09PSBvYmplY3Q7XG4gKiAvLyA9PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGlkZW50aXR5KHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpZGVudGl0eTtcbiIsIi8qKlxuICogQSBuby1vcGVyYXRpb24gZnVuY3Rpb24gdGhhdCByZXR1cm5zIGB1bmRlZmluZWRgIHJlZ2FyZGxlc3Mgb2YgdGhlXG4gKiBhcmd1bWVudHMgaXQgcmVjZWl2ZXMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBVdGlsaXR5XG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBvYmplY3QgPSB7ICd1c2VyJzogJ2ZyZWQnIH07XG4gKlxuICogXy5ub29wKG9iamVjdCkgPT09IHVuZGVmaW5lZDtcbiAqIC8vID0+IHRydWVcbiAqL1xuZnVuY3Rpb24gbm9vcCgpIHtcbiAgLy8gTm8gb3BlcmF0aW9uIHBlcmZvcm1lZC5cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBub29wO1xuIiwidmFyIGJhc2VQcm9wZXJ0eSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2Jhc2VQcm9wZXJ0eScpLFxuICAgIGJhc2VQcm9wZXJ0eURlZXAgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlUHJvcGVydHlEZWVwJyksXG4gICAgaXNLZXkgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0tleScpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlIGF0IGBwYXRoYCBvbiBhXG4gKiBnaXZlbiBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBVdGlsaXR5XG4gKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBvYmplY3RzID0gW1xuICogICB7ICdhJzogeyAnYic6IHsgJ2MnOiAyIH0gfSB9LFxuICogICB7ICdhJzogeyAnYic6IHsgJ2MnOiAxIH0gfSB9XG4gKiBdO1xuICpcbiAqIF8ubWFwKG9iamVjdHMsIF8ucHJvcGVydHkoJ2EuYi5jJykpO1xuICogLy8gPT4gWzIsIDFdXG4gKlxuICogXy5wbHVjayhfLnNvcnRCeShvYmplY3RzLCBfLnByb3BlcnR5KFsnYScsICdiJywgJ2MnXSkpLCAnYS5iLmMnKTtcbiAqIC8vID0+IFsxLCAyXVxuICovXG5mdW5jdGlvbiBwcm9wZXJ0eShwYXRoKSB7XG4gIHJldHVybiBpc0tleShwYXRoKSA/IGJhc2VQcm9wZXJ0eShwYXRoKSA6IGJhc2VQcm9wZXJ0eURlZXAocGF0aCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcHJvcGVydHk7XG4iLCIoZnVuY3Rpb24gKHByb2Nlc3Mpe1xuLy8gdmltOnRzPTQ6c3RzPTQ6c3c9NDpcbi8qIVxuICpcbiAqIENvcHlyaWdodCAyMDA5LTIwMTIgS3JpcyBLb3dhbCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIE1JVFxuICogbGljZW5zZSBmb3VuZCBhdCBodHRwOi8vZ2l0aHViLmNvbS9rcmlza293YWwvcS9yYXcvbWFzdGVyL0xJQ0VOU0VcbiAqXG4gKiBXaXRoIHBhcnRzIGJ5IFR5bGVyIENsb3NlXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDA5IFR5bGVyIENsb3NlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgTUlUIFggbGljZW5zZSBmb3VuZFxuICogYXQgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5odG1sXG4gKiBGb3JrZWQgYXQgcmVmX3NlbmQuanMgdmVyc2lvbjogMjAwOS0wNS0xMVxuICpcbiAqIFdpdGggcGFydHMgYnkgTWFyayBNaWxsZXJcbiAqIENvcHlyaWdodCAoQykgMjAxMSBHb29nbGUgSW5jLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4oZnVuY3Rpb24gKGRlZmluaXRpb24pIHtcbiAgICBcInVzZSBzdHJpY3RcIjtcblxuICAgIC8vIFRoaXMgZmlsZSB3aWxsIGZ1bmN0aW9uIHByb3Blcmx5IGFzIGEgPHNjcmlwdD4gdGFnLCBvciBhIG1vZHVsZVxuICAgIC8vIHVzaW5nIENvbW1vbkpTIGFuZCBOb2RlSlMgb3IgUmVxdWlyZUpTIG1vZHVsZSBmb3JtYXRzLiAgSW5cbiAgICAvLyBDb21tb24vTm9kZS9SZXF1aXJlSlMsIHRoZSBtb2R1bGUgZXhwb3J0cyB0aGUgUSBBUEkgYW5kIHdoZW5cbiAgICAvLyBleGVjdXRlZCBhcyBhIHNpbXBsZSA8c2NyaXB0PiwgaXQgY3JlYXRlcyBhIFEgZ2xvYmFsIGluc3RlYWQuXG5cbiAgICAvLyBNb250YWdlIFJlcXVpcmVcbiAgICBpZiAodHlwZW9mIGJvb3RzdHJhcCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGJvb3RzdHJhcChcInByb21pc2VcIiwgZGVmaW5pdGlvbik7XG5cbiAgICAvLyBDb21tb25KU1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG1vZHVsZSA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGRlZmluaXRpb24oKTtcblxuICAgIC8vIFJlcXVpcmVKU1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcbiAgICAgICAgZGVmaW5lKGRlZmluaXRpb24pO1xuXG4gICAgLy8gU0VTIChTZWN1cmUgRWNtYVNjcmlwdClcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBzZXMgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgaWYgKCFzZXMub2soKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VzLm1ha2VRID0gZGVmaW5pdGlvbjtcbiAgICAgICAgfVxuXG4gICAgLy8gPHNjcmlwdD5cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgfHwgdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgLy8gUHJlZmVyIHdpbmRvdyBvdmVyIHNlbGYgZm9yIGFkZC1vbiBzY3JpcHRzLiBVc2Ugc2VsZiBmb3JcbiAgICAgICAgLy8gbm9uLXdpbmRvd2VkIGNvbnRleHRzLlxuICAgICAgICB2YXIgZ2xvYmFsID0gdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHNlbGY7XG5cbiAgICAgICAgLy8gR2V0IHRoZSBgd2luZG93YCBvYmplY3QsIHNhdmUgdGhlIHByZXZpb3VzIFEgZ2xvYmFsXG4gICAgICAgIC8vIGFuZCBpbml0aWFsaXplIFEgYXMgYSBnbG9iYWwuXG4gICAgICAgIHZhciBwcmV2aW91c1EgPSBnbG9iYWwuUTtcbiAgICAgICAgZ2xvYmFsLlEgPSBkZWZpbml0aW9uKCk7XG5cbiAgICAgICAgLy8gQWRkIGEgbm9Db25mbGljdCBmdW5jdGlvbiBzbyBRIGNhbiBiZSByZW1vdmVkIGZyb20gdGhlXG4gICAgICAgIC8vIGdsb2JhbCBuYW1lc3BhY2UuXG4gICAgICAgIGdsb2JhbC5RLm5vQ29uZmxpY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBnbG9iYWwuUSA9IHByZXZpb3VzUTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9O1xuXG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBlbnZpcm9ubWVudCB3YXMgbm90IGFudGljaXBhdGVkIGJ5IFEuIFBsZWFzZSBmaWxlIGEgYnVnLlwiKTtcbiAgICB9XG5cbn0pKGZ1bmN0aW9uICgpIHtcblwidXNlIHN0cmljdFwiO1xuXG52YXIgaGFzU3RhY2tzID0gZmFsc2U7XG50cnkge1xuICAgIHRocm93IG5ldyBFcnJvcigpO1xufSBjYXRjaCAoZSkge1xuICAgIGhhc1N0YWNrcyA9ICEhZS5zdGFjaztcbn1cblxuLy8gQWxsIGNvZGUgYWZ0ZXIgdGhpcyBwb2ludCB3aWxsIGJlIGZpbHRlcmVkIGZyb20gc3RhY2sgdHJhY2VzIHJlcG9ydGVkXG4vLyBieSBRLlxudmFyIHFTdGFydGluZ0xpbmUgPSBjYXB0dXJlTGluZSgpO1xudmFyIHFGaWxlTmFtZTtcblxuLy8gc2hpbXNcblxuLy8gdXNlZCBmb3IgZmFsbGJhY2sgaW4gXCJhbGxSZXNvbHZlZFwiXG52YXIgbm9vcCA9IGZ1bmN0aW9uICgpIHt9O1xuXG4vLyBVc2UgdGhlIGZhc3Rlc3QgcG9zc2libGUgbWVhbnMgdG8gZXhlY3V0ZSBhIHRhc2sgaW4gYSBmdXR1cmUgdHVyblxuLy8gb2YgdGhlIGV2ZW50IGxvb3AuXG52YXIgbmV4dFRpY2sgPShmdW5jdGlvbiAoKSB7XG4gICAgLy8gbGlua2VkIGxpc3Qgb2YgdGFza3MgKHNpbmdsZSwgd2l0aCBoZWFkIG5vZGUpXG4gICAgdmFyIGhlYWQgPSB7dGFzazogdm9pZCAwLCBuZXh0OiBudWxsfTtcbiAgICB2YXIgdGFpbCA9IGhlYWQ7XG4gICAgdmFyIGZsdXNoaW5nID0gZmFsc2U7XG4gICAgdmFyIHJlcXVlc3RUaWNrID0gdm9pZCAwO1xuICAgIHZhciBpc05vZGVKUyA9IGZhbHNlO1xuICAgIC8vIHF1ZXVlIGZvciBsYXRlIHRhc2tzLCB1c2VkIGJ5IHVuaGFuZGxlZCByZWplY3Rpb24gdHJhY2tpbmdcbiAgICB2YXIgbGF0ZXJRdWV1ZSA9IFtdO1xuXG4gICAgZnVuY3Rpb24gZmx1c2goKSB7XG4gICAgICAgIC8qIGpzaGludCBsb29wZnVuYzogdHJ1ZSAqL1xuICAgICAgICB2YXIgdGFzaywgZG9tYWluO1xuXG4gICAgICAgIHdoaWxlIChoZWFkLm5leHQpIHtcbiAgICAgICAgICAgIGhlYWQgPSBoZWFkLm5leHQ7XG4gICAgICAgICAgICB0YXNrID0gaGVhZC50YXNrO1xuICAgICAgICAgICAgaGVhZC50YXNrID0gdm9pZCAwO1xuICAgICAgICAgICAgZG9tYWluID0gaGVhZC5kb21haW47XG5cbiAgICAgICAgICAgIGlmIChkb21haW4pIHtcbiAgICAgICAgICAgICAgICBoZWFkLmRvbWFpbiA9IHZvaWQgMDtcbiAgICAgICAgICAgICAgICBkb21haW4uZW50ZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJ1blNpbmdsZSh0YXNrLCBkb21haW4pO1xuXG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKGxhdGVyUXVldWUubGVuZ3RoKSB7XG4gICAgICAgICAgICB0YXNrID0gbGF0ZXJRdWV1ZS5wb3AoKTtcbiAgICAgICAgICAgIHJ1blNpbmdsZSh0YXNrKTtcbiAgICAgICAgfVxuICAgICAgICBmbHVzaGluZyA9IGZhbHNlO1xuICAgIH1cbiAgICAvLyBydW5zIGEgc2luZ2xlIGZ1bmN0aW9uIGluIHRoZSBhc3luYyBxdWV1ZVxuICAgIGZ1bmN0aW9uIHJ1blNpbmdsZSh0YXNrLCBkb21haW4pIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRhc2soKTtcblxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBpZiAoaXNOb2RlSlMpIHtcbiAgICAgICAgICAgICAgICAvLyBJbiBub2RlLCB1bmNhdWdodCBleGNlcHRpb25zIGFyZSBjb25zaWRlcmVkIGZhdGFsIGVycm9ycy5cbiAgICAgICAgICAgICAgICAvLyBSZS10aHJvdyB0aGVtIHN5bmNocm9ub3VzbHkgdG8gaW50ZXJydXB0IGZsdXNoaW5nIVxuXG4gICAgICAgICAgICAgICAgLy8gRW5zdXJlIGNvbnRpbnVhdGlvbiBpZiB0aGUgdW5jYXVnaHQgZXhjZXB0aW9uIGlzIHN1cHByZXNzZWRcbiAgICAgICAgICAgICAgICAvLyBsaXN0ZW5pbmcgXCJ1bmNhdWdodEV4Y2VwdGlvblwiIGV2ZW50cyAoYXMgZG9tYWlucyBkb2VzKS5cbiAgICAgICAgICAgICAgICAvLyBDb250aW51ZSBpbiBuZXh0IGV2ZW50IHRvIGF2b2lkIHRpY2sgcmVjdXJzaW9uLlxuICAgICAgICAgICAgICAgIGlmIChkb21haW4pIHtcbiAgICAgICAgICAgICAgICAgICAgZG9tYWluLmV4aXQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dChmbHVzaCwgMCk7XG4gICAgICAgICAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgICAgICAgICBkb21haW4uZW50ZXIoKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBlO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIEluIGJyb3dzZXJzLCB1bmNhdWdodCBleGNlcHRpb25zIGFyZSBub3QgZmF0YWwuXG4gICAgICAgICAgICAgICAgLy8gUmUtdGhyb3cgdGhlbSBhc3luY2hyb25vdXNseSB0byBhdm9pZCBzbG93LWRvd25zLlxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgICAgICAgIH0sIDApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgZG9tYWluLmV4aXQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5leHRUaWNrID0gZnVuY3Rpb24gKHRhc2spIHtcbiAgICAgICAgdGFpbCA9IHRhaWwubmV4dCA9IHtcbiAgICAgICAgICAgIHRhc2s6IHRhc2ssXG4gICAgICAgICAgICBkb21haW46IGlzTm9kZUpTICYmIHByb2Nlc3MuZG9tYWluLFxuICAgICAgICAgICAgbmV4dDogbnVsbFxuICAgICAgICB9O1xuXG4gICAgICAgIGlmICghZmx1c2hpbmcpIHtcbiAgICAgICAgICAgIGZsdXNoaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIHJlcXVlc3RUaWNrKCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgIHByb2Nlc3MudG9TdHJpbmcoKSA9PT0gXCJbb2JqZWN0IHByb2Nlc3NdXCIgJiYgcHJvY2Vzcy5uZXh0VGljaykge1xuICAgICAgICAvLyBFbnN1cmUgUSBpcyBpbiBhIHJlYWwgTm9kZSBlbnZpcm9ubWVudCwgd2l0aCBhIGBwcm9jZXNzLm5leHRUaWNrYC5cbiAgICAgICAgLy8gVG8gc2VlIHRocm91Z2ggZmFrZSBOb2RlIGVudmlyb25tZW50czpcbiAgICAgICAgLy8gKiBNb2NoYSB0ZXN0IHJ1bm5lciAtIGV4cG9zZXMgYSBgcHJvY2Vzc2AgZ2xvYmFsIHdpdGhvdXQgYSBgbmV4dFRpY2tgXG4gICAgICAgIC8vICogQnJvd3NlcmlmeSAtIGV4cG9zZXMgYSBgcHJvY2Vzcy5uZXhUaWNrYCBmdW5jdGlvbiB0aGF0IHVzZXNcbiAgICAgICAgLy8gICBgc2V0VGltZW91dGAuIEluIHRoaXMgY2FzZSBgc2V0SW1tZWRpYXRlYCBpcyBwcmVmZXJyZWQgYmVjYXVzZVxuICAgICAgICAvLyAgICBpdCBpcyBmYXN0ZXIuIEJyb3dzZXJpZnkncyBgcHJvY2Vzcy50b1N0cmluZygpYCB5aWVsZHNcbiAgICAgICAgLy8gICBcIltvYmplY3QgT2JqZWN0XVwiLCB3aGlsZSBpbiBhIHJlYWwgTm9kZSBlbnZpcm9ubWVudFxuICAgICAgICAvLyAgIGBwcm9jZXNzLm5leHRUaWNrKClgIHlpZWxkcyBcIltvYmplY3QgcHJvY2Vzc11cIi5cbiAgICAgICAgaXNOb2RlSlMgPSB0cnVlO1xuXG4gICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcHJvY2Vzcy5uZXh0VGljayhmbHVzaCk7XG4gICAgICAgIH07XG5cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBzZXRJbW1lZGlhdGUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAvLyBJbiBJRTEwLCBOb2RlLmpzIDAuOSssIG9yIGh0dHBzOi8vZ2l0aHViLmNvbS9Ob2JsZUpTL3NldEltbWVkaWF0ZVxuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgcmVxdWVzdFRpY2sgPSBzZXRJbW1lZGlhdGUuYmluZCh3aW5kb3csIGZsdXNoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHNldEltbWVkaWF0ZShmbHVzaCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBNZXNzYWdlQ2hhbm5lbCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAvLyBtb2Rlcm4gYnJvd3NlcnNcbiAgICAgICAgLy8gaHR0cDovL3d3dy5ub25ibG9ja2luZy5pby8yMDExLzA2L3dpbmRvd25leHR0aWNrLmh0bWxcbiAgICAgICAgdmFyIGNoYW5uZWwgPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcbiAgICAgICAgLy8gQXQgbGVhc3QgU2FmYXJpIFZlcnNpb24gNi4wLjUgKDg1MzYuMzAuMSkgaW50ZXJtaXR0ZW50bHkgY2Fubm90IGNyZWF0ZVxuICAgICAgICAvLyB3b3JraW5nIG1lc3NhZ2UgcG9ydHMgdGhlIGZpcnN0IHRpbWUgYSBwYWdlIGxvYWRzLlxuICAgICAgICBjaGFubmVsLnBvcnQxLm9ubWVzc2FnZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJlcXVlc3RUaWNrID0gcmVxdWVzdFBvcnRUaWNrO1xuICAgICAgICAgICAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSBmbHVzaDtcbiAgICAgICAgICAgIGZsdXNoKCk7XG4gICAgICAgIH07XG4gICAgICAgIHZhciByZXF1ZXN0UG9ydFRpY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAvLyBPcGVyYSByZXF1aXJlcyB1cyB0byBwcm92aWRlIGEgbWVzc2FnZSBwYXlsb2FkLCByZWdhcmRsZXNzIG9mXG4gICAgICAgICAgICAvLyB3aGV0aGVyIHdlIHVzZSBpdC5cbiAgICAgICAgICAgIGNoYW5uZWwucG9ydDIucG9zdE1lc3NhZ2UoMCk7XG4gICAgICAgIH07XG4gICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgc2V0VGltZW91dChmbHVzaCwgMCk7XG4gICAgICAgICAgICByZXF1ZXN0UG9ydFRpY2soKTtcbiAgICAgICAgfTtcblxuICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG9sZCBicm93c2Vyc1xuICAgICAgICByZXF1ZXN0VGljayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoZmx1c2gsIDApO1xuICAgICAgICB9O1xuICAgIH1cbiAgICAvLyBydW5zIGEgdGFzayBhZnRlciBhbGwgb3RoZXIgdGFza3MgaGF2ZSBiZWVuIHJ1blxuICAgIC8vIHRoaXMgaXMgdXNlZnVsIGZvciB1bmhhbmRsZWQgcmVqZWN0aW9uIHRyYWNraW5nIHRoYXQgbmVlZHMgdG8gaGFwcGVuXG4gICAgLy8gYWZ0ZXIgYWxsIGB0aGVuYGQgdGFza3MgaGF2ZSBiZWVuIHJ1bi5cbiAgICBuZXh0VGljay5ydW5BZnRlciA9IGZ1bmN0aW9uICh0YXNrKSB7XG4gICAgICAgIGxhdGVyUXVldWUucHVzaCh0YXNrKTtcbiAgICAgICAgaWYgKCFmbHVzaGluZykge1xuICAgICAgICAgICAgZmx1c2hpbmcgPSB0cnVlO1xuICAgICAgICAgICAgcmVxdWVzdFRpY2soKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIG5leHRUaWNrO1xufSkoKTtcblxuLy8gQXR0ZW1wdCB0byBtYWtlIGdlbmVyaWNzIHNhZmUgaW4gdGhlIGZhY2Ugb2YgZG93bnN0cmVhbVxuLy8gbW9kaWZpY2F0aW9ucy5cbi8vIFRoZXJlIGlzIG5vIHNpdHVhdGlvbiB3aGVyZSB0aGlzIGlzIG5lY2Vzc2FyeS5cbi8vIElmIHlvdSBuZWVkIGEgc2VjdXJpdHkgZ3VhcmFudGVlLCB0aGVzZSBwcmltb3JkaWFscyBuZWVkIHRvIGJlXG4vLyBkZWVwbHkgZnJvemVuIGFueXdheSwgYW5kIGlmIHlvdSBkb27igJl0IG5lZWQgYSBzZWN1cml0eSBndWFyYW50ZWUsXG4vLyB0aGlzIGlzIGp1c3QgcGxhaW4gcGFyYW5vaWQuXG4vLyBIb3dldmVyLCB0aGlzICoqbWlnaHQqKiBoYXZlIHRoZSBuaWNlIHNpZGUtZWZmZWN0IG9mIHJlZHVjaW5nIHRoZSBzaXplIG9mXG4vLyB0aGUgbWluaWZpZWQgY29kZSBieSByZWR1Y2luZyB4LmNhbGwoKSB0byBtZXJlbHkgeCgpXG4vLyBTZWUgTWFyayBNaWxsZXLigJlzIGV4cGxhbmF0aW9uIG9mIHdoYXQgdGhpcyBkb2VzLlxuLy8gaHR0cDovL3dpa2kuZWNtYXNjcmlwdC5vcmcvZG9rdS5waHA/aWQ9Y29udmVudGlvbnM6c2FmZV9tZXRhX3Byb2dyYW1taW5nXG52YXIgY2FsbCA9IEZ1bmN0aW9uLmNhbGw7XG5mdW5jdGlvbiB1bmN1cnJ5VGhpcyhmKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGNhbGwuYXBwbHkoZiwgYXJndW1lbnRzKTtcbiAgICB9O1xufVxuLy8gVGhpcyBpcyBlcXVpdmFsZW50LCBidXQgc2xvd2VyOlxuLy8gdW5jdXJyeVRoaXMgPSBGdW5jdGlvbl9iaW5kLmJpbmQoRnVuY3Rpb25fYmluZC5jYWxsKTtcbi8vIGh0dHA6Ly9qc3BlcmYuY29tL3VuY3Vycnl0aGlzXG5cbnZhciBhcnJheV9zbGljZSA9IHVuY3VycnlUaGlzKEFycmF5LnByb3RvdHlwZS5zbGljZSk7XG5cbnZhciBhcnJheV9yZWR1Y2UgPSB1bmN1cnJ5VGhpcyhcbiAgICBBcnJheS5wcm90b3R5cGUucmVkdWNlIHx8IGZ1bmN0aW9uIChjYWxsYmFjaywgYmFzaXMpIHtcbiAgICAgICAgdmFyIGluZGV4ID0gMCxcbiAgICAgICAgICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoO1xuICAgICAgICAvLyBjb25jZXJuaW5nIHRoZSBpbml0aWFsIHZhbHVlLCBpZiBvbmUgaXMgbm90IHByb3ZpZGVkXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAvLyBzZWVrIHRvIHRoZSBmaXJzdCB2YWx1ZSBpbiB0aGUgYXJyYXksIGFjY291bnRpbmdcbiAgICAgICAgICAgIC8vIGZvciB0aGUgcG9zc2liaWxpdHkgdGhhdCBpcyBpcyBhIHNwYXJzZSBhcnJheVxuICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICAgIGlmIChpbmRleCBpbiB0aGlzKSB7XG4gICAgICAgICAgICAgICAgICAgIGJhc2lzID0gdGhpc1tpbmRleCsrXTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICgrK2luZGV4ID49IGxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSB3aGlsZSAoMSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gcmVkdWNlXG4gICAgICAgIGZvciAoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgICAgLy8gYWNjb3VudCBmb3IgdGhlIHBvc3NpYmlsaXR5IHRoYXQgdGhlIGFycmF5IGlzIHNwYXJzZVxuICAgICAgICAgICAgaWYgKGluZGV4IGluIHRoaXMpIHtcbiAgICAgICAgICAgICAgICBiYXNpcyA9IGNhbGxiYWNrKGJhc2lzLCB0aGlzW2luZGV4XSwgaW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBiYXNpcztcbiAgICB9XG4pO1xuXG52YXIgYXJyYXlfaW5kZXhPZiA9IHVuY3VycnlUaGlzKFxuICAgIEFycmF5LnByb3RvdHlwZS5pbmRleE9mIHx8IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAvLyBub3QgYSB2ZXJ5IGdvb2Qgc2hpbSwgYnV0IGdvb2QgZW5vdWdoIGZvciBvdXIgb25lIHVzZSBvZiBpdFxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0aGlzW2ldID09PSB2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiAtMTtcbiAgICB9XG4pO1xuXG52YXIgYXJyYXlfbWFwID0gdW5jdXJyeVRoaXMoXG4gICAgQXJyYXkucHJvdG90eXBlLm1hcCB8fCBmdW5jdGlvbiAoY2FsbGJhY2ssIHRoaXNwKSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgdmFyIGNvbGxlY3QgPSBbXTtcbiAgICAgICAgYXJyYXlfcmVkdWNlKHNlbGYsIGZ1bmN0aW9uICh1bmRlZmluZWQsIHZhbHVlLCBpbmRleCkge1xuICAgICAgICAgICAgY29sbGVjdC5wdXNoKGNhbGxiYWNrLmNhbGwodGhpc3AsIHZhbHVlLCBpbmRleCwgc2VsZikpO1xuICAgICAgICB9LCB2b2lkIDApO1xuICAgICAgICByZXR1cm4gY29sbGVjdDtcbiAgICB9XG4pO1xuXG52YXIgb2JqZWN0X2NyZWF0ZSA9IE9iamVjdC5jcmVhdGUgfHwgZnVuY3Rpb24gKHByb3RvdHlwZSkge1xuICAgIGZ1bmN0aW9uIFR5cGUoKSB7IH1cbiAgICBUeXBlLnByb3RvdHlwZSA9IHByb3RvdHlwZTtcbiAgICByZXR1cm4gbmV3IFR5cGUoKTtcbn07XG5cbnZhciBvYmplY3RfaGFzT3duUHJvcGVydHkgPSB1bmN1cnJ5VGhpcyhPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5KTtcblxudmFyIG9iamVjdF9rZXlzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24gKG9iamVjdCkge1xuICAgIHZhciBrZXlzID0gW107XG4gICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAgICBpZiAob2JqZWN0X2hhc093blByb3BlcnR5KG9iamVjdCwga2V5KSkge1xuICAgICAgICAgICAga2V5cy5wdXNoKGtleSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGtleXM7XG59O1xuXG52YXIgb2JqZWN0X3RvU3RyaW5nID0gdW5jdXJyeVRoaXMoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZyk7XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSBPYmplY3QodmFsdWUpO1xufVxuXG4vLyBnZW5lcmF0b3IgcmVsYXRlZCBzaGltc1xuXG4vLyBGSVhNRTogUmVtb3ZlIHRoaXMgZnVuY3Rpb24gb25jZSBFUzYgZ2VuZXJhdG9ycyBhcmUgaW4gU3BpZGVyTW9ua2V5LlxuZnVuY3Rpb24gaXNTdG9wSXRlcmF0aW9uKGV4Y2VwdGlvbikge1xuICAgIHJldHVybiAoXG4gICAgICAgIG9iamVjdF90b1N0cmluZyhleGNlcHRpb24pID09PSBcIltvYmplY3QgU3RvcEl0ZXJhdGlvbl1cIiB8fFxuICAgICAgICBleGNlcHRpb24gaW5zdGFuY2VvZiBRUmV0dXJuVmFsdWVcbiAgICApO1xufVxuXG4vLyBGSVhNRTogUmVtb3ZlIHRoaXMgaGVscGVyIGFuZCBRLnJldHVybiBvbmNlIEVTNiBnZW5lcmF0b3JzIGFyZSBpblxuLy8gU3BpZGVyTW9ua2V5LlxudmFyIFFSZXR1cm5WYWx1ZTtcbmlmICh0eXBlb2YgUmV0dXJuVmFsdWUgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICBRUmV0dXJuVmFsdWUgPSBSZXR1cm5WYWx1ZTtcbn0gZWxzZSB7XG4gICAgUVJldHVyblZhbHVlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB9O1xufVxuXG4vLyBsb25nIHN0YWNrIHRyYWNlc1xuXG52YXIgU1RBQ0tfSlVNUF9TRVBBUkFUT1IgPSBcIkZyb20gcHJldmlvdXMgZXZlbnQ6XCI7XG5cbmZ1bmN0aW9uIG1ha2VTdGFja1RyYWNlTG9uZyhlcnJvciwgcHJvbWlzZSkge1xuICAgIC8vIElmIHBvc3NpYmxlLCB0cmFuc2Zvcm0gdGhlIGVycm9yIHN0YWNrIHRyYWNlIGJ5IHJlbW92aW5nIE5vZGUgYW5kIFFcbiAgICAvLyBjcnVmdCwgdGhlbiBjb25jYXRlbmF0aW5nIHdpdGggdGhlIHN0YWNrIHRyYWNlIG9mIGBwcm9taXNlYC4gU2VlICM1Ny5cbiAgICBpZiAoaGFzU3RhY2tzICYmXG4gICAgICAgIHByb21pc2Uuc3RhY2sgJiZcbiAgICAgICAgdHlwZW9mIGVycm9yID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgIGVycm9yICE9PSBudWxsICYmXG4gICAgICAgIGVycm9yLnN0YWNrICYmXG4gICAgICAgIGVycm9yLnN0YWNrLmluZGV4T2YoU1RBQ0tfSlVNUF9TRVBBUkFUT1IpID09PSAtMVxuICAgICkge1xuICAgICAgICB2YXIgc3RhY2tzID0gW107XG4gICAgICAgIGZvciAodmFyIHAgPSBwcm9taXNlOyAhIXA7IHAgPSBwLnNvdXJjZSkge1xuICAgICAgICAgICAgaWYgKHAuc3RhY2spIHtcbiAgICAgICAgICAgICAgICBzdGFja3MudW5zaGlmdChwLnN0YWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzdGFja3MudW5zaGlmdChlcnJvci5zdGFjayk7XG5cbiAgICAgICAgdmFyIGNvbmNhdGVkU3RhY2tzID0gc3RhY2tzLmpvaW4oXCJcXG5cIiArIFNUQUNLX0pVTVBfU0VQQVJBVE9SICsgXCJcXG5cIik7XG4gICAgICAgIGVycm9yLnN0YWNrID0gZmlsdGVyU3RhY2tTdHJpbmcoY29uY2F0ZWRTdGFja3MpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZmlsdGVyU3RhY2tTdHJpbmcoc3RhY2tTdHJpbmcpIHtcbiAgICB2YXIgbGluZXMgPSBzdGFja1N0cmluZy5zcGxpdChcIlxcblwiKTtcbiAgICB2YXIgZGVzaXJlZExpbmVzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgbGluZSA9IGxpbmVzW2ldO1xuXG4gICAgICAgIGlmICghaXNJbnRlcm5hbEZyYW1lKGxpbmUpICYmICFpc05vZGVGcmFtZShsaW5lKSAmJiBsaW5lKSB7XG4gICAgICAgICAgICBkZXNpcmVkTGluZXMucHVzaChsaW5lKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGVzaXJlZExpbmVzLmpvaW4oXCJcXG5cIik7XG59XG5cbmZ1bmN0aW9uIGlzTm9kZUZyYW1lKHN0YWNrTGluZSkge1xuICAgIHJldHVybiBzdGFja0xpbmUuaW5kZXhPZihcIihtb2R1bGUuanM6XCIpICE9PSAtMSB8fFxuICAgICAgICAgICBzdGFja0xpbmUuaW5kZXhPZihcIihub2RlLmpzOlwiKSAhPT0gLTE7XG59XG5cbmZ1bmN0aW9uIGdldEZpbGVOYW1lQW5kTGluZU51bWJlcihzdGFja0xpbmUpIHtcbiAgICAvLyBOYW1lZCBmdW5jdGlvbnM6IFwiYXQgZnVuY3Rpb25OYW1lIChmaWxlbmFtZTpsaW5lTnVtYmVyOmNvbHVtbk51bWJlcilcIlxuICAgIC8vIEluIElFMTAgZnVuY3Rpb24gbmFtZSBjYW4gaGF2ZSBzcGFjZXMgKFwiQW5vbnltb3VzIGZ1bmN0aW9uXCIpIE9fb1xuICAgIHZhciBhdHRlbXB0MSA9IC9hdCAuKyBcXCgoLispOihcXGQrKTooPzpcXGQrKVxcKSQvLmV4ZWMoc3RhY2tMaW5lKTtcbiAgICBpZiAoYXR0ZW1wdDEpIHtcbiAgICAgICAgcmV0dXJuIFthdHRlbXB0MVsxXSwgTnVtYmVyKGF0dGVtcHQxWzJdKV07XG4gICAgfVxuXG4gICAgLy8gQW5vbnltb3VzIGZ1bmN0aW9uczogXCJhdCBmaWxlbmFtZTpsaW5lTnVtYmVyOmNvbHVtbk51bWJlclwiXG4gICAgdmFyIGF0dGVtcHQyID0gL2F0IChbXiBdKyk6KFxcZCspOig/OlxcZCspJC8uZXhlYyhzdGFja0xpbmUpO1xuICAgIGlmIChhdHRlbXB0Mikge1xuICAgICAgICByZXR1cm4gW2F0dGVtcHQyWzFdLCBOdW1iZXIoYXR0ZW1wdDJbMl0pXTtcbiAgICB9XG5cbiAgICAvLyBGaXJlZm94IHN0eWxlOiBcImZ1bmN0aW9uQGZpbGVuYW1lOmxpbmVOdW1iZXIgb3IgQGZpbGVuYW1lOmxpbmVOdW1iZXJcIlxuICAgIHZhciBhdHRlbXB0MyA9IC8uKkAoLispOihcXGQrKSQvLmV4ZWMoc3RhY2tMaW5lKTtcbiAgICBpZiAoYXR0ZW1wdDMpIHtcbiAgICAgICAgcmV0dXJuIFthdHRlbXB0M1sxXSwgTnVtYmVyKGF0dGVtcHQzWzJdKV07XG4gICAgfVxufVxuXG5mdW5jdGlvbiBpc0ludGVybmFsRnJhbWUoc3RhY2tMaW5lKSB7XG4gICAgdmFyIGZpbGVOYW1lQW5kTGluZU51bWJlciA9IGdldEZpbGVOYW1lQW5kTGluZU51bWJlcihzdGFja0xpbmUpO1xuXG4gICAgaWYgKCFmaWxlTmFtZUFuZExpbmVOdW1iZXIpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHZhciBmaWxlTmFtZSA9IGZpbGVOYW1lQW5kTGluZU51bWJlclswXTtcbiAgICB2YXIgbGluZU51bWJlciA9IGZpbGVOYW1lQW5kTGluZU51bWJlclsxXTtcblxuICAgIHJldHVybiBmaWxlTmFtZSA9PT0gcUZpbGVOYW1lICYmXG4gICAgICAgIGxpbmVOdW1iZXIgPj0gcVN0YXJ0aW5nTGluZSAmJlxuICAgICAgICBsaW5lTnVtYmVyIDw9IHFFbmRpbmdMaW5lO1xufVxuXG4vLyBkaXNjb3ZlciBvd24gZmlsZSBuYW1lIGFuZCBsaW5lIG51bWJlciByYW5nZSBmb3IgZmlsdGVyaW5nIHN0YWNrXG4vLyB0cmFjZXNcbmZ1bmN0aW9uIGNhcHR1cmVMaW5lKCkge1xuICAgIGlmICghaGFzU3RhY2tzKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHZhciBsaW5lcyA9IGUuc3RhY2suc3BsaXQoXCJcXG5cIik7XG4gICAgICAgIHZhciBmaXJzdExpbmUgPSBsaW5lc1swXS5pbmRleE9mKFwiQFwiKSA+IDAgPyBsaW5lc1sxXSA6IGxpbmVzWzJdO1xuICAgICAgICB2YXIgZmlsZU5hbWVBbmRMaW5lTnVtYmVyID0gZ2V0RmlsZU5hbWVBbmRMaW5lTnVtYmVyKGZpcnN0TGluZSk7XG4gICAgICAgIGlmICghZmlsZU5hbWVBbmRMaW5lTnVtYmVyKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBxRmlsZU5hbWUgPSBmaWxlTmFtZUFuZExpbmVOdW1iZXJbMF07XG4gICAgICAgIHJldHVybiBmaWxlTmFtZUFuZExpbmVOdW1iZXJbMV07XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkZXByZWNhdGUoY2FsbGJhY2ssIG5hbWUsIGFsdGVybmF0aXZlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjb25zb2xlICE9PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgICB0eXBlb2YgY29uc29sZS53YXJuID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihuYW1lICsgXCIgaXMgZGVwcmVjYXRlZCwgdXNlIFwiICsgYWx0ZXJuYXRpdmUgK1xuICAgICAgICAgICAgICAgICAgICAgICAgIFwiIGluc3RlYWQuXCIsIG5ldyBFcnJvcihcIlwiKS5zdGFjayk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KGNhbGxiYWNrLCBhcmd1bWVudHMpO1xuICAgIH07XG59XG5cbi8vIGVuZCBvZiBzaGltc1xuLy8gYmVnaW5uaW5nIG9mIHJlYWwgd29ya1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBwcm9taXNlIGZvciBhbiBpbW1lZGlhdGUgcmVmZXJlbmNlLCBwYXNzZXMgcHJvbWlzZXMgdGhyb3VnaCwgb3JcbiAqIGNvZXJjZXMgcHJvbWlzZXMgZnJvbSBkaWZmZXJlbnQgc3lzdGVtcy5cbiAqIEBwYXJhbSB2YWx1ZSBpbW1lZGlhdGUgcmVmZXJlbmNlIG9yIHByb21pc2VcbiAqL1xuZnVuY3Rpb24gUSh2YWx1ZSkge1xuICAgIC8vIElmIHRoZSBvYmplY3QgaXMgYWxyZWFkeSBhIFByb21pc2UsIHJldHVybiBpdCBkaXJlY3RseS4gIFRoaXMgZW5hYmxlc1xuICAgIC8vIHRoZSByZXNvbHZlIGZ1bmN0aW9uIHRvIGJvdGggYmUgdXNlZCB0byBjcmVhdGVkIHJlZmVyZW5jZXMgZnJvbSBvYmplY3RzLFxuICAgIC8vIGJ1dCB0byB0b2xlcmFibHkgY29lcmNlIG5vbi1wcm9taXNlcyB0byBwcm9taXNlcy5cbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICAvLyBhc3NpbWlsYXRlIHRoZW5hYmxlc1xuICAgIGlmIChpc1Byb21pc2VBbGlrZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGNvZXJjZSh2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZ1bGZpbGwodmFsdWUpO1xuICAgIH1cbn1cblEucmVzb2x2ZSA9IFE7XG5cbi8qKlxuICogUGVyZm9ybXMgYSB0YXNrIGluIGEgZnV0dXJlIHR1cm4gb2YgdGhlIGV2ZW50IGxvb3AuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB0YXNrXG4gKi9cblEubmV4dFRpY2sgPSBuZXh0VGljaztcblxuLyoqXG4gKiBDb250cm9scyB3aGV0aGVyIG9yIG5vdCBsb25nIHN0YWNrIHRyYWNlcyB3aWxsIGJlIG9uXG4gKi9cblEubG9uZ1N0YWNrU3VwcG9ydCA9IGZhbHNlO1xuXG4vLyBlbmFibGUgbG9uZyBzdGFja3MgaWYgUV9ERUJVRyBpcyBzZXRcbmlmICh0eXBlb2YgcHJvY2VzcyA9PT0gXCJvYmplY3RcIiAmJiBwcm9jZXNzICYmIHByb2Nlc3MuZW52ICYmIHByb2Nlc3MuZW52LlFfREVCVUcpIHtcbiAgICBRLmxvbmdTdGFja1N1cHBvcnQgPSB0cnVlO1xufVxuXG4vKipcbiAqIENvbnN0cnVjdHMgYSB7cHJvbWlzZSwgcmVzb2x2ZSwgcmVqZWN0fSBvYmplY3QuXG4gKlxuICogYHJlc29sdmVgIGlzIGEgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggYSBtb3JlIHJlc29sdmVkIHZhbHVlIGZvciB0aGVcbiAqIHByb21pc2UuIFRvIGZ1bGZpbGwgdGhlIHByb21pc2UsIGludm9rZSBgcmVzb2x2ZWAgd2l0aCBhbnkgdmFsdWUgdGhhdCBpc1xuICogbm90IGEgdGhlbmFibGUuIFRvIHJlamVjdCB0aGUgcHJvbWlzZSwgaW52b2tlIGByZXNvbHZlYCB3aXRoIGEgcmVqZWN0ZWRcbiAqIHRoZW5hYmxlLCBvciBpbnZva2UgYHJlamVjdGAgd2l0aCB0aGUgcmVhc29uIGRpcmVjdGx5LiBUbyByZXNvbHZlIHRoZVxuICogcHJvbWlzZSB0byBhbm90aGVyIHRoZW5hYmxlLCB0aHVzIHB1dHRpbmcgaXQgaW4gdGhlIHNhbWUgc3RhdGUsIGludm9rZVxuICogYHJlc29sdmVgIHdpdGggdGhhdCBvdGhlciB0aGVuYWJsZS5cbiAqL1xuUS5kZWZlciA9IGRlZmVyO1xuZnVuY3Rpb24gZGVmZXIoKSB7XG4gICAgLy8gaWYgXCJtZXNzYWdlc1wiIGlzIGFuIFwiQXJyYXlcIiwgdGhhdCBpbmRpY2F0ZXMgdGhhdCB0aGUgcHJvbWlzZSBoYXMgbm90IHlldFxuICAgIC8vIGJlZW4gcmVzb2x2ZWQuICBJZiBpdCBpcyBcInVuZGVmaW5lZFwiLCBpdCBoYXMgYmVlbiByZXNvbHZlZC4gIEVhY2hcbiAgICAvLyBlbGVtZW50IG9mIHRoZSBtZXNzYWdlcyBhcnJheSBpcyBpdHNlbGYgYW4gYXJyYXkgb2YgY29tcGxldGUgYXJndW1lbnRzIHRvXG4gICAgLy8gZm9yd2FyZCB0byB0aGUgcmVzb2x2ZWQgcHJvbWlzZS4gIFdlIGNvZXJjZSB0aGUgcmVzb2x1dGlvbiB2YWx1ZSB0byBhXG4gICAgLy8gcHJvbWlzZSB1c2luZyB0aGUgYHJlc29sdmVgIGZ1bmN0aW9uIGJlY2F1c2UgaXQgaGFuZGxlcyBib3RoIGZ1bGx5XG4gICAgLy8gbm9uLXRoZW5hYmxlIHZhbHVlcyBhbmQgb3RoZXIgdGhlbmFibGVzIGdyYWNlZnVsbHkuXG4gICAgdmFyIG1lc3NhZ2VzID0gW10sIHByb2dyZXNzTGlzdGVuZXJzID0gW10sIHJlc29sdmVkUHJvbWlzZTtcblxuICAgIHZhciBkZWZlcnJlZCA9IG9iamVjdF9jcmVhdGUoZGVmZXIucHJvdG90eXBlKTtcbiAgICB2YXIgcHJvbWlzZSA9IG9iamVjdF9jcmVhdGUoUHJvbWlzZS5wcm90b3R5cGUpO1xuXG4gICAgcHJvbWlzZS5wcm9taXNlRGlzcGF0Y2ggPSBmdW5jdGlvbiAocmVzb2x2ZSwgb3AsIG9wZXJhbmRzKSB7XG4gICAgICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICAgICAgaWYgKG1lc3NhZ2VzKSB7XG4gICAgICAgICAgICBtZXNzYWdlcy5wdXNoKGFyZ3MpO1xuICAgICAgICAgICAgaWYgKG9wID09PSBcIndoZW5cIiAmJiBvcGVyYW5kc1sxXSkgeyAvLyBwcm9ncmVzcyBvcGVyYW5kXG4gICAgICAgICAgICAgICAgcHJvZ3Jlc3NMaXN0ZW5lcnMucHVzaChvcGVyYW5kc1sxXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBRLm5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlZFByb21pc2UucHJvbWlzZURpc3BhdGNoLmFwcGx5KHJlc29sdmVkUHJvbWlzZSwgYXJncyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvLyBYWFggZGVwcmVjYXRlZFxuICAgIHByb21pc2UudmFsdWVPZiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKG1lc3NhZ2VzKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbmVhcmVyVmFsdWUgPSBuZWFyZXIocmVzb2x2ZWRQcm9taXNlKTtcbiAgICAgICAgaWYgKGlzUHJvbWlzZShuZWFyZXJWYWx1ZSkpIHtcbiAgICAgICAgICAgIHJlc29sdmVkUHJvbWlzZSA9IG5lYXJlclZhbHVlOyAvLyBzaG9ydGVuIGNoYWluXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5lYXJlclZhbHVlO1xuICAgIH07XG5cbiAgICBwcm9taXNlLmluc3BlY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghcmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm4geyBzdGF0ZTogXCJwZW5kaW5nXCIgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzb2x2ZWRQcm9taXNlLmluc3BlY3QoKTtcbiAgICB9O1xuXG4gICAgaWYgKFEubG9uZ1N0YWNrU3VwcG9ydCAmJiBoYXNTdGFja3MpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBOT1RFOiBkb24ndCB0cnkgdG8gdXNlIGBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZWAgb3IgdHJhbnNmZXIgdGhlXG4gICAgICAgICAgICAvLyBhY2Nlc3NvciBhcm91bmQ7IHRoYXQgY2F1c2VzIG1lbW9yeSBsZWFrcyBhcyBwZXIgR0gtMTExLiBKdXN0XG4gICAgICAgICAgICAvLyByZWlmeSB0aGUgc3RhY2sgdHJhY2UgYXMgYSBzdHJpbmcgQVNBUC5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBBdCB0aGUgc2FtZSB0aW1lLCBjdXQgb2ZmIHRoZSBmaXJzdCBsaW5lOyBpdCdzIGFsd2F5cyBqdXN0XG4gICAgICAgICAgICAvLyBcIltvYmplY3QgUHJvbWlzZV1cXG5cIiwgYXMgcGVyIHRoZSBgdG9TdHJpbmdgLlxuICAgICAgICAgICAgcHJvbWlzZS5zdGFjayA9IGUuc3RhY2suc3Vic3RyaW5nKGUuc3RhY2suaW5kZXhPZihcIlxcblwiKSArIDEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gTk9URTogd2UgZG8gdGhlIGNoZWNrcyBmb3IgYHJlc29sdmVkUHJvbWlzZWAgaW4gZWFjaCBtZXRob2QsIGluc3RlYWQgb2ZcbiAgICAvLyBjb25zb2xpZGF0aW5nIHRoZW0gaW50byBgYmVjb21lYCwgc2luY2Ugb3RoZXJ3aXNlIHdlJ2QgY3JlYXRlIG5ld1xuICAgIC8vIHByb21pc2VzIHdpdGggdGhlIGxpbmVzIGBiZWNvbWUod2hhdGV2ZXIodmFsdWUpKWAuIFNlZSBlLmcuIEdILTI1Mi5cblxuICAgIGZ1bmN0aW9uIGJlY29tZShuZXdQcm9taXNlKSB7XG4gICAgICAgIHJlc29sdmVkUHJvbWlzZSA9IG5ld1Byb21pc2U7XG4gICAgICAgIHByb21pc2Uuc291cmNlID0gbmV3UHJvbWlzZTtcblxuICAgICAgICBhcnJheV9yZWR1Y2UobWVzc2FnZXMsIGZ1bmN0aW9uICh1bmRlZmluZWQsIG1lc3NhZ2UpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIG5ld1Byb21pc2UucHJvbWlzZURpc3BhdGNoLmFwcGx5KG5ld1Byb21pc2UsIG1lc3NhZ2UpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sIHZvaWQgMCk7XG5cbiAgICAgICAgbWVzc2FnZXMgPSB2b2lkIDA7XG4gICAgICAgIHByb2dyZXNzTGlzdGVuZXJzID0gdm9pZCAwO1xuICAgIH1cblxuICAgIGRlZmVycmVkLnByb21pc2UgPSBwcm9taXNlO1xuICAgIGRlZmVycmVkLnJlc29sdmUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgaWYgKHJlc29sdmVkUHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgYmVjb21lKFEodmFsdWUpKTtcbiAgICB9O1xuXG4gICAgZGVmZXJyZWQuZnVsZmlsbCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICBpZiAocmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBiZWNvbWUoZnVsZmlsbCh2YWx1ZSkpO1xuICAgIH07XG4gICAgZGVmZXJyZWQucmVqZWN0ID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgICBpZiAocmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBiZWNvbWUocmVqZWN0KHJlYXNvbikpO1xuICAgIH07XG4gICAgZGVmZXJyZWQubm90aWZ5ID0gZnVuY3Rpb24gKHByb2dyZXNzKSB7XG4gICAgICAgIGlmIChyZXNvbHZlZFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGFycmF5X3JlZHVjZShwcm9ncmVzc0xpc3RlbmVycywgZnVuY3Rpb24gKHVuZGVmaW5lZCwgcHJvZ3Jlc3NMaXN0ZW5lcikge1xuICAgICAgICAgICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcHJvZ3Jlc3NMaXN0ZW5lcihwcm9ncmVzcyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSwgdm9pZCAwKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIGRlZmVycmVkO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBOb2RlLXN0eWxlIGNhbGxiYWNrIHRoYXQgd2lsbCByZXNvbHZlIG9yIHJlamVjdCB0aGUgZGVmZXJyZWRcbiAqIHByb21pc2UuXG4gKiBAcmV0dXJucyBhIG5vZGViYWNrXG4gKi9cbmRlZmVyLnByb3RvdHlwZS5tYWtlTm9kZVJlc29sdmVyID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICByZXR1cm4gZnVuY3Rpb24gKGVycm9yLCB2YWx1ZSkge1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgIHNlbGYucmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMikge1xuICAgICAgICAgICAgc2VsZi5yZXNvbHZlKGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VsZi5yZXNvbHZlKHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuXG4vKipcbiAqIEBwYXJhbSByZXNvbHZlciB7RnVuY3Rpb259IGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIG5vdGhpbmcgYW5kIGFjY2VwdHNcbiAqIHRoZSByZXNvbHZlLCByZWplY3QsIGFuZCBub3RpZnkgZnVuY3Rpb25zIGZvciBhIGRlZmVycmVkLlxuICogQHJldHVybnMgYSBwcm9taXNlIHRoYXQgbWF5IGJlIHJlc29sdmVkIHdpdGggdGhlIGdpdmVuIHJlc29sdmUgYW5kIHJlamVjdFxuICogZnVuY3Rpb25zLCBvciByZWplY3RlZCBieSBhIHRocm93biBleGNlcHRpb24gaW4gcmVzb2x2ZXJcbiAqL1xuUS5Qcm9taXNlID0gcHJvbWlzZTsgLy8gRVM2XG5RLnByb21pc2UgPSBwcm9taXNlO1xuZnVuY3Rpb24gcHJvbWlzZShyZXNvbHZlcikge1xuICAgIGlmICh0eXBlb2YgcmVzb2x2ZXIgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwicmVzb2x2ZXIgbXVzdCBiZSBhIGZ1bmN0aW9uLlwiKTtcbiAgICB9XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB0cnkge1xuICAgICAgICByZXNvbHZlcihkZWZlcnJlZC5yZXNvbHZlLCBkZWZlcnJlZC5yZWplY3QsIGRlZmVycmVkLm5vdGlmeSk7XG4gICAgfSBjYXRjaCAocmVhc29uKSB7XG4gICAgICAgIGRlZmVycmVkLnJlamVjdChyZWFzb24pO1xuICAgIH1cbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn1cblxucHJvbWlzZS5yYWNlID0gcmFjZTsgLy8gRVM2XG5wcm9taXNlLmFsbCA9IGFsbDsgLy8gRVM2XG5wcm9taXNlLnJlamVjdCA9IHJlamVjdDsgLy8gRVM2XG5wcm9taXNlLnJlc29sdmUgPSBROyAvLyBFUzZcblxuLy8gWFhYIGV4cGVyaW1lbnRhbC4gIFRoaXMgbWV0aG9kIGlzIGEgd2F5IHRvIGRlbm90ZSB0aGF0IGEgbG9jYWwgdmFsdWUgaXNcbi8vIHNlcmlhbGl6YWJsZSBhbmQgc2hvdWxkIGJlIGltbWVkaWF0ZWx5IGRpc3BhdGNoZWQgdG8gYSByZW1vdGUgdXBvbiByZXF1ZXN0LFxuLy8gaW5zdGVhZCBvZiBwYXNzaW5nIGEgcmVmZXJlbmNlLlxuUS5wYXNzQnlDb3B5ID0gZnVuY3Rpb24gKG9iamVjdCkge1xuICAgIC8vZnJlZXplKG9iamVjdCk7XG4gICAgLy9wYXNzQnlDb3BpZXMuc2V0KG9iamVjdCwgdHJ1ZSk7XG4gICAgcmV0dXJuIG9iamVjdDtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnBhc3NCeUNvcHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgLy9mcmVlemUob2JqZWN0KTtcbiAgICAvL3Bhc3NCeUNvcGllcy5zZXQob2JqZWN0LCB0cnVlKTtcbiAgICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogSWYgdHdvIHByb21pc2VzIGV2ZW50dWFsbHkgZnVsZmlsbCB0byB0aGUgc2FtZSB2YWx1ZSwgcHJvbWlzZXMgdGhhdCB2YWx1ZSxcbiAqIGJ1dCBvdGhlcndpc2UgcmVqZWN0cy5cbiAqIEBwYXJhbSB4IHtBbnkqfVxuICogQHBhcmFtIHkge0FueSp9XG4gKiBAcmV0dXJucyB7QW55Kn0gYSBwcm9taXNlIGZvciB4IGFuZCB5IGlmIHRoZXkgYXJlIHRoZSBzYW1lLCBidXQgYSByZWplY3Rpb25cbiAqIG90aGVyd2lzZS5cbiAqXG4gKi9cblEuam9pbiA9IGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgcmV0dXJuIFEoeCkuam9pbih5KTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmpvaW4gPSBmdW5jdGlvbiAodGhhdCkge1xuICAgIHJldHVybiBRKFt0aGlzLCB0aGF0XSkuc3ByZWFkKGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgICAgIGlmICh4ID09PSB5KSB7XG4gICAgICAgICAgICAvLyBUT0RPOiBcIj09PVwiIHNob3VsZCBiZSBPYmplY3QuaXMgb3IgZXF1aXZcbiAgICAgICAgICAgIHJldHVybiB4O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FuJ3Qgam9pbjogbm90IHRoZSBzYW1lOiBcIiArIHggKyBcIiBcIiArIHkpO1xuICAgICAgICB9XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgZmlyc3Qgb2YgYW4gYXJyYXkgb2YgcHJvbWlzZXMgdG8gYmVjb21lIHNldHRsZWQuXG4gKiBAcGFyYW0gYW5zd2VycyB7QXJyYXlbQW55Kl19IHByb21pc2VzIHRvIHJhY2VcbiAqIEByZXR1cm5zIHtBbnkqfSB0aGUgZmlyc3QgcHJvbWlzZSB0byBiZSBzZXR0bGVkXG4gKi9cblEucmFjZSA9IHJhY2U7XG5mdW5jdGlvbiByYWNlKGFuc3dlclBzKSB7XG4gICAgcmV0dXJuIHByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAvLyBTd2l0Y2ggdG8gdGhpcyBvbmNlIHdlIGNhbiBhc3N1bWUgYXQgbGVhc3QgRVM1XG4gICAgICAgIC8vIGFuc3dlclBzLmZvckVhY2goZnVuY3Rpb24gKGFuc3dlclApIHtcbiAgICAgICAgLy8gICAgIFEoYW5zd2VyUCkudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAvLyB9KTtcbiAgICAgICAgLy8gVXNlIHRoaXMgaW4gdGhlIG1lYW50aW1lXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBhbnN3ZXJQcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgUShhbnN3ZXJQc1tpXSkudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5cblByb21pc2UucHJvdG90eXBlLnJhY2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbihRLnJhY2UpO1xufTtcblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgUHJvbWlzZSB3aXRoIGEgcHJvbWlzZSBkZXNjcmlwdG9yIG9iamVjdCBhbmQgb3B0aW9uYWwgZmFsbGJhY2tcbiAqIGZ1bmN0aW9uLiAgVGhlIGRlc2NyaXB0b3IgY29udGFpbnMgbWV0aG9kcyBsaWtlIHdoZW4ocmVqZWN0ZWQpLCBnZXQobmFtZSksXG4gKiBzZXQobmFtZSwgdmFsdWUpLCBwb3N0KG5hbWUsIGFyZ3MpLCBhbmQgZGVsZXRlKG5hbWUpLCB3aGljaCBhbGxcbiAqIHJldHVybiBlaXRoZXIgYSB2YWx1ZSwgYSBwcm9taXNlIGZvciBhIHZhbHVlLCBvciBhIHJlamVjdGlvbi4gIFRoZSBmYWxsYmFja1xuICogYWNjZXB0cyB0aGUgb3BlcmF0aW9uIG5hbWUsIGEgcmVzb2x2ZXIsIGFuZCBhbnkgZnVydGhlciBhcmd1bWVudHMgdGhhdCB3b3VsZFxuICogaGF2ZSBiZWVuIGZvcndhcmRlZCB0byB0aGUgYXBwcm9wcmlhdGUgbWV0aG9kIGFib3ZlIGhhZCBhIG1ldGhvZCBiZWVuXG4gKiBwcm92aWRlZCB3aXRoIHRoZSBwcm9wZXIgbmFtZS4gIFRoZSBBUEkgbWFrZXMgbm8gZ3VhcmFudGVlcyBhYm91dCB0aGUgbmF0dXJlXG4gKiBvZiB0aGUgcmV0dXJuZWQgb2JqZWN0LCBhcGFydCBmcm9tIHRoYXQgaXQgaXMgdXNhYmxlIHdoZXJlZXZlciBwcm9taXNlcyBhcmVcbiAqIGJvdWdodCBhbmQgc29sZC5cbiAqL1xuUS5tYWtlUHJvbWlzZSA9IFByb21pc2U7XG5mdW5jdGlvbiBQcm9taXNlKGRlc2NyaXB0b3IsIGZhbGxiYWNrLCBpbnNwZWN0KSB7XG4gICAgaWYgKGZhbGxiYWNrID09PSB2b2lkIDApIHtcbiAgICAgICAgZmFsbGJhY2sgPSBmdW5jdGlvbiAob3ApIHtcbiAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKFxuICAgICAgICAgICAgICAgIFwiUHJvbWlzZSBkb2VzIG5vdCBzdXBwb3J0IG9wZXJhdGlvbjogXCIgKyBvcFxuICAgICAgICAgICAgKSk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIGlmIChpbnNwZWN0ID09PSB2b2lkIDApIHtcbiAgICAgICAgaW5zcGVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB7c3RhdGU6IFwidW5rbm93blwifTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICB2YXIgcHJvbWlzZSA9IG9iamVjdF9jcmVhdGUoUHJvbWlzZS5wcm90b3R5cGUpO1xuXG4gICAgcHJvbWlzZS5wcm9taXNlRGlzcGF0Y2ggPSBmdW5jdGlvbiAocmVzb2x2ZSwgb3AsIGFyZ3MpIHtcbiAgICAgICAgdmFyIHJlc3VsdDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmIChkZXNjcmlwdG9yW29wXSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGRlc2NyaXB0b3Jbb3BdLmFwcGx5KHByb21pc2UsIGFyZ3MpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBmYWxsYmFjay5jYWxsKHByb21pc2UsIG9wLCBhcmdzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICByZXN1bHQgPSByZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVzb2x2ZSkge1xuICAgICAgICAgICAgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHByb21pc2UuaW5zcGVjdCA9IGluc3BlY3Q7XG5cbiAgICAvLyBYWFggZGVwcmVjYXRlZCBgdmFsdWVPZmAgYW5kIGBleGNlcHRpb25gIHN1cHBvcnRcbiAgICBpZiAoaW5zcGVjdCkge1xuICAgICAgICB2YXIgaW5zcGVjdGVkID0gaW5zcGVjdCgpO1xuICAgICAgICBpZiAoaW5zcGVjdGVkLnN0YXRlID09PSBcInJlamVjdGVkXCIpIHtcbiAgICAgICAgICAgIHByb21pc2UuZXhjZXB0aW9uID0gaW5zcGVjdGVkLnJlYXNvbjtcbiAgICAgICAgfVxuXG4gICAgICAgIHByb21pc2UudmFsdWVPZiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBpbnNwZWN0ZWQgPSBpbnNwZWN0KCk7XG4gICAgICAgICAgICBpZiAoaW5zcGVjdGVkLnN0YXRlID09PSBcInBlbmRpbmdcIiB8fFxuICAgICAgICAgICAgICAgIGluc3BlY3RlZC5zdGF0ZSA9PT0gXCJyZWplY3RlZFwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gaW5zcGVjdGVkLnZhbHVlO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiBwcm9taXNlO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gXCJbb2JqZWN0IFByb21pc2VdXCI7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50aGVuID0gZnVuY3Rpb24gKGZ1bGZpbGxlZCwgcmVqZWN0ZWQsIHByb2dyZXNzZWQpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB2YXIgZG9uZSA9IGZhbHNlOyAgIC8vIGVuc3VyZSB0aGUgdW50cnVzdGVkIHByb21pc2UgbWFrZXMgYXQgbW9zdCBhXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBzaW5nbGUgY2FsbCB0byBvbmUgb2YgdGhlIGNhbGxiYWNrc1xuXG4gICAgZnVuY3Rpb24gX2Z1bGZpbGxlZCh2YWx1ZSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiBmdWxmaWxsZWQgPT09IFwiZnVuY3Rpb25cIiA/IGZ1bGZpbGxlZCh2YWx1ZSkgOiB2YWx1ZTtcbiAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVqZWN0KGV4Y2VwdGlvbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfcmVqZWN0ZWQoZXhjZXB0aW9uKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcmVqZWN0ZWQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgbWFrZVN0YWNrVHJhY2VMb25nKGV4Y2VwdGlvbiwgc2VsZik7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3RlZChleGNlcHRpb24pO1xuICAgICAgICAgICAgfSBjYXRjaCAobmV3RXhjZXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXdFeGNlcHRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZWplY3QoZXhjZXB0aW9uKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfcHJvZ3Jlc3NlZCh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdHlwZW9mIHByb2dyZXNzZWQgPT09IFwiZnVuY3Rpb25cIiA/IHByb2dyZXNzZWQodmFsdWUpIDogdmFsdWU7XG4gICAgfVxuXG4gICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlbGYucHJvbWlzZURpc3BhdGNoKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkb25lID0gdHJ1ZTtcblxuICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZShfZnVsZmlsbGVkKHZhbHVlKSk7XG4gICAgICAgIH0sIFwid2hlblwiLCBbZnVuY3Rpb24gKGV4Y2VwdGlvbikge1xuICAgICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkb25lID0gdHJ1ZTtcblxuICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZShfcmVqZWN0ZWQoZXhjZXB0aW9uKSk7XG4gICAgICAgIH1dKTtcbiAgICB9KTtcblxuICAgIC8vIFByb2dyZXNzIHByb3BhZ2F0b3IgbmVlZCB0byBiZSBhdHRhY2hlZCBpbiB0aGUgY3VycmVudCB0aWNrLlxuICAgIHNlbGYucHJvbWlzZURpc3BhdGNoKHZvaWQgMCwgXCJ3aGVuXCIsIFt2b2lkIDAsIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgbmV3VmFsdWU7XG4gICAgICAgIHZhciB0aHJldyA9IGZhbHNlO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbmV3VmFsdWUgPSBfcHJvZ3Jlc3NlZCh2YWx1ZSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHRocmV3ID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChRLm9uZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBRLm9uZXJyb3IoZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRocmV3KSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5ub3RpZnkobmV3VmFsdWUpO1xuICAgICAgICB9XG4gICAgfV0pO1xuXG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG5RLnRhcCA9IGZ1bmN0aW9uIChwcm9taXNlLCBjYWxsYmFjaykge1xuICAgIHJldHVybiBRKHByb21pc2UpLnRhcChjYWxsYmFjayk7XG59O1xuXG4vKipcbiAqIFdvcmtzIGFsbW9zdCBsaWtlIFwiZmluYWxseVwiLCBidXQgbm90IGNhbGxlZCBmb3IgcmVqZWN0aW9ucy5cbiAqIE9yaWdpbmFsIHJlc29sdXRpb24gdmFsdWUgaXMgcGFzc2VkIHRocm91Z2ggY2FsbGJhY2sgdW5hZmZlY3RlZC5cbiAqIENhbGxiYWNrIG1heSByZXR1cm4gYSBwcm9taXNlIHRoYXQgd2lsbCBiZSBhd2FpdGVkIGZvci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gKiBAcmV0dXJucyB7US5Qcm9taXNlfVxuICogQGV4YW1wbGVcbiAqIGRvU29tZXRoaW5nKClcbiAqICAgLnRoZW4oLi4uKVxuICogICAudGFwKGNvbnNvbGUubG9nKVxuICogICAudGhlbiguLi4pO1xuICovXG5Qcm9taXNlLnByb3RvdHlwZS50YXAgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjayA9IFEoY2FsbGJhY2spO1xuXG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmZjYWxsKHZhbHVlKS50aGVuUmVzb2x2ZSh2YWx1ZSk7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhbiBvYnNlcnZlciBvbiBhIHByb21pc2UuXG4gKlxuICogR3VhcmFudGVlczpcbiAqXG4gKiAxLiB0aGF0IGZ1bGZpbGxlZCBhbmQgcmVqZWN0ZWQgd2lsbCBiZSBjYWxsZWQgb25seSBvbmNlLlxuICogMi4gdGhhdCBlaXRoZXIgdGhlIGZ1bGZpbGxlZCBjYWxsYmFjayBvciB0aGUgcmVqZWN0ZWQgY2FsbGJhY2sgd2lsbCBiZVxuICogICAgY2FsbGVkLCBidXQgbm90IGJvdGguXG4gKiAzLiB0aGF0IGZ1bGZpbGxlZCBhbmQgcmVqZWN0ZWQgd2lsbCBub3QgYmUgY2FsbGVkIGluIHRoaXMgdHVybi5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgICAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgdG8gb2JzZXJ2ZVxuICogQHBhcmFtIGZ1bGZpbGxlZCAgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdpdGggdGhlIGZ1bGZpbGxlZCB2YWx1ZVxuICogQHBhcmFtIHJlamVjdGVkICAgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdpdGggdGhlIHJlamVjdGlvbiBleGNlcHRpb25cbiAqIEBwYXJhbSBwcm9ncmVzc2VkIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCBvbiBhbnkgcHJvZ3Jlc3Mgbm90aWZpY2F0aW9uc1xuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlIGZyb20gdGhlIGludm9rZWQgY2FsbGJhY2tcbiAqL1xuUS53aGVuID0gd2hlbjtcbmZ1bmN0aW9uIHdoZW4odmFsdWUsIGZ1bGZpbGxlZCwgcmVqZWN0ZWQsIHByb2dyZXNzZWQpIHtcbiAgICByZXR1cm4gUSh2YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzc2VkKTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUudGhlblJlc29sdmUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHZhbHVlOyB9KTtcbn07XG5cblEudGhlblJlc29sdmUgPSBmdW5jdGlvbiAocHJvbWlzZSwgdmFsdWUpIHtcbiAgICByZXR1cm4gUShwcm9taXNlKS50aGVuUmVzb2x2ZSh2YWx1ZSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50aGVuUmVqZWN0ID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICAgIHJldHVybiB0aGlzLnRoZW4oZnVuY3Rpb24gKCkgeyB0aHJvdyByZWFzb247IH0pO1xufTtcblxuUS50aGVuUmVqZWN0ID0gZnVuY3Rpb24gKHByb21pc2UsIHJlYXNvbikge1xuICAgIHJldHVybiBRKHByb21pc2UpLnRoZW5SZWplY3QocmVhc29uKTtcbn07XG5cbi8qKlxuICogSWYgYW4gb2JqZWN0IGlzIG5vdCBhIHByb21pc2UsIGl0IGlzIGFzIFwibmVhclwiIGFzIHBvc3NpYmxlLlxuICogSWYgYSBwcm9taXNlIGlzIHJlamVjdGVkLCBpdCBpcyBhcyBcIm5lYXJcIiBhcyBwb3NzaWJsZSB0b28uXG4gKiBJZiBpdOKAmXMgYSBmdWxmaWxsZWQgcHJvbWlzZSwgdGhlIGZ1bGZpbGxtZW50IHZhbHVlIGlzIG5lYXJlci5cbiAqIElmIGl04oCZcyBhIGRlZmVycmVkIHByb21pc2UgYW5kIHRoZSBkZWZlcnJlZCBoYXMgYmVlbiByZXNvbHZlZCwgdGhlXG4gKiByZXNvbHV0aW9uIGlzIFwibmVhcmVyXCIuXG4gKiBAcGFyYW0gb2JqZWN0XG4gKiBAcmV0dXJucyBtb3N0IHJlc29sdmVkIChuZWFyZXN0KSBmb3JtIG9mIHRoZSBvYmplY3RcbiAqL1xuXG4vLyBYWFggc2hvdWxkIHdlIHJlLWRvIHRoaXM/XG5RLm5lYXJlciA9IG5lYXJlcjtcbmZ1bmN0aW9uIG5lYXJlcih2YWx1ZSkge1xuICAgIGlmIChpc1Byb21pc2UodmFsdWUpKSB7XG4gICAgICAgIHZhciBpbnNwZWN0ZWQgPSB2YWx1ZS5pbnNwZWN0KCk7XG4gICAgICAgIGlmIChpbnNwZWN0ZWQuc3RhdGUgPT09IFwiZnVsZmlsbGVkXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBpbnNwZWN0ZWQudmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xufVxuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHByb21pc2UuXG4gKiBPdGhlcndpc2UgaXQgaXMgYSBmdWxmaWxsZWQgdmFsdWUuXG4gKi9cblEuaXNQcm9taXNlID0gaXNQcm9taXNlO1xuZnVuY3Rpb24gaXNQcm9taXNlKG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgaW5zdGFuY2VvZiBQcm9taXNlO1xufVxuXG5RLmlzUHJvbWlzZUFsaWtlID0gaXNQcm9taXNlQWxpa2U7XG5mdW5jdGlvbiBpc1Byb21pc2VBbGlrZShvYmplY3QpIHtcbiAgICByZXR1cm4gaXNPYmplY3Qob2JqZWN0KSAmJiB0eXBlb2Ygb2JqZWN0LnRoZW4gPT09IFwiZnVuY3Rpb25cIjtcbn1cblxuLyoqXG4gKiBAcmV0dXJucyB3aGV0aGVyIHRoZSBnaXZlbiBvYmplY3QgaXMgYSBwZW5kaW5nIHByb21pc2UsIG1lYW5pbmcgbm90XG4gKiBmdWxmaWxsZWQgb3IgcmVqZWN0ZWQuXG4gKi9cblEuaXNQZW5kaW5nID0gaXNQZW5kaW5nO1xuZnVuY3Rpb24gaXNQZW5kaW5nKG9iamVjdCkge1xuICAgIHJldHVybiBpc1Byb21pc2Uob2JqZWN0KSAmJiBvYmplY3QuaW5zcGVjdCgpLnN0YXRlID09PSBcInBlbmRpbmdcIjtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuaXNQZW5kaW5nID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmluc3BlY3QoKS5zdGF0ZSA9PT0gXCJwZW5kaW5nXCI7XG59O1xuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHZhbHVlIG9yIGZ1bGZpbGxlZFxuICogcHJvbWlzZS5cbiAqL1xuUS5pc0Z1bGZpbGxlZCA9IGlzRnVsZmlsbGVkO1xuZnVuY3Rpb24gaXNGdWxmaWxsZWQob2JqZWN0KSB7XG4gICAgcmV0dXJuICFpc1Byb21pc2Uob2JqZWN0KSB8fCBvYmplY3QuaW5zcGVjdCgpLnN0YXRlID09PSBcImZ1bGZpbGxlZFwiO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5pc0Z1bGZpbGxlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5pbnNwZWN0KCkuc3RhdGUgPT09IFwiZnVsZmlsbGVkXCI7XG59O1xuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHJlamVjdGVkIHByb21pc2UuXG4gKi9cblEuaXNSZWplY3RlZCA9IGlzUmVqZWN0ZWQ7XG5mdW5jdGlvbiBpc1JlamVjdGVkKG9iamVjdCkge1xuICAgIHJldHVybiBpc1Byb21pc2Uob2JqZWN0KSAmJiBvYmplY3QuaW5zcGVjdCgpLnN0YXRlID09PSBcInJlamVjdGVkXCI7XG59XG5cblByb21pc2UucHJvdG90eXBlLmlzUmVqZWN0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuaW5zcGVjdCgpLnN0YXRlID09PSBcInJlamVjdGVkXCI7XG59O1xuXG4vLy8vIEJFR0lOIFVOSEFORExFRCBSRUpFQ1RJT04gVFJBQ0tJTkdcblxuLy8gVGhpcyBwcm9taXNlIGxpYnJhcnkgY29uc3VtZXMgZXhjZXB0aW9ucyB0aHJvd24gaW4gaGFuZGxlcnMgc28gdGhleSBjYW4gYmVcbi8vIGhhbmRsZWQgYnkgYSBzdWJzZXF1ZW50IHByb21pc2UuICBUaGUgZXhjZXB0aW9ucyBnZXQgYWRkZWQgdG8gdGhpcyBhcnJheSB3aGVuXG4vLyB0aGV5IGFyZSBjcmVhdGVkLCBhbmQgcmVtb3ZlZCB3aGVuIHRoZXkgYXJlIGhhbmRsZWQuICBOb3RlIHRoYXQgaW4gRVM2IG9yXG4vLyBzaGltbWVkIGVudmlyb25tZW50cywgdGhpcyB3b3VsZCBuYXR1cmFsbHkgYmUgYSBgU2V0YC5cbnZhciB1bmhhbmRsZWRSZWFzb25zID0gW107XG52YXIgdW5oYW5kbGVkUmVqZWN0aW9ucyA9IFtdO1xudmFyIHJlcG9ydGVkVW5oYW5kbGVkUmVqZWN0aW9ucyA9IFtdO1xudmFyIHRyYWNrVW5oYW5kbGVkUmVqZWN0aW9ucyA9IHRydWU7XG5cbmZ1bmN0aW9uIHJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucygpIHtcbiAgICB1bmhhbmRsZWRSZWFzb25zLmxlbmd0aCA9IDA7XG4gICAgdW5oYW5kbGVkUmVqZWN0aW9ucy5sZW5ndGggPSAwO1xuXG4gICAgaWYgKCF0cmFja1VuaGFuZGxlZFJlamVjdGlvbnMpIHtcbiAgICAgICAgdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zID0gdHJ1ZTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHRyYWNrUmVqZWN0aW9uKHByb21pc2UsIHJlYXNvbikge1xuICAgIGlmICghdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBwcm9jZXNzLmVtaXQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBRLm5leHRUaWNrLnJ1bkFmdGVyKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChhcnJheV9pbmRleE9mKHVuaGFuZGxlZFJlamVjdGlvbnMsIHByb21pc2UpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIHByb2Nlc3MuZW1pdChcInVuaGFuZGxlZFJlamVjdGlvblwiLCByZWFzb24sIHByb21pc2UpO1xuICAgICAgICAgICAgICAgIHJlcG9ydGVkVW5oYW5kbGVkUmVqZWN0aW9ucy5wdXNoKHByb21pc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICB1bmhhbmRsZWRSZWplY3Rpb25zLnB1c2gocHJvbWlzZSk7XG4gICAgaWYgKHJlYXNvbiAmJiB0eXBlb2YgcmVhc29uLnN0YWNrICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIHVuaGFuZGxlZFJlYXNvbnMucHVzaChyZWFzb24uc3RhY2spO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHVuaGFuZGxlZFJlYXNvbnMucHVzaChcIihubyBzdGFjaykgXCIgKyByZWFzb24pO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gdW50cmFja1JlamVjdGlvbihwcm9taXNlKSB7XG4gICAgaWYgKCF0cmFja1VuaGFuZGxlZFJlamVjdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBhdCA9IGFycmF5X2luZGV4T2YodW5oYW5kbGVkUmVqZWN0aW9ucywgcHJvbWlzZSk7XG4gICAgaWYgKGF0ICE9PSAtMSkge1xuICAgICAgICBpZiAodHlwZW9mIHByb2Nlc3MgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHByb2Nlc3MuZW1pdCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICBRLm5leHRUaWNrLnJ1bkFmdGVyKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgYXRSZXBvcnQgPSBhcnJheV9pbmRleE9mKHJlcG9ydGVkVW5oYW5kbGVkUmVqZWN0aW9ucywgcHJvbWlzZSk7XG4gICAgICAgICAgICAgICAgaWYgKGF0UmVwb3J0ICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICBwcm9jZXNzLmVtaXQoXCJyZWplY3Rpb25IYW5kbGVkXCIsIHVuaGFuZGxlZFJlYXNvbnNbYXRdLCBwcm9taXNlKTtcbiAgICAgICAgICAgICAgICAgICAgcmVwb3J0ZWRVbmhhbmRsZWRSZWplY3Rpb25zLnNwbGljZShhdFJlcG9ydCwgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdW5oYW5kbGVkUmVqZWN0aW9ucy5zcGxpY2UoYXQsIDEpO1xuICAgICAgICB1bmhhbmRsZWRSZWFzb25zLnNwbGljZShhdCwgMSk7XG4gICAgfVxufVxuXG5RLnJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucyA9IHJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucztcblxuUS5nZXRVbmhhbmRsZWRSZWFzb25zID0gZnVuY3Rpb24gKCkge1xuICAgIC8vIE1ha2UgYSBjb3B5IHNvIHRoYXQgY29uc3VtZXJzIGNhbid0IGludGVyZmVyZSB3aXRoIG91ciBpbnRlcm5hbCBzdGF0ZS5cbiAgICByZXR1cm4gdW5oYW5kbGVkUmVhc29ucy5zbGljZSgpO1xufTtcblxuUS5zdG9wVW5oYW5kbGVkUmVqZWN0aW9uVHJhY2tpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmVzZXRVbmhhbmRsZWRSZWplY3Rpb25zKCk7XG4gICAgdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zID0gZmFsc2U7XG59O1xuXG5yZXNldFVuaGFuZGxlZFJlamVjdGlvbnMoKTtcblxuLy8vLyBFTkQgVU5IQU5ETEVEIFJFSkVDVElPTiBUUkFDS0lOR1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSByZWplY3RlZCBwcm9taXNlLlxuICogQHBhcmFtIHJlYXNvbiB2YWx1ZSBkZXNjcmliaW5nIHRoZSBmYWlsdXJlXG4gKi9cblEucmVqZWN0ID0gcmVqZWN0O1xuZnVuY3Rpb24gcmVqZWN0KHJlYXNvbikge1xuICAgIHZhciByZWplY3Rpb24gPSBQcm9taXNlKHtcbiAgICAgICAgXCJ3aGVuXCI6IGZ1bmN0aW9uIChyZWplY3RlZCkge1xuICAgICAgICAgICAgLy8gbm90ZSB0aGF0IHRoZSBlcnJvciBoYXMgYmVlbiBoYW5kbGVkXG4gICAgICAgICAgICBpZiAocmVqZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICB1bnRyYWNrUmVqZWN0aW9uKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlamVjdGVkID8gcmVqZWN0ZWQocmVhc29uKSA6IHRoaXM7XG4gICAgICAgIH1cbiAgICB9LCBmdW5jdGlvbiBmYWxsYmFjaygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSwgZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgICAgICAgcmV0dXJuIHsgc3RhdGU6IFwicmVqZWN0ZWRcIiwgcmVhc29uOiByZWFzb24gfTtcbiAgICB9KTtcblxuICAgIC8vIE5vdGUgdGhhdCB0aGUgcmVhc29uIGhhcyBub3QgYmVlbiBoYW5kbGVkLlxuICAgIHRyYWNrUmVqZWN0aW9uKHJlamVjdGlvbiwgcmVhc29uKTtcblxuICAgIHJldHVybiByZWplY3Rpb247XG59XG5cbi8qKlxuICogQ29uc3RydWN0cyBhIGZ1bGZpbGxlZCBwcm9taXNlIGZvciBhbiBpbW1lZGlhdGUgcmVmZXJlbmNlLlxuICogQHBhcmFtIHZhbHVlIGltbWVkaWF0ZSByZWZlcmVuY2VcbiAqL1xuUS5mdWxmaWxsID0gZnVsZmlsbDtcbmZ1bmN0aW9uIGZ1bGZpbGwodmFsdWUpIHtcbiAgICByZXR1cm4gUHJvbWlzZSh7XG4gICAgICAgIFwid2hlblwiOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH0sXG4gICAgICAgIFwiZ2V0XCI6IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWVbbmFtZV07XG4gICAgICAgIH0sXG4gICAgICAgIFwic2V0XCI6IGZ1bmN0aW9uIChuYW1lLCByaHMpIHtcbiAgICAgICAgICAgIHZhbHVlW25hbWVdID0gcmhzO1xuICAgICAgICB9LFxuICAgICAgICBcImRlbGV0ZVwiOiBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICAgICAgZGVsZXRlIHZhbHVlW25hbWVdO1xuICAgICAgICB9LFxuICAgICAgICBcInBvc3RcIjogZnVuY3Rpb24gKG5hbWUsIGFyZ3MpIHtcbiAgICAgICAgICAgIC8vIE1hcmsgTWlsbGVyIHByb3Bvc2VzIHRoYXQgcG9zdCB3aXRoIG5vIG5hbWUgc2hvdWxkIGFwcGx5IGFcbiAgICAgICAgICAgIC8vIHByb21pc2VkIGZ1bmN0aW9uLlxuICAgICAgICAgICAgaWYgKG5hbWUgPT09IG51bGwgfHwgbmFtZSA9PT0gdm9pZCAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLmFwcGx5KHZvaWQgMCwgYXJncyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZVtuYW1lXS5hcHBseSh2YWx1ZSwgYXJncyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIFwiYXBwbHlcIjogZnVuY3Rpb24gKHRoaXNwLCBhcmdzKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWUuYXBwbHkodGhpc3AsIGFyZ3MpO1xuICAgICAgICB9LFxuICAgICAgICBcImtleXNcIjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIG9iamVjdF9rZXlzKHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH0sIHZvaWQgMCwgZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgICAgICAgcmV0dXJuIHsgc3RhdGU6IFwiZnVsZmlsbGVkXCIsIHZhbHVlOiB2YWx1ZSB9O1xuICAgIH0pO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIHRoZW5hYmxlcyB0byBRIHByb21pc2VzLlxuICogQHBhcmFtIHByb21pc2UgdGhlbmFibGUgcHJvbWlzZVxuICogQHJldHVybnMgYSBRIHByb21pc2VcbiAqL1xuZnVuY3Rpb24gY29lcmNlKHByb21pc2UpIHtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcHJvbWlzZS50aGVuKGRlZmVycmVkLnJlc29sdmUsIGRlZmVycmVkLnJlamVjdCwgZGVmZXJyZWQubm90aWZ5KTtcbiAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufVxuXG4vKipcbiAqIEFubm90YXRlcyBhbiBvYmplY3Qgc3VjaCB0aGF0IGl0IHdpbGwgbmV2ZXIgYmVcbiAqIHRyYW5zZmVycmVkIGF3YXkgZnJvbSB0aGlzIHByb2Nlc3Mgb3ZlciBhbnkgcHJvbWlzZVxuICogY29tbXVuaWNhdGlvbiBjaGFubmVsLlxuICogQHBhcmFtIG9iamVjdFxuICogQHJldHVybnMgcHJvbWlzZSBhIHdyYXBwaW5nIG9mIHRoYXQgb2JqZWN0IHRoYXRcbiAqIGFkZGl0aW9uYWxseSByZXNwb25kcyB0byB0aGUgXCJpc0RlZlwiIG1lc3NhZ2VcbiAqIHdpdGhvdXQgYSByZWplY3Rpb24uXG4gKi9cblEubWFzdGVyID0gbWFzdGVyO1xuZnVuY3Rpb24gbWFzdGVyKG9iamVjdCkge1xuICAgIHJldHVybiBQcm9taXNlKHtcbiAgICAgICAgXCJpc0RlZlwiOiBmdW5jdGlvbiAoKSB7fVxuICAgIH0sIGZ1bmN0aW9uIGZhbGxiYWNrKG9wLCBhcmdzKSB7XG4gICAgICAgIHJldHVybiBkaXNwYXRjaChvYmplY3QsIG9wLCBhcmdzKTtcbiAgICB9LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBRKG9iamVjdCkuaW5zcGVjdCgpO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIFNwcmVhZHMgdGhlIHZhbHVlcyBvZiBhIHByb21pc2VkIGFycmF5IG9mIGFyZ3VtZW50cyBpbnRvIHRoZVxuICogZnVsZmlsbG1lbnQgY2FsbGJhY2suXG4gKiBAcGFyYW0gZnVsZmlsbGVkIGNhbGxiYWNrIHRoYXQgcmVjZWl2ZXMgdmFyaWFkaWMgYXJndW1lbnRzIGZyb20gdGhlXG4gKiBwcm9taXNlZCBhcnJheVxuICogQHBhcmFtIHJlamVjdGVkIGNhbGxiYWNrIHRoYXQgcmVjZWl2ZXMgdGhlIGV4Y2VwdGlvbiBpZiB0aGUgcHJvbWlzZVxuICogaXMgcmVqZWN0ZWQuXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWUgb3IgdGhyb3duIGV4Y2VwdGlvbiBvZlxuICogZWl0aGVyIGNhbGxiYWNrLlxuICovXG5RLnNwcmVhZCA9IHNwcmVhZDtcbmZ1bmN0aW9uIHNwcmVhZCh2YWx1ZSwgZnVsZmlsbGVkLCByZWplY3RlZCkge1xuICAgIHJldHVybiBRKHZhbHVlKS5zcHJlYWQoZnVsZmlsbGVkLCByZWplY3RlZCk7XG59XG5cblByb21pc2UucHJvdG90eXBlLnNwcmVhZCA9IGZ1bmN0aW9uIChmdWxmaWxsZWQsIHJlamVjdGVkKSB7XG4gICAgcmV0dXJuIHRoaXMuYWxsKCkudGhlbihmdW5jdGlvbiAoYXJyYXkpIHtcbiAgICAgICAgcmV0dXJuIGZ1bGZpbGxlZC5hcHBseSh2b2lkIDAsIGFycmF5KTtcbiAgICB9LCByZWplY3RlZCk7XG59O1xuXG4vKipcbiAqIFRoZSBhc3luYyBmdW5jdGlvbiBpcyBhIGRlY29yYXRvciBmb3IgZ2VuZXJhdG9yIGZ1bmN0aW9ucywgdHVybmluZ1xuICogdGhlbSBpbnRvIGFzeW5jaHJvbm91cyBnZW5lcmF0b3JzLiAgQWx0aG91Z2ggZ2VuZXJhdG9ycyBhcmUgb25seSBwYXJ0XG4gKiBvZiB0aGUgbmV3ZXN0IEVDTUFTY3JpcHQgNiBkcmFmdHMsIHRoaXMgY29kZSBkb2VzIG5vdCBjYXVzZSBzeW50YXhcbiAqIGVycm9ycyBpbiBvbGRlciBlbmdpbmVzLiAgVGhpcyBjb2RlIHNob3VsZCBjb250aW51ZSB0byB3b3JrIGFuZCB3aWxsXG4gKiBpbiBmYWN0IGltcHJvdmUgb3ZlciB0aW1lIGFzIHRoZSBsYW5ndWFnZSBpbXByb3Zlcy5cbiAqXG4gKiBFUzYgZ2VuZXJhdG9ycyBhcmUgY3VycmVudGx5IHBhcnQgb2YgVjggdmVyc2lvbiAzLjE5IHdpdGggdGhlXG4gKiAtLWhhcm1vbnktZ2VuZXJhdG9ycyBydW50aW1lIGZsYWcgZW5hYmxlZC4gIFNwaWRlck1vbmtleSBoYXMgaGFkIHRoZW1cbiAqIGZvciBsb25nZXIsIGJ1dCB1bmRlciBhbiBvbGRlciBQeXRob24taW5zcGlyZWQgZm9ybS4gIFRoaXMgZnVuY3Rpb25cbiAqIHdvcmtzIG9uIGJvdGgga2luZHMgb2YgZ2VuZXJhdG9ycy5cbiAqXG4gKiBEZWNvcmF0ZXMgYSBnZW5lcmF0b3IgZnVuY3Rpb24gc3VjaCB0aGF0OlxuICogIC0gaXQgbWF5IHlpZWxkIHByb21pc2VzXG4gKiAgLSBleGVjdXRpb24gd2lsbCBjb250aW51ZSB3aGVuIHRoYXQgcHJvbWlzZSBpcyBmdWxmaWxsZWRcbiAqICAtIHRoZSB2YWx1ZSBvZiB0aGUgeWllbGQgZXhwcmVzc2lvbiB3aWxsIGJlIHRoZSBmdWxmaWxsZWQgdmFsdWVcbiAqICAtIGl0IHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlICh3aGVuIHRoZSBnZW5lcmF0b3JcbiAqICAgIHN0b3BzIGl0ZXJhdGluZylcbiAqICAtIHRoZSBkZWNvcmF0ZWQgZnVuY3Rpb24gcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqICAgIG9mIHRoZSBnZW5lcmF0b3Igb3IgdGhlIGZpcnN0IHJlamVjdGVkIHByb21pc2UgYW1vbmcgdGhvc2VcbiAqICAgIHlpZWxkZWQuXG4gKiAgLSBpZiBhbiBlcnJvciBpcyB0aHJvd24gaW4gdGhlIGdlbmVyYXRvciwgaXQgcHJvcGFnYXRlcyB0aHJvdWdoXG4gKiAgICBldmVyeSBmb2xsb3dpbmcgeWllbGQgdW50aWwgaXQgaXMgY2F1Z2h0LCBvciB1bnRpbCBpdCBlc2NhcGVzXG4gKiAgICB0aGUgZ2VuZXJhdG9yIGZ1bmN0aW9uIGFsdG9nZXRoZXIsIGFuZCBpcyB0cmFuc2xhdGVkIGludG8gYVxuICogICAgcmVqZWN0aW9uIGZvciB0aGUgcHJvbWlzZSByZXR1cm5lZCBieSB0aGUgZGVjb3JhdGVkIGdlbmVyYXRvci5cbiAqL1xuUS5hc3luYyA9IGFzeW5jO1xuZnVuY3Rpb24gYXN5bmMobWFrZUdlbmVyYXRvcikge1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIHdoZW4gdmVyYiBpcyBcInNlbmRcIiwgYXJnIGlzIGEgdmFsdWVcbiAgICAgICAgLy8gd2hlbiB2ZXJiIGlzIFwidGhyb3dcIiwgYXJnIGlzIGFuIGV4Y2VwdGlvblxuICAgICAgICBmdW5jdGlvbiBjb250aW51ZXIodmVyYiwgYXJnKSB7XG4gICAgICAgICAgICB2YXIgcmVzdWx0O1xuXG4gICAgICAgICAgICAvLyBVbnRpbCBWOCAzLjE5IC8gQ2hyb21pdW0gMjkgaXMgcmVsZWFzZWQsIFNwaWRlck1vbmtleSBpcyB0aGUgb25seVxuICAgICAgICAgICAgLy8gZW5naW5lIHRoYXQgaGFzIGEgZGVwbG95ZWQgYmFzZSBvZiBicm93c2VycyB0aGF0IHN1cHBvcnQgZ2VuZXJhdG9ycy5cbiAgICAgICAgICAgIC8vIEhvd2V2ZXIsIFNNJ3MgZ2VuZXJhdG9ycyB1c2UgdGhlIFB5dGhvbi1pbnNwaXJlZCBzZW1hbnRpY3Mgb2ZcbiAgICAgICAgICAgIC8vIG91dGRhdGVkIEVTNiBkcmFmdHMuICBXZSB3b3VsZCBsaWtlIHRvIHN1cHBvcnQgRVM2LCBidXQgd2UnZCBhbHNvXG4gICAgICAgICAgICAvLyBsaWtlIHRvIG1ha2UgaXQgcG9zc2libGUgdG8gdXNlIGdlbmVyYXRvcnMgaW4gZGVwbG95ZWQgYnJvd3NlcnMsIHNvXG4gICAgICAgICAgICAvLyB3ZSBhbHNvIHN1cHBvcnQgUHl0aG9uLXN0eWxlIGdlbmVyYXRvcnMuICBBdCBzb21lIHBvaW50IHdlIGNhbiByZW1vdmVcbiAgICAgICAgICAgIC8vIHRoaXMgYmxvY2suXG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgU3RvcEl0ZXJhdGlvbiA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgICAgIC8vIEVTNiBHZW5lcmF0b3JzXG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gZ2VuZXJhdG9yW3ZlcmJdKGFyZyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5kb25lKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBRKHJlc3VsdC52YWx1ZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHdoZW4ocmVzdWx0LnZhbHVlLCBjYWxsYmFjaywgZXJyYmFjayk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBTcGlkZXJNb25rZXkgR2VuZXJhdG9yc1xuICAgICAgICAgICAgICAgIC8vIEZJWE1FOiBSZW1vdmUgdGhpcyBjYXNlIHdoZW4gU00gZG9lcyBFUzYgZ2VuZXJhdG9ycy5cbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBnZW5lcmF0b3JbdmVyYl0oYXJnKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzU3RvcEl0ZXJhdGlvbihleGNlcHRpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUShleGNlcHRpb24udmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChleGNlcHRpb24pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB3aGVuKHJlc3VsdCwgY2FsbGJhY2ssIGVycmJhY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHZhciBnZW5lcmF0b3IgPSBtYWtlR2VuZXJhdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIHZhciBjYWxsYmFjayA9IGNvbnRpbnVlci5iaW5kKGNvbnRpbnVlciwgXCJuZXh0XCIpO1xuICAgICAgICB2YXIgZXJyYmFjayA9IGNvbnRpbnVlci5iaW5kKGNvbnRpbnVlciwgXCJ0aHJvd1wiKTtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgfTtcbn1cblxuLyoqXG4gKiBUaGUgc3Bhd24gZnVuY3Rpb24gaXMgYSBzbWFsbCB3cmFwcGVyIGFyb3VuZCBhc3luYyB0aGF0IGltbWVkaWF0ZWx5XG4gKiBjYWxscyB0aGUgZ2VuZXJhdG9yIGFuZCBhbHNvIGVuZHMgdGhlIHByb21pc2UgY2hhaW4sIHNvIHRoYXQgYW55XG4gKiB1bmhhbmRsZWQgZXJyb3JzIGFyZSB0aHJvd24gaW5zdGVhZCBvZiBmb3J3YXJkZWQgdG8gdGhlIGVycm9yXG4gKiBoYW5kbGVyLiBUaGlzIGlzIHVzZWZ1bCBiZWNhdXNlIGl0J3MgZXh0cmVtZWx5IGNvbW1vbiB0byBydW5cbiAqIGdlbmVyYXRvcnMgYXQgdGhlIHRvcC1sZXZlbCB0byB3b3JrIHdpdGggbGlicmFyaWVzLlxuICovXG5RLnNwYXduID0gc3Bhd247XG5mdW5jdGlvbiBzcGF3bihtYWtlR2VuZXJhdG9yKSB7XG4gICAgUS5kb25lKFEuYXN5bmMobWFrZUdlbmVyYXRvcikoKSk7XG59XG5cbi8vIEZJWE1FOiBSZW1vdmUgdGhpcyBpbnRlcmZhY2Ugb25jZSBFUzYgZ2VuZXJhdG9ycyBhcmUgaW4gU3BpZGVyTW9ua2V5LlxuLyoqXG4gKiBUaHJvd3MgYSBSZXR1cm5WYWx1ZSBleGNlcHRpb24gdG8gc3RvcCBhbiBhc3luY2hyb25vdXMgZ2VuZXJhdG9yLlxuICpcbiAqIFRoaXMgaW50ZXJmYWNlIGlzIGEgc3RvcC1nYXAgbWVhc3VyZSB0byBzdXBwb3J0IGdlbmVyYXRvciByZXR1cm5cbiAqIHZhbHVlcyBpbiBvbGRlciBGaXJlZm94L1NwaWRlck1vbmtleS4gIEluIGJyb3dzZXJzIHRoYXQgc3VwcG9ydCBFUzZcbiAqIGdlbmVyYXRvcnMgbGlrZSBDaHJvbWl1bSAyOSwganVzdCB1c2UgXCJyZXR1cm5cIiBpbiB5b3VyIGdlbmVyYXRvclxuICogZnVuY3Rpb25zLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSB0aGUgcmV0dXJuIHZhbHVlIGZvciB0aGUgc3Vycm91bmRpbmcgZ2VuZXJhdG9yXG4gKiBAdGhyb3dzIFJldHVyblZhbHVlIGV4Y2VwdGlvbiB3aXRoIHRoZSB2YWx1ZS5cbiAqIEBleGFtcGxlXG4gKiAvLyBFUzYgc3R5bGVcbiAqIFEuYXN5bmMoZnVuY3Rpb24qICgpIHtcbiAqICAgICAgdmFyIGZvbyA9IHlpZWxkIGdldEZvb1Byb21pc2UoKTtcbiAqICAgICAgdmFyIGJhciA9IHlpZWxkIGdldEJhclByb21pc2UoKTtcbiAqICAgICAgcmV0dXJuIGZvbyArIGJhcjtcbiAqIH0pXG4gKiAvLyBPbGRlciBTcGlkZXJNb25rZXkgc3R5bGVcbiAqIFEuYXN5bmMoZnVuY3Rpb24gKCkge1xuICogICAgICB2YXIgZm9vID0geWllbGQgZ2V0Rm9vUHJvbWlzZSgpO1xuICogICAgICB2YXIgYmFyID0geWllbGQgZ2V0QmFyUHJvbWlzZSgpO1xuICogICAgICBRLnJldHVybihmb28gKyBiYXIpO1xuICogfSlcbiAqL1xuUVtcInJldHVyblwiXSA9IF9yZXR1cm47XG5mdW5jdGlvbiBfcmV0dXJuKHZhbHVlKSB7XG4gICAgdGhyb3cgbmV3IFFSZXR1cm5WYWx1ZSh2YWx1ZSk7XG59XG5cbi8qKlxuICogVGhlIHByb21pc2VkIGZ1bmN0aW9uIGRlY29yYXRvciBlbnN1cmVzIHRoYXQgYW55IHByb21pc2UgYXJndW1lbnRzXG4gKiBhcmUgc2V0dGxlZCBhbmQgcGFzc2VkIGFzIHZhbHVlcyAoYHRoaXNgIGlzIGFsc28gc2V0dGxlZCBhbmQgcGFzc2VkXG4gKiBhcyBhIHZhbHVlKS4gIEl0IHdpbGwgYWxzbyBlbnN1cmUgdGhhdCB0aGUgcmVzdWx0IG9mIGEgZnVuY3Rpb24gaXNcbiAqIGFsd2F5cyBhIHByb21pc2UuXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBhZGQgPSBRLnByb21pc2VkKGZ1bmN0aW9uIChhLCBiKSB7XG4gKiAgICAgcmV0dXJuIGEgKyBiO1xuICogfSk7XG4gKiBhZGQoUShhKSwgUShCKSk7XG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIHRvIGRlY29yYXRlXG4gKiBAcmV0dXJucyB7ZnVuY3Rpb259IGEgZnVuY3Rpb24gdGhhdCBoYXMgYmVlbiBkZWNvcmF0ZWQuXG4gKi9cblEucHJvbWlzZWQgPSBwcm9taXNlZDtcbmZ1bmN0aW9uIHByb21pc2VkKGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHNwcmVhZChbdGhpcywgYWxsKGFyZ3VtZW50cyldLCBmdW5jdGlvbiAoc2VsZiwgYXJncykge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KHNlbGYsIGFyZ3MpO1xuICAgICAgICB9KTtcbiAgICB9O1xufVxuXG4vKipcbiAqIHNlbmRzIGEgbWVzc2FnZSB0byBhIHZhbHVlIGluIGEgZnV0dXJlIHR1cm5cbiAqIEBwYXJhbSBvYmplY3QqIHRoZSByZWNpcGllbnRcbiAqIEBwYXJhbSBvcCB0aGUgbmFtZSBvZiB0aGUgbWVzc2FnZSBvcGVyYXRpb24sIGUuZy4sIFwid2hlblwiLFxuICogQHBhcmFtIGFyZ3MgZnVydGhlciBhcmd1bWVudHMgdG8gYmUgZm9yd2FyZGVkIHRvIHRoZSBvcGVyYXRpb25cbiAqIEByZXR1cm5zIHJlc3VsdCB7UHJvbWlzZX0gYSBwcm9taXNlIGZvciB0aGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb25cbiAqL1xuUS5kaXNwYXRjaCA9IGRpc3BhdGNoO1xuZnVuY3Rpb24gZGlzcGF0Y2gob2JqZWN0LCBvcCwgYXJncykge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2gob3AsIGFyZ3MpO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5kaXNwYXRjaCA9IGZ1bmN0aW9uIChvcCwgYXJncykge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICBzZWxmLnByb21pc2VEaXNwYXRjaChkZWZlcnJlZC5yZXNvbHZlLCBvcCwgYXJncyk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIEdldHMgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgcHJvcGVydHkgdG8gZ2V0XG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSBwcm9wZXJ0eSB2YWx1ZVxuICovXG5RLmdldCA9IGZ1bmN0aW9uIChvYmplY3QsIGtleSkge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2goXCJnZXRcIiwgW2tleV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKGtleSkge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwiZ2V0XCIsIFtrZXldKTtcbn07XG5cbi8qKlxuICogU2V0cyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eSBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIG9iamVjdCBvYmplY3RcbiAqIEBwYXJhbSBuYW1lICAgICAgbmFtZSBvZiBwcm9wZXJ0eSB0byBzZXRcbiAqIEBwYXJhbSB2YWx1ZSAgICAgbmV3IHZhbHVlIG9mIHByb3BlcnR5XG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqL1xuUS5zZXQgPSBmdW5jdGlvbiAob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcInNldFwiLCBba2V5LCB2YWx1ZV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcInNldFwiLCBba2V5LCB2YWx1ZV0pO1xufTtcblxuLyoqXG4gKiBEZWxldGVzIGEgcHJvcGVydHkgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgcHJvcGVydHkgdG8gZGVsZXRlXG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqL1xuUS5kZWwgPSAvLyBYWFggbGVnYWN5XG5RW1wiZGVsZXRlXCJdID0gZnVuY3Rpb24gKG9iamVjdCwga2V5KSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImRlbGV0ZVwiLCBba2V5XSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5kZWwgPSAvLyBYWFggbGVnYWN5XG5Qcm9taXNlLnByb3RvdHlwZVtcImRlbGV0ZVwiXSA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImRlbGV0ZVwiLCBba2V5XSk7XG59O1xuXG4vKipcbiAqIEludm9rZXMgYSBtZXRob2QgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgbWV0aG9kIHRvIGludm9rZVxuICogQHBhcmFtIHZhbHVlICAgICBhIHZhbHVlIHRvIHBvc3QsIHR5cGljYWxseSBhbiBhcnJheSBvZlxuICogICAgICAgICAgICAgICAgICBpbnZvY2F0aW9uIGFyZ3VtZW50cyBmb3IgcHJvbWlzZXMgdGhhdFxuICogICAgICAgICAgICAgICAgICBhcmUgdWx0aW1hdGVseSBiYWNrZWQgd2l0aCBgcmVzb2x2ZWAgdmFsdWVzLFxuICogICAgICAgICAgICAgICAgICBhcyBvcHBvc2VkIHRvIHRob3NlIGJhY2tlZCB3aXRoIFVSTHNcbiAqICAgICAgICAgICAgICAgICAgd2hlcmVpbiB0aGUgcG9zdGVkIHZhbHVlIGNhbiBiZSBhbnlcbiAqICAgICAgICAgICAgICAgICAgSlNPTiBzZXJpYWxpemFibGUgb2JqZWN0LlxuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlXG4gKi9cbi8vIGJvdW5kIGxvY2FsbHkgYmVjYXVzZSBpdCBpcyB1c2VkIGJ5IG90aGVyIG1ldGhvZHNcblEubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblEucG9zdCA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWUsIGFyZ3MpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJnc10pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblByb21pc2UucHJvdG90eXBlLnBvc3QgPSBmdW5jdGlvbiAobmFtZSwgYXJncykge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJnc10pO1xufTtcblxuLyoqXG4gKiBJbnZva2VzIGEgbWV0aG9kIGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IG9iamVjdFxuICogQHBhcmFtIG5hbWUgICAgICBuYW1lIG9mIG1ldGhvZCB0byBpbnZva2VcbiAqIEBwYXJhbSAuLi5hcmdzICAgYXJyYXkgb2YgaW52b2NhdGlvbiBhcmd1bWVudHNcbiAqIEByZXR1cm4gcHJvbWlzZSBmb3IgdGhlIHJldHVybiB2YWx1ZVxuICovXG5RLnNlbmQgPSAvLyBYWFggTWFyayBNaWxsZXIncyBwcm9wb3NlZCBwYXJsYW5jZVxuUS5tY2FsbCA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5RLmludm9rZSA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWUgLyouLi5hcmdzKi8pIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAyKV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuc2VuZCA9IC8vIFhYWCBNYXJrIE1pbGxlcidzIHByb3Bvc2VkIHBhcmxhbmNlXG5Qcm9taXNlLnByb3RvdHlwZS5tY2FsbCA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5Qcm9taXNlLnByb3RvdHlwZS5pbnZva2UgPSBmdW5jdGlvbiAobmFtZSAvKi4uLmFyZ3MqLykge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKV0pO1xufTtcblxuLyoqXG4gKiBBcHBsaWVzIHRoZSBwcm9taXNlZCBmdW5jdGlvbiBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBmdW5jdGlvblxuICogQHBhcmFtIGFyZ3MgICAgICBhcnJheSBvZiBhcHBsaWNhdGlvbiBhcmd1bWVudHNcbiAqL1xuUS5mYXBwbHkgPSBmdW5jdGlvbiAob2JqZWN0LCBhcmdzKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImFwcGx5XCIsIFt2b2lkIDAsIGFyZ3NdKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmZhcHBseSA9IGZ1bmN0aW9uIChhcmdzKSB7XG4gICAgcmV0dXJuIHRoaXMuZGlzcGF0Y2goXCJhcHBseVwiLCBbdm9pZCAwLCBhcmdzXSk7XG59O1xuXG4vKipcbiAqIENhbGxzIHRoZSBwcm9taXNlZCBmdW5jdGlvbiBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBmdW5jdGlvblxuICogQHBhcmFtIC4uLmFyZ3MgICBhcnJheSBvZiBhcHBsaWNhdGlvbiBhcmd1bWVudHNcbiAqL1xuUVtcInRyeVwiXSA9XG5RLmZjYWxsID0gZnVuY3Rpb24gKG9iamVjdCAvKiAuLi5hcmdzKi8pIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwiYXBwbHlcIiwgW3ZvaWQgMCwgYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZmNhbGwgPSBmdW5jdGlvbiAoLyouLi5hcmdzKi8pIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImFwcGx5XCIsIFt2b2lkIDAsIGFycmF5X3NsaWNlKGFyZ3VtZW50cyldKTtcbn07XG5cbi8qKlxuICogQmluZHMgdGhlIHByb21pc2VkIGZ1bmN0aW9uLCB0cmFuc2Zvcm1pbmcgcmV0dXJuIHZhbHVlcyBpbnRvIGEgZnVsZmlsbGVkXG4gKiBwcm9taXNlIGFuZCB0aHJvd24gZXJyb3JzIGludG8gYSByZWplY3RlZCBvbmUuXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IGZ1bmN0aW9uXG4gKiBAcGFyYW0gLi4uYXJncyAgIGFycmF5IG9mIGFwcGxpY2F0aW9uIGFyZ3VtZW50c1xuICovXG5RLmZiaW5kID0gZnVuY3Rpb24gKG9iamVjdCAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBwcm9taXNlID0gUShvYmplY3QpO1xuICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gZmJvdW5kKCkge1xuICAgICAgICByZXR1cm4gcHJvbWlzZS5kaXNwYXRjaChcImFwcGx5XCIsIFtcbiAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICBhcmdzLmNvbmNhdChhcnJheV9zbGljZShhcmd1bWVudHMpKVxuICAgICAgICBdKTtcbiAgICB9O1xufTtcblByb21pc2UucHJvdG90eXBlLmZiaW5kID0gZnVuY3Rpb24gKC8qLi4uYXJncyovKSB7XG4gICAgdmFyIHByb21pc2UgPSB0aGlzO1xuICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gZmJvdW5kKCkge1xuICAgICAgICByZXR1cm4gcHJvbWlzZS5kaXNwYXRjaChcImFwcGx5XCIsIFtcbiAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICBhcmdzLmNvbmNhdChhcnJheV9zbGljZShhcmd1bWVudHMpKVxuICAgICAgICBdKTtcbiAgICB9O1xufTtcblxuLyoqXG4gKiBSZXF1ZXN0cyB0aGUgbmFtZXMgb2YgdGhlIG93bmVkIHByb3BlcnRpZXMgb2YgYSBwcm9taXNlZFxuICogb2JqZWN0IGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IG9iamVjdFxuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUga2V5cyBvZiB0aGUgZXZlbnR1YWxseSBzZXR0bGVkIG9iamVjdFxuICovXG5RLmtleXMgPSBmdW5jdGlvbiAob2JqZWN0KSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImtleXNcIiwgW10pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUua2V5cyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImtleXNcIiwgW10pO1xufTtcblxuLyoqXG4gKiBUdXJucyBhbiBhcnJheSBvZiBwcm9taXNlcyBpbnRvIGEgcHJvbWlzZSBmb3IgYW4gYXJyYXkuICBJZiBhbnkgb2ZcbiAqIHRoZSBwcm9taXNlcyBnZXRzIHJlamVjdGVkLCB0aGUgd2hvbGUgYXJyYXkgaXMgcmVqZWN0ZWQgaW1tZWRpYXRlbHkuXG4gKiBAcGFyYW0ge0FycmF5Kn0gYW4gYXJyYXkgKG9yIHByb21pc2UgZm9yIGFuIGFycmF5KSBvZiB2YWx1ZXMgKG9yXG4gKiBwcm9taXNlcyBmb3IgdmFsdWVzKVxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciBhbiBhcnJheSBvZiB0aGUgY29ycmVzcG9uZGluZyB2YWx1ZXNcbiAqL1xuLy8gQnkgTWFyayBNaWxsZXJcbi8vIGh0dHA6Ly93aWtpLmVjbWFzY3JpcHQub3JnL2Rva3UucGhwP2lkPXN0cmF3bWFuOmNvbmN1cnJlbmN5JnJldj0xMzA4Nzc2NTIxI2FsbGZ1bGZpbGxlZFxuUS5hbGwgPSBhbGw7XG5mdW5jdGlvbiBhbGwocHJvbWlzZXMpIHtcbiAgICByZXR1cm4gd2hlbihwcm9taXNlcywgZnVuY3Rpb24gKHByb21pc2VzKSB7XG4gICAgICAgIHZhciBwZW5kaW5nQ291bnQgPSAwO1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBhcnJheV9yZWR1Y2UocHJvbWlzZXMsIGZ1bmN0aW9uICh1bmRlZmluZWQsIHByb21pc2UsIGluZGV4KSB7XG4gICAgICAgICAgICB2YXIgc25hcHNob3Q7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgaXNQcm9taXNlKHByb21pc2UpICYmXG4gICAgICAgICAgICAgICAgKHNuYXBzaG90ID0gcHJvbWlzZS5pbnNwZWN0KCkpLnN0YXRlID09PSBcImZ1bGZpbGxlZFwiXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBwcm9taXNlc1tpbmRleF0gPSBzbmFwc2hvdC52YWx1ZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgKytwZW5kaW5nQ291bnQ7XG4gICAgICAgICAgICAgICAgd2hlbihcbiAgICAgICAgICAgICAgICAgICAgcHJvbWlzZSxcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9taXNlc1tpbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgtLXBlbmRpbmdDb3VudCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUocHJvbWlzZXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBkZWZlcnJlZC5yZWplY3QsXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIChwcm9ncmVzcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVmZXJyZWQubm90aWZ5KHsgaW5kZXg6IGluZGV4LCB2YWx1ZTogcHJvZ3Jlc3MgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCB2b2lkIDApO1xuICAgICAgICBpZiAocGVuZGluZ0NvdW50ID09PSAwKSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHByb21pc2VzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9KTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuYWxsID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBhbGwodGhpcyk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGZpcnN0IHJlc29sdmVkIHByb21pc2Ugb2YgYW4gYXJyYXkuIFByaW9yIHJlamVjdGVkIHByb21pc2VzIGFyZVxuICogaWdub3JlZC4gIFJlamVjdHMgb25seSBpZiBhbGwgcHJvbWlzZXMgYXJlIHJlamVjdGVkLlxuICogQHBhcmFtIHtBcnJheSp9IGFuIGFycmF5IGNvbnRhaW5pbmcgdmFsdWVzIG9yIHByb21pc2VzIGZvciB2YWx1ZXNcbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmdWxmaWxsZWQgd2l0aCB0aGUgdmFsdWUgb2YgdGhlIGZpcnN0IHJlc29sdmVkIHByb21pc2UsXG4gKiBvciBhIHJlamVjdGVkIHByb21pc2UgaWYgYWxsIHByb21pc2VzIGFyZSByZWplY3RlZC5cbiAqL1xuUS5hbnkgPSBhbnk7XG5cbmZ1bmN0aW9uIGFueShwcm9taXNlcykge1xuICAgIGlmIChwcm9taXNlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIFEucmVzb2x2ZSgpO1xuICAgIH1cblxuICAgIHZhciBkZWZlcnJlZCA9IFEuZGVmZXIoKTtcbiAgICB2YXIgcGVuZGluZ0NvdW50ID0gMDtcbiAgICBhcnJheV9yZWR1Y2UocHJvbWlzZXMsIGZ1bmN0aW9uIChwcmV2LCBjdXJyZW50LCBpbmRleCkge1xuICAgICAgICB2YXIgcHJvbWlzZSA9IHByb21pc2VzW2luZGV4XTtcblxuICAgICAgICBwZW5kaW5nQ291bnQrKztcblxuICAgICAgICB3aGVuKHByb21pc2UsIG9uRnVsZmlsbGVkLCBvblJlamVjdGVkLCBvblByb2dyZXNzKTtcbiAgICAgICAgZnVuY3Rpb24gb25GdWxmaWxsZWQocmVzdWx0KSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gb25SZWplY3RlZCgpIHtcbiAgICAgICAgICAgIHBlbmRpbmdDb3VudC0tO1xuICAgICAgICAgICAgaWYgKHBlbmRpbmdDb3VudCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlamVjdChuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIFwiQ2FuJ3QgZ2V0IGZ1bGZpbGxtZW50IHZhbHVlIGZyb20gYW55IHByb21pc2UsIGFsbCBcIiArXG4gICAgICAgICAgICAgICAgICAgIFwicHJvbWlzZXMgd2VyZSByZWplY3RlZC5cIlxuICAgICAgICAgICAgICAgICkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIG9uUHJvZ3Jlc3MocHJvZ3Jlc3MpIHtcbiAgICAgICAgICAgIGRlZmVycmVkLm5vdGlmeSh7XG4gICAgICAgICAgICAgICAgaW5kZXg6IGluZGV4LFxuICAgICAgICAgICAgICAgIHZhbHVlOiBwcm9ncmVzc1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9LCB1bmRlZmluZWQpO1xuXG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59XG5cblByb21pc2UucHJvdG90eXBlLmFueSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYW55KHRoaXMpO1xufTtcblxuLyoqXG4gKiBXYWl0cyBmb3IgYWxsIHByb21pc2VzIHRvIGJlIHNldHRsZWQsIGVpdGhlciBmdWxmaWxsZWQgb3JcbiAqIHJlamVjdGVkLiAgVGhpcyBpcyBkaXN0aW5jdCBmcm9tIGBhbGxgIHNpbmNlIHRoYXQgd291bGQgc3RvcFxuICogd2FpdGluZyBhdCB0aGUgZmlyc3QgcmVqZWN0aW9uLiAgVGhlIHByb21pc2UgcmV0dXJuZWQgYnlcbiAqIGBhbGxSZXNvbHZlZGAgd2lsbCBuZXZlciBiZSByZWplY3RlZC5cbiAqIEBwYXJhbSBwcm9taXNlcyBhIHByb21pc2UgZm9yIGFuIGFycmF5IChvciBhbiBhcnJheSkgb2YgcHJvbWlzZXNcbiAqIChvciB2YWx1ZXMpXG4gKiBAcmV0dXJuIGEgcHJvbWlzZSBmb3IgYW4gYXJyYXkgb2YgcHJvbWlzZXNcbiAqL1xuUS5hbGxSZXNvbHZlZCA9IGRlcHJlY2F0ZShhbGxSZXNvbHZlZCwgXCJhbGxSZXNvbHZlZFwiLCBcImFsbFNldHRsZWRcIik7XG5mdW5jdGlvbiBhbGxSZXNvbHZlZChwcm9taXNlcykge1xuICAgIHJldHVybiB3aGVuKHByb21pc2VzLCBmdW5jdGlvbiAocHJvbWlzZXMpIHtcbiAgICAgICAgcHJvbWlzZXMgPSBhcnJheV9tYXAocHJvbWlzZXMsIFEpO1xuICAgICAgICByZXR1cm4gd2hlbihhbGwoYXJyYXlfbWFwKHByb21pc2VzLCBmdW5jdGlvbiAocHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuIHdoZW4ocHJvbWlzZSwgbm9vcCwgbm9vcCk7XG4gICAgICAgIH0pKSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VzO1xuICAgICAgICB9KTtcbiAgICB9KTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuYWxsUmVzb2x2ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGFsbFJlc29sdmVkKHRoaXMpO1xufTtcblxuLyoqXG4gKiBAc2VlIFByb21pc2UjYWxsU2V0dGxlZFxuICovXG5RLmFsbFNldHRsZWQgPSBhbGxTZXR0bGVkO1xuZnVuY3Rpb24gYWxsU2V0dGxlZChwcm9taXNlcykge1xuICAgIHJldHVybiBRKHByb21pc2VzKS5hbGxTZXR0bGVkKCk7XG59XG5cbi8qKlxuICogVHVybnMgYW4gYXJyYXkgb2YgcHJvbWlzZXMgaW50byBhIHByb21pc2UgZm9yIGFuIGFycmF5IG9mIHRoZWlyIHN0YXRlcyAoYXNcbiAqIHJldHVybmVkIGJ5IGBpbnNwZWN0YCkgd2hlbiB0aGV5IGhhdmUgYWxsIHNldHRsZWQuXG4gKiBAcGFyYW0ge0FycmF5W0FueSpdfSB2YWx1ZXMgYW4gYXJyYXkgKG9yIHByb21pc2UgZm9yIGFuIGFycmF5KSBvZiB2YWx1ZXMgKG9yXG4gKiBwcm9taXNlcyBmb3IgdmFsdWVzKVxuICogQHJldHVybnMge0FycmF5W1N0YXRlXX0gYW4gYXJyYXkgb2Ygc3RhdGVzIGZvciB0aGUgcmVzcGVjdGl2ZSB2YWx1ZXMuXG4gKi9cblByb21pc2UucHJvdG90eXBlLmFsbFNldHRsZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAocHJvbWlzZXMpIHtcbiAgICAgICAgcmV0dXJuIGFsbChhcnJheV9tYXAocHJvbWlzZXMsIGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gICAgICAgICAgICBwcm9taXNlID0gUShwcm9taXNlKTtcbiAgICAgICAgICAgIGZ1bmN0aW9uIHJlZ2FyZGxlc3MoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2UuaW5zcGVjdCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHByb21pc2UudGhlbihyZWdhcmRsZXNzLCByZWdhcmRsZXNzKTtcbiAgICAgICAgfSkpO1xuICAgIH0pO1xufTtcblxuLyoqXG4gKiBDYXB0dXJlcyB0aGUgZmFpbHVyZSBvZiBhIHByb21pc2UsIGdpdmluZyBhbiBvcG9ydHVuaXR5IHRvIHJlY292ZXJcbiAqIHdpdGggYSBjYWxsYmFjay4gIElmIHRoZSBnaXZlbiBwcm9taXNlIGlzIGZ1bGZpbGxlZCwgdGhlIHJldHVybmVkXG4gKiBwcm9taXNlIGlzIGZ1bGZpbGxlZC5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZSBmb3Igc29tZXRoaW5nXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayB0byBmdWxmaWxsIHRoZSByZXR1cm5lZCBwcm9taXNlIGlmIHRoZVxuICogZ2l2ZW4gcHJvbWlzZSBpcyByZWplY3RlZFxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBjYWxsYmFja1xuICovXG5RLmZhaWwgPSAvLyBYWFggbGVnYWN5XG5RW1wiY2F0Y2hcIl0gPSBmdW5jdGlvbiAob2JqZWN0LCByZWplY3RlZCkge1xuICAgIHJldHVybiBRKG9iamVjdCkudGhlbih2b2lkIDAsIHJlamVjdGVkKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmZhaWwgPSAvLyBYWFggbGVnYWN5XG5Qcm9taXNlLnByb3RvdHlwZVtcImNhdGNoXCJdID0gZnVuY3Rpb24gKHJlamVjdGVkKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbih2b2lkIDAsIHJlamVjdGVkKTtcbn07XG5cbi8qKlxuICogQXR0YWNoZXMgYSBsaXN0ZW5lciB0aGF0IGNhbiByZXNwb25kIHRvIHByb2dyZXNzIG5vdGlmaWNhdGlvbnMgZnJvbSBhXG4gKiBwcm9taXNlJ3Mgb3JpZ2luYXRpbmcgZGVmZXJyZWQuIFRoaXMgbGlzdGVuZXIgcmVjZWl2ZXMgdGhlIGV4YWN0IGFyZ3VtZW50c1xuICogcGFzc2VkIHRvIGBgZGVmZXJyZWQubm90aWZ5YGAuXG4gKiBAcGFyYW0ge0FueSp9IHByb21pc2UgZm9yIHNvbWV0aGluZ1xuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgdG8gcmVjZWl2ZSBhbnkgcHJvZ3Jlc3Mgbm90aWZpY2F0aW9uc1xuICogQHJldHVybnMgdGhlIGdpdmVuIHByb21pc2UsIHVuY2hhbmdlZFxuICovXG5RLnByb2dyZXNzID0gcHJvZ3Jlc3M7XG5mdW5jdGlvbiBwcm9ncmVzcyhvYmplY3QsIHByb2dyZXNzZWQpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLnRoZW4odm9pZCAwLCB2b2lkIDAsIHByb2dyZXNzZWQpO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5wcm9ncmVzcyA9IGZ1bmN0aW9uIChwcm9ncmVzc2VkKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbih2b2lkIDAsIHZvaWQgMCwgcHJvZ3Jlc3NlZCk7XG59O1xuXG4vKipcbiAqIFByb3ZpZGVzIGFuIG9wcG9ydHVuaXR5IHRvIG9ic2VydmUgdGhlIHNldHRsaW5nIG9mIGEgcHJvbWlzZSxcbiAqIHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciB0aGUgcHJvbWlzZSBpcyBmdWxmaWxsZWQgb3IgcmVqZWN0ZWQuICBGb3J3YXJkc1xuICogdGhlIHJlc29sdXRpb24gdG8gdGhlIHJldHVybmVkIHByb21pc2Ugd2hlbiB0aGUgY2FsbGJhY2sgaXMgZG9uZS5cbiAqIFRoZSBjYWxsYmFjayBjYW4gcmV0dXJuIGEgcHJvbWlzZSB0byBkZWZlciBjb21wbGV0aW9uLlxuICogQHBhcmFtIHtBbnkqfSBwcm9taXNlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayB0byBvYnNlcnZlIHRoZSByZXNvbHV0aW9uIG9mIHRoZSBnaXZlblxuICogcHJvbWlzZSwgdGFrZXMgbm8gYXJndW1lbnRzLlxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmVzb2x1dGlvbiBvZiB0aGUgZ2l2ZW4gcHJvbWlzZSB3aGVuXG4gKiBgYGZpbmBgIGlzIGRvbmUuXG4gKi9cblEuZmluID0gLy8gWFhYIGxlZ2FjeVxuUVtcImZpbmFsbHlcIl0gPSBmdW5jdGlvbiAob2JqZWN0LCBjYWxsYmFjaykge1xuICAgIHJldHVybiBRKG9iamVjdClbXCJmaW5hbGx5XCJdKGNhbGxiYWNrKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmZpbiA9IC8vIFhYWCBsZWdhY3lcblByb21pc2UucHJvdG90eXBlW1wiZmluYWxseVwiXSA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gUShjYWxsYmFjayk7XG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmZjYWxsKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH0pO1xuICAgIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgICAgLy8gVE9ETyBhdHRlbXB0IHRvIHJlY3ljbGUgdGhlIHJlamVjdGlvbiB3aXRoIFwidGhpc1wiLlxuICAgICAgICByZXR1cm4gY2FsbGJhY2suZmNhbGwoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRocm93IHJlYXNvbjtcbiAgICAgICAgfSk7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFRlcm1pbmF0ZXMgYSBjaGFpbiBvZiBwcm9taXNlcywgZm9yY2luZyByZWplY3Rpb25zIHRvIGJlXG4gKiB0aHJvd24gYXMgZXhjZXB0aW9ucy5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZSBhdCB0aGUgZW5kIG9mIGEgY2hhaW4gb2YgcHJvbWlzZXNcbiAqIEByZXR1cm5zIG5vdGhpbmdcbiAqL1xuUS5kb25lID0gZnVuY3Rpb24gKG9iamVjdCwgZnVsZmlsbGVkLCByZWplY3RlZCwgcHJvZ3Jlc3MpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRvbmUoZnVsZmlsbGVkLCByZWplY3RlZCwgcHJvZ3Jlc3MpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZG9uZSA9IGZ1bmN0aW9uIChmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzcykge1xuICAgIHZhciBvblVuaGFuZGxlZEVycm9yID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgIC8vIGZvcndhcmQgdG8gYSBmdXR1cmUgdHVybiBzbyB0aGF0IGBgd2hlbmBgXG4gICAgICAgIC8vIGRvZXMgbm90IGNhdGNoIGl0IGFuZCB0dXJuIGl0IGludG8gYSByZWplY3Rpb24uXG4gICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbWFrZVN0YWNrVHJhY2VMb25nKGVycm9yLCBwcm9taXNlKTtcbiAgICAgICAgICAgIGlmIChRLm9uZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBRLm9uZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8vIEF2b2lkIHVubmVjZXNzYXJ5IGBuZXh0VGlja2BpbmcgdmlhIGFuIHVubmVjZXNzYXJ5IGB3aGVuYC5cbiAgICB2YXIgcHJvbWlzZSA9IGZ1bGZpbGxlZCB8fCByZWplY3RlZCB8fCBwcm9ncmVzcyA/XG4gICAgICAgIHRoaXMudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzcykgOlxuICAgICAgICB0aGlzO1xuXG4gICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmIHByb2Nlc3MgJiYgcHJvY2Vzcy5kb21haW4pIHtcbiAgICAgICAgb25VbmhhbmRsZWRFcnJvciA9IHByb2Nlc3MuZG9tYWluLmJpbmQob25VbmhhbmRsZWRFcnJvcik7XG4gICAgfVxuXG4gICAgcHJvbWlzZS50aGVuKHZvaWQgMCwgb25VbmhhbmRsZWRFcnJvcik7XG59O1xuXG4vKipcbiAqIENhdXNlcyBhIHByb21pc2UgdG8gYmUgcmVqZWN0ZWQgaWYgaXQgZG9lcyBub3QgZ2V0IGZ1bGZpbGxlZCBiZWZvcmVcbiAqIHNvbWUgbWlsbGlzZWNvbmRzIHRpbWUgb3V0LlxuICogQHBhcmFtIHtBbnkqfSBwcm9taXNlXG4gKiBAcGFyYW0ge051bWJlcn0gbWlsbGlzZWNvbmRzIHRpbWVvdXRcbiAqIEBwYXJhbSB7QW55Kn0gY3VzdG9tIGVycm9yIG1lc3NhZ2Ugb3IgRXJyb3Igb2JqZWN0IChvcHRpb25hbClcbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHJlc29sdXRpb24gb2YgdGhlIGdpdmVuIHByb21pc2UgaWYgaXQgaXNcbiAqIGZ1bGZpbGxlZCBiZWZvcmUgdGhlIHRpbWVvdXQsIG90aGVyd2lzZSByZWplY3RlZC5cbiAqL1xuUS50aW1lb3V0ID0gZnVuY3Rpb24gKG9iamVjdCwgbXMsIGVycm9yKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS50aW1lb3V0KG1zLCBlcnJvcik7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50aW1lb3V0ID0gZnVuY3Rpb24gKG1zLCBlcnJvcikge1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgdmFyIHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIWVycm9yIHx8IFwic3RyaW5nXCIgPT09IHR5cGVvZiBlcnJvcikge1xuICAgICAgICAgICAgZXJyb3IgPSBuZXcgRXJyb3IoZXJyb3IgfHwgXCJUaW1lZCBvdXQgYWZ0ZXIgXCIgKyBtcyArIFwiIG1zXCIpO1xuICAgICAgICAgICAgZXJyb3IuY29kZSA9IFwiRVRJTUVET1VUXCI7XG4gICAgICAgIH1cbiAgICAgICAgZGVmZXJyZWQucmVqZWN0KGVycm9yKTtcbiAgICB9LCBtcyk7XG5cbiAgICB0aGlzLnRoZW4oZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHZhbHVlKTtcbiAgICB9LCBmdW5jdGlvbiAoZXhjZXB0aW9uKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgICBkZWZlcnJlZC5yZWplY3QoZXhjZXB0aW9uKTtcbiAgICB9LCBkZWZlcnJlZC5ub3RpZnkpO1xuXG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIFJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgZ2l2ZW4gdmFsdWUgKG9yIHByb21pc2VkIHZhbHVlKSwgc29tZVxuICogbWlsbGlzZWNvbmRzIGFmdGVyIGl0IHJlc29sdmVkLiBQYXNzZXMgcmVqZWN0aW9ucyBpbW1lZGlhdGVseS5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZVxuICogQHBhcmFtIHtOdW1iZXJ9IG1pbGxpc2Vjb25kc1xuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmVzb2x1dGlvbiBvZiB0aGUgZ2l2ZW4gcHJvbWlzZSBhZnRlciBtaWxsaXNlY29uZHNcbiAqIHRpbWUgaGFzIGVsYXBzZWQgc2luY2UgdGhlIHJlc29sdXRpb24gb2YgdGhlIGdpdmVuIHByb21pc2UuXG4gKiBJZiB0aGUgZ2l2ZW4gcHJvbWlzZSByZWplY3RzLCB0aGF0IGlzIHBhc3NlZCBpbW1lZGlhdGVseS5cbiAqL1xuUS5kZWxheSA9IGZ1bmN0aW9uIChvYmplY3QsIHRpbWVvdXQpIHtcbiAgICBpZiAodGltZW91dCA9PT0gdm9pZCAwKSB7XG4gICAgICAgIHRpbWVvdXQgPSBvYmplY3Q7XG4gICAgICAgIG9iamVjdCA9IHZvaWQgMDtcbiAgICB9XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kZWxheSh0aW1lb3V0KTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmRlbGF5ID0gZnVuY3Rpb24gKHRpbWVvdXQpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUodmFsdWUpO1xuICAgICAgICB9LCB0aW1lb3V0KTtcbiAgICAgICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFBhc3NlcyBhIGNvbnRpbnVhdGlvbiB0byBhIE5vZGUgZnVuY3Rpb24sIHdoaWNoIGlzIGNhbGxlZCB3aXRoIHRoZSBnaXZlblxuICogYXJndW1lbnRzIHByb3ZpZGVkIGFzIGFuIGFycmF5LCBhbmQgcmV0dXJucyBhIHByb21pc2UuXG4gKlxuICogICAgICBRLm5mYXBwbHkoRlMucmVhZEZpbGUsIFtfX2ZpbGVuYW1lXSlcbiAqICAgICAgLnRoZW4oZnVuY3Rpb24gKGNvbnRlbnQpIHtcbiAqICAgICAgfSlcbiAqXG4gKi9cblEubmZhcHBseSA9IGZ1bmN0aW9uIChjYWxsYmFjaywgYXJncykge1xuICAgIHJldHVybiBRKGNhbGxiYWNrKS5uZmFwcGx5KGFyZ3MpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmZhcHBseSA9IGZ1bmN0aW9uIChhcmdzKSB7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmdzKTtcbiAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgdGhpcy5mYXBwbHkobm9kZUFyZ3MpLmZhaWwoZGVmZXJyZWQucmVqZWN0KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cbi8qKlxuICogUGFzc2VzIGEgY29udGludWF0aW9uIHRvIGEgTm9kZSBmdW5jdGlvbiwgd2hpY2ggaXMgY2FsbGVkIHdpdGggdGhlIGdpdmVuXG4gKiBhcmd1bWVudHMgcHJvdmlkZWQgaW5kaXZpZHVhbGx5LCBhbmQgcmV0dXJucyBhIHByb21pc2UuXG4gKiBAZXhhbXBsZVxuICogUS5uZmNhbGwoRlMucmVhZEZpbGUsIF9fZmlsZW5hbWUpXG4gKiAudGhlbihmdW5jdGlvbiAoY29udGVudCkge1xuICogfSlcbiAqXG4gKi9cblEubmZjYWxsID0gZnVuY3Rpb24gKGNhbGxiYWNrIC8qLi4uYXJncyovKSB7XG4gICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDEpO1xuICAgIHJldHVybiBRKGNhbGxiYWNrKS5uZmFwcGx5KGFyZ3MpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmZjYWxsID0gZnVuY3Rpb24gKC8qLi4uYXJncyovKSB7XG4gICAgdmFyIG5vZGVBcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICB0aGlzLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufTtcblxuLyoqXG4gKiBXcmFwcyBhIE5vZGVKUyBjb250aW51YXRpb24gcGFzc2luZyBmdW5jdGlvbiBhbmQgcmV0dXJucyBhbiBlcXVpdmFsZW50XG4gKiB2ZXJzaW9uIHRoYXQgcmV0dXJucyBhIHByb21pc2UuXG4gKiBAZXhhbXBsZVxuICogUS5uZmJpbmQoRlMucmVhZEZpbGUsIF9fZmlsZW5hbWUpKFwidXRmLThcIilcbiAqIC50aGVuKGNvbnNvbGUubG9nKVxuICogLmRvbmUoKVxuICovXG5RLm5mYmluZCA9XG5RLmRlbm9kZWlmeSA9IGZ1bmN0aW9uIChjYWxsYmFjayAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBiYXNlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMSk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG5vZGVBcmdzID0gYmFzZUFyZ3MuY29uY2F0KGFycmF5X3NsaWNlKGFyZ3VtZW50cykpO1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgICAgIFEoY2FsbGJhY2spLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmZiaW5kID1cblByb21pc2UucHJvdG90eXBlLmRlbm9kZWlmeSA9IGZ1bmN0aW9uICgvKi4uLmFyZ3MqLykge1xuICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICBhcmdzLnVuc2hpZnQodGhpcyk7XG4gICAgcmV0dXJuIFEuZGVub2RlaWZ5LmFwcGx5KHZvaWQgMCwgYXJncyk7XG59O1xuXG5RLm5iaW5kID0gZnVuY3Rpb24gKGNhbGxiYWNrLCB0aGlzcCAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBiYXNlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMik7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG5vZGVBcmdzID0gYmFzZUFyZ3MuY29uY2F0KGFycmF5X3NsaWNlKGFyZ3VtZW50cykpO1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgICAgIGZ1bmN0aW9uIGJvdW5kKCkge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KHRoaXNwLCBhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgICAgIFEoYm91bmQpLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmJpbmQgPSBmdW5jdGlvbiAoLyp0aGlzcCwgLi4uYXJncyovKSB7XG4gICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDApO1xuICAgIGFyZ3MudW5zaGlmdCh0aGlzKTtcbiAgICByZXR1cm4gUS5uYmluZC5hcHBseSh2b2lkIDAsIGFyZ3MpO1xufTtcblxuLyoqXG4gKiBDYWxscyBhIG1ldGhvZCBvZiBhIE5vZGUtc3R5bGUgb2JqZWN0IHRoYXQgYWNjZXB0cyBhIE5vZGUtc3R5bGVcbiAqIGNhbGxiYWNrIHdpdGggYSBnaXZlbiBhcnJheSBvZiBhcmd1bWVudHMsIHBsdXMgYSBwcm92aWRlZCBjYWxsYmFjay5cbiAqIEBwYXJhbSBvYmplY3QgYW4gb2JqZWN0IHRoYXQgaGFzIHRoZSBuYW1lZCBtZXRob2RcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG5hbWUgb2YgdGhlIG1ldGhvZCBvZiBvYmplY3RcbiAqIEBwYXJhbSB7QXJyYXl9IGFyZ3MgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIG1ldGhvZDsgdGhlIGNhbGxiYWNrXG4gKiB3aWxsIGJlIHByb3ZpZGVkIGJ5IFEgYW5kIGFwcGVuZGVkIHRvIHRoZXNlIGFyZ3VtZW50cy5cbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHZhbHVlIG9yIGVycm9yXG4gKi9cblEubm1hcHBseSA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5RLm5wb3N0ID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSwgYXJncykge1xuICAgIHJldHVybiBRKG9iamVjdCkubnBvc3QobmFtZSwgYXJncyk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5ubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblByb21pc2UucHJvdG90eXBlLm5wb3N0ID0gZnVuY3Rpb24gKG5hbWUsIGFyZ3MpIHtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmdzIHx8IFtdKTtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICB0aGlzLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgbm9kZUFyZ3NdKS5mYWlsKGRlZmVycmVkLnJlamVjdCk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIENhbGxzIGEgbWV0aG9kIG9mIGEgTm9kZS1zdHlsZSBvYmplY3QgdGhhdCBhY2NlcHRzIGEgTm9kZS1zdHlsZVxuICogY2FsbGJhY2ssIGZvcndhcmRpbmcgdGhlIGdpdmVuIHZhcmlhZGljIGFyZ3VtZW50cywgcGx1cyBhIHByb3ZpZGVkXG4gKiBjYWxsYmFjayBhcmd1bWVudC5cbiAqIEBwYXJhbSBvYmplY3QgYW4gb2JqZWN0IHRoYXQgaGFzIHRoZSBuYW1lZCBtZXRob2RcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG5hbWUgb2YgdGhlIG1ldGhvZCBvZiBvYmplY3RcbiAqIEBwYXJhbSAuLi5hcmdzIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBtZXRob2Q7IHRoZSBjYWxsYmFjayB3aWxsXG4gKiBiZSBwcm92aWRlZCBieSBRIGFuZCBhcHBlbmRlZCB0byB0aGVzZSBhcmd1bWVudHMuXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSB2YWx1ZSBvciBlcnJvclxuICovXG5RLm5zZW5kID0gLy8gWFhYIEJhc2VkIG9uIE1hcmsgTWlsbGVyJ3MgcHJvcG9zZWQgXCJzZW5kXCJcblEubm1jYWxsID0gLy8gWFhYIEJhc2VkIG9uIFwiUmVkc2FuZHJvJ3NcIiBwcm9wb3NhbFxuUS5uaW52b2tlID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBub2RlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMik7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgUShvYmplY3QpLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgbm9kZUFyZ3NdKS5mYWlsKGRlZmVycmVkLnJlamVjdCk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5uc2VuZCA9IC8vIFhYWCBCYXNlZCBvbiBNYXJrIE1pbGxlcidzIHByb3Bvc2VkIFwic2VuZFwiXG5Qcm9taXNlLnByb3RvdHlwZS5ubWNhbGwgPSAvLyBYWFggQmFzZWQgb24gXCJSZWRzYW5kcm8nc1wiIHByb3Bvc2FsXG5Qcm9taXNlLnByb3RvdHlwZS5uaW52b2tlID0gZnVuY3Rpb24gKG5hbWUgLyouLi5hcmdzKi8pIHtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDEpO1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgbm9kZUFyZ3MucHVzaChkZWZlcnJlZC5tYWtlTm9kZVJlc29sdmVyKCkpO1xuICAgIHRoaXMuZGlzcGF0Y2goXCJwb3N0XCIsIFtuYW1lLCBub2RlQXJnc10pLmZhaWwoZGVmZXJyZWQucmVqZWN0KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cbi8qKlxuICogSWYgYSBmdW5jdGlvbiB3b3VsZCBsaWtlIHRvIHN1cHBvcnQgYm90aCBOb2RlIGNvbnRpbnVhdGlvbi1wYXNzaW5nLXN0eWxlIGFuZFxuICogcHJvbWlzZS1yZXR1cm5pbmctc3R5bGUsIGl0IGNhbiBlbmQgaXRzIGludGVybmFsIHByb21pc2UgY2hhaW4gd2l0aFxuICogYG5vZGVpZnkobm9kZWJhY2spYCwgZm9yd2FyZGluZyB0aGUgb3B0aW9uYWwgbm9kZWJhY2sgYXJndW1lbnQuICBJZiB0aGUgdXNlclxuICogZWxlY3RzIHRvIHVzZSBhIG5vZGViYWNrLCB0aGUgcmVzdWx0IHdpbGwgYmUgc2VudCB0aGVyZS4gIElmIHRoZXkgZG8gbm90XG4gKiBwYXNzIGEgbm9kZWJhY2ssIHRoZXkgd2lsbCByZWNlaXZlIHRoZSByZXN1bHQgcHJvbWlzZS5cbiAqIEBwYXJhbSBvYmplY3QgYSByZXN1bHQgKG9yIGEgcHJvbWlzZSBmb3IgYSByZXN1bHQpXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBub2RlYmFjayBhIE5vZGUuanMtc3R5bGUgY2FsbGJhY2tcbiAqIEByZXR1cm5zIGVpdGhlciB0aGUgcHJvbWlzZSBvciBub3RoaW5nXG4gKi9cblEubm9kZWlmeSA9IG5vZGVpZnk7XG5mdW5jdGlvbiBub2RlaWZ5KG9iamVjdCwgbm9kZWJhY2spIHtcbiAgICByZXR1cm4gUShvYmplY3QpLm5vZGVpZnkobm9kZWJhY2spO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5ub2RlaWZ5ID0gZnVuY3Rpb24gKG5vZGViYWNrKSB7XG4gICAgaWYgKG5vZGViYWNrKSB7XG4gICAgICAgIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIG5vZGViYWNrKG51bGwsIHZhbHVlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIG5vZGViYWNrKGVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59O1xuXG5RLm5vQ29uZmxpY3QgPSBmdW5jdGlvbigpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJRLm5vQ29uZmxpY3Qgb25seSB3b3JrcyB3aGVuIFEgaXMgdXNlZCBhcyBhIGdsb2JhbFwiKTtcbn07XG5cbi8vIEFsbCBjb2RlIGJlZm9yZSB0aGlzIHBvaW50IHdpbGwgYmUgZmlsdGVyZWQgZnJvbSBzdGFjayB0cmFjZXMuXG52YXIgcUVuZGluZ0xpbmUgPSBjYXB0dXJlTGluZSgpO1xuXG5yZXR1cm4gUTtcblxufSk7XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKCdfcHJvY2VzcycpKVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ6dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiSW01dlpHVmZiVzlrZFd4bGN5OXhMM0V1YW5NaVhTd2libUZ0WlhNaU9sdGRMQ0p0WVhCd2FXNW5jeUk2SWp0QlFVRkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFTSXNJbVpwYkdVaU9pSm5aVzVsY21GMFpXUXVhbk1pTENKemIzVnlZMlZTYjI5MElqb2lJaXdpYzI5MWNtTmxjME52Ym5SbGJuUWlPbHNpTHk4Z2RtbHRPblJ6UFRRNmMzUnpQVFE2YzNjOU5EcGNiaThxSVZ4dUlDcGNiaUFxSUVOdmNIbHlhV2RvZENBeU1EQTVMVEl3TVRJZ1MzSnBjeUJMYjNkaGJDQjFibVJsY2lCMGFHVWdkR1Z5YlhNZ2IyWWdkR2hsSUUxSlZGeHVJQ29nYkdsalpXNXpaU0JtYjNWdVpDQmhkQ0JvZEhSd09pOHZaMmwwYUhWaUxtTnZiUzlyY21semEyOTNZV3d2Y1M5eVlYY3ZiV0Z6ZEdWeUwweEpRMFZPVTBWY2JpQXFYRzRnS2lCWGFYUm9JSEJoY25SeklHSjVJRlI1YkdWeUlFTnNiM05sWEc0Z0tpQkRiM0I1Y21sbmFIUWdNakF3TnkweU1EQTVJRlI1YkdWeUlFTnNiM05sSUhWdVpHVnlJSFJvWlNCMFpYSnRjeUJ2WmlCMGFHVWdUVWxVSUZnZ2JHbGpaVzV6WlNCbWIzVnVaRnh1SUNvZ1lYUWdhSFIwY0RvdkwzZDNkeTV2Y0dWdWMyOTFjbU5sTG05eVp5OXNhV05sYm5ObGN5OXRhWFF0YkdsalpXNXpaUzVvZEcxc1hHNGdLaUJHYjNKclpXUWdZWFFnY21WbVgzTmxibVF1YW5NZ2RtVnljMmx2YmpvZ01qQXdPUzB3TlMweE1WeHVJQ3BjYmlBcUlGZHBkR2dnY0dGeWRITWdZbmtnVFdGeWF5Qk5hV3hzWlhKY2JpQXFJRU52Y0hseWFXZG9kQ0FvUXlrZ01qQXhNU0JIYjI5bmJHVWdTVzVqTGx4dUlDcGNiaUFxSUV4cFkyVnVjMlZrSUhWdVpHVnlJSFJvWlNCQmNHRmphR1VnVEdsalpXNXpaU3dnVm1WeWMybHZiaUF5TGpBZ0tIUm9aU0JjSWt4cFkyVnVjMlZjSWlrN1hHNGdLaUI1YjNVZ2JXRjVJRzV2ZENCMWMyVWdkR2hwY3lCbWFXeGxJR1Y0WTJWd2RDQnBiaUJqYjIxd2JHbGhibU5sSUhkcGRHZ2dkR2hsSUV4cFkyVnVjMlV1WEc0Z0tpQlpiM1VnYldGNUlHOWlkR0ZwYmlCaElHTnZjSGtnYjJZZ2RHaGxJRXhwWTJWdWMyVWdZWFJjYmlBcVhHNGdLaUJvZEhSd09pOHZkM2QzTG1Gd1lXTm9aUzV2Y21jdmJHbGpaVzV6WlhNdlRFbERSVTVUUlMweUxqQmNiaUFxWEc0Z0tpQlZibXhsYzNNZ2NtVnhkV2x5WldRZ1lua2dZWEJ3YkdsallXSnNaU0JzWVhjZ2IzSWdZV2R5WldWa0lIUnZJR2x1SUhkeWFYUnBibWNzSUhOdlpuUjNZWEpsWEc0Z0tpQmthWE4wY21saWRYUmxaQ0IxYm1SbGNpQjBhR1VnVEdsalpXNXpaU0JwY3lCa2FYTjBjbWxpZFhSbFpDQnZiaUJoYmlCY0lrRlRJRWxUWENJZ1FrRlRTVk1zWEc0Z0tpQlhTVlJJVDFWVUlGZEJVbEpCVGxSSlJWTWdUMUlnUTA5T1JFbFVTVTlPVXlCUFJpQkJUbGtnUzBsT1JDd2daV2wwYUdWeUlHVjRjSEpsYzNNZ2IzSWdhVzF3YkdsbFpDNWNiaUFxSUZObFpTQjBhR1VnVEdsalpXNXpaU0JtYjNJZ2RHaGxJSE53WldOcFptbGpJR3hoYm1kMVlXZGxJR2R2ZG1WeWJtbHVaeUJ3WlhKdGFYTnphVzl1Y3lCaGJtUmNiaUFxSUd4cGJXbDBZWFJwYjI1eklIVnVaR1Z5SUhSb1pTQk1hV05sYm5ObExseHVJQ3BjYmlBcUwxeHVYRzRvWm5WdVkzUnBiMjRnS0dSbFptbHVhWFJwYjI0cElIdGNiaUFnSUNCY0luVnpaU0J6ZEhKcFkzUmNJanRjYmx4dUlDQWdJQzh2SUZSb2FYTWdabWxzWlNCM2FXeHNJR1oxYm1OMGFXOXVJSEJ5YjNCbGNteDVJR0Z6SUdFZ1BITmpjbWx3ZEQ0Z2RHRm5MQ0J2Y2lCaElHMXZaSFZzWlZ4dUlDQWdJQzh2SUhWemFXNW5JRU52YlcxdmJrcFRJR0Z1WkNCT2IyUmxTbE1nYjNJZ1VtVnhkV2x5WlVwVElHMXZaSFZzWlNCbWIzSnRZWFJ6TGlBZ1NXNWNiaUFnSUNBdkx5QkRiMjF0YjI0dlRtOWtaUzlTWlhGMWFYSmxTbE1zSUhSb1pTQnRiMlIxYkdVZ1pYaHdiM0owY3lCMGFHVWdVU0JCVUVrZ1lXNWtJSGRvWlc1Y2JpQWdJQ0F2THlCbGVHVmpkWFJsWkNCaGN5QmhJSE5wYlhCc1pTQThjMk55YVhCMFBpd2dhWFFnWTNKbFlYUmxjeUJoSUZFZ1oyeHZZbUZzSUdsdWMzUmxZV1F1WEc1Y2JpQWdJQ0F2THlCTmIyNTBZV2RsSUZKbGNYVnBjbVZjYmlBZ0lDQnBaaUFvZEhsd1pXOW1JR0p2YjNSemRISmhjQ0E5UFQwZ1hDSm1kVzVqZEdsdmJsd2lLU0I3WEc0Z0lDQWdJQ0FnSUdKdmIzUnpkSEpoY0NoY0luQnliMjFwYzJWY0lpd2daR1ZtYVc1cGRHbHZiaWs3WEc1Y2JpQWdJQ0F2THlCRGIyMXRiMjVLVTF4dUlDQWdJSDBnWld4elpTQnBaaUFvZEhsd1pXOW1JR1Y0Y0c5eWRITWdQVDA5SUZ3aWIySnFaV04wWENJZ0ppWWdkSGx3Wlc5bUlHMXZaSFZzWlNBOVBUMGdYQ0p2WW1wbFkzUmNJaWtnZTF4dUlDQWdJQ0FnSUNCdGIyUjFiR1V1Wlhod2IzSjBjeUE5SUdSbFptbHVhWFJwYjI0b0tUdGNibHh1SUNBZ0lDOHZJRkpsY1hWcGNtVktVMXh1SUNBZ0lIMGdaV3h6WlNCcFppQW9kSGx3Wlc5bUlHUmxabWx1WlNBOVBUMGdYQ0ptZFc1amRHbHZibHdpSUNZbUlHUmxabWx1WlM1aGJXUXBJSHRjYmlBZ0lDQWdJQ0FnWkdWbWFXNWxLR1JsWm1sdWFYUnBiMjRwTzF4dVhHNGdJQ0FnTHk4Z1UwVlRJQ2hUWldOMWNtVWdSV050WVZOamNtbHdkQ2xjYmlBZ0lDQjlJR1ZzYzJVZ2FXWWdLSFI1Y0dWdlppQnpaWE1nSVQwOUlGd2lkVzVrWldacGJtVmtYQ0lwSUh0Y2JpQWdJQ0FnSUNBZ2FXWWdLQ0Z6WlhNdWIyc29LU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjbVYwZFhKdU8xeHVJQ0FnSUNBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYzJWekxtMWhhMlZSSUQwZ1pHVm1hVzVwZEdsdmJqdGNiaUFnSUNBZ0lDQWdmVnh1WEc0Z0lDQWdMeThnUEhOamNtbHdkRDVjYmlBZ0lDQjlJR1ZzYzJVZ2FXWWdLSFI1Y0dWdlppQjNhVzVrYjNjZ0lUMDlJRndpZFc1a1pXWnBibVZrWENJZ2ZId2dkSGx3Wlc5bUlITmxiR1lnSVQwOUlGd2lkVzVrWldacGJtVmtYQ0lwSUh0Y2JpQWdJQ0FnSUNBZ0x5OGdVSEpsWm1WeUlIZHBibVJ2ZHlCdmRtVnlJSE5sYkdZZ1ptOXlJR0ZrWkMxdmJpQnpZM0pwY0hSekxpQlZjMlVnYzJWc1ppQm1iM0pjYmlBZ0lDQWdJQ0FnTHk4Z2JtOXVMWGRwYm1SdmQyVmtJR052Ym5SbGVIUnpMbHh1SUNBZ0lDQWdJQ0IyWVhJZ1oyeHZZbUZzSUQwZ2RIbHdaVzltSUhkcGJtUnZkeUFoUFQwZ1hDSjFibVJsWm1sdVpXUmNJaUEvSUhkcGJtUnZkeUE2SUhObGJHWTdYRzVjYmlBZ0lDQWdJQ0FnTHk4Z1IyVjBJSFJvWlNCZ2QybHVaRzkzWUNCdlltcGxZM1FzSUhOaGRtVWdkR2hsSUhCeVpYWnBiM1Z6SUZFZ1oyeHZZbUZzWEc0Z0lDQWdJQ0FnSUM4dklHRnVaQ0JwYm1sMGFXRnNhWHBsSUZFZ1lYTWdZU0JuYkc5aVlXd3VYRzRnSUNBZ0lDQWdJSFpoY2lCd2NtVjJhVzkxYzFFZ1BTQm5iRzlpWVd3dVVUdGNiaUFnSUNBZ0lDQWdaMnh2WW1Gc0xsRWdQU0JrWldacGJtbDBhVzl1S0NrN1hHNWNiaUFnSUNBZ0lDQWdMeThnUVdSa0lHRWdibTlEYjI1bWJHbGpkQ0JtZFc1amRHbHZiaUJ6YnlCUklHTmhiaUJpWlNCeVpXMXZkbVZrSUdaeWIyMGdkR2hsWEc0Z0lDQWdJQ0FnSUM4dklHZHNiMkpoYkNCdVlXMWxjM0JoWTJVdVhHNGdJQ0FnSUNBZ0lHZHNiMkpoYkM1UkxtNXZRMjl1Wm14cFkzUWdQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JuYkc5aVlXd3VVU0E5SUhCeVpYWnBiM1Z6VVR0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQjBhR2x6TzF4dUlDQWdJQ0FnSUNCOU8xeHVYRzRnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUNBZ2RHaHliM2NnYm1WM0lFVnljbTl5S0Z3aVZHaHBjeUJsYm5acGNtOXViV1Z1ZENCM1lYTWdibTkwSUdGdWRHbGphWEJoZEdWa0lHSjVJRkV1SUZCc1pXRnpaU0JtYVd4bElHRWdZblZuTGx3aUtUdGNiaUFnSUNCOVhHNWNibjBwS0daMWJtTjBhVzl1SUNncElIdGNibHdpZFhObElITjBjbWxqZEZ3aU8xeHVYRzUyWVhJZ2FHRnpVM1JoWTJ0eklEMGdabUZzYzJVN1hHNTBjbmtnZTF4dUlDQWdJSFJvY205M0lHNWxkeUJGY25KdmNpZ3BPMXh1ZlNCallYUmphQ0FvWlNrZ2UxeHVJQ0FnSUdoaGMxTjBZV05yY3lBOUlDRWhaUzV6ZEdGamF6dGNibjFjYmx4dUx5OGdRV3hzSUdOdlpHVWdZV1owWlhJZ2RHaHBjeUJ3YjJsdWRDQjNhV3hzSUdKbElHWnBiSFJsY21Wa0lHWnliMjBnYzNSaFkyc2dkSEpoWTJWeklISmxjRzl5ZEdWa1hHNHZMeUJpZVNCUkxseHVkbUZ5SUhGVGRHRnlkR2x1WjB4cGJtVWdQU0JqWVhCMGRYSmxUR2x1WlNncE8xeHVkbUZ5SUhGR2FXeGxUbUZ0WlR0Y2JseHVMeThnYzJocGJYTmNibHh1THk4Z2RYTmxaQ0JtYjNJZ1ptRnNiR0poWTJzZ2FXNGdYQ0poYkd4U1pYTnZiSFpsWkZ3aVhHNTJZWElnYm05dmNDQTlJR1oxYm1OMGFXOXVJQ2dwSUh0OU8xeHVYRzR2THlCVmMyVWdkR2hsSUdaaGMzUmxjM1FnY0c5emMybGliR1VnYldWaGJuTWdkRzhnWlhobFkzVjBaU0JoSUhSaGMyc2dhVzRnWVNCbWRYUjFjbVVnZEhWeWJseHVMeThnYjJZZ2RHaGxJR1YyWlc1MElHeHZiM0F1WEc1MllYSWdibVY0ZEZScFkyc2dQU2htZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnTHk4Z2JHbHVhMlZrSUd4cGMzUWdiMllnZEdGemEzTWdLSE5wYm1kc1pTd2dkMmwwYUNCb1pXRmtJRzV2WkdVcFhHNGdJQ0FnZG1GeUlHaGxZV1FnUFNCN2RHRnphem9nZG05cFpDQXdMQ0J1WlhoME9pQnVkV3hzZlR0Y2JpQWdJQ0IyWVhJZ2RHRnBiQ0E5SUdobFlXUTdYRzRnSUNBZ2RtRnlJR1pzZFhOb2FXNW5JRDBnWm1Gc2MyVTdYRzRnSUNBZ2RtRnlJSEpsY1hWbGMzUlVhV05ySUQwZ2RtOXBaQ0F3TzF4dUlDQWdJSFpoY2lCcGMwNXZaR1ZLVXlBOUlHWmhiSE5sTzF4dUlDQWdJQzh2SUhGMVpYVmxJR1p2Y2lCc1lYUmxJSFJoYzJ0ekxDQjFjMlZrSUdKNUlIVnVhR0Z1Wkd4bFpDQnlaV3BsWTNScGIyNGdkSEpoWTJ0cGJtZGNiaUFnSUNCMllYSWdiR0YwWlhKUmRXVjFaU0E5SUZ0ZE8xeHVYRzRnSUNBZ1puVnVZM1JwYjI0Z1pteDFjMmdvS1NCN1hHNGdJQ0FnSUNBZ0lDOHFJR3B6YUdsdWRDQnNiMjl3Wm5WdVl6b2dkSEoxWlNBcUwxeHVJQ0FnSUNBZ0lDQjJZWElnZEdGemF5d2daRzl0WVdsdU8xeHVYRzRnSUNBZ0lDQWdJSGRvYVd4bElDaG9aV0ZrTG01bGVIUXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHaGxZV1FnUFNCb1pXRmtMbTVsZUhRN1hHNGdJQ0FnSUNBZ0lDQWdJQ0IwWVhOcklEMGdhR1ZoWkM1MFlYTnJPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2FHVmhaQzUwWVhOcklEMGdkbTlwWkNBd08xeHVJQ0FnSUNBZ0lDQWdJQ0FnWkc5dFlXbHVJRDBnYUdWaFpDNWtiMjFoYVc0N1hHNWNiaUFnSUNBZ0lDQWdJQ0FnSUdsbUlDaGtiMjFoYVc0cElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQm9aV0ZrTG1SdmJXRnBiaUE5SUhadmFXUWdNRHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JrYjIxaGFXNHVaVzUwWlhJb0tUdGNiaUFnSUNBZ0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ0lDQWdJSEoxYmxOcGJtZHNaU2gwWVhOckxDQmtiMjFoYVc0cE8xeHVYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnZDJocGJHVWdLR3hoZEdWeVVYVmxkV1V1YkdWdVozUm9LU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjBZWE5ySUQwZ2JHRjBaWEpSZFdWMVpTNXdiM0FvS1R0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEoxYmxOcGJtZHNaU2gwWVhOcktUdGNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0JtYkhWemFHbHVaeUE5SUdaaGJITmxPMXh1SUNBZ0lIMWNiaUFnSUNBdkx5QnlkVzV6SUdFZ2MybHVaMnhsSUdaMWJtTjBhVzl1SUdsdUlIUm9aU0JoYzNsdVl5QnhkV1YxWlZ4dUlDQWdJR1oxYm1OMGFXOXVJSEoxYmxOcGJtZHNaU2gwWVhOckxDQmtiMjFoYVc0cElIdGNiaUFnSUNBZ0lDQWdkSEo1SUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFJoYzJzb0tUdGNibHh1SUNBZ0lDQWdJQ0I5SUdOaGRHTm9JQ2hsS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JwWmlBb2FYTk9iMlJsU2xNcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQXZMeUJKYmlCdWIyUmxMQ0IxYm1OaGRXZG9kQ0JsZUdObGNIUnBiMjV6SUdGeVpTQmpiMjV6YVdSbGNtVmtJR1poZEdGc0lHVnljbTl5Y3k1Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBdkx5QlNaUzEwYUhKdmR5QjBhR1Z0SUhONWJtTm9jbTl1YjNWemJIa2dkRzhnYVc1MFpYSnlkWEIwSUdac2RYTm9hVzVuSVZ4dVhHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0x5OGdSVzV6ZFhKbElHTnZiblJwYm5WaGRHbHZiaUJwWmlCMGFHVWdkVzVqWVhWbmFIUWdaWGhqWlhCMGFXOXVJR2x6SUhOMWNIQnlaWE56WldSY2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBdkx5QnNhWE4wWlc1cGJtY2dYQ0oxYm1OaGRXZG9kRVY0WTJWd2RHbHZibHdpSUdWMlpXNTBjeUFvWVhNZ1pHOXRZV2x1Y3lCa2IyVnpLUzVjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0F2THlCRGIyNTBhVzUxWlNCcGJpQnVaWGgwSUdWMlpXNTBJSFJ2SUdGMmIybGtJSFJwWTJzZ2NtVmpkWEp6YVc5dUxseHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHbG1JQ2hrYjIxaGFXNHBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ1pHOXRZV2x1TG1WNGFYUW9LVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnYzJWMFZHbHRaVzkxZENobWJIVnphQ3dnTUNrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLR1J2YldGcGJpa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCa2IyMWhhVzR1Wlc1MFpYSW9LVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0I5WEc1Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCMGFISnZkeUJsTzF4dVhHNGdJQ0FnSUNBZ0lDQWdJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQzh2SUVsdUlHSnliM2R6WlhKekxDQjFibU5oZFdkb2RDQmxlR05sY0hScGIyNXpJR0Z5WlNCdWIzUWdabUYwWVd3dVhHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0x5OGdVbVV0ZEdoeWIzY2dkR2hsYlNCaGMzbHVZMmh5YjI1dmRYTnNlU0IwYnlCaGRtOXBaQ0J6Ykc5M0xXUnZkMjV6TGx4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhObGRGUnBiV1Z2ZFhRb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCMGFISnZkeUJsTzF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUgwc0lEQXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQjlYRzVjYmlBZ0lDQWdJQ0FnYVdZZ0tHUnZiV0ZwYmlrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnWkc5dFlXbHVMbVY0YVhRb0tUdGNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lIMWNibHh1SUNBZ0lHNWxlSFJVYVdOcklEMGdablZ1WTNScGIyNGdLSFJoYzJzcElIdGNiaUFnSUNBZ0lDQWdkR0ZwYkNBOUlIUmhhV3d1Ym1WNGRDQTlJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIUmhjMnM2SUhSaGMyc3NYRzRnSUNBZ0lDQWdJQ0FnSUNCa2IyMWhhVzQ2SUdselRtOWtaVXBUSUNZbUlIQnliMk5sYzNNdVpHOXRZV2x1TEZ4dUlDQWdJQ0FnSUNBZ0lDQWdibVY0ZERvZ2JuVnNiRnh1SUNBZ0lDQWdJQ0I5TzF4dVhHNGdJQ0FnSUNBZ0lHbG1JQ2doWm14MWMyaHBibWNwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJR1pzZFhOb2FXNW5JRDBnZEhKMVpUdGNiaUFnSUNBZ0lDQWdJQ0FnSUhKbGNYVmxjM1JVYVdOcktDazdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQjlPMXh1WEc0Z0lDQWdhV1lnS0hSNWNHVnZaaUJ3Y205alpYTnpJRDA5UFNCY0ltOWlhbVZqZEZ3aUlDWW1YRzRnSUNBZ0lDQWdJSEJ5YjJObGMzTXVkRzlUZEhKcGJtY29LU0E5UFQwZ1hDSmJiMkpxWldOMElIQnliMk5sYzNOZFhDSWdKaVlnY0hKdlkyVnpjeTV1WlhoMFZHbGpheWtnZTF4dUlDQWdJQ0FnSUNBdkx5QkZibk4xY21VZ1VTQnBjeUJwYmlCaElISmxZV3dnVG05a1pTQmxiblpwY205dWJXVnVkQ3dnZDJsMGFDQmhJR0J3Y205alpYTnpMbTVsZUhSVWFXTnJZQzVjYmlBZ0lDQWdJQ0FnTHk4Z1ZHOGdjMlZsSUhSb2NtOTFaMmdnWm1GclpTQk9iMlJsSUdWdWRtbHliMjV0Wlc1MGN6cGNiaUFnSUNBZ0lDQWdMeThnS2lCTmIyTm9ZU0IwWlhOMElISjFibTVsY2lBdElHVjRjRzl6WlhNZ1lTQmdjSEp2WTJWemMyQWdaMnh2WW1Gc0lIZHBkR2h2ZFhRZ1lTQmdibVY0ZEZScFkydGdYRzRnSUNBZ0lDQWdJQzh2SUNvZ1FuSnZkM05sY21sbWVTQXRJR1Y0Y0c5elpYTWdZU0JnY0hKdlkyVnpjeTV1WlhoVWFXTnJZQ0JtZFc1amRHbHZiaUIwYUdGMElIVnpaWE5jYmlBZ0lDQWdJQ0FnTHk4Z0lDQmdjMlYwVkdsdFpXOTFkR0F1SUVsdUlIUm9hWE1nWTJGelpTQmdjMlYwU1cxdFpXUnBZWFJsWUNCcGN5QndjbVZtWlhKeVpXUWdZbVZqWVhWelpWeHVJQ0FnSUNBZ0lDQXZMeUFnSUNCcGRDQnBjeUJtWVhOMFpYSXVJRUp5YjNkelpYSnBabmtuY3lCZ2NISnZZMlZ6Y3k1MGIxTjBjbWx1WnlncFlDQjVhV1ZzWkhOY2JpQWdJQ0FnSUNBZ0x5OGdJQ0JjSWx0dlltcGxZM1FnVDJKcVpXTjBYVndpTENCM2FHbHNaU0JwYmlCaElISmxZV3dnVG05a1pTQmxiblpwY205dWJXVnVkRnh1SUNBZ0lDQWdJQ0F2THlBZ0lHQndjbTlqWlhOekxtNWxlSFJVYVdOcktDbGdJSGxwWld4a2N5QmNJbHR2WW1wbFkzUWdjSEp2WTJWemMxMWNJaTVjYmlBZ0lDQWdJQ0FnYVhOT2IyUmxTbE1nUFNCMGNuVmxPMXh1WEc0Z0lDQWdJQ0FnSUhKbGNYVmxjM1JVYVdOcklEMGdablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjSEp2WTJWemN5NXVaWGgwVkdsamF5aG1iSFZ6YUNrN1hHNGdJQ0FnSUNBZ0lIMDdYRzVjYmlBZ0lDQjlJR1ZzYzJVZ2FXWWdLSFI1Y0dWdlppQnpaWFJKYlcxbFpHbGhkR1VnUFQwOUlGd2lablZ1WTNScGIyNWNJaWtnZTF4dUlDQWdJQ0FnSUNBdkx5QkpiaUJKUlRFd0xDQk9iMlJsTG1weklEQXVPU3NzSUc5eUlHaDBkSEJ6T2k4dloybDBhSFZpTG1OdmJTOU9iMkpzWlVwVEwzTmxkRWx0YldWa2FXRjBaVnh1SUNBZ0lDQWdJQ0JwWmlBb2RIbHdaVzltSUhkcGJtUnZkeUFoUFQwZ1hDSjFibVJsWm1sdVpXUmNJaWtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjbVZ4ZFdWemRGUnBZMnNnUFNCelpYUkpiVzFsWkdsaGRHVXVZbWx1WkNoM2FXNWtiM2NzSUdac2RYTm9LVHRjYmlBZ0lDQWdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lISmxjWFZsYzNSVWFXTnJJRDBnWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lITmxkRWx0YldWa2FXRjBaU2htYkhWemFDazdYRzRnSUNBZ0lDQWdJQ0FnSUNCOU8xeHVJQ0FnSUNBZ0lDQjlYRzVjYmlBZ0lDQjlJR1ZzYzJVZ2FXWWdLSFI1Y0dWdlppQk5aWE56WVdkbFEyaGhibTVsYkNBaFBUMGdYQ0oxYm1SbFptbHVaV1JjSWlrZ2UxeHVJQ0FnSUNBZ0lDQXZMeUJ0YjJSbGNtNGdZbkp2ZDNObGNuTmNiaUFnSUNBZ0lDQWdMeThnYUhSMGNEb3ZMM2QzZHk1dWIyNWliRzlqYTJsdVp5NXBieTh5TURFeEx6QTJMM2RwYm1SdmQyNWxlSFIwYVdOckxtaDBiV3hjYmlBZ0lDQWdJQ0FnZG1GeUlHTm9ZVzV1Wld3Z1BTQnVaWGNnVFdWemMyRm5aVU5vWVc1dVpXd29LVHRjYmlBZ0lDQWdJQ0FnTHk4Z1FYUWdiR1ZoYzNRZ1UyRm1ZWEpwSUZabGNuTnBiMjRnTmk0d0xqVWdLRGcxTXpZdU16QXVNU2tnYVc1MFpYSnRhWFIwWlc1MGJIa2dZMkZ1Ym05MElHTnlaV0YwWlZ4dUlDQWdJQ0FnSUNBdkx5QjNiM0pyYVc1bklHMWxjM05oWjJVZ2NHOXlkSE1nZEdobElHWnBjbk4wSUhScGJXVWdZU0J3WVdkbElHeHZZV1J6TGx4dUlDQWdJQ0FnSUNCamFHRnVibVZzTG5CdmNuUXhMbTl1YldWemMyRm5aU0E5SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhKbGNYVmxjM1JVYVdOcklEMGdjbVZ4ZFdWemRGQnZjblJVYVdOck8xeHVJQ0FnSUNBZ0lDQWdJQ0FnWTJoaGJtNWxiQzV3YjNKME1TNXZibTFsYzNOaFoyVWdQU0JtYkhWemFEdGNiaUFnSUNBZ0lDQWdJQ0FnSUdac2RYTm9LQ2s3WEc0Z0lDQWdJQ0FnSUgwN1hHNGdJQ0FnSUNBZ0lIWmhjaUJ5WlhGMVpYTjBVRzl5ZEZScFkyc2dQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0F2THlCUGNHVnlZU0J5WlhGMWFYSmxjeUIxY3lCMGJ5QndjbTkyYVdSbElHRWdiV1Z6YzJGblpTQndZWGxzYjJGa0xDQnlaV2RoY21Sc1pYTnpJRzltWEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUIzYUdWMGFHVnlJSGRsSUhWelpTQnBkQzVjYmlBZ0lDQWdJQ0FnSUNBZ0lHTm9ZVzV1Wld3dWNHOXlkREl1Y0c5emRFMWxjM05oWjJVb01DazdYRzRnSUNBZ0lDQWdJSDA3WEc0Z0lDQWdJQ0FnSUhKbGNYVmxjM1JVYVdOcklEMGdablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjMlYwVkdsdFpXOTFkQ2htYkhWemFDd2dNQ2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnlaWEYxWlhOMFVHOXlkRlJwWTJzb0tUdGNiaUFnSUNBZ0lDQWdmVHRjYmx4dUlDQWdJSDBnWld4elpTQjdYRzRnSUNBZ0lDQWdJQzh2SUc5c1pDQmljbTkzYzJWeWMxeHVJQ0FnSUNBZ0lDQnlaWEYxWlhOMFZHbGpheUE5SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhObGRGUnBiV1Z2ZFhRb1pteDFjMmdzSURBcE8xeHVJQ0FnSUNBZ0lDQjlPMXh1SUNBZ0lIMWNiaUFnSUNBdkx5QnlkVzV6SUdFZ2RHRnpheUJoWm5SbGNpQmhiR3dnYjNSb1pYSWdkR0Z6YTNNZ2FHRjJaU0JpWldWdUlISjFibHh1SUNBZ0lDOHZJSFJvYVhNZ2FYTWdkWE5sWm5Wc0lHWnZjaUIxYm1oaGJtUnNaV1FnY21WcVpXTjBhVzl1SUhSeVlXTnJhVzVuSUhSb1lYUWdibVZsWkhNZ2RHOGdhR0Z3Y0dWdVhHNGdJQ0FnTHk4Z1lXWjBaWElnWVd4c0lHQjBhR1Z1WUdRZ2RHRnphM01nYUdGMlpTQmlaV1Z1SUhKMWJpNWNiaUFnSUNCdVpYaDBWR2xqYXk1eWRXNUJablJsY2lBOUlHWjFibU4wYVc5dUlDaDBZWE5yS1NCN1hHNGdJQ0FnSUNBZ0lHeGhkR1Z5VVhWbGRXVXVjSFZ6YUNoMFlYTnJLVHRjYmlBZ0lDQWdJQ0FnYVdZZ0tDRm1iSFZ6YUdsdVp5a2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ1pteDFjMmhwYm1jZ1BTQjBjblZsTzF4dUlDQWdJQ0FnSUNBZ0lDQWdjbVZ4ZFdWemRGUnBZMnNvS1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUgwN1hHNGdJQ0FnY21WMGRYSnVJRzVsZUhSVWFXTnJPMXh1ZlNrb0tUdGNibHh1THk4Z1FYUjBaVzF3ZENCMGJ5QnRZV3RsSUdkbGJtVnlhV056SUhOaFptVWdhVzRnZEdobElHWmhZMlVnYjJZZ1pHOTNibk4wY21WaGJWeHVMeThnYlc5a2FXWnBZMkYwYVc5dWN5NWNiaTh2SUZSb1pYSmxJR2x6SUc1dklITnBkSFZoZEdsdmJpQjNhR1Z5WlNCMGFHbHpJR2x6SUc1bFkyVnpjMkZ5ZVM1Y2JpOHZJRWxtSUhsdmRTQnVaV1ZrSUdFZ2MyVmpkWEpwZEhrZ1ozVmhjbUZ1ZEdWbExDQjBhR1Z6WlNCd2NtbHRiM0prYVdGc2N5QnVaV1ZrSUhSdklHSmxYRzR2THlCa1pXVndiSGtnWm5KdmVtVnVJR0Z1ZVhkaGVTd2dZVzVrSUdsbUlIbHZkU0JrYjI3aWdKbDBJRzVsWldRZ1lTQnpaV04xY21sMGVTQm5kV0Z5WVc1MFpXVXNYRzR2THlCMGFHbHpJR2x6SUdwMWMzUWdjR3hoYVc0Z2NHRnlZVzV2YVdRdVhHNHZMeUJJYjNkbGRtVnlMQ0IwYUdseklDb3FiV2xuYUhRcUtpQm9ZWFpsSUhSb1pTQnVhV05sSUhOcFpHVXRaV1ptWldOMElHOW1JSEpsWkhWamFXNW5JSFJvWlNCemFYcGxJRzltWEc0dkx5QjBhR1VnYldsdWFXWnBaV1FnWTI5a1pTQmllU0J5WldSMVkybHVaeUI0TG1OaGJHd29LU0IwYnlCdFpYSmxiSGtnZUNncFhHNHZMeUJUWldVZ1RXRnlheUJOYVd4c1pYTGlnSmx6SUdWNGNHeGhibUYwYVc5dUlHOW1JSGRvWVhRZ2RHaHBjeUJrYjJWekxseHVMeThnYUhSMGNEb3ZMM2RwYTJrdVpXTnRZWE5qY21sd2RDNXZjbWN2Wkc5cmRTNXdhSEEvYVdROVkyOXVkbVZ1ZEdsdmJuTTZjMkZtWlY5dFpYUmhYM0J5YjJkeVlXMXRhVzVuWEc1MllYSWdZMkZzYkNBOUlFWjFibU4wYVc5dUxtTmhiR3c3WEc1bWRXNWpkR2x2YmlCMWJtTjFjbko1VkdocGN5aG1LU0I3WEc0Z0lDQWdjbVYwZFhKdUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR05oYkd3dVlYQndiSGtvWml3Z1lYSm5kVzFsYm5SektUdGNiaUFnSUNCOU8xeHVmVnh1THk4Z1ZHaHBjeUJwY3lCbGNYVnBkbUZzWlc1MExDQmlkWFFnYzJ4dmQyVnlPbHh1THk4Z2RXNWpkWEp5ZVZSb2FYTWdQU0JHZFc1amRHbHZibDlpYVc1a0xtSnBibVFvUm5WdVkzUnBiMjVmWW1sdVpDNWpZV3hzS1R0Y2JpOHZJR2gwZEhBNkx5OXFjM0JsY21ZdVkyOXRMM1Z1WTNWeWNubDBhR2x6WEc1Y2JuWmhjaUJoY25KaGVWOXpiR2xqWlNBOUlIVnVZM1Z5Y25sVWFHbHpLRUZ5Y21GNUxuQnliM1J2ZEhsd1pTNXpiR2xqWlNrN1hHNWNiblpoY2lCaGNuSmhlVjl5WldSMVkyVWdQU0IxYm1OMWNuSjVWR2hwY3loY2JpQWdJQ0JCY25KaGVTNXdjbTkwYjNSNWNHVXVjbVZrZFdObElIeDhJR1oxYm1OMGFXOXVJQ2hqWVd4c1ltRmpheXdnWW1GemFYTXBJSHRjYmlBZ0lDQWdJQ0FnZG1GeUlHbHVaR1Y0SUQwZ01DeGNiaUFnSUNBZ0lDQWdJQ0FnSUd4bGJtZDBhQ0E5SUhSb2FYTXViR1Z1WjNSb08xeHVJQ0FnSUNBZ0lDQXZMeUJqYjI1alpYSnVhVzVuSUhSb1pTQnBibWwwYVdGc0lIWmhiSFZsTENCcFppQnZibVVnYVhNZ2JtOTBJSEJ5YjNacFpHVmtYRzRnSUNBZ0lDQWdJR2xtSUNoaGNtZDFiV1Z1ZEhNdWJHVnVaM1JvSUQwOVBTQXhLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUJ6WldWcklIUnZJSFJvWlNCbWFYSnpkQ0IyWVd4MVpTQnBiaUIwYUdVZ1lYSnlZWGtzSUdGalkyOTFiblJwYm1kY2JpQWdJQ0FnSUNBZ0lDQWdJQzh2SUdadmNpQjBhR1VnY0c5emMybGlhV3hwZEhrZ2RHaGhkQ0JwY3lCcGN5QmhJSE53WVhKelpTQmhjbkpoZVZ4dUlDQWdJQ0FnSUNBZ0lDQWdaRzhnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUdsbUlDaHBibVJsZUNCcGJpQjBhR2x6S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJR0poYzJseklEMGdkR2hwYzF0cGJtUmxlQ3NyWFR0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdZbkpsWVdzN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHbG1JQ2dySzJsdVpHVjRJRDQ5SUd4bGJtZDBhQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjBhSEp2ZHlCdVpYY2dWSGx3WlVWeWNtOXlLQ2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNBZ0lDQWdmU0IzYUdsc1pTQW9NU2s3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ0x5OGdjbVZrZFdObFhHNGdJQ0FnSUNBZ0lHWnZjaUFvT3lCcGJtUmxlQ0E4SUd4bGJtZDBhRHNnYVc1a1pYZ3JLeWtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdMeThnWVdOamIzVnVkQ0JtYjNJZ2RHaGxJSEJ2YzNOcFltbHNhWFI1SUhSb1lYUWdkR2hsSUdGeWNtRjVJR2x6SUhOd1lYSnpaVnh1SUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLR2x1WkdWNElHbHVJSFJvYVhNcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQmlZWE5wY3lBOUlHTmhiR3hpWVdOcktHSmhjMmx6TENCMGFHbHpXMmx1WkdWNFhTd2dhVzVrWlhncE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCaVlYTnBjenRjYmlBZ0lDQjlYRzRwTzF4dVhHNTJZWElnWVhKeVlYbGZhVzVrWlhoUFppQTlJSFZ1WTNWeWNubFVhR2x6S0Z4dUlDQWdJRUZ5Y21GNUxuQnliM1J2ZEhsd1pTNXBibVJsZUU5bUlIeDhJR1oxYm1OMGFXOXVJQ2gyWVd4MVpTa2dlMXh1SUNBZ0lDQWdJQ0F2THlCdWIzUWdZU0IyWlhKNUlHZHZiMlFnYzJocGJTd2dZblYwSUdkdmIyUWdaVzV2ZFdkb0lHWnZjaUJ2ZFhJZ2IyNWxJSFZ6WlNCdlppQnBkRnh1SUNBZ0lDQWdJQ0JtYjNJZ0tIWmhjaUJwSUQwZ01Ec2dhU0E4SUhSb2FYTXViR1Z1WjNSb095QnBLeXNwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJR2xtSUNoMGFHbHpXMmxkSUQwOVBTQjJZV3gxWlNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lISmxkSFZ5YmlCcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlBdE1UdGNiaUFnSUNCOVhHNHBPMXh1WEc1MllYSWdZWEp5WVhsZmJXRndJRDBnZFc1amRYSnllVlJvYVhNb1hHNGdJQ0FnUVhKeVlYa3VjSEp2ZEc5MGVYQmxMbTFoY0NCOGZDQm1kVzVqZEdsdmJpQW9ZMkZzYkdKaFkyc3NJSFJvYVhOd0tTQjdYRzRnSUNBZ0lDQWdJSFpoY2lCelpXeG1JRDBnZEdocGN6dGNiaUFnSUNBZ0lDQWdkbUZ5SUdOdmJHeGxZM1FnUFNCYlhUdGNiaUFnSUNBZ0lDQWdZWEp5WVhsZmNtVmtkV05sS0hObGJHWXNJR1oxYm1OMGFXOXVJQ2gxYm1SbFptbHVaV1FzSUhaaGJIVmxMQ0JwYm1SbGVDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ1kyOXNiR1ZqZEM1d2RYTm9LR05oYkd4aVlXTnJMbU5oYkd3b2RHaHBjM0FzSUhaaGJIVmxMQ0JwYm1SbGVDd2djMlZzWmlrcE8xeHVJQ0FnSUNBZ0lDQjlMQ0IyYjJsa0lEQXBPMXh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdZMjlzYkdWamREdGNiaUFnSUNCOVhHNHBPMXh1WEc1MllYSWdiMkpxWldOMFgyTnlaV0YwWlNBOUlFOWlhbVZqZEM1amNtVmhkR1VnZkh3Z1puVnVZM1JwYjI0Z0tIQnliM1J2ZEhsd1pTa2dlMXh1SUNBZ0lHWjFibU4wYVc5dUlGUjVjR1VvS1NCN0lIMWNiaUFnSUNCVWVYQmxMbkJ5YjNSdmRIbHdaU0E5SUhCeWIzUnZkSGx3WlR0Y2JpQWdJQ0J5WlhSMWNtNGdibVYzSUZSNWNHVW9LVHRjYm4wN1hHNWNiblpoY2lCdlltcGxZM1JmYUdGelQzZHVVSEp2Y0dWeWRIa2dQU0IxYm1OMWNuSjVWR2hwY3loUFltcGxZM1F1Y0hKdmRHOTBlWEJsTG1oaGMwOTNibEJ5YjNCbGNuUjVLVHRjYmx4dWRtRnlJRzlpYW1WamRGOXJaWGx6SUQwZ1QySnFaV04wTG10bGVYTWdmSHdnWm5WdVkzUnBiMjRnS0c5aWFtVmpkQ2tnZTF4dUlDQWdJSFpoY2lCclpYbHpJRDBnVzEwN1hHNGdJQ0FnWm05eUlDaDJZWElnYTJWNUlHbHVJRzlpYW1WamRDa2dlMXh1SUNBZ0lDQWdJQ0JwWmlBb2IySnFaV04wWDJoaGMwOTNibEJ5YjNCbGNuUjVLRzlpYW1WamRDd2dhMlY1S1NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYTJWNWN5NXdkWE5vS0d0bGVTazdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQjlYRzRnSUNBZ2NtVjBkWEp1SUd0bGVYTTdYRzU5TzF4dVhHNTJZWElnYjJKcVpXTjBYM1J2VTNSeWFXNW5JRDBnZFc1amRYSnllVlJvYVhNb1QySnFaV04wTG5CeWIzUnZkSGx3WlM1MGIxTjBjbWx1WnlrN1hHNWNibVoxYm1OMGFXOXVJR2x6VDJKcVpXTjBLSFpoYkhWbEtTQjdYRzRnSUNBZ2NtVjBkWEp1SUhaaGJIVmxJRDA5UFNCUFltcGxZM1FvZG1Gc2RXVXBPMXh1ZlZ4dVhHNHZMeUJuWlc1bGNtRjBiM0lnY21Wc1lYUmxaQ0J6YUdsdGMxeHVYRzR2THlCR1NWaE5SVG9nVW1WdGIzWmxJSFJvYVhNZ1puVnVZM1JwYjI0Z2IyNWpaU0JGVXpZZ1oyVnVaWEpoZEc5eWN5QmhjbVVnYVc0Z1UzQnBaR1Z5VFc5dWEyVjVMbHh1Wm5WdVkzUnBiMjRnYVhOVGRHOXdTWFJsY21GMGFXOXVLR1Y0WTJWd2RHbHZiaWtnZTF4dUlDQWdJSEpsZEhWeWJpQW9YRzRnSUNBZ0lDQWdJRzlpYW1WamRGOTBiMU4wY21sdVp5aGxlR05sY0hScGIyNHBJRDA5UFNCY0lsdHZZbXBsWTNRZ1UzUnZjRWwwWlhKaGRHbHZibDFjSWlCOGZGeHVJQ0FnSUNBZ0lDQmxlR05sY0hScGIyNGdhVzV6ZEdGdVkyVnZaaUJSVW1WMGRYSnVWbUZzZFdWY2JpQWdJQ0FwTzF4dWZWeHVYRzR2THlCR1NWaE5SVG9nVW1WdGIzWmxJSFJvYVhNZ2FHVnNjR1Z5SUdGdVpDQlJMbkpsZEhWeWJpQnZibU5sSUVWVE5pQm5aVzVsY21GMGIzSnpJR0Z5WlNCcGJseHVMeThnVTNCcFpHVnlUVzl1YTJWNUxseHVkbUZ5SUZGU1pYUjFjbTVXWVd4MVpUdGNibWxtSUNoMGVYQmxiMllnVW1WMGRYSnVWbUZzZFdVZ0lUMDlJRndpZFc1a1pXWnBibVZrWENJcElIdGNiaUFnSUNCUlVtVjBkWEp1Vm1Gc2RXVWdQU0JTWlhSMWNtNVdZV3gxWlR0Y2JuMGdaV3h6WlNCN1hHNGdJQ0FnVVZKbGRIVnlibFpoYkhWbElEMGdablZ1WTNScGIyNGdLSFpoYkhWbEtTQjdYRzRnSUNBZ0lDQWdJSFJvYVhNdWRtRnNkV1VnUFNCMllXeDFaVHRjYmlBZ0lDQjlPMXh1ZlZ4dVhHNHZMeUJzYjI1bklITjBZV05ySUhSeVlXTmxjMXh1WEc1MllYSWdVMVJCUTB0ZlNsVk5VRjlUUlZCQlVrRlVUMUlnUFNCY0lrWnliMjBnY0hKbGRtbHZkWE1nWlhabGJuUTZYQ0k3WEc1Y2JtWjFibU4wYVc5dUlHMWhhMlZUZEdGamExUnlZV05sVEc5dVp5aGxjbkp2Y2l3Z2NISnZiV2x6WlNrZ2UxeHVJQ0FnSUM4dklFbG1JSEJ2YzNOcFlteGxMQ0IwY21GdWMyWnZjbTBnZEdobElHVnljbTl5SUhOMFlXTnJJSFJ5WVdObElHSjVJSEpsYlc5MmFXNW5JRTV2WkdVZ1lXNWtJRkZjYmlBZ0lDQXZMeUJqY25WbWRDd2dkR2hsYmlCamIyNWpZWFJsYm1GMGFXNW5JSGRwZEdnZ2RHaGxJSE4wWVdOcklIUnlZV05sSUc5bUlHQndjbTl0YVhObFlDNGdVMlZsSUNNMU55NWNiaUFnSUNCcFppQW9hR0Z6VTNSaFkydHpJQ1ltWEc0Z0lDQWdJQ0FnSUhCeWIyMXBjMlV1YzNSaFkyc2dKaVpjYmlBZ0lDQWdJQ0FnZEhsd1pXOW1JR1Z5Y205eUlEMDlQU0JjSW05aWFtVmpkRndpSUNZbVhHNGdJQ0FnSUNBZ0lHVnljbTl5SUNFOVBTQnVkV3hzSUNZbVhHNGdJQ0FnSUNBZ0lHVnljbTl5TG5OMFlXTnJJQ1ltWEc0Z0lDQWdJQ0FnSUdWeWNtOXlMbk4wWVdOckxtbHVaR1Y0VDJZb1UxUkJRMHRmU2xWTlVGOVRSVkJCVWtGVVQxSXBJRDA5UFNBdE1WeHVJQ0FnSUNrZ2UxeHVJQ0FnSUNBZ0lDQjJZWElnYzNSaFkydHpJRDBnVzEwN1hHNGdJQ0FnSUNBZ0lHWnZjaUFvZG1GeUlIQWdQU0J3Y205dGFYTmxPeUFoSVhBN0lIQWdQU0J3TG5OdmRYSmpaU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdhV1lnS0hBdWMzUmhZMnNwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCemRHRmphM011ZFc1emFHbG1kQ2h3TG5OMFlXTnJLVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0J6ZEdGamEzTXVkVzV6YUdsbWRDaGxjbkp2Y2k1emRHRmpheWs3WEc1Y2JpQWdJQ0FnSUNBZ2RtRnlJR052Ym1OaGRHVmtVM1JoWTJ0eklEMGdjM1JoWTJ0ekxtcHZhVzRvWENKY1hHNWNJaUFySUZOVVFVTkxYMHBWVFZCZlUwVlFRVkpCVkU5U0lDc2dYQ0pjWEc1Y0lpazdYRzRnSUNBZ0lDQWdJR1Z5Y205eUxuTjBZV05ySUQwZ1ptbHNkR1Z5VTNSaFkydFRkSEpwYm1jb1kyOXVZMkYwWldSVGRHRmphM01wTzF4dUlDQWdJSDFjYm4xY2JseHVablZ1WTNScGIyNGdabWxzZEdWeVUzUmhZMnRUZEhKcGJtY29jM1JoWTJ0VGRISnBibWNwSUh0Y2JpQWdJQ0IyWVhJZ2JHbHVaWE1nUFNCemRHRmphMU4wY21sdVp5NXpjR3hwZENoY0lseGNibHdpS1R0Y2JpQWdJQ0IyWVhJZ1pHVnphWEpsWkV4cGJtVnpJRDBnVzEwN1hHNGdJQ0FnWm05eUlDaDJZWElnYVNBOUlEQTdJR2tnUENCc2FXNWxjeTVzWlc1bmRHZzdJQ3NyYVNrZ2UxeHVJQ0FnSUNBZ0lDQjJZWElnYkdsdVpTQTlJR3hwYm1WelcybGRPMXh1WEc0Z0lDQWdJQ0FnSUdsbUlDZ2hhWE5KYm5SbGNtNWhiRVp5WVcxbEtHeHBibVVwSUNZbUlDRnBjMDV2WkdWR2NtRnRaU2hzYVc1bEtTQW1KaUJzYVc1bEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCa1pYTnBjbVZrVEdsdVpYTXVjSFZ6YUNoc2FXNWxLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJSDFjYmlBZ0lDQnlaWFIxY200Z1pHVnphWEpsWkV4cGJtVnpMbXB2YVc0b1hDSmNYRzVjSWlrN1hHNTlYRzVjYm1aMWJtTjBhVzl1SUdselRtOWtaVVp5WVcxbEtITjBZV05yVEdsdVpTa2dlMXh1SUNBZ0lISmxkSFZ5YmlCemRHRmphMHhwYm1VdWFXNWtaWGhQWmloY0lpaHRiMlIxYkdVdWFuTTZYQ0lwSUNFOVBTQXRNU0I4ZkZ4dUlDQWdJQ0FnSUNBZ0lDQnpkR0ZqYTB4cGJtVXVhVzVrWlhoUFppaGNJaWh1YjJSbExtcHpPbHdpS1NBaFBUMGdMVEU3WEc1OVhHNWNibVoxYm1OMGFXOXVJR2RsZEVacGJHVk9ZVzFsUVc1a1RHbHVaVTUxYldKbGNpaHpkR0ZqYTB4cGJtVXBJSHRjYmlBZ0lDQXZMeUJPWVcxbFpDQm1kVzVqZEdsdmJuTTZJRndpWVhRZ1puVnVZM1JwYjI1T1lXMWxJQ2htYVd4bGJtRnRaVHBzYVc1bFRuVnRZbVZ5T21OdmJIVnRiazUxYldKbGNpbGNJbHh1SUNBZ0lDOHZJRWx1SUVsRk1UQWdablZ1WTNScGIyNGdibUZ0WlNCallXNGdhR0YyWlNCemNHRmpaWE1nS0Z3aVFXNXZibmx0YjNWeklHWjFibU4wYVc5dVhDSXBJRTlmYjF4dUlDQWdJSFpoY2lCaGRIUmxiWEIwTVNBOUlDOWhkQ0F1S3lCY1hDZ29MaXNwT2loY1hHUXJLVG9vUHpwY1hHUXJLVnhjS1NRdkxtVjRaV01vYzNSaFkydE1hVzVsS1R0Y2JpQWdJQ0JwWmlBb1lYUjBaVzF3ZERFcElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlGdGhkSFJsYlhCME1Wc3hYU3dnVG5WdFltVnlLR0YwZEdWdGNIUXhXekpkS1YwN1hHNGdJQ0FnZlZ4dVhHNGdJQ0FnTHk4Z1FXNXZibmx0YjNWeklHWjFibU4wYVc5dWN6b2dYQ0poZENCbWFXeGxibUZ0WlRwc2FXNWxUblZ0WW1WeU9tTnZiSFZ0Yms1MWJXSmxjbHdpWEc0Z0lDQWdkbUZ5SUdGMGRHVnRjSFF5SUQwZ0wyRjBJQ2hiWGlCZEt5azZLRnhjWkNzcE9pZy9PbHhjWkNzcEpDOHVaWGhsWXloemRHRmphMHhwYm1VcE8xeHVJQ0FnSUdsbUlDaGhkSFJsYlhCME1pa2dlMXh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdXMkYwZEdWdGNIUXlXekZkTENCT2RXMWlaWElvWVhSMFpXMXdkREpiTWwwcFhUdGNiaUFnSUNCOVhHNWNiaUFnSUNBdkx5QkdhWEpsWm05NElITjBlV3hsT2lCY0ltWjFibU4wYVc5dVFHWnBiR1Z1WVcxbE9teHBibVZPZFcxaVpYSWdiM0lnUUdacGJHVnVZVzFsT214cGJtVk9kVzFpWlhKY0lseHVJQ0FnSUhaaGNpQmhkSFJsYlhCME15QTlJQzh1S2tBb0xpc3BPaWhjWEdRcktTUXZMbVY0WldNb2MzUmhZMnRNYVc1bEtUdGNiaUFnSUNCcFppQW9ZWFIwWlcxd2RETXBJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJRnRoZEhSbGJYQjBNMXN4WFN3Z1RuVnRZbVZ5S0dGMGRHVnRjSFF6V3pKZEtWMDdYRzRnSUNBZ2ZWeHVmVnh1WEc1bWRXNWpkR2x2YmlCcGMwbHVkR1Z5Ym1Gc1JuSmhiV1VvYzNSaFkydE1hVzVsS1NCN1hHNGdJQ0FnZG1GeUlHWnBiR1ZPWVcxbFFXNWtUR2x1WlU1MWJXSmxjaUE5SUdkbGRFWnBiR1ZPWVcxbFFXNWtUR2x1WlU1MWJXSmxjaWh6ZEdGamEweHBibVVwTzF4dVhHNGdJQ0FnYVdZZ0tDRm1hV3hsVG1GdFpVRnVaRXhwYm1WT2RXMWlaWElwSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUdaaGJITmxPMXh1SUNBZ0lIMWNibHh1SUNBZ0lIWmhjaUJtYVd4bFRtRnRaU0E5SUdacGJHVk9ZVzFsUVc1a1RHbHVaVTUxYldKbGNsc3dYVHRjYmlBZ0lDQjJZWElnYkdsdVpVNTFiV0psY2lBOUlHWnBiR1ZPWVcxbFFXNWtUR2x1WlU1MWJXSmxjbHN4WFR0Y2JseHVJQ0FnSUhKbGRIVnliaUJtYVd4bFRtRnRaU0E5UFQwZ2NVWnBiR1ZPWVcxbElDWW1YRzRnSUNBZ0lDQWdJR3hwYm1WT2RXMWlaWElnUGowZ2NWTjBZWEowYVc1blRHbHVaU0FtSmx4dUlDQWdJQ0FnSUNCc2FXNWxUblZ0WW1WeUlEdzlJSEZGYm1ScGJtZE1hVzVsTzF4dWZWeHVYRzR2THlCa2FYTmpiM1psY2lCdmQyNGdabWxzWlNCdVlXMWxJR0Z1WkNCc2FXNWxJRzUxYldKbGNpQnlZVzVuWlNCbWIzSWdabWxzZEdWeWFXNW5JSE4wWVdOclhHNHZMeUIwY21GalpYTmNibVoxYm1OMGFXOXVJR05oY0hSMWNtVk1hVzVsS0NrZ2UxeHVJQ0FnSUdsbUlDZ2hhR0Z6VTNSaFkydHpLU0I3WEc0Z0lDQWdJQ0FnSUhKbGRIVnlianRjYmlBZ0lDQjlYRzVjYmlBZ0lDQjBjbmtnZTF4dUlDQWdJQ0FnSUNCMGFISnZkeUJ1WlhjZ1JYSnliM0lvS1R0Y2JpQWdJQ0I5SUdOaGRHTm9JQ2hsS1NCN1hHNGdJQ0FnSUNBZ0lIWmhjaUJzYVc1bGN5QTlJR1V1YzNSaFkyc3VjM0JzYVhRb1hDSmNYRzVjSWlrN1hHNGdJQ0FnSUNBZ0lIWmhjaUJtYVhKemRFeHBibVVnUFNCc2FXNWxjMXN3WFM1cGJtUmxlRTltS0Z3aVFGd2lLU0ErSURBZ1B5QnNhVzVsYzFzeFhTQTZJR3hwYm1Weld6SmRPMXh1SUNBZ0lDQWdJQ0IyWVhJZ1ptbHNaVTVoYldWQmJtUk1hVzVsVG5WdFltVnlJRDBnWjJWMFJtbHNaVTVoYldWQmJtUk1hVzVsVG5WdFltVnlLR1pwY25OMFRHbHVaU2s3WEc0Z0lDQWdJQ0FnSUdsbUlDZ2habWxzWlU1aGJXVkJibVJNYVc1bFRuVnRZbVZ5S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNDdYRzRnSUNBZ0lDQWdJSDFjYmx4dUlDQWdJQ0FnSUNCeFJtbHNaVTVoYldVZ1BTQm1hV3hsVG1GdFpVRnVaRXhwYm1WT2RXMWlaWEpiTUYwN1hHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCbWFXeGxUbUZ0WlVGdVpFeHBibVZPZFcxaVpYSmJNVjA3WEc0Z0lDQWdmVnh1ZlZ4dVhHNW1kVzVqZEdsdmJpQmtaWEJ5WldOaGRHVW9ZMkZzYkdKaFkyc3NJRzVoYldVc0lHRnNkR1Z5Ym1GMGFYWmxLU0I3WEc0Z0lDQWdjbVYwZFhKdUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnYVdZZ0tIUjVjR1Z2WmlCamIyNXpiMnhsSUNFOVBTQmNJblZ1WkdWbWFXNWxaRndpSUNZbVhHNGdJQ0FnSUNBZ0lDQWdJQ0IwZVhCbGIyWWdZMjl1YzI5c1pTNTNZWEp1SUQwOVBTQmNJbVoxYm1OMGFXOXVYQ0lwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJR052Ym5OdmJHVXVkMkZ5YmlodVlXMWxJQ3NnWENJZ2FYTWdaR1Z3Y21WallYUmxaQ3dnZFhObElGd2lJQ3NnWVd4MFpYSnVZWFJwZG1VZ0sxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lGd2lJR2x1YzNSbFlXUXVYQ0lzSUc1bGR5QkZjbkp2Y2loY0lsd2lLUzV6ZEdGamF5azdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR05oYkd4aVlXTnJMbUZ3Y0d4NUtHTmhiR3hpWVdOckxDQmhjbWQxYldWdWRITXBPMXh1SUNBZ0lIMDdYRzU5WEc1Y2JpOHZJR1Z1WkNCdlppQnphR2x0YzF4dUx5OGdZbVZuYVc1dWFXNW5JRzltSUhKbFlXd2dkMjl5YTF4dVhHNHZLaXBjYmlBcUlFTnZibk4wY25WamRITWdZU0J3Y205dGFYTmxJR1p2Y2lCaGJpQnBiVzFsWkdsaGRHVWdjbVZtWlhKbGJtTmxMQ0J3WVhOelpYTWdjSEp2YldselpYTWdkR2h5YjNWbmFDd2diM0pjYmlBcUlHTnZaWEpqWlhNZ2NISnZiV2x6WlhNZ1puSnZiU0JrYVdabVpYSmxiblFnYzNsemRHVnRjeTVjYmlBcUlFQndZWEpoYlNCMllXeDFaU0JwYlcxbFpHbGhkR1VnY21WbVpYSmxibU5sSUc5eUlIQnliMjFwYzJWY2JpQXFMMXh1Wm5WdVkzUnBiMjRnVVNoMllXeDFaU2tnZTF4dUlDQWdJQzh2SUVsbUlIUm9aU0J2WW1wbFkzUWdhWE1nWVd4eVpXRmtlU0JoSUZCeWIyMXBjMlVzSUhKbGRIVnliaUJwZENCa2FYSmxZM1JzZVM0Z0lGUm9hWE1nWlc1aFlteGxjMXh1SUNBZ0lDOHZJSFJvWlNCeVpYTnZiSFpsSUdaMWJtTjBhVzl1SUhSdklHSnZkR2dnWW1VZ2RYTmxaQ0IwYnlCamNtVmhkR1ZrSUhKbFptVnlaVzVqWlhNZ1puSnZiU0J2WW1wbFkzUnpMRnh1SUNBZ0lDOHZJR0oxZENCMGJ5QjBiMnhsY21GaWJIa2dZMjlsY21ObElHNXZiaTF3Y205dGFYTmxjeUIwYnlCd2NtOXRhWE5sY3k1Y2JpQWdJQ0JwWmlBb2RtRnNkV1VnYVc1emRHRnVZMlZ2WmlCUWNtOXRhWE5sS1NCN1hHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCMllXeDFaVHRjYmlBZ0lDQjlYRzVjYmlBZ0lDQXZMeUJoYzNOcGJXbHNZWFJsSUhSb1pXNWhZbXhsYzF4dUlDQWdJR2xtSUNocGMxQnliMjFwYzJWQmJHbHJaU2gyWVd4MVpTa3BJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR052WlhKalpTaDJZV3gxWlNrN1hHNGdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR1oxYkdacGJHd29kbUZzZFdVcE8xeHVJQ0FnSUgxY2JuMWNibEV1Y21WemIyeDJaU0E5SUZFN1hHNWNiaThxS2x4dUlDb2dVR1Z5Wm05eWJYTWdZU0IwWVhOcklHbHVJR0VnWm5WMGRYSmxJSFIxY200Z2IyWWdkR2hsSUdWMlpXNTBJR3h2YjNBdVhHNGdLaUJBY0dGeVlXMGdlMFoxYm1OMGFXOXVmU0IwWVhOclhHNGdLaTljYmxFdWJtVjRkRlJwWTJzZ1BTQnVaWGgwVkdsamF6dGNibHh1THlvcVhHNGdLaUJEYjI1MGNtOXNjeUIzYUdWMGFHVnlJRzl5SUc1dmRDQnNiMjVuSUhOMFlXTnJJSFJ5WVdObGN5QjNhV3hzSUdKbElHOXVYRzRnS2k5Y2JsRXViRzl1WjFOMFlXTnJVM1Z3Y0c5eWRDQTlJR1poYkhObE8xeHVYRzR2THlCbGJtRmliR1VnYkc5dVp5QnpkR0ZqYTNNZ2FXWWdVVjlFUlVKVlJ5QnBjeUJ6WlhSY2JtbG1JQ2gwZVhCbGIyWWdjSEp2WTJWemN5QTlQVDBnWENKdlltcGxZM1JjSWlBbUppQndjbTlqWlhOeklDWW1JSEJ5YjJObGMzTXVaVzUySUNZbUlIQnliMk5sYzNNdVpXNTJMbEZmUkVWQ1ZVY3BJSHRjYmlBZ0lDQlJMbXh2Ym1kVGRHRmphMU4xY0hCdmNuUWdQU0IwY25WbE8xeHVmVnh1WEc0dktpcGNiaUFxSUVOdmJuTjBjblZqZEhNZ1lTQjdjSEp2YldselpTd2djbVZ6YjJ4MlpTd2djbVZxWldOMGZTQnZZbXBsWTNRdVhHNGdLbHh1SUNvZ1lISmxjMjlzZG1WZ0lHbHpJR0VnWTJGc2JHSmhZMnNnZEc4Z2FXNTJiMnRsSUhkcGRHZ2dZU0J0YjNKbElISmxjMjlzZG1Wa0lIWmhiSFZsSUdadmNpQjBhR1ZjYmlBcUlIQnliMjFwYzJVdUlGUnZJR1oxYkdacGJHd2dkR2hsSUhCeWIyMXBjMlVzSUdsdWRtOXJaU0JnY21WemIyeDJaV0FnZDJsMGFDQmhibmtnZG1Gc2RXVWdkR2hoZENCcGMxeHVJQ29nYm05MElHRWdkR2hsYm1GaWJHVXVJRlJ2SUhKbGFtVmpkQ0IwYUdVZ2NISnZiV2x6WlN3Z2FXNTJiMnRsSUdCeVpYTnZiSFpsWUNCM2FYUm9JR0VnY21WcVpXTjBaV1JjYmlBcUlIUm9aVzVoWW14bExDQnZjaUJwYm5admEyVWdZSEpsYW1WamRHQWdkMmwwYUNCMGFHVWdjbVZoYzI5dUlHUnBjbVZqZEd4NUxpQlVieUJ5WlhOdmJIWmxJSFJvWlZ4dUlDb2djSEp2YldselpTQjBieUJoYm05MGFHVnlJSFJvWlc1aFlteGxMQ0IwYUhWeklIQjFkSFJwYm1jZ2FYUWdhVzRnZEdobElITmhiV1VnYzNSaGRHVXNJR2x1ZG05clpWeHVJQ29nWUhKbGMyOXNkbVZnSUhkcGRHZ2dkR2hoZENCdmRHaGxjaUIwYUdWdVlXSnNaUzVjYmlBcUwxeHVVUzVrWldabGNpQTlJR1JsWm1WeU8xeHVablZ1WTNScGIyNGdaR1ZtWlhJb0tTQjdYRzRnSUNBZ0x5OGdhV1lnWENKdFpYTnpZV2RsYzF3aUlHbHpJR0Z1SUZ3aVFYSnlZWGxjSWl3Z2RHaGhkQ0JwYm1ScFkyRjBaWE1nZEdoaGRDQjBhR1VnY0hKdmJXbHpaU0JvWVhNZ2JtOTBJSGxsZEZ4dUlDQWdJQzh2SUdKbFpXNGdjbVZ6YjJ4MlpXUXVJQ0JKWmlCcGRDQnBjeUJjSW5WdVpHVm1hVzVsWkZ3aUxDQnBkQ0JvWVhNZ1ltVmxiaUJ5WlhOdmJIWmxaQzRnSUVWaFkyaGNiaUFnSUNBdkx5QmxiR1Z0Wlc1MElHOW1JSFJvWlNCdFpYTnpZV2RsY3lCaGNuSmhlU0JwY3lCcGRITmxiR1lnWVc0Z1lYSnlZWGtnYjJZZ1kyOXRjR3hsZEdVZ1lYSm5kVzFsYm5SeklIUnZYRzRnSUNBZ0x5OGdabTl5ZDJGeVpDQjBieUIwYUdVZ2NtVnpiMngyWldRZ2NISnZiV2x6WlM0Z0lGZGxJR052WlhKalpTQjBhR1VnY21WemIyeDFkR2x2YmlCMllXeDFaU0IwYnlCaFhHNGdJQ0FnTHk4Z2NISnZiV2x6WlNCMWMybHVaeUIwYUdVZ1lISmxjMjlzZG1WZ0lHWjFibU4wYVc5dUlHSmxZMkYxYzJVZ2FYUWdhR0Z1Wkd4bGN5QmliM1JvSUdaMWJHeDVYRzRnSUNBZ0x5OGdibTl1TFhSb1pXNWhZbXhsSUhaaGJIVmxjeUJoYm1RZ2IzUm9aWElnZEdobGJtRmliR1Z6SUdkeVlXTmxablZzYkhrdVhHNGdJQ0FnZG1GeUlHMWxjM05oWjJWeklEMGdXMTBzSUhCeWIyZHlaWE56VEdsemRHVnVaWEp6SUQwZ1cxMHNJSEpsYzI5c2RtVmtVSEp2YldselpUdGNibHh1SUNBZ0lIWmhjaUJrWldabGNuSmxaQ0E5SUc5aWFtVmpkRjlqY21WaGRHVW9aR1ZtWlhJdWNISnZkRzkwZVhCbEtUdGNiaUFnSUNCMllYSWdjSEp2YldselpTQTlJRzlpYW1WamRGOWpjbVZoZEdVb1VISnZiV2x6WlM1d2NtOTBiM1I1Y0dVcE8xeHVYRzRnSUNBZ2NISnZiV2x6WlM1d2NtOXRhWE5sUkdsemNHRjBZMmdnUFNCbWRXNWpkR2x2YmlBb2NtVnpiMngyWlN3Z2IzQXNJRzl3WlhKaGJtUnpLU0I3WEc0Z0lDQWdJQ0FnSUhaaGNpQmhjbWR6SUQwZ1lYSnlZWGxmYzJ4cFkyVW9ZWEpuZFcxbGJuUnpLVHRjYmlBZ0lDQWdJQ0FnYVdZZ0tHMWxjM05oWjJWektTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCdFpYTnpZV2RsY3k1d2RYTm9LR0Z5WjNNcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnYVdZZ0tHOXdJRDA5UFNCY0luZG9aVzVjSWlBbUppQnZjR1Z5WVc1a2Mxc3hYU2tnZXlBdkx5QndjbTluY21WemN5QnZjR1Z5WVc1a1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NISnZaM0psYzNOTWFYTjBaVzVsY25NdWNIVnphQ2h2Y0dWeVlXNWtjMXN4WFNrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQlJMbTVsZUhSVWFXTnJLR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCeVpYTnZiSFpsWkZCeWIyMXBjMlV1Y0hKdmJXbHpaVVJwYzNCaGRHTm9MbUZ3Y0d4NUtISmxjMjlzZG1Wa1VISnZiV2x6WlN3Z1lYSm5jeWs3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJSDA3WEc1Y2JpQWdJQ0F2THlCWVdGZ2daR1Z3Y21WallYUmxaRnh1SUNBZ0lIQnliMjFwYzJVdWRtRnNkV1ZQWmlBOUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnYVdZZ0tHMWxjM05oWjJWektTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCeVpYUjFjbTRnY0hKdmJXbHpaVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCMllYSWdibVZoY21WeVZtRnNkV1VnUFNCdVpXRnlaWElvY21WemIyeDJaV1JRY205dGFYTmxLVHRjYmlBZ0lDQWdJQ0FnYVdZZ0tHbHpVSEp2YldselpTaHVaV0Z5WlhKV1lXeDFaU2twSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsYzI5c2RtVmtVSEp2YldselpTQTlJRzVsWVhKbGNsWmhiSFZsT3lBdkx5QnphRzl5ZEdWdUlHTm9ZV2x1WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUc1bFlYSmxjbFpoYkhWbE8xeHVJQ0FnSUgwN1hHNWNiaUFnSUNCd2NtOXRhWE5sTG1sdWMzQmxZM1FnUFNCbWRXNWpkR2x2YmlBb0tTQjdYRzRnSUNBZ0lDQWdJR2xtSUNnaGNtVnpiMngyWldSUWNtOXRhWE5sS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdleUJ6ZEdGMFpUb2dYQ0p3Wlc1a2FXNW5YQ0lnZlR0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQnlaWFIxY200Z2NtVnpiMngyWldSUWNtOXRhWE5sTG1sdWMzQmxZM1FvS1R0Y2JpQWdJQ0I5TzF4dVhHNGdJQ0FnYVdZZ0tGRXViRzl1WjFOMFlXTnJVM1Z3Y0c5eWRDQW1KaUJvWVhOVGRHRmphM01wSUh0Y2JpQWdJQ0FnSUNBZ2RISjVJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIUm9jbTkzSUc1bGR5QkZjbkp2Y2lncE8xeHVJQ0FnSUNBZ0lDQjlJR05oZEdOb0lDaGxLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUJPVDFSRk9pQmtiMjRuZENCMGNua2dkRzhnZFhObElHQkZjbkp2Y2k1allYQjBkWEpsVTNSaFkydFVjbUZqWldBZ2IzSWdkSEpoYm5ObVpYSWdkR2hsWEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUJoWTJObGMzTnZjaUJoY205MWJtUTdJSFJvWVhRZ1kyRjFjMlZ6SUcxbGJXOXllU0JzWldGcmN5QmhjeUJ3WlhJZ1IwZ3RNVEV4TGlCS2RYTjBYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QnlaV2xtZVNCMGFHVWdjM1JoWTJzZ2RISmhZMlVnWVhNZ1lTQnpkSEpwYm1jZ1FWTkJVQzVjYmlBZ0lDQWdJQ0FnSUNBZ0lDOHZYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QkJkQ0IwYUdVZ2MyRnRaU0IwYVcxbExDQmpkWFFnYjJabUlIUm9aU0JtYVhKemRDQnNhVzVsT3lCcGRDZHpJR0ZzZDJGNWN5QnFkWE4wWEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUJjSWx0dlltcGxZM1FnVUhKdmJXbHpaVjFjWEc1Y0lpd2dZWE1nY0dWeUlIUm9aU0JnZEc5VGRISnBibWRnTGx4dUlDQWdJQ0FnSUNBZ0lDQWdjSEp2YldselpTNXpkR0ZqYXlBOUlHVXVjM1JoWTJzdWMzVmljM1J5YVc1bktHVXVjM1JoWTJzdWFXNWtaWGhQWmloY0lseGNibHdpS1NBcklERXBPMXh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdmVnh1WEc0Z0lDQWdMeThnVGs5VVJUb2dkMlVnWkc4Z2RHaGxJR05vWldOcmN5Qm1iM0lnWUhKbGMyOXNkbVZrVUhKdmJXbHpaV0FnYVc0Z1pXRmphQ0J0WlhSb2IyUXNJR2x1YzNSbFlXUWdiMlpjYmlBZ0lDQXZMeUJqYjI1emIyeHBaR0YwYVc1bklIUm9aVzBnYVc1MGJ5QmdZbVZqYjIxbFlDd2djMmx1WTJVZ2IzUm9aWEozYVhObElIZGxKMlFnWTNKbFlYUmxJRzVsZDF4dUlDQWdJQzh2SUhCeWIyMXBjMlZ6SUhkcGRHZ2dkR2hsSUd4cGJtVnpJR0JpWldOdmJXVW9kMmhoZEdWMlpYSW9kbUZzZFdVcEtXQXVJRk5sWlNCbExtY3VJRWRJTFRJMU1pNWNibHh1SUNBZ0lHWjFibU4wYVc5dUlHSmxZMjl0WlNodVpYZFFjbTl0YVhObEtTQjdYRzRnSUNBZ0lDQWdJSEpsYzI5c2RtVmtVSEp2YldselpTQTlJRzVsZDFCeWIyMXBjMlU3WEc0Z0lDQWdJQ0FnSUhCeWIyMXBjMlV1YzI5MWNtTmxJRDBnYm1WM1VISnZiV2x6WlR0Y2JseHVJQ0FnSUNBZ0lDQmhjbkpoZVY5eVpXUjFZMlVvYldWemMyRm5aWE1zSUdaMWJtTjBhVzl1SUNoMWJtUmxabWx1WldRc0lHMWxjM05oWjJVcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUZFdWJtVjRkRlJwWTJzb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJRzVsZDFCeWIyMXBjMlV1Y0hKdmJXbHpaVVJwYzNCaGRHTm9MbUZ3Y0d4NUtHNWxkMUJ5YjIxcGMyVXNJRzFsYzNOaFoyVXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZTazdYRzRnSUNBZ0lDQWdJSDBzSUhadmFXUWdNQ2s3WEc1Y2JpQWdJQ0FnSUNBZ2JXVnpjMkZuWlhNZ1BTQjJiMmxrSURBN1hHNGdJQ0FnSUNBZ0lIQnliMmR5WlhOelRHbHpkR1Z1WlhKeklEMGdkbTlwWkNBd08xeHVJQ0FnSUgxY2JseHVJQ0FnSUdSbFptVnljbVZrTG5CeWIyMXBjMlVnUFNCd2NtOXRhWE5sTzF4dUlDQWdJR1JsWm1WeWNtVmtMbkpsYzI5c2RtVWdQU0JtZFc1amRHbHZiaUFvZG1Gc2RXVXBJSHRjYmlBZ0lDQWdJQ0FnYVdZZ0tISmxjMjlzZG1Wa1VISnZiV2x6WlNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVPMXh1SUNBZ0lDQWdJQ0I5WEc1Y2JpQWdJQ0FnSUNBZ1ltVmpiMjFsS0ZFb2RtRnNkV1VwS1R0Y2JpQWdJQ0I5TzF4dVhHNGdJQ0FnWkdWbVpYSnlaV1F1Wm5Wc1ptbHNiQ0E5SUdaMWJtTjBhVzl1SUNoMllXeDFaU2tnZTF4dUlDQWdJQ0FnSUNCcFppQW9jbVZ6YjJ4MlpXUlFjbTl0YVhObEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCeVpYUjFjbTQ3WEc0Z0lDQWdJQ0FnSUgxY2JseHVJQ0FnSUNBZ0lDQmlaV052YldVb1puVnNabWxzYkNoMllXeDFaU2twTzF4dUlDQWdJSDA3WEc0Z0lDQWdaR1ZtWlhKeVpXUXVjbVZxWldOMElEMGdablZ1WTNScGIyNGdLSEpsWVhOdmJpa2dlMXh1SUNBZ0lDQWdJQ0JwWmlBb2NtVnpiMngyWldSUWNtOXRhWE5sS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNDdYRzRnSUNBZ0lDQWdJSDFjYmx4dUlDQWdJQ0FnSUNCaVpXTnZiV1VvY21WcVpXTjBLSEpsWVhOdmJpa3BPMXh1SUNBZ0lIMDdYRzRnSUNBZ1pHVm1aWEp5WldRdWJtOTBhV1o1SUQwZ1puVnVZM1JwYjI0Z0tIQnliMmR5WlhOektTQjdYRzRnSUNBZ0lDQWdJR2xtSUNoeVpYTnZiSFpsWkZCeWIyMXBjMlVwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJqdGNiaUFnSUNBZ0lDQWdmVnh1WEc0Z0lDQWdJQ0FnSUdGeWNtRjVYM0psWkhWalpTaHdjbTluY21WemMweHBjM1JsYm1WeWN5d2dablZ1WTNScGIyNGdLSFZ1WkdWbWFXNWxaQ3dnY0hKdlozSmxjM05NYVhOMFpXNWxjaWtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdVUzV1WlhoMFZHbGpheWhtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NISnZaM0psYzNOTWFYTjBaVzVsY2lod2NtOW5jbVZ6Y3lrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5S1R0Y2JpQWdJQ0FnSUNBZ2ZTd2dkbTlwWkNBd0tUdGNiaUFnSUNCOU8xeHVYRzRnSUNBZ2NtVjBkWEp1SUdSbFptVnljbVZrTzF4dWZWeHVYRzR2S2lwY2JpQXFJRU55WldGMFpYTWdZU0JPYjJSbExYTjBlV3hsSUdOaGJHeGlZV05ySUhSb1lYUWdkMmxzYkNCeVpYTnZiSFpsSUc5eUlISmxhbVZqZENCMGFHVWdaR1ZtWlhKeVpXUmNiaUFxSUhCeWIyMXBjMlV1WEc0Z0tpQkFjbVYwZFhKdWN5QmhJRzV2WkdWaVlXTnJYRzRnS2k5Y2JtUmxabVZ5TG5CeWIzUnZkSGx3WlM1dFlXdGxUbTlrWlZKbGMyOXNkbVZ5SUQwZ1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lIWmhjaUJ6Wld4bUlEMGdkR2hwY3p0Y2JpQWdJQ0J5WlhSMWNtNGdablZ1WTNScGIyNGdLR1Z5Y205eUxDQjJZV3gxWlNrZ2UxeHVJQ0FnSUNBZ0lDQnBaaUFvWlhKeWIzSXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lITmxiR1l1Y21WcVpXTjBLR1Z5Y205eUtUdGNiaUFnSUNBZ0lDQWdmU0JsYkhObElHbG1JQ2hoY21kMWJXVnVkSE11YkdWdVozUm9JRDRnTWlrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYzJWc1ppNXlaWE52YkhabEtHRnljbUY1WDNOc2FXTmxLR0Z5WjNWdFpXNTBjeXdnTVNrcE8xeHVJQ0FnSUNBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYzJWc1ppNXlaWE52YkhabEtIWmhiSFZsS1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUgwN1hHNTlPMXh1WEc0dktpcGNiaUFxSUVCd1lYSmhiU0J5WlhOdmJIWmxjaUI3Um5WdVkzUnBiMjU5SUdFZ1puVnVZM1JwYjI0Z2RHaGhkQ0J5WlhSMWNtNXpJRzV2ZEdocGJtY2dZVzVrSUdGalkyVndkSE5jYmlBcUlIUm9aU0J5WlhOdmJIWmxMQ0J5WldwbFkzUXNJR0Z1WkNCdWIzUnBabmtnWm5WdVkzUnBiMjV6SUdadmNpQmhJR1JsWm1WeWNtVmtMbHh1SUNvZ1FISmxkSFZ5Ym5NZ1lTQndjbTl0YVhObElIUm9ZWFFnYldGNUlHSmxJSEpsYzI5c2RtVmtJSGRwZEdnZ2RHaGxJR2RwZG1WdUlISmxjMjlzZG1VZ1lXNWtJSEpsYW1WamRGeHVJQ29nWm5WdVkzUnBiMjV6TENCdmNpQnlaV3BsWTNSbFpDQmllU0JoSUhSb2NtOTNiaUJsZUdObGNIUnBiMjRnYVc0Z2NtVnpiMngyWlhKY2JpQXFMMXh1VVM1UWNtOXRhWE5sSUQwZ2NISnZiV2x6WlRzZ0x5OGdSVk0yWEc1UkxuQnliMjFwYzJVZ1BTQndjbTl0YVhObE8xeHVablZ1WTNScGIyNGdjSEp2YldselpTaHlaWE52YkhabGNpa2dlMXh1SUNBZ0lHbG1JQ2gwZVhCbGIyWWdjbVZ6YjJ4MlpYSWdJVDA5SUZ3aVpuVnVZM1JwYjI1Y0lpa2dlMXh1SUNBZ0lDQWdJQ0IwYUhKdmR5QnVaWGNnVkhsd1pVVnljbTl5S0Z3aWNtVnpiMngyWlhJZ2JYVnpkQ0JpWlNCaElHWjFibU4wYVc5dUxsd2lLVHRjYmlBZ0lDQjlYRzRnSUNBZ2RtRnlJR1JsWm1WeWNtVmtJRDBnWkdWbVpYSW9LVHRjYmlBZ0lDQjBjbmtnZTF4dUlDQWdJQ0FnSUNCeVpYTnZiSFpsY2loa1pXWmxjbkpsWkM1eVpYTnZiSFpsTENCa1pXWmxjbkpsWkM1eVpXcGxZM1FzSUdSbFptVnljbVZrTG01dmRHbG1lU2s3WEc0Z0lDQWdmU0JqWVhSamFDQW9jbVZoYzI5dUtTQjdYRzRnSUNBZ0lDQWdJR1JsWm1WeWNtVmtMbkpsYW1WamRDaHlaV0Z6YjI0cE8xeHVJQ0FnSUgxY2JpQWdJQ0J5WlhSMWNtNGdaR1ZtWlhKeVpXUXVjSEp2YldselpUdGNibjFjYmx4dWNISnZiV2x6WlM1eVlXTmxJRDBnY21GalpUc2dMeThnUlZNMlhHNXdjbTl0YVhObExtRnNiQ0E5SUdGc2JEc2dMeThnUlZNMlhHNXdjbTl0YVhObExuSmxhbVZqZENBOUlISmxhbVZqZERzZ0x5OGdSVk0yWEc1d2NtOXRhWE5sTG5KbGMyOXNkbVVnUFNCUk95QXZMeUJGVXpaY2JseHVMeThnV0ZoWUlHVjRjR1Z5YVcxbGJuUmhiQzRnSUZSb2FYTWdiV1YwYUc5a0lHbHpJR0VnZDJGNUlIUnZJR1JsYm05MFpTQjBhR0YwSUdFZ2JHOWpZV3dnZG1Gc2RXVWdhWE5jYmk4dklITmxjbWxoYkdsNllXSnNaU0JoYm1RZ2MyaHZkV3hrSUdKbElHbHRiV1ZrYVdGMFpXeDVJR1JwYzNCaGRHTm9aV1FnZEc4Z1lTQnlaVzF2ZEdVZ2RYQnZiaUJ5WlhGMVpYTjBMRnh1THk4Z2FXNXpkR1ZoWkNCdlppQndZWE56YVc1bklHRWdjbVZtWlhKbGJtTmxMbHh1VVM1d1lYTnpRbmxEYjNCNUlEMGdablZ1WTNScGIyNGdLRzlpYW1WamRDa2dlMXh1SUNBZ0lDOHZabkpsWlhwbEtHOWlhbVZqZENrN1hHNGdJQ0FnTHk5d1lYTnpRbmxEYjNCcFpYTXVjMlYwS0c5aWFtVmpkQ3dnZEhKMVpTazdYRzRnSUNBZ2NtVjBkWEp1SUc5aWFtVmpkRHRjYm4wN1hHNWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbkJoYzNOQ2VVTnZjSGtnUFNCbWRXNWpkR2x2YmlBb0tTQjdYRzRnSUNBZ0x5OW1jbVZsZW1Vb2IySnFaV04wS1R0Y2JpQWdJQ0F2TDNCaGMzTkNlVU52Y0dsbGN5NXpaWFFvYjJKcVpXTjBMQ0IwY25WbEtUdGNiaUFnSUNCeVpYUjFjbTRnZEdocGN6dGNibjA3WEc1Y2JpOHFLbHh1SUNvZ1NXWWdkSGR2SUhCeWIyMXBjMlZ6SUdWMlpXNTBkV0ZzYkhrZ1puVnNabWxzYkNCMGJ5QjBhR1VnYzJGdFpTQjJZV3gxWlN3Z2NISnZiV2x6WlhNZ2RHaGhkQ0IyWVd4MVpTeGNiaUFxSUdKMWRDQnZkR2hsY25kcGMyVWdjbVZxWldOMGN5NWNiaUFxSUVCd1lYSmhiU0I0SUh0QmJua3FmVnh1SUNvZ1FIQmhjbUZ0SUhrZ2UwRnVlU3A5WEc0Z0tpQkFjbVYwZFhKdWN5QjdRVzU1S24wZ1lTQndjbTl0YVhObElHWnZjaUI0SUdGdVpDQjVJR2xtSUhSb1pYa2dZWEpsSUhSb1pTQnpZVzFsTENCaWRYUWdZU0J5WldwbFkzUnBiMjVjYmlBcUlHOTBhR1Z5ZDJselpTNWNiaUFxWEc0Z0tpOWNibEV1YW05cGJpQTlJR1oxYm1OMGFXOXVJQ2g0TENCNUtTQjdYRzRnSUNBZ2NtVjBkWEp1SUZFb2VDa3VhbTlwYmloNUtUdGNibjA3WEc1Y2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExtcHZhVzRnUFNCbWRXNWpkR2x2YmlBb2RHaGhkQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQlJLRnQwYUdsekxDQjBhR0YwWFNrdWMzQnlaV0ZrS0daMWJtTjBhVzl1SUNoNExDQjVLU0I3WEc0Z0lDQWdJQ0FnSUdsbUlDaDRJRDA5UFNCNUtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QlVUMFJQT2lCY0lqMDlQVndpSUhOb2IzVnNaQ0JpWlNCUFltcGxZM1F1YVhNZ2IzSWdaWEYxYVhaY2JpQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQjRPMXh1SUNBZ0lDQWdJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2RHaHliM2NnYm1WM0lFVnljbTl5S0Z3aVEyRnVKM1FnYW05cGJqb2dibTkwSUhSb1pTQnpZVzFsT2lCY0lpQXJJSGdnS3lCY0lpQmNJaUFySUhrcE8xeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ2ZTazdYRzU5TzF4dVhHNHZLaXBjYmlBcUlGSmxkSFZ5Ym5NZ1lTQndjbTl0YVhObElHWnZjaUIwYUdVZ1ptbHljM1FnYjJZZ1lXNGdZWEp5WVhrZ2IyWWdjSEp2YldselpYTWdkRzhnWW1WamIyMWxJSE5sZEhSc1pXUXVYRzRnS2lCQWNHRnlZVzBnWVc1emQyVnljeUI3UVhKeVlYbGJRVzU1S2wxOUlIQnliMjFwYzJWeklIUnZJSEpoWTJWY2JpQXFJRUJ5WlhSMWNtNXpJSHRCYm5rcWZTQjBhR1VnWm1seWMzUWdjSEp2YldselpTQjBieUJpWlNCelpYUjBiR1ZrWEc0Z0tpOWNibEV1Y21GalpTQTlJSEpoWTJVN1hHNW1kVzVqZEdsdmJpQnlZV05sS0dGdWMzZGxjbEJ6S1NCN1hHNGdJQ0FnY21WMGRYSnVJSEJ5YjIxcGMyVW9ablZ1WTNScGIyNGdLSEpsYzI5c2RtVXNJSEpsYW1WamRDa2dlMXh1SUNBZ0lDQWdJQ0F2THlCVGQybDBZMmdnZEc4Z2RHaHBjeUJ2Ym1ObElIZGxJR05oYmlCaGMzTjFiV1VnWVhRZ2JHVmhjM1FnUlZNMVhHNGdJQ0FnSUNBZ0lDOHZJR0Z1YzNkbGNsQnpMbVp2Y2tWaFkyZ29ablZ1WTNScGIyNGdLR0Z1YzNkbGNsQXBJSHRjYmlBZ0lDQWdJQ0FnTHk4Z0lDQWdJRkVvWVc1emQyVnlVQ2t1ZEdobGJpaHlaWE52YkhabExDQnlaV3BsWTNRcE8xeHVJQ0FnSUNBZ0lDQXZMeUI5S1R0Y2JpQWdJQ0FnSUNBZ0x5OGdWWE5sSUhSb2FYTWdhVzRnZEdobElHMWxZVzUwYVcxbFhHNGdJQ0FnSUNBZ0lHWnZjaUFvZG1GeUlHa2dQU0F3TENCc1pXNGdQU0JoYm5OM1pYSlFjeTVzWlc1bmRHZzdJR2tnUENCc1pXNDdJR2tyS3lrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnVVNoaGJuTjNaWEpRYzF0cFhTa3VkR2hsYmloeVpYTnZiSFpsTENCeVpXcGxZM1FwTzF4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnZlNrN1hHNTlYRzVjYmxCeWIyMXBjMlV1Y0hKdmRHOTBlWEJsTG5KaFkyVWdQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnY21WMGRYSnVJSFJvYVhNdWRHaGxiaWhSTG5KaFkyVXBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQkRiMjV6ZEhKMVkzUnpJR0VnVUhKdmJXbHpaU0IzYVhSb0lHRWdjSEp2YldselpTQmtaWE5qY21sd2RHOXlJRzlpYW1WamRDQmhibVFnYjNCMGFXOXVZV3dnWm1Gc2JHSmhZMnRjYmlBcUlHWjFibU4wYVc5dUxpQWdWR2hsSUdSbGMyTnlhWEIwYjNJZ1kyOXVkR0ZwYm5NZ2JXVjBhRzlrY3lCc2FXdGxJSGRvWlc0b2NtVnFaV04wWldRcExDQm5aWFFvYm1GdFpTa3NYRzRnS2lCelpYUW9ibUZ0WlN3Z2RtRnNkV1VwTENCd2IzTjBLRzVoYldVc0lHRnlaM01wTENCaGJtUWdaR1ZzWlhSbEtHNWhiV1VwTENCM2FHbGphQ0JoYkd4Y2JpQXFJSEpsZEhWeWJpQmxhWFJvWlhJZ1lTQjJZV3gxWlN3Z1lTQndjbTl0YVhObElHWnZjaUJoSUhaaGJIVmxMQ0J2Y2lCaElISmxhbVZqZEdsdmJpNGdJRlJvWlNCbVlXeHNZbUZqYTF4dUlDb2dZV05qWlhCMGN5QjBhR1VnYjNCbGNtRjBhVzl1SUc1aGJXVXNJR0VnY21WemIyeDJaWElzSUdGdVpDQmhibmtnWm5WeWRHaGxjaUJoY21kMWJXVnVkSE1nZEdoaGRDQjNiM1ZzWkZ4dUlDb2dhR0YyWlNCaVpXVnVJR1p2Y25kaGNtUmxaQ0IwYnlCMGFHVWdZWEJ3Y205d2NtbGhkR1VnYldWMGFHOWtJR0ZpYjNabElHaGhaQ0JoSUcxbGRHaHZaQ0JpWldWdVhHNGdLaUJ3Y205MmFXUmxaQ0IzYVhSb0lIUm9aU0J3Y205d1pYSWdibUZ0WlM0Z0lGUm9aU0JCVUVrZ2JXRnJaWE1nYm04Z1ozVmhjbUZ1ZEdWbGN5QmhZbTkxZENCMGFHVWdibUYwZFhKbFhHNGdLaUJ2WmlCMGFHVWdjbVYwZFhKdVpXUWdiMkpxWldOMExDQmhjR0Z5ZENCbWNtOXRJSFJvWVhRZ2FYUWdhWE1nZFhOaFlteGxJSGRvWlhKbFpYWmxjaUJ3Y205dGFYTmxjeUJoY21WY2JpQXFJR0p2ZFdkb2RDQmhibVFnYzI5c1pDNWNiaUFxTDF4dVVTNXRZV3RsVUhKdmJXbHpaU0E5SUZCeWIyMXBjMlU3WEc1bWRXNWpkR2x2YmlCUWNtOXRhWE5sS0dSbGMyTnlhWEIwYjNJc0lHWmhiR3hpWVdOckxDQnBibk53WldOMEtTQjdYRzRnSUNBZ2FXWWdLR1poYkd4aVlXTnJJRDA5UFNCMmIybGtJREFwSUh0Y2JpQWdJQ0FnSUNBZ1ptRnNiR0poWTJzZ1BTQm1kVzVqZEdsdmJpQW9iM0FwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQnlaV3BsWTNRb2JtVjNJRVZ5Y205eUtGeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lGd2lVSEp2YldselpTQmtiMlZ6SUc1dmRDQnpkWEJ3YjNKMElHOXdaWEpoZEdsdmJqb2dYQ0lnS3lCdmNGeHVJQ0FnSUNBZ0lDQWdJQ0FnS1NrN1hHNGdJQ0FnSUNBZ0lIMDdYRzRnSUNBZ2ZWeHVJQ0FnSUdsbUlDaHBibk53WldOMElEMDlQU0IyYjJsa0lEQXBJSHRjYmlBZ0lDQWdJQ0FnYVc1emNHVmpkQ0E5SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhKbGRIVnliaUI3YzNSaGRHVTZJRndpZFc1cmJtOTNibHdpZlR0Y2JpQWdJQ0FnSUNBZ2ZUdGNiaUFnSUNCOVhHNWNiaUFnSUNCMllYSWdjSEp2YldselpTQTlJRzlpYW1WamRGOWpjbVZoZEdVb1VISnZiV2x6WlM1d2NtOTBiM1I1Y0dVcE8xeHVYRzRnSUNBZ2NISnZiV2x6WlM1d2NtOXRhWE5sUkdsemNHRjBZMmdnUFNCbWRXNWpkR2x2YmlBb2NtVnpiMngyWlN3Z2IzQXNJR0Z5WjNNcElIdGNiaUFnSUNBZ0lDQWdkbUZ5SUhKbGMzVnNkRHRjYmlBZ0lDQWdJQ0FnZEhKNUlIdGNiaUFnSUNBZ0lDQWdJQ0FnSUdsbUlDaGtaWE5qY21sd2RHOXlXMjl3WFNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lISmxjM1ZzZENBOUlHUmxjMk55YVhCMGIzSmJiM0JkTG1Gd2NHeDVLSEJ5YjIxcGMyVXNJR0Z5WjNNcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0J5WlhOMWJIUWdQU0JtWVd4c1ltRmpheTVqWVd4c0tIQnliMjFwYzJVc0lHOXdMQ0JoY21kektUdGNiaUFnSUNBZ0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ2ZTQmpZWFJqYUNBb1pYaGpaWEIwYVc5dUtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCeVpYTjFiSFFnUFNCeVpXcGxZM1FvWlhoalpYQjBhVzl1S1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQnBaaUFvY21WemIyeDJaU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjbVZ6YjJ4MlpTaHlaWE4xYkhRcE8xeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ2ZUdGNibHh1SUNBZ0lIQnliMjFwYzJVdWFXNXpjR1ZqZENBOUlHbHVjM0JsWTNRN1hHNWNiaUFnSUNBdkx5QllXRmdnWkdWd2NtVmpZWFJsWkNCZ2RtRnNkV1ZQWm1BZ1lXNWtJR0JsZUdObGNIUnBiMjVnSUhOMWNIQnZjblJjYmlBZ0lDQnBaaUFvYVc1emNHVmpkQ2tnZTF4dUlDQWdJQ0FnSUNCMllYSWdhVzV6Y0dWamRHVmtJRDBnYVc1emNHVmpkQ2dwTzF4dUlDQWdJQ0FnSUNCcFppQW9hVzV6Y0dWamRHVmtMbk4wWVhSbElEMDlQU0JjSW5KbGFtVmpkR1ZrWENJcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhCeWIyMXBjMlV1WlhoalpYQjBhVzl1SUQwZ2FXNXpjR1ZqZEdWa0xuSmxZWE52Ymp0Y2JpQWdJQ0FnSUNBZ2ZWeHVYRzRnSUNBZ0lDQWdJSEJ5YjIxcGMyVXVkbUZzZFdWUFppQTlJR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFpoY2lCcGJuTndaV04wWldRZ1BTQnBibk53WldOMEtDazdYRzRnSUNBZ0lDQWdJQ0FnSUNCcFppQW9hVzV6Y0dWamRHVmtMbk4wWVhSbElEMDlQU0JjSW5CbGJtUnBibWRjSWlCOGZGeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHbHVjM0JsWTNSbFpDNXpkR0YwWlNBOVBUMGdYQ0p5WldwbFkzUmxaRndpS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhCeWIyMXBjMlU3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJQ0FnSUNCeVpYUjFjbTRnYVc1emNHVmpkR1ZrTG5aaGJIVmxPMXh1SUNBZ0lDQWdJQ0I5TzF4dUlDQWdJSDFjYmx4dUlDQWdJSEpsZEhWeWJpQndjbTl0YVhObE8xeHVmVnh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1MGIxTjBjbWx1WnlBOUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQnlaWFIxY200Z1hDSmJiMkpxWldOMElGQnliMjFwYzJWZFhDSTdYRzU5TzF4dVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNTBhR1Z1SUQwZ1puVnVZM1JwYjI0Z0tHWjFiR1pwYkd4bFpDd2djbVZxWldOMFpXUXNJSEJ5YjJkeVpYTnpaV1FwSUh0Y2JpQWdJQ0IyWVhJZ2MyVnNaaUE5SUhSb2FYTTdYRzRnSUNBZ2RtRnlJR1JsWm1WeWNtVmtJRDBnWkdWbVpYSW9LVHRjYmlBZ0lDQjJZWElnWkc5dVpTQTlJR1poYkhObE95QWdJQzh2SUdWdWMzVnlaU0IwYUdVZ2RXNTBjblZ6ZEdWa0lIQnliMjFwYzJVZ2JXRnJaWE1nWVhRZ2JXOXpkQ0JoWEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0F2THlCemFXNW5iR1VnWTJGc2JDQjBieUJ2Ym1VZ2IyWWdkR2hsSUdOaGJHeGlZV05yYzF4dVhHNGdJQ0FnWm5WdVkzUnBiMjRnWDJaMWJHWnBiR3hsWkNoMllXeDFaU2tnZTF4dUlDQWdJQ0FnSUNCMGNua2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhSNWNHVnZaaUJtZFd4bWFXeHNaV1FnUFQwOUlGd2lablZ1WTNScGIyNWNJaUEvSUdaMWJHWnBiR3hsWkNoMllXeDFaU2tnT2lCMllXeDFaVHRjYmlBZ0lDQWdJQ0FnZlNCallYUmphQ0FvWlhoalpYQjBhVzl1S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdjbVZxWldOMEtHVjRZMlZ3ZEdsdmJpazdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQjlYRzVjYmlBZ0lDQm1kVzVqZEdsdmJpQmZjbVZxWldOMFpXUW9aWGhqWlhCMGFXOXVLU0I3WEc0Z0lDQWdJQ0FnSUdsbUlDaDBlWEJsYjJZZ2NtVnFaV04wWldRZ1BUMDlJRndpWm5WdVkzUnBiMjVjSWlrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYldGclpWTjBZV05yVkhKaFkyVk1iMjVuS0dWNFkyVndkR2x2Yml3Z2MyVnNaaWs3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjBjbmtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhKbGRIVnliaUJ5WldwbFkzUmxaQ2hsZUdObGNIUnBiMjRwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmU0JqWVhSamFDQW9ibVYzUlhoalpYQjBhVzl1S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhKbGFtVmpkQ2h1WlhkRmVHTmxjSFJwYjI0cE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCeVpXcGxZM1FvWlhoalpYQjBhVzl1S1R0Y2JpQWdJQ0I5WEc1Y2JpQWdJQ0JtZFc1amRHbHZiaUJmY0hKdlozSmxjM05sWkNoMllXeDFaU2tnZTF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnZEhsd1pXOW1JSEJ5YjJkeVpYTnpaV1FnUFQwOUlGd2lablZ1WTNScGIyNWNJaUEvSUhCeWIyZHlaWE56WldRb2RtRnNkV1VwSURvZ2RtRnNkV1U3WEc0Z0lDQWdmVnh1WEc0Z0lDQWdVUzV1WlhoMFZHbGpheWhtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lITmxiR1l1Y0hKdmJXbHpaVVJwYzNCaGRHTm9LR1oxYm1OMGFXOXVJQ2gyWVd4MVpTa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLR1J2Ym1VcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200N1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUNBZ0lDQmtiMjVsSUQwZ2RISjFaVHRjYmx4dUlDQWdJQ0FnSUNBZ0lDQWdaR1ZtWlhKeVpXUXVjbVZ6YjJ4MlpTaGZablZzWm1sc2JHVmtLSFpoYkhWbEtTazdYRzRnSUNBZ0lDQWdJSDBzSUZ3aWQyaGxibHdpTENCYlpuVnVZM1JwYjI0Z0tHVjRZMlZ3ZEdsdmJpa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLR1J2Ym1VcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200N1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUNBZ0lDQmtiMjVsSUQwZ2RISjFaVHRjYmx4dUlDQWdJQ0FnSUNBZ0lDQWdaR1ZtWlhKeVpXUXVjbVZ6YjJ4MlpTaGZjbVZxWldOMFpXUW9aWGhqWlhCMGFXOXVLU2s3WEc0Z0lDQWdJQ0FnSUgxZEtUdGNiaUFnSUNCOUtUdGNibHh1SUNBZ0lDOHZJRkJ5YjJkeVpYTnpJSEJ5YjNCaFoyRjBiM0lnYm1WbFpDQjBieUJpWlNCaGRIUmhZMmhsWkNCcGJpQjBhR1VnWTNWeWNtVnVkQ0IwYVdOckxseHVJQ0FnSUhObGJHWXVjSEp2YldselpVUnBjM0JoZEdOb0tIWnZhV1FnTUN3Z1hDSjNhR1Z1WENJc0lGdDJiMmxrSURBc0lHWjFibU4wYVc5dUlDaDJZV3gxWlNrZ2UxeHVJQ0FnSUNBZ0lDQjJZWElnYm1WM1ZtRnNkV1U3WEc0Z0lDQWdJQ0FnSUhaaGNpQjBhSEpsZHlBOUlHWmhiSE5sTzF4dUlDQWdJQ0FnSUNCMGNua2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2JtVjNWbUZzZFdVZ1BTQmZjSEp2WjNKbGMzTmxaQ2gyWVd4MVpTazdYRzRnSUNBZ0lDQWdJSDBnWTJGMFkyZ2dLR1VwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFJvY21WM0lEMGdkSEoxWlR0Y2JpQWdJQ0FnSUNBZ0lDQWdJR2xtSUNoUkxtOXVaWEp5YjNJcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQlJMbTl1WlhKeWIzSW9aU2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lIUm9jbTkzSUdVN1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUgxY2JseHVJQ0FnSUNBZ0lDQnBaaUFvSVhSb2NtVjNLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQmtaV1psY25KbFpDNXViM1JwWm5rb2JtVjNWbUZzZFdVcE8xeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ2ZWMHBPMXh1WEc0Z0lDQWdjbVYwZFhKdUlHUmxabVZ5Y21Wa0xuQnliMjFwYzJVN1hHNTlPMXh1WEc1UkxuUmhjQ0E5SUdaMWJtTjBhVzl1SUNod2NtOXRhWE5sTENCallXeHNZbUZqYXlrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0hCeWIyMXBjMlVwTG5SaGNDaGpZV3hzWW1GamF5azdYRzU5TzF4dVhHNHZLaXBjYmlBcUlGZHZjbXR6SUdGc2JXOXpkQ0JzYVd0bElGd2labWx1WVd4c2VWd2lMQ0JpZFhRZ2JtOTBJR05oYkd4bFpDQm1iM0lnY21WcVpXTjBhVzl1Y3k1Y2JpQXFJRTl5YVdkcGJtRnNJSEpsYzI5c2RYUnBiMjRnZG1Gc2RXVWdhWE1nY0dGemMyVmtJSFJvY205MVoyZ2dZMkZzYkdKaFkyc2dkVzVoWm1abFkzUmxaQzVjYmlBcUlFTmhiR3hpWVdOcklHMWhlU0J5WlhSMWNtNGdZU0J3Y205dGFYTmxJSFJvWVhRZ2QybHNiQ0JpWlNCaGQyRnBkR1ZrSUdadmNpNWNiaUFxSUVCd1lYSmhiU0I3Um5WdVkzUnBiMjU5SUdOaGJHeGlZV05yWEc0Z0tpQkFjbVYwZFhKdWN5QjdVUzVRY205dGFYTmxmVnh1SUNvZ1FHVjRZVzF3YkdWY2JpQXFJR1J2VTI5dFpYUm9hVzVuS0NsY2JpQXFJQ0FnTG5Sb1pXNG9MaTR1S1Z4dUlDb2dJQ0F1ZEdGd0tHTnZibk52YkdVdWJHOW5LVnh1SUNvZ0lDQXVkR2hsYmlndUxpNHBPMXh1SUNvdlhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNTBZWEFnUFNCbWRXNWpkR2x2YmlBb1kyRnNiR0poWTJzcElIdGNiaUFnSUNCallXeHNZbUZqYXlBOUlGRW9ZMkZzYkdKaFkyc3BPMXh1WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11ZEdobGJpaG1kVzVqZEdsdmJpQW9kbUZzZFdVcElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHTmhiR3hpWVdOckxtWmpZV3hzS0haaGJIVmxLUzUwYUdWdVVtVnpiMngyWlNoMllXeDFaU2s3WEc0Z0lDQWdmU2s3WEc1OU8xeHVYRzR2S2lwY2JpQXFJRkpsWjJsemRHVnljeUJoYmlCdlluTmxjblpsY2lCdmJpQmhJSEJ5YjIxcGMyVXVYRzRnS2x4dUlDb2dSM1ZoY21GdWRHVmxjenBjYmlBcVhHNGdLaUF4TGlCMGFHRjBJR1oxYkdacGJHeGxaQ0JoYm1RZ2NtVnFaV04wWldRZ2QybHNiQ0JpWlNCallXeHNaV1FnYjI1c2VTQnZibU5sTGx4dUlDb2dNaTRnZEdoaGRDQmxhWFJvWlhJZ2RHaGxJR1oxYkdacGJHeGxaQ0JqWVd4c1ltRmpheUJ2Y2lCMGFHVWdjbVZxWldOMFpXUWdZMkZzYkdKaFkyc2dkMmxzYkNCaVpWeHVJQ29nSUNBZ1kyRnNiR1ZrTENCaWRYUWdibTkwSUdKdmRHZ3VYRzRnS2lBekxpQjBhR0YwSUdaMWJHWnBiR3hsWkNCaGJtUWdjbVZxWldOMFpXUWdkMmxzYkNCdWIzUWdZbVVnWTJGc2JHVmtJR2x1SUhSb2FYTWdkSFZ5Ymk1Y2JpQXFYRzRnS2lCQWNHRnlZVzBnZG1Gc2RXVWdJQ0FnSUNCd2NtOXRhWE5sSUc5eUlHbHRiV1ZrYVdGMFpTQnlaV1psY21WdVkyVWdkRzhnYjJKelpYSjJaVnh1SUNvZ1FIQmhjbUZ0SUdaMWJHWnBiR3hsWkNBZ1puVnVZM1JwYjI0Z2RHOGdZbVVnWTJGc2JHVmtJSGRwZEdnZ2RHaGxJR1oxYkdacGJHeGxaQ0IyWVd4MVpWeHVJQ29nUUhCaGNtRnRJSEpsYW1WamRHVmtJQ0FnWm5WdVkzUnBiMjRnZEc4Z1ltVWdZMkZzYkdWa0lIZHBkR2dnZEdobElISmxhbVZqZEdsdmJpQmxlR05sY0hScGIyNWNiaUFxSUVCd1lYSmhiU0J3Y205bmNtVnpjMlZrSUdaMWJtTjBhVzl1SUhSdklHSmxJR05oYkd4bFpDQnZiaUJoYm5rZ2NISnZaM0psYzNNZ2JtOTBhV1pwWTJGMGFXOXVjMXh1SUNvZ1FISmxkSFZ5YmlCd2NtOXRhWE5sSUdadmNpQjBhR1VnY21WMGRYSnVJSFpoYkhWbElHWnliMjBnZEdobElHbHVkbTlyWldRZ1kyRnNiR0poWTJ0Y2JpQXFMMXh1VVM1M2FHVnVJRDBnZDJobGJqdGNibVoxYm1OMGFXOXVJSGRvWlc0b2RtRnNkV1VzSUdaMWJHWnBiR3hsWkN3Z2NtVnFaV04wWldRc0lIQnliMmR5WlhOelpXUXBJSHRjYmlBZ0lDQnlaWFIxY200Z1VTaDJZV3gxWlNrdWRHaGxiaWhtZFd4bWFXeHNaV1FzSUhKbGFtVmpkR1ZrTENCd2NtOW5jbVZ6YzJWa0tUdGNibjFjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWRHaGxibEpsYzI5c2RtVWdQU0JtZFc1amRHbHZiaUFvZG1Gc2RXVXBJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTUwYUdWdUtHWjFibU4wYVc5dUlDZ3BJSHNnY21WMGRYSnVJSFpoYkhWbE95QjlLVHRjYm4wN1hHNWNibEV1ZEdobGJsSmxjMjlzZG1VZ1BTQm1kVzVqZEdsdmJpQW9jSEp2YldselpTd2dkbUZzZFdVcElIdGNiaUFnSUNCeVpYUjFjbTRnVVNod2NtOXRhWE5sS1M1MGFHVnVVbVZ6YjJ4MlpTaDJZV3gxWlNrN1hHNTlPMXh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1MGFHVnVVbVZxWldOMElEMGdablZ1WTNScGIyNGdLSEpsWVhOdmJpa2dlMXh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpMblJvWlc0b1puVnVZM1JwYjI0Z0tDa2dleUIwYUhKdmR5QnlaV0Z6YjI0N0lIMHBPMXh1ZlR0Y2JseHVVUzUwYUdWdVVtVnFaV04wSUQwZ1puVnVZM1JwYjI0Z0tIQnliMjFwYzJVc0lISmxZWE52YmlrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0hCeWIyMXBjMlVwTG5Sb1pXNVNaV3BsWTNRb2NtVmhjMjl1S1R0Y2JuMDdYRzVjYmk4cUtseHVJQ29nU1dZZ1lXNGdiMkpxWldOMElHbHpJRzV2ZENCaElIQnliMjFwYzJVc0lHbDBJR2x6SUdGeklGd2libVZoY2x3aUlHRnpJSEJ2YzNOcFlteGxMbHh1SUNvZ1NXWWdZU0J3Y205dGFYTmxJR2x6SUhKbGFtVmpkR1ZrTENCcGRDQnBjeUJoY3lCY0ltNWxZWEpjSWlCaGN5QndiM056YVdKc1pTQjBiMjh1WEc0Z0tpQkpaaUJwZE9LQW1YTWdZU0JtZFd4bWFXeHNaV1FnY0hKdmJXbHpaU3dnZEdobElHWjFiR1pwYkd4dFpXNTBJSFpoYkhWbElHbHpJRzVsWVhKbGNpNWNiaUFxSUVsbUlHbDA0b0NaY3lCaElHUmxabVZ5Y21Wa0lIQnliMjFwYzJVZ1lXNWtJSFJvWlNCa1pXWmxjbkpsWkNCb1lYTWdZbVZsYmlCeVpYTnZiSFpsWkN3Z2RHaGxYRzRnS2lCeVpYTnZiSFYwYVc5dUlHbHpJRndpYm1WaGNtVnlYQ0l1WEc0Z0tpQkFjR0Z5WVcwZ2IySnFaV04wWEc0Z0tpQkFjbVYwZFhKdWN5QnRiM04wSUhKbGMyOXNkbVZrSUNodVpXRnlaWE4wS1NCbWIzSnRJRzltSUhSb1pTQnZZbXBsWTNSY2JpQXFMMXh1WEc0dkx5QllXRmdnYzJodmRXeGtJSGRsSUhKbExXUnZJSFJvYVhNL1hHNVJMbTVsWVhKbGNpQTlJRzVsWVhKbGNqdGNibVoxYm1OMGFXOXVJRzVsWVhKbGNpaDJZV3gxWlNrZ2UxeHVJQ0FnSUdsbUlDaHBjMUJ5YjIxcGMyVW9kbUZzZFdVcEtTQjdYRzRnSUNBZ0lDQWdJSFpoY2lCcGJuTndaV04wWldRZ1BTQjJZV3gxWlM1cGJuTndaV04wS0NrN1hHNGdJQ0FnSUNBZ0lHbG1JQ2hwYm5Od1pXTjBaV1F1YzNSaGRHVWdQVDA5SUZ3aVpuVnNabWxzYkdWa1hDSXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lISmxkSFZ5YmlCcGJuTndaV04wWldRdWRtRnNkV1U3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0I5WEc0Z0lDQWdjbVYwZFhKdUlIWmhiSFZsTzF4dWZWeHVYRzR2S2lwY2JpQXFJRUJ5WlhSMWNtNXpJSGRvWlhSb1pYSWdkR2hsSUdkcGRtVnVJRzlpYW1WamRDQnBjeUJoSUhCeWIyMXBjMlV1WEc0Z0tpQlBkR2hsY25kcGMyVWdhWFFnYVhNZ1lTQm1kV3htYVd4c1pXUWdkbUZzZFdVdVhHNGdLaTljYmxFdWFYTlFjbTl0YVhObElEMGdhWE5RY205dGFYTmxPMXh1Wm5WdVkzUnBiMjRnYVhOUWNtOXRhWE5sS0c5aWFtVmpkQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQnZZbXBsWTNRZ2FXNXpkR0Z1WTJWdlppQlFjbTl0YVhObE8xeHVmVnh1WEc1UkxtbHpVSEp2YldselpVRnNhV3RsSUQwZ2FYTlFjbTl0YVhObFFXeHBhMlU3WEc1bWRXNWpkR2x2YmlCcGMxQnliMjFwYzJWQmJHbHJaU2h2WW1wbFkzUXBJSHRjYmlBZ0lDQnlaWFIxY200Z2FYTlBZbXBsWTNRb2IySnFaV04wS1NBbUppQjBlWEJsYjJZZ2IySnFaV04wTG5Sb1pXNGdQVDA5SUZ3aVpuVnVZM1JwYjI1Y0lqdGNibjFjYmx4dUx5b3FYRzRnS2lCQWNtVjBkWEp1Y3lCM2FHVjBhR1Z5SUhSb1pTQm5hWFpsYmlCdlltcGxZM1FnYVhNZ1lTQndaVzVrYVc1bklIQnliMjFwYzJVc0lHMWxZVzVwYm1jZ2JtOTBYRzRnS2lCbWRXeG1hV3hzWldRZ2IzSWdjbVZxWldOMFpXUXVYRzRnS2k5Y2JsRXVhWE5RWlc1a2FXNW5JRDBnYVhOUVpXNWthVzVuTzF4dVpuVnVZM1JwYjI0Z2FYTlFaVzVrYVc1bktHOWlhbVZqZENrZ2UxeHVJQ0FnSUhKbGRIVnliaUJwYzFCeWIyMXBjMlVvYjJKcVpXTjBLU0FtSmlCdlltcGxZM1F1YVc1emNHVmpkQ2dwTG5OMFlYUmxJRDA5UFNCY0luQmxibVJwYm1kY0lqdGNibjFjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWFYTlFaVzVrYVc1bklEMGdablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TG1sdWMzQmxZM1FvS1M1emRHRjBaU0E5UFQwZ1hDSndaVzVrYVc1blhDSTdYRzU5TzF4dVhHNHZLaXBjYmlBcUlFQnlaWFIxY201eklIZG9aWFJvWlhJZ2RHaGxJR2RwZG1WdUlHOWlhbVZqZENCcGN5QmhJSFpoYkhWbElHOXlJR1oxYkdacGJHeGxaRnh1SUNvZ2NISnZiV2x6WlM1Y2JpQXFMMXh1VVM1cGMwWjFiR1pwYkd4bFpDQTlJR2x6Um5Wc1ptbHNiR1ZrTzF4dVpuVnVZM1JwYjI0Z2FYTkdkV3htYVd4c1pXUW9iMkpxWldOMEtTQjdYRzRnSUNBZ2NtVjBkWEp1SUNGcGMxQnliMjFwYzJVb2IySnFaV04wS1NCOGZDQnZZbXBsWTNRdWFXNXpjR1ZqZENncExuTjBZWFJsSUQwOVBTQmNJbVoxYkdacGJHeGxaRndpTzF4dWZWeHVYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzVwYzBaMWJHWnBiR3hsWkNBOUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTVwYm5Od1pXTjBLQ2t1YzNSaGRHVWdQVDA5SUZ3aVpuVnNabWxzYkdWa1hDSTdYRzU5TzF4dVhHNHZLaXBjYmlBcUlFQnlaWFIxY201eklIZG9aWFJvWlhJZ2RHaGxJR2RwZG1WdUlHOWlhbVZqZENCcGN5QmhJSEpsYW1WamRHVmtJSEJ5YjIxcGMyVXVYRzRnS2k5Y2JsRXVhWE5TWldwbFkzUmxaQ0E5SUdselVtVnFaV04wWldRN1hHNW1kVzVqZEdsdmJpQnBjMUpsYW1WamRHVmtLRzlpYW1WamRDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCcGMxQnliMjFwYzJVb2IySnFaV04wS1NBbUppQnZZbXBsWTNRdWFXNXpjR1ZqZENncExuTjBZWFJsSUQwOVBTQmNJbkpsYW1WamRHVmtYQ0k3WEc1OVhHNWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbWx6VW1WcVpXTjBaV1FnUFNCbWRXNWpkR2x2YmlBb0tTQjdYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTXVhVzV6Y0dWamRDZ3BMbk4wWVhSbElEMDlQU0JjSW5KbGFtVmpkR1ZrWENJN1hHNTlPMXh1WEc0dkx5OHZJRUpGUjBsT0lGVk9TRUZPUkV4RlJDQlNSVXBGUTFSSlQwNGdWRkpCUTB0SlRrZGNibHh1THk4Z1ZHaHBjeUJ3Y205dGFYTmxJR3hwWW5KaGNua2dZMjl1YzNWdFpYTWdaWGhqWlhCMGFXOXVjeUIwYUhKdmQyNGdhVzRnYUdGdVpHeGxjbk1nYzI4Z2RHaGxlU0JqWVc0Z1ltVmNiaTh2SUdoaGJtUnNaV1FnWW5rZ1lTQnpkV0p6WlhGMVpXNTBJSEJ5YjIxcGMyVXVJQ0JVYUdVZ1pYaGpaWEIwYVc5dWN5Qm5aWFFnWVdSa1pXUWdkRzhnZEdocGN5QmhjbkpoZVNCM2FHVnVYRzR2THlCMGFHVjVJR0Z5WlNCamNtVmhkR1ZrTENCaGJtUWdjbVZ0YjNabFpDQjNhR1Z1SUhSb1pYa2dZWEpsSUdoaGJtUnNaV1F1SUNCT2IzUmxJSFJvWVhRZ2FXNGdSVk0ySUc5eVhHNHZMeUJ6YUdsdGJXVmtJR1Z1ZG1seWIyNXRaVzUwY3l3Z2RHaHBjeUIzYjNWc1pDQnVZWFIxY21Gc2JIa2dZbVVnWVNCZ1UyVjBZQzVjYm5aaGNpQjFibWhoYm1Sc1pXUlNaV0Z6YjI1eklEMGdXMTA3WEc1MllYSWdkVzVvWVc1a2JHVmtVbVZxWldOMGFXOXVjeUE5SUZ0ZE8xeHVkbUZ5SUhKbGNHOXlkR1ZrVlc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3lBOUlGdGRPMXh1ZG1GeUlIUnlZV05yVlc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3lBOUlIUnlkV1U3WEc1Y2JtWjFibU4wYVc5dUlISmxjMlYwVlc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3lncElIdGNiaUFnSUNCMWJtaGhibVJzWldSU1pXRnpiMjV6TG14bGJtZDBhQ0E5SURBN1hHNGdJQ0FnZFc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3k1c1pXNW5kR2dnUFNBd08xeHVYRzRnSUNBZ2FXWWdLQ0YwY21GamExVnVhR0Z1Wkd4bFpGSmxhbVZqZEdsdmJuTXBJSHRjYmlBZ0lDQWdJQ0FnZEhKaFkydFZibWhoYm1Sc1pXUlNaV3BsWTNScGIyNXpJRDBnZEhKMVpUdGNiaUFnSUNCOVhHNTlYRzVjYm1aMWJtTjBhVzl1SUhSeVlXTnJVbVZxWldOMGFXOXVLSEJ5YjIxcGMyVXNJSEpsWVhOdmJpa2dlMXh1SUNBZ0lHbG1JQ2doZEhKaFkydFZibWhoYm1Sc1pXUlNaV3BsWTNScGIyNXpLU0I3WEc0Z0lDQWdJQ0FnSUhKbGRIVnlianRjYmlBZ0lDQjlYRzRnSUNBZ2FXWWdLSFI1Y0dWdlppQndjbTlqWlhOeklEMDlQU0JjSW05aWFtVmpkRndpSUNZbUlIUjVjR1Z2WmlCd2NtOWpaWE56TG1WdGFYUWdQVDA5SUZ3aVpuVnVZM1JwYjI1Y0lpa2dlMXh1SUNBZ0lDQWdJQ0JSTG01bGVIUlVhV05yTG5KMWJrRm1kR1Z5S0daMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUdsbUlDaGhjbkpoZVY5cGJtUmxlRTltS0hWdWFHRnVaR3hsWkZKbGFtVmpkR2x2Ym5Nc0lIQnliMjFwYzJVcElDRTlQU0F0TVNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lIQnliMk5sYzNNdVpXMXBkQ2hjSW5WdWFHRnVaR3hsWkZKbGFtVmpkR2x2Ymx3aUxDQnlaV0Z6YjI0c0lIQnliMjFwYzJVcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lISmxjRzl5ZEdWa1ZXNW9ZVzVrYkdWa1VtVnFaV04wYVc5dWN5NXdkWE5vS0hCeWIyMXBjMlVwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0I5S1R0Y2JpQWdJQ0I5WEc1Y2JpQWdJQ0IxYm1oaGJtUnNaV1JTWldwbFkzUnBiMjV6TG5CMWMyZ29jSEp2YldselpTazdYRzRnSUNBZ2FXWWdLSEpsWVhOdmJpQW1KaUIwZVhCbGIyWWdjbVZoYzI5dUxuTjBZV05ySUNFOVBTQmNJblZ1WkdWbWFXNWxaRndpS1NCN1hHNGdJQ0FnSUNBZ0lIVnVhR0Z1Wkd4bFpGSmxZWE52Ym5NdWNIVnphQ2h5WldGemIyNHVjM1JoWTJzcE8xeHVJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0FnSUhWdWFHRnVaR3hsWkZKbFlYTnZibk11Y0hWemFDaGNJaWh1YnlCemRHRmpheWtnWENJZ0t5QnlaV0Z6YjI0cE8xeHVJQ0FnSUgxY2JuMWNibHh1Wm5WdVkzUnBiMjRnZFc1MGNtRmphMUpsYW1WamRHbHZiaWh3Y205dGFYTmxLU0I3WEc0Z0lDQWdhV1lnS0NGMGNtRmphMVZ1YUdGdVpHeGxaRkpsYW1WamRHbHZibk1wSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1TzF4dUlDQWdJSDFjYmx4dUlDQWdJSFpoY2lCaGRDQTlJR0Z5Y21GNVgybHVaR1Y0VDJZb2RXNW9ZVzVrYkdWa1VtVnFaV04wYVc5dWN5d2djSEp2YldselpTazdYRzRnSUNBZ2FXWWdLR0YwSUNFOVBTQXRNU2tnZTF4dUlDQWdJQ0FnSUNCcFppQW9kSGx3Wlc5bUlIQnliMk5sYzNNZ1BUMDlJRndpYjJKcVpXTjBYQ0lnSmlZZ2RIbHdaVzltSUhCeWIyTmxjM011WlcxcGRDQTlQVDBnWENKbWRXNWpkR2x2Ymx3aUtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCUkxtNWxlSFJVYVdOckxuSjFia0ZtZEdWeUtHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0IyWVhJZ1lYUlNaWEJ2Y25RZ1BTQmhjbkpoZVY5cGJtUmxlRTltS0hKbGNHOXlkR1ZrVlc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3l3Z2NISnZiV2x6WlNrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLR0YwVW1Wd2IzSjBJQ0U5UFNBdE1Ta2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCd2NtOWpaWE56TG1WdGFYUW9YQ0p5WldwbFkzUnBiMjVJWVc1a2JHVmtYQ0lzSUhWdWFHRnVaR3hsWkZKbFlYTnZibk5iWVhSZExDQndjbTl0YVhObEtUdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY21Wd2IzSjBaV1JWYm1oaGJtUnNaV1JTWldwbFkzUnBiMjV6TG5Od2JHbGpaU2hoZEZKbGNHOXlkQ3dnTVNrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQWdJQ0FnZlNrN1hHNGdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lDQWdkVzVvWVc1a2JHVmtVbVZxWldOMGFXOXVjeTV6Y0d4cFkyVW9ZWFFzSURFcE8xeHVJQ0FnSUNBZ0lDQjFibWhoYm1Sc1pXUlNaV0Z6YjI1ekxuTndiR2xqWlNoaGRDd2dNU2s3WEc0Z0lDQWdmVnh1ZlZ4dVhHNVJMbkpsYzJWMFZXNW9ZVzVrYkdWa1VtVnFaV04wYVc5dWN5QTlJSEpsYzJWMFZXNW9ZVzVrYkdWa1VtVnFaV04wYVc5dWN6dGNibHh1VVM1blpYUlZibWhoYm1Sc1pXUlNaV0Z6YjI1eklEMGdablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJQzh2SUUxaGEyVWdZU0JqYjNCNUlITnZJSFJvWVhRZ1kyOXVjM1Z0WlhKeklHTmhiaWQwSUdsdWRHVnlabVZ5WlNCM2FYUm9JRzkxY2lCcGJuUmxjbTVoYkNCemRHRjBaUzVjYmlBZ0lDQnlaWFIxY200Z2RXNW9ZVzVrYkdWa1VtVmhjMjl1Y3k1emJHbGpaU2dwTzF4dWZUdGNibHh1VVM1emRHOXdWVzVvWVc1a2JHVmtVbVZxWldOMGFXOXVWSEpoWTJ0cGJtY2dQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnY21WelpYUlZibWhoYm1Sc1pXUlNaV3BsWTNScGIyNXpLQ2s3WEc0Z0lDQWdkSEpoWTJ0VmJtaGhibVJzWldSU1pXcGxZM1JwYjI1eklEMGdabUZzYzJVN1hHNTlPMXh1WEc1eVpYTmxkRlZ1YUdGdVpHeGxaRkpsYW1WamRHbHZibk1vS1R0Y2JseHVMeTh2THlCRlRrUWdWVTVJUVU1RVRFVkVJRkpGU2tWRFZFbFBUaUJVVWtGRFMwbE9SMXh1WEc0dktpcGNiaUFxSUVOdmJuTjBjblZqZEhNZ1lTQnlaV3BsWTNSbFpDQndjbTl0YVhObExseHVJQ29nUUhCaGNtRnRJSEpsWVhOdmJpQjJZV3gxWlNCa1pYTmpjbWxpYVc1bklIUm9aU0JtWVdsc2RYSmxYRzRnS2k5Y2JsRXVjbVZxWldOMElEMGdjbVZxWldOME8xeHVablZ1WTNScGIyNGdjbVZxWldOMEtISmxZWE52YmlrZ2UxeHVJQ0FnSUhaaGNpQnlaV3BsWTNScGIyNGdQU0JRY205dGFYTmxLSHRjYmlBZ0lDQWdJQ0FnWENKM2FHVnVYQ0k2SUdaMWJtTjBhVzl1SUNoeVpXcGxZM1JsWkNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnTHk4Z2JtOTBaU0IwYUdGMElIUm9aU0JsY25KdmNpQm9ZWE1nWW1WbGJpQm9ZVzVrYkdWa1hHNGdJQ0FnSUNBZ0lDQWdJQ0JwWmlBb2NtVnFaV04wWldRcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjFiblJ5WVdOclVtVnFaV04wYVc5dUtIUm9hWE1wTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhKbGFtVmpkR1ZrSUQ4Z2NtVnFaV04wWldRb2NtVmhjMjl1S1NBNklIUm9hWE03WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0I5TENCbWRXNWpkR2x2YmlCbVlXeHNZbUZqYXlncElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlIUm9hWE03WEc0Z0lDQWdmU3dnWm5WdVkzUnBiMjRnYVc1emNHVmpkQ2dwSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUhzZ2MzUmhkR1U2SUZ3aWNtVnFaV04wWldSY0lpd2djbVZoYzI5dU9pQnlaV0Z6YjI0Z2ZUdGNiaUFnSUNCOUtUdGNibHh1SUNBZ0lDOHZJRTV2ZEdVZ2RHaGhkQ0IwYUdVZ2NtVmhjMjl1SUdoaGN5QnViM1FnWW1WbGJpQm9ZVzVrYkdWa0xseHVJQ0FnSUhSeVlXTnJVbVZxWldOMGFXOXVLSEpsYW1WamRHbHZiaXdnY21WaGMyOXVLVHRjYmx4dUlDQWdJSEpsZEhWeWJpQnlaV3BsWTNScGIyNDdYRzU5WEc1Y2JpOHFLbHh1SUNvZ1EyOXVjM1J5ZFdOMGN5QmhJR1oxYkdacGJHeGxaQ0J3Y205dGFYTmxJR1p2Y2lCaGJpQnBiVzFsWkdsaGRHVWdjbVZtWlhKbGJtTmxMbHh1SUNvZ1FIQmhjbUZ0SUhaaGJIVmxJR2x0YldWa2FXRjBaU0J5WldabGNtVnVZMlZjYmlBcUwxeHVVUzVtZFd4bWFXeHNJRDBnWm5Wc1ptbHNiRHRjYm1aMWJtTjBhVzl1SUdaMWJHWnBiR3dvZG1Gc2RXVXBJSHRjYmlBZ0lDQnlaWFIxY200Z1VISnZiV2x6WlNoN1hHNGdJQ0FnSUNBZ0lGd2lkMmhsYmx3aU9pQm1kVzVqZEdsdmJpQW9LU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200Z2RtRnNkV1U3WEc0Z0lDQWdJQ0FnSUgwc1hHNGdJQ0FnSUNBZ0lGd2laMlYwWENJNklHWjFibU4wYVc5dUlDaHVZVzFsS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdkbUZzZFdWYmJtRnRaVjA3WEc0Z0lDQWdJQ0FnSUgwc1hHNGdJQ0FnSUNBZ0lGd2ljMlYwWENJNklHWjFibU4wYVc5dUlDaHVZVzFsTENCeWFITXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIWmhiSFZsVzI1aGJXVmRJRDBnY21oek8xeHVJQ0FnSUNBZ0lDQjlMRnh1SUNBZ0lDQWdJQ0JjSW1SbGJHVjBaVndpT2lCbWRXNWpkR2x2YmlBb2JtRnRaU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdaR1ZzWlhSbElIWmhiSFZsVzI1aGJXVmRPMXh1SUNBZ0lDQWdJQ0I5TEZ4dUlDQWdJQ0FnSUNCY0luQnZjM1JjSWpvZ1puVnVZM1JwYjI0Z0tHNWhiV1VzSUdGeVozTXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDOHZJRTFoY21zZ1RXbHNiR1Z5SUhCeWIzQnZjMlZ6SUhSb1lYUWdjRzl6ZENCM2FYUm9JRzV2SUc1aGJXVWdjMmh2ZFd4a0lHRndjR3g1SUdGY2JpQWdJQ0FnSUNBZ0lDQWdJQzh2SUhCeWIyMXBjMlZrSUdaMWJtTjBhVzl1TGx4dUlDQWdJQ0FnSUNBZ0lDQWdhV1lnS0c1aGJXVWdQVDA5SUc1MWJHd2dmSHdnYm1GdFpTQTlQVDBnZG05cFpDQXdLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSFpoYkhWbExtRndjR3g1S0hadmFXUWdNQ3dnWVhKbmN5azdYRzRnSUNBZ0lDQWdJQ0FnSUNCOUlHVnNjMlVnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhKbGRIVnliaUIyWVd4MVpWdHVZVzFsWFM1aGNIQnNlU2gyWVd4MVpTd2dZWEpuY3lrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUgwc1hHNGdJQ0FnSUNBZ0lGd2lZWEJ3YkhsY0lqb2dablZ1WTNScGIyNGdLSFJvYVhOd0xDQmhjbWR6S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdkbUZzZFdVdVlYQndiSGtvZEdocGMzQXNJR0Z5WjNNcE8xeHVJQ0FnSUNBZ0lDQjlMRnh1SUNBZ0lDQWdJQ0JjSW10bGVYTmNJam9nWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJRzlpYW1WamRGOXJaWGx6S0haaGJIVmxLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJSDBzSUhadmFXUWdNQ3dnWm5WdVkzUnBiMjRnYVc1emNHVmpkQ2dwSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUhzZ2MzUmhkR1U2SUZ3aVpuVnNabWxzYkdWa1hDSXNJSFpoYkhWbE9pQjJZV3gxWlNCOU8xeHVJQ0FnSUgwcE8xeHVmVnh1WEc0dktpcGNiaUFxSUVOdmJuWmxjblJ6SUhSb1pXNWhZbXhsY3lCMGJ5QlJJSEJ5YjIxcGMyVnpMbHh1SUNvZ1FIQmhjbUZ0SUhCeWIyMXBjMlVnZEdobGJtRmliR1VnY0hKdmJXbHpaVnh1SUNvZ1FISmxkSFZ5Ym5NZ1lTQlJJSEJ5YjIxcGMyVmNiaUFxTDF4dVpuVnVZM1JwYjI0Z1kyOWxjbU5sS0hCeWIyMXBjMlVwSUh0Y2JpQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUZFdWJtVjRkRlJwWTJzb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0IwY25rZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY0hKdmJXbHpaUzUwYUdWdUtHUmxabVZ5Y21Wa0xuSmxjMjlzZG1Vc0lHUmxabVZ5Y21Wa0xuSmxhbVZqZEN3Z1pHVm1aWEp5WldRdWJtOTBhV1o1S1R0Y2JpQWdJQ0FnSUNBZ2ZTQmpZWFJqYUNBb1pYaGpaWEIwYVc5dUtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCa1pXWmxjbkpsWkM1eVpXcGxZM1FvWlhoalpYQjBhVzl1S1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUgwcE8xeHVJQ0FnSUhKbGRIVnliaUJrWldabGNuSmxaQzV3Y205dGFYTmxPMXh1ZlZ4dVhHNHZLaXBjYmlBcUlFRnVibTkwWVhSbGN5QmhiaUJ2WW1wbFkzUWdjM1ZqYUNCMGFHRjBJR2wwSUhkcGJHd2dibVYyWlhJZ1ltVmNiaUFxSUhSeVlXNXpabVZ5Y21Wa0lHRjNZWGtnWm5KdmJTQjBhR2x6SUhCeWIyTmxjM01nYjNabGNpQmhibmtnY0hKdmJXbHpaVnh1SUNvZ1kyOXRiWFZ1YVdOaGRHbHZiaUJqYUdGdWJtVnNMbHh1SUNvZ1FIQmhjbUZ0SUc5aWFtVmpkRnh1SUNvZ1FISmxkSFZ5Ym5NZ2NISnZiV2x6WlNCaElIZHlZWEJ3YVc1bklHOW1JSFJvWVhRZ2IySnFaV04wSUhSb1lYUmNiaUFxSUdGa1pHbDBhVzl1WVd4c2VTQnlaWE53YjI1a2N5QjBieUIwYUdVZ1hDSnBjMFJsWmx3aUlHMWxjM05oWjJWY2JpQXFJSGRwZEdodmRYUWdZU0J5WldwbFkzUnBiMjR1WEc0Z0tpOWNibEV1YldGemRHVnlJRDBnYldGemRHVnlPMXh1Wm5WdVkzUnBiMjRnYldGemRHVnlLRzlpYW1WamRDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCUWNtOXRhWE5sS0h0Y2JpQWdJQ0FnSUNBZ1hDSnBjMFJsWmx3aU9pQm1kVzVqZEdsdmJpQW9LU0I3ZlZ4dUlDQWdJSDBzSUdaMWJtTjBhVzl1SUdaaGJHeGlZV05yS0c5d0xDQmhjbWR6S1NCN1hHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCa2FYTndZWFJqYUNodlltcGxZM1FzSUc5d0xDQmhjbWR6S1R0Y2JpQWdJQ0I5TENCbWRXNWpkR2x2YmlBb0tTQjdYRzRnSUNBZ0lDQWdJSEpsZEhWeWJpQlJLRzlpYW1WamRDa3VhVzV6Y0dWamRDZ3BPMXh1SUNBZ0lIMHBPMXh1ZlZ4dVhHNHZLaXBjYmlBcUlGTndjbVZoWkhNZ2RHaGxJSFpoYkhWbGN5QnZaaUJoSUhCeWIyMXBjMlZrSUdGeWNtRjVJRzltSUdGeVozVnRaVzUwY3lCcGJuUnZJSFJvWlZ4dUlDb2dablZzWm1sc2JHMWxiblFnWTJGc2JHSmhZMnN1WEc0Z0tpQkFjR0Z5WVcwZ1puVnNabWxzYkdWa0lHTmhiR3hpWVdOcklIUm9ZWFFnY21WalpXbDJaWE1nZG1GeWFXRmthV01nWVhKbmRXMWxiblJ6SUdaeWIyMGdkR2hsWEc0Z0tpQndjbTl0YVhObFpDQmhjbkpoZVZ4dUlDb2dRSEJoY21GdElISmxhbVZqZEdWa0lHTmhiR3hpWVdOcklIUm9ZWFFnY21WalpXbDJaWE1nZEdobElHVjRZMlZ3ZEdsdmJpQnBaaUIwYUdVZ2NISnZiV2x6WlZ4dUlDb2dhWE1nY21WcVpXTjBaV1F1WEc0Z0tpQkFjbVYwZFhKdWN5QmhJSEJ5YjIxcGMyVWdabTl5SUhSb1pTQnlaWFIxY200Z2RtRnNkV1VnYjNJZ2RHaHliM2R1SUdWNFkyVndkR2x2YmlCdlpseHVJQ29nWldsMGFHVnlJR05oYkd4aVlXTnJMbHh1SUNvdlhHNVJMbk53Y21WaFpDQTlJSE53Y21WaFpEdGNibVoxYm1OMGFXOXVJSE53Y21WaFpDaDJZV3gxWlN3Z1puVnNabWxzYkdWa0xDQnlaV3BsWTNSbFpDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCUktIWmhiSFZsS1M1emNISmxZV1FvWm5Wc1ptbHNiR1ZrTENCeVpXcGxZM1JsWkNrN1hHNTlYRzVjYmxCeWIyMXBjMlV1Y0hKdmRHOTBlWEJsTG5Od2NtVmhaQ0E5SUdaMWJtTjBhVzl1SUNobWRXeG1hV3hzWldRc0lISmxhbVZqZEdWa0tTQjdYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTXVZV3hzS0NrdWRHaGxiaWhtZFc1amRHbHZiaUFvWVhKeVlYa3BJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR1oxYkdacGJHeGxaQzVoY0hCc2VTaDJiMmxrSURBc0lHRnljbUY1S1R0Y2JpQWdJQ0I5TENCeVpXcGxZM1JsWkNrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUZSb1pTQmhjM2x1WXlCbWRXNWpkR2x2YmlCcGN5QmhJR1JsWTI5eVlYUnZjaUJtYjNJZ1oyVnVaWEpoZEc5eUlHWjFibU4wYVc5dWN5d2dkSFZ5Ym1sdVoxeHVJQ29nZEdobGJTQnBiblJ2SUdGemVXNWphSEp2Ym05MWN5Qm5aVzVsY21GMGIzSnpMaUFnUVd4MGFHOTFaMmdnWjJWdVpYSmhkRzl5Y3lCaGNtVWdiMjVzZVNCd1lYSjBYRzRnS2lCdlppQjBhR1VnYm1WM1pYTjBJRVZEVFVGVFkzSnBjSFFnTmlCa2NtRm1kSE1zSUhSb2FYTWdZMjlrWlNCa2IyVnpJRzV2ZENCallYVnpaU0J6ZVc1MFlYaGNiaUFxSUdWeWNtOXljeUJwYmlCdmJHUmxjaUJsYm1kcGJtVnpMaUFnVkdocGN5QmpiMlJsSUhOb2IzVnNaQ0JqYjI1MGFXNTFaU0IwYnlCM2IzSnJJR0Z1WkNCM2FXeHNYRzRnS2lCcGJpQm1ZV04wSUdsdGNISnZkbVVnYjNabGNpQjBhVzFsSUdGeklIUm9aU0JzWVc1bmRXRm5aU0JwYlhCeWIzWmxjeTVjYmlBcVhHNGdLaUJGVXpZZ1oyVnVaWEpoZEc5eWN5QmhjbVVnWTNWeWNtVnVkR3g1SUhCaGNuUWdiMllnVmpnZ2RtVnljMmx2YmlBekxqRTVJSGRwZEdnZ2RHaGxYRzRnS2lBdExXaGhjbTF2Ym5rdFoyVnVaWEpoZEc5eWN5QnlkVzUwYVcxbElHWnNZV2NnWlc1aFlteGxaQzRnSUZOd2FXUmxjazF2Ym10bGVTQm9ZWE1nYUdGa0lIUm9aVzFjYmlBcUlHWnZjaUJzYjI1blpYSXNJR0oxZENCMWJtUmxjaUJoYmlCdmJHUmxjaUJRZVhSb2IyNHRhVzV6Y0dseVpXUWdabTl5YlM0Z0lGUm9hWE1nWm5WdVkzUnBiMjVjYmlBcUlIZHZjbXR6SUc5dUlHSnZkR2dnYTJsdVpITWdiMllnWjJWdVpYSmhkRzl5Y3k1Y2JpQXFYRzRnS2lCRVpXTnZjbUYwWlhNZ1lTQm5aVzVsY21GMGIzSWdablZ1WTNScGIyNGdjM1ZqYUNCMGFHRjBPbHh1SUNvZ0lDMGdhWFFnYldGNUlIbHBaV3hrSUhCeWIyMXBjMlZ6WEc0Z0tpQWdMU0JsZUdWamRYUnBiMjRnZDJsc2JDQmpiMjUwYVc1MVpTQjNhR1Z1SUhSb1lYUWdjSEp2YldselpTQnBjeUJtZFd4bWFXeHNaV1JjYmlBcUlDQXRJSFJvWlNCMllXeDFaU0J2WmlCMGFHVWdlV2xsYkdRZ1pYaHdjbVZ6YzJsdmJpQjNhV3hzSUdKbElIUm9aU0JtZFd4bWFXeHNaV1FnZG1Gc2RXVmNiaUFxSUNBdElHbDBJSEpsZEhWeWJuTWdZU0J3Y205dGFYTmxJR1p2Y2lCMGFHVWdjbVYwZFhKdUlIWmhiSFZsSUNoM2FHVnVJSFJvWlNCblpXNWxjbUYwYjNKY2JpQXFJQ0FnSUhOMGIzQnpJR2wwWlhKaGRHbHVaeWxjYmlBcUlDQXRJSFJvWlNCa1pXTnZjbUYwWldRZ1puVnVZM1JwYjI0Z2NtVjBkWEp1Y3lCaElIQnliMjFwYzJVZ1ptOXlJSFJvWlNCeVpYUjFjbTRnZG1Gc2RXVmNiaUFxSUNBZ0lHOW1JSFJvWlNCblpXNWxjbUYwYjNJZ2IzSWdkR2hsSUdacGNuTjBJSEpsYW1WamRHVmtJSEJ5YjIxcGMyVWdZVzF2Ym1jZ2RHaHZjMlZjYmlBcUlDQWdJSGxwWld4a1pXUXVYRzRnS2lBZ0xTQnBaaUJoYmlCbGNuSnZjaUJwY3lCMGFISnZkMjRnYVc0Z2RHaGxJR2RsYm1WeVlYUnZjaXdnYVhRZ2NISnZjR0ZuWVhSbGN5QjBhSEp2ZFdkb1hHNGdLaUFnSUNCbGRtVnllU0JtYjJ4c2IzZHBibWNnZVdsbGJHUWdkVzUwYVd3Z2FYUWdhWE1nWTJGMVoyaDBMQ0J2Y2lCMWJuUnBiQ0JwZENCbGMyTmhjR1Z6WEc0Z0tpQWdJQ0IwYUdVZ1oyVnVaWEpoZEc5eUlHWjFibU4wYVc5dUlHRnNkRzluWlhSb1pYSXNJR0Z1WkNCcGN5QjBjbUZ1YzJ4aGRHVmtJR2x1ZEc4Z1lWeHVJQ29nSUNBZ2NtVnFaV04wYVc5dUlHWnZjaUIwYUdVZ2NISnZiV2x6WlNCeVpYUjFjbTVsWkNCaWVTQjBhR1VnWkdWamIzSmhkR1ZrSUdkbGJtVnlZWFJ2Y2k1Y2JpQXFMMXh1VVM1aGMzbHVZeUE5SUdGemVXNWpPMXh1Wm5WdVkzUnBiMjRnWVhONWJtTW9iV0ZyWlVkbGJtVnlZWFJ2Y2lrZ2UxeHVJQ0FnSUhKbGRIVnliaUJtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lDOHZJSGRvWlc0Z2RtVnlZaUJwY3lCY0luTmxibVJjSWl3Z1lYSm5JR2x6SUdFZ2RtRnNkV1ZjYmlBZ0lDQWdJQ0FnTHk4Z2QyaGxiaUIyWlhKaUlHbHpJRndpZEdoeWIzZGNJaXdnWVhKbklHbHpJR0Z1SUdWNFkyVndkR2x2Ymx4dUlDQWdJQ0FnSUNCbWRXNWpkR2x2YmlCamIyNTBhVzUxWlhJb2RtVnlZaXdnWVhKbktTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCMllYSWdjbVZ6ZFd4ME8xeHVYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QlZiblJwYkNCV09DQXpMakU1SUM4Z1EyaHliMjFwZFcwZ01qa2dhWE1nY21Wc1pXRnpaV1FzSUZOd2FXUmxjazF2Ym10bGVTQnBjeUIwYUdVZ2IyNXNlVnh1SUNBZ0lDQWdJQ0FnSUNBZ0x5OGdaVzVuYVc1bElIUm9ZWFFnYUdGeklHRWdaR1Z3Ykc5NVpXUWdZbUZ6WlNCdlppQmljbTkzYzJWeWN5QjBhR0YwSUhOMWNIQnZjblFnWjJWdVpYSmhkRzl5Y3k1Y2JpQWdJQ0FnSUNBZ0lDQWdJQzh2SUVodmQyVjJaWElzSUZOTkozTWdaMlZ1WlhKaGRHOXljeUIxYzJVZ2RHaGxJRkI1ZEdodmJpMXBibk53YVhKbFpDQnpaVzFoYm5ScFkzTWdiMlpjYmlBZ0lDQWdJQ0FnSUNBZ0lDOHZJRzkxZEdSaGRHVmtJRVZUTmlCa2NtRm1kSE11SUNCWFpTQjNiM1ZzWkNCc2FXdGxJSFJ2SUhOMWNIQnZjblFnUlZNMkxDQmlkWFFnZDJVblpDQmhiSE52WEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUJzYVd0bElIUnZJRzFoYTJVZ2FYUWdjRzl6YzJsaWJHVWdkRzhnZFhObElHZGxibVZ5WVhSdmNuTWdhVzRnWkdWd2JHOTVaV1FnWW5KdmQzTmxjbk1zSUhOdlhHNGdJQ0FnSUNBZ0lDQWdJQ0F2THlCM1pTQmhiSE52SUhOMWNIQnZjblFnVUhsMGFHOXVMWE4wZVd4bElHZGxibVZ5WVhSdmNuTXVJQ0JCZENCemIyMWxJSEJ2YVc1MElIZGxJR05oYmlCeVpXMXZkbVZjYmlBZ0lDQWdJQ0FnSUNBZ0lDOHZJSFJvYVhNZ1lteHZZMnN1WEc1Y2JpQWdJQ0FnSUNBZ0lDQWdJR2xtSUNoMGVYQmxiMllnVTNSdmNFbDBaWEpoZEdsdmJpQTlQVDBnWENKMWJtUmxabWx1WldSY0lpa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQzh2SUVWVE5pQkhaVzVsY21GMGIzSnpYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdkSEo1SUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdjbVZ6ZFd4MElEMGdaMlZ1WlhKaGRHOXlXM1psY21KZEtHRnlaeWs3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnZlNCallYUmphQ0FvWlhoalpYQjBhVzl1S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQnlaV3BsWTNRb1pYaGpaWEIwYVc5dUtUdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdhV1lnS0hKbGMzVnNkQzVrYjI1bEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhKbGRIVnliaUJSS0hKbGMzVnNkQzUyWVd4MVpTazdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdmU0JsYkhObElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSGRvWlc0b2NtVnpkV3gwTG5aaGJIVmxMQ0JqWVd4c1ltRmpheXdnWlhKeVltRmpheWs3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNBZ0lDQWdmU0JsYkhObElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQXZMeUJUY0dsa1pYSk5iMjVyWlhrZ1IyVnVaWEpoZEc5eWMxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDOHZJRVpKV0UxRk9pQlNaVzF2ZG1VZ2RHaHBjeUJqWVhObElIZG9aVzRnVTAwZ1pHOWxjeUJGVXpZZ1oyVnVaWEpoZEc5eWN5NWNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjBjbmtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQnlaWE4xYkhRZ1BTQm5aVzVsY21GMGIzSmJkbVZ5WWwwb1lYSm5LVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0I5SUdOaGRHTm9JQ2hsZUdObGNIUnBiMjRwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdhV1lnS0dselUzUnZjRWwwWlhKaGRHbHZiaWhsZUdObGNIUnBiMjRwS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCeVpYUjFjbTRnVVNobGVHTmxjSFJwYjI0dWRtRnNkV1VwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhKbGFtVmpkQ2hsZUdObGNIUnBiMjRwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQjNhR1Z1S0hKbGMzVnNkQ3dnWTJGc2JHSmhZMnNzSUdWeWNtSmhZMnNwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUhaaGNpQm5aVzVsY21GMGIzSWdQU0J0WVd0bFIyVnVaWEpoZEc5eUxtRndjR3g1S0hSb2FYTXNJR0Z5WjNWdFpXNTBjeWs3WEc0Z0lDQWdJQ0FnSUhaaGNpQmpZV3hzWW1GamF5QTlJR052Ym5ScGJuVmxjaTVpYVc1a0tHTnZiblJwYm5WbGNpd2dYQ0p1WlhoMFhDSXBPMXh1SUNBZ0lDQWdJQ0IyWVhJZ1pYSnlZbUZqYXlBOUlHTnZiblJwYm5WbGNpNWlhVzVrS0dOdmJuUnBiblZsY2l3Z1hDSjBhSEp2ZDF3aUtUdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHTmhiR3hpWVdOcktDazdYRzRnSUNBZ2ZUdGNibjFjYmx4dUx5b3FYRzRnS2lCVWFHVWdjM0JoZDI0Z1puVnVZM1JwYjI0Z2FYTWdZU0J6YldGc2JDQjNjbUZ3Y0dWeUlHRnliM1Z1WkNCaGMzbHVZeUIwYUdGMElHbHRiV1ZrYVdGMFpXeDVYRzRnS2lCallXeHNjeUIwYUdVZ1oyVnVaWEpoZEc5eUlHRnVaQ0JoYkhOdklHVnVaSE1nZEdobElIQnliMjFwYzJVZ1kyaGhhVzRzSUhOdklIUm9ZWFFnWVc1NVhHNGdLaUIxYm1oaGJtUnNaV1FnWlhKeWIzSnpJR0Z5WlNCMGFISnZkMjRnYVc1emRHVmhaQ0J2WmlCbWIzSjNZWEprWldRZ2RHOGdkR2hsSUdWeWNtOXlYRzRnS2lCb1lXNWtiR1Z5TGlCVWFHbHpJR2x6SUhWelpXWjFiQ0JpWldOaGRYTmxJR2wwSjNNZ1pYaDBjbVZ0Wld4NUlHTnZiVzF2YmlCMGJ5QnlkVzVjYmlBcUlHZGxibVZ5WVhSdmNuTWdZWFFnZEdobElIUnZjQzFzWlhabGJDQjBieUIzYjNKcklIZHBkR2dnYkdsaWNtRnlhV1Z6TGx4dUlDb3ZYRzVSTG5Od1lYZHVJRDBnYzNCaGQyNDdYRzVtZFc1amRHbHZiaUJ6Y0dGM2JpaHRZV3RsUjJWdVpYSmhkRzl5S1NCN1hHNGdJQ0FnVVM1a2IyNWxLRkV1WVhONWJtTW9iV0ZyWlVkbGJtVnlZWFJ2Y2lrb0tTazdYRzU5WEc1Y2JpOHZJRVpKV0UxRk9pQlNaVzF2ZG1VZ2RHaHBjeUJwYm5SbGNtWmhZMlVnYjI1alpTQkZVellnWjJWdVpYSmhkRzl5Y3lCaGNtVWdhVzRnVTNCcFpHVnlUVzl1YTJWNUxseHVMeW9xWEc0Z0tpQlVhSEp2ZDNNZ1lTQlNaWFIxY201V1lXeDFaU0JsZUdObGNIUnBiMjRnZEc4Z2MzUnZjQ0JoYmlCaGMzbHVZMmh5YjI1dmRYTWdaMlZ1WlhKaGRHOXlMbHh1SUNwY2JpQXFJRlJvYVhNZ2FXNTBaWEptWVdObElHbHpJR0VnYzNSdmNDMW5ZWEFnYldWaGMzVnlaU0IwYnlCemRYQndiM0owSUdkbGJtVnlZWFJ2Y2lCeVpYUjFjbTVjYmlBcUlIWmhiSFZsY3lCcGJpQnZiR1JsY2lCR2FYSmxabTk0TDFOd2FXUmxjazF2Ym10bGVTNGdJRWx1SUdKeWIzZHpaWEp6SUhSb1lYUWdjM1Z3Y0c5eWRDQkZVelpjYmlBcUlHZGxibVZ5WVhSdmNuTWdiR2xyWlNCRGFISnZiV2wxYlNBeU9Td2dhblZ6ZENCMWMyVWdYQ0p5WlhSMWNtNWNJaUJwYmlCNWIzVnlJR2RsYm1WeVlYUnZjbHh1SUNvZ1puVnVZM1JwYjI1ekxseHVJQ3BjYmlBcUlFQndZWEpoYlNCMllXeDFaU0IwYUdVZ2NtVjBkWEp1SUhaaGJIVmxJR1p2Y2lCMGFHVWdjM1Z5Y205MWJtUnBibWNnWjJWdVpYSmhkRzl5WEc0Z0tpQkFkR2h5YjNkeklGSmxkSFZ5YmxaaGJIVmxJR1Y0WTJWd2RHbHZiaUIzYVhSb0lIUm9aU0IyWVd4MVpTNWNiaUFxSUVCbGVHRnRjR3hsWEc0Z0tpQXZMeUJGVXpZZ2MzUjViR1ZjYmlBcUlGRXVZWE41Ym1Nb1puVnVZM1JwYjI0cUlDZ3BJSHRjYmlBcUlDQWdJQ0FnZG1GeUlHWnZieUE5SUhscFpXeGtJR2RsZEVadmIxQnliMjFwYzJVb0tUdGNiaUFxSUNBZ0lDQWdkbUZ5SUdKaGNpQTlJSGxwWld4a0lHZGxkRUpoY2xCeWIyMXBjMlVvS1R0Y2JpQXFJQ0FnSUNBZ2NtVjBkWEp1SUdadmJ5QXJJR0poY2p0Y2JpQXFJSDBwWEc0Z0tpQXZMeUJQYkdSbGNpQlRjR2xrWlhKTmIyNXJaWGtnYzNSNWJHVmNiaUFxSUZFdVlYTjVibU1vWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ29nSUNBZ0lDQjJZWElnWm05dklEMGdlV2xsYkdRZ1oyVjBSbTl2VUhKdmJXbHpaU2dwTzF4dUlDb2dJQ0FnSUNCMllYSWdZbUZ5SUQwZ2VXbGxiR1FnWjJWMFFtRnlVSEp2YldselpTZ3BPMXh1SUNvZ0lDQWdJQ0JSTG5KbGRIVnliaWhtYjI4Z0t5QmlZWElwTzF4dUlDb2dmU2xjYmlBcUwxeHVVVnRjSW5KbGRIVnlibHdpWFNBOUlGOXlaWFIxY200N1hHNW1kVzVqZEdsdmJpQmZjbVYwZFhKdUtIWmhiSFZsS1NCN1hHNGdJQ0FnZEdoeWIzY2dibVYzSUZGU1pYUjFjbTVXWVd4MVpTaDJZV3gxWlNrN1hHNTlYRzVjYmk4cUtseHVJQ29nVkdobElIQnliMjFwYzJWa0lHWjFibU4wYVc5dUlHUmxZMjl5WVhSdmNpQmxibk4xY21WeklIUm9ZWFFnWVc1NUlIQnliMjFwYzJVZ1lYSm5kVzFsYm5SelhHNGdLaUJoY21VZ2MyVjBkR3hsWkNCaGJtUWdjR0Z6YzJWa0lHRnpJSFpoYkhWbGN5QW9ZSFJvYVhOZ0lHbHpJR0ZzYzI4Z2MyVjBkR3hsWkNCaGJtUWdjR0Z6YzJWa1hHNGdLaUJoY3lCaElIWmhiSFZsS1M0Z0lFbDBJSGRwYkd3Z1lXeHpieUJsYm5OMWNtVWdkR2hoZENCMGFHVWdjbVZ6ZFd4MElHOW1JR0VnWm5WdVkzUnBiMjRnYVhOY2JpQXFJR0ZzZDJGNWN5QmhJSEJ5YjIxcGMyVXVYRzRnS2x4dUlDb2dRR1Y0WVcxd2JHVmNiaUFxSUhaaGNpQmhaR1FnUFNCUkxuQnliMjFwYzJWa0tHWjFibU4wYVc5dUlDaGhMQ0JpS1NCN1hHNGdLaUFnSUNBZ2NtVjBkWEp1SUdFZ0t5QmlPMXh1SUNvZ2ZTazdYRzRnS2lCaFpHUW9VU2hoS1N3Z1VTaENLU2s3WEc0Z0tseHVJQ29nUUhCaGNtRnRJSHRtZFc1amRHbHZibjBnWTJGc2JHSmhZMnNnVkdobElHWjFibU4wYVc5dUlIUnZJR1JsWTI5eVlYUmxYRzRnS2lCQWNtVjBkWEp1Y3lCN1puVnVZM1JwYjI1OUlHRWdablZ1WTNScGIyNGdkR2hoZENCb1lYTWdZbVZsYmlCa1pXTnZjbUYwWldRdVhHNGdLaTljYmxFdWNISnZiV2x6WldRZ1BTQndjbTl0YVhObFpEdGNibVoxYm1OMGFXOXVJSEJ5YjIxcGMyVmtLR05oYkd4aVlXTnJLU0I3WEc0Z0lDQWdjbVYwZFhKdUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJSE53Y21WaFpDaGJkR2hwY3l3Z1lXeHNLR0Z5WjNWdFpXNTBjeWxkTENCbWRXNWpkR2x2YmlBb2MyVnNaaXdnWVhKbmN5a2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUdOaGJHeGlZV05yTG1Gd2NHeDVLSE5sYkdZc0lHRnlaM01wTzF4dUlDQWdJQ0FnSUNCOUtUdGNiaUFnSUNCOU8xeHVmVnh1WEc0dktpcGNiaUFxSUhObGJtUnpJR0VnYldWemMyRm5aU0IwYnlCaElIWmhiSFZsSUdsdUlHRWdablYwZFhKbElIUjFjbTVjYmlBcUlFQndZWEpoYlNCdlltcGxZM1FxSUhSb1pTQnlaV05wY0dsbGJuUmNiaUFxSUVCd1lYSmhiU0J2Y0NCMGFHVWdibUZ0WlNCdlppQjBhR1VnYldWemMyRm5aU0J2Y0dWeVlYUnBiMjRzSUdVdVp5NHNJRndpZDJobGJsd2lMRnh1SUNvZ1FIQmhjbUZ0SUdGeVozTWdablZ5ZEdobGNpQmhjbWQxYldWdWRITWdkRzhnWW1VZ1ptOXlkMkZ5WkdWa0lIUnZJSFJvWlNCdmNHVnlZWFJwYjI1Y2JpQXFJRUJ5WlhSMWNtNXpJSEpsYzNWc2RDQjdVSEp2YldselpYMGdZU0J3Y205dGFYTmxJR1p2Y2lCMGFHVWdjbVZ6ZFd4MElHOW1JSFJvWlNCdmNHVnlZWFJwYjI1Y2JpQXFMMXh1VVM1a2FYTndZWFJqYUNBOUlHUnBjM0JoZEdOb08xeHVablZ1WTNScGIyNGdaR2x6Y0dGMFkyZ29iMkpxWldOMExDQnZjQ3dnWVhKbmN5a2dlMXh1SUNBZ0lISmxkSFZ5YmlCUktHOWlhbVZqZENrdVpHbHpjR0YwWTJnb2IzQXNJR0Z5WjNNcE8xeHVmVnh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1a2FYTndZWFJqYUNBOUlHWjFibU4wYVc5dUlDaHZjQ3dnWVhKbmN5a2dlMXh1SUNBZ0lIWmhjaUJ6Wld4bUlEMGdkR2hwY3p0Y2JpQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUZFdWJtVjRkRlJwWTJzb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0J6Wld4bUxuQnliMjFwYzJWRWFYTndZWFJqYUNoa1pXWmxjbkpsWkM1eVpYTnZiSFpsTENCdmNDd2dZWEpuY3lrN1hHNGdJQ0FnZlNrN1hHNGdJQ0FnY21WMGRYSnVJR1JsWm1WeWNtVmtMbkJ5YjIxcGMyVTdYRzU5TzF4dVhHNHZLaXBjYmlBcUlFZGxkSE1nZEdobElIWmhiSFZsSUc5bUlHRWdjSEp2Y0dWeWRIa2dhVzRnWVNCbWRYUjFjbVVnZEhWeWJpNWNiaUFxSUVCd1lYSmhiU0J2WW1wbFkzUWdJQ0FnY0hKdmJXbHpaU0J2Y2lCcGJXMWxaR2xoZEdVZ2NtVm1aWEpsYm1ObElHWnZjaUIwWVhKblpYUWdiMkpxWldOMFhHNGdLaUJBY0dGeVlXMGdibUZ0WlNBZ0lDQWdJRzVoYldVZ2IyWWdjSEp2Y0dWeWRIa2dkRzhnWjJWMFhHNGdLaUJBY21WMGRYSnVJSEJ5YjIxcGMyVWdabTl5SUhSb1pTQndjbTl3WlhKMGVTQjJZV3gxWlZ4dUlDb3ZYRzVSTG1kbGRDQTlJR1oxYm1OMGFXOXVJQ2h2WW1wbFkzUXNJR3RsZVNrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0c5aWFtVmpkQ2t1WkdsemNHRjBZMmdvWENKblpYUmNJaXdnVzJ0bGVWMHBPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVaMlYwSUQwZ1puVnVZM1JwYjI0Z0tHdGxlU2tnZTF4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TG1ScGMzQmhkR05vS0Z3aVoyVjBYQ0lzSUZ0clpYbGRLVHRjYm4wN1hHNWNiaThxS2x4dUlDb2dVMlYwY3lCMGFHVWdkbUZzZFdVZ2IyWWdZU0J3Y205d1pYSjBlU0JwYmlCaElHWjFkSFZ5WlNCMGRYSnVMbHh1SUNvZ1FIQmhjbUZ0SUc5aWFtVmpkQ0FnSUNCd2NtOXRhWE5sSUc5eUlHbHRiV1ZrYVdGMFpTQnlaV1psY21WdVkyVWdabTl5SUc5aWFtVmpkQ0J2WW1wbFkzUmNiaUFxSUVCd1lYSmhiU0J1WVcxbElDQWdJQ0FnYm1GdFpTQnZaaUJ3Y205d1pYSjBlU0IwYnlCelpYUmNiaUFxSUVCd1lYSmhiU0IyWVd4MVpTQWdJQ0FnYm1WM0lIWmhiSFZsSUc5bUlIQnliM0JsY25SNVhHNGdLaUJBY21WMGRYSnVJSEJ5YjIxcGMyVWdabTl5SUhSb1pTQnlaWFIxY200Z2RtRnNkV1ZjYmlBcUwxeHVVUzV6WlhRZ1BTQm1kVzVqZEdsdmJpQW9iMkpxWldOMExDQnJaWGtzSUhaaGJIVmxLU0I3WEc0Z0lDQWdjbVYwZFhKdUlGRW9iMkpxWldOMEtTNWthWE53WVhSamFDaGNJbk5sZEZ3aUxDQmJhMlY1TENCMllXeDFaVjBwTzF4dWZUdGNibHh1VUhKdmJXbHpaUzV3Y205MGIzUjVjR1V1YzJWMElEMGdablZ1WTNScGIyNGdLR3RsZVN3Z2RtRnNkV1VwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdkR2hwY3k1a2FYTndZWFJqYUNoY0luTmxkRndpTENCYmEyVjVMQ0IyWVd4MVpWMHBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQkVaV3hsZEdWeklHRWdjSEp2Y0dWeWRIa2dhVzRnWVNCbWRYUjFjbVVnZEhWeWJpNWNiaUFxSUVCd1lYSmhiU0J2WW1wbFkzUWdJQ0FnY0hKdmJXbHpaU0J2Y2lCcGJXMWxaR2xoZEdVZ2NtVm1aWEpsYm1ObElHWnZjaUIwWVhKblpYUWdiMkpxWldOMFhHNGdLaUJBY0dGeVlXMGdibUZ0WlNBZ0lDQWdJRzVoYldVZ2IyWWdjSEp2Y0dWeWRIa2dkRzhnWkdWc1pYUmxYRzRnS2lCQWNtVjBkWEp1SUhCeWIyMXBjMlVnWm05eUlIUm9aU0J5WlhSMWNtNGdkbUZzZFdWY2JpQXFMMXh1VVM1a1pXd2dQU0F2THlCWVdGZ2diR1ZuWVdONVhHNVJXMXdpWkdWc1pYUmxYQ0pkSUQwZ1puVnVZM1JwYjI0Z0tHOWlhbVZqZEN3Z2EyVjVLU0I3WEc0Z0lDQWdjbVYwZFhKdUlGRW9iMkpxWldOMEtTNWthWE53WVhSamFDaGNJbVJsYkdWMFpWd2lMQ0JiYTJWNVhTazdYRzU5TzF4dVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNWtaV3dnUFNBdkx5QllXRmdnYkdWbllXTjVYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaVnRjSW1SbGJHVjBaVndpWFNBOUlHWjFibU4wYVc5dUlDaHJaWGtwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdkR2hwY3k1a2FYTndZWFJqYUNoY0ltUmxiR1YwWlZ3aUxDQmJhMlY1WFNrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUVsdWRtOXJaWE1nWVNCdFpYUm9iMlFnYVc0Z1lTQm1kWFIxY21VZ2RIVnliaTVjYmlBcUlFQndZWEpoYlNCdlltcGxZM1FnSUNBZ2NISnZiV2x6WlNCdmNpQnBiVzFsWkdsaGRHVWdjbVZtWlhKbGJtTmxJR1p2Y2lCMFlYSm5aWFFnYjJKcVpXTjBYRzRnS2lCQWNHRnlZVzBnYm1GdFpTQWdJQ0FnSUc1aGJXVWdiMllnYldWMGFHOWtJSFJ2SUdsdWRtOXJaVnh1SUNvZ1FIQmhjbUZ0SUhaaGJIVmxJQ0FnSUNCaElIWmhiSFZsSUhSdklIQnZjM1FzSUhSNWNHbGpZV3hzZVNCaGJpQmhjbkpoZVNCdlpseHVJQ29nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JwYm5adlkyRjBhVzl1SUdGeVozVnRaVzUwY3lCbWIzSWdjSEp2YldselpYTWdkR2hoZEZ4dUlDb2dJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQmhjbVVnZFd4MGFXMWhkR1ZzZVNCaVlXTnJaV1FnZDJsMGFDQmdjbVZ6YjJ4MlpXQWdkbUZzZFdWekxGeHVJQ29nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JoY3lCdmNIQnZjMlZrSUhSdklIUm9iM05sSUdKaFkydGxaQ0IzYVhSb0lGVlNUSE5jYmlBcUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2QyaGxjbVZwYmlCMGFHVWdjRzl6ZEdWa0lIWmhiSFZsSUdOaGJpQmlaU0JoYm5sY2JpQXFJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdTbE5QVGlCelpYSnBZV3hwZW1GaWJHVWdiMkpxWldOMExseHVJQ29nUUhKbGRIVnliaUJ3Y205dGFYTmxJR1p2Y2lCMGFHVWdjbVYwZFhKdUlIWmhiSFZsWEc0Z0tpOWNiaTh2SUdKdmRXNWtJR3h2WTJGc2JIa2dZbVZqWVhWelpTQnBkQ0JwY3lCMWMyVmtJR0o1SUc5MGFHVnlJRzFsZEdodlpITmNibEV1YldGd2NHeDVJRDBnTHk4Z1dGaFlJRUZ6SUhCeWIzQnZjMlZrSUdKNUlGd2lVbVZrYzJGdVpISnZYQ0pjYmxFdWNHOXpkQ0E5SUdaMWJtTjBhVzl1SUNodlltcGxZM1FzSUc1aGJXVXNJR0Z5WjNNcElIdGNiaUFnSUNCeVpYUjFjbTRnVVNodlltcGxZM1FwTG1ScGMzQmhkR05vS0Z3aWNHOXpkRndpTENCYmJtRnRaU3dnWVhKbmMxMHBPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXViV0Z3Y0d4NUlEMGdMeThnV0ZoWUlFRnpJSEJ5YjNCdmMyVmtJR0o1SUZ3aVVtVmtjMkZ1WkhKdlhDSmNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbkJ2YzNRZ1BTQm1kVzVqZEdsdmJpQW9ibUZ0WlN3Z1lYSm5jeWtnZTF4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TG1ScGMzQmhkR05vS0Z3aWNHOXpkRndpTENCYmJtRnRaU3dnWVhKbmMxMHBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQkpiblp2YTJWeklHRWdiV1YwYUc5a0lHbHVJR0VnWm5WMGRYSmxJSFIxY200dVhHNGdLaUJBY0dGeVlXMGdiMkpxWldOMElDQWdJSEJ5YjIxcGMyVWdiM0lnYVcxdFpXUnBZWFJsSUhKbFptVnlaVzVqWlNCbWIzSWdkR0Z5WjJWMElHOWlhbVZqZEZ4dUlDb2dRSEJoY21GdElHNWhiV1VnSUNBZ0lDQnVZVzFsSUc5bUlHMWxkR2h2WkNCMGJ5QnBiblp2YTJWY2JpQXFJRUJ3WVhKaGJTQXVMaTVoY21keklDQWdZWEp5WVhrZ2IyWWdhVzUyYjJOaGRHbHZiaUJoY21kMWJXVnVkSE5jYmlBcUlFQnlaWFIxY200Z2NISnZiV2x6WlNCbWIzSWdkR2hsSUhKbGRIVnliaUIyWVd4MVpWeHVJQ292WEc1UkxuTmxibVFnUFNBdkx5QllXRmdnVFdGeWF5Qk5hV3hzWlhJbmN5QndjbTl3YjNObFpDQndZWEpzWVc1alpWeHVVUzV0WTJGc2JDQTlJQzh2SUZoWVdDQkJjeUJ3Y205d2IzTmxaQ0JpZVNCY0lsSmxaSE5oYm1SeWIxd2lYRzVSTG1sdWRtOXJaU0E5SUdaMWJtTjBhVzl1SUNodlltcGxZM1FzSUc1aGJXVWdMeW91TGk1aGNtZHpLaThwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdVU2h2WW1wbFkzUXBMbVJwYzNCaGRHTm9LRndpY0c5emRGd2lMQ0JiYm1GdFpTd2dZWEp5WVhsZmMyeHBZMlVvWVhKbmRXMWxiblJ6TENBeUtWMHBPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVjMlZ1WkNBOUlDOHZJRmhZV0NCTllYSnJJRTFwYkd4bGNpZHpJSEJ5YjNCdmMyVmtJSEJoY214aGJtTmxYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzV0WTJGc2JDQTlJQzh2SUZoWVdDQkJjeUJ3Y205d2IzTmxaQ0JpZVNCY0lsSmxaSE5oYm1SeWIxd2lYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzVwYm5admEyVWdQU0JtZFc1amRHbHZiaUFvYm1GdFpTQXZLaTR1TG1GeVozTXFMeWtnZTF4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TG1ScGMzQmhkR05vS0Z3aWNHOXpkRndpTENCYmJtRnRaU3dnWVhKeVlYbGZjMnhwWTJVb1lYSm5kVzFsYm5SekxDQXhLVjBwTzF4dWZUdGNibHh1THlvcVhHNGdLaUJCY0hCc2FXVnpJSFJvWlNCd2NtOXRhWE5sWkNCbWRXNWpkR2x2YmlCcGJpQmhJR1oxZEhWeVpTQjBkWEp1TGx4dUlDb2dRSEJoY21GdElHOWlhbVZqZENBZ0lDQndjbTl0YVhObElHOXlJR2x0YldWa2FXRjBaU0J5WldabGNtVnVZMlVnWm05eUlIUmhjbWRsZENCbWRXNWpkR2x2Ymx4dUlDb2dRSEJoY21GdElHRnlaM01nSUNBZ0lDQmhjbkpoZVNCdlppQmhjSEJzYVdOaGRHbHZiaUJoY21kMWJXVnVkSE5jYmlBcUwxeHVVUzVtWVhCd2JIa2dQU0JtZFc1amRHbHZiaUFvYjJKcVpXTjBMQ0JoY21kektTQjdYRzRnSUNBZ2NtVjBkWEp1SUZFb2IySnFaV04wS1M1a2FYTndZWFJqYUNoY0ltRndjR3g1WENJc0lGdDJiMmxrSURBc0lHRnlaM05kS1R0Y2JuMDdYRzVjYmxCeWIyMXBjMlV1Y0hKdmRHOTBlWEJsTG1aaGNIQnNlU0E5SUdaMWJtTjBhVzl1SUNoaGNtZHpLU0I3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11WkdsemNHRjBZMmdvWENKaGNIQnNlVndpTENCYmRtOXBaQ0F3TENCaGNtZHpYU2s3WEc1OU8xeHVYRzR2S2lwY2JpQXFJRU5oYkd4eklIUm9aU0J3Y205dGFYTmxaQ0JtZFc1amRHbHZiaUJwYmlCaElHWjFkSFZ5WlNCMGRYSnVMbHh1SUNvZ1FIQmhjbUZ0SUc5aWFtVmpkQ0FnSUNCd2NtOXRhWE5sSUc5eUlHbHRiV1ZrYVdGMFpTQnlaV1psY21WdVkyVWdabTl5SUhSaGNtZGxkQ0JtZFc1amRHbHZibHh1SUNvZ1FIQmhjbUZ0SUM0dUxtRnlaM01nSUNCaGNuSmhlU0J2WmlCaGNIQnNhV05oZEdsdmJpQmhjbWQxYldWdWRITmNiaUFxTDF4dVVWdGNJblJ5ZVZ3aVhTQTlYRzVSTG1aallXeHNJRDBnWm5WdVkzUnBiMjRnS0c5aWFtVmpkQ0F2S2lBdUxpNWhjbWR6S2k4cElIdGNiaUFnSUNCeVpYUjFjbTRnVVNodlltcGxZM1FwTG1ScGMzQmhkR05vS0Z3aVlYQndiSGxjSWl3Z1czWnZhV1FnTUN3Z1lYSnlZWGxmYzJ4cFkyVW9ZWEpuZFcxbGJuUnpMQ0F4S1YwcE8xeHVmVHRjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdVptTmhiR3dnUFNCbWRXNWpkR2x2YmlBb0x5b3VMaTVoY21kektpOHBJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTVrYVhOd1lYUmphQ2hjSW1Gd2NHeDVYQ0lzSUZ0MmIybGtJREFzSUdGeWNtRjVYM05zYVdObEtHRnlaM1Z0Wlc1MGN5bGRLVHRjYm4wN1hHNWNiaThxS2x4dUlDb2dRbWx1WkhNZ2RHaGxJSEJ5YjIxcGMyVmtJR1oxYm1OMGFXOXVMQ0IwY21GdWMyWnZjbTFwYm1jZ2NtVjBkWEp1SUhaaGJIVmxjeUJwYm5SdklHRWdablZzWm1sc2JHVmtYRzRnS2lCd2NtOXRhWE5sSUdGdVpDQjBhSEp2ZDI0Z1pYSnliM0p6SUdsdWRHOGdZU0J5WldwbFkzUmxaQ0J2Ym1VdVhHNGdLaUJBY0dGeVlXMGdiMkpxWldOMElDQWdJSEJ5YjIxcGMyVWdiM0lnYVcxdFpXUnBZWFJsSUhKbFptVnlaVzVqWlNCbWIzSWdkR0Z5WjJWMElHWjFibU4wYVc5dVhHNGdLaUJBY0dGeVlXMGdMaTR1WVhKbmN5QWdJR0Z5Y21GNUlHOW1JR0Z3Y0d4cFkyRjBhVzl1SUdGeVozVnRaVzUwYzF4dUlDb3ZYRzVSTG1aaWFXNWtJRDBnWm5WdVkzUnBiMjRnS0c5aWFtVmpkQ0F2S2k0dUxtRnlaM01xTHlrZ2UxeHVJQ0FnSUhaaGNpQndjbTl0YVhObElEMGdVU2h2WW1wbFkzUXBPMXh1SUNBZ0lIWmhjaUJoY21keklEMGdZWEp5WVhsZmMyeHBZMlVvWVhKbmRXMWxiblJ6TENBeEtUdGNiaUFnSUNCeVpYUjFjbTRnWm5WdVkzUnBiMjRnWm1KdmRXNWtLQ2tnZTF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnY0hKdmJXbHpaUzVrYVhOd1lYUmphQ2hjSW1Gd2NHeDVYQ0lzSUZ0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFJvYVhNc1hHNGdJQ0FnSUNBZ0lDQWdJQ0JoY21kekxtTnZibU5oZENoaGNuSmhlVjl6YkdsalpTaGhjbWQxYldWdWRITXBLVnh1SUNBZ0lDQWdJQ0JkS1R0Y2JpQWdJQ0I5TzF4dWZUdGNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbVppYVc1a0lEMGdablZ1WTNScGIyNGdLQzhxTGk0dVlYSm5jeW92S1NCN1hHNGdJQ0FnZG1GeUlIQnliMjFwYzJVZ1BTQjBhR2x6TzF4dUlDQWdJSFpoY2lCaGNtZHpJRDBnWVhKeVlYbGZjMnhwWTJVb1lYSm5kVzFsYm5SektUdGNiaUFnSUNCeVpYUjFjbTRnWm5WdVkzUnBiMjRnWm1KdmRXNWtLQ2tnZTF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnY0hKdmJXbHpaUzVrYVhOd1lYUmphQ2hjSW1Gd2NHeDVYQ0lzSUZ0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFJvYVhNc1hHNGdJQ0FnSUNBZ0lDQWdJQ0JoY21kekxtTnZibU5oZENoaGNuSmhlVjl6YkdsalpTaGhjbWQxYldWdWRITXBLVnh1SUNBZ0lDQWdJQ0JkS1R0Y2JpQWdJQ0I5TzF4dWZUdGNibHh1THlvcVhHNGdLaUJTWlhGMVpYTjBjeUIwYUdVZ2JtRnRaWE1nYjJZZ2RHaGxJRzkzYm1Wa0lIQnliM0JsY25ScFpYTWdiMllnWVNCd2NtOXRhWE5sWkZ4dUlDb2diMkpxWldOMElHbHVJR0VnWm5WMGRYSmxJSFIxY200dVhHNGdLaUJBY0dGeVlXMGdiMkpxWldOMElDQWdJSEJ5YjIxcGMyVWdiM0lnYVcxdFpXUnBZWFJsSUhKbFptVnlaVzVqWlNCbWIzSWdkR0Z5WjJWMElHOWlhbVZqZEZ4dUlDb2dRSEpsZEhWeWJpQndjbTl0YVhObElHWnZjaUIwYUdVZ2EyVjVjeUJ2WmlCMGFHVWdaWFpsYm5SMVlXeHNlU0J6WlhSMGJHVmtJRzlpYW1WamRGeHVJQ292WEc1UkxtdGxlWE1nUFNCbWRXNWpkR2x2YmlBb2IySnFaV04wS1NCN1hHNGdJQ0FnY21WMGRYSnVJRkVvYjJKcVpXTjBLUzVrYVhOd1lYUmphQ2hjSW10bGVYTmNJaXdnVzEwcE8xeHVmVHRjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWEyVjVjeUE5SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNCeVpYUjFjbTRnZEdocGN5NWthWE53WVhSamFDaGNJbXRsZVhOY0lpd2dXMTBwTzF4dWZUdGNibHh1THlvcVhHNGdLaUJVZFhKdWN5QmhiaUJoY25KaGVTQnZaaUJ3Y205dGFYTmxjeUJwYm5SdklHRWdjSEp2YldselpTQm1iM0lnWVc0Z1lYSnlZWGt1SUNCSlppQmhibmtnYjJaY2JpQXFJSFJvWlNCd2NtOXRhWE5sY3lCblpYUnpJSEpsYW1WamRHVmtMQ0IwYUdVZ2QyaHZiR1VnWVhKeVlYa2dhWE1nY21WcVpXTjBaV1FnYVcxdFpXUnBZWFJsYkhrdVhHNGdLaUJBY0dGeVlXMGdlMEZ5Y21GNUtuMGdZVzRnWVhKeVlYa2dLRzl5SUhCeWIyMXBjMlVnWm05eUlHRnVJR0Z5Y21GNUtTQnZaaUIyWVd4MVpYTWdLRzl5WEc0Z0tpQndjbTl0YVhObGN5Qm1iM0lnZG1Gc2RXVnpLVnh1SUNvZ1FISmxkSFZ5Ym5NZ1lTQndjbTl0YVhObElHWnZjaUJoYmlCaGNuSmhlU0J2WmlCMGFHVWdZMjl5Y21WemNHOXVaR2x1WnlCMllXeDFaWE5jYmlBcUwxeHVMeThnUW5rZ1RXRnlheUJOYVd4c1pYSmNiaTh2SUdoMGRIQTZMeTkzYVd0cExtVmpiV0Z6WTNKcGNIUXViM0puTDJSdmEzVXVjR2h3UDJsa1BYTjBjbUYzYldGdU9tTnZibU4xY25KbGJtTjVKbkpsZGoweE16QTROemMyTlRJeEkyRnNiR1oxYkdacGJHeGxaRnh1VVM1aGJHd2dQU0JoYkd3N1hHNW1kVzVqZEdsdmJpQmhiR3dvY0hKdmJXbHpaWE1wSUh0Y2JpQWdJQ0J5WlhSMWNtNGdkMmhsYmlod2NtOXRhWE5sY3l3Z1puVnVZM1JwYjI0Z0tIQnliMjFwYzJWektTQjdYRzRnSUNBZ0lDQWdJSFpoY2lCd1pXNWthVzVuUTI5MWJuUWdQU0F3TzF4dUlDQWdJQ0FnSUNCMllYSWdaR1ZtWlhKeVpXUWdQU0JrWldabGNpZ3BPMXh1SUNBZ0lDQWdJQ0JoY25KaGVWOXlaV1IxWTJVb2NISnZiV2x6WlhNc0lHWjFibU4wYVc5dUlDaDFibVJsWm1sdVpXUXNJSEJ5YjIxcGMyVXNJR2x1WkdWNEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCMllYSWdjMjVoY0hOb2IzUTdYRzRnSUNBZ0lDQWdJQ0FnSUNCcFppQW9YRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdhWE5RY205dGFYTmxLSEJ5YjIxcGMyVXBJQ1ltWEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnS0hOdVlYQnphRzkwSUQwZ2NISnZiV2x6WlM1cGJuTndaV04wS0NrcExuTjBZWFJsSUQwOVBTQmNJbVoxYkdacGJHeGxaRndpWEc0Z0lDQWdJQ0FnSUNBZ0lDQXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0J3Y205dGFYTmxjMXRwYm1SbGVGMGdQU0J6Ym1Gd2MyaHZkQzUyWVd4MVpUdGNiaUFnSUNBZ0lDQWdJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnS3l0d1pXNWthVzVuUTI5MWJuUTdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdkMmhsYmloY2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdjSEp2YldselpTeGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnWm5WdVkzUnBiMjRnS0haaGJIVmxLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0J3Y205dGFYTmxjMXRwYm1SbGVGMGdQU0IyWVd4MVpUdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHbG1JQ2d0TFhCbGJtUnBibWREYjNWdWRDQTlQVDBnTUNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJR1JsWm1WeWNtVmtMbkpsYzI5c2RtVW9jSEp2YldselpYTXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCOUxGeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JrWldabGNuSmxaQzV5WldwbFkzUXNYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUdaMWJtTjBhVzl1SUNod2NtOW5jbVZ6Y3lrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ1pHVm1aWEp5WldRdWJtOTBhV1o1S0hzZ2FXNWtaWGc2SUdsdVpHVjRMQ0IyWVd4MVpUb2djSEp2WjNKbGMzTWdmU2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQjlMQ0IyYjJsa0lEQXBPMXh1SUNBZ0lDQWdJQ0JwWmlBb2NHVnVaR2x1WjBOdmRXNTBJRDA5UFNBd0tTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCa1pXWmxjbkpsWkM1eVpYTnZiSFpsS0hCeWIyMXBjMlZ6S1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQnlaWFIxY200Z1pHVm1aWEp5WldRdWNISnZiV2x6WlR0Y2JpQWdJQ0I5S1R0Y2JuMWNibHh1VUhKdmJXbHpaUzV3Y205MGIzUjVjR1V1WVd4c0lEMGdablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQmhiR3dvZEdocGN5azdYRzU5TzF4dVhHNHZLaXBjYmlBcUlGSmxkSFZ5Ym5NZ2RHaGxJR1pwY25OMElISmxjMjlzZG1Wa0lIQnliMjFwYzJVZ2IyWWdZVzRnWVhKeVlYa3VJRkJ5YVc5eUlISmxhbVZqZEdWa0lIQnliMjFwYzJWeklHRnlaVnh1SUNvZ2FXZHViM0psWkM0Z0lGSmxhbVZqZEhNZ2IyNXNlU0JwWmlCaGJHd2djSEp2YldselpYTWdZWEpsSUhKbGFtVmpkR1ZrTGx4dUlDb2dRSEJoY21GdElIdEJjbkpoZVNwOUlHRnVJR0Z5Y21GNUlHTnZiblJoYVc1cGJtY2dkbUZzZFdWeklHOXlJSEJ5YjIxcGMyVnpJR1p2Y2lCMllXeDFaWE5jYmlBcUlFQnlaWFIxY201eklHRWdjSEp2YldselpTQm1kV3htYVd4c1pXUWdkMmwwYUNCMGFHVWdkbUZzZFdVZ2IyWWdkR2hsSUdacGNuTjBJSEpsYzI5c2RtVmtJSEJ5YjIxcGMyVXNYRzRnS2lCdmNpQmhJSEpsYW1WamRHVmtJSEJ5YjIxcGMyVWdhV1lnWVd4c0lIQnliMjFwYzJWeklHRnlaU0J5WldwbFkzUmxaQzVjYmlBcUwxeHVVUzVoYm5rZ1BTQmhibms3WEc1Y2JtWjFibU4wYVc5dUlHRnVlU2h3Y205dGFYTmxjeWtnZTF4dUlDQWdJR2xtSUNod2NtOXRhWE5sY3k1c1pXNW5kR2dnUFQwOUlEQXBJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJRkV1Y21WemIyeDJaU2dwTzF4dUlDQWdJSDFjYmx4dUlDQWdJSFpoY2lCa1pXWmxjbkpsWkNBOUlGRXVaR1ZtWlhJb0tUdGNiaUFnSUNCMllYSWdjR1Z1WkdsdVowTnZkVzUwSUQwZ01EdGNiaUFnSUNCaGNuSmhlVjl5WldSMVkyVW9jSEp2YldselpYTXNJR1oxYm1OMGFXOXVJQ2h3Y21WMkxDQmpkWEp5Wlc1MExDQnBibVJsZUNrZ2UxeHVJQ0FnSUNBZ0lDQjJZWElnY0hKdmJXbHpaU0E5SUhCeWIyMXBjMlZ6VzJsdVpHVjRYVHRjYmx4dUlDQWdJQ0FnSUNCd1pXNWthVzVuUTI5MWJuUXJLenRjYmx4dUlDQWdJQ0FnSUNCM2FHVnVLSEJ5YjIxcGMyVXNJRzl1Um5Wc1ptbHNiR1ZrTENCdmJsSmxhbVZqZEdWa0xDQnZibEJ5YjJkeVpYTnpLVHRjYmlBZ0lDQWdJQ0FnWm5WdVkzUnBiMjRnYjI1R2RXeG1hV3hzWldRb2NtVnpkV3gwS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JrWldabGNuSmxaQzV5WlhOdmJIWmxLSEpsYzNWc2RDazdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnWm5WdVkzUnBiMjRnYjI1U1pXcGxZM1JsWkNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhCbGJtUnBibWREYjNWdWRDMHRPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLSEJsYm1ScGJtZERiM1Z1ZENBOVBUMGdNQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUdSbFptVnljbVZrTG5KbGFtVmpkQ2h1WlhjZ1JYSnliM0lvWEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lGd2lRMkZ1SjNRZ1oyVjBJR1oxYkdacGJHeHRaVzUwSUhaaGJIVmxJR1p5YjIwZ1lXNTVJSEJ5YjIxcGMyVXNJR0ZzYkNCY0lpQXJYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUZ3aWNISnZiV2x6WlhNZ2QyVnlaU0J5WldwbFkzUmxaQzVjSWx4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNrcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lHWjFibU4wYVc5dUlHOXVVSEp2WjNKbGMzTW9jSEp2WjNKbGMzTXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHUmxabVZ5Y21Wa0xtNXZkR2xtZVNoN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2FXNWtaWGc2SUdsdVpHVjRMRnh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSFpoYkhWbE9pQndjbTluY21WemMxeHVJQ0FnSUNBZ0lDQWdJQ0FnZlNrN1hHNGdJQ0FnSUNBZ0lIMWNiaUFnSUNCOUxDQjFibVJsWm1sdVpXUXBPMXh1WEc0Z0lDQWdjbVYwZFhKdUlHUmxabVZ5Y21Wa0xuQnliMjFwYzJVN1hHNTlYRzVjYmxCeWIyMXBjMlV1Y0hKdmRHOTBlWEJsTG1GdWVTQTlJR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdZVzU1S0hSb2FYTXBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQlhZV2wwY3lCbWIzSWdZV3hzSUhCeWIyMXBjMlZ6SUhSdklHSmxJSE5sZEhSc1pXUXNJR1ZwZEdobGNpQm1kV3htYVd4c1pXUWdiM0pjYmlBcUlISmxhbVZqZEdWa0xpQWdWR2hwY3lCcGN5QmthWE4wYVc1amRDQm1jbTl0SUdCaGJHeGdJSE5wYm1ObElIUm9ZWFFnZDI5MWJHUWdjM1J2Y0Z4dUlDb2dkMkZwZEdsdVp5QmhkQ0IwYUdVZ1ptbHljM1FnY21WcVpXTjBhVzl1TGlBZ1ZHaGxJSEJ5YjIxcGMyVWdjbVYwZFhKdVpXUWdZbmxjYmlBcUlHQmhiR3hTWlhOdmJIWmxaR0FnZDJsc2JDQnVaWFpsY2lCaVpTQnlaV3BsWTNSbFpDNWNiaUFxSUVCd1lYSmhiU0J3Y205dGFYTmxjeUJoSUhCeWIyMXBjMlVnWm05eUlHRnVJR0Z5Y21GNUlDaHZjaUJoYmlCaGNuSmhlU2tnYjJZZ2NISnZiV2x6WlhOY2JpQXFJQ2h2Y2lCMllXeDFaWE1wWEc0Z0tpQkFjbVYwZFhKdUlHRWdjSEp2YldselpTQm1iM0lnWVc0Z1lYSnlZWGtnYjJZZ2NISnZiV2x6WlhOY2JpQXFMMXh1VVM1aGJHeFNaWE52YkhabFpDQTlJR1JsY0hKbFkyRjBaU2hoYkd4U1pYTnZiSFpsWkN3Z1hDSmhiR3hTWlhOdmJIWmxaRndpTENCY0ltRnNiRk5sZEhSc1pXUmNJaWs3WEc1bWRXNWpkR2x2YmlCaGJHeFNaWE52YkhabFpDaHdjbTl0YVhObGN5a2dlMXh1SUNBZ0lISmxkSFZ5YmlCM2FHVnVLSEJ5YjIxcGMyVnpMQ0JtZFc1amRHbHZiaUFvY0hKdmJXbHpaWE1wSUh0Y2JpQWdJQ0FnSUNBZ2NISnZiV2x6WlhNZ1BTQmhjbkpoZVY5dFlYQW9jSEp2YldselpYTXNJRkVwTzF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnZDJobGJpaGhiR3dvWVhKeVlYbGZiV0Z3S0hCeWIyMXBjMlZ6TENCbWRXNWpkR2x2YmlBb2NISnZiV2x6WlNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSGRvWlc0b2NISnZiV2x6WlN3Z2JtOXZjQ3dnYm05dmNDazdYRzRnSUNBZ0lDQWdJSDBwS1N3Z1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhCeWIyMXBjMlZ6TzF4dUlDQWdJQ0FnSUNCOUtUdGNiaUFnSUNCOUtUdGNibjFjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdVlXeHNVbVZ6YjJ4MlpXUWdQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnY21WMGRYSnVJR0ZzYkZKbGMyOXNkbVZrS0hSb2FYTXBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQkFjMlZsSUZCeWIyMXBjMlVqWVd4c1UyVjBkR3hsWkZ4dUlDb3ZYRzVSTG1Gc2JGTmxkSFJzWldRZ1BTQmhiR3hUWlhSMGJHVmtPMXh1Wm5WdVkzUnBiMjRnWVd4c1UyVjBkR3hsWkNod2NtOXRhWE5sY3lrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0hCeWIyMXBjMlZ6S1M1aGJHeFRaWFIwYkdWa0tDazdYRzU5WEc1Y2JpOHFLbHh1SUNvZ1ZIVnlibk1nWVc0Z1lYSnlZWGtnYjJZZ2NISnZiV2x6WlhNZ2FXNTBieUJoSUhCeWIyMXBjMlVnWm05eUlHRnVJR0Z5Y21GNUlHOW1JSFJvWldseUlITjBZWFJsY3lBb1lYTmNiaUFxSUhKbGRIVnlibVZrSUdKNUlHQnBibk53WldOMFlDa2dkMmhsYmlCMGFHVjVJR2hoZG1VZ1lXeHNJSE5sZEhSc1pXUXVYRzRnS2lCQWNHRnlZVzBnZTBGeWNtRjVXMEZ1ZVNwZGZTQjJZV3gxWlhNZ1lXNGdZWEp5WVhrZ0tHOXlJSEJ5YjIxcGMyVWdabTl5SUdGdUlHRnljbUY1S1NCdlppQjJZV3gxWlhNZ0tHOXlYRzRnS2lCd2NtOXRhWE5sY3lCbWIzSWdkbUZzZFdWektWeHVJQ29nUUhKbGRIVnlibk1nZTBGeWNtRjVXMU4wWVhSbFhYMGdZVzRnWVhKeVlYa2diMllnYzNSaGRHVnpJR1p2Y2lCMGFHVWdjbVZ6Y0dWamRHbDJaU0IyWVd4MVpYTXVYRzRnS2k5Y2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExtRnNiRk5sZEhSc1pXUWdQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnY21WMGRYSnVJSFJvYVhNdWRHaGxiaWhtZFc1amRHbHZiaUFvY0hKdmJXbHpaWE1wSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUdGc2JDaGhjbkpoZVY5dFlYQW9jSEp2YldselpYTXNJR1oxYm1OMGFXOXVJQ2h3Y205dGFYTmxLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQndjbTl0YVhObElEMGdVU2h3Y205dGFYTmxLVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHWjFibU4wYVc5dUlISmxaMkZ5Wkd4bGMzTW9LU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSEJ5YjIxcGMyVXVhVzV6Y0dWamRDZ3BPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSEJ5YjIxcGMyVXVkR2hsYmloeVpXZGhjbVJzWlhOekxDQnlaV2RoY21Sc1pYTnpLVHRjYmlBZ0lDQWdJQ0FnZlNrcE8xeHVJQ0FnSUgwcE8xeHVmVHRjYmx4dUx5b3FYRzRnS2lCRFlYQjBkWEpsY3lCMGFHVWdabUZwYkhWeVpTQnZaaUJoSUhCeWIyMXBjMlVzSUdkcGRtbHVaeUJoYmlCdmNHOXlkSFZ1YVhSNUlIUnZJSEpsWTI5MlpYSmNiaUFxSUhkcGRHZ2dZU0JqWVd4c1ltRmpheTRnSUVsbUlIUm9aU0JuYVhabGJpQndjbTl0YVhObElHbHpJR1oxYkdacGJHeGxaQ3dnZEdobElISmxkSFZ5Ym1Wa1hHNGdLaUJ3Y205dGFYTmxJR2x6SUdaMWJHWnBiR3hsWkM1Y2JpQXFJRUJ3WVhKaGJTQjdRVzU1S24wZ2NISnZiV2x6WlNCbWIzSWdjMjl0WlhSb2FXNW5YRzRnS2lCQWNHRnlZVzBnZTBaMWJtTjBhVzl1ZlNCallXeHNZbUZqYXlCMGJ5Qm1kV3htYVd4c0lIUm9aU0J5WlhSMWNtNWxaQ0J3Y205dGFYTmxJR2xtSUhSb1pWeHVJQ29nWjJsMlpXNGdjSEp2YldselpTQnBjeUJ5WldwbFkzUmxaRnh1SUNvZ1FISmxkSFZ5Ym5NZ1lTQndjbTl0YVhObElHWnZjaUIwYUdVZ2NtVjBkWEp1SUhaaGJIVmxJRzltSUhSb1pTQmpZV3hzWW1GamExeHVJQ292WEc1UkxtWmhhV3dnUFNBdkx5QllXRmdnYkdWbllXTjVYRzVSVzF3aVkyRjBZMmhjSWwwZ1BTQm1kVzVqZEdsdmJpQW9iMkpxWldOMExDQnlaV3BsWTNSbFpDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCUktHOWlhbVZqZENrdWRHaGxiaWgyYjJsa0lEQXNJSEpsYW1WamRHVmtLVHRjYm4wN1hHNWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbVpoYVd3Z1BTQXZMeUJZV0ZnZ2JHVm5ZV041WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlZ0Y0ltTmhkR05vWENKZElEMGdablZ1WTNScGIyNGdLSEpsYW1WamRHVmtLU0I3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11ZEdobGJpaDJiMmxrSURBc0lISmxhbVZqZEdWa0tUdGNibjA3WEc1Y2JpOHFLbHh1SUNvZ1FYUjBZV05vWlhNZ1lTQnNhWE4wWlc1bGNpQjBhR0YwSUdOaGJpQnlaWE53YjI1a0lIUnZJSEJ5YjJkeVpYTnpJRzV2ZEdsbWFXTmhkR2x2Ym5NZ1puSnZiU0JoWEc0Z0tpQndjbTl0YVhObEozTWdiM0pwWjJsdVlYUnBibWNnWkdWbVpYSnlaV1F1SUZSb2FYTWdiR2x6ZEdWdVpYSWdjbVZqWldsMlpYTWdkR2hsSUdWNFlXTjBJR0Z5WjNWdFpXNTBjMXh1SUNvZ2NHRnpjMlZrSUhSdklHQmdaR1ZtWlhKeVpXUXVibTkwYVdaNVlHQXVYRzRnS2lCQWNHRnlZVzBnZTBGdWVTcDlJSEJ5YjIxcGMyVWdabTl5SUhOdmJXVjBhR2x1WjF4dUlDb2dRSEJoY21GdElIdEdkVzVqZEdsdmJuMGdZMkZzYkdKaFkyc2dkRzhnY21WalpXbDJaU0JoYm5rZ2NISnZaM0psYzNNZ2JtOTBhV1pwWTJGMGFXOXVjMXh1SUNvZ1FISmxkSFZ5Ym5NZ2RHaGxJR2RwZG1WdUlIQnliMjFwYzJVc0lIVnVZMmhoYm1kbFpGeHVJQ292WEc1UkxuQnliMmR5WlhOeklEMGdjSEp2WjNKbGMzTTdYRzVtZFc1amRHbHZiaUJ3Y205bmNtVnpjeWh2WW1wbFkzUXNJSEJ5YjJkeVpYTnpaV1FwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdVU2h2WW1wbFkzUXBMblJvWlc0b2RtOXBaQ0F3TENCMmIybGtJREFzSUhCeWIyZHlaWE56WldRcE8xeHVmVnh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1d2NtOW5jbVZ6Y3lBOUlHWjFibU4wYVc5dUlDaHdjbTluY21WemMyVmtLU0I3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11ZEdobGJpaDJiMmxrSURBc0lIWnZhV1FnTUN3Z2NISnZaM0psYzNObFpDazdYRzU5TzF4dVhHNHZLaXBjYmlBcUlGQnliM1pwWkdWeklHRnVJRzl3Y0c5eWRIVnVhWFI1SUhSdklHOWljMlZ5ZG1VZ2RHaGxJSE5sZEhSc2FXNW5JRzltSUdFZ2NISnZiV2x6WlN4Y2JpQXFJSEpsWjJGeVpHeGxjM01nYjJZZ2QyaGxkR2hsY2lCMGFHVWdjSEp2YldselpTQnBjeUJtZFd4bWFXeHNaV1FnYjNJZ2NtVnFaV04wWldRdUlDQkdiM0ozWVhKa2MxeHVJQ29nZEdobElISmxjMjlzZFhScGIyNGdkRzhnZEdobElISmxkSFZ5Ym1Wa0lIQnliMjFwYzJVZ2QyaGxiaUIwYUdVZ1kyRnNiR0poWTJzZ2FYTWdaRzl1WlM1Y2JpQXFJRlJvWlNCallXeHNZbUZqYXlCallXNGdjbVYwZFhKdUlHRWdjSEp2YldselpTQjBieUJrWldabGNpQmpiMjF3YkdWMGFXOXVMbHh1SUNvZ1FIQmhjbUZ0SUh0QmJua3FmU0J3Y205dGFYTmxYRzRnS2lCQWNHRnlZVzBnZTBaMWJtTjBhVzl1ZlNCallXeHNZbUZqYXlCMGJ5QnZZbk5sY25abElIUm9aU0J5WlhOdmJIVjBhVzl1SUc5bUlIUm9aU0JuYVhabGJseHVJQ29nY0hKdmJXbHpaU3dnZEdGclpYTWdibThnWVhKbmRXMWxiblJ6TGx4dUlDb2dRSEpsZEhWeWJuTWdZU0J3Y205dGFYTmxJR1p2Y2lCMGFHVWdjbVZ6YjJ4MWRHbHZiaUJ2WmlCMGFHVWdaMmwyWlc0Z2NISnZiV2x6WlNCM2FHVnVYRzRnS2lCZ1lHWnBibUJnSUdseklHUnZibVV1WEc0Z0tpOWNibEV1Wm1sdUlEMGdMeThnV0ZoWUlHeGxaMkZqZVZ4dVVWdGNJbVpwYm1Gc2JIbGNJbDBnUFNCbWRXNWpkR2x2YmlBb2IySnFaV04wTENCallXeHNZbUZqYXlrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0c5aWFtVmpkQ2xiWENKbWFXNWhiR3g1WENKZEtHTmhiR3hpWVdOcktUdGNibjA3WEc1Y2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExtWnBiaUE5SUM4dklGaFlXQ0JzWldkaFkzbGNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxXMXdpWm1sdVlXeHNlVndpWFNBOUlHWjFibU4wYVc5dUlDaGpZV3hzWW1GamF5a2dlMXh1SUNBZ0lHTmhiR3hpWVdOcklEMGdVU2hqWVd4c1ltRmpheWs3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11ZEdobGJpaG1kVzVqZEdsdmJpQW9kbUZzZFdVcElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHTmhiR3hpWVdOckxtWmpZV3hzS0NrdWRHaGxiaWhtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdkbUZzZFdVN1hHNGdJQ0FnSUNBZ0lIMHBPMXh1SUNBZ0lIMHNJR1oxYm1OMGFXOXVJQ2h5WldGemIyNHBJSHRjYmlBZ0lDQWdJQ0FnTHk4Z1ZFOUVUeUJoZEhSbGJYQjBJSFJ2SUhKbFkzbGpiR1VnZEdobElISmxhbVZqZEdsdmJpQjNhWFJvSUZ3aWRHaHBjMXdpTGx4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnWTJGc2JHSmhZMnN1Wm1OaGJHd29LUzUwYUdWdUtHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIUm9jbTkzSUhKbFlYTnZianRjYmlBZ0lDQWdJQ0FnZlNrN1hHNGdJQ0FnZlNrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUZSbGNtMXBibUYwWlhNZ1lTQmphR0ZwYmlCdlppQndjbTl0YVhObGN5d2dabTl5WTJsdVp5QnlaV3BsWTNScGIyNXpJSFJ2SUdKbFhHNGdLaUIwYUhKdmQyNGdZWE1nWlhoalpYQjBhVzl1Y3k1Y2JpQXFJRUJ3WVhKaGJTQjdRVzU1S24wZ2NISnZiV2x6WlNCaGRDQjBhR1VnWlc1a0lHOW1JR0VnWTJoaGFXNGdiMllnY0hKdmJXbHpaWE5jYmlBcUlFQnlaWFIxY201eklHNXZkR2hwYm1kY2JpQXFMMXh1VVM1a2IyNWxJRDBnWm5WdVkzUnBiMjRnS0c5aWFtVmpkQ3dnWm5Wc1ptbHNiR1ZrTENCeVpXcGxZM1JsWkN3Z2NISnZaM0psYzNNcElIdGNiaUFnSUNCeVpYUjFjbTRnVVNodlltcGxZM1FwTG1SdmJtVW9ablZzWm1sc2JHVmtMQ0J5WldwbFkzUmxaQ3dnY0hKdlozSmxjM01wTzF4dWZUdGNibHh1VUhKdmJXbHpaUzV3Y205MGIzUjVjR1V1Wkc5dVpTQTlJR1oxYm1OMGFXOXVJQ2htZFd4bWFXeHNaV1FzSUhKbGFtVmpkR1ZrTENCd2NtOW5jbVZ6Y3lrZ2UxeHVJQ0FnSUhaaGNpQnZibFZ1YUdGdVpHeGxaRVZ5Y205eUlEMGdablZ1WTNScGIyNGdLR1Z5Y205eUtTQjdYRzRnSUNBZ0lDQWdJQzh2SUdadmNuZGhjbVFnZEc4Z1lTQm1kWFIxY21VZ2RIVnliaUJ6YnlCMGFHRjBJR0JnZDJobGJtQmdYRzRnSUNBZ0lDQWdJQzh2SUdSdlpYTWdibTkwSUdOaGRHTm9JR2wwSUdGdVpDQjBkWEp1SUdsMElHbHVkRzhnWVNCeVpXcGxZM1JwYjI0dVhHNGdJQ0FnSUNBZ0lGRXVibVY0ZEZScFkyc29ablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdiV0ZyWlZOMFlXTnJWSEpoWTJWTWIyNW5LR1Z5Y205eUxDQndjbTl0YVhObEtUdGNiaUFnSUNBZ0lDQWdJQ0FnSUdsbUlDaFJMbTl1WlhKeWIzSXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JSTG05dVpYSnliM0lvWlhKeWIzSXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCMGFISnZkeUJsY25KdmNqdGNiaUFnSUNBZ0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ2ZTazdYRzRnSUNBZ2ZUdGNibHh1SUNBZ0lDOHZJRUYyYjJsa0lIVnVibVZqWlhOellYSjVJR0J1WlhoMFZHbGphMkJwYm1jZ2RtbGhJR0Z1SUhWdWJtVmpaWE56WVhKNUlHQjNhR1Z1WUM1Y2JpQWdJQ0IyWVhJZ2NISnZiV2x6WlNBOUlHWjFiR1pwYkd4bFpDQjhmQ0J5WldwbFkzUmxaQ0I4ZkNCd2NtOW5jbVZ6Y3lBL1hHNGdJQ0FnSUNBZ0lIUm9hWE11ZEdobGJpaG1kV3htYVd4c1pXUXNJSEpsYW1WamRHVmtMQ0J3Y205bmNtVnpjeWtnT2x4dUlDQWdJQ0FnSUNCMGFHbHpPMXh1WEc0Z0lDQWdhV1lnS0hSNWNHVnZaaUJ3Y205alpYTnpJRDA5UFNCY0ltOWlhbVZqZEZ3aUlDWW1JSEJ5YjJObGMzTWdKaVlnY0hKdlkyVnpjeTVrYjIxaGFXNHBJSHRjYmlBZ0lDQWdJQ0FnYjI1VmJtaGhibVJzWldSRmNuSnZjaUE5SUhCeWIyTmxjM011Wkc5dFlXbHVMbUpwYm1Rb2IyNVZibWhoYm1Sc1pXUkZjbkp2Y2lrN1hHNGdJQ0FnZlZ4dVhHNGdJQ0FnY0hKdmJXbHpaUzUwYUdWdUtIWnZhV1FnTUN3Z2IyNVZibWhoYm1Sc1pXUkZjbkp2Y2lrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUVOaGRYTmxjeUJoSUhCeWIyMXBjMlVnZEc4Z1ltVWdjbVZxWldOMFpXUWdhV1lnYVhRZ1pHOWxjeUJ1YjNRZ1oyVjBJR1oxYkdacGJHeGxaQ0JpWldadmNtVmNiaUFxSUhOdmJXVWdiV2xzYkdselpXTnZibVJ6SUhScGJXVWdiM1YwTGx4dUlDb2dRSEJoY21GdElIdEJibmtxZlNCd2NtOXRhWE5sWEc0Z0tpQkFjR0Z5WVcwZ2UwNTFiV0psY24wZ2JXbHNiR2x6WldOdmJtUnpJSFJwYldWdmRYUmNiaUFxSUVCd1lYSmhiU0I3UVc1NUtuMGdZM1Z6ZEc5dElHVnljbTl5SUcxbGMzTmhaMlVnYjNJZ1JYSnliM0lnYjJKcVpXTjBJQ2h2Y0hScGIyNWhiQ2xjYmlBcUlFQnlaWFIxY201eklHRWdjSEp2YldselpTQm1iM0lnZEdobElISmxjMjlzZFhScGIyNGdiMllnZEdobElHZHBkbVZ1SUhCeWIyMXBjMlVnYVdZZ2FYUWdhWE5jYmlBcUlHWjFiR1pwYkd4bFpDQmlaV1p2Y21VZ2RHaGxJSFJwYldWdmRYUXNJRzkwYUdWeWQybHpaU0J5WldwbFkzUmxaQzVjYmlBcUwxeHVVUzUwYVcxbGIzVjBJRDBnWm5WdVkzUnBiMjRnS0c5aWFtVmpkQ3dnYlhNc0lHVnljbTl5S1NCN1hHNGdJQ0FnY21WMGRYSnVJRkVvYjJKcVpXTjBLUzUwYVcxbGIzVjBLRzF6TENCbGNuSnZjaWs3WEc1OU8xeHVYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzUwYVcxbGIzVjBJRDBnWm5WdVkzUnBiMjRnS0cxekxDQmxjbkp2Y2lrZ2UxeHVJQ0FnSUhaaGNpQmtaV1psY25KbFpDQTlJR1JsWm1WeUtDazdYRzRnSUNBZ2RtRnlJSFJwYldWdmRYUkpaQ0E5SUhObGRGUnBiV1Z2ZFhRb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0JwWmlBb0lXVnljbTl5SUh4OElGd2ljM1J5YVc1blhDSWdQVDA5SUhSNWNHVnZaaUJsY25KdmNpa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ1pYSnliM0lnUFNCdVpYY2dSWEp5YjNJb1pYSnliM0lnZkh3Z1hDSlVhVzFsWkNCdmRYUWdZV1owWlhJZ1hDSWdLeUJ0Y3lBcklGd2lJRzF6WENJcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnWlhKeWIzSXVZMjlrWlNBOUlGd2lSVlJKVFVWRVQxVlVYQ0k3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ1pHVm1aWEp5WldRdWNtVnFaV04wS0dWeWNtOXlLVHRjYmlBZ0lDQjlMQ0J0Y3lrN1hHNWNiaUFnSUNCMGFHbHpMblJvWlc0b1puVnVZM1JwYjI0Z0tIWmhiSFZsS1NCN1hHNGdJQ0FnSUNBZ0lHTnNaV0Z5VkdsdFpXOTFkQ2gwYVcxbGIzVjBTV1FwTzF4dUlDQWdJQ0FnSUNCa1pXWmxjbkpsWkM1eVpYTnZiSFpsS0haaGJIVmxLVHRjYmlBZ0lDQjlMQ0JtZFc1amRHbHZiaUFvWlhoalpYQjBhVzl1S1NCN1hHNGdJQ0FnSUNBZ0lHTnNaV0Z5VkdsdFpXOTFkQ2gwYVcxbGIzVjBTV1FwTzF4dUlDQWdJQ0FnSUNCa1pXWmxjbkpsWkM1eVpXcGxZM1FvWlhoalpYQjBhVzl1S1R0Y2JpQWdJQ0I5TENCa1pXWmxjbkpsWkM1dWIzUnBabmtwTzF4dVhHNGdJQ0FnY21WMGRYSnVJR1JsWm1WeWNtVmtMbkJ5YjIxcGMyVTdYRzU5TzF4dVhHNHZLaXBjYmlBcUlGSmxkSFZ5Ym5NZ1lTQndjbTl0YVhObElHWnZjaUIwYUdVZ1oybDJaVzRnZG1Gc2RXVWdLRzl5SUhCeWIyMXBjMlZrSUhaaGJIVmxLU3dnYzI5dFpWeHVJQ29nYldsc2JHbHpaV052Ym1SeklHRm1kR1Z5SUdsMElISmxjMjlzZG1Wa0xpQlFZWE56WlhNZ2NtVnFaV04wYVc5dWN5QnBiVzFsWkdsaGRHVnNlUzVjYmlBcUlFQndZWEpoYlNCN1FXNTVLbjBnY0hKdmJXbHpaVnh1SUNvZ1FIQmhjbUZ0SUh0T2RXMWlaWEo5SUcxcGJHeHBjMlZqYjI1a2MxeHVJQ29nUUhKbGRIVnlibk1nWVNCd2NtOXRhWE5sSUdadmNpQjBhR1VnY21WemIyeDFkR2x2YmlCdlppQjBhR1VnWjJsMlpXNGdjSEp2YldselpTQmhablJsY2lCdGFXeHNhWE5sWTI5dVpITmNiaUFxSUhScGJXVWdhR0Z6SUdWc1lYQnpaV1FnYzJsdVkyVWdkR2hsSUhKbGMyOXNkWFJwYjI0Z2IyWWdkR2hsSUdkcGRtVnVJSEJ5YjIxcGMyVXVYRzRnS2lCSlppQjBhR1VnWjJsMlpXNGdjSEp2YldselpTQnlaV3BsWTNSekxDQjBhR0YwSUdseklIQmhjM05sWkNCcGJXMWxaR2xoZEdWc2VTNWNiaUFxTDF4dVVTNWtaV3hoZVNBOUlHWjFibU4wYVc5dUlDaHZZbXBsWTNRc0lIUnBiV1Z2ZFhRcElIdGNiaUFnSUNCcFppQW9kR2x0Wlc5MWRDQTlQVDBnZG05cFpDQXdLU0I3WEc0Z0lDQWdJQ0FnSUhScGJXVnZkWFFnUFNCdlltcGxZM1E3WEc0Z0lDQWdJQ0FnSUc5aWFtVmpkQ0E5SUhadmFXUWdNRHRjYmlBZ0lDQjlYRzRnSUNBZ2NtVjBkWEp1SUZFb2IySnFaV04wS1M1a1pXeGhlU2gwYVcxbGIzVjBLVHRjYm4wN1hHNWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbVJsYkdGNUlEMGdablZ1WTNScGIyNGdLSFJwYldWdmRYUXBJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTUwYUdWdUtHWjFibU4wYVc5dUlDaDJZV3gxWlNrZ2UxeHVJQ0FnSUNBZ0lDQjJZWElnWkdWbVpYSnlaV1FnUFNCa1pXWmxjaWdwTzF4dUlDQWdJQ0FnSUNCelpYUlVhVzFsYjNWMEtHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHUmxabVZ5Y21Wa0xuSmxjMjlzZG1Vb2RtRnNkV1VwTzF4dUlDQWdJQ0FnSUNCOUxDQjBhVzFsYjNWMEtUdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHUmxabVZ5Y21Wa0xuQnliMjFwYzJVN1hHNGdJQ0FnZlNrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUZCaGMzTmxjeUJoSUdOdmJuUnBiblZoZEdsdmJpQjBieUJoSUU1dlpHVWdablZ1WTNScGIyNHNJSGRvYVdOb0lHbHpJR05oYkd4bFpDQjNhWFJvSUhSb1pTQm5hWFpsYmx4dUlDb2dZWEpuZFcxbGJuUnpJSEJ5YjNacFpHVmtJR0Z6SUdGdUlHRnljbUY1TENCaGJtUWdjbVYwZFhKdWN5QmhJSEJ5YjIxcGMyVXVYRzRnS2x4dUlDb2dJQ0FnSUNCUkxtNW1ZWEJ3Ykhrb1JsTXVjbVZoWkVacGJHVXNJRnRmWDJacGJHVnVZVzFsWFNsY2JpQXFJQ0FnSUNBZ0xuUm9aVzRvWm5WdVkzUnBiMjRnS0dOdmJuUmxiblFwSUh0Y2JpQXFJQ0FnSUNBZ2ZTbGNiaUFxWEc0Z0tpOWNibEV1Ym1aaGNIQnNlU0E5SUdaMWJtTjBhVzl1SUNoallXeHNZbUZqYXl3Z1lYSm5jeWtnZTF4dUlDQWdJSEpsZEhWeWJpQlJLR05oYkd4aVlXTnJLUzV1Wm1Gd2NHeDVLR0Z5WjNNcE8xeHVmVHRjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWJtWmhjSEJzZVNBOUlHWjFibU4wYVc5dUlDaGhjbWR6S1NCN1hHNGdJQ0FnZG1GeUlHUmxabVZ5Y21Wa0lEMGdaR1ZtWlhJb0tUdGNiaUFnSUNCMllYSWdibTlrWlVGeVozTWdQU0JoY25KaGVWOXpiR2xqWlNoaGNtZHpLVHRjYmlBZ0lDQnViMlJsUVhKbmN5NXdkWE5vS0dSbFptVnljbVZrTG0xaGEyVk9iMlJsVW1WemIyeDJaWElvS1NrN1hHNGdJQ0FnZEdocGN5NW1ZWEJ3Ykhrb2JtOWtaVUZ5WjNNcExtWmhhV3dvWkdWbVpYSnlaV1F1Y21WcVpXTjBLVHRjYmlBZ0lDQnlaWFIxY200Z1pHVm1aWEp5WldRdWNISnZiV2x6WlR0Y2JuMDdYRzVjYmk4cUtseHVJQ29nVUdGemMyVnpJR0VnWTI5dWRHbHVkV0YwYVc5dUlIUnZJR0VnVG05a1pTQm1kVzVqZEdsdmJpd2dkMmhwWTJnZ2FYTWdZMkZzYkdWa0lIZHBkR2dnZEdobElHZHBkbVZ1WEc0Z0tpQmhjbWQxYldWdWRITWdjSEp2ZG1sa1pXUWdhVzVrYVhacFpIVmhiR3g1TENCaGJtUWdjbVYwZFhKdWN5QmhJSEJ5YjIxcGMyVXVYRzRnS2lCQVpYaGhiWEJzWlZ4dUlDb2dVUzV1Wm1OaGJHd29SbE11Y21WaFpFWnBiR1VzSUY5ZlptbHNaVzVoYldVcFhHNGdLaUF1ZEdobGJpaG1kVzVqZEdsdmJpQW9ZMjl1ZEdWdWRDa2dlMXh1SUNvZ2ZTbGNiaUFxWEc0Z0tpOWNibEV1Ym1aallXeHNJRDBnWm5WdVkzUnBiMjRnS0dOaGJHeGlZV05ySUM4cUxpNHVZWEpuY3lvdktTQjdYRzRnSUNBZ2RtRnlJR0Z5WjNNZ1BTQmhjbkpoZVY5emJHbGpaU2hoY21kMWJXVnVkSE1zSURFcE8xeHVJQ0FnSUhKbGRIVnliaUJSS0dOaGJHeGlZV05yS1M1dVptRndjR3g1S0dGeVozTXBPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVibVpqWVd4c0lEMGdablZ1WTNScGIyNGdLQzhxTGk0dVlYSm5jeW92S1NCN1hHNGdJQ0FnZG1GeUlHNXZaR1ZCY21keklEMGdZWEp5WVhsZmMyeHBZMlVvWVhKbmRXMWxiblJ6S1R0Y2JpQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUc1dlpHVkJjbWR6TG5CMWMyZ29aR1ZtWlhKeVpXUXViV0ZyWlU1dlpHVlNaWE52YkhabGNpZ3BLVHRjYmlBZ0lDQjBhR2x6TG1aaGNIQnNlU2h1YjJSbFFYSm5jeWt1Wm1GcGJDaGtaV1psY25KbFpDNXlaV3BsWTNRcE8xeHVJQ0FnSUhKbGRIVnliaUJrWldabGNuSmxaQzV3Y205dGFYTmxPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQlhjbUZ3Y3lCaElFNXZaR1ZLVXlCamIyNTBhVzUxWVhScGIyNGdjR0Z6YzJsdVp5Qm1kVzVqZEdsdmJpQmhibVFnY21WMGRYSnVjeUJoYmlCbGNYVnBkbUZzWlc1MFhHNGdLaUIyWlhKemFXOXVJSFJvWVhRZ2NtVjBkWEp1Y3lCaElIQnliMjFwYzJVdVhHNGdLaUJBWlhoaGJYQnNaVnh1SUNvZ1VTNXVabUpwYm1Rb1JsTXVjbVZoWkVacGJHVXNJRjlmWm1sc1pXNWhiV1VwS0Z3aWRYUm1MVGhjSWlsY2JpQXFJQzUwYUdWdUtHTnZibk52YkdVdWJHOW5LVnh1SUNvZ0xtUnZibVVvS1Z4dUlDb3ZYRzVSTG01bVltbHVaQ0E5WEc1UkxtUmxibTlrWldsbWVTQTlJR1oxYm1OMGFXOXVJQ2hqWVd4c1ltRmpheUF2S2k0dUxtRnlaM01xTHlrZ2UxeHVJQ0FnSUhaaGNpQmlZWE5sUVhKbmN5QTlJR0Z5Y21GNVgzTnNhV05sS0dGeVozVnRaVzUwY3l3Z01TazdYRzRnSUNBZ2NtVjBkWEp1SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdkbUZ5SUc1dlpHVkJjbWR6SUQwZ1ltRnpaVUZ5WjNNdVkyOXVZMkYwS0dGeWNtRjVYM05zYVdObEtHRnlaM1Z0Wlc1MGN5a3BPMXh1SUNBZ0lDQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUNBZ0lDQnViMlJsUVhKbmN5NXdkWE5vS0dSbFptVnljbVZrTG0xaGEyVk9iMlJsVW1WemIyeDJaWElvS1NrN1hHNGdJQ0FnSUNBZ0lGRW9ZMkZzYkdKaFkyc3BMbVpoY0hCc2VTaHViMlJsUVhKbmN5a3VabUZwYkNoa1pXWmxjbkpsWkM1eVpXcGxZM1FwTzF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnWkdWbVpYSnlaV1F1Y0hKdmJXbHpaVHRjYmlBZ0lDQjlPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVibVppYVc1a0lEMWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbVJsYm05a1pXbG1lU0E5SUdaMWJtTjBhVzl1SUNndktpNHVMbUZ5WjNNcUx5a2dlMXh1SUNBZ0lIWmhjaUJoY21keklEMGdZWEp5WVhsZmMyeHBZMlVvWVhKbmRXMWxiblJ6S1R0Y2JpQWdJQ0JoY21kekxuVnVjMmhwWm5Rb2RHaHBjeWs3WEc0Z0lDQWdjbVYwZFhKdUlGRXVaR1Z1YjJSbGFXWjVMbUZ3Y0d4NUtIWnZhV1FnTUN3Z1lYSm5jeWs3WEc1OU8xeHVYRzVSTG01aWFXNWtJRDBnWm5WdVkzUnBiMjRnS0dOaGJHeGlZV05yTENCMGFHbHpjQ0F2S2k0dUxtRnlaM01xTHlrZ2UxeHVJQ0FnSUhaaGNpQmlZWE5sUVhKbmN5QTlJR0Z5Y21GNVgzTnNhV05sS0dGeVozVnRaVzUwY3l3Z01pazdYRzRnSUNBZ2NtVjBkWEp1SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdkbUZ5SUc1dlpHVkJjbWR6SUQwZ1ltRnpaVUZ5WjNNdVkyOXVZMkYwS0dGeWNtRjVYM05zYVdObEtHRnlaM1Z0Wlc1MGN5a3BPMXh1SUNBZ0lDQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUNBZ0lDQnViMlJsUVhKbmN5NXdkWE5vS0dSbFptVnljbVZrTG0xaGEyVk9iMlJsVW1WemIyeDJaWElvS1NrN1hHNGdJQ0FnSUNBZ0lHWjFibU4wYVc5dUlHSnZkVzVrS0NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJR05oYkd4aVlXTnJMbUZ3Y0d4NUtIUm9hWE53TENCaGNtZDFiV1Z1ZEhNcE8xeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJRkVvWW05MWJtUXBMbVpoY0hCc2VTaHViMlJsUVhKbmN5a3VabUZwYkNoa1pXWmxjbkpsWkM1eVpXcGxZM1FwTzF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnWkdWbVpYSnlaV1F1Y0hKdmJXbHpaVHRjYmlBZ0lDQjlPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVibUpwYm1RZ1BTQm1kVzVqZEdsdmJpQW9MeXAwYUdsemNDd2dMaTR1WVhKbmN5b3ZLU0I3WEc0Z0lDQWdkbUZ5SUdGeVozTWdQU0JoY25KaGVWOXpiR2xqWlNoaGNtZDFiV1Z1ZEhNc0lEQXBPMXh1SUNBZ0lHRnlaM011ZFc1emFHbG1kQ2gwYUdsektUdGNiaUFnSUNCeVpYUjFjbTRnVVM1dVltbHVaQzVoY0hCc2VTaDJiMmxrSURBc0lHRnlaM01wTzF4dWZUdGNibHh1THlvcVhHNGdLaUJEWVd4c2N5QmhJRzFsZEdodlpDQnZaaUJoSUU1dlpHVXRjM1I1YkdVZ2IySnFaV04wSUhSb1lYUWdZV05qWlhCMGN5QmhJRTV2WkdVdGMzUjViR1ZjYmlBcUlHTmhiR3hpWVdOcklIZHBkR2dnWVNCbmFYWmxiaUJoY25KaGVTQnZaaUJoY21kMWJXVnVkSE1zSUhCc2RYTWdZU0J3Y205MmFXUmxaQ0JqWVd4c1ltRmpheTVjYmlBcUlFQndZWEpoYlNCdlltcGxZM1FnWVc0Z2IySnFaV04wSUhSb1lYUWdhR0Z6SUhSb1pTQnVZVzFsWkNCdFpYUm9iMlJjYmlBcUlFQndZWEpoYlNCN1UzUnlhVzVuZlNCdVlXMWxJRzVoYldVZ2IyWWdkR2hsSUcxbGRHaHZaQ0J2WmlCdlltcGxZM1JjYmlBcUlFQndZWEpoYlNCN1FYSnlZWGw5SUdGeVozTWdZWEpuZFcxbGJuUnpJSFJ2SUhCaGMzTWdkRzhnZEdobElHMWxkR2h2WkRzZ2RHaGxJR05oYkd4aVlXTnJYRzRnS2lCM2FXeHNJR0psSUhCeWIzWnBaR1ZrSUdKNUlGRWdZVzVrSUdGd2NHVnVaR1ZrSUhSdklIUm9aWE5sSUdGeVozVnRaVzUwY3k1Y2JpQXFJRUJ5WlhSMWNtNXpJR0VnY0hKdmJXbHpaU0JtYjNJZ2RHaGxJSFpoYkhWbElHOXlJR1Z5Y205eVhHNGdLaTljYmxFdWJtMWhjSEJzZVNBOUlDOHZJRmhZV0NCQmN5QndjbTl3YjNObFpDQmllU0JjSWxKbFpITmhibVJ5YjF3aVhHNVJMbTV3YjNOMElEMGdablZ1WTNScGIyNGdLRzlpYW1WamRDd2dibUZ0WlN3Z1lYSm5jeWtnZTF4dUlDQWdJSEpsZEhWeWJpQlJLRzlpYW1WamRDa3VibkJ2YzNRb2JtRnRaU3dnWVhKbmN5azdYRzU5TzF4dVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNXViV0Z3Y0d4NUlEMGdMeThnV0ZoWUlFRnpJSEJ5YjNCdmMyVmtJR0o1SUZ3aVVtVmtjMkZ1WkhKdlhDSmNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbTV3YjNOMElEMGdablZ1WTNScGIyNGdLRzVoYldVc0lHRnlaM01wSUh0Y2JpQWdJQ0IyWVhJZ2JtOWtaVUZ5WjNNZ1BTQmhjbkpoZVY5emJHbGpaU2hoY21keklIeDhJRnRkS1R0Y2JpQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUc1dlpHVkJjbWR6TG5CMWMyZ29aR1ZtWlhKeVpXUXViV0ZyWlU1dlpHVlNaWE52YkhabGNpZ3BLVHRjYmlBZ0lDQjBhR2x6TG1ScGMzQmhkR05vS0Z3aWNHOXpkRndpTENCYmJtRnRaU3dnYm05a1pVRnlaM05kS1M1bVlXbHNLR1JsWm1WeWNtVmtMbkpsYW1WamRDazdYRzRnSUNBZ2NtVjBkWEp1SUdSbFptVnljbVZrTG5CeWIyMXBjMlU3WEc1OU8xeHVYRzR2S2lwY2JpQXFJRU5oYkd4eklHRWdiV1YwYUc5a0lHOW1JR0VnVG05a1pTMXpkSGxzWlNCdlltcGxZM1FnZEdoaGRDQmhZMk5sY0hSeklHRWdUbTlrWlMxemRIbHNaVnh1SUNvZ1kyRnNiR0poWTJzc0lHWnZjbmRoY21ScGJtY2dkR2hsSUdkcGRtVnVJSFpoY21saFpHbGpJR0Z5WjNWdFpXNTBjeXdnY0d4MWN5QmhJSEJ5YjNacFpHVmtYRzRnS2lCallXeHNZbUZqYXlCaGNtZDFiV1Z1ZEM1Y2JpQXFJRUJ3WVhKaGJTQnZZbXBsWTNRZ1lXNGdiMkpxWldOMElIUm9ZWFFnYUdGeklIUm9aU0J1WVcxbFpDQnRaWFJvYjJSY2JpQXFJRUJ3WVhKaGJTQjdVM1J5YVc1bmZTQnVZVzFsSUc1aGJXVWdiMllnZEdobElHMWxkR2h2WkNCdlppQnZZbXBsWTNSY2JpQXFJRUJ3WVhKaGJTQXVMaTVoY21keklHRnlaM1Z0Wlc1MGN5QjBieUJ3WVhOeklIUnZJSFJvWlNCdFpYUm9iMlE3SUhSb1pTQmpZV3hzWW1GamF5QjNhV3hzWEc0Z0tpQmlaU0J3Y205MmFXUmxaQ0JpZVNCUklHRnVaQ0JoY0hCbGJtUmxaQ0IwYnlCMGFHVnpaU0JoY21kMWJXVnVkSE11WEc0Z0tpQkFjbVYwZFhKdWN5QmhJSEJ5YjIxcGMyVWdabTl5SUhSb1pTQjJZV3gxWlNCdmNpQmxjbkp2Y2x4dUlDb3ZYRzVSTG01elpXNWtJRDBnTHk4Z1dGaFlJRUpoYzJWa0lHOXVJRTFoY21zZ1RXbHNiR1Z5SjNNZ2NISnZjRzl6WldRZ1hDSnpaVzVrWENKY2JsRXVibTFqWVd4c0lEMGdMeThnV0ZoWUlFSmhjMlZrSUc5dUlGd2lVbVZrYzJGdVpISnZKM05jSWlCd2NtOXdiM05oYkZ4dVVTNXVhVzUyYjJ0bElEMGdablZ1WTNScGIyNGdLRzlpYW1WamRDd2dibUZ0WlNBdktpNHVMbUZ5WjNNcUx5a2dlMXh1SUNBZ0lIWmhjaUJ1YjJSbFFYSm5jeUE5SUdGeWNtRjVYM05zYVdObEtHRnlaM1Z0Wlc1MGN5d2dNaWs3WEc0Z0lDQWdkbUZ5SUdSbFptVnljbVZrSUQwZ1pHVm1aWElvS1R0Y2JpQWdJQ0J1YjJSbFFYSm5jeTV3ZFhOb0tHUmxabVZ5Y21Wa0xtMWhhMlZPYjJSbFVtVnpiMngyWlhJb0tTazdYRzRnSUNBZ1VTaHZZbXBsWTNRcExtUnBjM0JoZEdOb0tGd2ljRzl6ZEZ3aUxDQmJibUZ0WlN3Z2JtOWtaVUZ5WjNOZEtTNW1ZV2xzS0dSbFptVnljbVZrTG5KbGFtVmpkQ2s3WEc0Z0lDQWdjbVYwZFhKdUlHUmxabVZ5Y21Wa0xuQnliMjFwYzJVN1hHNTlPMXh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1dWMyVnVaQ0E5SUM4dklGaFlXQ0JDWVhObFpDQnZiaUJOWVhKcklFMXBiR3hsY2lkeklIQnliM0J2YzJWa0lGd2ljMlZ1WkZ3aVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNXViV05oYkd3Z1BTQXZMeUJZV0ZnZ1FtRnpaV1FnYjI0Z1hDSlNaV1J6WVc1a2NtOG5jMXdpSUhCeWIzQnZjMkZzWEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1dWFXNTJiMnRsSUQwZ1puVnVZM1JwYjI0Z0tHNWhiV1VnTHlvdUxpNWhjbWR6S2k4cElIdGNiaUFnSUNCMllYSWdibTlrWlVGeVozTWdQU0JoY25KaGVWOXpiR2xqWlNoaGNtZDFiV1Z1ZEhNc0lERXBPMXh1SUNBZ0lIWmhjaUJrWldabGNuSmxaQ0E5SUdSbFptVnlLQ2s3WEc0Z0lDQWdibTlrWlVGeVozTXVjSFZ6YUNoa1pXWmxjbkpsWkM1dFlXdGxUbTlrWlZKbGMyOXNkbVZ5S0NrcE8xeHVJQ0FnSUhSb2FYTXVaR2x6Y0dGMFkyZ29YQ0p3YjNOMFhDSXNJRnR1WVcxbExDQnViMlJsUVhKbmMxMHBMbVpoYVd3b1pHVm1aWEp5WldRdWNtVnFaV04wS1R0Y2JpQWdJQ0J5WlhSMWNtNGdaR1ZtWlhKeVpXUXVjSEp2YldselpUdGNibjA3WEc1Y2JpOHFLbHh1SUNvZ1NXWWdZU0JtZFc1amRHbHZiaUIzYjNWc1pDQnNhV3RsSUhSdklITjFjSEJ2Y25RZ1ltOTBhQ0JPYjJSbElHTnZiblJwYm5WaGRHbHZiaTF3WVhOemFXNW5MWE4wZVd4bElHRnVaRnh1SUNvZ2NISnZiV2x6WlMxeVpYUjFjbTVwYm1jdGMzUjViR1VzSUdsMElHTmhiaUJsYm1RZ2FYUnpJR2x1ZEdWeWJtRnNJSEJ5YjIxcGMyVWdZMmhoYVc0Z2QybDBhRnh1SUNvZ1lHNXZaR1ZwWm5rb2JtOWtaV0poWTJzcFlDd2dabTl5ZDJGeVpHbHVaeUIwYUdVZ2IzQjBhVzl1WVd3Z2JtOWtaV0poWTJzZ1lYSm5kVzFsYm5RdUlDQkpaaUIwYUdVZ2RYTmxjbHh1SUNvZ1pXeGxZM1J6SUhSdklIVnpaU0JoSUc1dlpHVmlZV05yTENCMGFHVWdjbVZ6ZFd4MElIZHBiR3dnWW1VZ2MyVnVkQ0IwYUdWeVpTNGdJRWxtSUhSb1pYa2daRzhnYm05MFhHNGdLaUJ3WVhOeklHRWdibTlrWldKaFkyc3NJSFJvWlhrZ2QybHNiQ0J5WldObGFYWmxJSFJvWlNCeVpYTjFiSFFnY0hKdmJXbHpaUzVjYmlBcUlFQndZWEpoYlNCdlltcGxZM1FnWVNCeVpYTjFiSFFnS0c5eUlHRWdjSEp2YldselpTQm1iM0lnWVNCeVpYTjFiSFFwWEc0Z0tpQkFjR0Z5WVcwZ2UwWjFibU4wYVc5dWZTQnViMlJsWW1GamF5QmhJRTV2WkdVdWFuTXRjM1I1YkdVZ1kyRnNiR0poWTJ0Y2JpQXFJRUJ5WlhSMWNtNXpJR1ZwZEdobGNpQjBhR1VnY0hKdmJXbHpaU0J2Y2lCdWIzUm9hVzVuWEc0Z0tpOWNibEV1Ym05a1pXbG1lU0E5SUc1dlpHVnBabms3WEc1bWRXNWpkR2x2YmlCdWIyUmxhV1o1S0c5aWFtVmpkQ3dnYm05a1pXSmhZMnNwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdVU2h2WW1wbFkzUXBMbTV2WkdWcFpua29ibTlrWldKaFkyc3BPMXh1ZlZ4dVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNXViMlJsYVdaNUlEMGdablZ1WTNScGIyNGdLRzV2WkdWaVlXTnJLU0I3WEc0Z0lDQWdhV1lnS0c1dlpHVmlZV05yS1NCN1hHNGdJQ0FnSUNBZ0lIUm9hWE11ZEdobGJpaG1kVzVqZEdsdmJpQW9kbUZzZFdVcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUZFdWJtVjRkRlJwWTJzb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJRzV2WkdWaVlXTnJLRzUxYkd3c0lIWmhiSFZsS1R0Y2JpQWdJQ0FnSUNBZ0lDQWdJSDBwTzF4dUlDQWdJQ0FnSUNCOUxDQm1kVzVqZEdsdmJpQW9aWEp5YjNJcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUZFdWJtVjRkRlJwWTJzb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJRzV2WkdWaVlXTnJLR1Z5Y205eUtUdGNiaUFnSUNBZ0lDQWdJQ0FnSUgwcE8xeHVJQ0FnSUNBZ0lDQjlLVHRjYmlBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQnlaWFIxY200Z2RHaHBjenRjYmlBZ0lDQjlYRzU5TzF4dVhHNVJMbTV2UTI5dVpteHBZM1FnUFNCbWRXNWpkR2x2YmlncElIdGNiaUFnSUNCMGFISnZkeUJ1WlhjZ1JYSnliM0lvWENKUkxtNXZRMjl1Wm14cFkzUWdiMjVzZVNCM2IzSnJjeUIzYUdWdUlGRWdhWE1nZFhObFpDQmhjeUJoSUdkc2IySmhiRndpS1R0Y2JuMDdYRzVjYmk4dklFRnNiQ0JqYjJSbElHSmxabTl5WlNCMGFHbHpJSEJ2YVc1MElIZHBiR3dnWW1VZ1ptbHNkR1Z5WldRZ1puSnZiU0J6ZEdGamF5QjBjbUZqWlhNdVhHNTJZWElnY1VWdVpHbHVaMHhwYm1VZ1BTQmpZWEIwZFhKbFRHbHVaU2dwTzF4dVhHNXlaWFIxY200Z1VUdGNibHh1ZlNrN1hHNGlYWDA9IiwiXG4vKipcbiAqIFJlZHVjZSBgYXJyYCB3aXRoIGBmbmAuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gYXJyXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHBhcmFtIHtNaXhlZH0gaW5pdGlhbFxuICpcbiAqIFRPRE86IGNvbWJhdGlibGUgZXJyb3IgaGFuZGxpbmc/XG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihhcnIsIGZuLCBpbml0aWFsKXsgIFxuICB2YXIgaWR4ID0gMDtcbiAgdmFyIGxlbiA9IGFyci5sZW5ndGg7XG4gIHZhciBjdXJyID0gYXJndW1lbnRzLmxlbmd0aCA9PSAzXG4gICAgPyBpbml0aWFsXG4gICAgOiBhcnJbaWR4KytdO1xuXG4gIHdoaWxlIChpZHggPCBsZW4pIHtcbiAgICBjdXJyID0gZm4uY2FsbChudWxsLCBjdXJyLCBhcnJbaWR4XSwgKytpZHgsIGFycik7XG4gIH1cbiAgXG4gIHJldHVybiBjdXJyO1xufTsiLCIvKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxudmFyIEVtaXR0ZXIgPSByZXF1aXJlKCdlbWl0dGVyJyk7XG52YXIgcmVkdWNlID0gcmVxdWlyZSgncmVkdWNlJyk7XG5cbi8qKlxuICogUm9vdCByZWZlcmVuY2UgZm9yIGlmcmFtZXMuXG4gKi9cblxudmFyIHJvb3Q7XG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHsgLy8gQnJvd3NlciB3aW5kb3dcbiAgcm9vdCA9IHdpbmRvdztcbn0gZWxzZSBpZiAodHlwZW9mIHNlbGYgIT09ICd1bmRlZmluZWQnKSB7IC8vIFdlYiBXb3JrZXJcbiAgcm9vdCA9IHNlbGY7XG59IGVsc2UgeyAvLyBPdGhlciBlbnZpcm9ubWVudHNcbiAgcm9vdCA9IHRoaXM7XG59XG5cbi8qKlxuICogTm9vcC5cbiAqL1xuXG5mdW5jdGlvbiBub29wKCl7fTtcblxuLyoqXG4gKiBDaGVjayBpZiBgb2JqYCBpcyBhIGhvc3Qgb2JqZWN0LFxuICogd2UgZG9uJ3Qgd2FudCB0byBzZXJpYWxpemUgdGhlc2UgOilcbiAqXG4gKiBUT0RPOiBmdXR1cmUgcHJvb2YsIG1vdmUgdG8gY29tcG9lbnQgbGFuZFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBpc0hvc3Qob2JqKSB7XG4gIHZhciBzdHIgPSB7fS50b1N0cmluZy5jYWxsKG9iaik7XG5cbiAgc3dpdGNoIChzdHIpIHtcbiAgICBjYXNlICdbb2JqZWN0IEZpbGVdJzpcbiAgICBjYXNlICdbb2JqZWN0IEJsb2JdJzpcbiAgICBjYXNlICdbb2JqZWN0IEZvcm1EYXRhXSc6XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIFhIUi5cbiAqL1xuXG5yZXF1ZXN0LmdldFhIUiA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHJvb3QuWE1MSHR0cFJlcXVlc3RcbiAgICAgICYmICghcm9vdC5sb2NhdGlvbiB8fCAnZmlsZTonICE9IHJvb3QubG9jYXRpb24ucHJvdG9jb2xcbiAgICAgICAgICB8fCAhcm9vdC5BY3RpdmVYT2JqZWN0KSkge1xuICAgIHJldHVybiBuZXcgWE1MSHR0cFJlcXVlc3Q7XG4gIH0gZWxzZSB7XG4gICAgdHJ5IHsgcmV0dXJuIG5ldyBBY3RpdmVYT2JqZWN0KCdNaWNyb3NvZnQuWE1MSFRUUCcpOyB9IGNhdGNoKGUpIHt9XG4gICAgdHJ5IHsgcmV0dXJuIG5ldyBBY3RpdmVYT2JqZWN0KCdNc3htbDIuWE1MSFRUUC42LjAnKTsgfSBjYXRjaChlKSB7fVxuICAgIHRyeSB7IHJldHVybiBuZXcgQWN0aXZlWE9iamVjdCgnTXN4bWwyLlhNTEhUVFAuMy4wJyk7IH0gY2F0Y2goZSkge31cbiAgICB0cnkgeyByZXR1cm4gbmV3IEFjdGl2ZVhPYmplY3QoJ01zeG1sMi5YTUxIVFRQJyk7IH0gY2F0Y2goZSkge31cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59O1xuXG4vKipcbiAqIFJlbW92ZXMgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZSwgYWRkZWQgdG8gc3VwcG9ydCBJRS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc1xuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxudmFyIHRyaW0gPSAnJy50cmltXG4gID8gZnVuY3Rpb24ocykgeyByZXR1cm4gcy50cmltKCk7IH1cbiAgOiBmdW5jdGlvbihzKSB7IHJldHVybiBzLnJlcGxhY2UoLyheXFxzKnxcXHMqJCkvZywgJycpOyB9O1xuXG4vKipcbiAqIENoZWNrIGlmIGBvYmpgIGlzIGFuIG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gaXNPYmplY3Qob2JqKSB7XG4gIHJldHVybiBvYmogPT09IE9iamVjdChvYmopO1xufVxuXG4vKipcbiAqIFNlcmlhbGl6ZSB0aGUgZ2l2ZW4gYG9iamAuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gc2VyaWFsaXplKG9iaikge1xuICBpZiAoIWlzT2JqZWN0KG9iaikpIHJldHVybiBvYmo7XG4gIHZhciBwYWlycyA9IFtdO1xuICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgaWYgKG51bGwgIT0gb2JqW2tleV0pIHtcbiAgICAgIHB1c2hFbmNvZGVkS2V5VmFsdWVQYWlyKHBhaXJzLCBrZXksIG9ialtrZXldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICByZXR1cm4gcGFpcnMuam9pbignJicpO1xufVxuXG4vKipcbiAqIEhlbHBzICdzZXJpYWxpemUnIHdpdGggc2VyaWFsaXppbmcgYXJyYXlzLlxuICogTXV0YXRlcyB0aGUgcGFpcnMgYXJyYXkuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gcGFpcnNcbiAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcbiAqIEBwYXJhbSB7TWl4ZWR9IHZhbFxuICovXG5cbmZ1bmN0aW9uIHB1c2hFbmNvZGVkS2V5VmFsdWVQYWlyKHBhaXJzLCBrZXksIHZhbCkge1xuICBpZiAoQXJyYXkuaXNBcnJheSh2YWwpKSB7XG4gICAgcmV0dXJuIHZhbC5mb3JFYWNoKGZ1bmN0aW9uKHYpIHtcbiAgICAgIHB1c2hFbmNvZGVkS2V5VmFsdWVQYWlyKHBhaXJzLCBrZXksIHYpO1xuICAgIH0pO1xuICB9XG4gIHBhaXJzLnB1c2goZW5jb2RlVVJJQ29tcG9uZW50KGtleSlcbiAgICArICc9JyArIGVuY29kZVVSSUNvbXBvbmVudCh2YWwpKTtcbn1cblxuLyoqXG4gKiBFeHBvc2Ugc2VyaWFsaXphdGlvbiBtZXRob2QuXG4gKi9cblxuIHJlcXVlc3Quc2VyaWFsaXplT2JqZWN0ID0gc2VyaWFsaXplO1xuXG4gLyoqXG4gICogUGFyc2UgdGhlIGdpdmVuIHgtd3d3LWZvcm0tdXJsZW5jb2RlZCBgc3RyYC5cbiAgKlxuICAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAgKiBAcmV0dXJuIHtPYmplY3R9XG4gICogQGFwaSBwcml2YXRlXG4gICovXG5cbmZ1bmN0aW9uIHBhcnNlU3RyaW5nKHN0cikge1xuICB2YXIgb2JqID0ge307XG4gIHZhciBwYWlycyA9IHN0ci5zcGxpdCgnJicpO1xuICB2YXIgcGFydHM7XG4gIHZhciBwYWlyO1xuXG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBwYWlycy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgIHBhaXIgPSBwYWlyc1tpXTtcbiAgICBwYXJ0cyA9IHBhaXIuc3BsaXQoJz0nKTtcbiAgICBvYmpbZGVjb2RlVVJJQ29tcG9uZW50KHBhcnRzWzBdKV0gPSBkZWNvZGVVUklDb21wb25lbnQocGFydHNbMV0pO1xuICB9XG5cbiAgcmV0dXJuIG9iajtcbn1cblxuLyoqXG4gKiBFeHBvc2UgcGFyc2VyLlxuICovXG5cbnJlcXVlc3QucGFyc2VTdHJpbmcgPSBwYXJzZVN0cmluZztcblxuLyoqXG4gKiBEZWZhdWx0IE1JTUUgdHlwZSBtYXAuXG4gKlxuICogICAgIHN1cGVyYWdlbnQudHlwZXMueG1sID0gJ2FwcGxpY2F0aW9uL3htbCc7XG4gKlxuICovXG5cbnJlcXVlc3QudHlwZXMgPSB7XG4gIGh0bWw6ICd0ZXh0L2h0bWwnLFxuICBqc29uOiAnYXBwbGljYXRpb24vanNvbicsXG4gIHhtbDogJ2FwcGxpY2F0aW9uL3htbCcsXG4gIHVybGVuY29kZWQ6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnLFxuICAnZm9ybSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnLFxuICAnZm9ybS1kYXRhJzogJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCdcbn07XG5cbi8qKlxuICogRGVmYXVsdCBzZXJpYWxpemF0aW9uIG1hcC5cbiAqXG4gKiAgICAgc3VwZXJhZ2VudC5zZXJpYWxpemVbJ2FwcGxpY2F0aW9uL3htbCddID0gZnVuY3Rpb24ob2JqKXtcbiAqICAgICAgIHJldHVybiAnZ2VuZXJhdGVkIHhtbCBoZXJlJztcbiAqICAgICB9O1xuICpcbiAqL1xuXG4gcmVxdWVzdC5zZXJpYWxpemUgPSB7XG4gICAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJzogc2VyaWFsaXplLFxuICAgJ2FwcGxpY2F0aW9uL2pzb24nOiBKU09OLnN0cmluZ2lmeVxuIH07XG5cbiAvKipcbiAgKiBEZWZhdWx0IHBhcnNlcnMuXG4gICpcbiAgKiAgICAgc3VwZXJhZ2VudC5wYXJzZVsnYXBwbGljYXRpb24veG1sJ10gPSBmdW5jdGlvbihzdHIpe1xuICAqICAgICAgIHJldHVybiB7IG9iamVjdCBwYXJzZWQgZnJvbSBzdHIgfTtcbiAgKiAgICAgfTtcbiAgKlxuICAqL1xuXG5yZXF1ZXN0LnBhcnNlID0ge1xuICAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJzogcGFyc2VTdHJpbmcsXG4gICdhcHBsaWNhdGlvbi9qc29uJzogSlNPTi5wYXJzZVxufTtcblxuLyoqXG4gKiBQYXJzZSB0aGUgZ2l2ZW4gaGVhZGVyIGBzdHJgIGludG9cbiAqIGFuIG9iamVjdCBjb250YWluaW5nIHRoZSBtYXBwZWQgZmllbGRzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHBhcnNlSGVhZGVyKHN0cikge1xuICB2YXIgbGluZXMgPSBzdHIuc3BsaXQoL1xccj9cXG4vKTtcbiAgdmFyIGZpZWxkcyA9IHt9O1xuICB2YXIgaW5kZXg7XG4gIHZhciBsaW5lO1xuICB2YXIgZmllbGQ7XG4gIHZhciB2YWw7XG5cbiAgbGluZXMucG9wKCk7IC8vIHRyYWlsaW5nIENSTEZcblxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gbGluZXMubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICBsaW5lID0gbGluZXNbaV07XG4gICAgaW5kZXggPSBsaW5lLmluZGV4T2YoJzonKTtcbiAgICBmaWVsZCA9IGxpbmUuc2xpY2UoMCwgaW5kZXgpLnRvTG93ZXJDYXNlKCk7XG4gICAgdmFsID0gdHJpbShsaW5lLnNsaWNlKGluZGV4ICsgMSkpO1xuICAgIGZpZWxkc1tmaWVsZF0gPSB2YWw7XG4gIH1cblxuICByZXR1cm4gZmllbGRzO1xufVxuXG4vKipcbiAqIENoZWNrIGlmIGBtaW1lYCBpcyBqc29uIG9yIGhhcyAranNvbiBzdHJ1Y3R1cmVkIHN5bnRheCBzdWZmaXguXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1pbWVcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBpc0pTT04obWltZSkge1xuICByZXR1cm4gL1tcXC8rXWpzb25cXGIvLnRlc3QobWltZSk7XG59XG5cbi8qKlxuICogUmV0dXJuIHRoZSBtaW1lIHR5cGUgZm9yIHRoZSBnaXZlbiBgc3RyYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiB0eXBlKHN0cil7XG4gIHJldHVybiBzdHIuc3BsaXQoLyAqOyAqLykuc2hpZnQoKTtcbn07XG5cbi8qKlxuICogUmV0dXJuIGhlYWRlciBmaWVsZCBwYXJhbWV0ZXJzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHBhcmFtcyhzdHIpe1xuICByZXR1cm4gcmVkdWNlKHN0ci5zcGxpdCgvICo7ICovKSwgZnVuY3Rpb24ob2JqLCBzdHIpe1xuICAgIHZhciBwYXJ0cyA9IHN0ci5zcGxpdCgvICo9ICovKVxuICAgICAgLCBrZXkgPSBwYXJ0cy5zaGlmdCgpXG4gICAgICAsIHZhbCA9IHBhcnRzLnNoaWZ0KCk7XG5cbiAgICBpZiAoa2V5ICYmIHZhbCkgb2JqW2tleV0gPSB2YWw7XG4gICAgcmV0dXJuIG9iajtcbiAgfSwge30pO1xufTtcblxuLyoqXG4gKiBJbml0aWFsaXplIGEgbmV3IGBSZXNwb25zZWAgd2l0aCB0aGUgZ2l2ZW4gYHhocmAuXG4gKlxuICogIC0gc2V0IGZsYWdzICgub2ssIC5lcnJvciwgZXRjKVxuICogIC0gcGFyc2UgaGVhZGVyXG4gKlxuICogRXhhbXBsZXM6XG4gKlxuICogIEFsaWFzaW5nIGBzdXBlcmFnZW50YCBhcyBgcmVxdWVzdGAgaXMgbmljZTpcbiAqXG4gKiAgICAgIHJlcXVlc3QgPSBzdXBlcmFnZW50O1xuICpcbiAqICBXZSBjYW4gdXNlIHRoZSBwcm9taXNlLWxpa2UgQVBJLCBvciBwYXNzIGNhbGxiYWNrczpcbiAqXG4gKiAgICAgIHJlcXVlc3QuZ2V0KCcvJykuZW5kKGZ1bmN0aW9uKHJlcyl7fSk7XG4gKiAgICAgIHJlcXVlc3QuZ2V0KCcvJywgZnVuY3Rpb24ocmVzKXt9KTtcbiAqXG4gKiAgU2VuZGluZyBkYXRhIGNhbiBiZSBjaGFpbmVkOlxuICpcbiAqICAgICAgcmVxdWVzdFxuICogICAgICAgIC5wb3N0KCcvdXNlcicpXG4gKiAgICAgICAgLnNlbmQoeyBuYW1lOiAndGonIH0pXG4gKiAgICAgICAgLmVuZChmdW5jdGlvbihyZXMpe30pO1xuICpcbiAqICBPciBwYXNzZWQgdG8gYC5zZW5kKClgOlxuICpcbiAqICAgICAgcmVxdWVzdFxuICogICAgICAgIC5wb3N0KCcvdXNlcicpXG4gKiAgICAgICAgLnNlbmQoeyBuYW1lOiAndGonIH0sIGZ1bmN0aW9uKHJlcyl7fSk7XG4gKlxuICogIE9yIHBhc3NlZCB0byBgLnBvc3QoKWA6XG4gKlxuICogICAgICByZXF1ZXN0XG4gKiAgICAgICAgLnBvc3QoJy91c2VyJywgeyBuYW1lOiAndGonIH0pXG4gKiAgICAgICAgLmVuZChmdW5jdGlvbihyZXMpe30pO1xuICpcbiAqIE9yIGZ1cnRoZXIgcmVkdWNlZCB0byBhIHNpbmdsZSBjYWxsIGZvciBzaW1wbGUgY2FzZXM6XG4gKlxuICogICAgICByZXF1ZXN0XG4gKiAgICAgICAgLnBvc3QoJy91c2VyJywgeyBuYW1lOiAndGonIH0sIGZ1bmN0aW9uKHJlcyl7fSk7XG4gKlxuICogQHBhcmFtIHtYTUxIVFRQUmVxdWVzdH0geGhyXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gUmVzcG9uc2UocmVxLCBvcHRpb25zKSB7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICB0aGlzLnJlcSA9IHJlcTtcbiAgdGhpcy54aHIgPSB0aGlzLnJlcS54aHI7XG4gIC8vIHJlc3BvbnNlVGV4dCBpcyBhY2Nlc3NpYmxlIG9ubHkgaWYgcmVzcG9uc2VUeXBlIGlzICcnIG9yICd0ZXh0JyBhbmQgb24gb2xkZXIgYnJvd3NlcnNcbiAgdGhpcy50ZXh0ID0gKCh0aGlzLnJlcS5tZXRob2QgIT0nSEVBRCcgJiYgKHRoaXMueGhyLnJlc3BvbnNlVHlwZSA9PT0gJycgfHwgdGhpcy54aHIucmVzcG9uc2VUeXBlID09PSAndGV4dCcpKSB8fCB0eXBlb2YgdGhpcy54aHIucmVzcG9uc2VUeXBlID09PSAndW5kZWZpbmVkJylcbiAgICAgPyB0aGlzLnhoci5yZXNwb25zZVRleHRcbiAgICAgOiBudWxsO1xuICB0aGlzLnN0YXR1c1RleHQgPSB0aGlzLnJlcS54aHIuc3RhdHVzVGV4dDtcbiAgdGhpcy5zZXRTdGF0dXNQcm9wZXJ0aWVzKHRoaXMueGhyLnN0YXR1cyk7XG4gIHRoaXMuaGVhZGVyID0gdGhpcy5oZWFkZXJzID0gcGFyc2VIZWFkZXIodGhpcy54aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCkpO1xuICAvLyBnZXRBbGxSZXNwb25zZUhlYWRlcnMgc29tZXRpbWVzIGZhbHNlbHkgcmV0dXJucyBcIlwiIGZvciBDT1JTIHJlcXVlc3RzLCBidXRcbiAgLy8gZ2V0UmVzcG9uc2VIZWFkZXIgc3RpbGwgd29ya3MuIHNvIHdlIGdldCBjb250ZW50LXR5cGUgZXZlbiBpZiBnZXR0aW5nXG4gIC8vIG90aGVyIGhlYWRlcnMgZmFpbHMuXG4gIHRoaXMuaGVhZGVyWydjb250ZW50LXR5cGUnXSA9IHRoaXMueGhyLmdldFJlc3BvbnNlSGVhZGVyKCdjb250ZW50LXR5cGUnKTtcbiAgdGhpcy5zZXRIZWFkZXJQcm9wZXJ0aWVzKHRoaXMuaGVhZGVyKTtcbiAgdGhpcy5ib2R5ID0gdGhpcy5yZXEubWV0aG9kICE9ICdIRUFEJ1xuICAgID8gdGhpcy5wYXJzZUJvZHkodGhpcy50ZXh0ID8gdGhpcy50ZXh0IDogdGhpcy54aHIucmVzcG9uc2UpXG4gICAgOiBudWxsO1xufVxuXG4vKipcbiAqIEdldCBjYXNlLWluc2Vuc2l0aXZlIGBmaWVsZGAgdmFsdWUuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGZpZWxkXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlc3BvbnNlLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbihmaWVsZCl7XG4gIHJldHVybiB0aGlzLmhlYWRlcltmaWVsZC50b0xvd2VyQ2FzZSgpXTtcbn07XG5cbi8qKlxuICogU2V0IGhlYWRlciByZWxhdGVkIHByb3BlcnRpZXM6XG4gKlxuICogICAtIGAudHlwZWAgdGhlIGNvbnRlbnQgdHlwZSB3aXRob3V0IHBhcmFtc1xuICpcbiAqIEEgcmVzcG9uc2Ugb2YgXCJDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLThcIlxuICogd2lsbCBwcm92aWRlIHlvdSB3aXRoIGEgYC50eXBlYCBvZiBcInRleHQvcGxhaW5cIi5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gaGVhZGVyXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXNwb25zZS5wcm90b3R5cGUuc2V0SGVhZGVyUHJvcGVydGllcyA9IGZ1bmN0aW9uKGhlYWRlcil7XG4gIC8vIGNvbnRlbnQtdHlwZVxuICB2YXIgY3QgPSB0aGlzLmhlYWRlclsnY29udGVudC10eXBlJ10gfHwgJyc7XG4gIHRoaXMudHlwZSA9IHR5cGUoY3QpO1xuXG4gIC8vIHBhcmFtc1xuICB2YXIgb2JqID0gcGFyYW1zKGN0KTtcbiAgZm9yICh2YXIga2V5IGluIG9iaikgdGhpc1trZXldID0gb2JqW2tleV07XG59O1xuXG4vKipcbiAqIFBhcnNlIHRoZSBnaXZlbiBib2R5IGBzdHJgLlxuICpcbiAqIFVzZWQgZm9yIGF1dG8tcGFyc2luZyBvZiBib2RpZXMuIFBhcnNlcnNcbiAqIGFyZSBkZWZpbmVkIG9uIHRoZSBgc3VwZXJhZ2VudC5wYXJzZWAgb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge01peGVkfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVzcG9uc2UucHJvdG90eXBlLnBhcnNlQm9keSA9IGZ1bmN0aW9uKHN0cil7XG4gIHZhciBwYXJzZSA9IHJlcXVlc3QucGFyc2VbdGhpcy50eXBlXTtcbiAgcmV0dXJuIHBhcnNlICYmIHN0ciAmJiAoc3RyLmxlbmd0aCB8fCBzdHIgaW5zdGFuY2VvZiBPYmplY3QpXG4gICAgPyBwYXJzZShzdHIpXG4gICAgOiBudWxsO1xufTtcblxuLyoqXG4gKiBTZXQgZmxhZ3Mgc3VjaCBhcyBgLm9rYCBiYXNlZCBvbiBgc3RhdHVzYC5cbiAqXG4gKiBGb3IgZXhhbXBsZSBhIDJ4eCByZXNwb25zZSB3aWxsIGdpdmUgeW91IGEgYC5va2Agb2YgX190cnVlX19cbiAqIHdoZXJlYXMgNXh4IHdpbGwgYmUgX19mYWxzZV9fIGFuZCBgLmVycm9yYCB3aWxsIGJlIF9fdHJ1ZV9fLiBUaGVcbiAqIGAuY2xpZW50RXJyb3JgIGFuZCBgLnNlcnZlckVycm9yYCBhcmUgYWxzbyBhdmFpbGFibGUgdG8gYmUgbW9yZVxuICogc3BlY2lmaWMsIGFuZCBgLnN0YXR1c1R5cGVgIGlzIHRoZSBjbGFzcyBvZiBlcnJvciByYW5naW5nIGZyb20gMS4uNVxuICogc29tZXRpbWVzIHVzZWZ1bCBmb3IgbWFwcGluZyByZXNwb25kIGNvbG9ycyBldGMuXG4gKlxuICogXCJzdWdhclwiIHByb3BlcnRpZXMgYXJlIGFsc28gZGVmaW5lZCBmb3IgY29tbW9uIGNhc2VzLiBDdXJyZW50bHkgcHJvdmlkaW5nOlxuICpcbiAqICAgLSAubm9Db250ZW50XG4gKiAgIC0gLmJhZFJlcXVlc3RcbiAqICAgLSAudW5hdXRob3JpemVkXG4gKiAgIC0gLm5vdEFjY2VwdGFibGVcbiAqICAgLSAubm90Rm91bmRcbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gc3RhdHVzXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXNwb25zZS5wcm90b3R5cGUuc2V0U3RhdHVzUHJvcGVydGllcyA9IGZ1bmN0aW9uKHN0YXR1cyl7XG4gIC8vIGhhbmRsZSBJRTkgYnVnOiBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzEwMDQ2OTcyL21zaWUtcmV0dXJucy1zdGF0dXMtY29kZS1vZi0xMjIzLWZvci1hamF4LXJlcXVlc3RcbiAgaWYgKHN0YXR1cyA9PT0gMTIyMykge1xuICAgIHN0YXR1cyA9IDIwNDtcbiAgfVxuXG4gIHZhciB0eXBlID0gc3RhdHVzIC8gMTAwIHwgMDtcblxuICAvLyBzdGF0dXMgLyBjbGFzc1xuICB0aGlzLnN0YXR1cyA9IHRoaXMuc3RhdHVzQ29kZSA9IHN0YXR1cztcbiAgdGhpcy5zdGF0dXNUeXBlID0gdHlwZTtcblxuICAvLyBiYXNpY3NcbiAgdGhpcy5pbmZvID0gMSA9PSB0eXBlO1xuICB0aGlzLm9rID0gMiA9PSB0eXBlO1xuICB0aGlzLmNsaWVudEVycm9yID0gNCA9PSB0eXBlO1xuICB0aGlzLnNlcnZlckVycm9yID0gNSA9PSB0eXBlO1xuICB0aGlzLmVycm9yID0gKDQgPT0gdHlwZSB8fCA1ID09IHR5cGUpXG4gICAgPyB0aGlzLnRvRXJyb3IoKVxuICAgIDogZmFsc2U7XG5cbiAgLy8gc3VnYXJcbiAgdGhpcy5hY2NlcHRlZCA9IDIwMiA9PSBzdGF0dXM7XG4gIHRoaXMubm9Db250ZW50ID0gMjA0ID09IHN0YXR1cztcbiAgdGhpcy5iYWRSZXF1ZXN0ID0gNDAwID09IHN0YXR1cztcbiAgdGhpcy51bmF1dGhvcml6ZWQgPSA0MDEgPT0gc3RhdHVzO1xuICB0aGlzLm5vdEFjY2VwdGFibGUgPSA0MDYgPT0gc3RhdHVzO1xuICB0aGlzLm5vdEZvdW5kID0gNDA0ID09IHN0YXR1cztcbiAgdGhpcy5mb3JiaWRkZW4gPSA0MDMgPT0gc3RhdHVzO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gYW4gYEVycm9yYCByZXByZXNlbnRhdGl2ZSBvZiB0aGlzIHJlc3BvbnNlLlxuICpcbiAqIEByZXR1cm4ge0Vycm9yfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXNwb25zZS5wcm90b3R5cGUudG9FcnJvciA9IGZ1bmN0aW9uKCl7XG4gIHZhciByZXEgPSB0aGlzLnJlcTtcbiAgdmFyIG1ldGhvZCA9IHJlcS5tZXRob2Q7XG4gIHZhciB1cmwgPSByZXEudXJsO1xuXG4gIHZhciBtc2cgPSAnY2Fubm90ICcgKyBtZXRob2QgKyAnICcgKyB1cmwgKyAnICgnICsgdGhpcy5zdGF0dXMgKyAnKSc7XG4gIHZhciBlcnIgPSBuZXcgRXJyb3IobXNnKTtcbiAgZXJyLnN0YXR1cyA9IHRoaXMuc3RhdHVzO1xuICBlcnIubWV0aG9kID0gbWV0aG9kO1xuICBlcnIudXJsID0gdXJsO1xuXG4gIHJldHVybiBlcnI7XG59O1xuXG4vKipcbiAqIEV4cG9zZSBgUmVzcG9uc2VgLlxuICovXG5cbnJlcXVlc3QuUmVzcG9uc2UgPSBSZXNwb25zZTtcblxuLyoqXG4gKiBJbml0aWFsaXplIGEgbmV3IGBSZXF1ZXN0YCB3aXRoIHRoZSBnaXZlbiBgbWV0aG9kYCBhbmQgYHVybGAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZFxuICogQHBhcmFtIHtTdHJpbmd9IHVybFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBSZXF1ZXN0KG1ldGhvZCwgdXJsKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgRW1pdHRlci5jYWxsKHRoaXMpO1xuICB0aGlzLl9xdWVyeSA9IHRoaXMuX3F1ZXJ5IHx8IFtdO1xuICB0aGlzLm1ldGhvZCA9IG1ldGhvZDtcbiAgdGhpcy51cmwgPSB1cmw7XG4gIHRoaXMuaGVhZGVyID0ge307XG4gIHRoaXMuX2hlYWRlciA9IHt9O1xuICB0aGlzLm9uKCdlbmQnLCBmdW5jdGlvbigpe1xuICAgIHZhciBlcnIgPSBudWxsO1xuICAgIHZhciByZXMgPSBudWxsO1xuXG4gICAgdHJ5IHtcbiAgICAgIHJlcyA9IG5ldyBSZXNwb25zZShzZWxmKTtcbiAgICB9IGNhdGNoKGUpIHtcbiAgICAgIGVyciA9IG5ldyBFcnJvcignUGFyc2VyIGlzIHVuYWJsZSB0byBwYXJzZSB0aGUgcmVzcG9uc2UnKTtcbiAgICAgIGVyci5wYXJzZSA9IHRydWU7XG4gICAgICBlcnIub3JpZ2luYWwgPSBlO1xuICAgICAgLy8gaXNzdWUgIzY3NTogcmV0dXJuIHRoZSByYXcgcmVzcG9uc2UgaWYgdGhlIHJlc3BvbnNlIHBhcnNpbmcgZmFpbHNcbiAgICAgIGVyci5yYXdSZXNwb25zZSA9IHNlbGYueGhyICYmIHNlbGYueGhyLnJlc3BvbnNlVGV4dCA/IHNlbGYueGhyLnJlc3BvbnNlVGV4dCA6IG51bGw7XG4gICAgICByZXR1cm4gc2VsZi5jYWxsYmFjayhlcnIpO1xuICAgIH1cblxuICAgIHNlbGYuZW1pdCgncmVzcG9uc2UnLCByZXMpO1xuXG4gICAgaWYgKGVycikge1xuICAgICAgcmV0dXJuIHNlbGYuY2FsbGJhY2soZXJyLCByZXMpO1xuICAgIH1cblxuICAgIGlmIChyZXMuc3RhdHVzID49IDIwMCAmJiByZXMuc3RhdHVzIDwgMzAwKSB7XG4gICAgICByZXR1cm4gc2VsZi5jYWxsYmFjayhlcnIsIHJlcyk7XG4gICAgfVxuXG4gICAgdmFyIG5ld19lcnIgPSBuZXcgRXJyb3IocmVzLnN0YXR1c1RleHQgfHwgJ1Vuc3VjY2Vzc2Z1bCBIVFRQIHJlc3BvbnNlJyk7XG4gICAgbmV3X2Vyci5vcmlnaW5hbCA9IGVycjtcbiAgICBuZXdfZXJyLnJlc3BvbnNlID0gcmVzO1xuICAgIG5ld19lcnIuc3RhdHVzID0gcmVzLnN0YXR1cztcblxuICAgIHNlbGYuY2FsbGJhY2sobmV3X2VyciwgcmVzKTtcbiAgfSk7XG59XG5cbi8qKlxuICogTWl4aW4gYEVtaXR0ZXJgLlxuICovXG5cbkVtaXR0ZXIoUmVxdWVzdC5wcm90b3R5cGUpO1xuXG4vKipcbiAqIEFsbG93IGZvciBleHRlbnNpb25cbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS51c2UgPSBmdW5jdGlvbihmbikge1xuICBmbih0aGlzKTtcbiAgcmV0dXJuIHRoaXM7XG59XG5cbi8qKlxuICogU2V0IHRpbWVvdXQgdG8gYG1zYC5cbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gbXNcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS50aW1lb3V0ID0gZnVuY3Rpb24obXMpe1xuICB0aGlzLl90aW1lb3V0ID0gbXM7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBDbGVhciBwcmV2aW91cyB0aW1lb3V0LlxuICpcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5jbGVhclRpbWVvdXQgPSBmdW5jdGlvbigpe1xuICB0aGlzLl90aW1lb3V0ID0gMDtcbiAgY2xlYXJUaW1lb3V0KHRoaXMuX3RpbWVyKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEFib3J0IHRoZSByZXF1ZXN0LCBhbmQgY2xlYXIgcG90ZW50aWFsIHRpbWVvdXQuXG4gKlxuICogQHJldHVybiB7UmVxdWVzdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuYWJvcnQgPSBmdW5jdGlvbigpe1xuICBpZiAodGhpcy5hYm9ydGVkKSByZXR1cm47XG4gIHRoaXMuYWJvcnRlZCA9IHRydWU7XG4gIHRoaXMueGhyLmFib3J0KCk7XG4gIHRoaXMuY2xlYXJUaW1lb3V0KCk7XG4gIHRoaXMuZW1pdCgnYWJvcnQnKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldCBoZWFkZXIgYGZpZWxkYCB0byBgdmFsYCwgb3IgbXVsdGlwbGUgZmllbGRzIHdpdGggb25lIG9iamVjdC5cbiAqXG4gKiBFeGFtcGxlczpcbiAqXG4gKiAgICAgIHJlcS5nZXQoJy8nKVxuICogICAgICAgIC5zZXQoJ0FjY2VwdCcsICdhcHBsaWNhdGlvbi9qc29uJylcbiAqICAgICAgICAuc2V0KCdYLUFQSS1LZXknLCAnZm9vYmFyJylcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiAgICAgIHJlcS5nZXQoJy8nKVxuICogICAgICAgIC5zZXQoeyBBY2NlcHQ6ICdhcHBsaWNhdGlvbi9qc29uJywgJ1gtQVBJLUtleSc6ICdmb29iYXInIH0pXG4gKiAgICAgICAgLmVuZChjYWxsYmFjayk7XG4gKlxuICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fSBmaWVsZFxuICogQHBhcmFtIHtTdHJpbmd9IHZhbFxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uKGZpZWxkLCB2YWwpe1xuICBpZiAoaXNPYmplY3QoZmllbGQpKSB7XG4gICAgZm9yICh2YXIga2V5IGluIGZpZWxkKSB7XG4gICAgICB0aGlzLnNldChrZXksIGZpZWxkW2tleV0pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICB0aGlzLl9oZWFkZXJbZmllbGQudG9Mb3dlckNhc2UoKV0gPSB2YWw7XG4gIHRoaXMuaGVhZGVyW2ZpZWxkXSA9IHZhbDtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFJlbW92ZSBoZWFkZXIgYGZpZWxkYC5cbiAqXG4gKiBFeGFtcGxlOlxuICpcbiAqICAgICAgcmVxLmdldCgnLycpXG4gKiAgICAgICAgLnVuc2V0KCdVc2VyLUFnZW50JylcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZmllbGRcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS51bnNldCA9IGZ1bmN0aW9uKGZpZWxkKXtcbiAgZGVsZXRlIHRoaXMuX2hlYWRlcltmaWVsZC50b0xvd2VyQ2FzZSgpXTtcbiAgZGVsZXRlIHRoaXMuaGVhZGVyW2ZpZWxkXTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEdldCBjYXNlLWluc2Vuc2l0aXZlIGhlYWRlciBgZmllbGRgIHZhbHVlLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBmaWVsZFxuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuZ2V0SGVhZGVyID0gZnVuY3Rpb24oZmllbGQpe1xuICByZXR1cm4gdGhpcy5faGVhZGVyW2ZpZWxkLnRvTG93ZXJDYXNlKCldO1xufTtcblxuLyoqXG4gKiBTZXQgQ29udGVudC1UeXBlIHRvIGB0eXBlYCwgbWFwcGluZyB2YWx1ZXMgZnJvbSBgcmVxdWVzdC50eXBlc2AuXG4gKlxuICogRXhhbXBsZXM6XG4gKlxuICogICAgICBzdXBlcmFnZW50LnR5cGVzLnhtbCA9ICdhcHBsaWNhdGlvbi94bWwnO1xuICpcbiAqICAgICAgcmVxdWVzdC5wb3N0KCcvJylcbiAqICAgICAgICAudHlwZSgneG1sJylcbiAqICAgICAgICAuc2VuZCh4bWxzdHJpbmcpXG4gKiAgICAgICAgLmVuZChjYWxsYmFjayk7XG4gKlxuICogICAgICByZXF1ZXN0LnBvc3QoJy8nKVxuICogICAgICAgIC50eXBlKCdhcHBsaWNhdGlvbi94bWwnKVxuICogICAgICAgIC5zZW5kKHhtbHN0cmluZylcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLnR5cGUgPSBmdW5jdGlvbih0eXBlKXtcbiAgdGhpcy5zZXQoJ0NvbnRlbnQtVHlwZScsIHJlcXVlc3QudHlwZXNbdHlwZV0gfHwgdHlwZSk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBGb3JjZSBnaXZlbiBwYXJzZXJcbiAqXG4gKiBTZXRzIHRoZSBib2R5IHBhcnNlciBubyBtYXR0ZXIgdHlwZS5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5wYXJzZSA9IGZ1bmN0aW9uKGZuKXtcbiAgdGhpcy5fcGFyc2VyID0gZm47XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZXQgQWNjZXB0IHRvIGB0eXBlYCwgbWFwcGluZyB2YWx1ZXMgZnJvbSBgcmVxdWVzdC50eXBlc2AuXG4gKlxuICogRXhhbXBsZXM6XG4gKlxuICogICAgICBzdXBlcmFnZW50LnR5cGVzLmpzb24gPSAnYXBwbGljYXRpb24vanNvbic7XG4gKlxuICogICAgICByZXF1ZXN0LmdldCgnL2FnZW50JylcbiAqICAgICAgICAuYWNjZXB0KCdqc29uJylcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiAgICAgIHJlcXVlc3QuZ2V0KCcvYWdlbnQnKVxuICogICAgICAgIC5hY2NlcHQoJ2FwcGxpY2F0aW9uL2pzb24nKVxuICogICAgICAgIC5lbmQoY2FsbGJhY2spO1xuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBhY2NlcHRcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5hY2NlcHQgPSBmdW5jdGlvbih0eXBlKXtcbiAgdGhpcy5zZXQoJ0FjY2VwdCcsIHJlcXVlc3QudHlwZXNbdHlwZV0gfHwgdHlwZSk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZXQgQXV0aG9yaXphdGlvbiBmaWVsZCB2YWx1ZSB3aXRoIGB1c2VyYCBhbmQgYHBhc3NgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1c2VyXG4gKiBAcGFyYW0ge1N0cmluZ30gcGFzc1xuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmF1dGggPSBmdW5jdGlvbih1c2VyLCBwYXNzKXtcbiAgdmFyIHN0ciA9IGJ0b2EodXNlciArICc6JyArIHBhc3MpO1xuICB0aGlzLnNldCgnQXV0aG9yaXphdGlvbicsICdCYXNpYyAnICsgc3RyKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiogQWRkIHF1ZXJ5LXN0cmluZyBgdmFsYC5cbipcbiogRXhhbXBsZXM6XG4qXG4qICAgcmVxdWVzdC5nZXQoJy9zaG9lcycpXG4qICAgICAucXVlcnkoJ3NpemU9MTAnKVxuKiAgICAgLnF1ZXJ5KHsgY29sb3I6ICdibHVlJyB9KVxuKlxuKiBAcGFyYW0ge09iamVjdHxTdHJpbmd9IHZhbFxuKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiogQGFwaSBwdWJsaWNcbiovXG5cblJlcXVlc3QucHJvdG90eXBlLnF1ZXJ5ID0gZnVuY3Rpb24odmFsKXtcbiAgaWYgKCdzdHJpbmcnICE9IHR5cGVvZiB2YWwpIHZhbCA9IHNlcmlhbGl6ZSh2YWwpO1xuICBpZiAodmFsKSB0aGlzLl9xdWVyeS5wdXNoKHZhbCk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBXcml0ZSB0aGUgZmllbGQgYG5hbWVgIGFuZCBgdmFsYCBmb3IgXCJtdWx0aXBhcnQvZm9ybS1kYXRhXCJcbiAqIHJlcXVlc3QgYm9kaWVzLlxuICpcbiAqIGBgYCBqc1xuICogcmVxdWVzdC5wb3N0KCcvdXBsb2FkJylcbiAqICAgLmZpZWxkKCdmb28nLCAnYmFyJylcbiAqICAgLmVuZChjYWxsYmFjayk7XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICogQHBhcmFtIHtTdHJpbmd8QmxvYnxGaWxlfSB2YWxcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5maWVsZCA9IGZ1bmN0aW9uKG5hbWUsIHZhbCl7XG4gIGlmICghdGhpcy5fZm9ybURhdGEpIHRoaXMuX2Zvcm1EYXRhID0gbmV3IHJvb3QuRm9ybURhdGEoKTtcbiAgdGhpcy5fZm9ybURhdGEuYXBwZW5kKG5hbWUsIHZhbCk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBRdWV1ZSB0aGUgZ2l2ZW4gYGZpbGVgIGFzIGFuIGF0dGFjaG1lbnQgdG8gdGhlIHNwZWNpZmllZCBgZmllbGRgLFxuICogd2l0aCBvcHRpb25hbCBgZmlsZW5hbWVgLlxuICpcbiAqIGBgYCBqc1xuICogcmVxdWVzdC5wb3N0KCcvdXBsb2FkJylcbiAqICAgLmF0dGFjaChuZXcgQmxvYihbJzxhIGlkPVwiYVwiPjxiIGlkPVwiYlwiPmhleSE8L2I+PC9hPiddLCB7IHR5cGU6IFwidGV4dC9odG1sXCJ9KSlcbiAqICAgLmVuZChjYWxsYmFjayk7XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZmllbGRcbiAqIEBwYXJhbSB7QmxvYnxGaWxlfSBmaWxlXG4gKiBAcGFyYW0ge1N0cmluZ30gZmlsZW5hbWVcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5hdHRhY2ggPSBmdW5jdGlvbihmaWVsZCwgZmlsZSwgZmlsZW5hbWUpe1xuICBpZiAoIXRoaXMuX2Zvcm1EYXRhKSB0aGlzLl9mb3JtRGF0YSA9IG5ldyByb290LkZvcm1EYXRhKCk7XG4gIHRoaXMuX2Zvcm1EYXRhLmFwcGVuZChmaWVsZCwgZmlsZSwgZmlsZW5hbWUgfHwgZmlsZS5uYW1lKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNlbmQgYGRhdGFgIGFzIHRoZSByZXF1ZXN0IGJvZHksIGRlZmF1bHRpbmcgdGhlIGAudHlwZSgpYCB0byBcImpzb25cIiB3aGVuXG4gKiBhbiBvYmplY3QgaXMgZ2l2ZW4uXG4gKlxuICogRXhhbXBsZXM6XG4gKlxuICogICAgICAgLy8gbWFudWFsIGpzb25cbiAqICAgICAgIHJlcXVlc3QucG9zdCgnL3VzZXInKVxuICogICAgICAgICAudHlwZSgnanNvbicpXG4gKiAgICAgICAgIC5zZW5kKCd7XCJuYW1lXCI6XCJ0alwifScpXG4gKiAgICAgICAgIC5lbmQoY2FsbGJhY2spXG4gKlxuICogICAgICAgLy8gYXV0byBqc29uXG4gKiAgICAgICByZXF1ZXN0LnBvc3QoJy91c2VyJylcbiAqICAgICAgICAgLnNlbmQoeyBuYW1lOiAndGonIH0pXG4gKiAgICAgICAgIC5lbmQoY2FsbGJhY2spXG4gKlxuICogICAgICAgLy8gbWFudWFsIHgtd3d3LWZvcm0tdXJsZW5jb2RlZFxuICogICAgICAgcmVxdWVzdC5wb3N0KCcvdXNlcicpXG4gKiAgICAgICAgIC50eXBlKCdmb3JtJylcbiAqICAgICAgICAgLnNlbmQoJ25hbWU9dGonKVxuICogICAgICAgICAuZW5kKGNhbGxiYWNrKVxuICpcbiAqICAgICAgIC8vIGF1dG8geC13d3ctZm9ybS11cmxlbmNvZGVkXG4gKiAgICAgICByZXF1ZXN0LnBvc3QoJy91c2VyJylcbiAqICAgICAgICAgLnR5cGUoJ2Zvcm0nKVxuICogICAgICAgICAuc2VuZCh7IG5hbWU6ICd0aicgfSlcbiAqICAgICAgICAgLmVuZChjYWxsYmFjaylcbiAqXG4gKiAgICAgICAvLyBkZWZhdWx0cyB0byB4LXd3dy1mb3JtLXVybGVuY29kZWRcbiAgKiAgICAgIHJlcXVlc3QucG9zdCgnL3VzZXInKVxuICAqICAgICAgICAuc2VuZCgnbmFtZT10b2JpJylcbiAgKiAgICAgICAgLnNlbmQoJ3NwZWNpZXM9ZmVycmV0JylcbiAgKiAgICAgICAgLmVuZChjYWxsYmFjaylcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xPYmplY3R9IGRhdGFcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24oZGF0YSl7XG4gIHZhciBvYmogPSBpc09iamVjdChkYXRhKTtcbiAgdmFyIHR5cGUgPSB0aGlzLmdldEhlYWRlcignQ29udGVudC1UeXBlJyk7XG5cbiAgLy8gbWVyZ2VcbiAgaWYgKG9iaiAmJiBpc09iamVjdCh0aGlzLl9kYXRhKSkge1xuICAgIGZvciAodmFyIGtleSBpbiBkYXRhKSB7XG4gICAgICB0aGlzLl9kYXRhW2tleV0gPSBkYXRhW2tleV07XG4gICAgfVxuICB9IGVsc2UgaWYgKCdzdHJpbmcnID09IHR5cGVvZiBkYXRhKSB7XG4gICAgaWYgKCF0eXBlKSB0aGlzLnR5cGUoJ2Zvcm0nKTtcbiAgICB0eXBlID0gdGhpcy5nZXRIZWFkZXIoJ0NvbnRlbnQtVHlwZScpO1xuICAgIGlmICgnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyA9PSB0eXBlKSB7XG4gICAgICB0aGlzLl9kYXRhID0gdGhpcy5fZGF0YVxuICAgICAgICA/IHRoaXMuX2RhdGEgKyAnJicgKyBkYXRhXG4gICAgICAgIDogZGF0YTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fZGF0YSA9ICh0aGlzLl9kYXRhIHx8ICcnKSArIGRhdGE7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRoaXMuX2RhdGEgPSBkYXRhO1xuICB9XG5cbiAgaWYgKCFvYmogfHwgaXNIb3N0KGRhdGEpKSByZXR1cm4gdGhpcztcbiAgaWYgKCF0eXBlKSB0aGlzLnR5cGUoJ2pzb24nKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEludm9rZSB0aGUgY2FsbGJhY2sgd2l0aCBgZXJyYCBhbmQgYHJlc2BcbiAqIGFuZCBoYW5kbGUgYXJpdHkgY2hlY2suXG4gKlxuICogQHBhcmFtIHtFcnJvcn0gZXJyXG4gKiBAcGFyYW0ge1Jlc3BvbnNlfSByZXNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmNhbGxiYWNrID0gZnVuY3Rpb24oZXJyLCByZXMpe1xuICB2YXIgZm4gPSB0aGlzLl9jYWxsYmFjaztcbiAgdGhpcy5jbGVhclRpbWVvdXQoKTtcbiAgZm4oZXJyLCByZXMpO1xufTtcblxuLyoqXG4gKiBJbnZva2UgY2FsbGJhY2sgd2l0aCB4LWRvbWFpbiBlcnJvci5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5jcm9zc0RvbWFpbkVycm9yID0gZnVuY3Rpb24oKXtcbiAgdmFyIGVyciA9IG5ldyBFcnJvcignUmVxdWVzdCBoYXMgYmVlbiB0ZXJtaW5hdGVkXFxuUG9zc2libGUgY2F1c2VzOiB0aGUgbmV0d29yayBpcyBvZmZsaW5lLCBPcmlnaW4gaXMgbm90IGFsbG93ZWQgYnkgQWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2luLCB0aGUgcGFnZSBpcyBiZWluZyB1bmxvYWRlZCwgZXRjLicpO1xuICBlcnIuY3Jvc3NEb21haW4gPSB0cnVlO1xuXG4gIGVyci5zdGF0dXMgPSB0aGlzLnN0YXR1cztcbiAgZXJyLm1ldGhvZCA9IHRoaXMubWV0aG9kO1xuICBlcnIudXJsID0gdGhpcy51cmw7XG5cbiAgdGhpcy5jYWxsYmFjayhlcnIpO1xufTtcblxuLyoqXG4gKiBJbnZva2UgY2FsbGJhY2sgd2l0aCB0aW1lb3V0IGVycm9yLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlcXVlc3QucHJvdG90eXBlLnRpbWVvdXRFcnJvciA9IGZ1bmN0aW9uKCl7XG4gIHZhciB0aW1lb3V0ID0gdGhpcy5fdGltZW91dDtcbiAgdmFyIGVyciA9IG5ldyBFcnJvcigndGltZW91dCBvZiAnICsgdGltZW91dCArICdtcyBleGNlZWRlZCcpO1xuICBlcnIudGltZW91dCA9IHRpbWVvdXQ7XG4gIHRoaXMuY2FsbGJhY2soZXJyKTtcbn07XG5cbi8qKlxuICogRW5hYmxlIHRyYW5zbWlzc2lvbiBvZiBjb29raWVzIHdpdGggeC1kb21haW4gcmVxdWVzdHMuXG4gKlxuICogTm90ZSB0aGF0IGZvciB0aGlzIHRvIHdvcmsgdGhlIG9yaWdpbiBtdXN0IG5vdCBiZVxuICogdXNpbmcgXCJBY2Nlc3MtQ29udHJvbC1BbGxvdy1PcmlnaW5cIiB3aXRoIGEgd2lsZGNhcmQsXG4gKiBhbmQgYWxzbyBtdXN0IHNldCBcIkFjY2Vzcy1Db250cm9sLUFsbG93LUNyZWRlbnRpYWxzXCJcbiAqIHRvIFwidHJ1ZVwiLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUud2l0aENyZWRlbnRpYWxzID0gZnVuY3Rpb24oKXtcbiAgdGhpcy5fd2l0aENyZWRlbnRpYWxzID0gdHJ1ZTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEluaXRpYXRlIHJlcXVlc3QsIGludm9raW5nIGNhbGxiYWNrIGBmbihyZXMpYFxuICogd2l0aCBhbiBpbnN0YW5jZW9mIGBSZXNwb25zZWAuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbihmbil7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdmFyIHhociA9IHRoaXMueGhyID0gcmVxdWVzdC5nZXRYSFIoKTtcbiAgdmFyIHF1ZXJ5ID0gdGhpcy5fcXVlcnkuam9pbignJicpO1xuICB2YXIgdGltZW91dCA9IHRoaXMuX3RpbWVvdXQ7XG4gIHZhciBkYXRhID0gdGhpcy5fZm9ybURhdGEgfHwgdGhpcy5fZGF0YTtcblxuICAvLyBzdG9yZSBjYWxsYmFja1xuICB0aGlzLl9jYWxsYmFjayA9IGZuIHx8IG5vb3A7XG5cbiAgLy8gc3RhdGUgY2hhbmdlXG4gIHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpe1xuICAgIGlmICg0ICE9IHhoci5yZWFkeVN0YXRlKSByZXR1cm47XG5cbiAgICAvLyBJbiBJRTksIHJlYWRzIHRvIGFueSBwcm9wZXJ0eSAoZS5nLiBzdGF0dXMpIG9mZiBvZiBhbiBhYm9ydGVkIFhIUiB3aWxsXG4gICAgLy8gcmVzdWx0IGluIHRoZSBlcnJvciBcIkNvdWxkIG5vdCBjb21wbGV0ZSB0aGUgb3BlcmF0aW9uIGR1ZSB0byBlcnJvciBjMDBjMDIzZlwiXG4gICAgdmFyIHN0YXR1cztcbiAgICB0cnkgeyBzdGF0dXMgPSB4aHIuc3RhdHVzIH0gY2F0Y2goZSkgeyBzdGF0dXMgPSAwOyB9XG5cbiAgICBpZiAoMCA9PSBzdGF0dXMpIHtcbiAgICAgIGlmIChzZWxmLnRpbWVkb3V0KSByZXR1cm4gc2VsZi50aW1lb3V0RXJyb3IoKTtcbiAgICAgIGlmIChzZWxmLmFib3J0ZWQpIHJldHVybjtcbiAgICAgIHJldHVybiBzZWxmLmNyb3NzRG9tYWluRXJyb3IoKTtcbiAgICB9XG4gICAgc2VsZi5lbWl0KCdlbmQnKTtcbiAgfTtcblxuICAvLyBwcm9ncmVzc1xuICB2YXIgaGFuZGxlUHJvZ3Jlc3MgPSBmdW5jdGlvbihlKXtcbiAgICBpZiAoZS50b3RhbCA+IDApIHtcbiAgICAgIGUucGVyY2VudCA9IGUubG9hZGVkIC8gZS50b3RhbCAqIDEwMDtcbiAgICB9XG4gICAgZS5kaXJlY3Rpb24gPSAnZG93bmxvYWQnO1xuICAgIHNlbGYuZW1pdCgncHJvZ3Jlc3MnLCBlKTtcbiAgfTtcbiAgaWYgKHRoaXMuaGFzTGlzdGVuZXJzKCdwcm9ncmVzcycpKSB7XG4gICAgeGhyLm9ucHJvZ3Jlc3MgPSBoYW5kbGVQcm9ncmVzcztcbiAgfVxuICB0cnkge1xuICAgIGlmICh4aHIudXBsb2FkICYmIHRoaXMuaGFzTGlzdGVuZXJzKCdwcm9ncmVzcycpKSB7XG4gICAgICB4aHIudXBsb2FkLm9ucHJvZ3Jlc3MgPSBoYW5kbGVQcm9ncmVzcztcbiAgICB9XG4gIH0gY2F0Y2goZSkge1xuICAgIC8vIEFjY2Vzc2luZyB4aHIudXBsb2FkIGZhaWxzIGluIElFIGZyb20gYSB3ZWIgd29ya2VyLCBzbyBqdXN0IHByZXRlbmQgaXQgZG9lc24ndCBleGlzdC5cbiAgICAvLyBSZXBvcnRlZCBoZXJlOlxuICAgIC8vIGh0dHBzOi8vY29ubmVjdC5taWNyb3NvZnQuY29tL0lFL2ZlZWRiYWNrL2RldGFpbHMvODM3MjQ1L3htbGh0dHByZXF1ZXN0LXVwbG9hZC10aHJvd3MtaW52YWxpZC1hcmd1bWVudC13aGVuLXVzZWQtZnJvbS13ZWItd29ya2VyLWNvbnRleHRcbiAgfVxuXG4gIC8vIHRpbWVvdXRcbiAgaWYgKHRpbWVvdXQgJiYgIXRoaXMuX3RpbWVyKSB7XG4gICAgdGhpcy5fdGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7XG4gICAgICBzZWxmLnRpbWVkb3V0ID0gdHJ1ZTtcbiAgICAgIHNlbGYuYWJvcnQoKTtcbiAgICB9LCB0aW1lb3V0KTtcbiAgfVxuXG4gIC8vIHF1ZXJ5c3RyaW5nXG4gIGlmIChxdWVyeSkge1xuICAgIHF1ZXJ5ID0gcmVxdWVzdC5zZXJpYWxpemVPYmplY3QocXVlcnkpO1xuICAgIHRoaXMudXJsICs9IH50aGlzLnVybC5pbmRleE9mKCc/JylcbiAgICAgID8gJyYnICsgcXVlcnlcbiAgICAgIDogJz8nICsgcXVlcnk7XG4gIH1cblxuICAvLyBpbml0aWF0ZSByZXF1ZXN0XG4gIHhoci5vcGVuKHRoaXMubWV0aG9kLCB0aGlzLnVybCwgdHJ1ZSk7XG5cbiAgLy8gQ09SU1xuICBpZiAodGhpcy5fd2l0aENyZWRlbnRpYWxzKSB4aHIud2l0aENyZWRlbnRpYWxzID0gdHJ1ZTtcblxuICAvLyBib2R5XG4gIGlmICgnR0VUJyAhPSB0aGlzLm1ldGhvZCAmJiAnSEVBRCcgIT0gdGhpcy5tZXRob2QgJiYgJ3N0cmluZycgIT0gdHlwZW9mIGRhdGEgJiYgIWlzSG9zdChkYXRhKSkge1xuICAgIC8vIHNlcmlhbGl6ZSBzdHVmZlxuICAgIHZhciBjb250ZW50VHlwZSA9IHRoaXMuZ2V0SGVhZGVyKCdDb250ZW50LVR5cGUnKTtcbiAgICB2YXIgc2VyaWFsaXplID0gdGhpcy5fcGFyc2VyIHx8IHJlcXVlc3Quc2VyaWFsaXplW2NvbnRlbnRUeXBlID8gY29udGVudFR5cGUuc3BsaXQoJzsnKVswXSA6ICcnXTtcbiAgICBpZiAoIXNlcmlhbGl6ZSAmJiBpc0pTT04oY29udGVudFR5cGUpKSBzZXJpYWxpemUgPSByZXF1ZXN0LnNlcmlhbGl6ZVsnYXBwbGljYXRpb24vanNvbiddO1xuICAgIGlmIChzZXJpYWxpemUpIGRhdGEgPSBzZXJpYWxpemUoZGF0YSk7XG4gIH1cblxuICAvLyBzZXQgaGVhZGVyIGZpZWxkc1xuICBmb3IgKHZhciBmaWVsZCBpbiB0aGlzLmhlYWRlcikge1xuICAgIGlmIChudWxsID09IHRoaXMuaGVhZGVyW2ZpZWxkXSkgY29udGludWU7XG4gICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoZmllbGQsIHRoaXMuaGVhZGVyW2ZpZWxkXSk7XG4gIH1cblxuICAvLyBzZW5kIHN0dWZmXG4gIHRoaXMuZW1pdCgncmVxdWVzdCcsIHRoaXMpO1xuXG4gIC8vIElFMTEgeGhyLnNlbmQodW5kZWZpbmVkKSBzZW5kcyAndW5kZWZpbmVkJyBzdHJpbmcgYXMgUE9TVCBwYXlsb2FkIChpbnN0ZWFkIG9mIG5vdGhpbmcpXG4gIC8vIFdlIG5lZWQgbnVsbCBoZXJlIGlmIGRhdGEgaXMgdW5kZWZpbmVkXG4gIHhoci5zZW5kKHR5cGVvZiBkYXRhICE9PSAndW5kZWZpbmVkJyA/IGRhdGEgOiBudWxsKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEZhdXggcHJvbWlzZSBzdXBwb3J0XG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVsZmlsbFxuICogQHBhcmFtIHtGdW5jdGlvbn0gcmVqZWN0XG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICovXG5cblJlcXVlc3QucHJvdG90eXBlLnRoZW4gPSBmdW5jdGlvbiAoZnVsZmlsbCwgcmVqZWN0KSB7XG4gIHJldHVybiB0aGlzLmVuZChmdW5jdGlvbihlcnIsIHJlcykge1xuICAgIGVyciA/IHJlamVjdChlcnIpIDogZnVsZmlsbChyZXMpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBFeHBvc2UgYFJlcXVlc3RgLlxuICovXG5cbnJlcXVlc3QuUmVxdWVzdCA9IFJlcXVlc3Q7XG5cbi8qKlxuICogSXNzdWUgYSByZXF1ZXN0OlxuICpcbiAqIEV4YW1wbGVzOlxuICpcbiAqICAgIHJlcXVlc3QoJ0dFVCcsICcvdXNlcnMnKS5lbmQoY2FsbGJhY2spXG4gKiAgICByZXF1ZXN0KCcvdXNlcnMnKS5lbmQoY2FsbGJhY2spXG4gKiAgICByZXF1ZXN0KCcvdXNlcnMnLCBjYWxsYmFjaylcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kXG4gKiBAcGFyYW0ge1N0cmluZ3xGdW5jdGlvbn0gdXJsIG9yIGNhbGxiYWNrXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiByZXF1ZXN0KG1ldGhvZCwgdXJsKSB7XG4gIC8vIGNhbGxiYWNrXG4gIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiB1cmwpIHtcbiAgICByZXR1cm4gbmV3IFJlcXVlc3QoJ0dFVCcsIG1ldGhvZCkuZW5kKHVybCk7XG4gIH1cblxuICAvLyB1cmwgZmlyc3RcbiAgaWYgKDEgPT0gYXJndW1lbnRzLmxlbmd0aCkge1xuICAgIHJldHVybiBuZXcgUmVxdWVzdCgnR0VUJywgbWV0aG9kKTtcbiAgfVxuXG4gIHJldHVybiBuZXcgUmVxdWVzdChtZXRob2QsIHVybCk7XG59XG5cbi8qKlxuICogR0VUIGB1cmxgIHdpdGggb3B0aW9uYWwgY2FsbGJhY2sgYGZuKHJlcylgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmxcbiAqIEBwYXJhbSB7TWl4ZWR8RnVuY3Rpb259IGRhdGEgb3IgZm5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5yZXF1ZXN0LmdldCA9IGZ1bmN0aW9uKHVybCwgZGF0YSwgZm4pe1xuICB2YXIgcmVxID0gcmVxdWVzdCgnR0VUJywgdXJsKTtcbiAgaWYgKCdmdW5jdGlvbicgPT0gdHlwZW9mIGRhdGEpIGZuID0gZGF0YSwgZGF0YSA9IG51bGw7XG4gIGlmIChkYXRhKSByZXEucXVlcnkoZGF0YSk7XG4gIGlmIChmbikgcmVxLmVuZChmbik7XG4gIHJldHVybiByZXE7XG59O1xuXG4vKipcbiAqIEhFQUQgYHVybGAgd2l0aCBvcHRpb25hbCBjYWxsYmFjayBgZm4ocmVzKWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHVybFxuICogQHBhcmFtIHtNaXhlZHxGdW5jdGlvbn0gZGF0YSBvciBmblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge1JlcXVlc3R9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbnJlcXVlc3QuaGVhZCA9IGZ1bmN0aW9uKHVybCwgZGF0YSwgZm4pe1xuICB2YXIgcmVxID0gcmVxdWVzdCgnSEVBRCcsIHVybCk7XG4gIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiBkYXRhKSBmbiA9IGRhdGEsIGRhdGEgPSBudWxsO1xuICBpZiAoZGF0YSkgcmVxLnNlbmQoZGF0YSk7XG4gIGlmIChmbikgcmVxLmVuZChmbik7XG4gIHJldHVybiByZXE7XG59O1xuXG4vKipcbiAqIERFTEVURSBgdXJsYCB3aXRoIG9wdGlvbmFsIGNhbGxiYWNrIGBmbihyZXMpYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJsXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHJldHVybiB7UmVxdWVzdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gZGVsKHVybCwgZm4pe1xuICB2YXIgcmVxID0gcmVxdWVzdCgnREVMRVRFJywgdXJsKTtcbiAgaWYgKGZuKSByZXEuZW5kKGZuKTtcbiAgcmV0dXJuIHJlcTtcbn07XG5cbnJlcXVlc3RbJ2RlbCddID0gZGVsO1xucmVxdWVzdFsnZGVsZXRlJ10gPSBkZWw7XG5cbi8qKlxuICogUEFUQ0ggYHVybGAgd2l0aCBvcHRpb25hbCBgZGF0YWAgYW5kIGNhbGxiYWNrIGBmbihyZXMpYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJsXG4gKiBAcGFyYW0ge01peGVkfSBkYXRhXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHJldHVybiB7UmVxdWVzdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxucmVxdWVzdC5wYXRjaCA9IGZ1bmN0aW9uKHVybCwgZGF0YSwgZm4pe1xuICB2YXIgcmVxID0gcmVxdWVzdCgnUEFUQ0gnLCB1cmwpO1xuICBpZiAoJ2Z1bmN0aW9uJyA9PSB0eXBlb2YgZGF0YSkgZm4gPSBkYXRhLCBkYXRhID0gbnVsbDtcbiAgaWYgKGRhdGEpIHJlcS5zZW5kKGRhdGEpO1xuICBpZiAoZm4pIHJlcS5lbmQoZm4pO1xuICByZXR1cm4gcmVxO1xufTtcblxuLyoqXG4gKiBQT1NUIGB1cmxgIHdpdGggb3B0aW9uYWwgYGRhdGFgIGFuZCBjYWxsYmFjayBgZm4ocmVzKWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHVybFxuICogQHBhcmFtIHtNaXhlZH0gZGF0YVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge1JlcXVlc3R9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbnJlcXVlc3QucG9zdCA9IGZ1bmN0aW9uKHVybCwgZGF0YSwgZm4pe1xuICB2YXIgcmVxID0gcmVxdWVzdCgnUE9TVCcsIHVybCk7XG4gIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiBkYXRhKSBmbiA9IGRhdGEsIGRhdGEgPSBudWxsO1xuICBpZiAoZGF0YSkgcmVxLnNlbmQoZGF0YSk7XG4gIGlmIChmbikgcmVxLmVuZChmbik7XG4gIHJldHVybiByZXE7XG59O1xuXG4vKipcbiAqIFBVVCBgdXJsYCB3aXRoIG9wdGlvbmFsIGBkYXRhYCBhbmQgY2FsbGJhY2sgYGZuKHJlcylgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmxcbiAqIEBwYXJhbSB7TWl4ZWR8RnVuY3Rpb259IGRhdGEgb3IgZm5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5yZXF1ZXN0LnB1dCA9IGZ1bmN0aW9uKHVybCwgZGF0YSwgZm4pe1xuICB2YXIgcmVxID0gcmVxdWVzdCgnUFVUJywgdXJsKTtcbiAgaWYgKCdmdW5jdGlvbicgPT0gdHlwZW9mIGRhdGEpIGZuID0gZGF0YSwgZGF0YSA9IG51bGw7XG4gIGlmIChkYXRhKSByZXEuc2VuZChkYXRhKTtcbiAgaWYgKGZuKSByZXEuZW5kKGZuKTtcbiAgcmV0dXJuIHJlcTtcbn07XG5cbi8qKlxuICogRXhwb3NlIGByZXF1ZXN0YC5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVlc3Q7XG4iXX0=\r
18868 \r
18869  /*global JSONEditor*/\r
18870 'use strict';\r
18871 \r
18872 window.SwaggerUi = Backbone.Router.extend({\r
18873 \r
18874   dom_id: 'swagger_ui',\r
18875 \r
18876   // Attributes\r
18877   options: null,\r
18878   api: null,\r
18879   headerView: null,\r
18880   mainView: null,\r
18881 \r
18882   // SwaggerUi accepts all the same options as SwaggerApi\r
18883   initialize: function(options) {\r
18884     options = options || {};\r
18885 \r
18886     if (options.defaultModelRendering !== 'model') {\r
18887       options.defaultModelRendering = 'schema';\r
18888     }\r
18889 \r
18890     if (!options.highlightSizeThreshold) {\r
18891       options.highlightSizeThreshold = 100000;\r
18892     }\r
18893 \r
18894     // Allow dom_id to be overridden\r
18895     if (options.dom_id) {\r
18896       this.dom_id = options.dom_id;\r
18897       delete options.dom_id;\r
18898     }\r
18899 \r
18900     if (!options.supportedSubmitMethods){\r
18901       options.supportedSubmitMethods = [\r
18902         'get',\r
18903         'put',\r
18904         'post',\r
18905         'delete',\r
18906         'head',\r
18907         'options',\r
18908         'patch'\r
18909       ];\r
18910     }\r
18911 \r
18912     if (typeof options.oauth2RedirectUrl === 'string') {\r
18913       window.oAuthRedirectUrl = options.redirectUrl;\r
18914     }\r
18915 \r
18916     // Create an empty div which contains the dom_id\r
18917     if (! $('#' + this.dom_id).length){\r
18918       $('body').append('<div id="' + this.dom_id + '"></div>') ;\r
18919     }\r
18920 \r
18921     this.options = options;\r
18922 \r
18923     // set marked options\r
18924     marked.setOptions({gfm: true});\r
18925 \r
18926     // Set the callbacks\r
18927     var that = this;\r
18928     this.options.success = function() { return that.render(); };\r
18929     this.options.progress = function(d) { return that.showMessage(d); };\r
18930     this.options.failure = function(d) { return that.onLoadFailure(d); };\r
18931 \r
18932     // Create view to handle the header inputs\r
18933     this.headerView = new SwaggerUi.Views.HeaderView({el: $('#header')});\r
18934 \r
18935     // Event handler for when the baseUrl/apiKey is entered by user\r
18936     this.headerView.on('update-swagger-ui', function(data) {\r
18937       return that.updateSwaggerUi(data);\r
18938     });\r
18939 \r
18940     // JSon Editor custom theming\r
18941      JSONEditor.defaults.iconlibs.swagger = JSONEditor.AbstractIconLib.extend({\r
18942       mapping: {\r
18943         collapse: 'collapse',\r
18944         expand: 'expand'\r
18945         },\r
18946       icon_prefix: 'swagger-'\r
18947       });\r
18948 \r
18949   },\r
18950 \r
18951   // Set an option after initializing\r
18952   setOption: function(option, value) {\r
18953     this.options[option] = value;\r
18954   },\r
18955 \r
18956   // Get the value of a previously set option\r
18957   getOption: function(option) {\r
18958     return this.options[option];\r
18959   },\r
18960 \r
18961   // Event handler for when url/key is received from user\r
18962   updateSwaggerUi: function(data){\r
18963     this.options.url = data.url;\r
18964     this.load();\r
18965   },\r
18966 \r
18967   // Create an api and render\r
18968   load: function(){\r
18969     // Initialize the API object\r
18970     if (this.mainView) {\r
18971       this.mainView.clear();\r
18972     }\r
18973 \r
18974     if (this.authView) {\r
18975       this.authView.remove();\r
18976     }\r
18977     var url = this.options.url;\r
18978     if (url && url.indexOf('http') !== 0) {\r
18979       url = this.buildUrl(window.location.href.toString(), url);\r
18980     }\r
18981     if(this.api) {\r
18982       this.options.authorizations = this.api.clientAuthorizations.authz;\r
18983     }\r
18984     this.options.url = url;\r
18985     this.headerView.update(url);\r
18986 \r
18987     this.api = new SwaggerClient(this.options);\r
18988   },\r
18989 \r
18990   // collapse all sections\r
18991   collapseAll: function(){\r
18992     Docs.collapseEndpointListForResource('');\r
18993   },\r
18994 \r
18995   // list operations for all sections\r
18996   listAll: function(){\r
18997     Docs.collapseOperationsForResource('');\r
18998   },\r
18999 \r
19000   // expand operations for all sections\r
19001   expandAll: function(){\r
19002     Docs.expandOperationsForResource('');\r
19003   },\r
19004 \r
19005   // This is bound to success handler for SwaggerApi\r
19006   //  so it gets called when SwaggerApi completes loading\r
19007   render: function(){\r
19008     var authsModel;\r
19009     this.showMessage('Finished Loading Resource Information. Rendering Swagger UI...');\r
19010     this.mainView = new SwaggerUi.Views.MainView({\r
19011       model: this.api,\r
19012       el: $('#' + this.dom_id),\r
19013       swaggerOptions: this.options,\r
19014       router: this\r
19015     }).render();\r
19016     if (!_.isEmpty(this.api.securityDefinitions)){\r
19017       authsModel = _.map(this.api.securityDefinitions, function (auth, name) {\r
19018         var result = {};\r
19019         result[name] = auth;\r
19020         return result;\r
19021       });\r
19022       this.authView = new SwaggerUi.Views.AuthButtonView({\r
19023         data: SwaggerUi.utils.parseSecurityDefinitions(authsModel),\r
19024         router: this\r
19025       });\r
19026       $('#auth_container').append(this.authView.render().el);\r
19027     }\r
19028     this.showMessage();\r
19029     switch (this.options.docExpansion) {\r
19030       case 'full':\r
19031         this.expandAll(); break;\r
19032       case 'list':\r
19033         this.listAll(); break;\r
19034       default:\r
19035         break;\r
19036     }\r
19037     this.renderGFM();\r
19038 \r
19039     if (this.options.onComplete){\r
19040       this.options.onComplete(this.api, this);\r
19041     }\r
19042 \r
19043     setTimeout(Docs.shebang.bind(this), 100);\r
19044   },\r
19045 \r
19046   buildUrl: function(base, url){\r
19047     if (url.indexOf('/') === 0) {\r
19048       var parts = base.split('/');\r
19049       base = parts[0] + '//' + parts[2];\r
19050       return base + url;\r
19051     } else {\r
19052       var endOfPath = base.length;\r
19053 \r
19054       if (base.indexOf('?') > -1){\r
19055         endOfPath = Math.min(endOfPath, base.indexOf('?'));\r
19056       }\r
19057 \r
19058       if (base.indexOf('#') > -1){\r
19059         endOfPath = Math.min(endOfPath, base.indexOf('#'));\r
19060       }\r
19061 \r
19062       base = base.substring(0, endOfPath);\r
19063 \r
19064       if (base.indexOf('/', base.length - 1 ) !== -1){\r
19065         return base + url;\r
19066       }\r
19067 \r
19068       return base + '/' + url;\r
19069     }\r
19070   },\r
19071 \r
19072   // Shows message on topbar of the ui\r
19073   showMessage: function(data){\r
19074     if (data === undefined) {\r
19075       data = '';\r
19076     }\r
19077     var $msgbar = $('#message-bar');\r
19078     $msgbar.removeClass('message-fail');\r
19079     $msgbar.addClass('message-success');\r
19080     $msgbar.text(data);\r
19081     if(window.SwaggerTranslator) {\r
19082       window.SwaggerTranslator.translate($msgbar);\r
19083     }\r
19084   },\r
19085 \r
19086   // shows message in red\r
19087   onLoadFailure: function(data){\r
19088     if (data === undefined) {\r
19089       data = '';\r
19090     }\r
19091     $('#message-bar').removeClass('message-success');\r
19092     $('#message-bar').addClass('message-fail');\r
19093 \r
19094     var val = $('#message-bar').text(data);\r
19095 \r
19096     if (this.options.onFailure) {\r
19097       this.options.onFailure(data);\r
19098     }\r
19099 \r
19100     return val;\r
19101   },\r
19102 \r
19103   // Renders GFM for elements with 'markdown' class\r
19104   renderGFM: function(){\r
19105     $('.markdown').each(function(){\r
19106       $(this).html(marked($(this).html()));\r
19107     });\r
19108 \r
19109     $('.propDesc', '.model-signature .description').each(function () {\r
19110       $(this).html(marked($(this).html())).addClass('markdown');\r
19111     });\r
19112   }\r
19113 \r
19114 });\r
19115 \r
19116 window.SwaggerUi.Views = {};\r
19117 window.SwaggerUi.Models = {};\r
19118 window.SwaggerUi.Collections = {};\r
19119 window.SwaggerUi.partials = {};\r
19120 window.SwaggerUi.utils = {};\r
19121 \r
19122 // don't break backward compatibility with previous versions and warn users to upgrade their code\r
19123 (function(){\r
19124   window.authorizations = {\r
19125     add: function() {\r
19126       warn('Using window.authorizations is deprecated. Please use SwaggerUi.api.clientAuthorizations.add().');\r
19127 \r
19128       if (typeof window.swaggerUi === 'undefined') {\r
19129         throw new TypeError('window.swaggerUi is not defined');\r
19130       }\r
19131 \r
19132       if (window.swaggerUi instanceof SwaggerUi) {\r
19133         window.swaggerUi.api.clientAuthorizations.add.apply(window.swaggerUi.api.clientAuthorizations, arguments);\r
19134       }\r
19135     }\r
19136   };\r
19137 \r
19138   window.ApiKeyAuthorization = function() {\r
19139     warn('window.ApiKeyAuthorization is deprecated. Please use SwaggerClient.ApiKeyAuthorization.');\r
19140     SwaggerClient.ApiKeyAuthorization.apply(window, arguments);\r
19141   };\r
19142 \r
19143   window.PasswordAuthorization = function() {\r
19144     warn('window.PasswordAuthorization is deprecated. Please use SwaggerClient.PasswordAuthorization.');\r
19145     SwaggerClient.PasswordAuthorization.apply(window, arguments);\r
19146   };\r
19147 \r
19148   function warn(message) {\r
19149     if ('console' in window && typeof window.console.warn === 'function') {\r
19150       console.warn(message);\r
19151     }\r
19152   }\r
19153 })();\r
19154 \r
19155 \r
19156 // UMD\r
19157 (function (root, factory) {\r
19158     if (typeof define === 'function' && define.amd) {\r
19159         // AMD. Register as an anonymous module.\r
19160         define(['b'], function (b) {\r
19161             return (root.SwaggerUi = factory(b));\r
19162         });\r
19163     } else if (typeof exports === 'object') {\r
19164         // Node. Does not work with strict CommonJS, but\r
19165         // only CommonJS-like environments that support module.exports,\r
19166         // like Node.\r
19167         module.exports = factory(require('b'));\r
19168     } else {\r
19169         // Browser globals\r
19170         root.SwaggerUi = factory(root.b);\r
19171     }\r
19172 }(this, function () {\r
19173     return SwaggerUi;\r
19174 }));\r
19175 \r
19176 'use strict';\r
19177 \r
19178 window.SwaggerUi.utils = {\r
19179     parseSecurityDefinitions: function (security) {\r
19180         var auths = Object.assign({}, window.swaggerUi.api.authSchemes || window.swaggerUi.api.securityDefinitions);\r
19181         var oauth2Arr = [];\r
19182         var authsArr = [];\r
19183         var scopes = [];\r
19184         var utils = window.SwaggerUi.utils;\r
19185 \r
19186         if (!Array.isArray(security)) { return null; }\r
19187 \r
19188         security.forEach(function (item) {\r
19189             var singleSecurity = {};\r
19190             var singleOauth2Security = {};\r
19191 \r
19192             for (var key in item) {\r
19193                 if (Array.isArray(item[key])) {\r
19194                     if (!auths[key]) { continue; }\r
19195                     auths[key] = auths[key] || {};\r
19196                     if (auths[key].type === 'oauth2') {\r
19197                         singleOauth2Security[key] = Object.assign({}, auths[key]);\r
19198                         for (var i in singleOauth2Security[key].scopes) {\r
19199                             if (item[key].indexOf(i) < 0) {\r
19200                                 delete singleOauth2Security[key].scopes[i];\r
19201                             }\r
19202                         }\r
19203                         singleOauth2Security[key].scopes = utils.parseOauth2Scopes(singleOauth2Security[key].scopes);\r
19204                         scopes = _.merge(scopes, singleOauth2Security[key].scopes);\r
19205                     } else {\r
19206                         singleSecurity[key] = Object.assign({}, auths[key]);\r
19207                     }\r
19208                 } else {\r
19209                     if (item[key].type === 'oauth2') {\r
19210                         singleOauth2Security[key] = Object.assign({}, item[key]);\r
19211                         singleOauth2Security[key].scopes = utils.parseOauth2Scopes(singleOauth2Security[key].scopes);\r
19212                         scopes = _.merge(scopes, singleOauth2Security[key].scopes);\r
19213                     } else {\r
19214                         singleSecurity[key] = item[key];\r
19215                     }\r
19216                 }\r
19217             }\r
19218 \r
19219             if (!_.isEmpty(singleSecurity)) {\r
19220                 authsArr.push(singleSecurity);\r
19221             }\r
19222 \r
19223             if (!_.isEmpty(singleOauth2Security)){\r
19224                 oauth2Arr.push(singleOauth2Security);\r
19225             }\r
19226         });\r
19227 \r
19228         return {\r
19229             auths : authsArr,\r
19230             oauth2: oauth2Arr,\r
19231             scopes: scopes\r
19232         };\r
19233     },\r
19234 \r
19235     parseOauth2Scopes: function (data) {\r
19236         var scopes = Object.assign({}, data);\r
19237         var result = [];\r
19238         var key;\r
19239 \r
19240         for (key in scopes) {\r
19241             result.push({scope: key, description: scopes[key]});\r
19242         }\r
19243 \r
19244         return result;\r
19245     }\r
19246 };\r
19247 'use strict';\r
19248 \r
19249 SwaggerUi.Models.ApiKeyAuthModel = Backbone.Model.extend({\r
19250     defaults: {\r
19251         'in': '',\r
19252         name: '',\r
19253         title: '',\r
19254         value: ''\r
19255     },\r
19256 \r
19257     initialize: function () {\r
19258         this.on('change', this.validate);\r
19259     },\r
19260 \r
19261     validate: function () {\r
19262         var valid = !!this.get('value');\r
19263 \r
19264         this.set('valid', valid);\r
19265 \r
19266         return valid;\r
19267     }\r
19268 });\r
19269 'use strict';\r
19270 \r
19271 SwaggerUi.Views.ApiKeyAuthView = Backbone.View.extend({ // TODO: append this to global SwaggerUi\r
19272 \r
19273     events: {\r
19274         'change .input_apiKey_entry': 'apiKeyChange'\r
19275     },\r
19276 \r
19277     selectors: {\r
19278         apikeyInput: '.input_apiKey_entry'\r
19279     },\r
19280 \r
19281     template: Handlebars.templates.apikey_auth,\r
19282 \r
19283     initialize: function(opts) {\r
19284         this.options = opts || {};\r
19285         this.router = this.options.router;\r
19286     },\r
19287 \r
19288     render: function (){\r
19289         this.$el.html(this.template(this.model.toJSON()));\r
19290 \r
19291         return this;\r
19292     },\r
19293 \r
19294     apiKeyChange: function (e) {\r
19295         var val = $(e.target).val();\r
19296         if (val) {\r
19297             this.$(this.selectors.apikeyInput).removeClass('error');\r
19298         }\r
19299 \r
19300         this.model.set('value', val);\r
19301     },\r
19302 \r
19303     isValid: function () {\r
19304         return this.model.validate();\r
19305     },\r
19306 \r
19307     highlightInvalid: function () {\r
19308         if (!this.isValid()) {\r
19309             this.$(this.selectors.apikeyInput).addClass('error');\r
19310         }\r
19311     }\r
19312 \r
19313 });\r
19314 'use strict';\r
19315 \r
19316 SwaggerUi.Views.AuthButtonView = Backbone.View.extend({\r
19317     events: {\r
19318         'click .authorize__btn': 'authorizeBtnClick'\r
19319     },\r
19320 \r
19321     tpls: {\r
19322         popup: Handlebars.templates.popup,\r
19323         authBtn: Handlebars.templates.auth_button,\r
19324         authBtnOperation: Handlebars.templates.auth_button_operation\r
19325     },\r
19326 \r
19327     initialize: function(opts) {\r
19328         this.options = opts || {};\r
19329         this.options.data = this.options.data || {};\r
19330         this.isOperation = this.options.isOperation;\r
19331         this.model = this.model || {};\r
19332         this.router = this.options.router;\r
19333         this.auths = this.options.data.oauth2.concat(this.options.data.auths);\r
19334     },\r
19335 \r
19336     render: function () {\r
19337         var tplName = this.isOperation ? 'authBtnOperation' : 'authBtn';\r
19338 \r
19339         this.$authEl = this.renderAuths(this.auths);\r
19340         this.$el.html(this.tpls[tplName](this.model));\r
19341 \r
19342         return this;\r
19343     },\r
19344 \r
19345     authorizeBtnClick: function (e) {\r
19346         var authsModel;\r
19347 \r
19348         e.preventDefault();\r
19349 \r
19350         authsModel = {\r
19351             title: 'Available authorizations',\r
19352             content: this.$authEl\r
19353         };\r
19354 \r
19355         this.popup = new SwaggerUi.Views.PopupView({model: authsModel});\r
19356         this.popup.render();\r
19357     },\r
19358 \r
19359     renderAuths: function (auths) {\r
19360         var $el = $('<div>');\r
19361         var isLogout = false;\r
19362 \r
19363         auths.forEach(function (auth) {\r
19364             var authView = new SwaggerUi.Views.AuthView({data: auth, router: this.router});\r
19365             var authEl = authView.render().el;\r
19366             $el.append(authEl);\r
19367             if (authView.isLogout) {\r
19368                 isLogout = true;\r
19369             }\r
19370         }, this);\r
19371 \r
19372         this.model.isLogout = isLogout;\r
19373 \r
19374         return $el;\r
19375     }\r
19376 \r
19377 });\r
19378 \r
19379 'use strict';\r
19380 \r
19381 SwaggerUi.Collections.AuthsCollection = Backbone.Collection.extend({\r
19382     constructor: function() {\r
19383         var args = Array.prototype.slice.call(arguments);\r
19384 \r
19385         args[0] = this.parse(args[0]);\r
19386 \r
19387         Backbone.Collection.apply(this, args);\r
19388     },\r
19389 \r
19390     add: function (model) {\r
19391         var args = Array.prototype.slice.call(arguments);\r
19392 \r
19393         if (Array.isArray(model)) {\r
19394             args[0] = _.map(model, function(val) {\r
19395                 return this.handleOne(val);\r
19396             }, this);\r
19397         } else {\r
19398             args[0] = this.handleOne(model);\r
19399         }\r
19400 \r
19401         Backbone.Collection.prototype.add.apply(this, args);\r
19402     },\r
19403 \r
19404     handleOne: function (model) {\r
19405         var result = model;\r
19406 \r
19407         if (! (model instanceof Backbone.Model) ) {\r
19408             switch (model.type) {\r
19409                 case 'oauth2':\r
19410                     result = new SwaggerUi.Models.Oauth2Model(model);\r
19411                     break;\r
19412                 case 'basic':\r
19413                     result = new SwaggerUi.Models.BasicAuthModel(model);\r
19414                     break;\r
19415                 case 'apiKey':\r
19416                     result = new SwaggerUi.Models.ApiKeyAuthModel(model);\r
19417                     break;\r
19418                 default:\r
19419                     result = new Backbone.Model(model);\r
19420             }\r
19421         }\r
19422 \r
19423         return result;\r
19424     },\r
19425 \r
19426     isValid: function () {\r
19427         var valid = true;\r
19428 \r
19429         this.models.forEach(function(model) {\r
19430             if (!model.validate()) {\r
19431                 valid = false;\r
19432             }\r
19433         });\r
19434 \r
19435         return valid;\r
19436     },\r
19437 \r
19438     isAuthorized: function () {\r
19439         return this.length === this.where({ isLogout: true }).length;\r
19440     },\r
19441 \r
19442     isPartiallyAuthorized: function () {\r
19443         return this.where({ isLogout: true }).length > 0;\r
19444     },\r
19445 \r
19446     parse: function (data) {\r
19447         var authz = Object.assign({}, window.swaggerUi.api.clientAuthorizations.authz);\r
19448 \r
19449         return _.map(data, function (auth, name) {\r
19450             var isBasic = authz.basic && auth.type === 'basic';\r
19451 \r
19452             _.extend(auth, {\r
19453                 title: name\r
19454             });\r
19455 \r
19456             if (authz[name] || isBasic) {\r
19457                 _.extend(auth, {\r
19458                     isLogout: true,\r
19459                     value: isBasic ? undefined : authz[name].value,\r
19460                     username: isBasic ? authz.basic.username : undefined,\r
19461                     password: isBasic ? authz.basic.password : undefined,\r
19462                     valid: true\r
19463                 });\r
19464             }\r
19465 \r
19466             return auth;\r
19467         });\r
19468     }\r
19469 });\r
19470 'use strict';\r
19471 \r
19472 SwaggerUi.Views.AuthsCollectionView = Backbone.View.extend({\r
19473 \r
19474     initialize: function(opts) {\r
19475         this.options = opts || {};\r
19476         this.options.data = this.options.data || {};\r
19477         this.router = this.options.router;\r
19478 \r
19479         this.collection = new SwaggerUi.Collections.AuthsCollection(opts.data);\r
19480 \r
19481         this.$innerEl = $('<div>');\r
19482         this.authViews = [];\r
19483     },\r
19484 \r
19485     render: function () {\r
19486         this.collection.each(function (auth) {\r
19487             this.renderOneAuth(auth);\r
19488         }, this);\r
19489 \r
19490         this.$el.html(this.$innerEl.html() ? this.$innerEl : '');\r
19491 \r
19492         return this;\r
19493     },\r
19494 \r
19495     renderOneAuth: function (authModel) {\r
19496         var authViewEl, authView, authViewName;\r
19497         var type = authModel.get('type');\r
19498 \r
19499         if (type === 'apiKey') {\r
19500             authViewName = 'ApiKeyAuthView';\r
19501         } else if (type === 'basic' && this.$innerEl.find('.basic_auth_container').length === 0) {\r
19502             authViewName = 'BasicAuthView';\r
19503         } else if (type === 'oauth2') {\r
19504             authViewName = 'Oauth2View';\r
19505         }\r
19506 \r
19507         if (authViewName) {\r
19508             authView = new SwaggerUi.Views[authViewName]({model: authModel, router: this.router});\r
19509             authViewEl = authView.render().el;\r
19510             this.authViews.push(authView);\r
19511         }\r
19512 \r
19513         this.$innerEl.append(authViewEl);\r
19514     },\r
19515 \r
19516     highlightInvalid: function () {\r
19517         this.authViews.forEach(function (view) {\r
19518             view.highlightInvalid();\r
19519         }, this);\r
19520     }\r
19521 \r
19522 });\r
19523 \r
19524 'use strict';\r
19525 \r
19526 /* global redirect_uri */\r
19527 /* global clientId */\r
19528 /* global scopeSeparator */\r
19529 /* global additionalQueryStringParams */\r
19530 /* global clientSecret */\r
19531 /* global onOAuthComplete */\r
19532 /* global realm */\r
19533 /*jshint unused:false*/\r
19534 \r
19535 SwaggerUi.Views.AuthView = Backbone.View.extend({\r
19536     events: {\r
19537         'click .auth_submit__button': 'authorizeClick',\r
19538         'click .auth_logout__button': 'logoutClick'\r
19539     },\r
19540 \r
19541     tpls: {\r
19542         main: Handlebars.templates.auth_view\r
19543     },\r
19544 \r
19545     selectors: {\r
19546         innerEl: '.auth_inner',\r
19547         authBtn: '.auth_submit__button'\r
19548     },\r
19549 \r
19550     initialize: function(opts) {\r
19551         this.options = opts || {};\r
19552         opts.data = opts.data || {};\r
19553         this.router = this.options.router;\r
19554 \r
19555         this.authsCollectionView = new SwaggerUi.Views.AuthsCollectionView({data: opts.data});\r
19556 \r
19557         this.$el.html(this.tpls.main({\r
19558             isLogout: this.authsCollectionView.collection.isAuthorized(),\r
19559             isAuthorized: this.authsCollectionView.collection.isPartiallyAuthorized()\r
19560         }));\r
19561         this.$innerEl = this.$(this.selectors.innerEl);\r
19562         this.isLogout = this.authsCollectionView.collection.isPartiallyAuthorized();\r
19563     },\r
19564 \r
19565     render: function () {\r
19566         this.$innerEl.html(this.authsCollectionView.render().el);\r
19567 \r
19568         return this;\r
19569     },\r
19570 \r
19571     authorizeClick: function (e) {\r
19572         e.preventDefault();\r
19573         e.stopPropagation();\r
19574 \r
19575         if (this.authsCollectionView.collection.isValid()) {\r
19576             this.authorize();\r
19577         } else {\r
19578             this.authsCollectionView.highlightInvalid();\r
19579         }\r
19580     },\r
19581 \r
19582     authorize: function () {\r
19583         this.authsCollectionView.collection.forEach(function (auth) {\r
19584             var keyAuth, basicAuth;\r
19585             var type = auth.get('type');\r
19586 \r
19587             if (type === 'apiKey') {\r
19588                 keyAuth = new SwaggerClient.ApiKeyAuthorization(\r
19589                     auth.get('name'),\r
19590                     auth.get('value'),\r
19591                     auth.get('in')\r
19592                 );\r
19593 \r
19594                 this.router.api.clientAuthorizations.add(auth.get('title'), keyAuth);\r
19595             } else if (type === 'basic') {\r
19596                 basicAuth = new SwaggerClient.PasswordAuthorization(auth.get('username'), auth.get('password'));\r
19597                 this.router.api.clientAuthorizations.add(auth.get('type'), basicAuth);\r
19598             } else if (type === 'oauth2') {\r
19599                 this.handleOauth2Login(auth);\r
19600             }\r
19601         }, this);\r
19602 \r
19603         this.router.load();\r
19604     },\r
19605 \r
19606     logoutClick: function (e) {\r
19607         e.preventDefault();\r
19608 \r
19609         this.authsCollectionView.collection.forEach(function (auth) {\r
19610             var name = auth.get('type') === 'basic' ? 'basic' : auth.get('title');\r
19611 \r
19612             window.swaggerUi.api.clientAuthorizations.remove(name);\r
19613         });\r
19614 \r
19615         this.router.load();\r
19616     },\r
19617 \r
19618     // taken from lib/swagger-oauth.js\r
19619     handleOauth2Login: function (auth) {\r
19620         var host = window.location;\r
19621         var pathname = location.pathname.substring(0, location.pathname.lastIndexOf('/'));\r
19622         var defaultRedirectUrl = host.protocol + '//' + host.host + pathname + '/o2c.html';\r
19623         var redirectUrl = window.oAuthRedirectUrl || defaultRedirectUrl;\r
19624         var url = null;\r
19625         var scopes = _.map(auth.get('scopes'), function (scope) {\r
19626             return scope.scope;\r
19627         });\r
19628         var state, dets, ep;\r
19629         window.OAuthSchemeKey = auth.get('title');\r
19630 \r
19631         window.enabledScopes = scopes;\r
19632         var flow = auth.get('flow');\r
19633 \r
19634         if(auth.get('type') === 'oauth2' && flow && (flow === 'implicit' || flow === 'accessCode')) {\r
19635             dets = auth.attributes;\r
19636             url = dets.authorizationUrl + '?response_type=' + (flow === 'implicit' ? 'token' : 'code');\r
19637             window.swaggerUi.tokenName = dets.tokenName || 'access_token';\r
19638             window.swaggerUi.tokenUrl = (flow === 'accessCode' ? dets.tokenUrl : null);\r
19639             state = window.OAuthSchemeKey;\r
19640         }\r
19641         else if(auth.get('type') === 'oauth2' && flow && (flow === 'application')) {\r
19642             dets = auth.attributes;\r
19643             window.swaggerUi.tokenName = dets.tokenName || 'access_token';\r
19644             this.clientCredentialsFlow(scopes, dets.tokenUrl, window.OAuthSchemeKey);\r
19645             return;\r
19646         }\r
19647         else if(auth.get('grantTypes')) {\r
19648             // 1.2 support\r
19649             var o = auth.get('grantTypes');\r
19650             for(var t in o) {\r
19651                 if(o.hasOwnProperty(t) && t === 'implicit') {\r
19652                     dets = o[t];\r
19653                     ep = dets.loginEndpoint.url;\r
19654                     url = dets.loginEndpoint.url + '?response_type=token';\r
19655                     window.swaggerUi.tokenName = dets.tokenName;\r
19656                 }\r
19657                 else if (o.hasOwnProperty(t) && t === 'accessCode') {\r
19658                     dets = o[t];\r
19659                     ep = dets.tokenRequestEndpoint.url;\r
19660                     url = dets.tokenRequestEndpoint.url + '?response_type=code';\r
19661                     window.swaggerUi.tokenName = dets.tokenName;\r
19662                 }\r
19663             }\r
19664         }\r
19665 \r
19666         var redirect_uri = redirectUrl;\r
19667 \r
19668         url += '&redirect_uri=' + encodeURIComponent(redirectUrl);\r
19669         url += '&realm=' + encodeURIComponent(realm);\r
19670         url += '&client_id=' + encodeURIComponent(clientId);\r
19671         url += '&scope=' + encodeURIComponent(scopes.join(scopeSeparator));\r
19672         url += '&state=' + encodeURIComponent(state);\r
19673         for (var key in additionalQueryStringParams) {\r
19674             url += '&' + key + '=' + encodeURIComponent(additionalQueryStringParams[key]);\r
19675         }\r
19676 \r
19677         window.open(url);\r
19678     },\r
19679 \r
19680     // taken from lib/swagger-oauth.js\r
19681     clientCredentialsFlow: function (scopes, tokenUrl, OAuthSchemeKey) {\r
19682         var params = {\r
19683             'client_id': clientId,\r
19684             'client_secret': clientSecret,\r
19685             'scope': scopes.join(' '),\r
19686             'grant_type': 'client_credentials'\r
19687         };\r
19688         $.ajax({\r
19689             url : tokenUrl,\r
19690             type: 'POST',\r
19691             data: params,\r
19692             success: function (data)\r
19693             {\r
19694                 onOAuthComplete(data, OAuthSchemeKey);\r
19695             },\r
19696             error: function ()\r
19697             {\r
19698                 onOAuthComplete('');\r
19699             }\r
19700         });\r
19701     }\r
19702 \r
19703 });\r
19704 \r
19705 'use strict';\r
19706 \r
19707 SwaggerUi.Models.BasicAuthModel = Backbone.Model.extend({\r
19708     defaults: {\r
19709         username: '',\r
19710         password: '',\r
19711         title: 'basic'\r
19712     },\r
19713 \r
19714     initialize: function () {\r
19715         this.on('change', this.validate);\r
19716     },\r
19717 \r
19718     validate: function () {\r
19719         var valid = !!this.get('password') && !!this.get('username');\r
19720 \r
19721         this.set('valid', valid);\r
19722 \r
19723         return valid;\r
19724     }\r
19725 });\r
19726 'use strict';\r
19727 \r
19728 SwaggerUi.Views.BasicAuthView = Backbone.View.extend({\r
19729 \r
19730     initialize: function (opts) {\r
19731         this.options = opts || {};\r
19732         this.router = this.options.router;\r
19733     },\r
19734 \r
19735     events: {\r
19736         'change .auth_input': 'inputChange'\r
19737     },\r
19738 \r
19739     selectors: {\r
19740         usernameInput: '.basic_auth__username',\r
19741         passwordInput: '.basic_auth__password'\r
19742     },\r
19743 \r
19744     cls: {\r
19745         error: 'error'\r
19746     },\r
19747 \r
19748     template: Handlebars.templates.basic_auth,\r
19749 \r
19750     render: function(){\r
19751         $(this.el).html(this.template(this.model.toJSON()));\r
19752 \r
19753         return this;\r
19754     },\r
19755 \r
19756     inputChange: function (e) {\r
19757         var $el = $(e.target);\r
19758         var val = $el.val();\r
19759         var attr = $el.prop('name');\r
19760 \r
19761         if (val) {\r
19762             $el.removeClass(this.cls.error);\r
19763         }\r
19764 \r
19765         this.model.set(attr, val);\r
19766     },\r
19767 \r
19768     isValid: function () {\r
19769         return this.model.validate();\r
19770     },\r
19771 \r
19772     highlightInvalid: function () {\r
19773         if (!this.model.get('username')) {\r
19774             this.$(this.selectors.usernameInput).addClass(this.cls.error);\r
19775         }\r
19776 \r
19777         if (!this.model.get('password')) {\r
19778             this.$(this.selectors.passwordInput).addClass(this.cls.error);\r
19779         }\r
19780     }\r
19781 });\r
19782 'use strict';\r
19783 \r
19784 SwaggerUi.Views.ContentTypeView = Backbone.View.extend({\r
19785   initialize: function() {},\r
19786 \r
19787   render: function(){\r
19788         this.model.contentTypeId = 'ct' + Math.random();\r
19789     $(this.el).html(Handlebars.templates.content_type(this.model));\r
19790     return this;\r
19791   }\r
19792 });\r
19793 'use strict';\r
19794 \r
19795 SwaggerUi.Views.HeaderView = Backbone.View.extend({\r
19796   events: {\r
19797     'click #show-pet-store-icon'    : 'showPetStore',\r
19798     'click #explore'                : 'showCustom',\r
19799     'keyup #input_baseUrl'          : 'showCustomOnKeyup',\r
19800     'keyup #input_apiKey'           : 'showCustomOnKeyup'\r
19801   },\r
19802 \r
19803   initialize: function(){},\r
19804 \r
19805   showPetStore: function(){\r
19806     this.trigger('update-swagger-ui', {\r
19807       url:'http://petstore.swagger.io/v2/swagger.json'\r
19808     });\r
19809   },\r
19810 \r
19811   showCustomOnKeyup: function(e){\r
19812     if (e.keyCode === 13) {\r
19813       this.showCustom();\r
19814     }\r
19815   },\r
19816 \r
19817   showCustom: function(e){\r
19818     if (e) {\r
19819       e.preventDefault();\r
19820     }\r
19821 \r
19822     this.trigger('update-swagger-ui', {\r
19823       url: $('#input_baseUrl').val()\r
19824     });\r
19825   },\r
19826 \r
19827   update: function(url, apiKey, trigger){\r
19828     if (trigger === undefined) {\r
19829       trigger = false;\r
19830     }\r
19831 \r
19832     $('#input_baseUrl').val(url);\r
19833 \r
19834     if (trigger) {\r
19835       this.trigger('update-swagger-ui', {url:url});\r
19836     }\r
19837   }\r
19838 });\r
19839 \r
19840 'use strict';\r
19841 \r
19842 SwaggerUi.Views.MainView = Backbone.View.extend({\r
19843   apisSorter : {\r
19844     alpha   : function(a,b){ return a.name.localeCompare(b.name); }\r
19845   },\r
19846   operationsSorters : {\r
19847     alpha   : function(a,b){ return a.path.localeCompare(b.path); },\r
19848     method  : function(a,b){ return a.method.localeCompare(b.method); }\r
19849   },\r
19850   initialize: function(opts){\r
19851     var sorterOption, sorterFn, key, value;\r
19852     opts = opts || {};\r
19853 \r
19854     this.router = opts.router;\r
19855 \r
19856     // Sort APIs\r
19857     if (opts.swaggerOptions.apisSorter) {\r
19858       sorterOption = opts.swaggerOptions.apisSorter;\r
19859       if (_.isFunction(sorterOption)) {\r
19860         sorterFn = sorterOption;\r
19861       } else {\r
19862         sorterFn = this.apisSorter[sorterOption];\r
19863       }\r
19864       if (_.isFunction(sorterFn)) {\r
19865         this.model.apisArray.sort(sorterFn);\r
19866       }\r
19867     }\r
19868     // Sort operations of each API\r
19869     if (opts.swaggerOptions.operationsSorter) {\r
19870       sorterOption = opts.swaggerOptions.operationsSorter;\r
19871       if (_.isFunction(sorterOption)) {\r
19872         sorterFn = sorterOption;\r
19873       } else {\r
19874         sorterFn = this.operationsSorters[sorterOption];\r
19875       }\r
19876       if (_.isFunction(sorterFn)) {\r
19877         for (key in this.model.apisArray) {\r
19878           this.model.apisArray[key].operationsArray.sort(sorterFn);\r
19879         }\r
19880       }\r
19881     }\r
19882 \r
19883     // set up the UI for input\r
19884     this.model.auths = [];\r
19885 \r
19886     for (key in this.model.securityDefinitions) {\r
19887       value = this.model.securityDefinitions[key];\r
19888 \r
19889       this.model.auths.push({\r
19890         name: key,\r
19891         type: value.type,\r
19892         value: value\r
19893       });\r
19894     }\r
19895 \r
19896     if ('validatorUrl' in opts.swaggerOptions) {\r
19897       // Validator URL specified explicitly\r
19898       this.model.validatorUrl = opts.swaggerOptions.validatorUrl;\r
19899     } else if (this.model.url.indexOf('localhost') > 0 || this.model.url.indexOf('127.0.0.1') > 0) {\r
19900       // Localhost override\r
19901       this.model.validatorUrl = null;\r
19902     } else {\r
19903       // Default validator\r
19904       if(window.location.protocol === 'https:') {\r
19905         this.model.validatorUrl = 'https://online.swagger.io/validator';\r
19906       }\r
19907       else {\r
19908         this.model.validatorUrl = 'http://online.swagger.io/validator';\r
19909       }\r
19910     }\r
19911 \r
19912     // JSonEditor requires type='object' to be present on defined types, we add it if it's missing\r
19913     // is there any valid case were it should not be added ?\r
19914     var def;\r
19915     for(def in this.model.definitions){\r
19916       if (!this.model.definitions[def].type){\r
19917         this.model.definitions[def].type = 'object';\r
19918       }\r
19919     }\r
19920 \r
19921   },\r
19922 \r
19923   render: function () {\r
19924     $(this.el).html(Handlebars.templates.main(this.model));\r
19925     this.info = this.$('.info')[0];\r
19926 \r
19927     if (this.info) {\r
19928       this.info.addEventListener('click', this.onLinkClick, true);\r
19929     }\r
19930 \r
19931     this.model.securityDefinitions = this.model.securityDefinitions || {};\r
19932 \r
19933     // Render each resource\r
19934 \r
19935     var resources = {};\r
19936     var counter = 0;\r
19937     for (var i = 0; i < this.model.apisArray.length; i++) {\r
19938       var resource = this.model.apisArray[i];\r
19939       var id = resource.name;\r
19940       while (typeof resources[id] !== 'undefined') {\r
19941         id = id + '_' + counter;\r
19942         counter += 1;\r
19943       }\r
19944       resource.id = id;\r
19945       resources[id] = resource;\r
19946       this.addResource(resource, this.model.auths);\r
19947     }\r
19948 \r
19949     $('.propWrap').hover(function onHover(){\r
19950       $('.optionsWrapper', $(this)).show();\r
19951     }, function offhover(){\r
19952       $('.optionsWrapper', $(this)).hide();\r
19953     });\r
19954     return this;\r
19955   },\r
19956 \r
19957   addResource: function(resource, auths){\r
19958     // Render a resource and add it to resources li\r
19959     resource.id = resource.id.replace(/\s/g, '_');\r
19960 \r
19961     // Make all definitions available at the root of the resource so that they can\r
19962     // be loaded by the JSonEditor\r
19963     resource.definitions = this.model.definitions;\r
19964 \r
19965     var resourceView = new SwaggerUi.Views.ResourceView({\r
19966       model: resource,\r
19967       router: this.router,\r
19968       tagName: 'li',\r
19969       id: 'resource_' + resource.id,\r
19970       className: 'resource',\r
19971       auths: auths,\r
19972       swaggerOptions: this.options.swaggerOptions\r
19973     });\r
19974     $('#resources', this.el).append(resourceView.render().el);\r
19975   },\r
19976 \r
19977   clear: function(){\r
19978     $(this.el).html('');\r
19979   },\r
19980 \r
19981   onLinkClick: function (e) {\r
19982     var el = e.target;\r
19983 \r
19984     if (el.tagName === 'A' && el.href && !el.target) {\r
19985         e.preventDefault();\r
19986         window.open(el.href, '_blank');\r
19987     }\r
19988   }\r
19989 });\r
19990 \r
19991 'use strict';\r
19992 \r
19993 SwaggerUi.Models.Oauth2Model = Backbone.Model.extend({\r
19994     defaults: {\r
19995         scopes: {}\r
19996     },\r
19997 \r
19998     initialize: function () {\r
19999         this.on('change', this.validate);\r
20000     },\r
20001 \r
20002     setScopes: function (name, val) {\r
20003         var auth = _.extend({}, this.attributes);\r
20004         var index = _.findIndex(auth.scopes, function(o) {\r
20005             return o.scope === name;\r
20006         });\r
20007         auth.scopes[index].checked = val;\r
20008 \r
20009         this.set(auth);\r
20010         this.validate();\r
20011     },\r
20012 \r
20013     validate: function () {\r
20014         var valid =  _.findIndex(this.get('scopes'), function (o) {\r
20015            return o.checked === true;\r
20016         }) > -1;\r
20017 \r
20018         this.set('valid', valid);\r
20019 \r
20020         return valid;\r
20021     }\r
20022 });\r
20023 'use strict';\r
20024 \r
20025 SwaggerUi.Views.Oauth2View = Backbone.View.extend({\r
20026     events: {\r
20027         'change .oauth-scope': 'scopeChange'\r
20028     },\r
20029 \r
20030     template: Handlebars.templates.oauth2,\r
20031 \r
20032     render: function () {\r
20033         this.$el.html(this.template(this.model.toJSON()));\r
20034 \r
20035         return this;\r
20036     },\r
20037 \r
20038     scopeChange: function (e) {\r
20039         var val = $(e.target).prop('checked');\r
20040         var scope = $(e.target).data('scope');\r
20041 \r
20042         this.model.setScopes(scope, val);\r
20043     }\r
20044 });\r
20045 'use strict';\r
20046 \r
20047 SwaggerUi.Views.OperationView = Backbone.View.extend({\r
20048   invocationUrl: null,\r
20049 \r
20050   events: {\r
20051     'submit .sandbox'         : 'submitOperation',\r
20052     'click .submit'           : 'submitOperation',\r
20053     'click .response_hider'   : 'hideResponse',\r
20054     'click .toggleOperation'  : 'toggleOperationContent',\r
20055     'mouseenter .api-ic'      : 'mouseEnter',\r
20056     'dblclick .curl'          : 'selectText',\r
20057     'change [name=responseContentType]' : 'showSnippet'\r
20058   },\r
20059 \r
20060   initialize: function(opts) {\r
20061     opts = opts || {};\r
20062     this.router = opts.router;\r
20063     this.auths = opts.auths;\r
20064     this.parentId = this.model.parentId;\r
20065     this.nickname = this.model.nickname;\r
20066     this.model.encodedParentId = encodeURIComponent(this.parentId);\r
20067 \r
20068     if (opts.swaggerOptions) {\r
20069       this.model.defaultRendering = opts.swaggerOptions.defaultModelRendering;\r
20070 \r
20071       if (opts.swaggerOptions.showRequestHeaders) {\r
20072         this.model.showRequestHeaders = true;\r
20073       }\r
20074     }\r
20075     return this;\r
20076   },\r
20077 \r
20078   selectText: function(event) {\r
20079     var doc = document,\r
20080         text = event.target.firstChild,\r
20081         range,\r
20082         selection;\r
20083     if (doc.body.createTextRange) {\r
20084       range = document.body.createTextRange();\r
20085       range.moveToElementText(text);\r
20086       range.select();\r
20087     } else if (window.getSelection) {\r
20088       selection = window.getSelection();\r
20089       range = document.createRange();\r
20090       range.selectNodeContents(text);\r
20091       selection.removeAllRanges();\r
20092       selection.addRange(range);\r
20093     }\r
20094   },\r
20095 \r
20096   mouseEnter: function(e) {\r
20097     var elem = $(this.el).find('.content');\r
20098     var x = e.pageX;\r
20099     var y = e.pageY;\r
20100     var scX = $(window).scrollLeft();\r
20101     var scY = $(window).scrollTop();\r
20102     var scMaxX = scX + $(window).width();\r
20103     var scMaxY = scY + $(window).height();\r
20104     var wd = elem.width();\r
20105     var hgh = elem.height();\r
20106 \r
20107     if (x + wd > scMaxX) {\r
20108       x = scMaxX - wd;\r
20109     }\r
20110 \r
20111     if (x < scX) {\r
20112       x = scX;\r
20113     }\r
20114 \r
20115     if (y + hgh > scMaxY) {\r
20116       y = scMaxY - hgh;\r
20117     }\r
20118 \r
20119     if (y < scY) {\r
20120       y = scY;\r
20121     }\r
20122 \r
20123     var pos = {};\r
20124     pos.top = y;\r
20125     pos.left = x;\r
20126     elem.css(pos);\r
20127   },\r
20128 \r
20129   // Note: copied from CoffeeScript compiled file\r
20130   // TODO: redactor\r
20131   render: function() {\r
20132     var a, auth, auths, code, contentTypeModel, isMethodSubmissionSupported, k, key, l, len, len1, len2, len3, len4, m, modelAuths, n, o, p, param, q, ref, ref1, ref2, ref3, ref4, ref5, responseContentTypeView, responseSignatureView, schema, schemaObj, scopeIndex, signatureModel, statusCode, successResponse, type, v, value, produces, isXML, isJSON;\r
20133     isMethodSubmissionSupported = jQuery.inArray(this.model.method, this.model.supportedSubmitMethods()) >= 0;\r
20134     if (!isMethodSubmissionSupported) {\r
20135       this.model.isReadOnly = true;\r
20136     }\r
20137     this.model.description = this.model.description || this.model.notes;\r
20138     this.model.oauth = null;\r
20139     modelAuths = this.model.authorizations || this.model.security;\r
20140     if (modelAuths) {\r
20141       if (Array.isArray(modelAuths)) {\r
20142         for (l = 0, len = modelAuths.length; l < len; l++) {\r
20143           auths = modelAuths[l];\r
20144           for (key in auths) {\r
20145             for (a in this.auths) {\r
20146               auth = this.auths[a];\r
20147               if (key === auth.name) {\r
20148                 if (auth.type === 'oauth2') {\r
20149                   this.model.oauth = {};\r
20150                   this.model.oauth.scopes = [];\r
20151                   ref1 = auth.value.scopes;\r
20152                   for (k in ref1) {\r
20153                     v = ref1[k];\r
20154                     scopeIndex = auths[key].indexOf(k);\r
20155                     if (scopeIndex >= 0) {\r
20156                       o = {\r
20157                         scope: k,\r
20158                         description: v\r
20159                       };\r
20160                       this.model.oauth.scopes.push(o);\r
20161                     }\r
20162                   }\r
20163                 }\r
20164               }\r
20165             }\r
20166           }\r
20167         }\r
20168       } else {\r
20169         for (k in modelAuths) {\r
20170           v = modelAuths[k];\r
20171           if (k === 'oauth2') {\r
20172             if (this.model.oauth === null) {\r
20173               this.model.oauth = {};\r
20174             }\r
20175             if (this.model.oauth.scopes === void 0) {\r
20176               this.model.oauth.scopes = [];\r
20177             }\r
20178             for (m = 0, len1 = v.length; m < len1; m++) {\r
20179               o = v[m];\r
20180               this.model.oauth.scopes.push(o);\r
20181             }\r
20182           }\r
20183         }\r
20184       }\r
20185     }\r
20186     if (typeof this.model.responses !== 'undefined') {\r
20187       this.model.responseMessages = [];\r
20188       ref2 = this.model.responses;\r
20189       for (code in ref2) {\r
20190         value = ref2[code];\r
20191         schema = null;\r
20192         schemaObj = this.model.responses[code].schema;\r
20193         if (schemaObj && schemaObj.$ref) {\r
20194           schema = schemaObj.$ref;\r
20195           if (schema.indexOf('#/definitions/') !== -1) {\r
20196             schema = schema.replace(/^.*#\/definitions\//, '');\r
20197           }\r
20198         }\r
20199         this.model.responseMessages.push({\r
20200           code: code,\r
20201           message: value.description,\r
20202           responseModel: schema,\r
20203           headers: value.headers,\r
20204           schema: schemaObj\r
20205         });\r
20206       }\r
20207     }\r
20208     if (typeof this.model.responseMessages === 'undefined') {\r
20209       this.model.responseMessages = [];\r
20210     }\r
20211     signatureModel = null;\r
20212     produces = this.model.produces;\r
20213     isXML = this.contains(produces, 'xml');\r
20214     isJSON = isXML ? this.contains(produces, 'json') : true;\r
20215 \r
20216     if (this.model.successResponse) {\r
20217       successResponse = this.model.successResponse;\r
20218       for (key in successResponse) {\r
20219         value = successResponse[key];\r
20220         this.model.successCode = key;\r
20221         if (typeof value === 'object' && typeof value.createJSONSample === 'function') {\r
20222           this.model.successDescription = value.description;\r
20223           this.model.headers = this.parseResponseHeaders(value.headers);\r
20224           signatureModel = {\r
20225             sampleJSON: isJSON ? JSON.stringify(SwaggerUi.partials.signature.createJSONSample(value), void 0, 2) : false,\r
20226             isParam: false,\r
20227             sampleXML: isXML ? SwaggerUi.partials.signature.createXMLSample(value.name, value.definition, value.models) : false,\r
20228             signature: SwaggerUi.partials.signature.getModelSignature(value.name, value.definition, value.models, value.modelPropertyMacro)\r
20229           };\r
20230         } else {\r
20231           signatureModel = {\r
20232             signature: SwaggerUi.partials.signature.getPrimitiveSignature(value)\r
20233           };\r
20234         }\r
20235       }\r
20236     } else if (this.model.responseClassSignature && this.model.responseClassSignature !== 'string') {\r
20237       signatureModel = {\r
20238         sampleJSON: this.model.responseSampleJSON,\r
20239         isParam: false,\r
20240         signature: this.model.responseClassSignature\r
20241       };\r
20242     }\r
20243     $(this.el).html(Handlebars.templates.operation(this.model));\r
20244     if (signatureModel) {\r
20245       signatureModel.defaultRendering = this.model.defaultRendering;\r
20246       responseSignatureView = new SwaggerUi.Views.SignatureView({\r
20247         model: signatureModel,\r
20248         router: this.router,\r
20249         tagName: 'div'\r
20250       });\r
20251       $('.model-signature', $(this.el)).append(responseSignatureView.render().el);\r
20252     } else {\r
20253       this.model.responseClassSignature = 'string';\r
20254       $('.model-signature', $(this.el)).html(this.model.type);\r
20255     }\r
20256     contentTypeModel = {\r
20257       isParam: false\r
20258     };\r
20259     contentTypeModel.consumes = this.model.consumes;\r
20260     contentTypeModel.produces = this.model.produces;\r
20261     ref3 = this.model.parameters;\r
20262     for (n = 0, len2 = ref3.length; n < len2; n++) {\r
20263       param = ref3[n];\r
20264       type = param.type || param.dataType || '';\r
20265       if (typeof type === 'undefined') {\r
20266         schema = param.schema;\r
20267         if (schema && schema.$ref) {\r
20268           ref = schema.$ref;\r
20269           if (ref.indexOf('#/definitions/') === 0) {\r
20270             type = ref.substring('#/definitions/'.length);\r
20271           } else {\r
20272             type = ref;\r
20273           }\r
20274         }\r
20275       }\r
20276       if (type && type.toLowerCase() === 'file') {\r
20277         if (!contentTypeModel.consumes) {\r
20278           contentTypeModel.consumes = 'multipart/form-data';\r
20279         }\r
20280       }\r
20281       param.type = type;\r
20282     }\r
20283     responseContentTypeView = new SwaggerUi.Views.ResponseContentTypeView({\r
20284       model: contentTypeModel,\r
20285       router: this.router\r
20286     });\r
20287     $('.response-content-type', $(this.el)).append(responseContentTypeView.render().el);\r
20288     ref4 = this.model.parameters;\r
20289     for (p = 0, len3 = ref4.length; p < len3; p++) {\r
20290       param = ref4[p];\r
20291       this.addParameter(param, contentTypeModel.consumes);\r
20292     }\r
20293     ref5 = this.model.responseMessages;\r
20294     for (q = 0, len4 = ref5.length; q < len4; q++) {\r
20295       statusCode = ref5[q];\r
20296       statusCode.isXML = isXML;\r
20297       statusCode.isJSON = isJSON;\r
20298       if (!_.isUndefined(statusCode.headers)) {\r
20299         statusCode.headers = this.parseHeadersType(statusCode.headers);\r
20300       }\r
20301       this.addStatusCode(statusCode);\r
20302     }\r
20303 \r
20304     if (Array.isArray(this.model.security)) {\r
20305       var authsModel = SwaggerUi.utils.parseSecurityDefinitions(this.model.security);\r
20306 \r
20307       authsModel.isLogout = !_.isEmpty(window.swaggerUi.api.clientAuthorizations.authz);\r
20308       this.authView = new SwaggerUi.Views.AuthButtonView({\r
20309         data: authsModel,\r
20310         router: this.router,\r
20311         isOperation: true,\r
20312         model: {\r
20313           scopes: authsModel.scopes\r
20314         }\r
20315       });\r
20316       this.$('.authorize-wrapper').append(this.authView.render().el);\r
20317     }\r
20318 \r
20319     this.showSnippet();\r
20320     return this;\r
20321   },\r
20322 \r
20323   parseHeadersType: function (headers) {\r
20324     var map = {\r
20325       'string': {\r
20326         'date-time': 'dateTime',\r
20327         'date'     : 'date'\r
20328       }\r
20329     };\r
20330 \r
20331     _.forEach(headers, function (header) {\r
20332       var value;\r
20333       header = header || {};\r
20334       value = map[header.type] && map[header.type][header.format];\r
20335       if (!_.isUndefined(value)) {\r
20336         header.type = value;\r
20337       }\r
20338     });\r
20339 \r
20340     return headers;\r
20341   },\r
20342 \r
20343   contains: function (produces, type) {\r
20344     return produces.filter(function (val) {\r
20345       if (val.indexOf(type) > -1) {\r
20346         return true;\r
20347       }\r
20348     }).length;\r
20349   },\r
20350 \r
20351   parseResponseHeaders: function (data) {\r
20352     var HEADERS_SEPARATOR = '; ';\r
20353     var headers = _.clone(data);\r
20354 \r
20355     _.forEach(headers, function (header) {\r
20356       var other = [];\r
20357       _.forEach(header, function (value, key) {\r
20358         var properties = ['type', 'description'];\r
20359         if (properties.indexOf(key.toLowerCase()) === -1) {\r
20360           other.push(key + ': ' + value);\r
20361         }\r
20362       });\r
20363 \r
20364       other.join(HEADERS_SEPARATOR);\r
20365       header.other = other;\r
20366     });\r
20367 \r
20368     return headers;\r
20369   },\r
20370 \r
20371   addParameter: function(param, consumes) {\r
20372     // Render a parameter\r
20373     param.consumes = consumes;\r
20374     param.defaultRendering = this.model.defaultRendering;\r
20375 \r
20376     // Copy this param JSON spec so that it will be available for JsonEditor\r
20377     if(param.schema){\r
20378       $.extend(true, param.schema, this.model.definitions[param.type]);\r
20379       param.schema.definitions = this.model.definitions;\r
20380       // This is required for JsonEditor to display the root properly\r
20381       if(!param.schema.type){\r
20382         param.schema.type = 'object';\r
20383       }\r
20384       // This is the title that will be used by JsonEditor for the root\r
20385       // Since we already display the parameter's name in the Parameter column\r
20386       // We set this to space, we can't set it to null or space otherwise JsonEditor\r
20387       // will replace it with the text "root" which won't look good on screen\r
20388       if(!param.schema.title){\r
20389         param.schema.title = ' ';\r
20390       }\r
20391     }\r
20392 \r
20393     var paramView = new SwaggerUi.Views.ParameterView({\r
20394       model: param,\r
20395       tagName: 'tr',\r
20396       readOnly: this.model.isReadOnly,\r
20397       swaggerOptions: this.options.swaggerOptions\r
20398     });\r
20399     $('.operation-params', $(this.el)).append(paramView.render().el);\r
20400   },\r
20401 \r
20402   addStatusCode: function(statusCode) {\r
20403     // Render status codes\r
20404     statusCode.defaultRendering = this.model.defaultRendering;\r
20405     var statusCodeView = new SwaggerUi.Views.StatusCodeView({\r
20406       model: statusCode,\r
20407       tagName: 'tr',\r
20408       router: this.router\r
20409     });\r
20410     $('.operation-status', $(this.el)).append(statusCodeView.render().el);\r
20411   },\r
20412 \r
20413   // Note: copied from CoffeeScript compiled file\r
20414   // TODO: redactor\r
20415   submitOperation: function(e) {\r
20416     var error_free, form, isFileUpload, map, opts;\r
20417     if (e !== null) {\r
20418       e.preventDefault();\r
20419     }\r
20420     form = $('.sandbox', $(this.el));\r
20421     error_free = true;\r
20422     form.find('input.required').each(function() {\r
20423       $(this).removeClass('error');\r
20424       if (jQuery.trim($(this).val()) === '') {\r
20425         $(this).addClass('error');\r
20426         $(this).wiggle({\r
20427           callback: (function(_this) {\r
20428             return function() {\r
20429               $(_this).focus();\r
20430             };\r
20431           })(this)\r
20432         });\r
20433         error_free = false;\r
20434       }\r
20435     });\r
20436     form.find('textarea.required:visible').each(function() {\r
20437       $(this).removeClass('error');\r
20438       if (jQuery.trim($(this).val()) === '') {\r
20439         $(this).addClass('error');\r
20440         $(this).wiggle({\r
20441           callback: (function(_this) {\r
20442             return function() {\r
20443               return $(_this).focus();\r
20444             };\r
20445           })(this)\r
20446         });\r
20447         error_free = false;\r
20448       }\r
20449     });\r
20450     form.find('select.required').each(function() {\r
20451       $(this).removeClass('error');\r
20452       if (this.selectedIndex === -1) {\r
20453         $(this).addClass('error');\r
20454         $(this).wiggle({\r
20455           callback: (function(_this) {\r
20456             return function() {\r
20457               $(_this).focus();\r
20458             };\r
20459           })(this)\r
20460         });\r
20461         error_free = false;\r
20462       }\r
20463     });\r
20464     if (error_free) {\r
20465       map = this.getInputMap(form);\r
20466       isFileUpload = this.isFileUpload(form);\r
20467       opts = {\r
20468         parent: this\r
20469       };\r
20470       if (this.options.swaggerOptions) {\r
20471         for(var key in this.options.swaggerOptions) {\r
20472           opts[key] = this.options.swaggerOptions[key];\r
20473         }\r
20474       }\r
20475 \r
20476       var pi;\r
20477       for(pi = 0; pi < this.model.parameters.length; pi++){\r
20478         var p = this.model.parameters[pi];\r
20479         if( p.jsonEditor && p.jsonEditor.isEnabled()){\r
20480           var json = p.jsonEditor.getValue();\r
20481           map[p.name] = JSON.stringify(json);\r
20482         }\r
20483       }\r
20484 \r
20485       opts.responseContentType = $('div select[name=responseContentType]', $(this.el)).val();\r
20486       opts.requestContentType = $('div select[name=parameterContentType]', $(this.el)).val();\r
20487       $('.response_throbber', $(this.el)).show();\r
20488       if (isFileUpload) {\r
20489         $('.request_url', $(this.el)).html('<pre></pre>');\r
20490         $('.request_url pre', $(this.el)).text(this.invocationUrl);\r
20491 \r
20492         opts.useJQuery = true;\r
20493         map.parameterContentType = 'multipart/form-data';\r
20494         this.map = map;\r
20495         return this.model.execute(map, opts, this.showCompleteStatus, this.showErrorStatus, this);\r
20496       } else {\r
20497         this.map = map;\r
20498         return this.model.execute(map, opts, this.showCompleteStatus, this.showErrorStatus, this);\r
20499       }\r
20500     }\r
20501   },\r
20502 \r
20503   getInputMap: function (form) {\r
20504     var map, ref1, l, len, o, ref2, m, len1, val, ref3, n, len2;\r
20505     map = {};\r
20506     ref1 = form.find('input');\r
20507     for (l = 0, len = ref1.length; l < len; l++) {\r
20508       o = ref1[l];\r
20509       if ((o.value !== null) && jQuery.trim(o.value).length > 0) {\r
20510         map[o.name] = o.value;\r
20511       }\r
20512       if (o.type === 'file') {\r
20513         map[o.name] = o.files[0];\r
20514       }\r
20515     }\r
20516     ref2 = form.find('textarea');\r
20517     for (m = 0, len1 = ref2.length; m < len1; m++) {\r
20518       o = ref2[m];\r
20519       val = this.getTextAreaValue(o);\r
20520       if ((val !== null) && jQuery.trim(val).length > 0) {\r
20521         map[o.name] = val;\r
20522       }\r
20523     }\r
20524     ref3 = form.find('select');\r
20525     for (n = 0, len2 = ref3.length; n < len2; n++) {\r
20526       o = ref3[n];\r
20527       val = this.getSelectedValue(o);\r
20528       if ((val !== null) && jQuery.trim(val).length > 0) {\r
20529         map[o.name] = val;\r
20530       }\r
20531     }\r
20532     return map;\r
20533   },\r
20534 \r
20535   isFileUpload: function (form) {\r
20536     var ref1, l, len, o;\r
20537     var isFileUpload = false;\r
20538     ref1 = form.find('input');\r
20539     for (l = 0, len = ref1.length; l < len; l++) {\r
20540       o = ref1[l];\r
20541       if (o.type === 'file') {\r
20542         isFileUpload = true;\r
20543       }\r
20544     }\r
20545     return isFileUpload;\r
20546   },\r
20547 \r
20548   success: function(response, parent) {\r
20549     parent.showCompleteStatus(response);\r
20550   },\r
20551 \r
20552   // wraps a jquery response as a shred response\r
20553   wrap: function(data) {\r
20554     var h, headerArray, headers, i, l, len, o;\r
20555     headers = {};\r
20556     headerArray = data.getAllResponseHeaders().split('\r');\r
20557     for (l = 0, len = headerArray.length; l < len; l++) {\r
20558       i = headerArray[l];\r
20559       h = i.match(/^([^:]*?):(.*)$/);\r
20560       if (!h) {\r
20561         h = [];\r
20562       }\r
20563       h.shift();\r
20564       if (h[0] !== void 0 && h[1] !== void 0) {\r
20565         headers[h[0].trim()] = h[1].trim();\r
20566       }\r
20567     }\r
20568     o = {};\r
20569     o.content = {};\r
20570     o.content.data = data.responseText;\r
20571     o.headers = headers;\r
20572     o.request = {};\r
20573     o.request.url = this.invocationUrl;\r
20574     o.status = data.status;\r
20575     return o;\r
20576   },\r
20577 \r
20578   getSelectedValue: function(select) {\r
20579     if (!select.multiple) {\r
20580       return select.value;\r
20581     } else {\r
20582       var options = [];\r
20583       for (var l = 0, len = select.options.length; l < len; l++) {\r
20584         var opt = select.options[l];\r
20585         if (opt.selected) {\r
20586           options.push(opt.value);\r
20587         }\r
20588       }\r
20589       if (options.length > 0) {\r
20590         return options;\r
20591       } else {\r
20592         return null;\r
20593       }\r
20594     }\r
20595   },\r
20596 \r
20597   // handler for hide response link\r
20598   hideResponse: function(e) {\r
20599     if (e) { e.preventDefault(); }\r
20600     $('.response', $(this.el)).slideUp();\r
20601     $('.response_hider', $(this.el)).fadeOut();\r
20602   },\r
20603 \r
20604   // Show response from server\r
20605   showResponse: function(response) {\r
20606     var prettyJson = JSON.stringify(response, null, '\t').replace(/\n/g, '<br>');\r
20607     $('.response_body', $(this.el)).html(_.escape(prettyJson));\r
20608   },\r
20609 \r
20610   // Show error from server\r
20611   showErrorStatus: function(data, parent) {\r
20612     parent.showStatus(data);\r
20613   },\r
20614 \r
20615   // show the status codes\r
20616   showCompleteStatus: function(data, parent){\r
20617     parent.showStatus(data);\r
20618   },\r
20619 \r
20620   // Adapted from http://stackoverflow.com/a/2893259/454004\r
20621   // Note: directly ported from CoffeeScript\r
20622   // TODO: Cleanup CoffeeScript artifacts\r
20623   formatXml: function(xml) {\r
20624     var contexp, fn, formatted, indent, l, lastType, len, lines, ln, pad, reg, transitions, wsexp;\r
20625     reg = /(>)(<)(\/*)/g;\r
20626     wsexp = /[ ]*(.*)[ ]+\n/g;\r
20627     contexp = /(<.+>)(.+\n)/g;\r
20628     xml = xml.replace(/\r\n/g, '\n').replace(reg, '$1\n$2$3').replace(wsexp, '$1\n').replace(contexp, '$1\n$2');\r
20629     pad = 0;\r
20630     formatted = '';\r
20631     lines = xml.split('\n');\r
20632     indent = 0;\r
20633     lastType = 'other';\r
20634     transitions = {\r
20635       'single->single': 0,\r
20636       'single->closing': -1,\r
20637       'single->opening': 0,\r
20638       'single->other': 0,\r
20639       'closing->single': 0,\r
20640       'closing->closing': -1,\r
20641       'closing->opening': 0,\r
20642       'closing->other': 0,\r
20643       'opening->single': 1,\r
20644       'opening->closing': 0,\r
20645       'opening->opening': 1,\r
20646       'opening->other': 1,\r
20647       'other->single': 0,\r
20648       'other->closing': -1,\r
20649       'other->opening': 0,\r
20650       'other->other': 0\r
20651     };\r
20652     fn = function(ln) {\r
20653       var fromTo, j, key, padding, type, types, value;\r
20654       types = {\r
20655         single: Boolean(ln.match(/<.+\/>/)),\r
20656         closing: Boolean(ln.match(/<\/.+>/)),\r
20657         opening: Boolean(ln.match(/<[^!?].*>/))\r
20658       };\r
20659       type = ((function() {\r
20660         var results;\r
20661         results = [];\r
20662         for (key in types) {\r
20663           value = types[key];\r
20664           if (value) {\r
20665             results.push(key);\r
20666           }\r
20667         }\r
20668         return results;\r
20669       })())[0];\r
20670       type = type === void 0 ? 'other' : type;\r
20671       fromTo = lastType + '->' + type;\r
20672       lastType = type;\r
20673       padding = '';\r
20674       indent += transitions[fromTo];\r
20675       padding = ((function() {\r
20676         var m, ref1, results;\r
20677         results = [];\r
20678         for (j = m = 0, ref1 = indent; 0 <= ref1 ? m < ref1 : m > ref1; j = 0 <= ref1 ? ++m : --m) {\r
20679           results.push('  ');\r
20680         }\r
20681         return results;\r
20682       })()).join('');\r
20683       if (fromTo === 'opening->closing') {\r
20684         formatted = formatted.substr(0, formatted.length - 1) + ln + '\n';\r
20685       } else {\r
20686         formatted += padding + ln + '\n';\r
20687       }\r
20688     };\r
20689     for (l = 0, len = lines.length; l < len; l++) {\r
20690       ln = lines[l];\r
20691       fn(ln);\r
20692     }\r
20693     return formatted;\r
20694   },\r
20695 \r
20696   // puts the response data in UI\r
20697   showStatus: function(response) {\r
20698     var url, content;\r
20699     if (response.content === undefined) {\r
20700       content = response.data;\r
20701       url = response.url;\r
20702     } else {\r
20703       content = response.content.data;\r
20704       url = response.request.url;\r
20705     }\r
20706     var headers = response.headers;\r
20707     content = jQuery.trim(content);\r
20708 \r
20709     // if server is nice, and sends content-type back, we can use it\r
20710     var contentType = null;\r
20711     if (headers) {\r
20712       contentType = headers['Content-Type'] || headers['content-type'];\r
20713       if (contentType) {\r
20714         contentType = contentType.split(';')[0].trim();\r
20715       }\r
20716     }\r
20717     $('.response_body', $(this.el)).removeClass('json');\r
20718     $('.response_body', $(this.el)).removeClass('xml');\r
20719 \r
20720     var supportsAudioPlayback = function(contentType){\r
20721       var audioElement = document.createElement('audio');\r
20722       return !!(audioElement.canPlayType && audioElement.canPlayType(contentType).replace(/no/, ''));\r
20723     };\r
20724 \r
20725     var pre;\r
20726     var code;\r
20727     if (!content) {\r
20728       code = $('<code />').text('no content');\r
20729       pre = $('<pre class="json" />').append(code);\r
20730 \r
20731       // JSON\r
20732     } else if (contentType === 'application/json' || /\+json$/.test(contentType)) {\r
20733       var json = null;\r
20734       try {\r
20735         json = JSON.stringify(JSON.parse(content), null, '  ');\r
20736       } catch (_error) {\r
20737         json = 'can\'t parse JSON.  Raw result:\n\n' + content;\r
20738       }\r
20739       code = $('<code />').text(json);\r
20740       pre = $('<pre class="json" />').append(code);\r
20741 \r
20742       // XML\r
20743     } else if (contentType === 'application/xml' || /\+xml$/.test(contentType)) {\r
20744       code = $('<code />').text(this.formatXml(content));\r
20745       pre = $('<pre class="xml" />').append(code);\r
20746 \r
20747       // HTML\r
20748     } else if (contentType === 'text/html') {\r
20749       code = $('<code />').html(_.escape(content));\r
20750       pre = $('<pre class="xml" />').append(code);\r
20751 \r
20752       // Plain Text\r
20753     } else if (/text\/plain/.test(contentType)) {\r
20754       code = $('<code />').text(content);\r
20755       pre = $('<pre class="plain" />').append(code);\r
20756 \r
20757 \r
20758       // Image\r
20759     } else if (/^image\//.test(contentType)) {\r
20760       pre = $('<img>').attr('src', url);\r
20761 \r
20762       // Audio\r
20763     } else if (/^audio\//.test(contentType) && supportsAudioPlayback(contentType)) {\r
20764       pre = $('<audio controls>').append($('<source>').attr('src', url).attr('type', contentType));\r
20765 \r
20766       // Download\r
20767     } else if (headers['Content-Disposition'] && (/attachment/).test(headers['Content-Disposition']) ||\r
20768         headers['content-disposition'] && (/attachment/).test(headers['content-disposition']) ||\r
20769         headers['Content-Description'] && (/File Transfer/).test(headers['Content-Description']) ||\r
20770         headers['content-description'] && (/File Transfer/).test(headers['content-description'])) {\r
20771 \r
20772       if ('Blob' in window) {\r
20773         var type = contentType || 'text/html';\r
20774         var blob = new Blob([content], {type: type});\r
20775         var a = document.createElement('a');\r
20776         var href = window.URL.createObjectURL(blob);\r
20777         var fileName = response.url.substr(response.url.lastIndexOf('/') + 1);\r
20778         var download = [type, fileName, href].join(':');\r
20779 \r
20780         // Use filename from response header\r
20781         var disposition = headers['content-disposition'] || headers['Content-Disposition'];\r
20782         if(typeof disposition !== 'undefined') {\r
20783           var responseFilename = /filename=([^;]*);?/.exec(disposition);\r
20784           if(responseFilename !== null && responseFilename.length > 1) {\r
20785             download = responseFilename[1];\r
20786           }\r
20787         }\r
20788 \r
20789         a.setAttribute('href', href);\r
20790         a.setAttribute('download', download);\r
20791         a.innerText = 'Download ' + fileName;\r
20792 \r
20793         pre = $('<div/>').append(a);\r
20794       } else {\r
20795         pre = $('<pre class="json" />').append('Download headers detected but your browser does not support downloading binary via XHR (Blob).');\r
20796       }\r
20797 \r
20798       // Location header based redirect download\r
20799     } else if(headers.location || headers.Location) {\r
20800       window.location = response.url;\r
20801 \r
20802       // Anything else (CORS)\r
20803     } else {\r
20804       code = $('<code />').text(content);\r
20805       pre = $('<pre class="json" />').append(code);\r
20806     }\r
20807     var response_body = pre;\r
20808     $('.request_url', $(this.el)).html('<pre></pre>');\r
20809     $('.request_url pre', $(this.el)).text(url);\r
20810     $('.response_code', $(this.el)).html('<pre>' + response.status + '</pre>');\r
20811     $('.response_body', $(this.el)).html(response_body);\r
20812     $('.response_headers', $(this.el)).html('<pre>' + _.escape(JSON.stringify(response.headers, null, '  ')).replace(/\n/g, '<br>') + '</pre>');\r
20813     $('.response', $(this.el)).slideDown();\r
20814     $('.response_hider', $(this.el)).show();\r
20815     $('.response_throbber', $(this.el)).hide();\r
20816 \r
20817 \r
20818     // adds curl output\r
20819     var curlCommand = this.model.asCurl(this.map, {responseContentType: contentType});\r
20820     curlCommand = curlCommand.replace('!', '&#33;');\r
20821     $( 'div.curl', $(this.el)).html('<pre>' + _.escape(curlCommand) + '</pre>');\r
20822 \r
20823     // only highlight the response if response is less than threshold, default state is highlight response\r
20824     var opts = this.options.swaggerOptions;\r
20825 \r
20826     if (opts.showRequestHeaders) {\r
20827       var form = $('.sandbox', $(this.el)),\r
20828           map = this.getInputMap(form),\r
20829           requestHeaders = this.model.getHeaderParams(map);\r
20830       delete requestHeaders['Content-Type'];\r
20831       $('.request_headers', $(this.el)).html('<pre>' + _.escape(JSON.stringify(requestHeaders, null, '  ')).replace(/\n/g, '<br>') + '</pre>');\r
20832     }\r
20833 \r
20834     var response_body_el = $('.response_body', $(this.el))[0];\r
20835     // only highlight the response if response is less than threshold, default state is highlight response\r
20836     if (opts.highlightSizeThreshold && typeof response.data !== 'undefined' && response.data.length > opts.highlightSizeThreshold) {\r
20837       return response_body_el;\r
20838     } else {\r
20839       return hljs.highlightBlock(response_body_el);\r
20840     }\r
20841   },\r
20842 \r
20843   toggleOperationContent: function (event) {\r
20844     var elem = $('#' + Docs.escapeResourceName(this.parentId + '_' + this.nickname + '_content'));\r
20845     if (elem.is(':visible')){\r
20846       $.bbq.pushState('#/', 2);\r
20847       event.preventDefault();\r
20848       Docs.collapseOperation(elem);\r
20849     } else {\r
20850       Docs.expandOperation(elem);\r
20851     }\r
20852   },\r
20853 \r
20854   getTextAreaValue: function(textArea) {\r
20855     var param, parsed, result, i;\r
20856     if (textArea.value === null || jQuery.trim(textArea.value).length === 0) {\r
20857       return null;\r
20858     }\r
20859     param = this.getParamByName(textArea.name);\r
20860     if (param && param.type && param.type.toLowerCase() === 'array') {\r
20861       parsed = textArea.value.split('\n');\r
20862       result = [];\r
20863       for (i = 0; i < parsed.length; i++) {\r
20864         if (parsed[i] !== null && jQuery.trim(parsed[i]).length > 0) {\r
20865           result.push(parsed[i]);\r
20866         }\r
20867       }\r
20868       return result.length > 0 ? result : null;\r
20869     } else {\r
20870       return textArea.value;\r
20871     }\r
20872   },\r
20873 \r
20874   showSnippet: function () {\r
20875     var contentTypeEl = this.$('[name=responseContentType]');\r
20876     var xmlSnippetEl = this.$('.operation-status .snippet_xml, .response-class .snippet_xml');\r
20877     var jsonSnippetEl = this.$('.operation-status .snippet_json, .response-class .snippet_json');\r
20878     var contentType;\r
20879 \r
20880     if (!contentTypeEl.length) { return; }\r
20881     contentType = contentTypeEl.val();\r
20882 \r
20883     if (contentType.indexOf('xml') > -1) {\r
20884       xmlSnippetEl.show();\r
20885       jsonSnippetEl.hide();\r
20886     } else {\r
20887       jsonSnippetEl.show();\r
20888       xmlSnippetEl.hide();\r
20889     }\r
20890   },\r
20891 \r
20892   getParamByName: function(name) {\r
20893     var i;\r
20894     if (this.model.parameters) {\r
20895       for(i = 0; i < this.model.parameters.length; i++) {\r
20896         if (this.model.parameters[i].name === name) {\r
20897           return this.model.parameters[i];\r
20898         }\r
20899       }\r
20900     }\r
20901     return null;\r
20902   }\r
20903 \r
20904 });\r
20905 \r
20906 'use strict';\r
20907 \r
20908 SwaggerUi.Views.ParameterContentTypeView = Backbone.View.extend({\r
20909   initialize: function  () {},\r
20910 \r
20911   render: function(){\r
20912     this.model.parameterContentTypeId = 'pct' + Math.random();\r
20913     $(this.el).html(Handlebars.templates.parameter_content_type(this.model));\r
20914     return this;\r
20915   }\r
20916 \r
20917 });\r
20918 'use strict';\r
20919 \r
20920 SwaggerUi.Views.ParameterView = Backbone.View.extend({\r
20921   events: {\r
20922     'change [name=parameterContentType]' : 'toggleParameterSnippet'\r
20923   },\r
20924 \r
20925   initialize: function(){\r
20926     Handlebars.registerHelper('isArray', function(param, opts) {\r
20927       var paramType = param.type && param.type.toLowerCase();\r
20928       if (paramType === 'array' || param.allowMultiple) {\r
20929         return opts.fn(this);\r
20930       } else {\r
20931         return opts.inverse(this);\r
20932       }\r
20933     });\r
20934   },\r
20935 \r
20936   render: function() {\r
20937     var type = this.model.type || this.model.dataType;\r
20938     var modelType = this.model.modelSignature.type;\r
20939     var modelDefinitions = this.model.modelSignature.definitions;\r
20940     var schema = this.model.schema || {};\r
20941     var consumes = this.model.consumes || [];\r
20942     var sampleJSON, signatureView;\r
20943 \r
20944 \r
20945     if (typeof type === 'undefined') {\r
20946       if (schema.$ref) {\r
20947         var ref = schema.$ref;\r
20948         if (ref.indexOf('#/definitions/') === 0) {\r
20949           type = ref.substring('#/definitions/'.length);\r
20950         } else {\r
20951           type = ref;\r
20952         }\r
20953       }\r
20954     }\r
20955 \r
20956     this.model.type = type;\r
20957     this.model.paramType = this.model.in || this.model.paramType;\r
20958     this.model.isBody = this.model.paramType === 'body' || this.model.in === 'body';\r
20959     this.model.isFile = type && type.toLowerCase() === 'file';\r
20960 \r
20961     // Allow for default === false\r
20962     if(typeof this.model.default === 'undefined') {\r
20963       this.model.default = this.model.defaultValue;\r
20964     }\r
20965 \r
20966     this.model.hasDefault = (typeof this.model.default !== 'undefined');\r
20967     this.model.valueId = 'm' + this.model.name + Math.random();\r
20968 \r
20969     if (this.model.allowableValues) {\r
20970       this.model.isList = true;\r
20971     }\r
20972 \r
20973     var isXML = this.contains(consumes, 'xml');\r
20974     var isJSON = isXML ? this.contains(consumes, 'json') : true;\r
20975     sampleJSON = SwaggerUi.partials.signature.createParameterJSONSample(modelType, modelDefinitions);\r
20976 \r
20977     var template = this.template();\r
20978     $(this.el).html(template(this.model));\r
20979 \r
20980     var signatureModel = {\r
20981       sampleJSON: isJSON ? sampleJSON : false,\r
20982       sampleXML: sampleJSON && isXML ? SwaggerUi.partials.signature.createXMLSample('', schema, modelDefinitions, true) : false,\r
20983       isParam: true,\r
20984       signature: SwaggerUi.partials.signature.getParameterModelSignature(modelType, modelDefinitions),\r
20985       defaultRendering: this.model.defaultRendering\r
20986     };\r
20987 \r
20988     if (sampleJSON) {\r
20989       signatureView = new SwaggerUi.Views.SignatureView({model: signatureModel, tagName: 'div'});\r
20990       $('.model-signature', $(this.el)).append(signatureView.render().el);\r
20991     }\r
20992     else {\r
20993       $('.model-signature', $(this.el)).html(this.model.signature);\r
20994     }\r
20995 \r
20996     var isParam = false;\r
20997 \r
20998     if( this.options.swaggerOptions.jsonEditor && this.model.isBody && this.model.schema){\r
20999       var $self = $(this.el);\r
21000       this.model.jsonEditor =\r
21001         /* global JSONEditor */\r
21002         new JSONEditor($('.editor_holder', $self)[0],\r
21003                        {schema: this.model.schema, startval : this.model.default,\r
21004                         ajax:true,\r
21005                         disable_properties:true,\r
21006                         disable_edit_json:true,\r
21007                         iconlib: 'swagger' });\r
21008       // This is so that the signature can send back the sample to the json editor\r
21009       // TODO: SignatureView should expose an event "onSampleClicked" instead\r
21010       signatureModel.jsonEditor = this.model.jsonEditor;\r
21011       $('.body-textarea', $self).hide();\r
21012       $('.editor_holder', $self).show();\r
21013       $('.parameter-content-type', $self)\r
21014         .change(function(e){\r
21015             if(e.target.value === 'application/xml'){\r
21016               $('.body-textarea', $self).show();\r
21017               $('.editor_holder', $self).hide();\r
21018               this.model.jsonEditor.disable();\r
21019             }\r
21020             else {\r
21021               $('.body-textarea', $self).hide();\r
21022               $('.editor_holder', $self).show();\r
21023               this.model.jsonEditor.enable();\r
21024             }\r
21025         });\r
21026       }\r
21027 \r
21028 \r
21029     if (this.model.isBody) {\r
21030       isParam = true;\r
21031     }\r
21032 \r
21033     var contentTypeModel = {\r
21034       isParam: isParam\r
21035     };\r
21036 \r
21037     contentTypeModel.consumes = this.model.consumes;\r
21038 \r
21039     if (isParam) {\r
21040       var parameterContentTypeView = new SwaggerUi.Views.ParameterContentTypeView({model: contentTypeModel});\r
21041       $('.parameter-content-type', $(this.el)).append(parameterContentTypeView.render().el);\r
21042       this.toggleParameterSnippet();\r
21043     }\r
21044 \r
21045     else {\r
21046       var responseContentTypeView = new SwaggerUi.Views.ResponseContentTypeView({model: contentTypeModel});\r
21047       $('.response-content-type', $(this.el)).append(responseContentTypeView.render().el);\r
21048       this.toggleResponseSnippet();\r
21049     }\r
21050 \r
21051     return this;\r
21052   },\r
21053 \r
21054   contains: function (consumes, type) {\r
21055     return consumes.filter(function (val) {\r
21056       if (val.indexOf(type) > -1) {\r
21057         return true;\r
21058       }\r
21059     }).length;\r
21060   },\r
21061 \r
21062   toggleParameterSnippet: function () {\r
21063     var contentType = this.$('[name=parameterContentType]').val();\r
21064 \r
21065     this.toggleSnippet(contentType);\r
21066   },\r
21067 \r
21068   toggleResponseSnippet: function () {\r
21069     var contentEl = this.$('[name=responseContentType]');\r
21070 \r
21071     if (!contentEl.length) { return; }\r
21072 \r
21073     this.toggleSnippet(contentEl.val());\r
21074   },\r
21075 \r
21076   toggleSnippet: function (type) {\r
21077     type = type || '';\r
21078     if (type.indexOf('xml') > -1) {\r
21079       this.$('.snippet_xml').show();\r
21080       this.$('.snippet_json').hide();\r
21081     } else {\r
21082       this.$('.snippet_json').show();\r
21083       this.$('.snippet_xml').hide();\r
21084     }\r
21085   },\r
21086 \r
21087   // Return an appropriate template based on if the parameter is a list, readonly, required\r
21088   template: function(){\r
21089     if (this.model.isList) {\r
21090       return Handlebars.templates.param_list;\r
21091     } else {\r
21092       if (this.options.readOnly) {\r
21093         if (this.model.required) {\r
21094           return Handlebars.templates.param_readonly_required;\r
21095         } else {\r
21096           return Handlebars.templates.param_readonly;\r
21097         }\r
21098       } else {\r
21099         if (this.model.required) {\r
21100           return Handlebars.templates.param_required;\r
21101         } else {\r
21102           return Handlebars.templates.param;\r
21103         }\r
21104       }\r
21105     }\r
21106   }\r
21107 });\r
21108 \r
21109 'use strict';\r
21110 \r
21111 /* jshint -W122 */\r
21112 SwaggerUi.partials.signature = (function () {\r
21113   // copy-pasted from swagger-js\r
21114   var resolveSchema = function (schema) {\r
21115     if (_.isPlainObject(schema.schema)) {\r
21116       schema = resolveSchema(schema.schema);\r
21117     }\r
21118 \r
21119     return schema;\r
21120   };\r
21121 \r
21122   // copy-pasted from swagger-js\r
21123   var simpleRef = function (name) {\r
21124     if (typeof name === 'undefined') {\r
21125       return null;\r
21126     }\r
21127 \r
21128     if (name.indexOf('#/definitions/') === 0) {\r
21129       return name.substring('#/definitions/'.length);\r
21130     } else {\r
21131       return name;\r
21132     }\r
21133   };\r
21134 \r
21135   // copy-pasted from swagger-js\r
21136   var getInlineModel = function(inlineStr) {\r
21137     if(/^Inline Model \d+$/.test(inlineStr) && this.inlineModels) {\r
21138       var id = parseInt(inlineStr.substr('Inline Model'.length).trim(),10); //\r
21139       var model = this.inlineModels[id];\r
21140       return model;\r
21141     }\r
21142     // I'm returning null here, should I rather throw an error?\r
21143     return null;\r
21144   };\r
21145 \r
21146   // copy-pasted from swagger-js\r
21147   var formatXml = function(xml) {\r
21148     var contexp, fn, formatted, indent, l, lastType, len, lines, ln, pad, reg, transitions, wsexp;\r
21149     reg = /(>)(<)(\/*)/g;\r
21150     wsexp = /[ ]*(.*)[ ]+\n/g;\r
21151     contexp = /(<.+>)(.+\n)/g;\r
21152     xml = xml.replace(reg, '$1\n$2$3').replace(wsexp, '$1\n').replace(contexp, '$1\n$2');\r
21153     pad = 0;\r
21154     formatted = '';\r
21155     lines = xml.split('\n');\r
21156     indent = 0;\r
21157     lastType = 'other';\r
21158     transitions = {\r
21159       'single->single': 0,\r
21160       'single->closing': -1,\r
21161       'single->opening': 0,\r
21162       'single->other': 0,\r
21163       'closing->single': 0,\r
21164       'closing->closing': -1,\r
21165       'closing->opening': 0,\r
21166       'closing->other': 0,\r
21167       'opening->single': 1,\r
21168       'opening->closing': 0,\r
21169       'opening->opening': 1,\r
21170       'opening->other': 1,\r
21171       'other->single': 0,\r
21172       'other->closing': -1,\r
21173       'other->opening': 0,\r
21174       'other->other': 0\r
21175     };\r
21176     fn = function(ln) {\r
21177       var fromTo, j, key, padding, type, types, value;\r
21178       types = {\r
21179         single: Boolean(ln.match(/<.+\/>/)),\r
21180         closing: Boolean(ln.match(/<\/.+>/)),\r
21181         opening: Boolean(ln.match(/<[^!?].*>/))\r
21182       };\r
21183       type = ((function() {\r
21184         var results;\r
21185         results = [];\r
21186         for (key in types) {\r
21187           value = types[key];\r
21188           if (value) {\r
21189             results.push(key);\r
21190           }\r
21191         }\r
21192         return results;\r
21193       })())[0];\r
21194       type = type === void 0 ? 'other' : type;\r
21195       fromTo = lastType + '->' + type;\r
21196       lastType = type;\r
21197       padding = '';\r
21198       indent += transitions[fromTo];\r
21199       padding = ((function() {\r
21200         var m, ref1, results;\r
21201         results = [];\r
21202         for (j = m = 0, ref1 = indent; 0 <= ref1 ? m < ref1 : m > ref1; j = 0 <= ref1 ? ++m : --m) {\r
21203           results.push('  ');\r
21204         }\r
21205         return results;\r
21206       })()).join('');\r
21207       if (fromTo === 'opening->closing') {\r
21208         formatted = formatted.substr(0, formatted.length - 1) + ln + '\n';\r
21209       } else {\r
21210         formatted += padding + ln + '\n';\r
21211       }\r
21212     };\r
21213     for (l = 0, len = lines.length; l < len; l++) {\r
21214       ln = lines[l];\r
21215       fn(ln);\r
21216     }\r
21217     return formatted;\r
21218   };\r
21219 \r
21220   // copy-pasted from swagger-js\r
21221   var getModelSignature = function (name, schema, models, modelPropertyMacro) {\r
21222     var strongOpen = '<span class="strong">';\r
21223     var strongClose = '</span>';\r
21224 \r
21225     var optionHtml = function (label, value) {\r
21226       return '<tr><td class="optionName">' + label + ':</td><td>' + value + '</td></tr>';\r
21227     };\r
21228 \r
21229 \r
21230     // Allow for ignoring the 'name' argument.... shifting the rest\r
21231     if(_.isObject(arguments[0])) {\r
21232       name = void 0;\r
21233       schema = arguments[0];\r
21234       models = arguments[1];\r
21235       modelPropertyMacro = arguments[2];\r
21236     }\r
21237 \r
21238     models = models || {};\r
21239 \r
21240     // Resolve the schema (Handle nested schemas)\r
21241     schema = resolveSchema(schema);\r
21242 \r
21243     // Return for empty object\r
21244     if(_.isEmpty(schema)) {\r
21245       return strongOpen + 'Empty' + strongClose;\r
21246     }\r
21247 \r
21248     // Dereference $ref from 'models'\r
21249     if(typeof schema.$ref === 'string') {\r
21250       name = simpleRef(schema.$ref);\r
21251       schema = models[name];\r
21252       if(typeof schema === 'undefined')\r
21253       {\r
21254         return strongOpen + name + ' is not defined!' + strongClose;\r
21255       }\r
21256     }\r
21257 \r
21258     if(typeof name !== 'string') {\r
21259       name = schema.title || 'Inline Model';\r
21260     }\r
21261 \r
21262     // If we are a Model object... adjust accordingly\r
21263     if(schema.definition) {\r
21264       schema = schema.definition;\r
21265     }\r
21266 \r
21267     if(typeof modelPropertyMacro !== 'function') {\r
21268       modelPropertyMacro = function(prop){\r
21269         return (prop || {}).default;\r
21270       };\r
21271     }\r
21272 \r
21273     var references = {};\r
21274     var seenModels = [];\r
21275     var inlineModels = 0;\r
21276 \r
21277     // Generate current HTML\r
21278     var html = processModel(schema, name);\r
21279 \r
21280     // Generate references HTML\r
21281     while (_.keys(references).length > 0) {\r
21282       /* jshint ignore:start */\r
21283       _.forEach(references, function (schema, name) {\r
21284         var seenModel = _.indexOf(seenModels, name) > -1;\r
21285 \r
21286         delete references[name];\r
21287 \r
21288         if (!seenModel) {\r
21289           seenModels.push(name);\r
21290 \r
21291           html += '<br />' + processModel(schema, name);\r
21292         }\r
21293       });\r
21294       /* jshint ignore:end */\r
21295     }\r
21296 \r
21297     return html;\r
21298 \r
21299 \r
21300     function addReference(schema, name, skipRef) {\r
21301       var modelName = name;\r
21302       var model;\r
21303 \r
21304       if (schema.$ref) {\r
21305         modelName = schema.title || simpleRef(schema.$ref);\r
21306         model = models[simpleRef(schema.$ref)];\r
21307       } else if (_.isUndefined(name)) {\r
21308         modelName = schema.title || 'Inline Model ' + (++inlineModels);\r
21309         model = {definition: schema};\r
21310       }\r
21311 \r
21312       if (skipRef !== true) {\r
21313         references[modelName] = _.isUndefined(model) ? {} : model.definition;\r
21314       }\r
21315 \r
21316       return modelName;\r
21317     }\r
21318 \r
21319     function primitiveToHTML(schema) {\r
21320       var html = '<span class="propType">';\r
21321       var type = schema.type || 'object';\r
21322 \r
21323       if (schema.$ref) {\r
21324         html += addReference(schema, simpleRef(schema.$ref));\r
21325       } else if (type === 'object') {\r
21326         if (!_.isUndefined(schema.properties)) {\r
21327           html += addReference(schema);\r
21328         } else {\r
21329           html += 'object';\r
21330         }\r
21331       } else if (type === 'array') {\r
21332         html += 'Array[';\r
21333 \r
21334         if (_.isArray(schema.items)) {\r
21335           html += _.map(schema.items, addReference).join(',');\r
21336         } else if (_.isPlainObject(schema.items)) {\r
21337           if (_.isUndefined(schema.items.$ref)) {\r
21338             if (!_.isUndefined(schema.items.type) && _.indexOf(['array', 'object'], schema.items.type) === -1) {\r
21339               html += schema.items.type;\r
21340             } else {\r
21341               html += addReference(schema.items);\r
21342             }\r
21343           } else {\r
21344             html += addReference(schema.items, simpleRef(schema.items.$ref));\r
21345           }\r
21346         } else {\r
21347           console.log('Array type\'s \'items\' schema is not an array or an object, cannot process');\r
21348           html += 'object';\r
21349         }\r
21350 \r
21351         html += ']';\r
21352       } else {\r
21353         html += schema.type;\r
21354       }\r
21355 \r
21356       html += '</span>';\r
21357 \r
21358       return html;\r
21359     }\r
21360 \r
21361     function primitiveToOptionsHTML(schema, html) {\r
21362       var options = '';\r
21363       var type = schema.type || 'object';\r
21364       var isArray = type === 'array';\r
21365 \r
21366       if (isArray) {\r
21367         if (_.isPlainObject(schema.items) && !_.isUndefined(schema.items.type)) {\r
21368           type = schema.items.type;\r
21369         } else {\r
21370           type = 'object';\r
21371         }\r
21372       }\r
21373 \r
21374       if (!_.isUndefined(schema.default)) {\r
21375         options += optionHtml('Default', schema.default);\r
21376       }\r
21377 \r
21378       switch (type) {\r
21379       case 'string':\r
21380         if (schema.minLength) {\r
21381           options += optionHtml('Min. Length', schema.minLength);\r
21382         }\r
21383 \r
21384         if (schema.maxLength) {\r
21385           options += optionHtml('Max. Length', schema.maxLength);\r
21386         }\r
21387 \r
21388         if (schema.pattern) {\r
21389           options += optionHtml('Reg. Exp.', schema.pattern);\r
21390         }\r
21391         break;\r
21392       case 'integer':\r
21393       case 'number':\r
21394         if (schema.minimum) {\r
21395           options += optionHtml('Min. Value', schema.minimum);\r
21396         }\r
21397 \r
21398         if (schema.exclusiveMinimum) {\r
21399           options += optionHtml('Exclusive Min.', 'true');\r
21400         }\r
21401 \r
21402         if (schema.maximum) {\r
21403           options += optionHtml('Max. Value', schema.maximum);\r
21404         }\r
21405 \r
21406         if (schema.exclusiveMaximum) {\r
21407           options += optionHtml('Exclusive Max.', 'true');\r
21408         }\r
21409 \r
21410         if (schema.multipleOf) {\r
21411           options += optionHtml('Multiple Of', schema.multipleOf);\r
21412         }\r
21413 \r
21414         break;\r
21415       }\r
21416 \r
21417       if (isArray) {\r
21418         if (schema.minItems) {\r
21419           options += optionHtml('Min. Items', schema.minItems);\r
21420         }\r
21421 \r
21422         if (schema.maxItems) {\r
21423           options += optionHtml('Max. Items', schema.maxItems);\r
21424         }\r
21425 \r
21426         if (schema.uniqueItems) {\r
21427           options += optionHtml('Unique Items', 'true');\r
21428         }\r
21429 \r
21430         if (schema.collectionFormat) {\r
21431           options += optionHtml('Coll. Format', schema.collectionFormat);\r
21432         }\r
21433       }\r
21434 \r
21435       if (_.isUndefined(schema.items)) {\r
21436         if (_.isArray(schema.enum)) {\r
21437           var enumString;\r
21438 \r
21439           if (type === 'number' || type === 'integer') {\r
21440             enumString = schema.enum.join(', ');\r
21441           } else {\r
21442             enumString = '"' + schema.enum.join('", "') + '"';\r
21443           }\r
21444 \r
21445           options += optionHtml('Enum', enumString);\r
21446         }\r
21447       }\r
21448 \r
21449       if (options.length > 0) {\r
21450         html = '<span class="propWrap">' + html + '<table class="optionsWrapper"><tr><th colspan="2">' + type + '</th></tr>' + options + '</table></span>';\r
21451       }\r
21452 \r
21453       return html;\r
21454     }\r
21455 \r
21456     function processModel(schema, name) {\r
21457       var type = schema.type || 'object';\r
21458       var isArray = schema.type === 'array';\r
21459       var html = strongOpen + name + ' ' + (isArray ? '[' : '{') + strongClose;\r
21460       var contents;\r
21461 \r
21462       if (name) {\r
21463         seenModels.push(name);\r
21464       }\r
21465 \r
21466       if (isArray) {\r
21467         if (_.isArray(schema.items)) {\r
21468           html += '<div>' + _.map(schema.items, function (item) {\r
21469             var type = item.type || 'object';\r
21470 \r
21471             if (_.isUndefined(item.$ref)) {\r
21472               if (_.indexOf(['array', 'object'], type) > -1) {\r
21473                 if (type === 'object' && _.isUndefined(item.properties)) {\r
21474                   return 'object';\r
21475                 } else {\r
21476                   return addReference(item);\r
21477                 }\r
21478               } else {\r
21479                 return primitiveToOptionsHTML(item, type);\r
21480               }\r
21481             } else {\r
21482               return addReference(item, simpleRef(item.$ref));\r
21483             }\r
21484           }).join(',</div><div>');\r
21485         } else if (_.isPlainObject(schema.items)) {\r
21486           if (_.isUndefined(schema.items.$ref)) {\r
21487             if (_.indexOf(['array', 'object'], schema.items.type || 'object') > -1) {\r
21488               if ((_.isUndefined(schema.items.type) || schema.items.type === 'object') && _.isUndefined(schema.items.properties)) {\r
21489                 html += '<div>object</div>';\r
21490               } else {\r
21491                 html += '<div>' + addReference(schema.items) + '</div>';\r
21492               }\r
21493             } else {\r
21494               html += '<div>' + primitiveToOptionsHTML(schema.items, schema.items.type) + '</div>';\r
21495             }\r
21496           } else {\r
21497             html += '<div>' + addReference(schema.items, simpleRef(schema.items.$ref)) + '</div>';\r
21498           }\r
21499         } else {\r
21500           console.log('Array type\'s \'items\' property is not an array or an object, cannot process');\r
21501           html += '<div>object</div>';\r
21502         }\r
21503       } else {\r
21504         if (schema.$ref) {\r
21505           html += '<div>' + addReference(schema, name) + '</div>';\r
21506         } else if (type === 'object') {\r
21507           if (_.isPlainObject(schema.properties)) {\r
21508             contents = _.map(schema.properties, function (property, name) {\r
21509               var propertyIsRequired = (_.indexOf(schema.required, name) >= 0);\r
21510               var cProperty = _.cloneDeep(property);\r
21511 \r
21512               var requiredClass = propertyIsRequired ? 'required' : '';\r
21513               var html = '<span class="propName ' + requiredClass + '">' + name + '</span> (';\r
21514               var model;\r
21515               var propDescription;\r
21516 \r
21517               // Allow macro to set the default value\r
21518               cProperty.default = modelPropertyMacro(cProperty);\r
21519 \r
21520               // Resolve the schema (Handle nested schemas)\r
21521               cProperty = resolveSchema(cProperty);\r
21522 \r
21523               propDescription = property.description || cProperty.description;\r
21524 \r
21525               // We need to handle property references to primitives (Issue 339)\r
21526               if (!_.isUndefined(cProperty.$ref)) {\r
21527                 model = models[simpleRef(cProperty.$ref)];\r
21528 \r
21529                 if (!_.isUndefined(model) && _.indexOf([undefined, 'array', 'object'], model.definition.type) === -1) {\r
21530                   // Use referenced schema\r
21531                   cProperty = resolveSchema(model.definition);\r
21532                 }\r
21533               }\r
21534 \r
21535               html += primitiveToHTML(cProperty);\r
21536 \r
21537               if(!propertyIsRequired) {\r
21538                 html += ', <span class="propOptKey">optional</span>';\r
21539               }\r
21540 \r
21541               if(property.readOnly) {\r
21542                   html += ', <span class="propReadOnly">read only</span>';\r
21543               }\r
21544 \r
21545               html += ')';\r
21546 \r
21547               if (!_.isUndefined(propDescription)) {\r
21548                 html += ': ' + '<span class="propDesc">' + propDescription + '</span>';\r
21549               }\r
21550 \r
21551               if (cProperty.enum) {\r
21552                 html += ' = <span class="propVals">[\'' + cProperty.enum.join('\', \'') + '\']</span>';\r
21553               }\r
21554 \r
21555               return '<div' + (property.readOnly ? ' class="readOnly"' : '') + '>' + primitiveToOptionsHTML(cProperty, html);\r
21556             }).join(',</div>');\r
21557           }\r
21558 \r
21559           if (contents) {\r
21560             html += contents + '</div>';\r
21561           }\r
21562         } else {\r
21563           html += '<div>' + primitiveToOptionsHTML(schema, type) + '</div>';\r
21564         }\r
21565       }\r
21566 \r
21567       return html + strongOpen + (isArray ? ']' : '}') + strongClose;\r
21568     }\r
21569 \r
21570   };\r
21571 \r
21572   // copy-pasted from swagger-js\r
21573   var schemaToJSON = function (schema, models, modelsToIgnore, modelPropertyMacro) {\r
21574     // Resolve the schema (Handle nested schemas)\r
21575     schema = resolveSchema(schema);\r
21576 \r
21577     if(typeof modelPropertyMacro !== 'function') {\r
21578       modelPropertyMacro = function(prop){\r
21579         return (prop || {}).default;\r
21580       };\r
21581     }\r
21582 \r
21583     modelsToIgnore= modelsToIgnore || {};\r
21584 \r
21585     var type = schema.type || 'object';\r
21586     var format = schema.format;\r
21587     var model;\r
21588     var output;\r
21589 \r
21590     if (!_.isUndefined(schema.example)) {\r
21591       output = schema.example;\r
21592     } else if (_.isUndefined(schema.items) && _.isArray(schema.enum)) {\r
21593       output = schema.enum[0];\r
21594     }\r
21595 \r
21596     if (_.isUndefined(output)) {\r
21597       if (schema.$ref) {\r
21598         model = models[simpleRef(schema.$ref)];\r
21599 \r
21600         if (!_.isUndefined(model)) {\r
21601           if (_.isUndefined(modelsToIgnore[model.name])) {\r
21602             modelsToIgnore[model.name] = model;\r
21603             output = schemaToJSON(model.definition, models, modelsToIgnore, modelPropertyMacro);\r
21604             delete modelsToIgnore[model.name];\r
21605           } else {\r
21606             if (model.type === 'array') {\r
21607               output = [];\r
21608             } else {\r
21609               output = {};\r
21610             }\r
21611           }\r
21612         }\r
21613       } else if (!_.isUndefined(schema.default)) {\r
21614         output = schema.default;\r
21615       } else if (type === 'string') {\r
21616         if (format === 'date-time') {\r
21617           output = new Date().toISOString();\r
21618         } else if (format === 'date') {\r
21619           output = new Date().toISOString().split('T')[0];\r
21620         } else {\r
21621           output = 'string';\r
21622         }\r
21623       } else if (type === 'integer') {\r
21624         output = 0;\r
21625       } else if (type === 'number') {\r
21626         output = 0.0;\r
21627       } else if (type === 'boolean') {\r
21628         output = true;\r
21629       } else if (type === 'object') {\r
21630         output = {};\r
21631 \r
21632         _.forEach(schema.properties, function (property, name) {\r
21633           var cProperty = _.cloneDeep(property);\r
21634 \r
21635           // Allow macro to set the default value\r
21636           cProperty.default = modelPropertyMacro(property);\r
21637 \r
21638           output[name] = schemaToJSON(cProperty, models, modelsToIgnore, modelPropertyMacro);\r
21639         });\r
21640       } else if (type === 'array') {\r
21641         output = [];\r
21642 \r
21643         if (_.isArray(schema.items)) {\r
21644           _.forEach(schema.items, function (item) {\r
21645             output.push(schemaToJSON(item, models, modelsToIgnore, modelPropertyMacro));\r
21646           });\r
21647         } else if (_.isPlainObject(schema.items)) {\r
21648           output.push(schemaToJSON(schema.items, models, modelsToIgnore, modelPropertyMacro));\r
21649         } else if (_.isUndefined(schema.items)) {\r
21650           output.push({});\r
21651         } else {\r
21652           console.log('Array type\'s \'items\' property is not an array or an object, cannot process');\r
21653         }\r
21654       }\r
21655     }\r
21656 \r
21657     return output;\r
21658   };\r
21659 \r
21660   // copy-pasted from swagger-js\r
21661   var createJSONSample = function (value, modelsToIgnore) {\r
21662     modelsToIgnore = modelsToIgnore || {};\r
21663 \r
21664     modelsToIgnore[value.name] = value;\r
21665 \r
21666     // Response support\r
21667     if (value.examples && _.isPlainObject(value.examples) && value.examples['application/json']) {\r
21668       value.definition.example = value.examples['application/json'];\r
21669 \r
21670       if (_.isString(value.definition.example)) {\r
21671         value.definition.example = jsyaml.safeLoad(value.definition.example);\r
21672       }\r
21673     } else if (!value.definition.example) {\r
21674       value.definition.example = value.examples;\r
21675     }\r
21676 \r
21677     return schemaToJSON(value.definition, value.models, modelsToIgnore, value.modelPropertyMacro);\r
21678   };\r
21679 \r
21680   // copy-pasted from swagger-js\r
21681   var getParameterModelSignature = function (type, definitions) {\r
21682       var isPrimitive, listType;\r
21683 \r
21684       if (type instanceof Array) {\r
21685         listType = true;\r
21686         type = type[0];\r
21687       }\r
21688 \r
21689       // Convert undefined to string of 'undefined'\r
21690       if (typeof type === 'undefined') {\r
21691         type = 'undefined';\r
21692         isPrimitive = true;\r
21693 \r
21694       } else if (definitions[type]){\r
21695         // a model def exists?\r
21696         type = definitions[type]; /* Model */\r
21697         isPrimitive = false;\r
21698 \r
21699       } else if (getInlineModel(type)) {\r
21700         type = getInlineModel(type); /* Model */\r
21701         isPrimitive = false;\r
21702 \r
21703       } else {\r
21704         // We default to primitive\r
21705         isPrimitive = true;\r
21706       }\r
21707 \r
21708       if (isPrimitive) {\r
21709         if (listType) {\r
21710           return 'Array[' + type + ']';\r
21711         } else {\r
21712           return type.toString();\r
21713         }\r
21714       } else {\r
21715         if (listType) {\r
21716           return 'Array[' + getModelSignature(type.name, type.definition, type.models, type.modelPropertyMacro) + ']';\r
21717         } else {\r
21718           return getModelSignature(type.name, type.definition, type.models, type.modelPropertyMacro);\r
21719         }\r
21720       }\r
21721   };\r
21722 \r
21723   // copy-pasted from swagger-js\r
21724   var createParameterJSONSample = function (type, models) {\r
21725     var listType, sampleJson, innerType;\r
21726     models = models || {};\r
21727 \r
21728     listType = (type instanceof Array);\r
21729     innerType = listType ? type[0] : type;\r
21730 \r
21731     if(models[innerType]) {\r
21732       sampleJson = createJSONSample(models[innerType]);\r
21733     } else if (getInlineModel(innerType)){\r
21734       sampleJson = createJSONSample(getInlineModel(innerType)); // may return null, if type isn't correct\r
21735     }\r
21736 \r
21737 \r
21738     if (sampleJson) {\r
21739       sampleJson = listType ? [sampleJson] : sampleJson;\r
21740 \r
21741       if (typeof sampleJson === 'string') {\r
21742         return sampleJson;\r
21743       } else if (_.isObject(sampleJson)) {\r
21744         var t = sampleJson;\r
21745 \r
21746         if (sampleJson instanceof Array && sampleJson.length > 0) {\r
21747           t = sampleJson[0];\r
21748         }\r
21749 \r
21750         if (t.nodeName && typeof t === 'Node') {\r
21751           var xmlString = new XMLSerializer().serializeToString(t);\r
21752 \r
21753           return formatXml(xmlString);\r
21754         } else {\r
21755           return JSON.stringify(sampleJson, null, 2);\r
21756         }\r
21757       } else {\r
21758         return sampleJson;\r
21759       }\r
21760     }\r
21761   };\r
21762 \r
21763   var wrapTag = function (name, value, attrs) {\r
21764     var str, attributes;\r
21765 \r
21766     attrs = attrs || [];\r
21767 \r
21768     attributes = attrs.map(function (attr) {\r
21769       return ' ' + attr.name + '="' + attr.value + '"';\r
21770     }).join('');\r
21771 \r
21772     if (!name) {\r
21773       return getErrorMessage('Node name is not provided');\r
21774     }\r
21775 \r
21776     str = [\r
21777       '<', name,\r
21778       attributes,\r
21779       '>',\r
21780       value,\r
21781       '</', name, '>'\r
21782     ];\r
21783 \r
21784     return str.join('');\r
21785   };\r
21786 \r
21787   var getName = function (name, xml) {\r
21788     var result = name || '';\r
21789 \r
21790     xml = xml || {};\r
21791 \r
21792     if (xml.name) {\r
21793       result = xml.name;\r
21794     }\r
21795 \r
21796     if (xml.prefix) {\r
21797       result = xml.prefix + ':' + result;\r
21798     }\r
21799 \r
21800     return result;\r
21801   };\r
21802 \r
21803   var getNamespace = function (xml) {\r
21804     var namespace = '';\r
21805     var name = 'xmlns';\r
21806 \r
21807     xml = xml || {};\r
21808 \r
21809     if (xml.namespace) {\r
21810       namespace = xml.namespace;\r
21811     } else {\r
21812       return namespace;\r
21813     }\r
21814 \r
21815     if (xml.prefix) {\r
21816       name += ':' + xml.prefix;\r
21817     }\r
21818 \r
21819     return {\r
21820       name: name,\r
21821       value: namespace\r
21822     };\r
21823   };\r
21824 \r
21825   var createArrayXML = function (descriptor) {\r
21826     var name = descriptor.name;\r
21827     var config = descriptor.config;\r
21828     var definition = descriptor.definition;\r
21829     var models = descriptor.models;\r
21830     var value;\r
21831     var items = definition.items;\r
21832     var xml = definition.xml || {};\r
21833 \r
21834     if (!items) { return getErrorMessage(); }\r
21835 \r
21836     value = createSchemaXML(name, items, models, config);\r
21837 \r
21838     xml = xml || {};\r
21839 \r
21840     if (xml.wrapped) {\r
21841       value = wrapTag(name, value);\r
21842     }\r
21843 \r
21844     return value;\r
21845   };\r
21846 \r
21847   var getPrimitiveSignature = function (schema) {\r
21848     var type, items;\r
21849 \r
21850     schema = schema || {};\r
21851     items = schema.items || {};\r
21852     type = schema.type || '';\r
21853 \r
21854     switch (type) {\r
21855       case 'object': return 'Object is not a primitive';\r
21856       case 'array' : return 'Array[' + (items.format || items.type) + ']';\r
21857       default: return schema.format || type;\r
21858     }\r
21859   };\r
21860 \r
21861   var createPrimitiveXML = function (descriptor) {\r
21862     var name = descriptor.name;\r
21863     var definition = descriptor.definition;\r
21864     var primitivesMap = {\r
21865       'string': {\r
21866         'date': new Date(1).toISOString().split('T')[0],\r
21867         'date-time' : new Date(1).toISOString(),\r
21868         'default': 'string'\r
21869       },\r
21870       'integer': {\r
21871         'default': 1\r
21872       },\r
21873       'number': {\r
21874         'default': 1.1\r
21875       },\r
21876       'boolean': {\r
21877         'default': true\r
21878       }\r
21879     };\r
21880     var type = definition.type;\r
21881     var format = definition.format;\r
21882     var xml = definition.xml || {};\r
21883     var namespace = getNamespace(xml);\r
21884     var attributes = [];\r
21885     var value;\r
21886 \r
21887     if (_.keys(primitivesMap).indexOf(type) < 0) { return getErrorMessage(); }\r
21888 \r
21889     if (_.isArray(definition.enum)){\r
21890       value = definition.enum[0];\r
21891     } else {\r
21892       value = definition.example || primitivesMap[type][format] || primitivesMap[type].default;\r
21893     }\r
21894 \r
21895     if (xml.attribute) {\r
21896       return {name: name, value: value};\r
21897     }\r
21898 \r
21899     if (namespace) {\r
21900       attributes.push(namespace);\r
21901     }\r
21902 \r
21903     return wrapTag(name, value, attributes);\r
21904   };\r
21905 \r
21906   function createObjectXML (descriptor) {\r
21907     var name = descriptor.name;\r
21908     var definition = descriptor.definition;\r
21909     var config = descriptor.config;\r
21910     var models = descriptor.models;\r
21911     var isParam = descriptor.config.isParam;\r
21912     var serializedProperties;\r
21913     var attrs = [];\r
21914     var properties = definition.properties;\r
21915     var additionalProperties = definition.additionalProperties;\r
21916     var xml = definition.xml;\r
21917     var namespace = getNamespace(xml);\r
21918 \r
21919     if (namespace) {\r
21920       attrs.push(namespace);\r
21921     }\r
21922 \r
21923     if (!properties && !additionalProperties) { return getErrorMessage(); }\r
21924 \r
21925     properties = properties || {};\r
21926 \r
21927     serializedProperties = _.map(properties, function (prop, key) {\r
21928       var xml, result;\r
21929 \r
21930       if (isParam && prop.readOnly) {\r
21931         return '';\r
21932       }\r
21933 \r
21934       xml = prop.xml || {};\r
21935       result = createSchemaXML(key, prop, models, config);\r
21936 \r
21937       if (xml.attribute) {\r
21938         attrs.push(result);\r
21939         return '';\r
21940       }\r
21941 \r
21942       return result;\r
21943     }).join('');\r
21944 \r
21945     if (additionalProperties) {\r
21946       serializedProperties += '<!-- additional elements allowed -->';\r
21947     }\r
21948 \r
21949     return wrapTag(name, serializedProperties, attrs);\r
21950   }\r
21951 \r
21952   function getInfiniteLoopMessage (name) {\r
21953     return '<!-- Infinite loop $ref:' + name + ' -->';\r
21954   }\r
21955 \r
21956   function getErrorMessage (details) {\r
21957     details = details ? ': ' + details : '';\r
21958     return '<!-- invalid XML' + details + ' -->';\r
21959   }\r
21960 \r
21961   function createSchemaXML (name, definition, models, config) {\r
21962     var $ref = _.isObject(definition) ? definition.$ref : null;\r
21963     var output, index;\r
21964     config = config || {};\r
21965     config.modelsToIgnore = config.modelsToIgnore || [];\r
21966     var descriptor = _.isString($ref) ? getDescriptorByRef($ref, name, models, config)\r
21967         : getDescriptor(name, definition, models, config);\r
21968 \r
21969     if (!descriptor) {\r
21970       return getErrorMessage();\r
21971     }\r
21972 \r
21973     switch (descriptor.type) {\r
21974       case 'array':\r
21975         output = createArrayXML(descriptor); break;\r
21976       case 'object':\r
21977         output = createObjectXML(descriptor); break;\r
21978       case 'loop':\r
21979         output = getInfiniteLoopMessage(descriptor.name); break;\r
21980       default:\r
21981         output = createPrimitiveXML(descriptor);\r
21982     }\r
21983 \r
21984     if ($ref) {\r
21985       index = config.modelsToIgnore.indexOf($ref);\r
21986       if (index > -1) {\r
21987         config.modelsToIgnore.splice(index, 1);\r
21988       }\r
21989     }\r
21990 \r
21991     return output;\r
21992   }\r
21993 \r
21994   function Descriptor (name, type, definition, models, config) {\r
21995     if (arguments.length < 4) {\r
21996       throw new Error();\r
21997     }\r
21998 \r
21999     this.config = config || {};\r
22000     this.config.modelsToIgnore = this.config.modelsToIgnore || [];\r
22001     this.name = getName(name, definition.xml);\r
22002     this.definition = definition;\r
22003     this.models = models;\r
22004     this.type = type;\r
22005   }\r
22006 \r
22007   function getDescriptorByRef($ref, name, models, config) {\r
22008     var modelType = simpleRef($ref);\r
22009     var model = models[modelType] || {};\r
22010     var type = model.definition && model.definition.type ? model.definition.type : 'object';\r
22011     name = name || model.name;\r
22012 \r
22013     if (config.modelsToIgnore.indexOf($ref) > -1) {\r
22014       type = 'loop';\r
22015       name = modelType;\r
22016     } else {\r
22017       config.modelsToIgnore.push($ref);\r
22018     }\r
22019 \r
22020     if (!model.definition) {\r
22021       return null;\r
22022     }\r
22023 \r
22024     return new Descriptor(name, type, model.definition, models, config);\r
22025   }\r
22026 \r
22027   function getDescriptor (name, definition, models, config){\r
22028     var type = definition.type || 'object';\r
22029 \r
22030     if (!definition) {\r
22031       return null;\r
22032     }\r
22033 \r
22034     return new Descriptor(name, type, definition, models, config);\r
22035   }\r
22036 \r
22037   function createXMLSample (name, definition, models, isParam) {\r
22038     var prolog = '<?xml version="1.0"?>';\r
22039 \r
22040     return formatXml(prolog + createSchemaXML(name, definition, models, { isParam: isParam } ));\r
22041   }\r
22042 \r
22043   return {\r
22044       getModelSignature: getModelSignature,\r
22045       createJSONSample: createJSONSample,\r
22046       getParameterModelSignature: getParameterModelSignature,\r
22047       createParameterJSONSample: createParameterJSONSample,\r
22048       createSchemaXML: createSchemaXML,\r
22049       createXMLSample: createXMLSample,\r
22050       getPrimitiveSignature: getPrimitiveSignature\r
22051   };\r
22052 \r
22053 })();\r
22054 \r
22055 'use strict';\r
22056 \r
22057 SwaggerUi.Views.PopupView = Backbone.View.extend({\r
22058     events: {\r
22059         'click .api-popup-cancel': 'cancelClick'\r
22060     },\r
22061 \r
22062     template: Handlebars.templates.popup,\r
22063     className: 'api-popup-dialog',\r
22064 \r
22065     selectors: {\r
22066         content: '.api-popup-content',\r
22067         main   : '#swagger-ui-container'\r
22068     },\r
22069 \r
22070     initialize: function(){\r
22071         this.$el.html(this.template(this.model));\r
22072     },\r
22073 \r
22074     render: function () {\r
22075         this.$(this.selectors.content).append(this.model.content);\r
22076         $(this.selectors.main).first().append(this.el);\r
22077         this.showPopup();\r
22078 \r
22079         return this;\r
22080     },\r
22081 \r
22082     showPopup: function () {\r
22083         this.$el.show();\r
22084     },\r
22085 \r
22086     cancelClick: function () {\r
22087         this.remove();\r
22088     }\r
22089 \r
22090 });\r
22091 \r
22092 'use strict';\r
22093 \r
22094 SwaggerUi.Views.ResourceView = Backbone.View.extend({\r
22095   initialize: function(opts) {\r
22096     opts = opts || {};\r
22097     this.router = opts.router;\r
22098     this.auths = opts.auths;\r
22099     if ('' === this.model.description) {\r
22100       this.model.description = null;\r
22101     }\r
22102     if (this.model.description) {\r
22103       this.model.summary = this.model.description;\r
22104     }\r
22105   },\r
22106 \r
22107   render: function(){\r
22108     var methods = {};\r
22109 \r
22110 \r
22111     $(this.el).html(Handlebars.templates.resource(this.model));\r
22112 \r
22113     // Render each operation\r
22114     for (var i = 0; i < this.model.operationsArray.length; i++) {\r
22115       var operation = this.model.operationsArray[i];\r
22116       var counter = 0;\r
22117       var id = operation.nickname;\r
22118 \r
22119       while (typeof methods[id] !== 'undefined') {\r
22120         id = id + '_' + counter;\r
22121         counter += 1;\r
22122       }\r
22123 \r
22124       methods[id] = operation;\r
22125 \r
22126       operation.nickname = id;\r
22127       operation.parentId = this.model.id;\r
22128       operation.definitions = this.model.definitions; // make Json Schema available for JSonEditor in this operation\r
22129       this.addOperation(operation);\r
22130     }\r
22131 \r
22132     $('.toggleEndpointList', this.el).click(this.callDocs.bind(this, 'toggleEndpointListForResource'));\r
22133     $('.collapseResource', this.el).click(this.callDocs.bind(this, 'collapseOperationsForResource'));\r
22134     $('.expandResource', this.el).click(this.callDocs.bind(this, 'expandOperationsForResource'));\r
22135 \r
22136     return this;\r
22137   },\r
22138 \r
22139   addOperation: function(operation) {\r
22140 \r
22141     operation.number = this.number;\r
22142 \r
22143     // Render an operation and add it to operations li\r
22144     var operationView = new SwaggerUi.Views.OperationView({\r
22145       model: operation,\r
22146       router: this.router,\r
22147       tagName: 'li',\r
22148       className: 'endpoint',\r
22149       swaggerOptions: this.options.swaggerOptions,\r
22150       auths: this.auths\r
22151     });\r
22152 \r
22153     $('.endpoints', $(this.el)).append(operationView.render().el);\r
22154 \r
22155     this.number++;\r
22156 \r
22157   },\r
22158   // Generic Event handler (`Docs` is global)\r
22159 \r
22160 \r
22161   callDocs: function(fnName, e) {\r
22162     e.preventDefault();\r
22163     Docs[fnName](e.currentTarget.getAttribute('data-id'));\r
22164   }\r
22165 });\r
22166 'use strict';\r
22167 \r
22168 SwaggerUi.Views.ResponseContentTypeView = Backbone.View.extend({\r
22169   initialize: function(){},\r
22170 \r
22171   render: function(){\r
22172     this.model.responseContentTypeId = 'rct' + Math.random();\r
22173     $(this.el).html(Handlebars.templates.response_content_type(this.model));\r
22174     return this;\r
22175   }\r
22176 });\r
22177 'use strict';\r
22178 \r
22179 SwaggerUi.Views.SignatureView = Backbone.View.extend({\r
22180   events: {\r
22181     'click a.description-link'       : 'switchToDescription',\r
22182     'click a.snippet-link'           : 'switchToSnippet',\r
22183     'mousedown .snippet_json'          : 'jsonSnippetMouseDown',\r
22184     'mousedown .snippet_xml'          : 'xmlSnippetMouseDown'\r
22185   },\r
22186 \r
22187   initialize: function () {\r
22188   },\r
22189 \r
22190   render: function(){\r
22191 \r
22192     $(this.el).html(Handlebars.templates.signature(this.model));\r
22193 \r
22194     if (this.model.defaultRendering === 'model') {\r
22195       this.switchToDescription();\r
22196     } else {\r
22197       this.switchToSnippet();\r
22198     }\r
22199 \r
22200     return this;\r
22201   },\r
22202 \r
22203   // handler for show signature\r
22204   switchToDescription: function(e){\r
22205     if (e) { e.preventDefault(); }\r
22206 \r
22207     $('.snippet', $(this.el)).hide();\r
22208     $('.description', $(this.el)).show();\r
22209     $('.description-link', $(this.el)).addClass('selected');\r
22210     $('.snippet-link', $(this.el)).removeClass('selected');\r
22211   },\r
22212 \r
22213   // handler for show sample\r
22214   switchToSnippet: function(e){\r
22215     if (e) { e.preventDefault(); }\r
22216 \r
22217     $('.snippet', $(this.el)).show();\r
22218     $('.description', $(this.el)).hide();\r
22219     $('.snippet-link', $(this.el)).addClass('selected');\r
22220     $('.description-link', $(this.el)).removeClass('selected');\r
22221   },\r
22222 \r
22223   // handler for snippet to text area\r
22224   snippetToTextArea: function(val) {\r
22225     var textArea = $('textarea', $(this.el.parentNode.parentNode.parentNode));\r
22226 \r
22227     // Fix for bug in IE 10/11 which causes placeholder text to be copied to "value"\r
22228     if ($.trim(textArea.val()) === '' || textArea.prop('placeholder') === textArea.val()) {\r
22229       textArea.val(val);\r
22230       // TODO move this code outside of the view and expose an event instead\r
22231       if( this.model.jsonEditor && this.model.jsonEditor.isEnabled()){\r
22232         this.model.jsonEditor.setValue(JSON.parse(this.model.sampleJSON));\r
22233       }\r
22234     }\r
22235   },\r
22236 \r
22237   jsonSnippetMouseDown: function (e) {\r
22238     if (this.model.isParam) {\r
22239       if (e) { e.preventDefault(); }\r
22240 \r
22241       this.snippetToTextArea(this.model.sampleJSON);\r
22242     }\r
22243   },\r
22244 \r
22245   xmlSnippetMouseDown: function (e) {\r
22246     if (this.model.isParam) {\r
22247       if (e) { e.preventDefault(); }\r
22248 \r
22249       this.snippetToTextArea(this.model.sampleXML);\r
22250     }\r
22251   }\r
22252 });\r
22253 'use strict';\r
22254 \r
22255 SwaggerUi.Views.StatusCodeView = Backbone.View.extend({\r
22256   initialize: function (opts) {\r
22257     this.options = opts || {};\r
22258     this.router = this.options.router;\r
22259   },\r
22260 \r
22261   render: function(){\r
22262     var responseModel, responseModelView;\r
22263     var value = this.router.api.models[this.model.responseModel];\r
22264     $(this.el).html(Handlebars.templates.status_code(this.model));\r
22265 \r
22266     if (this.router.api.models.hasOwnProperty(this.model.responseModel)) {\r
22267       responseModel = {\r
22268         sampleJSON: JSON.stringify(SwaggerUi.partials.signature.createJSONSample(value), void 0, 2),\r
22269         sampleXML: this.model.isXML ? SwaggerUi.partials.signature.createXMLSample('', this.model.schema, this.router.api.models) : false,\r
22270         isParam: false,\r
22271         signature: SwaggerUi.partials.signature.getModelSignature(this.model.responseModel, value, this.router.api.models),\r
22272         defaultRendering: this.model.defaultRendering\r
22273       };\r
22274     } else {\r
22275       responseModel = {\r
22276         signature: SwaggerUi.partials.signature.getPrimitiveSignature(this.model.schema)\r
22277       };\r
22278     }\r
22279 \r
22280     responseModelView = new SwaggerUi.Views.SignatureView({model: responseModel, tagName: 'div'});\r
22281     $('.model-signature', this.$el).append(responseModelView.render().el);\r
22282     return this;\r
22283   }\r
22284 });}).call(this);