UNPKG

@glimmer/runtime

Version:

Minimal runtime needed to render Glimmer templates

497 lines (403 loc) 49.9 kB
var _a, _b; import { DEBUG } from '@glimmer/env'; import { assertGlobalContextWasSet } from '@glimmer/global-context'; import { createIteratorItemRef, UNDEFINED_REFERENCE } from '@glimmer/reference'; import { assert, LOCAL_LOGGER, Stack, unwrapHandle } from '@glimmer/util'; import { beginTrackFrame, endTrackFrame, resetTracking } from '@glimmer/validator'; import { $fp, $pc, $s0, $s1, $sp, $t0, $t1, $v0, isLowLevelRegister } from '@glimmer/vm'; import { associateDestroyableChild } from '@glimmer/destroyable'; import { BeginTrackFrameOpcode, EndTrackFrameOpcode, JumpIfNotModifiedOpcode } from '../compiled/opcodes/vm'; import { APPEND_OPCODES } from '../opcodes'; import { PartialScopeImpl } from '../scope'; import { ARGS, CONSTANTS, DESTROYABLE_STACK, HEAP, INNER_VM, REGISTERS, STACKS } from '../symbols'; import { VMArgumentsImpl } from './arguments'; import LowLevelVM from './low-level'; import RenderResultImpl from './render-result'; import EvaluationStackImpl from './stack'; import { ListBlockOpcode, ListItemOpcode, ResumableVMStateImpl, TryOpcode } from './update'; class Stacks { constructor() { this.scope = new Stack(); this.dynamicScope = new Stack(); this.updating = new Stack(); this.cache = new Stack(); this.list = new Stack(); } } export default class VM { /** * End of migrated. */ constructor(runtime, { pc, scope, dynamicScope, stack }, elementStack, context) { this.runtime = runtime; this.elementStack = elementStack; this.context = context; this[_a] = new Stacks(); this[_b] = new Stack(); this.s0 = null; this.s1 = null; this.t0 = null; this.t1 = null; this.v0 = null; this.resume = initVM(this.context); if (DEBUG) { assertGlobalContextWasSet(); } let evalStack = EvaluationStackImpl.restore(stack); (false && assert(typeof pc === 'number', 'pc is a number')); evalStack[REGISTERS][$pc] = pc; evalStack[REGISTERS][$sp] = stack.length - 1; evalStack[REGISTERS][$fp] = -1; this[HEAP] = this.program.heap; this[CONSTANTS] = this.program.constants; this.elementStack = elementStack; this[STACKS].scope.push(scope); this[STACKS].dynamicScope.push(dynamicScope); this[ARGS] = new VMArgumentsImpl(); this[INNER_VM] = new LowLevelVM(evalStack, this[HEAP], runtime.program, { debugBefore: opcode => { return APPEND_OPCODES.debugBefore(this, opcode); }, debugAfter: state => { APPEND_OPCODES.debugAfter(this, state); } }, evalStack[REGISTERS]); this.destructor = {}; this[DESTROYABLE_STACK].push(this.destructor); } get stack() { return this[INNER_VM].stack; } /* Registers */ get pc() { return this[INNER_VM].fetchRegister($pc); } // Fetch a value from a register onto the stack fetch(register) { let value = this.fetchValue(register); this.stack.push(value); } // Load a value from the stack into a register load(register) { let value = this.stack.pop(); this.loadValue(register, value); } fetchValue(register) { if (isLowLevelRegister(register)) { return this[INNER_VM].fetchRegister(register); } switch (register) { case $s0: return this.s0; case $s1: return this.s1; case $t0: return this.t0; case $t1: return this.t1; case $v0: return this.v0; } } // Load a value into a register loadValue(register, value) { if (isLowLevelRegister(register)) { this[INNER_VM].loadRegister(register, value); } switch (register) { case $s0: this.s0 = value; break; case $s1: this.s1 = value; break; case $t0: this.t0 = value; break; case $t1: this.t1 = value; break; case $v0: this.v0 = value; break; } } /** * Migrated to Inner */ // Start a new frame and save $ra and $fp on the stack pushFrame() { this[INNER_VM].pushFrame(); } // Restore $ra, $sp and $fp popFrame() { this[INNER_VM].popFrame(); } // Jump to an address in `program` goto(offset) { this[INNER_VM].goto(offset); } // Save $pc into $ra, then jump to a new address in `program` (jal in MIPS) call(handle) { this[INNER_VM].call(handle); } // Put a specific `program` address in $ra returnTo(offset) { this[INNER_VM].returnTo(offset); } // Return to the `program` address stored in $ra return() { this[INNER_VM].return(); } static initial(runtime, context, { handle, self, dynamicScope, treeBuilder, numSymbols, owner }) { let scope = PartialScopeImpl.root(self, numSymbols, owner); let state = vmState(runtime.program.heap.getaddr(handle), scope, dynamicScope); let vm = initVM(context)(runtime, state, treeBuilder); vm.pushUpdating(); return vm; } static empty(runtime, { handle, treeBuilder, dynamicScope, owner }, context) { let vm = initVM(context)(runtime, vmState(runtime.program.heap.getaddr(handle), PartialScopeImpl.root(UNDEFINED_REFERENCE, 0, owner), dynamicScope), treeBuilder); vm.pushUpdating(); return vm; } compile(block) { let handle = unwrapHandle(block.compile(this.context)); return handle; } get program() { return this.runtime.program; } get env() { return this.runtime.env; } captureState(args, pc = this[INNER_VM].fetchRegister($pc)) { return { pc, scope: this.scope(), dynamicScope: this.dynamicScope(), stack: this.stack.capture(args) }; } capture(args, pc = this[INNER_VM].fetchRegister($pc)) { return new ResumableVMStateImpl(this.captureState(args, pc), this.resume); } beginCacheGroup(name) { let opcodes = this.updating(); let guard = new JumpIfNotModifiedOpcode(); opcodes.push(guard); opcodes.push(new BeginTrackFrameOpcode(name)); this[STACKS].cache.push(guard); beginTrackFrame(name); } commitCacheGroup() { let opcodes = this.updating(); let guard = this[STACKS].cache.pop(); let tag = endTrackFrame(); opcodes.push(new EndTrackFrameOpcode(guard)); guard.finalize(tag, opcodes.length); } enter(args) { let updating = []; let state = this.capture(args); let block = this.elements().pushUpdatableBlock(); let tryOpcode = new TryOpcode(state, this.runtime, block, updating); this.didEnter(tryOpcode); } enterItem({ key, value, memo }) { let { stack } = this; let valueRef = createIteratorItemRef(value); let memoRef = createIteratorItemRef(memo); stack.push(valueRef); stack.push(memoRef); let state = this.capture(2); let block = this.elements().pushUpdatableBlock(); let opcode = new ListItemOpcode(state, this.runtime, block, key, memoRef, valueRef); this.didEnter(opcode); return opcode; } registerItem(opcode) { this.listBlock().initializeChild(opcode); } enterList(iterableRef, offset) { let updating = []; let addr = this[INNER_VM].target(offset); let state = this.capture(0, addr); let list = this.elements().pushBlockList(updating); let opcode = new ListBlockOpcode(state, this.runtime, list, updating, iterableRef); this[STACKS].list.push(opcode); this.didEnter(opcode); } didEnter(opcode) { this.associateDestroyable(opcode); this[DESTROYABLE_STACK].push(opcode); this.updateWith(opcode); this.pushUpdating(opcode.children); } exit() { this[DESTROYABLE_STACK].pop(); this.elements().popBlock(); this.popUpdating(); } exitList() { this.exit(); this[STACKS].list.pop(); } pushUpdating(list = []) { this[STACKS].updating.push(list); } popUpdating() { return this[STACKS].updating.pop(); } updateWith(opcode) { this.updating().push(opcode); } listBlock() { return this[STACKS].list.current; } associateDestroyable(child) { let parent = this[DESTROYABLE_STACK].current; associateDestroyableChild(parent, child); } tryUpdating() { return this[STACKS].updating.current; } updating() { return this[STACKS].updating.current; } elements() { return this.elementStack; } scope() { return this[STACKS].scope.current; } dynamicScope() { return this[STACKS].dynamicScope.current; } pushChildScope() { this[STACKS].scope.push(this.scope().child()); } pushDynamicScope() { let child = this.dynamicScope().child(); this[STACKS].dynamicScope.push(child); return child; } pushRootScope(size, owner) { let scope = PartialScopeImpl.sized(size, owner); this[STACKS].scope.push(scope); return scope; } pushScope(scope) { this[STACKS].scope.push(scope); } popScope() { this[STACKS].scope.pop(); } popDynamicScope() { this[STACKS].dynamicScope.pop(); } /// SCOPE HELPERS getOwner() { return this.scope().owner; } getSelf() { return this.scope().getSelf(); } referenceForSymbol(symbol) { return this.scope().getSymbol(symbol); } /// EXECUTION execute(initialize) { if (DEBUG) { let hasErrored = true; try { let value = this._execute(initialize); // using a boolean here to avoid breaking ergonomics of "pause on uncaught exceptions" // which would happen with a `catch` + `throw` hasErrored = false; return value; } finally { if (hasErrored) { // If any existing blocks are open, due to an error or something like // that, we need to close them all and clean things up properly. let elements = this.elements(); while (elements.hasBlocks) { elements.popBlock(); } // eslint-disable-next-line no-console console.error(`\n\nError occurred:\n\n${resetTracking()}\n\n`); } } } else { return this._execute(initialize); } } _execute(initialize) { if (false /* LOCAL_SHOULD_LOG */ ) { LOCAL_LOGGER.log(`EXECUTING FROM ${this[INNER_VM].fetchRegister($pc)}`); } if (initialize) initialize(this); let result; while (true) { result = this.next(); if (result.done) break; } return result.value; } next() { let { env, elementStack } = this; let opcode = this[INNER_VM].nextStatement(); let result; if (opcode !== null) { this[INNER_VM].evaluateOuter(opcode, this); result = { done: false, value: null }; } else { // Unload the stack this.stack.reset(); result = { done: true, value: new RenderResultImpl(env, this.popUpdating(), elementStack.popBlock(), this.destructor) }; } return result; } bindDynamicScope(names) { let scope = this.dynamicScope(); for (let i = names.length - 1; i >= 0; i--) { let name = names[i]; scope.set(name, this.stack.pop()); } } } _a = STACKS, _b = DESTROYABLE_STACK; function vmState(pc, scope, dynamicScope) { return { pc, scope, dynamicScope, stack: [] }; } function initVM(context) { return (runtime, state, builder) => new VM(runtime, state, builder, context); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL3J1bnRpbWUvbGliL3ZtL2FwcGVuZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLFNBQVMsS0FBVCxRQUFzQixjQUF0QjtBQUNBLFNBQVMseUJBQVQsUUFBMEMseUJBQTFDO0FBd0JBLFNBQ0UscUJBREYsRUFLRSxtQkFMRixRQU1PLG9CQU5QO0FBT0EsU0FBUyxNQUFULEVBQXlCLFlBQXpCLEVBQXVDLEtBQXZDLEVBQThDLFlBQTlDLFFBQWtFLGVBQWxFO0FBQ0EsU0FBUyxlQUFULEVBQTBCLGFBQTFCLEVBQXlDLGFBQXpDLFFBQThELG9CQUE5RDtBQUNBLFNBQ0UsR0FERixFQUVFLEdBRkYsRUFHRSxHQUhGLEVBSUUsR0FKRixFQUtFLEdBTEYsRUFNRSxHQU5GLEVBT0UsR0FQRixFQVFFLEdBUkYsRUFTRSxrQkFURixRQWFPLGFBYlA7QUFjQSxTQUFTLHlCQUFULFFBQTBDLHNCQUExQztBQUNBLFNBQ0UscUJBREYsRUFFRSxtQkFGRixFQUdFLHVCQUhGLFFBSU8sd0JBSlA7QUFLQSxTQUFTLGNBQVQsUUFBMkMsWUFBM0M7QUFDQSxTQUFTLGdCQUFULFFBQWlDLFVBQWpDO0FBQ0EsU0FBUyxJQUFULEVBQWUsU0FBZixFQUEwQixpQkFBMUIsRUFBNkMsSUFBN0MsRUFBbUQsUUFBbkQsRUFBNkQsU0FBN0QsRUFBd0UsTUFBeEUsUUFBc0YsWUFBdEY7QUFDQSxTQUFTLGVBQVQsUUFBZ0MsYUFBaEM7QUFFQSxPQUFPLFVBQVAsTUFBdUIsYUFBdkI7QUFDQSxPQUFPLGdCQUFQLE1BQTZCLGlCQUE3QjtBQUNBLE9BQU8sbUJBQVAsTUFBcUQsU0FBckQ7QUFDQSxTQUVFLGVBRkYsRUFHRSxjQUhGLEVBS0Usb0JBTEYsRUFNRSxTQU5GLFFBUU8sVUFSUDs7QUFpRkEsTUFBTSxNQUFOLENBQVk7QUFBWixFQUFBLFdBQUEsR0FBQTtBQUNXLFNBQUEsS0FBQSxHQUFRLElBQUksS0FBSixFQUFS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OUIsUUFBSSxLQUFLLEdBQUcsS0FBSyxZQUFMLEVBQVo7O0FBRUEsU0FBSyxJQUFJLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTixHQUFlLENBQTVCLEVBQStCLENBQUMsSUFBSSxDQUFwQyxFQUF1QyxDQUFDLEVBQXhDLEVBQTRDO0FBQzFDLFVBQUksSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFELENBQWhCO0FBQ0EsTUFBQSxLQUFLLENBQUMsR0FBTixDQUFVLElBQVYsRUFBZ0IsS0FBSyxLQUFMLENBQVcsR0FBWCxFQUFoQjtBQUNEO0FBQ0Y7O0FBbmVvQjtLQUNILE0sRUFBTSxFQUFBLEdBR04saUI7O0FBa2VwQixTQUFTLE9BQVQsQ0FBaUIsRUFBakIsRUFBNkIsS0FBN0IsRUFBMkMsWUFBM0MsRUFBcUU7QUFDbkUsU0FBTztBQUNMLElBQUEsRUFESztBQUVMLElBQUEsS0FGSztBQUdMLElBQUEsWUFISztBQUlMLElBQUEsS0FBSyxFQUFFO0FBSkYsR0FBUDtBQU1EOztBQXFCRCxTQUFTLE1BQVQsQ0FBZ0IsT0FBaEIsRUFBc0Q7QUFDcEQsU0FBTyxDQUFDLE9BQUQsRUFBVSxLQUFWLEVBQWlCLE9BQWpCLEtBQTZCLElBQUksRUFBSixDQUFPLE9BQVAsRUFBZ0IsS0FBaEIsRUFBdUIsT0FBdkIsRUFBZ0MsT0FBaEMsQ0FBcEM7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERFQlVHIH0gZnJvbSAnQGdsaW1tZXIvZW52JztcbmltcG9ydCB7IGFzc2VydEdsb2JhbENvbnRleHRXYXNTZXQgfSBmcm9tICdAZ2xpbW1lci9nbG9iYWwtY29udGV4dCc7XG5pbXBvcnQge1xuICBDb21waWxhYmxlVGVtcGxhdGUsXG4gIERlc3Ryb3lhYmxlLFxuICBEeW5hbWljU2NvcGUsXG4gIEVsZW1lbnRCdWlsZGVyLFxuICBFbnZpcm9ubWVudCxcbiAgT3B0aW9uLFxuICBQYXJ0aWFsU2NvcGUsXG4gIFJlbmRlclJlc3VsdCxcbiAgUmljaEl0ZXJhdG9yUmVzdWx0LFxuICBSdW50aW1lQ29uc3RhbnRzLFxuICBSdW50aW1lQ29udGV4dCxcbiAgUnVudGltZUhlYXAsXG4gIFJ1bnRpbWVQcm9ncmFtLFxuICBTY29wZSxcbiAgQ29tcGlsZVRpbWVDb21waWxhdGlvbkNvbnRleHQsXG4gIFZNIGFzIFB1YmxpY1ZNLFxuICBSZXNvbHV0aW9uVGltZUNvbnN0YW50cyxcbiAgT3duZXIsXG4gIFVwZGF0aW5nT3Bjb2RlLFxufSBmcm9tICdAZ2xpbW1lci9pbnRlcmZhY2VzJztcbmltcG9ydCB7IExPQ0FMX1NIT1VMRF9MT0cgfSBmcm9tICdAZ2xpbW1lci9sb2NhbC1kZWJ1Zy1mbGFncyc7XG5pbXBvcnQgeyBSdW50aW1lT3BJbXBsIH0gZnJvbSAnQGdsaW1tZXIvcHJvZ3JhbSc7XG5pbXBvcnQge1xuICBjcmVhdGVJdGVyYXRvckl0ZW1SZWYsXG4gIE9wYXF1ZUl0ZXJhdGlvbkl0ZW0sXG4gIE9wYXF1ZUl0ZXJhdG9yLFxuICBSZWZlcmVuY2UsXG4gIFVOREVGSU5FRF9SRUZFUkVOQ0UsXG59IGZyb20gJ0BnbGltbWVyL3JlZmVyZW5jZSc7XG5pbXBvcnQgeyBhc3NlcnQsIGV4cGVjdCwgTE9DQUxfTE9HR0VSLCBTdGFjaywgdW53cmFwSGFuZGxlIH0gZnJvbSAnQGdsaW1tZXIvdXRpbCc7XG5pbXBvcnQgeyBiZWdpblRyYWNrRnJhbWUsIGVuZFRyYWNrRnJhbWUsIHJlc2V0VHJhY2tpbmcgfSBmcm9tICdAZ2xpbW1lci92YWxpZGF0b3InO1xuaW1wb3J0IHtcbiAgJGZwLFxuICAkcGMsXG4gICRzMCxcbiAgJHMxLFxuICAkc3AsXG4gICR0MCxcbiAgJHQxLFxuICAkdjAsXG4gIGlzTG93TGV2ZWxSZWdpc3RlcixcbiAgTWFjaGluZVJlZ2lzdGVyLFxuICBSZWdpc3RlcixcbiAgU3lzY2FsbFJlZ2lzdGVyLFxufSBmcm9tICdAZ2xpbW1lci92bSc7XG5pbXBvcnQgeyBhc3NvY2lhdGVEZXN0cm95YWJsZUNoaWxkIH0gZnJvbSAnQGdsaW1tZXIvZGVzdHJveWFibGUnO1xuaW1wb3J0IHtcbiAgQmVnaW5UcmFja0ZyYW1lT3Bjb2RlLFxuICBFbmRUcmFja0ZyYW1lT3Bjb2RlLFxuICBKdW1wSWZOb3RNb2RpZmllZE9wY29kZSxcbn0gZnJvbSAnLi4vY29tcGlsZWQvb3Bjb2Rlcy92bSc7XG5pbXBvcnQgeyBBUFBFTkRfT1BDT0RFUywgRGVidWdTdGF0ZSB9IGZyb20gJy4uL29wY29kZXMnO1xuaW1wb3J0IHsgUGFydGlhbFNjb3BlSW1wbCB9IGZyb20gJy4uL3Njb3BlJztcbmltcG9ydCB7IEFSR1MsIENPTlNUQU5UUywgREVTVFJPWUFCTEVfU1RBQ0ssIEhFQVAsIElOTkVSX1ZNLCBSRUdJU1RFUlMsIFNUQUNLUyB9IGZyb20gJy4uL3N5bWJvbHMnO1xuaW1wb3J0IHsgVk1Bcmd1bWVudHNJbXBsIH0gZnJvbSAnLi9hcmd1bWVudHMnO1xuaW1wb3J0IHsgTGl2ZUJsb2NrTGlzdCB9IGZyb20gJy4vZWxlbWVudC1idWlsZGVyJztcbmltcG9ydCBMb3dMZXZlbFZNIGZyb20gJy4vbG93LWxldmVsJztcbmltcG9ydCBSZW5kZXJSZXN1bHRJbXBsIGZyb20gJy4vcmVuZGVyLXJlc3VsdCc7XG5pbXBvcnQgRXZhbHVhdGlvblN0YWNrSW1wbCwgeyBFdmFsdWF0aW9uU3RhY2sgfSBmcm9tICcuL3N0YWNrJztcbmltcG9ydCB7XG4gIEJsb2NrT3Bjb2RlLFxuICBMaXN0QmxvY2tPcGNvZGUsXG4gIExpc3RJdGVtT3Bjb2RlLFxuICBSZXN1bWFibGVWTVN0YXRlLFxuICBSZXN1bWFibGVWTVN0YXRlSW1wbCxcbiAgVHJ5T3Bjb2RlLFxuICBWTVN0YXRlLFxufSBmcm9tICcuL3VwZGF0ZSc7XG5cbi8qKlxuICogVGhpcyBpbnRlcmZhY2UgaXMgdXNlZCBieSBpbnRlcm5hbCBvcGNvZGVzLCBhbmQgaXMgbW9yZSBzdGFibGUgdGhhblxuICogdGhlIGltcGxlbWVudGF0aW9uIG9mIHRoZSBBcHBlbmQgVk0gaXRzZWxmLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEludGVybmFsVk0ge1xuICByZWFkb25seSBbQ09OU1RBTlRTXTogUnVudGltZUNvbnN0YW50cyAmIFJlc29sdXRpb25UaW1lQ29uc3RhbnRzO1xuICByZWFkb25seSBbQVJHU106IFZNQXJndW1lbnRzSW1wbDtcblxuICByZWFkb25seSBlbnY6IEVudmlyb25tZW50O1xuICByZWFkb25seSBzdGFjazogRXZhbHVhdGlvblN0YWNrO1xuICByZWFkb25seSBydW50aW1lOiBSdW50aW1lQ29udGV4dDtcbiAgcmVhZG9ubHkgY29udGV4dDogQ29tcGlsZVRpbWVDb21waWxhdGlvbkNvbnRleHQ7XG5cbiAgbG9hZFZhbHVlKHJlZ2lzdGVyOiBNYWNoaW5lUmVnaXN0ZXIsIHZhbHVlOiBudW1iZXIpOiB2b2lkO1xuICBsb2FkVmFsdWUocmVnaXN0ZXI6IFJlZ2lzdGVyLCB2YWx1ZTogdW5rbm93bik6IHZvaWQ7XG4gIGxvYWRWYWx1ZShyZWdpc3RlcjogUmVnaXN0ZXIgfCBNYWNoaW5lUmVnaXN0ZXIsIHZhbHVlOiB1bmtub3duKTogdm9pZDtcblxuICBmZXRjaFZhbHVlKHJlZ2lzdGVyOiBNYWNoaW5lUmVnaXN0ZXIucmEgfCBNYWNoaW5lUmVnaXN0ZXIucGMpOiBudW1iZXI7XG4gIC8vIFRPRE86IFNvbWV0aGluZyBiZXR0ZXIgdGhhbiBhIHR5cGUgYXNzZXJ0aW9uP1xuICBmZXRjaFZhbHVlPFQ+KHJlZ2lzdGVyOiBSZWdpc3Rlcik6IFQ7XG4gIGZldGNoVmFsdWUocmVnaXN0ZXI6IFJlZ2lzdGVyKTogdW5rbm93bjtcblxuICBsb2FkKHJlZ2lzdGVyOiBSZWdpc3Rlcik6IHZvaWQ7XG4gIGZldGNoKHJlZ2lzdGVyOiBSZWdpc3Rlcik6IHZvaWQ7XG5cbiAgY29tcGlsZShibG9jazogQ29tcGlsYWJsZVRlbXBsYXRlKTogbnVtYmVyO1xuXG4gIHNjb3BlKCk6IFNjb3BlO1xuICBlbGVtZW50cygpOiBFbGVtZW50QnVpbGRlcjtcblxuICBnZXRPd25lcigpOiBPd25lcjtcbiAgZ2V0U2VsZigpOiBSZWZlcmVuY2U7XG5cbiAgdXBkYXRlV2l0aChvcGNvZGU6IFVwZGF0aW5nT3Bjb2RlKTogdm9pZDtcblxuICBhc3NvY2lhdGVEZXN0cm95YWJsZShkOiBEZXN0cm95YWJsZSk6IHZvaWQ7XG5cbiAgYmVnaW5DYWNoZUdyb3VwKG5hbWU/OiBzdHJpbmcpOiB2b2lkO1xuICBjb21taXRDYWNoZUdyb3VwKCk6IHZvaWQ7XG5cbiAgLy8vIEl0ZXJhdGlvbiAvLy9cblxuICBlbnRlckxpc3QoaXRlcmFibGVSZWY6IFJlZmVyZW5jZTxPcGFxdWVJdGVyYXRvcj4sIG9mZnNldDogbnVtYmVyKTogdm9pZDtcbiAgZXhpdExpc3QoKTogdm9pZDtcbiAgZW50ZXJJdGVtKGl0ZW06IE9wYXF1ZUl0ZXJhdGlvbkl0ZW0pOiBMaXN0SXRlbU9wY29kZTtcbiAgcmVnaXN0ZXJJdGVtKGl0ZW06IExpc3RJdGVtT3Bjb2RlKTogdm9pZDtcblxuICBwdXNoUm9vdFNjb3BlKHNpemU6IG51bWJlciwgb3duZXI6IE93bmVyKTogUGFydGlhbFNjb3BlO1xuICBwdXNoQ2hpbGRTY29wZSgpOiB2b2lkO1xuICBwb3BTY29wZSgpOiB2b2lkO1xuICBwdXNoU2NvcGUoc2NvcGU6IFNjb3BlKTogdm9pZDtcblxuICBkeW5hbWljU2NvcGUoKTogRHluYW1pY1Njb3BlO1xuICBiaW5kRHluYW1pY1Njb3BlKG5hbWVzOiBzdHJpbmdbXSk6IHZvaWQ7XG4gIHB1c2hEeW5hbWljU2NvcGUoKTogdm9pZDtcbiAgcG9wRHluYW1pY1Njb3BlKCk6IHZvaWQ7XG5cbiAgZW50ZXIoYXJnczogbnVtYmVyKTogdm9pZDtcbiAgZXhpdCgpOiB2b2lkO1xuXG4gIGdvdG8ocGM6IG51bWJlcik6IHZvaWQ7XG4gIGNhbGwoaGFuZGxlOiBudW1iZXIpOiB2b2lkO1xuICBwdXNoRnJhbWUoKTogdm9pZDtcblxuICByZWZlcmVuY2VGb3JTeW1ib2woc3ltYm9sOiBudW1iZXIpOiBSZWZlcmVuY2U7XG5cbiAgZXhlY3V0ZShpbml0aWFsaXplPzogKHZtOiB0aGlzKSA9PiB2b2lkKTogUmVuZGVyUmVzdWx0O1xuICBwdXNoVXBkYXRpbmcobGlzdD86IFVwZGF0aW5nT3Bjb2RlW10pOiB2b2lkO1xuICBuZXh0KCk6IFJpY2hJdGVyYXRvclJlc3VsdDxudWxsLCBSZW5kZXJSZXN1bHQ+O1xufVxuXG5jbGFzcyBTdGFja3Mge1xuICByZWFkb25seSBzY29wZSA9IG5ldyBTdGFjazxTY29wZT4oKTtcbiAgcmVhZG9ubHkgZHluYW1pY1Njb3BlID0gbmV3IFN0YWNrPER5bmFtaWNTY29wZT4oKTtcbiAgcmVhZG9ubHkgdXBkYXRpbmcgPSBuZXcgU3RhY2s8VXBkYXRpbmdPcGNvZGVbXT4oKTtcbiAgcmVhZG9ubHkgY2FjaGUgPSBuZXcgU3RhY2s8SnVtcElmTm90TW9kaWZpZWRPcGNvZGU+KCk7XG4gIHJlYWRvbmx5IGxpc3QgPSBuZXcgU3RhY2s8TGlzdEJsb2NrT3Bjb2RlPigpO1xufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWTSBpbXBsZW1lbnRzIFB1YmxpY1ZNLCBJbnRlcm5hbFZNIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbU1RBQ0tTXSA9IG5ldyBTdGFja3MoKTtcbiAgcHJpdmF0ZSByZWFkb25seSBbSEVBUF06IFJ1bnRpbWVIZWFwO1xuICBwcml2YXRlIHJlYWRvbmx5IGRlc3RydWN0b3I6IG9iamVjdDtcbiAgcHJpdmF0ZSByZWFkb25seSBbREVTVFJPWUFCTEVfU1RBQ0tdID0gbmV3IFN0YWNrPG9iamVjdD4oKTtcbiAgcmVhZG9ubHkgW0NPTlNUQU5UU106IFJ1bnRpbWVDb25zdGFudHMgJiBSZXNvbHV0aW9uVGltZUNvbnN0YW50cztcbiAgcmVhZG9ubHkgW0FSR1NdOiBWTUFyZ3VtZW50c0ltcGw7XG4gIHJlYWRvbmx5IFtJTk5FUl9WTV06IExvd0xldmVsVk07XG5cbiAgZ2V0IHN0YWNrKCk6IEV2YWx1YXRpb25TdGFjayB7XG4gICAgcmV0dXJuIHRoaXNbSU5ORVJfVk1dLnN0YWNrIGFzIEV2YWx1YXRpb25TdGFjaztcbiAgfVxuXG4gIC8qIFJlZ2lzdGVycyAqL1xuXG4gIGdldCBwYygpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzW0lOTkVSX1ZNXS5mZXRjaFJlZ2lzdGVyKCRwYyk7XG4gIH1cblxuICBwdWJsaWMgczA6IHVua25vd24gPSBudWxsO1xuICBwdWJsaWMgczE6IHVua25vd24gPSBudWxsO1xuICBwdWJsaWMgdDA6IHVua25vd24gPSBudWxsO1xuICBwdWJsaWMgdDE6IHVua25vd24gPSBudWxsO1xuICBwdWJsaWMgdjA6IHVua25vd24gPSBudWxsO1xuXG4gIC8vIEZldGNoIGEgdmFsdWUgZnJvbSBhIHJlZ2lzdGVyIG9udG8gdGhlIHN0YWNrXG4gIGZldGNoKHJlZ2lzdGVyOiBTeXNjYWxsUmVnaXN0ZXIpOiB2b2lkIHtcbiAgICBsZXQgdmFsdWUgPSB0aGlzLmZldGNoVmFsdWUocmVnaXN0ZXIpO1xuXG4gICAgdGhpcy5zdGFjay5wdXNoKHZhbHVlKTtcbiAgfVxuXG4gIC8vIExvYWQgYSB2YWx1ZSBmcm9tIHRoZSBzdGFjayBpbnRvIGEgcmVnaXN0ZXJcbiAgbG9hZChyZWdpc3RlcjogU3lzY2FsbFJlZ2lzdGVyKSB7XG4gICAgbGV0IHZhbHVlID0gdGhpcy5zdGFjay5wb3AoKTtcblxuICAgIHRoaXMubG9hZFZhbHVlKHJlZ2lzdGVyLCB2YWx1ZSk7XG4gIH1cblxuICAvLyBGZXRjaCBhIHZhbHVlIGZyb20gYSByZWdpc3RlclxuICBmZXRjaFZhbHVlKHJlZ2lzdGVyOiBNYWNoaW5lUmVnaXN0ZXIpOiBudW1iZXI7XG4gIGZldGNoVmFsdWU8VD4ocmVnaXN0ZXI6IFJlZ2lzdGVyKTogVDtcbiAgZmV0Y2hWYWx1ZShyZWdpc3RlcjogUmVnaXN0ZXIgfCBNYWNoaW5lUmVnaXN0ZXIpOiB1bmtub3duIHtcbiAgICBpZiAoaXNMb3dMZXZlbFJlZ2lzdGVyKHJlZ2lzdGVyKSkge1xuICAgICAgcmV0dXJuIHRoaXNbSU5ORVJfVk1dLmZldGNoUmVnaXN0ZXIocmVnaXN0ZXIpO1xuICAgIH1cblxuICAgIHN3aXRjaCAocmVnaXN0ZXIpIHtcbiAgICAgIGNhc2UgJHMwOlxuICAgICAgICByZXR1cm4gdGhpcy5zMDtcbiAgICAgIGNhc2UgJHMxOlxuICAgICAgICByZXR1cm4gdGhpcy5zMTtcbiAgICAgIGNhc2UgJHQwOlxuICAgICAgICByZXR1cm4gdGhpcy50MDtcbiAgICAgIGNhc2UgJHQxOlxuICAgICAgICByZXR1cm4gdGhpcy50MTtcbiAgICAgIGNhc2UgJHYwOlxuICAgICAgICByZXR1cm4gdGhpcy52MDtcbiAgICB9XG4gIH1cblxuICAvLyBMb2FkIGEgdmFsdWUgaW50byBhIHJlZ2lzdGVyXG5cbiAgbG9hZFZhbHVlPFQ+KHJlZ2lzdGVyOiBSZWdpc3RlciB8IE1hY2hpbmVSZWdpc3RlciwgdmFsdWU6IFQpOiB2b2lkIHtcbiAgICBpZiAoaXNMb3dMZXZlbFJlZ2lzdGVyKHJlZ2lzdGVyKSkge1xuICAgICAgdGhpc1tJTk5FUl9WTV0ubG9hZFJlZ2lzdGVyKHJlZ2lzdGVyLCAodmFsdWUgYXMgYW55KSBhcyBudW1iZXIpO1xuICAgIH1cblxuICAgIHN3aXRjaCAocmVnaXN0ZXIpIHtcbiAgICAgIGNhc2UgJHMwOlxuICAgICAgICB0aGlzLnMwID0gdmFsdWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAkczE6XG4gICAgICAgIHRoaXMuczEgPSB2YWx1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICR0MDpcbiAgICAgICAgdGhpcy50MCA9IHZhbHVlO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJHQxOlxuICAgICAgICB0aGlzLnQxID0gdmFsdWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAkdjA6XG4gICAgICAgIHRoaXMudjAgPSB2YWx1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE1pZ3JhdGVkIHRvIElubmVyXG4gICAqL1xuXG4gIC8vIFN0YXJ0IGEgbmV3IGZyYW1lIGFuZCBzYXZlICRyYSBhbmQgJGZwIG9uIHRoZSBzdGFja1xuICBwdXNoRnJhbWUoKSB7XG4gICAgdGhpc1tJTk5FUl9WTV0ucHVzaEZyYW1lKCk7XG4gIH1cblxuICAvLyBSZXN0b3JlICRyYSwgJHNwIGFuZCAkZnBcbiAgcG9wRnJhbWUoKSB7XG4gICAgdGhpc1tJTk5FUl9WTV0ucG9wRnJhbWUoKTtcbiAgfVxuXG4gIC8vIEp1bXAgdG8gYW4gYWRkcmVzcyBpbiBgcHJvZ3JhbWBcbiAgZ290byhvZmZzZXQ6IG51bWJlcikge1xuICAgIHRoaXNbSU5ORVJfVk1dLmdvdG8ob2Zmc2V0KTtcbiAgfVxuXG4gIC8vIFNhdmUgJHBjIGludG8gJHJhLCB0aGVuIGp1bXAgdG8gYSBuZXcgYWRkcmVzcyBpbiBgcHJvZ3JhbWAgKGphbCBpbiBNSVBTKVxuICBjYWxsKGhhbmRsZTogbnVtYmVyKSB7XG4gICAgdGhpc1tJTk5FUl9WTV0uY2FsbChoYW5kbGUpO1xuICB9XG5cbiAgLy8gUHV0IGEgc3BlY2lmaWMgYHByb2dyYW1gIGFkZHJlc3MgaW4gJHJhXG4gIHJldHVyblRvKG9mZnNldDogbnVtYmVyKSB7XG4gICAgdGhpc1tJTk5FUl9WTV0ucmV0dXJuVG8ob2Zmc2V0KTtcbiAgfVxuXG4gIC8vIFJldHVybiB0byB0aGUgYHByb2dyYW1gIGFkZHJlc3Mgc3RvcmVkIGluICRyYVxuICByZXR1cm4oKSB7XG4gICAgdGhpc1tJTk5FUl9WTV0ucmV0dXJuKCk7XG4gIH1cblxuICAvKipcbiAgICogRW5kIG9mIG1pZ3JhdGVkLlxuICAgKi9cblxuICBjb25zdHJ1Y3RvcihcbiAgICByZWFkb25seSBydW50aW1lOiBSdW50aW1lQ29udGV4dCxcbiAgICB7IHBjLCBzY29wZSwgZHluYW1pY1Njb3BlLCBzdGFjayB9OiBWTVN0YXRlLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgZWxlbWVudFN0YWNrOiBFbGVtZW50QnVpbGRlcixcbiAgICByZWFkb25seSBjb250ZXh0OiBDb21waWxlVGltZUNvbXBpbGF0aW9uQ29udGV4dFxuICApIHtcbiAgICBpZiAoREVCVUcpIHtcbiAgICAgIGFzc2VydEdsb2JhbENvbnRleHRXYXNTZXQhKCk7XG4gICAgfVxuXG4gICAgbGV0IGV2YWxTdGFjayA9IEV2YWx1YXRpb25TdGFja0ltcGwucmVzdG9yZShzdGFjayk7XG5cbiAgICBhc3NlcnQodHlwZW9mIHBjID09PSAnbnVtYmVyJywgJ3BjIGlzIGEgbnVtYmVyJyk7XG5cbiAgICBldmFsU3RhY2tbUkVHSVNURVJTXVskcGNdID0gcGM7XG4gICAgZXZhbFN0YWNrW1JFR0lTVEVSU11bJHNwXSA9IHN0YWNrLmxlbmd0aCAtIDE7XG4gICAgZXZhbFN0YWNrW1JFR0lTVEVSU11bJGZwXSA9IC0xO1xuXG4gICAgdGhpc1tIRUFQXSA9IHRoaXMucHJvZ3JhbS5oZWFwO1xuICAgIHRoaXNbQ09OU1RBTlRTXSA9IHRoaXMucHJvZ3JhbS5jb25zdGFudHM7XG4gICAgdGhpcy5lbGVtZW50U3RhY2sgPSBlbGVtZW50U3RhY2s7XG4gICAgdGhpc1tTVEFDS1NdLnNjb3BlLnB1c2goc2NvcGUpO1xuICAgIHRoaXNbU1RBQ0tTXS5keW5hbWljU2NvcGUucHVzaChkeW5hbWljU2NvcGUpO1xuICAgIHRoaXNbQVJHU10gPSBuZXcgVk1Bcmd1bWVudHNJbXBsKCk7XG4gICAgdGhpc1tJTk5FUl9WTV0gPSBuZXcgTG93TGV2ZWxWTShcbiAgICAgIGV2YWxTdGFjayxcbiAgICAgIHRoaXNbSEVBUF0sXG4gICAgICBydW50aW1lLnByb2dyYW0sXG4gICAgICB7XG4gICAgICAgIGRlYnVnQmVmb3JlOiAob3Bjb2RlOiBSdW50aW1lT3BJbXBsKTogRGVidWdTdGF0ZSA9PiB7XG4gICAgICAgICAgcmV0dXJuIEFQUEVORF9PUENPREVTLmRlYnVnQmVmb3JlKHRoaXMsIG9wY29kZSk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZGVidWdBZnRlcjogKHN0YXRlOiBEZWJ1Z1N0YXRlKTogdm9pZCA9PiB7XG4gICAgICAgICAgQVBQRU5EX09QQ09ERVMuZGVidWdBZnRlcih0aGlzLCBzdGF0ZSk7XG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgZXZhbFN0YWNrW1JFR0lTVEVSU11cbiAgICApO1xuXG4gICAgdGhpcy5kZXN0cnVjdG9yID0ge307XG4gICAgdGhpc1tERVNUUk9ZQUJMRV9TVEFDS10ucHVzaCh0aGlzLmRlc3RydWN0b3IpO1xuICB9XG5cbiAgc3RhdGljIGluaXRpYWwoXG4gICAgcnVudGltZTogUnVudGltZUNvbnRleHQsXG4gICAgY29udGV4dDogQ29tcGlsZVRpbWVDb21waWxhdGlvbkNvbnRleHQsXG4gICAgeyBoYW5kbGUsIHNlbGYsIGR5bmFtaWNTY29wZSwgdHJlZUJ1aWxkZXIsIG51bVN5bWJvbHMsIG93bmVyIH06IEluaXRPcHRpb25zXG4gICkge1xuICAgIGxldCBzY29wZSA9IFBhcnRpYWxTY29wZUltcGwucm9vdChzZWxmLCBudW1TeW1ib2xzLCBvd25lcik7XG4gICAgbGV0IHN0YXRlID0gdm1TdGF0ZShydW50aW1lLnByb2dyYW0uaGVhcC5nZXRhZGRyKGhhbmRsZSksIHNjb3BlLCBkeW5hbWljU2NvcGUpO1xuICAgIGxldCB2bSA9IGluaXRWTShjb250ZXh0KShydW50aW1lLCBzdGF0ZSwgdHJlZUJ1aWxkZXIpO1xuICAgIHZtLnB1c2hVcGRhdGluZygpO1xuICAgIHJldHVybiB2bTtcbiAgfVxuXG4gIHN0YXRpYyBlbXB0eShcbiAgICBydW50aW1lOiBSdW50aW1lQ29udGV4dCxcbiAgICB7IGhhbmRsZSwgdHJlZUJ1aWxkZXIsIGR5bmFtaWNTY29wZSwgb3duZXIgfTogTWluaW1hbEluaXRPcHRpb25zLFxuICAgIGNvbnRleHQ6IENvbXBpbGVUaW1lQ29tcGlsYXRpb25Db250ZXh0XG4gICkge1xuICAgIGxldCB2bSA9IGluaXRWTShjb250ZXh0KShcbiAgICAgIHJ1bnRpbWUsXG4gICAgICB2bVN0YXRlKFxuICAgICAgICBydW50aW1lLnByb2dyYW0uaGVhcC5nZXRhZGRyKGhhbmRsZSksXG4gICAgICAgIFBhcnRpYWxTY29wZUltcGwucm9vdChVTkRFRklORURfUkVGRVJFTkNFLCAwLCBvd25lciksXG4gICAgICAgIGR5bmFtaWNTY29wZVxuICAgICAgKSxcbiAgICAgIHRyZWVCdWlsZGVyXG4gICAgKTtcbiAgICB2bS5wdXNoVXBkYXRpbmcoKTtcbiAgICByZXR1cm4gdm07XG4gIH1cblxuICBwcml2YXRlIHJlc3VtZTogVm1Jbml0Q2FsbGJhY2sgPSBpbml0Vk0odGhpcy5jb250ZXh0KTtcblxuICBjb21waWxlKGJsb2NrOiBDb21waWxhYmxlVGVtcGxhdGUpOiBudW1iZXIge1xuICAgIGxldCBoYW5kbGUgPSB1bndyYXBIYW5kbGUoYmxvY2suY29tcGlsZSh0aGlzLmNvbnRleHQpKTtcblxuICAgIHJldHVybiBoYW5kbGU7XG4gIH1cblxuICBnZXQgcHJvZ3JhbSgpOiBSdW50aW1lUHJvZ3JhbSB7XG4gICAgcmV0dXJuIHRoaXMucnVudGltZS5wcm9ncmFtO1xuICB9XG5cbiAgZ2V0IGVudigpOiBFbnZpcm9ubWVudCB7XG4gICAgcmV0dXJuIHRoaXMucnVudGltZS5lbnY7XG4gIH1cblxuICBjYXB0dXJlU3RhdGUoYXJnczogbnVtYmVyLCBwYyA9IHRoaXNbSU5ORVJfVk1dLmZldGNoUmVnaXN0ZXIoJHBjKSk6IFZNU3RhdGUge1xuICAgIHJldHVybiB7XG4gICAgICBwYyxcbiAgICAgIHNjb3BlOiB0aGlzLnNjb3BlKCksXG4gICAgICBkeW5hbWljU2NvcGU6IHRoaXMuZHluYW1pY1Njb3BlKCksXG4gICAgICBzdGFjazogdGhpcy5zdGFjay5jYXB0dXJlKGFyZ3MpLFxuICAgIH07XG4gIH1cblxuICBjYXB0dXJlKGFyZ3M6IG51bWJlciwgcGMgPSB0aGlzW0lOTkVSX1ZNXS5mZXRjaFJlZ2lzdGVyKCRwYykpOiBSZXN1bWFibGVWTVN0YXRlIHtcbiAgICByZXR1cm4gbmV3IFJlc3VtYWJsZVZNU3RhdGVJbXBsKHRoaXMuY2FwdHVyZVN0YXRlKGFyZ3MsIHBjKSwgdGhpcy5yZXN1bWUpO1xuICB9XG5cbiAgYmVnaW5DYWNoZUdyb3VwKG5hbWU/OiBzdHJpbmcpIHtcbiAgICBsZXQgb3Bjb2RlcyA9IHRoaXMudXBkYXRpbmcoKTtcbiAgICBsZXQgZ3VhcmQgPSBuZXcgSnVtcElmTm90TW9kaWZpZWRPcGNvZGUoKTtcblxuICAgIG9wY29kZXMucHVzaChndWFyZCk7XG4gICAgb3Bjb2Rlcy5wdXNoKG5ldyBCZWdpblRyYWNrRnJhbWVPcGNvZGUobmFtZSkpO1xuICAgIHRoaXNbU1RBQ0tTXS5jYWNoZS5wdXNoKGd1YXJkKTtcblxuICAgIGJlZ2luVHJhY2tGcmFtZShuYW1lKTtcbiAgfVxuXG4gIGNvbW1pdENhY2hlR3JvdXAoKSB7XG4gICAgbGV0IG9wY29kZXMgPSB0aGlzLnVwZGF0aW5nKCk7XG4gICAgbGV0IGd1YXJkID0gZXhwZWN0KHRoaXNbU1RBQ0tTXS5jYWNoZS5wb3AoKSwgJ1ZNIEJVRzogRXhwZWN0ZWQgYSBjYWNoZSBncm91cCcpO1xuXG4gICAgbGV0IHRhZyA9IGVuZFRyYWNrRnJhbWUoKTtcbiAgICBvcGNvZGVzLnB1c2gobmV3IEVuZFRyYWNrRnJhbWVPcGNvZGUoZ3VhcmQpKTtcblxuICAgIGd1YXJkLmZpbmFsaXplKHRhZywgb3Bjb2Rlcy5sZW5ndGgpO1xuICB9XG5cbiAgZW50ZXIoYXJnczogbnVtYmVyKSB7XG4gICAgbGV0IHVwZGF0aW5nOiBVcGRhdGluZ09wY29kZVtdID0gW107XG5cbiAgICBsZXQgc3RhdGUgPSB0aGlzLmNhcHR1cmUoYXJncyk7XG4gICAgbGV0IGJsb2NrID0gdGhpcy5lbGVtZW50cygpLnB1c2hVcGRhdGFibGVCbG9jaygpO1xuXG4gICAgbGV0IHRyeU9wY29kZSA9IG5ldyBUcnlPcGNvZGUoc3RhdGUsIHRoaXMucnVudGltZSwgYmxvY2ssIHVwZGF0aW5nKTtcblxuICAgIHRoaXMuZGlkRW50ZXIodHJ5T3Bjb2RlKTtcbiAgfVxuXG4gIGVudGVySXRlbSh7IGtleSwgdmFsdWUsIG1lbW8gfTogT3BhcXVlSXRlcmF0aW9uSXRlbSk6IExpc3RJdGVtT3Bjb2RlIHtcbiAgICBsZXQgeyBzdGFjayB9ID0gdGhpcztcblxuICAgIGxldCB2YWx1ZVJlZiA9IGNyZWF0ZUl0ZXJhdG9ySXRlbVJlZih2YWx1ZSk7XG4gICAgbGV0IG1lbW9SZWYgPSBjcmVhdGVJdGVyYXRvckl0ZW1SZWYobWVtbyk7XG5cbiAgICBzdGFjay5wdXNoKHZhbHVlUmVmKTtcbiAgICBzdGFjay5wdXNoKG1lbW9SZWYpO1xuXG4gICAgbGV0IHN0YXRlID0gdGhpcy5jYXB0dXJlKDIpO1xuICAgIGxldCBibG9jayA9IHRoaXMuZWxlbWVudHMoKS5wdXNoVXBkYXRhYmxlQmxvY2soKTtcblxuICAgIGxldCBvcGNvZGUgPSBuZXcgTGlzdEl0ZW1PcGNvZGUoc3RhdGUsIHRoaXMucnVudGltZSwgYmxvY2ssIGtleSwgbWVtb1JlZiwgdmFsdWVSZWYpO1xuICAgIHRoaXMuZGlkRW50ZXIob3Bjb2RlKTtcblxuICAgIHJldHVybiBvcGNvZGU7XG4gIH1cblxuICByZWdpc3Rlckl0ZW0ob3Bjb2RlOiBMaXN0SXRlbU9wY29kZSkge1xuICAgIHRoaXMubGlzdEJsb2NrKCkuaW5pdGlhbGl6ZUNoaWxkKG9wY29kZSk7XG4gIH1cblxuICBlbnRlckxpc3QoaXRlcmFibGVSZWY6IFJlZmVyZW5jZTxPcGFxdWVJdGVyYXRvcj4sIG9mZnNldDogbnVtYmVyKSB7XG4gICAgbGV0IHVwZGF0aW5nOiBMaXN0SXRlbU9wY29kZVtdID0gW107XG5cbiAgICBsZXQgYWRkciA9IHRoaXNbSU5ORVJfVk1dLnRhcmdldChvZmZzZXQpO1xuICAgIGxldCBzdGF0ZSA9IHRoaXMuY2FwdHVyZSgwLCBhZGRyKTtcbiAgICBsZXQgbGlzdCA9IHRoaXMuZWxlbWVudHMoKS5wdXNoQmxvY2tMaXN0KHVwZGF0aW5nKSBhcyBMaXZlQmxvY2tMaXN0O1xuXG4gICAgbGV0IG9wY29kZSA9IG5ldyBMaXN0QmxvY2tPcGNvZGUoc3RhdGUsIHRoaXMucnVudGltZSwgbGlzdCwgdXBkYXRpbmcsIGl0ZXJhYmxlUmVmKTtcblxuICAgIHRoaXNbU1RBQ0tTXS5saXN0LnB1c2gob3Bjb2RlKTtcblxuICAgIHRoaXMuZGlkRW50ZXIob3Bjb2RlKTtcbiAgfVxuXG4gIHByaXZhdGUgZGlkRW50ZXIob3Bjb2RlOiBCbG9ja09wY29kZSkge1xuICAgIHRoaXMuYXNzb2NpYXRlRGVzdHJveWFibGUob3Bjb2RlKTtcbiAgICB0aGlzW0RFU1RST1lBQkxFX1NUQUNLXS5wdXNoKG9wY29kZSk7XG4gICAgdGhpcy51cGRhdGVXaXRoKG9wY29kZSk7XG4gICAgdGhpcy5wdXNoVXBkYXRpbmcob3Bjb2RlLmNoaWxkcmVuKTtcbiAgfVxuXG4gIGV4aXQoKSB7XG4gICAgdGhpc1tERVNUUk9ZQUJMRV9TVEFDS10ucG9wKCk7XG4gICAgdGhpcy5lbGVtZW50cygpLnBvcEJsb2NrKCk7XG4gICAgdGhpcy5wb3BVcGRhdGluZygpO1xuICB9XG5cbiAgZXhpdExpc3QoKSB7XG4gICAgdGhpcy5leGl0KCk7XG4gICAgdGhpc1tTVEFDS1NdLmxpc3QucG9wKCk7XG4gIH1cblxuICBwdXNoVXBkYXRpbmcobGlzdDogVXBkYXRpbmdPcGNvZGVbXSA9IFtdKTogdm9pZCB7XG4gICAgdGhpc1tTVEFDS1NdLnVwZGF0aW5nLnB1c2gobGlzdCk7XG4gIH1cblxuICBwb3BVcGRhdGluZygpOiBVcGRhdGluZ09wY29kZVtdIHtcbiAgICByZXR1cm4gZXhwZWN0KHRoaXNbU1RBQ0tTXS51cGRhdGluZy5wb3AoKSwgXCJjYW4ndCBwb3AgYW4gZW1wdHkgc3RhY2tcIik7XG4gIH1cblxuICB1cGRhdGVXaXRoKG9wY29kZTogVXBkYXRpbmdPcGNvZGUpIHtcbiAgICB0aGlzLnVwZGF0aW5nKCkucHVzaChvcGNvZGUpO1xuICB9XG5cbiAgbGlzdEJsb2NrKCk6IExpc3RCbG9ja09wY29kZSB7XG4gICAgcmV0dXJuIGV4cGVjdCh0aGlzW1NUQUNLU10ubGlzdC5jdXJyZW50LCAnZXhwZWN0ZWQgYSBsaXN0IGJsb2NrJyk7XG4gIH1cblxuICBhc3NvY2lhdGVEZXN0cm95YWJsZShjaGlsZDogRGVzdHJveWFibGUpOiB2b2lkIHtcbiAgICBsZXQgcGFyZW50ID0gZXhwZWN0KHRoaXNbREVTVFJPWUFCTEVfU1RBQ0tdLmN1cnJlbnQsICdFeHBlY3RlZCBkZXN0cnVjdG9yIHBhcmVudCcpO1xuICAgIGFzc29jaWF0ZURlc3Ryb3lhYmxlQ2hpbGQocGFyZW50LCBjaGlsZCk7XG4gIH1cblxuICB0cnlVcGRhdGluZygpOiBPcHRpb248VXBkYXRpbmdPcGNvZGVbXT4ge1xuICAgIHJldHVybiB0aGlzW1NUQUNLU10udXBkYXRpbmcuY3VycmVudDtcbiAgfVxuXG4gIHVwZGF0aW5nKCk6IFVwZGF0aW5nT3Bjb2RlW10ge1xuICAgIHJldHVybiBleHBlY3QoXG4gICAgICB0aGlzW1NUQUNLU10udXBkYXRpbmcuY3VycmVudCxcbiAgICAgICdleHBlY3RlZCB1cGRhdGluZyBvcGNvZGUgb24gdGhlIHVwZGF0aW5nIG9wY29kZSBzdGFjaydcbiAgICApO1xuICB9XG5cbiAgZWxlbWVudHMoKTogRWxlbWVudEJ1aWxkZXIge1xuICAgIHJldHVybiB0aGlzLmVsZW1lbnRTdGFjaztcbiAgfVxuXG4gIHNjb3BlKCk6IFNjb3BlIHtcbiAgICByZXR1cm4gZXhwZWN0KHRoaXNbU1RBQ0tTXS5zY29wZS5jdXJyZW50LCAnZXhwZWN0ZWQgc2NvcGUgb24gdGhlIHNjb3BlIHN0YWNrJyk7XG4gIH1cblxuICBkeW5hbWljU2NvcGUoKTogRHluYW1pY1Njb3BlIHtcbiAgICByZXR1cm4gZXhwZWN0KFxuICAgICAgdGhpc1tTVEFDS1NdLmR5bmFtaWNTY29wZS5jdXJyZW50LFxuICAgICAgJ2V4cGVjdGVkIGR5bmFtaWMgc2NvcGUgb24gdGhlIGR5bmFtaWMgc2NvcGUgc3RhY2snXG4gICAgKTtcbiAgfVxuXG4gIHB1c2hDaGlsZFNjb3BlKCkge1xuICAgIHRoaXNbU1RBQ0tTXS5zY29wZS5wdXNoKHRoaXMuc2NvcGUoKS5jaGlsZCgpKTtcbiAgfVxuXG4gIHB1c2hEeW5hbWljU2NvcGUoKTogRHluYW1pY1Njb3BlIHtcbiAgICBsZXQgY2hpbGQgPSB0aGlzLmR5bmFtaWNTY29wZSgpLmNoaWxkKCk7XG4gICAgdGhpc1tTVEFDS1NdLmR5bmFtaWNTY29wZS5wdXNoKGNoaWxkKTtcbiAgICByZXR1cm4gY2hpbGQ7XG4gIH1cblxuICBwdXNoUm9vdFNjb3BlKHNpemU6IG51bWJlciwgb3duZXI6IE93bmVyKTogUGFydGlhbFNjb3BlIHtcbiAgICBsZXQgc2NvcGUgPSBQYXJ0aWFsU2NvcGVJbXBsLnNpemVkKHNpemUsIG93bmVyKTtcbiAgICB0aGlzW1NUQUNLU10uc2NvcGUucHVzaChzY29wZSk7XG4gICAgcmV0dXJuIHNjb3BlO1xuICB9XG5cbiAgcHVzaFNjb3BlKHNjb3BlOiBTY29wZSkge1xuICAgIHRoaXNbU1RBQ0tTXS5zY29wZS5wdXNoKHNjb3BlKTtcbiAgfVxuXG4gIHBvcFNjb3BlKCkge1xuICAgIHRoaXNbU1RBQ0tTXS5zY29wZS5wb3AoKTtcbiAgfVxuXG4gIHBvcER5bmFtaWNTY29wZSgpIHtcbiAgICB0aGlzW1NUQUNLU10uZHluYW1pY1Njb3BlLnBvcCgpO1xuICB9XG5cbiAgLy8vIFNDT1BFIEhFTFBFUlNcblxuICBnZXRPd25lcigpOiBPd25lciB7XG4gICAgcmV0dXJuIHRoaXMuc2NvcGUoKS5vd25lcjtcbiAgfVxuXG4gIGdldFNlbGYoKTogUmVmZXJlbmNlPGFueT4ge1xuICAgIHJldHVybiB0aGlzLnNjb3BlKCkuZ2V0U2VsZigpO1xuICB9XG5cbiAgcmVmZXJlbmNlRm9yU3ltYm9sKHN5bWJvbDogbnVtYmVyKTogUmVmZXJlbmNlIHtcbiAgICByZXR1cm4gdGhpcy5zY29wZSgpLmdldFN5bWJvbChzeW1ib2wpO1xuICB9XG5cbiAgLy8vIEVYRUNVVElPTlxuXG4gIGV4ZWN1dGUoaW5pdGlhbGl6ZT86ICh2bTogdGhpcykgPT4gdm9pZCk6IFJlbmRlclJlc3VsdCB7XG4gICAgaWYgKERFQlVHKSB7XG4gICAgICBsZXQgaGFzRXJyb3JlZCA9IHRydWU7XG4gICAgICB0cnkge1xuICAgICAgICBsZXQgdmFsdWUgPSB0aGlzLl9leGVjdXRlKGluaXRpYWxpemUpO1xuXG4gICAgICAgIC8vIHVzaW5nIGEgYm9vbGVhbiBoZXJlIHRvIGF2b2lkIGJyZWFraW5nIGVyZ29ub21pY3Mgb2YgXCJwYXVzZSBvbiB1bmNhdWdodCBleGNlcHRpb25zXCJcbiAgICAgICAgLy8gd2hpY2ggd291bGQgaGFwcGVuIHdpdGggYSBgY2F0Y2hgICsgYHRocm93YFxuICAgICAgICBoYXNFcnJvcmVkID0gZmFsc2U7XG5cbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgaWYgKGhhc0Vycm9yZWQpIHtcbiAgICAgICAgICAvLyBJZiBhbnkgZXhpc3RpbmcgYmxvY2tzIGFyZSBvcGVuLCBkdWUgdG8gYW4gZXJyb3Igb3Igc29tZXRoaW5nIGxpa2VcbiAgICAgICAgICAvLyB0aGF0LCB3ZSBuZWVkIHRvIGNsb3NlIHRoZW0gYWxsIGFuZCBjbGVhbiB0aGluZ3MgdXAgcHJvcGVybHkuXG4gICAgICAgICAgbGV0IGVsZW1lbnRzID0gdGhpcy5lbGVtZW50cygpO1xuXG4gICAgICAgICAgd2hpbGUgKGVsZW1lbnRzLmhhc0Jsb2Nrcykge1xuICAgICAgICAgICAgZWxlbWVudHMucG9wQmxvY2soKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYFxcblxcbkVycm9yIG9jY3VycmVkOlxcblxcbiR7cmVzZXRUcmFja2luZygpfVxcblxcbmApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLl9leGVjdXRlKGluaXRpYWxpemUpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2V4ZWN1dGUoaW5pdGlhbGl6ZT86ICh2bTogdGhpcykgPT4gdm9pZCk6IFJlbmRlclJlc3VsdCB7XG4gICAgaWYgKExPQ0FMX1NIT1VMRF9MT0cpIHtcbiAgICAgIExPQ0FMX0xPR0dFUi5sb2coYEVYRUNVVElORyBGUk9NICR7dGhpc1tJTk5FUl9WTV0uZmV0Y2hSZWdpc3RlcigkcGMpfWApO1xuICAgIH1cblxuICAgIGlmIChpbml0aWFsaXplKSBpbml0aWFsaXplKHRoaXMpO1xuXG4gICAgbGV0IHJlc3VsdDogUmljaEl0ZXJhdG9yUmVzdWx0PG51bGwsIFJlbmRlclJlc3VsdD47XG5cbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgcmVzdWx0ID0gdGhpcy5uZXh0KCk7XG4gICAgICBpZiAocmVzdWx0LmRvbmUpIGJyZWFrO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQudmFsdWU7XG4gIH1cblxuICBuZXh0KCk6IFJpY2hJdGVyYXRvclJlc3VsdDxudWxsLCBSZW5kZXJSZXN1bHQ+IHtcbiAgICBsZXQgeyBlbnYsIGVsZW1lbnRTdGFjayB9ID0gdGhpcztcbiAgICBsZXQgb3Bjb2RlID0gdGhpc1tJTk5FUl9WTV0ubmV4dFN0YXRlbWVudCgpO1xuICAgIGxldCByZXN1bHQ6IFJpY2hJdGVyYXRvclJlc3VsdDxudWxsLCBSZW5kZXJSZXN1bHQ+O1xuICAgIGlmIChvcGNvZGUgIT09IG51bGwpIHtcbiAgICAgIHRoaXNbSU5ORVJfVk1dLmV2YWx1YXRlT3V0ZXIob3Bjb2RlLCB0aGlzKTtcbiAgICAgIHJlc3VsdCA9IHsgZG9uZTogZmFsc2UsIHZhbHVlOiBudWxsIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFVubG9hZCB0aGUgc3RhY2tcbiAgICAgIHRoaXMuc3RhY2sucmVzZXQoKTtcblxuICAgICAgcmVzdWx0ID0ge1xuICAgICAgICBkb25lOiB0cnVlLFxuICAgICAgICB2YWx1ZTogbmV3IFJlbmRlclJlc3VsdEltcGwoXG4gICAgICAgICAgZW52LFxuICAgICAgICAgIHRoaXMucG9wVXBkYXRpbmcoKSxcbiAgICAgICAgICBlbGVtZW50U3RhY2sucG9wQmxvY2soKSxcbiAgICAgICAgICB0aGlzLmRlc3RydWN0b3JcbiAgICAgICAgKSxcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBiaW5kRHluYW1pY1Njb3BlKG5hbWVzOiBzdHJpbmdbXSkge1xuICAgIGxldCBzY29wZSA9IHRoaXMuZHluYW1pY1Njb3BlKCk7XG5cbiAgICBmb3IgKGxldCBpID0gbmFtZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGxldCBuYW1lID0gbmFtZXNbaV07XG4gICAgICBzY29wZS5zZXQobmFtZSwgdGhpcy5zdGFjay5wb3A8UmVmZXJlbmNlPHVua25vd24+PigpKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gdm1TdGF0ZShwYzogbnVtYmVyLCBzY29wZTogU2NvcGUsIGR5bmFtaWNTY29wZTogRHluYW1pY1Njb3BlKSB7XG4gIHJldHVybiB7XG4gICAgcGMsXG4gICAgc2NvcGUsXG4gICAgZHluYW1pY1Njb3BlLFxuICAgIHN0YWNrOiBbXSxcbiAgfTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBNaW5pbWFsSW5pdE9wdGlvbnMge1xuICBoYW5kbGU6IG51bWJlcjtcbiAgdHJlZUJ1aWxkZXI6IEVsZW1lbnRCdWlsZGVyO1xuICBkeW5hbWljU2NvcGU6IER5bmFtaWNTY29wZTtcbiAgb3duZXI6IE93bmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEluaXRPcHRpb25zIGV4dGVuZHMgTWluaW1hbEluaXRPcHRpb25zIHtcbiAgc2VsZjogUmVmZXJlbmNlO1xuICBudW1TeW1ib2xzOiBudW1iZXI7XG59XG5cbmV4cG9ydCB0eXBlIFZtSW5pdENhbGxiYWNrID0gKFxuICB0aGlzOiB2b2lkLFxuICBydW50aW1lOiBSdW50aW1lQ29udGV4dCxcbiAgc3RhdGU6IFZNU3RhdGUsXG4gIGJ1aWxkZXI6IEVsZW1lbnRCdWlsZGVyXG4pID0+IEludGVybmFsVk07XG5cbmZ1bmN0aW9uIGluaXRWTShjb250ZXh0OiBDb21waWxlVGltZUNvbXBpbGF0aW9uQ29udGV4dCk6IFZtSW5pdENhbGxiYWNrIHtcbiAgcmV0dXJuIChydW50aW1lLCBzdGF0ZSwgYnVpbGRlcikgPT4gbmV3IFZNKHJ1bnRpbWUsIHN0YXRlLCBidWlsZGVyLCBjb250ZXh0KTtcbn1cbiJdLCJzb3VyY2VSb290IjoiIn0=