ember-legacy-class-transform
Version:
The default blueprint for ember-cli addons.
437 lines (371 loc) • 42.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.AccessorBlueprint = exports.DataBlueprint = exports.Mixin = exports.Blueprint = exports.Descriptor = exports.BLUEPRINT = exports.DESCRIPTOR = undefined;
exports.extend = extend;
exports.relinkSubclasses = relinkSubclasses;
exports.toMixin = toMixin;
exports.wrapMethod = wrapMethod;
var _objectReference = require("@glimmer/object-reference");
var _util = require("@glimmer/util");
var _object = require("./object");
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 _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);
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
var isArray = Array.isArray;
var DESCRIPTOR = exports.DESCRIPTOR = "5d90f84f-908e-4a42-9749-3d0f523c262c";
var BLUEPRINT = exports.BLUEPRINT = "8d97cf5f-db9e-48d8-a6b2-7a75b7170805";
var Descriptor = exports.Descriptor = function Descriptor() {
_classCallCheck(this, Descriptor);
this["5d90f84f-908e-4a42-9749-3d0f523c262c"] = true;
};
var Blueprint = exports.Blueprint = function Blueprint() {
_classCallCheck(this, Blueprint);
this["8d97cf5f-db9e-48d8-a6b2-7a75b7170805"] = true;
};
var Mixin = exports.Mixin = function () {
function Mixin(extensions, mixins) {
var _dependencies;
_classCallCheck(this, Mixin);
this.extensions = null;
this.concatenatedProperties = [];
this.mergedProperties = [];
this.dependencies = [];
this.reopen(extensions);
(_dependencies = this.dependencies).push.apply(_dependencies, mixins);
}
Mixin.create = function create() {
for (var _len = arguments.length, args = Array(_len), _key2 = 0; _key2 < _len; _key2++) {
args[_key2] = arguments[_key2];
}
var extensions = args[args.length - 1];
if (args.length === 0) {
return new this({}, []);
} else if (extensions instanceof Mixin) {
return new this({}, args);
} else {
var deps = args.slice(0, -1).map(toMixin);
return new this(extensions, deps);
}
};
Mixin.mixins = function mixins(obj) {
if (typeof obj !== 'object' || obj === null) return [];
var meta = _object.ClassMeta.for(obj);
if (!meta) return [];
return meta.getAppliedMixins();
};
Mixin.prototype.detect = function detect(obj) {
if (typeof obj !== 'object' || obj === null) return false;
if (obj instanceof Mixin) {
return obj.dependencies.indexOf(this) !== -1;
}
var meta = _object.ClassMeta.for(obj);
return !!meta && meta.hasAppliedMixin(this);
};
Mixin.prototype.reopen = function reopen(extensions) {
if (this.extensions) {
this.dependencies.push(toMixin(this.extensions));
}
if (typeof extensions === 'object' && 'concatenatedProperties' in extensions) {
var concat = void 0;
var rawConcat = extensions.concatenatedProperties;
if (isArray(rawConcat)) {
concat = rawConcat.slice();
} else if (rawConcat === null || rawConcat === undefined) {
concat = [];
} else {
concat = [rawConcat];
}
delete extensions.concatenatedProperties;
this.concatenatedProperties = concat;
}
if (typeof extensions === 'object' && 'mergedProperties' in extensions) {
var merged = void 0;
var rawMerged = extensions.mergedProperties;
if (isArray(rawMerged)) {
merged = rawMerged.slice();
} else if (rawMerged === null || rawMerged === undefined) {
merged = [];
} else {
merged = [rawMerged];
}
delete extensions.mergedProperties;
this.mergedProperties = merged;
}
var normalized = Object.keys(extensions).reduce(function (obj, key) {
var value = extensions[key];
switch (typeof value) {
case 'function':
obj[key] = new MethodBlueprint({ value: value });
break;
case 'object':
if (value && BLUEPRINT in value) {
obj[key] = value;
break;
}
/* falls through */
default:
obj[key] = new DataBlueprint({ value: value });
}
return obj;
}, (0, _util.dict)());
this.extensions = (0, _util.dict)();
(0, _util.assign)(this.extensions, (0, _object.turbocharge)(normalized));
};
Mixin.prototype.apply = function apply(target) {
var meta = target[_objectReference.CLASS_META] = target[_objectReference.CLASS_META] || new _object.ClassMeta();
this.dependencies.forEach(function (m) {
return m.apply(target);
});
this.mergeProperties(target, target, meta);
meta.addMixin(this);
meta.seal();
meta.reseal(target);
return target;
};
Mixin.prototype.extendPrototype = function extendPrototype(Original) {
Original.prototype = Object.create(Original.prototype);
this.dependencies.forEach(function (m) {
return m.extendPrototype(Original);
});
this.extendPrototypeOnto(Original, Original);
};
Mixin.prototype.extendPrototypeOnto = function extendPrototypeOnto(Subclass, Parent) {
this.dependencies.forEach(function (m) {
return m.extendPrototypeOnto(Subclass, Parent);
});
this.mergeProperties(Subclass.prototype, Parent.prototype, Subclass[_objectReference.CLASS_META]);
Subclass[_objectReference.CLASS_META].addMixin(this);
};
Mixin.prototype.extendStatic = function extendStatic(Target) {
this.dependencies.forEach(function (m) {
return m.extendStatic(Target);
});
this.mergeProperties(Target, Object.getPrototypeOf(Target), Target[_objectReference.CLASS_META][_objectReference.CLASS_META]);
Target[_objectReference.CLASS_META].addStaticMixin(this);
};
Mixin.prototype.mergeProperties = function mergeProperties(target, parent, meta) {
var _this = this;
if (meta.hasAppliedMixin(this)) return;
meta.addAppliedMixin(this);
this.mergedProperties.forEach(function (k) {
return meta.addMergedProperty(k, parent[k]);
});
this.concatenatedProperties.forEach(function (k) {
return meta.addConcatenatedProperty(k, []);
});
new ValueDescriptor({ value: meta.getConcatenatedProperties() }).define(target, 'concatenatedProperties');
new ValueDescriptor({ value: meta.getMergedProperties() }).define(target, 'mergedProperties');
Object.keys(this.extensions).forEach(function (key) {
var extension = _this.extensions[key];
var desc = extension.descriptor(target, key, meta);
desc.define(target, key, parent);
});
new ValueDescriptor({ value: _utils.ROOT }).define(target, '_super');
};
return Mixin;
}();
function extend(Parent) {
var Super = Parent;
var Subclass = function (_Super) {
_inherits(Subclass, _Super);
function Subclass() {
_classCallCheck(this, Subclass);
return _possibleConstructorReturn(this, _Super.apply(this, arguments));
}
return Subclass;
}(Super);
Subclass[_objectReference.CLASS_META] = _object.InstanceMeta.fromParent(Parent[_objectReference.CLASS_META]);
for (var _len2 = arguments.length, extensions = Array(_len2 > 1 ? _len2 - 1 : 0), _key3 = 1; _key3 < _len2; _key3++) {
extensions[_key3 - 1] = arguments[_key3];
}
var mixins = extensions.map(toMixin);
Parent[_objectReference.CLASS_META].addSubclass(Subclass);
mixins.forEach(function (m) {
return Subclass[_objectReference.CLASS_META].addMixin(m);
});
_object.ClassMeta.applyAllMixins(Subclass, Parent);
return Subclass;
}
function relinkSubclasses(Parent) {
Parent[_objectReference.CLASS_META].getSubclasses().forEach(function (Subclass) {
Subclass[_objectReference.CLASS_META].reset(Parent[_objectReference.CLASS_META]);
Subclass.prototype = Object.create(Parent.prototype);
_object.ClassMeta.applyAllMixins(Subclass, Parent);
// recurse into sub-subclasses
relinkSubclasses(Subclass);
});
}
function toMixin(extension) {
if (extension instanceof Mixin) return extension;else return new Mixin(extension, []);
}
var ValueDescriptor = function (_Descriptor) {
_inherits(ValueDescriptor, _Descriptor);
function ValueDescriptor(_ref) {
var _ref$enumerable = _ref.enumerable,
enumerable = _ref$enumerable === undefined ? true : _ref$enumerable,
_ref$configurable = _ref.configurable,
configurable = _ref$configurable === undefined ? true : _ref$configurable,
_ref$writable = _ref.writable,
writable = _ref$writable === undefined ? true : _ref$writable,
value = _ref.value;
_classCallCheck(this, ValueDescriptor);
var _this3 = _possibleConstructorReturn(this, _Descriptor.call(this));
_this3.enumerable = enumerable;
_this3.configurable = configurable;
_this3.writable = writable;
_this3.value = value;
return _this3;
}
ValueDescriptor.prototype.define = function define(target, key, _home) {
Object.defineProperty(target, key, {
enumerable: this.enumerable,
configurable: this.configurable,
writable: this.writable,
value: this.value
});
};
return ValueDescriptor;
}(Descriptor);
var DataBlueprint = exports.DataBlueprint = function (_Blueprint) {
_inherits(DataBlueprint, _Blueprint);
function DataBlueprint(_ref2) {
var _ref2$enumerable = _ref2.enumerable,
enumerable = _ref2$enumerable === undefined ? true : _ref2$enumerable,
_ref2$configurable = _ref2.configurable,
configurable = _ref2$configurable === undefined ? true : _ref2$configurable,
_ref2$writable = _ref2.writable,
writable = _ref2$writable === undefined ? true : _ref2$writable,
value = _ref2.value;
_classCallCheck(this, DataBlueprint);
var _this4 = _possibleConstructorReturn(this, _Blueprint.call(this));
_this4.enumerable = enumerable;
_this4.configurable = configurable;
_this4.value = value;
_this4.writable = writable;
return _this4;
}
DataBlueprint.prototype.descriptor = function descriptor(_target, key, classMeta) {
var enumerable = this.enumerable,
configurable = this.configurable,
writable = this.writable,
value = this.value;
if (classMeta.hasConcatenatedProperty(key)) {
classMeta.addConcatenatedProperty(key, value);
value = classMeta.getConcatenatedProperty(key);
} else if (classMeta.hasMergedProperty(key)) {
classMeta.addMergedProperty(key, value);
value = classMeta.getMergedProperty(key);
}
return new ValueDescriptor({ enumerable: enumerable, configurable: configurable, writable: writable, value: value });
};
return DataBlueprint;
}(Blueprint);
var AccessorBlueprint = exports.AccessorBlueprint = function (_Blueprint2) {
_inherits(AccessorBlueprint, _Blueprint2);
function AccessorBlueprint(_ref3) {
var _ref3$enumerable = _ref3.enumerable,
enumerable = _ref3$enumerable === undefined ? true : _ref3$enumerable,
_ref3$configurable = _ref3.configurable,
configurable = _ref3$configurable === undefined ? true : _ref3$configurable,
get = _ref3.get,
set = _ref3.set;
_classCallCheck(this, AccessorBlueprint);
var _this5 = _possibleConstructorReturn(this, _Blueprint2.call(this));
_this5.enumerable = enumerable;
_this5.configurable = configurable;
_this5.get = get;
_this5.set = set;
return _this5;
}
AccessorBlueprint.prototype.descriptor = function descriptor(_target, _key, _classMeta) {
return new ValueDescriptor({
enumerable: this.enumerable,
configurable: this.configurable,
get: this.get,
set: this.set
});
};
return AccessorBlueprint;
}(Blueprint);
var MethodDescriptor = function (_ValueDescriptor) {
_inherits(MethodDescriptor, _ValueDescriptor);
function MethodDescriptor() {
_classCallCheck(this, MethodDescriptor);
return _possibleConstructorReturn(this, _ValueDescriptor.apply(this, arguments));
}
MethodDescriptor.prototype.define = function define(target, key, home) {
this.value = wrapMethod(home, key, this.value);
_ValueDescriptor.prototype.define.call(this, target, key, home);
};
return MethodDescriptor;
}(ValueDescriptor);
var MethodBlueprint = function (_DataBlueprint) {
_inherits(MethodBlueprint, _DataBlueprint);
function MethodBlueprint() {
_classCallCheck(this, MethodBlueprint);
return _possibleConstructorReturn(this, _DataBlueprint.apply(this, arguments));
}
MethodBlueprint.prototype.descriptor = function descriptor(target, key, classMeta) {
var desc = _DataBlueprint.prototype.descriptor.call(this, target, key, classMeta);
return new MethodDescriptor(desc);
};
return MethodBlueprint;
}(DataBlueprint);
function wrapMethod(home, methodName, original) {
if (!(methodName in home)) return maybeWrap(original);
var superMethod = home[methodName];
var func = function () {
for (var _len3 = arguments.length, args = Array(_len3), _key4 = 0; _key4 < _len3; _key4++) {
args[_key4] = arguments[_key4];
}
if (!this) return original.apply(this, args);
var lastSuper = this._super;
this._super = superMethod;
try {
return original.apply(this, args);
} finally {
this._super = lastSuper;
}
};
func.__wrapped = true;
return func;
}
function maybeWrap(original) {
if ('__wrapped' in original) return original;
return function () {
for (var _len4 = arguments.length, args = Array(_len4), _key5 = 0; _key5 < _len4; _key5++) {
args[_key5] = arguments[_key5];
}
if (!this) return original.apply(this, args);
var lastSuper = this._super;
this._super = _utils.ROOT;
try {
return original.apply(this, args);
} finally {
this._super = lastSuper;
}
};
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9taXhpbi5qcyJdLCJuYW1lcyI6WyJDTEFTU19NRVRBIiwiZGljdCIsImFzc2lnbiIsIkNsYXNzTWV0YSIsIkluc3RhbmNlTWV0YSIsInR1cmJvY2hhcmdlIiwiUk9PVCIsImlzQXJyYXkiLCJBcnJheSIsIkRFU0NSSVBUT1IiLCJCTFVFUFJJTlQiLCJEZXNjcmlwdG9yIiwiQmx1ZXByaW50IiwiTWl4aW4iLCJleHRlbnNpb25zIiwibWl4aW5zIiwiY29uY2F0ZW5hdGVkUHJvcGVydGllcyIsIm1lcmdlZFByb3BlcnRpZXMiLCJkZXBlbmRlbmNpZXMiLCJyZW9wZW4iLCJwdXNoIiwiY3JlYXRlIiwiYXJncyIsImxlbmd0aCIsImRlcHMiLCJzbGljZSIsIm1hcCIsInRvTWl4aW4iLCJvYmoiLCJtZXRhIiwiZm9yIiwiZ2V0QXBwbGllZE1peGlucyIsImRldGVjdCIsImluZGV4T2YiLCJoYXNBcHBsaWVkTWl4aW4iLCJjb25jYXQiLCJyYXdDb25jYXQiLCJ1bmRlZmluZWQiLCJtZXJnZWQiLCJyYXdNZXJnZWQiLCJub3JtYWxpemVkIiwiT2JqZWN0Iiwia2V5cyIsInJlZHVjZSIsImtleSIsInZhbHVlIiwiTWV0aG9kQmx1ZXByaW50IiwiRGF0YUJsdWVwcmludCIsImFwcGx5IiwidGFyZ2V0IiwiZm9yRWFjaCIsIm0iLCJtZXJnZVByb3BlcnRpZXMiLCJhZGRNaXhpbiIsInNlYWwiLCJyZXNlYWwiLCJleHRlbmRQcm90b3R5cGUiLCJPcmlnaW5hbCIsInByb3RvdHlwZSIsImV4dGVuZFByb3RvdHlwZU9udG8iLCJTdWJjbGFzcyIsIlBhcmVudCIsImV4dGVuZFN0YXRpYyIsIlRhcmdldCIsImdldFByb3RvdHlwZU9mIiwiYWRkU3RhdGljTWl4aW4iLCJwYXJlbnQiLCJhZGRBcHBsaWVkTWl4aW4iLCJhZGRNZXJnZWRQcm9wZXJ0eSIsImsiLCJhZGRDb25jYXRlbmF0ZWRQcm9wZXJ0eSIsIlZhbHVlRGVzY3JpcHRvciIsImdldENvbmNhdGVuYXRlZFByb3BlcnRpZXMiLCJkZWZpbmUiLCJnZXRNZXJnZWRQcm9wZXJ0aWVzIiwiZXh0ZW5zaW9uIiwiZGVzYyIsImRlc2NyaXB0b3IiLCJleHRlbmQiLCJTdXBlciIsImZyb21QYXJlbnQiLCJhZGRTdWJjbGFzcyIsImFwcGx5QWxsTWl4aW5zIiwicmVsaW5rU3ViY2xhc3NlcyIsImdldFN1YmNsYXNzZXMiLCJyZXNldCIsImVudW1lcmFibGUiLCJjb25maWd1cmFibGUiLCJ3cml0YWJsZSIsIl9ob21lIiwiZGVmaW5lUHJvcGVydHkiLCJfdGFyZ2V0IiwiY2xhc3NNZXRhIiwiaGFzQ29uY2F0ZW5hdGVkUHJvcGVydHkiLCJnZXRDb25jYXRlbmF0ZWRQcm9wZXJ0eSIsImhhc01lcmdlZFByb3BlcnR5IiwiZ2V0TWVyZ2VkUHJvcGVydHkiLCJBY2Nlc3NvckJsdWVwcmludCIsImdldCIsInNldCIsIl9rZXkiLCJfY2xhc3NNZXRhIiwiTWV0aG9kRGVzY3JpcHRvciIsImhvbWUiLCJ3cmFwTWV0aG9kIiwibWV0aG9kTmFtZSIsIm9yaWdpbmFsIiwibWF5YmVXcmFwIiwic3VwZXJNZXRob2QiLCJmdW5jIiwibGFzdFN1cGVyIiwiX3N1cGVyIiwiX193cmFwcGVkIl0sIm1hcHBpbmdzIjoiOzs7Ozs7UUE0SU8sQUFBUztRQVVULEFBQVM7UUFTVCxBQUFTO1FBcUVULEFBQVM7O0FBcE9oQixBQUFTLEFBQWtCOztBQUMzQixBQUFTLEFBQU0sQUFBYzs7QUFDN0IsQUFBUyxBQUFXLEFBQWMsQUFBbUI7O0FBQ3JELEFBQVMsQUFBWTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQUNiLEEsVSxBQUFZLE1BQVosQSxBQUNSOztBQUFPLElBQU0sa0NBQU4sQUFBbUIsQUFDMUI7QUFBTyxJQUFNLGdDQUFOLEFBQWtCLEFBQ3pCO0lBQUEsQUFBYSxrQ0FDVCxzQkFBYzswQkFDVjs7U0FBQSxBQUFLLDBDQUFMLEFBQStDLEFBQ2xEO0FBSEwsQUFLQTtJQUFBLEFBQWEsZ0NBQ1QscUJBQWM7MEJBQ1Y7O1NBQUEsQUFBSyww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Q3JCO2FBQUEsQUFBSyxBQUFTLEFBQ2Q7WUFBSSxBQUNBO21CQUFPLFNBQUEsQUFBUyxNQUFULEFBQWUsTUFBdEIsQUFBTyxBQUFxQixBQUMvQjtBQUZELGtCQUVVLEFBQ047aUJBQUEsQUFBSyxTQUFMLEFBQWMsQUFDakI7QUFDSjtBQVRELEFBVUgiLCJmaWxlIjoibGliL21peGluLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ0xBU1NfTUVUQSB9IGZyb20gJ0BnbGltbWVyL29iamVjdC1yZWZlcmVuY2UnO1xuaW1wb3J0IHsgZGljdCwgYXNzaWduIH0gZnJvbSAnQGdsaW1tZXIvdXRpbCc7XG5pbXBvcnQgeyBDbGFzc01ldGEsIEluc3RhbmNlTWV0YSwgdHVyYm9jaGFyZ2UgfSBmcm9tICcuL29iamVjdCc7XG5pbXBvcnQgeyBST09UIH0gZnJvbSAnLi91dGlscyc7XG5jb25zdCB7IGlzQXJyYXkgfSA9IEFycmF5O1xuZXhwb3J0IGNvbnN0IERFU0NSSVBUT1IgPSBcIjVkOTBmODRmLTkwOGUtNGE0Mi05NzQ5LTNkMGY1MjNjMjYyY1wiO1xuZXhwb3J0IGNvbnN0IEJMVUVQUklOVCA9IFwiOGQ5N2NmNWYtZGI5ZS00OGQ4LWE2YjItN2E3NWI3MTcwODA1XCI7XG5leHBvcnQgY2xhc3MgRGVzY3JpcHRvciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXNbXCI1ZDkwZjg0Zi05MDhlLTRhNDItOTc0OS0zZDBmNTIzYzI2MmNcIl0gPSB0cnVlO1xuICAgIH1cbn1cbmV4cG9ydCBjbGFzcyBCbHVlcHJpbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzW1wiOGQ5N2NmNWYtZGI5ZS00OGQ4LWE2YjItN2E3NWI3MTcwODA1XCJdID0gdHJ1ZTtcbiAgICB9XG59XG5leHBvcnQgY2xhc3MgTWl4aW4ge1xuICAgIGNvbnN0cnVjdG9yKGV4dGVuc2lvbnMsIG1peGlucykge1xuICAgICAgICB0aGlzLmV4dGVuc2lvbnMgPSBudWxsO1xuICAgICAgICB0aGlzLmNvbmNhdGVuYXRlZFByb3BlcnRpZXMgPSBbXTtcbiAgICAgICAgdGhpcy5tZXJnZWRQcm9wZXJ0aWVzID0gW107XG4gICAgICAgIHRoaXMuZGVwZW5kZW5jaWVzID0gW107XG4gICAgICAgIHRoaXMucmVvcGVuKGV4dGVuc2lvbnMpO1xuICAgICAgICB0aGlzLmRlcGVuZGVuY2llcy5wdXNoKC4uLm1peGlucyk7XG4gICAgfVxuICAgIHN0YXRpYyBjcmVhdGUoLi4uYXJncykge1xuICAgICAgICBsZXQgZXh0ZW5zaW9ucyA9IGFyZ3NbYXJncy5sZW5ndGggLSAxXTtcbiAgICAgICAgaWYgKGFyZ3MubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IHRoaXMoe30sIFtdKTtcbiAgICAgICAgfSBlbHNlIGlmIChleHRlbnNpb25zIGluc3RhbmNlb2YgTWl4aW4pIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgdGhpcyh7fSwgYXJncyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsZXQgZGVwcyA9IGFyZ3Muc2xpY2UoMCwgLTEpLm1hcCh0b01peGluKTtcbiAgICAgICAgICAgIHJldHVybiBuZXcgdGhpcyhleHRlbnNpb25zLCBkZXBzKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgbWl4aW5zKG9iaikge1xuICAgICAgICBpZiAodHlwZW9mIG9iaiAhPT0gJ29iamVjdCcgfHwgb2JqID09PSBudWxsKSByZXR1cm4gW107XG4gICAgICAgIGxldCBtZXRhID0gQ2xhc3NNZXRhLmZvcihvYmopO1xuICAgICAgICBpZiAoIW1ldGEpIHJldHVybiBbXTtcbiAgICAgICAgcmV0dXJuIG1ldGEuZ2V0QXBwbGllZE1peGlucygpO1xuICAgIH1cbiAgICBkZXRlY3Qob2JqKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb2JqICE9PSAnb2JqZWN0JyB8fCBvYmogPT09IG51bGwpIHJldHVybiBmYWxzZTtcbiAgICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIE1peGluKSB7XG4gICAgICAgICAgICByZXR1cm4gb2JqLmRlcGVuZGVuY2llcy5pbmRleE9mKHRoaXMpICE9PSAtMTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgbWV0YSA9IENsYXNzTWV0YS5mb3Iob2JqKTtcbiAgICAgICAgcmV0dXJuICEhbWV0YSAmJiBtZXRhLmhhc0FwcGxpZWRNaXhpbih0aGlzKTtcbiAgICB9XG4gICAgcmVvcGVuKGV4dGVuc2lvbnMpIHtcbiAgICAgICAgaWYgKHRoaXMuZXh0ZW5zaW9ucykge1xuICAgICAgICAgICAgdGhpcy5kZXBlbmRlbmNpZXMucHVzaCh0b01peGluKHRoaXMuZXh0ZW5zaW9ucykpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgZXh0ZW5zaW9ucyA9PT0gJ29iamVjdCcgJiYgJ2NvbmNhdGVuYXRlZFByb3BlcnRpZXMnIGluIGV4dGVuc2lvbnMpIHtcbiAgICAgICAgICAgIGxldCBjb25jYXQ7XG4gICAgICAgICAgICBsZXQgcmF3Q29uY2F0ID0gZXh0ZW5zaW9ucy5jb25jYXRlbmF0ZWRQcm9wZXJ0aWVzO1xuICAgICAgICAgICAgaWYgKGlzQXJyYXkocmF3Q29uY2F0KSkge1xuICAgICAgICAgICAgICAgIGNvbmNhdCA9IHJhd0NvbmNhdC5zbGljZSgpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChyYXdDb25jYXQgPT09IG51bGwgfHwgcmF3Q29uY2F0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBjb25jYXQgPSBbXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uY2F0ID0gW3Jhd0NvbmNhdF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWxldGUgZXh0ZW5zaW9ucy5jb25jYXRlbmF0ZWRQcm9wZXJ0aWVzO1xuICAgICAgICAgICAgdGhpcy5jb25jYXRlbmF0ZWRQcm9wZXJ0aWVzID0gY29uY2F0O1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgZXh0ZW5zaW9ucyA9PT0gJ29iamVjdCcgJiYgJ21lcmdlZFByb3BlcnRpZXMnIGluIGV4dGVuc2lvbnMpIHtcbiAgICAgICAgICAgIGxldCBtZXJnZWQ7XG4gICAgICAgICAgICBsZXQgcmF3TWVyZ2VkID0gZXh0ZW5zaW9ucy5tZXJnZWRQcm9wZXJ0aWVzO1xuICAgICAgICAgICAgaWYgKGlzQXJyYXkocmF3TWVyZ2VkKSkge1xuICAgICAgICAgICAgICAgIG1lcmdlZCA9IHJhd01lcmdlZC5zbGljZSgpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChyYXdNZXJnZWQgPT09IG51bGwgfHwgcmF3TWVyZ2VkID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBtZXJnZWQgPSBbXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbWVyZ2VkID0gW3Jhd01lcmdlZF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWxldGUgZXh0ZW5zaW9ucy5tZXJnZWRQcm9wZXJ0aWVzO1xuICAgICAgICAgICAgdGhpcy5tZXJnZWRQcm9wZXJ0aWVzID0gbWVyZ2VkO1xuICAgICAgICB9XG4gICAgICAgIGxldCBub3JtYWxpemVkID0gT2JqZWN0LmtleXMoZXh0ZW5zaW9ucykucmVkdWNlKChvYmosIGtleSkgPT4ge1xuICAgICAgICAgICAgbGV0IHZhbHVlID0gZXh0ZW5zaW9uc1trZXldO1xuICAgICAgICAgICAgc3dpdGNoICh0eXBlb2YgdmFsdWUpIHtcbiAgICAgICAgICAgICAgICBjYXNlICdmdW5jdGlvbic6XG4gICAgICAgICAgICAgICAgICAgIG9ialtrZXldID0gbmV3IE1ldGhvZEJsdWVwcmludCh7IHZhbHVlIH0pO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdvYmplY3QnOlxuICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgJiYgQkxVRVBSSU5UIGluIHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvYmpba2V5XSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgb2JqW2tleV0gPSBuZXcgRGF0YUJsdWVwcmludCh7IHZhbHVlIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG9iajtcbiAgICAgICAgfSwgZGljdCgpKTtcbiAgICAgICAgdGhpcy5leHRlbnNpb25zID0gZGljdCgpO1xuICAgICAgICBhc3NpZ24odGhpcy5leHRlbnNpb25zLCB0dXJib2NoYXJnZShub3JtYWxpemVkKSk7XG4gICAgfVxuICAgIGFwcGx5KHRhcmdldCkge1xuICAgICAgICBsZXQgbWV0YSA9IHRhcmdldFtDTEFTU19NRVRBXSA9IHRhcmdldFtDTEFTU19NRVRBXSB8fCBuZXcgQ2xhc3NNZXRhKCk7XG4gICAgICAgIHRoaXMuZGVwZW5kZW5jaWVzLmZvckVhY2gobSA9PiBtLmFwcGx5KHRhcmdldCkpO1xuICAgICAgICB0aGlzLm1lcmdlUHJvcGVydGllcyh0YXJnZXQsIHRhcmdldCwgbWV0YSk7XG4gICAgICAgIG1ldGEuYWRkTWl4aW4odGhpcyk7XG4gICAgICAgIG1ldGEuc2VhbCgpO1xuICAgICAgICBtZXRhLnJlc2VhbCh0YXJnZXQpO1xuICAgICAgICByZXR1cm4gdGFyZ2V0O1xuICAgIH1cbiAgICBleHRlbmRQcm90b3R5cGUoT3JpZ2luYWwpIHtcbiAgICAgICAgT3JpZ2luYWwucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShPcmlnaW5hbC5wcm90b3R5cGUpO1xuICAgICAgICB0aGlzLmRlcGVuZGVuY2llcy5mb3JFYWNoKG0gPT4gbS5leHRlbmRQcm90b3R5cGUoT3JpZ2luYWwpKTtcbiAgICAgICAgdGhpcy5leHRlbmRQcm90b3R5cGVPbnRvKE9yaWdpbmFsLCBPcmlnaW5hbCk7XG4gICAgfVxuICAgIGV4dGVuZFByb3RvdHlwZU9udG8oU3ViY2xhc3MsIFBhcmVudCkge1xuICAgICAgICB0aGlzLmRlcGVuZGVuY2llcy5mb3JFYWNoKG0gPT4gbS5leHRlbmRQcm90b3R5cGVPbnRvKFN1YmNsYXNzLCBQYXJlbnQpKTtcbiAgICAgICAgdGhpcy5tZXJnZVByb3BlcnRpZXMoU3ViY2xhc3MucHJvdG90eXBlLCBQYXJlbnQucHJvdG90eXBlLCBTdWJjbGFzc1tDTEFTU19NRVRBXSk7XG4gICAgICAgIFN1YmNsYXNzW0NMQVNTX01FVEFdLmFkZE1peGluKHRoaXMpO1xuICAgIH1cbiAgICBleHRlbmRTdGF0aWMoVGFyZ2V0KSB7XG4gICAgICAgIHRoaXMuZGVwZW5kZW5jaWVzLmZvckVhY2gobSA9PiBtLmV4dGVuZFN0YXRpYyhUYXJnZXQpKTtcbiAgICAgICAgdGhpcy5tZXJnZVByb3BlcnRpZXMoVGFyZ2V0LCBPYmplY3QuZ2V0UHJvdG90eXBlT2YoVGFyZ2V0KSwgVGFyZ2V0W0NMQVNTX01FVEFdW0NMQVNTX01FVEFdKTtcbiAgICAgICAgVGFyZ2V0W0NMQVNTX01FVEFdLmFkZFN0YXRpY01peGluKHRoaXMpO1xuICAgIH1cbiAgICBtZXJnZVByb3BlcnRpZXModGFyZ2V0LCBwYXJlbnQsIG1ldGEpIHtcbiAgICAgICAgaWYgKG1ldGEuaGFzQXBwbGllZE1peGluKHRoaXMpKSByZXR1cm47XG4gICAgICAgIG1ldGEuYWRkQXBwbGllZE1peGluKHRoaXMpO1xuICAgICAgICB0aGlzLm1lcmdlZFByb3BlcnRpZXMuZm9yRWFjaChrID0+IG1ldGEuYWRkTWVyZ2VkUHJvcGVydHkoaywgcGFyZW50W2tdKSk7XG4gICAgICAgIHRoaXMuY29uY2F0ZW5hdGVkUHJvcGVydGllcy5mb3JFYWNoKGsgPT4gbWV0YS5hZGRDb25jYXRlbmF0ZWRQcm9wZXJ0eShrLCBbXSkpO1xuICAgICAgICBuZXcgVmFsdWVEZXNjcmlwdG9yKHsgdmFsdWU6IG1ldGEuZ2V0Q29uY2F0ZW5hdGVkUHJvcGVydGllcygpIH0pLmRlZmluZSh0YXJnZXQsICdjb25jYXRlbmF0ZWRQcm9wZXJ0aWVzJyk7XG4gICAgICAgIG5ldyBWYWx1ZURlc2NyaXB0b3IoeyB2YWx1ZTogbWV0YS5nZXRNZXJnZWRQcm9wZXJ0aWVzKCkgfSkuZGVmaW5lKHRhcmdldCwgJ21lcmdlZFByb3BlcnRpZXMnKTtcbiAgICAgICAgT2JqZWN0LmtleXModGhpcy5leHRlbnNpb25zKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgICAgICBsZXQgZXh0ZW5zaW9uID0gdGhpcy5leHRlbnNpb25zW2tleV07XG4gICAgICAgICAgICBsZXQgZGVzYyA9IGV4dGVuc2lvbi5kZXNjcmlwdG9yKHRhcmdldCwga2V5LCBtZXRhKTtcbiAgICAgICAgICAgIGRlc2MuZGVmaW5lKHRhcmdldCwga2V5LCBwYXJlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgbmV3IFZhbHVlRGVzY3JpcHRvcih7IHZhbHVlOiBST09UIH0pLmRlZmluZSh0YXJnZXQsICdfc3VwZXInKTtcbiAgICB9XG59XG5leHBvcnQgZnVuY3Rpb24gZXh0ZW5kKFBhcmVudCwgLi4uZXh0ZW5zaW9ucykge1xuICAgIGxldCBTdXBlciA9IFBhcmVudDtcbiAgICBsZXQgU3ViY2xhc3MgPSBjbGFzcyBleHRlbmRzIFN1cGVyIHt9O1xuICAgIFN1YmNsYXNzW0NMQVNTX01FVEFdID0gSW5zdGFuY2VNZXRhLmZyb21QYXJlbnQoUGFyZW50W0NMQVNTX01FVEFdKTtcbiAgICBsZXQgbWl4aW5zID0gZXh0ZW5zaW9ucy5tYXAodG9NaXhpbik7XG4gICAgUGFyZW50W0NMQVNTX01FVEFdLmFkZFN1YmNsYXNzKFN1YmNsYXNzKTtcbiAgICBtaXhpbnMuZm9yRWFjaChtID0+IFN1YmNsYXNzW0NMQVNTX01FVEFdLmFkZE1peGluKG0pKTtcbiAgICBDbGFzc01ldGEuYXBwbHlBbGxNaXhpbnMoU3ViY2xhc3MsIFBhcmVudCk7XG4gICAgcmV0dXJuIFN1YmNsYXNzO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHJlbGlua1N1YmNsYXNzZXMoUGFyZW50KSB7XG4gICAgUGFyZW50W0NMQVNTX01FVEFdLmdldFN1YmNsYXNzZXMoKS5mb3JFYWNoKFN1YmNsYXNzID0+IHtcbiAgICAgICAgU3ViY2xhc3NbQ0xBU1NfTUVUQV0ucmVzZXQoUGFyZW50W0NMQVNTX01FVEFdKTtcbiAgICAgICAgU3ViY2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShQYXJlbnQucHJvdG90eXBlKTtcbiAgICAgICAgQ2xhc3NNZXRhLmFwcGx5QWxsTWl4aW5zKFN1YmNsYXNzLCBQYXJlbnQpO1xuICAgICAgICAvLyByZWN1cnNlIGludG8gc3ViLXN1YmNsYXNzZXNcbiAgICAgICAgcmVsaW5rU3ViY2xhc3NlcyhTdWJjbGFzcyk7XG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gdG9NaXhpbihleHRlbnNpb24pIHtcbiAgICBpZiAoZXh0ZW5zaW9uIGluc3RhbmNlb2YgTWl4aW4pIHJldHVybiBleHRlbnNpb247ZWxzZSByZXR1cm4gbmV3IE1peGluKGV4dGVuc2lvbiwgW10pO1xufVxuY2xhc3MgVmFsdWVEZXNjcmlwdG9yIGV4dGVuZHMgRGVzY3JpcHRvciB7XG4gICAgY29uc3RydWN0b3IoeyBlbnVtZXJhYmxlID0gdHJ1ZSwgY29uZmlndXJhYmxlID0gdHJ1ZSwgd3JpdGFibGUgPSB0cnVlLCB2YWx1ZSB9KSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMuZW51bWVyYWJsZSA9IGVudW1lcmFibGU7XG4gICAgICAgIHRoaXMuY29uZmlndXJhYmxlID0gY29uZmlndXJhYmxlO1xuICAgICAgICB0aGlzLndyaXRhYmxlID0gd3JpdGFibGU7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB9XG4gICAgZGVmaW5lKHRhcmdldCwga2V5LCBfaG9tZSkge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIHtcbiAgICAgICAgICAgIGVudW1lcmFibGU6IHRoaXMuZW51bWVyYWJsZSxcbiAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdGhpcy5jb25maWd1cmFibGUsXG4gICAgICAgICAgICB3cml0YWJsZTogdGhpcy53cml0YWJsZSxcbiAgICAgICAgICAgIHZhbHVlOiB0aGlzLnZhbHVlXG4gICAgICAgIH0pO1xuICAgIH1cbn1cbmV4cG9ydCBjbGFzcyBEYXRhQmx1ZXByaW50IGV4dGVuZHMgQmx1ZXByaW50IHtcbiAgICBjb25zdHJ1Y3Rvcih7IGVudW1lcmFibGUgPSB0cnVlLCBjb25maWd1cmFibGUgPSB0cnVlLCB3cml0YWJsZSA9IHRydWUsIHZhbHVlIH0pIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5lbnVtZXJhYmxlID0gZW51bWVyYWJsZTtcbiAgICAgICAgdGhpcy5jb25maWd1cmFibGUgPSBjb25maWd1cmFibGU7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgdGhpcy53cml0YWJsZSA9IHdyaXRhYmxlO1xuICAgIH1cbiAgICBkZXNjcmlwdG9yKF90YXJnZXQsIGtleSwgY2xhc3NNZXRhKSB7XG4gICAgICAgIGxldCB7IGVudW1lcmFibGUsIGNvbmZpZ3VyYWJsZSwgd3JpdGFibGUsIHZhbHVlIH0gPSB0aGlzO1xuICAgICAgICBpZiAoY2xhc3NNZXRhLmhhc0NvbmNhdGVuYXRlZFByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgIGNsYXNzTWV0YS5hZGRDb25jYXRlbmF0ZWRQcm9wZXJ0eShrZXksIHZhbHVlKTtcbiAgICAgICAgICAgIHZhbHVlID0gY2xhc3NNZXRhLmdldENvbmNhdGVuYXRlZFByb3BlcnR5KGtleSk7XG4gICAgICAgIH0gZWxzZSBpZiAoY2xhc3NNZXRhLmhhc01lcmdlZFByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgIGNsYXNzTWV0YS5hZGRNZXJnZWRQcm9wZXJ0eShrZXksIHZhbHVlKTtcbiAgICAgICAgICAgIHZhbHVlID0gY2xhc3NNZXRhLmdldE1lcmdlZFByb3BlcnR5KGtleSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBWYWx1ZURlc2NyaXB0b3IoeyBlbnVtZXJhYmxlLCBjb25maWd1cmFibGUsIHdyaXRhYmxlLCB2YWx1ZSB9KTtcbiAgICB9XG59XG5leHBvcnQgY2xhc3MgQWNjZXNzb3JCbHVlcHJpbnQgZXh0ZW5kcyBCbHVlcHJpbnQge1xuICAgIGNvbnN0cnVjdG9yKHsgZW51bWVyYWJsZSA9IHRydWUsIGNvbmZpZ3VyYWJsZSA9IHRydWUsIGdldCwgc2V0IH0pIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5lbnVtZXJhYmxlID0gZW51bWVyYWJsZTtcbiAgICAgICAgdGhpcy5jb25maWd1cmFibGUgPSBjb25maWd1cmFibGU7XG4gICAgICAgIHRoaXMuZ2V0ID0gZ2V0O1xuICAgICAgICB0aGlzLnNldCA9IHNldDtcbiAgICB9XG4gICAgZGVzY3JpcHRvcihfdGFyZ2V0LCBfa2V5LCBfY2xhc3NNZXRhKSB7XG4gICAgICAgIHJldHVybiBuZXcgVmFsdWVEZXNjcmlwdG9yKHtcbiAgICAgICAgICAgIGVudW1lcmFibGU6IHRoaXMuZW51bWVyYWJsZSxcbiAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdGhpcy5jb25maWd1cmFibGUsXG4gICAgICAgICAgICBnZXQ6IHRoaXMuZ2V0LFxuICAgICAgICAgICAgc2V0OiB0aGlzLnNldFxuICAgICAgICB9KTtcbiAgICB9XG59XG5jbGFzcyBNZXRob2REZXNjcmlwdG9yIGV4dGVuZHMgVmFsdWVEZXNjcmlwdG9yIHtcbiAgICBkZWZpbmUodGFyZ2V0LCBrZXksIGhvbWUpIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9IHdyYXBNZXRob2QoaG9tZSwga2V5LCB0aGlzLnZhbHVlKTtcbiAgICAgICAgc3VwZXIuZGVmaW5lKHRhcmdldCwga2V5LCBob21lKTtcbiAgICB9XG59XG5jbGFzcyBNZXRob2RCbHVlcHJpbnQgZXh0ZW5kcyBEYXRhQmx1ZXByaW50IHtcbiAgICBkZXNjcmlwdG9yKHRhcmdldCwga2V5LCBjbGFzc01ldGEpIHtcbiAgICAgICAgbGV0IGRlc2MgPSBzdXBlci5kZXNjcmlwdG9yKHRhcmdldCwga2V5LCBjbGFzc01ldGEpO1xuICAgICAgICByZXR1cm4gbmV3IE1ldGhvZERlc2NyaXB0b3IoZGVzYyk7XG4gICAgfVxufVxuZXhwb3J0IGZ1bmN0aW9uIHdyYXBNZXRob2QoaG9tZSwgbWV0aG9kTmFtZSwgb3JpZ2luYWwpIHtcbiAgICBpZiAoIShtZXRob2ROYW1lIGluIGhvbWUpKSByZXR1cm4gbWF5YmVXcmFwKG9yaWdpbmFsKTtcbiAgICBsZXQgc3VwZXJNZXRob2QgPSBob21lW21ldGhvZE5hbWVdO1xuICAgIGxldCBmdW5jID0gZnVuY3Rpb24gKC4uLmFyZ3MpIHtcbiAgICAgICAgaWYgKCF0aGlzKSByZXR1cm4gb3JpZ2luYWwuYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgIGxldCBsYXN0U3VwZXIgPSB0aGlzLl9zdXBlcjtcbiAgICAgICAgdGhpcy5fc3VwZXIgPSBzdXBlck1ldGhvZDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIHRoaXMuX3N1cGVyID0gbGFzdFN1cGVyO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jLl9fd3JhcHBlZCA9IHRydWU7XG4gICAgcmV0dXJuIGZ1bmM7XG59XG5mdW5jdGlvbiBtYXliZVdyYXAob3JpZ2luYWwpIHtcbiAgICBpZiAoJ19fd3JhcHBlZCcgaW4gb3JpZ2luYWwpIHJldHVybiBvcmlnaW5hbDtcbiAgICByZXR1cm4gZnVuY3Rpb24gKC4uLmFyZ3MpIHtcbiAgICAgICAgaWYgKCF0aGlzKSByZXR1cm4gb3JpZ2luYWwuYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgIGxldCBsYXN0U3VwZXIgPSB0aGlzLl9zdXBlcjtcbiAgICAgICAgdGhpcy5fc3VwZXIgPSBST09UO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIG9yaWdpbmFsLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgdGhpcy5fc3VwZXIgPSBsYXN0U3VwZXI7XG4gICAgICAgIH1cbiAgICB9O1xufSJdfQ==