@aws-cdk/core
Version:
AWS Cloud Development Kit Core Library
207 lines • 22.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.withResolved = exports.isResolvableObject = exports.Tokenization = exports.Token = exports.TokenComparison = void 0;
const lazy_1 = require("./lazy");
const encoding_1 = require("./private/encoding");
const intrinsic_1 = require("./private/intrinsic");
const resolve_1 = require("./private/resolve");
const token_map_1 = require("./private/token-map");
/**
* An enum-like class that represents the result of comparing two Tokens.
*
* The return type of {@link Token.compareStrings}.
*/
class TokenComparison {
constructor() {
}
}
exports.TokenComparison = TokenComparison;
/**
* This means we're certain the two components are NOT Tokens, and identical.
*/
TokenComparison.SAME = new TokenComparison();
/**
* This means we're certain the two components are NOT Tokens, and different.
*/
TokenComparison.DIFFERENT = new TokenComparison();
/**
* This means exactly one of the components is a Token.
*/
TokenComparison.ONE_UNRESOLVED = new TokenComparison();
/**
* This means both components are Tokens.
*/
TokenComparison.BOTH_UNRESOLVED = new TokenComparison();
/**
* Represents a special or lazily-evaluated value.
*
* Can be used to delay evaluation of a certain value in case, for example,
* that it requires some context or late-bound data. Can also be used to
* mark values that need special processing at document rendering time.
*
* Tokens can be embedded into strings while retaining their original
* semantics.
*/
class Token {
/**
* Returns true if obj represents an unresolved value.
*
* One of these must be true:
*
* - `obj` is an IResolvable
* - `obj` is a string containing at least one encoded `IResolvable`
* - `obj` is either an encoded number or list
*
* This does NOT recurse into lists or objects to see if they
* containing resolvables.
*
* @param obj The object to test.
*/
static isUnresolved(obj) {
return encoding_1.unresolved(obj);
}
/**
* Return a reversible string representation of this token.
*
* If the Token is initialized with a literal, the stringified value of the
* literal is returned. Otherwise, a special quoted string representation
* of the Token is returned that can be embedded into other strings.
*
* Strings with quoted Tokens in them can be restored back into
* complex values with the Tokens restored by calling `resolve()`
* on the string.
*/
static asString(value, options = {}) {
if (typeof value === 'string') {
return value;
}
return token_map_1.TokenMap.instance().registerString(Token.asAny(value), options.displayHint);
}
/**
* Return a reversible number representation of this token.
*/
static asNumber(value) {
if (typeof value === 'number') {
return value;
}
return token_map_1.TokenMap.instance().registerNumber(Token.asAny(value));
}
/**
* Return a reversible list representation of this token.
*/
static asList(value, options = {}) {
if (Array.isArray(value) && value.every(x => typeof x === 'string')) {
return value;
}
return token_map_1.TokenMap.instance().registerList(Token.asAny(value), options.displayHint);
}
/**
* Return a resolvable representation of the given value.
*/
static asAny(value) {
return isResolvableObject(value) ? value : new intrinsic_1.Intrinsic(value);
}
/**
* Compare two strings that might contain Tokens with each other.
*/
static compareStrings(possibleToken1, possibleToken2) {
const firstIsUnresolved = Token.isUnresolved(possibleToken1);
const secondIsUnresolved = Token.isUnresolved(possibleToken2);
if (firstIsUnresolved && secondIsUnresolved) {
return TokenComparison.BOTH_UNRESOLVED;
}
if (firstIsUnresolved || secondIsUnresolved) {
return TokenComparison.ONE_UNRESOLVED;
}
return possibleToken1 === possibleToken2 ? TokenComparison.SAME : TokenComparison.DIFFERENT;
}
constructor() {
}
}
exports.Token = Token;
/**
* Less oft-needed functions to manipulate Tokens.
*/
class Tokenization {
/**
* Un-encode a string potentially containing encoded tokens.
*/
static reverseString(s) {
return token_map_1.TokenMap.instance().splitString(s);
}
/**
* Un-encode a Tokenized value from a number.
*/
static reverseNumber(n) {
return token_map_1.TokenMap.instance().lookupNumberToken(n);
}
/**
* Un-encode a Tokenized value from a list.
*/
static reverseList(l) {
return token_map_1.TokenMap.instance().lookupList(l);
}
/**
* Resolves an object by evaluating all tokens and removing any undefined or empty objects or arrays.
*
* Values can only be primitives, arrays or tokens. Other objects (i.e. with methods) will be rejected.
*
* @param obj The object to resolve.
* @param options Prefix key path components for diagnostics.
*/
static resolve(obj, options) {
return resolve_1.resolve(obj, {
scope: options.scope,
resolver: options.resolver,
preparing: (options.preparing !== undefined ? options.preparing : false),
});
}
/**
* Return whether the given object is an IResolvable object.
*
* This is different from Token.isUnresolved() which will also check for
* encoded Tokens, whereas this method will only do a type check on the given
* object.
*/
static isResolvable(obj) {
return isResolvableObject(obj);
}
/**
* Stringify a number directly or lazily if it's a Token.
*
* If it is an object (i.e., { Ref: 'SomeLogicalId' }), return it as-is.
*/
static stringifyNumber(x) {
// only convert numbers to strings so that Refs, conditions, and other things don't end up synthesizing as [object object]
if (Token.isUnresolved(x)) {
return lazy_1.Lazy.stringValue({
produce: context => {
const resolved = context.resolve(x);
return typeof resolved !== 'number' ? resolved : `${resolved}`;
},
});
}
else {
return typeof x !== 'number' ? x : `${x}`;
}
}
constructor() {
}
}
exports.Tokenization = Tokenization;
function isResolvableObject(x) {
return typeof (x) === 'object' && x !== null && typeof x.resolve === 'function';
}
exports.isResolvableObject = isResolvableObject;
function withResolved(...args) {
if (args.length < 2) {
return;
}
const argArray = args.slice(0, args.length - 1);
if (argArray.some(Token.isUnresolved)) {
return;
}
args[args.length - 1].apply(arguments, argArray);
}
exports.withResolved = withResolved;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9rZW4uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ0b2tlbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSxpQ0FBOEI7QUFDOUIsaURBQWdEO0FBQ2hELG1EQUFnRDtBQUNoRCwrQ0FBNEM7QUFDNUMsbURBQStDOzs7Ozs7QUFRL0MsTUFBYSxlQUFlO0lBbUIxQjtJQUNBLENBQUM7O0FBcEJILDBDQXFCQzs7OztBQWhCd0Isb0JBQUksR0FBRyxJQUFJLGVBQWUsRUFBRSxDQUFDOzs7O0FBTTdCLHlCQUFTLEdBQUcsSUFBSSxlQUFlLEVBQUUsQ0FBQzs7OztBQUdsQyw4QkFBYyxHQUFHLElBQUksZUFBZSxFQUFFLENBQUM7Ozs7QUFHdkMsK0JBQWUsR0FBRyxJQUFJLGVBQWUsRUFBRSxDQUFDOzs7Ozs7Ozs7OztBQWdCakUsTUFBYSxLQUFLOzs7Ozs7Ozs7Ozs7Ozs7SUFlVCxNQUFNLENBQUMsWUFBWSxDQUFDLEdBQVE7UUFDakMsT0FBTyxxQkFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3pCLENBQUM7Ozs7Ozs7Ozs7OztJQWFNLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBVSxFQUFFLFVBQTJCLEVBQUU7UUFDOUQsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLEVBQUU7WUFBRSxPQUFPLEtBQUssQ0FBQztTQUFFO1FBQ2hELE9BQU8sb0JBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsRUFBRSxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDckYsQ0FBQzs7OztJQUtNLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBVTtRQUMvQixJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsRUFBRTtZQUFFLE9BQU8sS0FBSyxDQUFDO1NBQUU7UUFDaEQsT0FBTyxvQkFBUSxDQUFDLFFBQVEsRUFBRSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxD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QUMsQ0FBQyxDQUFDLENBQUM7b0JBQ3BDLE9BQU8sT0FBTyxRQUFRLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsUUFBUSxFQUFFLENBQUM7Z0JBQ2pFLENBQUM7YUFDRixDQUFDLENBQUM7U0FDSjthQUFNO1lBQ0wsT0FBTyxPQUFPLENBQUMsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztTQUMzQztJQUNILENBQUM7SUFFRDtJQUNBLENBQUM7Q0FDRjtBQXBFRCxvQ0FvRUM7QUFzQ0QsU0FBZ0Isa0JBQWtCLENBQUMsQ0FBTTtJQUN2QyxPQUFPLE9BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxRQUFRLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEtBQUssVUFBVSxDQUFDO0FBQ2pGLENBQUM7QUFGRCxnREFFQztBQVdELFNBQWdCLFlBQVksQ0FBQyxHQUFHLElBQVc7SUFDekMsSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtRQUFFLE9BQU87S0FBRTtJQUNoQyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ2hELElBQUksUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLEVBQUU7UUFBRSxPQUFPO0tBQUU7SUFDbEQsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSxRQUFRLENBQUMsQ0FBQztBQUNuRCxDQUFDO0FBTEQsb0NBS0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgeyBMYXp5IH0gZnJvbSAnLi9sYXp5JztcbmltcG9ydCB7IHVucmVzb2x2ZWQgfSBmcm9tICcuL3ByaXZhdGUvZW5jb2RpbmcnO1xuaW1wb3J0IHsgSW50cmluc2ljIH0gZnJvbSAnLi9wcml2YXRlL2ludHJpbnNpYyc7XG5pbXBvcnQgeyByZXNvbHZlIH0gZnJvbSAnLi9wcml2YXRlL3Jlc29sdmUnO1xuaW1wb3J0IHsgVG9rZW5NYXAgfSBmcm9tICcuL3ByaXZhdGUvdG9rZW4tbWFwJztcbmltcG9ydCB7IElSZXNvbHZhYmxlLCBJVG9rZW5SZXNvbHZlciB9IGZyb20gJy4vcmVzb2x2YWJsZSc7XG5pbXBvcnQgeyBUb2tlbml6ZWRTdHJpbmdGcmFnbWVudHMgfSBmcm9tICcuL3N0cmluZy1mcmFnbWVudHMnO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5leHBvcnQgY2xhc3MgVG9rZW5Db21wYXJpc29uIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IFNBTUUgPSBuZXcgVG9rZW5Db21wYXJpc29uKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IERJRkZFUkVOVCA9IG5ldyBUb2tlbkNvbXBhcmlzb24oKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IE9ORV9VTlJFU09MVkVEID0gbmV3IFRva2VuQ29tcGFyaXNvbigpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IEJPVEhfVU5SRVNPTFZFRCA9IG5ldyBUb2tlbkNvbXBhcmlzb24oKTtcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKCkge1xuICB9XG59XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuZXhwb3J0IGNsYXNzIFRva2VuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgc3RhdGljIGlzVW5yZXNvbHZlZChvYmo6IGFueSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB1bnJlc29sdmVkKG9iaik7XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHN0YXRpYyBhc1N0cmluZyh2YWx1ZTogYW55LCBvcHRpb25zOiBFbmNvZGluZ09wdGlvbnMgPSB7fSk6IHN0cmluZyB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHsgcmV0dXJuIHZhbHVlOyB9XG4gICAgcmV0dXJuIFRva2VuTWFwLmluc3RhbmNlKCkucmVnaXN0ZXJTdHJpbmcoVG9rZW4uYXNBbnkodmFsdWUpLCBvcHRpb25zLmRpc3BsYXlIaW50KTtcbiAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHN0YXRpYyBhc051bWJlcih2YWx1ZTogYW55KTogbnVtYmVyIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykgeyByZXR1cm4gdmFsdWU7IH1cbiAgICByZXR1cm4gVG9rZW5NYXAuaW5zdGFuY2UoKS5yZWdpc3Rlck51bWJlcihUb2tlbi5hc0FueSh2YWx1ZSkpO1xuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHN0YXRpYyBhc0xpc3QodmFsdWU6IGFueSwgb3B0aW9uczogRW5jb2RpbmdPcHRpb25zID0ge30pOiBzdHJpbmdbXSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpICYmIHZhbHVlLmV2ZXJ5KHggPT4gdHlwZW9mIHggPT09ICdzdHJpbmcnKSkgeyByZXR1cm4gdmFsdWU7IH1cbiAgICByZXR1cm4gVG9rZW5NYXAuaW5zdGFuY2UoKS5yZWdpc3Rlckxpc3QoVG9rZW4uYXNBbnkodmFsdWUpLCBvcHRpb25zLmRpc3BsYXlIaW50KTtcbiAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyBzdGF0aWMgYXNBbnkodmFsdWU6IGFueSk6IElSZXNvbHZhYmxlIHtcbiAgICByZXR1cm4gaXNSZXNvbHZhYmxlT2JqZWN0KHZhbHVlKSA/IHZhbHVlIDogbmV3IEludHJpbnNpYyh2YWx1ZSk7XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHN0YXRpYyBjb21wYXJlU3RyaW5ncyhwb3NzaWJsZVRva2VuMTogc3RyaW5nLCBwb3NzaWJsZVRva2VuMjogc3RyaW5nKTogVG9rZW5Db21wYXJpc29uIHtcbiAgICBjb25zdCBmaXJzdElzVW5yZXNvbHZlZCA9IFRva2VuLmlzVW5yZXNvbHZlZChwb3NzaWJsZVRva2VuMSk7XG4gICAgY29uc3Qgc2Vjb25kSXNVbnJlc29sdmVkID0gVG9rZW4uaXNVbnJlc29sdmVkKHBvc3NpYmxlVG9rZW4yKTtcblxuICAgIGlmIChmaXJzdElzVW5yZXNvbHZlZCAmJiBzZWNvbmRJc1VucmVzb2x2ZWQpIHtcbiAgICAgIHJldHVybiBUb2tlbkNvbXBhcmlzb24uQk9USF9VTlJFU09MVkVEO1xuICAgIH1cbiAgICBpZiAoZmlyc3RJc1VucmVzb2x2ZWQgfHwgc2Vjb25kSXNVbnJlc29sdmVkKSB7XG4gICAgICByZXR1cm4gVG9rZW5Db21wYXJpc29uLk9ORV9VTlJFU09MVkVEO1xuICAgIH1cblxuICAgIHJldHVybiBwb3NzaWJsZVRva2VuMSA9PT0gcG9zc2libGVUb2tlbjIgPyBUb2tlbkNvbXBhcmlzb24uU0FNRSA6IFRva2VuQ29tcGFyaXNvbi5ESUZGRVJFTlQ7XG4gIH1cblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKCkge1xuICB9XG59XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuZXhwb3J0IGNsYXNzIFRva2VuaXphdGlvbiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyBzdGF0aWMgcmV2ZXJzZVN0cmluZyhzOiBzdHJpbmcpOiBUb2tlbml6ZWRTdHJpbmdGcmFnbWVudHMge1xuICAgIHJldHVybiBUb2tlbk1hcC5pbnN0YW5jZSgpLnNwbGl0U3RyaW5nKHMpO1xuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHN0YXRpYyByZXZlcnNlTnVtYmVyKG46IG51bWJlcik6IElSZXNvbHZhYmxlIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gVG9rZW5NYXAuaW5zdGFuY2UoKS5sb29rdXBOdW1iZXJUb2tlbihuKTtcbiAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgc3RhdGljIHJldmVyc2VMaXN0KGw6IHN0cmluZ1tdKTogSVJlc29sdmFibGUgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBUb2tlbk1hcC5pbnN0YW5jZSgpLmxvb2t1cExpc3QobCk7XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHN0YXRpYyByZXNvbHZlKG9iajogYW55LCBvcHRpb25zOiBSZXNvbHZlT3B0aW9ucyk6IGFueSB7XG4gICAgcmV0dXJuIHJlc29sdmUob2JqLCB7XG4gICAgICBzY29wZTogb3B0aW9ucy5zY29wZSxcbiAgICAgIHJlc29sdmVyOiBvcHRpb25zLnJlc29sdmVyLFxuICAgICAgcHJlcGFyaW5nOiAob3B0aW9ucy5wcmVwYXJpbmcgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMucHJlcGFyaW5nIDogZmFsc2UpLFxuICAgIH0pO1xuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgc3RhdGljIGlzUmVzb2x2YWJsZShvYmo6IGFueSk6IG9iaiBpcyBJUmVzb2x2YWJsZSB7XG4gICAgcmV0dXJuIGlzUmVzb2x2YWJsZU9iamVjdChvYmopO1xuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgc3RhdGljIHN0cmluZ2lmeU51bWJlcih4OiBudW1iZXIpIHtcbiAgICAvLyBvbmx5IGNvbnZlcnQgbnVtYmVycyB0byBzdHJpbmdzIHNvIHRoYXQgUmVmcywgY29uZGl0aW9ucywgYW5kIG90aGVyIHRoaW5ncyBkb24ndCBlbmQgdXAgc3ludGhlc2l6aW5nIGFzIFtvYmplY3Qgb2JqZWN0XVxuXG4gICAgaWYgKFRva2VuLmlzVW5yZXNvbHZlZCh4KSkge1xuICAgICAgcmV0dXJuIExhenkuc3RyaW5nVmFsdWUoe1xuICAgICAgICBwcm9kdWNlOiBjb250ZXh0ID0+IHtcbiAgICAgICAgICBjb25zdCByZXNvbHZlZCA9IGNvbnRleHQucmVzb2x2ZSh4KTtcbiAgICAgICAgICByZXR1cm4gdHlwZW9mIHJlc29sdmVkICE9PSAnbnVtYmVyJyA/IHJlc29sdmVkIDogYCR7cmVzb2x2ZWR9YDtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdHlwZW9mIHggIT09ICdudW1iZXInID8geCA6IGAke3h9YDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKCkge1xuICB9XG59XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbmV4cG9ydCBpbnRlcmZhY2UgUmVzb2x2ZU9wdGlvbnMge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBzY29wZTogSUNvbnN0cnVjdDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IHJlc29sdmVyOiBJVG9rZW5SZXNvbHZlcjtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgcHJlcGFyaW5nPzogYm9vbGVhbjtcbn1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbmV4cG9ydCBpbnRlcmZhY2UgRW5jb2RpbmdPcHRpb25zIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IGRpc3BsYXlIaW50Pzogc3RyaW5nO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNSZXNvbHZhYmxlT2JqZWN0KHg6IGFueSk6IHggaXMgSVJlc29sdmFibGUge1xuICByZXR1cm4gdHlwZW9mKHgpID09PSAnb2JqZWN0JyAmJiB4ICE9PSBudWxsICYmIHR5cGVvZiB4LnJlc29sdmUgPT09ICdmdW5jdGlvbic7XG59XG5cbi8qKlxuICogQ2FsbCB0aGUgZ2l2ZW4gZnVuY3Rpb24gb25seSBpZiBhbGwgZ2l2ZW4gdmFsdWVzIGFyZSByZXNvbHZlZFxuICpcbiAqIEV4cG9ydGVkIGFzIGEgZnVuY3Rpb24gc2luY2UgaXQgd2lsbCBiZSB1c2VkIGJ5IFR5cGVTY3JpcHQgbW9kdWxlcywgYnV0XG4gKiBjYW4ndCBiZSBleHBvc2VkIHZpYSBKU0lJIGJlY2F1c2Ugb2YgdGhlIGdlbmVyaWNzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gd2l0aFJlc29sdmVkPEE+KGE6IEEsIGZuOiAoYTogQSkgPT4gdm9pZCk6IHZvaWQ7XG5leHBvcnQgZnVuY3Rpb24gd2l0aFJlc29sdmVkPEEsIEI+KGE6IEEsIGI6IEIsIGZuOiAoYTogQSwgYjogQikgPT4gdm9pZCk6IHZvaWQ7XG5leHBvcnQgZnVuY3Rpb24gd2l0aFJlc29sdmVkPEEsIEIsIEM+KGE6IEEsIGI6IEIsIGM6IEMsIGZuOiAoYTogQSwgYjogQiwgYzogQykgPT4gdm9pZCk6IHZvaWQ7XG5leHBvcnQgZnVuY3Rpb24gd2l0aFJlc29sdmVkKC4uLmFyZ3M6IGFueVtdKSB7XG4gIGlmIChhcmdzLmxlbmd0aCA8IDIpIHsgcmV0dXJuOyB9XG4gIGNvbnN0IGFyZ0FycmF5ID0gYXJncy5zbGljZSgwLCBhcmdzLmxlbmd0aCAtIDEpO1xuICBpZiAoYXJnQXJyYXkuc29tZShUb2tlbi5pc1VucmVzb2x2ZWQpKSB7IHJldHVybjsgfVxuICBhcmdzW2FyZ3MubGVuZ3RoIC0gMV0uYXBwbHkoYXJndW1lbnRzLCBhcmdBcnJheSk7XG59XG4iXX0=