UNPKG

ember-legacy-class-transform

Version:
342 lines (331 loc) 38.5 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.EvaluationStack = undefined; var _opcodes = require('../opcodes'); var _environment = require('../environment'); var _util = require('@glimmer/util'); var _reference = require('@glimmer/reference'); var _vm = require('../compiled/opcodes/vm'); var _update = require('./update'); var _renderResult = require('./render-result'); var _renderResult2 = _interopRequireDefault(_renderResult); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } class EvaluationStack { constructor(stack, fp, sp) { this.stack = stack; this.fp = fp; this.sp = sp; if (false) { Object.seal(this); } } static empty() { return new this([], 0, -1); } static restore(snapshot) { return new this(snapshot.slice(), 0, snapshot.length - 1); } isEmpty() { return this.sp === -1; } push(value) { this.stack[++this.sp] = value; } dup(position = this.sp) { this.push(this.stack[position]); } pop(n = 1) { let top = this.stack[this.sp]; this.sp -= n; return top; } peek() { return this.stack[this.sp]; } fromBase(offset) { return this.stack[this.fp - offset]; } fromTop(offset) { return this.stack[this.sp - offset]; } capture(items) { let end = this.sp + 1; let start = end - items; return this.stack.slice(start, end); } reset() { this.stack.length = 0; } toArray() { return this.stack.slice(this.fp, this.sp + 1); } } exports.EvaluationStack = EvaluationStack; class VM { constructor(env, scope, dynamicScope, elementStack) { this.env = env; this.elementStack = elementStack; this.dynamicScopeStack = new _util.Stack(); this.scopeStack = new _util.Stack(); this.updatingOpcodeStack = new _util.Stack(); this.cacheGroups = new _util.Stack(); this.listBlockStack = new _util.Stack(); this.stack = EvaluationStack.empty(); /* Registers */ this.pc = -1; this.ra = -1; this.s0 = null; this.s1 = null; this.t0 = null; this.t1 = null; this.env = env; this.heap = env.program.heap; this.constants = env.program.constants; this.elementStack = elementStack; this.scopeStack.push(scope); this.dynamicScopeStack.push(dynamicScope); } get fp() { return this.stack.fp; } set fp(fp) { this.stack.fp = fp; } get sp() { return this.stack.sp; } set sp(sp) { this.stack.sp = sp; } // Fetch a value from a register onto the stack fetch(register) { this.stack.push(this[_opcodes.Register[register]]); } // Load a value from the stack into a register load(register) { this[_opcodes.Register[register]] = this.stack.pop(); } // Fetch a value from a register fetchValue(register) { return this[_opcodes.Register[register]]; } // Load a value into a register loadValue(register, value) { this[_opcodes.Register[register]] = value; } // Start a new frame and save $ra and $fp on the stack pushFrame() { this.stack.push(this.ra); this.stack.push(this.fp); this.fp = this.sp - 1; } // Restore $ra, $sp and $fp popFrame() { this.sp = this.fp - 1; this.ra = this.stack.fromBase(0); this.fp = this.stack.fromBase(-1); } // Jump to an address in `program` goto(offset) { this.pc = (0, _util.typePos)(this.pc + offset); } // Save $pc into $ra, then jump to a new address in `program` (jal in MIPS) call(handle) { let pc = this.heap.getaddr(handle); this.ra = this.pc; this.pc = pc; } // Put a specific `program` address in $ra returnTo(offset) { this.ra = (0, _util.typePos)(this.pc + offset); } // Return to the `program` address stored in $ra return() { this.pc = this.ra; } static initial(env, self, dynamicScope, elementStack, program) { let scope = _environment.Scope.root(self, program.symbolTable.symbols.length); let vm = new VM(env, scope, dynamicScope, elementStack); vm.pc = vm.heap.getaddr(program.handle); vm.updatingOpcodeStack.push(new _util.LinkedList()); return vm; } capture(args) { return { dynamicScope: this.dynamicScope(), env: this.env, scope: this.scope(), stack: this.stack.capture(args) }; } beginCacheGroup() { this.cacheGroups.push(this.updating().tail()); } commitCacheGroup() { // JumpIfNotModified(END) // (head) // (....) // (tail) // DidModify // END: Noop let END = new _vm.LabelOpcode("END"); let opcodes = this.updating(); let marker = this.cacheGroups.pop(); let head = marker ? opcodes.nextNode(marker) : opcodes.head(); let tail = opcodes.tail(); let tag = (0, _reference.combineSlice)(new _util.ListSlice(head, tail)); let guard = new _vm.JumpIfNotModifiedOpcode(tag, END); opcodes.insertBefore(guard, head); opcodes.append(new _vm.DidModifyOpcode(guard)); opcodes.append(END); } enter(args) { let updating = new _util.LinkedList(); let state = this.capture(args); let tracker = this.elements().pushUpdatableBlock(); let tryOpcode = new _update.TryOpcode(this.heap.gethandle(this.pc), state, tracker, updating); this.didEnter(tryOpcode); } iterate(memo, value) { let stack = this.stack; stack.push(value); stack.push(memo); let state = this.capture(2); let tracker = this.elements().pushUpdatableBlock(); // let ip = this.ip; // this.ip = end + 4; // this.frames.push(ip); return new _update.TryOpcode(this.heap.gethandle(this.pc), state, tracker, new _util.LinkedList()); } enterItem(key, opcode) { this.listBlock().map[key] = opcode; this.didEnter(opcode); } enterList(relativeStart) { let updating = new _util.LinkedList(); let state = this.capture(0); let tracker = this.elements().pushBlockList(updating); let artifacts = this.stack.peek().artifacts; let start = this.heap.gethandle((0, _util.typePos)(this.pc + relativeStart)); let opcode = new _update.ListBlockOpcode(start, state, tracker, updating, artifacts); this.listBlockStack.push(opcode); this.didEnter(opcode); } didEnter(opcode) { this.updateWith(opcode); this.updatingOpcodeStack.push(opcode.children); } exit() { this.elements().popBlock(); this.updatingOpcodeStack.pop(); let parent = this.updating().tail(); parent.didInitializeChildren(); } exitList() { this.exit(); this.listBlockStack.pop(); } updateWith(opcode) { this.updating().append(opcode); } listBlock() { return (0, _util.expect)(this.listBlockStack.current, 'expected a list block'); } updating() { return (0, _util.expect)(this.updatingOpcodeStack.current, 'expected updating opcode on the updating opcode stack'); } elements() { return this.elementStack; } scope() { return (0, _util.expect)(this.scopeStack.current, 'expected scope on the scope stack'); } dynamicScope() { return (0, _util.expect)(this.dynamicScopeStack.current, 'expected dynamic scope on the dynamic scope stack'); } pushChildScope() { this.scopeStack.push(this.scope().child()); } pushCallerScope(childScope = false) { let callerScope = (0, _util.expect)(this.scope().getCallerScope(), 'pushCallerScope is called when a caller scope is present'); this.scopeStack.push(childScope ? callerScope.child() : callerScope); } pushDynamicScope() { let child = this.dynamicScope().child(); this.dynamicScopeStack.push(child); return child; } pushRootScope(size, bindCaller) { let scope = _environment.Scope.sized(size); if (bindCaller) scope.bindCallerScope(this.scope()); this.scopeStack.push(scope); return scope; } popScope() { this.scopeStack.pop(); } popDynamicScope() { this.dynamicScopeStack.pop(); } newDestroyable(d) { this.elements().newDestroyable(d); } /// SCOPE HELPERS getSelf() { return this.scope().getSelf(); } referenceForSymbol(symbol) { return this.scope().getSymbol(symbol); } /// EXECUTION execute(start, initialize) { this.pc = this.heap.getaddr(start); if (initialize) initialize(this); let result; while (true) { result = this.next(); if (result.done) break; } return result.value; } next() { let { env, updatingOpcodeStack, elementStack } = this; let opcode = this.nextStatement(env); let result; if (opcode !== null) { _opcodes.APPEND_OPCODES.evaluate(this, opcode, opcode.type); result = { done: false, value: null }; } else { // Unload the stack this.stack.reset(); result = { done: true, value: new _renderResult2.default(env, (0, _util.expect)(updatingOpcodeStack.pop(), 'there should be a final updating opcode stack'), elementStack.popBlock()) }; } return result; } nextStatement(env) { let { pc } = this; if (pc === -1) { return null; } let program = env.program; this.pc += 4; return program.opcode(pc); } evaluateOpcode(opcode) { _opcodes.APPEND_OPCODES.evaluate(this, opcode, opcode.type); } bindDynamicScope(names) { let scope = this.dynamicScope(); for (let i = names.length - 1; i >= 0; i--) { let name = this.constants.getString(names[i]); scope.set(name, this.stack.pop()); } } } exports.default = VM; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi92bS9hcHBlbmQuanMiXSwibmFtZXMiOlsiRXZhbHVhdGlvblN0YWNrIiwiY29uc3RydWN0b3IiLCJzdGFjayIsImZwIiwic3AiLCJPYmplY3QiLCJzZWFsIiwiZW1wdHkiLCJyZXN0b3JlIiwic25hcHNob3QiLCJzbGljZSIsImxlbmd0aCIsImlzRW1wdHkiLCJwdXNoIiwidmFsdWUiLCJkdXAiLCJwb3NpdGlvbiIsInBvcCIsIm4iLCJ0b3AiLCJwZWVrIiwiZnJvbUJhc2UiLCJvZmZzZXQiLCJmcm9tVG9wIiwiY2FwdHVyZSIsIml0ZW1zIiwiZW5kIiwic3RhcnQiLCJyZXNldCIsInRvQXJyYXkiLCJWTSIsImVudiIsInNjb3BlIiwiZHluYW1pY1Njb3BlIiwiZWxlbWVudFN0YWNrIiwiZHluYW1pY1Njb3BlU3RhY2siLCJzY29wZVN0YWNrIiwidXBkYXRpbmdPcGNvZGVTdGFjayIsImNhY2hlR3JvdXBzIiwibGlzdEJsb2NrU3RhY2siLCJwYyIsInJhIiwiczAiLCJzMSIsInQwIiwidDEiLCJoZWFwIiwicHJvZ3JhbSIsImNvbnN0YW50cyIsImZldGNoIiwicmVnaXN0ZXIiLCJsb2FkIiwiZmV0Y2hWYWx1ZSIsImxvYWRWYWx1ZSIsInB1c2hGcmFtZSIsInBvcEZyYW1lIiwiZ290byIsImNhbGwiLCJoYW5kbGUiLCJnZXRhZGRyIiwicmV0dXJuVG8iLCJyZXR1cm4iLCJpbml0aWFsIiwic2VsZiIsInJvb3QiLCJzeW1ib2xUYWJsZSIsInN5bWJvbHMiLCJ2bSIsImFyZ3MiLCJiZWdpbkNhY2hlR3JvdXAiLCJ1cGRhdGluZyIsInRhaWwiLCJjb21taXRDYWNoZUdyb3VwIiwiRU5EIiwib3Bjb2RlcyIsIm1hcmtlciIsImhlYWQiLCJuZXh0Tm9kZSIsInRhZyIsImd1YXJkIiwiaW5zZXJ0QmVmb3JlIiwiYXBwZW5kIiwiZW50ZXIiLCJzdGF0ZSIsInRyYWNrZXIiLCJlbGVtZW50cyIsInB1c2hVcGRhdGFibGVCbG9jayIsInRyeU9wY29kZSIsImdldGhhbmRsZSIsImRpZEVudGVyIiwiaXRlcmF0ZSIsIm1lbW8iLCJlbnRlckl0ZW0iLCJrZXkiLCJvcGNvZGUiLCJsaXN0QmxvY2siLCJtYXAiLCJlbnRlckxpc3QiLCJyZWxhdGl2ZVN0YXJ0IiwicHVzaEJsb2NrTGlzdCIsImFydGlmYWN0cyIsInVwZGF0ZVdpdGgiLCJjaGlsZHJlbiIsImV4aXQiLCJwb3BCbG9jayIsInBhcmVudCIsImRpZEluaXRpYWxpemVDaGlsZHJlbiIsImV4aXRMaXN0IiwiY3VycmVudCIsInB1c2hDaGlsZFNjb3BlIiwiY2hpbGQiLCJwdXNoQ2FsbGVyU2NvcGUiLCJjaGlsZFNjb3BlIiwiY2FsbGVyU2NvcGUiLCJnZXRDYWxsZXJTY29wZSIsInB1c2hEeW5hbWljU2NvcGUiLCJwdXNoUm9vdFNjb3BlIiwic2l6ZSIsImJpbmRDYWxsZXIiLCJzaXplZCIsImJpbmRDYWxsZXJTY29wZSIsInBvcFNjb3BlIiwicG9wRHluYW1pY1Njb3BlIiwibmV3RGVzdHJveWFibGUiLCJkIiwiZ2V0U2VsZiIsInJlZmVyZW5jZUZvclN5bWJvbCIsInN5bWJvbCIsImdldFN5bWJvbCIsImV4ZWN1dGUiLCJpbml0aWFsaXplIiwicmVzdWx0IiwibmV4dCIsImRvbmUiLCJuZXh0U3RhdGVtZW50IiwiZXZhbHVhdGUiLCJ0eXBlIiwiZXZhbHVhdGVPcGNvZGUiLCJiaW5kRHluYW1pY1Njb3BlIiwibmFtZXMiLCJpIiwibmFtZSIsImdldFN0cmluZyIsInNldCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7QUFHTyxNQUFNQSxlQUFOLENBQXNCO0FBQ3pCQyxnQkFBWUMsS0FBWixFQUFtQkMsRUFBbkIsRUFBdUJDLEVBQXZCLEVBQTJCO0FBQ3ZCLGFBQUtGLEtBQUwsR0FBYUEsS0FBYjtBQUNBLGFBQUtDLEVBQUwsR0FBVUEsRUFBVjtBQUNBLGFBQUtDLEVBQUwsR0FBVUEsRUFBVjtBQUNBLFlBQUksS0FBSixFQUFXO0FB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LEVBQW1CO0FBQ2YsWUFBSSxFQUFFUyxFQUFGLEtBQVMsSUFBYjtBQUNBLFlBQUlBLE9BQU8sQ0FBQyxDQUFaLEVBQWU7QUFDWCxtQkFBTyxJQUFQO0FBQ0g7QUFDRCxZQUFJTyxVQUFVaEIsSUFBSWdCLE9BQWxCO0FBQ0EsYUFBS1AsRUFBTCxJQUFXLENBQVg7QUFDQSxlQUFPTyxRQUFRK0MsTUFBUixDQUFldEQsRUFBZixDQUFQO0FBQ0g7QUFDRGlHLG1CQUFlM0MsTUFBZixFQUF1QjtBQUNuQixnQ0FBZXlDLFFBQWYsQ0FBd0IsSUFBeEIsRUFBOEJ6QyxNQUE5QixFQUFzQ0EsT0FBTzBDLElBQTdDO0FBQ0g7QUFDREUscUJBQWlCQyxLQUFqQixFQUF3QjtBQUNwQixZQUFJM0csUUFBUSxLQUFLQyxZQUFMLEVBQVo7QUFDQSxhQUFLLElBQUkyRyxJQUFJRCxNQUFNaEksTUFBTixHQUFlLENBQTVCLEVBQStCaUksS0FBSyxDQUFwQyxFQUF1Q0EsR0FBdkMsRUFBNEM7QUFDeEMsZ0JBQUlDLE9BQU8sS0FBSzdGLFNBQUwsQ0FBZThGLFNBQWYsQ0FBeUJILE1BQU1DLENBQU4sQ0FBekIsQ0FBWDtBQUNBNUcsa0JBQU0rRyxHQUFOLENBQVVGLElBQVYsRUFBZ0IsS0FBSzNJLEtBQUwsQ0FBV2UsR0FBWCxFQUFoQjtBQUNIO0FBQ0o7QUF0UW1CO2tCQUFIYSxFIiwiZmlsZSI6ImxpYi92bS9hcHBlbmQuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBSZWdpc3RlciB9IGZyb20gJy4uL29wY29kZXMnO1xuaW1wb3J0IHsgU2NvcGUgfSBmcm9tICcuLi9lbnZpcm9ubWVudCc7XG5pbXBvcnQgeyBTdGFjaywgTGlua2VkTGlzdCwgTGlzdFNsaWNlLCBleHBlY3QsIHR5cGVQb3MgfSBmcm9tICdAZ2xpbW1lci91dGlsJztcbmltcG9ydCB7IGNvbWJpbmVTbGljZSB9IGZyb20gJ0BnbGltbWVyL3JlZmVyZW5jZSc7XG5pbXBvcnQgeyBMYWJlbE9wY29kZSwgSnVtcElmTm90TW9kaWZpZWRPcGNvZGUsIERpZE1vZGlmeU9wY29kZSB9IGZyb20gJy4uL2NvbXBpbGVkL29wY29kZXMvdm0nO1xuaW1wb3J0IHsgTGlzdEJsb2NrT3Bjb2RlLCBUcnlPcGNvZGUgfSBmcm9tICcuL3VwZGF0ZSc7XG5pbXBvcnQgUmVuZGVyUmVzdWx0IGZyb20gJy4vcmVuZGVyLXJlc3VsdCc7XG5cbmltcG9ydCB7IEFQUEVORF9PUENPREVTIH0gZnJvbSAnLi4vb3Bjb2Rlcyc7XG5leHBvcnQgY2xhc3MgRXZhbHVhdGlvblN0YWNrIHtcbiAgICBjb25zdHJ1Y3RvcihzdGFjaywgZnAsIHNwKSB7XG4gICAgICAgIHRoaXMuc3RhY2sgPSBzdGFjaztcbiAgICAgICAgdGhpcy5mcCA9IGZwO1xuICAgICAgICB0aGlzLnNwID0gc3A7XG4gICAgICAgIGlmIChmYWxzZSkge1xuICAgICAgICAgICAgT2JqZWN0LnNlYWwodGhpcyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIGVtcHR5KCkge1xuICAgICAgICByZXR1cm4gbmV3IHRoaXMoW10sIDAsIC0xKTtcbiAgICB9XG4gICAgc3RhdGljIHJlc3RvcmUoc25hcHNob3QpIHtcbiAgICAgICAgcmV0dXJuIG5ldyB0aGlzKHNuYXBzaG90LnNsaWNlKCksIDAsIHNuYXBzaG90Lmxlbmd0aCAtIDEpO1xuICAgIH1cbiAgICBpc0VtcHR5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zcCA9PT0gLTE7XG4gICAgfVxuICAgIHB1c2godmFsdWUpIHtcbiAgICAgICAgdGhpcy5zdGFja1srK3RoaXMuc3BdID0gdmFsdWU7XG4gICAgfVxuICAgIGR1cChwb3NpdGlvbiA9IHRoaXMuc3ApIHtcbiAgICAgICAgdGhpcy5wdXNoKHRoaXMuc3RhY2tbcG9zaXRpb25dKTtcbiAgICB9XG4gICAgcG9wKG4gPSAxKSB7XG4gICAgICAgIGxldCB0b3AgPSB0aGlzLnN0YWNrW3RoaXMuc3BdO1xuICAgICAgICB0aGlzLnNwIC09IG47XG4gICAgICAgIHJldHVybiB0b3A7XG4gICAgfVxuICAgIHBlZWsoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0YWNrW3RoaXMuc3BdO1xuICAgIH1cbiAgICBmcm9tQmFzZShvZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhY2tbdGhpcy5mcCAtIG9mZnNldF07XG4gICAgfVxuICAgIGZyb21Ub3Aob2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0YWNrW3RoaXMuc3AgLSBvZmZzZXRdO1xuICAgIH1cbiAgICBjYXB0dXJlKGl0ZW1zKSB7XG4gICAgICAgIGxldCBlbmQgPSB0aGlzLnNwICsgMTtcbiAgICAgICAgbGV0IHN0YXJ0ID0gZW5kIC0gaXRlbXM7XG4gICAgICAgIHJldHVybiB0aGlzLnN0YWNrLnNsaWNlKHN0YXJ0LCBlbmQpO1xuICAgIH1cbiAgICByZXNldCgpIHtcbiAgICAgICAgdGhpcy5zdGFjay5sZW5ndGggPSAwO1xuICAgIH1cbiAgICB0b0FycmF5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zdGFjay5zbGljZSh0aGlzLmZwLCB0aGlzLnNwICsgMSk7XG4gICAgfVxufVxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVk0ge1xuICAgIGNvbnN0cnVjdG9yKGVudiwgc2NvcGUsIGR5bmFtaWNTY29wZSwgZWxlbWVudFN0YWNrKSB7XG4gICAgICAgIHRoaXMuZW52ID0gZW52O1xuICAgICAgICB0aGlzLmVsZW1lbnRTdGFjayA9IGVsZW1lbnRTdGFjaztcbiAgICAgICAgdGhpcy5keW5hbWljU2NvcGVTdGFjayA9IG5ldyBTdGFjaygpO1xuICAgICAgICB0aGlzLnNjb3BlU3RhY2sgPSBuZXcgU3RhY2soKTtcbiAgICAgICAgdGhpcy51cGRhdGluZ09wY29kZVN0YWNrID0gbmV3IFN0YWNrKCk7XG4gICAgICAgIHRoaXMuY2FjaGVHcm91cHMgPSBuZXcgU3RhY2soKTtcbiAgICAgICAgdGhpcy5saXN0QmxvY2tTdGFjayA9IG5ldyBTdGFjaygpO1xuICAgICAgICB0aGlzLnN0YWNrID0gRXZhbHVhdGlvblN0YWNrLmVtcHR5KCk7XG4gICAgICAgIC8qIFJlZ2lzdGVycyAqL1xuICAgICAgICB0aGlzLnBjID0gLTE7XG4gICAgICAgIHRoaXMucmEgPSAtMTtcbiAgICAgICAgdGhpcy5zMCA9IG51bGw7XG4gICAgICAgIHRoaXMuczEgPSBudWxsO1xuICAgICAgICB0aGlzLnQwID0gbnVsbDtcbiAgICAgICAgdGhpcy50MSA9IG51bGw7XG4gICAgICAgIHRoaXMuZW52ID0gZW52O1xuICAgICAgICB0aGlzLmhlYXAgPSBlbnYucHJvZ3JhbS5oZWFwO1xuICAgICAgICB0aGlzLmNvbnN0YW50cyA9IGVudi5wcm9ncmFtLmNvbnN0YW50cztcbiAgICAgICAgdGhpcy5lbGVtZW50U3RhY2sgPSBlbGVtZW50U3RhY2s7XG4gICAgICAgIHRoaXMuc2NvcGVTdGFjay5wdXNoKHNjb3BlKTtcbiAgICAgICAgdGhpcy5keW5hbWljU2NvcGVTdGFjay5wdXNoKGR5bmFtaWNTY29wZSk7XG4gICAgfVxuICAgIGdldCBmcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhY2suZnA7XG4gICAgfVxuICAgIHNldCBmcChmcCkge1xuICAgICAgICB0aGlzLnN0YWNrLmZwID0gZnA7XG4gICAgfVxuICAgIGdldCBzcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhY2suc3A7XG4gICAgfVxuICAgIHNldCBzcChzcCkge1xuICAgICAgICB0aGlzLnN0YWNrLnNwID0gc3A7XG4gICAgfVxuICAgIC8vIEZldGNoIGEgdmFsdWUgZnJvbSBhIHJlZ2lzdGVyIG9udG8gdGhlIHN0YWNrXG4gICAgZmV0Y2gocmVnaXN0ZXIpIHtcbiAgICAgICAgdGhpcy5zdGFjay5wdXNoKHRoaXNbUmVnaXN0ZXJbcmVnaXN0ZXJdXSk7XG4gICAgfVxuICAgIC8vIExvYWQgYSB2YWx1ZSBmcm9tIHRoZSBzdGFjayBpbnRvIGEgcmVnaXN0ZXJcbiAgICBsb2FkKHJlZ2lzdGVyKSB7XG4gICAgICAgIHRoaXNbUmVnaXN0ZXJbcmVnaXN0ZXJdXSA9IHRoaXMuc3RhY2sucG9wKCk7XG4gICAgfVxuICAgIC8vIEZldGNoIGEgdmFsdWUgZnJvbSBhIHJlZ2lzdGVyXG4gICAgZmV0Y2hWYWx1ZShyZWdpc3Rlcikge1xuICAgICAgICByZXR1cm4gdGhpc1tSZWdpc3RlcltyZWdpc3Rlcl1dO1xuICAgIH1cbiAgICAvLyBMb2FkIGEgdmFsdWUgaW50byBhIHJlZ2lzdGVyXG4gICAgbG9hZFZhbHVlKHJlZ2lzdGVyLCB2YWx1ZSkge1xuICAgICAgICB0aGlzW1JlZ2lzdGVyW3JlZ2lzdGVyXV0gPSB2YWx1ZTtcbiAgICB9XG4gICAgLy8gU3RhcnQgYSBuZXcgZnJhbWUgYW5kIHNhdmUgJHJhIGFuZCAkZnAgb24gdGhlIHN0YWNrXG4gICAgcHVzaEZyYW1lKCkge1xuICAgICAgICB0aGlzLnN0YWNrLnB1c2godGhpcy5yYSk7XG4gICAgICAgIHRoaXMuc3RhY2sucHVzaCh0aGlzLmZwKTtcbiAgICAgICAgdGhpcy5mcCA9IHRoaXMuc3AgLSAxO1xuICAgIH1cbiAgICAvLyBSZXN0b3JlICRyYSwgJHNwIGFuZCAkZnBcbiAgICBwb3BGcmFtZSgpIHtcbiAgICAgICAgdGhpcy5zcCA9IHRoaXMuZnAgLSAxO1xuICAgICAgICB0aGlzLnJhID0gdGhpcy5zdGFjay5mcm9tQmFzZSgwKTtcbiAgICAgICAgdGhpcy5mcCA9IHRoaXMuc3RhY2suZnJvbUJhc2UoLTEpO1xuICAgIH1cbiAgICAvLyBKdW1wIHRvIGFuIGFkZHJlc3MgaW4gYHByb2dyYW1gXG4gICAgZ290byhvZmZzZXQpIHtcbiAgICAgICAgdGhpcy5wYyA9IHR5cGVQb3ModGhpcy5wYyArIG9mZnNldCk7XG4gICAgfVxuICAgIC8vIFNhdmUgJHBjIGludG8gJHJhLCB0aGVuIGp1bXAgdG8gYSBuZXcgYWRkcmVzcyBpbiBgcHJvZ3JhbWAgKGphbCBpbiBNSVBTKVxuICAgIGNhbGwoaGFuZGxlKSB7XG4gICAgICAgIGxldCBwYyA9IHRoaXMuaGVhcC5nZXRhZGRyKGhhbmRsZSk7XG4gICAgICAgIHRoaXMucmEgPSB0aGlzLnBjO1xuICAgICAgICB0aGlzLnBjID0gcGM7XG4gICAgfVxuICAgIC8vIFB1dCBhIHNwZWNpZmljIGBwcm9ncmFtYCBhZGRyZXNzIGluICRyYVxuICAgIHJldHVyblRvKG9mZnNldCkge1xuICAgICAgICB0aGlzLnJhID0gdHlwZVBvcyh0aGlzLnBjICsgb2Zmc2V0KTtcbiAgICB9XG4gICAgLy8gUmV0dXJuIHRvIHRoZSBgcHJvZ3JhbWAgYWRkcmVzcyBzdG9yZWQgaW4gJHJhXG4gICAgcmV0dXJuKCkge1xuICAgICAgICB0aGlzLnBjID0gdGhpcy5yYTtcbiAgICB9XG4gICAgc3RhdGljIGluaXRpYWwoZW52LCBzZWxmLCBkeW5hbWljU2NvcGUsIGVsZW1lbnRTdGFjaywgcHJvZ3JhbSkge1xuICAgICAgICBsZXQgc2NvcGUgPSBTY29wZS5yb290KHNlbGYsIHByb2dyYW0uc3ltYm9sVGFibGUuc3ltYm9scy5sZW5ndGgpO1xuICAgICAgICBsZXQgdm0gPSBuZXcgVk0oZW52LCBzY29wZSwgZHluYW1pY1Njb3BlLCBlbGVtZW50U3RhY2spO1xuICAgICAgICB2bS5wYyA9IHZtLmhlYXAuZ2V0YWRkcihwcm9ncmFtLmhhbmRsZSk7XG4gICAgICAgIHZtLnVwZGF0aW5nT3Bjb2RlU3RhY2sucHVzaChuZXcgTGlua2VkTGlzdCgpKTtcbiAgICAgICAgcmV0dXJuIHZtO1xuICAgIH1cbiAgICBjYXB0dXJlKGFyZ3MpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGR5bmFtaWNTY29wZTogdGhpcy5keW5hbWljU2NvcGUoKSxcbiAgICAgICAgICAgIGVudjogdGhpcy5lbnYsXG4gICAgICAgICAgICBzY29wZTogdGhpcy5zY29wZSgpLFxuICAgICAgICAgICAgc3RhY2s6IHRoaXMuc3RhY2suY2FwdHVyZShhcmdzKVxuICAgICAgICB9O1xuICAgIH1cbiAgICBiZWdpbkNhY2hlR3JvdXAoKSB7XG4gICAgICAgIHRoaXMuY2FjaGVHcm91cHMucHVzaCh0aGlzLnVwZGF0aW5nKCkudGFpbCgpKTtcbiAgICB9XG4gICAgY29tbWl0Q2FjaGVHcm91cCgpIHtcbiAgICAgICAgLy8gICAgICAgIEp1bXBJZk5vdE1vZGlmaWVkKEVORClcbiAgICAgICAgLy8gICAgICAgIChoZWFkKVxuICAgICAgICAvLyAgICAgICAgKC4uLi4pXG4gICAgICAgIC8vICAgICAgICAodGFpbClcbiAgICAgICAgLy8gICAgICAgIERpZE1vZGlmeVxuICAgICAgICAvLyBFTkQ6ICAgTm9vcFxuICAgICAgICBsZXQgRU5EID0gbmV3IExhYmVsT3Bjb2RlKFwiRU5EXCIpO1xuICAgICAgICBsZXQgb3Bjb2RlcyA9IHRoaXMudXBkYXRpbmcoKTtcbiAgICAgICAgbGV0IG1hcmtlciA9IHRoaXMuY2FjaGVHcm91cHMucG9wKCk7XG4gICAgICAgIGxldCBoZWFkID0gbWFya2VyID8gb3Bjb2Rlcy5uZXh0Tm9kZShtYXJrZXIpIDogb3Bjb2Rlcy5oZWFkKCk7XG4gICAgICAgIGxldCB0YWlsID0gb3Bjb2Rlcy50YWlsKCk7XG4gICAgICAgIGxldCB0YWcgPSBjb21iaW5lU2xpY2UobmV3IExpc3RTbGljZShoZWFkLCB0YWlsKSk7XG4gICAgICAgIGxldCBndWFyZCA9IG5ldyBKdW1wSWZOb3RNb2RpZmllZE9wY29kZSh0YWcsIEVORCk7XG4gICAgICAgIG9wY29kZXMuaW5zZXJ0QmVmb3JlKGd1YXJkLCBoZWFkKTtcbiAgICAgICAgb3Bjb2Rlcy5hcHBlbmQobmV3IERpZE1vZGlmeU9wY29kZShndWFyZCkpO1xuICAgICAgICBvcGNvZGVzLmFwcGVuZChFTkQpO1xuICAgIH1cbiAgICBlbnRlcihhcmdzKSB7XG4gICAgICAgIGxldCB1cGRhdGluZyA9IG5ldyBMaW5rZWRMaXN0KCk7XG4gICAgICAgIGxldCBzdGF0ZSA9IHRoaXMuY2FwdHVyZShhcmdzKTtcbiAgICAgICAgbGV0IHRyYWNrZXIgPSB0aGlzLmVsZW1lbnRzKCkucHVzaFVwZGF0YWJsZUJsb2NrKCk7XG4gICAgICAgIGxldCB0cnlPcGNvZGUgPSBuZXcgVHJ5T3Bjb2RlKHRoaXMuaGVhcC5nZXRoYW5kbGUodGhpcy5wYyksIHN0YXRlLCB0cmFja2VyLCB1cGRhdGluZyk7XG4gICAgICAgIHRoaXMuZGlkRW50ZXIodHJ5T3Bjb2RlKTtcbiAgICB9XG4gICAgaXRlcmF0ZShtZW1vLCB2YWx1ZSkge1xuICAgICAgICBsZXQgc3RhY2sgPSB0aGlzLnN0YWNrO1xuICAgICAgICBzdGFjay5wdXNoKHZhbHVlKTtcbiAgICAgICAgc3RhY2sucHVzaChtZW1vKTtcbiAgICAgICAgbGV0IHN0YXRlID0gdGhpcy5jYXB0dXJlKDIpO1xuICAgICAgICBsZXQgdHJhY2tlciA9IHRoaXMuZWxlbWVudHMoKS5wdXNoVXBkYXRhYmxlQmxvY2soKTtcbiAgICAgICAgLy8gbGV0IGlwID0gdGhpcy5pcDtcbiAgICAgICAgLy8gdGhpcy5pcCA9IGVuZCArIDQ7XG4gICAgICAgIC8vIHRoaXMuZnJhbWVzLnB1c2goaXApO1xuICAgICAgICByZXR1cm4gbmV3IFRyeU9wY29kZSh0aGlzLmhlYXAuZ2V0aGFuZGxlKHRoaXMucGMpLCBzdGF0ZSwgdHJhY2tlciwgbmV3IExpbmtlZExpc3QoKSk7XG4gICAgfVxuICAgIGVudGVySXRlbShrZXksIG9wY29kZSkge1xuICAgICAgICB0aGlzLmxpc3RCbG9jaygpLm1hcFtrZXldID0gb3Bjb2RlO1xuICAgICAgICB0aGlzLmRpZEVudGVyKG9wY29kZSk7XG4gICAgfVxuICAgIGVudGVyTGlzdChyZWxhdGl2ZVN0YXJ0KSB7XG4gICAgICAgIGxldCB1cGRhdGluZyA9IG5ldyBMaW5rZWRMaXN0KCk7XG4gICAgICAgIGxldCBzdGF0ZSA9IHRoaXMuY2FwdHVyZSgwKTtcbiAgICAgICAgbGV0IHRyYWNrZXIgPSB0aGlzLmVsZW1lbnRzKCkucHVzaEJsb2NrTGlzdCh1cGRhdGluZyk7XG4gICAgICAgIGxldCBhcnRpZmFjdHMgPSB0aGlzLnN0YWNrLnBlZWsoKS5hcnRpZmFjdHM7XG4gICAgICAgIGxldCBzdGFydCA9IHRoaXMuaGVhcC5nZXRoYW5kbGUodHlwZVBvcyh0aGlzLnBjICsgcmVsYXRpdmVTdGFydCkpO1xuICAgICAgICBsZXQgb3Bjb2RlID0gbmV3IExpc3RCbG9ja09wY29kZShzdGFydCwgc3RhdGUsIHRyYWNrZXIsIHVwZGF0aW5nLCBhcnRpZmFjdHMpO1xuICAgICAgICB0aGlzLmxpc3RCbG9ja1N0YWNrLnB1c2gob3Bjb2RlKTtcbiAgICAgICAgdGhpcy5kaWRFbnRlcihvcGNvZGUpO1xuICAgIH1cbiAgICBkaWRFbnRlcihvcGNvZGUpIHtcbiAgICAgICAgdGhpcy51cGRhdGVXaXRoKG9wY29kZSk7XG4gICAgICAgIHRoaXMudXBkYXRpbmdPcGNvZGVTdGFjay5wdXNoKG9wY29kZS5jaGlsZHJlbik7XG4gICAgfVxuICAgIGV4aXQoKSB7XG4gICAgICAgIHRoaXMuZWxlbWVudHMoKS5wb3BCbG9jaygpO1xuICAgICAgICB0aGlzLnVwZGF0aW5nT3Bjb2RlU3RhY2sucG9wKCk7XG4gICAgICAgIGxldCBwYXJlbnQgPSB0aGlzLnVwZGF0aW5nKCkudGFpbCgpO1xuICAgICAgICBwYXJlbnQuZGlkSW5pdGlhbGl6ZUNoaWxkcmVuKCk7XG4gICAgfVxuICAgIGV4aXRMaXN0KCkge1xuICAgICAgICB0aGlzLmV4aXQoKTtcbiAgICAgICAgdGhpcy5saXN0QmxvY2tTdGFjay5wb3AoKTtcbiAgICB9XG4gICAgdXBkYXRlV2l0aChvcGNvZGUpIHtcbiAgICAgICAgdGhpcy51cGRhdGluZygpLmFwcGVuZChvcGNvZGUpO1xuICAgIH1cbiAgICBsaXN0QmxvY2soKSB7XG4gICAgICAgIHJldHVybiBleHBlY3QodGhpcy5saXN0QmxvY2tTdGFjay5jdXJyZW50LCAnZXhwZWN0ZWQgYSBsaXN0IGJsb2NrJyk7XG4gICAgfVxuICAgIHVwZGF0aW5nKCkge1xuICAgICAgICByZXR1cm4gZXhwZWN0KHRoaXMudXBkYXRpbmdPcGNvZGVTdGFjay5jdXJyZW50LCAnZXhwZWN0ZWQgdXBkYXRpbmcgb3Bjb2RlIG9uIHRoZSB1cGRhdGluZyBvcGNvZGUgc3RhY2snKTtcbiAgICB9XG4gICAgZWxlbWVudHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnRTdGFjaztcbiAgICB9XG4gICAgc2NvcGUoKSB7XG4gICAgICAgIHJldHVybiBleHBlY3QodGhpcy5zY29wZVN0YWNrLmN1cnJlbnQsICdleHBlY3RlZCBzY29wZSBvbiB0aGUgc2NvcGUgc3RhY2snKTtcbiAgICB9XG4gICAgZHluYW1pY1Njb3BlKCkge1xuICAgICAgICByZXR1cm4gZXhwZWN0KHRoaXMuZHluYW1pY1Njb3BlU3RhY2suY3VycmVudCwgJ2V4cGVjdGVkIGR5bmFtaWMgc2NvcGUgb24gdGhlIGR5bmFtaWMgc2NvcGUgc3RhY2snKTtcbiAgICB9XG4gICAgcHVzaENoaWxkU2NvcGUoKSB7XG4gICAgICAgIHRoaXMuc2NvcGVTdGFjay5wdXNoKHRoaXMuc2NvcGUoKS5jaGlsZCgpKTtcbiAgICB9XG4gICAgcHVzaENhbGxlclNjb3BlKGNoaWxkU2NvcGUgPSBmYWxzZSkge1xuICAgICAgICBsZXQgY2FsbGVyU2NvcGUgPSBleHBlY3QodGhpcy5zY29wZSgpLmdldENhbGxlclNjb3BlKCksICdwdXNoQ2FsbGVyU2NvcGUgaXMgY2FsbGVkIHdoZW4gYSBjYWxsZXIgc2NvcGUgaXMgcHJlc2VudCcpO1xuICAgICAgICB0aGlzLnNjb3BlU3RhY2sucHVzaChjaGlsZFNjb3BlID8gY2FsbGVyU2NvcGUuY2hpbGQoKSA6IGNhbGxlclNjb3BlKTtcbiAgICB9XG4gICAgcHVzaER5bmFtaWNTY29wZSgpIHtcbiAgICAgICAgbGV0IGNoaWxkID0gdGhpcy5keW5hbWljU2NvcGUoKS5jaGlsZCgpO1xuICAgICAgICB0aGlzLmR5bmFtaWNTY29wZVN0YWNrLnB1c2goY2hpbGQpO1xuICAgICAgICByZXR1cm4gY2hpbGQ7XG4gICAgfVxuICAgIHB1c2hSb290U2NvcGUoc2l6ZSwgYmluZENhbGxlcikge1xuICAgICAgICBsZXQgc2NvcGUgPSBTY29wZS5zaXplZChzaXplKTtcbiAgICAgICAgaWYgKGJpbmRDYWxsZXIpIHNjb3BlLmJpbmRDYWxsZXJTY29wZSh0aGlzLnNjb3BlKCkpO1xuICAgICAgICB0aGlzLnNjb3BlU3RhY2sucHVzaChzY29wZSk7XG4gICAgICAgIHJldHVybiBzY29wZTtcbiAgICB9XG4gICAgcG9wU2NvcGUoKSB7XG4gICAgICAgIHRoaXMuc2NvcGVTdGFjay5wb3AoKTtcbiAgICB9XG4gICAgcG9wRHluYW1pY1Njb3BlKCkge1xuICAgICAgICB0aGlzLmR5bmFtaWNTY29wZVN0YWNrLnBvcCgpO1xuICAgIH1cbiAgICBuZXdEZXN0cm95YWJsZShkKSB7XG4gICAgICAgIHRoaXMuZWxlbWVudHMoKS5uZXdEZXN0cm95YWJsZShkKTtcbiAgICB9XG4gICAgLy8vIFNDT1BFIEhFTFBFUlNcbiAgICBnZXRTZWxmKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zY29wZSgpLmdldFNlbGYoKTtcbiAgICB9XG4gICAgcmVmZXJlbmNlRm9yU3ltYm9sKHN5bWJvbCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zY29wZSgpLmdldFN5bWJvbChzeW1ib2wpO1xuICAgIH1cbiAgICAvLy8gRVhFQ1VUSU9OXG4gICAgZXhlY3V0ZShzdGFydCwgaW5pdGlhbGl6ZSkge1xuICAgICAgICB0aGlzLnBjID0gdGhpcy5oZWFwLmdldGFkZHIoc3RhcnQpO1xuICAgICAgICBpZiAoaW5pdGlhbGl6ZSkgaW5pdGlhbGl6ZSh0aGlzKTtcbiAgICAgICAgbGV0IHJlc3VsdDtcbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgIHJlc3VsdCA9IHRoaXMubmV4dCgpO1xuICAgICAgICAgICAgaWYgKHJlc3VsdC5kb25lKSBicmVhaztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0LnZhbHVlO1xuICAgIH1cbiAgICBuZXh0KCkge1xuICAgICAgICBsZXQgeyBlbnYsIHVwZGF0aW5nT3Bjb2RlU3RhY2ssIGVsZW1lbnRTdGFjayB9ID0gdGhpcztcbiAgICAgICAgbGV0IG9wY29kZSA9IHRoaXMubmV4dFN0YXRlbWVudChlbnYpO1xuICAgICAgICBsZXQgcmVzdWx0O1xuICAgICAgICBpZiAob3Bjb2RlICE9PSBudWxsKSB7XG4gICAgICAgICAgICBBUFBFTkRfT1BDT0RFUy5ldmFsdWF0ZSh0aGlzLCBvcGNvZGUsIG9wY29kZS50eXBlKTtcbiAgICAgICAgICAgIHJlc3VsdCA9IHsgZG9uZTogZmFsc2UsIHZhbHVlOiBudWxsIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBVbmxvYWQgdGhlIHN0YWNrXG4gICAgICAgICAgICB0aGlzLnN0YWNrLnJlc2V0KCk7XG4gICAgICAgICAgICByZXN1bHQgPSB7XG4gICAgICAgICAgICAgICAgZG9uZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogbmV3IFJlbmRlclJlc3VsdChlbnYsIGV4cGVjdCh1cGRhdGluZ09wY29kZVN0YWNrLnBvcCgpLCAndGhlcmUgc2hvdWxkIGJlIGEgZmluYWwgdXBkYXRpbmcgb3Bjb2RlIHN0YWNrJyksIGVsZW1lbnRTdGFjay5wb3BCbG9jaygpKVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICBuZXh0U3RhdGVtZW50KGVudikge1xuICAgICAgICBsZXQgeyBwYyB9ID0gdGhpcztcbiAgICAgICAgaWYgKHBjID09PSAtMSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHByb2dyYW0gPSBlbnYucHJvZ3JhbTtcbiAgICAgICAgdGhpcy5wYyArPSA0O1xuICAgICAgICByZXR1cm4gcHJvZ3JhbS5vcGNvZGUocGMpO1xuICAgIH1cbiAgICBldmFsdWF0ZU9wY29kZShvcGNvZGUpIHtcbiAgICAgICAgQVBQRU5EX09QQ09ERVMuZXZhbHVhdGUodGhpcywgb3Bjb2RlLCBvcGNvZGUudHlwZSk7XG4gICAgfVxuICAgIGJpbmREeW5hbWljU2NvcGUobmFtZXMpIHtcbiAgICAgICAgbGV0IHNjb3BlID0gdGhpcy5keW5hbWljU2NvcGUoKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IG5hbWVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICBsZXQgbmFtZSA9IHRoaXMuY29uc3RhbnRzLmdldFN0cmluZyhuYW1lc1tpXSk7XG4gICAgICAgICAgICBzY29wZS5zZXQobmFtZSwgdGhpcy5zdGFjay5wb3AoKSk7XG4gICAgICAgIH1cbiAgICB9XG59Il19