UNPKG

ember-legacy-class-transform

Version:
436 lines (350 loc) 42.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.InstanceMeta = exports.ClassMeta = exports.EMPTY_CACHE = undefined; exports.turbocharge = turbocharge; var _objectReference = require("@glimmer/object-reference"); var _util = require("@glimmer/util"); var _mixin = require("./mixin"); var _utils = require("./utils"); function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults);for (var i = 0; i < keys.length; i++) { var key = keys[i];var value = Object.getOwnPropertyDescriptor(defaults, key);if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } }return obj; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); }return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); }subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : _defaults(subClass, superClass); } var isArray = Array.isArray; var EMPTY_CACHE = exports.EMPTY_CACHE = function EMPTY_CACHE() {}; var CLASS_META = "df8be4c8-4e89-44e2-a8f9-550c8dacdca7"; function turbocharge(obj) { // function Dummy() {} // Dummy.prototype = obj; return obj; } var SealedMeta = function (_Meta) { _inherits(SealedMeta, _Meta); function SealedMeta() { _classCallCheck(this, SealedMeta); return _possibleConstructorReturn(this, _Meta.apply(this, arguments)); } SealedMeta.prototype.addReferenceTypeFor = function addReferenceTypeFor() { throw new Error("Cannot modify reference types on a sealed meta"); }; return SealedMeta; }(_objectReference.Meta); var ClassMeta = exports.ClassMeta = function () { function ClassMeta() { _classCallCheck(this, ClassMeta); this.referenceTypes = (0, _util.dict)(); this.propertyMetadata = (0, _util.dict)(); this.concatenatedProperties = (0, _util.dict)(); this.hasConcatenatedProperties = false; this.mergedProperties = (0, _util.dict)(); this.hasMergedProperties = false; this.mixins = []; this.appliedMixins = []; this.staticMixins = []; this.subclasses = []; this.slots = []; this.InstanceMetaConstructor = null; } ClassMeta.fromParent = function fromParent(parent) { var meta = new this(); meta.reset(parent); return meta; }; ClassMeta.for = function _for(object) { if (CLASS_META in object) return object[CLASS_META];else if (object.constructor) return object.constructor[CLASS_META] || null;else return null; }; ClassMeta.prototype.init = function init(object, attrs) { if (typeof attrs !== 'object' || attrs === null) return; if (this.hasConcatenatedProperties) { var concatProps = this.concatenatedProperties; for (var prop in concatProps) { if (prop in attrs) { var concat = concatProps[prop].slice(); object[prop] = concat.concat(attrs[prop]); } } } if (this.hasMergedProperties) { var mergedProps = this.mergedProperties; for (var _prop in mergedProps) { if (_prop in attrs) { var merged = (0, _util.assign)({}, mergedProps[_prop]); object[_prop] = (0, _util.assign)(merged, attrs[_prop]); } } } }; ClassMeta.prototype.addStaticMixin = function addStaticMixin(mixin) { this.staticMixins.push(mixin); }; ClassMeta.prototype.addMixin = function addMixin(mixin) { this.mixins.push(mixin); }; ClassMeta.prototype.getStaticMixins = function getStaticMixins() { return this.staticMixins; }; ClassMeta.prototype.getMixins = function getMixins() { return this.mixins; }; ClassMeta.prototype.addAppliedMixin = function addAppliedMixin(mixin) { this.appliedMixins.push(mixin); }; ClassMeta.prototype.hasAppliedMixin = function hasAppliedMixin(mixin) { return this.appliedMixins.indexOf(mixin) !== -1; }; ClassMeta.prototype.getAppliedMixins = function getAppliedMixins() { return this.appliedMixins; }; ClassMeta.prototype.hasStaticMixin = function hasStaticMixin(mixin) { return this.staticMixins.indexOf(mixin) !== -1; }; ClassMeta.applyAllMixins = function applyAllMixins(Subclass, Parent) { Subclass[CLASS_META].getMixins().forEach(function (m) { return m.extendPrototypeOnto(Subclass, Parent); }); Subclass[CLASS_META].getStaticMixins().forEach(function (m) { return m.extendStatic(Subclass); }); Subclass[CLASS_META].seal(); }; ClassMeta.prototype.addSubclass = function addSubclass(constructor) { this.subclasses.push(constructor); }; ClassMeta.prototype.getSubclasses = function getSubclasses() { return this.subclasses; }; ClassMeta.prototype.addPropertyMetadata = function addPropertyMetadata(property, value) { this.propertyMetadata[property] = value; }; ClassMeta.prototype.metadataForProperty = function metadataForProperty(property) { return this.propertyMetadata[property]; }; ClassMeta.prototype.addReferenceTypeFor = function addReferenceTypeFor(property, type) { this.referenceTypes[property] = type; }; ClassMeta.prototype.addSlotFor = function addSlotFor(property) { this.slots.push(property); }; ClassMeta.prototype.hasConcatenatedProperty = function hasConcatenatedProperty(property) { if (!this.hasConcatenatedProperties) return false; return property in this.concatenatedProperties; }; ClassMeta.prototype.getConcatenatedProperty = function getConcatenatedProperty(property) { return this.concatenatedProperties[property]; }; ClassMeta.prototype.getConcatenatedProperties = function getConcatenatedProperties() { return Object.keys(this.concatenatedProperties); }; ClassMeta.prototype.addConcatenatedProperty = function addConcatenatedProperty(property, value) { this.hasConcatenatedProperties = true; if (property in this.concatenatedProperties) { var val = this.concatenatedProperties[property].concat(value); this.concatenatedProperties[property] = val; } else { this.concatenatedProperties[property] = value; } }; ClassMeta.prototype.hasMergedProperty = function hasMergedProperty(property) { if (!this.hasMergedProperties) return false; return property in this.mergedProperties; }; ClassMeta.prototype.getMergedProperty = function getMergedProperty(property) { return this.mergedProperties[property]; }; ClassMeta.prototype.getMergedProperties = function getMergedProperties() { return Object.keys(this.mergedProperties); }; ClassMeta.prototype.addMergedProperty = function addMergedProperty(property, value) { this.hasMergedProperties = true; if (isArray(value)) { throw new Error('You passed in `' + JSON.stringify(value) + '` as the value for `foo` but `foo` cannot be an Array'); } if (property in this.mergedProperties && this.mergedProperties[property] && value) { this.mergedProperties[property] = mergeMergedProperties(value, this.mergedProperties[property]); } else { value = value === null ? value : value || {}; this.mergedProperties[property] = value; } }; ClassMeta.prototype.getReferenceTypes = function getReferenceTypes() { return this.referenceTypes; }; ClassMeta.prototype.getPropertyMetadata = function getPropertyMetadata() { return this.propertyMetadata; }; ClassMeta.prototype.reset = function reset(parent) { this.referenceTypes = (0, _util.dict)(); this.propertyMetadata = (0, _util.dict)(); this.concatenatedProperties = (0, _util.dict)(); this.mergedProperties = (0, _util.dict)(); if (parent) { this.hasConcatenatedProperties = parent.hasConcatenatedProperties; for (var prop in parent.concatenatedProperties) { this.concatenatedProperties[prop] = parent.concatenatedProperties[prop].slice(); } this.hasMergedProperties = parent.hasMergedProperties; for (var _prop2 in parent.mergedProperties) { this.mergedProperties[_prop2] = (0, _util.assign)({}, parent.mergedProperties[_prop2]); } (0, _util.assign)(this.referenceTypes, parent.referenceTypes); (0, _util.assign)(this.propertyMetadata, parent.propertyMetadata); } }; ClassMeta.prototype.reseal = function reseal(obj) { var meta = _objectReference.Meta.for(obj); var fresh = new this.InstanceMetaConstructor(obj, {}); var referenceTypes = meta.getReferenceTypes(); var slots = meta.getSlots(); turbocharge((0, _util.assign)(referenceTypes, this.referenceTypes)); turbocharge((0, _util.assign)(slots, fresh.getSlots())); }; ClassMeta.prototype.seal = function seal() { var referenceTypes = turbocharge((0, _util.assign)({}, this.referenceTypes)); turbocharge(this.concatenatedProperties); turbocharge(this.mergedProperties); if (!this.hasMergedProperties && !this.hasConcatenatedProperties) { this.init = function () {}; } var slots = this.slots; var Slots = function Slots() { var _this2 = this; _classCallCheck(this, Slots); slots.forEach(function (name) { _this2[name] = EMPTY_CACHE; }); }; this.InstanceMetaConstructor = function (_SealedMeta) { _inherits(_class, _SealedMeta); function _class() { _classCallCheck(this, _class); var _this3 = _possibleConstructorReturn(this, _SealedMeta.apply(this, arguments)); _this3.slots = new Slots(); _this3.referenceTypes = referenceTypes; return _this3; } _class.prototype.getReferenceTypes = function getReferenceTypes() { return this.referenceTypes; }; _class.prototype.referenceTypeFor = function referenceTypeFor(property) { return this.referenceTypes[property] || _objectReference.PropertyReference; }; _class.prototype.getSlots = function getSlots() { return this.slots; }; return _class; }(SealedMeta); turbocharge(this); }; return ClassMeta; }(); function mergeMergedProperties(attrs, parent) { var merged = (0, _util.assign)({}, parent); for (var prop in attrs) { if (prop in parent && typeof parent[prop] === 'function' && typeof attrs[prop] === 'function') { var wrapped = (0, _mixin.wrapMethod)(parent, prop, attrs[prop]); merged[prop] = wrapped; } else { merged[prop] = attrs[prop]; } } return merged; } var InstanceMeta = exports.InstanceMeta = function (_ClassMeta) { _inherits(InstanceMeta, _ClassMeta); function InstanceMeta() { _classCallCheck(this, InstanceMeta); var _this4 = _possibleConstructorReturn(this, _ClassMeta.apply(this, arguments)); _this4["df8be4c8-4e89-44e2-a8f9-550c8dacdca7"] = ClassMeta.fromParent(null); return _this4; } InstanceMeta.fromParent = function fromParent(parent) { return _ClassMeta.fromParent.call(this, parent); }; InstanceMeta.prototype.reset = function reset(parent) { _ClassMeta.prototype.reset.call(this, parent); if (parent) this[CLASS_META].reset(parent[CLASS_META]); }; InstanceMeta.prototype.seal = function seal() { _ClassMeta.prototype.seal.call(this); this[CLASS_META].seal(); }; return InstanceMeta; }(ClassMeta); var GlimmerObject = function () { function GlimmerObject(attrs) { _classCallCheck(this, GlimmerObject); this._super = _utils.ROOT; this._meta = null; if (attrs) (0, _util.assign)(this, attrs); this.constructor[CLASS_META].init(this, attrs || null); this._super = _utils.ROOT; (0, _util.initializeGuid)(this); this.init(); } GlimmerObject.extend = function extend() { for (var _len = arguments.length, extensions = Array(_len), _key = 0; _key < _len; _key++) { extensions[_key] = arguments[_key]; } return _mixin.extend.apply(undefined, [this].concat(extensions)); }; GlimmerObject.create = function create(attrs) { return new this(attrs); }; GlimmerObject.reopen = function reopen(extensions) { (0, _mixin.toMixin)(extensions).extendPrototype(this); this[CLASS_META].seal(); (0, _mixin.relinkSubclasses)(this); }; GlimmerObject.reopenClass = function reopenClass(extensions) { (0, _mixin.toMixin)(extensions).extendStatic(this); this[CLASS_META].seal(); }; GlimmerObject.metaForProperty = function metaForProperty(property) { var value = this[CLASS_META].metadataForProperty(property); if (!value) throw new Error('metaForProperty() could not find a computed property with key \'' + property + '\'.'); return value; }; GlimmerObject.eachComputedProperty = function eachComputedProperty(callback) { var metadata = this[CLASS_META].getPropertyMetadata(); if (!metadata) return; for (var prop in metadata) { callback(prop, metadata[prop]); } }; GlimmerObject.prototype.init = function init() {}; GlimmerObject.prototype.get = function get(key) { return this[key]; }; GlimmerObject.prototype.set = function set(key, value) { this[key] = value; }; GlimmerObject.prototype.setProperties = function setProperties(attrs) { (0, _util.assign)(this, attrs); }; GlimmerObject.prototype.destroy = function destroy() {}; return GlimmerObject; }(); exports.default = GlimmerObject; GlimmerObject["df8be4c8-4e89-44e2-a8f9-550c8dacdca7"] = InstanceMeta.fromParent(null); GlimmerObject.isClass = true; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9vYmplY3QuanMiXSwibmFtZXMiOlsiTWV0YSIsIlByb3BlcnR5UmVmZXJlbmNlIiwiZGljdCIsImFzc2lnbiIsImluaXRpYWxpemVHdWlkIiwiZXh0ZW5kIiwiZXh0ZW5kQ2xhc3MiLCJ0b01peGluIiwicmVsaW5rU3ViY2xhc3NlcyIsIndyYXBNZXRob2QiLCJpc0FycmF5IiwiQXJyYXkiLCJST09UIiwiRU1QVFlfQ0FDSEUiLCJDTEFTU19NRVRBIiwidHVyYm9jaGFyZ2UiLCJvYmoiLCJTZWFsZWRNZXRhIiwiYWRkUmVmZXJlbmNlVHlwZUZvciIsIkVycm9yIiwiQ2xhc3NNZXRhIiwicmVmZXJlbmNlVHlwZXMiLCJwcm9wZXJ0eU1ldGFkYXRhIiwiY29uY2F0ZW5hdGVkUHJvcGVydGllcyIsImhhc0NvbmNhdGVuYXRlZFByb3BlcnRpZXMiLCJtZXJnZWRQcm9wZXJ0aWVzIiwiaGFzTWVyZ2VkUHJvcGVydGllcyIsIm1peGlucyIsImFwcGxpZWRNaXhpbnMiLCJzdGF0aWNNaXhpbnMiLCJzdWJjbGFzc2VzIiwic2xvdHMiLCJJbnN0YW5jZU1ldGFDb25zdHJ1Y3RvciIsImZyb21QYXJlbnQiLCJwYXJlbnQiLCJtZXRhIiwicmVzZXQiLCJmb3IiLCJvYmplY3QiLCJjb25zdHJ1Y3RvciIsImluaXQiLCJhdHRycyIsImNvbmNhdFByb3BzIiwicHJvcCIsImNvbmNhdCIsInNsaWNlIiwibWVyZ2VkUHJvcHMiLCJtZXJnZWQiLCJhZGRTdGF0aWNNaXhpbiIsIm1peGluIiwicHVzaCIsImFkZE1peGluIiwiZ2V0U3RhdGljTWl4aW5zIiwiZ2V0TWl4aW5zIiwiYWRkQXBwbGllZE1peGluIiwiaGFzQXBwbGllZE1peGluIiwiaW5kZXhPZiIsImdldEFwcGxpZWRNaXhpbnMiLCJoYXNTdGF0aWNNaXhpbiIsImFwcGx5QWxsTWl4aW5zIiwiU3ViY2xhc3MiLCJQYXJlbnQiLCJmb3JFYWNoIiwibSIsImV4dGVuZFByb3RvdHlwZU9udG8iLCJleHRlbmRTdGF0aWMiLCJzZWFsIiwiYWRkU3ViY2xhc3MiLCJnZXRTdWJjbGFzc2VzIiwiYWRkUHJvcGVydHlNZXRhZGF0YSIsInByb3BlcnR5IiwidmFsdWUiLCJtZXRhZGF0YUZvclByb3BlcnR5IiwidHlwZSIsImFkZFNsb3RGb3IiLCJoYXNDb25jYXRlbmF0ZWRQcm9wZXJ0eSIsImdldENvbmNhdGVuYXRlZFByb3BlcnR5IiwiZ2V0Q29uY2F0ZW5hdGVkUHJvcGVydGllcyIsIk9iamVjdCIsImtleXMiLCJhZGRDb25jYXRlbmF0ZWRQcm9wZXJ0eSIsInZhbCIsImhhc01lcmdlZFByb3BlcnR5IiwiZ2V0TWVyZ2VkUHJvcGVydHkiLCJnZXRNZXJnZWRQcm9wZXJ0aWVzIiwiYWRkTWVyZ2VkUHJvcGVydHkiLCJKU09OIiwic3RyaW5naWZ5IiwibWVyZ2VNZXJnZWRQcm9wZXJ0aWVzIiwiZ2V0UmVmZXJlbmNlVHlwZXMiLCJnZXRQcm9wZXJ0eU1ldGFkYXRhIiwicmVzZWFsIiwiZnJlc2giLCJnZXRTbG90cyIsIlNsb3RzIiwibmFtZSIsImFyZ3VtZW50cyIsInJlZmVyZW5jZVR5cGVGb3IiLCJ3cmFwcGVkIiwiSW5zdGFuY2VNZXRhIiwiR2xpbW1lck9iamVjdCIsIl9zdXBlciIsIl9tZXRhIiwiZXh0ZW5zaW9ucyIsImNyZWF0ZSIsInJlb3BlbiIsImV4dGVuZFByb3RvdHlwZSIsInJlb3BlbkNsYXNzIiwibWV0YUZvclByb3BlcnR5IiwiZWFjaENvbXB1dGVkUHJvcGVydHkiLCJjYWxsYmFjayIsIm1ldGFkYXRhIiwiZ2V0Iiwia2V5Iiwic2V0Iiwic2V0UHJvcGVydGllcyIsImRlc3Ryb3kiLCJpc0NsYXNzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7UUFPTyxBQUFTOztBQVBoQixBQUFTLEFBQU0sQUFBeUI7O0FBQ3hDLEFBQVMsQUFBTSxBQUFRLEFBQXNCOztBQUM3QyxBQUFTLEFBQVUsQUFBYSxBQUFTLEFBQWtCLEFBQWtCOztBQUU3RSxBQUFTLEFBQVksQUFDckI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7SUFGUSxBLFVBQVksQSxNLEFBQVo7O0FBRUQsSUFBTSxvQ0FBYyxTQUFBLEFBQVMsY0FBYyxBQUFFLENBQTdDO0FBQ1AsSUFBTSxhQUFOLEFBQW1CLEFBQ25CO0FBQU8scUJBQUEsQUFBcUIsS0FBSyxBQUM3QjtBQUNBO0FBQ0E7V0FBQSxBQUFPLEFBQ1Y7OztJQUNLLEE7Ozs7Ozs7Ozt5QkFDRixBLHFEQUE4QixBQUMxQjtjQUFNLElBQUEsQUFBSSxNQUFWLEFBQU0sQUFBVSxBQUNuQjtBOzs7QSxBQUhvQixBQUt6Qjs7SUFBQSxBQUFhLDRDQUNUO3lCQUFjOzhCQUNWOzthQUFBLEFBQUssaUJBQUwsQUFBc0IsQUFDdEI7YUFBQSxBQUFLLG1CQUFMLEFBQXdCLEFBQ3hCO2FBQUEsQUFBSyx5QkFBTCxBQUE4QixBQUM5QjthQUFBLEFBQUssNEJBQUwsQUFBaUMsQUFDakM7YUFBQSxBQUFLLG1CQUFMLEFBQXdCLEFBQ3hCO2FBQUEsQUFBSyxzQkFBTCxBQUEyQixBQUMzQjthQUFBLEFBQUssU0FBTCxBQUFjLEFBQ2Q7YUFBQSxBQUFLLGdCQUFMLEFBQXFCLEFBQ3JCO2FBQUEsQUFBSyxlQUFMLEFBQW9CLEFBQ3BCO2FBQUEsQUFBSyxhQUFMLEFBQWtCLEFBQ2xCO2FBQUEsQUFBSyxRQUFMLEFBQWEsQUFDYjthQUFBLEFBQUssMEJBQUwsQUFBK0IsQUFDbEM7QUFkTDs7Y0FBQSxBQWVXLGlDQWZYLEFBZXNCLFFBQVEsQUFDdEI7WUFBSSxPQUFPLElBQVgsQUFBVyxBQUFJLEFBQ2Y7YUFBQSxBQUFLLE1BQUwsQUFBVyxBQUNYO2VBQUEsQUFBTyxBQUNWO0FBbkJMOztjQUFBLEFBb0JXLG9CQXBCWCxBQW9CZSxRQUFRLEFBQ2Y7WUFBSSxjQUFKLEFBQWtCLFFBQVEsT0FBTyxPQUFqQyxBQUEwQixBQUFPLEFBQU8saUJBQWlCLElBQUksT0FBSixBQUFXLGFBQWEsT0FBTyxPQUFBLEFBQU8sWUFBUCxBQUFtQixlQUFsRCxBQUF3QixBQUF5QyxVQUFVLE9BQUEsQUFBTyxBQUM5STtBQXRCTDs7d0JBQUEsQUF1QkkscUJBdkJKLEFBdUJTLFFBdkJULEFBdUJpQixPQUFPLEFBQ2hCO1lBQUksT0FBQSxBQUFPLFVBQVAsQUFBaUIsWUFBWSxVQUFqQyxBQUEyQyxNQUFNLEFBQ2pEO1lBQUksS0FBSixBQUFTLDJCQUEyQixBQUNoQztnQkFBSSxjQUFjLEtBQWxCLEFBQXVCLEFBQ3ZCO2lCQUFLLElBQUwsQUFBUyxRQUFULEFBQWlCLGFBQWEsQUFDMUI7b0JBQUksUUFBSixBQUFZLE9BQU8sQUFDZjt3QkFBSSxTQUFTLFlBQUEsQUFBWSxNQUF6QixBQUFhLEFBQWtCLEFBQy9COzJCQUFBLEFBQU8sUUFBUSxPQUFBLEFBQU8sT0FBTyxNQUE3QixBQUFlLEFBQWMsQUFBTSxBQUN0QztBQUNKO0FBQ0o7QUFDRDtZQUFJLEtBQUosQUFBUyxxQkFBcUIsQUFDMUI7Z0JBQUksY0FBYyxLQUFsQixBQUF1QixBQUN2QjtpQkFBSyxJQUFMLEFBQVMsU0FBVCxBQUFpQixhQUFhLEFBQzFCO29CQUFJLFNBQUosQUFBWSxPQUFPLEFBQ2Y7d0JBQUksU0FBUyxrQkFBQSxBQUFPLElBQUksWUFBeEIsQUFBYSxBQUFXLEFBQVksQUFDcEM7MkJBQUEsQUFBTyxTQUFRLGtCQUFBLEFBQU8sUUFBUSxNQUE5QixBQUFlLEFBQWUsQUFBTSxBQUN2QztBQUNKO0FBQ0o7QUFDSjtBQTNDTDs7d0JBQUEsQUE0Q0kseUNBNUNKLEFBNENtQixPQUFPLEFBQ2xCO2FBQUEsQUFBSyxhQUFMLEFBQWtCLEtBQWxCLEFBQXVCLEFBQzFCO0FBOUNMOzt3QkFBQSxBQStDSSw2QkEvQ0osQUErQ2EsT0FBTyxBQUNaO2FBQUEsQUFBSyxPQUFMLEFBQVksS0FBWixBQUFpQixBQUNwQjtBQWpETDs7d0JBQUEsQUFrREksNkNBQWtCLEFBQ2Q7ZUFBTyxLQUFQLEFBQVksQUFDZjtBQXBETDs7d0JBQUEsQUFxREksaUNBQVksQUFDUjtlQUFPLEtBQVAsQUFBWSxBQUNmO0FBdkRMOzt3QkFBQSxBQXdESSwyQ0F4REosQUF3RG9CLE9BQU8sQUFDbkI7YUFBQSxBQUFLLGNBQUwsQUFBbUIsS0FBbkIsQUFBd0IsQUFDM0I7QUExREw7O3dCQUFBLEFBMkRJLDJDQTNESixBQTJEb0IsT0FBTyxBQUNuQjtlQUFPLEtBQUEsQUFBSyxjQUFMLEFBQW1CLFFBQW5CLEFBQTJCLFdBQVcsQ0FBN0MsQUFBOEMsQUFDakQ7QUE3REw7O3dCQUFBLEFBOERJLCtDQUFtQixBQUNmO2VBQU8sS0FBUCxBQUFZLEFBQ2Y7QUFoRUw7O3dCQUFBLEFBaUVJLHlDQWpFSixBQWlFbUIsT0FBTyxBQUNsQjtlQUFPLEtBQUEsQUFBSyxhQUFMLEFBQWtCLFFBQWxCLEFBQTBCLFdBQVcsQ0FBNUMsQUFBNkMsQUFDaEQ7QUFuRUw7O2NBQUEsQUFvRVcseUNBcEVYLEFBb0UwQixVQXBFMUIsQUFvRW9DLFFBQVEsQUFDcEM7aUJBQUEsQUFBUyxZQUFULEFBQXFCLFlBQXJCLEFBQWlDLFFBQVEsYUFBQTttQkFBSyxFQUFBLEFBQUUsb0JBQUYsQUFBc0IsVUFBM0IsQUFBSyxBQUFnQztBQUE5RSxBQUNBO2lCQUFBLEFBQVMsWUFBVCxBQUFxQixrQkFBckIsQUFBdUMsUUFBUSxhQUFBO21CQUFLLEVBQUEsQUFBRSxhQUFQLEFBQUssQUFBZTtBQUFuRSxBQUNBO2lCQUFBLEFBQVMsWUFBVCxBQUFxQixBQUN4QjtBQXhFTDs7d0JBQUEsQUF5RUksbUNBekVKLEFBeUVnQixhQUFhLEFBQ3JCO2FBQUEsQUFBSyxXQUFMLEFBQWdCLEtBQWhCLEFBQXFCLEFBQ3hCO0FBM0VMOzt3QkFBQSxBQTRFSSx5Q0FBZ0IsQUFDWjtlQUFPLEtBQVAsQUFBWSxBQUNmO0FBOUVMOzt3QkFBQSxBQStFSSxtREEvRUosQUErRXdCLFVBL0V4QixBQStFa0MsT0FBTyxBQUNqQzthQUFBLEFBQUssaUJBQUwsQUFBc0IsWUFBdEIsQUFBa0MsQUFDckM7QUFqRkw7O3dCQUFBLEFBa0ZJLG1EQWxGSixBQWtGd0IsVUFBVSxBQUMxQjtlQUFPLEtBQUEsQUFBSyxpQkFBWixBQUFPLEFBQXNCLEFBQ2hDO0FBcEZMOzt3QkFBQSxBQXFGSSxtREFyRkosQUFxRndCLFVBckZ4QixBQXFGa0MsTUFBTSxBQUNoQzthQUFBLEFBQUssZUFBTCxBQUFvQixZQUFwQixBQUFnQyxBQUNuQztBQXZGTDs7d0JBQUEsQUF3RkksaUNBeEZKLEFBd0ZlLFVBQVUsQUFDakI7YUFBQSxBQUFLLE1BQUwsQUFBVyxLQUFYLEFBQWdCLEFBQ25CO0FBMUZMOzt3QkFBQSxBQTJGSSwyREEzRkosQUEyRjRCLFVBQVUsQUFDOUI7WUFBSSxDQUFDLEtBQUwsQUFBVSwyQkFBMkIsT0FBQSxBQUFPLEFBQzVDO2VBQU8sWUFBWSxLQUFuQixBQUF3QixBQUMzQjtBQTlGTDs7d0JBQUEsQUErRkksMkRBL0ZKLEFBK0Y0QixVQUFVLEFBQzlCO2VBQU8sS0FBQSxBQUFLLHVCQUFaLEFBQU8sQUFBNEIsQUFDdEM7QUFqR0w7O3dCQUFBLEFBa0dJLGlFQUE0QixBQUN4QjtlQUFPLE9BQUEsQUFBTyxLQUFLLEtBQW5CLEFBQU8sQUFBaUIsQUFDM0I7QUFwR0w7O3dCQUFBLEFBcUdJLDJEQXJHSixBQXFHNEIsVUFyRzVCLEFBcUdzQyxPQUFPLEFBQ3JDO2FBQUEsQUFBSyw0QkFBTCxBQUFpQyxBQUNqQztZQUFJLFlBQVksS0FBaEIsQUFBcUIsd0JBQXdCLEFBQ3pDO2dCQUFJLE1BQU0sS0FBQSxBQUFLLHVCQUFMLEFBQTRCLFVBQTVCLEFBQXNDLE9BQWhELEFBQVUsQUFBNkMsQUFDdkQ7aUJBQUEsQUFBSyx1QkFBTCxBQUE0QixZQUE1QixBQUF3QyxBQUMzQztBQUhELGVBR08sQUFDSDtpQkFBQSxBQUFLLHVCQUFMLEFBQTRCLFlBQTVCLEFBQXdDLEFBQzNDO0FBQ0o7QUE3R0w7O3dCQUFBLEFBOEdJLCtDQTlHSixBQThHc0IsVUFBVSxBQUN4QjtZQUFJLENBQUMsS0FBTCxBQUFVLHFCQUFxQixPQUFBLEFBQU8sQUFDdEM7ZUFBTyxZQUFZLEtBQW5CLEFBQXdCLEFBQzNCO0FBakhMOzt3QkFBQSxBQWtISSwrQ0FsSEosQUFrSHNCLFVBQVUsQUFDeEI7ZUFBTyxLQUFBLEFBQUssaUJBQVosQUFBTyxBQUFzQixBQUNoQztBQXBITDs7d0JBQUEsQUFxSEkscURBQXNCLEFBQ2xCO2VBQU8sT0FBQSxBQUFPLEtBQUssS0FBbkIsQUFBTyxBQUFpQixBQUMzQjtBQXZITDs7d0JBQUEsQUF3SEksK0NBeEhKLEFBd0hzQixVQXhIdEIsQUF3SGdDLE9BQU8sQUFDL0I7YUFBQSxBQUFLLHNCQUFMLEFBQTJCLEFBQzNCO1lBQUksUUFBSixBQUFJLEFBQVEsUUFBUSxBQUNoQjtrQkFBTSxJQUFBLEFBQUksMEJBQXlCLEtBQUEsQUFBSyxVQUFsQyxBQUE2QixBQUFlLFNBQWxELEFBQ0g7QUFDRDtZQUFJLFlBQVksS0FBWixBQUFpQixvQkFBb0IsS0FBQSxBQUFLLGlCQUExQyxBQUFxQyxBQUFzQixhQUEvRCxBQUE0RSxPQUFPLEFBQy9FO2lCQUFBLEFBQUssaUJBQUwsQUFBc0IsWUFBWSxzQkFBQSxBQUFzQixPQUFPLEtBQUEsQUFBSyxpQkFBcEUsQUFBa0MsQUFBNkIsQUFBc0IsQUFDeEY7QUFGRCxlQUVPLEFBQ0g7b0JBQVEsVUFBQSxBQUFVLE9BQVYsQUFBaUIsUUFBUSxTQUFqQyxBQUEwQyxBQUMxQztpQkFBQSxBQUFLLGlCQUFMLEFBQXNCLFlBQXRCLEFBQWtDLEFBQ3JDO0FBQ0o7QUFuSUw7O3dCQUFBLEFBb0lJLGlEQUFvQixBQUNoQjtlQUFPLEtBQVAsQUFBWSxBQUNmO0FBdElMOzt3QkFBQSxBQXVJSSxxREFBc0IsQUFDbEI7ZUFBTyxLQUFQLEFBQVksQUFDZjtBQXpJTDs7d0JBQUEsQUEwSUksdUJBMUlKLEFBMElVLFFBQVEsQUFDVjthQUFBLEFBQUssaUJBQUwsQUFBc0IsQUFDdEI7YUFBQSxBQUFLLG1CQUFMLEFBQXdCLEFBQ3hCO2FBQUEsQUFBSyx5QkFBTCxBQUE4QixBQUM5QjthQUFBLEFBQUssbUJBQUwsQUFBd0IsQUFDeEI7WUFBQSxBQUFJLFFBQVEsQUFDUjtpQkFBQSxBQUFLLDRCQUE0QixPQUFqQyxBQUF3QyxBQUN4QztpQkFBSyxJQUFMLEFBQVMsUUFBUSxPQUFqQixBQUF3Qix3QkFBd0IsQUFDNUM7cUJBQUEsQUFBSyx1QkFBTCxBQUE0QixRQUFRLE9BQUEsQUFBTyx1QkFBUCxBQUE4QixNQUFsRSxBQUFvQyxBQUFvQyxBQUMzRTtBQUNEO2lCQUFBLEFBQUssc0JBQXNCLE9BQTNCLEFBQWtDLEFBQ2xDO2lCQUFLLElBQUwsQUFBUyxVQUFRLE9BQWpCLEFBQXdCLGtCQUFrQixBQUN0QztxQkFBQSxBQUFLLGlCQUFMLEFBQXNCLFVBQVEsa0JBQUEsQUFBTyxJQUFJLE9BQUEsQUFBTyxpQkFBaEQsQUFBOEIsQUFBVyxBQUF3QixBQUNwRTtBQUNEOzhCQUFPLEtBQVAsQUFBWSxnQkFBZ0IsT0FBNUIsQUFBbUMsQUFDbkM7OEJBQU8sS0FBUCxBQUFZLGtCQUFrQixPQUE5QixBQUFxQyxBQUN4QztBQUNKO0FBM0pMOzt3QkFBQSxBQTRKSSx5QkE1SkosQUE0SlcsS0FBSyxBQUNSO1lBQUksT0FBTyxzQkFBQSxBQUFLLElBQWhCLEFBQVcsQUFBUyxBQUNwQjtZQUFJLFFBQVEsSUFBSSxLQUFKLEFBQVMsd0JBQVQsQUFBaUMsS0FBN0MsQUFBWSxBQUFzQyxBQUNsRDtZQUFJLGlCQUFpQixLQUFyQixBQUFxQixBQUFLLEFBQzFCO1lBQUksUUFBUSxLQUFaLEFBQVksQUFBSyxBQUNqQjtvQkFBWSxrQkFBQSxBQUFPLGdCQUFnQixLQUFuQyxBQUFZLEFBQTRCLEFBQ3hDO29CQUFZLGtCQUFBLEFBQU8sT0FBTyxNQUExQixBQUFZLEFBQWMsQUFBTSxBQUNuQztBQW5LTDs7d0JBQUEsQUFvS0ksdUJBQU8sQUFDSDtZQUFJLGlCQUFpQixZQUFZLGtCQUFBLEFBQU8sSUFBSSxLQUE1QyxBQUFxQixBQUFZLEFBQWdCLEFBQ2pEO29CQUFZLEtBQVosQUFBaUIsQUFDakI7b0JBQVksS0FBWixBQUFpQixBQUNqQjtZQUFJLENBQUMsS0FBRCxBQUFNLHVCQUF1QixDQUFDLEtBQWxDLEFBQXVDLDJCQUEyQixBQUM5RDtpQkFBQSxBQUFLLE9BQU8sWUFBWSxBQUFFLENBQTFCLEFBQ0g7QUFDRDtZQUFJLFFBQVEsS0FQVCxBQU9ILEFBQWlCOztZQVBkLEFBUUcsUUFDRixpQkFBYzt5QkFBQTs7a0NBQ1Y7O2tCQUFBLEFBQU0sUUFBUSxnQkFBUSxBQUNsQjt1QkFBQSxBQUFLLFFBQUwsQUFBYSxBQUNoQjtBQUZELEFBR0g7QUFiRixBQWVIOzthQUFBLEFBQUssaURBQUw7OEJBQ0k7OzhCQUFjO3NDQUFBOzs4REFDVix3QkFEVSxBQUNWLEFBQVMsQUFDVDs7dUJBQUEsQUFBSyxRQUFRLElBQWIsQUFBYSxBQUFJLEFBQ2pCO3VCQUFBLEFBQUssaUJBSEssQUFHVixBQUFzQjt1QkFDekI7QUFMTDs7NkJBQUEsQUFNSSxpREFBb0IsQUFDaEI7dUJBQU8sS0FBUCxBQUFZLEFBQ2Y7QUFSTDs7NkJBQUEsQUFTSSw2Q0FUSixBQVNxQixVQUFVLEFBQ3ZCO3VCQUFPLEtBQUEsQUFBSyxlQUFaLEFBQU8sQUFBb0IsQUFBYSxBQUMzQztBQVhMOzs2QkFBQSxBQVlJLCtCQUFXLEFBQ1A7dUJBQU8sS0FBUCxBQUFZLEFBQ2Y7QUFkTDs7bUJBQUE7VUFBQSxBQUE2QyxBQWdCN0M7b0JBQUEsQUFBWSxBQUNmO0FBcE1MOztXQUFBOztBQXNNQSxTQUFBLEFBQVMsc0JBQVQsQUFBK0IsT0FBL0IsQUFBc0MsUUFBUSxBQUMxQztRQUFJLFNBQVMsa0JBQUEsQUFBTyxJQUFwQixBQUFhLEFBQVcsQUFDeEI7U0FBSyxJQUFMLEFBQVMsUUFBVCxBQUFpQixPQUFPLEFBQ3BCO1lBQUksUUFBQSxBQUFRLFVBQVUsT0FBTyxPQUFQLEFBQU8sQUFBTyxVQUFoQyxBQUEwQyxjQUFjLE9BQU8sTUFBUCxBQUFPLEFBQU0sVUFBekUsQUFBbUYsWUFBWSxBQUMzRjtnQkFBSSxVQUFVLHVCQUFBLEFBQVcsUUFBWCxBQUFtQixNQUFNLE1BQXZDLEFBQWMsQUFBeUIsQUFBTSxBQUM3QzttQkFBQSxBQUFPLFFBQVAsQUFBZSxBQUNsQjtBQUhELGVBR08sQUFDSDttQkFBQSxBQUFPLFFBQVEsTUFBZixBQUFlLEFBQU0sQUFDeEI7QUFDSjtBQUNEO1dBQUEsQUFBTyxBQUNWO0FBQ0Q7SUFBQSxBQUFhLDREQUFiOzRCQUNJOzs0QkFBYzs4QkFBQTs7c0RBQ1YsdUJBRFUsQUFDVixBQUFTLEFBQ1Q7O2VBQUEsQUFBSywwQ0FBMEMsVUFBQSxBQUFVLFdBRi9DLEFBRVYsQUFBK0MsQUFBcUI7ZUFDdkU7QUFKTDs7aUJBQUEsQUFLVyxpQ0FMWCxBQUtzQixRQUFRLEFBQ3RCO2VBQU8sV0FBQSxBQUFNLHNCQUFiLEFBQU8sQUFBaUIsQUFDM0I7QUFQTDs7MkJBQUEsQUFRSSx1QkFSSixBQVFVLFFBQVEsQUFDVjs2QkFBQSxBQUFNLGlCQUFOLEFBQVksQUFDWjtZQUFBLEFBQUksUUFBUSxLQUFBLEFBQUssWUFBTCxBQUFpQixNQUFNLE9BQXZCLEFBQXVCLEFBQU8sQUFDN0M7QUFYTDs7MkJBQUEsQUFZSSx1QkFBTyxBQUNIOzZCQUFBLEFBQU0sVUFDTjthQUFBLEFBQUssWUFBTCxBQUFpQixBQUNwQjtBQWZMOztXQUFBO0VBQUEsQUFBa0M7O0ksQUFpQmIsNEJBQ2pCOzJCQUFBLEFBQVksT0FBTzs4QkFDZjs7YUFBQSxBQUFLLEFBQVMsQUFDZDthQUFBLEFBQUssUUFBTCxBQUFhLEFBQ2I7WUFBQSxBQUFJLE9BQU8sa0JBQUEsQUFBTyxNQUFQLEFBQWEsQUFDeEI7YUFBQSxBQUFLLFlBQUwsQUFBaUIsWUFBakIsQUFBNkIsS0FBN0IsQUFBa0MsTUFBTSxTQUF4QyxBQUFpRCxBQUNqRDthQUFBLEFBQUssQUFBUyxBQUNkO2tDQUFBLEFBQWUsQUFDZjthQUFBLEFBQUssQUFDUjs7O2tCQUNNLEEsMkJBQXNCOzBDQUFaLEFBQVkseURBQVo7QUFBWSx5Q0FBQTtBQUN6Qjs7ZUFBTyxnQ0FBQSxBQUFZLGFBQW5CLEFBQU8sQUFBcUIsQUFDL0I7QTs7a0IsQUFDTSx5QkFBTyxBLE9BQU8sQUFDakI7ZUFBTyxJQUFBLEFBQUksS0FBWCxBQUFPLEFBQVMsQUFDbkI7QTs7a0JBQ00sQSx5QixBQUFPLFlBQVksQUFDdEI7NEJBQUEsQUFBUSxZQUFSLEFBQW9CLGdCQUFwQixBQUFvQyxBQUNwQzthQUFBLEFBQUssWUFBTCxBQUFpQixBQUNqQjtxQ0FBQSxBQUFpQixBQUNwQjtBOztrQkFDTSxBLG1DLEFBQVksWUFBWSxBQUMzQjs0QkFBQSxBQUFRLFlBQVIsQUFBb0IsYUFBcEIsQUFBaUMsQUFDakM7YUFBQSxBQUFLLFlBQUwsQUFBaUIsQUFDcEI7QTs7a0JBQ00sQSwyQ0FBZ0IsQSxVQUFVLEFBQzdCO1lBQUksUUFBUSxLQUFBLEFBQUssWUFBTCxBQUFpQixvQkFBN0IsQUFBWSxBQUFxQyxBQUNqRDtZQUFJLENBQUosQUFBSyxPQUFPLE1BQU0sSUFBQSxBQUFJLDJFQUFKLEFBQTRFLFdBQWxGLEFBQ1o7ZUFBQSxBQUFPLEFBQ1Y7QTs7a0JBQ00sQSxxREFBcUIsQSxVQUFVLEFBQ2xDO1lBQUksV0FBVyxLQUFBLEFBQUssWUFBcEIsQUFBZSxBQUFpQixBQUNoQztZQUFJLENBQUosQUFBSyxVQUFVLEFBQ2Y7YUFBSyxJQUFMLEFBQVMsUUFBVCxBQUFpQixVQUFVLEFBQ3ZCO3FCQUFBLEFBQVMsTUFBTSxTQUFmLEFBQWUsQUFBUyxBQUMzQjtBQUNKO0E7OzRCQUNELEEsdUJBQU8sQUFBRSxDOzs0QixBQUNULG1CQUFJLEEsS0FBSyxBQUNMO2VBQU8sS0FBUCxBQUFPLEFBQUssQUFDZjtBOzs0QkFDRCxBLG1CQUFJLEEsSyxBQUFLLE9BQU8sQUFDWjthQUFBLEFBQUssT0FBTCxBQUFZLEFBQ2Y7QTs7NEJBQ0QsQSx1Q0FBYyxBLE9BQU8sQUFDakI7MEJBQUEsQUFBTyxNQUFQLEFBQWEsQUFDaEI7QTs7NEIsQUFDRCw2QkFBVSxBQUFFLEM7Ozs7O2tCQS9DSyxBOzs7QUFpRHJCLGNBQUEsQUFBYywwQ0FBMEMsYUFBQSxBQUFhLFdBQXJFLEFBQXdELEFBQXdCO0FBQ2hGLGNBQUEsQUFBYyxVQUFkLEFBQXdCIiwiZmlsZSI6ImxpYi9vYmplY3QuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBNZXRhLCBQcm9wZXJ0eVJlZmVyZW5jZSB9IGZyb20gJ0BnbGltbWVyL29iamVjdC1yZWZlcmVuY2UnO1xuaW1wb3J0IHsgZGljdCwgYXNzaWduLCBpbml0aWFsaXplR3VpZCB9IGZyb20gJ0BnbGltbWVyL3V0aWwnO1xuaW1wb3J0IHsgZXh0ZW5kIGFzIGV4dGVuZENsYXNzLCB0b01peGluLCByZWxpbmtTdWJjbGFzc2VzLCB3cmFwTWV0aG9kIH0gZnJvbSAnLi9taXhpbic7XG5jb25zdCB7IGlzQXJyYXkgfSA9IEFycmF5O1xuaW1wb3J0IHsgUk9PVCB9IGZyb20gJy4vdXRpbHMnO1xuZXhwb3J0IGNvbnN0IEVNUFRZX0NBQ0hFID0gZnVuY3Rpb24gRU1QVFlfQ0FDSEUoKSB7fTtcbmNvbnN0IENMQVNTX01FVEEgPSBcImRmOGJlNGM4LTRlODktNDRlMi1hOGY5LTU1MGM4ZGFjZGNhN1wiO1xuZXhwb3J0IGZ1bmN0aW9uIHR1cmJvY2hhcmdlKG9iaikge1xuICAgIC8vIGZ1bmN0aW9uIER1bW15KCkge31cbiAgICAvLyBEdW1teS5wcm90b3R5cGUgPSBvYmo7XG4gICAgcmV0dXJuIG9iajtcbn1cbmNsYXNzIFNlYWxlZE1ldGEgZXh0ZW5kcyBNZXRhIHtcbiAgICBhZGRSZWZlcmVuY2VUeXBlRm9yKC4uLl9hcmdzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBtb2RpZnkgcmVmZXJlbmNlIHR5cGVzIG9uIGEgc2VhbGVkIG1ldGFcIik7XG4gICAgfVxufVxuZXhwb3J0IGNsYXNzIENsYXNzTWV0YSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMucmVmZXJlbmNlVHlwZXMgPSBkaWN0KCk7XG4gICAgICAgIHRoaXMucHJvcGVydHlNZXRhZGF0YSA9IGRpY3QoKTtcbiAgICAgICAgdGhpcy5jb25jYXRlbmF0ZWRQcm9wZXJ0aWVzID0gZGljdCgpO1xuICAgICAgICB0aGlzLmhhc0NvbmNhdGVuYXRlZFByb3BlcnRpZXMgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5tZXJnZWRQcm9wZXJ0aWVzID0gZGljdCgpO1xuICAgICAgICB0aGlzLmhhc01lcmdlZFByb3BlcnRpZXMgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5taXhpbnMgPSBbXTtcbiAgICAgICAgdGhpcy5hcHBsaWVkTWl4aW5zID0gW107XG4gICAgICAgIHRoaXMuc3RhdGljTWl4aW5zID0gW107XG4gICAgICAgIHRoaXMuc3ViY2xhc3NlcyA9IFtdO1xuICAgICAgICB0aGlzLnNsb3RzID0gW107XG4gICAgICAgIHRoaXMuSW5zdGFuY2VNZXRhQ29uc3RydWN0b3IgPSBudWxsO1xuICAgIH1cbiAgICBzdGF0aWMgZnJvbVBhcmVudChwYXJlbnQpIHtcbiAgICAgICAgbGV0IG1ldGEgPSBuZXcgdGhpcygpO1xuICAgICAgICBtZXRhLnJlc2V0KHBhcmVudCk7XG4gICAgICAgIHJldHVybiBtZXRhO1xuICAgIH1cbiAgICBzdGF0aWMgZm9yKG9iamVjdCkge1xuICAgICAgICBpZiAoQ0xBU1NfTUVUQSBpbiBvYmplY3QpIHJldHVybiBvYmplY3RbQ0xBU1NfTUVUQV07ZWxzZSBpZiAob2JqZWN0LmNvbnN0cnVjdG9yKSByZXR1cm4gb2JqZWN0LmNvbnN0cnVjdG9yW0NMQVNTX01FVEFdIHx8IG51bGw7ZWxzZSByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaW5pdChvYmplY3QsIGF0dHJzKSB7XG4gICAgICAgIGlmICh0eXBlb2YgYXR0cnMgIT09ICdvYmplY3QnIHx8IGF0dHJzID09PSBudWxsKSByZXR1cm47XG4gICAgICAgIGlmICh0aGlzLmhhc0NvbmNhdGVuYXRlZFByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgIGxldCBjb25jYXRQcm9wcyA9IHRoaXMuY29uY2F0ZW5hdGVkUHJvcGVydGllcztcbiAgICAgICAgICAgIGZvciAobGV0IHByb3AgaW4gY29uY2F0UHJvcHMpIHtcbiAgICAgICAgICAgICAgICBpZiAocHJvcCBpbiBhdHRycykge1xuICAgICAgICAgICAgICAgICAgICBsZXQgY29uY2F0ID0gY29uY2F0UHJvcHNbcHJvcF0uc2xpY2UoKTtcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0W3Byb3BdID0gY29uY2F0LmNvbmNhdChhdHRyc1twcm9wXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmhhc01lcmdlZFByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgIGxldCBtZXJnZWRQcm9wcyA9IHRoaXMubWVyZ2VkUHJvcGVydGllcztcbiAgICAgICAgICAgIGZvciAobGV0IHByb3AgaW4gbWVyZ2VkUHJvcHMpIHtcbiAgICAgICAgICAgICAgICBpZiAocHJvcCBpbiBhdHRycykge1xuICAgICAgICAgICAgICAgICAgICBsZXQgbWVyZ2VkID0gYXNzaWduKHt9LCBtZXJnZWRQcm9wc1twcm9wXSk7XG4gICAgICAgICAgICAgICAgICAgIG9iamVjdFtwcm9wXSA9IGFzc2lnbihtZXJnZWQsIGF0dHJzW3Byb3BdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgYWRkU3RhdGljTWl4aW4obWl4aW4pIHtcbiAgICAgICAgdGhpcy5zdGF0aWNNaXhpbnMucHVzaChtaXhpbik7XG4gICAgfVxuICAgIGFkZE1peGluKG1peGluKSB7XG4gICAgICAgIHRoaXMubWl4aW5zLnB1c2gobWl4aW4pO1xuICAgIH1cbiAgICBnZXRTdGF0aWNNaXhpbnMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0YXRpY01peGlucztcbiAgICB9XG4gICAgZ2V0TWl4aW5zKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5taXhpbnM7XG4gICAgfVxuICAgIGFkZEFwcGxpZWRNaXhpbihtaXhpbikge1xuICAgICAgICB0aGlzLmFwcGxpZWRNaXhpbnMucHVzaChtaXhpbik7XG4gICAgfVxuICAgIGhhc0FwcGxpZWRNaXhpbihtaXhpbikge1xuICAgICAgICByZXR1cm4gdGhpcy5hcHBsaWVkTWl4aW5zLmluZGV4T2YobWl4aW4pICE9PSAtMTtcbiAgICB9XG4gICAgZ2V0QXBwbGllZE1peGlucygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXBwbGllZE1peGlucztcbiAgICB9XG4gICAgaGFzU3RhdGljTWl4aW4obWl4aW4pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhdGljTWl4aW5zLmluZGV4T2YobWl4aW4pICE9PSAtMTtcbiAgICB9XG4gICAgc3RhdGljIGFwcGx5QWxsTWl4aW5zKFN1YmNsYXNzLCBQYXJlbnQpIHtcbiAgICAgICAgU3ViY2xhc3NbQ0xBU1NfTUVUQV0uZ2V0TWl4aW5zKCkuZm9yRWFjaChtID0+IG0uZXh0ZW5kUHJvdG90eXBlT250byhTdWJjbGFzcywgUGFyZW50KSk7XG4gICAgICAgIFN1YmNsYXNzW0NMQVNTX01FVEFdLmdldFN0YXRpY01peGlucygpLmZvckVhY2gobSA9PiBtLmV4dGVuZFN0YXRpYyhTdWJjbGFzcykpO1xuICAgICAgICBTdWJjbGFzc1tDTEFTU19NRVRBXS5zZWFsKCk7XG4gICAgfVxuICAgIGFkZFN1YmNsYXNzKGNvbnN0cnVjdG9yKSB7XG4gICAgICAgIHRoaXMuc3ViY2xhc3Nlcy5wdXNoKGNvbnN0cnVjdG9yKTtcbiAgICB9XG4gICAgZ2V0U3ViY2xhc3NlcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3ViY2xhc3NlcztcbiAgICB9XG4gICAgYWRkUHJvcGVydHlNZXRhZGF0YShwcm9wZXJ0eSwgdmFsdWUpIHtcbiAgICAgICAgdGhpcy5wcm9wZXJ0eU1ldGFkYXRhW3Byb3BlcnR5XSA9IHZhbHVlO1xuICAgIH1cbiAgICBtZXRhZGF0YUZvclByb3BlcnR5KHByb3BlcnR5KSB7XG4gICAgICAgIHJldHVybiB0aGlzLnByb3BlcnR5TWV0YWRhdGFbcHJvcGVydHldO1xuICAgIH1cbiAgICBhZGRSZWZlcmVuY2VUeXBlRm9yKHByb3BlcnR5LCB0eXBlKSB7XG4gICAgICAgIHRoaXMucmVmZXJlbmNlVHlwZXNbcHJvcGVydHldID0gdHlwZTtcbiAgICB9XG4gICAgYWRkU2xvdEZvcihwcm9wZXJ0eSkge1xuICAgICAgICB0aGlzLnNsb3RzLnB1c2gocHJvcGVydHkpO1xuICAgIH1cbiAgICBoYXNDb25jYXRlbmF0ZWRQcm9wZXJ0eShwcm9wZXJ0eSkge1xuICAgICAgICBpZiAoIXRoaXMuaGFzQ29uY2F0ZW5hdGVkUHJvcGVydGllcykgcmV0dXJuIGZhbHNlO1xuICAgICAgICByZXR1cm4gcHJvcGVydHkgaW4gdGhpcy5jb25jYXRlbmF0ZWRQcm9wZXJ0aWVzO1xuICAgIH1cbiAgICBnZXRDb25jYXRlbmF0ZWRQcm9wZXJ0eShwcm9wZXJ0eSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25jYXRlbmF0ZWRQcm9wZXJ0aWVzW3Byb3BlcnR5XTtcbiAgICB9XG4gICAgZ2V0Q29uY2F0ZW5hdGVkUHJvcGVydGllcygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuY29uY2F0ZW5hdGVkUHJvcGVydGllcyk7XG4gICAgfVxuICAgIGFkZENvbmNhdGVuYXRlZFByb3BlcnR5KHByb3BlcnR5LCB2YWx1ZSkge1xuICAgICAgICB0aGlzLmhhc0NvbmNhdGVuYXRlZFByb3BlcnRpZXMgPSB0cnVlO1xuICAgICAgICBpZiAocHJvcGVydHkgaW4gdGhpcy5jb25jYXRlbmF0ZWRQcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICBsZXQgdmFsID0gdGhpcy5jb25jYXRlbmF0ZWRQcm9wZXJ0aWVzW3Byb3BlcnR5XS5jb25jYXQodmFsdWUpO1xuICAgICAgICAgICAgdGhpcy5jb25jYXRlbmF0ZWRQcm9wZXJ0aWVzW3Byb3BlcnR5XSA9IHZhbDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY29uY2F0ZW5hdGVkUHJvcGVydGllc1twcm9wZXJ0eV0gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBoYXNNZXJnZWRQcm9wZXJ0eShwcm9wZXJ0eSkge1xuICAgICAgICBpZiAoIXRoaXMuaGFzTWVyZ2VkUHJvcGVydGllcykgcmV0dXJuIGZhbHNlO1xuICAgICAgICByZXR1cm4gcHJvcGVydHkgaW4gdGhpcy5tZXJnZWRQcm9wZXJ0aWVzO1xuICAgIH1cbiAgICBnZXRNZXJnZWRQcm9wZXJ0eShwcm9wZXJ0eSkge1xuICAgICAgICByZXR1cm4gdGhpcy5tZXJnZWRQcm9wZXJ0aWVzW3Byb3BlcnR5XTtcbiAgICB9XG4gICAgZ2V0TWVyZ2VkUHJvcGVydGllcygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMubWVyZ2VkUHJvcGVydGllcyk7XG4gICAgfVxuICAgIGFkZE1lcmdlZFByb3BlcnR5KHByb3BlcnR5LCB2YWx1ZSkge1xuICAgICAgICB0aGlzLmhhc01lcmdlZFByb3BlcnRpZXMgPSB0cnVlO1xuICAgICAgICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgWW91IHBhc3NlZCBpbiBcXGAke0pTT04uc3RyaW5naWZ5KHZhbHVlKX1cXGAgYXMgdGhlIHZhbHVlIGZvciBcXGBmb29cXGAgYnV0IFxcYGZvb1xcYCBjYW5ub3QgYmUgYW4gQXJyYXlgKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocHJvcGVydHkgaW4gdGhpcy5tZXJnZWRQcm9wZXJ0aWVzICYmIHRoaXMubWVyZ2VkUHJvcGVydGllc1twcm9wZXJ0eV0gJiYgdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMubWVyZ2VkUHJvcGVydGllc1twcm9wZXJ0eV0gPSBtZXJnZU1lcmdlZFByb3BlcnRpZXModmFsdWUsIHRoaXMubWVyZ2VkUHJvcGVydGllc1twcm9wZXJ0eV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZSA9PT0gbnVsbCA/IHZhbHVlIDogdmFsdWUgfHwge307XG4gICAgICAgICAgICB0aGlzLm1lcmdlZFByb3BlcnRpZXNbcHJvcGVydHldID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0UmVmZXJlbmNlVHlwZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlZmVyZW5jZVR5cGVzO1xuICAgIH1cbiAgICBnZXRQcm9wZXJ0eU1ldGFkYXRhKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9wZXJ0eU1ldGFkYXRhO1xuICAgIH1cbiAgICByZXNldChwYXJlbnQpIHtcbiAgICAgICAgdGhpcy5yZWZlcmVuY2VUeXBlcyA9IGRpY3QoKTtcbiAgICAgICAgdGhpcy5wcm9wZXJ0eU1ldGFkYXRhID0gZGljdCgpO1xuICAgICAgICB0aGlzLmNvbmNhdGVuYXRlZFByb3BlcnRpZXMgPSBkaWN0KCk7XG4gICAgICAgIHRoaXMubWVyZ2VkUHJvcGVydGllcyA9IGRpY3QoKTtcbiAgICAgICAgaWYgKHBhcmVudCkge1xuICAgICAgICAgICAgdGhpcy5oYXNDb25jYXRlbmF0ZWRQcm9wZXJ0aWVzID0gcGFyZW50Lmhhc0NvbmNhdGVuYXRlZFByb3BlcnRpZXM7XG4gICAgICAgICAgICBmb3IgKGxldCBwcm9wIGluIHBhcmVudC5jb25jYXRlbmF0ZWRQcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb25jYXRlbmF0ZWRQcm9wZXJ0aWVzW3Byb3BdID0gcGFyZW50LmNvbmNhdGVuYXRlZFByb3BlcnRpZXNbcHJvcF0uc2xpY2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuaGFzTWVyZ2VkUHJvcGVydGllcyA9IHBhcmVudC5oYXNNZXJnZWRQcm9wZXJ0aWVzO1xuICAgICAgICAgICAgZm9yIChsZXQgcHJvcCBpbiBwYXJlbnQubWVyZ2VkUHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgIHRoaXMubWVyZ2VkUHJvcGVydGllc1twcm9wXSA9IGFzc2lnbih7fSwgcGFyZW50Lm1lcmdlZFByb3BlcnRpZXNbcHJvcF0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXNzaWduKHRoaXMucmVmZXJlbmNlVHlwZXMsIHBhcmVudC5yZWZlcmVuY2VUeXBlcyk7XG4gICAgICAgICAgICBhc3NpZ24odGhpcy5wcm9wZXJ0eU1ldGFkYXRhLCBwYXJlbnQucHJvcGVydHlNZXRhZGF0YSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmVzZWFsKG9iaikge1xuICAgICAgICBsZXQgbWV0YSA9IE1ldGEuZm9yKG9iaik7XG4gICAgICAgIGxldCBmcmVzaCA9IG5ldyB0aGlzLkluc3RhbmNlTWV0YUNvbnN0cnVjdG9yKG9iaiwge30pO1xuICAgICAgICBsZXQgcmVmZXJlbmNlVHlwZXMgPSBtZXRhLmdldFJlZmVyZW5jZVR5cGVzKCk7XG4gICAgICAgIGxldCBzbG90cyA9IG1ldGEuZ2V0U2xvdHMoKTtcbiAgICAgICAgdHVyYm9jaGFyZ2UoYXNzaWduKHJlZmVyZW5jZVR5cGVzLCB0aGlzLnJlZmVyZW5jZVR5cGVzKSk7XG4gICAgICAgIHR1cmJvY2hhcmdlKGFzc2lnbihzbG90cywgZnJlc2guZ2V0U2xvdHMoKSkpO1xuICAgIH1cbiAgICBzZWFsKCkge1xuICAgICAgICBsZXQgcmVmZXJlbmNlVHlwZXMgPSB0dXJib2NoYXJnZShhc3NpZ24oe30sIHRoaXMucmVmZXJlbmNlVHlwZXMpKTtcbiAgICAgICAgdHVyYm9jaGFyZ2UodGhpcy5jb25jYXRlbmF0ZWRQcm9wZXJ0aWVzKTtcbiAgICAgICAgdHVyYm9jaGFyZ2UodGhpcy5tZXJnZWRQcm9wZXJ0aWVzKTtcbiAgICAgICAgaWYgKCF0aGlzLmhhc01lcmdlZFByb3BlcnRpZXMgJiYgIXRoaXMuaGFzQ29uY2F0ZW5hdGVkUHJvcGVydGllcykge1xuICAgICAgICAgICAgdGhpcy5pbml0ID0gZnVuY3Rpb24gKCkge307XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHNsb3RzID0gdGhpcy5zbG90cztcbiAgICAgICAgY2xhc3MgU2xvdHMge1xuICAgICAgICAgICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgICAgICAgICAgc2xvdHMuZm9yRWFjaChuYW1lID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpc1tuYW1lXSA9IEVNUFRZX0NBQ0hFO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuSW5zdGFuY2VNZXRhQ29uc3RydWN0b3IgPSBjbGFzcyBleHRlbmRzIFNlYWxlZE1ldGEge1xuICAgICAgICAgICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgICAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNsb3RzID0gbmV3IFNsb3RzKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZWZlcmVuY2VUeXBlcyA9IHJlZmVyZW5jZVR5cGVzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZ2V0UmVmZXJlbmNlVHlwZXMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVmZXJlbmNlVHlwZXM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZWZlcmVuY2VUeXBlRm9yKHByb3BlcnR5KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVmZXJlbmNlVHlwZXNbcHJvcGVydHldIHx8IFByb3BlcnR5UmVmZXJlbmNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZ2V0U2xvdHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2xvdHM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHR1cmJvY2hhcmdlKHRoaXMpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIG1lcmdlTWVyZ2VkUHJvcGVydGllcyhhdHRycywgcGFyZW50KSB7XG4gICAgbGV0IG1lcmdlZCA9IGFzc2lnbih7fSwgcGFyZW50KTtcbiAgICBmb3IgKGxldCBwcm9wIGluIGF0dHJzKSB7XG4gICAgICAgIGlmIChwcm9wIGluIHBhcmVudCAmJiB0eXBlb2YgcGFyZW50W3Byb3BdID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBhdHRyc1twcm9wXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgbGV0IHdyYXBwZWQgPSB3cmFwTWV0aG9kKHBhcmVudCwgcHJvcCwgYXR0cnNbcHJvcF0pO1xuICAgICAgICAgICAgbWVyZ2VkW3Byb3BdID0gd3JhcHBlZDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG1lcmdlZFtwcm9wXSA9IGF0dHJzW3Byb3BdO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBtZXJnZWQ7XG59XG5leHBvcnQgY2xhc3MgSW5zdGFuY2VNZXRhIGV4dGVuZHMgQ2xhc3NNZXRhIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpc1tcImRmOGJlNGM4LTRlODktNDRlMi1hOGY5LTU1MGM4ZGFjZGNhN1wiXSA9IENsYXNzTWV0YS5mcm9tUGFyZW50KG51bGwpO1xuICAgIH1cbiAgICBzdGF0aWMgZnJvbVBhcmVudChwYXJlbnQpIHtcbiAgICAgICAgcmV0dXJuIHN1cGVyLmZyb21QYXJlbnQocGFyZW50KTtcbiAgICB9XG4gICAgcmVzZXQocGFyZW50KSB7XG4gICAgICAgIHN1cGVyLnJlc2V0KHBhcmVudCk7XG4gICAgICAgIGlmIChwYXJlbnQpIHRoaXNbQ0xBU1NfTUVUQV0ucmVzZXQocGFyZW50W0NMQVNTX01FVEFdKTtcbiAgICB9XG4gICAgc2VhbCgpIHtcbiAgICAgICAgc3VwZXIuc2VhbCgpO1xuICAgICAgICB0aGlzW0NMQVNTX01FVEFdLnNlYWwoKTtcbiAgICB9XG59XG5leHBvcnQgZGVmYXVsdCBjbGFzcyBHbGltbWVyT2JqZWN0IHtcbiAgICBjb25zdHJ1Y3RvcihhdHRycykge1xuICAgICAgICB0aGlzLl9zdXBlciA9IFJPT1Q7XG4gICAgICAgIHRoaXMuX21ldGEgPSBudWxsO1xuICAgICAgICBpZiAoYXR0cnMpIGFzc2lnbih0aGlzLCBhdHRycyk7XG4gICAgICAgIHRoaXMuY29uc3RydWN0b3JbQ0xBU1NfTUVUQV0uaW5pdCh0aGlzLCBhdHRycyB8fCBudWxsKTtcbiAgICAgICAgdGhpcy5fc3VwZXIgPSBST09UO1xuICAgICAgICBpbml0aWFsaXplR3VpZCh0aGlzKTtcbiAgICAgICAgdGhpcy5pbml0KCk7XG4gICAgfVxuICAgIHN0YXRpYyBleHRlbmQoLi4uZXh0ZW5zaW9ucykge1xuICAgICAgICByZXR1cm4gZXh0ZW5kQ2xhc3ModGhpcywgLi4uZXh0ZW5zaW9ucyk7XG4gICAgfVxuICAgIHN0YXRpYyBjcmVhdGUoYXR0cnMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyB0aGlzKGF0dHJzKTtcbiAgICB9XG4gICAgc3RhdGljIHJlb3BlbihleHRlbnNpb25zKSB7XG4gICAgICAgIHRvTWl4aW4oZXh0ZW5zaW9ucykuZXh0ZW5kUHJvdG90eXBlKHRoaXMpO1xuICAgICAgICB0aGlzW0NMQVNTX01FVEFdLnNlYWwoKTtcbiAgICAgICAgcmVsaW5rU3ViY2xhc3Nlcyh0aGlzKTtcbiAgICB9XG4gICAgc3RhdGljIHJlb3BlbkNsYXNzKGV4dGVuc2lvbnMpIHtcbiAgICAgICAgdG9NaXhpbihleHRlbnNpb25zKS5leHRlbmRTdGF0aWModGhpcyk7XG4gICAgICAgIHRoaXNbQ0xBU1NfTUVUQV0uc2VhbCgpO1xuICAgIH1cbiAgICBzdGF0aWMgbWV0YUZvclByb3BlcnR5KHByb3BlcnR5KSB7XG4gICAgICAgIGxldCB2YWx1ZSA9IHRoaXNbQ0xBU1NfTUVUQV0ubWV0YWRhdGFGb3JQcm9wZXJ0eShwcm9wZXJ0eSk7XG4gICAgICAgIGlmICghdmFsdWUpIHRocm93IG5ldyBFcnJvcihgbWV0YUZvclByb3BlcnR5KCkgY291bGQgbm90IGZpbmQgYSBjb21wdXRlZCBwcm9wZXJ0eSB3aXRoIGtleSAnJHtwcm9wZXJ0eX0nLmApO1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICAgIHN0YXRpYyBlYWNoQ29tcHV0ZWRQcm9wZXJ0eShjYWxsYmFjaykge1xuICAgICAgICBsZXQgbWV0YWRhdGEgPSB0aGlzW0NMQVNTX01FVEFdLmdldFByb3BlcnR5TWV0YWRhdGEoKTtcbiAgICAgICAgaWYgKCFtZXRhZGF0YSkgcmV0dXJuO1xuICAgICAgICBmb3IgKGxldCBwcm9wIGluIG1ldGFkYXRhKSB7XG4gICAgICAgICAgICBjYWxsYmFjayhwcm9wLCBtZXRhZGF0YVtwcm9wXSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaW5pdCgpIHt9XG4gICAgZ2V0KGtleSkge1xuICAgICAgICByZXR1cm4gdGhpc1trZXldO1xuICAgIH1cbiAgICBzZXQoa2V5LCB2YWx1ZSkge1xuICAgICAgICB0aGlzW2tleV0gPSB2YWx1ZTtcbiAgICB9XG4gICAgc2V0UHJvcGVydGllcyhhdHRycykge1xuICAgICAgICBhc3NpZ24odGhpcywgYXR0cnMpO1xuICAgIH1cbiAgICBkZXN0cm95KCkge31cbn1cbkdsaW1tZXJPYmplY3RbXCJkZjhiZTRjOC00ZTg5LTQ0ZTItYThmOS01NTBjOGRhY2RjYTdcIl0gPSBJbnN0YW5jZU1ldGEuZnJvbVBhcmVudChudWxsKTtcbkdsaW1tZXJPYmplY3QuaXNDbGFzcyA9IHRydWU7Il19