tedious
Version:
A TDS driver, for connecting to MS SQLServer databases.
245 lines (244 loc) • 31 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _errors = require("./errors");
var _formatHex = require("./format-hex");
var _writableTrackingBuffer = _interopRequireDefault(require("./tracking-buffer/writable-tracking-buffer"));
var _crypto = require("crypto");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const traceIdSize = 36;
const TOKEN = {
VERSION: 0x00,
ENCRYPTION: 0x01,
INSTOPT: 0x02,
THREADID: 0x03,
MARS: 0x04,
TRACEID: 0x05,
FEDAUTHREQUIRED: 0x06,
TERMINATOR: 0xFF
};
const ENCRYPT = {
OFF: 0x00,
ON: 0x01,
NOT_SUP: 0x02,
REQ: 0x03
};
const encryptByValue = {};
for (const name in ENCRYPT) {
const value = ENCRYPT[name];
encryptByValue[value] = name;
}
const MARS = {
OFF: 0x00,
ON: 0x01
};
const marsByValue = {};
for (const name in MARS) {
const value = MARS[name];
marsByValue[value] = name;
}
/*
s2.2.6.5
*/
class PreloginPayload {
constructor(bufferOrOptions = {
encrypt: false,
version: {
major: 0,
minor: 0,
build: 0,
subbuild: 0
}
}) {
if (bufferOrOptions instanceof Buffer) {
this.data = bufferOrOptions;
this.options = {
encrypt: false,
version: {
major: 0,
minor: 0,
build: 0,
subbuild: 0
}
};
} else {
this.options = bufferOrOptions;
this.createOptions();
}
this.extractOptions();
}
createOptions() {
const options = [this.createVersionOption(), this.createEncryptionOption(), this.createInstanceOption(), this.createThreadIdOption(), this.createMarsOption(), this.createTraceIdOption(), this.createFedAuthOption()];
let length = 0;
for (let i = 0, len = options.length; i < len; i++) {
const option = options[i];
length += 5 + option.data.length;
}
length++; // terminator
this.data = Buffer.alloc(length, 0);
let optionOffset = 0;
let optionDataOffset = 5 * options.length + 1;
for (let j = 0, len = options.length; j < len; j++) {
const option = options[j];
this.data.writeUInt8(option.token, optionOffset + 0);
this.data.writeUInt16BE(optionDataOffset, optionOffset + 1);
this.data.writeUInt16BE(option.data.length, optionOffset + 3);
optionOffset += 5;
option.data.copy(this.data, optionDataOffset);
optionDataOffset += option.data.length;
}
this.data.writeUInt8(TOKEN.TERMINATOR, optionOffset);
}
createVersionOption() {
const buffer = new _writableTrackingBuffer.default();
buffer.writeUInt8(this.options.version.major);
buffer.writeUInt8(this.options.version.minor);
buffer.writeUInt16BE(this.options.version.build);
buffer.writeUInt16BE(this.options.version.subbuild);
return {
token: TOKEN.VERSION,
data: buffer.data
};
}
createEncryptionOption() {
const buffer = new _writableTrackingBuffer.default();
if (this.options.encrypt) {
buffer.writeUInt8(ENCRYPT.ON);
} else {
buffer.writeUInt8(ENCRYPT.NOT_SUP);
}
return {
token: TOKEN.ENCRYPTION,
data: buffer.data
};
}
createInstanceOption() {
const buffer = new _writableTrackingBuffer.default();
buffer.writeUInt8(0x00);
return {
token: TOKEN.INSTOPT,
data: buffer.data
};
}
createThreadIdOption() {
const buffer = new _writableTrackingBuffer.default();
buffer.writeUInt32BE(0x00);
return {
token: TOKEN.THREADID,
data: buffer.data
};
}
createMarsOption() {
const buffer = new _writableTrackingBuffer.default();
buffer.writeUInt8(MARS.OFF);
return {
token: TOKEN.MARS,
data: buffer.data
};
}
createTraceIdOption() {
const buffer = new _writableTrackingBuffer.default();
// Generate a random series of bytes to use as the TraceID.
// Used for debugging purposes.
buffer.writeBuffer((0, _crypto.randomBytes)(traceIdSize));
return {
token: TOKEN.TRACEID,
data: buffer.data
};
}
createFedAuthOption() {
const buffer = new _writableTrackingBuffer.default();
buffer.writeUInt8(0x01);
return {
token: TOKEN.FEDAUTHREQUIRED,
data: buffer.data
};
}
extractOptions() {
let offset = 0;
let encryptionOffset;
while (this.data[offset] !== TOKEN.TERMINATOR) {
let dataOffset = this.data.readUInt16BE(offset + 1);
const dataLength = this.data.readUInt16BE(offset + 3);
switch (this.data[offset]) {
case TOKEN.VERSION:
this.extractVersion(dataOffset);
break;
case TOKEN.ENCRYPTION:
if (encryptionOffset !== undefined) {
throw new _errors.ConnectionError('Duplicate ENCRYPTION option in PRELOGIN response', 'EENCRYPT');
}
if (dataLength !== 1 || dataOffset >= this.data.length) {
throw new _errors.ConnectionError('Malformed ENCRYPTION option in PRELOGIN response', 'EENCRYPT');
}
encryptionOffset = dataOffset;
this.extractEncryption(dataOffset);
break;
case TOKEN.INSTOPT:
this.extractInstance(dataOffset);
break;
case TOKEN.THREADID:
if (dataLength > 0) {
this.extractThreadId(dataOffset);
}
break;
case TOKEN.MARS:
this.extractMars(dataOffset);
break;
case TOKEN.TRACEID:
this.extractTraceId(dataOffset);
break;
case TOKEN.FEDAUTHREQUIRED:
this.extractFedAuth(dataOffset);
break;
}
offset += 5;
dataOffset += dataLength;
}
if (encryptionOffset !== undefined && encryptionOffset <= offset) {
throw new _errors.ConnectionError('Malformed ENCRYPTION option in PRELOGIN response', 'EENCRYPT');
}
}
extractVersion(offset) {
this.version = {
major: this.data.readUInt8(offset + 0),
minor: this.data.readUInt8(offset + 1),
build: this.data.readUInt16BE(offset + 2),
subbuild: this.data.readUInt16BE(offset + 4)
};
}
extractEncryption(offset) {
this.encryption = this.data.readUInt8(offset);
this.encryptionString = encryptByValue[this.encryption];
}
extractInstance(offset) {
this.instance = this.data.readUInt8(offset);
}
extractThreadId(offset) {
this.threadId = this.data.readUInt32BE(offset);
}
extractMars(offset) {
this.mars = this.data.readUInt8(offset);
this.marsString = marsByValue[this.mars];
}
extractTraceId(offset) {
this.traceId = this.data.subarray(offset, offset + traceIdSize);
}
extractFedAuth(offset) {
this.fedAuthRequired = this.data.readUInt8(offset);
}
toString(indent = '') {
const {
major,
minor,
build,
subbuild
} = this.version;
return indent + 'PreLogin - ' + `version:${major}.${minor}.${build}.${subbuild}, ` + `encryption:0x${(0, _formatHex.formatHex)(this.encryption ? this.encryption : 0, 2)}(${this.encryptionString ? this.encryptionString : ''}), ` + `instopt:0x${(0, _formatHex.formatHex)(this.instance ? this.instance : 0, 2)}, ` + `threadId:0x${(0, _formatHex.formatHex)(this.threadId ? this.threadId : 0, 8)}, ` + `mars:0x${(0, _formatHex.formatHex)(this.mars ? this.mars : 0, 2)}(${this.marsString ? this.marsString : ''}), ` + `traceId:${this.traceId ? this.traceId.toString('hex') : ''}`;
}
}
var _default = exports.default = PreloginPayload;
module.exports = PreloginPayload;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfZXJyb3JzIiwicmVxdWlyZSIsIl9mb3JtYXRIZXgiLCJfd3JpdGFibGVUcmFja2luZ0J1ZmZlciIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfY3J5cHRvIiwiZSIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwidHJhY2VJZFNpemUiLCJUT0tFTiIsIlZFUlNJT04iLCJFTkNSWVBUSU9OIiwiSU5TVE9QVCIsIlRIUkVBRElEIiwiTUFSUyIsIlRSQUNFSUQiLCJGRURBVVRIUkVRVUlSRUQiLCJURVJNSU5BVE9SIiwiRU5DUllQVCIsIk9GRiIsIk9OIiwiTk9UX1NVUCIsIlJFUSIsImVuY3J5cHRCeVZhbHVlIiwibmFtZSIsInZhbHVlIiwibWFyc0J5VmFsdWUiLCJQcmVsb2dpblBheWxvYWQiLCJjb25zdHJ1Y3RvciIsImJ1ZmZlck9yT3B0aW9ucyIsImVuY3J5cHQiLCJ2ZXJzaW9uIiwibWFqb3IiLCJtaW5vciIsImJ1aWxkIiwic3ViYnVpbGQiLCJCdWZmZXIiLCJkYXRhIiwib3B0aW9ucyIsImNyZWF0ZU9wdGlvbnMiLCJleHRyYWN0T3B0aW9ucyIsImNyZWF0ZVZlcnNpb25PcHRpb24iLCJjcmVhdGVFbmNyeXB0aW9uT3B0aW9uIiwiY3JlYXRlSW5zdGFuY2VPcHRpb24iLCJjcmVhdGVUaHJlYWRJZE9wdGlvbiIsImNyZWF0ZU1hcnNPcHRpb24iLCJjcmVhdGVUcmFjZUlkT3B0aW9uIiwiY3JlYXRlRmVkQXV0aE9wdGlvbiIsImxlbmd0aCIsImkiLCJsZW4iLCJvcHRpb24iLCJhbGxvYyIsIm9wdGlvbk9mZnNldCIsIm9wdGlvbkRhdGFPZmZzZXQiLCJqIiwid3JpdGVVSW50OCIsInRva2VuIiwid3JpdGVVSW50MTZCRSIsImNvcHkiLCJidWZmZXIiLCJXcml0YWJsZVRyYWNraW5nQnVmZmVyIiwid3JpdGVVSW50MzJCRSIsIndyaXRlQnVmZmVyIiwicmFuZG9tQnl0ZXMiLCJvZmZzZXQiLCJlbmNyeXB0aW9uT2Zmc2V0IiwiZGF0YU9mZnNldCIsInJlYWRVSW50MTZCRSIsImRhdGFMZW5ndGgiLCJleHRyYWN0VmVyc2lvbiIsInVuZGVmaW5lZCIsIkNvbm5lY3Rpb25FcnJvciIsImV4dHJhY3RFbmNyeXB0aW9uIiwiZXh0cmFjdEluc3RhbmNlIiwiZXh0cmFjdFRocmVhZElkIiwiZXh0cmFjdE1hcnMiLCJleHRyYWN0VHJhY2VJZCIsImV4dHJhY3RGZWRBdXRoIiwicmVhZFVJbnQ4IiwiZW5jcnlwdGlvbiIsImVuY3J5cHRpb25TdHJpbmciLCJpbnN0YW5jZSIsInRocmVhZElkIiwicmVhZFVJbnQzMkJFIiwibWFycyIsIm1hcnNTdHJpbmciLCJ0cmFjZUlkIiwic3ViYXJyYXkiLCJmZWRBdXRoUmVxdWlyZWQiLCJ0b1N0cmluZyIsImluZGVudCIsImZvcm1hdEhleCIsIl9kZWZhdWx0IiwiZXhwb3J0cyIsIm1vZHVsZSJdLCJzb3VyY2VzIjpbIi4uL3NyYy9wcmVsb2dpbi1wYXlsb2FkLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbm5lY3Rpb25FcnJvciB9IGZyb20gJy4vZXJyb3JzJztcbmltcG9ydCB7IGZvcm1hdEhleCB9IGZyb20gJy4vZm9ybWF0LWhleCc7XG5cbmltcG9ydCBXcml0YWJsZVRyYWNraW5nQnVmZmVyIGZyb20gJy4vdHJhY2tpbmctYnVmZmVyL3dyaXRhYmxlLXRyYWNraW5nLWJ1ZmZlcic7XG5pbXBvcnQgeyByYW5kb21CeXRlcyB9IGZyb20gJ2NyeXB0byc7XG5cbmNvbnN0IHRyYWNlSWRTaXplID0gMzY7XG5cbmNvbnN0IFRPS0VOID0ge1xuICBWRVJTSU9OOiAweDAwLFxuICBFTkNSWVBUSU9OOiAweDAxLFxuICBJTlNUT1BUOiAweDAyLFxuICBUSFJFQURJRDogMHgwMyxcbiAgTUFSUzogMHgwNCxcbiAgVFJBQ0VJRDogMHgwNSxcbiAgRkVEQVVUSFJFUVVJUkVEOiAweDA2LFxuICBURVJNSU5BVE9SOiAweEZGXG59O1xuXG5jb25zdCBFTkNSWVBUOiB7IFtrZXk6IHN0cmluZ106IG51bWJlciB9ID0ge1xuICBPRkY6IDB4MDAsXG4gIE9OOiAweDAxLFxuICBOT1RfU1VQOiAweDAyLFxuICBSRVE6IDB4MDNcbn07XG5cbmNvbnN0IGVuY3J5cHRCeVZhbHVlOiB7IFtrZXk6IG51bWJlcl06IHN0cmluZyB9ID0ge307XG5cbmZvciAoY29uc3QgbmFtZSBpbiBFTkNSWVBUKSB7XG4gIGNvbnN0IHZhbHVlID0gRU5DUllQVFtuYW1lXTtcbiAgZW5jcnlwdEJ5VmFsdWVbdmFsdWVdID0gbmFtZTtcbn1cblxuY29uc3QgTUFSUzogeyBba2V5OiBzdHJpbmddOiBudW1iZXIgfSA9IHtcbiAgT0ZGOiAweDAwLFxuICBPTjogMHgwMVxufTtcblxuY29uc3QgbWFyc0J5VmFsdWU6IHsgW2tleTogbnVtYmVyXTogc3RyaW5nIH0gPSB7fTtcblxuZm9yIChjb25zdCBuYW1lIGluIE1BUlMpIHtcbiAgY29uc3QgdmFsdWUgPSBNQVJTW25hbWVdO1xuICBtYXJzQnlWYWx1ZVt2YWx1ZV0gPSBuYW1lO1xufVxuXG5pbnRlcmZhY2UgT3B0aW9ucyB7XG4gIGVuY3J5cHQ6IGJvb2xlYW47XG4gIHZlcnNpb246IHtcbiAgICBtYWpvcjogbnVtYmVyO1xuICAgIG1pbm9yOiBudW1iZXI7XG4gICAgYnVpbGQ6IG51bWJlcjtcbiAgICBzdWJidWlsZDogbnVtYmVyO1xuICB9O1xufVxuXG4vKlxuICBzMi4yLjYuNVxuICovXG5jbGFzcyBQcmVsb2dpblBheWxvYWQge1xuICBkZWNsYXJlIGRhdGE6IEJ1ZmZlcjtcbiAgZGVjbGFyZSBvcHRpb25zOiBPcHRpb25zO1xuXG4gIGRlY2xhcmUgdmVyc2lvbjoge1xuICAgIG1ham9yOiBudW1iZXI7XG4gICAgbWlub3I6IG51bWJlcjtcbiAgICBidWlsZDogbnVtYmVyO1xuICAgIHN1YmJ1aWxkOiBudW1iZXI7XG4gIH07XG5cbiAgZGVjbGFyZSBlbmNyeXB0aW9uOiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gIGRlY2xhcmUgZW5jcnlwdGlvblN0cmluZzogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gIGRlY2xhcmUgaW5zdGFuY2U6IG51bWJlcjtcblxuICBkZWNsYXJlIHRocmVhZElkOiBudW1iZXI7XG5cbiAgZGVjbGFyZSBtYXJzOiBudW1iZXI7XG4gIGRlY2xhcmUgbWFyc1N0cmluZzogc3RyaW5nO1xuICBkZWNsYXJlIHRyYWNlSWQ6IEJ1ZmZlcjtcbiAgZGVjbGFyZSBmZWRBdXRoUmVxdWlyZWQ6IG51bWJlcjtcblxuICBjb25zdHJ1Y3RvcihidWZmZXJPck9wdGlvbnM6IEJ1ZmZlciB8IE9wdGlvbnMgPSB7IGVuY3J5cHQ6IGZhbHNlLCB2ZXJzaW9uOiB7IG1ham9yOiAwLCBtaW5vcjogMCwgYnVpbGQ6IDAsIHN1YmJ1aWxkOiAwIH0gfSkge1xuICAgIGlmIChidWZmZXJPck9wdGlvbnMgaW5zdGFuY2VvZiBCdWZmZXIpIHtcbiAgICAgIHRoaXMuZGF0YSA9IGJ1ZmZlck9yT3B0aW9ucztcbiAgICAgIHRoaXMub3B0aW9ucyA9IHsgZW5jcnlwdDogZmFsc2UsIHZlcnNpb246IHsgbWFqb3I6IDAsIG1pbm9yOiAwLCBidWlsZDogMCwgc3ViYnVpbGQ6IDAgfSB9O1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm9wdGlvbnMgPSBidWZmZXJPck9wdGlvbnMgYXMgT3B0aW9ucztcbiAgICAgIHRoaXMuY3JlYXRlT3B0aW9ucygpO1xuICAgIH1cbiAgICB0aGlzLmV4dHJhY3RPcHRpb25zKCk7XG4gIH1cblxuICBjcmVhdGVPcHRpb25zKCkge1xuICAgIGNvbnN0IG9wdGlvbnMgPSBbXG4gICAgICB0aGlzLmNyZWF0ZVZlcnNpb25PcHRpb24oKSxcbiAgICAgIHRoaXMuY3JlYXRlRW5jcnlwdGlvbk9wdGlvbigpLFxuICAgICAgdGhpcy5jcmVhdGVJbnN0YW5jZU9wdGlvbigpLFxuICAgICAgdGhpcy5jcmVhdGVUaHJlYWRJZE9wdGlvbigpLFxuICAgICAgdGhpcy5jcmVhdGVNYXJzT3B0aW9uKCksXG4gICAgICB0aGlzLmNyZWF0ZVRyYWNlSWRPcHRpb24oKSxcbiAgICAgIHRoaXMuY3JlYXRlRmVkQXV0aE9wdGlvbigpXG4gICAgXTtcblxuICAgIGxldCBsZW5ndGggPSAwO1xuICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBvcHRpb25zLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICBjb25zdCBvcHRpb24gPSBvcHRpb25zW2ldO1xuICAgICAgbGVuZ3RoICs9IDUgKyBvcHRpb24uZGF0YS5sZW5ndGg7XG4gICAgfVxuICAgIGxlbmd0aCsrOyAvLyB0ZXJtaW5hdG9yXG4gICAgdGhpcy5kYXRhID0gQnVmZmVyLmFsbG9jKGxlbmd0aCwgMCk7XG4gICAgbGV0IG9wdGlvbk9mZnNldCA9IDA7XG4gICAgbGV0IG9wdGlvbkRhdGFPZmZzZXQgPSA1ICogb3B0aW9ucy5sZW5ndGggKyAxO1xuXG4gICAgZm9yIChsZXQgaiA9IDAsIGxlbiA9IG9wdGlvbnMubGVuZ3RoOyBqIDwgbGVuOyBqKyspIHtcbiAgICAgIGNvbnN0IG9wdGlvbiA9IG9wdGlvbnNbal07XG4gICAgICB0aGlzLmRhdGEud3JpdGVVSW50OChvcHRpb24udG9rZW4sIG9wdGlvbk9mZnNldCArIDApO1xuICAgICAgdGhpcy5kYXRhLndyaXRlVUludDE2QkUob3B0aW9uRGF0YU9mZnNldCwgb3B0aW9uT2Zmc2V0ICsgMSk7XG4gICAgICB0aGlzLmRhdGEud3JpdGVVSW50MTZCRShvcHRpb24uZGF0YS5sZW5ndGgsIG9wdGlvbk9mZnNldCArIDMpO1xuICAgICAgb3B0aW9uT2Zmc2V0ICs9IDU7XG4gICAgICBvcHRpb24uZGF0YS5jb3B5KHRoaXMuZGF0YSwgb3B0aW9uRGF0YU9mZnNldCk7XG4gICAgICBvcHRpb25EYXRhT2Zmc2V0ICs9IG9wdGlvbi5kYXRhLmxlbmd0aDtcbiAgICB9XG5cbiAgICB0aGlzLmRhdGEud3JpdGVVSW50OChUT0tFTi5URVJNSU5BVE9SLCBvcHRpb25PZmZzZXQpO1xuICB9XG5cbiAgY3JlYXRlVmVyc2lvbk9wdGlvbigpIHtcbiAgICBjb25zdCBidWZmZXIgPSBuZXcgV3JpdGFibGVUcmFja2luZ0J1ZmZlcigpO1xuICAgIGJ1ZmZlci53cml0ZVVJbnQ4KHRoaXMub3B0aW9ucy52ZXJzaW9uLm1ham9yKTtcbiAgICBidWZmZXIud3JpdGVVSW50OCh0aGlzLm9wdGlvbnMudmVyc2lvbi5taW5vcik7XG4gICAgYnVmZmVyLndyaXRlVUludDE2QkUodGhpcy5vcHRpb25zLnZlcnNpb24uYnVpbGQpO1xuICAgIGJ1ZmZlci53cml0ZVVJbnQxNkJFKHRoaXMub3B0aW9ucy52ZXJzaW9uLnN1YmJ1aWxkKTtcbiAgICByZXR1cm4ge1xuICAgICAgdG9rZW46IFRPS0VOLlZFUlNJT04sXG4gICAgICBkYXRhOiBidWZmZXIuZGF0YVxuICAgIH07XG4gIH1cblxuICBjcmVhdGVFbmNyeXB0aW9uT3B0aW9uKCkge1xuICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBXcml0YWJsZVRyYWNraW5nQnVmZmVyKCk7XG4gICAgaWYgKHRoaXMub3B0aW9ucy5lbmNyeXB0KSB7XG4gICAgICBidWZmZXIud3JpdGVVSW50OChFTkNSWVBULk9OKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYnVmZmVyLndyaXRlVUludDgoRU5DUllQVC5OT1RfU1VQKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIHRva2VuOiBUT0tFTi5FTkNSWVBUSU9OLFxuICAgICAgZGF0YTogYnVmZmVyLmRhdGFcbiAgICB9O1xuICB9XG5cbiAgY3JlYXRlSW5zdGFuY2VPcHRpb24oKSB7XG4gICAgY29uc3QgYnVmZmVyID0gbmV3IFdyaXRhYmxlVHJhY2tpbmdCdWZmZXIoKTtcbiAgICBidWZmZXIud3JpdGVVSW50OCgweDAwKTtcbiAgICByZXR1cm4ge1xuICAgICAgdG9rZW46IFRPS0VOLklOU1RPUFQsXG4gICAgICBkYXRhOiBidWZmZXIuZGF0YVxuICAgIH07XG4gIH1cblxuICBjcmVhdGVUaHJlYWRJZE9wdGlvbigpIHtcbiAgICBjb25zdCBidWZmZXIgPSBuZXcgV3JpdGFibGVUcmFja2luZ0J1ZmZlcigpO1xuICAgIGJ1ZmZlci53cml0ZVVJbnQzMkJFKDB4MDApO1xuICAgIHJldHVybiB7XG4gICAgICB0b2tlbjogVE9LRU4uVEhSRUFESUQsXG4gICAgICBkYXRhOiBidWZmZXIuZGF0YVxuICAgIH07XG4gIH1cblxuICBjcmVhdGVNYXJzT3B0aW9uKCkge1xuICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBXcml0YWJsZVRyYWNraW5nQnVmZmVyKCk7XG4gICAgYnVmZmVyLndyaXRlVUludDgoTUFSUy5PRkYpO1xuICAgIHJldHVybiB7XG4gICAgICB0b2tlbjogVE9LRU4uTUFSUyxcbiAgICAgIGRhdGE6IGJ1ZmZlci5kYXRhXG4gICAgfTtcbiAgfVxuXG4gIGNyZWF0ZVRyYWNlSWRPcHRpb24oKSB7XG4gICAgY29uc3QgYnVmZmVyID0gbmV3IFdyaXRhYmxlVHJhY2tpbmdCdWZmZXIoKTtcbiAgICAvLyBHZW5lcmF0ZSBhIHJhbmRvbSBzZXJpZXMgb2YgYnl0ZXMgdG8gdXNlIGFzIHRoZSBUcmFjZUlELlxuICAgIC8vIFVzZWQgZm9yIGRlYnVnZ2luZyBwdXJwb3Nlcy5cbiAgICBidWZmZXIud3JpdGVCdWZmZXIocmFuZG9tQnl0ZXModHJhY2VJZFNpemUpKTtcbiAgICByZXR1cm4ge1xuICAgICAgdG9rZW46IFRPS0VOLlRSQUNFSUQsXG4gICAgICBkYXRhOiBidWZmZXIuZGF0YVxuICAgIH07XG4gIH1cblxuICBjcmVhdGVGZWRBdXRoT3B0aW9uKCkge1xuICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBXcml0YWJsZVRyYWNraW5nQnVmZmVyKCk7XG4gICAgYnVmZmVyLndyaXRlVUludDgoMHgwMSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHRva2VuOiBUT0tFTi5GRURBVVRIUkVRVUlSRUQsXG4gICAgICBkYXRhOiBidWZmZXIuZGF0YVxuICAgIH07XG4gIH1cblxuICBleHRyYWN0T3B0aW9ucygpIHtcbiAgICBsZXQgb2Zmc2V0ID0gMDtcbiAgICBsZXQgZW5jcnlwdGlvbk9mZnNldDogbnVtYmVyIHwgdW5kZWZpbmVkO1xuICAgIHdoaWxlICh0aGlzLmRhdGFbb2Zmc2V0XSAhPT0gVE9LRU4uVEVSTUlOQVRPUikge1xuICAgICAgbGV0IGRhdGFPZmZzZXQgPSB0aGlzLmRhdGEucmVhZFVJbnQxNkJFKG9mZnNldCArIDEpO1xuICAgICAgY29uc3QgZGF0YUxlbmd0aCA9IHRoaXMuZGF0YS5yZWFkVUludDE2QkUob2Zmc2V0ICsgMyk7XG4gICAgICBzd2l0Y2ggKHRoaXMuZGF0YVtvZmZzZXRdKSB7XG4gICAgICAgIGNhc2UgVE9LRU4uVkVSU0lPTjpcbiAgICAgICAgICB0aGlzLmV4dHJhY3RWZXJzaW9uKGRhdGFPZmZzZXQpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFRPS0VOLkVOQ1JZUFRJT046XG4gICAgICAgICAgaWYgKGVuY3J5cHRpb25PZmZzZXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IENvbm5lY3Rpb25FcnJvcignRHVwbGljYXRlIEVOQ1JZUFRJT04gb3B0aW9uIGluIFBSRUxPR0lOIHJlc3BvbnNlJywgJ0VFTkNSWVBUJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChkYXRhTGVuZ3RoICE9PSAxIHx8IGRhdGFPZmZzZXQgPj0gdGhpcy5kYXRhLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IENvbm5lY3Rpb25FcnJvcignTWFsZm9ybWVkIEVOQ1JZUFRJT04gb3B0aW9uIGluIFBSRUxPR0lOIHJlc3BvbnNlJywgJ0VFTkNSWVBUJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVuY3J5cHRpb25PZmZzZXQgPSBkYXRhT2Zmc2V0O1xuICAgICAgICAgIHRoaXMuZXh0cmFjdEVuY3J5cHRpb24oZGF0YU9mZnNldCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgVE9LRU4uSU5TVE9QVDpcbiAgICAgICAgICB0aGlzLmV4dHJhY3RJbnN0YW5jZShkYXRhT2Zmc2V0KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBUT0tFTi5USFJFQURJRDpcbiAgICAgICAgICBpZiAoZGF0YUxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuZXh0cmFjdFRocmVhZElkKGRhdGFPZmZzZXQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBUT0tFTi5NQVJTOlxuICAgICAgICAgIHRoaXMuZXh0cmFjdE1hcnMoZGF0YU9mZnNldCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgVE9LRU4uVFJBQ0VJRDpcbiAgICAgICAgICB0aGlzLmV4dHJhY3RUcmFjZUlkKGRhdGFPZmZzZXQpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFRPS0VOLkZFREFVVEhSRVFVSVJFRDpcbiAgICAgICAgICB0aGlzLmV4dHJhY3RGZWRBdXRoKGRhdGFPZmZzZXQpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgb2Zmc2V0ICs9IDU7XG4gICAgICBkYXRhT2Zmc2V0ICs9IGRhdGFMZW5ndGg7XG4gICAgfVxuICAgIGlmIChlbmNyeXB0aW9uT2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgZW5jcnlwdGlvbk9mZnNldCA8PSBvZmZzZXQpIHtcbiAgICAgIHRocm93IG5ldyBDb25uZWN0aW9uRXJyb3IoJ01hbGZvcm1lZCBFTkNSWVBUSU9OIG9wdGlvbiBpbiBQUkVMT0dJTiByZXNwb25zZScsICdFRU5DUllQVCcpO1xuICAgIH1cbiAgfVxuXG4gIGV4dHJhY3RWZXJzaW9uKG9mZnNldDogbnVtYmVyKSB7XG4gICAgdGhpcy52ZXJzaW9uID0ge1xuICAgICAgbWFqb3I6IHRoaXMuZGF0YS5yZWFkVUludDgob2Zmc2V0ICsgMCksXG4gICAgICBtaW5vcjogdGhpcy5kYXRhLnJlYWRVSW50OChvZmZzZXQgKyAxKSxcbiAgICAgIGJ1aWxkOiB0aGlzLmRhdGEucmVhZFVJbnQxNkJFKG9mZnNldCArIDIpLFxuICAgICAgc3ViYnVpbGQ6IHRoaXMuZGF0YS5yZWFkVUludDE2QkUob2Zmc2V0ICsgNClcbiAgICB9O1xuICB9XG5cbiAgZXh0cmFjdEVuY3J5cHRpb24ob2Zmc2V0OiBudW1iZXIpIHtcbiAgICB0aGlzLmVuY3J5cHRpb24gPSB0aGlzLmRhdGEucmVhZFVJbnQ4KG9mZnNldCk7XG4gICAgdGhpcy5lbmNyeXB0aW9uU3RyaW5nID0gZW5jcnlwdEJ5VmFsdWVbdGhpcy5lbmNyeXB0aW9uXTtcbiAgfVxuXG4gIGV4dHJhY3RJbnN0YW5jZShvZmZzZXQ6IG51bWJlcikge1xuICAgIHRoaXMuaW5zdGFuY2UgPSB0aGlzLmRhdGEucmVhZFVJbnQ4KG9mZnNldCk7XG4gIH1cblxuICBleHRyYWN0VGhyZWFkSWQob2Zmc2V0OiBudW1iZXIpIHtcbiAgICB0aGlzLnRocmVhZElkID0gdGhpcy5kYXRhLnJlYWRVSW50MzJCRShvZmZzZXQpO1xuICB9XG5cbiAgZXh0cmFjdE1hcnMob2Zmc2V0OiBudW1iZXIpIHtcbiAgICB0aGlzLm1hcnMgPSB0aGlzLmRhdGEucmVhZFVJbnQ4KG9mZnNldCk7XG4gICAgdGhpcy5tYXJzU3RyaW5nID0gbWFyc0J5VmFsdWVbdGhpcy5tYXJzXTtcbiAgfVxuXG4gIGV4dHJhY3RUcmFjZUlkKG9mZnNldDogbnVtYmVyKSB7XG4gICAgdGhpcy50cmFjZUlkID0gdGhpcy5kYXRhLnN1YmFycmF5KG9mZnNldCwgb2Zmc2V0ICsgdHJhY2VJZFNpemUpO1xuICB9XG5cbiAgZXh0cmFjdEZlZEF1dGgob2Zmc2V0OiBudW1iZXIpIHtcbiAgICB0aGlzLmZlZEF1dGhSZXF1aXJlZCA9IHRoaXMuZGF0YS5yZWFkVUludDgob2Zmc2V0KTtcbiAgfVxuXG4gIHRvU3RyaW5nKGluZGVudCA9ICcnKSB7XG4gICAgY29uc3QgeyBtYWpvciwgbWlub3IsIGJ1aWxkLCBzdWJidWlsZCB9ID0gdGhpcy52ZXJzaW9uO1xuICAgIHJldHVybiBpbmRlbnQgKyAnUHJlTG9naW4gLSAnICtcbiAgICAgIGB2ZXJzaW9uOiR7bWFqb3J9LiR7bWlub3J9LiR7YnVpbGR9LiR7c3ViYnVpbGR9LCBgICtcbiAgICAgIGBlbmNyeXB0aW9uOjB4JHtmb3JtYXRIZXgodGhpcy5lbmNyeXB0aW9uID8gdGhpcy5lbmNyeXB0aW9uIDogMCwgMil9KCR7dGhpcy5lbmNyeXB0aW9uU3RyaW5nID8gdGhpcy5lbmNyeXB0aW9uU3RyaW5nIDogJyd9KSwgYCArXG4gICAgICBgaW5zdG9wdDoweCR7Zm9ybWF0SGV4KHRoaXMuaW5zdGFuY2UgPyB0aGlzLmluc3RhbmNlIDogMCwgMil9LCBgICtcbiAgICAgIGB0aHJlYWRJZDoweCR7Zm9ybWF0SGV4KHRoaXMudGhyZWFkSWQgPyB0aGlzLnRocmVhZElkIDogMCwgOCl9LCBgICtcbiAgICAgIGBtYXJzOjB4JHtmb3JtYXRIZXgodGhpcy5tYXJzID8gdGhpcy5tYXJzIDogMCwgMil9KCR7dGhpcy5tYXJzU3RyaW5nID8gdGhpcy5tYXJzU3RyaW5nIDogJyd9KSwgYCArXG4gICAgICBgdHJhY2VJZDoke3RoaXMudHJhY2VJZCA/IHRoaXMudHJhY2VJZC50b1N0cmluZygnaGV4JykgOiAnJ31gO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFByZWxvZ2luUGF5bG9hZDtcbm1vZHVsZS5leHBvcnRzID0gUHJlbG9naW5QYXlsb2FkO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxJQUFBQSxPQUFBLEdBQUFDLE9BQUE7QUFDQSxJQUFBQyxVQUFBLEdBQUFELE9BQUE7QUFFQSxJQUFBRSx1QkFBQSxHQUFBQyxzQkFBQSxDQUFBSCxPQUFBO0FBQ0EsSUFBQUksT0FBQSxHQUFBSixPQUFBO0FBQXFDLFNBQUFHLHVCQUFBRSxDQUFBLFdBQUFBLENBQUEsSUFBQUEsQ0FBQSxDQUFBQyxVQUFBLEdBQUFELENBQUEsS0FBQUUsT0FBQSxFQUFBRixDQUFBO0FBRXJDLE1BQU1HLFdBQVcsR0FBRyxFQUFFO0FBRXRCLE1BQU1DLEtBQUssR0FBRztFQUNaQyxPQUFPLEVBQUUsSUFBSTtFQUNiQyxVQUFVLEVBQUUsSUFBSTtFQUNoQkMsT0FBTyxFQUFFLElBQUk7RUFDYkMsUUFBUSxFQUFF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