UNPKG

@aws-cdk/core

Version:

AWS Cloud Development Kit Core Library

164 lines 17.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const token_1 = require("../token"); const encoding_1 = require("./encoding"); const glob = global; const STRING_SYMBOL = Symbol.for('@aws-cdk/core.TokenMap.STRING'); const LIST_SYMBOL = Symbol.for('@aws-cdk/core.TokenMap.LIST'); const NUMBER_SYMBOL = Symbol.for('@aws-cdk/core.TokenMap.NUMBER'); /** * Central place where we keep a mapping from Tokens to their String representation * * The string representation is used to embed token into strings, * and stored to be able to reverse that mapping. * * All instances of TokenStringMap share the same storage, so that this process * works even when different copies of the library are loaded. */ class TokenMap { constructor() { this.stringTokenMap = new Map(); this.numberTokenMap = new Map(); this.tokenCounter = 0; } /** * Singleton instance of the token string map */ static instance() { if (!glob.__cdkTokenMap) { glob.__cdkTokenMap = new TokenMap(); } return glob.__cdkTokenMap; } /** * Generate a unique string for this Token, returning a key * * Every call for the same Token will produce a new unique string, no * attempt is made to deduplicate. Token objects should cache the * value themselves, if required. * * The token can choose (part of) its own representation string with a * hint. This may be used to produce aesthetically pleasing and * recognizable token representations for humans. */ registerString(token, displayHint) { return cachedValue(token, STRING_SYMBOL, () => { const key = this.registerStringKey(token, displayHint); return `${encoding_1.BEGIN_STRING_TOKEN_MARKER}${key}${encoding_1.END_TOKEN_MARKER}`; }); } /** * Generate a unique string for this Token, returning a key */ registerList(token, displayHint) { return cachedValue(token, LIST_SYMBOL, () => { const key = this.registerStringKey(token, displayHint); return [`${encoding_1.BEGIN_LIST_TOKEN_MARKER}${key}${encoding_1.END_TOKEN_MARKER}`]; }); } /** * Create a unique number representation for this Token and return it */ registerNumber(token) { return cachedValue(token, NUMBER_SYMBOL, () => { return this.registerNumberKey(token); }); } /** * Lookup a token from an encoded value */ tokenFromEncoding(x) { if (typeof x === 'string') { return this.lookupString(x); } if (Array.isArray(x)) { return this.lookupList(x); } if (token_1.Token.isUnresolved(x)) { return x; } return undefined; } /** * Reverse a string representation into a Token object */ lookupString(s) { const fragments = this.splitString(s); if (fragments.tokens.length > 0 && fragments.length === 1) { return fragments.firstToken; } return undefined; } /** * Reverse a string representation into a Token object */ lookupList(xs) { if (xs.length !== 1) { return undefined; } const str = encoding_1.TokenString.forListToken(xs[0]); const fragments = str.split(this.lookupToken.bind(this)); if (fragments.length === 1) { return fragments.firstToken; } return undefined; } /** * Split a string into literals and Tokens */ splitString(s) { const str = encoding_1.TokenString.forString(s); return str.split(this.lookupToken.bind(this)); } /** * Reverse a number encoding into a Token, or undefined if the number wasn't a Token */ lookupNumberToken(x) { const tokenIndex = encoding_1.extractTokenDouble(x); if (tokenIndex === undefined) { return undefined; } const t = this.numberTokenMap.get(tokenIndex); if (t === undefined) { throw new Error('Encoded representation of unknown number Token found'); } return t; } /** * Find a Token by key. * * This excludes the token markers. */ lookupToken(key) { const token = this.stringTokenMap.get(key); if (!token) { throw new Error(`Unrecognized token key: ${key}`); } return token; } registerStringKey(token, displayHint) { const counter = this.tokenCounter++; const representation = (displayHint || `TOKEN`).replace(new RegExp(`[^${encoding_1.VALID_KEY_CHARS}]`, 'g'), '.'); const key = `${representation}.${counter}`; this.stringTokenMap.set(key, token); return key; } registerNumberKey(token) { const counter = this.tokenCounter++; this.numberTokenMap.set(counter, token); return encoding_1.createTokenDouble(counter); } } exports.TokenMap = TokenMap; /** * Get a cached value for an object, storing it on the object in a symbol */ function cachedValue(x, sym, prod) { let cached = x[sym]; if (cached === undefined) { cached = prod(); Object.defineProperty(x, sym, { value: cached }); } return cached; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9rZW4tbWFwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsidG9rZW4tbWFwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBRUEsb0NBQWlDO0FBQ2pDLHlDQUN5RjtBQUV6RixNQUFNLElBQUksR0FBRyxNQUFhLENBQUM7QUFFM0IsTUFBTSxhQUFhLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO0FBQ2xFLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsNkJBQTZCLENBQUMsQ0FBQztBQUM5RCxNQUFNLGFBQWEsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLCtCQUErQixDQUFDLENBQUM7QUFFbEU7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFhLFFBQVE7SUFBckI7UUFXbUIsbUJBQWMsR0FBRyxJQUFJLEdBQUcsRUFBdUIsQ0FBQztRQUNoRCxtQkFBYyxHQUFHLElBQUksR0FBRyxFQUF1QixDQUFDO1FBQ3pELGlCQUFZLEdBQUcsQ0FBQyxDQUFDO0lBc0gzQixDQUFDO0lBbElDOztPQUVHO0lBQ0ksTUFBTSxDQUFDLFFBQVE7UUFDcEIsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUU7WUFDdkIsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLFFBQVEsRUFBRSxDQUFDO1NBQ3JDO1FBQ0QsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDO0lBQzVCLENBQUM7SUFNRDs7Ozs7Ozs7OztPQVVHO0lBQ0ksY0FBYyxDQUFDLEtBQWtCLEVBQUUsV0FBb0I7UUFDNUQsT0FBTyxXQUFXLENBQUMsS0FBSyxFQUFFLGFBQWEsRUFBRSxHQUFHLEVBQUU7WUFDNUMsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsQ0FBQztZQUN2RCxPQUFPLEdBQUcsb0NBQXlCLEdBQUcsR0FBRyxHQUFHLDJCQUFnQixFQUFFLENBQUM7UUFDakUsQ0FBQyxDQUFDLENBQUM7SUFDTCxD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QztJQUNwQyxJQUFJLE1BQU0sS0FBSyxTQUFTLEVBQUU7UUFDeEIsTUFBTSxHQUFHLElBQUksRUFBRSxDQUFDO1FBQ2hCLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO0tBQ2xEO0lBQ0QsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IElSZXNvbHZhYmxlIH0gZnJvbSBcIi4uL3Jlc29sdmFibGVcIjtcbmltcG9ydCB7IFRva2VuaXplZFN0cmluZ0ZyYWdtZW50cyB9IGZyb20gXCIuLi9zdHJpbmctZnJhZ21lbnRzXCI7XG5pbXBvcnQgeyBUb2tlbiB9IGZyb20gXCIuLi90b2tlblwiO1xuaW1wb3J0IHsgQkVHSU5fTElTVF9UT0tFTl9NQVJLRVIsIEJFR0lOX1NUUklOR19UT0tFTl9NQVJLRVIsIGNyZWF0ZVRva2VuRG91YmxlLFxuICBFTkRfVE9LRU5fTUFSS0VSLCBleHRyYWN0VG9rZW5Eb3VibGUsIFRva2VuU3RyaW5nLCBWQUxJRF9LRVlfQ0hBUlMgfSBmcm9tIFwiLi9lbmNvZGluZ1wiO1xuXG5jb25zdCBnbG9iID0gZ2xvYmFsIGFzIGFueTtcblxuY29uc3QgU1RSSU5HX1NZTUJPTCA9IFN5bWJvbC5mb3IoJ0Bhd3MtY2RrL2NvcmUuVG9rZW5NYXAuU1RSSU5HJyk7XG5jb25zdCBMSVNUX1NZTUJPTCA9IFN5bWJvbC5mb3IoJ0Bhd3MtY2RrL2NvcmUuVG9rZW5NYXAuTElTVCcpO1xuY29uc3QgTlVNQkVSX1NZTUJPTCA9IFN5bWJvbC5mb3IoJ0Bhd3MtY2RrL2NvcmUuVG9rZW5NYXAuTlVNQkVSJyk7XG5cbi8qKlxuICogQ2VudHJhbCBwbGFjZSB3aGVyZSB3ZSBrZWVwIGEgbWFwcGluZyBmcm9tIFRva2VucyB0byB0aGVpciBTdHJpbmcgcmVwcmVzZW50YXRpb25cbiAqXG4gKiBUaGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGlzIHVzZWQgdG8gZW1iZWQgdG9rZW4gaW50byBzdHJpbmdzLFxuICogYW5kIHN0b3JlZCB0byBiZSBhYmxlIHRvIHJldmVyc2UgdGhhdCBtYXBwaW5nLlxuICpcbiAqIEFsbCBpbnN0YW5jZXMgb2YgVG9rZW5TdHJpbmdNYXAgc2hhcmUgdGhlIHNhbWUgc3RvcmFnZSwgc28gdGhhdCB0aGlzIHByb2Nlc3NcbiAqIHdvcmtzIGV2ZW4gd2hlbiBkaWZmZXJlbnQgY29waWVzIG9mIHRoZSBsaWJyYXJ5IGFyZSBsb2FkZWQuXG4gKi9cbmV4cG9ydCBjbGFzcyBUb2tlbk1hcCB7XG4gIC8qKlxuICAgKiBTaW5nbGV0b24gaW5zdGFuY2Ugb2YgdGhlIHRva2VuIHN0cmluZyBtYXBcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgaW5zdGFuY2UoKTogVG9rZW5NYXAge1xuICAgIGlmICghZ2xvYi5fX2Nka1Rva2VuTWFwKSB7XG4gICAgICBnbG9iLl9fY2RrVG9rZW5NYXAgPSBuZXcgVG9rZW5NYXAoKTtcbiAgICB9XG4gICAgcmV0dXJuIGdsb2IuX19jZGtUb2tlbk1hcDtcbiAgfVxuXG4gIHByaXZhdGUgcmVhZG9ubHkgc3RyaW5nVG9rZW5NYXAgPSBuZXcgTWFwPHN0cmluZywgSVJlc29sdmFibGU+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgbnVtYmVyVG9rZW5NYXAgPSBuZXcgTWFwPG51bWJlciwgSVJlc29sdmFibGU+KCk7XG4gIHByaXZhdGUgdG9rZW5Db3VudGVyID0gMDtcblxuICAvKipcbiAgICogR2VuZXJhdGUgYSB1bmlxdWUgc3RyaW5nIGZvciB0aGlzIFRva2VuLCByZXR1cm5pbmcgYSBrZXlcbiAgICpcbiAgICogRXZlcnkgY2FsbCBmb3IgdGhlIHNhbWUgVG9rZW4gd2lsbCBwcm9kdWNlIGEgbmV3IHVuaXF1ZSBzdHJpbmcsIG5vXG4gICAqIGF0dGVtcHQgaXMgbWFkZSB0byBkZWR1cGxpY2F0ZS4gVG9rZW4gb2JqZWN0cyBzaG91bGQgY2FjaGUgdGhlXG4gICAqIHZhbHVlIHRoZW1zZWx2ZXMsIGlmIHJlcXVpcmVkLlxuICAgKlxuICAgKiBUaGUgdG9rZW4gY2FuIGNob29zZSAocGFydCBvZikgaXRzIG93biByZXByZXNlbnRhdGlvbiBzdHJpbmcgd2l0aCBhXG4gICAqIGhpbnQuIFRoaXMgbWF5IGJlIHVzZWQgdG8gcHJvZHVjZSBhZXN0aGV0aWNhbGx5IHBsZWFzaW5nIGFuZFxuICAgKiByZWNvZ25pemFibGUgdG9rZW4gcmVwcmVzZW50YXRpb25zIGZvciBodW1hbnMuXG4gICAqL1xuICBwdWJsaWMgcmVnaXN0ZXJTdHJpbmcodG9rZW46IElSZXNvbHZhYmxlLCBkaXNwbGF5SGludD86IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGNhY2hlZFZhbHVlKHRva2VuLCBTVFJJTkdfU1lNQk9MLCAoKSA9PiB7XG4gICAgICBjb25zdCBrZXkgPSB0aGlzLnJlZ2lzdGVyU3RyaW5nS2V5KHRva2VuLCBkaXNwbGF5SGludCk7XG4gICAgICByZXR1cm4gYCR7QkVHSU5fU1RSSU5HX1RPS0VOX01BUktFUn0ke2tleX0ke0VORF9UT0tFTl9NQVJLRVJ9YDtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSBhIHVuaXF1ZSBzdHJpbmcgZm9yIHRoaXMgVG9rZW4sIHJldHVybmluZyBhIGtleVxuICAgKi9cbiAgcHVibGljIHJlZ2lzdGVyTGlzdCh0b2tlbjogSVJlc29sdmFibGUsIGRpc3BsYXlIaW50Pzogc3RyaW5nKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBjYWNoZWRWYWx1ZSh0b2tlbiwgTElTVF9TWU1CT0wsICgpID0+IHtcbiAgICAgIGNvbnN0IGtleSA9IHRoaXMucmVnaXN0ZXJTdHJpbmdLZXkodG9rZW4sIGRpc3BsYXlIaW50KTtcbiAgICAgIHJldHVybiBbYCR7QkVHSU5fTElTVF9UT0tFTl9NQVJLRVJ9JHtrZXl9JHtFTkRfVE9LRU5fTUFSS0VSfWBdO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIHVuaXF1ZSBudW1iZXIgcmVwcmVzZW50YXRpb24gZm9yIHRoaXMgVG9rZW4gYW5kIHJldHVybiBpdFxuICAgKi9cbiAgcHVibGljIHJlZ2lzdGVyTnVtYmVyKHRva2VuOiBJUmVzb2x2YWJsZSk6IG51bWJlciB7XG4gICAgcmV0dXJuIGNhY2hlZFZhbHVlKHRva2VuLCBOVU1CRVJfU1lNQk9MLCAoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5yZWdpc3Rlck51bWJlcktleSh0b2tlbik7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogTG9va3VwIGEgdG9rZW4gZnJvbSBhbiBlbmNvZGVkIHZhbHVlXG4gICAqL1xuICBwdWJsaWMgdG9rZW5Gcm9tRW5jb2RpbmcoeDogYW55KTogSVJlc29sdmFibGUgfCB1bmRlZmluZWQge1xuICAgIGlmICh0eXBlb2YgeCA9PT0gJ3N0cmluZycpIHsgcmV0dXJuIHRoaXMubG9va3VwU3RyaW5nKHgpOyB9XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoeCkpIHsgcmV0dXJuIHRoaXMubG9va3VwTGlzdCh4KTsgfVxuICAgIGlmIChUb2tlbi5pc1VucmVzb2x2ZWQoeCkpIHsgcmV0dXJuIHg7IH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldmVyc2UgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gaW50byBhIFRva2VuIG9iamVjdFxuICAgKi9cbiAgcHVibGljIGxvb2t1cFN0cmluZyhzOiBzdHJpbmcpOiBJUmVzb2x2YWJsZSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgZnJhZ21lbnRzID0gdGhpcy5zcGxpdFN0cmluZyhzKTtcbiAgICBpZiAoZnJhZ21lbnRzLnRva2Vucy5sZW5ndGggPiAwICYmIGZyYWdtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgIHJldHVybiBmcmFnbWVudHMuZmlyc3RUb2tlbjtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXZlcnNlIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGludG8gYSBUb2tlbiBvYmplY3RcbiAgICovXG4gIHB1YmxpYyBsb29rdXBMaXN0KHhzOiBzdHJpbmdbXSk6IElSZXNvbHZhYmxlIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoeHMubGVuZ3RoICE9PSAxKSB7IHJldHVybiB1bmRlZmluZWQ7IH1cbiAgICBjb25zdCBzdHIgPSBUb2tlblN0cmluZy5mb3JMaXN0VG9rZW4oeHNbMF0pO1xuICAgIGNvbnN0IGZyYWdtZW50cyA9IHN0ci5zcGxpdCh0aGlzLmxvb2t1cFRva2VuLmJpbmQodGhpcykpO1xuICAgIGlmIChmcmFnbWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICByZXR1cm4gZnJhZ21lbnRzLmZpcnN0VG9rZW47XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogU3BsaXQgYSBzdHJpbmcgaW50byBsaXRlcmFscyBhbmQgVG9rZW5zXG4gICAqL1xuICBwdWJsaWMgc3BsaXRTdHJpbmcoczogc3RyaW5nKTogVG9rZW5pemVkU3RyaW5nRnJhZ21lbnRzIHtcbiAgICBjb25zdCBzdHIgPSBUb2tlblN0cmluZy5mb3JTdHJpbmcocyk7XG4gICAgcmV0dXJuIHN0ci5zcGxpdCh0aGlzLmxvb2t1cFRva2VuLmJpbmQodGhpcykpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldmVyc2UgYSBudW1iZXIgZW5jb2RpbmcgaW50byBhIFRva2VuLCBvciB1bmRlZmluZWQgaWYgdGhlIG51bWJlciB3YXNuJ3QgYSBUb2tlblxuICAgKi9cbiAgcHVibGljIGxvb2t1cE51bWJlclRva2VuKHg6IG51bWJlcik6IElSZXNvbHZhYmxlIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCB0b2tlbkluZGV4ID0gZXh0cmFjdFRva2VuRG91YmxlKHgpO1xuICAgIGlmICh0b2tlbkluZGV4ID09PSB1bmRlZmluZWQpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfVxuICAgIGNvbnN0IHQgPSB0aGlzLm51bWJlclRva2VuTWFwLmdldCh0b2tlbkluZGV4KTtcbiAgICBpZiAodCA9PT0gdW5kZWZpbmVkKSB7IHRocm93IG5ldyBFcnJvcignRW5jb2RlZCByZXByZXNlbnRhdGlvbiBvZiB1bmtub3duIG51bWJlciBUb2tlbiBmb3VuZCcpOyB9XG4gICAgcmV0dXJuIHQ7XG4gIH1cblxuICAvKipcbiAgICogRmluZCBhIFRva2VuIGJ5IGtleS5cbiAgICpcbiAgICogVGhpcyBleGNsdWRlcyB0aGUgdG9rZW4gbWFya2Vycy5cbiAgICovXG4gIHB1YmxpYyBsb29rdXBUb2tlbihrZXk6IHN0cmluZyk6IElSZXNvbHZhYmxlIHtcbiAgICBjb25zdCB0b2tlbiA9IHRoaXMuc3RyaW5nVG9rZW5NYXAuZ2V0KGtleSk7XG4gICAgaWYgKCF0b2tlbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnJlY29nbml6ZWQgdG9rZW4ga2V5OiAke2tleX1gKTtcbiAgICB9XG4gICAgcmV0dXJuIHRva2VuO1xuICB9XG5cbiAgcHJpdmF0ZSByZWdpc3RlclN0cmluZ0tleSh0b2tlbjogSVJlc29sdmFibGUsIGRpc3BsYXlIaW50Pzogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBjb3VudGVyID0gdGhpcy50b2tlbkNvdW50ZXIrKztcbiAgICBjb25zdCByZXByZXNlbnRhdGlvbiA9IChkaXNwbGF5SGludCB8fCBgVE9LRU5gKS5yZXBsYWNlKG5ldyBSZWdFeHAoYFteJHtWQUxJRF9LRVlfQ0hBUlN9XWAsICdnJyksICcuJyk7XG4gICAgY29uc3Qga2V5ID0gYCR7cmVwcmVzZW50YXRpb259LiR7Y291bnRlcn1gO1xuICAgIHRoaXMuc3RyaW5nVG9rZW5NYXAuc2V0KGtleSwgdG9rZW4pO1xuICAgIHJldHVybiBrZXk7XG4gIH1cblxuICBwcml2YXRlIHJlZ2lzdGVyTnVtYmVyS2V5KHRva2VuOiBJUmVzb2x2YWJsZSk6IG51bWJlciB7XG4gICAgY29uc3QgY291bnRlciA9IHRoaXMudG9rZW5Db3VudGVyKys7XG4gICAgdGhpcy5udW1iZXJUb2tlbk1hcC5zZXQoY291bnRlciwgdG9rZW4pO1xuICAgIHJldHVybiBjcmVhdGVUb2tlbkRvdWJsZShjb3VudGVyKTtcbiAgfVxufVxuXG4vKipcbiAqIEdldCBhIGNhY2hlZCB2YWx1ZSBmb3IgYW4gb2JqZWN0LCBzdG9yaW5nIGl0IG9uIHRoZSBvYmplY3QgaW4gYSBzeW1ib2xcbiAqL1xuZnVuY3Rpb24gY2FjaGVkVmFsdWU8QSBleHRlbmRzIG9iamVjdCwgQj4oeDogQSwgc3ltOiBzeW1ib2wsIHByb2Q6ICgpID0+IEIpIHtcbiAgbGV0IGNhY2hlZCA9ICh4IGFzIGFueSlbc3ltIGFzIGFueV07XG4gIGlmIChjYWNoZWQgPT09IHVuZGVmaW5lZCkge1xuICAgIGNhY2hlZCA9IHByb2QoKTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoeCwgc3ltLCB7IHZhbHVlOiBjYWNoZWQgfSk7XG4gIH1cbiAgcmV0dXJuIGNhY2hlZDtcbn1cbiJdfQ==