Skip to content

Instantly share code, notes, and snippets.

@jtenner
Created April 21, 2016 14:51
Show Gist options
  • Save jtenner/ce0ae98f5f1cfeead9502808c5ae9f93 to your computer and use it in GitHub Desktop.
Save jtenner/ce0ae98f5f1cfeead9502808c5ae9f93 to your computer and use it in GitHub Desktop.
requirebin sketch
var e2d = require('e2d');
var r = e2d.Renderer.create(400, 400);
var helloWorld = e2d.fillText('Hello World');
r.ready();
r.on('frame',
() => r.render(
e2d.clearRect(400, 400),
e2d.translate(200, 200,
helloWorld
)
)
);
setTimeout(function(){
;require=(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){
// Source: http://jsfiddle.net/vWx8V/
// http://stackoverflow.com/questions/5603195/full-list-of-javascript-keycodes
/**
* Conenience method returns corresponding value for given keyName or keyCode.
*
* @param {Mixed} keyCode {Number} or keyName {String}
* @return {Mixed}
* @api public
*/
exports = module.exports = function(searchInput) {
// Keyboard Events
if (searchInput && 'object' === typeof searchInput) {
var hasKeyCode = searchInput.which || searchInput.keyCode || searchInput.charCode
if (hasKeyCode) searchInput = hasKeyCode
}
// Numbers
if ('number' === typeof searchInput) return names[searchInput]
// Everything else (cast to string)
var search = String(searchInput)
// check codes
var foundNamedKey = codes[search.toLowerCase()]
if (foundNamedKey) return foundNamedKey
// check aliases
var foundNamedKey = aliases[search.toLowerCase()]
if (foundNamedKey) return foundNamedKey
// weird character?
if (search.length === 1) return search.charCodeAt(0)
return undefined
}
/**
* Get by name
*
* exports.code['enter'] // => 13
*/
var codes = exports.code = exports.codes = {
'backspace': 8,
'tab': 9,
'enter': 13,
'shift': 16,
'ctrl': 17,
'alt': 18,
'pause/break': 19,
'caps lock': 20,
'esc': 27,
'space': 32,
'page up': 33,
'page down': 34,
'end': 35,
'home': 36,
'left': 37,
'up': 38,
'right': 39,
'down': 40,
'insert': 45,
'delete': 46,
'command': 91,
'right click': 93,
'numpad *': 106,
'numpad +': 107,
'numpad -': 109,
'numpad .': 110,
'numpad /': 111,
'num lock': 144,
'scroll lock': 145,
'my computer': 182,
'my calculator': 183,
';': 186,
'=': 187,
',': 188,
'-': 189,
'.': 190,
'/': 191,
'`': 192,
'[': 219,
'\\': 220,
']': 221,
"'": 222,
}
// Helper aliases
var aliases = exports.aliases = {
'windows': 91,
'⇧': 16,
'⌥': 18,
'⌃': 17,
'⌘': 91,
'ctl': 17,
'control': 17,
'option': 18,
'pause': 19,
'break': 19,
'caps': 20,
'return': 13,
'escape': 27,
'spc': 32,
'pgup': 33,
'pgdn': 33,
'ins': 45,
'del': 46,
'cmd': 91
}
/*!
* Programatically add the following
*/
// lower case chars
for (i = 97; i < 123; i++) codes[String.fromCharCode(i)] = i - 32
// numbers
for (var i = 48; i < 58; i++) codes[i - 48] = i
// function keys
for (i = 1; i < 13; i++) codes['f'+i] = i + 111
// numpad keys
for (i = 0; i < 10; i++) codes['numpad '+i] = i + 96
/**
* Get by code
*
* exports.name[13] // => 'Enter'
*/
var names = exports.names = exports.title = {} // title for backward compat
// Create reverse mapping
for (i in codes) names[codes[i]] = i
// Add aliases
for (var alias in aliases) {
codes[alias] = aliases[alias]
}
},{}],2:[function(require,module,exports){
module.exports = function (point, vs) {
// ray-casting algorithm based on
// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
var x = point[0], y = point[1];
var inside = false;
for (var i = 0, j = vs.length - 1; i < vs.length; j = i++) {
var xi = vs[i][0], yi = vs[i][1];
var xj = vs[j][0], yj = vs[j][1];
var intersect = ((yi > y) != (yj > y))
&& (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
if (intersect) inside = !inside;
}
return inside;
};
},{}],3:[function(require,module,exports){
//jshint worker: true, browser: true, node: true
'use strict';
function Canvas(width, height) {
var Renderer = require('./Renderer');
this.renderer = new Renderer(width, height, window.document.createElement('div'));
this.fillPattern = null;
this.skipPatternCreation = false;
return Object.seal(this);
}
Canvas.prototype.render = function render(children) {
var result = [],
i;
for (i = 0; i < arguments.length; i++) {
result.push(arguments[i]);
}
this.renderer.render(result);
if (!this.skipPatternCreation) {
this.fillPattern = this.renderer.ctx.createPattern(this.renderer.canvas, 'no-repeat');
}
return this;
};
Canvas.prototype.style = function style() {
var defs = [];
for (var i = 0; i < arguments.length; i++) {
defs.push(arguments[i]);
}
this.renderer.style.apply(this.renderer, defs);
return this;
};
Canvas.prototype.toImage = function toImage(imageID) {
return this.renderer.toImage();
};
Canvas.prototype.resize = function resize(width, height) {
this.renderer.resize(+width, +height);
return this;
};
Object.defineProperty(Canvas.prototype, 'height', {
get: function() {
return this.renderer.canvas.width;
},
enumerable: true,
configurable: false
});
Object.defineProperty(Canvas.prototype, 'width', {
get: function() {
return this.renderer.canvas.width;
},
enumerable: true,
configurable: false
});
Canvas.create = function create(width, height, id) {
return new Canvas(width, height, id);
};
Object.seal(Canvas);
Object.seal(Canvas.prototype);
module.exports = Canvas;
},{"./Renderer":6}],4:[function(require,module,exports){
//jshint node: true, browser: true, worker: true
'use strict';
var path = require('path'),
events = require('events'),
util = require('util');
util.inherits(Img, events.EventEmitter);
function Img() {
events.EventEmitter.call(this);
this.imageElement = null;
this.imagePattern = null;
this.imagePatternRepeat = null;
Object.seal(this);
}
Object.defineProperty(Img.prototype, 'src', {
set: function(val) {
var element = new Image();
this.imageElement = element;
element.src = val;
if (element.complete) { //firefox compatibility code
setTimeout(this.imageLoad.bind(this), 0);
} else {
element.onload = this.imageLoad.bind(this);
}
},
get: function() {
return this.imageElement.src;
}
});
Img.prototype.imageLoad = function imageLoad() {
var ctx = window.document.createElement('canvas').getContext('2d');
this.imagePattern = ctx.createPattern(this.imageElement, 'no-repeat');
this.imagePatternRepeat = ctx.createPattern(this.imageElement, 'repeat');
return this.emit('load', this);
};
Object.defineProperty(Img.prototype, 'width', {
enumerable: true,
get: function() {
return this.imageElement.width;
},
set: function(value) {
this.imageElement.width = value;
}
});
Object.defineProperty(Img.prototype, 'height', {
enumerable: true,
get: function() {
return this.imageElement.height;
},
set: function(value) {
this.imageElement.height = value;
}
});
Object.seal(Img);
Object.seal(Img.prototype);
module.exports = Img;
},{"events":59,"path":61,"util":64}],5:[function(require,module,exports){
//jshint node: true
'use strict';
function Instruction(type, props) {
this.type = type;
this.props = props;
Object.seal(this);
}
Object.seal(Instruction);
Object.seal(Instruction.prototype);
module.exports = Instruction;
},{}],6:[function(require,module,exports){
//jshint node: true, browser: true, worker: true
'use strict';
var createLinearGradient = require('./createLinearGradient'),
createRadialGradient = require('./createRadialGradient'),
events = require('events'),
util = require('util'),
keycode = require('keycode'),
transformPoints = require('./transformPoints'),
pointInPolygon = require('point-in-polygon'),
identity = [1, 0, 0, 1, 0, 0],
Img = require('./Img');
util.inherits(Renderer, events.EventEmitter);
function Renderer(width, height, parent, opts) {
events.EventEmitter.call(this);
opts = opts || {};
//virtual stack
this.transformStack = new Float64Array(
((opts.transformStackCount || 500) + 1) * 6 //properties
);
this.transformStackIndex = 6;
this.transformStack.set(identity);
this.fillStyleStack = [];
this.strokeStyleStack = [];
this.lineStyleStack = [];
this.textStyleStack = [];
this.shadowStyleStack = [];
this.globalAlphaStack = [];
this.imageSmoothingEnabledStack = [];
this.globalCompositeOperationStack = [];
this.pi2 = Math.PI * 2;
this.isReady = false;
this.mouseState = 'up';
this.mouseData = {
x: 0,
y: 0,
state: this.mouseState,
clicked: false,
activeRegions: []
};
this.lastMouseEvent = null;
this.ranMouseEvent = false;
this.mouseRegions = [];
this.activeRegions = [];
this.styleQueue = [];
//user input here
this.keyData = {};
this.touchData = {
touches: [],
ids: []
};
this.lastTouchEvent = null;
this.ranTouchEvent = false;
this.touchRegions = [];
//set parent
if (parent && parent.nodeType === 1) {
this.parent = parent;
} else {
this.parent = window.document.createElement('div');
this.parent.style.margin = '0 auto';
this.parent.style.width = width + 'px';
this.parent.style.height = height + 'px';
window.document.body.appendChild(this.parent);
}
//set width and height automatically
if (!width || width <= 0) {
width = window.innerWidth;
}
if (!height || height <= 0) {
height = window.innerHeight;
}
this.canvas = window.document.createElement('canvas');
//focusable canvas bugfix
this.canvas.tabIndex = 1;
this.ctx = this.canvas.getContext('2d');
this.canvas.width = width;
this.canvas.height = height;
this.parent.appendChild(this.canvas);
//hook mouse, keyboard, and keyboard events right away
this.hookMouseEvents();
this.hookKeyboardEvents();
this.hookTouchEvents();
this.boundHookRenderFunction = this.hookRender.bind(this);
Object.seal(this);
}
Renderer.prototype.render = function render(args) {
var i,
len,
child,
props,
type,
cache,
matrix = [1, 0, 0, 1, 0, 0],
sinr,
cosr,
ctx = this.ctx,
children = [],
concat = children.concat;
//flush the virtual stack
this.fillStyleStack.splice(0, this.fillStyleStack.length);
this.strokeStyleStack.splice(0, this.strokeStyleStack.length);
this.lineStyleStack.splice(0, this.lineStyleStack.length);
this.textStyleStack.splice(0, this.textStyleStack.length);
this.shadowStyleStack.splice(0, this.shadowStyleStack.length);
this.globalCompositeOperationStack.splice(0, this.globalCompositeOperationStack.length);
this.globalAlphaStack.splice(0, this.globalAlphaStack.length);
this.imageSmoothingEnabledStack.splice(0, this.imageSmoothingEnabledStack.length);
for (i = 0, len = arguments.length; i < len; i++) {
children.push(arguments[i]);
}
//loop over every child
for (i = 0, len = children.length; i < len; i++) {
child = children[i];
//flattening algorithm
if (child && child.constructor === Array) {
children = concat.apply([], children);
child = children[i];
while (child && child.constructor === Array) {
children = concat.apply([], children);
child = children[i];
}
len = children.length;
}
//child must be truthy
if (!child) {
continue;
}
//set props and type object
props = child.props;
type = child.type;
if (type === 'transform') {
matrix[0] = this.transformStack[this.transformStackIndex - 6];
matrix[1] = this.transformStack[this.transformStackIndex - 5];
matrix[2] = this.transformStack[this.transformStackIndex - 4];
matrix[3] = this.transformStack[this.transformStackIndex - 3];
matrix[4] = this.transformStack[this.transformStackIndex - 2];
matrix[5] = this.transformStack[this.transformStackIndex - 1];
this.transformStackIndex += 6;
if (this.transformStackIndex > this.transformStack.length) {
this.increaseTransformStackSize();
}
this.transformStack[this.transformStackIndex - 6] = //d
matrix[0] * props[0] + matrix[2] * props[1];
this.transformStack[this.transformStackIndex - 5] = //b
matrix[1] * props[0] + matrix[3] * props[1];
this.transformStack[this.transformStackIndex - 4] = //c
matrix[0] * props[2] + matrix[2] * props[3];
this.transformStack[this.transformStackIndex - 3] = //d
matrix[1] * props[2] + matrix[3] * props[3];
this.transformStack[this.transformStackIndex - 2] = //e
matrix[0] * props[4] + matrix[2] * props[5] + matrix[4];
this.transformStack[this.transformStackIndex - 1] = //f
matrix[1] * props[4] + matrix[3] * props[5] + matrix[5];
ctx.setTransform(
this.transformStack[this.transformStackIndex - 6],
this.transformStack[this.transformStackIndex - 5],
this.transformStack[this.transformStackIndex - 4],
this.transformStack[this.transformStackIndex - 3],
this.transformStack[this.transformStackIndex - 2],
this.transformStack[this.transformStackIndex - 1]
);
continue;
}
if (type === 'setTransform') {
this.transformStackIndex += 6;
if (this.transformStackIndex > this.transformStack.length) {
this.increaseTransformStackSize();
}
this.transformStack[this.transformStackIndex - 6] = props[0];//a
this.transformStack[this.transformStackIndex - 5] = props[1];//b
this.transformStack[this.transformStackIndex - 4] = props[2];//c
this.transformStack[this.transformStackIndex - 3] = props[3];//d
this.transformStack[this.transformStackIndex - 2] = props[4];//e
this.transformStack[this.transformStackIndex - 1] = props[5];//f
ctx.setTransform(props[0], props[1], props[2], props[3], props[4], props[5]);
continue;
}
if (type === 'scale') {
matrix[0] = this.transformStack[this.transformStackIndex - 6];
matrix[1] = this.transformStack[this.transformStackIndex - 5];
matrix[2] = this.transformStack[this.transformStackIndex - 4];
matrix[3] = this.transformStack[this.transformStackIndex - 3];
matrix[4] = this.transformStack[this.transformStackIndex - 2];
matrix[5] = this.transformStack[this.transformStackIndex - 1];
this.transformStackIndex += 6;
if (this.transformStackIndex > this.transformStack.length) {
this.increaseTransformStackSize();
}
this.transformStack[this.transformStackIndex - 6] = matrix[0] * props.x; //a
this.transformStack[this.transformStackIndex - 5] = matrix[1] * props.x; //b
this.transformStack[this.transformStackIndex - 4] = matrix[2] * props.y; //c
this.transformStack[this.transformStackIndex - 3] = matrix[3] * props.y; //d
this.transformStack[this.transformStackIndex - 2] = matrix[4]; //e
this.transformStack[this.transformStackIndex - 1] = matrix[5]; //f
ctx.setTransform(
this.transformStack[this.transformStackIndex - 6],
this.transformStack[this.transformStackIndex - 5],
this.transformStack[this.transformStackIndex - 4],
this.transformStack[this.transformStackIndex - 3],
this.transformStack[this.transformStackIndex - 2],
this.transformStack[this.transformStackIndex - 1]
);
continue;
}
if (type === 'translate') {
matrix[0] = this.transformStack[this.transformStackIndex - 6];
matrix[1] = this.transformStack[this.transformStackIndex - 5];
matrix[2] = this.transformStack[this.transformStackIndex - 4];
matrix[3] = this.transformStack[this.transformStackIndex - 3];
matrix[4] = this.transformStack[this.transformStackIndex - 2];
matrix[5] = this.transformStack[this.transformStackIndex - 1];
this.transformStackIndex += 6;
if (this.transformStackIndex > this.transformStack.length) {
this.increaseTransformStackSize();
}
this.transformStack[this.transformStackIndex - 6] = matrix[0]; //a
this.transformStack[this.transformStackIndex - 5] = matrix[1]; //b
this.transformStack[this.transformStackIndex - 4] = matrix[2]; //c
this.transformStack[this.transformStackIndex - 3] = matrix[3]; //d
this.transformStack[this.transformStackIndex - 2] = matrix[4] + matrix[0] * props.x + matrix[2] * props.y; //e
this.transformStack[this.transformStackIndex - 1] = matrix[5] + matrix[1] * props.x + matrix[3] * props.y; //f
ctx.setTransform(
this.transformStack[this.transformStackIndex - 6],
this.transformStack[this.transformStackIndex - 5],
this.transformStack[this.transformStackIndex - 4],
this.transformStack[this.transformStackIndex - 3],
this.transformStack[this.transformStackIndex - 2],
this.transformStack[this.transformStackIndex - 1]
);
continue;
}
if (type === 'rotate') {
matrix[0] = this.transformStack[this.transformStackIndex - 6];
matrix[1] = this.transformStack[this.transformStackIndex - 5];
matrix[2] = this.transformStack[this.transformStackIndex - 4];
matrix[3] = this.transformStack[this.transformStackIndex - 3];
matrix[4] = this.transformStack[this.transformStackIndex - 2];
matrix[5] = this.transformStack[this.transformStackIndex - 1];
cosr = Math.cos(props.r);
sinr = Math.sin(props.r);
this.transformStackIndex += 6;
if (this.transformStackIndex > this.transformStack.length) {
this.increaseTransformStackSize();
}
this.transformStack[this.transformStackIndex - 6] =
matrix[0] * cosr + matrix[2] * sinr; //a
this.transformStack[this.transformStackIndex - 5] =
matrix[1] * cosr + matrix[3] * sinr; //b
this.transformStack[this.transformStackIndex - 4] =
matrix[0] * -sinr + matrix[2] * cosr; //c
this.transformStack[this.transformStackIndex - 3] =
matrix[1] * -sinr + matrix[3] * cosr; //d
this.transformStack[this.transformStackIndex - 2] = matrix[4]; //e
this.transformStack[this.transformStackIndex - 1] = matrix[5];//f
ctx.setTransform(
this.transformStack[this.transformStackIndex - 6],
this.transformStack[this.transformStackIndex - 5],
this.transformStack[this.transformStackIndex - 4],
this.transformStack[this.transformStackIndex - 3],
this.transformStack[this.transformStackIndex - 2],
this.transformStack[this.transformStackIndex - 1]
);
continue;
}
if (type === 'restore') {
this.transformStackIndex -= 6;
matrix[0] = this.transformStack[this.transformStackIndex - 6];
matrix[1] = this.transformStack[this.transformStackIndex - 5];
matrix[2] = this.transformStack[this.transformStackIndex - 4];
matrix[3] = this.transformStack[this.transformStackIndex - 3];
matrix[4] = this.transformStack[this.transformStackIndex - 2];
matrix[5] = this.transformStack[this.transformStackIndex - 1];
ctx.setTransform(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
continue;
}
if (type === 'fillRect') {
ctx.fillRect(props.x, props.y, props.width, props.height);
continue;
}
if (type === 'strokeRect') {
ctx.strokeRect(props.x, props.y, props.width, props.height);
continue;
}
if (type === 'clearRect') {
ctx.clearRect(props.x, props.y, props.width, props.height);
continue;
}
if (type === 'rect') {
ctx.rect(props.x, props.y, props.width, props.height);
continue;
}
if (type === 'fillStyle') {
this.fillStyleStack.push(ctx.fillStyle);
ctx.fillStyle = props.value;
continue;
}
if (type === 'strokeStyle') {
this.strokeStyleStack.push(ctx.strokeStyle);
ctx.strokeStyle = props.value;
continue;
}
if (type === 'endFillStyle') {
ctx.fillStyle = this.fillStyleStack.pop();
continue;
}
if (type === 'endStrokeStyle') {
ctx.strokeStyle = this.strokeStyleStack.pop();
continue;
}
if (type === 'lineStyle') {
this.lineStyleStack.push({
lineWidth: ctx.lineWidth,
lineCap: ctx.lineCap,
lineJoin: ctx.lineJoin,
miterLimit: ctx.miterLimit,
lineDash: ctx.getLineDash(),
lineDashOffset: ctx.lineDashOffset
});
if (props.lineWidth !== null) {
ctx.lineWidth = props.lineWidth;
}
if (props.lineCap !== null) {
ctx.lineCap = props.lineCap;
}
if (props.lineJoin !== null) {
ctx.lineJoin = props.lineJoin;
}
if (props.miterLimit !== null) {
ctx.miterLimit = props.miterLimit;
}
if (props.lineDash.length > 0) {
ctx.setLineDash(props.lineDash);
}
if (props.lineDashOffset !== null) {
ctx.lineDashOffset = props.lineDashOffset;
}
continue;
}
if (type === 'endLineStyle') {
cache = this.lineStyleStack.pop();
ctx.lineWidth = cache.lineWidth;
ctx.lineCap = cache.lineCap;
ctx.lineJoin = cache.lineJoin;
ctx.miterLimit = cache.miterLimit;
ctx.setLineDash(cache.lineDash);
ctx.lineDashOffset = cache.lineDashOffset;
continue;
}
if (type === 'textStyle') {
this.textStyleStack.push({
font: ctx.font,
textAlign: ctx.textAlign,
textBaseline: ctx.textBaseline,
direction: ctx.direction
});
if (props.font !== null) {
ctx.font = props.font;
}
if (props.textAlign !== null) {
ctx.textAlign = props.textAlign;
}
if (props.textBaseline !== null) {
ctx.textBaseline = props.textBaseline;
}
if (props.lineJoin !== null) {
ctx.direction = props.direction;
}
continue;
}
if (type === 'endTextStyle') {
cache = this.textStyleStack.pop();
ctx.font = cache.font;
ctx.textAlign = cache.textAlign;
ctx.textBaseline = cache.textBaseline;
ctx.direction = cache.direction;
continue;
}
if (type === 'shadowStyle') {
this.shadowStyleStack.push({
shadowBlur: ctx.shadowBlur,
shadowColor: ctx.shadowColor,
shadowOffsetX: ctx.shadowOffsetX,
shadowOffsetY: ctx.shadowOffsetY
});
if (props.shadowBlur !== null) {
ctx.shadowBlur = props.shadowBlur;
}
if (props.shadowColor !== null) {
ctx.shadowColor = props.shadowColor;
}
if (props.shadowOffsetX !== null) {
ctx.shadowOffsetX = props.shadowOffsetX;
}
if (props.shadowOffsetY !== null) {
ctx.shadowOffsetY = props.shadowOffsetY;
}
continue;
}
if (type === 'endShadowStyle') {
cache = this.shadowStyleStack.pop();
ctx.shadowBlur = cache.shadowBlur;
ctx.shadowColor = cache.shadowColor;
ctx.shadowOffsetX = cache.shadowOffsetX;
ctx.shadowOffsetY = cache.shadowOffsetY;
continue;
}
if (type === 'strokeText') {
if (props.maxWidth) {
ctx.strokeText(props.text, props.x, props.y, props.maxWidth);
continue;
}
ctx.strokeText(props.text, props.x, props.y);
continue;
}
if (type === 'fillText') {
if (props.maxWidth) {
ctx.fillText(props.text, props.x, props.y, props.maxWidth);
continue;
}
ctx.fillText(props.text, props.x, props.y);
continue;
}
if (type === 'text') {
if (props.maxWidth !== 0) {
if (props.fill) {
ctx.fillText(props.text, props.x, props.y, props.maxWidth);
}
if (props.stroke) {
ctx.strokeText(props.text, props.x, props.y, props.maxWidth);
}
continue;
}
if (props.fill) {
ctx.fillText(props.text, props.x, props.y);
}
if (props.stroke) {
ctx.strokeText(props.text, props.x, props.y);
}
continue;
}
if (type === 'drawImage') {
if (!props.img) {
continue;
}
cache = props.img.constructor === Img ? props.img.imageElement || new Image() : props.img;
ctx.drawImage(cache || new Image(), props.dx, props.dy);
continue;
}
if (type === 'drawImageSize') {
if (!props.img) {
continue;
}
cache = props.img.constructor === Img ? props.img.imageElement || new Image() : props.img;
ctx.drawImage(cache, props.dx, props.dy, props.dWidth, props.dHeight);
continue;
}
if (type === 'drawImageSource') {
if (!props.img) {
continue;
}
cache = props.img.constructor === Img ? props.img.imageElement || new Image() : props.img;
ctx.drawImage(cache, props.sx, props.sy, props.sWidth, props.sHeight, props.dx, props.dy, props.dWidth, props.dHeight);
continue;
}
if (type === 'fillImagePattern') {
if (!props.img) {
continue;
}
ctx.fillStyle = props.img.imagePatternRepeat;
ctx.translate(props.dx, props.dy);
ctx.fillRect(0, 0, props.dWidth, props.dHeight);
ctx.restore();
continue;
}
if (type === 'fillImage') {
if (!props.img) {
continue;
}
cache = props.img.imageElement;
ctx.save();
ctx.fillStyle = props.img.imagePattern;
ctx.translate(props.dx, props.dy);
ctx.fillRect(0, 0, cache.width, cache.height);
ctx.restore();
continue;
}
if (type === 'fillImageSize') {
if (!props.img) {
continue;
}
cache = props.img.imageElement;
ctx.save();
ctx.fillStyle = props.img.imagePattern;
ctx.translate(props.dx, props.dy);
ctx.scale(props.dWidth / cache.width, props.dHeight / cache.height);
ctx.fillRect(0, 0, cache.width, cache.height);
ctx.restore();
continue;
}
if (type === 'fillImageSource') {
if (!props.img) {
continue;
}
ctx.save();
ctx.fillStyle = props.img.imagePattern;
ctx.translate(props.dx, props.dy);
ctx.scale(props.dWidth / props.sWidth, props.dHeight / props.sHeight);
ctx.translate(-props.sx, -props.sy);
ctx.fillRect(props.sx, props.sy, props.sWidth, props.sHeight);
ctx.restore();
continue;
}
if (type === 'fillCanvas') {
if (!props.img) {
continue;
}
cache = props.img;
ctx.save();
ctx.fillStyle = cache.fillPattern;
ctx.translate(props.dx, props.dy);
ctx.fillRect(0, 0, cache.width, cache.height);
ctx.restore();
continue;
}
if (type === 'fillCanvasSize') {
if (!props.img) {
continue;
}
cache = props.img;
ctx.save();
ctx.fillStyle = cache.fillPattern;
ctx.translate(props.dx, props.dy);
ctx.scale(props.dWidth / cache.width, props.dHeight / cache.height);
ctx.fillRect(0, 0, cache.width, cache.height);
ctx.restore();
continue;
}
if (type === 'fillCanvasSource') {
if (!props.img) {
continue;
}
ctx.save();
ctx.fillStyle = props.img.fillPattern;
ctx.translate(props.dx, props.dy);
ctx.scale(props.dWidth / props.sWidth, props.dHeight / props.sHeight);
ctx.translate(-props.sx, -props.sy);
ctx.fillRect(props.sx, props.sy, props.sWidth, props.sHeight);
ctx.restore();
continue;
}
if (type === 'drawCanvas') {
if (!props.img) {
continue;
}
ctx.drawImage(props.img.renderer.canvas, props.dx, props.dy);
continue;
}
if (type === 'drawCanvasSize') {
if (!props.img) {
continue;
}
ctx.drawImage(props.img.renderer.canvas, props.dx, props.dy, props.dWidth, props.dHeight);
continue;
}
if (type === 'drawCanvasSource') {
if (!props.img) {
continue;
}
ctx.drawImage(props.img.renderer.canvas, props.sx, props.sy, props.sWidth, props.sHeight, props.dx, props.dy, props.dWidth, props.dHeight);
continue;
}
if (type === 'strokeArc') {
ctx.beginPath();
ctx.arc(props.x, props.y, props.r, props.startAngle, props.endAngle);
ctx.closePath();
ctx.stroke();
continue;
}
if (type === 'strokeArc-counterclockwise') {
ctx.beginPath();
ctx.arc(props.x, props.y, props.r, props.startAngle, props.endAngle, true);
ctx.closePath();
ctx.stroke();
continue;
}
if (type === 'fillArc') {
ctx.beginPath();
ctx.arc(props.x, props.y, props.r, props.startAngle, props.endAngle);
ctx.closePath();
ctx.fill();
continue;
}
if (type === 'fillArc-counterclockwise') {
ctx.beginPath();
ctx.arc(props.x, props.y, props.r, props.startAngle, props.endAngle, true);
ctx.closePath();
ctx.fill();
continue;
}
if (type === 'moveTo') {
ctx.moveTo(props.x, props.y);
continue;
}
if (type === 'lineTo') {
ctx.lineTo(props.x, props.y);
continue;
}
if (type === 'bezierCurveTo') {
ctx.bezierCurveTo(props.cp1x, props.cp1y, props.cp2x, props.cp2y, props.x, props.y);
continue;
}
if (type === 'quadraticCurveTo') {
ctx.quadraticCurveTo(props.cpx, props.cpy, props.x, props.y);
continue;
}
if (type === 'anticlockwise-arc') {
ctx.arc(props.x, props.y, props.r, props.startAngle, props.endAngle, true);
continue;
}
if (type === 'arc') {
ctx.arc(props.x, props.y, props.r, props.startAngle, props.endAngle);
continue;
}
if (type === 'full-arc') {
ctx.arc(props.x, props.y, props.r, 0, this.pi2);
continue;
}
if (type === 'quick-arc') {
ctx.arc(0, 0, props.r, 0, this.pi2);
continue;
}
if (type === 'arcTo') {
ctx.arcTo(props.x1, props.y1, props.x2, props.y2, props.r);
continue;
}
if (type === 'anticlockwise-ellipse') {
this.save();
this.translate(props.x, props.y);
this.rotate(props.rotation);
this.scale(props.radiusX, props.radiusY);
this.arc(0, 0, 1, props.startAngle, props.endAngle, true);
this.restore();
continue;
}
if (type === 'ellipse') {
this.save();
this.translate(props.x, props.y);
this.rotate(props.rotation);
this.scale(props.radiusX, props.radiusY);
this.arc(0, 0, 1, props.startAngle, props.endAngle);
this.restore();
continue;
}
if (type === 'full-ellipse') {
this.save();
this.translate(props.x, props.y);
this.rotate(props.rotation);
this.scale(props.radiusX, props.radiusY);
this.arc(0, 0, 1, 0, this.pi2);
this.restore();
continue;
}
if (type === 'quick-ellipse') {
this.save();
this.translate(props.x, props.y);
this.scale(props.radiusX, props.radiusY);
this.arc(0, 0, 1, 0, this.pi2);
this.restore();
continue;
}
if (type === 'globalCompositeOperation') {
this.globalCompositeOperationStack.push(ctx.globalCompositeOperation);
ctx.globalCompositeOperation = props.value;
continue;
}
if (type === 'endGlobalCompositeOperation') {
ctx.globalCompositeOperation = this.globalCompositeOperationStack.pop();
continue;
}
if (type === 'fill') {
ctx.fill();
continue;
}
if (type === 'stroke') {
ctx.stroke();
continue;
}
if (type === 'beginClip') {
ctx.save();
ctx.beginPath();
continue;
}
if (type === 'clip') {
ctx.clip();
continue;
}
if (type === 'endClip') {
ctx.restore();
continue;
}
if (type === 'beginPath') {
ctx.beginPath();
continue;
}
if (type === 'closePath') {
ctx.closePath();
continue;
}
if (type === 'globalAlpha') {
this.globalAlphaStack.push(ctx.globalAlpha);
ctx.globalAlpha *= props.value;
continue;
}
if (type === 'endGlobalAlpha') {
ctx.globalAlpha = this.globalAlphaStack.pop();
continue;
}
if (type === 'hitRegion') {
matrix[0] = this.transformStack[this.transformStackIndex - 6];
matrix[1] = this.transformStack[this.transformStackIndex - 5];
matrix[2] = this.transformStack[this.transformStackIndex - 4];
matrix[3] = this.transformStack[this.transformStackIndex - 3];
matrix[4] = this.transformStack[this.transformStackIndex - 2];
matrix[5] = this.transformStack[this.transformStackIndex - 1];
cache = {
id: props.id,
points: transformPoints(props.points, matrix)
};
this.mouseRegions.push(cache);
this.touchRegions.push(cache);
continue;
}
if (type === 'imageSmoothingEnabled') {
this.imageSmoothingEnabledStack.push(ctx.imageSmoothingEnabled);
ctx.imageSmoothingEnabled = props.value;
continue;
}
if (type === 'endImageSmoothingEnabled') {
ctx.imageSmoothingEnabled = this.imageSmoothingEnabledStack.pop();
continue;
}
}
return this.applyStyles();
};
Renderer.create = function create(width, height, parent, worker) {
if (arguments.length > 2) {
return new Renderer(width, height, parent, worker);
}
if (arguments.length === 2) {
return new Renderer(width, height);
}
return new Renderer();
};
Renderer.prototype.resize = function(width, height) {
//only resize if the sizes are different, because it clears the canvas
if (this.canvas.width.toString() !== width.toString()) {
this.canvas.width = width;
if (this.parent !== document.body) {
this.parent.style.width = width + "px";
}
}
if (this.canvas.height.toString() !== height.toString()) {
this.canvas.height = height;
if (this.parent !== document.body) {
this.parent.style.height = height + "px";
}
}
};
Renderer.prototype.toImage = function toImage() {
var Img = require('./Img');
var img = new Img();
img.src = this.canvas.toDataURL('image/png');
return img;
};
Renderer.prototype.hookRender = function hookRender() {
//If the client has sent a 'ready' command and a tree exists
if (this.isReady) {
//fire the mouse event again if it wasn't run
if (this.lastMouseEvent && !this.ranMouseEvent) {
this.mouseMove(this.lastMouseEvent);
}
if (this.lastTouchEvent && !this.ranTouchEvent) {
this.touchEvent(this.lastMouseEvent);
}
this.fireFrame();
}
return window.requestAnimationFrame(this.boundHookRenderFunction);
};
Renderer.prototype.hookMouseEvents = function hookMouseEvents() {
//whenever the mouse moves, report the position
window.document.addEventListener('mousemove', this.mouseMove.bind(this));
//only report mousedown on canvas
this.canvas.addEventListener('mousedown', this.mouseDown.bind(this));
//mouse up can happen anywhere
return window.document.addEventListener('mouseup', this.mouseUp.bind(this));
};
Renderer.prototype.hookTouchEvents = function hookTouchEvents() {
return ['touchstart', 'touchmove', 'touchend', 'touchcancel'].forEach(function(evt) {
return window.document.addEventListener(evt, this.touchEvent.bind(this));
}, this);
};
Renderer.prototype.touchEvent = function touchEvent(evt) {
var rect = this.canvas.getBoundingClientRect(),
touchRegions = this.touchRegions.slice(),
mousePoint = [0,0],
region;
var previousIds = this.touchData.ids.splice(0, this.touchData.ids.length),
previousTouches = this.touchData.touches.splice(0, this.touchData.touches.length),
touchPoint;
for(var i = 0; i < evt.touches.length; i++) {
var touch = evt.touches.item(i);
var index = previousIds.indexOf(touch.identifier);
touchPoint = index === -1 ? { x: 0, y: 0, activeRegions: [], id: touch.identifier, touched: true, held: false } : previousTouches[index];
touchPoint.touched = index === -1;
touchPoint.held = !touchPoint.touched;
touchPoint.x = touch.clientX - rect.left;
touchPoint.y = touch.clientY - rect.top;
this.touchData.touches.push(touchPoint);
this.touchData.ids.push(touchPoint.identifier);
mousePoint[0] = touchPoint.x;
mousePoint[1] = touchPoint.y;
touchPoint.activeRegions.splice(0, touchPoint.activeRegions.length);
for(var j = 0; j < this.mouseRegions.length; i++) {
region = touchRegions[j];
if (pointInPolygon(mousePoint, region.points)) {
touchPoint.activeRegions.push(region.id);
touchRegions.splice(touchRegions.indexOf(region), 1);
j -= 1;
}
}
}
this.lastTouchEvent = evt;
this.ranTouchEvent = true;
evt.preventDefault();
this.emit('touch', this.touchData);
return false;
};
Renderer.prototype.mouseMove = function mouseMove(evt) {
//get bounding rectangle
var rect = this.canvas.getBoundingClientRect(),
mousePoint = [0,0],
region;
this.lastMouseEvent = evt;
this.ranMouseEvent = true;
mousePoint[0] = evt.clientX - rect.left;
mousePoint[1] = evt.clientY - rect.top;
for(var i = 0; i < this.mouseRegions.length; i++) {
region = this.mouseRegions[i];
if (pointInPolygon(mousePoint, region.points)) {
this.activeRegions.push(region.id);
this.mouseRegions.splice(this.mouseRegions.indexOf(region), 1);
i -= 1;
}
}
this.mouseData.x = mousePoint[0];
this.mouseData.y = mousePoint[1];
//new state is down, last state is up
this.mouseData.clicked = this.mouseState === 'down' && this.mouseData.state === 'up';
this.mouseData.state = this.mouseState;
this.mouseData.activeRegions = this.activeRegions;
this.emit('mouse', this.mouseData);
//default event stuff
evt.preventDefault();
return false;
};
Renderer.prototype.mouseDown = function mouseMove(evt) {
//set the mouseState down
this.mouseState = 'down';
this.canvas.focus();
//defer to mouseMove
return this.mouseMove(evt);
};
Renderer.prototype.mouseUp = function mouseMove(evt) {
//set the mouse state
this.mouseState = 'up';
//defer to mouse move
return this.mouseMove(evt);
};
Renderer.prototype.hookKeyboardEvents = function hookKeyboardEvents() {
//every code in keycode.code needs to be on keyData
for (var name in keycode.code) {
if (keycode.code.hasOwnProperty(name)) {
this.keyData[name] = "up";
}
}
//keydown should only happen ON the canvas
this.canvas.addEventListener('keydown', this.keyDown.bind(this));
//but keyup should be captured everywhere
return window.document.addEventListener('keyup', this.keyUp.bind(this));
};
Renderer.prototype.keyChange = function keyChange(evt) {
this.emit('key', this.keyData);
evt.preventDefault();
return false;
};
Renderer.prototype.keyDown = function keyDown(evt) {
this.keyData[keycode(evt.keyCode)] = "down";
return this.keyChange(evt);
};
Renderer.prototype.keyUp = function keyUp(evt) {
this.keyData[keycode(evt.keyCode)] = "up";
return this.keyChange(evt);
};
Renderer.prototype.fireFrame = function() {
this.mouseRegions.splice(0, this.mouseRegions.length);
this.touchRegions.splice(0, this.touchRegions.length);
this.emit('frame', {});
this.activeRegions.splice(0, this.activeRegions.length);
this.ranMouseEvent = false;
return this;
};
Renderer.prototype.style = function style() {
var children = [],
styles = [],
concat = children.concat,
len,
i,
child,
name;
for(i = 0, len = arguments.length; i < len; i++) {
children.push(arguments[i]);
}
for (i = 0, len = children.length; i < len; i++) {
child = children[i];
if (child && child.constructor === Array) {
children = concat.apply([], children);
child = children[i];
while(child && child.constructor === Array) {
children = concat.apply([], children);
child = children[i];
}
len = children.length;
}
if (child) {
styles.push(child);
}
}
for (i = 0; i < styles.length; i++) {
this.styleQueue.push(styles[i]);
}
return this;
};
Renderer.prototype.applyStyles = function applyStyles() {
var styleVal, value;
for(var i = 0; i < this.styleQueue.length; i++) {
styleVal = this.styleQueue[i];
for(var name in styleVal) {
if (styleVal.hasOwnProperty(name)) {
this.canvas.style[name] = styleVal[name];
}
}
}
this.styleQueue.splice(0, this.styleQueue.length);
return this;
};
Renderer.prototype.ready = function ready() {
this.isReady = true;
this.fireFrame();
return window.requestAnimationFrame(this.hookRender.bind(this));
};
Renderer.prototype.measureText = function measureText(font, text) {
var oldFont = this.ctx.font,
result;
this.ctx.font = font;
result = this.ctx.measureText(text);
this.ctx.font = oldFont;
return result;
};
Renderer.prototype.increaseTransformStackSize = function increaseTransformStackSize() {
var cache = this.transformStack;
this.transformStack = new Float64Array(this.transformStack.length + 600); //add 100 more
this.transformStack.set(cache);
return this;
};
Object.defineProperty(Renderer.prototype, 'height', {
get: function() {
return this.canvas.width;
},
enumerable: true,
configurable: false
});
Object.defineProperty(Renderer.prototype, 'width', {
get: function() {
return this.canvas.width;
},
enumerable: true,
configurable: false
});
Object.seal(Renderer);
Object.seal(Renderer.prototype);
module.exports = Renderer;
},{"./Img":4,"./createLinearGradient":17,"./createRadialGradient":18,"./transformPoints":57,"events":59,"keycode":1,"point-in-polygon":2,"util":64}],7:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function addColorStop(offset, color) {
return new Instruction('addColorStop', { offset: offset, color: color });
}
module.exports = addColorStop;
},{"./Instruction":5}],8:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function arc(x, y, r, startAngle, endAngle, anticlockwise) {
if (arguments.length > 5) {
return new Instruction(anticlockwise ? 'anticlockwise-arc' : 'arc', { x: x, y: y, r: r, startAngle: startAngle, endAngle: endAngle });
}
if (arguments.length === 5) {
return new Instruction('arc', { x: x, y: y, r: r, startAngle: startAngle, endAngle: endAngle });
}
if (arguments.length >= 3) {
return new Instruction('full-arc', { x: x, y: y, r: r});
}
if (arguments.length >= 1) {
return new Instruction('quick-arc', { r: x });
}
return new Instruction('quick-arc', { r: 1 });
}
module.exports = arc;
},{"./Instruction":5}],9:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function arcTo(x1, y1, x2, y2, r) {
return new Instruction('arcTo', { x1: x1, y1: y1, x2: x2, y2: y2, r: r });
}
module.exports = arcTo;
},{"./Instruction":5}],10:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function beginPath() {
return new Instruction('beginPath');
}
module.exports = beginPath;
},{"./Instruction":5}],11:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) {
return new Instruction('bezierCurveTo', {
cp1x: cp1x,
cp1y: cp1y,
cp2x: cp2x,
cp2y: cp2y,
x: x,
y: y
});
}
module.exports = bezierCurveTo;
},{"./Instruction":5}],12:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function fillRect(x, y, width, height) {
if (arguments.length > 2) {
return new Instruction("clearRect", { x: x, y: y, width: width, height: height });
} else {
return new Instruction("clearRect", { x: 0, y: 0, width: x, height: y });
}
}
module.exports = fillRect;
},{"./Instruction":5}],13:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function clip(path, children) {
var result = [new Instruction('beginClip'), path, new Instruction('clip')];
for(var i = 1; i < arguments.length; i++) {
result.push(arguments[i]);
}
result.push(new Instruction('endClip'));
return result;
}
module.exports = clip;
},{"./Instruction":5}],14:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function clipPath() {
return new Instruction('clipPath');
}
module.exports = clipPath;
},{"./Instruction":5}],15:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function closePath() {
return new Instruction('closePath');
}
module.exports = closePath;
},{"./Instruction":5}],16:[function(require,module,exports){
'use strict';
var concat = [].concat;
function createClass() {
var args = [], i;
for(i = 0; i < arguments.length; i++) {
args.push(arguments[i]);
}
for(i = 0; i < args.length; i++) {
while (args[i] && args[i].constructor === Array) {
args = concat.apply([], args);
}
if (args[i] && args[i].type === 'placeholder') {
// remove the placeholder
break;
}
}
return (function() {
var start = args, end = start.splice(i + 1, args.length);
start.pop();
return function createdClass() {
var children = [], i;
for(i = 0; i < arguments.length; i++) {
children.push(arguments[i]);
}
return [
start, children, end
];
};
}());
}
module.exports = createClass;
},{}],17:[function(require,module,exports){
//jshint node: true, browser: true, worker: true
'use strict';
function createLinearGradient(x0, y0, x1, y1, children) {
var ctx = window.document.createElement('canvas').getContext('2d'),
grd = ctx.createLinearGradient(x0, y0, x1, y1);
for(var i = 0; i < children.length; i++) {
var colorStop = children[i];
grd.addColorStop(colorStop.props.offset, colorStop.props.color);
}
return grd;
}
module.exports = createLinearGradient;
},{}],18:[function(require,module,exports){
//jshint node: true, browser: true, worker: true
'use strict';
function createRadialGradient(x0, y0, r0, x1, y1, r1, children) {
var ctx = window.document.createElement('canvas').getContext('2d'),
grd = ctx.createRadialGradient(x0, y0, r0, x1, y1, r1);
for(var i = 0; i < children.length; i++) {
var colorStop = children[i];
grd.addColorStop(colorStop.props.offset, colorStop.props.color);
}
return grd;
}
module.exports = createRadialGradient;
},{}],19:[function(require,module,exports){
'use strict';
function createRegularPolygon(radius, position, sides) {
radius = +radius || 1;
position[0] = +position[0] || 0;
position[1] = +position[1] || 0;
sides = +sides || 3;
var polygon = [];
for(var i = 0; i < sides; i++) {
polygon.push([
position[0] + radius * Math.cos(Math.PI * 2 * i / sides),
position[1] + radius * Math.sin(Math.PI * 2 * i / sides)
]);
}
return polygon;
}
module.exports = createRegularPolygon;
},{}],20:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function drawCanvas(canvas, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) {
if (arguments.length === 9) {
return new Instruction('drawCanvasSource', {
img: canvas,
sx: sx,
sy: sy,
sWidth: sWidth,
sHeight: sHeight,
dx: dx,
dy: dy,
dWidth: dWidth,
dHeight: dHeight
});
}
if (arguments.length >= 5) {
return new Instruction('drawCanvasSize', {
img: canvas,
dx: sx,
dy: sy,
dWidth: sWidth,
dHeight: sHeight
});
}
if (arguments.length >= 3) {
return new Instruction('drawCanvas', {
img: canvas,
dx: sx,
dy: sy
});
}
return new Instruction('drawCanvas', {
img: canvas,
dx: 0,
dy: 0
});
}
module.exports = drawCanvas;
},{"./Instruction":5}],21:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function drawImage(img, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) {
if (arguments.length === 9) {
return new Instruction('drawImageSource', {
img: img,
sx: sx,
sy: sy,
sWidth: sWidth,
sHeight: sHeight,
dx: dx,
dy: dy,
dWidth: dWidth,
dHeight: dHeight
});
}
if (arguments.length >= 5) {
return new Instruction('drawImageSize', {
img: img,
dx: sx,
dy: sy,
dWidth: sWidth,
dHeight: sHeight
});
}
if (arguments.length >= 3) {
return new Instruction('drawImage', {
img: img,
dx: sx,
dy: sy
});
}
return new Instruction('drawImage', {
img: img,
dx: 0,
dy: 0
});
}
module.exports = drawImage;
},{"./Instruction":5}],22:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise) {
if (arguments.length > 7) {
return new Instruction(anticlockwise ? 'anticlockwise-ellipse' : 'ellipse', { x: x, y: y, radiusX: radiusX, radiusY: radiusY, startAngle: startAngle, endAngle: endAngle });
}
if (arguments.length === 7) {
return new Instruction('ellipse', { x: x, y: y, radiusX: radiusX, radiusY: radiusY, rotation: rotation, startAngle: startAngle, endAngle: endAngle });
}
if (arguments.length >= 5) {
return new Instruction('full-ellipse', { x: x, y: y, radiusX: radiusX, radiusY: radiusY, rotation: rotation });
}
if (arguments.length === 4) {
return new Instruction('quick-ellipse', { x: x, y: y, radiusX: radiusX, radiusY: radiusY });
}
return new Instruction('quick-ellipse', { x: 0, y: 0, radiusX: x, radiusY: y });
}
module.exports = ellipse;
},{"./Instruction":5}],23:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function fill() {
return new Instruction('fill');
}
module.exports = fill;
},{"./Instruction":5}],24:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction'),
pi2 = Math.PI * 2;
function fillArc(x, y, r, startAngle, endAngle, counterclockwise) {
if (arguments.length >= 6 && counterclockwise) {
return new Instruction("fillArc-counterclockwise", { x: x, y: y, r: r, startAngle: startAngle, endAngle: endAngle });
}
if (arguments.length > 3) {
return new Instruction("fillArc", { x: x, y: y, r: r, startAngle: startAngle, endAngle: endAngle });
}
if (arguments.length > 1){
return new Instruction("fillArc", { x: x, y: y, r: r, startAngle: 0, endAngle: pi2 });
}
return new Instruction("fillArc", { x: 0, y: 0, r: x, startAngle: 0, endAngle: pi2 });
}
module.exports = fillArc;
},{"./Instruction":5}],25:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function fillImage(img, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) {
if (arguments.length === 9) {
return new Instruction('fillCanvasSource', {
img: img,
sx: sx,
sy: sy,
sWidth: sWidth,
sHeight: sHeight,
dx: dx,
dy: dy,
dWidth: dWidth,
dHeight: dHeight
});
}
if (arguments.length >= 5) {
return new Instruction('fillCanvasSize', {
img: img,
dx: sx,
dy: sy,
dWidth: sWidth,
dHeight: sHeight
});
}
if (arguments.length >= 3) {
return new Instruction('fillCanvas', {
img: img,
dx: sx,
dy: sy
});
}
return new Instruction('fillCanvas', {
img: img,
dx: 0,
dy: 0
});
}
module.exports = fillImage;
},{"./Instruction":5}],26:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function fillImage(img, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) {
if (arguments.length === 9) {
return new Instruction('fillImageSource', {
img: img,
sx: sx,
sy: sy,
sWidth: sWidth,
sHeight: sHeight,
dx: dx,
dy: dy,
dWidth: dWidth,
dHeight: dHeight
});
}
if (arguments.length >= 5) {
return new Instruction('fillImageSize', {
img: img,
dx: sx,
dy: sy,
dWidth: sWidth,
dHeight: sHeight
});
}
if (arguments.length >= 3) {
return new Instruction('fillImage', {
img: img,
dx: sx,
dy: sy
});
}
return new Instruction('fillImage', {
img: img,
dx: 0,
dy: 0
});
}
module.exports = fillImage;
},{"./Instruction":5}],27:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function fillImagePattern(img, dx, dy, dWidth, dHeight) {
if (arguments.length >= 5) {
return new Instruction('fillImagePattern', {
img: img,
dx: dx,
dy: dy,
dWidth: dWidth,
dHeight: dHeight
});
}
if (arguments.length >= 3) {
return new Instruction('fillImagePattern', {
img: img,
dx: 0,
dy: 0,
dWidth: dx,
dHeight: dy
});
}
return new Instruction('fillImagePattern', {
img: img,
dx: 0,
dy: 0,
dWidth: 0,
dHeight: 0
});
}
module.exports = fillImagePattern;
},{"./Instruction":5}],28:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function fillRect(x, y, width, height) {
if (arguments.length >= 4) {
return new Instruction("fillRect", { x: x, y: y, width: width, height: height });
} else {
return new Instruction("fillRect", { x: 0, y: 0, width: x, height: y });
}
}
module.exports = fillRect;
},{"./Instruction":5}],29:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function fillStyle(value, children) {
var result = [new Instruction('fillStyle', { value: value })];
for(var i = 1; i < arguments.length; i++) {
result.push(arguments[i]);
}
result.push(new Instruction('endFillStyle'));
return result;
}
module.exports = fillStyle;
},{"./Instruction":5}],30:[function(require,module,exports){
var Instruction = require('./Instruction');
module.exports = function fillText(text, x, y, maxWidth) {
if (arguments.length < 4) {
maxWidth = null;
}
if (arguments.length < 3) {
x = 0;
y = 0;
}
return new Instruction('fillText', {
text: text,
x: x,
y: y,
maxWidth: maxWidth
});
};
},{"./Instruction":5}],31:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function globalAlpha(alpha, children) {
var result = [new Instruction('globalAlpha', { value: alpha })];
for(var i = 1; i < arguments.length; i++) {
result.push(arguments[i]);
}
result.push(new Instruction('endGlobalAlpha'));
return result;
}
module.exports = globalAlpha;
},{"./Instruction":5}],32:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function globalCompositeOperation(operationType, children) {
var result = [new Instruction('globalCompositeOperation', { value: operationType })];
if (arguments.length === 0) {
return [];
}
for (var i = 1; i < arguments.length; i++) {
result.push(arguments[i]);
}
result.push(new Instruction('endGlobalCompositeOperation'));
return result;
}
module.exports = globalCompositeOperation;
},{"./Instruction":5}],33:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction'),
hitRegion = require('./hitRegion');
function hitRect(id, x, y, width, height) {
if (arguments.length <= 3) {
width = x;
height = y;
x = 0;
y = 0;
}
var points = [
[x, y],
[x, y + height],
[x + width, y + height],
[x + width, y]
];
return hitRegion(id, points);
}
module.exports = hitRect;
},{"./Instruction":5,"./hitRegion":34}],34:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function hitRegion(id, points) {
return new Instruction('hitRegion', {
id: id,
points: points
});
}
module.exports = hitRegion;
},{"./Instruction":5}],35:[function(require,module,exports){
'use strict';
var Instruction = require('./Instruction');
module.exports = function imageSmoothingEnabled(val, children) {
children = [];
for(var i = 1; i < arguments.length; i++) {
children.push(arguments[i]);
}
return [new Instruction('imageSmoothingEnabled', { value: Boolean(val) })].concat(children).concat(new Instruction('endImageSmoothingEnabled'));
};
},{"./Instruction":5}],36:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function lineStyle(value, children) {
value = value || {};
var result = {
lineWidth: null,
lineCap: null,
lineJoin: null,
miterLimit: null,
lineDash: [],
lineDashOffset: null
};
if (typeof value.lineWidth !== 'undefined') {
result.lineWidth = value.lineWidth;
}
if (typeof value.lineCap !== 'undefined') {
result.lineCap = value.lineCap;
}
if (typeof value.lineJoin !== 'undefined') {
result.lineJoin = value.lineJoin;
}
if (typeof value.miterLimit !== 'undefined') {
result.miterLimit = value.miterLimit;
}
if (typeof value.lineDash !== 'undefined') {
result.lineDash = value.lineDash;
}
if (typeof value.lineDashOffset !== 'undefined') {
result.lineDashOffset = value.lineDashOffset;
}
var tree = [new Instruction('lineStyle', result)];
for(var i = 1; i < arguments.length; i++) {
tree.push(arguments[i]);
}
tree.push(new Instruction('endLineStyle'));
return tree;
}
module.exports = lineStyle;
},{"./Instruction":5}],37:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function lineTo(x, y) {
if (arguments.length === 0) {
return new Instruction('lineTo', { x: 0, y: 0});
}
return new Instruction('lineTo', { x: x, y: y });
}
module.exports = lineTo;
},{"./Instruction":5}],38:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function moveTo(x, y) {
if (arguments.length === 0) {
return new Instruction('moveTo', { x: 0, y: 0});
}
return new Instruction('moveTo', { x: x, y: y });
}
module.exports = moveTo;
},{"./Instruction":5}],39:[function(require,module,exports){
'use strict';
var moveTo = require('./moveTo'), lineTo = require('./lineTo');
function moveToLineTo(point, index) {
return index === 0 ? moveTo(point[0], point[1]) : lineTo(point[0], point[1]);
}
module.exports = moveToLineTo;
},{"./lineTo":37,"./moveTo":38}],40:[function(require,module,exports){
//jshint node: true
'use strict';
var beginPath = require('./beginPath'),
closePath = require('./closePath');
function path(children) {
var result = [beginPath()];
for(var i = 0; i < arguments.length; i++) {
result.push(arguments[i]);
}
result.push(closePath());
return result;
}
module.exports = path;
},{"./beginPath":10,"./closePath":15}],41:[function(require,module,exports){
'use strict';
var Instruction = require('./Instruction');
module.exports = function placeHolder() {
return new Instruction('placeholder');
};
},{"./Instruction":5}],42:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function quadraticCurveTo(cpx, cpy, x, y) {
return new Instruction('quadraticCurveTo', {
cpx: cpx,
cpy: cpy,
x: x,
y: y
});
}
module.exports = quadraticCurveTo;
},{"./Instruction":5}],43:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function rect(x, y, width, height) {
if (arguments.length > 2) {
return new Instruction("rect", { x: x, y: y, width: width, height: height });
} else {
return new Instruction("rect", { x: 0, y: 0, width: x, height: y });
}
}
module.exports = rect;
},{"./Instruction":5}],44:[function(require,module,exports){
'use strict';
var setTransform = require('./setTransform');
module.exports = function resetTransform() {
var args = [];
for(var i = 0; i < arguments.length; i++) {
args.push(arguments[i]);
}
return setTransform([1, 0, 0, 1, 0, 0], args);
};
},{"./setTransform":47}],45:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function rotate(r, children) {
r = +r;
var result = [new Instruction('rotate', { r: r })];
for(var i = 1; i < arguments.length; i++) {
result.push(arguments[i]);
}
result.push(new Instruction('restore'));
return result;
}
module.exports = rotate;
},{"./Instruction":5}],46:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function scale(x, y, children) {
var i = 2;
if (typeof y !== 'number') {
y = x;
i = 1;
}
children = children || [];
var result = [new Instruction('scale', { x: x, y: y })],
child;
for (; i < arguments.length; i++) {
result.push(arguments[i]);
}
result.push(new Instruction('restore'));
return result;
}
module.exports = scale;
},{"./Instruction":5}],47:[function(require,module,exports){
'use strict';
var Instruction = require('./Instruction');
module.exports = function(matrix, children) {
var result = [new Instruction('setTransform', [
matrix[0],
matrix[1],
matrix[2],
matrix[3],
matrix[4],
matrix[5]
])];
for(var i = 1; i < arguments.length; i++) {
result.push(arguments[i]);
}
result.push(new Instruction('restore'));
return result;
};
},{"./Instruction":5}],48:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function shadowStyle(value, children) {
value = value || {};
var result = {
shadowBlur: null,
shadowColor: null,
shadowOffsetX: null,
shadowOffsetY: null
};
if (typeof value.shadowBlur !== 'undefined') {
result.shadowBlur = value.shadowBlur;
}
if (typeof value.shadowColor !== 'undefined') {
result.shadowColor = value.shadowColor;
}
if (typeof value.shadowOffsetX !== 'undefined') {
result.shadowOffsetX = value.shadowOffsetX;
}
if (typeof value.direction !== 'undefined') {
result.shadowOffsetY = value.shadowOffsetY;
}
var tree = [new Instruction('shadowStyle', value)];
for (var i = 1; i < arguments.length; i++) {
tree.push(arguments[i]);
}
tree.push(new Instruction('endShadowStyle'));
return tree;
}
module.exports = shadowStyle;
},{"./Instruction":5}],49:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function stroke() {
return new Instruction('stroke');
}
module.exports = stroke;
},{"./Instruction":5}],50:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction'),
pi2 = Math.PI * 2;
function strokeArc(x, y, r, startAngle, endAngle, counterclockwise) {
if (arguments.length >= 6 && counterclockwise) {
return new Instruction("strokeArc-counterclockwise", { x: x, y: y, r: r, startAngle: startAngle, endAngle: endAngle });
}
if (arguments.length > 3) {
return new Instruction("strokeArc", { x: x, y: y, r: r, startAngle: startAngle, endAngle: endAngle });
}
if (arguments.length > 1){
return new Instruction("strokeArc", { x: x, y: y, r: r, startAngle: 0, endAngle: pi2 });
}
return new Instruction("strokeArc", { x: 0, y: 0, r: x, startAngle: 0, endAngle: pi2 });
}
module.exports = strokeArc;
},{"./Instruction":5}],51:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function strokeRect(x, y, width, height) {
if (arguments.length > 2) {
return new Instruction("strokeRect", { x: x, y: y, width: width, height: height });
} else {
return new Instruction("strokeRect", { x: 0, y: 0, width: x, height: y });
}
}
module.exports = strokeRect;
},{"./Instruction":5}],52:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function fillStyle(value, children) {
var result = [ new Instruction('strokeStyle', { value: value }) ];
for(var i = 1; i < arguments.length; i++) {
result.push(arguments[i]);
}
result.push(new Instruction('endStrokeStyle'));
return result;
}
module.exports = fillStyle;
},{"./Instruction":5}],53:[function(require,module,exports){
var Instruction = require('./Instruction');
module.exports = function strokeText(text, x, y, maxWidth) {
if (arguments.length < 4) {
maxWidth = null;
}
if (arguments.length < 3) {
x = 0;
y = 0;
}
return new Instruction('strokeText', {
text: text,
x: x,
y: y,
maxWidth: maxWidth
});
};
},{"./Instruction":5}],54:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function text(str, x, y, fill, stroke, maxWidth) {
if (arguments.length === 6) {
return new Instruction('text', {
x: x,
y: y,
fill: fill,
stroke: stroke,
text: str,
maxWidth: maxWidth
});
}
if (arguments.length === 5) {
return new Instruction('text', {
x: x,
y: y,
fill: fill,
stroke: stroke,
text: str,
maxWidth: 0
});
}
if (arguments.length === 4) {
return new Instruction('text', {
x: x,
y: y,
fill: fill,
stroke: false,
text: str,
maxWidth: 0
});
}
if (arguments.length === 3) {
return new Instruction('text', {
x: x,
y: y,
fill: true,
stroke: false,
text: str,
maxWidth: 0
});
}
return new Instruction('text', {
x: 0,
y: 0,
fill: true,
stroke: false,
text: str,
maxWidth: 0
});
}
module.exports = text;
},{"./Instruction":5}],55:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function textStyle(value, children) {
value = value || {};
var result = {
font: null,
textAlign: null,
textBaseline: null,
direction: null
};
if (typeof value.font !== 'undefined') {
result.font = value.font;
}
if (typeof value.textAlign !== 'undefined') {
result.textAlign = value.textAlign;
}
if (typeof value.textBaseline !== 'undefined') {
result.textBaseline = value.textBaseline;
}
if (typeof value.direction !== 'undefined') {
result.direction = value.direction;
}
var tree = [new Instruction('textStyle', value)];
for(var i = 1; i < arguments.length; i++) {
tree.push(arguments[i]);
}
tree.push(new Instruction('endTextStyle'));
return tree;
}
module.exports = textStyle;
},{"./Instruction":5}],56:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function transform(values, children) {
var transformResult = [
new Instruction('transform',[
values[0],
values[1],
values[2],
values[3],
values[4],
values[5]
])
];
for(var i = 1, len = arguments.length; i < len; i++) {
transformResult.push(arguments[i]);
}
transformResult.push(new Instruction('restore'));
return transformResult;
}
module.exports = transform;
},{"./Instruction":5}],57:[function(require,module,exports){
//jshint node: true
'use strict';
function transformPoints(points, matrix) {
var result = [],
len = points.length,
point;
for(var i = 0; i < len; i++) {
point = points[i];
result.push([
matrix[0] * point[0] + matrix[2] * point[1] + matrix[4],
matrix[1] * point[0] + matrix[3] * point[1] + matrix[5]
]);
}
return result;
}
module.exports = transformPoints;
},{}],58:[function(require,module,exports){
//jshint node: true
'use strict';
var Instruction = require('./Instruction');
function translate(x, y, children) {
var result = [new Instruction('translate', { x: x, y: y })];
var val;
for (var i = 2; i < arguments.length; i++) {
val = arguments[i];
if (Array.isArray(val)) {
result = result.concat(val);
continue;
}
result.push(arguments[i]);
}
result.push(new Instruction('restore'));
return result;
}
module.exports = translate;
},{"./Instruction":5}],59:[function(require,module,exports){
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
function EventEmitter() {
this._events = this._events || {};
this._maxListeners = this._maxListeners || undefined;
}
module.exports = EventEmitter;
// Backwards-compat with node 0.10.x
EventEmitter.EventEmitter = EventEmitter;
EventEmitter.prototype._events = undefined;
EventEmitter.prototype._maxListeners = undefined;
// By default EventEmitters will print a warning if more than 10 listeners are
// added to it. This is a useful default which helps finding memory leaks.
EventEmitter.defaultMaxListeners = 10;
// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
EventEmitter.prototype.setMaxListeners = function(n) {
if (!isNumber(n) || n < 0 || isNaN(n))
throw TypeError('n must be a positive number');
this._maxListeners = n;
return this;
};
EventEmitter.prototype.emit = function(type) {
var er, handler, len, args, i, listeners;
if (!this._events)
this._events = {};
// If there is no 'error' event listener then throw.
if (type === 'error') {
if (!this._events.error ||
(isObject(this._events.error) && !this._events.error.length)) {
er = arguments[1];
if (er instanceof Error) {
throw er; // Unhandled 'error' event
} else {
throw TypeError('Uncaught, unspecified "error" event.');
}
return false;
}
}
handler = this._events[type];
if (isUndefined(handler))
return false;
if (isFunction(handler)) {
switch (arguments.length) {
// fast cases
case 1:
handler.call(this);
break;
case 2:
handler.call(this, arguments[1]);
break;
case 3:
handler.call(this, arguments[1], arguments[2]);
break;
// slower
default:
len = arguments.length;
args = new Array(len - 1);
for (i = 1; i < len; i++)
args[i - 1] = arguments[i];
handler.apply(this, args);
}
} else if (isObject(handler)) {
len = arguments.length;
args = new Array(len - 1);
for (i = 1; i < len; i++)
args[i - 1] = arguments[i];
listeners = handler.slice();
len = listeners.length;
for (i = 0; i < len; i++)
listeners[i].apply(this, args);
}
return true;
};
EventEmitter.prototype.addListener = function(type, listener) {
var m;
if (!isFunction(listener))
throw TypeError('listener must be a function');
if (!this._events)
this._events = {};
// To avoid recursion in the case that type === "newListener"! Before
// adding it to the listeners, first emit "newListener".
if (this._events.newListener)
this.emit('newListener', type,
isFunction(listener.listener) ?
listener.listener : listener);
if (!this._events[type])
// Optimize the case of one listener. Don't need the extra array object.
this._events[type] = listener;
else if (isObject(this._events[type]))
// If we've already got an array, just append.
this._events[type].push(listener);
else
// Adding the second element, need to change to array.
this._events[type] = [this._events[type], listener];
// Check for listener leak
if (isObject(this._events[type]) && !this._events[type].warned) {
var m;
if (!isUndefined(this._maxListeners)) {
m = this._maxListeners;
} else {
m = EventEmitter.defaultMaxListeners;
}
if (m && m > 0 && this._events[type].length > m) {
this._events[type].warned = true;
console.error('(node) warning: possible EventEmitter memory ' +
'leak detected. %d listeners added. ' +
'Use emitter.setMaxListeners() to increase limit.',
this._events[type].length);
if (typeof console.trace === 'function') {
// not supported in IE 10
console.trace();
}
}
}
return this;
};
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
EventEmitter.prototype.once = function(type, listener) {
if (!isFunction(listener))
throw TypeError('listener must be a function');
var fired = false;
function g() {
this.removeListener(type, g);
if (!fired) {
fired = true;
listener.apply(this, arguments);
}
}
g.listener = listener;
this.on(type, g);
return this;
};
// emits a 'removeListener' event iff the listener was removed
EventEmitter.prototype.removeListener = function(type, listener) {
var list, position, length, i;
if (!isFunction(listener))
throw TypeError('listener must be a function');
if (!this._events || !this._events[type])
return this;
list = this._events[type];
length = list.length;
position = -1;
if (list === listener ||
(isFunction(list.listener) && list.listener === listener)) {
delete this._events[type];
if (this._events.removeListener)
this.emit('removeListener', type, listener);
} else if (isObject(list)) {
for (i = length; i-- > 0;) {
if (list[i] === listener ||
(list[i].listener && list[i].listener === listener)) {
position = i;
break;
}
}
if (position < 0)
return this;
if (list.length === 1) {
list.length = 0;
delete this._events[type];
} else {
list.splice(position, 1);
}
if (this._events.removeListener)
this.emit('removeListener', type, listener);
}
return this;
};
EventEmitter.prototype.removeAllListeners = function(type) {
var key, listeners;
if (!this._events)
return this;
// not listening for removeListener, no need to emit
if (!this._events.removeListener) {
if (arguments.length === 0)
this._events = {};
else if (this._events[type])
delete this._events[type];
return this;
}
// emit removeListener for all listeners on all events
if (arguments.length === 0) {
for (key in this._events) {
if (key === 'removeListener') continue;
this.removeAllListeners(key);
}
this.removeAllListeners('removeListener');
this._events = {};
return this;
}
listeners = this._events[type];
if (isFunction(listeners)) {
this.removeListener(type, listeners);
} else {
// LIFO order
while (listeners.length)
this.removeListener(type, listeners[listeners.length - 1]);
}
delete this._events[type];
return this;
};
EventEmitter.prototype.listeners = function(type) {
var ret;
if (!this._events || !this._events[type])
ret = [];
else if (isFunction(this._events[type]))
ret = [this._events[type]];
else
ret = this._events[type].slice();
return ret;
};
EventEmitter.listenerCount = function(emitter, type) {
var ret;
if (!emitter._events || !emitter._events[type])
ret = 0;
else if (isFunction(emitter._events[type]))
ret = 1;
else
ret = emitter._events[type].length;
return ret;
};
function isFunction(arg) {
return typeof arg === 'function';
}
function isNumber(arg) {
return typeof arg === 'number';
}
function isObject(arg) {
return typeof arg === 'object' && arg !== null;
}
function isUndefined(arg) {
return arg === void 0;
}
},{}],60:[function(require,module,exports){
if (typeof Object.create === 'function') {
// implementation from standard node.js 'util' module
module.exports = function inherits(ctor, superCtor) {
ctor.super_ = superCtor
ctor.prototype = Object.create(superCtor.prototype, {
constructor: {
value: ctor,
enumerable: false,
writable: true,
configurable: true
}
});
};
} else {
// old school shim for old browsers
module.exports = function inherits(ctor, superCtor) {
ctor.super_ = superCtor
var TempCtor = function () {}
TempCtor.prototype = superCtor.prototype
ctor.prototype = new TempCtor()
ctor.prototype.constructor = ctor
}
}
},{}],61:[function(require,module,exports){
(function (process){
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
// resolves . and .. elements in a path array with directory names there
// must be no slashes, empty elements, or device names (c:\) in the array
// (so also no leading and trailing slashes - it does not distinguish
// relative and absolute paths)
function normalizeArray(parts, allowAboveRoot) {
// if the path tries to go above the root, `up` ends up > 0
var up = 0;
for (var i = parts.length - 1; i >= 0; i--) {
var last = parts[i];
if (last === '.') {
parts.splice(i, 1);
} else if (last === '..') {
parts.splice(i, 1);
up++;
} else if (up) {
parts.splice(i, 1);
up--;
}
}
// if the path is allowed to go above the root, restore leading ..s
if (allowAboveRoot) {
for (; up--; up) {
parts.unshift('..');
}
}
return parts;
}
// Split a filename into [root, dir, basename, ext], unix version
// 'root' is just a slash, or nothing.
var splitPathRe =
/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
var splitPath = function(filename) {
return splitPathRe.exec(filename).slice(1);
};
// path.resolve([from ...], to)
// posix version
exports.resolve = function() {
var resolvedPath = '',
resolvedAbsolute = false;
for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
var path = (i >= 0) ? arguments[i] : process.cwd();
// Skip empty and invalid entries
if (typeof path !== 'string') {
throw new TypeError('Arguments to path.resolve must be strings');
} else if (!path) {
continue;
}
resolvedPath = path + '/' + resolvedPath;
resolvedAbsolute = path.charAt(0) === '/';
}
// At this point the path should be resolved to a full absolute path, but
// handle relative paths to be safe (might happen when process.cwd() fails)
// Normalize the path
resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
return !!p;
}), !resolvedAbsolute).join('/');
return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
};
// path.normalize(path)
// posix version
exports.normalize = function(path) {
var isAbsolute = exports.isAbsolute(path),
trailingSlash = substr(path, -1) === '/';
// Normalize the path
path = normalizeArray(filter(path.split('/'), function(p) {
return !!p;
}), !isAbsolute).join('/');
if (!path && !isAbsolute) {
path = '.';
}
if (path && trailingSlash) {
path += '/';
}
return (isAbsolute ? '/' : '') + path;
};
// posix version
exports.isAbsolute = function(path) {
return path.charAt(0) === '/';
};
// posix version
exports.join = function() {
var paths = Array.prototype.slice.call(arguments, 0);
return exports.normalize(filter(paths, function(p, index) {
if (typeof p !== 'string') {
throw new TypeError('Arguments to path.join must be strings');
}
return p;
}).join('/'));
};
// path.relative(from, to)
// posix version
exports.relative = function(from, to) {
from = exports.resolve(from).substr(1);
to = exports.resolve(to).substr(1);
function trim(arr) {
var start = 0;
for (; start < arr.length; start++) {
if (arr[start] !== '') break;
}
var end = arr.length - 1;
for (; end >= 0; end--) {
if (arr[end] !== '') break;
}
if (start > end) return [];
return arr.slice(start, end - start + 1);
}
var fromParts = trim(from.split('/'));
var toParts = trim(to.split('/'));
var length = Math.min(fromParts.length, toParts.length);
var samePartsLength = length;
for (var i = 0; i < length; i++) {
if (fromParts[i] !== toParts[i]) {
samePartsLength = i;
break;
}
}
var outputParts = [];
for (var i = samePartsLength; i < fromParts.length; i++) {
outputParts.push('..');
}
outputParts = outputParts.concat(toParts.slice(samePartsLength));
return outputParts.join('/');
};
exports.sep = '/';
exports.delimiter = ':';
exports.dirname = function(path) {
var result = splitPath(path),
root = result[0],
dir = result[1];
if (!root && !dir) {
// No dirname whatsoever
return '.';
}
if (dir) {
// It has a dirname, strip trailing slash
dir = dir.substr(0, dir.length - 1);
}
return root + dir;
};
exports.basename = function(path, ext) {
var f = splitPath(path)[2];
// TODO: make this comparison case-insensitive on windows?
if (ext && f.substr(-1 * ext.length) === ext) {
f = f.substr(0, f.length - ext.length);
}
return f;
};
exports.extname = function(path) {
return splitPath(path)[3];
};
function filter (xs, f) {
if (xs.filter) return xs.filter(f);
var res = [];
for (var i = 0; i < xs.length; i++) {
if (f(xs[i], i, xs)) res.push(xs[i]);
}
return res;
}
// String.prototype.substr - negative index don't work in IE8
var substr = 'ab'.substr(-1) === 'b'
? function (str, start, len) { return str.substr(start, len) }
: function (str, start, len) {
if (start < 0) start = str.length + start;
return str.substr(start, len);
}
;
}).call(this,require('_process'))
},{"_process":62}],62:[function(require,module,exports){
// shim for using process in browser
var process = module.exports = {};
process.nextTick = (function () {
var canSetImmediate = typeof window !== 'undefined'
&& window.setImmediate;
var canPost = typeof window !== 'undefined'
&& window.postMessage && window.addEventListener
;
if (canSetImmediate) {
return function (f) { return window.setImmediate(f) };
}
if (canPost) {
var queue = [];
window.addEventListener('message', function (ev) {
var source = ev.source;
if ((source === window || source === null) && ev.data === 'process-tick') {
ev.stopPropagation();
if (queue.length > 0) {
var fn = queue.shift();
fn();
}
}
}, true);
return function nextTick(fn) {
queue.push(fn);
window.postMessage('process-tick', '*');
};
}
return function nextTick(fn) {
setTimeout(fn, 0);
};
})();
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
function noop() {}
process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.binding = function (name) {
throw new Error('process.binding is not supported');
}
// TODO(shtylman)
process.cwd = function () { return '/' };
process.chdir = function (dir) {
throw new Error('process.chdir is not supported');
};
},{}],63:[function(require,module,exports){
module.exports = function isBuffer(arg) {
return arg && typeof arg === 'object'
&& typeof arg.copy === 'function'
&& typeof arg.fill === 'function'
&& typeof arg.readUInt8 === 'function';
}
},{}],64:[function(require,module,exports){
(function (process,global){
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var formatRegExp = /%[sdj%]/g;
exports.format = function(f) {
if (!isString(f)) {
var objects = [];
for (var i = 0; i < arguments.length; i++) {
objects.push(inspect(arguments[i]));
}
return objects.join(' ');
}
var i = 1;
var args = arguments;
var len = args.length;
var str = String(f).replace(formatRegExp, function(x) {
if (x === '%%') return '%';
if (i >= len) return x;
switch (x) {
case '%s': return String(args[i++]);
case '%d': return Number(args[i++]);
case '%j':
try {
return JSON.stringify(args[i++]);
} catch (_) {
return '[Circular]';
}
default:
return x;
}
});
for (var x = args[i]; i < len; x = args[++i]) {
if (isNull(x) || !isObject(x)) {
str += ' ' + x;
} else {
str += ' ' + inspect(x);
}
}
return str;
};
// Mark that a method should not be used.
// Returns a modified function which warns once by default.
// If --no-deprecation is set, then it is a no-op.
exports.deprecate = function(fn, msg) {
// Allow for deprecating things in the process of starting up.
if (isUndefined(global.process)) {
return function() {
return exports.deprecate(fn, msg).apply(this, arguments);
};
}
if (process.noDeprecation === true) {
return fn;
}
var warned = false;
function deprecated() {
if (!warned) {
if (process.throwDeprecation) {
throw new Error(msg);
} else if (process.traceDeprecation) {
console.trace(msg);
} else {
console.error(msg);
}
warned = true;
}
return fn.apply(this, arguments);
}
return deprecated;
};
var debugs = {};
var debugEnviron;
exports.debuglog = function(set) {
if (isUndefined(debugEnviron))
debugEnviron = process.env.NODE_DEBUG || '';
set = set.toUpperCase();
if (!debugs[set]) {
if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
var pid = process.pid;
debugs[set] = function() {
var msg = exports.format.apply(exports, arguments);
console.error('%s %d: %s', set, pid, msg);
};
} else {
debugs[set] = function() {};
}
}
return debugs[set];
};
/**
* Echos the value of a value. Trys to print the value out
* in the best way possible given the different types.
*
* @param {Object} obj The object to print out.
* @param {Object} opts Optional options object that alters the output.
*/
/* legacy: obj, showHidden, depth, colors*/
function inspect(obj, opts) {
// default options
var ctx = {
seen: [],
stylize: stylizeNoColor
};
// legacy...
if (arguments.length >= 3) ctx.depth = arguments[2];
if (arguments.length >= 4) ctx.colors = arguments[3];
if (isBoolean(opts)) {
// legacy...
ctx.showHidden = opts;
} else if (opts) {
// got an "options" object
exports._extend(ctx, opts);
}
// set default options
if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
if (isUndefined(ctx.depth)) ctx.depth = 2;
if (isUndefined(ctx.colors)) ctx.colors = false;
if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
if (ctx.colors) ctx.stylize = stylizeWithColor;
return formatValue(ctx, obj, ctx.depth);
}
exports.inspect = inspect;
// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
inspect.colors = {
'bold' : [1, 22],
'italic' : [3, 23],
'underline' : [4, 24],
'inverse' : [7, 27],
'white' : [37, 39],
'grey' : [90, 39],
'black' : [30, 39],
'blue' : [34, 39],
'cyan' : [36, 39],
'green' : [32, 39],
'magenta' : [35, 39],
'red' : [31, 39],
'yellow' : [33, 39]
};
// Don't use 'blue' not visible on cmd.exe
inspect.styles = {
'special': 'cyan',
'number': 'yellow',
'boolean': 'yellow',
'undefined': 'grey',
'null': 'bold',
'string': 'green',
'date': 'magenta',
// "name": intentionally not styling
'regexp': 'red'
};
function stylizeWithColor(str, styleType) {
var style = inspect.styles[styleType];
if (style) {
return '\u001b[' + inspect.colors[style][0] + 'm' + str +
'\u001b[' + inspect.colors[style][1] + 'm';
} else {
return str;
}
}
function stylizeNoColor(str, styleType) {
return str;
}
function arrayToHash(array) {
var hash = {};
array.forEach(function(val, idx) {
hash[val] = true;
});
return hash;
}
function formatValue(ctx, value, recurseTimes) {
// Provide a hook for user-specified inspect functions.
// Check that value is an object with an inspect function on it
if (ctx.customInspect &&
value &&
isFunction(value.inspect) &&
// Filter out the util module, it's inspect function is special
value.inspect !== exports.inspect &&
// Also filter out any prototype objects using the circular check.
!(value.constructor && value.constructor.prototype === value)) {
var ret = value.inspect(recurseTimes, ctx);
if (!isString(ret)) {
ret = formatValue(ctx, ret, recurseTimes);
}
return ret;
}
// Primitive types cannot have properties
var primitive = formatPrimitive(ctx, value);
if (primitive) {
return primitive;
}
// Look up the keys of the object.
var keys = Object.keys(value);
var visibleKeys = arrayToHash(keys);
if (ctx.showHidden) {
keys = Object.getOwnPropertyNames(value);
}
// IE doesn't make error fields non-enumerable
// http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
if (isError(value)
&& (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
return formatError(value);
}
// Some type of object without properties can be shortcutted.
if (keys.length === 0) {
if (isFunction(value)) {
var name = value.name ? ': ' + value.name : '';
return ctx.stylize('[Function' + name + ']', 'special');
}
if (isRegExp(value)) {
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
}
if (isDate(value)) {
return ctx.stylize(Date.prototype.toString.call(value), 'date');
}
if (isError(value)) {
return formatError(value);
}
}
var base = '', array = false, braces = ['{', '}'];
// Make Array say that they are Array
if (isArray(value)) {
array = true;
braces = ['[', ']'];
}
// Make functions say that they are functions
if (isFunction(value)) {
var n = value.name ? ': ' + value.name : '';
base = ' [Function' + n + ']';
}
// Make RegExps say that they are RegExps
if (isRegExp(value)) {
base = ' ' + RegExp.prototype.toString.call(value);
}
// Make dates with properties first say the date
if (isDate(value)) {
base = ' ' + Date.prototype.toUTCString.call(value);
}
// Make error with message first say the error
if (isError(value)) {
base = ' ' + formatError(value);
}
if (keys.length === 0 && (!array || value.length == 0)) {
return braces[0] + base + braces[1];
}
if (recurseTimes < 0) {
if (isRegExp(value)) {
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
} else {
return ctx.stylize('[Object]', 'special');
}
}
ctx.seen.push(value);
var output;
if (array) {
output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
} else {
output = keys.map(function(key) {
return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
});
}
ctx.seen.pop();
return reduceToSingleString(output, base, braces);
}
function formatPrimitive(ctx, value) {
if (isUndefined(value))
return ctx.stylize('undefined', 'undefined');
if (isString(value)) {
var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
.replace(/'/g, "\\'")
.replace(/\\"/g, '"') + '\'';
return ctx.stylize(simple, 'string');
}
if (isNumber(value))
return ctx.stylize('' + value, 'number');
if (isBoolean(value))
return ctx.stylize('' + value, 'boolean');
// For some reason typeof null is "object", so special case here.
if (isNull(value))
return ctx.stylize('null', 'null');
}
function formatError(value) {
return '[' + Error.prototype.toString.call(value) + ']';
}
function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
var output = [];
for (var i = 0, l = value.length; i < l; ++i) {
if (hasOwnProperty(value, String(i))) {
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
String(i), true));
} else {
output.push('');
}
}
keys.forEach(function(key) {
if (!key.match(/^\d+$/)) {
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
key, true));
}
});
return output;
}
function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
var name, str, desc;
desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
if (desc.get) {
if (desc.set) {
str = ctx.stylize('[Getter/Setter]', 'special');
} else {
str = ctx.stylize('[Getter]', 'special');
}
} else {
if (desc.set) {
str = ctx.stylize('[Setter]', 'special');
}
}
if (!hasOwnProperty(visibleKeys, key)) {
name = '[' + key + ']';
}
if (!str) {
if (ctx.seen.indexOf(desc.value) < 0) {
if (isNull(recurseTimes)) {
str = formatValue(ctx, desc.value, null);
} else {
str = formatValue(ctx, desc.value, recurseTimes - 1);
}
if (str.indexOf('\n') > -1) {
if (array) {
str = str.split('\n').map(function(line) {
return ' ' + line;
}).join('\n').substr(2);
} else {
str = '\n' + str.split('\n').map(function(line) {
return ' ' + line;
}).join('\n');
}
}
} else {
str = ctx.stylize('[Circular]', 'special');
}
}
if (isUndefined(name)) {
if (array && key.match(/^\d+$/)) {
return str;
}
name = JSON.stringify('' + key);
if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
name = name.substr(1, name.length - 2);
name = ctx.stylize(name, 'name');
} else {
name = name.replace(/'/g, "\\'")
.replace(/\\"/g, '"')
.replace(/(^"|"$)/g, "'");
name = ctx.stylize(name, 'string');
}
}
return name + ': ' + str;
}
function reduceToSingleString(output, base, braces) {
var numLinesEst = 0;
var length = output.reduce(function(prev, cur) {
numLinesEst++;
if (cur.indexOf('\n') >= 0) numLinesEst++;
return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
}, 0);
if (length > 60) {
return braces[0] +
(base === '' ? '' : base + '\n ') +
' ' +
output.join(',\n ') +
' ' +
braces[1];
}
return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
}
// NOTE: These type checking functions intentionally don't use `instanceof`
// because it is fragile and can be easily faked with `Object.create()`.
function isArray(ar) {
return Array.isArray(ar);
}
exports.isArray = isArray;
function isBoolean(arg) {
return typeof arg === 'boolean';
}
exports.isBoolean = isBoolean;
function isNull(arg) {
return arg === null;
}
exports.isNull = isNull;
function isNullOrUndefined(arg) {
return arg == null;
}
exports.isNullOrUndefined = isNullOrUndefined;
function isNumber(arg) {
return typeof arg === 'number';
}
exports.isNumber = isNumber;
function isString(arg) {
return typeof arg === 'string';
}
exports.isString = isString;
function isSymbol(arg) {
return typeof arg === 'symbol';
}
exports.isSymbol = isSymbol;
function isUndefined(arg) {
return arg === void 0;
}
exports.isUndefined = isUndefined;
function isRegExp(re) {
return isObject(re) && objectToString(re) === '[object RegExp]';
}
exports.isRegExp = isRegExp;
function isObject(arg) {
return typeof arg === 'object' && arg !== null;
}
exports.isObject = isObject;
function isDate(d) {
return isObject(d) && objectToString(d) === '[object Date]';
}
exports.isDate = isDate;
function isError(e) {
return isObject(e) &&
(objectToString(e) === '[object Error]' || e instanceof Error);
}
exports.isError = isError;
function isFunction(arg) {
return typeof arg === 'function';
}
exports.isFunction = isFunction;
function isPrimitive(arg) {
return arg === null ||
typeof arg === 'boolean' ||
typeof arg === 'number' ||
typeof arg === 'string' ||
typeof arg === 'symbol' || // ES6 symbol
typeof arg === 'undefined';
}
exports.isPrimitive = isPrimitive;
exports.isBuffer = require('./support/isBuffer');
function objectToString(o) {
return Object.prototype.toString.call(o);
}
function pad(n) {
return n < 10 ? '0' + n.toString(10) : n.toString(10);
}
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
'Oct', 'Nov', 'Dec'];
// 26 Feb 16:19:34
function timestamp() {
var d = new Date();
var time = [pad(d.getHours()),
pad(d.getMinutes()),
pad(d.getSeconds())].join(':');
return [d.getDate(), months[d.getMonth()], time].join(' ');
}
// log is just a thin wrapper to console.log that prepends a timestamp
exports.log = function() {
console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
};
/**
* Inherit the prototype methods from one constructor into another.
*
* The Function.prototype.inherits from lang.js rewritten as a standalone
* function (not on Function.prototype). NOTE: If this file is to be loaded
* during bootstrapping this function needs to be rewritten using some native
* functions as prototype setup using normal JavaScript does not work as
* expected during bootstrapping (see mirror.js in r114903).
*
* @param {function} ctor Constructor function which needs to inherit the
* prototype.
* @param {function} superCtor Constructor function to inherit prototype from.
*/
exports.inherits = require('inherits');
exports._extend = function(origin, add) {
// Don't do anything if add isn't an object
if (!add || !isObject(add)) return origin;
var keys = Object.keys(add);
var i = keys.length;
while (i--) {
origin[keys[i]] = add[keys[i]];
}
return origin;
};
function hasOwnProperty(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}
}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./support/isBuffer":63,"_process":62,"inherits":60}],"e2d":[function(require,module,exports){
//jshint node: true
'use strict';
module.exports = {
addColorStop: require('./src/addColorStop'),
arc: require('./src/arc'),
arcTo: require('./src/arcTo'),
beginPath: require('./src/beginPath'),
bezierCurveTo: require('./src/bezierCurveTo'),
Canvas: require('./src/Canvas'),
clearRect: require('./src/clearRect'),
clip: require('./src/clip'),
clipPath: require('./src/clipPath'),
closePath: require('./src/closePath'),
createClass: require('./src/createClass'),
createLinearGradient: require('./src/createLinearGradient'),
createRadialGradient: require('./src/createRadialGradient'),
createRegularPolygon : require('./src/createRegularPolygon'),
drawCanvas: require('./src/drawCanvas'),
drawImage: require('./src/drawImage'),
ellipse: require('./src/ellipse'),
fill: require('./src/fill'),
fillArc: require('./src/fillArc'),
fillCanvas: require('./src/fillCanvas'),
fillImage: require('./src/fillImage'),
fillImagePattern: require('./src/fillImagePattern'),
fillRect: require('./src/fillRect'),
fillStyle: require('./src/fillStyle'),
fillText: require('./src/fillText'),
globalAlpha: require('./src/globalAlpha'),
globalCompositeOperation: require('./src/globalCompositeOperation'),
hitRect: require('./src/hitRect'),
hitRegion: require('./src/hitRegion'),
imageSmoothingEnabled: require('./src/imageSmoothingEnabled'),
Img: require('./src/Img'),
Instruction: require('./src/Instruction'),
lineStyle: require('./src/lineStyle'),
lineTo: require('./src/lineTo'),
moveTo: require('./src/moveTo'),
moveToLineTo: require('./src/moveToLineTo'),
path: require('./src/path'),
placeHolder: require('./src/placeHolder'),
quadraticCurveTo: require('./src/quadraticCurveTo'),
rect: require('./src/rect'),
Renderer: require('./src/Renderer'),
resetTransform: require('./src/resetTransform'),
rotate: require('./src/rotate'),
scale: require('./src/scale'),
setTransform: require('./src/setTransform'),
shadowStyle: require('./src/shadowStyle'),
stroke: require('./src/stroke'),
strokeArc: require('./src/strokeArc'),
strokeRect: require('./src/strokeRect'),
strokeStyle: require('./src/strokeStyle'),
strokeText: require('./src/strokeText'),
text: require('./src/text'),
textStyle: require('./src/textStyle'),
transform: require('./src/transform'),
transformPoints: require('./src/transformPoints'),
translate: require('./src/translate')
};
},{"./src/Canvas":3,"./src/Img":4,"./src/Instruction":5,"./src/Renderer":6,"./src/addColorStop":7,"./src/arc":8,"./src/arcTo":9,"./src/beginPath":10,"./src/bezierCurveTo":11,"./src/clearRect":12,"./src/clip":13,"./src/clipPath":14,"./src/closePath":15,"./src/createClass":16,"./src/createLinearGradient":17,"./src/createRadialGradient":18,"./src/createRegularPolygon":19,"./src/drawCanvas":20,"./src/drawImage":21,"./src/ellipse":22,"./src/fill":23,"./src/fillArc":24,"./src/fillCanvas":25,"./src/fillImage":26,"./src/fillImagePattern":27,"./src/fillRect":28,"./src/fillStyle":29,"./src/fillText":30,"./src/globalAlpha":31,"./src/globalCompositeOperation":32,"./src/hitRect":33,"./src/hitRegion":34,"./src/imageSmoothingEnabled":35,"./src/lineStyle":36,"./src/lineTo":37,"./src/moveTo":38,"./src/moveToLineTo":39,"./src/path":40,"./src/placeHolder":41,"./src/quadraticCurveTo":42,"./src/rect":43,"./src/resetTransform":44,"./src/rotate":45,"./src/scale":46,"./src/setTransform":47,"./src/shadowStyle":48,"./src/stroke":49,"./src/strokeArc":50,"./src/strokeRect":51,"./src/strokeStyle":52,"./src/strokeText":53,"./src/text":54,"./src/textStyle":55,"./src/transform":56,"./src/transformPoints":57,"./src/translate":58}]},{},[])
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi91c3IvbGliL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL25vZGVfbW9kdWxlcy9rZXljb2RlL2luZGV4LmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9ub2RlX21vZHVsZXMvcG9pbnQtaW4tcG9seWdvbi9pbmRleC5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL0NhbnZhcy5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL0ltZy5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL0luc3RydWN0aW9uLmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvUmVuZGVyZXIuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9hZGRDb2xvclN0b3AuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9hcmMuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9hcmNUby5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL2JlZ2luUGF0aC5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL2JlemllckN1cnZlVG8uanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9jbGVhclJlY3QuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9jbGlwLmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvY2xpcFBhdGguanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9jbG9zZVBhdGguanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9jcmVhdGVDbGFzcy5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL2NyZWF0ZUxpbmVhckdyYWRpZW50LmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvY3JlYXRlUmFkaWFsR3JhZGllbnQuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9jcmVhdGVSZWd1bGFyUG9seWdvbi5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL2RyYXdDYW52YXMuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9kcmF3SW1hZ2UuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9lbGxpcHNlLmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvZmlsbC5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL2ZpbGxBcmMuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9maWxsQ2FudmFzLmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvZmlsbEltYWdlLmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvZmlsbEltYWdlUGF0dGVybi5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL2ZpbGxSZWN0LmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvZmlsbFN0eWxlLmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvZmlsbFRleHQuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9nbG9iYWxBbHBoYS5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL2dsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbi5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL2hpdFJlY3QuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9oaXRSZWdpb24uanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9pbWFnZVNtb290aGluZ0VuYWJsZWQuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9saW5lU3R5bGUuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9saW5lVG8uanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9tb3ZlVG8uanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9tb3ZlVG9MaW5lVG8uanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9wYXRoLmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvcGxhY2VIb2xkZXIuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9xdWFkcmF0aWNDdXJ2ZVRvLmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvcmVjdC5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL3Jlc2V0VHJhbnNmb3JtLmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvcm90YXRlLmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvc2NhbGUuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9zZXRUcmFuc2Zvcm0uanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9zaGFkb3dTdHlsZS5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL3N0cm9rZS5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL3N0cm9rZUFyYy5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL3N0cm9rZVJlY3QuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy9zdHJva2VTdHlsZS5qcyIsIi90bXAvZTJkMTE2MzIwLTM3NjAtdzA2bGQ1L25vZGVfbW9kdWxlcy9lMmQvc3JjL3N0cm9rZVRleHQuanMiLCIvdG1wL2UyZDExNjMyMC0zNzYwLXcwNmxkNS9ub2RlX21vZHVsZXMvZTJkL3NyYy90ZXh0LmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvdGV4dFN0eWxlLmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvdHJhbnNmb3JtLmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvdHJhbnNmb3JtUG9pbnRzLmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9zcmMvdHJhbnNsYXRlLmpzIiwiL3Vzci9saWIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2V2ZW50cy9ldmVudHMuanMiLCIvdXNyL2xpYi9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvaW5oZXJpdHMvaW5oZXJpdHNfYnJvd3Nlci5qcyIsIi91c3IvbGliL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wYXRoLWJyb3dzZXJpZnkvaW5kZXguanMiLCIvdXNyL2xpYi9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHJvY2Vzcy9icm93c2VyLmpzIiwiL3Vzci9saWIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3V0aWwvc3VwcG9ydC9pc0J1ZmZlckJyb3dzZXIuanMiLCIvdXNyL2xpYi9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvdXRpbC91dGlsLmpzIiwiL3RtcC9lMmQxMTYzMjAtMzc2MC13MDZsZDUvbm9kZV9tb2R1bGVzL2UyZC9pbmRleC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25KQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pzQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNiQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvU0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVrQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCIvLyBTb3VyY2U6IGh0dHA6Ly9qc2ZpZGRsZS5uZXQvdld4OFYvXG4vLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzU2MDMxOTUvZnVsbC1saXN0LW9mLWphdmFzY3JpcHQta2V5Y29kZXNcblxuXG5cbi8qKlxuICogQ29uZW5pZW5jZSBtZXRob2QgcmV0dXJucyBjb3JyZXNwb25kaW5nIHZhbHVlIGZvciBnaXZlbiBrZXlOYW1lIG9yIGtleUNvZGUuXG4gKlxuICogQHBhcmFtIHtNaXhlZH0ga2V5Q29kZSB7TnVtYmVyfSBvciBrZXlOYW1lIHtTdHJpbmd9XG4gKiBAcmV0dXJuIHtNaXhlZH1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oc2VhcmNoSW5wdXQpIHtcbiAgLy8gS2V5Ym9hcmQgRXZlbnRzXG4gIGlmIChzZWFyY2hJbnB1dCAmJiAnb2JqZWN0JyA9PT0gdHlwZW9mIHNlYXJjaElucHV0KSB7XG4gICAgdmFyIGhhc0tleUNvZGUgPSBzZWFyY2hJbnB1dC53aGljaCB8fCBzZWFyY2hJbnB1dC5rZXlDb2RlIHx8IHNlYXJjaElucHV0LmNoYXJDb2RlXG4gICAgaWYgKGhhc0tleUNvZGUpIHNlYXJjaElucHV0ID0gaGFzS2V5Q29kZVxuICB9XG5cbiAgLy8gTnVtYmVyc1xuICBpZiAoJ251bWJlcicgPT09IHR5cGVvZiBzZWFyY2hJbnB1dCkgcmV0dXJuIG5hbWVzW3NlYXJjaElucHV0XVxuXG4gIC8vIEV2ZXJ5dGhpbmcgZWxzZSAoY2FzdCB0byBzdHJpbmcpXG4gIHZhciBzZWFyY2ggPSBTdHJpbmcoc2VhcmNoSW5wdXQpXG5cbiAgLy8gY2hlY2sgY29kZXNcbiAgdmFyIGZvdW5kTmFtZWRLZXkgPSBjb2Rlc1tzZWFyY2gudG9Mb3dlckNhc2UoKV1cbiAgaWYgKGZvdW5kTmFtZWRLZXkpIHJldHVybiBmb3VuZE5hbWVkS2V5XG5cbiAgLy8gY2hlY2sgYWxpYXNlc1xuICB2YXIgZm91bmROYW1lZEtleSA9IGFsaWFzZXNbc2VhcmNoLnRvTG93ZXJDYXNlKCldXG4gIGlmIChmb3VuZE5hbWVkS2V5KSByZXR1cm4gZm91bmROYW1lZEtleVxuXG4gIC8vIHdlaXJkIGNoYXJhY3Rlcj9cbiAgaWYgKHNlYXJjaC5sZW5ndGggPT09IDEpIHJldHVybiBzZWFyY2guY2hhckNvZGVBdCgwKVxuXG4gIHJldHVybiB1bmRlZmluZWRcbn1cblxuLyoqXG4gKiBHZXQgYnkgbmFtZVxuICpcbiAqICAgZXhwb3J0cy5jb2RlWydlbnRlciddIC8vID0+IDEzXG4gKi9cblxudmFyIGNvZGVzID0gZXhwb3J0cy5jb2RlID0gZXhwb3J0cy5jb2RlcyA9IHtcbiAgJ2JhY2tzcGFjZSc6IDgsXG4gICd0YWInOiA5LFxuICAnZW50ZXInOiAxMyxcbiAgJ3NoaWZ0JzogMTYsXG4gICdjdHJsJzogMTcsXG4gICdhbHQnOiAxOCxcbiAgJ3BhdXNlL2JyZWFrJzogMTksXG4gICdjYXBzIGxvY2snOiAyMCxcbiAgJ2VzYyc6IDI3LFxuICAnc3BhY2UnOiAzMixcbiAgJ3BhZ2UgdXAnOiAzMyxcbiAgJ3BhZ2UgZG93bic6IDM0LFxuICAnZW5kJzogMzUsXG4gICdob21lJzogMzYsXG4gICdsZWZ0JzogMzcsXG4gICd1cCc6IDM4LFxuICAncmlnaHQnOiAzOSxcbiAgJ2Rvd24nOiA0MCxcbiAgJ2luc2VydCc6IDQ1LFxuICAnZGVsZXRlJzogNDYsXG4gICdjb21tYW5kJzogOTEsXG4gICdyaWdodCBjbGljayc6IDkzLFxuICAnbnVtcGFkIConOiAxMDYsXG4gICdudW1wYWQgKyc6IDEwNyxcbiAgJ251bXBhZCAtJzogMTA5LFxuICAnbnVtcGFkIC4nOiAxMTAsXG4gICdudW1wYWQgLyc6IDExMSxcbiAgJ251bSBsb2NrJzogMTQ0LFxuICAnc2Nyb2xsIGxvY2snOiAxNDUsXG4gICdteSBjb21wdXRlcic6IDE4MixcbiAgJ215IGNhbGN1bGF0b3InOiAxODMsXG4gICc7JzogMTg2LFxuICAnPSc6IDE4NyxcbiAgJywnOiAxODgsXG4gICctJzogMTg5LFxuICAnLic6IDE5MCxcbiAgJy8nOiAxOTEsXG4gICdgJzogMTkyLFxuICAnWyc6IDIxOSxcbiAgJ1xcXFwnOiAyMjAsXG4gICddJzogMjIxLFxuICBcIidcIjogMjIyLFxufVxuXG4vLyBIZWxwZXIgYWxpYXNlc1xuXG52YXIgYWxpYXNlcyA9IGV4cG9ydHMuYWxpYXNlcyA9IHtcbiAgJ3dpbmRvd3MnOiA5MSxcbiAgJ+KHpyc6IDE2LFxuICAn4oylJzogMTgsXG4gICfijIMnOiAxNyxcbiAgJ+KMmCc6IDkxLFxuICAnY3RsJzogMTcsXG4gICdjb250cm9sJzogMTcsXG4gICdvcHRpb24nOiAxOCxcbiAgJ3BhdXNlJzogMTksXG4gICdicmVhayc6IDE5LFxuICAnY2Fwcyc6IDIwLFxuICAncmV0dXJuJzogMTMsXG4gICdlc2NhcGUnOiAyNyxcbiAgJ3NwYyc6IDMyLFxuICAncGd1cCc6IDMzLFxuICAncGdkbic6IDMzLFxuICAnaW5zJzogNDUsXG4gICdkZWwnOiA0NixcbiAgJ2NtZCc6IDkxXG59XG5cblxuLyohXG4gKiBQcm9ncmFtYXRpY2FsbHkgYWRkIHRoZSBmb2xsb3dpbmdcbiAqL1xuXG4vLyBsb3dlciBjYXNlIGNoYXJzXG5mb3IgKGkgPSA5NzsgaSA8IDEyMzsgaSsrKSBjb2Rlc1tTdHJpbmcuZnJvbUNoYXJDb2RlKGkpXSA9IGkgLSAzMlxuXG4vLyBudW1iZXJzXG5mb3IgKHZhciBpID0gNDg7IGkgPCA1ODsgaSsrKSBjb2Rlc1tpIC0gNDhdID0gaVxuXG4vLyBmdW5jdGlvbiBrZXlzXG5mb3IgKGkgPSAxOyBpIDwgMTM7IGkrKykgY29kZXNbJ2YnK2ldID0gaSArIDExMVxuXG4vLyBudW1wYWQga2V5c1xuZm9yIChpID0gMDsgaSA8IDEwOyBpKyspIGNvZGVzWydudW1wYWQgJytpXSA9IGkgKyA5NlxuXG4vKipcbiAqIEdldCBieSBjb2RlXG4gKlxuICogICBleHBvcnRzLm5hbWVbMTNdIC8vID0+ICdFbnRlcidcbiAqL1xuXG52YXIgbmFtZXMgPSBleHBvcnRzLm5hbWVzID0gZXhwb3J0cy50aXRsZSA9IHt9IC8vIHRpdGxlIGZvciBiYWNrd2FyZCBjb21wYXRcblxuLy8gQ3JlYXRlIHJldmVyc2UgbWFwcGluZ1xuZm9yIChpIGluIGNvZGVzKSBuYW1lc1tjb2Rlc1tpXV0gPSBpXG5cbi8vIEFkZCBhbGlhc2VzXG5mb3IgKHZhciBhbGlhcyBpbiBhbGlhc2VzKSB7XG4gIGNvZGVzW2FsaWFzXSA9IGFsaWFzZXNbYWxpYXNdXG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChwb2ludCwgdnMpIHtcbiAgICAvLyByYXktY2FzdGluZyBhbGdvcml0aG0gYmFzZWQgb25cbiAgICAvLyBodHRwOi8vd3d3LmVjc2UucnBpLmVkdS9Ib21lcGFnZXMvd3JmL1Jlc2VhcmNoL1Nob3J0X05vdGVzL3BucG9seS5odG1sXG4gICAgXG4gICAgdmFyIHggPSBwb2ludFswXSwgeSA9IHBvaW50WzFdO1xuICAgIFxuICAgIHZhciBpbnNpZGUgPSBmYWxzZTtcbiAgICBmb3IgKHZhciBpID0gMCwgaiA9IHZzLmxlbmd0aCAtIDE7IGkgPCB2cy5sZW5ndGg7IGogPSBpKyspIHtcbiAgICAgICAgdmFyIHhpID0gdnNbaV1bMF0sIHlpID0gdnNbaV1bMV07XG4gICAgICAgIHZhciB4aiA9IHZzW2pdWzBdLCB5aiA9IHZzW2pdWzFdO1xuICAgICAgICBcbiAgICAgICAgdmFyIGludGVyc2VjdCA9ICgoeWkgPiB5KSAhPSAoeWogPiB5KSlcbiAgICAgICAgICAgICYmICh4IDwgKHhqIC0geGkpICogKHkgLSB5aSkgLyAoeWogLSB5aSkgKyB4aSk7XG4gICAgICAgIGlmIChpbnRlcnNlY3QpIGluc2lkZSA9ICFpbnNpZGU7XG4gICAgfVxuICAgIFxuICAgIHJldHVybiBpbnNpZGU7XG59O1xuIiwiLy9qc2hpbnQgd29ya2VyOiB0cnVlLCBicm93c2VyOiB0cnVlLCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbmZ1bmN0aW9uIENhbnZhcyh3aWR0aCwgaGVpZ2h0KSB7XHJcblxyXG4gIHZhciBSZW5kZXJlciA9IHJlcXVpcmUoJy4vUmVuZGVyZXInKTtcclxuICB0aGlzLnJlbmRlcmVyID0gbmV3IFJlbmRlcmVyKHdpZHRoLCBoZWlnaHQsIHdpbmRvdy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKSk7XHJcbiAgdGhpcy5maWxsUGF0dGVybiA9IG51bGw7XHJcbiAgdGhpcy5za2lwUGF0dGVybkNyZWF0aW9uID0gZmFsc2U7XHJcblxyXG4gIHJldHVybiBPYmplY3Quc2VhbCh0aGlzKTtcclxufVxyXG5cclxuQ2FudmFzLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiByZW5kZXIoY2hpbGRyZW4pIHtcclxuICB2YXIgcmVzdWx0ID0gW10sXHJcbiAgICAgIGk7XHJcbiAgZm9yIChpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xyXG4gICAgcmVzdWx0LnB1c2goYXJndW1lbnRzW2ldKTtcclxuICB9XHJcblxyXG4gIHRoaXMucmVuZGVyZXIucmVuZGVyKHJlc3VsdCk7XHJcbiAgaWYgKCF0aGlzLnNraXBQYXR0ZXJuQ3JlYXRpb24pIHtcclxuICAgIHRoaXMuZmlsbFBhdHRlcm4gPSB0aGlzLnJlbmRlcmVyLmN0eC5jcmVhdGVQYXR0ZXJuKHRoaXMucmVuZGVyZXIuY2FudmFzLCAnbm8tcmVwZWF0Jyk7XHJcbiAgfVxyXG4gIHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuQ2FudmFzLnByb3RvdHlwZS5zdHlsZSA9IGZ1bmN0aW9uIHN0eWxlKCkge1xyXG4gIHZhciBkZWZzID0gW107XHJcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcclxuICAgIGRlZnMucHVzaChhcmd1bWVudHNbaV0pO1xyXG4gIH1cclxuICB0aGlzLnJlbmRlcmVyLnN0eWxlLmFwcGx5KHRoaXMucmVuZGVyZXIsIGRlZnMpO1xyXG4gIHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuQ2FudmFzLnByb3RvdHlwZS50b0ltYWdlID0gZnVuY3Rpb24gdG9JbWFnZShpbWFnZUlEKSB7XHJcbiAgcmV0dXJuIHRoaXMucmVuZGVyZXIudG9JbWFnZSgpO1xyXG59O1xyXG5cclxuQ2FudmFzLnByb3RvdHlwZS5yZXNpemUgPSBmdW5jdGlvbiByZXNpemUod2lkdGgsIGhlaWdodCkge1xyXG4gIHRoaXMucmVuZGVyZXIucmVzaXplKCt3aWR0aCwgK2hlaWdodCk7XHJcbiAgcmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoQ2FudmFzLnByb3RvdHlwZSwgJ2hlaWdodCcsIHtcclxuICBnZXQ6IGZ1bmN0aW9uKCkge1xyXG4gICAgcmV0dXJuIHRoaXMucmVuZGVyZXIuY2FudmFzLndpZHRoO1xyXG4gIH0sXHJcbiAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICBjb25maWd1cmFibGU6IGZhbHNlXHJcbn0pO1xyXG5cclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KENhbnZhcy5wcm90b3R5cGUsICd3aWR0aCcsIHtcclxuICBnZXQ6IGZ1bmN0aW9uKCkge1xyXG4gICAgcmV0dXJuIHRoaXMucmVuZGVyZXIuY2FudmFzLndpZHRoO1xyXG4gIH0sXHJcbiAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICBjb25maWd1cmFibGU6IGZhbHNlXHJcbn0pO1xyXG5cclxuXHJcbkNhbnZhcy5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUod2lkdGgsIGhlaWdodCwgaWQpIHtcclxuICByZXR1cm4gbmV3IENhbnZhcyh3aWR0aCwgaGVpZ2h0LCBpZCk7XHJcbn07XHJcblxyXG5cclxuT2JqZWN0LnNlYWwoQ2FudmFzKTtcclxuT2JqZWN0LnNlYWwoQ2FudmFzLnByb3RvdHlwZSk7XHJcbm1vZHVsZS5leHBvcnRzID0gQ2FudmFzO1xyXG4iLCIvL2pzaGludCBub2RlOiB0cnVlLCBicm93c2VyOiB0cnVlLCB3b3JrZXI6IHRydWVcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIHBhdGggPSByZXF1aXJlKCdwYXRoJyksXHJcbiAgICBldmVudHMgPSByZXF1aXJlKCdldmVudHMnKSxcclxuICAgIHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XHJcblxyXG51dGlsLmluaGVyaXRzKEltZywgZXZlbnRzLkV2ZW50RW1pdHRlcik7XHJcblxyXG5mdW5jdGlvbiBJbWcoKSB7XHJcbiAgZXZlbnRzLkV2ZW50RW1pdHRlci5jYWxsKHRoaXMpO1xyXG4gIHRoaXMuaW1hZ2VFbGVtZW50ID0gbnVsbDtcclxuICB0aGlzLmltYWdlUGF0dGVybiA9IG51bGw7XHJcbiAgdGhpcy5pbWFnZVBhdHRlcm5SZXBlYXQgPSBudWxsO1xyXG4gIE9iamVjdC5zZWFsKHRoaXMpO1xyXG59XHJcblxyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoSW1nLnByb3RvdHlwZSwgJ3NyYycsIHtcclxuICBzZXQ6IGZ1bmN0aW9uKHZhbCkge1xyXG5cclxuICAgIHZhciBlbGVtZW50ID0gbmV3IEltYWdlKCk7XHJcbiAgICB0aGlzLmltYWdlRWxlbWVudCA9IGVsZW1lbnQ7XHJcbiAgICBlbGVtZW50LnNyYyA9IHZhbDtcclxuXHJcbiAgICBpZiAoZWxlbWVudC5jb21wbGV0ZSkgeyAvL2ZpcmVmb3ggY29tcGF0aWJpbGl0eSBjb2RlXHJcbiAgICAgIHNldFRpbWVvdXQodGhpcy5pbWFnZUxvYWQuYmluZCh0aGlzKSwgMCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBlbGVtZW50Lm9ubG9hZCA9IHRoaXMuaW1hZ2VMb2FkLmJpbmQodGhpcyk7XHJcbiAgICB9XHJcbiAgfSxcclxuICBnZXQ6IGZ1bmN0aW9uKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuaW1hZ2VFbGVtZW50LnNyYztcclxuICB9XHJcbn0pO1xyXG5cclxuSW1nLnByb3RvdHlwZS5pbWFnZUxvYWQgPSBmdW5jdGlvbiBpbWFnZUxvYWQoKSB7XHJcblxyXG4gIHZhciBjdHggPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJykuZ2V0Q29udGV4dCgnMmQnKTtcclxuICB0aGlzLmltYWdlUGF0dGVybiA9IGN0eC5jcmVhdGVQYXR0ZXJuKHRoaXMuaW1hZ2VFbGVtZW50LCAnbm8tcmVwZWF0Jyk7XHJcbiAgdGhpcy5pbWFnZVBhdHRlcm5SZXBlYXQgPSBjdHguY3JlYXRlUGF0dGVybih0aGlzLmltYWdlRWxlbWVudCwgJ3JlcGVhdCcpO1xyXG5cclxuICByZXR1cm4gdGhpcy5lbWl0KCdsb2FkJywgdGhpcyk7XHJcbn07XHJcblxyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoSW1nLnByb3RvdHlwZSwgJ3dpZHRoJywge1xyXG4gIGVudW1lcmFibGU6IHRydWUsXHJcbiAgZ2V0OiBmdW5jdGlvbigpIHtcclxuICAgIHJldHVybiB0aGlzLmltYWdlRWxlbWVudC53aWR0aDtcclxuICB9LFxyXG4gIHNldDogZnVuY3Rpb24odmFsdWUpIHtcclxuICAgIHRoaXMuaW1hZ2VFbGVtZW50LndpZHRoID0gdmFsdWU7XHJcbiAgfVxyXG59KTtcclxuXHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShJbWcucHJvdG90eXBlLCAnaGVpZ2h0Jywge1xyXG4gIGVudW1lcmFibGU6IHRydWUsXHJcbiAgZ2V0OiBmdW5jdGlvbigpIHtcclxuICAgIHJldHVybiB0aGlzLmltYWdlRWxlbWVudC5oZWlnaHQ7XHJcbiAgfSxcclxuICBzZXQ6IGZ1bmN0aW9uKHZhbHVlKSB7XHJcbiAgICB0aGlzLmltYWdlRWxlbWVudC5oZWlnaHQgPSB2YWx1ZTtcclxuICB9XHJcbn0pO1xyXG5cclxuT2JqZWN0LnNlYWwoSW1nKTtcclxuT2JqZWN0LnNlYWwoSW1nLnByb3RvdHlwZSk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IEltZztcclxuIiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbmZ1bmN0aW9uIEluc3RydWN0aW9uKHR5cGUsIHByb3BzKSB7XHJcbiAgdGhpcy50eXBlID0gdHlwZTtcclxuICB0aGlzLnByb3BzID0gcHJvcHM7XHJcbiAgT2JqZWN0LnNlYWwodGhpcyk7XHJcbn1cclxuXHJcbk9iamVjdC5zZWFsKEluc3RydWN0aW9uKTtcclxuT2JqZWN0LnNlYWwoSW5zdHJ1Y3Rpb24ucHJvdG90eXBlKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gSW5zdHJ1Y3Rpb247IiwiLy9qc2hpbnQgbm9kZTogdHJ1ZSwgYnJvd3NlcjogdHJ1ZSwgd29ya2VyOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBjcmVhdGVMaW5lYXJHcmFkaWVudCA9IHJlcXVpcmUoJy4vY3JlYXRlTGluZWFyR3JhZGllbnQnKSxcclxuICAgIGNyZWF0ZVJhZGlhbEdyYWRpZW50ID0gcmVxdWlyZSgnLi9jcmVhdGVSYWRpYWxHcmFkaWVudCcpLFxyXG4gICAgZXZlbnRzID0gcmVxdWlyZSgnZXZlbnRzJyksXHJcbiAgICB1dGlsID0gcmVxdWlyZSgndXRpbCcpLFxyXG4gICAga2V5Y29kZSA9IHJlcXVpcmUoJ2tleWNvZGUnKSxcclxuICAgIHRyYW5zZm9ybVBvaW50cyA9IHJlcXVpcmUoJy4vdHJhbnNmb3JtUG9pbnRzJyksXHJcbiAgICBwb2ludEluUG9seWdvbiA9IHJlcXVpcmUoJ3BvaW50LWluLXBvbHlnb24nKSxcclxuICAgIGlkZW50aXR5ID0gWzEsIDAsIDAsIDEsIDAsIDBdLFxyXG4gICAgSW1nID0gcmVxdWlyZSgnLi9JbWcnKTtcclxuXHJcbnV0aWwuaW5oZXJpdHMoUmVuZGVyZXIsIGV2ZW50cy5FdmVudEVtaXR0ZXIpO1xyXG5cclxuZnVuY3Rpb24gUmVuZGVyZXIod2lkdGgsIGhlaWdodCwgcGFyZW50LCBvcHRzKSB7XHJcbiAgZXZlbnRzLkV2ZW50RW1pdHRlci5jYWxsKHRoaXMpO1xyXG4gIG9wdHMgPSBvcHRzIHx8IHt9O1xyXG5cclxuICAvL3ZpcnR1YWwgc3RhY2tcclxuICB0aGlzLnRyYW5zZm9ybVN0YWNrID0gbmV3IEZsb2F0NjRBcnJheShcclxuICAgICgob3B0cy50cmFuc2Zvcm1TdGFja0NvdW50IHx8IDUwMCkgKyAxKSAqIDYgLy9wcm9wZXJ0aWVzXHJcbiAgKTtcclxuICB0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggPSA2O1xyXG4gIHRoaXMudHJhbnNmb3JtU3RhY2suc2V0KGlkZW50aXR5KTtcclxuXHJcbiAgdGhpcy5maWxsU3R5bGVTdGFjayA9IFtdO1xyXG4gIHRoaXMuc3Ryb2tlU3R5bGVTdGFjayA9IFtdO1xyXG4gIHRoaXMubGluZVN0eWxlU3RhY2sgPSBbXTtcclxuICB0aGlzLnRleHRTdHlsZVN0YWNrID0gW107XHJcbiAgdGhpcy5zaGFkb3dTdHlsZVN0YWNrID0gW107XHJcbiAgdGhpcy5nbG9iYWxBbHBoYVN0YWNrID0gW107XHJcbiAgdGhpcy5pbWFnZVNtb290aGluZ0VuYWJsZWRTdGFjayA9IFtdO1xyXG4gIHRoaXMuZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uU3RhY2sgPSBbXTtcclxuXHJcbiAgdGhpcy5waTIgPSBNYXRoLlBJICogMjtcclxuXHJcbiAgdGhpcy5pc1JlYWR5ID0gZmFsc2U7XHJcbiAgdGhpcy5tb3VzZVN0YXRlID0gJ3VwJztcclxuICB0aGlzLm1vdXNlRGF0YSA9IHtcclxuICAgIHg6IDAsXHJcbiAgICB5OiAwLFxyXG4gICAgc3RhdGU6IHRoaXMubW91c2VTdGF0ZSxcclxuICAgIGNsaWNrZWQ6IGZhbHNlLFxyXG4gICAgYWN0aXZlUmVnaW9uczogW11cclxuICB9O1xyXG4gIHRoaXMubGFzdE1vdXNlRXZlbnQgPSBudWxsO1xyXG4gIHRoaXMucmFuTW91c2VFdmVudCA9IGZhbHNlO1xyXG4gIHRoaXMubW91c2VSZWdpb25zID0gW107XHJcbiAgdGhpcy5hY3RpdmVSZWdpb25zID0gW107XHJcbiAgdGhpcy5zdHlsZVF1ZXVlID0gW107XHJcblxyXG4gIC8vdXNlciBpbnB1dCBoZXJlXHJcbiAgdGhpcy5rZXlEYXRhID0ge307XHJcblxyXG4gIHRoaXMudG91Y2hEYXRhID0ge1xyXG4gICAgdG91Y2hlczogW10sXHJcbiAgICBpZHM6IFtdXHJcbiAgfTtcclxuICB0aGlzLmxhc3RUb3VjaEV2ZW50ID0gbnVsbDtcclxuICB0aGlzLnJhblRvdWNoRXZlbnQgPSBmYWxzZTtcclxuICB0aGlzLnRvdWNoUmVnaW9ucyA9IFtdO1xyXG5cclxuICAvL3NldCBwYXJlbnRcclxuICBpZiAocGFyZW50ICYmIHBhcmVudC5ub2RlVHlwZSA9PT0gMSkge1xyXG4gICAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7XHJcbiAgfSBlbHNlIHtcclxuICAgIHRoaXMucGFyZW50ID0gd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xyXG4gICAgdGhpcy5wYXJlbnQuc3R5bGUubWFyZ2luID0gJzAgYXV0byc7XHJcbiAgICB0aGlzLnBhcmVudC5zdHlsZS53aWR0aCA9IHdpZHRoICsgJ3B4JztcclxuICAgIHRoaXMucGFyZW50LnN0eWxlLmhlaWdodCA9IGhlaWdodCArICdweCc7XHJcbiAgICB3aW5kb3cuZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCh0aGlzLnBhcmVudCk7XHJcbiAgfVxyXG5cclxuICAvL3NldCB3aWR0aCBhbmQgaGVpZ2h0IGF1dG9tYXRpY2FsbHlcclxuICBpZiAoIXdpZHRoIHx8IHdpZHRoIDw9IDApIHtcclxuICAgIHdpZHRoID0gd2luZG93LmlubmVyV2lkdGg7XHJcbiAgfVxyXG5cclxuICBpZiAoIWhlaWdodCB8fCBoZWlnaHQgPD0gMCkge1xyXG4gICAgaGVpZ2h0ID0gd2luZG93LmlubmVySGVpZ2h0O1xyXG4gIH1cclxuXHJcbiAgdGhpcy5jYW52YXMgPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XHJcblxyXG4gIC8vZm9jdXNhYmxlIGNhbnZhcyBidWdmaXhcclxuICB0aGlzLmNhbnZhcy50YWJJbmRleCA9IDE7XHJcblxyXG4gIHRoaXMuY3R4ID0gdGhpcy5jYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcclxuXHJcbiAgdGhpcy5jYW52YXMud2lkdGggPSB3aWR0aDtcclxuICB0aGlzLmNhbnZhcy5oZWlnaHQgPSBoZWlnaHQ7XHJcbiAgdGhpcy5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5jYW52YXMpO1xyXG5cclxuICAvL2hvb2sgbW91c2UsIGtleWJvYXJkLCBhbmQga2V5Ym9hcmQgZXZlbnRzIHJpZ2h0IGF3YXlcclxuICB0aGlzLmhvb2tNb3VzZUV2ZW50cygpO1xyXG4gIHRoaXMuaG9va0tleWJvYXJkRXZlbnRzKCk7XHJcbiAgdGhpcy5ob29rVG91Y2hFdmVudHMoKTtcclxuXHJcbiAgdGhpcy5ib3VuZEhvb2tSZW5kZXJGdW5jdGlvbiA9IHRoaXMuaG9va1JlbmRlci5iaW5kKHRoaXMpO1xyXG4gIE9iamVjdC5zZWFsKHRoaXMpO1xyXG59XHJcblxyXG5SZW5kZXJlci5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gcmVuZGVyKGFyZ3MpIHtcclxuICB2YXIgaSxcclxuICAgICAgbGVuLFxyXG4gICAgICBjaGlsZCxcclxuICAgICAgcHJvcHMsXHJcbiAgICAgIHR5cGUsXHJcbiAgICAgIGNhY2hlLFxyXG4gICAgICBtYXRyaXggPSBbMSwgMCwgMCwgMSwgMCwgMF0sXHJcbiAgICAgIHNpbnIsXHJcbiAgICAgIGNvc3IsXHJcbiAgICAgIGN0eCA9IHRoaXMuY3R4LFxyXG4gICAgICBjaGlsZHJlbiA9IFtdLFxyXG4gICAgICBjb25jYXQgPSBjaGlsZHJlbi5jb25jYXQ7XHJcblxyXG4gIC8vZmx1c2ggdGhlIHZpcnR1YWwgc3RhY2tcclxuXHJcbiAgdGhpcy5maWxsU3R5bGVTdGFjay5zcGxpY2UoMCwgdGhpcy5maWxsU3R5bGVTdGFjay5sZW5ndGgpO1xyXG4gIHRoaXMuc3Ryb2tlU3R5bGVTdGFjay5zcGxpY2UoMCwgdGhpcy5zdHJva2VTdHlsZVN0YWNrLmxlbmd0aCk7XHJcbiAgdGhpcy5saW5lU3R5bGVTdGFjay5zcGxpY2UoMCwgdGhpcy5saW5lU3R5bGVTdGFjay5sZW5ndGgpO1xyXG4gIHRoaXMudGV4dFN0eWxlU3RhY2suc3BsaWNlKDAsIHRoaXMudGV4dFN0eWxlU3RhY2subGVuZ3RoKTtcclxuICB0aGlzLnNoYWRvd1N0eWxlU3RhY2suc3BsaWNlKDAsIHRoaXMuc2hhZG93U3R5bGVTdGFjay5sZW5ndGgpO1xyXG4gIHRoaXMuZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uU3RhY2suc3BsaWNlKDAsIHRoaXMuZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uU3RhY2subGVuZ3RoKTtcclxuICB0aGlzLmdsb2JhbEFscGhhU3RhY2suc3BsaWNlKDAsIHRoaXMuZ2xvYmFsQWxwaGFTdGFjay5sZW5ndGgpO1xyXG4gIHRoaXMuaW1hZ2VTbW9vdGhpbmdFbmFibGVkU3RhY2suc3BsaWNlKDAsIHRoaXMuaW1hZ2VTbW9vdGhpbmdFbmFibGVkU3RhY2subGVuZ3RoKTtcclxuXHJcbiAgZm9yIChpID0gMCwgbGVuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICBjaGlsZHJlbi5wdXNoKGFyZ3VtZW50c1tpXSk7XHJcbiAgfVxyXG5cclxuICAvL2xvb3Agb3ZlciBldmVyeSBjaGlsZFxyXG4gIGZvciAoaSA9IDAsIGxlbiA9IGNoaWxkcmVuLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICBjaGlsZCA9IGNoaWxkcmVuW2ldO1xyXG5cclxuICAgIC8vZmxhdHRlbmluZyBhbGdvcml0aG1cclxuICAgIGlmIChjaGlsZCAmJiBjaGlsZC5jb25zdHJ1Y3RvciA9PT0gQXJyYXkpIHtcclxuICAgICAgY2hpbGRyZW4gPSBjb25jYXQuYXBwbHkoW10sIGNoaWxkcmVuKTtcclxuICAgICAgY2hpbGQgPSBjaGlsZHJlbltpXTtcclxuICAgICAgd2hpbGUgKGNoaWxkICYmIGNoaWxkLmNvbnN0cnVjdG9yID09PSBBcnJheSkge1xyXG4gICAgICAgIGNoaWxkcmVuID0gY29uY2F0LmFwcGx5KFtdLCBjaGlsZHJlbik7XHJcbiAgICAgICAgY2hpbGQgPSBjaGlsZHJlbltpXTtcclxuICAgICAgfVxyXG4gICAgICBsZW4gPSBjaGlsZHJlbi5sZW5ndGg7XHJcbiAgICB9XHJcblxyXG4gICAgLy9jaGlsZCBtdXN0IGJlIHRydXRoeVxyXG4gICAgaWYgKCFjaGlsZCkge1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICAvL3NldCBwcm9wcyBhbmQgdHlwZSBvYmplY3RcclxuICAgIHByb3BzID0gY2hpbGQucHJvcHM7XHJcbiAgICB0eXBlID0gY2hpbGQudHlwZTtcclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3RyYW5zZm9ybScpIHtcclxuICAgICAgbWF0cml4WzBdID0gdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA2XTtcclxuICAgICAgbWF0cml4WzFdID0gdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA1XTtcclxuICAgICAgbWF0cml4WzJdID0gdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA0XTtcclxuICAgICAgbWF0cml4WzNdID0gdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAzXTtcclxuICAgICAgbWF0cml4WzRdID0gdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAyXTtcclxuICAgICAgbWF0cml4WzVdID0gdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAxXTtcclxuXHJcblxyXG4gICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggKz0gNjtcclxuICAgICAgaWYgKHRoaXMudHJhbnNmb3JtU3RhY2tJbmRleCA+IHRoaXMudHJhbnNmb3JtU3RhY2subGVuZ3RoKSB7XHJcbiAgICAgICAgdGhpcy5pbmNyZWFzZVRyYW5zZm9ybVN0YWNrU2l6ZSgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDZdID0gLy9kXHJcbiAgICAgICAgbWF0cml4WzBdICogcHJvcHNbMF0gKyBtYXRyaXhbMl0gKiBwcm9wc1sxXTtcclxuICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA1XSA9IC8vYlxyXG4gICAgICAgIG1hdHJpeFsxXSAqIHByb3BzWzBdICsgbWF0cml4WzNdICogcHJvcHNbMV07XHJcbiAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gNF0gPSAvL2NcclxuICAgICAgICBtYXRyaXhbMF0gKiBwcm9wc1syXSArIG1hdHJpeFsyXSAqIHByb3BzWzNdO1xyXG4gICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdID0gLy9kXHJcbiAgICAgICAgbWF0cml4WzFdICogcHJvcHNbMl0gKyBtYXRyaXhbM10gKiBwcm9wc1szXTtcclxuICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAyXSA9IC8vZVxyXG4gICAgICAgIG1hdHJpeFswXSAqIHByb3BzWzRdICsgbWF0cml4WzJdICogcHJvcHNbNV0gKyBtYXRyaXhbNF07XHJcbiAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gMV0gPSAvL2ZcclxuICAgICAgICBtYXRyaXhbMV0gKiBwcm9wc1s0XSArIG1hdHJpeFszXSAqIHByb3BzWzVdICsgbWF0cml4WzVdO1xyXG5cclxuICAgICAgY3R4LnNldFRyYW5zZm9ybShcclxuICAgICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDZdLFxyXG4gICAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gNV0sXHJcbiAgICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSxcclxuICAgICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdLFxyXG4gICAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gMl0sXHJcbiAgICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAxXVxyXG4gICAgICApO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdzZXRUcmFuc2Zvcm0nKSB7XHJcbiAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tJbmRleCArPSA2O1xyXG4gICAgICBpZiAodGhpcy50cmFuc2Zvcm1TdGFja0luZGV4ID4gdGhpcy50cmFuc2Zvcm1TdGFjay5sZW5ndGgpIHtcclxuICAgICAgICB0aGlzLmluY3JlYXNlVHJhbnNmb3JtU3RhY2tTaXplKCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gNl0gPSBwcm9wc1swXTsvL2FcclxuICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA1XSA9IHByb3BzWzFdOy8vYlxyXG4gICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdID0gcHJvcHNbMl07Ly9jXHJcbiAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gM10gPSBwcm9wc1szXTsvL2RcclxuICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAyXSA9IHByb3BzWzRdOy8vZVxyXG4gICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdID0gcHJvcHNbNV07Ly9mXHJcbiAgICAgIGN0eC5zZXRUcmFuc2Zvcm0ocHJvcHNbMF0sIHByb3BzWzFdLCBwcm9wc1syXSwgcHJvcHNbM10sIHByb3BzWzRdLCBwcm9wc1s1XSk7XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnc2NhbGUnKSB7XHJcbiAgICAgIG1hdHJpeFswXSA9IHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gNl07XHJcbiAgICAgIG1hdHJpeFsxXSA9IHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gNV07XHJcbiAgICAgIG1hdHJpeFsyXSA9IHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gNF07XHJcbiAgICAgIG1hdHJpeFszXSA9IHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gM107XHJcbiAgICAgIG1hdHJpeFs0XSA9IHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gMl07XHJcbiAgICAgIG1hdHJpeFs1XSA9IHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gMV07XHJcblxyXG4gICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggKz0gNjtcclxuICAgICAgaWYgKHRoaXMudHJhbnNmb3JtU3RhY2tJbmRleCA+IHRoaXMudHJhbnNmb3JtU3RhY2subGVuZ3RoKSB7XHJcbiAgICAgICAgdGhpcy5pbmNyZWFzZVRyYW5zZm9ybVN0YWNrU2l6ZSgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDZdID0gbWF0cml4WzBdICogcHJvcHMueDsgLy9hXHJcbiAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gNV0gPSBtYXRyaXhbMV0gKiBwcm9wcy54OyAvL2JcclxuICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSA9IG1hdHJpeFsyXSAqIHByb3BzLnk7IC8vY1xyXG4gICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdID0gbWF0cml4WzNdICogcHJvcHMueTsgLy9kXHJcbiAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gMl0gPSBtYXRyaXhbNF07IC8vZVxyXG4gICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdID0gbWF0cml4WzVdOyAvL2ZcclxuXHJcbiAgICAgIGN0eC5zZXRUcmFuc2Zvcm0oXHJcbiAgICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA2XSxcclxuICAgICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDVdLFxyXG4gICAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gNF0sXHJcbiAgICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAzXSxcclxuICAgICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDJdLFxyXG4gICAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gMV1cclxuICAgICAgKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAndHJhbnNsYXRlJykge1xyXG4gICAgICBtYXRyaXhbMF0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDZdO1xyXG4gICAgICBtYXRyaXhbMV0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDVdO1xyXG4gICAgICBtYXRyaXhbMl0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdO1xyXG4gICAgICBtYXRyaXhbM10gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdO1xyXG4gICAgICBtYXRyaXhbNF0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDJdO1xyXG4gICAgICBtYXRyaXhbNV0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdO1xyXG5cclxuICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4ICs9IDY7XHJcbiAgICAgIGlmICh0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggPiB0aGlzLnRyYW5zZm9ybVN0YWNrLmxlbmd0aCkge1xyXG4gICAgICAgIHRoaXMuaW5jcmVhc2VUcmFuc2Zvcm1TdGFja1NpemUoKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA2XSA9IG1hdHJpeFswXTsgLy9hXHJcbiAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gNV0gPSBtYXRyaXhbMV07IC8vYlxyXG4gICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdID0gbWF0cml4WzJdOyAvL2NcclxuICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAzXSA9IG1hdHJpeFszXTsgLy9kXHJcbiAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gMl0gPSBtYXRyaXhbNF0gKyBtYXRyaXhbMF0gKiBwcm9wcy54ICsgbWF0cml4WzJdICogcHJvcHMueTsgLy9lXHJcbiAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gMV0gPSBtYXRyaXhbNV0gKyBtYXRyaXhbMV0gKiBwcm9wcy54ICsgbWF0cml4WzNdICogcHJvcHMueTsgLy9mXHJcblxyXG4gICAgICBjdHguc2V0VHJhbnNmb3JtKFxyXG4gICAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gNl0sXHJcbiAgICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA1XSxcclxuICAgICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdLFxyXG4gICAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gM10sXHJcbiAgICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAyXSxcclxuICAgICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdXHJcbiAgICAgICk7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3JvdGF0ZScpIHtcclxuICAgICAgbWF0cml4WzBdID0gdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA2XTtcclxuICAgICAgbWF0cml4WzFdID0gdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA1XTtcclxuICAgICAgbWF0cml4WzJdID0gdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA0XTtcclxuICAgICAgbWF0cml4WzNdID0gdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAzXTtcclxuICAgICAgbWF0cml4WzRdID0gdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAyXTtcclxuICAgICAgbWF0cml4WzVdID0gdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAxXTtcclxuICAgICAgY29zciA9IE1hdGguY29zKHByb3BzLnIpO1xyXG4gICAgICBzaW5yID0gTWF0aC5zaW4ocHJvcHMucik7XHJcblxyXG4gICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggKz0gNjtcclxuICAgICAgaWYgKHRoaXMudHJhbnNmb3JtU3RhY2tJbmRleCA+IHRoaXMudHJhbnNmb3JtU3RhY2subGVuZ3RoKSB7XHJcbiAgICAgICAgdGhpcy5pbmNyZWFzZVRyYW5zZm9ybVN0YWNrU2l6ZSgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDZdID1cclxuICAgICAgICBtYXRyaXhbMF0gKiBjb3NyICsgbWF0cml4WzJdICogc2lucjsgLy9hXHJcbiAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gNV0gPVxyXG4gICAgICAgIG1hdHJpeFsxXSAqIGNvc3IgKyBtYXRyaXhbM10gKiBzaW5yOyAvL2JcclxuICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSA9XHJcbiAgICAgICAgbWF0cml4WzBdICogLXNpbnIgKyBtYXRyaXhbMl0gKiBjb3NyOyAvL2NcclxuICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAzXSA9XHJcbiAgICAgICAgbWF0cml4WzFdICogLXNpbnIgKyBtYXRyaXhbM10gKiBjb3NyOyAvL2RcclxuICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAyXSA9IG1hdHJpeFs0XTsgLy9lXHJcbiAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gMV0gPSBtYXRyaXhbNV07Ly9mXHJcblxyXG4gICAgICBjdHguc2V0VHJhbnNmb3JtKFxyXG4gICAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gNl0sXHJcbiAgICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSA1XSxcclxuICAgICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdLFxyXG4gICAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tbdGhpcy50cmFuc2Zvcm1TdGFja0luZGV4IC0gM10sXHJcbiAgICAgICAgdGhpcy50cmFuc2Zvcm1TdGFja1t0aGlzLnRyYW5zZm9ybVN0YWNrSW5kZXggLSAyXSxcclxuICAgICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdXHJcbiAgICAgICk7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3Jlc3RvcmUnKSB7XHJcbiAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtPSA2O1xyXG4gICAgICBtYXRyaXhbMF0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDZdO1xyXG4gICAgICBtYXRyaXhbMV0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDVdO1xyXG4gICAgICBtYXRyaXhbMl0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdO1xyXG4gICAgICBtYXRyaXhbM10gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdO1xyXG4gICAgICBtYXRyaXhbNF0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDJdO1xyXG4gICAgICBtYXRyaXhbNV0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdO1xyXG5cclxuICAgICAgY3R4LnNldFRyYW5zZm9ybShtYXRyaXhbMF0sIG1hdHJpeFsxXSwgbWF0cml4WzJdLCBtYXRyaXhbM10sIG1hdHJpeFs0XSwgbWF0cml4WzVdKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZmlsbFJlY3QnKSB7XHJcbiAgICAgIGN0eC5maWxsUmVjdChwcm9wcy54LCBwcm9wcy55LCBwcm9wcy53aWR0aCwgcHJvcHMuaGVpZ2h0KTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnc3Ryb2tlUmVjdCcpIHtcclxuICAgICAgY3R4LnN0cm9rZVJlY3QocHJvcHMueCwgcHJvcHMueSwgcHJvcHMud2lkdGgsIHByb3BzLmhlaWdodCk7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2NsZWFyUmVjdCcpIHtcclxuICAgICAgY3R4LmNsZWFyUmVjdChwcm9wcy54LCBwcm9wcy55LCBwcm9wcy53aWR0aCwgcHJvcHMuaGVpZ2h0KTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAncmVjdCcpIHtcclxuICAgICAgY3R4LnJlY3QocHJvcHMueCwgcHJvcHMueSwgcHJvcHMud2lkdGgsIHByb3BzLmhlaWdodCk7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2ZpbGxTdHlsZScpIHtcclxuICAgICAgdGhpcy5maWxsU3R5bGVTdGFjay5wdXNoKGN0eC5maWxsU3R5bGUpO1xyXG4gICAgICBjdHguZmlsbFN0eWxlID0gcHJvcHMudmFsdWU7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3N0cm9rZVN0eWxlJykge1xyXG4gICAgICB0aGlzLnN0cm9rZVN0eWxlU3RhY2sucHVzaChjdHguc3Ryb2tlU3R5bGUpO1xyXG4gICAgICBjdHguc3Ryb2tlU3R5bGUgPSBwcm9wcy52YWx1ZTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZW5kRmlsbFN0eWxlJykge1xyXG4gICAgICBjdHguZmlsbFN0eWxlID0gdGhpcy5maWxsU3R5bGVTdGFjay5wb3AoKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZW5kU3Ryb2tlU3R5bGUnKSB7XHJcbiAgICAgIGN0eC5zdHJva2VTdHlsZSA9IHRoaXMuc3Ryb2tlU3R5bGVTdGFjay5wb3AoKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG4gICAgaWYgKHR5cGUgPT09ICdsaW5lU3R5bGUnKSB7XHJcbiAgICAgIHRoaXMubGluZVN0eWxlU3RhY2sucHVzaCh7XHJcbiAgICAgICAgbGluZVdpZHRoOiBjdHgubGluZVdpZHRoLFxyXG4gICAgICAgIGxpbmVDYXA6IGN0eC5saW5lQ2FwLFxyXG4gICAgICAgIGxpbmVKb2luOiBjdHgubGluZUpvaW4sXHJcbiAgICAgICAgbWl0ZXJMaW1pdDogY3R4Lm1pdGVyTGltaXQsXHJcbiAgICAgICAgbGluZURhc2g6IGN0eC5nZXRMaW5lRGFzaCgpLFxyXG4gICAgICAgIGxpbmVEYXNoT2Zmc2V0OiBjdHgubGluZURhc2hPZmZzZXRcclxuICAgICAgfSk7XHJcblxyXG4gICAgICBpZiAocHJvcHMubGluZVdpZHRoICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LmxpbmVXaWR0aCA9IHByb3BzLmxpbmVXaWR0aDtcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJvcHMubGluZUNhcCAhPT0gbnVsbCkge1xyXG4gICAgICAgIGN0eC5saW5lQ2FwID0gcHJvcHMubGluZUNhcDtcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJvcHMubGluZUpvaW4gIT09IG51bGwpIHtcclxuICAgICAgICBjdHgubGluZUpvaW4gPSBwcm9wcy5saW5lSm9pbjtcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJvcHMubWl0ZXJMaW1pdCAhPT0gbnVsbCkge1xyXG4gICAgICAgIGN0eC5taXRlckxpbWl0ID0gcHJvcHMubWl0ZXJMaW1pdDtcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJvcHMubGluZURhc2gubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIGN0eC5zZXRMaW5lRGFzaChwcm9wcy5saW5lRGFzaCk7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHByb3BzLmxpbmVEYXNoT2Zmc2V0ICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LmxpbmVEYXNoT2Zmc2V0ID0gcHJvcHMubGluZURhc2hPZmZzZXQ7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZW5kTGluZVN0eWxlJykge1xyXG4gICAgICBjYWNoZSA9IHRoaXMubGluZVN0eWxlU3RhY2sucG9wKCk7XHJcbiAgICAgIGN0eC5saW5lV2lkdGggPSBjYWNoZS5saW5lV2lkdGg7XHJcbiAgICAgIGN0eC5saW5lQ2FwID0gY2FjaGUubGluZUNhcDtcclxuICAgICAgY3R4LmxpbmVKb2luID0gY2FjaGUubGluZUpvaW47XHJcbiAgICAgIGN0eC5taXRlckxpbWl0ID0gY2FjaGUubWl0ZXJMaW1pdDtcclxuICAgICAgY3R4LnNldExpbmVEYXNoKGNhY2hlLmxpbmVEYXNoKTtcclxuICAgICAgY3R4LmxpbmVEYXNoT2Zmc2V0ID0gY2FjaGUubGluZURhc2hPZmZzZXQ7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3RleHRTdHlsZScpIHtcclxuICAgICAgdGhpcy50ZXh0U3R5bGVTdGFjay5wdXNoKHtcclxuICAgICAgICBmb250OiBjdHguZm9udCxcclxuICAgICAgICB0ZXh0QWxpZ246IGN0eC50ZXh0QWxpZ24sXHJcbiAgICAgICAgdGV4dEJhc2VsaW5lOiBjdHgudGV4dEJhc2VsaW5lLFxyXG4gICAgICAgIGRpcmVjdGlvbjogY3R4LmRpcmVjdGlvblxyXG4gICAgICB9KTtcclxuICAgICAgaWYgKHByb3BzLmZvbnQgIT09IG51bGwpIHtcclxuICAgICAgICBjdHguZm9udCA9IHByb3BzLmZvbnQ7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHByb3BzLnRleHRBbGlnbiAhPT0gbnVsbCkge1xyXG4gICAgICAgIGN0eC50ZXh0QWxpZ24gPSBwcm9wcy50ZXh0QWxpZ247XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHByb3BzLnRleHRCYXNlbGluZSAhPT0gbnVsbCkge1xyXG4gICAgICAgIGN0eC50ZXh0QmFzZWxpbmUgPSBwcm9wcy50ZXh0QmFzZWxpbmU7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHByb3BzLmxpbmVKb2luICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LmRpcmVjdGlvbiA9IHByb3BzLmRpcmVjdGlvbjtcclxuICAgICAgfVxyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdlbmRUZXh0U3R5bGUnKSB7XHJcbiAgICAgIGNhY2hlID0gdGhpcy50ZXh0U3R5bGVTdGFjay5wb3AoKTtcclxuICAgICAgY3R4LmZvbnQgPSBjYWNoZS5mb250O1xyXG4gICAgICBjdHgudGV4dEFsaWduID0gY2FjaGUudGV4dEFsaWduO1xyXG4gICAgICBjdHgudGV4dEJhc2VsaW5lID0gY2FjaGUudGV4dEJhc2VsaW5lO1xyXG4gICAgICBjdHguZGlyZWN0aW9uID0gY2FjaGUuZGlyZWN0aW9uO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdzaGFkb3dTdHlsZScpIHtcclxuICAgICAgdGhpcy5zaGFkb3dTdHlsZVN0YWNrLnB1c2goe1xyXG4gICAgICAgIHNoYWRvd0JsdXI6IGN0eC5zaGFkb3dCbHVyLFxyXG4gICAgICAgIHNoYWRvd0NvbG9yOiBjdHguc2hhZG93Q29sb3IsXHJcbiAgICAgICAgc2hhZG93T2Zmc2V0WDogY3R4LnNoYWRvd09mZnNldFgsXHJcbiAgICAgICAgc2hhZG93T2Zmc2V0WTogY3R4LnNoYWRvd09mZnNldFlcclxuICAgICAgfSk7XHJcbiAgICAgIGlmIChwcm9wcy5zaGFkb3dCbHVyICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LnNoYWRvd0JsdXIgPSBwcm9wcy5zaGFkb3dCbHVyO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChwcm9wcy5zaGFkb3dDb2xvciAhPT0gbnVsbCkge1xyXG4gICAgICAgIGN0eC5zaGFkb3dDb2xvciA9IHByb3BzLnNoYWRvd0NvbG9yO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChwcm9wcy5zaGFkb3dPZmZzZXRYICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LnNoYWRvd09mZnNldFggPSBwcm9wcy5zaGFkb3dPZmZzZXRYO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChwcm9wcy5zaGFkb3dPZmZzZXRZICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LnNoYWRvd09mZnNldFkgPSBwcm9wcy5zaGFkb3dPZmZzZXRZO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2VuZFNoYWRvd1N0eWxlJykge1xyXG4gICAgICBjYWNoZSA9IHRoaXMuc2hhZG93U3R5bGVTdGFjay5wb3AoKTtcclxuICAgICAgY3R4LnNoYWRvd0JsdXIgPSBjYWNoZS5zaGFkb3dCbHVyO1xyXG4gICAgICBjdHguc2hhZG93Q29sb3IgPSBjYWNoZS5zaGFkb3dDb2xvcjtcclxuICAgICAgY3R4LnNoYWRvd09mZnNldFggPSBjYWNoZS5zaGFkb3dPZmZzZXRYO1xyXG4gICAgICBjdHguc2hhZG93T2Zmc2V0WSA9IGNhY2hlLnNoYWRvd09mZnNldFk7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3N0cm9rZVRleHQnKSB7XHJcbiAgICAgIGlmIChwcm9wcy5tYXhXaWR0aCkge1xyXG4gICAgICAgIGN0eC5zdHJva2VUZXh0KHByb3BzLnRleHQsIHByb3BzLngsIHByb3BzLnksIHByb3BzLm1heFdpZHRoKTtcclxuICAgICAgICBjb250aW51ZTtcclxuICAgICAgfVxyXG4gICAgICBjdHguc3Ryb2tlVGV4dChwcm9wcy50ZXh0LCBwcm9wcy54LCBwcm9wcy55KTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdmaWxsVGV4dCcpIHtcclxuICAgICAgaWYgKHByb3BzLm1heFdpZHRoKSB7XHJcbiAgICAgICAgY3R4LmZpbGxUZXh0KHByb3BzLnRleHQsIHByb3BzLngsIHByb3BzLnksIHByb3BzLm1heFdpZHRoKTtcclxuICAgICAgICBjb250aW51ZTtcclxuICAgICAgfVxyXG4gICAgICBjdHguZmlsbFRleHQocHJvcHMudGV4dCwgcHJvcHMueCwgcHJvcHMueSk7XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAndGV4dCcpIHtcclxuICAgICAgaWYgKHByb3BzLm1heFdpZHRoICE9PSAwKSB7XHJcbiAgICAgICAgaWYgKHByb3BzLmZpbGwpIHtcclxuICAgICAgICAgIGN0eC5maWxsVGV4dChwcm9wcy50ZXh0LCBwcm9wcy54LCBwcm9wcy55LCBwcm9wcy5tYXhXaWR0aCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChwcm9wcy5zdHJva2UpIHtcclxuICAgICAgICAgIGN0eC5zdHJva2VUZXh0KHByb3BzLnRleHQsIHByb3BzLngsIHByb3BzLnksIHByb3BzLm1heFdpZHRoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChwcm9wcy5maWxsKSB7XHJcbiAgICAgICAgY3R4LmZpbGxUZXh0KHByb3BzLnRleHQsIHByb3BzLngsIHByb3BzLnkpO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChwcm9wcy5zdHJva2UpIHtcclxuICAgICAgICBjdHguc3Ryb2tlVGV4dChwcm9wcy50ZXh0LCBwcm9wcy54LCBwcm9wcy55KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG5cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2RyYXdJbWFnZScpIHtcclxuICAgICAgaWYgKCFwcm9wcy5pbWcpIHtcclxuICAgICAgICBjb250aW51ZTtcclxuICAgICAgfVxyXG4gICAgICBjYWNoZSA9IHByb3BzLmltZy5jb25zdHJ1Y3RvciA9PT0gSW1nID8gcHJvcHMuaW1nLmltYWdlRWxlbWVudCB8fCBuZXcgSW1hZ2UoKSA6IHByb3BzLmltZztcclxuICAgICAgY3R4LmRyYXdJbWFnZShjYWNoZSB8fCBuZXcgSW1hZ2UoKSwgcHJvcHMuZHgsIHByb3BzLmR5KTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdkcmF3SW1hZ2VTaXplJykge1xyXG4gICAgICBpZiAoIXByb3BzLmltZykge1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcbiAgICAgIGNhY2hlID0gcHJvcHMuaW1nLmNvbnN0cnVjdG9yID09PSBJbWcgPyBwcm9wcy5pbWcuaW1hZ2VFbGVtZW50IHx8IG5ldyBJbWFnZSgpIDogcHJvcHMuaW1nO1xyXG4gICAgICBjdHguZHJhd0ltYWdlKGNhY2hlLCBwcm9wcy5keCwgcHJvcHMuZHksIHByb3BzLmRXaWR0aCwgcHJvcHMuZEhlaWdodCk7XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZHJhd0ltYWdlU291cmNlJykge1xyXG4gICAgICBpZiAoIXByb3BzLmltZykge1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcbiAgICAgIGNhY2hlID0gcHJvcHMuaW1nLmNvbnN0cnVjdG9yID09PSBJbWcgPyBwcm9wcy5pbWcuaW1hZ2VFbGVtZW50IHx8IG5ldyBJbWFnZSgpIDogcHJvcHMuaW1nO1xyXG4gICAgICBjdHguZHJhd0ltYWdlKGNhY2hlLCBwcm9wcy5zeCwgcHJvcHMuc3ksIHByb3BzLnNXaWR0aCwgcHJvcHMuc0hlaWdodCwgcHJvcHMuZHgsIHByb3BzLmR5LCBwcm9wcy5kV2lkdGgsIHByb3BzLmRIZWlnaHQpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2ZpbGxJbWFnZVBhdHRlcm4nKSB7XHJcbiAgICAgIGlmICghcHJvcHMuaW1nKSB7XHJcbiAgICAgICAgY29udGludWU7XHJcbiAgICAgIH1cclxuICAgICAgY3R4LmZpbGxTdHlsZSA9IHByb3BzLmltZy5pbWFnZVBhdHRlcm5SZXBlYXQ7XHJcbiAgICAgIGN0eC50cmFuc2xhdGUocHJvcHMuZHgsIHByb3BzLmR5KTtcclxuICAgICAgY3R4LmZpbGxSZWN0KDAsIDAsIHByb3BzLmRXaWR0aCwgcHJvcHMuZEhlaWdodCk7XHJcbiAgICAgIGN0eC5yZXN0b3JlKCk7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2ZpbGxJbWFnZScpIHtcclxuICAgICAgaWYgKCFwcm9wcy5pbWcpIHtcclxuICAgICAgICBjb250aW51ZTtcclxuICAgICAgfVxyXG4gICAgICBjYWNoZSA9IHByb3BzLmltZy5pbWFnZUVsZW1lbnQ7XHJcbiAgICAgIGN0eC5zYXZlKCk7XHJcbiAgICAgIGN0eC5maWxsU3R5bGUgPSBwcm9wcy5pbWcuaW1hZ2VQYXR0ZXJuO1xyXG4gICAgICBjdHgudHJhbnNsYXRlKHByb3BzLmR4LCBwcm9wcy5keSk7XHJcbiAgICAgIGN0eC5maWxsUmVjdCgwLCAwLCBjYWNoZS53aWR0aCwgY2FjaGUuaGVpZ2h0KTtcclxuICAgICAgY3R4LnJlc3RvcmUoKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZmlsbEltYWdlU2l6ZScpIHtcclxuICAgICAgaWYgKCFwcm9wcy5pbWcpIHtcclxuICAgICAgICBjb250aW51ZTtcclxuICAgICAgfVxyXG4gICAgICBjYWNoZSA9IHByb3BzLmltZy5pbWFnZUVsZW1lbnQ7XHJcbiAgICAgIGN0eC5zYXZlKCk7XHJcbiAgICAgIGN0eC5maWxsU3R5bGUgPSBwcm9wcy5pbWcuaW1hZ2VQYXR0ZXJuO1xyXG4gICAgICBjdHgudHJhbnNsYXRlKHByb3BzLmR4LCBwcm9wcy5keSk7XHJcbiAgICAgIGN0eC5zY2FsZShwcm9wcy5kV2lkdGggLyBjYWNoZS53aWR0aCwgcHJvcHMuZEhlaWdodCAvIGNhY2hlLmhlaWdodCk7XHJcbiAgICAgIGN0eC5maWxsUmVjdCgwLCAwLCBjYWNoZS53aWR0aCwgY2FjaGUuaGVpZ2h0KTtcclxuICAgICAgY3R4LnJlc3RvcmUoKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZmlsbEltYWdlU291cmNlJykge1xyXG4gICAgICBpZiAoIXByb3BzLmltZykge1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcbiAgICAgIGN0eC5zYXZlKCk7XHJcbiAgICAgIGN0eC5maWxsU3R5bGUgPSBwcm9wcy5pbWcuaW1hZ2VQYXR0ZXJuO1xyXG4gICAgICBjdHgudHJhbnNsYXRlKHByb3BzLmR4LCBwcm9wcy5keSk7XHJcbiAgICAgIGN0eC5zY2FsZShwcm9wcy5kV2lkdGggLyBwcm9wcy5zV2lkdGgsIHByb3BzLmRIZWlnaHQgLyBwcm9wcy5zSGVpZ2h0KTtcclxuICAgICAgY3R4LnRyYW5zbGF0ZSgtcHJvcHMuc3gsIC1wcm9wcy5zeSk7XHJcbiAgICAgIGN0eC5maWxsUmVjdChwcm9wcy5zeCwgcHJvcHMuc3ksIHByb3BzLnNXaWR0aCwgcHJvcHMuc0hlaWdodCk7XHJcbiAgICAgIGN0eC5yZXN0b3JlKCk7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdmaWxsQ2FudmFzJykge1xyXG4gICAgICBpZiAoIXByb3BzLmltZykge1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcbiAgICAgIGNhY2hlID0gcHJvcHMuaW1nO1xyXG4gICAgICBjdHguc2F2ZSgpO1xyXG4gICAgICBjdHguZmlsbFN0eWxlID0gY2FjaGUuZmlsbFBhdHRlcm47XHJcbiAgICAgIGN0eC50cmFuc2xhdGUocHJvcHMuZHgsIHByb3BzLmR5KTtcclxuICAgICAgY3R4LmZpbGxSZWN0KDAsIDAsIGNhY2hlLndpZHRoLCBjYWNoZS5oZWlnaHQpO1xyXG4gICAgICBjdHgucmVzdG9yZSgpO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdmaWxsQ2FudmFzU2l6ZScpIHtcclxuICAgICAgaWYgKCFwcm9wcy5pbWcpIHtcclxuICAgICAgICBjb250aW51ZTtcclxuICAgICAgfVxyXG4gICAgICBjYWNoZSA9IHByb3BzLmltZztcclxuICAgICAgY3R4LnNhdmUoKTtcclxuICAgICAgY3R4LmZpbGxTdHlsZSA9IGNhY2hlLmZpbGxQYXR0ZXJuO1xyXG4gICAgICBjdHgudHJhbnNsYXRlKHByb3BzLmR4LCBwcm9wcy5keSk7XHJcbiAgICAgIGN0eC5zY2FsZShwcm9wcy5kV2lkdGggLyBjYWNoZS53aWR0aCwgcHJvcHMuZEhlaWdodCAvIGNhY2hlLmhlaWdodCk7XHJcbiAgICAgIGN0eC5maWxsUmVjdCgwLCAwLCBjYWNoZS53aWR0aCwgY2FjaGUuaGVpZ2h0KTtcclxuICAgICAgY3R4LnJlc3RvcmUoKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZmlsbENhbnZhc1NvdXJjZScpIHtcclxuICAgICAgaWYgKCFwcm9wcy5pbWcpIHtcclxuICAgICAgICBjb250aW51ZTtcclxuICAgICAgfVxyXG4gICAgICBjdHguc2F2ZSgpO1xyXG4gICAgICBjdHguZmlsbFN0eWxlID0gcHJvcHMuaW1nLmZpbGxQYXR0ZXJuO1xyXG4gICAgICBjdHgudHJhbnNsYXRlKHByb3BzLmR4LCBwcm9wcy5keSk7XHJcbiAgICAgIGN0eC5zY2FsZShwcm9wcy5kV2lkdGggLyBwcm9wcy5zV2lkdGgsIHByb3BzLmRIZWlnaHQgLyBwcm9wcy5zSGVpZ2h0KTtcclxuICAgICAgY3R4LnRyYW5zbGF0ZSgtcHJvcHMuc3gsIC1wcm9wcy5zeSk7XHJcbiAgICAgIGN0eC5maWxsUmVjdChwcm9wcy5zeCwgcHJvcHMuc3ksIHByb3BzLnNXaWR0aCwgcHJvcHMuc0hlaWdodCk7XHJcbiAgICAgIGN0eC5yZXN0b3JlKCk7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2RyYXdDYW52YXMnKSB7XHJcbiAgICAgIGlmICghcHJvcHMuaW1nKSB7XHJcbiAgICAgICAgY29udGludWU7XHJcbiAgICAgIH1cclxuICAgICAgY3R4LmRyYXdJbWFnZShwcm9wcy5pbWcucmVuZGVyZXIuY2FudmFzLCBwcm9wcy5keCwgcHJvcHMuZHkpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2RyYXdDYW52YXNTaXplJykge1xyXG4gICAgICBpZiAoIXByb3BzLmltZykge1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcbiAgICAgIGN0eC5kcmF3SW1hZ2UocHJvcHMuaW1nLnJlbmRlcmVyLmNhbnZhcywgcHJvcHMuZHgsIHByb3BzLmR5LCBwcm9wcy5kV2lkdGgsIHByb3BzLmRIZWlnaHQpO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdkcmF3Q2FudmFzU291cmNlJykge1xyXG4gICAgICBpZiAoIXByb3BzLmltZykge1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcbiAgICAgIGN0eC5kcmF3SW1hZ2UocHJvcHMuaW1nLnJlbmRlcmVyLmNhbnZhcywgcHJvcHMuc3gsIHByb3BzLnN5LCBwcm9wcy5zV2lkdGgsIHByb3BzLnNIZWlnaHQsIHByb3BzLmR4LCBwcm9wcy5keSwgcHJvcHMuZFdpZHRoLCBwcm9wcy5kSGVpZ2h0KTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnc3Ryb2tlQXJjJykge1xyXG4gICAgICBjdHguYmVnaW5QYXRoKCk7XHJcbiAgICAgIGN0eC5hcmMocHJvcHMueCwgcHJvcHMueSwgcHJvcHMuciwgcHJvcHMuc3RhcnRBbmdsZSwgcHJvcHMuZW5kQW5nbGUpO1xyXG4gICAgICBjdHguY2xvc2VQYXRoKCk7XHJcbiAgICAgIGN0eC5zdHJva2UoKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnc3Ryb2tlQXJjLWNvdW50ZXJjbG9ja3dpc2UnKSB7XHJcbiAgICAgIGN0eC5iZWdpblBhdGgoKTtcclxuICAgICAgY3R4LmFyYyhwcm9wcy54LCBwcm9wcy55LCBwcm9wcy5yLCBwcm9wcy5zdGFydEFuZ2xlLCBwcm9wcy5lbmRBbmdsZSwgdHJ1ZSk7XHJcbiAgICAgIGN0eC5jbG9zZVBhdGgoKTtcclxuICAgICAgY3R4LnN0cm9rZSgpO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZmlsbEFyYycpIHtcclxuICAgICAgY3R4LmJlZ2luUGF0aCgpO1xyXG4gICAgICBjdHguYXJjKHByb3BzLngsIHByb3BzLnksIHByb3BzLnIsIHByb3BzLnN0YXJ0QW5nbGUsIHByb3BzLmVuZEFuZ2xlKTtcclxuICAgICAgY3R4LmNsb3NlUGF0aCgpO1xyXG4gICAgICBjdHguZmlsbCgpO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdmaWxsQXJjLWNvdW50ZXJjbG9ja3dpc2UnKSB7XHJcbiAgICAgIGN0eC5iZWdpblBhdGgoKTtcclxuICAgICAgY3R4LmFyYyhwcm9wcy54LCBwcm9wcy55LCBwcm9wcy5yLCBwcm9wcy5zdGFydEFuZ2xlLCBwcm9wcy5lbmRBbmdsZSwgdHJ1ZSk7XHJcbiAgICAgIGN0eC5jbG9zZVBhdGgoKTtcclxuICAgICAgY3R4LmZpbGwoKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnbW92ZVRvJykge1xyXG4gICAgICBjdHgubW92ZVRvKHByb3BzLngsIHByb3BzLnkpO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdsaW5lVG8nKSB7XHJcbiAgICAgIGN0eC5saW5lVG8ocHJvcHMueCwgcHJvcHMueSk7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2JlemllckN1cnZlVG8nKSB7XHJcbiAgICAgIGN0eC5iZXppZXJDdXJ2ZVRvKHByb3BzLmNwMXgsIHByb3BzLmNwMXksIHByb3BzLmNwMngsIHByb3BzLmNwMnksIHByb3BzLngsIHByb3BzLnkpO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdxdWFkcmF0aWNDdXJ2ZVRvJykge1xyXG4gICAgICBjdHgucXVhZHJhdGljQ3VydmVUbyhwcm9wcy5jcHgsIHByb3BzLmNweSwgcHJvcHMueCwgcHJvcHMueSk7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2FudGljbG9ja3dpc2UtYXJjJykge1xyXG4gICAgICBjdHguYXJjKHByb3BzLngsIHByb3BzLnksIHByb3BzLnIsIHByb3BzLnN0YXJ0QW5nbGUsIHByb3BzLmVuZEFuZ2xlLCB0cnVlKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnYXJjJykge1xyXG4gICAgICBjdHguYXJjKHByb3BzLngsIHByb3BzLnksIHByb3BzLnIsIHByb3BzLnN0YXJ0QW5nbGUsIHByb3BzLmVuZEFuZ2xlKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdmdWxsLWFyYycpIHtcclxuICAgICAgY3R4LmFyYyhwcm9wcy54LCBwcm9wcy55LCBwcm9wcy5yLCAwLCB0aGlzLnBpMik7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3F1aWNrLWFyYycpIHtcclxuICAgICAgY3R4LmFyYygwLCAwLCBwcm9wcy5yLCAwLCB0aGlzLnBpMik7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2FyY1RvJykge1xyXG4gICAgICBjdHguYXJjVG8ocHJvcHMueDEsIHByb3BzLnkxLCBwcm9wcy54MiwgcHJvcHMueTIsIHByb3BzLnIpO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdhbnRpY2xvY2t3aXNlLWVsbGlwc2UnKSB7XHJcbiAgICAgIHRoaXMuc2F2ZSgpO1xyXG4gICAgICB0aGlzLnRyYW5zbGF0ZShwcm9wcy54LCBwcm9wcy55KTtcclxuICAgICAgdGhpcy5yb3RhdGUocHJvcHMucm90YXRpb24pO1xyXG4gICAgICB0aGlzLnNjYWxlKHByb3BzLnJhZGl1c1gsIHByb3BzLnJhZGl1c1kpO1xyXG4gICAgICB0aGlzLmFyYygwLCAwLCAxLCBwcm9wcy5zdGFydEFuZ2xlLCBwcm9wcy5lbmRBbmdsZSwgdHJ1ZSk7XHJcbiAgICAgIHRoaXMucmVzdG9yZSgpO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdlbGxpcHNlJykge1xyXG4gICAgICB0aGlzLnNhdmUoKTtcclxuICAgICAgdGhpcy50cmFuc2xhdGUocHJvcHMueCwgcHJvcHMueSk7XHJcbiAgICAgIHRoaXMucm90YXRlKHByb3BzLnJvdGF0aW9uKTtcclxuICAgICAgdGhpcy5zY2FsZShwcm9wcy5yYWRpdXNYLCBwcm9wcy5yYWRpdXNZKTtcclxuICAgICAgdGhpcy5hcmMoMCwgMCwgMSwgcHJvcHMuc3RhcnRBbmdsZSwgcHJvcHMuZW5kQW5nbGUpO1xyXG4gICAgICB0aGlzLnJlc3RvcmUoKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZnVsbC1lbGxpcHNlJykge1xyXG4gICAgICB0aGlzLnNhdmUoKTtcclxuICAgICAgdGhpcy50cmFuc2xhdGUocHJvcHMueCwgcHJvcHMueSk7XHJcbiAgICAgIHRoaXMucm90YXRlKHByb3BzLnJvdGF0aW9uKTtcclxuICAgICAgdGhpcy5zY2FsZShwcm9wcy5yYWRpdXNYLCBwcm9wcy5yYWRpdXNZKTtcclxuICAgICAgdGhpcy5hcmMoMCwgMCwgMSwgMCwgdGhpcy5waTIpO1xyXG4gICAgICB0aGlzLnJlc3RvcmUoKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAncXVpY2stZWxsaXBzZScpIHtcclxuICAgICAgdGhpcy5zYXZlKCk7XHJcbiAgICAgIHRoaXMudHJhbnNsYXRlKHByb3BzLngsIHByb3BzLnkpO1xyXG4gICAgICB0aGlzLnNjYWxlKHByb3BzLnJhZGl1c1gsIHByb3BzLnJhZGl1c1kpO1xyXG4gICAgICB0aGlzLmFyYygwLCAwLCAxLCAwLCB0aGlzLnBpMik7XHJcbiAgICAgIHRoaXMucmVzdG9yZSgpO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdnbG9iYWxDb21wb3NpdGVPcGVyYXRpb24nKSB7XHJcbiAgICAgIHRoaXMuZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uU3RhY2sucHVzaChjdHguZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uKTtcclxuICAgICAgY3R4Lmdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbiA9IHByb3BzLnZhbHVlO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdlbmRHbG9iYWxDb21wb3NpdGVPcGVyYXRpb24nKSB7XHJcbiAgICAgIGN0eC5nbG9iYWxDb21wb3NpdGVPcGVyYXRpb24gPSB0aGlzLmdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvblN0YWNrLnBvcCgpO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdmaWxsJykge1xyXG4gICAgICBjdHguZmlsbCgpO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdzdHJva2UnKSB7XHJcbiAgICAgIGN0eC5zdHJva2UoKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnYmVnaW5DbGlwJykge1xyXG4gICAgICBjdHguc2F2ZSgpO1xyXG4gICAgICBjdHguYmVnaW5QYXRoKCk7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2NsaXAnKSB7XHJcbiAgICAgIGN0eC5jbGlwKCk7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2VuZENsaXAnKSB7XHJcbiAgICAgIGN0eC5yZXN0b3JlKCk7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2JlZ2luUGF0aCcpIHtcclxuICAgICAgY3R4LmJlZ2luUGF0aCgpO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdjbG9zZVBhdGgnKSB7XHJcbiAgICAgIGN0eC5jbG9zZVBhdGgoKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZ2xvYmFsQWxwaGEnKSB7XHJcbiAgICAgIHRoaXMuZ2xvYmFsQWxwaGFTdGFjay5wdXNoKGN0eC5nbG9iYWxBbHBoYSk7XHJcbiAgICAgIGN0eC5nbG9iYWxBbHBoYSAqPSBwcm9wcy52YWx1ZTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZW5kR2xvYmFsQWxwaGEnKSB7XHJcbiAgICAgIGN0eC5nbG9iYWxBbHBoYSA9IHRoaXMuZ2xvYmFsQWxwaGFTdGFjay5wb3AoKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnaGl0UmVnaW9uJykge1xyXG4gICAgICBtYXRyaXhbMF0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDZdO1xyXG4gICAgICBtYXRyaXhbMV0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDVdO1xyXG4gICAgICBtYXRyaXhbMl0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdO1xyXG4gICAgICBtYXRyaXhbM10gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdO1xyXG4gICAgICBtYXRyaXhbNF0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDJdO1xyXG4gICAgICBtYXRyaXhbNV0gPSB0aGlzLnRyYW5zZm9ybVN0YWNrW3RoaXMudHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdO1xyXG4gICAgICBjYWNoZSA9IHtcclxuICAgICAgICBpZDogcHJvcHMuaWQsXHJcbiAgICAgICAgcG9pbnRzOiB0cmFuc2Zvcm1Qb2ludHMocHJvcHMucG9pbnRzLCBtYXRyaXgpXHJcbiAgICAgIH07XHJcbiAgICAgIHRoaXMubW91c2VSZWdpb25zLnB1c2goY2FjaGUpO1xyXG4gICAgICB0aGlzLnRvdWNoUmVnaW9ucy5wdXNoKGNhY2hlKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnaW1hZ2VTbW9vdGhpbmdFbmFibGVkJykge1xyXG4gICAgICB0aGlzLmltYWdlU21vb3RoaW5nRW5hYmxlZFN0YWNrLnB1c2goY3R4LmltYWdlU21vb3RoaW5nRW5hYmxlZCk7XHJcbiAgICAgIGN0eC5pbWFnZVNtb290aGluZ0VuYWJsZWQgPSBwcm9wcy52YWx1ZTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZW5kSW1hZ2VTbW9vdGhpbmdFbmFibGVkJykge1xyXG4gICAgICBjdHguaW1hZ2VTbW9vdGhpbmdFbmFibGVkID0gdGhpcy5pbWFnZVNtb290aGluZ0VuYWJsZWRTdGFjay5wb3AoKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZXR1cm4gdGhpcy5hcHBseVN0eWxlcygpO1xyXG59O1xyXG5cclxuUmVuZGVyZXIuY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHdpZHRoLCBoZWlnaHQsIHBhcmVudCwgd29ya2VyKSB7XHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAyKSB7XHJcbiAgICByZXR1cm4gbmV3IFJlbmRlcmVyKHdpZHRoLCBoZWlnaHQsIHBhcmVudCwgd29ya2VyKTtcclxuICB9XHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDIpIHtcclxuICAgIHJldHVybiBuZXcgUmVuZGVyZXIod2lkdGgsIGhlaWdodCk7XHJcbiAgfVxyXG4gIHJldHVybiBuZXcgUmVuZGVyZXIoKTtcclxufTtcclxuXHJcblxyXG5SZW5kZXJlci5wcm90b3R5cGUucmVzaXplID0gZnVuY3Rpb24od2lkdGgsIGhlaWdodCkge1xyXG4gIC8vb25seSByZXNpemUgaWYgdGhlIHNpemVzIGFyZSBkaWZmZXJlbnQsIGJlY2F1c2UgaXQgY2xlYXJzIHRoZSBjYW52YXNcclxuICBpZiAodGhpcy5jYW52YXMud2lkdGgudG9TdHJpbmcoKSAhPT0gd2lkdGgudG9TdHJpbmcoKSkge1xyXG4gICAgdGhpcy5jYW52YXMud2lkdGggPSB3aWR0aDtcclxuICAgIGlmICh0aGlzLnBhcmVudCAhPT0gZG9jdW1lbnQuYm9keSkge1xyXG4gICAgICB0aGlzLnBhcmVudC5zdHlsZS53aWR0aCA9IHdpZHRoICsgXCJweFwiO1xyXG4gICAgfVxyXG4gIH1cclxuICBpZiAodGhpcy5jYW52YXMuaGVpZ2h0LnRvU3RyaW5nKCkgIT09IGhlaWdodC50b1N0cmluZygpKSB7XHJcbiAgICB0aGlzLmNhbnZhcy5oZWlnaHQgPSBoZWlnaHQ7XHJcbiAgICBpZiAodGhpcy5wYXJlbnQgIT09IGRvY3VtZW50LmJvZHkpIHtcclxuICAgICAgdGhpcy5wYXJlbnQuc3R5bGUuaGVpZ2h0ID0gaGVpZ2h0ICsgXCJweFwiO1xyXG4gICAgfVxyXG4gIH1cclxufTtcclxuXHJcblJlbmRlcmVyLnByb3RvdHlwZS50b0ltYWdlID0gZnVuY3Rpb24gdG9JbWFnZSgpIHtcclxuICB2YXIgSW1nID0gcmVxdWlyZSgnLi9JbWcnKTtcclxuICB2YXIgaW1nID0gbmV3IEltZygpO1xyXG4gIGltZy5zcmMgPSB0aGlzLmNhbnZhcy50b0RhdGFVUkwoJ2ltYWdlL3BuZycpO1xyXG4gIHJldHVybiBpbWc7XHJcbn07XHJcblxyXG5cclxuUmVuZGVyZXIucHJvdG90eXBlLmhvb2tSZW5kZXIgPSBmdW5jdGlvbiBob29rUmVuZGVyKCkge1xyXG5cclxuICAvL0lmIHRoZSBjbGllbnQgaGFzIHNlbnQgYSAncmVhZHknIGNvbW1hbmQgYW5kIGEgdHJlZSBleGlzdHNcclxuICBpZiAodGhpcy5pc1JlYWR5KSB7XHJcbiAgICAvL2ZpcmUgdGhlIG1vdXNlIGV2ZW50IGFnYWluIGlmIGl0IHdhc24ndCBydW5cclxuICAgIGlmICh0aGlzLmxhc3RNb3VzZUV2ZW50ICYmICF0aGlzLnJhbk1vdXNlRXZlbnQpIHtcclxuICAgICAgdGhpcy5tb3VzZU1vdmUodGhpcy5sYXN0TW91c2VFdmVudCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMubGFzdFRvdWNoRXZlbnQgJiYgIXRoaXMucmFuVG91Y2hFdmVudCkge1xyXG4gICAgICB0aGlzLnRvdWNoRXZlbnQodGhpcy5sYXN0TW91c2VFdmVudCk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5maXJlRnJhbWUoKTtcclxuXHJcbiAgfVxyXG5cclxuICByZXR1cm4gd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLmJvdW5kSG9va1JlbmRlckZ1bmN0aW9uKTtcclxufTtcclxuXHJcblJlbmRlcmVyLnByb3RvdHlwZS5ob29rTW91c2VFdmVudHMgPSBmdW5jdGlvbiBob29rTW91c2VFdmVudHMoKSB7XHJcbiAgLy93aGVuZXZlciB0aGUgbW91c2UgbW92ZXMsIHJlcG9ydCB0aGUgcG9zaXRpb25cclxuICB3aW5kb3cuZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdGhpcy5tb3VzZU1vdmUuYmluZCh0aGlzKSk7XHJcblxyXG4gIC8vb25seSByZXBvcnQgbW91c2Vkb3duIG9uIGNhbnZhc1xyXG4gIHRoaXMuY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIHRoaXMubW91c2VEb3duLmJpbmQodGhpcykpO1xyXG5cclxuICAvL21vdXNlIHVwIGNhbiBoYXBwZW4gYW55d2hlcmVcclxuICByZXR1cm4gd2luZG93LmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLm1vdXNlVXAuYmluZCh0aGlzKSk7XHJcbn07XHJcblxyXG5SZW5kZXJlci5wcm90b3R5cGUuaG9va1RvdWNoRXZlbnRzID0gZnVuY3Rpb24gaG9va1RvdWNoRXZlbnRzKCkge1xyXG5cclxuICByZXR1cm4gWyd0b3VjaHN0YXJ0JywgJ3RvdWNobW92ZScsICd0b3VjaGVuZCcsICd0b3VjaGNhbmNlbCddLmZvckVhY2goZnVuY3Rpb24oZXZ0KSB7XHJcbiAgICByZXR1cm4gd2luZG93LmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoZXZ0LCB0aGlzLnRvdWNoRXZlbnQuYmluZCh0aGlzKSk7XHJcbiAgfSwgdGhpcyk7XHJcbn07XHJcblxyXG5SZW5kZXJlci5wcm90b3R5cGUudG91Y2hFdmVudCA9IGZ1bmN0aW9uIHRvdWNoRXZlbnQoZXZ0KSB7XHJcbiAgdmFyIHJlY3QgPSB0aGlzLmNhbnZhcy5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxcclxuICAgICAgdG91Y2hSZWdpb25zID0gdGhpcy50b3VjaFJlZ2lvbnMuc2xpY2UoKSxcclxuICAgICAgbW91c2VQb2ludCA9IFswLDBdLFxyXG4gICAgICByZWdpb247XHJcblxyXG4gIHZhciBwcmV2aW91c0lkcyA9IHRoaXMudG91Y2hEYXRhLmlkcy5zcGxpY2UoMCwgdGhpcy50b3VjaERhdGEuaWRzLmxlbmd0aCksXHJcbiAgICBwcmV2aW91c1RvdWNoZXMgPSB0aGlzLnRvdWNoRGF0YS50b3VjaGVzLnNwbGljZSgwLCB0aGlzLnRvdWNoRGF0YS50b3VjaGVzLmxlbmd0aCksXHJcbiAgICB0b3VjaFBvaW50O1xyXG5cclxuICBmb3IodmFyIGkgPSAwOyBpIDwgZXZ0LnRvdWNoZXMubGVuZ3RoOyBpKyspIHtcclxuICAgIHZhciB0b3VjaCA9IGV2dC50b3VjaGVzLml0ZW0oaSk7XHJcbiAgICB2YXIgaW5kZXggPSBwcmV2aW91c0lkcy5pbmRleE9mKHRvdWNoLmlkZW50aWZpZXIpO1xyXG5cclxuICAgIHRvdWNoUG9pbnQgPSBpbmRleCA9PT0gLTEgPyB7IHg6IDAsIHk6IDAsIGFjdGl2ZVJlZ2lvbnM6IFtdLCBpZDogdG91Y2guaWRlbnRpZmllciwgdG91Y2hlZDogdHJ1ZSwgaGVsZDogZmFsc2UgfSA6IHByZXZpb3VzVG91Y2hlc1tpbmRleF07XHJcbiAgICB0b3VjaFBvaW50LnRvdWNoZWQgPSBpbmRleCA9PT0gLTE7XHJcbiAgICB0b3VjaFBvaW50LmhlbGQgPSAhdG91Y2hQb2ludC50b3VjaGVkO1xyXG5cclxuICAgIHRvdWNoUG9pbnQueCA9IHRvdWNoLmNsaWVudFggLSByZWN0LmxlZnQ7XHJcbiAgICB0b3VjaFBvaW50LnkgPSB0b3VjaC5jbGllbnRZIC0gcmVjdC50b3A7XHJcbiAgICB0aGlzLnRvdWNoRGF0YS50b3VjaGVzLnB1c2godG91Y2hQb2ludCk7XHJcbiAgICB0aGlzLnRvdWNoRGF0YS5pZHMucHVzaCh0b3VjaFBvaW50LmlkZW50aWZpZXIpO1xyXG5cclxuICAgIG1vdXNlUG9pbnRbMF0gPSB0b3VjaFBvaW50Lng7XHJcbiAgICBtb3VzZVBvaW50WzFdID0gdG91Y2hQb2ludC55O1xyXG5cclxuICAgIHRvdWNoUG9pbnQuYWN0aXZlUmVnaW9ucy5zcGxpY2UoMCwgdG91Y2hQb2ludC5hY3RpdmVSZWdpb25zLmxlbmd0aCk7XHJcblxyXG4gICAgZm9yKHZhciBqID0gMDsgaiA8IHRoaXMubW91c2VSZWdpb25zLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgIHJlZ2lvbiA9IHRvdWNoUmVnaW9uc1tqXTtcclxuICAgICAgaWYgKHBvaW50SW5Qb2x5Z29uKG1vdXNlUG9pbnQsIHJlZ2lvbi5wb2ludHMpKSB7XHJcbiAgICAgICAgdG91Y2hQb2ludC5hY3RpdmVSZWdpb25zLnB1c2gocmVnaW9uLmlkKTtcclxuICAgICAgICB0b3VjaFJlZ2lvbnMuc3BsaWNlKHRvdWNoUmVnaW9ucy5pbmRleE9mKHJlZ2lvbiksIDEpO1xyXG4gICAgICAgIGogLT0gMTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcblxyXG4gIHRoaXMubGFzdFRvdWNoRXZlbnQgPSBldnQ7XHJcbiAgdGhpcy5yYW5Ub3VjaEV2ZW50ID0gdHJ1ZTtcclxuXHJcblxyXG4gIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gIHRoaXMuZW1pdCgndG91Y2gnLCB0aGlzLnRvdWNoRGF0YSk7XHJcbiAgcmV0dXJuIGZhbHNlO1xyXG59O1xyXG5cclxuUmVuZGVyZXIucHJvdG90eXBlLm1vdXNlTW92ZSA9IGZ1bmN0aW9uIG1vdXNlTW92ZShldnQpIHtcclxuICAvL2dldCBib3VuZGluZyByZWN0YW5nbGVcclxuICB2YXIgcmVjdCA9IHRoaXMuY2FudmFzLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLFxyXG4gICAgICBtb3VzZVBvaW50ID0gWzAsMF0sXHJcbiAgICAgIHJlZ2lvbjtcclxuICB0aGlzLmxhc3RNb3VzZUV2ZW50ID0gZXZ0O1xyXG4gIHRoaXMucmFuTW91c2VFdmVudCA9IHRydWU7XHJcblxyXG4gIG1vdXNlUG9pbnRbMF0gPSBldnQuY2xpZW50WCAtIHJlY3QubGVmdDtcclxuICBtb3VzZVBvaW50WzFdID0gZXZ0LmNsaWVudFkgLSByZWN0LnRvcDtcclxuXHJcbiAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMubW91c2VSZWdpb25zLmxlbmd0aDsgaSsrKSB7XHJcbiAgICByZWdpb24gPSB0aGlzLm1vdXNlUmVnaW9uc1tpXTtcclxuICAgIGlmIChwb2ludEluUG9seWdvbihtb3VzZVBvaW50LCByZWdpb24ucG9pbnRzKSkge1xyXG4gICAgICB0aGlzLmFjdGl2ZVJlZ2lvbnMucHVzaChyZWdpb24uaWQpO1xyXG4gICAgICB0aGlzLm1vdXNlUmVnaW9ucy5zcGxpY2UodGhpcy5tb3VzZVJlZ2lvbnMuaW5kZXhPZihyZWdpb24pLCAxKTtcclxuICAgICAgaSAtPSAxO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgdGhpcy5tb3VzZURhdGEueCA9IG1vdXNlUG9pbnRbMF07XHJcbiAgdGhpcy5tb3VzZURhdGEueSA9IG1vdXNlUG9pbnRbMV07XHJcblxyXG4gIC8vbmV3IHN0YXRlIGlzIGRvd24sIGxhc3Qgc3RhdGUgaXMgdXBcclxuXHJcbiAgdGhpcy5tb3VzZURhdGEuY2xpY2tlZCA9IHRoaXMubW91c2VTdGF0ZSA9PT0gJ2Rvd24nICYmIHRoaXMubW91c2VEYXRhLnN0YXRlID09PSAndXAnO1xyXG5cclxuICB0aGlzLm1vdXNlRGF0YS5zdGF0ZSA9IHRoaXMubW91c2VTdGF0ZTtcclxuICB0aGlzLm1vdXNlRGF0YS5hY3RpdmVSZWdpb25zID0gdGhpcy5hY3RpdmVSZWdpb25zO1xyXG5cclxuICB0aGlzLmVtaXQoJ21vdXNlJywgdGhpcy5tb3VzZURhdGEpO1xyXG4gIC8vZGVmYXVsdCBldmVudCBzdHVmZlxyXG4gIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gIHJldHVybiBmYWxzZTtcclxufTtcclxuXHJcblJlbmRlcmVyLnByb3RvdHlwZS5tb3VzZURvd24gPSBmdW5jdGlvbiBtb3VzZU1vdmUoZXZ0KSB7XHJcbiAgLy9zZXQgdGhlIG1vdXNlU3RhdGUgZG93blxyXG4gIHRoaXMubW91c2VTdGF0ZSA9ICdkb3duJztcclxuICB0aGlzLmNhbnZhcy5mb2N1cygpO1xyXG4gIC8vZGVmZXIgdG8gbW91c2VNb3ZlXHJcbiAgcmV0dXJuIHRoaXMubW91c2VNb3ZlKGV2dCk7XHJcbn07XHJcblxyXG5SZW5kZXJlci5wcm90b3R5cGUubW91c2VVcCA9IGZ1bmN0aW9uIG1vdXNlTW92ZShldnQpIHtcclxuICAvL3NldCB0aGUgbW91c2Ugc3RhdGVcclxuICB0aGlzLm1vdXNlU3RhdGUgPSAndXAnO1xyXG4gIC8vZGVmZXIgdG8gbW91c2UgbW92ZVxyXG4gIHJldHVybiB0aGlzLm1vdXNlTW92ZShldnQpO1xyXG59O1xyXG5cclxuUmVuZGVyZXIucHJvdG90eXBlLmhvb2tLZXlib2FyZEV2ZW50cyA9IGZ1bmN0aW9uIGhvb2tLZXlib2FyZEV2ZW50cygpIHtcclxuXHJcbiAgLy9ldmVyeSBjb2RlIGluIGtleWNvZGUuY29kZSBuZWVkcyB0byBiZSBvbiBrZXlEYXRhXHJcbiAgZm9yICh2YXIgbmFtZSBpbiBrZXljb2RlLmNvZGUpIHtcclxuICAgIGlmIChrZXljb2RlLmNvZGUuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcclxuICAgICAgdGhpcy5rZXlEYXRhW25hbWVdID0gXCJ1cFwiO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy9rZXlkb3duIHNob3VsZCBvbmx5IGhhcHBlbiBPTiB0aGUgY2FudmFzXHJcbiAgdGhpcy5jYW52YXMuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIHRoaXMua2V5RG93bi5iaW5kKHRoaXMpKTtcclxuXHJcbiAgLy9idXQga2V5dXAgc2hvdWxkIGJlIGNhcHR1cmVkIGV2ZXJ5d2hlcmVcclxuICByZXR1cm4gd2luZG93LmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2tleXVwJywgdGhpcy5rZXlVcC5iaW5kKHRoaXMpKTtcclxufTtcclxuXHJcblJlbmRlcmVyLnByb3RvdHlwZS5rZXlDaGFuZ2UgPSBmdW5jdGlvbiBrZXlDaGFuZ2UoZXZ0KSB7XHJcbiAgdGhpcy5lbWl0KCdrZXknLCB0aGlzLmtleURhdGEpO1xyXG4gIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gIHJldHVybiBmYWxzZTtcclxufTtcclxuXHJcblJlbmRlcmVyLnByb3RvdHlwZS5rZXlEb3duID0gZnVuY3Rpb24ga2V5RG93bihldnQpIHtcclxuICB0aGlzLmtleURhdGFba2V5Y29kZShldnQua2V5Q29kZSldID0gXCJkb3duXCI7XHJcbiAgcmV0dXJuIHRoaXMua2V5Q2hhbmdlKGV2dCk7XHJcbn07XHJcblxyXG5SZW5kZXJlci5wcm90b3R5cGUua2V5VXAgPSBmdW5jdGlvbiBrZXlVcChldnQpIHtcclxuICB0aGlzLmtleURhdGFba2V5Y29kZShldnQua2V5Q29kZSldID0gXCJ1cFwiO1xyXG4gIHJldHVybiB0aGlzLmtleUNoYW5nZShldnQpO1xyXG59O1xyXG5cclxuUmVuZGVyZXIucHJvdG90eXBlLmZpcmVGcmFtZSA9IGZ1bmN0aW9uKCkge1xyXG4gIHRoaXMubW91c2VSZWdpb25zLnNwbGljZSgwLCB0aGlzLm1vdXNlUmVnaW9ucy5sZW5ndGgpO1xyXG4gIHRoaXMudG91Y2hSZWdpb25zLnNwbGljZSgwLCB0aGlzLnRvdWNoUmVnaW9ucy5sZW5ndGgpO1xyXG5cclxuICB0aGlzLmVtaXQoJ2ZyYW1lJywge30pO1xyXG4gIHRoaXMuYWN0aXZlUmVnaW9ucy5zcGxpY2UoMCwgdGhpcy5hY3RpdmVSZWdpb25zLmxlbmd0aCk7XHJcbiAgdGhpcy5yYW5Nb3VzZUV2ZW50ID0gZmFsc2U7XHJcbiAgcmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG5SZW5kZXJlci5wcm90b3R5cGUuc3R5bGUgPSBmdW5jdGlvbiBzdHlsZSgpIHtcclxuICB2YXIgY2hpbGRyZW4gPSBbXSxcclxuICAgICAgc3R5bGVzID0gW10sXHJcbiAgICAgIGNvbmNhdCA9IGNoaWxkcmVuLmNvbmNhdCxcclxuICAgICAgbGVuLFxyXG4gICAgICBpLFxyXG4gICAgICBjaGlsZCxcclxuICAgICAgbmFtZTtcclxuICBmb3IoaSA9IDAsIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgY2hpbGRyZW4ucHVzaChhcmd1bWVudHNbaV0pO1xyXG4gIH1cclxuXHJcbiAgZm9yIChpID0gMCwgbGVuID0gY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgIGNoaWxkID0gY2hpbGRyZW5baV07XHJcbiAgICBpZiAoY2hpbGQgJiYgY2hpbGQuY29uc3RydWN0b3IgPT09IEFycmF5KSB7XHJcbiAgICAgIGNoaWxkcmVuID0gY29uY2F0LmFwcGx5KFtdLCBjaGlsZHJlbik7XHJcbiAgICAgIGNoaWxkID0gY2hpbGRyZW5baV07XHJcbiAgICAgIHdoaWxlKGNoaWxkICYmIGNoaWxkLmNvbnN0cnVjdG9yID09PSBBcnJheSkge1xyXG4gICAgICAgIGNoaWxkcmVuID0gY29uY2F0LmFwcGx5KFtdLCBjaGlsZHJlbik7XHJcbiAgICAgICAgY2hpbGQgPSBjaGlsZHJlbltpXTtcclxuICAgICAgfVxyXG4gICAgICBsZW4gPSBjaGlsZHJlbi5sZW5ndGg7XHJcbiAgICB9XHJcbiAgICBpZiAoY2hpbGQpIHtcclxuICAgICAgc3R5bGVzLnB1c2goY2hpbGQpO1xyXG4gICAgfVxyXG4gIH1cclxuICBmb3IgKGkgPSAwOyBpIDwgc3R5bGVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICB0aGlzLnN0eWxlUXVldWUucHVzaChzdHlsZXNbaV0pO1xyXG4gIH1cclxuICByZXR1cm4gdGhpcztcclxufTtcclxuXHJcblJlbmRlcmVyLnByb3RvdHlwZS5hcHBseVN0eWxlcyA9IGZ1bmN0aW9uIGFwcGx5U3R5bGVzKCkge1xyXG4gIHZhciBzdHlsZVZhbCwgdmFsdWU7XHJcbiAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMuc3R5bGVRdWV1ZS5sZW5ndGg7IGkrKykge1xyXG4gICAgc3R5bGVWYWwgPSB0aGlzLnN0eWxlUXVldWVbaV07XHJcbiAgICBmb3IodmFyIG5hbWUgaW4gc3R5bGVWYWwpIHtcclxuICAgICAgaWYgKHN0eWxlVmFsLmhhc093blByb3BlcnR5KG5hbWUpKSB7XHJcbiAgICAgICAgdGhpcy5jYW52YXMuc3R5bGVbbmFtZV0gPSBzdHlsZVZhbFtuYW1lXTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuICB0aGlzLnN0eWxlUXVldWUuc3BsaWNlKDAsIHRoaXMuc3R5bGVRdWV1ZS5sZW5ndGgpO1xyXG4gIHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuUmVuZGVyZXIucHJvdG90eXBlLnJlYWR5ID0gZnVuY3Rpb24gcmVhZHkoKSB7XHJcbiAgdGhpcy5pc1JlYWR5ID0gdHJ1ZTtcclxuICB0aGlzLmZpcmVGcmFtZSgpO1xyXG4gIHJldHVybiB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRoaXMuaG9va1JlbmRlci5iaW5kKHRoaXMpKTtcclxufTtcclxuXHJcblJlbmRlcmVyLnByb3RvdHlwZS5tZWFzdXJlVGV4dCA9IGZ1bmN0aW9uIG1lYXN1cmVUZXh0KGZvbnQsIHRleHQpIHtcclxuICB2YXIgb2xkRm9udCA9IHRoaXMuY3R4LmZvbnQsXHJcbiAgICAgIHJlc3VsdDtcclxuXHJcbiAgdGhpcy5jdHguZm9udCA9IGZvbnQ7XHJcbiAgcmVzdWx0ID0gdGhpcy5jdHgubWVhc3VyZVRleHQodGV4dCk7XHJcbiAgdGhpcy5jdHguZm9udCA9IG9sZEZvbnQ7XHJcbiAgcmV0dXJuIHJlc3VsdDtcclxufTtcclxuXHJcblJlbmRlcmVyLnByb3RvdHlwZS5pbmNyZWFzZVRyYW5zZm9ybVN0YWNrU2l6ZSA9IGZ1bmN0aW9uIGluY3JlYXNlVHJhbnNmb3JtU3RhY2tTaXplKCkge1xyXG4gIHZhciBjYWNoZSA9IHRoaXMudHJhbnNmb3JtU3RhY2s7XHJcbiAgdGhpcy50cmFuc2Zvcm1TdGFjayA9IG5ldyBGbG9hdDY0QXJyYXkodGhpcy50cmFuc2Zvcm1TdGFjay5sZW5ndGggKyA2MDApOyAvL2FkZCAxMDAgbW9yZVxyXG4gIHRoaXMudHJhbnNmb3JtU3RhY2suc2V0KGNhY2hlKTtcclxuICByZXR1cm4gdGhpcztcclxufTtcclxuXHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZW5kZXJlci5wcm90b3R5cGUsICdoZWlnaHQnLCB7XHJcbiAgZ2V0OiBmdW5jdGlvbigpIHtcclxuICAgIHJldHVybiB0aGlzLmNhbnZhcy53aWR0aDtcclxuICB9LFxyXG4gIGVudW1lcmFibGU6IHRydWUsXHJcbiAgY29uZmlndXJhYmxlOiBmYWxzZVxyXG59KTtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlbmRlcmVyLnByb3RvdHlwZSwgJ3dpZHRoJywge1xyXG4gIGdldDogZnVuY3Rpb24oKSB7XHJcbiAgICByZXR1cm4gdGhpcy5jYW52YXMud2lkdGg7XHJcbiAgfSxcclxuICBlbnVtZXJhYmxlOiB0cnVlLFxyXG4gIGNvbmZpZ3VyYWJsZTogZmFsc2VcclxufSk7XHJcbk9iamVjdC5zZWFsKFJlbmRlcmVyKTtcclxuT2JqZWN0LnNlYWwoUmVuZGVyZXIucHJvdG90eXBlKTtcclxubW9kdWxlLmV4cG9ydHMgPSBSZW5kZXJlcjtcclxuIiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG5cclxuJ3VzZSBzdHJpY3QnO1xyXG52YXIgSW5zdHJ1Y3Rpb24gPSByZXF1aXJlKCcuL0luc3RydWN0aW9uJyk7XHJcblxyXG5mdW5jdGlvbiBhZGRDb2xvclN0b3Aob2Zmc2V0LCBjb2xvcikge1xyXG4gIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ2FkZENvbG9yU3RvcCcsIHsgb2Zmc2V0OiBvZmZzZXQsIGNvbG9yOiBjb2xvciB9KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBhZGRDb2xvclN0b3A7IiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuXHJcbmZ1bmN0aW9uIGFyYyh4LCB5LCByLCBzdGFydEFuZ2xlLCBlbmRBbmdsZSwgYW50aWNsb2Nrd2lzZSkge1xyXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID4gNSkge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbihhbnRpY2xvY2t3aXNlID8gJ2FudGljbG9ja3dpc2UtYXJjJyA6ICdhcmMnLCB7IHg6IHgsIHk6IHksIHI6IHIsIHN0YXJ0QW5nbGU6IHN0YXJ0QW5nbGUsIGVuZEFuZ2xlOiBlbmRBbmdsZSB9KTtcclxuICB9XHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDUpIHtcclxuICAgIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ2FyYycsIHsgeDogeCwgeTogeSwgcjogciwgc3RhcnRBbmdsZTogc3RhcnRBbmdsZSwgZW5kQW5nbGU6IGVuZEFuZ2xlIH0pO1xyXG4gIH1cclxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSAzKSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdmdWxsLWFyYycsIHsgeDogeCwgeTogeSwgcjogcn0pO1xyXG4gIH1cclxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSAxKSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdxdWljay1hcmMnLCB7IHI6IHggfSk7XHJcbiAgfVxyXG4gIFxyXG4gIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ3F1aWNrLWFyYycsIHsgcjogMSB9KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBhcmM7IiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuXHJcbmZ1bmN0aW9uIGFyY1RvKHgxLCB5MSwgeDIsIHkyLCByKSB7XHJcbiAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignYXJjVG8nLCB7IHgxOiB4MSwgeTE6IHkxLCB4MjogeDIsIHkyOiB5MiwgcjogciB9KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBhcmNUbztcclxuIiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuXHJcbmZ1bmN0aW9uIGJlZ2luUGF0aCgpIHtcclxuICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdiZWdpblBhdGgnKTtcclxufVxyXG5tb2R1bGUuZXhwb3J0cyA9IGJlZ2luUGF0aDsiLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxudmFyIEluc3RydWN0aW9uID0gcmVxdWlyZSgnLi9JbnN0cnVjdGlvbicpO1xyXG5cclxuZnVuY3Rpb24gYmV6aWVyQ3VydmVUbyhjcDF4LCBjcDF5LCBjcDJ4LCBjcDJ5LCB4LCB5KSB7XHJcbiAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignYmV6aWVyQ3VydmVUbycsIHtcclxuICAgIGNwMXg6IGNwMXgsIFxyXG4gICAgY3AxeTogY3AxeSwgXHJcbiAgICBjcDJ4OiBjcDJ4LCBcclxuICAgIGNwMnk6IGNwMnksIFxyXG4gICAgeDogeCwgXHJcbiAgICB5OiB5XHJcbiAgfSk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gYmV6aWVyQ3VydmVUbzsiLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxudmFyIEluc3RydWN0aW9uID0gcmVxdWlyZSgnLi9JbnN0cnVjdGlvbicpO1xyXG5cclxuZnVuY3Rpb24gZmlsbFJlY3QoeCwgeSwgd2lkdGgsIGhlaWdodCkge1xyXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMikge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbihcImNsZWFyUmVjdFwiLCB7IHg6IHgsIHk6IHksIHdpZHRoOiB3aWR0aCwgaGVpZ2h0OiBoZWlnaHQgfSk7XHJcbiAgfSBlbHNlIHtcclxuICAgIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oXCJjbGVhclJlY3RcIiwgeyB4OiAwLCB5OiAwLCB3aWR0aDogeCwgaGVpZ2h0OiB5IH0pO1xyXG4gIH1cclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmaWxsUmVjdDsiLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuXHJcbmZ1bmN0aW9uIGNsaXAocGF0aCwgY2hpbGRyZW4pIHtcclxuICB2YXIgcmVzdWx0ID0gW25ldyBJbnN0cnVjdGlvbignYmVnaW5DbGlwJyksIHBhdGgsIG5ldyBJbnN0cnVjdGlvbignY2xpcCcpXTtcclxuXHJcbiAgZm9yKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xyXG4gICAgcmVzdWx0LnB1c2goYXJndW1lbnRzW2ldKTtcclxuICB9XHJcblxyXG4gIHJlc3VsdC5wdXNoKG5ldyBJbnN0cnVjdGlvbignZW5kQ2xpcCcpKTtcclxuICByZXR1cm4gcmVzdWx0O1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGNsaXA7XHJcbiIsIi8vanNoaW50IG5vZGU6IHRydWVcclxuJ3VzZSBzdHJpY3QnO1xyXG52YXIgSW5zdHJ1Y3Rpb24gPSByZXF1aXJlKCcuL0luc3RydWN0aW9uJyk7XHJcblxyXG5mdW5jdGlvbiBjbGlwUGF0aCgpIHtcclxuICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdjbGlwUGF0aCcpO1xyXG59XHJcbm1vZHVsZS5leHBvcnRzID0gY2xpcFBhdGg7IiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuXHJcbmZ1bmN0aW9uIGNsb3NlUGF0aCgpIHtcclxuICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdjbG9zZVBhdGgnKTtcclxufVxyXG5tb2R1bGUuZXhwb3J0cyA9IGNsb3NlUGF0aDsiLCIndXNlIHN0cmljdCc7XHJcbnZhciBjb25jYXQgPSBbXS5jb25jYXQ7XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVDbGFzcygpIHtcclxuICB2YXIgYXJncyA9IFtdLCBpO1xyXG4gIGZvcihpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xyXG4gICAgYXJncy5wdXNoKGFyZ3VtZW50c1tpXSk7XHJcbiAgfVxyXG5cclxuICBmb3IoaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICB3aGlsZSAoYXJnc1tpXSAmJiBhcmdzW2ldLmNvbnN0cnVjdG9yID09PSBBcnJheSkge1xyXG4gICAgICBhcmdzID0gY29uY2F0LmFwcGx5KFtdLCBhcmdzKTtcclxuICAgIH1cclxuICAgIGlmIChhcmdzW2ldICYmIGFyZ3NbaV0udHlwZSA9PT0gJ3BsYWNlaG9sZGVyJykge1xyXG4gICAgICAgLy8gcmVtb3ZlIHRoZSBwbGFjZWhvbGRlclxyXG4gICAgICBicmVhaztcclxuICAgIH1cclxuICB9XHJcbiAgcmV0dXJuIChmdW5jdGlvbigpIHtcclxuICAgIHZhciBzdGFydCA9IGFyZ3MsIGVuZCA9IHN0YXJ0LnNwbGljZShpICsgMSwgYXJncy5sZW5ndGgpO1xyXG4gICAgc3RhcnQucG9wKCk7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gY3JlYXRlZENsYXNzKCkge1xyXG4gICAgICB2YXIgY2hpbGRyZW4gPSBbXSwgaTtcclxuICAgICAgZm9yKGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgY2hpbGRyZW4ucHVzaChhcmd1bWVudHNbaV0pO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiBbXHJcbiAgICAgICAgc3RhcnQsIGNoaWxkcmVuLCBlbmRcclxuICAgICAgXTtcclxuICAgIH07XHJcbiAgfSgpKTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVDbGFzcztcclxuIiwiLy9qc2hpbnQgbm9kZTogdHJ1ZSwgYnJvd3NlcjogdHJ1ZSwgd29ya2VyOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZUxpbmVhckdyYWRpZW50KHgwLCB5MCwgeDEsIHkxLCBjaGlsZHJlbikge1xyXG4gIHZhciBjdHggPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJykuZ2V0Q29udGV4dCgnMmQnKSxcclxuICAgIGdyZCA9IGN0eC5jcmVhdGVMaW5lYXJHcmFkaWVudCh4MCwgeTAsIHgxLCB5MSk7XHJcbiAgZm9yKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XHJcbiAgICB2YXIgY29sb3JTdG9wID0gY2hpbGRyZW5baV07XHJcbiAgICBncmQuYWRkQ29sb3JTdG9wKGNvbG9yU3RvcC5wcm9wcy5vZmZzZXQsIGNvbG9yU3RvcC5wcm9wcy5jb2xvcik7XHJcbiAgfVxyXG4gIHJldHVybiBncmQ7XHJcbn1cclxuXHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUxpbmVhckdyYWRpZW50O1xyXG4iLCIvL2pzaGludCBub2RlOiB0cnVlLCBicm93c2VyOiB0cnVlLCB3b3JrZXI6IHRydWVcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxuZnVuY3Rpb24gY3JlYXRlUmFkaWFsR3JhZGllbnQoeDAsIHkwLCByMCwgeDEsIHkxLCByMSwgY2hpbGRyZW4pIHtcclxuICB2YXIgY3R4ID0gd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpLmdldENvbnRleHQoJzJkJyksXHJcbiAgICBncmQgPSBjdHguY3JlYXRlUmFkaWFsR3JhZGllbnQoeDAsIHkwLCByMCwgeDEsIHkxLCByMSk7XHJcbiAgZm9yKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XHJcbiAgICB2YXIgY29sb3JTdG9wID0gY2hpbGRyZW5baV07XHJcbiAgICBncmQuYWRkQ29sb3JTdG9wKGNvbG9yU3RvcC5wcm9wcy5vZmZzZXQsIGNvbG9yU3RvcC5wcm9wcy5jb2xvcik7XHJcbiAgfVxyXG4gIHJldHVybiBncmQ7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlUmFkaWFsR3JhZGllbnQ7XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZVJlZ3VsYXJQb2x5Z29uKHJhZGl1cywgcG9zaXRpb24sIHNpZGVzKSB7XHJcbiAgcmFkaXVzID0gK3JhZGl1cyB8fCAxO1xyXG4gIHBvc2l0aW9uWzBdID0gK3Bvc2l0aW9uWzBdIHx8IDA7XHJcbiAgcG9zaXRpb25bMV0gPSArcG9zaXRpb25bMV0gfHwgMDtcclxuICBzaWRlcyA9ICtzaWRlcyB8fCAzO1xyXG4gIHZhciBwb2x5Z29uID0gW107XHJcbiAgZm9yKHZhciBpID0gMDsgaSA8IHNpZGVzOyBpKyspIHtcclxuICAgIHBvbHlnb24ucHVzaChbXHJcbiAgICAgIHBvc2l0aW9uWzBdICsgcmFkaXVzICogTWF0aC5jb3MoTWF0aC5QSSAqIDIgKiBpIC8gc2lkZXMpLFxyXG4gICAgICBwb3NpdGlvblsxXSArIHJhZGl1cyAqIE1hdGguc2luKE1hdGguUEkgKiAyICogaSAvIHNpZGVzKVxyXG4gICAgXSk7XHJcbiAgfVxyXG4gIHJldHVybiBwb2x5Z29uO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZVJlZ3VsYXJQb2x5Z29uO1xyXG4iLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxudmFyIEluc3RydWN0aW9uID0gcmVxdWlyZSgnLi9JbnN0cnVjdGlvbicpO1xyXG5cclxuZnVuY3Rpb24gZHJhd0NhbnZhcyhjYW52YXMsIHN4LCBzeSwgc1dpZHRoLCBzSGVpZ2h0LCBkeCwgZHksIGRXaWR0aCwgZEhlaWdodCkge1xyXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSA5KSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdkcmF3Q2FudmFzU291cmNlJywge1xyXG4gICAgICBpbWc6IGNhbnZhcyxcclxuICAgICAgc3g6IHN4LFxyXG4gICAgICBzeTogc3ksXHJcbiAgICAgIHNXaWR0aDogc1dpZHRoLFxyXG4gICAgICBzSGVpZ2h0OiBzSGVpZ2h0LFxyXG4gICAgICBkeDogZHgsXHJcbiAgICAgIGR5OiBkeSxcclxuICAgICAgZFdpZHRoOiBkV2lkdGgsXHJcbiAgICAgIGRIZWlnaHQ6IGRIZWlnaHRcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gNSkge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignZHJhd0NhbnZhc1NpemUnLCB7XHJcbiAgICAgIGltZzogY2FudmFzLFxyXG4gICAgICBkeDogc3gsXHJcbiAgICAgIGR5OiBzeSxcclxuICAgICAgZFdpZHRoOiBzV2lkdGgsXHJcbiAgICAgIGRIZWlnaHQ6IHNIZWlnaHRcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gMykge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignZHJhd0NhbnZhcycsIHtcclxuICAgICAgaW1nOiBjYW52YXMsXHJcbiAgICAgIGR4OiBzeCxcclxuICAgICAgZHk6IHN5XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ2RyYXdDYW52YXMnLCB7XHJcbiAgICBpbWc6IGNhbnZhcyxcclxuICAgIGR4OiAwLFxyXG4gICAgZHk6IDBcclxuICB9KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBkcmF3Q2FudmFzO1xyXG4iLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxudmFyIEluc3RydWN0aW9uID0gcmVxdWlyZSgnLi9JbnN0cnVjdGlvbicpO1xyXG5cclxuZnVuY3Rpb24gZHJhd0ltYWdlKGltZywgc3gsIHN5LCBzV2lkdGgsIHNIZWlnaHQsIGR4LCBkeSwgZFdpZHRoLCBkSGVpZ2h0KSB7XHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDkpIHtcclxuICAgIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ2RyYXdJbWFnZVNvdXJjZScsIHtcclxuICAgICAgaW1nOiBpbWcsXHJcbiAgICAgIHN4OiBzeCxcclxuICAgICAgc3k6IHN5LFxyXG4gICAgICBzV2lkdGg6IHNXaWR0aCxcclxuICAgICAgc0hlaWdodDogc0hlaWdodCxcclxuICAgICAgZHg6IGR4LFxyXG4gICAgICBkeTogZHksXHJcbiAgICAgIGRXaWR0aDogZFdpZHRoLFxyXG4gICAgICBkSGVpZ2h0OiBkSGVpZ2h0XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDUpIHtcclxuICAgIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ2RyYXdJbWFnZVNpemUnLCB7XHJcbiAgICAgIGltZzogaW1nLFxyXG4gICAgICBkeDogc3gsXHJcbiAgICAgIGR5OiBzeSxcclxuICAgICAgZFdpZHRoOiBzV2lkdGgsXHJcbiAgICAgIGRIZWlnaHQ6IHNIZWlnaHRcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gMykge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignZHJhd0ltYWdlJywge1xyXG4gICAgICBpbWc6IGltZyxcclxuICAgICAgZHg6IHN4LFxyXG4gICAgICBkeTogc3lcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignZHJhd0ltYWdlJywge1xyXG4gICAgaW1nOiBpbWcsXHJcbiAgICBkeDogMCxcclxuICAgIGR5OiAwXHJcbiAgfSk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZHJhd0ltYWdlO1xyXG4iLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxudmFyIEluc3RydWN0aW9uID0gcmVxdWlyZSgnLi9JbnN0cnVjdGlvbicpO1xyXG5cclxuZnVuY3Rpb24gZWxsaXBzZSh4LCB5LCByYWRpdXNYLCByYWRpdXNZLCByb3RhdGlvbiwgc3RhcnRBbmdsZSwgZW5kQW5nbGUsIGFudGljbG9ja3dpc2UpIHtcclxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDcpIHtcclxuICAgIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oYW50aWNsb2Nrd2lzZSA/ICdhbnRpY2xvY2t3aXNlLWVsbGlwc2UnIDogJ2VsbGlwc2UnLCB7IHg6IHgsIHk6IHksIHJhZGl1c1g6IHJhZGl1c1gsIHJhZGl1c1k6IHJhZGl1c1ksIHN0YXJ0QW5nbGU6IHN0YXJ0QW5nbGUsIGVuZEFuZ2xlOiBlbmRBbmdsZSB9KTtcclxuICB9XHJcbiAgXHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDcpIHtcclxuICAgIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ2VsbGlwc2UnLCB7IHg6IHgsIHk6IHksIHJhZGl1c1g6IHJhZGl1c1gsIHJhZGl1c1k6IHJhZGl1c1ksIHJvdGF0aW9uOiByb3RhdGlvbiwgc3RhcnRBbmdsZTogc3RhcnRBbmdsZSwgZW5kQW5nbGU6IGVuZEFuZ2xlIH0pO1xyXG4gIH1cclxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSA1KSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdmdWxsLWVsbGlwc2UnLCB7IHg6IHgsIHk6IHksIHJhZGl1c1g6IHJhZGl1c1gsIHJhZGl1c1k6IHJhZGl1c1ksIHJvdGF0aW9uOiByb3RhdGlvbiB9KTtcclxuICB9XHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDQpIHtcclxuICAgIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ3F1aWNrLWVsbGlwc2UnLCB7IHg6IHgsIHk6IHksIHJhZGl1c1g6IHJhZGl1c1gsIHJhZGl1c1k6IHJhZGl1c1kgfSk7XHJcbiAgfVxyXG4gIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ3F1aWNrLWVsbGlwc2UnLCB7IHg6IDAsIHk6IDAsIHJhZGl1c1g6IHgsIHJhZGl1c1k6IHkgfSk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZWxsaXBzZTsiLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxudmFyIEluc3RydWN0aW9uID0gcmVxdWlyZSgnLi9JbnN0cnVjdGlvbicpO1xyXG5cclxuZnVuY3Rpb24gZmlsbCgpIHtcclxuICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdmaWxsJyk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZmlsbDsiLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxudmFyIEluc3RydWN0aW9uID0gcmVxdWlyZSgnLi9JbnN0cnVjdGlvbicpLFxyXG4gICAgcGkyID0gTWF0aC5QSSAqIDI7XHJcblxyXG5mdW5jdGlvbiBmaWxsQXJjKHgsIHksIHIsIHN0YXJ0QW5nbGUsIGVuZEFuZ2xlLCBjb3VudGVyY2xvY2t3aXNlKSB7XHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gNiAmJiBjb3VudGVyY2xvY2t3aXNlKSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKFwiZmlsbEFyYy1jb3VudGVyY2xvY2t3aXNlXCIsIHsgeDogeCwgeTogeSwgcjogciwgc3RhcnRBbmdsZTogc3RhcnRBbmdsZSwgZW5kQW5nbGU6IGVuZEFuZ2xlIH0pO1xyXG4gICAgXHJcbiAgfVxyXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMykge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbihcImZpbGxBcmNcIiwgeyB4OiB4LCB5OiB5LCByOiByLCBzdGFydEFuZ2xlOiBzdGFydEFuZ2xlLCBlbmRBbmdsZTogZW5kQW5nbGUgfSk7XHJcbiAgfSBcclxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpe1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbihcImZpbGxBcmNcIiwgeyB4OiB4LCB5OiB5LCByOiByLCBzdGFydEFuZ2xlOiAwLCBlbmRBbmdsZTogcGkyIH0pO1xyXG4gIH1cclxuICByZXR1cm4gbmV3IEluc3RydWN0aW9uKFwiZmlsbEFyY1wiLCAgeyB4OiAwLCB5OiAwLCByOiB4LCBzdGFydEFuZ2xlOiAwLCBlbmRBbmdsZTogcGkyIH0pO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZpbGxBcmM7IiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuXHJcbmZ1bmN0aW9uIGZpbGxJbWFnZShpbWcsIHN4LCBzeSwgc1dpZHRoLCBzSGVpZ2h0LCBkeCwgZHksIGRXaWR0aCwgZEhlaWdodCkge1xyXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSA5KSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdmaWxsQ2FudmFzU291cmNlJywge1xyXG4gICAgICBpbWc6IGltZyxcclxuICAgICAgc3g6IHN4LFxyXG4gICAgICBzeTogc3ksXHJcbiAgICAgIHNXaWR0aDogc1dpZHRoLFxyXG4gICAgICBzSGVpZ2h0OiBzSGVpZ2h0LFxyXG4gICAgICBkeDogZHgsXHJcbiAgICAgIGR5OiBkeSxcclxuICAgICAgZFdpZHRoOiBkV2lkdGgsXHJcbiAgICAgIGRIZWlnaHQ6IGRIZWlnaHRcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gNSkge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignZmlsbENhbnZhc1NpemUnLCB7XHJcbiAgICAgIGltZzogaW1nLFxyXG4gICAgICBkeDogc3gsXHJcbiAgICAgIGR5OiBzeSxcclxuICAgICAgZFdpZHRoOiBzV2lkdGgsXHJcbiAgICAgIGRIZWlnaHQ6IHNIZWlnaHRcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gMykge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignZmlsbENhbnZhcycsIHtcclxuICAgICAgaW1nOiBpbWcsXHJcbiAgICAgIGR4OiBzeCxcclxuICAgICAgZHk6IHN5XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ2ZpbGxDYW52YXMnLCB7XHJcbiAgICBpbWc6IGltZyxcclxuICAgIGR4OiAwLFxyXG4gICAgZHk6IDBcclxuICB9KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmaWxsSW1hZ2U7XHJcbiIsIi8vanNoaW50IG5vZGU6IHRydWVcclxuJ3VzZSBzdHJpY3QnO1xyXG52YXIgSW5zdHJ1Y3Rpb24gPSByZXF1aXJlKCcuL0luc3RydWN0aW9uJyk7XHJcblxyXG5mdW5jdGlvbiBmaWxsSW1hZ2UoaW1nLCBzeCwgc3ksIHNXaWR0aCwgc0hlaWdodCwgZHgsIGR5LCBkV2lkdGgsIGRIZWlnaHQpIHtcclxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gOSkge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignZmlsbEltYWdlU291cmNlJywge1xyXG4gICAgICBpbWc6IGltZyxcclxuICAgICAgc3g6IHN4LFxyXG4gICAgICBzeTogc3ksXHJcbiAgICAgIHNXaWR0aDogc1dpZHRoLFxyXG4gICAgICBzSGVpZ2h0OiBzSGVpZ2h0LFxyXG4gICAgICBkeDogZHgsXHJcbiAgICAgIGR5OiBkeSxcclxuICAgICAgZFdpZHRoOiBkV2lkdGgsXHJcbiAgICAgIGRIZWlnaHQ6IGRIZWlnaHRcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gNSkge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignZmlsbEltYWdlU2l6ZScsIHtcclxuICAgICAgaW1nOiBpbWcsXHJcbiAgICAgIGR4OiBzeCxcclxuICAgICAgZHk6IHN5LFxyXG4gICAgICBkV2lkdGg6IHNXaWR0aCxcclxuICAgICAgZEhlaWdodDogc0hlaWdodFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSAzKSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdmaWxsSW1hZ2UnLCB7XHJcbiAgICAgIGltZzogaW1nLFxyXG4gICAgICBkeDogc3gsXHJcbiAgICAgIGR5OiBzeVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdmaWxsSW1hZ2UnLCB7XHJcbiAgICBpbWc6IGltZyxcclxuICAgIGR4OiAwLFxyXG4gICAgZHk6IDBcclxuICB9KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmaWxsSW1hZ2U7XHJcbiIsIi8vanNoaW50IG5vZGU6IHRydWVcclxuJ3VzZSBzdHJpY3QnO1xyXG52YXIgSW5zdHJ1Y3Rpb24gPSByZXF1aXJlKCcuL0luc3RydWN0aW9uJyk7XHJcblxyXG5mdW5jdGlvbiBmaWxsSW1hZ2VQYXR0ZXJuKGltZywgZHgsIGR5LCBkV2lkdGgsIGRIZWlnaHQpIHtcclxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSA1KSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdmaWxsSW1hZ2VQYXR0ZXJuJywge1xyXG4gICAgICBpbWc6IGltZyxcclxuICAgICAgZHg6IGR4LFxyXG4gICAgICBkeTogZHksXHJcbiAgICAgIGRXaWR0aDogZFdpZHRoLFxyXG4gICAgICBkSGVpZ2h0OiBkSGVpZ2h0XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDMpIHtcclxuICAgIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ2ZpbGxJbWFnZVBhdHRlcm4nLCB7XHJcbiAgICAgIGltZzogaW1nLFxyXG4gICAgICBkeDogMCxcclxuICAgICAgZHk6IDAsXHJcbiAgICAgIGRXaWR0aDogZHgsXHJcbiAgICAgIGRIZWlnaHQ6IGR5XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ2ZpbGxJbWFnZVBhdHRlcm4nLCB7XHJcbiAgICBpbWc6IGltZyxcclxuICAgIGR4OiAwLFxyXG4gICAgZHk6IDAsXHJcbiAgICBkV2lkdGg6IDAsXHJcbiAgICBkSGVpZ2h0OiAwXHJcbiAgfSk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZmlsbEltYWdlUGF0dGVybjtcclxuIiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuXHJcbmZ1bmN0aW9uIGZpbGxSZWN0KHgsIHksIHdpZHRoLCBoZWlnaHQpIHtcclxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSA0KSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKFwiZmlsbFJlY3RcIiwgeyB4OiB4LCB5OiB5LCB3aWR0aDogd2lkdGgsIGhlaWdodDogaGVpZ2h0IH0pO1xyXG4gIH0gZWxzZSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKFwiZmlsbFJlY3RcIiwgeyB4OiAwLCB5OiAwLCB3aWR0aDogeCwgaGVpZ2h0OiB5IH0pO1xyXG4gIH1cclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmaWxsUmVjdDsiLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxudmFyIEluc3RydWN0aW9uID0gcmVxdWlyZSgnLi9JbnN0cnVjdGlvbicpO1xyXG5cclxuZnVuY3Rpb24gZmlsbFN0eWxlKHZhbHVlLCBjaGlsZHJlbikge1xyXG4gIHZhciByZXN1bHQgPSBbbmV3IEluc3RydWN0aW9uKCdmaWxsU3R5bGUnLCB7IHZhbHVlOiB2YWx1ZSB9KV07XHJcblxyXG4gIGZvcih2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcclxuICAgIHJlc3VsdC5wdXNoKGFyZ3VtZW50c1tpXSk7XHJcbiAgfVxyXG4gIHJlc3VsdC5wdXNoKG5ldyBJbnN0cnVjdGlvbignZW5kRmlsbFN0eWxlJykpO1xyXG4gIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZmlsbFN0eWxlO1xyXG4iLCJ2YXIgSW5zdHJ1Y3Rpb24gPSByZXF1aXJlKCcuL0luc3RydWN0aW9uJyk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGZpbGxUZXh0KHRleHQsIHgsIHksIG1heFdpZHRoKSB7XHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCA0KSB7XHJcbiAgICBtYXhXaWR0aCA9IG51bGw7XHJcbiAgfVxyXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMykge1xyXG4gICAgeCA9IDA7XHJcbiAgICB5ID0gMDtcclxuICB9XHJcbiAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignZmlsbFRleHQnLCB7XHJcbiAgICB0ZXh0OiB0ZXh0LFxyXG4gICAgeDogeCxcclxuICAgIHk6IHksXHJcbiAgICBtYXhXaWR0aDogbWF4V2lkdGhcclxuICB9KTtcclxufTtcclxuIiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuXHJcbmZ1bmN0aW9uIGdsb2JhbEFscGhhKGFscGhhLCBjaGlsZHJlbikge1xyXG4gIHZhciByZXN1bHQgPSBbbmV3IEluc3RydWN0aW9uKCdnbG9iYWxBbHBoYScsIHsgdmFsdWU6IGFscGhhIH0pXTtcclxuICBmb3IodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICByZXN1bHQucHVzaChhcmd1bWVudHNbaV0pO1xyXG4gIH1cclxuICByZXN1bHQucHVzaChuZXcgSW5zdHJ1Y3Rpb24oJ2VuZEdsb2JhbEFscGhhJykpO1xyXG4gIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZ2xvYmFsQWxwaGE7IiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuXHJcbmZ1bmN0aW9uIGdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbihvcGVyYXRpb25UeXBlLCBjaGlsZHJlbikge1xyXG4gIHZhciByZXN1bHQgPSBbbmV3IEluc3RydWN0aW9uKCdnbG9iYWxDb21wb3NpdGVPcGVyYXRpb24nLCB7IHZhbHVlOiBvcGVyYXRpb25UeXBlIH0pXTtcclxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgcmV0dXJuIFtdO1xyXG4gIH1cclxuICBcclxuICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xyXG4gICAgcmVzdWx0LnB1c2goYXJndW1lbnRzW2ldKTtcclxuICB9XHJcbiAgcmVzdWx0LnB1c2gobmV3IEluc3RydWN0aW9uKCdlbmRHbG9iYWxDb21wb3NpdGVPcGVyYXRpb24nKSk7XHJcbiAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBnbG9iYWxDb21wb3NpdGVPcGVyYXRpb247IiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKSxcclxuICAgIGhpdFJlZ2lvbiA9IHJlcXVpcmUoJy4vaGl0UmVnaW9uJyk7XHJcblxyXG5cclxuZnVuY3Rpb24gaGl0UmVjdChpZCwgeCwgeSwgd2lkdGgsIGhlaWdodCkge1xyXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoIDw9IDMpIHtcclxuICAgIHdpZHRoID0geDtcclxuICAgIGhlaWdodCA9IHk7XHJcbiAgICB4ID0gMDtcclxuICAgIHkgPSAwO1xyXG4gIH1cclxuICBcclxuICB2YXIgcG9pbnRzID0gW1xyXG4gICAgW3gsIHldLFxyXG4gICAgW3gsIHkgKyBoZWlnaHRdLFxyXG4gICAgW3ggKyB3aWR0aCwgeSArIGhlaWdodF0sXHJcbiAgICBbeCArIHdpZHRoLCB5XVxyXG4gIF07XHJcbiAgXHJcbiAgcmV0dXJuIGhpdFJlZ2lvbihpZCwgcG9pbnRzKTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBoaXRSZWN0OyIsIi8vanNoaW50IG5vZGU6IHRydWVcclxuJ3VzZSBzdHJpY3QnO1xyXG52YXIgSW5zdHJ1Y3Rpb24gPSByZXF1aXJlKCcuL0luc3RydWN0aW9uJyk7XHJcblxyXG5cclxuZnVuY3Rpb24gaGl0UmVnaW9uKGlkLCBwb2ludHMpIHtcclxuICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdoaXRSZWdpb24nLCB7XHJcbiAgICBpZDogaWQsXHJcbiAgICBwb2ludHM6IHBvaW50c1xyXG4gIH0pO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGhpdFJlZ2lvbjsiLCIndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW1hZ2VTbW9vdGhpbmdFbmFibGVkKHZhbCwgY2hpbGRyZW4pIHtcclxuICBjaGlsZHJlbiA9IFtdO1xyXG4gIGZvcih2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcclxuICAgIGNoaWxkcmVuLnB1c2goYXJndW1lbnRzW2ldKTtcclxuICB9XHJcbiAgcmV0dXJuIFtuZXcgSW5zdHJ1Y3Rpb24oJ2ltYWdlU21vb3RoaW5nRW5hYmxlZCcsIHsgdmFsdWU6IEJvb2xlYW4odmFsKSB9KV0uY29uY2F0KGNoaWxkcmVuKS5jb25jYXQobmV3IEluc3RydWN0aW9uKCdlbmRJbWFnZVNtb290aGluZ0VuYWJsZWQnKSk7XHJcbn07XHJcbiIsIi8vanNoaW50IG5vZGU6IHRydWVcclxuJ3VzZSBzdHJpY3QnO1xyXG52YXIgSW5zdHJ1Y3Rpb24gPSByZXF1aXJlKCcuL0luc3RydWN0aW9uJyk7XHJcblxyXG5mdW5jdGlvbiBsaW5lU3R5bGUodmFsdWUsIGNoaWxkcmVuKSB7XHJcbiAgXHJcbiAgdmFsdWUgPSB2YWx1ZSB8fCB7fTtcclxuICB2YXIgcmVzdWx0ID0ge1xyXG4gICAgbGluZVdpZHRoOiBudWxsLFxyXG4gICAgbGluZUNhcDogbnVsbCxcclxuICAgIGxpbmVKb2luOiBudWxsLFxyXG4gICAgbWl0ZXJMaW1pdDogbnVsbCxcclxuICAgIGxpbmVEYXNoOiBbXSxcclxuICAgIGxpbmVEYXNoT2Zmc2V0OiBudWxsXHJcbiAgfTtcclxuICBcclxuICBpZiAodHlwZW9mIHZhbHVlLmxpbmVXaWR0aCAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHJlc3VsdC5saW5lV2lkdGggPSB2YWx1ZS5saW5lV2lkdGg7XHJcbiAgfVxyXG4gIGlmICh0eXBlb2YgdmFsdWUubGluZUNhcCAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHJlc3VsdC5saW5lQ2FwID0gdmFsdWUubGluZUNhcDtcclxuICB9XHJcbiAgaWYgKHR5cGVvZiB2YWx1ZS5saW5lSm9pbiAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHJlc3VsdC5saW5lSm9pbiA9IHZhbHVlLmxpbmVKb2luO1xyXG4gIH1cclxuICBpZiAodHlwZW9mIHZhbHVlLm1pdGVyTGltaXQgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQubWl0ZXJMaW1pdCA9IHZhbHVlLm1pdGVyTGltaXQ7XHJcbiAgfVxyXG4gIGlmICh0eXBlb2YgdmFsdWUubGluZURhc2ggIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQubGluZURhc2ggPSB2YWx1ZS5saW5lRGFzaDtcclxuICB9XHJcbiAgaWYgKHR5cGVvZiB2YWx1ZS5saW5lRGFzaE9mZnNldCAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHJlc3VsdC5saW5lRGFzaE9mZnNldCA9IHZhbHVlLmxpbmVEYXNoT2Zmc2V0O1xyXG4gIH1cclxuICB2YXIgdHJlZSA9IFtuZXcgSW5zdHJ1Y3Rpb24oJ2xpbmVTdHlsZScsIHJlc3VsdCldO1xyXG4gIGZvcih2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcclxuICAgIHRyZWUucHVzaChhcmd1bWVudHNbaV0pO1xyXG4gIH1cclxuICB0cmVlLnB1c2gobmV3IEluc3RydWN0aW9uKCdlbmRMaW5lU3R5bGUnKSk7XHJcbiAgcmV0dXJuIHRyZWU7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gbGluZVN0eWxlOyIsIi8vanNoaW50IG5vZGU6IHRydWVcclxuJ3VzZSBzdHJpY3QnO1xyXG52YXIgSW5zdHJ1Y3Rpb24gPSByZXF1aXJlKCcuL0luc3RydWN0aW9uJyk7XHJcblxyXG5mdW5jdGlvbiBsaW5lVG8oeCwgeSkge1xyXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdsaW5lVG8nLCB7IHg6IDAsIHk6IDB9KTtcclxuICB9XHJcbiAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignbGluZVRvJywgeyB4OiB4LCB5OiB5IH0pO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGxpbmVUbzsiLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxudmFyIEluc3RydWN0aW9uID0gcmVxdWlyZSgnLi9JbnN0cnVjdGlvbicpO1xyXG5cclxuZnVuY3Rpb24gbW92ZVRvKHgsIHkpIHtcclxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignbW92ZVRvJywgeyB4OiAwLCB5OiAwfSk7XHJcbiAgfVxyXG4gIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ21vdmVUbycsIHsgeDogeCwgeTogeSB9KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBtb3ZlVG87IiwiJ3VzZSBzdHJpY3QnO1xyXG52YXIgbW92ZVRvID0gcmVxdWlyZSgnLi9tb3ZlVG8nKSwgbGluZVRvID0gcmVxdWlyZSgnLi9saW5lVG8nKTtcclxuZnVuY3Rpb24gbW92ZVRvTGluZVRvKHBvaW50LCBpbmRleCkge1xyXG4gIHJldHVybiBpbmRleCA9PT0gMCA/IG1vdmVUbyhwb2ludFswXSwgcG9pbnRbMV0pIDogbGluZVRvKHBvaW50WzBdLCBwb2ludFsxXSk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gbW92ZVRvTGluZVRvO1xyXG4iLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBiZWdpblBhdGggPSByZXF1aXJlKCcuL2JlZ2luUGF0aCcpLFxyXG4gICAgY2xvc2VQYXRoID0gcmVxdWlyZSgnLi9jbG9zZVBhdGgnKTtcclxuXHJcbmZ1bmN0aW9uIHBhdGgoY2hpbGRyZW4pIHtcclxuICB2YXIgcmVzdWx0ID0gW2JlZ2luUGF0aCgpXTtcclxuICBmb3IodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICByZXN1bHQucHVzaChhcmd1bWVudHNbaV0pO1xyXG4gIH1cclxuICByZXN1bHQucHVzaChjbG9zZVBhdGgoKSk7XHJcbiAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBwYXRoOyIsIid1c2Ugc3RyaWN0JztcclxudmFyIEluc3RydWN0aW9uID0gcmVxdWlyZSgnLi9JbnN0cnVjdGlvbicpO1xyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHBsYWNlSG9sZGVyKCkge1xyXG4gIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ3BsYWNlaG9sZGVyJyk7XHJcbn07XHJcbiIsIi8vanNoaW50IG5vZGU6IHRydWVcclxuJ3VzZSBzdHJpY3QnO1xyXG52YXIgSW5zdHJ1Y3Rpb24gPSByZXF1aXJlKCcuL0luc3RydWN0aW9uJyk7XHJcblxyXG5mdW5jdGlvbiBxdWFkcmF0aWNDdXJ2ZVRvKGNweCwgY3B5LCB4LCB5KSB7XHJcbiAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbigncXVhZHJhdGljQ3VydmVUbycsIHtcclxuICAgIGNweDogY3B4LCBcclxuICAgIGNweTogY3B5LCBcclxuICAgIHg6IHgsIFxyXG4gICAgeTogeVxyXG4gIH0pO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHF1YWRyYXRpY0N1cnZlVG87IiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuXHJcbmZ1bmN0aW9uIHJlY3QoeCwgeSwgd2lkdGgsIGhlaWdodCkge1xyXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMikge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbihcInJlY3RcIiwgeyB4OiB4LCB5OiB5LCB3aWR0aDogd2lkdGgsIGhlaWdodDogaGVpZ2h0IH0pO1xyXG4gIH0gZWxzZSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKFwicmVjdFwiLCB7IHg6IDAsIHk6IDAsIHdpZHRoOiB4LCBoZWlnaHQ6IHkgfSk7XHJcbiAgfVxyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHJlY3Q7IiwiJ3VzZSBzdHJpY3QnO1xyXG52YXIgc2V0VHJhbnNmb3JtID0gcmVxdWlyZSgnLi9zZXRUcmFuc2Zvcm0nKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcmVzZXRUcmFuc2Zvcm0oKSB7XHJcbiAgdmFyIGFyZ3MgPSBbXTtcclxuICBmb3IodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICBhcmdzLnB1c2goYXJndW1lbnRzW2ldKTtcclxuICB9XHJcbiAgcmV0dXJuIHNldFRyYW5zZm9ybShbMSwgMCwgMCwgMSwgMCwgMF0sIGFyZ3MpO1xyXG59O1xyXG4iLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxudmFyIEluc3RydWN0aW9uID0gcmVxdWlyZSgnLi9JbnN0cnVjdGlvbicpO1xyXG5cclxuZnVuY3Rpb24gcm90YXRlKHIsIGNoaWxkcmVuKSB7XHJcbiAgciA9ICtyO1xyXG4gIHZhciByZXN1bHQgPSBbbmV3IEluc3RydWN0aW9uKCdyb3RhdGUnLCB7IHI6IHIgfSldO1xyXG4gIGZvcih2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcclxuICAgIHJlc3VsdC5wdXNoKGFyZ3VtZW50c1tpXSk7XHJcbiAgfVxyXG4gIHJlc3VsdC5wdXNoKG5ldyBJbnN0cnVjdGlvbigncmVzdG9yZScpKTtcclxuICByZXR1cm4gcmVzdWx0O1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHJvdGF0ZTsiLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxudmFyIEluc3RydWN0aW9uID0gcmVxdWlyZSgnLi9JbnN0cnVjdGlvbicpO1xyXG5cclxuZnVuY3Rpb24gc2NhbGUoeCwgeSwgY2hpbGRyZW4pIHtcclxuICB2YXIgaSA9IDI7XHJcbiAgaWYgKHR5cGVvZiB5ICE9PSAnbnVtYmVyJykge1xyXG4gICAgeSA9IHg7XHJcbiAgICBpID0gMTtcclxuICB9XHJcbiAgY2hpbGRyZW4gPSBjaGlsZHJlbiB8fCBbXTtcclxuICBcclxuICB2YXIgcmVzdWx0ID0gW25ldyBJbnN0cnVjdGlvbignc2NhbGUnLCB7IHg6IHgsIHk6IHkgfSldLFxyXG4gICAgICBjaGlsZDtcclxuICBmb3IgKDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xyXG4gICAgcmVzdWx0LnB1c2goYXJndW1lbnRzW2ldKTtcclxuICB9XHJcbiAgcmVzdWx0LnB1c2gobmV3IEluc3RydWN0aW9uKCdyZXN0b3JlJykpO1xyXG4gIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gc2NhbGU7IiwiJ3VzZSBzdHJpY3QnO1xyXG52YXIgSW5zdHJ1Y3Rpb24gPSByZXF1aXJlKCcuL0luc3RydWN0aW9uJyk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKG1hdHJpeCwgY2hpbGRyZW4pIHtcclxuXHJcbiAgdmFyIHJlc3VsdCA9IFtuZXcgSW5zdHJ1Y3Rpb24oJ3NldFRyYW5zZm9ybScsIFtcclxuICAgIG1hdHJpeFswXSxcclxuICAgIG1hdHJpeFsxXSxcclxuICAgIG1hdHJpeFsyXSxcclxuICAgIG1hdHJpeFszXSxcclxuICAgIG1hdHJpeFs0XSxcclxuICAgIG1hdHJpeFs1XVxyXG4gIF0pXTtcclxuICBmb3IodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICByZXN1bHQucHVzaChhcmd1bWVudHNbaV0pO1xyXG4gIH1cclxuICByZXN1bHQucHVzaChuZXcgSW5zdHJ1Y3Rpb24oJ3Jlc3RvcmUnKSk7XHJcbiAgcmV0dXJuIHJlc3VsdDtcclxufTtcclxuIiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuXHJcbmZ1bmN0aW9uIHNoYWRvd1N0eWxlKHZhbHVlLCBjaGlsZHJlbikge1xyXG4gIHZhbHVlID0gdmFsdWUgfHwge307XHJcbiAgdmFyIHJlc3VsdCA9IHtcclxuICAgIHNoYWRvd0JsdXI6IG51bGwsXHJcbiAgICBzaGFkb3dDb2xvcjogbnVsbCxcclxuICAgIHNoYWRvd09mZnNldFg6IG51bGwsXHJcbiAgICBzaGFkb3dPZmZzZXRZOiBudWxsXHJcbiAgfTtcclxuICBcclxuICBpZiAodHlwZW9mIHZhbHVlLnNoYWRvd0JsdXIgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQuc2hhZG93Qmx1ciA9IHZhbHVlLnNoYWRvd0JsdXI7IFxyXG4gIH1cclxuICBpZiAodHlwZW9mIHZhbHVlLnNoYWRvd0NvbG9yICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgcmVzdWx0LnNoYWRvd0NvbG9yID0gdmFsdWUuc2hhZG93Q29sb3I7IFxyXG4gIH1cclxuICBpZiAodHlwZW9mIHZhbHVlLnNoYWRvd09mZnNldFggIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQuc2hhZG93T2Zmc2V0WCA9IHZhbHVlLnNoYWRvd09mZnNldFg7IFxyXG4gIH1cclxuICBpZiAodHlwZW9mIHZhbHVlLmRpcmVjdGlvbiAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHJlc3VsdC5zaGFkb3dPZmZzZXRZID0gdmFsdWUuc2hhZG93T2Zmc2V0WTsgXHJcbiAgfVxyXG4gIFxyXG4gIHZhciB0cmVlID0gW25ldyBJbnN0cnVjdGlvbignc2hhZG93U3R5bGUnLCB2YWx1ZSldO1xyXG4gIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICB0cmVlLnB1c2goYXJndW1lbnRzW2ldKTtcclxuICB9XHJcbiAgdHJlZS5wdXNoKG5ldyBJbnN0cnVjdGlvbignZW5kU2hhZG93U3R5bGUnKSk7XHJcbiAgXHJcbiAgcmV0dXJuIHRyZWU7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gc2hhZG93U3R5bGU7IiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuXHJcbmZ1bmN0aW9uIHN0cm9rZSgpIHtcclxuICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdzdHJva2UnKTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBzdHJva2U7IiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKSxcclxuICAgIHBpMiA9IE1hdGguUEkgKiAyO1xyXG5cclxuZnVuY3Rpb24gc3Ryb2tlQXJjKHgsIHksIHIsIHN0YXJ0QW5nbGUsIGVuZEFuZ2xlLCBjb3VudGVyY2xvY2t3aXNlKSB7XHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gNiAmJiBjb3VudGVyY2xvY2t3aXNlKSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKFwic3Ryb2tlQXJjLWNvdW50ZXJjbG9ja3dpc2VcIiwgeyB4OiB4LCB5OiB5LCByOiByLCBzdGFydEFuZ2xlOiBzdGFydEFuZ2xlLCBlbmRBbmdsZTogZW5kQW5nbGUgfSk7XHJcbiAgfVxyXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMykge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbihcInN0cm9rZUFyY1wiLCB7IHg6IHgsIHk6IHksIHI6IHIsIHN0YXJ0QW5nbGU6IHN0YXJ0QW5nbGUsIGVuZEFuZ2xlOiBlbmRBbmdsZSB9KTtcclxuICB9IFxyXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSl7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKFwic3Ryb2tlQXJjXCIsIHsgeDogeCwgeTogeSwgcjogciwgc3RhcnRBbmdsZTogMCwgZW5kQW5nbGU6IHBpMiB9KTtcclxuICB9XHJcbiAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbihcInN0cm9rZUFyY1wiLCAgeyB4OiAwLCB5OiAwLCByOiB4LCBzdGFydEFuZ2xlOiAwLCBlbmRBbmdsZTogcGkyIH0pO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHN0cm9rZUFyYzsiLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxudmFyIEluc3RydWN0aW9uID0gcmVxdWlyZSgnLi9JbnN0cnVjdGlvbicpO1xyXG5cclxuZnVuY3Rpb24gc3Ryb2tlUmVjdCh4LCB5LCB3aWR0aCwgaGVpZ2h0KSB7XHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAyKSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKFwic3Ryb2tlUmVjdFwiLCB7IHg6IHgsIHk6IHksIHdpZHRoOiB3aWR0aCwgaGVpZ2h0OiBoZWlnaHQgfSk7XHJcbiAgfSBlbHNlIHtcclxuICAgIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oXCJzdHJva2VSZWN0XCIsIHsgeDogMCwgeTogMCwgd2lkdGg6IHgsIGhlaWdodDogeSB9KTtcclxuICB9XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gc3Ryb2tlUmVjdDsiLCIvL2pzaGludCBub2RlOiB0cnVlXHJcbid1c2Ugc3RyaWN0JztcclxudmFyIEluc3RydWN0aW9uID0gcmVxdWlyZSgnLi9JbnN0cnVjdGlvbicpO1xyXG5cclxuZnVuY3Rpb24gZmlsbFN0eWxlKHZhbHVlLCBjaGlsZHJlbikge1xyXG4gIHZhciByZXN1bHQgPSBbIG5ldyBJbnN0cnVjdGlvbignc3Ryb2tlU3R5bGUnLCB7IHZhbHVlOiB2YWx1ZSB9KSBdO1xyXG4gIGZvcih2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcclxuICAgIHJlc3VsdC5wdXNoKGFyZ3VtZW50c1tpXSk7XHJcbiAgfVxyXG4gIHJlc3VsdC5wdXNoKG5ldyBJbnN0cnVjdGlvbignZW5kU3Ryb2tlU3R5bGUnKSk7XHJcbiAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmaWxsU3R5bGU7XHJcbiIsInZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gc3Ryb2tlVGV4dCh0ZXh0LCB4LCB5LCBtYXhXaWR0aCkge1xyXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgNCkge1xyXG4gICAgbWF4V2lkdGggPSBudWxsO1xyXG4gIH1cclxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDMpIHtcclxuICAgIHggPSAwO1xyXG4gICAgeSA9IDA7XHJcbiAgfVxyXG4gIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ3N0cm9rZVRleHQnLCB7XHJcbiAgICB0ZXh0OiB0ZXh0LFxyXG4gICAgeDogeCxcclxuICAgIHk6IHksXHJcbiAgICBtYXhXaWR0aDogbWF4V2lkdGhcclxuICB9KTtcclxufTtcclxuIiwiLy9qc2hpbnQgbm9kZTogdHJ1ZVxyXG4ndXNlIHN0cmljdCc7XHJcbnZhciBJbnN0cnVjdGlvbiA9IHJlcXVpcmUoJy4vSW5zdHJ1Y3Rpb24nKTtcclxuZnVuY3Rpb24gdGV4dChzdHIsIHgsIHksIGZpbGwsIHN0cm9rZSwgbWF4V2lkdGgpIHtcclxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gNikge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbigndGV4dCcsIHtcclxuICAgICAgeDogeCxcclxuICAgICAgeTogeSxcclxuICAgICAgZmlsbDogZmlsbCxcclxuICAgICAgc3Ryb2tlOiBzdHJva2UsXHJcbiAgICAgIHRleHQ6IHN0cixcclxuICAgICAgbWF4V2lkdGg6IG1heFdpZHRoXHJcbiAgICB9KTtcclxuICB9XHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDUpIHtcclxuICAgIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ3RleHQnLCB7XHJcbiAgICAgIHg6IHgsXHJcbiAgICAgIHk6IHksXHJcbiAgICAgIGZpbGw6IGZpbGwsXHJcbiAgICAgIHN0cm9rZTogc3Ryb2tlLFxyXG4gICAgICB0ZXh0OiBzdHIsXHJcbiAgICAgIG1heFdpZHRoOiAwXHJcbiAgICB9KTtcclxuICB9XHJcbiAgXHJcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDQpIHtcclxuICAgIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ3RleHQnLCB7XHJcbiAgICAgIHg6IHgsXHJcbiAgICAgIHk6IHksXHJcbiAgICAgIGZpbGw6IGZpbGwsXHJcbiAgICAgIHN0cm9rZTogZmFsc2UsXHJcbiAgICAgIHRleHQ6IHN0cixcclxuICAgICAgbWF4V2lkdGg6IDBcclxuICAgIH0pO1xyXG4gIH1cclxuICBcclxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMykge1xyXG4gICAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbigndGV4dCcsIHtcclxuICAgICAgeDogeCxcclxuICAgICAgeTogeSxcclxuICAgICAgZmlsbDogdHJ1ZSxcclxuICAgICAgc3Ryb2tlOiBmYWxzZSxcclxuICAgICAgdGV4dDogc3RyLFxyXG4gICAgICBtYXhXaWR0aDogMFxyXG4gICAgfSk7XHJcbiAgfVxyXG4gIFxyXG4gIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ3RleHQnLCB7XHJcbiAgICB4OiAwLFxyXG4gICAgeTogMCxcclxuICAgIGZpbGw6IHRydWUsXHJcbiAgICBzdHJva2U6IGZhbHNlLFxyXG4gICAgdGV4dDogc3RyLFxyXG4gICAgbWF4V2lkdGg6IDBcclxuICB9KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSB0ZXh0OyIsIi8vanNoaW50IG5vZGU6IHRydWVcclxuJ3VzZSBzdHJpY3QnO1xyXG52YXIgSW5zdHJ1Y3Rpb24gPSByZXF1aXJlKCcuL0luc3RydWN0aW9uJyk7XHJcblxyXG5mdW5jdGlvbiB0ZXh0U3R5bGUodmFsdWUsIGNoaWxkcmVuKSB7XHJcbiAgdmFsdWUgPSB2YWx1ZSB8fCB7fTtcclxuICB2YXIgcmVzdWx0ID0ge1xyXG4gICAgZm9udDogbnVsbCxcclxuICAgIHRleHRBbGlnbjogbnVsbCxcclxuICAgIHRleHRCYXNlbGluZTogbnVsbCxcclxuICAgIGRpcmVjdGlvbjogbnVsbFxyXG4gIH07XHJcbiAgXHJcbiAgaWYgKHR5cGVvZiB2YWx1ZS5mb250ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgcmVzdWx0LmZvbnQgPSB2YWx1ZS5mb250OyBcclxuICB9XHJcbiAgaWYgKHR5cGVvZiB2YWx1ZS50ZXh0QWxpZ24gIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQudGV4dEFsaWduID0gdmFsdWUudGV4dEFsaWduOyBcclxuICB9XHJcbiAgaWYgKHR5cGVvZiB2YWx1ZS50ZXh0QmFzZWxpbmUgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQudGV4dEJhc2VsaW5lID0gdmFsdWUudGV4dEJhc2VsaW5lOyBcclxuICB9XHJcbiAgaWYgKHR5cGVvZiB2YWx1ZS5kaXJlY3Rpb24gIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQuZGlyZWN0aW9uID0gdmFsdWUuZGlyZWN0aW9uOyBcclxuICB9XHJcbiAgdmFyIHRyZWUgPSBbbmV3IEluc3RydWN0aW9uKCd0ZXh0U3R5bGUnLCB2YWx1ZSldO1xyXG4gIGZvcih2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcclxuICAgIHRyZWUucHVzaChhcmd1bWVudHNbaV0pO1xyXG4gIH1cclxuICB0cmVlLnB1c2gobmV3IEluc3RydWN0aW9uKCdlbmRUZXh0U3R5bGUnKSk7XHJcbiAgcmV0dXJuIHRyZWU7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gdGV4dFN0eWxlOyIsIi8vanNoaW50IG5vZGU6IHRydWVcclxuJ3VzZSBzdHJpY3QnO1xyXG52YXIgSW5zdHJ1Y3Rpb24gPSByZXF1aXJlKCcuL0luc3RydWN0aW9uJyk7XHJcblxyXG5mdW5jdGlvbiB0cmFuc2Zvcm0odmFsdWVzLCBjaGlsZHJlbikge1xyXG5cclxuICB2YXIgdHJhbnNmb3JtUmVzdWx0ID0gW1xyXG4gICAgbmV3IEluc3RydWN0aW9uKCd0cmFuc2Zvcm0nLFtcclxuICAgICAgdmFsdWVzWzBdLFxyXG4gICAgICB2YWx1ZXNbMV0sXHJcbiAgICAgIHZhbHVlc1syXSxcclxuICAgICAgdmFsdWVzWzNdLFxyXG4gICAgICB2YWx1ZXNbNF0sXHJcbiAgICAgIHZhbHVlc1s1XVxyXG4gICAgXSlcclxuICBdO1xyXG4gIGZvcih2YXIgaSA9IDEsIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgdHJhbnNmb3JtUmVzdWx0LnB1c2goYXJndW1lbnRzW2ldKTtcclxuICB9XHJcbiAgdHJhbnNmb3JtUmVzdWx0LnB1c2gobmV3IEluc3RydWN0aW9uKCdyZXN0b3JlJykpO1xyXG5cclxuICByZXR1cm4gdHJhbnNmb3JtUmVzdWx0O1xyXG59XHJcblxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSB0cmFuc2Zvcm07XHJcbiIsIi8vanNoaW50IG5vZGU6IHRydWVcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxuZnVuY3Rpb24gdHJhbnNmb3JtUG9pbnRzKHBvaW50cywgbWF0cml4KSB7XHJcbiAgdmFyIHJlc3VsdCA9IFtdLFxyXG4gICAgICBsZW4gPSBwb2ludHMubGVuZ3RoLFxyXG4gICAgICBwb2ludDtcclxuXHJcbiAgZm9yKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICBwb2ludCA9IHBvaW50c1tpXTtcclxuICAgIHJlc3VsdC5wdXNoKFtcclxuICAgICAgbWF0cml4WzBdICogcG9pbnRbMF0gKyBtYXRyaXhbMl0gKiBwb2ludFsxXSArIG1hdHJpeFs0XSxcclxuICAgICAgbWF0cml4WzFdICogcG9pbnRbMF0gKyBtYXRyaXhbM10gKiBwb2ludFsxXSArIG1hdHJpeFs1XVxyXG4gICAgXSk7XHJcbiAgfVxyXG4gIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gdHJhbnNmb3JtUG9pbnRzOyIsIi8vanNoaW50IG5vZGU6IHRydWVcclxuJ3VzZSBzdHJpY3QnO1xyXG52YXIgSW5zdHJ1Y3Rpb24gPSByZXF1aXJlKCcuL0luc3RydWN0aW9uJyk7XHJcblxyXG5mdW5jdGlvbiB0cmFuc2xhdGUoeCwgeSwgY2hpbGRyZW4pIHtcclxuICBcclxuICB2YXIgcmVzdWx0ID0gW25ldyBJbnN0cnVjdGlvbigndHJhbnNsYXRlJywgeyB4OiB4LCB5OiB5IH0pXTtcclxuICB2YXIgdmFsO1xyXG4gIGZvciAodmFyIGkgPSAyOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICB2YWwgPSBhcmd1bWVudHNbaV07XHJcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWwpKSB7XHJcbiAgICAgIHJlc3VsdCA9IHJlc3VsdC5jb25jYXQodmFsKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcbiAgICByZXN1bHQucHVzaChhcmd1bWVudHNbaV0pO1xyXG4gIH1cclxuICBcclxuICByZXN1bHQucHVzaChuZXcgSW5zdHJ1Y3Rpb24oJ3Jlc3RvcmUnKSk7XHJcbiAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSB0cmFuc2xhdGU7IiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbmZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcbiAgdGhpcy5fZXZlbnRzID0gdGhpcy5fZXZlbnRzIHx8IHt9O1xuICB0aGlzLl9tYXhMaXN0ZW5lcnMgPSB0aGlzLl9tYXhMaXN0ZW5lcnMgfHwgdW5kZWZpbmVkO1xufVxubW9kdWxlLmV4cG9ydHMgPSBFdmVudEVtaXR0ZXI7XG5cbi8vIEJhY2t3YXJkcy1jb21wYXQgd2l0aCBub2RlIDAuMTAueFxuRXZlbnRFbWl0dGVyLkV2ZW50RW1pdHRlciA9IEV2ZW50RW1pdHRlcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fZXZlbnRzID0gdW5kZWZpbmVkO1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fbWF4TGlzdGVuZXJzID0gdW5kZWZpbmVkO1xuXG4vLyBCeSBkZWZhdWx0IEV2ZW50RW1pdHRlcnMgd2lsbCBwcmludCBhIHdhcm5pbmcgaWYgbW9yZSB0aGFuIDEwIGxpc3RlbmVycyBhcmVcbi8vIGFkZGVkIHRvIGl0LiBUaGlzIGlzIGEgdXNlZnVsIGRlZmF1bHQgd2hpY2ggaGVscHMgZmluZGluZyBtZW1vcnkgbGVha3MuXG5FdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycyA9IDEwO1xuXG4vLyBPYnZpb3VzbHkgbm90IGFsbCBFbWl0dGVycyBzaG91bGQgYmUgbGltaXRlZCB0byAxMC4gVGhpcyBmdW5jdGlvbiBhbGxvd3Ncbi8vIHRoYXQgdG8gYmUgaW5jcmVhc2VkLiBTZXQgdG8gemVybyBmb3IgdW5saW1pdGVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbihuKSB7XG4gIGlmICghaXNOdW1iZXIobikgfHwgbiA8IDAgfHwgaXNOYU4obikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCduIG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbih0eXBlKSB7XG4gIHZhciBlciwgaGFuZGxlciwgbGVuLCBhcmdzLCBpLCBsaXN0ZW5lcnM7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMpXG4gICAgdGhpcy5fZXZlbnRzID0ge307XG5cbiAgLy8gSWYgdGhlcmUgaXMgbm8gJ2Vycm9yJyBldmVudCBsaXN0ZW5lciB0aGVuIHRocm93LlxuICBpZiAodHlwZSA9PT0gJ2Vycm9yJykge1xuICAgIGlmICghdGhpcy5fZXZlbnRzLmVycm9yIHx8XG4gICAgICAgIChpc09iamVjdCh0aGlzLl9ldmVudHMuZXJyb3IpICYmICF0aGlzLl9ldmVudHMuZXJyb3IubGVuZ3RoKSkge1xuICAgICAgZXIgPSBhcmd1bWVudHNbMV07XG4gICAgICBpZiAoZXIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICB0aHJvdyBlcjsgLy8gVW5oYW5kbGVkICdlcnJvcicgZXZlbnRcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IFR5cGVFcnJvcignVW5jYXVnaHQsIHVuc3BlY2lmaWVkIFwiZXJyb3JcIiBldmVudC4nKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBoYW5kbGVyID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIGlmIChpc1VuZGVmaW5lZChoYW5kbGVyKSlcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgaWYgKGlzRnVuY3Rpb24oaGFuZGxlcikpIHtcbiAgICBzd2l0Y2ggKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIC8vIGZhc3QgY2FzZXNcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMsIGFyZ3VtZW50c1sxXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzOlxuICAgICAgICBoYW5kbGVyLmNhbGwodGhpcywgYXJndW1lbnRzWzFdLCBhcmd1bWVudHNbMl0pO1xuICAgICAgICBicmVhaztcbiAgICAgIC8vIHNsb3dlclxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICAgICAgYXJncyA9IG5ldyBBcnJheShsZW4gLSAxKTtcbiAgICAgICAgZm9yIChpID0gMTsgaSA8IGxlbjsgaSsrKVxuICAgICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgICBoYW5kbGVyLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH1cbiAgfSBlbHNlIGlmIChpc09iamVjdChoYW5kbGVyKSkge1xuICAgIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgYXJncyA9IG5ldyBBcnJheShsZW4gLSAxKTtcbiAgICBmb3IgKGkgPSAxOyBpIDwgbGVuOyBpKyspXG4gICAgICBhcmdzW2kgLSAxXSA9IGFyZ3VtZW50c1tpXTtcblxuICAgIGxpc3RlbmVycyA9IGhhbmRsZXIuc2xpY2UoKTtcbiAgICBsZW4gPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKylcbiAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBtO1xuXG4gIGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICBpZiAoIXRoaXMuX2V2ZW50cylcbiAgICB0aGlzLl9ldmVudHMgPSB7fTtcblxuICAvLyBUbyBhdm9pZCByZWN1cnNpb24gaW4gdGhlIGNhc2UgdGhhdCB0eXBlID09PSBcIm5ld0xpc3RlbmVyXCIhIEJlZm9yZVxuICAvLyBhZGRpbmcgaXQgdG8gdGhlIGxpc3RlbmVycywgZmlyc3QgZW1pdCBcIm5ld0xpc3RlbmVyXCIuXG4gIGlmICh0aGlzLl9ldmVudHMubmV3TGlzdGVuZXIpXG4gICAgdGhpcy5lbWl0KCduZXdMaXN0ZW5lcicsIHR5cGUsXG4gICAgICAgICAgICAgIGlzRnVuY3Rpb24obGlzdGVuZXIubGlzdGVuZXIpID9cbiAgICAgICAgICAgICAgbGlzdGVuZXIubGlzdGVuZXIgOiBsaXN0ZW5lcik7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgLy8gT3B0aW1pemUgdGhlIGNhc2Ugb2Ygb25lIGxpc3RlbmVyLiBEb24ndCBuZWVkIHRoZSBleHRyYSBhcnJheSBvYmplY3QuXG4gICAgdGhpcy5fZXZlbnRzW3R5cGVdID0gbGlzdGVuZXI7XG4gIGVsc2UgaWYgKGlzT2JqZWN0KHRoaXMuX2V2ZW50c1t0eXBlXSkpXG4gICAgLy8gSWYgd2UndmUgYWxyZWFkeSBnb3QgYW4gYXJyYXksIGp1c3QgYXBwZW5kLlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXS5wdXNoKGxpc3RlbmVyKTtcbiAgZWxzZVxuICAgIC8vIEFkZGluZyB0aGUgc2Vjb25kIGVsZW1lbnQsIG5lZWQgdG8gY2hhbmdlIHRvIGFycmF5LlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXSA9IFt0aGlzLl9ldmVudHNbdHlwZV0sIGxpc3RlbmVyXTtcblxuICAvLyBDaGVjayBmb3IgbGlzdGVuZXIgbGVha1xuICBpZiAoaXNPYmplY3QodGhpcy5fZXZlbnRzW3R5cGVdKSAmJiAhdGhpcy5fZXZlbnRzW3R5cGVdLndhcm5lZCkge1xuICAgIHZhciBtO1xuICAgIGlmICghaXNVbmRlZmluZWQodGhpcy5fbWF4TGlzdGVuZXJzKSkge1xuICAgICAgbSA9IHRoaXMuX21heExpc3RlbmVycztcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IEV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzO1xuICAgIH1cblxuICAgIGlmIChtICYmIG0gPiAwICYmIHRoaXMuX2V2ZW50c1t0eXBlXS5sZW5ndGggPiBtKSB7XG4gICAgICB0aGlzLl9ldmVudHNbdHlwZV0ud2FybmVkID0gdHJ1ZTtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJyhub2RlKSB3YXJuaW5nOiBwb3NzaWJsZSBFdmVudEVtaXR0ZXIgbWVtb3J5ICcgK1xuICAgICAgICAgICAgICAgICAgICAnbGVhayBkZXRlY3RlZC4gJWQgbGlzdGVuZXJzIGFkZGVkLiAnICtcbiAgICAgICAgICAgICAgICAgICAgJ1VzZSBlbWl0dGVyLnNldE1heExpc3RlbmVycygpIHRvIGluY3JlYXNlIGxpbWl0LicsXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50c1t0eXBlXS5sZW5ndGgpO1xuICAgICAgaWYgKHR5cGVvZiBjb25zb2xlLnRyYWNlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIC8vIG5vdCBzdXBwb3J0ZWQgaW4gSUUgMTBcbiAgICAgICAgY29uc29sZS50cmFjZSgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICB2YXIgZmlyZWQgPSBmYWxzZTtcblxuICBmdW5jdGlvbiBnKCkge1xuICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgZyk7XG5cbiAgICBpZiAoIWZpcmVkKSB7XG4gICAgICBmaXJlZCA9IHRydWU7XG4gICAgICBsaXN0ZW5lci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cbiAgfVxuXG4gIGcubGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgdGhpcy5vbih0eXBlLCBnKTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIGVtaXRzIGEgJ3JlbW92ZUxpc3RlbmVyJyBldmVudCBpZmYgdGhlIGxpc3RlbmVyIHdhcyByZW1vdmVkXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIGxpc3QsIHBvc2l0aW9uLCBsZW5ndGgsIGk7XG5cbiAgaWYgKCFpc0Z1bmN0aW9uKGxpc3RlbmVyKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ2xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzIHx8ICF0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgbGlzdCA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgbGVuZ3RoID0gbGlzdC5sZW5ndGg7XG4gIHBvc2l0aW9uID0gLTE7XG5cbiAgaWYgKGxpc3QgPT09IGxpc3RlbmVyIHx8XG4gICAgICAoaXNGdW5jdGlvbihsaXN0Lmxpc3RlbmVyKSAmJiBsaXN0Lmxpc3RlbmVyID09PSBsaXN0ZW5lcikpIHtcbiAgICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuICAgIGlmICh0aGlzLl9ldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgbGlzdGVuZXIpO1xuXG4gIH0gZWxzZSBpZiAoaXNPYmplY3QobGlzdCkpIHtcbiAgICBmb3IgKGkgPSBsZW5ndGg7IGktLSA+IDA7KSB7XG4gICAgICBpZiAobGlzdFtpXSA9PT0gbGlzdGVuZXIgfHxcbiAgICAgICAgICAobGlzdFtpXS5saXN0ZW5lciAmJiBsaXN0W2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikpIHtcbiAgICAgICAgcG9zaXRpb24gPSBpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocG9zaXRpb24gPCAwKVxuICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICBpZiAobGlzdC5sZW5ndGggPT09IDEpIHtcbiAgICAgIGxpc3QubGVuZ3RoID0gMDtcbiAgICAgIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGxpc3Quc3BsaWNlKHBvc2l0aW9uLCAxKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIGxpc3RlbmVyKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBmdW5jdGlvbih0eXBlKSB7XG4gIHZhciBrZXksIGxpc3RlbmVycztcblxuICBpZiAoIXRoaXMuX2V2ZW50cylcbiAgICByZXR1cm4gdGhpcztcblxuICAvLyBub3QgbGlzdGVuaW5nIGZvciByZW1vdmVMaXN0ZW5lciwgbm8gbmVlZCB0byBlbWl0XG4gIGlmICghdGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApXG4gICAgICB0aGlzLl9ldmVudHMgPSB7fTtcbiAgICBlbHNlIGlmICh0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gZW1pdCByZW1vdmVMaXN0ZW5lciBmb3IgYWxsIGxpc3RlbmVycyBvbiBhbGwgZXZlbnRzXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgZm9yIChrZXkgaW4gdGhpcy5fZXZlbnRzKSB7XG4gICAgICBpZiAoa2V5ID09PSAncmVtb3ZlTGlzdGVuZXInKSBjb250aW51ZTtcbiAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKGtleSk7XG4gICAgfVxuICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKCdyZW1vdmVMaXN0ZW5lcicpO1xuICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgbGlzdGVuZXJzID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIGlmIChpc0Z1bmN0aW9uKGxpc3RlbmVycykpIHtcbiAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVycyk7XG4gIH0gZWxzZSB7XG4gICAgLy8gTElGTyBvcmRlclxuICAgIHdoaWxlIChsaXN0ZW5lcnMubGVuZ3RoKVxuICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnNbbGlzdGVuZXJzLmxlbmd0aCAtIDFdKTtcbiAgfVxuICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lcnMgPSBmdW5jdGlvbih0eXBlKSB7XG4gIHZhciByZXQ7XG4gIGlmICghdGhpcy5fZXZlbnRzIHx8ICF0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgcmV0ID0gW107XG4gIGVsc2UgaWYgKGlzRnVuY3Rpb24odGhpcy5fZXZlbnRzW3R5cGVdKSlcbiAgICByZXQgPSBbdGhpcy5fZXZlbnRzW3R5cGVdXTtcbiAgZWxzZVxuICAgIHJldCA9IHRoaXMuX2V2ZW50c1t0eXBlXS5zbGljZSgpO1xuICByZXR1cm4gcmV0O1xufTtcblxuRXZlbnRFbWl0dGVyLmxpc3RlbmVyQ291bnQgPSBmdW5jdGlvbihlbWl0dGVyLCB0eXBlKSB7XG4gIHZhciByZXQ7XG4gIGlmICghZW1pdHRlci5fZXZlbnRzIHx8ICFlbWl0dGVyLl9ldmVudHNbdHlwZV0pXG4gICAgcmV0ID0gMDtcbiAgZWxzZSBpZiAoaXNGdW5jdGlvbihlbWl0dGVyLl9ldmVudHNbdHlwZV0pKVxuICAgIHJldCA9IDE7XG4gIGVsc2VcbiAgICByZXQgPSBlbWl0dGVyLl9ldmVudHNbdHlwZV0ubGVuZ3RoO1xuICByZXR1cm4gcmV0O1xufTtcblxuZnVuY3Rpb24gaXNGdW5jdGlvbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdmdW5jdGlvbic7XG59XG5cbmZ1bmN0aW9uIGlzTnVtYmVyKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ251bWJlcic7XG59XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ29iamVjdCcgJiYgYXJnICE9PSBudWxsO1xufVxuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gdm9pZCAwO1xufVxuIiwiaWYgKHR5cGVvZiBPYmplY3QuY3JlYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gIC8vIGltcGxlbWVudGF0aW9uIGZyb20gc3RhbmRhcmQgbm9kZS5qcyAndXRpbCcgbW9kdWxlXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDdG9yLnByb3RvdHlwZSwge1xuICAgICAgY29uc3RydWN0b3I6IHtcbiAgICAgICAgdmFsdWU6IGN0b3IsXG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgICB9XG4gICAgfSk7XG4gIH07XG59IGVsc2Uge1xuICAvLyBvbGQgc2Nob29sIHNoaW0gZm9yIG9sZCBicm93c2Vyc1xuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgdmFyIFRlbXBDdG9yID0gZnVuY3Rpb24gKCkge31cbiAgICBUZW1wQ3Rvci5wcm90b3R5cGUgPSBzdXBlckN0b3IucHJvdG90eXBlXG4gICAgY3Rvci5wcm90b3R5cGUgPSBuZXcgVGVtcEN0b3IoKVxuICAgIGN0b3IucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gY3RvclxuICB9XG59XG4iLCIoZnVuY3Rpb24gKHByb2Nlc3Mpe1xuLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbi8vIHJlc29sdmVzIC4gYW5kIC4uIGVsZW1lbnRzIGluIGEgcGF0aCBhcnJheSB3aXRoIGRpcmVjdG9yeSBuYW1lcyB0aGVyZVxuLy8gbXVzdCBiZSBubyBzbGFzaGVzLCBlbXB0eSBlbGVtZW50cywgb3IgZGV2aWNlIG5hbWVzIChjOlxcKSBpbiB0aGUgYXJyYXlcbi8vIChzbyBhbHNvIG5vIGxlYWRpbmcgYW5kIHRyYWlsaW5nIHNsYXNoZXMgLSBpdCBkb2VzIG5vdCBkaXN0aW5ndWlzaFxuLy8gcmVsYXRpdmUgYW5kIGFic29sdXRlIHBhdGhzKVxuZnVuY3Rpb24gbm9ybWFsaXplQXJyYXkocGFydHMsIGFsbG93QWJvdmVSb290KSB7XG4gIC8vIGlmIHRoZSBwYXRoIHRyaWVzIHRvIGdvIGFib3ZlIHRoZSByb290LCBgdXBgIGVuZHMgdXAgPiAwXG4gIHZhciB1cCA9IDA7XG4gIGZvciAodmFyIGkgPSBwYXJ0cy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIHZhciBsYXN0ID0gcGFydHNbaV07XG4gICAgaWYgKGxhc3QgPT09ICcuJykge1xuICAgICAgcGFydHMuc3BsaWNlKGksIDEpO1xuICAgIH0gZWxzZSBpZiAobGFzdCA9PT0gJy4uJykge1xuICAgICAgcGFydHMuc3BsaWNlKGksIDEpO1xuICAgICAgdXArKztcbiAgICB9IGVsc2UgaWYgKHVwKSB7XG4gICAgICBwYXJ0cy5zcGxpY2UoaSwgMSk7XG4gICAgICB1cC0tO1xuICAgIH1cbiAgfVxuXG4gIC8vIGlmIHRoZSBwYXRoIGlzIGFsbG93ZWQgdG8gZ28gYWJvdmUgdGhlIHJvb3QsIHJlc3RvcmUgbGVhZGluZyAuLnNcbiAgaWYgKGFsbG93QWJvdmVSb290KSB7XG4gICAgZm9yICg7IHVwLS07IHVwKSB7XG4gICAgICBwYXJ0cy51bnNoaWZ0KCcuLicpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBwYXJ0cztcbn1cblxuLy8gU3BsaXQgYSBmaWxlbmFtZSBpbnRvIFtyb290LCBkaXIsIGJhc2VuYW1lLCBleHRdLCB1bml4IHZlcnNpb25cbi8vICdyb290JyBpcyBqdXN0IGEgc2xhc2gsIG9yIG5vdGhpbmcuXG52YXIgc3BsaXRQYXRoUmUgPVxuICAgIC9eKFxcLz98KShbXFxzXFxTXSo/KSgoPzpcXC57MSwyfXxbXlxcL10rP3wpKFxcLlteLlxcL10qfCkpKD86W1xcL10qKSQvO1xudmFyIHNwbGl0UGF0aCA9IGZ1bmN0aW9uKGZpbGVuYW1lKSB7XG4gIHJldHVybiBzcGxpdFBhdGhSZS5leGVjKGZpbGVuYW1lKS5zbGljZSgxKTtcbn07XG5cbi8vIHBhdGgucmVzb2x2ZShbZnJvbSAuLi5dLCB0bylcbi8vIHBvc2l4IHZlcnNpb25cbmV4cG9ydHMucmVzb2x2ZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcmVzb2x2ZWRQYXRoID0gJycsXG4gICAgICByZXNvbHZlZEFic29sdXRlID0gZmFsc2U7XG5cbiAgZm9yICh2YXIgaSA9IGFyZ3VtZW50cy5sZW5ndGggLSAxOyBpID49IC0xICYmICFyZXNvbHZlZEFic29sdXRlOyBpLS0pIHtcbiAgICB2YXIgcGF0aCA9IChpID49IDApID8gYXJndW1lbnRzW2ldIDogcHJvY2Vzcy5jd2QoKTtcblxuICAgIC8vIFNraXAgZW1wdHkgYW5kIGludmFsaWQgZW50cmllc1xuICAgIGlmICh0eXBlb2YgcGF0aCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50cyB0byBwYXRoLnJlc29sdmUgbXVzdCBiZSBzdHJpbmdzJyk7XG4gICAgfSBlbHNlIGlmICghcGF0aCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgcmVzb2x2ZWRQYXRoID0gcGF0aCArICcvJyArIHJlc29sdmVkUGF0aDtcbiAgICByZXNvbHZlZEFic29sdXRlID0gcGF0aC5jaGFyQXQoMCkgPT09ICcvJztcbiAgfVxuXG4gIC8vIEF0IHRoaXMgcG9pbnQgdGhlIHBhdGggc2hvdWxkIGJlIHJlc29sdmVkIHRvIGEgZnVsbCBhYnNvbHV0ZSBwYXRoLCBidXRcbiAgLy8gaGFuZGxlIHJlbGF0aXZlIHBhdGhzIHRvIGJlIHNhZmUgKG1pZ2h0IGhhcHBlbiB3aGVuIHByb2Nlc3MuY3dkKCkgZmFpbHMpXG5cbiAgLy8gTm9ybWFsaXplIHRoZSBwYXRoXG4gIHJlc29sdmVkUGF0aCA9IG5vcm1hbGl6ZUFycmF5KGZpbHRlcihyZXNvbHZlZFBhdGguc3BsaXQoJy8nKSwgZnVuY3Rpb24ocCkge1xuICAgIHJldHVybiAhIXA7XG4gIH0pLCAhcmVzb2x2ZWRBYnNvbHV0ZSkuam9pbignLycpO1xuXG4gIHJldHVybiAoKHJlc29sdmVkQWJzb2x1dGUgPyAnLycgOiAnJykgKyByZXNvbHZlZFBhdGgpIHx8ICcuJztcbn07XG5cbi8vIHBhdGgubm9ybWFsaXplKHBhdGgpXG4vLyBwb3NpeCB2ZXJzaW9uXG5leHBvcnRzLm5vcm1hbGl6ZSA9IGZ1bmN0aW9uKHBhdGgpIHtcbiAgdmFyIGlzQWJzb2x1dGUgPSBleHBvcnRzLmlzQWJzb2x1dGUocGF0aCksXG4gICAgICB0cmFpbGluZ1NsYXNoID0gc3Vic3RyKHBhdGgsIC0xKSA9PT0gJy8nO1xuXG4gIC8vIE5vcm1hbGl6ZSB0aGUgcGF0aFxuICBwYXRoID0gbm9ybWFsaXplQXJyYXkoZmlsdGVyKHBhdGguc3BsaXQoJy8nKSwgZnVuY3Rpb24ocCkge1xuICAgIHJldHVybiAhIXA7XG4gIH0pLCAhaXNBYnNvbHV0ZSkuam9pbignLycpO1xuXG4gIGlmICghcGF0aCAmJiAhaXNBYnNvbHV0ZSkge1xuICAgIHBhdGggPSAnLic7XG4gIH1cbiAgaWYgKHBhdGggJiYgdHJhaWxpbmdTbGFzaCkge1xuICAgIHBhdGggKz0gJy8nO1xuICB9XG5cbiAgcmV0dXJuIChpc0Fic29sdXRlID8gJy8nIDogJycpICsgcGF0aDtcbn07XG5cbi8vIHBvc2l4IHZlcnNpb25cbmV4cG9ydHMuaXNBYnNvbHV0ZSA9IGZ1bmN0aW9uKHBhdGgpIHtcbiAgcmV0dXJuIHBhdGguY2hhckF0KDApID09PSAnLyc7XG59O1xuXG4vLyBwb3NpeCB2ZXJzaW9uXG5leHBvcnRzLmpvaW4gPSBmdW5jdGlvbigpIHtcbiAgdmFyIHBhdGhzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKTtcbiAgcmV0dXJuIGV4cG9ydHMubm9ybWFsaXplKGZpbHRlcihwYXRocywgZnVuY3Rpb24ocCwgaW5kZXgpIHtcbiAgICBpZiAodHlwZW9mIHAgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudHMgdG8gcGF0aC5qb2luIG11c3QgYmUgc3RyaW5ncycpO1xuICAgIH1cbiAgICByZXR1cm4gcDtcbiAgfSkuam9pbignLycpKTtcbn07XG5cblxuLy8gcGF0aC5yZWxhdGl2ZShmcm9tLCB0bylcbi8vIHBvc2l4IHZlcnNpb25cbmV4cG9ydHMucmVsYXRpdmUgPSBmdW5jdGlvbihmcm9tLCB0bykge1xuICBmcm9tID0gZXhwb3J0cy5yZXNvbHZlKGZyb20pLnN1YnN0cigxKTtcbiAgdG8gPSBleHBvcnRzLnJlc29sdmUodG8pLnN1YnN0cigxKTtcblxuICBmdW5jdGlvbiB0cmltKGFycikge1xuICAgIHZhciBzdGFydCA9IDA7XG4gICAgZm9yICg7IHN0YXJ0IDwgYXJyLmxlbmd0aDsgc3RhcnQrKykge1xuICAgICAgaWYgKGFycltzdGFydF0gIT09ICcnKSBicmVhaztcbiAgICB9XG5cbiAgICB2YXIgZW5kID0gYXJyLmxlbmd0aCAtIDE7XG4gICAgZm9yICg7IGVuZCA+PSAwOyBlbmQtLSkge1xuICAgICAgaWYgKGFycltlbmRdICE9PSAnJykgYnJlYWs7XG4gICAgfVxuXG4gICAgaWYgKHN0YXJ0ID4gZW5kKSByZXR1cm4gW107XG4gICAgcmV0dXJuIGFyci5zbGljZShzdGFydCwgZW5kIC0gc3RhcnQgKyAxKTtcbiAgfVxuXG4gIHZhciBmcm9tUGFydHMgPSB0cmltKGZyb20uc3BsaXQoJy8nKSk7XG4gIHZhciB0b1BhcnRzID0gdHJpbSh0by5zcGxpdCgnLycpKTtcblxuICB2YXIgbGVuZ3RoID0gTWF0aC5taW4oZnJvbVBhcnRzLmxlbmd0aCwgdG9QYXJ0cy5sZW5ndGgpO1xuICB2YXIgc2FtZVBhcnRzTGVuZ3RoID0gbGVuZ3RoO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGZyb21QYXJ0c1tpXSAhPT0gdG9QYXJ0c1tpXSkge1xuICAgICAgc2FtZVBhcnRzTGVuZ3RoID0gaTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHZhciBvdXRwdXRQYXJ0cyA9IFtdO1xuICBmb3IgKHZhciBpID0gc2FtZVBhcnRzTGVuZ3RoOyBpIDwgZnJvbVBhcnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgb3V0cHV0UGFydHMucHVzaCgnLi4nKTtcbiAgfVxuXG4gIG91dHB1dFBhcnRzID0gb3V0cHV0UGFydHMuY29uY2F0KHRvUGFydHMuc2xpY2Uoc2FtZVBhcnRzTGVuZ3RoKSk7XG5cbiAgcmV0dXJuIG91dHB1dFBhcnRzLmpvaW4oJy8nKTtcbn07XG5cbmV4cG9ydHMuc2VwID0gJy8nO1xuZXhwb3J0cy5kZWxpbWl0ZXIgPSAnOic7XG5cbmV4cG9ydHMuZGlybmFtZSA9IGZ1bmN0aW9uKHBhdGgpIHtcbiAgdmFyIHJlc3VsdCA9IHNwbGl0UGF0aChwYXRoKSxcbiAgICAgIHJvb3QgPSByZXN1bHRbMF0sXG4gICAgICBkaXIgPSByZXN1bHRbMV07XG5cbiAgaWYgKCFyb290ICYmICFkaXIpIHtcbiAgICAvLyBObyBkaXJuYW1lIHdoYXRzb2V2ZXJcbiAgICByZXR1cm4gJy4nO1xuICB9XG5cbiAgaWYgKGRpcikge1xuICAgIC8vIEl0IGhhcyBhIGRpcm5hbWUsIHN0cmlwIHRyYWlsaW5nIHNsYXNoXG4gICAgZGlyID0gZGlyLnN1YnN0cigwLCBkaXIubGVuZ3RoIC0gMSk7XG4gIH1cblxuICByZXR1cm4gcm9vdCArIGRpcjtcbn07XG5cblxuZXhwb3J0cy5iYXNlbmFtZSA9IGZ1bmN0aW9uKHBhdGgsIGV4dCkge1xuICB2YXIgZiA9IHNwbGl0UGF0aChwYXRoKVsyXTtcbiAgLy8gVE9ETzogbWFrZSB0aGlzIGNvbXBhcmlzb24gY2FzZS1pbnNlbnNpdGl2ZSBvbiB3aW5kb3dzP1xuICBpZiAoZXh0ICYmIGYuc3Vic3RyKC0xICogZXh0Lmxlbmd0aCkgPT09IGV4dCkge1xuICAgIGYgPSBmLnN1YnN0cigwLCBmLmxlbmd0aCAtIGV4dC5sZW5ndGgpO1xuICB9XG4gIHJldHVybiBmO1xufTtcblxuXG5leHBvcnRzLmV4dG5hbWUgPSBmdW5jdGlvbihwYXRoKSB7XG4gIHJldHVybiBzcGxpdFBhdGgocGF0aClbM107XG59O1xuXG5mdW5jdGlvbiBmaWx0ZXIgKHhzLCBmKSB7XG4gICAgaWYgKHhzLmZpbHRlcikgcmV0dXJuIHhzLmZpbHRlcihmKTtcbiAgICB2YXIgcmVzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB4cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoZih4c1tpXSwgaSwgeHMpKSByZXMucHVzaCh4c1tpXSk7XG4gICAgfVxuICAgIHJldHVybiByZXM7XG59XG5cbi8vIFN0cmluZy5wcm90b3R5cGUuc3Vic3RyIC0gbmVnYXRpdmUgaW5kZXggZG9uJ3Qgd29yayBpbiBJRThcbnZhciBzdWJzdHIgPSAnYWInLnN1YnN0cigtMSkgPT09ICdiJ1xuICAgID8gZnVuY3Rpb24gKHN0ciwgc3RhcnQsIGxlbikgeyByZXR1cm4gc3RyLnN1YnN0cihzdGFydCwgbGVuKSB9XG4gICAgOiBmdW5jdGlvbiAoc3RyLCBzdGFydCwgbGVuKSB7XG4gICAgICAgIGlmIChzdGFydCA8IDApIHN0YXJ0ID0gc3RyLmxlbmd0aCArIHN0YXJ0O1xuICAgICAgICByZXR1cm4gc3RyLnN1YnN0cihzdGFydCwgbGVuKTtcbiAgICB9XG47XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKCdfcHJvY2VzcycpKSIsIi8vIHNoaW0gZm9yIHVzaW5nIHByb2Nlc3MgaW4gYnJvd3NlclxuXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG5cbnByb2Nlc3MubmV4dFRpY2sgPSAoZnVuY3Rpb24gKCkge1xuICAgIHZhciBjYW5TZXRJbW1lZGlhdGUgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJ1xuICAgICYmIHdpbmRvdy5zZXRJbW1lZGlhdGU7XG4gICAgdmFyIGNhblBvc3QgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJ1xuICAgICYmIHdpbmRvdy5wb3N0TWVzc2FnZSAmJiB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lclxuICAgIDtcblxuICAgIGlmIChjYW5TZXRJbW1lZGlhdGUpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChmKSB7IHJldHVybiB3aW5kb3cuc2V0SW1tZWRpYXRlKGYpIH07XG4gICAgfVxuXG4gICAgaWYgKGNhblBvc3QpIHtcbiAgICAgICAgdmFyIHF1ZXVlID0gW107XG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgICAgICB2YXIgc291cmNlID0gZXYuc291cmNlO1xuICAgICAgICAgICAgaWYgKChzb3VyY2UgPT09IHdpbmRvdyB8fCBzb3VyY2UgPT09IG51bGwpICYmIGV2LmRhdGEgPT09ICdwcm9jZXNzLXRpY2snKSB7XG4gICAgICAgICAgICAgICAgZXYuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgaWYgKHF1ZXVlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGZuID0gcXVldWUuc2hpZnQoKTtcbiAgICAgICAgICAgICAgICAgICAgZm4oKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIHRydWUpO1xuXG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBuZXh0VGljayhmbikge1xuICAgICAgICAgICAgcXVldWUucHVzaChmbik7XG4gICAgICAgICAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ3Byb2Nlc3MtdGljaycsICcqJyk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIGZ1bmN0aW9uIG5leHRUaWNrKGZuKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZm4sIDApO1xuICAgIH07XG59KSgpO1xuXG5wcm9jZXNzLnRpdGxlID0gJ2Jyb3dzZXInO1xucHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcbnByb2Nlc3MuZW52ID0ge307XG5wcm9jZXNzLmFyZ3YgPSBbXTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnByb2Nlc3Mub24gPSBub29wO1xucHJvY2Vzcy5hZGRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLm9uY2UgPSBub29wO1xucHJvY2Vzcy5vZmYgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUFsbExpc3RlbmVycyA9IG5vb3A7XG5wcm9jZXNzLmVtaXQgPSBub29wO1xuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn1cblxuLy8gVE9ETyhzaHR5bG1hbilcbnByb2Nlc3MuY3dkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gJy8nIH07XG5wcm9jZXNzLmNoZGlyID0gZnVuY3Rpb24gKGRpcikge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc0J1ZmZlcihhcmcpIHtcbiAgcmV0dXJuIGFyZyAmJiB0eXBlb2YgYXJnID09PSAnb2JqZWN0J1xuICAgICYmIHR5cGVvZiBhcmcuY29weSA9PT0gJ2Z1bmN0aW9uJ1xuICAgICYmIHR5cGVvZiBhcmcuZmlsbCA9PT0gJ2Z1bmN0aW9uJ1xuICAgICYmIHR5cGVvZiBhcmcucmVhZFVJbnQ4ID09PSAnZnVuY3Rpb24nO1xufSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwpe1xuLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbnZhciBmb3JtYXRSZWdFeHAgPSAvJVtzZGolXS9nO1xuZXhwb3J0cy5mb3JtYXQgPSBmdW5jdGlvbihmKSB7XG4gIGlmICghaXNTdHJpbmcoZikpIHtcbiAgICB2YXIgb2JqZWN0cyA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBvYmplY3RzLnB1c2goaW5zcGVjdChhcmd1bWVudHNbaV0pKTtcbiAgICB9XG4gICAgcmV0dXJuIG9iamVjdHMuam9pbignICcpO1xuICB9XG5cbiAgdmFyIGkgPSAxO1xuICB2YXIgYXJncyA9IGFyZ3VtZW50cztcbiAgdmFyIGxlbiA9IGFyZ3MubGVuZ3RoO1xuICB2YXIgc3RyID0gU3RyaW5nKGYpLnJlcGxhY2UoZm9ybWF0UmVnRXhwLCBmdW5jdGlvbih4KSB7XG4gICAgaWYgKHggPT09ICclJScpIHJldHVybiAnJSc7XG4gICAgaWYgKGkgPj0gbGVuKSByZXR1cm4geDtcbiAgICBzd2l0Y2ggKHgpIHtcbiAgICAgIGNhc2UgJyVzJzogcmV0dXJuIFN0cmluZyhhcmdzW2krK10pO1xuICAgICAgY2FzZSAnJWQnOiByZXR1cm4gTnVtYmVyKGFyZ3NbaSsrXSk7XG4gICAgICBjYXNlICclaic6XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGFyZ3NbaSsrXSk7XG4gICAgICAgIH0gY2F0Y2ggKF8pIHtcbiAgICAgICAgICByZXR1cm4gJ1tDaXJjdWxhcl0nO1xuICAgICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4geDtcbiAgICB9XG4gIH0pO1xuICBmb3IgKHZhciB4ID0gYXJnc1tpXTsgaSA8IGxlbjsgeCA9IGFyZ3NbKytpXSkge1xuICAgIGlmIChpc051bGwoeCkgfHwgIWlzT2JqZWN0KHgpKSB7XG4gICAgICBzdHIgKz0gJyAnICsgeDtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RyICs9ICcgJyArIGluc3BlY3QoeCk7XG4gICAgfVxuICB9XG4gIHJldHVybiBzdHI7XG59O1xuXG5cbi8vIE1hcmsgdGhhdCBhIG1ldGhvZCBzaG91bGQgbm90IGJlIHVzZWQuXG4vLyBSZXR1cm5zIGEgbW9kaWZpZWQgZnVuY3Rpb24gd2hpY2ggd2FybnMgb25jZSBieSBkZWZhdWx0LlxuLy8gSWYgLS1uby1kZXByZWNhdGlvbiBpcyBzZXQsIHRoZW4gaXQgaXMgYSBuby1vcC5cbmV4cG9ydHMuZGVwcmVjYXRlID0gZnVuY3Rpb24oZm4sIG1zZykge1xuICAvLyBBbGxvdyBmb3IgZGVwcmVjYXRpbmcgdGhpbmdzIGluIHRoZSBwcm9jZXNzIG9mIHN0YXJ0aW5nIHVwLlxuICBpZiAoaXNVbmRlZmluZWQoZ2xvYmFsLnByb2Nlc3MpKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGV4cG9ydHMuZGVwcmVjYXRlKGZuLCBtc2cpLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfTtcbiAgfVxuXG4gIGlmIChwcm9jZXNzLm5vRGVwcmVjYXRpb24gPT09IHRydWUpIHtcbiAgICByZXR1cm4gZm47XG4gIH1cblxuICB2YXIgd2FybmVkID0gZmFsc2U7XG4gIGZ1bmN0aW9uIGRlcHJlY2F0ZWQoKSB7XG4gICAgaWYgKCF3YXJuZWQpIHtcbiAgICAgIGlmIChwcm9jZXNzLnRocm93RGVwcmVjYXRpb24pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XG4gICAgICB9IGVsc2UgaWYgKHByb2Nlc3MudHJhY2VEZXByZWNhdGlvbikge1xuICAgICAgICBjb25zb2xlLnRyYWNlKG1zZyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLmVycm9yKG1zZyk7XG4gICAgICB9XG4gICAgICB3YXJuZWQgPSB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfVxuXG4gIHJldHVybiBkZXByZWNhdGVkO1xufTtcblxuXG52YXIgZGVidWdzID0ge307XG52YXIgZGVidWdFbnZpcm9uO1xuZXhwb3J0cy5kZWJ1Z2xvZyA9IGZ1bmN0aW9uKHNldCkge1xuICBpZiAoaXNVbmRlZmluZWQoZGVidWdFbnZpcm9uKSlcbiAgICBkZWJ1Z0Vudmlyb24gPSBwcm9jZXNzLmVudi5OT0RFX0RFQlVHIHx8ICcnO1xuICBzZXQgPSBzZXQudG9VcHBlckNhc2UoKTtcbiAgaWYgKCFkZWJ1Z3Nbc2V0XSkge1xuICAgIGlmIChuZXcgUmVnRXhwKCdcXFxcYicgKyBzZXQgKyAnXFxcXGInLCAnaScpLnRlc3QoZGVidWdFbnZpcm9uKSkge1xuICAgICAgdmFyIHBpZCA9IHByb2Nlc3MucGlkO1xuICAgICAgZGVidWdzW3NldF0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIG1zZyA9IGV4cG9ydHMuZm9ybWF0LmFwcGx5KGV4cG9ydHMsIGFyZ3VtZW50cyk7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJyVzICVkOiAlcycsIHNldCwgcGlkLCBtc2cpO1xuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGVidWdzW3NldF0gPSBmdW5jdGlvbigpIHt9O1xuICAgIH1cbiAgfVxuICByZXR1cm4gZGVidWdzW3NldF07XG59O1xuXG5cbi8qKlxuICogRWNob3MgdGhlIHZhbHVlIG9mIGEgdmFsdWUuIFRyeXMgdG8gcHJpbnQgdGhlIHZhbHVlIG91dFxuICogaW4gdGhlIGJlc3Qgd2F5IHBvc3NpYmxlIGdpdmVuIHRoZSBkaWZmZXJlbnQgdHlwZXMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iaiBUaGUgb2JqZWN0IHRvIHByaW50IG91dC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzIE9wdGlvbmFsIG9wdGlvbnMgb2JqZWN0IHRoYXQgYWx0ZXJzIHRoZSBvdXRwdXQuXG4gKi9cbi8qIGxlZ2FjeTogb2JqLCBzaG93SGlkZGVuLCBkZXB0aCwgY29sb3JzKi9cbmZ1bmN0aW9uIGluc3BlY3Qob2JqLCBvcHRzKSB7XG4gIC8vIGRlZmF1bHQgb3B0aW9uc1xuICB2YXIgY3R4ID0ge1xuICAgIHNlZW46IFtdLFxuICAgIHN0eWxpemU6IHN0eWxpemVOb0NvbG9yXG4gIH07XG4gIC8vIGxlZ2FjeS4uLlxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSAzKSBjdHguZGVwdGggPSBhcmd1bWVudHNbMl07XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDQpIGN0eC5jb2xvcnMgPSBhcmd1bWVudHNbM107XG4gIGlmIChpc0Jvb2xlYW4ob3B0cykpIHtcbiAgICAvLyBsZWdhY3kuLi5cbiAgICBjdHguc2hvd0hpZGRlbiA9IG9wdHM7XG4gIH0gZWxzZSBpZiAob3B0cykge1xuICAgIC8vIGdvdCBhbiBcIm9wdGlvbnNcIiBvYmplY3RcbiAgICBleHBvcnRzLl9leHRlbmQoY3R4LCBvcHRzKTtcbiAgfVxuICAvLyBzZXQgZGVmYXVsdCBvcHRpb25zXG4gIGlmIChpc1VuZGVmaW5lZChjdHguc2hvd0hpZGRlbikpIGN0eC5zaG93SGlkZGVuID0gZmFsc2U7XG4gIGlmIChpc1VuZGVmaW5lZChjdHguZGVwdGgpKSBjdHguZGVwdGggPSAyO1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LmNvbG9ycykpIGN0eC5jb2xvcnMgPSBmYWxzZTtcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5jdXN0b21JbnNwZWN0KSkgY3R4LmN1c3RvbUluc3BlY3QgPSB0cnVlO1xuICBpZiAoY3R4LmNvbG9ycykgY3R4LnN0eWxpemUgPSBzdHlsaXplV2l0aENvbG9yO1xuICByZXR1cm4gZm9ybWF0VmFsdWUoY3R4LCBvYmosIGN0eC5kZXB0aCk7XG59XG5leHBvcnRzLmluc3BlY3QgPSBpbnNwZWN0O1xuXG5cbi8vIGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQU5TSV9lc2NhcGVfY29kZSNncmFwaGljc1xuaW5zcGVjdC5jb2xvcnMgPSB7XG4gICdib2xkJyA6IFsxLCAyMl0sXG4gICdpdGFsaWMnIDogWzMsIDIzXSxcbiAgJ3VuZGVybGluZScgOiBbNCwgMjRdLFxuICAnaW52ZXJzZScgOiBbNywgMjddLFxuICAnd2hpdGUnIDogWzM3LCAzOV0sXG4gICdncmV5JyA6IFs5MCwgMzldLFxuICAnYmxhY2snIDogWzMwLCAzOV0sXG4gICdibHVlJyA6IFszNCwgMzldLFxuICAnY3lhbicgOiBbMzYsIDM5XSxcbiAgJ2dyZWVuJyA6IFszMiwgMzldLFxuICAnbWFnZW50YScgOiBbMzUsIDM5XSxcbiAgJ3JlZCcgOiBbMzEsIDM5XSxcbiAgJ3llbGxvdycgOiBbMzMsIDM5XVxufTtcblxuLy8gRG9uJ3QgdXNlICdibHVlJyBub3QgdmlzaWJsZSBvbiBjbWQuZXhlXG5pbnNwZWN0LnN0eWxlcyA9IHtcbiAgJ3NwZWNpYWwnOiAnY3lhbicsXG4gICdudW1iZXInOiAneWVsbG93JyxcbiAgJ2Jvb2xlYW4nOiAneWVsbG93JyxcbiAgJ3VuZGVmaW5lZCc6ICdncmV5JyxcbiAgJ251bGwnOiAnYm9sZCcsXG4gICdzdHJpbmcnOiAnZ3JlZW4nLFxuICAnZGF0ZSc6ICdtYWdlbnRhJyxcbiAgLy8gXCJuYW1lXCI6IGludGVudGlvbmFsbHkgbm90IHN0eWxpbmdcbiAgJ3JlZ2V4cCc6ICdyZWQnXG59O1xuXG5cbmZ1bmN0aW9uIHN0eWxpemVXaXRoQ29sb3Ioc3RyLCBzdHlsZVR5cGUpIHtcbiAgdmFyIHN0eWxlID0gaW5zcGVjdC5zdHlsZXNbc3R5bGVUeXBlXTtcblxuICBpZiAoc3R5bGUpIHtcbiAgICByZXR1cm4gJ1xcdTAwMWJbJyArIGluc3BlY3QuY29sb3JzW3N0eWxlXVswXSArICdtJyArIHN0ciArXG4gICAgICAgICAgICdcXHUwMDFiWycgKyBpbnNwZWN0LmNvbG9yc1tzdHlsZV1bMV0gKyAnbSc7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHN0cjtcbiAgfVxufVxuXG5cbmZ1bmN0aW9uIHN0eWxpemVOb0NvbG9yKHN0ciwgc3R5bGVUeXBlKSB7XG4gIHJldHVybiBzdHI7XG59XG5cblxuZnVuY3Rpb24gYXJyYXlUb0hhc2goYXJyYXkpIHtcbiAgdmFyIGhhc2ggPSB7fTtcblxuICBhcnJheS5mb3JFYWNoKGZ1bmN0aW9uKHZhbCwgaWR4KSB7XG4gICAgaGFzaFt2YWxdID0gdHJ1ZTtcbiAgfSk7XG5cbiAgcmV0dXJuIGhhc2g7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0VmFsdWUoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzKSB7XG4gIC8vIFByb3ZpZGUgYSBob29rIGZvciB1c2VyLXNwZWNpZmllZCBpbnNwZWN0IGZ1bmN0aW9ucy5cbiAgLy8gQ2hlY2sgdGhhdCB2YWx1ZSBpcyBhbiBvYmplY3Qgd2l0aCBhbiBpbnNwZWN0IGZ1bmN0aW9uIG9uIGl0XG4gIGlmIChjdHguY3VzdG9tSW5zcGVjdCAmJlxuICAgICAgdmFsdWUgJiZcbiAgICAgIGlzRnVuY3Rpb24odmFsdWUuaW5zcGVjdCkgJiZcbiAgICAgIC8vIEZpbHRlciBvdXQgdGhlIHV0aWwgbW9kdWxlLCBpdCdzIGluc3BlY3QgZnVuY3Rpb24gaXMgc3BlY2lhbFxuICAgICAgdmFsdWUuaW5zcGVjdCAhPT0gZXhwb3J0cy5pbnNwZWN0ICYmXG4gICAgICAvLyBBbHNvIGZpbHRlciBvdXQgYW55IHByb3RvdHlwZSBvYmplY3RzIHVzaW5nIHRoZSBjaXJjdWxhciBjaGVjay5cbiAgICAgICEodmFsdWUuY29uc3RydWN0b3IgJiYgdmFsdWUuY29uc3RydWN0b3IucHJvdG90eXBlID09PSB2YWx1ZSkpIHtcbiAgICB2YXIgcmV0ID0gdmFsdWUuaW5zcGVjdChyZWN1cnNlVGltZXMsIGN0eCk7XG4gICAgaWYgKCFpc1N0cmluZyhyZXQpKSB7XG4gICAgICByZXQgPSBmb3JtYXRWYWx1ZShjdHgsIHJldCwgcmVjdXJzZVRpbWVzKTtcbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbiAgfVxuXG4gIC8vIFByaW1pdGl2ZSB0eXBlcyBjYW5ub3QgaGF2ZSBwcm9wZXJ0aWVzXG4gIHZhciBwcmltaXRpdmUgPSBmb3JtYXRQcmltaXRpdmUoY3R4LCB2YWx1ZSk7XG4gIGlmIChwcmltaXRpdmUpIHtcbiAgICByZXR1cm4gcHJpbWl0aXZlO1xuICB9XG5cbiAgLy8gTG9vayB1cCB0aGUga2V5cyBvZiB0aGUgb2JqZWN0LlxuICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKHZhbHVlKTtcbiAgdmFyIHZpc2libGVLZXlzID0gYXJyYXlUb0hhc2goa2V5cyk7XG5cbiAgaWYgKGN0eC5zaG93SGlkZGVuKSB7XG4gICAga2V5cyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHZhbHVlKTtcbiAgfVxuXG4gIC8vIElFIGRvZXNuJ3QgbWFrZSBlcnJvciBmaWVsZHMgbm9uLWVudW1lcmFibGVcbiAgLy8gaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L2llL2R3dzUyc2J0KHY9dnMuOTQpLmFzcHhcbiAgaWYgKGlzRXJyb3IodmFsdWUpXG4gICAgICAmJiAoa2V5cy5pbmRleE9mKCdtZXNzYWdlJykgPj0gMCB8fCBrZXlzLmluZGV4T2YoJ2Rlc2NyaXB0aW9uJykgPj0gMCkpIHtcbiAgICByZXR1cm4gZm9ybWF0RXJyb3IodmFsdWUpO1xuICB9XG5cbiAgLy8gU29tZSB0eXBlIG9mIG9iamVjdCB3aXRob3V0IHByb3BlcnRpZXMgY2FuIGJlIHNob3J0Y3V0dGVkLlxuICBpZiAoa2V5cy5sZW5ndGggPT09IDApIHtcbiAgICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHtcbiAgICAgIHZhciBuYW1lID0gdmFsdWUubmFtZSA/ICc6ICcgKyB2YWx1ZS5uYW1lIDogJyc7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoJ1tGdW5jdGlvbicgKyBuYW1lICsgJ10nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSwgJ3JlZ2V4cCcpO1xuICAgIH1cbiAgICBpZiAoaXNEYXRlKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKERhdGUucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAnZGF0ZScpO1xuICAgIH1cbiAgICBpZiAoaXNFcnJvcih2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBmb3JtYXRFcnJvcih2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIGJhc2UgPSAnJywgYXJyYXkgPSBmYWxzZSwgYnJhY2VzID0gWyd7JywgJ30nXTtcblxuICAvLyBNYWtlIEFycmF5IHNheSB0aGF0IHRoZXkgYXJlIEFycmF5XG4gIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgIGFycmF5ID0gdHJ1ZTtcbiAgICBicmFjZXMgPSBbJ1snLCAnXSddO1xuICB9XG5cbiAgLy8gTWFrZSBmdW5jdGlvbnMgc2F5IHRoYXQgdGhleSBhcmUgZnVuY3Rpb25zXG4gIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgIHZhciBuID0gdmFsdWUubmFtZSA/ICc6ICcgKyB2YWx1ZS5uYW1lIDogJyc7XG4gICAgYmFzZSA9ICcgW0Z1bmN0aW9uJyArIG4gKyAnXSc7XG4gIH1cblxuICAvLyBNYWtlIFJlZ0V4cHMgc2F5IHRoYXQgdGhleSBhcmUgUmVnRXhwc1xuICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgYmFzZSA9ICcgJyArIFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSk7XG4gIH1cblxuICAvLyBNYWtlIGRhdGVzIHdpdGggcHJvcGVydGllcyBmaXJzdCBzYXkgdGhlIGRhdGVcbiAgaWYgKGlzRGF0ZSh2YWx1ZSkpIHtcbiAgICBiYXNlID0gJyAnICsgRGF0ZS5wcm90b3R5cGUudG9VVENTdHJpbmcuY2FsbCh2YWx1ZSk7XG4gIH1cblxuICAvLyBNYWtlIGVycm9yIHdpdGggbWVzc2FnZSBmaXJzdCBzYXkgdGhlIGVycm9yXG4gIGlmIChpc0Vycm9yKHZhbHVlKSkge1xuICAgIGJhc2UgPSAnICcgKyBmb3JtYXRFcnJvcih2YWx1ZSk7XG4gIH1cblxuICBpZiAoa2V5cy5sZW5ndGggPT09IDAgJiYgKCFhcnJheSB8fCB2YWx1ZS5sZW5ndGggPT0gMCkpIHtcbiAgICByZXR1cm4gYnJhY2VzWzBdICsgYmFzZSArIGJyYWNlc1sxXTtcbiAgfVxuXG4gIGlmIChyZWN1cnNlVGltZXMgPCAwKSB7XG4gICAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdyZWdleHAnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKCdbT2JqZWN0XScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9XG5cbiAgY3R4LnNlZW4ucHVzaCh2YWx1ZSk7XG5cbiAgdmFyIG91dHB1dDtcbiAgaWYgKGFycmF5KSB7XG4gICAgb3V0cHV0ID0gZm9ybWF0QXJyYXkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5cyk7XG4gIH0gZWxzZSB7XG4gICAgb3V0cHV0ID0ga2V5cy5tYXAoZnVuY3Rpb24oa2V5KSB7XG4gICAgICByZXR1cm4gZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5LCBhcnJheSk7XG4gICAgfSk7XG4gIH1cblxuICBjdHguc2Vlbi5wb3AoKTtcblxuICByZXR1cm4gcmVkdWNlVG9TaW5nbGVTdHJpbmcob3V0cHV0LCBiYXNlLCBicmFjZXMpO1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdFByaW1pdGl2ZShjdHgsIHZhbHVlKSB7XG4gIGlmIChpc1VuZGVmaW5lZCh2YWx1ZSkpXG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKCd1bmRlZmluZWQnLCAndW5kZWZpbmVkJyk7XG4gIGlmIChpc1N0cmluZyh2YWx1ZSkpIHtcbiAgICB2YXIgc2ltcGxlID0gJ1xcJycgKyBKU09OLnN0cmluZ2lmeSh2YWx1ZSkucmVwbGFjZSgvXlwifFwiJC9nLCAnJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8nL2csIFwiXFxcXCdcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXFxcXCIvZywgJ1wiJykgKyAnXFwnJztcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoc2ltcGxlLCAnc3RyaW5nJyk7XG4gIH1cbiAgaWYgKGlzTnVtYmVyKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJycgKyB2YWx1ZSwgJ251bWJlcicpO1xuICBpZiAoaXNCb29sZWFuKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJycgKyB2YWx1ZSwgJ2Jvb2xlYW4nKTtcbiAgLy8gRm9yIHNvbWUgcmVhc29uIHR5cGVvZiBudWxsIGlzIFwib2JqZWN0XCIsIHNvIHNwZWNpYWwgY2FzZSBoZXJlLlxuICBpZiAoaXNOdWxsKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJ251bGwnLCAnbnVsbCcpO1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdEVycm9yKHZhbHVlKSB7XG4gIHJldHVybiAnWycgKyBFcnJvci5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSkgKyAnXSc7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0QXJyYXkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5cykge1xuICB2YXIgb3V0cHV0ID0gW107XG4gIGZvciAodmFyIGkgPSAwLCBsID0gdmFsdWUubGVuZ3RoOyBpIDwgbDsgKytpKSB7XG4gICAgaWYgKGhhc093blByb3BlcnR5KHZhbHVlLCBTdHJpbmcoaSkpKSB7XG4gICAgICBvdXRwdXQucHVzaChmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLFxuICAgICAgICAgIFN0cmluZyhpKSwgdHJ1ZSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBvdXRwdXQucHVzaCgnJyk7XG4gICAgfVxuICB9XG4gIGtleXMuZm9yRWFjaChmdW5jdGlvbihrZXkpIHtcbiAgICBpZiAoIWtleS5tYXRjaCgvXlxcZCskLykpIHtcbiAgICAgIG91dHB1dC5wdXNoKGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsXG4gICAgICAgICAga2V5LCB0cnVlKSk7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIG91dHB1dDtcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXksIGFycmF5KSB7XG4gIHZhciBuYW1lLCBzdHIsIGRlc2M7XG4gIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHZhbHVlLCBrZXkpIHx8IHsgdmFsdWU6IHZhbHVlW2tleV0gfTtcbiAgaWYgKGRlc2MuZ2V0KSB7XG4gICAgaWYgKGRlc2Muc2V0KSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW0dldHRlci9TZXR0ZXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tHZXR0ZXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGRlc2Muc2V0KSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW1NldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuICBpZiAoIWhhc093blByb3BlcnR5KHZpc2libGVLZXlzLCBrZXkpKSB7XG4gICAgbmFtZSA9ICdbJyArIGtleSArICddJztcbiAgfVxuICBpZiAoIXN0cikge1xuICAgIGlmIChjdHguc2Vlbi5pbmRleE9mKGRlc2MudmFsdWUpIDwgMCkge1xuICAgICAgaWYgKGlzTnVsbChyZWN1cnNlVGltZXMpKSB7XG4gICAgICAgIHN0ciA9IGZvcm1hdFZhbHVlKGN0eCwgZGVzYy52YWx1ZSwgbnVsbCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdHIgPSBmb3JtYXRWYWx1ZShjdHgsIGRlc2MudmFsdWUsIHJlY3Vyc2VUaW1lcyAtIDEpO1xuICAgICAgfVxuICAgICAgaWYgKHN0ci5pbmRleE9mKCdcXG4nKSA+IC0xKSB7XG4gICAgICAgIGlmIChhcnJheSkge1xuICAgICAgICAgIHN0ciA9IHN0ci5zcGxpdCgnXFxuJykubWFwKGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgICAgIHJldHVybiAnICAnICsgbGluZTtcbiAgICAgICAgICB9KS5qb2luKCdcXG4nKS5zdWJzdHIoMik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3RyID0gJ1xcbicgKyBzdHIuc3BsaXQoJ1xcbicpLm1hcChmdW5jdGlvbihsaW5lKSB7XG4gICAgICAgICAgICByZXR1cm4gJyAgICcgKyBsaW5lO1xuICAgICAgICAgIH0pLmpvaW4oJ1xcbicpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbQ2lyY3VsYXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH1cbiAgaWYgKGlzVW5kZWZpbmVkKG5hbWUpKSB7XG4gICAgaWYgKGFycmF5ICYmIGtleS5tYXRjaCgvXlxcZCskLykpIHtcbiAgICAgIHJldHVybiBzdHI7XG4gICAgfVxuICAgIG5hbWUgPSBKU09OLnN0cmluZ2lmeSgnJyArIGtleSk7XG4gICAgaWYgKG5hbWUubWF0Y2goL15cIihbYS16QS1aX11bYS16QS1aXzAtOV0qKVwiJC8pKSB7XG4gICAgICBuYW1lID0gbmFtZS5zdWJzdHIoMSwgbmFtZS5sZW5ndGggLSAyKTtcbiAgICAgIG5hbWUgPSBjdHguc3R5bGl6ZShuYW1lLCAnbmFtZScpO1xuICAgIH0gZWxzZSB7XG4gICAgICBuYW1lID0gbmFtZS5yZXBsYWNlKC8nL2csIFwiXFxcXCdcIilcbiAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xcXFxcIi9nLCAnXCInKVxuICAgICAgICAgICAgICAgICAucmVwbGFjZSgvKF5cInxcIiQpL2csIFwiJ1wiKTtcbiAgICAgIG5hbWUgPSBjdHguc3R5bGl6ZShuYW1lLCAnc3RyaW5nJyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5hbWUgKyAnOiAnICsgc3RyO1xufVxuXG5cbmZ1bmN0aW9uIHJlZHVjZVRvU2luZ2xlU3RyaW5nKG91dHB1dCwgYmFzZSwgYnJhY2VzKSB7XG4gIHZhciBudW1MaW5lc0VzdCA9IDA7XG4gIHZhciBsZW5ndGggPSBvdXRwdXQucmVkdWNlKGZ1bmN0aW9uKHByZXYsIGN1cikge1xuICAgIG51bUxpbmVzRXN0Kys7XG4gICAgaWYgKGN1ci5pbmRleE9mKCdcXG4nKSA+PSAwKSBudW1MaW5lc0VzdCsrO1xuICAgIHJldHVybiBwcmV2ICsgY3VyLnJlcGxhY2UoL1xcdTAwMWJcXFtcXGRcXGQ/bS9nLCAnJykubGVuZ3RoICsgMTtcbiAgfSwgMCk7XG5cbiAgaWYgKGxlbmd0aCA+IDYwKSB7XG4gICAgcmV0dXJuIGJyYWNlc1swXSArXG4gICAgICAgICAgIChiYXNlID09PSAnJyA/ICcnIDogYmFzZSArICdcXG4gJykgK1xuICAgICAgICAgICAnICcgK1xuICAgICAgICAgICBvdXRwdXQuam9pbignLFxcbiAgJykgK1xuICAgICAgICAgICAnICcgK1xuICAgICAgICAgICBicmFjZXNbMV07XG4gIH1cblxuICByZXR1cm4gYnJhY2VzWzBdICsgYmFzZSArICcgJyArIG91dHB1dC5qb2luKCcsICcpICsgJyAnICsgYnJhY2VzWzFdO1xufVxuXG5cbi8vIE5PVEU6IFRoZXNlIHR5cGUgY2hlY2tpbmcgZnVuY3Rpb25zIGludGVudGlvbmFsbHkgZG9uJ3QgdXNlIGBpbnN0YW5jZW9mYFxuLy8gYmVjYXVzZSBpdCBpcyBmcmFnaWxlIGFuZCBjYW4gYmUgZWFzaWx5IGZha2VkIHdpdGggYE9iamVjdC5jcmVhdGUoKWAuXG5mdW5jdGlvbiBpc0FycmF5KGFyKSB7XG4gIHJldHVybiBBcnJheS5pc0FycmF5KGFyKTtcbn1cbmV4cG9ydHMuaXNBcnJheSA9IGlzQXJyYXk7XG5cbmZ1bmN0aW9uIGlzQm9vbGVhbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdib29sZWFuJztcbn1cbmV4cG9ydHMuaXNCb29sZWFuID0gaXNCb29sZWFuO1xuXG5mdW5jdGlvbiBpc051bGwoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IG51bGw7XG59XG5leHBvcnRzLmlzTnVsbCA9IGlzTnVsbDtcblxuZnVuY3Rpb24gaXNOdWxsT3JVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsT3JVbmRlZmluZWQgPSBpc051bGxPclVuZGVmaW5lZDtcblxuZnVuY3Rpb24gaXNOdW1iZXIoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnbnVtYmVyJztcbn1cbmV4cG9ydHMuaXNOdW1iZXIgPSBpc051bWJlcjtcblxuZnVuY3Rpb24gaXNTdHJpbmcoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnc3RyaW5nJztcbn1cbmV4cG9ydHMuaXNTdHJpbmcgPSBpc1N0cmluZztcblxuZnVuY3Rpb24gaXNTeW1ib2woYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnc3ltYm9sJztcbn1cbmV4cG9ydHMuaXNTeW1ib2wgPSBpc1N5bWJvbDtcblxuZnVuY3Rpb24gaXNVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IHZvaWQgMDtcbn1cbmV4cG9ydHMuaXNVbmRlZmluZWQgPSBpc1VuZGVmaW5lZDtcblxuZnVuY3Rpb24gaXNSZWdFeHAocmUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KHJlKSAmJiBvYmplY3RUb1N0cmluZyhyZSkgPT09ICdbb2JqZWN0IFJlZ0V4cF0nO1xufVxuZXhwb3J0cy5pc1JlZ0V4cCA9IGlzUmVnRXhwO1xuXG5mdW5jdGlvbiBpc09iamVjdChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdvYmplY3QnICYmIGFyZyAhPT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNPYmplY3QgPSBpc09iamVjdDtcblxuZnVuY3Rpb24gaXNEYXRlKGQpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KGQpICYmIG9iamVjdFRvU3RyaW5nKGQpID09PSAnW29iamVjdCBEYXRlXSc7XG59XG5leHBvcnRzLmlzRGF0ZSA9IGlzRGF0ZTtcblxuZnVuY3Rpb24gaXNFcnJvcihlKSB7XG4gIHJldHVybiBpc09iamVjdChlKSAmJlxuICAgICAgKG9iamVjdFRvU3RyaW5nKGUpID09PSAnW29iamVjdCBFcnJvcl0nIHx8IGUgaW5zdGFuY2VvZiBFcnJvcik7XG59XG5leHBvcnRzLmlzRXJyb3IgPSBpc0Vycm9yO1xuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJztcbn1cbmV4cG9ydHMuaXNGdW5jdGlvbiA9IGlzRnVuY3Rpb247XG5cbmZ1bmN0aW9uIGlzUHJpbWl0aXZlKGFyZykge1xuICByZXR1cm4gYXJnID09PSBudWxsIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnYm9vbGVhbicgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdudW1iZXInIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnc3RyaW5nJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3N5bWJvbCcgfHwgIC8vIEVTNiBzeW1ib2xcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICd1bmRlZmluZWQnO1xufVxuZXhwb3J0cy5pc1ByaW1pdGl2ZSA9IGlzUHJpbWl0aXZlO1xuXG5leHBvcnRzLmlzQnVmZmVyID0gcmVxdWlyZSgnLi9zdXBwb3J0L2lzQnVmZmVyJyk7XG5cbmZ1bmN0aW9uIG9iamVjdFRvU3RyaW5nKG8pIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKTtcbn1cblxuXG5mdW5jdGlvbiBwYWQobikge1xuICByZXR1cm4gbiA8IDEwID8gJzAnICsgbi50b1N0cmluZygxMCkgOiBuLnRvU3RyaW5nKDEwKTtcbn1cblxuXG52YXIgbW9udGhzID0gWydKYW4nLCAnRmViJywgJ01hcicsICdBcHInLCAnTWF5JywgJ0p1bicsICdKdWwnLCAnQXVnJywgJ1NlcCcsXG4gICAgICAgICAgICAgICdPY3QnLCAnTm92JywgJ0RlYyddO1xuXG4vLyAyNiBGZWIgMTY6MTk6MzRcbmZ1bmN0aW9uIHRpbWVzdGFtcCgpIHtcbiAgdmFyIGQgPSBuZXcgRGF0ZSgpO1xuICB2YXIgdGltZSA9IFtwYWQoZC5nZXRIb3VycygpKSxcbiAgICAgICAgICAgICAgcGFkKGQuZ2V0TWludXRlcygpKSxcbiAgICAgICAgICAgICAgcGFkKGQuZ2V0U2Vjb25kcygpKV0uam9pbignOicpO1xuICByZXR1cm4gW2QuZ2V0RGF0ZSgpLCBtb250aHNbZC5nZXRNb250aCgpXSwgdGltZV0uam9pbignICcpO1xufVxuXG5cbi8vIGxvZyBpcyBqdXN0IGEgdGhpbiB3cmFwcGVyIHRvIGNvbnNvbGUubG9nIHRoYXQgcHJlcGVuZHMgYSB0aW1lc3RhbXBcbmV4cG9ydHMubG9nID0gZnVuY3Rpb24oKSB7XG4gIGNvbnNvbGUubG9nKCclcyAtICVzJywgdGltZXN0YW1wKCksIGV4cG9ydHMuZm9ybWF0LmFwcGx5KGV4cG9ydHMsIGFyZ3VtZW50cykpO1xufTtcblxuXG4vKipcbiAqIEluaGVyaXQgdGhlIHByb3RvdHlwZSBtZXRob2RzIGZyb20gb25lIGNvbnN0cnVjdG9yIGludG8gYW5vdGhlci5cbiAqXG4gKiBUaGUgRnVuY3Rpb24ucHJvdG90eXBlLmluaGVyaXRzIGZyb20gbGFuZy5qcyByZXdyaXR0ZW4gYXMgYSBzdGFuZGFsb25lXG4gKiBmdW5jdGlvbiAobm90IG9uIEZ1bmN0aW9uLnByb3RvdHlwZSkuIE5PVEU6IElmIHRoaXMgZmlsZSBpcyB0byBiZSBsb2FkZWRcbiAqIGR1cmluZyBib290c3RyYXBwaW5nIHRoaXMgZnVuY3Rpb24gbmVlZHMgdG8gYmUgcmV3cml0dGVuIHVzaW5nIHNvbWUgbmF0aXZlXG4gKiBmdW5jdGlvbnMgYXMgcHJvdG90eXBlIHNldHVwIHVzaW5nIG5vcm1hbCBKYXZhU2NyaXB0IGRvZXMgbm90IHdvcmsgYXNcbiAqIGV4cGVjdGVkIGR1cmluZyBib290c3RyYXBwaW5nIChzZWUgbWlycm9yLmpzIGluIHIxMTQ5MDMpLlxuICpcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IGN0b3IgQ29uc3RydWN0b3IgZnVuY3Rpb24gd2hpY2ggbmVlZHMgdG8gaW5oZXJpdCB0aGVcbiAqICAgICBwcm90b3R5cGUuXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBzdXBlckN0b3IgQ29uc3RydWN0b3IgZnVuY3Rpb24gdG8gaW5oZXJpdCBwcm90b3R5cGUgZnJvbS5cbiAqL1xuZXhwb3J0cy5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbmV4cG9ydHMuX2V4dGVuZCA9IGZ1bmN0aW9uKG9yaWdpbiwgYWRkKSB7XG4gIC8vIERvbid0IGRvIGFueXRoaW5nIGlmIGFkZCBpc24ndCBhbiBvYmplY3RcbiAgaWYgKCFhZGQgfHwgIWlzT2JqZWN0KGFkZCkpIHJldHVybiBvcmlnaW47XG5cbiAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhhZGQpO1xuICB2YXIgaSA9IGtleXMubGVuZ3RoO1xuICB3aGlsZSAoaS0tKSB7XG4gICAgb3JpZ2luW2tleXNbaV1dID0gYWRkW2tleXNbaV1dO1xuICB9XG4gIHJldHVybiBvcmlnaW47XG59O1xuXG5mdW5jdGlvbiBoYXNPd25Qcm9wZXJ0eShvYmosIHByb3ApIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApO1xufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZSgnX3Byb2Nlc3MnKSx0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDogdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9KSIsIi8vanNoaW50IG5vZGU6IHRydWVcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSB7XHJcbiAgICBhZGRDb2xvclN0b3A6IHJlcXVpcmUoJy4vc3JjL2FkZENvbG9yU3RvcCcpLFxyXG4gICAgYXJjOiByZXF1aXJlKCcuL3NyYy9hcmMnKSxcclxuICAgIGFyY1RvOiByZXF1aXJlKCcuL3NyYy9hcmNUbycpLFxyXG4gICAgYmVnaW5QYXRoOiByZXF1aXJlKCcuL3NyYy9iZWdpblBhdGgnKSxcclxuICAgIGJlemllckN1cnZlVG86IHJlcXVpcmUoJy4vc3JjL2JlemllckN1cnZlVG8nKSxcclxuICAgIENhbnZhczogcmVxdWlyZSgnLi9zcmMvQ2FudmFzJyksXHJcbiAgICBjbGVhclJlY3Q6IHJlcXVpcmUoJy4vc3JjL2NsZWFyUmVjdCcpLFxyXG4gICAgY2xpcDogcmVxdWlyZSgnLi9zcmMvY2xpcCcpLFxyXG4gICAgY2xpcFBhdGg6IHJlcXVpcmUoJy4vc3JjL2NsaXBQYXRoJyksXHJcbiAgICBjbG9zZVBhdGg6IHJlcXVpcmUoJy4vc3JjL2Nsb3NlUGF0aCcpLFxyXG4gICAgY3JlYXRlQ2xhc3M6IHJlcXVpcmUoJy4vc3JjL2NyZWF0ZUNsYXNzJyksXHJcbiAgICBjcmVhdGVMaW5lYXJHcmFkaWVudDogcmVxdWlyZSgnLi9zcmMvY3JlYXRlTGluZWFyR3JhZGllbnQnKSxcclxuICAgIGNyZWF0ZVJhZGlhbEdyYWRpZW50OiByZXF1aXJlKCcuL3NyYy9jcmVhdGVSYWRpYWxHcmFkaWVudCcpLFxyXG4gICAgY3JlYXRlUmVndWxhclBvbHlnb24gOiByZXF1aXJlKCcuL3NyYy9jcmVhdGVSZWd1bGFyUG9seWdvbicpLFxyXG4gICAgZHJhd0NhbnZhczogcmVxdWlyZSgnLi9zcmMvZHJhd0NhbnZhcycpLFxyXG4gICAgZHJhd0ltYWdlOiByZXF1aXJlKCcuL3NyYy9kcmF3SW1hZ2UnKSxcclxuICAgIGVsbGlwc2U6IHJlcXVpcmUoJy4vc3JjL2VsbGlwc2UnKSxcclxuICAgIGZpbGw6IHJlcXVpcmUoJy4vc3JjL2ZpbGwnKSxcclxuICAgIGZpbGxBcmM6IHJlcXVpcmUoJy4vc3JjL2ZpbGxBcmMnKSxcclxuICAgIGZpbGxDYW52YXM6IHJlcXVpcmUoJy4vc3JjL2ZpbGxDYW52YXMnKSxcclxuICAgIGZpbGxJbWFnZTogcmVxdWlyZSgnLi9zcmMvZmlsbEltYWdlJyksXHJcbiAgICBmaWxsSW1hZ2VQYXR0ZXJuOiByZXF1aXJlKCcuL3NyYy9maWxsSW1hZ2VQYXR0ZXJuJyksXHJcbiAgICBmaWxsUmVjdDogcmVxdWlyZSgnLi9zcmMvZmlsbFJlY3QnKSxcclxuICAgIGZpbGxTdHlsZTogcmVxdWlyZSgnLi9zcmMvZmlsbFN0eWxlJyksXHJcbiAgICBmaWxsVGV4dDogcmVxdWlyZSgnLi9zcmMvZmlsbFRleHQnKSxcclxuICAgIGdsb2JhbEFscGhhOiByZXF1aXJlKCcuL3NyYy9nbG9iYWxBbHBoYScpLFxyXG4gICAgZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uOiByZXF1aXJlKCcuL3NyYy9nbG9iYWxDb21wb3NpdGVPcGVyYXRpb24nKSxcclxuICAgIGhpdFJlY3Q6IHJlcXVpcmUoJy4vc3JjL2hpdFJlY3QnKSxcclxuICAgIGhpdFJlZ2lvbjogcmVxdWlyZSgnLi9zcmMvaGl0UmVnaW9uJyksXHJcbiAgICBpbWFnZVNtb290aGluZ0VuYWJsZWQ6IHJlcXVpcmUoJy4vc3JjL2ltYWdlU21vb3RoaW5nRW5hYmxlZCcpLFxyXG4gICAgSW1nOiByZXF1aXJlKCcuL3NyYy9JbWcnKSxcclxuICAgIEluc3RydWN0aW9uOiByZXF1aXJlKCcuL3NyYy9JbnN0cnVjdGlvbicpLFxyXG4gICAgbGluZVN0eWxlOiByZXF1aXJlKCcuL3NyYy9saW5lU3R5bGUnKSxcclxuICAgIGxpbmVUbzogcmVxdWlyZSgnLi9zcmMvbGluZVRvJyksXHJcbiAgICBtb3ZlVG86IHJlcXVpcmUoJy4vc3JjL21vdmVUbycpLFxyXG4gICAgbW92ZVRvTGluZVRvOiByZXF1aXJlKCcuL3NyYy9tb3ZlVG9MaW5lVG8nKSxcclxuICAgIHBhdGg6IHJlcXVpcmUoJy4vc3JjL3BhdGgnKSxcclxuICAgIHBsYWNlSG9sZGVyOiByZXF1aXJlKCcuL3NyYy9wbGFjZUhvbGRlcicpLFxyXG4gICAgcXVhZHJhdGljQ3VydmVUbzogcmVxdWlyZSgnLi9zcmMvcXVhZHJhdGljQ3VydmVUbycpLFxyXG4gICAgcmVjdDogcmVxdWlyZSgnLi9zcmMvcmVjdCcpLFxyXG4gICAgUmVuZGVyZXI6IHJlcXVpcmUoJy4vc3JjL1JlbmRlcmVyJyksXHJcbiAgICByZXNldFRyYW5zZm9ybTogcmVxdWlyZSgnLi9zcmMvcmVzZXRUcmFuc2Zvcm0nKSxcclxuICAgIHJvdGF0ZTogcmVxdWlyZSgnLi9zcmMvcm90YXRlJyksXHJcbiAgICBzY2FsZTogcmVxdWlyZSgnLi9zcmMvc2NhbGUnKSxcclxuICAgIHNldFRyYW5zZm9ybTogcmVxdWlyZSgnLi9zcmMvc2V0VHJhbnNmb3JtJyksXHJcbiAgICBzaGFkb3dTdHlsZTogcmVxdWlyZSgnLi9zcmMvc2hhZG93U3R5bGUnKSxcclxuICAgIHN0cm9rZTogcmVxdWlyZSgnLi9zcmMvc3Ryb2tlJyksXHJcbiAgICBzdHJva2VBcmM6IHJlcXVpcmUoJy4vc3JjL3N0cm9rZUFyYycpLFxyXG4gICAgc3Ryb2tlUmVjdDogcmVxdWlyZSgnLi9zcmMvc3Ryb2tlUmVjdCcpLFxyXG4gICAgc3Ryb2tlU3R5bGU6IHJlcXVpcmUoJy4vc3JjL3N0cm9rZVN0eWxlJyksXHJcbiAgICBzdHJva2VUZXh0OiByZXF1aXJlKCcuL3NyYy9zdHJva2VUZXh0JyksXHJcbiAgICB0ZXh0OiByZXF1aXJlKCcuL3NyYy90ZXh0JyksXHJcbiAgICB0ZXh0U3R5bGU6IHJlcXVpcmUoJy4vc3JjL3RleHRTdHlsZScpLFxyXG4gICAgdHJhbnNmb3JtOiByZXF1aXJlKCcuL3NyYy90cmFuc2Zvcm0nKSxcclxuICAgIHRyYW5zZm9ybVBvaW50czogcmVxdWlyZSgnLi9zcmMvdHJhbnNmb3JtUG9pbnRzJyksXHJcbiAgICB0cmFuc2xhdGU6IHJlcXVpcmUoJy4vc3JjL3RyYW5zbGF0ZScpXHJcbn07XHJcbiJdfQ==
var e2d = require('e2d');
var r = e2d.Renderer.create(400, 400);
var helloWorld = e2d.fillText('Hello World');
r.ready();
r.on('frame',
() => r.render(
e2d.clearRect(400, 400),
e2d.translate(200, 200,
helloWorld
)
)
);
;}, 0)
{
"name": "requirebin-sketch",
"version": "1.0.0",
"dependencies": {
"e2d": "3.2.1"
}
}
<!-- contents of this file will be placed inside the <body> -->
<!-- contents of this file will be placed inside the <head> -->
<link rel = "stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" type="text/css">
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment