mStream/public/js/aurora.js

4004 lines
321 KiB
JavaScript

(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.AV = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
// Generated by CoffeeScript 1.7.1
(function() {
var Asset, BufferSource, Decoder, Demuxer, EventEmitter, FileSource, HTTPSource,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
EventEmitter = require('./core/events');
HTTPSource = require('./sources/node/http');
FileSource = require('./sources/node/file');
BufferSource = require('./sources/buffer');
Demuxer = require('./demuxer');
Decoder = require('./decoder');
Asset = (function(_super) {
__extends(Asset, _super);
function Asset(source) {
this.source = source;
this._decode = __bind(this._decode, this);
this.findDecoder = __bind(this.findDecoder, this);
this.probe = __bind(this.probe, this);
this.buffered = 0;
this.duration = null;
this.format = null;
this.metadata = null;
this.active = false;
this.demuxer = null;
this.decoder = null;
this.source.once('data', this.probe);
this.source.on('error', (function(_this) {
return function(err) {
_this.emit('error', err);
return _this.stop();
};
})(this));
this.source.on('progress', (function(_this) {
return function(buffered) {
_this.buffered = buffered;
return _this.emit('buffer', _this.buffered);
};
})(this));
}
Asset.fromURL = function(url, opts) {
return new Asset(new HTTPSource(url, opts));
};
Asset.fromFile = function(file) {
return new Asset(new FileSource(file));
};
Asset.fromBuffer = function(buffer) {
return new Asset(new BufferSource(buffer));
};
Asset.prototype.start = function(decode) {
if (this.active) {
return;
}
if (decode != null) {
this.shouldDecode = decode;
}
if (this.shouldDecode == null) {
this.shouldDecode = true;
}
this.active = true;
this.source.start();
if (this.decoder && this.shouldDecode) {
return this._decode();
}
};
Asset.prototype.stop = function() {
if (!this.active) {
return;
}
this.active = false;
return this.source.pause();
};
Asset.prototype.get = function(event, callback) {
if (event !== 'format' && event !== 'duration' && event !== 'metadata') {
return;
}
if (this[event] != null) {
return callback(this[event]);
} else {
this.once(event, (function(_this) {
return function(value) {
_this.stop();
return callback(value);
};
})(this));
return this.start();
}
};
Asset.prototype.decodePacket = function() {
return this.decoder.decode();
};
Asset.prototype.decodeToBuffer = function(callback) {
var chunks, dataHandler, length;
length = 0;
chunks = [];
this.on('data', dataHandler = function(chunk) {
length += chunk.length;
return chunks.push(chunk);
});
this.once('end', function() {
var buf, chunk, offset, _i, _len;
buf = new Float32Array(length);
offset = 0;
for (_i = 0, _len = chunks.length; _i < _len; _i++) {
chunk = chunks[_i];
buf.set(chunk, offset);
offset += chunk.length;
}
this.off('data', dataHandler);
return callback(buf);
});
return this.start();
};
Asset.prototype.probe = function(chunk) {
var demuxer;
if (!this.active) {
return;
}
demuxer = Demuxer.find(chunk);
if (!demuxer) {
return this.emit('error', 'A demuxer for this container was not found.');
}
this.demuxer = new demuxer(this.source, chunk);
this.demuxer.on('format', this.findDecoder);
this.demuxer.on('duration', (function(_this) {
return function(duration) {
_this.duration = duration;
return _this.emit('duration', _this.duration);
};
})(this));
this.demuxer.on('metadata', (function(_this) {
return function(metadata) {
_this.metadata = metadata;
return _this.emit('metadata', _this.metadata);
};
})(this));
return this.demuxer.on('error', (function(_this) {
return function(err) {
_this.emit('error', err);
return _this.stop();
};
})(this));
};
Asset.prototype.findDecoder = function(format) {
var decoder, div;
this.format = format;
if (!this.active) {
return;
}
this.emit('format', this.format);
decoder = Decoder.find(this.format.formatID);
if (!decoder) {
return this.emit('error', "A decoder for " + this.format.formatID + " was not found.");
}
this.decoder = new decoder(this.demuxer, this.format);
if (this.format.floatingPoint) {
this.decoder.on('data', (function(_this) {
return function(buffer) {
return _this.emit('data', buffer);
};
})(this));
} else {
div = Math.pow(2, this.format.bitsPerChannel - 1);
this.decoder.on('data', (function(_this) {
return function(buffer) {
var buf, i, sample, _i, _len;
buf = new Float32Array(buffer.length);
for (i = _i = 0, _len = buffer.length; _i < _len; i = ++_i) {
sample = buffer[i];
buf[i] = sample / div;
}
return _this.emit('data', buf);
};
})(this));
}
this.decoder.on('error', (function(_this) {
return function(err) {
_this.emit('error', err);
return _this.stop();
};
})(this));
this.decoder.on('end', (function(_this) {
return function() {
return _this.emit('end');
};
})(this));
this.emit('decodeStart');
if (this.shouldDecode) {
return this._decode();
}
};
Asset.prototype._decode = function() {
while (this.decoder.decode() && this.active) {
continue;
}
if (this.active) {
return this.decoder.once('data', this._decode);
}
};
Asset.prototype.destroy = function() {
var _ref, _ref1, _ref2;
this.stop();
if ((_ref = this.demuxer) != null) {
_ref.off();
}
if ((_ref1 = this.decoder) != null) {
_ref1.off();
}
if ((_ref2 = this.source) != null) {
_ref2.off();
}
return this.off();
};
return Asset;
})(EventEmitter);
module.exports = Asset;
}).call(this);
},{"./core/events":8,"./decoder":11,"./demuxer":14,"./sources/buffer":31,"./sources/node/file":29,"./sources/node/http":30}],2:[function(require,module,exports){
// Generated by CoffeeScript 1.7.1
(function() {
var key, val, _ref;
_ref = require('./aurora_base');
for (key in _ref) {
val = _ref[key];
exports[key] = val;
}
require('./demuxers/caf');
require('./demuxers/m4a');
require('./demuxers/aiff');
require('./demuxers/wave');
require('./demuxers/au');
require('./decoders/lpcm');
require('./decoders/xlaw');
}).call(this);
},{"./aurora_base":3,"./decoders/lpcm":12,"./decoders/xlaw":13,"./demuxers/aiff":15,"./demuxers/au":16,"./demuxers/caf":17,"./demuxers/m4a":18,"./demuxers/wave":19}],3:[function(require,module,exports){
// Generated by CoffeeScript 1.7.1
(function() {
exports.Base = require('./core/base');
exports.Buffer = require('./core/buffer');
exports.BufferList = require('./core/bufferlist');
exports.Stream = require('./core/stream');
exports.Bitstream = require('./core/bitstream');
exports.EventEmitter = require('./core/events');
exports.UnderflowError = require('./core/underflow');
exports.HTTPSource = require('./sources/node/http');
exports.FileSource = require('./sources/node/file');
exports.BufferSource = require('./sources/buffer');
exports.Demuxer = require('./demuxer');
exports.Decoder = require('./decoder');
exports.AudioDevice = require('./device');
exports.Asset = require('./asset');
exports.Player = require('./player');
exports.Filter = require('./filter');
exports.VolumeFilter = require('./filters/volume');
exports.BalanceFilter = require('./filters/balance');
}).call(this);
},{"./asset":1,"./core/base":4,"./core/bitstream":5,"./core/buffer":6,"./core/bufferlist":7,"./core/events":8,"./core/stream":9,"./core/underflow":10,"./decoder":11,"./demuxer":14,"./device":20,"./filter":24,"./filters/balance":25,"./filters/volume":26,"./player":27,"./sources/buffer":31,"./sources/node/file":29,"./sources/node/http":30}],4:[function(require,module,exports){
// Generated by CoffeeScript 1.7.1
(function() {
var Base,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
Base = (function() {
var fnTest;
function Base() {}
fnTest = /\b_super\b/;
Base.extend = function(prop) {
var Class, fn, key, keys, _ref, _super;
Class = (function(_super) {
__extends(Class, _super);
function Class() {
return Class.__super__.constructor.apply(this, arguments);
}
return Class;
})(this);
if (typeof prop === 'function') {
keys = Object.keys(Class.prototype);
prop.call(Class, Class);
prop = {};
_ref = Class.prototype;
for (key in _ref) {
fn = _ref[key];
if (__indexOf.call(keys, key) < 0) {
prop[key] = fn;
}
}
}
_super = Class.__super__;
for (key in prop) {
fn = prop[key];
if (typeof fn === 'function' && fnTest.test(fn)) {
(function(key, fn) {
return Class.prototype[key] = function() {
var ret, tmp;
tmp = this._super;
this._super = _super[key];
ret = fn.apply(this, arguments);
this._super = tmp;
return ret;
};
})(key, fn);
} else {
Class.prototype[key] = fn;
}
}
return Class;
};
return Base;
})();
module.exports = Base;
}).call(this);
},{}],5:[function(require,module,exports){
// Generated by CoffeeScript 1.7.1
(function() {
var Bitstream;
Bitstream = (function() {
function Bitstream(stream) {
this.stream = stream;
this.bitPosition = 0;
}
Bitstream.prototype.copy = function() {
var result;
result = new Bitstream(this.stream.copy());
result.bitPosition = this.bitPosition;
return result;
};
Bitstream.prototype.offset = function() {
return 8 * this.stream.offset + this.bitPosition;
};
Bitstream.prototype.available = function(bits) {
return this.stream.available((bits + 8 - this.bitPosition) / 8);
};
Bitstream.prototype.advance = function(bits) {
var pos;
pos = this.bitPosition + bits;
this.stream.advance(pos >> 3);
return this.bitPosition = pos & 7;
};
Bitstream.prototype.rewind = function(bits) {
var pos;
pos = this.bitPosition - bits;
this.stream.rewind(Math.abs(pos >> 3));
return this.bitPosition = pos & 7;
};
Bitstream.prototype.seek = function(offset) {
var curOffset;
curOffset = this.offset();
if (offset > curOffset) {
return this.advance(offset - curOffset);
} else if (offset < curOffset) {
return this.rewind(curOffset - offset);
}
};
Bitstream.prototype.align = function() {
if (this.bitPosition !== 0) {
this.bitPosition = 0;
return this.stream.advance(1);
}
};
Bitstream.prototype.read = function(bits, signed) {
var a, a0, a1, a2, a3, a4, mBits;
if (bits === 0) {
return 0;
}
mBits = bits + this.bitPosition;
if (mBits <= 8) {
a = ((this.stream.peekUInt8() << this.bitPosition) & 0xff) >>> (8 - bits);
} else if (mBits <= 16) {
a = ((this.stream.peekUInt16() << this.bitPosition) & 0xffff) >>> (16 - bits);
} else if (mBits <= 24) {
a = ((this.stream.peekUInt24() << this.bitPosition) & 0xffffff) >>> (24 - bits);
} else if (mBits <= 32) {
a = (this.stream.peekUInt32() << this.bitPosition) >>> (32 - bits);
} else if (mBits <= 40) {
a0 = this.stream.peekUInt8(0) * 0x0100000000;
a1 = this.stream.peekUInt8(1) << 24 >>> 0;
a2 = this.stream.peekUInt8(2) << 16;
a3 = this.stream.peekUInt8(3) << 8;
a4 = this.stream.peekUInt8(4);
a = a0 + a1 + a2 + a3 + a4;
a %= Math.pow(2, 40 - this.bitPosition);
a = Math.floor(a / Math.pow(2, 40 - this.bitPosition - bits));
} else {
throw new Error("Too many bits!");
}
if (signed) {
if (mBits < 32) {
if (a >>> (bits - 1)) {
a = ((1 << bits >>> 0) - a) * -1;
}
} else {
if (a / Math.pow(2, bits - 1) | 0) {
a = (Math.pow(2, bits) - a) * -1;
}
}
}
this.advance(bits);
return a;
};
Bitstream.prototype.peek = function(bits, signed) {
var a, a0, a1, a2, a3, a4, mBits;
if (bits === 0) {
return 0;
}
mBits = bits + this.bitPosition;
if (mBits <= 8) {
a = ((this.stream.peekUInt8() << this.bitPosition) & 0xff) >>> (8 - bits);
} else if (mBits <= 16) {
a = ((this.stream.peekUInt16() << this.bitPosition) & 0xffff) >>> (16 - bits);
} else if (mBits <= 24) {
a = ((this.stream.peekUInt24() << this.bitPosition) & 0xffffff) >>> (24 - bits);
} else if (mBits <= 32) {
a = (this.stream.peekUInt32() << this.bitPosition) >>> (32 - bits);
} else if (mBits <= 40) {
a0 = this.stream.peekUInt8(0) * 0x0100000000;
a1 = this.stream.peekUInt8(1) << 24 >>> 0;
a2 = this.stream.peekUInt8(2) << 16;
a3 = this.stream.peekUInt8(3) << 8;
a4 = this.stream.peekUInt8(4);
a = a0 + a1 + a2 + a3 + a4;
a %= Math.pow(2, 40 - this.bitPosition);
a = Math.floor(a / Math.pow(2, 40 - this.bitPosition - bits));
} else {
throw new Error("Too many bits!");
}
if (signed) {
if (mBits < 32) {
if (a >>> (bits - 1)) {
a = ((1 << bits >>> 0) - a) * -1;
}
} else {
if (a / Math.pow(2, bits - 1) | 0) {
a = (Math.pow(2, bits) - a) * -1;
}
}
}
return a;
};
Bitstream.prototype.readLSB = function(bits, signed) {
var a, mBits;
if (bits === 0) {
return 0;
}
if (bits > 40) {
throw new Error("Too many bits!");
}
mBits = bits + this.bitPosition;
a = (this.stream.peekUInt8(0)) >>> this.bitPosition;
if (mBits > 8) {
a |= (this.stream.peekUInt8(1)) << (8 - this.bitPosition);
}
if (mBits > 16) {
a |= (this.stream.peekUInt8(2)) << (16 - this.bitPosition);
}
if (mBits > 24) {
a += (this.stream.peekUInt8(3)) << (24 - this.bitPosition) >>> 0;
}
if (mBits > 32) {
a += (this.stream.peekUInt8(4)) * Math.pow(2, 32 - this.bitPosition);
}
if (mBits >= 32) {
a %= Math.pow(2, bits);
} else {
a &= (1 << bits) - 1;
}
if (signed) {
if (mBits < 32) {
if (a >>> (bits - 1)) {
a = ((1 << bits >>> 0) - a) * -1;
}
} else {
if (a / Math.pow(2, bits - 1) | 0) {
a = (Math.pow(2, bits) - a) * -1;
}
}
}
this.advance(bits);
return a;
};
Bitstream.prototype.peekLSB = function(bits, signed) {
var a, mBits;
if (bits === 0) {
return 0;
}
if (bits > 40) {
throw new Error("Too many bits!");
}
mBits = bits + this.bitPosition;
a = (this.stream.peekUInt8(0)) >>> this.bitPosition;
if (mBits > 8) {
a |= (this.stream.peekUInt8(1)) << (8 - this.bitPosition);
}
if (mBits > 16) {
a |= (this.stream.peekUInt8(2)) << (16 - this.bitPosition);
}
if (mBits > 24) {
a += (this.stream.peekUInt8(3)) << (24 - this.bitPosition) >>> 0;
}
if (mBits > 32) {
a += (this.stream.peekUInt8(4)) * Math.pow(2, 32 - this.bitPosition);
}
if (mBits >= 32) {
a %= Math.pow(2, bits);
} else {
a &= (1 << bits) - 1;
}
if (signed) {
if (mBits < 32) {
if (a >>> (bits - 1)) {
a = ((1 << bits >>> 0) - a) * -1;
}
} else {
if (a / Math.pow(2, bits - 1) | 0) {
a = (Math.pow(2, bits) - a) * -1;
}
}
}
return a;
};
return Bitstream;
})();
module.exports = Bitstream;
}).call(this);
},{}],6:[function(require,module,exports){
(function (global){
// Generated by CoffeeScript 1.7.1
(function() {
var AVBuffer;
AVBuffer = (function() {
var BlobBuilder, URL;
function AVBuffer(input) {
var _ref;
if (input instanceof Uint8Array) {
this.data = input;
} else if (input instanceof ArrayBuffer || Array.isArray(input) || typeof input === 'number' || ((_ref = global.Buffer) != null ? _ref.isBuffer(input) : void 0)) {
this.data = new Uint8Array(input);
} else if (input.buffer instanceof ArrayBuffer) {
this.data = new Uint8Array(input.buffer, input.byteOffset, input.length * input.BYTES_PER_ELEMENT);
} else if (input instanceof AVBuffer) {
this.data = input.data;
} else {
throw new Error("Constructing buffer with unknown type.");
}
this.length = this.data.length;
this.next = null;
this.prev = null;
}
AVBuffer.allocate = function(size) {
return new AVBuffer(size);
};
AVBuffer.prototype.copy = function() {
return new AVBuffer(new Uint8Array(this.data));
};
AVBuffer.prototype.slice = function(position, length) {
if (length == null) {
length = this.length;
}
if (position === 0 && length >= this.length) {
return new AVBuffer(this.data);
} else {
return new AVBuffer(this.data.subarray(position, position + length));
}
};
BlobBuilder = global.BlobBuilder || global.MozBlobBuilder || global.WebKitBlobBuilder;
URL = global.URL || global.webkitURL || global.mozURL;
AVBuffer.makeBlob = function(data, type) {
var bb;
if (type == null) {
type = 'application/octet-stream';
}
try {
return new Blob([data], {
type: type
});
} catch (_error) {}
if (BlobBuilder != null) {
bb = new BlobBuilder;
bb.append(data);
return bb.getBlob(type);
}
return null;
};
AVBuffer.makeBlobURL = function(data, type) {
return URL != null ? URL.createObjectURL(this.makeBlob(data, type)) : void 0;
};
AVBuffer.revokeBlobURL = function(url) {
return URL != null ? URL.revokeObjectURL(url) : void 0;
};
AVBuffer.prototype.toBlob = function() {
return AVBuffer.makeBlob(this.data.buffer);
};
AVBuffer.prototype.toBlobURL = function() {
return AVBuffer.makeBlobURL(this.data.buffer);
};
return AVBuffer;
})();
module.exports = AVBuffer;
}).call(this);
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],7:[function(require,module,exports){
// Generated by CoffeeScript 1.7.1
(function() {
var BufferList;
BufferList = (function() {
function BufferList() {
this.first = null;
this.last = null;
this.numBuffers = 0;
this.availableBytes = 0;
this.availableBuffers = 0;
}
BufferList.prototype.copy = function() {
var result;
result = new BufferList;
result.first = this.first;
result.last = this.last;
result.numBuffers = this.numBuffers;
result.availableBytes = this.availableBytes;
result.availableBuffers = this.availableBuffers;
return result;
};
BufferList.prototype.append = function(buffer) {
var _ref;
buffer.prev = this.last;
if ((_ref = this.last) != null) {
_ref.next = buffer;
}
this.last = buffer;
if (this.first == null) {
this.first = buffer;
}
this.availableBytes += buffer.length;
this.availableBuffers++;
return this.numBuffers++;
};
BufferList.prototype.advance = function() {
if (this.first) {
this.availableBytes -= this.first.length;
this.availableBuffers--;
this.first = this.first.next;
return this.first != null;
}
return false;
};
BufferList.prototype.rewind = function() {
var _ref;
if (this.first && !this.first.prev) {
return false;
}
this.first = ((_ref = this.first) != null ? _ref.prev : void 0) || this.last;
if (this.first) {
this.availableBytes += this.first.length;
this.availableBuffers++;
}
return this.first != null;
};
BufferList.prototype.reset = function() {
var _results;
_results = [];
while (this.rewind()) {
continue;
}
return _results;
};
return BufferList;
})();
module.exports = BufferList;
}).call(this);
},{}],8:[function(require,module,exports){
// Generated by CoffeeScript 1.7.1
(function() {
var Base, EventEmitter,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
__slice = [].slice;
Base = require('./base');
EventEmitter = (function(_super) {
__extends(EventEmitter, _super);
function EventEmitter() {
return EventEmitter.__super__.constructor.apply(this, arguments);
}
EventEmitter.prototype.on = function(event, fn) {
var _base;
if (this.events == null) {
this.events = {};
}
if ((_base = this.events)[event] == null) {
_base[event] = [];
}
return this.events[event].push(fn);
};
EventEmitter.prototype.off = function(event, fn) {
var events, index, _ref;
if (this.events == null) {
return;
}
if ((_ref = this.events) != null ? _ref[event] : void 0) {
if (fn != null) {
index = this.events[event].indexOf(fn);
if (~index) {
return this.events[event].splice(index, 1);
}
} else {
return this.events[event];
}
} else if (event == null) {
return events = {};
}
};
EventEmitter.prototype.once = function(event, fn) {
var cb;
return this.on(event, cb = function() {
this.off(event, cb);
return fn.apply(this, arguments);
});
};
EventEmitter.prototype.emit = function() {
var args, event, fn, _i, _len, _ref, _ref1;
event = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
if (!((_ref = this.events) != null ? _ref[event] : void 0)) {
return;
}
_ref1 = this.events[event].slice();
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
fn = _ref1[_i];
fn.apply(this, args);
}
};
return EventEmitter;
})(Base);
module.exports = EventEmitter;
}).call(this);
},{"./base":4}],9:[function(require,module,exports){
// Generated by CoffeeScript 1.7.1
(function() {
var AVBuffer, BufferList, Stream, UnderflowError;
BufferList = require('./bufferlist');
AVBuffer = require('./buffer');
UnderflowError = require('./underflow');
Stream = (function() {
var buf, decodeString, float32, float64, float64Fallback, float80, int16, int32, int8, nativeEndian, uint16, uint32, uint8;
buf = new ArrayBuffer(16);
uint8 = new Uint8Array(buf);
int8 = new Int8Array(buf);
uint16 = new Uint16Array(buf);
int16 = new Int16Array(buf);
uint32 = new Uint32Array(buf);
int32 = new Int32Array(buf);
float32 = new Float32Array(buf);
if (typeof Float64Array !== "undefined" && Float64Array !== null) {
float64 = new Float64Array(buf);
}
nativeEndian = new Uint16Array(new Uint8Array([0x12, 0x34]).buffer)[0] === 0x3412;
function Stream(list) {
this.list = list;
this.localOffset = 0;
this.offset = 0;
}
Stream.fromBuffer = function(buffer) {
var list;
list = new BufferList;
list.append(buffer);
return new Stream(list);
};
Stream.prototype.copy = function() {
var result;
result = new Stream(this.list.copy());
result.localOffset = this.localOffset;
result.offset = this.offset;
return result;
};
Stream.prototype.available = function(bytes) {
return bytes <= this.list.availableBytes - this.localOffset;
};
Stream.prototype.remainingBytes = function() {
return this.list.availableBytes - this.localOffset;
};
Stream.prototype.advance = function(bytes) {
if (!this.available(bytes)) {
throw new UnderflowError();
}
this.localOffset += bytes;
this.offset += bytes;
while (this.list.first && this.localOffset >= this.list.first.length) {
this.localOffset -= this.list.first.length;
this.list.advance();
}
return this;
};
Stream.prototype.rewind = function(bytes) {
if (bytes > this.offset) {
throw new UnderflowError();
}
if (!this.list.first) {
this.list.rewind();
this.localOffset = this.list.first.length;
}
this.localOffset -= bytes;
this.offset -= bytes;
while (this.list.first.prev && this.localOffset < 0) {
this.list.rewind();
this.localOffset += this.list.first.length;
}
return this;
};
Stream.prototype.seek = function(position) {
if (position > this.offset) {
return this.advance(position - this.offset);
} else if (position < this.offset) {
return this.rewind(this.offset - position);
}
};
Stream.prototype.readUInt8 = function() {
var a;
if (!this.available(1)) {
throw new UnderflowError();
}
a = this.list.first.data[this.localOffset];
this.localOffset += 1;
this.offset += 1;
if (this.localOffset === this.list.first.length) {
this.localOffset = 0;
this.list.advance();
}
return a;
};
Stream.prototype.peekUInt8 = function(offset) {
var buffer;
if (offset == null) {
offset = 0;
}
if (!this.available(offset + 1)) {
throw new UnderflowError();
}
offset = this.localOffset + offset;
buffer = this.list.first;
while (buffer) {
if (buffer.length > offset) {
return buffer.data[offset];
}
offset -= buffer.length;
buffer = buffer.next;
}
return 0;
};
Stream.prototype.read = function(bytes, littleEndian) {
var i, _i, _j, _ref;
if (littleEndian == null) {
littleEndian = false;
}
if (littleEndian === nativeEndian) {
for (i = _i = 0; _i < bytes; i = _i += 1) {
uint8[i] = this.readUInt8();
}
} else {
for (i = _j = _ref = bytes - 1; _j >= 0; i = _j += -1) {
uint8[i] = this.readUInt8();
}
}
};
Stream.prototype.peek = function(bytes, offset, littleEndian) {
var i, _i, _j;
if (littleEndian == null) {
littleEndian = false;
}
if (littleEndian === nativeEndian) {
for (i = _i = 0; _i < bytes; i = _i += 1) {
uint8[i] = this.peekUInt8(offset + i);
}
} else {
for (i = _j = 0; _j < bytes; i = _j += 1) {
uint8[bytes - i - 1] = this.peekUInt8(offset + i);
}
}
};
Stream.prototype.readInt8 = function() {
this.read(1);
return int8[0];
};
Stream.prototype.peekInt8 = function(offset) {
if (offset == null) {
offset = 0;
}
this.peek(1, offset);
return int8[0];
};
Stream.prototype.readUInt16 = function(littleEndian) {
this.read(2, littleEndian);
return uint16[0];
};
Stream.prototype.peekUInt16 = function(offset, littleEndian) {
if (offset == null) {
offset = 0;
}
this.peek(2, offset, littleEndian);
return uint16[0];
};
Stream.prototype.readInt16 = function(littleEndian) {
this.read(2, littleEndian);
return int16[0];
};
Stream.prototype.peekInt16 = function(offset, littleEndian) {
if (offset == null) {
offset = 0;
}
this.peek(2, offset, littleEndian);
return int16[0];
};
Stream.prototype.readUInt24 = function(littleEndian) {
if (littleEndian) {
return this.readUInt16(true) + (this.readUInt8() << 16);
} else {
return (this.readUInt16() << 8) + this.readUInt8();
}
};
Stream.prototype.peekUInt24 = function(offset, littleEndian) {
if (offset == null) {
offset = 0;
}
if (littleEndian) {
return this.peekUInt16(offset, true) + (this.peekUInt8(offset + 2) << 16);
} else {
return (this.peekUInt16(offset) << 8) + this.peekUInt8(offset + 2);
}
};
Stream.prototype.readInt24 = function(littleEndian) {
if (littleEndian) {
return this.readUInt16(true) + (this.readInt8() << 16);
} else {
return (this.readInt16() << 8) + this.readUInt8();
}
};
Stream.prototype.peekInt24 = function(offset, littleEndian) {
if (offset == null) {
offset = 0;
}
if (littleEndian) {
return this.peekUInt16(offset, true) + (this.peekInt8(offset + 2) << 16);
} else {
return (this.peekInt16(offset) << 8) + this.peekUInt8(offset + 2);
}
};
Stream.prototype.readUInt32 = function(littleEndian) {
this.read(4, littleEndian);
return uint32[0];
};
Stream.prototype.peekUInt32 = function(offset, littleEndian) {
if (offset == null) {
offset = 0;
}
this.peek(4, offset, littleEndian);
return uint32[0];
};
Stream.prototype.readInt32 = function(littleEndian) {
this.read(4, littleEndian);
return int32[0];
};
Stream.prototype.peekInt32 = function(offset, littleEndian) {
if (offset == null) {
offset = 0;
}
this.peek(4, offset, littleEndian);
return int32[0];
};
Stream.prototype.readFloat32 = function(littleEndian) {
this.read(4, littleEndian);
return float32[0];
};
Stream.prototype.peekFloat32 = function(offset, littleEndian) {
if (offset == null) {
offset = 0;
}
this.peek(4, offset, littleEndian);
return float32[0];
};
Stream.prototype.readFloat64 = function(littleEndian) {
this.read(8, littleEndian);
if (float64) {
return float64[0];
} else {
return float64Fallback();
}
};
float64Fallback = function() {
var exp, frac, high, low, out, sign;
low = uint32[0], high = uint32[1];
if (!high || high === 0x80000000) {
return 0.0;
}
sign = 1 - (high >>> 31) * 2;
exp = (high >>> 20) & 0x7ff;
frac = high & 0xfffff;
if (exp === 0x7ff) {
if (frac) {
return NaN;
}
return sign * Infinity;
}
exp -= 1023;
out = (frac | 0x100000) * Math.pow(2, exp - 20);
out += low * Math.pow(2, exp - 52);
return sign * out;
};
Stream.prototype.peekFloat64 = function(offset, littleEndian) {
if (offset == null) {
offset = 0;
}
this.peek(8, offset, littleEndian);
if (float64) {
return float64[0];
} else {
return float64Fallback();
}
};
Stream.prototype.readFloat80 = function(littleEndian) {
this.read(10, littleEndian);
return float80();
};
float80 = function() {
var a0, a1, exp, high, low, out, sign;
high = uint32[0], low = uint32[1];
a0 = uint8[9];
a1 = uint8[8];
sign = 1 - (a0 >>> 7) * 2;
exp = ((a0 & 0x7F) << 8) | a1;
if (exp === 0 && low === 0 && high === 0) {
return 0;
}
if (exp === 0x7fff) {
if (low === 0 && high === 0) {
return sign * Infinity;
}
return NaN;
}
exp -= 16383;
out = low * Math.pow(2, exp - 31);
out += high * Math.pow(2, exp - 63);
return sign * out;
};
Stream.prototype.peekFloat80 = function(offset, littleEndian) {
if (offset == null) {
offset = 0;
}
this.peek(10, offset, littleEndian);
return float80();
};
Stream.prototype.readBuffer = function(length) {
var i, result, to, _i;
result = AVBuffer.allocate(length);
to = result.data;
for (i = _i = 0; _i < length; i = _i += 1) {
to[i] = this.readUInt8();
}
return result;
};
Stream.prototype.peekBuffer = function(offset, length) {
var i, result, to, _i;
if (offset == null) {
offset = 0;
}
result = AVBuffer.allocate(length);
to = result.data;
for (i = _i = 0; _i < length; i = _i += 1) {
to[i] = this.peekUInt8(offset + i);
}
return result;
};
Stream.prototype.readSingleBuffer = function(length) {
var result;
result = this.list.first.slice(this.localOffset, length);
this.advance(result.length);
return result;
};
Stream.prototype.peekSingleBuffer = function(offset, length) {
var result;
result = this.list.first.slice(this.localOffset + offset, length);
return result;
};
Stream.prototype.readString = function(length, encoding) {
if (encoding == null) {
encoding = 'ascii';
}
return decodeString.call(this, 0, length, encoding, true);
};
Stream.prototype.peekString = function(offset, length, encoding) {
if (offset == null) {
offset = 0;
}
if (encoding == null) {
encoding = 'ascii';
}
return decodeString.call(this, offset, length, encoding, false);
};
decodeString = function(offset, length, encoding, advance) {
var b1, b2, b3, b4, bom, c, end, littleEndian, nullEnd, pt, result, w1, w2;
encoding = encoding.toLowerCase();
nullEnd = length === null ? 0 : -1;
if (length == null) {
length = Infinity;
}
end = offset + length;
result = '';
switch (encoding) {
case 'ascii':
case 'latin1':
while (offset < end && (c = this.peekUInt8(offset++)) !== nullEnd) {
result += String.fromCharCode(c);
}
break;
case 'utf8':
case 'utf-8':
while (offset < end && (b1 = this.peekUInt8(offset++)) !== nullEnd) {
if ((b1 & 0x80) === 0) {
result += String.fromCharCode(b1);
} else if ((b1 & 0xe0) === 0xc0) {
b2 = this.peekUInt8(offset++) & 0x3f;
result += String.fromCharCode(((b1 & 0x1f) << 6) | b2);
} else if ((b1 & 0xf0) === 0xe0) {
b2 = this.peekUInt8(offset++) & 0x3f;
b3 = this.peekUInt8(offset++) & 0x3f;
result += String.fromCharCode(((b1 & 0x0f) << 12) | (b2 << 6) | b3);
} else if ((b1 & 0xf8) === 0xf0) {
b2 = this.peekUInt8(offset++) & 0x3f;
b3 = this.peekUInt8(offset++) & 0x3f;
b4 = this.peekUInt8(offset++) & 0x3f;
pt = (((b1 & 0x0f) << 18) | (b2 << 12) | (b3 << 6) | b4) - 0x10000;
result += String.fromCharCode(0xd800 + (pt >> 10), 0xdc00 + (pt & 0x3ff));
}
}
break;
case 'utf16-be':
case 'utf16be':
case 'utf16le':
case 'utf16-le':
case 'utf16bom':
case 'utf16-bom':
switch (encoding) {
case 'utf16be':
case 'utf16-be':
littleEndian = false;
break;
case 'utf16le':
case 'utf16-le':
littleEndian = true;
break;
case 'utf16bom':
case 'utf16-bom':
if (length < 2 || (bom = this.peekUInt16(offset)) === nullEnd) {
if (advance) {
this.advance(offset += 2);
}
return result;
}
littleEndian = bom === 0xfffe;
offset += 2;
}
while (offset < end && (w1 = this.peekUInt16(offset, littleEndian)) !== nullEnd) {
offset += 2;
if (w1 < 0xd800 || w1 > 0xdfff) {
result += String.fromCharCode(w1);
} else {
if (w1 > 0xdbff) {
throw new Error("Invalid utf16 sequence.");
}
w2 = this.peekUInt16(offset, littleEndian);
if (w2 < 0xdc00 || w2 > 0xdfff) {
throw new Error("Invalid utf16 sequence.");
}
result += String.fromCharCode(w1, w2);
offset += 2;
}
}
if (w1 === nullEnd) {
offset += 2;
}
break;
default:
throw new Error("Unknown encoding: " + encoding);
}
if (advance) {
this.advance(offset);
}
return result;
};
return Stream;
})();
module.exports = Stream;
}).call(this);
},{"./buffer":6,"./bufferlist":7,"./underflow":10}],10:[function(require,module,exports){
// Generated by CoffeeScript 1.7.1
(function() {
var UnderflowError,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
UnderflowError = (function(_super) {
__extends(UnderflowError, _super);
function UnderflowError() {
UnderflowError.__super__.constructor.apply(this, arguments);
this.name = 'UnderflowError';
this.stack = new Error().stack;
}
return UnderflowError;
})(Error);
module.exports = UnderflowError;
}).call(this);
},{}],11:[function(require,module,exports){
// Generated by CoffeeScript 1.7.1
(function() {
var Bitstream, BufferList, Decoder, EventEmitter, Stream, UnderflowError,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
EventEmitter = require('./core/events');
BufferList = require('./core/bufferlist');
Stream = require('./core/stream');
Bitstream = require('./core/bitstream');
UnderflowError = require('./core/underflow');
Decoder = (function(_super) {
var codecs;
__extends(Decoder, _super);
function Decoder(demuxer, format) {
var list;
this.demuxer = demuxer;
this.format = format;
list = new BufferList;
this.stream = new Stream(list);
this.bitstream = new Bitstream(this.stream);
this.receivedFinalBuffer = false;
this.waiting = false;
this.demuxer.on('cookie', (function(_this) {
return function(cookie) {
var error;
try {
return _this.setCookie(cookie);
} catch (_error) {
error = _error;
return _this.emit('error', error);
}
};
})(this));
this.demuxer.on('data', (function(_this) {
return function(chunk) {
list.append(chunk);
if (_this.waiting) {
return _this.decode();
}
};
})(this));
this.demuxer.on('end', (function(_this) {
return function() {
_this.receivedFinalBuffer = true;
if (_this.waiting) {
return _this.decode();
}
};
})(this));
this.init();
}
Decoder.prototype.init = function() {};
Decoder.prototype.setCookie = function(cookie) {};
Decoder.prototype.readChunk = function() {};
Decoder.prototype.decode = function() {
var error, offset, packet;
this.waiting = !this.receivedFinalBuffer;
offset = this.bitstream.offset();
try {
packet = this.readChunk();
} catch (_error) {
error = _error;
if (!(error instanceof UnderflowError)) {
this.emit('error', error);
return false;
}
}
if (packet) {
this.emit('data', packet);
if (this.receivedFinalBuffer) {
this.emit('end');
}
return true;
} else if (!this.receivedFinalBuffer) {
this.bitstream.seek(offset);
this.waiting = true;
} else {
this.emit('end');
}
return false;
};
Decoder.prototype.seek = function(timestamp) {
var seekPoint;
seekPoint = this.demuxer.seek(timestamp);
this.stream.seek(seekPoint.offset);
return seekPoint.timestamp;
};
codecs = {};
Decoder.register = function(id, decoder) {
return codecs[id] = decoder;
};
Decoder.find = function(id) {
return codecs[id] || null;
};
return Decoder;
})(EventEmitter);
module.exports = Decoder;
}).call(this);
},{"./core/bitstream":5,"./core/bufferlist":7,"./core/events":8,"./core/stream":9,"./core/underflow":10}],12:[function(require,module,exports){
// Generated by CoffeeScript 1.7.1
(function() {
var Decoder, LPCMDecoder,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
Decoder = require('../decoder');
LPCMDecoder = (function(_super) {
__extends(LPCMDecoder, _super);
function LPCMDecoder() {
this.readChunk = __bind(this.readChunk, this);
return LPCMDecoder.__super__.constructor.apply(this, arguments);
}
Decoder.register('lpcm', LPCMDecoder);
LPCMDecoder.prototype.readChunk = function() {
var chunkSize, i, littleEndian, output, samples, stream, _i, _j, _k, _l, _m, _n;
stream = this.stream;
littleEndian = this.format.littleEndian;
chunkSize = Math.min(4096, stream.remainingBytes());
samples = chunkSize / (this.format.bitsPerChannel / 8) | 0;
if (chunkSize < this.format.bitsPerChannel / 8) {
return null;
}
if (this.format.floatingPoint) {
switch (this.format.bitsPerChannel) {
case 32:
output = new Float32Array(samples);
for (i = _i = 0; _i < samples; i = _i += 1) {
output[i] = stream.readFloat32(littleEndian);
}
break;
case 64:
output = new Float64Array(samples);
for (i = _j = 0; _j < samples; i = _j += 1) {
output[i] = stream.readFloat64(littleEndian);
}
break;
default:
throw new Error('Unsupported bit depth.');
}
} else {
switch (this.format.bitsPerChannel) {
case 8:
output = new Int8Array(samples);
for (i = _k = 0; _k < samples; i = _k += 1) {
output[i] = stream.readInt8();
}
break;
case 16:
output = new Int16Array(samples);
for (i = _l = 0; _l < samples; i = _l += 1) {
output[i] = stream.readInt16(littleEndian);
}
break;
case 24:
output = new Int32Array(samples);
for (i = _m = 0; _m < samples; i = _m += 1) {
output[i] = stream.readInt24(littleEndian);
}
break;
case 32:
output = new Int32Array(samples);
for (i = _n = 0; _n < samples; i = _n += 1) {
output[i] = stream.readInt32(littleEndian);
}
break;
default:
throw new Error('Unsupported bit depth.');
}
}
return output;
};
return LPCMDecoder;
})(Decoder);
}).call(this);
},{"../decoder":11}],13:[function(require,module,exports){
// Generated by CoffeeScript 1.7.1
(function() {
var Decoder, XLAWDecoder,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
Decoder = require('../decoder');
XLAWDecoder = (function(_super) {
var BIAS, QUANT_MASK, SEG_MASK, SEG_SHIFT, SIGN_BIT;
__extends(XLAWDecoder, _super);
function XLAWDecoder() {
this.readChunk = __bind(this.readChunk, this);
return XLAWDecoder.__super__.constructor.apply(this, arguments);
}
Decoder.register('ulaw', XLAWDecoder);
Decoder.register('alaw', XLAWDecoder);
SIGN_BIT = 0x80;
QUANT_MASK = 0xf;
SEG_SHIFT = 4;
SEG_MASK = 0x70;
BIAS = 0x84;
XLAWDecoder.prototype.init = function() {
var i, seg, t, table, val, _i, _j;
this.format.bitsPerChannel = 16;
this.table = table = new Int16Array(256);
if (this.format.formatID === 'ulaw') {
for (i = _i = 0; _i < 256; i = ++_i) {
val = ~i;
t = ((val & QUANT_MASK) << 3) + BIAS;
t <<= (val & SEG_MASK) >>> SEG_SHIFT;
table[i] = val & SIGN_BIT ? BIAS - t : t - BIAS;
}
} else {
for (i = _j = 0; _j < 256; i = ++_j) {
val = i ^ 0x55;
t = val & QUANT_MASK;
seg = (val & SEG_MASK) >>> SEG_SHIFT;
if (seg) {
t = (t + t + 1 + 32) << (seg + 2);
} else {
t = (t + t + 1) << 3;
}
table[i] = val & SIGN_BIT ? t : -t;
}
}
};
XLAWDecoder.prototype.readChunk = function() {
var i, output, samples, stream, table, _i;
stream = this.stream, table = this.table;
samples = Math.min(4096, this.stream.remainingBytes());
if (samples === 0) {
return;
}
output = new Int16Array(samples);
for (i = _i = 0; _i < samples; i = _i += 1) {
output[i] = table[stream.readUInt8()];
}
return output;
};
return XLAWDecoder;
})(Decoder);
}).call(this);
},{"../decoder":11}],14:[function(require,module,exports){
// Generated by CoffeeScript 1.7.1
(function() {
var BufferList, Demuxer, EventEmitter, Stream,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
EventEmitter = require('./core/events');
BufferList = require('./core/bufferlist');
Stream = require('./core/stream');
Demuxer = (function(_super) {
var formats;
__extends(Demuxer, _super);
Demuxer.probe = function(buffer) {
return false;
};
function Demuxer(source, chunk) {
var list, received;
list = new BufferList;
list.append(chunk);
this.stream = new Stream(list);
received = false;
source.on('data', (function(_this) {
return function(chunk) {
var e;
received = true;
list.append(chunk);
try {
return _this.readChunk(chunk);
} catch (_error) {
e = _error;
return _this.emit('error', e);
}
};
})(this));
source.on('error', (function(_this) {
return function(err) {
return _this.emit('error', err);
};
})(this));
source.on('end', (function(_this) {
return function() {
if (!received) {
_this.readChunk(chunk);
}
return _this.emit('end');
};
})(this));
this.seekPoints = [];
this.init();
}
Demuxer.prototype.init = function() {};
Demuxer.prototype.readChunk = function(chunk) {};
Demuxer.prototype.addSeekPoint = function(offset, timestamp) {
var index;
index = this.searchTimestamp(timestamp);
return this.seekPoints.splice(index, 0, {
offset: offset,
timestamp: timestamp
});
};
Demuxer.prototype.searchTimestamp = function(timestamp, backward) {
var high, low, mid, time;
low = 0;
high = this.seekPoints.length;
if (high > 0 && this.seekPoints[high - 1].timestamp < timestamp) {
return high;
}
while (low < high) {
mid = (low + high) >> 1;
time = this.seekPoints[mid].timestamp;
if (time < timestamp) {
low = mid + 1;
} else if (time >= timestamp) {
high = mid;
}
}
if (high > this.seekPoints.length) {
high = this.seekPoints.length;
}
return high;
};
Demuxer.prototype.seek = function(timestamp) {
var index, seekPoint;
if (this.format && this.format.framesPerPacket > 0 && this.format.bytesPerPacket > 0) {
seekPoint = {
timestamp: timestamp,
offset: this.format.bytesPerPacket * timestamp / this.format.framesPerPacket
};
return seekPoint;
} else {
index = this.searchTimestamp(timestamp);
return this.seekPoints[index];
}
};
formats = [];
Demuxer.register = function(demuxer) {
return formats.push(demuxer);
};
Demuxer.find = function(buffer) {
var e, format, offset, stream, _i, _len;
stream = Stream.fromBuffer(buffer);
for (_i = 0, _len = formats.length; _i < _len; _i++) {
format = formats[_i];
offset = stream.offset;
try {
if (format.probe(stream)) {
return format;
}
} catch (_error) {
e = _error;
}
stream.seek(offset);
}
return null;
};
return Demuxer;
})(EventEmitter);
module.exports = Demuxer;
}).call(this);
},{"./core/bufferlist":7,"./core/events":8,"./core/stream":9}],15:[function(require,module,exports){
// Generated by CoffeeScript 1.7.1
(function() {
var AIFFDemuxer, Demuxer,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
Demuxer = require('../demuxer');
AIFFDemuxer = (function(_super) {
__extends(AIFFDemuxer, _super);
function AIFFDemuxer() {
return AIFFDemuxer.__super__.constructor.apply(this, arguments);
}
Demuxer.register(AIFFDemuxer);
AIFFDemuxer.probe = function(buffer) {
var _ref;
return buffer.peekString(0, 4) === 'FORM' && ((_ref = buffer.peekString(8, 4)) === 'AIFF' || _ref === 'AIFC');
};
AIFFDemuxer.prototype.readChunk = function() {
var buffer, format, offset, _ref;
if (!this.readStart && this.stream.available(12)) {
if (this.stream.readString(4) !== 'FORM') {
return this.emit('error', 'Invalid AIFF.');
}
this.fileSize = this.stream.readUInt32();
this.fileType = this.stream.readString(4);
this.readStart = true;
if ((_ref = this.fileType) !== 'AIFF' && _ref !== 'AIFC') {
return this.emit('error', 'Invalid AIFF.');
}
}
while (this.stream.available(1)) {
if (!this.readHeaders && this.stream.available(8)) {
this.type = this.stream.readString(4);
this.len = this.stream.readUInt32();
}
switch (this.type) {
case 'COMM':
if (!this.stream.available(this.len)) {
return;
}
this.format = {
formatID: 'lpcm',
channelsPerFrame: this.stream.readUInt16(),
sampleCount: this.stream.readUInt32(),
bitsPerChannel: this.stream.readUInt16(),
sampleRate: this.stream.readFloat80(),
framesPerPacket: 1,
littleEndian: false,
floatingPoint: false
};
this.format.bytesPerPacket = (this.format.bitsPerChannel / 8) * this.format.channelsPerFrame;
if (this.fileType === 'AIFC') {
format = this.stream.readString(4);
this.format.littleEndian = format === 'sowt' && this.format.bitsPerChannel > 8;
this.format.floatingPoint = format === 'fl32' || format === 'fl64';
if (format === 'twos' || format === 'sowt' || format === 'fl32' || format === 'fl64' || format === 'NONE') {
format = 'lpcm';
}
this.format.formatID = format;
this.len -= 4;
}
this.stream.advance(this.len - 18);
this.emit('format', this.format);
this.emit('duration', this.format.sampleCount / this.format.sampleRate * 1000 | 0);
break;
case 'SSND':
if (!(this.readSSNDHeader && this.stream.available(4))) {
offset = this.stream.readUInt32();
this.stream.advance(4);
this.stream.advance(offset);
this.readSSNDHeader = true;
}
buffer = this.stream.readSingleBuffer(this.len);
this.len -= buffer.length;
this.readHeaders = this.len > 0;
this.emit('data', buffer);
break;
default:
if (!this.stream.available(this.len)) {
return;
}
this.stream.advance(this.len);
}
if (this.type !== 'SSND') {
this.readHeaders = false;
}
}
};
return AIFFDemuxer;
})(Demuxer);
}).call(this);
},{"../demuxer":14}],16:[function(require,module,exports){
// Generated by CoffeeScript 1.7.1
(function() {
var AUDemuxer, Demuxer,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
Demuxer = require('../demuxer');
AUDemuxer = (function(_super) {
var bps, formats;
__extends(AUDemuxer, _super);
function AUDemuxer() {
return AUDemuxer.__super__.constructor.apply(this, arguments);
}
Demuxer.register(AUDemuxer);
AUDemuxer.probe = function(buffer) {
return buffer.peekString(0, 4) === '.snd';
};
bps = [8, 8, 16, 24, 32, 32, 64];
bps[26] = 8;
formats = {
1: 'ulaw',
27: 'alaw'
};
AUDemuxer.prototype.readChunk = function() {
var bytes, dataSize, encoding, size;
if (!this.readHeader && this.stream.available(24)) {
if (this.stream.readString(4) !== '.snd') {
return this.emit('error', 'Invalid AU file.');
}
size = this.stream.readUInt32();
dataSize = this.stream.readUInt32();
encoding = this.stream.readUInt32();
this.format = {
formatID: formats[encoding] || 'lpcm',
littleEndian: false,
floatingPoint: encoding === 6 || encoding === 7,
bitsPerChannel: bps[encoding - 1],
sampleRate: this.stream.readUInt32(),
channelsPerFrame: this.stream.readUInt32(),
framesPerPacket: 1
};
if (this.format.bitsPerChannel == null) {
return this.emit('error', 'Unsupported encoding in AU file.');
}
this.format.bytesPerPacket = (this.format.bitsPerChannel / 8) * this.format.channelsPerFrame;
if (dataSize !== 0xffffffff) {
bytes = this.format.bitsPerChannel / 8;
this.emit('duration', dataSize / bytes / this.format.channelsPerFrame / this.format.sampleRate * 1000 | 0);
}
this.emit('format', this.format);
this.readHeader = true;
}
if (this.readHeader) {
while (this.stream.available(1)) {
this.emit('data', this.stream.readSingleBuffer(this.stream.remainingBytes()));
}
}
};
return AUDemuxer;
})(Demuxer);
}).call(this);
},{"../demuxer":14}],17:[function(require,module,exports){
// Generated by CoffeeScript 1.7.1
(function() {
var CAFDemuxer, Demuxer, M4ADemuxer,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
Demuxer = require('../demuxer');
M4ADemuxer = require('./m4a');
CAFDemuxer = (function(_super) {
__extends(CAFDemuxer, _super);
function CAFDemuxer() {
return CAFDemuxer.__super__.constructor.apply(this, arguments);
}
Demuxer.register(CAFDemuxer);
CAFDemuxer.probe = function(buffer) {
return buffer.peekString(0, 4) === 'caff';
};
CAFDemuxer.prototype.readChunk = function() {
var buffer, byteOffset, cookie, entries, flags, i, key, metadata, offset, sampleOffset, value, _i, _j, _ref;
if (!this.format && this.stream.available(64)) {
if (this.stream.readString(4) !== 'caff') {
return this.emit('error', "Invalid CAF, does not begin with 'caff'");
}
this.stream.advance(4);
if (this.stream.readString(4) !== 'desc') {
return this.emit('error', "Invalid CAF, 'caff' is not followed by 'desc'");
}
if (!(this.stream.readUInt32() === 0 && this.stream.readUInt32() === 32)) {
return this.emit('error', "Invalid 'desc' size, should be 32");
}
this.format = {};
this.format.sampleRate = this.stream.readFloat64();
this.format.formatID = this.stream.readString(4);
flags = this.stream.readUInt32();
if (this.format.formatID === 'lpcm') {
this.format.floatingPoint = Boolean(flags & 1);
this.format.littleEndian = Boolean(flags & 2);
}
this.format.bytesPerPacket = this.stream.readUInt32();
this.format.framesPerPacket = this.stream.readUInt32();
this.format.channelsPerFrame = this.stream.readUInt32();
this.format.bitsPerChannel = this.stream.readUInt32();
this.emit('format', this.format);
}
while (this.stream.available(1)) {
if (!this.headerCache) {
this.headerCache = {
type: this.stream.readString(4),
oversize: this.stream.readUInt32() !== 0,
size: this.stream.readUInt32()
};
if (this.headerCache.oversize) {
return this.emit('error', "Holy Shit, an oversized file, not supported in JS");
}
}
switch (this.headerCache.type) {
case 'kuki':
if (this.stream.available(this.headerCache.size)) {
if (this.format.formatID === 'aac ') {
offset = this.stream.offset + this.headerCache.size;
if (cookie = M4ADemuxer.readEsds(this.stream)) {
this.emit('cookie', cookie);
}
this.stream.seek(offset);
} else {
buffer = this.stream.readBuffer(this.headerCache.size);
this.emit('cookie', buffer);
}
this.headerCache = null;
}
break;
case 'pakt':
if (this.stream.available(this.headerCache.size)) {
if (this.stream.readUInt32() !== 0) {
return this.emit('error', 'Sizes greater than 32 bits are not supported.');
}
this.numPackets = this.stream.readUInt32();
if (this.stream.readUInt32() !== 0) {
return this.emit('error', 'Sizes greater than 32 bits are not supported.');
}
this.numFrames = this.stream.readUInt32();
this.primingFrames = this.stream.readUInt32();
this.remainderFrames = this.stream.readUInt32();
this.emit('duration', this.numFrames / this.format.sampleRate * 1000 | 0);
this.sentDuration = true;
byteOffset = 0;
sampleOffset = 0;
for (i = _i = 0, _ref = this.numPackets; _i < _ref; i = _i += 1) {
this.addSeekPoint(byteOffset, sampleOffset);
byteOffset += this.format.bytesPerPacket || M4ADemuxer.readDescrLen(this.stream);
sampleOffset += this.format.framesPerPacket || M4ADemuxer.readDescrLen(this.stream);
}
this.headerCache = null;
}
break;
case 'info':
entries = this.stream.readUInt32();
metadata = {};
for (i = _j = 0; 0 <= entries ? _j < entries : _j > entries; i = 0 <= entries ? ++_j : --_j) {
key = this.stream.readString(null);
value = this.stream.readString(null);
metadata[key] = value;
}
this.emit('metadata', metadata);
this.headerCache = null;
break;
case 'data':
if (!this.sentFirstDataChunk) {
this.stream.advance(4);
this.headerCache.size -= 4;
if (this.format.bytesPerPacket !== 0 && !this.sentDuration) {
this.numFrames = this.headerCache.size / this.format.bytesPerPacket;
this.emit('duration', this.numFrames / this.format.sampleRate * 1000 | 0);
}
this.sentFirstDataChunk = true;
}
buffer = this.stream.readSingleBuffer(this.headerCache.size);
this.headerCache.size -= buffer.length;
this.emit('data', buffer);
if (this.headerCache.size <= 0) {
this.headerCache = null;
}
break;
default:
if (this.stream.available(this.headerCache.size)) {
this.stream.advance(this.headerCache.size);
this.headerCache = null;
}
}
}
};
return CAFDemuxer;
})(Demuxer);
}).call(this);
},{"../demuxer":14,"./m4a":18}],18:[function(require,module,exports){
// Generated by CoffeeScript 1.7.1
(function() {
var Demuxer, M4ADemuxer,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
Demuxer = require('../demuxer');
M4ADemuxer = (function(_super) {
var BITS_PER_CHANNEL, TYPES, after, atom, atoms, bool, containers, diskTrack, genres, meta, string;
__extends(M4ADemuxer, _super);
function M4ADemuxer() {
return M4ADemuxer.__super__.constructor.apply(this, arguments);
}
Demuxer.register(M4ADemuxer);
TYPES = ['M4A ', 'M4P ', 'M4B ', 'M4V ', 'isom', 'mp42', 'qt '];
M4ADemuxer.probe = function(buffer) {
var _ref;
return buffer.peekString(4, 4) === 'ftyp' && (_ref = buffer.peekString(8, 4), __indexOf.call(TYPES, _ref) >= 0);
};
M4ADemuxer.prototype.init = function() {
this.atoms = [];
this.offsets = [];
this.track = null;
return this.tracks = [];
};
atoms = {};
containers = {};
atom = function(name, fn) {
var c, container, _i, _len, _ref;
c = [];
_ref = name.split('.').slice(0, -1);
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
container = _ref[_i];
c.push(container);
containers[c.join('.')] = true;
}
if (atoms[name] == null) {
atoms[name] = {};
}
return atoms[name].fn = fn;
};
after = function(name, fn) {
if (atoms[name] == null) {
atoms[name] = {};
}
return atoms[name].after = fn;
};
M4ADemuxer.prototype.readChunk = function() {
var handler, path, type;
this["break"] = false;
while (this.stream.available(1) && !this["break"]) {
if (!this.readHeaders) {
if (!this.stream.available(8)) {
return;
}
this.len = this.stream.readUInt32() - 8;
this.type = this.stream.readString(4);
if (this.len === 0) {
continue;
}
this.atoms.push(this.type);
this.offsets.push(this.stream.offset + this.len);
this.readHeaders = true;
}
path = this.atoms.join('.');
handler = atoms[path];
if (handler != null ? handler.fn : void 0) {
if (!(this.stream.available(this.len) || path === 'mdat')) {
return;
}
handler.fn.call(this);
if (path in containers) {
this.readHeaders = false;
}
} else if (path in containers) {
this.readHeaders = false;
} else {
if (!this.stream.available(this.len)) {
return;
}
this.stream.advance(this.len);
}
while (this.stream.offset >= this.offsets[this.offsets.length - 1]) {
handler = atoms[this.atoms.join('.')];
if (handler != null ? handler.after : void 0) {
handler.after.call(this);
}
type = this.atoms.pop();
this.offsets.pop();
this.readHeaders = false;
}
}
};
atom('ftyp', function() {
var _ref;
if (_ref = this.stream.readString(4), __indexOf.call(TYPES, _ref) < 0) {
return this.emit('error', 'Not a valid M4A file.');
}
return this.stream.advance(this.len - 4);
});
atom('moov.trak', function() {
this.track = {};
return this.tracks.push(this.track);
});
atom('moov.trak.tkhd', function() {
this.stream.advance(4);
this.stream.advance(8);
this.track.id = this.stream.readUInt32();
return this.stream.advance(this.len - 16);
});
atom('moov.trak.mdia.hdlr', function() {
this.stream.advance(4);
this.stream.advance(4);
this.track.type = this.stream.readString(4);
this.stream.advance(12);
return this.stream.advance(this.len - 24);
});
atom('moov.trak.mdia.mdhd', function() {
this.stream.advance(4);
this.stream.advance(8);
this.track.timeScale = this.stream.readUInt32();
this.track.duration = this.stream.readUInt32();
return this.stream.advance(4);
});
BITS_PER_CHANNEL = {
ulaw: 8,
alaw: 8,
in24: 24,
in32: 32,
fl32: 32,
fl64: 64
};
atom('moov.trak.mdia.minf.stbl.stsd', function() {
var format, numEntries, version, _ref, _ref1;
this.stream.advance(4);
numEntries = this.stream.readUInt32();
if (this.track.type !== 'soun') {
return this.stream.advance(this.len - 8);
}
if (numEntries !== 1) {
return this.emit('error', "Only expecting one entry in sample description atom!");
}
this.stream.advance(4);
format = this.track.format = {};
format.formatID = this.stream.readString(4);
this.stream.advance(6);
this.stream.advance(2);
version = this.stream.readUInt16();
this.stream.advance(6);
format.channelsPerFrame = this.stream.readUInt16();
format.bitsPerChannel = this.stream.readUInt16();
this.stream.advance(4);
format.sampleRate = this.stream.readUInt16();
this.stream.advance(2);
if (version === 1) {
format.framesPerPacket = this.stream.readUInt32();
this.stream.advance(4);
format.bytesPerFrame = this.stream.readUInt32();
this.stream.advance(4);
} else if (version !== 0) {
this.emit('error', 'Unknown version in stsd atom');
}
if (BITS_PER_CHANNEL[format.formatID] != null) {
format.bitsPerChannel = BITS_PER_CHANNEL[format.formatID];
}
format.floatingPoint = (_ref = format.formatID) === 'fl32' || _ref === 'fl64';
format.littleEndian = format.formatID === 'sowt' && format.bitsPerChannel > 8;
if ((_ref1 = format.formatID) === 'twos' || _ref1 === 'sowt' || _ref1 === 'in24' || _ref1 === 'in32' || _ref1 === 'fl32' || _ref1 === 'fl64' || _ref1 === 'raw ' || _ref1 === 'NONE') {
return format.formatID = 'lpcm';
}
});
atom('moov.trak.mdia.minf.stbl.stsd.alac', function() {
this.stream.advance(4);
return this.track.cookie = this.stream.readBuffer(this.len - 4);
});
atom('moov.trak.mdia.minf.stbl.stsd.esds', function() {
var offset;
offset = this.stream.offset + this.len;
this.track.cookie = M4ADemuxer.readEsds(this.stream);
return this.stream.seek(offset);
});
atom('moov.trak.mdia.minf.stbl.stsd.wave.enda', function() {
return this.track.format.littleEndian = !!this.stream.readUInt16();
});
M4ADemuxer.readDescrLen = function(stream) {
var c, count, len;
len = 0;
count = 4;
while (count--) {
c = stream.readUInt8();
len = (len << 7) | (c & 0x7f);
if (!(c & 0x80)) {
break;
}
}
return len;
};
M4ADemuxer.readEsds = function(stream) {
var codec_id, flags, len, tag;
stream.advance(4);
tag = stream.readUInt8();
len = M4ADemuxer.readDescrLen(stream);
if (tag === 0x03) {
stream.advance(2);
flags = stream.readUInt8();
if (flags & 0x80) {
stream.advance(2);
}
if (flags & 0x40) {
stream.advance(stream.readUInt8());
}
if (flags & 0x20) {
stream.advance(2);
}
} else {
stream.advance(2);
}
tag = stream.readUInt8();
len = M4ADemuxer.readDescrLen(stream);
if (tag === 0x04) {
codec_id = stream.readUInt8();
stream.advance(1);
stream.advance(3);
stream.advance(4);
stream.advance(4);
tag = stream.readUInt8();
len = M4ADemuxer.readDescrLen(stream);
if (tag === 0x05) {
return stream.readBuffer(len);
}
}
return null;
};
atom('moov.trak.mdia.minf.stbl.stts', function() {
var entries, i, _i;
this.stream.advance(4);
entries = this.stream.readUInt32();
this.track.stts = [];
for (i = _i = 0; _i < entries; i = _i += 1) {
this.track.stts[i] = {
count: this.stream.readUInt32(),
duration: this.stream.readUInt32()
};
}
return this.setupSeekPoints();
});
atom('moov.trak.mdia.minf.stbl.stsc', function() {
var entries, i, _i;
this.stream.advance(4);
entries = this.stream.readUInt32();
this.track.stsc = [];
for (i = _i = 0; _i < entries; i = _i += 1) {
this.track.stsc[i] = {
first: this.stream.readUInt32(),
count: this.stream.readUInt32(),
id: this.stream.readUInt32()
};
}
return this.setupSeekPoints();
});
atom('moov.trak.mdia.minf.stbl.stsz', function() {
var entries, i, _i;
this.stream.advance(4);
this.track.sampleSize = this.stream.readUInt32();
entries = this.stream.readUInt32();
if (this.track.sampleSize === 0 && entries > 0) {
this.track.sampleSizes = [];
for (i = _i = 0; _i < entries; i = _i += 1) {
this.track.sampleSizes[i] = this.stream.readUInt32();
}
}
return this.setupSeekPoints();
});
atom('moov.trak.mdia.minf.stbl.stco', function() {
var entries, i, _i;
this.stream.advance(4);
entries = this.stream.readUInt32();
this.track.chunkOffsets = [];
for (i = _i = 0; _i < entries; i = _i += 1) {
this.track.chunkOffsets[i] = this.stream.readUInt32();
}
return this.setupSeekPoints();
});
atom('moov.trak.tref.chap', function() {
var entries, i, _i;
entries = this.len >> 2;
this.track.chapterTracks = [];
for (i = _i = 0; _i < entries; i = _i += 1) {
this.track.chapterTracks[i] = this.stream.readUInt32();
}
});
M4ADemuxer.prototype.setupSeekPoints = function() {
var i, j, offset, position, sampleIndex, size, stscIndex, sttsIndex, sttsSample, timestamp, _i, _j, _len, _ref, _ref1, _results;
if (!((this.track.chunkOffsets != null) && (this.track.stsc != null) && (this.track.sampleSize != null) && (this.track.stts != null))) {
return;
}
stscIndex = 0;
sttsIndex = 0;
sttsIndex = 0;
sttsSample = 0;
sampleIndex = 0;
offset = 0;
timestamp = 0;
this.track.seekPoints = [];
_ref = this.track.chunkOffsets;
_results = [];
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
position = _ref[i];
for (j = _j = 0, _ref1 = this.track.stsc[stscIndex].count; _j < _ref1; j = _j += 1) {
this.track.seekPoints.push({
offset: offset,
position: position,
timestamp: timestamp
});
size = this.track.sampleSize || this.track.sampleSizes[sampleIndex++];
offset += size;
position += size;
timestamp += this.track.stts[sttsIndex].duration;
if (sttsIndex + 1 < this.track.stts.length && ++sttsSample === this.track.stts[sttsIndex].count) {
sttsSample = 0;
sttsIndex++;
}
}
if (stscIndex + 1 < this.track.stsc.length && i + 1 === this.track.stsc[stscIndex + 1].first) {
_results.push(stscIndex++);
} else {
_results.push(void 0);
}
}
return _results;
};
after('moov', function() {
var track, _i, _len, _ref;
if (this.mdatOffset != null) {
this.stream.seek(this.mdatOffset - 8);
}
_ref = this.tracks;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
track = _ref[_i];
if (!(track.type === 'soun')) {
continue;
}
this.track = track;
break;
}
if (this.track.type !== 'soun') {
this.track = null;
return this.emit('error', 'No audio tracks in m4a file.');
}
this.emit('format', this.track.format);
this.emit('duration', this.track.duration / this.track.timeScale * 1000 | 0);
if (this.track.cookie) {
this.emit('cookie', this.track.cookie);
}
return this.seekPoints = this.track.seekPoints;
});
atom('mdat', function() {
var bytes, chunkSize, length, numSamples, offset, sample, size, _i;
if (!this.startedData) {
if (this.mdatOffset == null) {
this.mdatOffset = this.stream.offset;
}
if (this.tracks.length === 0) {
bytes = Math.min(this.stream.remainingBytes(), this.len);
this.stream.advance(bytes);
this.len -= bytes;
return;
}
this.chunkIndex = 0;
this.stscIndex = 0;
this.sampleIndex = 0;
this.tailOffset = 0;
this.tailSamples = 0;
this.startedData = true;
}
if (!this.readChapters) {
this.readChapters = this.parseChapters();
if (this["break"] = !this.readChapters) {
return;
}
this.stream.seek(this.mdatOffset);
}
offset = this.track.chunkOffsets[this.chunkIndex] + this.tailOffset;
length = 0;
if (!this.stream.available(offset - this.stream.offset)) {
this["break"] = true;
return;
}
this.stream.seek(offset);
while (this.chunkIndex < this.track.chunkOffsets.length) {
numSamples = this.track.stsc[this.stscIndex].count - this.tailSamples;
chunkSize = 0;
for (sample = _i = 0; _i < numSamples; sample = _i += 1) {
size = this.track.sampleSize || this.track.sampleSizes[this.sampleIndex];
if (!this.stream.available(length + size)) {
break;
}
length += size;
chunkSize += size;
this.sampleIndex++;
}
if (sample < numSamples) {
this.tailOffset += chunkSize;
this.tailSamples += sample;
break;
} else {
this.chunkIndex++;
this.tailOffset = 0;
this.tailSamples = 0;
if (this.stscIndex + 1 < this.track.stsc.length && this.chunkIndex + 1 === this.track.stsc[this.stscIndex + 1].first) {
this.stscIndex++;
}
if (offset + length !== this.track.chunkOffsets[this.chunkIndex]) {
break;
}
}
}
if (length > 0) {
this.emit('data', this.stream.readBuffer(length));
return this["break"] = this.chunkIndex === this.track.chunkOffsets.length;
} else {
return this["break"] = true;
}
});
M4ADemuxer.prototype.parseChapters = function() {
var bom, id, len, nextTimestamp, point, title, track, _i, _len, _ref, _ref1, _ref2, _ref3;
if (!(((_ref = this.track.chapterTracks) != null ? _ref.length : void 0) > 0)) {
return true;
}
id = this.track.chapterTracks[0];
_ref1 = this.tracks;
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
track = _ref1[_i];
if (track.id === id) {
break;
}
}
if (track.id !== id) {
this.emit('error', 'Chapter track does not exist.');
}
if (this.chapters == null) {
this.chapters = [];
}
while (this.chapters.length < track.seekPoints.length) {
point = track.seekPoints[this.chapters.length];
if (!this.stream.available(point.position - this.stream.offset + 32)) {
return false;
}
this.stream.seek(point.position);
len = this.stream.readUInt16();
title = null;
if (!this.stream.available(len)) {
return false;
}
if (len > 2) {
bom = this.stream.peekUInt16();
if (bom === 0xfeff || bom === 0xfffe) {
title = this.stream.readString(len, 'utf16-bom');
}
}
if (title == null) {
title = this.stream.readString(len, 'utf8');
}
nextTimestamp = (_ref2 = (_ref3 = track.seekPoints[this.chapters.length + 1]) != null ? _ref3.timestamp : void 0) != null ? _ref2 : track.duration;
this.chapters.push({
title: title,
timestamp: point.timestamp / track.timeScale * 1000 | 0,
duration: (nextTimestamp - point.timestamp) / track.timeScale * 1000 | 0
});
}
this.emit('chapters', this.chapters);
return true;
};
atom('moov.udta.meta', function() {
this.metadata = {};
return this.stream.advance(4);
});
after('moov.udta.meta', function() {
return this.emit('metadata', this.metadata);
});
meta = function(field, name, fn) {
return atom("moov.udta.meta.ilst." + field + ".data", function() {
this.stream.advance(8);
this.len -= 8;
return fn.call(this, name);
});
};
string = function(field) {
return this.metadata[field] = this.stream.readString(this.len, 'utf8');
};
meta('©alb', 'album', string);
meta('©arg', 'arranger', string);
meta('©art', 'artist', string);
meta('©ART', 'artist', string);
meta('aART', 'albumArtist', string);
meta('catg', 'category', string);
meta('©com', 'composer', string);
meta('©cpy', 'copyright', string);
meta('cprt', 'copyright', string);
meta('©cmt', 'comments', string);
meta('©day', 'releaseDate', string);
meta('desc', 'description', string);
meta('©gen', 'genre', string);
meta('©grp', 'grouping', string);
meta('©isr', 'ISRC', string);
meta('keyw', 'keywords', string);
meta('©lab', 'recordLabel', string);
meta('ldes', 'longDescription', string);
meta('©lyr', 'lyrics', string);
meta('©nam', 'title', string);
meta('©phg', 'recordingCopyright', string);
meta('©prd', 'producer', string);
meta('©prf', 'performers', string);
meta('purd', 'purchaseDate', string);
meta('purl', 'podcastURL', string);
meta('©swf', 'songwriter', string);
meta('©too', 'encoder', string);
meta('©wrt', 'composer', string);
meta('covr', 'coverArt', function(field) {
return this.metadata[field] = this.stream.readBuffer(this.len);
});
genres = ["Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk", "Fusion", "Trance", "Classical", "Instrumental", "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise", "AlternRock", "Bass", "Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic", "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta", "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American", "Cabaret", "New Wave", "Psychadelic", "Rave", "Showtunes", "Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock", "Folk", "Folk/Rock", "National Folk", "Swing", "Fast Fusion", "Bebob", "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde", "Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus", "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba", "Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle", "Duet", "Punk Rock", "Drum Solo", "A Capella", "Euro-House", "Dance Hall"];
meta('gnre', 'genre', function(field) {
return this.metadata[field] = genres[this.stream.readUInt16() - 1];
});
meta('tmpo', 'tempo', function(field) {
return this.metadata[field] = this.stream.readUInt16();
});
meta('rtng', 'rating', function(field) {
var rating;
rating = this.stream.readUInt8();
return this.metadata[field] = rating === 2 ? 'Clean' : rating !== 0 ? 'Explicit' : 'None';
});
diskTrack = function(field) {
this.stream.advance(2);
this.metadata[field] = this.stream.readUInt16() + ' of ' + this.stream.readUInt16();
return this.stream.advance(this.len - 6);
};
meta('disk', 'diskNumber', diskTrack);
meta('trkn', 'trackNumber', diskTrack);
bool = function(field) {
return this.metadata[field] = this.stream.readUInt8() === 1;
};
meta('cpil', 'compilation', bool);
meta('pcst', 'podcast', bool);
meta('pgap', 'gapless', bool);
return M4ADemuxer;
})(Demuxer);
module.exports = M4ADemuxer;
}).call(this);
},{"../demuxer":14}],19:[function(require,module,exports){
// Generated by CoffeeScript 1.7.1
(function() {
var Demuxer, WAVEDemuxer,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
Demuxer = require('../demuxer');
WAVEDemuxer = (function(_super) {
var formats;
__extends(WAVEDemuxer, _super);
function WAVEDemuxer() {
return WAVEDemuxer.__super__.constructor.apply(this, arguments);
}
Demuxer.register(WAVEDemuxer);
WAVEDemuxer.probe = function(buffer) {
return buffer.peekString(0, 4) === 'RIFF' && buffer.peekString(8, 4) === 'WAVE';
};
formats = {
0x0001: 'lpcm',
0x0003: 'lpcm',
0x0006: 'alaw',
0x0007: 'ulaw'
};
WAVEDemuxer.prototype.readChunk = function() {
var buffer, bytes, encoding;
if (!this.readStart && this.stream.available(12)) {
if (this.stream.readString(4) !== 'RIFF') {
return this.emit('error', 'Invalid WAV file.');
}
this.fileSize = this.stream.readUInt32(true);
this.readStart = true;
if (this.stream.readString(4) !== 'WAVE') {
return this.emit('error', 'Invalid WAV file.');
}
}
while (this.stream.available(1)) {
if (!this.readHeaders && this.stream.available(8)) {
this.type = this.stream.readString(4);
this.len = this.stream.readUInt32(true);
}
switch (this.type) {
case 'fmt ':
encoding = this.stream.readUInt16(true);
if (!(encoding in formats)) {
return this.emit('error', 'Unsupported format in WAV file.');
}
this.format = {
formatID: formats[encoding],
floatingPoint: encoding === 0x0003,
littleEndian: formats[encoding] === 'lpcm',
channelsPerFrame: this.stream.readUInt16(true),
sampleRate: this.stream.readUInt32(true),
framesPerPacket: 1
};
this.stream.advance(4);
this.stream.advance(2);
this.format.bitsPerChannel = this.stream.readUInt16(true);
this.format.bytesPerPacket = (this.format.bitsPerChannel / 8) * this.format.channelsPerFrame;
this.emit('format', this.format);
this.stream.advance(this.len - 16);
break;
case 'data':
if (!this.sentDuration) {
bytes = this.format.bitsPerChannel / 8;
this.emit('duration', this.len / bytes / this.format.channelsPerFrame / this.format.sampleRate * 1000 | 0);
this.sentDuration = true;
}
buffer = this.stream.readSingleBuffer(this.len);
this.len -= buffer.length;
this.readHeaders = this.len > 0;
this.emit('data', buffer);
break;
default:
if (!this.stream.available(this.len)) {
return;
}
this.stream.advance(this.len);
}
if (this.type !== 'data') {
this.readHeaders = false;
}
}
};
return WAVEDemuxer;
})(Demuxer);
}).call(this);
},{"../demuxer":14}],20:[function(require,module,exports){
// Generated by CoffeeScript 1.7.1
(function() {
var AudioDevice, EventEmitter,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
EventEmitter = require('./core/events');
AudioDevice = (function(_super) {
var devices;
__extends(AudioDevice, _super);
function AudioDevice(sampleRate, channels) {
this.sampleRate = sampleRate;
this.channels = channels;
this.updateTime = __bind(this.updateTime, this);
this.playing = false;
this.currentTime = 0;
this._lastTime = 0;
}
AudioDevice.prototype.start = function() {
if (this.playing) {
return;
}
this.playing = true;
if (this.device == null) {
this.device = AudioDevice.create(this.sampleRate, this.channels);
}
if (!this.device) {
throw new Error("No supported audio device found.");
}
this._lastTime = this.device.getDeviceTime();
this._timer = setInterval(this.updateTime, 200);
return this.device.on('refill', this.refill = (function(_this) {
return function(buffer) {
return _this.emit('refill', buffer);
};
})(this));
};
AudioDevice.prototype.stop = function() {
if (!this.playing) {
return;
}
this.playing = false;
this.device.off('refill', this.refill);
return clearInterval(this._timer);
};
AudioDevice.prototype.destroy = function() {
var _ref;
this.stop();
return (_ref = this.device) != null ? _ref.destroy() : void 0;
};
AudioDevice.prototype.seek = function(currentTime) {
this.currentTime = currentTime;
if (this.playing) {
this._lastTime = this.device.getDeviceTime();
}
return this.emit('timeUpdate', this.currentTime);
};
AudioDevice.prototype.updateTime = function() {
var time;
time = this.device.getDeviceTime();
this.currentTime += (time - this._lastTime) / this.device.sampleRate * 1000 | 0;
this._lastTime = time;
return this.emit('timeUpdate', this.currentTime);
};
devices = [];
AudioDevice.register = function(device) {
return devices.push(device);
};
AudioDevice.create = function(sampleRate, channels) {
var device, _i, _len;
for (_i = 0, _len = devices.length; _i < _len; _i++) {
device = devices[_i];
if (device.supported) {
return new device(sampleRate, channels);
}
}
return null;
};
return AudioDevice;
})(EventEmitter);
module.exports = AudioDevice;
}).call(this);
},{"./core/events":8}],21:[function(require,module,exports){
// Generated by CoffeeScript 1.7.1
(function() {
var AVBuffer, AudioDevice, EventEmitter, MozillaAudioDevice,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
EventEmitter = require('../core/events');
AudioDevice = require('../device');
AVBuffer = require('../core/buffer');
MozillaAudioDevice = (function(_super) {
var createTimer, destroyTimer;
__extends(MozillaAudioDevice, _super);
AudioDevice.register(MozillaAudioDevice);
MozillaAudioDevice.supported = (typeof Audio !== "undefined" && Audio !== null) && 'mozWriteAudio' in new Audio;
function MozillaAudioDevice(sampleRate, channels) {
this.sampleRate = sampleRate;
this.channels = channels;
this.refill = __bind(this.refill, this);
this.audio = new Audio;
this.audio.mozSetup(this.channels, this.sampleRate);
this.writePosition = 0;
this.prebufferSize = this.sampleRate / 2;
this.tail = null;
this.timer = createTimer(this.refill, 100);
}
MozillaAudioDevice.prototype.refill = function() {
var available, buffer, currentPosition, written;
if (this.tail) {
written = this.audio.mozWriteAudio(this.tail);
this.writePosition += written;
if (this.writePosition < this.tail.length) {
this.tail = this.tail.subarray(written);
} else {
this.tail = null;
}
}
currentPosition = this.audio.mozCurrentSampleOffset();
available = currentPosition + this.prebufferSize - this.writePosition;
if (available > 0) {
buffer = new Float32Array(available);
this.emit('refill', buffer);
written = this.audio.mozWriteAudio(buffer);
if (written < buffer.length) {
this.tail = buffer.subarray(written);
}
this.writePosition += written;
}
};
MozillaAudioDevice.prototype.destroy = function() {
return destroyTimer(this.timer);
};
MozillaAudioDevice.prototype.getDeviceTime = function() {
return this.audio.mozCurrentSampleOffset() / this.channels;
};
createTimer = function(fn, interval) {
var url, worker;
url = AVBuffer.makeBlobURL("setInterval(function() { postMessage('ping'); }, " + interval + ");");
if (url == null) {
return setInterval(fn, interval);
}
worker = new Worker(url);
worker.onmessage = fn;
worker.url = url;
return worker;
};
destroyTimer = function(timer) {
if (timer.terminate) {
timer.terminate();
return URL.revokeObjectURL(timer.url);
} else {
return clearInterval(timer);
}
};
return MozillaAudioDevice;
})(EventEmitter);
}).call(this);
},{"../core/buffer":6,"../core/events":8,"../device":20}],22:[function(require,module,exports){
//JavaScript Audio Resampler
//Copyright (C) 2011-2015 Grant Galitz
//Released to Public Domain
function Resampler(fromSampleRate, toSampleRate, channels, inputBufferLength) {
this.fromSampleRate = +fromSampleRate;
this.toSampleRate = +toSampleRate;
this.channels = channels | 0;
this.inputBufferLength = inputBufferLength;
this.initialize();
}
Resampler.prototype.initialize = function () {
//Perform some checks:
if (this.fromSampleRate > 0 && this.toSampleRate > 0 && this.channels > 0) {
if (this.fromSampleRate == this.toSampleRate) {
//Setup a resampler bypass:
this.resampler = this.bypassResampler; //Resampler just returns what was passed through.
this.ratioWeight = 1;
} else {
this.ratioWeight = this.fromSampleRate / this.toSampleRate;
if (this.fromSampleRate < this.toSampleRate) {
/*
Use generic linear interpolation if upsampling,
as linear interpolation produces a gradient that we want
and works fine with two input sample points per output in this case.
*/
this.compileLinearInterpolationFunction();
this.lastWeight = 1;
} else {
/*
Custom resampler I wrote that doesn't skip samples
like standard linear interpolation in high downsampling.
This is more accurate than linear interpolation on downsampling.
*/
this.compileMultiTapFunction();
this.tailExists = false;
this.lastWeight = 0;
}
var outputBufferSize = (Math.ceil(this.inputBufferLength * this.toSampleRate / this.fromSampleRate / this.channels * 1.01) * this.channels) + this.channels;
this.outputBuffer = new Float32Array(outputBufferSize);
this.lastOutput = new Float32Array(this.channels);
}
} else {
throw(new Error("Invalid settings specified for the resampler."));
}
};
Resampler.prototype.compileLinearInterpolationFunction = function () {
var toCompile = "var outputOffset = 0;\
var bufferLength = buffer.length;\
if (bufferLength > 0) {\
var weight = this.lastWeight;\
var firstWeight = 0;\
var secondWeight = 0;\
var sourceOffset = 0;\
var outputOffset = 0;\
var outputBuffer = this.outputBuffer;\
for (; weight < 1; weight += " + this.ratioWeight + ") {\
secondWeight = weight % 1;\
firstWeight = 1 - secondWeight;";
for (var channel = 0; channel < this.channels; ++channel) {
toCompile += "outputBuffer[outputOffset++] = (this.lastOutput[" + channel + "] * firstWeight) + (buffer[" + channel + "] * secondWeight);";
}
toCompile += "}\
weight -= 1;\
for (bufferLength -= " + this.channels + ", sourceOffset = Math.floor(weight) * " + this.channels + "; sourceOffset < bufferLength;) {\
secondWeight = weight % 1;\
firstWeight = 1 - secondWeight;";
for (var channel = 0; channel < this.channels; ++channel) {
toCompile += "outputBuffer[outputOffset++] = (buffer[sourceOffset" + ((channel > 0) ? (" + " + channel) : "") + "] * firstWeight) + (buffer[sourceOffset + " + (this.channels + channel) + "] * secondWeight);";
}
toCompile += "weight += " + this.ratioWeight + ";\
sourceOffset = Math.floor(weight) * " + this.channels + ";\
}";
for (var channel = 0; channel < this.channels; ++channel) {
toCompile += "this.lastOutput[" + channel + "] = buffer[sourceOffset++];";
}
toCompile += "this.lastWeight = weight % 1;\
}\
return this.outputBuffer;";
this.resampler = Function("buffer", toCompile);
};
Resampler.prototype.compileMultiTapFunction = function () {
var toCompile = "var outputOffset = 0;\
var bufferLength = buffer.length;\
if (bufferLength > 0) {\
var weight = 0;";
for (var channel = 0; channel < this.channels; ++channel) {
toCompile += "var output" + channel + " = 0;"
}
toCompile += "var actualPosition = 0;\
var amountToNext = 0;\
var alreadyProcessedTail = !this.tailExists;\
this.tailExists = false;\
var outputBuffer = this.outputBuffer;\
var currentPosition = 0;\
do {\
if (alreadyProcessedTail) {\
weight = " + this.ratioWeight + ";";
for (channel = 0; channel < this.channels; ++channel) {
toCompile += "output" + channel + " = 0;"
}
toCompile += "}\
else {\
weight = this.lastWeight;";
for (channel = 0; channel < this.channels; ++channel) {
toCompile += "output" + channel + " = this.lastOutput[" + channel + "];"
}
toCompile += "alreadyProcessedTail = true;\
}\
while (weight > 0 && actualPosition < bufferLength) {\
amountToNext = 1 + actualPosition - currentPosition;\
if (weight >= amountToNext) {";
for (channel = 0; channel < this.channels; ++channel) {
toCompile += "output" + channel + " += buffer[actualPosition++] * amountToNext;"
}
toCompile += "currentPosition = actualPosition;\
weight -= amountToNext;\
}\
else {";
for (channel = 0; channel < this.channels; ++channel) {
toCompile += "output" + channel + " += buffer[actualPosition" + ((channel > 0) ? (" + " + channel) : "") + "] * weight;"
}
toCompile += "currentPosition += weight;\
weight = 0;\
break;\
}\
}\
if (weight <= 0) {";
for (channel = 0; channel < this.channels; ++channel) {
toCompile += "outputBuffer[outputOffset++] = output" + channel + " / " + this.ratioWeight + ";"
}
toCompile += "}\
else {\
this.lastWeight = weight;";
for (channel = 0; channel < this.channels; ++channel) {
toCompile += "this.lastOutput[" + channel + "] = output" + channel + ";"
}
toCompile += "this.tailExists = true;\
break;\
}\
} while (actualPosition < bufferLength);\
}\
return this.outputBuffer;";
this.resampler = Function("buffer", toCompile);
};
Resampler.prototype.bypassResampler = function (inputBuffer) {
return inputBuffer;
};
module.exports = Resampler;
},{}],23:[function(require,module,exports){
(function (global){
// Generated by CoffeeScript 1.7.1
(function() {
var AudioDevice, EventEmitter, Resampler, WebAudioDevice,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
EventEmitter = require('../core/events');
AudioDevice = require('../device');
Resampler = require('./resampler');
WebAudioDevice = (function(_super) {
var AudioContext, createProcessor, sharedContext;
__extends(WebAudioDevice, _super);
AudioDevice.register(WebAudioDevice);
AudioContext = global.AudioContext || global.webkitAudioContext;
WebAudioDevice.supported = AudioContext && (typeof AudioContext.prototype[createProcessor = 'createScriptProcessor'] === 'function' || typeof AudioContext.prototype[createProcessor = 'createJavaScriptNode'] === 'function');
sharedContext = null;
function WebAudioDevice(sampleRate, channels) {
this.sampleRate = sampleRate;
this.channels = channels;
this.refill = __bind(this.refill, this);
this.context = sharedContext != null ? sharedContext : sharedContext = new AudioContext;
this.deviceSampleRate = this.context.sampleRate;
this.bufferSize = Math.ceil(4096 / (this.deviceSampleRate / this.sampleRate) * this.channels);
this.bufferSize += this.bufferSize % this.channels;
if (this.deviceSampleRate !== this.sampleRate) {
this.resampler = new Resampler(this.sampleRate, this.deviceSampleRate, this.channels, this.bufferSize);
}
this.node = this.context[createProcessor](4096, this.channels, this.channels);
this.node.onaudioprocess = this.refill;
this.node.connect(this.context.destination);
}
WebAudioDevice.prototype.refill = function(event) {
var channelCount, channels, data, i, n, outputBuffer, _i, _j, _k, _ref;
outputBuffer = event.outputBuffer;
channelCount = outputBuffer.numberOfChannels;
channels = new Array(channelCount);
for (i = _i = 0; _i < channelCount; i = _i += 1) {
channels[i] = outputBuffer.getChannelData(i);
}
data = new Float32Array(this.bufferSize);
this.emit('refill', data);
if (this.resampler) {
data = this.resampler.resampler(data);
}
for (i = _j = 0, _ref = outputBuffer.length; _j < _ref; i = _j += 1) {
for (n = _k = 0; _k < channelCount; n = _k += 1) {
channels[n][i] = data[i * channelCount + n];
}
}
};
WebAudioDevice.prototype.destroy = function() {
return this.node.disconnect(0);
};
WebAudioDevice.prototype.getDeviceTime = function() {
return this.context.currentTime * this.sampleRate;
};
return WebAudioDevice;
})(EventEmitter);
}).call(this);
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"../core/events":8,"../device":20,"./resampler":22}],24:[function(require,module,exports){
// Generated by CoffeeScript 1.7.1
(function() {
var Filter;
Filter = (function() {
function Filter(context, key) {
if (context && key) {
Object.defineProperty(this, 'value', {
get: function() {
return context[key];
}
});
}
}
Filter.prototype.process = function(buffer) {};
return Filter;
})();
module.exports = Filter;
}).call(this);
},{}],25:[function(require,module,exports){
// Generated by CoffeeScript 1.7.1
(function() {
var BalanceFilter, Filter,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
Filter = require('../filter');
BalanceFilter = (function(_super) {
__extends(BalanceFilter, _super);
function BalanceFilter() {
return BalanceFilter.__super__.constructor.apply(this, arguments);
}
BalanceFilter.prototype.process = function(buffer) {
var i, pan, _i, _ref;
if (this.value === 0) {
return;
}
pan = Math.max(-50, Math.min(50, this.value));
for (i = _i = 0, _ref = buffer.length; _i < _ref; i = _i += 2) {
buffer[i] *= Math.min(1, (50 - pan) / 50);
buffer[i + 1] *= Math.min(1, (50 + pan) / 50);
}
};
return BalanceFilter;
})(Filter);
module.exports = BalanceFilter;
}).call(this);
},{"../filter":24}],26:[function(require,module,exports){
// Generated by CoffeeScript 1.7.1
(function() {
var Filter, VolumeFilter,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
Filter = require('../filter');
VolumeFilter = (function(_super) {
__extends(VolumeFilter, _super);
function VolumeFilter() {
return VolumeFilter.__super__.constructor.apply(this, arguments);
}
VolumeFilter.prototype.process = function(buffer) {
var i, vol, _i, _ref;
if (this.value >= 100) {
return;
}
vol = Math.max(0, Math.min(100, this.value)) / 100;
for (i = _i = 0, _ref = buffer.length; _i < _ref; i = _i += 1) {
buffer[i] *= vol;
}
};
return VolumeFilter;
})(Filter);
module.exports = VolumeFilter;
}).call(this);
},{"../filter":24}],27:[function(require,module,exports){
// Generated by CoffeeScript 1.7.1
(function() {
var Asset, AudioDevice, BalanceFilter, EventEmitter, Player, Queue, VolumeFilter,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
EventEmitter = require('./core/events');
Asset = require('./asset');
VolumeFilter = require('./filters/volume');
BalanceFilter = require('./filters/balance');
Queue = require('./queue');
AudioDevice = require('./device');
Player = (function(_super) {
__extends(Player, _super);
function Player(asset) {
this.asset = asset;
this.startPlaying = __bind(this.startPlaying, this);
this.playing = false;
this.buffered = 0;
this.currentTime = 0;
this.duration = 0;
this.volume = 100;
this.pan = 0;
this.metadata = {};
this.filters = [new VolumeFilter(this, 'volume'), new BalanceFilter(this, 'pan')];
this.asset.on('buffer', (function(_this) {
return function(buffered) {
_this.buffered = buffered;
return _this.emit('buffer', _this.buffered);
};
})(this));
this.asset.on('decodeStart', (function(_this) {
return function() {
_this.queue = new Queue(_this.asset);
return _this.queue.once('ready', _this.startPlaying);
};
})(this));
this.asset.on('format', (function(_this) {
return function(format) {
_this.format = format;
return _this.emit('format', _this.format);
};
})(this));
this.asset.on('metadata', (function(_this) {
return function(metadata) {
_this.metadata = metadata;
return _this.emit('metadata', _this.metadata);
};
})(this));
this.asset.on('duration', (function(_this) {
return function(duration) {
_this.duration = duration;
return _this.emit('duration', _this.duration);
};
})(this));
this.asset.on('error', (function(_this) {
return function(error) {
return _this.emit('error', error);
};
})(this));
}
Player.fromURL = function(url, opts) {
return new Player(Asset.fromURL(url, opts));
};
Player.fromFile = function(file) {
return new Player(Asset.fromFile(file));
};
Player.fromBuffer = function(buffer) {
return new Player(Asset.fromBuffer(buffer));
};
Player.prototype.preload = function() {
if (!this.asset) {
return;
}
this.startedPreloading = true;
return this.asset.start(false);
};
Player.prototype.play = function() {
var _ref;
if (this.playing) {
return;
}
if (!this.startedPreloading) {
this.preload();
}
this.playing = true;
return (_ref = this.device) != null ? _ref.start() : void 0;
};
Player.prototype.pause = function() {
var _ref;
if (!this.playing) {
return;
}
this.playing = false;
return (_ref = this.device) != null ? _ref.stop() : void 0;
};
Player.prototype.togglePlayback = function() {
if (this.playing) {
return this.pause();
} else {
return this.play();
}
};
Player.prototype.stop = function() {
var _ref;
this.pause();
this.asset.stop();
return (_ref = this.device) != null ? _ref.destroy() : void 0;
};
Player.prototype.seek = function(timestamp) {
var _ref;
if ((_ref = this.device) != null) {
_ref.stop();
}
this.queue.once('ready', (function(_this) {
return function() {
var _ref1, _ref2;
if ((_ref1 = _this.device) != null) {
_ref1.seek(_this.currentTime);
}
if (_this.playing) {
return (_ref2 = _this.device) != null ? _ref2.start() : void 0;
}
};
})(this));
timestamp = (timestamp / 1000) * this.format.sampleRate;
timestamp = this.asset.decoder.seek(timestamp);
this.currentTime = timestamp / this.format.sampleRate * 1000 | 0;
this.queue.reset();
return this.currentTime;
};
Player.prototype.startPlaying = function() {
var frame, frameOffset;
frame = this.queue.read();
frameOffset = 0;
this.device = new AudioDevice(this.format.sampleRate, this.format.channelsPerFrame);
this.device.on('timeUpdate', (function(_this) {
return function(currentTime) {
_this.currentTime = currentTime;
return _this.emit('progress', _this.currentTime);
};
})(this));
this.refill = (function(_this) {
return function(buffer) {
var bufferOffset, filter, i, max, _i, _j, _len, _ref;
if (!_this.playing) {
return;
}
if (!frame) {
frame = _this.queue.read();
frameOffset = 0;
}
bufferOffset = 0;
while (frame && bufferOffset < buffer.length) {
max = Math.min(frame.length - frameOffset, buffer.length - bufferOffset);
for (i = _i = 0; _i < max; i = _i += 1) {
buffer[bufferOffset++] = frame[frameOffset++];
}
if (frameOffset === frame.length) {
frame = _this.queue.read();
frameOffset = 0;
}
}
_ref = _this.filters;
for (_j = 0, _len = _ref.length; _j < _len; _j++) {
filter = _ref[_j];
filter.process(buffer);
}
if (!frame) {
if (_this.queue.ended) {
_this.currentTime = _this.duration;
_this.emit('progress', _this.currentTime);
_this.emit('end');
_this.stop();
} else {
_this.device.stop();
}
}
};
})(this);
this.device.on('refill', this.refill);
if (this.playing) {
this.device.start();
}
return this.emit('ready');
};
Player.prototype.destroy = function() {
var _ref, _ref1;
this.stop();
if ((_ref = this.device) != null) {
_ref.off();
}
if ((_ref1 = this.asset) != null) {
_ref1.destroy();
}
return this.off();
};
return Player;
})(EventEmitter);
module.exports = Player;
}).call(this);
},{"./asset":1,"./core/events":8,"./device":20,"./filters/balance":25,"./filters/volume":26,"./queue":28}],28:[function(require,module,exports){
// Generated by CoffeeScript 1.7.1
(function() {
var EventEmitter, Queue,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
EventEmitter = require('./core/events');
Queue = (function(_super) {
__extends(Queue, _super);
function Queue(asset) {
this.asset = asset;
this.write = __bind(this.write, this);
this.readyMark = 64;
this.finished = false;
this.buffering = true;
this.ended = false;
this.buffers = [];
this.asset.on('data', this.write);
this.asset.on('end', (function(_this) {
return function() {
return _this.ended = true;
};
})(this));
this.asset.decodePacket();
}
Queue.prototype.write = function(buffer) {
if (buffer) {
this.buffers.push(buffer);
}
if (this.buffering) {
if (this.buffers.length >= this.readyMark || this.ended) {
this.buffering = false;
return this.emit('ready');
} else {
return this.asset.decodePacket();
}
}
};
Queue.prototype.read = function() {
if (this.buffers.length === 0) {
return null;
}
this.asset.decodePacket();
return this.buffers.shift();
};
Queue.prototype.reset = function() {
this.buffers.length = 0;
this.buffering = true;
return this.asset.decodePacket();
};
return Queue;
})(EventEmitter);
module.exports = Queue;
}).call(this);
},{"./core/events":8}],29:[function(require,module,exports){
var AVBuffer, EventEmitter, FileSource,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
EventEmitter = require('../../core/events');
AVBuffer = require('../../core/buffer');
FileSource = (function(_super) {
__extends(FileSource, _super);
function FileSource(file) {
this.file = file;
if (typeof FileReader === "undefined" || FileReader === null) {
return this.emit('error', 'This browser does not have FileReader support.');
}
this.offset = 0;
this.length = this.file.size;
this.chunkSize = 1 << 20;
this.file[this.slice = 'slice'] || this.file[this.slice = 'webkitSlice'] || this.file[this.slice = 'mozSlice'];
}
FileSource.prototype.start = function() {
if (this.reader) {
if (!this.active) {
return this.loop();
}
}
this.reader = new FileReader;
this.active = true;
this.reader.onload = (function(_this) {
return function(e) {
var buf;
buf = new AVBuffer(new Uint8Array(e.target.result));
_this.offset += buf.length;
_this.emit('data', buf);
_this.active = false;
if (_this.offset < _this.length) {
return _this.loop();
}
};
})(this);
this.reader.onloadend = (function(_this) {
return function() {
if (_this.offset === _this.length) {
_this.emit('end');
return _this.reader = null;
}
};
})(this);
this.reader.onerror = (function(_this) {
return function(e) {
return _this.emit('error', e);
};
})(this);
this.reader.onprogress = (function(_this) {
return function(e) {
return _this.emit('progress', (_this.offset + e.loaded) / _this.length * 100);
};
})(this);
return this.loop();
};
FileSource.prototype.loop = function() {
var blob, endPos;
this.active = true;
endPos = Math.min(this.offset + this.chunkSize, this.length);
blob = this.file[this.slice](this.offset, endPos);
return this.reader.readAsArrayBuffer(blob);
};
FileSource.prototype.pause = function() {
var _ref;
this.active = false;
try {
return (_ref = this.reader) != null ? _ref.abort() : void 0;
} catch (_error) {}
};
FileSource.prototype.reset = function() {
this.pause();
return this.offset = 0;
};
return FileSource;
})(EventEmitter);
module.exports = FileSource;
},{"../../core/buffer":6,"../../core/events":8}],30:[function(require,module,exports){
var AVBuffer, EventEmitter, HTTPSource,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
EventEmitter = require('../../core/events');
AVBuffer = require('../../core/buffer');
HTTPSource = (function(_super) {
__extends(HTTPSource, _super);
function HTTPSource(url, opts) {
this.url = url;
this.opts = opts != null ? opts : {};
this.chunkSize = 1 << 20;
this.inflight = false;
if (this.opts.length) {
this.length = this.opts.length;
}
this.reset();
}
HTTPSource.prototype.start = function() {
if (this.length) {
if (!this.inflight) {
return this.loop();
}
}
this.inflight = true;
this.xhr = new XMLHttpRequest();
this.xhr.onload = (function(_this) {
return function(event) {
_this.length = parseInt(_this.xhr.getResponseHeader("Content-Length"));
_this.inflight = false;
return _this.loop();
};
})(this);
this.xhr.onerror = (function(_this) {
return function(err) {
_this.pause();
return _this.emit('error', err);
};
})(this);
this.xhr.onabort = (function(_this) {
return function(event) {
return _this.inflight = false;
};
})(this);
this.xhr.open("HEAD", this.url, true);
return this.xhr.send(null);
};
HTTPSource.prototype.loop = function() {
var endPos;
if (this.inflight || !this.length) {
return this.emit('error', 'Something is wrong in HTTPSource.loop');
}
this.inflight = true;
this.xhr = new XMLHttpRequest();
this.xhr.onload = (function(_this) {
return function(event) {
var buf, buffer, i, txt, _i, _ref;
if (_this.xhr.response) {
buf = new Uint8Array(_this.xhr.response);
} else {
txt = _this.xhr.responseText;
buf = new Uint8Array(txt.length);
for (i = _i = 0, _ref = txt.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
buf[i] = txt.charCodeAt(i) & 0xff;
}
}
buffer = new AVBuffer(buf);
_this.offset += buffer.length;
_this.emit('data', buffer);
if (_this.offset >= _this.length) {
_this.emit('end');
}
_this.inflight = false;
if (!(_this.offset >= _this.length)) {
return _this.loop();
}
};
})(this);
this.xhr.onprogress = (function(_this) {
return function(event) {
return _this.emit('progress', (_this.offset + event.loaded) / _this.length * 100);
};
})(this);
this.xhr.onerror = (function(_this) {
return function(err) {
_this.emit('error', err);
return _this.pause();
};
})(this);
this.xhr.onabort = (function(_this) {
return function(event) {
return _this.inflight = false;
};
})(this);
this.xhr.open("GET", this.url, true);
this.xhr.responseType = "arraybuffer";
endPos = Math.min(this.offset + this.chunkSize, this.length - 1);
this.xhr.setRequestHeader("If-None-Match", "webkit-no-cache");
this.xhr.setRequestHeader("Range", "bytes=" + this.offset + "-" + endPos);
this.xhr.overrideMimeType('text/plain; charset=x-user-defined');
return this.xhr.send(null);
};
HTTPSource.prototype.pause = function() {
var _ref;
this.inflight = false;
return (_ref = this.xhr) != null ? _ref.abort() : void 0;
};
HTTPSource.prototype.reset = function() {
this.pause();
return this.offset = 0;
};
return HTTPSource;
})(EventEmitter);
module.exports = HTTPSource;
},{"../../core/buffer":6,"../../core/events":8}],31:[function(require,module,exports){
(function (global){
// Generated by CoffeeScript 1.7.1
(function() {
var AVBuffer, BufferList, BufferSource, EventEmitter,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
EventEmitter = require('../core/events');
BufferList = require('../core/bufferlist');
AVBuffer = require('../core/buffer');
BufferSource = (function(_super) {
var clearImmediate, setImmediate;
__extends(BufferSource, _super);
function BufferSource(input) {
this.loop = __bind(this.loop, this);
if (input instanceof BufferList) {
this.list = input;
} else {
this.list = new BufferList;
this.list.append(new AVBuffer(input));
}
this.paused = true;
}
setImmediate = global.setImmediate || function(fn) {
return global.setTimeout(fn, 0);
};
clearImmediate = global.clearImmediate || function(timer) {
return global.clearTimeout(timer);
};
BufferSource.prototype.start = function() {
this.paused = false;
return this._timer = setImmediate(this.loop);
};
BufferSource.prototype.loop = function() {
this.emit('progress', (this.list.numBuffers - this.list.availableBuffers + 1) / this.list.numBuffers * 100 | 0);
this.emit('data', this.list.first);
if (this.list.advance()) {
return setImmediate(this.loop);
} else {
return this.emit('end');
}
};
BufferSource.prototype.pause = function() {
clearImmediate(this._timer);
return this.paused = true;
};
BufferSource.prototype.reset = function() {
this.pause();
return this.list.rewind();
};
return BufferSource;
})(EventEmitter);
module.exports = BufferSource;
}).call(this);
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"../core/buffer":6,"../core/bufferlist":7,"../core/events":8}],32:[function(require,module,exports){
var key, val, _ref;
_ref = require('./src/aurora');
for (key in _ref) {
val = _ref[key];
exports[key] = val;
}
require('./src/devices/webaudio');
require('./src/devices/mozilla');
},{"./src/aurora":2,"./src/devices/mozilla":21,"./src/devices/webaudio":23}]},{},[32])(32)
});
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJzcmMvYXNzZXQuanMiLCJzcmMvYXVyb3JhLmpzIiwic3JjL2F1cm9yYV9iYXNlLmpzIiwic3JjL2NvcmUvYmFzZS5qcyIsInNyYy9jb3JlL2JpdHN0cmVhbS5qcyIsInNyYy9jb3JlL2J1ZmZlci5qcyIsInNyYy9jb3JlL2J1ZmZlcmxpc3QuanMiLCJzcmMvY29yZS9ldmVudHMuanMiLCJzcmMvY29yZS9zdHJlYW0uanMiLCJzcmMvY29yZS91bmRlcmZsb3cuanMiLCJzcmMvZGVjb2Rlci5qcyIsInNyYy9kZWNvZGVycy9scGNtLmpzIiwic3JjL2RlY29kZXJzL3hsYXcuanMiLCJzcmMvZGVtdXhlci5qcyIsInNyYy9kZW11eGVycy9haWZmLmpzIiwic3JjL2RlbXV4ZXJzL2F1LmpzIiwic3JjL2RlbXV4ZXJzL2NhZi5qcyIsInNyYy9kZW11eGVycy9tNGEuanMiLCJzcmMvZGVtdXhlcnMvd2F2ZS5qcyIsInNyYy9kZXZpY2UuanMiLCJzcmMvZGV2aWNlcy9tb3ppbGxhLmpzIiwic3JjL2RldmljZXMvcmVzYW1wbGVyLmpzIiwic3JjL2RldmljZXMvd2ViYXVkaW8uanMiLCJzcmMvZmlsdGVyLmpzIiwic3JjL2ZpbHRlcnMvYmFsYW5jZS5qcyIsInNyYy9maWx0ZXJzL3ZvbHVtZS5qcyIsInNyYy9wbGF5ZXIuanMiLCJzcmMvcXVldWUuanMiLCIvVXNlcnMvcHNvcmkvRG9jdW1lbnRzL0NvZGUvYXVyb3JhLmpzL3NyYy9zb3VyY2VzL2Jyb3dzZXIvZmlsZS5jb2ZmZWUiLCIvVXNlcnMvcHNvcmkvRG9jdW1lbnRzL0NvZGUvYXVyb3JhLmpzL3NyYy9zb3VyY2VzL2Jyb3dzZXIvaHR0cC5jb2ZmZWUiLCJzcmMvc291cmNlcy9idWZmZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDbk9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3pGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xnQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25GQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9JQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeG5CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUM1SkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUMzRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaE9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEVBLElBQUEsa0NBQUE7RUFBQTtpU0FBQTs7QUFBQSxZQUFBLEdBQWUsT0FBQSxDQUFRLG1CQUFSLENBQWYsQ0FBQTs7QUFBQSxRQUNBLEdBQVcsT0FBQSxDQUFRLG1CQUFSLENBRFgsQ0FBQTs7QUFBQTtBQUlJLCtCQUFBLENBQUE7O0FBQWEsRUFBQSxvQkFBRSxJQUFGLEdBQUE7QUFDVCxJQURVLElBQUMsQ0FBQSxPQUFBLElBQ1gsQ0FBQTtBQUFBLElBQUEsSUFBTyx3REFBUDtBQUNJLGFBQU8sSUFBQyxDQUFBLElBQUQsQ0FBTSxPQUFOLEVBQWUsZ0RBQWYsQ0FBUCxDQURKO0tBQUE7QUFBQSxJQUdBLElBQUMsQ0FBQSxNQUFELEdBQVUsQ0FIVixDQUFBO0FBQUEsSUFJQSxJQUFDLENBQUEsTUFBRCxHQUFVLElBQUMsQ0FBQSxJQUFJLENBQUMsSUFKaEIsQ0FBQTtBQUFBLElBS0EsSUFBQyxDQUFBLFNBQUQsR0FBYSxDQUFBLElBQUssRUFMbEIsQ0FBQTtBQUFBLElBTUEsSUFBQyxDQUFBLElBQUssQ0FBQSxJQUFDLENBQUEsS0FBRCxHQUFTLE9BQVQsQ0FBTixJQUEyQixJQUFDLENBQUEsSUFBSyxDQUFBLElBQUMsQ0FBQSxLQUFELEdBQVMsYUFBVCxDQUFqQyxJQUE0RCxJQUFDLENBQUEsSUFBSyxDQUFBLElBQUMsQ0FBQSxLQUFELEdBQVMsVUFBVCxDQU5sRSxDQURTO0VBQUEsQ0FBYjs7QUFBQSx1QkFTQSxLQUFBLEdBQU8sU0FBQSxHQUFBO0FBQ0gsSUFBQSxJQUFHLElBQUMsQ0FBQSxNQUFKO0FBQ0ksTUFBQSxJQUFBLENBQUEsSUFBdUIsQ0FBQSxNQUF2QjtBQUFBLGVBQU8sSUFBQyxDQUFBLElBQUQsQ0FBQSxDQUFQLENBQUE7T0FESjtLQUFBO0FBQUEsSUFHQSxJQUFDLENBQUEsTUFBRCxHQUFVLEdBQUEsQ0FBQSxVQUhWLENBQUE7QUFBQSxJQUlBLElBQUMsQ0FBQSxNQUFELEdBQVUsSUFKVixDQUFBO0FBQUEsSUFNQSxJQUFDLENBQUEsTUFBTSxDQUFDLE1BQVIsR0FBaUIsQ0FBQSxTQUFBLEtBQUEsR0FBQTthQUFBLFNBQUMsQ0FBRCxHQUFBO0FBQ2IsWUFBQSxHQUFBO0FBQUEsUUFBQSxHQUFBLEdBQVUsSUFBQSxRQUFBLENBQWEsSUFBQSxVQUFBLENBQVcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFwQixDQUFiLENBQVYsQ0FBQTtBQUFBLFFBQ0EsS0FBQyxDQUFBLE1BQUQsSUFBVyxHQUFHLENBQUMsTUFEZixDQUFBO0FBQUEsUUFHQSxLQUFDLENBQUEsSUFBRCxDQUFNLE1BQU4sRUFBYyxHQUFkLENBSEEsQ0FBQTtBQUFBLFFBSUEsS0FBQyxDQUFBLE1BQUQsR0FBVSxLQUpWLENBQUE7QUFLQSxRQUFBLElBQVcsS0FBQyxDQUFBLE1BQUQsR0FBVSxLQUFDLENBQUEsTUFBdEI7aUJBQUEsS0FBQyxDQUFBLElBQUQsQ0FBQSxFQUFBO1NBTmE7TUFBQSxFQUFBO0lBQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQU5qQixDQUFBO0FBQUEsSUFjQSxJQUFDLENBQUEsTUFBTSxDQUFDLFNBQVIsR0FBb0IsQ0FBQSxTQUFBLEtBQUEsR0FBQTthQUFBLFNBQUEsR0FBQTtBQUNoQixRQUFBLElBQUcsS0FBQyxDQUFBLE1BQUQsS0FBVyxLQUFDLENBQUEsTUFBZjtBQUNJLFVBQUEsS0FBQyxDQUFBLElBQUQsQ0FBTSxLQUFOLENBQUEsQ0FBQTtpQkFDQSxLQUFDLENBQUEsTUFBRCxHQUFVLEtBRmQ7U0FEZ0I7TUFBQSxFQUFBO0lBQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQWRwQixDQUFBO0FBQUEsSUFtQkEsSUFBQyxDQUFBLE1BQU0sQ0FBQyxPQUFSLEdBQWtCLENBQUEsU0FBQSxLQUFBLEdBQUE7YUFBQSxTQUFDLENBQUQsR0FBQTtlQUNkLEtBQUMsQ0FBQSxJQUFELENBQU0sT0FBTixFQUFlLENBQWYsRUFEYztNQUFBLEVBQUE7SUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBbkJsQixDQUFBO0FBQUEsSUFzQkEsSUFBQyxDQUFBLE1BQU0sQ0FBQyxVQUFSLEdBQXFCLENBQUEsU0FBQSxLQUFBLEdBQUE7YUFBQSxTQUFDLENBQUQsR0FBQTtlQUNqQixLQUFDLENBQUEsSUFBRCxDQUFNLFVBQU4sRUFBa0IsQ0FBQyxLQUFDLENBQUEsTUFBRCxHQUFVLENBQUMsQ0FBQyxNQUFiLENBQUEsR0FBdUIsS0FBQyxDQUFBLE1BQXhCLEdBQWlDLEdBQW5ELEVBRGlCO01BQUEsRUFBQTtJQUFBLENBQUEsQ0FBQSxDQUFBLElBQUEsQ0F0QnJCLENBQUE7V0F5QkEsSUFBQyxDQUFBLElBQUQsQ0FBQSxFQTFCRztFQUFBLENBVFAsQ0FBQTs7QUFBQSx1QkFxQ0EsSUFBQSxHQUFNLFNBQUEsR0FBQTtBQUNGLFFBQUEsWUFBQTtBQUFBLElBQUEsSUFBQyxDQUFBLE1BQUQsR0FBVSxJQUFWLENBQUE7QUFBQSxJQUNBLE1BQUEsR0FBUyxJQUFJLENBQUMsR0FBTCxDQUFTLElBQUMsQ0FBQSxNQUFELEdBQVUsSUFBQyxDQUFBLFNBQXBCLEVBQStCLElBQUMsQ0FBQSxNQUFoQyxDQURULENBQUE7QUFBQSxJQUdBLElBQUEsR0FBTyxJQUFDLENBQUEsSUFBSyxDQUFBLElBQUMsQ0FBQSxLQUFELENBQU4sQ0FBYyxJQUFDLENBQUEsTUFBZixFQUF1QixNQUF2QixDQUhQLENBQUE7V0FJQSxJQUFDLENBQUEsTUFBTSxDQUFDLGlCQUFSLENBQTBCLElBQTFCLEVBTEU7RUFBQSxDQXJDTixDQUFBOztBQUFBLHVCQTRDQSxLQUFBLEdBQU8sU0FBQSxHQUFBO0FBQ0gsUUFBQSxJQUFBO0FBQUEsSUFBQSxJQUFDLENBQUEsTUFBRCxHQUFVLEtBQVYsQ0FBQTtBQUNBO2dEQUNTLENBQUUsS0FBVCxDQUFBLFdBREY7S0FBQSxrQkFGRztFQUFBLENBNUNQLENBQUE7O0FBQUEsdUJBaURBLEtBQUEsR0FBTyxTQUFBLEdBQUE7QUFDSCxJQUFBLElBQUMsQ0FBQSxLQUFELENBQUEsQ0FBQSxDQUFBO1dBQ0EsSUFBQyxDQUFBLE1BQUQsR0FBVSxFQUZQO0VBQUEsQ0FqRFAsQ0FBQTs7b0JBQUE7O0dBRHFCLGFBSHpCLENBQUE7O0FBQUEsTUF5RE0sQ0FBQyxPQUFQLEdBQWlCLFVBekRqQixDQUFBOzs7QUNBQSxJQUFBLGtDQUFBO0VBQUE7aVNBQUE7O0FBQUEsWUFBQSxHQUFlLE9BQUEsQ0FBUSxtQkFBUixDQUFmLENBQUE7O0FBQUEsUUFDQSxHQUFXLE9BQUEsQ0FBUSxtQkFBUixDQURYLENBQUE7O0FBQUE7QUFJSSwrQkFBQSxDQUFBOztBQUFhLEVBQUEsb0JBQUUsR0FBRixFQUFRLElBQVIsR0FBQTtBQUNULElBRFUsSUFBQyxDQUFBLE1BQUEsR0FDWCxDQUFBO0FBQUEsSUFEZ0IsSUFBQyxDQUFBLHNCQUFBLE9BQU8sRUFDeEIsQ0FBQTtBQUFBLElBQUEsSUFBQyxDQUFBLFNBQUQsR0FBYSxDQUFBLElBQUssRUFBbEIsQ0FBQTtBQUFBLElBQ0EsSUFBQyxDQUFBLFFBQUQsR0FBWSxLQURaLENBQUE7QUFFQSxJQUFBLElBQUcsSUFBQyxDQUFBLElBQUksQ0FBQyxNQUFUO0FBQ0ksTUFBQSxJQUFDLENBQUEsTUFBRCxHQUFVLElBQUMsQ0FBQSxJQUFJLENBQUMsTUFBaEIsQ0FESjtLQUZBO0FBQUEsSUFJQSxJQUFDLENBQUEsS0FBRCxDQUFBLENBSkEsQ0FEUztFQUFBLENBQWI7O0FBQUEsdUJBT0EsS0FBQSxHQUFPLFNBQUEsR0FBQTtBQUNILElBQUEsSUFBRyxJQUFDLENBQUEsTUFBSjtBQUNJLE1BQUEsSUFBQSxDQUFBLElBQXVCLENBQUEsUUFBdkI7QUFBQSxlQUFPLElBQUMsQ0FBQSxJQUFELENBQUEsQ0FBUCxDQUFBO09BREo7S0FBQTtBQUFBLElBR0EsSUFBQyxDQUFBLFFBQUQsR0FBWSxJQUhaLENBQUE7QUFBQSxJQUlBLElBQUMsQ0FBQSxHQUFELEdBQVcsSUFBQSxjQUFBLENBQUEsQ0FKWCxDQUFBO0FBQUEsSUFNQSxJQUFDLENBQUEsR0FBRyxDQUFDLE1BQUwsR0FBYyxDQUFBLFNBQUEsS0FBQSxHQUFBO2FBQUEsU0FBQyxLQUFELEdBQUE7QUFDVixRQUFBLEtBQUMsQ0FBQSxNQUFELEdBQVUsUUFBQSxDQUFTLEtBQUMsQ0FBQSxHQUFHLENBQUMsaUJBQUwsQ0FBdUIsZ0JBQXZCLENBQVQsQ0FBVixDQUFBO0FBQUEsUUFDQSxLQUFDLENBQUEsUUFBRCxHQUFZLEtBRFosQ0FBQTtlQUVBLEtBQUMsQ0FBQSxJQUFELENBQUEsRUFIVTtNQUFBLEVBQUE7SUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBTmQsQ0FBQTtBQUFBLElBV0EsSUFBQyxDQUFBLEdBQUcsQ0FBQyxPQUFMLEdBQWUsQ0FBQSxTQUFBLEtBQUEsR0FBQTthQUFBLFNBQUMsR0FBRCxHQUFBO0FBQ1gsUUFBQSxLQUFDLENBQUEsS0FBRCxDQUFBLENBQUEsQ0FBQTtlQUNBLEtBQUMsQ0FBQSxJQUFELENBQU0sT0FBTixFQUFlLEdBQWYsRUFGVztNQUFBLEVBQUE7SUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBWGYsQ0FBQTtBQUFBLElBZUEsSUFBQyxDQUFBLEdBQUcsQ0FBQyxPQUFMLEdBQWUsQ0FBQSxTQUFBLEtBQUEsR0FBQTthQUFBLFNBQUMsS0FBRCxHQUFBO2VBQ1gsS0FBQyxDQUFBLFFBQUQsR0FBWSxNQUREO01BQUEsRUFBQTtJQUFBLENBQUEsQ0FBQSxDQUFBLElBQUEsQ0FmZixDQUFBO0FBQUEsSUFrQkEsSUFBQyxDQUFBLEdBQUcsQ0FBQyxJQUFMLENBQVUsTUFBVixFQUFrQixJQUFDLENBQUEsR0FBbkIsRUFBd0IsSUFBeEIsQ0FsQkEsQ0FBQTtXQW1CQSxJQUFDLENBQUEsR0FBRyxDQUFDLElBQUwsQ0FBVSxJQUFWLEVBcEJHO0VBQUEsQ0FQUCxDQUFBOztBQUFBLHVCQTZCQSxJQUFBLEdBQU0sU0FBQSxHQUFBO0FBQ0YsUUFBQSxNQUFBO0FBQUEsSUFBQSxJQUFHLElBQUMsQ0FBQSxRQUFELElBQWEsQ0FBQSxJQUFLLENBQUEsTUFBckI7QUFDSSxhQUFPLElBQUMsQ0FBQSxJQUFELENBQU0sT0FBTixFQUFlLHVDQUFmLENBQVAsQ0FESjtLQUFBO0FBQUEsSUFHQSxJQUFDLENBQUEsUUFBRCxHQUFZLElBSFosQ0FBQTtBQUFBLElBSUEsSUFBQyxDQUFBLEdBQUQsR0FBVyxJQUFBLGNBQUEsQ0FBQSxDQUpYLENBQUE7QUFBQSxJQU1BLElBQUMsQ0FBQSxHQUFHLENBQUMsTUFBTCxHQUFjLENBQUEsU0FBQSxLQUFBLEdBQUE7YUFBQSxTQUFDLEtBQUQsR0FBQTtBQUNWLFlBQUEsNkJBQUE7QUFBQSxRQUFBLElBQUcsS0FBQyxDQUFBLEdBQUcsQ0FBQyxRQUFSO0FBQ0ksVUFBQSxHQUFBLEdBQVUsSUFBQSxVQUFBLENBQVcsS0FBQyxDQUFBLEdBQUcsQ0FBQyxRQUFoQixDQUFWLENBREo7U0FBQSxNQUFBO0FBR0ksVUFBQSxHQUFBLEdBQU0sS0FBQyxDQUFBLEdBQUcsQ0FBQyxZQUFYLENBQUE7QUFBQSxVQUNBLEdBQUEsR0FBVSxJQUFBLFVBQUEsQ0FBVyxHQUFHLENBQUMsTUFBZixDQURWLENBQUE7QUFFQSxlQUFTLDZGQUFULEdBQUE7QUFDSSxZQUFBLEdBQUksQ0FBQSxDQUFBLENBQUosR0FBUyxHQUFHLENBQUMsVUFBSixDQUFlLENBQWYsQ0FBQSxHQUFvQixJQUE3QixDQURKO0FBQUEsV0FMSjtTQUFBO0FBQUEsUUFRQSxNQUFBLEdBQWEsSUFBQSxRQUFBLENBQVMsR0FBVCxDQVJiLENBQUE7QUFBQSxRQVNBLEtBQUMsQ0FBQSxNQUFELElBQVcsTUFBTSxDQUFDLE1BVGxCLENBQUE7QUFBQSxRQVdBLEtBQUMsQ0FBQSxJQUFELENBQU0sTUFBTixFQUFjLE1BQWQsQ0FYQSxDQUFBO0FBWUEsUUFBQSxJQUFlLEtBQUMsQ0FBQSxNQUFELElBQVcsS0FBQyxDQUFBLE1BQTNCO0FBQUEsVUFBQSxLQUFDLENBQUEsSUFBRCxDQUFNLEtBQU4sQ0FBQSxDQUFBO1NBWkE7QUFBQSxRQWNBLEtBQUMsQ0FBQSxRQUFELEdBQVksS0FkWixDQUFBO0FBZUEsUUFBQSxJQUFBLENBQUEsQ0FBZSxLQUFDLENBQUEsTUFBRCxJQUFXLEtBQUMsQ0FBQSxNQUEzQixDQUFBO2lCQUFBLEtBQUMsQ0FBQSxJQUFELENBQUEsRUFBQTtTQWhCVTtNQUFBLEVBQUE7SUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBTmQsQ0FBQTtBQUFBLElBd0JBLElBQUMsQ0FBQSxHQUFHLENBQUMsVUFBTCxHQUFrQixDQUFBLFNBQUEsS0FBQSxHQUFBO2FBQUEsU0FBQyxLQUFELEdBQUE7ZUFDZCxLQUFDLENBQUEsSUFBRCxDQUFNLFVBQU4sRUFBa0IsQ0FBQyxLQUFDLENBQUEsTUFBRCxHQUFVLEtBQUssQ0FBQyxNQUFqQixDQUFBLEdBQTJCLEtBQUMsQ0FBQSxNQUE1QixHQUFxQyxHQUF2RCxFQURjO01BQUEsRUFBQTtJQUFBLENBQUEsQ0FBQSxDQUFBLElBQUEsQ0F4QmxCLENBQUE7QUFBQSxJQTJCQSxJQUFDLENBQUEsR0FBRyxDQUFDLE9BQUwsR0FBZSxDQUFBLFNBQUEsS0FBQSxHQUFBO2FBQUEsU0FBQyxHQUFELEdBQUE7QUFDWCxRQUFBLEtBQUMsQ0FBQSxJQUFELENBQU0sT0FBTixFQUFlLEdBQWYsQ0FBQSxDQUFBO2VBQ0EsS0FBQyxDQUFBLEtBQUQsQ0FBQSxFQUZXO01BQUEsRUFBQTtJQUFBLENBQUEsQ0FBQSxDQUFBLElBQUEsQ0EzQmYsQ0FBQTtBQUFBLElBK0JBLElBQUMsQ0FBQSxHQUFHLENBQUMsT0FBTCxHQUFlLENBQUEsU0FBQSxLQUFBLEdBQUE7YUFBQSxTQUFDLEtBQUQsR0FBQTtlQUNYLEtBQUMsQ0FBQSxRQUFELEdBQVksTUFERDtNQUFBLEVBQUE7SUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBL0JmLENBQUE7QUFBQSxJQWtDQSxJQUFDLENBQUEsR0FBRyxDQUFDLElBQUwsQ0FBVSxLQUFWLEVBQWlCLElBQUMsQ0FBQSxHQUFsQixFQUF1QixJQUF2QixDQWxDQSxDQUFBO0FBQUEsSUFtQ0EsSUFBQyxDQUFBLEdBQUcsQ0FBQyxZQUFMLEdBQW9CLGFBbkNwQixDQUFBO0FBQUEsSUFxQ0EsTUFBQSxHQUFTLElBQUksQ0FBQyxHQUFMLENBQVMsSUFBQyxDQUFBLE1BQUQsR0FBVSxJQUFDLENBQUEsU0FBcEIsRUFBK0IsSUFBQyxDQUFBLE1BQUQsR0FBVSxDQUF6QyxDQXJDVCxDQUFBO0FBQUEsSUFzQ0EsSUFBQyxDQUFBLEdBQUcsQ0FBQyxnQkFBTCxDQUFzQixlQUF0QixFQUF1QyxpQkFBdkMsQ0F0Q0EsQ0FBQTtBQUFBLElBdUNBLElBQUMsQ0FBQSxHQUFHLENBQUMsZ0JBQUwsQ0FBc0IsT0FBdEIsRUFBZ0MsUUFBQSxHQUFPLElBQUMsQ0FBQSxNQUFSLEdBQWdCLEdBQWhCLEdBQWtCLE1BQWxELENBdkNBLENBQUE7QUFBQSxJQXdDQSxJQUFDLENBQUEsR0FBRyxDQUFDLGdCQUFMLENBQXNCLG9DQUF0QixDQXhDQSxDQUFBO1dBeUNBLElBQUMsQ0FBQSxHQUFHLENBQUMsSUFBTCxDQUFVLElBQVYsRUExQ0U7RUFBQSxDQTdCTixDQUFBOztBQUFBLHVCQXlFQSxLQUFBLEdBQU8sU0FBQSxHQUFBO0FBQ0gsUUFBQSxJQUFBO0FBQUEsSUFBQSxJQUFDLENBQUEsUUFBRCxHQUFZLEtBQVosQ0FBQTsyQ0FDSSxDQUFFLEtBQU4sQ0FBQSxXQUZHO0VBQUEsQ0F6RVAsQ0FBQTs7QUFBQSx1QkE2RUEsS0FBQSxHQUFPLFNBQUEsR0FBQTtBQUNILElBQUEsSUFBQyxDQUFBLEtBQUQsQ0FBQSxDQUFBLENBQUE7V0FDQSxJQUFDLENBQUEsTUFBRCxHQUFVLEVBRlA7RUFBQSxDQTdFUCxDQUFBOztvQkFBQTs7R0FEcUIsYUFIekIsQ0FBQTs7QUFBQSxNQXFGTSxDQUFDLE9BQVAsR0FBaUIsVUFyRmpCLENBQUE7Ozs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuNy4xXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBBc3NldCwgQnVmZmVyU291cmNlLCBEZWNvZGVyLCBEZW11eGVyLCBFdmVudEVtaXR0ZXIsIEZpbGVTb3VyY2UsIEhUVFBTb3VyY2UsXG4gICAgX19iaW5kID0gZnVuY3Rpb24oZm4sIG1lKXsgcmV0dXJuIGZ1bmN0aW9uKCl7IHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTsgfTsgfSxcbiAgICBfX2hhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgICBfX2V4dGVuZHMgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKF9faGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfTtcblxuICBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuL2NvcmUvZXZlbnRzJyk7XG5cbiAgSFRUUFNvdXJjZSA9IHJlcXVpcmUoJy4vc291cmNlcy9ub2RlL2h0dHAnKTtcblxuICBGaWxlU291cmNlID0gcmVxdWlyZSgnLi9zb3VyY2VzL25vZGUvZmlsZScpO1xuXG4gIEJ1ZmZlclNvdXJjZSA9IHJlcXVpcmUoJy4vc291cmNlcy9idWZmZXInKTtcblxuICBEZW11eGVyID0gcmVxdWlyZSgnLi9kZW11eGVyJyk7XG5cbiAgRGVjb2RlciA9IHJlcXVpcmUoJy4vZGVjb2RlcicpO1xuXG4gIEFzc2V0ID0gKGZ1bmN0aW9uKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhBc3NldCwgX3N1cGVyKTtcblxuICAgIGZ1bmN0aW9uIEFzc2V0KHNvdXJjZSkge1xuICAgICAgdGhpcy5zb3VyY2UgPSBzb3VyY2U7XG4gICAgICB0aGlzLl9kZWNvZGUgPSBfX2JpbmQodGhpcy5fZGVjb2RlLCB0aGlzKTtcbiAgICAgIHRoaXMuZmluZERlY29kZXIgPSBfX2JpbmQodGhpcy5maW5kRGVjb2RlciwgdGhpcyk7XG4gICAgICB0aGlzLnByb2JlID0gX19iaW5kKHRoaXMucHJvYmUsIHRoaXMpO1xuICAgICAgdGhpcy5idWZmZXJlZCA9IDA7XG4gICAgICB0aGlzLmR1cmF0aW9uID0gbnVsbDtcbiAgICAgIHRoaXMuZm9ybWF0ID0gbnVsbDtcbiAgICAgIHRoaXMubWV0YWRhdGEgPSBudWxsO1xuICAgICAgdGhpcy5hY3RpdmUgPSBmYWxzZTtcbiAgICAgIHRoaXMuZGVtdXhlciA9IG51bGw7XG4gICAgICB0aGlzLmRlY29kZXIgPSBudWxsO1xuICAgICAgdGhpcy5zb3VyY2Uub25jZSgnZGF0YScsIHRoaXMucHJvYmUpO1xuICAgICAgdGhpcy5zb3VyY2Uub24oJ2Vycm9yJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihlcnIpIHtcbiAgICAgICAgICBfdGhpcy5lbWl0KCdlcnJvcicsIGVycik7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLnN0b3AoKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHRoaXMuc291cmNlLm9uKCdwcm9ncmVzcycsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oYnVmZmVyZWQpIHtcbiAgICAgICAgICBfdGhpcy5idWZmZXJlZCA9IGJ1ZmZlcmVkO1xuICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdidWZmZXInLCBfdGhpcy5idWZmZXJlZCk7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgfVxuXG4gICAgQXNzZXQuZnJvbVVSTCA9IGZ1bmN0aW9uKHVybCwgb3B0cykge1xuICAgICAgcmV0dXJuIG5ldyBBc3NldChuZXcgSFRUUFNvdXJjZSh1cmwsIG9wdHMpKTtcbiAgICB9O1xuXG4gICAgQXNzZXQuZnJvbUZpbGUgPSBmdW5jdGlvbihmaWxlKSB7XG4gICAgICByZXR1cm4gbmV3IEFzc2V0KG5ldyBGaWxlU291cmNlKGZpbGUpKTtcbiAgICB9O1xuXG4gICAgQXNzZXQuZnJvbUJ1ZmZlciA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgcmV0dXJuIG5ldyBBc3NldChuZXcgQnVmZmVyU291cmNlKGJ1ZmZlcikpO1xuICAgIH07XG5cbiAgICBBc3NldC5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbihkZWNvZGUpIHtcbiAgICAgIGlmICh0aGlzLmFjdGl2ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoZGVjb2RlICE9IG51bGwpIHtcbiAgICAgICAgdGhpcy5zaG91bGREZWNvZGUgPSBkZWNvZGU7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5zaG91bGREZWNvZGUgPT0gbnVsbCkge1xuICAgICAgICB0aGlzLnNob3VsZERlY29kZSA9IHRydWU7XG4gICAgICB9XG4gICAgICB0aGlzLmFjdGl2ZSA9IHRydWU7XG4gICAgICB0aGlzLnNvdXJjZS5zdGFydCgpO1xuICAgICAgaWYgKHRoaXMuZGVjb2RlciAmJiB0aGlzLnNob3VsZERlY29kZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVjb2RlKCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIEFzc2V0LnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoIXRoaXMuYWN0aXZlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuYWN0aXZlID0gZmFsc2U7XG4gICAgICByZXR1cm4gdGhpcy5zb3VyY2UucGF1c2UoKTtcbiAgICB9O1xuXG4gICAgQXNzZXQucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKGV2ZW50LCBjYWxsYmFjaykge1xuICAgICAgaWYgKGV2ZW50ICE9PSAnZm9ybWF0JyAmJiBldmVudCAhPT0gJ2R1cmF0aW9uJyAmJiBldmVudCAhPT0gJ21ldGFkYXRhJykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAodGhpc1tldmVudF0gIT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gY2FsbGJhY2sodGhpc1tldmVudF0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5vbmNlKGV2ZW50LCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgICByZXR1cm4gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgICAgIF90aGlzLnN0b3AoKTtcbiAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayh2YWx1ZSk7XG4gICAgICAgICAgfTtcbiAgICAgICAgfSkodGhpcykpO1xuICAgICAgICByZXR1cm4gdGhpcy5zdGFydCgpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBBc3NldC5wcm90b3R5cGUuZGVjb2RlUGFja2V0ID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5kZWNvZGVyLmRlY29kZSgpO1xuICAgIH07XG5cbiAgICBBc3NldC5wcm90b3R5cGUuZGVjb2RlVG9CdWZmZXIgPSBmdW5jdGlvbihjYWxsYmFjaykge1xuICAgICAgdmFyIGNodW5rcywgZGF0YUhhbmRsZXIsIGxlbmd0aDtcbiAgICAgIGxlbmd0aCA9IDA7XG4gICAgICBjaHVua3MgPSBbXTtcbiAgICAgIHRoaXMub24oJ2RhdGEnLCBkYXRhSGFuZGxlciA9IGZ1bmN0aW9uKGNodW5rKSB7XG4gICAgICAgIGxlbmd0aCArPSBjaHVuay5sZW5ndGg7XG4gICAgICAgIHJldHVybiBjaHVua3MucHVzaChjaHVuayk7XG4gICAgICB9KTtcbiAgICAgIHRoaXMub25jZSgnZW5kJywgZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBidWYsIGNodW5rLCBvZmZzZXQsIF9pLCBfbGVuO1xuICAgICAgICBidWYgPSBuZXcgRmxvYXQzMkFycmF5KGxlbmd0aCk7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICAgIGZvciAoX2kgPSAwLCBfbGVuID0gY2h1bmtzLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgICAgY2h1bmsgPSBjaHVua3NbX2ldO1xuICAgICAgICAgIGJ1Zi5zZXQoY2h1bmssIG9mZnNldCk7XG4gICAgICAgICAgb2Zmc2V0ICs9IGNodW5rLmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9mZignZGF0YScsIGRhdGFIYW5kbGVyKTtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGJ1Zik7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiB0aGlzLnN0YXJ0KCk7XG4gICAgfTtcblxuICAgIEFzc2V0LnByb3RvdHlwZS5wcm9iZSA9IGZ1bmN0aW9uKGNodW5rKSB7XG4gICAgICB2YXIgZGVtdXhlcjtcbiAgICAgIGlmICghdGhpcy5hY3RpdmUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgZGVtdXhlciA9IERlbXV4ZXIuZmluZChjaHVuayk7XG4gICAgICBpZiAoIWRlbXV4ZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnQSBkZW11eGVyIGZvciB0aGlzIGNvbnRhaW5lciB3YXMgbm90IGZvdW5kLicpO1xuICAgICAgfVxuICAgICAgdGhpcy5kZW11eGVyID0gbmV3IGRlbXV4ZXIodGhpcy5zb3VyY2UsIGNodW5rKTtcbiAgICAgIHRoaXMuZGVtdXhlci5vbignZm9ybWF0JywgdGhpcy5maW5kRGVjb2Rlcik7XG4gICAgICB0aGlzLmRlbXV4ZXIub24oJ2R1cmF0aW9uJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihkdXJhdGlvbikge1xuICAgICAgICAgIF90aGlzLmR1cmF0aW9uID0gZHVyYXRpb247XG4gICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ2R1cmF0aW9uJywgX3RoaXMuZHVyYXRpb24pO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5kZW11eGVyLm9uKCdtZXRhZGF0YScsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24obWV0YWRhdGEpIHtcbiAgICAgICAgICBfdGhpcy5tZXRhZGF0YSA9IG1ldGFkYXRhO1xuICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdtZXRhZGF0YScsIF90aGlzLm1ldGFkYXRhKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHJldHVybiB0aGlzLmRlbXV4ZXIub24oJ2Vycm9yJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihlcnIpIHtcbiAgICAgICAgICBfdGhpcy5lbWl0KCdlcnJvcicsIGVycik7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLnN0b3AoKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICB9O1xuXG4gICAgQXNzZXQucHJvdG90eXBlLmZpbmREZWNvZGVyID0gZnVuY3Rpb24oZm9ybWF0KSB7XG4gICAgICB2YXIgZGVjb2RlciwgZGl2O1xuICAgICAgdGhpcy5mb3JtYXQgPSBmb3JtYXQ7XG4gICAgICBpZiAoIXRoaXMuYWN0aXZlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuZW1pdCgnZm9ybWF0JywgdGhpcy5mb3JtYXQpO1xuICAgICAgZGVjb2RlciA9IERlY29kZXIuZmluZCh0aGlzLmZvcm1hdC5mb3JtYXRJRCk7XG4gICAgICBpZiAoIWRlY29kZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCBcIkEgZGVjb2RlciBmb3IgXCIgKyB0aGlzLmZvcm1hdC5mb3JtYXRJRCArIFwiIHdhcyBub3QgZm91bmQuXCIpO1xuICAgICAgfVxuICAgICAgdGhpcy5kZWNvZGVyID0gbmV3IGRlY29kZXIodGhpcy5kZW11eGVyLCB0aGlzLmZvcm1hdCk7XG4gICAgICBpZiAodGhpcy5mb3JtYXQuZmxvYXRpbmdQb2ludCkge1xuICAgICAgICB0aGlzLmRlY29kZXIub24oJ2RhdGEnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnZGF0YScsIGJ1ZmZlcik7XG4gICAgICAgICAgfTtcbiAgICAgICAgfSkodGhpcykpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGl2ID0gTWF0aC5wb3coMiwgdGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwgLSAxKTtcbiAgICAgICAgdGhpcy5kZWNvZGVyLm9uKCdkYXRhJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgICAgICAgdmFyIGJ1ZiwgaSwgc2FtcGxlLCBfaSwgX2xlbjtcbiAgICAgICAgICAgIGJ1ZiA9IG5ldyBGbG9hdDMyQXJyYXkoYnVmZmVyLmxlbmd0aCk7XG4gICAgICAgICAgICBmb3IgKGkgPSBfaSA9IDAsIF9sZW4gPSBidWZmZXIubGVuZ3RoOyBfaSA8IF9sZW47IGkgPSArK19pKSB7XG4gICAgICAgICAgICAgIHNhbXBsZSA9IGJ1ZmZlcltpXTtcbiAgICAgICAgICAgICAgYnVmW2ldID0gc2FtcGxlIC8gZGl2O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ2RhdGEnLCBidWYpO1xuICAgICAgICAgIH07XG4gICAgICAgIH0pKHRoaXMpKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZGVjb2Rlci5vbignZXJyb3InLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGVycikge1xuICAgICAgICAgIF90aGlzLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuc3RvcCgpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5kZWNvZGVyLm9uKCdlbmQnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdlbmQnKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHRoaXMuZW1pdCgnZGVjb2RlU3RhcnQnKTtcbiAgICAgIGlmICh0aGlzLnNob3VsZERlY29kZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVjb2RlKCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIEFzc2V0LnByb3RvdHlwZS5fZGVjb2RlID0gZnVuY3Rpb24oKSB7XG4gICAgICB3aGlsZSAodGhpcy5kZWNvZGVyLmRlY29kZSgpICYmIHRoaXMuYWN0aXZlKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuYWN0aXZlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRlY29kZXIub25jZSgnZGF0YScsIHRoaXMuX2RlY29kZSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIEFzc2V0LnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgX3JlZiwgX3JlZjEsIF9yZWYyO1xuICAgICAgdGhpcy5zdG9wKCk7XG4gICAgICBpZiAoKF9yZWYgPSB0aGlzLmRlbXV4ZXIpICE9IG51bGwpIHtcbiAgICAgICAgX3JlZi5vZmYoKTtcbiAgICAgIH1cbiAgICAgIGlmICgoX3JlZjEgPSB0aGlzLmRlY29kZXIpICE9IG51bGwpIHtcbiAgICAgICAgX3JlZjEub2ZmKCk7XG4gICAgICB9XG4gICAgICBpZiAoKF9yZWYyID0gdGhpcy5zb3VyY2UpICE9IG51bGwpIHtcbiAgICAgICAgX3JlZjIub2ZmKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5vZmYoKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIEFzc2V0O1xuXG4gIH0pKEV2ZW50RW1pdHRlcik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBBc3NldDtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS43LjFcbihmdW5jdGlvbigpIHtcbiAgdmFyIGtleSwgdmFsLCBfcmVmO1xuXG4gIF9yZWYgPSByZXF1aXJlKCcuL2F1cm9yYV9iYXNlJyk7XG4gIGZvciAoa2V5IGluIF9yZWYpIHtcbiAgICB2YWwgPSBfcmVmW2tleV07XG4gICAgZXhwb3J0c1trZXldID0gdmFsO1xuICB9XG5cbiAgcmVxdWlyZSgnLi9kZW11eGVycy9jYWYnKTtcblxuICByZXF1aXJlKCcuL2RlbXV4ZXJzL200YScpO1xuXG4gIHJlcXVpcmUoJy4vZGVtdXhlcnMvYWlmZicpO1xuXG4gIHJlcXVpcmUoJy4vZGVtdXhlcnMvd2F2ZScpO1xuXG4gIHJlcXVpcmUoJy4vZGVtdXhlcnMvYXUnKTtcblxuICByZXF1aXJlKCcuL2RlY29kZXJzL2xwY20nKTtcblxuICByZXF1aXJlKCcuL2RlY29kZXJzL3hsYXcnKTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS43LjFcbihmdW5jdGlvbigpIHtcbiAgZXhwb3J0cy5CYXNlID0gcmVxdWlyZSgnLi9jb3JlL2Jhc2UnKTtcblxuICBleHBvcnRzLkJ1ZmZlciA9IHJlcXVpcmUoJy4vY29yZS9idWZmZXInKTtcblxuICBleHBvcnRzLkJ1ZmZlckxpc3QgPSByZXF1aXJlKCcuL2NvcmUvYnVmZmVybGlzdCcpO1xuXG4gIGV4cG9ydHMuU3RyZWFtID0gcmVxdWlyZSgnLi9jb3JlL3N0cmVhbScpO1xuXG4gIGV4cG9ydHMuQml0c3RyZWFtID0gcmVxdWlyZSgnLi9jb3JlL2JpdHN0cmVhbScpO1xuXG4gIGV4cG9ydHMuRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnLi9jb3JlL2V2ZW50cycpO1xuXG4gIGV4cG9ydHMuVW5kZXJmbG93RXJyb3IgPSByZXF1aXJlKCcuL2NvcmUvdW5kZXJmbG93Jyk7XG5cbiAgZXhwb3J0cy5IVFRQU291cmNlID0gcmVxdWlyZSgnLi9zb3VyY2VzL25vZGUvaHR0cCcpO1xuXG4gIGV4cG9ydHMuRmlsZVNvdXJjZSA9IHJlcXVpcmUoJy4vc291cmNlcy9ub2RlL2ZpbGUnKTtcblxuICBleHBvcnRzLkJ1ZmZlclNvdXJjZSA9IHJlcXVpcmUoJy4vc291cmNlcy9idWZmZXInKTtcblxuICBleHBvcnRzLkRlbXV4ZXIgPSByZXF1aXJlKCcuL2RlbXV4ZXInKTtcblxuICBleHBvcnRzLkRlY29kZXIgPSByZXF1aXJlKCcuL2RlY29kZXInKTtcblxuICBleHBvcnRzLkF1ZGlvRGV2aWNlID0gcmVxdWlyZSgnLi9kZXZpY2UnKTtcblxuICBleHBvcnRzLkFzc2V0ID0gcmVxdWlyZSgnLi9hc3NldCcpO1xuXG4gIGV4cG9ydHMuUGxheWVyID0gcmVxdWlyZSgnLi9wbGF5ZXInKTtcblxuICBleHBvcnRzLkZpbHRlciA9IHJlcXVpcmUoJy4vZmlsdGVyJyk7XG5cbiAgZXhwb3J0cy5Wb2x1bWVGaWx0ZXIgPSByZXF1aXJlKCcuL2ZpbHRlcnMvdm9sdW1lJyk7XG5cbiAgZXhwb3J0cy5CYWxhbmNlRmlsdGVyID0gcmVxdWlyZSgnLi9maWx0ZXJzL2JhbGFuY2UnKTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS43LjFcbihmdW5jdGlvbigpIHtcbiAgdmFyIEJhc2UsXG4gICAgX19oYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHksXG4gICAgX19leHRlbmRzID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChfX2hhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgX19pbmRleE9mID0gW10uaW5kZXhPZiB8fCBmdW5jdGlvbihpdGVtKSB7IGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy5sZW5ndGg7IGkgPCBsOyBpKyspIHsgaWYgKGkgaW4gdGhpcyAmJiB0aGlzW2ldID09PSBpdGVtKSByZXR1cm4gaTsgfSByZXR1cm4gLTE7IH07XG5cbiAgQmFzZSA9IChmdW5jdGlvbigpIHtcbiAgICB2YXIgZm5UZXN0O1xuXG4gICAgZnVuY3Rpb24gQmFzZSgpIHt9XG5cbiAgICBmblRlc3QgPSAvXFxiX3N1cGVyXFxiLztcblxuICAgIEJhc2UuZXh0ZW5kID0gZnVuY3Rpb24ocHJvcCkge1xuICAgICAgdmFyIENsYXNzLCBmbiwga2V5LCBrZXlzLCBfcmVmLCBfc3VwZXI7XG4gICAgICBDbGFzcyA9IChmdW5jdGlvbihfc3VwZXIpIHtcbiAgICAgICAgX19leHRlbmRzKENsYXNzLCBfc3VwZXIpO1xuXG4gICAgICAgIGZ1bmN0aW9uIENsYXNzKCkge1xuICAgICAgICAgIHJldHVybiBDbGFzcy5fX3N1cGVyX18uY29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBDbGFzcztcblxuICAgICAgfSkodGhpcyk7XG4gICAgICBpZiAodHlwZW9mIHByb3AgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAga2V5cyA9IE9iamVjdC5rZXlzKENsYXNzLnByb3RvdHlwZSk7XG4gICAgICAgIHByb3AuY2FsbChDbGFzcywgQ2xhc3MpO1xuICAgICAgICBwcm9wID0ge307XG4gICAgICAgIF9yZWYgPSBDbGFzcy5wcm90b3R5cGU7XG4gICAgICAgIGZvciAoa2V5IGluIF9yZWYpIHtcbiAgICAgICAgICBmbiA9IF9yZWZba2V5XTtcbiAgICAgICAgICBpZiAoX19pbmRleE9mLmNhbGwoa2V5cywga2V5KSA8IDApIHtcbiAgICAgICAgICAgIHByb3Bba2V5XSA9IGZuO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgX3N1cGVyID0gQ2xhc3MuX19zdXBlcl9fO1xuICAgICAgZm9yIChrZXkgaW4gcHJvcCkge1xuICAgICAgICBmbiA9IHByb3Bba2V5XTtcbiAgICAgICAgaWYgKHR5cGVvZiBmbiA9PT0gJ2Z1bmN0aW9uJyAmJiBmblRlc3QudGVzdChmbikpIHtcbiAgICAgICAgICAoZnVuY3Rpb24oa2V5LCBmbikge1xuICAgICAgICAgICAgcmV0dXJuIENsYXNzLnByb3RvdHlwZVtrZXldID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgIHZhciByZXQsIHRtcDtcbiAgICAgICAgICAgICAgdG1wID0gdGhpcy5fc3VwZXI7XG4gICAgICAgICAgICAgIHRoaXMuX3N1cGVyID0gX3N1cGVyW2tleV07XG4gICAgICAgICAgICAgIHJldCA9IGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICAgIHRoaXMuX3N1cGVyID0gdG1wO1xuICAgICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9KShrZXksIGZuKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBDbGFzcy5wcm90b3R5cGVba2V5XSA9IGZuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gQ2xhc3M7XG4gICAgfTtcblxuICAgIHJldHVybiBCYXNlO1xuXG4gIH0pKCk7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBCYXNlO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjcuMVxuKGZ1bmN0aW9uKCkge1xuICB2YXIgQml0c3RyZWFtO1xuXG4gIEJpdHN0cmVhbSA9IChmdW5jdGlvbigpIHtcbiAgICBmdW5jdGlvbiBCaXRzdHJlYW0oc3RyZWFtKSB7XG4gICAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgIHRoaXMuYml0UG9zaXRpb24gPSAwO1xuICAgIH1cblxuICAgIEJpdHN0cmVhbS5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlc3VsdDtcbiAgICAgIHJlc3VsdCA9IG5ldyBCaXRzdHJlYW0odGhpcy5zdHJlYW0uY29weSgpKTtcbiAgICAgIHJlc3VsdC5iaXRQb3NpdGlvbiA9IHRoaXMuYml0UG9zaXRpb247XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICBCaXRzdHJlYW0ucHJvdG90eXBlLm9mZnNldCA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIDggKiB0aGlzLnN0cmVhbS5vZmZzZXQgKyB0aGlzLmJpdFBvc2l0aW9uO1xuICAgIH07XG5cbiAgICBCaXRzdHJlYW0ucHJvdG90eXBlLmF2YWlsYWJsZSA9IGZ1bmN0aW9uKGJpdHMpIHtcbiAgICAgIHJldHVybiB0aGlzLnN0cmVhbS5hdmFpbGFibGUoKGJpdHMgKyA4IC0gdGhpcy5iaXRQb3NpdGlvbikgLyA4KTtcbiAgICB9O1xuXG4gICAgQml0c3RyZWFtLnByb3RvdHlwZS5hZHZhbmNlID0gZnVuY3Rpb24oYml0cykge1xuICAgICAgdmFyIHBvcztcbiAgICAgIHBvcyA9IHRoaXMuYml0UG9zaXRpb24gKyBiaXRzO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZShwb3MgPj4gMyk7XG4gICAgICByZXR1cm4gdGhpcy5iaXRQb3NpdGlvbiA9IHBvcyAmIDc7XG4gICAgfTtcblxuICAgIEJpdHN0cmVhbS5wcm90b3R5cGUucmV3aW5kID0gZnVuY3Rpb24oYml0cykge1xuICAgICAgdmFyIHBvcztcbiAgICAgIHBvcyA9IHRoaXMuYml0UG9zaXRpb24gLSBiaXRzO1xuICAgICAgdGhpcy5zdHJlYW0ucmV3aW5kKE1hdGguYWJzKHBvcyA+PiAzKSk7XG4gICAgICByZXR1cm4gdGhpcy5iaXRQb3NpdGlvbiA9IHBvcyAmIDc7XG4gICAgfTtcblxuICAgIEJpdHN0cmVhbS5wcm90b3R5cGUuc2VlayA9IGZ1bmN0aW9uKG9mZnNldCkge1xuICAgICAgdmFyIGN1ck9mZnNldDtcbiAgICAgIGN1ck9mZnNldCA9IHRoaXMub2Zmc2V0KCk7XG4gICAgICBpZiAob2Zmc2V0ID4gY3VyT2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFkdmFuY2Uob2Zmc2V0IC0gY3VyT2Zmc2V0KTtcbiAgICAgIH0gZWxzZSBpZiAob2Zmc2V0IDwgY3VyT2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJld2luZChjdXJPZmZzZXQgLSBvZmZzZXQpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBCaXRzdHJlYW0ucHJvdG90eXBlLmFsaWduID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5iaXRQb3NpdGlvbiAhPT0gMCkge1xuICAgICAgICB0aGlzLmJpdFBvc2l0aW9uID0gMDtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RyZWFtLmFkdmFuY2UoMSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIEJpdHN0cmVhbS5wcm90b3R5cGUucmVhZCA9IGZ1bmN0aW9uKGJpdHMsIHNpZ25lZCkge1xuICAgICAgdmFyIGEsIGEwLCBhMSwgYTIsIGEzLCBhNCwgbUJpdHM7XG4gICAgICBpZiAoYml0cyA9PT0gMCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICAgIG1CaXRzID0gYml0cyArIHRoaXMuYml0UG9zaXRpb247XG4gICAgICBpZiAobUJpdHMgPD0gOCkge1xuICAgICAgICBhID0gKCh0aGlzLnN0cmVhbS5wZWVrVUludDgoKSA8PCB0aGlzLmJpdFBvc2l0aW9uKSAmIDB4ZmYpID4+PiAoOCAtIGJpdHMpO1xuICAgICAgfSBlbHNlIGlmIChtQml0cyA8PSAxNikge1xuICAgICAgICBhID0gKCh0aGlzLnN0cmVhbS5wZWVrVUludDE2KCkgPDwgdGhpcy5iaXRQb3NpdGlvbikgJiAweGZmZmYpID4+PiAoMTYgLSBiaXRzKTtcbiAgICAgIH0gZWxzZSBpZiAobUJpdHMgPD0gMjQpIHtcbiAgICAgICAgYSA9ICgodGhpcy5zdHJlYW0ucGVla1VJbnQyNCgpIDw8IHRoaXMuYml0UG9zaXRpb24pICYgMHhmZmZmZmYpID4+PiAoMjQgLSBiaXRzKTtcbiAgICAgIH0gZWxzZSBpZiAobUJpdHMgPD0gMzIpIHtcbiAgICAgICAgYSA9ICh0aGlzLnN0cmVhbS5wZWVrVUludDMyKCkgPDwgdGhpcy5iaXRQb3NpdGlvbikgPj4+ICgzMiAtIGJpdHMpO1xuICAgICAgfSBlbHNlIGlmIChtQml0cyA8PSA0MCkge1xuICAgICAgICBhMCA9IHRoaXMuc3RyZWFtLnBlZWtVSW50OCgwKSAqIDB4MDEwMDAwMDAwMDtcbiAgICAgICAgYTEgPSB0aGlzLnN0cmVhbS5wZWVrVUludDgoMSkgPDwgMjQgPj4+IDA7XG4gICAgICAgIGEyID0gdGhpcy5zdHJlYW0ucGVla1VJbnQ4KDIpIDw8IDE2O1xuICAgICAgICBhMyA9IHRoaXMuc3RyZWFtLnBlZWtVSW50OCgzKSA8PCA4O1xuICAgICAgICBhNCA9IHRoaXMuc3RyZWFtLnBlZWtVSW50OCg0KTtcbiAgICAgICAgYSA9IGEwICsgYTEgKyBhMiArIGEzICsgYTQ7XG4gICAgICAgIGEgJT0gTWF0aC5wb3coMiwgNDAgLSB0aGlzLmJpdFBvc2l0aW9uKTtcbiAgICAgICAgYSA9IE1hdGguZmxvb3IoYSAvIE1hdGgucG93KDIsIDQwIC0gdGhpcy5iaXRQb3NpdGlvbiAtIGJpdHMpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRvbyBtYW55IGJpdHMhXCIpO1xuICAgICAgfVxuICAgICAgaWYgKHNpZ25lZCkge1xuICAgICAgICBpZiAobUJpdHMgPCAzMikge1xuICAgICAgICAgIGlmIChhID4+PiAoYml0cyAtIDEpKSB7XG4gICAgICAgICAgICBhID0gKCgxIDw8IGJpdHMgPj4+IDApIC0gYSkgKiAtMTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKGEgLyBNYXRoLnBvdygyLCBiaXRzIC0gMSkgfCAwKSB7XG4gICAgICAgICAgICBhID0gKE1hdGgucG93KDIsIGJpdHMpIC0gYSkgKiAtMTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMuYWR2YW5jZShiaXRzKTtcbiAgICAgIHJldHVybiBhO1xuICAgIH07XG5cbiAgICBCaXRzdHJlYW0ucHJvdG90eXBlLnBlZWsgPSBmdW5jdGlvbihiaXRzLCBzaWduZWQpIHtcbiAgICAgIHZhciBhLCBhMCwgYTEsIGEyLCBhMywgYTQsIG1CaXRzO1xuICAgICAgaWYgKGJpdHMgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG4gICAgICBtQml0cyA9IGJpdHMgKyB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgaWYgKG1CaXRzIDw9IDgpIHtcbiAgICAgICAgYSA9ICgodGhpcy5zdHJlYW0ucGVla1VJbnQ4KCkgPDwgdGhpcy5iaXRQb3NpdGlvbikgJiAweGZmKSA+Pj4gKDggLSBiaXRzKTtcbiAgICAgIH0gZWxzZSBpZiAobUJpdHMgPD0gMTYpIHtcbiAgICAgICAgYSA9ICgodGhpcy5zdHJlYW0ucGVla1VJbnQxNigpIDw8IHRoaXMuYml0UG9zaXRpb24pICYgMHhmZmZmKSA+Pj4gKDE2IC0gYml0cyk7XG4gICAgICB9IGVsc2UgaWYgKG1CaXRzIDw9IDI0KSB7XG4gICAgICAgIGEgPSAoKHRoaXMuc3RyZWFtLnBlZWtVSW50MjQoKSA8PCB0aGlzLmJpdFBvc2l0aW9uKSAmIDB4ZmZmZmZmKSA+Pj4gKDI0IC0gYml0cyk7XG4gICAgICB9IGVsc2UgaWYgKG1CaXRzIDw9IDMyKSB7XG4gICAgICAgIGEgPSAodGhpcy5zdHJlYW0ucGVla1VJbnQzMigpIDw8IHRoaXMuYml0UG9zaXRpb24pID4+PiAoMzIgLSBiaXRzKTtcbiAgICAgIH0gZWxzZSBpZiAobUJpdHMgPD0gNDApIHtcbiAgICAgICAgYTAgPSB0aGlzLnN0cmVhbS5wZWVrVUludDgoMCkgKiAweDAxMDAwMDAwMDA7XG4gICAgICAgIGExID0gdGhpcy5zdHJlYW0ucGVla1VJbnQ4KDEpIDw8IDI0ID4+PiAwO1xuICAgICAgICBhMiA9IHRoaXMuc3RyZWFtLnBlZWtVSW50OCgyKSA8PCAxNjtcbiAgICAgICAgYTMgPSB0aGlzLnN0cmVhbS5wZWVrVUludDgoMykgPDwgODtcbiAgICAgICAgYTQgPSB0aGlzLnN0cmVhbS5wZWVrVUludDgoNCk7XG4gICAgICAgIGEgPSBhMCArIGExICsgYTIgKyBhMyArIGE0O1xuICAgICAgICBhICU9IE1hdGgucG93KDIsIDQwIC0gdGhpcy5iaXRQb3NpdGlvbik7XG4gICAgICAgIGEgPSBNYXRoLmZsb29yKGEgLyBNYXRoLnBvdygyLCA0MCAtIHRoaXMuYml0UG9zaXRpb24gLSBiaXRzKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUb28gbWFueSBiaXRzIVwiKTtcbiAgICAgIH1cbiAgICAgIGlmIChzaWduZWQpIHtcbiAgICAgICAgaWYgKG1CaXRzIDwgMzIpIHtcbiAgICAgICAgICBpZiAoYSA+Pj4gKGJpdHMgLSAxKSkge1xuICAgICAgICAgICAgYSA9ICgoMSA8PCBiaXRzID4+PiAwKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChhIC8gTWF0aC5wb3coMiwgYml0cyAtIDEpIHwgMCkge1xuICAgICAgICAgICAgYSA9IChNYXRoLnBvdygyLCBiaXRzKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gYTtcbiAgICB9O1xuXG4gICAgQml0c3RyZWFtLnByb3RvdHlwZS5yZWFkTFNCID0gZnVuY3Rpb24oYml0cywgc2lnbmVkKSB7XG4gICAgICB2YXIgYSwgbUJpdHM7XG4gICAgICBpZiAoYml0cyA9PT0gMCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICAgIGlmIChiaXRzID4gNDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVG9vIG1hbnkgYml0cyFcIik7XG4gICAgICB9XG4gICAgICBtQml0cyA9IGJpdHMgKyB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgYSA9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMCkpID4+PiB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgaWYgKG1CaXRzID4gOCkge1xuICAgICAgICBhIHw9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMSkpIDw8ICg4IC0gdGhpcy5iaXRQb3NpdGlvbik7XG4gICAgICB9XG4gICAgICBpZiAobUJpdHMgPiAxNikge1xuICAgICAgICBhIHw9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMikpIDw8ICgxNiAtIHRoaXMuYml0UG9zaXRpb24pO1xuICAgICAgfVxuICAgICAgaWYgKG1CaXRzID4gMjQpIHtcbiAgICAgICAgYSArPSAodGhpcy5zdHJlYW0ucGVla1VJbnQ4KDMpKSA8PCAoMjQgLSB0aGlzLmJpdFBvc2l0aW9uKSA+Pj4gMDtcbiAgICAgIH1cbiAgICAgIGlmIChtQml0cyA+IDMyKSB7XG4gICAgICAgIGEgKz0gKHRoaXMuc3RyZWFtLnBlZWtVSW50OCg0KSkgKiBNYXRoLnBvdygyLCAzMiAtIHRoaXMuYml0UG9zaXRpb24pO1xuICAgICAgfVxuICAgICAgaWYgKG1CaXRzID49IDMyKSB7XG4gICAgICAgIGEgJT0gTWF0aC5wb3coMiwgYml0cyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhICY9ICgxIDw8IGJpdHMpIC0gMTtcbiAgICAgIH1cbiAgICAgIGlmIChzaWduZWQpIHtcbiAgICAgICAgaWYgKG1CaXRzIDwgMzIpIHtcbiAgICAgICAgICBpZiAoYSA+Pj4gKGJpdHMgLSAxKSkge1xuICAgICAgICAgICAgYSA9ICgoMSA8PCBiaXRzID4+PiAwKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChhIC8gTWF0aC5wb3coMiwgYml0cyAtIDEpIHwgMCkge1xuICAgICAgICAgICAgYSA9IChNYXRoLnBvdygyLCBiaXRzKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLmFkdmFuY2UoYml0cyk7XG4gICAgICByZXR1cm4gYTtcbiAgICB9O1xuXG4gICAgQml0c3RyZWFtLnByb3RvdHlwZS5wZWVrTFNCID0gZnVuY3Rpb24oYml0cywgc2lnbmVkKSB7XG4gICAgICB2YXIgYSwgbUJpdHM7XG4gICAgICBpZiAoYml0cyA9PT0gMCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICAgIGlmIChiaXRzID4gNDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVG9vIG1hbnkgYml0cyFcIik7XG4gICAgICB9XG4gICAgICBtQml0cyA9IGJpdHMgKyB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgYSA9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMCkpID4+PiB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgaWYgKG1CaXRzID4gOCkge1xuICAgICAgICBhIHw9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMSkpIDw8ICg4IC0gdGhpcy5iaXRQb3NpdGlvbik7XG4gICAgICB9XG4gICAgICBpZiAobUJpdHMgPiAxNikge1xuICAgICAgICBhIHw9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMikpIDw8ICgxNiAtIHRoaXMuYml0UG9zaXRpb24pO1xuICAgICAgfVxuICAgICAgaWYgKG1CaXRzID4gMjQpIHtcbiAgICAgICAgYSArPSAodGhpcy5zdHJlYW0ucGVla1VJbnQ4KDMpKSA8PCAoMjQgLSB0aGlzLmJpdFBvc2l0aW9uKSA+Pj4gMDtcbiAgICAgIH1cbiAgICAgIGlmIChtQml0cyA+IDMyKSB7XG4gICAgICAgIGEgKz0gKHRoaXMuc3RyZWFtLnBlZWtVSW50OCg0KSkgKiBNYXRoLnBvdygyLCAzMiAtIHRoaXMuYml0UG9zaXRpb24pO1xuICAgICAgfVxuICAgICAgaWYgKG1CaXRzID49IDMyKSB7XG4gICAgICAgIGEgJT0gTWF0aC5wb3coMiwgYml0cyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhICY9ICgxIDw8IGJpdHMpIC0gMTtcbiAgICAgIH1cbiAgICAgIGlmIChzaWduZWQpIHtcbiAgICAgICAgaWYgKG1CaXRzIDwgMzIpIHtcbiAgICAgICAgICBpZiAoYSA+Pj4gKGJpdHMgLSAxKSkge1xuICAgICAgICAgICAgYSA9ICgoMSA8PCBiaXRzID4+PiAwKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChhIC8gTWF0aC5wb3coMiwgYml0cyAtIDEpIHwgMCkge1xuICAgICAgICAgICAgYSA9IChNYXRoLnBvdygyLCBiaXRzKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gYTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIEJpdHN0cmVhbTtcblxuICB9KSgpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gQml0c3RyZWFtO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjcuMVxuKGZ1bmN0aW9uKCkge1xuICB2YXIgQVZCdWZmZXI7XG5cbiAgQVZCdWZmZXIgPSAoZnVuY3Rpb24oKSB7XG4gICAgdmFyIEJsb2JCdWlsZGVyLCBVUkw7XG5cbiAgICBmdW5jdGlvbiBBVkJ1ZmZlcihpbnB1dCkge1xuICAgICAgdmFyIF9yZWY7XG4gICAgICBpZiAoaW5wdXQgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgICAgIHRoaXMuZGF0YSA9IGlucHV0O1xuICAgICAgfSBlbHNlIGlmIChpbnB1dCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyIHx8IEFycmF5LmlzQXJyYXkoaW5wdXQpIHx8IHR5cGVvZiBpbnB1dCA9PT0gJ251bWJlcicgfHwgKChfcmVmID0gZ2xvYmFsLkJ1ZmZlcikgIT0gbnVsbCA/IF9yZWYuaXNCdWZmZXIoaW5wdXQpIDogdm9pZCAwKSkge1xuICAgICAgICB0aGlzLmRhdGEgPSBuZXcgVWludDhBcnJheShpbnB1dCk7XG4gICAgICB9IGVsc2UgaWYgKGlucHV0LmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgICAgIHRoaXMuZGF0YSA9IG5ldyBVaW50OEFycmF5KGlucHV0LmJ1ZmZlciwgaW5wdXQuYnl0ZU9mZnNldCwgaW5wdXQubGVuZ3RoICogaW5wdXQuQllURVNfUEVSX0VMRU1FTlQpO1xuICAgICAgfSBlbHNlIGlmIChpbnB1dCBpbnN0YW5jZW9mIEFWQnVmZmVyKSB7XG4gICAgICAgIHRoaXMuZGF0YSA9IGlucHV0LmRhdGE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb25zdHJ1Y3RpbmcgYnVmZmVyIHdpdGggdW5rbm93biB0eXBlLlwiKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubGVuZ3RoID0gdGhpcy5kYXRhLmxlbmd0aDtcbiAgICAgIHRoaXMubmV4dCA9IG51bGw7XG4gICAgICB0aGlzLnByZXYgPSBudWxsO1xuICAgIH1cblxuICAgIEFWQnVmZmVyLmFsbG9jYXRlID0gZnVuY3Rpb24oc2l6ZSkge1xuICAgICAgcmV0dXJuIG5ldyBBVkJ1ZmZlcihzaXplKTtcbiAgICB9O1xuXG4gICAgQVZCdWZmZXIucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBuZXcgQVZCdWZmZXIobmV3IFVpbnQ4QXJyYXkodGhpcy5kYXRhKSk7XG4gICAgfTtcblxuICAgIEFWQnVmZmVyLnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uKHBvc2l0aW9uLCBsZW5ndGgpIHtcbiAgICAgIGlmIChsZW5ndGggPT0gbnVsbCkge1xuICAgICAgICBsZW5ndGggPSB0aGlzLmxlbmd0aDtcbiAgICAgIH1cbiAgICAgIGlmIChwb3NpdGlvbiA9PT0gMCAmJiBsZW5ndGggPj0gdGhpcy5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBBVkJ1ZmZlcih0aGlzLmRhdGEpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIG5ldyBBVkJ1ZmZlcih0aGlzLmRhdGEuc3ViYXJyYXkocG9zaXRpb24sIHBvc2l0aW9uICsgbGVuZ3RoKSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIEJsb2JCdWlsZGVyID0gZ2xvYmFsLkJsb2JCdWlsZGVyIHx8IGdsb2JhbC5Nb3pCbG9iQnVpbGRlciB8fCBnbG9iYWwuV2ViS2l0QmxvYkJ1aWxkZXI7XG5cbiAgICBVUkwgPSBnbG9iYWwuVVJMIHx8IGdsb2JhbC53ZWJraXRVUkwgfHwgZ2xvYmFsLm1velVSTDtcblxuICAgIEFWQnVmZmVyLm1ha2VCbG9iID0gZnVuY3Rpb24oZGF0YSwgdHlwZSkge1xuICAgICAgdmFyIGJiO1xuICAgICAgaWYgKHR5cGUgPT0gbnVsbCkge1xuICAgICAgICB0eXBlID0gJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSc7XG4gICAgICB9XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gbmV3IEJsb2IoW2RhdGFdLCB7XG4gICAgICAgICAgdHlwZTogdHlwZVxuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2ggKF9lcnJvcikge31cbiAgICAgIGlmIChCbG9iQnVpbGRlciAhPSBudWxsKSB7XG4gICAgICAgIGJiID0gbmV3IEJsb2JCdWlsZGVyO1xuICAgICAgICBiYi5hcHBlbmQoZGF0YSk7XG4gICAgICAgIHJldHVybiBiYi5nZXRCbG9iKHR5cGUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcblxuICAgIEFWQnVmZmVyLm1ha2VCbG9iVVJMID0gZnVuY3Rpb24oZGF0YSwgdHlwZSkge1xuICAgICAgcmV0dXJuIFVSTCAhPSBudWxsID8gVVJMLmNyZWF0ZU9iamVjdFVSTCh0aGlzLm1ha2VCbG9iKGRhdGEsIHR5cGUpKSA6IHZvaWQgMDtcbiAgICB9O1xuXG4gICAgQVZCdWZmZXIucmV2b2tlQmxvYlVSTCA9IGZ1bmN0aW9uKHVybCkge1xuICAgICAgcmV0dXJuIFVSTCAhPSBudWxsID8gVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpIDogdm9pZCAwO1xuICAgIH07XG5cbiAgICBBVkJ1ZmZlci5wcm90b3R5cGUudG9CbG9iID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gQVZCdWZmZXIubWFrZUJsb2IodGhpcy5kYXRhLmJ1ZmZlcik7XG4gICAgfTtcblxuICAgIEFWQnVmZmVyLnByb3RvdHlwZS50b0Jsb2JVUkwgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBBVkJ1ZmZlci5tYWtlQmxvYlVSTCh0aGlzLmRhdGEuYnVmZmVyKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIEFWQnVmZmVyO1xuXG4gIH0pKCk7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBBVkJ1ZmZlcjtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS43LjFcbihmdW5jdGlvbigpIHtcbiAgdmFyIEJ1ZmZlckxpc3Q7XG5cbiAgQnVmZmVyTGlzdCA9IChmdW5jdGlvbigpIHtcbiAgICBmdW5jdGlvbiBCdWZmZXJMaXN0KCkge1xuICAgICAgdGhpcy5maXJzdCA9IG51bGw7XG4gICAgICB0aGlzLmxhc3QgPSBudWxsO1xuICAgICAgdGhpcy5udW1CdWZmZXJzID0gMDtcbiAgICAgIHRoaXMuYXZhaWxhYmxlQnl0ZXMgPSAwO1xuICAgICAgdGhpcy5hdmFpbGFibGVCdWZmZXJzID0gMDtcbiAgICB9XG5cbiAgICBCdWZmZXJMaXN0LnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgcmVzdWx0O1xuICAgICAgcmVzdWx0ID0gbmV3IEJ1ZmZlckxpc3Q7XG4gICAgICByZXN1bHQuZmlyc3QgPSB0aGlzLmZpcnN0O1xuICAgICAgcmVzdWx0Lmxhc3QgPSB0aGlzLmxhc3Q7XG4gICAgICByZXN1bHQubnVtQnVmZmVycyA9IHRoaXMubnVtQnVmZmVycztcbiAgICAgIHJlc3VsdC5hdmFpbGFibGVCeXRlcyA9IHRoaXMuYXZhaWxhYmxlQnl0ZXM7XG4gICAgICByZXN1bHQuYXZhaWxhYmxlQnVmZmVycyA9IHRoaXMuYXZhaWxhYmxlQnVmZmVycztcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxuICAgIEJ1ZmZlckxpc3QucHJvdG90eXBlLmFwcGVuZCA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgdmFyIF9yZWY7XG4gICAgICBidWZmZXIucHJldiA9IHRoaXMubGFzdDtcbiAgICAgIGlmICgoX3JlZiA9IHRoaXMubGFzdCkgIT0gbnVsbCkge1xuICAgICAgICBfcmVmLm5leHQgPSBidWZmZXI7XG4gICAgICB9XG4gICAgICB0aGlzLmxhc3QgPSBidWZmZXI7XG4gICAgICBpZiAodGhpcy5maXJzdCA9PSBudWxsKSB7XG4gICAgICAgIHRoaXMuZmlyc3QgPSBidWZmZXI7XG4gICAgICB9XG4gICAgICB0aGlzLmF2YWlsYWJsZUJ5dGVzICs9IGJ1ZmZlci5sZW5ndGg7XG4gICAgICB0aGlzLmF2YWlsYWJsZUJ1ZmZlcnMrKztcbiAgICAgIHJldHVybiB0aGlzLm51bUJ1ZmZlcnMrKztcbiAgICB9O1xuXG4gICAgQnVmZmVyTGlzdC5wcm90b3R5cGUuYWR2YW5jZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHRoaXMuZmlyc3QpIHtcbiAgICAgICAgdGhpcy5hdmFpbGFibGVCeXRlcyAtPSB0aGlzLmZpcnN0Lmxlbmd0aDtcbiAgICAgICAgdGhpcy5hdmFpbGFibGVCdWZmZXJzLS07XG4gICAgICAgIHRoaXMuZmlyc3QgPSB0aGlzLmZpcnN0Lm5leHQ7XG4gICAgICAgIHJldHVybiB0aGlzLmZpcnN0ICE9IG51bGw7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcblxuICAgIEJ1ZmZlckxpc3QucHJvdG90eXBlLnJld2luZCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIF9yZWY7XG4gICAgICBpZiAodGhpcy5maXJzdCAmJiAhdGhpcy5maXJzdC5wcmV2KSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZmlyc3QgPSAoKF9yZWYgPSB0aGlzLmZpcnN0KSAhPSBudWxsID8gX3JlZi5wcmV2IDogdm9pZCAwKSB8fCB0aGlzLmxhc3Q7XG4gICAgICBpZiAodGhpcy5maXJzdCkge1xuICAgICAgICB0aGlzLmF2YWlsYWJsZUJ5dGVzICs9IHRoaXMuZmlyc3QubGVuZ3RoO1xuICAgICAgICB0aGlzLmF2YWlsYWJsZUJ1ZmZlcnMrKztcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmZpcnN0ICE9IG51bGw7XG4gICAgfTtcblxuICAgIEJ1ZmZlckxpc3QucHJvdG90eXBlLnJlc2V0ID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgX3Jlc3VsdHM7XG4gICAgICBfcmVzdWx0cyA9IFtdO1xuICAgICAgd2hpbGUgKHRoaXMucmV3aW5kKCkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gX3Jlc3VsdHM7XG4gICAgfTtcblxuICAgIHJldHVybiBCdWZmZXJMaXN0O1xuXG4gIH0pKCk7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBCdWZmZXJMaXN0O1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjcuMVxuKGZ1bmN0aW9uKCkge1xuICB2YXIgQmFzZSwgRXZlbnRFbWl0dGVyLFxuICAgIF9faGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5LFxuICAgIF9fZXh0ZW5kcyA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoX19oYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIF9fc2xpY2UgPSBbXS5zbGljZTtcblxuICBCYXNlID0gcmVxdWlyZSgnLi9iYXNlJyk7XG5cbiAgRXZlbnRFbWl0dGVyID0gKGZ1bmN0aW9uKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhFdmVudEVtaXR0ZXIsIF9zdXBlcik7XG5cbiAgICBmdW5jdGlvbiBFdmVudEVtaXR0ZXIoKSB7XG4gICAgICByZXR1cm4gRXZlbnRFbWl0dGVyLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIEV2ZW50RW1pdHRlci5wcm90b3R5cGUub24gPSBmdW5jdGlvbihldmVudCwgZm4pIHtcbiAgICAgIHZhciBfYmFzZTtcbiAgICAgIGlmICh0aGlzLmV2ZW50cyA9PSBudWxsKSB7XG4gICAgICAgIHRoaXMuZXZlbnRzID0ge307XG4gICAgICB9XG4gICAgICBpZiAoKF9iYXNlID0gdGhpcy5ldmVudHMpW2V2ZW50XSA9PSBudWxsKSB7XG4gICAgICAgIF9iYXNlW2V2ZW50XSA9IFtdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuZXZlbnRzW2V2ZW50XS5wdXNoKGZuKTtcbiAgICB9O1xuXG4gICAgRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vZmYgPSBmdW5jdGlvbihldmVudCwgZm4pIHtcbiAgICAgIHZhciBldmVudHMsIGluZGV4LCBfcmVmO1xuICAgICAgaWYgKHRoaXMuZXZlbnRzID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKChfcmVmID0gdGhpcy5ldmVudHMpICE9IG51bGwgPyBfcmVmW2V2ZW50XSA6IHZvaWQgMCkge1xuICAgICAgICBpZiAoZm4gIT0gbnVsbCkge1xuICAgICAgICAgIGluZGV4ID0gdGhpcy5ldmVudHNbZXZlbnRdLmluZGV4T2YoZm4pO1xuICAgICAgICAgIGlmICh+aW5kZXgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmV2ZW50c1tldmVudF0uc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZXZlbnRzW2V2ZW50XTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChldmVudCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBldmVudHMgPSB7fTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbmNlID0gZnVuY3Rpb24oZXZlbnQsIGZuKSB7XG4gICAgICB2YXIgY2I7XG4gICAgICByZXR1cm4gdGhpcy5vbihldmVudCwgY2IgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdGhpcy5vZmYoZXZlbnQsIGNiKTtcbiAgICAgICAgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYXJncywgZXZlbnQsIGZuLCBfaSwgX2xlbiwgX3JlZiwgX3JlZjE7XG4gICAgICBldmVudCA9IGFyZ3VtZW50c1swXSwgYXJncyA9IDIgPD0gYXJndW1lbnRzLmxlbmd0aCA/IF9fc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpIDogW107XG4gICAgICBpZiAoISgoX3JlZiA9IHRoaXMuZXZlbnRzKSAhPSBudWxsID8gX3JlZltldmVudF0gOiB2b2lkIDApKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIF9yZWYxID0gdGhpcy5ldmVudHNbZXZlbnRdLnNsaWNlKCk7XG4gICAgICBmb3IgKF9pID0gMCwgX2xlbiA9IF9yZWYxLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgIGZuID0gX3JlZjFbX2ldO1xuICAgICAgICBmbi5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIEV2ZW50RW1pdHRlcjtcblxuICB9KShCYXNlKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS43LjFcbihmdW5jdGlvbigpIHtcbiAgdmFyIEFWQnVmZmVyLCBCdWZmZXJMaXN0LCBTdHJlYW0sIFVuZGVyZmxvd0Vycm9yO1xuXG4gIEJ1ZmZlckxpc3QgPSByZXF1aXJlKCcuL2J1ZmZlcmxpc3QnKTtcblxuICBBVkJ1ZmZlciA9IHJlcXVpcmUoJy4vYnVmZmVyJyk7XG5cbiAgVW5kZXJmbG93RXJyb3IgPSByZXF1aXJlKCcuL3VuZGVyZmxvdycpO1xuXG4gIFN0cmVhbSA9IChmdW5jdGlvbigpIHtcbiAgICB2YXIgYnVmLCBkZWNvZGVTdHJpbmcsIGZsb2F0MzIsIGZsb2F0NjQsIGZsb2F0NjRGYWxsYmFjaywgZmxvYXQ4MCwgaW50MTYsIGludDMyLCBpbnQ4LCBuYXRpdmVFbmRpYW4sIHVpbnQxNiwgdWludDMyLCB1aW50ODtcblxuICAgIGJ1ZiA9IG5ldyBBcnJheUJ1ZmZlcigxNik7XG5cbiAgICB1aW50OCA9IG5ldyBVaW50OEFycmF5KGJ1Zik7XG5cbiAgICBpbnQ4ID0gbmV3IEludDhBcnJheShidWYpO1xuXG4gICAgdWludDE2ID0gbmV3IFVpbnQxNkFycmF5KGJ1Zik7XG5cbiAgICBpbnQxNiA9IG5ldyBJbnQxNkFycmF5KGJ1Zik7XG5cbiAgICB1aW50MzIgPSBuZXcgVWludDMyQXJyYXkoYnVmKTtcblxuICAgIGludDMyID0gbmV3IEludDMyQXJyYXkoYnVmKTtcblxuICAgIGZsb2F0MzIgPSBuZXcgRmxvYXQzMkFycmF5KGJ1Zik7XG5cbiAgICBpZiAodHlwZW9mIEZsb2F0NjRBcnJheSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBGbG9hdDY0QXJyYXkgIT09IG51bGwpIHtcbiAgICAgIGZsb2F0NjQgPSBuZXcgRmxvYXQ2NEFycmF5KGJ1Zik7XG4gICAgfVxuXG4gICAgbmF0aXZlRW5kaWFuID0gbmV3IFVpbnQxNkFycmF5KG5ldyBVaW50OEFycmF5KFsweDEyLCAweDM0XSkuYnVmZmVyKVswXSA9PT0gMHgzNDEyO1xuXG4gICAgZnVuY3Rpb24gU3RyZWFtKGxpc3QpIHtcbiAgICAgIHRoaXMubGlzdCA9IGxpc3Q7XG4gICAgICB0aGlzLmxvY2FsT2Zmc2V0ID0gMDtcbiAgICAgIHRoaXMub2Zmc2V0ID0gMDtcbiAgICB9XG5cbiAgICBTdHJlYW0uZnJvbUJ1ZmZlciA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgdmFyIGxpc3Q7XG4gICAgICBsaXN0ID0gbmV3IEJ1ZmZlckxpc3Q7XG4gICAgICBsaXN0LmFwcGVuZChidWZmZXIpO1xuICAgICAgcmV0dXJuIG5ldyBTdHJlYW0obGlzdCk7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlc3VsdDtcbiAgICAgIHJlc3VsdCA9IG5ldyBTdHJlYW0odGhpcy5saXN0LmNvcHkoKSk7XG4gICAgICByZXN1bHQubG9jYWxPZmZzZXQgPSB0aGlzLmxvY2FsT2Zmc2V0O1xuICAgICAgcmVzdWx0Lm9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5hdmFpbGFibGUgPSBmdW5jdGlvbihieXRlcykge1xuICAgICAgcmV0dXJuIGJ5dGVzIDw9IHRoaXMubGlzdC5hdmFpbGFibGVCeXRlcyAtIHRoaXMubG9jYWxPZmZzZXQ7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVtYWluaW5nQnl0ZXMgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLmxpc3QuYXZhaWxhYmxlQnl0ZXMgLSB0aGlzLmxvY2FsT2Zmc2V0O1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLmFkdmFuY2UgPSBmdW5jdGlvbihieXRlcykge1xuICAgICAgaWYgKCF0aGlzLmF2YWlsYWJsZShieXRlcykpIHtcbiAgICAgICAgdGhyb3cgbmV3IFVuZGVyZmxvd0Vycm9yKCk7XG4gICAgICB9XG4gICAgICB0aGlzLmxvY2FsT2Zmc2V0ICs9IGJ5dGVzO1xuICAgICAgdGhpcy5vZmZzZXQgKz0gYnl0ZXM7XG4gICAgICB3aGlsZSAodGhpcy5saXN0LmZpcnN0ICYmIHRoaXMubG9jYWxPZmZzZXQgPj0gdGhpcy5saXN0LmZpcnN0Lmxlbmd0aCkge1xuICAgICAgICB0aGlzLmxvY2FsT2Zmc2V0IC09IHRoaXMubGlzdC5maXJzdC5sZW5ndGg7XG4gICAgICAgIHRoaXMubGlzdC5hZHZhbmNlKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZXdpbmQgPSBmdW5jdGlvbihieXRlcykge1xuICAgICAgaWYgKGJ5dGVzID4gdGhpcy5vZmZzZXQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFVuZGVyZmxvd0Vycm9yKCk7XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMubGlzdC5maXJzdCkge1xuICAgICAgICB0aGlzLmxpc3QucmV3aW5kKCk7XG4gICAgICAgIHRoaXMubG9jYWxPZmZzZXQgPSB0aGlzLmxpc3QuZmlyc3QubGVuZ3RoO1xuICAgICAgfVxuICAgICAgdGhpcy5sb2NhbE9mZnNldCAtPSBieXRlcztcbiAgICAgIHRoaXMub2Zmc2V0IC09IGJ5dGVzO1xuICAgICAgd2hpbGUgKHRoaXMubGlzdC5maXJzdC5wcmV2ICYmIHRoaXMubG9jYWxPZmZzZXQgPCAwKSB7XG4gICAgICAgIHRoaXMubGlzdC5yZXdpbmQoKTtcbiAgICAgICAgdGhpcy5sb2NhbE9mZnNldCArPSB0aGlzLmxpc3QuZmlyc3QubGVuZ3RoO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUuc2VlayA9IGZ1bmN0aW9uKHBvc2l0aW9uKSB7XG4gICAgICBpZiAocG9zaXRpb24gPiB0aGlzLm9mZnNldCkge1xuICAgICAgICByZXR1cm4gdGhpcy5hZHZhbmNlKHBvc2l0aW9uIC0gdGhpcy5vZmZzZXQpO1xuICAgICAgfSBlbHNlIGlmIChwb3NpdGlvbiA8IHRoaXMub2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJld2luZCh0aGlzLm9mZnNldCAtIHBvc2l0aW9uKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkVUludDggPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBhO1xuICAgICAgaWYgKCF0aGlzLmF2YWlsYWJsZSgxKSkge1xuICAgICAgICB0aHJvdyBuZXcgVW5kZXJmbG93RXJyb3IoKTtcbiAgICAgIH1cbiAgICAgIGEgPSB0aGlzLmxpc3QuZmlyc3QuZGF0YVt0aGlzLmxvY2FsT2Zmc2V0XTtcbiAgICAgIHRoaXMubG9jYWxPZmZzZXQgKz0gMTtcbiAgICAgIHRoaXMub2Zmc2V0ICs9IDE7XG4gICAgICBpZiAodGhpcy5sb2NhbE9mZnNldCA9PT0gdGhpcy5saXN0LmZpcnN0Lmxlbmd0aCkge1xuICAgICAgICB0aGlzLmxvY2FsT2Zmc2V0ID0gMDtcbiAgICAgICAgdGhpcy5saXN0LmFkdmFuY2UoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtVSW50OCA9IGZ1bmN0aW9uKG9mZnNldCkge1xuICAgICAgdmFyIGJ1ZmZlcjtcbiAgICAgIGlmIChvZmZzZXQgPT0gbnVsbCkge1xuICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgfVxuICAgICAgaWYgKCF0aGlzLmF2YWlsYWJsZShvZmZzZXQgKyAxKSkge1xuICAgICAgICB0aHJvdyBuZXcgVW5kZXJmbG93RXJyb3IoKTtcbiAgICAgIH1cbiAgICAgIG9mZnNldCA9IHRoaXMubG9jYWxPZmZzZXQgKyBvZmZzZXQ7XG4gICAgICBidWZmZXIgPSB0aGlzLmxpc3QuZmlyc3Q7XG4gICAgICB3aGlsZSAoYnVmZmVyKSB7XG4gICAgICAgIGlmIChidWZmZXIubGVuZ3RoID4gb2Zmc2V0KSB7XG4gICAgICAgICAgcmV0dXJuIGJ1ZmZlci5kYXRhW29mZnNldF07XG4gICAgICAgIH1cbiAgICAgICAgb2Zmc2V0IC09IGJ1ZmZlci5sZW5ndGg7XG4gICAgICAgIGJ1ZmZlciA9IGJ1ZmZlci5uZXh0O1xuICAgICAgfVxuICAgICAgcmV0dXJuIDA7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzLCBsaXR0bGVFbmRpYW4pIHtcbiAgICAgIHZhciBpLCBfaSwgX2osIF9yZWY7XG4gICAgICBpZiAobGl0dGxlRW5kaWFuID09IG51bGwpIHtcbiAgICAgICAgbGl0dGxlRW5kaWFuID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAobGl0dGxlRW5kaWFuID09PSBuYXRpdmVFbmRpYW4pIHtcbiAgICAgICAgZm9yIChpID0gX2kgPSAwOyBfaSA8IGJ5dGVzOyBpID0gX2kgKz0gMSkge1xuICAgICAgICAgIHVpbnQ4W2ldID0gdGhpcy5yZWFkVUludDgoKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm9yIChpID0gX2ogPSBfcmVmID0gYnl0ZXMgLSAxOyBfaiA+PSAwOyBpID0gX2ogKz0gLTEpIHtcbiAgICAgICAgICB1aW50OFtpXSA9IHRoaXMucmVhZFVJbnQ4KCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5wZWVrID0gZnVuY3Rpb24oYnl0ZXMsIG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gICAgICB2YXIgaSwgX2ksIF9qO1xuICAgICAgaWYgKGxpdHRsZUVuZGlhbiA9PSBudWxsKSB7XG4gICAgICAgIGxpdHRsZUVuZGlhbiA9IGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKGxpdHRsZUVuZGlhbiA9PT0gbmF0aXZlRW5kaWFuKSB7XG4gICAgICAgIGZvciAoaSA9IF9pID0gMDsgX2kgPCBieXRlczsgaSA9IF9pICs9IDEpIHtcbiAgICAgICAgICB1aW50OFtpXSA9IHRoaXMucGVla1VJbnQ4KG9mZnNldCArIGkpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKGkgPSBfaiA9IDA7IF9qIDwgYnl0ZXM7IGkgPSBfaiArPSAxKSB7XG4gICAgICAgICAgdWludDhbYnl0ZXMgLSBpIC0gMV0gPSB0aGlzLnBlZWtVSW50OChvZmZzZXQgKyBpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlYWRJbnQ4ID0gZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLnJlYWQoMSk7XG4gICAgICByZXR1cm4gaW50OFswXTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5wZWVrSW50OCA9IGZ1bmN0aW9uKG9mZnNldCkge1xuICAgICAgaWYgKG9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICB9XG4gICAgICB0aGlzLnBlZWsoMSwgb2Zmc2V0KTtcbiAgICAgIHJldHVybiBpbnQ4WzBdO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlYWRVSW50MTYgPSBmdW5jdGlvbihsaXR0bGVFbmRpYW4pIHtcbiAgICAgIHRoaXMucmVhZCgyLCBsaXR0bGVFbmRpYW4pO1xuICAgICAgcmV0dXJuIHVpbnQxNlswXTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5wZWVrVUludDE2ID0gZnVuY3Rpb24ob2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgICAgIGlmIChvZmZzZXQgPT0gbnVsbCkge1xuICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgfVxuICAgICAgdGhpcy5wZWVrKDIsIG9mZnNldCwgbGl0dGxlRW5kaWFuKTtcbiAgICAgIHJldHVybiB1aW50MTZbMF07XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZEludDE2ID0gZnVuY3Rpb24obGl0dGxlRW5kaWFuKSB7XG4gICAgICB0aGlzLnJlYWQoMiwgbGl0dGxlRW5kaWFuKTtcbiAgICAgIHJldHVybiBpbnQxNlswXTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5wZWVrSW50MTYgPSBmdW5jdGlvbihvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICAgICAgaWYgKG9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICB9XG4gICAgICB0aGlzLnBlZWsoMiwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pO1xuICAgICAgcmV0dXJuIGludDE2WzBdO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlYWRVSW50MjQgPSBmdW5jdGlvbihsaXR0bGVFbmRpYW4pIHtcbiAgICAgIGlmIChsaXR0bGVFbmRpYW4pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVhZFVJbnQxNih0cnVlKSArICh0aGlzLnJlYWRVSW50OCgpIDw8IDE2KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiAodGhpcy5yZWFkVUludDE2KCkgPDwgOCkgKyB0aGlzLnJlYWRVSW50OCgpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtVSW50MjQgPSBmdW5jdGlvbihvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICAgICAgaWYgKG9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICB9XG4gICAgICBpZiAobGl0dGxlRW5kaWFuKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBlZWtVSW50MTYob2Zmc2V0LCB0cnVlKSArICh0aGlzLnBlZWtVSW50OChvZmZzZXQgKyAyKSA8PCAxNik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gKHRoaXMucGVla1VJbnQxNihvZmZzZXQpIDw8IDgpICsgdGhpcy5wZWVrVUludDgob2Zmc2V0ICsgMik7XG4gICAgICB9XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZEludDI0ID0gZnVuY3Rpb24obGl0dGxlRW5kaWFuKSB7XG4gICAgICBpZiAobGl0dGxlRW5kaWFuKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlYWRVSW50MTYodHJ1ZSkgKyAodGhpcy5yZWFkSW50OCgpIDw8IDE2KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiAodGhpcy5yZWFkSW50MTYoKSA8PCA4KSArIHRoaXMucmVhZFVJbnQ4KCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVla0ludDI0ID0gZnVuY3Rpb24ob2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgICAgIGlmIChvZmZzZXQgPT0gbnVsbCkge1xuICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgfVxuICAgICAgaWYgKGxpdHRsZUVuZGlhbikge1xuICAgICAgICByZXR1cm4gdGhpcy5wZWVrVUludDE2KG9mZnNldCwgdHJ1ZSkgKyAodGhpcy5wZWVrSW50OChvZmZzZXQgKyAyKSA8PCAxNik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gKHRoaXMucGVla0ludDE2KG9mZnNldCkgPDwgOCkgKyB0aGlzLnBlZWtVSW50OChvZmZzZXQgKyAyKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkVUludDMyID0gZnVuY3Rpb24obGl0dGxlRW5kaWFuKSB7XG4gICAgICB0aGlzLnJlYWQoNCwgbGl0dGxlRW5kaWFuKTtcbiAgICAgIHJldHVybiB1aW50MzJbMF07XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVla1VJbnQzMiA9IGZ1bmN0aW9uKG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gICAgICBpZiAob2Zmc2V0ID09IG51bGwpIHtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgIH1cbiAgICAgIHRoaXMucGVlayg0LCBvZmZzZXQsIGxpdHRsZUVuZGlhbik7XG4gICAgICByZXR1cm4gdWludDMyWzBdO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlYWRJbnQzMiA9IGZ1bmN0aW9uKGxpdHRsZUVuZGlhbikge1xuICAgICAgdGhpcy5yZWFkKDQsIGxpdHRsZUVuZGlhbik7XG4gICAgICByZXR1cm4gaW50MzJbMF07XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVla0ludDMyID0gZnVuY3Rpb24ob2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgICAgIGlmIChvZmZzZXQgPT0gbnVsbCkge1xuICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgfVxuICAgICAgdGhpcy5wZWVrKDQsIG9mZnNldCwgbGl0dGxlRW5kaWFuKTtcbiAgICAgIHJldHVybiBpbnQzMlswXTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkRmxvYXQzMiA9IGZ1bmN0aW9uKGxpdHRsZUVuZGlhbikge1xuICAgICAgdGhpcy5yZWFkKDQsIGxpdHRsZUVuZGlhbik7XG4gICAgICByZXR1cm4gZmxvYXQzMlswXTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5wZWVrRmxvYXQzMiA9IGZ1bmN0aW9uKG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gICAgICBpZiAob2Zmc2V0ID09IG51bGwpIHtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgIH1cbiAgICAgIHRoaXMucGVlayg0LCBvZmZzZXQsIGxpdHRsZUVuZGlhbik7XG4gICAgICByZXR1cm4gZmxvYXQzMlswXTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkRmxvYXQ2NCA9IGZ1bmN0aW9uKGxpdHRsZUVuZGlhbikge1xuICAgICAgdGhpcy5yZWFkKDgsIGxpdHRsZUVuZGlhbik7XG4gICAgICBpZiAoZmxvYXQ2NCkge1xuICAgICAgICByZXR1cm4gZmxvYXQ2NFswXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmbG9hdDY0RmFsbGJhY2soKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgZmxvYXQ2NEZhbGxiYWNrID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgZXhwLCBmcmFjLCBoaWdoLCBsb3csIG91dCwgc2lnbjtcbiAgICAgIGxvdyA9IHVpbnQzMlswXSwgaGlnaCA9IHVpbnQzMlsxXTtcbiAgICAgIGlmICghaGlnaCB8fCBoaWdoID09PSAweDgwMDAwMDAwKSB7XG4gICAgICAgIHJldHVybiAwLjA7XG4gICAgICB9XG4gICAgICBzaWduID0gMSAtIChoaWdoID4+PiAzMSkgKiAyO1xuICAgICAgZXhwID0gKGhpZ2ggPj4+IDIwKSAmIDB4N2ZmO1xuICAgICAgZnJhYyA9IGhpZ2ggJiAweGZmZmZmO1xuICAgICAgaWYgKGV4cCA9PT0gMHg3ZmYpIHtcbiAgICAgICAgaWYgKGZyYWMpIHtcbiAgICAgICAgICByZXR1cm4gTmFOO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzaWduICogSW5maW5pdHk7XG4gICAgICB9XG4gICAgICBleHAgLT0gMTAyMztcbiAgICAgIG91dCA9IChmcmFjIHwgMHgxMDAwMDApICogTWF0aC5wb3coMiwgZXhwIC0gMjApO1xuICAgICAgb3V0ICs9IGxvdyAqIE1hdGgucG93KDIsIGV4cCAtIDUyKTtcbiAgICAgIHJldHVybiBzaWduICogb3V0O1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtGbG9hdDY0ID0gZnVuY3Rpb24ob2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgICAgIGlmIChvZmZzZXQgPT0gbnVsbCkge1xuICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgfVxuICAgICAgdGhpcy5wZWVrKDgsIG9mZnNldCwgbGl0dGxlRW5kaWFuKTtcbiAgICAgIGlmIChmbG9hdDY0KSB7XG4gICAgICAgIHJldHVybiBmbG9hdDY0WzBdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZsb2F0NjRGYWxsYmFjaygpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlYWRGbG9hdDgwID0gZnVuY3Rpb24obGl0dGxlRW5kaWFuKSB7XG4gICAgICB0aGlzLnJlYWQoMTAsIGxpdHRsZUVuZGlhbik7XG4gICAgICByZXR1cm4gZmxvYXQ4MCgpO1xuICAgIH07XG5cbiAgICBmbG9hdDgwID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYTAsIGExLCBleHAsIGhpZ2gsIGxvdywgb3V0LCBzaWduO1xuICAgICAgaGlnaCA9IHVpbnQzMlswXSwgbG93ID0gdWludDMyWzFdO1xuICAgICAgYTAgPSB1aW50OFs5XTtcbiAgICAgIGExID0gdWludDhbOF07XG4gICAgICBzaWduID0gMSAtIChhMCA+Pj4gNykgKiAyO1xuICAgICAgZXhwID0gKChhMCAmIDB4N0YpIDw8IDgpIHwgYTE7XG4gICAgICBpZiAoZXhwID09PSAwICYmIGxvdyA9PT0gMCAmJiBoaWdoID09PSAwKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgICAgfVxuICAgICAgaWYgKGV4cCA9PT0gMHg3ZmZmKSB7XG4gICAgICAgIGlmIChsb3cgPT09IDAgJiYgaGlnaCA9PT0gMCkge1xuICAgICAgICAgIHJldHVybiBzaWduICogSW5maW5pdHk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIE5hTjtcbiAgICAgIH1cbiAgICAgIGV4cCAtPSAxNjM4MztcbiAgICAgIG91dCA9IGxvdyAqIE1hdGgucG93KDIsIGV4cCAtIDMxKTtcbiAgICAgIG91dCArPSBoaWdoICogTWF0aC5wb3coMiwgZXhwIC0gNjMpO1xuICAgICAgcmV0dXJuIHNpZ24gKiBvdXQ7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVla0Zsb2F0ODAgPSBmdW5jdGlvbihvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICAgICAgaWYgKG9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICB9XG4gICAgICB0aGlzLnBlZWsoMTAsIG9mZnNldCwgbGl0dGxlRW5kaWFuKTtcbiAgICAgIHJldHVybiBmbG9hdDgwKCk7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZEJ1ZmZlciA9IGZ1bmN0aW9uKGxlbmd0aCkge1xuICAgICAgdmFyIGksIHJlc3VsdCwgdG8sIF9pO1xuICAgICAgcmVzdWx0ID0gQVZCdWZmZXIuYWxsb2NhdGUobGVuZ3RoKTtcbiAgICAgIHRvID0gcmVzdWx0LmRhdGE7XG4gICAgICBmb3IgKGkgPSBfaSA9IDA7IF9pIDwgbGVuZ3RoOyBpID0gX2kgKz0gMSkge1xuICAgICAgICB0b1tpXSA9IHRoaXMucmVhZFVJbnQ4KCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtCdWZmZXIgPSBmdW5jdGlvbihvZmZzZXQsIGxlbmd0aCkge1xuICAgICAgdmFyIGksIHJlc3VsdCwgdG8sIF9pO1xuICAgICAgaWYgKG9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICB9XG4gICAgICByZXN1bHQgPSBBVkJ1ZmZlci5hbGxvY2F0ZShsZW5ndGgpO1xuICAgICAgdG8gPSByZXN1bHQuZGF0YTtcbiAgICAgIGZvciAoaSA9IF9pID0gMDsgX2kgPCBsZW5ndGg7IGkgPSBfaSArPSAxKSB7XG4gICAgICAgIHRvW2ldID0gdGhpcy5wZWVrVUludDgob2Zmc2V0ICsgaSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlYWRTaW5nbGVCdWZmZXIgPSBmdW5jdGlvbihsZW5ndGgpIHtcbiAgICAgIHZhciByZXN1bHQ7XG4gICAgICByZXN1bHQgPSB0aGlzLmxpc3QuZmlyc3Quc2xpY2UodGhpcy5sb2NhbE9mZnNldCwgbGVuZ3RoKTtcbiAgICAgIHRoaXMuYWR2YW5jZShyZXN1bHQubGVuZ3RoKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVla1NpbmdsZUJ1ZmZlciA9IGZ1bmN0aW9uKG9mZnNldCwgbGVuZ3RoKSB7XG4gICAgICB2YXIgcmVzdWx0O1xuICAgICAgcmVzdWx0ID0gdGhpcy5saXN0LmZpcnN0LnNsaWNlKHRoaXMubG9jYWxPZmZzZXQgKyBvZmZzZXQsIGxlbmd0aCk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlYWRTdHJpbmcgPSBmdW5jdGlvbihsZW5ndGgsIGVuY29kaW5nKSB7XG4gICAgICBpZiAoZW5jb2RpbmcgPT0gbnVsbCkge1xuICAgICAgICBlbmNvZGluZyA9ICdhc2NpaSc7XG4gICAgICB9XG4gICAgICByZXR1cm4gZGVjb2RlU3RyaW5nLmNhbGwodGhpcywgMCwgbGVuZ3RoLCBlbmNvZGluZywgdHJ1ZSk7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVla1N0cmluZyA9IGZ1bmN0aW9uKG9mZnNldCwgbGVuZ3RoLCBlbmNvZGluZykge1xuICAgICAgaWYgKG9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICB9XG4gICAgICBpZiAoZW5jb2RpbmcgPT0gbnVsbCkge1xuICAgICAgICBlbmNvZGluZyA9ICdhc2NpaSc7XG4gICAgICB9XG4gICAgICByZXR1cm4gZGVjb2RlU3RyaW5nLmNhbGwodGhpcywgb2Zmc2V0LCBsZW5ndGgsIGVuY29kaW5nLCBmYWxzZSk7XG4gICAgfTtcblxuICAgIGRlY29kZVN0cmluZyA9IGZ1bmN0aW9uKG9mZnNldCwgbGVuZ3RoLCBlbmNvZGluZywgYWR2YW5jZSkge1xuICAgICAgdmFyIGIxLCBiMiwgYjMsIGI0LCBib20sIGMsIGVuZCwgbGl0dGxlRW5kaWFuLCBudWxsRW5kLCBwdCwgcmVzdWx0LCB3MSwgdzI7XG4gICAgICBlbmNvZGluZyA9IGVuY29kaW5nLnRvTG93ZXJDYXNlKCk7XG4gICAgICBudWxsRW5kID0gbGVuZ3RoID09PSBudWxsID8gMCA6IC0xO1xuICAgICAgaWYgKGxlbmd0aCA9PSBudWxsKSB7XG4gICAgICAgIGxlbmd0aCA9IEluZmluaXR5O1xuICAgICAgfVxuICAgICAgZW5kID0gb2Zmc2V0ICsgbGVuZ3RoO1xuICAgICAgcmVzdWx0ID0gJyc7XG4gICAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgICAgICB3aGlsZSAob2Zmc2V0IDwgZW5kICYmIChjID0gdGhpcy5wZWVrVUludDgob2Zmc2V0KyspKSAhPT0gbnVsbEVuZCkge1xuICAgICAgICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICd1dGY4JzpcbiAgICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICAgIHdoaWxlIChvZmZzZXQgPCBlbmQgJiYgKGIxID0gdGhpcy5wZWVrVUludDgob2Zmc2V0KyspKSAhPT0gbnVsbEVuZCkge1xuICAgICAgICAgICAgaWYgKChiMSAmIDB4ODApID09PSAwKSB7XG4gICAgICAgICAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGIxKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoKGIxICYgMHhlMCkgPT09IDB4YzApIHtcbiAgICAgICAgICAgICAgYjIgPSB0aGlzLnBlZWtVSW50OChvZmZzZXQrKykgJiAweDNmO1xuICAgICAgICAgICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoKGIxICYgMHgxZikgPDwgNikgfCBiMik7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKChiMSAmIDB4ZjApID09PSAweGUwKSB7XG4gICAgICAgICAgICAgIGIyID0gdGhpcy5wZWVrVUludDgob2Zmc2V0KyspICYgMHgzZjtcbiAgICAgICAgICAgICAgYjMgPSB0aGlzLnBlZWtVSW50OChvZmZzZXQrKykgJiAweDNmO1xuICAgICAgICAgICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoKGIxICYgMHgwZikgPDwgMTIpIHwgKGIyIDw8IDYpIHwgYjMpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICgoYjEgJiAweGY4KSA9PT0gMHhmMCkge1xuICAgICAgICAgICAgICBiMiA9IHRoaXMucGVla1VJbnQ4KG9mZnNldCsrKSAmIDB4M2Y7XG4gICAgICAgICAgICAgIGIzID0gdGhpcy5wZWVrVUludDgob2Zmc2V0KyspICYgMHgzZjtcbiAgICAgICAgICAgICAgYjQgPSB0aGlzLnBlZWtVSW50OChvZmZzZXQrKykgJiAweDNmO1xuICAgICAgICAgICAgICBwdCA9ICgoKGIxICYgMHgwZikgPDwgMTgpIHwgKGIyIDw8IDEyKSB8IChiMyA8PCA2KSB8IGI0KSAtIDB4MTAwMDA7XG4gICAgICAgICAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4ZDgwMCArIChwdCA+PiAxMCksIDB4ZGMwMCArIChwdCAmIDB4M2ZmKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICd1dGYxNi1iZSc6XG4gICAgICAgIGNhc2UgJ3V0ZjE2YmUnOlxuICAgICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgICAgY2FzZSAndXRmMTYtbGUnOlxuICAgICAgICBjYXNlICd1dGYxNmJvbSc6XG4gICAgICAgIGNhc2UgJ3V0ZjE2LWJvbSc6XG4gICAgICAgICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgICAgICAgY2FzZSAndXRmMTZiZSc6XG4gICAgICAgICAgICBjYXNlICd1dGYxNi1iZSc6XG4gICAgICAgICAgICAgIGxpdHRsZUVuZGlhbiA9IGZhbHNlO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgICAgICAgY2FzZSAndXRmMTYtbGUnOlxuICAgICAgICAgICAgICBsaXR0bGVFbmRpYW4gPSB0cnVlO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ3V0ZjE2Ym9tJzpcbiAgICAgICAgICAgIGNhc2UgJ3V0ZjE2LWJvbSc6XG4gICAgICAgICAgICAgIGlmIChsZW5ndGggPCAyIHx8IChib20gPSB0aGlzLnBlZWtVSW50MTYob2Zmc2V0KSkgPT09IG51bGxFbmQpIHtcbiAgICAgICAgICAgICAgICBpZiAoYWR2YW5jZSkge1xuICAgICAgICAgICAgICAgICAgdGhpcy5hZHZhbmNlKG9mZnNldCArPSAyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBsaXR0bGVFbmRpYW4gPSBib20gPT09IDB4ZmZmZTtcbiAgICAgICAgICAgICAgb2Zmc2V0ICs9IDI7XG4gICAgICAgICAgfVxuICAgICAgICAgIHdoaWxlIChvZmZzZXQgPCBlbmQgJiYgKHcxID0gdGhpcy5wZWVrVUludDE2KG9mZnNldCwgbGl0dGxlRW5kaWFuKSkgIT09IG51bGxFbmQpIHtcbiAgICAgICAgICAgIG9mZnNldCArPSAyO1xuICAgICAgICAgICAgaWYgKHcxIDwgMHhkODAwIHx8IHcxID4gMHhkZmZmKSB7XG4gICAgICAgICAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHcxKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGlmICh3MSA+IDB4ZGJmZikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgdXRmMTYgc2VxdWVuY2UuXCIpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHcyID0gdGhpcy5wZWVrVUludDE2KG9mZnNldCwgbGl0dGxlRW5kaWFuKTtcbiAgICAgICAgICAgICAgaWYgKHcyIDwgMHhkYzAwIHx8IHcyID4gMHhkZmZmKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCB1dGYxNiBzZXF1ZW5jZS5cIik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUodzEsIHcyKTtcbiAgICAgICAgICAgICAgb2Zmc2V0ICs9IDI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh3MSA9PT0gbnVsbEVuZCkge1xuICAgICAgICAgICAgb2Zmc2V0ICs9IDI7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gZW5jb2Rpbmc6IFwiICsgZW5jb2RpbmcpO1xuICAgICAgfVxuICAgICAgaWYgKGFkdmFuY2UpIHtcbiAgICAgICAgdGhpcy5hZHZhbmNlKG9mZnNldCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICByZXR1cm4gU3RyZWFtO1xuXG4gIH0pKCk7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBTdHJlYW07XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuNy4xXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBVbmRlcmZsb3dFcnJvcixcbiAgICBfX2hhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgICBfX2V4dGVuZHMgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKF9faGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfTtcblxuICBVbmRlcmZsb3dFcnJvciA9IChmdW5jdGlvbihfc3VwZXIpIHtcbiAgICBfX2V4dGVuZHMoVW5kZXJmbG93RXJyb3IsIF9zdXBlcik7XG5cbiAgICBmdW5jdGlvbiBVbmRlcmZsb3dFcnJvcigpIHtcbiAgICAgIFVuZGVyZmxvd0Vycm9yLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgdGhpcy5uYW1lID0gJ1VuZGVyZmxvd0Vycm9yJztcbiAgICAgIHRoaXMuc3RhY2sgPSBuZXcgRXJyb3IoKS5zdGFjaztcbiAgICB9XG5cbiAgICByZXR1cm4gVW5kZXJmbG93RXJyb3I7XG5cbiAgfSkoRXJyb3IpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gVW5kZXJmbG93RXJyb3I7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuNy4xXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBCaXRzdHJlYW0sIEJ1ZmZlckxpc3QsIERlY29kZXIsIEV2ZW50RW1pdHRlciwgU3RyZWFtLCBVbmRlcmZsb3dFcnJvcixcbiAgICBfX2hhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgICBfX2V4dGVuZHMgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKF9faGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfTtcblxuICBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuL2NvcmUvZXZlbnRzJyk7XG5cbiAgQnVmZmVyTGlzdCA9IHJlcXVpcmUoJy4vY29yZS9idWZmZXJsaXN0Jyk7XG5cbiAgU3RyZWFtID0gcmVxdWlyZSgnLi9jb3JlL3N0cmVhbScpO1xuXG4gIEJpdHN0cmVhbSA9IHJlcXVpcmUoJy4vY29yZS9iaXRzdHJlYW0nKTtcblxuICBVbmRlcmZsb3dFcnJvciA9IHJlcXVpcmUoJy4vY29yZS91bmRlcmZsb3cnKTtcblxuICBEZWNvZGVyID0gKGZ1bmN0aW9uKF9zdXBlcikge1xuICAgIHZhciBjb2RlY3M7XG5cbiAgICBfX2V4dGVuZHMoRGVjb2RlciwgX3N1cGVyKTtcblxuICAgIGZ1bmN0aW9uIERlY29kZXIoZGVtdXhlciwgZm9ybWF0KSB7XG4gICAgICB2YXIgbGlzdDtcbiAgICAgIHRoaXMuZGVtdXhlciA9IGRlbXV4ZXI7XG4gICAgICB0aGlzLmZvcm1hdCA9IGZvcm1hdDtcbiAgICAgIGxpc3QgPSBuZXcgQnVmZmVyTGlzdDtcbiAgICAgIHRoaXMuc3RyZWFtID0gbmV3IFN0cmVhbShsaXN0KTtcbiAgICAgIHRoaXMuYml0c3RyZWFtID0gbmV3IEJpdHN0cmVhbSh0aGlzLnN0cmVhbSk7XG4gICAgICB0aGlzLnJlY2VpdmVkRmluYWxCdWZmZXIgPSBmYWxzZTtcbiAgICAgIHRoaXMud2FpdGluZyA9IGZhbHNlO1xuICAgICAgdGhpcy5kZW11eGVyLm9uKCdjb29raWUnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGNvb2tpZSkge1xuICAgICAgICAgIHZhciBlcnJvcjtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIF90aGlzLnNldENvb2tpZShjb29raWUpO1xuICAgICAgICAgIH0gY2F0Y2ggKF9lcnJvcikge1xuICAgICAgICAgICAgZXJyb3IgPSBfZXJyb3I7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnZXJyb3InLCBlcnJvcik7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5kZW11eGVyLm9uKCdkYXRhJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihjaHVuaykge1xuICAgICAgICAgIGxpc3QuYXBwZW5kKGNodW5rKTtcbiAgICAgICAgICBpZiAoX3RoaXMud2FpdGluZykge1xuICAgICAgICAgICAgcmV0dXJuIF90aGlzLmRlY29kZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHRoaXMuZGVtdXhlci5vbignZW5kJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICBfdGhpcy5yZWNlaXZlZEZpbmFsQnVmZmVyID0gdHJ1ZTtcbiAgICAgICAgICBpZiAoX3RoaXMud2FpdGluZykge1xuICAgICAgICAgICAgcmV0dXJuIF90aGlzLmRlY29kZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHRoaXMuaW5pdCgpO1xuICAgIH1cblxuICAgIERlY29kZXIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbigpIHt9O1xuXG4gICAgRGVjb2Rlci5wcm90b3R5cGUuc2V0Q29va2llID0gZnVuY3Rpb24oY29va2llKSB7fTtcblxuICAgIERlY29kZXIucHJvdG90eXBlLnJlYWRDaHVuayA9IGZ1bmN0aW9uKCkge307XG5cbiAgICBEZWNvZGVyLnByb3RvdHlwZS5kZWNvZGUgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBlcnJvciwgb2Zmc2V0LCBwYWNrZXQ7XG4gICAgICB0aGlzLndhaXRpbmcgPSAhdGhpcy5yZWNlaXZlZEZpbmFsQnVmZmVyO1xuICAgICAgb2Zmc2V0ID0gdGhpcy5iaXRzdHJlYW0ub2Zmc2V0KCk7XG4gICAgICB0cnkge1xuICAgICAgICBwYWNrZXQgPSB0aGlzLnJlYWRDaHVuaygpO1xuICAgICAgfSBjYXRjaCAoX2Vycm9yKSB7XG4gICAgICAgIGVycm9yID0gX2Vycm9yO1xuICAgICAgICBpZiAoIShlcnJvciBpbnN0YW5jZW9mIFVuZGVyZmxvd0Vycm9yKSkge1xuICAgICAgICAgIHRoaXMuZW1pdCgnZXJyb3InLCBlcnJvcik7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAocGFja2V0KSB7XG4gICAgICAgIHRoaXMuZW1pdCgnZGF0YScsIHBhY2tldCk7XG4gICAgICAgIGlmICh0aGlzLnJlY2VpdmVkRmluYWxCdWZmZXIpIHtcbiAgICAgICAgICB0aGlzLmVtaXQoJ2VuZCcpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSBlbHNlIGlmICghdGhpcy5yZWNlaXZlZEZpbmFsQnVmZmVyKSB7XG4gICAgICAgIHRoaXMuYml0c3RyZWFtLnNlZWsob2Zmc2V0KTtcbiAgICAgICAgdGhpcy53YWl0aW5nID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuZW1pdCgnZW5kJyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcblxuICAgIERlY29kZXIucHJvdG90eXBlLnNlZWsgPSBmdW5jdGlvbih0aW1lc3RhbXApIHtcbiAgICAgIHZhciBzZWVrUG9pbnQ7XG4gICAgICBzZWVrUG9pbnQgPSB0aGlzLmRlbXV4ZXIuc2Vlayh0aW1lc3RhbXApO1xuICAgICAgdGhpcy5zdHJlYW0uc2VlayhzZWVrUG9pbnQub2Zmc2V0KTtcbiAgICAgIHJldHVybiBzZWVrUG9pbnQudGltZXN0YW1wO1xuICAgIH07XG5cbiAgICBjb2RlY3MgPSB7fTtcblxuICAgIERlY29kZXIucmVnaXN0ZXIgPSBmdW5jdGlvbihpZCwgZGVjb2Rlcikge1xuICAgICAgcmV0dXJuIGNvZGVjc1tpZF0gPSBkZWNvZGVyO1xuICAgIH07XG5cbiAgICBEZWNvZGVyLmZpbmQgPSBmdW5jdGlvbihpZCkge1xuICAgICAgcmV0dXJuIGNvZGVjc1tpZF0gfHwgbnVsbDtcbiAgICB9O1xuXG4gICAgcmV0dXJuIERlY29kZXI7XG5cbiAgfSkoRXZlbnRFbWl0dGVyKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IERlY29kZXI7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuNy4xXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBEZWNvZGVyLCBMUENNRGVjb2RlcixcbiAgICBfX2JpbmQgPSBmdW5jdGlvbihmbiwgbWUpeyByZXR1cm4gZnVuY3Rpb24oKXsgcmV0dXJuIGZuLmFwcGx5KG1lLCBhcmd1bWVudHMpOyB9OyB9LFxuICAgIF9faGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5LFxuICAgIF9fZXh0ZW5kcyA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoX19oYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9O1xuXG4gIERlY29kZXIgPSByZXF1aXJlKCcuLi9kZWNvZGVyJyk7XG5cbiAgTFBDTURlY29kZXIgPSAoZnVuY3Rpb24oX3N1cGVyKSB7XG4gICAgX19leHRlbmRzKExQQ01EZWNvZGVyLCBfc3VwZXIpO1xuXG4gICAgZnVuY3Rpb24gTFBDTURlY29kZXIoKSB7XG4gICAgICB0aGlzLnJlYWRDaHVuayA9IF9fYmluZCh0aGlzLnJlYWRDaHVuaywgdGhpcyk7XG4gICAgICByZXR1cm4gTFBDTURlY29kZXIuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgRGVjb2Rlci5yZWdpc3RlcignbHBjbScsIExQQ01EZWNvZGVyKTtcblxuICAgIExQQ01EZWNvZGVyLnByb3RvdHlwZS5yZWFkQ2h1bmsgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBjaHVua1NpemUsIGksIGxpdHRsZUVuZGlhbiwgb3V0cHV0LCBzYW1wbGVzLCBzdHJlYW0sIF9pLCBfaiwgX2ssIF9sLCBfbSwgX247XG4gICAgICBzdHJlYW0gPSB0aGlzLnN0cmVhbTtcbiAgICAgIGxpdHRsZUVuZGlhbiA9IHRoaXMuZm9ybWF0LmxpdHRsZUVuZGlhbjtcbiAgICAgIGNodW5rU2l6ZSA9IE1hdGgubWluKDQwOTYsIHN0cmVhbS5yZW1haW5pbmdCeXRlcygpKTtcbiAgICAgIHNhbXBsZXMgPSBjaHVua1NpemUgLyAodGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwgLyA4KSB8IDA7XG4gICAgICBpZiAoY2h1bmtTaXplIDwgdGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwgLyA4KSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuZm9ybWF0LmZsb2F0aW5nUG9pbnQpIHtcbiAgICAgICAgc3dpdGNoICh0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCkge1xuICAgICAgICAgIGNhc2UgMzI6XG4gICAgICAgICAgICBvdXRwdXQgPSBuZXcgRmxvYXQzMkFycmF5KHNhbXBsZXMpO1xuICAgICAgICAgICAgZm9yIChpID0gX2kgPSAwOyBfaSA8IHNhbXBsZXM7IGkgPSBfaSArPSAxKSB7XG4gICAgICAgICAgICAgIG91dHB1dFtpXSA9IHN0cmVhbS5yZWFkRmxvYXQzMihsaXR0bGVFbmRpYW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSA2NDpcbiAgICAgICAgICAgIG91dHB1dCA9IG5ldyBGbG9hdDY0QXJyYXkoc2FtcGxlcyk7XG4gICAgICAgICAgICBmb3IgKGkgPSBfaiA9IDA7IF9qIDwgc2FtcGxlczsgaSA9IF9qICs9IDEpIHtcbiAgICAgICAgICAgICAgb3V0cHV0W2ldID0gc3RyZWFtLnJlYWRGbG9hdDY0KGxpdHRsZUVuZGlhbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBiaXQgZGVwdGguJyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN3aXRjaCAodGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwpIHtcbiAgICAgICAgICBjYXNlIDg6XG4gICAgICAgICAgICBvdXRwdXQgPSBuZXcgSW50OEFycmF5KHNhbXBsZXMpO1xuICAgICAgICAgICAgZm9yIChpID0gX2sgPSAwOyBfayA8IHNhbXBsZXM7IGkgPSBfayArPSAxKSB7XG4gICAgICAgICAgICAgIG91dHB1dFtpXSA9IHN0cmVhbS5yZWFkSW50OCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAxNjpcbiAgICAgICAgICAgIG91dHB1dCA9IG5ldyBJbnQxNkFycmF5KHNhbXBsZXMpO1xuICAgICAgICAgICAgZm9yIChpID0gX2wgPSAwOyBfbCA8IHNhbXBsZXM7IGkgPSBfbCArPSAxKSB7XG4gICAgICAgICAgICAgIG91dHB1dFtpXSA9IHN0cmVhbS5yZWFkSW50MTYobGl0dGxlRW5kaWFuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgMjQ6XG4gICAgICAgICAgICBvdXRwdXQgPSBuZXcgSW50MzJBcnJheShzYW1wbGVzKTtcbiAgICAgICAgICAgIGZvciAoaSA9IF9tID0gMDsgX20gPCBzYW1wbGVzOyBpID0gX20gKz0gMSkge1xuICAgICAgICAgICAgICBvdXRwdXRbaV0gPSBzdHJlYW0ucmVhZEludDI0KGxpdHRsZUVuZGlhbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIDMyOlxuICAgICAgICAgICAgb3V0cHV0ID0gbmV3IEludDMyQXJyYXkoc2FtcGxlcyk7XG4gICAgICAgICAgICBmb3IgKGkgPSBfbiA9IDA7IF9uIDwgc2FtcGxlczsgaSA9IF9uICs9IDEpIHtcbiAgICAgICAgICAgICAgb3V0cHV0W2ldID0gc3RyZWFtLnJlYWRJbnQzMihsaXR0bGVFbmRpYW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgYml0IGRlcHRoLicpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gb3V0cHV0O1xuICAgIH07XG5cbiAgICByZXR1cm4gTFBDTURlY29kZXI7XG5cbiAgfSkoRGVjb2Rlcik7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuNy4xXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBEZWNvZGVyLCBYTEFXRGVjb2RlcixcbiAgICBfX2JpbmQgPSBmdW5jdGlvbihmbiwgbWUpeyByZXR1cm4gZnVuY3Rpb24oKXsgcmV0dXJuIGZuLmFwcGx5KG1lLCBhcmd1bWVudHMpOyB9OyB9LFxuICAgIF9faGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5LFxuICAgIF9fZXh0ZW5kcyA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoX19oYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9O1xuXG4gIERlY29kZXIgPSByZXF1aXJlKCcuLi9kZWNvZGVyJyk7XG5cbiAgWExBV0RlY29kZXIgPSAoZnVuY3Rpb24oX3N1cGVyKSB7XG4gICAgdmFyIEJJQVMsIFFVQU5UX01BU0ssIFNFR19NQVNLLCBTRUdfU0hJRlQsIFNJR05fQklUO1xuXG4gICAgX19leHRlbmRzKFhMQVdEZWNvZGVyLCBfc3VwZXIpO1xuXG4gICAgZnVuY3Rpb24gWExBV0RlY29kZXIoKSB7XG4gICAgICB0aGlzLnJlYWRDaHVuayA9IF9fYmluZCh0aGlzLnJlYWRDaHVuaywgdGhpcyk7XG4gICAgICByZXR1cm4gWExBV0RlY29kZXIuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgRGVjb2Rlci5yZWdpc3RlcigndWxhdycsIFhMQVdEZWNvZGVyKTtcblxuICAgIERlY29kZXIucmVnaXN0ZXIoJ2FsYXcnLCBYTEFXRGVjb2Rlcik7XG5cbiAgICBTSUdOX0JJVCA9IDB4ODA7XG5cbiAgICBRVUFOVF9NQVNLID0gMHhmO1xuXG4gICAgU0VHX1NISUZUID0gNDtcblxuICAgIFNFR19NQVNLID0gMHg3MDtcblxuICAgIEJJQVMgPSAweDg0O1xuXG4gICAgWExBV0RlY29kZXIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBpLCBzZWcsIHQsIHRhYmxlLCB2YWwsIF9pLCBfajtcbiAgICAgIHRoaXMuZm9ybWF0LmJpdHNQZXJDaGFubmVsID0gMTY7XG4gICAgICB0aGlzLnRhYmxlID0gdGFibGUgPSBuZXcgSW50MTZBcnJheSgyNTYpO1xuICAgICAgaWYgKHRoaXMuZm9ybWF0LmZvcm1hdElEID09PSAndWxhdycpIHtcbiAgICAgICAgZm9yIChpID0gX2kgPSAwOyBfaSA8IDI1NjsgaSA9ICsrX2kpIHtcbiAgICAgICAgICB2YWwgPSB+aTtcbiAgICAgICAgICB0ID0gKCh2YWwgJiBRVUFOVF9NQVNLKSA8PCAzKSArIEJJQVM7XG4gICAgICAgICAgdCA8PD0gKHZhbCAmIFNFR19NQVNLKSA+Pj4gU0VHX1NISUZUO1xuICAgICAgICAgIHRhYmxlW2ldID0gdmFsICYgU0lHTl9CSVQgPyBCSUFTIC0gdCA6IHQgLSBCSUFTO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKGkgPSBfaiA9IDA7IF9qIDwgMjU2OyBpID0gKytfaikge1xuICAgICAgICAgIHZhbCA9IGkgXiAweDU1O1xuICAgICAgICAgIHQgPSB2YWwgJiBRVUFOVF9NQVNLO1xuICAgICAgICAgIHNlZyA9ICh2YWwgJiBTRUdfTUFTSykgPj4+IFNFR19TSElGVDtcbiAgICAgICAgICBpZiAoc2VnKSB7XG4gICAgICAgICAgICB0ID0gKHQgKyB0ICsgMSArIDMyKSA8PCAoc2VnICsgMik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHQgPSAodCArIHQgKyAxKSA8PCAzO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0YWJsZVtpXSA9IHZhbCAmIFNJR05fQklUID8gdCA6IC10O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIFhMQVdEZWNvZGVyLnByb3RvdHlwZS5yZWFkQ2h1bmsgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBpLCBvdXRwdXQsIHNhbXBsZXMsIHN0cmVhbSwgdGFibGUsIF9pO1xuICAgICAgc3RyZWFtID0gdGhpcy5zdHJlYW0sIHRhYmxlID0gdGhpcy50YWJsZTtcbiAgICAgIHNhbXBsZXMgPSBNYXRoLm1pbig0MDk2LCB0aGlzLnN0cmVhbS5yZW1haW5pbmdCeXRlcygpKTtcbiAgICAgIGlmIChzYW1wbGVzID09PSAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIG91dHB1dCA9IG5ldyBJbnQxNkFycmF5KHNhbXBsZXMpO1xuICAgICAgZm9yIChpID0gX2kgPSAwOyBfaSA8IHNhbXBsZXM7IGkgPSBfaSArPSAxKSB7XG4gICAgICAgIG91dHB1dFtpXSA9IHRhYmxlW3N0cmVhbS5yZWFkVUludDgoKV07XG4gICAgICB9XG4gICAgICByZXR1cm4gb3V0cHV0O1xuICAgIH07XG5cbiAgICByZXR1cm4gWExBV0RlY29kZXI7XG5cbiAgfSkoRGVjb2Rlcik7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuNy4xXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBCdWZmZXJMaXN0LCBEZW11eGVyLCBFdmVudEVtaXR0ZXIsIFN0cmVhbSxcbiAgICBfX2hhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgICBfX2V4dGVuZHMgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKF9faGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfTtcblxuICBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuL2NvcmUvZXZlbnRzJyk7XG5cbiAgQnVmZmVyTGlzdCA9IHJlcXVpcmUoJy4vY29yZS9idWZmZXJsaXN0Jyk7XG5cbiAgU3RyZWFtID0gcmVxdWlyZSgnLi9jb3JlL3N0cmVhbScpO1xuXG4gIERlbXV4ZXIgPSAoZnVuY3Rpb24oX3N1cGVyKSB7XG4gICAgdmFyIGZvcm1hdHM7XG5cbiAgICBfX2V4dGVuZHMoRGVtdXhlciwgX3N1cGVyKTtcblxuICAgIERlbXV4ZXIucHJvYmUgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gRGVtdXhlcihzb3VyY2UsIGNodW5rKSB7XG4gICAgICB2YXIgbGlzdCwgcmVjZWl2ZWQ7XG4gICAgICBsaXN0ID0gbmV3IEJ1ZmZlckxpc3Q7XG4gICAgICBsaXN0LmFwcGVuZChjaHVuayk7XG4gICAgICB0aGlzLnN0cmVhbSA9IG5ldyBTdHJlYW0obGlzdCk7XG4gICAgICByZWNlaXZlZCA9IGZhbHNlO1xuICAgICAgc291cmNlLm9uKCdkYXRhJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihjaHVuaykge1xuICAgICAgICAgIHZhciBlO1xuICAgICAgICAgIHJlY2VpdmVkID0gdHJ1ZTtcbiAgICAgICAgICBsaXN0LmFwcGVuZChjaHVuayk7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBfdGhpcy5yZWFkQ2h1bmsoY2h1bmspO1xuICAgICAgICAgIH0gY2F0Y2ggKF9lcnJvcikge1xuICAgICAgICAgICAgZSA9IF9lcnJvcjtcbiAgICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdlcnJvcicsIGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHNvdXJjZS5vbignZXJyb3InLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGVycikge1xuICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdlcnJvcicsIGVycik7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICBzb3VyY2Uub24oJ2VuZCcsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgaWYgKCFyZWNlaXZlZCkge1xuICAgICAgICAgICAgX3RoaXMucmVhZENodW5rKGNodW5rKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ2VuZCcpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5zZWVrUG9pbnRzID0gW107XG4gICAgICB0aGlzLmluaXQoKTtcbiAgICB9XG5cbiAgICBEZW11eGVyLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24oKSB7fTtcblxuICAgIERlbXV4ZXIucHJvdG90eXBlLnJlYWRDaHVuayA9IGZ1bmN0aW9uKGNodW5rKSB7fTtcblxuICAgIERlbXV4ZXIucHJvdG90eXBlLmFkZFNlZWtQb2ludCA9IGZ1bmN0aW9uKG9mZnNldCwgdGltZXN0YW1wKSB7XG4gICAgICB2YXIgaW5kZXg7XG4gICAgICBpbmRleCA9IHRoaXMuc2VhcmNoVGltZXN0YW1wKHRpbWVzdGFtcCk7XG4gICAgICByZXR1cm4gdGhpcy5zZWVrUG9pbnRzLnNwbGljZShpbmRleCwgMCwge1xuICAgICAgICBvZmZzZXQ6IG9mZnNldCxcbiAgICAgICAgdGltZXN0YW1wOiB0aW1lc3RhbXBcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBEZW11eGVyLnByb3RvdHlwZS5zZWFyY2hUaW1lc3RhbXAgPSBmdW5jdGlvbih0aW1lc3RhbXAsIGJhY2t3YXJkKSB7XG4gICAgICB2YXIgaGlnaCwgbG93LCBtaWQsIHRpbWU7XG4gICAgICBsb3cgPSAwO1xuICAgICAgaGlnaCA9IHRoaXMuc2Vla1BvaW50cy5sZW5ndGg7XG4gICAgICBpZiAoaGlnaCA+IDAgJiYgdGhpcy5zZWVrUG9pbnRzW2hpZ2ggLSAxXS50aW1lc3RhbXAgPCB0aW1lc3RhbXApIHtcbiAgICAgICAgcmV0dXJuIGhpZ2g7XG4gICAgICB9XG4gICAgICB3aGlsZSAobG93IDwgaGlnaCkge1xuICAgICAgICBtaWQgPSAobG93ICsgaGlnaCkgPj4gMTtcbiAgICAgICAgdGltZSA9IHRoaXMuc2Vla1BvaW50c1ttaWRdLnRpbWVzdGFtcDtcbiAgICAgICAgaWYgKHRpbWUgPCB0aW1lc3RhbXApIHtcbiAgICAgICAgICBsb3cgPSBtaWQgKyAxO1xuICAgICAgICB9IGVsc2UgaWYgKHRpbWUgPj0gdGltZXN0YW1wKSB7XG4gICAgICAgICAgaGlnaCA9IG1pZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGhpZ2ggPiB0aGlzLnNlZWtQb2ludHMubGVuZ3RoKSB7XG4gICAgICAgIGhpZ2ggPSB0aGlzLnNlZWtQb2ludHMubGVuZ3RoO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGhpZ2g7XG4gICAgfTtcblxuICAgIERlbXV4ZXIucHJvdG90eXBlLnNlZWsgPSBmdW5jdGlvbih0aW1lc3RhbXApIHtcbiAgICAgIHZhciBpbmRleCwgc2Vla1BvaW50O1xuICAgICAgaWYgKHRoaXMuZm9ybWF0ICYmIHRoaXMuZm9ybWF0LmZyYW1lc1BlclBhY2tldCA+IDAgJiYgdGhpcy5mb3JtYXQuYnl0ZXNQZXJQYWNrZXQgPiAwKSB7XG4gICAgICAgIHNlZWtQb2ludCA9IHtcbiAgICAgICAgICB0aW1lc3RhbXA6IHRpbWVzdGFtcCxcbiAgICAgICAgICBvZmZzZXQ6IHRoaXMuZm9ybWF0LmJ5dGVzUGVyUGFja2V0ICogdGltZXN0YW1wIC8gdGhpcy5mb3JtYXQuZnJhbWVzUGVyUGFja2V0XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBzZWVrUG9pbnQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpbmRleCA9IHRoaXMuc2VhcmNoVGltZXN0YW1wKHRpbWVzdGFtcCk7XG4gICAgICAgIHJldHVybiB0aGlzLnNlZWtQb2ludHNbaW5kZXhdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBmb3JtYXRzID0gW107XG5cbiAgICBEZW11eGVyLnJlZ2lzdGVyID0gZnVuY3Rpb24oZGVtdXhlcikge1xuICAgICAgcmV0dXJuIGZvcm1hdHMucHVzaChkZW11eGVyKTtcbiAgICB9O1xuXG4gICAgRGVtdXhlci5maW5kID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICB2YXIgZSwgZm9ybWF0LCBvZmZzZXQsIHN0cmVhbSwgX2ksIF9sZW47XG4gICAgICBzdHJlYW0gPSBTdHJlYW0uZnJvbUJ1ZmZlcihidWZmZXIpO1xuICAgICAgZm9yIChfaSA9IDAsIF9sZW4gPSBmb3JtYXRzLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgIGZvcm1hdCA9IGZvcm1hdHNbX2ldO1xuICAgICAgICBvZmZzZXQgPSBzdHJlYW0ub2Zmc2V0O1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGlmIChmb3JtYXQucHJvYmUoc3RyZWFtKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZvcm1hdDtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKF9lcnJvcikge1xuICAgICAgICAgIGUgPSBfZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgc3RyZWFtLnNlZWsob2Zmc2V0KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG5cbiAgICByZXR1cm4gRGVtdXhlcjtcblxuICB9KShFdmVudEVtaXR0ZXIpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gRGVtdXhlcjtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS43LjFcbihmdW5jdGlvbigpIHtcbiAgdmFyIEFJRkZEZW11eGVyLCBEZW11eGVyLFxuICAgIF9faGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5LFxuICAgIF9fZXh0ZW5kcyA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoX19oYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9O1xuXG4gIERlbXV4ZXIgPSByZXF1aXJlKCcuLi9kZW11eGVyJyk7XG5cbiAgQUlGRkRlbXV4ZXIgPSAoZnVuY3Rpb24oX3N1cGVyKSB7XG4gICAgX19leHRlbmRzKEFJRkZEZW11eGVyLCBfc3VwZXIpO1xuXG4gICAgZnVuY3Rpb24gQUlGRkRlbXV4ZXIoKSB7XG4gICAgICByZXR1cm4gQUlGRkRlbXV4ZXIuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgRGVtdXhlci5yZWdpc3RlcihBSUZGRGVtdXhlcik7XG5cbiAgICBBSUZGRGVtdXhlci5wcm9iZSA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgdmFyIF9yZWY7XG4gICAgICByZXR1cm4gYnVmZmVyLnBlZWtTdHJpbmcoMCwgNCkgPT09ICdGT1JNJyAmJiAoKF9yZWYgPSBidWZmZXIucGVla1N0cmluZyg4LCA0KSkgPT09ICdBSUZGJyB8fCBfcmVmID09PSAnQUlGQycpO1xuICAgIH07XG5cbiAgICBBSUZGRGVtdXhlci5wcm90b3R5cGUucmVhZENodW5rID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYnVmZmVyLCBmb3JtYXQsIG9mZnNldCwgX3JlZjtcbiAgICAgIGlmICghdGhpcy5yZWFkU3RhcnQgJiYgdGhpcy5zdHJlYW0uYXZhaWxhYmxlKDEyKSkge1xuICAgICAgICBpZiAodGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KSAhPT0gJ0ZPUk0nKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnSW52YWxpZCBBSUZGLicpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZmlsZVNpemUgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgIHRoaXMuZmlsZVR5cGUgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpO1xuICAgICAgICB0aGlzLnJlYWRTdGFydCA9IHRydWU7XG4gICAgICAgIGlmICgoX3JlZiA9IHRoaXMuZmlsZVR5cGUpICE9PSAnQUlGRicgJiYgX3JlZiAhPT0gJ0FJRkMnKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnSW52YWxpZCBBSUZGLicpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB3aGlsZSAodGhpcy5zdHJlYW0uYXZhaWxhYmxlKDEpKSB7XG4gICAgICAgIGlmICghdGhpcy5yZWFkSGVhZGVycyAmJiB0aGlzLnN0cmVhbS5hdmFpbGFibGUoOCkpIHtcbiAgICAgICAgICB0aGlzLnR5cGUgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpO1xuICAgICAgICAgIHRoaXMubGVuID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICB9XG4gICAgICAgIHN3aXRjaCAodGhpcy50eXBlKSB7XG4gICAgICAgICAgY2FzZSAnQ09NTSc6XG4gICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmF2YWlsYWJsZSh0aGlzLmxlbikpIHtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5mb3JtYXQgPSB7XG4gICAgICAgICAgICAgIGZvcm1hdElEOiAnbHBjbScsXG4gICAgICAgICAgICAgIGNoYW5uZWxzUGVyRnJhbWU6IHRoaXMuc3RyZWFtLnJlYWRVSW50MTYoKSxcbiAgICAgICAgICAgICAgc2FtcGxlQ291bnQ6IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKSxcbiAgICAgICAgICAgICAgYml0c1BlckNoYW5uZWw6IHRoaXMuc3RyZWFtLnJlYWRVSW50MTYoKSxcbiAgICAgICAgICAgICAgc2FtcGxlUmF0ZTogdGhpcy5zdHJlYW0ucmVhZEZsb2F0ODAoKSxcbiAgICAgICAgICAgICAgZnJhbWVzUGVyUGFja2V0OiAxLFxuICAgICAgICAgICAgICBsaXR0bGVFbmRpYW46IGZhbHNlLFxuICAgICAgICAgICAgICBmbG9hdGluZ1BvaW50OiBmYWxzZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHRoaXMuZm9ybWF0LmJ5dGVzUGVyUGFja2V0ID0gKHRoaXMuZm9ybWF0LmJpdHNQZXJDaGFubmVsIC8gOCkgKiB0aGlzLmZvcm1hdC5jaGFubmVsc1BlckZyYW1lO1xuICAgICAgICAgICAgaWYgKHRoaXMuZmlsZVR5cGUgPT09ICdBSUZDJykge1xuICAgICAgICAgICAgICBmb3JtYXQgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpO1xuICAgICAgICAgICAgICB0aGlzLmZvcm1hdC5saXR0bGVFbmRpYW4gPSBmb3JtYXQgPT09ICdzb3d0JyAmJiB0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCA+IDg7XG4gICAgICAgICAgICAgIHRoaXMuZm9ybWF0LmZsb2F0aW5nUG9pbnQgPSBmb3JtYXQgPT09ICdmbDMyJyB8fCBmb3JtYXQgPT09ICdmbDY0JztcbiAgICAgICAgICAgICAgaWYgKGZvcm1hdCA9PT0gJ3R3b3MnIHx8IGZvcm1hdCA9PT0gJ3Nvd3QnIHx8IGZvcm1hdCA9PT0gJ2ZsMzInIHx8IGZvcm1hdCA9PT0gJ2ZsNjQnIHx8IGZvcm1hdCA9PT0gJ05PTkUnKSB7XG4gICAgICAgICAgICAgICAgZm9ybWF0ID0gJ2xwY20nO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHRoaXMuZm9ybWF0LmZvcm1hdElEID0gZm9ybWF0O1xuICAgICAgICAgICAgICB0aGlzLmxlbiAtPSA0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSh0aGlzLmxlbiAtIDE4KTtcbiAgICAgICAgICAgIHRoaXMuZW1pdCgnZm9ybWF0JywgdGhpcy5mb3JtYXQpO1xuICAgICAgICAgICAgdGhpcy5lbWl0KCdkdXJhdGlvbicsIHRoaXMuZm9ybWF0LnNhbXBsZUNvdW50IC8gdGhpcy5mb3JtYXQuc2FtcGxlUmF0ZSAqIDEwMDAgfCAwKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ1NTTkQnOlxuICAgICAgICAgICAgaWYgKCEodGhpcy5yZWFkU1NOREhlYWRlciAmJiB0aGlzLnN0cmVhbS5hdmFpbGFibGUoNCkpKSB7XG4gICAgICAgICAgICAgIG9mZnNldCA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZShvZmZzZXQpO1xuICAgICAgICAgICAgICB0aGlzLnJlYWRTU05ESGVhZGVyID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJ1ZmZlciA9IHRoaXMuc3RyZWFtLnJlYWRTaW5nbGVCdWZmZXIodGhpcy5sZW4pO1xuICAgICAgICAgICAgdGhpcy5sZW4gLT0gYnVmZmVyLmxlbmd0aDtcbiAgICAgICAgICAgIHRoaXMucmVhZEhlYWRlcnMgPSB0aGlzLmxlbiA+IDA7XG4gICAgICAgICAgICB0aGlzLmVtaXQoJ2RhdGEnLCBidWZmZXIpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGlmICghdGhpcy5zdHJlYW0uYXZhaWxhYmxlKHRoaXMubGVuKSkge1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKHRoaXMubGVuKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy50eXBlICE9PSAnU1NORCcpIHtcbiAgICAgICAgICB0aGlzLnJlYWRIZWFkZXJzID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIEFJRkZEZW11eGVyO1xuXG4gIH0pKERlbXV4ZXIpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjcuMVxuKGZ1bmN0aW9uKCkge1xuICB2YXIgQVVEZW11eGVyLCBEZW11eGVyLFxuICAgIF9faGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5LFxuICAgIF9fZXh0ZW5kcyA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoX19oYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9O1xuXG4gIERlbXV4ZXIgPSByZXF1aXJlKCcuLi9kZW11eGVyJyk7XG5cbiAgQVVEZW11eGVyID0gKGZ1bmN0aW9uKF9zdXBlcikge1xuICAgIHZhciBicHMsIGZvcm1hdHM7XG5cbiAgICBfX2V4dGVuZHMoQVVEZW11eGVyLCBfc3VwZXIpO1xuXG4gICAgZnVuY3Rpb24gQVVEZW11eGVyKCkge1xuICAgICAgcmV0dXJuIEFVRGVtdXhlci5fX3N1cGVyX18uY29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICBEZW11eGVyLnJlZ2lzdGVyKEFVRGVtdXhlcik7XG5cbiAgICBBVURlbXV4ZXIucHJvYmUgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHJldHVybiBidWZmZXIucGVla1N0cmluZygwLCA0KSA9PT0gJy5zbmQnO1xuICAgIH07XG5cbiAgICBicHMgPSBbOCwgOCwgMTYsIDI0LCAzMiwgMzIsIDY0XTtcblxuICAgIGJwc1syNl0gPSA4O1xuXG4gICAgZm9ybWF0cyA9IHtcbiAgICAgIDE6ICd1bGF3JyxcbiAgICAgIDI3OiAnYWxhdydcbiAgICB9O1xuXG4gICAgQVVEZW11eGVyLnByb3RvdHlwZS5yZWFkQ2h1bmsgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBieXRlcywgZGF0YVNpemUsIGVuY29kaW5nLCBzaXplO1xuICAgICAgaWYgKCF0aGlzLnJlYWRIZWFkZXIgJiYgdGhpcy5zdHJlYW0uYXZhaWxhYmxlKDI0KSkge1xuICAgICAgICBpZiAodGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KSAhPT0gJy5zbmQnKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnSW52YWxpZCBBVSBmaWxlLicpO1xuICAgICAgICB9XG4gICAgICAgIHNpemUgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgIGRhdGFTaXplID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICBlbmNvZGluZyA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgdGhpcy5mb3JtYXQgPSB7XG4gICAgICAgICAgZm9ybWF0SUQ6IGZvcm1hdHNbZW5jb2RpbmddIHx8ICdscGNtJyxcbiAgICAgICAgICBsaXR0bGVFbmRpYW46IGZhbHNlLFxuICAgICAgICAgIGZsb2F0aW5nUG9pbnQ6IGVuY29kaW5nID09PSA2IHx8IGVuY29kaW5nID09PSA3LFxuICAgICAgICAgIGJpdHNQZXJDaGFubmVsOiBicHNbZW5jb2RpbmcgLSAxXSxcbiAgICAgICAgICBzYW1wbGVSYXRlOiB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCksXG4gICAgICAgICAgY2hhbm5lbHNQZXJGcmFtZTogdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpLFxuICAgICAgICAgIGZyYW1lc1BlclBhY2tldDogMVxuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwgPT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ2Vycm9yJywgJ1Vuc3VwcG9ydGVkIGVuY29kaW5nIGluIEFVIGZpbGUuJyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5mb3JtYXQuYnl0ZXNQZXJQYWNrZXQgPSAodGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwgLyA4KSAqIHRoaXMuZm9ybWF0LmNoYW5uZWxzUGVyRnJhbWU7XG4gICAgICAgIGlmIChkYXRhU2l6ZSAhPT0gMHhmZmZmZmZmZikge1xuICAgICAgICAgIGJ5dGVzID0gdGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwgLyA4O1xuICAgICAgICAgIHRoaXMuZW1pdCgnZHVyYXRpb24nLCBkYXRhU2l6ZSAvIGJ5dGVzIC8gdGhpcy5mb3JtYXQuY2hhbm5lbHNQZXJGcmFtZSAvIHRoaXMuZm9ybWF0LnNhbXBsZVJhdGUgKiAxMDAwIHwgMCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5lbWl0KCdmb3JtYXQnLCB0aGlzLmZvcm1hdCk7XG4gICAgICAgIHRoaXMucmVhZEhlYWRlciA9IHRydWU7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5yZWFkSGVhZGVyKSB7XG4gICAgICAgIHdoaWxlICh0aGlzLnN0cmVhbS5hdmFpbGFibGUoMSkpIHtcbiAgICAgICAgICB0aGlzLmVtaXQoJ2RhdGEnLCB0aGlzLnN0cmVhbS5yZWFkU2luZ2xlQnVmZmVyKHRoaXMuc3RyZWFtLnJlbWFpbmluZ0J5dGVzKCkpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gQVVEZW11eGVyO1xuXG4gIH0pKERlbXV4ZXIpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjcuMVxuKGZ1bmN0aW9uKCkge1xuICB2YXIgQ0FGRGVtdXhlciwgRGVtdXhlciwgTTRBRGVtdXhlcixcbiAgICBfX2hhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgICBfX2V4dGVuZHMgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKF9faGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfTtcblxuICBEZW11eGVyID0gcmVxdWlyZSgnLi4vZGVtdXhlcicpO1xuXG4gIE00QURlbXV4ZXIgPSByZXF1aXJlKCcuL200YScpO1xuXG4gIENBRkRlbXV4ZXIgPSAoZnVuY3Rpb24oX3N1cGVyKSB7XG4gICAgX19leHRlbmRzKENBRkRlbXV4ZXIsIF9zdXBlcik7XG5cbiAgICBmdW5jdGlvbiBDQUZEZW11eGVyKCkge1xuICAgICAgcmV0dXJuIENBRkRlbXV4ZXIuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgRGVtdXhlci5yZWdpc3RlcihDQUZEZW11eGVyKTtcblxuICAgIENBRkRlbXV4ZXIucHJvYmUgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHJldHVybiBidWZmZXIucGVla1N0cmluZygwLCA0KSA9PT0gJ2NhZmYnO1xuICAgIH07XG5cbiAgICBDQUZEZW11eGVyLnByb3RvdHlwZS5yZWFkQ2h1bmsgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBidWZmZXIsIGJ5dGVPZmZzZXQsIGNvb2tpZSwgZW50cmllcywgZmxhZ3MsIGksIGtleSwgbWV0YWRhdGEsIG9mZnNldCwgc2FtcGxlT2Zmc2V0LCB2YWx1ZSwgX2ksIF9qLCBfcmVmO1xuICAgICAgaWYgKCF0aGlzLmZvcm1hdCAmJiB0aGlzLnN0cmVhbS5hdmFpbGFibGUoNjQpKSB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpICE9PSAnY2FmZicpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsIFwiSW52YWxpZCBDQUYsIGRvZXMgbm90IGJlZ2luIHdpdGggJ2NhZmYnXCIpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpICE9PSAnZGVzYycpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsIFwiSW52YWxpZCBDQUYsICdjYWZmJyBpcyBub3QgZm9sbG93ZWQgYnkgJ2Rlc2MnXCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghKHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKSA9PT0gMCAmJiB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCkgPT09IDMyKSkge1xuICAgICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ2Vycm9yJywgXCJJbnZhbGlkICdkZXNjJyBzaXplLCBzaG91bGQgYmUgMzJcIik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5mb3JtYXQgPSB7fTtcbiAgICAgICAgdGhpcy5mb3JtYXQuc2FtcGxlUmF0ZSA9IHRoaXMuc3RyZWFtLnJlYWRGbG9hdDY0KCk7XG4gICAgICAgIHRoaXMuZm9ybWF0LmZvcm1hdElEID0gdGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KTtcbiAgICAgICAgZmxhZ3MgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgIGlmICh0aGlzLmZvcm1hdC5mb3JtYXRJRCA9PT0gJ2xwY20nKSB7XG4gICAgICAgICAgdGhpcy5mb3JtYXQuZmxvYXRpbmdQb2ludCA9IEJvb2xlYW4oZmxhZ3MgJiAxKTtcbiAgICAgICAgICB0aGlzLmZvcm1hdC5saXR0bGVFbmRpYW4gPSBCb29sZWFuKGZsYWdzICYgMik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5mb3JtYXQuYnl0ZXNQZXJQYWNrZXQgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgIHRoaXMuZm9ybWF0LmZyYW1lc1BlclBhY2tldCA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgdGhpcy5mb3JtYXQuY2hhbm5lbHNQZXJGcmFtZSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgdGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgIHRoaXMuZW1pdCgnZm9ybWF0JywgdGhpcy5mb3JtYXQpO1xuICAgICAgfVxuICAgICAgd2hpbGUgKHRoaXMuc3RyZWFtLmF2YWlsYWJsZSgxKSkge1xuICAgICAgICBpZiAoIXRoaXMuaGVhZGVyQ2FjaGUpIHtcbiAgICAgICAgICB0aGlzLmhlYWRlckNhY2hlID0ge1xuICAgICAgICAgICAgdHlwZTogdGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KSxcbiAgICAgICAgICAgIG92ZXJzaXplOiB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCkgIT09IDAsXG4gICAgICAgICAgICBzaXplOiB0aGlzLnN0cmVhbS5yZWFkVUludDMyKClcbiAgICAgICAgICB9O1xuICAgICAgICAgIGlmICh0aGlzLmhlYWRlckNhY2hlLm92ZXJzaXplKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsIFwiSG9seSBTaGl0LCBhbiBvdmVyc2l6ZWQgZmlsZSwgbm90IHN1cHBvcnRlZCBpbiBKU1wiKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc3dpdGNoICh0aGlzLmhlYWRlckNhY2hlLnR5cGUpIHtcbiAgICAgICAgICBjYXNlICdrdWtpJzpcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5hdmFpbGFibGUodGhpcy5oZWFkZXJDYWNoZS5zaXplKSkge1xuICAgICAgICAgICAgICBpZiAodGhpcy5mb3JtYXQuZm9ybWF0SUQgPT09ICdhYWMgJykge1xuICAgICAgICAgICAgICAgIG9mZnNldCA9IHRoaXMuc3RyZWFtLm9mZnNldCArIHRoaXMuaGVhZGVyQ2FjaGUuc2l6ZTtcbiAgICAgICAgICAgICAgICBpZiAoY29va2llID0gTTRBRGVtdXhlci5yZWFkRXNkcyh0aGlzLnN0cmVhbSkpIHtcbiAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdCgnY29va2llJywgY29va2llKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2VlayhvZmZzZXQpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGJ1ZmZlciA9IHRoaXMuc3RyZWFtLnJlYWRCdWZmZXIodGhpcy5oZWFkZXJDYWNoZS5zaXplKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXQoJ2Nvb2tpZScsIGJ1ZmZlcik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdGhpcy5oZWFkZXJDYWNoZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdwYWt0JzpcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5hdmFpbGFibGUodGhpcy5oZWFkZXJDYWNoZS5zaXplKSkge1xuICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnU2l6ZXMgZ3JlYXRlciB0aGFuIDMyIGJpdHMgYXJlIG5vdCBzdXBwb3J0ZWQuJyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdGhpcy5udW1QYWNrZXRzID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnU2l6ZXMgZ3JlYXRlciB0aGFuIDMyIGJpdHMgYXJlIG5vdCBzdXBwb3J0ZWQuJyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdGhpcy5udW1GcmFtZXMgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgICAgICAgIHRoaXMucHJpbWluZ0ZyYW1lcyA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgICAgICAgdGhpcy5yZW1haW5kZXJGcmFtZXMgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgICAgICAgIHRoaXMuZW1pdCgnZHVyYXRpb24nLCB0aGlzLm51bUZyYW1lcyAvIHRoaXMuZm9ybWF0LnNhbXBsZVJhdGUgKiAxMDAwIHwgMCk7XG4gICAgICAgICAgICAgIHRoaXMuc2VudER1cmF0aW9uID0gdHJ1ZTtcbiAgICAgICAgICAgICAgYnl0ZU9mZnNldCA9IDA7XG4gICAgICAgICAgICAgIHNhbXBsZU9mZnNldCA9IDA7XG4gICAgICAgICAgICAgIGZvciAoaSA9IF9pID0gMCwgX3JlZiA9IHRoaXMubnVtUGFja2V0czsgX2kgPCBfcmVmOyBpID0gX2kgKz0gMSkge1xuICAgICAgICAgICAgICAgIHRoaXMuYWRkU2Vla1BvaW50KGJ5dGVPZmZzZXQsIHNhbXBsZU9mZnNldCk7XG4gICAgICAgICAgICAgICAgYnl0ZU9mZnNldCArPSB0aGlzLmZvcm1hdC5ieXRlc1BlclBhY2tldCB8fCBNNEFEZW11eGVyLnJlYWREZXNjckxlbih0aGlzLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgc2FtcGxlT2Zmc2V0ICs9IHRoaXMuZm9ybWF0LmZyYW1lc1BlclBhY2tldCB8fCBNNEFEZW11eGVyLnJlYWREZXNjckxlbih0aGlzLnN0cmVhbSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdGhpcy5oZWFkZXJDYWNoZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdpbmZvJzpcbiAgICAgICAgICAgIGVudHJpZXMgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgICAgICBtZXRhZGF0YSA9IHt9O1xuICAgICAgICAgICAgZm9yIChpID0gX2ogPSAwOyAwIDw9IGVudHJpZXMgPyBfaiA8IGVudHJpZXMgOiBfaiA+IGVudHJpZXM7IGkgPSAwIDw9IGVudHJpZXMgPyArK19qIDogLS1faikge1xuICAgICAgICAgICAgICBrZXkgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKG51bGwpO1xuICAgICAgICAgICAgICB2YWx1ZSA9IHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcobnVsbCk7XG4gICAgICAgICAgICAgIG1ldGFkYXRhW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZW1pdCgnbWV0YWRhdGEnLCBtZXRhZGF0YSk7XG4gICAgICAgICAgICB0aGlzLmhlYWRlckNhY2hlID0gbnVsbDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ2RhdGEnOlxuICAgICAgICAgICAgaWYgKCF0aGlzLnNlbnRGaXJzdERhdGFDaHVuaykge1xuICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgICAgICAgICB0aGlzLmhlYWRlckNhY2hlLnNpemUgLT0gNDtcbiAgICAgICAgICAgICAgaWYgKHRoaXMuZm9ybWF0LmJ5dGVzUGVyUGFja2V0ICE9PSAwICYmICF0aGlzLnNlbnREdXJhdGlvbikge1xuICAgICAgICAgICAgICAgIHRoaXMubnVtRnJhbWVzID0gdGhpcy5oZWFkZXJDYWNoZS5zaXplIC8gdGhpcy5mb3JtYXQuYnl0ZXNQZXJQYWNrZXQ7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0KCdkdXJhdGlvbicsIHRoaXMubnVtRnJhbWVzIC8gdGhpcy5mb3JtYXQuc2FtcGxlUmF0ZSAqIDEwMDAgfCAwKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB0aGlzLnNlbnRGaXJzdERhdGFDaHVuayA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBidWZmZXIgPSB0aGlzLnN0cmVhbS5yZWFkU2luZ2xlQnVmZmVyKHRoaXMuaGVhZGVyQ2FjaGUuc2l6ZSk7XG4gICAgICAgICAgICB0aGlzLmhlYWRlckNhY2hlLnNpemUgLT0gYnVmZmVyLmxlbmd0aDtcbiAgICAgICAgICAgIHRoaXMuZW1pdCgnZGF0YScsIGJ1ZmZlcik7XG4gICAgICAgICAgICBpZiAodGhpcy5oZWFkZXJDYWNoZS5zaXplIDw9IDApIHtcbiAgICAgICAgICAgICAgdGhpcy5oZWFkZXJDYWNoZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmF2YWlsYWJsZSh0aGlzLmhlYWRlckNhY2hlLnNpemUpKSB7XG4gICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UodGhpcy5oZWFkZXJDYWNoZS5zaXplKTtcbiAgICAgICAgICAgICAgdGhpcy5oZWFkZXJDYWNoZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIENBRkRlbXV4ZXI7XG5cbiAgfSkoRGVtdXhlcik7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuNy4xXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBEZW11eGVyLCBNNEFEZW11eGVyLFxuICAgIF9faGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5LFxuICAgIF9fZXh0ZW5kcyA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoX19oYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIF9faW5kZXhPZiA9IFtdLmluZGV4T2YgfHwgZnVuY3Rpb24oaXRlbSkgeyBmb3IgKHZhciBpID0gMCwgbCA9IHRoaXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7IGlmIChpIGluIHRoaXMgJiYgdGhpc1tpXSA9PT0gaXRlbSkgcmV0dXJuIGk7IH0gcmV0dXJuIC0xOyB9O1xuXG4gIERlbXV4ZXIgPSByZXF1aXJlKCcuLi9kZW11eGVyJyk7XG5cbiAgTTRBRGVtdXhlciA9IChmdW5jdGlvbihfc3VwZXIpIHtcbiAgICB2YXIgQklUU19QRVJfQ0hBTk5FTCwgVFlQRVMsIGFmdGVyLCBhdG9tLCBhdG9tcywgYm9vbCwgY29udGFpbmVycywgZGlza1RyYWNrLCBnZW5yZXMsIG1ldGEsIHN0cmluZztcblxuICAgIF9fZXh0ZW5kcyhNNEFEZW11eGVyLCBfc3VwZXIpO1xuXG4gICAgZnVuY3Rpb24gTTRBRGVtdXhlcigpIHtcbiAgICAgIHJldHVybiBNNEFEZW11eGVyLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIERlbXV4ZXIucmVnaXN0ZXIoTTRBRGVtdXhlcik7XG5cbiAgICBUWVBFUyA9IFsnTTRBICcsICdNNFAgJywgJ000QiAnLCAnTTRWICcsICdpc29tJywgJ21wNDInLCAncXQgICddO1xuXG4gICAgTTRBRGVtdXhlci5wcm9iZSA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgdmFyIF9yZWY7XG4gICAgICByZXR1cm4gYnVmZmVyLnBlZWtTdHJpbmcoNCwgNCkgPT09ICdmdHlwJyAmJiAoX3JlZiA9IGJ1ZmZlci5wZWVrU3RyaW5nKDgsIDQpLCBfX2luZGV4T2YuY2FsbChUWVBFUywgX3JlZikgPj0gMCk7XG4gICAgfTtcblxuICAgIE00QURlbXV4ZXIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuYXRvbXMgPSBbXTtcbiAgICAgIHRoaXMub2Zmc2V0cyA9IFtdO1xuICAgICAgdGhpcy50cmFjayA9IG51bGw7XG4gICAgICByZXR1cm4gdGhpcy50cmFja3MgPSBbXTtcbiAgICB9O1xuXG4gICAgYXRvbXMgPSB7fTtcblxuICAgIGNvbnRhaW5lcnMgPSB7fTtcblxuICAgIGF0b20gPSBmdW5jdGlvbihuYW1lLCBmbikge1xuICAgICAgdmFyIGMsIGNvbnRhaW5lciwgX2ksIF9sZW4sIF9yZWY7XG4gICAgICBjID0gW107XG4gICAgICBfcmVmID0gbmFtZS5zcGxpdCgnLicpLnNsaWNlKDAsIC0xKTtcbiAgICAgIGZvciAoX2kgPSAwLCBfbGVuID0gX3JlZi5sZW5ndGg7IF9pIDwgX2xlbjsgX2krKykge1xuICAgICAgICBjb250YWluZXIgPSBfcmVmW19pXTtcbiAgICAgICAgYy5wdXNoKGNvbnRhaW5lcik7XG4gICAgICAgIGNvbnRhaW5lcnNbYy5qb2luKCcuJyldID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGlmIChhdG9tc1tuYW1lXSA9PSBudWxsKSB7XG4gICAgICAgIGF0b21zW25hbWVdID0ge307XG4gICAgICB9XG4gICAgICByZXR1cm4gYXRvbXNbbmFtZV0uZm4gPSBmbjtcbiAgICB9O1xuXG4gICAgYWZ0ZXIgPSBmdW5jdGlvbihuYW1lLCBmbikge1xuICAgICAgaWYgKGF0b21zW25hbWVdID09IG51bGwpIHtcbiAgICAgICAgYXRvbXNbbmFtZV0gPSB7fTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhdG9tc1tuYW1lXS5hZnRlciA9IGZuO1xuICAgIH07XG5cbiAgICBNNEFEZW11eGVyLnByb3RvdHlwZS5yZWFkQ2h1bmsgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBoYW5kbGVyLCBwYXRoLCB0eXBlO1xuICAgICAgdGhpc1tcImJyZWFrXCJdID0gZmFsc2U7XG4gICAgICB3aGlsZSAodGhpcy5zdHJlYW0uYXZhaWxhYmxlKDEpICYmICF0aGlzW1wiYnJlYWtcIl0pIHtcbiAgICAgICAgaWYgKCF0aGlzLnJlYWRIZWFkZXJzKSB7XG4gICAgICAgICAgaWYgKCF0aGlzLnN0cmVhbS5hdmFpbGFibGUoOCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5sZW4gPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCkgLSA4O1xuICAgICAgICAgIHRoaXMudHlwZSA9IHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcoNCk7XG4gICAgICAgICAgaWYgKHRoaXMubGVuID09PSAwKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5hdG9tcy5wdXNoKHRoaXMudHlwZSk7XG4gICAgICAgICAgdGhpcy5vZmZzZXRzLnB1c2godGhpcy5zdHJlYW0ub2Zmc2V0ICsgdGhpcy5sZW4pO1xuICAgICAgICAgIHRoaXMucmVhZEhlYWRlcnMgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHBhdGggPSB0aGlzLmF0b21zLmpvaW4oJy4nKTtcbiAgICAgICAgaGFuZGxlciA9IGF0b21zW3BhdGhdO1xuICAgICAgICBpZiAoaGFuZGxlciAhPSBudWxsID8gaGFuZGxlci5mbiA6IHZvaWQgMCkge1xuICAgICAgICAgIGlmICghKHRoaXMuc3RyZWFtLmF2YWlsYWJsZSh0aGlzLmxlbikgfHwgcGF0aCA9PT0gJ21kYXQnKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICBoYW5kbGVyLmZuLmNhbGwodGhpcyk7XG4gICAgICAgICAgaWYgKHBhdGggaW4gY29udGFpbmVycykge1xuICAgICAgICAgICAgdGhpcy5yZWFkSGVhZGVycyA9IGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChwYXRoIGluIGNvbnRhaW5lcnMpIHtcbiAgICAgICAgICB0aGlzLnJlYWRIZWFkZXJzID0gZmFsc2U7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKCF0aGlzLnN0cmVhbS5hdmFpbGFibGUodGhpcy5sZW4pKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UodGhpcy5sZW4pO1xuICAgICAgICB9XG4gICAgICAgIHdoaWxlICh0aGlzLnN0cmVhbS5vZmZzZXQgPj0gdGhpcy5vZmZzZXRzW3RoaXMub2Zmc2V0cy5sZW5ndGggLSAxXSkge1xuICAgICAgICAgIGhhbmRsZXIgPSBhdG9tc1t0aGlzLmF0b21zLmpvaW4oJy4nKV07XG4gICAgICAgICAgaWYgKGhhbmRsZXIgIT0gbnVsbCA/IGhhbmRsZXIuYWZ0ZXIgOiB2b2lkIDApIHtcbiAgICAgICAgICAgIGhhbmRsZXIuYWZ0ZXIuY2FsbCh0aGlzKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdHlwZSA9IHRoaXMuYXRvbXMucG9wKCk7XG4gICAgICAgICAgdGhpcy5vZmZzZXRzLnBvcCgpO1xuICAgICAgICAgIHRoaXMucmVhZEhlYWRlcnMgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBhdG9tKCdmdHlwJywgZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgX3JlZjtcbiAgICAgIGlmIChfcmVmID0gdGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KSwgX19pbmRleE9mLmNhbGwoVFlQRVMsIF9yZWYpIDwgMCkge1xuICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsICdOb3QgYSB2YWxpZCBNNEEgZmlsZS4nKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLnN0cmVhbS5hZHZhbmNlKHRoaXMubGVuIC0gNCk7XG4gICAgfSk7XG5cbiAgICBhdG9tKCdtb292LnRyYWsnLCBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMudHJhY2sgPSB7fTtcbiAgICAgIHJldHVybiB0aGlzLnRyYWNrcy5wdXNoKHRoaXMudHJhY2spO1xuICAgIH0pO1xuXG4gICAgYXRvbSgnbW9vdi50cmFrLnRraGQnLCBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDgpO1xuICAgICAgdGhpcy50cmFjay5pZCA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgIHJldHVybiB0aGlzLnN0cmVhbS5hZHZhbmNlKHRoaXMubGVuIC0gMTYpO1xuICAgIH0pO1xuXG4gICAgYXRvbSgnbW9vdi50cmFrLm1kaWEuaGRscicsIGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICB0aGlzLnRyYWNrLnR5cGUgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSgxMik7XG4gICAgICByZXR1cm4gdGhpcy5zdHJlYW0uYWR2YW5jZSh0aGlzLmxlbiAtIDI0KTtcbiAgICB9KTtcblxuICAgIGF0b20oJ21vb3YudHJhay5tZGlhLm1kaGQnLCBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDgpO1xuICAgICAgdGhpcy50cmFjay50aW1lU2NhbGUgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICB0aGlzLnRyYWNrLmR1cmF0aW9uID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgcmV0dXJuIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgfSk7XG5cbiAgICBCSVRTX1BFUl9DSEFOTkVMID0ge1xuICAgICAgdWxhdzogOCxcbiAgICAgIGFsYXc6IDgsXG4gICAgICBpbjI0OiAyNCxcbiAgICAgIGluMzI6IDMyLFxuICAgICAgZmwzMjogMzIsXG4gICAgICBmbDY0OiA2NFxuICAgIH07XG5cbiAgICBhdG9tKCdtb292LnRyYWsubWRpYS5taW5mLnN0Ymwuc3RzZCcsIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGZvcm1hdCwgbnVtRW50cmllcywgdmVyc2lvbiwgX3JlZiwgX3JlZjE7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgbnVtRW50cmllcyA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgIGlmICh0aGlzLnRyYWNrLnR5cGUgIT09ICdzb3VuJykge1xuICAgICAgICByZXR1cm4gdGhpcy5zdHJlYW0uYWR2YW5jZSh0aGlzLmxlbiAtIDgpO1xuICAgICAgfVxuICAgICAgaWYgKG51bUVudHJpZXMgIT09IDEpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCBcIk9ubHkgZXhwZWN0aW5nIG9uZSBlbnRyeSBpbiBzYW1wbGUgZGVzY3JpcHRpb24gYXRvbSFcIik7XG4gICAgICB9XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgZm9ybWF0ID0gdGhpcy50cmFjay5mb3JtYXQgPSB7fTtcbiAgICAgIGZvcm1hdC5mb3JtYXRJRCA9IHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcoNCk7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDYpO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSgyKTtcbiAgICAgIHZlcnNpb24gPSB0aGlzLnN0cmVhbS5yZWFkVUludDE2KCk7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDYpO1xuICAgICAgZm9ybWF0LmNoYW5uZWxzUGVyRnJhbWUgPSB0aGlzLnN0cmVhbS5yZWFkVUludDE2KCk7XG4gICAgICBmb3JtYXQuYml0c1BlckNoYW5uZWwgPSB0aGlzLnN0cmVhbS5yZWFkVUludDE2KCk7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgZm9ybWF0LnNhbXBsZVJhdGUgPSB0aGlzLnN0cmVhbS5yZWFkVUludDE2KCk7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDIpO1xuICAgICAgaWYgKHZlcnNpb24gPT09IDEpIHtcbiAgICAgICAgZm9ybWF0LmZyYW1lc1BlclBhY2tldCA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgICAgZm9ybWF0LmJ5dGVzUGVyRnJhbWUgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICB9IGVsc2UgaWYgKHZlcnNpb24gIT09IDApIHtcbiAgICAgICAgdGhpcy5lbWl0KCdlcnJvcicsICdVbmtub3duIHZlcnNpb24gaW4gc3RzZCBhdG9tJyk7XG4gICAgICB9XG4gICAgICBpZiAoQklUU19QRVJfQ0hBTk5FTFtmb3JtYXQuZm9ybWF0SURdICE9IG51bGwpIHtcbiAgICAgICAgZm9ybWF0LmJpdHNQZXJDaGFubmVsID0gQklUU19QRVJfQ0hBTk5FTFtmb3JtYXQuZm9ybWF0SURdO1xuICAgICAgfVxuICAgICAgZm9ybWF0LmZsb2F0aW5nUG9pbnQgPSAoX3JlZiA9IGZvcm1hdC5mb3JtYXRJRCkgPT09ICdmbDMyJyB8fCBfcmVmID09PSAnZmw2NCc7XG4gICAgICBmb3JtYXQubGl0dGxlRW5kaWFuID0gZm9ybWF0LmZvcm1hdElEID09PSAnc293dCcgJiYgZm9ybWF0LmJpdHNQZXJDaGFubmVsID4gODtcbiAgICAgIGlmICgoX3JlZjEgPSBmb3JtYXQuZm9ybWF0SUQpID09PSAndHdvcycgfHwgX3JlZjEgPT09ICdzb3d0JyB8fCBfcmVmMSA9PT0gJ2luMjQnIHx8IF9yZWYxID09PSAnaW4zMicgfHwgX3JlZjEgPT09ICdmbDMyJyB8fCBfcmVmMSA9PT0gJ2ZsNjQnIHx8IF9yZWYxID09PSAncmF3ICcgfHwgX3JlZjEgPT09ICdOT05FJykge1xuICAgICAgICByZXR1cm4gZm9ybWF0LmZvcm1hdElEID0gJ2xwY20nO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgYXRvbSgnbW9vdi50cmFrLm1kaWEubWluZi5zdGJsLnN0c2QuYWxhYycsIGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgIHJldHVybiB0aGlzLnRyYWNrLmNvb2tpZSA9IHRoaXMuc3RyZWFtLnJlYWRCdWZmZXIodGhpcy5sZW4gLSA0KTtcbiAgICB9KTtcblxuICAgIGF0b20oJ21vb3YudHJhay5tZGlhLm1pbmYuc3RibC5zdHNkLmVzZHMnLCBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBvZmZzZXQ7XG4gICAgICBvZmZzZXQgPSB0aGlzLnN0cmVhbS5vZmZzZXQgKyB0aGlzLmxlbjtcbiAgICAgIHRoaXMudHJhY2suY29va2llID0gTTRBRGVtdXhlci5yZWFkRXNkcyh0aGlzLnN0cmVhbSk7XG4gICAgICByZXR1cm4gdGhpcy5zdHJlYW0uc2VlayhvZmZzZXQpO1xuICAgIH0pO1xuXG4gICAgYXRvbSgnbW9vdi50cmFrLm1kaWEubWluZi5zdGJsLnN0c2Qud2F2ZS5lbmRhJywgZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy50cmFjay5mb3JtYXQubGl0dGxlRW5kaWFuID0gISF0aGlzLnN0cmVhbS5yZWFkVUludDE2KCk7XG4gICAgfSk7XG5cbiAgICBNNEFEZW11eGVyLnJlYWREZXNjckxlbiA9IGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgICAgdmFyIGMsIGNvdW50LCBsZW47XG4gICAgICBsZW4gPSAwO1xuICAgICAgY291bnQgPSA0O1xuICAgICAgd2hpbGUgKGNvdW50LS0pIHtcbiAgICAgICAgYyA9IHN0cmVhbS5yZWFkVUludDgoKTtcbiAgICAgICAgbGVuID0gKGxlbiA8PCA3KSB8IChjICYgMHg3Zik7XG4gICAgICAgIGlmICghKGMgJiAweDgwKSkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbGVuO1xuICAgIH07XG5cbiAgICBNNEFEZW11eGVyLnJlYWRFc2RzID0gZnVuY3Rpb24oc3RyZWFtKSB7XG4gICAgICB2YXIgY29kZWNfaWQsIGZsYWdzLCBsZW4sIHRhZztcbiAgICAgIHN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgdGFnID0gc3RyZWFtLnJlYWRVSW50OCgpO1xuICAgICAgbGVuID0gTTRBRGVtdXhlci5yZWFkRGVzY3JMZW4oc3RyZWFtKTtcbiAgICAgIGlmICh0YWcgPT09IDB4MDMpIHtcbiAgICAgICAgc3RyZWFtLmFkdmFuY2UoMik7XG4gICAgICAgIGZsYWdzID0gc3RyZWFtLnJlYWRVSW50OCgpO1xuICAgICAgICBpZiAoZmxhZ3MgJiAweDgwKSB7XG4gICAgICAgICAgc3RyZWFtLmFkdmFuY2UoMik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZsYWdzICYgMHg0MCkge1xuICAgICAgICAgIHN0cmVhbS5hZHZhbmNlKHN0cmVhbS5yZWFkVUludDgoKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZsYWdzICYgMHgyMCkge1xuICAgICAgICAgIHN0cmVhbS5hZHZhbmNlKDIpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdHJlYW0uYWR2YW5jZSgyKTtcbiAgICAgIH1cbiAgICAgIHRhZyA9IHN0cmVhbS5yZWFkVUludDgoKTtcbiAgICAgIGxlbiA9IE00QURlbXV4ZXIucmVhZERlc2NyTGVuKHN0cmVhbSk7XG4gICAgICBpZiAodGFnID09PSAweDA0KSB7XG4gICAgICAgIGNvZGVjX2lkID0gc3RyZWFtLnJlYWRVSW50OCgpO1xuICAgICAgICBzdHJlYW0uYWR2YW5jZSgxKTtcbiAgICAgICAgc3RyZWFtLmFkdmFuY2UoMyk7XG4gICAgICAgIHN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgICBzdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgICAgdGFnID0gc3RyZWFtLnJlYWRVSW50OCgpO1xuICAgICAgICBsZW4gPSBNNEFEZW11eGVyLnJlYWREZXNjckxlbihzdHJlYW0pO1xuICAgICAgICBpZiAodGFnID09PSAweDA1KSB7XG4gICAgICAgICAgcmV0dXJuIHN0cmVhbS5yZWFkQnVmZmVyKGxlbik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG5cbiAgICBhdG9tKCdtb292LnRyYWsubWRpYS5taW5mLnN0Ymwuc3R0cycsIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGVudHJpZXMsIGksIF9pO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgIGVudHJpZXMgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICB0aGlzLnRyYWNrLnN0dHMgPSBbXTtcbiAgICAgIGZvciAoaSA9IF9pID0gMDsgX2kgPCBlbnRyaWVzOyBpID0gX2kgKz0gMSkge1xuICAgICAgICB0aGlzLnRyYWNrLnN0dHNbaV0gPSB7XG4gICAgICAgICAgY291bnQ6IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKSxcbiAgICAgICAgICBkdXJhdGlvbjogdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5zZXR1cFNlZWtQb2ludHMoKTtcbiAgICB9KTtcblxuICAgIGF0b20oJ21vb3YudHJhay5tZGlhLm1pbmYuc3RibC5zdHNjJywgZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgZW50cmllcywgaSwgX2k7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgZW50cmllcyA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgIHRoaXMudHJhY2suc3RzYyA9IFtdO1xuICAgICAgZm9yIChpID0gX2kgPSAwOyBfaSA8IGVudHJpZXM7IGkgPSBfaSArPSAxKSB7XG4gICAgICAgIHRoaXMudHJhY2suc3RzY1tpXSA9IHtcbiAgICAgICAgICBmaXJzdDogdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpLFxuICAgICAgICAgIGNvdW50OiB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCksXG4gICAgICAgICAgaWQ6IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKVxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuc2V0dXBTZWVrUG9pbnRzKCk7XG4gICAgfSk7XG5cbiAgICBhdG9tKCdtb292LnRyYWsubWRpYS5taW5mLnN0Ymwuc3RzeicsIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGVudHJpZXMsIGksIF9pO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgIHRoaXMudHJhY2suc2FtcGxlU2l6ZSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgIGVudHJpZXMgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICBpZiAodGhpcy50cmFjay5zYW1wbGVTaXplID09PSAwICYmIGVudHJpZXMgPiAwKSB7XG4gICAgICAgIHRoaXMudHJhY2suc2FtcGxlU2l6ZXMgPSBbXTtcbiAgICAgICAgZm9yIChpID0gX2kgPSAwOyBfaSA8IGVudHJpZXM7IGkgPSBfaSArPSAxKSB7XG4gICAgICAgICAgdGhpcy50cmFjay5zYW1wbGVTaXplc1tpXSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuc2V0dXBTZWVrUG9pbnRzKCk7XG4gICAgfSk7XG5cbiAgICBhdG9tKCdtb292LnRyYWsubWRpYS5taW5mLnN0Ymwuc3RjbycsIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGVudHJpZXMsIGksIF9pO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgIGVudHJpZXMgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICB0aGlzLnRyYWNrLmNodW5rT2Zmc2V0cyA9IFtdO1xuICAgICAgZm9yIChpID0gX2kgPSAwOyBfaSA8IGVudHJpZXM7IGkgPSBfaSArPSAxKSB7XG4gICAgICAgIHRoaXMudHJhY2suY2h1bmtPZmZzZXRzW2ldID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuc2V0dXBTZWVrUG9pbnRzKCk7XG4gICAgfSk7XG5cbiAgICBhdG9tKCdtb292LnRyYWsudHJlZi5jaGFwJywgZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgZW50cmllcywgaSwgX2k7XG4gICAgICBlbnRyaWVzID0gdGhpcy5sZW4gPj4gMjtcbiAgICAgIHRoaXMudHJhY2suY2hhcHRlclRyYWNrcyA9IFtdO1xuICAgICAgZm9yIChpID0gX2kgPSAwOyBfaSA8IGVudHJpZXM7IGkgPSBfaSArPSAxKSB7XG4gICAgICAgIHRoaXMudHJhY2suY2hhcHRlclRyYWNrc1tpXSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIE00QURlbXV4ZXIucHJvdG90eXBlLnNldHVwU2Vla1BvaW50cyA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGksIGosIG9mZnNldCwgcG9zaXRpb24sIHNhbXBsZUluZGV4LCBzaXplLCBzdHNjSW5kZXgsIHN0dHNJbmRleCwgc3R0c1NhbXBsZSwgdGltZXN0YW1wLCBfaSwgX2osIF9sZW4sIF9yZWYsIF9yZWYxLCBfcmVzdWx0cztcbiAgICAgIGlmICghKCh0aGlzLnRyYWNrLmNodW5rT2Zmc2V0cyAhPSBudWxsKSAmJiAodGhpcy50cmFjay5zdHNjICE9IG51bGwpICYmICh0aGlzLnRyYWNrLnNhbXBsZVNpemUgIT0gbnVsbCkgJiYgKHRoaXMudHJhY2suc3R0cyAhPSBudWxsKSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgc3RzY0luZGV4ID0gMDtcbiAgICAgIHN0dHNJbmRleCA9IDA7XG4gICAgICBzdHRzSW5kZXggPSAwO1xuICAgICAgc3R0c1NhbXBsZSA9IDA7XG4gICAgICBzYW1wbGVJbmRleCA9IDA7XG4gICAgICBvZmZzZXQgPSAwO1xuICAgICAgdGltZXN0YW1wID0gMDtcbiAgICAgIHRoaXMudHJhY2suc2Vla1BvaW50cyA9IFtdO1xuICAgICAgX3JlZiA9IHRoaXMudHJhY2suY2h1bmtPZmZzZXRzO1xuICAgICAgX3Jlc3VsdHMgPSBbXTtcbiAgICAgIGZvciAoaSA9IF9pID0gMCwgX2xlbiA9IF9yZWYubGVuZ3RoOyBfaSA8IF9sZW47IGkgPSArK19pKSB7XG4gICAgICAgIHBvc2l0aW9uID0gX3JlZltpXTtcbiAgICAgICAgZm9yIChqID0gX2ogPSAwLCBfcmVmMSA9IHRoaXMudHJhY2suc3RzY1tzdHNjSW5kZXhdLmNvdW50OyBfaiA8IF9yZWYxOyBqID0gX2ogKz0gMSkge1xuICAgICAgICAgIHRoaXMudHJhY2suc2Vla1BvaW50cy5wdXNoKHtcbiAgICAgICAgICAgIG9mZnNldDogb2Zmc2V0LFxuICAgICAgICAgICAgcG9zaXRpb246IHBvc2l0aW9uLFxuICAgICAgICAgICAgdGltZXN0YW1wOiB0aW1lc3RhbXBcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBzaXplID0gdGhpcy50cmFjay5zYW1wbGVTaXplIHx8IHRoaXMudHJhY2suc2FtcGxlU2l6ZXNbc2FtcGxlSW5kZXgrK107XG4gICAgICAgICAgb2Zmc2V0ICs9IHNpemU7XG4gICAgICAgICAgcG9zaXRpb24gKz0gc2l6ZTtcbiAgICAgICAgICB0aW1lc3RhbXAgKz0gdGhpcy50cmFjay5zdHRzW3N0dHNJbmRleF0uZHVyYXRpb247XG4gICAgICAgICAgaWYgKHN0dHNJbmRleCArIDEgPCB0aGlzLnRyYWNrLnN0dHMubGVuZ3RoICYmICsrc3R0c1NhbXBsZSA9PT0gdGhpcy50cmFjay5zdHRzW3N0dHNJbmRleF0uY291bnQpIHtcbiAgICAgICAgICAgIHN0dHNTYW1wbGUgPSAwO1xuICAgICAgICAgICAgc3R0c0luZGV4Kys7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChzdHNjSW5kZXggKyAxIDwgdGhpcy50cmFjay5zdHNjLmxlbmd0aCAmJiBpICsgMSA9PT0gdGhpcy50cmFjay5zdHNjW3N0c2NJbmRleCArIDFdLmZpcnN0KSB7XG4gICAgICAgICAgX3Jlc3VsdHMucHVzaChzdHNjSW5kZXgrKyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgX3Jlc3VsdHMucHVzaCh2b2lkIDApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gX3Jlc3VsdHM7XG4gICAgfTtcblxuICAgIGFmdGVyKCdtb292JywgZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgdHJhY2ssIF9pLCBfbGVuLCBfcmVmO1xuICAgICAgaWYgKHRoaXMubWRhdE9mZnNldCAhPSBudWxsKSB7XG4gICAgICAgIHRoaXMuc3RyZWFtLnNlZWsodGhpcy5tZGF0T2Zmc2V0IC0gOCk7XG4gICAgICB9XG4gICAgICBfcmVmID0gdGhpcy50cmFja3M7XG4gICAgICBmb3IgKF9pID0gMCwgX2xlbiA9IF9yZWYubGVuZ3RoOyBfaSA8IF9sZW47IF9pKyspIHtcbiAgICAgICAgdHJhY2sgPSBfcmVmW19pXTtcbiAgICAgICAgaWYgKCEodHJhY2sudHlwZSA9PT0gJ3NvdW4nKSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudHJhY2sgPSB0cmFjaztcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy50cmFjay50eXBlICE9PSAnc291bicpIHtcbiAgICAgICAgdGhpcy50cmFjayA9IG51bGw7XG4gICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ2Vycm9yJywgJ05vIGF1ZGlvIHRyYWNrcyBpbiBtNGEgZmlsZS4nKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZW1pdCgnZm9ybWF0JywgdGhpcy50cmFjay5mb3JtYXQpO1xuICAgICAgdGhpcy5lbWl0KCdkdXJhdGlvbicsIHRoaXMudHJhY2suZHVyYXRpb24gLyB0aGlzLnRyYWNrLnRpbWVTY2FsZSAqIDEwMDAgfCAwKTtcbiAgICAgIGlmICh0aGlzLnRyYWNrLmNvb2tpZSkge1xuICAgICAgICB0aGlzLmVtaXQoJ2Nvb2tpZScsIHRoaXMudHJhY2suY29va2llKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLnNlZWtQb2ludHMgPSB0aGlzLnRyYWNrLnNlZWtQb2ludHM7XG4gICAgfSk7XG5cbiAgICBhdG9tKCdtZGF0JywgZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYnl0ZXMsIGNodW5rU2l6ZSwgbGVuZ3RoLCBudW1TYW1wbGVzLCBvZmZzZXQsIHNhbXBsZSwgc2l6ZSwgX2k7XG4gICAgICBpZiAoIXRoaXMuc3RhcnRlZERhdGEpIHtcbiAgICAgICAgaWYgKHRoaXMubWRhdE9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgICAgdGhpcy5tZGF0T2Zmc2V0ID0gdGhpcy5zdHJlYW0ub2Zmc2V0O1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnRyYWNrcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICBieXRlcyA9IE1hdGgubWluKHRoaXMuc3RyZWFtLnJlbWFpbmluZ0J5dGVzKCksIHRoaXMubGVuKTtcbiAgICAgICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKGJ5dGVzKTtcbiAgICAgICAgICB0aGlzLmxlbiAtPSBieXRlcztcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jaHVua0luZGV4ID0gMDtcbiAgICAgICAgdGhpcy5zdHNjSW5kZXggPSAwO1xuICAgICAgICB0aGlzLnNhbXBsZUluZGV4ID0gMDtcbiAgICAgICAgdGhpcy50YWlsT2Zmc2V0ID0gMDtcbiAgICAgICAgdGhpcy50YWlsU2FtcGxlcyA9IDA7XG4gICAgICAgIHRoaXMuc3RhcnRlZERhdGEgPSB0cnVlO1xuICAgICAgfVxuICAgICAgaWYgKCF0aGlzLnJlYWRDaGFwdGVycykge1xuICAgICAgICB0aGlzLnJlYWRDaGFwdGVycyA9IHRoaXMucGFyc2VDaGFwdGVycygpO1xuICAgICAgICBpZiAodGhpc1tcImJyZWFrXCJdID0gIXRoaXMucmVhZENoYXB0ZXJzKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3RyZWFtLnNlZWsodGhpcy5tZGF0T2Zmc2V0KTtcbiAgICAgIH1cbiAgICAgIG9mZnNldCA9IHRoaXMudHJhY2suY2h1bmtPZmZzZXRzW3RoaXMuY2h1bmtJbmRleF0gKyB0aGlzLnRhaWxPZmZzZXQ7XG4gICAgICBsZW5ndGggPSAwO1xuICAgICAgaWYgKCF0aGlzLnN0cmVhbS5hdmFpbGFibGUob2Zmc2V0IC0gdGhpcy5zdHJlYW0ub2Zmc2V0KSkge1xuICAgICAgICB0aGlzW1wiYnJlYWtcIl0gPSB0cnVlO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLnN0cmVhbS5zZWVrKG9mZnNldCk7XG4gICAgICB3aGlsZSAodGhpcy5jaHVua0luZGV4IDwgdGhpcy50cmFjay5jaHVua09mZnNldHMubGVuZ3RoKSB7XG4gICAgICAgIG51bVNhbXBsZXMgPSB0aGlzLnRyYWNrLnN0c2NbdGhpcy5zdHNjSW5kZXhdLmNvdW50IC0gdGhpcy50YWlsU2FtcGxlcztcbiAgICAgICAgY2h1bmtTaXplID0gMDtcbiAgICAgICAgZm9yIChzYW1wbGUgPSBfaSA9IDA7IF9pIDwgbnVtU2FtcGxlczsgc2FtcGxlID0gX2kgKz0gMSkge1xuICAgICAgICAgIHNpemUgPSB0aGlzLnRyYWNrLnNhbXBsZVNpemUgfHwgdGhpcy50cmFjay5zYW1wbGVTaXplc1t0aGlzLnNhbXBsZUluZGV4XTtcbiAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmF2YWlsYWJsZShsZW5ndGggKyBzaXplKSkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGxlbmd0aCArPSBzaXplO1xuICAgICAgICAgIGNodW5rU2l6ZSArPSBzaXplO1xuICAgICAgICAgIHRoaXMuc2FtcGxlSW5kZXgrKztcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2FtcGxlIDwgbnVtU2FtcGxlcykge1xuICAgICAgICAgIHRoaXMudGFpbE9mZnNldCArPSBjaHVua1NpemU7XG4gICAgICAgICAgdGhpcy50YWlsU2FtcGxlcyArPSBzYW1wbGU7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5jaHVua0luZGV4Kys7XG4gICAgICAgICAgdGhpcy50YWlsT2Zmc2V0ID0gMDtcbiAgICAgICAgICB0aGlzLnRhaWxTYW1wbGVzID0gMDtcbiAgICAgICAgICBpZiAodGhpcy5zdHNjSW5kZXggKyAxIDwgdGhpcy50cmFjay5zdHNjLmxlbmd0aCAmJiB0aGlzLmNodW5rSW5kZXggKyAxID09PSB0aGlzLnRyYWNrLnN0c2NbdGhpcy5zdHNjSW5kZXggKyAxXS5maXJzdCkge1xuICAgICAgICAgICAgdGhpcy5zdHNjSW5kZXgrKztcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKG9mZnNldCArIGxlbmd0aCAhPT0gdGhpcy50cmFjay5jaHVua09mZnNldHNbdGhpcy5jaHVua0luZGV4XSkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLmVtaXQoJ2RhdGEnLCB0aGlzLnN0cmVhbS5yZWFkQnVmZmVyKGxlbmd0aCkpO1xuICAgICAgICByZXR1cm4gdGhpc1tcImJyZWFrXCJdID0gdGhpcy5jaHVua0luZGV4ID09PSB0aGlzLnRyYWNrLmNodW5rT2Zmc2V0cy5sZW5ndGg7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdGhpc1tcImJyZWFrXCJdID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIE00QURlbXV4ZXIucHJvdG90eXBlLnBhcnNlQ2hhcHRlcnMgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBib20sIGlkLCBsZW4sIG5leHRUaW1lc3RhbXAsIHBvaW50LCB0aXRsZSwgdHJhY2ssIF9pLCBfbGVuLCBfcmVmLCBfcmVmMSwgX3JlZjIsIF9yZWYzO1xuICAgICAgaWYgKCEoKChfcmVmID0gdGhpcy50cmFjay5jaGFwdGVyVHJhY2tzKSAhPSBudWxsID8gX3JlZi5sZW5ndGggOiB2b2lkIDApID4gMCkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBpZCA9IHRoaXMudHJhY2suY2hhcHRlclRyYWNrc1swXTtcbiAgICAgIF9yZWYxID0gdGhpcy50cmFja3M7XG4gICAgICBmb3IgKF9pID0gMCwgX2xlbiA9IF9yZWYxLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgIHRyYWNrID0gX3JlZjFbX2ldO1xuICAgICAgICBpZiAodHJhY2suaWQgPT09IGlkKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICh0cmFjay5pZCAhPT0gaWQpIHtcbiAgICAgICAgdGhpcy5lbWl0KCdlcnJvcicsICdDaGFwdGVyIHRyYWNrIGRvZXMgbm90IGV4aXN0LicpO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuY2hhcHRlcnMgPT0gbnVsbCkge1xuICAgICAgICB0aGlzLmNoYXB0ZXJzID0gW107XG4gICAgICB9XG4gICAgICB3aGlsZSAodGhpcy5jaGFwdGVycy5sZW5ndGggPCB0cmFjay5zZWVrUG9pbnRzLmxlbmd0aCkge1xuICAgICAgICBwb2ludCA9IHRyYWNrLnNlZWtQb2ludHNbdGhpcy5jaGFwdGVycy5sZW5ndGhdO1xuICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmF2YWlsYWJsZShwb2ludC5wb3NpdGlvbiAtIHRoaXMuc3RyZWFtLm9mZnNldCArIDMyKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnN0cmVhbS5zZWVrKHBvaW50LnBvc2l0aW9uKTtcbiAgICAgICAgbGVuID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQxNigpO1xuICAgICAgICB0aXRsZSA9IG51bGw7XG4gICAgICAgIGlmICghdGhpcy5zdHJlYW0uYXZhaWxhYmxlKGxlbikpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGxlbiA+IDIpIHtcbiAgICAgICAgICBib20gPSB0aGlzLnN0cmVhbS5wZWVrVUludDE2KCk7XG4gICAgICAgICAgaWYgKGJvbSA9PT0gMHhmZWZmIHx8IGJvbSA9PT0gMHhmZmZlKSB7XG4gICAgICAgICAgICB0aXRsZSA9IHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcobGVuLCAndXRmMTYtYm9tJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aXRsZSA9PSBudWxsKSB7XG4gICAgICAgICAgdGl0bGUgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKGxlbiwgJ3V0ZjgnKTtcbiAgICAgICAgfVxuICAgICAgICBuZXh0VGltZXN0YW1wID0gKF9yZWYyID0gKF9yZWYzID0gdHJhY2suc2Vla1BvaW50c1t0aGlzLmNoYXB0ZXJzLmxlbmd0aCArIDFdKSAhPSBudWxsID8gX3JlZjMudGltZXN0YW1wIDogdm9pZCAwKSAhPSBudWxsID8gX3JlZjIgOiB0cmFjay5kdXJhdGlvbjtcbiAgICAgICAgdGhpcy5jaGFwdGVycy5wdXNoKHtcbiAgICAgICAgICB0aXRsZTogdGl0bGUsXG4gICAgICAgICAgdGltZXN0YW1wOiBwb2ludC50aW1lc3RhbXAgLyB0cmFjay50aW1lU2NhbGUgKiAxMDAwIHwgMCxcbiAgICAgICAgICBkdXJhdGlvbjogKG5leHRUaW1lc3RhbXAgLSBwb2ludC50aW1lc3RhbXApIC8gdHJhY2sudGltZVNjYWxlICogMTAwMCB8IDBcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICB0aGlzLmVtaXQoJ2NoYXB0ZXJzJywgdGhpcy5jaGFwdGVycyk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuXG4gICAgYXRvbSgnbW9vdi51ZHRhLm1ldGEnLCBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMubWV0YWRhdGEgPSB7fTtcbiAgICAgIHJldHVybiB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXIoJ21vb3YudWR0YS5tZXRhJywgZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbWl0KCdtZXRhZGF0YScsIHRoaXMubWV0YWRhdGEpO1xuICAgIH0pO1xuXG4gICAgbWV0YSA9IGZ1bmN0aW9uKGZpZWxkLCBuYW1lLCBmbikge1xuICAgICAgcmV0dXJuIGF0b20oXCJtb292LnVkdGEubWV0YS5pbHN0LlwiICsgZmllbGQgKyBcIi5kYXRhXCIsIGZ1bmN0aW9uKCkge1xuICAgICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDgpO1xuICAgICAgICB0aGlzLmxlbiAtPSA4O1xuICAgICAgICByZXR1cm4gZm4uY2FsbCh0aGlzLCBuYW1lKTtcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBzdHJpbmcgPSBmdW5jdGlvbihmaWVsZCkge1xuICAgICAgcmV0dXJuIHRoaXMubWV0YWRhdGFbZmllbGRdID0gdGhpcy5zdHJlYW0ucmVhZFN0cmluZyh0aGlzLmxlbiwgJ3V0ZjgnKTtcbiAgICB9O1xuXG4gICAgbWV0YSgnwqlhbGInLCAnYWxidW0nLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqlhcmcnLCAnYXJyYW5nZXInLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqlhcnQnLCAnYXJ0aXN0Jywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpQVJUJywgJ2FydGlzdCcsIHN0cmluZyk7XG5cbiAgICBtZXRhKCdhQVJUJywgJ2FsYnVtQXJ0aXN0Jywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ2NhdGcnLCAnY2F0ZWdvcnknLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqljb20nLCAnY29tcG9zZXInLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqljcHknLCAnY29weXJpZ2h0Jywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ2NwcnQnLCAnY29weXJpZ2h0Jywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpY210JywgJ2NvbW1lbnRzJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpZGF5JywgJ3JlbGVhc2VEYXRlJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ2Rlc2MnLCAnZGVzY3JpcHRpb24nLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqlnZW4nLCAnZ2VucmUnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqlncnAnLCAnZ3JvdXBpbmcnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqlpc3InLCAnSVNSQycsIHN0cmluZyk7XG5cbiAgICBtZXRhKCdrZXl3JywgJ2tleXdvcmRzJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpbGFiJywgJ3JlY29yZExhYmVsJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ2xkZXMnLCAnbG9uZ0Rlc2NyaXB0aW9uJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpbHlyJywgJ2x5cmljcycsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqW5hbScsICd0aXRsZScsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqXBoZycsICdyZWNvcmRpbmdDb3B5cmlnaHQnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqlwcmQnLCAncHJvZHVjZXInLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqlwcmYnLCAncGVyZm9ybWVycycsIHN0cmluZyk7XG5cbiAgICBtZXRhKCdwdXJkJywgJ3B1cmNoYXNlRGF0ZScsIHN0cmluZyk7XG5cbiAgICBtZXRhKCdwdXJsJywgJ3BvZGNhc3RVUkwnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqlzd2YnLCAnc29uZ3dyaXRlcicsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqXRvbycsICdlbmNvZGVyJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8Kpd3J0JywgJ2NvbXBvc2VyJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ2NvdnInLCAnY292ZXJBcnQnLCBmdW5jdGlvbihmaWVsZCkge1xuICAgICAgcmV0dXJuIHRoaXMubWV0YWRhdGFbZmllbGRdID0gdGhpcy5zdHJlYW0ucmVhZEJ1ZmZlcih0aGlzLmxlbik7XG4gICAgfSk7XG5cbiAgICBnZW5yZXMgPSBbXCJCbHVlc1wiLCBcIkNsYXNzaWMgUm9ja1wiLCBcIkNvdW50cnlcIiwgXCJEYW5jZVwiLCBcIkRpc2NvXCIsIFwiRnVua1wiLCBcIkdydW5nZVwiLCBcIkhpcC1Ib3BcIiwgXCJKYXp6XCIsIFwiTWV0YWxcIiwgXCJOZXcgQWdlXCIsIFwiT2xkaWVzXCIsIFwiT3RoZXJcIiwgXCJQb3BcIiwgXCJSJkJcIiwgXCJSYXBcIiwgXCJSZWdnYWVcIiwgXCJSb2NrXCIsIFwiVGVjaG5vXCIsIFwiSW5kdXN0cmlhbFwiLCBcIkFsdGVybmF0aXZlXCIsIFwiU2thXCIsIFwiRGVhdGggTWV0YWxcIiwgXCJQcmFua3NcIiwgXCJTb3VuZHRyYWNrXCIsIFwiRXVyby1UZWNobm9cIiwgXCJBbWJpZW50XCIsIFwiVHJpcC1Ib3BcIiwgXCJWb2NhbFwiLCBcIkphenorRnVua1wiLCBcIkZ1c2lvblwiLCBcIlRyYW5jZVwiLCBcIkNsYXNzaWNhbFwiLCBcIkluc3RydW1lbnRhbFwiLCBcIkFjaWRcIiwgXCJIb3VzZVwiLCBcIkdhbWVcIiwgXCJTb3VuZCBDbGlwXCIsIFwiR29zcGVsXCIsIFwiTm9pc2VcIiwgXCJBbHRlcm5Sb2NrXCIsIFwiQmFzc1wiLCBcIlNvdWxcIiwgXCJQdW5rXCIsIFwiU3BhY2VcIiwgXCJNZWRpdGF0aXZlXCIsIFwiSW5zdHJ1bWVudGFsIFBvcFwiLCBcIkluc3RydW1lbnRhbCBSb2NrXCIsIFwiRXRobmljXCIsIFwiR290aGljXCIsIFwiRGFya3dhdmVcIiwgXCJUZWNobm8tSW5kdXN0cmlhbFwiLCBcIkVsZWN0cm9uaWNcIiwgXCJQb3AtRm9sa1wiLCBcIkV1cm9kYW5jZVwiLCBcIkRyZWFtXCIsIFwiU291dGhlcm4gUm9ja1wiLCBcIkNvbWVkeVwiLCBcIkN1bHRcIiwgXCJHYW5nc3RhXCIsIFwiVG9wIDQwXCIsIFwiQ2hyaXN0aWFuIFJhcFwiLCBcIlBvcC9GdW5rXCIsIFwiSnVuZ2xlXCIsIFwiTmF0aXZlIEFtZXJpY2FuXCIsIFwiQ2FiYXJldFwiLCBcIk5ldyBXYXZlXCIsIFwiUHN5Y2hhZGVsaWNcIiwgXCJSYXZlXCIsIFwiU2hvd3R1bmVzXCIsIFwiVHJhaWxlclwiLCBcIkxvLUZpXCIsIFwiVHJpYmFsXCIsIFwiQWNpZCBQdW5rXCIsIFwiQWNpZCBKYXp6XCIsIFwiUG9sa2FcIiwgXCJSZXRyb1wiLCBcIk11c2ljYWxcIiwgXCJSb2NrICYgUm9sbFwiLCBcIkhhcmQgUm9ja1wiLCBcIkZvbGtcIiwgXCJGb2xrL1JvY2tcIiwgXCJOYXRpb25hbCBGb2xrXCIsIFwiU3dpbmdcIiwgXCJGYXN0IEZ1c2lvblwiLCBcIkJlYm9iXCIsIFwiTGF0aW5cIiwgXCJSZXZpdmFsXCIsIFwiQ2VsdGljXCIsIFwiQmx1ZWdyYXNzXCIsIFwiQXZhbnRnYXJkZVwiLCBcIkdvdGhpYyBSb2NrXCIsIFwiUHJvZ3Jlc3NpdmUgUm9ja1wiLCBcIlBzeWNoZWRlbGljIFJvY2tcIiwgXCJTeW1waG9uaWMgUm9ja1wiLCBcIlNsb3cgUm9ja1wiLCBcIkJpZyBCYW5kXCIsIFwiQ2hvcnVzXCIsIFwiRWFzeSBMaXN0ZW5pbmdcIiwgXCJBY291c3RpY1wiLCBcIkh1bW91clwiLCBcIlNwZWVjaFwiLCBcIkNoYW5zb25cIiwgXCJPcGVyYVwiLCBcIkNoYW1iZXIgTXVzaWNcIiwgXCJTb25hdGFcIiwgXCJTeW1waG9ueVwiLCBcIkJvb3R5IEJhc3NcIiwgXCJQcmltdXNcIiwgXCJQb3JuIEdyb292ZVwiLCBcIlNhdGlyZVwiLCBcIlNsb3cgSmFtXCIsIFwiQ2x1YlwiLCBcIlRhbmdvXCIsIFwiU2FtYmFcIiwgXCJGb2xrbG9yZVwiLCBcIkJhbGxhZFwiLCBcIlBvd2VyIEJhbGxhZFwiLCBcIlJoeXRobWljIFNvdWxcIiwgXCJGcmVlc3R5bGVcIiwgXCJEdWV0XCIsIFwiUHVuayBSb2NrXCIsIFwiRHJ1bSBTb2xvXCIsIFwiQSBDYXBlbGxhXCIsIFwiRXVyby1Ib3VzZVwiLCBcIkRhbmNlIEhhbGxcIl07XG5cbiAgICBtZXRhKCdnbnJlJywgJ2dlbnJlJywgZnVuY3Rpb24oZmllbGQpIHtcbiAgICAgIHJldHVybiB0aGlzLm1ldGFkYXRhW2ZpZWxkXSA9IGdlbnJlc1t0aGlzLnN0cmVhbS5yZWFkVUludDE2KCkgLSAxXTtcbiAgICB9KTtcblxuICAgIG1ldGEoJ3RtcG8nLCAndGVtcG8nLCBmdW5jdGlvbihmaWVsZCkge1xuICAgICAgcmV0dXJuIHRoaXMubWV0YWRhdGFbZmllbGRdID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQxNigpO1xuICAgIH0pO1xuXG4gICAgbWV0YSgncnRuZycsICdyYXRpbmcnLCBmdW5jdGlvbihmaWVsZCkge1xuICAgICAgdmFyIHJhdGluZztcbiAgICAgIHJhdGluZyA9IHRoaXMuc3RyZWFtLnJlYWRVSW50OCgpO1xuICAgICAgcmV0dXJuIHRoaXMubWV0YWRhdGFbZmllbGRdID0gcmF0aW5nID09PSAyID8gJ0NsZWFuJyA6IHJhdGluZyAhPT0gMCA/ICdFeHBsaWNpdCcgOiAnTm9uZSc7XG4gICAgfSk7XG5cbiAgICBkaXNrVHJhY2sgPSBmdW5jdGlvbihmaWVsZCkge1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSgyKTtcbiAgICAgIHRoaXMubWV0YWRhdGFbZmllbGRdID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQxNigpICsgJyBvZiAnICsgdGhpcy5zdHJlYW0ucmVhZFVJbnQxNigpO1xuICAgICAgcmV0dXJuIHRoaXMuc3RyZWFtLmFkdmFuY2UodGhpcy5sZW4gLSA2KTtcbiAgICB9O1xuXG4gICAgbWV0YSgnZGlzaycsICdkaXNrTnVtYmVyJywgZGlza1RyYWNrKTtcblxuICAgIG1ldGEoJ3Rya24nLCAndHJhY2tOdW1iZXInLCBkaXNrVHJhY2spO1xuXG4gICAgYm9vbCA9IGZ1bmN0aW9uKGZpZWxkKSB7XG4gICAgICByZXR1cm4gdGhpcy5tZXRhZGF0YVtmaWVsZF0gPSB0aGlzLnN0cmVhbS5yZWFkVUludDgoKSA9PT0gMTtcbiAgICB9O1xuXG4gICAgbWV0YSgnY3BpbCcsICdjb21waWxhdGlvbicsIGJvb2wpO1xuXG4gICAgbWV0YSgncGNzdCcsICdwb2RjYXN0JywgYm9vbCk7XG5cbiAgICBtZXRhKCdwZ2FwJywgJ2dhcGxlc3MnLCBib29sKTtcblxuICAgIHJldHVybiBNNEFEZW11eGVyO1xuXG4gIH0pKERlbXV4ZXIpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gTTRBRGVtdXhlcjtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS43LjFcbihmdW5jdGlvbigpIHtcbiAgdmFyIERlbXV4ZXIsIFdBVkVEZW11eGVyLFxuICAgIF9faGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5LFxuICAgIF9fZXh0ZW5kcyA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoX19oYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9O1xuXG4gIERlbXV4ZXIgPSByZXF1aXJlKCcuLi9kZW11eGVyJyk7XG5cbiAgV0FWRURlbXV4ZXIgPSAoZnVuY3Rpb24oX3N1cGVyKSB7XG4gICAgdmFyIGZvcm1hdHM7XG5cbiAgICBfX2V4dGVuZHMoV0FWRURlbXV4ZXIsIF9zdXBlcik7XG5cbiAgICBmdW5jdGlvbiBXQVZFRGVtdXhlcigpIHtcbiAgICAgIHJldHVybiBXQVZFRGVtdXhlci5fX3N1cGVyX18uY29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICBEZW11eGVyLnJlZ2lzdGVyKFdBVkVEZW11eGVyKTtcblxuICAgIFdBVkVEZW11eGVyLnByb2JlID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICByZXR1cm4gYnVmZmVyLnBlZWtTdHJpbmcoMCwgNCkgPT09ICdSSUZGJyAmJiBidWZmZXIucGVla1N0cmluZyg4LCA0KSA9PT0gJ1dBVkUnO1xuICAgIH07XG5cbiAgICBmb3JtYXRzID0ge1xuICAgICAgMHgwMDAxOiAnbHBjbScsXG4gICAgICAweDAwMDM6ICdscGNtJyxcbiAgICAgIDB4MDAwNjogJ2FsYXcnLFxuICAgICAgMHgwMDA3OiAndWxhdydcbiAgICB9O1xuXG4gICAgV0FWRURlbXV4ZXIucHJvdG90eXBlLnJlYWRDaHVuayA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGJ1ZmZlciwgYnl0ZXMsIGVuY29kaW5nO1xuICAgICAgaWYgKCF0aGlzLnJlYWRTdGFydCAmJiB0aGlzLnN0cmVhbS5hdmFpbGFibGUoMTIpKSB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpICE9PSAnUklGRicpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsICdJbnZhbGlkIFdBViBmaWxlLicpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZmlsZVNpemUgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKHRydWUpO1xuICAgICAgICB0aGlzLnJlYWRTdGFydCA9IHRydWU7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpICE9PSAnV0FWRScpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsICdJbnZhbGlkIFdBViBmaWxlLicpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB3aGlsZSAodGhpcy5zdHJlYW0uYXZhaWxhYmxlKDEpKSB7XG4gICAgICAgIGlmICghdGhpcy5yZWFkSGVhZGVycyAmJiB0aGlzLnN0cmVhbS5hdmFpbGFibGUoOCkpIHtcbiAgICAgICAgICB0aGlzLnR5cGUgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpO1xuICAgICAgICAgIHRoaXMubGVuID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMih0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICBzd2l0Y2ggKHRoaXMudHlwZSkge1xuICAgICAgICAgIGNhc2UgJ2ZtdCAnOlxuICAgICAgICAgICAgZW5jb2RpbmcgPSB0aGlzLnN0cmVhbS5yZWFkVUludDE2KHRydWUpO1xuICAgICAgICAgICAgaWYgKCEoZW5jb2RpbmcgaW4gZm9ybWF0cykpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnVW5zdXBwb3J0ZWQgZm9ybWF0IGluIFdBViBmaWxlLicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5mb3JtYXQgPSB7XG4gICAgICAgICAgICAgIGZvcm1hdElEOiBmb3JtYXRzW2VuY29kaW5nXSxcbiAgICAgICAgICAgICAgZmxvYXRpbmdQb2ludDogZW5jb2RpbmcgPT09IDB4MDAwMyxcbiAgICAgICAgICAgICAgbGl0dGxlRW5kaWFuOiBmb3JtYXRzW2VuY29kaW5nXSA9PT0gJ2xwY20nLFxuICAgICAgICAgICAgICBjaGFubmVsc1BlckZyYW1lOiB0aGlzLnN0cmVhbS5yZWFkVUludDE2KHRydWUpLFxuICAgICAgICAgICAgICBzYW1wbGVSYXRlOiB0aGlzLnN0cmVhbS5yZWFkVUludDMyKHRydWUpLFxuICAgICAgICAgICAgICBmcmFtZXNQZXJQYWNrZXQ6IDFcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSgyKTtcbiAgICAgICAgICAgIHRoaXMuZm9ybWF0LmJpdHNQZXJDaGFubmVsID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQxNih0cnVlKTtcbiAgICAgICAgICAgIHRoaXMuZm9ybWF0LmJ5dGVzUGVyUGFja2V0ID0gKHRoaXMuZm9ybWF0LmJpdHNQZXJDaGFubmVsIC8gOCkgKiB0aGlzLmZvcm1hdC5jaGFubmVsc1BlckZyYW1lO1xuICAgICAgICAgICAgdGhpcy5lbWl0KCdmb3JtYXQnLCB0aGlzLmZvcm1hdCk7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKHRoaXMubGVuIC0gMTYpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnZGF0YSc6XG4gICAgICAgICAgICBpZiAoIXRoaXMuc2VudER1cmF0aW9uKSB7XG4gICAgICAgICAgICAgIGJ5dGVzID0gdGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwgLyA4O1xuICAgICAgICAgICAgICB0aGlzLmVtaXQoJ2R1cmF0aW9uJywgdGhpcy5sZW4gLyBieXRlcyAvIHRoaXMuZm9ybWF0LmNoYW5uZWxzUGVyRnJhbWUgLyB0aGlzLmZvcm1hdC5zYW1wbGVSYXRlICogMTAwMCB8IDApO1xuICAgICAgICAgICAgICB0aGlzLnNlbnREdXJhdGlvbiA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBidWZmZXIgPSB0aGlzLnN0cmVhbS5yZWFkU2luZ2xlQnVmZmVyKHRoaXMubGVuKTtcbiAgICAgICAgICAgIHRoaXMubGVuIC09IGJ1ZmZlci5sZW5ndGg7XG4gICAgICAgICAgICB0aGlzLnJlYWRIZWFkZXJzID0gdGhpcy5sZW4gPiAwO1xuICAgICAgICAgICAgdGhpcy5lbWl0KCdkYXRhJywgYnVmZmVyKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmF2YWlsYWJsZSh0aGlzLmxlbikpIHtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSh0aGlzLmxlbik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMudHlwZSAhPT0gJ2RhdGEnKSB7XG4gICAgICAgICAgdGhpcy5yZWFkSGVhZGVycyA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBXQVZFRGVtdXhlcjtcblxuICB9KShEZW11eGVyKTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS43LjFcbihmdW5jdGlvbigpIHtcbiAgdmFyIEF1ZGlvRGV2aWNlLCBFdmVudEVtaXR0ZXIsXG4gICAgX19iaW5kID0gZnVuY3Rpb24oZm4sIG1lKXsgcmV0dXJuIGZ1bmN0aW9uKCl7IHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTsgfTsgfSxcbiAgICBfX2hhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgICBfX2V4dGVuZHMgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKF9faGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfTtcblxuICBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuL2NvcmUvZXZlbnRzJyk7XG5cbiAgQXVkaW9EZXZpY2UgPSAoZnVuY3Rpb24oX3N1cGVyKSB7XG4gICAgdmFyIGRldmljZXM7XG5cbiAgICBfX2V4dGVuZHMoQXVkaW9EZXZpY2UsIF9zdXBlcik7XG5cbiAgICBmdW5jdGlvbiBBdWRpb0RldmljZShzYW1wbGVSYXRlLCBjaGFubmVscykge1xuICAgICAgdGhpcy5zYW1wbGVSYXRlID0gc2FtcGxlUmF0ZTtcbiAgICAgIHRoaXMuY2hhbm5lbHMgPSBjaGFubmVscztcbiAgICAgIHRoaXMudXBkYXRlVGltZSA9IF9fYmluZCh0aGlzLnVwZGF0ZVRpbWUsIHRoaXMpO1xuICAgICAgdGhpcy5wbGF5aW5nID0gZmFsc2U7XG4gICAgICB0aGlzLmN1cnJlbnRUaW1lID0gMDtcbiAgICAgIHRoaXMuX2xhc3RUaW1lID0gMDtcbiAgICB9XG5cbiAgICBBdWRpb0RldmljZS5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0aGlzLnBsYXlpbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5wbGF5aW5nID0gdHJ1ZTtcbiAgICAgIGlmICh0aGlzLmRldmljZSA9PSBudWxsKSB7XG4gICAgICAgIHRoaXMuZGV2aWNlID0gQXVkaW9EZXZpY2UuY3JlYXRlKHRoaXMuc2FtcGxlUmF0ZSwgdGhpcy5jaGFubmVscyk7XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMuZGV2aWNlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIHN1cHBvcnRlZCBhdWRpbyBkZXZpY2UgZm91bmQuXCIpO1xuICAgICAgfVxuICAgICAgdGhpcy5fbGFzdFRpbWUgPSB0aGlzLmRldmljZS5nZXREZXZpY2VUaW1lKCk7XG4gICAgICB0aGlzLl90aW1lciA9IHNldEludGVydmFsKHRoaXMudXBkYXRlVGltZSwgMjAwKTtcbiAgICAgIHJldHVybiB0aGlzLmRldmljZS5vbigncmVmaWxsJywgdGhpcy5yZWZpbGwgPSAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdyZWZpbGwnLCBidWZmZXIpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgIH07XG5cbiAgICBBdWRpb0RldmljZS5wcm90b3R5cGUuc3RvcCA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKCF0aGlzLnBsYXlpbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5wbGF5aW5nID0gZmFsc2U7XG4gICAgICB0aGlzLmRldmljZS5vZmYoJ3JlZmlsbCcsIHRoaXMucmVmaWxsKTtcbiAgICAgIHJldHVybiBjbGVhckludGVydmFsKHRoaXMuX3RpbWVyKTtcbiAgICB9O1xuXG4gICAgQXVkaW9EZXZpY2UucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBfcmVmO1xuICAgICAgdGhpcy5zdG9wKCk7XG4gICAgICByZXR1cm4gKF9yZWYgPSB0aGlzLmRldmljZSkgIT0gbnVsbCA/IF9yZWYuZGVzdHJveSgpIDogdm9pZCAwO1xuICAgIH07XG5cbiAgICBBdWRpb0RldmljZS5wcm90b3R5cGUuc2VlayA9IGZ1bmN0aW9uKGN1cnJlbnRUaW1lKSB7XG4gICAgICB0aGlzLmN1cnJlbnRUaW1lID0gY3VycmVudFRpbWU7XG4gICAgICBpZiAodGhpcy5wbGF5aW5nKSB7XG4gICAgICAgIHRoaXMuX2xhc3RUaW1lID0gdGhpcy5kZXZpY2UuZ2V0RGV2aWNlVGltZSgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuZW1pdCgndGltZVVwZGF0ZScsIHRoaXMuY3VycmVudFRpbWUpO1xuICAgIH07XG5cbiAgICBBdWRpb0RldmljZS5wcm90b3R5cGUudXBkYXRlVGltZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHRpbWU7XG4gICAgICB0aW1lID0gdGhpcy5kZXZpY2UuZ2V0RGV2aWNlVGltZSgpO1xuICAgICAgdGhpcy5jdXJyZW50VGltZSArPSAodGltZSAtIHRoaXMuX2xhc3RUaW1lKSAvIHRoaXMuZGV2aWNlLnNhbXBsZVJhdGUgKiAxMDAwIHwgMDtcbiAgICAgIHRoaXMuX2xhc3RUaW1lID0gdGltZTtcbiAgICAgIHJldHVybiB0aGlzLmVtaXQoJ3RpbWVVcGRhdGUnLCB0aGlzLmN1cnJlbnRUaW1lKTtcbiAgICB9O1xuXG4gICAgZGV2aWNlcyA9IFtdO1xuXG4gICAgQXVkaW9EZXZpY2UucmVnaXN0ZXIgPSBmdW5jdGlvbihkZXZpY2UpIHtcbiAgICAgIHJldHVybiBkZXZpY2VzLnB1c2goZGV2aWNlKTtcbiAgICB9O1xuXG4gICAgQXVkaW9EZXZpY2UuY3JlYXRlID0gZnVuY3Rpb24oc2FtcGxlUmF0ZSwgY2hhbm5lbHMpIHtcbiAgICAgIHZhciBkZXZpY2UsIF9pLCBfbGVuO1xuICAgICAgZm9yIChfaSA9IDAsIF9sZW4gPSBkZXZpY2VzLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgIGRldmljZSA9IGRldmljZXNbX2ldO1xuICAgICAgICBpZiAoZGV2aWNlLnN1cHBvcnRlZCkge1xuICAgICAgICAgIHJldHVybiBuZXcgZGV2aWNlKHNhbXBsZVJhdGUsIGNoYW5uZWxzKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcblxuICAgIHJldHVybiBBdWRpb0RldmljZTtcblxuICB9KShFdmVudEVtaXR0ZXIpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gQXVkaW9EZXZpY2U7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuNy4xXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBBVkJ1ZmZlciwgQXVkaW9EZXZpY2UsIEV2ZW50RW1pdHRlciwgTW96aWxsYUF1ZGlvRGV2aWNlLFxuICAgIF9fYmluZCA9IGZ1bmN0aW9uKGZuLCBtZSl7IHJldHVybiBmdW5jdGlvbigpeyByZXR1cm4gZm4uYXBwbHkobWUsIGFyZ3VtZW50cyk7IH07IH0sXG4gICAgX19oYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHksXG4gICAgX19leHRlbmRzID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChfX2hhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH07XG5cbiAgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnLi4vY29yZS9ldmVudHMnKTtcblxuICBBdWRpb0RldmljZSA9IHJlcXVpcmUoJy4uL2RldmljZScpO1xuXG4gIEFWQnVmZmVyID0gcmVxdWlyZSgnLi4vY29yZS9idWZmZXInKTtcblxuICBNb3ppbGxhQXVkaW9EZXZpY2UgPSAoZnVuY3Rpb24oX3N1cGVyKSB7XG4gICAgdmFyIGNyZWF0ZVRpbWVyLCBkZXN0cm95VGltZXI7XG5cbiAgICBfX2V4dGVuZHMoTW96aWxsYUF1ZGlvRGV2aWNlLCBfc3VwZXIpO1xuXG4gICAgQXVkaW9EZXZpY2UucmVnaXN0ZXIoTW96aWxsYUF1ZGlvRGV2aWNlKTtcblxuICAgIE1vemlsbGFBdWRpb0RldmljZS5zdXBwb3J0ZWQgPSAodHlwZW9mIEF1ZGlvICE9PSBcInVuZGVmaW5lZFwiICYmIEF1ZGlvICE9PSBudWxsKSAmJiAnbW96V3JpdGVBdWRpbycgaW4gbmV3IEF1ZGlvO1xuXG4gICAgZnVuY3Rpb24gTW96aWxsYUF1ZGlvRGV2aWNlKHNhbXBsZVJhdGUsIGNoYW5uZWxzKSB7XG4gICAgICB0aGlzLnNhbXBsZVJhdGUgPSBzYW1wbGVSYXRlO1xuICAgICAgdGhpcy5jaGFubmVscyA9IGNoYW5uZWxzO1xuICAgICAgdGhpcy5yZWZpbGwgPSBfX2JpbmQodGhpcy5yZWZpbGwsIHRoaXMpO1xuICAgICAgdGhpcy5hdWRpbyA9IG5ldyBBdWRpbztcbiAgICAgIHRoaXMuYXVkaW8ubW96U2V0dXAodGhpcy5jaGFubmVscywgdGhpcy5zYW1wbGVSYXRlKTtcbiAgICAgIHRoaXMud3JpdGVQb3NpdGlvbiA9IDA7XG4gICAgICB0aGlzLnByZWJ1ZmZlclNpemUgPSB0aGlzLnNhbXBsZVJhdGUgLyAyO1xuICAgICAgdGhpcy50YWlsID0gbnVsbDtcbiAgICAgIHRoaXMudGltZXIgPSBjcmVhdGVUaW1lcih0aGlzLnJlZmlsbCwgMTAwKTtcbiAgICB9XG5cbiAgICBNb3ppbGxhQXVkaW9EZXZpY2UucHJvdG90eXBlLnJlZmlsbCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGF2YWlsYWJsZSwgYnVmZmVyLCBjdXJyZW50UG9zaXRpb24sIHdyaXR0ZW47XG4gICAgICBpZiAodGhpcy50YWlsKSB7XG4gICAgICAgIHdyaXR0ZW4gPSB0aGlzLmF1ZGlvLm1veldyaXRlQXVkaW8odGhpcy50YWlsKTtcbiAgICAgICAgdGhpcy53cml0ZVBvc2l0aW9uICs9IHdyaXR0ZW47XG4gICAgICAgIGlmICh0aGlzLndyaXRlUG9zaXRpb24gPCB0aGlzLnRhaWwubGVuZ3RoKSB7XG4gICAgICAgICAgdGhpcy50YWlsID0gdGhpcy50YWlsLnN1YmFycmF5KHdyaXR0ZW4pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMudGFpbCA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGN1cnJlbnRQb3NpdGlvbiA9IHRoaXMuYXVkaW8ubW96Q3VycmVudFNhbXBsZU9mZnNldCgpO1xuICAgICAgYXZhaWxhYmxlID0gY3VycmVudFBvc2l0aW9uICsgdGhpcy5wcmVidWZmZXJTaXplIC0gdGhpcy53cml0ZVBvc2l0aW9uO1xuICAgICAgaWYgKGF2YWlsYWJsZSA+IDApIHtcbiAgICAgICAgYnVmZmVyID0gbmV3IEZsb2F0MzJBcnJheShhdmFpbGFibGUpO1xuICAgICAgICB0aGlzLmVtaXQoJ3JlZmlsbCcsIGJ1ZmZlcik7XG4gICAgICAgIHdyaXR0ZW4gPSB0aGlzLmF1ZGlvLm1veldyaXRlQXVkaW8oYnVmZmVyKTtcbiAgICAgICAgaWYgKHdyaXR0ZW4gPCBidWZmZXIubGVuZ3RoKSB7XG4gICAgICAgICAgdGhpcy50YWlsID0gYnVmZmVyLnN1YmFycmF5KHdyaXR0ZW4pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMud3JpdGVQb3NpdGlvbiArPSB3cml0dGVuO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBNb3ppbGxhQXVkaW9EZXZpY2UucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBkZXN0cm95VGltZXIodGhpcy50aW1lcik7XG4gICAgfTtcblxuICAgIE1vemlsbGFBdWRpb0RldmljZS5wcm90b3R5cGUuZ2V0RGV2aWNlVGltZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuYXVkaW8ubW96Q3VycmVudFNhbXBsZU9mZnNldCgpIC8gdGhpcy5jaGFubmVscztcbiAgICB9O1xuXG4gICAgY3JlYXRlVGltZXIgPSBmdW5jdGlvbihmbiwgaW50ZXJ2YWwpIHtcbiAgICAgIHZhciB1cmwsIHdvcmtlcjtcbiAgICAgIHVybCA9IEFWQnVmZmVyLm1ha2VCbG9iVVJMKFwic2V0SW50ZXJ2YWwoZnVuY3Rpb24oKSB7IHBvc3RNZXNzYWdlKCdwaW5nJyk7IH0sIFwiICsgaW50ZXJ2YWwgKyBcIik7XCIpO1xuICAgICAgaWYgKHVybCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBzZXRJbnRlcnZhbChmbiwgaW50ZXJ2YWwpO1xuICAgICAgfVxuICAgICAgd29ya2VyID0gbmV3IFdvcmtlcih1cmwpO1xuICAgICAgd29ya2VyLm9ubWVzc2FnZSA9IGZuO1xuICAgICAgd29ya2VyLnVybCA9IHVybDtcbiAgICAgIHJldHVybiB3b3JrZXI7XG4gICAgfTtcblxuICAgIGRlc3Ryb3lUaW1lciA9IGZ1bmN0aW9uKHRpbWVyKSB7XG4gICAgICBpZiAodGltZXIudGVybWluYXRlKSB7XG4gICAgICAgIHRpbWVyLnRlcm1pbmF0ZSgpO1xuICAgICAgICByZXR1cm4gVVJMLnJldm9rZU9iamVjdFVSTCh0aW1lci51cmwpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGNsZWFySW50ZXJ2YWwodGltZXIpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gTW96aWxsYUF1ZGlvRGV2aWNlO1xuXG4gIH0pKEV2ZW50RW1pdHRlcik7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvL0phdmFTY3JpcHQgQXVkaW8gUmVzYW1wbGVyXG4vL0NvcHlyaWdodCAoQykgMjAxMS0yMDE1IEdyYW50IEdhbGl0elxuLy9SZWxlYXNlZCB0byBQdWJsaWMgRG9tYWluXG5mdW5jdGlvbiBSZXNhbXBsZXIoZnJvbVNhbXBsZVJhdGUsIHRvU2FtcGxlUmF0ZSwgY2hhbm5lbHMsIGlucHV0QnVmZmVyTGVuZ3RoKSB7XG4gIHRoaXMuZnJvbVNhbXBsZVJhdGUgPSArZnJvbVNhbXBsZVJhdGU7XG4gIHRoaXMudG9TYW1wbGVSYXRlID0gK3RvU2FtcGxlUmF0ZTtcbiAgdGhpcy5jaGFubmVscyA9IGNoYW5uZWxzIHwgMDtcbiAgdGhpcy5pbnB1dEJ1ZmZlckxlbmd0aCA9IGlucHV0QnVmZmVyTGVuZ3RoO1xuICB0aGlzLmluaXRpYWxpemUoKTtcbn1cblxuUmVzYW1wbGVyLnByb3RvdHlwZS5pbml0aWFsaXplID0gZnVuY3Rpb24gKCkge1xuICAvL1BlcmZvcm0gc29tZSBjaGVja3M6XG4gIGlmICh0aGlzLmZyb21TYW1wbGVSYXRlID4gMCAmJiB0aGlzLnRvU2FtcGxlUmF0ZSA+IDAgJiYgdGhpcy5jaGFubmVscyA+IDApIHtcbiAgICBpZiAodGhpcy5mcm9tU2FtcGxlUmF0ZSA9PSB0aGlzLnRvU2FtcGxlUmF0ZSkge1xuICAgICAgLy9TZXR1cCBhIHJlc2FtcGxlciBieXBhc3M6XG4gICAgICB0aGlzLnJlc2FtcGxlciA9IHRoaXMuYnlwYXNzUmVzYW1wbGVyOyAgICAvL1Jlc2FtcGxlciBqdXN0IHJldHVybnMgd2hhdCB3YXMgcGFzc2VkIHRocm91Z2guXG4gICAgICB0aGlzLnJhdGlvV2VpZ2h0ID0gMTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5yYXRpb1dlaWdodCA9IHRoaXMuZnJvbVNhbXBsZVJhdGUgLyB0aGlzLnRvU2FtcGxlUmF0ZTtcbiAgICAgIGlmICh0aGlzLmZyb21TYW1wbGVSYXRlIDwgdGhpcy50b1NhbXBsZVJhdGUpIHtcbiAgICAgICAgLypcbiAgICAgICAgICBVc2UgZ2VuZXJpYyBsaW5lYXIgaW50ZXJwb2xhdGlvbiBpZiB1cHNhbXBsaW5nLFxuICAgICAgICAgIGFzIGxpbmVhciBpbnRlcnBvbGF0aW9uIHByb2R1Y2VzIGEgZ3JhZGllbnQgdGhhdCB3ZSB3YW50XG4gICAgICAgICAgYW5kIHdvcmtzIGZpbmUgd2l0aCB0d28gaW5wdXQgc2FtcGxlIHBvaW50cyBwZXIgb3V0cHV0IGluIHRoaXMgY2FzZS5cbiAgICAgICAgKi9cbiAgICAgICAgdGhpcy5jb21waWxlTGluZWFySW50ZXJwb2xhdGlvbkZ1bmN0aW9uKCk7XG4gICAgICAgIHRoaXMubGFzdFdlaWdodCA9IDE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvKlxuICAgICAgICAgIEN1c3RvbSByZXNhbXBsZXIgSSB3cm90ZSB0aGF0IGRvZXNuJ3Qgc2tpcCBzYW1wbGVzXG4gICAgICAgICAgbGlrZSBzdGFuZGFyZCBsaW5lYXIgaW50ZXJwb2xhdGlvbiBpbiBoaWdoIGRvd25zYW1wbGluZy5cbiAgICAgICAgICBUaGlzIGlzIG1vcmUgYWNjdXJhdGUgdGhhbiBsaW5lYXIgaW50ZXJwb2xhdGlvbiBvbiBkb3duc2FtcGxpbmcuXG4gICAgICAgICovXG4gICAgICAgIHRoaXMuY29tcGlsZU11bHRpVGFwRnVuY3Rpb24oKTtcbiAgICAgICAgdGhpcy50YWlsRXhpc3RzID0gZmFsc2U7XG4gICAgICAgIHRoaXMubGFzdFdlaWdodCA9IDA7XG4gICAgICB9XG4gICAgICBcbiAgICAgIHZhciBvdXRwdXRCdWZmZXJTaXplID0gKE1hdGguY2VpbCh0aGlzLmlucHV0QnVmZmVyTGVuZ3RoICogdGhpcy50b1NhbXBsZVJhdGUgLyB0aGlzLmZyb21TYW1wbGVSYXRlIC8gdGhpcy5jaGFubmVscyAqIDEuMDEpICogdGhpcy5jaGFubmVscykgKyB0aGlzLmNoYW5uZWxzO1xuICAgICAgdGhpcy5vdXRwdXRCdWZmZXIgPSBuZXcgRmxvYXQzMkFycmF5KG91dHB1dEJ1ZmZlclNpemUpO1xuICAgICAgdGhpcy5sYXN0T3V0cHV0ID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLmNoYW5uZWxzKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cobmV3IEVycm9yKFwiSW52YWxpZCBzZXR0aW5ncyBzcGVjaWZpZWQgZm9yIHRoZSByZXNhbXBsZXIuXCIpKTtcbiAgfVxufTtcblxuUmVzYW1wbGVyLnByb3RvdHlwZS5jb21waWxlTGluZWFySW50ZXJwb2xhdGlvbkZ1bmN0aW9uID0gZnVuY3Rpb24gKCkge1xuICB2YXIgdG9Db21waWxlID0gXCJ2YXIgb3V0cHV0T2Zmc2V0ID0gMDtcXFxuICAgIHZhciBidWZmZXJMZW5ndGggPSBidWZmZXIubGVuZ3RoO1xcXG4gICAgaWYgKGJ1ZmZlckxlbmd0aCA+IDApIHtcXFxuICAgICAgdmFyIHdlaWdodCA9IHRoaXMubGFzdFdlaWdodDtcXFxuICAgICAgdmFyIGZpcnN0V2VpZ2h0ID0gMDtcXFxuICAgICAgdmFyIHNlY29uZFdlaWdodCA9IDA7XFxcbiAgICAgIHZhciBzb3VyY2VPZmZzZXQgPSAwO1xcXG4gICAgICB2YXIgb3V0cHV0T2Zmc2V0ID0gMDtcXFxuICAgICAgdmFyIG91dHB1dEJ1ZmZlciA9IHRoaXMub3V0cHV0QnVmZmVyO1xcXG4gICAgICBmb3IgKDsgd2VpZ2h0IDwgMTsgd2VpZ2h0ICs9IFwiICsgdGhpcy5yYXRpb1dlaWdodCArIFwiKSB7XFxcbiAgICAgICAgc2Vjb25kV2VpZ2h0ID0gd2VpZ2h0ICUgMTtcXFxuICAgICAgICBmaXJzdFdlaWdodCA9IDEgLSBzZWNvbmRXZWlnaHQ7XCI7XG4gICAgICAgIGZvciAodmFyIGNoYW5uZWwgPSAwOyBjaGFubmVsIDwgdGhpcy5jaGFubmVsczsgKytjaGFubmVsKSB7XG4gICAgICAgICAgdG9Db21waWxlICs9IFwib3V0cHV0QnVmZmVyW291dHB1dE9mZnNldCsrXSA9ICh0aGlzLmxhc3RPdXRwdXRbXCIgKyBjaGFubmVsICsgXCJdICogZmlyc3RXZWlnaHQpICsgKGJ1ZmZlcltcIiArIGNoYW5uZWwgKyBcIl0gKiBzZWNvbmRXZWlnaHQpO1wiO1xuICAgICAgICB9XG4gICAgICB0b0NvbXBpbGUgKz0gXCJ9XFxcbiAgICAgIHdlaWdodCAtPSAxO1xcXG4gICAgICBmb3IgKGJ1ZmZlckxlbmd0aCAtPSBcIiArIHRoaXMuY2hhbm5lbHMgKyBcIiwgc291cmNlT2Zmc2V0ID0gTWF0aC5mbG9vcih3ZWlnaHQpICogXCIgKyB0aGlzLmNoYW5uZWxzICsgXCI7IHNvdXJjZU9mZnNldCA8IGJ1ZmZlckxlbmd0aDspIHtcXFxuICAgICAgICBzZWNvbmRXZWlnaHQgPSB3ZWlnaHQgJSAxO1xcXG4gICAgICAgIGZpcnN0V2VpZ2h0ID0gMSAtIHNlY29uZFdlaWdodDtcIjtcbiAgICAgICAgZm9yICh2YXIgY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCB0aGlzLmNoYW5uZWxzOyArK2NoYW5uZWwpIHtcbiAgICAgICAgICB0b0NvbXBpbGUgKz0gXCJvdXRwdXRCdWZmZXJbb3V0cHV0T2Zmc2V0KytdID0gKGJ1ZmZlcltzb3VyY2VPZmZzZXRcIiArICgoY2hhbm5lbCA+IDApID8gKFwiICsgXCIgKyBjaGFubmVsKSA6IFwiXCIpICsgXCJdICogZmlyc3RXZWlnaHQpICsgKGJ1ZmZlcltzb3VyY2VPZmZzZXQgKyBcIiArICh0aGlzLmNoYW5uZWxzICsgY2hhbm5lbCkgKyBcIl0gKiBzZWNvbmRXZWlnaHQpO1wiO1xuICAgICAgICB9XG4gICAgICAgIHRvQ29tcGlsZSArPSBcIndlaWdodCArPSBcIiArIHRoaXMucmF0aW9XZWlnaHQgKyBcIjtcXFxuICAgICAgICBzb3VyY2VPZmZzZXQgPSBNYXRoLmZsb29yKHdlaWdodCkgKiBcIiArIHRoaXMuY2hhbm5lbHMgKyBcIjtcXFxuICAgICAgfVwiO1xuICAgICAgZm9yICh2YXIgY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCB0aGlzLmNoYW5uZWxzOyArK2NoYW5uZWwpIHtcbiAgICAgICAgdG9Db21waWxlICs9IFwidGhpcy5sYXN0T3V0cHV0W1wiICsgY2hhbm5lbCArIFwiXSA9IGJ1ZmZlcltzb3VyY2VPZmZzZXQrK107XCI7XG4gICAgICB9XG4gICAgICB0b0NvbXBpbGUgKz0gXCJ0aGlzLmxhc3RXZWlnaHQgPSB3ZWlnaHQgJSAxO1xcXG4gICAgfVxcXG4gICAgcmV0dXJuIHRoaXMub3V0cHV0QnVmZmVyO1wiO1xuICAgIFxuICB0aGlzLnJlc2FtcGxlciA9IEZ1bmN0aW9uKFwiYnVmZmVyXCIsIHRvQ29tcGlsZSk7XG59O1xuXG5SZXNhbXBsZXIucHJvdG90eXBlLmNvbXBpbGVNdWx0aVRhcEZ1bmN0aW9uID0gZnVuY3Rpb24gKCkge1xuICB2YXIgdG9Db21waWxlID0gXCJ2YXIgb3V0cHV0T2Zmc2V0ID0gMDtcXFxuICAgIHZhciBidWZmZXJMZW5ndGggPSBidWZmZXIubGVuZ3RoO1xcXG4gICAgaWYgKGJ1ZmZlckxlbmd0aCA+IDApIHtcXFxuICAgICAgdmFyIHdlaWdodCA9IDA7XCI7XG4gICAgICBmb3IgKHZhciBjaGFubmVsID0gMDsgY2hhbm5lbCA8IHRoaXMuY2hhbm5lbHM7ICsrY2hhbm5lbCkge1xuICAgICAgICB0b0NvbXBpbGUgKz0gXCJ2YXIgb3V0cHV0XCIgKyBjaGFubmVsICsgXCIgPSAwO1wiXG4gICAgICB9XG4gICAgICB0b0NvbXBpbGUgKz0gXCJ2YXIgYWN0dWFsUG9zaXRpb24gPSAwO1xcXG4gICAgICB2YXIgYW1vdW50VG9OZXh0ID0gMDtcXFxuICAgICAgdmFyIGFscmVhZHlQcm9jZXNzZWRUYWlsID0gIXRoaXMudGFpbEV4aXN0cztcXFxuICAgICAgdGhpcy50YWlsRXhpc3RzID0gZmFsc2U7XFxcbiAgICAgIHZhciBvdXRwdXRCdWZmZXIgPSB0aGlzLm91dHB1dEJ1ZmZlcjtcXFxuICAgICAgdmFyIGN1cnJlbnRQb3NpdGlvbiA9IDA7XFxcbiAgICAgIGRvIHtcXFxuICAgICAgICBpZiAoYWxyZWFkeVByb2Nlc3NlZFRhaWwpIHtcXFxuICAgICAgICAgIHdlaWdodCA9IFwiICsgdGhpcy5yYXRpb1dlaWdodCArIFwiO1wiO1xuICAgICAgICAgIGZvciAoY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCB0aGlzLmNoYW5uZWxzOyArK2NoYW5uZWwpIHtcbiAgICAgICAgICAgIHRvQ29tcGlsZSArPSBcIm91dHB1dFwiICsgY2hhbm5lbCArIFwiID0gMDtcIlxuICAgICAgICAgIH1cbiAgICAgICAgdG9Db21waWxlICs9IFwifVxcXG4gICAgICAgIGVsc2Uge1xcXG4gICAgICAgICAgd2VpZ2h0ID0gdGhpcy5sYXN0V2VpZ2h0O1wiO1xuICAgICAgICAgIGZvciAoY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCB0aGlzLmNoYW5uZWxzOyArK2NoYW5uZWwpIHtcbiAgICAgICAgICAgIHRvQ29tcGlsZSArPSBcIm91dHB1dFwiICsgY2hhbm5lbCArIFwiID0gdGhpcy5sYXN0T3V0cHV0W1wiICsgY2hhbm5lbCArIFwiXTtcIlxuICAgICAgICAgIH1cbiAgICAgICAgICB0b0NvbXBpbGUgKz0gXCJhbHJlYWR5UHJvY2Vzc2VkVGFpbCA9IHRydWU7XFxcbiAgICAgICAgfVxcXG4gICAgICAgIHdoaWxlICh3ZWlnaHQgPiAwICYmIGFjdHVhbFBvc2l0aW9uIDwgYnVmZmVyTGVuZ3RoKSB7XFxcbiAgICAgICAgICBhbW91bnRUb05leHQgPSAxICsgYWN0dWFsUG9zaXRpb24gLSBjdXJyZW50UG9zaXRpb247XFxcbiAgICAgICAgICBpZiAod2VpZ2h0ID49IGFtb3VudFRvTmV4dCkge1wiO1xuICAgICAgICAgICAgZm9yIChjaGFubmVsID0gMDsgY2hhbm5lbCA8IHRoaXMuY2hhbm5lbHM7ICsrY2hhbm5lbCkge1xuICAgICAgICAgICAgICB0b0NvbXBpbGUgKz0gXCJvdXRwdXRcIiArIGNoYW5uZWwgKyBcIiArPSBidWZmZXJbYWN0dWFsUG9zaXRpb24rK10gKiBhbW91bnRUb05leHQ7XCJcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRvQ29tcGlsZSArPSBcImN1cnJlbnRQb3NpdGlvbiA9IGFjdHVhbFBvc2l0aW9uO1xcXG4gICAgICAgICAgICB3ZWlnaHQgLT0gYW1vdW50VG9OZXh0O1xcXG4gICAgICAgICAgfVxcXG4gICAgICAgICAgZWxzZSB7XCI7XG4gICAgICAgICAgICBmb3IgKGNoYW5uZWwgPSAwOyBjaGFubmVsIDwgdGhpcy5jaGFubmVsczsgKytjaGFubmVsKSB7XG4gICAgICAgICAgICAgIHRvQ29tcGlsZSArPSBcIm91dHB1dFwiICsgY2hhbm5lbCArIFwiICs9IGJ1ZmZlclthY3R1YWxQb3NpdGlvblwiICsgKChjaGFubmVsID4gMCkgPyAoXCIgKyBcIiArIGNoYW5uZWwpIDogXCJcIikgKyBcIl0gKiB3ZWlnaHQ7XCJcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRvQ29tcGlsZSArPSBcImN1cnJlbnRQb3NpdGlvbiArPSB3ZWlnaHQ7XFxcbiAgICAgICAgICAgIHdlaWdodCA9IDA7XFxcbiAgICAgICAgICAgIGJyZWFrO1xcXG4gICAgICAgICAgfVxcXG4gICAgICAgIH1cXFxuICAgICAgICBpZiAod2VpZ2h0IDw9IDApIHtcIjtcbiAgICAgICAgICBmb3IgKGNoYW5uZWwgPSAwOyBjaGFubmVsIDwgdGhpcy5jaGFubmVsczsgKytjaGFubmVsKSB7XG4gICAgICAgICAgICB0b0NvbXBpbGUgKz0gXCJvdXRwdXRCdWZmZXJbb3V0cHV0T2Zmc2V0KytdID0gb3V0cHV0XCIgKyBjaGFubmVsICsgXCIgLyBcIiArIHRoaXMucmF0aW9XZWlnaHQgKyBcIjtcIlxuICAgICAgICAgIH1cbiAgICAgICAgdG9Db21waWxlICs9IFwifVxcXG4gICAgICAgIGVsc2Uge1xcXG4gICAgICAgICAgdGhpcy5sYXN0V2VpZ2h0ID0gd2VpZ2h0O1wiO1xuICAgICAgICAgIGZvciAoY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCB0aGlzLmNoYW5uZWxzOyArK2NoYW5uZWwpIHtcbiAgICAgICAgICAgIHRvQ29tcGlsZSArPSBcInRoaXMubGFzdE91dHB1dFtcIiArIGNoYW5uZWwgKyBcIl0gPSBvdXRwdXRcIiArIGNoYW5uZWwgKyBcIjtcIlxuICAgICAgICAgIH1cbiAgICAgICAgICB0b0NvbXBpbGUgKz0gXCJ0aGlzLnRhaWxFeGlzdHMgPSB0cnVlO1xcXG4gICAgICAgICAgYnJlYWs7XFxcbiAgICAgICAgfVxcXG4gICAgICB9IHdoaWxlIChhY3R1YWxQb3NpdGlvbiA8IGJ1ZmZlckxlbmd0aCk7XFxcbiAgICB9XFxcbiAgICByZXR1cm4gdGhpcy5vdXRwdXRCdWZmZXI7XCI7XG4gIFxuICB0aGlzLnJlc2FtcGxlciA9IEZ1bmN0aW9uKFwiYnVmZmVyXCIsIHRvQ29tcGlsZSk7XG59O1xuXG5SZXNhbXBsZXIucHJvdG90eXBlLmJ5cGFzc1Jlc2FtcGxlciA9IGZ1bmN0aW9uIChpbnB1dEJ1ZmZlcikge1xuICByZXR1cm4gaW5wdXRCdWZmZXI7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlc2FtcGxlcjtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS43LjFcbihmdW5jdGlvbigpIHtcbiAgdmFyIEF1ZGlvRGV2aWNlLCBFdmVudEVtaXR0ZXIsIFJlc2FtcGxlciwgV2ViQXVkaW9EZXZpY2UsXG4gICAgX19iaW5kID0gZnVuY3Rpb24oZm4sIG1lKXsgcmV0dXJuIGZ1bmN0aW9uKCl7IHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTsgfTsgfSxcbiAgICBfX2hhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgICBfX2V4dGVuZHMgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKF9faGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfTtcblxuICBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuLi9jb3JlL2V2ZW50cycpO1xuXG4gIEF1ZGlvRGV2aWNlID0gcmVxdWlyZSgnLi4vZGV2aWNlJyk7XG5cbiAgUmVzYW1wbGVyID0gcmVxdWlyZSgnLi9yZXNhbXBsZXInKTtcblxuICBXZWJBdWRpb0RldmljZSA9IChmdW5jdGlvbihfc3VwZXIpIHtcbiAgICB2YXIgQXVkaW9Db250ZXh0LCBjcmVhdGVQcm9jZXNzb3IsIHNoYXJlZENvbnRleHQ7XG5cbiAgICBfX2V4dGVuZHMoV2ViQXVkaW9EZXZpY2UsIF9zdXBlcik7XG5cbiAgICBBdWRpb0RldmljZS5yZWdpc3RlcihXZWJBdWRpb0RldmljZSk7XG5cbiAgICBBdWRpb0NvbnRleHQgPSBnbG9iYWwuQXVkaW9Db250ZXh0IHx8IGdsb2JhbC53ZWJraXRBdWRpb0NvbnRleHQ7XG5cbiAgICBXZWJBdWRpb0RldmljZS5zdXBwb3J0ZWQgPSBBdWRpb0NvbnRleHQgJiYgKHR5cGVvZiBBdWRpb0NvbnRleHQucHJvdG90eXBlW2NyZWF0ZVByb2Nlc3NvciA9ICdjcmVhdGVTY3JpcHRQcm9jZXNzb3InXSA9PT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgQXVkaW9Db250ZXh0LnByb3RvdHlwZVtjcmVhdGVQcm9jZXNzb3IgPSAnY3JlYXRlSmF2YVNjcmlwdE5vZGUnXSA9PT0gJ2Z1bmN0aW9uJyk7XG5cbiAgICBzaGFyZWRDb250ZXh0ID0gbnVsbDtcblxuICAgIGZ1bmN0aW9uIFdlYkF1ZGlvRGV2aWNlKHNhbXBsZVJhdGUsIGNoYW5uZWxzKSB7XG4gICAgICB0aGlzLnNhbXBsZVJhdGUgPSBzYW1wbGVSYXRlO1xuICAgICAgdGhpcy5jaGFubmVscyA9IGNoYW5uZWxzO1xuICAgICAgdGhpcy5yZWZpbGwgPSBfX2JpbmQodGhpcy5yZWZpbGwsIHRoaXMpO1xuICAgICAgdGhpcy5jb250ZXh0ID0gc2hhcmVkQ29udGV4dCAhPSBudWxsID8gc2hhcmVkQ29udGV4dCA6IHNoYXJlZENvbnRleHQgPSBuZXcgQXVkaW9Db250ZXh0O1xuICAgICAgdGhpcy5kZXZpY2VTYW1wbGVSYXRlID0gdGhpcy5jb250ZXh0LnNhbXBsZVJhdGU7XG4gICAgICB0aGlzLmJ1ZmZlclNpemUgPSBNYXRoLmNlaWwoNDA5NiAvICh0aGlzLmRldmljZVNhbXBsZVJhdGUgLyB0aGlzLnNhbXBsZVJhdGUpICogdGhpcy5jaGFubmVscyk7XG4gICAgICB0aGlzLmJ1ZmZlclNpemUgKz0gdGhpcy5idWZmZXJTaXplICUgdGhpcy5jaGFubmVscztcbiAgICAgIGlmICh0aGlzLmRldmljZVNhbXBsZVJhdGUgIT09IHRoaXMuc2FtcGxlUmF0ZSkge1xuICAgICAgICB0aGlzLnJlc2FtcGxlciA9IG5ldyBSZXNhbXBsZXIodGhpcy5zYW1wbGVSYXRlLCB0aGlzLmRldmljZVNhbXBsZVJhdGUsIHRoaXMuY2hhbm5lbHMsIHRoaXMuYnVmZmVyU2l6ZSk7XG4gICAgICB9XG4gICAgICB0aGlzLm5vZGUgPSB0aGlzLmNvbnRleHRbY3JlYXRlUHJvY2Vzc29yXSg0MDk2LCB0aGlzLmNoYW5uZWxzLCB0aGlzLmNoYW5uZWxzKTtcbiAgICAgIHRoaXMubm9kZS5vbmF1ZGlvcHJvY2VzcyA9IHRoaXMucmVmaWxsO1xuICAgICAgdGhpcy5ub2RlLmNvbm5lY3QodGhpcy5jb250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICB9XG5cbiAgICBXZWJBdWRpb0RldmljZS5wcm90b3R5cGUucmVmaWxsID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgIHZhciBjaGFubmVsQ291bnQsIGNoYW5uZWxzLCBkYXRhLCBpLCBuLCBvdXRwdXRCdWZmZXIsIF9pLCBfaiwgX2ssIF9yZWY7XG4gICAgICBvdXRwdXRCdWZmZXIgPSBldmVudC5vdXRwdXRCdWZmZXI7XG4gICAgICBjaGFubmVsQ291bnQgPSBvdXRwdXRCdWZmZXIubnVtYmVyT2ZDaGFubmVscztcbiAgICAgIGNoYW5uZWxzID0gbmV3IEFycmF5KGNoYW5uZWxDb3VudCk7XG4gICAgICBmb3IgKGkgPSBfaSA9IDA7IF9pIDwgY2hhbm5lbENvdW50OyBpID0gX2kgKz0gMSkge1xuICAgICAgICBjaGFubmVsc1tpXSA9IG91dHB1dEJ1ZmZlci5nZXRDaGFubmVsRGF0YShpKTtcbiAgICAgIH1cbiAgICAgIGRhdGEgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYnVmZmVyU2l6ZSk7XG4gICAgICB0aGlzLmVtaXQoJ3JlZmlsbCcsIGRhdGEpO1xuICAgICAgaWYgKHRoaXMucmVzYW1wbGVyKSB7XG4gICAgICAgIGRhdGEgPSB0aGlzLnJlc2FtcGxlci5yZXNhbXBsZXIoZGF0YSk7XG4gICAgICB9XG4gICAgICBmb3IgKGkgPSBfaiA9IDAsIF9yZWYgPSBvdXRwdXRCdWZmZXIubGVuZ3RoOyBfaiA8IF9yZWY7IGkgPSBfaiArPSAxKSB7XG4gICAgICAgIGZvciAobiA9IF9rID0gMDsgX2sgPCBjaGFubmVsQ291bnQ7IG4gPSBfayArPSAxKSB7XG4gICAgICAgICAgY2hhbm5lbHNbbl1baV0gPSBkYXRhW2kgKiBjaGFubmVsQ291bnQgKyBuXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBXZWJBdWRpb0RldmljZS5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMubm9kZS5kaXNjb25uZWN0KDApO1xuICAgIH07XG5cbiAgICBXZWJBdWRpb0RldmljZS5wcm90b3R5cGUuZ2V0RGV2aWNlVGltZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC5jdXJyZW50VGltZSAqIHRoaXMuc2FtcGxlUmF0ZTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFdlYkF1ZGlvRGV2aWNlO1xuXG4gIH0pKEV2ZW50RW1pdHRlcik7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuNy4xXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBGaWx0ZXI7XG5cbiAgRmlsdGVyID0gKGZ1bmN0aW9uKCkge1xuICAgIGZ1bmN0aW9uIEZpbHRlcihjb250ZXh0LCBrZXkpIHtcbiAgICAgIGlmIChjb250ZXh0ICYmIGtleSkge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3ZhbHVlJywge1xuICAgICAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gY29udGV4dFtrZXldO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgRmlsdGVyLnByb3RvdHlwZS5wcm9jZXNzID0gZnVuY3Rpb24oYnVmZmVyKSB7fTtcblxuICAgIHJldHVybiBGaWx0ZXI7XG5cbiAgfSkoKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IEZpbHRlcjtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS43LjFcbihmdW5jdGlvbigpIHtcbiAgdmFyIEJhbGFuY2VGaWx0ZXIsIEZpbHRlcixcbiAgICBfX2hhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgICBfX2V4dGVuZHMgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKF9faGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfTtcblxuICBGaWx0ZXIgPSByZXF1aXJlKCcuLi9maWx0ZXInKTtcblxuICBCYWxhbmNlRmlsdGVyID0gKGZ1bmN0aW9uKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhCYWxhbmNlRmlsdGVyLCBfc3VwZXIpO1xuXG4gICAgZnVuY3Rpb24gQmFsYW5jZUZpbHRlcigpIHtcbiAgICAgIHJldHVybiBCYWxhbmNlRmlsdGVyLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIEJhbGFuY2VGaWx0ZXIucHJvdG90eXBlLnByb2Nlc3MgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHZhciBpLCBwYW4sIF9pLCBfcmVmO1xuICAgICAgaWYgKHRoaXMudmFsdWUgPT09IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcGFuID0gTWF0aC5tYXgoLTUwLCBNYXRoLm1pbig1MCwgdGhpcy52YWx1ZSkpO1xuICAgICAgZm9yIChpID0gX2kgPSAwLCBfcmVmID0gYnVmZmVyLmxlbmd0aDsgX2kgPCBfcmVmOyBpID0gX2kgKz0gMikge1xuICAgICAgICBidWZmZXJbaV0gKj0gTWF0aC5taW4oMSwgKDUwIC0gcGFuKSAvIDUwKTtcbiAgICAgICAgYnVmZmVyW2kgKyAxXSAqPSBNYXRoLm1pbigxLCAoNTAgKyBwYW4pIC8gNTApO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gQmFsYW5jZUZpbHRlcjtcblxuICB9KShGaWx0ZXIpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gQmFsYW5jZUZpbHRlcjtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS43LjFcbihmdW5jdGlvbigpIHtcbiAgdmFyIEZpbHRlciwgVm9sdW1lRmlsdGVyLFxuICAgIF9faGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5LFxuICAgIF9fZXh0ZW5kcyA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoX19oYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9O1xuXG4gIEZpbHRlciA9IHJlcXVpcmUoJy4uL2ZpbHRlcicpO1xuXG4gIFZvbHVtZUZpbHRlciA9IChmdW5jdGlvbihfc3VwZXIpIHtcbiAgICBfX2V4dGVuZHMoVm9sdW1lRmlsdGVyLCBfc3VwZXIpO1xuXG4gICAgZnVuY3Rpb24gVm9sdW1lRmlsdGVyKCkge1xuICAgICAgcmV0dXJuIFZvbHVtZUZpbHRlci5fX3N1cGVyX18uY29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICBWb2x1bWVGaWx0ZXIucHJvdG90eXBlLnByb2Nlc3MgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHZhciBpLCB2b2wsIF9pLCBfcmVmO1xuICAgICAgaWYgKHRoaXMudmFsdWUgPj0gMTAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHZvbCA9IE1hdGgubWF4KDAsIE1hdGgubWluKDEwMCwgdGhpcy52YWx1ZSkpIC8gMTAwO1xuICAgICAgZm9yIChpID0gX2kgPSAwLCBfcmVmID0gYnVmZmVyLmxlbmd0aDsgX2kgPCBfcmVmOyBpID0gX2kgKz0gMSkge1xuICAgICAgICBidWZmZXJbaV0gKj0gdm9sO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gVm9sdW1lRmlsdGVyO1xuXG4gIH0pKEZpbHRlcik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBWb2x1bWVGaWx0ZXI7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuNy4xXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBBc3NldCwgQXVkaW9EZXZpY2UsIEJhbGFuY2VGaWx0ZXIsIEV2ZW50RW1pdHRlciwgUGxheWVyLCBRdWV1ZSwgVm9sdW1lRmlsdGVyLFxuICAgIF9fYmluZCA9IGZ1bmN0aW9uKGZuLCBtZSl7IHJldHVybiBmdW5jdGlvbigpeyByZXR1cm4gZm4uYXBwbHkobWUsIGFyZ3VtZW50cyk7IH07IH0sXG4gICAgX19oYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHksXG4gICAgX19leHRlbmRzID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChfX2hhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH07XG5cbiAgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnLi9jb3JlL2V2ZW50cycpO1xuXG4gIEFzc2V0ID0gcmVxdWlyZSgnLi9hc3NldCcpO1xuXG4gIFZvbHVtZUZpbHRlciA9IHJlcXVpcmUoJy4vZmlsdGVycy92b2x1bWUnKTtcblxuICBCYWxhbmNlRmlsdGVyID0gcmVxdWlyZSgnLi9maWx0ZXJzL2JhbGFuY2UnKTtcblxuICBRdWV1ZSA9IHJlcXVpcmUoJy4vcXVldWUnKTtcblxuICBBdWRpb0RldmljZSA9IHJlcXVpcmUoJy4vZGV2aWNlJyk7XG5cbiAgUGxheWVyID0gKGZ1bmN0aW9uKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhQbGF5ZXIsIF9zdXBlcik7XG5cbiAgICBmdW5jdGlvbiBQbGF5ZXIoYXNzZXQpIHtcbiAgICAgIHRoaXMuYXNzZXQgPSBhc3NldDtcbiAgICAgIHRoaXMuc3RhcnRQbGF5aW5nID0gX19iaW5kKHRoaXMuc3RhcnRQbGF5aW5nLCB0aGlzKTtcbiAgICAgIHRoaXMucGxheWluZyA9IGZhbHNlO1xuICAgICAgdGhpcy5idWZmZXJlZCA9IDA7XG4gICAgICB0aGlzLmN1cnJlbnRUaW1lID0gMDtcbiAgICAgIHRoaXMuZHVyYXRpb24gPSAwO1xuICAgICAgdGhpcy52b2x1bWUgPSAxMDA7XG4gICAgICB0aGlzLnBhbiA9IDA7XG4gICAgICB0aGlzLm1ldGFkYXRhID0ge307XG4gICAgICB0aGlzLmZpbHRlcnMgPSBbbmV3IFZvbHVtZUZpbHRlcih0aGlzLCAndm9sdW1lJyksIG5ldyBCYWxhbmNlRmlsdGVyKHRoaXMsICdwYW4nKV07XG4gICAgICB0aGlzLmFzc2V0Lm9uKCdidWZmZXInLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGJ1ZmZlcmVkKSB7XG4gICAgICAgICAgX3RoaXMuYnVmZmVyZWQgPSBidWZmZXJlZDtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnYnVmZmVyJywgX3RoaXMuYnVmZmVyZWQpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5hc3NldC5vbignZGVjb2RlU3RhcnQnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgIF90aGlzLnF1ZXVlID0gbmV3IFF1ZXVlKF90aGlzLmFzc2V0KTtcbiAgICAgICAgICByZXR1cm4gX3RoaXMucXVldWUub25jZSgncmVhZHknLCBfdGhpcy5zdGFydFBsYXlpbmcpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5hc3NldC5vbignZm9ybWF0JywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihmb3JtYXQpIHtcbiAgICAgICAgICBfdGhpcy5mb3JtYXQgPSBmb3JtYXQ7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ2Zvcm1hdCcsIF90aGlzLmZvcm1hdCk7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLmFzc2V0Lm9uKCdtZXRhZGF0YScsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24obWV0YWRhdGEpIHtcbiAgICAgICAgICBfdGhpcy5tZXRhZGF0YSA9IG1ldGFkYXRhO1xuICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdtZXRhZGF0YScsIF90aGlzLm1ldGFkYXRhKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHRoaXMuYXNzZXQub24oJ2R1cmF0aW9uJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihkdXJhdGlvbikge1xuICAgICAgICAgIF90aGlzLmR1cmF0aW9uID0gZHVyYXRpb247XG4gICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ2R1cmF0aW9uJywgX3RoaXMuZHVyYXRpb24pO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5hc3NldC5vbignZXJyb3InLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ2Vycm9yJywgZXJyb3IpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgIH1cblxuICAgIFBsYXllci5mcm9tVVJMID0gZnVuY3Rpb24odXJsLCBvcHRzKSB7XG4gICAgICByZXR1cm4gbmV3IFBsYXllcihBc3NldC5mcm9tVVJMKHVybCwgb3B0cykpO1xuICAgIH07XG5cbiAgICBQbGF5ZXIuZnJvbUZpbGUgPSBmdW5jdGlvbihmaWxlKSB7XG4gICAgICByZXR1cm4gbmV3IFBsYXllcihBc3NldC5mcm9tRmlsZShmaWxlKSk7XG4gICAgfTtcblxuICAgIFBsYXllci5mcm9tQnVmZmVyID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICByZXR1cm4gbmV3IFBsYXllcihBc3NldC5mcm9tQnVmZmVyKGJ1ZmZlcikpO1xuICAgIH07XG5cbiAgICBQbGF5ZXIucHJvdG90eXBlLnByZWxvYWQgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmICghdGhpcy5hc3NldCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLnN0YXJ0ZWRQcmVsb2FkaW5nID0gdHJ1ZTtcbiAgICAgIHJldHVybiB0aGlzLmFzc2V0LnN0YXJ0KGZhbHNlKTtcbiAgICB9O1xuXG4gICAgUGxheWVyLnByb3RvdHlwZS5wbGF5ID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgX3JlZjtcbiAgICAgIGlmICh0aGlzLnBsYXlpbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKCF0aGlzLnN0YXJ0ZWRQcmVsb2FkaW5nKSB7XG4gICAgICAgIHRoaXMucHJlbG9hZCgpO1xuICAgICAgfVxuICAgICAgdGhpcy5wbGF5aW5nID0gdHJ1ZTtcbiAgICAgIHJldHVybiAoX3JlZiA9IHRoaXMuZGV2aWNlKSAhPSBudWxsID8gX3JlZi5zdGFydCgpIDogdm9pZCAwO1xuICAgIH07XG5cbiAgICBQbGF5ZXIucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgX3JlZjtcbiAgICAgIGlmICghdGhpcy5wbGF5aW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMucGxheWluZyA9IGZhbHNlO1xuICAgICAgcmV0dXJuIChfcmVmID0gdGhpcy5kZXZpY2UpICE9IG51bGwgPyBfcmVmLnN0b3AoKSA6IHZvaWQgMDtcbiAgICB9O1xuXG4gICAgUGxheWVyLnByb3RvdHlwZS50b2dnbGVQbGF5YmFjayA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHRoaXMucGxheWluZykge1xuICAgICAgICByZXR1cm4gdGhpcy5wYXVzZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGxheSgpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBQbGF5ZXIucHJvdG90eXBlLnN0b3AgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBfcmVmO1xuICAgICAgdGhpcy5wYXVzZSgpO1xuICAgICAgdGhpcy5hc3NldC5zdG9wKCk7XG4gICAgICByZXR1cm4gKF9yZWYgPSB0aGlzLmRldmljZSkgIT0gbnVsbCA/IF9yZWYuZGVzdHJveSgpIDogdm9pZCAwO1xuICAgIH07XG5cbiAgICBQbGF5ZXIucHJvdG90eXBlLnNlZWsgPSBmdW5jdGlvbih0aW1lc3RhbXApIHtcbiAgICAgIHZhciBfcmVmO1xuICAgICAgaWYgKChfcmVmID0gdGhpcy5kZXZpY2UpICE9IG51bGwpIHtcbiAgICAgICAgX3JlZi5zdG9wKCk7XG4gICAgICB9XG4gICAgICB0aGlzLnF1ZXVlLm9uY2UoJ3JlYWR5JywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICB2YXIgX3JlZjEsIF9yZWYyO1xuICAgICAgICAgIGlmICgoX3JlZjEgPSBfdGhpcy5kZXZpY2UpICE9IG51bGwpIHtcbiAgICAgICAgICAgIF9yZWYxLnNlZWsoX3RoaXMuY3VycmVudFRpbWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoX3RoaXMucGxheWluZykge1xuICAgICAgICAgICAgcmV0dXJuIChfcmVmMiA9IF90aGlzLmRldmljZSkgIT0gbnVsbCA/IF9yZWYyLnN0YXJ0KCkgOiB2b2lkIDA7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGltZXN0YW1wID0gKHRpbWVzdGFtcCAvIDEwMDApICogdGhpcy5mb3JtYXQuc2FtcGxlUmF0ZTtcbiAgICAgIHRpbWVzdGFtcCA9IHRoaXMuYXNzZXQuZGVjb2Rlci5zZWVrKHRpbWVzdGFtcCk7XG4gICAgICB0aGlzLmN1cnJlbnRUaW1lID0gdGltZXN0YW1wIC8gdGhpcy5mb3JtYXQuc2FtcGxlUmF0ZSAqIDEwMDAgfCAwO1xuICAgICAgdGhpcy5xdWV1ZS5yZXNldCgpO1xuICAgICAgcmV0dXJuIHRoaXMuY3VycmVudFRpbWU7XG4gICAgfTtcblxuICAgIFBsYXllci5wcm90b3R5cGUuc3RhcnRQbGF5aW5nID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgZnJhbWUsIGZyYW1lT2Zmc2V0O1xuICAgICAgZnJhbWUgPSB0aGlzLnF1ZXVlLnJlYWQoKTtcbiAgICAgIGZyYW1lT2Zmc2V0ID0gMDtcbiAgICAgIHRoaXMuZGV2aWNlID0gbmV3IEF1ZGlvRGV2aWNlKHRoaXMuZm9ybWF0LnNhbXBsZVJhdGUsIHRoaXMuZm9ybWF0LmNoYW5uZWxzUGVyRnJhbWUpO1xuICAgICAgdGhpcy5kZXZpY2Uub24oJ3RpbWVVcGRhdGUnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGN1cnJlbnRUaW1lKSB7XG4gICAgICAgICAgX3RoaXMuY3VycmVudFRpbWUgPSBjdXJyZW50VGltZTtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgncHJvZ3Jlc3MnLCBfdGhpcy5jdXJyZW50VGltZSk7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLnJlZmlsbCA9IChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICAgICAgdmFyIGJ1ZmZlck9mZnNldCwgZmlsdGVyLCBpLCBtYXgsIF9pLCBfaiwgX2xlbiwgX3JlZjtcbiAgICAgICAgICBpZiAoIV90aGlzLnBsYXlpbmcpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFmcmFtZSkge1xuICAgICAgICAgICAgZnJhbWUgPSBfdGhpcy5xdWV1ZS5yZWFkKCk7XG4gICAgICAgICAgICBmcmFtZU9mZnNldCA9IDA7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJ1ZmZlck9mZnNldCA9IDA7XG4gICAgICAgICAgd2hpbGUgKGZyYW1lICYmIGJ1ZmZlck9mZnNldCA8IGJ1ZmZlci5sZW5ndGgpIHtcbiAgICAgICAgICAgIG1heCA9IE1hdGgubWluKGZyYW1lLmxlbmd0aCAtIGZyYW1lT2Zmc2V0LCBidWZmZXIubGVuZ3RoIC0gYnVmZmVyT2Zmc2V0KTtcbiAgICAgICAgICAgIGZvciAoaSA9IF9pID0gMDsgX2kgPCBtYXg7IGkgPSBfaSArPSAxKSB7XG4gICAgICAgICAgICAgIGJ1ZmZlcltidWZmZXJPZmZzZXQrK10gPSBmcmFtZVtmcmFtZU9mZnNldCsrXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChmcmFtZU9mZnNldCA9PT0gZnJhbWUubGVuZ3RoKSB7XG4gICAgICAgICAgICAgIGZyYW1lID0gX3RoaXMucXVldWUucmVhZCgpO1xuICAgICAgICAgICAgICBmcmFtZU9mZnNldCA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIF9yZWYgPSBfdGhpcy5maWx0ZXJzO1xuICAgICAgICAgIGZvciAoX2ogPSAwLCBfbGVuID0gX3JlZi5sZW5ndGg7IF9qIDwgX2xlbjsgX2orKykge1xuICAgICAgICAgICAgZmlsdGVyID0gX3JlZltfal07XG4gICAgICAgICAgICBmaWx0ZXIucHJvY2VzcyhidWZmZXIpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIWZyYW1lKSB7XG4gICAgICAgICAgICBpZiAoX3RoaXMucXVldWUuZW5kZWQpIHtcbiAgICAgICAgICAgICAgX3RoaXMuY3VycmVudFRpbWUgPSBfdGhpcy5kdXJhdGlvbjtcbiAgICAgICAgICAgICAgX3RoaXMuZW1pdCgncHJvZ3Jlc3MnLCBfdGhpcy5jdXJyZW50VGltZSk7XG4gICAgICAgICAgICAgIF90aGlzLmVtaXQoJ2VuZCcpO1xuICAgICAgICAgICAgICBfdGhpcy5zdG9wKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBfdGhpcy5kZXZpY2Uuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpO1xuICAgICAgdGhpcy5kZXZpY2Uub24oJ3JlZmlsbCcsIHRoaXMucmVmaWxsKTtcbiAgICAgIGlmICh0aGlzLnBsYXlpbmcpIHtcbiAgICAgICAgdGhpcy5kZXZpY2Uuc3RhcnQoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmVtaXQoJ3JlYWR5Jyk7XG4gICAgfTtcblxuICAgIFBsYXllci5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIF9yZWYsIF9yZWYxO1xuICAgICAgdGhpcy5zdG9wKCk7XG4gICAgICBpZiAoKF9yZWYgPSB0aGlzLmRldmljZSkgIT0gbnVsbCkge1xuICAgICAgICBfcmVmLm9mZigpO1xuICAgICAgfVxuICAgICAgaWYgKChfcmVmMSA9IHRoaXMuYXNzZXQpICE9IG51bGwpIHtcbiAgICAgICAgX3JlZjEuZGVzdHJveSgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMub2ZmKCk7XG4gICAgfTtcblxuICAgIHJldHVybiBQbGF5ZXI7XG5cbiAgfSkoRXZlbnRFbWl0dGVyKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IFBsYXllcjtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS43LjFcbihmdW5jdGlvbigpIHtcbiAgdmFyIEV2ZW50RW1pdHRlciwgUXVldWUsXG4gICAgX19iaW5kID0gZnVuY3Rpb24oZm4sIG1lKXsgcmV0dXJuIGZ1bmN0aW9uKCl7IHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTsgfTsgfSxcbiAgICBfX2hhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgICBfX2V4dGVuZHMgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKF9faGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfTtcblxuICBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuL2NvcmUvZXZlbnRzJyk7XG5cbiAgUXVldWUgPSAoZnVuY3Rpb24oX3N1cGVyKSB7XG4gICAgX19leHRlbmRzKFF1ZXVlLCBfc3VwZXIpO1xuXG4gICAgZnVuY3Rpb24gUXVldWUoYXNzZXQpIHtcbiAgICAgIHRoaXMuYXNzZXQgPSBhc3NldDtcbiAgICAgIHRoaXMud3JpdGUgPSBfX2JpbmQodGhpcy53cml0ZSwgdGhpcyk7XG4gICAgICB0aGlzLnJlYWR5TWFyayA9IDY0O1xuICAgICAgdGhpcy5maW5pc2hlZCA9IGZhbHNlO1xuICAgICAgdGhpcy5idWZmZXJpbmcgPSB0cnVlO1xuICAgICAgdGhpcy5lbmRlZCA9IGZhbHNlO1xuICAgICAgdGhpcy5idWZmZXJzID0gW107XG4gICAgICB0aGlzLmFzc2V0Lm9uKCdkYXRhJywgdGhpcy53cml0ZSk7XG4gICAgICB0aGlzLmFzc2V0Lm9uKCdlbmQnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHJldHVybiBfdGhpcy5lbmRlZCA9IHRydWU7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLmFzc2V0LmRlY29kZVBhY2tldCgpO1xuICAgIH1cblxuICAgIFF1ZXVlLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgaWYgKGJ1ZmZlcikge1xuICAgICAgICB0aGlzLmJ1ZmZlcnMucHVzaChidWZmZXIpO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuYnVmZmVyaW5nKSB7XG4gICAgICAgIGlmICh0aGlzLmJ1ZmZlcnMubGVuZ3RoID49IHRoaXMucmVhZHlNYXJrIHx8IHRoaXMuZW5kZWQpIHtcbiAgICAgICAgICB0aGlzLmJ1ZmZlcmluZyA9IGZhbHNlO1xuICAgICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ3JlYWR5Jyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuYXNzZXQuZGVjb2RlUGFja2V0KCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgUXVldWUucHJvdG90eXBlLnJlYWQgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0aGlzLmJ1ZmZlcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgdGhpcy5hc3NldC5kZWNvZGVQYWNrZXQoKTtcbiAgICAgIHJldHVybiB0aGlzLmJ1ZmZlcnMuc2hpZnQoKTtcbiAgICB9O1xuXG4gICAgUXVldWUucHJvdG90eXBlLnJlc2V0ID0gZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLmJ1ZmZlcnMubGVuZ3RoID0gMDtcbiAgICAgIHRoaXMuYnVmZmVyaW5nID0gdHJ1ZTtcbiAgICAgIHJldHVybiB0aGlzLmFzc2V0LmRlY29kZVBhY2tldCgpO1xuICAgIH07XG5cbiAgICByZXR1cm4gUXVldWU7XG5cbiAgfSkoRXZlbnRFbWl0dGVyKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IFF1ZXVlO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiRXZlbnRFbWl0dGVyID0gcmVxdWlyZSAnLi4vLi4vY29yZS9ldmVudHMnXG5BVkJ1ZmZlciA9IHJlcXVpcmUgJy4uLy4uL2NvcmUvYnVmZmVyJ1xuXG5jbGFzcyBGaWxlU291cmNlIGV4dGVuZHMgRXZlbnRFbWl0dGVyXG4gICAgY29uc3RydWN0b3I6IChAZmlsZSkgLT5cbiAgICAgICAgaWYgbm90IEZpbGVSZWFkZXI/XG4gICAgICAgICAgICByZXR1cm4gQGVtaXQgJ2Vycm9yJywgJ1RoaXMgYnJvd3NlciBkb2VzIG5vdCBoYXZlIEZpbGVSZWFkZXIgc3VwcG9ydC4nXG4gICAgICAgIFxuICAgICAgICBAb2Zmc2V0ID0gMFxuICAgICAgICBAbGVuZ3RoID0gQGZpbGUuc2l6ZVxuICAgICAgICBAY2h1bmtTaXplID0gMSA8PCAyMFxuICAgICAgICBAZmlsZVtAc2xpY2UgPSAnc2xpY2UnXSBvciBAZmlsZVtAc2xpY2UgPSAnd2Via2l0U2xpY2UnXSBvciBAZmlsZVtAc2xpY2UgPSAnbW96U2xpY2UnXVxuICAgICAgICAgICAgXG4gICAgc3RhcnQ6IC0+XG4gICAgICAgIGlmIEByZWFkZXJcbiAgICAgICAgICAgIHJldHVybiBAbG9vcCgpIHVubGVzcyBAYWN0aXZlXG4gICAgICAgIFxuICAgICAgICBAcmVhZGVyID0gbmV3IEZpbGVSZWFkZXJcbiAgICAgICAgQGFjdGl2ZSA9IHRydWVcbiAgICAgICAgXG4gICAgICAgIEByZWFkZXIub25sb2FkID0gKGUpID0+XG4gICAgICAgICAgICBidWYgPSBuZXcgQVZCdWZmZXIobmV3IFVpbnQ4QXJyYXkoZS50YXJnZXQucmVzdWx0KSlcbiAgICAgICAgICAgIEBvZmZzZXQgKz0gYnVmLmxlbmd0aFxuICAgICAgICBcbiAgICAgICAgICAgIEBlbWl0ICdkYXRhJywgYnVmICAgXG4gICAgICAgICAgICBAYWN0aXZlID0gZmFsc2UgICAgIFxuICAgICAgICAgICAgQGxvb3AoKSBpZiBAb2Zmc2V0IDwgQGxlbmd0aFxuICAgICAgICBcbiAgICAgICAgQHJlYWRlci5vbmxvYWRlbmQgPSA9PlxuICAgICAgICAgICAgaWYgQG9mZnNldCBpcyBAbGVuZ3RoXG4gICAgICAgICAgICAgICAgQGVtaXQgJ2VuZCdcbiAgICAgICAgICAgICAgICBAcmVhZGVyID0gbnVsbFxuICAgICAgICBcbiAgICAgICAgQHJlYWRlci5vbmVycm9yID0gKGUpID0+XG4gICAgICAgICAgICBAZW1pdCAnZXJyb3InLCBlXG4gICAgICAgIFxuICAgICAgICBAcmVhZGVyLm9ucHJvZ3Jlc3MgPSAoZSkgPT5cbiAgICAgICAgICAgIEBlbWl0ICdwcm9ncmVzcycsIChAb2Zmc2V0ICsgZS5sb2FkZWQpIC8gQGxlbmd0aCAqIDEwMFxuICAgICAgICBcbiAgICAgICAgQGxvb3AoKVxuICAgICAgICBcbiAgICBsb29wOiAtPlxuICAgICAgICBAYWN0aXZlID0gdHJ1ZVxuICAgICAgICBlbmRQb3MgPSBNYXRoLm1pbihAb2Zmc2V0ICsgQGNodW5rU2l6ZSwgQGxlbmd0aClcbiAgICAgICAgXG4gICAgICAgIGJsb2IgPSBAZmlsZVtAc2xpY2VdKEBvZmZzZXQsIGVuZFBvcylcbiAgICAgICAgQHJlYWRlci5yZWFkQXNBcnJheUJ1ZmZlcihibG9iKVxuICAgICAgICBcbiAgICBwYXVzZTogLT5cbiAgICAgICAgQGFjdGl2ZSA9IGZhbHNlXG4gICAgICAgIHRyeVxuICAgICAgICAgIEByZWFkZXI/LmFib3J0KClcbiAgICAgICAgXG4gICAgcmVzZXQ6IC0+XG4gICAgICAgIEBwYXVzZSgpXG4gICAgICAgIEBvZmZzZXQgPSAwXG5cbm1vZHVsZS5leHBvcnRzID0gRmlsZVNvdXJjZVxuIiwiRXZlbnRFbWl0dGVyID0gcmVxdWlyZSAnLi4vLi4vY29yZS9ldmVudHMnXG5BVkJ1ZmZlciA9IHJlcXVpcmUgJy4uLy4uL2NvcmUvYnVmZmVyJ1xuXG5jbGFzcyBIVFRQU291cmNlIGV4dGVuZHMgRXZlbnRFbWl0dGVyXG4gICAgY29uc3RydWN0b3I6IChAdXJsLCBAb3B0cyA9IHt9KSAtPlxuICAgICAgICBAY2h1bmtTaXplID0gMSA8PCAyMFxuICAgICAgICBAaW5mbGlnaHQgPSBmYWxzZVxuICAgICAgICBpZiBAb3B0cy5sZW5ndGhcbiAgICAgICAgICAgIEBsZW5ndGggPSBAb3B0cy5sZW5ndGhcbiAgICAgICAgQHJlc2V0KClcbiAgICAgICAgXG4gICAgc3RhcnQ6IC0+XG4gICAgICAgIGlmIEBsZW5ndGhcbiAgICAgICAgICAgIHJldHVybiBAbG9vcCgpIHVubGVzcyBAaW5mbGlnaHRcbiAgICAgICAgXG4gICAgICAgIEBpbmZsaWdodCA9IHRydWVcbiAgICAgICAgQHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpXG4gICAgICAgIFxuICAgICAgICBAeGhyLm9ubG9hZCA9IChldmVudCkgPT5cbiAgICAgICAgICAgIEBsZW5ndGggPSBwYXJzZUludCBAeGhyLmdldFJlc3BvbnNlSGVhZGVyKFwiQ29udGVudC1MZW5ndGhcIikgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICBAaW5mbGlnaHQgPSBmYWxzZVxuICAgICAgICAgICAgQGxvb3AoKVxuICAgICAgICBcbiAgICAgICAgQHhoci5vbmVycm9yID0gKGVycikgPT5cbiAgICAgICAgICAgIEBwYXVzZSgpXG4gICAgICAgICAgICBAZW1pdCAnZXJyb3InLCBlcnJcbiAgICAgICAgICAgIFxuICAgICAgICBAeGhyLm9uYWJvcnQgPSAoZXZlbnQpID0+XG4gICAgICAgICAgICBAaW5mbGlnaHQgPSBmYWxzZVxuICAgICAgICBcbiAgICAgICAgQHhoci5vcGVuKFwiSEVBRFwiLCBAdXJsLCB0cnVlKVxuICAgICAgICBAeGhyLnNlbmQobnVsbClcbiAgICAgICAgXG4gICAgbG9vcDogLT5cbiAgICAgICAgaWYgQGluZmxpZ2h0IG9yIG5vdCBAbGVuZ3RoXG4gICAgICAgICAgICByZXR1cm4gQGVtaXQgJ2Vycm9yJywgJ1NvbWV0aGluZyBpcyB3cm9uZyBpbiBIVFRQU291cmNlLmxvb3AnXG4gICAgICAgICAgICBcbiAgICAgICAgQGluZmxpZ2h0ID0gdHJ1ZVxuICAgICAgICBAeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KClcbiAgICAgICAgXG4gICAgICAgIEB4aHIub25sb2FkID0gKGV2ZW50KSA9PlxuICAgICAgICAgICAgaWYgQHhoci5yZXNwb25zZVxuICAgICAgICAgICAgICAgIGJ1ZiA9IG5ldyBVaW50OEFycmF5KEB4aHIucmVzcG9uc2UpXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgdHh0ID0gQHhoci5yZXNwb25zZVRleHRcbiAgICAgICAgICAgICAgICBidWYgPSBuZXcgVWludDhBcnJheSh0eHQubGVuZ3RoKVxuICAgICAgICAgICAgICAgIGZvciBpIGluIFswLi4udHh0Lmxlbmd0aF1cbiAgICAgICAgICAgICAgICAgICAgYnVmW2ldID0gdHh0LmNoYXJDb2RlQXQoaSkgJiAweGZmXG5cbiAgICAgICAgICAgIGJ1ZmZlciA9IG5ldyBBVkJ1ZmZlcihidWYpXG4gICAgICAgICAgICBAb2Zmc2V0ICs9IGJ1ZmZlci5sZW5ndGhcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgQGVtaXQgJ2RhdGEnLCBidWZmZXJcbiAgICAgICAgICAgIEBlbWl0ICdlbmQnIGlmIEBvZmZzZXQgPj0gQGxlbmd0aFxuXG4gICAgICAgICAgICBAaW5mbGlnaHQgPSBmYWxzZVxuICAgICAgICAgICAgQGxvb3AoKSB1bmxlc3MgQG9mZnNldCA+PSBAbGVuZ3RoXG4gICAgICAgICAgICBcbiAgICAgICAgQHhoci5vbnByb2dyZXNzID0gKGV2ZW50KSA9PlxuICAgICAgICAgICAgQGVtaXQgJ3Byb2dyZXNzJywgKEBvZmZzZXQgKyBldmVudC5sb2FkZWQpIC8gQGxlbmd0aCAqIDEwMFxuXG4gICAgICAgIEB4aHIub25lcnJvciA9IChlcnIpID0+XG4gICAgICAgICAgICBAZW1pdCAnZXJyb3InLCBlcnJcbiAgICAgICAgICAgIEBwYXVzZSgpXG5cbiAgICAgICAgQHhoci5vbmFib3J0ID0gKGV2ZW50KSA9PlxuICAgICAgICAgICAgQGluZmxpZ2h0ID0gZmFsc2VcblxuICAgICAgICBAeGhyLm9wZW4oXCJHRVRcIiwgQHVybCwgdHJ1ZSlcbiAgICAgICAgQHhoci5yZXNwb25zZVR5cGUgPSBcImFycmF5YnVmZmVyXCJcblxuICAgICAgICBlbmRQb3MgPSBNYXRoLm1pbihAb2Zmc2V0ICsgQGNodW5rU2l6ZSwgQGxlbmd0aCAtIDEpXG4gICAgICAgIEB4aHIuc2V0UmVxdWVzdEhlYWRlcihcIklmLU5vbmUtTWF0Y2hcIiwgXCJ3ZWJraXQtbm8tY2FjaGVcIilcbiAgICAgICAgQHhoci5zZXRSZXF1ZXN0SGVhZGVyKFwiUmFuZ2VcIiwgXCJieXRlcz0je0BvZmZzZXR9LSN7ZW5kUG9zfVwiKVxuICAgICAgICBAeGhyLm92ZXJyaWRlTWltZVR5cGUoJ3RleHQvcGxhaW47IGNoYXJzZXQ9eC11c2VyLWRlZmluZWQnKVxuICAgICAgICBAeGhyLnNlbmQobnVsbClcbiAgICAgICAgXG4gICAgcGF1c2U6IC0+XG4gICAgICAgIEBpbmZsaWdodCA9IGZhbHNlXG4gICAgICAgIEB4aHI/LmFib3J0KClcbiAgICAgICAgXG4gICAgcmVzZXQ6IC0+XG4gICAgICAgIEBwYXVzZSgpXG4gICAgICAgIEBvZmZzZXQgPSAwXG4gICAgICAgIFxubW9kdWxlLmV4cG9ydHMgPSBIVFRQU291cmNlXG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuNy4xXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBBVkJ1ZmZlciwgQnVmZmVyTGlzdCwgQnVmZmVyU291cmNlLCBFdmVudEVtaXR0ZXIsXG4gICAgX19iaW5kID0gZnVuY3Rpb24oZm4sIG1lKXsgcmV0dXJuIGZ1bmN0aW9uKCl7IHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTsgfTsgfSxcbiAgICBfX2hhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgICBfX2V4dGVuZHMgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKF9faGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfTtcblxuICBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuLi9jb3JlL2V2ZW50cycpO1xuXG4gIEJ1ZmZlckxpc3QgPSByZXF1aXJlKCcuLi9jb3JlL2J1ZmZlcmxpc3QnKTtcblxuICBBVkJ1ZmZlciA9IHJlcXVpcmUoJy4uL2NvcmUvYnVmZmVyJyk7XG5cbiAgQnVmZmVyU291cmNlID0gKGZ1bmN0aW9uKF9zdXBlcikge1xuICAgIHZhciBjbGVhckltbWVkaWF0ZSwgc2V0SW1tZWRpYXRlO1xuXG4gICAgX19leHRlbmRzKEJ1ZmZlclNvdXJjZSwgX3N1cGVyKTtcblxuICAgIGZ1bmN0aW9uIEJ1ZmZlclNvdXJjZShpbnB1dCkge1xuICAgICAgdGhpcy5sb29wID0gX19iaW5kKHRoaXMubG9vcCwgdGhpcyk7XG4gICAgICBpZiAoaW5wdXQgaW5zdGFuY2VvZiBCdWZmZXJMaXN0KSB7XG4gICAgICAgIHRoaXMubGlzdCA9IGlucHV0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5saXN0ID0gbmV3IEJ1ZmZlckxpc3Q7XG4gICAgICAgIHRoaXMubGlzdC5hcHBlbmQobmV3IEFWQnVmZmVyKGlucHV0KSk7XG4gICAgICB9XG4gICAgICB0aGlzLnBhdXNlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgc2V0SW1tZWRpYXRlID0gZ2xvYmFsLnNldEltbWVkaWF0ZSB8fCBmdW5jdGlvbihmbikge1xuICAgICAgcmV0dXJuIGdsb2JhbC5zZXRUaW1lb3V0KGZuLCAwKTtcbiAgICB9O1xuXG4gICAgY2xlYXJJbW1lZGlhdGUgPSBnbG9iYWwuY2xlYXJJbW1lZGlhdGUgfHwgZnVuY3Rpb24odGltZXIpIHtcbiAgICAgIHJldHVybiBnbG9iYWwuY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICB9O1xuXG4gICAgQnVmZmVyU291cmNlLnByb3RvdHlwZS5zdGFydCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5wYXVzZWQgPSBmYWxzZTtcbiAgICAgIHJldHVybiB0aGlzLl90aW1lciA9IHNldEltbWVkaWF0ZSh0aGlzLmxvb3ApO1xuICAgIH07XG5cbiAgICBCdWZmZXJTb3VyY2UucHJvdG90eXBlLmxvb3AgPSBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuZW1pdCgncHJvZ3Jlc3MnLCAodGhpcy5saXN0Lm51bUJ1ZmZlcnMgLSB0aGlzLmxpc3QuYXZhaWxhYmxlQnVmZmVycyArIDEpIC8gdGhpcy5saXN0Lm51bUJ1ZmZlcnMgKiAxMDAgfCAwKTtcbiAgICAgIHRoaXMuZW1pdCgnZGF0YScsIHRoaXMubGlzdC5maXJzdCk7XG4gICAgICBpZiAodGhpcy5saXN0LmFkdmFuY2UoKSkge1xuICAgICAgICByZXR1cm4gc2V0SW1tZWRpYXRlKHRoaXMubG9vcCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlbmQnKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgQnVmZmVyU291cmNlLnByb3RvdHlwZS5wYXVzZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgY2xlYXJJbW1lZGlhdGUodGhpcy5fdGltZXIpO1xuICAgICAgcmV0dXJuIHRoaXMucGF1c2VkID0gdHJ1ZTtcbiAgICB9O1xuXG4gICAgQnVmZmVyU291cmNlLnByb3RvdHlwZS5yZXNldCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5wYXVzZSgpO1xuICAgICAgcmV0dXJuIHRoaXMubGlzdC5yZXdpbmQoKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIEJ1ZmZlclNvdXJjZTtcblxuICB9KShFdmVudEVtaXR0ZXIpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gQnVmZmVyU291cmNlO1xuXG59KS5jYWxsKHRoaXMpO1xuIl19