UNPKG

@glimmer/runtime

Version:

Minimal runtime needed to render Glimmer templates

486 lines (402 loc) 42.4 kB
import { DEBUG } from '@glimmer/env'; import { createDebugAliasRef, UNDEFINED_REFERENCE, valueForRef } from '@glimmer/reference'; import { dict, emptyArray, EMPTY_STRING_ARRAY } from '@glimmer/util'; import { CONSTANT_TAG } from '@glimmer/validator'; import { $sp } from '@glimmer/vm'; import { REGISTERS } from '../symbols'; /* The calling convention is: * 0-N block arguments at the bottom * 0-N positional arguments next (left-to-right) * 0-N named arguments next */ export class VMArgumentsImpl { constructor() { this.stack = null; this.positional = new PositionalArgumentsImpl(); this.named = new NamedArgumentsImpl(); this.blocks = new BlockArgumentsImpl(); } empty(stack) { let base = stack[REGISTERS][$sp] + 1; this.named.empty(stack, base); this.positional.empty(stack, base); this.blocks.empty(stack, base); return this; } setup(stack, names, blockNames, positionalCount, atNames) { this.stack = stack; /* | ... | blocks | positional | named | | ... | b0 b1 | p0 p1 p2 p3 | n0 n1 | index | ... | 4/5/6 7/8/9 | 10 11 12 13 | 14 15 | ^ ^ ^ ^ bbase pbase nbase sp */ let named = this.named; let namedCount = names.length; let namedBase = stack[REGISTERS][$sp] - namedCount + 1; named.setup(stack, namedBase, namedCount, names, atNames); let positional = this.positional; let positionalBase = namedBase - positionalCount; positional.setup(stack, positionalBase, positionalCount); let blocks = this.blocks; let blocksCount = blockNames.length; let blocksBase = positionalBase - blocksCount * 3; blocks.setup(stack, blocksBase, blocksCount, blockNames); } get base() { return this.blocks.base; } get length() { return this.positional.length + this.named.length + this.blocks.length * 3; } at(pos) { return this.positional.at(pos); } realloc(offset) { let { stack } = this; if (offset > 0 && stack !== null) { let { positional, named } = this; let newBase = positional.base + offset; let length = positional.length + named.length; for (let i = length - 1; i >= 0; i--) { stack.copy(i + positional.base, i + newBase); } positional.base += offset; named.base += offset; stack[REGISTERS][$sp] += offset; } } capture() { let positional = this.positional.length === 0 ? EMPTY_POSITIONAL : this.positional.capture(); let named = this.named.length === 0 ? EMPTY_NAMED : this.named.capture(); return { named, positional }; } clear() { let { stack, length } = this; if (length > 0 && stack !== null) stack.pop(length); } } const EMPTY_REFERENCES = emptyArray(); export class PositionalArgumentsImpl { constructor() { this.base = 0; this.length = 0; this.stack = null; this._references = null; } empty(stack, base) { this.stack = stack; this.base = base; this.length = 0; this._references = EMPTY_REFERENCES; } setup(stack, base, length) { this.stack = stack; this.base = base; this.length = length; if (length === 0) { this._references = EMPTY_REFERENCES; } else { this._references = null; } } at(position) { let { base, length, stack } = this; if (position < 0 || position >= length) { return UNDEFINED_REFERENCE; } return stack.get(position, base); } capture() { return this.references; } prepend(other) { let additions = other.length; if (additions > 0) { let { base, length, stack } = this; this.base = base = base - additions; this.length = length + additions; for (let i = 0; i < additions; i++) { stack.set(other[i], i, base); } this._references = null; } } get references() { let references = this._references; if (!references) { let { stack, base, length } = this; references = this._references = stack.slice(base, base + length); } return references; } } export class NamedArgumentsImpl { constructor() { this.base = 0; this.length = 0; this._references = null; this._names = EMPTY_STRING_ARRAY; this._atNames = EMPTY_STRING_ARRAY; } empty(stack, base) { this.stack = stack; this.base = base; this.length = 0; this._references = EMPTY_REFERENCES; this._names = EMPTY_STRING_ARRAY; this._atNames = EMPTY_STRING_ARRAY; } setup(stack, base, length, names, atNames) { this.stack = stack; this.base = base; this.length = length; if (length === 0) { this._references = EMPTY_REFERENCES; this._names = EMPTY_STRING_ARRAY; this._atNames = EMPTY_STRING_ARRAY; } else { this._references = null; if (atNames) { this._names = null; this._atNames = names; } else { this._names = names; this._atNames = null; } } } get names() { let names = this._names; if (!names) { names = this._names = this._atNames.map(this.toSyntheticName); } return names; } get atNames() { let atNames = this._atNames; if (!atNames) { atNames = this._atNames = this._names.map(this.toAtName); } return atNames; } has(name) { return this.names.indexOf(name) !== -1; } get(name, atNames = false) { let { base, stack } = this; let names = atNames ? this.atNames : this.names; let idx = names.indexOf(name); if (idx === -1) { return UNDEFINED_REFERENCE; } let ref = stack.get(idx, base); if (DEBUG) { return createDebugAliasRef(atNames ? name : `@${name}`, ref); } else { return ref; } } capture() { let { names, references } = this; let map = dict(); for (let i = 0; i < names.length; i++) { let name = names[i]; if (DEBUG) { map[name] = createDebugAliasRef(`@${name}`, references[i]); } else { map[name] = references[i]; } } return map; } merge(other) { let keys = Object.keys(other); if (keys.length > 0) { let { names, length, stack } = this; let newNames = names.slice(); for (let i = 0; i < keys.length; i++) { let name = keys[i]; let idx = newNames.indexOf(name); if (idx === -1) { length = newNames.push(name); stack.push(other[name]); } } this.length = length; this._references = null; this._names = newNames; this._atNames = null; } } get references() { let references = this._references; if (!references) { let { base, length, stack } = this; references = this._references = stack.slice(base, base + length); } return references; } toSyntheticName(name) { return name.slice(1); } toAtName(name) { return `@${name}`; } } function toSymbolName(name) { return `&${name}`; } const EMPTY_BLOCK_VALUES = emptyArray(); export class BlockArgumentsImpl { constructor() { this.internalValues = null; this._symbolNames = null; this.internalTag = null; this.names = EMPTY_STRING_ARRAY; this.length = 0; this.base = 0; } empty(stack, base) { this.stack = stack; this.names = EMPTY_STRING_ARRAY; this.base = base; this.length = 0; this._symbolNames = null; this.internalTag = CONSTANT_TAG; this.internalValues = EMPTY_BLOCK_VALUES; } setup(stack, base, length, names) { this.stack = stack; this.names = names; this.base = base; this.length = length; this._symbolNames = null; if (length === 0) { this.internalTag = CONSTANT_TAG; this.internalValues = EMPTY_BLOCK_VALUES; } else { this.internalTag = null; this.internalValues = null; } } get values() { let values = this.internalValues; if (!values) { let { base, length, stack } = this; values = this.internalValues = stack.slice(base, base + length * 3); } return values; } has(name) { return this.names.indexOf(name) !== -1; } get(name) { let idx = this.names.indexOf(name); if (idx === -1) { return null; } let { base, stack } = this; let table = stack.get(idx * 3, base); let scope = stack.get(idx * 3 + 1, base); let handle = stack.get(idx * 3 + 2, base); return handle === null ? null : [handle, scope, table]; } capture() { return new CapturedBlockArgumentsImpl(this.names, this.values); } get symbolNames() { let symbolNames = this._symbolNames; if (symbolNames === null) { symbolNames = this._symbolNames = this.names.map(toSymbolName); } return symbolNames; } } class CapturedBlockArgumentsImpl { constructor(names, values) { this.names = names; this.values = values; this.length = names.length; } has(name) { return this.names.indexOf(name) !== -1; } get(name) { let idx = this.names.indexOf(name); if (idx === -1) return null; return [this.values[idx * 3 + 2], this.values[idx * 3 + 1], this.values[idx * 3]]; } } export function createCapturedArgs(named, positional) { return { named, positional }; } export function reifyNamed(named) { let reified = dict(); for (let key in named) { reified[key] = valueForRef(named[key]); } return reified; } export function reifyPositional(positional) { return positional.map(valueForRef); } export function reifyArgs(args) { return { named: reifyNamed(args.named), positional: reifyPositional(args.positional) }; } export const EMPTY_NAMED = Object.freeze(Object.create(null)); export const EMPTY_POSITIONAL = EMPTY_REFERENCES; export const EMPTY_ARGS = createCapturedArgs(EMPTY_NAMED, EMPTY_POSITIONAL); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL3J1bnRpbWUvbGliL3ZtL2FyZ3VtZW50cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxTQUFTLEtBQVQsUUFBc0IsY0FBdEI7QUFrQkEsU0FDRSxtQkFERixFQUdFLG1CQUhGLEVBSUUsV0FKRixRQUtPLG9CQUxQO0FBTUEsU0FBUyxJQUFULEVBQWUsVUFBZixFQUEyQixrQkFBM0IsUUFBcUQsZUFBckQ7QUFDQSxTQUFTLFlBQVQsUUFBa0Msb0JBQWxDO0FBQ0EsU0FBUyxHQUFULFFBQW9CLGFBQXBCO0FBRUEsU0FBUyxTQUFULFFBQTBCLFlBQTFCO0FBR0E7Ozs7Ozs7O0FBUUEsT0FBTSxNQUFPLGVBQVAsQ0FBc0I7QUFBNUIsRUFBQSxXQUFBLEdBQUE7QUFDVSxTQUFBLEtBQUEsR0FBaUMsSUFBakM7QUFDRCxTQUFBLFVBQUEsR0FBYSxJQUFJLHVCQUFKLEVBQWI7QUFDQSxTQUFBLEtBQUEsR0FBUSxJQUFJLGtCQUFKLEVBQVI7QUFDQSxTQUFBLE1BQUEsR0FBUyxJQUFJLGtCQUFKLEVBQVQ7QUF1RlI7O0FBckZDLEVBQUEsS0FBSyxDQUFDLEtBQUQsRUFBdUI7QUFDMUIsUUFBSSxJQUFJLEdBQUcsS0FBSyxDQUFDLFNBQUQsQ0FBTCxDQUFpQixHQUFqQixJQUF3QixDQUFuQztBQUVBLFNBQUssS0FBTCxDQUFXLEtBQVgsQ0FBaUIsS0FBakIsRUFBd0IsSUFBeEI7QUFDQSxTQUFLLFVBQUwsQ0FBZ0IsS0FBaEIsQ0FBc0IsS0FBdEIsRUFBNkIsSUFBN0I7QUFDQSxTQUFLLE1BQUwsQ0FBWSxLQUFaLENBQWtCLEtBQWxCLEVBQXlCLElBQXpCO0FBRUEsV0FBTyxJQUFQO0FBQ0Q7O0FBRUQsRUFBQSxLQUFLLENBQ0gsS0FERyxFQUVILEtBRkcsRUFHSCxVQUhHLEVBSUgsZUFKRyxFQUtILE9BTEcsRUFLYTtBQUVoQixTQUFLLEtBQUwsR0FBYSxLQUFiO0FBRUE7Ozs7Ozs7O0FBUUEs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LFVBQVUsRUFBRSxlQUFlLENBQUMsSUFBSSxDQUFDLFVBQU47QUFGdEIsR0FBUDtBQUlEO0FBRUQsT0FBTyxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsTUFBUCxDQUFjLE1BQU0sQ0FBQyxNQUFQLENBQWMsSUFBZCxDQUFkLENBQXBCO0FBQ1AsT0FBTyxNQUFNLGdCQUFnQixHQUFHLGdCQUF6QjtBQUNQLE9BQU8sTUFBTSxVQUFVLEdBQUcsa0JBQWtCLENBQUMsV0FBRCxFQUFjLGdCQUFkLENBQXJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY2hlY2ssIENoZWNrQmxvY2tTeW1ib2xUYWJsZSwgQ2hlY2tIYW5kbGUsIENoZWNrT3B0aW9uLCBDaGVja09yIH0gZnJvbSAnQGdsaW1tZXIvZGVidWcnO1xuaW1wb3J0IHsgREVCVUcgfSBmcm9tICdAZ2xpbW1lci9lbnYnO1xuaW1wb3J0IHtcbiAgQmxvY2tBcmd1bWVudHMsXG4gIEJsb2NrU3ltYm9sVGFibGUsXG4gIEJsb2NrVmFsdWUsXG4gIENhcHR1cmVkQXJndW1lbnRzLFxuICBDYXB0dXJlZEJsb2NrQXJndW1lbnRzLFxuICBDYXB0dXJlZE5hbWVkQXJndW1lbnRzLFxuICBDYXB0dXJlZFBvc2l0aW9uYWxBcmd1bWVudHMsXG4gIENvbXBpbGFibGVCbG9jayxcbiAgRGljdCxcbiAgTmFtZWRBcmd1bWVudHMsXG4gIE9wdGlvbixcbiAgUG9zaXRpb25hbEFyZ3VtZW50cyxcbiAgU2NvcGUsXG4gIFNjb3BlQmxvY2ssXG4gIFZNQXJndW1lbnRzLFxufSBmcm9tICdAZ2xpbW1lci9pbnRlcmZhY2VzJztcbmltcG9ydCB7XG4gIGNyZWF0ZURlYnVnQWxpYXNSZWYsXG4gIFJlZmVyZW5jZSxcbiAgVU5ERUZJTkVEX1JFRkVSRU5DRSxcbiAgdmFsdWVGb3JSZWYsXG59IGZyb20gJ0BnbGltbWVyL3JlZmVyZW5jZSc7XG5pbXBvcnQgeyBkaWN0LCBlbXB0eUFycmF5LCBFTVBUWV9TVFJJTkdfQVJSQVkgfSBmcm9tICdAZ2xpbW1lci91dGlsJztcbmltcG9ydCB7IENPTlNUQU5UX1RBRywgVGFnIH0gZnJvbSAnQGdsaW1tZXIvdmFsaWRhdG9yJztcbmltcG9ydCB7ICRzcCB9IGZyb20gJ0BnbGltbWVyL3ZtJztcbmltcG9ydCB7IENoZWNrQ29tcGlsYWJsZUJsb2NrLCBDaGVja1JlZmVyZW5jZSwgQ2hlY2tTY29wZSB9IGZyb20gJy4uL2NvbXBpbGVkL29wY29kZXMvLWRlYnVnLXN0cmlwJztcbmltcG9ydCB7IFJFR0lTVEVSUyB9IGZyb20gJy4uL3N5bWJvbHMnO1xuaW1wb3J0IHsgRXZhbHVhdGlvblN0YWNrIH0gZnJvbSAnLi9zdGFjayc7XG5cbi8qXG4gIFRoZSBjYWxsaW5nIGNvbnZlbnRpb24gaXM6XG5cbiAgKiAwLU4gYmxvY2sgYXJndW1lbnRzIGF0IHRoZSBib3R0b21cbiAgKiAwLU4gcG9zaXRpb25hbCBhcmd1bWVudHMgbmV4dCAobGVmdC10by1yaWdodClcbiAgKiAwLU4gbmFtZWQgYXJndW1lbnRzIG5leHRcbiovXG5cbmV4cG9ydCBjbGFzcyBWTUFyZ3VtZW50c0ltcGwgaW1wbGVtZW50cyBWTUFyZ3VtZW50cyB7XG4gIHByaXZhdGUgc3RhY2s6IE9wdGlvbjxFdmFsdWF0aW9uU3RhY2s+ID0gbnVsbDtcbiAgcHVibGljIHBvc2l0aW9uYWwgPSBuZXcgUG9zaXRpb25hbEFyZ3VtZW50c0ltcGwoKTtcbiAgcHVibGljIG5hbWVkID0gbmV3IE5hbWVkQXJndW1lbnRzSW1wbCgpO1xuICBwdWJsaWMgYmxvY2tzID0gbmV3IEJsb2NrQXJndW1lbnRzSW1wbCgpO1xuXG4gIGVtcHR5KHN0YWNrOiBFdmFsdWF0aW9uU3RhY2spOiB0aGlzIHtcbiAgICBsZXQgYmFzZSA9IHN0YWNrW1JFR0lTVEVSU11bJHNwXSArIDE7XG5cbiAgICB0aGlzLm5hbWVkLmVtcHR5KHN0YWNrLCBiYXNlKTtcbiAgICB0aGlzLnBvc2l0aW9uYWwuZW1wdHkoc3RhY2ssIGJhc2UpO1xuICAgIHRoaXMuYmxvY2tzLmVtcHR5KHN0YWNrLCBiYXNlKTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc2V0dXAoXG4gICAgc3RhY2s6IEV2YWx1YXRpb25TdGFjayxcbiAgICBuYW1lczogcmVhZG9ubHkgc3RyaW5nW10sXG4gICAgYmxvY2tOYW1lczogcmVhZG9ubHkgc3RyaW5nW10sXG4gICAgcG9zaXRpb25hbENvdW50OiBudW1iZXIsXG4gICAgYXROYW1lczogYm9vbGVhblxuICApIHtcbiAgICB0aGlzLnN0YWNrID0gc3RhY2s7XG5cbiAgICAvKlxuICAgICAgICAgICB8IC4uLiB8IGJsb2NrcyAgICAgIHwgcG9zaXRpb25hbCAgfCBuYW1lZCB8XG4gICAgICAgICAgIHwgLi4uIHwgYjAgICAgYjEgICAgfCBwMCBwMSBwMiBwMyB8IG4wIG4xIHxcbiAgICAgaW5kZXggfCAuLi4gfCA0LzUvNiA3LzgvOSB8IDEwIDExIDEyIDEzIHwgMTQgMTUgfFxuICAgICAgICAgICAgICAgICAgIF4gICAgICAgICAgICAgXiAgICAgICAgICAgICBeICBeXG4gICAgICAgICAgICAgICAgIGJiYXNlICAgICAgICAgcGJhc2UgICAgICAgbmJhc2UgIHNwXG4gICAgKi9cblxuICAgIGxldCBuYW1lZCA9IHRoaXMubmFtZWQ7XG4gICAgbGV0IG5hbWVkQ291bnQgPSBuYW1lcy5sZW5ndGg7XG4gICAgbGV0IG5hbWVkQmFzZSA9IHN0YWNrW1JFR0lTVEVSU11bJHNwXSAtIG5hbWVkQ291bnQgKyAxO1xuXG4gICAgbmFtZWQuc2V0dXAoc3RhY2ssIG5hbWVkQmFzZSwgbmFtZWRDb3VudCwgbmFtZXMsIGF0TmFtZXMpO1xuXG4gICAgbGV0IHBvc2l0aW9uYWwgPSB0aGlzLnBvc2l0aW9uYWw7XG4gICAgbGV0IHBvc2l0aW9uYWxCYXNlID0gbmFtZWRCYXNlIC0gcG9zaXRpb25hbENvdW50O1xuXG4gICAgcG9zaXRpb25hbC5zZXR1cChzdGFjaywgcG9zaXRpb25hbEJhc2UsIHBvc2l0aW9uYWxDb3VudCk7XG5cbiAgICBsZXQgYmxvY2tzID0gdGhpcy5ibG9ja3M7XG4gICAgbGV0IGJsb2Nrc0NvdW50ID0gYmxvY2tOYW1lcy5sZW5ndGg7XG4gICAgbGV0IGJsb2Nrc0Jhc2UgPSBwb3NpdGlvbmFsQmFzZSAtIGJsb2Nrc0NvdW50ICogMztcblxuICAgIGJsb2Nrcy5zZXR1cChzdGFjaywgYmxvY2tzQmFzZSwgYmxvY2tzQ291bnQsIGJsb2NrTmFtZXMpO1xuICB9XG5cbiAgZ2V0IGJhc2UoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5ibG9ja3MuYmFzZTtcbiAgfVxuXG4gIGdldCBsZW5ndGgoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5wb3NpdGlvbmFsLmxlbmd0aCArIHRoaXMubmFtZWQubGVuZ3RoICsgdGhpcy5ibG9ja3MubGVuZ3RoICogMztcbiAgfVxuXG4gIGF0KHBvczogbnVtYmVyKTogUmVmZXJlbmNlIHtcbiAgICByZXR1cm4gdGhpcy5wb3NpdGlvbmFsLmF0KHBvcyk7XG4gIH1cblxuICByZWFsbG9jKG9mZnNldDogbnVtYmVyKSB7XG4gICAgbGV0IHsgc3RhY2sgfSA9IHRoaXM7XG4gICAgaWYgKG9mZnNldCA+IDAgJiYgc3RhY2sgIT09IG51bGwpIHtcbiAgICAgIGxldCB7IHBvc2l0aW9uYWwsIG5hbWVkIH0gPSB0aGlzO1xuICAgICAgbGV0IG5ld0Jhc2UgPSBwb3NpdGlvbmFsLmJhc2UgKyBvZmZzZXQ7XG4gICAgICBsZXQgbGVuZ3RoID0gcG9zaXRpb25hbC5sZW5ndGggKyBuYW1lZC5sZW5ndGg7XG5cbiAgICAgIGZvciAobGV0IGkgPSBsZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBzdGFjay5jb3B5KGkgKyBwb3NpdGlvbmFsLmJhc2UsIGkgKyBuZXdCYXNlKTtcbiAgICAgIH1cblxuICAgICAgcG9zaXRpb25hbC5iYXNlICs9IG9mZnNldDtcbiAgICAgIG5hbWVkLmJhc2UgKz0gb2Zmc2V0O1xuICAgICAgc3RhY2tbUkVHSVNURVJTXVskc3BdICs9IG9mZnNldDtcbiAgICB9XG4gIH1cblxuICBjYXB0dXJlKCk6IENhcHR1cmVkQXJndW1lbnRzIHtcbiAgICBsZXQgcG9zaXRpb25hbCA9IHRoaXMucG9zaXRpb25hbC5sZW5ndGggPT09IDAgPyBFTVBUWV9QT1NJVElPTkFMIDogdGhpcy5wb3NpdGlvbmFsLmNhcHR1cmUoKTtcbiAgICBsZXQgbmFtZWQgPSB0aGlzLm5hbWVkLmxlbmd0aCA9PT0gMCA/IEVNUFRZX05BTUVEIDogdGhpcy5uYW1lZC5jYXB0dXJlKCk7XG5cbiAgICByZXR1cm4geyBuYW1lZCwgcG9zaXRpb25hbCB9IGFzIENhcHR1cmVkQXJndW1lbnRzO1xuICB9XG5cbiAgY2xlYXIoKTogdm9pZCB7XG4gICAgbGV0IHsgc3RhY2ssIGxlbmd0aCB9ID0gdGhpcztcbiAgICBpZiAobGVuZ3RoID4gMCAmJiBzdGFjayAhPT0gbnVsbCkgc3RhY2sucG9wKGxlbmd0aCk7XG4gIH1cbn1cblxuY29uc3QgRU1QVFlfUkVGRVJFTkNFUyA9IGVtcHR5QXJyYXk8UmVmZXJlbmNlPigpO1xuXG5leHBvcnQgY2xhc3MgUG9zaXRpb25hbEFyZ3VtZW50c0ltcGwgaW1wbGVtZW50cyBQb3NpdGlvbmFsQXJndW1lbnRzIHtcbiAgcHVibGljIGJhc2UgPSAwO1xuICBwdWJsaWMgbGVuZ3RoID0gMDtcblxuICBwcml2YXRlIHN0YWNrOiBFdmFsdWF0aW9uU3RhY2sgPSBudWxsIGFzIGFueTtcblxuICBwcml2YXRlIF9yZWZlcmVuY2VzOiBPcHRpb248cmVhZG9ubHkgUmVmZXJlbmNlW10+ID0gbnVsbDtcblxuICBlbXB0eShzdGFjazogRXZhbHVhdGlvblN0YWNrLCBiYXNlOiBudW1iZXIpIHtcbiAgICB0aGlzLnN0YWNrID0gc3RhY2s7XG4gICAgdGhpcy5iYXNlID0gYmFzZTtcbiAgICB0aGlzLmxlbmd0aCA9IDA7XG5cbiAgICB0aGlzLl9yZWZlcmVuY2VzID0gRU1QVFlfUkVGRVJFTkNFUztcbiAgfVxuXG4gIHNldHVwKHN0YWNrOiBFdmFsdWF0aW9uU3RhY2ssIGJhc2U6IG51bWJlciwgbGVuZ3RoOiBudW1iZXIpIHtcbiAgICB0aGlzLnN0YWNrID0gc3RhY2s7XG4gICAgdGhpcy5iYXNlID0gYmFzZTtcbiAgICB0aGlzLmxlbmd0aCA9IGxlbmd0aDtcblxuICAgIGlmIChsZW5ndGggPT09IDApIHtcbiAgICAgIHRoaXMuX3JlZmVyZW5jZXMgPSBFTVBUWV9SRUZFUkVOQ0VTO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9yZWZlcmVuY2VzID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBhdChwb3NpdGlvbjogbnVtYmVyKTogUmVmZXJlbmNlIHtcbiAgICBsZXQgeyBiYXNlLCBsZW5ndGgsIHN0YWNrIH0gPSB0aGlzO1xuXG4gICAgaWYgKHBvc2l0aW9uIDwgMCB8fCBwb3NpdGlvbiA+PSBsZW5ndGgpIHtcbiAgICAgIHJldHVybiBVTkRFRklORURfUkVGRVJFTkNFO1xuICAgIH1cblxuICAgIHJldHVybiBjaGVjayhzdGFjay5nZXQocG9zaXRpb24sIGJhc2UpLCBDaGVja1JlZmVyZW5jZSk7XG4gIH1cblxuICBjYXB0dXJlKCk6IENhcHR1cmVkUG9zaXRpb25hbEFyZ3VtZW50cyB7XG4gICAgcmV0dXJuIHRoaXMucmVmZXJlbmNlcyBhcyBDYXB0dXJlZFBvc2l0aW9uYWxBcmd1bWVudHM7XG4gIH1cblxuICBwcmVwZW5kKG90aGVyOiBSZWZlcmVuY2VbXSkge1xuICAgIGxldCBhZGRpdGlvbnMgPSBvdGhlci5sZW5ndGg7XG5cbiAgICBpZiAoYWRkaXRpb25zID4gMCkge1xuICAgICAgbGV0IHsgYmFzZSwgbGVuZ3RoLCBzdGFjayB9ID0gdGhpcztcblxuICAgICAgdGhpcy5iYXNlID0gYmFzZSA9IGJhc2UgLSBhZGRpdGlvbnM7XG4gICAgICB0aGlzLmxlbmd0aCA9IGxlbmd0aCArIGFkZGl0aW9ucztcblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhZGRpdGlvbnM7IGkrKykge1xuICAgICAgICBzdGFjay5zZXQob3RoZXJbaV0sIGksIGJhc2UpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9yZWZlcmVuY2VzID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldCByZWZlcmVuY2VzKCk6IHJlYWRvbmx5IFJlZmVyZW5jZVtdIHtcbiAgICBsZXQgcmVmZXJlbmNlcyA9IHRoaXMuX3JlZmVyZW5jZXM7XG5cbiAgICBpZiAoIXJlZmVyZW5jZXMpIHtcbiAgICAgIGxldCB7IHN0YWNrLCBiYXNlLCBsZW5ndGggfSA9IHRoaXM7XG4gICAgICByZWZlcmVuY2VzID0gdGhpcy5fcmVmZXJlbmNlcyA9IHN0YWNrLnNsaWNlPFJlZmVyZW5jZT4oYmFzZSwgYmFzZSArIGxlbmd0aCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlZmVyZW5jZXM7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIE5hbWVkQXJndW1lbnRzSW1wbCBpbXBsZW1lbnRzIE5hbWVkQXJndW1lbnRzIHtcbiAgcHVibGljIGJhc2UgPSAwO1xuICBwdWJsaWMgbGVuZ3RoID0gMDtcblxuICBwcml2YXRlIHN0YWNrITogRXZhbHVhdGlvblN0YWNrO1xuXG4gIHByaXZhdGUgX3JlZmVyZW5jZXM6IE9wdGlvbjxyZWFkb25seSBSZWZlcmVuY2VbXT4gPSBudWxsO1xuXG4gIHByaXZhdGUgX25hbWVzOiBPcHRpb248cmVhZG9ubHkgc3RyaW5nW10+ID0gRU1QVFlfU1RSSU5HX0FSUkFZO1xuICBwcml2YXRlIF9hdE5hbWVzOiBPcHRpb248cmVhZG9ubHkgc3RyaW5nW10+ID0gRU1QVFlfU1RSSU5HX0FSUkFZO1xuXG4gIGVtcHR5KHN0YWNrOiBFdmFsdWF0aW9uU3RhY2ssIGJhc2U6IG51bWJlcikge1xuICAgIHRoaXMuc3RhY2sgPSBzdGFjaztcbiAgICB0aGlzLmJhc2UgPSBiYXNlO1xuICAgIHRoaXMubGVuZ3RoID0gMDtcblxuICAgIHRoaXMuX3JlZmVyZW5jZXMgPSBFTVBUWV9SRUZFUkVOQ0VTO1xuICAgIHRoaXMuX25hbWVzID0gRU1QVFlfU1RSSU5HX0FSUkFZO1xuICAgIHRoaXMuX2F0TmFtZXMgPSBFTVBUWV9TVFJJTkdfQVJSQVk7XG4gIH1cblxuICBzZXR1cChcbiAgICBzdGFjazogRXZhbHVhdGlvblN0YWNrLFxuICAgIGJhc2U6IG51bWJlcixcbiAgICBsZW5ndGg6IG51bWJlcixcbiAgICBuYW1lczogcmVhZG9ubHkgc3RyaW5nW10sXG4gICAgYXROYW1lczogYm9vbGVhblxuICApIHtcbiAgICB0aGlzLnN0YWNrID0gc3RhY2s7XG4gICAgdGhpcy5iYXNlID0gYmFzZTtcbiAgICB0aGlzLmxlbmd0aCA9IGxlbmd0aDtcblxuICAgIGlmIChsZW5ndGggPT09IDApIHtcbiAgICAgIHRoaXMuX3JlZmVyZW5jZXMgPSBFTVBUWV9SRUZFUkVOQ0VTO1xuICAgICAgdGhpcy5fbmFtZXMgPSBFTVBUWV9TVFJJTkdfQVJSQVk7XG4gICAgICB0aGlzLl9hdE5hbWVzID0gRU1QVFlfU1RSSU5HX0FSUkFZO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9yZWZlcmVuY2VzID0gbnVsbDtcblxuICAgICAgaWYgKGF0TmFtZXMpIHtcbiAgICAgICAgdGhpcy5fbmFtZXMgPSBudWxsO1xuICAgICAgICB0aGlzLl9hdE5hbWVzID0gbmFtZXM7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9uYW1lcyA9IG5hbWVzO1xuICAgICAgICB0aGlzLl9hdE5hbWVzID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBnZXQgbmFtZXMoKTogcmVhZG9ubHkgc3RyaW5nW10ge1xuICAgIGxldCBuYW1lcyA9IHRoaXMuX25hbWVzO1xuXG4gICAgaWYgKCFuYW1lcykge1xuICAgICAgbmFtZXMgPSB0aGlzLl9uYW1lcyA9IHRoaXMuX2F0TmFtZXMhLm1hcCh0aGlzLnRvU3ludGhldGljTmFtZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5hbWVzITtcbiAgfVxuXG4gIGdldCBhdE5hbWVzKCk6IHJlYWRvbmx5IHN0cmluZ1tdIHtcbiAgICBsZXQgYXROYW1lcyA9IHRoaXMuX2F0TmFtZXM7XG5cbiAgICBpZiAoIWF0TmFtZXMpIHtcbiAgICAgIGF0TmFtZXMgPSB0aGlzLl9hdE5hbWVzID0gdGhpcy5fbmFtZXMhLm1hcCh0aGlzLnRvQXROYW1lKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXROYW1lcyE7XG4gIH1cblxuICBoYXMobmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMubmFtZXMuaW5kZXhPZihuYW1lKSAhPT0gLTE7XG4gIH1cblxuICBnZXQobmFtZTogc3RyaW5nLCBhdE5hbWVzID0gZmFsc2UpOiBSZWZlcmVuY2Uge1xuICAgIGxldCB7IGJhc2UsIHN0YWNrIH0gPSB0aGlzO1xuXG4gICAgbGV0IG5hbWVzID0gYXROYW1lcyA/IHRoaXMuYXROYW1lcyA6IHRoaXMubmFtZXM7XG5cbiAgICBsZXQgaWR4ID0gbmFtZXMuaW5kZXhPZihuYW1lKTtcblxuICAgIGlmIChpZHggPT09IC0xKSB7XG4gICAgICByZXR1cm4gVU5ERUZJTkVEX1JFRkVSRU5DRTtcbiAgICB9XG5cbiAgICBsZXQgcmVmID0gc3RhY2suZ2V0PFJlZmVyZW5jZT4oaWR4LCBiYXNlKTtcblxuICAgIGlmIChERUJVRykge1xuICAgICAgcmV0dXJuIGNyZWF0ZURlYnVnQWxpYXNSZWYhKGF0TmFtZXMgPyBuYW1lIDogYEAke25hbWV9YCwgcmVmKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHJlZjtcbiAgICB9XG4gIH1cblxuICBjYXB0dXJlKCk6IENhcHR1cmVkTmFtZWRBcmd1bWVudHMge1xuICAgIGxldCB7IG5hbWVzLCByZWZlcmVuY2VzIH0gPSB0aGlzO1xuICAgIGxldCBtYXAgPSBkaWN0PFJlZmVyZW5jZT4oKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbmFtZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGxldCBuYW1lID0gbmFtZXNbaV07XG5cbiAgICAgIGlmIChERUJVRykge1xuICAgICAgICBtYXBbbmFtZV0gPSBjcmVhdGVEZWJ1Z0FsaWFzUmVmIShgQCR7bmFtZX1gLCByZWZlcmVuY2VzW2ldKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG1hcFtuYW1lXSA9IHJlZmVyZW5jZXNbaV07XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG1hcCBhcyBDYXB0dXJlZE5hbWVkQXJndW1lbnRzO1xuICB9XG5cbiAgbWVyZ2Uob3RoZXI6IFJlY29yZDxzdHJpbmcsIFJlZmVyZW5jZT4pIHtcbiAgICBsZXQga2V5cyA9IE9iamVjdC5rZXlzKG90aGVyKTtcblxuICAgIGlmIChrZXlzLmxlbmd0aCA+IDApIHtcbiAgICAgIGxldCB7IG5hbWVzLCBsZW5ndGgsIHN0YWNrIH0gPSB0aGlzO1xuICAgICAgbGV0IG5ld05hbWVzID0gbmFtZXMuc2xpY2UoKTtcblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxldCBuYW1lID0ga2V5c1tpXTtcbiAgICAgICAgbGV0IGlkeCA9IG5ld05hbWVzLmluZGV4T2YobmFtZSk7XG5cbiAgICAgICAgaWYgKGlkeCA9PT0gLTEpIHtcbiAgICAgICAgICBsZW5ndGggPSBuZXdOYW1lcy5wdXNoKG5hbWUpO1xuICAgICAgICAgIHN0YWNrLnB1c2gob3RoZXJbbmFtZV0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHRoaXMubGVuZ3RoID0gbGVuZ3RoO1xuICAgICAgdGhpcy5fcmVmZXJlbmNlcyA9IG51bGw7XG4gICAgICB0aGlzLl9uYW1lcyA9IG5ld05hbWVzO1xuICAgICAgdGhpcy5fYXROYW1lcyA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXQgcmVmZXJlbmNlcygpOiByZWFkb25seSBSZWZlcmVuY2VbXSB7XG4gICAgbGV0IHJlZmVyZW5jZXMgPSB0aGlzLl9yZWZlcmVuY2VzO1xuXG4gICAgaWYgKCFyZWZlcmVuY2VzKSB7XG4gICAgICBsZXQgeyBiYXNlLCBsZW5ndGgsIHN0YWNrIH0gPSB0aGlzO1xuICAgICAgcmVmZXJlbmNlcyA9IHRoaXMuX3JlZmVyZW5jZXMgPSBzdGFjay5zbGljZTxSZWZlcmVuY2U+KGJhc2UsIGJhc2UgKyBsZW5ndGgpO1xuICAgIH1cblxuICAgIHJldHVybiByZWZlcmVuY2VzO1xuICB9XG5cbiAgcHJpdmF0ZSB0b1N5bnRoZXRpY05hbWUodGhpczogdm9pZCwgbmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gbmFtZS5zbGljZSgxKTtcbiAgfVxuXG4gIHByaXZhdGUgdG9BdE5hbWUodGhpczogdm9pZCwgbmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYEAke25hbWV9YDtcbiAgfVxufVxuXG5mdW5jdGlvbiB0b1N5bWJvbE5hbWUobmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGAmJHtuYW1lfWA7XG59XG5cbmNvbnN0IEVNUFRZX0JMT0NLX1ZBTFVFUyA9IGVtcHR5QXJyYXk8QmxvY2tWYWx1ZT4oKTtcblxuZXhwb3J0IGNsYXNzIEJsb2NrQXJndW1lbnRzSW1wbCBpbXBsZW1lbnRzIEJsb2NrQXJndW1lbnRzIHtcbiAgcHJpdmF0ZSBzdGFjayE6IEV2YWx1YXRpb25TdGFjaztcbiAgcHJpdmF0ZSBpbnRlcm5hbFZhbHVlczogT3B0aW9uPHJlYWRvbmx5IEJsb2NrVmFsdWVbXT4gPSBudWxsO1xuICBwcml2YXRlIF9zeW1ib2xOYW1lczogT3B0aW9uPHJlYWRvbmx5IHN0cmluZ1tdPiA9IG51bGw7XG5cbiAgcHVibGljIGludGVybmFsVGFnOiBPcHRpb248VGFnPiA9IG51bGw7XG4gIHB1YmxpYyBuYW1lczogcmVhZG9ubHkgc3RyaW5nW10gPSBFTVBUWV9TVFJJTkdfQVJSQVk7XG5cbiAgcHVibGljIGxlbmd0aCA9IDA7XG4gIHB1YmxpYyBiYXNlID0gMDtcblxuICBlbXB0eShzdGFjazogRXZhbHVhdGlvblN0YWNrLCBiYXNlOiBudW1iZXIpIHtcbiAgICB0aGlzLnN0YWNrID0gc3RhY2s7XG4gICAgdGhpcy5uYW1lcyA9IEVNUFRZX1NUUklOR19BUlJBWTtcbiAgICB0aGlzLmJhc2UgPSBiYXNlO1xuICAgIHRoaXMubGVuZ3RoID0gMDtcbiAgICB0aGlzLl9zeW1ib2xOYW1lcyA9IG51bGw7XG5cbiAgICB0aGlzLmludGVybmFsVGFnID0gQ09OU1RBTlRfVEFHO1xuICAgIHRoaXMuaW50ZXJuYWxWYWx1ZXMgPSBFTVBUWV9CTE9DS19WQUxVRVM7XG4gIH1cblxuICBzZXR1cChzdGFjazogRXZhbHVhdGlvblN0YWNrLCBiYXNlOiBudW1iZXIsIGxlbmd0aDogbnVtYmVyLCBuYW1lczogcmVhZG9ubHkgc3RyaW5nW10pIHtcbiAgICB0aGlzLnN0YWNrID0gc3RhY2s7XG4gICAgdGhpcy5uYW1lcyA9IG5hbWVzO1xuICAgIHRoaXMuYmFzZSA9IGJhc2U7XG4gICAgdGhpcy5sZW5ndGggPSBsZW5ndGg7XG4gICAgdGhpcy5fc3ltYm9sTmFtZXMgPSBudWxsO1xuXG4gICAgaWYgKGxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5pbnRlcm5hbFRhZyA9IENPTlNUQU5UX1RBRztcbiAgICAgIHRoaXMuaW50ZXJuYWxWYWx1ZXMgPSBFTVBUWV9CTE9DS19WQUxVRVM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaW50ZXJuYWxUYWcgPSBudWxsO1xuICAgICAgdGhpcy5pbnRlcm5hbFZhbHVlcyA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgZ2V0IHZhbHVlcygpOiByZWFkb25seSBCbG9ja1ZhbHVlW10ge1xuICAgIGxldCB2YWx1ZXMgPSB0aGlzLmludGVybmFsVmFsdWVzO1xuXG4gICAgaWYgKCF2YWx1ZXMpIHtcbiAgICAgIGxldCB7IGJhc2UsIGxlbmd0aCwgc3RhY2sgfSA9IHRoaXM7XG4gICAgICB2YWx1ZXMgPSB0aGlzLmludGVybmFsVmFsdWVzID0gc3RhY2suc2xpY2U8QmxvY2tWYWx1ZT4oYmFzZSwgYmFzZSArIGxlbmd0aCAqIDMpO1xuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZXM7XG4gIH1cblxuICBoYXMobmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMubmFtZXMhLmluZGV4T2YobmFtZSkgIT09IC0xO1xuICB9XG5cbiAgZ2V0KG5hbWU6IHN0cmluZyk6IE9wdGlvbjxTY29wZUJsb2NrPiB7XG4gICAgbGV0IGlkeCA9IHRoaXMubmFtZXMhLmluZGV4T2YobmFtZSk7XG5cbiAgICBpZiAoaWR4ID09PSAtMSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgbGV0IHsgYmFzZSwgc3RhY2sgfSA9IHRoaXM7XG5cbiAgICBsZXQgdGFibGUgPSBjaGVjayhzdGFjay5nZXQoaWR4ICogMywgYmFzZSksIENoZWNrT3B0aW9uKENoZWNrQmxvY2tTeW1ib2xUYWJsZSkpO1xuICAgIGxldCBzY29wZSA9IGNoZWNrKHN0YWNrLmdldChpZHggKiAzICsgMSwgYmFzZSksIENoZWNrT3B0aW9uKENoZWNrU2NvcGUpKTtcbiAgICBsZXQgaGFuZGxlID0gY2hlY2soXG4gICAgICBzdGFjay5nZXQoaWR4ICogMyArIDIsIGJhc2UpLFxuICAgICAgQ2hlY2tPcHRpb24oQ2hlY2tPcihDaGVja0hhbmRsZSwgQ2hlY2tDb21waWxhYmxlQmxvY2spKVxuICAgICk7XG5cbiAgICByZXR1cm4gaGFuZGxlID09PSBudWxsID8gbnVsbCA6IChbaGFuZGxlLCBzY29wZSEsIHRhYmxlIV0gYXMgU2NvcGVCbG9jayk7XG4gIH1cblxuICBjYXB0dXJlKCk6IENhcHR1cmVkQmxvY2tBcmd1bWVudHMge1xuICAgIHJldHVybiBuZXcgQ2FwdHVyZWRCbG9ja0FyZ3VtZW50c0ltcGwodGhpcy5uYW1lcywgdGhpcy52YWx1ZXMpO1xuICB9XG5cbiAgZ2V0IHN5bWJvbE5hbWVzKCk6IHJlYWRvbmx5IHN0cmluZ1tdIHtcbiAgICBsZXQgc3ltYm9sTmFtZXMgPSB0aGlzLl9zeW1ib2xOYW1lcztcblxuICAgIGlmIChzeW1ib2xOYW1lcyA9PT0gbnVsbCkge1xuICAgICAgc3ltYm9sTmFtZXMgPSB0aGlzLl9zeW1ib2xOYW1lcyA9IHRoaXMubmFtZXMubWFwKHRvU3ltYm9sTmFtZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN5bWJvbE5hbWVzO1xuICB9XG59XG5cbmNsYXNzIENhcHR1cmVkQmxvY2tBcmd1bWVudHNJbXBsIGltcGxlbWVudHMgQ2FwdHVyZWRCbG9ja0FyZ3VtZW50cyB7XG4gIHB1YmxpYyBsZW5ndGg6IG51bWJlcjtcblxuICBjb25zdHJ1Y3RvcihwdWJsaWMgbmFtZXM6IHJlYWRvbmx5IHN0cmluZ1tdLCBwdWJsaWMgdmFsdWVzOiByZWFkb25seSBPcHRpb248QmxvY2tWYWx1ZT5bXSkge1xuICAgIHRoaXMubGVuZ3RoID0gbmFtZXMubGVuZ3RoO1xuICB9XG5cbiAgaGFzKG5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLm5hbWVzLmluZGV4T2YobmFtZSkgIT09IC0xO1xuICB9XG5cbiAgZ2V0KG5hbWU6IHN0cmluZyk6IE9wdGlvbjxTY29wZUJsb2NrPiB7XG4gICAgbGV0IGlkeCA9IHRoaXMubmFtZXMuaW5kZXhPZihuYW1lKTtcblxuICAgIGlmIChpZHggPT09IC0xKSByZXR1cm4gbnVsbDtcblxuICAgIHJldHVybiBbXG4gICAgICB0aGlzLnZhbHVlc1tpZHggKiAzICsgMl0gYXMgQ29tcGlsYWJsZUJsb2NrLFxuICAgICAgdGhpcy52YWx1ZXNbaWR4ICogMyArIDFdIGFzIFNjb3BlLFxuICAgICAgdGhpcy52YWx1ZXNbaWR4ICogM10gYXMgQmxvY2tTeW1ib2xUYWJsZSxcbiAgICBdO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVDYXB0dXJlZEFyZ3MobmFtZWQ6IERpY3Q8UmVmZXJlbmNlPiwgcG9zaXRpb25hbDogUmVmZXJlbmNlW10pIHtcbiAgcmV0dXJuIHtcbiAgICBuYW1lZCxcbiAgICBwb3NpdGlvbmFsLFxuICB9IGFzIENhcHR1cmVkQXJndW1lbnRzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVpZnlOYW1lZChuYW1lZDogQ2FwdHVyZWROYW1lZEFyZ3VtZW50cykge1xuICBsZXQgcmVpZmllZCA9IGRpY3QoKTtcblxuICBmb3IgKGxldCBrZXkgaW4gbmFtZWQpIHtcbiAgICByZWlmaWVkW2tleV0gPSB2YWx1ZUZvclJlZihuYW1lZFtrZXldKTtcbiAgfVxuXG4gIHJldHVybiByZWlmaWVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVpZnlQb3NpdGlvbmFsKHBvc2l0aW9uYWw6IENhcHR1cmVkUG9zaXRpb25hbEFyZ3VtZW50cykge1xuICByZXR1cm4gcG9zaXRpb25hbC5tYXAodmFsdWVGb3JSZWYpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVpZnlBcmdzKGFyZ3M6IENhcHR1cmVkQXJndW1lbnRzKSB7XG4gIHJldHVybiB7XG4gICAgbmFtZWQ6IHJlaWZ5TmFtZWQoYXJncy5uYW1lZCksXG4gICAgcG9zaXRpb25hbDogcmVpZnlQb3NpdGlvbmFsKGFyZ3MucG9zaXRpb25hbCksXG4gIH07XG59XG5cbmV4cG9ydCBjb25zdCBFTVBUWV9OQU1FRCA9IE9iamVjdC5mcmVlemUoT2JqZWN0LmNyZWF0ZShudWxsKSkgYXMgQ2FwdHVyZWROYW1lZEFyZ3VtZW50cztcbmV4cG9ydCBjb25zdCBFTVBUWV9QT1NJVElPTkFMID0gRU1QVFlfUkVGRVJFTkNFUyBhcyBDYXB0dXJlZFBvc2l0aW9uYWxBcmd1bWVudHM7XG5leHBvcnQgY29uc3QgRU1QVFlfQVJHUyA9IGNyZWF0ZUNhcHR1cmVkQXJncyhFTVBUWV9OQU1FRCwgRU1QVFlfUE9TSVRJT05BTCk7XG4iXSwic291cmNlUm9vdCI6IiJ9