UNPKG

ember-legacy-class-transform

Version:
354 lines (347 loc) 39.1 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.Environment = exports.Program = exports.Heap = exports.Opcode = exports.Scope = undefined; var _functions = require('./syntax/functions'); var _constants = require('./environment/constants'); var _references = require('./references'); var _attributeManagers = require('./dom/attribute-managers'); var _util = require('@glimmer/util'); class Scope { constructor( // the 0th slot is `self` slots, callerScope, // named arguments and blocks passed to a layout that uses eval evalScope, // locals in scope when the partial was invoked partialMap) { this.slots = slots; this.callerScope = callerScope; this.evalScope = evalScope; this.partialMap = partialMap; } static root(self, size = 0) { let refs = new Array(size + 1); for (let i = 0; i <= size; i++) { refs[i] = _references.UNDEFINED_REFERENCE; } return new Scope(refs, null, null, null).init({ self }); } static sized(size = 0) { let refs = new Array(size + 1); for (let i = 0; i <= size; i++) { refs[i] = _references.UNDEFINED_REFERENCE; } return new Scope(refs, null, null, null); } init({ self }) { this.slots[0] = self; return this; } getSelf() { return this.get(0); } getSymbol(symbol) { return this.get(symbol); } getBlock(symbol) { return this.get(symbol); } getEvalScope() { return this.evalScope; } getPartialMap() { return this.partialMap; } bind(symbol, value) { this.set(symbol, value); } bindSelf(self) { this.set(0, self); } bindSymbol(symbol, value) { this.set(symbol, value); } bindBlock(symbol, value) { this.set(symbol, value); } bindEvalScope(map) { this.evalScope = map; } bindPartialMap(map) { this.partialMap = map; } bindCallerScope(scope) { this.callerScope = scope; } getCallerScope() { return this.callerScope; } child() { return new Scope(this.slots.slice(), this.callerScope, this.evalScope, this.partialMap); } get(index) { if (index >= this.slots.length) { throw new RangeError(`BUG: cannot get $${index} from scope; length=${this.slots.length}`); } return this.slots[index]; } set(index, value) { if (index >= this.slots.length) { throw new RangeError(`BUG: cannot get $${index} from scope; length=${this.slots.length}`); } this.slots[index] = value; } } exports.Scope = Scope; class Transaction { constructor() { this.scheduledInstallManagers = []; this.scheduledInstallModifiers = []; this.scheduledUpdateModifierManagers = []; this.scheduledUpdateModifiers = []; this.createdComponents = []; this.createdManagers = []; this.updatedComponents = []; this.updatedManagers = []; this.destructors = []; } didCreate(component, manager) { this.createdComponents.push(component); this.createdManagers.push(manager); } didUpdate(component, manager) { this.updatedComponents.push(component); this.updatedManagers.push(manager); } scheduleInstallModifier(modifier, manager) { this.scheduledInstallManagers.push(manager); this.scheduledInstallModifiers.push(modifier); } scheduleUpdateModifier(modifier, manager) { this.scheduledUpdateModifierManagers.push(manager); this.scheduledUpdateModifiers.push(modifier); } didDestroy(d) { this.destructors.push(d); } commit() { let { createdComponents, createdManagers } = this; for (let i = 0; i < createdComponents.length; i++) { let component = createdComponents[i]; let manager = createdManagers[i]; manager.didCreate(component); } let { updatedComponents, updatedManagers } = this; for (let i = 0; i < updatedComponents.length; i++) { let component = updatedComponents[i]; let manager = updatedManagers[i]; manager.didUpdate(component); } let { destructors } = this; for (let i = 0; i < destructors.length; i++) { destructors[i].destroy(); } let { scheduledInstallManagers, scheduledInstallModifiers } = this; for (let i = 0; i < scheduledInstallManagers.length; i++) { let manager = scheduledInstallManagers[i]; let modifier = scheduledInstallModifiers[i]; manager.install(modifier); } let { scheduledUpdateModifierManagers, scheduledUpdateModifiers } = this; for (let i = 0; i < scheduledUpdateModifierManagers.length; i++) { let manager = scheduledUpdateModifierManagers[i]; let modifier = scheduledUpdateModifiers[i]; manager.update(modifier); } } } class Opcode { constructor(heap) { this.heap = heap; this.offset = 0; } get type() { return this.heap.getbyaddr(this.offset); } get op1() { return this.heap.getbyaddr(this.offset + 1); } get op2() { return this.heap.getbyaddr(this.offset + 2); } get op3() { return this.heap.getbyaddr(this.offset + 3); } } exports.Opcode = Opcode; var TableSlotState; (function (TableSlotState) { TableSlotState[TableSlotState["Allocated"] = 0] = "Allocated"; TableSlotState[TableSlotState["Freed"] = 1] = "Freed"; TableSlotState[TableSlotState["Purged"] = 2] = "Purged"; TableSlotState[TableSlotState["Pointer"] = 3] = "Pointer"; })(TableSlotState || (TableSlotState = {})); class Heap { constructor() { this.heap = []; this.offset = 0; this.handle = 0; /** * layout: * * - pointer into heap * - size * - freed (0 or 1) */ this.table = []; } push(item) { this.heap[this.offset++] = item; } getbyaddr(address) { return this.heap[address]; } setbyaddr(address, value) { this.heap[address] = value; } malloc() { this.table.push(this.offset, 0, 0); let handle = this.handle; this.handle += 3; return handle; } finishMalloc(handle) { let start = this.table[handle]; let finish = this.offset; this.table[handle + 1] = finish - start; } size() { return this.offset; } // It is illegal to close over this address, as compaction // may move it. However, it is legal to use this address // multiple times between compactions. getaddr(handle) { return this.table[handle]; } gethandle(address) { this.table.push(address, 0, TableSlotState.Pointer); let handle = this.handle; this.handle += 3; return handle; } sizeof(handle) { if (false) { return this.table[handle + 1]; } return -1; } free(handle) { this.table[handle + 2] = 1; } compact() { let compactedSize = 0; let { table, table: { length }, heap } = this; for (let i = 0; i < length; i += 3) { let offset = table[i]; let size = table[i + 1]; let state = table[i + 2]; if (state === TableSlotState.Purged) { continue; } else if (state === TableSlotState.Freed) { // transition to "already freed" // a good improvement would be to reuse // these slots table[i + 2] = 2; compactedSize += size; } else if (state === TableSlotState.Allocated) { for (let j = offset; j <= i + size; j++) { heap[j - compactedSize] = heap[j]; } table[i] = offset - compactedSize; } else if (state === TableSlotState.Pointer) { table[i] = offset - compactedSize; } } this.offset = this.offset - compactedSize; } } exports.Heap = Heap; class Program { constructor() { this.heap = new Heap(); this._opcode = new Opcode(this.heap); this.constants = new _constants.Constants(); } opcode(offset) { this._opcode.offset = offset; return this._opcode; } } exports.Program = Program; class Environment { constructor({ appendOperations, updateOperations }) { this._macros = null; this._transaction = null; this.program = new Program(); this.appendOperations = appendOperations; this.updateOperations = updateOperations; } toConditionalReference(reference) { return new _references.ConditionalReference(reference); } getAppendOperations() { return this.appendOperations; } getDOM() { return this.updateOperations; } getIdentity(object) { return (0, _util.ensureGuid)(object) + ''; } begin() { (0, _util.assert)(!this._transaction, 'a glimmer transaction was begun, but one already exists. You may have a nested transaction'); this._transaction = new Transaction(); } get transaction() { return (0, _util.expect)(this._transaction, 'must be in a transaction'); } didCreate(component, manager) { this.transaction.didCreate(component, manager); } didUpdate(component, manager) { this.transaction.didUpdate(component, manager); } scheduleInstallModifier(modifier, manager) { this.transaction.scheduleInstallModifier(modifier, manager); } scheduleUpdateModifier(modifier, manager) { this.transaction.scheduleUpdateModifier(modifier, manager); } didDestroy(d) { this.transaction.didDestroy(d); } commit() { let transaction = this.transaction; this._transaction = null; transaction.commit(); } attributeFor(element, attr, isTrusting, namespace) { return (0, _attributeManagers.defaultManagers)(element, attr, isTrusting, namespace === undefined ? null : namespace); } macros() { let macros = this._macros; if (!macros) { this._macros = macros = this.populateBuiltins(); } return macros; } populateBuiltins() { return (0, _functions.populateBuiltins)(); } } exports.Environment = Environment; exports.default = Environment; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9lbnZpcm9ubWVudC5qcyJdLCJuYW1lcyI6WyJTY29wZSIsImNvbnN0cnVjdG9yIiwic2xvdHMiLCJjYWxsZXJTY29wZSIsImV2YWxTY29wZSIsInBhcnRpYWxNYXAiLCJyb290Iiwic2VsZiIsInNpemUiLCJyZWZzIiwiQXJyYXkiLCJpIiwiaW5pdCIsInNpemVkIiwiZ2V0U2VsZiIsImdldCIsImdldFN5bWJvbCIsInN5bWJvbCIsImdldEJsb2NrIiwiZ2V0RXZhbFNjb3BlIiwiZ2V0UGFydGlhbE1hcCIsImJpbmQiLCJ2YWx1ZSIsInNldCIsImJpbmRTZWxmIiwiYmluZFN5bWJvbCIsImJpbmRCbG9jayIsImJpbmRFdmFsU2NvcGUiLCJtYXAiLCJiaW5kUGFydGlhbE1hcCIsImJpbmRDYWxsZXJTY29wZSIsInNjb3BlIiwiZ2V0Q2FsbGVyU2NvcGUiLCJjaGlsZCIsInNsaWNlIiwiaW5kZXgiLCJsZW5ndGgiLCJSYW5nZUVycm9yIiwiVHJhbnNhY3Rpb24iLCJzY2hlZHVsZWRJbnN0YWxsTWFuYWdlcnMiLCJzY2hlZHVsZWRJbnN0YWxsTW9kaWZpZXJzIiwic2NoZWR1bGVkVXBkYXRlTW9kaWZpZXJNYW5hZ2VycyIsInNjaGVkdWxlZFVwZGF0ZU1vZGlmaWVycyIsImNyZWF0ZWRDb21wb25lbnRzIiwiY3JlYXRlZE1hbmFnZXJzIiwidXBkYXRlZENvbXBvbmVudHMiLCJ1cGRhdGVkTWFuYWdlcnMiLCJkZXN0cnVjdG9ycyIsImRpZENyZWF0ZSIsImNvbXBvbmVudCIsIm1hbmFnZXIiLCJwdXNoIiwiZGlkVXBkYXRlIiwic2NoZWR1bGVJbnN0YWxsTW9kaWZpZXIiLCJtb2RpZmllciIsInNjaGVkdWxlVXBkYXRlTW9kaWZpZXIiLCJkaWREZXN0cm95IiwiZCIsImNvbW1pdCIsImRlc3Ryb3kiLCJpbnN0YWxsIiwidXBkYXRlIiwiT3Bjb2RlIiwiaGVhcCIsIm9mZnNldCIsInR5cGUiLCJnZXRieWFkZHIiLCJvcDEiLCJvcDIiLCJvcDMiLCJUYWJsZVNsb3RTdGF0ZSIsIkhlYXAiLCJoYW5kbGUiLCJ0YWJsZSIsIml0ZW0iLCJhZGRyZXNzIiwic2V0YnlhZGRyIiwibWFsbG9jIiwiZmluaXNoTWFsbG9jIiwic3RhcnQiLCJmaW5pc2giLCJnZXRhZGRyIiwiZ2V0aGFuZGxlIiwiUG9pbnRlciIsInNpemVvZiIsImZyZWUiLCJjb21wYWN0IiwiY29tcGFjdGVkU2l6ZSIsInN0YXRlIiwiUHVyZ2VkIiwiRnJlZWQiLCJBbGxvY2F0ZWQiLCJqIiwiUHJvZ3JhbSIsIl9vcGNvZGUiLCJjb25zdGFudHMiLCJvcGNvZGUiLCJFbnZpcm9ubWVudCIsImFwcGVuZE9wZXJhdGlvbnMiLCJ1cGRhdGVPcGVyYXRpb25zIiwiX21hY3JvcyIsIl90cmFuc2FjdGlvbiIsInByb2dyYW0iLCJ0b0NvbmRpdGlvbmFsUmVmZXJlbmNlIiwicmVmZXJlbmNlIiwiZ2V0QXBwZW5kT3BlcmF0aW9ucyIsImdldERPTSIsImdldElkZW50aXR5Iiwib2JqZWN0IiwiYmVnaW4iLCJ0cmFuc2FjdGlvbiIsImF0dHJpYnV0ZUZvciIsImVsZW1lbnQiLCJhdHRyIiwiaXNUcnVzdGluZyIsIm5hbWVzcGFjZSIsInVuZGVmaW5lZCIsIm1hY3JvcyIsInBvcHVsYXRlQnVpbHRpbnMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFFTyxNQUFNQSxLQUFOLENBQVk7QUFDZkM7QUFDQTtBQUNBQyxTQUZBLEVBRU9DLFdBRlA7QUFHQTtBQUNBQyxhQUpBO0FBS0E7QUFDQUMsY0FOQSxFQU1ZO0FBQ1IsYUFBS0gsS0FBTCxHQUFhQSxLQUFiO0FBQ0EsYUFBS0MsV0FBTCxHQUFtQkEsV0FBbkI7QUFDQSxhQUFLQyxTQUFMLEdBQWlCQSxTQUFqQjtBQUNBLGFBQUtDLFVBQUwsR0FBa0JBLFVBQWxCO0FBQ0g7QUFDRCxXQUFPQyxJQUFQLENBQVlDLElBQVosRUFBa0JDLE9BQU8sQ0FBekIsRUFBNEI7QUFDeEIsWUFBSUMsT0FBTyxJQUFJQyxLQUFKLENB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O0FBQ0RDLGFBQVM7QUFDTCxZQUFJb0QsY0FBYyxLQUFLQSxXQUF2QjtBQUNBLGFBQUtULFlBQUwsR0FBb0IsSUFBcEI7QUFDQVMsb0JBQVlwRCxNQUFaO0FBQ0g7QUFDRHFELGlCQUFhQyxPQUFiLEVBQXNCQyxJQUF0QixFQUE0QkMsVUFBNUIsRUFBd0NDLFNBQXhDLEVBQW1EO0FBQy9DLGVBQU8sd0NBQWdCSCxPQUFoQixFQUF5QkMsSUFBekIsRUFBK0JDLFVBQS9CLEVBQTJDQyxjQUFjQyxTQUFkLEdBQTBCLElBQTFCLEdBQWlDRCxTQUE1RSxDQUFQO0FBQ0g7QUFDREUsYUFBUztBQUNMLFlBQUlBLFNBQVMsS0FBS2pCLE9BQWxCO0FBQ0EsWUFBSSxDQUFDaUIsTUFBTCxFQUFhO0FBQ1QsaUJBQUtqQixPQUFMLEdBQWVpQixTQUFTLEtBQUtDLGdCQUFMLEVBQXhCO0FBQ0g7QUFDRCxlQUFPRCxNQUFQO0FBQ0g7QUFDREMsdUJBQW1CO0FBQ2YsZUFBTyxrQ0FBUDtBQUNIO0FBM0RvQjtRQUFackIsVyxHQUFBQSxXO2tCQTZERUEsVyIsImZpbGUiOiJsaWIvZW52aXJvbm1lbnQuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBwb3B1bGF0ZUJ1aWx0aW5zIH0gZnJvbSAnLi9zeW50YXgvZnVuY3Rpb25zJztcbmltcG9ydCB7IENvbnN0YW50cyB9IGZyb20gJy4vZW52aXJvbm1lbnQvY29uc3RhbnRzJztcbmltcG9ydCB7IFVOREVGSU5FRF9SRUZFUkVOQ0UsIENvbmRpdGlvbmFsUmVmZXJlbmNlIH0gZnJvbSAnLi9yZWZlcmVuY2VzJztcbmltcG9ydCB7IGRlZmF1bHRNYW5hZ2VycyB9IGZyb20gJy4vZG9tL2F0dHJpYnV0ZS1tYW5hZ2Vycyc7XG5pbXBvcnQgeyBhc3NlcnQsIGVuc3VyZUd1aWQsIGV4cGVjdCB9IGZyb20gJ0BnbGltbWVyL3V0aWwnO1xuXG5leHBvcnQgY2xhc3MgU2NvcGUge1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8vIHRoZSAwdGggc2xvdCBpcyBgc2VsZmBcbiAgICBzbG90cywgY2FsbGVyU2NvcGUsXG4gICAgLy8gbmFtZWQgYXJndW1lbnRzIGFuZCBibG9ja3MgcGFzc2VkIHRvIGEgbGF5b3V0IHRoYXQgdXNlcyBldmFsXG4gICAgZXZhbFNjb3BlLFxuICAgIC8vIGxvY2FscyBpbiBzY29wZSB3aGVuIHRoZSBwYXJ0aWFsIHdhcyBpbnZva2VkXG4gICAgcGFydGlhbE1hcCkge1xuICAgICAgICB0aGlzLnNsb3RzID0gc2xvdHM7XG4gICAgICAgIHRoaXMuY2FsbGVyU2NvcGUgPSBjYWxsZXJTY29wZTtcbiAgICAgICAgdGhpcy5ldmFsU2NvcGUgPSBldmFsU2NvcGU7XG4gICAgICAgIHRoaXMucGFydGlhbE1hcCA9IHBhcnRpYWxNYXA7XG4gICAgfVxuICAgIHN0YXRpYyByb290KHNlbGYsIHNpemUgPSAwKSB7XG4gICAgICAgIGxldCByZWZzID0gbmV3IEFycmF5KHNpemUgKyAxKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPD0gc2l6ZTsgaSsrKSB7XG4gICAgICAgICAgICByZWZzW2ldID0gVU5ERUZJTkVEX1JFRkVSRU5DRTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFNjb3BlKHJlZnMsIG51bGwsIG51bGwsIG51bGwpLmluaXQoeyBzZWxmIH0pO1xuICAgIH1cbiAgICBzdGF0aWMgc2l6ZWQoc2l6ZSA9IDApIHtcbiAgICAgICAgbGV0IHJlZnMgPSBuZXcgQXJyYXkoc2l6ZSArIDEpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8PSBzaXplOyBpKyspIHtcbiAgICAgICAgICAgIHJlZnNbaV0gPSBVTkRFRklORURfUkVGRVJFTkNFO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgU2NvcGUocmVmcywgbnVsbCwgbnVsbCwgbnVsbCk7XG4gICAgfVxuICAgIGluaXQoeyBzZWxmIH0pIHtcbiAgICAgICAgdGhpcy5zbG90c1swXSA9IHNlbGY7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBnZXRTZWxmKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXQoMCk7XG4gICAgfVxuICAgIGdldFN5bWJvbChzeW1ib2wpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0KHN5bWJvbCk7XG4gICAgfVxuICAgIGdldEJsb2NrKHN5bWJvbCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXQoc3ltYm9sKTtcbiAgICB9XG4gICAgZ2V0RXZhbFNjb3BlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ldmFsU2NvcGU7XG4gICAgfVxuICAgIGdldFBhcnRpYWxNYXAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBhcnRpYWxNYXA7XG4gICAgfVxuICAgIGJpbmQoc3ltYm9sLCB2YWx1ZSkge1xuICAgICAgICB0aGlzLnNldChzeW1ib2wsIHZhbHVlKTtcbiAgICB9XG4gICAgYmluZFNlbGYoc2VsZikge1xuICAgICAgICB0aGlzLnNldCgwLCBzZWxmKTtcbiAgICB9XG4gICAgYmluZFN5bWJvbChzeW1ib2wsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMuc2V0KHN5bWJvbCwgdmFsdWUpO1xuICAgIH1cbiAgICBiaW5kQmxvY2soc3ltYm9sLCB2YWx1ZSkge1xuICAgICAgICB0aGlzLnNldChzeW1ib2wsIHZhbHVlKTtcbiAgICB9XG4gICAgYmluZEV2YWxTY29wZShtYXApIHtcbiAgICAgICAgdGhpcy5ldmFsU2NvcGUgPSBtYXA7XG4gICAgfVxuICAgIGJpbmRQYXJ0aWFsTWFwKG1hcCkge1xuICAgICAgICB0aGlzLnBhcnRpYWxNYXAgPSBtYXA7XG4gICAgfVxuICAgIGJpbmRDYWxsZXJTY29wZShzY29wZSkge1xuICAgICAgICB0aGlzLmNhbGxlclNjb3BlID0gc2NvcGU7XG4gICAgfVxuICAgIGdldENhbGxlclNjb3BlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jYWxsZXJTY29wZTtcbiAgICB9XG4gICAgY2hpbGQoKSB7XG4gICAgICAgIHJldHVybiBuZXcgU2NvcGUodGhpcy5zbG90cy5zbGljZSgpLCB0aGlzLmNhbGxlclNjb3BlLCB0aGlzLmV2YWxTY29wZSwgdGhpcy5wYXJ0aWFsTWFwKTtcbiAgICB9XG4gICAgZ2V0KGluZGV4KSB7XG4gICAgICAgIGlmIChpbmRleCA+PSB0aGlzLnNsb3RzLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoYEJVRzogY2Fubm90IGdldCAkJHtpbmRleH0gZnJvbSBzY29wZTsgbGVuZ3RoPSR7dGhpcy5zbG90cy5sZW5ndGh9YCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuc2xvdHNbaW5kZXhdO1xuICAgIH1cbiAgICBzZXQoaW5kZXgsIHZhbHVlKSB7XG4gICAgICAgIGlmIChpbmRleCA+PSB0aGlzLnNsb3RzLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoYEJVRzogY2Fubm90IGdldCAkJHtpbmRleH0gZnJvbSBzY29wZTsgbGVuZ3RoPSR7dGhpcy5zbG90cy5sZW5ndGh9YCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zbG90c1tpbmRleF0gPSB2YWx1ZTtcbiAgICB9XG59XG5jbGFzcyBUcmFuc2FjdGlvbiB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuc2NoZWR1bGVkSW5zdGFsbE1hbmFnZXJzID0gW107XG4gICAgICAgIHRoaXMuc2NoZWR1bGVkSW5zdGFsbE1vZGlmaWVycyA9IFtdO1xuICAgICAgICB0aGlzLnNjaGVkdWxlZFVwZGF0ZU1vZGlmaWVyTWFuYWdlcnMgPSBbXTtcbiAgICAgICAgdGhpcy5zY2hlZHVsZWRVcGRhdGVNb2RpZmllcnMgPSBbXTtcbiAgICAgICAgdGhpcy5jcmVhdGVkQ29tcG9uZW50cyA9IFtdO1xuICAgICAgICB0aGlzLmNyZWF0ZWRNYW5hZ2VycyA9IFtdO1xuICAgICAgICB0aGlzLnVwZGF0ZWRDb21wb25lbnRzID0gW107XG4gICAgICAgIHRoaXMudXBkYXRlZE1hbmFnZXJzID0gW107XG4gICAgICAgIHRoaXMuZGVzdHJ1Y3RvcnMgPSBbXTtcbiAgICB9XG4gICAgZGlkQ3JlYXRlKGNvbXBvbmVudCwgbWFuYWdlcikge1xuICAgICAgICB0aGlzLmNyZWF0ZWRDb21wb25lbnRzLnB1c2goY29tcG9uZW50KTtcbiAgICAgICAgdGhpcy5jcmVhdGVkTWFuYWdlcnMucHVzaChtYW5hZ2VyKTtcbiAgICB9XG4gICAgZGlkVXBkYXRlKGNvbXBvbmVudCwgbWFuYWdlcikge1xuICAgICAgICB0aGlzLnVwZGF0ZWRDb21wb25lbnRzLnB1c2goY29tcG9uZW50KTtcbiAgICAgICAgdGhpcy51cGRhdGVkTWFuYWdlcnMucHVzaChtYW5hZ2VyKTtcbiAgICB9XG4gICAgc2NoZWR1bGVJbnN0YWxsTW9kaWZpZXIobW9kaWZpZXIsIG1hbmFnZXIpIHtcbiAgICAgICAgdGhpcy5zY2hlZHVsZWRJbnN0YWxsTWFuYWdlcnMucHVzaChtYW5hZ2VyKTtcbiAgICAgICAgdGhpcy5zY2hlZHVsZWRJbnN0YWxsTW9kaWZpZXJzLnB1c2gobW9kaWZpZXIpO1xuICAgIH1cbiAgICBzY2hlZHVsZVVwZGF0ZU1vZGlmaWVyKG1vZGlmaWVyLCBtYW5hZ2VyKSB7XG4gICAgICAgIHRoaXMuc2NoZWR1bGVkVXBkYXRlTW9kaWZpZXJNYW5hZ2Vycy5wdXNoKG1hbmFnZXIpO1xuICAgICAgICB0aGlzLnNjaGVkdWxlZFVwZGF0ZU1vZGlmaWVycy5wdXNoKG1vZGlmaWVyKTtcbiAgICB9XG4gICAgZGlkRGVzdHJveShkKSB7XG4gICAgICAgIHRoaXMuZGVzdHJ1Y3RvcnMucHVzaChkKTtcbiAgICB9XG4gICAgY29tbWl0KCkge1xuICAgICAgICBsZXQgeyBjcmVhdGVkQ29tcG9uZW50cywgY3JlYXRlZE1hbmFnZXJzIH0gPSB0aGlzO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNyZWF0ZWRDb21wb25lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgY29tcG9uZW50ID0gY3JlYXRlZENvbXBvbmVudHNbaV07XG4gICAgICAgICAgICBsZXQgbWFuYWdlciA9IGNyZWF0ZWRNYW5hZ2Vyc1tpXTtcbiAgICAgICAgICAgIG1hbmFnZXIuZGlkQ3JlYXRlKGNvbXBvbmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHsgdXBkYXRlZENvbXBvbmVudHMsIHVwZGF0ZWRNYW5hZ2VycyB9ID0gdGhpcztcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB1cGRhdGVkQ29tcG9uZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IGNvbXBvbmVudCA9IHVwZGF0ZWRDb21wb25lbnRzW2ldO1xuICAgICAgICAgICAgbGV0IG1hbmFnZXIgPSB1cGRhdGVkTWFuYWdlcnNbaV07XG4gICAgICAgICAgICBtYW5hZ2VyLmRpZFVwZGF0ZShjb21wb25lbnQpO1xuICAgICAgICB9XG4gICAgICAgIGxldCB7IGRlc3RydWN0b3JzIH0gPSB0aGlzO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRlc3RydWN0b3JzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBkZXN0cnVjdG9yc1tpXS5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHsgc2NoZWR1bGVkSW5zdGFsbE1hbmFnZXJzLCBzY2hlZHVsZWRJbnN0YWxsTW9kaWZpZXJzIH0gPSB0aGlzO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNjaGVkdWxlZEluc3RhbGxNYW5hZ2Vycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IG1hbmFnZXIgPSBzY2hlZHVsZWRJbnN0YWxsTWFuYWdlcnNbaV07XG4gICAgICAgICAgICBsZXQgbW9kaWZpZXIgPSBzY2hlZHVsZWRJbnN0YWxsTW9kaWZpZXJzW2ldO1xuICAgICAgICAgICAgbWFuYWdlci5pbnN0YWxsKG1vZGlmaWVyKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgeyBzY2hlZHVsZWRVcGRhdGVNb2RpZmllck1hbmFnZXJzLCBzY2hlZHVsZWRVcGRhdGVNb2RpZmllcnMgfSA9IHRoaXM7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2NoZWR1bGVkVXBkYXRlTW9kaWZpZXJNYW5hZ2Vycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IG1hbmFnZXIgPSBzY2hlZHVsZWRVcGRhdGVNb2RpZmllck1hbmFnZXJzW2ldO1xuICAgICAgICAgICAgbGV0IG1vZGlmaWVyID0gc2NoZWR1bGVkVXBkYXRlTW9kaWZpZXJzW2ldO1xuICAgICAgICAgICAgbWFuYWdlci51cGRhdGUobW9kaWZpZXIpO1xuICAgICAgICB9XG4gICAgfVxufVxuZXhwb3J0IGNsYXNzIE9wY29kZSB7XG4gICAgY29uc3RydWN0b3IoaGVhcCkge1xuICAgICAgICB0aGlzLmhlYXAgPSBoZWFwO1xuICAgICAgICB0aGlzLm9mZnNldCA9IDA7XG4gICAgfVxuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5oZWFwLmdldGJ5YWRkcih0aGlzLm9mZnNldCk7XG4gICAgfVxuICAgIGdldCBvcDEoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmhlYXAuZ2V0YnlhZGRyKHRoaXMub2Zmc2V0ICsgMSk7XG4gICAgfVxuICAgIGdldCBvcDIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmhlYXAuZ2V0YnlhZGRyKHRoaXMub2Zmc2V0ICsgMik7XG4gICAgfVxuICAgIGdldCBvcDMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmhlYXAuZ2V0YnlhZGRyKHRoaXMub2Zmc2V0ICsgMyk7XG4gICAgfVxufVxudmFyIFRhYmxlU2xvdFN0YXRlO1xuKGZ1bmN0aW9uIChUYWJsZVNsb3RTdGF0ZSkge1xuICAgIFRhYmxlU2xvdFN0YXRlW1RhYmxlU2xvdFN0YXRlW1wiQWxsb2NhdGVkXCJdID0gMF0gPSBcIkFsbG9jYXRlZFwiO1xuICAgIFRhYmxlU2xvdFN0YXRlW1RhYmxlU2xvdFN0YXRlW1wiRnJlZWRcIl0gPSAxXSA9IFwiRnJlZWRcIjtcbiAgICBUYWJsZVNsb3RTdGF0ZVtUYWJsZVNsb3RTdGF0ZVtcIlB1cmdlZFwiXSA9IDJdID0gXCJQdXJnZWRcIjtcbiAgICBUYWJsZVNsb3RTdGF0ZVtUYWJsZVNsb3RTdGF0ZVtcIlBvaW50ZXJcIl0gPSAzXSA9IFwiUG9pbnRlclwiO1xufSkoVGFibGVTbG90U3RhdGUgfHwgKFRhYmxlU2xvdFN0YXRlID0ge30pKTtcbmV4cG9ydCBjbGFzcyBIZWFwIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5oZWFwID0gW107XG4gICAgICAgIHRoaXMub2Zmc2V0ID0gMDtcbiAgICAgICAgdGhpcy5oYW5kbGUgPSAwO1xuICAgICAgICAvKipcbiAgICAgICAgICogbGF5b3V0OlxuICAgICAgICAgKlxuICAgICAgICAgKiAtIHBvaW50ZXIgaW50byBoZWFwXG4gICAgICAgICAqIC0gc2l6ZVxuICAgICAgICAgKiAtIGZyZWVkICgwIG9yIDEpXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnRhYmxlID0gW107XG4gICAgfVxuICAgIHB1c2goaXRlbSkge1xuICAgICAgICB0aGlzLmhlYXBbdGhpcy5vZmZzZXQrK10gPSBpdGVtO1xuICAgIH1cbiAgICBnZXRieWFkZHIoYWRkcmVzcykge1xuICAgICAgICByZXR1cm4gdGhpcy5oZWFwW2FkZHJlc3NdO1xuICAgIH1cbiAgICBzZXRieWFkZHIoYWRkcmVzcywgdmFsdWUpIHtcbiAgICAgICAgdGhpcy5oZWFwW2FkZHJlc3NdID0gdmFsdWU7XG4gICAgfVxuICAgIG1hbGxvYygpIHtcbiAgICAgICAgdGhpcy50YWJsZS5wdXNoKHRoaXMub2Zmc2V0LCAwLCAwKTtcbiAgICAgICAgbGV0IGhhbmRsZSA9IHRoaXMuaGFuZGxlO1xuICAgICAgICB0aGlzLmhhbmRsZSArPSAzO1xuICAgICAgICByZXR1cm4gaGFuZGxlO1xuICAgIH1cbiAgICBmaW5pc2hNYWxsb2MoaGFuZGxlKSB7XG4gICAgICAgIGxldCBzdGFydCA9IHRoaXMudGFibGVbaGFuZGxlXTtcbiAgICAgICAgbGV0IGZpbmlzaCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICB0aGlzLnRhYmxlW2hhbmRsZSArIDFdID0gZmluaXNoIC0gc3RhcnQ7XG4gICAgfVxuICAgIHNpemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9mZnNldDtcbiAgICB9XG4gICAgLy8gSXQgaXMgaWxsZWdhbCB0byBjbG9zZSBvdmVyIHRoaXMgYWRkcmVzcywgYXMgY29tcGFjdGlvblxuICAgIC8vIG1heSBtb3ZlIGl0LiBIb3dldmVyLCBpdCBpcyBsZWdhbCB0byB1c2UgdGhpcyBhZGRyZXNzXG4gICAgLy8gbXVsdGlwbGUgdGltZXMgYmV0d2VlbiBjb21wYWN0aW9ucy5cbiAgICBnZXRhZGRyKGhhbmRsZSkge1xuICAgICAgICByZXR1cm4gdGhpcy50YWJsZVtoYW5kbGVdO1xuICAgIH1cbiAgICBnZXRoYW5kbGUoYWRkcmVzcykge1xuICAgICAgICB0aGlzLnRhYmxlLnB1c2goYWRkcmVzcywgMCwgVGFibGVTbG90U3RhdGUuUG9pbnRlcik7XG4gICAgICAgIGxldCBoYW5kbGUgPSB0aGlzLmhhbmRsZTtcbiAgICAgICAgdGhpcy5oYW5kbGUgKz0gMztcbiAgICAgICAgcmV0dXJuIGhhbmRsZTtcbiAgICB9XG4gICAgc2l6ZW9mKGhhbmRsZSkge1xuICAgICAgICBpZiAoZmFsc2UpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnRhYmxlW2hhbmRsZSArIDFdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAtMTtcbiAgICB9XG4gICAgZnJlZShoYW5kbGUpIHtcbiAgICAgICAgdGhpcy50YWJsZVtoYW5kbGUgKyAyXSA9IDE7XG4gICAgfVxuICAgIGNvbXBhY3QoKSB7XG4gICAgICAgIGxldCBjb21wYWN0ZWRTaXplID0gMDtcbiAgICAgICAgbGV0IHsgdGFibGUsIHRhYmxlOiB7IGxlbmd0aCB9LCBoZWFwIH0gPSB0aGlzO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAzKSB7XG4gICAgICAgICAgICBsZXQgb2Zmc2V0ID0gdGFibGVbaV07XG4gICAgICAgICAgICBsZXQgc2l6ZSA9IHRhYmxlW2kgKyAxXTtcbiAgICAgICAgICAgIGxldCBzdGF0ZSA9IHRhYmxlW2kgKyAyXTtcbiAgICAgICAgICAgIGlmIChzdGF0ZSA9PT0gVGFibGVTbG90U3RhdGUuUHVyZ2VkKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHN0YXRlID09PSBUYWJsZVNsb3RTdGF0ZS5GcmVlZCkge1xuICAgICAgICAgICAgICAgIC8vIHRyYW5zaXRpb24gdG8gXCJhbHJlYWR5IGZyZWVkXCJcbiAgICAgICAgICAgICAgICAvLyBhIGdvb2QgaW1wcm92ZW1lbnQgd291bGQgYmUgdG8gcmV1c2VcbiAgICAgICAgICAgICAgICAvLyB0aGVzZSBzbG90c1xuICAgICAgICAgICAgICAgIHRhYmxlW2kgKyAyXSA9IDI7XG4gICAgICAgICAgICAgICAgY29tcGFjdGVkU2l6ZSArPSBzaXplO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChzdGF0ZSA9PT0gVGFibGVTbG90U3RhdGUuQWxsb2NhdGVkKSB7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IG9mZnNldDsgaiA8PSBpICsgc2l6ZTsgaisrKSB7XG4gICAgICAgICAgICAgICAgICAgIGhlYXBbaiAtIGNvbXBhY3RlZFNpemVdID0gaGVhcFtqXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGFibGVbaV0gPSBvZmZzZXQgLSBjb21wYWN0ZWRTaXplO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChzdGF0ZSA9PT0gVGFibGVTbG90U3RhdGUuUG9pbnRlcikge1xuICAgICAgICAgICAgICAgIHRhYmxlW2ldID0gb2Zmc2V0IC0gY29tcGFjdGVkU2l6ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9mZnNldCA9IHRoaXMub2Zmc2V0IC0gY29tcGFjdGVkU2l6ZTtcbiAgICB9XG59XG5leHBvcnQgY2xhc3MgUHJvZ3JhbSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuaGVhcCA9IG5ldyBIZWFwKCk7XG4gICAgICAgIHRoaXMuX29wY29kZSA9IG5ldyBPcGNvZGUodGhpcy5oZWFwKTtcbiAgICAgICAgdGhpcy5jb25zdGFudHMgPSBuZXcgQ29uc3RhbnRzKCk7XG4gICAgfVxuICAgIG9wY29kZShvZmZzZXQpIHtcbiAgICAgICAgdGhpcy5fb3Bjb2RlLm9mZnNldCA9IG9mZnNldDtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29wY29kZTtcbiAgICB9XG59XG5leHBvcnQgY2xhc3MgRW52aXJvbm1lbnQge1xuICAgIGNvbnN0cnVjdG9yKHsgYXBwZW5kT3BlcmF0aW9ucywgdXBkYXRlT3BlcmF0aW9ucyB9KSB7XG4gICAgICAgIHRoaXMuX21hY3JvcyA9IG51bGw7XG4gICAgICAgIHRoaXMuX3RyYW5zYWN0aW9uID0gbnVsbDtcbiAgICAgICAgdGhpcy5wcm9ncmFtID0gbmV3IFByb2dyYW0oKTtcbiAgICAgICAgdGhpcy5hcHBlbmRPcGVyYXRpb25zID0gYXBwZW5kT3BlcmF0aW9ucztcbiAgICAgICAgdGhpcy51cGRhdGVPcGVyYXRpb25zID0gdXBkYXRlT3BlcmF0aW9ucztcbiAgICB9XG4gICAgdG9Db25kaXRpb25hbFJlZmVyZW5jZShyZWZlcmVuY2UpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBDb25kaXRpb25hbFJlZmVyZW5jZShyZWZlcmVuY2UpO1xuICAgIH1cbiAgICBnZXRBcHBlbmRPcGVyYXRpb25zKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5hcHBlbmRPcGVyYXRpb25zO1xuICAgIH1cbiAgICBnZXRET00oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnVwZGF0ZU9wZXJhdGlvbnM7XG4gICAgfVxuICAgIGdldElkZW50aXR5KG9iamVjdCkge1xuICAgICAgICByZXR1cm4gZW5zdXJlR3VpZChvYmplY3QpICsgJyc7XG4gICAgfVxuICAgIGJlZ2luKCkge1xuICAgICAgICBhc3NlcnQoIXRoaXMuX3RyYW5zYWN0aW9uLCAnYSBnbGltbWVyIHRyYW5zYWN0aW9uIHdhcyBiZWd1biwgYnV0IG9uZSBhbHJlYWR5IGV4aXN0cy4gWW91IG1heSBoYXZlIGEgbmVzdGVkIHRyYW5zYWN0aW9uJyk7XG4gICAgICAgIHRoaXMuX3RyYW5zYWN0aW9uID0gbmV3IFRyYW5zYWN0aW9uKCk7XG4gICAgfVxuICAgIGdldCB0cmFuc2FjdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIGV4cGVjdCh0aGlzLl90cmFuc2FjdGlvbiwgJ211c3QgYmUgaW4gYSB0cmFuc2FjdGlvbicpO1xuICAgIH1cbiAgICBkaWRDcmVhdGUoY29tcG9uZW50LCBtYW5hZ2VyKSB7XG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb24uZGlkQ3JlYXRlKGNvbXBvbmVudCwgbWFuYWdlcik7XG4gICAgfVxuICAgIGRpZFVwZGF0ZShjb21wb25lbnQsIG1hbmFnZXIpIHtcbiAgICAgICAgdGhpcy50cmFuc2FjdGlvbi5kaWRVcGRhdGUoY29tcG9uZW50LCBtYW5hZ2VyKTtcbiAgICB9XG4gICAgc2NoZWR1bGVJbnN0YWxsTW9kaWZpZXIobW9kaWZpZXIsIG1hbmFnZXIpIHtcbiAgICAgICAgdGhpcy50cmFuc2FjdGlvbi5zY2hlZHVsZUluc3RhbGxNb2RpZmllcihtb2RpZmllciwgbWFuYWdlcik7XG4gICAgfVxuICAgIHNjaGVkdWxlVXBkYXRlTW9kaWZpZXIobW9kaWZpZXIsIG1hbmFnZXIpIHtcbiAgICAgICAgdGhpcy50cmFuc2FjdGlvbi5zY2hlZHVsZVVwZGF0ZU1vZGlmaWVyKG1vZGlmaWVyLCBtYW5hZ2VyKTtcbiAgICB9XG4gICAgZGlkRGVzdHJveShkKSB7XG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb24uZGlkRGVzdHJveShkKTtcbiAgICB9XG4gICAgY29tbWl0KCkge1xuICAgICAgICBsZXQgdHJhbnNhY3Rpb24gPSB0aGlzLnRyYW5zYWN0aW9uO1xuICAgICAgICB0aGlzLl90cmFuc2FjdGlvbiA9IG51bGw7XG4gICAgICAgIHRyYW5zYWN0aW9uLmNvbW1pdCgpO1xuICAgIH1cbiAgICBhdHRyaWJ1dGVGb3IoZWxlbWVudCwgYXR0ciwgaXNUcnVzdGluZywgbmFtZXNwYWNlKSB7XG4gICAgICAgIHJldHVybiBkZWZhdWx0TWFuYWdlcnMoZWxlbWVudCwgYXR0ciwgaXNUcnVzdGluZywgbmFtZXNwYWNlID09PSB1bmRlZmluZWQgPyBudWxsIDogbmFtZXNwYWNlKTtcbiAgICB9XG4gICAgbWFjcm9zKCkge1xuICAgICAgICBsZXQgbWFjcm9zID0gdGhpcy5fbWFjcm9zO1xuICAgICAgICBpZiAoIW1hY3Jvcykge1xuICAgICAgICAgICAgdGhpcy5fbWFjcm9zID0gbWFjcm9zID0gdGhpcy5wb3B1bGF0ZUJ1aWx0aW5zKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1hY3JvcztcbiAgICB9XG4gICAgcG9wdWxhdGVCdWlsdGlucygpIHtcbiAgICAgICAgcmV0dXJuIHBvcHVsYXRlQnVpbHRpbnMoKTtcbiAgICB9XG59XG5leHBvcnQgZGVmYXVsdCBFbnZpcm9ubWVudDsiXX0=