ember-legacy-class-transform
Version:
The default blueprint for ember-cli addons.
342 lines (331 loc) • 38.5 kB
JavaScript
'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