vendor: 9,917 bytes, lines 1-335
1(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){ 2'use strict'; 3 4var has = Object.prototype.hasOwnProperty 5 , prefix = '~'; 6 7/** 8 * Constructor to create a storage for our `EE` objects. 9 * An `Events` instance is a plain object whose properties are event names. 10 * 11 * @constructor 12 * @api private 13 */ 14function Events() {} 15 16// 17// We try to not inherit from `Object.prototype`. In some engines creating an 18// instance in this way is faster than calling `Object.create(null)` directly. 19// If `Object.create(null)` is not supported we prefix the event names with a 20// character to make sure that the built-in object properties are not 21// overridden or used as an attack vector. 22// 23if (Object.create) { 24 Events.prototype = Object.create(null); 25 26 // 27 // This hack is needed because the `__proto__` property is still inherited in 28 // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5. 29 // 30 if (!new Events().__proto__) prefix = false; 31} 32 33/** 34 * Representation of a single event listener. 35 * 36 * @param {Function} fn The listener function. 37 * @param {Mixed} context The context to invoke the listener with. 38 * @param {Boolean} [once=false] Specify if the listener is a one-time listener. 39 * @constructor 40 * @api private 41 */ 42function EE(fn, context, once) { 43 this.fn = fn; 44 this.context = context; 45 this.once = once || false; 46} 47 48/** 49 * Minimal `EventEmitter` interface that is molded against the Node.js 50 * `EventEmitter` interface. 51 * 52 * @constructor 53 * @api public 54 */ 55function EventEmitter() { 56 this._events = new Events(); 57 this._eventsCount = 0; 58} 59 60/** 61 * Return an array listing the events for which the emitter has registered 62 * listeners. 63 * 64 * @returns {Array} 65 * @api public 66 */ 67EventEmitter.prototype.eventNames = function eventNames() { 68 var names = [] 69 , events 70 , name; 71 72 if (this._eventsCount === 0) return names; 73 74 for (name in (events = this._events)) { 75 if (has.call(events, name)) names.push(prefix ? name.slice(1) : name); 76 } 77 78 if (Object.getOwnPropertySymbols) { 79 return names.concat(Object.getOwnPropertySymbols(events)); 80 } 81 82 return names; 83}; 84 85/** 86 * Return the listeners registered for a given event. 87 * 88 * @param {String|Symbol} event The event name. 89 * @param {Boolean} exists Only check if there are listeners. 90 * @returns {Array|Boolean} 91 * @api public 92 */ 93EventEmitter.prototype.listeners = function listeners(event, exists) { 94 var evt = prefix ? prefix + event : event 95 , available = this._events[evt]; 96 97 if (exists) return !!available; 98 if (!available) return []; 99 if (available.fn) return [available.fn]; 100 101 for (var i = 0, l = available.length, ee = new Array(l); i < l; i++) { 102 ee[i] = available[i].fn; 103 } 104 105 return ee; 106}; 107 108/** 109 * Calls each of the listeners registered for a given event. 110 * 111 * @param {String|Symbol} event The event name. 112 * @returns {Boolean} `true` if the event had listeners, else `false`. 113 * @api public 114 */ 115EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) { 116 var evt = prefix ? prefix + event : event; 117 118 if (!this._events[evt]) return false; 119 120 var listeners = this._events[evt] 121 , len = arguments.length 122 , args 123 , i; 124 125 if (listeners.fn) { 126 if (listeners.once) this.removeListener(event, listeners.fn, undefined, true); 127 128 switch (len) { 129 case 1: return listeners.fn.call(listeners.context), true; 130 case 2: return listeners.fn.call(listeners.context, a1), true; 131 case 3: return listeners.fn.call(listeners.context, a1, a2), true; 132 case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true; 133 case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true; 134 case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true; 135 } 136 137 for (i = 1, args = new Array(len -1); i < len; i++) { 138 args[i - 1] = arguments[i]; 139 } 140 141 listeners.fn.apply(listeners.context, args); 142 } else { 143 var length = listeners.length 144 , j; 145 146 for (i = 0; i < length; i++) { 147 if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true); 148 149 switch (len) { 150 case 1: listeners[i].fn.call(listeners[i].context); break; 151 case 2: listeners[i].fn.call(listeners[i].context, a1); break; 152 case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break; 153 case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break; 154 default: 155 if (!args) for (j = 1, args = new Array(len -1); j < len; j++) { 156 args[j - 1] = arguments[j]; 157 } 158 159 listeners[i].fn.apply(listeners[i].context, args); 160 } 161 } 162 } 163 164 return true; 165}; 166 167/** 168 * Add a listener for a given event. 169 * 170 * @param {String|Symbol} event The event name. 171 * @param {Function} fn The listener function. 172 * @param {Mixed} [context=this] The context to invoke the listener with. 173 * @returns {EventEmitter} `this`. 174 * @api public 175 */ 176EventEmitter.prototype.on = function on(event, fn, context) { 177 var listener = new EE(fn, context || this) 178 , evt = prefix ? prefix + event : event; 179 180 if (!this._events[evt]) this._events[evt] = listener, this._eventsCount++; 181 else if (!this._events[evt].fn) this._events[evt].push(listener); 182 else this._events[evt] = [this._events[evt], listener]; 183 184 return this; 185}; 186 187/** 188 * Add a one-time listener for a given event. 189 * 190 * @param {String|Symbol} event The event name. 191 * @param {Function} fn The listener function. 192 * @param {Mixed} [context=this] The context to invoke the listener with. 193 * @returns {EventEmitter} `this`. 194 * @api public 195 */ 196EventEmitter.prototype.once = function once(event, fn, context) { 197 var listener = new EE(fn, context || this, true) 198 , evt = prefix ? prefix + event : event; 199 200 if (!this._events[evt]) this._events[evt] = listener, this._eventsCount++; 201 else if (!this._events[evt].fn) this._events[evt].push(listener); 202 else this._events[evt] = [this._events[evt], listener]; 203 204 return this; 205}; 206 207/** 208 * Remove the listeners of a given event. 209 * 210 * @param {String|Symbol} event The event name. 211 * @param {Function} fn Only remove the listeners that match this function. 212 * @param {Mixed} context Only remove the listeners that have this context. 213 * @param {Boolean} once Only remove one-time listeners. 214 * @returns {EventEmitter} `this`. 215 * @api public 216 */ 217EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) { 218 var evt = prefix ? prefix + event : event; 219 220 if (!this._events[evt]) return this; 221 if (!fn) { 222 if (--this._eventsCount === 0) this._events = new Events(); 223 else delete this._events[evt]; 224 return this; 225 } 226 227 var listeners = this._events[evt]; 228 229 if (listeners.fn) { 230 if ( 231 listeners.fn === fn 232 && (!once || listeners.once) 233 && (!context || listeners.context === context) 234 ) { 235 if (--this._eventsCount === 0) this._events = new Events(); 236 else delete this._events[evt]; 237 } 238 } else { 239 for (var i = 0, events = [], length = listeners.length; i < length; i++) { 240 if ( 241 listeners[i].fn !== fn 242 || (once && !listeners[i].once) 243 || (context && listeners[i].context !== context) 244 ) { 245 events.push(listeners[i]); 246 } 247 } 248 249 // 250 // Reset the array, or remove it completely if we have no more listeners. 251 // 252 if (events.length) this._events[evt] = events.length === 1 ? events[0] : events; 253 else if (--this._eventsCount === 0) this._events = new Events(); 254 else delete this._events[evt]; 255 } 256 257 return this; 258}; 259 260/** 261 * Remove all listeners, or those of the specified event. 262 * 263 * @param {String|Symbol} [event] The event name. 264 * @returns {EventEmitter} `this`. 265 * @api public 266 */ 267EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) { 268 var evt; 269 270 if (event) { 271 evt = prefix ? prefix + event : event; 272 if (this._events[evt]) { 273 if (--this._eventsCount === 0) this._events = new Events(); 274 else delete this._events[evt]; 275 } 276 } else { 277 this._events = new Events(); 278 this._eventsCount = 0; 279 } 280 281 return this; 282}; 283 284// 285// Alias methods names because people roll like that. 286// 287EventEmitter.prototype.off = EventEmitter.prototype.removeListener; 288EventEmitter.prototype.addListener = EventEmitter.prototype.on; 289 290// 291// This function doesn't apply anymore. 292// 293EventEmitter.prototype.setMaxListeners = function setMaxListeners() { 294 return this; 295}; 296 297// 298// Expose the prefix. 299// 300EventEmitter.prefixed = prefix; 301 302// 303// Expose the module. 304// 305if ('undefined' !== typeof module) { 306 module.exports = EventEmitter; 307} 308 309},{}],2:[function(require,module,exports){ 310(function (Buffer){ 311var jsfx; 312(function (jsfx) { 313 var Filter = (function () { 314 function Filter(vertexSource, fragmentSource) { 315 if (vertexSource === void 0) { vertexSource = null; } 316 if (fragmentSource === void 0) { fragmentSource = null; } 317 this.vertexSource = vertexSource; 318 this.fragmentSource = fragmentSource; 319 this.properties = {}; 320 } 321 /** 322 * Returns all the properties of the shader. Useful for drawWebGl when are are just passing along data 323 * to the shader. 324 * 325 * @returns {{}|*} 326 */ 327 Filter.prototype.getProperties = function () { 328 return this.properties; 329 }; 330 /** 331 * The javascript implementation of the filter 332 * 333 * @param imageData 334 */ 335 Filter.prototype.drawCanvas = function (imageData) {
336 throw new Error("Must be implemented"); 337 }; 338 /** 339 * The WebGL implementation of the filter 340 * 341 * @param renderer 342 */ 343 Filter.prototype.drawWebGL = function (renderer) { 344 var shader = renderer.getShader(this); 345 var properties = this.getProperties(); 346 renderer.getTexture().use(); 347 renderer.getNextTexture().drawTo(function () { 348 shader.uniforms(properties).drawRect(); 349 }); 350 }; 351 Filter.prototype.getVertexSource = function () { 352 return this.vertexSource; 353 }; 354 Filter.prototype.getFragmentSource = function () { 355 return this.fragmentSource; 356 }; 357 Filter.clamp = function (low, value, high) { 358 return Math.max(low, Math.min(value, high)); 359 }; 360 return Filter; 361 })(); 362 jsfx.Filter = Filter; 363})(jsfx || (jsfx = {})); 364var __extends = (this && this.__extends) || function (d, b) { 365 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 366 function __() { this.constructor = d; } 367 __.prototype = b.prototype; 368 d.prototype = new __(); 369}; 370var jsfx; 371(function (jsfx) { 372 var IterableFilter = (function (_super) { 373 __extends(IterableFilter, _super); 374 function IterableFilter() { 375 _super.apply(this, arguments); 376 } 377 IterableFilter.prototype.drawCanvas = function (imageData) { 378 return IterableFilter.drawCanvas([this], imageData); 379 }; 380 IterableFilter.prototype.iterateCanvas = function (imageData) {
381 throw new Error("Must be implemented"); 382 }; 383 IterableFilter.drawCanvas = function (filters, imageData) { 384 var helper; 385 for (var i = 0; i < imageData.data.length; i += 4) { 386 helper = new jsfx.util.ImageDataHelper(imageData, i); 387 for (var j = 0; j < filters.length; j++) { 388 filters[j].iterateCanvas(helper); 389 } 390 helper.save(); 391 } 392 return imageData; 393 }; 394 return IterableFilter; 395 })(jsfx.Filter); 396 jsfx.IterableFilter = IterableFilter; 397})(jsfx || (jsfx = {})); 398var jsfx; 399(function (jsfx) { 400 var hasWebGL = (function () { 401 try { 402 var canvas = document.createElement("canvas"); 403 return !!(canvas.getContext("webgl") || canvas.getContext("experimental-webgl")); 404 } 405 catch (e) { 406 return false; 407 } 408 })(); 409 function Renderer(type) { 410 if (!type) { 411 type = hasWebGL ? "webgl" : "canvas"; 412 } 413 if (type === "webgl") { 414 return new jsfx.webgl.Renderer(); 415 } 416 return new jsfx.canvas.Renderer(); 417 } 418 jsfx.Renderer = Renderer; 419})(jsfx || (jsfx = {})); 420var jsfx; 421(function (jsfx) { 422 var Source = (function () { 423 function Source(element) { 424 this.element = element; 425 } 426 Object.defineProperty(Source.prototype, "width", { 427 get: function () { 428 return this.element.width; 429 }, 430 enumerable: true, 431 configurable: true 432 }); 433 Object.defineProperty(Source.prototype, "height", { 434 get: function () { 435 return this.element.height; 436 }, 437 enumerable: true, 438 configurable: true 439 }); 440 return Source; 441 })(); 442 jsfx.Source = Source; 443})(jsfx || (jsfx = {})); 444var jsfx; 445(function (jsfx) { 446 var canvas; 447 (function (canvas) { 448 var Renderer = (function () {
449 function Renderer() { 450 this.canvas = jsfx.canvas.Renderer.createCanvas(); 451 this.ctx = this.canvas.getContext("2d"); 452 this.source = null; 453 this.imageData = null; 454 } 455 Renderer.prototype.setSource = function (source) { 456 // first, clean up 457 if (this.source) { 458 this.cleanUp(); 459 } 460 // re-set data and start rendering 461 this.source = source; 462 this.canvas.width = source.width; 463 this.canvas.height = source.height; 464 // draw the image on to a canvas we can manipulate 465 this.ctx.drawImage(source.element, 0, 0, source.width, source.height); 466 // store the pixels 467 this.imageData = this.ctx.getImageData(0, 0, source.width, source.height); 468 return this; 469 }; 470 Renderer.prototype.getSource = function () { 471 return this.source; 472 }; 473 Renderer.prototype.applyFilter = function (filter) { 474 this.imageData = filter.drawCanvas(this.imageData); 475 return this; 476 }; 477 Renderer.prototype.applyFilters = function (filters) { 478 var stack = []; 479 var filter; 480 for (var i = 0; i < filters.length; i++) { 481 filter = filters[i]; 482 if (filter instanceof jsfx.IterableFilter) { 483 stack.push(filter); 484 } 485 else { 486 // if there if something in the stack, apply that first 487 if (stack.length > 0) { 488 this.applyFilterStack(stack); 489 stack = []; 490 } 491 // apply current filter 492 this.applyFilter(filter); 493 } 494 } 495 // if there is still a stack left, apply it 496 if (stack.length > 0) { 497 this.applyFilterStack(stack); 498 } 499 return this; 500 }; 501 Renderer.prototype.applyFilterStack = function (stack) { 502 this.imageData = jsfx.IterableFilter.drawCanvas(stack, this.imageData); 503 return this; 504 }; 505 Renderer.prototype.render = function () { 506 this.ctx.putImageData(this.imageData, 0, 0); 507 }; 508 Renderer.prototype.getCanvas = function () { 509 return this.canvas; 510 }; 511 Renderer.prototype.cleanUp = function () { 512 this.imageData = null; 513 this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); 514 }; 515 Renderer.createCanvas = function () { 516 return typeof Buffer !== "undefined" && typeof window === "undefined" ? 517 // Commented out, since it was causing require failures. 518 // new (require("canvas"))(100, 100) : 519 null : 520 document.createElement("canvas"); 521 }; 522 return Renderer; 523 })(); 524 canvas.Renderer = Renderer; 525 })(canvas = jsfx.canvas || (jsfx.canvas = {})); 526})(jsfx || (jsfx = {})); 527var jsfx; 528(function (jsfx) { 529 var filter; 530 (function (filter) { 531 /** 532 * @filter Blur 533 * @description This is the TriangleBlur from glfx, but for the canvas implementation, we are cheating by 534 * using StackBlur. The implementations are obviously very different, but the results are very close. 535 * @param radius The radius of the pyramid convolved with the image. 536 */ 537 var Blur = (function (_super) { 538 __extends(Blur, _super); 539 function Blur(radius) { 540 _super.call(this, null, "\n uniform sampler2D texture;\n uniform vec2 delta;\n varying vec2 texCoord;\n\n void main() {\n vec4 color = vec4(0.0);\n float total = 0.0;\n\n /* randomize the lookup values to hide the fixed number of samples */\n //float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);\n\n vec3 scale = vec3(12.9898, 78.233, 151.7182);\n float offset = fract(sin(dot(gl_FragCoord.xyz
540+ 0.0, scale)) * 43758.5453 + 0.0);\n\n for (float t = -30.0; t <= 30.0; t++) {\n float percent = (t + offset - 0.5) / 30.0;\n float weight = 1.0 - abs(percent);\n vec4 sample = texture2D(texture, texCoord + delta * percent);\n\n /* switch to pre-multiplied alpha to correctly blur transparent images */\n sample.rgb *= sample.a;\n\n color += sample * weight;\n total += weight;\n }\n\n gl_FragColor = color / total;\n\n /* switch back from pre-multiplied alpha */\n gl_FragColor.rgb /= gl_FragColor.a + 0.00001;\n }\n "); 541 // set properties 542 this.properties.radius = radius; 543 } 544 Blur.prototype.drawWebGL = function (renderer) { 545 var shader = renderer.getShader(this); 546 var firstPass = { delta: [this.properties.radius / renderer.getSource().width, 0] }; 547 var secondPass = { delta: [0, this.properties.radius / renderer.getSource().height] }; 548 renderer.getTexture().use(); 549 renderer.getNextTexture().drawTo(function () { 550 shader.uniforms(firstPass).drawRect(); 551 }); 552 renderer.getTexture().use(); 553 renderer.getNextTexture().drawTo(function () { 554 shader.uniforms(secondPass).drawRect(); 555 }); 556 }; 557 Blur.prototype.drawCanvas = function (imageData) { 558 var pixels = imageData.data; 559 var radius = this.properties.radius; 560 var width = imageData.width; 561 var height = imageData.height; 562 var x, y, i, p, yp, yi, yw, r_sum, g_sum, b_sum, a_sum, r_out_sum, g_out_sum, b_out_sum, a_out_sum, r_in_sum, g_in_sum, b_in_sum, a_in_sum, pr, pg, pb, pa, rbs; 563 var div = radius + radius + 1; 564 var widthMinus1 = width - 1; 565 var heightMinus1 = height - 1; 566 var radiusPlus1 = radius + 1; 567 var sumFactor = radiusPlus1 * (radiusPlus1 + 1) / 2; 568 var stackStart = new BlurStack(); 569 var stack = stackStart; 570 for (i = 1; i < div; i++) { 571 stack = stack.next = new BlurStack(); 572 if (i == radiusPlus1) 573 var stackEnd = stack; 574 } 575 stack.next = stackStart; 576 var stackIn = null; 577 var stackOut = null; 578 yw = yi = 0; 579 var mul_sum = mul_table[radius]; 580 var shg_sum = shg_table[radius]; 581 for (y = 0; y < height; y++) { 582 r_in_sum = g_in_sum = b_in_sum = a_in_sum = r_sum = g_sum = b_sum = a_sum = 0; 583 r_out_sum = radiusPlus1 * (pr = pixels[yi]); 584 g_out_sum = radiusPlus1 * (pg = pixels[yi + 1]); 585 b_out_sum = radiusPlus1 * (pb = pixels[yi + 2]); 586 a_out_sum = radiusPlus1 * (pa = pixels[yi + 3]); 587 r_sum += sumFactor * pr; 588 g_sum += sumFactor * pg; 589 b_sum += sumFactor * pb; 590 a_sum += sumFactor * pa; 591 stack = stackStart; 592 for (i = 0; i < radiusPlus1; i++) { 593 stack.r = pr; 594 stack.g = pg; 595 stack.b = pb; 596 stack.a = pa; 597 stack = stack.next; 598 } 599 for (i = 1; i < radiusPlus1; i++) { 600 p = yi + ((widthMinus1 < i ? widthMinus1 : i) << 2); 601 r_sum += (stack.r = (pr = pixels[p])) * (rbs = radiusPlus1 - i); 602 g_sum += (stack.g = (pg = pixels[p + 1])) * rbs; 603 b_sum += (stack.b = (pb = pixels[p + 2])) * rbs; 604 a_sum += (stack.a = (pa = pixels[p + 3])) * rbs; 605 r_in_sum += pr; 606 g_in_sum += pg; 607 b_in_sum += pb; 608 a_in_sum += pa; 609 stack = stack.next; 610 } 611 stackIn = stackStart; 612 stackOut = stackEnd; 613 for (x = 0; x < width; x++) { 614 pixels[yi + 3] = pa = (a_sum * mul_sum) >> shg_sum; 615 if (pa != 0) { 616 pa = 255 / pa; 617 pixels[yi] = ((r_sum * mul_sum) >> shg_sum) * pa; 618 pixels[yi + 1] = ((g_sum * mul_sum) >> shg_sum) * pa; 619 pixels[yi + 2] = ((b_sum * mul_sum) >> shg_sum) * pa; 620 } 621 else { 622 pixels[yi] = pixels[yi + 1] = pixels[yi + 2] = 0; 623 } 624 r_sum -= r_out_sum; 625 g_sum -= g_out_sum; 626 b_sum -= b_out_sum; 627 a_sum -= a_out_sum; 628 r_out_sum -= stackIn.r; 629 g_out_sum -= stackIn.g; 630 b_out_sum -= stackIn.b; 631 a_out_sum -= stackIn.a; 632 p = (yw + ((p = x + radius + 1) < widthMinus1 ? p
632: widthMinus1)) << 2; 633 r_in_sum += (stackIn.r = pixels[p]); 634 g_in_sum += (stackIn.g = pixels[p + 1]); 635 b_in_sum += (stackIn.b = pixels[p + 2]); 636 a_in_sum += (stackIn.a = pixels[p + 3]); 637 r_sum += r_in_sum; 638 g_sum += g_in_sum; 639 b_sum += b_in_sum; 640 a_sum += a_in_sum; 641 stackIn = stackIn.next; 642 r_out_sum += (pr = stackOut.r); 643 g_out_sum += (pg = stackOut.g); 644 b_out_sum += (pb = stackOut.b); 645 a_out_sum += (pa = stackOut.a); 646 r_in_sum -= pr; 647 g_in_sum -= pg; 648 b_in_sum -= pb; 649 a_in_sum -= pa; 650 stackOut = stackOut.next; 651 yi += 4; 652 } 653 yw += width; 654 } 655 for (x = 0; x < width; x++) { 656 g_in_sum = b_in_sum = a_in_sum = r_in_sum = g_sum = b_sum = a_sum = r_sum = 0; 657 yi = x << 2; 658 r_out_sum = radiusPlus1 * (pr = pixels[yi]); 659 g_out_sum = radiusPlus1 * (pg = pixels[yi + 1]); 660 b_out_sum = radiusPlus1 * (pb = pixels[yi + 2]); 661 a_out_sum = radiusPlus1 * (pa = pixels[yi + 3]); 662 r_sum += sumFactor * pr; 663 g_sum += sumFactor * pg; 664 b_sum += sumFactor * pb; 665 a_sum += sumFactor * pa; 666 stack = stackStart; 667 for (i = 0; i < radiusPlus1; i++) { 668 stack.r = pr; 669 stack.g = pg; 670 stack.b = pb; 671 stack.a = pa; 672 stack = stack.next; 673 } 674 yp = width; 675 for (i = 1; i <= radius; i++) { 676 yi = (yp + x) << 2; 677 r_sum += (stack.r = (pr = pixels[yi])) * (rbs = radiusPlus1 - i); 678 g_sum += (stack.g = (pg = pixels[yi + 1])) * rbs; 679 b_sum += (stack.b = (pb = pixels[yi + 2])) * rbs; 680 a_sum += (stack.a = (pa = pixels[yi + 3])) * rbs; 681 r_in_sum += pr; 682 g_in_sum += pg; 683 b_in_sum += pb; 684 a_in_sum += pa; 685 stack = stack.next; 686 if (i < heightMinus1) { 687 yp += width; 688 } 689 } 690 yi = x; 691 stackIn = stackStart; 692 stackOut = stackEnd; 693 for (y = 0; y < height; y++) { 694 p = yi << 2; 695 pixels[p + 3] = pa = (a_sum * mul_sum) >> shg_sum; 696 if (pa > 0) { 697 pa = 255 / pa; 698 pixels[p] = ((r_sum * mul_sum) >> shg_sum) * pa; 699 pixels[p + 1] = ((g_sum * mul_sum) >> shg_sum) * pa; 700 pixels[p + 2] = ((b_sum * mul_sum) >> shg_sum) * pa; 701 } 702 else { 703 pixels[p] = pixels[p + 1] = pixels[p + 2] = 0; 704 } 705 r_sum -= r_out_sum; 706 g_sum -= g_out_sum; 707 b_sum -= b_out_sum; 708 a_sum -= a_out_sum; 709 r_out_sum -= stackIn.r; 710 g_out_sum -= stackIn.g; 711 b_out_sum -= stackIn.b; 712 a_out_sum -= stackIn.a; 713 p = (x + (((p = y + radiusPlus1) < heightMinus1 ? p : heightMinus1) * width)) << 2; 714 r_sum += (r_in_sum += (stackIn.r = pixels[p])); 715 g_sum += (g_in_sum += (stackIn.g = pixels[p + 1])); 716 b_sum += (b_in_sum += (stackIn.b = pixels[p + 2])); 717 a_sum += (a_in_sum += (stackIn.a = pixels[p + 3])); 718 stackIn = stackIn.next; 719 r_out_sum += (pr = stackOut.r); 720 g_out_sum += (pg = stackOut.g); 721 b_out_sum += (pb = stackOut.b); 722 a_out_sum += (pa = stackOut.a); 723 r_in_sum -= pr; 724 g_in_sum -= pg; 725 b_in_sum -= pb; 726 a_in_sum -= pa; 727 stackOut = stackOut.next; 728 yi += width; 729 } 730 } 731 return imageData; 732 }; 733 return Blur; 734 })(jsfx.Filter); 735 filter.Blur = Blur; 736 var mul_table = [ 737 512, 512, 456, 512, 328, 456, 335, 512, 405, 328, 271, 456, 388, 335, 292, 512, 738 454, 405, 364, 328, 298, 271, 496, 456, 420, 388, 360, 335, 312, 292, 273, 512, 739 482, 454, 428, 405, 383, 364, 345, 328, 312, 298, 284, 271, 259, 496, 475, 456, 740 437, 420, 404, 388, 374, 360, 347, 335, 323, 312, 302, 292, 282, 273, 265, 512, 741 497, 482, 468, 454, 441, 428, 417, 405, 394, 383, 373, 364, 354, 345, 337, 328, 742 320, 312, 305, 298, 291, 284, 278, 271, 265, 259, 507, 496, 485, 475, 465, 456,
743 446, 437, 428, 420, 412, 404, 396, 388, 381, 374, 367, 360, 354, 347, 341, 335, 744 329, 323, 318, 312, 307, 302, 297, 292, 287, 282, 278, 273, 269, 265, 261, 512, 745 505, 497, 489, 482, 475, 468, 461, 454, 447, 441, 435, 428, 422, 417, 411, 405, 746 399, 394, 389, 383, 378, 373, 368, 364, 359, 354, 350, 345, 341, 337, 332, 328, 747 324, 320, 316, 312, 309, 305, 301, 298, 294, 291, 287, 284, 281, 278, 274, 271, 748 268, 265, 262, 259, 257, 507, 501, 496, 491, 485, 480, 475, 470, 465, 460, 456, 749 451, 446, 442, 437, 433, 428, 424, 420, 416, 412, 408, 404, 400, 396, 392, 388, 750 385, 381, 377, 374, 370, 367, 363, 360, 357, 354, 350, 347, 344, 341, 338, 335, 751 332, 329, 326, 323, 320, 318, 315, 312, 310, 307, 304, 302, 299, 297, 294, 292, 752 289, 287, 285, 282, 280, 278, 275, 273, 271, 269, 267, 265, 263, 261, 259]; 753 var shg_table = [ 754 9, 11, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, 755 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 756 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 757 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 758 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 759 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 760 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 761 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 762 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 763 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 764 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 765 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 766 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 767 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 768 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 769 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24]; 770 var BlurStack = (function () { 771 function BlurStack() { 772 this.r = 0; 773 this.g = 0; 774 this.b = 0; 775 this.a = 0; 776 this.next = null; 777 } 778 return BlurStack; 779 })(); 780 })(filter = jsfx.filter || (jsfx.filter = {})); 781})(jsfx || (jsfx = {})); 782var jsfx; 783(function (jsfx) { 784 var filter; 785 (function (filter) { 786 /** 787 * @filter Brightness 788 * @description Provides additive brightness control. 789 * @param brightness -1 to 1 (-1 is solid black, 0 is no change, and 1 is solid white) 790 */ 791 var Brightness = (function (_super) { 792 __extends(Brightness, _super); 793 function Brightness(brightness) { 794 _super.call(this, null, "\n uniform sampler2D texture;\n uniform float brightness;\n varying vec2 texCoord;\n\n void main() {\n vec4 color = texture2D(texture, texCoord);\n color.rgb += brightness;\n\n gl_FragColor = color;\n }\n "); 795 // set properties 796 this.properties.brightness = jsfx.Filter.clamp(-1, brightness, 1) || 0; 797 } 798 Brightness.prototype.iterateCanvas = function (helper) { 799 var brightness = this.properties.brightness; 800 helper.r += brightness; 801 helper.g += brightness; 802 helper.b += brightness; 803 }; 804 return Brightness; 805 })(jsfx.IterableFilter); 806 filter.Brightness = Brightness; 807 })(filter = jsfx.filter || (jsfx.filter = {})); 808})(jsfx || (jsfx = {})); 809var jsfx; 810(function (jsfx) { 811 var filter; 812 (function (filter) { 813 /** 814 * @filter Contrast 815 * @description Provides multiplicative contrast control. 816 * @param contrast -1 to 1 (-1 is solid gray, 0 is no change, and 1 is maximum contrast) 817 */ 818 var Contrast = (function (_super) { 819 __extends(Contrast, _super); 820 function Contrast(contrast) { 821 _super.call(this, null, "\n uniform sampler2D texture;\n uniform float contrast;\n varying vec2 texCoord;\n\n void main() {\n vec4 color = texture2D(texture, texCoord);\n\n if (contrast > 0.0) {\n color.rgb = (color.rgb - 0.5) / (1.0 - contrast) + 0.5;\n } else {\n color.rgb = (color.rgb - 0.5) * (1.0 + contrast) + 0.5;\n }\n\n gl_FragColor = color;\n }\n "); 822 // set properties 823 this.properties.contrast = jsfx.Filter.clamp(-1, contrast, 1) || 0; 824 } 825 Contrast.prototype.iterateCanvas = function (helper) { 826 var contrast = this.properties.contrast; 827 if (contrast > 0) { 828 helper.r = (helper.r - 0.5) / (1 - contrast) + 0.5; 829 helper.g = (helper.g - 0.5) / (1 - contrast) + 0.5; 830 helper.b = (helper.b - 0.5) / (1 - contrast) + 0.5; 831 } 832 else { 833 helper.r = (helper.r - 0.5) * (1 + contrast) + 0.5; 834 helper.g = (helper.g - 0.5) * (1 + contrast) + 0.5; 835 helper.b = (helper.b - 0.5) * (1 + contrast) + 0.5; 836 } 837 }; 838 return Contrast; 839 })(jsfx.IterableFilter); 840 filter.Contrast = Contrast; 841 })(filter = jsfx.filter || (jsfx.filter = {})); 842})(jsfx || (jsfx = {})); 843var jsfx; 844(function (jsfx) { 845 var filter; 846 (function (filter) { 847 /** 848 * @filter Curves
849 * @description A powerful mapping tool that transforms the colors in the image 850 * by an arbitrary function. The function is interpolated between 851 * a set of 2D points using splines. The curves filter can take 852 * either one or three arguments which will apply the mapping to 853 * either luminance or RGB values, respectively. 854 * @param red A list of points that define the function for the red channel. 855 * Each point is a list of two values: the value before the mapping 856 * and the value after the mapping, both in the range 0 to 1. For 857 * example, [[0,1], [1,0]] would invert the red channel while 858 * [[0,0], [1,1]] would leave the red channel unchanged. If green 859 * and blue are omitted then this argument also applies to the 860 * green and blue channels. 861 * @param green (optional) A list of points that define the function for the green 862 * channel (just like for red). 863 * @param blue (optional) A list of points that define the function for the blue 864 * channel (just like for red). 865 */ 866 var Curves = (function (_super) { 867 __extends(Curves, _super); 868 function Curves(red, green, blue) { 869 _super.call(this, null, "\n uniform sampler2D texture;\n uniform sampler2D map;\n varying vec2 texCoord;\n\n void main() {\n vec4 color = texture2D(texture, texCoord);\n color.r = texture2D(map, vec2(color.r)).r;\n color.g = texture2D(map, vec2(color.g)).g;\n color.b = texture2D(map, vec2(color.b)).b;\n gl_FragColor = color;\n }\n "); 870 this.red = red; 871 this.green = green; 872 this.blue = blue; 873 // interpolate 874 red = Curves.splineInterpolate(red); 875 if (arguments.length == 1) { 876 green = blue = red; 877 } 878 else { 879 green = Curves.splineInterpolate(green); 880 blue = Curves.splineInterpolate(blue); 881 } 882 this.red = red; 883 this.green = green; 884 this.blue = blue; 885 } 886 Curves.prototype.drawCanvas = function (imageData) { 887 var pixels = imageData.data; 888 var amount = this.properties.amount; 889 var r, g, b; 890 for (var i = 0; i < pixels.length; i += 4) { 891 // get color values 892 r = pixels[i] / 255; 893 g = pixels[i + 1] / 255; 894 b = pixels[i + 2] / 255; 895 r = Math.min(1.0, (r * (1 - (0.607 * amount))) + (g * (0.769 * amount)) + (b * (0.189 * amount))); 896 g = Math.min(1.0, (r * 0.349 * amount) + (g * (1 - (0.314 * amount))) + (b * 0.168 * amount)); 897 b = Math.min(1.0, (r * 0.272 * amount) + (g * 0.534 * amount) + (b * (1 - (0.869 * amount)))); 898 // set values 899 pixels[i] = r * 255; 900 pixels[i + 1] = g * 255; 901 pixels[i + 2] = b * 255; 902 } 903 return imageData; 904 }; 905 Curves.splineInterpolate = function (points) { 906 var interpolator = new jsfx.util.SplineInterpolator(points); 907 var array = []; 908 for (var i = 0; i < 256; i++) { 909 array.push(jsfx.Filter.clamp(0, Math.floor(interpolator.interpolate(i / 255) * 256), 255)); 910 } 911 return array; 912 }; 913 return Curves; 914 })(jsfx.Filter); 915 filter.Curves = Curves; 916 })(filter = jsfx.filter || (jsfx.filter = {})); 917})(jsfx || (jsfx = {})); 918var jsfx; 919(function (jsfx) { 920 var filter; 921 (function (filter) { 922 /** 923 * @filter Hue / Saturation
924 * @description Provides rotational hue control. RGB color space 925 * can be imagined as a cube where the axes are the red, green, and blue color 926 * values. Hue changing works by rotating the color vector around the grayscale 927 * line, which is the straight line from black (0, 0, 0) to white (1, 1, 1). 928 * @param hue -1 to 1 (-1 is 180 degree rotation in the negative direction, 0 is no change, 929 * and 1 is 180 degree rotation in the positive direction) 930 */ 931 var Hue = (function (_super) { 932 __extends(Hue, _super); 933 function Hue(hue) { 934 _super.call(this, null, "\n uniform sampler2D texture;\n uniform float hue;\n varying vec2 texCoord;\n\n void main() {\n vec4 color = texture2D(texture, texCoord);\n\n /* hue adjustment, wolfram alpha: RotationTransform[angle, {1, 1, 1}][{x, y, z}] */\n float angle = hue * 3.14159265;\n float s = sin(angle), c = cos(angle);\n vec3 weights = (vec3(2.0 * c, -sqrt(3.0) * s - c, sqrt(3.0) * s - c) + 1.0) / 3.0;\n color.rgb = vec3(\n dot(color.rgb, weights.xyz),\n dot(color.rgb, weights.zxy),\n dot(color.rgb, weights.yzx)\n );\n\n gl_FragColor = color;\n }\n "); 935 // set properties 936 this.properties.hue = jsfx.Filter.clamp(-1, hue, 1) || 0; 937 // pre-calculate data for canvas iteration 938 var angle = hue * 3.14159265; 939 var sin = Math.sin(angle); 940 var cos = Math.cos(angle); 941 this.weights = new jsfx.util.Vector3(2 * cos, -Math.sqrt(3.0) * sin - cos, Math.sqrt(3.0) * sin - cos) 942 .addScalar(1.0) 943 .divideScalar(3.0); 944 } 945 Hue.prototype.iterateCanvas = function (helper) { 946 var rgb = helper.toVector3(); 947 helper.r = rgb.dot(this.weights); 948 helper.g = rgb.dotScalars(this.weights.z, this.weights.x, this.weights.y); 949 helper.b = rgb.dotScalars(this.weights.y, this.weights.z, this.weights.x); 950 }; 951 return Hue; 952 })(jsfx.IterableFilter); 953 filter.Hue = Hue; 954 })(filter = jsfx.filter || (jsfx.filter = {})); 955})(jsfx || (jsfx = {})); 956var jsfx; 957(function (jsfx) { 958 var filter; 959 (function (filter) { 960 /** 961 * @filter Hue / Saturation 962 * @description Provides multiplicative saturation control. RGB color space 963 * can be imagined as a cube where the axes are the red, green, and blue color 964 * values. 965 * Saturation is implemented by scaling all color channel values either toward 966 * or away from the average color channel value. 967 * @param saturation -1 to 1 (-1 is solid gray, 0 is no change, and 1 is maximum contrast) 968 */ 969 var Saturation = (function (_super) { 970 __extends(Saturation, _super); 971 function Saturation(saturation) { 972 _super.call(this, null, "\n uniform sampler2D texture;\n uniform float saturation;\n varying vec2 texCoord;\n\n void main() {\n vec4 color = texture2D(texture, texCoord);\n\n float average = (color.r + color.g + color.b) / 3.0;\n if (saturation > 0.0) {\n color.rgb += (average - color.rgb) * (1.0 - 1.0 / (1.001 - saturation));\n } else {\n color.rgb += (average - color.rgb) * (-saturation);\n }\n\n gl_FragColor = color;\n }\n "); 973 // set properties 974 this.properties.saturation = jsfx.Filter.clamp(-1, saturation, 1) || 0; 975 } 976 Saturation.prototype.iterateCanvas = function (helper) { 977 var saturation = this.properties.saturation; 978 var average = (helper.r + helper.g + helper.b) / 3; 979 if (saturation > 0) { 980 helper.r += (average - helper.r) * (1 - 1 / (1.001 - saturation)); 981 helper.g += (average - helper.g) * (1 - 1 / (1.001 - saturation)); 982 helper.b += (average - helper.b) * (1 - 1 / (1.001 - saturation)); 983 } 984 else { 985 helper.r += (average - helper.r) * (-saturation); 986 helper.g += (average - helper.g) * (-saturation); 987 helper.b += (average - helper.b) * (-saturation); 988 } 989 }; 990 return Saturation; 991 })(jsfx.IterableFilter); 992 filter.Saturation = Saturation; 993 })(filter = jsfx.filter || (jsfx.filter = {})); 994})(jsfx || (jsfx = {})); 995var jsfx; 996(function (jsfx) { 997 var filter; 998 (function (filter) { 999 /** 1000 * @filter Sepia
1001 * @description Gives the image a reddish-brown monochrome tint that imitates an old photograph. 1002 * @param amount 0 to 1 (0 for no effect, 1 for full sepia coloring) 1003 */ 1004 var Sepia = (function (_super) { 1005 __extends(Sepia, _super); 1006 function Sepia(amount) { 1007 _super.call(this, null, "\n uniform sampler2D texture;\n uniform float amount;\n varying vec2 texCoord;\n\n void main() {\n vec4 color = texture2D(texture, texCoord);\n float r = color.r;\n float g = color.g;\n float b = color.b;\n\n color.r = min(1.0, (r * (1.0 - (0.607 * amount))) + (g * (0.769 * amount)) + (b * (0.189 * amount)));\n color.g = min(1.0, (r * 0.349 * amount) + (g * (1.0 - (0.314 * amount))) + (b * 0.168 * amount));\n color.b = min(1.0, (r * 0.272 * amount) + (g * 0.534 * amount) + (b * (1.0 - (0.869 * amount))));\n\n gl_FragColor = color;\n }\n "); 1008 // set properties 1009 this.properties.amount = jsfx.Filter.clamp(-1, amount, 1) || 0; 1010 } 1011 Sepia.prototype.iterateCanvas = function (helper) { 1012 var r = helper.r; 1013 var g = helper.g; 1014 var b = helper.b; 1015 var amount = this.properties.amount; 1016 helper.r = Math.min(1.0, (r * (1.0 - (0.607 * amount))) + (g * (0.769 * amount)) + (b * (0.189 * amount))); 1017 helper.g = Math.min(1.0, (r * 0.349 * amount) + (g * (1.0 - (0.314 * amount))) + (b * 0.168 * amount)); 1018 helper.b = Math.min(1.0, (r * 0.272 * amount) + (g * 0.534 * amount) + (b * (1.0 - (0.869 * amount)))); 1019 }; 1020 return Sepia; 1021 })(jsfx.IterableFilter); 1022 filter.Sepia = Sepia; 1023 })(filter = jsfx.filter || (jsfx.filter = {})); 1024})(jsfx || (jsfx = {})); 1025var jsfx; 1026(function (jsfx) { 1027 var filter; 1028 (function (filter) { 1029 /** 1030 * @filter Unsharp Mask 1031 * @description A form of image sharpening that amplifies high-frequencies in the image. It 1032 * is implemented by scaling pixels away from the average of their neighbors. 1033 * @param radius 0 to 180 - The blur radius that calculates the average of the neighboring pixels. 1034 * @param strength A scale factor where 0 is no effect and higher values cause a stronger effect. 1035 * @note Could potentially be converted to an IterableFilter, but we somehow need the original ImageData 1036 */ 1037 var UnsharpMask = (function (_super) { 1038 __extends(UnsharpMask, _super); 1039 function UnsharpMask(radius, strength) { 1040 _super.call(this, null, "\n uniform sampler2D blurredTexture;\n uniform sampler2D originalTexture;\n uniform float strength;\n uniform float threshold;\n varying vec2 texCoord;\n\n void main() {\n vec4 blurred = texture2D(blurredTexture, texCoord);\n vec4 original = texture2D(originalTexture, texCoord);\n gl_FragColor = mix(blurred, original, 1.0 + strength);\n }\n "); 1041 // set properties 1042 this.properties.radius = radius; 1043 this.properties.strength = strength; 1044 } 1045 UnsharpMask.prototype.drawWebGL = function (renderer) { 1046 var shader = renderer.getShader(this); 1047 var radius = this.properties.radius; 1048 var strength = this.properties.strength; 1049 // create a new texture 1050 var extraTexture = renderer.createTexture(); 1051 // use a texture and draw to it 1052 renderer.getTexture().use(); 1053 extraTexture.drawTo(renderer.getDefaultShader().drawRect.bind(renderer.getDefaultShader())); 1054 // blur current texture 1055 extraTexture.use(1); 1056 // draw the blur 1057 var blur = new filter.Blur(radius); 1058 blur.drawWebGL(renderer); 1059 // use the stored texture to detect edges 1060 shader.textures({ 1061 originalTexture: 1 1062 }); 1063 renderer.getTexture().use(); 1064 renderer.getNextTexture().drawTo(function () { 1065 shader.uniforms({ strength: strength }).drawRect(); 1066 }); 1067 extraTexture.unuse(1); 1068 }; 1069 UnsharpMask.prototype.drawCanvas = function (imageData) { 1070 var pixels = imageData.data; 1071 // props 1072 var radius = this.properties.radius; 1073 var strength = this.properties.strength + 1; 1074 // clone of data 1075 // @todo: declared my own Uint8ClampedArray above since I am having issues with TypeScript.
1076 // additionally, my previous called imageData.data.set(original) (which I also can't here because of TS mapping) 1077 var original = new Uint8ClampedArray(imageData.data); 1078 imageData.data = original; 1079 // blur image 1080 var blur = new filter.Blur(radius); 1081 blur.drawCanvas(imageData); 1082 // trying to replicate mix() from webgl, which is basically x * (1 -a) 1083 for (var i = 0; i < pixels.length; i += 4) { 1084 pixels[i] = pixels[i] * (1 - strength) + original[i] * strength; 1085 pixels[i + 1] = pixels[i + 1] * (1 - strength) + original[i + 1] * strength; 1086 pixels[i + 2] = pixels[i + 2] * (1 - strength) + original[i + 2] * strength; 1087 } 1088 return imageData; 1089 }; 1090 return UnsharpMask; 1091 })(jsfx.Filter); 1092 filter.UnsharpMask = UnsharpMask; 1093 })(filter = jsfx.filter || (jsfx.filter = {})); 1094})(jsfx || (jsfx = {})); 1095var jsfx; 1096(function (jsfx) { 1097 var util; 1098 (function (util) { 1099 var ImageDataHelper = (function () { 1100 function ImageDataHelper(imageData, index) { 1101 this.imageData = imageData; 1102 this.index = index; 1103 this.r = this.imageData.data[index] / 255; 1104 this.g = this.imageData.data[index + 1] / 255; 1105 this.b = this.imageData.data[index + 2] / 255; 1106 this.a = this.imageData.data[index + 3] / 255; 1107 } 1108 ImageDataHelper.prototype.getImageData = function () { 1109 return this.imageData; 1110 }; 1111 ImageDataHelper.prototype.save = function () { 1112 this.imageData.data[this.index] = this.r * 255; 1113 this.imageData.data[this.index + 1] = this.g * 255; 1114 this.imageData.data[this.index + 2] = this.b * 255; 1115 this.imageData.data[this.index + 3] = this.a * 255; 1116 }; 1117 ImageDataHelper.prototype.toVector3 = function () { 1118 return new jsfx.util.Vector3(this.r, this.g, this.b); 1119 }; 1120 ImageDataHelper.prototype.fromVector3 = function (v) { 1121 this.r = v.x; 1122 this.g = v.y; 1123 this.b = v.z; 1124 }; 1125 return ImageDataHelper; 1126 })(); 1127 util.ImageDataHelper = ImageDataHelper; 1128 })(util = jsfx.util || (jsfx.util = {})); 1129})(jsfx || (jsfx = {})); 1130var jsfx; 1131(function (jsfx) { 1132 var util; 1133 (function (util) { 1134 /** 1135 * From SplineInterpolator.cs in the Paint.NET source code 1136 */ 1137 var SplineInterpolator = (function () { 1138 function SplineInterpolator(points) { 1139 this.points = points; 1140 var n = points.length; 1141 var i; 1142 this.xa = []; 1143 this.ya = []; 1144 this.u = []; 1145 this.y2 = []; 1146 points.sort(function (a, b) { 1147 return a[0] - b[0]; 1148 }); 1149 for (i = 0; i < n; i++) { 1150 this.xa.push(points[i][0]); 1151 this.ya.push(points[i][1]); 1152 } 1153 this.u[0] = 0; 1154 this.y2[0] = 0; 1155 for (i = 1; i < n - 1; ++i) { 1156 // This is the decomposition loop of the tri-diagonal algorithm. 1157 // y2 and u are used for temporary storage of the decomposed factors. 1158 var wx = this.xa[i + 1] - this.xa[i - 1]; 1159 var sig = (this.xa[i] - this.xa[i - 1]) / wx; 1160 var p = sig * this.y2[i - 1] + 2.0; 1161 this.y2[i] = (sig - 1.0) / p; 1162 var ddydx = (this.ya[i + 1] - this.ya[i]) / (this.xa[i + 1] - this.xa[i]) - 1163 (this.ya[i] - this.ya[i - 1]) / (this.xa[i] - this.xa[i - 1]); 1164 this.u[i] = (6.0 * ddydx / wx - sig * this.u[i - 1]) / p; 1165 } 1166 this.y2[n - 1] = 0; 1167 // This is the back-substitution loop of the tri-diagonal algorithm 1168 for (i = n - 2; i >= 0; --i) { 1169 this.y2[i] = this.y2[i] * this.y2[i + 1] + this.u[i]; 1170 } 1171 } 1172 SplineInterpolator.prototype.interpolate = function (x) { 1173 var n = this.ya.length; 1174 var klo = 0; 1175 var khi = n - 1; 1176 // We will find the right place in the table by means of 1177 // bisection. This is optimal if sequential calls to this 1178 // routine are at random values of x. If sequential calls 1179 // are in order, and closely spaced, one would do better 1180 // to store previous values of klo and khi. 1181 while (khi - klo > 1) { 1182 var k = (khi + klo) >> 1; 1183 if (this.xa[k] > x) { 1184 khi = k; 1185 } 1186 else { 1187 klo = k; 1188 } 1189 } 1190 var h = this.xa[khi] - this.xa[klo]; 1191 var a = (this.xa[khi] - x) / h; 1192 var b = (x - this.xa[klo]) / h; 1193 // Cubic spline polynomial is now evaluated.
1194 return a * this.ya[klo] + b * this.ya[khi] + 1195 ((a * a * a - a) * this.y2[klo] + (b * b * b - b) * this.y2[khi]) * (h * h) / 6.0; 1196 }; 1197 return SplineInterpolator; 1198 })(); 1199 util.SplineInterpolator = SplineInterpolator; 1200 })(util = jsfx.util || (jsfx.util = {})); 1201})(jsfx || (jsfx = {})); 1202/** 1203 * Vector3 Utility Class 1204 * -> Taken from https://github.com/mrdoob/three.js/blob/master/src/math/Vector3.js with only the functions we need. 1205 */ 1206var jsfx; 1207(function (jsfx) { 1208 var util; 1209 (function (util) { 1210 var Vector3 = (function () { 1211 function Vector3(x, y, z) { 1212 this.x = x; 1213 this.y = y; 1214 this.z = z; 1215 } 1216 Vector3.prototype.addScalar = function (s) { 1217 this.x += s; 1218 this.y += s; 1219 this.z += s; 1220 return this; 1221 }; 1222 Vector3.prototype.multiplyScalar = function (s) { 1223 this.x *= s; 1224 this.y *= s; 1225 this.z *= s; 1226 return this; 1227 }; 1228 Vector3.prototype.divideScalar = function (s) { 1229 if (s !== 0) { 1230 var invScalar = 1 / s; 1231 this.x *= invScalar; 1232 this.y *= invScalar; 1233 this.z *= invScalar; 1234 } 1235 else { 1236 this.x = 0; 1237 this.y = 0; 1238 this.z = 0; 1239 } 1240 return this; 1241 }; 1242 Vector3.prototype.length = function () { 1243 return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); 1244 }; 1245 Vector3.prototype.dot = function (v) { 1246 return this.x * v.x + this.y * v.y + this.z * v.z; 1247 }; 1248 Vector3.prototype.dotScalars = function (x, y, z) { 1249 return this.x * x + this.y * y + this.z * z; 1250 }; 1251 return Vector3; 1252 })(); 1253 util.Vector3 = Vector3; 1254 })(util = jsfx.util || (jsfx.util = {})); 1255})(jsfx || (jsfx = {})); 1256var jsfx; 1257(function (jsfx) { 1258 var webgl; 1259 (function (webgl) { 1260 var Renderer = (function () {
1261 function Renderer() { 1262 this.canvas = document.createElement("canvas"); 1263 this.gl = this.canvas.getContext("experimental-webgl", { premultipliedAlpha: false }); 1264 this.gl.pixelStorei(this.gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 1); 1265 // variables to store the source 1266 this.source = null; 1267 this.sourceTexture = null; 1268 // store the textures and buffers 1269 this.textures = null; 1270 this.currentTexture = 0; 1271 // initialize a shader cache 1272 this.gl.shaderCache = {}; 1273 } 1274 Renderer.prototype.setSource = function (source) { 1275 // first, clean up 1276 if (this.source) { 1277 this.cleanUp(); 1278 } 1279 // re-initialize renderer for rendering with new source 1280 this.source = source; 1281 this.sourceTexture = jsfx.webgl.Texture.fromElement(this.gl, source.element); 1282 // initialize the renderer textures 1283 this.initialize(); 1284 // draw the source texture onto the first texture 1285 this.sourceTexture.use(); 1286 this.getTexture().drawTo(this.getDefaultShader().drawRect.bind(this.getDefaultShader())); 1287 return this; 1288 }; 1289 Renderer.prototype.getSource = function () { 1290 return this.source; 1291 }; 1292 Renderer.prototype.applyFilter = function (filter) { 1293 filter.drawWebGL(this); 1294 return this; 1295 }; 1296 Renderer.prototype.applyFilters = function (filters) { 1297 var _this = this; 1298 filters.forEach(function (filter) { 1299 filter.drawWebGL(_this); 1300 }); 1301 return this; 1302 }; 1303 Renderer.prototype.render = function () { 1304 this.getTexture().use(); 1305 this.getFlippedShader().drawRect(); 1306 }; 1307 Renderer.prototype.getCanvas = function () { 1308 return this.canvas; 1309 }; 1310 Renderer.prototype.getTexture = function () { 1311 return this.textures[this.currentTexture % 2]; 1312 }; 1313 Renderer.prototype.getNextTexture = function () { 1314 return this.textures[++this.currentTexture % 2]; 1315 }; 1316 Renderer.prototype.createTexture = function () { 1317 return new jsfx.webgl.Texture(this.gl, this.source.width, this.source.height, this.gl.RGBA, this.gl.UNSIGNED_BYTE); 1318 }; 1319 Renderer.prototype.getShader = function (filter) { 1320 var cacheKey = filter.getVertexSource() + filter.getFragmentSource(); 1321 return this.gl.shaderCache.hasOwnProperty(cacheKey) ? 1322 this.gl.shaderCache[cacheKey] : 1323 new jsfx.webgl.Shader(this.gl, filter.getVertexSource(), filter.getFragmentSource()); 1324 }; 1325 Renderer.prototype.getDefaultShader = function () { 1326 if (!this.gl.shaderCache.def) { 1327 this.gl.shaderCache.def = new jsfx.webgl.Shader(this.gl); 1328 } 1329 return this.gl.shaderCache.def; 1330 }; 1331 Renderer.prototype.getFlippedShader = function () { 1332 if (!this.gl.shaderCache.flipped) { 1333 this.gl.shaderCache.flipped = new jsfx.webgl.Shader(this.gl, null, "\n uniform sampler2D texture;\n varying vec2 texCoord;\n\n void main() {\n gl_FragColor = texture2D(texture, vec2(texCoord.x, 1.0 - texCoord.y));\n }\n "); 1334 } 1335 return this.gl.shaderCache.flipped; 1336 }; 1337 Renderer.prototype.initialize = function () { 1338 this.canvas.width = this.source.width; 1339 this.canvas.height = this.source.height; 1340 // initialize the textures 1341 var textures = []; 1342 for (var i = 0; i < 2; i++) { 1343 textures.push(this.createTexture()); 1344 } 1345 this.textures = textures; 1346 }; 1347 Renderer.prototype.cleanUp = function () { 1348 // destroy source texture 1349 this.sourceTexture.destroy(); 1350 // destroy textures used for filters 1351 for (var i = 0; i < 2; i++) { 1352 this.textures[i].destroy(); 1353 } 1354 // re-set textures 1355 this.textures = null; 1356 }; 1357 return Renderer; 1358 })(); 1359 webgl.Renderer = Renderer; 1360 })(webgl = jsfx.webgl || (jsfx.webgl = {})); 1361})(jsfx || (jsfx = {})); 1362var jsfx; 1363(function (jsfx) { 1364 var webgl; 1365 (function (webgl) { 1366 var Shader = (function () { 1367 function Shader(gl, vertexSource, fragmentSource) { 1368 this.gl = gl; 1369 // get the shader source 1370 this.vertexSource = vertexSource || Shader.defaultVertexSource; 1371 this.fragmentSource = fragmentSource || Shader.defaultFragmentSource; 1372 // set precision 1373 this.fragmentSource = "precision highp float;" + this.fragmentSource; 1374 // init vars 1375 this.vertexAttribute = null; 1376 this.texCoordAttribute = null; 1377 // create the program 1378 this.program = gl.createProgram(); 1379 // attach the shaders 1380 gl.attachShader(this.program, compileSource(gl, gl.VERTEX_SHADER, this.vertexSource)); 1381 gl.attachShader(this.program, compileSource(gl, gl.FRAGMENT_SHADER, this.fragmentSource)); 1382 // link the program and ensure it worked 1383 gl.linkProgram(this.program); 1384 if (!gl.getProgramParameter(this.program, gl.LINK_STATUS)) { 1385 throw "link error: " + gl.getProgramInfoLog(this.program); 1386 } 1387 } 1388 /** 1389 * textures are uniforms too but for some reason can't be specified by this.gl.uniform1f, 1390 * even though floating point numbers represent the integers 0 through 7 exactly 1391 * 1392 * @param textures 1393 * @returns {Shader} 1394 */ 1395 Shader.prototype.textures = function (textures) { 1396 this.gl.useProgram(this.program); 1397 for (var name in textures) { 1398 if (!textures.hasOwnProperty(name)) { 1399 continue; 1400 } 1401 this.gl.uniform1i(this.gl.getUniformLocation(this.program, name), textures[name]); 1402 } 1403 return this; 1404 }; 1405 Shader.prototype.uniforms = function (uniforms) { 1406 this.gl.useProgram(this.program); 1407 for (var name in uniforms) { 1408 if (!uniforms.hasOwnProperty(name)) { 1409 continue; 1410 } 1411 var location = this.gl.getUniformLocation(this.program, name); 1412 if (location === null) { 1413 // will be null if the uniform isn't used in the shader 1414 continue; 1415 } 1416 var value = uniforms[name]; 1417 if (isArray(value)) { 1418 switch (value.length) { 1419 case 1: 1420 this.gl.uniform1fv(location, new Float32Array(value)); 1421 break; 1422 case 2: 1423 this.gl.uniform2fv(location, new Float32Array(value)); 1424 break; 1425 case 3: 1426 this.gl.uniform3fv(location, new Float32Array(value)); 1427 break; 1428 case 4: 1429 this.gl.uniform4fv(location, new Float32Array(value)); 1430 break; 1431 case 9: 1432 this.gl.uniformMatrix3fv(location, false, new Float32Array(value)); 1433 break; 1434 case 16: 1435 this.gl.uniformMatrix4fv(location, false, new Float32Array(value)); 1436 break; 1437 default: 1438 throw "dont't know how to load uniform \"" + name + "\" of length " + value.length; 1439 } 1440 } 1441 else if (isNumber(value)) { 1442 this.gl.uniform1f(location, value); 1443 } 1444 else { 1445 throw "attempted to set uniform \"" + name + "\" to invali
1445d value " + (value || "undefined").toString(); 1446 } 1447 } 1448 return this; 1449 }; 1450 Shader.prototype.drawRect = function (left, top, right, bottom) { 1451 var undefined; 1452 var viewport = this.gl.getParameter(this.gl.VIEWPORT); 1453 top = top !== undefined ? (top - viewport[1]) / viewport[3] : 0; 1454 left = left !== undefined ? (left - viewport[0]) / viewport[2] : 0; 1455 right = right !== undefined ? (right - viewport[0]) / viewport[2] : 1; 1456 bottom = bottom !== undefined ? (bottom - viewport[1]) / viewport[3] : 1; 1457 if (!this.gl.vertexBuffer) { 1458 this.gl.vertexBuffer = this.gl.createBuffer(); 1459 } 1460 this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.gl.vertexBuffer); 1461 this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array([left, top, left, bottom, right, top, right, bottom]), this.gl.STATIC_DRAW); 1462 if (!this.gl.texCoordBuffer) { 1463 this.gl.texCoordBuffer = this.gl.createBuffer(); 1464 this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.gl.texCoordBuffer); 1465 this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array([0, 0, 0, 1, 1, 0, 1, 1]), this.gl.STATIC_DRAW); 1466 } 1467 if (this.vertexAttribute == null) { 1468 this.vertexAttribute = this.gl.getAttribLocation(this.program, "vertex"); 1469 this.gl.enableVertexAttribArray(this.vertexAttribute); 1470 } 1471 if (this.texCoordAttribute == null) { 1472 this.texCoordAttribute = this.gl.getAttribLocation(this.program, "_texCoord"); 1473 this.gl.enableVertexAttribArray(this.texCoordAttribute); 1474 } 1475 this.gl.useProgram(this.program); 1476 this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.gl.vertexBuffer); 1477 this.gl.vertexAttribPointer(this.vertexAttribute, 2, this.gl.FLOAT, false, 0, 0); 1478 this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.gl.texCoordBuffer); 1479 this.gl.vertexAttribPointer(this.texCoordAttribute, 2, this.gl.FLOAT, false, 0, 0); 1480 this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4); 1481 }; 1482 Shader.prototype.destroy = function () { 1483 this.gl.deleteProgram(this.program); 1484 this.program = null; 1485 }; 1486 Shader.defaultVertexSource = "\nattribute vec2 vertex;\nattribute vec2 _texCoord;\nvarying vec2 texCoord;\n\nvoid main() {\n texCoord = _texCoord;\n gl_Position = vec4(vertex * 2.0 - 1.0, 0.0, 1.0);\n}"; 1487 Shader.defaultFragmentSource = "\nuniform sampler2D texture;\nvarying vec2 texCoord;\n\nvoid main() {\n gl_FragColor = texture2D(texture, texCoord);\n}"; 1488 return Shader; 1489 })(); 1490 webgl.Shader = Shader; 1491 function compileSource(gl, type, source) { 1492 var shader = gl.createShader(type); 1493 gl.shaderSource(shader, source); 1494 gl.compileShader(shader); 1495 if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { 1496 throw "compile error: " + gl.getShaderInfoLog(shader); 1497 } 1498 return shader; 1499 } 1500 function isArray(obj) { 1501 return Object.prototype.toString.call(obj) === "[object Array]"; 1502 } 1503 function isNumber(obj) { 1504 return Object.prototype.toString.call(obj) === "[object Number]"; 1505 } 1506 })(webgl = jsfx.webgl || (jsfx.webgl = {})); 1507})(jsfx || (jsfx = {})); 1508var jsfx; 1509(function (jsfx) { 1510 var webgl; 1511 (function (webgl) { 1512 var Texture = (function () { 1513 function Texture(gl, width, height, format, type) { 1514 if (format === void 0) { format = gl.RGBA; } 1515 if (type === void 0) { type = gl.UNSIGNED_BYTE; } 1516 this.gl = gl; 1517 this.width = width; 1518 this.height = height; 1519 this.format = format; 1520 this.type = type; 1521 this.id = gl.createTexture(); 1522 this.element = null; 1523 gl.bindTexture(gl.TEXTURE_2D, this.id); 1524 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); 1525 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); 1526 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 1527 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 1528 if (width && height) { 1529 gl.texImage2D(gl.TEXTURE_2D, 0, this.format, width, height, 0, this.format, this.type, null); 1530 } 1531 } 1532 Texture.prototype.loadContentsOf = function (element) { 1533 this.element = element; 1534 this.width = element.width; 1535 this.height = element.height; 1536 this.gl.bindTexture(this.gl.TEXTURE_2D, this.id); 1537 this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.format, this.format, this.type, element); 1538 }; 1539 Texture.prototype.initFromBytes = function (width, height, data) { 1540 this.width = width; 1541 this.height = height; 1542 this.format = this.gl.RGBA; 1543 this.type = this.gl.UNSIGNED_BYTE; 1544 this.gl.bindTexture(this.gl.TEXTURE_2D, this.id); 1545 this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, width, height, 0, this.gl.RGBA, this.type, new Uint8Array(data)); 1546 }; 1547 Texture.prototype.use = function (unit) { 1548 this.gl.activeTexture(this.gl.TEXTURE0 + (unit || 0)); 1549 this.gl.bindTexture(this.gl.TEXTURE_2D, this.id); 1550 }; 1551 Texture.prototype.unuse = function (unit) { 1552 this.gl.activeTexture(this.gl.TEXTURE0 + (unit || 0)); 1553 this.gl.bindTexture(this.gl.TEXTURE_2D, null); 1554 }; 1555 Texture.prototype.drawTo = function (callback) { 1556 // create and bind frame buffer 1557 this.gl.frameBuffer = this.gl.frameBuffer || this.gl.createFramebuffer(); 1558 this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.gl.frameBuffer); 1559 this.gl.framebufferTexture2D(this.gl.FRAMEBUFFER, this.gl.COLOR_ATTACHMENT0, this.gl.TEXTURE_2D, this.id, 0); 1560 // ensure there was no error 1561 if (this.gl.checkFramebufferStatus(this.gl.FRAMEBUFFER) !== this.gl.FRAMEBUFFER_COMPLETE) { 1562 throw new Error("incomplete framebuffer"); 1563 } 1564 // set the viewport 1565 this.gl.viewport(0, 0, this.width, this.height); 1566 // do the drawing 1567 callback(); 1568 // stop rendering to this texture 1569 this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null); 1570 }; 1571 Texture.prototype.destroy = function () {
1572 this.gl.deleteTexture(this.id); 1573 this.id = null; 1574 }; 1575 Texture.fromElement = function (gl, element) { 1576 var texture = new Texture(gl, 0, 0); 1577 texture.loadContentsOf(element); 1578 return texture; 1579 }; 1580 return Texture; 1581 })(); 1582 webgl.Texture = Texture; 1583 })(webgl = jsfx.webgl || (jsfx.webgl = {})); 1584})(jsfx || (jsfx = {})); 1585 1586module.exports = jsfx; 1587 1588}).call(this,require("buffer").Buffer) 1589 1590},{"buffer":8}],3:[function(require,module,exports){ 1591var Emitter = require('./emitter'); 1592 1593function Dropzone(el) { 1594 var self = this; 1595 var input = document.createElement('input'); 1596 input.setAttribute('type', 'file'); 1597 input.setAttribute('multiple', true); 1598 input.style.display = 'none'; 1599 input.addEventListener('change', function(e) { 1600 self.onFile_(e); 1601 }); 1602 el.appendChild(input); 1603 1604 el.addEventListener('dragover', function(e) { 1605 e.preventDefault(); 1606 e.stopPropagation(); 1607 el.classList.add('dragover'); 1608 }); 1609 1610 el.addEventListener('dragleave', function(e) { 1611 e.preventDefault(); 1612 e.stopPropagation(); 1613 el.classList.remove('dragover'); 1614 }); 1615 1616 el.addEventListener('drop', function(e) { 1617 file = self.getFile_(e); 1618 e.preventDefault(); 1619 e.stopPropagation(); 1620 el.classList.remove('dragover'); 1621 if (file) { 1622 self.onFile_(e); 1623 } 1624 }); 1625 1626 el.addEventListener('click', function() { 1627 // TODO: Figure out about re-enabling click to upload. 1628 //input.value = null; 1629 //input.click(); 1630 }); 1631} 1632 1633Dropzone.prototype = new Emitter(); 1634 1635Dropzone.prototype.getFile_ = function(e) { 1636 var files; 1637 if (e.dataTransfer) { 1638 files = e.dataTransfer.files; 1639 } else if(e.target) { 1640 files = e.target.files; 1641 } 1642 1643 if (files.length > 1) { 1644 this.emit('error', 'Multiple files dropped. Please convert one at a time.'); 1645 return null; 1646 } else { 1647 // Just take the first file. 1648 return files[0]; 1649 } 1650}; 1651 1652Dropzone.prototype.onFile_ = function(e) { 1653 var file = this.getFile_(e); 1654 if (!file.name.endsWith('jpg')) { 1655 this.emit('error', 'Dropped file must have the .jpg extension'); 1656 } else { 1657 this.emit('file', file); 1658 } 1659}; 1660 1661module.exports = Dropzone; 1662 1663},{"./emitter":4}],4:[function(require,module,exports){ 1664/* 1665 * Copyright 2015 Google Inc. All Rights Reserved. 1666 * Licensed under the Apache License, Version 2.0 (the "License"); 1667 * you may not use this file except in compliance with the License. 1668 * You may obtain a copy of the License at 1669 * 1670 * http://www.apache.org/licenses/LICENSE-2.0 1671 * 1672 * Unless required by applicable law or agreed to in writing, software 1673 * distributed under the License is distributed on an "AS IS" BASIS, 1674 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1675 * See the License for the specific language governing permissions and 1676 * limitations under the License. 1677 */ 1678 1679 1680function Emitter() { 1681 this.initEmitter(); 1682} 1683 1684Emitter.prototype.initEmitter = function() { 1685 this.callbacks = {}; 1686}; 1687 1688Emitter.prototype.emit = function(eventName) { 1689 var callbacks = this.callbacks[eventName]; 1690 if (!callbacks) { 1691 console.log('No valid callback specified.'); 1692 return; 1693 } 1694 var args = [].slice.call(arguments) 1695 // Eliminate the first param (the callback). 1696 args.shift(); 1697 for (var i = 0; i < callbacks.length; i++) { 1698 callbacks[i].apply(this, args); 1699 } 1700}; 1701 1702Emitter.prototype.on = function(eventName, callback) { 1703 if (eventName in this.callbacks) { 1704 var cbs = this.callbacks[eventName] 1705 if (cbs.indexOf(callback) == -1) { 1706 cbs.push(callback); 1707 } 1708 } else { 1709 this.callbacks[eventName] = [callback]; 1710 } 1711}; 1712 1713Emitter.prototype.removeListener = function(eventName, callback) { 1714 if (!(eventName in this.callbacks)) { 1715 return; 1716 } 1717 var cbs = this.callbacks[eventName]; 1718 var ind = cbs.indexOf(callback); 1719 if (ind == -1) { 1720 console.warn('No matching callback found'); 1721 return; 1722 } 1723 cbs.splice(ind, 1); 1724}; 1725 1726module.exports = Emitter; 1727 1728},{}],5:[function(require,module,exports){ 1729var OdsConverter = require('./ods-converter'); 1730var Dropzone = require('./dropzone'); 1731 1732 1733//var Target_Resolution = parseInt(document.getElementById("Target_Res").valueAsNumber); 1734//var TARGET_SIZE = Target_Resolution; 1735 1736var dz = document.querySelector('#dropzone'); 1737var dropzone = new Dropzone(dz); 1738dropzone.on('file', onFileDropped); 1739dropzone.on('error', onDropError); 1740 1741converter = new OdsConverter(); 1742converter.on('convert', onOdsConverted); 1743converter.on('error', onOdsConversionError); 1744 1745// Make all dialogs disappear if clicked out of. 1746dz.addEventListener('click', function(e) { 1747 if (e.target.nodeName.toLowerCase() == 'dialog') { 1748 if (dialog.open) { 1749 dialog.close(); 1750 } 1751 } 1752}); 1753 1754// Hook up the open file link. 1755document.querySelector('#openfile').addEventListener('click', onOpenClicked); 1756 1757var filename; 1758 1759function onFileDropped(file) { 1760 // Show a new dialog. 1761 showDialog('progress'); 1762 1763 console.log('onFileDropped', file.name); 1764 filename = file.name; 1765 1766 var reader = new FileReader(); 1767 reader.onload = function(e) { 1768 var arrayBuffer = reader.result; 1769 // Kick off the conversion process. 1770 converter.convert(arrayBuffer); 1771 } 1772 1773 reader.readAsArrayBuffer(file); 1774} 1775 1776function onOdsConverted(canvas, audio) { 1777 console.log('onOdsConverted, %s x %s', canvas.width, canvas.height); 1778 1779 canvas.toBlob(function(blob) { 1780 var dlImage = document.querySelector('#dl-image'); 1781 dlImage.disabled = false;
1782 dlImage.addEventListener('click', onImageClick); 1783 function onImageClick() { 1784 createLink(URL.createObjectURL(blob), getConvertedFilename(filename)).click(); 1785 dlImage.removeEventListener('click', onImageClick); 1786 } 1787 1788 var dlAudio = document.querySelector('#dl-audio'); 1789 dlAudio.disabled = false; 1790 dlAudio.addEventListener('click', onAudioClick); 1791 function onAudioClick() { 1792 createLink(audio, getConvertedFilename(filename, '.mp4')).click(); 1793 dlAudio.removeEventListener('click', onAudioClick); 1794 } 1795 1796 showDialog('success'); 1797 }, 'image/jpeg'); 1798 1799} 1800 1801function createLink(url, filename) { 1802 var link = document.createElement('a'); 1803 link.download = filename; 1804 link.href = url; 1805 return link; 1806} 1807 1808function onOdsConversionError(error) { 1809 console.log('onOdsConversionError', error); 1810 showDialog('fail') 1811 setErrorMessage('Conversion error: ' + error); 1812} 1813 1814function onDropError(error) { 1815 console.log('onDropError', error); 1816 showDialog('fail') 1817 setErrorMessage('Drop error: ' + error); 1818} 1819 1820function getConvertedFilename(filename, opt_ext) { 1821 var extIndex = filename.lastIndexOf('.'); 1822 var basename = filename.substring(0, extIndex); 1823 var ext = opt_ext || filename.substring(extIndex); 1824 return basename + '-converted' + ext; 1825} 1826 1827function showDialog(id) { 1828 // Close previously open dialog (if it exists). 1829 if (window.dialog && dialog.open) { 1830 dialog.close(); 1831 } 1832 dialog = document.querySelector('#' + id); 1833 dialog.showModal(); 1834} 1835 1836function setErrorMessage(errorMessage) { 1837 var error = document.querySelector('#error'); 1838 error.innerHTML = errorMessage; 1839} 1840 1841function onOpenClicked(e) { 1842 var input = document.createElement('input'); 1843 input.type = 'file'; 1844 input.click(); 1845 input.addEventListener('change', onFilePicked); 1846} 1847 1848function onFilePicked(e) { 1849 // TODO: Validation. 1850 var file = e.path[0].files[0]; 1851 onFileDropped(file); 1852}; 1853 1854},{"./dropzone":3,"./ods-converter":6}],6:[function(require,module,exports){ 1855var EventEmitter3 = require('eventemitter3'); 1856var jsfx = require('jsfx'); 1857 1858 1859var startParsing; 1860 1861var width = 640; 1862 1863var M_SOI = 0xd8; 1864var M_APP1 = 0xe1; 1865var M_SOS = 0xda; 1866 1867var XMP_SIGNATURE = 'http://ns.adobe.com/xap/1.0/'; 1868var EXTENSTION_SIGNATURE = 'http://ns.adobe.com/xmp/extension/'; 1869var EXT_PREFIX_LENGTH = 71; 1870 1871//var Target_Resolution = parseInt(document.getElementById("Target_Res").valueAsNumber); 1872//var TARGET_SIZE = Target_Resolution; 1873var TARGET_SIZE; 1874function OdsConverter() { 1875 this.lastWidth = null; 1876} 1877 1878OdsConverter.prototype = new EventEmitter3(); 1879 1880OdsConverter.prototype.convert = function(arrayBuffer) { 1881 this.decode_(arrayBuffer); 1882}; 1883 1884/** 1885 * Given the last converted Cardboard Camera image, this method returns the 1886 * best pow-of-two width for the image. 1887 */ 1888OdsConverter.prototype.getOptimalWidth = function() { 1889 if (!this.lastWidth) { 1890 return -1; 1891 } 1892 return Math.ceil(Math.log(this.lastWidth)/Math.log(2)) 1893}; 1894 1895OdsConverter.prototype.decode_ = function(arrayBuffer) { 1896 var scope = this; 1897 1898 if (!arrayBuffer) { 1899 return; 1900 } 1901 startParsing = Date.now(); 1902 console.log('Started parsing'); 1903 var bytes = new Uint8Array(arrayBuffer); 1904 var doc = extractXMP(bytes, function(e) { 1905 scope.emit('error', e); 1906 }); 1907 if (!doc) { 1908 // No valid doc, so we quit. 1909 return; 1910 } 1911 var gPano = getObjectMeta(doc, 'GPano'); 1912 var gImage = getObjectMeta(doc, 'GImage'); 1913 var gAudio = getObjectMeta(doc, 'GAudio'); 1914 var image = makeImageFromBinary('image/jpeg', bytes); 1915 var audio = makeAudio(gAudio.Mime, gAudio.Data); 1916 1917 image.onload = function () { 1918 this.setupScene_(gPano, gImage, image, audio); 1919 }.bind(this); 1920 1921} 1922 1923OdsConverter.prototype.setupScene_ = function(gPano, gImage, leftImage, audio) { 1924 // Ensure the right image is valid. 1925 if (!gImage.Mime || !gImage.Data) { 1926 this.emit('error', 'No valid right eye image found in the XMP metadata. This might not be a valid Cardboard Camera image.'); 1927 return; 1928 } 1929 1930 var rightImage = makeImage(gImage.Mime, gImage.Data); 1931 rightImage.onload = function () { 1932 console.log('Parsing took ' + (Date.now() - startParsing) + ' ms');
1933 this.buildImage_(leftImage, rightImage, gPano, audio); 1934 }.bind(this); 1935} 1936 1937OdsConverter.prototype.buildImage_ = function(leftImage, rightImage, gPano, audio) { 1938 var fullWidth = parseInt(gPano['FullPanoWidthPixels']); 1939 var cropLeft = parseInt(gPano['CroppedAreaLeftPixels']); 1940 var cropTop = parseInt(gPano['CroppedAreaTopPixels']); 1941 var cropWidth = parseInt(gPano['CroppedAreaImageWidthPixels']); 1942 var initialHeadingDeg = parseInt(gPano['InitialViewHeadingDegrees']); 1943 TARGET_SIZE = fullWidth; 1944 var ratio = TARGET_SIZE / fullWidth; 1945 1946 // Handle partial panos. 1947 var scaleWidth = 1; 1948 if (cropWidth != fullWidth) { 1949 scaleWidth = cropWidth / fullWidth; 1950 } 1951 1952 // A canvas for the over-under rendering. 1953 var canvas = document.createElement('canvas'); 1954 canvas.width = TARGET_SIZE; 1955 canvas.height = TARGET_SIZE; 1956 1957 // Scaled dimensions for left and right eye images. 1958 var imageWidth = TARGET_SIZE * scaleWidth; 1959 var imageHeight = leftImage.height * ratio; 1960 1961 // Save the original size of the most recently converted image. 1962 this.lastWidth = canvas.width; 1963 1964 // Offsets for where to render each image. For partial panos (ie. imageWidth < 1965 // TARGET_SIZE), render the image centered. 1966 var offsetX = (TARGET_SIZE - imageWidth) / 2; 1967 var x = Math.floor(cropLeft * ratio) + offsetX; 1968 var y = Math.floor(cropTop * ratio); 1969 var ctx = canvas.getContext('2d'); 1970 1971 // Clear the canvas. 1972 ctx.fillStyle = '#000'; 1973 ctx.fillRect(0, 0, canvas.width, canvas.height); 1974 1975 // Draw the left and right images onto the canvas. 1976 ctx.drawImage(leftImage, x, y, imageWidth, imageHeight); 1977 ctx.drawImage(rightImage, x, y + canvas.height/2, imageWidth, imageHeight); 1978 1979 var halfHeight = Math.floor(canvas.height / 2); 1980 // Offsets are the offsets for each eye. 1981 var offsets = [0, halfHeight]; 1982 1983 // Calculate how much to blur the image. 1984 var blurRadius = imageHeight / 2; 1985 1986 for (var i = 0; i < offsets.length; i++) { 1987 var offset = offsets[i]; 1988 1989 // Calculate the dimensions of the actual image. 1990 var top = offset + y; 1991 var bottom = offset + y + imageHeight - 1; 1992 1993 // Repeat the top part. 1994 repeatImage(canvas, top, offset); 1995 1996 // Repeat the bottom part. 1997 repeatImage(canvas, bottom, offset + halfHeight); 1998 } 1999 2000 2001 var buffer = document.createElement('canvas'); 2002 var b_ctx = buffer.getContext('2d'); 2003 buffer.width = 4569; 2004 buffer.height = 4569; 2005 2006 resample_single(canvas, 4569, 4569, true); 2007 2008 b_ctx.drawImage(canvas, 0, 0, 4569, 4569, 2009 0, 0, buffer.width, buffer.height); 2010 var blurCanvas = blurImage(buffer, blurRadius); 2011 ctx.drawImage(blurCanvas, 0, 0, 4569, 4569); 2012 2013 2014 resample_single(canvas, TARGET_SIZE, TARGET_SIZE, true); 2015 2016 2017 /* 2018 b_ctx.fillStyle = '#000'; 2019 b_ctx.fillRect(0, 0, buffer.width, buffer.height); 2020 2021 b_ctx.drawImage(canvas, 4569, 0, 4569, 4569, 2022 0, 0, buffer.width, buffer.height); 2023 blurCanvas = blurImage(buffer, blurRadius); 2024 ctx.drawImage(blurCanvas, 4569, 0); 2025 2026 b_ctx.fillStyle = '#000'; 2027 b_ctx.fillRect(0, 0, buffer.width, buffer.height); 2028 2029 b_ctx.drawImage(canvas, 4569, 4569, 4569, 4569, 2030 0, 0, buffer.width, buffer.height); 2031 blurCanvas = blurImage(buffer, blurRadius); 2032 ctx.drawImage(blurCanvas, 4569, 4569); 2033 2034 b_ctx.fillStyle = '#000'; 2035 b_ctx.fillRect(0, 0, buffer.width, buffer.height); 2036 2037 b_ctx.drawImage(canvas, 0, 4569, 4569, 4569, 2038 0, 0, buffer.width, buffer.height); 2039 blurCanvas = blurImage(buffer, blurRadius); 2040 ctx.drawImage(blurCanvas, 0, 4569); 2041 */ 2042 2043 // Re-render the images themselves. 2044 //Test 2045 ctx.drawImage(leftImage, x, y, imageWidth, imageHeight); 2046 ctx.drawImage(rightImage, x, y + canvas.height/2, imageWidth, imageHeight); 2047
2048 this.emit('convert', canvas, audio); 2049} 2050 2051 2052function repeatImage(canvas, startY, endY) { 2053 var ctx = canvas.getContext('2d'); 2054 2055 var y = Math.min(startY, endY); 2056 var height = Math.abs(startY - endY); 2057 2058 // Repeat the start line through the whole range. 2059 ctx.drawImage(canvas, 0, startY, canvas.width, 1, 2060 0, y, canvas.width, height); 2061 2062} 2063 2064function blurImage(canvas, radius) { 2065 2066 var source = new jsfx.Source(canvas); 2067 source.height = 4096; 2068 source.width = 4096; 2069 //var blurFilter = new jsfx.filter.Brightness(0.5); 2070 var blurFilter = new jsfx.filter.Blur(radius); 2071 2072 var renderer = new jsfx.Renderer(); 2073 renderer.setSource(source); 2074 renderer.applyFilters([blurFilter]); 2075 renderer.render(); 2076 2077 var canvas2 = renderer.getCanvas(); 2078 2079 return canvas2; 2080} 2081 2082/** 2083 * Hermite resize - fast image resize/resample using Hermite filter. 1 cpu version! 2084 * 2085 * @param {HtmlElement} canvas 2086 * @param {int} width 2087 * @param {int} height 2088 * @param {boolean} resize_canvas if true, canvas will be resized. Optional. 2089 */ 2090function resample_single(canvas, width, height, resize_canvas) { 2091 var width_source = canvas.width; 2092 var height_source = canvas.height; 2093 width = Math.round(width); 2094 height = Math.round(height); 2095 2096 var ratio_w = width_source / width; 2097 var ratio_h = height_source / height; 2098 var ratio_w_half = Math.ceil(ratio_w / 2); 2099 var ratio_h_half = Math.ceil(ratio_h / 2); 2100 2101 var ctx = canvas.getContext("2d"); 2102 var img = ctx.getImageData(0, 0, width_source, height_source); 2103 var img2 = ctx.createImageData(width, height); 2104 var data = img.data; 2105 var data2 = img2.data; 2106 2107 for (var j = 0; j < height; j++) { 2108 for (var i = 0; i < width; i++) { 2109 var x2 = (i + j * width) * 4; 2110 var weight = 0; 2111 var weights = 0; 2112 var weights_alpha = 0; 2113 var gx_r = 0; 2114 var gx_g = 0; 2115 var gx_b = 0; 2116 var gx_a = 0; 2117 var center_y = (j + 0.5) * ratio_h; 2118 var yy_start = Math.floor(j * ratio_h); 2119 var yy_stop = Math.ceil((j + 1) * ratio_h); 2120 for (var yy = yy_start; yy < yy_stop; yy++) { 2121 var dy = Math.abs(center_y - (yy + 0.5)) / ratio_h_half; 2122 var center_x = (i + 0.5) * ratio_w; 2123 var w0 = dy * dy; //pre-calc part of w 2124 var xx_start = Math.floor(i * ratio_w); 2125 var xx_stop = Math.ceil((i + 1) * ratio_w); 2126 for (var xx = xx_start; xx < xx_stop; xx++) { 2127 var dx = Math.abs(center_x - (xx + 0.5)) / ratio_w_half; 2128 var w = Math.sqrt(w0 + dx * dx); 2129 if (w >= 1) { 2130 //pixel too far 2131 continue; 2132 } 2133 //hermite filter 2134 weight = 2 * w * w * w - 3 * w * w + 1; 2135 var pos_x = 4 * (xx + yy * width_source); 2136 //alpha 2137 gx_a += weight * data[pos_x + 3]; 2138 weights_alpha += weight; 2139 //colors 2140 if (data[pos_x + 3] < 255) 2141 weight = weight * data[pos_x + 3] / 250; 2142 gx_r += weight * data[pos_x]; 2143 gx_g += weight * data[pos_x + 1]; 2144 gx_b += weight * data[pos_x + 2]; 2145 weights += weight; 2146 } 2147 } 2148 data2[x2] = gx_r / weights; 2149 data2[x2 + 1] = gx_g / weights; 2150 data2[x2 + 2] = gx_b / weights; 2151 data2[x2 + 3] = gx_a / weights_alpha; 2152 } 2153 } 2154 //clear and resize canvas 2155 if (resize_canvas === true) { 2156 canvas.width = width; 2157 canvas.height = height; 2158 } else { 2159 ctx.clearRect(0, 0, width_source, height_source); 2160 } 2161 2162 //draw 2163 ctx.putImageData(img2, 0, 0); 2164} 2165 2166function makeImage(mime, data) { 2167 var img = new Image(); 2168 img.src = 'data:' + mime + ';base64,' + data; 2169 return img; 2170} 2171 2172function makeImageFromBinary(mime, bytes) { 2173 var blob = new Blob([bytes], {type: mime}); 2174 var url = URL.createObjectURL(blob); 2175 var img = new Image(); 2176 img.src = url; 2177 return img; 2178} 2179 2180function makeAudio(mime, data) { 2181 return 'data:' + mime + ';base64,' + data; 2182} 2183 2184function byteToString(bytes, start, end) { 2185 var s = ''; 2186 start = start || 0; 2187 end = end || bytes.length; 2188 for (var i = start; i < end; i++) { 2189 if (bytes[i]) { 2190 var c = String.fromCharCode(bytes[i]); 2191 s += c; 2192 } 2193 } 2194 return s; 2195} 2196 2197function getObjectMeta (doc, tag) { 2198 var meta = {}; 2199 var descriptions = doc.querySelectorAll('Description'); 2200 for (var i = 0; i < descriptions.length; i++) { 2201 var node = descriptions[i]; 2202 for (var j in node.attributes) { 2203 var attr = node.attributes[j]; 2204 if (attr.prefix == tag) { 2205 meta[attr.localName] = attr.value; 2206 } 2207 } 2208 } 2209 return meta; 2210} 2211 2212function extractXMP(bytes, errorCallback) { 2213 var sections = parseJpeg(bytes, true); 2214 if (sections === null) { 2215 errorCallback('No XMP metadata found in specified image file. This might not be a valid Cardboard Camera image.'); 2216 return; 2217 } 2218 var xml = ''; 2219 var visitedExtended = false;
2220 for (var i = 0; i < sections.length; i++) { 2221 var isXmp = true; 2222 var isExt = true; 2223 var section = sections[i]; 2224 for (var j = 0; j < section.data.length; j++) { 2225 var a = String.fromCharCode(section.data[j]); 2226 if (isXmp && a != XMP_SIGNATURE[j]) { 2227 isXmp = false; 2228 } 2229 if (isExt && a != EXTENSTION_SIGNATURE[j]) { 2230 isExt = false; 2231 } 2232 if (!isExt || !isXmp) { 2233 break; 2234 } 2235 } 2236 2237 if (isXmp) { 2238 var str = byteToString(section.data); 2239 var re = new RegExp('<x:xmpmeta([\\s\\S]*)</x:xmpmeta>'); 2240 xml = str.match(re)[0]; 2241 } 2242 else if (isExt) { 2243 var len = EXT_PREFIX_LENGTH; 2244 if (visitedExtended) { 2245 len +=4; 2246 } 2247 visitedExtended = true; 2248 xml += byteToString(section.data, len); 2249 } 2250 } 2251 var parser = new DOMParser(); 2252 var doc = parser.parseFromString('<xml>' + xml + '</xml>', 'text/xml'); 2253 return doc; 2254} 2255 2256function binaryToBase64 (bytes) { 2257 var b64 = []; 2258 var pageSize = 100000; 2259 for (var i = 0; i < bytes.length; i += pageSize) { 2260 b64.push(btoa(String.fromCharCode.apply(null, 2261 bytes.subarray(i, i + pageSize)))); 2262 } 2263 return b64.join(''); 2264} 2265 2266function parseJpeg (bytes, readMetaOnly) { 2267 var c; 2268 var i = 0; 2269 var read = function() { 2270 return i < bytes.length ? bytes[i++] : -1; 2271 }; 2272 2273 if (read() != 0xff || read() != M_SOI) { 2274 return null; 2275 } 2276 var sections = []; 2277 while((c = read()) != -1) { 2278 if (c != 0xff) { 2279 return null; 2280 } 2281 while((c = read()) == 0xff) { 2282 } 2283 2284 if (c == -1) { 2285 return null 2286 } 2287 var marker = c; 2288 if (marker == M_SOS) { 2289 // M_SOS indicates that image data will follow and no metadata after 2290 // that so read all data at one time. 2291 if (!readMetaOnly) { 2292 var section = { 2293 marker: marker, 2294 length: -1, 2295 data: bytes.subarray(i) 2296 }; 2297 sections.push(section); 2298 } 2299 return sections; 2300 } 2301 var lh = read(); 2302 var ll = read(); 2303 if (lh == -1 || ll == -1) { 2304 return null; 2305 } 2306 var length = lh << 8 | ll; 2307 if (!readMetaOnly || c == M_APP1) { 2308 var section = { 2309 marker: marker, 2310 length: length, 2311 data: bytes.subarray(i, i + length - 2) 2312 }; 2313 sections.push(section); 2314 } 2315 // Move i to end of section. 2316 i += length - 2; 2317 } 2318 return sections; 2319} 2320 2321module.exports = OdsConverter; 2322 2323},{"eventemitter3":1,"jsfx":2}],7:[function(require,module,exports){ 2324'use strict' 2325 2326exports.toByteArray = toByteArray 2327exports.fromByteArray = fromByteArray 2328 2329var lookup = [] 2330var revLookup = [] 2331var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array 2332 2333function init () { 2334 var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' 2335 for (var i = 0, len = code.length; i < len; ++i) { 2336 lookup[i] = code[i] 2337 revLookup[code.charCodeAt(i)] = i 2338 } 2339 2340 revLookup['-'.charCodeAt(0)] = 62 2341 revLookup['_'.charCodeAt(0)] = 63 2342} 2343 2344init() 2345 2346function toByteArray (b64) { 2347 var i, j, l, tmp, placeHolders, arr 2348 var len = b64.length 2349 2350 if (len % 4 > 0) { 2351 throw new Error('Invalid string. Length must be a multiple of 4') 2352 } 2353 2354 // the number of equal signs (place holders) 2355 // if there are two placeholders, than the two characters before it 2356 // represent one byte 2357 // if there is only one, then the three characters before it represent 2 bytes 2358 // this is just a cheap hack to not do indexOf twice 2359 placeHolders = b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0 2360 2361 // base64 is 4/3 + up to two characters of the original data 2362 arr = new Arr(len * 3 / 4 - placeHolders) 2363 2364 // if there are placeholders, only get up to the last complete 4 chars 2365 l = placeHolders > 0 ? len - 4 : len 2366 2367 var L = 0 2368 2369 for (i = 0, j = 0; i < l; i += 4, j += 3) { 2370 tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)] 2371 arr[L++] = (tmp >> 16) & 0xFF 2372 arr[L++] = (tmp >> 8) & 0xFF 2373 arr[L++] = tmp & 0xFF 2374 } 2375 2376 if (placeHolders === 2) { 2377 tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4) 2378 arr[L++] = tmp & 0xFF 2379 } else if (placeHolders === 1) { 2380 tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2) 2381 arr[L++] = (tmp >> 8) & 0xFF 2382 arr[L++] = tmp & 0xFF 2383 } 2384 2385 return arr 2386} 2387 2388function tripletToBase64 (num) { 2389 return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F] 2390} 2391 2392function encodeChunk (uint8, start, end) { 2393 var tmp 2394 var output = [] 2395 for (var i = start; i < end; i += 3) { 2396 tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) 2397 output.push(tripletToBase64(tmp)) 2398 } 2399 return output.join('') 2400} 2401 2402function fromByteArray (uint8) { 2403 var tmp 2404 var len = uint8.length 2405 var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes 2406 var output = '' 2407 var parts = [] 2408 var maxChunkLength = 16383 // must be multiple of 3 2409 2410 // go through the array every three bytes, we'll deal with trailing stuff later 2411 for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { 2412 parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength))) 2413 } 2414 2415 // pad the end with zeros, but make sure to not forget the extra bytes 2416 if (extraBytes === 1) { 2417 tmp = uint8[len - 1] 2418 output += lookup[tmp >> 2] 2419 output += lookup[(tmp << 4) & 0x3F] 2420 output += '==' 2421 } else if (extraBytes === 2) { 2422 tmp = (uint8[len - 2] << 8) + (uint8[len - 1]) 2423 output += lookup[tmp >> 10] 2424 output += lookup[(tmp >> 4) & 0x3F] 2425 output += lookup[(tmp << 2) & 0x3F] 2426 output += '=' 2427 } 2428 2429 parts.push(output) 2430 2431 return parts.join('') 2432} 2433 2434},{}],8:[function(require,module,exports){ 2435(function (global){ 2436/*! 2437 * The buffer module from node.js, for the browser. 2438 * 2439 * @author Feross Aboukhadijeh <[email protected]> <http://feross.org> 2440 * @license MIT 2441 */ 2442/* eslint-disable no-proto */ 2443 2444'use strict' 2445 2446var base64 = require('base64-js') 2447var ieee754 = require('ieee754') 2448var isArray = require('isarray') 2449 2450exports.Buffer = Buffer 2451exports.SlowBuffer = SlowBuffer 2452exports.INSPECT_MAX_BYTES = 50 2453 2454/** 2455 * If `Buffer.TYPED_ARRAY_SUPPORT`: 2456 * === true Use Uint8Array implementation (fastest) 2457 * === false Use Object implementation (most compatible, even IE6) 2458 * 2459 * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, 2460 * Opera 11.6+, iOS 4.2+. 2461 * 2462 * Due to various browser bugs, sometimes the Object implementation will be used even 2463 * when the browser supports typed arrays. 2464 *
vendor: 9,750 bytes, lines 2465-2834
2465 * Note: 2466 * 2467 * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, 2468 * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. 2469 * 2470 * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. 2471 * 2472 * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of 2473 * incorrect length in some situations. 2474 2475 * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they 2476 * get the Object implementation, which is slower but behaves correctly. 2477 */ 2478Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined 2479 ? global.TYPED_ARRAY_SUPPORT 2480 : typedArraySupport() 2481 2482/* 2483 * Export kMaxLength after typed array support is determined. 2484 */ 2485exports.kMaxLength = kMaxLength() 2486 2487function typedArraySupport () { 2488 try { 2489 var arr = new Uint8Array(1) 2490 arr.foo = function () { return 42 } 2491 return arr.foo() === 42 && // typed array instances can be augmented 2492 typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` 2493 arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` 2494 } catch (e) { 2495 return false 2496 } 2497} 2498 2499function kMaxLength () { 2500 return Buffer.TYPED_ARRAY_SUPPORT 2501 ? 0x7fffffff 2502 : 0x3fffffff 2503} 2504 2505function createBuffer (that, length) { 2506 if (kMaxLength() < length) { 2507 throw new RangeError('Invalid typed array length') 2508 } 2509 if (Buffer.TYPED_ARRAY_SUPPORT) { 2510 // Return an augmented `Uint8Array` instance, for best performance 2511 that = new Uint8Array(length) 2512 that.__proto__ = Buffer.prototype 2513 } else { 2514 // Fallback: Return an object instance of the Buffer class 2515 if (that === null) { 2516 that = new Buffer(length) 2517 } 2518 that.length = length 2519 } 2520 2521 return that 2522} 2523 2524/** 2525 * The Buffer constructor returns instances of `Uint8Array` that have their 2526 * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of 2527 * `Uint8Array`, so the returned instances will have all the node `Buffer` methods 2528 * and the `Uint8Array` methods. Square bracket notation works as expected -- it 2529 * returns a single octet. 2530 * 2531 * The `Uint8Array` prototype remains unmodified. 2532 */ 2533 2534function Buffer (arg, encodingOrOffset, length) { 2535 if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) { 2536 return new Buffer(arg, encodingOrOffset, length) 2537 } 2538 2539 // Common case. 2540 if (typeof arg === 'number') { 2541 if (typeof encodingOrOffset === 'string') { 2542 throw new Error( 2543 'If encoding is specified then the first argument must be a string' 2544 ) 2545 } 2546 return allocUnsafe(this, arg) 2547 } 2548 return from(this, arg, encodingOrOffset, length) 2549} 2550 2551Buffer.poolSize = 8192 // not used by this implementation 2552 2553// TODO: Legacy, not needed anymore. Remove in next major version. 2554Buffer._augment = function (arr) { 2555 arr.__proto__ = Buffer.prototype 2556 return arr 2557} 2558 2559function from (that, value, encodingOrOffset, length) { 2560 if (typeof value === 'number') { 2561 throw new TypeError('"value" argument must not be a number') 2562 } 2563 2564 if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { 2565 return fromArrayBuffer(that, value, encodingOrOffset, length) 2566 } 2567 2568 if (typeof value === 'string') { 2569 return fromString(that, value, encodingOrOffset) 2570 } 2571 2572 return fromObject(that, value) 2573} 2574 2575/** 2576 * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError 2577 * if value is a number. 2578 * Buffer.from(str[, encoding]) 2579 * Buffer.from(array) 2580 * Buffer.from(buffer) 2581 * Buffer.from(arrayBuffer[, byteOffset[, length]]) 2582 **/ 2583Buffer.from = function (value, encodingOrOffset, length) { 2584 return from(null, value, encodingOrOffset, length) 2585} 2586 2587if (Buffer.TYPED_ARRAY_SUPPORT) { 2588 Buffer.prototype.__proto__ = Uint8Array.prototype 2589 Buffer.__proto__ = Uint8Array 2590 if (typeof Symbol !== 'undefined' && Symbol.species && 2591 Buffer[Symbol.species] === Buffer) { 2592 // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97 2593 Object.defineProperty(Buffer, Symbol.species, { 2594 value: null, 2595 configurable: true 2596 }) 2597 } 2598} 2599 2600function assertSize (size) { 2601 if (typeof size !== 'number') { 2602 throw new TypeError('"size" argument must be a number') 2603 } 2604} 2605 2606function alloc (that, size, fill, encoding) { 2607 assertSize(size) 2608 if (size <= 0) { 2609 return createBuffer(that, size) 2610 } 2611 if (fill !== undefined) { 2612 // Only pay attention to encoding if it's a string. This 2613 // prevents accidentally sending in a number that would 2614 // be interpretted as a start offset. 2615 return typeof encoding === 'string' 2616 ? createBuffer(that, size).fill(fill, encoding) 2617 : createBuffer(that, size).fill(fill) 2618 } 2619 return createBuffer(that, size) 2620} 2621 2622/** 2623 * Creates a new filled Buffer instance. 2624 * alloc(size[, fill[, encoding]]) 2625 **/ 2626Buffer.alloc = function (size, fill, encoding) { 2627 return alloc(null, size, fill, encoding) 2628} 2629 2630function allocUnsafe (that, size) { 2631 assertSize(size) 2632 that = createBuffer(that, size < 0 ? 0 : checked(size) | 0) 2633 if (!Buffer.TYPED_ARRAY_SUPPORT) { 2634 for (var i = 0; i < size; i++) { 2635 that[i] = 0 2636 } 2637 } 2638 return that 2639} 2640 2641/** 2642 * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance. 2643 * */ 2644Buffer.allocUnsafe = function (size) { 2645 return allocUnsafe(null, size) 2646} 2647/** 2648 * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. 2649 */ 2650Buffer.allocUnsafeSlow = function (size) { 2651 return allocUnsafe(null, size) 2652} 2653 2654function fromString (that, string, encoding) { 2655 if (typeof encoding !== 'string' || encoding === '') { 2656 encoding = 'utf8' 2657 } 2658 2659 if (!Buffer.isEncoding(encoding)) { 2660 throw new TypeError('"encoding" must be a valid string encoding') 2661 } 2662 2663 var length = byteLength(string, encoding) | 0 2664 that = createBuffer(that, length) 2665 2666 that.write(string, encoding) 2667 return that 2668} 2669 2670function fromArrayLike (that, array) { 2671 var length = checked(array.length) | 0 2672 that = createBuffer(that, length) 2673 for (var i = 0; i < length; i += 1) { 2674 that[i] = array[i] & 255 2675 } 2676 return that 2677} 2678 2679function fromArrayBuffer (that, array, byteOffset, length) { 2680 array.byteLength // this throws if `array` is not a valid ArrayBuffer 2681 2682 if (byteOffset < 0 || array.byteLength < byteOffset) { 2683 throw new RangeError('\'offset\' is out of bounds') 2684 } 2685 2686 if (array.byteLength < byteOffset + (length || 0)) { 2687 throw new RangeError('\'length\' is out of bounds') 2688 } 2689 2690 if (length === undefined) { 2691 array = new Uint8Array(array, byteOffset) 2692 } else { 2693 array = new Uint8Array(array, byteOffset, length) 2694 } 2695 2696 if (Buffer.TYPED_ARRAY_SUPPORT) { 2697 // Return an augmented `Uint8Array` instance, for best performance 2698 that = array 2699 that.__proto__ = Buffer.prototype 2700 } else { 2701 // Fallback: Return an object instance of the Buffer class 2702 that = fromArrayLike(that, array) 2703 } 2704 return that 2705} 2706 2707function fromObject (that, obj) { 2708 if (Buffer.isBuffer(obj)) { 2709 var len = checked(obj.length) | 0 2710 that = createBuffer(that, len) 2711 2712 if (that.length === 0) { 2713 return that 2714 } 2715 2716 obj.copy(that, 0, 0, len) 2717 return that 2718 } 2719 2720 if (obj) { 2721 if ((typeof ArrayBuffer !== 'undefined' && 2722 obj.buffer instanceof ArrayBuffer) || 'length' in obj) { 2723 if (typeof obj.length !== 'number' || isnan(obj.length)) { 2724 return createBuffer(that, 0) 2725 } 2726 return fromArrayLike(that, obj) 2727 } 2728 2729 if (obj.type === 'Buffer' && isArray(obj.data)) { 2730 return fromArrayLike(that, obj.data) 2731 } 2732 } 2733 2734 throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.') 2735} 2736 2737function checked (length) { 2738 // Note: cannot use `length < kMaxLength` here because that fails when 2739 // length is NaN (which is otherwise coerced to zero.) 2740 if (length >= kMaxLength()) { 2741 throw new RangeError('Attempt to allocate Buffer larger than maximum ' + 2742 'size: 0x' + kMaxLength().toString(16) + ' bytes') 2743 } 2744 return length | 0 2745} 2746 2747function SlowBuffer (length) { 2748 if (+length != length) { // eslint-disable-line eqeqeq 2749 length = 0 2750 } 2751 return Buffer.alloc(+length) 2752} 2753 2754Buffer.isBuffer = function isBuffer (b) { 2755 return !!(b != null && b._isBuffer) 2756} 2757 2758Buffer.compare = function compare (a, b) { 2759 if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { 2760 throw new TypeError('Arguments must be Buffers') 2761 } 2762 2763 if (a === b) return 0 2764 2765 var x = a.length 2766 var y = b.length 2767 2768 for (var i = 0, len = Math.min(x, y); i < len; ++i) { 2769 if (a[i] !== b[i]) { 2770 x = a[i] 2771 y = b[i] 2772 break 2773 } 2774 } 2775 2776 if (x < y) return -1 2777 if (y < x) return 1 2778 return 0 2779} 2780 2781Buffer.isEncoding = function isEncoding (encoding) { 2782 switch (String(encoding).toLowerCase()) { 2783 case 'hex': 2784 case 'utf8': 2785 case 'utf-8': 2786 case 'ascii': 2787 case 'binary': 2788 case 'base64': 2789 case 'raw': 2790 case 'ucs2': 2791 case 'ucs-2': 2792 case 'utf16le': 2793 case 'utf-16le': 2794 return true 2795 default: 2796 return false 2797 } 2798} 2799 2800Buffer.concat = function concat (list, length) { 2801 if (!isArray(list)) { 2802 throw new TypeError('"list" argument must be an Array of Buffers') 2803 } 2804 2805 if (list.length === 0) { 2806 return Buffer.alloc(0) 2807 } 2808 2809 var i 2810 if (length === undefined) { 2811 length = 0 2812 for (i = 0; i < list.length; i++) { 2813 length += list[i].length 2814 } 2815 } 2816 2817 var buffer = Buffer.allocUnsafe(length) 2818 var pos = 0 2819 for (i = 0; i < list.length; i++) { 2820 var buf = list[i] 2821 if (!Buffer.isBuffer(buf)) { 2822 throw new TypeError('"list" argument must be an Array of Buffers') 2823 } 2824 buf.copy(buffer, pos) 2825 pos += buf.length 2826 } 2827 return buffer 2828} 2829 2830function byteLength (string, encoding) { 2831 if (Buffer.isBuffer(string)) { 2832 return string.length 2833 } 2834 if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&
vendor: 6,996 bytes, lines 2835-3123
2835 (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) { 2836 return string.byteLength 2837 } 2838 if (typeof string !== 'string') { 2839 string = '' + string 2840 } 2841 2842 var len = string.length 2843 if (len === 0) return 0 2844 2845 // Use a for loop to avoid recursion 2846 var loweredCase = false 2847 for (;;) { 2848 switch (encoding) { 2849 case 'ascii': 2850 case 'binary': 2851 // Deprecated 2852 case 'raw': 2853 case 'raws': 2854 return len 2855 case 'utf8': 2856 case 'utf-8': 2857 case undefined: 2858 return utf8ToBytes(string).length 2859 case 'ucs2': 2860 case 'ucs-2': 2861 case 'utf16le': 2862 case 'utf-16le': 2863 return len * 2 2864 case 'hex': 2865 return len >>> 1 2866 case 'base64': 2867 return base64ToBytes(string).length 2868 default: 2869 if (loweredCase) return utf8ToBytes(string).length // assume utf8 2870 encoding = ('' + encoding).toLowerCase() 2871 loweredCase = true 2872 } 2873 } 2874} 2875Buffer.byteLength = byteLength 2876 2877function slowToString (encoding, start, end) { 2878 var loweredCase = false 2879 2880 // No need to verify that "this.length <= MAX_UINT32" since it's a read-only 2881 // property of a typed array. 2882 2883 // This behaves neither like String nor Uint8Array in that we set start/end 2884 // to their upper/lower bounds if the value passed is out of range. 2885 // undefined is handled specially as per ECMA-262 6th Edition, 2886 // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization. 2887 if (start === undefined || start < 0) { 2888 start = 0 2889 } 2890 // Return early if start > this.length. Done here to prevent potential uint32 2891 // coercion fail below. 2892 if (start > this.length) { 2893 return '' 2894 } 2895 2896 if (end === undefined || end > this.length) { 2897 end = this.length 2898 } 2899 2900 if (end <= 0) { 2901 return '' 2902 } 2903 2904 // Force coersion to uint32. This will also coerce falsey/NaN values to 0. 2905 end >>>= 0 2906 start >>>= 0 2907 2908 if (end <= start) { 2909 return '' 2910 } 2911 2912 if (!encoding) encoding = 'utf8' 2913 2914 while (true) { 2915 switch (encoding) { 2916 case 'hex': 2917 return hexSlice(this, start, end) 2918 2919 case 'utf8': 2920 case 'utf-8': 2921 return utf8Slice(this, start, end) 2922 2923 case 'ascii': 2924 return asciiSlice(this, start, end) 2925 2926 case 'binary': 2927 return binarySlice(this, start, end) 2928 2929 case 'base64': 2930 return base64Slice(this, start, end) 2931 2932 case 'ucs2': 2933 case 'ucs-2': 2934 case 'utf16le': 2935 case 'utf-16le': 2936 return utf16leSlice(this, start, end) 2937 2938 default: 2939 if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) 2940 encoding = (encoding + '').toLowerCase() 2941 loweredCase = true 2942 } 2943 } 2944} 2945 2946// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect 2947// Buffer instances. 2948Buffer.prototype._isBuffer = true 2949 2950function swap (b, n, m) { 2951 var i = b[n] 2952 b[n] = b[m] 2953 b[m] = i 2954} 2955 2956Buffer.prototype.swap16 = function swap16 () { 2957 var len = this.length 2958 if (len % 2 !== 0) { 2959 throw new RangeError('Buffer size must be a multiple of 16-bits') 2960 } 2961 for (var i = 0; i < len; i += 2) { 2962 swap(this, i, i + 1) 2963 } 2964 return this 2965} 2966 2967Buffer.prototype.swap32 = function swap32 () { 2968 var len = this.length 2969 if (len % 4 !== 0) { 2970 throw new RangeError('Buffer size must be a multiple of 32-bits') 2971 } 2972 for (var i = 0; i < len; i += 4) { 2973 swap(this, i, i + 3) 2974 swap(this, i + 1, i + 2) 2975 } 2976 return this 2977} 2978 2979Buffer.prototype.toString = function toString () { 2980 var length = this.length | 0 2981 if (length === 0) return '' 2982 if (arguments.length === 0) return utf8Slice(this, 0, length) 2983 return slowToString.apply(this, arguments) 2984} 2985 2986Buffer.prototype.equals = function equals (b) { 2987 if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') 2988 if (this === b) return true 2989 return Buffer.compare(this, b) === 0 2990} 2991 2992Buffer.prototype.inspect = function inspect () { 2993 var str = '' 2994 var max = exports.INSPECT_MAX_BYTES 2995 if (this.length > 0) { 2996 str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') 2997 if (this.length > max) str += ' ... ' 2998 } 2999 return '<Buffer ' + str + '>' 3000} 3001 3002Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) { 3003 if (!Buffer.isBuffer(target)) { 3004 throw new TypeError('Argument must be a Buffer') 3005 } 3006 3007 if (start === undefined) { 3008 start = 0 3009 } 3010 if (end === undefined) { 3011 end = target ? target.length : 0 3012 } 3013 if (thisStart === undefined) { 3014 thisStart = 0 3015 } 3016 if (thisEnd === undefined) { 3017 thisEnd = this.length 3018 } 3019 3020 if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) { 3021 throw new RangeError('out of range index') 3022 } 3023 3024 if (thisStart >= thisEnd && start >= end) { 3025 return 0 3026 } 3027 if (thisStart >= thisEnd) { 3028 return -1 3029 } 3030 if (start >= end) { 3031 return 1 3032 } 3033 3034 start >>>= 0 3035 end >>>= 0 3036 thisStart >>>= 0 3037 thisEnd >>>= 0 3038 3039 if (this === target) return 0 3040 3041 var x = thisEnd - thisStart 3042 var y = end - start 3043 var len = Math.min(x, y) 3044 3045 var thisCopy = this.slice(thisStart, thisEnd) 3046 var targetCopy = target.slice(start, end) 3047 3048 for (var i = 0; i < len; ++i) { 3049 if (thisCopy[i] !== targetCopy[i]) { 3050 x = thisCopy[i] 3051 y = targetCopy[i] 3052 break 3053 } 3054 } 3055 3056 if (x < y) return -1 3057 if (y < x) return 1 3058 return 0 3059} 3060 3061function arrayIndexOf (arr, val, byteOffset, encoding) { 3062 var indexSize = 1 3063 var arrLength = arr.length 3064 var valLength = val.length 3065 3066 if (encoding !== undefined) { 3067 encoding = String(encoding).toLowerCase() 3068 if (encoding === 'ucs2' || encoding === 'ucs-2' || 3069 encoding === 'utf16le' || encoding === 'utf-16le') { 3070 if (arr.length < 2 || val.length < 2) { 3071 return -1 3072 } 3073 indexSize = 2 3074 arrLength /= 2 3075 valLength /= 2 3076 byteOffset /= 2 3077 } 3078 } 3079 3080 function read (buf, i) { 3081 if (indexSize === 1) { 3082 return buf[i] 3083 } else { 3084 return buf.readUInt16BE(i * indexSize) 3085 } 3086 } 3087 3088 var foundIndex = -1 3089 for (var i = 0; byteOffset + i < arrLength; i++) { 3090 if (read(arr, byteOffset + i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { 3091 if (foundIndex === -1) foundIndex = i 3092 if (i - foundIndex + 1 === valLength) return (byteOffset + foundIndex) * indexSize 3093 } else { 3094 if (foundIndex !== -1) i -= i - foundIndex 3095 foundIndex = -1 3096 } 3097 } 3098 return -1 3099} 3100 3101Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) { 3102 if (typeof byteOffset === 'string') { 3103 encoding = byteOffset 3104 byteOffset = 0 3105 } else if (byteOffset > 0x7fffffff) { 3106 byteOffset = 0x7fffffff 3107 } else if (byteOffset < -0x80000000) { 3108 byteOffset = -0x80000000 3109 } 3110 byteOffset >>= 0 3111 3112 if (this.length === 0) return -1 3113 if (byteOffset >= this.length) return -1 3114 3115 // Negative offsets start from the end of the buffer 3116 if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0) 3117 3118 if (typeof val === 'string') { 3119 val = Buffer.from(val, encoding) 3120 } 3121 3122 if (Buffer.isBuffer(val)) { 3123 // special case: looking for empty string/buffer always fail
vendor: 6,278 bytes, lines 3123-3338
3123s 3124 if (val.length === 0) { 3125 return -1 3126 } 3127 return arrayIndexOf(this, val, byteOffset, encoding) 3128 } 3129 if (typeof val === 'number') { 3130 if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') { 3131 return Uint8Array.prototype.indexOf.call(this, val, byteOffset) 3132 } 3133 return arrayIndexOf(this, [ val ], byteOffset, encoding) 3134 } 3135 3136 throw new TypeError('val must be string, number or Buffer') 3137} 3138 3139Buffer.prototype.includes = function includes (val, byteOffset, encoding) { 3140 return this.indexOf(val, byteOffset, encoding) !== -1 3141} 3142 3143function hexWrite (buf, string, offset, length) { 3144 offset = Number(offset) || 0 3145 var remaining = buf.length - offset 3146 if (!length) { 3147 length = remaining 3148 } else { 3149 length = Number(length) 3150 if (length > remaining) { 3151 length = remaining 3152 } 3153 } 3154 3155 // must be an even number of digits 3156 var strLen = string.length 3157 if (strLen % 2 !== 0) throw new Error('Invalid hex string') 3158 3159 if (length > strLen / 2) { 3160 length = strLen / 2 3161 } 3162 for (var i = 0; i < length; i++) { 3163 var parsed = parseInt(string.substr(i * 2, 2), 16) 3164 if (isNaN(parsed)) return i 3165 buf[offset + i] = parsed 3166 } 3167 return i 3168} 3169 3170function utf8Write (buf, string, offset, length) { 3171 return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) 3172} 3173 3174function asciiWrite (buf, string, offset, length) { 3175 return blitBuffer(asciiToBytes(string), buf, offset, length) 3176} 3177 3178function binaryWrite (buf, string, offset, length) { 3179 return asciiWrite(buf, string, offset, length) 3180} 3181 3182function base64Write (buf, string, offset, length) { 3183 return blitBuffer(base64ToBytes(string), buf, offset, length) 3184} 3185 3186function ucs2Write (buf, string, offset, length) { 3187 return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) 3188} 3189 3190Buffer.prototype.write = function write (string, offset, length, encoding) { 3191 // Buffer#write(string) 3192 if (offset === undefined) { 3193 encoding = 'utf8' 3194 length = this.length 3195 offset = 0 3196 // Buffer#write(string, encoding) 3197 } else if (length === undefined && typeof offset === 'string') { 3198 encoding = offset 3199 length = this.length 3200 offset = 0 3201 // Buffer#write(string, offset[, length][, encoding]) 3202 } else if (isFinite(offset)) { 3203 offset = offset | 0 3204 if (isFinite(length)) { 3205 length = length | 0 3206 if (encoding === undefined) encoding = 'utf8' 3207 } else { 3208 encoding = length 3209 length = undefined 3210 } 3211 // legacy write(string, encoding, offset, length) - remove in v0.13 3212 } else { 3213 throw new Error( 3214 'Buffer.write(string, encoding, offset[, length]) is no longer supported' 3215 ) 3216 } 3217 3218 var remaining = this.length - offset 3219 if (length === undefined || length > remaining) length = remaining 3220 3221 if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { 3222 throw new RangeError('Attempt to write outside buffer bounds') 3223 } 3224 3225 if (!encoding) encoding = 'utf8' 3226 3227 var loweredCase = false 3228 for (;;) { 3229 switch (encoding) { 3230 case 'hex': 3231 return hexWrite(this, string, offset, length) 3232 3233 case 'utf8': 3234 case 'utf-8': 3235 return utf8Write(this, string, offset, length) 3236 3237 case 'ascii': 3238 return asciiWrite(this, string, offset, length) 3239 3240 case 'binary': 3241 return binaryWrite(this, string, offset, length) 3242 3243 case 'base64': 3244 // Warning: maxLength not taken into account in base64Write 3245 return base64Write(this, string, offset, length) 3246 3247 case 'ucs2': 3248 case 'ucs-2': 3249 case 'utf16le': 3250 case 'utf-16le': 3251 return ucs2Write(this, string, offset, length) 3252 3253 default: 3254 if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) 3255 encoding = ('' + encoding).toLowerCase() 3256 loweredCase = true 3257 } 3258 } 3259} 3260 3261Buffer.prototype.toJSON = function toJSON () { 3262 return { 3263 type: 'Buffer', 3264 data: Array.prototype.slice.call(this._arr || this, 0) 3265 } 3266} 3267 3268function base64Slice (buf, start, end) { 3269 if (start === 0 && end === buf.length) { 3270 return base64.fromByteArray(buf) 3271 } else { 3272 return base64.fromByteArray(buf.slice(start, end)) 3273 } 3274} 3275 3276function utf8Slice (buf, start, end) { 3277 end = Math.min(buf.length, end) 3278 var res = [] 3279 3280 var i = start 3281 while (i < end) { 3282 var firstByte = buf[i] 3283 var codePoint = null 3284 var bytesPerSequence = (firstByte > 0xEF) ? 4 3285 : (firstByte > 0xDF) ? 3 3286 : (firstByte > 0xBF) ? 2 3287 : 1 3288 3289 if (i + bytesPerSequence <= end) { 3290 var secondByte, thirdByte, fourthByte, tempCodePoint 3291 3292 switch (bytesPerSequence) { 3293 case 1: 3294 if (firstByte < 0x80) { 3295 codePoint = firstByte 3296 } 3297 break 3298 case 2: 3299 secondByte = buf[i + 1] 3300 if ((secondByte & 0xC0) === 0x80) { 3301 tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F) 3302 if (tempCodePoint > 0x7F) { 3303 codePoint = tempCodePoint 3304 } 3305 } 3306 break 3307 case 3: 3308 secondByte = buf[i + 1] 3309 thirdByte = buf[i + 2] 3310 if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { 3311 tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F) 3312 if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { 3313 codePoint = tempCodePoint 3314 } 3315 } 3316 break 3317 case 4: 3318 secondByte = buf[i + 1] 3319 thirdByte = buf[i + 2] 3320 fourthByte = buf[i + 3] 3321 if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { 3322 tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F) 3323 if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { 3324 codePoint = tempCodePoint 3325 } 3326 } 3327 } 3328 } 3329 3330 if (codePoint === null) { 3331 // we did not generate a valid codePoint so insert a 3332 // replacement char (U+FFFD) and advance only 1 byte 3333 codePoint = 0xFFFD 3334 bytesPerSequence = 1 3335 } else if (codePoint > 0xFFFF) { 3336 // encode to utf16 (surrogate pair dance) 3337 codePoint -= 0x10000 3338 res.push(codePoint >>>
vendor: 2,429 bytes, lines 3338-3452
3338 10 & 0x3FF | 0xD800) 3339 codePoint = 0xDC00 | codePoint & 0x3FF 3340 } 3341 3342 res.push(codePoint) 3343 i += bytesPerSequence 3344 } 3345 3346 return decodeCodePointsArray(res) 3347} 3348 3349// Based on http://stackoverflow.com/a/22747272/680742, the browser with 3350// the lowest limit is Chrome, with 0x10000 args. 3351// We go 1 magnitude less, for safety 3352var MAX_ARGUMENTS_LENGTH = 0x1000 3353 3354function decodeCodePointsArray (codePoints) { 3355 var len = codePoints.length 3356 if (len <= MAX_ARGUMENTS_LENGTH) { 3357 return String.fromCharCode.apply(String, codePoints) // avoid extra slice() 3358 } 3359 3360 // Decode in chunks to avoid "call stack size exceeded". 3361 var res = '' 3362 var i = 0 3363 while (i < len) { 3364 res += String.fromCharCode.apply( 3365 String, 3366 codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) 3367 ) 3368 } 3369 return res 3370} 3371 3372function asciiSlice (buf, start, end) { 3373 var ret = '' 3374 end = Math.min(buf.length, end) 3375 3376 for (var i = start; i < end; i++) { 3377 ret += String.fromCharCode(buf[i] & 0x7F) 3378 } 3379 return ret 3380} 3381 3382function binarySlice (buf, start, end) { 3383 var ret = '' 3384 end = Math.min(buf.length, end) 3385 3386 for (var i = start; i < end; i++) { 3387 ret += String.fromCharCode(buf[i]) 3388 } 3389 return ret 3390} 3391 3392function hexSlice (buf, start, end) { 3393 var len = buf.length 3394 3395 if (!start || start < 0) start = 0 3396 if (!end || end < 0 || end > len) end = len 3397 3398 var out = '' 3399 for (var i = start; i < end; i++) { 3400 out += toHex(buf[i]) 3401 } 3402 return out 3403} 3404 3405function utf16leSlice (buf, start, end) { 3406 var bytes = buf.slice(start, end) 3407 var res = '' 3408 for (var i = 0; i < bytes.length; i += 2) { 3409 res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) 3410 } 3411 return res 3412} 3413 3414Buffer.prototype.slice = function slice (start, end) { 3415 var len = this.length 3416 start = ~~start 3417 end = end === undefined ? len : ~~end 3418 3419 if (start < 0) { 3420 start += len 3421 if (start < 0) start = 0 3422 } else if (start > len) { 3423 start = len 3424 } 3425 3426 if (end < 0) { 3427 end += len 3428 if (end < 0) end = 0 3429 } else if (end > len) { 3430 end = len 3431 } 3432 3433 if (end < start) end = start 3434 3435 var newBuf 3436 if (Buffer.TYPED_ARRAY_SUPPORT) { 3437 newBuf = this.subarray(start, end) 3438 newBuf.__proto__ = Buffer.prototype 3439 } else { 3440 var sliceLen = end - start 3441 newBuf = new Buffer(sliceLen, undefined) 3442 for (var i = 0; i < sliceLen; i++) { 3443 newBuf[i] = this[i + start] 3444 } 3445 } 3446 3447 return newBuf 3448} 3449 3450/* 3451 * Need to make sure that buffer isn't trying to write out of bounds. 3452 */
vendor: 9,979 bytes, lines 3453-3793
3453function checkOffset (offset, ext, length) { 3454 if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') 3455 if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') 3456} 3457 3458Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { 3459 offset = offset | 0 3460 byteLength = byteLength | 0 3461 if (!noAssert) checkOffset(offset, byteLength, this.length) 3462 3463 var val = this[offset] 3464 var mul = 1 3465 var i = 0 3466 while (++i < byteLength && (mul *= 0x100)) { 3467 val += this[offset + i] * mul 3468 } 3469 3470 return val 3471} 3472 3473Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { 3474 offset = offset | 0 3475 byteLength = byteLength | 0 3476 if (!noAssert) { 3477 checkOffset(offset, byteLength, this.length) 3478 } 3479 3480 var val = this[offset + --byteLength] 3481 var mul = 1 3482 while (byteLength > 0 && (mul *= 0x100)) { 3483 val += this[offset + --byteLength] * mul 3484 } 3485 3486 return val 3487} 3488 3489Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { 3490 if (!noAssert) checkOffset(offset, 1, this.length) 3491 return this[offset] 3492} 3493 3494Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { 3495 if (!noAssert) checkOffset(offset, 2, this.length) 3496 return this[offset] | (this[offset + 1] << 8) 3497} 3498 3499Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { 3500 if (!noAssert) checkOffset(offset, 2, this.length) 3501 return (this[offset] << 8) | this[offset + 1] 3502} 3503 3504Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { 3505 if (!noAssert) checkOffset(offset, 4, this.length) 3506 3507 return ((this[offset]) | 3508 (this[offset + 1] << 8) | 3509 (this[offset + 2] << 16)) + 3510 (this[offset + 3] * 0x1000000) 3511} 3512 3513Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { 3514 if (!noAssert) checkOffset(offset, 4, this.length) 3515 3516 return (this[offset] * 0x1000000) + 3517 ((this[offset + 1] << 16) | 3518 (this[offset + 2] << 8) | 3519 this[offset + 3]) 3520} 3521 3522Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { 3523 offset = offset | 0 3524 byteLength = byteLength | 0 3525 if (!noAssert) checkOffset(offset, byteLength, this.length) 3526 3527 var val = this[offset] 3528 var mul = 1 3529 var i = 0 3530 while (++i < byteLength && (mul *= 0x100)) { 3531 val += this[offset + i] * mul 3532 } 3533 mul *= 0x80 3534 3535 if (val >= mul) val -= Math.pow(2, 8 * byteLength) 3536 3537 return val 3538} 3539 3540Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { 3541 offset = offset | 0 3542 byteLength = byteLength | 0 3543 if (!noAssert) checkOffset(offset, byteLength, this.length) 3544 3545 var i = byteLength 3546 var mul = 1 3547 var val = this[offset + --i] 3548 while (i > 0 && (mul *= 0x100)) { 3549 val += this[offset + --i] * mul 3550 } 3551 mul *= 0x80 3552 3553 if (val >= mul) val -= Math.pow(2, 8 * byteLength) 3554 3555 return val 3556} 3557 3558Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { 3559 if (!noAssert) checkOffset(offset, 1, this.length) 3560 if (!(this[offset] & 0x80)) return (this[offset]) 3561 return ((0xff - this[offset] + 1) * -1) 3562} 3563 3564Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { 3565 if (!noAssert) checkOffset(offset, 2, this.length) 3566 var val = this[offset] | (this[offset + 1] << 8) 3567 return (val & 0x8000) ? val | 0xFFFF0000 : val 3568} 3569 3570Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { 3571 if (!noAssert) checkOffset(offset, 2, this.length) 3572 var val = this[offset + 1] | (this[offset] << 8) 3573 return (val & 0x8000) ? val | 0xFFFF0000 : val 3574} 3575 3576Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { 3577 if (!noAssert) checkOffset(offset, 4, this.length) 3578 3579 return (this[offset]) | 3580 (this[offset + 1] << 8) | 3581 (this[offset + 2] << 16) | 3582 (this[offset + 3] << 24) 3583} 3584 3585Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { 3586 if (!noAssert) checkOffset(offset, 4, this.length) 3587 3588 return (this[offset] << 24) | 3589 (this[offset + 1] << 16) | 3590 (this[offset + 2] << 8) | 3591 (this[offset + 3]) 3592} 3593 3594Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { 3595 if (!noAssert) checkOffset(offset, 4, this.length) 3596 return ieee754.read(this, offset, true, 23, 4) 3597} 3598 3599Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { 3600 if (!noAssert) checkOffset(offset, 4, this.length) 3601 return ieee754.read(this, offset, false, 23, 4) 3602} 3603 3604Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { 3605 if (!noAssert) checkOffset(offset, 8, this.length) 3606 return ieee754.read(this, offset, true, 52, 8) 3607} 3608 3609Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { 3610 if (!noAssert) checkOffset(offset, 8, this.length) 3611 return ieee754.read(this, offset, false, 52, 8) 3612} 3613 3614function checkInt (buf, value, offset, ext, max, min) { 3615 if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance') 3616 if (value > max || value < min) throw new RangeError('"value" argument is out of bounds') 3617 if (offset + ext > buf.length) throw new RangeError('Index out of range') 3618} 3619 3620Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { 3621 value = +value 3622 offset = offset | 0 3623 byteLength = byteLength | 0 3624 if (!noAssert) { 3625 var maxBytes = Math.pow(2, 8 * byteLength) - 1 3626 checkInt(this, value, offset, byteLength, maxBytes, 0) 3627 } 3628 3629 var mul = 1 3630 var i = 0 3631 this[offset] = value & 0xFF 3632 while (++i < byteLength && (mul *= 0x100)) { 3633 this[offset + i] = (value / mul) & 0xFF 3634 } 3635 3636 return offset + byteLength 3637} 3638 3639Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { 3640 value = +value 3641 offset = offset | 0 3642 byteLength = byteLength | 0 3643 if (!noAssert) { 3644 var maxBytes = Math.pow(2, 8 * byteLength) - 1 3645 checkInt(this, value, offset, byteLength, maxBytes, 0) 3646 } 3647 3648 var i = byteLength - 1 3649 var mul = 1 3650 this[offset + i] = value & 0xFF 3651 while (--i >= 0 && (mul *= 0x100)) { 3652 this[offset + i] = (value / mul) & 0xFF 3653 } 3654 3655 return offset + byteLength 3656} 3657 3658Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { 3659 value = +value 3660 offset = offset | 0 3661 if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) 3662 if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) 3663 this[offset] = (value & 0xff) 3664 return offset + 1 3665} 3666 3667function objectWriteUInt16 (buf, value, offset, littleEndian) { 3668 if (value < 0) value = 0xffff + value + 1 3669 for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) { 3670 buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> 3671 (littleEndian ? i : 1 - i) * 8 3672 } 3673} 3674 3675Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { 3676 value = +value 3677 offset = offset | 0 3678 if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) 3679 if (Buffer.TYPED_ARRAY_SUPPORT) { 3680 this[offset] = (value & 0xff) 3681 this[offset + 1] = (value >>> 8) 3682 } else { 3683 objectWriteUInt16(this, value, offset, true) 3684 } 3685 return offset + 2 3686} 3687 3688Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { 3689 value = +value 3690 offset = offset | 0 3691 if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) 3692 if (Buffer.TYPED_ARRAY_SUPPORT) { 3693 this[offset] = (value >>> 8) 3694 this[offset + 1] = (value & 0xff) 3695 } else { 3696 objectWriteUInt16(this, value, offset, false) 3697 } 3698 return offset + 2 3699} 3700 3701function objectWriteUInt32 (buf, value, offset, littleEndian) { 3702 if (value < 0) value = 0xffffffff + value + 1 3703 for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) { 3704 buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff 3705 } 3706} 3707 3708Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { 3709 value = +value 3710 offset = offset | 0 3711 if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) 3712 if (Buffer.TYPED_ARRAY_SUPPORT) { 3713 this[offset + 3] = (value >>> 24) 3714 this[offset + 2] = (value >>> 16) 3715 this[offset + 1] = (value >>> 8) 3716 this[offset] = (value & 0xff) 3717 } else { 3718 objectWriteUInt32(this, value, offset, true) 3719 } 3720 return offset + 4 3721} 3722 3723Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { 3724 value = +value 3725 offset = offset | 0 3726 if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) 3727 if (Buffer.TYPED_ARRAY_SUPPORT) { 3728 this[offset] = (value >>> 24) 3729 this[offset + 1] = (value >>> 16) 3730 this[offset + 2] = (value >>> 8) 3731 this[offset + 3] = (value & 0xff) 3732 } else { 3733 objectWriteUInt32(this, value, offset, false) 3734 } 3735 return offset + 4 3736} 3737 3738Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { 3739 value = +value 3740 offset = offset | 0 3741 if (!noAssert) { 3742 var limit = Math.pow(2, 8 * byteLength - 1) 3743 3744 checkInt(this, value, offset, byteLength, limit - 1, -limit) 3745 } 3746 3747 var i = 0 3748 var mul = 1 3749 var sub = 0 3750 this[offset] = value & 0xFF 3751 while (++i < byteLength && (mul *= 0x100)) { 3752 if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) { 3753 sub = 1 3754 } 3755 this[offset + i] = ((value / mul) >> 0) - sub & 0xFF 3756 } 3757 3758 return offset + byteLength 3759} 3760 3761Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { 3762 value = +value 3763 offset = offset | 0 3764 if (!noAssert) { 3765 var limit = Math.pow(2, 8 * byteLength - 1) 3766 3767 checkInt(this, value, offset, byteLength, limit - 1, -limit) 3768 } 3769 3770 var i = byteLength - 1 3771 var mul = 1 3772 var sub = 0 3773 this[offset + i] = value & 0xFF 3774 while (--i >= 0 && (mul *= 0x100)) { 3775 if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) { 3776 sub = 1 3777 } 3778 this[offset + i] = ((value / mul) >> 0) - sub & 0xFF 3779 } 3780 3781 return offset + byteLength 3782} 3783 3784Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { 3785 value = +value 3786 offset = offset | 0 3787 if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) 3788 if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) 3789 if (value < 0) value = 0xff + value + 1 3790 this[offset] = (value & 0xff) 3791 return offset + 1 3792} 3793
vendor: 8,271 bytes, lines 3794-4081
3794Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { 3795 value = +value 3796 offset = offset | 0 3797 if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) 3798 if (Buffer.TYPED_ARRAY_SUPPORT) { 3799 this[offset] = (value & 0xff) 3800 this[offset + 1] = (value >>> 8) 3801 } else { 3802 objectWriteUInt16(this, value, offset, true) 3803 } 3804 return offset + 2 3805} 3806 3807Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { 3808 value = +value 3809 offset = offset | 0 3810 if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) 3811 if (Buffer.TYPED_ARRAY_SUPPORT) { 3812 this[offset] = (value >>> 8) 3813 this[offset + 1] = (value & 0xff) 3814 } else { 3815 objectWriteUInt16(this, value, offset, false) 3816 } 3817 return offset + 2 3818} 3819 3820Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { 3821 value = +value 3822 offset = offset | 0 3823 if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) 3824 if (Buffer.TYPED_ARRAY_SUPPORT) { 3825 this[offset] = (value & 0xff) 3826 this[offset + 1] = (value >>> 8) 3827 this[offset + 2] = (value >>> 16) 3828 this[offset + 3] = (value >>> 24) 3829 } else { 3830 objectWriteUInt32(this, value, offset, true) 3831 } 3832 return offset + 4 3833} 3834 3835Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { 3836 value = +value 3837 offset = offset | 0 3838 if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) 3839 if (value < 0) value = 0xffffffff + value + 1 3840 if (Buffer.TYPED_ARRAY_SUPPORT) { 3841 this[offset] = (value >>> 24) 3842 this[offset + 1] = (value >>> 16) 3843 this[offset + 2] = (value >>> 8) 3844 this[offset + 3] = (value & 0xff) 3845 } else { 3846 objectWriteUInt32(this, value, offset, false) 3847 } 3848 return offset + 4 3849} 3850 3851function checkIEEE754 (buf, value, offset, ext, max, min) { 3852 if (offset + ext > buf.length) throw new RangeError('Index out of range') 3853 if (offset < 0) throw new RangeError('Index out of range') 3854} 3855 3856function writeFloat (buf, value, offset, littleEndian, noAssert) { 3857 if (!noAssert) { 3858 checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) 3859 } 3860 ieee754.write(buf, value, offset, littleEndian, 23, 4) 3861 return offset + 4 3862} 3863 3864Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { 3865 return writeFloat(this, value, offset, true, noAssert) 3866} 3867 3868Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { 3869 return writeFloat(this, value, offset, false, noAssert) 3870} 3871 3872function writeDouble (buf, value, offset, littleEndian, noAssert) { 3873 if (!noAssert) { 3874 checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) 3875 } 3876 ieee754.write(buf, value, offset, littleEndian, 52, 8) 3877 return offset + 8 3878} 3879 3880Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { 3881 return writeDouble(this, value, offset, true, noAssert) 3882} 3883 3884Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { 3885 return writeDouble(this, value, offset, false, noAssert) 3886} 3887 3888// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) 3889Buffer.prototype.copy = function copy (target, targetStart, start, end) { 3890 if (!start) start = 0 3891 if (!end && end !== 0) end = this.length 3892 if (targetStart >= target.length) targetStart = target.length 3893 if (!targetStart) targetStart = 0 3894 if (end > 0 && end < start) end = start 3895 3896 // Copy 0 bytes; we're done 3897 if (end === start) return 0 3898 if (target.length === 0 || this.length === 0) return 0 3899 3900 // Fatal error conditions 3901 if (targetStart < 0) { 3902 throw new RangeError('targetStart out of bounds') 3903 } 3904 if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') 3905 if (end < 0) throw new RangeError('sourceEnd out of bounds') 3906 3907 // Are we oob? 3908 if (end > this.length) end = this.length 3909 if (target.length - targetStart < end - start) { 3910 end = target.length - targetStart + start 3911 } 3912 3913 var len = end - start 3914 var i 3915 3916 if (this === target && start < targetStart && targetStart < end) { 3917 // descending copy from end 3918 for (i = len - 1; i >= 0; i--) { 3919 target[i + targetStart] = this[i + start] 3920 } 3921 } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { 3922 // ascending copy from start 3923 for (i = 0; i < len; i++) { 3924 target[i + targetStart] = this[i + start] 3925 } 3926 } else { 3927 Uint8Array.prototype.set.call( 3928 target, 3929 this.subarray(start, start + len), 3930 targetStart 3931 ) 3932 } 3933 3934 return len 3935} 3936 3937// Usage: 3938// buffer.fill(number[, offset[, end]]) 3939// buffer.fill(buffer[, offset[, end]]) 3940// buffer.fill(string[, offset[, end]][, encoding]) 3941Buffer.prototype.fill = function fill (val, start, end, encoding) { 3942 // Handle string cases: 3943 if (typeof val === 'string') { 3944 if (typeof start === 'string') { 3945 encoding = start 3946 start = 0 3947 end = this.length 3948 } else if (typeof end === 'string') { 3949 encoding = end 3950 end = this.length 3951 } 3952 if (val.length === 1) { 3953 var code = val.charCodeAt(0) 3954 if (code < 256) { 3955 val = code 3956 } 3957 } 3958 if (encoding !== undefined && typeof encoding !== 'string') { 3959 throw new TypeError('encoding must be a string') 3960 } 3961 if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) { 3962 throw new TypeError('Unknown encoding: ' + encoding) 3963 } 3964 } else if (typeof val === 'number') { 3965 val = val & 255 3966 } 3967 3968 // Invalid ranges are not set to a default, so can range check early. 3969 if (start < 0 || this.length < start || this.length < end) { 3970 throw new RangeError('Out of range index') 3971 } 3972 3973 if (end <= start) { 3974 return this 3975 } 3976 3977 start = start >>> 0 3978 end = end === undefined ? this.length : end >>> 0 3979 3980 if (!val) val = 0 3981 3982 var i 3983 if (typeof val === 'number') { 3984 for (i = start; i < end; i++) { 3985 this[i] = val 3986 } 3987 } else { 3988 var bytes = Buffer.isBuffer(val) 3989 ? val 3990 : utf8ToBytes(new Buffer(val, encoding).toString()) 3991 var len = bytes.length 3992 for (i = 0; i < end - start; i++) { 3993 this[i + start] = bytes[i % len] 3994 } 3995 } 3996 3997 return this 3998} 3999 4000// HELPER FUNCTIONS 4001// ================ 4002 4003var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g 4004 4005function base64clean (str) { 4006 // Node strips out invalid characters like \n and \t from the string, base64-js does not 4007 str = stringtrim(str).replace(INVALID_BASE64_RE, '') 4008 // Node converts strings with length < 2 to '' 4009 if (str.length < 2) return '' 4010 // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not 4011 while (str.length % 4 !== 0) { 4012 str = str + '=' 4013 } 4014 return str 4015} 4016 4017function stringtrim (str) { 4018 if (str.trim) return str.trim() 4019 return str.replace(/^\s+|\s+$/g, '') 4020} 4021 4022function toHex (n) { 4023 if (n < 16) return '0' + n.toString(16) 4024 return n.toString(16) 4025} 4026 4027function utf8ToBytes (string, units) { 4028 units = units || Infinity 4029 var codePoint 4030 var length = string.length 4031 var leadSurrogate = null 4032 var bytes = [] 4033 4034 for (var i = 0; i < length; i++) { 4035 codePoint = string.charCodeAt(i) 4036 4037 // is surrogate component 4038 if (codePoint > 0xD7FF && codePoint < 0xE000) { 4039 // last char was a lead 4040 if (!leadSurrogate) { 4041 // no lead yet 4042 if (codePoint > 0xDBFF) { 4043 // unexpected trail 4044 if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) 4045 continue 4046 } else if (i + 1 === length) { 4047 // unpaired lead 4048 if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) 4049 continue 4050 } 4051 4052 // valid lead 4053 leadSurrogate = codePoint 4054 4055 continue 4056 } 4057 4058 // 2 leads in a row 4059 if (codePoint < 0xDC00) { 4060 if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) 4061 leadSurrogate = codePoint 4062 continue 4063 } 4064 4065 // valid surrogate pair 4066 codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000 4067 } else if (leadSurrogate) { 4068 // valid bmp char, but last char was a lead 4069 if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) 4070 } 4071 4072 leadSurrogate = null 4073 4074 // encode utf8 4075 if (codePoint < 0x80) { 4076 if ((units -= 1) < 0) break 4077 bytes.push(codePoint) 4078 } else if (codePoint < 0x800) { 4079 if ((units -= 2) < 0) break 4080 bytes.push( 4081 codePoint >> 0x6 | 0xC0,
vendor: 4,107 bytes, lines 4082-4244
4082 codePoint & 0x3F | 0x80 4083 ) 4084 } else if (codePoint < 0x10000) { 4085 if ((units -= 3) < 0) break 4086 bytes.push( 4087 codePoint >> 0xC | 0xE0, 4088 codePoint >> 0x6 & 0x3F | 0x80, 4089 codePoint & 0x3F | 0x80 4090 ) 4091 } else if (codePoint < 0x110000) { 4092 if ((units -= 4) < 0) break 4093 bytes.push( 4094 codePoint >> 0x12 | 0xF0, 4095 codePoint >> 0xC & 0x3F | 0x80, 4096 codePoint >> 0x6 & 0x3F | 0x80, 4097 codePoint & 0x3F | 0x80 4098 ) 4099 } else { 4100 throw new Error('Invalid code point') 4101 } 4102 } 4103 4104 return bytes 4105} 4106 4107function asciiToBytes (str) { 4108 var byteArray = [] 4109 for (var i = 0; i < str.length; i++) { 4110 // Node's code seems to be doing this and not & 0x7F.. 4111 byteArray.push(str.charCodeAt(i) & 0xFF) 4112 } 4113 return byteArray 4114} 4115 4116function utf16leToBytes (str, units) { 4117 var c, hi, lo 4118 var byteArray = [] 4119 for (var i = 0; i < str.length; i++) { 4120 if ((units -= 2) < 0) break 4121 4122 c = str.charCodeAt(i) 4123 hi = c >> 8 4124 lo = c % 256 4125 byteArray.push(lo) 4126 byteArray.push(hi) 4127 } 4128 4129 return byteArray 4130} 4131 4132function base64ToBytes (str) { 4133 return base64.toByteArray(base64clean(str)) 4134} 4135 4136function blitBuffer (src, dst, offset, length) { 4137 for (var i = 0; i < length; i++) { 4138 if ((i + offset >= dst.length) || (i >= src.length)) break 4139 dst[i + offset] = src[i] 4140 } 4141 return i 4142} 4143 4144function isnan (val) { 4145 return val !== val // eslint-disable-line no-self-compare 4146} 4147 4148}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 4149 4150},{"base64-js":7,"ieee754":9,"isarray":10}],9:[function(require,module,exports){ 4151exports.read = function (buffer, offset, isLE, mLen, nBytes) { 4152 var e, m 4153 var eLen = nBytes * 8 - mLen - 1 4154 var eMax = (1 << eLen) - 1 4155 var eBias = eMax >> 1 4156 var nBits = -7 4157 var i = isLE ? (nBytes - 1) : 0 4158 var d = isLE ? -1 : 1 4159 var s = buffer[offset + i] 4160 4161 i += d 4162 4163 e = s & ((1 << (-nBits)) - 1) 4164 s >>= (-nBits) 4165 nBits += eLen 4166 for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} 4167 4168 m = e & ((1 << (-nBits)) - 1) 4169 e >>= (-nBits) 4170 nBits += mLen 4171 for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} 4172 4173 if (e === 0) { 4174 e = 1 - eBias 4175 } else if (e === eMax) { 4176 return m ? NaN : ((s ? -1 : 1) * Infinity) 4177 } else { 4178 m = m + Math.pow(2, mLen) 4179 e = e - eBias 4180 } 4181 return (s ? -1 : 1) * m * Math.pow(2, e - mLen) 4182} 4183 4184exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { 4185 var e, m, c 4186 var eLen = nBytes * 8 - mLen - 1 4187 var eMax = (1 << eLen) - 1 4188 var eBias = eMax >> 1 4189 var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) 4190 var i = isLE ? 0 : (nBytes - 1) 4191 var d = isLE ? 1 : -1 4192 var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 4193 4194 value = Math.abs(value) 4195 4196 if (isNaN(value) || value === Infinity) { 4197 m = isNaN(value) ? 1 : 0 4198 e = eMax 4199 } else { 4200 e = Math.floor(Math.log(value) / Math.LN2) 4201 if (value * (c = Math.pow(2, -e)) < 1) { 4202 e-- 4203 c *= 2 4204 } 4205 if (e + eBias >= 1) { 4206 value += rt / c 4207 } else { 4208 value += rt * Math.pow(2, 1 - eBias) 4209 } 4210 if (value * c >= 2) { 4211 e++ 4212 c /= 2 4213 } 4214 4215 if (e + eBias >= eMax) { 4216 m = 0 4217 e = eMax 4218 } else if (e + eBias >= 1) { 4219 m = (value * c - 1) * Math.pow(2, mLen) 4220 e = e + eBias 4221 } else { 4222 m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) 4223 e = 0 4224 } 4225 } 4226 4227 for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} 4228 4229 e = (e << mLen) | m 4230 eLen += mLen 4231 for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} 4232 4233 buffer[offset + i - d] |= s * 128 4234} 4235 4236},{}],10:[function(require,module,exports){ 4237var toString = {}.toString; 4238 4239module.exports = Array.isArray || function (arr) { 4240 return toString.call(arr) == '[object Array]'; 4241}; 4242 4243},{}]},{},[5]) 4244//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2hvbWVicmV3L2xpYi9ub2RlX21vZHVsZXMvd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS
42445qcyIsIm5vZGVfbW9kdWxlcy9ldmVudGVtaXR0ZXIzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2pzZngvYnVpbGQvanNmeC5qcyIsInNyYy9kcm9wem9uZS5qcyIsInNyYy9lbWl0dGVyLmpzIiwic3JjL21haW4uanMiLCJzcmMvb2RzLWNvbnZlcnRlci5qcyIsIi4uLy4uLy4uL2hvbWVicmV3L2xpYi9ub2RlX21vZHVsZXMvd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL2Jhc2U2NC1qcy9saWIvYjY0LmpzIiwiLi4vLi4vLi4vaG9tZWJyZXcvbGliL25vZGVfbW9kdWxlcy93YXRjaGlmeS9ub2RlX21vZHVsZXMvYnVmZmVyL2luZGV4LmpzIiwiLi4vLi4vLi4vaG9tZWJyZXcvbGliL25vZGVfbW9kdWxlcy93YXRjaGlmeS9ub2RlX21vZHVsZXMvaWVlZTc1NC9pbmRleC5qcyIsIi4uLy4uLy4uL2hvbWVicmV3L2xpYi9ub2RlX21vZHVsZXMvd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL2lzYXJyYXkvaW5kZXguanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDbFRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUM1dkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUM3R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQT
4244tBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQy9xREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybi
4244BuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCIndXNlIHN0cmljdCc7XG5cbnZhciBoYXMgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5XG4gICwgcHJlZml4ID0gJ34nO1xuXG4vKipcbiAqIENvbnN0cnVjdG9yIHRvIGNyZWF0ZSBhIHN0b3JhZ2UgZm9yIG91ciBgRUVgIG9iamVjdHMuXG4gKiBBbiBgRXZlbnRzYCBpbnN0YW5jZSBpcyBhIHBsYWluIG9iamVjdCB3aG9zZSBwcm9wZXJ0aWVzIGFyZSBldmVudCBuYW1lcy5cbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBFdmVudHMoKSB7fVxuXG4vL1xuLy8gV2UgdHJ5IHRvIG5vdCBpbmhlcml0IGZyb20gYE9iamVjdC5wcm90b3R5cGVgLiBJbiBzb21lIGVuZ2luZXMgY3JlYXRpbmcgYW5cbi8vIGluc3RhbmNlIGluIHRoaXMgd2F5IGlzIGZhc3RlciB0aGFuIGNhbGxpbmcgYE9iamVjdC5jcmVhdGUobnVsbClgIGRpcmVjdGx5LlxuLy8gSWYgYE9iamVjdC5jcmVhdGUobnVsbClgIGlzIG5vdCBzdXBwb3J0ZWQgd2UgcHJlZml4IHRoZSBldmVudCBuYW1lcyB3aXRoIGFcbi8vIGNoYXJhY3RlciB0byBtYWtlIHN1cmUgdGhhdCB0aGUgYnVpbHQtaW4gb2JqZWN0IHByb3BlcnRpZXMgYXJlIG5vdFxuLy8gb3ZlcnJpZGRlbiBvciB1c2VkIGFzIGFuIGF0dGFjayB2ZWN0b3IuXG4vL1xuaWYgKE9iamVjdC5jcmVhdGUpIHtcbiAgRXZlbnRzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5cbiAgLy9cbiAgLy8gVGhpcyBoYWNrIGlzIG5lZWRlZCBiZWNhdXNlIHRoZSBgX19wcm90b19fYCBwcm9wZXJ0eSBpcyBzdGlsbCBpbmhlcml0ZWQgaW5cbiAgLy8gc29tZSBvbGQgYnJvd3NlcnMgbGlrZSBBbmRyb2lkIDQsIGlQaG9uZSA1LjEsIE9wZXJhIDExIGFuZCBTYWZhcmkgNS5cbiAgLy9cbiAgaWYgKCFuZXcgRXZlbnRzKCkuX19wcm90b19fKSBwcmVmaXggPSBmYWxzZTtcbn1cblxuLyoqXG4gKiBSZXByZXNlbnRhdGlvbiBvZiBhIHNpbmdsZSBldmVudCBsaXN0ZW5lci5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgbGlzdGVuZXIgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge01peGVkfSBjb250ZXh0IFRoZSBjb250ZXh0IHRvIGludm9rZSB0aGUgbGlzdGVuZXIgd2l0aC5cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gW29uY2U9ZmFsc2VdIFNwZWNpZnkgaWYgdGhlIGxpc3RlbmVyIGlzIGEgb25lLXRpbWUgbGlzdGVuZXIuXG4gKiBAY29uc3RydWN0b3JcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBFRShmbiwgY29udGV4dCwgb25jZSkge1xuICB0aGlzLmZuID0gZm47XG4gIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG4gIHRoaXMub25jZSA9IG9uY2UgfHwgZmFsc2U7XG59XG5cbi8qKlxuICogTWluaW1hbCBgRXZlbnRFbWl0dGVyYCBpbnRlcmZhY2UgdGhhdCBpcyBtb2xkZWQgYWdhaW5zdCB0aGUgTm9kZS5qc1xuICogYEV2ZW50RW1pdHRlcmAgaW50ZXJmYWNlLlxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICogQGFwaSBwdWJsaWNcbiAqL1xuZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkge1xuICB0aGlzLl9ldmVudHMgPSBuZXcgRXZlbnRzKCk7XG4gIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbn1cblxuLyoqXG4gKiBSZXR1cm4gYW4gYXJyYXkgbGlzdGluZyB0aGUgZXZlbnRzIGZvciB3aGljaCB0aGUgZW1pdHRlciBoYXMgcmVnaXN0ZXJlZFxuICogbGlzdGVuZXJzLlxuICpcbiAqIEByZXR1cm5zIHtBcnJheX1cbiAqIEBhcGkgcHVibGljXG4gKi9cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZXZlbnROYW1lcyA9IGZ1bmN0aW9uIGV2ZW50TmFtZXMoKSB7XG4gIHZhciBuYW1lcyA9IFtdXG4gICAgLCBldmVudHNcbiAgICAsIG5hbWU7XG5cbiAgaWYgKHRoaXMuX2V2ZW50c0NvdW50ID09PSAwKSByZXR1cm4gbmFtZXM7XG5cbiAgZm9yIChuYW1lIGluIChldmVudHMgPSB0aGlzLl9ldmVudHMpKSB7XG4gICAgaWYgKGhhcy5jYWxsKGV2ZW50cywgbmFtZSkpIG5hbWVzLnB1c2gocHJlZml4ID8gbmFtZS5zbGljZSgxKSA6IG5hbWUpO1xuICB9XG5cbiAgaWYgKE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMpIHtcbiAgICByZXR1cm4gbmFtZXMuY29uY2F0KE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMoZXZlbnRzKSk7XG4gIH1cblxuICByZXR1cm4gbmFtZXM7XG59O1xuXG4vKipcbiAqIFJldHVybiB0aGUgbGlzdGVuZXJzIHJlZ2lzdGVyZWQgZm9yIGEgZ2l2ZW4gZXZlbnQuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8U3ltYm9sfSBldmVudCBUaGUgZXZlbnQgbmFtZS5cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gZXhpc3RzIE9ubHkgY2hlY2sgaWYgdGhlcmUgYXJlIGxpc3RlbmVycy5cbiAqIEByZXR1cm5zIHtBcnJheXxCb29sZWFufVxuICogQGFwaSBwdWJsaWNcbiAqL1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lcnMgPSBmdW5jdGlvbiBsaXN0ZW5lcnMoZXZlbnQsIGV4aXN0cykge1xuICB2YXIgZXZ0ID0gcHJlZml4ID8gcHJlZml4ICsgZXZlbnQgOiBldmVudFxuICAgICwgYXZhaWxhYmxlID0gdGhpcy5fZXZlbnRzW2V2dF07XG5cbiAgaWYgKGV4aXN0cykgcmV0dXJuICEhYXZhaWxhYmxlO1xuICBpZiAoIWF2YWlsYWJsZSkgcmV0dXJuIFtdO1xuICBpZiAoYXZhaWxhYmxlLmZuKSByZXR1cm4gW2F2YWlsYWJsZS5mbl07XG5cbiAgZm9yICh2YXIgaSA9IDAsIGwgPSBhdmFpbGFibGUubGVuZ3RoLCBlZSA9IG5ldyBBcnJheShsKTsgaSA8IGw7IGkrKykge1xuICAgIGVlW2ldID0gYXZhaWxhYmxlW2ldLmZuO1xuICB9XG5cbiAgcmV0dXJuIGVlO1xufTtcblxuLyoqXG4gKiBDYWxscyBlYWNoIG9mIHRoZSBsaXN0ZW5lcnMgcmVnaXN0ZXJlZCBmb3IgYSBnaXZlbiBldmVudC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xTeW1ib2x9IGV2ZW50IFRoZSBldmVudCBuYW1lLlxuICogQHJldHVybnMge0Jvb2xlYW59IGB0cnVlYCBpZiB0aGUgZXZlbnQgaGFkIGxpc3RlbmVycywgZWxzZSBgZmFsc2VgLlxuICogQGFwaSBwdWJsaWNcbiAqL1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24gZW1pdChldmVudCwgYTEsIGEyLCBhMywgYTQsIGE1KSB7XG4gIHZhciBldnQgPSBwcmVmaXggPyBwcmVmaXggKyBldmVudCA6IGV2ZW50O1xuXG4gIGlmICghdGhpcy5fZXZlbnRzW2V2dF0pIHJldHVybi
4244BmYWxzZTtcblxuICB2YXIgbGlzdGVuZXJzID0gdGhpcy5fZXZlbnRzW2V2dF1cbiAgICAsIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGhcbiAgICAsIGFyZ3NcbiAgICAsIGk7XG5cbiAgaWYgKGxpc3RlbmVycy5mbikge1xuICAgIGlmIChsaXN0ZW5lcnMub25jZSkgdGhpcy5yZW1vdmVMaXN0ZW5lcihldmVudCwgbGlzdGVuZXJzLmZuLCB1bmRlZmluZWQsIHRydWUpO1xuXG4gICAgc3dpdGNoIChsZW4pIHtcbiAgICAgIGNhc2UgMTogcmV0dXJuIGxpc3RlbmVycy5mbi5jYWxsKGxpc3RlbmVycy5jb250ZXh0KSwgdHJ1ZTtcbiAgICAgIGNhc2UgMjogcmV0dXJuIGxpc3RlbmVycy5mbi5jYWxsKGxpc3RlbmVycy5jb250ZXh0LCBhMSksIHRydWU7XG4gICAgICBjYXNlIDM6IHJldHVybiBsaXN0ZW5lcnMuZm4uY2FsbChsaXN0ZW5lcnMuY29udGV4dCwgYTEsIGEyKSwgdHJ1ZTtcbiAgICAgIGNhc2UgNDogcmV0dXJuIGxpc3RlbmVycy5mbi5jYWxsKGxpc3RlbmVycy5jb250ZXh0LCBhMSwgYTIsIGEzKSwgdHJ1ZTtcbiAgICAgIGNhc2UgNTogcmV0dXJuIGxpc3RlbmVycy5mbi5jYWxsKGxpc3RlbmVycy5jb250ZXh0LCBhMSwgYTIsIGEzLCBhNCksIHRydWU7XG4gICAgICBjYXNlIDY6IHJldHVybiBsaXN0ZW5lcnMuZm4uY2FsbChsaXN0ZW5lcnMuY29udGV4dCwgYTEsIGEyLCBhMywgYTQsIGE1KSwgdHJ1ZTtcbiAgICB9XG5cbiAgICBmb3IgKGkgPSAxLCBhcmdzID0gbmV3IEFycmF5KGxlbiAtMSk7IGkgPCBsZW47IGkrKykge1xuICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgfVxuXG4gICAgbGlzdGVuZXJzLmZuLmFwcGx5KGxpc3RlbmVycy5jb250ZXh0LCBhcmdzKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgbGVuZ3RoID0gbGlzdGVuZXJzLmxlbmd0aFxuICAgICAgLCBqO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAobGlzdGVuZXJzW2ldLm9uY2UpIHRoaXMucmVtb3ZlTGlzdGVuZXIoZXZlbnQsIGxpc3RlbmVyc1tpXS5mbiwgdW5kZWZpbmVkLCB0cnVlKTtcblxuICAgICAgc3dpdGNoIChsZW4pIHtcbiAgICAgICAgY2FzZSAxOiBsaXN0ZW5lcnNbaV0uZm4uY2FsbChsaXN0ZW5lcnNbaV0uY29udGV4dCk7IGJyZWFrO1xuICAgICAgICBjYXNlIDI6IGxpc3RlbmVyc1tpXS5mbi5jYWxsKGxpc3RlbmVyc1tpXS5jb250ZXh0LCBhMSk7IGJyZWFrO1xuICAgICAgICBjYXNlIDM6IGxpc3RlbmVyc1tpXS5mbi5jYWxsKGxpc3RlbmVyc1tpXS5jb250ZXh0LCBhMSwgYTIpOyBicmVhaztcbiAgICAgICAgY2FzZSA0OiBsaXN0ZW5lcnNbaV0uZm4uY2FsbChsaXN0ZW5lcnNbaV0uY29udGV4dCwgYTEsIGEyLCBhMyk7IGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIGlmICghYXJncykgZm9yIChqID0gMSwgYXJncyA9IG5ldyBBcnJheShsZW4gLTEpOyBqIDwgbGVuOyBqKyspIHtcbiAgICAgICAgICAgIGFyZ3NbaiAtIDFdID0gYXJndW1lbnRzW2pdO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGxpc3RlbmVyc1tpXS5mbi5hcHBseShsaXN0ZW5lcnNbaV0uY29udGV4dCwgYXJncyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG4vKipcbiAqIEFkZCBhIGxpc3RlbmVyIGZvciBhIGdpdmVuIGV2ZW50LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfFN5bWJvbH0gZXZlbnQgVGhlIGV2ZW50IG5hbWUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgbGlzdGVuZXIgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge01peGVkfSBbY29udGV4dD10aGlzXSBUaGUgY29udGV4dCB0byBpbnZva2UgdGhlIGxpc3RlbmVyIHdpdGguXG4gKiBAcmV0dXJucyB7RXZlbnRFbWl0dGVyfSBgdGhpc2AuXG4gKiBAYXBpIHB1YmxpY1xuICovXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uID0gZnVuY3Rpb24gb24oZXZlbnQsIGZuLCBjb250ZXh0KSB7XG4gIHZhciBsaXN0ZW5lciA9IG5ldyBFRShmbiwgY29udGV4dCB8fCB0aGlzKVxuICAgICwgZXZ0ID0gcHJlZml4ID8gcHJlZml4ICsgZXZlbnQgOiBldmVudDtcblxuICBpZiAoIXRoaXMuX2V2ZW50c1tldnRdKSB0aGlzLl9ldmVudHNbZXZ0XSA9IGxpc3RlbmVyLCB0aGlzLl9ldmVudHNDb3VudCsrO1xuICBlbHNlIGlmICghdGhpcy5fZXZlbnRzW2V2dF0uZm4pIHRoaXMuX2V2ZW50c1tldnRdLnB1c2gobGlzdGVuZXIpO1xuICBlbHNlIHRoaXMuX2V2ZW50c1tldnRdID0gW3RoaXMuX2V2ZW50c1tldnRdLCBsaXN0ZW5lcl07XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEFkZCBhIG9uZS10aW1lIGxpc3RlbmVyIGZvciBhIGdpdmVuIGV2ZW50LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfFN5bWJvbH0gZXZlbnQgVGhlIGV2ZW50IG5hbWUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgbGlzdGVuZXIgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge01peGVkfSBbY29udGV4dD10aGlzXSBUaGUgY29udGV4dCB0byBpbnZva2UgdGhlIGxpc3RlbmVyIHdpdGguXG4gKiBAcmV0dXJucyB7RXZlbnRFbWl0dGVyfSBgdGhpc2AuXG4gKiBAYXBpIHB1YmxpY1xuICovXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiBvbmNlKGV2ZW50LCBmbiwgY29udGV4dCkge1xuICB2YXIgbGlzdGVuZXIgPSBuZXcgRUUoZm4sIGNvbnRleHQgfHwgdGhpcywgdHJ1ZSlcbiAgICAsIGV2dCA9IHByZWZpeCA/IHByZWZpeCArIGV2ZW50IDogZXZlbnQ7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHNbZXZ0XSkgdGhpcy5fZXZlbnRzW2V2dF0gPSBsaXN0ZW5lciwgdGhpcy5fZXZlbnRzQ291bnQrKztcbiAgZWxzZSBpZiAoIXRoaXMuX2V2ZW50c1tldnRdLmZuKSB0aGlzLl9ldmVudHNbZXZ0XS5wdXNoKGxpc3RlbmVyKTtcbiAgZWxzZSB0aGlzLl9ldmVudHNbZXZ0XSA9IFt0aGlzLl9ldmVudHNbZXZ0XSwgbGlzdGVuZXJdO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZW1vdmUgdGhlIGxpc3RlbmVycyBvZiBhIGdpdmVuIGV2ZW50LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfFN5bWJvbH0gZXZlbnQgVGhlIGV2ZW50IG5hbWUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBPbmx5IHJlbW92ZSB0aGUgbGlzdGVuZXJzIHRoYXQgbWF0Y2ggdGhpcyBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7TWl4ZWR9IGNvbnRleHQgT25seSByZW1vdmUgdGhlIGxpc3RlbmVycyB0aGF0IGhh
4244dmUgdGhpcyBjb250ZXh0LlxuICogQHBhcmFtIHtCb29sZWFufSBvbmNlIE9ubHkgcmVtb3ZlIG9uZS10aW1lIGxpc3RlbmVycy5cbiAqIEByZXR1cm5zIHtFdmVudEVtaXR0ZXJ9IGB0aGlzYC5cbiAqIEBhcGkgcHVibGljXG4gKi9cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlTGlzdGVuZXIgPSBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcihldmVudCwgZm4sIGNvbnRleHQsIG9uY2UpIHtcbiAgdmFyIGV2dCA9IHByZWZpeCA/IHByZWZpeCArIGV2ZW50IDogZXZlbnQ7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHNbZXZ0XSkgcmV0dXJuIHRoaXM7XG4gIGlmICghZm4pIHtcbiAgICBpZiAoLS10aGlzLl9ldmVudHNDb3VudCA9PT0gMCkgdGhpcy5fZXZlbnRzID0gbmV3IEV2ZW50cygpO1xuICAgIGVsc2UgZGVsZXRlIHRoaXMuX2V2ZW50c1tldnRdO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgdmFyIGxpc3RlbmVycyA9IHRoaXMuX2V2ZW50c1tldnRdO1xuXG4gIGlmIChsaXN0ZW5lcnMuZm4pIHtcbiAgICBpZiAoXG4gICAgICAgICBsaXN0ZW5lcnMuZm4gPT09IGZuXG4gICAgICAmJiAoIW9uY2UgfHwgbGlzdGVuZXJzLm9uY2UpXG4gICAgICAmJiAoIWNvbnRleHQgfHwgbGlzdGVuZXJzLmNvbnRleHQgPT09IGNvbnRleHQpXG4gICAgKSB7XG4gICAgICBpZiAoLS10aGlzLl9ldmVudHNDb3VudCA9PT0gMCkgdGhpcy5fZXZlbnRzID0gbmV3IEV2ZW50cygpO1xuICAgICAgZWxzZSBkZWxldGUgdGhpcy5fZXZlbnRzW2V2dF07XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGZvciAodmFyIGkgPSAwLCBldmVudHMgPSBbXSwgbGVuZ3RoID0gbGlzdGVuZXJzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoXG4gICAgICAgICAgIGxpc3RlbmVyc1tpXS5mbiAhPT0gZm5cbiAgICAgICAgfHwgKG9uY2UgJiYgIWxpc3RlbmVyc1tpXS5vbmNlKVxuICAgICAgICB8fCAoY29udGV4dCAmJiBsaXN0ZW5lcnNbaV0uY29udGV4dCAhPT0gY29udGV4dClcbiAgICAgICkge1xuICAgICAgICBldmVudHMucHVzaChsaXN0ZW5lcnNbaV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vXG4gICAgLy8gUmVzZXQgdGhlIGFycmF5LCBvciByZW1vdmUgaXQgY29tcGxldGVseSBpZiB3ZSBoYXZlIG5vIG1vcmUgbGlzdGVuZXJzLlxuICAgIC8vXG4gICAgaWYgKGV2ZW50cy5sZW5ndGgpIHRoaXMuX2V2ZW50c1tldnRdID0gZXZlbnRzLmxlbmd0aCA9PT0gMSA/IGV2ZW50c1swXSA6IGV2ZW50cztcbiAgICBlbHNlIGlmICgtLXRoaXMuX2V2ZW50c0NvdW50ID09PSAwKSB0aGlzLl9ldmVudHMgPSBuZXcgRXZlbnRzKCk7XG4gICAgZWxzZSBkZWxldGUgdGhpcy5fZXZlbnRzW2V2dF07XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogUmVtb3ZlIGFsbCBsaXN0ZW5lcnMsIG9yIHRob3NlIG9mIHRoZSBzcGVjaWZpZWQgZXZlbnQuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8U3ltYm9sfSBbZXZlbnRdIFRoZSBldmVudCBuYW1lLlxuICogQHJldHVybnMge0V2ZW50RW1pdHRlcn0gYHRoaXNgLlxuICogQGFwaSBwdWJsaWNcbiAqL1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBmdW5jdGlvbiByZW1vdmVBbGxMaXN0ZW5lcnMoZXZlbnQpIHtcbiAgdmFyIGV2dDtcblxuICBpZiAoZXZlbnQpIHtcbiAgICBldnQgPSBwcmVmaXggPyBwcmVmaXggKyBldmVudCA6IGV2ZW50O1xuICAgIGlmICh0aGlzLl9ldmVudHNbZXZ0XSkge1xuICAgICAgaWYgKC0tdGhpcy5fZXZlbnRzQ291bnQgPT09IDApIHRoaXMuX2V2ZW50cyA9IG5ldyBFdmVudHMoKTtcbiAgICAgIGVsc2UgZGVsZXRlIHRoaXMuX2V2ZW50c1tldnRdO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aGlzLl9ldmVudHMgPSBuZXcgRXZlbnRzKCk7XG4gICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vL1xuLy8gQWxpYXMgbWV0aG9kcyBuYW1lcyBiZWNhdXNlIHBlb3BsZSByb2xsIGxpa2UgdGhhdC5cbi8vXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9mZiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlTGlzdGVuZXI7XG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyID0gRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbjtcblxuLy9cbi8vIFRoaXMgZnVuY3Rpb24gZG9lc24ndCBhcHBseSBhbnltb3JlLlxuLy9cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuc2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24gc2V0TWF4TGlzdGVuZXJzKCkge1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8vXG4vLyBFeHBvc2UgdGhlIHByZWZpeC5cbi8vXG5FdmVudEVtaXR0ZXIucHJlZml4ZWQgPSBwcmVmaXg7XG5cbi8vXG4vLyBFeHBvc2UgdGhlIG1vZHVsZS5cbi8vXG5pZiAoJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiBtb2R1bGUpIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSBFdmVudEVtaXR0ZXI7XG59XG4iLCJ2YXIganNmeDtcclxuKGZ1bmN0aW9uIChqc2Z4KSB7XHJcbiAgICB2YXIgRmlsdGVyID0gKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBmdW5jdGlvbiBGaWx0ZXIodmVydGV4U291cmNlLCBmcmFnbWVudFNvdXJjZSkge1xyXG4gICAgICAgICAgICBpZiAodmVydGV4U291cmNlID09PSB2b2lkIDApIHsgdmVydGV4U291cmNlID0gbnVsbDsgfVxyXG4gICAgICAgICAgICBpZiAoZnJhZ21lbnRTb3VyY2UgPT09IHZvaWQgMCkgeyBmcmFnbWVudFNvdXJjZSA9IG51bGw7IH1cclxuICAgICAgICAgICAgdGhpcy52ZXJ0ZXhTb3VyY2UgPSB2ZXJ0ZXhTb3VyY2U7XHJcbiAgICAgICAgICAgIHRoaXMuZnJhZ21lbnRTb3VyY2UgPSBmcmFnbWVudFNvdXJjZTtcclxuICAgICAgICAgICAgdGhpcy5wcm9wZXJ0aWVzID0ge307XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFJldHVybnMgYWxsIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBzaGFkZXIuIFVzZWZ1bCBmb3IgZHJhd1dlYkdsIHdoZW4gYXJlIGFyZSBqdXN0IHBhc3NpbmcgYWxvbmcgZGF0YVxyXG4gICAgICAgICAqIHRvIHRoZSBzaGFkZXIuXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBAcmV0dXJucyB7e318Kn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBGaWx0ZXIucHJvdG90eXBlLmdldFByb3BlcnRpZXMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgI
4244HJldHVybiB0aGlzLnByb3BlcnRpZXM7XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBUaGUgamF2YXNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgZmlsdGVyXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBAcGFyYW0gaW1hZ2VEYXRhXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgRmlsdGVyLnByb3RvdHlwZS5kcmF3Q2FudmFzID0gZnVuY3Rpb24gKGltYWdlRGF0YSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNdXN0IGJlIGltcGxlbWVudGVkXCIpO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogVGhlIFdlYkdMIGltcGxlbWVudGF0aW9uIG9mIHRoZSBmaWx0ZXJcclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIEBwYXJhbSByZW5kZXJlclxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEZpbHRlci5wcm90b3R5cGUuZHJhd1dlYkdMID0gZnVuY3Rpb24gKHJlbmRlcmVyKSB7XHJcbiAgICAgICAgICAgIHZhciBzaGFkZXIgPSByZW5kZXJlci5nZXRTaGFkZXIodGhpcyk7XHJcbiAgICAgICAgICAgIHZhciBwcm9wZXJ0aWVzID0gdGhpcy5nZXRQcm9wZXJ0aWVzKCk7XHJcbiAgICAgICAgICAgIHJlbmRlcmVyLmdldFRleHR1cmUoKS51c2UoKTtcclxuICAgICAgICAgICAgcmVuZGVyZXIuZ2V0TmV4dFRleHR1cmUoKS5kcmF3VG8oZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgc2hhZGVyLnVuaWZvcm1zKHByb3BlcnRpZXMpLmRyYXdSZWN0KCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgRmlsdGVyLnByb3RvdHlwZS5nZXRWZXJ0ZXhTb3VyY2UgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnZlcnRleFNvdXJjZTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIEZpbHRlci5wcm90b3R5cGUuZ2V0RnJhZ21lbnRTb3VyY2UgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmZyYWdtZW50U291cmNlO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgRmlsdGVyLmNsYW1wID0gZnVuY3Rpb24gKGxvdywgdmFsdWUsIGhpZ2gpIHtcclxuICAgICAgICAgICAgcmV0dXJuIE1hdGgubWF4KGxvdywgTWF0aC5taW4odmFsdWUsIGhpZ2gpKTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIHJldHVybiBGaWx0ZXI7XHJcbiAgICB9KSgpO1xyXG4gICAganNmeC5GaWx0ZXIgPSBGaWx0ZXI7XHJcbn0pKGpzZnggfHwgKGpzZnggPSB7fSkpO1xyXG52YXIgX19leHRlbmRzID0gKHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMpIHx8IGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTtcclxuICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGU7XHJcbiAgICBkLnByb3RvdHlwZSA9IG5ldyBfXygpO1xyXG59O1xyXG52YXIganNmeDtcclxuKGZ1bmN0aW9uIChqc2Z4KSB7XHJcbiAgICB2YXIgSXRlcmFibGVGaWx0ZXIgPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgICAgIF9fZXh0ZW5kcyhJdGVyYWJsZUZpbHRlciwgX3N1cGVyKTtcclxuICAgICAgICBmdW5jdGlvbiBJdGVyYWJsZUZpbHRlcigpIHtcclxuICAgICAgICAgICAgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIEl0ZXJhYmxlRmlsdGVyLnByb3RvdHlwZS5kcmF3Q2FudmFzID0gZnVuY3Rpb24gKGltYWdlRGF0YSkge1xyXG4gICAgICAgICAgICByZXR1cm4gSXRlcmFibGVGaWx0ZXIuZHJhd0NhbnZhcyhbdGhpc10sIGltYWdlRGF0YSk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICBJdGVyYWJsZUZpbHRlci5wcm90b3R5cGUuaXRlcmF0ZUNhbnZhcyA9IGZ1bmN0aW9uIChpbWFnZURhdGEpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTXVzdCBiZSBpbXBsZW1lbnRlZFwiKTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIEl0ZXJhYmxlRmlsdGVyLmRyYXdDYW52YXMgPSBmdW5jdGlvbiAoZmlsdGVycywgaW1hZ2VEYXRhKSB7XHJcbiAgICAgICAgICAgIHZhciBoZWxwZXI7XHJcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaW1hZ2VEYXRhLmRhdGEubGVuZ3RoOyBpICs9IDQpIHtcclxuICAgICAgICAgICAgICAgIGhlbHBlciA9IG5ldyBqc2Z4LnV0aWwuSW1hZ2VEYXRhSGVscGVyKGltYWdlRGF0YSwgaSk7XHJcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGZpbHRlcnMubGVuZ3RoOyBqKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBmaWx0ZXJzW2pdLml0ZXJhdGVDYW52YXMoaGVscGVyKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGhlbHBlci5zYXZlKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIGltYWdlRGF0YTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIHJldHVybiBJdGVyYWJsZUZpbHRlcjtcclxuICAgIH0pKGpzZnguRmlsdGVyKTtcclxuICAgIGpzZnguSXRlcmFibGVGaWx0ZXIgPSBJdGVyYWJsZUZpbHRlcjtcclxufSkoanNmeCB8fCAoanNmeCA9IHt9KSk7XHJcbnZhciBqc2Z4O1xyXG4oZnVuY3Rpb24gKGpzZngpIHtcclxuICAgIHZhciBoYXNXZWJHTCA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgdmFyIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJjYW52YXNcIik7XHJcbiAgICAgICAgICAgIHJldHVybiAhIShjYW52YXMuZ2V0Q29udGV4dChcIndlYmdsXCIpIHx8IGNhbnZhcy5nZXRDb250ZXh0KFwiZXhwZXJpbWVudGFsLXdlYmdsXCIpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgIH0pKCk7XHJcbiAgICBmdW5jdGlvbiBSZW5kZXJlcih0eXBlKSB7XHJcbiAgICAgICAgaWYgKCF0eXBlKSB7XHJcbiAgICAgICAgICAgIHR5cGUgPSBoYXNXZWJHTCA/IFwid2ViZ2xcIiA6IFwiY2FudmFzXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0eXBlID09PSBcIndlYmdsXCIpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG5ldyBqc2Z4LndlYmdsLlJlbmRlcmVyKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgI
4244HJldHVybiBuZXcganNmeC5jYW52YXMuUmVuZGVyZXIoKTtcclxuICAgIH1cclxuICAgIGpzZnguUmVuZGVyZXIgPSBSZW5kZXJlcjtcclxufSkoanNmeCB8fCAoanNmeCA9IHt9KSk7XHJcbnZhciBqc2Z4O1xyXG4oZnVuY3Rpb24gKGpzZngpIHtcclxuICAgIHZhciBTb3VyY2UgPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIFNvdXJjZShlbGVtZW50KSB7XHJcbiAgICAgICAgICAgIHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShTb3VyY2UucHJvdG90eXBlLCBcIndpZHRoXCIsIHtcclxuICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lbGVtZW50LndpZHRoO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxyXG4gICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgICAgICB9KTtcclxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoU291cmNlLnByb3RvdHlwZSwgXCJoZWlnaHRcIiwge1xyXG4gICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnQuaGVpZ2h0O1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxyXG4gICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gU291cmNlO1xyXG4gICAgfSkoKTtcclxuICAgIGpzZnguU291cmNlID0gU291cmNlO1xyXG59KShqc2Z4IHx8IChqc2Z4ID0ge30pKTtcclxudmFyIGpzZng7XHJcbihmdW5jdGlvbiAoanNmeCkge1xyXG4gICAgdmFyIGNhbnZhcztcclxuICAgIChmdW5jdGlvbiAoY2FudmFzKSB7XHJcbiAgICAgICAgdmFyIFJlbmRlcmVyID0gKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgZnVuY3Rpb24gUmVuZGVyZXIoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNhbnZhcyA9IGpzZnguY2FudmFzLlJlbmRlcmVyLmNyZWF0ZUNhbnZhcygpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jdHggPSB0aGlzLmNhbnZhcy5nZXRDb250ZXh0KFwiMmRcIik7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNvdXJjZSA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmltYWdlRGF0YSA9IG51bGw7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgUmVuZGVyZXIucHJvdG90eXBlLnNldFNvdXJjZSA9IGZ1bmN0aW9uIChzb3VyY2UpIHtcclxuICAgICAgICAgICAgICAgIC8vIGZpcnN0LCBjbGVhbiB1cFxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc291cmNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jbGVhblVwKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvLyByZS1zZXQgZGF0YSBhbmQgc3RhcnQgcmVuZGVyaW5nXHJcbiAgICAgICAgICAgICAgICB0aGlzLnNvdXJjZSA9IHNvdXJjZTtcclxuICAgICAgICAgICAgICAgIHRoaXMuY2FudmFzLndpZHRoID0gc291cmNlLndpZHRoO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jYW52YXMuaGVpZ2h0ID0gc291cmNlLmhlaWdodDtcclxuICAgICAgICAgICAgICAgIC8vIGRyYXcgdGhlIGltYWdlIG9uIHRvIGEgY2FudmFzIHdlIGNhbiBtYW5pcHVsYXRlXHJcbiAgICAgICAgICAgICAgICB0aGlzLmN0eC5kcmF3SW1hZ2Uoc291cmNlLmVsZW1lbnQsIDAsIDAsIHNvdXJjZS53aWR0aCwgc291cmNlLmhlaWdodCk7XHJcbiAgICAgICAgICAgICAgICAvLyBzdG9yZSB0aGUgcGl4ZWxzXHJcbiAgICAgICAgICAgICAgICB0aGlzLmltYWdlRGF0YSA9IHRoaXMuY3R4LmdldEltYWdlRGF0YSgwLCAwLCBzb3VyY2Uud2lkdGgsIHNvdXJjZS5oZWlnaHQpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIFJlbmRlcmVyLnByb3RvdHlwZS5nZXRTb3VyY2UgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zb3VyY2U7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIFJlbmRlcmVyLnByb3RvdHlwZS5hcHBseUZpbHRlciA9IGZ1bmN0aW9uIChmaWx0ZXIpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuaW1hZ2VEYXRhID0gZmlsdGVyLmRyYXdDYW52YXModGhpcy5pbWFnZURhdGEpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIFJlbmRlcmVyLnByb3RvdHlwZS5hcHBseUZpbHRlcnMgPSBmdW5jdGlvbiAoZmlsdGVycykge1xyXG4gICAgICAgICAgICAgICAgdmFyIHN0YWNrID0gW107XHJcbiAgICAgICAgICAgICAgICB2Y
4244XIgZmlsdGVyO1xyXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBmaWx0ZXJzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gZmlsdGVyc1tpXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZmlsdGVyIGluc3RhbmNlb2YganNmeC5JdGVyYWJsZUZpbHRlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGFjay5wdXNoKGZpbHRlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiB0aGVyZSBpZiBzb21ldGhpbmcgaW4gdGhlIHN0YWNrLCBhcHBseSB0aGF0IGZpcnN0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGFjay5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFwcGx5RmlsdGVyU3RhY2soc3RhY2spO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhY2sgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBhcHBseSBjdXJyZW50IGZpbHRlclxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFwcGx5RmlsdGVyKGZpbHRlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy8gaWYgdGhlcmUgaXMgc3RpbGwgYSBzdGFjayBsZWZ0LCBhcHBseSBpdFxyXG4gICAgICAgICAgICAgICAgaWYgKHN0YWNrLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFwcGx5RmlsdGVyU3RhY2soc3RhY2spO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIFJlbmRlcmVyLnByb3RvdHlwZS5hcHBseUZpbHRlclN0YWNrID0gZnVuY3Rpb24gKHN0YWNrKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmltYWdlRGF0YSA9IGpzZnguSXRlcmFibGVGaWx0ZXIuZHJhd0NhbnZhcyhzdGFjaywgdGhpcy5pbWFnZURhdGEpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIFJlbmRlcmVyLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmN0eC5wdXRJbWFnZURhdGEodGhpcy5pbWFnZURhdGEsIDAsIDApO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBSZW5kZXJlci5wcm90b3R5cGUuZ2V0Q2FudmFzID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2FudmFzO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBSZW5kZXJlci5wcm90b3R5cGUuY2xlYW5VcCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuaW1hZ2VEYXRhID0gbnVsbDtcclxuICAgICAgICAgICAgICAgIHRoaXMuY3R4LmNsZWFyUmVjdCgwLCAwLCB0aGlzLmNhbnZhcy53aWR0aCwgdGhpcy5jYW52YXMuaGVpZ2h0KTtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgUmVuZGVyZXIuY3JlYXRlQ2FudmFzID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiBCdWZmZXIgIT09IFwidW5kZWZpbmVkXCIgJiYgdHlwZW9mIHdpbmRvdyA9PT0gXCJ1bmRlZmluZWRcIiA/XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gQ29tbWVudGVkIG91dCwgc2luY2UgaXQgd2FzIGNhdXNpbmcgcmVxdWlyZSBmYWlsdXJlcy5cclxuICAgICAgICAgICAgICAgICAgICAvLyBuZXcgKHJlcXVpcmUoXCJjYW52YXNcIikpKDEwMCwgMTAwKSA6XHJcbiAgICAgICAgICAgICAgICAgICAgbnVsbCA6XHJcbiAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgcmV0dXJuIFJlbmRlcmVyO1xyXG4gICAgICAgIH0pKCk7XHJcbiAgICAgICAgY2FudmFzLlJlbmRlcmVyID0gUmVuZGVyZXI7XHJcbiAgICB9KShjYW52YXMgPSBqc2Z4LmNhbnZhcyB8fCAoanNmeC5jYW52YXMgPSB7fSkpO1xyXG59KShqc2Z4IHx8IChqc2Z4ID0ge30pKTtcclxudmFyIGpzZng7XHJcbihmdW5jdGlvbiAoanNmeCkge1xyXG4gICAgdmFyIGZpbHRlcjtcclxuICAgIChmdW5jdGlvbiAoZmlsdGVyKSB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGZpbHRlciAgICAgICAgIEJsdXJcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gICAgVGhpcyBpcyB0aGUgVHJpYW5nbGVCbHVyIGZyb20gZ2xmeCwgYnV0IGZvciB0aGUgY2FudmFzIGltcGxlbWVudGF0aW9uLCB3ZSBhcmUgY2hlYXRpbmcgYnlcclxuICAgICAgICAgKiAgICAgICAgICAgICAgICAgdXNpbmcgU3RhY2tCbHVyLiBUaGUgaW1wbGVtZW50YXRpb25zIGFyZSBvYnZpb3VzbHkgdmVyeSBkaWZmZXJlbnQsIGJ1dCB0aGUgcmVzdWx0cyBhcmUgdmVyeSBjbG9zZS5cclxuICAgICAgICAgKiBAcGFyYW0gcmFkaXVzICAgVGhlIHJhZGl1cyBvZiB0aGUgcHlyYW1pZCBjb252b2x2ZWQgd2l0aCB0aGUgaW1hZ2UuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdmFyIEJsdXIgPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgICAgICAgICBfX2V4dGVuZHMoQmx1ciwgX3N1cGVyKTtcclxuICAgICAgICAgICAgZnVuY3Rpb24gQmx1cihyYWRpdXMpIHtcclxuICAgICAgICAgICAgICAgIF9zdXBlci5jYWxsKHRoaXMsIG51bGwsIFwiXFxuICAgICAgICAgICAgdW5pZm9ybSBzYW1wbGVyMkQgdGV4dHVyZTtcXG4gICAgICAgICAgICB1bmlmb3JtIHZlYzIgZGVsdGE7XFxuICAgICAgICAgICAgdmFyeWluZyB2ZWMyIHRleENvb3JkO1xcblxcbiAgICAgICAgICAgIHZvaWQgbWFpbigpIHtcXG4gICAgICAgICAgICAgICAgdmVjNCBjb2xvciA9IHZlYzQoMC4wKTtcXG4gICAgICAgICAgICAgICAgZmxvYXQgdG90YWwgPSAwLjA7XFxuXFxuICAgICAgICAgICAgICAgIC8qIHJhbmRvbWl6ZSB0aGUgbG9va3VwIHZhbHVlcyB0byBoaWRlIHRoZSBmaXhlZCBudW1iZXIgb2Ygc2FtcGxlcyAqL1xcbiAgICAgICAgICAgICAgICAvL2Zsb2F0IG9mZnNldCA9IHJhbmRvbSh2ZWMzKDEyLjk4OTgsIDc4LjIzMywgMTUxLjcxODIpLCAwLjApO1xcblxcbiAgICAgICAgICAgICAgICB2ZWMzIHNjYWxlID0gdmVjMygxMi45ODk4LCA3OC4yMzMsI
4244DE1MS43MTgyKTtcXG4gICAgICAgICAgICAgICAgZmxvYXQgb2Zmc2V0ID0gZnJhY3Qoc2luKGRvdChnbF9GcmFnQ29vcmQueHl6ICsgMC4wLCBzY2FsZSkpICogNDM3NTguNTQ1MyArIDAuMCk7XFxuXFxuICAgICAgICAgICAgICAgIGZvciAoZmxvYXQgdCA9IC0zMC4wOyB0IDw9IDMwLjA7IHQrKykge1xcbiAgICAgICAgICAgICAgICAgICAgZmxvYXQgcGVyY2VudCA9ICh0ICsgb2Zmc2V0IC0gMC41KSAvIDMwLjA7XFxuICAgICAgICAgICAgICAgICAgICBmbG9hdCB3ZWlnaHQgPSAxLjAgLSBhYnMocGVyY2VudCk7XFxuICAgICAgICAgICAgICAgICAgICB2ZWM0IHNhbXBsZSA9IHRleHR1cmUyRCh0ZXh0dXJlLCB0ZXhDb29yZCArIGRlbHRhICogcGVyY2VudCk7XFxuXFxuICAgICAgICAgICAgICAgICAgICAvKiBzd2l0Y2ggdG8gcHJlLW11bHRpcGxpZWQgYWxwaGEgdG8gY29ycmVjdGx5IGJsdXIgdHJhbnNwYXJlbnQgaW1hZ2VzICovXFxuICAgICAgICAgICAgICAgICAgICBzYW1wbGUucmdiICo9IHNhbXBsZS5hO1xcblxcbiAgICAgICAgICAgICAgICAgICAgY29sb3IgKz0gc2FtcGxlICogd2VpZ2h0O1xcbiAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gd2VpZ2h0O1xcbiAgICAgICAgICAgICAgICB9XFxuXFxuICAgICAgICAgICAgICAgIGdsX0ZyYWdDb2xvciA9IGNvbG9yIC8gdG90YWw7XFxuXFxuICAgICAgICAgICAgICAgIC8qIHN3aXRjaCBiYWNrIGZyb20gcHJlLW11bHRpcGxpZWQgYWxwaGEgKi9cXG4gICAgICAgICAgICAgICAgZ2xfRnJhZ0NvbG9yLnJnYiAvPSBnbF9GcmFnQ29sb3IuYSArIDAuMDAwMDE7XFxuICAgICAgICAgICAgfVxcbiAgICAgICAgXCIpO1xyXG4gICAgICAgICAgICAgICAgLy8gc2V0IHByb3BlcnRpZXNcclxuICAgICAgICAgICAgICAgIHRoaXMucHJvcGVydGllcy5yYWRpdXMgPSByYWRpdXM7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgQmx1ci5wcm90b3R5cGUuZHJhd1dlYkdMID0gZnVuY3Rpb24gKHJlbmRlcmVyKSB7XHJcbiAgICAgICAgICAgICAgICB2Y
4244XIgc2hhZGVyID0gcmVuZGVyZXIuZ2V0U2hhZGVyKHRoaXMpO1xyXG4gICAgICAgICAgICAgICAgdmFyIGZpcnN0UGFzcyA9IHsgZGVsdGE6IFt0aGlzLnByb3BlcnRpZXMucmFkaXVzIC8gcmVuZGVyZXIuZ2V0U291cmNlKCkud2lkdGgsIDBdIH07XHJcbiAgICAgICAgICAgICAgICB2YXIgc2Vjb25kUGFzcyA9IHsgZGVsdGE6IFswLCB0aGlzLnByb3BlcnRpZXMucmFkaXVzIC8gcmVuZGVyZXIuZ2V0U291cmNlKCkuaGVpZ2h0XSB9O1xyXG4gICAgICAgICAgICAgICAgcmVuZGVyZXIuZ2V0VGV4dHVyZSgpLnVzZSgpO1xyXG4gICAgICAgICAgICAgICAgcmVuZGVyZXIuZ2V0TmV4dFRleHR1cmUoKS5kcmF3VG8oZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNoYWRlci51bmlmb3JtcyhmaXJzdFBhc3MpLmRyYXdSZWN0KCk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIHJlbmRlcmVyLmdldFRleHR1cmUoKS51c2UoKTtcclxuICAgICAgICAgICAgICAgIHJlbmRlcmVyLmdldE5leHRUZXh0dXJlKCkuZHJhd1RvKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICBzaGFkZXIudW5pZm9ybXMoc2Vjb25kUGFzcykuZHJhd1JlY3QoKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBCbHVyLnByb3RvdHlwZS5kcmF3Q2FudmFzID0gZnVuY3Rpb24gKGltYWdlRGF0YSkge1xyXG4gICAgICAgICAgICAgICAgdmFyIHBpeGVscyA9IGltYWdlRGF0YS5kYXRhO1xyXG4gICAgICAgICAgICAgICAgdmFyIHJhZGl1cyA9IHRoaXMucHJvcGVydGllcy5yYWRpdXM7XHJcbiAgICAgICAgICAgICAgICB2Y
4244XIgd2lkdGggPSBpbWFnZURhdGEud2lkdGg7XHJcbiAgICAgICAgICAgICAgICB2YXIgaGVpZ2h0ID0gaW1hZ2VEYXRhLmhlaWdodDtcclxuICAgICAgICAgICAgICAgIHZhciB4LCB5LCBpLCBwLCB5cCwgeWksIHl3LCByX3N1bSwgZ19zdW0sIGJfc3VtLCBhX3N1bSwgcl9vdXRfc3VtLCBnX291dF9zdW0sIGJfb3V0X3N1bSwgYV9vdXRfc3VtLCByX2luX3N1bSwgZ19pbl9zdW0sIGJfaW5fc3VtLCBhX2luX3N1bSwgcHIsIHBnLCBwYiwgcGEsIHJicztcclxuICAgICAgICAgICAgICAgIHZhciBkaXYgPSByYWRpdXMgKyByYWRpdXMgKyAxO1xyXG4gICAgICAgICAgICAgICAgdmFyIHdpZHRoTWludXMxID0gd2lkdGggLSAxO1xyXG4gICAgICAgICAgICAgICAgdmFyIGhlaWdodE1pbnVzMSA9IGhlaWdodCAtIDE7XHJcbiAgICAgICAgICAgICAgICB2YXIgcmFkaXVzUGx1czEgPSByYWRpdXMgKyAxO1xyXG4gICAgICAgICAgICAgICAgdmFyIHN1bUZhY3RvciA9IHJhZGl1c1BsdXMxICogKHJhZGl1c1BsdXMxICsgMSkgLyAyO1xyXG4gICAgICAgICAgICAgICAgdmFyIHN0YWNrU3RhcnQgPSBuZXcgQmx1clN0YWNrKCk7XHJcbiAgICAgICAgICAgICAgICB2YXIgc3RhY2sgPSBzdGFja1N0YXJ0O1xyXG4gICAgICAgICAgICAgICAgZm9yIChpID0gMTsgaSA8IGRpdjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc3RhY2sgPSBzdGFjay5uZXh0ID0gbmV3IEJsdXJTdGFjaygpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpID09IHJhZGl1c1BsdXMxKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB2Y
4244XIgc3RhY2tFbmQgPSBzdGFjaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHN0YWNrLm5leHQgPSBzdGFja1N0YXJ0O1xyXG4gICAgICAgICAgICAgICAgdmFyIHN0YWNrSW4gPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgdmFyIHN0YWNrT3V0ID0gbnVsbDtcclxuICAgICAgICAgICAgICAgIHl3ID0geWkgPSAwO1xyXG4gICAgICAgICAgICAgICAgdmFyIG11bF9zdW0gPSBtdWxfdGFibGVbcmFkaXVzXTtcclxuICAgICAgICAgICAgICAgIHZhciBzaGdfc3VtID0gc2hnX3RhYmxlW3JhZGl1c107XHJcbiAgICAgICAgICAgICAgICBmb3IgKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHtcclxuICAgICAgICAgICAgICAgICAgICByX2luX3N1bSA9IGdfaW5fc3VtID0gYl9pbl9zdW0gPSBhX2luX3N1bSA9IHJfc3VtID0gZ19zdW0gPSBiX3N1bSA9IGFfc3VtID0gMDtcclxuICAgICAgICAgICAgICAgICAgICByX291dF9zdW0gPSByYWRpdXNQbHVzMSAqIChwciA9IHBpeGVsc1t5aV0pO1xyXG4gICAgICAgICAgICAgICAgICAgIGdfb3V0X3N1bSA9IHJhZGl1c1BsdXMxICogKHBnID0gcGl4ZWxzW3lpICsgMV0pO1xyXG4gICAgICAgICAgICAgICAgICAgIGJfb3V0X3N1bSA9IHJhZGl1c1BsdXMxICogKHBiID0gcGl4ZWxzW3lpICsgMl0pO1xyXG4gICAgICAgICAgICAgICAgICAgIGFfb3V0X3N1bSA9IHJhZGl1c1BsdXMxICogKHBhID0gcGl4ZWxzW3lpICsgM10pO1xyXG4gICAgICAgICAgICAgICAgICAgIHJfc3VtICs9IHN1bUZhY3RvciAqIHByO1xyXG4gICAgICAgICAgICAgICAgICAgIGdfc3VtICs9IHN1bUZhY3RvciAqIHBnO1xyXG4gICAgICAgICAgICAgICAgICAgIGJfc3VtICs9IHN1bUZhY3RvciAqIHBiO1xyXG4gICAgICAgICAgICAgICAgICAgIGFfc3VtICs9IHN1bUZhY3RvciAqIHBhO1xyXG4gICAgICAgICAgICAgICAgICAgIHN0YWNrID0gc3RhY2tTdGFydDtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgcmFkaXVzUGx1czE7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGFjay5yID0gcHI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YWNrLmcgPSBwZztcclxuICAgICAgICAgICAgICAgICAgICAgICAgc3RhY2suYiA9IHBiO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGFjay5hID0gcGE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YWNrID0gc3RhY2submV4dDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMTsgaSA8IHJhZGl1c1BsdXMxOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcCA9IHlpICsgKCh3aWR0aE1pbnVzMSA8IGkgPyB3aWR0aE1pbnVzMSA6IGkpIDw8IDIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByX3N1bSArPSAoc3RhY2suciA9IChwciA9IHBpeGVsc1twXSkpICogKHJicyA9IHJhZGl1c1BsdXMxIC0gaSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGdfc3VtICs9IChzdGFjay5nID0gKHBnID0gcGl4ZWxzW3AgKyAxXSkpICogcmJzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiX3N1bSArPSAoc3RhY2suYiA9IChwYiA9IHBpeGVsc1twICsgMl0pKSAqIHJicztcclxuICAgICAgICAgICAgICAgICAgICAgICAgYV9zdW0gKz0gKHN0YWNrLmEgPSAocGEgPSBwaXhlbHNbcCArIDNdKSkgKiByYnM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJfaW5fc3VtICs9IHByO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBnX2luX3N1bSArPSBwZztcclxuICAgICAgICAgICAgICAgICAgICAgICAgYl9pbl9zdW0gKz0gcGI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFfaW5fc3VtICs9IHBhO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGFjayA9IHN0YWNrLm5leHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHN0YWNrSW4gPSBzdGFja1N0YXJ0O1xyXG4gICAgICAgICAgICAgICAgICAgIHN0YWNrT3V0ID0gc3RhY2tFbmQ7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yICh4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGl4ZWxzW3lpICsgM10gPSBwYSA9IChhX3N1bSAqIG11bF9zdW0pID4+IHNoZ19zdW07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYSAhPSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYSA9IDI1NSAvIHBhO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGl4ZWxzW3lpXSA9ICgocl9zdW0gKiBtdWxfc3VtKSA+PiBzaGdfc3VtKSAqIHBhO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGl4ZWxzW3lpICsgMV0gPSAoKGdfc3VtICogbXVsX3N1bSkgPj4gc2hnX3N1bSkgKiBwYTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpeGVsc1t5aSArIDJdID0gKChiX3N1bSAqIG11bF9zdW0pID4+IHNoZ19zdW0pICogcGE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXhlbHNbeWldID0gcGl4ZWxzW3lpICsgMV0gPSBwaXhlbHNbeWkgKyAyXSA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgcl9zdW0gLT0gcl9vdXRfc3VtO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBnX3N1bSAtPSBnX291dF9zdW07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJfc3VtIC09IGJfb3V0X3N1bTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYV9zdW0gLT0gYV9vdXRfc3VtO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByX291dF9zdW0gLT0gc3RhY2tJbi5yO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBnX291dF9zdW0gLT0gc3RhY2tJbi5nO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiX291dF9zdW0gLT0gc3RhY2tJbi5iO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhX291dF9zdW0gLT0gc3RhY2tJbi5hO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwID0gKHl3ICsgKChwID0geCArIHJhZGl1cyArIDEpIDwgd2lkdGhNaW51czEgPyBwIDogd2lkdGhNaW51czEpKSA8PCAyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByX2luX3N1bSArPSAoc3RhY2tJbi5yID0gcGl4ZWxzW3BdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZ19pbl9zdW0gKz0gKHN0YWNrSW4uZyA9IHBpeGVsc1twICsgMV0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiX2luX3N1bSArPSAoc3RhY2tJbi5iID0gcGl4ZWxzW3AgKyAyXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFfaW5fc3VtICs9IChzdGFja0luLmEgPSBwaXhlbHNbcCArIDNdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcl9zdW0gKz0gcl9pbl9zdW07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGdfc3VtICs9IGdfaW5fc3VtO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiX3N1bSArPSBiX2luX3N1bTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYV9zdW0gKz0gYV9pbl9zdW07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgI
4244HN0YWNrSW4gPSBzdGFja0luLm5leHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJfb3V0X3N1bSArPSAocHIgPSBzdGFja091dC5yKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZ19vdXRfc3VtICs9IChwZyA9IHN0YWNrT3V0LmcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiX291dF9zdW0gKz0gKHBiID0gc3RhY2tPdXQuYik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFfb3V0X3N1bSArPSAocGEgPSBzdGFja091dC5hKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcl9pbl9zdW0gLT0gcHI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGdfaW5fc3VtIC09IHBnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiX2luX3N1bSAtPSBwYjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYV9pbl9zdW0gLT0gcGE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YWNrT3V0ID0gc3RhY2tPdXQubmV4dDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgeWkgKz0gNDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgeXcgKz0gd2lkdGg7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgd2lkdGg7IHgrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGdfaW5fc3VtID0gYl9pbl9zdW0gPSBhX2luX3N1bSA9IHJfaW5fc3VtID0gZ19zdW0gPSBiX3N1bSA9IGFfc3VtID0gcl9zdW0gPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHlpID0geCA8PCAyO1xyXG4gICAgICAgICAgICAgICAgICAgIHJfb3V0X3N1bSA9IHJhZGl1c1BsdXMxICogKHByID0gcGl4ZWxzW3lpXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgZ19vdXRfc3VtID0gcmFkaXVzUGx1czEgKiAocGcgPSBwaXhlbHNbeWkgKyAxXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgYl9vdXRfc3VtID0gcmFkaXVzUGx1czEgKiAocGIgPSBwaXhlbHNbeWkgKyAyXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgYV9vdXRfc3VtID0gcmFkaXVzUGx1czEgKiAocGEgPSBwaXhlbHNbeWkgKyAzXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcl9zdW0gKz0gc3VtRmFjdG9yICogcHI7XHJcbiAgICAgICAgICAgICAgICAgICAgZ19zdW0gKz0gc3VtRmFjdG9yICogcGc7XHJcbiAgICAgICAgICAgICAgICAgICAgYl9zdW0gKz0gc3VtRmFjdG9yICogcGI7XHJcbiAgICAgICAgICAgICAgICAgICAgYV9zdW0gKz0gc3VtRmFjdG9yICogcGE7XHJcbiAgICAgICAgICAgICAgICAgICAgc3RhY2sgPSBzdGFja1N0YXJ0O1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCByYWRpdXNQbHVzMTsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YWNrLnIgPSBwcjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc3RhY2suZyA9IHBnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGFjay5iID0gcGI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YWNrLmEgPSBwYTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc3RhY2sgPSBzdGFjay5uZXh0O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB5cCA9IHdpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDE7IGkgPD0gcmFkaXVzOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgeWkgPSAoeXAgKyB4KSA8PCAyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByX3N1bSArPSAoc3RhY2suciA9IChwciA9IHBpeGVsc1t5aV0pKSAqIChyYnMgPSByYWRpdXNQbHVzMSAtIGkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBnX3N1bSArPSAoc3RhY2suZyA9IChwZyA9IHBpeGVsc1t5aSArIDFdKSkgKiByYnM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJfc3VtICs9IChzdGFjay5iID0gKHBiID0gcGl4ZWxzW3lpICsgMl0pKSAqIHJicztcclxuICAgICAgICAgICAgICAgICAgICAgICAgYV9zdW0gKz0gKHN0YWNrLmEgPSAocGEgPSBwaXhlbHNbeWkgKyAzXSkpICogcmJzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByX2luX3N1bSArPSBwcjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZ19pbl9zdW0gKz0gcGc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJfaW5fc3VtICs9IHBiO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhX2luX3N1bSArPSBwYTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc3RhY2sgPSBzdGFjay5uZXh0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaSA8IGhlaWdodE1pbnVzMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeXAgKz0gd2lkdGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgeWkgPSB4O1xyXG4gICAgICAgICAgICAgICAgICAgIHN0YWNrSW4gPSBzdGFja1N0YXJ0O1xyXG4gICAgICAgICAgICAgICAgICAgIHN0YWNrT3V0ID0gc3RhY2tFbmQ7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yICh5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHAgPSB5aSA8PCAyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwaXhlbHNbcCArIDNdID0gcGEgPSAoYV9zdW0gKiBtdWxfc3VtKSA+PiBzaGdfc3VtO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocGEgPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYSA9IDI1NSAvIHBhO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGl4ZWxzW3BdID0gKChyX3N1bSAqIG11bF9zdW0pID4+IHNoZ19zdW0pICogcGE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXhlbHNbcCArIDFdID0gKChnX3N1bSAqIG11bF9zdW0pID4+IHNoZ19zdW0pICogcGE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXhlbHNbcCArIDJdID0gKChiX3N1bSAqIG11bF9zdW0pID4+IHNoZ19zdW0pICogcGE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgI
4244H1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXhlbHNbcF0gPSBwaXhlbHNbcCArIDFdID0gcGl4ZWxzW3AgKyAyXSA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgcl9zdW0gLT0gcl9vdXRfc3VtO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBnX3N1bSAtPSBnX291dF9zdW07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJfc3VtIC09IGJfb3V0X3N1bTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYV9zdW0gLT0gYV9vdXRfc3VtO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByX291dF9zdW0gLT0gc3RhY2tJbi5yO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBnX291dF9zdW0gLT0gc3RhY2tJbi5nO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiX291dF9zdW0gLT0gc3RhY2tJbi5iO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhX291dF9zdW0gLT0gc3RhY2tJbi5hO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwID0gKHggKyAoKChwID0geSArIHJhZGl1c1BsdXMxKSA8IGhlaWdodE1pbnVzMSA/IHAgOiBoZWlnaHRNaW51czEpICogd2lkdGgpKSA8PCAyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByX3N1bSArPSAocl9pbl9zdW0gKz0gKHN0YWNrSW4uciA9IHBpeGVsc1twXSkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBnX3N1bSArPSAoZ19pbl9zdW0gKz0gKHN0YWNrSW4uZyA9IHBpeGVsc1twICsgMV0pKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYl9zdW0gKz0gKGJfaW5fc3VtICs9IChzdGFja0luLmIgPSBwaXhlbHNbcCArIDJdKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFfc3VtICs9IChhX2luX3N1bSArPSAoc3RhY2tJbi5hID0gcGl4ZWxzW3AgKyAzXSkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGFja0luID0gc3RhY2tJbi5uZXh0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByX291dF9zdW0gKz0gKHByID0gc3RhY2tPdXQucik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGdfb3V0X3N1bSArPSAocGcgPSBzdGFja091dC5nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYl9vdXRfc3VtICs9IChwYiA9IHN0YWNrT3V0LmIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhX291dF9zdW0gKz0gKHBhID0gc3RhY2tPdXQuYSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJfaW5fc3VtIC09IHByO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBnX2luX3N1bSAtPSBwZztcclxuICAgICAgICAgICAgICAgICAgICAgICAgYl9pbl9zdW0gLT0gcGI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFfaW5fc3VtIC09IHBhO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGFja091dCA9IHN0YWNrT3V0Lm5leHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHlpICs9IHdpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybiBpbWFnZURhdGE7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIHJldHVybiBCbHVyO1xyXG4gICAgICAgIH0pKGpzZnguRmlsdGVyKTtcclxuICAgICAgICBmaWx0ZXIuQmx1ciA9IEJsdXI7XHJcbiAgICAgICAgdmFyIG11bF90YWJsZSA9IFtcclxuICAgICAgICAgICAgNTEyLCA1MTIsIDQ1NiwgNTEyLCAzMjgsIDQ1NiwgMzM1LCA1MTIsIDQwNSwgMzI4LCAyNzEsIDQ1NiwgMzg4LCAzMzUsIDI5MiwgNTEyLFxyXG4gICAgICAgICAgICA0NTQsIDQwNSwgMzY0LCAzMjgsIDI5OCwgMjcxLCA0OTYsIDQ1NiwgNDIwLCAzODgsIDM2MCwgMzM1LCAzMTIsIDI5MiwgMjczLCA1MTIsXHJcbiAgICAgICAgICAgIDQ4MiwgNDU0LCA0MjgsIDQwNSwgMzgzLCAzNjQsIDM0NSwgMzI4LCAzMTIsIDI5OCwgMjg0LCAyNzEsIDI1OSwgNDk2LCA0NzUsIDQ1NixcclxuICAgICAgICAgICAgNDM3LCA0MjAsIDQwNCwgMzg4LCAzNzQsIDM2MCwgMzQ3LCAzMzUsIDMyMywgMzEyLCAzMDIsIDI5MiwgMjgyLCAyNzMsIDI2NSwgNTEyLFxyXG4gICAgICAgICAgICA0OTcsIDQ4MiwgNDY4LCA0NTQsIDQ0MSwgNDI4LCA0MTcsIDQwNSwgMzk0LCAzODMsIDM3MywgMzY0LCAzNTQsIDM0NSwgMzM3LCAzMjgsXHJcbiAgICAgICAgICAgIDMyMCwgMzEyLCAzMDUsIDI5OCwgMjkxLCAyODQsIDI3OCwgMjcxLCAyNjUsIDI1OSwgNTA3LCA0OTYsIDQ4NSwgNDc1LCA0NjUsIDQ1NixcclxuICAgICAgICAgICAgNDQ2LCA0MzcsIDQyOCwgNDIwLCA0MTIsIDQwNCwgMzk2LCAzODgsIDM4MSwgMzc0LCAzNjcsIDM2MCwgMzU0LCAzNDcsIDM0MSwgMzM1LFxyXG4gICAgICAgICAgICAzMjksIDMyMywgMzE4LCAzMTIsIDMwNywgMzAyLCAyOTcsIDI5MiwgMjg3LCAyODIsIDI3OCwgMjczLCAyNjksIDI2NSwgMjYxLCA1MTIsXHJcbiAgICAgICAgICAgIDUwNSwgNDk3LCA0ODksIDQ4MiwgNDc1LCA0NjgsIDQ2MSwgNDU0LCA0NDcsIDQ0MSwgNDM1LCA0MjgsIDQyMiwgNDE3LCA0MTEsIDQwNSxcclxuICAgICAgICAgICAgMzk5LCAzOTQsIDM4OSwgMzgzLCAzNzgsIDM3MywgMzY4LCAzNjQsIDM1OSwgMzU0LCAzNTAsIDM0NSwgMzQxLCAzMzcsIDMzMiwgMzI4LFxyXG4gICAgICAgICAgICAzMjQsIDMyMCwgMzE2LCAzMTIsIDMwOSwgMzA1LCAzMDEsIDI5OCwgMjk0LCAyOTEsIDI4NywgMjg0LCAyODEsIDI3OCwgMjc0LCAyNzEsXHJcbiAgICAgICAgICAgIDI2OCwgMjY1LCAyNjIsIDI1OSwgMjU3LCA1MDcsIDUwMSwgNDk2LCA0OTEsIDQ4NSwgNDgwLCA0NzUsIDQ3MCwgNDY1LCA0NjAsIDQ1NixcclxuICAgICAgICAgICAgNDUxLCA0NDYsIDQ0MiwgNDM3LCA0MzMsIDQyOCwgNDI0LCA0MjAsIDQxNiwgNDEyLCA0MDgsIDQwNCwgNDAwLCAzOTYsIDM5MiwgMzg4LFxyXG4gICAgICAgICAgICAzODUsIDM4MSwgMzc3LCAzNzQsIDM3MCwgMzY3LCAzNjMsIDM2MCwgMzU3LCAzNTQsIDM1MCwgMzQ3LCAzNDQsIDM0MSwgMzM4LCAzMzUsXHJcbiAgICAgICAgICAgIDMzMiwgMzI5LCAzMjYsIDMyMywgMzIwLCAzMTgsIDMxNSwgMzEyLCAzMTAsIDMwNywgMzA0LCAzMDIsIDI5OSwgMjk3LCAyOTQsIDI5MixcclxuICAgICAgICAgICAgMjg5LCAyODcsIDI4NSwgMjgyLCAyODAsIDI3OCwgMjc1LCAyNzMsIDI3MSwgMjY5LCAyNjcsIDI2NSwgMjYzLCAyNjEsIDI1OV07XHJcbiAgICAgICAgdmFyIHNoZ190YWJsZSA9IFtcclxuICAgICAgICAgICAgOSwgMTEsIDEyLCAxMywgMTMsIDE0LCAxNCwgMTUsIDE1LCAxNSwgMTUsIDE2LCAxNiwgMTYsIDE2LCAxNyxcclxuICAgICAgICAgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTgsIDE4LCAxOCwgMTgsIDE4LCAxOCwgMTgsIDE4LCAxOCwgMTksXHJcbiAgICAgICAgICAgIDE5LCAxOSwgMTksIDE5LCAxOSwgMTksIDE5LCAxOSwgMTksIDE5LCAxOSwgMTksIDE5LCAyMCwgMjAsIDIwLFxyXG4gICAgICAgICAgICAyMCwgMjAsIDIwLCAyMCwgMjAsIDIwLCAyMCwgMjAsIDIwLCAyMCwgMjAsIDIwLCAyMCwgMjAsIDIwLCAyMSxcclxuICAgICAgICAgICAgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsXHJcbiAgICAgICAgICAgIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMiwgMjIsIDIyLCAyMiwgMjIsIDIyLFxyXG4gICAgICAgICAgICAyMiwgMjIsIDIyLCAyMiwgMjIsIDIyLCAyMiwgMjIsIDIyLCAyMiwgMjIsIDIyLCAyMiwgMjIsIDIyLCAyMixcclxuICAgICAgICAgICAgMjIsIDIyLCAyMiwgMjIsIDIyLCAyMiwgMjIsIDIyLCAyMiwgMjIsIDIyLCAyMiwgMjIsIDIyLCAyMiwgMjMsXHJcbiAgICAgICAgICAgIDIzLCAyMywgMjMsIDIzLCAyMywgMjMsIDIzLCAyMywgMjMsIDIzLCAyMywgMjMsIDIzLCAyMywgMjMsIDIzLFxyXG4gICAgICAgICAgICAyMywgMjMsIDIzLCAyMywgMjMsIDIzLCAyMywgMjMsIDIzLCAyMywgMjMsIDIzLCAyMywgMjMsIDIzLCAyMyxcclxuICAgICAgICAgICAgMjMsIDIzLCAyMywgMjMsIDIzLCAyMywgMjMsIDIzLCAyMywgMjMsIDIzLCAyMywgMjMsIDIzLCAyMywgMjMsXHJcbiAgICAgICAgICAgIDIzLCAyMywgMjMsIDIzLCAyMywgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LFxyXG4gICAgICAgICAgICAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCxcclxuICAgICAgICAgICAgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsXHJcbiAgICAgICAgICAgIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LFxyXG4gICAgICAgICAgICAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0LCAyNCwgMjQsIDI0XTtcclxuICAgICAgICB2Y
4244XIgQmx1clN0YWNrID0gKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgZnVuY3Rpb24gQmx1clN0YWNrKCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5yID0gMDtcclxuICAgICAgICAgICAgICAgIHRoaXMuZyA9IDA7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmIgPSAwO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5hID0gMDtcclxuICAgICAgICAgICAgICAgIHRoaXMubmV4dCA9IG51bGw7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIEJsdXJTdGFjaztcclxuICAgICAgICB9KSgpO1xyXG4gICAgfSkoZmlsdGVyID0ganNmeC5maWx0ZXIgfHwgKGpzZnguZmlsdGVyID0ge30pKTtcclxufSkoanNmeCB8fCAoanNmeCA9IHt9KSk7XHJcbnZhciBqc2Z4O1xyXG4oZnVuY3Rpb24gKGpzZngpIHtcclxuICAgIHZhciBmaWx0ZXI7XHJcbiAgICAoZnVuY3Rpb24gKGZpbHRlcikge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBmaWx0ZXIgICAgICAgICAgIEJyaWdodG5lc3NcclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gICAgICBQcm92aWRlcyBhZGRpdGl2ZSBicmlnaHRuZXNzIGNvbnRyb2wuXHJcbiAgICAgICAgICogQHBhcmFtIGJyaWdodG5lc3MgLTEgdG8gMSAoLTEgaXMgc29saWQgYmxhY2ssIDAgaXMgbm8gY2hhbmdlLCBhbmQgMSBpcyBzb2xpZCB3aGl0ZSlcclxuICAgICAgICAgKi9cclxuICAgICAgICB2YXIgQnJpZ2h0bmVzcyA9IChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcbiAgICAgICAgICAgIF9fZXh0ZW5kcyhCcmlnaHRuZXNzLCBfc3VwZXIpO1xyXG4gICAgICAgICAgICBmdW5jdGlvbiBCcmlnaHRuZXNzKGJyaWdodG5lc3MpIHtcclxuICAgICAgICAgICAgICAgIF9zdXBlci5jYWxsKHRoaXMsIG51bGwsIFwiXFxuICAgICAgICAgICAgdW5pZm9ybSBzYW1wbGVyMkQgdGV4dHVyZTtcXG4gICAgICAgICAgICB1bmlmb3JtIGZsb2F0IGJyaWdodG5lc3M7XFxuICAgICAgICAgICAgdmFyeWluZyB2ZWMyIHRleENvb3JkO1xcblxcbiAgICAgICAgICAgIHZvaWQgbWFpbigpIHtcXG4gICAgICAgICAgICAgICAgdmVjNCBjb2xvciA9IHRleHR1cmUyRCh0ZXh0dXJlLCB0ZXhDb29yZCk7XFxuICAgICAgICAgICAgICAgIGNvbG9yLnJnYiArPSBicmlnaHRuZXNzO1xcblxcbiAgICAgICAgICAgICAgICBnbF9GcmFnQ29sb3IgPSBjb2xvcjtcXG4gICAgICAgICAgICB9XFxuICAgICAgICBcIik7XHJcbiAgICAgICAgICAgICAgICAvLyBzZXQgcHJvcGVydGllc1xyXG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wZXJ0aWVzLmJyaWdodG5lc3MgPSBqc2Z4LkZpbHRlci5jbGFtcCgtMSwgYnJpZ2h0bmVzcywgMSkgfHwgMDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBCcmlnaHRuZXNzLnByb3RvdHlwZS5pdGVyYXRlQ2FudmFzID0gZnVuY3Rpb24gKGhlbHBlcikge1xyXG4gICAgICAgICAgICAgICAgdmFyIGJyaWdodG5lc3MgPSB0aGlzLnByb3BlcnRpZXMuYnJpZ2h0bmVzcztcclxuICAgICAgICAgICAgICAgIGhlbHBlci5yICs9IGJyaWdodG5lc3M7XHJcbiAgICAgICAgICAgICAgICBoZWxwZXIuZyArPSBicmlnaHRuZXNzO1xyXG4gICAgICAgICAgICAgICAgaGVscGVyLmIgKz0gYnJpZ2h0bmVzcztcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgcmV0dXJuIEJyaWdodG5lc3M7XHJcbiAgICAgICAgfSkoanNmeC5JdGVyYWJsZUZpbHRlcik7XHJcbiAgICAgICAgZmlsdGVyLkJyaWdodG5lc3MgPSBCcmlnaHRuZXNzO1xyXG4gICAgfSkoZmlsdGVyID0ganNmeC5maWx0ZXIgfHwgKGpzZnguZmlsdGVyID0ge30pKTtcclxufSkoanNmeCB8fCAoanNmeCA9IHt9KSk7XHJcbnZhciBqc2Z4O1xyXG4oZnVuY3Rpb24gKGpzZngpIHtcclxuICAgIHZhciBmaWx0ZXI7XHJcbiAgICAoZnVuY3Rpb24gKGZpbHRlcikge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBmaWx0ZXIgICAgICAgICAgIENvbnRyYXN0XHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uICAgICAgUHJvdmlkZXMgbXVsdGlwbGljYXRpdmUgY29udHJhc3QgY29udHJvbC5cclxuICAgICAgICAgKiBAcGFyYW0gY29udHJhc3QgICAtMSB0byAxICgtMSBpcyBzb2xpZCBncmF5LCAwIGlzIG5vIGNoYW5nZSwgYW5kIDEgaXMgbWF4aW11bSBjb250cmFzdClcclxuICAgICAgICAgKi9cclxuICAgICAgICB2Y
4244XIgQ29udHJhc3QgPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgICAgICAgICBfX2V4dGVuZHMoQ29udHJhc3QsIF9zdXBlcik7XHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIENvbnRyYXN0KGNvbnRyYXN0KSB7XHJcbiAgICAgICAgICAgICAgICBfc3VwZXIuY2FsbCh0aGlzLCBudWxsLCBcIlxcbiAgICAgICAgICAgIHVuaWZvcm0gc2FtcGxlcjJEIHRleHR1cmU7XFxuICAgICAgICAgICAgdW5pZm9ybSBmbG9hdCBjb250cmFzdDtcXG4gICAgICAgICAgICB2YXJ5aW5nIHZlYzIgdGV4Q29vcmQ7XFxuXFxuICAgICAgICAgICAgdm9pZCBtYWluKCkge1xcbiAgICAgICAgICAgICAgICB2ZWM0IGNvbG9yID0gdGV4dHVyZTJEKHRleHR1cmUsIHRleENvb3JkKTtcXG5cXG4gICAgICAgICAgICAgICAgaWYgKGNvbnRyYXN0ID4gMC4wKSB7XFxuICAgICAgICAgICAgICAgICAgICBjb2xvci5yZ2IgPSAoY29sb3IucmdiIC0gMC41KSAvICgxLjAgLSBjb250cmFzdCkgKyAwLjU7XFxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XFxuICAgICAgICAgICAgICAgICAgICBjb2xvci5yZ2IgPSAoY29sb3IucmdiIC0gMC41KSAqICgxLjAgKyBjb250cmFzdCkgKyAwLjU7XFxuICAgICAgICAgICAgICAgIH1cXG5cXG4gICAgICAgICAgICAgICAgZ2xfRnJhZ0NvbG9yID0gY29sb3I7XFxuICAgICAgICAgICAgfVxcbiAgICAgICAgXCIpO1xyXG4gICAgICAgICAgICAgICAgLy8gc2V0IHByb3BlcnRpZXNcclxuICAgICAgICAgICAgICAgIHRoaXMucHJvcGVydGllcy5jb250cmFzdCA9IGpzZnguRmlsdGVyLmNsYW1wKC0xLCBjb250cmFzdCwgMSkgfHwgMDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBDb250cmFzdC5wcm90b3R5cGUuaXRlcmF0ZUNhbnZhcyA9IGZ1bmN0aW9uIChoZWxwZXIpIHtcclxuICAgICAgICAgICAgICAgIHZhciBjb250cmFzdCA9IHRoaXMucHJvcGVydGllcy5jb250cmFzdDtcclxuICAgICAgICAgICAgICAgIGlmIChjb250cmFzdCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBoZWxwZXIuciA9IChoZWxwZXIuciAtIDAuNSkgLyAoMSAtIGNvbnRyYXN0KSArIDAuNTtcclxuICAgICAgICAgICAgICAgICAgICBoZWxwZXIuZyA9IChoZWxwZXIuZyAtIDAuNSkgLyAoMSAtIGNvbnRyYXN0KSArIDAuNTtcclxuICAgICAgICAgICAgICAgICAgICBoZWxwZXIuYiA9IChoZWxwZXIuYiAtIDAuNSkgLyAoMSAtIGNvbnRyYXN0KSArIDAuNTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGhlbHBlci5yID0gKGhlbHBlci5yIC0gMC41KSAqICgxICsgY29udHJhc3QpICsgMC41O1xyXG4gICAgICAgICAgICAgICAgICAgIGhlbHBlci5nID0gKGhlbHBlci5nIC0gMC41KSAqICgxICsgY29udHJhc3QpICsgMC41O1xyXG4gICAgICAgICAgICAgICAgICAgIGhlbHBlci5iID0gKGhlbHBlci5iIC0gMC41KSAqICgxICsgY29udHJhc3QpICsgMC41O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICByZXR1cm4gQ29udHJhc3Q7XHJcbiAgICAgICAgfSkoanNmeC5JdGVyYWJsZUZpbHRlcik7XHJcbiAgICAgICAgZmlsdGVyLkNvbnRyYXN0ID0gQ29udHJhc3Q7XHJcbiAgICB9KShmaWx0ZXIgPSBqc2Z4LmZpbHRlciB8fCAoanNmeC5maWx0ZXIgPSB7fSkpO1xyXG59KShqc2Z4IHx8IChqc2Z4ID0ge30pKTtcclxudmFyIGpzZng7XHJcbihmdW5jdGlvbiAoanNmeCkge1xyXG4gICAgdmFyIGZpbHRlcjtcclxuICAgIChmdW5jdGlvbiAoZmlsdGVyKSB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGZpbHRlciAgICAgIEN1cnZlc1xyXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiBBIHBvd2VyZnVsIG1hcHBpbmcgdG9vbCB0aGF0IHRyYW5zZm9ybXMgdGhlIGNvbG9ycyBpbiB0aGUgaW1hZ2VcclxuICAgICAgICAgKiAgICAgICAgICAgICAgYnkgYW4gYXJiaXRyYXJ5IGZ1bmN0aW9uLiBUaGUgZnVuY3Rpb24gaXMgaW50ZXJwb2xhdGVkIGJldHdlZW5cclxuICAgICAgICAgKiAgICAgICAgICAgICAgYSBzZXQgb2YgMkQgcG9pbnRzIHVzaW5nIHNwbGluZXMuIFRoZSBjdXJ2ZXMgZmlsdGVyIGNhbiB0YWtlXHJcbiAgICAgICAgICogICAgICAgICAgICAgIGVpdGhlciBvbmUgb3IgdGhyZWUgYXJndW1lbnRzIHdoaWNoIHdpbGwgYXBwbHkgdGhlIG1hcHBpbmcgdG9cclxuICAgICAgICAgKiAgICAgICAgICAgICAgZWl0aGVyIGx1bWluYW5jZSBvciBSR0IgdmFsdWVzLCByZXNwZWN0aXZlbHkuXHJcbiAgICAgICAgICogQHBhcmFtIHJlZCAgIEEgbGlzdCBvZiBwb2ludHMgdGhhdCBkZWZpbmUgdGhlIGZ1bmN0aW9uIGZvciB0aGUgcmVkIGNoYW5uZWwuXHJcbiAgICAgICAgICogICAgICAgICAgICAgIEVhY2ggcG9pbnQgaXMgYSBsaXN0IG9mIHR3byB2YWx1ZXM6IHRoZSB2YWx1ZSBiZWZvcmUgdGhlIG1hcHBpbmdcclxuICAgICAgICAgKiAgICAgICAgICAgICAgYW5kIHRoZSB2YWx1ZSBhZnRlciB0aGUgbWFwcGluZywgYm90aCBpbiB0aGUgcmFuZ2UgMCB0byAxLiBGb3JcclxuICAgICAgICAgKiAgICAgICAgICAgICAgZXhhbXBsZSwgW1swLDFdLCBbMSwwXV0gd291bGQgaW52ZXJ0IHRoZSByZWQgY2hhbm5lbCB3aGlsZVxyXG4gICAgICAgICAqICAgICAgICAgICAgICBbWzAsMF0sIFsxLDFdXSB3b3VsZCBsZWF2ZSB0aGUgcmVkIGNoYW5uZWwgdW5jaGFuZ2VkLiBJZiBncmVlblxyXG4gICAgICAgICAqICAgICAgICAgICAgICBhbmQgYmx1ZSBhcmUgb21pdHRlZCB0aGVuIHRoaXMgYXJndW1lbnQgYWxzbyBhcHBsaWVzIHRvIHRoZVxyXG4gICAgICAgICAqICAgICAgICAgICAgICBncmVlbiBhbmQgYmx1ZSBjaGFubmVscy5cclxuICAgICAgICAgKiBAcGFyYW0gZ3JlZW4gKG9wdGlvbmFsKSBBIGxpc3Qgb2YgcG9pbnRzIHRoYXQgZGVmaW5lIHRoZSBmdW5jdGlvbiBmb3IgdGhlIGdyZWVuXHJcbiAgICAgICAgICogICAgICAgICAgICAgIGNoYW5uZWwgKGp1c3QgbGlrZSBmb3IgcmVkKS5cclxuICAgICAgICAgKiBAcGFyYW0gYmx1ZSAgKG9wdGlvbmFsKSBBIGxpc3Qgb2YgcG9pbnRzIHRoYXQgZGVmaW5lIHRoZSBmdW5jdGlvbiBmb3IgdGhlIGJsdWVcclxuICAgICAgICAgKiAgICAgICAgICAgICAgY2hhbm5lbCAoanVzdCBsaWtlIGZvciByZWQpLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgI
4244HZhciBDdXJ2ZXMgPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgICAgICAgICBfX2V4dGVuZHMoQ3VydmVzLCBfc3VwZXIpO1xyXG4gICAgICAgICAgICBmdW5jdGlvbiBDdXJ2ZXMocmVkLCBncmVlbiwgYmx1ZSkge1xyXG4gICAgICAgICAgICAgICAgX3N1cGVyLmNhbGwodGhpcywgbnVsbCwgXCJcXG4gICAgICAgICAgICB1bmlmb3JtIHNhbXBsZXIyRCB0ZXh0dXJlO1xcbiAgICAgICAgICAgIHVuaWZvcm0gc2FtcGxlcjJEIG1hcDtcXG4gICAgICAgICAgICB2YXJ5aW5nIHZlYzIgdGV4Q29vcmQ7XFxuXFxuICAgICAgICAgICAgdm9pZCBtYWluKCkge1xcbiAgICAgICAgICAgICAgICB2ZWM0IGNvbG9yID0gdGV4dHVyZTJEKHRleHR1cmUsIHRleENvb3JkKTtcXG4gICAgICAgICAgICAgICAgY29sb3IuciA9IHRleHR1cmUyRChtYXAsIHZlYzIoY29sb3IucikpLnI7XFxuICAgICAgICAgICAgICAgIGNvbG9yLmcgPSB0ZXh0dXJlMkQobWFwLCB2ZWMyKGNvbG9yLmcpKS5nO1xcbiAgICAgICAgICAgICAgICBjb2xvci5iID0gdGV4dHVyZTJEKG1hcCwgdmVjMihjb2xvci5iKSkuYjtcXG4gICAgICAgICAgICAgICAgZ2xfRnJhZ0NvbG9yID0gY29sb3I7XFxuICAgICAgICAgICAgfVxcbiAgICAgICAgXCIpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5yZWQgPSByZWQ7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmdyZWVuID0gZ3JlZW47XHJcbiAgICAgICAgICAgICAgICB0aGlzLmJsdWUgPSBibHVlO1xyXG4gICAgICAgICAgICAgICAgLy8gaW50ZXJwb2xhdGVcclxuICAgICAgICAgICAgICAgIHJlZCA9IEN1cnZlcy5zcGxpbmVJbnRlcnBvbGF0ZShyZWQpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT0gMSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGdyZWVuID0gYmx1ZSA9IHJlZDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGdyZWVuID0gQ3VydmVzLnNwbGluZUludGVycG9sYXRlKGdyZWVuKTtcclxuICAgICAgICAgICAgICAgICAgICBibHVlID0gQ3VydmVzLnNwbGluZUludGVycG9sYXRlKGJsdWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGhpcy5yZWQgPSByZWQ7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmdyZWVuID0gZ3JlZW47XHJcbiAgICAgICAgICAgICAgICB0aGlzLmJsdWUgPSBibHVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIEN1cnZlcy5wcm90b3R5cGUuZHJhd0NhbnZhcyA9IGZ1bmN0aW9uIChpbWFnZURhdGEpIHtcclxuICAgICAgICAgICAgICAgIHZhciBwaXhlbHMgPSBpbWFnZURhdGEuZGF0YTtcclxuICAgICAgICAgICAgICAgIHZhciBhbW91bnQgPSB0aGlzLnByb3BlcnRpZXMuYW1vdW50O1xyXG4gICAgICAgICAgICAgICAgdmFyIHIsIGcsIGI7XHJcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHBpeGVscy5sZW5ndGg7IGkgKz0gNCkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGdldCBjb2xvciB2YWx1ZXNcclxuICAgICAgICAgICAgICAgICAgICByID0gcGl4ZWxzW2ldIC8gMjU1O1xyXG4gICAgICAgICAgICAgICAgICAgIGcgPSBwaXhlbHNbaSArIDFdIC8gMjU1O1xyXG4gICAgICAgICAgICAgICAgICAgIGIgPSBwaXhlbHNbaSArIDJdIC8gMjU1O1xyXG4gICAgICAgICAgICAgICAgICAgIHIgPSBNYXRoLm1pbigxLjAsIChyICogKDEgLSAoMC42MDcgKiBhbW91bnQpKSkgKyAoZyAqICgwLjc2OSAqIGFtb3VudCkpICsgKGIgKiAoMC4xODkgKiBhbW91bnQpKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgZyA9IE1hdGgubWluKDEuMCwgKHIgKiAwLjM0OSAqIGFtb3VudCkgKyAoZyAqICgxIC0gKDAuMzE0ICogYW1vdW50KSkpICsgKGIgKiAwLjE2OCAqIGFtb3VudCkpO1xyXG4gICAgICAgICAgICAgICAgICAgIGIgPSBNYXRoLm1pbigxLjAsIChyICogMC4yNzIgKiBhbW91bnQpICsgKGcgKiAwLjUzNCAqIGFtb3VudCkgKyAoYiAqICgxIC0gKDAuODY5ICogYW1vdW50KSkpKTtcclxuICAgICAgICAgICAgICAgICAgICAvLyBzZXQgdmFsdWVzXHJcbiAgICAgICAgICAgICAgICAgICAgcGl4ZWxzW2ldID0gciAqIDI1NTtcclxuICAgICAgICAgICAgICAgICAgICBwaXhlbHNbaSArIDFdID0gZyAqIDI1NTtcclxuICAgICAgICAgICAgICAgICAgICBwaXhlbHNbaSArIDJdID0gYiAqIDI1NTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybiBpbWFnZURhdGE7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIEN1cnZlcy5zcGxpbmVJbnRlcnBvbGF0ZSA9IGZ1bmN0aW9uIChwb2ludHMpIHtcclxuICAgICAgICAgICAgICAgIHZhciBpbnRlcnBvbGF0b3IgPSBuZXcganNmeC51dGlsLlNwbGluZUludGVycG9sYXRvcihwb2ludHMpO1xyXG4gICAgICAgICAgICAgICAgdmFyIGFycmF5ID0gW107XHJcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDI1NjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYXJyYXkucHVzaChqc2Z4LkZpbHRlci5jbGFtcCgwLCBNYXRoLmZsb29yKGludGVycG9sYXRvci5pbnRlcnBvbGF0ZShpIC8gMjU1KSAqIDI1NiksIDI1NSkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5O1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICByZXR1cm4gQ3VydmVzO1xyXG4gICAgICAgIH0pKGpzZnguRmlsdGVyKTtcclxuICAgICAgICBmaWx0ZXIuQ3VydmVzID0gQ3VydmVzO1xyXG4gICAgfSkoZmlsdGVyID0ganNmeC5maWx0ZXIgfHwgKGpzZnguZmlsdGVyID0ge30pKTtcclxufSkoanNmeCB8fCAoanNmeCA9IHt9KSk7XHJcbnZhciBqc2Z4O1xyXG4oZnVuY3Rpb24gKGpzZngpIHtcclxuICAgIHZhciBmaWx0ZXI7XHJcbiAgICAoZnVuY3Rpb24gKGZpbHRlcikge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBmaWx0ZXIgICAgICAgICAgIEh1ZSAvIFNhdHVyYXRpb25cclxuICAgICAgICAgKiBAZGVzY3JpcHRpb24gICAgICBQcm92aWRlcyByb3RhdGlvbmFsIGh1ZSBjb250cm9sLiBSR0IgY29sb3Igc3BhY2VcclxuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICBjYW4gYmUgaW1hZ2luZWQgYXMgYSBjdWJlIHdoZXJlIHRoZSBheGVzIGFyZSB0aGUgcmVkLCBncmVlbiwgYW5kIGJsdWUgY29sb3JcclxuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICB2YWx1ZXMuIEh1ZSBjaGFuZ2luZyB3b3JrcyBieSByb3RhdGluZyB0aGUgY29sb3IgdmVjdG9yIGFyb3VuZCB0aGUgZ3JheXNjYWxlXHJcbiAgICAgICAgICogICAgICAgICAgICAgICAgICAgbGluZSwgd2hpY2ggaXMgdGhlIHN0cmFpZ2h0IGxpbmUgZnJvbSBibGFjayAoMCwgMCwgMCkgdG8gd2hpdGUgKDEsIDEsIDEpLlxyXG4gICAgICAgICAqIEBwYXJhbSBodWUgICAgICAgIC0xIHRvIDEgKC0xIGlzIDE4MCBkZWdyZWUgcm90YXRpb24gaW4gdGhlIG5lZ2F0aXZlIGRpcmVjdGlvbiwgMCBpcyBubyBjaGFuZ2UsXHJcbiAgICAgICAgICogICAgICAgICAgICAgICAgICAgYW5kIDEgaXMgMTgwIGRlZ3JlZSByb3RhdGlvbiBpbiB0aGUgcG9zaXRpdmUgZGlyZWN0aW9uKVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgI
4244HZhciBIdWUgPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgICAgICAgICBfX2V4dGVuZHMoSHVlLCBfc3VwZXIpO1xyXG4gICAgICAgICAgICBmdW5jdGlvbiBIdWUoaHVlKSB7XHJcbiAgICAgICAgICAgICAgICBfc3VwZXIuY2FsbCh0aGlzLCBudWxsLCBcIlxcbiAgICAgICAgICAgIHVuaWZvcm0gc2FtcGxlcjJEIHRleHR1cmU7XFxuICAgICAgICAgICAgdW5pZm9ybSBmbG9hdCBodWU7XFxuICAgICAgICAgICAgdmFyeWluZyB2ZWMyIHRleENvb3JkO1xcblxcbiAgICAgICAgICAgIHZvaWQgbWFpbigpIHtcXG4gICAgICAgICAgICAgICAgdmVjNCBjb2xvciA9IHRleHR1cmUyRCh0ZXh0dXJlLCB0ZXhDb29yZCk7XFxuXFxuICAgICAgICAgICAgICAgIC8qIGh1ZSBhZGp1c3RtZW50LCB3b2xmcmFtIGFscGhhOiBSb3RhdGlvblRyYW5zZm9ybVthbmdsZSwgezEsIDEsIDF9XVt7eCwgeSwgen1dICovXFxuICAgICAgICAgICAgICAgIGZsb2F0IGFuZ2xlID0gaHVlICogMy4xNDE1OTI2NTtcXG4gICAgICAgICAgICAgICAgZmxvYXQgcyA9IHNpbihhbmdsZSksIGMgPSBjb3MoYW5nbGUpO1xcbiAgICAgICAgICAgICAgICB2ZWMzIHdlaWdodHMgPSAodmVjMygyLjAgKiBjLCAtc3FydCgzLjApICogcyAtIGMsIHNxcnQoMy4wKSAqIHMgLSBjKSArIDEuMCkgLyAzLjA7XFxuICAgICAgICAgICAgICAgIGNvbG9yLnJnYiA9IHZlYzMoXFxuICAgICAgICAgICAgICAgICAgICBkb3QoY29sb3IucmdiLCB3ZWlnaHRzLnh5eiksXFxuICAgICAgICAgICAgICAgICAgICBkb3QoY29sb3IucmdiLCB3ZWlnaHRzLnp4eSksXFxuICAgICAgICAgICAgICAgICAgICBkb3QoY29sb3IucmdiLCB3ZWlnaHRzLnl6eClcXG4gICAgICAgICAgICAgICAgKTtcXG5cXG4gICAgICAgICAgICAgICAgZ2xfRnJhZ0NvbG9yID0gY29sb3I7XFxuICAgICAgICAgICAgfVxcbiAgICAgICAgXCIpO1xyXG4gICAgICAgICAgICAgICAgLy8gc2V0IHByb3BlcnRpZXNcclxuICAgICAgICAgICAgICAgIHRoaXMucHJvcGVydGllcy5odWUgPSBqc2Z4LkZpbHRlci5jbGFtcCgtMSwgaHVlLCAxKSB8fCAwO1xyXG4gICAgICAgICAgICAgICAgLy8gcHJlLWNhbGN1bGF0ZSBkYXRhIGZvciBjYW52YXMgaXRlcmF0aW9uXHJcbiAgICAgICAgICAgICAgICB2Y
4244XIgYW5nbGUgPSBodWUgKiAzLjE0MTU5MjY1O1xyXG4gICAgICAgICAgICAgICAgdmFyIHNpbiA9IE1hdGguc2luKGFuZ2xlKTtcclxuICAgICAgICAgICAgICAgIHZhciBjb3MgPSBNYXRoLmNvcyhhbmdsZSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLndlaWdodHMgPSBuZXcganNmeC51dGlsLlZlY3RvcjMoMiAqIGNvcywgLU1hdGguc3FydCgzLjApICogc2luIC0gY29zLCBNYXRoLnNxcnQoMy4wKSAqIHNpbiAtIGNvcylcclxuICAgICAgICAgICAgICAgICAgICAuYWRkU2NhbGFyKDEuMClcclxuICAgICAgICAgICAgICAgICAgICAuZGl2aWRlU2NhbGFyKDMuMCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgSHVlLnByb3RvdHlwZS5pdGVyYXRlQ2FudmFzID0gZnVuY3Rpb24gKGhlbHBlcikge1xyXG4gICAgICAgICAgICAgICAgdmFyIHJnYiA9IGhlbHBlci50b1ZlY3RvcjMoKTtcclxuICAgICAgICAgICAgICAgIGhlbHBlci5yID0gcmdiLmRvdCh0aGlzLndlaWdodHMpO1xyXG4gICAgICAgICAgICAgICAgaGVscGVyLmcgPSByZ2IuZG90U2NhbGFycyh0aGlzLndlaWdodHMueiwgdGhpcy53ZWlnaHRzLngsIHRoaXMud2VpZ2h0cy55KTtcclxuICAgICAgICAgICAgICAgIGhlbHBlci5iID0gcmdiLmRvdFNjYWxhcnModGhpcy53ZWlnaHRzLnksIHRoaXMud2VpZ2h0cy56LCB0aGlzLndlaWdodHMueCk7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIHJldHVybiBIdWU7XHJcbiAgICAgICAgfSkoanNmeC5JdGVyYWJsZUZpbHRlcik7XHJcbiAgICAgICAgZmlsdGVyLkh1ZSA9IEh1ZTtcclxuICAgIH0pKGZpbHRlciA9IGpzZnguZmlsdGVyIHx8IChqc2Z4LmZpbHRlciA9IHt9KSk7XHJcbn0pKGpzZnggfHwgKGpzZnggPSB7fSkpO1xyXG52YXIganNmeDtcclxuKGZ1bmN0aW9uIChqc2Z4KSB7XHJcbiAgICB2YXIgZmlsdGVyO1xyXG4gICAgKGZ1bmN0aW9uIChmaWx0ZXIpIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZmlsdGVyICAgICAgICAgICBIdWUgLyBTYXR1cmF0aW9uXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uICAgICAgUHJvdmlkZXMgbXVsdGlwbGljYXRpdmUgc2F0dXJhdGlvbiBjb250cm9sLiBSR0IgY29sb3Igc3BhY2VcclxuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICBjYW4gYmUgaW1hZ2luZWQgYXMgYSBjdWJlIHdoZXJlIHRoZSBheGVzIGFyZSB0aGUgcmVkLCBncmVlbiwgYW5kIGJsdWUgY29sb3JcclxuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICB2YWx1ZXMuXHJcbiAgICAgICAgICogICAgICAgICAgICAgICAgICAgU2F0dXJhdGlvbiBpcyBpbXBsZW1lbnRlZCBieSBzY2FsaW5nIGFsbCBjb2xvciBjaGFubmVsIHZhbHVlcyBlaXRoZXIgdG93YXJkXHJcbiAgICAgICAgICogICAgICAgICAgICAgICAgICAgb3IgYXdheSBmcm9tIHRoZSBhdmVyYWdlIGNvbG9yIGNoYW5uZWwgdmFsdWUuXHJcbiAgICAgICAgICogQHBhcmFtIHNhdHVyYXRpb24gLTEgdG8gMSAoLTEgaXMgc29saWQgZ3JheSwgMCBpcyBubyBjaGFuZ2UsIGFuZCAxIGlzIG1heGltdW0gY29udHJhc3QpXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdmFyIFNhdHVyYXRpb24gPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgICAgICAgICBfX2V4dGVuZHMoU2F0dXJhdGlvbiwgX3N1cGVyKTtcclxuICAgICAgICAgICAgZnVuY3Rpb24gU2F0dXJhdGlvbihzYXR1cmF0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICBfc3VwZXIuY2FsbCh0aGlzLCBudWxsLCBcIlxcbiAgICAgICAgICAgIHVuaWZvcm0gc2FtcGxlcjJEIHRleHR1cmU7XFxuICAgICAgICAgICAgdW5pZm9ybSBmbG9hdCBzYXR1cmF0aW9uO1xcbiAgICAgICAgICAgIHZhcnlpbmcgdmVjMiB0ZXhDb29yZDtcXG5cXG4gICAgICAgICAgICB2b2lkIG1haW4oKSB7XFxuICAgICAgICAgICAgICAgIHZlYzQgY29sb3IgPSB0ZXh0dXJlMkQodGV4dHVyZSwgdGV4Q29vcmQpO1xcblxcbiAgICAgICAgICAgICAgICBmbG9hdCBhdmVyYWdlID0gKGNvbG9yLnIgKyBjb2xvci5nICsgY29sb3IuYikgLyAzLjA7XFxuICAgICAgICAgICAgICAgIGlmIChzYXR1cmF0aW9uID4gMC4wKSB7XFxuICAgICAgICAgICAgICAgICAgICBjb2xvci5yZ2IgKz0gKGF2ZXJhZ2UgLSBjb2xvci5yZ2IpICogKDEuMCAtIDEuMCAvICgxLjAwMSAtIHNhdHVyYXRpb24pKTtcXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcXG4gICAgICAgICAgICAgICAgICAgIGNvbG9yLnJnYiArPSAoYXZlcmFnZSAtIGNvbG9yLnJnYikgKiAoLXNhdHVyYXRpb24pO1xcbiAgICAgICAgICAgICAgICB9XFxuXFxuICAgICAgICAgICAgICAgIGdsX0ZyYWdDb2xvciA9IGNvbG9yO1xcbiAgICAgICAgICAgIH1cXG4gICAgICAgIFwiKTtcclxuICAgICAgICAgICAgICAgIC8vIHNldCBwcm9wZXJ0aWVzXHJcbiAgICAgICAgICAgICAgICB0aGlzLnByb3BlcnRpZXMuc2F0dXJhdGlvbiA9IGpzZnguRmlsdGVyLmNsYW1wKC0xLCBzYXR1cmF0aW9uLCAxKSB8fCAwO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIFNhdHVyYXRpb24ucHJvdG90eXBlLml0ZXJhdGVDYW52YXMgPSBmdW5jdGlvbiAoaGVscGVyKSB7XHJcbiAgICAgICAgICAgICAgICB2Y
4244XIgc2F0dXJhdGlvbiA9IHRoaXMucHJvcGVydGllcy5zYXR1cmF0aW9uO1xyXG4gICAgICAgICAgICAgICAgdmFyIGF2ZXJhZ2UgPSAoaGVscGVyLnIgKyBoZWxwZXIuZyArIGhlbHBlci5iKSAvIDM7XHJcbiAgICAgICAgICAgICAgICBpZiAoc2F0dXJhdGlvbiA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBoZWxwZXIuciArPSAoYXZlcmFnZSAtIGhlbHBlci5yKSAqICgxIC0gMSAvICgxLjAwMSAtIHNhdHVyYXRpb24pKTtcclxuICAgICAgICAgICAgICAgICAgICBoZWxwZXIuZyArPSAoYXZlcmFnZSAtIGhlbHBlci5nKSAqICgxIC0gMSAvICgxLjAwMSAtIHNhdHVyYXRpb24pKTtcclxuICAgICAgICAgICAgICAgICAgICBoZWxwZXIuYiArPSAoYXZlcmFnZSAtIGhlbHBlci5iKSAqICgxIC0gMSAvICgxLjAwMSAtIHNhdHVyYXRpb24pKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGhlbHBlci5yICs9IChhdmVyYWdlIC0gaGVscGVyLnIpICogKC1zYXR1cmF0aW9uKTtcclxuICAgICAgICAgICAgICAgICAgICBoZWxwZXIuZyArPSAoYXZlcmFnZSAtIGhlbHBlci5nKSAqICgtc2F0dXJhdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgaGVscGVyLmIgKz0gKGF2ZXJhZ2UgLSBoZWxwZXIuYikgKiAoLXNhdHVyYXRpb24pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICByZXR1cm4gU2F0dXJhdGlvbjtcclxuICAgICAgICB9KShqc2Z4Lkl0ZXJhYmxlRmlsdGVyKTtcclxuICAgICAgICBmaWx0ZXIuU2F0dXJhdGlvbiA9IFNhdHVyYXRpb247XHJcbiAgICB9KShmaWx0ZXIgPSBqc2Z4LmZpbHRlciB8fCAoanNmeC5maWx0ZXIgPSB7fSkpO1xyXG59KShqc2Z4IHx8IChqc2Z4ID0ge30pKTtcclxudmFyIGpzZng7XHJcbihmdW5jdGlvbiAoanNmeCkge1xyXG4gICAgdmFyIGZpbHRlcjtcclxuICAgIChmdW5jdGlvbiAoZmlsdGVyKSB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGZpbHRlciAgICAgICAgIFNlcGlhXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uICAgIEdpdmVzIHRoZSBpbWFnZSBhIHJlZGRpc2gtYnJvd24gbW9ub2Nocm9tZSB0aW50IHRoYXQgaW1pdGF0ZXMgYW4gb2xkIHBob3RvZ3JhcGguXHJcbiAgICAgICAgICogQHBhcmFtIGFtb3VudCAgIDAgdG8gMSAoMCBmb3Igbm8gZWZmZWN0LCAxIGZvciBmdWxsIHNlcGlhIGNvbG9yaW5nKVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHZhciBTZXBpYSA9IChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcbiAgICAgICAgICAgIF9fZXh0ZW5kcyhTZXBpYSwgX3N1cGVyKTtcclxuICAgICAgICAgICAgZnVuY3Rpb24gU2VwaWEoYW1vdW50KSB7XHJcbiAgICAgICAgICAgICAgICBfc3VwZXIuY2FsbCh0aGlzLCBudWxsLCBcIlxcbiAgICAgICAgICAgIHVuaWZvcm0gc2FtcGxlcjJEIHRleHR1cmU7XFxuICAgICAgICAgICAgdW5pZm9ybSBmbG9hdCBhbW91bnQ7XFxuICAgICAgICAgICAgdmFyeWluZyB2ZWMyIHRleENvb3JkO1xcblxcbiAgICAgICAgICAgIHZvaWQgbWFpbigpIHtcXG4gICAgICAgICAgICAgICAgdmVjNCBjb2xvciA9IHRleHR1cmUyRCh0ZXh0dXJlLCB0ZXhDb29yZCk7XFxuICAgICAgICAgICAgICAgIGZsb2F0IHIgPSBjb2xvci5yO1xcbiAgICAgICAgICAgICAgICBmbG9hdCBnID0gY29sb3IuZztcXG4gICAgICAgICAgICAgICAgZmxvYXQgYiA9IGNvbG9yLmI7XFxuXFxuICAgICAgICAgICAgICAgIGNvbG9yLnIgPSBtaW4oMS4wLCAociAqICgxLjAgLSAoMC42MDcgKiBhbW91bnQpKSkgKyAoZyAqICgwLjc2OSAqIGFtb3VudCkpICsgKGIgKiAoMC4xODkgKiBhbW91bnQpKSk7XFxuICAgICAgICAgICAgICAgIGNvbG9yLmcgPSBtaW4oMS4wLCAociAqIDAuMzQ5ICogYW1vdW50KSArIChnICogKDEuMCAtICgwLjMxNCAqIGFtb3VudCkpKSArIChiICogMC4xNjggKiBhbW91bnQpKTtcXG4gICAgICAgICAgICAgICAgY29sb3IuYiA9IG1pbigxLjAsIChyICogMC4yNzIgKiBhbW91bnQpICsgKGcgKiAwLjUzNCAqIGFtb3VudCkgKyAoYiAqICgxLjAgLSAoMC44NjkgKiBhbW91bnQpKSkpO1xcblxcbiAgICAgICAgICAgICAgICBnbF9GcmFnQ29sb3IgPSBjb2xvcjtcXG4gICAgICAgICAgICB9XFxuICAgICAgICBcIik7XHJcbiAgICAgICAgICAgICAgICAvLyBzZXQgcHJvcGVydGllc1xyXG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wZXJ0aWVzLmFtb3VudCA9IGpzZnguRmlsdGVyLmNsYW1wKC0xLCBhbW91bnQsIDEpIHx8IDA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgU2VwaWEucHJvdG90eXBlLml0ZXJhdGVDYW52YXMgPSBmdW5jdGlvbiAoaGVscGVyKSB7XHJcbiAgICAgICAgICAgICAgICB2Y
4244XIgciA9IGhlbHBlci5yO1xyXG4gICAgICAgICAgICAgICAgdmFyIGcgPSBoZWxwZXIuZztcclxuICAgICAgICAgICAgICAgIHZhciBiID0gaGVscGVyLmI7XHJcbiAgICAgICAgICAgICAgICB2YXIgYW1vdW50ID0gdGhpcy5wcm9wZXJ0aWVzLmFtb3VudDtcclxuICAgICAgICAgICAgICAgIGhlbHBlci5yID0gTWF0aC5taW4oMS4wLCAociAqICgxLjAgLSAoMC42MDcgKiBhbW91bnQpKSkgKyAoZyAqICgwLjc2OSAqIGFtb3VudCkpICsgKGIgKiAoMC4xODkgKiBhbW91bnQpKSk7XHJcbiAgICAgICAgICAgICAgICBoZWxwZXIuZyA9IE1hdGgubWluKDEuMCwgKHIgKiAwLjM0OSAqIGFtb3VudCkgKyAoZyAqICgxLjAgLSAoMC4zMTQgKiBhbW91bnQpKSkgKyAoYiAqIDAuMTY4ICogYW1vdW50KSk7XHJcbiAgICAgICAgICAgICAgICBoZWxwZXIuYiA9IE1hdGgubWluKDEuMCwgKHIgKiAwLjI3MiAqIGFtb3VudCkgKyAoZyAqIDAuNTM0ICogYW1vdW50KSArIChiICogKDEuMCAtICgwLjg2OSAqIGFtb3VudCkpKSk7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIHJldHVybiBTZXBpYTtcclxuICAgICAgICB9KShqc2Z4Lkl0ZXJhYmxlRmlsdGVyKTtcclxuICAgICAgICBmaWx0ZXIuU2VwaWEgPSBTZXBpYTtcclxuICAgIH0pKGZpbHRlciA9IGpzZnguZmlsdGVyIHx8IChqc2Z4LmZpbHRlciA9IHt9KSk7XHJcbn0pKGpzZnggfHwgKGpzZnggPSB7fSkpO1xyXG52YXIganNmeDtcclxuKGZ1bmN0aW9uIChqc2Z4KSB7XHJcbiAgICB2YXIgZmlsdGVyO1xyXG4gICAgKGZ1bmN0aW9uIChmaWx0ZXIpIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZmlsdGVyICAgICAgICAgVW5zaGFycCBNYXNrXHJcbiAgICAgICAgICogQGRlc2NyaXB0aW9uICAgIEEgZm9ybSBvZiBpbWFnZSBzaGFycGVuaW5nIHRoYXQgYW1wbGlmaWVzIGhpZ2gtZnJlcXVlbmNpZXMgaW4gdGhlIGltYWdlLiBJdFxyXG4gICAgICAgICAqICAgICAgICAgICAgICAgICBpcyBpbXBsZW1lbnRlZCBieSBzY2FsaW5nIHBpeGVscyBhd2F5IGZyb20gdGhlIGF2ZXJhZ2Ugb2YgdGhlaXIgbmVpZ2hib3JzLlxyXG4gICAgICAgICAqIEBwYXJhbSByYWRpdXMgICAwIHRvIDE4MCAtIFRoZSBibHVyIHJhZGl1cyB0aGF0IGNhbGN1bGF0ZXMgdGhlIGF2ZXJhZ2Ugb2YgdGhlIG5laWdoYm9yaW5nIHBpeGVscy5cclxuICAgICAgICAgKiBAcGFyYW0gc3RyZW5ndGggQSBzY2FsZSBmYWN0b3Igd2hlcmUgMCBpcyBubyBlZmZlY3QgYW5kIGhpZ2hlciB2YWx1ZXMgY2F1c2UgYSBzdHJvbmdlciBlZmZlY3QuXHJcbiAgICAgICAgICogQG5vdGUgICAgICAgICAgIENvdWxkIHBvdGVudGlhbGx5IGJlIGNvbnZlcnRlZCB0byBhbiBJdGVyYWJsZUZpbHRlciwgYnV0IHdlIHNvbWVob3cgbmVlZCB0aGUgb3JpZ2luYWwgSW1hZ2VEYXRhXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdmFyIFVuc2hhcnBNYXNrID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgICAgICAgICAgX19leHRlbmRzKFVuc2hhcnBNYXNrLCBfc3VwZXIpO1xyXG4gICAgICAgICAgICBmdW5jdGlvbiBVbnNoYXJwTWFzayhyYWRpdXMsIHN0cmVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICBfc3VwZXIuY2FsbCh0aGlzLCBudWxsLCBcIlxcbiAgICAgICAgICAgIHVuaWZvcm0gc2FtcGxlcjJEIGJsdXJyZWRUZXh0dXJlO1xcbiAgICAgICAgICAgIHVuaWZvcm0gc2FtcGxlcjJEIG9yaWdpbmFsVGV4dHVyZTtcXG4gICAgICAgICAgICB1bmlmb3JtIGZsb2F0IHN0cmVuZ3RoO1xcbiAgICAgICAgICAgIHVuaWZvcm0gZmxvYXQgdGhyZXNob2xkO1xcbiAgICAgICAgICAgIHZhcnlpbmcgdmVjMiB0ZXhDb29yZDtcXG5cXG4gICAgICAgICAgICB2b2lkIG1haW4oKSB7XFxuICAgICAgICAgICAgICAgIHZlYzQgYmx1cnJlZCA9IHRleHR1cmUyRChibHVycmVkVGV4dHVyZSwgdGV4Q29vcmQpO1xcbiAgICAgICAgICAgICAgICB2ZWM0IG9yaWdpbmFsID0gdGV4dHVyZTJEKG9yaWdpbmFsVGV4dHVyZSwgdGV4Q29vcmQpO1xcbiAgICAgICAgICAgICAgICBnbF9GcmFnQ29sb3IgPSBtaXgoYmx1cnJlZCwgb3JpZ2luYWwsIDEuMCArIHN0cmVuZ3RoKTtcXG4gICAgICAgICAgICB9XFxuICAgICAgICBcIik7XHJcbiAgICAgICAgICAgICAgICAvLyBzZXQgcHJvcGVydGllc1xyXG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wZXJ0aWVzLnJhZGl1cyA9IHJhZGl1cztcclxuICAgICAgICAgICAgICAgIHRoaXMucHJvcGVydGllcy5zdHJlbmd0aCA9IHN0cmVuZ3RoO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIFVuc2hhcnBNYXNrLnByb3RvdHlwZS5kcmF3V2ViR0wgPSBmdW5jdGlvbiAocmVuZGVyZXIpIHtcclxuICAgICAgICAgICAgICAgIHZhciBzaGFkZXIgPSByZW5kZXJlci5nZXRTaGFkZXIodGhpcyk7XHJcbiAgICAgICAgICAgICAgICB2Y
4244XIgcmFkaXVzID0gdGhpcy5wcm9wZXJ0aWVzLnJhZGl1cztcclxuICAgICAgICAgICAgICAgIHZhciBzdHJlbmd0aCA9IHRoaXMucHJvcGVydGllcy5zdHJlbmd0aDtcclxuICAgICAgICAgICAgICAgIC8vIGNyZWF0ZSBhIG5ldyB0ZXh0dXJlXHJcbiAgICAgICAgICAgICAgICB2YXIgZXh0cmFUZXh0dXJlID0gcmVuZGVyZXIuY3JlYXRlVGV4dHVyZSgpO1xyXG4gICAgICAgICAgICAgICAgLy8gdXNlIGEgdGV4dHVyZSBhbmQgZHJhdyB0byBpdFxyXG4gICAgICAgICAgICAgICAgcmVuZGVyZXIuZ2V0VGV4dHVyZSgpLnVzZSgpO1xyXG4gICAgICAgICAgICAgICAgZXh0cmFUZXh0dXJlLmRyYXdUbyhyZW5kZXJlci5nZXREZWZhdWx0U2hhZGVyKCkuZHJhd1JlY3QuYmluZChyZW5kZXJlci5nZXREZWZhdWx0U2hhZGVyKCkpKTtcclxuICAgICAgICAgICAgICAgIC8vIGJsdXIgY3VycmVudCB0ZXh0dXJlXHJcbiAgICAgICAgICAgICAgICBleHRyYVRleHR1cmUudXNlKDEpO1xyXG4gICAgICAgICAgICAgICAgLy8gZHJhdyB0aGUgYmx1clxyXG4gICAgICAgICAgICAgICAgdmFyIGJsdXIgPSBuZXcgZmlsdGVyLkJsdXIocmFkaXVzKTtcclxuICAgICAgICAgICAgICAgIGJsdXIuZHJhd1dlYkdMKHJlbmRlcmVyKTtcclxuICAgICAgICAgICAgICAgIC8vIHVzZSB0aGUgc3RvcmVkIHRleHR1cmUgdG8gZGV0ZWN0IGVkZ2VzXHJcbiAgICAgICAgICAgICAgICBzaGFkZXIudGV4dHVyZXMoe1xyXG4gICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsVGV4dHVyZTogMVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICByZW5kZXJlci5nZXRUZXh0dXJlKCkudXNlKCk7XHJcbiAgICAgICAgICAgICAgICByZW5kZXJlci5nZXROZXh0VGV4dHVyZSgpLmRyYXdUbyhmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2hhZGVyLnVuaWZvcm1zKHsgc3RyZW5ndGg6IHN0cmVuZ3RoIH0pLmRyYXdSZWN0KCk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIGV4dHJhVGV4dHVyZS51bnVzZSgxKTtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgVW5zaGFycE1hc2sucHJvdG90eXBlLmRyYXdDYW52YXMgPSBmdW5jdGlvbiAoaW1hZ2VEYXRhKSB7XHJcbiAgICAgICAgICAgICAgICB2Y
4244XIgcGl4ZWxzID0gaW1hZ2VEYXRhLmRhdGE7XHJcbiAgICAgICAgICAgICAgICAvLyBwcm9wc1xyXG4gICAgICAgICAgICAgICAgdmFyIHJhZGl1cyA9IHRoaXMucHJvcGVydGllcy5yYWRpdXM7XHJcbiAgICAgICAgICAgICAgICB2YXIgc3RyZW5ndGggPSB0aGlzLnByb3BlcnRpZXMuc3RyZW5ndGggKyAxO1xyXG4gICAgICAgICAgICAgICAgLy8gY2xvbmUgb2YgZGF0YVxyXG4gICAgICAgICAgICAgICAgLy8gQHRvZG86IGRlY2xhcmVkIG15IG93biBVaW50OENsYW1wZWRBcnJheSBhYm92ZSBzaW5jZSBJIGFtIGhhdmluZyBpc3N1ZXMgd2l0aCBUeXBlU2NyaXB0LlxyXG4gICAgICAgICAgICAgICAgLy8gYWRkaXRpb25hbGx5LCBteSBwcmV2aW91cyBjYWxsZWQgaW1hZ2VEYXRhLmRhdGEuc2V0KG9yaWdpbmFsKSAod2hpY2ggSSBhbHNvIGNhbid0IGhlcmUgYmVjYXVzZSBvZiBUUyBtYXBwaW5nKVxyXG4gICAgICAgICAgICAgICAgdmFyIG9yaWdpbmFsID0gbmV3IFVpbnQ4Q2xhbXBlZEFycmF5KGltYWdlRGF0YS5kYXRhKTtcclxuICAgICAgICAgICAgICAgIGltYWdlRGF0YS5kYXRhID0gb3JpZ2luYWw7XHJcbiAgICAgICAgICAgICAgICAvLyBibHVyIGltYWdlXHJcbiAgICAgICAgICAgICAgICB2YXIgYmx1ciA9IG5ldyBmaWx0ZXIuQmx1cihyYWRpdXMpO1xyXG4gICAgICAgICAgICAgICAgYmx1ci5kcmF3Q2FudmFzKGltYWdlRGF0YSk7XHJcbiAgICAgICAgICAgICAgICAvLyB0cnlpbmcgdG8gcmVwbGljYXRlIG1peCgpIGZyb20gd2ViZ2wsIHdoaWNoIGlzIGJhc2ljYWxseSB4ICogKDEgLWEpXHJcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHBpeGVscy5sZW5ndGg7IGkgKz0gNCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHBpeGVsc1tpXSA9IHBpeGVsc1tpXSAqICgxIC0gc3RyZW5ndGgpICsgb3JpZ2luYWxbaV0gKiBzdHJlbmd0aDtcclxuICAgICAgICAgICAgICAgICAgICBwaXhlbHNbaSArIDFdID0gcGl4ZWxzW2kgKyAxXSAqICgxIC0gc3RyZW5ndGgpICsgb3JpZ2luYWxbaSArIDFdICogc3RyZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgcGl4ZWxzW2kgKyAyXSA9IHBpeGVsc1tpICsgMl0gKiAoMSAtIHN0cmVuZ3RoKSArIG9yaWdpbmFsW2kgKyAyXSAqIHN0cmVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGltYWdlRGF0YTtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgcmV0dXJuIFVuc2hhcnBNYXNrO1xyXG4gICAgICAgIH0pKGpzZnguRmlsdGVyKTtcclxuICAgICAgICBmaWx0ZXIuVW5zaGFycE1hc2sgPSBVbnNoYXJwTWFzaztcclxuICAgIH0pKGZpbHRlciA9IGpzZnguZmlsdGVyIHx8IChqc2Z4LmZpbHRlciA9IHt9KSk7XHJcbn0pKGpzZnggfHwgKGpzZnggPSB7fSkpO1xyXG52YXIganNmeDtcclxuKGZ1bmN0aW9uIChqc2Z4KSB7XHJcbiAgICB2YXIgdXRpbDtcclxuICAgIChmdW5jdGlvbiAodXRpbCkge1xyXG4gICAgICAgIHZhciBJbWFnZURhdGFIZWxwZXIgPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBmdW5jdGlvbiBJbWFnZURhdGFIZWxwZXIoaW1hZ2VEYXRhLCBpbmRleCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5pbWFnZURhdGEgPSBpbWFnZURhdGE7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmluZGV4ID0gaW5kZXg7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnIgPSB0aGlzLmltYWdlRGF0YS5kYXRhW2luZGV4XSAvIDI1NTtcclxuICAgICAgICAgICAgICAgIHRoaXMuZyA9IHRoaXMuaW1hZ2VEYXRhLmRhdGFbaW5kZXggKyAxXSAvIDI1NTtcclxuICAgICAgICAgICAgICAgIHRoaXMuYiA9IHRoaXMuaW1hZ2VEYXRhLmRhdGFbaW5kZXggKyAyXSAvIDI1NTtcclxuICAgICAgICAgICAgICAgIHRoaXMuYSA9IHRoaXMuaW1hZ2VEYXRhLmRhdGFbaW5kZXggKyAzXSAvIDI1NTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBJbWFnZURhdGFIZWxwZXIucHJvdG90eXBlLmdldEltYWdlRGF0YSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmltYWdlRGF0YTtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgSW1hZ2VEYXRhSGVscGVyLnByb3RvdHlwZS5zYXZlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5pbWFnZURhdGEuZGF0YVt0aGlzLmluZGV4XSA9IHRoaXMuciAqIDI1NTtcclxuICAgICAgICAgICAgICAgIHRoaXMuaW1hZ2VEYXRhLmRhdGFbdGhpcy5pbmRleCArIDFdID0gdGhpcy5nICogMjU1O1xyXG4gICAgICAgICAgICAgICAgdGhpcy5pbWFnZURhdGEuZGF0YVt0aGlzLmluZGV4ICsgMl0gPSB0aGlzLmIgKiAyNTU7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmltYWdlRGF0YS5kYXRhW3RoaXMuaW5kZXggKyAzXSA9IHRoaXMuYSAqIDI1NTtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgSW1hZ2VEYXRhSGVscGVyLnByb3RvdHlwZS50b1ZlY3RvcjMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IGpzZngudXRpbC5WZWN0b3IzKHRoaXMuciwgdGhpcy5nLCB0aGlzLmIpO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBJbWFnZURhdGFIZWxwZXIucHJvdG90eXBlLmZyb21WZWN0b3IzID0gZnVuY3Rpb24gKHYpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuciA9IHYueDtcclxuICAgICAgICAgICAgICAgIHRoaXMuZyA9IHYueTtcclxuICAgICAgICAgICAgICAgIHRoaXMuYiA9IHYuejtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgcmV0dXJuIEltYWdlRGF0YUhlbHBlcjtcclxuICAgICAgICB9KSgpO1xyXG4gICAgICAgIHV0aWwuSW1hZ2VEYXRhSGVscGVyID0gSW1hZ2VEYXRhSGVscGVyO1xyXG4gICAgfSkodXRpbCA9IGpzZngudXRpbCB8fCAoanNmeC51dGlsID0ge30pKTtcclxufSkoanNmeCB8fCAoanNmeCA9IHt9KSk7XHJcbnZhciBqc2Z4O1xyXG4oZnVuY3Rpb24gKGpzZngpIHtcclxuICAgIHZhciB1dGlsO1xyXG4gICAgKGZ1bmN0aW9uICh1dGlsKSB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRnJvbSBTcGxpbmVJbnRlcnBvbGF0b3IuY3MgaW4gdGhlIFBhaW50Lk5FVCBzb3VyY2UgY29kZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgI
4244HZhciBTcGxpbmVJbnRlcnBvbGF0b3IgPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBmdW5jdGlvbiBTcGxpbmVJbnRlcnBvbGF0b3IocG9pbnRzKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnBvaW50cyA9IHBvaW50cztcclxuICAgICAgICAgICAgICAgIHZhciBuID0gcG9pbnRzLmxlbmd0aDtcclxuICAgICAgICAgICAgICAgIHZhciBpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy54YSA9IFtdO1xyXG4gICAgICAgICAgICAgICAgdGhpcy55YSA9IFtdO1xyXG4gICAgICAgICAgICAgICAgdGhpcy51ID0gW107XHJcbiAgICAgICAgICAgICAgICB0aGlzLnkyID0gW107XHJcbiAgICAgICAgICAgICAgICBwb2ludHMuc29ydChmdW5jdGlvbiAoYSwgYikge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhWzBdIC0gYlswXTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IG47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMueGEucHVzaChwb2ludHNbaV1bMF0pO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMueWEucHVzaChwb2ludHNbaV1bMV0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGhpcy51WzBdID0gMDtcclxuICAgICAgICAgICAgICAgIHRoaXMueTJbMF0gPSAwO1xyXG4gICAgICAgICAgICAgICAgZm9yIChpID0gMTsgaSA8IG4gLSAxOyArK2kpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIHRoZSBkZWNvbXBvc2l0aW9uIGxvb3Agb2YgdGhlIHRyaS1kaWFnb25hbCBhbGdvcml0aG0uXHJcbiAgICAgICAgICAgICAgICAgICAgLy8geTIgYW5kIHUgYXJlIHVzZWQgZm9yIHRlbXBvcmFyeSBzdG9yYWdlIG9mIHRoZSBkZWNvbXBvc2VkIGZhY3RvcnMuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHd4ID0gdGhpcy54YVtpICsgMV0gLSB0aGlzLnhhW2kgLSAxXTtcclxuICAgICAgICAgICAgICAgICAgICB2Y
4244XIgc2lnID0gKHRoaXMueGFbaV0gLSB0aGlzLnhhW2kgLSAxXSkgLyB3eDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcCA9IHNpZyAqIHRoaXMueTJbaSAtIDFdICsgMi4wO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMueTJbaV0gPSAoc2lnIC0gMS4wKSAvIHA7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGRkeWR4ID0gKHRoaXMueWFbaSArIDFdIC0gdGhpcy55YVtpXSkgLyAodGhpcy54YVtpICsgMV0gLSB0aGlzLnhhW2ldKSAtXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICh0aGlzLnlhW2ldIC0gdGhpcy55YVtpIC0gMV0pIC8gKHRoaXMueGFbaV0gLSB0aGlzLnhhW2kgLSAxXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51W2ldID0gKDYuMCAqIGRkeWR4IC8gd3ggLSBzaWcgKiB0aGlzLnVbaSAtIDFdKSAvIHA7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGlzLnkyW24gLSAxXSA9IDA7XHJcbiAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIHRoZSBiYWNrLXN1YnN0aXR1dGlvbiBsb29wIG9mIHRoZSB0cmktZGlhZ29uYWwgYWxnb3JpdGhtXHJcbiAgICAgICAgICAgICAgICBmb3IgKGkgPSBuIC0gMjsgaSA+PSAwOyAtLWkpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnkyW2ldID0gdGhpcy55MltpXSAqIHRoaXMueTJbaSArIDFdICsgdGhpcy51W2ldO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIFNwbGluZUludGVycG9sYXRvci5wcm90b3R5cGUuaW50ZXJwb2xhdGUgPSBmdW5jdGlvbiAoeCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIG4gPSB0aGlzLnlhLmxlbmd0aDtcclxuICAgICAgICAgICAgICAgIHZhciBrbG8gPSAwO1xyXG4gICAgICAgICAgICAgICAgdmFyIGtoaSA9IG4gLSAxO1xyXG4gICAgICAgICAgICAgICAgLy8gV2Ugd2lsbCBmaW5kIHRoZSByaWdodCBwbGFjZSBpbiB0aGUgdGFibGUgYnkgbWVhbnMgb2ZcclxuICAgICAgICAgICAgICAgIC8vIGJpc2VjdGlvbi4gVGhpcyBpcyBvcHRpbWFsIGlmIHNlcXVlbnRpYWwgY2FsbHMgdG8gdGhpc1xyXG4gICAgICAgICAgICAgICAgLy8gcm91dGluZSBhcmUgYXQgcmFuZG9tIHZhbHVlcyBvZiB4LiBJZiBzZXF1ZW50aWFsIGNhbGxzXHJcbiAgICAgICAgICAgICAgICAvLyBhcmUgaW4gb3JkZXIsIGFuZCBjbG9zZWx5IHNwYWNlZCwgb25lIHdvdWxkIGRvIGJldHRlclxyXG4gICAgICAgICAgICAgICAgLy8gdG8gc3RvcmUgcHJldmlvdXMgdmFsdWVzIG9mIGtsbyBhbmQga2hpLlxyXG4gICAgICAgICAgICAgICAgd2hpbGUgKGtoaSAtIGtsbyA+IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICB2Y
4244XIgayA9IChraGkgKyBrbG8pID4+IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMueGFba10gPiB4KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGtoaSA9IGs7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBrbG8gPSBrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHZhciBoID0gdGhpcy54YVtraGldIC0gdGhpcy54YVtrbG9dO1xyXG4gICAgICAgICAgICAgICAgdmFyIGEgPSAodGhpcy54YVtraGldIC0geCkgLyBoO1xyXG4gICAgICAgICAgICAgICAgdmFyIGIgPSAoeCAtIHRoaXMueGFba2xvXSkgLyBoO1xyXG4gICAgICAgICAgICAgICAgLy8gQ3ViaWMgc3BsaW5lIHBvbHlub21pYWwgaXMgbm93IGV2YWx1YXRlZC5cclxuICAgICAgICAgICAgICAgIHJldHVybiBhICogdGhpcy55YVtrbG9dICsgYiAqIHRoaXMueWFba2hpXSArXHJcbiAgICAgICAgICAgICAgICAgICAgKChhICogYSAqIGEgLSBhKSAqIHRoaXMueTJba2xvXSArIChiICogYiAqIGIgLSBiKSAqIHRoaXMueTJba2hpXSkgKiAoaCAqIGgpIC8gNi4wO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICByZXR1cm4gU3BsaW5lSW50ZXJwb2xhdG9yO1xyXG4gICAgICAgIH0pKCk7XHJcbiAgICAgICAgdXRpbC5TcGxpbmVJbnRlcnBvbGF0b3IgPSBTcGxpbmVJbnRlcnBvbGF0b3I7XHJcbiAgICB9KSh1dGlsID0ganNmeC51dGlsIHx8IChqc2Z4LnV0aWwgPSB7fSkpO1xyXG59KShqc2Z4IHx8IChqc2Z4ID0ge30pKTtcclxuLyoqXHJcbiAqIFZlY3RvcjMgVXRpbGl0eSBDbGFzc1xyXG4gKiAgLT4gVGFrZW4gZnJvbSBodHRwczovL2dpdGh1Yi5jb20vbXJkb29iL3RocmVlLmpzL2Jsb2IvbWFzdGVyL3NyYy9tYXRoL1ZlY3RvcjMuanMgd2l0aCBvbmx5IHRoZSBmdW5jdGlvbnMgd2UgbmVlZC5cclxuICovXHJcbnZhciBqc2Z4O1xyXG4oZnVuY3Rpb24gKGpzZngpIHtcclxuICAgIHZhciB1dGlsO1xyXG4gICAgKGZ1bmN0aW9uICh1dGlsKSB7XHJcbiAgICAgICAgdmFyIFZlY3RvcjMgPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBmdW5jdGlvbiBWZWN0b3IzKHgsIHksIHopIHtcclxuICAgICAgICAgICAgICAgIHRoaXMueCA9IHg7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnkgPSB5O1xyXG4gICAgICAgICAgICAgICAgdGhpcy56ID0gejtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBWZWN0b3IzLnByb3RvdHlwZS5hZGRTY2FsYXIgPSBmdW5jdGlvbiAocykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy54ICs9IHM7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnkgKz0gcztcclxuICAgICAgICAgICAgICAgIHRoaXMueiArPSBzO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIFZlY3RvcjMucHJvdG90eXBlLm11bHRpcGx5U2NhbGFyID0gZnVuY3Rpb24gKHMpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMueCAqPSBzO1xyXG4gICAgICAgICAgICAgICAgdGhpcy55ICo9IHM7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnogKj0gcztcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBWZWN0b3IzLnByb3RvdHlwZS5kaXZpZGVTY2FsYXIgPSBmdW5jdGlvbiAocykge1xyXG4gICAgICAgICAgICAgICAgaWYgKHMgIT09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICB2Y
4244XIgaW52U2NhbGFyID0gMSAvIHM7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy54ICo9IGludlNjYWxhcjtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnkgKj0gaW52U2NhbGFyO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMueiAqPSBpbnZTY2FsYXI7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnggPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMueSA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy56ID0gMDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBWZWN0b3IzLnByb3RvdHlwZS5sZW5ndGggPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gTWF0aC5zcXJ0KHRoaXMueCAqIHRoaXMueCArIHRoaXMueSAqIHRoaXMueSArIHRoaXMueiAqIHRoaXMueik7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIFZlY3RvcjMucHJvdG90eXBlLmRvdCA9IGZ1bmN0aW9uICh2KSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy54ICogdi54ICsgdGhpcy55ICogdi55ICsgdGhpcy56ICogdi56O1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBWZWN0b3IzLnByb3RvdHlwZS5kb3RTY2FsYXJzID0gZnVuY3Rpb24gKHgsIHksIHopIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnggKiB4ICsgdGhpcy55ICogeSArIHRoaXMueiAqIHo7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIHJldHVybiBWZWN0b3IzO1xyXG4gICAgICAgIH0pKCk7XHJcbiAgICAgICAgdXRpbC5WZWN0b3IzID0gVmVjdG9yMztcclxuICAgIH0pKHV0aWwgPSBqc2Z4LnV0aWwgfHwgKGpzZngudXRpbCA9IHt9KSk7XHJcbn0pKGpzZnggfHwgKGpzZnggPSB7fSkpO1xyXG52YXIganNmeDtcclxuKGZ1bmN0aW9uIChqc2Z4KSB7XHJcbiAgICB2YXIgd2ViZ2w7XHJcbiAgICAoZnVuY3Rpb24gKHdlYmdsKSB7XHJcbiAgICAgICAgdmFyIFJlbmRlcmVyID0gKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgZnVuY3Rpb24gUmVuZGVyZXIoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJjYW52YXNcIik7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmdsID0gdGhpcy5jYW52YXMuZ2V0Q29udGV4dChcImV4cGVyaW1lbnRhbC13ZWJnbFwiLCB7IHByZW11bHRpcGxpZWRBbHBoYTogZmFsc2UgfSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmdsLnBpeGVsU3RvcmVpKHRoaXMuZ2wuVU5QQUNLX1BSRU1VTFRJUExZX0FMUEhBX1dFQkdMLCAxKTtcclxuICAgICAgICAgICAgICAgIC8vIHZhcmlhYmxlcyB0byBzdG9yZSB0aGUgc291cmNlXHJcbiAgICAgICAgICAgICAgICB0aGlzLnNvdXJjZSA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNvdXJjZVRleHR1cmUgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgLy8gc3RvcmUgdGhlIHRleHR1cmVzIGFuZCBidWZmZXJzXHJcbiAgICAgICAgICAgICAgICB0aGlzLnRleHR1cmVzID0gbnVsbDtcclxuICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudFRleHR1cmUgPSAwO1xyXG4gICAgICAgICAgICAgICAgLy8gaW5pdGlhbGl6ZSBhIHNoYWRlciBjYWNoZVxyXG4gICAgICAgICAgICAgICAgdGhpcy5nbC5zaGFkZXJDYWNoZSA9IHt9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIFJlbmRlcmVyLnByb3RvdHlwZS5zZXRTb3VyY2UgPSBmdW5jdGlvbiAoc291cmNlKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBmaXJzdCwgY2xlYW4gdXBcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnNvdXJjZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2xlYW5VcCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy8gcmUtaW5pdGlhbGl6ZSByZW5kZXJlciBmb3IgcmVuZGVyaW5nIHdpdGggbmV3IHNvdXJjZVxyXG4gICAgICAgICAgICAgICAgdGhpcy5zb3VyY2UgPSBzb3VyY2U7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNvdXJjZVRleHR1cmUgPSBqc2Z4LndlYmdsLlRleHR1cmUuZnJvbUVsZW1lbnQodGhpcy5nbCwgc291cmNlLmVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgLy8gaW5pdGlhbGl6ZSB0aGUgcmVuZGVyZXIgdGV4dHVyZXNcclxuICAgICAgICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZSgpO1xyXG4gICAgICAgICAgICAgICAgLy8gZHJhdyB0aGUgc291cmNlIHRleHR1cmUgb250byB0aGUgZmlyc3QgdGV4dHVyZVxyXG4gICAgICAgICAgICAgICAgdGhpcy5zb3VyY2VUZXh0dXJlLnVzZSgpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5nZXRUZXh0dXJlKCkuZHJhd1RvKHRoaXMuZ2V0RGVmYXVsdFNoYWRlcigpLmRyYXdSZWN0LmJpbmQodGhpcy5nZXREZWZhdWx0U2hhZGVyKCkpKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBSZW5kZXJlci5wcm90b3R5cGUuZ2V0U291cmNlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuc291cmNlO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBSZW5kZXJlci5wcm90b3R5cGUuYXBwbHlGaWx0ZXIgPSBmdW5jdGlvbiAoZmlsdGVyKSB7XHJcbiAgICAgICAgICAgICAgICBmaWx0ZXIuZHJhd1dlYkdMKHRoaXMpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIFJlbmRlcmVyLnByb3RvdHlwZS5hcHBseUZpbHRlcnMgPSBmdW5jdGlvbiAoZmlsdGVycykge1xyXG4gICAgICAgICAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICAgICAgICAgIGZpbHRlcnMuZm9yRWFjaChmdW5jdGlvbiAoZmlsdGVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZmlsdGVyLmRyYXdXZWJHTChfdGhpcyk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgI
4244HJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBSZW5kZXJlci5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5nZXRUZXh0dXJlKCkudXNlKCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmdldEZsaXBwZWRTaGFkZXIoKS5kcmF3UmVjdCgpO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBSZW5kZXJlci5wcm90b3R5cGUuZ2V0Q2FudmFzID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2FudmFzO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBSZW5kZXJlci5wcm90b3R5cGUuZ2V0VGV4dHVyZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnRleHR1cmVzW3RoaXMuY3VycmVudFRleHR1cmUgJSAyXTtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgUmVuZGVyZXIucHJvdG90eXBlLmdldE5leHRUZXh0dXJlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudGV4dHVyZXNbKyt0aGlzLmN1cnJlbnRUZXh0dXJlICUgMl07XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIFJlbmRlcmVyLnByb3RvdHlwZS5jcmVhdGVUZXh0dXJlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBqc2Z4LndlYmdsLlRleHR1cmUodGhpcy5nbCwgdGhpcy5zb3VyY2Uud2lkdGgsIHRoaXMuc291cmNlLmhlaWdodCwgdGh
4244pcy5nbC5SR0JBLCB0aGlzLmdsLlVOU0lHTkVEX0JZVEUpO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBSZW5kZXJlci5wcm90b3R5cGUuZ2V0U2hhZGVyID0gZnVuY3Rpb24gKGZpbHRlcikge1xyXG4gICAgICAgICAgICAgICAgdmFyIGNhY2hlS2V5ID0gZmlsdGVyLmdldFZlcnRleFNvdXJjZSgpICsgZmlsdGVyLmdldEZyYWdtZW50U291cmNlKCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nbC5zaGFkZXJDYWNoZS5oYXNPd25Qcm9wZXJ0eShjYWNoZUtleSkgP1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZ2wuc2hhZGVyQ2FjaGVbY2FjaGVLZXldIDpcclxuICAgICAgICAgICAgICAgICAgICBuZXcganNmeC53ZWJnbC5TaGFkZXIodGhpcy5nbCwgZmlsdGVyLmdldFZlcnRleFNvdXJjZSgpLCBmaWx0ZXIuZ2V0RnJhZ21lbnRTb3VyY2UoKSk7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIFJlbmRlcmVyLnByb3RvdHlwZS5nZXREZWZhdWx0U2hhZGVyID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmdsLnNoYWRlckNhY2hlLmRlZikge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZ2wuc2hhZGVyQ2FjaGUuZGVmID0gbmV3IGpzZngud2ViZ2wuU2hhZGVyKHRoaXMuZ2wpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2wuc2hhZGVyQ2FjaGUuZGVmO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBSZW5kZXJlci5wcm90b3R5cGUuZ2V0RmxpcHBlZFNoYWRlciA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5nbC5zaGFkZXJDYWNoZS5mbGlwcGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5nbC5zaGFkZXJDYWNoZS5mbGlwcGVkID0gbmV3IGpzZngud2ViZ2wuU2hhZGVyKHRoaXMuZ2wsIG51bGwsIFwiXFxuICAgICAgICAgICAgICAgIHVuaWZvcm0gc2FtcGxlcjJEIHRleHR1cmU7XFxuICAgICAgICAgICAgICAgIHZhcnlpbmcgdmVjMiB0ZXhDb29yZDtcXG5cXG4gICAgICAgICAgICAgICAgdm9pZCBtYWluKCkge1xcbiAgICAgICAgICAgICAgICAgICAgZ2xfRnJhZ0NvbG9yID0gdGV4dHVyZTJEKHRleHR1cmUsIHZlYzIodGV4Q29vcmQueCwgMS4wIC0gdGV4Q29vcmQueSkpO1xcbiAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgXCIpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2wuc2hhZGVyQ2FjaGUuZmxpcHBlZDtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgUmVuZGVyZXIucHJvdG90eXBlLmluaXRpYWxpemUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNhbnZhcy53aWR0aCA9IHRoaXMuc291cmNlLndpZHRoO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jYW52YXMuaGVpZ2h0ID0gdGhpcy5zb3VyY2UuaGVpZ2h0O1xyXG4gICAgICAgICAgICAgICAgLy8gaW5pdGlhbGl6ZSB0aGUgdGV4dHVyZXNcclxuICAgICAgICAgICAgICAgIHZhciB0ZXh0dXJlcyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAyOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICB0ZXh0dXJlcy5wdXNoKHRoaXMuY3JlYXRlVGV4dHVyZSgpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHRoaXMudGV4dHVyZXMgPSB0ZXh0dXJlcztcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgUmVuZGVyZXIucHJvdG90eXBlLmNsZWFuVXAgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBkZXN0cm95IHNvdXJjZSB0ZXh0dXJlXHJcbiAgICAgICAgICAgICAgICB0aGlzLnNvdXJjZVRleHR1cmUuZGVzdHJveSgpO1xyXG4gICAgICAgICAgICAgICAgLy8gZGVzdHJveSB0ZXh0dXJlcyB1c2VkIGZvciBmaWx0ZXJzXHJcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDI7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudGV4dHVyZXNbaV0uZGVzdHJveSgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy8gcmUtc2V0IHRleHR1cmVzXHJcbiAgICAgICAgICAgICAgICB0aGlzLnRleHR1cmVzID0gbnVsbDtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgcmV0dXJuIFJlbmRlcmVyO1xyXG4gICAgICAgIH0pKCk7XHJcbiAgICAgICAgd2ViZ2wuUmVuZGVyZXIgPSBSZW5kZXJlcjtcclxuICAgIH0pKHdlYmdsID0ganNmeC53ZWJnbCB8fCAoanNmeC53ZWJnbCA9IHt9KSk7XHJcbn0pKGpzZnggfHwgKGpzZnggPSB7fSkpO1xyXG52YXIganNmeDtcclxuKGZ1bmN0aW9uIChqc2Z4KSB7XHJcbiAgICB2YXIgd2ViZ2w7XHJcbiAgICAoZnVuY3Rpb24gKHdlYmdsKSB7XHJcbiAgICAgICAgdmFyIFNoYWRlciA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIFNoYWRlcihnbCwgdmVydGV4U291cmNlLCBmcmFnbWVudFNvdXJjZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5nbCA9IGdsO1xyXG4gICAgICAgICAgICAgICAgLy8gZ2V0IHRoZSBzaGFkZXIgc291cmNlXHJcbiAgICAgICAgICAgICAgICB0aGlzLnZlcnRleFNvdXJjZSA9IHZlcnRleFNvdXJjZSB8fCBTaGFkZXIuZGVmYXVsdFZlcnRleFNvdXJjZTtcclxuICAgICAgICAgICAgICAgIHRoaXMuZnJhZ21lbnRTb3VyY2UgPSBmcmFnbWVudFNvdXJjZSB8fCBTaGFkZXIuZGVmYXVsdEZyYWdtZW50U291cmNlO1xyXG4gICAgICAgICAgICAgICAgLy8gc2V0IHByZWNpc2lvblxyXG4gICAgICAgICAgICAgICAgdGhpcy5mcmFnbWVudFNvdXJjZSA9IFwicHJlY2lzaW9uIGhpZ2hwIGZsb2F0O1wiICsgdGhpcy5mcmFnbWVudFNvdXJjZTtcclxuICAgICAgICAgICAgICAgIC8vIGluaXQgdmFyc1xyXG4gICAgICAgICAgICAgICAgdGhpcy52ZXJ0ZXhBdHRyaWJ1dGUgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgdGhpcy50ZXhDb29yZEF0dHJpYnV0ZSA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAvLyBjcmVhdGUgdGhlIHByb2dyYW1cclxuICAgICAgICAgICAgICAgI
4244HRoaXMucHJvZ3JhbSA9IGdsLmNyZWF0ZVByb2dyYW0oKTtcclxuICAgICAgICAgICAgICAgIC8vIGF0dGFjaCB0aGUgc2hhZGVyc1xyXG4gICAgICAgICAgICAgICAgZ2wuYXR0YWNoU2hhZGVyKHRoaXMucHJvZ3JhbSwgY29tcGlsZVNvdXJjZShnbCwgZ2wuVkVSVEVYX1NIQURFUiwgdGhpcy52ZXJ0ZXhTb3VyY2UpKTtcclxuICAgICAgICAgICAgICAgIGdsLmF0dGFjaFNoYWRlcih0aGlzLnByb2dyYW0sIGNvbXBpbGVTb3VyY2UoZ2wsIGdsLkZSQUdNRU5UX1NIQURFUiwgdGhpcy5mcmFnbWVudFNvdXJjZSkpO1xyXG4gICAgICAgICAgICAgICAgLy8gbGluayB0aGUgcHJvZ3JhbSBhbmQgZW5zdXJlIGl0IHdvcmtlZFxyXG4gICAgICAgICAgICAgICAgZ2wubGlua1Byb2dyYW0odGhpcy5wcm9ncmFtKTtcclxuICAgICAgICAgICAgICAgIGlmICghZ2wuZ2V0UHJvZ3JhbVBhcmFtZXRlcih0aGlzLnByb2dyYW0sIGdsLkxJTktfU1RBVFVTKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFwibGluayBlcnJvcjogXCIgKyBnbC5nZXRQcm9ncmFtSW5mb0xvZyh0aGlzLnByb2dyYW0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiB0ZXh0dXJlcyBhcmUgdW5pZm9ybXMgdG9vIGJ1dCBmb3Igc29tZSByZWFzb24gY2FuJ3QgYmUgc3BlY2lmaWVkIGJ5IHRoaXMuZ2wudW5pZm9ybTFmLFxyXG4gICAgICAgICAgICAgKiBldmVuIHRob3VnaCBmbG9hdGluZyBwb2ludCBudW1iZXJzIHJlcHJlc2VudCB0aGUgaW50ZWdlcnMgMCB0aHJvdWdoIDcgZXhhY3RseVxyXG4gICAgICAgICAgICAgKlxyXG4gICAgICAgICAgICAgKiBAcGFyYW0gdGV4dHVyZXNcclxuICAgICAgICAgICAgICogQHJldHVybnMge1NoYWRlcn1cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIFNoYWRlci5wcm90b3R5cGUudGV4dHVyZXMgPSBmdW5jdGlvbiAodGV4dHVyZXMpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZ2wudXNlUHJvZ3JhbSh0aGlzLnByb2dyYW0pO1xyXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgbmFtZSBpbiB0ZXh0dXJlcykge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghdGV4dHVyZXMuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZ2wudW5pZm9ybTFpKHRoaXMuZ2wuZ2V0VW5pZm9ybUxvY2F0aW9uKHRoaXMucHJvZ3JhbSwgbmFtZSksIHRleHR1cmVzW25hbWVdKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBTaGFkZXIucHJvdG90eXBlLnVuaWZvcm1zID0gZnVuY3Rpb24gKHVuaWZvcm1zKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmdsLnVzZVByb2dyYW0odGhpcy5wcm9ncmFtKTtcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIG5hbWUgaW4gdW5pZm9ybXMpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIXVuaWZvcm1zLmhhc093blByb3BlcnR5KG5hbWUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB2Y
4244XIgbG9jYXRpb24gPSB0aGlzLmdsLmdldFVuaWZvcm1Mb2NhdGlvbih0aGlzLnByb2dyYW0sIG5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChsb2NhdGlvbiA9PT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB3aWxsIGJlIG51bGwgaWYgdGhlIHVuaWZvcm0gaXNuJ3QgdXNlZCBpbiB0aGUgc2hhZGVyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB2YXIgdmFsdWUgPSB1bmlmb3Jtc1tuYW1lXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoICh2YWx1ZS5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmdsLnVuaWZvcm0xZnYobG9jYXRpb24sIG5ldyBGbG9hdDMyQXJyYXkodmFsdWUpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmdsLnVuaWZvcm0yZnYobG9jYXRpb24sIG5ldyBGbG9hdDMyQXJyYXkodmFsdWUpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMzpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmdsLnVuaWZvcm0zZnYobG9jYXRpb24sIG5ldyBGbG9hdDMyQXJyYXkodmFsdWUpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgNDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmdsLnVuaWZvcm00ZnYobG9jYXRpb24sIG5ldyBGbG9hdDMyQXJyYXkodmFsdWUpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgOTpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmdsLnVuaWZvcm1NYXRyaXgzZnYobG9jYXRpb24sIGZhbHNlLCBuZXcgRmxvYXQzMkFycmF5KHZhbHVlKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE2OlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZ2wudW5pZm9ybU1hdHJpeDRmdihsb2NhdGlvbiwgZmFsc2UsIG5ldyBGbG9hdDMyQXJyYXkodmFsdWUpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgXCJkb250J3Qga25vdyBob3cgdG8gbG9hZCB1bmlmb3JtIFxcXCJcIiArIG5hbWUgKyBcIlxcXCIgb2YgbGVuZ3RoIFwiICsgdmFsdWUubGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGlzTnVtYmVyKHZhbHVlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmdsLnVuaWZvcm0xZihsb2NhdGlvbiwgdmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgXCJhdHRlbXB0ZWQgdG8gc2V0IHVuaWZvcm0gXFxcIlwiICsgbmFtZSArIFwiXFxcIiB0byBpbnZhbGlkIHZhbHVlIFwiICsgKHZhbHVlIHx8IFwidW5kZWZpbmVkXCIpLnRvU3RyaW5nKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIFNoYWRlci5wcm90b3R5cGUuZHJhd1JlY3QgPSBmdW5jdGlvbiAobGVmdCwgdG9wLCByaWdodCwgYm90dG9tKSB7XHJcbiAgICAgICAgICAgICAgICB2Y
4244XIgdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgdmFyIHZpZXdwb3J0ID0gdGhpcy5nbC5nZXRQYXJhbWV0ZXIodGhpcy5nbC5WSUVXUE9SVCk7XHJcbiAgICAgICAgICAgICAgICB0b3AgPSB0b3AgIT09IHVuZGVmaW5lZCA/ICh0b3AgLSB2aWV3cG9ydFsxXSkgLyB2aWV3cG9ydFszXSA6IDA7XHJcbiAgICAgICAgICAgICAgICBsZWZ0ID0gbGVmdCAhPT0gdW5kZWZpbmVkID8gKGxlZnQgLSB2aWV3cG9ydFswXSkgLyB2aWV3cG9ydFsyXSA6IDA7XHJcbiAgICAgICAgICAgICAgICByaWdodCA9IHJpZ2h0ICE9PSB1bmRlZmluZWQgPyAocmlnaHQgLSB2aWV3cG9ydFswXSkgLyB2aWV3cG9ydFsyXSA6IDE7XHJcbiAgICAgICAgICAgICAgICBib3R0b20gPSBib3R0b20gIT09IHVuZGVmaW5lZCA/IChib3R0b20gLSB2aWV3cG9ydFsxXSkgLyB2aWV3cG9ydFszXSA6IDE7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuZ2wudmVydGV4QnVmZmVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5nbC52ZXJ0ZXhCdWZmZXIgPSB0aGlzLmdsLmNyZWF0ZUJ1ZmZlcigpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGhpcy5nbC5iaW5kQnVmZmVyKHRoaXMuZ2wuQVJSQVlfQlVGRkVSLCB0aGlzLmdsLnZlcnRleEJ1ZmZlcik7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmdsLmJ1ZmZlckRhdGEodGhpcy5nbC5BUlJBWV9CVUZGRVIsIG5ldyBGbG9hdDMyQXJyYXkoW2xlZnQsIHRvcCwgbGVmdCwgYm90dG9tLCByaWdodCwgdG9wLCByaWdodCwgYm90dG9tXSksIHRoaXMuZ2wuU1RBVElDX0RSQVcpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmdsLnRleENvb3JkQnVmZmVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5nbC50ZXhDb29yZEJ1ZmZlciA9IHRoaXMuZ2wuY3JlYXRlQnVmZmVyKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5nbC5iaW5kQnVmZmVyKHRoaXMuZ2wuQVJSQVlfQlVGRkVSLCB0aGlzLmdsLnRleENvb3JkQnVmZmVyKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmdsLmJ1ZmZlckRhdGEodGhpcy5nbC5BUlJBWV9CVUZGRVIsIG5ldyBGbG9hdDMyQXJyYXkoWzAsIDAsIDAsIDEsIDEsIDAsIDEsIDFdKSwgdGhpcy5nbC5TVEFUSUNfRFJBVyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy52ZXJ0ZXhBdHRyaWJ1dGUgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmVydGV4QXR0cmlidXRlID0gdGhpcy5nbC5nZXRBdHRyaWJMb2NhdGlvbih0aGlzLnByb2dyYW0sIFwidmVydGV4XCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZ2wuZW5hYmxlVmVydGV4QXR0cmliQXJyYXkodGhpcy52ZXJ0ZXhBdHRyaWJ1dGUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMudGV4Q29vcmRBdHRyaWJ1dGUgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudGV4Q29vcmRBdHRyaWJ1dGUgPSB0aGlzLmdsLmdldEF0dHJpYkxvY2F0aW9uKHRoaXMucHJvZ3JhbSwgXCJfdGV4Q29vcmRcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5nbC5lbmFibGVWZXJ0ZXhBdHRyaWJBcnJheSh0aGlzLnRleENvb3JkQXR0cmlidXRlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHRoaXMuZ2wudXNlUHJvZ3JhbSh0aGlzLnByb2dyYW0pO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5nbC5iaW5kQnVmZmVyKHRoaXMuZ2wuQVJSQVlfQlVGRkVSLCB0aGlzLmdsLnZlcnRleEJ1ZmZlcik7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmdsLnZlcnRleEF0dHJpYlBvaW50ZXIodGhpcy52ZXJ0ZXhBdHRyaWJ1dGUsIDIsIHRoaXMuZ2wuRkxPQVQsIGZhbHNlLCAwLCAwKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuZ2wuYmluZEJ1ZmZlcih0aGlzLmdsLkFSUkFZX0JVRkZFUiwgdGhpcy5nbC50ZXhDb29yZEJ1ZmZlcik7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmdsLnZlcnRleEF0dHJpYlBvaW50ZXIodGhpcy50ZXhDb29yZEF0dHJpYnV0ZSwgMiwgdGhpcy5nbC5GTE9BVCwgZmFsc2UsIDAsIDApO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5nbC5kcmF3QXJyYXlzKHRoaXMuZ2wuVFJJQU5HTEVfU1RSSVAsIDAsIDQpO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBTaGFkZXIucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmdsLmRlbGV0ZVByb2dyYW0odGhpcy5wcm9ncmFtKTtcclxuICAgICAgICAgICAgICAgIHRoaXMucHJvZ3JhbSA9IG51bGw7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIFNoYWRlci5kZWZhdWx0VmVydGV4U291cmNlID0gXCJcXG5hdHRyaWJ1dGUgdmVjMiB2ZXJ0ZXg7XFxuYXR0cmlidXRlIHZlYzIgX3RleENvb3JkO1xcbnZhcnlpbmcgdmVjMiB0ZXhDb29yZDtcXG5cXG52b2lkIG1haW4oKSB7XFxuICAgIHRleENvb3JkID0gX3RleENvb3JkO1xcbiAgICBnbF9Qb3NpdGlvbiA9IHZlYzQodmVydGV4ICogMi4wIC0gMS4wLCAwLjAsIDEuMCk7XFxufVwiO1xyXG4gICAgICAgICAgICBTaGFkZXIuZGVmYXVsdEZyYWdtZW50U291cmNlID0gXCJcXG51bmlmb3JtIHNhbXBsZXIyRCB0ZXh0dXJlO1xcbnZhcnlpbmcgdmVjMiB0ZXhDb29yZDtcXG5cXG52b2lkIG1haW4oKSB7XFxuICAgIGdsX0ZyYWdDb2xvciA9IHRleHR1cmUyRCh0ZXh0dXJlLCB0ZXhDb29yZCk7XFxufVwiO1xyXG4gICAgICAgICAgICByZXR1cm4gU2hhZGVyO1xyXG4gICAgICAgIH0pKCk7XHJcbiAgICAgICAgd2ViZ2wuU2hhZGVyID0gU2hhZGVyO1xyXG4gICAgICAgIGZ1bmN0aW9uIGNvbXBpbGVTb3VyY2UoZ2wsIHR5cGUsIHNvdXJjZSkge1xyXG4gICAgICAgICAgICB2Y
4244XIgc2hhZGVyID0gZ2wuY3JlYXRlU2hhZGVyKHR5cGUpO1xyXG4gICAgICAgICAgICBnbC5zaGFkZXJTb3VyY2Uoc2hhZGVyLCBzb3VyY2UpO1xyXG4gICAgICAgICAgICBnbC5jb21waWxlU2hhZGVyKHNoYWRlcik7XHJcbiAgICAgICAgICAgIGlmICghZ2wuZ2V0U2hhZGVyUGFyYW1ldGVyKHNoYWRlciwgZ2wuQ09NUElMRV9TVEFUVVMpKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBcImNvbXBpbGUgZXJyb3I6IFwiICsgZ2wuZ2V0U2hhZGVySW5mb0xvZyhzaGFkZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBzaGFkZXI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZ1bmN0aW9uIGlzQXJyYXkob2JqKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqKSA9PT0gXCJbb2JqZWN0IEFycmF5XVwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmdW5jdGlvbiBpc051bWJlcihvYmopIHtcclxuICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmopID09PSBcIltvYmplY3QgTnVtYmVyXVwiO1xyXG4gICAgICAgIH1cclxuICAgIH0pKHdlYmdsID0ganNmeC53ZWJnbCB8fCAoanNmeC53ZWJnbCA9IHt9KSk7XHJcbn0pKGpzZnggfHwgKGpzZnggPSB7fSkpO1xyXG52YXIganNmeDtcclxuKGZ1bmN0aW9uIChqc2Z4KSB7XHJcbiAgICB2YXIgd2ViZ2w7XHJcbiAgICAoZnVuY3Rpb24gKHdlYmdsKSB7XHJcbiAgICAgICAgdmFyIFRleHR1cmUgPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBmdW5jdGlvbiBUZXh0dXJlKGdsLCB3aWR0aCwgaGVpZ2h0LCBmb3JtYXQsIHR5cGUpIHtcclxuICAgICAgICAgICAgICAgIGlmIChmb3JtYXQgPT09IHZvaWQgMCkgeyBmb3JtYXQgPSBnbC5SR0JBOyB9XHJcbiAgICAgICAgICAgICAgICBpZiAodHlwZSA9PT0gdm9pZCAwKSB7IHR5cGUgPSBnbC5VTlNJR05FRF9CWVRFOyB9XHJcbiAgICAgICAgICAgICAgICB0aGlzLmdsID0gZ2w7XHJcbiAgICAgICAgICAgICAgICB0aGlzLndpZHRoID0gd2lkdGg7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmhlaWdodCA9IGhlaWdodDtcclxuICAgICAgICAgICAgICAgIHRoaXMuZm9ybWF0ID0gZm9ybWF0O1xyXG4gICAgICAgICAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcclxuICAgICAgICAgICAgICAgIHRoaXMuaWQgPSBnbC5jcmVhdGVUZXh0dXJlKCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnQgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV8yRCwgdGhpcy5pZCk7XHJcbiAgICAgICAgICAgICAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfTUFHX0ZJTFRFUiwgZ2wuTElORUFSKTtcclxuICAgICAgICAgICAgICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9NSU5fRklMVEVSLCBnbC5MSU5FQVIpO1xyXG4gICAgICAgICAgICAgICAgZ2wudGV4UGFyYW1ldGVyaShnbC5URVhUVVJFXzJELCBnbC5URVhUVVJFX1dSQVBfUywgZ2wuQ0xBTVBfVE9fRURHRSk7XHJcbiAgICAgICAgICAgICAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfV1JBUF9ULCBnbC5DTEFNUF9UT19FREdFKTtcclxuICAgICAgICAgICAgICAgIGlmICh3aWR0aCAmJi
4244BoZWlnaHQpIHtcclxuICAgICAgICAgICAgICAgICAgICBnbC50ZXhJbWFnZTJEKGdsLlRFWFRVUkVfMkQsIDAsIHRoaXMuZm9ybWF0LCB3aWR0aCwgaGVpZ2h0LCAwLCB0aGlzLmZvcm1hdCwgdGhpcy50eXBlLCBudWxsKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBUZXh0dXJlLnByb3RvdHlwZS5sb2FkQ29udGVudHNPZiA9IGZ1bmN0aW9uIChlbGVtZW50KSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnQgPSBlbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgdGhpcy53aWR0aCA9IGVsZW1lbnQud2lkdGg7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmhlaWdodCA9IGVsZW1lbnQuaGVpZ2h0O1xyXG4gICAgICAgICAgICAgICAgdGhpcy5nbC5iaW5kVGV4dHVyZSh0aGlzLmdsLlRFWFRVUkVfMkQsIHRoaXMuaWQpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5nbC50ZXhJbWFnZTJEKHRoaXMuZ2wuVEVYVFVSRV8yRCwgMCwgdGhpcy5mb3JtYXQsIHRoaXMuZm9ybWF0LCB0aGlzLnR5cGUsIGVsZW1lbnQpO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBUZXh0dXJlLnByb3RvdHlwZS5pbml0RnJvbUJ5dGVzID0gZnVuY3Rpb24gKHdpZHRoLCBoZWlnaHQsIGRhdGEpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMud2lkdGggPSB3aWR0aDtcclxuICAgICAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gaGVpZ2h0O1xyXG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtYXQgPSB0aGlzLmdsLlJHQkE7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnR5cGUgPSB0aGlzLmdsLlVOU0lHTkVEX0JZVEU7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmdsLmJpbmRUZXh0dXJlKHRoaXMuZ2wuVEVYVFVSRV8yRCwgdGhpcy5pZCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmdsLnRleEltYWdlMkQodGhpcy5nbC5URVhUVVJFXzJELCAwLCB0aGlzLmdsLlJHQkEsIHdpZHRoLCBoZWlnaHQsIDAsIHRoaXMuZ2wuUkdCQSwgdGhpcy50eXBlLCBuZXcgVWludDhBcnJheShkYXRhKSk7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIFRleHR1cmUucHJvdG90eXBlLnVzZSA9IGZ1bmN0aW9uICh1bml0KSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmdsLmFjdGl2ZVRleHR1cmUodGhpcy5nbC5URVhUVVJFMCArICh1bml0IHx8IDApKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuZ2wuYmluZFRleHR1cmUodGhpcy5nbC5URVhUVVJFXzJELCB0aGlzLmlkKTtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgVGV4dHVyZS5wcm90b3R5cGUudW51c2UgPSBmdW5jdGlvbiAodW5pdCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5nbC5hY3RpdmVUZXh0dXJlKHRoaXMuZ2wuVEVYVFVSRTAgKyAodW5pdCB8fCAwKSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmdsLmJpbmRUZXh0dXJlKHRoaXMuZ2wuVEVYVFVSRV8yRCwgbnVsbCk7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIFRleHR1cmUucHJvdG90eXBlLmRyYXdUbyA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xyXG4gICAgICAgICAgICAgICAgLy8gY3JlYXRlIGFuZCBiaW5kIGZyYW1lIGJ1ZmZlclxyXG4gICAgICAgICAgICAgICAgdGhpcy5nbC5mcmFtZUJ1ZmZlciA9IHRoaXMuZ2wuZnJhbWVCdWZmZXIgfHwgdGhpcy5nbC5jcmVhdGVGcmFtZWJ1ZmZlcigpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5nbC5iaW5kRnJhbWVidWZmZXIodGhpcy5nbC5GUkFNRUJVRkZFUiwgdGhpcy5nbC5mcmFtZUJ1ZmZlcik7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmdsLmZyYW1lYnVmZmVyVGV4dHVyZTJEKHRoaXMuZ2wuRlJBTUVCVUZGRVIsIHRoaXMuZ2wuQ09MT1JfQVRUQUNITUVOVDAsIHRoaXMuZ2wuVEVYVFVSRV8yRCwgdGhpcy5pZCwgMCk7XHJcbiAgICAgICAgICAgICAgICAvLyBlbnN1cmUgdGhlcmUgd2FzIG5vIGVycm9yXHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5nbC5jaGVja0ZyYW1lYnVmZmVyU3R
4244hdHVzKHRoaXMuZ2wuRlJBTUVCVUZGRVIpICE9PSB0aGlzLmdsLkZSQU1FQlVGRkVSX0NPTVBMRVRFKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiaW5jb21wbGV0ZSBmcmFtZWJ1ZmZlclwiKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vIHNldCB0aGUgdmlld3BvcnRcclxuICAgICAgICAgICAgICAgIHRoaXMuZ2wudmlld3BvcnQoMCwgMCwgdGhpcy53aWR0aCwgdGhpcy5oZWlnaHQpO1xyXG4gICAgICAgICAgICAgICAgLy8gZG8gdGhlIGRyYXdpbmdcclxuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCk7XHJcbiAgICAgICAgICAgICAgICAvLyBzdG9wIHJlbmRlcmluZyB0byB0aGlzIHRleHR1cmVcclxuICAgICAgICAgICAgICAgIHRoaXMuZ2wuYmluZEZyYW1lYnVmZmVyKHRoaXMuZ2wuRlJBTUVCVUZGRVIsIG51bGwpO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBUZXh0dXJlLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5nbC5kZWxldGVUZXh0dXJlKHRoaXMuaWQpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5pZCA9IG51bGw7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIFRleHR1cmUuZnJvbUVsZW1lbnQgPSBmdW5jdGlvbiAoZ2wsIGVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgIHZhciB0ZXh0dXJlID0gbmV3IFRleHR1cmUoZ2wsIDAsIDApO1xyXG4gICAgICAgICAgICAgICAgdGV4dHVyZS5sb2FkQ29udGVudHNPZihlbGVtZW50KTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0dXJlO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICByZXR1cm4gVGV4dHVyZTtcclxuICAgICAgICB9KSgpO1xyXG4gICAgICAgIHdlYmdsLlRleHR1cmUgPSBUZXh0dXJlO1xyXG4gICAgfSkod2ViZ2wgPSBqc2Z4LndlYmdsIHx8IChqc2Z4LndlYmdsID0ge30pKTtcclxufSkoanNmeCB8fCAoanNmeCA9IHt9KSk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGpzZng7XHJcbiIsInZhciBFbWl0dGVyID0gcmVxdWlyZSgnLi9lbWl0dGVyJyk7XG5cbmZ1bmN0aW9uIERyb3B6b25lKGVsKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdmFyIGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKTtcbiAgaW5wdXQuc2V0QXR0cmlidXRlKCd0eXBlJywgJ2ZpbGUnKTtcbiAgaW5wdXQuc2V0QXR0cmlidXRlKCdtdWx0aXBsZScsIHRydWUpO1xuICBpbnB1dC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICBpbnB1dC5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCBmdW5jdGlvbihlKSB7XG4gICAgc2VsZi5vbkZpbGVfKGUpO1xuICB9KTtcbiAgZWwuYXBwZW5kQ2hpbGQoaW5wdXQpO1xuXG4gIGVsLmFkZEV2ZW50TGlzdGVuZXIoJ2RyYWdvdmVyJywgZnVuY3Rpb24oZSkge1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGVsLmNsYXNzTGlzdC5hZGQoJ2RyYWdvdmVyJyk7XG4gIH0pO1xuXG4gIGVsLmFkZEV2ZW50TGlzdGVuZXIoJ2RyYWdsZWF2ZScsIGZ1bmN0aW9uKGUpIHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBlbC5jbGFzc0xpc3QucmVtb3ZlKCdkcmFnb3ZlcicpO1xuICB9KTtcblxuICBlbC5hZGRFdmVudExpc3RlbmVyKCdkcm9wJywgZnVuY3Rpb24oZSkge1xuICAgIGZpbGUgPSBzZWxmLmdldEZpbGVfKGUpO1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGVsLmNsYXNzTGlzdC5yZW1vdmUoJ2RyYWdvdmVyJyk7XG4gICAgaWYgKGZpbGUpIHtcbiAgICAgIHNlbGYub25GaWxlXyhlKTtcbiAgICB9XG4gIH0pO1xuXG4gIGVsLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG4gICAgLy8gVE9ETzogRmlndXJlIG91dCBhYm91dCByZS1lbmFibGluZyBjbGljayB0byB1cGxvYWQuXG4gICAgLy9pbnB1dC52YWx1ZSA9IG51bGw7XG4gICAgLy9pbnB1dC5jbGljaygpO1xuICB9KTtcbn1cblxuRHJvcHpvbmUucHJvdG90eXBlID0gbmV3IEVtaXR0ZXIoKTtcblxuRHJvcHpvbmUucHJvdG90eXBlLmdldEZpbGVfID0gZnVuY3Rpb24oZSkge1xuICB2YXIgZmlsZXM7XG4gIGlmIChlLmRhdGFUcmFuc2Zlcikge1xuICAgIGZpbGVzID0gZS5kYXRhVHJhbnNmZXIuZmlsZXM7XG4gIH0gZWxzZSBpZihlLnRhcmdldCkge1xuICAgIGZpbGVzID0gZS50YXJnZXQuZmlsZXM7XG4gIH1cblxuICBpZiAoZmlsZXMubGVuZ3RoID4gMSkge1xuICAgIHRoaXMuZW1pdCgnZXJyb3InLCAnTXVsdGlwbGUgZmlsZXMgZHJvcHBlZC4gUGxlYXNlIGNvbnZlcnQgb25lIGF0IGEgdGltZS4nKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfSBlbHNlIHtcbiAgICAvLyBKdXN0IHRha2UgdGhlIGZpcnN0IGZpbGUuXG4gICAgcmV0dXJuIGZpbGVzWzBdO1xuICB9XG59O1xuXG5Ecm9wem9uZS5wcm90b3R5cGUub25GaWxlXyA9IGZ1bmN0aW9uKGUpIHtcbiAgdmFyIGZpbGUgPSB0aGlzLmdldEZpbGVfKGUpO1xuICBpZiAoIWZpbGUubmFtZS5lbmRzV2l0aCgnanBnJykpIHtcbiAgICB0aGlzLmVtaXQoJ2Vycm9yJywgJ0Ryb3BwZWQgZmlsZSBtdXN0IGhhdmUgdGhlIC5qcGcgZXh0ZW5zaW9uJyk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5lbWl0KCdmaWxlJywgZmlsZSk7XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gRHJvcHpvbmU7XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMTUgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9y
4244IGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5cbmZ1bmN0aW9uIEVtaXR0ZXIoKSB7XG4gIHRoaXMuaW5pdEVtaXR0ZXIoKTtcbn1cblxuRW1pdHRlci5wcm90b3R5cGUuaW5pdEVtaXR0ZXIgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5jYWxsYmFja3MgPSB7fTtcbn07XG5cbkVtaXR0ZXIucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbihldmVudE5hbWUpIHtcbiAgdmFyIGNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzW2V2ZW50TmFtZV07XG4gIGlmICghY2FsbGJhY2tzKSB7XG4gICAgY29uc29sZS5sb2coJ05vIHZhbGlkIGNhbGxiYWNrIHNwZWNpZmllZC4nKTtcbiAgICByZXR1cm47XG4gIH1cbiAgdmFyIGFyZ3MgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cylcbiAgLy8gRWxpbWluYXRlIHRoZSBmaXJzdCBwYXJhbSAodGhlIGNhbGxiYWNrKS5cbiAgYXJncy5zaGlmdCgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGNhbGxiYWNrcy5sZW5ndGg7IGkrKykge1xuICAgIGNhbGxiYWNrc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgfVxufTtcblxuRW1pdHRlci5wcm90b3R5cGUub24gPSBmdW5jdGlvbihldmVudE5hbWUsIGNhbGxiYWNrKSB7XG4gIGlmIChldmVudE5hbWUgaW4gdGhpcy5jYWxsYmFja3MpIHtcbiAgICB2YXIgY2JzID0gdGhpcy5jYWxsYmFja3NbZXZlbnROYW1lXVxuICAgIGlmIChjYnMuaW5kZXhPZihjYWxsYmFjaykgPT0gLTEpIHtcbiAgICAgIGNicy5wdXNoKGNhbGxiYWNrKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5jYWxsYmFja3NbZXZlbnROYW1lXSA9IFtjYWxsYmFja107XG4gIH1cbn07XG5cbkVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID0gZnVuY3Rpb24oZXZlbnROYW1lLCBjYWxsYmFjaykge1xuICBpZiAoIShldmVudE5hbWUgaW4gdGhpcy5jYWxsYmFja3MpKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciBjYnMgPSB0aGlzLmNhbGxiYWNrc1tldmVudE5hbWVdO1xuICB2YXIgaW5kID0gY2JzLmluZGV4T2YoY2FsbGJhY2spO1xuICBpZiAoaW5kID09IC0xKSB7XG4gICAgY29uc29sZS53YXJuKCdObyBtYXRjaGluZyBjYWxsYmFjayBmb3VuZCcpO1xuICAgIHJldHVybjtcbiAgfVxuICBjYnMuc3BsaWNlKGluZCwgMSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEVtaXR0ZXI7XG4iLCJ2YXIgT2RzQ29udmVydGVyID0gcmVxdWlyZSgnLi9vZHMtY29udmVydGVyJyk7XG52YXIgRHJvcHpvbmUgPSByZXF1aXJlKCcuL2Ryb3B6b25lJyk7XG5cbnZhciBUQVJHRVRfU0laRSA9IDQwOTY7XG5cbnZhciBkeiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNkcm9wem9uZScpO1xudmFyIGRyb3B6b25lID0gbmV3IERyb3B6b25lKGR6KTtcbmRyb3B6b25lLm9uKCdmaWxlJywgb25GaWxlRHJvcHBlZCk7XG5kcm9wem9uZS5vbignZXJyb3InLCBvbkRyb3BFcnJvcik7XG5cbmNvbnZlcnRlciA9IG5ldyBPZHNDb252ZXJ0ZXIoKTtcbmNvbnZlcnRlci5vbignY29udmVydCcsIG9uT2RzQ29udmVydGVkKTtcbmNvbnZlcnRlci5vbignZXJyb3InLCBvbk9kc0NvbnZlcnNpb25FcnJvcik7XG5cbi8vIE1ha2UgYWxsIGRpYWxvZ3MgZGlzYXBwZWFyIGlmIGNsaWNrZWQgb3V0IG9mLlxuZHouYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbihlKSB7XG4gIGlmIChlLnRhcmdldC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09ICdkaWFsb2cnKSB7XG4gICAgaWYgKGRpYWxvZy5vcGVuKSB7XG4gICAgICBkaWFsb2cuY2xvc2UoKTtcbiAgICB9XG4gIH1cbn0pO1xuXG4vLyBIb29rIHVwIHRoZSBvcGVuIGZpbGUgbGluay5cbmRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNvcGVuZmlsZScpLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgb25PcGVuQ2xpY2tlZCk7XG5cbnZhciBmaWxlbmFtZTtcblxuZnVuY3Rpb24gb25GaWxlRHJvcHBlZChmaWxlKSB7XG4gIC8vIFNob3cgYSBuZXcgZGlhbG9nLlxuICBzaG93RGlhbG9nKCdwcm9ncmVzcycpO1xuXG4gIGNvbnNvbGUubG9nKCdvbkZpbGVEcm9wcGVkJywgZmlsZS5uYW1lKTtcbiAgZmlsZW5hbWUgPSBmaWxlLm5hbWU7XG5cbiAgdmFyIHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gIHJlYWRlci5vbmxvYWQgPSBmdW5jdGlvbihlKSB7XG4gICAgdmFyIGFycmF5QnVmZmVyID0gcmVhZGVyLnJlc3VsdDtcbiAgICAvLyBLaWNrIG9mZiB0aGUgY29udmVyc2lvbiBwcm9jZXNzLlxuICAgIGNvbnZlcnRlci5jb252ZXJ0KGFycmF5QnVmZmVyKTtcbiAgfVxuXG4gIHJlYWRlci5yZWFkQXNBcnJheUJ1ZmZlcihmaWxlKTtcbn1cblxuZnVuY3Rpb24gb25PZHNDb252ZXJ0ZWQoY2FudmFzLCBhdWRpbykge1xuICBjb25zb2xlLmxvZygnb25PZHNDb252ZXJ0ZWQsICVzIHggJXMnLCBjYW52YXMud2lkdGgsIGNhbnZhcy5oZWlnaHQpO1xuXG4gIGNhbnZhcy50b0Jsb2IoZnVuY3Rpb24oYmxvYikge1xuICAgIHZhciBkbEltYWdlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2RsLWltYWdlJyk7XG4gICAgZGxJbWFnZS5kaXNhYmxlZCA9IGZhbHNlO1xuICAgIGRsSW1hZ2UuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBvbkltYWdlQ2xpY2spO1xuICAgIGZ1bmN0aW9uIG9uSW1hZ2VDbGljaygpIHtcbiAgICAgIGNyZWF0ZUxpbmsoVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKSwgZ2V0Q29udmVydGVkRmlsZW5hbWUoZmlsZW5hbWUpKS5jbGljaygpO1xuICAgICAgZGxJbWFnZS5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIG9uSW1hZ2VDbGljayk7XG4gICAgfVxuXG4gICAgdmFyIGRsQXVkaW8gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjZGwtYXVkaW8nKTtcbiAgICBkbEF1ZGlvLmRpc2FibGVkID0gZmFsc2U7XG4gICAgZGxBdWRpby5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIG9uQXVkaW9DbGljayk7XG4gICAgZnVuY3Rpb24gb25BdWRpb0NsaWNrKCkge1xuICAgICAgY3JlYXRlTGluayhhdWRpbywgZ2V0Q29udmVydGVkRmlsZW5hbWUoZmlsZW5hbWUsICcubXA0JykpLmNsaWNrKCk7XG4gICAgICBkbEF1ZGlvLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgb25BdWRpb0NsaWNrKTtcbiAgICB9XG5cbiAgICBzaG93RGlhbG9nKCdzdWNjZXNzJyk7XG4gIH0sICdpbWFnZS9qcGVnJyk7XG5cbn1cblxuZnVuY3Rpb24gY3JlYXRlTGluayh1cmwsIGZpbGVuYW1lKSB7XG4gIHZhciBsaW5rID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpO1xuICBsaW5rLmRvd25sb2FkID0gZmlsZW5hbWU7XG4gIGxpbmsuaHJlZiA9IHVybDtcbiAgcmV0dXJuIGxpbms7XG59XG5cbmZ1bmN0aW9uIG9uT2RzQ29udmVyc2lvbkVycm9yKGVycm9yKSB7XG4gIGNvbnNvbGUubG9nKCdvbk9kc0NvbnZlcnNpb25FcnJvcicsIGVycm9yKTtcbiAgc2hvd0RpYWxvZygnZmFpbCcpXG4gIHNldEVycm9yTWVzc2FnZSgnQ29udmVyc2lvbiBlcnJvcjogJyArIGVycm9yKTtcbn1cblxuZnVuY3Rpb24gb25Ecm9wRXJyb3IoZXJyb3IpIHtcbiAgY29uc29sZS5sb2coJ29uRHJvcEVycm9yJywgZXJyb3IpO1xuICBzaG93RGlhbG9nKCdmYWlsJylcbiAgc2V0RXJyb3JNZXNzYWdlKCdEcm9wIGVycm9yOiAnICsgZXJyb3IpO1xufVxuXG5mdW5jdGlvbiBnZXRDb252ZXJ0ZWRGaWxlbmFtZShmaWxlbmFtZSwgb3B0X2V4dCkge1xuICB2YXIgZXh0SW5kZXggPSBmaWxlbmFtZS5sYXN0SW5kZXhPZignLicpO1xuICB2YXIgYmFzZW5hbWUgPSBmaWxlbmFtZS5zdWJzdHJpbmcoMCwgZXh0SW5kZXgpO1xuICB2YXIgZXh0ID0gb3B0X2V4dCB8fCBmaWxlbmFtZS5zdWJzdHJpbmcoZXh0SW5kZXgpO1xuICByZXR1cm4gYmFzZW5hbWUgKyAnLWNvbnZlcnRlZCcgKyBleHQ7XG59XG5cbmZ1bmN0aW9uIHNob3dEaWFsb2coaWQpIHtcbiAgLy8gQ2xvc2UgcHJldmlvdXNseSBvcGVuIGRpYWxvZyAoaWYgaXQgZXhpc3RzKS5cbiAgaWYgKHdpbmRvdy5kaWFsb2cgJiYgZGlhbG9nLm9wZW4pIHtcbiAgICBkaWFsb2cuY2xvc2UoKTtcbiAgfVxuICBkaWFsb2cgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjJyArIGlkKTtcbiAgZGlhbG9nLnNob3dNb2RhbCgpO1xufVxuXG5mdW5jdGlvbiBzZXRFcnJvck1lc3NhZ2UoZXJyb3JNZXNzYWdlKSB7XG4gIHZhciBlcnJvciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNlcnJvcicpO1xuICBlcnJvci5pbm5lckhUTUwgPSBlcnJvck1lc3NhZ2U7XG59XG5cbmZ1bmN0aW9uIG9uT3BlbkNsaWNrZWQoZSkge1xuICB2YXIgaW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbnB1dCcpO1xuICBpbnB1dC50eXBlID0gJ2ZpbGUnO1xuICBpbnB1dC5jbGljaygpO1xuICBpbnB1dC5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCBvbkZpbGVQaWNrZWQpO1xufVxuXG5mdW5jdGlvbiBvbkZpbGVQaWNrZWQoZSkge1xuICAvLyBUT0RPOiBWYWxpZGF0aW9uLlxuICB2YXIgZmlsZSA9IGUucGF0aFswXS5maWxlc1swXTtcbiAgb25GaWxlRHJvcHBlZChmaWxlKTtcbn07XG4iLCJ2YXIgRXZlbnRFbWl0dGVyMyA9IHJlcXVpcmUoJ2V2ZW50ZW1pdHRlcjMnKTtcbnZhciBqc2Z4ID0gcmVxdWlyZSgnanNmeCcpO1xuXG5cbnZhciBzdGFydFBhcnNpbmc7XG5cbnZhciB3aWR0aCA9IDY0MDtcblxudmFyIE1fU09JID0gMHhkODtcbnZhciBNX0FQUDEgPSAweGUxO1xudmFyIE1fU09TID0gMHhkYTtcblxudmFyIFhNUF9TSUdOQVRVUkUgPSAnaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyc7XG52YXIgRVhURU5TVElPTl9TSUdOQVRVUkUgPSAnaHR0cDovL25zLmFkb2JlLmNvbS94bXAvZXh0ZW5zaW9uLyc7XG52YXIgRVhUX1BSRUZJWF9MRU5HVEggPSA3MTtcblxuXG52YXIgVEFSR0VUX1NJWkUgPSA0MDk2O1xuXG5mdW5jdGlvbiBPZHNDb252ZXJ0ZXIoKSB7XG4gIHRoaXMubGFzdFdpZHRoID0gbnVsbDtcbn1cblxuT2RzQ29udmVydGVyLnByb3RvdHlwZSA9IG5ldyBFdmVudEVtaXR0ZXIzKCk7XG5cbk9kc0NvbnZlcnRlci5wcm90b3R5cGUuY29udmVydCA9IGZ1bmN0aW9uKGFycmF5QnVmZmVyKSB7XG4gIHRoaXMuZGVjb2RlXyhhcnJheUJ1ZmZlcik7XG59O1xuXG4vKipcbiAqIEdpdmVuIHRoZSBsYXN0IGNvbnZlcnRlZCBDYXJkYm9hcmQgQ2FtZXJhIGltYWdlLCB0aGlzIG1ldGhvZCByZXR1cm5zIHRoZVxuICogYmVzdCBwb3ctb2YtdHdvIHdpZHRoIGZvciB0aGUgaW1hZ2UuXG4gKi9cbk9kc0NvbnZlcnRlci5wcm90b3R5cGUuZ2V0T3B0aW
42441hbFdpZHRoID0gZnVuY3Rpb24oKSB7XG4gIGlmICghdGhpcy5sYXN0V2lkdGgpIHtcbiAgICByZXR1cm4gLTE7XG4gIH1cbiAgcmV0dXJuIE1hdGguY2VpbChNYXRoLmxvZyh0aGlzLmxhc3RXaWR0aCkvTWF0aC5sb2coMikpXG59O1xuXG5PZHNDb252ZXJ0ZXIucHJvdG90eXBlLmRlY29kZV8gPSBmdW5jdGlvbihhcnJheUJ1ZmZlcikge1xuICB2YXIgc2NvcGUgPSB0aGlzO1xuXG4gIGlmICghYXJyYXlCdWZmZXIpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgc3RhcnRQYXJzaW5nID0gRGF0ZS5ub3coKTtcbiAgY29uc29sZS5sb2coJ1N0YXJ0ZWQgcGFyc2luZycpO1xuICB2YXIgYnl0ZXMgPSBuZXcgVWludDhBcnJheShhcnJheUJ1ZmZlcik7XG4gIHZhciBkb2MgPSBleHRyYWN0WE1QKGJ5dGVzLCBmdW5jdGlvbihlKSB7XG4gICAgc2NvcGUuZW1pdCgnZXJyb3InLCBlKTtcbiAgfSk7XG4gIGlmICghZG9jKSB7XG4gICAgLy8gTm8gdmFsaWQgZG9jLCBzbyB3ZSBxdWl0LlxuICAgIHJldHVybjtcbiAgfVxuICB2YXIgZ1Bhbm8gPSBnZXRPYmplY3RNZXRhKGRvYywgJ0dQYW5vJyk7XG4gIHZhciBnSW1hZ2UgPSBnZXRPYmplY3RNZXRhKGRvYywgJ0dJbWFnZScpO1xuICB2YXIgZ0F1ZGlvID0gZ2V0T2JqZWN0TWV0YShkb2MsICdHQXVkaW8nKTtcbiAgdmFyIGltYWdlID0gbWFrZUltYWdlRnJvbUJpbmFyeSgnaW1hZ2UvanBlZycsIGJ5dGVzKTtcbiAgdmFyIGF1ZGlvID0gbWFrZUF1ZGlvKGdBdWRpby5NaW1lLCBnQXVkaW8uRGF0YSk7XG5cbiAgaW1hZ2Uub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuc2V0dXBTY2VuZV8oZ1Bhbm8sIGdJbWFnZSwgaW1hZ2UsIGF1ZGlvKTtcbiAgfS5iaW5kKHRoaXMpO1xuXG59XG5cbk9kc0NvbnZlcnRlci5wcm90b3R5cGUuc2V0dXBTY2VuZV8gPSBmdW5jdGlvbihnUGFubywgZ0ltYWdlLCBsZWZ0SW1hZ2UsIGF1ZGlvKSB7XG4gIC8vIEVuc3VyZSB0aGUgcmlnaHQgaW1hZ2UgaXMgdmFsaWQuXG4gIGlmICghZ0ltYWdlLk1pbWUgfHwgIWdJbWFnZS5EYXRhKSB7XG4gICAgdGhpcy5lbWl0KCdlcnJvcicsICdObyB2YWxpZCByaWdodCBleWUgaW1hZ2UgZm91bmQgaW4gdGhlIFhNUCBtZXRhZGF0YS4gVGhpcyBtaWdodCBub3QgYmUgYSB2YWxpZCBDYXJkYm9hcmQgQ2FtZXJhIGltYWdlLicpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciByaWdodEltYWdlID0gbWFrZUltYWdlKGdJbWFnZS5NaW1lLCBnSW1hZ2UuRGF0YSk7XG4gIHJpZ2h0SW1hZ2Uub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgIGNvbnNvbGUubG9nKCdQYXJzaW5nIHRvb2sgJyArIChEYXRlLm5vdygpIC0gc3RhcnRQYXJzaW5nKSArICcgbXMnKTtcbiAgICB0aGlzLmJ1aWxkSW1hZ2VfKGxlZnRJbWFnZSwgcmlnaHRJbWFnZSwgZ1Bhbm8sIGF1ZGlvKTtcbiAgfS5iaW5kKHRoaXMpO1xufVxuXG5PZHNDb252ZXJ0ZXIucHJvdG90eXBlLmJ1aWxkSW1hZ2VfID0gZnVuY3Rpb24obGVmdEltYWdlLCByaWdodEltYWdlLCBnUGFubywgYXVkaW8pIHtcbiAgdmFyIGZ1bGxXaWR0aCA9IHBhcnNlSW50KGdQYW5vWydGdWxsUGFub1dpZHRoUGl4ZWxzJ10pO1xuICB2YXIgY3JvcExlZnQgPSBwYXJzZUludChnUGFub1snQ3JvcHBlZEFyZWFMZWZ0UGl4ZWxzJ10pO1xuICB2YXIgY3JvcFRvcCA9IHBhcnNlSW50KGdQYW5vWydDcm9wcGVkQXJlYVRvcFBpeGVscyddKTtcbiAgdmFyIGNyb3BXaWR0aCA9IHBhcnNlSW50KGdQYW5vWydDcm9wcGVkQXJlYUltYWdlV2lkdGhQaXhlbHMnXSk7XG4gIHZhciBpbml0aWFsSGVhZGluZ0RlZyA9IHBhcnNlSW50KGdQYW5vWydJbml0aWFsVmlld0hlYWRpbmdEZWdyZWVzJ10pO1xuXG4gIHZhciByYXRpbyA9IFRBUkdFVF9TSVpFIC8gZnVsbFdpZHRoO1xuXG4gIC8vIEhhbmRsZSBwYXJ0aWFsIHBhbm9zLlxuICB2YXIgc2NhbGVXaWR0aCA9IDE7XG4gIGlmIChjcm9wV2lkdGggIT0gZnVsbFdpZHRoKSB7XG4gICAgc2NhbGVXaWR0aCA9IGNyb3BXaWR0aCAvIGZ1bGxXaWR0aDtcbiAgfVxuXG4gIC8vIEEgY2FudmFzIGZvciB0aGUgb3Zlci11bmRlciByZW5kZXJpbmcuXG4gIHZhciBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgY2FudmFzLndpZHRoID0gVEFSR0VUX1NJWkU7XG4gIGNhbnZhcy5oZWlnaHQgPSBUQVJHRVRfU0laRTtcblxuICAvLyBTY2FsZWQgZGltZW5zaW9ucyBmb3IgbGVmdCBhbmQgcmlnaHQgZXllIGltYWdlcy5cbiAgdmFyIGltYWdlV2lkdGggPSBUQVJHRVRfU0laRSAqIHNjYWxlV2lkdGg7XG4gIHZhciBpbWFnZUhlaWdodCA9IGxlZnRJbWFnZS5oZWlnaHQgKiByYXRpbztcblxuICAvLyBTYXZlIHRoZSBvcmlnaW5hbCBzaXplIG9mIHRoZSBtb3N0IHJlY2VudGx5IGNvbnZlcnRlZCBpbWFnZS5cbiAgdGhpcy5sYXN0V2lkdGggPSBjYW52YXMud2lkdGg7XG5cbiAgLy8gT2Zmc2V0cyBmb3Igd2hlcmUgdG8gcmVuZGVyIGVhY2ggaW1hZ2UuIEZvciBwYXJ0aWFsIHBhbm9zIChpZS4gaW1hZ2VXaWR0aCA8XG4gIC8vIFRBUkdFVF9TSVpFKSwgcmVuZGVyIHRoZSBpbWFnZSBjZW50ZXJlZC5cbiAgdmFyIG9mZnNldFggPSAoVEFSR0VUX1NJWkUgLSBpbWFnZVdpZHRoKSAvIDI7XG4gIHZhciB4ID0gTWF0aC5mbG9vcihjcm9wTGVmdCAqIHJhdGlvKSArIG9mZnNldFg7XG4gIHZhciB5ID0gTWF0aC5mbG9vcihjcm9wVG9wICogcmF0aW8pO1xuICB2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG5cbiAgLy8gQ2xlYXIgdGhlIGNhbnZhcy5cbiAgY3R4LmZpbGxTdHlsZSA9ICcjMDAwJztcbiAgY3R4LmZpbGxSZWN0KDAsIDAsIGNhbnZhcy53aWR0aCwgY2FudmFzLmhlaWdodCk7XG5cbiAgLy8gRHJhdyB0aGUgbGVmdCBhbmQgcmlnaHQgaW1hZ2VzIG9udG8gdGhlIGNhbnZhcy5cbiAgY3R4LmRyYXdJbWFnZShsZWZ0SW1hZ2UsIHgsIHksIGltYWdlV2lkdGgsIGltYWdlSGVpZ2h0KTtcbiAgY3R4LmRyYXdJbWFnZShyaWdodEltYWdlLCB4LCB5ICsgY2FudmFzLmhlaWdodC8yLCBpbWFnZVdpZHRoLCBpbWFnZUhlaWdodCk7XG5cbiAgdmFyIGhhbGZIZWlnaHQgPSBNYXRoLmZsb29yKGNhbnZhcy5oZWlnaHQgLyAyKTtcbiAgLy8gT2Zmc2V0cyBhcmUgdGhlIG9mZnNldHMgZm9yIGVhY2ggZXllLlxuICB2YXIgb2Zmc2V0cyA9IFswLCBoYWxmSGVpZ2h0XTtcblxuICAvLyBDYWxjdWxhdGUgaG93IG11Y2ggdG8gYmx1ciB0aGUgaW1hZ2UuXG4gIHZhciBibHVyUmFkaXVzID0gaW1hZ2VIZWlnaHQgLyAyO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgb2Zmc2V0cy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBvZmZzZXQgPSBvZmZzZXRzW2ldO1xuXG4gICAgLy8gQ2FsY3VsYXRlIHRoZSBkaW1lbnNpb25zIG9mIHRoZSBhY3R1YWwgaW1hZ2UuXG4gICAgdmFyIHRvcCA9IG9mZnNldCArIHk7XG4gICAgdmFyIGJvdHRvbSA9IG9mZnNldCArIHkgKyBpbWFnZUhlaWdodCAtIDE7XG5cbiAgICAvLyBSZXBlYXQgdGhlIHRvcCBwYXJ0LlxuICAgIHJlcGVhdEltYWdlKGNhbnZhcywgdG9wLCBvZmZzZXQpO1xuXG4gICAgLy8gUmVwZWF0IHR
4244oZSBib3R0b20gcGFydC5cbiAgICByZXBlYXRJbWFnZShjYW52YXMsIGJvdHRvbSwgb2Zmc2V0ICsgaGFsZkhlaWdodCk7XG4gIH1cbiAgdmFyIGJsdXJDYW52YXMgPSBibHVySW1hZ2UoY2FudmFzLCBibHVyUmFkaXVzKTtcblxuICAvLyBDb3B5IHRoZSBibHVycmVkIGNhbnZhcyBvbnRvIHRoZSByZWd1bGFyIG9uZS5cbiAgY3R4LmRyYXdJbWFnZShibHVyQ2FudmFzLCAwLCAwKTtcblxuICAvLyBSZS1yZW5kZXIgdGhlIGltYWdlcyB0aGVtc2VsdmVzLlxuICBjdHguZHJhd0ltYWdlKGxlZnRJbWFnZSwgeCwgeSwgaW1hZ2VXaWR0aCwgaW1hZ2VIZWlnaHQpO1xuICBjdHguZHJhd0ltYWdlKHJpZ2h0SW1hZ2UsIHgsIHkgKyBjYW52YXMuaGVpZ2h0LzIsIGltYWdlV2lkdGgsIGltYWdlSGVpZ2h0KTtcblxuICB0aGlzLmVtaXQoJ2NvbnZlcnQnLCBjYW52YXMsIGF1ZGlvKTtcbn1cblxuZnVuY3Rpb24gcmVwZWF0SW1hZ2UoY2FudmFzLCBzdGFydFksIGVuZFkpIHtcbiAgdmFyIGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuXG4gIHZhciB5ID0gTWF0aC5taW4oc3RhcnRZLCBlbmRZKTtcbiAgdmFyIGhlaWdodCA9IE1hdGguYWJzKHN0YXJ0WSAtIGVuZFkpO1xuXG4gIC8vIFJlcGVhdCB0aGUgc3RhcnQgbGluZSB0aHJvdWdoIHRoZSB3aG9sZSByYW5nZS5cbiAgY3R4LmRyYXdJbWFnZShjYW52YXMsIDAsIHN0YXJ0WSwgY2FudmFzLndpZHRoLCAxLFxuICAgICAgICAgICAgICAgICAgICAgICAgMCwgeSwgY2FudmFzLndpZHRoLCBoZWlnaHQpO1xuXG59XG5cbmZ1bmN0aW9uIGJsdXJJbWFnZShjYW52YXMsIHJhZGl1cykge1xuICB2YXIgc291cmNlID0gbmV3IGpzZnguU291cmNlKGNhbnZhcyk7XG5cbiAgLy92YXIgYmx1ckZpbHRlciA9IG5ldyBqc2Z4LmZpbHRlci5CcmlnaHRuZXNzKDAuNSk7XG4gIHZhciBibHVyRmlsdGVyID0gbmV3IGpzZnguZmlsdGVyLkJsdXIocmFkaXVzKTtcblxuICB2YXIgcmVuZGVyZXIgPSBuZXcganNmeC5SZW5kZXJlcigpO1xuICByZW5kZXJlci5zZXRTb3VyY2Uoc291cmNlKVxuICAgICAgLmFwcGx5RmlsdGVycyhbYmx1ckZpbHRlcl0pXG4gICAgICAucmVuZGVyKCk7XG5cbiAgcmV0dXJuIHJlbmRlcmVyLmdldENhbnZhcygpO1xufVxuXG5mdW5jdGlvbiBtYWtlSW1hZ2UobWltZSwgZGF0YSkge1xuICB2YXIgaW1nID0gbmV3IEltYWdlKCk7XG4gIGltZy5zcmMgPSAnZGF0YTonICsgbWltZSArICc7YmFzZTY0LCcgKyBkYXRhO1xuICByZXR1cm4gaW1nO1xufVxuXG5mdW5jdGlvbiBtYWtlSW1hZ2VGcm9tQmluYXJ5KG1pbWUsIGJ5dGVzKSB7XG4gIHZhciBibG9iID0gbmV3IEJsb2IoW2J5dGVzXSwge3R5cGU6IG1pbWV9KTtcbiAgdmFyIHVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gIHZhciBpbWcgPSBuZXcgSW1hZ2UoKTtcbiAgaW1nLnNyYyA9IHVybDtcbiAgcmV0dXJuIGltZztcbn1cblxuZnVuY3Rpb24gbWFrZUF1ZGlvKG1pbWUsIGRhdGEpIHtcbiAgcmV0dXJuICdkYXRhOicgKyBtaW1lICsgJztiYXNlNjQsJyArIGRhdGE7XG59XG5cbmZ1bmN0aW9uIGJ5dGVUb1N0cmluZyhieXRlcywgc3RhcnQsIGVuZCkge1xuICB2YXIgcyA9ICcnO1xuICBzdGFydCA9IHN0YXJ0IHx8IDA7XG4gIGVuZCA9IGVuZCB8fCBieXRlcy5sZW5ndGg7XG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgaWYgKGJ5dGVzW2ldKSB7XG4gICAgICB2Y
4244XIgYyA9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZXNbaV0pO1xuICAgICAgcyArPSBjO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcztcbn1cblxuZnVuY3Rpb24gZ2V0T2JqZWN0TWV0YSAoZG9jLCB0YWcpIHtcbiAgdmFyIG1ldGEgPSB7fTtcbiAgdmFyIGRlc2NyaXB0aW9ucyA9IGRvYy5xdWVyeVNlbGVjdG9yQWxsKCdEZXNjcmlwdGlvbicpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGRlc2NyaXB0aW9ucy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBub2RlID0gZGVzY3JpcHRpb25zW2ldO1xuICAgIGZvciAodmFyIGogaW4gbm9kZS5hdHRyaWJ1dGVzKSB7XG4gICAgICB2YXIgYXR0ciA9IG5vZGUuYXR0cmlidXRlc1tqXTtcbiAgICAgIGlmIChhdHRyLnByZWZpeCA9PSB0YWcpIHtcbiAgICAgICAgbWV0YVthdHRyLmxvY2FsTmFtZV0gPSBhdHRyLnZhbHVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gbWV0YTtcbn1cblxuZnVuY3Rpb24gZXh0cmFjdFhNUChieXRlcywgZXJyb3JDYWxsYmFjaykge1xuICB2YXIgc2VjdGlvbnMgPSBwYXJzZUpwZWcoYnl0ZXMsIHRydWUpO1xuICBpZiAoc2VjdGlvbnMgPT09IG51bGwpIHtcbiAgICBlcnJvckNhbGxiYWNrKCdObyBYTVAgbWV0YWRhdGEgZm91bmQgaW4gc3BlY2lmaWVkIGltYWdlIGZpbGUuIFRoaXMgbWlnaHQgbm90IGJlIGEgdmFsaWQgQ2FyZGJvYXJkIENhbWVyYSBpbWFnZS4nKTtcbiAgICByZXR1cm47XG4gIH1cbiAgdmFyIHhtbCA9ICcnO1xuICB2YXIgdmlzaXRlZEV4dGVuZGVkID0gZmFsc2U7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc2VjdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgaXNYbXAgPSB0cnVlO1xuICAgIHZhciBpc0V4dCA9IHRydWU7XG4gICAgdmFyIHNlY3Rpb24gPSBzZWN0aW9uc1tpXTtcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IHNlY3Rpb24uZGF0YS5sZW5ndGg7IGorKykge1xuICAgICAgdmFyIGEgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHNlY3Rpb24uZGF0YVtqXSk7XG4gICAgICBpZiAoaXNYbXAgJiYgYSAhPSBYTVBfU0lHTkFUVVJFW2pdKSB7XG4gICAgICAgIGlzWG1wID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAoaXNFeHQgJiYgYSAhPSBFWFRFTlNUSU9OX1NJR05BVFVSRVtqXSkge1xuICAgICAgICBpc0V4dCA9IGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKCFpc0V4dCB8fCAhaXNYbXApIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGlzWG1wKSB7XG4gICAgICB2Y
4244XIgc3RyID0gYnl0ZVRvU3RyaW5nKHNlY3Rpb24uZGF0YSk7XG4gICAgICB2YXIgcmUgPSBuZXcgUmVnRXhwKCc8eDp4bXBtZXRhKFtcXFxcc1xcXFxTXSopPC94OnhtcG1ldGE+Jyk7XG4gICAgICB4bWwgPSBzdHIubWF0Y2gocmUpWzBdO1xuICAgIH1cbiAgICBlbHNlIGlmIChpc0V4dCkge1xuICAgICAgdmFyIGxlbiA9IEVYVF9QUkVGSVhfTEVOR1RIO1xuICAgICAgaWYgKHZpc2l0ZWRFeHRlbmRlZCkge1xuICAgICAgICBsZW4gKz00O1xuICAgICAgfVxuICAgICAgdmlzaXRlZEV4dGVuZGVkID0gdHJ1ZTtcbiAgICAgIHhtbCArPSBieXRlVG9TdHJpbmcoc2VjdGlvbi5kYXRhLCBsZW4pO1xuICAgIH1cbiAgfVxuICB2YXIgcGFyc2VyID0gbmV3IERPTVBhcnNlcigpO1xuICB2YXIgZG9jID0gcGFyc2VyLnBhcnNlRnJvbVN0cmluZygnPHhtbD4nICsgeG1sICsgJzwveG1sPicsICd0ZXh0L3htbCcpO1xuICByZXR1cm4gZG9jO1xufVxuXG5mdW5jdGlvbiBiaW5hcnlUb0Jhc2U2NCAoYnl0ZXMpIHtcbiAgdmFyIGI2NCA9IFtdO1xuICB2YXIgcGFnZVNpemUgPSAxMDAwMDA7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpICs9IHBhZ2VTaXplKSB7XG4gICAgYjY0LnB1c2goYnRvYShTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzLnN1YmFycmF5KGksIGkgKyBwYWdlU2l6ZSkpKSk7XG4gIH1cbiAgcmV0dXJuIGI2NC5qb2luKCcnKTtcbn1cblxuZnVuY3Rpb24gcGFyc2VKcGVnIChieXRlcywgcmVhZE1ldGFPbmx5KSB7XG4gIHZhciBjO1xuICB2YXIgaSA9IDA7XG4gIHZhciByZWFkID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGkgPCBieXRlcy5sZW5ndGggPyBieXRlc1tpKytdIDogLTE7XG4gIH07XG5cbiAgaWYgKHJlYWQoKSAhPSAweGZmIHx8IHJlYWQoKSAhPSBNX1NPSSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHZhciBzZWN0aW9ucyA9IFtdO1xuICB3aGlsZSgoYyA9IHJlYWQoKSkgIT0gLTEpIHtcbiAgICBpZiAoYyAhPSAweGZmKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgd2hpbGUoKGMgPSByZWFkKCkpID09IDB4ZmYpIHtcbiAgICB9XG5cbiAgICBpZiAoYyA9PSAtMSkge1xuICAgICAgcmV0dXJuIG51bGxcbiAgICB9XG4gICAgdmFyIG1hcmtlciA9IGM7XG4gICAgaWYgKG1hcmtlciA9PSBNX1NPUykge1xuICAgICAgLy8gTV9TT1MgaW5kaWNhdGVzIHRoYXQgaW1hZ2UgZGF0YSB3aWxsIGZvbGxvdyBhbmQgbm8gbWV0YWRhdGEgYWZ0ZXJcbiAgICAgIC8vIHRoYXQgc28gcmVhZCBhbGwgZGF0YSBhdCBvbmUgdGltZS5cbiAgICAgIGlmICghcmVhZE1ldGFPbmx5KSB7XG4gICAgICAgIHZhciBzZWN0aW9uID0ge1xuICAgICAgICAgIG1hcmtlcjogbWFya2VyLFxuICAgICAgICAgIGxlbmd0aDogLTEsXG4gICAgICAgICAgZGF0YTogYnl0ZXMuc3ViYXJyYXkoaSlcbiAgICAgICAgfTtcbiAgICAgICAgc2VjdGlvbnMucHVzaChzZWN0aW9uKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBzZWN0aW9ucztcbiAgICB9XG4gICAgdmFyIGxoID0gcmVhZCgpO1xuICAgIHZhciBsbCA9IHJlYWQoKTtcbiAgICBpZiAobGggPT0gLTEgfHwgbGwgPT0gLTEpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICB2YXIgbGVuZ3RoID0gbGggPDwgOCB8IGxsO1xuICAgIGlmICghcmVhZE1ldGFPbmx5IHx8IGMgPT0gTV9BUFAxKSB7XG4gICAgICB2Y
4244XIgc2VjdGlvbiA9IHtcbiAgICAgICAgbWFya2VyOiBtYXJrZXIsXG4gICAgICAgIGxlbmd0aDogbGVuZ3RoLFxuICAgICAgICBkYXRhOiBieXRlcy5zdWJhcnJheShpLCBpICsgbGVuZ3RoIC0gMilcbiAgICAgIH07XG4gICAgICBzZWN0aW9ucy5wdXNoKHNlY3Rpb24pO1xuICAgIH1cbiAgICAvLyBNb3ZlIGkgdG8gZW5kIG9mIHNlY3Rpb24uXG4gICAgaSArPSBsZW5ndGggLSAyO1xuICB9XG4gIHJldHVybiBzZWN0aW9ucztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBPZHNDb252ZXJ0ZXI7XG4iLCIndXNlIHN0cmljdCdcblxuZXhwb3J0cy50b0J5dGVBcnJheSA9IHRvQnl0ZUFycmF5XG5leHBvcnRzLmZyb21CeXRlQXJyYXkgPSBmcm9tQnl0ZUFycmF5XG5cbnZhciBsb29rdXAgPSBbXVxudmFyIHJldkxvb2t1cCA9IFtdXG52YXIgQXJyID0gdHlwZW9mIFVpbnQ4QXJyYXkgIT09ICd1bmRlZmluZWQnID8gVWludDhBcnJheSA6IEFycmF5XG5cbmZ1bmN0aW9uIGluaXQgKCkge1xuICB2YXIgY29kZSA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvJ1xuICBmb3IgKHZhciBpID0gMCwgbGVuID0gY29kZS5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgIGxvb2t1cFtpXSA9IGNvZGVbaV1cbiAgICByZXZMb29rdXBbY29kZS5jaGFyQ29kZUF0KGkpXSA9IGlcbiAgfVxuXG4gIHJldkxvb2t1cFsnLScuY2hhckNvZGVBdCgwKV0gPSA2MlxuICByZXZMb29rdXBbJ18nLmNoYXJDb2RlQXQoMCldID0gNjNcbn1cblxuaW5pdCgpXG5cbmZ1bmN0aW9uIHRvQnl0ZUFycmF5IChiNjQpIHtcbiAgdmFyIGksIGosIGwsIHRtcCwgcGxhY2VIb2xkZXJzLCBhcnJcbiAgdmFyIGxlbiA9IGI2NC5sZW5ndGhcblxuICBpZiAobGVuICUgNCA+IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc3RyaW5nLiBMZW5ndGggbXVzdCBiZSBhIG11bHRpcGxlIG9mIDQnKVxuICB9XG5cbiAgLy8gdGhlIG51bWJlciBvZiBlcXVhbCBzaWducyAocGxhY2UgaG9sZGVycylcbiAgLy8gaWYgdGhlcmUgYXJlIHR3byBwbGFjZWhvbGRlcnMsIHRoYW4gdGhlIHR3byBjaGFyYWN0ZXJzIGJlZm9yZSBpdFxuICAvLyByZXByZXNlbnQgb25lIGJ5dGVcbiAgLy8gaWYgdGhlcmUgaXMgb25seSBvbmUsIHRoZW4gdGhlIHRocmVlIGNoYXJhY3RlcnMgYmVmb3JlIGl0IHJlcHJlc2VudCAyIGJ5dGVzXG4gIC8vIHRoaXMgaXMganVzdCBhIGNoZWFwIGhhY2sgdG8gbm90IGRvIGluZGV4T2YgdHdpY2VcbiAgcGxhY2VIb2xkZXJzID0gYjY0W2xlbiAtIDJdID09PSAnPScgPyAyIDogYjY0W2xlbiAtIDFdID09PSAnPScgPyAxIDogMFxuXG4gIC8vIGJhc2U2NCBpcyA0LzMgKyB1cCB0byB0d28gY2hhcmFjdGVycyBvZiB0aGUgb3JpZ2luYWwgZGF0YVxuICBhcnIgPSBuZXcgQXJyKGxlbiAqIDMgLyA0IC0gcGxhY2VIb2xkZXJzKVxuXG4gIC8vIGlmIHRoZXJlIGFyZSBwbGFjZWhvbGRlcnMsIG9ubHkgZ2V0IHVwIHRvIHRoZSBsYXN0IGNvbXBsZXRlIDQgY2hhcnNcbiAgbCA9IHBsYWNlSG9sZGVycyA+IDAgPyBsZW4gLSA0IDogbGVuXG5cbiAgdmFyIEwgPSAwXG5cbiAgZm9yIChpID0gMCwgaiA9IDA7IGkgPCBsOyBpICs9IDQsIGogKz0gMykge1xuICAgIHRtcCA9IChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldIDw8IDE4KSB8IChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA8PCAxMikgfCAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAyKV0gPDwgNikgfCByZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDMpXVxuICAgIGFycltMKytdID0gKHRtcCA+PiAxNikgJiAweEZGXG4gICAgYXJyW0wrK10gPSAodG1wID4+IDgpICYgMHhGRlxuICAgIGFycltMKytdID0gdG1wICYgMHhGRlxuICB9XG5cbiAgaWYgKHBsYWNlSG9sZGVycyA9PT0gMikge1xuICAgIHRtcCA9IChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldIDw8IDIpIHwgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMSldID4+IDQpXG4gICAgYXJyW0wrK10gPSB0bXAgJiAweEZGXG4gIH0gZWxzZSBpZiAocGxhY2VIb2xkZXJzID09PSAxKSB7XG4gICAgdG1wID0gKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV0gPDwgMTApIHwgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMSldIDw8IDQpIHwgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMildID4+IDIpXG4gICAgYXJyW0wrK10gPSAodG1wID4+IDgpICYgMHhGRlxuICAgIGFycltMKytdID0gdG1wICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIGFyclxufVxuXG5mdW5jdGlvbiB0cmlwbGV0VG9CYXNlNjQgKG51bSkge1xuICByZXR1cm4gbG9va3VwW251bSA+PiAxOCAmIDB4M0ZdICsgbG9va3VwW251bSA+PiAxMiAmIDB4M0ZdICsgbG9va3VwW251bSA+PiA2ICYgMHgzRl0gKyBsb29rdXBbbnVtICYgMHgzRl1cbn1cblxuZnVuY3Rpb24gZW5jb2RlQ2h1bmsgKHVpbnQ4LCBzdGFydCwgZW5kKSB7XG4gIHZhciB0bXBcbiAgdmFyIG91dHB1dCA9IFtdXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSArPSAzKSB7XG4gICAgdG1wID0gKHVpbnQ4W2ldIDw8IDE2KSArICh1aW50OFtpICsgMV0gPDwgOCkgKyAodWludDhbaSArIDJdKVxuICAgIG91dHB1dC5wdXNoKHRyaXBsZXRUb0Jhc2U2NCh0bXApKVxuICB9XG4gIHJldHVybiBvdXRwdXQuam9pbignJylcbn1cblxuZnVuY3Rpb24gZnJvbUJ5dGVBcnJheSAodWludDgpIHtcbiAgdmFyIHRtcFxuICB2YXIgbGVuID0gdWludDgubGVuZ3RoXG4gIHZhciBleHRyYUJ5dGVzID0gbGVuICUgMyAvLyBpZiB3ZSBoYXZlIDEgYnl0ZSBsZWZ0LCBwYWQgMiBieXRlc1xuICB2YXIgb3V0cHV0ID0gJydcbiAgdmFyIHBhcnRzID0gW11cbiAgdmFyIG1heENodW5rTGVuZ3RoID0gMTYzODMgLy8gbXVzdCBiZSBtdWx0aXBsZSBvZiAzXG5cbiAgLy8gZ28gdGhyb3VnaCB0aGUgYXJyYXkgZXZlcnkgdGhyZWUgYnl0ZXMsIHdlJ2xsIGRlYWwgd2l0aCB0cmFpbGluZyBzdHVmZiBsYXRlclxuICBmb3IgKHZhciBpID0gMCwgbGVuMiA9IGxlbiAtIGV4dHJhQnl0ZXM7IGkgPCBsZW4yOyBpICs9IG1heENodW5rTGVuZ3RoKSB7XG4gICAgcGFydHMucHVzaChlbmNvZGVDaHVuayh1aW50OCwgaSwgKGkgKyBtYXhDaHVua0xlbmd0aCkgPiBsZW4yID8gbGVuMiA6IChpICsgbWF4Q2h1bmtMZW5ndGgpKSlcbiAgfVxuXG4gIC8vIHBhZCB0aGUgZW5kIHdpdGggemVyb3MsIGJ1dCBtYWtlIHN1cmUgdG8gbm90IGZvcmdldCB0aGUgZXh0cmEgYnl0ZXNcbiAgaWYgKGV4dHJhQnl0ZXMgPT09IDEpIHtcbiAgICB0bXAgPSB1aW50OFtsZW4gLSAxXVxuICAgIG91
4244dHB1dCArPSBsb29rdXBbdG1wID4+IDJdXG4gICAgb3V0cHV0ICs9IGxvb2t1cFsodG1wIDw8IDQpICYgMHgzRl1cbiAgICBvdXRwdXQgKz0gJz09J1xuICB9IGVsc2UgaWYgKGV4dHJhQnl0ZXMgPT09IDIpIHtcbiAgICB0bXAgPSAodWludDhbbGVuIC0gMl0gPDwgOCkgKyAodWludDhbbGVuIC0gMV0pXG4gICAgb3V0cHV0ICs9IGxvb2t1cFt0bXAgPj4gMTBdXG4gICAgb3V0cHV0ICs9IGxvb2t1cFsodG1wID4+IDQpICYgMHgzRl1cbiAgICBvdXRwdXQgKz0gbG9va3VwWyh0bXAgPDwgMikgJiAweDNGXVxuICAgIG91dHB1dCArPSAnPSdcbiAgfVxuXG4gIHBhcnRzLnB1c2gob3V0cHV0KVxuXG4gIHJldHVybiBwYXJ0cy5qb2luKCcnKVxufVxuIiwiLyohXG4gKiBUaGUgYnVmZmVyIG1vZHVsZSBmcm9tIG5vZGUuanMsIGZvciB0aGUgYnJvd3Nlci5cbiAqXG4gKiBAYXV0aG9yICAgRmVyb3NzIEFib3VraGFkaWplaCA8ZmVyb3NzQGZlcm9zcy5vcmc+IDxodHRwOi8vZmVyb3NzLm9yZz5cbiAqIEBsaWNlbnNlICBNSVRcbiAqL1xuLyogZXNsaW50LWRpc2FibGUgbm8tcHJvdG8gKi9cblxuJ3VzZSBzdHJpY3QnXG5cbnZhciBiYXNlNjQgPSByZXF1aXJlKCdiYXNlNjQtanMnKVxudmFyIGllZWU3NTQgPSByZXF1aXJlKCdpZWVlNzU0JylcbnZhciBpc0FycmF5ID0gcmVxdWlyZSgnaXNhcnJheScpXG5cbmV4cG9ydHMuQnVmZmVyID0gQnVmZmVyXG5leHBvcnRzLlNsb3dCdWZmZXIgPSBTbG93QnVmZmVyXG5leHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTID0gNTBcblxuLyoqXG4gKiBJZiBgQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlRgOlxuICogICA9PT0gdHJ1ZSAgICBVc2UgVWludDhBcnJheSBpbXBsZW1lbnRhdGlvbiAoZmFzdGVzdClcbiAqICAgPT09IGZhbHNlICAgVXNlIE9iamVjdCBpbXBsZW1lbnRhdGlvbiAobW9zdCBjb21wYXRpYmxlLCBldmVuIElFNilcbiAqXG4gKiBCcm93c2VycyB0aGF0IHN1cHBvcnQgdHlwZWQgYXJyYXlzIGFyZSBJRSAxMCssIEZpcmVmb3ggNCssIENocm9tZSA3KywgU2FmYXJpIDUuMSssXG4gKiBPcGVyYSAxMS42KywgaU9TIDQuMisuXG4gKlxuICogRHVlIHRvIHZhcmlvdXMgYnJvd3NlciBidWdzLCBzb21ldGltZXMgdGhlIE9iamVjdCBpbXBsZW1lbnRhdGlvbiB3aWxsIGJlIHVzZWQgZXZlblxuICogd2hlbiB0aGUgYnJvd3NlciBzdXBwb3J0cyB0eXBlZCBhcnJheXMuXG4gKlxuICogTm90ZTpcbiAqXG4gKiAgIC0gRmlyZWZveCA0LTI5IGxhY2tzIHN1cHBvcnQgZm9yIGFkZGluZyBuZXcgcHJvcGVydGllcyB0byBgVWludDhBcnJheWAgaW5zdGFuY2VzLFxuICogICAgIFNlZTogaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9Njk1NDM4LlxuICpcbiAqICAgLSBDaHJvbWUgOS0xMCBpcyBtaXNzaW5nIHRoZSBgVHlwZWRBcnJheS5wcm90b3R5cGUuc3ViYXJyYXlgIGZ1bmN0aW9uLlxuICpcbiAqICAgLSBJRTEwIGhhcyBhIGJyb2tlbiBgVHlwZWRBcnJheS5wcm90b3R5cGUuc3ViYXJyYXlgIGZ1bmN0aW9uIHdoaWNoIHJldHVybnMgYXJyYXlzIG9mXG4gKiAgICAgaW5jb3JyZWN0IGxlbmd0aCBpbiBzb21lIHNpdHVhdGlvbnMuXG5cbiAqIFdlIGRldGVjdCB0aGVzZSBidWdneSBicm93c2VycyBhbmQgc2V0IGBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVGAgdG8gYGZhbHNlYCBzbyB0aGV5XG4gKiBnZXQgdGhlIE9iamVjdCBpbXBsZW1lbnRhdGlvbiwgd2hpY2ggaXMgc2xvd2VyIGJ1dCBiZWhhdmVzIGNvcnJlY3RseS5cbiAqL1xuQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgPSBnbG9iYWwuVFlQRURfQVJSQVlfU1VQUE9SVCAhPT0gdW5kZWZpbmVkXG4gID8gZ2xvYmFsLlRZUEVEX0FSUkFZX1NVUFBPUlRcbiAgOiB0eXBlZEFycmF5U3VwcG9ydCgpXG5cbi8qXG4gKiBFeHBvcnQga01heExlbmd0aCBhZnRlciB0eXBlZCBhcnJheSBzdXBwb3J0IGlzIGRldGVybWluZWQuXG4gKi9cbmV4cG9ydHMua01heExlbmd0aCA9IGtNYXhMZW5ndGgoKVxuXG5mdW5jdGlvbiB0eXBlZEFycmF5U3VwcG9ydCAoKSB7XG4gIHRyeSB7XG4gICAgdmFyIGFyciA9IG5ldyBVaW50OEFycmF5KDEpXG4gICAgYXJyLmZvbyA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDQyIH1cbiAgICByZXR1cm4gYXJyLmZvbygpID09PSA0MiAmJiAvLyB0eXBlZCBhcnJheSBpbnN0YW5jZXMgY2FuIGJlIGF1Z21lbnRlZFxuICAgICAgICB0eXBlb2YgYXJyLnN1YmFycmF5ID09PSAnZnVuY3Rpb24nICYmIC8vIGNocm9tZSA5LTEwIGxhY2sgYHN1YmFycmF5YFxuICAgICAgICBhcnIuc3ViYXJyYXkoMSwgMSkuYnl0ZUxlbmd0aCA9PT0gMCAvLyBpZTEwIGhhcyBicm9rZW4gYHN1YmFycmF5YFxuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuZnVuY3Rpb24ga01heExlbmd0aCAoKSB7XG4gIHJldHVybiBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVFxuICAgID8gMHg3ZmZmZmZmZlxuICAgIDogMHgzZmZmZmZmZlxufVxuXG5mdW5jdGlvbiBjcmVhdGVCdWZmZXIgKHRoYXQsIGxlbmd0aCkge1xuICBpZiAoa01heExlbmd0aCgpIDwgbGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0ludmFsaWQgdHlwZWQgYXJyYXkgbGVuZ3RoJylcbiAgfVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZSwgZm9yIGJlc3QgcGVyZm9ybWFuY2VcbiAgICB0aGF0ID0gbmV3IFVpbnQ4QXJyYXkobGVuZ3RoKVxuICAgIHRoYXQuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICB9IGVsc2Uge1xuICAgIC8vIEZhbGxiYWNrOiBSZXR1cm4gYW4gb2JqZWN0IGluc3RhbmNlIG9mIHRoZSBCdWZmZXIgY2xhc3NcbiAgICBpZiAodGhhdCA9PT0gbnVsbCkge1xuICAgICAgdGhhdCA9IG5ldyBCdWZmZXIobGVuZ3RoKVxuICAgIH1cbiAgICB0aGF0Lmxlbmd0aCA9IGxlbmd0aFxuICB9XG5cbiAgcmV0dXJuIHRoYXRcbn1cblxuLyoqXG4gKiBUaGUgQnVmZmVyIGNvbnN0cnVjdG9yIHJldHVybnMgaW5zdGFuY2VzIG9mIGBVaW50OEFycmF5YCB0aGF0IGhh
4244dmUgdGhlaXJcbiAqIHByb3RvdHlwZSBjaGFuZ2VkIHRvIGBCdWZmZXIucHJvdG90eXBlYC4gRnVydGhlcm1vcmUsIGBCdWZmZXJgIGlzIGEgc3ViY2xhc3Mgb2ZcbiAqIGBVaW50OEFycmF5YCwgc28gdGhlIHJldHVybmVkIGluc3RhbmNlcyB3aWxsIGhhdmUgYWxsIHRoZSBub2RlIGBCdWZmZXJgIG1ldGhvZHNcbiAqIGFuZCB0aGUgYFVpbnQ4QXJyYXlgIG1ldGhvZHMuIFNxdWFyZSBicmFja2V0IG5vdGF0aW9uIHdvcmtzIGFzIGV4cGVjdGVkIC0tIGl0XG4gKiByZXR1cm5zIGEgc2luZ2xlIG9jdGV0LlxuICpcbiAqIFRoZSBgVWludDhBcnJheWAgcHJvdG90eXBlIHJlbWFpbnMgdW5tb2RpZmllZC5cbiAqL1xuXG5mdW5jdGlvbiBCdWZmZXIgKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgJiYgISh0aGlzIGluc3RhbmNlb2YgQnVmZmVyKSkge1xuICAgIHJldHVybiBuZXcgQnVmZmVyKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxuICB9XG5cbiAgLy8gQ29tbW9uIGNhc2UuXG4gIGlmICh0eXBlb2YgYXJnID09PSAnbnVtYmVyJykge1xuICAgIGlmICh0eXBlb2YgZW5jb2RpbmdPck9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ0lmIGVuY29kaW5nIGlzIHNwZWNpZmllZCB0aGVuIHRoZSBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nJ1xuICAgICAgKVxuICAgIH1cbiAgICByZXR1cm4gYWxsb2NVbnNhZmUodGhpcywgYXJnKVxuICB9XG4gIHJldHVybiBmcm9tKHRoaXMsIGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxufVxuXG5CdWZmZXIucG9vbFNpemUgPSA4MTkyIC8vIG5vdCB1c2VkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb25cblxuLy8gVE9ETzogTGVnYWN5LCBub3QgbmVlZGVkIGFueW1vcmUuIFJlbW92ZSBpbiBuZXh0IG1ham9yIHZlcnNpb24uXG5CdWZmZXIuX2F1Z21lbnQgPSBmdW5jdGlvbiAoYXJyKSB7XG4gIGFyci5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIHJldHVybiBhcnJcbn1cblxuZnVuY3Rpb24gZnJvbSAodGhhdCwgdmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1widmFsdWVcIiBhcmd1bWVudCBtdXN0IG5vdCBiZSBhIG51bWJlcicpXG4gIH1cblxuICBpZiAodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJiB2YWx1ZSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgcmV0dXJuIGZyb21BcnJheUJ1ZmZlcih0aGF0LCB2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxuICB9XG5cbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZnJvbVN0cmluZyh0aGF0LCB2YWx1ZSwgZW5jb2RpbmdPck9mZnNldClcbiAgfVxuXG4gIHJldHVybiBmcm9tT2JqZWN0KHRoYXQsIHZhbHVlKVxufVxuXG4vKipcbiAqIEZ1bmN0aW9uYWxseSBlcXVpdmFsZW50IHRvIEJ1ZmZlcihhcmcsIGVuY29kaW5nKSBidXQgdGhyb3dzIGEgVHlwZUVycm9yXG4gKiBpZiB2YWx1ZSBpcyBhIG51bWJlci5cbiAqIEJ1ZmZlci5mcm9tKHN0clssIGVuY29kaW5nXSlcbiAqIEJ1ZmZlci5mcm9tKGFycmF5KVxuICogQnVmZmVyLmZyb20oYnVmZmVyKVxuICogQnVmZmVyLmZyb20oYXJyYXlCdWZmZXJbLCBieXRlT2Zmc2V0WywgbGVuZ3RoXV0pXG4gKiovXG5CdWZmZXIuZnJvbSA9IGZ1bmN0aW9uICh2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBmcm9tKG51bGwsIHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG59XG5cbmlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICBCdWZmZXIucHJvdG90eXBlLl9fcHJvdG9fXyA9IFVpbnQ4QXJyYXkucHJvdG90eXBlXG4gIEJ1ZmZlci5fX3Byb3RvX18gPSBVaW50OEFycmF5XG4gIGlmICh0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2wuc3BlY2llcyAmJlxuICAgICAgQnVmZmVyW1N5bWJvbC5zcGVjaWVzXSA9PT0gQnVmZmVyKSB7XG4gICAgLy8gRml4IHN1YmFycmF5KCkgaW4gRVMyMDE2LiBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyL3B1bGwvOTdcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQnVmZmVyLCBTeW1ib2wuc3BlY2llcywge1xuICAgICAgdmFsdWU6IG51bGwsXG4gICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KVxuICB9XG59XG5cbmZ1bmN0aW9uIGFzc2VydFNpemUgKHNpemUpIHtcbiAgaWYgKHR5cGVvZiBzaXplICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wic2l6ZVwiIGFyZ3VtZW50IG11c3QgYmUgYSBudW1iZXInKVxuICB9XG59XG5cbmZ1bmN0aW9uIGFsbG9jICh0aGF0LCBzaXplLCBmaWxsLCBlbmNvZGluZykge1xuICBhc3NlcnRTaXplKHNpemUpXG4gIGlmIChzaXplIDw9IDApIHtcbiAgICByZXR1cm4gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpXG4gIH1cbiAgaWYgKGZpbGwgIT09IHVuZGVmaW5lZCkge1xuICAgIC8vIE9ubHkgcGF5IGF0dGVudGlvbiB0byBlbmNvZGluZyBpZiBpdCdzIGEgc3RyaW5nLiBUaGlzXG4gICAgLy8gcHJldmVudHMgYWNjaWRlbnRhbGx5IHNlbmRpbmcgaW4gYSBudW1iZXIgdGhhdCB3b3VsZFxuICAgIC8vIGJlIGludGVycHJldHRlZCBhcyBhIHN0YXJ0IG9mZnNldC5cbiAgICByZXR1cm4gdHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJ1xuICAgICAgPyBjcmVhdGVCdWZmZXIodGhhdCwgc2l6ZSkuZmlsbChmaWxsLCBlbmNvZGluZylcbiAgICAgIDogY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpLmZpbGwoZmlsbClcbiAgfVxuICByZXR1cm4gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpXG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBmaWxsZWQgQnVmZmVyIGluc3RhbmNlLlxuICogYWxsb2Moc2l6ZVssIGZpbGxbLCBlbmNvZGluZ11dKVxuICoqL1xuQnVmZmVyLmFsbG9jID0gZnVuY3Rpb24gKHNpemUsIGZpbGwsIGVuY29kaW5nKSB7XG4gIHJldHVybi
4244BhbGxvYyhudWxsLCBzaXplLCBmaWxsLCBlbmNvZGluZylcbn1cblxuZnVuY3Rpb24gYWxsb2NVbnNhZmUgKHRoYXQsIHNpemUpIHtcbiAgYXNzZXJ0U2l6ZShzaXplKVxuICB0aGF0ID0gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUgPCAwID8gMCA6IGNoZWNrZWQoc2l6ZSkgfCAwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaXplOyBpKyspIHtcbiAgICAgIHRoYXRbaV0gPSAwXG4gICAgfVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbi8qKlxuICogRXF1aXZhbGVudCB0byBCdWZmZXIobnVtKSwgYnkgZGVmYXVsdCBjcmVhdGVzIGEgbm9uLXplcm8tZmlsbGVkIEJ1ZmZlciBpbnN0YW5jZS5cbiAqICovXG5CdWZmZXIuYWxsb2NVbnNhZmUgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICByZXR1cm4gYWxsb2NVbnNhZmUobnVsbCwgc2l6ZSlcbn1cbi8qKlxuICogRXF1aXZhbGVudCB0byBTbG93QnVmZmVyKG51bSksIGJ5IGRlZmF1bHQgY3JlYXRlcyBhIG5vbi16ZXJvLWZpbGxlZCBCdWZmZXIgaW5zdGFuY2UuXG4gKi9cbkJ1ZmZlci5hbGxvY1Vuc2FmZVNsb3cgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICByZXR1cm4gYWxsb2NVbnNhZmUobnVsbCwgc2l6ZSlcbn1cblxuZnVuY3Rpb24gZnJvbVN0cmluZyAodGhhdCwgc3RyaW5nLCBlbmNvZGluZykge1xuICBpZiAodHlwZW9mIGVuY29kaW5nICE9PSAnc3RyaW5nJyB8fCBlbmNvZGluZyA9PT0gJycpIHtcbiAgICBlbmNvZGluZyA9ICd1dGY4J1xuICB9XG5cbiAgaWYgKCFCdWZmZXIuaXNFbmNvZGluZyhlbmNvZGluZykpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImVuY29kaW5nXCIgbXVzdCBiZSBhIHZhbGlkIHN0cmluZyBlbmNvZGluZycpXG4gIH1cblxuICB2YXIgbGVuZ3RoID0gYnl0ZUxlbmd0aChzdHJpbmcsIGVuY29kaW5nKSB8IDBcbiAgdGhhdCA9IGNyZWF0ZUJ1ZmZlcih0aGF0LCBsZW5ndGgpXG5cbiAgdGhhdC53cml0ZShzdHJpbmcsIGVuY29kaW5nKVxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tQXJyYXlMaWtlICh0aGF0LCBhcnJheSkge1xuICB2YXIgbGVuZ3RoID0gY2hlY2tlZChhcnJheS5sZW5ndGgpIHwgMFxuICB0aGF0ID0gY3JlYXRlQnVmZmVyKHRoYXQsIGxlbmd0aClcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgIHRoYXRbaV0gPSBhcnJheVtpXSAmIDI1NVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUJ1ZmZlciAodGhhdCwgYXJyYXksIGJ5dGVPZmZzZXQsIGxlbmd0aCkge1xuICBhcnJheS5ieXRlTGVuZ3RoIC8vIHRoaXMgdGhyb3dzIGlmIGBhcnJheWAgaXMgbm90IGEgdmFsaWQgQXJyYXlCdWZmZXJcblxuICBpZiAoYnl0ZU9mZnNldCA8IDAgfHwgYXJyYXkuYnl0ZUxlbmd0aCA8IGJ5dGVPZmZzZXQpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXFwnb2Zmc2V0XFwnIGlzIG91dCBvZiBib3VuZHMnKVxuICB9XG5cbiAgaWYgKGFycmF5LmJ5dGVMZW5ndGggPCBieXRlT2Zmc2V0ICsgKGxlbmd0aCB8fCAwKSkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdcXCdsZW5ndGhcXCcgaXMgb3V0IG9mIGJvdW5kcycpXG4gIH1cblxuICBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBhcnJheSA9IG5ldyBVaW50OEFycmF5KGFycmF5LCBieXRlT2Zmc2V0KVxuICB9IGVsc2Uge1xuICAgIGFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXksIGJ5dGVPZmZzZXQsIGxlbmd0aClcbiAgfVxuXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIC8vIFJldHVybiBhbiBhdWdtZW50ZWQgYFVpbnQ4QXJyYXlgIGluc3RhbmNlLCBmb3IgYmVzdCBwZXJmb3JtYW5jZVxuICAgIHRoYXQgPSBhcnJheVxuICAgIHRoYXQuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICB9IGVsc2Uge1xuICAgIC8vIEZhbGxiYWNrOiBSZXR1cm4gYW4gb2JqZWN0IGluc3RhbmNlIG9mIHRoZSBCdWZmZXIgY2xhc3NcbiAgICB0aGF0ID0gZnJvbUFycmF5TGlrZSh0aGF0LCBhcnJheSlcbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tT2JqZWN0ICh0aGF0LCBvYmopIHtcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihvYmopKSB7XG4gICAgdmFyIGxlbiA9IGNoZWNrZWQob2JqLmxlbmd0aCkgfCAwXG4gICAgdGhhdCA9IGNyZWF0ZUJ1ZmZlcih0aGF0LCBsZW4pXG5cbiAgICBpZiAodGhhdC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB0aGF0XG4gICAgfVxuXG4gICAgb2JqLmNvcHkodGhhdCwgMCwgMCwgbGVuKVxuICAgIHJldHVybiB0aGF0XG4gIH1cblxuICBpZiAob2JqKSB7XG4gICAgaWYgKCh0eXBlb2YgQXJyYXlCdWZmZXIgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgIG9iai5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgfHwgJ2xlbmd0aCcgaW4gb2JqKSB7XG4gICAgICBpZiAodHlwZW9mIG9iai5sZW5ndGggIT09ICdudW1iZXInIHx8IGlzbmFuKG9iai5sZW5ndGgpKSB7XG4gICAgICAgIHJldHVybiBjcmVhdGVCdWZmZXIodGhhdCwgMClcbiAgICAgIH1cbiAgICAgIHJldHVybiBmcm9tQXJyYXlMaWtlKHRoYXQsIG9iailcbiAgICB9XG5cbiAgICBpZiAob2JqLnR5cGUgPT09ICdCdWZmZXInICYmIGlzQXJyYXkob2JqLmRhdGEpKSB7XG4gICAgICByZXR1cm4gZnJvbUFycmF5TGlrZSh0aGF0LCBvYmouZGF0YSlcbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKCdGaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nLCBCdWZmZXIsIEFycmF5QnVmZmVyLCBBcnJheSwgb3IgYXJyYXktbGlrZSBvYmplY3QuJylcbn1cblxuZnVuY3Rpb24gY2hlY2tlZCAobGVuZ3RoKSB7XG4gIC8vIE5vdGU6IGNhbm5vdCB1c2UgYGxlbmd0aCA8IGtNYXhMZW5ndGhgIGhlcmUgYmVjYXVzZSB0aGF0IGZhaWxzIHdoZW5cbiAgLy8gbGVuZ3RoIGlzIE5hTiAod2hpY2ggaXMgb3RoZXJ3aXNlIGNvZXJjZWQgdG8gemVyby4pXG4gIGlmIChsZW5ndGggPj0ga01heExlbmd0aCgpKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0F0dGVtcHQgdG8gYWxsb2NhdGUgQnVmZmVyIGxhcmdlciB0aGFuIG1heGltdW0gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgJ3NpemU6IDB4JyArIGtNYXhMZW5ndGgoKS50b1N0cmluZygxNikgKyAnIGJ5dGVzJylcbiAgfVxuICByZXR1cm4gbGVuZ3RoIHwgMFxufVxuXG5mdW5jdGlvbiBTbG93QnVmZmVyIChsZW5ndGgpIHtcbiAgaWYgKCtsZW5ndGggIT0gbGVuZ3RoKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZXFlcWVxXG4gICAgbGVuZ3RoID0gMFxuICB9XG4gI
4244HJldHVybiBCdWZmZXIuYWxsb2MoK2xlbmd0aClcbn1cblxuQnVmZmVyLmlzQnVmZmVyID0gZnVuY3Rpb24gaXNCdWZmZXIgKGIpIHtcbiAgcmV0dXJuICEhKGIgIT0gbnVsbCAmJiBiLl9pc0J1ZmZlcilcbn1cblxuQnVmZmVyLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlIChhLCBiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGEpIHx8ICFCdWZmZXIuaXNCdWZmZXIoYikpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudHMgbXVzdCBiZSBCdWZmZXJzJylcbiAgfVxuXG4gIGlmIChhID09PSBiKSByZXR1cm4gMFxuXG4gIHZhciB4ID0gYS5sZW5ndGhcbiAgdmFyIHkgPSBiLmxlbmd0aFxuXG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBNYXRoLm1pbih4LCB5KTsgaSA8IGxlbjsgKytpKSB7XG4gICAgaWYgKGFbaV0gIT09IGJbaV0pIHtcbiAgICAgIHggPSBhW2ldXG4gICAgICB5ID0gYltpXVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cblxuICBpZiAoeCA8IHkpIHJldHVybiAtMVxuICBpZiAoeSA8IHgpIHJldHVybiAxXG4gIHJldHVybiAwXG59XG5cbkJ1ZmZlci5pc0VuY29kaW5nID0gZnVuY3Rpb24gaXNFbmNvZGluZyAoZW5jb2RpbmcpIHtcbiAgc3dpdGNoIChTdHJpbmcoZW5jb2RpbmcpLnRvTG93ZXJDYXNlKCkpIHtcbiAgICBjYXNlICdoZXgnOlxuICAgIGNhc2UgJ3V0ZjgnOlxuICAgIGNhc2UgJ3V0Zi04JzpcbiAgICBjYXNlICdhc2NpaSc6XG4gICAgY2FzZSAnYmluYXJ5JzpcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgIGNhc2UgJ3Jhdyc6XG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndWNzLTInOlxuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgIHJldHVybiB0cnVlXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBmYWxzZVxuICB9XG59XG5cbkJ1ZmZlci5jb25jYXQgPSBmdW5jdGlvbiBjb25jYXQgKGxpc3QsIGxlbmd0aCkge1xuICBpZiAoIWlzQXJyYXkobGlzdCkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RcIiBhcmd1bWVudCBtdXN0IGJlIGFuIEFycmF5IG9mIEJ1ZmZlcnMnKVxuICB9XG5cbiAgaWYgKGxpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5hbGxvYygwKVxuICB9XG5cbiAgdmFyIGlcbiAgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbGVuZ3RoID0gMFxuICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBsZW5ndGggKz0gbGlzdFtpXS5sZW5ndGhcbiAgICB9XG4gIH1cblxuICB2YXIgYnVmZmVyID0gQnVmZmVyLmFsbG9jVW5zYWZlKGxlbmd0aClcbiAgdmFyIHBvcyA9IDBcbiAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgYnVmID0gbGlzdFtpXVxuICAgIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZikpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdFwiIGFyZ3VtZW50IG11c3QgYmUgYW4gQXJyYXkgb2YgQnVmZmVycycpXG4gICAgfVxuICAgIGJ1Zi5jb3B5KGJ1ZmZlciwgcG9zKVxuICAgIHBvcyArPSBidWYubGVuZ3RoXG4gIH1cbiAgcmV0dXJuIGJ1ZmZlclxufVxuXG5mdW5jdGlvbiBieXRlTGVuZ3RoIChzdHJpbmcsIGVuY29kaW5nKSB7XG4gIGlmIChCdWZmZXIuaXNCdWZmZXIoc3RyaW5nKSkge1xuICAgIHJldHVybiBzdHJpbmcubGVuZ3RoXG4gIH1cbiAgaWYgKHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIEFycmF5QnVmZmVyLmlzVmlldyA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgKEFycmF5QnVmZmVyLmlzVmlldyhzdHJpbmcpIHx8IHN0cmluZyBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSkge1xuICAgIHJldHVybiBzdHJpbmcuYnl0ZUxlbmd0aFxuICB9XG4gIGlmICh0eXBlb2Ygc3RyaW5nICE9PSAnc3RyaW5nJykge1xuICAgIHN0cmluZyA9ICcnICsgc3RyaW5nXG4gIH1cblxuICB2YXIgbGVuID0gc3RyaW5nLmxlbmd0aFxuICBpZiAobGVuID09PSAwKSByZXR1cm4gMFxuXG4gIC8vIFVzZSBhIGZvciBsb29wIHRvIGF2b2lkIHJlY3Vyc2lvblxuICB2Y
4244XIgbG93ZXJlZENhc2UgPSBmYWxzZVxuICBmb3IgKDs7KSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgIC8vIERlcHJlY2F0ZWRcbiAgICAgIGNhc2UgJ3Jhdyc6XG4gICAgICBjYXNlICdyYXdzJzpcbiAgICAgICAgcmV0dXJuIGxlblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICBjYXNlIHVuZGVmaW5lZDpcbiAgICAgICAgcmV0dXJuIHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gbGVuICogMlxuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGxlbiA+Pj4gMVxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgcmV0dXJuIGJhc2U2NFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGhcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgcmV0dXJuIHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoIC8vIGFzc3VtZSB1dGY4XG4gICAgICAgIGVuY29kaW5nID0gKCcnICsgZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5CdWZmZXIuYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGhcblxuZnVuY3Rpb24gc2xvd1RvU3RyaW5nIChlbmNvZGluZywgc3RhcnQsIGVuZCkge1xuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuXG4gIC8vIE5vIG5lZWQgdG8gdmVyaWZ5IHRoYXQgXCJ0aGlzLmxlbmd0aCA8PSBNQVhfVUlOVDMyXCIgc2luY2UgaXQncyBhIHJlYWQtb25seVxuICAvLyBwcm9wZXJ0eSBvZiBhIHR5cGVkIGFycmF5LlxuXG4gIC8vIFRoaXMgYmVoYXZlcyBuZWl0aGVyIGxpa2UgU3RyaW5nIG5vciBVaW50OEFycmF5IGluIHRoYXQgd2Ugc2V0IHN0YXJ0L2VuZFxuICAvLyB0byB0aGVpciB1cHBlci9sb3dlciBib3VuZHMgaWYgdGhlIHZhbHVlIHBhc3NlZCBpcyBvdXQgb2YgcmFuZ2UuXG4gIC8vIHVuZGVmaW5lZCBpcyBoYW5kbGVkIHNwZWNpYWxseSBhcyBwZXIgRUNNQS0yNjIgNnRoIEVkaXRpb24sXG4gIC8vIFNlY3Rpb24gMTMuMy4zLjcgUnVudGltZSBTZW1hbnRpY3M6IEtleWVkQmluZGluZ0luaXRpYWxpemF0aW9uLlxuICBpZiAoc3RhcnQgPT09IHVuZGVmaW5lZCB8fCBzdGFydCA8IDApIHtcbiAgICBzdGFydCA9IDBcbiAgfVxuICAvLyBSZXR1cm4gZWFybHkgaWYgc3RhcnQgPiB0aGlzLmxlbmd0aC4gRG9uZSBoZXJlIHRvIHByZXZlbnQgcG9
42440ZW50aWFsIHVpbnQzMlxuICAvLyBjb2VyY2lvbiBmYWlsIGJlbG93LlxuICBpZiAoc3RhcnQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkIHx8IGVuZCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgfVxuXG4gIGlmIChlbmQgPD0gMCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgLy8gRm9yY2UgY29lcnNpb24gdG8gdWludDMyLiBUaGlzIHdpbGwgYWxzbyBjb2VyY2UgZmFsc2V5L05hTiB2YWx1ZXMgdG8gMC5cbiAgZW5kID4+Pj0gMFxuICBzdGFydCA+Pj49IDBcblxuICBpZiAoZW5kIDw9IHN0YXJ0KSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIHdoaWxlICh0cnVlKSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGhleFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgICAgcmV0dXJuIGFzY2lpU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGJpbmFyeVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIHJldHVybiBiYXNlNjRTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gdXRmMTZsZVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgICAgICBlbmNvZGluZyA9IChlbmNvZGluZyArICcnKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuXG4vLyBUaGUgcHJvcGVydHkgaXMgdXNlZCBieSBgQnVmZmVyLmlzQnVmZmVyYCBhbmQgYGlzLWJ1ZmZlcmAgKGluIFNhZmFyaSA1LTcpIHRvIGRldGVjdFxuLy8gQnVmZmVyIGluc3RhbmNlcy5cbkJ1ZmZlci5wcm90b3R5cGUuX2lzQnVmZmVyID0gdHJ1ZVxuXG5mdW5jdGlvbiBzd2FwIChiLCBuLCBtKSB7XG4gIHZhciBpID0gYltuXVxuICBiW25dID0gYlttXVxuICBiW21dID0gaVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnN3YXAxNiA9IGZ1bmN0aW9uIHN3YXAxNiAoKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuICUgMiAhPT0gMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgMTYtYml0cycpXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKz0gMikge1xuICAgIHN3YXAodGhpcywgaSwgaSArIDEpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zd2FwMzIgPSBmdW5jdGlvbiBzd2FwMzIgKCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgaWYgKGxlbiAlIDQgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDMyLWJpdHMnKVxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDQpIHtcbiAgICBzd2FwKHRoaXMsIGksIGkgKyAzKVxuICAgIHN3YXAodGhpcywgaSArIDEsIGkgKyAyKVxuICB9XG4gIHJldHVybiB0aGlzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZyAoKSB7XG4gIHZhciBsZW5ndGggPSB0aGlzLmxlbmd0aCB8IDBcbiAgaWYgKGxlbmd0aCA9PT0gMCkgcmV0dXJuICcnXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSByZXR1cm4gdXRmOFNsaWNlKHRoaXMsIDAsIGxlbmd0aClcbiAgcmV0dXJuIHNsb3dUb1N0cmluZy5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gZXF1YWxzIChiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyJylcbiAgaWYgKHRoaXMgPT09IGIpIHJldHVybiB0cnVlXG4gIHJldHVybiBCdWZmZXIuY29tcGFyZSh0aGlzLCBiKSA9PT0gMFxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluc3BlY3QgPSBmdW5jdGlvbiBpbnNwZWN0ICgpIHtcbiAgdmFyIHN0ciA9ICcnXG4gIHZhciBtYXggPSBleHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTXG4gIGlmICh0aGlzLmxlbmd0aCA+IDApIHtcbiAgICBzdHIgPSB0aGlzLnRvU3RyaW5nKCdoZXgnLCAwLCBtYXgpLm1hdGNoKC8uezJ9L2cpLmpvaW4oJyAnKVxuICAgIGlmICh0aGlzLmxlbmd0aCA+IG1heCkgc3RyICs9ICcgLi4uICdcbiAgfVxuICByZXR1cm4gJzxCdWZmZXIgJyArIHN0ciArICc+J1xufVxuXG5CdWZmZXIucHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlICh0YXJnZXQsIHN0YXJ0LCBlbmQsIHRoaXNTdGFydCwgdGhpc0VuZCkge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcih0YXJnZXQpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlcicpXG4gIH1cblxuICBpZiAoc3RhcnQgPT09IHVuZGVmaW5lZCkge1xuICAgIHN0YXJ0ID0gMFxuICB9XG4gIGlmIChlbmQgPT09IHVuZGVmaW5lZCkge1xuICAgIGVuZCA9IHRhcmdldCA/IHRhcmdldC5sZW5ndGggOiAwXG4gIH1cbiAgaWYgKHRoaXNTdGFydCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhpc1N0YXJ0ID0gMFxuICB9XG4gIGlmICh0aGlzRW5kID09PSB1bmRlZmluZWQpIHtcbiAgICB0aGlzRW5kID0gdGhpcy5sZW5ndGhcbiAgfVxuXG4gIGlmIChzdGFydCA8IDAgfHwgZW5kID4gdGFyZ2V0Lmxlbmd0aCB8fCB0aGlzU3RhcnQgPCAwIHx8IHRoaXNFbmQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdvdXQgb2YgcmFuZ2UgaW5kZXgnKVxuICB9XG5cbiAgaWYgKHRoaXNTdGFydCA+PSB0aGlzRW5kICYmIHN0YXJ0ID49IGVuZCkge1xuICAgIHJldHVybiAwXG4gIH1cbiAgaWYgKHRoaXNTdGFydCA+PSB0aGlzRW5kKSB7XG4gICAgcmV0dXJuIC0xXG4gIH1cbiAgaWYgKHN0YXJ0ID49IGVuZCkge1xuICAgIHJldHVybiAxXG4gIH1cblxuICBzdGFydCA+Pj49IDBcbiAgZW5kID4+Pj0gMFxuICB0aGlzU3RhcnQgPj4+PSAwXG4gIHRoaXNFbmQgPj4+PSAwXG5cbiAgaWYgKHRoaXMgPT09IHRhcmdldCkgcmV0dXJuIDBcblxuICB2Y
4244XIgeCA9IHRoaXNFbmQgLSB0aGlzU3RhcnRcbiAgdmFyIHkgPSBlbmQgLSBzdGFydFxuICB2YXIgbGVuID0gTWF0aC5taW4oeCwgeSlcblxuICB2YXIgdGhpc0NvcHkgPSB0aGlzLnNsaWNlKHRoaXNTdGFydCwgdGhpc0VuZClcbiAgdmFyIHRhcmdldENvcHkgPSB0YXJnZXQuc2xpY2Uoc3RhcnQsIGVuZClcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgaWYgKHRoaXNDb3B5W2ldICE9PSB0YXJnZXRDb3B5W2ldKSB7XG4gICAgICB4ID0gdGhpc0NvcHlbaV1cbiAgICAgIHkgPSB0YXJnZXRDb3B5W2ldXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuXG4gIGlmICh4IDwgeSkgcmV0dXJuIC0xXG4gIGlmICh5IDwgeCkgcmV0dXJuIDFcbiAgcmV0dXJuIDBcbn1cblxuZnVuY3Rpb24gYXJyYXlJbmRleE9mIChhcnIsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpIHtcbiAgdmFyIGluZGV4U2l6ZSA9IDFcbiAgdmFyIGFyckxlbmd0aCA9IGFyci5sZW5ndGhcbiAgdmFyIHZhbExlbmd0aCA9IHZhbC5sZW5ndGhcblxuICBpZiAoZW5jb2RpbmcgIT09IHVuZGVmaW5lZCkge1xuICAgIGVuY29kaW5nID0gU3RyaW5nKGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgaWYgKGVuY29kaW5nID09PSAndWNzMicgfHwgZW5jb2RpbmcgPT09ICd1Y3MtMicgfHxcbiAgICAgICAgZW5jb2RpbmcgPT09ICd1dGYxNmxlJyB8fCBlbmNvZGluZyA9PT0gJ3V0Zi0xNmxlJykge1xuICAgICAgaWYgKGFyci5sZW5ndGggPCAyIHx8IHZhbC5sZW5ndGggPCAyKSB7XG4gICAgICAgIHJldHVybiAtMVxuICAgICAgfVxuICAgICAgaW5kZXhTaXplID0gMlxuICAgICAgYXJyTGVuZ3RoIC89IDJcbiAgICAgIHZhbExlbmd0aCAvPSAyXG4gICAgICBieXRlT2Zmc2V0IC89IDJcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZWFkIChidWYsIGkpIHtcbiAgICBpZiAoaW5kZXhTaXplID09PSAxKSB7XG4gICAgICByZXR1cm4gYnVmW2ldXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBidWYucmVhZFVJbnQxNkJFKGkgKiBpbmRleFNpemUpXG4gICAgfVxuICB9XG5cbiAgdmFyIGZvdW5kSW5kZXggPSAtMVxuICBmb3IgKHZhciBpID0gMDsgYnl0ZU9mZnNldCArIGkgPCBhcnJMZW5ndGg7IGkrKykge1xuICAgIGlmIChyZWFkKGFyciwgYnl0ZU9mZnNldCArIGkpID09PSByZWFkKHZhbCwgZm91bmRJbmRleCA9PT0gLTEgPyAwIDogaSAtIGZvdW5kSW5kZXgpKSB7XG4gICAgICBpZiAoZm91bmRJbmRleCA9PT0gLTEpIGZvdW5kSW5kZXggPSBpXG4gICAgICBpZiAoaSAtIGZvdW5kSW5kZXggKyAxID09PSB2YWxMZW5ndGgpIHJldHVybiAoYnl0ZU9mZnNldCArIGZvdW5kSW5kZXgpICogaW5kZXhTaXplXG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChmb3VuZEluZGV4ICE9PSAtMSkgaSAtPSBpIC0gZm91bmRJbmRleFxuICAgICAgZm91bmRJbmRleCA9IC0xXG4gICAgfVxuICB9XG4gIHJldHVybiAtMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluZGV4T2YgPSBmdW5jdGlvbiBpbmRleE9mICh2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSB7XG4gIGlmICh0eXBlb2YgYnl0ZU9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmNvZGluZyA9IGJ5dGVPZmZzZXRcbiAgICBieXRlT2Zmc2V0ID0gMFxuICB9IGVsc2UgaWYgKGJ5dGVPZmZzZXQgPiAweDdmZmZmZmZmKSB7XG4gICAgYnl0ZU9mZnNldCA9IDB4N2ZmZmZmZmZcbiAgfSBlbHNlIGlmIChieXRlT2Zmc2V0IDwgLTB4ODAwMDAwMDApIHtcbiAgICBieXRlT2Zmc2V0ID0gLTB4ODAwMDAwMDBcbiAgfVxuICBieXRlT2Zmc2V0ID4+PSAwXG5cbiAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gLTFcbiAgaWYgKGJ5dGVPZmZzZXQgPj0gdGhpcy5sZW5ndGgpIHJldHVybiAtMVxuXG4gIC8vIE5lZ2F0aXZlIG9mZnNldHMgc3RhcnQgZnJvbSB0aGUgZW5kIG9mIHRoZSBidWZmZXJcbiAgaWYgKGJ5dGVPZmZzZXQgPCAwKSBieXRlT2Zmc2V0ID0gTWF0aC5tYXgodGhpcy5sZW5ndGggKyBieXRlT2Zmc2V0LCAwKVxuXG4gIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgIHZhbCA9IEJ1ZmZlci5mcm9tKHZhbCwgZW5jb2RpbmcpXG4gIH1cblxuICBpZiAoQnVmZmVyLmlzQnVmZmVyKHZhbCkpIHtcbiAgICAvLyBzcGVjaWFsIGNhc2U6IGxvb2tpbmcgZm9yIGVtcHR5IHN0cmluZy9idWZmZXIgYWx3YXlzIGZhaWxzXG4gICAgaWYgKHZhbC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiAtMVxuICAgIH1cbiAgICByZXR1cm4gYXJyYXlJbmRleE9mKHRoaXMsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpXG4gIH1cbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUICYmIFVpbnQ4QXJyYXkucHJvdG90eXBlLmluZGV4T2YgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiBVaW50OEFycmF5LnByb3RvdHlwZS5pbmRleE9mLmNhbGwodGhpcywgdmFsLCBieXRlT2Zmc2V0KVxuICAgIH1cbiAgICByZXR1cm4gYXJyYXlJbmRleE9mKHRoaXMsIFsgdmFsIF0sIGJ5dGVPZmZzZXQsIGVuY29kaW5nKVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcigndmFsIG11c3QgYmUgc3RyaW5nLCBudW1iZXIgb3IgQnVmZmVyJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbmNsdWRlcyA9IGZ1bmN0aW9uIGluY2x1ZGVzICh2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSB7XG4gIHJldHVybiB0aGlzLmluZGV4T2YodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykgIT09IC0xXG59XG5cbmZ1bmN0aW9uIGhleFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgb2Zmc2V0ID0gTnVtYmVyKG9mZnNldCkgfHwgMFxuICB2YXIgcmVtYWluaW5nID0gYnVmLmxlbmd0aCAtIG9mZnNldFxuICBpZiAoIWxlbmd0aCkge1xuICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICB9IGVsc2Uge1xuICAgIGxlbmd0aCA9IE51bWJlcihsZW5ndGgpXG4gICAgaWYgKGxlbmd0aCA+IHJlbWFpbmluZykge1xuICAgICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gICAgfVxuICB9XG5cbiAgLy8gbXVzdCBiZSBhbiBldmVuIG51bWJlciBvZiBkaWdpdHNcbiAgdmFyIHN0ckxlbiA9IHN0cmluZy5sZW5ndGhcbiAgaWYgKHN0ckxlbiAlIDIgIT09IDApIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBoZXggc3RyaW5nJylcblxuICBpZiAobGVuZ3RoID4gc3RyTGVuIC8gMikge1xuICAgIGxlbmd0aCA9IHN0ckxlbiAvIDJcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcnNlZCA9IHBhcnNlSW50KHN0cmluZy5zdWJzdHIoaSAqIDIsIDIpLCAxNilcbiAgICBpZiAoaXNOYU4ocGFyc2VkKSkgcmV0dXJuIGlcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSBwYXJzZWRcbiAgfVxuICByZXR1cm4gaVxufVxuXG5mdW5jdGlvbiB1dGY4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcih1dGY4VG9CeXRlcyhzdHJpbmcsIGJ1Zi5sZW5ndGggLSBvZmZzZXQpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBhc2NpaVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIoYXNjaWlUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGJpbmFyeVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGFzY2lpV3JpdGUoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBiYXNlNjRXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybi
4244BibGl0QnVmZmVyKGJhc2U2NFRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gdWNzMldyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIodXRmMTZsZVRvQnl0ZXMoc3RyaW5nLCBidWYubGVuZ3RoIC0gb2Zmc2V0KSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIHdyaXRlIChzdHJpbmcsIG9mZnNldCwgbGVuZ3RoLCBlbmNvZGluZykge1xuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nKVxuICBpZiAob2Zmc2V0ID09PSB1bmRlZmluZWQpIHtcbiAgICBlbmNvZGluZyA9ICd1dGY4J1xuICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gICAgb2Zmc2V0ID0gMFxuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nLCBlbmNvZGluZylcbiAgfSBlbHNlIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygb2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgIGVuY29kaW5nID0gb2Zmc2V0XG4gICAgbGVuZ3RoID0gdGhpcy5sZW5ndGhcbiAgICBvZmZzZXQgPSAwXG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcsIG9mZnNldFssIGxlbmd0aF1bLCBlbmNvZGluZ10pXG4gIH0gZWxzZSBpZiAoaXNGaW5pdGUob2Zmc2V0KSkge1xuICAgIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgICBpZiAoaXNGaW5pdGUobGVuZ3RoKSkge1xuICAgICAgbGVuZ3RoID0gbGVuZ3RoIHwgMFxuICAgICAgaWYgKGVuY29kaW5nID09PSB1bmRlZmluZWQpIGVuY29kaW5nID0gJ3V0ZjgnXG4gICAgfSBlbHNlIHtcbiAgICAgIGVuY29kaW5nID0gbGVuZ3RoXG4gICAgICBsZW5ndGggPSB1bmRlZmluZWRcbiAgICB9XG4gIC8vIGxlZ2FjeSB3cml0ZShzdHJpbmcsIGVuY29kaW5nLCBvZmZzZXQsIGxlbmd0aCkgLSByZW1vdmUgaW4gdjAuMTNcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnQnVmZmVyLndyaXRlKHN0cmluZywgZW5jb2RpbmcsIG9mZnNldFssIGxlbmd0aF0pIGlzIG5vIGxvbmdlciBzdXBwb3J0ZWQnXG4gICAgKVxuICB9XG5cbiAgdmFyIHJlbWFpbmluZyA9IHRoaXMubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCB8fCBsZW5ndGggPiByZW1haW5pbmcpIGxlbmd0aCA9IHJlbWFpbmluZ1xuXG4gIGlmICgoc3RyaW5nLmxlbmd0aCA+IDAgJiYgKGxlbmd0aCA8IDAgfHwgb2Zmc2V0IDwgMCkpIHx8IG9mZnNldCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0F0dGVtcHQgdG8gd3JpdGUgb3V0c2lkZSBidWZmZXIgYm91bmRzJylcbiAgfVxuXG4gIGlmICghZW5jb2RpbmcpIGVuY29kaW5nID0gJ3V0ZjgnXG5cbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcbiAgZm9yICg7Oykge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBoZXhXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICAgIHJldHVybiBhc2NpaVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBiaW5hcnlXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICAvLyBXYXJuaW5nOiBtYXhMZW5ndGggbm90IHRha2VuIGludG8gYWNjb3VudCBpbiBiYXNlNjRXcml0ZVxuICAgICAgICByZXR1cm4gYmFzZTY0V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIHVjczJXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICAgICAgZW5jb2RpbmcgPSAoJycgKyBlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04gKCkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6ICdCdWZmZXInLFxuICAgIGRhdGE6IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKHRoaXMuX2FyciB8fCB0aGlzLCAwKVxuICB9XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKHN0YXJ0ID09PSAwICYmIGVuZCA9PT0gYnVmLmxlbmd0aCkge1xuICAgIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYpXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1Zi5zbGljZShzdGFydCwgZW5kKSlcbiAgfVxufVxuXG5mdW5jdGlvbiB1dGY4U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG4gIHZhciByZXMgPSBbXVxuXG4gIHZhciBpID0gc3RhcnRcbiAgd2hpbGUgKGkgPCBlbmQpIHtcbiAgICB2YXIgZmlyc3RCeXRlID0gYnVmW2ldXG4gICAgdmFyIGNvZGVQb2ludCA9IG51bGxcbiAgICB2YXIgYnl0ZXNQZXJTZXF1ZW5jZSA9IChmaXJzdEJ5dGUgPiAweEVGKSA/IDRcbiAgICAgIDogKGZpcnN0Qnl0ZSA+IDB4REYpID8gM1xuICAgICAgOiAoZmlyc3RCeXRlID4gMHhCRikgPyAyXG4gICAgICA6IDFcblxuICAgIGlmIChpICsgYnl0ZXNQZXJTZXF1ZW5jZSA8PSBlbmQpIHtcbiAgICAgIHZhciBzZWNvbmRCeXRlLCB0aGlyZEJ5dGUsIGZvdXJ0aEJ5dGUsIHRlbXBDb2RlUG9pbnRcblxuICAgICAgc3dpdGNoIChieXRlc1BlclNlcXVlbmNlKSB7XG4gICAgICAgIGNhc2UgMTpcbiAgICAgICAgICBpZiAoZmlyc3RCeXRlIDwgMHg4MCkge1xuICAgICAgICAgICAgY29
4244kZVBvaW50ID0gZmlyc3RCeXRlXG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgMjpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4MUYpIDw8IDB4NiB8IChzZWNvbmRCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHg3Rikge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgMzpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIHRoaXJkQnl0ZSA9IGJ1ZltpICsgMl1cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAodGhpcmRCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHhGKSA8PCAweEMgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpIDw8IDB4NiB8ICh0aGlyZEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweDdGRiAmJiAodGVtcENvZGVQb2ludCA8IDB4RDgwMCB8fCB0ZW1wQ29kZVBvaW50ID4gMHhERkZGKSkge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgNDpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIHRoaXJkQnl0ZSA9IGJ1ZltpICsgMl1cbiAgICAgICAgICBmb3VydGhCeXRlID0gYnVmW2kgKyAzXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwICYmICh0aGlyZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAoZm91cnRoQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4RikgPDwgMHgxMiB8IChzZWNvbmRCeXRlICYgMHgzRikgPDwgMHhDIHwgKHRoaXJkQnl0ZSAmIDB4M0YpIDw8IDB4NiB8IChmb3VydGhCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHhGRkZGICYmIHRlbXBDb2RlUG9pbnQgPCAweDExMDAwMCkge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChjb2RlUG9pbnQgPT09IG51bGwpIHtcbiAgICAgIC8vIHdlIGRpZCBub3QgZ2VuZXJhdGUgYSB2YWxpZCBjb2RlUG9pbnQgc28gaW5zZXJ0IGFcbiAgICAgIC8vIHJlcGxhY2VtZW50IGNoYXIgKFUrRkZGRCkgYW5kIGFkdmFuY2Ugb25seSAxIGJ5dGVcbiAgICAgIGNvZGVQb2ludCA9IDB4RkZGRFxuICAgICAgYnl0ZXNQZXJTZXF1ZW5jZSA9IDFcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA+IDB4RkZGRikge1xuICAgICAgLy8gZW5jb2RlIHRvIHV0ZjE2IChzdXJyb2dhdGUgcGFpciBkYW5jZSlcbiAgICAgIGNvZGVQb2ludCAtPSAweDEwMDAwXG4gICAgICByZXMucHVzaChjb2RlUG9pbnQgPj4+IDEwICYgMHgzRkYgfCAweEQ4MDApXG4gICAgICBjb2RlUG9pbnQgPSAweERDMDAgfCBjb2RlUG9pbnQgJiAweDNGRlxuICAgIH1cblxuICAgIHJlcy5wdXNoKGNvZGVQb2ludClcbiAgICBpICs9IGJ5dGVzUGVyU2VxdWVuY2VcbiAgfVxuXG4gIHJldHVybiBkZWNvZGVDb2RlUG9pbnRzQXJyYXkocmVzKVxufVxuXG4vLyBCYXNlZCBvbiBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8yMjc0NzI3Mi82ODA3NDIsIHRoZSBicm93c2VyIHdpdGhcbi8vIHRoZSBsb3dlc3QgbGltaXQgaXMgQ2hyb21lLCB3aXRoIDB4MTAwMDAgYXJncy5cbi8vIFdlIGdvIDEgbWFnbml0dWRlIGxlc3MsIGZvciBzYWZldHlcbnZhciBNQVhfQVJHVU1FTlRTX0xFTkdUSCA9IDB4MTAwMFxuXG5mdW5jdGlvbiBkZWNvZGVDb2RlUG9pbnRzQXJyYXkgKGNvZGVQb2ludHMpIHtcbiAgdmFyIGxlbiA9IGNvZGVQb2ludHMubGVuZ3RoXG4gIGlmIChsZW4gPD0gTUFYX0FSR1VNRU5UU19MRU5HVEgpIHtcbiAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsIGNvZGVQb2ludHMpIC8vIGF2b2lkIGV4dHJhIHNsaWNlKClcbiAgfVxuXG4gIC8vIERlY29kZSBpbiBjaHVua3MgdG8gYXZvaWQgXCJjYWxsIHN0YWNrIHNpemUgZXhjZWVkZWRcIi5cbiAgdmFyIHJlcyA9ICcnXG4gIHZhciBpID0gMFxuICB3aGlsZSAoaSA8IGxlbikge1xuICAgIHJlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFxuICAgICAgU3RyaW5nLFxuICAgICAgY29kZVBvaW50cy5zbGljZShpLCBpICs9IE1BWF9BUkdVTUVOVFNfTEVOR1RIKVxuICAgIClcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbmZ1bmN0aW9uIGFzY2lpU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgcmV0ID0gJydcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldICYgMHg3RilcbiAgfVxuICByZXR1cm4gcmV0XG59XG5cbmZ1bmN0aW9uIGJpbmFyeVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJldCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSlcbiAgfVxuICByZXR1cm4gcmV0XG59XG5cbmZ1bmN0aW9uIGhleFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcblxuICBpZiAoIXN0YXJ0IHx8IHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIGlmICghZW5kIHx8IGVuZCA8IDAgfHwgZW5kID4gbGVuKSBlbmQgPSBsZW5cblxuICB2YXIgb3V0ID0gJydcbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICBvdXQgKz0gdG9IZXgoYnVmW2ldKVxuICB9XG4gI
4244HJldHVybiBvdXRcbn1cblxuZnVuY3Rpb24gdXRmMTZsZVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGJ5dGVzID0gYnVmLnNsaWNlKHN0YXJ0LCBlbmQpXG4gIHZhciByZXMgPSAnJ1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgcmVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZXNbaV0gKyBieXRlc1tpICsgMV0gKiAyNTYpXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnNsaWNlID0gZnVuY3Rpb24gc2xpY2UgKHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIHN0YXJ0ID0gfn5zdGFydFxuICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCA/IGxlbiA6IH5+ZW5kXG5cbiAgaWYgKHN0YXJ0IDwgMCkge1xuICAgIHN0YXJ0ICs9IGxlblxuICAgIGlmIChzdGFydCA8IDApIHN0YXJ0ID0gMFxuICB9IGVsc2UgaWYgKHN0YXJ0ID4gbGVuKSB7XG4gICAgc3RhcnQgPSBsZW5cbiAgfVxuXG4gIGlmIChlbmQgPCAwKSB7XG4gICAgZW5kICs9IGxlblxuICAgIGlmIChlbmQgPCAwKSBlbmQgPSAwXG4gIH0gZWxzZSBpZiAoZW5kID4gbGVuKSB7XG4gICAgZW5kID0gbGVuXG4gIH1cblxuICBpZiAoZW5kIDwgc3RhcnQpIGVuZCA9IHN0YXJ0XG5cbiAgdmFyIG5ld0J1ZlxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICBuZXdCdWYgPSB0aGlzLnN1YmFycmF5KHN0YXJ0LCBlbmQpXG4gICAgbmV3QnVmLl9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgfSBlbHNlIHtcbiAgICB2YXIgc2xpY2VMZW4gPSBlbmQgLSBzdGFydFxuICAgIG5ld0J1ZiA9IG5ldyBCdWZmZXIoc2xpY2VMZW4sIHVuZGVmaW5lZClcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNsaWNlTGVuOyBpKyspIHtcbiAgICAgIG5ld0J1ZltpXSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBuZXdCdWZcbn1cblxuLypcbiAqIE5lZWQgdG8gbWFrZSBzdXJlIHRoYXQgYnVmZmVyIGlzbid0IHRyeWluZyB0byB3cml0ZSBvdXQgb2YgYm91bmRzLlxuICovXG5mdW5jdGlvbiBjaGVja09mZnNldCAob2Zmc2V0LCBleHQsIGxlbmd0aCkge1xuICBpZiAoKG9mZnNldCAlIDEpICE9PSAwIHx8IG9mZnNldCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdvZmZzZXQgaXMgbm90IHVpbnQnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gbGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVHJ5aW5nIHRvIGFjY2VzcyBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnRMRSA9IGZ1bmN0aW9uIHJlYWRVSW50TEUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIGldICogbXVsXG4gIH1cblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnRCRSA9IGZ1bmN0aW9uIHJlYWRVSW50QkUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG4gIH1cblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAtLWJ5dGVMZW5ndGhdXG4gIHZhciBtdWwgPSAxXG4gIHdoaWxlIChieXRlTGVuZ3RoID4gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIC0tYnl0ZUxlbmd0aF0gKiBtdWxcbiAgfVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDggPSBmdW5jdGlvbiByZWFkVUludDggKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAxLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIHRoaXNbb2Zmc2V0XVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZMRSA9IGZ1bmN0aW9uIHJlYWRVSW50MTZMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gdGhpc1tvZmZzZXRdIHwgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2QkUgPSBmdW5jdGlvbiByZWFkVUludDE2QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuICh0aGlzW29mZnNldF0gPDwgOCkgfCB0aGlzW29mZnNldCArIDFdXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkxFID0gZnVuY3Rpb24gcmVhZFVJbnQzMkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICgodGhpc1tvZmZzZXRdKSB8XG4gICAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KSB8XG4gICAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCAxNikpICtcbiAgICAgICh0aGlzW29mZnNldCArIDNdICogMHgxMDAwMDAwKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJCRSA9IGZ1bmN0aW9uIHJlYWRVSW50MzJCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdICogMHgxMDAwMDAwKSArXG4gICAgKCh0aGlzW29mZnNldCArIDFdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgOCkgfFxuICAgIHRoaXNbb2Zmc2V0ICsgM10pXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludExFID0gZnVuY3Rpb24gcmVhZEludExFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XVxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz
42440gdGhpc1tvZmZzZXQgKyBpXSAqIG11bFxuICB9XG4gIG11bCAqPSAweDgwXG5cbiAgaWYgKHZhbCA+PSBtdWwpIHZhbCAtPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aClcblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludEJFID0gZnVuY3Rpb24gcmVhZEludEJFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoXG4gIHZhciBtdWwgPSAxXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIC0taV1cbiAgd2hpbGUgKGkgPiAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgLS1pXSAqIG11bFxuICB9XG4gIG11bCAqPSAweDgwXG5cbiAgaWYgKHZhbCA+PSBtdWwpIHZhbCAtPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aClcblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDggPSBmdW5jdGlvbiByZWFkSW50OCAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDEsIHRoaXMubGVuZ3RoKVxuICBpZiAoISh0aGlzW29mZnNldF0gJiAweDgwKSkgcmV0dXJuICh0aGlzW29mZnNldF0pXG4gIHJldHVybiAoKDB4ZmYgLSB0aGlzW29mZnNldF0gKyAxKSAqIC0xKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkxFID0gZnVuY3Rpb24gcmVhZEludDE2TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XSB8ICh0aGlzW29mZnNldCArIDFdIDw8IDgpXG4gIHJldHVybiAodmFsICYgMHg4MDAwKSA/IHZhbCB8IDB4RkZGRjAwMDAgOiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZCRSA9IGZ1bmN0aW9uIHJlYWRJbnQxNkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIDFdIHwgKHRoaXNbb2Zmc2V0XSA8PCA4KVxuICByZXR1cm4gKHZhbCAmIDB4ODAwMCkgPyB2YWwgfCAweEZGRkYwMDAwIDogdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDMyTEUgPSBmdW5jdGlvbiByZWFkSW50MzJMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdKSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOCkgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgM10gPDwgMjQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDMyQkUgPSBmdW5jdGlvbiByZWFkSW50MzJCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdIDw8IDI0KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCA4KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgM10pXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0TEUgPSBmdW5jdGlvbiByZWFkRmxvYXRMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgdHJ1ZSwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0QkUgPSBmdW5jdGlvbiByZWFkRmxvYXRCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgZmFsc2UsIDIzLCA0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVMRSA9IGZ1bmN0aW9uIHJlYWREb3VibGVMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDgsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgdHJ1ZSwgNTIsIDgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUJFID0gZnVuY3Rpb24gcmVhZERvdWJsZUJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgOCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCBmYWxzZSwgNTIsIDgpXG59XG5cbmZ1bmN0aW9uIGNoZWNrSW50IChidWYsIHZhbHVlLCBvZmZzZXQsIGV4dCwgbWF4LCBtaW4pIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSkgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJidWZmZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyIGluc3RhbmNlJylcbiAgaWYgKHZhbHVlID4gbWF4IHx8IHZhbHVlIDwgbWluKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXCJ2YWx1ZVwiIGFyZ3VtZW50IGlzIG91dCBvZiBib3VuZHMnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnRMRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBtYXhCeXRlcyA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKSAtIDFcbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBtYXhCeXRlcywgMClcbiAgfVxuXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybi
4244BvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50QkUgPSBmdW5jdGlvbiB3cml0ZVVJbnRCRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBtYXhCeXRlcyA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKSAtIDFcbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBtYXhCeXRlcywgMClcbiAgfVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdGhpc1tvZmZzZXQgKyBpXSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoLS1pID49IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50OCA9IGZ1bmN0aW9uIHdyaXRlVUludDggKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMSwgMHhmZiwgMClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkgdmFsdWUgPSBNYXRoLmZsb29yKHZhbHVlKVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgMVxufVxuXG5mdW5jdGlvbiBvYmplY3RXcml0ZVVJbnQxNiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmYgKyB2YWx1ZSArIDFcbiAgZm9yICh2YXIgaSA9IDAsIGogPSBNYXRoLm1pbihidWYubGVuZ3RoIC0gb2Zmc2V0LCAyKTsgaSA8IGo7IGkrKykge1xuICAgIGJ1ZltvZmZzZXQgKyBpXSA9ICh2YWx1ZSAmICgweGZmIDw8ICg4ICogKGxpdHRsZUVuZGlhbiA/IGkgOiAxIC0gaSkpKSkgPj4+XG4gICAgICAobGl0dGxlRW5kaWFuID8gaSA6IDEgLSBpKSAqIDhcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQxNkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVVSW50MTZCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweGZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5mdW5jdGlvbiBvYmplY3RXcml0ZVVJbnQzMiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmZmZmZmICsgdmFsdWUgKyAxXG4gIGZvciAodmFyIGkgPSAwLCBqID0gTWF0aC5taW4oYnVmLmxlbmd0aCAtIG9mZnNldCwgNCk7IGkgPCBqOyBpKyspIHtcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSAodmFsdWUgPj4+IChsaXR0bGVFbmRpYW4gPyBpIDogMyAtIGkpICogOCkgJiAweGZmXG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkxFID0gZnVuY3Rpb24gd3JpdGVVSW50MzJMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweGZmZmZmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50TEUgPSBmdW5jdGlvbiB3cml0ZUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gMFxuICB2YXIgbXVsID0gMVxuICB2YXIgc3ViID0gMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICBpZiAodmFsdWUgPCAwICYmIHN1YiA9PT0gMCAmJiB0aGlzW29mZnNldCArIGkgLSAxXSAhPT0gMCkge1xuICAgICAgc3ViID0gMVxuICAgIH1cbiAgICB0aGlzW29mZnNldCArIGldID0gKCh2YWx1ZSAvIG11bCkgPj4gMCkgLSBzdWIgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50QkUgPSBmdW5jdGlvbiB3cml0ZUludEJFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHN1YiA9IDBcbiAgdGhpc1tvZmZzZXQgKyBpXSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoLS1pID49IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICBpZiAodmFsdWUgPCAwICYmIHN1YiA9PT0gMCAmJiB0aGlzW29mZnNldCArIGkgKyAxXSAhPT0gMCkge1xuICAgICAgc3ViID0gMVxuICAgIH1cbiAgICB0aGlzW29mZnNldCArIGldID0gKCh2YWx1ZSAvIG11bCkgPj4gMCkgLSBzdWIgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50OCA9IGZ1bmN0aW9uIHdyaXRlSW50OCAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAxLCAweDdmLCAtMHg4MClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkgdmFsdWUgPSBNYXRoLmZsb29yKHZhbHVlKVxuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmYgKyB2YWx1ZSArIDFcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2TEUgPSBmdW5jdGlvbiB3cml0ZUludDE2TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHg3ZmZmLCAtMHg4MDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZCRSA9IGZ1bmN0aW9uIHdyaXRlSW50MTZCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweDdmZmYsIC0weDgwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJMRSA9IGZ1bmN0aW9uIHdyaXRlSW50MzJMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgPj4+IDI0KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZUludDMyQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHg3ZmZmZmZmZiwgLTB4ODAwMDAwMDApXG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZmZmZmZmZiArIHZhbHVlICsgMVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDI0KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuZnVuY3Rpb24gY2hlY2tJRUVFNzU0IChidWYsIHZhbHVlLCBvZmZzZXQsIGV4dCwgbWF4LCBtaW4pIHtcbiAgaWYgKG9mZnNldCArIGV4dCA+IGJ1Zi5sZW5ndGgpIHR
4244ocm93IG5ldyBSYW5nZUVycm9yKCdJbmRleCBvdXQgb2YgcmFuZ2UnKVxuICBpZiAob2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbmZ1bmN0aW9uIHdyaXRlRmxvYXQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgNCwgMy40MDI4MjM0NjYzODUyODg2ZSszOCwgLTMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgpXG4gIH1cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgMjMsIDQpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdExFID0gZnVuY3Rpb24gd3JpdGVGbG9hdExFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0QkUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gd3JpdGVEb3VibGUgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgOCwgMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgsIC0xLjc5NzY5MzEzNDg2MjMxNTdFKzMwOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCA1MiwgOClcbiAgcmV0dXJuIG9mZnNldCArIDhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUxFID0gZnVuY3Rpb24gd3JpdGVEb3VibGVMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlQkUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG4vLyBjb3B5KHRhcmdldEJ1ZmZlciwgdGFyZ2V0U3RhcnQ9MCwgc291cmNlU3RhcnQ9MCwgc291cmNlRW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbiBjb3B5ICh0YXJnZXQsIHRhcmdldFN0YXJ0LCBzdGFydCwgZW5kKSB7XG4gIGlmICghc3RhcnQpIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCAmJiBlbmQgIT09IDApIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXRTdGFydCA+PSB0YXJnZXQubGVuZ3RoKSB0YXJnZXRTdGFydCA9IHRhcmdldC5sZW5ndGhcbiAgaWYgKCF0YXJnZXRTdGFydCkgdGFyZ2V0U3RhcnQgPSAwXG4gIGlmIChlbmQgPiAwICYmIGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIC8vIENvcHkgMCBieXRlczsgd2UncmUgZG9uZVxuICBpZiAoZW5kID09PSBzdGFydCkgcmV0dXJuIDBcbiAgaWYgKHRhcmdldC5sZW5ndGggPT09IDAgfHwgdGhpcy5sZW5ndGggPT09IDApIHJldHVybiAwXG5cbiAgLy8gRmF0YWwgZXJyb3IgY29uZGl0aW9uc1xuICBpZiAodGFyZ2V0U3RhcnQgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3RhcmdldFN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICB9XG4gIGlmIChzdGFydCA8IDAgfHwgc3RhcnQgPj0gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgaWYgKGVuZCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VFbmQgb3V0IG9mIGJvdW5kcycpXG5cbiAgLy8gQXJlIHdlIG9vYj9cbiAgaWYgKGVuZCA+IHRoaXMubGVuZ3RoKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0Lmxlbmd0aCAtIHRhcmdldFN0YXJ0IDwgZW5kIC0gc3RhcnQpIHtcbiAgICBlbmQgPSB0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0U3RhcnQgKyBzdGFydFxuICB9XG5cbiAgdmFyIGxlbiA9IGVuZCAtIHN0YXJ0XG4gIHZhciBpXG5cbiAgaWYgKHRoaXMgPT09IHRhcmdldCAmJiBzdGFydCA8IHRhcmdldFN0YXJ0ICYmIHRhcmdldFN0YXJ0IDwgZW5kKSB7XG4gICAgLy8gZGVzY2VuZGluZyBjb3B5IGZyb20gZW5kXG4gICAgZm9yIChpID0gbGVuIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIHRhcmdldFtpICsgdGFyZ2V0U3RhcnRdID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9IGVsc2UgaWYgKGxlbiA8IDEwMDAgfHwgIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gYXNjZW5kaW5nIGNvcHkgZnJvbSBzdGFydFxuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRTdGFydF0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgVWludDhBcnJheS5wcm90b3R5cGUuc2V0LmNhbGwoXG4gICAgICB0YXJnZXQsXG4gICAgICB0aGlzLnN1YmFycmF5KHN0YXJ0LCBzdGFydCArIGxlbiksXG4gICAgICB0YXJnZXRTdGFydFxuICAgIClcbiAgfVxuXG4gIHJldHVybiBsZW5cbn1cblxuLy8gVXNhZ2U6XG4vLyAgICBidWZmZXIuZmlsbChudW1iZXJbLCBvZmZzZXRbLCBlbmRdXSlcbi8vICAgIGJ1ZmZlci5maWxsKGJ1ZmZlclssIG9mZnNldFssIGVuZF1dKVxuLy8gICAgYnVmZmVyLmZpbGwoc3RyaW5nWywgb2Zmc2V0WywgZW5kXV1bLCBlbmNvZGluZ10pXG5CdWZmZXIucHJvdG90eXBlLmZpbGwgPSBmdW5jdGlvbiBmaWxsICh2YWwsIHN0YXJ0LCBlbmQsIGVuY29kaW5nKSB7XG4gIC8vIEhhbmRsZSBzdHJpbmcgY2FzZXM6XG4gIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgIGlmICh0eXBlb2Ygc3RhcnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlbmNvZGluZyA9IHN0YXJ0XG4gICAgICBzdGFydCA9IDBcbiAgICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZW5kID09PSAnc3RyaW5nJykge1xuICAgICAgZW5jb2RpbmcgPSBlbmRcbiAgICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gICAgfVxuICAgIGlmICh2YWwubGVuZ3RoID09PSAxKSB7XG4gICAgICB2Y
4244XIgY29kZSA9IHZhbC5jaGFyQ29kZUF0KDApXG4gICAgICBpZiAoY29kZSA8IDI1Nikge1xuICAgICAgICB2YWwgPSBjb2RlXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlbmNvZGluZyAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2VuY29kaW5nIG11c3QgYmUgYSBzdHJpbmcnKVxuICAgIH1cbiAgICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJyAmJiAhQnVmZmVyLmlzRW5jb2RpbmcoZW5jb2RpbmcpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgdmFsID0gdmFsICYgMjU1XG4gIH1cblxuICAvLyBJbnZhbGlkIHJhbmdlcyBhcmUgbm90IHNldCB0byBhIGRlZmF1bHQsIHNvIGNhbiByYW5nZSBjaGVjayBlYXJseS5cbiAgaWYgKHN0YXJ0IDwgMCB8fCB0aGlzLmxlbmd0aCA8IHN0YXJ0IHx8IHRoaXMubGVuZ3RoIDwgZW5kKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ091dCBvZiByYW5nZSBpbmRleCcpXG4gIH1cblxuICBpZiAoZW5kIDw9IHN0YXJ0KSB7XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIHN0YXJ0ID0gc3RhcnQgPj4+IDBcbiAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyB0aGlzLmxlbmd0aCA6IGVuZCA+Pj4gMFxuXG4gIGlmICghdmFsKSB2YWwgPSAwXG5cbiAgdmFyIGlcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgZm9yIChpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgICAgdGhpc1tpXSA9IHZhbFxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgYnl0ZXMgPSBCdWZmZXIuaXNCdWZmZXIodmFsKVxuICAgICAgPyB2YWxcbiAgICAgIDogdXRmOFRvQnl0ZXMobmV3IEJ1ZmZlcih2YWwsIGVuY29kaW5nKS50b1N0cmluZygpKVxuICAgIHZhciBsZW4gPSBieXRlcy5sZW5ndGhcbiAgICBmb3IgKGkgPSAwOyBpIDwgZW5kIC0gc3RhcnQ7IGkrKykge1xuICAgICAgdGhpc1tpICsgc3RhcnRdID0gYnl0ZXNbaSAlIGxlbl1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpc1xufVxuXG4vLyBIRUxQRVIgRlVOQ1RJT05TXG4vLyA9PT09PT09PT09PT09PT09XG5cbnZhciBJTlZBTElEX0JBU0U2NF9SRSA9IC9bXitcXC8wLTlBLVphLXotX10vZ1xuXG5mdW5jdGlvbiBiYXNlNjRjbGVhbiAoc3RyKSB7XG4gIC8vIE5vZGUgc3RyaXBzIG91dCBpbnZhbGlkIGNoYXJhY3RlcnMgbGlrZSBcXG4gYW5kIFxcdCBmcm9tIHRoZSBzdHJpbmcsIGJhc2U2NC1qcyBkb2VzIG5vdFxuICBzdHIgPSBzdHJpbmd0cmltKHN0cikucmVwbGFjZShJTlZBTElEX0JBU0U2NF9SRSwgJycpXG4gIC8vIE5vZGUgY29udmVydHMgc3RyaW5ncyB3aXRoIGxlbmd0aCA8IDIgdG8gJydcbiAgaWYgKHN0ci5sZW5ndGggPCAyKSByZXR1cm4gJydcbiAgLy8gTm9kZSBhbGxvd3MgZm9yIG5vbi1wYWRkZWQgYmFzZTY0IHN0cmluZ3MgKG1pc3NpbmcgdHJhaWxpbmcgPT09KSwgYmFzZTY0LWpzIGRvZXMgbm90XG4gIHdoaWxlIChzdHIubGVuZ3RoICUgNCAhPT0gMCkge1xuICAgIHN0ciA9IHN0ciArICc9J1xuICB9XG4gIHJldHVybiBzdHJcbn1cblxuZnVuY3Rpb24gc3RyaW5ndHJpbSAoc3RyKSB7XG4gIGlmIChzdHIudHJpbSkgcmV0dXJuIHN0ci50cmltKClcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9eXFxzK3xcXHMrJC9nLCAnJylcbn1cblxuZnVuY3Rpb24gdG9IZXggKG4pIHtcbiAgaWYgKG4gPCAxNikgcmV0dXJuICcwJyArIG4udG9TdHJpbmcoMTYpXG4gIHJldHVybiBuLnRvU3RyaW5nKDE2KVxufVxuXG5mdW5jdGlvbiB1dGY4VG9CeXRlcyAoc3RyaW5nLCB1bml0cykge1xuICB1bml0cyA9IHVuaXRzIHx8IEluZmluaXR5XG4gIHZhciBjb2RlUG9pbnRcbiAgdmFyIGxlbmd0aCA9IHN0cmluZy5sZW5ndGhcbiAgdmFyIGxlYWRTdXJyb2dhdGUgPSBudWxsXG4gIHZhciBieXRlcyA9IFtdXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgIGNvZGVQb2ludCA9IHN0cmluZy5jaGFyQ29kZUF0KGkpXG5cbiAgICAvLyBpcyBzdXJyb2dhdGUgY29tcG9uZW50XG4gICAgaWYgKGNvZGVQb2ludCA+IDB4RDdGRiAmJiBjb2RlUG9pbnQgPCAweEUwMDApIHtcbiAgICAgIC8vIGxhc3QgY2hhciB3YXMgYSBsZWFkXG4gICAgICBpZiAoIWxlYWRTdXJyb2dhdGUpIHtcbiAgICAgICAgLy8gbm8gbGVhZCB5ZXRcbiAgICAgICAgaWYgKGNvZGVQb2ludCA+IDB4REJGRikge1xuICAgICAgICAgIC8vIHVuZXhwZWN0ZWQgdHJhaWxcbiAgICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9IGVsc2UgaWYgKGkgKyAxID09PSBsZW5ndGgpIHtcbiAgICAgICAgICAvLyB1bnBhaXJlZCBsZWFkXG4gICAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHZhbGlkIGxlYWRcbiAgICAgICAgbGVhZFN1cnJvZ2F0ZSA9IGNvZGVQb2ludFxuXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIDIgbGVhZHMgaW4gYSByb3dcbiAgICAgIGlmIChjb2RlUG9pbnQgPCAweERDMDApIHtcbiAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgIGxlYWRTdXJyb2dhdGUgPSBjb2RlUG9pbnRcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgLy8gdmFsaWQgc3Vycm9nYXRlIHBhaXJcbiAgICAgIGNvZGVQb2ludCA9IChsZWFkU3Vycm9nYXRlIC0gMHhEODAwIDw8IDEwIHwgY29kZVBvaW50IC0gMHhEQzAwKSArIDB4MTAwMDBcbiAgICB9IGVsc2UgaWYgKGxlYWRTdXJyb2dhdGUpIHtcbiAgICAgIC8vIHZhbGlkIGJtcCBjaGFyLCBidXQgbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgIH1cblxuICAgIGxlYWRTdXJyb2dhdGUgPSBudWxsXG5cbiAgICAvLyBlbmNvZGUgdXRmOFxuICAgIGlmIChjb2RlUG9pbnQgPCAweDgwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDEpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goY29kZVBvaW50KVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHg4MDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMikgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29
4244kZVBvaW50ID4+IDB4NiB8IDB4QzAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDEwMDAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDMpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgfCAweEUwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2ICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDExMDAwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSA0KSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHgxMiB8IDB4RjAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY29kZSBwb2ludCcpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVzXG59XG5cbmZ1bmN0aW9uIGFzY2lpVG9CeXRlcyAoc3RyKSB7XG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykge1xuICAgIC8vIE5vZGUncyBjb2RlIHNlZW1zIHRvIGJlIGRvaW5nIHRoaXMgYW5kIG5vdCAmIDB4N0YuLlxuICAgIGJ5dGVBcnJheS5wdXNoKHN0ci5jaGFyQ29kZUF0KGkpICYgMHhGRilcbiAgfVxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVUb0J5dGVzIChzdHIsIHVuaXRzKSB7XG4gIHZhciBjLCBoaSwgbG9cbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKCh1bml0cyAtPSAyKSA8IDApIGJyZWFrXG5cbiAgICBjID0gc3RyLmNoYXJDb2RlQXQoaSlcbiAgICBoaSA9IGMgPj4gOFxuICAgIGxvID0gYyAlIDI1NlxuICAgIGJ5dGVBcnJheS5wdXNoKGxvKVxuICAgIGJ5dGVBcnJheS5wdXNoKGhpKVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiBiYXNlNjRUb0J5dGVzIChzdHIpIHtcbiAgcmV0dXJuIGJhc2U2NC50b0J5dGVBcnJheShiYXNlNjRjbGVhbihzdHIpKVxufVxuXG5mdW5jdGlvbiBibGl0QnVmZmVyIChzcmMsIGRzdCwgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgIGlmICgoaSArIG9mZnNldCA+PSBkc3QubGVuZ3RoKSB8fCAoaSA+PSBzcmMubGVuZ3RoKSkgYnJlYWtcbiAgICBkc3RbaSArIG9mZnNldF0gPSBzcmNbaV1cbiAgfVxuICByZXR1cm4gaVxufVxuXG5mdW5jdGlvbiBpc25hbiAodmFsKSB7XG4gIHJldHVybiB2YWwgIT09IHZhbCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXNlbGYtY29tcGFyZVxufVxuIiwiZXhwb3J0cy5yZWFkID0gZnVuY3Rpb24gKGJ1ZmZlciwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG1cbiAgdmFyIGVMZW4gPSBuQnl0ZXMgKiA4IC0gbUxlbiAtIDFcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDFcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxXG4gIHZhciBuQml0cyA9IC03XG4gIHZhciBpID0gaXNMRSA/IChuQnl0ZXMgLSAxKSA6IDBcbiAgdmFyIGQgPSBpc0xFID8gLTEgOiAxXG4gIHZhciBzID0gYnVmZmVyW29mZnNldCArIGldXG5cbiAgaSArPSBkXG5cbiAgZSA9IHMgJiAoKDEgPDwgKC1uQml0cykpIC0gMSlcbiAgcyA+Pj0gKC1uQml0cylcbiAgbkJpdHMgKz0gZUxlblxuICBmb3IgKDsgbkJpdHMgPiAwOyBlID0gZSAqIDI1NiArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIG0gPSBlICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpXG4gIGUgPj49ICgtbkJpdHMpXG4gIG5CaXRzICs9IG1MZW5cbiAgZm9yICg7IG5CaXRzID4gMDsgbSA9IG0gKiAyNTYgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cblxuICBpZiAoZSA9PT0gMCkge1xuICAgIGUgPSAxIC0gZUJpYXNcbiAgfSBlbHNlIGlmIChlID09PSBlTWF4KSB7XG4gICAgcmV0dXJuIG0gPyBOYU4gOiAoKHMgPyAtMSA6IDEpICogSW5maW5pdHkpXG4gIH0gZWxzZSB7XG4gICAgbSA9IG0gKyBNYXRoLnBvdygyLCBtTGVuKVxuICAgIGUgPSBlIC0gZUJpYXNcbiAgfVxuICByZXR1cm4gKHMgPyAtMSA6IDEpICogbSAqIE1hdGgucG93KDIsIGUgLSBtTGVuKVxufVxuXG5leHBvcnRzLndyaXRlID0gZnVuY3Rpb24gKGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtLCBjXG4gIHZhciBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxXG4gIHZhciBlTWF4ID0gKDEgPDwgZUxlbikgLSAxXG4gIHZhciBlQmlhcyA9IGVNYXggPj4gMVxuICB2YXIgcnQgPSAobUxlbiA9PT0gMjMgPyBNYXRoLnBvdygyLCAtMjQpIC0gTWF0aC5wb3coMiwgLTc3KSA6IDApXG4gIHZhciBpID0gaXNMRSA/IDAgOiAobkJ5dGVzIC0gMSlcbiAgdmFyIGQgPSBpc0xFID8gMSA6IC0xXG4gIHZhciBzID0gdmFsdWUgPCAwIHx8ICh2YWx1ZSA9PT0gMCAmJiAxIC8gdmFsdWUgPCAwKSA/IDEgOiAwXG5cbiAgdmFsdWUgPSBNYXRoLmFicyh2YWx1ZSlcblxuICBpZiAoaXNOYU4odmFsdWUpIHx8IHZhbHVlID09PSBJbmZpbml0eSkge1xuICAgIG0gPSBpc05hTih2YWx1ZSkgPyAxIDogMFxuICAgIGUgPSBlTWF4XG4gIH0gZWxzZSB7XG4gICAgZSA9IE1hdGguZmxvb3IoTWF0aC5sb2codmFsdWUpIC8gTWF0aC5MTjIpXG4gICAgaWYgKHZhbHVlICogKGMgPSBNYXRoLnBvdygyLCAtZSkpIDwgMSkge1xuICAgICAgZS0tXG4gICAgICBjICo9IDJcbiAgICB9XG4gICAgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICB2YWx1ZSArPSBydCAvIGNcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWUgKz0gcnQgKiBNYXRoLnBvdygyLCAxIC0gZUJpYXMpXG4gICAgfVxuICAgIGlmICh2YWx1ZSAqIGMgPj0gMikge1xuICAgICAgZSsrXG4gICAgICBjIC89IDJcbiAgICB9XG5cbiAgICBpZiAoZSArIGVCaWFzID49IGVNYXgpIHtcbiAgICAgIG0gPSAwXG4gICAgICBlID0gZU1heFxuICAgIH0gZWxzZSBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIG0gPSAodmFsdWUgKiBjIC0gMSkgKiBNYXRoLnBvdygyLCBtTGVuKVxuICAgICAgZSA9IGUgKyBlQmlhc1xuICAgIH0gZWxzZSB7XG4gICAgICBtID0gdmFsdWUgKiBNYXRoLnBvdygyLCBlQmlhcyAtIDEpICogTWF0aC5wb3coMiwgbUxlbilcbiAgICAgIGUgPSAwXG4gICAgfVxuICB9XG5cbiAgZm9yICg7IG1MZW4gPj0gODsgYnVmZmVyW29mZnNldCArIGldID0gbSAmID
4244B4ZmYsIGkgKz0gZCwgbSAvPSAyNTYsIG1MZW4gLT0gOCkge31cblxuICBlID0gKGUgPDwgbUxlbikgfCBtXG4gIGVMZW4gKz0gbUxlblxuICBmb3IgKDsgZUxlbiA+IDA7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IGUgJiAweGZmLCBpICs9IGQsIGUgLz0gMjU2LCBlTGVuIC09IDgpIHt9XG5cbiAgYnVmZmVyW29mZnNldCArIGkgLSBkXSB8PSBzICogMTI4XG59XG4iLCJ2YXIgdG9TdHJpbmcgPSB7fS50b1N0cmluZztcblxubW9kdWxlLmV4cG9ydHMgPSBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uIChhcnIpIHtcbiAgcmV0dXJuIHRvU3RyaW5nLmNhbGwoYXJyKSA9PSAnW29iamVjdCBBcnJheV0nO1xufTtcbiJdfQ==
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.