@caminojs-nikos/caminojs
Version:
Camino Platform JS Library
736 lines • 58.7 kB
JavaScript
"use strict";
/**
* @packageDocumentation
* @module Utils-Payload
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MAGNETPayload = exports.ONIONPayload = exports.IPFSPayload = exports.URLPayload = exports.EMAILPayload = exports.YAMLPayload = exports.JSONPayload = exports.CSVPayload = exports.SVGPayload = exports.ICOPayload = exports.BMPPayload = exports.PNGPayload = exports.JPEGPayload = exports.SECPENCPayload = exports.SECPSIGPayload = exports.NODEIDPayload = exports.CHAINIDPayload = exports.SUBNETIDPayload = exports.NFTIDPayload = exports.UTXOIDPayload = exports.ASSETIDPayload = exports.TXIDPayload = exports.cb58EncodedPayload = exports.CCHAINADDRPayload = exports.PCHAINADDRPayload = exports.XCHAINADDRPayload = exports.ChainAddressPayload = exports.BIGNUMPayload = exports.B64STRPayload = exports.B58STRPayload = exports.HEXSTRPayload = exports.UTF8Payload = exports.BINPayload = exports.PayloadBase = exports.PayloadTypes = void 0;
const buffer_1 = require("buffer/");
const bintools_1 = __importDefault(require("./bintools"));
const bn_js_1 = __importDefault(require("bn.js"));
const errors_1 = require("../utils/errors");
const serialization_1 = require("../utils/serialization");
/**
* @ignore
*/
const bintools = bintools_1.default.getInstance();
const serialization = serialization_1.Serialization.getInstance();
/**
* Class for determining payload types and managing the lookup table.
*/
class PayloadTypes {
/**
* Given an encoded payload buffer returns the payload content (minus typeID).
*/
getContent(payload) {
const pl = bintools.copyFrom(payload, 5);
return pl;
}
/**
* Given an encoded payload buffer returns the payload (with typeID).
*/
getPayload(payload) {
const pl = bintools.copyFrom(payload, 4);
return pl;
}
/**
* Given a payload buffer returns the proper TypeID.
*/
getTypeID(payload) {
const offset = 4;
const typeID = bintools
.copyFrom(payload, offset, offset + 1)
.readUInt8(0);
return typeID;
}
/**
* Given a type string returns the proper TypeID.
*/
lookupID(typestr) {
return this.types.indexOf(typestr);
}
/**
* Given a TypeID returns a string describing the payload type.
*/
lookupType(value) {
return this.types[`${value}`];
}
/**
* Given a TypeID returns the proper [[PayloadBase]].
*/
select(typeID, ...args) {
switch (typeID) {
case 0:
return new BINPayload(...args);
case 1:
return new UTF8Payload(...args);
case 2:
return new HEXSTRPayload(...args);
case 3:
return new B58STRPayload(...args);
case 4:
return new B64STRPayload(...args);
case 5:
return new BIGNUMPayload(...args);
case 6:
return new XCHAINADDRPayload(...args);
case 7:
return new PCHAINADDRPayload(...args);
case 8:
return new CCHAINADDRPayload(...args);
case 9:
return new TXIDPayload(...args);
case 10:
return new ASSETIDPayload(...args);
case 11:
return new UTXOIDPayload(...args);
case 12:
return new NFTIDPayload(...args);
case 13:
return new SUBNETIDPayload(...args);
case 14:
return new CHAINIDPayload(...args);
case 15:
return new NODEIDPayload(...args);
case 16:
return new SECPSIGPayload(...args);
case 17:
return new SECPENCPayload(...args);
case 18:
return new JPEGPayload(...args);
case 19:
return new PNGPayload(...args);
case 20:
return new BMPPayload(...args);
case 21:
return new ICOPayload(...args);
case 22:
return new SVGPayload(...args);
case 23:
return new CSVPayload(...args);
case 24:
return new JSONPayload(...args);
case 25:
return new YAMLPayload(...args);
case 26:
return new EMAILPayload(...args);
case 27:
return new URLPayload(...args);
case 28:
return new IPFSPayload(...args);
case 29:
return new ONIONPayload(...args);
case 30:
return new MAGNETPayload(...args);
}
throw new errors_1.TypeIdError(`Error - PayloadTypes.select: unknown typeid ${typeID}`);
}
/**
* Given a [[PayloadBase]] which may not be cast properly, returns a properly cast [[PayloadBase]].
*/
recast(unknowPayload) {
return this.select(unknowPayload.typeID(), unknowPayload.returnType());
}
/**
* Returns the [[PayloadTypes]] singleton.
*/
static getInstance() {
if (!PayloadTypes.instance) {
PayloadTypes.instance = new PayloadTypes();
}
return PayloadTypes.instance;
}
constructor() {
this.types = [];
this.types = [
"BIN",
"UTF8",
"HEXSTR",
"B58STR",
"B64STR",
"BIGNUM",
"XCHAINADDR",
"PCHAINADDR",
"CCHAINADDR",
"TXID",
"ASSETID",
"UTXOID",
"NFTID",
"SUBNETID",
"CHAINID",
"NODEID",
"SECPSIG",
"SECPENC",
"JPEG",
"PNG",
"BMP",
"ICO",
"SVG",
"CSV",
"JSON",
"YAML",
"EMAIL",
"URL",
"IPFS",
"ONION",
"MAGNET"
];
}
}
exports.PayloadTypes = PayloadTypes;
/**
* Base class for payloads.
*/
class PayloadBase {
/**
* Returns the TypeID for the payload.
*/
typeID() {
return this.typeid;
}
/**
* Returns the string name for the payload's type.
*/
typeName() {
return PayloadTypes.getInstance().lookupType(this.typeid);
}
/**
* Returns the payload content (minus typeID).
*/
getContent() {
const pl = bintools.copyFrom(this.payload);
return pl;
}
/**
* Returns the payload (with typeID).
*/
getPayload() {
const typeID = buffer_1.Buffer.alloc(1);
typeID.writeUInt8(this.typeid, 0);
const pl = buffer_1.Buffer.concat([typeID, bintools.copyFrom(this.payload)]);
return pl;
}
/**
* Decodes the payload as a {@link https://github.com/feross/buffer|Buffer} including 4 bytes for the length and TypeID.
*/
fromBuffer(bytes, offset = 0) {
const size = bintools
.copyFrom(bytes, offset, offset + 4)
.readUInt32BE(0);
offset += 4;
this.typeid = bintools.copyFrom(bytes, offset, offset + 1).readUInt8(0);
offset += 1;
this.payload = bintools.copyFrom(bytes, offset, offset + size - 1);
offset += size - 1;
return offset;
}
/**
* Encodes the payload as a {@link https://github.com/feross/buffer|Buffer} including 4 bytes for the length and TypeID.
*/
toBuffer() {
const sizebuff = buffer_1.Buffer.alloc(4);
sizebuff.writeUInt32BE(this.payload.length + 1, 0);
const typebuff = buffer_1.Buffer.alloc(1);
typebuff.writeUInt8(this.typeid, 0);
return buffer_1.Buffer.concat([sizebuff, typebuff, this.payload]);
}
constructor() {
this.payload = buffer_1.Buffer.alloc(0);
this.typeid = undefined;
}
}
exports.PayloadBase = PayloadBase;
/**
* Class for payloads representing simple binary blobs.
*/
class BINPayload extends PayloadBase {
/**
* Returns a {@link https://github.com/feross/buffer|Buffer} for the payload.
*/
returnType() {
return this.payload;
}
/**
* @param payload Buffer only
*/
constructor(payload = undefined) {
super();
this.typeid = 0;
if (payload instanceof buffer_1.Buffer) {
this.payload = payload;
}
else if (typeof payload === "string") {
this.payload = bintools.b58ToBuffer(payload);
}
}
}
exports.BINPayload = BINPayload;
/**
* Class for payloads representing UTF8 encoding.
*/
class UTF8Payload extends PayloadBase {
/**
* Returns a string for the payload.
*/
returnType() {
return this.payload.toString("utf8");
}
/**
* @param payload Buffer utf8 string
*/
constructor(payload = undefined) {
super();
this.typeid = 1;
if (payload instanceof buffer_1.Buffer) {
this.payload = payload;
}
else if (typeof payload === "string") {
this.payload = buffer_1.Buffer.from(payload, "utf8");
}
}
}
exports.UTF8Payload = UTF8Payload;
/**
* Class for payloads representing Hexadecimal encoding.
*/
class HEXSTRPayload extends PayloadBase {
/**
* Returns a hex string for the payload.
*/
returnType() {
return this.payload.toString("hex");
}
/**
* @param payload Buffer or hex string
*/
constructor(payload = undefined) {
super();
this.typeid = 2;
if (payload instanceof buffer_1.Buffer) {
this.payload = payload;
}
else if (typeof payload === "string") {
if (payload.startsWith("0x") || !payload.match(/^[0-9A-Fa-f]+$/)) {
throw new errors_1.HexError("HEXSTRPayload.constructor -- hex string may not start with 0x and must be in /^[0-9A-Fa-f]+$/: " +
payload);
}
this.payload = buffer_1.Buffer.from(payload, "hex");
}
}
}
exports.HEXSTRPayload = HEXSTRPayload;
/**
* Class for payloads representing Base58 encoding.
*/
class B58STRPayload extends PayloadBase {
/**
* Returns a base58 string for the payload.
*/
returnType() {
return bintools.bufferToB58(this.payload);
}
/**
* @param payload Buffer or cb58 encoded string
*/
constructor(payload = undefined) {
super();
this.typeid = 3;
if (payload instanceof buffer_1.Buffer) {
this.payload = payload;
}
else if (typeof payload === "string") {
this.payload = bintools.b58ToBuffer(payload);
}
}
}
exports.B58STRPayload = B58STRPayload;
/**
* Class for payloads representing Base64 encoding.
*/
class B64STRPayload extends PayloadBase {
/**
* Returns a base64 string for the payload.
*/
returnType() {
return this.payload.toString("base64");
}
/**
* @param payload Buffer of base64 string
*/
constructor(payload = undefined) {
super();
this.typeid = 4;
if (payload instanceof buffer_1.Buffer) {
this.payload = payload;
}
else if (typeof payload === "string") {
this.payload = buffer_1.Buffer.from(payload, "base64");
}
}
}
exports.B64STRPayload = B64STRPayload;
/**
* Class for payloads representing Big Numbers.
*
* @param payload Accepts a Buffer, BN, or base64 string
*/
class BIGNUMPayload extends PayloadBase {
/**
* Returns a {@link https://github.com/indutny/bn.js/|BN} for the payload.
*/
returnType() {
return bintools.fromBufferToBN(this.payload);
}
/**
* @param payload Buffer, BN, or base64 string
*/
constructor(payload = undefined) {
super();
this.typeid = 5;
if (payload instanceof buffer_1.Buffer) {
this.payload = payload;
}
else if (payload instanceof bn_js_1.default) {
this.payload = bintools.fromBNToBuffer(payload);
}
else if (typeof payload === "string") {
this.payload = buffer_1.Buffer.from(payload, "hex");
}
}
}
exports.BIGNUMPayload = BIGNUMPayload;
/**
* Class for payloads representing chain addresses.
*
*/
class ChainAddressPayload extends PayloadBase {
/**
* Returns the chainid.
*/
returnChainID() {
return this.chainid;
}
/**
* Returns an address string for the payload.
*/
returnType(hrp) {
const type = "bech32";
return serialization.bufferToType(this.payload, type, hrp, this.chainid);
}
/**
* @param payload Buffer or address string
*/
constructor(payload = undefined, hrp) {
super();
this.typeid = 6;
this.chainid = "";
if (payload instanceof buffer_1.Buffer) {
this.payload = payload;
}
else if (typeof payload === "string") {
if (hrp != undefined) {
this.payload = bintools.stringToAddress(payload, hrp);
}
else {
this.payload = bintools.stringToAddress(payload);
}
}
}
}
exports.ChainAddressPayload = ChainAddressPayload;
/**
* Class for payloads representing X-Chin addresses.
*/
class XCHAINADDRPayload extends ChainAddressPayload {
constructor() {
super(...arguments);
this.typeid = 6;
this.chainid = "X";
}
}
exports.XCHAINADDRPayload = XCHAINADDRPayload;
/**
* Class for payloads representing P-Chain addresses.
*/
class PCHAINADDRPayload extends ChainAddressPayload {
constructor() {
super(...arguments);
this.typeid = 7;
this.chainid = "P";
}
}
exports.PCHAINADDRPayload = PCHAINADDRPayload;
/**
* Class for payloads representing C-Chain addresses.
*/
class CCHAINADDRPayload extends ChainAddressPayload {
constructor() {
super(...arguments);
this.typeid = 8;
this.chainid = "C";
}
}
exports.CCHAINADDRPayload = CCHAINADDRPayload;
/**
* Class for payloads representing data serialized by bintools.cb58Encode().
*/
class cb58EncodedPayload extends PayloadBase {
/**
* Returns a bintools.cb58Encoded string for the payload.
*/
returnType() {
return bintools.cb58Encode(this.payload);
}
/**
* @param payload Buffer or cb58 encoded string
*/
constructor(payload = undefined) {
super();
if (payload instanceof buffer_1.Buffer) {
this.payload = payload;
}
else if (typeof payload === "string") {
this.payload = bintools.cb58Decode(payload);
}
}
}
exports.cb58EncodedPayload = cb58EncodedPayload;
/**
* Class for payloads representing TxIDs.
*/
class TXIDPayload extends cb58EncodedPayload {
constructor() {
super(...arguments);
this.typeid = 9;
}
}
exports.TXIDPayload = TXIDPayload;
/**
* Class for payloads representing AssetIDs.
*/
class ASSETIDPayload extends cb58EncodedPayload {
constructor() {
super(...arguments);
this.typeid = 10;
}
}
exports.ASSETIDPayload = ASSETIDPayload;
/**
* Class for payloads representing NODEIDs.
*/
class UTXOIDPayload extends cb58EncodedPayload {
constructor() {
super(...arguments);
this.typeid = 11;
}
}
exports.UTXOIDPayload = UTXOIDPayload;
/**
* Class for payloads representing NFTIDs (UTXOIDs in an NFT context).
*/
class NFTIDPayload extends UTXOIDPayload {
constructor() {
super(...arguments);
this.typeid = 12;
}
}
exports.NFTIDPayload = NFTIDPayload;
/**
* Class for payloads representing SubnetIDs.
*/
class SUBNETIDPayload extends cb58EncodedPayload {
constructor() {
super(...arguments);
this.typeid = 13;
}
}
exports.SUBNETIDPayload = SUBNETIDPayload;
/**
* Class for payloads representing ChainIDs.
*/
class CHAINIDPayload extends cb58EncodedPayload {
constructor() {
super(...arguments);
this.typeid = 14;
}
}
exports.CHAINIDPayload = CHAINIDPayload;
/**
* Class for payloads representing NodeIDs.
*/
class NODEIDPayload extends cb58EncodedPayload {
constructor() {
super(...arguments);
this.typeid = 15;
}
}
exports.NODEIDPayload = NODEIDPayload;
/**
* Class for payloads representing secp256k1 signatures.
* convention: secp256k1 signature (130 bytes)
*/
class SECPSIGPayload extends B58STRPayload {
constructor() {
super(...arguments);
this.typeid = 16;
}
}
exports.SECPSIGPayload = SECPSIGPayload;
/**
* Class for payloads representing secp256k1 encrypted messages.
* convention: public key (65 bytes) + secp256k1 encrypted message for that public key
*/
class SECPENCPayload extends B58STRPayload {
constructor() {
super(...arguments);
this.typeid = 17;
}
}
exports.SECPENCPayload = SECPENCPayload;
/**
* Class for payloads representing JPEG images.
*/
class JPEGPayload extends BINPayload {
constructor() {
super(...arguments);
this.typeid = 18;
}
}
exports.JPEGPayload = JPEGPayload;
class PNGPayload extends BINPayload {
constructor() {
super(...arguments);
this.typeid = 19;
}
}
exports.PNGPayload = PNGPayload;
/**
* Class for payloads representing BMP images.
*/
class BMPPayload extends BINPayload {
constructor() {
super(...arguments);
this.typeid = 20;
}
}
exports.BMPPayload = BMPPayload;
/**
* Class for payloads representing ICO images.
*/
class ICOPayload extends BINPayload {
constructor() {
super(...arguments);
this.typeid = 21;
}
}
exports.ICOPayload = ICOPayload;
/**
* Class for payloads representing SVG images.
*/
class SVGPayload extends UTF8Payload {
constructor() {
super(...arguments);
this.typeid = 22;
}
}
exports.SVGPayload = SVGPayload;
/**
* Class for payloads representing CSV files.
*/
class CSVPayload extends UTF8Payload {
constructor() {
super(...arguments);
this.typeid = 23;
}
}
exports.CSVPayload = CSVPayload;
/**
* Class for payloads representing JSON strings.
*/
class JSONPayload extends PayloadBase {
/**
* Returns a JSON-decoded object for the payload.
*/
returnType() {
return JSON.parse(this.payload.toString("utf8"));
}
constructor(payload = undefined) {
super();
this.typeid = 24;
if (payload instanceof buffer_1.Buffer) {
this.payload = payload;
}
else if (typeof payload === "string") {
this.payload = buffer_1.Buffer.from(payload, "utf8");
}
else if (payload) {
let jsonstr = JSON.stringify(payload);
this.payload = buffer_1.Buffer.from(jsonstr, "utf8");
}
}
}
exports.JSONPayload = JSONPayload;
/**
* Class for payloads representing YAML definitions.
*/
class YAMLPayload extends UTF8Payload {
constructor() {
super(...arguments);
this.typeid = 25;
}
}
exports.YAMLPayload = YAMLPayload;
/**
* Class for payloads representing email addresses.
*/
class EMAILPayload extends UTF8Payload {
constructor() {
super(...arguments);
this.typeid = 26;
}
}
exports.EMAILPayload = EMAILPayload;
/**
* Class for payloads representing URL strings.
*/
class URLPayload extends UTF8Payload {
constructor() {
super(...arguments);
this.typeid = 27;
}
}
exports.URLPayload = URLPayload;
/**
* Class for payloads representing IPFS addresses.
*/
class IPFSPayload extends B58STRPayload {
constructor() {
super(...arguments);
this.typeid = 28;
}
}
exports.IPFSPayload = IPFSPayload;
/**
* Class for payloads representing onion URLs.
*/
class ONIONPayload extends UTF8Payload {
constructor() {
super(...arguments);
this.typeid = 29;
}
}
exports.ONIONPayload = ONIONPayload;
/**
* Class for payloads representing torrent magnet links.
*/
class MAGNETPayload extends UTF8Payload {
constructor() {
super(...arguments);
this.typeid = 30;
}
}
exports.MAGNETPayload = MAGNETPayload;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF5bG9hZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9wYXlsb2FkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7O0dBR0c7Ozs7OztBQUVILG9DQUFnQztBQUNoQywwREFBaUM7QUFDakMsa0RBQXNCO0FBQ3RCLDRDQUF1RDtBQUN2RCwwREFBc0U7QUFFdEU7O0dBRUc7QUFDSCxNQUFNLFFBQVEsR0FBYSxrQkFBUSxDQUFDLFdBQVcsRUFBRSxDQUFBO0FBQ2pELE1BQU0sYUFBYSxHQUFrQiw2QkFBYSxDQUFDLFdBQVcsRUFBRSxDQUFBO0FBRWhFOztHQUVHO0FBQ0gsTUFBYSxZQUFZO0lBSXZCOztPQUVHO0lBQ0gsVUFBVSxDQUFDLE9BQWU7UUFDeEIsTUFBTSxFQUFFLEdBQVcsUUFBUSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUE7UUFDaEQsT0FBTyxFQUFFLENBQUE7SUFDWCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxVQUFVLENBQUMsT0FBZTtRQUN4QixNQUFNLEVBQUUsR0FBVyxRQUFRLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQTtRQUNoRCxPQUFPLEVBQUUsQ0FBQTtJQUNYLENBQUM7SUFFRDs7T0FFRztJQUNILFNBQVMsQ0FBQyxPQUFlO1FBQ3ZCLE1BQU0sTUFBTSxHQUFXLENBQUMsQ0FBQTtRQUN4QixNQUFNLE1BQU0sR0FBVyxRQUFRO2FBQzVCLFFBQVEsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sR0FBRyxDQUFDLENBQUM7YUFDckMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBQ2YsT0FBTyxNQUFNLENBQUE7SUFDZixDQUFDO0lBRUQ7O09BRUc7SUFDSCxRQUFRLENBQUMsT0FBZTtRQUN0QixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFBO0lBQ3BDLENBQUM7SUFFRDs7T0FFRztJ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QUEzQzs7UUFDWSxXQUFNLEdBQUcsRUFBRSxDQUFBO0lBQ3ZCLENBQUM7Q0FBQTtBQUZELGdDQUVDO0FBRUQ7O0dBRUc7QUFDSCxNQUFhLFdBQVksU0FBUSxhQUFhO0lBQTlDOztRQUNZLFdBQU0sR0FBRyxFQUFFLENBQUE7SUFDdkIsQ0FBQztDQUFBO0FBRkQsa0NBRUM7QUFFRDs7R0FFRztBQUNILE1BQWEsWUFBYSxTQUFRLFdBQVc7SUFBN0M7O1FBQ1ksV0FBTSxHQUFHLEVBQUUsQ0FBQTtJQUN2QixDQUFDO0NBQUE7QUFGRCxvQ0FFQztBQUVEOztHQUVHO0FBQ0gsTUFBYSxhQUFjLFNBQVEsV0FBVztJQUE5Qzs7UUFDWSxXQUFNLEdBQUcsRUFBRSxDQUFBO0lBQ3ZCLENBQUM7Q0FBQTtBQUZELHNDQUVDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAcGFja2FnZURvY3VtZW50YXRpb25cbiAqIEBtb2R1bGUgVXRpbHMtUGF5bG9hZFxuICovXG5cbmltcG9ydCB7IEJ1ZmZlciB9IGZyb20gXCJidWZmZXIvXCJcbmltcG9ydCBCaW5Ub29scyBmcm9tIFwiLi9iaW50b29sc1wiXG5pbXBvcnQgQk4gZnJvbSBcImJuLmpzXCJcbmltcG9ydCB7IFR5cGVJZEVycm9yLCBIZXhFcnJvciB9IGZyb20gXCIuLi91dGlscy9lcnJvcnNcIlxuaW1wb3J0IHsgU2VyaWFsaXphdGlvbiwgU2VyaWFsaXplZFR5cGUgfSBmcm9tIFwiLi4vdXRpbHMvc2VyaWFsaXphdGlvblwiXG5cbi8qKlxuICogQGlnbm9yZVxuICovXG5jb25zdCBiaW50b29sczogQmluVG9vbHMgPSBCaW5Ub29scy5nZXRJbnN0YW5jZSgpXG5jb25zdCBzZXJpYWxpemF0aW9uOiBTZXJpYWxpemF0aW9uID0gU2VyaWFsaXphdGlvbi5nZXRJbnN0YW5jZSgpXG5cbi8qKlxuICogQ2xhc3MgZm9yIGRldGVybWluaW5nIHBheWxvYWQgdHlwZXMgYW5kIG1hbmFnaW5nIHRoZSBsb29rdXAgdGFibGUuXG4gKi9cbmV4cG9ydCBjbGFzcyBQYXlsb2FkVHlwZXMge1xuICBwcml2YXRlIHN0YXRpYyBpbnN0YW5jZTogUGF5bG9hZFR5cGVzXG4gIHByb3RlY3RlZCB0eXBlczogc3RyaW5nW10gPSBbXVxuXG4gIC8qKlxuICAgKiBHaXZlbiBhbiBlbmNvZGVkIHBheWxvYWQgYnVmZmVyIHJldHVybnMgdGhlIHBheWxvYWQgY29udGVudCAobWludXMgdHlwZUlEKS5cbiAgICovXG4gIGdldENvbnRlbnQocGF5bG9hZDogQnVmZmVyKTogQnVmZmVyIHtcbiAgICBjb25zdCBwbDogQnVmZmVyID0gYmludG9vbHMuY29weUZyb20ocGF5bG9hZCwgNSlcbiAgICByZXR1cm4gcGxcbiAgfVxuXG4gIC8qKlxuICAgKiBHaXZlbiBhbiBlbmNvZGVkIHBheWxvYWQgYnVmZmVyIHJldHVybnMgdGhlIHBheWxvYWQgKHdpdGggdHlwZUlEKS5cbiAgICovXG4gIGdldFBheWxvYWQocGF5bG9hZDogQnVmZmVyKTogQnVmZmVyIHtcbiAgICBjb25zdCBwbDogQnVmZmVyID0gYmludG9vbHMuY29weUZyb20ocGF5bG9hZCwgNClcbiAgICByZXR1cm4gcGxcbiAgfVxuXG4gIC8qKlxuICAgKiBHaXZlbiBhIHBheWxvYWQgYnVmZmVyIHJldHVybnMgdGhlIHByb3BlciBUeXBlSUQuXG4gICAqL1xuICBnZXRUeXBlSUQocGF5bG9hZDogQnVmZmVyKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQ6IG51bWJlciA9IDRcbiAgICBjb25zdCB0eXBlSUQ6IG51bWJlciA9IGJpbnRvb2xzXG4gICAgICAuY29weUZyb20ocGF5bG9hZCwgb2Zmc2V0LCBvZmZzZXQgKyAxKVxuICAgICAgLnJlYWRVSW50OCgwKVxuICAgIHJldHVybiB0eXBlSURcbiAgfVxuXG4gIC8qKlxuICAgKiBHaXZlbiBhIHR5cGUgc3RyaW5nIHJldHVybnMgdGhlIHByb3BlciBUeXBlSUQuXG4gICAqL1xuICBsb29rdXBJRCh0eXBlc3RyOiBzdHJpbmcpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLnR5cGVzLmluZGV4T2YodHlwZXN0cilcbiAgfVxuXG4gIC8qKlxuICAgKiBHaXZlbiBhIFR5cGVJRCByZXR1cm5zIGEgc3RyaW5nIGRlc2NyaWJpbmcgdGhlIHBheWxvYWQgdHlwZS5cbiAgICovXG4gIGxvb2t1cFR5cGUodmFsdWU6IG51bWJlcik6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMudHlwZXNbYCR7dmFsdWV9YF1cbiAgfVxuXG4gIC8qKlxuICAgKiBHaXZlbiBhIFR5cGVJRCByZXR1cm5zIHRoZSBwcm9wZXIgW1tQYXlsb2FkQmFzZV1dLlxuICAgKi9cbiAgc2VsZWN0KHR5cGVJRDogbnVtYmVyLCAuLi5hcmdzOiBhbnlbXSk6IFBheWxvYWRCYXNlIHtcbiAgICBzd2l0Y2ggKHR5cGVJRCkge1xuICAgICAgY2FzZSAwOlxuICAgICAgICByZXR1cm4gbmV3IEJJTlBheWxvYWQoLi4uYXJncylcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgcmV0dXJuIG5ldyBVVEY4UGF5bG9hZCguLi5hcmdzKVxuICAgICAgY2FzZSAyOlxuICAgICAgICByZXR1cm4gbmV3IEhFWFNUUlBheWxvYWQoLi4uYXJncylcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgcmV0dXJuIG5ldyBCNThTVFJQYXlsb2FkKC4uLmFyZ3MpXG4gICAgICBjYXNlIDQ6XG4gICAgICAgIHJldHVybiBuZXcgQjY0U1RSUGF5bG9hZCguLi5hcmdzKVxuICAgICAgY2FzZSA1OlxuICAgICAgICByZXR1cm4gbmV3IEJJR05VTVBheWxvYWQoLi4uYXJncylcbiAgICAgIGNhc2UgNjpcbiAgICAgICAgcmV0dXJuIG5ldyBYQ0hBSU5BRERSUGF5bG9hZCguLi5hcmdzKVxuICAgICAgY2FzZSA3OlxuICAgICAgICByZXR1cm4gbmV3IFBDSEFJTkFERFJQYXlsb2FkKC4uLmFyZ3MpXG4gICAgICBjYXNlIDg6XG4gICAgICAgIHJldHVybiBuZXcgQ0NIQUlOQUREUlBheWxvYWQoLi4uYXJncylcbiAgICAgIGNhc2UgOTpcbiAgICAgICAgcmV0dXJuIG5ldyBUWElEUGF5bG9hZCguLi5hcmdzKVxuICAgICAgY2FzZSAxMDpcbiAgICAgICAgcmV0dXJuIG5ldyBBU1NFVElEUGF5bG9hZCguLi5hcmdzKVxuICAgICAgY2FzZSAxMTpcbiAgICAgICAgcmV0dXJuIG5ldyBVVFhPSURQYXlsb2FkKC4uLmFyZ3MpXG4gICAgICBjYXNlIDEyOlxuICAgICAgICByZXR1cm4gbmV3IE5GVElEUGF5bG9hZCguLi5hcmdzKVxuICAgICAgY2FzZSAxMzpcbiAgICAgICAgcmV0dXJuIG5ldyBTVUJORVRJRFBheWxvYWQoLi4uYXJncylcbiAgICAgIGNhc2UgMTQ6XG4gICAgICAgIHJldHVybiBuZXcgQ0hBSU5JRFBheWxvYWQoLi4uYXJncylcbiAgICAgIGNhc2UgMTU6XG4gICAgICAgIHJldHVybiBuZXcgTk9ERUlEUGF5bG9hZCguLi5hcmdzKVxuICAgICAgY2FzZSAxNjpcbiAgICAgICAgcmV0dXJuIG5ldyBTRUNQU0lHUGF5bG9hZCguLi5hcmdzKVxuICAgICAgY2FzZSAxNzpcbiAgICAgICAgcmV0dXJuIG5ldyBTRUNQRU5DUGF5bG9hZCguLi5hcmdzKVxuICAgICAgY2FzZSAxODpcbiAgICAgICAgcmV0dXJuIG5ldyBKUEVHUGF5bG9hZCguLi5hcmdzKVxuICAgICAgY2FzZSAxOTpcbiAgICAgICAgcmV0dXJuIG5ldyBQTkdQYXlsb2FkKC4uLmFyZ3MpXG4gICAgICBjYXNlIDIwOlxuICAgICAgICByZXR1cm4gbmV3IEJNUFBheWxvYWQoLi4uYXJncylcbiAgICAgIGNhc2UgMjE6XG4gICAgICAgIHJldHVybiBuZXcgSUNPUGF5bG9hZCguLi5hcmdzKVxuICAgICAgY2FzZSAyMjpcbiAgICAgICAgcmV0dXJuIG5ldyBTVkdQYXlsb2FkKC4uLmFyZ3MpXG4gICAgICBjYXNlIDIzOlxuICAgICAgICByZXR1cm4gbmV3IENTVlBheWxvYWQoLi4uYXJncylcbiAgICAgIGNhc2UgMjQ6XG4gICAgICAgIHJldHVybiBuZXcgSlNPTlBheWxvYWQoLi4uYXJncylcbiAgICAgIGNhc2UgMjU6XG4gICAgICAgIHJldHVybiBuZXcgWUFNTFBheWxvYWQoLi4uYXJncylcbiAgICAgIGNhc2UgMjY6XG4gICAgICAgIHJldHVybiBuZXcgRU1BSUxQYXlsb2FkKC4uLmFyZ3MpXG4gICAgICBjYXNlIDI3OlxuICAgICAgICByZXR1cm4gbmV3IFVSTFBheWxvYWQoLi4uYXJncylcbiAgICAgIGNhc2UgMjg6XG4gICAgICAgIHJldHVybiBuZXcgSVBGU1BheWxvYWQoLi4uYXJncylcbiAgICAgIGNhc2UgMjk6XG4gICAgICAgIHJldHVybiBuZXcgT05JT05QYXlsb2FkKC4uLmFyZ3MpXG4gICAgICBjYXNlIDMwOlxuICAgICAgICByZXR1cm4gbmV3IE1BR05FVFBheWxvYWQoLi4uYXJncylcbiAgICB9XG4gICAgdGhyb3cgbmV3IFR5cGVJZEVycm9yKFxuICAgICAgYEVycm9yIC0gUGF5bG9hZFR5cGVzLnNlbGVjdDogdW5rbm93biB0eXBlaWQgJHt0eXBlSUR9YFxuICAgIClcbiAgfVxuXG4gIC8qKlxuICAgKiBHaXZlbiBhIFtbUGF5bG9hZEJhc2VdXSB3aGljaCBtYXkgbm90IGJlIGNhc3QgcHJvcGVybHksIHJldHVybnMgYSBwcm9wZXJseSBjYXN0IFtbUGF5bG9hZEJhc2VdXS5cbiAgICovXG4gIHJlY2FzdCh1bmtub3dQYXlsb2FkOiBQYXlsb2FkQmFzZSk6IFBheWxvYWRCYXNlIHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3QodW5rbm93UGF5bG9hZC50eXBlSUQoKSwgdW5rbm93UGF5bG9hZC5yZXR1cm5UeXBlKCkpXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgW1tQYXlsb2FkVHlwZXNdXSBzaW5nbGV0b24uXG4gICAqL1xuICBzdGF0aWMgZ2V0SW5zdGFuY2UoKTogUGF5bG9hZFR5cGVzIHtcbiAgICBpZiAoIVBheWxvYWRUeXBlcy5pbnN0YW5jZSkge1xuICAgICAgUGF5bG9hZFR5cGVzLmluc3RhbmNlID0gbmV3IFBheWxvYWRUeXBlcygpXG4gICAgfVxuXG4gICAgcmV0dXJuIFBheWxvYWRUeXBlcy5pbnN0YW5jZVxuICB9XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLnR5cGVzID0gW1xuICAgICAgXCJCSU5cIixcbiAgICAgIFwiVVRGOFwiLFxuICAgICAgXCJIRVhTVFJcIixcbiAgICAgIFwiQjU4U1RSXCIsXG4gICAgICBcIkI2NFNUUlwiLFxuICAgICAgXCJCSUdOVU1cIixcbiAgICAgIFwiWENIQUlOQUREUlwiLFxuICAgICAgXCJQQ0hBSU5BRERSXCIsXG4gICAgICBcIkNDSEFJTkFERFJcIixcbiAgICAgIFwiVFhJRFwiLFxuICAgICAgXCJBU1NFVElEXCIsXG4gICAgICBcIlVUWE9JRFwiLFxuICAgICAgXCJORlRJRFwiLFxuICAgICAgXCJTVUJORVRJRFwiLFxuICAgICAgXCJDSEFJTklEXCIsXG4gICAgICBcIk5PREVJRFwiLFxuICAgICAgXCJTRUNQU0lHXCIsXG4gICAgICBcIlNFQ1BFTkNcIixcbiAgICAgIFwiSlBFR1wiLFxuICAgICAgXCJQTkdcIixcbiAgICAgIFwiQk1QXCIsXG4gICAgICBcIklDT1wiLFxuICAgICAgXCJTVkdcIixcbiAgICAgIFwiQ1NWXCIsXG4gICAgICBcIkpTT05cIixcbiAgICAgIFwiWUFNTFwiLFxuICAgICAgXCJFTUFJTFwiLFxuICAgICAgXCJVUkxcIixcbiAgICAgIFwiSVBGU1wiLFxuICAgICAgXCJPTklPTlwiLFxuICAgICAgXCJNQUdORVRcIlxuICAgIF1cbiAgfVxufVxuXG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIHBheWxvYWRzLlxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgUGF5bG9hZEJhc2Uge1xuICBwcm90ZWN0ZWQgcGF5bG9hZDogQnVmZmVyID0gQnVmZmVyLmFsbG9jKDApXG4gIHByb3RlY3RlZCB0eXBlaWQ6IG51bWJlciA9IHVuZGVmaW5lZFxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBUeXBlSUQgZm9yIHRoZSBwYXlsb2FkLlxuICAgKi9cbiAgdHlwZUlEKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMudHlwZWlkXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgc3RyaW5nIG5hbWUgZm9yIHRoZSBwYXlsb2FkJ3MgdHlwZS5cbiAgICovXG4gIHR5cGVOYW1lKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIFBheWxvYWRUeXBlcy5nZXRJbnN0YW5jZSgpLmxvb2t1cFR5cGUodGhpcy50eXBlaWQpXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgcGF5bG9hZCBjb250ZW50IChtaW51cyB0eXBlSUQpLlxuICAgKi9cbiAgZ2V0Q29udGVudCgpOiBCdWZmZXIge1xuICAgIGNvbnN0IHBsOiBCdWZmZXIgPSBiaW50b29scy5jb3B5RnJvbSh0aGlzLnBheWxvYWQpXG4gICAgcmV0dXJuIHBsXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgcGF5bG9hZCAod2l0aCB0eXBlSUQpLlxuICAgKi9cbiAgZ2V0UGF5bG9hZCgpOiBCdWZmZXIge1xuICAgIGNvbnN0IHR5cGVJRDogQnVmZmVyID0gQnVmZmVyLmFsbG9jKDEpXG4gICAgdHlwZUlELndyaXRlVUludDgodGhpcy50eXBlaWQsIDApXG4gICAgY29uc3QgcGw6IEJ1ZmZlciA9IEJ1ZmZlci5jb25jYXQoW3R5cGVJRCwgYmludG9vbHMuY29weUZyb20odGhpcy5wYXlsb2FkKV0pXG4gICAgcmV0dXJuIHBsXG4gIH1cblxuICAvKipcbiAgICogRGVjb2RlcyB0aGUgcGF5bG9hZCBhcyBhIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vZmVyb3NzL2J1ZmZlcnxCdWZmZXJ9IGluY2x1ZGluZyA0IGJ5dGVzIGZvciB0aGUgbGVuZ3RoIGFuZCBUeXBlSUQuXG4gICAqL1xuICBmcm9tQnVmZmVyKGJ5dGVzOiBCdWZmZXIsIG9mZnNldDogbnVtYmVyID0gMCk6IG51bWJlciB7XG4gICAgY29uc3Qgc2l6ZTogbnVtYmVyID0gYmludG9vbHNcbiAgICAgIC5jb3B5RnJvbShieXRlcywgb2Zmc2V0LCBvZmZzZXQgKyA0KVxuICAgICAgLnJlYWRVSW50MzJCRSgwKVxuICAgIG9mZnNldCArPSA0XG4gICAgdGhpcy50eXBlaWQgPSBiaW50b29scy5jb3B5RnJvbShieXRlcywgb2Zmc2V0LCBvZmZzZXQgKyAxKS5yZWFkVUludDgoMClcbiAgICBvZmZzZXQgKz0gMVxuICAgIHRoaXMucGF5bG9hZCA9IGJpbnRvb2xzLmNvcHlGcm9tKGJ5dGVzLCBvZmZzZXQsIG9mZnNldCArIHNpemUgLSAxKVxuICAgIG9mZnNldCArPSBzaXplIC0gMVxuICAgIHJldHVybiBvZmZzZXRcbiAgfVxuXG4gIC8qKlxuICAgKiBFbmNvZGVzIHRoZSBwYXlsb2FkIGFzIGEge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyfEJ1ZmZlcn0gaW5jbHVkaW5nIDQgYnl0ZXMgZm9yIHRoZSBsZW5ndGggYW5kIFR5cGVJRC5cbiAgICovXG4gIHRvQnVmZmVyKCk6IEJ1ZmZlciB7XG4gICAgY29uc3Qgc2l6ZWJ1ZmY6IEJ1ZmZlciA9IEJ1ZmZlci5hbGxvYyg0KVxuICAgIHNpemVidWZmLndyaXRlVUludDMyQkUodGhpcy5wYXlsb2FkLmxlbmd0aCArIDEsIDApXG4gICAgY29uc3QgdHlwZWJ1ZmY6IEJ1ZmZlciA9IEJ1ZmZlci5hbGxvYygxKVxuICAgIHR5cGVidWZmLndyaXRlVUludDgodGhpcy50eXBlaWQsIDApXG4gICAgcmV0dXJuIEJ1ZmZlci5jb25jYXQoW3NpemVidWZmLCB0eXBlYnVmZiwgdGhpcy5wYXlsb2FkXSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBleHBlY3RlZCB0eXBlIGZvciB0aGUgcGF5bG9hZC5cbiAgICovXG4gIGFic3RyYWN0IHJldHVyblR5cGUoLi4uYXJnczogYW55KTogYW55XG5cbiAgY29uc3RydWN0b3IoKSB7fVxufVxuXG4vKipcbiAqIENsYXNzIGZvciBwYXlsb2FkcyByZXByZXNlbnRpbmcgc2ltcGxlIGJpbmFyeSBibG9icy5cbiAqL1xuZXhwb3J0IGNsYXNzIEJJTlBheWxvYWQgZXh0ZW5kcyBQYXlsb2FkQmFzZSB7XG4gIHByb3RlY3RlZCB0eXBlaWQgPSAwXG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL2Zlcm9zcy9idWZmZXJ8QnVmZmVyfSBmb3IgdGhlIHBheWxvYWQuXG4gICAqL1xuICByZXR1cm5UeXBlKCk6IEJ1ZmZlciB7XG4gICAgcmV0dXJuIHRoaXMucGF5bG9hZFxuICB9XG4gIC8qKlxuICAgKiBAcGFyYW0gcGF5bG9hZCBCdWZmZXIgb25seVxuICAgKi9cbiAgY29uc3RydWN0b3IocGF5bG9hZDogYW55ID0gdW5kZWZpbmVkKSB7XG4gICAgc3VwZXIoKVxuICAgIGlmIChwYXlsb2FkIGluc3RhbmNlb2YgQnVmZmVyKSB7XG4gICAgICB0aGlzLnBheWxvYWQgPSBwYXlsb2FkXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgcGF5bG9hZCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgdGhpcy5wYXlsb2FkID0gYmludG9vbHMuYjU4VG9CdWZmZXIocGF5bG9hZClcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBDbGFzcyBmb3IgcGF5bG9hZHMgcmVwcmVzZW50aW5nIFVURjggZW5jb2RpbmcuXG4gKi9cbmV4cG9ydCBjbGFzcyBVVEY4UGF5bG9hZCBleHRlbmRzIFBheWxvYWRCYXNlIHtcbiAgcHJvdGVjdGVkIHR5cGVpZCA9IDFcblxuICAvKipcbiAgICogUmV0dXJucyBhIHN0cmluZyBmb3IgdGhlIHBheWxvYWQuXG4gICAqL1xuICByZXR1cm5UeXBlKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMucGF5bG9hZC50b1N0cmluZyhcInV0ZjhcIilcbiAgfVxuICAvKipcbiAgICogQHBhcmFtIHBheWxvYWQgQnVmZmVyIHV0Zjggc3RyaW5nXG4gICAqL1xuICBjb25zdHJ1Y3RvcihwYXlsb2FkOiBhbnkgPSB1bmRlZmluZWQpIHtcbiAgICBzdXBlcigpXG4gICAgaWYgKHBheWxvYWQgaW5zdGFuY2VvZiBCdWZmZXIpIHtcbiAgICAgIHRoaXMucGF5bG9hZCA9IHBheWxvYWRcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBwYXlsb2FkID09PSBcInN0cmluZ1wiKSB7XG4gICAgICB0aGlzLnBheWxvYWQgPSBCdWZmZXIuZnJvbShwYXlsb2FkLCBcInV0ZjhcIilcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBDbGFzcyBmb3IgcGF5bG9hZHMgcmVwcmVzZW50aW5nIEhleGFkZWNpbWFsIGVuY29kaW5nLlxuICovXG5leHBvcnQgY2xhc3MgSEVYU1RSUGF5bG9hZCBleHRlbmRzIFBheWxvYWRCYXNlIHtcbiAgcHJvdGVjdGVkIHR5cGVpZCA9IDJcblxuICAvKipcbiAgICogUmV0dXJucyBhIGhleCBzdHJpbmcgZm9yIHRoZSBwYXlsb2FkLlxuICAgKi9cbiAgcmV0dXJuVHlwZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnBheWxvYWQudG9TdHJpbmcoXCJoZXhcIilcbiAgfVxuICAvKipcbiAgICogQHBhcmFtIHBheWxvYWQgQnVmZmVyIG9yIGhleCBzdHJpbmdcbiAgICovXG4gIGNvbnN0cnVjdG9yKHBheWxvYWQ6IGFueSA9IHVuZGVmaW5lZCkge1xuICAgIHN1cGVyKClcbiAgICBpZiAocGF5bG9hZCBpbnN0YW5jZW9mIEJ1ZmZlcikge1xuICAgICAgdGhpcy5wYXlsb2FkID0gcGF5bG9hZFxuICAgIH0gZWxzZSBpZiAodHlwZW9mIHBheWxvYWQgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIGlmIChwYXlsb2FkLnN0YXJ0c1dpdGgoXCIweFwiKSB8fCAhcGF5bG9hZC5tYXRjaCgvXlswLTlBLUZhLWZdKyQvKSkge1xuICAgICAgICB0aHJvdyBuZXcgSGV4RXJyb3IoXG4gICAgICAgICAgXCJIRVhTVFJQYXlsb2FkLmNvbnN0cnVjdG9yIC0tIGhleCBzdHJpbmcgbWF5IG5vdCBzdGFydCB3aXRoIDB4IGFuZCBtdXN0IGJlIGluIC9eWzAtOUEtRmEtZl0rJC86IFwiICtcbiAgICAgICAgICAgIHBheWxvYWRcbiAgICAgICAgKVxuICAgICAgfVxuICAgICAgdGhpcy5wYXlsb2FkID0gQnVmZmVyLmZyb20ocGF5bG9hZCwgXCJoZXhcIilcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBDbGFzcyBmb3IgcGF5bG9hZHMgcmVwcmVzZW50aW5nIEJhc2U1OCBlbmNvZGluZy5cbiAqL1xuZXhwb3J0IGNsYXNzIEI1OFNUUlBheWxvYWQgZXh0ZW5kcyBQYXlsb2FkQmFzZSB7XG4gIHByb3RlY3RlZCB0eXBlaWQgPSAzXG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBiYXNlNTggc3RyaW5nIGZvciB0aGUgcGF5bG9hZC5cbiAgICovXG4gIHJldHVyblR5cGUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYmludG9vbHMuYnVmZmVyVG9CNTgodGhpcy5wYXlsb2FkKVxuICB9XG4gIC8qKlxuICAgKiBAcGFyYW0gcGF5bG9hZCBCdWZmZXIgb3IgY2I1OCBlbmNvZGVkIHN0cmluZ1xuICAgKi9cbiAgY29uc3RydWN0b3IocGF5bG9hZDogYW55ID0gdW5kZWZpbmVkKSB7XG4gICAgc3VwZXIoKVxuICAgIGlmIChwYXlsb2FkIGluc3RhbmNlb2YgQnVmZmVyKSB7XG4gICAgICB0aGlzLnBheWxvYWQgPSBwYXlsb2FkXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgcGF5bG9hZCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgdGhpcy5wYXlsb2FkID0gYmludG9vbHMuYjU4VG9CdWZmZXIocGF5bG9hZClcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBDbGFzcyBmb3IgcGF5bG9hZHMgcmVwcmVzZW50aW5nIEJhc2U2NCBlbmNvZGluZy5cbiAqL1xuZXhwb3J0IGNsYXNzIEI2NFNUUlBheWxvYWQgZXh0ZW5kcyBQYXlsb2FkQmFzZSB7XG4gIHByb3RlY3RlZCB0eXBlaWQgPSA0XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBiYXNlNjQgc3RyaW5nIGZvciB0aGUgcGF5bG9hZC5cbiAgICovXG4gIHJldHVyblR5cGUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5wYXlsb2FkLnRvU3RyaW5nKFwiYmFzZTY0XCIpXG4gIH1cbiAgLyoqXG4gICAqIEBwYXJhbSBwYXlsb2FkIEJ1ZmZlciBvZiBiYXNlNjQgc3RyaW5nXG4gICAqL1xuICBjb25zdHJ1Y3RvcihwYXlsb2FkOiBhbnkgPSB1bmRlZmluZWQpIHtcbiAgICBzdXBlcigpXG4gICAgaWYgKHBheWxvYWQgaW5zdGFuY2VvZiBCdWZmZXIpIHtcbiAgICAgIHRoaXMucGF5bG9hZCA9IHBheWxvYWRcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBwYXlsb2FkID09PSBcInN0cmluZ1wiKSB7XG4gICAgICB0aGlzLnBheWxvYWQgPSBCdWZmZXIuZnJvbShwYXlsb2FkLCBcImJhc2U2NFwiKVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIENsYXNzIGZvciBwYXlsb2FkcyByZXByZXNlbnRpbmcgQmlnIE51bWJlcnMuXG4gKlxuICogQHBhcmFtIHBheWxvYWQgQWNjZXB0cyBhIEJ1ZmZlciwgQk4sIG9yIGJhc2U2NCBzdHJpbmdcb