UNPKG

ember-legacy-class-transform

Version:
437 lines (371 loc) 42.8 kB
"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==