@aws-cdk/core
Version:
AWS Cloud Development Kit Core Library
201 lines • 21.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const string_fragments_1 = require("../string-fragments");
const token_1 = require("../token");
// Details for encoding and decoding Tokens into native types; should not be exported
exports.BEGIN_STRING_TOKEN_MARKER = '${Token[';
exports.BEGIN_LIST_TOKEN_MARKER = '#{Token[';
exports.END_TOKEN_MARKER = ']}';
exports.VALID_KEY_CHARS = 'a-zA-Z0-9:._-';
const QUOTED_BEGIN_STRING_TOKEN_MARKER = regexQuote(exports.BEGIN_STRING_TOKEN_MARKER);
const QUOTED_BEGIN_LIST_TOKEN_MARKER = regexQuote(exports.BEGIN_LIST_TOKEN_MARKER);
const QUOTED_END_TOKEN_MARKER = regexQuote(exports.END_TOKEN_MARKER);
const STRING_TOKEN_REGEX = new RegExp(`${QUOTED_BEGIN_STRING_TOKEN_MARKER}([${exports.VALID_KEY_CHARS}]+)${QUOTED_END_TOKEN_MARKER}`, 'g');
const LIST_TOKEN_REGEX = new RegExp(`${QUOTED_BEGIN_LIST_TOKEN_MARKER}([${exports.VALID_KEY_CHARS}]+)${QUOTED_END_TOKEN_MARKER}`, 'g');
/**
* A string with markers in it that can be resolved to external values
*/
class TokenString {
constructor(str, re) {
this.str = str;
this.re = re;
}
/**
* Returns a `TokenString` for this string.
*/
static forString(s) {
return new TokenString(s, STRING_TOKEN_REGEX);
}
/**
* Returns a `TokenString` for this string (must be the first string element of the list)
*/
static forListToken(s) {
return new TokenString(s, LIST_TOKEN_REGEX);
}
/**
* Split string on markers, substituting markers with Tokens
*/
split(lookup) {
const ret = new string_fragments_1.TokenizedStringFragments();
let rest = 0;
this.re.lastIndex = 0; // Reset
let m = this.re.exec(this.str);
while (m) {
if (m.index > rest) {
ret.addLiteral(this.str.substring(rest, m.index));
}
ret.addToken(lookup(m[1]));
rest = this.re.lastIndex;
m = this.re.exec(this.str);
}
if (rest < this.str.length) {
ret.addLiteral(this.str.substring(rest));
}
return ret;
}
/**
* Indicates if this string includes tokens.
*/
test() {
this.re.lastIndex = 0; // Reset
return this.re.test(this.str);
}
}
exports.TokenString = TokenString;
/**
* Quote a string for use in a regex
*/
function regexQuote(s) {
return s.replace(/[.?*+^$[\]\\(){}|-]/g, '\\$&');
}
exports.regexQuote = regexQuote;
/**
* Concatenator that disregards the input
*
* Can be used when traversing the tokens is important, but the
* result isn't.
*/
class NullConcat {
join(_left, _right) {
return undefined;
}
}
exports.NullConcat = NullConcat;
function containsListTokenElement(xs) {
return xs.some(x => typeof (x) === 'string' && TokenString.forListToken(x).test());
}
exports.containsListTokenElement = containsListTokenElement;
/**
* Returns true if obj is a token (i.e. has the resolve() method or is a string
* that includes token markers), or it's a listifictaion of a Token string.
*
* @param obj The object to test.
*/
function unresolved(obj) {
if (typeof (obj) === 'string') {
return TokenString.forString(obj).test();
}
else if (typeof obj === 'number') {
return extractTokenDouble(obj) !== undefined;
}
else if (Array.isArray(obj) && obj.length === 1) {
return typeof (obj[0]) === 'string' && TokenString.forListToken(obj[0]).test();
}
else {
return token_1.isResolvableObject(obj);
}
}
exports.unresolved = unresolved;
/**
* Bit pattern in the top 16 bits of a double to indicate a Token
*
* An IEEE double in LE memory order looks like this (grouped
* into octets, then grouped into 32-bit words):
*
* mmmmmmmm.mmmmmmmm.mmmmmmmm.mmmmmmmm | mmmmmmmm.mmmmmmmm.EEEEmmmm.sEEEEEEE
*
* - m: mantissa (52 bits)
* - E: exponent (11 bits)
* - s: sign (1 bit)
*
* We put the following marker into the top 16 bits (exponent and sign), and
* use the mantissa part to encode the token index. To save some bit twiddling
* we use all top 16 bits for the tag. That loses us 4 mantissa bits to store
* information in but we still have 48, which is going to be plenty for any
* number of tokens to be created during the lifetime of any CDK application.
*
* Can't have all bits set because that makes a NaN, so unset the least
* significant exponent bit.
*
* Currently not supporting BE architectures.
*/
// tslint:disable-next-line:no-bitwise
const DOUBLE_TOKEN_MARKER_BITS = 0xFBFF << 16;
/**
* Highest encodable number
*/
const MAX_ENCODABLE_INTEGER = Math.pow(2, 48) - 1;
/**
* Get 2^32 as a number, so we can do multiplication and div instead of bit shifting
*
* Necessary because in JavaScript, bit operations implicitly convert
* to int32 and we need them to work on "int64"s.
*
* So instead of x >> 32, we do Math.floor(x / 2^32), and vice versa.
*/
const BITS32 = Math.pow(2, 32);
/**
* Return a special Double value that encodes the given nonnegative integer
*
* We use this to encode Token ordinals.
*/
function createTokenDouble(x) {
if (Math.floor(x) !== x || x < 0) {
throw new Error('Can only encode positive integers');
}
if (x > MAX_ENCODABLE_INTEGER) {
throw new Error(`Got an index too large to encode: ${x}`);
}
const buf = new ArrayBuffer(8);
const ints = new Uint32Array(buf);
// tslint:disable:no-bitwise
ints[0] = x & 0x0000FFFFFFFF; // Bottom 32 bits of number
// This needs an "x >> 32" but that will make it a 32-bit number instead
// of a 64-bit number.
ints[1] = (shr32(x) & 0xFFFF) | DOUBLE_TOKEN_MARKER_BITS; // Top 16 bits of number and the mask
// tslint:enable:no-bitwise
return (new Float64Array(buf))[0];
}
exports.createTokenDouble = createTokenDouble;
/**
* Shift a 64-bit int right 32 bits
*/
function shr32(x) {
return Math.floor(x / BITS32);
}
/**
* Shift a 64-bit left 32 bits
*/
function shl32(x) {
return x * BITS32;
}
/**
* Extract the encoded integer out of the special Double value
*
* Returns undefined if the float is a not an encoded token.
*/
function extractTokenDouble(encoded) {
const buf = new ArrayBuffer(8);
(new Float64Array(buf))[0] = encoded;
const ints = new Uint32Array(buf);
// tslint:disable:no-bitwise
if ((ints[1] & 0xFFFF0000) !== DOUBLE_TOKEN_MARKER_BITS) {
return undefined;
}
// Must use + instead of | here (bitwise operations
// will force 32-bits integer arithmetic, + will not).
return ints[0] + shl32(ints[1] & 0xFFFF);
// tslint:enable:no-bitwise
}
exports.extractTokenDouble = extractTokenDouble;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5jb2RpbmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJlbmNvZGluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUNBLDBEQUErRDtBQUMvRCxvQ0FBOEM7QUFFOUMscUZBQXFGO0FBRXhFLFFBQUEseUJBQXlCLEdBQUcsVUFBVSxDQUFDO0FBQ3ZDLFFBQUEsdUJBQXVCLEdBQUcsVUFBVSxDQUFDO0FBQ3JDLFFBQUEsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO0FBRXhCLFFBQUEsZUFBZSxHQUFHLGVBQWUsQ0FBQztBQUUvQyxNQUFNLGdDQUFnQyxHQUFHLFVBQVUsQ0FBQyxpQ0FBeUIsQ0FBQyxDQUFDO0FBQy9FLE1BQU0sOEJBQThCLEdBQUcsVUFBVSxDQUFDLCtCQUF1QixDQUFDLENBQUM7QUFDM0UsTUFBTSx1QkFBdUIsR0FBRyxVQUFVLENBQUMsd0JBQWdCLENBQUMsQ0FBQztBQUU3RCxNQUFNLGtCQUFrQixHQUFHLElBQUksTUFBTSxDQUFDLEdBQUcsZ0NBQWdDLEtBQUssdUJBQWUsTUFBTSx1QkFBdUIsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ25JLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxNQUFNLENBQUMsR0FBRyw4QkFBOEIsS0FBSyx1QkFBZSxNQUFNLHVCQUF1QixFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFFL0g7O0dBRUc7QUFDSCxNQUFhLFdBQVc7SUFldEIsWUFBNkIsR0FBVyxFQUFtQixFQUFVO1FBQXhDLFFBQUcsR0FBSCxHQUFHLENBQVE7UUFBbUIsT0FBRSxHQUFGLEVBQUUsQ0FBUTtJQUNyRSxDQUFDO0lBZkQ7O09BRUc7SUFDSSxNQUFNLENBQUMsU0FBUyxDQUFDLENBQVM7UUFDL0IsT0FBTyxJQUFJLFdBQVcsQ0FBQyxDQUFDLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxNQUFNLENBQUMsWUFBWSxDQUFDLENBQVM7UUFDbEMsT0FBTyxJQUFJLFdBQVcs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d0JBQXdCLENBQUMsQ0FBQyxxQ0FBcUM7SUFDL0YsMkJBQTJCO0lBRTNCLE9BQU8sQ0FBQyxJQUFJLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3BDLENBQUM7QUFwQkQsOENBb0JDO0FBRUQ7O0dBRUc7QUFDSCxTQUFTLEtBQUssQ0FBQyxDQUFTO0lBQ3RCLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUM7QUFDaEMsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBUyxLQUFLLENBQUMsQ0FBUztJQUN0QixPQUFPLENBQUMsR0FBRyxNQUFNLENBQUM7QUFDcEIsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFnQixrQkFBa0IsQ0FBQyxPQUFlO0lBQ2hELE1BQU0sR0FBRyxHQUFHLElBQUksV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQy9CLENBQUMsSUFBSSxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUM7SUFFckMsTUFBTSxJQUFJLEdBQUcsSUFBSSxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUM7SUFFbEMsNEJBQTRCO0lBQzVCLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsVUFBVSxDQUFDLEtBQUssd0JBQXdCLEVBQUU7UUFDdkQsT0FBTyxTQUFTLENBQUM7S0FDbEI7SUFFRCxtREFBbUQ7SUFDbkQsc0RBQXNEO0lBQ3RELE9BQU8sSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUM7SUFDekMsMkJBQTJCO0FBQzdCLENBQUM7QUFmRCxnREFlQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IElGcmFnbWVudENvbmNhdGVuYXRvciwgSVJlc29sdmFibGUgfSBmcm9tICcuLi9yZXNvbHZhYmxlJztcbmltcG9ydCB7IFRva2VuaXplZFN0cmluZ0ZyYWdtZW50cyB9IGZyb20gJy4uL3N0cmluZy1mcmFnbWVudHMnO1xuaW1wb3J0IHsgaXNSZXNvbHZhYmxlT2JqZWN0IH0gZnJvbSAnLi4vdG9rZW4nO1xuXG4vLyBEZXRhaWxzIGZvciBlbmNvZGluZyBhbmQgZGVjb2RpbmcgVG9rZW5zIGludG8gbmF0aXZlIHR5cGVzOyBzaG91bGQgbm90IGJlIGV4cG9ydGVkXG5cbmV4cG9ydCBjb25zdCBCRUdJTl9TVFJJTkdfVE9LRU5fTUFSS0VSID0gJyR7VG9rZW5bJztcbmV4cG9ydCBjb25zdCBCRUdJTl9MSVNUX1RPS0VOX01BUktFUiA9ICcje1Rva2VuWyc7XG5leHBvcnQgY29uc3QgRU5EX1RPS0VOX01BUktFUiA9ICddfSc7XG5cbmV4cG9ydCBjb25zdCBWQUxJRF9LRVlfQ0hBUlMgPSAnYS16QS1aMC05Oi5fLSc7XG5cbmNvbnN0IFFVT1RFRF9CRUdJTl9TVFJJTkdfVE9LRU5fTUFSS0VSID0gcmVnZXhRdW90ZShCRUdJTl9TVFJJTkdfVE9LRU5fTUFSS0VSKTtcbmNvbnN0IFFVT1RFRF9CRUdJTl9MSVNUX1RPS0VOX01BUktFUiA9IHJlZ2V4UXVvdGUoQkVHSU5fTElTVF9UT0tFTl9NQVJLRVIpO1xuY29uc3QgUVVPVEVEX0VORF9UT0tFTl9NQVJLRVIgPSByZWdleFF1b3RlKEVORF9UT0tFTl9NQVJLRVIpO1xuXG5jb25zdCBTVFJJTkdfVE9LRU5fUkVHRVggPSBuZXcgUmVnRXhwKGAke1FVT1RFRF9CRUdJTl9TVFJJTkdfVE9LRU5fTUFSS0VSfShbJHtWQUxJRF9LRVlfQ0hBUlN9XSspJHtRVU9URURfRU5EX1RPS0VOX01BUktFUn1gLCAnZycpO1xuY29uc3QgTElTVF9UT0tFTl9SRUdFWCA9IG5ldyBSZWdFeHAoYCR7UVVPVEVEX0JFR0lOX0xJU1RfVE9LRU5fTUFSS0VSfShbJHtWQUxJRF9LRVlfQ0hBUlN9XSspJHtRVU9URURfRU5EX1RPS0VOX01BUktFUn1gLCAnZycpO1xuXG4vKipcbiAqIEEgc3RyaW5nIHdpdGggbWFya2VycyBpbiBpdCB0aGF0IGNhbiBiZSByZXNvbHZlZCB0byBleHRlcm5hbCB2YWx1ZXNcbiAqL1xuZXhwb3J0IGNsYXNzIFRva2VuU3RyaW5nIHtcbiAgLyoqXG4gICAqIFJldHVybnMgYSBgVG9rZW5TdHJpbmdgIGZvciB0aGlzIHN0cmluZy5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZm9yU3RyaW5nKHM6IHN0cmluZykge1xuICAgIHJldHVybiBuZXcgVG9rZW5TdHJpbmcocywgU1RSSU5HX1RPS0VOX1JFR0VYKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgYFRva2VuU3RyaW5nYCBmb3IgdGhpcyBzdHJpbmcgKG11c3QgYmUgdGhlIGZpcnN0IHN0cmluZyBlbGVtZW50IG9mIHRoZSBsaXN0KVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBmb3JMaXN0VG9rZW4oczogc3RyaW5nKSB7XG4gICAgcmV0dXJuIG5ldyBUb2tlblN0cmluZyhzLCBMSVNUX1RPS0VOX1JFR0VYKTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgc3RyOiBzdHJpbmcsIHByaXZhdGUgcmVhZG9ubHkgcmU6IFJlZ0V4cCkge1xuICB9XG5cbiAgLyoqXG4gICAqIFNwbGl0IHN0cmluZyBvbiBtYXJrZXJzLCBzdWJzdGl0dXRpbmcgbWFya2VycyB3aXRoIFRva2Vuc1xuICAgKi9cbiAgcHVibGljIHNwbGl0KGxvb2t1cDogKGlkOiBzdHJpbmcpID0+IElSZXNvbHZhYmxlKTogVG9rZW5pemVkU3RyaW5nRnJhZ21lbnRzIHtcbiAgICBjb25zdCByZXQgPSBuZXcgVG9rZW5pemVkU3RyaW5nRnJhZ21lbnRzKCk7XG5cbiAgICBsZXQgcmVzdCA9IDA7XG4gICAgdGhpcy5yZS5sYXN0SW5kZXggPSAwOyAvLyBSZXNldFxuICAgIGxldCBtID0gdGhpcy5yZS5leGVjKHRoaXMuc3RyKTtcbiAgICB3aGlsZSAobSkge1xuICAgICAgaWYgKG0uaW5kZXggPiByZXN0KSB7XG4gICAgICAgIHJldC5hZGRMaXRlcmFsKHRoaXMuc3RyLnN1YnN0cmluZyhyZXN0LCBtLmluZGV4KSk7XG4gICAgICB9XG5cbiAgICAgIHJldC5hZGRUb2tlbihsb29rdXAobVsxXSkpO1xuXG4gICAgICByZXN0ID0gdGhpcy5yZS5sYXN0SW5kZXg7XG4gICAgICBtID0gdGhpcy5yZS5leGVjKHRoaXMuc3RyKTtcbiAgICB9XG5cbiAgICBpZiAocmVzdCA8IHRoaXMuc3RyLmxlbmd0aCkge1xuICAgICAgcmV0LmFkZExpdGVyYWwodGhpcy5zdHIuc3Vic3RyaW5nKHJlc3QpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmV0O1xuICB9XG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyBpZiB0aGlzIHN0cmluZyBpbmNsdWRlcyB0b2tlbnMuXG4gICAqL1xuICBwdWJsaWMgdGVzdCgpOiBib29sZWFuIHtcbiAgICB0aGlzLnJlLmxhc3RJbmRleCA9IDA7IC8vIFJlc2V0XG4gICAgcmV0dXJuIHRoaXMucmUudGVzdCh0aGlzLnN0cik7XG4gIH1cbn1cblxuLyoqXG4gKiBRdW90ZSBhIHN0cmluZyBmb3IgdXNlIGluIGEgcmVnZXhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2V4UXVvdGUoczogc3RyaW5nKSB7XG4gIHJldHVybiBzLnJlcGxhY2UoL1suPyorXiRbXFxdXFxcXCgpe318LV0vZywgJ1xcXFwkJicpO1xufVxuXG4vKipcbiAqIENvbmNhdGVuYXRvciB0aGF0IGRpc3JlZ2FyZHMgdGhlIGlucHV0XG4gKlxuICogQ2FuIGJlIHVzZWQgd2hlbiB0cmF2ZXJzaW5nIHRoZSB0b2tlbnMgaXMgaW1wb3J0YW50LCBidXQgdGhlXG4gKiByZXN1bHQgaXNuJ3QuXG4gKi9cbmV4cG9ydCBjbGFzcyBOdWxsQ29uY2F0IGltcGxlbWVudHMgSUZyYWdtZW50Q29uY2F0ZW5hdG9yIHtcbiAgcHVibGljIGpvaW4oX2xlZnQ6IGFueSB8IHVuZGVmaW5lZCwgX3JpZ2h0OiBhbnkgfCB1bmRlZmluZWQpOiBhbnkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNvbnRhaW5zTGlzdFRva2VuRWxlbWVudCh4czogYW55W10pIHtcbiAgcmV0dXJuIHhzLnNvbWUoeCA9PiB0eXBlb2YoeCkgPT09ICdzdHJpbmcnICYmIFRva2VuU3RyaW5nLmZvckxpc3RUb2tlbih4KS50ZXN0KCkpO1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiBvYmogaXMgYSB0b2tlbiAoaS5lLiBoYXMgdGhlIHJlc29sdmUoKSBtZXRob2Qgb3IgaXMgYSBzdHJpbmdcbiAqIHRoYXQgaW5jbHVkZXMgdG9rZW4gbWFya2VycyksIG9yIGl0J3MgYSBsaXN0aWZpY3RhaW9uIG9mIGEgVG9rZW4gc3RyaW5nLlxuICpcbiAqIEBwYXJhbSBvYmogVGhlIG9iamVjdCB0byB0ZXN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gdW5yZXNvbHZlZChvYmo6IGFueSk6IGJvb2xlYW4ge1xuICBpZiAodHlwZW9mKG9iaikgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIFRva2VuU3RyaW5nLmZvclN0cmluZyhvYmopLnRlc3QoKTtcbiAgfSBlbHNlIGlmICh0eXBlb2Ygb2JqID09PSAnbnVtYmVyJykge1xuICAgIHJldHVybiBleHRyYWN0VG9rZW5Eb3VibGUob2JqKSAhPT0gdW5kZWZpbmVkO1xuICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkob2JqKSAmJiBvYmoubGVuZ3RoID09PSAxKSB7XG4gICAgcmV0dXJuIHR5cGVvZihvYmpbMF0pID09PSAnc3RyaW5nJyAmJiBUb2tlblN0cmluZy5mb3JMaXN0VG9rZW4ob2JqWzBdKS50ZXN0KCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGlzUmVzb2x2YWJsZU9iamVjdChvYmopO1xuICB9XG59XG5cbi8qKlxuICogQml0IHBhdHRlcm4gaW4gdGhlIHRvcCAxNiBiaXRzIG9mIGEgZG91YmxlIHRvIGluZGljYXRlIGEgVG9rZW5cbiAqXG4gKiBBbiBJRUVFIGRvdWJsZSBpbiBMRSBtZW1vcnkgb3JkZXIgbG9va3MgbGlrZSB0aGlzIChncm91cGVkXG4gKiBpbnRvIG9jdGV0cywgdGhlbiBncm91cGVkIGludG8gMzItYml0IHdvcmRzKTpcbiAqXG4gKiBtbW1tbW1tbS5tbW1tbW1tbS5tbW1tbW1tbS5tbW1tbW1tbSB8IG1tbW1tbW1tLm1tbW1tbW1tLkVFRUVtbW1tLnNFRUVFRUVFXG4gKlxuICogLSBtOiBtYW50aXNzYSAoNTIgYml0cylcbiAqIC0gRTogZXhwb25lbnQgKDExIGJpdHMpXG4gKiAtIHM6IHNpZ24gKDEgYml0KVxuICpcbiAqIFdlIHB1dCB0aGUgZm9sbG93aW5nIG1hcmtlciBpbnRvIHRoZSB0b3AgMTYgYml0cyAoZXhwb25lbnQgYW5kIHNpZ24pLCBhbmRcbiAqIHVzZSB0aGUgbWFudGlzc2EgcGFydCB0byBlbmNvZGUgdGhlIHRva2VuIGluZGV4LiBUbyBzYXZlIHNvbWUgYml0IHR3aWRkbGluZ1xuICogd2UgdXNlIGFsbCB0b3AgMTYgYml0cyBmb3IgdGhlIHRhZy4gVGhhdCBsb3NlcyB1cyA0IG1hbnRpc3NhIGJpdHMgdG8gc3RvcmVcbiAqIGluZm9ybWF0aW9uIGluIGJ1dCB3ZSBzdGlsbCBoYXZlIDQ4LCB3aGljaCBpcyBnb2luZyB0byBiZSBwbGVudHkgZm9yIGFueVxuICogbnVtYmVyIG9mIHRva2VucyB0byBiZSBjcmVhdGVkIGR1cmluZyB0aGUgbGlmZXRpbWUgb2YgYW55IENESyBhcHBsaWNhdGlvbi5cbiAqXG4gKiBDYW4ndCBoYXZlIGFsbCBiaXRzIHNldCBiZWNhdXNlIHRoYXQgbWFrZXMgYSBOYU4sIHNvIHVuc2V0IHRoZSBsZWFzdFxuICogc2lnbmlmaWNhbnQgZXhwb25lbnQgYml0LlxuICpcbiAqIEN1cnJlbnRseSBub3Qgc3VwcG9ydGluZyBCRSBhcmNoaXRlY3R1cmVzLlxuICovXG4vLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tYml0d2lzZVxuY29uc3QgRE9VQkxFX1RPS0VOX01BUktFUl9CSVRTID0gMHhGQkZGIDw8IDE2O1xuXG4vKipcbiAqIEhpZ2hlc3QgZW5jb2RhYmxlIG51bWJlclxuICovXG5jb25zdCBNQVhfRU5DT0RBQkxFX0lOVEVHRVIgPSBNYXRoLnBvdygyLCA0OCkgLSAxO1xuXG4vKipcbiAqIEdldCAyXjMyIGFzIGEgbnVtYmVyLCBzbyB3ZSBjYW4gZG8gbXVsdGlwbGljYXRpb24gYW5kIGRpdiBpbnN0ZWFkIG9mIGJpdCBzaGlmdGluZ1xuICpcbiAqIE5lY2Vzc2FyeSBiZWNhdXNlIGluIEphdmFTY3JpcHQsIGJpdCBvcGVyYXRpb25zIGltcGxpY2l0bHkgY29udmVydFxuICogdG8gaW50MzIgYW5kIHdlIG5lZWQgdGhlbSB0byB3b3JrIG9uIFwiaW50NjRcInMuXG4gKlxuICogU28gaW5zdGVhZCBvZiB4ID4+IDMyLCB3ZSBkbyBNYXRoLmZsb29yKHggLyAyXjMyKSwgYW5kIHZpY2UgdmVyc2EuXG4gKi9cbmNvbnN0IEJJVFMzMiA9IE1hdGgucG93KDIsIDMyKTtcblxuLyoqXG4gKiBSZXR1cm4gYSBzcGVjaWFsIERvdWJsZSB2YWx1ZSB0aGF0IGVuY29kZXMgdGhlIGdpdmVuIG5vbm5lZ2F0aXZlIGludGVnZXJcbiAqXG4gKiBXZSB1c2UgdGhpcyB0byBlbmNvZGUgVG9rZW4gb3JkaW5hbHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVUb2tlbkRvdWJsZSh4OiBudW1iZXIpIHtcbiAgaWYgKE1hdGguZmxvb3IoeCkgIT09IHggfHwgeCA8IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhbiBvbmx5IGVuY29kZSBwb3NpdGl2ZSBpbnRlZ2VycycpO1xuICB9XG4gIGlmICh4ID4gTUFYX0VOQ09EQUJMRV9JTlRFR0VSKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBHb3QgYW4gaW5kZXggdG9vIGxhcmdlIHRvIGVuY29kZTogJHt4fWApO1xuICB9XG5cbiAgY29uc3QgYnVmID0gbmV3IEFycmF5QnVmZmVyKDgpO1xuICBjb25zdCBpbnRzID0gbmV3IFVpbnQzMkFycmF5KGJ1Zik7XG5cbiAgLy8gdHNsaW50OmRpc2FibGU6bm8tYml0d2lzZVxuICBpbnRzWzBdID0gIHggJiAweDAwMDBGRkZGRkZGRjsgLy8gQm90dG9tIDMyIGJpdHMgb2YgbnVtYmVyXG5cbiAgLy8gVGhpcyBuZWVkcyBhbiBcInggPj4gMzJcIiBidXQgdGhhdCB3aWxsIG1ha2UgaXQgYSAzMi1iaXQgbnVtYmVyIGluc3RlYWRcbiAgLy8gb2YgYSA2NC1iaXQgbnVtYmVyLlxuICBpbnRzWzFdID0gKHNocjMyKHgpICYgMHhGRkZGKSB8IERPVUJMRV9UT0tFTl9NQVJLRVJfQklUUzsgLy8gVG9wIDE2IGJpdHMgb2YgbnVtYmVyIGFuZCB0aGUgbWFza1xuICAvLyB0c2xpbnQ6ZW5hYmxlOm5vLWJpdHdpc2VcblxuICByZXR1cm4gKG5ldyBGbG9hdDY0QXJyYXkoYnVmKSlbMF07XG59XG5cbi8qKlxuICogU2hpZnQgYSA2NC1iaXQgaW50IHJpZ2h0IDMyIGJpdHNcbiAqL1xuZnVuY3Rpb24gc2hyMzIoeDogbnVtYmVyKSB7XG4gIHJldHVybiBNYXRoLmZsb29yKHggLyBCSVRTMzIpO1xufVxuXG4vKipcbiAqIFNoaWZ0IGEgNjQtYml0IGxlZnQgMzIgYml0c1xuICovXG5mdW5jdGlvbiBzaGwzMih4OiBudW1iZXIpIHtcbiAgcmV0dXJuIHggKiBCSVRTMzI7XG59XG5cbi8qKlxuICogRXh0cmFjdCB0aGUgZW5jb2RlZCBpbnRlZ2VyIG91dCBvZiB0aGUgc3BlY2lhbCBEb3VibGUgdmFsdWVcbiAqXG4gKiBSZXR1cm5zIHVuZGVmaW5lZCBpZiB0aGUgZmxvYXQgaXMgYSBub3QgYW4gZW5jb2RlZCB0b2tlbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGV4dHJhY3RUb2tlbkRvdWJsZShlbmNvZGVkOiBudW1iZXIpOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICBjb25zdCBidWYgPSBuZXcgQXJyYXlCdWZmZXIoOCk7XG4gIChuZXcgRmxvYXQ2NEFycmF5KGJ1ZikpWzBdID0gZW5jb2RlZDtcblxuICBjb25zdCBpbnRzID0gbmV3IFVpbnQzMkFycmF5KGJ1Zik7XG5cbiAgLy8gdHNsaW50OmRpc2FibGU6bm8tYml0d2lzZVxuICBpZiAoKGludHNbMV0gJiAweEZGRkYwMDAwKSAhPT0gRE9VQkxFX1RPS0VOX01BUktFUl9CSVRTKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8vIE11c3QgdXNlICsgaW5zdGVhZCBvZiB8IGhlcmUgKGJpdHdpc2Ugb3BlcmF0aW9uc1xuICAvLyB3aWxsIGZvcmNlIDMyLWJpdHMgaW50ZWdlciBhcml0aG1ldGljLCArIHdpbGwgbm90KS5cbiAgcmV0dXJuIGludHNbMF0gKyBzaGwzMihpbnRzWzFdICYgMHhGRkZGKTtcbiAgLy8gdHNsaW50OmVuYWJsZTpuby1iaXR3aXNlXG59XG4iXX0=