amazon-route-53-dns-zone-file
Version:
Makes DNS Zone File easy. Parses and validates BIND zone files and can be extended for custom features. Functionality is modular. Features are made open for extension and closed for runtime mutation. Written in TypeScript.
322 lines • 40.2 kB
JavaScript
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
to[j] = from[i];
return to;
};
import { parseTtl, getHasValidTtl } from '../ttl/parse_ttl';
import { ParserInvalidArgumentsError } from '../errors/parsing_error_invalid_arguments';
import { getRecordNameUsingOrigin, zipArrayToObj } from './utils_parser';
import { SUPPORTED_RECORD_TYPES, ErrorKeyKind, RecordMinLengthKind, RecordMaxLengthKind, DirectiveKind, } from '../shared/constants_domain_specific';
/** we indexed how long each value must be, so subtract $NAME_TTL + $IN_TYPE + $VALUES */
var getLengths = function (recordType, values, lineParts) {
var valuesLength = values.length;
var minLength = RecordMinLengthKind[recordType];
var maxLength = RecordMaxLengthKind[recordType];
var nameAndTtlLength = lineParts.length - valuesLength - 2;
return [nameAndTtlLength, valuesLength, minLength, maxLength];
};
/**
* @idea we can include this in validation so it can be extended
* @note this uses Lengths type (everything after nameAndTtl)
* @throws {ParserInvalidArgumentsError} with invalid input lengths
*/
export var assertRecordLengths = function (recordType, valuesLength, minLength, maxLength) {
var isExact = +minLength === +maxLength;
var isExactAndNotEq = isExact && minLength !== valuesLength;
if (isExactAndNotEq || minLength > valuesLength) {
throw new ParserInvalidArgumentsError(recordType, valuesLength, minLength);
}
};
/**
* $NAME_TTL = [name] [ttl]
* $IN_TYPE = `IN $TYPE`
*
* [name] [ttl] - IN $TYPE - value < 4
* [ttl] - IN $TYPE - value < 3
* - IN $TYPE - value < 2
*
* [ttl] [name] - IN TYPE - value < this is not supported by prod
*
* these 2 are where it gets tricky - do we prefer name, or ttl?
* [name] - IN TYPE - value
* [ttl] - IN TYPE - value
*
* @perf bench & experiment as a class
* @note has sideEffects - may swap ttl order in array
*/
var normalizeRecord = function (lineContent, lineParts, recordType, zoneObj, previousName) {
/** add `IN` if it does not exist */
var typeIndex = lineParts.lastIndexOf(recordType);
var newName = '';
if (typeIndex === 0 || lineParts[typeIndex - 1] !== 'IN') {
lineParts.splice(typeIndex, 0, 'IN');
}
/** remove duplicate `IN` */
var firstInIndex = lineParts.indexOf('IN');
var lastInIndex = lineParts.lastIndexOf('IN');
if (firstInIndex !== lastInIndex) {
lineParts.splice(firstInIndex, 1);
}
var values = lineParts.slice(lineParts.lastIndexOf(recordType) + 1);
var _a = __read(getLengths(recordType, values, lineParts)), nameAndTtlLength = _a[0], rest = _a.slice(1);
assertRecordLengths.apply(void 0, __spreadArray([recordType], __read(rest)));
/**
* @todo @perf move to separate fn
* @spec RFC-1035: <lineContent> contents are oneOf:
* @example
* `[<TTL>] [<class>] <type> <RDATA>` // assume this one
* `[<class>] [<TTL>] <type> <RDATA>` // but also support this one
*/
var getHas = function () {
switch (nameAndTtlLength) {
// we have name || ttl
case 1: {
// does not start with a space (if so, then it's a child of the parent [as long as parent is same type])
var hasName_1 = /^\s+/.test(lineContent) === false;
return {
hasTtl: !hasName_1,
hasName: hasName_1
};
}
// ([name, ttl] | [ttl, name]) => [name, ttl]
case 2: {
var _a = __read(lineParts, 2), first = _a[0], second = _a[1];
var didFirstHaveTtl = getHasValidTtl(first);
var didSecondHaveTtl = getHasValidTtl(second);
var hasTtl_1 = didFirstHaveTtl || didSecondHaveTtl;
// swap order
if (didFirstHaveTtl && !didSecondHaveTtl) {
lineParts[0] = second;
lineParts[1] = first;
}
return {
hasTtl: hasTtl_1,
hasName: lineParts[0] !== ''
};
}
// no name or ttl, we can use the top level
case 0: {
return {
hasTtl: false,
hasName: false
};
}
// too many args for name + ttl
default: {
throw new Error(recordType);
}
}
};
var _b = getHas(), hasName = _b.hasName, hasTtl = _b.hasTtl;
var normalized = {
values: values,
recordType: recordType,
tokens: lineParts
};
// unshift name
if (!hasName) {
var recordsSoFar = zoneObj[recordType];
/** @idea simplify by removing the else if here since we have previousName now */
if (previousName) {
normalized.tokens.unshift(previousName);
}
else if (Array.isArray(recordsSoFar) && recordsSoFar.length > 0) {
normalized.tokens.unshift(recordsSoFar[recordsSoFar.length - 1].name || '@');
}
else {
normalized.tokens.unshift('@');
}
}
else {
newName = normalized.tokens[0];
}
// unshift ttl
if (hasTtl) {
normalized.tokens[1] = "" + parseTtl(normalized.tokens[1])[0];
}
else {
// move name to 0, then put ttl at 1
normalized.tokens.unshift(normalized.tokens[0]);
// we want the tokens to stay as strings, so we cast the numerical $ttl to a string
// if there is not a ttl, we have added an `undefined` to this array
normalized.tokens[1] =
zoneObj.$TTL === undefined ? undefined : "" + zoneObj.$TTL;
}
var _c = __read(normalized.tokens, 2), nameValue = _c[0], ttlValue = _c[1];
var finalName = getRecordNameUsingOrigin(nameValue, zoneObj);
return __assign(__assign({}, normalized), { name: finalName, ttl: typeof ttlValue === 'string' ? +ttlValue : undefined, previousName: newName || previousName });
};
var fromAtSymbolValuesToOrigin = function (_a, _b) {
var values = _a.values;
var zoneObj = _b.zoneObj;
return values.map(function (x) {
// replace @ with origin
if (x === '@' && zoneObj.$ORIGIN)
return zoneObj.$ORIGIN;
// escaped values
else if (x === '\\@')
return '@';
// nothing changed
return x;
});
};
export var parsers = {
NS: zipArrayToObj('host', function (record, parser) { return (__assign(__assign({}, record), { values: fromAtSymbolValuesToOrigin(record, parser) })); }),
A: zipArrayToObj('ip', function (record, parser) { return (__assign(__assign({}, record), { values: fromAtSymbolValuesToOrigin(record, parser) })); }),
AAAA: zipArrayToObj('ip', function (record, parser) { return (__assign(__assign({}, record), { values: fromAtSymbolValuesToOrigin(record, parser) })); }),
CNAME: zipArrayToObj('alias', function (record, parser) { return (__assign(__assign({}, record), { values: fromAtSymbolValuesToOrigin(record, parser) })); }),
MX: zipArrayToObj('preference host', function (record, parser) { return (__assign(__assign({}, record), { values: fromAtSymbolValuesToOrigin(record, parser) })); }),
TXT: zipArrayToObj('txt'),
PTR: zipArrayToObj('host', function (record, parser) { return (__assign(__assign({}, record), { values: fromAtSymbolValuesToOrigin(record, parser) })); }),
SRV: zipArrayToObj('target port weight priority'),
NAPTR: zipArrayToObj('order preference flags services regexp replacement'),
SPF: zipArrayToObj('data', function (x) { return (__assign(__assign({}, x), { values: [x.values.join(' ').trim()] })); }),
CAA: zipArrayToObj('flags tag data', function (x) { return (__assign(__assign({}, x), { data: x.data.replace(/^"(.+?)"$/, '$1') })); }),
SOA: zipArrayToObj('minimum expire retry refresh serial rname mname')
};
var originVisitor = {
isSatisfied: function (_a) {
var lineParts = _a.lineParts;
return lineParts.indexOf('$ORIGIN') === 0;
},
visit: function (parser, _a) {
var lineParts = _a.lineParts, addMeta = _a.addMeta;
parser.zoneObj.$ORIGIN = lineParts[1];
return addMeta({
instructionType: DirectiveKind.Origin,
value: lineParts[1]
});
}
};
var ttlVisitor = {
isSatisfied: function (_a) {
var lineParts = _a.lineParts;
return lineParts.indexOf('$TTL') === 0;
},
visit: function (_a, _b) {
var zoneObj = _a.zoneObj;
var addMeta = _b.addMeta, lineParts = _b.lineParts;
var _c = __read(parseTtl(lineParts[1]), 2), ttl = _c[0], error = _c[1];
if (!error) {
zoneObj.$TTL = ttl;
addMeta({
instructionType: DirectiveKind.TimeToLive,
value: ttl
});
}
else {
addMeta({
instructionType: DirectiveKind.TimeToLive,
value: ttl,
errorType: error,
error: error
});
}
}
};
var soaVisitor = {
isSatisfied: function (_a) {
var lineParts = _a.lineParts;
return lineParts.includes('SOA');
},
visit: function (_a, _b) {
var zoneObj = _a.zoneObj;
var addMeta = _b.addMeta, lineParts = _b.lineParts;
zoneObj.SOA = parsers.SOA({
tokens: lineParts,
values: lineParts.slice(lineParts.indexOf('SOA') + 1)
});
addMeta({ instructionType: 'SOA', value: zoneObj.SOA });
}
};
/**
* intersection.
* checks whether the array of strings include any of the supported record types
*/
var getSupportedType = function (lineParts) {
return SUPPORTED_RECORD_TYPES.find(function (supportedType) {
return lineParts.includes(supportedType);
});
};
var simpleRecordsVisitor = {
isSatisfied: function (_a) {
var lineParts = _a.lineParts;
return !!getSupportedType(lineParts);
},
visit: function (parser, _a) {
var _b, _c;
var addMeta = _a.addMeta, lineParts = _a.lineParts, lineContent = _a.lineContent;
var zoneObj = parser.zoneObj, stack = parser.stack;
var type = getSupportedType(lineParts);
// make sure the list exists
if (!Array.isArray(zoneObj[type])) {
zoneObj[type] = [];
}
// reference the array and because we defaulted it above, assert the type
var listForType = zoneObj[type];
try {
var previousName = (_c = (_b = stack[stack.length - 1]) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : '';
var normalized = normalizeRecord(lineContent, lineParts, type, zoneObj, previousName);
stack.push(normalized);
var parsed = parsers[type](normalized, parser);
listForType.push(parsed);
addMeta({ instructionType: type, value: parsed });
}
catch (error) {
addMeta({
instructionType: type,
value: lineParts.join(' '),
error: error,
errorType: error instanceof ParserInvalidArgumentsError
? ErrorKeyKind.WrongLength
: ErrorKeyKind.WrongNameArgsLength
});
}
}
};
var fallbackVisitor = {
isSatisfied: function () { return true; },
visit: function (parser, _a) {
var addMeta = _a.addMeta, lineParts = _a.lineParts;
addMeta({
instructionType: ErrorKeyKind.Unknown,
errorType: ErrorKeyKind.BadDirective,
value: lineParts.join(' ')
});
}
};
export var visitors = [
originVisitor,
ttlVisitor,
soaVisitor,
simpleRecordsVisitor,
fallbackVisitor,
];
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlzaXRvcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcGFyc2VyL3Zpc2l0b3JzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxjQUFjLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUM1RCxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUN4RixPQUFPLEVBQUUsd0JBQXdCLEVBQUUsYUFBYSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFLekUsT0FBTyxFQUNMLHNCQUFzQixFQUN0QixZQUFZLEVBQ1osbUJBQW1CLEVBQ25CLG1CQUFtQixFQUNuQixhQUFhLEdBRWQsTUFBTSxxQ0FBcUMsQ0FBQztBQVU3Qyx5RkFBeUY7QUFDekYsSUFBTSxVQUFVLEdBQUcsVUFDakIsVUFBc0IsRUFDdEIsTUFBaUIsRUFDakIsU0FBbUI7SUFFbkIsSUFBTSxZQUFZLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUNuQyxJQUFNLFNBQVMsR0FBRyxtQkFBbUIsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNsRCxJQUFNLFNBQVMsR0FBRyxtQkFBbUIsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNsRCxJQUFNLGdCQUFnQixHQUFHLFNBQVMsQ0FBQyxNQUFNLEdBQUcsWUFBWSxHQUFHLENBQUMsQ0FBQztJQUU3RCxPQUFPLENBQUMsZ0JBQWdCLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBRSxTQUFTLENBQUMsQ0FBQztBQUNoRSxDQUFDLENBQUM7QUFFRjs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLElBQU0sbUJBQW1CLEdBQUcsVUFDakMsVUFBc0IsRUFDdEIsWUFBb0IsRUFDcEIsU0FBaUIsRUFDakIsU0FBaUI7SUFFakIsSUFBTSxPQUFPLEdBQUcsQ0FBQyxTQUFTLEtBQUssQ0FBQyxTQUFTLENBQUM7SUFDMUMsSUFBTSxlQUFl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VixvQkFBb0I7SUFDcEIsZUFBZTtDQUNoQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcGFyc2VUdGwsIGdldEhhc1ZhbGlkVHRsIH0gZnJvbSAnLi4vdHRsL3BhcnNlX3R0bCc7XG5pbXBvcnQgeyBQYXJzZXJJbnZhbGlkQXJndW1lbnRzRXJyb3IgfSBmcm9tICcuLi9lcnJvcnMvcGFyc2luZ19lcnJvcl9pbnZhbGlkX2FyZ3VtZW50cyc7XG5pbXBvcnQgeyBnZXRSZWNvcmROYW1lVXNpbmdPcmlnaW4sIHppcEFycmF5VG9PYmogfSBmcm9tICcuL3V0aWxzX3BhcnNlcic7XG5pbXBvcnQge1xuICBab25lUmVjb3JkVHlwaW5ncyBhcyBSZWNvcmRUeXBpbmdzLFxuICBQYXJzZWRUeXBpbmdzLFxufSBmcm9tICcuLi9zaGFyZWQvdHlwZXNfZG9tYWluX3NwZWNpZmljJztcbmltcG9ydCB7XG4gIFNVUFBPUlRFRF9SRUNPUkRfVFlQRVMsXG4gIEVycm9yS2V5S2luZCxcbiAgUmVjb3JkTWluTGVuZ3RoS2luZCxcbiAgUmVjb3JkTWF4TGVuZ3RoS2luZCxcbiAgRGlyZWN0aXZlS2luZCxcbiAgUmVjb3JkVHlwZSxcbn0gZnJvbSAnLi4vc2hhcmVkL2NvbnN0YW50c19kb21haW5fc3BlY2lmaWMnO1xuaW1wb3J0IHtcbiAgUGFyc2VyVHlwaW5ncyxcbiAgSW5wdXRUeXBpbmdzLFxuICBQYXJzaW5nUmVjb3JkRGF0YVR5cGUsXG59IGZyb20gJy4vdHlwZXNfcGFyc2VyJztcblxuLyoqIG5hbWVBbmRUdGwsIHZhbHVlcywgbWluLCBtYXggKi9cbnR5cGUgTGVuZ3RocyA9IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuXG4vKiogd2UgaW5kZXhlZCBob3cgbG9uZyBlYWNoIHZhbHVlIG11c3QgYmUsIHNvIHN1YnRyYWN0ICROQU1FX1RUTCArICRJTl9UWVBFICsgJFZBTFVFUyAqL1xuY29uc3QgZ2V0TGVuZ3RocyA9IChcbiAgcmVjb3JkVHlwZTogUmVjb3JkVHlwZSxcbiAgdmFsdWVzOiB1bmtub3duW10sXG4gIGxpbmVQYXJ0czogc3RyaW5nW11cbik6IExlbmd0aHMgPT4ge1xuICBjb25zdCB2YWx1ZXNMZW5ndGggPSB2YWx1ZXMubGVuZ3RoO1xuICBjb25zdCBtaW5MZW5ndGggPSBSZWNvcmRNaW5MZW5ndGhLaW5kW3JlY29yZFR5cGVdO1xuICBjb25zdCBtYXhMZW5ndGggPSBSZWNvcmRNYXhMZW5ndGhLaW5kW3JlY29yZFR5cGVdO1xuICBjb25zdCBuYW1lQW5kVHRsTGVuZ3RoID0gbGluZVBhcnRzLmxlbmd0aCAtIHZhbHVlc0xlbmd0aCAtIDI7XG5cbiAgcmV0dXJuIFtuYW1lQW5kVHRsTGVuZ3RoLCB2YWx1ZXNMZW5ndGgsIG1pbkxlbmd0aCwgbWF4TGVuZ3RoXTtcbn07XG5cbi8qKlxuICogQGlkZWEgd2UgY2FuIGluY2x1ZGUgdGhpcyBpbiB2YWxpZGF0aW9uIHNvIGl0IGNhbiBiZSBleHRlbmRlZFxuICogQG5vdGUgdGhpcyB1c2VzIExlbmd0aHMgdHlwZSAoZXZlcnl0aGluZyBhZnRlciBuYW1lQW5kVHRsKVxuICogQHRocm93cyB7UGFyc2VySW52YWxpZEFyZ3VtZW50c0Vycm9yfSB3aXRoIGludmFsaWQgaW5wdXQgbGVuZ3Roc1xuICovXG5leHBvcnQgY29uc3QgYXNzZXJ0UmVjb3JkTGVuZ3RocyA9IChcbiAgcmVjb3JkVHlwZTogUmVjb3JkVHlwZSxcbiAgdmFsdWVzTGVuZ3RoOiBudW1iZXIsXG4gIG1pbkxlbmd0aDogbnVtYmVyLFxuICBtYXhMZW5ndGg6IG51bWJlclxuKSA9PiB7XG4gIGNvbnN0IGlzRXhhY3QgPSArbWluTGVuZ3RoID09PSArbWF4TGVuZ3RoO1xuICBjb25zdCBpc0V4YWN0QW5kTm90RXEgPSBpc0V4YWN0ICYmIG1pbkxlbmd0aCAhPT0gdmFsdWVzTGVuZ3RoO1xuXG4gIGlmIChpc0V4YWN0QW5kTm90RXEgfHwgbWluTGVuZ3RoID4gdmFsdWVzTGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlckludmFsaWRBcmd1bWVudHNFcnJvcihyZWNvcmRUeXBlLCB2YWx1ZXNMZW5ndGgsIG1pbkxlbmd0aCk7XG4gIH1cbn07XG5cbi8qKlxuICogJE5BTUVfVFRMID0gW25hbWVdIFt0dGxdXG4gKiAkSU5fVFlQRSA9IGBJTiAkVFlQRWBcbiAqXG4gKiBbbmFtZV0gW3R0bF0gLSBJTiAkVFlQRSAtIHZhbHVlIDwgNFxuICogICAgICAgIFt0dGxdIC0gSU4gJFRZUEUgLSB2YWx1ZSA8IDNcbiAqICAgICAgICAgICAgICAtIElOICRUWVBFIC0gdmFsdWUgPCAyXG4gKlxuICogW3R0bF0gW25hbWVdIC0gSU4gVFlQRSAtIHZhbHVlIDwgdGhpcyBpcyBub3Qgc3VwcG9ydGVkIGJ5IHByb2RcbiAqXG4gKiB0aGVzZSAyIGFyZSB3aGVyZSBpdCBnZXRzIHRyaWNreSAtIGRvIHdlIHByZWZlciBuYW1lLCBvciB0dGw/XG4gKiBbbmFtZV0gLSBJTiBUWVBFIC0gdmFsdWVcbiAqIFt0dGxdIC0gSU4gVFlQRSAtIHZhbHVlXG4gKlxuICogQHBlcmYgYmVuY2ggJiBleHBlcmltZW50IGFzIGEgY2xhc3NcbiAqIEBub3RlIGhhcyBzaWRlRWZmZWN0cyAtIG1heSBzd2FwIHR0bCBvcmRlciBpbiBhcnJheVxuICovXG5jb25zdCBub3JtYWxpemVSZWNvcmQgPSAoXG4gIGxpbmVDb250ZW50OiBzdHJpbmcsXG4gIGxpbmVQYXJ0czogc3RyaW5nW10sXG4gIHJlY29yZFR5cGU6IElucHV0VHlwaW5ncy5TdXBwb3J0ZWRSZWNvcmRUeXBlLFxuICB6b25lT2JqOiBQYXJzZWRUeXBpbmdzLk9iaixcbiAgcHJldmlvdXNOYW1lOiBzdHJpbmdcbik6IFBhcnNpbmdSZWNvcmREYXRhVHlwZSA9PiB7XG4gIC8qKiBhZGQgYElOYCBpZiBpdCBkb2VzIG5vdCBleGlzdCAqL1xuICBjb25zdCB0eXBlSW5kZXggPSBsaW5lUGFydHMubGFzdEluZGV4T2YocmVjb3JkVHlwZSk7XG5cbiAgbGV0IG5ld05hbWU6IHN0cmluZyA9ICcnO1xuXG4gIGlmICh0eXBlSW5kZXggPT09IDAgfHwgbGluZVBhcnRzW3R5cGVJbmRleCAtIDFdICE9PSAnSU4nKSB7XG4gICAgbGluZVBhcnRzLnNwbGljZSh0eXBlSW5kZXgsIDAsICdJTicpO1xuICB9XG4gIC8qKiByZW1vdmUgZHVwbGljYXRlIGBJTmAgKi9cbiAgY29uc3QgZmlyc3RJbkluZGV4ID0gbGluZVBhcnRzLmluZGV4T2YoJ0lOJyk7XG4gIGNvbnN0IGxhc3RJbkluZGV4ID0gbGluZVBhcnRzLmxhc3RJbmRleE9mKCdJTicpO1xuXG4gIGlmIChmaXJzdEluSW5kZXggIT09IGxhc3RJbkluZGV4KSB7XG4gICAgbGluZVBhcnRzLnNwbGljZShmaXJzdEluSW5kZXgsIDEpO1xuICB9XG5cbiAgY29uc3QgdmFsdWVzID0gbGluZVBhcnRzLnNsaWNlKGxpbmVQYXJ0cy5sYXN0SW5kZXhPZihyZWNvcmRUeXBlKSArIDEpO1xuICBjb25zdCBbbmFtZUFuZFR0bExlbmd0aCwgLi4ucmVzdF0gPSBnZXRMZW5ndGhzKHJlY29yZFR5cGUsIHZhbHVlcywgbGluZVBhcnRzKTtcbiAgYXNzZXJ0UmVjb3JkTGVuZ3RocyhyZWNvcmRUeXBlLCAuLi5yZXN0KTtcblxuICAvKipcbiAgICogQHRvZG8gQHBlcmYgbW92ZSB0byBzZXBhcmF0ZSBmblxuICAgKiBAc3BlYyBSRkMtMTAzNTogPGxpbmVDb250ZW50PiBjb250ZW50cyBhcmUgb25lT2Y6XG4gICAqIEBleGFtcGxlXG4gICAqICAgYFs8VFRMPl0gWzxjbGFzcz5dIDx0eXBlPiA8UkRBVEE+YCAvLyBhc3N1bWUgdGhpcyBvbmVcbiAgICogICBgWzxjbGFzcz5dIFs8VFRMPl0gPHR5cGU+IDxSREFUQT5gIC8vIGJ1dCBhbHNvIHN1cHBvcnQgdGhpcyBvbmVcbiAgICovXG4gIGNvbnN0IGdldEhhcyA9ICgpID0+IHtcbiAgICBzd2l0Y2ggKG5hbWVBbmRUdGxMZW5ndGgpIHtcbiAgICAgIC8vIHdlIGhhdmUgbmFtZSB8fCB0dGxcbiAgICAgIGNhc2UgMToge1xuICAgICAgICAvLyBkb2VzIG5vdCBzdGFydCB3aXRoIGEgc3BhY2UgKGlmIHNvLCB0aGVuIGl0J3MgYSBjaGlsZCBvZiB0aGUgcGFyZW50IFthcyBsb25nIGFzIHBhcmVudCBpcyBzYW1lIHR5cGVdKVxuICAgICAgICBjb25zdCBoYXNOYW1lID0gL15cXHMrLy50ZXN0KGxpbmVDb250ZW50KSA9PT0gZmFsc2U7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBoYXNUdGw6ICFoYXNOYW1lLFxuICAgICAgICAgIGhhc05hbWUsXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICAvLyAoW25hbWUsIHR0bF0gfCBbdHRsLCBuYW1lXSkgPT4gW25hbWUsIHR0bF1cbiAgICAgIGNhc2UgMjoge1xuICAgICAgICBjb25zdCBbZmlyc3QsIHNlY29uZF0gPSBsaW5lUGFydHM7XG4gICAgICAgIGNvbnN0IGRpZEZpcnN0SGF2ZVR0bCA9IGdldEhhc1ZhbGlkVHRsKGZpcnN0KTtcbiAgICAgICAgY29uc3QgZGlkU2Vjb25kSGF2ZVR0bCA9IGdldEhhc1ZhbGlkVHRsKHNlY29uZCk7XG4gICAgICAgIGNvbnN0IGhhc1R0bCA9IGRpZEZpcnN0SGF2ZVR0bCB8fCBkaWRTZWNvbmRIYXZlVHRsO1xuXG4gICAgICAgIC8vIHN3YXAgb3JkZXJcbiAgICAgICAgaWYgKGRpZEZpcnN0SGF2ZVR0bCAmJiAhZGlkU2Vjb25kSGF2ZVR0bCkge1xuICAgICAgICAgIGxpbmVQYXJ0c1swXSA9IHNlY29uZDtcbiAgICAgICAgICBsaW5lUGFydHNbMV0gPSBmaXJzdDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgaGFzVHRsLFxuICAgICAgICAgIGhhc05hbWU6IGxpbmVQYXJ0c1swXSAhPT0gJycsXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICAvLyBubyBuYW1lIG9yIHR0bCwgd2UgY2FuIHVzZSB0aGUgdG9wIGxldmVsXG4gICAgICBjYXNlIDA6IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBoYXNUdGw6IGZhbHNlLFxuICAgICAgICAgIGhhc05hbWU6IGZhbHNlLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgLy8gdG9vIG1hbnkgYXJncyBmb3IgbmFtZSArIHR0bFxuICAgICAgZGVmYXVsdDoge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IocmVjb3JkVHlwZSk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IHsgaGFzTmFtZSwgaGFzVHRsIH0gPSBnZXRIYXMoKTtcbiAgY29uc3Qgbm9ybWFsaXplZCA9IHtcbiAgICB2YWx1ZXMsXG4gICAgcmVjb3JkVHlwZSxcbiAgICB0b2tlbnM6IGxpbmVQYXJ0cyxcbiAgfTtcblxuICAvLyB1bnNoaWZ0IG5hbWVcbiAgaWYgKCFoYXNOYW1lKSB7XG4gICAgY29uc3QgcmVjb3Jkc1NvRmFyID0gem9uZU9ialtyZWNvcmRUeXBlXTtcblxuICAgIC8qKiBAaWRlYSBzaW1wbGlmeSBieSByZW1vdmluZyB0aGUgZWxzZSBpZiBoZXJlIHNpbmNlIHdlIGhhdmUgcHJldmlvdXNOYW1lIG5vdyAqL1xuICAgIGlmIChwcmV2aW91c05hbWUpIHtcbiAgICAgIG5vcm1hbGl6ZWQudG9rZW5zLnVuc2hpZnQocHJldmlvdXNOYW1lKTtcbiAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkocmVjb3Jkc1NvRmFyKSAmJiByZWNvcmRzU29GYXIubGVuZ3RoID4gMCkge1xuICAgICAgbm9ybWFsaXplZC50b2tlbnMudW5zaGlmdChcbiAgICAgICAgcmVjb3Jkc1NvRmFyW3JlY29yZHNTb0Zhci5sZW5ndGggLSAxXS5uYW1lIHx8ICdAJ1xuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbm9ybWFsaXplZC50b2tlbnMudW5zaGlmdCgnQCcpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBuZXdOYW1lID0gbm9ybWFsaXplZC50b2tlbnNbMF07XG4gIH1cblxuICAvLyB1bnNoaWZ0IHR0bFxuICBpZiAoaGFzVHRsKSB7XG4gICAgbm9ybWFsaXplZC50b2tlbnNbMV0gPSBgJHtwYXJzZVR0bChub3JtYWxpemVkLnRva2Vuc1sxXSlbMF19YDtcbiAgfSBlbHNlIHtcbiAgICAvLyBtb3ZlIG5hbWUgdG8gMCwgdGhlbiBwdXQgdHRsIGF0IDFcbiAgICBub3JtYWxpemVkLnRva2Vucy51bnNoaWZ0KG5vcm1hbGl6ZWQudG9rZW5zWzBdKTtcbiAgICAvLyB3ZSB3YW50IHRoZSB0b2tlbnMgdG8gc3RheSBhcyBzdHJpbmdzLCBzbyB3ZSBjYXN0IHRoZSBudW1lcmljYWwgJHR0bCB0byBhIHN0cmluZ1xuICAgIC8vIGlmIHRoZXJlIGlzIG5vdCBhIHR0bCwgd2UgaGF2ZSBhZGRlZCBhbiBgdW5kZWZpbmVkYCB0byB0aGlzIGFycmF5XG4gICAgbm9ybWFsaXplZC50b2tlbnNbMV0gPVxuICAgICAgem9uZU9iai4kVFRMID09PSB1bmRlZmluZWQgPyAodW5kZWZpbmVkIGFzIGFueSkgOiBgJHt6b25lT2JqLiRUVEx9YDtcbiAgfVxuXG4gIGNvbnN0IFtuYW1lVmFsdWUsIHR0bFZhbHVlXSA9IG5vcm1hbGl6ZWQudG9rZW5zO1xuICBjb25zdCBmaW5hbE5hbWUgPSBnZXRSZWNvcmROYW1lVXNpbmdPcmlnaW4obmFtZVZhbHVlLCB6b25lT2JqKTtcblxuICByZXR1cm4ge1xuICAgIC4uLm5vcm1hbGl6ZWQsXG4gICAgbmFtZTogZmluYWxOYW1lLFxuICAgIHR0bDogdHlwZW9mIHR0bFZhbHVlID09PSAnc3RyaW5nJyA/ICt0dGxWYWx1ZSA6IHVuZGVmaW5lZCxcbiAgICBwcmV2aW91c05hbWU6IG5ld05hbWUgfHwgcHJldmlvdXNOYW1lLFxuICB9O1xufTtcblxuY29uc3QgZnJvbUF0U3ltYm9sVmFsdWVzVG9PcmlnaW4gPSA8XG4gIFJlY29yZCBleHRlbmRzIFBhcnNlZFR5cGluZ3MuQnlUeXBlW2tleW9mIFBhcnNlZFR5cGluZ3MuQnlUeXBlXVxuPihcbiAgeyB2YWx1ZXMgfTogUmVjb3JkLFxuICB7IHpvbmVPYmogfTogUGFyc2VyVHlwaW5ncy5QYXJzZXJcbikgPT4ge1xuICByZXR1cm4gdmFsdWVzLm1hcCh4ID0+IHtcbiAgICAvLyByZXBsYWNlIEAgd2l0aCBvcmlnaW5cbiAgICBpZiAoeCA9PT0gJ0AnICYmIHpvbmVPYmouJE9SSUdJTikgcmV0dXJuIHpvbmVPYmouJE9SSUdJTjtcbiAgICAvLyBlc2NhcGVkIHZhbHVlc1xuICAgIGVsc2UgaWYgKHggPT09ICdcXFxcQCcpIHJldHVybiAnQCc7XG4gICAgLy8gbm90aGluZyBjaGFuZ2VkXG4gICAgcmV0dXJuIHg7XG4gIH0pIGFzIFJlY29yZFsndmFsdWVzJ107XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VycyA9IHtcbiAgTlM6IHppcEFycmF5VG9PYmo8UmVjb3JkVHlwaW5ncy5OUz4oJ2hvc3QnLCAocmVjb3JkLCBwYXJzZXIpID0+ICh7XG4gICAgLi4ucmVjb3JkLFxuICAgIHZhbHVlczogZnJvbUF0U3ltYm9sVmFsdWVzVG9PcmlnaW48UmVjb3JkVHlwaW5ncy5OUz4ocmVjb3JkLCBwYXJzZXIpLFxuICB9KSksXG4gIEE6IHppcEFycmF5VG9PYmo8UmVjb3JkVHlwaW5ncy5BPignaXAnLCAocmVjb3JkLCBwYXJzZXIpID0+ICh7XG4gICAgLi4ucmVjb3JkLFxuICAgIHZhbHVlczogZnJvbUF0U3ltYm9sVmFsdWVzVG9PcmlnaW48UmVjb3JkVHlwaW5ncy5BPihyZWNvcmQsIHBhcnNlciksXG4gIH0pKSxcbiAgQUFBQTogemlwQXJyYXlUb09iajxSZWNvcmRUeXBpbmdzLkFBQUE+KCdpcCcsIChyZWNvcmQsIHBhcnNlcikgPT4gKHtcbiAgICAuLi5yZWNvcmQsXG4gICAgdmFsdWVzOiBmcm9tQXRTeW1ib2xWYWx1ZXNUb09yaWdpbjxSZWNvcmRUeXBpbmdzLkFBQUE+KHJlY29yZCwgcGFyc2VyKSxcbiAgfSkpLFxuICBDTkFNRTogemlwQXJyYXlUb09iajxSZWNvcmRUeXBpbmdzLkNOQU1FPignYWxpYXMnLCAocmVjb3JkLCBwYXJzZXIpID0+ICh7XG4gICAgLi4ucmVjb3JkLFxuICAgIHZhbHVlczogZnJvbUF0U3ltYm9sVmFsdWVzVG9PcmlnaW48UmVjb3JkVHlwaW5ncy5DTkFNRT4ocmVjb3JkLCBwYXJzZXIpLFxuICB9KSksXG4gIE1YOiB6aXBBcnJheVRvT2JqPFJlY29yZFR5cGluZ3MuTVg+KCdwcmVmZXJlbmNlIGhvc3QnLCAocmVjb3JkLCBwYXJzZXIpID0+ICh7XG4gICAgLi4ucmVjb3JkLFxuICAgIHZhbHVlczogZnJvbUF0U3ltYm9sVmFsdWVzVG9PcmlnaW48UmVjb3JkVHlwaW5ncy5NWD4ocmVjb3JkLCBwYXJzZXIpLFxuICB9KSksXG4gIFRYVDogemlwQXJyYXlUb09iajxSZWNvcmRUeXBpbmdzLlRYVD4oJ3R4dCcpLFxuICBQVFI6IHppcEFycmF5VG9PYmo8UmVjb3JkVHlwaW5ncy5QVFI+KCdob3N0JywgKHJlY29yZCwgcGFyc2VyKSA9PiAoe1xuICAgIC4uLnJlY29yZCxcbiAgICB2YWx1ZXM6IGZyb21BdFN5bWJvbFZhbHVlc1RvT3JpZ2luPFJlY29yZFR5cGluZ3MuUFRSPihyZWNvcmQsIHBhcnNlciksXG4gIH0pKSxcbiAgU1JWOiB6aXBBcnJheVRvT2JqPFJlY29yZFR5cGluZ3MuU1JWPigndGFyZ2V0IHBvcnQgd2VpZ2h0IHByaW9yaXR5JyksXG4gIE5BUFRSOiB6aXBBcnJheVRvT2JqPFJlY29yZFR5cGluZ3MuTkFQVFI+KFxuICAgICdvcmRlciBwcmVmZXJlbmNlIGZsYWdzIHNlcnZpY2VzIHJlZ2V4cCByZXBsYWNlbWVudCdcbiAgKSxcbiAgU1BGOiB6aXBBcnJheVRvT2JqPFJlY29yZFR5cGluZ3MuU1BGPignZGF0YScsIHggPT4gKHtcbiAgICAuLi54LFxuICAgIHZhbHVlczogW3gudmFsdWVzLmpvaW4oJyAnKS50cmltKCldLFxuICB9KSksXG4gIENBQTogemlwQXJyYXlUb09iajxSZWNvcmRUeXBpbmdzLkNBQT4oJ2ZsYWdzIHRhZyBkYXRhJywgeCA9PiAoe1xuICAgIC4uLngsXG4gICAgZGF0YTogeC5kYXRhLnJlcGxhY2UoL15cIiguKz8pXCIkLywgJyQxJyksXG4gIH0pKSxcbiAgU09BOiB6aXBBcnJheVRvT2JqPFJlY29yZFR5cGluZ3MuU09BPihcbiAgICAnbWluaW11bSBleHBpcmUgcmV0cnkgcmVmcmVzaCBzZXJpYWwgcm5hbWUgbW5hbWUnXG4gICkgYXMgKFxuICAgIHg6IE9taXQ8UGFyc2luZ1JlY29yZERhdGFUeXBlLCAnbmFtZScgfCAncHJldmlvdXNOYW1lJz5cbiAgKSA9PiBSZWNvcmRUeXBpbmdzLlNPQSxcbn0gYXMgY29uc3Q7XG5cbmNvbnN0IG9yaWdpblZpc2l0b3I6IFBhcnNlclR5cGluZ3MuVmlzaXRvciA9IHtcbiAgaXNTYXRpc2ZpZWQ6ICh7IGxpbmVQYXJ0cyB9KSA9PiBsaW5lUGFydHMuaW5kZXhPZignJE9SSUdJTicpID09PSAwLFxuICB2aXNpdChwYXJzZXIsIHsgbGluZVBhcnRzLCBhZGRNZXRhIH0pIHtcbiAgICBwYXJzZXIuem9uZU9iai4kT1JJR0lOID0gbGluZVBhcnRzWzFdO1xuICAgIHJldHVybiBhZGRNZXRhKHtcbiAgICAgIGluc3RydWN0aW9uVHlwZTogRGlyZWN0aXZlS2luZC5PcmlnaW4sXG4gICAgICB2YWx1ZTogbGluZVBhcnRzWzFdLFxuICAgIH0pO1xuICB9LFxufTtcbmNvbnN0IHR0bFZpc2l0b3I6IFBhcnNlclR5cGluZ3MuVmlzaXRvciA9IHtcbiAgaXNTYXRpc2ZpZWQ6ICh7IGxpbmVQYXJ0cyB9KSA9PiBsaW5lUGFydHMuaW5kZXhPZignJFRUTCcpID09PSAwLFxuICB2aXNpdCh7IHpvbmVPYmogfSwgeyBhZGRNZXRhLCBsaW5lUGFydHMgfSkge1xuICAgIGNvbnN0IFt0dGwsIGVycm9yXSA9IHBhcnNlVHRsKGxpbmVQYXJ0c1sxXSk7XG5cbiAgICBpZiAoIWVycm9yKSB7XG4gICAgICB6b25lT2JqLiRUVEwgPSB0dGw7XG4gICAgICBhZGRNZXRhKHtcbiAgICAgICAgaW5zdHJ1Y3Rpb25UeXBlOiBEaXJlY3RpdmVLaW5kLlRpbWVUb0xpdmUsXG4gICAgICAgIHZhbHVlOiB0dGwsXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgYWRkTWV0YSh7XG4gICAgICAgIGluc3RydWN0aW9uVHlwZTogRGlyZWN0aXZlS2luZC5UaW1lVG9MaXZlLFxuICAgICAgICB2YWx1ZTogdHRsLFxuICAgICAgICBlcnJvclR5cGU6IGVycm9yLFxuICAgICAgICBlcnJvcixcbiAgICAgIH0pO1xuICAgIH1cbiAgfSxcbn07XG5cbmNvbnN0IHNvYVZpc2l0b3I6IFBhcnNlclR5cGluZ3MuVmlzaXRvciA9IHtcbiAgaXNTYXRpc2ZpZWQ6ICh7IGxpbmVQYXJ0cyB9KSA9PiBsaW5lUGFydHMuaW5jbHVkZXMoJ1NPQScpLFxuICB2aXNpdCh7IHpvbmVPYmogfSwgeyBhZGRNZXRhLCBsaW5lUGFydHMgfSkge1xuICAgIHpvbmVPYmouU09BID0gcGFyc2Vycy5TT0Eoe1xuICAgICAgdG9rZW5zOiBsaW5lUGFydHMsXG4gICAgICB2YWx1ZXM6IGxpbmVQYXJ0cy5zbGljZShsaW5lUGFydHMuaW5kZXhPZignU09BJykgKyAxKSxcbiAgICB9KTtcbiAgICBhZGRNZXRhKHsgaW5zdHJ1Y3Rpb25UeXBlOiAnU09BJywgdmFsdWU6IHpvbmVPYmouU09BIH0pO1xuICB9LFxufTtcblxuLyoqXG4gKiBpbnRlcnNlY3Rpb24uXG4gKiBjaGVja3Mgd2hldGhlciB0aGUgYXJyYXkgb2Ygc3RyaW5ncyBpbmNsdWRlIGFueSBvZiB0aGUgc3VwcG9ydGVkIHJlY29yZCB0eXBlc1xuICovXG5jb25zdCBnZXRTdXBwb3J0ZWRUeXBlID0gKGxpbmVQYXJ0czogc3RyaW5nW10pID0+XG4gIFNVUFBPUlRFRF9SRUNPUkRfVFlQRVMuZmluZChzdXBwb3J0ZWRUeXBlID0+XG4gICAgbGluZVBhcnRzLmluY2x1ZGVzKHN1cHBvcnRlZFR5cGUpXG4gICk7XG5cbmNvbnN0IHNpbXBsZVJlY29yZHNWaXNpdG9yOiBQYXJzZXJUeXBpbmdzLlZpc2l0b3IgPSB7XG4gIGlzU2F0aXNmaWVkOiAoeyBsaW5lUGFydHMgfSkgPT4gISFnZXRTdXBwb3J0ZWRUeXBlKGxpbmVQYXJ0cyksXG4gIHZpc2l0KHBhcnNlciwgeyBhZGRNZXRhLCBsaW5lUGFydHMsIGxpbmVDb250ZW50IH0pIHtcbiAgICBjb25zdCB7IHpvbmVPYmosIHN0YWNrIH0gPSBwYXJzZXI7XG4gICAgY29uc3QgdHlwZSA9IGdldFN1cHBvcnRlZFR5cGUobGluZVBhcnRzKSBhcyBSZWNvcmRUeXBlO1xuXG4gICAgLy8gbWFrZSBzdXJlIHRoZSBsaXN0IGV4aXN0c1xuICAgIGlmICghQXJyYXkuaXNBcnJheSh6b25lT2JqW3R5cGVdKSkge1xuICAgICAgem9uZU9ialt0eXBlXSA9IFtdIGFzIGFueVtdO1xuICAgIH1cbiAgICAvLyByZWZlcmVuY2UgdGhlIGFycmF5IGFuZCBiZWNhdXNlIHdlIGRlZmF1bHRlZCBpdCBhYm92ZSwgYXNzZXJ0IHRoZSB0eXBlXG4gICAgY29uc3QgbGlzdEZvclR5cGUgPSB6b25lT2JqW3R5cGVdIGFzIFJlY29yZFR5cGluZ3MuQW55SW5kZXhTaWduYXR1cmVbXTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBwcmV2aW91c05hbWUgPSBzdGFja1tzdGFjay5sZW5ndGggLSAxXT8ubmFtZSA/PyAnJztcbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSBub3JtYWxpemVSZWNvcmQoXG4gICAgICAgIGxpbmVDb250ZW50LFxuICAgICAgICBsaW5lUGFydHMsXG4gICAgICAgIHR5cGUsXG4gICAgICAgIHpvbmVPYmosXG4gICAgICAgIHByZXZpb3VzTmFtZVxuICAgICAgKTtcblxuICAgICAgc3RhY2sucHVzaChub3JtYWxpemVkKTtcbiAgICAgIGNvbnN0IHBhcnNlZCA9IHBhcnNlcnNbdHlwZV0obm9ybWFsaXplZCwgcGFyc2VyKTtcbiAgICAgIGxpc3RGb3JUeXBlLnB1c2gocGFyc2VkKTtcbiAgICAgIGFkZE1ldGEoeyBpbnN0cnVjdGlvblR5cGU6IHR5cGUsIHZhbHVlOiBwYXJzZWQgfSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGFkZE1ldGEoe1xuICAgICAgICBpbnN0cnVjdGlvblR5cGU6IHR5cGUsXG4gICAgICAgIHZhbHVlOiBsaW5lUGFydHMuam9pbignICcpLFxuICAgICAgICBlcnJvcixcbiAgICAgICAgZXJyb3JUeXBlOlxuICAgICAgICAgIGVycm9yIGluc3RhbmNlb2YgUGFyc2VySW52YWxpZEFyZ3VtZW50c0Vycm9yXG4gICAgICAgICAgICA/IEVycm9yS2V5S2luZC5Xcm9uZ0xlbmd0aFxuICAgICAgICAgICAgOiBFcnJvcktleUtpbmQuV3JvbmdOYW1lQXJnc0xlbmd0aCxcbiAgICAgIH0pO1xuICAgIH1cbiAgfSxcbn07XG5cbmNvbnN0IGZhbGxiYWNrVmlzaXRvcjogUGFyc2VyVHlwaW5ncy5WaXNpdG9yID0ge1xuICBpc1NhdGlzZmllZDogKCkgPT4gdHJ1ZSxcbiAgdmlzaXQocGFyc2VyLCB7IGFkZE1ldGEsIGxpbmVQYXJ0cyB9KSB7XG4gICAgYWRkTWV0YSh7XG4gICAgICBpbnN0cnVjdGlvblR5cGU6IEVycm9yS2V5S2luZC5Vbmtub3duLFxuICAgICAgZXJyb3JUeXBlOiBFcnJvcktleUtpbmQuQmFkRGlyZWN0aXZlLFxuICAgICAgdmFsdWU6IGxpbmVQYXJ0cy5qb2luKCcgJyksXG4gICAgfSk7XG4gIH0sXG59O1xuXG5leHBvcnQgY29uc3QgdmlzaXRvcnMgPSBbXG4gIG9yaWdpblZpc2l0b3IsXG4gIHR0bFZpc2l0b3IsXG4gIHNvYVZpc2l0b3IsXG4gIHNpbXBsZVJlY29yZHNWaXNpdG9yLFxuICBmYWxsYmFja1Zpc2l0b3IsXG5dO1xuIl19