@caminojs-nikos/caminojs
Version:
Camino Platform JS Library
286 lines • 39.6 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.StandardAmountInput = exports.StandardTransferableInput = exports.StandardParseableInput = exports.Input = exports.BaseInputComparator = void 0;
/**
* @packageDocumentation
* @module Common-Inputs
*/
const buffer_1 = require("buffer/");
const bintools_1 = __importDefault(require("../utils/bintools"));
const bn_js_1 = __importDefault(require("bn.js"));
const credentials_1 = require("./credentials");
const serialization_1 = require("../utils/serialization");
/**
* @ignore
*/
const bintools = bintools_1.default.getInstance();
const serialization = serialization_1.Serialization.getInstance();
const BaseInputComparator = () => (a, b) => {
const aoutid = buffer_1.Buffer.alloc(4);
aoutid.writeUInt32BE(a.getInputID(), 0);
const abuff = a.toBuffer();
const boutid = buffer_1.Buffer.alloc(4);
boutid.writeUInt32BE(b.getInputID(), 0);
const bbuff = b.toBuffer();
const asort = buffer_1.Buffer.concat([aoutid, abuff], aoutid.length + abuff.length);
const bsort = buffer_1.Buffer.concat([boutid, bbuff], boutid.length + bbuff.length);
return buffer_1.Buffer.compare(asort, bsort);
};
exports.BaseInputComparator = BaseInputComparator;
class Input extends serialization_1.Serializable {
constructor() {
super(...arguments);
this._typeName = "Input";
this._typeID = undefined;
this.sigCount = buffer_1.Buffer.alloc(4);
this.sigIdxs = []; // idxs of signers from utxo
/**
* Returns the array of [[SigIdx]] for this [[Input]]
*/
this.getSigIdxs = () => this.sigIdxs;
/**
* Creates and adds a [[SigIdx]] to the [[Input]].
*
* @param addressIdx The index of the address to reference in the signatures
* @param address The address of the source of the signature
*/
this.addSignatureIdx = (addressIdx, address) => {
const sigidx = new credentials_1.SigIdx();
const b = buffer_1.Buffer.alloc(4);
b.writeUInt32BE(addressIdx, 0);
sigidx.fromBuffer(b);
sigidx.setSource(address);
this.sigIdxs.push(sigidx);
this.sigCount.writeUInt32BE(this.sigIdxs.length, 0);
};
}
serialize(encoding = "hex") {
let fields = super.serialize(encoding);
return Object.assign(Object.assign({}, fields), { sigIdxs: this.sigIdxs.map((s) => s.serialize(encoding)) });
}
deserialize(fields, encoding = "hex") {
super.deserialize(fields, encoding);
this.sigIdxs = fields["sigIdxs"].map((s) => {
let sidx = new credentials_1.SigIdx();
sidx.deserialize(s, encoding);
return sidx;
});
this.sigCount.writeUInt32BE(this.sigIdxs.length, 0);
}
getInput() {
return this;
}
fromBuffer(bytes, offset = 0) {
this.sigCount = bintools.copyFrom(bytes, offset, offset + 4);
offset += 4;
const sigCount = this.sigCount.readUInt32BE(0);
this.sigIdxs = [];
for (let i = 0; i < sigCount; i++) {
const sigidx = new credentials_1.SigIdx();
const sigbuff = bintools.copyFrom(bytes, offset, offset + 4);
sigidx.fromBuffer(sigbuff);
offset += 4;
this.sigIdxs.push(sigidx);
}
return offset;
}
toBuffer() {
this.sigCount.writeUInt32BE(this.sigIdxs.length, 0);
let bsize = this.sigCount.length;
const barr = [this.sigCount];
for (let i = 0; i < this.sigIdxs.length; i++) {
const b = this.sigIdxs[`${i}`].toBuffer();
barr.push(b);
bsize += b.length;
}
return buffer_1.Buffer.concat(barr, bsize);
}
/**
* Returns a base-58 representation of the [[Input]].
*/
toString() {
return bintools.bufferToB58(this.toBuffer());
}
}
exports.Input = Input;
class StandardParseableInput extends serialization_1.Serializable {
serialize(encoding = "hex") {
let fields = super.serialize(encoding);
return Object.assign(Object.assign({}, fields), { input: this.input.serialize(encoding) });
}
addSignatureIdx(addressIdx, address) {
this.input.addSignatureIdx(addressIdx, address);
}
toBuffer() {
const inbuff = this.input.toBuffer();
const inid = buffer_1.Buffer.alloc(4);
inid.writeUInt32BE(this.input.getInputID(), 0);
const barr = [inid, inbuff];
return buffer_1.Buffer.concat(barr, inid.length + inbuff.length);
}
/**
* Class representing an [[StandardParseableInput]] for a transaction.
*
* @param input A number representing the InputID of the [[StandardParseableInput]]
*/
constructor(input = undefined) {
super();
this._typeName = "StandardParseableInput";
this._typeID = undefined;
this.getInput = () => this.input;
this.getSigIdxs = () => {
return this.input.getSigIdxs();
};
this.input = input;
}
}
exports.StandardParseableInput = StandardParseableInput;
/**
* Returns a function used to sort an array of [[StandardParseableInput]]s
*/
StandardParseableInput.comparator = () => (a, b) => {
const sorta = a.toBuffer();
const sortb = b.toBuffer();
return buffer_1.Buffer.compare(sorta, sortb);
};
class StandardTransferableInput extends StandardParseableInput {
serialize(encoding = "hex") {
let fields = super.serialize(encoding);
return Object.assign(Object.assign({}, fields), { txid: serialization.encoder(this.txid, encoding, "Buffer", "cb58"), outputidx: serialization.encoder(this.outputidx, encoding, "Buffer", "decimalString"), assetID: serialization.encoder(this.assetID, encoding, "Buffer", "cb58") });
}
deserialize(fields, encoding = "hex") {
super.deserialize(fields, encoding);
this.txid = serialization.decoder(fields["txid"], encoding, "cb58", "Buffer", 32);
this.outputidx = serialization.decoder(fields["outputidx"], encoding, "decimalString", "Buffer", 4);
this.assetID = serialization.decoder(fields["assetID"], encoding, "cb58", "Buffer", 32);
//input deserialization must be implmented in child classes
}
/**
* Returns a {@link https://github.com/feross/buffer|Buffer} representation of the [[StandardTransferableInput]].
*/
toBuffer() {
const parseableBuff = super.toBuffer();
const bsize = this.txid.length +
this.outputidx.length +
this.assetID.length +
parseableBuff.length;
const barr = [
this.txid,
this.outputidx,
this.assetID,
parseableBuff
];
const buff = buffer_1.Buffer.concat(barr, bsize);
return buff;
}
/**
* Returns a base-58 representation of the [[StandardTransferableInput]].
*/
toString() {
/* istanbul ignore next */
return bintools.bufferToB58(this.toBuffer());
}
/**
* Class representing an [[StandardTransferableInput]] for a transaction.
*
* @param txid A {@link https://github.com/feross/buffer|Buffer} containing the transaction ID of the referenced UTXO
* @param outputidx A {@link https://github.com/feross/buffer|Buffer} containing the index of the output in the transaction consumed in the [[StandardTransferableInput]]
* @param assetID A {@link https://github.com/feross/buffer|Buffer} representing the assetID of the [[Input]]
* @param input An [[Input]] to be made transferable
*/
constructor(txid = undefined, outputidx = undefined, assetID = undefined, input = undefined) {
super();
this._typeName = "StandardTransferableInput";
this._typeID = undefined;
this.txid = buffer_1.Buffer.alloc(32);
this.outputidx = buffer_1.Buffer.alloc(4);
this.assetID = buffer_1.Buffer.alloc(32);
/**
* Returns a {@link https://github.com/feross/buffer|Buffer} of the TxID.
*/
this.getTxID = () => this.txid;
/**
* Returns a {@link https://github.com/feross/buffer|Buffer} of the OutputIdx.
*/
this.getOutputIdx = () => this.outputidx;
/**
* Returns a base-58 string representation of the UTXOID this [[StandardTransferableInput]] references.
*/
this.getUTXOID = () => bintools.bufferToB58(buffer_1.Buffer.concat([this.txid, this.outputidx]));
/**
* Returns the input.
*/
this.getInput = () => this.input;
/**
* Returns the assetID of the input.
*/
this.getAssetID = () => this.assetID;
if (typeof txid !== undefined &&
typeof outputidx !== undefined &&
typeof assetID !== undefined &&
input !== undefined) {
this.input = input;
this.txid = txid;
this.outputidx = outputidx;
this.assetID = assetID;
}
}
}
exports.StandardTransferableInput = StandardTransferableInput;
/**
* An [[Input]] class which specifies a token amount .
*/
class StandardAmountInput extends Input {
serialize(encoding = "hex") {
let fields = super.serialize(encoding);
return Object.assign(Object.assign({}, fields), { amount: serialization.encoder(this.amount, encoding, "Buffer", "decimalString", 8) });
}
deserialize(fields, encoding = "hex") {
super.deserialize(fields, encoding);
this.amount = serialization.decoder(fields["amount"], encoding, "decimalString", "Buffer", 8);
this.amountValue = bintools.fromBufferToBN(this.amount);
}
/**
* Popuates the instance from a {@link https://github.com/feross/buffer|Buffer} representing the [[AmountInput]] and returns the size of the input.
*/
fromBuffer(bytes, offset = 0) {
this.amount = bintools.copyFrom(bytes, offset, offset + 8);
this.amountValue = bintools.fromBufferToBN(this.amount);
offset += 8;
return super.fromBuffer(bytes, offset);
}
/**
* Returns the buffer representing the [[AmountInput]] instance.
*/
toBuffer() {
const superbuff = super.toBuffer();
const bsize = this.amount.length + superbuff.length;
const barr = [this.amount, superbuff];
return buffer_1.Buffer.concat(barr, bsize);
}
/**
* An [[AmountInput]] class which issues a payment on an assetID.
*
* @param amount A {@link https://github.com/indutny/bn.js/|BN} representing the amount in the input
*/
constructor(amount = undefined) {
super();
this._typeName = "StandardAmountInput";
this._typeID = undefined;
this.amount = buffer_1.Buffer.alloc(8);
this.amountValue = new bn_js_1.default(0);
/**
* Returns the amount as a {@link https://github.com/indutny/bn.js/|BN}.
*/
this.getAmount = () => this.amountValue.clone();
if (amount) {
this.amountValue = amount.clone();
this.amount = bintools.fromBNToBuffer(amount, 8);
}
}
}
exports.StandardAmountInput = StandardAmountInput;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29tbW9uL2lucHV0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBOzs7R0FHRztBQUNILG9DQUFnQztBQUNoQyxpRUFBd0M7QUFDeEMsa0RBQXNCO0FBQ3RCLCtDQUFzQztBQUN0QywwREFJK0I7QUFFL0I7O0dBRUc7QUFDSCxNQUFNLFFBQVEsR0FBYSxrQkFBUSxDQUFDLFdBQVcsRUFBRSxDQUFBO0FBQ2pELE1BQU0sYUFBYSxHQUFrQiw2QkFBYSxDQUFDLFdBQVcsRUFBRSxDQUFBO0FBb0J6RCxNQUFNLG1CQUFtQixHQUM5QixHQUFpRCxFQUFFLENBQ25ELENBQUMsQ0FBWSxFQUFFLENBQVksRUFBYyxFQUFFO0lBQ3pDLE1BQU0sTUFBTSxHQUFXLGVBQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUE7SUFDdEMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUE7SUFDdkMsTUFBTSxLQUFLLEdBQVcsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFBO0lBRWxDLE1BQU0sTUFBTSxHQUFXLGVBQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUE7SUFDdEMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUE7SUFDdkMsTUFBTSxLQUFLLEdBQVcsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFBO0lBRWxDLE1BQU0sS0FBSyxHQUFXLGVBQU0sQ0FBQyxNQUFNLENBQ2pDLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxFQUNmLE1BQU0sQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FDN0IsQ0FBQTtJQUNELE1BQU0sS0FBSyxHQUFXLGVBQU0sQ0FBQyxNQUFNLENBQ2pDLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxFQUNmLE1BQU0s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VyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFBO1FBQzNELE1BQU0sSUFBSSxHQUFhLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQTtRQUMvQyxPQUFPLGVBQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFBO0lBQ25DLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsWUFBWSxTQUFhLFNBQVM7UUFDaEMsS0FBSyxFQUFFLENBQUE7UUE5REMsY0FBUyxHQUFHLHFCQUFxQixDQUFBO1FBQ2pDLFlBQU8sR0FBRyxTQUFTLENBQUE7UUEyQm5CLFdBQU0sR0FBVyxlQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBQ2hDLGdCQUFXLEdBQU8sSUFBSSxlQUFFLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFFckM7O1dBRUc7UUFDSCxjQUFTLEdBQUcsR0FBTyxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsQ0FBQTtRQTZCNUMsSUFBSSxNQUFNLEVBQUU7WUFDVixJQUFJLENBQUMsV0FBVyxHQUFHLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQTtZQUNqQyxJQUFJLENBQUMsTUFBTSxHQUFHLFFBQVEsQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFBO1NBQ2pEO0lBQ0gsQ0FBQztDQUNGO0FBckVELGtEQXFFQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG4gKiBAbW9kdWxlIENvbW1vbi1JbnB1dHNcbiAqL1xuaW1wb3J0IHsgQnVmZmVyIH0gZnJvbSBcImJ1ZmZlci9cIlxuaW1wb3J0IEJpblRvb2xzIGZyb20gXCIuLi91dGlscy9iaW50b29sc1wiXG5pbXBvcnQgQk4gZnJvbSBcImJuLmpzXCJcbmltcG9ydCB7IFNpZ0lkeCB9IGZyb20gXCIuL2NyZWRlbnRpYWxzXCJcbmltcG9ydCB7XG4gIFNlcmlhbGl6YWJsZSxcbiAgU2VyaWFsaXphdGlvbixcbiAgU2VyaWFsaXplZEVuY29kaW5nXG59IGZyb20gXCIuLi91dGlscy9zZXJpYWxpemF0aW9uXCJcblxuLyoqXG4gKiBAaWdub3JlXG4gKi9cbmNvbnN0IGJpbnRvb2xzOiBCaW5Ub29scyA9IEJpblRvb2xzLmdldEluc3RhbmNlKClcbmNvbnN0IHNlcmlhbGl6YXRpb246IFNlcmlhbGl6YXRpb24gPSBTZXJpYWxpemF0aW9uLmdldEluc3RhbmNlKClcblxuZXhwb3J0IGludGVyZmFjZSBCYXNlSW5wdXQge1xuICBnZXRUeXBlSUQoKTogbnVtYmVyXG5cbiAgc2VyaWFsaXplKGVuY29kaW5nOiBTZXJpYWxpemVkRW5jb2RpbmcpOiBvYmplY3RcbiAgZGVzZXJpYWxpemUoZmllbGRzOiBvYmplY3QsIGVuY29kaW5nOiBTZXJpYWxpemVkRW5jb2RpbmcpOiB2b2lkXG4gIGZyb21CdWZmZXIoYnl0ZXM6IEJ1ZmZlciwgb2Zmc2V0OiBudW1iZXIpOiBudW1iZXJcbiAgdG9CdWZmZXIoKTogQnVmZmVyXG5cbiAgZ2V0SW5wdXQoKTogQmFzZUlucHV0XG4gIGdldElucHV0SUQoKTogbnVtYmVyXG4gIGdldENyZWRlbnRpYWxJRCgpOiBudW1iZXJcbiAgYWRkU2lnbmF0dXJlSWR4KGFkZHJlc3NJZHg6IG51bWJlciwgYWRkcmVzczogQnVmZmVyKTogdm9pZFxuICBnZXRTaWdJZHhzKCk6IFNpZ0lkeFtdXG5cbiAgY2xvbmUoKTogdGhpc1xuICBjcmVhdGUoLi4uYXJnczogYW55W10pOiB0aGlzXG59XG5cbmV4cG9ydCBjb25zdCBCYXNlSW5wdXRDb21wYXJhdG9yID1cbiAgKCk6ICgoYTogQmFzZUlucHV0LCBiOiBCYXNlSW5wdXQpID0+IDEgfCAtMSB8IDApID0+XG4gIChhOiBCYXNlSW5wdXQsIGI6IEJhc2VJbnB1dCk6IDEgfCAtMSB8IDAgPT4ge1xuICAgIGNvbnN0IGFvdXRpZDogQnVmZmVyID0gQnVmZmVyLmFsbG9jKDQpXG4gICAgYW91dGlkLndyaXRlVUludDMyQkUoYS5nZXRJbnB1dElEKCksIDApXG4gICAgY29uc3QgYWJ1ZmY6IEJ1ZmZlciA9IGEudG9CdWZmZXIoKVxuXG4gICAgY29uc3QgYm91dGlkOiBCdWZmZXIgPSBCdWZmZXIuYWxsb2MoNClcbiAgICBib3V0aWQud3JpdGVVSW50MzJCRShiLmdldElucHV0SUQoKSwgMClcbiAgICBjb25zdCBiYnVmZjogQnVmZmVyID0gYi50b0J1ZmZlcigpXG5cbiAgICBjb25zdCBhc29ydDogQnVmZmVyID0gQnVmZmVyLmNvbmNhdChcbiAgICAgIFthb3V0aWQsIGFidWZmXSxcbiAgICAgIGFvdXRpZC5sZW5ndGggKyBhYnVmZi5sZW5ndGhcbiAgICApXG4gICAgY29uc3QgYnNvcnQ6IEJ1ZmZlciA9IEJ1ZmZlci5jb25jYXQoXG4gICAgICBbYm91dGlkLCBiYnVmZl0sXG4gICAgICBib3V0aWQubGVuZ3RoICsgYmJ1ZmYubGVuZ3RoXG4gICAgKVxuICAgIHJldHVybiBCdWZmZXIuY29tcGFyZShhc29ydCwgYnNvcnQpIGFzIDEgfCAtMSB8IDBcbiAgfVxuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgSW5wdXQgZXh0ZW5kcyBTZXJpYWxpemFibGUge1xuICBwcm90ZWN0ZWQgX3R5cGVOYW1lID0gXCJJbnB1dFwiXG4gIHByb3RlY3RlZCBfdHlwZUlEID0gdW5kZWZpbmVkXG5cbiAgc2VyaWFsaXplKGVuY29kaW5nOiBTZXJpYWxpemVkRW5jb2RpbmcgPSBcImhleFwiKTogb2JqZWN0IHtcbiAgICBsZXQgZmllbGRzOiBvYmplY3QgPSBzdXBlci5zZXJpYWxpemUoZW5jb2RpbmcpXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmZpZWxkcyxcbiAgICAgIHNpZ0lkeHM6IHRoaXMuc2lnSWR4cy5tYXAoKHMpID0+IHMuc2VyaWFsaXplKGVuY29kaW5nKSlcbiAgICB9XG4gIH1cbiAgZGVzZXJpYWxpemUoZmllbGRzOiBvYmplY3QsIGVuY29kaW5nOiBTZXJpYWxpemVkRW5jb2RpbmcgPSBcImhleFwiKSB7XG4gICAgc3VwZXIuZGVzZXJpYWxpemUoZmllbGRzLCBlbmNvZGluZylcbiAgICB0aGlzLnNpZ0lkeHMgPSBmaWVsZHNbXCJzaWdJZHhzXCJdLm1hcCgoczogb2JqZWN0KSA9PiB7XG4gICAgICBsZXQgc2lkeDogU2lnSWR4ID0gbmV3IFNpZ0lkeCgpXG4gICAgICBzaWR4LmRlc2VyaWFsaXplKHMsIGVuY29kaW5nKVxuICAgICAgcmV0dXJuIHNpZHhcbiAgICB9KVxuICAgIHRoaXMuc2lnQ291bnQud3JpdGVVSW50MzJCRSh0aGlzLnNpZ0lkeHMubGVuZ3RoLCAwKVxuICB9XG5cbiAgcHJvdGVjdGVkIHNpZ0NvdW50OiBCdWZmZXIgPSBCdWZmZXIuYWxsb2MoNClcbiAgcHJvdGVjdGVkIHNpZ0lkeHM6IFNpZ0lkeFtdID0gW10gLy8gaWR4cyBvZiBzaWduZXJzIGZyb20gdXR4b1xuXG4gIGdldElucHV0KCk6IEJhc2VJbnB1dCB7XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIGFic3RyYWN0IGdldElucHV0SUQoKTogbnVtYmVyXG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGFycmF5IG9mIFtbU2lnSWR4XV0gZm9yIHRoaXMgW1tJbnB1dF1dXG4gICAqL1xuICBnZXRTaWdJZHhzID0gKCk6IFNpZ0lkeFtdID0+IHRoaXMuc2lnSWR4c1xuXG4gIGFic3RyYWN0IGdldENyZWRlbnRpYWxJRCgpOiBudW1iZXJcblxuICAvKipcbiAgICogQ3JlYXRlcyBhbmQgYWRkcyBhIFtbU2lnSWR4XV0gdG8gdGhlIFtbSW5wdXRdXS5cbiAgICpcbiAgICogQHBhcmFtIGFkZHJlc3NJZHggVGhlIGluZGV4IG9mIHRoZSBhZGRyZXNzIHRvIHJlZmVyZW5jZSBpbiB0aGUgc2lnbmF0dXJlc1xuICAgKiBAcGFyYW0gYWRkcmVzcyBUaGUgYWRkcmVzcyBvZiB0aGUgc291cmNlIG9mIHRoZSBzaWduYXR1cmVcbiAgICovXG4gIGFkZFNpZ25hdHVyZUlkeCA9IChhZGRyZXNzSWR4OiBudW1iZXIsIGFkZHJlc3M6IEJ1ZmZlcikgPT4ge1xuICAgIGNvbnN0IHNpZ2lkeDogU2lnSWR4ID0gbmV3IFNpZ0lkeCgpXG4gICAgY29uc3QgYjogQnVmZmVyID0gQnVmZmVyLmFsbG9jKDQpXG4gICAgYi53cml0ZVVJbnQzMkJFKGFkZHJlc3NJZHgsIDApXG4gICAgc2lnaWR4LmZyb21CdWZmZXIoYilcbiAgICBzaWdpZHguc2V0U291cmNlKGFkZHJlc3MpXG4gICAgdGhpcy5zaWdJZHhzLnB1c2goc2lnaWR4KVxuICAgIHRoaXMuc2lnQ291bnQud3JpdGVVSW50MzJCRSh0aGlzLnNpZ0lkeHMubGVuZ3RoLCAwKVxuICB9XG5cbiAgZnJvbUJ1ZmZlcihieXRlczogQnVmZmVyLCBvZmZzZXQ6IG51bWJlciA9IDApOiBudW1iZXIge1xuICAgIHRoaXMuc2lnQ291bnQgPSBiaW50b29scy5jb3B5RnJvbShieXRlcywgb2Zmc2V0LCBvZmZzZXQgKyA0KVxuICAgIG9mZnNldCArPSA0XG4gICAgY29uc3Qgc2lnQ291bnQ6IG51bWJlciA9IHRoaXMuc2lnQ291bnQucmVhZFVJbnQzMkJFKDApXG4gICAgdGhpcy5zaWdJZHhzID0gW11cbiAgICBmb3IgKGxldCBpOiBudW1iZXIgPSAwOyBpIDwgc2lnQ291bnQ7IGkrKykge1xuICAgICAgY29uc3Qgc2lnaWR4ID0gbmV3IFNpZ0lkeCgpXG4gICAgICBjb25zdCBzaWdidWZmOiBCdWZmZXIgPSBiaW50b29scy5jb3B5RnJvbShieXRlcywgb2Zmc2V0LCBvZmZzZXQgKyA0KVxuICAgICAgc2lnaWR4LmZyb21CdWZmZXIoc2lnYnVmZilcbiAgICAgIG9mZnNldCArPSA0XG4gICAgICB0aGlzLnNpZ0lkeHMucHVzaChzaWdpZHgpXG4gICAgfVxuICAgIHJldHVybiBvZmZzZXRcbiAgfVxuXG4gIHRvQnVmZmVyKCk6IEJ1ZmZlciB7XG4gICAgdGhpcy5zaWdDb3VudC53cml0ZVVJbnQzMkJFKHRoaXMuc2lnSWR4cy5sZW5ndGgsIDApXG4gICAgbGV0IGJzaXplOiBudW1iZXIgPSB0aGlzLnNpZ0NvdW50Lmxlbmd0aFxuICAgIGNvbnN0IGJhcnI6IEJ1ZmZlcltdID0gW3RoaXMuc2lnQ291bnRdXG4gICAgZm9yIChsZXQgaTogbnVtYmVyID0gMDsgaSA8IHRoaXMuc2lnSWR4cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgYjogQnVmZmVyID0gdGhpcy5zaWdJZHhzW2Ake2l9YF0udG9CdWZmZXIoKVxuICAgICAgYmFyci5wdXNoKGIpXG4gICAgICBic2l6ZSArPSBiLmxlbmd0aFxuICAgIH1cbiAgICByZXR1cm4gQnVmZmVyLmNvbmNhdChiYXJyLCBic2l6ZSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgYmFzZS01OCByZXByZXNlbnRhdGlvbiBvZiB0aGUgW1tJbnB1dF1dLlxuICAgKi9cbiAgdG9TdHJpbmcoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYmludG9vbHMuYnVmZmVyVG9CNTgodGhpcy50b0J1ZmZlcigpKVxuICB9XG5cbiAgYWJzdHJhY3QgY2xvbmUoKTogdGhpc1xuXG4gIGFic3RyYWN0IGNyZWF0ZSguLi5hcmdzOiBhbnlbXSk6IHRoaXNcblxuICBhYnN0cmFjdCBzZWxlY3QoaWQ6IG51bWJlciwgLi4uYXJnczogYW55W10pOiBCYXNlSW5wdXRcbn1cblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFN0YW5kYXJkUGFyc2VhYmxlSW5wdXQgZXh0ZW5kcyBTZXJpYWxpemFibGUge1xuICBwcm90ZWN0ZWQgX3R5cGVOYW1lID0gXCJTdGFuZGFyZFBhcnNlYWJsZUlucHV0XCJcbiAgcHJvdGVjdGVkIF90eXBlSUQgPSB1bmRlZmluZWRcblxuICBzZXJpYWxpemUoZW5jb2Rpbmc6IFNlcmlhbGl6ZWRFbmNvZGluZyA9IFwiaGV4XCIpOiBvYmplY3Qge1xuICAgIGxldCBmaWVsZHM6IG9iamVjdCA9IHN1cGVyLnNlcmlhbGl6ZShlbmNvZGluZylcbiAgICByZXR1cm4ge1xuICAgICAgLi4uZmllbGRzLFxuICAgICAgaW5wdXQ6IHRoaXMuaW5wdXQuc2VyaWFsaXplKGVuY29kaW5nKVxuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBpbnB1dDogQmFzZUlucHV0XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBmdW5jdGlvbiB1c2VkIHRvIHNvcnQgYW4gYXJyYXkgb2YgW1tTdGFuZGFyZFBhcnNlYWJsZUlucHV0XV1zXG4gICAqL1xuICBzdGF0aWMgY29tcGFyYXRvciA9XG4gICAgKCk6ICgoXG4gICAgICBhOiBTdGFuZGFyZFBhcnNlYWJsZUlucHV0LFxuICAgICAgYjogU3RhbmRhcmRQYXJzZWFibGVJbnB1dFxuICAgICkgPT4gMSB8IC0xIHwgMCkgPT5cbiAgICAoYTogU3RhbmRhcmRQYXJzZWFibGVJbnB1dCwgYjogU3RhbmRhcmRQYXJzZWFibGVJbnB1dCk6IDEgfCAtMSB8IDAgPT4ge1xuICAgICAgY29uc3Qgc29ydGEgPSBhLnRvQnVmZmVyKClcbiAgICAgIGNvbnN0IHNvcnRiID0gYi50b0J1ZmZlcigpXG4gICAgICByZXR1cm4gQnVmZmVyLmNvbXBhcmUoc29ydGEsIHNvcnRiKSBhcyAxIHwgLTEgfCAwXG4gICAgfVxuXG4gIGdldElucHV0ID0gKCk6IEJhc2VJbnB1dCA9PiB0aGlzLmlucHV0XG5cbiAgYWRkU2lnbmF0dXJlSWR4KGFkZHJlc3NJZHg6IG51bWJlciwgYWRkcmVzczogQnVmZmVyKTogdm9pZCB7XG4gICAgdGhpcy5pbnB1dC5hZGRTaWduYXR1cmVJZHgoYWRkcmVzc0lkeCwgYWRkcmVzcylcbiAgfVxuXG4gIGdldFNpZ0lkeHMgPSAoKTogU2lnSWR4W10gPT4ge1xuICAgIHJldHVybiB0aGlzLmlucHV0LmdldFNpZ0lkeHMoKVxuICB9XG5cbiAgLy8gbXVzdCBiZSBpbXBsZW1lbnRlZCB0byBzZWxlY3QgaW5wdXQgdHlwZXMgZm9yIHRoZSBWTSBpbiBxdWVzdGlvblxuICBhYnN0cmFjdCBmcm9tQnVmZmVyKGJ5dGVzOiBCdWZmZXIsIG9mZnNldD86IG51bWJlcik6IG51bWJlclxuXG4gIHRvQnVmZmVyKCk6IEJ1ZmZlciB7XG4gICAgY29uc3QgaW5idWZmOiBCdWZmZXIgPSB0aGlzLmlucHV0LnRvQnVmZmVyKClcbiAgICBjb25zdCBpbmlkOiBCdWZmZXIgPSBCdWZmZXIuYWxsb2MoNClcbiAgICBpbmlkLndyaXRlVUludDMyQkUodGhpcy5pbnB1dC5nZXRJbnB1dElEKCksIDApXG4gICAgY29uc3QgYmFycjogQnVmZmVyW10gPSBbaW5pZCwgaW5idWZmXVxuICAgIHJldHVybiBCdWZmZXIuY29uY2F0KGJhcnIsIGluaWQubGVuZ3RoICsgaW5idWZmLmxlbmd0aClcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGFzcyByZXByZXNlbnRpbmcgYW4gW1tTdGFuZGFyZFBhcnNlYWJsZUlucHV0XV0gZm9yIGEgdHJhbnNhY3Rpb24uXG4gICAqXG4gICAqIEBwYXJhbSBpbnB1dCBBIG51bWJlciByZXByZXNlbnRpbmcgdGhlIElucHV0SUQgb2YgdGhlIFtbU3RhbmRhcmRQYXJzZWFibGVJbnB1dF1dXG4gICAqL1xuICBjb25zdHJ1Y3RvcihpbnB1dDogQmFzZUlucHV0ID0gdW5kZWZpbmVkKSB7XG4gICAgc3VwZXIoKVxuICAgIHRoaXMuaW5wdXQgPSBpbnB1dFxuICB9XG59XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBTdGFuZGFyZFRyYW5zZmVyYWJsZUlucHV0IGV4dGVuZHMgU3RhbmRhcmRQYXJzZWFibGVJbnB1dCB7XG4gIHByb3RlY3RlZCBfdHlwZU5hbWUgPSBcIlN0YW5kYXJkVHJhbnNmZXJhYmxlSW5wdXRcIlxuICBwcm90ZWN0ZWQgX3R5cGVJRCA9IHVuZGVmaW5lZFxuXG4gIHNlcmlhbGl6ZShlbmNvZGluZzogU2VyaWFsaXplZEVuY29kaW5nID0gXCJoZXhcIik6IG9iamVjdCB7XG4gICAgbGV0IGZpZWxkczogb2JqZWN0ID0gc3VwZXIuc2VyaWFsaXplKGVuY29kaW5nKVxuICAgIHJldHVybiB7XG4gICAgICAuLi5maWVsZHMsXG4gICAgICB0eGlkOiBzZXJpYWxpemF0aW9uLmVuY29kZXIodGhpcy50eGlkLCBlbmNvZGluZywgXCJCdWZmZXJcIiwgXCJjYjU4XCIpLFxuICAgICAgb3V0cHV0aWR4OiBzZXJpYWxpemF0aW9uLmVuY29kZXIoXG4gICAgICAgIHRoaXMub3V0cHV0aWR4LFxuICAgICAgICBlbmNvZGluZyxcbiAgICAgICAgXCJCdWZmZXJcIixcbiAgICAgICAgXCJkZWNpbWFsU3RyaW5nXCJcbiAgICAgICksXG4gICAgICBhc3NldElEOiBzZXJpYWxpemF0aW9uLmVuY29kZXIodGhpcy5hc3NldElELCBlbmNvZGluZywgXCJCdWZmZXJcIiwgXCJjYjU4XCIpXG4gICAgfVxuICB9XG4gIGRlc2VyaWFsaXplKGZpZWxkczogb2JqZWN0LCBlbmNvZGluZzogU2VyaWFsaXplZEVuY29kaW5nID0gXCJoZXhcIikge1xuICAgIHN1cGVyLmRlc2VyaWFsaXplKGZpZWxkcywgZW5jb2RpbmcpXG4gICAgdGhpcy50eGlkID0gc2VyaWFsaXphdGlvbi5kZWNvZGVyKFxuICAgICAgZmllbGRzW1widHhpZFwiXSxcbiAgICAgIGVuY29kaW5nLFxuICAgICAgXCJjYjU4XCIsXG4gICAgICBcIkJ1ZmZlclwiLFxuICAgICAgMzJcbiAgICApXG4gICAgdGhpcy5vdXRwdXRpZHggPSBzZXJpYWxpemF0aW9uLmRlY29kZXIoXG4gICAgICBmaWVsZHNbXCJvdXRwdXRpZHhcIl0sXG4gICAgICBlbmNvZGluZyxcbiAgICAgIFwiZGVjaW1hbFN0cmluZ1wiLFxuICAgICAgXCJCdWZmZXJcIixcbiAgICAgIDRcbiAgICApXG4gICAgdGhpcy5hc3NldElEID0gc2VyaWFsaXphdGlvbi5kZWNvZGVyKFxuICAgICAgZmllbGRzW1wiYXNzZXRJRFwiXSxcbiAgICAgIGVuY29kaW5nLFxuICAgICAgXCJjYjU4XCIsXG4gICAgICBcIkJ1ZmZlclwiLFxuICAgICAgMzJcbiAgICApXG4gICAgLy9pbnB1dCBkZXNlcmlhbGl6YXRpb24gbXVzdCBiZSBpbXBsbWVudGVkIGluIGNoaWxkIGNsYXNzZXNcbiAgfVxuXG4gIHByb3RlY3RlZCB0eGlkOiBCdWZmZXIgPSBCdWZmZXIuYWxsb2MoMzIpXG4gIHByb3RlY3RlZCBvdXRwdXRpZHg6IEJ1ZmZlciA9IEJ1ZmZlci5hbGxvYyg0KVxuICBwcm90ZWN0ZWQgYXNzZXRJRDogQnVmZmVyID0gQnVmZmVyLmFsbG9jKDMyKVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyfEJ1ZmZlcn0gb2YgdGhlIFR4SUQuXG4gICAqL1xuICBnZXRUeElEID0gKCk6IC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovIEJ1ZmZlciA9PiB0aGlzLnR4aWRcblxuICAvKipcbiAgICogUmV0dXJucyBhIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vZmVyb3NzL2J1ZmZlcnxCdWZmZXJ9ICBvZiB0aGUgT3V0cHV0SWR4LlxuICAgKi9cbiAgZ2V0T3V0cHV0SWR4ID0gKCk6IC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovIEJ1ZmZlciA9PiB0aGlzLm91dHB1dGlkeFxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgYmFzZS01OCBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIFVUWE9JRCB0aGlzIFtbU3RhbmRhcmRUcmFuc2ZlcmFibGVJbnB1dF1dIHJlZmVyZW5jZXMuXG4gICAqL1xuICBnZXRVVFhPSUQgPSAoKTogc3RyaW5nID0+XG4gICAgYmludG9vbHMuYnVmZmVyVG9CNTgoQnVmZmVyLmNvbmNhdChbdGhpcy50eGlkLCB0aGlzLm91dHB1dGlkeF0pKVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBpbnB1dC5cbiAgICovXG4gIGdldElucHV0ID0gKCk6IEJhc2VJbnB1dCA9PiB0aGlzLmlucHV0XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGFzc2V0SUQgb2YgdGhlIGlucHV0LlxuICAgKi9cbiAgZ2V0QXNzZXRJRCA9ICgpOiBCdWZmZXIgPT4gdGhpcy5hc3NldElEXG5cbiAgYWJzdHJhY3QgZnJvbUJ1ZmZlcihieXRlczogQnVmZmVyLCBvZmZzZXQ/OiBudW1iZXIpOiBudW1iZXJcblxuICAvKipcbiAgICogUmV0dXJucyBhIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vZmVyb3NzL2J1ZmZlcnxCdWZmZXJ9IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBbW1N0YW5kYXJkVHJhbnNmZXJhYmxlSW5wdXRdXS5cbiAgICovXG4gIHRvQnVmZmVyKCk6IEJ1ZmZlciB7XG4gICAgY29uc3QgcGFyc2VhYmxlQnVmZjogQnVmZmVyID0gc3VwZXIudG9CdWZmZXIoKVxuICAgIGNvbnN0IGJzaXplOiBudW1iZXIgPVxuICAgICAgdGhpcy50eGlkLmxlbmd0aCArXG4gICAgICB0aGlzLm91dHB1dGlkeC5sZW5ndGggK1xuICAgICAgdGhpcy5hc3NldElELmxlbmd0aCArXG4gICAgICBwYXJzZWFibGVCdWZmLmxlbmd0aFxuICAgIGNvbnN0IGJhcnI6IEJ1ZmZlcltdID0gW1xuICAgICAgdGhpcy50eGlkLFxuICAgICAgdGhpcy5vdXRwdXRpZHgsXG4gICAgICB0aGlzLmFzc2V0SUQsXG4gICAgICBwYXJzZWFibGVCdWZmXG4gICAgXVxuICAgIGNvbnN0IGJ1ZmY6IEJ1ZmZlciA9IEJ1ZmZlci5jb25jYXQoYmFyciwgYnNpemUpXG4gICAgcmV0dXJuIGJ1ZmZcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgYmFzZS01OCByZXByZXNlbnRhdGlvbiBvZiB0aGUgW1tTdGFuZGFyZFRyYW5zZmVyYWJsZUlucHV0XV0uXG4gICAqL1xuICB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgcmV0dXJuIGJpbnRvb2xzLmJ1ZmZlclRvQjU4KHRoaXMudG9CdWZmZXIoKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGFzcyByZXByZXNlbnRpbmcgYW4gW1tTdGFuZGFyZFRyYW5zZmVyYWJsZUlucHV0XV0gZm9yIGEgdHJhbnNhY3Rpb24uXG4gICAqXG4gICAqIEBwYXJhbSB0eGlkIEEge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyfEJ1ZmZlcn0gY29udGFpbmluZyB0aGUgdHJhbnNhY3Rpb24gSUQgb2YgdGhlIHJlZmVyZW5jZWQgVVRYT1xuICAgKiBAcGFyYW0gb3V0cHV0aWR4IEEge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyfEJ1ZmZlcn0gY29udGFpbmluZyB0aGUgaW5kZXggb2YgdGhlIG91dHB1dCBpbiB0aGUgdHJhbnNhY3Rpb24gY29uc3VtZWQgaW4gdGhlIFtbU3RhbmRhcmRUcmFuc2ZlcmFibGVJbnB1dF1dXG4gICAqIEBwYXJhbSBhc3NldElEIEEge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyfEJ1ZmZlcn0gcmVwcmVzZW50aW5nIHRoZSBhc3NldElEIG9mIHRoZSBbW0lucHV0XV1cbiAgICogQHBhcmFtIGlucHV0IEFuIFtbSW5wdXRdXSB0byBiZSBtYWRlIHRyYW5zZmVyYWJsZVxuICAgKi9cbiAgY29uc3RydWN0b3IoXG4gICAgdHhpZDogQnVmZmVyID0gdW5kZWZpbmVkLFxuICAgIG91dHB1dGlkeDogQnVmZmVyID0gdW5kZWZpbmVkLFxuICAgIGFzc2V0SUQ6IEJ1ZmZlciA9IHVuZGVmaW5lZCxcbiAgICBpbnB1dDogQmFzZUlucHV0ID0gdW5kZWZpbmVkXG4gICkge1xuICAgIHN1cGVyKClcbiAgICBpZiAoXG4gICAgICB0eXBlb2YgdHhpZCAhPT0gdW5kZWZpbmVkICYmXG4gICAgICB0eXBlb2Ygb3V0cHV0aWR4ICE9PSB1bmRlZmluZWQgJiZcbiAgICAgIHR5cGVvZiBhc3NldElEICE9PSB1bmRlZmluZWQgJiZcbiAgICAgIGlucHV0ICE9PSB1bmRlZmluZWRcbiAgICApIHtcbiAgICAgIHRoaXMuaW5wdXQgPSBpbnB1dFxuICAgICAgdGhpcy50eGlkID0gdHhpZFxuICAgICAgdGhpcy5vdXRwdXRpZHggPSBvdXRwdXRpZHhcbiAgICAgIHRoaXMuYXNzZXRJRCA9IGFzc2V0SURcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBBbiBbW0lucHV0XV0gY2xhc3Mgd2hpY2ggc3BlY2lmaWVzIGEgdG9rZW4gYW1vdW50IC5cbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFN0YW5kYXJkQW1vdW50SW5wdXQgZXh0ZW5kcyBJbnB1dCB7XG4gIHByb3RlY3RlZCBfdHlwZU5hbWUgPSBcIlN0YW5kYXJkQW1vdW50SW5wdXRcIlxuICBwcm90ZWN0ZWQgX3R5cGVJRCA9IHVuZGVmaW5lZFxuXG4gIHNlcmlhbGl6ZShlbmNvZGluZzogU2VyaWFsaXplZEVuY29kaW5nID0gXCJoZXhcIik6IG9iamVjdCB7XG4gICAgbGV0IGZpZWxkczogb2JqZWN0ID0gc3VwZXIuc2VyaWFsaXplKGVuY29kaW5nKVxuICAgIHJldHVybiB7XG4gICAgICAuLi5maWVsZHMsXG4gICAgICBhbW91bnQ6IHNlcmlhbGl6YXRpb24uZW5jb2RlcihcbiAgICAgICAgdGhpcy5hbW91bnQsXG4gICAgICAgIGVuY29kaW5nLFxuICAgICAgICBcIkJ1ZmZlclwiLFxuICAgICAgICBcImRlY2ltYWxTdHJpbmdcIixcbiAgICAgICAgOFxuICAgICAgKVxuICAgIH1cbiAgfVxuICBkZXNlcmlhbGl6ZShmaWVsZHM6IG9iamVjdCwgZW5jb2Rpbmc6IFNlcmlhbGl6ZWRFbmNvZGluZyA9IFwiaGV4XCIpIHtcbiAgICBzdXBlci5kZXNlcmlhbGl6ZShmaWVsZHMsIGVuY29kaW5nKVxuICAgIHRoaXMuYW1vdW50ID0gc2VyaWFsaXphdGlvbi5kZWNvZGVyKFxuICAgICAgZmllbGRzW1wiYW1vdW50XCJdLFxuICAgICAgZW5jb2RpbmcsXG4gICAgICBcImRlY2ltYWxTdHJpbmdcIixcbiAgICAgIFwiQnVmZmVyXCIsXG4gICAgICA4XG4gICAgKVxuICAgIHRoaXMuYW1vdW50VmFsdWUgPSBiaW50b29scy5mcm9tQnVmZmVyVG9CTih0aGlzLmFtb3VudClcbiAgfVxuXG4gIHByb3RlY3RlZCBhbW91bnQ6IEJ1ZmZlciA9IEJ1ZmZlci5hbGxvYyg4KVxuICBwcm90ZWN0ZWQgYW1vdW50VmFsdWU6IEJOID0gbmV3IEJOKDApXG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGFtb3VudCBhcyBhIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vaW5kdXRueS9ibi5qcy98Qk59LlxuICAgKi9cbiAgZ2V0QW1vdW50ID0gKCk6IEJOID0+IHRoaXMuYW1vdW50VmFsdWUuY2xvbmUoKVxuXG4gIC8qKlxuICAgKiBQb3B1YXRlcyB0aGUgaW5zdGFuY2UgZnJvbSBhIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vZmVyb3NzL2J1ZmZlcnxCdWZmZXJ9IHJlcHJlc2VudGluZyB0aGUgW1tBbW91bnRJbnB1dF1dIGFuZCByZXR1cm5zIHRoZSBzaXplIG9mIHRoZSBpbnB1dC5cbiAgICovXG4gIGZyb21CdWZmZXIoYnl0ZXM6IEJ1ZmZlciwgb2Zmc2V0OiBudW1iZXIgPSAwKTogbnVtYmVyIHtcbiAgICB0aGlzLmFtb3VudCA9IGJpbnRvb2xzLmNvcHlGcm9tKGJ5dGVzLCBvZmZzZXQsIG9mZnNldCArIDgpXG4gICAgdGhpcy5hbW91bnRWYWx1ZSA9IGJpbnRvb2xzLmZyb21CdWZmZXJUb0JOKHRoaXMuYW1vdW50KVxuICAgIG9mZnNldCArPSA4XG4gICAgcmV0dXJuIHN1cGVyLmZyb21CdWZmZXIoYnl0ZXMsIG9mZnNldClcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBidWZmZXIgcmVwcmVzZW50aW5nIHRoZSBbW0Ftb3VudElucHV0XV0gaW5zdGFuY2UuXG4gICAqL1xuICB0b0J1ZmZlcigpOiBCdWZmZXIge1xuICAgIGNvbnN0IHN1cGVyYnVmZjogQnVmZmVyID0gc3VwZXIudG9CdWZmZXIoKVxuICAgIGNvbnN0IGJzaXplOiBudW1iZXIgPSB0aGlzLmFtb3VudC5sZW5ndGggKyBzdXBlcmJ1ZmYubGVuZ3RoXG4gICAgY29uc3QgYmFycjogQnVmZmVyW10gPSBbdGhpcy5hbW91bnQsIHN1cGVyYnVmZl1cbiAgICByZXR1cm4gQnVmZmVyLmNvbmNhdChiYXJyLCBic2l6ZSlcbiAgfVxuXG4gIC8qKlxuICAgKiBBbiBbW0Ftb3VudElucHV0XV0gY2xhc3Mgd2hpY2ggaXNzdWVzIGEgcGF5bWVudCBvbiBhbiBhc3NldElELlxuICAgKlxuICAgKiBAcGFyYW0gYW1vdW50IEEge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9pbmR1dG55L2JuLmpzL3xCTn0gcmVwcmVzZW50aW5nIHRoZSBhbW91bnQgaW4gdGhlIGlucHV0XG4gICAqL1xuICBjb25zdHJ1Y3RvcihhbW91bnQ6IEJOID0gdW5kZWZpbmVkKSB7XG4gICAgc3VwZXIoKVxuICAgIGlmIChhbW91bnQpIHtcbiAgICAgIHRoaXMuYW1vdW50VmFsdWUgPSBhbW91bnQuY2xvbmUoKVxuICAgICAgdGhpcy5hbW91bnQgPSBiaW50b29scy5mcm9tQk5Ub0J1ZmZlcihhbW91bnQsIDgpXG4gICAgfVxuICB9XG59XG4iXX0=