700 lines
69 KiB
JavaScript
700 lines
69 KiB
JavaScript
"use strict";
|
|
var __defProp = Object.defineProperty;
|
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
var __export = (target, all) => {
|
|
for (var name in all)
|
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames(from))
|
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
|
|
// src/index.ts
|
|
var src_exports = {};
|
|
__export(src_exports, {
|
|
CTL: () => CTL,
|
|
OggDemuxer: () => OggDemuxer,
|
|
OpusDecoder: () => OpusDecoder,
|
|
OpusEncoder: () => OpusEncoder,
|
|
OpusStream: () => OpusStream,
|
|
WebmDemuxer: () => WebmDemuxer,
|
|
addLibopusProvider: () => addLibopusProvider,
|
|
removeLibopusProvider: () => removeLibopusProvider,
|
|
setLibopusProvider: () => setLibopusProvider,
|
|
version: () => version
|
|
});
|
|
module.exports = __toCommonJS(src_exports);
|
|
|
|
// src/OggDemuxer.ts
|
|
var import_node_stream = require("stream");
|
|
var OGG_PAGE_HEADER_SIZE = 26;
|
|
var STREAM_STRUCTURE_VERSION = 0;
|
|
var charCode = /* @__PURE__ */ __name((x) => x.charCodeAt(0), "charCode");
|
|
var OGGS_HEADER = Buffer.from([..."OggS"].map(charCode));
|
|
var OPUS_HEAD = Buffer.from([..."OpusHead"].map(charCode));
|
|
var OPUS_TAGS = Buffer.from([..."OpusTags"].map(charCode));
|
|
var _OggDemuxer = class _OggDemuxer extends import_node_stream.Transform {
|
|
/**
|
|
* Creates a new OggOpus demuxer.
|
|
* @param {Object} [options] options that you would pass to a regular Transform stream.
|
|
* @memberof opus
|
|
*/
|
|
constructor(options = {}) {
|
|
super(Object.assign({ readableObjectMode: true }, options));
|
|
__publicField(this, "_remainder", null);
|
|
__publicField(this, "_head", null);
|
|
__publicField(this, "_bitstream", null);
|
|
this._remainder = null;
|
|
this._head = null;
|
|
this._bitstream = null;
|
|
}
|
|
_transform(chunk, encoding, done) {
|
|
if (this._remainder) {
|
|
chunk = Buffer.concat([this._remainder, chunk]);
|
|
this._remainder = null;
|
|
}
|
|
try {
|
|
while (chunk) {
|
|
const result = this._readPage(chunk);
|
|
if (result) chunk = result;
|
|
else
|
|
break;
|
|
}
|
|
} catch (error) {
|
|
done(error);
|
|
return;
|
|
}
|
|
this._remainder = chunk;
|
|
done();
|
|
}
|
|
/**
|
|
* Reads a page from a buffer
|
|
* @private
|
|
* @param {Buffer} chunk the chunk containing the page
|
|
* @returns {boolean|Buffer} if a buffer, it will be a slice of the excess data of the original, otherwise it will be
|
|
* false and would indicate that there is not enough data to go ahead with reading this page.
|
|
*/
|
|
_readPage(chunk) {
|
|
if (chunk.length < OGG_PAGE_HEADER_SIZE) {
|
|
return false;
|
|
}
|
|
if (!chunk.subarray(0, 4).equals(OGGS_HEADER)) {
|
|
throw Error(`capture_pattern is not ${OGGS_HEADER}`);
|
|
}
|
|
if (chunk.readUInt8(4) !== STREAM_STRUCTURE_VERSION) {
|
|
throw Error(
|
|
`stream_structure_version is not ${STREAM_STRUCTURE_VERSION}`
|
|
);
|
|
}
|
|
if (chunk.length < 27) return false;
|
|
const pageSegments = chunk.readUInt8(26);
|
|
if (chunk.length < 27 + pageSegments) return false;
|
|
const table = chunk.subarray(27, 27 + pageSegments);
|
|
const bitstream = chunk.readUInt32BE(14);
|
|
const sizes = [];
|
|
let totalSize = 0;
|
|
for (let i = 0; i < pageSegments; ) {
|
|
let size = 0, x = 255;
|
|
while (x === 255) {
|
|
if (i >= table.length) return false;
|
|
x = table.readUInt8(i);
|
|
i++;
|
|
size += x;
|
|
}
|
|
sizes.push(size);
|
|
totalSize += size;
|
|
}
|
|
if (chunk.length < 27 + pageSegments + totalSize) return false;
|
|
let start = 27 + pageSegments;
|
|
for (const size of sizes) {
|
|
const segment = chunk.subarray(start, start + size);
|
|
const header = segment.subarray(0, 8);
|
|
if (this._head) {
|
|
if (header.equals(OPUS_TAGS)) this.emit("tags", segment);
|
|
else if (this._bitstream === bitstream) this.push(segment);
|
|
} else if (header.equals(OPUS_HEAD)) {
|
|
this.emit("head", segment);
|
|
this._head = segment;
|
|
this._bitstream = bitstream;
|
|
} else {
|
|
this.emit("unknownSegment", segment);
|
|
}
|
|
start += size;
|
|
}
|
|
return chunk.subarray(start);
|
|
}
|
|
_destroy(err, cb) {
|
|
this._cleanup();
|
|
return cb ? cb(err) : void 0;
|
|
}
|
|
_final(cb) {
|
|
this._cleanup();
|
|
cb();
|
|
}
|
|
/**
|
|
* Cleans up the demuxer when it is no longer required.
|
|
* @private
|
|
*/
|
|
_cleanup() {
|
|
this._remainder = null;
|
|
this._head = null;
|
|
this._bitstream = null;
|
|
}
|
|
};
|
|
__name(_OggDemuxer, "OggDemuxer");
|
|
var OggDemuxer = _OggDemuxer;
|
|
|
|
// src/OpusEncoder.ts
|
|
var import_node_stream2 = require("stream");
|
|
var loadModule = /* @__PURE__ */ __name((modules) => {
|
|
const errors = [];
|
|
for (const [name, fn] of modules) {
|
|
try {
|
|
return {
|
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
...fn(require(name)),
|
|
name
|
|
};
|
|
} catch (e) {
|
|
errors.push(`Failed to load ${name}: ${e}`);
|
|
continue;
|
|
}
|
|
}
|
|
throw new Error(
|
|
`Could not load opus module, tried ${modules.length} different modules. Errors: ${errors.join("\n")}`
|
|
);
|
|
}, "loadModule");
|
|
var CTL = {
|
|
BITRATE: 4002,
|
|
FEC: 4012,
|
|
PLP: 4014
|
|
};
|
|
var OPUS_MOD_REGISTRY = [
|
|
[
|
|
"mediaplex",
|
|
(mod) => {
|
|
if (!mod.OpusEncoder) throw new Error("Unsupported mediaplex version");
|
|
return { Encoder: mod.OpusEncoder };
|
|
}
|
|
],
|
|
["@discordjs/opus", (opus) => ({ Encoder: opus.OpusEncoder })],
|
|
["opusscript", (opus) => ({ Encoder: opus })],
|
|
[
|
|
"@evan/opus",
|
|
(opus) => {
|
|
const { Encoder, Decoder } = opus;
|
|
const _OpusEncoder2 = class _OpusEncoder2 {
|
|
constructor(_rate, _channels, _application) {
|
|
this._rate = _rate;
|
|
this._channels = _channels;
|
|
this._application = _application;
|
|
__publicField(this, "_encoder");
|
|
__publicField(this, "_decoder");
|
|
}
|
|
_ensureEncoder() {
|
|
if (this._encoder) return;
|
|
this._encoder = new Encoder({
|
|
channels: this._channels,
|
|
sample_rate: this._rate,
|
|
application: {
|
|
2048: "voip",
|
|
2049: "audio",
|
|
2051: "restricted_lowdelay"
|
|
}[this._application]
|
|
});
|
|
}
|
|
_ensureDecoder() {
|
|
if (this._decoder) return;
|
|
this._decoder = new Decoder({
|
|
channels: this._channels,
|
|
sample_rate: this._rate
|
|
});
|
|
}
|
|
encode(buffer) {
|
|
this._ensureEncoder();
|
|
return Buffer.from(this._encoder.encode(buffer));
|
|
}
|
|
decode(buffer) {
|
|
this._ensureDecoder();
|
|
return Buffer.from(this._decoder.decode(buffer));
|
|
}
|
|
applyEncoderCTL(ctl, value) {
|
|
this._ensureEncoder();
|
|
this._encoder.ctl(ctl, value);
|
|
}
|
|
delete() {
|
|
this._encoder = null;
|
|
this._decoder = null;
|
|
}
|
|
};
|
|
__name(_OpusEncoder2, "OpusEncoder");
|
|
let OpusEncoder2 = _OpusEncoder2;
|
|
return { Encoder: OpusEncoder2 };
|
|
}
|
|
],
|
|
["node-opus", (opus) => ({ Encoder: opus.OpusEncoder })]
|
|
];
|
|
var Opus = {};
|
|
var addLibopusProvider = /* @__PURE__ */ __name((provider) => {
|
|
if (OPUS_MOD_REGISTRY.some(([, fn]) => fn === provider[1])) return;
|
|
OPUS_MOD_REGISTRY.push(provider);
|
|
}, "addLibopusProvider");
|
|
var removeLibopusProvider = /* @__PURE__ */ __name((name) => {
|
|
const index = OPUS_MOD_REGISTRY.findIndex((o) => o[0] === name);
|
|
if (index === -1) return false;
|
|
OPUS_MOD_REGISTRY.splice(index, 1);
|
|
return true;
|
|
}, "removeLibopusProvider");
|
|
var setLibopusProvider = /* @__PURE__ */ __name((provider, name) => {
|
|
Opus = { Encoder: provider, name };
|
|
}, "setLibopusProvider");
|
|
function loadOpus(refresh = false) {
|
|
if (Opus.Encoder && !refresh) return Opus;
|
|
Opus = loadModule(OPUS_MOD_REGISTRY);
|
|
return Opus;
|
|
}
|
|
__name(loadOpus, "loadOpus");
|
|
var charCode2 = /* @__PURE__ */ __name((x) => x.charCodeAt(0), "charCode");
|
|
var OPUS_HEAD2 = Buffer.from([..."OpusHead"].map(charCode2));
|
|
var OPUS_TAGS2 = Buffer.from([..."OpusTags"].map(charCode2));
|
|
var _OpusStream = class _OpusStream extends import_node_stream2.Transform {
|
|
/**
|
|
* Creates a new Opus transformer.
|
|
* @private
|
|
* @memberof opus
|
|
* @param {Object} [options] options that you would pass to a regular Transform stream
|
|
*/
|
|
constructor(options = {}) {
|
|
if (!loadOpus().Encoder) {
|
|
throw Error(
|
|
`Could not find an Opus module! Please install one of ${OPUS_MOD_REGISTRY.map(
|
|
(o) => o[0]
|
|
).join(", ")}.`
|
|
);
|
|
}
|
|
super(Object.assign({ readableObjectMode: true }, options));
|
|
__publicField(this, "encoder", null);
|
|
__publicField(this, "_options");
|
|
__publicField(this, "_required");
|
|
const lib = Opus;
|
|
if (lib.name === "opusscript") {
|
|
options.application = lib.Encoder.Application[options.application];
|
|
}
|
|
this.encoder = new lib.Encoder(
|
|
options.rate,
|
|
options.channels,
|
|
options.application
|
|
);
|
|
this._options = options;
|
|
this._required = this._options.frameSize * this._options.channels * 2;
|
|
}
|
|
_encode(buffer) {
|
|
if (Opus.name === "opusscript") {
|
|
return this.encoder.encode(buffer, this._options.frameSize);
|
|
} else {
|
|
return this.encoder.encode(buffer);
|
|
}
|
|
}
|
|
_decode(buffer) {
|
|
if (Opus.name === "opusscript") {
|
|
return this.encoder.decode(buffer, this._options.frameSize);
|
|
} else {
|
|
return this.encoder.decode(buffer);
|
|
}
|
|
}
|
|
/**
|
|
* Returns the Opus module being used - `mediaplex`, `opusscript`, `node-opus`, or `@discordjs/opus`.
|
|
* @type {string}
|
|
* @readonly
|
|
* @example
|
|
* console.log(`Using Opus module ${OpusEncoder.type}`);
|
|
*/
|
|
static get type() {
|
|
return Opus.name;
|
|
}
|
|
/**
|
|
* Sets the bitrate of the stream.
|
|
* @param {number} bitrate the bitrate to use use, e.g. 48000
|
|
* @public
|
|
*/
|
|
setBitrate(bitrate) {
|
|
(this.encoder.applyEncoderCTL || this.encoder.encoderCTL).apply(
|
|
this.encoder,
|
|
[CTL.BITRATE, Math.min(128e3, Math.max(16e3, bitrate))]
|
|
);
|
|
}
|
|
/**
|
|
* Enables or disables forward error correction.
|
|
* @param {boolean} enabled whether or not to enable FEC.
|
|
* @public
|
|
*/
|
|
setFEC(enabled) {
|
|
(this.encoder.applyEncoderCTL || this.encoder.encoderCTL).apply(
|
|
this.encoder,
|
|
[CTL.FEC, enabled ? 1 : 0]
|
|
);
|
|
}
|
|
/**
|
|
* Sets the expected packet loss over network transmission.
|
|
* @param {number} [percentage] a percentage (represented between 0 and 1)
|
|
*/
|
|
setPLP(percentage) {
|
|
(this.encoder.applyEncoderCTL || this.encoder.encoderCTL).apply(
|
|
this.encoder,
|
|
[CTL.PLP, Math.min(100, Math.max(0, percentage * 100))]
|
|
);
|
|
}
|
|
_final(cb) {
|
|
this._cleanup();
|
|
cb();
|
|
}
|
|
_destroy(err, cb) {
|
|
this._cleanup();
|
|
return cb ? cb(err) : void 0;
|
|
}
|
|
/**
|
|
* Cleans up the Opus stream when it is no longer needed
|
|
* @private
|
|
*/
|
|
_cleanup() {
|
|
if (typeof this.encoder?.delete === "function") this.encoder.delete();
|
|
this.encoder = null;
|
|
}
|
|
};
|
|
__name(_OpusStream, "OpusStream");
|
|
var OpusStream = _OpusStream;
|
|
var _OpusEncoder = class _OpusEncoder extends OpusStream {
|
|
/**
|
|
* Creates a new Opus encoder stream.
|
|
* @memberof opus
|
|
* @param {Object} options options that you would pass to a regular OpusStream, plus a few more:
|
|
* @param {number} options.frameSize the frame size in bytes to use (e.g. 960 for stereo audio at 48KHz with a frame
|
|
* duration of 20ms)
|
|
* @param {number} options.channels the number of channels to use
|
|
* @param {number} options.rate the sampling rate in Hz
|
|
*/
|
|
constructor(options = {}) {
|
|
super(options);
|
|
__publicField(this, "_buffer", Buffer.allocUnsafe(0));
|
|
}
|
|
_transform(newChunk, encoding, done) {
|
|
const chunk = Buffer.concat([this._buffer, newChunk]);
|
|
let i = 0;
|
|
while (chunk.length >= i + this._required) {
|
|
const pcm = chunk.slice(i, i + this._required);
|
|
let opus;
|
|
try {
|
|
opus = this.encoder.encode(pcm);
|
|
} catch (error) {
|
|
done(error);
|
|
return;
|
|
}
|
|
this.push(opus);
|
|
i += this._required;
|
|
}
|
|
if (i > 0) this._buffer = chunk.slice(i);
|
|
done();
|
|
}
|
|
_destroy(err, cb) {
|
|
super._destroy(err, cb);
|
|
this._buffer = Buffer.allocUnsafe(0);
|
|
}
|
|
};
|
|
__name(_OpusEncoder, "OpusEncoder");
|
|
var OpusEncoder = _OpusEncoder;
|
|
var _OpusDecoder = class _OpusDecoder extends OpusStream {
|
|
_transform(chunk, encoding, done) {
|
|
const signature = chunk.slice(0, 8);
|
|
if (chunk.length >= 8 && signature.equals(OPUS_HEAD2)) {
|
|
this.emit("format", {
|
|
channels: this._options.channels,
|
|
sampleRate: this._options.rate,
|
|
bitDepth: 16,
|
|
float: false,
|
|
signed: true,
|
|
version: chunk.readUInt8(8),
|
|
preSkip: chunk.readUInt16LE(10),
|
|
gain: chunk.readUInt16LE(16)
|
|
});
|
|
return done();
|
|
}
|
|
if (chunk.length >= 8 && signature.equals(OPUS_TAGS2)) {
|
|
this.emit("tags", chunk);
|
|
return done();
|
|
}
|
|
try {
|
|
this.push(this._decode(chunk));
|
|
} catch (e) {
|
|
return done(e);
|
|
}
|
|
return done();
|
|
}
|
|
};
|
|
__name(_OpusDecoder, "OpusDecoder");
|
|
var OpusDecoder = _OpusDecoder;
|
|
|
|
// src/WebmBase.ts
|
|
var import_node_stream3 = require("stream");
|
|
var _WebmBaseDemuxer = class _WebmBaseDemuxer extends import_node_stream3.Transform {
|
|
/**
|
|
* Creates a new Webm demuxer.
|
|
* @param {Object} [options] options that you would pass to a regular Transform stream.
|
|
*/
|
|
constructor(options = {}) {
|
|
super(Object.assign({ readableObjectMode: true }, options));
|
|
__publicField(this, "_remainder", null);
|
|
__publicField(this, "_length", 0);
|
|
__publicField(this, "_count", 0);
|
|
__publicField(this, "_skipUntil", null);
|
|
__publicField(this, "_track", null);
|
|
__publicField(this, "_incompleteTrack", {});
|
|
__publicField(this, "_ebmlFound", false);
|
|
this._remainder = null;
|
|
this._length = 0;
|
|
this._count = 0;
|
|
this._skipUntil = null;
|
|
this._track = null;
|
|
this._incompleteTrack = {};
|
|
this._ebmlFound = false;
|
|
}
|
|
_checkHead(data) {
|
|
}
|
|
_transform(chunk, encoding, done) {
|
|
this._length += chunk.length;
|
|
if (this._remainder) {
|
|
chunk = Buffer.concat([this._remainder, chunk]);
|
|
this._remainder = null;
|
|
}
|
|
let offset = 0;
|
|
if (this._skipUntil && this._length > this._skipUntil) {
|
|
offset = this._skipUntil - this._count;
|
|
this._skipUntil = null;
|
|
} else if (this._skipUntil) {
|
|
this._count += chunk.length;
|
|
done();
|
|
return;
|
|
}
|
|
let result;
|
|
while (result !== _WebmBaseDemuxer.TOO_SHORT) {
|
|
try {
|
|
result = this._readTag(chunk, offset);
|
|
} catch (error) {
|
|
done(error);
|
|
return;
|
|
}
|
|
if (result === _WebmBaseDemuxer.TOO_SHORT) break;
|
|
if (result._skipUntil) {
|
|
this._skipUntil = result._skipUntil;
|
|
break;
|
|
}
|
|
if (result.offset) offset = result.offset;
|
|
else
|
|
break;
|
|
}
|
|
this._count += offset;
|
|
this._remainder = chunk.subarray(offset);
|
|
done();
|
|
return;
|
|
}
|
|
/**
|
|
* Reads an EBML ID from a buffer.
|
|
* @private
|
|
* @param {Buffer} chunk the buffer to read from.
|
|
* @param {number} offset the offset in the buffer.
|
|
* @returns {Object|Symbol} contains an `id` property (buffer) and the new `offset` (number).
|
|
* Returns the TOO_SHORT symbol if the data wasn't big enough to facilitate the request.
|
|
*/
|
|
_readEBMLId(chunk, offset) {
|
|
const idLength = vintLength(chunk, offset);
|
|
if (idLength === _WebmBaseDemuxer.TOO_SHORT)
|
|
return _WebmBaseDemuxer.TOO_SHORT;
|
|
return {
|
|
id: chunk.subarray(offset, offset + idLength),
|
|
offset: offset + idLength
|
|
};
|
|
}
|
|
/**
|
|
* Reads a size variable-integer to calculate the length of the data of a tag.
|
|
* @private
|
|
* @param {Buffer} chunk the buffer to read from.
|
|
* @param {number} offset the offset in the buffer.
|
|
* @returns {Object|Symbol} contains property `offset` (number), `dataLength` (number) and `sizeLength` (number).
|
|
* Returns the TOO_SHORT symbol if the data wasn't big enough to facilitate the request.
|
|
*/
|
|
_readTagDataSize(chunk, offset) {
|
|
const sizeLength = vintLength(chunk, offset);
|
|
if (sizeLength === _WebmBaseDemuxer.TOO_SHORT)
|
|
return _WebmBaseDemuxer.TOO_SHORT;
|
|
const dataLength = expandVint(chunk, offset, offset + sizeLength);
|
|
return { offset: offset + sizeLength, dataLength, sizeLength };
|
|
}
|
|
/**
|
|
* Takes a buffer and attempts to read and process a tag.
|
|
* @private
|
|
* @param {Buffer} chunk the buffer to read from.
|
|
* @param {number} offset the offset in the buffer.
|
|
* @returns {Object|Symbol} contains the new `offset` (number) and optionally the `_skipUntil` property,
|
|
* indicating that the stream should ignore any data until a certain length is reached.
|
|
* Returns the TOO_SHORT symbol if the data wasn't big enough to facilitate the request.
|
|
*/
|
|
_readTag(chunk, offset) {
|
|
const idData = this._readEBMLId(chunk, offset);
|
|
if (idData === _WebmBaseDemuxer.TOO_SHORT) return _WebmBaseDemuxer.TOO_SHORT;
|
|
const ebmlID = idData.id.toString("hex");
|
|
if (!this._ebmlFound) {
|
|
if (ebmlID === "1a45dfa3") this._ebmlFound = true;
|
|
else
|
|
throw Error("Did not find the EBML tag at the start of the stream");
|
|
}
|
|
offset = idData.offset;
|
|
const sizeData = this._readTagDataSize(chunk, offset);
|
|
if (sizeData === _WebmBaseDemuxer.TOO_SHORT)
|
|
return _WebmBaseDemuxer.TOO_SHORT;
|
|
const { dataLength } = sizeData;
|
|
offset = sizeData.offset;
|
|
if (typeof _WebmBaseDemuxer.TAGS[ebmlID] === "undefined") {
|
|
if (chunk.length > offset + dataLength) {
|
|
return { offset: offset + dataLength };
|
|
}
|
|
return {
|
|
offset,
|
|
_skipUntil: this._count + offset + dataLength
|
|
};
|
|
}
|
|
const tagHasChildren = _WebmBaseDemuxer.TAGS[ebmlID];
|
|
if (tagHasChildren) {
|
|
return { offset };
|
|
}
|
|
if (offset + dataLength > chunk.length)
|
|
return _WebmBaseDemuxer.TOO_SHORT;
|
|
const data = chunk.subarray(
|
|
offset,
|
|
offset + dataLength
|
|
);
|
|
if (!this._track) {
|
|
if (ebmlID === "ae") this._incompleteTrack = {};
|
|
if (ebmlID === "d7") this._incompleteTrack.number = data[0];
|
|
if (ebmlID === "83") this._incompleteTrack.type = data[0];
|
|
if (this._incompleteTrack.type === 2 && typeof this._incompleteTrack.number !== "undefined") {
|
|
this._track = this._incompleteTrack;
|
|
}
|
|
}
|
|
if (ebmlID === "63a2") {
|
|
this._checkHead(data);
|
|
this.emit("head", data);
|
|
} else if (ebmlID === "a3") {
|
|
if (!this._track) throw Error("No audio track in this webm!");
|
|
if ((data[0] & 15) === this._track.number) {
|
|
this.push(data.subarray(4));
|
|
}
|
|
}
|
|
return { offset: offset + dataLength };
|
|
}
|
|
_destroy(err, cb) {
|
|
this._cleanup();
|
|
return cb ? cb(err) : void 0;
|
|
}
|
|
_final(cb) {
|
|
this._cleanup();
|
|
cb();
|
|
}
|
|
/**
|
|
* Cleans up the demuxer when it is no longer required.
|
|
* @private
|
|
*/
|
|
_cleanup() {
|
|
this._remainder = null;
|
|
this._incompleteTrack = {};
|
|
}
|
|
};
|
|
__name(_WebmBaseDemuxer, "WebmBaseDemuxer");
|
|
__publicField(_WebmBaseDemuxer, "TAGS", {
|
|
// value is true if the element has children
|
|
"1a45dfa3": true,
|
|
// EBML
|
|
"18538067": true,
|
|
// Segment
|
|
"1f43b675": true,
|
|
// Cluster
|
|
"1654ae6b": true,
|
|
// Tracks
|
|
ae: true,
|
|
// TrackEntry
|
|
d7: false,
|
|
// TrackNumber
|
|
"83": false,
|
|
// TrackType
|
|
a3: false,
|
|
// SimpleBlock
|
|
"63a2": false
|
|
});
|
|
__publicField(_WebmBaseDemuxer, "TOO_SHORT", Symbol("TOO_SHORT"));
|
|
var WebmBaseDemuxer = _WebmBaseDemuxer;
|
|
function vintLength(buffer, index) {
|
|
if (index < 0 || index > buffer.length - 1) {
|
|
return WebmBaseDemuxer.TOO_SHORT;
|
|
}
|
|
let i = 0;
|
|
for (; i < 8; i++) if (1 << 7 - i & buffer[index]) break;
|
|
i++;
|
|
if (index + i > buffer.length) {
|
|
return WebmBaseDemuxer.TOO_SHORT;
|
|
}
|
|
return i;
|
|
}
|
|
__name(vintLength, "vintLength");
|
|
function expandVint(buffer, start, end) {
|
|
const length = vintLength(buffer, start);
|
|
if (end > buffer.length || length === WebmBaseDemuxer.TOO_SHORT)
|
|
return WebmBaseDemuxer.TOO_SHORT;
|
|
const mask = (1 << 8 - length) - 1;
|
|
let value = buffer[start] & mask;
|
|
for (let i = start + 1; i < end; i++) {
|
|
value = (value << 8) + buffer[i];
|
|
}
|
|
return value;
|
|
}
|
|
__name(expandVint, "expandVint");
|
|
|
|
// src/WebmDemuxer.ts
|
|
var OPUS_HEAD3 = Buffer.from([..."OpusHead"].map((x) => x.charCodeAt(0)));
|
|
var _WebmDemuxer = class _WebmDemuxer extends WebmBaseDemuxer {
|
|
_checkHead(data) {
|
|
if (!data.subarray(0, 8).equals(OPUS_HEAD3)) {
|
|
throw Error("Audio codec is not Opus!");
|
|
}
|
|
}
|
|
};
|
|
__name(_WebmDemuxer, "WebmDemuxer");
|
|
var WebmDemuxer = _WebmDemuxer;
|
|
|
|
// src/version.ts
|
|
var version = (
|
|
/* @__MACRO__ getVersion */
|
|
"7.2.0"
|
|
);
|
|
// Annotate the CommonJS export names for ESM import in node:
|
|
0 && (module.exports = {
|
|
CTL,
|
|
OggDemuxer,
|
|
OpusDecoder,
|
|
OpusEncoder,
|
|
OpusStream,
|
|
WebmDemuxer,
|
|
addLibopusProvider,
|
|
removeLibopusProvider,
|
|
setLibopusProvider,
|
|
version
|
|
});
|
|
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2luZGV4LnRzIiwgIi4uL3NyYy9PZ2dEZW11eGVyLnRzIiwgIi4uL3NyYy9PcHVzRW5jb2Rlci50cyIsICIuLi9zcmMvV2VibUJhc2UudHMiLCAiLi4vc3JjL1dlYm1EZW11eGVyLnRzIiwgIi4uL3NyYy92ZXJzaW9uLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJleHBvcnQgKiBmcm9tICcuL09nZ0RlbXV4ZXInO1xuZXhwb3J0ICogZnJvbSAnLi9PcHVzRW5jb2Rlcic7XG5leHBvcnQgKiBmcm9tICcuL1dlYm1EZW11eGVyJztcblxuZXhwb3J0IHsgdmVyc2lvbiB9IGZyb20gJy4vdmVyc2lvbic7IiwgIi8vIGJhc2VkIG9uIGh0dHBzOi8vZ2l0aHViLmNvbS9hbWlzaHNoYWgvcHJpc20tbWVkaWEvYmxvYi80ZWYxZDZmOWY1MzA0MmMwODVjMWY2ODYyN2U4ODkwMDNlMjQ4ZDc3L3NyYy9vcHVzL09nZ0RlbXV4ZXIuanNcblxuaW1wb3J0IHsgVHJhbnNmb3JtLCBUcmFuc2Zvcm1DYWxsYmFjayB9IGZyb20gJ25vZGU6c3RyZWFtJztcblxuY29uc3QgT0dHX1BBR0VfSEVBREVSX1NJWkUgPSAyNjtcbmNvbnN0IFNUUkVBTV9TVFJVQ1RVUkVfVkVSU0lPTiA9IDA7XG5cbmNvbnN0IGNoYXJDb2RlID0gKHg6IHN0cmluZykgPT4geC5jaGFyQ29kZUF0KDApO1xuY29uc3QgT0dHU19IRUFERVIgPSBCdWZmZXIuZnJvbShbLi4uJ09nZ1MnXS5tYXAoY2hhckNvZGUpKTtcbmNvbnN0IE9QVVNfSEVBRCA9IEJ1ZmZlci5mcm9tKFsuLi4nT3B1c0hlYWQnXS5tYXAoY2hhckNvZGUpKTtcbmNvbnN0IE9QVVNfVEFHUyA9IEJ1ZmZlci5mcm9tKFsuLi4nT3B1c1RhZ3MnXS5tYXAoY2hhckNvZGUpKTtcblxuLyoqXG4gKiBEZW11eGVzIGFuIE9nZyBzdHJlYW0gKGNvbnRhaW5pbmcgT3B1cyBhdWRpbykgdG8gb3V0cHV0IGFuIE9wdXMgc3RyZWFtLlxuICovXG5leHBvcnQgY2xhc3MgT2dnRGVtdXhlciBleHRlbmRzIFRyYW5zZm9ybSB7XG4gIHByaXZhdGUgX3JlbWFpbmRlcjogQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgX2hlYWQ6IEJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIF9iaXRzdHJlYW06IG51bWJlciB8IG51bGwgPSBudWxsO1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IE9nZ09wdXMgZGVtdXhlci5cbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSBvcHRpb25zIHRoYXQgeW91IHdvdWxkIHBhc3MgdG8gYSByZWd1bGFyIFRyYW5zZm9ybSBzdHJlYW0uXG4gICAqIEBtZW1iZXJvZiBvcHVzXG4gICAqL1xuICBwdWJsaWMgY29uc3RydWN0b3Iob3B0aW9ucyA9IHt9KSB7XG4gICAgc3VwZXIoT2JqZWN0LmFzc2lnbih7IHJlYWRhYmxlT2JqZWN0TW9kZTogdHJ1ZSB9LCBvcHRpb25zKSk7XG4gICAgdGhpcy5fcmVtYWluZGVyID0gbnVsbDtcbiAgICB0aGlzLl9oZWFkID0gbnVsbDtcbiAgICB0aGlzLl9iaXRzdHJlYW0gPSBudWxsO1xuICB9XG5cbiAgX3RyYW5zZm9ybShjaHVuazogQnVmZmVyLCBlbmNvZGluZzogQnVmZmVyRW5jb2RpbmcsIGRvbmU6IFRyYW5zZm9ybUNhbGxiYWNrKSB7XG4gICAgaWYgKHRoaXMuX3JlbWFpbmRlcikge1xuICAgICAgY2h1bmsgPSBCdWZmZXIuY29uY2F0KFt0aGlzLl9yZW1haW5kZXIsIGNodW5rXSk7XG4gICAgICB0aGlzLl9yZW1haW5kZXIgPSBudWxsO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICB3aGlsZSAoY2h1bmspIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5fcmVhZFBhZ2UoY2h1bmspO1xuICAgICAgICBpZiAocmVzdWx0KSBjaHVuayA9IHJlc3VsdDtlbHNlXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBkb25lKGVycm9yIGFzIEVycm9yKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLl9yZW1haW5kZXIgPSBjaHVuaztcbiAgICBkb25lKCk7XG4gIH1cblxuICAvKipcbiAgICogUmVhZHMgYSBwYWdlIGZyb20gYSBidWZmZXJcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtCdWZmZXJ9IGNodW5rIHRoZSBjaHVuayBjb250YWluaW5nIHRoZSBwYWdlXG4gICAqIEByZXR1cm5zIHtib29sZWFufEJ1ZmZlcn0gaWYgYSBidWZmZXIsIGl0IHdpbGwgYmUgYSBzbGljZSBvZiB0aGUgZXhjZXNzIGRhdGEgb2YgdGhlIG9yaWdpbmFsLCBvdGhlcndpc2UgaXQgd2lsbCBiZVxuICAgKiBmYWxzZSBhbmQgd291bGQgaW5kaWNhdGUgdGhhdCB0aGVyZSBpcyBub3QgZW5vdWdoIGRhdGEgdG8gZ28gYWhlYWQgd2l0aCByZWFkaW5nIHRoaXMgcGFnZS5cbiAgICovXG4gIF9yZWFkUGFnZShjaHVuazogQnVmZmVyKSB7XG4gICAgaWYgKGNodW5rLmxlbmd0aCA8IE9HR19QQUdFX0hFQURFUl9TSVpFKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghY2h1bmsuc3ViYXJyYXkoMCwgNCkuZXF1YWxzKE9HR1NfSEVBREVSKSkge1xuICAgICAgdGhyb3cgRXJyb3IoYGNhcHR1cmVfcGF0dGVybiBpcyBub3QgJHtPR0dTX0hFQURFUn1gKTtcbiAgICB9XG4gICAgaWYgKGNodW5rLnJlYWRVSW50OCg0KSAhPT0gU1RSRUFNX1NUUlVDVFVSRV9WRVJTSU9OKSB7XG4gICAgICB0aHJvdyBFcnJvcihcbiAgICAgICAgYHN0cmVhbV9zdHJ1Y3R1cmVfdmVyc2lvbiBpcyBub3QgJHtTVFJFQU1fU1RSVUNUVVJFX1ZFUlNJT059YFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoY2h1bmsubGVuZ3RoIDwgMjcpIHJldHVybiBmYWxzZTtcbiAgICBjb25zdCBwYWdlU2VnbWVudHMgPSBjaHVuay5yZWFkVUludDgoMjYpO1xuICAgIGlmIChjaHVuay5sZW5ndGggPCAyNyArIHBhZ2VTZWdtZW50cykgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IHRhYmxlID0gY2h1bmsuc3ViYXJyYXkoMjcsIDI3ICsgcGFnZVNlZ21lbnRzKTtcbiAgICBjb25zdCBiaXRzdHJlYW0gPSBjaHVuay5yZWFkVUludDMyQkUoMTQpO1xuXG4gICAgY29uc3Qgc2l6ZXM6IG51bWJlcltdID0gW107XG4gICAgbGV0IHRvdGFsU2l6ZSA9IDA7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhZ2VTZWdtZW50czspIHtcbiAgICAgIGxldCBzaXplID0gMCxcbiAgICAgICAgeCA9IDI1NTtcbiAgICAgIHdoaWxlICh4ID09PSAyNTUpIHtcbiAgICAgICAgaWYgKGkgPj0gdGFibGUubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIHggPSB0YWJsZS5yZWFkVUludDgoaSk7XG4gICAgICAgIGkrKztcbiAgICAgICAgc2l6ZSArPSB4O1xuICAgICAgfVxuICAgICAgc2l6ZXMucHVzaChzaXplKTtcbiAgICAgIHRvdGFsU2l6ZSArPSBzaXplO1xuICAgIH1cblxuICAgIGlmIChjaHVuay5sZW5ndGggPCAyNyArIHBhZ2VTZWdtZW50cyArIHRvdGFsU2l6ZSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgbGV0IHN0YXJ0ID0gMjcgKyBwYWdlU2VnbWVudHM7XG4gICAgZm9yIChjb25zdCBzaXplIG9mIHNpemVzKSB7XG4gICAgICBjb25zdCBzZWdtZW50ID0gY2h1bmsuc3ViYXJyYXkoc3RhcnQsIHN0YXJ0ICsgc2l6ZSk7XG4gICAgICBjb25zdCBoZWFkZXIgPSBzZWdtZW50LnN1YmFycmF5KDAsIDgpO1xuICAgICAgaWYgKHRoaXMuX2hlYWQpIHtcbiAgICAgICAgaWYgKGhlYWRlci5lcXVhbHMoT1BVU19UQUdTKSkgdGhpcy5lbWl0KCd0YWdzJywgc2VnbWVudCk7ZWxzZVxuICAgICAgICBpZiAodGhpcy5fYml0c3RyZWFtID09PSBiaXRzdHJlYW0pIHRoaXMucHVzaChzZWdtZW50KTtcbiAgICAgIH0gZWxzZSBpZiAoaGVhZGVyLmVxdWFscyhPUFVTX0hFQUQpKSB7XG4gICAgICAgIHRoaXMuZW1pdCgnaGVhZCcsIHNlZ21lbnQpO1xuICAgICAgICB0aGlzLl9oZWFkID0gc2VnbWVudDtcbiAgICAgICAgdGhpcy5fYml0c3RyZWFtID0gYml0c3RyZWFtO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5lbWl0KCd1bmtub3duU2VnbWVudCcsIHNlZ21lbnQpO1xuICAgICAgfVxuICAgICAgc3RhcnQgKz0gc2l6ZTtcbiAgICB9XG4gICAgcmV0dXJuIGNodW5rLnN1YmFycmF5KHN0YXJ0KTtcbiAgfVxuXG4gIF9kZXN0cm95KGVycjogRXJyb3IsIGNiOiAoZXJyb3I6IEVycm9yIHwgbnVsbCkgPT4gdm9pZCkge1xuICAgIHRoaXMuX2NsZWFudXAoKTtcbiAgICByZXR1cm4gY2IgPyBjYihlcnIpIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgX2ZpbmFsKGNiOiBUcmFuc2Zvcm1DYWxsYmFjaykge1xuICAgIHRoaXMuX2NsZWFudXAoKTtcbiAgICBjYigpO1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFucyB1cCB0aGUgZGVtdXhlciB3aGVuIGl0IGlzIG5vIGxvbmdlciByZXF1aXJlZC5cbiAgICogQHByaXZhdGVcbiAgICovXG4gIF9jbGVhbnVwKCkge1xuICAgIHRoaXMuX3JlbWFpbmRlciA9IG51bGw7XG4gICAgdGhpcy5faGVhZCA9IG51bGw7XG4gICAgdGhpcy5fYml0c3RyZWFtID0gbnVsbDtcbiAgfVxufSIsICIvLyBiYXNlZCBvbiBodHRwczovL2dpdGh1Yi5jb20vYW1pc2hzaGFoL3ByaXNtLW1lZGlhL2Jsb2IvNGVmMWQ2ZjlmNTMwNDJjMDg1YzFmNjg2MjdlODg5MDAzZTI0OGQ3Ny9zcmMvb3B1cy9PcHVzLmpzXG5cbmltcG9ydCB7IFRyYW5zZm9ybSwgdHlwZSBUcmFuc2Zvcm1DYWxsYmFjayB9IGZyb20gJ25vZGU6c3RyZWFtJztcblxuZXhwb3J0IHR5cGUgSUVuY29kZXIgPSB7XG4gIG5ldyAocmF0ZTogbnVtYmVyLCBjaGFubmVsczogbnVtYmVyLCBhcHBsaWNhdGlvbjogbnVtYmVyKToge1xuICAgIGVuY29kZShidWZmZXI6IEJ1ZmZlcik6IEJ1ZmZlcjtcbiAgICBlbmNvZGUoYnVmZmVyOiBCdWZmZXIsIGZyYW1lU2l6ZTogbnVtYmVyKTogQnVmZmVyO1xuICAgIGVuY29kZShidWZmZXI6IEJ1ZmZlciwgZnJhbWVTaXplPzogbnVtYmVyKTogQnVmZmVyO1xuICAgIGRlY29kZShidWZmZXI6IEJ1ZmZlcik6IEJ1ZmZlcjtcbiAgICBkZWNvZGUoYnVmZmVyOiBCdWZmZXIsIGZyYW1lU2l6ZTogbnVtYmVyKTogQnVmZmVyO1xuICAgIGRlY29kZShidWZmZXI6IEJ1ZmZlciwgZnJhbWVTaXplPzogbnVtYmVyKTogQnVmZmVyO1xuICAgIGFwcGx5RW5jb2RlckNUTD8oY3RsOiBudW1iZXIsIHZhbHVlOiBudW1iZXIpOiB2b2lkO1xuICAgIGVuY29kZXJDVEw/KGN0bDogbnVtYmVyLCB2YWx1ZTogbnVtYmVyKTogdm9pZDtcbiAgICBkZWxldGU/KCk6IHZvaWQ7XG4gIH07XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gIEFwcGxpY2F0aW9uPzogYW55O1xufTtcblxudHlwZSBJTW9kID0gW1xuICBzdHJpbmcsXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gIChtb2Q6IGFueSkgPT4ge1xuICAgIEVuY29kZXI6IElFbmNvZGVyO1xuICB9XTtcblxuXG5jb25zdCBsb2FkTW9kdWxlID0gKFxubW9kdWxlczogSU1vZFtdKVxuOiB7XG4gIEVuY29kZXI6IElFbmNvZGVyO1xuICBuYW1lOiBzdHJpbmc7XG59ID0+IHtcbiAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIGZvciAoY29uc3QgW25hbWUsIGZuXSBvZiBtb2R1bGVzKSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdmFyLXJlcXVpcmVzXG4gICAgICAgIC4uLmZuKHJlcXVpcmUobmFtZSkpLFxuICAgICAgICBuYW1lXG4gICAgICB9O1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGVycm9ycy5wdXNoKGBGYWlsZWQgdG8gbG9hZCAke25hbWV9OiAke2V9YCk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgYENvdWxkIG5vdCBsb2FkIG9wdXMgbW9kdWxlLCB0cmllZCAke1xuICAgIG1vZHVsZXMubGVuZ3RofSBkaWZmZXJlbnQgbW9kdWxlcy4gRXJyb3JzOiAke1xuICAgIGVycm9ycy5qb2luKCdcXG4nKX1gXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3QgQ1RMID0ge1xuICBCSVRSQVRFOiAweGZhMixcbiAgRkVDOiAweGZhYyxcbiAgUExQOiAweGZhZVxufSBhcyBjb25zdDtcblxuY29uc3QgT1BVU19NT0RfUkVHSVNUUlk6IElNb2RbXSA9IFtcbltcbidtZWRpYXBsZXgnLFxuKG1vZCkgPT4ge1xuICBpZiAoIW1vZC5PcHVzRW5jb2RlcikgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBtZWRpYXBsZXggdmVyc2lvbicpO1xuICByZXR1cm4geyBFbmNvZGVyOiBtb2QuT3B1c0VuY29kZXIgfTtcbn1dLFxuXG5bJ0BkaXNjb3JkanMvb3B1cycsIChvcHVzKSA9PiAoeyBFbmNvZGVyOiBvcHVzLk9wdXNFbmNvZGVyIH0pXSxcblsnb3B1c3NjcmlwdCcsIChvcHVzKSA9PiAoeyBFbmNvZGVyOiBvcHVzIH0pXSxcbltcbidAZXZhbi9vcHVzJyxcbihvcHVzKSA9PiB7XG4gIGNvbnN0IHsgRW5jb2RlciwgRGVjb2RlciB9ID0gb3B1cyBhcyB0eXBlb2YgaW1wb3J0KCdAZXZhbi9vcHVzJyk7XG5cbiAgY2xhc3MgT3B1c0VuY29kZXIge1xuICAgIHByaXZhdGUgX2VuY29kZXIhOiBJbnN0YW5jZVR5cGU8dHlwZW9mIEVuY29kZXI+IHwgbnVsbDtcbiAgICBwcml2YXRlIF9kZWNvZGVyITogSW5zdGFuY2VUeXBlPHR5cGVvZiBEZWNvZGVyPiB8IG51bGw7XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBfcmF0ZTogbnVtYmVyLFxuICAgIHByaXZhdGUgX2NoYW5uZWxzOiBudW1iZXIsXG4gICAgcHJpdmF0ZSBfYXBwbGljYXRpb246IG51bWJlcilcbiAgICB7fVxuXG4gICAgcHJpdmF0ZSBfZW5zdXJlRW5jb2RlcigpIHtcbiAgICAgIGlmICh0aGlzLl9lbmNvZGVyKSByZXR1cm47XG4gICAgICB0aGlzLl9lbmNvZGVyID0gbmV3IEVuY29kZXIoe1xuICAgICAgICBjaGFubmVsczogdGhpcy5fY2hhbm5lbHMgYXMgMixcbiAgICAgICAgc2FtcGxlX3JhdGU6IHRoaXMuX3JhdGUgYXMgNDgwMDAsXG4gICAgICAgIGFwcGxpY2F0aW9uOiAoPGNvbnN0PiB7XG4gICAgICAgICAgMjA0ODogJ3ZvaXAnLFxuICAgICAgICAgIDIwNDk6ICdhdWRpbycsXG4gICAgICAgICAgMjA1MTogJ3Jlc3RyaWN0ZWRfbG93ZGVsYXknXG4gICAgICAgIH0pW3RoaXMuX2FwcGxpY2F0aW9uXVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfZW5zdXJlRGVjb2RlcigpIHtcbiAgICAgIGlmICh0aGlzLl9kZWNvZGVyKSByZXR1cm47XG4gICAgICB0aGlzLl9kZWNvZGVyID0gbmV3IERlY29kZXIoe1xuICAgICAgICBjaGFubmVsczogdGhpcy5fY2hhbm5lbHMgYXMgMixcbiAgICAgICAgc2FtcGxlX3JhdGU6IHRoaXMuX3JhdGUgYXMgNDgwMDBcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBlbmNvZGUoYnVmZmVyOiBCdWZmZXIpIHtcbiAgICAgIHRoaXMuX2Vuc3VyZUVuY29kZXIoKTtcbiAgICAgIHJldHVybiBCdWZmZXIuZnJvbSh0aGlzLl9lbmNvZGVyIS5lbmNvZGUoYnVmZmVyKSk7XG4gICAgfVxuXG4gICAgcHVibGljIGRlY29kZShidWZmZXI6IEJ1ZmZlcikge1xuICAgICAgdGhpcy5fZW5zdXJlRGVjb2RlcigpO1xuICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKHRoaXMuX2RlY29kZXIhLmRlY29kZShidWZmZXIpKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXBwbHlFbmNvZGVyQ1RMKGN0bDogbnVtYmVyLCB2YWx1ZTogbnVtYmVyKSB7XG4gICAgICB0aGlzLl9lbnN1cmVFbmNvZGVyKCk7XG4gICAgICB0aGlzLl9lbmNvZGVyIS5jdGwoY3RsLCB2YWx1ZSk7XG4gICAgfVxuXG4gICAgcHVibGljIGRlbGV0ZSgpIHtcbiAgICAgIHRoaXMuX2VuY29kZXIgPSBudWxsO1xuICAgICAgdGhpcy5fZGVjb2RlciA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHsgRW5jb2RlcjogT3B1c0VuY29kZXIgfTtcbn1dLFxuXG5bJ25vZGUtb3B1cycsIChvcHVzKSA9PiAoeyBFbmNvZGVyOiBvcHVzLk9wdXNFbmNvZGVyIH0pXV07XG5cblxubGV0IE9wdXM6IHtFbmNvZGVyPzogSUVuY29kZXI7bmFtZT86IHN0cmluZzt9ID0ge307XG5cbi8qKlxuICogQWRkIGEgbmV3IE9wdXMgcHJvdmlkZXIgdG8gdGhlIHJlZ2lzdHJ5LiBUaGlzIHdpbGwgYmUgdHJpZWQgdG8gbG9hZCBpbiBvcmRlciBhdCBydW50aW1lLlxuICogQHBhcmFtIHByb3ZpZGVyIC0gVGhlIHByb3ZpZGVyIHRvIGFkZFxuICovXG5leHBvcnQgY29uc3QgYWRkTGlib3B1c1Byb3ZpZGVyID0gKHByb3ZpZGVyOiBJTW9kKSA9PiB7XG4gIGlmIChPUFVTX01PRF9SRUdJU1RSWS5zb21lKChbLCBmbl0pID0+IGZuID09PSBwcm92aWRlclsxXSkpIHJldHVybjtcbiAgT1BVU19NT0RfUkVHSVNUUlkucHVzaChwcm92aWRlcik7XG59O1xuXG4vKipcbiAqIFJlbW92ZSBhbiBPcHVzIHByb3ZpZGVyIGZyb20gdGhlIHJlZ2lzdHJ5LlxuICogQHBhcmFtIG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgcHJvdmlkZXIgdG8gcmVtb3ZlXG4gKi9cbmV4cG9ydCBjb25zdCByZW1vdmVMaWJvcHVzUHJvdmlkZXIgPSAobmFtZTogc3RyaW5nKSA9PiB7XG4gIGNvbnN0IGluZGV4ID0gT1BVU19NT0RfUkVHSVNUUlkuZmluZEluZGV4KChvKSA9PiBvWzBdID09PSBuYW1lKTtcbiAgaWYgKGluZGV4ID09PSAtMSkgcmV0dXJuIGZhbHNlO1xuICBPUFVTX01PRF9SRUdJU1RSWS5zcGxpY2UoaW5kZXgsIDEpO1xuICByZXR1cm4gdHJ1ZTtcbn07XG5cbi8qKlxuICogU2V0IHRoZSBPcHVzIHByb3ZpZGVyIHRvIHVzZS4gVGhpcyB3aWxsIG92ZXJyaWRlIHRoZSBhdXRvbWF0aWMgcHJvdmlkZXIgc2VsZWN0aW9uLlxuICogQHBhcmFtIHByb3ZpZGVyIC0gVGhlIHByb3ZpZGVyIHRvIHVzZVxuICovXG5leHBvcnQgY29uc3Qgc2V0TGlib3B1c1Byb3ZpZGVyID0gKHByb3ZpZGVyOiBJRW5jb2RlciwgbmFtZTogc3RyaW5nKSA9PiB7XG4gIE9wdXMgPSB7IEVuY29kZXI6IHByb3ZpZGVyLCBuYW1lIH07XG59O1xuXG5mdW5jdGlvbiBsb2FkT3B1cyhyZWZyZXNoID0gZmFsc2UpIHtcbiAgaWYgKE9wdXMuRW5jb2RlciAmJiAhcmVmcmVzaCkgcmV0dXJuIE9wdXM7XG5cbiAgT3B1cyA9IGxvYWRNb2R1bGUoT1BVU19NT0RfUkVHSVNUUlkpO1xuICByZXR1cm4gT3B1cztcbn1cblxuY29uc3QgY2hhckNvZGUgPSAoeDogc3RyaW5nKSA9PiB4LmNoYXJDb2RlQXQoMCk7XG5jb25zdCBPUFVTX0hFQUQgPSBCdWZmZXIuZnJvbShbLi4uJ09wdXNIZWFkJ10ubWFwKGNoYXJDb2RlKSk7XG5jb25zdCBPUFVTX1RBR1MgPSBCdWZmZXIuZnJvbShbLi4uJ09wdXNUYWdzJ10ubWFwKGNoYXJDb2RlKSk7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSU9wdXNTdHJlYW1Jbml0IHtcbiAgZnJhbWVTaXplOiBudW1iZXI7XG4gIGNoYW5uZWxzOiBudW1iZXI7XG4gIHJhdGU6IG51bWJlcjtcbiAgYXBwbGljYXRpb24/OiBudW1iZXI7XG59XG5cbi8vIGZyYW1lIHNpemUgPSAoY2hhbm5lbHMgKiByYXRlICogZnJhbWVfZHVyYXRpb24pIC8gMTAwMFxuXG4vKipcbiAqIFRha2VzIGEgc3RyZWFtIG9mIE9wdXMgZGF0YSBhbmQgb3V0cHV0cyBhIHN0cmVhbSBvZiBQQ00gZGF0YSwgb3IgdGhlIGludmVyc2UuXG4gKiAqKllvdSBzaG91bGRuJ3QgZGlyZWN0bHkgaW5zdGFudGlhdGUgdGhpcyBjbGFzcywgc2VlIG9wdXMuRW5jb2RlciBhbmQgb3B1cy5EZWNvZGVyIGluc3RlYWQhKipcbiAqIEBtZW1iZXJvZiBvcHVzXG4gKiBAZXh0ZW5kcyBUcmFuc2Zvcm1TdHJlYW1cbiAqIEBwcm90ZWN0ZWRcbiAqL1xuZXhwb3J0IGNsYXNzIE9wdXNTdHJlYW0gZXh0ZW5kcyBUcmFuc2Zvcm0ge1xuICBwdWJsaWMgZW5jb2RlcjogSW5zdGFuY2VUeXBlPElFbmNvZGVyPiB8IG51bGwgPSBudWxsO1xuICBwdWJsaWMgX29wdGlvbnM6IElPcHVzU3RyZWFtSW5pdDtcbiAgcHVibGljIF9yZXF1aXJlZDogbnVtYmVyO1xuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBPcHVzIHRyYW5zZm9ybWVyLlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAbWVtYmVyb2Ygb3B1c1xuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIG9wdGlvbnMgdGhhdCB5b3Ugd291bGQgcGFzcyB0byBhIHJlZ3VsYXIgVHJhbnNmb3JtIHN0cmVhbVxuICAgKi9cbiAgY29uc3RydWN0b3Iob3B0aW9ucyA9IHt9IGFzIElPcHVzU3RyZWFtSW5pdCkge1xuICAgIGlmICghbG9hZE9wdXMoKS5FbmNvZGVyKSB7XG4gICAgICB0aHJvdyBFcnJvcihcbiAgICAgICAgYENvdWxkIG5vdCBmaW5kIGFuIE9wdXMgbW9kdWxlISBQbGVhc2UgaW5zdGFsbCBvbmUgb2YgJHtPUFVTX01PRF9SRUdJU1RSWS5tYXAoXG4gICAgICAgICAgKG8pID0+IG9bMF1cbiAgICAgICAgKS5qb2luKCcsICcpfS5gXG4gICAgICApO1xuICAgIH1cbiAgICBzdXBlcihPYmplY3QuYXNzaWduKHsgcmVhZGFibGVPYmplY3RNb2RlOiB0cnVlIH0sIG9wdGlvbnMpKTtcblxuICAgIGNvbnN0IGxpYiA9IE9wdXMgYXMgUmVxdWlyZWQ8dHlwZW9mIE9wdXM+O1xuXG4gICAgaWYgKGxpYi5uYW1lID09PSAnb3B1c3NjcmlwdCcpIHtcbiAgICAgIG9wdGlvbnMuYXBwbGljYXRpb24gPSBsaWIuRW5jb2Rlci5BcHBsaWNhdGlvbiFbb3B0aW9ucy5hcHBsaWNhdGlvbiFdO1xuICAgIH1cblxuICAgIHRoaXMuZW5jb2RlciA9IG5ldyBsaWIuRW5jb2RlcihcbiAgICAgIG9wdGlvbnMucmF0ZSxcbiAgICAgIG9wdGlvbnMuY2hhbm5lbHMsXG4gICAgICBvcHRpb25zLmFwcGxpY2F0aW9uIVxuICAgICk7XG5cbiAgICB0aGlzLl9vcHRpb25zID0gb3B0aW9ucztcbiAgICB0aGlzLl9yZXF1aXJlZCA9IHRoaXMuX29wdGlvbnMuZnJhbWVTaXplICogdGhpcy5fb3B0aW9ucy5jaGFubmVscyAqIDI7XG4gIH1cblxuICBfZW5jb2RlKGJ1ZmZlcjogQnVmZmVyKSB7XG4gICAgaWYgKE9wdXMubmFtZSA9PT0gJ29wdXNzY3JpcHQnKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmNvZGVyIS5lbmNvZGUoYnVmZmVyLCB0aGlzLl9vcHRpb25zLmZyYW1lU2l6ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLmVuY29kZXIhLmVuY29kZShidWZmZXIpO1xuICAgIH1cbiAgfVxuXG4gIF9kZWNvZGUoYnVmZmVyOiBCdWZmZXIpIHtcbiAgICBpZiAoT3B1cy5uYW1lID09PSAnb3B1c3NjcmlwdCcpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuY29kZXIhLmRlY29kZShidWZmZXIsIHRoaXMuX29wdGlvbnMuZnJhbWVTaXplKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuZW5jb2RlciEuZGVjb2RlKGJ1ZmZlcik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIE9wdXMgbW9kdWxlIGJlaW5nIHVzZWQgLSBgbWVkaWFwbGV4YCwgYG9wdXNzY3JpcHRgLCBgbm9kZS1vcHVzYCwgb3IgYEBkaXNjb3JkanMvb3B1c2AuXG4gICAqIEB0eXBlIHtzdHJpbmd9XG4gICAqIEByZWFkb25seVxuICAgKiBAZXhhbXBsZVxuICAgKiBjb25zb2xlLmxvZyhgVXNpbmcgT3B1cyBtb2R1bGUgJHtPcHVzRW5jb2Rlci50eXBlfWApO1xuICAgKi9cbiAgc3RhdGljIGdldCB0eXBlKCkge1xuICAgIHJldHVybiBPcHVzLm5hbWU7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgYml0cmF0ZSBvZiB0aGUgc3RyZWFtLlxuICAgKiBAcGFyYW0ge251bWJlcn0gYml0cmF0ZSB0aGUgYml0cmF0ZSB0byB1c2UgdXNlLCBlLmcuIDQ4MDAwXG4gICAqIEBwdWJsaWNcbiAgICovXG4gIHNldEJpdHJhdGUoYml0cmF0ZTogbnVtYmVyKSB7XG4gICAgKHRoaXMuZW5jb2RlciEuYXBwbHlFbmNvZGVyQ1RMISB8fCB0aGlzLmVuY29kZXIhLmVuY29kZXJDVEwpLmFwcGx5KFxuICAgICAgdGhpcy5lbmNvZGVyISxcbiAgICAgIFtDVEwuQklUUkFURSwgTWF0aC5taW4oMTI4ZTMsIE1hdGgubWF4KDE2ZTMsIGJpdHJhdGUpKV1cbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEVuYWJsZXMgb3IgZGlzYWJsZXMgZm9yd2FyZCBlcnJvciBjb3JyZWN0aW9uLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IGVuYWJsZWQgd2hldGhlciBvciBub3QgdG8gZW5hYmxlIEZFQy5cbiAgICogQHB1YmxpY1xuICAgKi9cbiAgc2V0RkVDKGVuYWJsZWQ6IGJvb2xlYW4pIHtcbiAgICAodGhpcy5lbmNvZGVyIS5hcHBseUVuY29kZXJDVEwhIHx8IHRoaXMuZW5jb2RlciEuZW5jb2RlckNUTCkuYXBwbHkoXG4gICAgICB0aGlzLmVuY29kZXIhLFxuICAgICAgW0NUTC5GRUMsIGVuYWJsZWQgPyAxIDogMF1cbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIGV4cGVjdGVkIHBhY2tldCBsb3NzIG92ZXIgbmV0d29yayB0cmFuc21pc3Npb24uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbcGVyY2VudGFnZV0gYSBwZXJjZW50YWdlIChyZXByZXNlbnRlZCBiZXR3ZWVuIDAgYW5kIDEpXG4gICAqL1xuICBzZXRQTFAocGVyY2VudGFnZTogbnVtYmVyKSB7XG4gICAgKHRoaXMuZW5jb2RlciEuYXBwbHlFbmNvZGVyQ1RMISB8fCB0aGlzLmVuY29kZXIhLmVuY29kZXJDVEwpLmFwcGx5KFxuICAgICAgdGhpcy5lbmNvZGVyISxcbiAgICAgIFtDVEwuUExQLCBNYXRoLm1pbigxMDAsIE1hdGgubWF4KDAsIHBlcmNlbnRhZ2UgKiAxMDApKV1cbiAgICApO1xuICB9XG5cbiAgX2ZpbmFsKGNiOiAoKSA9PiB2b2lkKSB7XG4gICAgdGhpcy5fY2xlYW51cCgpO1xuICAgIGNiKCk7XG4gIH1cblxuICBfZGVzdHJveShlcnI6IEVycm9yIHwgbnVsbCwgY2I6IChlcnI6IEVycm9yIHwgbnVsbCkgPT4gdm9pZCkge1xuICAgIHRoaXMuX2NsZWFudXAoKTtcbiAgICByZXR1cm4gY2IgPyBjYihlcnIpIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFucyB1cCB0aGUgT3B1cyBzdHJlYW0gd2hlbiBpdCBpcyBubyBsb25nZXIgbmVlZGVkXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBfY2xlYW51cCgpIHtcbiAgICBpZiAodHlwZW9mIHRoaXMuZW5jb2Rlcj8uZGVsZXRlID09PSAnZnVuY3Rpb24nKSB0aGlzLmVuY29kZXIhLmRlbGV0ZSEoKTtcbiAgICB0aGlzLmVuY29kZXIgPSBudWxsO1xuICB9XG59XG5cbi8qKlxuICogQW4gT3B1cyBlbmNvZGVyIHN0cmVhbS5cbiAqXG4gKiBPdXRwdXRzIG9wdXMgcGFja2V0cyBpbiBbb2JqZWN0IG1vZGUuXShodHRwczovL25vZGVqcy5vcmcvYXBpL3N0cmVhbS5odG1sI3N0cmVhbV9vYmplY3RfbW9kZSlcbiAqIEBleHRlbmRzIG9wdXMuT3B1c1N0cmVhbVxuICogQG1lbWJlcm9mIG9wdXNcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBlbmNvZGVyID0gbmV3IHByaXNtLm9wdXMuRW5jb2Rlcih7IGZyYW1lU2l6ZTogOTYwLCBjaGFubmVsczogMiwgcmF0ZTogNDgwMDAgfSk7XG4gKiBwY21BdWRpby5waXBlKGVuY29kZXIpO1xuICogLy8gZW5jb2RlciB3aWxsIG5vdyBvdXRwdXQgT3B1cy1lbmNvZGVkIGF1ZGlvIHBhY2tldHNcbiAqL1xuZXhwb3J0IGNsYXNzIE9wdXNFbmNvZGVyIGV4dGVuZHMgT3B1c1N0cmVhbSB7XG4gIF9idWZmZXI6IEJ1ZmZlciA9IEJ1ZmZlci5hbGxvY1Vuc2FmZSgwKTtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBPcHVzIGVuY29kZXIgc3RyZWFtLlxuICAgKiBAbWVtYmVyb2Ygb3B1c1xuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBvcHRpb25zIHRoYXQgeW91IHdvdWxkIHBhc3MgdG8gYSByZWd1bGFyIE9wdXNTdHJlYW0sIHBsdXMgYSBmZXcgbW9yZTpcbiAgICogQHBhcmFtIHtudW1iZXJ9IG9wdGlvbnMuZnJhbWVTaXplIHRoZSBmcmFtZSBzaXplIGluIGJ5dGVzIHRvIHVzZSAoZS5nLiA5NjAgZm9yIHN0ZXJlbyBhdWRpbyBhdCA0OEtIeiB3aXRoIGEgZnJhbWVcbiAgICogZHVyYXRpb24gb2YgMjBtcylcbiAgICogQHBhcmFtIHtudW1iZXJ9IG9wdGlvbnMuY2hhbm5lbHMgdGhlIG51bWJlciBvZiBjaGFubmVscyB0byB1c2VcbiAgICogQHBhcmFtIHtudW1iZXJ9IG9wdGlvbnMucmF0ZSB0aGUgc2FtcGxpbmcgcmF0ZSBpbiBIelxuICAgKi9cbiAgY29uc3RydWN0b3Iob3B0aW9ucyA9IHt9IGFzIElPcHVzU3RyZWFtSW5pdCkge1xuICAgIHN1cGVyKG9wdGlvbnMpO1xuICB9XG5cbiAgcHVibGljIF90cmFuc2Zvcm0oXG4gIG5ld0NodW5rOiBCdWZmZXIsXG4gIGVuY29kaW5nOiBCdWZmZXJFbmNvZGluZyxcbiAgZG9uZTogVHJhbnNmb3JtQ2FsbGJhY2spXG4gIDogdm9pZCB7XG4gICAgY29uc3QgY2h1bmsgPSBCdWZmZXIuY29uY2F0KFt0aGlzLl9idWZmZXIsIG5ld0NodW5rXSk7XG5cbiAgICBsZXQgaSA9IDA7XG4gICAgd2hpbGUgKGNodW5rLmxlbmd0aCA+PSBpICsgdGhpcy5fcmVxdWlyZWQpIHtcbiAgICAgIGNvbnN0IHBjbSA9IGNodW5rLnNsaWNlKGksIGkgKyB0aGlzLl9yZXF1aXJlZCk7XG4gICAgICBsZXQgb3B1czogQnVmZmVyIHwgdW5kZWZpbmVkO1xuICAgICAgdHJ5IHtcbiAgICAgICAgb3B1cyA9IHRoaXMuZW5jb2RlciEuZW5jb2RlKHBjbSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBkb25lKGVycm9yIGFzIEVycm9yKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5wdXNoKG9wdXMpO1xuICAgICAgaSArPSB0aGlzLl9yZXF1aXJlZDtcbiAgICB9XG5cbiAgICBpZiAoaSA+IDApIHRoaXMuX2J1ZmZlciA9IGNodW5rLnNsaWNlKGkpO1xuICAgIGRvbmUoKTtcbiAgfVxuXG4gIF9kZXN0cm95KGVycjogRXJyb3IsIGNiOiAoZXJyOiBFcnJvciB8IG51bGwpID0+IHZvaWQpIHtcbiAgICBzdXBlci5fZGVzdHJveShlcnIsIGNiKTtcbiAgICB0aGlzLl9idWZmZXIgPSBCdWZmZXIuYWxsb2NVbnNhZmUoMCk7XG4gIH1cbn1cblxuLyoqXG4gKiBBbiBPcHVzIGRlY29kZXIgc3RyZWFtLlxuICpcbiAqIE5vdGUgdGhhdCBhbnkgc3RyZWFtIHlvdSBwaXBlIGludG8gdGhpcyBtdXN0IGJlIGluXG4gKiBbb2JqZWN0IG1vZGVdKGh0dHBzOi8vbm9kZWpzLm9yZy9hcGkvc3RyZWFtLmh0bWwjc3RyZWFtX29iamVjdF9tb2RlKSBhbmQgc2hvdWxkIG91dHB1dCBPcHVzIHBhY2tldHMuXG4gKiBAZXh0ZW5kcyBvcHVzLk9wdXNTdHJlYW1cbiAqIEBtZW1iZXJvZiBvcHVzXG4gKiBAZXhhbXBsZVxuICogY29uc3QgZGVjb2RlciA9IG5ldyBPcHVzRGVjb2Rlcih7IGZyYW1lU2l6ZTogOTYwLCBjaGFubmVsczogMiwgcmF0ZTogNDgwMDAgfSk7XG4gKiBpbnB1dC5waXBlKGRlY29kZXIpO1xuICogLy8gZGVjb2RlciB3aWxsIG5vdyBvdXRwdXQgUENNIGF1ZGlvXG4gKi9cbmV4cG9ydCBjbGFzcyBPcHVzRGVjb2RlciBleHRlbmRzIE9wdXNTdHJlYW0ge1xuICBfdHJhbnNmb3JtKFxuICBjaHVuazogQnVmZmVyLFxuICBlbmNvZGluZzogQnVmZmVyRW5jb2RpbmcsXG4gIGRvbmU6IChlPzogRXJyb3IgfCBudWxsLCBjaHVuaz86IEJ1ZmZlcikgPT4gdm9pZClcbiAge1xuICAgIGNvbnN0IHNpZ25hdHVyZSA9IGNodW5rLnNsaWNlKDAsIDgpO1xuICAgIGlmIChjaHVuay5sZW5ndGggPj0gOCAmJiBzaWduYXR1cmUuZXF1YWxzKE9QVVNfSEVBRCkpIHtcbiAgICAgIHRoaXMuZW1pdCgnZm9ybWF0Jywge1xuICAgICAgICBjaGFubmVsczogdGhpcy5fb3B0aW9ucy5jaGFubmVscyxcbiAgICAgICAgc2FtcGxlUmF0ZTogdGhpcy5fb3B0aW9ucy5yYXRlLFxuICAgICAgICBiaXREZXB0aDogMTYsXG4gICAgICAgIGZsb2F0OiBmYWxzZSxcbiAgICAgICAgc2lnbmVkOiB0cnVlLFxuICAgICAgICB2ZXJzaW9uOiBjaHVuay5yZWFkVUludDgoOCksXG4gICAgICAgIHByZVNraXA6IGNodW5rLnJlYWRVSW50MTZMRSgxMCksXG4gICAgICAgIGdhaW46IGNodW5rLnJlYWRVSW50MTZMRSgxNilcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGRvbmUoKTtcbiAgICB9XG4gICAgaWYgKGNodW5rLmxlbmd0aCA+PSA4ICYmIHNpZ25hdHVyZS5lcXVhbHMoT1BVU19UQUdTKSkge1xuICAgICAgdGhpcy5lbWl0KCd0YWdzJywgY2h1bmspO1xuICAgICAgcmV0dXJuIGRvbmUoKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMucHVzaCh0aGlzLl9kZWNvZGUoY2h1bmspKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gZG9uZShlIGFzIEVycm9yKTtcbiAgICB9XG4gICAgcmV0dXJuIGRvbmUoKTtcbiAgfVxufSIsICIvLyBiYXNlZCBvbiBodHRwczovL2dpdGh1Yi5jb20vYW1pc2hzaGFoL3ByaXNtLW1lZGlhL2Jsb2IvNGVmMWQ2ZjlmNTMwNDJjMDg1YzFmNjg2MjdlODg5MDAzZTI0OGQ3Ny9zcmMvY29yZS9XZWJtQmFzZS5qc1xuXG5pbXBvcnQgeyBUcmFuc2Zvcm0sIFRyYW5zZm9ybUNhbGxiYWNrIH0gZnJvbSAnbm9kZTpzdHJlYW0nO1xuXG5leHBvcnQgY2xhc3MgV2VibUJhc2VEZW11eGVyIGV4dGVuZHMgVHJhbnNmb3JtIHtcbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBUQUdTID0ge1xuICAgIC8vIHZhbHVlIGlzIHRydWUgaWYgdGhlIGVsZW1lbnQgaGFzIGNoaWxkcmVuXG4gICAgJzFhNDVkZmEzJzogdHJ1ZSwgLy8gRUJNTFxuICAgICcxODUzODA2Nyc6IHRydWUsIC8vIFNlZ21lbnRcbiAgICAnMWY0M2I2NzUnOiB0cnVlLCAvLyBDbHVzdGVyXG4gICAgJzE2NTRhZTZiJzogdHJ1ZSwgLy8gVHJhY2tzXG4gICAgYWU6IHRydWUsIC8vIFRyYWNrRW50cnlcbiAgICBkNzogZmFsc2UsIC8vIFRyYWNrTnVtYmVyXG4gICAgJzgzJzogZmFsc2UsIC8vIFRyYWNrVHlwZVxuICAgIGEzOiBmYWxzZSwgLy8gU2ltcGxlQmxvY2tcbiAgICAnNjNhMic6IGZhbHNlXG4gIH07XG5cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBUT09fU0hPUlQgPSBTeW1ib2woJ1RPT19TSE9SVCcpO1xuXG4gIHByaXZhdGUgX3JlbWFpbmRlcjogQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgX2xlbmd0aCA9IDA7XG4gIHByaXZhdGUgX2NvdW50ID0gMDtcbiAgcHJpdmF0ZSBfc2tpcFVudGlsOiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBfdHJhY2s6IHtudW1iZXI6IG51bWJlcjt0eXBlOiBudW1iZXI7fSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIF9pbmNvbXBsZXRlVHJhY2s6IHtudW1iZXI/OiBudW1iZXI7dHlwZT86IG51bWJlcjt9ID0ge307XG4gIHByaXZhdGUgX2VibWxGb3VuZCA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IFdlYm0gZGVtdXhlci5cbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSBvcHRpb25zIHRoYXQgeW91IHdvdWxkIHBhc3MgdG8gYSByZWd1bGFyIFRyYW5zZm9ybSBzdHJlYW0uXG4gICAqL1xuICBjb25zdHJ1Y3RvcihvcHRpb25zID0ge30pIHtcbiAgICBzdXBlcihPYmplY3QuYXNzaWduKHsgcmVhZGFibGVPYmplY3RNb2RlOiB0cnVlIH0sIG9wdGlvbnMpKTtcbiAgICB0aGlzLl9yZW1haW5kZXIgPSBudWxsO1xuICAgIHRoaXMuX2xlbmd0aCA9IDA7XG4gICAgdGhpcy5fY291bnQgPSAwO1xuICAgIHRoaXMuX3NraXBVbnRpbCA9IG51bGw7XG4gICAgdGhpcy5fdHJhY2sgPSBudWxsO1xuICAgIHRoaXMuX2luY29tcGxldGVUcmFjayA9IHt9O1xuICAgIHRoaXMuX2VibWxGb3VuZCA9IGZhbHNlO1xuICB9XG5cbiAgcHVibGljIF9jaGVja0hlYWQoZGF0YTogQnVmZmVyKSB7XG4gICAgdm9pZCBkYXRhO1xuICB9XG5cbiAgX3RyYW5zZm9ybShjaHVuazogQnVmZmVyLCBlbmNvZGluZzogQnVmZmVyRW5jb2RpbmcsIGRvbmU6IFRyYW5zZm9ybUNhbGxiYWNrKSB7XG4gICAgdGhpcy5fbGVuZ3RoICs9IGNodW5rLmxlbmd0aDtcbiAgICBpZiAodGhpcy5fcmVtYWluZGVyKSB7XG4gICAgICBjaHVuayA9IEJ1ZmZlci5jb25jYXQoW3RoaXMuX3JlbWFpbmRlciwgY2h1bmtdKTtcbiAgICAgIHRoaXMuX3JlbWFpbmRlciA9IG51bGw7XG4gICAgfVxuICAgIGxldCBvZmZzZXQgPSAwO1xuICAgIGlmICh0aGlzLl9za2lwVW50aWwgJiYgdGhpcy5fbGVuZ3RoID4gdGhpcy5fc2tpcFVudGlsKSB7XG4gICAgICBvZmZzZXQgPSB0aGlzLl9za2lwVW50aWwgLSB0aGlzLl9jb3VudDtcbiAgICAgIHRoaXMuX3NraXBVbnRpbCA9IG51bGw7XG4gICAgfSBlbHNlIGlmICh0aGlzLl9za2lwVW50aWwpIHtcbiAgICAgIHRoaXMuX2NvdW50ICs9IGNodW5rLmxlbmd0aDtcbiAgICAgIGRvbmUoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsZXQgcmVzdWx0O1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICB3aGlsZSAocmVzdWx0ICE9PSBXZWJtQmFzZURlbXV4ZXIuVE9PX1NIT1JUKSB7XG4gICAgICB0cnkge1xuICAgICAgICByZXN1bHQgPSB0aGlzLl9yZWFkVGFnKGNodW5rLCBvZmZzZXQpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgZG9uZShlcnJvciBhcyBFcnJvcik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChyZXN1bHQgPT09IFdlYm1CYXNlRGVtdXhlci5UT09fU0hPUlQpIGJyZWFrO1xuICAgICAgaWYgKHJlc3VsdC5fc2tpcFVudGlsKSB7XG4gICAgICAgIHRoaXMuX3NraXBVbnRpbCA9IHJlc3VsdC5fc2tpcFVudGlsO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmIChyZXN1bHQub2Zmc2V0KSBvZmZzZXQgPSByZXN1bHQub2Zmc2V0O2Vsc2VcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICB0aGlzLl9jb3VudCArPSBvZmZzZXQ7XG4gICAgdGhpcy5fcmVtYWluZGVyID0gY2h1bmsuc3ViYXJyYXkob2Zmc2V0KTtcbiAgICBkb25lKCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlYWRzIGFuIEVCTUwgSUQgZnJvbSBhIGJ1ZmZlci5cbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtCdWZmZXJ9IGNodW5rIHRoZSBidWZmZXIgdG8gcmVhZCBmcm9tLlxuICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IHRoZSBvZmZzZXQgaW4gdGhlIGJ1ZmZlci5cbiAgICogQHJldHVybnMge09iamVjdHxTeW1ib2x9IGNvbnRhaW5zIGFuIGBpZGAgcHJvcGVydHkgKGJ1ZmZlcikgYW5kIHRoZSBuZXcgYG9mZnNldGAgKG51bWJlcikuXG4gICAqIFJldHVybnMgdGhlIFRPT19TSE9SVCBzeW1ib2wgaWYgdGhlIGRhdGEgd2Fzbid0IGJpZyBlbm91Z2ggdG8gZmFjaWxpdGF0ZSB0aGUgcmVxdWVzdC5cbiAgICovXG4gIF9yZWFkRUJNTElkKGNodW5rOiBCdWZmZXIsIG9mZnNldDogbnVtYmVyKSB7XG4gICAgY29uc3QgaWRMZW5ndGggPSB2aW50TGVuZ3RoKGNodW5rLCBvZmZzZXQpO1xuICAgIGlmIChpZExlbmd0aCA9PT0gV2VibUJhc2VEZW11eGVyLlRPT19TSE9SVClcbiAgICByZXR1cm4gV2VibUJhc2VEZW11eGVyLlRPT19TSE9SVDtcbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IGNodW5rLnN1YmFycmF5KG9mZnNldCwgb2Zmc2V0ICsgaWRMZW5ndGgpLFxuICAgICAgb2Zmc2V0OiBvZmZzZXQgKyBpZExlbmd0aFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogUmVhZHMgYSBzaXplIHZhcmlhYmxlLWludGVnZXIgdG8gY2FsY3VsYXRlIHRoZSBsZW5ndGggb2YgdGhlIGRhdGEgb2YgYSB0YWcuXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QnVmZmVyfSBjaHVuayB0aGUgYnVmZmVyIHRvIHJlYWQgZnJvbS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCB0aGUgb2Zmc2V0IGluIHRoZSBidWZmZXIuXG4gICAqIEByZXR1cm5zIHtPYmplY3R8U3ltYm9sfSBjb250YWlucyBwcm9wZXJ0eSBgb2Zmc2V0YCAobnVtYmVyKSwgYGRhdGFMZW5ndGhgIChudW1iZXIpIGFuZCBgc2l6ZUxlbmd0aGAgKG51bWJlcikuXG4gICAqIFJldHVybnMgdGhlIFRPT19TSE9SVCBzeW1ib2wgaWYgdGhlIGRhdGEgd2Fzbid0IGJpZyBlbm91Z2ggdG8gZmFjaWxpdGF0ZSB0aGUgcmVxdWVzdC5cbiAgICovXG4gIF9yZWFkVGFnRGF0YVNpemUoY2h1bms6IEJ1ZmZlciwgb2Zmc2V0OiBudW1iZXIpIHtcbiAgICBjb25zdCBzaXplTGVuZ3RoID0gdmludExlbmd0aChjaHVuaywgb2Zmc2V0KTtcbiAgICBpZiAoc2l6ZUxlbmd0aCA9PT0gV2VibUJhc2VEZW11eGVyLlRPT19TSE9SVClcbiAgICByZXR1cm4gV2VibUJhc2VEZW11eGVyLlRPT19TSE9SVDtcbiAgICBjb25zdCBkYXRhTGVuZ3RoID0gZXhwYW5kVmludChjaHVuaywgb2Zmc2V0LCBvZmZzZXQgKyBzaXplTGVuZ3RoKTtcbiAgICByZXR1cm4geyBvZmZzZXQ6IG9mZnNldCArIHNpemVMZW5ndGgsIGRhdGFMZW5ndGgsIHNpemVMZW5ndGggfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUYWtlcyBhIGJ1ZmZlciBhbmQgYXR0ZW1wdHMgdG8gcmVhZCBhbmQgcHJvY2VzcyBhIHRhZy5cbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtCdWZmZXJ9IGNodW5rIHRoZSBidWZmZXIgdG8gcmVhZCBmcm9tLlxuICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IHRoZSBvZmZzZXQgaW4gdGhlIGJ1ZmZlci5cbiAgICogQHJldHVybnMge09iamVjdHxTeW1ib2x9IGNvbnRhaW5zIHRoZSBuZXcgYG9mZnNldGAgKG51bWJlcikgYW5kIG9wdGlvbmFsbHkgdGhlIGBfc2tpcFVudGlsYCBwcm9wZXJ0eSxcbiAgICogaW5kaWNhdGluZyB0aGF0IHRoZSBzdHJlYW0gc2hvdWxkIGlnbm9yZSBhbnkgZGF0YSB1bnRpbCBhIGNlcnRhaW4gbGVuZ3RoIGlzIHJlYWNoZWQuXG4gICAqIFJldHVybnMgdGhlIFRPT19TSE9SVCBzeW1ib2wgaWYgdGhlIGRhdGEgd2Fzbid0IGJpZyBlbm91Z2ggdG8gZmFjaWxpdGF0ZSB0aGUgcmVxdWVzdC5cbiAgICovXG4gIF9yZWFkVGFnKGNodW5rOiBCdWZmZXIsIG9mZnNldDogbnVtYmVyKSB7XG4gICAgY29uc3QgaWREYXRhID0gdGhpcy5fcmVhZEVCTUxJZChjaHVuaywgb2Zmc2V0KTtcbiAgICBpZiAoaWREYXRhID09PSBXZWJtQmFzZURlbXV4ZXIuVE9PX1NIT1JUKSByZXR1cm4gV2VibUJhc2VEZW11eGVyLlRPT19TSE9SVDtcbiAgICBjb25zdCBlYm1sSUQgPSBpZERhdGEuaWQudG9TdHJpbmcoJ2hleCcpO1xuICAgIGlmICghdGhpcy5fZWJtbEZvdW5kKSB7XG4gICAgICBpZiAoZWJtbElEID09PSAnMWE0NWRmYTMnKSB0aGlzLl9lYm1sRm91bmQgPSB0cnVlO2Vsc2VcbiAgICAgIHRocm93IEVycm9yKCdEaWQgbm90IGZpbmQgdGhlIEVCTUwgdGFnIGF0IHRoZSBzdGFydCBvZiB0aGUgc3RyZWFtJyk7XG4gICAgfVxuICAgIG9mZnNldCA9IGlkRGF0YS5vZmZzZXQ7XG4gICAgY29uc3Qgc2l6ZURhdGEgPSB0aGlzLl9yZWFkVGFnRGF0YVNpemUoY2h1bmssIG9mZnNldCk7XG4gICAgaWYgKHNpemVEYXRhID09PSBXZWJtQmFzZURlbXV4ZXIuVE9PX1NIT1JUKVxuICAgIHJldHVybiBXZWJtQmFzZURlbXV4ZXIuVE9PX1NIT1JUO1xuICAgIGNvbnN0IHsgZGF0YUxlbmd0aCB9ID0gc2l6ZURhdGE7XG4gICAgb2Zmc2V0ID0gc2l6ZURhdGEub2Zmc2V0O1xuICAgIC8vIElmIHRoaXMgdGFnIGlzbid0IHVzZWZ1bCwgdGVsbCB0aGUgc3RyZWFtIHRvIHN0b3AgcHJvY2Vzc2luZyBkYXRhIHVudGlsIHRoZSB0YWcgZW5kc1xuICAgIGlmIChcbiAgICB0eXBlb2YgV2VibUJhc2VEZW11eGVyLlRBR1NbXG4gICAgZWJtbElEIGFzIGtleW9mICh0eXBlb2YgV2VibUJhc2VEZW11eGVyKVsnVEFHUyddXSA9PT1cbiAgICAndW5kZWZpbmVkJylcbiAgICB7XG4gICAgICBpZiAoY2h1bmsubGVuZ3RoID4gb2Zmc2V0ICsgKGRhdGFMZW5ndGggYXMgbnVtYmVyKSkge1xuICAgICAgICByZXR1cm4geyBvZmZzZXQ6IG9mZnNldCArIChkYXRhTGVuZ3RoIGFzIG51bWJlcikgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7XG4gICAgICAgIG9mZnNldCxcbiAgICAgICAgX3NraXBVbnRpbDogdGhpcy5fY291bnQgKyAob2Zmc2V0IGFzIG51bWJlcikgKyAoZGF0YUxlbmd0aCBhcyBudW1iZXIpXG4gICAgICB9O1xuICAgIH1cblxuICAgIGNvbnN0IHRhZ0hhc0NoaWxkcmVuID1cbiAgICBXZWJtQmFzZURlbXV4ZXIuVEFHU1tlYm1sSUQgYXMga2V5b2YgKHR5cGVvZiBXZWJtQmFzZURlbXV4ZXIpWydUQUdTJ11dO1xuICAgIGlmICh0YWdIYXNDaGlsZHJlbikge1xuICAgICAgcmV0dXJuIHsgb2Zmc2V0IH07XG4gICAgfVxuXG4gICAgaWYgKChvZmZzZXQgYXMgbnVtYmVyKSArIChkYXRhTGVuZ3RoIGFzIG51bWJlcikgPiBjaHVuay5sZW5ndGgpXG4gICAgcmV0dXJuIFdlYm1CYXNlRGVtdXhlci5UT09fU0hPUlQ7XG4gICAgY29uc3QgZGF0YSA9IGNodW5rLnN1YmFycmF5KFxuICAgICAgb2Zmc2V0LFxuICAgICAgKG9mZnNldCBhcyBudW1iZXIpICsgKGRhdGFMZW5ndGggYXMgbnVtYmVyKVxuICAgICk7XG4gICAgaWYgKCF0aGlzLl90cmFjaykge1xuICAgICAgaWYgKGVibWxJRCA9PT0gJ2FlJykgdGhpcy5faW5jb21wbGV0ZVRyYWNrID0ge307XG4gICAgICBpZiAoZWJtbElEID09PSAnZDcnKSB0aGlzLl9pbmNvbXBsZXRlVHJhY2subnVtYmVyID0gZGF0YVswXTtcbiAgICAgIGlmIChlYm1sSUQgPT09ICc4MycpIHRoaXMuX2luY29tcGxldGVUcmFjay50eXBlID0gZGF0YVswXTtcbiAgICAgIGlmIChcbiAgICAgIHRoaXMuX2luY29tcGxldGVUcmFjay50eXBlID09PSAyICYmXG4gICAgICB0eXBlb2YgdGhpcy5faW5jb21wbGV0ZVRyYWNrLm51bWJlciAhPT0gJ3VuZGVmaW5lZCcpXG4gICAgICB7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy5fdHJhY2sgPSB0aGlzLl9pbmNvbXBsZXRlVHJhY2s7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlYm1sSUQgPT09ICc2M2EyJykge1xuICAgICAgdGhpcy5fY2hlY2tIZWFkKGRhdGEpO1xuICAgICAgdGhpcy5lbWl0KCdoZWFkJywgZGF0YSk7XG4gICAgfSBlbHNlIGlmIChlYm1sSUQgPT09ICdhMycpIHtcbiAgICAgIGlmICghdGhpcy5fdHJhY2spIHRocm93IEVycm9yKCdObyBhdWRpbyB0cmFjayBpbiB0aGlzIHdlYm0hJyk7XG4gICAgICBpZiAoKGRhdGFbMF0gJiAweGYpID09PSB0aGlzLl90cmFjay5udW1iZXIpIHtcbiAgICAgICAgdGhpcy5wdXNoKGRhdGEuc3ViYXJyYXkoNCkpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4geyBvZmZzZXQ6IChvZmZzZXQgYXMgbnVtYmVyKSArIChkYXRhTGVuZ3RoIGFzIG51bWJlcikgfTtcbiAgfVxuXG4gIF9kZXN0cm95KGVycjogRXJyb3IsIGNiOiAoZXJyb3I6IEVycm9yIHwgbnVsbCkgPT4gdm9pZCkge1xuICAgIHRoaXMuX2NsZWFudXAoKTtcbiAgICByZXR1cm4gY2IgPyBjYihlcnIpIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgX2ZpbmFsKGNiOiBUcmFuc2Zvcm1DYWxsYmFjaykge1xuICAgIHRoaXMuX2NsZWFudXAoKTtcbiAgICBjYigpO1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFucyB1cCB0aGUgZGVtdXhlciB3aGVuIGl0IGlzIG5vIGxvbmdlciByZXF1aXJlZC5cbiAgICogQHByaXZhdGVcbiAgICovXG4gIF9jbGVhbnVwKCkge1xuICAgIHRoaXMuX3JlbWFpbmRlciA9IG51bGw7XG4gICAgdGhpcy5faW5jb21wbGV0ZVRyYWNrID0ge307XG4gIH1cbn1cblxuZnVuY3Rpb24gdmludExlbmd0aChidWZmZXI6IEJ1ZmZlciwgaW5kZXg6IG51bWJlcikge1xuICBpZiAoaW5kZXggPCAwIHx8IGluZGV4ID4gYnVmZmVyLmxlbmd0aCAtIDEpIHtcbiAgICByZXR1cm4gV2VibUJhc2VEZW11eGVyLlRPT19TSE9SVDtcbiAgfVxuICBsZXQgaSA9IDA7XG4gIGZvciAoOyBpIDwgODsgaSsrKSBpZiAoMSA8PCA3IC0gaSAmIGJ1ZmZlcltpbmRleF0pIGJyZWFrO1xuICBpKys7XG4gIGlmIChpbmRleCArIGkgPiBidWZmZXIubGVuZ3RoKSB7XG4gICAgcmV0dXJuIFdlYm1CYXNlRGVtdXhlci5UT09fU0hPUlQ7XG4gIH1cbiAgcmV0dXJuIGk7XG59XG5cbmZ1bmN0aW9uIGV4cGFuZFZpbnQoYnVmZmVyOiBCdWZmZXIsIHN0YXJ0OiBudW1iZXIsIGVuZDogbnVtYmVyKSB7XG4gIGNvbnN0IGxlbmd0aCA9IHZpbnRMZW5ndGgoYnVmZmVyLCBzdGFydCk7XG4gIGlmIChlbmQgPiBidWZmZXIubGVuZ3RoIHx8IGxlbmd0aCA9PT0gV2VibUJhc2VEZW11eGVyLlRPT19TSE9SVClcbiAgcmV0dXJuIFdlYm1CYXNlRGVtdXhlci5UT09fU0hPUlQ7XG4gIC8vIEB0cy1pZ25vcmVcbiAgY29uc3QgbWFzayA9ICgxIDw8IDggLSBsZW5ndGgpIC0gMTtcbiAgbGV0IHZhbHVlID0gYnVmZmVyW3N0YXJ0XSAmIG1hc2s7XG4gIGZvciAobGV0IGkgPSBzdGFydCArIDE7IGkgPCBlbmQ7IGkrKykge1xuICAgIHZhbHVlID0gKHZhbHVlIDw8IDgpICsgYnVmZmVyW2ldO1xuICB9XG4gIHJldHVybiB2YWx1ZTtcbn0iLCAiLy8gYmFzZWQgb24gaHR0cHM6Ly9naXRodWIuY29tL2FtaXNoc2hhaC9wcmlzbS1tZWRpYS9ibG9iLzRlZjFkNmY5ZjUzMDQyYzA4NWMxZjY4NjI3ZTg4OTAwM2UyNDhkNzcvc3JjL29wdXMvV2VibURlbXV4ZXIuanNcblxuaW1wb3J0IHsgV2VibUJhc2VEZW11eGVyIH0gZnJvbSAnLi9XZWJtQmFzZSc7XG5cbmNvbnN0IE9QVVNfSEVBRCA9IEJ1ZmZlci5mcm9tKFsuLi4nT3B1c0hlYWQnXS5tYXAoKHgpID0+IHguY2hhckNvZGVBdCgwKSkpO1xuXG4vKipcbiAqIERlbXV4ZXMgYSBXZWJtIHN0cmVhbSAoY29udGFpbmluZyBPcHVzIGF1ZGlvKSB0byBvdXRwdXQgYW4gT3B1cyBzdHJlYW0uXG4gKiBAZXhhbXBsZVxuICogY29uc3QgZnMgPSByZXF1aXJlKCdmcycpO1xuICogY29uc3QgZmlsZSA9IGZzLmNyZWF0ZVJlYWRTdHJlYW0oJy4vYXVkaW8ud2VibScpO1xuICogY29uc3QgZGVtdXhlciA9IG5ldyBXZWJtRGVtdXhlcigpO1xuICogY29uc3Qgb3B1cyA9IGZpbGUucGlwZShkZW11eGVyKTtcbiAqIC8vIG9wdXMgaXMgbm93IGEgUmVhZGFibGVTdHJlYW0gaW4gb2JqZWN0IG1vZGUgb3V0cHV0dGluZyBPcHVzIHBhY2tldHNcbiAqL1xuZXhwb3J0IGNsYXNzIFdlYm1EZW11eGVyIGV4dGVuZHMgV2VibUJhc2VEZW11eGVyIHtcbiAgX2NoZWNrSGVhZChkYXRhOiBCdWZmZXIpIHtcbiAgICBpZiAoIWRhdGEuc3ViYXJyYXkoMCwgOCkuZXF1YWxzKE9QVVNfSEVBRCkpIHtcbiAgICAgIHRocm93IEVycm9yKCdBdWRpbyBjb2RlYyBpcyBub3QgT3B1cyEnKTtcbiAgICB9XG4gIH1cbn0iLCAiXG5cblxuXG5cblxuZXhwb3J0IGNvbnN0IHZlcnNpb24gPSAvKiBAX19NQUNST19fIGdldFZlcnNpb24gKi9cIjcuMi4wXCI7Il0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7QUNFQSx5QkFBNkM7QUFFN0MsSUFBTSx1QkFBdUI7QUFDN0IsSUFBTSwyQkFBMkI7QUFFakMsSUFBTSxXQUFXLHdCQUFDLE1BQWMsRUFBRSxXQUFXLENBQUMsR0FBN0I7QUFDakIsSUFBTSxjQUFjLE9BQU8sS0FBSyxDQUFDLEdBQUcsTUFBTSxFQUFFLElBQUksUUFBUSxDQUFDO0FBQ3pELElBQU0sWUFBWSxPQUFPLEtBQUssQ0FBQyxHQUFHLFVBQVUsRUFBRSxJQUFJLFFBQVEsQ0FBQztBQUMzRCxJQUFNLFlBQVksT0FBTyxLQUFLLENBQUMsR0FBRyxVQUFVLEVBQUUsSUFBSSxRQUFRLENBQUM7QUFLcEQsSUFBTSxjQUFOLE1BQU0sb0JBQW1CLDZCQUFVO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBVWpDLFlBQVksVUFBVSxDQUFDLEdBQUc7QUFDL0IsVUFBTSxPQUFPLE9BQU8sRUFBRSxvQkFBb0IsS0FBSyxHQUFHLE9BQU8sQ0FBQztBQVY1RCx3QkFBUSxjQUE0QjtBQUNwQyx3QkFBUSxTQUF1QjtBQUMvQix3QkFBUSxjQUE0QjtBQVNsQyxTQUFLLGFBQWE7QUFDbEIsU0FBSyxRQUFRO0FBQ2IsU0FBSyxhQUFhO0FBQUEsRUFDcEI7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STtBQUNSLFNBQU8sSUFBSSxHQUFHLElBQUssS0FBSSxLQUFLLElBQUksSUFBSSxPQUFPLEtBQUssRUFBRztBQUNuRDtBQUNBLE1BQUksUUFBUSxJQUFJLE9BQU8sUUFBUTtBQUM3QixXQUFPLGdCQUFnQjtBQUFBLEVBQ3pCO0FBQ0EsU0FBTztBQUNUO0FBWFM7QUFhVCxTQUFTLFdBQVcsUUFBZ0IsT0FBZSxLQUFhO0FBQzlELFFBQU0sU0FBUyxXQUFXLFFBQVEsS0FBSztBQUN2QyxNQUFJLE1BQU0sT0FBTyxVQUFVLFdBQVcsZ0JBQWdCO0FBQ3RELFdBQU8sZ0JBQWdCO0FBRXZCLFFBQU0sUUFBUSxLQUFLLElBQUksVUFBVTtBQUNqQyxNQUFJLFFBQVEsT0FBTyxLQUFLLElBQUk7QUFDNUIsV0FBUyxJQUFJLFFBQVEsR0FBRyxJQUFJLEtBQUssS0FBSztBQUNwQyxhQUFTLFNBQVMsS0FBSyxPQUFPLENBQUM7QUFBQSxFQUNqQztBQUNBLFNBQU87QUFDVDtBQVhTOzs7QUMvTlQsSUFBTUMsYUFBWSxPQUFPLEtBQUssQ0FBQyxHQUFHLFVBQVUsRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUM7QUFXbEUsSUFBTSxlQUFOLE1BQU0scUJBQW9CLGdCQUFnQjtBQUFBLEVBQy9DLFdBQVcsTUFBYztBQUN2QixRQUFJLENBQUMsS0FBSyxTQUFTLEdBQUcsQ0FBQyxFQUFFLE9BQU9BLFVBQVMsR0FBRztBQUMxQyxZQUFNLE1BQU0sMEJBQTBCO0FBQUEsSUFDeEM7QUFBQSxFQUNGO0FBQ0Y7QUFOaUQ7QUFBMUMsSUFBTSxjQUFOOzs7QUNUQSxJQUFNO0FBQUE7QUFBQSxFQUFxQztBQUFBOyIsCiAgIm5hbWVzIjogWyJpbXBvcnRfbm9kZV9zdHJlYW0iLCAiX09wdXNFbmNvZGVyIiwgIk9wdXNFbmNvZGVyIiwgImNoYXJDb2RlIiwgIk9QVVNfSEVBRCIsICJPUFVTX1RBR1MiLCAiaW1wb3J0X25vZGVfc3RyZWFtIiwgIk9QVVNfSEVBRCJdCn0K
|