ember-legacy-class-transform
Version:
The default blueprint for ember-cli addons.
405 lines (326 loc) • 43.1 kB
JavaScript
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); }
import { Meta, PropertyReference } from '@glimmer/object-reference';
import { dict, assign, initializeGuid } from '@glimmer/util';
import { extend as extendClass, toMixin, relinkSubclasses, wrapMethod } from './mixin';
var isArray = Array.isArray;
import { ROOT } from './utils';
export var EMPTY_CACHE = function EMPTY_CACHE() {};
var CLASS_META = "df8be4c8-4e89-44e2-a8f9-550c8dacdca7";
export 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;
}(Meta);
export var ClassMeta = function () {
function ClassMeta() {
_classCallCheck(this, ClassMeta);
this.referenceTypes = dict();
this.propertyMetadata = dict();
this.concatenatedProperties = dict();
this.hasConcatenatedProperties = false;
this.mergedProperties = 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 = assign({}, mergedProps[_prop]);
object[_prop] = 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 = dict();
this.propertyMetadata = dict();
this.concatenatedProperties = dict();
this.mergedProperties = 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] = assign({}, parent.mergedProperties[_prop2]);
}
assign(this.referenceTypes, parent.referenceTypes);
assign(this.propertyMetadata, parent.propertyMetadata);
}
};
ClassMeta.prototype.reseal = function reseal(obj) {
var meta = Meta.for(obj);
var fresh = new this.InstanceMetaConstructor(obj, {});
var referenceTypes = meta.getReferenceTypes();
var slots = meta.getSlots();
turbocharge(assign(referenceTypes, this.referenceTypes));
turbocharge(assign(slots, fresh.getSlots()));
};
ClassMeta.prototype.seal = function seal() {
var referenceTypes = turbocharge(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] || PropertyReference;
};
_class.prototype.getSlots = function getSlots() {
return this.slots;
};
return _class;
}(SealedMeta);
turbocharge(this);
};
return ClassMeta;
}();
function mergeMergedProperties(attrs, parent) {
var merged = assign({}, parent);
for (var prop in attrs) {
if (prop in parent && typeof parent[prop] === 'function' && typeof attrs[prop] === 'function') {
var wrapped = wrapMethod(parent, prop, attrs[prop]);
merged[prop] = wrapped;
} else {
merged[prop] = attrs[prop];
}
}
return merged;
}
export var 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 = ROOT;
this._meta = null;
if (attrs) assign(this, attrs);
this.constructor[CLASS_META].init(this, attrs || null);
this._super = ROOT;
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 extendClass.apply(undefined, [this].concat(extensions));
};
GlimmerObject.create = function create(attrs) {
return new this(attrs);
};
GlimmerObject.reopen = function reopen(extensions) {
toMixin(extensions).extendPrototype(this);
this[CLASS_META].seal();
relinkSubclasses(this);
};
GlimmerObject.reopenClass = function reopenClass(extensions) {
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) {
assign(this, attrs);
};
GlimmerObject.prototype.destroy = function destroy() {};
return GlimmerObject;
}();
export default GlimmerObject;
GlimmerObject["df8be4c8-4e89-44e2-a8f9-550c8dacdca7"] = InstanceMeta.fromParent(null);
GlimmerObject.isClass = true;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9vYmplY3QuanMiXSwibmFtZXMiOlsiTWV0YSIsIlByb3BlcnR5UmVmZXJlbmNlIiwiZGljdCIsImFzc2lnbiIsImluaXRpYWxpemVHdWlkIiwiZXh0ZW5kIiwiZXh0ZW5kQ2xhc3MiLCJ0b01peGluIiwicmVsaW5rU3ViY2xhc3NlcyIsIndyYXBNZXRob2QiLCJpc0FycmF5IiwiQXJyYXkiLCJST09UIiwiRU1QVFlfQ0FDSEUiLCJDTEFTU19NRVRBIiwidHVyYm9jaGFyZ2UiLCJvYmoiLCJTZWFsZWRNZXRhIiwiYWRkUmVmZXJlbmNlVHlwZUZvciIsIkVycm9yIiwiQ2xhc3NNZXRhIiwicmVmZXJlbmNlVHlwZXMiLCJwcm9wZXJ0eU1ldGFkYXRhIiwiY29uY2F0ZW5hdGVkUHJvcGVydGllcyIsImhhc0NvbmNhdGVuYXRlZFByb3BlcnRpZXMiLCJtZXJnZWRQcm9wZXJ0aWVzIiwiaGFzTWVyZ2VkUHJvcGVydGllcyIsIm1peGlucyIsImFwcGxpZWRNaXhpbnMiLCJzdGF0aWNNaXhpbnMiLCJzdWJjbGFzc2VzIiwic2xvdHMiLCJJbnN0YW5jZU1ldGFDb25zdHJ1Y3RvciIsImZyb21QYXJlbnQiLCJwYXJlbnQiLCJtZXRhIiwicmVzZXQiLCJmb3IiLCJvYmplY3QiLCJjb25zdHJ1Y3RvciIsImluaXQiLCJhdHRycyIsImNvbmNhdFByb3BzIiwicHJvcCIsImNvbmNhdCIsInNsaWNlIiwibWVyZ2VkUHJvcHMiLCJtZXJnZWQiLCJhZGRTdGF0aWNNaXhpbiIsIm1peGluIiwicHVzaCIsImFkZE1peGluIiwiZ2V0U3RhdGljTWl4aW5zIiwiZ2V0TWl4aW5zIiwiYWRkQXBwbGllZE1peGluIiwiaGFzQXBwbGllZE1peGluIiwiaW5kZXhPZiIsImdldEFwcGxpZWRNaXhpbnMiLCJoYXNTdGF0aWNNaXhpbiIsImFwcGx5QWxsTWl4aW5zIiwiU3ViY2xhc3MiLCJQYXJlbnQiLCJmb3JFYWNoIiwibSIsImV4dGVuZFByb3RvdHlwZU9udG8iLCJleHRlbmRTdGF0aWMiLCJzZWFsIiwiYWRkU3ViY2xhc3MiLCJnZXRTdWJjbGFzc2VzIiwiYWRkUHJvcGVydHlNZXRhZGF0YSIsInByb3BlcnR5IiwidmFsdWUiLCJtZXRhZGF0YUZvclByb3BlcnR5IiwidHlwZSIsImFkZFNsb3RGb3IiLCJoYXNDb25jYXRlbmF0ZWRQcm9wZXJ0eSIsImdldENvbmNhdGVuYXRlZFByb3BlcnR5IiwiZ2V0Q29uY2F0ZW5hdGVkUHJvcGVydGllcyIsIk9iamVjdCIsImtleXMiLCJhZGRDb25jYXRlbmF0ZWRQcm9wZXJ0eSIsInZhbCIsImhhc01lcmdlZFByb3BlcnR5IiwiZ2V0TWVyZ2VkUHJvcGVydHkiLCJnZXRNZXJnZWRQcm9wZXJ0aWVzIiwiYWRkTWVyZ2VkUHJvcGVydHkiLCJKU09OIiwic3RyaW5naWZ5IiwibWVyZ2VNZXJnZWRQcm9wZXJ0aWVzIiwiZ2V0UmVmZXJlbmNlVHlwZXMiLCJnZXRQcm9wZXJ0eU1ldGFkYXRhIiwicmVzZWFsIiwiZnJlc2giLCJnZXRTbG90cyIsIlNsb3RzIiwibmFtZSIsImFyZ3VtZW50cyIsInJlZmVyZW5jZVR5cGVGb3IiLCJ3cmFwcGVkIiwiSW5zdGFuY2VNZXRhIiwiR2xpbW1lck9iamVjdCIsIl9zdXBlciIsIl9tZXRhIiwiZXh0ZW5zaW9ucyIsImNyZWF0ZSIsInJlb3BlbiIsImV4dGVuZFByb3RvdHlwZSIsInJlb3BlbkNsYXNzIiwibWV0YUZvclByb3BlcnR5IiwiZWFjaENvbXB1dGVkUHJvcGVydHkiLCJjYWxsYmFjayIsIm1ldGFkYXRhIiwiZ2V0Iiwia2V5Iiwic2V0Iiwic2V0UHJvcGVydGllcyIsImRlc3Ryb3kiLCJpc0NsYXNzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUFBLFNBQVNBLElBQVQsRUFBZUMsaUJBQWYsUUFBd0MsMkJBQXhDO0FBQ0EsU0FBU0MsSUFBVCxFQUFlQyxNQUFmLEVBQXVCQyxjQUF2QixRQUE2QyxlQUE3QztBQUNBLFNBQVNDLFVBQVVDLFdBQW5CLEVBQWdDQyxPQUFoQyxFQUF5Q0MsZ0JBQXpDLEVBQTJE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QS9DS2hCLGE7O0FBaURyQkEsY0FBYyxzQ0FBZCxJQUF3REQsYUFBYWxFLFVBQWIsQ0FBd0IsSUFBeEIsQ0FBeEQ7QUFDQW1FLGNBQWNpQixPQUFkLEdBQXdCLElBQXhCIiwiZmlsZSI6ImxpYi9vYmplY3QuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBNZXRhLCBQcm9wZXJ0eVJlZmVyZW5jZSB9IGZyb20gJ0BnbGltbWVyL29iamVjdC1yZWZlcmVuY2UnO1xuaW1wb3J0IHsgZGljdCwgYXNzaWduLCBpbml0aWFsaXplR3VpZCB9IGZyb20gJ0BnbGltbWVyL3V0aWwnO1xuaW1wb3J0IHsgZXh0ZW5kIGFzIGV4dGVuZENsYXNzLCB0b01peGluLCByZWxpbmtTdWJjbGFzc2VzLCB3cmFwTWV0aG9kIH0gZnJvbSAnLi9taXhpbic7XG5jb25zdCB7IGlzQXJyYXkgfSA9IEFycmF5O1xuaW1wb3J0IHsgUk9PVCB9IGZyb20gJy4vdXRpbHMnO1xuZXhwb3J0IGNvbnN0IEVNUFRZX0NBQ0hFID0gZnVuY3Rpb24gRU1QVFlfQ0FDSEUoKSB7fTtcbmNvbnN0IENMQVNTX01FVEEgPSBcImRmOGJlNGM4LTRlODktNDRlMi1hOGY5LTU1MGM4ZGFjZGNhN1wiO1xuZXhwb3J0IGZ1bmN0aW9uIHR1cmJvY2hhcmdlKG9iaikge1xuICAgIC8vIGZ1bmN0aW9uIER1bW15KCkge31cbiAgICAvLyBEdW1teS5wcm90b3R5cGUgPSBvYmo7XG4gICAgcmV0dXJuIG9iajtcbn1cbmNsYXNzIFNlYWxlZE1ldGEgZXh0ZW5kcyBNZXRhIHtcbiAgICBhZGRSZWZlcmVuY2VUeXBlRm9yKC4uLl9hcmdzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBtb2RpZnkgcmVmZXJlbmNlIHR5cGVzIG9uIGEgc2VhbGVkIG1ldGFcIik7XG4gICAgfVxufVxuZXhwb3J0IGNsYXNzIENsYXNzTWV0YSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMucmVmZXJlbmNlVHlwZXMgPSBkaWN0KCk7XG4gICAgICAgIHRoaXMucHJvcGVydHlNZXRhZGF0YSA9IGRpY3QoKTtcbiAgICAgICAgdGhpcy5jb25jYXRlbmF0ZWRQcm9wZXJ0aWVzID0gZGljdCgpO1xuICAgICAgICB0aGlzLmhhc0NvbmNhdGVuYXRlZFByb3BlcnRpZXMgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5tZXJnZWRQcm9wZXJ0aWVzID0gZGljdCgpO1xuICAgICAgICB0aGlzLmhhc01lcmdlZFByb3BlcnRpZXMgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5taXhpbnMgPSBbXTtcbiAgICAgICAgdGhpcy5hcHBsaWVkTWl4aW5zID0gW107XG4gICAgICAgIHRoaXMuc3RhdGljTWl4aW5zID0gW107XG4gICAgICAgIHRoaXMuc3ViY2xhc3NlcyA9IFtdO1xuICAgICAgICB0aGlzLnNsb3RzID0gW107XG4gICAgICAgIHRoaXMuSW5zdGFuY2VNZXRhQ29uc3RydWN0b3IgPSBudWxsO1xuICAgIH1cbiAgICBzdGF0aWMgZnJvbVBhcmVudChwYXJlbnQpIHtcbiAgICAgICAgbGV0IG1ldGEgPSBuZXcgdGhpcygpO1xuICAgICAgICBtZXRhLnJlc2V0KHBhcmVudCk7XG4gICAgICAgIHJldHVybiBtZXRhO1xuICAgIH1cbiAgICBzdGF0aWMgZm9yKG9iamVjdCkge1xuICAgICAgICBpZiAoQ0xBU1NfTUVUQSBpbiBvYmplY3QpIHJldHVybiBvYmplY3RbQ0xBU1NfTUVUQV07ZWxzZSBpZiAob2JqZWN0LmNvbnN0cnVjdG9yKSByZXR1cm4gb2JqZWN0LmNvbnN0cnVjdG9yW0NMQVNTX01FVEFdIHx8IG51bGw7ZWxzZSByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaW5pdChvYmplY3QsIGF0dHJzKSB7XG4gICAgICAgIGlmICh0eXBlb2YgYXR0cnMgIT09ICdvYmplY3QnIHx8IGF0dHJzID09PSBudWxsKSByZXR1cm47XG4gICAgICAgIGlmICh0aGlzLmhhc0NvbmNhdGVuYXRlZFByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgIGxldCBjb25jYXRQcm9wcyA9IHRoaXMuY29uY2F0ZW5hdGVkUHJvcGVydGllcztcbiAgICAgICAgICAgIGZvciAobGV0IHByb3AgaW4gY29uY2F0UHJvcHMpIHtcbiAgICAgICAgICAgICAgICBpZiAocHJvcCBpbiBhdHRycykge1xuICAgICAgICAgICAgICAgICAgICBsZXQgY29uY2F0ID0gY29uY2F0UHJvcHNbcHJvcF0uc2xpY2UoKTtcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0W3Byb3BdID0gY29uY2F0LmNvbmNhdChhdHRyc1twcm9wXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmhhc01lcmdlZFByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgIGxldCBtZXJnZWRQcm9wcyA9IHRoaXMubWVyZ2VkUHJvcGVydGllcztcbiAgICAgICAgICAgIGZvciAobGV0IHByb3AgaW4gbWVyZ2VkUHJvcHMpIHtcbiAgICAgICAgICAgICAgICBpZiAocHJvcCBpbiBhdHRycykge1xuICAgICAgICAgICAgICAgICAgICBsZXQgbWVyZ2VkID0gYXNzaWduKHt9LCBtZXJnZWRQcm9wc1twcm9wXSk7XG4gICAgICAgICAgICAgICAgICAgIG9iamVjdFtwcm9wXSA9IGFzc2lnbihtZXJnZWQsIGF0dHJzW3Byb3BdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgYWRkU3RhdGljTWl4aW4obWl4aW4pIHtcbiAgICAgICAgdGhpcy5zdGF0aWNNaXhpbnMucHVzaChtaXhpbik7XG4gICAgfVxuICAgIGFkZE1peGluKG1peGluKSB7XG4gICAgICAgIHRoaXMubWl4aW5zLnB1c2gobWl4aW4pO1xuICAgIH1cbiAgICBnZXRTdGF0aWNNaXhpbnMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0YXRpY01peGlucztcbiAgICB9XG4gICAgZ2V0TWl4aW5zKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5taXhpbnM7XG4gICAgfVxuICAgIGFkZEFwcGxpZWRNaXhpbihtaXhpbikge1xuICAgICAgICB0aGlzLmFwcGxpZWRNaXhpbnMucHVzaChtaXhpbik7XG4gICAgfVxuICAgIGhhc0FwcGxpZWRNaXhpbihtaXhpbikge1xuICAgICAgICByZXR1cm4gdGhpcy5hcHBsaWVkTWl4aW5zLmluZGV4T2YobWl4aW4pICE9PSAtMTtcbiAgICB9XG4gICAgZ2V0QXBwbGllZE1peGlucygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXBwbGllZE1peGlucztcbiAgICB9XG4gICAgaGFzU3RhdGljTWl4aW4obWl4aW4pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhdGljTWl4aW5zLmluZGV4T2YobWl4aW4pICE9PSAtMTtcbiAgICB9XG4gICAgc3RhdGljIGFwcGx5QWxsTWl4aW5zKFN1YmNsYXNzLCBQYXJlbnQpIHtcbiAgICAgICAgU3ViY2xhc3NbQ0xBU1NfTUVUQV0uZ2V0TWl4aW5zKCkuZm9yRWFjaChtID0+IG0uZXh0ZW5kUHJvdG90eXBlT250byhTdWJjbGFzcywgUGFyZW50KSk7XG4gICAgICAgIFN1YmNsYXNzW0NMQVNTX01FVEFdLmdldFN0YXRpY01peGlucygpLmZvckVhY2gobSA9PiBtLmV4dGVuZFN0YXRpYyhTdWJjbGFzcykpO1xuICAgICAgICBTdWJjbGFzc1tDTEFTU19NRVRBXS5zZWFsKCk7XG4gICAgfVxuICAgIGFkZFN1YmNsYXNzKGNvbnN0cnVjdG9yKSB7XG4gICAgICAgIHRoaXMuc3ViY2xhc3Nlcy5wdXNoKGNvbnN0cnVjdG9yKTtcbiAgICB9XG4gICAgZ2V0U3ViY2xhc3NlcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3ViY2xhc3NlcztcbiAgICB9XG4gICAgYWRkUHJvcGVydHlNZXRhZGF0YShwcm9wZXJ0eSwgdmFsdWUpIHtcbiAgICAgICAgdGhpcy5wcm9wZXJ0eU1ldGFkYXRhW3Byb3BlcnR5XSA9IHZhbHVlO1xuICAgIH1cbiAgICBtZXRhZGF0YUZvclByb3BlcnR5KHByb3BlcnR5KSB7XG4gICAgICAgIHJldHVybiB0aGlzLnByb3BlcnR5TWV0YWRhdGFbcHJvcGVydHldO1xuICAgIH1cbiAgICBhZGRSZWZlcmVuY2VUeXBlRm9yKHByb3BlcnR5LCB0eXBlKSB7XG4gICAgICAgIHRoaXMucmVmZXJlbmNlVHlwZXNbcHJvcGVydHldID0gdHlwZTtcbiAgICB9XG4gICAgYWRkU2xvdEZvcihwcm9wZXJ0eSkge1xuICAgICAgICB0aGlzLnNsb3RzLnB1c2gocHJvcGVydHkpO1xuICAgIH1cbiAgICBoYXNDb25jYXRlbmF0ZWRQcm9wZXJ0eShwcm9wZXJ0eSkge1xuICAgICAgICBpZiAoIXRoaXMuaGFzQ29uY2F0ZW5hdGVkUHJvcGVydGllcykgcmV0dXJuIGZhbHNlO1xuICAgICAgICByZXR1cm4gcHJvcGVydHkgaW4gdGhpcy5jb25jYXRlbmF0ZWRQcm9wZXJ0aWVzO1xuICAgIH1cbiAgICBnZXRDb25jYXRlbmF0ZWRQcm9wZXJ0eShwcm9wZXJ0eSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25jYXRlbmF0ZWRQcm9wZXJ0aWVzW3Byb3BlcnR5XTtcbiAgICB9XG4gICAgZ2V0Q29uY2F0ZW5hdGVkUHJvcGVydGllcygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuY29uY2F0ZW5hdGVkUHJvcGVydGllcyk7XG4gICAgfVxuICAgIGFkZENvbmNhdGVuYXRlZFByb3BlcnR5KHByb3BlcnR5LCB2YWx1ZSkge1xuICAgICAgICB0aGlzLmhhc0NvbmNhdGVuYXRlZFByb3BlcnRpZXMgPSB0cnVlO1xuICAgICAgICBpZiAocHJvcGVydHkgaW4gdGhpcy5jb25jYXRlbmF0ZWRQcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICBsZXQgdmFsID0gdGhpcy5jb25jYXRlbmF0ZWRQcm9wZXJ0aWVzW3Byb3BlcnR5XS5jb25jYXQodmFsdWUpO1xuICAgICAgICAgICAgdGhpcy5jb25jYXRlbmF0ZWRQcm9wZXJ0aWVzW3Byb3BlcnR5XSA9IHZhbDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY29uY2F0ZW5hdGVkUHJvcGVydGllc1twcm9wZXJ0eV0gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBoYXNNZXJnZWRQcm9wZXJ0eShwcm9wZXJ0eSkge1xuICAgICAgICBpZiAoIXRoaXMuaGFzTWVyZ2VkUHJvcGVydGllcykgcmV0dXJuIGZhbHNlO1xuICAgICAgICByZXR1cm4gcHJvcGVydHkgaW4gdGhpcy5tZXJnZWRQcm9wZXJ0aWVzO1xuICAgIH1cbiAgICBnZXRNZXJnZWRQcm9wZXJ0eShwcm9wZXJ0eSkge1xuICAgICAgICByZXR1cm4gdGhpcy5tZXJnZWRQcm9wZXJ0aWVzW3Byb3BlcnR5XTtcbiAgICB9XG4gICAgZ2V0TWVyZ2VkUHJvcGVydGllcygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMubWVyZ2VkUHJvcGVydGllcyk7XG4gICAgfVxuICAgIGFkZE1lcmdlZFByb3BlcnR5KHByb3BlcnR5LCB2YWx1ZSkge1xuICAgICAgICB0aGlzLmhhc01lcmdlZFByb3BlcnRpZXMgPSB0cnVlO1xuICAgICAgICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgWW91IHBhc3NlZCBpbiBcXGAke0pTT04uc3RyaW5naWZ5KHZhbHVlKX1cXGAgYXMgdGhlIHZhbHVlIGZvciBcXGBmb29cXGAgYnV0IFxcYGZvb1xcYCBjYW5ub3QgYmUgYW4gQXJyYXlgKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocHJvcGVydHkgaW4gdGhpcy5tZXJnZWRQcm9wZXJ0aWVzICYmIHRoaXMubWVyZ2VkUHJvcGVydGllc1twcm9wZXJ0eV0gJiYgdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMubWVyZ2VkUHJvcGVydGllc1twcm9wZXJ0eV0gPSBtZXJnZU1lcmdlZFByb3BlcnRpZXModmFsdWUsIHRoaXMubWVyZ2VkUHJvcGVydGllc1twcm9wZXJ0eV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZSA9PT0gbnVsbCA/IHZhbHVlIDogdmFsdWUgfHwge307XG4gICAgICAgICAgICB0aGlzLm1lcmdlZFByb3BlcnRpZXNbcHJvcGVydHldID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0UmVmZXJlbmNlVHlwZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlZmVyZW5jZVR5cGVzO1xuICAgIH1cbiAgICBnZXRQcm9wZXJ0eU1ldGFkYXRhKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9wZXJ0eU1ldGFkYXRhO1xuICAgIH1cbiAgICByZXNldChwYXJlbnQpIHtcbiAgICAgICAgdGhpcy5yZWZlcmVuY2VUeXBlcyA9IGRpY3QoKTtcbiAgICAgICAgdGhpcy5wcm9wZXJ0eU1ldGFkYXRhID0gZGljdCgpO1xuICAgICAgICB0aGlzLmNvbmNhdGVuYXRlZFByb3BlcnRpZXMgPSBkaWN0KCk7XG4gICAgICAgIHRoaXMubWVyZ2VkUHJvcGVydGllcyA9IGRpY3QoKTtcbiAgICAgICAgaWYgKHBhcmVudCkge1xuICAgICAgICAgICAgdGhpcy5oYXNDb25jYXRlbmF0ZWRQcm9wZXJ0aWVzID0gcGFyZW50Lmhhc0NvbmNhdGVuYXRlZFByb3BlcnRpZXM7XG4gICAgICAgICAgICBmb3IgKGxldCBwcm9wIGluIHBhcmVudC5jb25jYXRlbmF0ZWRQcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb25jYXRlbmF0ZWRQcm9wZXJ0aWVzW3Byb3BdID0gcGFyZW50LmNvbmNhdGVuYXRlZFByb3BlcnRpZXNbcHJvcF0uc2xpY2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuaGFzTWVyZ2VkUHJvcGVydGllcyA9IHBhcmVudC5oYXNNZXJnZWRQcm9wZXJ0aWVzO1xuICAgICAgICAgICAgZm9yIChsZXQgcHJvcCBpbiBwYXJlbnQubWVyZ2VkUHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgIHRoaXMubWVyZ2VkUHJvcGVydGllc1twcm9wXSA9IGFzc2lnbih7fSwgcGFyZW50Lm1lcmdlZFByb3BlcnRpZXNbcHJvcF0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXNzaWduKHRoaXMucmVmZXJlbmNlVHlwZXMsIHBhcmVudC5yZWZlcmVuY2VUeXBlcyk7XG4gICAgICAgICAgICBhc3NpZ24odGhpcy5wcm9wZXJ0eU1ldGFkYXRhLCBwYXJlbnQucHJvcGVydHlNZXRhZGF0YSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmVzZWFsKG9iaikge1xuICAgICAgICBsZXQgbWV0YSA9IE1ldGEuZm9yKG9iaik7XG4gICAgICAgIGxldCBmcmVzaCA9IG5ldyB0aGlzLkluc3RhbmNlTWV0YUNvbnN0cnVjdG9yKG9iaiwge30pO1xuICAgICAgICBsZXQgcmVmZXJlbmNlVHlwZXMgPSBtZXRhLmdldFJlZmVyZW5jZVR5cGVzKCk7XG4gICAgICAgIGxldCBzbG90cyA9IG1ldGEuZ2V0U2xvdHMoKTtcbiAgICAgICAgdHVyYm9jaGFyZ2UoYXNzaWduKHJlZmVyZW5jZVR5cGVzLCB0aGlzLnJlZmVyZW5jZVR5cGVzKSk7XG4gICAgICAgIHR1cmJvY2hhcmdlKGFzc2lnbihzbG90cywgZnJlc2guZ2V0U2xvdHMoKSkpO1xuICAgIH1cbiAgICBzZWFsKCkge1xuICAgICAgICBsZXQgcmVmZXJlbmNlVHlwZXMgPSB0dXJib2NoYXJnZShhc3NpZ24oe30sIHRoaXMucmVmZXJlbmNlVHlwZXMpKTtcbiAgICAgICAgdHVyYm9jaGFyZ2UodGhpcy5jb25jYXRlbmF0ZWRQcm9wZXJ0aWVzKTtcbiAgICAgICAgdHVyYm9jaGFyZ2UodGhpcy5tZXJnZWRQcm9wZXJ0aWVzKTtcbiAgICAgICAgaWYgKCF0aGlzLmhhc01lcmdlZFByb3BlcnRpZXMgJiYgIXRoaXMuaGFzQ29uY2F0ZW5hdGVkUHJvcGVydGllcykge1xuICAgICAgICAgICAgdGhpcy5pbml0ID0gZnVuY3Rpb24gKCkge307XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHNsb3RzID0gdGhpcy5zbG90cztcbiAgICAgICAgY2xhc3MgU2xvdHMge1xuICAgICAgICAgICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgICAgICAgICAgc2xvdHMuZm9yRWFjaChuYW1lID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpc1tuYW1lXSA9IEVNUFRZX0NBQ0hFO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuSW5zdGFuY2VNZXRhQ29uc3RydWN0b3IgPSBjbGFzcyBleHRlbmRzIFNlYWxlZE1ldGEge1xuICAgICAgICAgICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgICAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNsb3RzID0gbmV3IFNsb3RzKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZWZlcmVuY2VUeXBlcyA9IHJlZmVyZW5jZVR5cGVzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZ2V0UmVmZXJlbmNlVHlwZXMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVmZXJlbmNlVHlwZXM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZWZlcmVuY2VUeXBlRm9yKHByb3BlcnR5KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVmZXJlbmNlVHlwZXNbcHJvcGVydHldIHx8IFByb3BlcnR5UmVmZXJlbmNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZ2V0U2xvdHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2xvdHM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHR1cmJvY2hhcmdlKHRoaXMpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIG1lcmdlTWVyZ2VkUHJvcGVydGllcyhhdHRycywgcGFyZW50KSB7XG4gICAgbGV0IG1lcmdlZCA9IGFzc2lnbih7fSwgcGFyZW50KTtcbiAgICBmb3IgKGxldCBwcm9wIGluIGF0dHJzKSB7XG4gICAgICAgIGlmIChwcm9wIGluIHBhcmVudCAmJiB0eXBlb2YgcGFyZW50W3Byb3BdID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBhdHRyc1twcm9wXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgbGV0IHdyYXBwZWQgPSB3cmFwTWV0aG9kKHBhcmVudCwgcHJvcCwgYXR0cnNbcHJvcF0pO1xuICAgICAgICAgICAgbWVyZ2VkW3Byb3BdID0gd3JhcHBlZDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG1lcmdlZFtwcm9wXSA9IGF0dHJzW3Byb3BdO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBtZXJnZWQ7XG59XG5leHBvcnQgY2xhc3MgSW5zdGFuY2VNZXRhIGV4dGVuZHMgQ2xhc3NNZXRhIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpc1tcImRmOGJlNGM4LTRlODktNDRlMi1hOGY5LTU1MGM4ZGFjZGNhN1wiXSA9IENsYXNzTWV0YS5mcm9tUGFyZW50KG51bGwpO1xuICAgIH1cbiAgICBzdGF0aWMgZnJvbVBhcmVudChwYXJlbnQpIHtcbiAgICAgICAgcmV0dXJuIHN1cGVyLmZyb21QYXJlbnQocGFyZW50KTtcbiAgICB9XG4gICAgcmVzZXQocGFyZW50KSB7XG4gICAgICAgIHN1cGVyLnJlc2V0KHBhcmVudCk7XG4gICAgICAgIGlmIChwYXJlbnQpIHRoaXNbQ0xBU1NfTUVUQV0ucmVzZXQocGFyZW50W0NMQVNTX01FVEFdKTtcbiAgICB9XG4gICAgc2VhbCgpIHtcbiAgICAgICAgc3VwZXIuc2VhbCgpO1xuICAgICAgICB0aGlzW0NMQVNTX01FVEFdLnNlYWwoKTtcbiAgICB9XG59XG5leHBvcnQgZGVmYXVsdCBjbGFzcyBHbGltbWVyT2JqZWN0IHtcbiAgICBjb25zdHJ1Y3RvcihhdHRycykge1xuICAgICAgICB0aGlzLl9zdXBlciA9IFJPT1Q7XG4gICAgICAgIHRoaXMuX21ldGEgPSBudWxsO1xuICAgICAgICBpZiAoYXR0cnMpIGFzc2lnbih0aGlzLCBhdHRycyk7XG4gICAgICAgIHRoaXMuY29uc3RydWN0b3JbQ0xBU1NfTUVUQV0uaW5pdCh0aGlzLCBhdHRycyB8fCBudWxsKTtcbiAgICAgICAgdGhpcy5fc3VwZXIgPSBST09UO1xuICAgICAgICBpbml0aWFsaXplR3VpZCh0aGlzKTtcbiAgICAgICAgdGhpcy5pbml0KCk7XG4gICAgfVxuICAgIHN0YXRpYyBleHRlbmQoLi4uZXh0ZW5zaW9ucykge1xuICAgICAgICByZXR1cm4gZXh0ZW5kQ2xhc3ModGhpcywgLi4uZXh0ZW5zaW9ucyk7XG4gICAgfVxuICAgIHN0YXRpYyBjcmVhdGUoYXR0cnMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyB0aGlzKGF0dHJzKTtcbiAgICB9XG4gICAgc3RhdGljIHJlb3BlbihleHRlbnNpb25zKSB7XG4gICAgICAgIHRvTWl4aW4oZXh0ZW5zaW9ucykuZXh0ZW5kUHJvdG90eXBlKHRoaXMpO1xuICAgICAgICB0aGlzW0NMQVNTX01FVEFdLnNlYWwoKTtcbiAgICAgICAgcmVsaW5rU3ViY2xhc3Nlcyh0aGlzKTtcbiAgICB9XG4gICAgc3RhdGljIHJlb3BlbkNsYXNzKGV4dGVuc2lvbnMpIHtcbiAgICAgICAgdG9NaXhpbihleHRlbnNpb25zKS5leHRlbmRTdGF0aWModGhpcyk7XG4gICAgICAgIHRoaXNbQ0xBU1NfTUVUQV0uc2VhbCgpO1xuICAgIH1cbiAgICBzdGF0aWMgbWV0YUZvclByb3BlcnR5KHByb3BlcnR5KSB7XG4gICAgICAgIGxldCB2YWx1ZSA9IHRoaXNbQ0xBU1NfTUVUQV0ubWV0YWRhdGFGb3JQcm9wZXJ0eShwcm9wZXJ0eSk7XG4gICAgICAgIGlmICghdmFsdWUpIHRocm93IG5ldyBFcnJvcihgbWV0YUZvclByb3BlcnR5KCkgY291bGQgbm90IGZpbmQgYSBjb21wdXRlZCBwcm9wZXJ0eSB3aXRoIGtleSAnJHtwcm9wZXJ0eX0nLmApO1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICAgIHN0YXRpYyBlYWNoQ29tcHV0ZWRQcm9wZXJ0eShjYWxsYmFjaykge1xuICAgICAgICBsZXQgbWV0YWRhdGEgPSB0aGlzW0NMQVNTX01FVEFdLmdldFByb3BlcnR5TWV0YWRhdGEoKTtcbiAgICAgICAgaWYgKCFtZXRhZGF0YSkgcmV0dXJuO1xuICAgICAgICBmb3IgKGxldCBwcm9wIGluIG1ldGFkYXRhKSB7XG4gICAgICAgICAgICBjYWxsYmFjayhwcm9wLCBtZXRhZGF0YVtwcm9wXSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaW5pdCgpIHt9XG4gICAgZ2V0KGtleSkge1xuICAgICAgICByZXR1cm4gdGhpc1trZXldO1xuICAgIH1cbiAgICBzZXQoa2V5LCB2YWx1ZSkge1xuICAgICAgICB0aGlzW2tleV0gPSB2YWx1ZTtcbiAgICB9XG4gICAgc2V0UHJvcGVydGllcyhhdHRycykge1xuICAgICAgICBhc3NpZ24odGhpcywgYXR0cnMpO1xuICAgIH1cbiAgICBkZXN0cm95KCkge31cbn1cbkdsaW1tZXJPYmplY3RbXCJkZjhiZTRjOC00ZTg5LTQ0ZTItYThmOS01NTBjOGRhY2RjYTdcIl0gPSBJbnN0YW5jZU1ldGEuZnJvbVBhcmVudChudWxsKTtcbkdsaW1tZXJPYmplY3QuaXNDbGFzcyA9IHRydWU7Il19