ember-legacy-class-transform
Version:
The default blueprint for ember-cli addons.
278 lines (272 loc) • 37 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');
const { isArray } = Array;
const DESCRIPTOR = exports.DESCRIPTOR = "5d90f84f-908e-4a42-9749-3d0f523c262c";
const BLUEPRINT = exports.BLUEPRINT = "8d97cf5f-db9e-48d8-a6b2-7a75b7170805";
class Descriptor {
constructor() {
this["5d90f84f-908e-4a42-9749-3d0f523c262c"] = true;
}
}
exports.Descriptor = Descriptor;
class Blueprint {
constructor() {
this["8d97cf5f-db9e-48d8-a6b2-7a75b7170805"] = true;
}
}
exports.Blueprint = Blueprint;
class Mixin {
constructor(extensions, mixins) {
this.extensions = null;
this.concatenatedProperties = [];
this.mergedProperties = [];
this.dependencies = [];
this.reopen(extensions);
this.dependencies.push(...mixins);
}
static create(...args) {
let extensions = args[args.length - 1];
if (args.length === 0) {
return new this({}, []);
} else if (extensions instanceof Mixin) {
return new this({}, args);
} else {
let deps = args.slice(0, -1).map(toMixin);
return new this(extensions, deps);
}
}
static mixins(obj) {
if (typeof obj !== 'object' || obj === null) return [];
let meta = _object.ClassMeta.for(obj);
if (!meta) return [];
return meta.getAppliedMixins();
}
detect(obj) {
if (typeof obj !== 'object' || obj === null) return false;
if (obj instanceof Mixin) {
return obj.dependencies.indexOf(this) !== -1;
}
let meta = _object.ClassMeta.for(obj);
return !!meta && meta.hasAppliedMixin(this);
}
reopen(extensions) {
if (this.extensions) {
this.dependencies.push(toMixin(this.extensions));
}
if (typeof extensions === 'object' && 'concatenatedProperties' in extensions) {
let concat;
let 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) {
let merged;
let 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;
}
let normalized = Object.keys(extensions).reduce((obj, key) => {
let value = extensions[key];
switch (typeof value) {
case 'function':
obj[key] = new MethodBlueprint({ value });
break;
case 'object':
if (value && BLUEPRINT in value) {
obj[key] = value;
break;
}
/* falls through */
default:
obj[key] = new DataBlueprint({ value });
}
return obj;
}, (0, _util.dict)());
this.extensions = (0, _util.dict)();
(0, _util.assign)(this.extensions, (0, _object.turbocharge)(normalized));
}
apply(target) {
let meta = target[_objectReference.CLASS_META] = target[_objectReference.CLASS_META] || new _object.ClassMeta();
this.dependencies.forEach(m => m.apply(target));
this.mergeProperties(target, target, meta);
meta.addMixin(this);
meta.seal();
meta.reseal(target);
return target;
}
extendPrototype(Original) {
Original.prototype = Object.create(Original.prototype);
this.dependencies.forEach(m => m.extendPrototype(Original));
this.extendPrototypeOnto(Original, Original);
}
extendPrototypeOnto(Subclass, Parent) {
this.dependencies.forEach(m => m.extendPrototypeOnto(Subclass, Parent));
this.mergeProperties(Subclass.prototype, Parent.prototype, Subclass[_objectReference.CLASS_META]);
Subclass[_objectReference.CLASS_META].addMixin(this);
}
extendStatic(Target) {
this.dependencies.forEach(m => m.extendStatic(Target));
this.mergeProperties(Target, Object.getPrototypeOf(Target), Target[_objectReference.CLASS_META][_objectReference.CLASS_META]);
Target[_objectReference.CLASS_META].addStaticMixin(this);
}
mergeProperties(target, parent, meta) {
if (meta.hasAppliedMixin(this)) return;
meta.addAppliedMixin(this);
this.mergedProperties.forEach(k => meta.addMergedProperty(k, parent[k]));
this.concatenatedProperties.forEach(k => meta.addConcatenatedProperty(k, []));
new ValueDescriptor({ value: meta.getConcatenatedProperties() }).define(target, 'concatenatedProperties');
new ValueDescriptor({ value: meta.getMergedProperties() }).define(target, 'mergedProperties');
Object.keys(this.extensions).forEach(key => {
let extension = this.extensions[key];
let desc = extension.descriptor(target, key, meta);
desc.define(target, key, parent);
});
new ValueDescriptor({ value: _utils.ROOT }).define(target, '_super');
}
}
exports.Mixin = Mixin;
function extend(Parent, ...extensions) {
let Super = Parent;
let Subclass = class extends Super {};
Subclass[_objectReference.CLASS_META] = _object.InstanceMeta.fromParent(Parent[_objectReference.CLASS_META]);
let mixins = extensions.map(toMixin);
Parent[_objectReference.CLASS_META].addSubclass(Subclass);
mixins.forEach(m => Subclass[_objectReference.CLASS_META].addMixin(m));
_object.ClassMeta.applyAllMixins(Subclass, Parent);
return Subclass;
}
function relinkSubclasses(Parent) {
Parent[_objectReference.CLASS_META].getSubclasses().forEach(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, []);
}
class ValueDescriptor extends Descriptor {
constructor({ enumerable = true, configurable = true, writable = true, value }) {
super();
this.enumerable = enumerable;
this.configurable = configurable;
this.writable = writable;
this.value = value;
}
define(target, key, _home) {
Object.defineProperty(target, key, {
enumerable: this.enumerable,
configurable: this.configurable,
writable: this.writable,
value: this.value
});
}
}
class DataBlueprint extends Blueprint {
constructor({ enumerable = true, configurable = true, writable = true, value }) {
super();
this.enumerable = enumerable;
this.configurable = configurable;
this.value = value;
this.writable = writable;
}
descriptor(_target, key, classMeta) {
let { enumerable, configurable, writable, value } = this;
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, configurable, writable, value });
}
}
exports.DataBlueprint = DataBlueprint;
class AccessorBlueprint extends Blueprint {
constructor({ enumerable = true, configurable = true, get, set }) {
super();
this.enumerable = enumerable;
this.configurable = configurable;
this.get = get;
this.set = set;
}
descriptor(_target, _key, _classMeta) {
return new ValueDescriptor({
enumerable: this.enumerable,
configurable: this.configurable,
get: this.get,
set: this.set
});
}
}
exports.AccessorBlueprint = AccessorBlueprint;
class MethodDescriptor extends ValueDescriptor {
define(target, key, home) {
this.value = wrapMethod(home, key, this.value);
super.define(target, key, home);
}
}
class MethodBlueprint extends DataBlueprint {
descriptor(target, key, classMeta) {
let desc = super.descriptor(target, key, classMeta);
return new MethodDescriptor(desc);
}
}
function wrapMethod(home, methodName, original) {
if (!(methodName in home)) return maybeWrap(original);
let superMethod = home[methodName];
let func = function (...args) {
if (!this) return original.apply(this, args);
let 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 (...args) {
if (!this) return original.apply(this, args);
let 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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9taXhpbi5qcyJdLCJuYW1lcyI6WyJleHRlbmQiLCJyZWxpbmtTdWJjbGFzc2VzIiwidG9NaXhpbiIsIndyYXBNZXRob2QiLCJpc0FycmF5IiwiQXJyYXkiLCJERVNDUklQVE9SIiwiQkxVRVBSSU5UIiwiRGVzY3JpcHRvciIsImNvbnN0cnVjdG9yIiwiQmx1ZXByaW50IiwiTWl4aW4iLCJleHRlbnNpb25zIiwibWl4aW5zIiwiY29uY2F0ZW5hdGVkUHJvcGVydGllcyIsIm1lcmdlZFByb3BlcnRpZXMiLCJkZXBlbmRlbmNpZXMiLCJyZW9wZW4iLCJwdXNoIiwiY3JlYXRlIiwiYXJncyIsImxlbmd0aCIsImRlcHMiLCJzbGljZSIsIm1hcCIsIm9iaiIsIm1ldGEiLCJmb3IiLCJnZXRBcHBsaWVkTWl4aW5zIiwiZGV0ZWN0IiwiaW5kZXhPZiIsImhhc0FwcGxpZWRNaXhpbiIsImNvbmNhdCIsInJhd0NvbmNhdCIsInVuZGVmaW5lZCIsIm1lcmdlZCIsInJhd01lcmdlZCIsIm5vcm1hbGl6ZWQiLCJPYmplY3QiLCJrZXlzIiwicmVkdWNlIiwia2V5IiwidmFsdWUiLCJNZXRob2RCbHVlcHJpbnQiLCJEYXRhQmx1ZXByaW50IiwiYXBwbHkiLCJ0YXJnZXQiLCJmb3JFYWNoIiwibSIsIm1lcmdlUHJvcGVydGllcyIsImFkZE1peGluIiwic2VhbCIsInJlc2VhbCIsImV4dGVuZFByb3RvdHlwZSIsIk9yaWdpbmFsIiwicHJvdG90eXBlIiwiZXh0ZW5kUHJvdG90eXBlT250byIsIlN1YmNsYXNzIiwiUGFyZW50IiwiZXh0ZW5kU3RhdGljIiwiVGFyZ2V0IiwiZ2V0UHJvdG90eXBlT2YiLCJhZGRTdGF0aWNNaXhpbiIsInBhcmVudCIsImFkZEFwcGxpZWRNaXhpbiIsImsiLCJhZGRNZXJnZWRQcm9wZXJ0eSIsImFkZENvbmNhdGVuYXRlZFByb3BlcnR5IiwiVmFsdWVEZXNjcmlwdG9yIiwiZ2V0Q29uY2F0ZW5hdGVkUHJvcGVydGllcyIsImRlZmluZSIsImdldE1lcmdlZFByb3BlcnRpZXMiLCJleHRlbnNpb24iLCJkZXNjIiwiZGVzY3JpcHRvciIsIlN1cGVyIiwiZnJvbVBhcmVudCIsImFkZFN1YmNsYXNzIiwiYXBwbHlBbGxNaXhpbnMiLCJnZXRTdWJjbGFzc2VzIiwicmVzZXQiLCJlbnVtZXJhYmxlIiwiY29uZmlndXJhYmxlIiwid3JpdGFibGUiLCJfaG9tZSIsImRlZmluZVByb3BlcnR5IiwiX3RhcmdldCIsImNsYXNzTWV0YSIsImhhc0NvbmNhdGVuYXRlZFByb3BlcnR5IiwiZ2V0Q29uY2F0ZW5hdGVkUHJvcGVydHkiLCJoYXNNZXJnZWRQcm9wZXJ0eSIsImdldE1lcmdlZFByb3BlcnR5IiwiQWNjZXNzb3JCbHVlcHJpbnQiLCJnZXQiLCJzZXQiLCJfa2V5IiwiX2NsYXNzTWV0YSIsIk1ldGhvZERlc2NyaXB0b3IiLCJob21lIiwibWV0aG9kTmFtZSIsIm9yaWdpbmFsIiwibWF5YmVXcmFwIiwic3VwZXJNZXRob2QiLCJmdW5jIiwibGFzdFN1cGVyIiwiX3N1cGVyIiwiX193cmFwcGVkIl0sIm1hcHBpbmdzIjoiOzs7Ozs7UUE0SWdCQSxNLEdBQUFBLE07UUFVQUMsZ0IsR0FBQUEsZ0I7UUFTQUMsTyxHQUFBQSxPO1FBcUVBQyxVLEdBQUFBLFU7O0FBcE9oQjs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQSxNQUFNLEVBQUVDLE9BQUYsS0FBY0MsS0FBcEI7QUFDTyxNQUFNQyxrQ0FBYSxzQ0FBbkI7QUFDQSxNQUFNQyxnQ0FBWSxzQ0FBbEI7QUFDQSxNQUFNQyxVQUFOLENBQWlCO0FBQ3BCQyxrQkFBYztBQUNWLGFBQUssc0NBQUwsSUFBK0MsSUFBL0M7QUFDSDtBQUhtQjtRQUFYRCxVLEdBQUFBLFU7QUFLTixNQUFNRSxTQUFOLENBQWdCO0FBQ25CRCxrQkFBYztBQUNWLGFBQUssc0NBQUwsSUFBK0MsSUFBL0M7QUFDSDtBQUhrQjtRQUFWQyxTLEdBQUFBLFM7QUFLTixNQUFNQyxLQUFOLENBQVk7QUFDZkYsZ0JBQVlHLFVBQVosRUFBd0JDLE1BQXhC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QWUsSUFBZixFQUFxQnpCLElBQXJCLENBQVA7QUFDSCxTQUZELFNBRVU7QUFDTixpQkFBS3FGLE1BQUwsR0FBY0QsU0FBZDtBQUNIO0FBQ0osS0FURDtBQVVIIiwiZmlsZSI6ImxpYi9taXhpbi5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENMQVNTX01FVEEgfSBmcm9tICdAZ2xpbW1lci9vYmplY3QtcmVmZXJlbmNlJztcbmltcG9ydCB7IGRpY3QsIGFzc2lnbiB9IGZyb20gJ0BnbGltbWVyL3V0aWwnO1xuaW1wb3J0IHsgQ2xhc3NNZXRhLCBJbnN0YW5jZU1ldGEsIHR1cmJvY2hhcmdlIH0gZnJvbSAnLi9vYmplY3QnO1xuaW1wb3J0IHsgUk9PVCB9IGZyb20gJy4vdXRpbHMnO1xuY29uc3QgeyBpc0FycmF5IH0gPSBBcnJheTtcbmV4cG9ydCBjb25zdCBERVNDUklQVE9SID0gXCI1ZDkwZjg0Zi05MDhlLTRhNDItOTc0OS0zZDBmNTIzYzI2MmNcIjtcbmV4cG9ydCBjb25zdCBCTFVFUFJJTlQgPSBcIjhkOTdjZjVmLWRiOWUtNDhkOC1hNmIyLTdhNzViNzE3MDgwNVwiO1xuZXhwb3J0IGNsYXNzIERlc2NyaXB0b3Ige1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzW1wiNWQ5MGY4NGYtOTA4ZS00YTQyLTk3NDktM2QwZjUyM2MyNjJjXCJdID0gdHJ1ZTtcbiAgICB9XG59XG5leHBvcnQgY2xhc3MgQmx1ZXByaW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpc1tcIjhkOTdjZjVmLWRiOWUtNDhkOC1hNmIyLTdhNzViNzE3MDgwNVwiXSA9IHRydWU7XG4gICAgfVxufVxuZXhwb3J0IGNsYXNzIE1peGluIHtcbiAgICBjb25zdHJ1Y3RvcihleHRlbnNpb25zLCBtaXhpbnMpIHtcbiAgICAgICAgdGhpcy5leHRlbnNpb25zID0gbnVsbDtcbiAgICAgICAgdGhpcy5jb25jYXRlbmF0ZWRQcm9wZXJ0aWVzID0gW107XG4gICAgICAgIHRoaXMubWVyZ2VkUHJvcGVydGllcyA9IFtdO1xuICAgICAgICB0aGlzLmRlcGVuZGVuY2llcyA9IFtdO1xuICAgICAgICB0aGlzLnJlb3BlbihleHRlbnNpb25zKTtcbiAgICAgICAgdGhpcy5kZXBlbmRlbmNpZXMucHVzaCguLi5taXhpbnMpO1xuICAgIH1cbiAgICBzdGF0aWMgY3JlYXRlKC4uLmFyZ3MpIHtcbiAgICAgICAgbGV0IGV4dGVuc2lvbnMgPSBhcmdzW2FyZ3MubGVuZ3RoIC0gMV07XG4gICAgICAgIGlmIChhcmdzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyB0aGlzKHt9LCBbXSk7XG4gICAgICAgIH0gZWxzZSBpZiAoZXh0ZW5zaW9ucyBpbnN0YW5jZW9mIE1peGluKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IHRoaXMoe30sIGFyZ3MpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGV0IGRlcHMgPSBhcmdzLnNsaWNlKDAsIC0xKS5tYXAodG9NaXhpbik7XG4gICAgICAgICAgICByZXR1cm4gbmV3IHRoaXMoZXh0ZW5zaW9ucywgZGVwcyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIG1peGlucyhvYmopIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmogIT09ICdvYmplY3QnIHx8IG9iaiA9PT0gbnVsbCkgcmV0dXJuIFtdO1xuICAgICAgICBsZXQgbWV0YSA9IENsYXNzTWV0YS5mb3Iob2JqKTtcbiAgICAgICAgaWYgKCFtZXRhKSByZXR1cm4gW107XG4gICAgICAgIHJldHVybiBtZXRhLmdldEFwcGxpZWRNaXhpbnMoKTtcbiAgICB9XG4gICAgZGV0ZWN0KG9iaikge1xuICAgICAgICBpZiAodHlwZW9mIG9iaiAhPT0gJ29iamVjdCcgfHwgb2JqID09PSBudWxsKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIGlmIChvYmogaW5zdGFuY2VvZiBNaXhpbikge1xuICAgICAgICAgICAgcmV0dXJuIG9iai5kZXBlbmRlbmNpZXMuaW5kZXhPZih0aGlzKSAhPT0gLTE7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IG1ldGEgPSBDbGFzc01ldGEuZm9yKG9iaik7XG4gICAgICAgIHJldHVybiAhIW1ldGEgJiYgbWV0YS5oYXNBcHBsaWVkTWl4aW4odGhpcyk7XG4gICAgfVxuICAgIHJlb3BlbihleHRlbnNpb25zKSB7XG4gICAgICAgIGlmICh0aGlzLmV4dGVuc2lvbnMpIHtcbiAgICAgICAgICAgIHRoaXMuZGVwZW5kZW5jaWVzLnB1c2godG9NaXhpbih0aGlzLmV4dGVuc2lvbnMpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGV4dGVuc2lvbnMgPT09ICdvYmplY3QnICYmICdjb25jYXRlbmF0ZWRQcm9wZXJ0aWVzJyBpbiBleHRlbnNpb25zKSB7XG4gICAgICAgICAgICBsZXQgY29uY2F0O1xuICAgICAgICAgICAgbGV0IHJhd0NvbmNhdCA9IGV4dGVuc2lvbnMuY29uY2F0ZW5hdGVkUHJvcGVydGllcztcbiAgICAgICAgICAgIGlmIChpc0FycmF5KHJhd0NvbmNhdCkpIHtcbiAgICAgICAgICAgICAgICBjb25jYXQgPSByYXdDb25jYXQuc2xpY2UoKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocmF3Q29uY2F0ID09PSBudWxsIHx8IHJhd0NvbmNhdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgY29uY2F0ID0gW107XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbmNhdCA9IFtyYXdDb25jYXRdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVsZXRlIGV4dGVuc2lvbnMuY29uY2F0ZW5hdGVkUHJvcGVydGllcztcbiAgICAgICAgICAgIHRoaXMuY29uY2F0ZW5hdGVkUHJvcGVydGllcyA9IGNvbmNhdDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGV4dGVuc2lvbnMgPT09ICdvYmplY3QnICYmICdtZXJnZWRQcm9wZXJ0aWVzJyBpbiBleHRlbnNpb25zKSB7XG4gICAgICAgICAgICBsZXQgbWVyZ2VkO1xuICAgICAgICAgICAgbGV0IHJhd01lcmdlZCA9IGV4dGVuc2lvbnMubWVyZ2VkUHJvcGVydGllcztcbiAgICAgICAgICAgIGlmIChpc0FycmF5KHJhd01lcmdlZCkpIHtcbiAgICAgICAgICAgICAgICBtZXJnZWQgPSByYXdNZXJnZWQuc2xpY2UoKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocmF3TWVyZ2VkID09PSBudWxsIHx8IHJhd01lcmdlZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgbWVyZ2VkID0gW107XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG1lcmdlZCA9IFtyYXdNZXJnZWRdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVsZXRlIGV4dGVuc2lvbnMubWVyZ2VkUHJvcGVydGllcztcbiAgICAgICAgICAgIHRoaXMubWVyZ2VkUHJvcGVydGllcyA9IG1lcmdlZDtcbiAgICAgICAgfVxuICAgICAgICBsZXQgbm9ybWFsaXplZCA9IE9iamVjdC5rZXlzKGV4dGVuc2lvbnMpLnJlZHVjZSgob2JqLCBrZXkpID0+IHtcbiAgICAgICAgICAgIGxldCB2YWx1ZSA9IGV4dGVuc2lvbnNba2V5XTtcbiAgICAgICAgICAgIHN3aXRjaCAodHlwZW9mIHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAnZnVuY3Rpb24nOlxuICAgICAgICAgICAgICAgICAgICBvYmpba2V5XSA9IG5ldyBNZXRob2RCbHVlcHJpbnQoeyB2YWx1ZSB9KTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnb2JqZWN0JzpcbiAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlICYmIEJMVUVQUklOVCBpbiB2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgb2JqW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIG9ialtrZXldID0gbmV3IERhdGFCbHVlcHJpbnQoeyB2YWx1ZSB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBvYmo7XG4gICAgICAgIH0sIGRpY3QoKSk7XG4gICAgICAgIHRoaXMuZXh0ZW5zaW9ucyA9IGRpY3QoKTtcbiAgICAgICAgYXNzaWduKHRoaXMuZXh0ZW5zaW9ucywgdHVyYm9jaGFyZ2Uobm9ybWFsaXplZCkpO1xuICAgIH1cbiAgICBhcHBseSh0YXJnZXQpIHtcbiAgICAgICAgbGV0IG1ldGEgPSB0YXJnZXRbQ0xBU1NfTUVUQV0gPSB0YXJnZXRbQ0xBU1NfTUVUQV0gfHwgbmV3IENsYXNzTWV0YSgpO1xuICAgICAgICB0aGlzLmRlcGVuZGVuY2llcy5mb3JFYWNoKG0gPT4gbS5hcHBseSh0YXJnZXQpKTtcbiAgICAgICAgdGhpcy5tZXJnZVByb3BlcnRpZXModGFyZ2V0LCB0YXJnZXQsIG1ldGEpO1xuICAgICAgICBtZXRhLmFkZE1peGluKHRoaXMpO1xuICAgICAgICBtZXRhLnNlYWwoKTtcbiAgICAgICAgbWV0YS5yZXNlYWwodGFyZ2V0KTtcbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9XG4gICAgZXh0ZW5kUHJvdG90eXBlKE9yaWdpbmFsKSB7XG4gICAgICAgIE9yaWdpbmFsLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoT3JpZ2luYWwucHJvdG90eXBlKTtcbiAgICAgICAgdGhpcy5kZXBlbmRlbmNpZXMuZm9yRWFjaChtID0+IG0uZXh0ZW5kUHJvdG90eXBlKE9yaWdpbmFsKSk7XG4gICAgICAgIHRoaXMuZXh0ZW5kUHJvdG90eXBlT250byhPcmlnaW5hbCwgT3JpZ2luYWwpO1xuICAgIH1cbiAgICBleHRlbmRQcm90b3R5cGVPbnRvKFN1YmNsYXNzLCBQYXJlbnQpIHtcbiAgICAgICAgdGhpcy5kZXBlbmRlbmNpZXMuZm9yRWFjaChtID0+IG0uZXh0ZW5kUHJvdG90eXBlT250byhTdWJjbGFzcywgUGFyZW50KSk7XG4gICAgICAgIHRoaXMubWVyZ2VQcm9wZXJ0aWVzKFN1YmNsYXNzLnByb3RvdHlwZSwgUGFyZW50LnByb3RvdHlwZSwgU3ViY2xhc3NbQ0xBU1NfTUVUQV0pO1xuICAgICAgICBTdWJjbGFzc1tDTEFTU19NRVRBXS5hZGRNaXhpbih0aGlzKTtcbiAgICB9XG4gICAgZXh0ZW5kU3RhdGljKFRhcmdldCkge1xuICAgICAgICB0aGlzLmRlcGVuZGVuY2llcy5mb3JFYWNoKG0gPT4gbS5leHRlbmRTdGF0aWMoVGFyZ2V0KSk7XG4gICAgICAgIHRoaXMubWVyZ2VQcm9wZXJ0aWVzKFRhcmdldCwgT2JqZWN0LmdldFByb3RvdHlwZU9mKFRhcmdldCksIFRhcmdldFtDTEFTU19NRVRBXVtDTEFTU19NRVRBXSk7XG4gICAgICAgIFRhcmdldFtDTEFTU19NRVRBXS5hZGRTdGF0aWNNaXhpbih0aGlzKTtcbiAgICB9XG4gICAgbWVyZ2VQcm9wZXJ0aWVzKHRhcmdldCwgcGFyZW50LCBtZXRhKSB7XG4gICAgICAgIGlmIChtZXRhLmhhc0FwcGxpZWRNaXhpbih0aGlzKSkgcmV0dXJuO1xuICAgICAgICBtZXRhLmFkZEFwcGxpZWRNaXhpbih0aGlzKTtcbiAgICAgICAgdGhpcy5tZXJnZWRQcm9wZXJ0aWVzLmZvckVhY2goayA9PiBtZXRhLmFkZE1lcmdlZFByb3BlcnR5KGssIHBhcmVudFtrXSkpO1xuICAgICAgICB0aGlzLmNvbmNhdGVuYXRlZFByb3BlcnRpZXMuZm9yRWFjaChrID0+IG1ldGEuYWRkQ29uY2F0ZW5hdGVkUHJvcGVydHkoaywgW10pKTtcbiAgICAgICAgbmV3IFZhbHVlRGVzY3JpcHRvcih7IHZhbHVlOiBtZXRhLmdldENvbmNhdGVuYXRlZFByb3BlcnRpZXMoKSB9KS5kZWZpbmUodGFyZ2V0LCAnY29uY2F0ZW5hdGVkUHJvcGVydGllcycpO1xuICAgICAgICBuZXcgVmFsdWVEZXNjcmlwdG9yKHsgdmFsdWU6IG1ldGEuZ2V0TWVyZ2VkUHJvcGVydGllcygpIH0pLmRlZmluZSh0YXJnZXQsICdtZXJnZWRQcm9wZXJ0aWVzJyk7XG4gICAgICAgIE9iamVjdC5rZXlzKHRoaXMuZXh0ZW5zaW9ucykuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICAgICAgbGV0IGV4dGVuc2lvbiA9IHRoaXMuZXh0ZW5zaW9uc1trZXldO1xuICAgICAgICAgICAgbGV0IGRlc2MgPSBleHRlbnNpb24uZGVzY3JpcHRvcih0YXJnZXQsIGtleSwgbWV0YSk7XG4gICAgICAgICAgICBkZXNjLmRlZmluZSh0YXJnZXQsIGtleSwgcGFyZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIG5ldyBWYWx1ZURlc2NyaXB0b3IoeyB2YWx1ZTogUk9PVCB9KS5kZWZpbmUodGFyZ2V0LCAnX3N1cGVyJyk7XG4gICAgfVxufVxuZXhwb3J0IGZ1bmN0aW9uIGV4dGVuZChQYXJlbnQsIC4uLmV4dGVuc2lvbnMpIHtcbiAgICBsZXQgU3VwZXIgPSBQYXJlbnQ7XG4gICAgbGV0IFN1YmNsYXNzID0gY2xhc3MgZXh0ZW5kcyBTdXBlciB7fTtcbiAgICBTdWJjbGFzc1tDTEFTU19NRVRBXSA9IEluc3RhbmNlTWV0YS5mcm9tUGFyZW50KFBhcmVudFtDTEFTU19NRVRBXSk7XG4gICAgbGV0IG1peGlucyA9IGV4dGVuc2lvbnMubWFwKHRvTWl4aW4pO1xuICAgIFBhcmVudFtDTEFTU19NRVRBXS5hZGRTdWJjbGFzcyhTdWJjbGFzcyk7XG4gICAgbWl4aW5zLmZvckVhY2gobSA9PiBTdWJjbGFzc1tDTEFTU19NRVRBXS5hZGRNaXhpbihtKSk7XG4gICAgQ2xhc3NNZXRhLmFwcGx5QWxsTWl4aW5zKFN1YmNsYXNzLCBQYXJlbnQpO1xuICAgIHJldHVybiBTdWJjbGFzcztcbn1cbmV4cG9ydCBmdW5jdGlvbiByZWxpbmtTdWJjbGFzc2VzKFBhcmVudCkge1xuICAgIFBhcmVudFtDTEFTU19NRVRBXS5nZXRTdWJjbGFzc2VzKCkuZm9yRWFjaChTdWJjbGFzcyA9PiB7XG4gICAgICAgIFN1YmNsYXNzW0NMQVNTX01FVEFdLnJlc2V0KFBhcmVudFtDTEFTU19NRVRBXSk7XG4gICAgICAgIFN1YmNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoUGFyZW50LnByb3RvdHlwZSk7XG4gICAgICAgIENsYXNzTWV0YS5hcHBseUFsbE1peGlucyhTdWJjbGFzcywgUGFyZW50KTtcbiAgICAgICAgLy8gcmVjdXJzZSBpbnRvIHN1Yi1zdWJjbGFzc2VzXG4gICAgICAgIHJlbGlua1N1YmNsYXNzZXMoU3ViY2xhc3MpO1xuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHRvTWl4aW4oZXh0ZW5zaW9uKSB7XG4gICAgaWYgKGV4dGVuc2lvbiBpbnN0YW5jZW9mIE1peGluKSByZXR1cm4gZXh0ZW5zaW9uO2Vsc2UgcmV0dXJuIG5ldyBNaXhpbihleHRlbnNpb24sIFtdKTtcbn1cbmNsYXNzIFZhbHVlRGVzY3JpcHRvciBleHRlbmRzIERlc2NyaXB0b3Ige1xuICAgIGNvbnN0cnVjdG9yKHsgZW51bWVyYWJsZSA9IHRydWUsIGNvbmZpZ3VyYWJsZSA9IHRydWUsIHdyaXRhYmxlID0gdHJ1ZSwgdmFsdWUgfSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLmVudW1lcmFibGUgPSBlbnVtZXJhYmxlO1xuICAgICAgICB0aGlzLmNvbmZpZ3VyYWJsZSA9IGNvbmZpZ3VyYWJsZTtcbiAgICAgICAgdGhpcy53cml0YWJsZSA9IHdyaXRhYmxlO1xuICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgfVxuICAgIGRlZmluZSh0YXJnZXQsIGtleSwgX2hvbWUpIHtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCB7XG4gICAgICAgICAgICBlbnVtZXJhYmxlOiB0aGlzLmVudW1lcmFibGUsXG4gICAgICAgICAgICBjb25maWd1cmFibGU6IHRoaXMuY29uZmlndXJhYmxlLFxuICAgICAgICAgICAgd3JpdGFibGU6IHRoaXMud3JpdGFibGUsXG4gICAgICAgICAgICB2YWx1ZTogdGhpcy52YWx1ZVxuICAgICAgICB9KTtcbiAgICB9XG59XG5leHBvcnQgY2xhc3MgRGF0YUJsdWVwcmludCBleHRlbmRzIEJsdWVwcmludCB7XG4gICAgY29uc3RydWN0b3IoeyBlbnVtZXJhYmxlID0gdHJ1ZSwgY29uZmlndXJhYmxlID0gdHJ1ZSwgd3JpdGFibGUgPSB0cnVlLCB2YWx1ZSB9KSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMuZW51bWVyYWJsZSA9IGVudW1lcmFibGU7XG4gICAgICAgIHRoaXMuY29uZmlndXJhYmxlID0gY29uZmlndXJhYmxlO1xuICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgICAgIHRoaXMud3JpdGFibGUgPSB3cml0YWJsZTtcbiAgICB9XG4gICAgZGVzY3JpcHRvcihfdGFyZ2V0LCBrZXksIGNsYXNzTWV0YSkge1xuICAgICAgICBsZXQgeyBlbnVtZXJhYmxlLCBjb25maWd1cmFibGUsIHdyaXRhYmxlLCB2YWx1ZSB9ID0gdGhpcztcbiAgICAgICAgaWYgKGNsYXNzTWV0YS5oYXNDb25jYXRlbmF0ZWRQcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICBjbGFzc01ldGEuYWRkQ29uY2F0ZW5hdGVkUHJvcGVydHkoa2V5LCB2YWx1ZSk7XG4gICAgICAgICAgICB2YWx1ZSA9IGNsYXNzTWV0YS5nZXRDb25jYXRlbmF0ZWRQcm9wZXJ0eShrZXkpO1xuICAgICAgICB9IGVsc2UgaWYgKGNsYXNzTWV0YS5oYXNNZXJnZWRQcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICBjbGFzc01ldGEuYWRkTWVyZ2VkUHJvcGVydHkoa2V5LCB2YWx1ZSk7XG4gICAgICAgICAgICB2YWx1ZSA9IGNsYXNzTWV0YS5nZXRNZXJnZWRQcm9wZXJ0eShrZXkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgVmFsdWVEZXNjcmlwdG9yKHsgZW51bWVyYWJsZSwgY29uZmlndXJhYmxlLCB3cml0YWJsZSwgdmFsdWUgfSk7XG4gICAgfVxufVxuZXhwb3J0IGNsYXNzIEFjY2Vzc29yQmx1ZXByaW50IGV4dGVuZHMgQmx1ZXByaW50IHtcbiAgICBjb25zdHJ1Y3Rvcih7IGVudW1lcmFibGUgPSB0cnVlLCBjb25maWd1cmFibGUgPSB0cnVlLCBnZXQsIHNldCB9KSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMuZW51bWVyYWJsZSA9IGVudW1lcmFibGU7XG4gICAgICAgIHRoaXMuY29uZmlndXJhYmxlID0gY29uZmlndXJhYmxlO1xuICAgICAgICB0aGlzLmdldCA9IGdldDtcbiAgICAgICAgdGhpcy5zZXQgPSBzZXQ7XG4gICAgfVxuICAgIGRlc2NyaXB0b3IoX3RhcmdldCwgX2tleSwgX2NsYXNzTWV0YSkge1xuICAgICAgICByZXR1cm4gbmV3IFZhbHVlRGVzY3JpcHRvcih7XG4gICAgICAgICAgICBlbnVtZXJhYmxlOiB0aGlzLmVudW1lcmFibGUsXG4gICAgICAgICAgICBjb25maWd1cmFibGU6IHRoaXMuY29uZmlndXJhYmxlLFxuICAgICAgICAgICAgZ2V0OiB0aGlzLmdldCxcbiAgICAgICAgICAgIHNldDogdGhpcy5zZXRcbiAgICAgICAgfSk7XG4gICAgfVxufVxuY2xhc3MgTWV0aG9kRGVzY3JpcHRvciBleHRlbmRzIFZhbHVlRGVzY3JpcHRvciB7XG4gICAgZGVmaW5lKHRhcmdldCwga2V5LCBob21lKSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSB3cmFwTWV0aG9kKGhvbWUsIGtleSwgdGhpcy52YWx1ZSk7XG4gICAgICAgIHN1cGVyLmRlZmluZSh0YXJnZXQsIGtleSwgaG9tZSk7XG4gICAgfVxufVxuY2xhc3MgTWV0aG9kQmx1ZXByaW50IGV4dGVuZHMgRGF0YUJsdWVwcmludCB7XG4gICAgZGVzY3JpcHRvcih0YXJnZXQsIGtleSwgY2xhc3NNZXRhKSB7XG4gICAgICAgIGxldCBkZXNjID0gc3VwZXIuZGVzY3JpcHRvcih0YXJnZXQsIGtleSwgY2xhc3NNZXRhKTtcbiAgICAgICAgcmV0dXJuIG5ldyBNZXRob2REZXNjcmlwdG9yKGRlc2MpO1xuICAgIH1cbn1cbmV4cG9ydCBmdW5jdGlvbiB3cmFwTWV0aG9kKGhvbWUsIG1ldGhvZE5hbWUsIG9yaWdpbmFsKSB7XG4gICAgaWYgKCEobWV0aG9kTmFtZSBpbiBob21lKSkgcmV0dXJuIG1heWJlV3JhcChvcmlnaW5hbCk7XG4gICAgbGV0IHN1cGVyTWV0aG9kID0gaG9tZVttZXRob2ROYW1lXTtcbiAgICBsZXQgZnVuYyA9IGZ1bmN0aW9uICguLi5hcmdzKSB7XG4gICAgICAgIGlmICghdGhpcykgcmV0dXJuIG9yaWdpbmFsLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICBsZXQgbGFzdFN1cGVyID0gdGhpcy5fc3VwZXI7XG4gICAgICAgIHRoaXMuX3N1cGVyID0gc3VwZXJNZXRob2Q7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gb3JpZ2luYWwuYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICB0aGlzLl9zdXBlciA9IGxhc3RTdXBlcjtcbiAgICAgICAgfVxuICAgIH07XG4gICAgZnVuYy5fX3dyYXBwZWQgPSB0cnVlO1xuICAgIHJldHVybiBmdW5jO1xufVxuZnVuY3Rpb24gbWF5YmVXcmFwKG9yaWdpbmFsKSB7XG4gICAgaWYgKCdfX3dyYXBwZWQnIGluIG9yaWdpbmFsKSByZXR1cm4gb3JpZ2luYWw7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICguLi5hcmdzKSB7XG4gICAgICAgIGlmICghdGhpcykgcmV0dXJuIG9yaWdpbmFsLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICBsZXQgbGFzdFN1cGVyID0gdGhpcy5fc3VwZXI7XG4gICAgICAgIHRoaXMuX3N1cGVyID0gUk9PVDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIHRoaXMuX3N1cGVyID0gbGFzdFN1cGVyO1xuICAgICAgICB9XG4gICAgfTtcbn0iXX0=