UNPKG

@angular/core

Version:

Angular - the core framework

136 lines 14.6 kB
/** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ import { APP_ID, PLATFORM_ID } from './application/application_tokens'; import { inject } from './di/injector_compatibility'; import { ɵɵdefineInjectable } from './di/interface/defs'; import { getDocument } from './render3/interfaces/document'; /** * Create a `StateKey<T>` that can be used to store value of type T with `TransferState`. * * Example: * * ``` * const COUNTER_KEY = makeStateKey<number>('counter'); * let value = 10; * * transferState.set(COUNTER_KEY, value); * ``` * * @publicApi */ export function makeStateKey(key) { return key; } function initTransferState() { const transferState = new TransferState(); if (inject(PLATFORM_ID) === 'browser') { transferState.store = retrieveTransferredState(getDocument(), inject(APP_ID)); } return transferState; } /** * A key value store that is transferred from the application on the server side to the application * on the client side. * * The `TransferState` is available as an injectable token. * On the client, just inject this token using DI and use it, it will be lazily initialized. * On the server it's already included if `renderApplication` function is used. Otherwise, import * the `ServerTransferStateModule` module to make the `TransferState` available. * * The values in the store are serialized/deserialized using JSON.stringify/JSON.parse. So only * boolean, number, string, null and non-class objects will be serialized and deserialized in a * non-lossy manner. * * @publicApi */ export class TransferState { constructor() { /** @internal */ this.store = {}; this.onSerializeCallbacks = {}; } /** @nocollapse */ static { this.ɵprov = ɵɵdefineInjectable({ token: TransferState, providedIn: 'root', factory: initTransferState, }); } /** * Get the value corresponding to a key. Return `defaultValue` if key is not found. */ get(key, defaultValue) { return this.store[key] !== undefined ? this.store[key] : defaultValue; } /** * Set the value corresponding to a key. */ set(key, value) { this.store[key] = value; } /** * Remove a key from the store. */ remove(key) { delete this.store[key]; } /** * Test whether a key exists in the store. */ hasKey(key) { return this.store.hasOwnProperty(key); } /** * Indicates whether the state is empty. */ get isEmpty() { return Object.keys(this.store).length === 0; } /** * Register a callback to provide the value for a key when `toJson` is called. */ onSerialize(key, callback) { this.onSerializeCallbacks[key] = callback; } /** * Serialize the current state of the store to JSON. */ toJson() { // Call the onSerialize callbacks and put those values into the store. for (const key in this.onSerializeCallbacks) { if (this.onSerializeCallbacks.hasOwnProperty(key)) { try { this.store[key] = this.onSerializeCallbacks[key](); } catch (e) { console.warn('Exception in onSerialize callback: ', e); } } } // Escape script tag to avoid break out of <script> tag in serialized output. // Encoding of `<` is the same behaviour as G3 script_builders. return JSON.stringify(this.store).replace(/</g, '\\u003C'); } } function retrieveTransferredState(doc, appId) { // Locate the script tag with the JSON data transferred from the server. // The id of the script tag is set to the Angular appId + 'state'. const script = doc.getElementById(appId + '-state'); if (script?.textContent) { try { // Avoid using any here as it triggers lint errors in google3 (any is not allowed). // Decoding of `<` is done of the box by browsers and node.js, same behaviour as G3 // script_builders. return JSON.parse(script.textContent); } catch (e) { console.warn('Exception while restoring TransferState for app ' + appId, e); } } return {}; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNmZXJfc3RhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy90cmFuc2Zlcl9zdGF0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFFSCxPQUFPLEVBQUMsTUFBTSxFQUFFLFdBQVcsRUFBQyxNQUFNLGtDQUFrQyxDQUFDO0FBQ3JFLE9BQU8sRUFBQyxNQUFNLEVBQUMsTUFBTSw2QkFBNkIsQ0FBQztBQUNuRCxPQUFPLEVBQUMsa0JBQWtCLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQztBQUN2RCxPQUFPLEVBQUMsV0FBVyxFQUFDLE1BQU0sK0JBQStCLENBQUM7QUFxQjFEOzs7Ozs7Ozs7Ozs7O0dBYUc7QUFDSCxNQUFNLFVBQVUsWUFBWSxDQUFXLEdBQVc7SUFDaEQsT0FBTyxHQUFrQixDQUFDO0FBQzVCLENBQUM7QUFFRCxTQUFTLGlCQUFpQjtJQUN4QixNQUFNLGFBQWEsR0FBRyxJQUFJLGFBQWEsRUFBRSxDQUFDO0lBQzFDLElBQUksTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQ3RDLGFBQWEsQ0FBQyxLQUFLLEdBQUcsd0JBQXdCLENBQUMsV0FBVyxFQUFFLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFDaEYsQ0FBQztJQUVELE9BQU8sYUFBYSxDQUFDO0FBQ3ZCLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILE1BQU0sT0FBTyxhQUFhO0lBQTFCO1FBUUUsZ0JBQWdCO1FBQ2hCLFVBQUssR0FBd0MsRUFBRSxDQUFDO1FBRXhDLHlCQUFvQixHQUE2QyxFQUFFLENBQUM7SUErRDlFLENBQUM7SUF6RUMsa0JBQWtCO2FBQ1gsVUFBSyxHQUE2QixrQkFBa0IsQ0FBQztRQUMxRCxLQUFLLEVBQUUsYUFBYTtRQUNwQixVQUFVLEVBQUUsTUFBTTtRQUNsQixPQUFPLEVBQUUsaUJBQWlCO0tBQzNCLENBQUMsQUFKVSxDQUlUO0lBT0g7O09BRUc7SUFDSCxHQUFHLENBQUksR0FBZ0IsRUFBRSxZQUFlO1FBQ3RDLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFPLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQztJQUMvRSxDQUFDO0lBRUQ7O09BRUc7SUFDSCxHQUFHLENBQUksR0FBZ0IsRUFBRSxLQUFRO1FBQy9CLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsS0FBSyxDQUFDO0lBQzFCLENBQUM7SUFFRDs7T0FFRztJQUNILE1BQU0sQ0FBSSxHQUFnQjtRQUN4QixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDekIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsTUFBTSxDQUFJLEdBQWdCO1FBQ3hCLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDeEMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsSUFBSSxPQUFPO1FBQ1QsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxDQUFDO0lBQzlDLENBQUM7SUFFRDs7T0FFRztJQUNILFdBQVcsQ0FBSSxHQUFnQixFQUFFLFFBQWlCO1FBQ2hELElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsR0FBRyxRQUFRLENBQUM7SUFDNUMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsTUFBTTtRQUNKLHNFQUFzRTtRQUN0RSxLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1lBQzVDLElBQUksSUFBSSxDQUFDLG9CQUFvQixDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUNsRCxJQUFJLENBQUM7b0JBQ0gsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDckQsQ0FBQztnQkFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO29CQUNYLE9BQU8sQ0FBQyxJQUFJLENBQUMscUNBQXFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQ3pELENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztRQUVELDZFQUE2RTtRQUM3RSwrREFBK0Q7UUFDL0QsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQzdELENBQUM7O0FBR0gsU0FBUyx3QkFBd0IsQ0FDL0IsR0FBYSxFQUNiLEtBQWE7SUFFYix3RUFBd0U7SUFDeEUsa0VBQWtFO0lBQ2xFLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxjQUFjLENBQUMsS0FBSyxHQUFHLFFBQVEsQ0FBQyxDQUFDO0lBQ3BELElBQUksTUFBTSxFQUFFLFdBQVcsRUFBRSxDQUFDO1FBQ3hCLElBQUksQ0FBQztZQUNILG1GQUFtRjtZQUNuRixtRkFBbUY7WUFDbkYsbUJBQW1CO1lBQ25CLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFPLENBQUM7UUFDOUMsQ0FBQztRQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDWCxPQUFPLENBQUMsSUFBSSxDQUFDLGtEQUFrRCxHQUFHLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM5RSxDQUFDO0lBQ0gsQ0FBQztJQUVELE9BQU8sRUFBRSxDQUFDO0FBQ1osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQge0FQUF9JRCwgUExBVEZPUk1fSUR9IGZyb20gJy4vYXBwbGljYXRpb24vYXBwbGljYXRpb25fdG9rZW5zJztcbmltcG9ydCB7aW5qZWN0fSBmcm9tICcuL2RpL2luamVjdG9yX2NvbXBhdGliaWxpdHknO1xuaW1wb3J0IHvJtcm1ZGVmaW5lSW5qZWN0YWJsZX0gZnJvbSAnLi9kaS9pbnRlcmZhY2UvZGVmcyc7XG5pbXBvcnQge2dldERvY3VtZW50fSBmcm9tICcuL3JlbmRlcjMvaW50ZXJmYWNlcy9kb2N1bWVudCc7XG5cbi8qKlxuICogQSB0eXBlLXNhZmUga2V5IHRvIHVzZSB3aXRoIGBUcmFuc2ZlclN0YXRlYC5cbiAqXG4gKiBFeGFtcGxlOlxuICpcbiAqIGBgYFxuICogY29uc3QgQ09VTlRFUl9LRVkgPSBtYWtlU3RhdGVLZXk8bnVtYmVyPignY291bnRlcicpO1xuICogbGV0IHZhbHVlID0gMTA7XG4gKlxuICogdHJhbnNmZXJTdGF0ZS5zZXQoQ09VTlRFUl9LRVksIHZhbHVlKTtcbiAqIGBgYFxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuZXhwb3J0IHR5cGUgU3RhdGVLZXk8VD4gPSBzdHJpbmcgJiB7XG4gIF9fbm90X2Ffc3RyaW5nOiBuZXZlcjtcbiAgX192YWx1ZV90eXBlPzogVDtcbn07XG5cbi8qKlxuICogQ3JlYXRlIGEgYFN0YXRlS2V5PFQ+YCB0aGF0IGNhbiBiZSB1c2VkIHRvIHN0b3JlIHZhbHVlIG9mIHR5cGUgVCB3aXRoIGBUcmFuc2ZlclN0YXRlYC5cbiAqXG4gKiBFeGFtcGxlOlxuICpcbiAqIGBgYFxuICogY29uc3QgQ09VTlRFUl9LRVkgPSBtYWtlU3RhdGVLZXk8bnVtYmVyPignY291bnRlcicpO1xuICogbGV0IHZhbHVlID0gMTA7XG4gKlxuICogdHJhbnNmZXJTdGF0ZS5zZXQoQ09VTlRFUl9LRVksIHZhbHVlKTtcbiAqIGBgYFxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1ha2VTdGF0ZUtleTxUID0gdm9pZD4oa2V5OiBzdHJpbmcpOiBTdGF0ZUtleTxUPiB7XG4gIHJldHVybiBrZXkgYXMgU3RhdGVLZXk8VD47XG59XG5cbmZ1bmN0aW9uIGluaXRUcmFuc2ZlclN0YXRlKCk6IFRyYW5zZmVyU3RhdGUge1xuICBjb25zdCB0cmFuc2ZlclN0YXRlID0gbmV3IFRyYW5zZmVyU3RhdGUoKTtcbiAgaWYgKGluamVjdChQTEFURk9STV9JRCkgPT09ICdicm93c2VyJykge1xuICAgIHRyYW5zZmVyU3RhdGUuc3RvcmUgPSByZXRyaWV2ZVRyYW5zZmVycmVkU3RhdGUoZ2V0RG9jdW1lbnQoKSwgaW5qZWN0KEFQUF9JRCkpO1xuICB9XG5cbiAgcmV0dXJuIHRyYW5zZmVyU3RhdGU7XG59XG5cbi8qKlxuICogQSBrZXkgdmFsdWUgc3RvcmUgdGhhdCBpcyB0cmFuc2ZlcnJlZCBmcm9tIHRoZSBhcHBsaWNhdGlvbiBvbiB0aGUgc2VydmVyIHNpZGUgdG8gdGhlIGFwcGxpY2F0aW9uXG4gKiBvbiB0aGUgY2xpZW50IHNpZGUuXG4gKlxuICogVGhlIGBUcmFuc2ZlclN0YXRlYCBpcyBhdmFpbGFibGUgYXMgYW4gaW5qZWN0YWJsZSB0b2tlbi5cbiAqIE9uIHRoZSBjbGllbnQsIGp1c3QgaW5qZWN0IHRoaXMgdG9rZW4gdXNpbmcgREkgYW5kIHVzZSBpdCwgaXQgd2lsbCBiZSBsYXppbHkgaW5pdGlhbGl6ZWQuXG4gKiBPbiB0aGUgc2VydmVyIGl0J3MgYWxyZWFkeSBpbmNsdWRlZCBpZiBgcmVuZGVyQXBwbGljYXRpb25gIGZ1bmN0aW9uIGlzIHVzZWQuIE90aGVyd2lzZSwgaW1wb3J0XG4gKiB0aGUgYFNlcnZlclRyYW5zZmVyU3RhdGVNb2R1bGVgIG1vZHVsZSB0byBtYWtlIHRoZSBgVHJhbnNmZXJTdGF0ZWAgYXZhaWxhYmxlLlxuICpcbiAqIFRoZSB2YWx1ZXMgaW4gdGhlIHN0b3JlIGFyZSBzZXJpYWxpemVkL2Rlc2VyaWFsaXplZCB1c2luZyBKU09OLnN0cmluZ2lmeS9KU09OLnBhcnNlLiBTbyBvbmx5XG4gKiBib29sZWFuLCBudW1iZXIsIHN0cmluZywgbnVsbCBhbmQgbm9uLWNsYXNzIG9iamVjdHMgd2lsbCBiZSBzZXJpYWxpemVkIGFuZCBkZXNlcmlhbGl6ZWQgaW4gYVxuICogbm9uLWxvc3N5IG1hbm5lci5cbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmV4cG9ydCBjbGFzcyBUcmFuc2ZlclN0YXRlIHtcbiAgLyoqIEBub2NvbGxhcHNlICovXG4gIHN0YXRpYyDJtXByb3YgPSAvKiogQHB1cmVPckJyZWFrTXlDb2RlICovIMm1ybVkZWZpbmVJbmplY3RhYmxlKHtcbiAgICB0b2tlbjogVHJhbnNmZXJTdGF0ZSxcbiAgICBwcm92aWRlZEluOiAncm9vdCcsXG4gICAgZmFjdG9yeTogaW5pdFRyYW5zZmVyU3RhdGUsXG4gIH0pO1xuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgc3RvcmU6IFJlY29yZDxzdHJpbmcsIHVua25vd24gfCB1bmRlZmluZWQ+ID0ge307XG5cbiAgcHJpdmF0ZSBvblNlcmlhbGl6ZUNhbGxiYWNrczoge1trOiBzdHJpbmddOiAoKSA9PiB1bmtub3duIHwgdW5kZWZpbmVkfSA9IHt9O1xuXG4gIC8qKlxuICAgKiBHZXQgdGhlIHZhbHVlIGNvcnJlc3BvbmRpbmcgdG8gYSBrZXkuIFJldHVybiBgZGVmYXVsdFZhbHVlYCBpZiBrZXkgaXMgbm90IGZvdW5kLlxuICAgKi9cbiAgZ2V0PFQ+KGtleTogU3RhdGVLZXk8VD4sIGRlZmF1bHRWYWx1ZTogVCk6IFQge1xuICAgIHJldHVybiB0aGlzLnN0b3JlW2tleV0gIT09IHVuZGVmaW5lZCA/ICh0aGlzLnN0b3JlW2tleV0gYXMgVCkgOiBkZWZhdWx0VmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogU2V0IHRoZSB2YWx1ZSBjb3JyZXNwb25kaW5nIHRvIGEga2V5LlxuICAgKi9cbiAgc2V0PFQ+KGtleTogU3RhdGVLZXk8VD4sIHZhbHVlOiBUKTogdm9pZCB7XG4gICAgdGhpcy5zdG9yZVtrZXldID0gdmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlIGEga2V5IGZyb20gdGhlIHN0b3JlLlxuICAgKi9cbiAgcmVtb3ZlPFQ+KGtleTogU3RhdGVLZXk8VD4pOiB2b2lkIHtcbiAgICBkZWxldGUgdGhpcy5zdG9yZVtrZXldO1xuICB9XG5cbiAgLyoqXG4gICAqIFRlc3Qgd2hldGhlciBhIGtleSBleGlzdHMgaW4gdGhlIHN0b3JlLlxuICAgKi9cbiAgaGFzS2V5PFQ+KGtleTogU3RhdGVLZXk8VD4pOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zdG9yZS5oYXNPd25Qcm9wZXJ0eShrZXkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBzdGF0ZSBpcyBlbXB0eS5cbiAgICovXG4gIGdldCBpc0VtcHR5KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLnN0b3JlKS5sZW5ndGggPT09IDA7XG4gIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXIgYSBjYWxsYmFjayB0byBwcm92aWRlIHRoZSB2YWx1ZSBmb3IgYSBrZXkgd2hlbiBgdG9Kc29uYCBpcyBjYWxsZWQuXG4gICAqL1xuICBvblNlcmlhbGl6ZTxUPihrZXk6IFN0YXRlS2V5PFQ+LCBjYWxsYmFjazogKCkgPT4gVCk6IHZvaWQge1xuICAgIHRoaXMub25TZXJpYWxpemVDYWxsYmFja3Nba2V5XSA9IGNhbGxiYWNrO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlcmlhbGl6ZSB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgc3RvcmUgdG8gSlNPTi5cbiAgICovXG4gIHRvSnNvbigpOiBzdHJpbmcge1xuICAgIC8vIENhbGwgdGhlIG9uU2VyaWFsaXplIGNhbGxiYWNrcyBhbmQgcHV0IHRob3NlIHZhbHVlcyBpbnRvIHRoZSBzdG9yZS5cbiAgICBmb3IgKGNvbnN0IGtleSBpbiB0aGlzLm9uU2VyaWFsaXplQ2FsbGJhY2tzKSB7XG4gICAgICBpZiAodGhpcy5vblNlcmlhbGl6ZUNhbGxiYWNrcy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdGhpcy5zdG9yZVtrZXldID0gdGhpcy5vblNlcmlhbGl6ZUNhbGxiYWNrc1trZXldKCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oJ0V4Y2VwdGlvbiBpbiBvblNlcmlhbGl6ZSBjYWxsYmFjazogJywgZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBFc2NhcGUgc2NyaXB0IHRhZyB0byBhdm9pZCBicmVhayBvdXQgb2YgPHNjcmlwdD4gdGFnIGluIHNlcmlhbGl6ZWQgb3V0cHV0LlxuICAgIC8vIEVuY29kaW5nIG9mIGA8YCBpcyB0aGUgc2FtZSBiZWhhdmlvdXIgYXMgRzMgc2NyaXB0X2J1aWxkZXJzLlxuICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh0aGlzLnN0b3JlKS5yZXBsYWNlKC88L2csICdcXFxcdTAwM0MnKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZXRyaWV2ZVRyYW5zZmVycmVkU3RhdGUoXG4gIGRvYzogRG9jdW1lbnQsXG4gIGFwcElkOiBzdHJpbmcsXG4pOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duIHwgdW5kZWZpbmVkPiB7XG4gIC8vIExvY2F0ZSB0aGUgc2NyaXB0IHRhZyB3aXRoIHRoZSBKU09OIGRhdGEgdHJhbnNmZXJyZWQgZnJvbSB0aGUgc2VydmVyLlxuICAvLyBUaGUgaWQgb2YgdGhlIHNjcmlwdCB0YWcgaXMgc2V0IHRvIHRoZSBBbmd1bGFyIGFwcElkICsgJ3N0YXRlJy5cbiAgY29uc3Qgc2NyaXB0ID0gZG9jLmdldEVsZW1lbnRCeUlkKGFwcElkICsgJy1zdGF0ZScpO1xuICBpZiAoc2NyaXB0Py50ZXh0Q29udGVudCkge1xuICAgIHRyeSB7XG4gICAgICAvLyBBdm9pZCB1c2luZyBhbnkgaGVyZSBhcyBpdCB0cmlnZ2VycyBsaW50IGVycm9ycyBpbiBnb29nbGUzIChhbnkgaXMgbm90IGFsbG93ZWQpLlxuICAgICAgLy8gRGVjb2Rpbmcgb2YgYDxgIGlzIGRvbmUgb2YgdGhlIGJveCBieSBicm93c2VycyBhbmQgbm9kZS5qcywgc2FtZSBiZWhhdmlvdXIgYXMgRzNcbiAgICAgIC8vIHNjcmlwdF9idWlsZGVycy5cbiAgICAgIHJldHVybiBKU09OLnBhcnNlKHNjcmlwdC50ZXh0Q29udGVudCkgYXMge307XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29uc29sZS53YXJuKCdFeGNlcHRpb24gd2hpbGUgcmVzdG9yaW5nIFRyYW5zZmVyU3RhdGUgZm9yIGFwcCAnICsgYXBwSWQsIGUpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7fTtcbn1cbiJdfQ==